From d51d8e36520da7a66122efd7afadfa447a28a317 Mon Sep 17 00:00:00 2001 From: hasufell Date: Mon, 19 May 2014 00:03:37 +0200 Subject: [PATCH 01/26] ALL: Add flint --- external/flint-2.4.3/AUTHORS | 127 + external/flint-2.4.3/INSTALL | 26 + external/flint-2.4.3/Makefile | 254 + external/flint-2.4.3/Makefile.in | 221 + external/flint-2.4.3/Makefile.subdirs | 89 + external/flint-2.4.3/NEWS | 1102 + external/flint-2.4.3/NTL-interface.h | 172 + external/flint-2.4.3/README | 15 + external/flint-2.4.3/arith.h | 242 + external/flint-2.4.3/arith/bell_number.c | 37 + .../flint-2.4.3/arith/bell_number_bsplit.c | 124 + .../flint-2.4.3/arith/bell_number_multi_mod.c | 65 + external/flint-2.4.3/arith/bell_number_nmod.c | 110 + .../flint-2.4.3/arith/bell_number_nmod_vec.c | 35 + .../arith/bell_number_nmod_vec_recursive.c | 56 + .../arith/bell_number_nmod_vec_series.c | 62 + external/flint-2.4.3/arith/bell_number_size.c | 36 + external/flint-2.4.3/arith/bell_number_vec.c | 35 + .../arith/bell_number_vec_multi_mod.c | 105 + .../arith/bell_number_vec_recursive.c | 57 + external/flint-2.4.3/arith/bernoulli_number.c | 36 + .../arith/bernoulli_number_denom.c | 80 + .../flint-2.4.3/arith/bernoulli_number_size.c | 41 + .../flint-2.4.3/arith/bernoulli_number_vec.c | 59 + .../arith/bernoulli_number_vec_multi_mod.c | 150 + .../arith/bernoulli_number_vec_recursive.c | 165 + .../arith/bernoulli_number_vec_zeta.c | 35 + .../flint-2.4.3/arith/bernoulli_number_zeta.c | 87 + .../flint-2.4.3/arith/bernoulli_polynomial.c | 73 + .../arith/chebyshev_t_polynomial.c | 72 + .../arith/chebyshev_u_polynomial.c | 72 + .../arith/cyclotomic_cos_polynomial.c | 268 + .../flint-2.4.3/arith/cyclotomic_polynomial.c | 160 + .../arith/dedekind_cosine_sum_factored.c | 307 + external/flint-2.4.3/arith/dedekind_sum.c | 84 + .../flint-2.4.3/arith/dedekind_sum_coprime.c | 54 + .../arith/dedekind_sum_coprime_d.c | 57 + .../arith/dedekind_sum_coprime_large.c | 96 + .../flint-2.4.3/arith/dedekind_sum_naive.c | 82 + external/flint-2.4.3/arith/divisor_sigma.c | 87 + external/flint-2.4.3/arith/divisors.c | 165 + external/flint-2.4.3/arith/doc/arith.txt | 876 + external/flint-2.4.3/arith/euler_number.c | 31 + .../flint-2.4.3/arith/euler_number_size.c | 38 + external/flint-2.4.3/arith/euler_number_vec.c | 147 + .../flint-2.4.3/arith/euler_number_zeta.c | 80 + external/flint-2.4.3/arith/euler_phi.c | 67 + external/flint-2.4.3/arith/euler_polynomial.c | 53 + external/flint-2.4.3/arith/harmonic_number.c | 124 + .../flint-2.4.3/arith/landau_function_vec.c | 68 + .../flint-2.4.3/arith/legendre_polynomial.c | 97 + external/flint-2.4.3/arith/moebius_mu.c | 56 + .../flint-2.4.3/arith/number_of_partitions.c | 70 + .../arith/number_of_partitions_mpfr.c | 539 + .../arith/number_of_partitions_nmod_vec.c | 61 + .../arith/number_of_partitions_vec.c | 57 + external/flint-2.4.3/arith/pi_chudnovsky.c | 653 + external/flint-2.4.3/arith/primorial.c | 151 + .../flint-2.4.3/arith/profile/p-bernoulli.c | 120 + external/flint-2.4.3/arith/ramanujan_tau.c | 120 + external/flint-2.4.3/arith/stirling1.c | 138 + external/flint-2.4.3/arith/stirling2.c | 134 + external/flint-2.4.3/arith/stirlingmat.c | 119 + external/flint-2.4.3/arith/sum_of_squares.c | 137 + .../flint-2.4.3/arith/sum_of_squares_vec.c | 108 + .../arith/swinnerton_dyer_polynomial.c | 138 + .../flint-2.4.3/arith/test/t-bell_number.c | 120 + .../arith/test/t-bell_number_multi_mod.c | 72 + .../arith/test/t-bell_number_nmod.c | 77 + .../arith/test/t-bell_number_nmod_vec.c | 78 + .../arith/test/t-bell_number_vec.c | 69 + .../arith/test/t-bernoulli_number.c | 120 + .../arith/test/t-bernoulli_number_denom.c | 67 + .../arith/test/t-bernoulli_number_vec.c | 102 + .../arith/test/t-bernoulli_polynomial.c | 89 + .../arith/test/t-chebyshev_t_polynomial.c | 82 + .../arith/test/t-chebyshev_u_polynomial.c | 72 + .../arith/test/t-cyclotomic_cos_polynomial.c | 129 + .../arith/test/t-cyclotomic_polynomial.c | 145 + .../flint-2.4.3/arith/test/t-dedekind_sum.c | 192 + .../arith/test/t-dedekind_sum_coprime_d.c | 86 + .../arith/test/t-dedekind_sum_coprime_large.c | 83 + .../flint-2.4.3/arith/test/t-divisor_sigma.c | 94 + external/flint-2.4.3/arith/test/t-divisors.c | 86 + .../arith/test/t-euler_number_vec.c | 81 + .../arith/test/t-euler_number_zeta.c | 74 + external/flint-2.4.3/arith/test/t-euler_phi.c | 118 + .../arith/test/t-euler_polynomial.c | 93 + external/flint-2.4.3/arith/test/t-harmonic.c | 154 + .../arith/test/t-landau_function_vec.c | 70 + .../arith/test/t-legendre_polynomial.c | 86 + .../flint-2.4.3/arith/test/t-moebius_mu.c | 98 + .../arith/test/t-number_of_partitions.c | 160 + .../arith/test/t-number_of_partitions_vec.c | 120 + .../flint-2.4.3/arith/test/t-pi_chudnovsky.c | 66 + external/flint-2.4.3/arith/test/t-primorial.c | 69 + .../flint-2.4.3/arith/test/t-ramanujan_tau.c | 172 + external/flint-2.4.3/arith/test/t-stirling.c | 215 + .../flint-2.4.3/arith/test/t-sum_of_squares.c | 88 + .../arith/test/t-swinnerton_dyer_polynomial.c | 80 + .../arith/zeta_inv_euler_product.c | 107 + external/flint-2.4.3/arithxx.h | 339 + external/flint-2.4.3/clz_tab.c | 45 + external/flint-2.4.3/code_conventions.txt | 109 + external/flint-2.4.3/config.h | 8 + external/flint-2.4.3/configure | 647 + external/flint-2.4.3/doc/longlong.txt | 140 + external/flint-2.4.3/doc/profiler.txt | 167 + external/flint-2.4.3/double_extras.h | 68 + .../double_extras/doc/double_extras.txt | 71 + external/flint-2.4.3/double_extras/lambertw.c | 168 + external/flint-2.4.3/double_extras/randtest.c | 54 + .../double_extras/test/t-lambertw.c | 160 + external/flint-2.4.3/examples/crt.c | 78 + external/flint-2.4.3/examples/crt.cpp | 68 + external/flint-2.4.3/examples/delta_qexp.c | 69 + external/flint-2.4.3/examples/delta_qexp.cpp | 59 + external/flint-2.4.3/examples/fmpq_poly.c | 57 + external/flint-2.4.3/examples/fmpq_poly.cpp | 45 + external/flint-2.4.3/examples/fmpz_mod_poly.c | 56 + .../flint-2.4.3/examples/fmpz_mod_poly.cpp | 49 + .../examples/fmpz_poly_factor_zassenhaus.c | 73 + .../examples/fmpz_poly_factor_zassenhaus.cpp | 63 + .../flint-2.4.3/examples/fmpz_poly_hensel_P1 | 1 + external/flint-2.4.3/examples/fmpz_poly_q.c | 61 + external/flint-2.4.3/examples/fmpz_poly_q.cpp | 44 + external/flint-2.4.3/examples/fooxx.cpp | 365 + external/flint-2.4.3/examples/fq_poly.c | 160 + external/flint-2.4.3/examples/multi_crt.c | 103 + external/flint-2.4.3/examples/multi_crt.cpp | 73 + external/flint-2.4.3/examples/padic.c | 164 + external/flint-2.4.3/examples/padic.cpp | 116 + external/flint-2.4.3/examples/partitions.c | 30 + external/flint-2.4.3/examples/partitions.cpp | 24 + external/flint-2.4.3/examples/primegen.c | 69 + external/flint-2.4.3/examples/qadic.c | 174 + external/flint-2.4.3/examples/radix.c | 139 + external/flint-2.4.3/examples/radix.cpp | 94 + .../flint-2.4.3/examples/stirling_matrix.c | 76 + .../flint-2.4.3/examples/stirling_matrix.cpp | 65 + external/flint-2.4.3/fft.h | 289 + external/flint-2.4.3/fft/README | 296 + external/flint-2.4.3/fft/adjust.c | 55 + external/flint-2.4.3/fft/adjust_sqrt2.c | 86 + external/flint-2.4.3/fft/butterfly_lshB.c | 117 + external/flint-2.4.3/fft/butterfly_rshB.c | 105 + external/flint-2.4.3/fft/combine_bits.c | 114 + external/flint-2.4.3/fft/convolution.c | 84 + external/flint-2.4.3/fft/div_2expmod_2expp1.c | 56 + external/flint-2.4.3/fft/doc/fft.txt | 658 + external/flint-2.4.3/fft/fermat_to_mpz.c | 55 + .../flint-2.4.3/fft/fft_mfa_truncate_sqrt2.c | 325 + .../fft/fft_mfa_truncate_sqrt2_inner.c | 91 + external/flint-2.4.3/fft/fft_negacylic.c | 86 + external/flint-2.4.3/fft/fft_radix2.c | 75 + external/flint-2.4.3/fft/fft_truncate.c | 90 + external/flint-2.4.3/fft/fft_truncate_sqrt2.c | 117 + .../flint-2.4.3/fft/ifft_mfa_truncate_sqrt2.c | 370 + external/flint-2.4.3/fft/ifft_negacyclic.c | 92 + external/flint-2.4.3/fft/ifft_radix2.c | 75 + external/flint-2.4.3/fft/ifft_truncate.c | 120 + .../flint-2.4.3/fft/ifft_truncate_sqrt2.c | 121 + external/flint-2.4.3/fft/mul_2expmod_2expp1.c | 55 + external/flint-2.4.3/fft/mul_fft_main.c | 105 + .../flint-2.4.3/fft/mul_mfa_truncate_sqrt2.c | 102 + external/flint-2.4.3/fft/mul_truncate_sqrt2.c | 113 + external/flint-2.4.3/fft/mulmod_2expp1.c | 254 + external/flint-2.4.3/fft/normmod_2expp1.c | 59 + .../flint-2.4.3/fft/profile/p-mul_fft_main.c | 79 + .../fft/profile/p-mul_mfa_truncate_sqrt2.c | 87 + .../fft/profile/p-mul_truncate_sqrt2.c | 87 + external/flint-2.4.3/fft/split_bits.c | 110 + external/flint-2.4.3/fft/test/t-adjust.c | 127 + .../flint-2.4.3/fft/test/t-adjust_sqrt2.c | 137 + external/flint-2.4.3/fft/test/t-butterfly.c | 226 + .../flint-2.4.3/fft/test/t-butterfly_lshB.c | 159 + .../flint-2.4.3/fft/test/t-butterfly_rshB.c | 173 + .../flint-2.4.3/fft/test/t-butterfly_sqrt2.c | 238 + .../fft/test/t-butterfly_twiddle.c | 232 + .../fft/test/t-div_2expmod_2expp1.c | 121 + .../fft/test/t-fft_ifft_mfa_truncate_sqrt2.c | 114 + .../fft/test/t-fft_ifft_negacyclic.c | 109 + .../flint-2.4.3/fft/test/t-fft_ifft_radix2.c | 108 + .../fft/test/t-fft_ifft_truncate.c | 111 + .../fft/test/t-fft_ifft_truncate_sqrt2.c | 113 + .../fft/test/t-mul_2expmod_2expp1.c | 121 + .../flint-2.4.3/fft/test/t-mul_fft_main.c | 116 + .../fft/test/t-mul_mfa_truncate_sqrt2.c | 126 + .../fft/test/t-mul_truncate_sqrt2.c | 126 + .../flint-2.4.3/fft/test/t-mulmod_2expp1.c | 148 + .../flint-2.4.3/fft/test/t-normmod_2expp1.c | 108 + .../fft/test/t-split_combine_bits.c | 95 + external/flint-2.4.3/fft/tune/tune-fft.c | 200 + external/flint-2.4.3/fft_tuning.h | 19 + external/flint-2.4.3/fft_tuning32.in | 19 + external/flint-2.4.3/fft_tuning64.in | 19 + external/flint-2.4.3/flint.h | 339 + external/flint-2.4.3/flint.supp | 16 + external/flint-2.4.3/flintxx.h | 26 + external/flint-2.4.3/flintxx/default_rules.h | 395 + external/flint-2.4.3/flintxx/doc/Makefile | 4 + external/flint-2.4.3/flintxx/doc/design.tex | 423 + external/flint-2.4.3/flintxx/doc/flintxx.txt | 4772 +++ .../flint-2.4.3/flintxx/doc/genericxx.txt | 478 + external/flint-2.4.3/flintxx/dummy.c | 2 + .../flint-2.4.3/flintxx/evaluation_tools.h | 1114 + external/flint-2.4.3/flintxx/expression.h | 961 + .../flint-2.4.3/flintxx/expression_traits.h | 109 + external/flint-2.4.3/flintxx/flint_classes.h | 760 + .../flint-2.4.3/flintxx/flint_exception.h | 55 + external/flint-2.4.3/flintxx/forwarding.h | 234 + external/flint-2.4.3/flintxx/frandxx.h | 52 + external/flint-2.4.3/flintxx/ltuple.h | 424 + external/flint-2.4.3/flintxx/matrix.h | 462 + external/flint-2.4.3/flintxx/mp.h | 139 + external/flint-2.4.3/flintxx/rules.h | 453 + external/flint-2.4.3/flintxx/stdmath.h | 153 + external/flint-2.4.3/flintxx/test/helpers.h | 199 + .../test/make-compiler-errors-report.sh | 32 + external/flint-2.4.3/flintxx/test/myint.h | 458 + .../flint-2.4.3/flintxx/test/t-arithxx.cpp | 237 + .../flint-2.4.3/flintxx/test/t-codegen.cpp | 833 + .../flintxx/test/t-compiler-errors.cc | 130 + .../flint-2.4.3/flintxx/test/t-expression.cpp | 394 + .../flintxx/test/t-flint_classes.cpp | 75 + .../flint-2.4.3/flintxx/test/t-fmpq_matxx.cpp | 340 + .../flintxx/test/t-fmpq_polyxx.cpp | 327 + .../flint-2.4.3/flintxx/test/t-fmpqxx.cpp | 248 + .../flint-2.4.3/flintxx/test/t-fmpz_matxx.cpp | 304 + .../flintxx/test/t-fmpz_mod_polyxx.cpp | 394 + .../flintxx/test/t-fmpz_poly_matxx.cpp | 292 + .../flintxx/test/t-fmpz_poly_qxx.cpp | 178 + .../flintxx/test/t-fmpz_polyxx.cpp | 492 + .../flint-2.4.3/flintxx/test/t-fmpzxx.cpp | 615 + .../flint-2.4.3/flintxx/test/t-forwarding.cpp | 165 + .../flint-2.4.3/flintxx/test/t-ltuple.cpp | 192 + external/flint-2.4.3/flintxx/test/t-mp.cpp | 133 + .../flint-2.4.3/flintxx/test/t-nmod_matxx.cpp | 327 + .../flintxx/test/t-nmod_poly_matxx.cpp | 279 + .../flintxx/test/t-nmod_polyxx.cpp | 522 + .../flint-2.4.3/flintxx/test/t-nmod_vecxx.cpp | 157 + .../flintxx/test/t-padic_matxx.cpp | 214 + .../flintxx/test/t-padic_polyxx.cpp | 219 + .../flint-2.4.3/flintxx/test/t-padicxx.cpp | 241 + .../flint-2.4.3/flintxx/test/t-permxx.cpp | 68 + .../flint-2.4.3/flintxx/test/t-qadicxx.cpp | 207 + .../flint-2.4.3/flintxx/test/t-traits.cpp | 136 + external/flint-2.4.3/flintxx/test/t-tuple.cpp | 417 + .../flint-2.4.3/flintxx/test/t-vector.cpp | 105 + external/flint-2.4.3/flintxx/traits.h | 144 + external/flint-2.4.3/flintxx/traits_fwd.h | 41 + external/flint-2.4.3/flintxx/tuple.h | 650 + external/flint-2.4.3/flintxx/vector.h | 461 + external/flint-2.4.3/fmpq.h | 316 + external/flint-2.4.3/fmpq/add.c | 155 + external/flint-2.4.3/fmpq/addmul.c | 49 + external/flint-2.4.3/fmpq/canonicalise.c | 62 + external/flint-2.4.3/fmpq/cfrac_bound.c | 37 + external/flint-2.4.3/fmpq/clear_readonly.c | 33 + external/flint-2.4.3/fmpq/cmp.c | 81 + external/flint-2.4.3/fmpq/div.c | 64 + external/flint-2.4.3/fmpq/div_2exp.c | 49 + external/flint-2.4.3/fmpq/div_fmpz.c | 46 + external/flint-2.4.3/fmpq/doc/fmpq.txt | 594 + external/flint-2.4.3/fmpq/fprint.c | 46 + external/flint-2.4.3/fmpq/get_cfrac.c | 54 + external/flint-2.4.3/fmpq/get_mpfr.c | 62 + external/flint-2.4.3/fmpq/get_str.c | 63 + external/flint-2.4.3/fmpq/height.c | 35 + external/flint-2.4.3/fmpq/height_bits.c | 37 + external/flint-2.4.3/fmpq/init_set_readonly.c | 33 + external/flint-2.4.3/fmpq/inv.c | 46 + external/flint-2.4.3/fmpq/is_canonical.c | 47 + external/flint-2.4.3/fmpq/mod_fmpz.c | 47 + .../flint-2.4.3/fmpq/mpq_clear_readonly.c | 33 + .../flint-2.4.3/fmpq/mpq_init_set_readonly.c | 33 + external/flint-2.4.3/fmpq/mul.c | 105 + external/flint-2.4.3/fmpq/mul_2exp.c | 49 + external/flint-2.4.3/fmpq/mul_fmpz.c | 39 + external/flint-2.4.3/fmpq/next_calkin_wilf.c | 68 + external/flint-2.4.3/fmpq/next_minimal.c | 99 + .../fmpq/next_signed_calkin_wilf.c | 49 + .../flint-2.4.3/fmpq/next_signed_minimal.c | 49 + external/flint-2.4.3/fmpq/pow_si.c | 68 + external/flint-2.4.3/fmpq/randbits.c | 43 + external/flint-2.4.3/fmpq/randtest.c | 81 + external/flint-2.4.3/fmpq/reconstruct_fmpz.c | 116 + external/flint-2.4.3/fmpq/set_cfrac.c | 96 + external/flint-2.4.3/fmpq/set_fmpz_frac.c | 74 + external/flint-2.4.3/fmpq/set_si.c | 54 + external/flint-2.4.3/fmpq/sub.c | 142 + external/flint-2.4.3/fmpq/submul.c | 49 + external/flint-2.4.3/fmpq/test/t-abs.c | 113 + external/flint-2.4.3/fmpq/test/t-add.c | 194 + external/flint-2.4.3/fmpq/test/t-addmul.c | 203 + .../flint-2.4.3/fmpq/test/t-canonicalise.c | 113 + .../flint-2.4.3/fmpq/test/t-cfrac_bound.c | 86 + external/flint-2.4.3/fmpq/test/t-cmp.c | 93 + external/flint-2.4.3/fmpq/test/t-div.c | 208 + external/flint-2.4.3/fmpq/test/t-div_2exp.c | 154 + external/flint-2.4.3/fmpq/test/t-div_fmpz.c | 112 + external/flint-2.4.3/fmpq/test/t-get_cfrac.c | 103 + external/flint-2.4.3/fmpq/test/t-get_mpfr.c | 96 + external/flint-2.4.3/fmpq/test/t-get_str.c | 92 + external/flint-2.4.3/fmpq/test/t-height.c | 75 + .../fmpq/test/t-init_set_readonly.c | 126 + external/flint-2.4.3/fmpq/test/t-inv.c | 156 + .../fmpq/test/t-mpq_init_set_readonly.c | 104 + external/flint-2.4.3/fmpq/test/t-mul.c | 194 + external/flint-2.4.3/fmpq/test/t-mul_2exp.c | 154 + external/flint-2.4.3/fmpq/test/t-mul_fmpz.c | 110 + .../fmpq/test/t-next_calkin_wilf.c | 119 + .../flint-2.4.3/fmpq/test/t-next_minimal.c | 119 + external/flint-2.4.3/fmpq/test/t-one.c | 104 + external/flint-2.4.3/fmpq/test/t-pow_si.c | 122 + .../fmpq/test/t-reconstruct_fmpz.c | 121 + .../fmpq/test/t-reconstruct_fmpz_2.c | 139 + external/flint-2.4.3/fmpq/test/t-set_cfrac.c | 83 + .../flint-2.4.3/fmpq/test/t-set_fmpz_frac.c | 85 + external/flint-2.4.3/fmpq/test/t-set_si.c | 87 + external/flint-2.4.3/fmpq/test/t-sub.c | 194 + external/flint-2.4.3/fmpq/test/t-submul.c | 203 + external/flint-2.4.3/fmpq_mat.h | 193 + external/flint-2.4.3/fmpq_mat/add.c | 37 + external/flint-2.4.3/fmpq_mat/clear.c | 40 + external/flint-2.4.3/fmpq_mat/det.c | 73 + .../flint-2.4.3/fmpq_mat/doc/fmpq_mat.txt | 428 + external/flint-2.4.3/fmpq_mat/equal.c | 48 + external/flint-2.4.3/fmpq_mat/get_fmpz_mat.c | 45 + .../fmpq_mat/get_fmpz_mat_colwise.c | 71 + .../fmpq_mat/get_fmpz_mat_entrywise.c | 42 + .../fmpq_mat/get_fmpz_mat_matwise.c | 69 + .../fmpq_mat/get_fmpz_mat_mod_fmpz.c | 43 + .../fmpq_mat/get_fmpz_mat_rowwise.c | 97 + .../flint-2.4.3/fmpq_mat/hilbert_matrix.c | 35 + external/flint-2.4.3/fmpq_mat/init.c | 49 + external/flint-2.4.3/fmpq_mat/inv.c | 110 + external/flint-2.4.3/fmpq_mat/is_integral.c | 42 + external/flint-2.4.3/fmpq_mat/is_zero.c | 42 + external/flint-2.4.3/fmpq_mat/mul.c | 32 + external/flint-2.4.3/fmpq_mat/mul_cleared.c | 67 + external/flint-2.4.3/fmpq_mat/mul_direct.c | 60 + external/flint-2.4.3/fmpq_mat/mul_fmpz_mat.c | 60 + .../flint-2.4.3/fmpq_mat/mul_r_fmpz_mat.c | 60 + external/flint-2.4.3/fmpq_mat/neg.c | 37 + external/flint-2.4.3/fmpq_mat/one.c | 41 + external/flint-2.4.3/fmpq_mat/pivot.c | 55 + external/flint-2.4.3/fmpq_mat/print.c | 46 + external/flint-2.4.3/fmpq_mat/randbits.c | 35 + external/flint-2.4.3/fmpq_mat/randtest.c | 35 + external/flint-2.4.3/fmpq_mat/rref.c | 35 + .../flint-2.4.3/fmpq_mat/rref_classical.c | 86 + .../flint-2.4.3/fmpq_mat/rref_fraction_free.c | 53 + .../flint-2.4.3/fmpq_mat/scalar_div_fmpz.c | 38 + .../flint-2.4.3/fmpq_mat/scalar_mul_fmpz.c | 38 + external/flint-2.4.3/fmpq_mat/set.c | 35 + external/flint-2.4.3/fmpq_mat/set_fmpz_mat.c | 40 + .../fmpq_mat/set_fmpz_mat_div_fmpz.c | 69 + .../fmpq_mat/set_fmpz_mat_mod_fmpz.c | 76 + external/flint-2.4.3/fmpq_mat/solve_dixon.c | 53 + .../fmpq_mat/solve_fraction_free.c | 55 + external/flint-2.4.3/fmpq_mat/sub.c | 37 + external/flint-2.4.3/fmpq_mat/test/t-add.c | 171 + external/flint-2.4.3/fmpq_mat/test/t-det.c | 105 + .../flint-2.4.3/fmpq_mat/test/t-init_clear.c | 66 + external/flint-2.4.3/fmpq_mat/test/t-inv.c | 191 + .../flint-2.4.3/fmpq_mat/test/t-is_integral.c | 89 + external/flint-2.4.3/fmpq_mat/test/t-mul.c | 92 + external/flint-2.4.3/fmpq_mat/test/t-neg.c | 118 + external/flint-2.4.3/fmpq_mat/test/t-one.c | 91 + external/flint-2.4.3/fmpq_mat/test/t-rref.c | 117 + .../fmpq_mat/test/t-scalar_div_fmpz.c | 131 + .../fmpq_mat/test/t-scalar_mul_fmpz.c | 131 + .../flint-2.4.3/fmpq_mat/test/t-solve_dixon.c | 142 + .../fmpq_mat/test/t-solve_fraction_free.c | 143 + external/flint-2.4.3/fmpq_mat/test/t-sub.c | 173 + external/flint-2.4.3/fmpq_mat/test/t-trace.c | 96 + .../flint-2.4.3/fmpq_mat/test/t-transpose.c | 124 + external/flint-2.4.3/fmpq_mat/trace.c | 41 + external/flint-2.4.3/fmpq_mat/transpose.c | 47 + external/flint-2.4.3/fmpq_mat/zero.c | 35 + external/flint-2.4.3/fmpq_matxx.h | 478 + external/flint-2.4.3/fmpq_poly.h | 737 + external/flint-2.4.3/fmpq_poly/add.c | 154 + external/flint-2.4.3/fmpq_poly/asin_series.c | 101 + external/flint-2.4.3/fmpq_poly/asinh_series.c | 100 + external/flint-2.4.3/fmpq_poly/atan_series.c | 99 + external/flint-2.4.3/fmpq_poly/atanh_series.c | 100 + external/flint-2.4.3/fmpq_poly/canonicalise.c | 70 + external/flint-2.4.3/fmpq_poly/clear.c | 44 + external/flint-2.4.3/fmpq_poly/cmp.c | 101 + external/flint-2.4.3/fmpq_poly/compose.c | 116 + .../flint-2.4.3/fmpq_poly/compose_series.c | 114 + .../fmpq_poly/compose_series_brent_kung.c | 235 + .../fmpq_poly/compose_series_horner.c | 161 + external/flint-2.4.3/fmpq_poly/content.c | 43 + external/flint-2.4.3/fmpq_poly/cos_series.c | 112 + external/flint-2.4.3/fmpq_poly/cosh_series.c | 112 + external/flint-2.4.3/fmpq_poly/debug.c | 48 + external/flint-2.4.3/fmpq_poly/derivative.c | 53 + external/flint-2.4.3/fmpq_poly/div.c | 127 + external/flint-2.4.3/fmpq_poly/div_series.c | 103 + external/flint-2.4.3/fmpq_poly/divrem.c | 179 + .../flint-2.4.3/fmpq_poly/doc/fmpq_poly.txt | 1657 + external/flint-2.4.3/fmpq_poly/equal.c | 38 + .../flint-2.4.3/fmpq_poly/evaluate_fmpq.c | 73 + .../flint-2.4.3/fmpq_poly/evaluate_fmpz.c | 60 + external/flint-2.4.3/fmpq_poly/evaluate_mpq.c | 46 + external/flint-2.4.3/fmpq_poly/evaluate_mpz.c | 46 + external/flint-2.4.3/fmpq_poly/exp_series.c | 131 + external/flint-2.4.3/fmpq_poly/fit_length.c | 42 + external/flint-2.4.3/fmpq_poly/fprint.c | 96 + .../flint-2.4.3/fmpq_poly/fprint_pretty.c | 184 + external/flint-2.4.3/fmpq_poly/fread.c | 71 + external/flint-2.4.3/fmpq_poly/gcd.c | 146 + .../flint-2.4.3/fmpq_poly/get_coeff_fmpq.c | 46 + .../flint-2.4.3/fmpq_poly/get_coeff_mpq.c | 45 + external/flint-2.4.3/fmpq_poly/get_slice.c | 64 + external/flint-2.4.3/fmpq_poly/get_str.c | 92 + .../flint-2.4.3/fmpq_poly/get_str_pretty.c | 218 + external/flint-2.4.3/fmpq_poly/init.c | 52 + external/flint-2.4.3/fmpq_poly/integral.c | 74 + .../fmpq_poly/interpolate_fmpz_vec.c | 123 + external/flint-2.4.3/fmpq_poly/inv.c | 65 + .../flint-2.4.3/fmpq_poly/inv_series_newton.c | 147 + .../flint-2.4.3/fmpq_poly/invsqrt_series.c | 133 + external/flint-2.4.3/fmpq_poly/is_canonical.c | 64 + external/flint-2.4.3/fmpq_poly/is_monic.c | 41 + .../flint-2.4.3/fmpq_poly/is_squarefree.c | 37 + external/flint-2.4.3/fmpq_poly/lcm.c | 138 + external/flint-2.4.3/fmpq_poly/log_series.c | 96 + external/flint-2.4.3/fmpq_poly/make_monic.c | 53 + external/flint-2.4.3/fmpq_poly/mul.c | 115 + external/flint-2.4.3/fmpq_poly/mullow.c | 82 + external/flint-2.4.3/fmpq_poly/neg.c | 46 + external/flint-2.4.3/fmpq_poly/normalise.c | 38 + external/flint-2.4.3/fmpq_poly/pow.c | 72 + external/flint-2.4.3/fmpq_poly/powers_clear.c | 46 + .../flint-2.4.3/fmpq_poly/powers_precompute.c | 83 + .../flint-2.4.3/fmpq_poly/primitive_part.c | 56 + external/flint-2.4.3/fmpq_poly/randtest.c | 126 + external/flint-2.4.3/fmpq_poly/realloc.c | 65 + external/flint-2.4.3/fmpq_poly/rem.c | 131 + .../fmpq_poly/rem_powers_precomp.c | 123 + external/flint-2.4.3/fmpq_poly/rescale.c | 92 + external/flint-2.4.3/fmpq_poly/resultant.c | 164 + external/flint-2.4.3/fmpq_poly/reverse.c | 49 + .../flint-2.4.3/fmpq_poly/revert_series.c | 99 + .../fmpq_poly/revert_series_lagrange.c | 180 + .../fmpq_poly/revert_series_lagrange_fast.c | 218 + .../fmpq_poly/revert_series_newton.c | 162 + .../flint-2.4.3/fmpq_poly/scalar_div_fmpq.c | 129 + .../flint-2.4.3/fmpq_poly/scalar_div_fmpz.c | 86 + .../flint-2.4.3/fmpq_poly/scalar_div_mpq.c | 41 + .../flint-2.4.3/fmpq_poly/scalar_div_mpz.c | 41 + .../flint-2.4.3/fmpq_poly/scalar_div_si.c | 99 + .../flint-2.4.3/fmpq_poly/scalar_div_ui.c | 81 + .../flint-2.4.3/fmpq_poly/scalar_mul_fmpq.c | 126 + .../flint-2.4.3/fmpq_poly/scalar_mul_fmpz.c | 80 + .../flint-2.4.3/fmpq_poly/scalar_mul_mpq.c | 40 + .../flint-2.4.3/fmpq_poly/scalar_mul_mpz.c | 41 + .../flint-2.4.3/fmpq_poly/scalar_mul_si.c | 86 + .../flint-2.4.3/fmpq_poly/scalar_mul_ui.c | 77 + external/flint-2.4.3/fmpq_poly/set.c | 46 + .../flint-2.4.3/fmpq_poly/set_array_mpq.c | 72 + .../flint-2.4.3/fmpq_poly/set_coeff_fmpq.c | 99 + .../flint-2.4.3/fmpq_poly/set_coeff_fmpz.c | 61 + .../flint-2.4.3/fmpq_poly/set_coeff_mpq.c | 43 + .../flint-2.4.3/fmpq_poly/set_coeff_mpz.c | 41 + external/flint-2.4.3/fmpq_poly/set_coeff_si.c | 62 + external/flint-2.4.3/fmpq_poly/set_coeff_ui.c | 62 + external/flint-2.4.3/fmpq_poly/set_fmpq.c | 39 + external/flint-2.4.3/fmpq_poly/set_fmpz.c | 39 + .../flint-2.4.3/fmpq_poly/set_fmpz_poly.c | 46 + external/flint-2.4.3/fmpq_poly/set_length.c | 39 + external/flint-2.4.3/fmpq_poly/set_mpq.c | 39 + external/flint-2.4.3/fmpq_poly/set_mpz.c | 39 + external/flint-2.4.3/fmpq_poly/set_si.c | 39 + external/flint-2.4.3/fmpq_poly/set_str.c | 137 + external/flint-2.4.3/fmpq_poly/set_ui.c | 39 + external/flint-2.4.3/fmpq_poly/shift_left.c | 52 + external/flint-2.4.3/fmpq_poly/shift_right.c | 53 + external/flint-2.4.3/fmpq_poly/sin_series.c | 103 + external/flint-2.4.3/fmpq_poly/sinh_series.c | 112 + external/flint-2.4.3/fmpq_poly/sqrt_series.c | 102 + external/flint-2.4.3/fmpq_poly/sub.c | 146 + external/flint-2.4.3/fmpq_poly/swap.c | 51 + external/flint-2.4.3/fmpq_poly/tan_series.c | 141 + external/flint-2.4.3/fmpq_poly/tanh_series.c | 101 + external/flint-2.4.3/fmpq_poly/test/t-add.c | 113 + .../fmpq_poly/test/t-asin_series.c | 128 + .../fmpq_poly/test/t-asinh_series.c | 127 + .../fmpq_poly/test/t-atan_series.c | 132 + .../fmpq_poly/test/t-atanh_series.c | 131 + external/flint-2.4.3/fmpq_poly/test/t-cmp.c | 126 + .../flint-2.4.3/fmpq_poly/test/t-compose.c | 161 + .../fmpq_poly/test/t-compose_series.c | 152 + .../test/t-compose_series_brent_kung.c | 152 + .../fmpq_poly/test/t-compose_series_horner.c | 152 + .../flint-2.4.3/fmpq_poly/test/t-content.c | 91 + .../flint-2.4.3/fmpq_poly/test/t-cos_series.c | 129 + .../fmpq_poly/test/t-cosh_series.c | 129 + .../flint-2.4.3/fmpq_poly/test/t-derivative.c | 146 + external/flint-2.4.3/fmpq_poly/test/t-div.c | 152 + .../flint-2.4.3/fmpq_poly/test/t-div_series.c | 161 + .../flint-2.4.3/fmpq_poly/test/t-divrem.c | 169 + .../fmpq_poly/test/t-evaluate_fmpq.c | 181 + .../fmpq_poly/test/t-evaluate_fmpz.c | 130 + .../fmpq_poly/test/t-evaluate_mpq.c | 181 + .../fmpq_poly/test/t-evaluate_mpz.c | 142 + .../flint-2.4.3/fmpq_poly/test/t-exp_series.c | 137 + external/flint-2.4.3/fmpq_poly/test/t-gcd.c | 270 + .../fmpq_poly/test/t-get_set_coeff_fmpq.c | 90 + .../fmpq_poly/test/t-get_set_coeff_fmpz.c | 98 + .../fmpq_poly/test/t-get_set_coeff_mpq.c | 102 + .../fmpq_poly/test/t-get_set_coeff_mpz.c | 97 + .../fmpq_poly/test/t-get_set_coeff_si.c | 91 + .../fmpq_poly/test/t-get_set_coeff_ui.c | 90 + .../fmpq_poly/test/t-get_set_str.c | 80 + .../flint-2.4.3/fmpq_poly/test/t-get_slice.c | 157 + .../fmpq_poly/test/t-init_realloc_clear.c | 75 + .../flint-2.4.3/fmpq_poly/test/t-integral.c | 109 + .../fmpq_poly/test/t-interpolate_fmpz_vec.c | 97 + external/flint-2.4.3/fmpq_poly/test/t-inv.c | 80 + .../fmpq_poly/test/t-inv_series_newton.c | 124 + .../fmpq_poly/test/t-invsqrt_series.c | 120 + .../fmpq_poly/test/t-is_squarefree.c | 135 + external/flint-2.4.3/fmpq_poly/test/t-lcm.c | 265 + .../flint-2.4.3/fmpq_poly/test/t-log_series.c | 137 + .../flint-2.4.3/fmpq_poly/test/t-make_monic.c | 101 + external/flint-2.4.3/fmpq_poly/test/t-mul.c | 152 + .../flint-2.4.3/fmpq_poly/test/t-mullow.c | 84 + external/flint-2.4.3/fmpq_poly/test/t-neg.c | 80 + external/flint-2.4.3/fmpq_poly/test/t-pow.c | 127 + .../fmpq_poly/test/t-primitive_part.c | 124 + .../flint-2.4.3/fmpq_poly/test/t-print_read.c | 270 + external/flint-2.4.3/fmpq_poly/test/t-rem.c | 152 + .../fmpq_poly/test/t-rem_powers_precomp.c | 162 + .../flint-2.4.3/fmpq_poly/test/t-rescale.c | 117 + .../flint-2.4.3/fmpq_poly/test/t-resultant.c | 188 + .../flint-2.4.3/fmpq_poly/test/t-reverse.c | 115 + .../fmpq_poly/test/t-revert_series.c | 121 + .../fmpq_poly/test/t-revert_series_lagrange.c | 121 + .../test/t-revert_series_lagrange_fast.c | 121 + .../fmpq_poly/test/t-revert_series_newton.c | 121 + .../fmpq_poly/test/t-scalar_div_fmpq.c | 176 + .../fmpq_poly/test/t-scalar_div_fmpz.c | 216 + .../fmpq_poly/test/t-scalar_div_mpq.c | 208 + .../fmpq_poly/test/t-scalar_div_mpz.c | 230 + .../fmpq_poly/test/t-scalar_div_si.c | 160 + .../fmpq_poly/test/t-scalar_div_ui.c | 118 + .../fmpq_poly/test/t-scalar_mul_fmpq.c | 179 + .../fmpq_poly/test/t-scalar_mul_fmpz.c | 160 + .../fmpq_poly/test/t-scalar_mul_mpq.c | 208 + .../fmpq_poly/test/t-scalar_mul_mpz.c | 168 + .../fmpq_poly/test/t-scalar_mul_si.c | 152 + .../fmpq_poly/test/t-scalar_mul_ui.c | 154 + .../fmpq_poly/test/t-set_array_mpq.c | 86 + .../flint-2.4.3/fmpq_poly/test/t-set_equal.c | 121 + .../fmpq_poly/test/t-shift_left_right.c | 142 + .../flint-2.4.3/fmpq_poly/test/t-sin_series.c | 120 + .../fmpq_poly/test/t-sinh_series.c | 120 + .../fmpq_poly/test/t-sqrt_series.c | 119 + external/flint-2.4.3/fmpq_poly/test/t-sub.c | 150 + external/flint-2.4.3/fmpq_poly/test/t-swap.c | 78 + .../flint-2.4.3/fmpq_poly/test/t-tan_series.c | 120 + .../fmpq_poly/test/t-tanh_series.c | 120 + external/flint-2.4.3/fmpq_poly/test/t-xgcd.c | 228 + external/flint-2.4.3/fmpq_poly/test/t-zero.c | 75 + external/flint-2.4.3/fmpq_poly/xgcd.c | 248 + external/flint-2.4.3/fmpq_poly/zero.c | 37 + external/flint-2.4.3/fmpq_polyxx.h | 568 + external/flint-2.4.3/fmpqxx.h | 471 + external/flint-2.4.3/fmpz-conversions-gc.in | 10 + .../flint-2.4.3/fmpz-conversions-reentrant.in | 10 + .../flint-2.4.3/fmpz-conversions-single.in | 10 + external/flint-2.4.3/fmpz-conversions.h | 10 + external/flint-2.4.3/fmpz.h | 678 + external/flint-2.4.3/fmpz/CRT_ui.c | 100 + external/flint-2.4.3/fmpz/abs.c | 48 + external/flint-2.4.3/fmpz/abs_fits_ui.c | 37 + .../flint-2.4.3/fmpz/abs_lbound_ui_2exp.c | 87 + .../flint-2.4.3/fmpz/abs_ubound_ui_2exp.c | 112 + external/flint-2.4.3/fmpz/add.c | 69 + external/flint-2.4.3/fmpz/add_ui.c | 58 + external/flint-2.4.3/fmpz/addmul.c | 58 + external/flint-2.4.3/fmpz/addmul_ui.c | 109 + external/flint-2.4.3/fmpz/and.c | 69 + external/flint-2.4.3/fmpz/bin_uiui.c | 39 + external/flint-2.4.3/fmpz/bit_pack.c | 185 + external/flint-2.4.3/fmpz/bit_unpack.c | 222 + external/flint-2.4.3/fmpz/bits.c | 37 + external/flint-2.4.3/fmpz/cdiv_q.c | 87 + external/flint-2.4.3/fmpz/cdiv_q_2exp.c | 46 + external/flint-2.4.3/fmpz/cdiv_q_si.c | 69 + external/flint-2.4.3/fmpz/cdiv_q_ui.c | 69 + external/flint-2.4.3/fmpz/clear_readonly.c | 41 + external/flint-2.4.3/fmpz/clog.c | 78 + external/flint-2.4.3/fmpz/clog_ui.c | 89 + external/flint-2.4.3/fmpz/clrbit.c | 46 + external/flint-2.4.3/fmpz/cmp.c | 61 + external/flint-2.4.3/fmpz/cmp_si.c | 41 + external/flint-2.4.3/fmpz/cmp_ui.c | 45 + external/flint-2.4.3/fmpz/cmpabs.c | 51 + external/flint-2.4.3/fmpz/comb_clear.c | 79 + external/flint-2.4.3/fmpz/comb_init.c | 157 + external/flint-2.4.3/fmpz/combit.c | 50 + external/flint-2.4.3/fmpz/complement.c | 55 + external/flint-2.4.3/fmpz/divexact.c | 74 + external/flint-2.4.3/fmpz/divexact_si.c | 64 + external/flint-2.4.3/fmpz/divexact_ui.c | 55 + external/flint-2.4.3/fmpz/divisible.c | 64 + external/flint-2.4.3/fmpz/divisible_si.c | 49 + external/flint-2.4.3/fmpz/dlog.c | 52 + external/flint-2.4.3/fmpz/doc/fmpz.txt | 1155 + external/flint-2.4.3/fmpz/doc/reentrant.txt | 110 + external/flint-2.4.3/fmpz/doc/single.txt | 117 + external/flint-2.4.3/fmpz/equal.c | 38 + external/flint-2.4.3/fmpz/equal_si.c | 35 + external/flint-2.4.3/fmpz/equal_ui.c | 36 + external/flint-2.4.3/fmpz/fac_ui.c | 56 + external/flint-2.4.3/fmpz/fdiv_q.c | 87 + external/flint-2.4.3/fmpz/fdiv_q_2exp.c | 45 + external/flint-2.4.3/fmpz/fdiv_q_si.c | 70 + external/flint-2.4.3/fmpz/fdiv_q_ui.c | 69 + external/flint-2.4.3/fmpz/fdiv_qr.c | 107 + external/flint-2.4.3/fmpz/fdiv_qr_preinvn.c | 226 + external/flint-2.4.3/fmpz/fdiv_r.c | 95 + external/flint-2.4.3/fmpz/fdiv_r_2exp.c | 65 + external/flint-2.4.3/fmpz/fdiv_ui.c | 62 + external/flint-2.4.3/fmpz/fib_ui.c | 70 + external/flint-2.4.3/fmpz/fits_si.c | 92 + external/flint-2.4.3/fmpz/flog.c | 80 + external/flint-2.4.3/fmpz/flog_ui.c | 85 + external/flint-2.4.3/fmpz/fmpz.c | 159 + external/flint-2.4.3/fmpz/fprint.c | 38 + external/flint-2.4.3/fmpz/fread.c | 45 + external/flint-2.4.3/fmpz/gcd.c | 85 + external/flint-2.4.3/fmpz/gcdinv.c | 74 + external/flint-2.4.3/fmpz/get_d.c | 67 + external/flint-2.4.3/fmpz/get_d_2exp.c | 60 + external/flint-2.4.3/fmpz/get_mpz.c | 38 + external/flint-2.4.3/fmpz/get_si.c | 35 + external/flint-2.4.3/fmpz/get_str.c | 48 + external/flint-2.4.3/fmpz/get_ui.c | 38 + external/flint-2.4.3/fmpz/init2.c | 44 + external/flint-2.4.3/fmpz/init_set_readonly.c | 49 + external/flint-2.4.3/fmpz/inlines.c | 73 + external/flint-2.4.3/fmpz/inp_raw.c | 41 + external/flint-2.4.3/fmpz/invmod.c | 127 + .../flint-2.4.3/fmpz/is_prime_pseudosquare.c | 357 + external/flint-2.4.3/fmpz/is_probabprime.c | 48 + external/flint-2.4.3/fmpz/is_square.c | 45 + external/flint-2.4.3/fmpz/jacobi.c | 60 + external/flint-2.4.3/fmpz/lcm.c | 59 + external/flint-2.4.3/fmpz/link/fmpz_gc.c | 212 + .../flint-2.4.3/fmpz/link/fmpz_reentrant.c | 111 + external/flint-2.4.3/fmpz/link/fmpz_single.c | 159 + external/flint-2.4.3/fmpz/mod.c | 82 + external/flint-2.4.3/fmpz/mod_ui.c | 39 + .../flint-2.4.3/fmpz/mpz_clear_readonly.c | 34 + .../flint-2.4.3/fmpz/mpz_init_set_readonly.c | 41 + external/flint-2.4.3/fmpz/mul.c | 59 + external/flint-2.4.3/fmpz/mul_2exp.c | 60 + external/flint-2.4.3/fmpz/mul_si.c | 59 + .../flint-2.4.3/fmpz/mul_si_tdiv_q_2exp.c | 99 + external/flint-2.4.3/fmpz/mul_tdiv_q_2exp.c | 63 + external/flint-2.4.3/fmpz/mul_ui.c | 59 + external/flint-2.4.3/fmpz/multi_CRT_ui.c | 152 + external/flint-2.4.3/fmpz/multi_mod_ui.c | 116 + external/flint-2.4.3/fmpz/or.c | 68 + external/flint-2.4.3/fmpz/out_raw.c | 42 + external/flint-2.4.3/fmpz/popcnt.c | 42 + external/flint-2.4.3/fmpz/pow_ui.c | 70 + external/flint-2.4.3/fmpz/powm.c | 87 + external/flint-2.4.3/fmpz/powm_ui.c | 111 + external/flint-2.4.3/fmpz/preinvn_clear.c | 34 + external/flint-2.4.3/fmpz/preinvn_init.c | 70 + external/flint-2.4.3/fmpz/print.c | 38 + .../fmpz/profile/p-fdiv_qr_preinvn.c | 126 + external/flint-2.4.3/fmpz/randbits.c | 55 + external/flint-2.4.3/fmpz/randm.c | 55 + external/flint-2.4.3/fmpz/randtest.c | 93 + external/flint-2.4.3/fmpz/randtest_mod.c | 73 + external/flint-2.4.3/fmpz/read.c | 44 + external/flint-2.4.3/fmpz/remove.c | 144 + external/flint-2.4.3/fmpz/rfac_ui.c | 134 + external/flint-2.4.3/fmpz/rfac_uiui.c | 59 + external/flint-2.4.3/fmpz/root.c | 97 + external/flint-2.4.3/fmpz/set.c | 47 + external/flint-2.4.3/fmpz/set_d.c | 54 + external/flint-2.4.3/fmpz/set_mpz.c | 64 + external/flint-2.4.3/fmpz/set_str.c | 42 + external/flint-2.4.3/fmpz/setbit.c | 53 + external/flint-2.4.3/fmpz/sgn.c | 42 + external/flint-2.4.3/fmpz/size.c | 42 + external/flint-2.4.3/fmpz/sizeinbase.c | 40 + external/flint-2.4.3/fmpz/sqrt.c | 49 + external/flint-2.4.3/fmpz/sqrtmod.c | 173 + external/flint-2.4.3/fmpz/sqrtrem.c | 58 + external/flint-2.4.3/fmpz/sub.c | 78 + external/flint-2.4.3/fmpz/sub_ui.c | 60 + external/flint-2.4.3/fmpz/submul.c | 59 + external/flint-2.4.3/fmpz/submul_ui.c | 97 + external/flint-2.4.3/fmpz/tdiv_q.c | 73 + external/flint-2.4.3/fmpz/tdiv_q_2exp.c | 51 + external/flint-2.4.3/fmpz/tdiv_q_si.c | 64 + external/flint-2.4.3/fmpz/tdiv_q_ui.c | 66 + external/flint-2.4.3/fmpz/tdiv_qr.c | 88 + external/flint-2.4.3/fmpz/tdiv_ui.c | 56 + external/flint-2.4.3/fmpz/test/t-abs.c | 113 + .../flint-2.4.3/fmpz/test/t-abs_fits_ui.c | 91 + .../fmpz/test/t-abs_lbound_ui_2exp.c | 102 + .../fmpz/test/t-abs_ubound_ui_2exp.c | 139 + external/flint-2.4.3/fmpz/test/t-add.c | 217 + external/flint-2.4.3/fmpz/test/t-add_ui.c | 127 + external/flint-2.4.3/fmpz/test/t-addmul.c | 217 + external/flint-2.4.3/fmpz/test/t-addmul_ui.c | 127 + external/flint-2.4.3/fmpz/test/t-and.c | 217 + external/flint-2.4.3/fmpz/test/t-bin_uiui.c | 76 + external/flint-2.4.3/fmpz/test/t-bit_pack.c | 115 + external/flint-2.4.3/fmpz/test/t-bits.c | 76 + external/flint-2.4.3/fmpz/test/t-cdiv_q.c | 217 + .../flint-2.4.3/fmpz/test/t-cdiv_q_2exp.c | 125 + external/flint-2.4.3/fmpz/test/t-cdiv_q_si.c | 131 + external/flint-2.4.3/fmpz/test/t-cdiv_q_ui.c | 131 + external/flint-2.4.3/fmpz/test/t-clog.c | 147 + external/flint-2.4.3/fmpz/test/t-clog_ui.c | 122 + external/flint-2.4.3/fmpz/test/t-cmp.c | 109 + external/flint-2.4.3/fmpz/test/t-cmp_si.c | 83 + external/flint-2.4.3/fmpz/test/t-cmp_ui.c | 82 + external/flint-2.4.3/fmpz/test/t-cmpabs.c | 109 + .../flint-2.4.3/fmpz/test/t-comb_init_clear.c | 71 + external/flint-2.4.3/fmpz/test/t-combit.c | 83 + external/flint-2.4.3/fmpz/test/t-complement.c | 117 + external/flint-2.4.3/fmpz/test/t-crt_ui.c | 117 + external/flint-2.4.3/fmpz/test/t-divexact.c | 220 + .../flint-2.4.3/fmpz/test/t-divexact2_uiui.c | 138 + .../flint-2.4.3/fmpz/test/t-divexact_si.c | 131 + .../flint-2.4.3/fmpz/test/t-divexact_ui.c | 126 + external/flint-2.4.3/fmpz/test/t-divisible.c | 146 + .../flint-2.4.3/fmpz/test/t-divisible_si.c | 120 + external/flint-2.4.3/fmpz/test/t-dlog.c | 89 + external/flint-2.4.3/fmpz/test/t-equal.c | 103 + external/flint-2.4.3/fmpz/test/t-equal_si.c | 116 + external/flint-2.4.3/fmpz/test/t-equal_ui.c | 115 + external/flint-2.4.3/fmpz/test/t-fac_ui.c | 76 + external/flint-2.4.3/fmpz/test/t-fdiv_q.c | 213 + .../flint-2.4.3/fmpz/test/t-fdiv_q_2exp.c | 125 + external/flint-2.4.3/fmpz/test/t-fdiv_q_si.c | 131 + external/flint-2.4.3/fmpz/test/t-fdiv_q_ui.c | 131 + external/flint-2.4.3/fmpz/test/t-fdiv_qr.c | 317 + .../flint-2.4.3/fmpz/test/t-fdiv_qr_preinvn.c | 327 + external/flint-2.4.3/fmpz/test/t-fdiv_r.c | 213 + .../flint-2.4.3/fmpz/test/t-fdiv_r_2exp.c | 127 + external/flint-2.4.3/fmpz/test/t-fdiv_ui.c | 78 + external/flint-2.4.3/fmpz/test/t-fib_ui.c | 82 + external/flint-2.4.3/fmpz/test/t-fits_si.c | 101 + external/flint-2.4.3/fmpz/test/t-flog.c | 144 + external/flint-2.4.3/fmpz/test/t-flog_ui.c | 119 + external/flint-2.4.3/fmpz/test/t-fmpz.c | 70 + .../flint-2.4.3/fmpz/test/t-fmpz_cleanup.c | 79 + external/flint-2.4.3/fmpz/test/t-gcd.c | 226 + external/flint-2.4.3/fmpz/test/t-gcdinv.c | 218 + external/flint-2.4.3/fmpz/test/t-get_d.c | 97 + external/flint-2.4.3/fmpz/test/t-get_d_2exp.c | 74 + external/flint-2.4.3/fmpz/test/t-get_mpz.c | 84 + external/flint-2.4.3/fmpz/test/t-get_si.c | 107 + external/flint-2.4.3/fmpz/test/t-get_str.c | 90 + external/flint-2.4.3/fmpz/test/t-get_ui.c | 71 + external/flint-2.4.3/fmpz/test/t-init2.c | 69 + external/flint-2.4.3/fmpz/test/t-init_set.c | 92 + .../fmpz/test/t-init_set_readonly.c | 122 + .../flint-2.4.3/fmpz/test/t-init_set_ui.c | 71 + external/flint-2.4.3/fmpz/test/t-invmod.c | 220 + external/flint-2.4.3/fmpz/test/t-is_even.c | 96 + .../fmpz/test/t-is_prime_pseudosquare.c | 72 + external/flint-2.4.3/fmpz/test/t-is_square.c | 80 + external/flint-2.4.3/fmpz/test/t-jacobi.c | 93 + external/flint-2.4.3/fmpz/test/t-lcm.c | 227 + external/flint-2.4.3/fmpz/test/t-mod.c | 214 + external/flint-2.4.3/fmpz/test/t-mod_ui.c | 129 + .../fmpz/test/t-mpz_init_set_readonly.c | 102 + external/flint-2.4.3/fmpz/test/t-mul.c | 213 + external/flint-2.4.3/fmpz/test/t-mul2_uiui.c | 132 + external/flint-2.4.3/fmpz/test/t-mul_2exp.c | 126 + external/flint-2.4.3/fmpz/test/t-mul_si.c | 125 + .../fmpz/test/t-mul_si_tdiv_q_2exp.c | 134 + .../flint-2.4.3/fmpz/test/t-mul_tdiv_q_2exp.c | 226 + external/flint-2.4.3/fmpz/test/t-mul_ui.c | 125 + .../flint-2.4.3/fmpz/test/t-multi_CRT_ui.c | 134 + .../fmpz/test/t-multi_CRT_ui_unsigned.c | 132 + external/flint-2.4.3/fmpz/test/t-neg.c | 117 + external/flint-2.4.3/fmpz/test/t-neg_ui.c | 77 + external/flint-2.4.3/fmpz/test/t-neg_uiui.c | 81 + external/flint-2.4.3/fmpz/test/t-or.c | 217 + .../flint-2.4.3/fmpz/test/t-out_inp_raw.c | 179 + external/flint-2.4.3/fmpz/test/t-popcnt.c | 79 + external/flint-2.4.3/fmpz/test/t-pow_ui.c | 125 + external/flint-2.4.3/fmpz/test/t-powm.c | 207 + external/flint-2.4.3/fmpz/test/t-powm_ui.c | 194 + external/flint-2.4.3/fmpz/test/t-print_read.c | 265 + external/flint-2.4.3/fmpz/test/t-remove.c | 254 + external/flint-2.4.3/fmpz/test/t-rfac_ui.c | 123 + external/flint-2.4.3/fmpz/test/t-rfac_uiui.c | 94 + external/flint-2.4.3/fmpz/test/t-root.c | 130 + external/flint-2.4.3/fmpz/test/t-set.c | 87 + .../flint-2.4.3/fmpz/test/t-set_ui_smod.c | 81 + external/flint-2.4.3/fmpz/test/t-set_uiui.c | 80 + external/flint-2.4.3/fmpz/test/t-setbit.c | 88 + external/flint-2.4.3/fmpz/test/t-sgn.c | 78 + external/flint-2.4.3/fmpz/test/t-size.c | 78 + external/flint-2.4.3/fmpz/test/t-sizeinbase.c | 81 + external/flint-2.4.3/fmpz/test/t-sqrt.c | 122 + external/flint-2.4.3/fmpz/test/t-sqrtmod.c | 141 + external/flint-2.4.3/fmpz/test/t-sqrtrem.c | 168 + external/flint-2.4.3/fmpz/test/t-sub.c | 213 + external/flint-2.4.3/fmpz/test/t-sub_ui.c | 125 + external/flint-2.4.3/fmpz/test/t-submul.c | 214 + external/flint-2.4.3/fmpz/test/t-submul_ui.c | 125 + external/flint-2.4.3/fmpz/test/t-swap.c | 83 + external/flint-2.4.3/fmpz/test/t-tdiv_q.c | 214 + .../flint-2.4.3/fmpz/test/t-tdiv_q_2exp.c | 125 + external/flint-2.4.3/fmpz/test/t-tdiv_q_si.c | 131 + external/flint-2.4.3/fmpz/test/t-tdiv_q_ui.c | 131 + external/flint-2.4.3/fmpz/test/t-tdiv_qr.c | 312 + external/flint-2.4.3/fmpz/test/t-tdiv_ui.c | 78 + external/flint-2.4.3/fmpz/test/t-tstbit.c | 79 + external/flint-2.4.3/fmpz/test/t-val2.c | 85 + external/flint-2.4.3/fmpz/test/t-xgcd.c | 305 + .../flint-2.4.3/fmpz/test/t-xgcd_partial.c | 99 + external/flint-2.4.3/fmpz/test/t-xor.c | 217 + external/flint-2.4.3/fmpz/tstbit.c | 46 + external/flint-2.4.3/fmpz/val2.c | 60 + external/flint-2.4.3/fmpz/xgcd.c | 91 + external/flint-2.4.3/fmpz/xgcd_partial.c | 126 + external/flint-2.4.3/fmpz/xor.c | 70 + external/flint-2.4.3/fmpz_factor.h | 88 + external/flint-2.4.3/fmpz_factor/append_ui.c | 39 + external/flint-2.4.3/fmpz_factor/clear.c | 37 + .../fmpz_factor/doc/fmpz_factor.txt | 96 + external/flint-2.4.3/fmpz_factor/expand.c | 34 + .../fmpz_factor/expand_iterative.c | 45 + .../flint-2.4.3/fmpz_factor/expand_multiexp.c | 91 + .../fmpz_factor/extend_factor_ui.c | 59 + external/flint-2.4.3/fmpz_factor/factor.c | 139 + external/flint-2.4.3/fmpz_factor/factor_pp1.c | 602 + external/flint-2.4.3/fmpz_factor/factor_si.c | 48 + .../fmpz_factor/factor_trial_range.c | 133 + external/flint-2.4.3/fmpz_factor/fit_length.c | 51 + external/flint-2.4.3/fmpz_factor/init.c | 40 + external/flint-2.4.3/fmpz_factor/print.c | 62 + .../fmpz_factor/profile/p-factor_pp1.c | 81 + external/flint-2.4.3/fmpz_factor/set_length.c | 42 + .../flint-2.4.3/fmpz_factor/test/t-factor.c | 176 + .../fmpz_factor/test/t-factor_pp1.c | 112 + external/flint-2.4.3/fmpz_factorxx.h | 189 + external/flint-2.4.3/fmpz_mat.h | 316 + external/flint-2.4.3/fmpz_mat/CRT_ui.c | 59 + external/flint-2.4.3/fmpz_mat/add.c | 38 + external/flint-2.4.3/fmpz_mat/charpoly.c | 124 + external/flint-2.4.3/fmpz_mat/clear.c | 39 + external/flint-2.4.3/fmpz_mat/det.c | 54 + external/flint-2.4.3/fmpz_mat/det_bareiss.c | 57 + external/flint-2.4.3/fmpz_mat/det_bound.c | 57 + external/flint-2.4.3/fmpz_mat/det_cofactor.c | 136 + external/flint-2.4.3/fmpz_mat/det_divisor.c | 82 + external/flint-2.4.3/fmpz_mat/det_modular.c | 36 + .../fmpz_mat/det_modular_accelerated.c | 36 + .../fmpz_mat/det_modular_given_divisor.c | 127 + .../flint-2.4.3/fmpz_mat/doc/fmpz_mat.txt | 860 + external/flint-2.4.3/fmpz_mat/equal.c | 49 + external/flint-2.4.3/fmpz_mat/fflu.c | 92 + .../flint-2.4.3/fmpz_mat/find_pivot_any.c | 41 + external/flint-2.4.3/fmpz_mat/fprint.c | 111 + external/flint-2.4.3/fmpz_mat/fread.c | 95 + external/flint-2.4.3/fmpz_mat/get_nmod_mat.c | 37 + external/flint-2.4.3/fmpz_mat/init.c | 45 + external/flint-2.4.3/fmpz_mat/init_set.c | 34 + external/flint-2.4.3/fmpz_mat/inv.c | 79 + external/flint-2.4.3/fmpz_mat/is_zero.c | 43 + external/flint-2.4.3/fmpz_mat/max_bits.c | 52 + external/flint-2.4.3/fmpz_mat/mul.c | 78 + external/flint-2.4.3/fmpz_mat/mul_classical.c | 60 + .../fmpz_mat/mul_classical_inline.c | 131 + external/flint-2.4.3/fmpz_mat/mul_multi_mod.c | 140 + external/flint-2.4.3/fmpz_mat/multi_CRT_ui.c | 72 + external/flint-2.4.3/fmpz_mat/multi_mod_ui.c | 69 + external/flint-2.4.3/fmpz_mat/neg.c | 38 + external/flint-2.4.3/fmpz_mat/nullspace.c | 91 + external/flint-2.4.3/fmpz_mat/one.c | 38 + external/flint-2.4.3/fmpz_mat/pow.c | 75 + external/flint-2.4.3/fmpz_mat/profile/p-det.c | 116 + external/flint-2.4.3/fmpz_mat/profile/p-mul.c | 133 + external/flint-2.4.3/fmpz_mat/randajtai.c | 68 + external/flint-2.4.3/fmpz_mat/randbits.c | 39 + external/flint-2.4.3/fmpz_mat/randdet.c | 101 + external/flint-2.4.3/fmpz_mat/randintrel.c | 52 + external/flint-2.4.3/fmpz_mat/randntrulike.c | 83 + external/flint-2.4.3/fmpz_mat/randntrulike2.c | 83 + external/flint-2.4.3/fmpz_mat/randops.c | 67 + external/flint-2.4.3/fmpz_mat/randpermdiag.c | 52 + external/flint-2.4.3/fmpz_mat/randrank.c | 48 + external/flint-2.4.3/fmpz_mat/randsimdioph.c | 56 + external/flint-2.4.3/fmpz_mat/randtest.c | 39 + .../flint-2.4.3/fmpz_mat/randtest_unsigned.c | 39 + external/flint-2.4.3/fmpz_mat/rank.c | 47 + external/flint-2.4.3/fmpz_mat/rref.c | 105 + external/flint-2.4.3/fmpz_mat/rref_mod.c | 98 + .../flint-2.4.3/fmpz_mat/scalar_addmul_fmpz.c | 36 + .../fmpz_mat/scalar_addmul_nmod_mat_fmpz.c | 37 + .../fmpz_mat/scalar_addmul_nmod_mat_ui.c | 37 + .../flint-2.4.3/fmpz_mat/scalar_addmul_si.c | 35 + .../flint-2.4.3/fmpz_mat/scalar_addmul_ui.c | 36 + .../fmpz_mat/scalar_divexact_fmpz.c | 36 + .../flint-2.4.3/fmpz_mat/scalar_divexact_si.c | 36 + .../flint-2.4.3/fmpz_mat/scalar_divexact_ui.c | 36 + .../flint-2.4.3/fmpz_mat/scalar_mod_fmpz.c | 40 + .../flint-2.4.3/fmpz_mat/scalar_mul_fmpz.c | 36 + external/flint-2.4.3/fmpz_mat/scalar_mul_si.c | 36 + external/flint-2.4.3/fmpz_mat/scalar_mul_ui.c | 36 + .../flint-2.4.3/fmpz_mat/scalar_submul_fmpz.c | 36 + .../flint-2.4.3/fmpz_mat/scalar_submul_si.c | 35 + .../flint-2.4.3/fmpz_mat/scalar_submul_ui.c | 36 + external/flint-2.4.3/fmpz_mat/set.c | 40 + external/flint-2.4.3/fmpz_mat/set_nmod_mat.c | 37 + .../fmpz_mat/set_nmod_mat_unsigned.c | 36 + external/flint-2.4.3/fmpz_mat/solve.c | 37 + external/flint-2.4.3/fmpz_mat/solve_bound.c | 63 + external/flint-2.4.3/fmpz_mat/solve_cramer.c | 172 + external/flint-2.4.3/fmpz_mat/solve_dixon.c | 251 + external/flint-2.4.3/fmpz_mat/solve_fflu.c | 56 + .../flint-2.4.3/fmpz_mat/solve_fflu_precomp.c | 97 + external/flint-2.4.3/fmpz_mat/sqr.c | 69 + external/flint-2.4.3/fmpz_mat/sub.c | 38 + external/flint-2.4.3/fmpz_mat/swap.c | 39 + external/flint-2.4.3/fmpz_mat/test/t-CRT_ui.c | 119 + .../fmpz_mat/test/t-CRT_ui_unsigned.c | 118 + .../flint-2.4.3/fmpz_mat/test/t-add_sub.c | 81 + .../flint-2.4.3/fmpz_mat/test/t-charpoly.c | 92 + external/flint-2.4.3/fmpz_mat/test/t-det.c | 110 + .../flint-2.4.3/fmpz_mat/test/t-det_bound.c | 82 + .../flint-2.4.3/fmpz_mat/test/t-det_divisor.c | 106 + .../flint-2.4.3/fmpz_mat/test/t-det_modular.c | 107 + .../fmpz_mat/test/t-det_modular_accelerated.c | 107 + external/flint-2.4.3/fmpz_mat/test/t-entry.c | 82 + external/flint-2.4.3/fmpz_mat/test/t-equal.c | 97 + .../fmpz_mat/test/t-get_nmod_mat.c | 87 + .../flint-2.4.3/fmpz_mat/test/t-init_clear.c | 65 + external/flint-2.4.3/fmpz_mat/test/t-inv.c | 148 + .../flint-2.4.3/fmpz_mat/test/t-is_empty.c | 65 + .../flint-2.4.3/fmpz_mat/test/t-is_square.c | 65 + .../flint-2.4.3/fmpz_mat/test/t-is_zero.c | 76 + .../flint-2.4.3/fmpz_mat/test/t-max_bits.c | 72 + external/flint-2.4.3/fmpz_mat/test/t-mul.c | 92 + .../fmpz_mat/test/t-mul_classical.c | 84 + .../fmpz_mat/test/t-mul_multi_mod.c | 84 + .../fmpz_mat/test/t-multi_CRT_ui.c | 112 + .../fmpz_mat/test/t-multi_CRT_ui_unsigned.c | 111 + .../flint-2.4.3/fmpz_mat/test/t-nullspace.c | 108 + external/flint-2.4.3/fmpz_mat/test/t-one.c | 76 + external/flint-2.4.3/fmpz_mat/test/t-pow.c | 93 + .../flint-2.4.3/fmpz_mat/test/t-print_read.c | 269 + external/flint-2.4.3/fmpz_mat/test/t-rank.c | 96 + external/flint-2.4.3/fmpz_mat/test/t-rref.c | 192 + .../flint-2.4.3/fmpz_mat/test/t-rref_mod.c | 172 + .../fmpz_mat/test/t-scalar_addmul_fmpz.c | 85 + .../test/t-scalar_addmul_nmod_mat_fmpz.c | 91 + .../test/t-scalar_addmul_nmod_mat_ui.c | 90 + .../fmpz_mat/test/t-scalar_addmul_si.c | 84 + .../fmpz_mat/test/t-scalar_addmul_ui.c | 84 + .../fmpz_mat/test/t-scalar_mod_fmpz.c | 84 + .../fmpz_mat/test/t-scalar_mul_fmpz.c | 95 + .../fmpz_mat/test/t-scalar_mul_si.c | 93 + .../fmpz_mat/test/t-scalar_mul_ui.c | 92 + external/flint-2.4.3/fmpz_mat/test/t-solve.c | 131 + .../flint-2.4.3/fmpz_mat/test/t-solve_bound.c | 123 + .../fmpz_mat/test/t-solve_cramer.c | 131 + .../flint-2.4.3/fmpz_mat/test/t-solve_dixon.c | 134 + external/flint-2.4.3/fmpz_mat/test/t-sqr.c | 88 + external/flint-2.4.3/fmpz_mat/test/t-trace.c | 97 + .../flint-2.4.3/fmpz_mat/test/t-transpose.c | 103 + external/flint-2.4.3/fmpz_mat/test/t-zero.c | 76 + external/flint-2.4.3/fmpz_mat/trace.c | 41 + external/flint-2.4.3/fmpz_mat/transpose.c | 56 + external/flint-2.4.3/fmpz_mat/zero.c | 38 + external/flint-2.4.3/fmpz_matxx.h | 534 + external/flint-2.4.3/fmpz_mod_poly.h | 832 + external/flint-2.4.3/fmpz_mod_poly/add.c | 60 + external/flint-2.4.3/fmpz_mod_poly/clear.c | 42 + .../fmpz_mod_poly/compose_divconquer.c | 160 + .../fmpz_mod_poly/compose_horner.c | 108 + .../flint-2.4.3/fmpz_mod_poly/compose_mod.c | 108 + .../fmpz_mod_poly/compose_mod_brent_kung.c | 181 + .../compose_mod_brent_kung_precomp_preinv.c | 255 + .../compose_mod_brent_kung_preinv.c | 183 + .../fmpz_mod_poly/compose_mod_horner.c | 141 + .../flint-2.4.3/fmpz_mod_poly/derivative.c | 70 + .../flint-2.4.3/fmpz_mod_poly/div_basecase.c | 114 + .../fmpz_mod_poly/div_newton_n_preinv.c | 111 + .../fmpz_mod_poly/divrem_basecase.c | 121 + .../fmpz_mod_poly/divrem_divconquer.c | 196 + .../divrem_divconquer_recursive.c | 140 + external/flint-2.4.3/fmpz_mod_poly/divrem_f.c | 120 + .../fmpz_mod_poly/divrem_newton_n_preinv.c | 134 + .../fmpz_mod_poly/doc/fmpz_mod_poly.txt | 1612 + .../flint-2.4.3/fmpz_mod_poly/evaluate_fmpz.c | 80 + .../fmpz_mod_poly/evaluate_fmpz_vec.c | 50 + .../fmpz_mod_poly/evaluate_fmpz_vec_fast.c | 151 + .../fmpz_mod_poly/evaluate_fmpz_vec_iter.c | 49 + .../flint-2.4.3/fmpz_mod_poly/fit_length.c | 42 + external/flint-2.4.3/fmpz_mod_poly/fprint.c | 70 + external/flint-2.4.3/fmpz_mod_poly/fread.c | 69 + .../flint-2.4.3/fmpz_mod_poly/gcd_euclidean.c | 151 + .../fmpz_mod_poly/gcd_euclidean_f.c | 176 + external/flint-2.4.3/fmpz_mod_poly/gcdinv.c | 133 + .../flint-2.4.3/fmpz_mod_poly/get_fmpz_poly.c | 38 + external/flint-2.4.3/fmpz_mod_poly/init.c | 53 + .../fmpz_mod_poly/inv_series_newton.c | 134 + external/flint-2.4.3/fmpz_mod_poly/invmod.c | 108 + .../flint-2.4.3/fmpz_mod_poly/make_monic.c | 52 + external/flint-2.4.3/fmpz_mod_poly/mul.c | 84 + external/flint-2.4.3/fmpz_mod_poly/mullow.c | 87 + external/flint-2.4.3/fmpz_mod_poly/mulmod.c | 110 + .../flint-2.4.3/fmpz_mod_poly/mulmod_preinv.c | 121 + external/flint-2.4.3/fmpz_mod_poly/neg.c | 54 + .../flint-2.4.3/fmpz_mod_poly/normalise.c | 39 + external/flint-2.4.3/fmpz_mod_poly/pow.c | 162 + .../flint-2.4.3/fmpz_mod_poly/pow_trunc.c | 105 + .../fmpz_mod_poly/pow_trunc_binexp.c | 174 + .../fmpz_mod_poly/powmod_fmpz_binexp.c | 172 + .../fmpz_mod_poly/powmod_fmpz_binexp_preinv.c | 182 + .../fmpz_mod_poly/powmod_ui_binexp.c | 161 + .../fmpz_mod_poly/powmod_ui_binexp_preinv.c | 170 + .../fmpz_mod_poly/powmod_x_fmpz_preinv.c | 208 + .../fmpz_mod_poly/profile/p-invert.c | 93 + .../flint-2.4.3/fmpz_mod_poly/profile/p-mul.c | 85 + .../fmpz_mod_poly/profile/p-tree.c | 86 + external/flint-2.4.3/fmpz_mod_poly/radix.c | 235 + external/flint-2.4.3/fmpz_mod_poly/randtest.c | 198 + external/flint-2.4.3/fmpz_mod_poly/realloc.c | 57 + .../flint-2.4.3/fmpz_mod_poly/rem_basecase.c | 98 + external/flint-2.4.3/fmpz_mod_poly/remove.c | 55 + external/flint-2.4.3/fmpz_mod_poly/reverse.c | 76 + .../fmpz_mod_poly/scalar_mul_fmpz.c | 49 + external/flint-2.4.3/fmpz_mod_poly/set.c | 45 + .../fmpz_mod_poly/set_coeff_fmpz.c | 47 + .../flint-2.4.3/fmpz_mod_poly/set_coeff_ui.c | 47 + external/flint-2.4.3/fmpz_mod_poly/set_fmpz.c | 38 + .../flint-2.4.3/fmpz_mod_poly/set_fmpz_poly.c | 45 + .../flint-2.4.3/fmpz_mod_poly/shift_left.c | 72 + .../flint-2.4.3/fmpz_mod_poly/shift_right.c | 69 + external/flint-2.4.3/fmpz_mod_poly/sqr.c | 71 + external/flint-2.4.3/fmpz_mod_poly/sub.c | 60 + external/flint-2.4.3/fmpz_mod_poly/swap.c | 52 + .../flint-2.4.3/fmpz_mod_poly/test/t-add.c | 121 + .../fmpz_mod_poly/test/t-compose_divconquer.c | 170 + .../fmpz_mod_poly/test/t-compose_horner.c | 170 + .../fmpz_mod_poly/test/t-compose_mod.c | 202 + .../test/t-compose_mod_brent_kung.c | 206 + .../t-compose_mod_brent_kung_precomp_preinv.c | 253 + .../test/t-compose_mod_brent_kung_preinv.c | 281 + .../fmpz_mod_poly/test/t-compose_mod_horner.c | 202 + .../fmpz_mod_poly/test/t-derivative.c | 163 + .../fmpz_mod_poly/test/t-div_basecase.c | 206 + .../test/t-div_newton_n_preinv.c | 297 + .../fmpz_mod_poly/test/t-divrem_basecase.c | 213 + .../fmpz_mod_poly/test/t-divrem_divconquer.c | 213 + .../fmpz_mod_poly/test/t-divrem_f.c | 176 + .../test/t-divrem_newton_n_preinv.c | 521 + .../fmpz_mod_poly/test/t-evaluate_fmpz.c | 130 + .../test/t-evaluate_fmpz_vec_fast.c | 106 + .../fmpz_mod_poly/test/t-gcd_euclidean.c | 335 + .../fmpz_mod_poly/test/t-gcd_euclidean_f.c | 100 + .../flint-2.4.3/fmpz_mod_poly/test/t-gcdinv.c | 160 + .../fmpz_mod_poly/test/t-get_set_fmpz_poly.c | 84 + .../fmpz_mod_poly/test/t-init_realloc_clear.c | 95 + .../fmpz_mod_poly/test/t-inv_series_newton.c | 104 + .../flint-2.4.3/fmpz_mod_poly/test/t-invmod.c | 231 + .../flint-2.4.3/fmpz_mod_poly/test/t-mul.c | 161 + .../flint-2.4.3/fmpz_mod_poly/test/t-mullow.c | 88 + .../flint-2.4.3/fmpz_mod_poly/test/t-mulmod.c | 213 + .../fmpz_mod_poly/test/t-mulmod_preinv.c | 305 + .../flint-2.4.3/fmpz_mod_poly/test/t-neg.c | 83 + .../fmpz_mod_poly/test/t-pow_trunc.c | 131 + .../fmpz_mod_poly/test/t-pow_trunc_binexp.c | 131 + .../fmpz_mod_poly/test/t-powmod_fmpz_binexp.c | 238 + .../test/t-powmod_fmpz_binexp_preinv.c | 308 + .../fmpz_mod_poly/test/t-powmod_ui_binexp.c | 232 + .../test/t-powmod_ui_binexp_preinv.c | 294 + .../test/t-powmod_x_fmpz_preinv.c | 256 + .../fmpz_mod_poly/test/t-print_read.c | 265 + .../flint-2.4.3/fmpz_mod_poly/test/t-radix.c | 148 + .../fmpz_mod_poly/test/t-rem_basecase.c | 206 + .../fmpz_mod_poly/test/t-scalar_mul_fmpz.c | 86 + .../fmpz_mod_poly/test/t-set_equal.c | 120 + .../fmpz_mod_poly/test/t-shift_left_right.c | 151 + .../flint-2.4.3/fmpz_mod_poly/test/t-sub.c | 160 + .../flint-2.4.3/fmpz_mod_poly/test/t-swap.c | 84 + .../flint-2.4.3/fmpz_mod_poly/test/t-xgcd.c | 166 + .../fmpz_mod_poly/test/t-xgcd_euclidean.c | 166 + .../flint-2.4.3/fmpz_mod_poly/test/t-zero.c | 75 + external/flint-2.4.3/fmpz_mod_poly/tree.c | 115 + .../fmpz_mod_poly/xgcd_euclidean.c | 243 + .../flint-2.4.3/fmpz_mod_poly/zero_coeffs.c | 46 + external/flint-2.4.3/fmpz_mod_poly_factor.h | 117 + .../flint-2.4.3/fmpz_mod_poly_factor/clear.c | 44 + .../flint-2.4.3/fmpz_mod_poly_factor/concat.c | 42 + .../doc/fmpz_mod_poly_factor.txt | 174 + .../flint-2.4.3/fmpz_mod_poly_factor/factor.c | 40 + .../fmpz_mod_poly_factor/factor_berlekamp.c | 303 + .../factor_cantor_zassenhaus.c | 78 + .../factor_distinct_deg.c | 219 + .../fmpz_mod_poly_factor/factor_equal_deg.c | 66 + .../factor_equal_deg_prob.c | 117 + .../factor_kaltofen_shoup.c | 83 + .../fmpz_mod_poly_factor/factor_squarefree.c | 163 + .../fmpz_mod_poly_factor/fit_length.c | 41 + .../flint-2.4.3/fmpz_mod_poly_factor/init.c | 50 + .../flint-2.4.3/fmpz_mod_poly_factor/insert.c | 72 + .../fmpz_mod_poly_factor/is_irreducible.c | 43 + .../fmpz_mod_poly_factor/is_irreducible_ddf.c | 146 + .../is_irreducible_rabin.c | 112 + .../fmpz_mod_poly_factor/is_squarefree.c | 68 + .../flint-2.4.3/fmpz_mod_poly_factor/pow.c | 40 + .../flint-2.4.3/fmpz_mod_poly_factor/print.c | 45 + .../fmpz_mod_poly_factor/profile/p-factor.c | 377 + .../fmpz_mod_poly_factor/realloc.c | 84 + .../flint-2.4.3/fmpz_mod_poly_factor/set.c | 59 + .../fmpz_mod_poly_factor/test/t-factor.c | 142 + .../test/t-factor_berlekamp.c | 142 + .../test/t-factor_cantor_zassenhaus.c | 142 + .../test/t-factor_distinct_deg.c | 137 + .../test/t-factor_equal_deg_prob.c | 108 + .../test/t-factor_kaltofen_shoup.c | 142 + .../test/t-factor_squarefree.c | 144 + .../test/t-is_irreducible.c | 99 + .../test/t-is_irreducible_ddf.c | 99 + .../test/t-is_irreducible_rabin.c | 99 + .../test/t-is_squarefree.c | 112 + external/flint-2.4.3/fmpz_mod_poly_factorxx.h | 147 + external/flint-2.4.3/fmpz_mod_polyxx.h | 688 + external/flint-2.4.3/fmpz_poly.h | 1175 + external/flint-2.4.3/fmpz_poly/2norm.c | 45 + .../fmpz_poly/2norm_normalised_bits.c | 44 + external/flint-2.4.3/fmpz_poly/CRT_ui.c | 113 + external/flint-2.4.3/fmpz_poly/add.c | 62 + external/flint-2.4.3/fmpz_poly/bit_pack.c | 99 + external/flint-2.4.3/fmpz_poly/bit_unpack.c | 157 + external/flint-2.4.3/fmpz_poly/bound_roots.c | 87 + external/flint-2.4.3/fmpz_poly/clear.c | 43 + external/flint-2.4.3/fmpz_poly/compose.c | 86 + .../fmpz_poly/compose_divconquer.c | 253 + .../flint-2.4.3/fmpz_poly/compose_horner.c | 105 + .../flint-2.4.3/fmpz_poly/compose_series.c | 93 + .../fmpz_poly/compose_series_brent_kung.c | 137 + .../fmpz_poly/compose_series_horner.c | 124 + external/flint-2.4.3/fmpz_poly/content.c | 47 + external/flint-2.4.3/fmpz_poly/derivative.c | 53 + external/flint-2.4.3/fmpz_poly/div.c | 80 + external/flint-2.4.3/fmpz_poly/div_basecase.c | 125 + .../flint-2.4.3/fmpz_poly/div_divconquer.c | 156 + .../fmpz_poly/div_divconquer_recursive.c | 108 + external/flint-2.4.3/fmpz_poly/div_preinv.c | 104 + external/flint-2.4.3/fmpz_poly/div_root.c | 78 + external/flint-2.4.3/fmpz_poly/div_series.c | 107 + external/flint-2.4.3/fmpz_poly/divides.c | 87 + external/flint-2.4.3/fmpz_poly/divrem.c | 99 + .../flint-2.4.3/fmpz_poly/divrem_basecase.c | 122 + .../flint-2.4.3/fmpz_poly/divrem_divconquer.c | 194 + .../fmpz_poly/divrem_divconquer_recursive.c | 137 + .../flint-2.4.3/fmpz_poly/divrem_preinv.c | 113 + .../divremlow_divconquer_recursive.c | 151 + .../flint-2.4.3/fmpz_poly/doc/fmpz_poly.txt | 2848 ++ external/flint-2.4.3/fmpz_poly/equal.c | 47 + .../fmpz_poly/evaluate_divconquer_fmpz.c | 108 + .../flint-2.4.3/fmpz_poly/evaluate_fmpz.c | 54 + .../flint-2.4.3/fmpz_poly/evaluate_fmpz_vec.c | 39 + .../fmpz_poly/evaluate_horner_fmpz.c | 72 + .../fmpz_poly/evaluate_horner_mpq.c | 94 + external/flint-2.4.3/fmpz_poly/evaluate_mod.c | 67 + external/flint-2.4.3/fmpz_poly/evaluate_mpq.c | 57 + external/flint-2.4.3/fmpz_poly/fit_length.c | 41 + external/flint-2.4.3/fmpz_poly/fprint.c | 45 + .../flint-2.4.3/fmpz_poly/fprint_pretty.c | 184 + external/flint-2.4.3/fmpz_poly/fread.c | 67 + external/flint-2.4.3/fmpz_poly/fread_pretty.c | 290 + external/flint-2.4.3/fmpz_poly/gcd.c | 98 + .../flint-2.4.3/fmpz_poly/gcd_heuristic.c | 335 + external/flint-2.4.3/fmpz_poly/gcd_modular.c | 346 + .../flint-2.4.3/fmpz_poly/gcd_subresultant.c | 170 + .../flint-2.4.3/fmpz_poly/get_coeff_fmpz.c | 39 + external/flint-2.4.3/fmpz_poly/get_coeff_si.c | 36 + external/flint-2.4.3/fmpz_poly/get_coeff_ui.c | 36 + .../flint-2.4.3/fmpz_poly/get_nmod_poly.c | 51 + external/flint-2.4.3/fmpz_poly/get_str.c | 72 + .../flint-2.4.3/fmpz_poly/get_str_pretty.c | 121 + .../flint-2.4.3/fmpz_poly/hensel_build_tree.c | 128 + .../fmpz_poly/hensel_continue_lift.c | 114 + external/flint-2.4.3/fmpz_poly/hensel_lift.c | 72 + .../flint-2.4.3/fmpz_poly/hensel_lift_once.c | 63 + .../fmpz_poly/hensel_lift_only_inverse.c | 120 + .../flint-2.4.3/fmpz_poly/hensel_lift_tree.c | 48 + .../fmpz_poly/hensel_lift_tree_recursive.c | 56 + .../fmpz_poly/hensel_lift_without_inverse.c | 108 + .../flint-2.4.3/fmpz_poly/hensel_start_lift.c | 119 + external/flint-2.4.3/fmpz_poly/init.c | 51 + .../fmpz_poly/interpolate_fmpz_vec.c | 83 + .../flint-2.4.3/fmpz_poly/inv_series_newton.c | 121 + .../flint-2.4.3/fmpz_poly/is_squarefree.c | 73 + external/flint-2.4.3/fmpz_poly/lcm.c | 105 + .../fmpz_poly/monomial_to_newton.c | 39 + external/flint-2.4.3/fmpz_poly/mul.c | 100 + external/flint-2.4.3/fmpz_poly/mul_KS.c | 141 + external/flint-2.4.3/fmpz_poly/mul_SS.c | 66 + .../flint-2.4.3/fmpz_poly/mul_classical.c | 90 + .../flint-2.4.3/fmpz_poly/mul_karatsuba.c | 195 + .../flint-2.4.3/fmpz_poly/mulhigh_classical.c | 101 + .../fmpz_poly/mulhigh_karatsuba_n.c | 165 + external/flint-2.4.3/fmpz_poly/mulhigh_n.c | 64 + external/flint-2.4.3/fmpz_poly/mullow.c | 126 + external/flint-2.4.3/fmpz_poly/mullow_KS.c | 144 + external/flint-2.4.3/fmpz_poly/mullow_SS.c | 142 + .../flint-2.4.3/fmpz_poly/mullow_classical.c | 97 + .../fmpz_poly/mullow_karatsuba_n.c | 173 + .../flint-2.4.3/fmpz_poly/mulmid_classical.c | 94 + external/flint-2.4.3/fmpz_poly/neg.c | 41 + .../fmpz_poly/newton_to_monomial.c | 39 + external/flint-2.4.3/fmpz_poly/normalise.c | 37 + external/flint-2.4.3/fmpz_poly/pow.c | 92 + .../flint-2.4.3/fmpz_poly/pow_addchains.c | 202 + external/flint-2.4.3/fmpz_poly/pow_binexp.c | 156 + external/flint-2.4.3/fmpz_poly/pow_binomial.c | 123 + .../flint-2.4.3/fmpz_poly/pow_multinomial.c | 123 + external/flint-2.4.3/fmpz_poly/pow_small.c | 66 + external/flint-2.4.3/fmpz_poly/pow_trunc.c | 188 + external/flint-2.4.3/fmpz_poly/powers_clear.c | 45 + .../flint-2.4.3/fmpz_poly/powers_precompute.c | 77 + external/flint-2.4.3/fmpz_poly/preinvert.c | 121 + .../flint-2.4.3/fmpz_poly/primitive_part.c | 57 + .../fmpz_poly/product_roots_fmpz_vec.c | 77 + .../fmpz_poly/profile/bm-div_divconquer.c | 148 + .../flint-2.4.3/fmpz_poly/profile/p-compose.c | 167 + .../flint-2.4.3/fmpz_poly/profile/p-mul.c | 235 + .../fmpz_poly/profile/p-mul_triangle.c | 261 + .../flint-2.4.3/fmpz_poly/profile/p-pow.c | 138 + .../fmpz_poly/profile/p-pow_binomial.c | 103 + .../fmpz_poly/profile/p-rem_powers_precomp.c | 158 + external/flint-2.4.3/fmpz_poly/pseudo_div.c | 80 + .../fmpz_poly/pseudo_divrem_basecase.c | 145 + .../fmpz_poly/pseudo_divrem_cohen.c | 156 + .../fmpz_poly/pseudo_divrem_divconquer.c | 363 + external/flint-2.4.3/fmpz_poly/pseudo_rem.c | 83 + .../flint-2.4.3/fmpz_poly/pseudo_rem_cohen.c | 110 + external/flint-2.4.3/fmpz_poly/randtest.c | 67 + external/flint-2.4.3/fmpz_poly/realloc.c | 57 + external/flint-2.4.3/fmpz_poly/rem.c | 87 + external/flint-2.4.3/fmpz_poly/rem_basecase.c | 99 + .../fmpz_poly/rem_powers_precomp.c | 98 + external/flint-2.4.3/fmpz_poly/resultant.c | 144 + external/flint-2.4.3/fmpz_poly/reverse.c | 76 + .../flint-2.4.3/fmpz_poly/revert_series.c | 88 + .../fmpz_poly/revert_series_lagrange.c | 117 + .../fmpz_poly/revert_series_lagrange_fast.c | 143 + .../fmpz_poly/revert_series_newton.c | 131 + .../fmpz_poly/scalar_addmul_fmpz.c | 45 + .../fmpz_poly/scalar_divexact_fmpz.c | 51 + .../fmpz_poly/scalar_divexact_si.c | 51 + .../fmpz_poly/scalar_divexact_ui.c | 51 + .../flint-2.4.3/fmpz_poly/scalar_fdiv_2exp.c | 46 + .../flint-2.4.3/fmpz_poly/scalar_fdiv_fmpz.c | 51 + .../flint-2.4.3/fmpz_poly/scalar_fdiv_si.c | 51 + .../flint-2.4.3/fmpz_poly/scalar_fdiv_ui.c | 51 + .../flint-2.4.3/fmpz_poly/scalar_mul_2exp.c | 45 + .../flint-2.4.3/fmpz_poly/scalar_mul_fmpz.c | 46 + .../flint-2.4.3/fmpz_poly/scalar_mul_si.c | 63 + .../flint-2.4.3/fmpz_poly/scalar_mul_ui.c | 56 + .../fmpz_poly/scalar_submul_fmpz.c | 45 + .../flint-2.4.3/fmpz_poly/scalar_tdiv_2exp.c | 46 + .../flint-2.4.3/fmpz_poly/scalar_tdiv_fmpz.c | 51 + .../flint-2.4.3/fmpz_poly/scalar_tdiv_si.c | 51 + .../flint-2.4.3/fmpz_poly/scalar_tdiv_ui.c | 51 + external/flint-2.4.3/fmpz_poly/set.c | 45 + .../flint-2.4.3/fmpz_poly/set_coeff_fmpz.c | 45 + external/flint-2.4.3/fmpz_poly/set_coeff_si.c | 45 + external/flint-2.4.3/fmpz_poly/set_coeff_ui.c | 45 + external/flint-2.4.3/fmpz_poly/set_fmpz.c | 42 + external/flint-2.4.3/fmpz_poly/set_mpz.c | 42 + .../flint-2.4.3/fmpz_poly/set_nmod_poly.c | 50 + .../fmpz_poly/set_nmod_poly_unsigned.c | 50 + external/flint-2.4.3/fmpz_poly/set_si.c | 42 + external/flint-2.4.3/fmpz_poly/set_str.c | 122 + external/flint-2.4.3/fmpz_poly/set_ui.c | 42 + external/flint-2.4.3/fmpz_poly/shift_left.c | 71 + external/flint-2.4.3/fmpz_poly/shift_right.c | 69 + external/flint-2.4.3/fmpz_poly/signature.c | 143 + external/flint-2.4.3/fmpz_poly/sqr.c | 85 + external/flint-2.4.3/fmpz_poly/sqr_KS.c | 111 + .../flint-2.4.3/fmpz_poly/sqr_classical.c | 87 + .../flint-2.4.3/fmpz_poly/sqr_karatsuba.c | 120 + external/flint-2.4.3/fmpz_poly/sqrlow.c | 96 + external/flint-2.4.3/fmpz_poly/sqrlow_KS.c | 108 + .../flint-2.4.3/fmpz_poly/sqrlow_classical.c | 91 + .../fmpz_poly/sqrlow_karatsuba_n.c | 147 + external/flint-2.4.3/fmpz_poly/sqrt.c | 66 + .../flint-2.4.3/fmpz_poly/sqrt_classical.c | 134 + external/flint-2.4.3/fmpz_poly/sub.c | 62 + external/flint-2.4.3/fmpz_poly/swap.c | 51 + external/flint-2.4.3/fmpz_poly/taylor_shift.c | 47 + .../fmpz_poly/taylor_shift_divconquer.c | 60 + .../fmpz_poly/taylor_shift_horner.c | 64 + .../fmpz_poly/test/t-2norm_normalised_bits.c | 89 + .../flint-2.4.3/fmpz_poly/test/t-CRT_ui.c | 118 + .../fmpz_poly/test/t-CRT_ui_unsigned.c | 117 + external/flint-2.4.3/fmpz_poly/test/t-add.c | 108 + .../flint-2.4.3/fmpz_poly/test/t-bit_pack.c | 206 + .../fmpz_poly/test/t-bound_roots.c | 112 + .../flint-2.4.3/fmpz_poly/test/t-compose.c | 188 + .../fmpz_poly/test/t-compose_divconquer.c | 136 + .../fmpz_poly/test/t-compose_horner.c | 136 + .../fmpz_poly/test/t-compose_series.c | 152 + .../test/t-compose_series_brent_kung.c | 151 + .../fmpz_poly/test/t-compose_series_horner.c | 152 + .../flint-2.4.3/fmpz_poly/test/t-content.c | 84 + .../flint-2.4.3/fmpz_poly/test/t-derivative.c | 138 + .../fmpz_poly/test/t-div_basecase.c | 143 + .../fmpz_poly/test/t-div_divconquer.c | 143 + .../flint-2.4.3/fmpz_poly/test/t-div_preinv.c | 155 + .../flint-2.4.3/fmpz_poly/test/t-div_root.c | 133 + .../flint-2.4.3/fmpz_poly/test/t-div_series.c | 150 + .../flint-2.4.3/fmpz_poly/test/t-divides.c | 173 + .../fmpz_poly/test/t-divrem_basecase.c | 208 + .../fmpz_poly/test/t-divrem_divconquer.c | 208 + .../fmpz_poly/test/t-divrem_preinv.c | 228 + .../flint-2.4.3/fmpz_poly/test/t-equal_fmpz.c | 82 + .../test/t-evaluate_divconquer_fmpz.c | 110 + .../fmpz_poly/test/t-evaluate_fmpz.c | 79 + .../fmpz_poly/test/t-evaluate_horner_fmpz.c | 116 + .../fmpz_poly/test/t-evaluate_horner_mpq.c | 181 + .../fmpz_poly/test/t-evaluate_mod.c | 87 + external/flint-2.4.3/fmpz_poly/test/t-gcd.c | 146 + .../fmpz_poly/test/t-gcd_heuristic.c | 235 + .../fmpz_poly/test/t-gcd_modular.c | 256 + .../fmpz_poly/test/t-gcd_subresultant.c | 145 + .../fmpz_poly/test/t-get_coeff_ptr.c | 76 + .../fmpz_poly/test/t-get_nmod_poly.c | 87 + .../fmpz_poly/test/t-get_set_coeff_fmpz.c | 83 + .../fmpz_poly/test/t-get_set_coeff_mpz.c | 90 + .../fmpz_poly/test/t-get_set_coeff_si.c | 77 + .../fmpz_poly/test/t-get_set_coeff_ui.c | 76 + .../fmpz_poly/test/t-get_set_str.c | 77 + .../flint-2.4.3/fmpz_poly/test/t-get_str.c | 88 + .../fmpz_poly/test/t-get_str_pretty.c | 88 + .../fmpz_poly/test/t-hensel_lift.c | 213 + .../fmpz_poly/test/t-hensel_lift_once.c | 132 + .../test/t-hensel_lift_without_only_inverse.c | 212 + .../test/t-hensel_start_continue_lift.c | 177 + .../fmpz_poly/test/t-init_realloc_clear.c | 74 + .../fmpz_poly/test/t-interpolate_fmpz_vec.c | 88 + .../fmpz_poly/test/t-inv_series_newton.c | 116 + .../fmpz_poly/test/t-is_squarefree.c | 135 + external/flint-2.4.3/fmpz_poly/test/t-lcm.c | 152 + external/flint-2.4.3/fmpz_poly/test/t-mul.c | 188 + .../flint-2.4.3/fmpz_poly/test/t-mul_KS.c | 234 + .../flint-2.4.3/fmpz_poly/test/t-mul_SS.c | 223 + .../fmpz_poly/test/t-mul_classical.c | 184 + .../fmpz_poly/test/t-mul_karatsuba.c | 181 + .../fmpz_poly/test/t-mulhigh_classical.c | 150 + .../fmpz_poly/test/t-mulhigh_karatsuba_n.c | 145 + .../flint-2.4.3/fmpz_poly/test/t-mulhigh_n.c | 88 + .../flint-2.4.3/fmpz_poly/test/t-mullow.c | 80 + .../flint-2.4.3/fmpz_poly/test/t-mullow_KS.c | 149 + .../flint-2.4.3/fmpz_poly/test/t-mullow_SS.c | 149 + .../fmpz_poly/test/t-mullow_classical.c | 149 + .../fmpz_poly/test/t-mullow_karatsuba_n.c | 143 + .../fmpz_poly/test/t-mulmid_classical.c | 152 + external/flint-2.4.3/fmpz_poly/test/t-neg.c | 76 + .../fmpz_poly/test/t-newton_to_monomial.c | 85 + external/flint-2.4.3/fmpz_poly/test/t-pow.c | 122 + .../fmpz_poly/test/t-pow_addchains.c | 110 + .../flint-2.4.3/fmpz_poly/test/t-pow_binexp.c | 108 + .../fmpz_poly/test/t-pow_binomial.c | 114 + .../fmpz_poly/test/t-pow_multinomial.c | 109 + .../flint-2.4.3/fmpz_poly/test/t-pow_trunc.c | 118 + .../fmpz_poly/test/t-primitive_part.c | 106 + .../flint-2.4.3/fmpz_poly/test/t-print_read.c | 269 + .../fmpz_poly/test/t-print_read_pretty.c | 273 + .../fmpz_poly/test/t-product_roots_fmpz_vec.c | 92 + .../flint-2.4.3/fmpz_poly/test/t-pseudo_div.c | 147 + .../fmpz_poly/test/t-pseudo_divrem_basecase.c | 217 + .../fmpz_poly/test/t-pseudo_divrem_cohen.c | 217 + .../test/t-pseudo_divrem_divconquer.c | 217 + .../flint-2.4.3/fmpz_poly/test/t-pseudo_rem.c | 144 + .../fmpz_poly/test/t-pseudo_rem_cohen.c | 139 + .../fmpz_poly/test/t-rem_basecase.c | 143 + .../fmpz_poly/test/t-rem_powers_precomp.c | 155 + .../flint-2.4.3/fmpz_poly/test/t-resultant.c | 126 + .../flint-2.4.3/fmpz_poly/test/t-reverse.c | 115 + .../fmpz_poly/test/t-revert_series.c | 119 + .../fmpz_poly/test/t-revert_series_lagrange.c | 119 + .../test/t-revert_series_lagrange_fast.c | 119 + .../fmpz_poly/test/t-revert_series_newton.c | 119 + .../fmpz_poly/test/t-scalar_addmul_fmpz.c | 121 + .../fmpz_poly/test/t-scalar_divexact_mpz.c | 100 + .../fmpz_poly/test/t-scalar_fdiv_mpz.c | 100 + .../fmpz_poly/test/t-scalar_mul_fmpz.c | 111 + .../fmpz_poly/test/t-scalar_mul_mpz.c | 97 + .../fmpz_poly/test/t-scalar_mul_si.c | 137 + .../fmpz_poly/test/t-scalar_mul_ui.c | 106 + .../fmpz_poly/test/t-scalar_submul_fmpz.c | 121 + .../flint-2.4.3/fmpz_poly/test/t-set_equal.c | 108 + .../fmpz_poly/test/t-set_fmpz_equal.c | 112 + .../fmpz_poly/test/t-set_mpz_equal.c | 116 + .../fmpz_poly/test/t-set_si_equal.c | 107 + .../fmpz_poly/test/t-set_ui_equal.c | 106 + .../fmpz_poly/test/t-shift_left_right.c | 132 + .../flint-2.4.3/fmpz_poly/test/t-signature.c | 157 + external/flint-2.4.3/fmpz_poly/test/t-sqr.c | 141 + .../flint-2.4.3/fmpz_poly/test/t-sqr_KS.c | 168 + .../fmpz_poly/test/t-sqr_classical.c | 105 + .../fmpz_poly/test/t-sqr_karatsuba.c | 141 + .../flint-2.4.3/fmpz_poly/test/t-sqrlow.c | 112 + .../flint-2.4.3/fmpz_poly/test/t-sqrlow_KS.c | 112 + .../fmpz_poly/test/t-sqrlow_classical.c | 112 + .../fmpz_poly/test/t-sqrlow_karatsuba_n.c | 112 + external/flint-2.4.3/fmpz_poly/test/t-sqrt.c | 172 + external/flint-2.4.3/fmpz_poly/test/t-sub.c | 140 + external/flint-2.4.3/fmpz_poly/test/t-swap.c | 77 + .../fmpz_poly/test/t-taylor_shift.c | 121 + .../test/t-taylor_shift_divconquer.c | 121 + .../fmpz_poly/test/t-taylor_shift_horner.c | 121 + .../fmpz_poly/test/t-xgcd_modular.c | 308 + external/flint-2.4.3/fmpz_poly/test/t-zero.c | 69 + .../fmpz_poly/test/t-zero_coeffs.c | 74 + external/flint-2.4.3/fmpz_poly/xgcd_modular.c | 240 + external/flint-2.4.3/fmpz_poly/zero_coeffs.c | 46 + external/flint-2.4.3/fmpz_poly_factor.h | 83 + external/flint-2.4.3/fmpz_poly_factor/clear.c | 50 + .../flint-2.4.3/fmpz_poly_factor/concat.c | 43 + .../fmpz_poly_factor/doc/fmpz_poly_factor.txt | 151 + .../fmpz_poly_factor/factor_squarefree.c | 96 + .../fmpz_poly_factor/factor_zassenhaus.c | 290 + .../factor_zassenhaus_recombination.c | 146 + .../flint-2.4.3/fmpz_poly_factor/fit_length.c | 39 + external/flint-2.4.3/fmpz_poly_factor/init.c | 67 + .../flint-2.4.3/fmpz_poly_factor/insert.c | 54 + external/flint-2.4.3/fmpz_poly_factor/print.c | 45 + .../flint-2.4.3/fmpz_poly_factor/realloc.c | 80 + external/flint-2.4.3/fmpz_poly_factor/set.c | 58 + .../test/t-factor_squarefree.c | 114 + .../test/t-factor_zassenhaus.c | 102 + external/flint-2.4.3/fmpz_poly_factorxx.h | 157 + external/flint-2.4.3/fmpz_poly_mat.h | 240 + external/flint-2.4.3/fmpz_poly_mat/add.c | 42 + external/flint-2.4.3/fmpz_poly_mat/clear.c | 44 + external/flint-2.4.3/fmpz_poly_mat/det.c | 63 + external/flint-2.4.3/fmpz_poly_mat/det_fflu.c | 53 + .../fmpz_poly_mat/det_interpolate.c | 75 + .../fmpz_poly_mat/doc/fmpz_poly_mat.txt | 500 + external/flint-2.4.3/fmpz_poly_mat/equal.c | 45 + .../flint-2.4.3/fmpz_poly_mat/evaluate_fmpz.c | 41 + external/flint-2.4.3/fmpz_poly_mat/fflu.c | 112 + .../fmpz_poly_mat/find_pivot_any.c | 44 + .../fmpz_poly_mat/find_pivot_partial.c | 67 + external/flint-2.4.3/fmpz_poly_mat/init.c | 52 + external/flint-2.4.3/fmpz_poly_mat/init_set.c | 36 + external/flint-2.4.3/fmpz_poly_mat/inv.c | 105 + external/flint-2.4.3/fmpz_poly_mat/is_one.c | 57 + external/flint-2.4.3/fmpz_poly_mat/is_zero.c | 45 + external/flint-2.4.3/fmpz_poly_mat/max_bits.c | 57 + .../flint-2.4.3/fmpz_poly_mat/max_length.c | 48 + external/flint-2.4.3/fmpz_poly_mat/mul.c | 43 + external/flint-2.4.3/fmpz_poly_mat/mul_KS.c | 95 + .../flint-2.4.3/fmpz_poly_mat/mul_classical.c | 81 + external/flint-2.4.3/fmpz_poly_mat/mullow.c | 81 + external/flint-2.4.3/fmpz_poly_mat/neg.c | 40 + .../flint-2.4.3/fmpz_poly_mat/nullspace.c | 95 + external/flint-2.4.3/fmpz_poly_mat/one.c | 41 + external/flint-2.4.3/fmpz_poly_mat/pow.c | 75 + .../flint-2.4.3/fmpz_poly_mat/pow_trunc.c | 82 + external/flint-2.4.3/fmpz_poly_mat/print.c | 50 + external/flint-2.4.3/fmpz_poly_mat/prod.c | 70 + external/flint-2.4.3/fmpz_poly_mat/randtest.c | 39 + .../fmpz_poly_mat/randtest_sparse.c | 55 + .../fmpz_poly_mat/randtest_unsigned.c | 39 + external/flint-2.4.3/fmpz_poly_mat/rank.c | 49 + external/flint-2.4.3/fmpz_poly_mat/rref.c | 111 + .../fmpz_poly_mat/scalar_mul_fmpz.c | 42 + .../fmpz_poly_mat/scalar_mul_fmpz_poly.c | 42 + external/flint-2.4.3/fmpz_poly_mat/set.c | 43 + external/flint-2.4.3/fmpz_poly_mat/solve.c | 38 + .../flint-2.4.3/fmpz_poly_mat/solve_fflu.c | 60 + .../fmpz_poly_mat/solve_fflu_precomp.c | 103 + external/flint-2.4.3/fmpz_poly_mat/sqr.c | 38 + external/flint-2.4.3/fmpz_poly_mat/sqr_KS.c | 80 + .../flint-2.4.3/fmpz_poly_mat/sqr_classical.c | 72 + external/flint-2.4.3/fmpz_poly_mat/sqrlow.c | 86 + external/flint-2.4.3/fmpz_poly_mat/sub.c | 42 + external/flint-2.4.3/fmpz_poly_mat/swap.c | 42 + .../flint-2.4.3/fmpz_poly_mat/test/t-add.c | 186 + .../flint-2.4.3/fmpz_poly_mat/test/t-det.c | 109 + .../fmpz_poly_mat/test/t-det_interpolate.c | 87 + .../fmpz_poly_mat/test/t-init_clear.c | 67 + .../flint-2.4.3/fmpz_poly_mat/test/t-inv.c | 163 + .../flint-2.4.3/fmpz_poly_mat/test/t-mul.c | 191 + .../flint-2.4.3/fmpz_poly_mat/test/t-mul_KS.c | 182 + .../flint-2.4.3/fmpz_poly_mat/test/t-mullow.c | 178 + .../flint-2.4.3/fmpz_poly_mat/test/t-neg.c | 134 + .../fmpz_poly_mat/test/t-nullspace.c | 101 + .../flint-2.4.3/fmpz_poly_mat/test/t-one.c | 90 + .../flint-2.4.3/fmpz_poly_mat/test/t-pow.c | 124 + .../fmpz_poly_mat/test/t-pow_trunc.c | 126 + .../flint-2.4.3/fmpz_poly_mat/test/t-prod.c | 94 + .../flint-2.4.3/fmpz_poly_mat/test/t-rank.c | 95 + .../flint-2.4.3/fmpz_poly_mat/test/t-rref.c | 179 + .../fmpz_poly_mat/test/t-solve_fflu.c | 141 + .../flint-2.4.3/fmpz_poly_mat/test/t-sqr.c | 135 + .../flint-2.4.3/fmpz_poly_mat/test/t-sqr_KS.c | 123 + .../flint-2.4.3/fmpz_poly_mat/test/t-sqrlow.c | 124 + .../flint-2.4.3/fmpz_poly_mat/test/t-sub.c | 186 + .../flint-2.4.3/fmpz_poly_mat/test/t-trace.c | 99 + .../flint-2.4.3/fmpz_poly_mat/test/t-zero.c | 84 + external/flint-2.4.3/fmpz_poly_mat/trace.c | 43 + .../flint-2.4.3/fmpz_poly_mat/transpose.c | 55 + external/flint-2.4.3/fmpz_poly_mat/truncate.c | 39 + external/flint-2.4.3/fmpz_poly_mat/zero.c | 39 + external/flint-2.4.3/fmpz_poly_matxx.h | 490 + external/flint-2.4.3/fmpz_poly_q.h | 185 + external/flint-2.4.3/fmpz_poly_q/add.c | 255 + external/flint-2.4.3/fmpz_poly_q/addmul.c | 37 + .../flint-2.4.3/fmpz_poly_q/canonicalise.c | 56 + external/flint-2.4.3/fmpz_poly_q/clear.c | 43 + external/flint-2.4.3/fmpz_poly_q/derivative.c | 96 + external/flint-2.4.3/fmpz_poly_q/div.c | 137 + .../fmpz_poly_q/doc/fmpz_poly_q.txt | 320 + external/flint-2.4.3/fmpz_poly_q/evaluate.c | 81 + external/flint-2.4.3/fmpz_poly_q/get_str.c | 83 + .../flint-2.4.3/fmpz_poly_q/get_str_pretty.c | 94 + external/flint-2.4.3/fmpz_poly_q/init.c | 36 + external/flint-2.4.3/fmpz_poly_q/inv.c | 59 + .../flint-2.4.3/fmpz_poly_q/is_canonical.c | 45 + external/flint-2.4.3/fmpz_poly_q/mul.c | 132 + external/flint-2.4.3/fmpz_poly_q/pow.c | 40 + external/flint-2.4.3/fmpz_poly_q/print.c | 40 + .../flint-2.4.3/fmpz_poly_q/print_pretty.c | 40 + external/flint-2.4.3/fmpz_poly_q/randtest.c | 52 + .../flint-2.4.3/fmpz_poly_q/scalar_div_mpq.c | 50 + .../flint-2.4.3/fmpz_poly_q/scalar_div_mpz.c | 47 + .../flint-2.4.3/fmpz_poly_q/scalar_div_si.c | 104 + .../flint-2.4.3/fmpz_poly_q/scalar_mul_mpq.c | 44 + .../flint-2.4.3/fmpz_poly_q/scalar_mul_mpz.c | 41 + .../flint-2.4.3/fmpz_poly_q/scalar_mul_si.c | 76 + external/flint-2.4.3/fmpz_poly_q/set.c | 36 + external/flint-2.4.3/fmpz_poly_q/set_si.c | 33 + external/flint-2.4.3/fmpz_poly_q/set_str.c | 92 + external/flint-2.4.3/fmpz_poly_q/sub.c | 174 + external/flint-2.4.3/fmpz_poly_q/submul.c | 37 + external/flint-2.4.3/fmpz_poly_q/swap.c | 42 + external/flint-2.4.3/fmpz_poly_q/test/t-add.c | 114 + .../flint-2.4.3/fmpz_poly_q/test/t-addmul.c | 83 + external/flint-2.4.3/fmpz_poly_q/test/t-all.c | 1546 + .../fmpz_poly_q/test/t-derivative.c | 116 + external/flint-2.4.3/fmpz_poly_q/test/t-div.c | 116 + .../flint-2.4.3/fmpz_poly_q/test/t-evaluate.c | 68 + .../fmpz_poly_q/test/t-init_clear.c | 41 + external/flint-2.4.3/fmpz_poly_q/test/t-inv.c | 73 + external/flint-2.4.3/fmpz_poly_q/test/t-mul.c | 116 + external/flint-2.4.3/fmpz_poly_q/test/t-neg.c | 73 + external/flint-2.4.3/fmpz_poly_q/test/t-pow.c | 50 + .../fmpz_poly_q/test/t-scalar_div_mpq.c | 114 + .../fmpz_poly_q/test/t-scalar_div_mpz.c | 104 + .../fmpz_poly_q/test/t-scalar_div_si.c | 94 + .../fmpz_poly_q/test/t-scalar_mul_mpq.c | 114 + .../fmpz_poly_q/test/t-scalar_mul_mpz.c | 104 + .../fmpz_poly_q/test/t-scalar_mul_si.c | 90 + .../fmpz_poly_q/test/t-set_equal.c | 83 + .../fmpz_poly_q/test/t-set_si_equal.c | 81 + external/flint-2.4.3/fmpz_poly_q/test/t-sub.c | 81 + .../flint-2.4.3/fmpz_poly_q/test/t-submul.c | 83 + .../flint-2.4.3/fmpz_poly_q/test/t-swap.c | 51 + .../flint-2.4.3/fmpz_poly_q/test/t-zero.c | 42 + external/flint-2.4.3/fmpz_poly_qxx.h | 302 + external/flint-2.4.3/fmpz_polyxx.h | 962 + external/flint-2.4.3/fmpz_vec.h | 233 + external/flint-2.4.3/fmpz_vec/add.c | 37 + external/flint-2.4.3/fmpz_vec/clear.c | 39 + external/flint-2.4.3/fmpz_vec/content.c | 38 + .../flint-2.4.3/fmpz_vec/doc/fmpz_vec.txt | 438 + external/flint-2.4.3/fmpz_vec/equal.c | 43 + external/flint-2.4.3/fmpz_vec/fprint.c | 65 + external/flint-2.4.3/fmpz_vec/fread.c | 87 + external/flint-2.4.3/fmpz_vec/get_fft.c | 102 + external/flint-2.4.3/fmpz_vec/get_nmod_vec.c | 40 + external/flint-2.4.3/fmpz_vec/height.c | 42 + external/flint-2.4.3/fmpz_vec/height_index.c | 95 + external/flint-2.4.3/fmpz_vec/init.c | 36 + external/flint-2.4.3/fmpz_vec/is_zero.c | 39 + external/flint-2.4.3/fmpz_vec/lcm.c | 41 + external/flint-2.4.3/fmpz_vec/max_bits.c | 91 + external/flint-2.4.3/fmpz_vec/max_bits_ref.c | 46 + external/flint-2.4.3/fmpz_vec/max_limbs.c | 45 + external/flint-2.4.3/fmpz_vec/neg.c | 37 + external/flint-2.4.3/fmpz_vec/prod.c | 59 + external/flint-2.4.3/fmpz_vec/randtest.c | 82 + .../flint-2.4.3/fmpz_vec/scalar_addmul_fmpz.c | 54 + .../flint-2.4.3/fmpz_vec/scalar_addmul_si.c | 42 + .../fmpz_vec/scalar_addmul_si_2exp.c | 86 + .../fmpz_vec/scalar_divexact_fmpz.c | 53 + .../flint-2.4.3/fmpz_vec/scalar_divexact_si.c | 38 + .../flint-2.4.3/fmpz_vec/scalar_divexact_ui.c | 39 + .../flint-2.4.3/fmpz_vec/scalar_fdiv_q_2exp.c | 39 + .../flint-2.4.3/fmpz_vec/scalar_fdiv_q_fmpz.c | 39 + .../flint-2.4.3/fmpz_vec/scalar_fdiv_q_si.c | 38 + .../flint-2.4.3/fmpz_vec/scalar_fdiv_q_ui.c | 38 + .../flint-2.4.3/fmpz_vec/scalar_fdiv_r_2exp.c | 40 + .../flint-2.4.3/fmpz_vec/scalar_mod_fmpz.c | 38 + .../flint-2.4.3/fmpz_vec/scalar_mul_2exp.c | 38 + .../flint-2.4.3/fmpz_vec/scalar_mul_fmpz.c | 54 + external/flint-2.4.3/fmpz_vec/scalar_mul_si.c | 37 + external/flint-2.4.3/fmpz_vec/scalar_mul_ui.c | 37 + .../flint-2.4.3/fmpz_vec/scalar_smod_fmpz.c | 51 + .../flint-2.4.3/fmpz_vec/scalar_submul_fmpz.c | 55 + .../flint-2.4.3/fmpz_vec/scalar_submul_si.c | 43 + .../fmpz_vec/scalar_submul_si_2exp.c | 87 + .../flint-2.4.3/fmpz_vec/scalar_tdiv_q_2exp.c | 39 + .../flint-2.4.3/fmpz_vec/scalar_tdiv_q_fmpz.c | 38 + .../flint-2.4.3/fmpz_vec/scalar_tdiv_q_si.c | 37 + .../flint-2.4.3/fmpz_vec/scalar_tdiv_q_ui.c | 37 + external/flint-2.4.3/fmpz_vec/set.c | 37 + external/flint-2.4.3/fmpz_vec/set_fft.c | 84 + external/flint-2.4.3/fmpz_vec/set_nmod_vec.c | 40 + external/flint-2.4.3/fmpz_vec/sort.c | 39 + external/flint-2.4.3/fmpz_vec/sub.c | 37 + external/flint-2.4.3/fmpz_vec/sum.c | 50 + external/flint-2.4.3/fmpz_vec/swap.c | 37 + external/flint-2.4.3/fmpz_vec/test/t-add.c | 107 + .../flint-2.4.3/fmpz_vec/test/t-content.c | 85 + .../flint-2.4.3/fmpz_vec/test/t-get_set_fft.c | 131 + .../fmpz_vec/test/t-get_set_nmod_vec.c | 96 + external/flint-2.4.3/fmpz_vec/test/t-height.c | 83 + .../fmpz_vec/test/t-height_index.c | 87 + .../flint-2.4.3/fmpz_vec/test/t-init_clear.c | 61 + .../flint-2.4.3/fmpz_vec/test/t-is_zero.c | 92 + external/flint-2.4.3/fmpz_vec/test/t-lcm.c | 93 + .../flint-2.4.3/fmpz_vec/test/t-max_bits.c | 74 + .../flint-2.4.3/fmpz_vec/test/t-max_limbs.c | 79 + external/flint-2.4.3/fmpz_vec/test/t-neg.c | 101 + external/flint-2.4.3/fmpz_vec/test/t-prod.c | 88 + .../fmpz_vec/test/t-scalar_addmul_fmpz.c | 124 + .../fmpz_vec/test/t-scalar_addmul_si.c | 90 + .../fmpz_vec/test/t-scalar_addmul_si_2exp.c | 91 + .../fmpz_vec/test/t-scalar_divexact_fmpz.c | 116 + .../fmpz_vec/test/t-scalar_divexact_si.c | 110 + .../fmpz_vec/test/t-scalar_divexact_ui.c | 105 + .../fmpz_vec/test/t-scalar_fdiv_q_fmpz.c | 163 + .../fmpz_vec/test/t-scalar_mod_fmpz.c | 116 + .../fmpz_vec/test/t-scalar_mul_2exp.c | 107 + .../fmpz_vec/test/t-scalar_mul_fmpz.c | 165 + .../fmpz_vec/test/t-scalar_mul_si.c | 111 + .../fmpz_vec/test/t-scalar_mul_ui.c | 108 + .../fmpz_vec/test/t-scalar_smod_fmpz.c | 137 + .../fmpz_vec/test/t-scalar_submul_fmpz.c | 124 + .../fmpz_vec/test/t-scalar_submul_si.c | 88 + .../fmpz_vec/test/t-scalar_submul_si_2exp.c | 89 + .../flint-2.4.3/fmpz_vec/test/t-set_equal.c | 124 + external/flint-2.4.3/fmpz_vec/test/t-sub.c | 139 + external/flint-2.4.3/fmpz_vec/test/t-sum.c | 88 + external/flint-2.4.3/fmpz_vec/test/t-swap.c | 79 + external/flint-2.4.3/fmpz_vec/test/t-zero.c | 72 + external/flint-2.4.3/fmpz_vec/zero.c | 37 + external/flint-2.4.3/fmpz_vecxx.h | 110 + external/flint-2.4.3/fmpzxx.h | 799 + external/flint-2.4.3/fprintf.c | 125 + external/flint-2.4.3/fq.h | 365 + external/flint-2.4.3/fq/Makefile | 54 + external/flint-2.4.3/fq/add.c | 43 + external/flint-2.4.3/fq/bit_pack.c | 34 + external/flint-2.4.3/fq/bit_unpack.c | 34 + external/flint-2.4.3/fq/ctx_clear.c | 39 + external/flint-2.4.3/fq/ctx_init.c | 52 + external/flint-2.4.3/fq/ctx_init_conway.c | 128 + external/flint-2.4.3/fq/ctx_init_modulus.c | 92 + external/flint-2.4.3/fq/ctx_randtest.c | 59 + external/flint-2.4.3/fq/doc/fq.txt | 468 + external/flint-2.4.3/fq/frobenius.c | 102 + external/flint-2.4.3/fq/get_str.c | 32 + external/flint-2.4.3/fq/get_str_pretty.c | 32 + external/flint-2.4.3/fq/inv.c | 85 + external/flint-2.4.3/fq/mul.c | 35 + external/flint-2.4.3/fq/mul_fmpz.c | 35 + external/flint-2.4.3/fq/mul_si.c | 35 + external/flint-2.4.3/fq/mul_ui.c | 35 + external/flint-2.4.3/fq/neg.c | 39 + external/flint-2.4.3/fq/norm.c | 212 + external/flint-2.4.3/fq/pow.c | 175 + external/flint-2.4.3/fq/pow_ui.c | 37 + external/flint-2.4.3/fq/profile/p-inv.c | 83 + external/flint-2.4.3/fq/profile/p-mul.c | 66 + external/flint-2.4.3/fq/profile/p-reduce.c | 100 + external/flint-2.4.3/fq/pth_root.c | 44 + external/flint-2.4.3/fq/randtest.c | 88 + external/flint-2.4.3/fq/sqr.c | 36 + external/flint-2.4.3/fq/sub.c | 43 + external/flint-2.4.3/fq/sub_one.c | 37 + external/flint-2.4.3/fq/test/t-add.c | 39 + external/flint-2.4.3/fq/test/t-ctx_init.c | 38 + external/flint-2.4.3/fq/test/t-frobenius.c | 39 + external/flint-2.4.3/fq/test/t-inv.c | 39 + external/flint-2.4.3/fq/test/t-mul.c | 39 + external/flint-2.4.3/fq/test/t-mul_fmpz.c | 39 + external/flint-2.4.3/fq/test/t-mul_si.c | 39 + external/flint-2.4.3/fq/test/t-mul_ui.c | 39 + external/flint-2.4.3/fq/test/t-neg.c | 39 + external/flint-2.4.3/fq/test/t-norm.c | 39 + external/flint-2.4.3/fq/test/t-pow.c | 39 + external/flint-2.4.3/fq/test/t-pth_root.c | 39 + external/flint-2.4.3/fq/test/t-sqr.c | 39 + external/flint-2.4.3/fq/test/t-sub.c | 39 + external/flint-2.4.3/fq/test/t-trace.c | 39 + external/flint-2.4.3/fq/trace.c | 77 + external/flint-2.4.3/fq_mat.h | 53 + external/flint-2.4.3/fq_mat/add.c | 36 + external/flint-2.4.3/fq_mat/clear.c | 36 + external/flint-2.4.3/fq_mat/doc/fq_mat.txt | 428 + external/flint-2.4.3/fq_mat/equal.c | 36 + external/flint-2.4.3/fq_mat/fprint.c | 36 + external/flint-2.4.3/fq_mat/init.c | 36 + external/flint-2.4.3/fq_mat/init_set.c | 36 + external/flint-2.4.3/fq_mat/is_zero.c | 36 + external/flint-2.4.3/fq_mat/lu.c | 36 + external/flint-2.4.3/fq_mat/lu_classical.c | 36 + external/flint-2.4.3/fq_mat/lu_recursive.c | 36 + external/flint-2.4.3/fq_mat/mul.c | 36 + external/flint-2.4.3/fq_mat/mul_KS.c | 36 + external/flint-2.4.3/fq_mat/mul_classical.c | 36 + external/flint-2.4.3/fq_mat/neg.c | 36 + external/flint-2.4.3/fq_mat/profile/p-mul.c | 36 + external/flint-2.4.3/fq_mat/randops.c | 36 + external/flint-2.4.3/fq_mat/randpermdiag.c | 36 + external/flint-2.4.3/fq_mat/randrank.c | 36 + external/flint-2.4.3/fq_mat/randtest.c | 36 + external/flint-2.4.3/fq_mat/randtril.c | 36 + external/flint-2.4.3/fq_mat/randtriu.c | 36 + external/flint-2.4.3/fq_mat/rref.c | 36 + external/flint-2.4.3/fq_mat/set.c | 36 + external/flint-2.4.3/fq_mat/solve_tril.c | 36 + .../flint-2.4.3/fq_mat/solve_tril_classical.c | 36 + .../flint-2.4.3/fq_mat/solve_tril_recursive.c | 36 + external/flint-2.4.3/fq_mat/solve_triu.c | 36 + .../flint-2.4.3/fq_mat/solve_triu_classical.c | 36 + .../flint-2.4.3/fq_mat/solve_triu_recursive.c | 36 + external/flint-2.4.3/fq_mat/sub.c | 36 + external/flint-2.4.3/fq_mat/submul.c | 36 + external/flint-2.4.3/fq_mat/swap.c | 36 + external/flint-2.4.3/fq_mat/test/t-add_sub.c | 36 + external/flint-2.4.3/fq_mat/test/t-equal.c | 36 + external/flint-2.4.3/fq_mat/test/t-is_zero.c | 36 + .../flint-2.4.3/fq_mat/test/t-lu_classical.c | 36 + .../flint-2.4.3/fq_mat/test/t-lu_recursive.c | 36 + external/flint-2.4.3/fq_mat/test/t-mul.c | 36 + external/flint-2.4.3/fq_mat/test/t-mul_KS.c | 36 + external/flint-2.4.3/fq_mat/test/t-rref.c | 36 + .../flint-2.4.3/fq_mat/test/t-solve_tril.c | 36 + .../fq_mat/test/t-solve_tril_classical.c | 36 + .../fq_mat/test/t-solve_tril_recursive.c | 36 + .../flint-2.4.3/fq_mat/test/t-solve_triu.c | 36 + .../fq_mat/test/t-solve_triu_classical.c | 36 + .../fq_mat/test/t-solve_triu_recursive.c | 36 + external/flint-2.4.3/fq_mat/test/t-submul.c | 36 + external/flint-2.4.3/fq_mat/test/t-zero.c | 36 + external/flint-2.4.3/fq_mat/window_clear.c | 36 + external/flint-2.4.3/fq_mat/window_init.c | 36 + external/flint-2.4.3/fq_mat/zero.c | 36 + external/flint-2.4.3/fq_mat_templates.h | 296 + external/flint-2.4.3/fq_mat_templates/add.c | 49 + external/flint-2.4.3/fq_mat_templates/clear.c | 47 + external/flint-2.4.3/fq_mat_templates/equal.c | 59 + .../flint-2.4.3/fq_mat_templates/fprint.c | 126 + external/flint-2.4.3/fq_mat_templates/init.c | 59 + .../flint-2.4.3/fq_mat_templates/init_set.c | 43 + .../flint-2.4.3/fq_mat_templates/is_zero.c | 51 + external/flint-2.4.3/fq_mat_templates/lu.c | 40 + .../fq_mat_templates/lu_classical.c | 131 + .../fq_mat_templates/lu_recursive.c | 158 + external/flint-2.4.3/fq_mat_templates/mul.c | 43 + .../flint-2.4.3/fq_mat_templates/mul_KS.c | 100 + .../fq_mat_templates/mul_classical.c | 88 + external/flint-2.4.3/fq_mat_templates/neg.c | 47 + .../fq_mat_templates/profile/p-mul.c | 132 + .../flint-2.4.3/fq_mat_templates/randops.c | 76 + .../fq_mat_templates/randpermdiag.c | 63 + .../flint-2.4.3/fq_mat_templates/randrank.c | 55 + .../flint-2.4.3/fq_mat_templates/randtest.c | 47 + .../flint-2.4.3/fq_mat_templates/randtril.c | 63 + .../flint-2.4.3/fq_mat_templates/randtriu.c | 63 + external/flint-2.4.3/fq_mat_templates/rref.c | 148 + external/flint-2.4.3/fq_mat_templates/set.c | 49 + .../flint-2.4.3/fq_mat_templates/solve_tril.c | 49 + .../fq_mat_templates/solve_tril_classical.c | 82 + .../fq_mat_templates/solve_tril_recursive.c | 77 + .../flint-2.4.3/fq_mat_templates/solve_triu.c | 49 + .../fq_mat_templates/solve_triu_classical.c | 83 + .../fq_mat_templates/solve_triu_recursive.c | 77 + external/flint-2.4.3/fq_mat_templates/sub.c | 49 + .../flint-2.4.3/fq_mat_templates/submul.c | 47 + external/flint-2.4.3/fq_mat_templates/swap.c | 47 + .../fq_mat_templates/test/t-add_sub.c | 88 + .../fq_mat_templates/test/t-equal.c | 113 + .../fq_mat_templates/test/t-is_zero.c | 90 + .../fq_mat_templates/test/t-lu_classical.c | 185 + .../fq_mat_templates/test/t-lu_recursive.c | 184 + .../flint-2.4.3/fq_mat_templates/test/t-mul.c | 135 + .../fq_mat_templates/test/t-mul_KS.c | 135 + .../fq_mat_templates/test/t-rref.c | 210 + .../fq_mat_templates/test/t-solve_tril.c | 111 + .../test/t-solve_tril_classical.c | 110 + .../test/t-solve_tril_recursive.c | 110 + .../fq_mat_templates/test/t-solve_triu.c | 110 + .../test/t-solve_triu_classical.c | 110 + .../test/t-solve_triu_recursive.c | 110 + .../fq_mat_templates/test/t-submul.c | 115 + .../fq_mat_templates/test/t-zero.c | 88 + .../fq_mat_templates/window_clear.c | 43 + .../fq_mat_templates/window_init.c | 54 + external/flint-2.4.3/fq_mat_templates/zero.c | 42 + external/flint-2.4.3/fq_nmod.h | 404 + external/flint-2.4.3/fq_nmod/add.c | 42 + external/flint-2.4.3/fq_nmod/bit_pack.c | 34 + external/flint-2.4.3/fq_nmod/bit_unpack.c | 34 + external/flint-2.4.3/fq_nmod/ctx_clear.c | 38 + external/flint-2.4.3/fq_nmod/ctx_init.c | 51 + .../flint-2.4.3/fq_nmod/ctx_init_conway.c | 124 + .../flint-2.4.3/fq_nmod/ctx_init_modulus.c | 91 + external/flint-2.4.3/fq_nmod/ctx_randtest.c | 55 + external/flint-2.4.3/fq_nmod/doc/fq_nmod.txt | 486 + external/flint-2.4.3/fq_nmod/frobenius.c | 102 + external/flint-2.4.3/fq_nmod/get_str.c | 32 + external/flint-2.4.3/fq_nmod/get_str_pretty.c | 33 + external/flint-2.4.3/fq_nmod/inv.c | 83 + external/flint-2.4.3/fq_nmod/mul.c | 35 + external/flint-2.4.3/fq_nmod/mul_fmpz.c | 38 + external/flint-2.4.3/fq_nmod/mul_si.c | 36 + external/flint-2.4.3/fq_nmod/mul_ui.c | 31 + external/flint-2.4.3/fq_nmod/neg.c | 36 + external/flint-2.4.3/fq_nmod/norm.c | 105 + external/flint-2.4.3/fq_nmod/pow.c | 184 + external/flint-2.4.3/fq_nmod/pth_root.c | 45 + external/flint-2.4.3/fq_nmod/randtest.c | 68 + external/flint-2.4.3/fq_nmod/sqr.c | 33 + external/flint-2.4.3/fq_nmod/sub.c | 42 + external/flint-2.4.3/fq_nmod/sub_one.c | 36 + external/flint-2.4.3/fq_nmod/test/t-add.c | 36 + .../flint-2.4.3/fq_nmod/test/t-ctx_init.c | 36 + .../flint-2.4.3/fq_nmod/test/t-frobenius.c | 36 + external/flint-2.4.3/fq_nmod/test/t-inv.c | 36 + external/flint-2.4.3/fq_nmod/test/t-mul.c | 36 + .../flint-2.4.3/fq_nmod/test/t-mul_fmpz.c | 139 + external/flint-2.4.3/fq_nmod/test/t-mul_si.c | 122 + external/flint-2.4.3/fq_nmod/test/t-mul_ui.c | 115 + external/flint-2.4.3/fq_nmod/test/t-neg.c | 36 + external/flint-2.4.3/fq_nmod/test/t-norm.c | 36 + external/flint-2.4.3/fq_nmod/test/t-pow.c | 36 + .../flint-2.4.3/fq_nmod/test/t-pth_root.c | 36 + external/flint-2.4.3/fq_nmod/test/t-sqr.c | 36 + external/flint-2.4.3/fq_nmod/test/t-sub.c | 36 + external/flint-2.4.3/fq_nmod/test/t-trace.c | 36 + external/flint-2.4.3/fq_nmod/trace.c | 85 + external/flint-2.4.3/fq_nmod_mat.h | 53 + external/flint-2.4.3/fq_nmod_mat/add.c | 36 + external/flint-2.4.3/fq_nmod_mat/clear.c | 36 + .../fq_nmod_mat/doc/fq_nmod_mat.txt | 442 + external/flint-2.4.3/fq_nmod_mat/equal.c | 36 + external/flint-2.4.3/fq_nmod_mat/fprint.c | 36 + external/flint-2.4.3/fq_nmod_mat/init.c | 36 + external/flint-2.4.3/fq_nmod_mat/init_set.c | 36 + external/flint-2.4.3/fq_nmod_mat/is_zero.c | 36 + external/flint-2.4.3/fq_nmod_mat/lu.c | 36 + .../flint-2.4.3/fq_nmod_mat/lu_classical.c | 36 + .../flint-2.4.3/fq_nmod_mat/lu_recursive.c | 36 + external/flint-2.4.3/fq_nmod_mat/mul.c | 36 + external/flint-2.4.3/fq_nmod_mat/mul_KS.c | 36 + .../flint-2.4.3/fq_nmod_mat/mul_classical.c | 36 + external/flint-2.4.3/fq_nmod_mat/neg.c | 36 + external/flint-2.4.3/fq_nmod_mat/randops.c | 36 + .../flint-2.4.3/fq_nmod_mat/randpermdiag.c | 36 + external/flint-2.4.3/fq_nmod_mat/randrank.c | 36 + external/flint-2.4.3/fq_nmod_mat/randtest.c | 36 + external/flint-2.4.3/fq_nmod_mat/randtril.c | 36 + external/flint-2.4.3/fq_nmod_mat/randtriu.c | 36 + external/flint-2.4.3/fq_nmod_mat/rref.c | 36 + external/flint-2.4.3/fq_nmod_mat/set.c | 36 + external/flint-2.4.3/fq_nmod_mat/solve_tril.c | 36 + .../fq_nmod_mat/solve_tril_classical.c | 36 + .../fq_nmod_mat/solve_tril_recursive.c | 36 + external/flint-2.4.3/fq_nmod_mat/solve_triu.c | 36 + .../fq_nmod_mat/solve_triu_classical.c | 36 + .../fq_nmod_mat/solve_triu_recursive.c | 36 + external/flint-2.4.3/fq_nmod_mat/sub.c | 36 + external/flint-2.4.3/fq_nmod_mat/submul.c | 36 + external/flint-2.4.3/fq_nmod_mat/swap.c | 36 + .../flint-2.4.3/fq_nmod_mat/test/t-add_sub.c | 36 + .../flint-2.4.3/fq_nmod_mat/test/t-equal.c | 36 + .../flint-2.4.3/fq_nmod_mat/test/t-is_zero.c | 36 + .../fq_nmod_mat/test/t-lu_classical.c | 36 + .../fq_nmod_mat/test/t-lu_recursive.c | 36 + external/flint-2.4.3/fq_nmod_mat/test/t-mul.c | 36 + .../flint-2.4.3/fq_nmod_mat/test/t-mul_KS.c | 36 + .../flint-2.4.3/fq_nmod_mat/test/t-rref.c | 36 + .../fq_nmod_mat/test/t-solve_tril.c | 36 + .../fq_nmod_mat/test/t-solve_tril_classical.c | 36 + .../fq_nmod_mat/test/t-solve_tril_recursive.c | 36 + .../fq_nmod_mat/test/t-solve_triu.c | 36 + .../fq_nmod_mat/test/t-solve_triu_classical.c | 36 + .../fq_nmod_mat/test/t-solve_triu_recursive.c | 36 + .../flint-2.4.3/fq_nmod_mat/test/t-submul.c | 36 + .../flint-2.4.3/fq_nmod_mat/test/t-zero.c | 36 + .../flint-2.4.3/fq_nmod_mat/window_clear.c | 36 + .../flint-2.4.3/fq_nmod_mat/window_init.c | 36 + external/flint-2.4.3/fq_nmod_mat/zero.c | 36 + external/flint-2.4.3/fq_nmod_poly.h | 53 + external/flint-2.4.3/fq_nmod_poly/add.c | 36 + external/flint-2.4.3/fq_nmod_poly/clear.c | 36 + external/flint-2.4.3/fq_nmod_poly/compose.c | 36 + .../fq_nmod_poly/compose_divconquer.c | 36 + .../flint-2.4.3/fq_nmod_poly/compose_horner.c | 36 + .../flint-2.4.3/fq_nmod_poly/compose_mod.c | 36 + .../fq_nmod_poly/compose_mod_brent_kung.c | 36 + .../compose_mod_brent_kung_precomp_preinv.c | 36 + .../compose_mod_brent_kung_preinv.c | 36 + .../fq_nmod_poly/compose_mod_horner.c | 36 + .../fq_nmod_poly/compose_mod_horner_preinv.c | 36 + .../fq_nmod_poly/compose_mod_preinv.c | 36 + external/flint-2.4.3/fq_nmod_poly/deflate.c | 36 + external/flint-2.4.3/fq_nmod_poly/deflation.c | 36 + .../flint-2.4.3/fq_nmod_poly/derivative.c | 36 + .../flint-2.4.3/fq_nmod_poly/div_basecase.c | 36 + .../fq_nmod_poly/div_newton_n_preinv.c | 36 + external/flint-2.4.3/fq_nmod_poly/divides.c | 36 + .../fq_nmod_poly/divrem_basecase.c | 36 + .../fq_nmod_poly/divrem_divconquer.c | 36 + .../divrem_divconquer_recursive.c | 36 + .../fq_nmod_poly/divrem_newton_n_preinv.c | 36 + .../fq_nmod_poly/doc/fq_nmod_poly.txt | 1596 + external/flint-2.4.3/fq_nmod_poly/equal.c | 36 + .../flint-2.4.3/fq_nmod_poly/evaluate_fq.c | 36 + .../flint-2.4.3/fq_nmod_poly/fit_length.c | 36 + external/flint-2.4.3/fq_nmod_poly/fprint.c | 36 + .../flint-2.4.3/fq_nmod_poly/fprint_pretty.c | 36 + .../flint-2.4.3/fq_nmod_poly/gcd_euclidean.c | 36 + external/flint-2.4.3/fq_nmod_poly/gen.c | 36 + external/flint-2.4.3/fq_nmod_poly/get_coeff.c | 36 + external/flint-2.4.3/fq_nmod_poly/get_str.c | 36 + .../flint-2.4.3/fq_nmod_poly/get_str_pretty.c | 36 + .../flint-2.4.3/fq_nmod_poly/hamming_weight.c | 36 + external/flint-2.4.3/fq_nmod_poly/inflate.c | 36 + external/flint-2.4.3/fq_nmod_poly/init.c | 36 + .../fq_nmod_poly/inv_series_newton.c | 36 + .../flint-2.4.3/fq_nmod_poly/make_monic.c | 36 + external/flint-2.4.3/fq_nmod_poly/mul.c | 36 + external/flint-2.4.3/fq_nmod_poly/mul_KS.c | 36 + .../flint-2.4.3/fq_nmod_poly/mul_classical.c | 36 + external/flint-2.4.3/fq_nmod_poly/mullow.c | 36 + external/flint-2.4.3/fq_nmod_poly/mullow_KS.c | 36 + .../fq_nmod_poly/mullow_classical.c | 36 + external/flint-2.4.3/fq_nmod_poly/mulmod.c | 36 + .../flint-2.4.3/fq_nmod_poly/mulmod_preinv.c | 36 + external/flint-2.4.3/fq_nmod_poly/neg.c | 36 + external/flint-2.4.3/fq_nmod_poly/normalise.c | 36 + external/flint-2.4.3/fq_nmod_poly/one.c | 36 + external/flint-2.4.3/fq_nmod_poly/pow.c | 36 + .../fq_nmod_poly/powmod_fmpz_binexp.c | 36 + .../fq_nmod_poly/powmod_fmpz_binexp_preinv.c | 36 + .../fq_nmod_poly/powmod_fmpz_sliding_preinv.c | 36 + .../fq_nmod_poly/powmod_ui_binexp.c | 36 + .../fq_nmod_poly/powmod_ui_binexp_preinv.c | 36 + .../fq_nmod_poly/powmod_x_fmpz_preinv.c | 36 + .../p-factor_kaltofen_shoup_vs_fq_poly.c | 164 + .../fq_nmod_poly/profile/p-factor_xnpxp1.c | 36 + .../fq_nmod_poly/profile/p-is_irreducible.c | 36 + .../profile/p-iterated_frobenius.c | 36 + .../profile/p-iterated_frobenius_table.c | 36 + .../fq_nmod_poly/profile/p-mullow.c | 36 + external/flint-2.4.3/fq_nmod_poly/randtest.c | 36 + .../fq_nmod_poly/randtest_irreducible.c | 36 + .../flint-2.4.3/fq_nmod_poly/randtest_monic.c | 36 + external/flint-2.4.3/fq_nmod_poly/realloc.c | 36 + external/flint-2.4.3/fq_nmod_poly/remove.c | 36 + external/flint-2.4.3/fq_nmod_poly/reverse.c | 36 + .../fq_nmod_poly/scalar_addmul_fq.c | 36 + .../flint-2.4.3/fq_nmod_poly/scalar_mul_fq.c | 36 + .../fq_nmod_poly/scalar_submul_fq.c | 36 + external/flint-2.4.3/fq_nmod_poly/set.c | 36 + external/flint-2.4.3/fq_nmod_poly/set_coeff.c | 36 + external/flint-2.4.3/fq_nmod_poly/set_fq.c | 36 + .../flint-2.4.3/fq_nmod_poly/shift_left.c | 36 + .../flint-2.4.3/fq_nmod_poly/shift_right.c | 36 + external/flint-2.4.3/fq_nmod_poly/sqr.c | 36 + external/flint-2.4.3/fq_nmod_poly/sqr_KS.c | 36 + .../flint-2.4.3/fq_nmod_poly/sqr_classical.c | 36 + external/flint-2.4.3/fq_nmod_poly/sub.c | 36 + external/flint-2.4.3/fq_nmod_poly/swap.c | 36 + .../flint-2.4.3/fq_nmod_poly/test/t-add.c | 36 + .../flint-2.4.3/fq_nmod_poly/test/t-compose.c | 36 + .../fq_nmod_poly/test/t-compose_divconquer.c | 36 + .../fq_nmod_poly/test/t-compose_horner.c | 36 + .../fq_nmod_poly/test/t-compose_mod.c | 36 + .../test/t-compose_mod_brent_kung.c | 36 + .../test/t-compose_mod_brent_kung_preinv.c | 36 + .../fq_nmod_poly/test/t-compose_mod_horner.c | 36 + .../test/t-compose_mod_horner_preinv.c | 36 + .../fq_nmod_poly/test/t-compose_mod_preinv.c | 36 + .../flint-2.4.3/fq_nmod_poly/test/t-deflate.c | 36 + .../fq_nmod_poly/test/t-derivative.c | 36 + .../fq_nmod_poly/test/t-div_basecase.c | 36 + .../fq_nmod_poly/test/t-div_newton_n_preinv.c | 36 + .../flint-2.4.3/fq_nmod_poly/test/t-divides.c | 36 + .../fq_nmod_poly/test/t-divrem_basecase.c | 36 + .../fq_nmod_poly/test/t-divrem_divconquer.c | 36 + .../test/t-divrem_newton_n_preinv.c | 36 + .../fq_nmod_poly/test/t-evaluate_fq.c | 36 + .../fq_nmod_poly/test/t-gcd_euclidean.c | 36 + .../flint-2.4.3/fq_nmod_poly/test/t-get_str.c | 36 + .../fq_nmod_poly/test/t-get_str_pretty.c | 36 + .../fq_nmod_poly/test/t-hamming_weight.c | 36 + .../flint-2.4.3/fq_nmod_poly/test/t-inflate.c | 36 + .../fq_nmod_poly/test/t-inv_series_newton.c | 36 + .../fq_nmod_poly/test/t-make_monic.c | 36 + .../flint-2.4.3/fq_nmod_poly/test/t-mul.c | 36 + .../flint-2.4.3/fq_nmod_poly/test/t-mul_KS.c | 36 + .../fq_nmod_poly/test/t-mul_classical.c | 36 + .../flint-2.4.3/fq_nmod_poly/test/t-mullow.c | 36 + .../fq_nmod_poly/test/t-mullow_KS.c | 36 + .../fq_nmod_poly/test/t-mullow_classical.c | 36 + .../flint-2.4.3/fq_nmod_poly/test/t-mulmod.c | 36 + .../fq_nmod_poly/test/t-mulmod_preinv.c | 36 + .../flint-2.4.3/fq_nmod_poly/test/t-neg.c | 36 + .../flint-2.4.3/fq_nmod_poly/test/t-pow.c | 36 + .../fq_nmod_poly/test/t-powmod_fmpz_binexp.c | 36 + .../test/t-powmod_fmpz_binexp_preinv.c | 36 + .../test/t-powmod_fmpz_sliding_preinv.c | 36 + .../fq_nmod_poly/test/t-powmod_ui_binexp.c | 36 + .../test/t-powmod_ui_binexp_preinv.c | 36 + .../test/t-powmod_x_fmpz_preinv.c | 36 + .../test/t-randtest_irreducible.c | 36 + .../fq_nmod_poly/test/t-scalar_addmul_fq.c | 36 + .../fq_nmod_poly/test/t-scalar_mul_fq.c | 36 + .../fq_nmod_poly/test/t-scalar_submul_fq.c | 36 + .../fq_nmod_poly/test/t-shift_left_right.c | 36 + .../flint-2.4.3/fq_nmod_poly/test/t-sqr.c | 36 + .../flint-2.4.3/fq_nmod_poly/test/t-sqr_KS.c | 36 + .../fq_nmod_poly/test/t-sqr_classical.c | 36 + .../flint-2.4.3/fq_nmod_poly/test/t-sub.c | 36 + external/flint-2.4.3/fq_nmod_poly/truncate.c | 36 + external/flint-2.4.3/fq_nmod_poly_factor.h | 53 + .../flint-2.4.3/fq_nmod_poly_factor/clear.c | 36 + .../flint-2.4.3/fq_nmod_poly_factor/concat.c | 36 + .../doc/fq_nmod_poly_factor.txt | 254 + .../flint-2.4.3/fq_nmod_poly_factor/factor.c | 36 + .../fq_nmod_poly_factor/factor_berlekamp.c | 36 + .../factor_cantor_zassenhaus.c | 36 + .../fq_nmod_poly_factor/factor_distinct_deg.c | 36 + .../fq_nmod_poly_factor/factor_equal_deg.c | 36 + .../factor_equal_deg_prob.c | 36 + .../factor_kaltofen_shoup.c | 36 + .../fq_nmod_poly_factor/factor_squarefree.c | 36 + .../fq_nmod_poly_factor/fit_length.c | 36 + .../flint-2.4.3/fq_nmod_poly_factor/init.c | 36 + .../flint-2.4.3/fq_nmod_poly_factor/insert.c | 36 + .../fq_nmod_poly_factor/is_irreducible.c | 36 + .../is_irreducible_ben_or.c | 36 + .../fq_nmod_poly_factor/is_irreducible_ddf.c | 36 + .../fq_nmod_poly_factor/is_squarefree.c | 36 + .../iterated_frobenius_preinv.c | 36 + .../flint-2.4.3/fq_nmod_poly_factor/pow.c | 36 + .../flint-2.4.3/fq_nmod_poly_factor/print.c | 36 + .../fq_nmod_poly_factor/print_pretty.c | 36 + .../flint-2.4.3/fq_nmod_poly_factor/realloc.c | 36 + .../flint-2.4.3/fq_nmod_poly_factor/set.c | 36 + .../fq_nmod_poly_factor/test/t-factor.c | 36 + .../test/t-factor_berlekamp.c | 36 + .../test/t-factor_cantor_zassenhaus.c | 36 + .../test/t-factor_distinct_deg.c | 36 + .../test/t-factor_equal_deg_prob.c | 36 + .../test/t-factor_kaltofen_shoup.c | 36 + .../test/t-factor_squarefree.c | 36 + .../test/t-is_irreducible.c | 36 + .../test/t-is_irreducible_ben_or.c | 36 + .../test/t-is_irreducible_ddf.c | 36 + .../test/t-is_squarefree.c | 36 + .../test/t-iterated_frobenius_preinv.c | 36 + external/flint-2.4.3/fq_nmod_vec.h | 57 + external/flint-2.4.3/fq_nmod_vec/add.c | 36 + external/flint-2.4.3/fq_nmod_vec/clear.c | 36 + .../fq_nmod_vec/doc/fq_nmod_vec.txt | 168 + external/flint-2.4.3/fq_nmod_vec/dot.c | 36 + external/flint-2.4.3/fq_nmod_vec/equal.c | 36 + external/flint-2.4.3/fq_nmod_vec/fprint.c | 36 + external/flint-2.4.3/fq_nmod_vec/init.c | 36 + external/flint-2.4.3/fq_nmod_vec/is_zero.c | 36 + external/flint-2.4.3/fq_nmod_vec/neg.c | 36 + external/flint-2.4.3/fq_nmod_vec/randtest.c | 36 + .../fq_nmod_vec/scalar_addmul_fq.c | 36 + .../fq_nmod_vec/scalar_submul_fq.c | 36 + external/flint-2.4.3/fq_nmod_vec/set.c | 36 + external/flint-2.4.3/fq_nmod_vec/sub.c | 36 + external/flint-2.4.3/fq_nmod_vec/swap.c | 36 + external/flint-2.4.3/fq_nmod_vec/test/t-add.c | 36 + .../flint-2.4.3/fq_nmod_vec/test/t-is_zero.c | 36 + external/flint-2.4.3/fq_nmod_vec/test/t-neg.c | 36 + external/flint-2.4.3/fq_nmod_vec/test/t-sub.c | 36 + .../flint-2.4.3/fq_nmod_vec/test/t-swap.c | 36 + .../flint-2.4.3/fq_nmod_vec/test/t-zero.c | 36 + external/flint-2.4.3/fq_nmod_vec/zero.c | 36 + external/flint-2.4.3/fq_poly.h | 53 + external/flint-2.4.3/fq_poly/Makefile | 54 + external/flint-2.4.3/fq_poly/add.c | 39 + external/flint-2.4.3/fq_poly/clear.c | 40 + external/flint-2.4.3/fq_poly/compose.c | 39 + .../flint-2.4.3/fq_poly/compose_divconquer.c | 39 + external/flint-2.4.3/fq_poly/compose_horner.c | 39 + external/flint-2.4.3/fq_poly/compose_mod.c | 38 + .../fq_poly/compose_mod_brent_kung.c | 39 + .../compose_mod_brent_kung_precomp_preinv.c | 36 + .../fq_poly/compose_mod_brent_kung_preinv.c | 39 + .../flint-2.4.3/fq_poly/compose_mod_horner.c | 38 + .../fq_poly/compose_mod_horner_preinv.c | 38 + .../flint-2.4.3/fq_poly/compose_mod_preinv.c | 38 + external/flint-2.4.3/fq_poly/deflate.c | 39 + external/flint-2.4.3/fq_poly/deflation.c | 40 + external/flint-2.4.3/fq_poly/derivative.c | 39 + external/flint-2.4.3/fq_poly/div_basecase.c | 40 + .../flint-2.4.3/fq_poly/div_newton_n_preinv.c | 41 + external/flint-2.4.3/fq_poly/divides.c | 39 + .../flint-2.4.3/fq_poly/divrem_basecase.c | 39 + .../flint-2.4.3/fq_poly/divrem_divconquer.c | 38 + .../fq_poly/divrem_divconquer_recursive.c | 38 + .../fq_poly/divrem_newton_n_preinv.c | 40 + external/flint-2.4.3/fq_poly/doc/fq_poly.txt | 1560 + external/flint-2.4.3/fq_poly/equal.c | 40 + external/flint-2.4.3/fq_poly/evaluate_fq.c | 39 + external/flint-2.4.3/fq_poly/fit_length.c | 40 + external/flint-2.4.3/fq_poly/fprint.c | 38 + external/flint-2.4.3/fq_poly/fprint_pretty.c | 39 + external/flint-2.4.3/fq_poly/gcd_euclidean.c | 40 + external/flint-2.4.3/fq_poly/gen.c | 38 + external/flint-2.4.3/fq_poly/get_coeff.c | 41 + external/flint-2.4.3/fq_poly/get_str.c | 37 + external/flint-2.4.3/fq_poly/get_str_pretty.c | 37 + external/flint-2.4.3/fq_poly/hamming_weight.c | 39 + external/flint-2.4.3/fq_poly/inflate.c | 40 + external/flint-2.4.3/fq_poly/init.c | 40 + .../flint-2.4.3/fq_poly/inv_series_newton.c | 39 + external/flint-2.4.3/fq_poly/make_monic.c | 41 + external/flint-2.4.3/fq_poly/mul.c | 41 + external/flint-2.4.3/fq_poly/mul_KS.c | 40 + external/flint-2.4.3/fq_poly/mul_classical.c | 39 + external/flint-2.4.3/fq_poly/mul_reorder.c | 39 + external/flint-2.4.3/fq_poly/mullow.c | 40 + external/flint-2.4.3/fq_poly/mullow_KS.c | 40 + .../flint-2.4.3/fq_poly/mullow_classical.c | 40 + external/flint-2.4.3/fq_poly/mulmod.c | 38 + external/flint-2.4.3/fq_poly/mulmod_preinv.c | 40 + external/flint-2.4.3/fq_poly/neg.c | 39 + external/flint-2.4.3/fq_poly/normalise.c | 40 + external/flint-2.4.3/fq_poly/one.c | 39 + external/flint-2.4.3/fq_poly/pow.c | 39 + .../flint-2.4.3/fq_poly/powmod_fmpz_binexp.c | 38 + .../fq_poly/powmod_fmpz_binexp_preinv.c | 38 + .../fq_poly/powmod_fmpz_sliding_preinv.c | 36 + .../flint-2.4.3/fq_poly/powmod_ui_binexp.c | 38 + .../fq_poly/powmod_ui_binexp_preinv.c | 38 + .../fq_poly/powmod_x_fmpz_preinv.c | 36 + .../fq_poly/profile/p-compose_mod.c | 129 + .../fq_poly/profile/p-compose_mod_preinv.c | 132 + .../fq_poly/profile/p-factor_xnpxp1.c | 36 + .../fq_poly/profile/p-is_irreducible.c | 36 + .../fq_poly/profile/p-iterated_frobenius.c | 36 + .../profile/p-iterated_frobenius_table.c | 36 + .../flint-2.4.3/fq_poly/profile/p-mulmod.c | 167 + external/flint-2.4.3/fq_poly/randtest.c | 40 + .../fq_poly/randtest_irreducible.c | 38 + external/flint-2.4.3/fq_poly/randtest_monic.c | 40 + external/flint-2.4.3/fq_poly/realloc.c | 40 + external/flint-2.4.3/fq_poly/remove.c | 42 + external/flint-2.4.3/fq_poly/reverse.c | 38 + .../flint-2.4.3/fq_poly/scalar_addmul_fq.c | 40 + external/flint-2.4.3/fq_poly/scalar_mul_fq.c | 40 + .../flint-2.4.3/fq_poly/scalar_submul_fq.c | 40 + external/flint-2.4.3/fq_poly/set.c | 41 + external/flint-2.4.3/fq_poly/set_coeff.c | 40 + external/flint-2.4.3/fq_poly/set_fq.c | 39 + external/flint-2.4.3/fq_poly/shift_left.c | 40 + external/flint-2.4.3/fq_poly/shift_right.c | 40 + external/flint-2.4.3/fq_poly/sqr.c | 41 + external/flint-2.4.3/fq_poly/sqr_KS.c | 40 + external/flint-2.4.3/fq_poly/sqr_classical.c | 39 + external/flint-2.4.3/fq_poly/sqr_reorder.c | 39 + external/flint-2.4.3/fq_poly/sub.c | 39 + external/flint-2.4.3/fq_poly/swap.c | 40 + external/flint-2.4.3/fq_poly/test/t-add.c | 40 + external/flint-2.4.3/fq_poly/test/t-compose.c | 39 + .../fq_poly/test/t-compose_divconquer.c | 39 + .../fq_poly/test/t-compose_horner.c | 39 + .../flint-2.4.3/fq_poly/test/t-compose_mod.c | 38 + .../fq_poly/test/t-compose_mod_brent_kung.c | 38 + .../test/t-compose_mod_brent_kung_preinv.c | 38 + .../fq_poly/test/t-compose_mod_horner.c | 38 + .../test/t-compose_mod_horner_preinv.c | 38 + .../fq_poly/test/t-compose_mod_preinv.c | 38 + external/flint-2.4.3/fq_poly/test/t-deflate.c | 39 + .../flint-2.4.3/fq_poly/test/t-derivative.c | 39 + .../flint-2.4.3/fq_poly/test/t-div_basecase.c | 40 + .../fq_poly/test/t-div_newton_n_preinv.c | 40 + external/flint-2.4.3/fq_poly/test/t-divides.c | 39 + .../fq_poly/test/t-divrem_basecase.c | 39 + .../fq_poly/test/t-divrem_divconquer.c | 38 + .../fq_poly/test/t-divrem_newton_n_preinv.c | 40 + .../flint-2.4.3/fq_poly/test/t-evaluate_fq.c | 39 + .../fq_poly/test/t-gcd_euclidean.c | 40 + external/flint-2.4.3/fq_poly/test/t-get_str.c | 38 + .../fq_poly/test/t-get_str_pretty.c | 38 + .../fq_poly/test/t-hamming_weight.c | 40 + external/flint-2.4.3/fq_poly/test/t-inflate.c | 39 + .../fq_poly/test/t-inv_series_newton.c | 40 + .../flint-2.4.3/fq_poly/test/t-make_monic.c | 40 + external/flint-2.4.3/fq_poly/test/t-mul.c | 40 + external/flint-2.4.3/fq_poly/test/t-mul_KS.c | 40 + .../fq_poly/test/t-mul_classical.c | 40 + .../flint-2.4.3/fq_poly/test/t-mul_reorder.c | 40 + external/flint-2.4.3/fq_poly/test/t-mullow.c | 39 + .../flint-2.4.3/fq_poly/test/t-mullow_KS.c | 39 + .../fq_poly/test/t-mullow_classical.c | 39 + external/flint-2.4.3/fq_poly/test/t-mulmod.c | 38 + .../fq_poly/test/t-mulmod_preinv.c | 41 + external/flint-2.4.3/fq_poly/test/t-neg.c | 40 + external/flint-2.4.3/fq_poly/test/t-pow.c | 40 + .../fq_poly/test/t-powmod_fmpz_binexp.c | 38 + .../test/t-powmod_fmpz_binexp_preinv.c | 38 + .../test/t-powmod_fmpz_sliding_preinv.c | 36 + .../fq_poly/test/t-powmod_ui_binexp.c | 38 + .../fq_poly/test/t-powmod_ui_binexp_preinv.c | 38 + .../fq_poly/test/t-powmod_x_fmpz_preinv.c | 36 + .../fq_poly/test/t-randtest_irreducible.c | 36 + .../fq_poly/test/t-scalar_addmul_fq.c | 39 + .../fq_poly/test/t-scalar_mul_fq.c | 39 + .../fq_poly/test/t-scalar_submul_fq.c | 39 + .../fq_poly/test/t-shift_left_right.c | 40 + external/flint-2.4.3/fq_poly/test/t-sqr.c | 40 + external/flint-2.4.3/fq_poly/test/t-sqr_KS.c | 40 + .../fq_poly/test/t-sqr_classical.c | 40 + .../flint-2.4.3/fq_poly/test/t-sqr_reorder.c | 40 + external/flint-2.4.3/fq_poly/test/t-sub.c | 40 + external/flint-2.4.3/fq_poly/truncate.c | 40 + external/flint-2.4.3/fq_poly_factor.h | 53 + external/flint-2.4.3/fq_poly_factor/clear.c | 38 + external/flint-2.4.3/fq_poly_factor/concat.c | 38 + .../fq_poly_factor/doc/fq_poly_factor.txt | 254 + external/flint-2.4.3/fq_poly_factor/factor.c | 42 + .../fq_poly_factor/factor_berlekamp.c | 38 + .../fq_poly_factor/factor_cantor_zassenhaus.c | 39 + .../fq_poly_factor/factor_distinct_deg.c | 37 + .../fq_poly_factor/factor_equal_deg.c | 37 + .../fq_poly_factor/factor_equal_deg_prob.c | 38 + .../fq_poly_factor/factor_kaltofen_shoup.c | 37 + .../fq_poly_factor/factor_squarefree.c | 37 + .../flint-2.4.3/fq_poly_factor/fit_length.c | 38 + external/flint-2.4.3/fq_poly_factor/init.c | 38 + external/flint-2.4.3/fq_poly_factor/insert.c | 38 + .../fq_poly_factor/is_irreducible.c | 38 + .../fq_poly_factor/is_irreducible_ben_or.c | 36 + .../fq_poly_factor/is_irreducible_ddf.c | 38 + .../fq_poly_factor/is_squarefree.c | 38 + .../iterated_frobenius_preinv.c | 36 + external/flint-2.4.3/fq_poly_factor/pow.c | 38 + external/flint-2.4.3/fq_poly_factor/print.c | 38 + .../flint-2.4.3/fq_poly_factor/print_pretty.c | 38 + external/flint-2.4.3/fq_poly_factor/realloc.c | 38 + external/flint-2.4.3/fq_poly_factor/set.c | 38 + .../fq_poly_factor/test/t-factor.c | 42 + .../fq_poly_factor/test/t-factor_berlekamp.c | 38 + .../test/t-factor_cantor_zassenhaus.c | 38 + .../test/t-factor_distinct_deg.c | 38 + .../test/t-factor_equal_deg_prob.c | 38 + .../test/t-factor_kaltofen_shoup.c | 38 + .../fq_poly_factor/test/t-factor_squarefree.c | 38 + .../fq_poly_factor/test/t-is_irreducible.c | 38 + .../test/t-is_irreducible_ben_or.c | 36 + .../test/t-is_irreducible_ddf.c | 38 + .../fq_poly_factor/test/t-is_squarefree.c | 38 + .../test/t-iterated_frobenius_preinv.c | 36 + .../flint-2.4.3/fq_poly_factor_templates.h | 186 + .../fq_poly_factor_templates/clear.c | 53 + .../fq_poly_factor_templates/concat.c | 48 + .../fq_poly_factor_templates/factor.c | 232 + .../factor_berlekamp.c | 320 + .../factor_cantor_zassenhaus.c | 92 + .../factor_distinct_deg.c | 216 + .../factor_equal_deg.c | 76 + .../factor_equal_deg_prob.c | 130 + .../factor_kaltofen_shoup.c | 89 + .../factor_squarefree.c | 180 + .../fq_poly_factor_templates/fit_length.c | 48 + .../fq_poly_factor_templates/init.c | 52 + .../fq_poly_factor_templates/insert.c | 76 + .../fq_poly_factor_templates/is_irreducible.c | 49 + .../is_irreducible_ben_or.c | 110 + .../is_irreducible_ddf.c | 82 + .../fq_poly_factor_templates/is_squarefree.c | 75 + .../iterated_frobenius_preinv.c | 74 + .../fq_poly_factor_templates/pow.c | 47 + .../fq_poly_factor_templates/print.c | 51 + .../fq_poly_factor_templates/print_pretty.c | 47 + .../fq_poly_factor_templates/realloc.c | 91 + .../fq_poly_factor_templates/set.c | 66 + .../fq_poly_factor_templates/test/t-factor.c | 278 + .../test/t-factor_berlekamp.c | 153 + .../test/t-factor_cantor_zassenhaus.c | 152 + .../test/t-factor_distinct_deg.c | 145 + .../test/t-factor_equal_deg_prob.c | 117 + .../test/t-factor_kaltofen_shoup.c | 160 + .../test/t-factor_squarefree.c | 150 + .../test/t-is_irreducible.c | 108 + .../test/t-is_irreducible_ben_or.c | 108 + .../test/t-is_irreducible_ddf.c | 108 + .../test/t-is_squarefree.c | 123 + .../test/t-iterated_frobenius_preinv.c | 114 + external/flint-2.4.3/fq_poly_templates.h | 1135 + external/flint-2.4.3/fq_poly_templates/add.c | 71 + .../flint-2.4.3/fq_poly_templates/clear.c | 44 + .../flint-2.4.3/fq_poly_templates/compose.c | 90 + .../fq_poly_templates/compose_divconquer.c | 204 + .../fq_poly_templates/compose_horner.c | 112 + .../fq_poly_templates/compose_mod.c | 122 + .../compose_mod_brent_kung.c | 193 + .../compose_mod_brent_kung_precomp_preinv.c | 275 + .../compose_mod_brent_kung_preinv.c | 201 + .../fq_poly_templates/compose_mod_horner.c | 155 + .../compose_mod_horner_preinv.c | 164 + .../fq_poly_templates/compose_mod_preinv.c | 131 + .../flint-2.4.3/fq_poly_templates/deflate.c | 61 + .../flint-2.4.3/fq_poly_templates/deflation.c | 65 + .../fq_poly_templates/derivative.c | 64 + .../fq_poly_templates/div_basecase.c | 125 + .../fq_poly_templates/div_newton_n_preinv.c | 105 + .../flint-2.4.3/fq_poly_templates/divides.c | 113 + .../fq_poly_templates/divrem_basecase.c | 127 + .../fq_poly_templates/divrem_divconquer.c | 214 + .../divrem_divconquer_recursive.c | 149 + .../divrem_newton_n_preinv.c | 131 + .../flint-2.4.3/fq_poly_templates/equal.c | 54 + .../fq_poly_templates/evaluate_fq.c | 83 + .../fq_poly_templates/fit_length.c | 47 + .../flint-2.4.3/fq_poly_templates/fprint.c | 70 + .../fq_poly_templates/fprint_pretty.c | 138 + .../fq_poly_templates/gcd_euclidean.c | 166 + external/flint-2.4.3/fq_poly_templates/gen.c | 41 + .../flint-2.4.3/fq_poly_templates/get_coeff.c | 45 + .../flint-2.4.3/fq_poly_templates/get_str.c | 97 + .../fq_poly_templates/get_str_pretty.c | 127 + .../fq_poly_templates/hamming_weight.c | 52 + .../flint-2.4.3/fq_poly_templates/inflate.c | 71 + external/flint-2.4.3/fq_poly_templates/init.c | 51 + .../fq_poly_templates/inv_series_newton.c | 137 + .../fq_poly_templates/make_monic.c | 63 + external/flint-2.4.3/fq_poly_templates/mul.c | 91 + .../flint-2.4.3/fq_poly_templates/mul_KS.c | 111 + .../fq_poly_templates/mul_classical.c | 98 + .../fq_poly_templates/mul_reorder.c | 243 + .../flint-2.4.3/fq_poly_templates/mullow.c | 92 + .../flint-2.4.3/fq_poly_templates/mullow_KS.c | 117 + .../fq_poly_templates/mullow_classical.c | 104 + .../flint-2.4.3/fq_poly_templates/mulmod.c | 117 + .../fq_poly_templates/mulmod_preinv.c | 117 + external/flint-2.4.3/fq_poly_templates/neg.c | 53 + .../flint-2.4.3/fq_poly_templates/normalise.c | 55 + external/flint-2.4.3/fq_poly_templates/one.c | 41 + external/flint-2.4.3/fq_poly_templates/pow.c | 166 + .../fq_poly_templates/powmod_fmpz_binexp.c | 187 + .../powmod_fmpz_binexp_preinv.c | 188 + .../powmod_fmpz_sliding_preinv.c | 274 + .../fq_poly_templates/powmod_ui_binexp.c | 170 + .../powmod_ui_binexp_preinv.c | 170 + .../fq_poly_templates/powmod_x_fmpz_preinv.c | 212 + .../profile/p-factor_xnpxp1.c | 88 + .../profile/p-is_irreducible.c | 129 + .../profile/p-iterated_frobenius.c | 196 + .../profile/p-iterated_frobenius_table.c | 412 + .../fq_poly_templates/profile/p-mullow.c | 136 + .../fq_poly_templates/profile/p-sqr.c | 131 + .../flint-2.4.3/fq_poly_templates/randtest.c | 69 + .../fq_poly_templates/randtest_irreducible.c | 94 + .../fq_poly_templates/randtest_monic.c | 50 + .../flint-2.4.3/fq_poly_templates/realloc.c | 73 + .../flint-2.4.3/fq_poly_templates/remove.c | 64 + .../flint-2.4.3/fq_poly_templates/reverse.c | 83 + .../fq_poly_templates/scalar_addmul_fq.c | 82 + .../fq_poly_templates/scalar_mul_fq.c | 65 + .../fq_poly_templates/scalar_submul_fq.c | 82 + external/flint-2.4.3/fq_poly_templates/set.c | 62 + .../flint-2.4.3/fq_poly_templates/set_coeff.c | 54 + .../flint-2.4.3/fq_poly_templates/set_fq.c | 50 + .../fq_poly_templates/shift_left.c | 78 + .../fq_poly_templates/shift_right.c | 75 + external/flint-2.4.3/fq_poly_templates/sqr.c | 84 + .../flint-2.4.3/fq_poly_templates/sqr_KS.c | 96 + .../fq_poly_templates/sqr_classical.c | 103 + .../fq_poly_templates/sqr_reorder.c | 244 + external/flint-2.4.3/fq_poly_templates/sub.c | 70 + external/flint-2.4.3/fq_poly_templates/swap.c | 57 + .../fq_poly_templates/test/t-add.c | 263 + .../fq_poly_templates/test/t-compose.c | 184 + .../test/t-compose_divconquer.c | 184 + .../fq_poly_templates/test/t-compose_horner.c | 184 + .../fq_poly_templates/test/t-compose_mod.c | 246 + .../test/t-compose_mod_brent_kung.c | 250 + .../test/t-compose_mod_brent_kung_preinv.c | 273 + .../test/t-compose_mod_horner.c | 246 + .../test/t-compose_mod_horner_preinv.c | 265 + .../test/t-compose_mod_preinv.c | 266 + .../fq_poly_templates/test/t-deflate.c | 135 + .../fq_poly_templates/test/t-derivative.c | 185 + .../fq_poly_templates/test/t-div_basecase.c | 174 + .../test/t-div_newton_n_preinv.c | 230 + .../fq_poly_templates/test/t-divides.c | 172 + .../test/t-divrem_basecase.c | 274 + .../test/t-divrem_divconquer.c | 179 + .../test/t-divrem_newton_n_preinv.c | 381 + .../fq_poly_templates/test/t-evaluate_fq.c | 157 + .../fq_poly_templates/test/t-gcd_euclidean.c | 254 + .../fq_poly_templates/test/t-get_str.c | 66 + .../fq_poly_templates/test/t-get_str_pretty.c | 66 + .../fq_poly_templates/test/t-hamming_weight.c | 135 + .../fq_poly_templates/test/t-inflate.c | 108 + .../test/t-inv_series_newton.c | 93 + .../fq_poly_templates/test/t-make_monic.c | 117 + .../fq_poly_templates/test/t-mul.c | 272 + .../fq_poly_templates/test/t-mul_KS.c | 272 + .../fq_poly_templates/test/t-mul_classical.c | 272 + .../fq_poly_templates/test/t-mul_reorder.c | 272 + .../fq_poly_templates/test/t-mullow.c | 100 + .../fq_poly_templates/test/t-mullow_KS.c | 100 + .../test/t-mullow_classical.c | 100 + .../fq_poly_templates/test/t-mulmod.c | 238 + .../fq_poly_templates/test/t-mulmod_preinv.c | 338 + .../fq_poly_templates/test/t-neg.c | 160 + .../fq_poly_templates/test/t-pow.c | 152 + .../test/t-powmod_fmpz_binexp.c | 265 + .../test/t-powmod_fmpz_binexp_preinv.c | 286 + .../test/t-powmod_fmpz_sliding_preinv.c | 304 + .../test/t-powmod_ui_binexp.c | 256 + .../test/t-powmod_ui_binexp_preinv.c | 276 + .../test/t-powmod_x_fmpz_preinv.c | 153 + .../test/t-randtest_irreducible.c | 74 + .../test/t-scalar_addmul_fq.c | 149 + .../fq_poly_templates/test/t-scalar_mul_fq.c | 95 + .../test/t-scalar_submul_fq.c | 149 + .../test/t-shift_left_right.c | 178 + .../fq_poly_templates/test/t-sqr.c | 175 + .../fq_poly_templates/test/t-sqr_KS.c | 175 + .../fq_poly_templates/test/t-sqr_classical.c | 175 + .../fq_poly_templates/test/t-sqr_reorder.c | 175 + .../fq_poly_templates/test/t-sub.c | 215 + .../flint-2.4.3/fq_poly_templates/truncate.c | 49 + .../flint-2.4.3/fq_templates/test/t-add.c | 238 + .../fq_templates/test/t-ctx_init.c | 120 + .../fq_templates/test/t-frobenius.c | 246 + .../flint-2.4.3/fq_templates/test/t-inv.c | 125 + .../flint-2.4.3/fq_templates/test/t-mul.c | 240 + .../fq_templates/test/t-mul_fmpz.c | 128 + .../flint-2.4.3/fq_templates/test/t-mul_si.c | 125 + .../flint-2.4.3/fq_templates/test/t-mul_ui.c | 125 + .../flint-2.4.3/fq_templates/test/t-neg.c | 129 + .../flint-2.4.3/fq_templates/test/t-norm.c | 110 + .../flint-2.4.3/fq_templates/test/t-pow.c | 136 + .../fq_templates/test/t-pth_root.c | 84 + .../flint-2.4.3/fq_templates/test/t-sqr.c | 127 + .../flint-2.4.3/fq_templates/test/t-sub.c | 240 + .../flint-2.4.3/fq_templates/test/t-trace.c | 109 + external/flint-2.4.3/fq_vec.h | 57 + external/flint-2.4.3/fq_vec/add.c | 36 + external/flint-2.4.3/fq_vec/clear.c | 36 + external/flint-2.4.3/fq_vec/doc/fq_vec.txt | 159 + external/flint-2.4.3/fq_vec/dot.c | 36 + external/flint-2.4.3/fq_vec/equal.c | 36 + external/flint-2.4.3/fq_vec/fprint.c | 36 + external/flint-2.4.3/fq_vec/init.c | 36 + external/flint-2.4.3/fq_vec/is_zero.c | 36 + external/flint-2.4.3/fq_vec/neg.c | 36 + external/flint-2.4.3/fq_vec/randtest.c | 36 + .../flint-2.4.3/fq_vec/scalar_addmul_fq.c | 36 + .../flint-2.4.3/fq_vec/scalar_submul_fq.c | 36 + external/flint-2.4.3/fq_vec/set.c | 36 + external/flint-2.4.3/fq_vec/sub.c | 36 + external/flint-2.4.3/fq_vec/swap.c | 36 + external/flint-2.4.3/fq_vec/test/t-add.c | 36 + external/flint-2.4.3/fq_vec/test/t-is_zero.c | 36 + external/flint-2.4.3/fq_vec/test/t-neg.c | 36 + external/flint-2.4.3/fq_vec/test/t-sub.c | 36 + external/flint-2.4.3/fq_vec/test/t-swap.c | 36 + external/flint-2.4.3/fq_vec/test/t-zero.c | 36 + external/flint-2.4.3/fq_vec/zero.c | 36 + external/flint-2.4.3/fq_vec_templates.h | 141 + external/flint-2.4.3/fq_vec_templates/add.c | 44 + external/flint-2.4.3/fq_vec_templates/clear.c | 42 + external/flint-2.4.3/fq_vec_templates/dot.c | 52 + external/flint-2.4.3/fq_vec_templates/equal.c | 49 + .../flint-2.4.3/fq_vec_templates/fprint.c | 72 + external/flint-2.4.3/fq_vec_templates/init.c | 43 + .../flint-2.4.3/fq_vec_templates/is_zero.c | 44 + external/flint-2.4.3/fq_vec_templates/neg.c | 43 + .../flint-2.4.3/fq_vec_templates/randtest.c | 60 + .../fq_vec_templates/scalar_addmul_fq.c | 52 + .../fq_vec_templates/scalar_submul_fq.c | 52 + external/flint-2.4.3/fq_vec_templates/set.c | 43 + external/flint-2.4.3/fq_vec_templates/sub.c | 44 + external/flint-2.4.3/fq_vec_templates/swap.c | 42 + .../flint-2.4.3/fq_vec_templates/test/t-add.c | 121 + .../fq_vec_templates/test/t-is_zero.c | 102 + .../flint-2.4.3/fq_vec_templates/test/t-neg.c | 111 + .../flint-2.4.3/fq_vec_templates/test/t-sub.c | 158 + .../fq_vec_templates/test/t-swap.c | 86 + .../fq_vec_templates/test/t-zero.c | 77 + external/flint-2.4.3/fq_vec_templates/zero.c | 42 + external/flint-2.4.3/fq_zech.h | 321 + external/flint-2.4.3/fq_zech/add.c | 52 + external/flint-2.4.3/fq_zech/bit_pack.c | 38 + external/flint-2.4.3/fq_zech/bit_unpack.c | 39 + external/flint-2.4.3/fq_zech/clear.c | 28 + external/flint-2.4.3/fq_zech/ctx_clear.c | 42 + external/flint-2.4.3/fq_zech/ctx_init.c | 187 + external/flint-2.4.3/fq_zech/ctx_randtest.c | 51 + external/flint-2.4.3/fq_zech/doc/fq_zech.txt | 484 + external/flint-2.4.3/fq_zech/frobenius.c | 53 + external/flint-2.4.3/fq_zech/get_fq_nmod.c | 46 + external/flint-2.4.3/fq_zech/get_str.c | 34 + external/flint-2.4.3/fq_zech/get_str_pretty.c | 36 + external/flint-2.4.3/fq_zech/inv.c | 45 + external/flint-2.4.3/fq_zech/mul.c | 40 + external/flint-2.4.3/fq_zech/mul_fmpz.c | 43 + external/flint-2.4.3/fq_zech/mul_si.c | 49 + external/flint-2.4.3/fq_zech/mul_ui.c | 48 + external/flint-2.4.3/fq_zech/neg.c | 43 + external/flint-2.4.3/fq_zech/norm.c | 38 + external/flint-2.4.3/fq_zech/pow.c | 68 + external/flint-2.4.3/fq_zech/pth_root.c | 51 + external/flint-2.4.3/fq_zech/randtest.c | 39 + external/flint-2.4.3/fq_zech/set_fmpz.c | 43 + external/flint-2.4.3/fq_zech/set_fq_nmod.c | 46 + external/flint-2.4.3/fq_zech/sqr.c | 38 + external/flint-2.4.3/fq_zech/sub.c | 53 + external/flint-2.4.3/fq_zech/sub_one.c | 36 + external/flint-2.4.3/fq_zech/test/t-add.c | 224 + .../flint-2.4.3/fq_zech/test/t-ctx_init.c | 121 + .../flint-2.4.3/fq_zech/test/t-frobenius.c | 122 + .../fq_zech/test/t-get_set_fq_nmod.c | 86 + external/flint-2.4.3/fq_zech/test/t-inv.c | 118 + external/flint-2.4.3/fq_zech/test/t-mul.c | 213 + .../flint-2.4.3/fq_zech/test/t-mul_fmpz.c | 143 + external/flint-2.4.3/fq_zech/test/t-mul_ui.c | 141 + external/flint-2.4.3/fq_zech/test/t-neg.c | 121 + external/flint-2.4.3/fq_zech/test/t-norm.c | 98 + external/flint-2.4.3/fq_zech/test/t-pow.c | 124 + external/flint-2.4.3/fq_zech/test/t-sqr.c | 115 + external/flint-2.4.3/fq_zech/test/t-sub.c | 214 + external/flint-2.4.3/fq_zech/test/t-trace.c | 95 + external/flint-2.4.3/fq_zech/trace.c | 62 + external/flint-2.4.3/fq_zech_mat.h | 53 + external/flint-2.4.3/fq_zech_mat/add.c | 36 + external/flint-2.4.3/fq_zech_mat/clear.c | 36 + .../fq_zech_mat/doc/fq_zech_mat.txt | 442 + external/flint-2.4.3/fq_zech_mat/equal.c | 36 + external/flint-2.4.3/fq_zech_mat/fprint.c | 36 + external/flint-2.4.3/fq_zech_mat/init.c | 36 + external/flint-2.4.3/fq_zech_mat/init_set.c | 36 + external/flint-2.4.3/fq_zech_mat/is_zero.c | 36 + external/flint-2.4.3/fq_zech_mat/lu.c | 36 + .../flint-2.4.3/fq_zech_mat/lu_classical.c | 36 + .../flint-2.4.3/fq_zech_mat/lu_recursive.c | 36 + external/flint-2.4.3/fq_zech_mat/mul.c | 36 + external/flint-2.4.3/fq_zech_mat/mul_KS.c | 36 + .../flint-2.4.3/fq_zech_mat/mul_classical.c | 36 + external/flint-2.4.3/fq_zech_mat/neg.c | 36 + external/flint-2.4.3/fq_zech_mat/randops.c | 36 + .../flint-2.4.3/fq_zech_mat/randpermdiag.c | 36 + external/flint-2.4.3/fq_zech_mat/randrank.c | 36 + external/flint-2.4.3/fq_zech_mat/randtest.c | 36 + external/flint-2.4.3/fq_zech_mat/randtril.c | 36 + external/flint-2.4.3/fq_zech_mat/randtriu.c | 36 + external/flint-2.4.3/fq_zech_mat/rref.c | 36 + external/flint-2.4.3/fq_zech_mat/set.c | 36 + external/flint-2.4.3/fq_zech_mat/solve_tril.c | 36 + .../fq_zech_mat/solve_tril_classical.c | 36 + .../fq_zech_mat/solve_tril_recursive.c | 36 + external/flint-2.4.3/fq_zech_mat/solve_triu.c | 36 + .../fq_zech_mat/solve_triu_classical.c | 36 + .../fq_zech_mat/solve_triu_recursive.c | 36 + external/flint-2.4.3/fq_zech_mat/sub.c | 36 + external/flint-2.4.3/fq_zech_mat/submul.c | 36 + external/flint-2.4.3/fq_zech_mat/swap.c | 36 + .../flint-2.4.3/fq_zech_mat/test/t-add_sub.c | 36 + .../flint-2.4.3/fq_zech_mat/test/t-equal.c | 36 + .../flint-2.4.3/fq_zech_mat/test/t-is_zero.c | 36 + .../fq_zech_mat/test/t-lu_classical.c | 36 + .../fq_zech_mat/test/t-lu_recursive.c | 36 + external/flint-2.4.3/fq_zech_mat/test/t-mul.c | 36 + .../flint-2.4.3/fq_zech_mat/test/t-mul_KS.c | 36 + .../flint-2.4.3/fq_zech_mat/test/t-rref.c | 36 + .../fq_zech_mat/test/t-solve_tril.c | 36 + .../fq_zech_mat/test/t-solve_tril_classical.c | 36 + .../fq_zech_mat/test/t-solve_tril_recursive.c | 36 + .../fq_zech_mat/test/t-solve_triu.c | 36 + .../fq_zech_mat/test/t-solve_triu_classical.c | 36 + .../fq_zech_mat/test/t-solve_triu_recursive.c | 36 + .../flint-2.4.3/fq_zech_mat/test/t-submul.c | 36 + .../flint-2.4.3/fq_zech_mat/test/t-zero.c | 36 + .../flint-2.4.3/fq_zech_mat/window_clear.c | 36 + .../flint-2.4.3/fq_zech_mat/window_init.c | 36 + external/flint-2.4.3/fq_zech_mat/zero.c | 36 + external/flint-2.4.3/fq_zech_poly.h | 51 + external/flint-2.4.3/fq_zech_poly/add.c | 36 + external/flint-2.4.3/fq_zech_poly/clear.c | 36 + external/flint-2.4.3/fq_zech_poly/compose.c | 36 + .../fq_zech_poly/compose_divconquer.c | 36 + .../flint-2.4.3/fq_zech_poly/compose_horner.c | 36 + .../flint-2.4.3/fq_zech_poly/compose_mod.c | 36 + .../fq_zech_poly/compose_mod_brent_kung.c | 36 + .../compose_mod_brent_kung_precomp_preinv.c | 36 + .../compose_mod_brent_kung_preinv.c | 36 + .../fq_zech_poly/compose_mod_horner.c | 36 + .../fq_zech_poly/compose_mod_horner_preinv.c | 36 + .../fq_zech_poly/compose_mod_preinv.c | 36 + external/flint-2.4.3/fq_zech_poly/deflate.c | 36 + external/flint-2.4.3/fq_zech_poly/deflation.c | 36 + .../flint-2.4.3/fq_zech_poly/derivative.c | 36 + .../flint-2.4.3/fq_zech_poly/div_basecase.c | 36 + .../fq_zech_poly/div_newton_n_preinv.c | 36 + external/flint-2.4.3/fq_zech_poly/divides.c | 36 + .../fq_zech_poly/divrem_basecase.c | 36 + .../fq_zech_poly/divrem_divconquer.c | 36 + .../divrem_divconquer_recursive.c | 36 + .../fq_zech_poly/divrem_newton_n_preinv.c | 36 + .../fq_zech_poly/doc/fq_zech_poly.txt | 1596 + external/flint-2.4.3/fq_zech_poly/equal.c | 36 + .../flint-2.4.3/fq_zech_poly/evaluate_fq.c | 36 + .../flint-2.4.3/fq_zech_poly/fit_length.c | 36 + external/flint-2.4.3/fq_zech_poly/fprint.c | 36 + .../flint-2.4.3/fq_zech_poly/fprint_pretty.c | 36 + .../flint-2.4.3/fq_zech_poly/gcd_euclidean.c | 36 + external/flint-2.4.3/fq_zech_poly/gen.c | 36 + external/flint-2.4.3/fq_zech_poly/get_coeff.c | 36 + external/flint-2.4.3/fq_zech_poly/get_str.c | 36 + .../flint-2.4.3/fq_zech_poly/get_str_pretty.c | 36 + .../flint-2.4.3/fq_zech_poly/hamming_weight.c | 36 + external/flint-2.4.3/fq_zech_poly/inflate.c | 36 + external/flint-2.4.3/fq_zech_poly/init.c | 36 + .../fq_zech_poly/inv_series_newton.c | 36 + .../flint-2.4.3/fq_zech_poly/make_monic.c | 36 + external/flint-2.4.3/fq_zech_poly/mul.c | 36 + external/flint-2.4.3/fq_zech_poly/mul_KS.c | 36 + .../flint-2.4.3/fq_zech_poly/mul_classical.c | 36 + external/flint-2.4.3/fq_zech_poly/mullow.c | 36 + external/flint-2.4.3/fq_zech_poly/mullow_KS.c | 36 + .../fq_zech_poly/mullow_classical.c | 36 + external/flint-2.4.3/fq_zech_poly/mulmod.c | 36 + .../flint-2.4.3/fq_zech_poly/mulmod_preinv.c | 36 + external/flint-2.4.3/fq_zech_poly/neg.c | 36 + external/flint-2.4.3/fq_zech_poly/normalise.c | 36 + external/flint-2.4.3/fq_zech_poly/one.c | 36 + external/flint-2.4.3/fq_zech_poly/pow.c | 36 + .../fq_zech_poly/powmod_fmpz_binexp.c | 36 + .../fq_zech_poly/powmod_fmpz_binexp_preinv.c | 36 + .../fq_zech_poly/powmod_fmpz_sliding_preinv.c | 36 + .../fq_zech_poly/powmod_ui_binexp.c | 36 + .../fq_zech_poly/powmod_ui_binexp_preinv.c | 36 + .../fq_zech_poly/powmod_x_fmpz_preinv.c | 36 + .../p-factor_kaltofen_shoup_vs_fq_nmod_poly.c | 155 + .../profile/p-factor_vs_fq_nmod.c | 145 + .../fq_zech_poly/profile/p-factor_xnpxp1.c | 36 + .../fq_zech_poly/profile/p-is_irreducible.c | 36 + .../profile/p-iterated_frobenius.c | 36 + .../profile/p-iterated_frobenius_table.c | 36 + .../fq_zech_poly/profile/p-mullow.c | 36 + .../flint-2.4.3/fq_zech_poly/profile/p-sqr.c | 36 + external/flint-2.4.3/fq_zech_poly/randtest.c | 36 + .../fq_zech_poly/randtest_irreducible.c | 36 + .../flint-2.4.3/fq_zech_poly/randtest_monic.c | 36 + external/flint-2.4.3/fq_zech_poly/realloc.c | 36 + external/flint-2.4.3/fq_zech_poly/remove.c | 36 + external/flint-2.4.3/fq_zech_poly/reverse.c | 36 + .../fq_zech_poly/scalar_addmul_fq.c | 36 + .../flint-2.4.3/fq_zech_poly/scalar_mul_fq.c | 36 + .../fq_zech_poly/scalar_submul_fq.c | 36 + external/flint-2.4.3/fq_zech_poly/set.c | 36 + external/flint-2.4.3/fq_zech_poly/set_coeff.c | 36 + external/flint-2.4.3/fq_zech_poly/set_fq.c | 36 + .../flint-2.4.3/fq_zech_poly/shift_left.c | 36 + .../flint-2.4.3/fq_zech_poly/shift_right.c | 36 + external/flint-2.4.3/fq_zech_poly/sqr.c | 36 + external/flint-2.4.3/fq_zech_poly/sqr_KS.c | 36 + .../flint-2.4.3/fq_zech_poly/sqr_classical.c | 36 + external/flint-2.4.3/fq_zech_poly/sub.c | 36 + external/flint-2.4.3/fq_zech_poly/swap.c | 36 + .../flint-2.4.3/fq_zech_poly/test/t-add.c | 36 + .../flint-2.4.3/fq_zech_poly/test/t-compose.c | 36 + .../fq_zech_poly/test/t-compose_divconquer.c | 36 + .../fq_zech_poly/test/t-compose_horner.c | 36 + .../fq_zech_poly/test/t-compose_mod.c | 36 + .../test/t-compose_mod_brent_kung.c | 36 + .../test/t-compose_mod_brent_kung_preinv.c | 36 + .../fq_zech_poly/test/t-compose_mod_horner.c | 36 + .../test/t-compose_mod_horner_preinv.c | 36 + .../fq_zech_poly/test/t-compose_mod_preinv.c | 36 + .../flint-2.4.3/fq_zech_poly/test/t-deflate.c | 36 + .../fq_zech_poly/test/t-derivative.c | 36 + .../fq_zech_poly/test/t-div_basecase.c | 36 + .../fq_zech_poly/test/t-div_newton_n_preinv.c | 36 + .../flint-2.4.3/fq_zech_poly/test/t-divides.c | 36 + .../fq_zech_poly/test/t-divrem_basecase.c | 36 + .../fq_zech_poly/test/t-divrem_divconquer.c | 36 + .../test/t-divrem_newton_n_preinv.c | 36 + .../fq_zech_poly/test/t-evaluate_fq.c | 36 + .../fq_zech_poly/test/t-gcd_euclidean.c | 36 + .../flint-2.4.3/fq_zech_poly/test/t-get_str.c | 36 + .../fq_zech_poly/test/t-get_str_pretty.c | 36 + .../fq_zech_poly/test/t-hamming_weight.c | 36 + .../flint-2.4.3/fq_zech_poly/test/t-inflate.c | 36 + .../fq_zech_poly/test/t-inv_series_newton.c | 36 + .../fq_zech_poly/test/t-make_monic.c | 36 + .../flint-2.4.3/fq_zech_poly/test/t-mul.c | 36 + .../flint-2.4.3/fq_zech_poly/test/t-mul_KS.c | 36 + .../fq_zech_poly/test/t-mul_classical.c | 36 + .../flint-2.4.3/fq_zech_poly/test/t-mullow.c | 36 + .../fq_zech_poly/test/t-mullow_KS.c | 36 + .../fq_zech_poly/test/t-mullow_classical.c | 36 + .../flint-2.4.3/fq_zech_poly/test/t-mulmod.c | 36 + .../fq_zech_poly/test/t-mulmod_preinv.c | 36 + .../flint-2.4.3/fq_zech_poly/test/t-neg.c | 36 + .../flint-2.4.3/fq_zech_poly/test/t-pow.c | 36 + .../fq_zech_poly/test/t-powmod_fmpz_binexp.c | 36 + .../test/t-powmod_fmpz_binexp_preinv.c | 36 + .../test/t-powmod_fmpz_sliding_preinv.c | 36 + .../fq_zech_poly/test/t-powmod_ui_binexp.c | 36 + .../test/t-powmod_ui_binexp_preinv.c | 36 + .../test/t-powmod_x_fmpz_preinv.c | 36 + .../test/t-randtest_irreducible.c | 36 + .../fq_zech_poly/test/t-scalar_addmul_fq.c | 36 + .../fq_zech_poly/test/t-scalar_mul_fq.c | 36 + .../fq_zech_poly/test/t-scalar_submul_fq.c | 36 + .../fq_zech_poly/test/t-shift_left_right.c | 36 + .../flint-2.4.3/fq_zech_poly/test/t-sqr.c | 36 + .../flint-2.4.3/fq_zech_poly/test/t-sqr_KS.c | 36 + .../fq_zech_poly/test/t-sqr_classical.c | 36 + .../flint-2.4.3/fq_zech_poly/test/t-sub.c | 36 + external/flint-2.4.3/fq_zech_poly/truncate.c | 36 + external/flint-2.4.3/fq_zech_poly_factor.h | 53 + .../flint-2.4.3/fq_zech_poly_factor/clear.c | 36 + .../flint-2.4.3/fq_zech_poly_factor/concat.c | 36 + .../doc/fq_zech_poly_factor.txt | 254 + .../flint-2.4.3/fq_zech_poly_factor/factor.c | 36 + .../fq_zech_poly_factor/factor_berlekamp.c | 36 + .../factor_cantor_zassenhaus.c | 36 + .../fq_zech_poly_factor/factor_distinct_deg.c | 36 + .../fq_zech_poly_factor/factor_equal_deg.c | 36 + .../factor_equal_deg_prob.c | 36 + .../factor_kaltofen_shoup.c | 36 + .../fq_zech_poly_factor/factor_squarefree.c | 36 + .../fq_zech_poly_factor/fit_length.c | 36 + .../flint-2.4.3/fq_zech_poly_factor/init.c | 36 + .../flint-2.4.3/fq_zech_poly_factor/insert.c | 36 + .../fq_zech_poly_factor/is_irreducible.c | 36 + .../is_irreducible_ben_or.c | 36 + .../fq_zech_poly_factor/is_irreducible_ddf.c | 36 + .../fq_zech_poly_factor/is_squarefree.c | 36 + .../iterated_frobenius_preinv.c | 36 + .../flint-2.4.3/fq_zech_poly_factor/pow.c | 36 + .../flint-2.4.3/fq_zech_poly_factor/print.c | 36 + .../fq_zech_poly_factor/print_pretty.c | 36 + .../flint-2.4.3/fq_zech_poly_factor/realloc.c | 36 + .../flint-2.4.3/fq_zech_poly_factor/set.c | 36 + .../fq_zech_poly_factor/test/t-factor.c | 36 + .../test/t-factor_berlekamp.c | 36 + .../test/t-factor_cantor_zassenhaus.c | 36 + .../test/t-factor_distinct_deg.c | 36 + .../test/t-factor_equal_deg_prob.c | 36 + .../test/t-factor_kaltofen_shoup.c | 36 + .../test/t-factor_squarefree.c | 36 + .../test/t-is_irreducible.c | 36 + .../test/t-is_irreducible_ben_or.c | 36 + .../test/t-is_irreducible_ddf.c | 36 + .../test/t-is_squarefree.c | 36 + .../test/t-iterated_frobenius_preinv.c | 36 + external/flint-2.4.3/fq_zech_vec.h | 57 + external/flint-2.4.3/fq_zech_vec/add.c | 36 + external/flint-2.4.3/fq_zech_vec/clear.c | 36 + .../fq_zech_vec/doc/fq_zech_vec.txt | 168 + external/flint-2.4.3/fq_zech_vec/dot.c | 36 + external/flint-2.4.3/fq_zech_vec/equal.c | 36 + external/flint-2.4.3/fq_zech_vec/fprint.c | 36 + external/flint-2.4.3/fq_zech_vec/init.c | 36 + external/flint-2.4.3/fq_zech_vec/is_zero.c | 36 + external/flint-2.4.3/fq_zech_vec/neg.c | 36 + external/flint-2.4.3/fq_zech_vec/randtest.c | 36 + .../fq_zech_vec/scalar_addmul_fq.c | 36 + .../fq_zech_vec/scalar_submul_fq.c | 36 + external/flint-2.4.3/fq_zech_vec/set.c | 36 + external/flint-2.4.3/fq_zech_vec/sub.c | 36 + external/flint-2.4.3/fq_zech_vec/swap.c | 36 + external/flint-2.4.3/fq_zech_vec/test/t-add.c | 36 + .../flint-2.4.3/fq_zech_vec/test/t-is_zero.c | 36 + external/flint-2.4.3/fq_zech_vec/test/t-neg.c | 36 + external/flint-2.4.3/fq_zech_vec/test/t-sub.c | 36 + .../flint-2.4.3/fq_zech_vec/test/t-swap.c | 36 + .../flint-2.4.3/fq_zech_vec/test/t-zero.c | 36 + external/flint-2.4.3/fq_zech_vec/zero.c | 36 + external/flint-2.4.3/fscanf.c | 138 + external/flint-2.4.3/gmpcompat.h | 524 + external/flint-2.4.3/gpl-2.0.txt | 339 + .../flint-2.4.3/interfaces/NTL-interface.cpp | 468 + .../flint-2.4.3/interfaces/doc/interfaces.txt | 117 + .../interfaces/test/t-NTL-interface.cpp | 547 + external/flint-2.4.3/long_extras.h | 53 + .../long_extras/doc/long_extras.txt | 63 + external/flint-2.4.3/long_extras/randint.c | 44 + external/flint-2.4.3/long_extras/randtest.c | 71 + external/flint-2.4.3/long_extras/sizeinbase.c | 63 + .../long_extras/test/t-sizeinbase.c | 78 + external/flint-2.4.3/longlong.h | 533 + external/flint-2.4.3/memory_manager.c | 159 + external/flint-2.4.3/mpfr_mat.h | 57 + external/flint-2.4.3/mpfr_mat/clear.c | 43 + .../flint-2.4.3/mpfr_mat/doc/mpfr_mat.txt | 42 + external/flint-2.4.3/mpfr_mat/init.c | 54 + .../flint-2.4.3/mpfr_mat/test/t-init_clear.c | 65 + external/flint-2.4.3/mpfr_poly.h | 138 + external/flint-2.4.3/mpfr_vec.h | 62 + external/flint-2.4.3/mpfr_vec/add.c | 38 + external/flint-2.4.3/mpfr_vec/clear.c | 39 + .../flint-2.4.3/mpfr_vec/doc/mpfr_vec.txt | 78 + external/flint-2.4.3/mpfr_vec/init.c | 44 + .../flint-2.4.3/mpfr_vec/scalar_mul_2exp.c | 38 + .../flint-2.4.3/mpfr_vec/scalar_mul_mpfr.c | 38 + .../flint-2.4.3/mpfr_vec/scalar_product.c | 48 + external/flint-2.4.3/mpfr_vec/set.c | 38 + .../flint-2.4.3/mpfr_vec/test/t-init_clear.c | 62 + external/flint-2.4.3/mpfr_vec/zero.c | 38 + external/flint-2.4.3/mpn_extras.h | 246 + external/flint-2.4.3/mpn_extras/debug.c | 50 + external/flint-2.4.3/mpn_extras/divides.c | 39 + .../flint-2.4.3/mpn_extras/divrem_preinv1.c | 59 + .../flint-2.4.3/mpn_extras/divrem_preinvn.c | 120 + .../flint-2.4.3/mpn_extras/doc/mpn_extras.txt | 262 + .../flint-2.4.3/mpn_extras/factor_trial.c | 48 + external/flint-2.4.3/mpn_extras/gcd_full.c | 91 + external/flint-2.4.3/mpn_extras/harmonic.c | 190 + external/flint-2.4.3/mpn_extras/mod_preinvn.c | 101 + .../mpn_extras/mulmod_2expp1_basecase.c | 115 + .../flint-2.4.3/mpn_extras/mulmod_preinv1.c | 67 + .../flint-2.4.3/mpn_extras/mulmod_preinvn.c | 64 + external/flint-2.4.3/mpn_extras/preinv1.c | 60 + external/flint-2.4.3/mpn_extras/preinvn.c | 56 + .../mpn_extras/profile/p-mulmod_preinvn.c | 169 + external/flint-2.4.3/mpn_extras/remove_2exp.c | 56 + .../flint-2.4.3/mpn_extras/remove_power.c | 107 + .../flint-2.4.3/mpn_extras/test/t-divides.c | 136 + .../mpn_extras/test/t-divrem_preinv1.c | 118 + .../mpn_extras/test/t-divrem_preinvn.c | 183 + .../flint-2.4.3/mpn_extras/test/t-gcd_full.c | 98 + .../mpn_extras/test/t-mod_preinvn.c | 158 + .../mpn_extras/test/t-mulmod_2expp1.c | 257 + .../mpn_extras/test/t-mulmod_preinv1.c | 118 + .../mpn_extras/test/t-mulmod_preinvn.c | 119 + .../mpn_extras/test/t-remove_2exp.c | 70 + .../mpn_extras/test/t-remove_power.c | 85 + external/flint-2.4.3/nmod_mat.h | 217 + external/flint-2.4.3/nmod_mat/add.c | 44 + external/flint-2.4.3/nmod_mat/addmul.c | 56 + external/flint-2.4.3/nmod_mat/clear.c | 40 + external/flint-2.4.3/nmod_mat/det.c | 86 + .../flint-2.4.3/nmod_mat/doc/nmod_mat.txt | 472 + external/flint-2.4.3/nmod_mat/equal.c | 58 + external/flint-2.4.3/nmod_mat/init.c | 52 + external/flint-2.4.3/nmod_mat/init_set.c | 57 + external/flint-2.4.3/nmod_mat/inv.c | 70 + external/flint-2.4.3/nmod_mat/is_zero.c | 48 + external/flint-2.4.3/nmod_mat/lu.c | 37 + external/flint-2.4.3/nmod_mat/lu_classical.c | 110 + external/flint-2.4.3/nmod_mat/lu_recursive.c | 147 + external/flint-2.4.3/nmod_mat/mul.c | 51 + external/flint-2.4.3/nmod_mat/mul_classical.c | 223 + external/flint-2.4.3/nmod_mat/mul_strassen.c | 169 + external/flint-2.4.3/nmod_mat/neg.c | 42 + external/flint-2.4.3/nmod_mat/nullspace.c | 95 + external/flint-2.4.3/nmod_mat/print_pretty.c | 63 + external/flint-2.4.3/nmod_mat/profile/p-mul.c | 100 + external/flint-2.4.3/nmod_mat/randfull.c | 40 + external/flint-2.4.3/nmod_mat/randops.c | 73 + external/flint-2.4.3/nmod_mat/randpermdiag.c | 55 + external/flint-2.4.3/nmod_mat/randrank.c | 52 + external/flint-2.4.3/nmod_mat/randtest.c | 35 + external/flint-2.4.3/nmod_mat/randtril.c | 56 + external/flint-2.4.3/nmod_mat/randtriu.c | 56 + external/flint-2.4.3/nmod_mat/rank.c | 54 + external/flint-2.4.3/nmod_mat/rref.c | 122 + external/flint-2.4.3/nmod_mat/scalar_mul.c | 56 + external/flint-2.4.3/nmod_mat/set.c | 42 + external/flint-2.4.3/nmod_mat/solve.c | 73 + external/flint-2.4.3/nmod_mat/solve_tril.c | 45 + .../nmod_mat/solve_tril_classical.c | 79 + .../nmod_mat/solve_tril_recursive.c | 75 + external/flint-2.4.3/nmod_mat/solve_triu.c | 45 + .../nmod_mat/solve_triu_classical.c | 80 + .../nmod_mat/solve_triu_recursive.c | 73 + external/flint-2.4.3/nmod_mat/solve_vec.c | 59 + external/flint-2.4.3/nmod_mat/sub.c | 44 + external/flint-2.4.3/nmod_mat/submul.c | 56 + external/flint-2.4.3/nmod_mat/test/t-add.c | 79 + external/flint-2.4.3/nmod_mat/test/t-addmul.c | 116 + external/flint-2.4.3/nmod_mat/test/t-det.c | 100 + .../flint-2.4.3/nmod_mat/test/t-init_clear.c | 79 + external/flint-2.4.3/nmod_mat/test/t-inv.c | 146 + .../nmod_mat/test/t-lu_classical.c | 169 + .../nmod_mat/test/t-lu_recursive.c | 169 + external/flint-2.4.3/nmod_mat/test/t-mul.c | 138 + .../nmod_mat/test/t-mul_strassen.c | 86 + external/flint-2.4.3/nmod_mat/test/t-neg.c | 90 + .../flint-2.4.3/nmod_mat/test/t-nullspace.c | 110 + external/flint-2.4.3/nmod_mat/test/t-rank.c | 100 + external/flint-2.4.3/nmod_mat/test/t-rref.c | 167 + .../flint-2.4.3/nmod_mat/test/t-scalar_mul.c | 96 + external/flint-2.4.3/nmod_mat/test/t-solve.c | 134 + .../flint-2.4.3/nmod_mat/test/t-solve_tril.c | 104 + .../nmod_mat/test/t-solve_tril_classical.c | 104 + .../nmod_mat/test/t-solve_tril_recursive.c | 104 + .../flint-2.4.3/nmod_mat/test/t-solve_triu.c | 104 + .../nmod_mat/test/t-solve_triu_classical.c | 104 + .../nmod_mat/test/t-solve_triu_recursive.c | 104 + .../flint-2.4.3/nmod_mat/test/t-solve_vec.c | 128 + external/flint-2.4.3/nmod_mat/test/t-submul.c | 116 + external/flint-2.4.3/nmod_mat/test/t-trace.c | 91 + .../flint-2.4.3/nmod_mat/test/t-transpose.c | 144 + external/flint-2.4.3/nmod_mat/trace.c | 47 + external/flint-2.4.3/nmod_mat/transpose.c | 62 + external/flint-2.4.3/nmod_mat/window_clear.c | 38 + external/flint-2.4.3/nmod_mat/window_init.c | 49 + external/flint-2.4.3/nmod_mat/zero.c | 45 + external/flint-2.4.3/nmod_matxx.h | 555 + external/flint-2.4.3/nmod_poly.h | 1162 + external/flint-2.4.3/nmod_poly/KS2_pack.c | 163 + external/flint-2.4.3/nmod_poly/KS2_reduce.c | 248 + external/flint-2.4.3/nmod_poly/KS2_unpack.c | 284 + external/flint-2.4.3/nmod_poly/add.c | 63 + external/flint-2.4.3/nmod_poly/asin_series.c | 88 + external/flint-2.4.3/nmod_poly/asinh_series.c | 87 + external/flint-2.4.3/nmod_poly/atan_series.c | 86 + external/flint-2.4.3/nmod_poly/atanh_series.c | 87 + external/flint-2.4.3/nmod_poly/bit_pack.c | 173 + external/flint-2.4.3/nmod_poly/bit_unpack.c | 246 + external/flint-2.4.3/nmod_poly/clear.c | 38 + external/flint-2.4.3/nmod_poly/compose.c | 82 + .../nmod_poly/compose_divconquer.c | 258 + .../flint-2.4.3/nmod_poly/compose_horner.c | 122 + external/flint-2.4.3/nmod_poly/compose_mod.c | 102 + .../nmod_poly/compose_mod_brent_kung.c | 168 + .../compose_mod_brent_kung_precomp_preinv.c | 236 + .../nmod_poly/compose_mod_brent_kung_preinv.c | 173 + .../nmod_poly/compose_mod_horner.c | 133 + .../flint-2.4.3/nmod_poly/compose_series.c | 98 + .../nmod_poly/compose_series_brent_kung.c | 140 + .../nmod_poly/compose_series_divconquer.c | 215 + .../nmod_poly/compose_series_horner.c | 127 + external/flint-2.4.3/nmod_poly/cos_series.c | 90 + external/flint-2.4.3/nmod_poly/cosh_series.c | 99 + external/flint-2.4.3/nmod_poly/deflate.c | 56 + external/flint-2.4.3/nmod_poly/deflation.c | 60 + external/flint-2.4.3/nmod_poly/derivative.c | 63 + external/flint-2.4.3/nmod_poly/div.c | 99 + external/flint-2.4.3/nmod_poly/div_basecase.c | 271 + .../flint-2.4.3/nmod_poly/div_divconquer.c | 162 + .../nmod_poly/div_divconquer_recursive.c | 113 + external/flint-2.4.3/nmod_poly/div_newton.c | 100 + .../nmod_poly/div_newton_n_preinv.c | 106 + external/flint-2.4.3/nmod_poly/div_root.c | 86 + external/flint-2.4.3/nmod_poly/div_series.c | 109 + external/flint-2.4.3/nmod_poly/divrem.c | 120 + .../flint-2.4.3/nmod_poly/divrem_basecase.c | 253 + .../flint-2.4.3/nmod_poly/divrem_divconquer.c | 195 + .../nmod_poly/divrem_divconquer_recursive.c | 141 + .../flint-2.4.3/nmod_poly/divrem_newton.c | 108 + .../nmod_poly/divrem_newton_n_preinv.c | 132 + external/flint-2.4.3/nmod_poly/divrem_q0.c | 50 + external/flint-2.4.3/nmod_poly/divrem_q1.c | 69 + .../flint-2.4.3/nmod_poly/doc/nmod_poly.txt | 2473 ++ .../flint-2.4.3/nmod_poly/evaluate_fmpz.c | 72 + .../flint-2.4.3/nmod_poly/evaluate_nmod.c | 62 + .../flint-2.4.3/nmod_poly/evaluate_nmod_vec.c | 47 + .../nmod_poly/evaluate_nmod_vec_fast.c | 137 + .../nmod_poly/evaluate_nmod_vec_iter.c | 46 + external/flint-2.4.3/nmod_poly/exp_series.c | 215 + .../nmod_poly/exp_series_basecase.c | 89 + .../nmod_poly/exp_series_monomial_ui.c | 116 + external/flint-2.4.3/nmod_poly/fit_length.c | 43 + external/flint-2.4.3/nmod_poly/fread.c | 57 + external/flint-2.4.3/nmod_poly/gcd.c | 90 + .../flint-2.4.3/nmod_poly/gcd_euclidean.c | 149 + external/flint-2.4.3/nmod_poly/gcd_hgcd.c | 156 + external/flint-2.4.3/nmod_poly/gcdinv.c | 132 + external/flint-2.4.3/nmod_poly/get_str.c | 64 + external/flint-2.4.3/nmod_poly/hgcd.c | 507 + external/flint-2.4.3/nmod_poly/inflate.c | 58 + external/flint-2.4.3/nmod_poly/init.c | 50 + external/flint-2.4.3/nmod_poly/init2.c | 55 + external/flint-2.4.3/nmod_poly/integral.c | 94 + .../nmod_poly/interpolate_nmod_vec.c | 61 + .../interpolate_nmod_vec_barycentric.c | 93 + .../nmod_poly/interpolate_nmod_vec_fast.c | 145 + .../nmod_poly/interpolate_nmod_vec_newton.c | 111 + .../nmod_poly/inv_series_basecase.c | 105 + .../flint-2.4.3/nmod_poly/inv_series_newton.c | 130 + external/flint-2.4.3/nmod_poly/invmod.c | 107 + .../flint-2.4.3/nmod_poly/invsqrt_series.c | 130 + external/flint-2.4.3/nmod_poly/log_series.c | 98 + .../nmod_poly/log_series_monomial_ui.c | 109 + external/flint-2.4.3/nmod_poly/make_monic.c | 55 + external/flint-2.4.3/nmod_poly/mul.c | 101 + external/flint-2.4.3/nmod_poly/mul_KS.c | 118 + external/flint-2.4.3/nmod_poly/mul_KS2.c | 255 + external/flint-2.4.3/nmod_poly/mul_KS4.c | 400 + .../flint-2.4.3/nmod_poly/mul_classical.c | 119 + external/flint-2.4.3/nmod_poly/mulhigh.c | 96 + .../flint-2.4.3/nmod_poly/mulhigh_classical.c | 150 + external/flint-2.4.3/nmod_poly/mullow.c | 100 + external/flint-2.4.3/nmod_poly/mullow_KS.c | 120 + .../flint-2.4.3/nmod_poly/mullow_classical.c | 139 + external/flint-2.4.3/nmod_poly/mulmod.c | 102 + .../flint-2.4.3/nmod_poly/mulmod_preinv.c | 121 + external/flint-2.4.3/nmod_poly/neg.c | 41 + external/flint-2.4.3/nmod_poly/pow.c | 88 + external/flint-2.4.3/nmod_poly/pow_binexp.c | 164 + external/flint-2.4.3/nmod_poly/pow_trunc.c | 104 + .../flint-2.4.3/nmod_poly/pow_trunc_binexp.c | 173 + .../flint-2.4.3/nmod_poly/powmod_mpz_binexp.c | 190 + .../nmod_poly/powmod_mpz_binexp_preinv.c | 202 + .../flint-2.4.3/nmod_poly/powmod_ui_binexp.c | 155 + .../nmod_poly/powmod_ui_binexp_preinv.c | 168 + .../nmod_poly/powmod_x_ui_preinv.c | 196 + .../nmod_poly/product_roots_nmod_vec.c | 79 + .../flint-2.4.3/nmod_poly/profile/p-gcd.c | 150 + .../flint-2.4.3/nmod_poly/profile/p-mul.c | 111 + .../flint-2.4.3/nmod_poly/profile/p-mulmod.c | 158 + external/flint-2.4.3/nmod_poly/randtest.c | 156 + external/flint-2.4.3/nmod_poly/realloc.c | 56 + external/flint-2.4.3/nmod_poly/rem.c | 99 + external/flint-2.4.3/nmod_poly/rem_basecase.c | 201 + external/flint-2.4.3/nmod_poly/rem_q1.c | 65 + external/flint-2.4.3/nmod_poly/remove.c | 55 + .../nmod_poly/resultant_euclidean.c | 152 + external/flint-2.4.3/nmod_poly/reverse.c | 66 + .../flint-2.4.3/nmod_poly/revert_series.c | 91 + .../nmod_poly/revert_series_lagrange.c | 114 + .../nmod_poly/revert_series_lagrange_fast.c | 137 + .../nmod_poly/revert_series_newton.c | 129 + .../flint-2.4.3/nmod_poly/scalar_mul_nmod.c | 48 + external/flint-2.4.3/nmod_poly/set_coeff_ui.c | 61 + external/flint-2.4.3/nmod_poly/set_str.c | 64 + external/flint-2.4.3/nmod_poly/shift_left.c | 45 + external/flint-2.4.3/nmod_poly/shift_right.c | 49 + external/flint-2.4.3/nmod_poly/sin_series.c | 87 + external/flint-2.4.3/nmod_poly/sinh_series.c | 97 + external/flint-2.4.3/nmod_poly/sqrt.c | 136 + external/flint-2.4.3/nmod_poly/sqrt_series.c | 99 + external/flint-2.4.3/nmod_poly/sub.c | 66 + external/flint-2.4.3/nmod_poly/tan_series.c | 122 + external/flint-2.4.3/nmod_poly/tanh_series.c | 87 + external/flint-2.4.3/nmod_poly/taylor_shift.c | 47 + .../nmod_poly/taylor_shift_convolution.c | 96 + .../nmod_poly/taylor_shift_horner.c | 61 + external/flint-2.4.3/nmod_poly/test/t-add.c | 107 + .../nmod_poly/test/t-asin_series.c | 126 + .../nmod_poly/test/t-asinh_series.c | 125 + .../nmod_poly/test/t-atan_series.c | 127 + .../nmod_poly/test/t-atanh_series.c | 126 + .../flint-2.4.3/nmod_poly/test/t-bit_pack.c | 137 + .../flint-2.4.3/nmod_poly/test/t-compose.c | 183 + .../nmod_poly/test/t-compose_divconquer.c | 139 + .../nmod_poly/test/t-compose_horner.c | 123 + .../nmod_poly/test/t-compose_mod.c | 185 + .../nmod_poly/test/t-compose_mod_brent_kung.c | 189 + .../t-compose_mod_brent_kung_precomp_preinv.c | 235 + .../test/t-compose_mod_brent_kung_preinv.c | 259 + .../nmod_poly/test/t-compose_mod_horner.c | 185 + .../nmod_poly/test/t-compose_series.c | 157 + .../test/t-compose_series_brent_kung.c | 157 + .../test/t-compose_series_divconquer.c | 145 + .../nmod_poly/test/t-compose_series_horner.c | 157 + .../flint-2.4.3/nmod_poly/test/t-cos_series.c | 128 + .../nmod_poly/test/t-cosh_series.c | 128 + .../flint-2.4.3/nmod_poly/test/t-deflate.c | 121 + .../flint-2.4.3/nmod_poly/test/t-derivative.c | 118 + external/flint-2.4.3/nmod_poly/test/t-div.c | 158 + .../nmod_poly/test/t-div_basecase.c | 168 + .../nmod_poly/test/t-div_divconquer.c | 158 + .../flint-2.4.3/nmod_poly/test/t-div_newton.c | 158 + .../nmod_poly/test/t-div_newton_n_preinv.c | 235 + .../flint-2.4.3/nmod_poly/test/t-div_root.c | 133 + .../flint-2.4.3/nmod_poly/test/t-div_series.c | 168 + .../flint-2.4.3/nmod_poly/test/t-divrem.c | 327 + .../nmod_poly/test/t-divrem_basecase.c | 261 + .../nmod_poly/test/t-divrem_divconquer.c | 241 + .../nmod_poly/test/t-divrem_newton.c | 241 + .../nmod_poly/test/t-divrem_newton_n_preinv.c | 385 + .../nmod_poly/test/t-evaluate_nmod.c | 112 + .../nmod_poly/test/t-evaluate_nmod_vec_fast.c | 90 + .../flint-2.4.3/nmod_poly/test/t-exp_series.c | 147 + .../nmod_poly/test/t-exp_series_basecase.c | 141 + .../nmod_poly/test/t-exp_series_monomial_ui.c | 90 + .../nmod_poly/test/t-fread_print.c | 106 + external/flint-2.4.3/nmod_poly/test/t-gcd.c | 167 + .../nmod_poly/test/t-gcd_euclidean.c | 166 + .../flint-2.4.3/nmod_poly/test/t-gcd_hgcd.c | 168 + .../flint-2.4.3/nmod_poly/test/t-gcdinv.c | 154 + .../nmod_poly/test/t-get_set_coeff_ui.c | 75 + .../nmod_poly/test/t-get_set_str.c | 77 + external/flint-2.4.3/nmod_poly/test/t-hgcd.c | 164 + .../flint-2.4.3/nmod_poly/test/t-inflate.c | 93 + .../nmod_poly/test/t-init_realloc_clear.c | 77 + .../flint-2.4.3/nmod_poly/test/t-integral.c | 114 + .../nmod_poly/test/t-interpolate_nmod_vec.c | 89 + .../test/t-interpolate_nmod_vec_barycentric.c | 91 + .../test/t-interpolate_nmod_vec_fast.c | 89 + .../test/t-interpolate_nmod_vec_newton.c | 91 + .../nmod_poly/test/t-inv_series_basecase.c | 122 + .../nmod_poly/test/t-inv_series_newton.c | 122 + .../flint-2.4.3/nmod_poly/test/t-invmod.c | 221 + .../nmod_poly/test/t-invsqrt_series.c | 125 + .../flint-2.4.3/nmod_poly/test/t-log_series.c | 141 + .../nmod_poly/test/t-log_series_monomial_ui.c | 91 + .../flint-2.4.3/nmod_poly/test/t-make_monic.c | 106 + external/flint-2.4.3/nmod_poly/test/t-mul.c | 147 + .../flint-2.4.3/nmod_poly/test/t-mul_KS.c | 137 + .../flint-2.4.3/nmod_poly/test/t-mul_KS2.c | 170 + .../flint-2.4.3/nmod_poly/test/t-mul_KS4.c | 170 + .../nmod_poly/test/t-mul_classical.c | 147 + .../flint-2.4.3/nmod_poly/test/t-mulhigh.c | 89 + .../nmod_poly/test/t-mulhigh_classical.c | 176 + .../flint-2.4.3/nmod_poly/test/t-mullow.c | 80 + .../flint-2.4.3/nmod_poly/test/t-mullow_KS.c | 149 + .../nmod_poly/test/t-mullow_classical.c | 159 + .../flint-2.4.3/nmod_poly/test/t-mulmod.c | 213 + .../nmod_poly/test/t-mulmod_preinv.c | 301 + external/flint-2.4.3/nmod_poly/test/t-neg.c | 74 + external/flint-2.4.3/nmod_poly/test/t-pow.c | 117 + .../flint-2.4.3/nmod_poly/test/t-pow_binexp.c | 117 + .../flint-2.4.3/nmod_poly/test/t-pow_trunc.c | 120 + .../nmod_poly/test/t-pow_trunc_binexp.c | 120 + .../nmod_poly/test/t-powmod_mpz_binexp.c | 178 + .../test/t-powmod_mpz_binexp_preinv.c | 251 + .../nmod_poly/test/t-powmod_ui_binexp.c | 177 + .../test/t-powmod_ui_binexp_preinv.c | 248 + .../nmod_poly/test/t-powmod_x_ui_binexp.c | 192 + .../nmod_poly/test/t-product_roots_nmod_vec.c | 92 + external/flint-2.4.3/nmod_poly/test/t-rem.c | 203 + .../nmod_poly/test/t-rem_basecase.c | 173 + .../flint-2.4.3/nmod_poly/test/t-resultant.c | 128 + .../nmod_poly/test/t-resultant_euclidean.c | 128 + .../flint-2.4.3/nmod_poly/test/t-reverse.c | 106 + .../nmod_poly/test/t-revert_series.c | 123 + .../nmod_poly/test/t-revert_series_lagrange.c | 124 + .../test/t-revert_series_lagrange_fast.c | 124 + .../nmod_poly/test/t-revert_series_newton.c | 124 + .../nmod_poly/test/t-scalar_mul_nmod.c | 110 + .../nmod_poly/test/t-shift_left_right.c | 108 + .../flint-2.4.3/nmod_poly/test/t-sin_series.c | 119 + .../nmod_poly/test/t-sinh_series.c | 119 + external/flint-2.4.3/nmod_poly/test/t-sqrt.c | 160 + .../nmod_poly/test/t-sqrt_series.c | 123 + external/flint-2.4.3/nmod_poly/test/t-sub.c | 142 + .../flint-2.4.3/nmod_poly/test/t-tan_series.c | 119 + .../nmod_poly/test/t-tanh_series.c | 119 + .../nmod_poly/test/t-taylor_shift.c | 153 + .../test/t-taylor_shift_convolution.c | 123 + .../nmod_poly/test/t-taylor_shift_horner.c | 115 + external/flint-2.4.3/nmod_poly/test/t-xgcd.c | 333 + .../nmod_poly/test/t-xgcd_euclidean.c | 327 + .../flint-2.4.3/nmod_poly/test/t-xgcd_hgcd.c | 332 + external/flint-2.4.3/nmod_poly/tree.c | 123 + external/flint-2.4.3/nmod_poly/xgcd.c | 153 + .../flint-2.4.3/nmod_poly/xgcd_euclidean.c | 247 + external/flint-2.4.3/nmod_poly/xgcd_hgcd.c | 361 + external/flint-2.4.3/nmod_poly_factor.h | 129 + external/flint-2.4.3/nmod_poly_factor/clear.c | 43 + .../flint-2.4.3/nmod_poly_factor/concat.c | 40 + .../nmod_poly_factor/doc/nmod_poly_factor.txt | 218 + .../flint-2.4.3/nmod_poly_factor/factor.c | 191 + .../nmod_poly_factor/factor_berlekamp.c | 238 + .../factor_cantor_zassenhaus.c | 76 + .../nmod_poly_factor/factor_distinct_deg.c | 213 + .../nmod_poly_factor/factor_equal_deg.c | 61 + .../nmod_poly_factor/factor_equal_deg_prob.c | 107 + .../nmod_poly_factor/factor_kaltofen_shoup.c | 82 + .../nmod_poly_factor/factor_squarefree.c | 150 + .../flint-2.4.3/nmod_poly_factor/fit_length.c | 39 + external/flint-2.4.3/nmod_poly_factor/init.c | 46 + .../flint-2.4.3/nmod_poly_factor/insert.c | 67 + .../nmod_poly_factor/is_irreducible.c | 42 + .../nmod_poly_factor/is_irreducible_ddf.c | 140 + .../nmod_poly_factor/is_irreducible_rabin.c | 111 + .../nmod_poly_factor/is_squarefree.c | 60 + external/flint-2.4.3/nmod_poly_factor/pow.c | 39 + external/flint-2.4.3/nmod_poly_factor/print.c | 44 + .../nmod_poly_factor/profile/p-factor.c | 353 + .../nmod_poly_factor/profile/p-factorbench.c | 75 + .../flint-2.4.3/nmod_poly_factor/realloc.c | 77 + external/flint-2.4.3/nmod_poly_factor/set.c | 58 + .../nmod_poly_factor/test/t-factor.c | 271 + .../test/t-factor_berlekamp.c | 110 + .../test/t-factor_cantor_zassenhaus.c | 144 + .../test/t-factor_distinct_deg.c | 130 + .../test/t-factor_kaltofen_shoup.c | 135 + .../test/t-factor_squarefree.c | 140 + .../nmod_poly_factor/test/t-is_irreducible.c | 109 + .../test/t-is_irreducible_ddf.c | 115 + .../test/t-is_irreducible_rabin.c | 118 + .../nmod_poly_factor/test/t-is_squarefree.c | 106 + external/flint-2.4.3/nmod_poly_mat.h | 227 + external/flint-2.4.3/nmod_poly_mat/add.c | 41 + external/flint-2.4.3/nmod_poly_mat/clear.c | 43 + external/flint-2.4.3/nmod_poly_mat/det.c | 62 + external/flint-2.4.3/nmod_poly_mat/det_fflu.c | 52 + .../nmod_poly_mat/det_interpolate.c | 82 + .../nmod_poly_mat/doc/nmod_poly_mat.txt | 471 + external/flint-2.4.3/nmod_poly_mat/equal.c | 44 + .../flint-2.4.3/nmod_poly_mat/evaluate_nmod.c | 41 + external/flint-2.4.3/nmod_poly_mat/fflu.c | 112 + .../nmod_poly_mat/find_pivot_any.c | 43 + .../nmod_poly_mat/find_pivot_partial.c | 56 + external/flint-2.4.3/nmod_poly_mat/init.c | 53 + external/flint-2.4.3/nmod_poly_mat/init_set.c | 35 + external/flint-2.4.3/nmod_poly_mat/inv.c | 104 + external/flint-2.4.3/nmod_poly_mat/is_one.c | 56 + external/flint-2.4.3/nmod_poly_mat/is_zero.c | 44 + .../flint-2.4.3/nmod_poly_mat/max_length.c | 47 + external/flint-2.4.3/nmod_poly_mat/mul.c | 68 + external/flint-2.4.3/nmod_poly_mat/mul_KS.c | 80 + .../flint-2.4.3/nmod_poly_mat/mul_classical.c | 80 + .../nmod_poly_mat/mul_interpolate.c | 157 + external/flint-2.4.3/nmod_poly_mat/neg.c | 39 + .../flint-2.4.3/nmod_poly_mat/nullspace.c | 93 + external/flint-2.4.3/nmod_poly_mat/one.c | 40 + external/flint-2.4.3/nmod_poly_mat/pow.c | 74 + external/flint-2.4.3/nmod_poly_mat/print.c | 51 + external/flint-2.4.3/nmod_poly_mat/randtest.c | 39 + .../nmod_poly_mat/randtest_sparse.c | 53 + external/flint-2.4.3/nmod_poly_mat/rank.c | 47 + external/flint-2.4.3/nmod_poly_mat/rref.c | 111 + .../nmod_poly_mat/scalar_mul_nmod.c | 40 + .../nmod_poly_mat/scalar_mul_nmod_poly.c | 40 + external/flint-2.4.3/nmod_poly_mat/set.c | 42 + external/flint-2.4.3/nmod_poly_mat/solve.c | 36 + .../flint-2.4.3/nmod_poly_mat/solve_fflu.c | 58 + .../nmod_poly_mat/solve_fflu_precomp.c | 102 + external/flint-2.4.3/nmod_poly_mat/sqr.c | 61 + external/flint-2.4.3/nmod_poly_mat/sqr_KS.c | 73 + .../flint-2.4.3/nmod_poly_mat/sqr_classical.c | 78 + .../nmod_poly_mat/sqr_interpolate.c | 138 + external/flint-2.4.3/nmod_poly_mat/sub.c | 42 + external/flint-2.4.3/nmod_poly_mat/swap.c | 42 + .../flint-2.4.3/nmod_poly_mat/test/t-add.c | 183 + .../flint-2.4.3/nmod_poly_mat/test/t-det.c | 110 + .../nmod_poly_mat/test/t-det_interpolate.c | 88 + .../nmod_poly_mat/test/t-init_clear.c | 67 + .../flint-2.4.3/nmod_poly_mat/test/t-inv.c | 164 + .../flint-2.4.3/nmod_poly_mat/test/t-mul.c | 189 + .../flint-2.4.3/nmod_poly_mat/test/t-mul_KS.c | 175 + .../nmod_poly_mat/test/t-mul_interpolate.c | 202 + .../flint-2.4.3/nmod_poly_mat/test/t-neg.c | 130 + .../nmod_poly_mat/test/t-nullspace.c | 100 + .../flint-2.4.3/nmod_poly_mat/test/t-one.c | 91 + .../flint-2.4.3/nmod_poly_mat/test/t-pow.c | 125 + .../flint-2.4.3/nmod_poly_mat/test/t-rank.c | 99 + .../flint-2.4.3/nmod_poly_mat/test/t-rref.c | 180 + .../nmod_poly_mat/test/t-solve_fflu.c | 142 + .../flint-2.4.3/nmod_poly_mat/test/t-sqr.c | 132 + .../flint-2.4.3/nmod_poly_mat/test/t-sqr_KS.c | 122 + .../nmod_poly_mat/test/t-sqr_interpolate.c | 138 + .../flint-2.4.3/nmod_poly_mat/test/t-sub.c | 183 + .../flint-2.4.3/nmod_poly_mat/test/t-trace.c | 99 + .../flint-2.4.3/nmod_poly_mat/test/t-zero.c | 83 + external/flint-2.4.3/nmod_poly_mat/trace.c | 43 + external/flint-2.4.3/nmod_poly_mat/zero.c | 39 + external/flint-2.4.3/nmod_poly_matxx.h | 412 + external/flint-2.4.3/nmod_polyxx.h | 935 + external/flint-2.4.3/nmod_vec.h | 317 + external/flint-2.4.3/nmod_vec/add.c | 46 + .../flint-2.4.3/nmod_vec/doc/nmod_vec.txt | 257 + external/flint-2.4.3/nmod_vec/dot.c | 39 + .../flint-2.4.3/nmod_vec/dot_bound_limbs.c | 45 + external/flint-2.4.3/nmod_vec/dot_ptr.c | 40 + external/flint-2.4.3/nmod_vec/max_bits.c | 48 + external/flint-2.4.3/nmod_vec/neg.c | 37 + .../nmod_vec/profile/p-add_sub_neg.c | 128 + .../flint-2.4.3/nmod_vec/profile/p-reduce.c | 88 + .../nmod_vec/profile/p-scalar_mul.c | 96 + external/flint-2.4.3/nmod_vec/randtest.c | 53 + external/flint-2.4.3/nmod_vec/reduce.c | 37 + .../flint-2.4.3/nmod_vec/scalar_addmul_nmod.c | 46 + .../flint-2.4.3/nmod_vec/scalar_mul_nmod.c | 49 + external/flint-2.4.3/nmod_vec/sub.c | 45 + .../flint-2.4.3/nmod_vec/test/t-add_sub_neg.c | 112 + external/flint-2.4.3/nmod_vec/test/t-dot.c | 99 + .../nmod_vec/test/t-dot_bound_limbs.c | 82 + .../flint-2.4.3/nmod_vec/test/t-dot_ptr.c | 92 + external/flint-2.4.3/nmod_vec/test/t-nmod.c | 263 + external/flint-2.4.3/nmod_vec/test/t-reduce.c | 79 + .../nmod_vec/test/t-scalar_addmul_nmod.c | 83 + .../nmod_vec/test/t-scalar_mul_nmod.c | 84 + external/flint-2.4.3/nmod_vecxx.h | 417 + external/flint-2.4.3/padic.h | 343 + external/flint-2.4.3/padic/add.c | 127 + external/flint-2.4.3/padic/clear.c | 32 + external/flint-2.4.3/padic/ctx_clear.c | 37 + external/flint-2.4.3/padic/ctx_init.c | 63 + external/flint-2.4.3/padic/div.c | 55 + external/flint-2.4.3/padic/doc/padic.txt | 628 + external/flint-2.4.3/padic/exp.c | 98 + external/flint-2.4.3/padic/exp_balanced.c | 263 + external/flint-2.4.3/padic/exp_rectangular.c | 197 + external/flint-2.4.3/padic/fprint.c | 162 + external/flint-2.4.3/padic/get_fmpq.c | 61 + external/flint-2.4.3/padic/get_fmpz.c | 56 + external/flint-2.4.3/padic/get_mpq.c | 37 + external/flint-2.4.3/padic/get_mpz.c | 37 + external/flint-2.4.3/padic/get_str.c | 214 + external/flint-2.4.3/padic/init.c | 41 + external/flint-2.4.3/padic/inv.c | 125 + external/flint-2.4.3/padic/lifts.c | 76 + external/flint-2.4.3/padic/log.c | 162 + external/flint-2.4.3/padic/log_balanced.c | 224 + external/flint-2.4.3/padic/log_rectangular.c | 214 + external/flint-2.4.3/padic/log_satoh.c | 125 + external/flint-2.4.3/padic/mul.c | 44 + external/flint-2.4.3/padic/neg.c | 52 + external/flint-2.4.3/padic/pow_si.c | 62 + .../padic/profile/p-exp_balanced_2.c | 126 + .../padic/profile/p-exp_balanced_p.c | 126 + .../padic/profile/p-exp_rectangular.c | 126 + external/flint-2.4.3/padic/profile/p-inv.c | 123 + .../padic/profile/p-log_balanced.c | 137 + .../padic/profile/p-log_rectangular.c | 137 + external/flint-2.4.3/padic/profile/p-mul.c | 127 + external/flint-2.4.3/padic/profile/p-sqrt.c | 127 + .../flint-2.4.3/padic/profile/p-teichmuller.c | 115 + external/flint-2.4.3/padic/randtest.c | 103 + external/flint-2.4.3/padic/reduce.c | 54 + external/flint-2.4.3/padic/set.c | 38 + external/flint-2.4.3/padic/set_fmpq.c | 57 + external/flint-2.4.3/padic/set_fmpz.c | 40 + external/flint-2.4.3/padic/set_mpq.c | 37 + external/flint-2.4.3/padic/set_mpz.c | 37 + external/flint-2.4.3/padic/set_si.c | 34 + external/flint-2.4.3/padic/set_ui.c | 58 + external/flint-2.4.3/padic/shift.c | 41 + external/flint-2.4.3/padic/sqrt.c | 242 + external/flint-2.4.3/padic/sub.c | 126 + external/flint-2.4.3/padic/teichmuller.c | 123 + external/flint-2.4.3/padic/test/t-add.c | 303 + external/flint-2.4.3/padic/test/t-div.c | 209 + external/flint-2.4.3/padic/test/t-exp.c | 257 + .../flint-2.4.3/padic/test/t-exp_balanced.c | 257 + .../padic/test/t-exp_rectangular.c | 257 + .../flint-2.4.3/padic/test/t-get_set_fmpz.c | 89 + .../flint-2.4.3/padic/test/t-get_set_mpq.c | 90 + .../flint-2.4.3/padic/test/t-get_set_mpz.c | 93 + external/flint-2.4.3/padic/test/t-get_str.c | 89 + external/flint-2.4.3/padic/test/t-inv.c | 238 + external/flint-2.4.3/padic/test/t-log.c | 359 + .../flint-2.4.3/padic/test/t-log_balanced.c | 360 + .../padic/test/t-log_rectangular.c | 359 + external/flint-2.4.3/padic/test/t-log_satoh.c | 360 + external/flint-2.4.3/padic/test/t-mul.c | 311 + external/flint-2.4.3/padic/test/t-neg.c | 161 + external/flint-2.4.3/padic/test/t-pow_si.c | 257 + external/flint-2.4.3/padic/test/t-randtest.c | 142 + external/flint-2.4.3/padic/test/t-shift.c | 152 + external/flint-2.4.3/padic/test/t-sqrt.c | 440 + external/flint-2.4.3/padic/test/t-sub.c | 304 + .../flint-2.4.3/padic/test/t-teichmuller.c | 127 + external/flint-2.4.3/padic/test/t-val_fac.c | 188 + external/flint-2.4.3/padic/val_fac.c | 87 + external/flint-2.4.3/padic_mat.h | 262 + external/flint-2.4.3/padic_mat/Makefile | 54 + external/flint-2.4.3/padic_mat/add.c | 127 + external/flint-2.4.3/padic_mat/canonicalise.c | 131 + external/flint-2.4.3/padic_mat/clear.c | 34 + .../flint-2.4.3/padic_mat/doc/padic_mat.txt | 349 + external/flint-2.4.3/padic_mat/equal.c | 40 + external/flint-2.4.3/padic_mat/fprint.c | 142 + .../flint-2.4.3/padic_mat/fprint_pretty.c | 63 + .../flint-2.4.3/padic_mat/get_entry_padic.c | 37 + external/flint-2.4.3/padic_mat/get_fmpq_mat.c | 63 + external/flint-2.4.3/padic_mat/init.c | 42 + external/flint-2.4.3/padic_mat/is_zero.c | 40 + external/flint-2.4.3/padic_mat/mul.c | 50 + external/flint-2.4.3/padic_mat/neg.c | 43 + external/flint-2.4.3/padic_mat/one.c | 42 + external/flint-2.4.3/padic_mat/randtest.c | 68 + external/flint-2.4.3/padic_mat/reduce.c | 64 + .../flint-2.4.3/padic_mat/scalar_div_fmpz.c | 73 + .../flint-2.4.3/padic_mat/scalar_mul_fmpz.c | 64 + .../flint-2.4.3/padic_mat/scalar_mul_padic.c | 55 + external/flint-2.4.3/padic_mat/set.c | 51 + .../flint-2.4.3/padic_mat/set_entry_padic.c | 69 + external/flint-2.4.3/padic_mat/set_fmpq_mat.c | 94 + external/flint-2.4.3/padic_mat/sub.c | 121 + external/flint-2.4.3/padic_mat/swap.c | 39 + external/flint-2.4.3/padic_mat/test/t-add.c | 259 + .../padic_mat/test/t-get_set_entry_padic.c | 100 + .../padic_mat/test/t-get_set_fmpq_mat.c | 96 + external/flint-2.4.3/padic_mat/test/t-mul.c | 358 + external/flint-2.4.3/padic_mat/test/t-neg.c | 132 + .../padic_mat/test/t-scalar_div_fmpz.c | 97 + .../padic_mat/test/t-scalar_mul_fmpz.c | 97 + .../padic_mat/test/t-scalar_mul_padic.c | 97 + external/flint-2.4.3/padic_mat/test/t-sub.c | 255 + external/flint-2.4.3/padic_mat/transpose.c | 34 + external/flint-2.4.3/padic_mat/zero.c | 34 + external/flint-2.4.3/padic_matxx.h | 349 + external/flint-2.4.3/padic_poly.h | 429 + external/flint-2.4.3/padic_poly/Makefile | 54 + external/flint-2.4.3/padic_poly/add.c | 147 + .../flint-2.4.3/padic_poly/canonicalise.c | 54 + external/flint-2.4.3/padic_poly/clear.c | 42 + external/flint-2.4.3/padic_poly/compose.c | 195 + external/flint-2.4.3/padic_poly/compose_pow.c | 106 + external/flint-2.4.3/padic_poly/derivative.c | 66 + .../flint-2.4.3/padic_poly/doc/padic_poly.txt | 662 + external/flint-2.4.3/padic_poly/equal.c | 42 + .../flint-2.4.3/padic_poly/evaluate_padic.c | 188 + external/flint-2.4.3/padic_poly/fit_length.c | 52 + external/flint-2.4.3/padic_poly/fprint.c | 75 + .../flint-2.4.3/padic_poly/fprint_pretty.c | 174 + .../flint-2.4.3/padic_poly/get_coeff_padic.c | 42 + .../flint-2.4.3/padic_poly/get_fmpq_poly.c | 83 + .../flint-2.4.3/padic_poly/get_fmpz_poly.c | 63 + external/flint-2.4.3/padic_poly/init.c | 50 + external/flint-2.4.3/padic_poly/inv_series.c | 108 + .../flint-2.4.3/padic_poly/is_canonical.c | 47 + external/flint-2.4.3/padic_poly/is_reduced.c | 68 + external/flint-2.4.3/padic_poly/mul.c | 91 + external/flint-2.4.3/padic_poly/neg.c | 64 + external/flint-2.4.3/padic_poly/normalise.c | 38 + external/flint-2.4.3/padic_poly/pow.c | 89 + external/flint-2.4.3/padic_poly/randtest.c | 127 + external/flint-2.4.3/padic_poly/realloc.c | 57 + external/flint-2.4.3/padic_poly/reduce.c | 59 + .../flint-2.4.3/padic_poly/scalar_mul_padic.c | 72 + external/flint-2.4.3/padic_poly/set.c | 69 + .../flint-2.4.3/padic_poly/set_coeff_padic.c | 89 + external/flint-2.4.3/padic_poly/set_fmpq.c | 38 + .../flint-2.4.3/padic_poly/set_fmpq_poly.c | 68 + external/flint-2.4.3/padic_poly/set_fmpz.c | 38 + .../flint-2.4.3/padic_poly/set_fmpz_poly.c | 42 + external/flint-2.4.3/padic_poly/set_padic.c | 61 + external/flint-2.4.3/padic_poly/set_si.c | 37 + external/flint-2.4.3/padic_poly/set_ui.c | 37 + external/flint-2.4.3/padic_poly/shift_left.c | 54 + external/flint-2.4.3/padic_poly/shift_right.c | 50 + external/flint-2.4.3/padic_poly/sub.c | 146 + external/flint-2.4.3/padic_poly/swap.c | 56 + external/flint-2.4.3/padic_poly/test/t-add.c | 193 + .../flint-2.4.3/padic_poly/test/t-compose.c | 138 + .../padic_poly/test/t-compose_pow.c | 140 + .../padic_poly/test/t-derivative.c | 138 + .../padic_poly/test/t-evaluate_padic.c | 135 + .../padic_poly/test/t-get_set_fmpq_poly.c | 90 + .../padic_poly/test/t-init_realloc_clear.c | 98 + .../padic_poly/test/t-inv_series.c | 170 + external/flint-2.4.3/padic_poly/test/t-mul.c | 247 + external/flint-2.4.3/padic_poly/test/t-neg.c | 126 + external/flint-2.4.3/padic_poly/test/t-one.c | 83 + external/flint-2.4.3/padic_poly/test/t-pow.c | 172 + .../padic_poly/test/t-shift_left_right.c | 167 + external/flint-2.4.3/padic_poly/test/t-sub.c | 170 + .../flint-2.4.3/padic_poly/test/t-truncate.c | 142 + external/flint-2.4.3/padic_poly/test/t-zero.c | 82 + external/flint-2.4.3/padic_polyxx.h | 398 + external/flint-2.4.3/padicxx.h | 634 + external/flint-2.4.3/perm.h | 195 + external/flint-2.4.3/perm/doc/perm.txt | 108 + external/flint-2.4.3/perm/parity.c | 61 + external/flint-2.4.3/perm/randtest.c | 50 + external/flint-2.4.3/perm/test/t-compose.c | 111 + external/flint-2.4.3/perm/test/t-inv.c | 102 + external/flint-2.4.3/perm/test/t-parity.c | 86 + external/flint-2.4.3/permxx.h | 114 + external/flint-2.4.3/printf.c | 169 + external/flint-2.4.3/profile/p-udiv_qrnnd.c | 81 + .../flint-2.4.3/profile/p-udiv_qrnnd_preinv.c | 84 + external/flint-2.4.3/profile/timings.txt | 11 + external/flint-2.4.3/profiler.c | 149 + external/flint-2.4.3/profiler.h | 253 + external/flint-2.4.3/qadic.h | 467 + external/flint-2.4.3/qadic/CPimport.txt | 35357 ++++++++++++++++ external/flint-2.4.3/qadic/Makefile | 54 + external/flint-2.4.3/qadic/ctx_clear.c | 37 + external/flint-2.4.3/qadic/ctx_init_conway.c | 144 + external/flint-2.4.3/qadic/doc/qadic.txt | 620 + external/flint-2.4.3/qadic/exp.c | 108 + external/flint-2.4.3/qadic/exp_balanced.c | 235 + external/flint-2.4.3/qadic/exp_rectangular.c | 226 + external/flint-2.4.3/qadic/fprint_pretty.c | 172 + external/flint-2.4.3/qadic/frobenius.c | 361 + external/flint-2.4.3/qadic/inv.c | 189 + external/flint-2.4.3/qadic/log.c | 110 + external/flint-2.4.3/qadic/log_balanced.c | 308 + external/flint-2.4.3/qadic/log_rectangular.c | 240 + external/flint-2.4.3/qadic/mul.c | 97 + external/flint-2.4.3/qadic/norm.c | 113 + external/flint-2.4.3/qadic/norm_analytic.c | 122 + external/flint-2.4.3/qadic/norm_resultant.c | 192 + external/flint-2.4.3/qadic/pow.c | 198 + .../qadic/profile/p-exp_balanced.c | 134 + .../qadic/profile/p-exp_rectangular.c | 134 + .../flint-2.4.3/qadic/profile/p-frobenius.c | 134 + external/flint-2.4.3/qadic/profile/p-inv.c | 134 + .../qadic/profile/p-log_balanced.c | 137 + .../qadic/profile/p-log_rectangular.c | 137 + external/flint-2.4.3/qadic/profile/p-mul.c | 148 + .../qadic/profile/p-norm_analytic.c | 138 + .../qadic/profile/p-norm_resultant.c | 138 + external/flint-2.4.3/qadic/profile/p-sqrt.c | 145 + .../flint-2.4.3/qadic/profile/p-teichmuller.c | 126 + external/flint-2.4.3/qadic/profile/p-trace.c | 135 + external/flint-2.4.3/qadic/set_fmpz_poly.c | 47 + external/flint-2.4.3/qadic/sqrt.c | 850 + external/flint-2.4.3/qadic/teichmuller.c | 177 + external/flint-2.4.3/qadic/test/t-add.c | 269 + external/flint-2.4.3/qadic/test/t-exp.c | 151 + .../flint-2.4.3/qadic/test/t-exp_balanced.c | 151 + .../qadic/test/t-exp_rectangular.c | 151 + external/flint-2.4.3/qadic/test/t-frobenius.c | 274 + external/flint-2.4.3/qadic/test/t-inv.c | 130 + external/flint-2.4.3/qadic/test/t-log.c | 207 + .../flint-2.4.3/qadic/test/t-log_balanced.c | 207 + .../qadic/test/t-log_rectangular.c | 206 + external/flint-2.4.3/qadic/test/t-mul.c | 267 + external/flint-2.4.3/qadic/test/t-neg.c | 137 + external/flint-2.4.3/qadic/test/t-norm.c | 111 + .../flint-2.4.3/qadic/test/t-norm_analytic.c | 113 + .../flint-2.4.3/qadic/test/t-norm_resultant.c | 111 + external/flint-2.4.3/qadic/test/t-pow.c | 143 + external/flint-2.4.3/qadic/test/t-sqrt.c | 723 + external/flint-2.4.3/qadic/test/t-sub.c | 268 + .../flint-2.4.3/qadic/test/t-teichmuller.c | 139 + external/flint-2.4.3/qadic/test/t-trace.c | 111 + external/flint-2.4.3/qadic/trace.c | 90 + external/flint-2.4.3/qadicxx.h | 414 + external/flint-2.4.3/qsieve.h | 309 + external/flint-2.4.3/qsieve/block_lanczos.c | 970 + external/flint-2.4.3/qsieve/doc/qsieve.txt | 42 + external/flint-2.4.3/qsieve/ll_clear.c | 96 + .../flint-2.4.3/qsieve/ll_collect_relations.c | 407 + .../flint-2.4.3/qsieve/ll_compute_poly_data.c | 452 + external/flint-2.4.3/qsieve/ll_factor.c | 285 + external/flint-2.4.3/qsieve/ll_init.c | 77 + .../flint-2.4.3/qsieve/ll_insert_relations.c | 255 + .../flint-2.4.3/qsieve/ll_knuth_schroeppel.c | 141 + external/flint-2.4.3/qsieve/ll_linalg_init.c | 69 + external/flint-2.4.3/qsieve/ll_poly_init.c | 58 + external/flint-2.4.3/qsieve/ll_primes_init.c | 197 + external/flint-2.4.3/qsieve/ll_square_root.c | 93 + .../flint-2.4.3/qsieve/test/t-ll_factor.c | 89 + .../qsieve/test/t-ll_knuth_schroeppel.c | 66 + external/flint-2.4.3/scanf.c | 138 + external/flint-2.4.3/sprintf.c | 125 + external/flint-2.4.3/sscanf.c | 152 + external/flint-2.4.3/templates.h | 47 + external/flint-2.4.3/test/t-add_ssaaaa.c | 71 + external/flint-2.4.3/test/t-add_sssaaaaaa.c | 74 + .../flint-2.4.3/test/t-count_leading_zeros.c | 64 + .../flint-2.4.3/test/t-count_trailing_zeros.c | 64 + external/flint-2.4.3/test/t-sdiv_qrnnd.c | 74 + external/flint-2.4.3/test/t-smul_ppmm.c | 101 + external/flint-2.4.3/test/t-sub_ddmmss.c | 72 + external/flint-2.4.3/test/t-udiv_qrnnd.c | 71 + .../flint-2.4.3/test/t-udiv_qrnnd_preinv.c | 73 + external/flint-2.4.3/test/t-umul_ppmm.c | 81 + external/flint-2.4.3/test_helpers.c | 29 + external/flint-2.4.3/thread_support.c | 39 + external/flint-2.4.3/todo.txt | 357 + external/flint-2.4.3/ulong_extras.h | 381 + .../flint-2.4.3/ulong_extras/cleanup_primes.c | 46 + external/flint-2.4.3/ulong_extras/clog.c | 50 + .../flint-2.4.3/ulong_extras/compute_primes.c | 118 + .../ulong_extras/discrete_log_bsgs.c | 73 + .../ulong_extras/divrem2_precomp.c | 89 + .../ulong_extras/doc/ulong_extras.txt | 1209 + external/flint-2.4.3/ulong_extras/euler_phi.c | 46 + external/flint-2.4.3/ulong_extras/factor.c | 103 + .../flint-2.4.3/ulong_extras/factor_SQUFOF.c | 159 + .../flint-2.4.3/ulong_extras/factor_insert.c | 48 + .../flint-2.4.3/ulong_extras/factor_lehman.c | 79 + .../ulong_extras/factor_one_line.c | 62 + .../flint-2.4.3/ulong_extras/factor_partial.c | 107 + .../ulong_extras/factor_power235.c | 93 + .../flint-2.4.3/ulong_extras/factor_pp1.c | 209 + .../flint-2.4.3/ulong_extras/factor_trial.c | 33 + .../ulong_extras/factor_trial_partial.c | 58 + .../ulong_extras/factor_trial_range.c | 52 + .../ulong_extras/factorial_fast_mod2_preinv.c | 78 + .../ulong_extras/factorial_mod2_preinv.c | 82 + external/flint-2.4.3/ulong_extras/flog.c | 47 + external/flint-2.4.3/ulong_extras/gcd.c | 75 + external/flint-2.4.3/ulong_extras/gcdinv.c | 138 + external/flint-2.4.3/ulong_extras/invmod.c | 136 + .../ulong_extras/is_oddprime_binary.c | 56 + .../ulong_extras/is_oddprime_small.c | 77 + .../ulong_extras/is_perfect_power235.c | 83 + external/flint-2.4.3/ulong_extras/is_prime.c | 45 + .../ulong_extras/is_prime_pocklington.c | 99 + .../ulong_extras/is_prime_pseudosquare.c | 128 + .../flint-2.4.3/ulong_extras/is_probabprime.c | 111 + .../ulong_extras/is_probabprime_BPSW.c | 74 + .../ulong_extras/is_probabprime_fermat.c | 38 + .../ulong_extras/is_probabprime_fibonacci.c | 141 + .../ulong_extras/is_probabprime_lucas.c | 184 + external/flint-2.4.3/ulong_extras/is_square.c | 57 + .../flint-2.4.3/ulong_extras/is_squarefree.c | 32 + .../is_strong_probabprime2_preinv.c | 51 + .../is_strong_probabprime_precomp.c | 51 + external/flint-2.4.3/ulong_extras/jacobi.c | 112 + .../flint-2.4.3/ulong_extras/ll_mod_preinv.c | 103 + .../flint-2.4.3/ulong_extras/lll_mod_preinv.c | 88 + .../flint-2.4.3/ulong_extras/mod2_precomp.c | 67 + .../flint-2.4.3/ulong_extras/mod2_preinv.c | 72 + .../flint-2.4.3/ulong_extras/mod_precomp.c | 39 + .../flint-2.4.3/ulong_extras/moebius_mu.c | 117 + .../flint-2.4.3/ulong_extras/mulmod2_preinv.c | 38 + .../flint-2.4.3/ulong_extras/mulmod_precomp.c | 44 + .../flint-2.4.3/ulong_extras/mulmod_preinv.c | 58 + external/flint-2.4.3/ulong_extras/nextprime.c | 131 + external/flint-2.4.3/ulong_extras/nth_prime.c | 44 + .../ulong_extras/nth_prime_bounds.c | 49 + external/flint-2.4.3/ulong_extras/pow.c | 41 + .../flint-2.4.3/ulong_extras/powmod2_preinv.c | 60 + .../flint-2.4.3/ulong_extras/powmod_precomp.c | 63 + .../prime_inverses_arr_readonly.c | 44 + external/flint-2.4.3/ulong_extras/prime_pi.c | 66 + .../ulong_extras/prime_pi_bounds.c | 38 + .../ulong_extras/primes_arr_readonly.c | 44 + .../flint-2.4.3/ulong_extras/primes_clear.c | 37 + .../ulong_extras/primes_extend_small.c | 55 + .../flint-2.4.3/ulong_extras/primes_init.c | 41 + .../ulong_extras/primes_jump_after.c | 43 + .../ulong_extras/primes_sieve_range.c | 107 + .../ulong_extras/primitive_root_prime.c | 78 + .../ulong_extras/profile/p-factor.c | 107 + .../ulong_extras/profile/p-factor_pp1.c | 72 + .../profile/p-is_probabprime_BPSW.c | 81 + .../ulong_extras/profile/p-lll_mod_preinv.c | 108 + .../ulong_extras/profile/p-mod2_precomp.c | 78 + .../ulong_extras/profile/p-mod2_preinv.c | 183 + .../ulong_extras/profile/p-mod_precomp.c | 76 + .../ulong_extras/profile/p-mulmod2_preinv.c | 75 + .../ulong_extras/profile/p-mulmod_precomp.c | 76 + .../ulong_extras/profile/timings.txt | 172 + external/flint-2.4.3/ulong_extras/randbits.c | 34 + external/flint-2.4.3/ulong_extras/randint.c | 34 + external/flint-2.4.3/ulong_extras/randlimb.c | 50 + external/flint-2.4.3/ulong_extras/randprime.c | 73 + external/flint-2.4.3/ulong_extras/randtest.c | 89 + external/flint-2.4.3/ulong_extras/remove.c | 77 + .../ulong_extras/remove2_precomp.c | 57 + external/flint-2.4.3/ulong_extras/revbin.c | 56 + .../flint-2.4.3/ulong_extras/sizeinbase.c | 40 + external/flint-2.4.3/ulong_extras/sqrt.c | 44 + external/flint-2.4.3/ulong_extras/sqrtmod.c | 92 + .../ulong_extras/sqrtmod_primepow.c | 345 + external/flint-2.4.3/ulong_extras/sqrtmodn.c | 139 + external/flint-2.4.3/ulong_extras/sqrtrem.c | 44 + .../flint-2.4.3/ulong_extras/test/t-addmod.c | 71 + .../flint-2.4.3/ulong_extras/test/t-clog.c | 69 + .../ulong_extras/test/t-compute_primes.c | 88 + .../ulong_extras/test/t-discrete_log_bsgs.c | 65 + .../ulong_extras/test/t-divrem2_precomp.c | 72 + .../ulong_extras/test/t-euler_phi.c | 56 + .../flint-2.4.3/ulong_extras/test/t-factor.c | 95 + .../ulong_extras/test/t-factor_SQUFOF.c | 81 + .../ulong_extras/test/t-factor_lehman.c | 107 + .../ulong_extras/test/t-factor_one_line.c | 84 + .../ulong_extras/test/t-factor_partial.c | 71 + .../ulong_extras/test/t-factor_power235.c | 121 + .../ulong_extras/test/t-factor_pp1.c | 81 + .../ulong_extras/test/t-factor_trial.c | 69 + .../test/t-factor_trial_partial.c | 77 + .../ulong_extras/test/t-factor_trial_range.c | 70 + .../test/t-factorial_fast_mod2_preinv.c | 80 + .../test/t-factorial_mod2_preinv.c | 80 + .../flint-2.4.3/ulong_extras/test/t-flog.c | 69 + .../flint-2.4.3/ulong_extras/test/t-gcd.c | 71 + .../ulong_extras/test/t-gcd_full.c | 71 + .../flint-2.4.3/ulong_extras/test/t-gcdinv.c | 76 + .../flint-2.4.3/ulong_extras/test/t-invmod.c | 70 + .../ulong_extras/test/t-is_oddprime_binary.c | 99 + .../ulong_extras/test/t-is_oddprime_small.c | 96 + .../ulong_extras/test/t-is_perfect_power235.c | 117 + .../ulong_extras/test/t-is_prime.c | 92 + .../test/t-is_prime_pocklington.c | 103 + .../test/t-is_prime_pseudosquare.c | 92 + .../ulong_extras/test/t-is_probabprime.c | 92 + .../ulong_extras/test/t-is_probabprime_BPSW.c | 91 + .../test/t-is_probabprime_fermat.c | 109 + .../test/t-is_probabprime_fibonacci.c | 95 + .../test/t-is_probabprime_lucas.c | 94 + .../ulong_extras/test/t-is_square.c | 80 + .../ulong_extras/test/t-is_squarefree.c | 86 + .../test/t-is_strong_probabprime2_preinv.c | 125 + .../test/t-is_strong_probabprime_precomp.c | 122 + .../flint-2.4.3/ulong_extras/test/t-jacobi.c | 76 + .../ulong_extras/test/t-ll_mod_preinv.c | 70 + .../ulong_extras/test/t-lll_mod_preinv.c | 71 + .../ulong_extras/test/t-mod2_precomp.c | 69 + .../ulong_extras/test/t-mod2_preinv.c | 67 + .../ulong_extras/test/t-mod_precomp.c | 75 + .../ulong_extras/test/t-moebius_mu.c | 96 + .../ulong_extras/test/t-mulmod2_preinv.c | 72 + .../ulong_extras/test/t-mulmod_precomp.c | 74 + .../ulong_extras/test/t-nextprime.c | 90 + .../ulong_extras/test/t-nth_prime_bounds.c | 86 + .../flint-2.4.3/ulong_extras/test/t-pow.c | 71 + .../flint-2.4.3/ulong_extras/test/t-powmod.c | 90 + .../flint-2.4.3/ulong_extras/test/t-powmod2.c | 89 + .../ulong_extras/test/t-powmod2_preinv.c | 90 + .../ulong_extras/test/t-powmod2_ui_preinv.c | 85 + .../ulong_extras/test/t-powmod_precomp.c | 92 + .../ulong_extras/test/t-powmod_ui_precomp.c | 87 + .../ulong_extras/test/t-prime_pi.c | 63 + .../ulong_extras/test/t-prime_pi_bounds.c | 84 + .../flint-2.4.3/ulong_extras/test/t-primes.c | 98 + .../ulong_extras/test/t-primes_jump_after.c | 76 + .../test/t-primitive_root_prime.c | 66 + .../flint-2.4.3/ulong_extras/test/t-remove.c | 122 + .../ulong_extras/test/t-remove2_precomp.c | 126 + .../ulong_extras/test/t-sizeinbase.c | 77 + .../flint-2.4.3/ulong_extras/test/t-sqrt.c | 104 + .../flint-2.4.3/ulong_extras/test/t-sqrtmod.c | 93 + .../ulong_extras/test/t-sqrtmod_primepow.c | 215 + .../ulong_extras/test/t-sqrtmodn.c | 146 + .../flint-2.4.3/ulong_extras/test/t-sqrtrem.c | 110 + .../flint-2.4.3/ulong_extras/test/t-submod.c | 70 + .../flint-2.4.3/ulong_extras/test/t-xgcd.c | 78 + external/flint-2.4.3/ulong_extras/xgcd.c | 172 + external/flint-2.4.3/version.c | 28 + 3752 files changed, 446416 insertions(+) create mode 100644 external/flint-2.4.3/AUTHORS create mode 100644 external/flint-2.4.3/INSTALL create mode 100644 external/flint-2.4.3/Makefile create mode 100644 external/flint-2.4.3/Makefile.in create mode 100644 external/flint-2.4.3/Makefile.subdirs create mode 100644 external/flint-2.4.3/NEWS create mode 100644 external/flint-2.4.3/NTL-interface.h create mode 100644 external/flint-2.4.3/README create mode 100644 external/flint-2.4.3/arith.h create mode 100644 external/flint-2.4.3/arith/bell_number.c create mode 100644 external/flint-2.4.3/arith/bell_number_bsplit.c create mode 100644 external/flint-2.4.3/arith/bell_number_multi_mod.c create mode 100644 external/flint-2.4.3/arith/bell_number_nmod.c create mode 100644 external/flint-2.4.3/arith/bell_number_nmod_vec.c create mode 100644 external/flint-2.4.3/arith/bell_number_nmod_vec_recursive.c create mode 100644 external/flint-2.4.3/arith/bell_number_nmod_vec_series.c create mode 100644 external/flint-2.4.3/arith/bell_number_size.c create mode 100644 external/flint-2.4.3/arith/bell_number_vec.c create mode 100644 external/flint-2.4.3/arith/bell_number_vec_multi_mod.c create mode 100644 external/flint-2.4.3/arith/bell_number_vec_recursive.c create mode 100644 external/flint-2.4.3/arith/bernoulli_number.c create mode 100644 external/flint-2.4.3/arith/bernoulli_number_denom.c create mode 100644 external/flint-2.4.3/arith/bernoulli_number_size.c create mode 100644 external/flint-2.4.3/arith/bernoulli_number_vec.c create mode 100644 external/flint-2.4.3/arith/bernoulli_number_vec_multi_mod.c create mode 100644 external/flint-2.4.3/arith/bernoulli_number_vec_recursive.c create mode 100644 external/flint-2.4.3/arith/bernoulli_number_vec_zeta.c create mode 100644 external/flint-2.4.3/arith/bernoulli_number_zeta.c create mode 100644 external/flint-2.4.3/arith/bernoulli_polynomial.c create mode 100644 external/flint-2.4.3/arith/chebyshev_t_polynomial.c create mode 100644 external/flint-2.4.3/arith/chebyshev_u_polynomial.c create mode 100644 external/flint-2.4.3/arith/cyclotomic_cos_polynomial.c create mode 100644 external/flint-2.4.3/arith/cyclotomic_polynomial.c create mode 100644 external/flint-2.4.3/arith/dedekind_cosine_sum_factored.c create mode 100644 external/flint-2.4.3/arith/dedekind_sum.c create mode 100644 external/flint-2.4.3/arith/dedekind_sum_coprime.c create mode 100644 external/flint-2.4.3/arith/dedekind_sum_coprime_d.c create mode 100644 external/flint-2.4.3/arith/dedekind_sum_coprime_large.c create mode 100644 external/flint-2.4.3/arith/dedekind_sum_naive.c create mode 100644 external/flint-2.4.3/arith/divisor_sigma.c create mode 100644 external/flint-2.4.3/arith/divisors.c create mode 100644 external/flint-2.4.3/arith/doc/arith.txt create mode 100644 external/flint-2.4.3/arith/euler_number.c create mode 100644 external/flint-2.4.3/arith/euler_number_size.c create mode 100644 external/flint-2.4.3/arith/euler_number_vec.c create mode 100644 external/flint-2.4.3/arith/euler_number_zeta.c create mode 100644 external/flint-2.4.3/arith/euler_phi.c create mode 100644 external/flint-2.4.3/arith/euler_polynomial.c create mode 100644 external/flint-2.4.3/arith/harmonic_number.c create mode 100644 external/flint-2.4.3/arith/landau_function_vec.c create mode 100644 external/flint-2.4.3/arith/legendre_polynomial.c create mode 100644 external/flint-2.4.3/arith/moebius_mu.c create mode 100644 external/flint-2.4.3/arith/number_of_partitions.c create mode 100644 external/flint-2.4.3/arith/number_of_partitions_mpfr.c create mode 100644 external/flint-2.4.3/arith/number_of_partitions_nmod_vec.c create mode 100644 external/flint-2.4.3/arith/number_of_partitions_vec.c create mode 100644 external/flint-2.4.3/arith/pi_chudnovsky.c create mode 100644 external/flint-2.4.3/arith/primorial.c create mode 100644 external/flint-2.4.3/arith/profile/p-bernoulli.c create mode 100644 external/flint-2.4.3/arith/ramanujan_tau.c create mode 100644 external/flint-2.4.3/arith/stirling1.c create mode 100644 external/flint-2.4.3/arith/stirling2.c create mode 100644 external/flint-2.4.3/arith/stirlingmat.c create mode 100644 external/flint-2.4.3/arith/sum_of_squares.c create mode 100644 external/flint-2.4.3/arith/sum_of_squares_vec.c create mode 100644 external/flint-2.4.3/arith/swinnerton_dyer_polynomial.c create mode 100644 external/flint-2.4.3/arith/test/t-bell_number.c create mode 100644 external/flint-2.4.3/arith/test/t-bell_number_multi_mod.c create mode 100644 external/flint-2.4.3/arith/test/t-bell_number_nmod.c create mode 100644 external/flint-2.4.3/arith/test/t-bell_number_nmod_vec.c create mode 100644 external/flint-2.4.3/arith/test/t-bell_number_vec.c create mode 100644 external/flint-2.4.3/arith/test/t-bernoulli_number.c create mode 100644 external/flint-2.4.3/arith/test/t-bernoulli_number_denom.c create mode 100644 external/flint-2.4.3/arith/test/t-bernoulli_number_vec.c create mode 100644 external/flint-2.4.3/arith/test/t-bernoulli_polynomial.c create mode 100644 external/flint-2.4.3/arith/test/t-chebyshev_t_polynomial.c create mode 100644 external/flint-2.4.3/arith/test/t-chebyshev_u_polynomial.c create mode 100644 external/flint-2.4.3/arith/test/t-cyclotomic_cos_polynomial.c create mode 100644 external/flint-2.4.3/arith/test/t-cyclotomic_polynomial.c create mode 100644 external/flint-2.4.3/arith/test/t-dedekind_sum.c create mode 100644 external/flint-2.4.3/arith/test/t-dedekind_sum_coprime_d.c create mode 100644 external/flint-2.4.3/arith/test/t-dedekind_sum_coprime_large.c create mode 100644 external/flint-2.4.3/arith/test/t-divisor_sigma.c create mode 100644 external/flint-2.4.3/arith/test/t-divisors.c create mode 100644 external/flint-2.4.3/arith/test/t-euler_number_vec.c create mode 100644 external/flint-2.4.3/arith/test/t-euler_number_zeta.c create mode 100644 external/flint-2.4.3/arith/test/t-euler_phi.c create mode 100644 external/flint-2.4.3/arith/test/t-euler_polynomial.c create mode 100644 external/flint-2.4.3/arith/test/t-harmonic.c create mode 100644 external/flint-2.4.3/arith/test/t-landau_function_vec.c create mode 100644 external/flint-2.4.3/arith/test/t-legendre_polynomial.c create mode 100644 external/flint-2.4.3/arith/test/t-moebius_mu.c create mode 100644 external/flint-2.4.3/arith/test/t-number_of_partitions.c create mode 100644 external/flint-2.4.3/arith/test/t-number_of_partitions_vec.c create mode 100644 external/flint-2.4.3/arith/test/t-pi_chudnovsky.c create mode 100644 external/flint-2.4.3/arith/test/t-primorial.c create mode 100644 external/flint-2.4.3/arith/test/t-ramanujan_tau.c create mode 100644 external/flint-2.4.3/arith/test/t-stirling.c create mode 100644 external/flint-2.4.3/arith/test/t-sum_of_squares.c create mode 100644 external/flint-2.4.3/arith/test/t-swinnerton_dyer_polynomial.c create mode 100644 external/flint-2.4.3/arith/zeta_inv_euler_product.c create mode 100644 external/flint-2.4.3/arithxx.h create mode 100644 external/flint-2.4.3/clz_tab.c create mode 100644 external/flint-2.4.3/code_conventions.txt create mode 100644 external/flint-2.4.3/config.h create mode 100755 external/flint-2.4.3/configure create mode 100644 external/flint-2.4.3/doc/longlong.txt create mode 100644 external/flint-2.4.3/doc/profiler.txt create mode 100644 external/flint-2.4.3/double_extras.h create mode 100644 external/flint-2.4.3/double_extras/doc/double_extras.txt create mode 100644 external/flint-2.4.3/double_extras/lambertw.c create mode 100644 external/flint-2.4.3/double_extras/randtest.c create mode 100644 external/flint-2.4.3/double_extras/test/t-lambertw.c create mode 100644 external/flint-2.4.3/examples/crt.c create mode 100644 external/flint-2.4.3/examples/crt.cpp create mode 100644 external/flint-2.4.3/examples/delta_qexp.c create mode 100644 external/flint-2.4.3/examples/delta_qexp.cpp create mode 100644 external/flint-2.4.3/examples/fmpq_poly.c create mode 100644 external/flint-2.4.3/examples/fmpq_poly.cpp create mode 100644 external/flint-2.4.3/examples/fmpz_mod_poly.c create mode 100644 external/flint-2.4.3/examples/fmpz_mod_poly.cpp create mode 100644 external/flint-2.4.3/examples/fmpz_poly_factor_zassenhaus.c create mode 100644 external/flint-2.4.3/examples/fmpz_poly_factor_zassenhaus.cpp create mode 100644 external/flint-2.4.3/examples/fmpz_poly_hensel_P1 create mode 100644 external/flint-2.4.3/examples/fmpz_poly_q.c create mode 100644 external/flint-2.4.3/examples/fmpz_poly_q.cpp create mode 100644 external/flint-2.4.3/examples/fooxx.cpp create mode 100644 external/flint-2.4.3/examples/fq_poly.c create mode 100644 external/flint-2.4.3/examples/multi_crt.c create mode 100644 external/flint-2.4.3/examples/multi_crt.cpp create mode 100644 external/flint-2.4.3/examples/padic.c create mode 100644 external/flint-2.4.3/examples/padic.cpp create mode 100644 external/flint-2.4.3/examples/partitions.c create mode 100644 external/flint-2.4.3/examples/partitions.cpp create mode 100644 external/flint-2.4.3/examples/primegen.c create mode 100644 external/flint-2.4.3/examples/qadic.c create mode 100644 external/flint-2.4.3/examples/radix.c create mode 100644 external/flint-2.4.3/examples/radix.cpp create mode 100644 external/flint-2.4.3/examples/stirling_matrix.c create mode 100644 external/flint-2.4.3/examples/stirling_matrix.cpp create mode 100644 external/flint-2.4.3/fft.h create mode 100644 external/flint-2.4.3/fft/README create mode 100644 external/flint-2.4.3/fft/adjust.c create mode 100644 external/flint-2.4.3/fft/adjust_sqrt2.c create mode 100644 external/flint-2.4.3/fft/butterfly_lshB.c create mode 100644 external/flint-2.4.3/fft/butterfly_rshB.c create mode 100644 external/flint-2.4.3/fft/combine_bits.c create mode 100644 external/flint-2.4.3/fft/convolution.c create mode 100644 external/flint-2.4.3/fft/div_2expmod_2expp1.c create mode 100644 external/flint-2.4.3/fft/doc/fft.txt create mode 100644 external/flint-2.4.3/fft/fermat_to_mpz.c create mode 100644 external/flint-2.4.3/fft/fft_mfa_truncate_sqrt2.c create mode 100644 external/flint-2.4.3/fft/fft_mfa_truncate_sqrt2_inner.c create mode 100644 external/flint-2.4.3/fft/fft_negacylic.c create mode 100644 external/flint-2.4.3/fft/fft_radix2.c create mode 100644 external/flint-2.4.3/fft/fft_truncate.c create mode 100644 external/flint-2.4.3/fft/fft_truncate_sqrt2.c create mode 100644 external/flint-2.4.3/fft/ifft_mfa_truncate_sqrt2.c create mode 100644 external/flint-2.4.3/fft/ifft_negacyclic.c create mode 100644 external/flint-2.4.3/fft/ifft_radix2.c create mode 100644 external/flint-2.4.3/fft/ifft_truncate.c create mode 100644 external/flint-2.4.3/fft/ifft_truncate_sqrt2.c create mode 100644 external/flint-2.4.3/fft/mul_2expmod_2expp1.c create mode 100644 external/flint-2.4.3/fft/mul_fft_main.c create mode 100644 external/flint-2.4.3/fft/mul_mfa_truncate_sqrt2.c create mode 100644 external/flint-2.4.3/fft/mul_truncate_sqrt2.c create mode 100644 external/flint-2.4.3/fft/mulmod_2expp1.c create mode 100644 external/flint-2.4.3/fft/normmod_2expp1.c create mode 100644 external/flint-2.4.3/fft/profile/p-mul_fft_main.c create mode 100644 external/flint-2.4.3/fft/profile/p-mul_mfa_truncate_sqrt2.c create mode 100644 external/flint-2.4.3/fft/profile/p-mul_truncate_sqrt2.c create mode 100644 external/flint-2.4.3/fft/split_bits.c create mode 100644 external/flint-2.4.3/fft/test/t-adjust.c create mode 100644 external/flint-2.4.3/fft/test/t-adjust_sqrt2.c create mode 100644 external/flint-2.4.3/fft/test/t-butterfly.c create mode 100644 external/flint-2.4.3/fft/test/t-butterfly_lshB.c create mode 100644 external/flint-2.4.3/fft/test/t-butterfly_rshB.c create mode 100644 external/flint-2.4.3/fft/test/t-butterfly_sqrt2.c create mode 100644 external/flint-2.4.3/fft/test/t-butterfly_twiddle.c create mode 100644 external/flint-2.4.3/fft/test/t-div_2expmod_2expp1.c create mode 100644 external/flint-2.4.3/fft/test/t-fft_ifft_mfa_truncate_sqrt2.c create mode 100644 external/flint-2.4.3/fft/test/t-fft_ifft_negacyclic.c create mode 100644 external/flint-2.4.3/fft/test/t-fft_ifft_radix2.c create mode 100644 external/flint-2.4.3/fft/test/t-fft_ifft_truncate.c create mode 100644 external/flint-2.4.3/fft/test/t-fft_ifft_truncate_sqrt2.c create mode 100644 external/flint-2.4.3/fft/test/t-mul_2expmod_2expp1.c create mode 100644 external/flint-2.4.3/fft/test/t-mul_fft_main.c create mode 100644 external/flint-2.4.3/fft/test/t-mul_mfa_truncate_sqrt2.c create mode 100644 external/flint-2.4.3/fft/test/t-mul_truncate_sqrt2.c create mode 100644 external/flint-2.4.3/fft/test/t-mulmod_2expp1.c create mode 100644 external/flint-2.4.3/fft/test/t-normmod_2expp1.c create mode 100644 external/flint-2.4.3/fft/test/t-split_combine_bits.c create mode 100644 external/flint-2.4.3/fft/tune/tune-fft.c create mode 100644 external/flint-2.4.3/fft_tuning.h create mode 100644 external/flint-2.4.3/fft_tuning32.in create mode 100644 external/flint-2.4.3/fft_tuning64.in create mode 100644 external/flint-2.4.3/flint.h create mode 100644 external/flint-2.4.3/flint.supp create mode 100644 external/flint-2.4.3/flintxx.h create mode 100644 external/flint-2.4.3/flintxx/default_rules.h create mode 100644 external/flint-2.4.3/flintxx/doc/Makefile create mode 100644 external/flint-2.4.3/flintxx/doc/design.tex create mode 100644 external/flint-2.4.3/flintxx/doc/flintxx.txt create mode 100644 external/flint-2.4.3/flintxx/doc/genericxx.txt create mode 100644 external/flint-2.4.3/flintxx/dummy.c create mode 100644 external/flint-2.4.3/flintxx/evaluation_tools.h create mode 100644 external/flint-2.4.3/flintxx/expression.h create mode 100644 external/flint-2.4.3/flintxx/expression_traits.h create mode 100644 external/flint-2.4.3/flintxx/flint_classes.h create mode 100644 external/flint-2.4.3/flintxx/flint_exception.h create mode 100644 external/flint-2.4.3/flintxx/forwarding.h create mode 100644 external/flint-2.4.3/flintxx/frandxx.h create mode 100644 external/flint-2.4.3/flintxx/ltuple.h create mode 100644 external/flint-2.4.3/flintxx/matrix.h create mode 100644 external/flint-2.4.3/flintxx/mp.h create mode 100644 external/flint-2.4.3/flintxx/rules.h create mode 100644 external/flint-2.4.3/flintxx/stdmath.h create mode 100644 external/flint-2.4.3/flintxx/test/helpers.h create mode 100755 external/flint-2.4.3/flintxx/test/make-compiler-errors-report.sh create mode 100644 external/flint-2.4.3/flintxx/test/myint.h create mode 100644 external/flint-2.4.3/flintxx/test/t-arithxx.cpp create mode 100644 external/flint-2.4.3/flintxx/test/t-codegen.cpp create mode 100644 external/flint-2.4.3/flintxx/test/t-compiler-errors.cc create mode 100644 external/flint-2.4.3/flintxx/test/t-expression.cpp create mode 100644 external/flint-2.4.3/flintxx/test/t-flint_classes.cpp create mode 100644 external/flint-2.4.3/flintxx/test/t-fmpq_matxx.cpp create mode 100644 external/flint-2.4.3/flintxx/test/t-fmpq_polyxx.cpp create mode 100644 external/flint-2.4.3/flintxx/test/t-fmpqxx.cpp create mode 100644 external/flint-2.4.3/flintxx/test/t-fmpz_matxx.cpp create mode 100644 external/flint-2.4.3/flintxx/test/t-fmpz_mod_polyxx.cpp create mode 100644 external/flint-2.4.3/flintxx/test/t-fmpz_poly_matxx.cpp create mode 100644 external/flint-2.4.3/flintxx/test/t-fmpz_poly_qxx.cpp create mode 100644 external/flint-2.4.3/flintxx/test/t-fmpz_polyxx.cpp create mode 100644 external/flint-2.4.3/flintxx/test/t-fmpzxx.cpp create mode 100644 external/flint-2.4.3/flintxx/test/t-forwarding.cpp create mode 100644 external/flint-2.4.3/flintxx/test/t-ltuple.cpp create mode 100644 external/flint-2.4.3/flintxx/test/t-mp.cpp create mode 100644 external/flint-2.4.3/flintxx/test/t-nmod_matxx.cpp create mode 100644 external/flint-2.4.3/flintxx/test/t-nmod_poly_matxx.cpp create mode 100644 external/flint-2.4.3/flintxx/test/t-nmod_polyxx.cpp create mode 100644 external/flint-2.4.3/flintxx/test/t-nmod_vecxx.cpp create mode 100644 external/flint-2.4.3/flintxx/test/t-padic_matxx.cpp create mode 100644 external/flint-2.4.3/flintxx/test/t-padic_polyxx.cpp create mode 100644 external/flint-2.4.3/flintxx/test/t-padicxx.cpp create mode 100644 external/flint-2.4.3/flintxx/test/t-permxx.cpp create mode 100644 external/flint-2.4.3/flintxx/test/t-qadicxx.cpp create mode 100644 external/flint-2.4.3/flintxx/test/t-traits.cpp create mode 100644 external/flint-2.4.3/flintxx/test/t-tuple.cpp create mode 100644 external/flint-2.4.3/flintxx/test/t-vector.cpp create mode 100644 external/flint-2.4.3/flintxx/traits.h create mode 100644 external/flint-2.4.3/flintxx/traits_fwd.h create mode 100644 external/flint-2.4.3/flintxx/tuple.h create mode 100644 external/flint-2.4.3/flintxx/vector.h create mode 100644 external/flint-2.4.3/fmpq.h create mode 100644 external/flint-2.4.3/fmpq/add.c create mode 100644 external/flint-2.4.3/fmpq/addmul.c create mode 100644 external/flint-2.4.3/fmpq/canonicalise.c create mode 100644 external/flint-2.4.3/fmpq/cfrac_bound.c create mode 100644 external/flint-2.4.3/fmpq/clear_readonly.c create mode 100644 external/flint-2.4.3/fmpq/cmp.c create mode 100644 external/flint-2.4.3/fmpq/div.c create mode 100644 external/flint-2.4.3/fmpq/div_2exp.c create mode 100644 external/flint-2.4.3/fmpq/div_fmpz.c create mode 100644 external/flint-2.4.3/fmpq/doc/fmpq.txt create mode 100644 external/flint-2.4.3/fmpq/fprint.c create mode 100644 external/flint-2.4.3/fmpq/get_cfrac.c create mode 100644 external/flint-2.4.3/fmpq/get_mpfr.c create mode 100644 external/flint-2.4.3/fmpq/get_str.c create mode 100644 external/flint-2.4.3/fmpq/height.c create mode 100644 external/flint-2.4.3/fmpq/height_bits.c create mode 100644 external/flint-2.4.3/fmpq/init_set_readonly.c create mode 100644 external/flint-2.4.3/fmpq/inv.c create mode 100644 external/flint-2.4.3/fmpq/is_canonical.c create mode 100644 external/flint-2.4.3/fmpq/mod_fmpz.c create mode 100644 external/flint-2.4.3/fmpq/mpq_clear_readonly.c create mode 100644 external/flint-2.4.3/fmpq/mpq_init_set_readonly.c create mode 100644 external/flint-2.4.3/fmpq/mul.c create mode 100644 external/flint-2.4.3/fmpq/mul_2exp.c create mode 100644 external/flint-2.4.3/fmpq/mul_fmpz.c create mode 100644 external/flint-2.4.3/fmpq/next_calkin_wilf.c create mode 100644 external/flint-2.4.3/fmpq/next_minimal.c create mode 100644 external/flint-2.4.3/fmpq/next_signed_calkin_wilf.c create mode 100644 external/flint-2.4.3/fmpq/next_signed_minimal.c create mode 100644 external/flint-2.4.3/fmpq/pow_si.c create mode 100644 external/flint-2.4.3/fmpq/randbits.c create mode 100644 external/flint-2.4.3/fmpq/randtest.c create mode 100644 external/flint-2.4.3/fmpq/reconstruct_fmpz.c create mode 100644 external/flint-2.4.3/fmpq/set_cfrac.c create mode 100644 external/flint-2.4.3/fmpq/set_fmpz_frac.c create mode 100644 external/flint-2.4.3/fmpq/set_si.c create mode 100644 external/flint-2.4.3/fmpq/sub.c create mode 100644 external/flint-2.4.3/fmpq/submul.c create mode 100644 external/flint-2.4.3/fmpq/test/t-abs.c create mode 100644 external/flint-2.4.3/fmpq/test/t-add.c create mode 100644 external/flint-2.4.3/fmpq/test/t-addmul.c create mode 100644 external/flint-2.4.3/fmpq/test/t-canonicalise.c create mode 100644 external/flint-2.4.3/fmpq/test/t-cfrac_bound.c create mode 100644 external/flint-2.4.3/fmpq/test/t-cmp.c create mode 100644 external/flint-2.4.3/fmpq/test/t-div.c create mode 100644 external/flint-2.4.3/fmpq/test/t-div_2exp.c create mode 100644 external/flint-2.4.3/fmpq/test/t-div_fmpz.c create mode 100644 external/flint-2.4.3/fmpq/test/t-get_cfrac.c create mode 100644 external/flint-2.4.3/fmpq/test/t-get_mpfr.c create mode 100644 external/flint-2.4.3/fmpq/test/t-get_str.c create mode 100644 external/flint-2.4.3/fmpq/test/t-height.c create mode 100644 external/flint-2.4.3/fmpq/test/t-init_set_readonly.c create mode 100644 external/flint-2.4.3/fmpq/test/t-inv.c create mode 100644 external/flint-2.4.3/fmpq/test/t-mpq_init_set_readonly.c create mode 100644 external/flint-2.4.3/fmpq/test/t-mul.c create mode 100644 external/flint-2.4.3/fmpq/test/t-mul_2exp.c create mode 100644 external/flint-2.4.3/fmpq/test/t-mul_fmpz.c create mode 100644 external/flint-2.4.3/fmpq/test/t-next_calkin_wilf.c create mode 100644 external/flint-2.4.3/fmpq/test/t-next_minimal.c create mode 100644 external/flint-2.4.3/fmpq/test/t-one.c create mode 100644 external/flint-2.4.3/fmpq/test/t-pow_si.c create mode 100644 external/flint-2.4.3/fmpq/test/t-reconstruct_fmpz.c create mode 100644 external/flint-2.4.3/fmpq/test/t-reconstruct_fmpz_2.c create mode 100644 external/flint-2.4.3/fmpq/test/t-set_cfrac.c create mode 100644 external/flint-2.4.3/fmpq/test/t-set_fmpz_frac.c create mode 100644 external/flint-2.4.3/fmpq/test/t-set_si.c create mode 100644 external/flint-2.4.3/fmpq/test/t-sub.c create mode 100644 external/flint-2.4.3/fmpq/test/t-submul.c create mode 100644 external/flint-2.4.3/fmpq_mat.h create mode 100644 external/flint-2.4.3/fmpq_mat/add.c create mode 100644 external/flint-2.4.3/fmpq_mat/clear.c create mode 100644 external/flint-2.4.3/fmpq_mat/det.c create mode 100644 external/flint-2.4.3/fmpq_mat/doc/fmpq_mat.txt create mode 100644 external/flint-2.4.3/fmpq_mat/equal.c create mode 100644 external/flint-2.4.3/fmpq_mat/get_fmpz_mat.c create mode 100644 external/flint-2.4.3/fmpq_mat/get_fmpz_mat_colwise.c create mode 100644 external/flint-2.4.3/fmpq_mat/get_fmpz_mat_entrywise.c create mode 100644 external/flint-2.4.3/fmpq_mat/get_fmpz_mat_matwise.c create mode 100644 external/flint-2.4.3/fmpq_mat/get_fmpz_mat_mod_fmpz.c create mode 100644 external/flint-2.4.3/fmpq_mat/get_fmpz_mat_rowwise.c create mode 100644 external/flint-2.4.3/fmpq_mat/hilbert_matrix.c create mode 100644 external/flint-2.4.3/fmpq_mat/init.c create mode 100644 external/flint-2.4.3/fmpq_mat/inv.c create mode 100644 external/flint-2.4.3/fmpq_mat/is_integral.c create mode 100644 external/flint-2.4.3/fmpq_mat/is_zero.c create mode 100644 external/flint-2.4.3/fmpq_mat/mul.c create mode 100644 external/flint-2.4.3/fmpq_mat/mul_cleared.c create mode 100644 external/flint-2.4.3/fmpq_mat/mul_direct.c create mode 100644 external/flint-2.4.3/fmpq_mat/mul_fmpz_mat.c create mode 100644 external/flint-2.4.3/fmpq_mat/mul_r_fmpz_mat.c create mode 100644 external/flint-2.4.3/fmpq_mat/neg.c create mode 100644 external/flint-2.4.3/fmpq_mat/one.c create mode 100644 external/flint-2.4.3/fmpq_mat/pivot.c create mode 100644 external/flint-2.4.3/fmpq_mat/print.c create mode 100644 external/flint-2.4.3/fmpq_mat/randbits.c create mode 100644 external/flint-2.4.3/fmpq_mat/randtest.c create mode 100644 external/flint-2.4.3/fmpq_mat/rref.c create mode 100644 external/flint-2.4.3/fmpq_mat/rref_classical.c create mode 100644 external/flint-2.4.3/fmpq_mat/rref_fraction_free.c create mode 100644 external/flint-2.4.3/fmpq_mat/scalar_div_fmpz.c create mode 100644 external/flint-2.4.3/fmpq_mat/scalar_mul_fmpz.c create mode 100644 external/flint-2.4.3/fmpq_mat/set.c create mode 100644 external/flint-2.4.3/fmpq_mat/set_fmpz_mat.c create mode 100644 external/flint-2.4.3/fmpq_mat/set_fmpz_mat_div_fmpz.c create mode 100644 external/flint-2.4.3/fmpq_mat/set_fmpz_mat_mod_fmpz.c create mode 100644 external/flint-2.4.3/fmpq_mat/solve_dixon.c create mode 100644 external/flint-2.4.3/fmpq_mat/solve_fraction_free.c create mode 100644 external/flint-2.4.3/fmpq_mat/sub.c create mode 100644 external/flint-2.4.3/fmpq_mat/test/t-add.c create mode 100644 external/flint-2.4.3/fmpq_mat/test/t-det.c create mode 100644 external/flint-2.4.3/fmpq_mat/test/t-init_clear.c create mode 100644 external/flint-2.4.3/fmpq_mat/test/t-inv.c create mode 100644 external/flint-2.4.3/fmpq_mat/test/t-is_integral.c create mode 100644 external/flint-2.4.3/fmpq_mat/test/t-mul.c create mode 100644 external/flint-2.4.3/fmpq_mat/test/t-neg.c create mode 100644 external/flint-2.4.3/fmpq_mat/test/t-one.c create mode 100644 external/flint-2.4.3/fmpq_mat/test/t-rref.c create mode 100644 external/flint-2.4.3/fmpq_mat/test/t-scalar_div_fmpz.c create mode 100644 external/flint-2.4.3/fmpq_mat/test/t-scalar_mul_fmpz.c create mode 100644 external/flint-2.4.3/fmpq_mat/test/t-solve_dixon.c create mode 100644 external/flint-2.4.3/fmpq_mat/test/t-solve_fraction_free.c create mode 100644 external/flint-2.4.3/fmpq_mat/test/t-sub.c create mode 100644 external/flint-2.4.3/fmpq_mat/test/t-trace.c create mode 100644 external/flint-2.4.3/fmpq_mat/test/t-transpose.c create mode 100644 external/flint-2.4.3/fmpq_mat/trace.c create mode 100644 external/flint-2.4.3/fmpq_mat/transpose.c create mode 100644 external/flint-2.4.3/fmpq_mat/zero.c create mode 100644 external/flint-2.4.3/fmpq_matxx.h create mode 100644 external/flint-2.4.3/fmpq_poly.h create mode 100644 external/flint-2.4.3/fmpq_poly/add.c create mode 100644 external/flint-2.4.3/fmpq_poly/asin_series.c create mode 100644 external/flint-2.4.3/fmpq_poly/asinh_series.c create mode 100644 external/flint-2.4.3/fmpq_poly/atan_series.c create mode 100644 external/flint-2.4.3/fmpq_poly/atanh_series.c create mode 100644 external/flint-2.4.3/fmpq_poly/canonicalise.c create mode 100644 external/flint-2.4.3/fmpq_poly/clear.c create mode 100644 external/flint-2.4.3/fmpq_poly/cmp.c create mode 100644 external/flint-2.4.3/fmpq_poly/compose.c create mode 100644 external/flint-2.4.3/fmpq_poly/compose_series.c create mode 100644 external/flint-2.4.3/fmpq_poly/compose_series_brent_kung.c create mode 100644 external/flint-2.4.3/fmpq_poly/compose_series_horner.c create mode 100644 external/flint-2.4.3/fmpq_poly/content.c create mode 100644 external/flint-2.4.3/fmpq_poly/cos_series.c create mode 100644 external/flint-2.4.3/fmpq_poly/cosh_series.c create mode 100644 external/flint-2.4.3/fmpq_poly/debug.c create mode 100644 external/flint-2.4.3/fmpq_poly/derivative.c create mode 100644 external/flint-2.4.3/fmpq_poly/div.c create mode 100644 external/flint-2.4.3/fmpq_poly/div_series.c create mode 100644 external/flint-2.4.3/fmpq_poly/divrem.c create mode 100644 external/flint-2.4.3/fmpq_poly/doc/fmpq_poly.txt create mode 100644 external/flint-2.4.3/fmpq_poly/equal.c create mode 100644 external/flint-2.4.3/fmpq_poly/evaluate_fmpq.c create mode 100644 external/flint-2.4.3/fmpq_poly/evaluate_fmpz.c create mode 100644 external/flint-2.4.3/fmpq_poly/evaluate_mpq.c create mode 100644 external/flint-2.4.3/fmpq_poly/evaluate_mpz.c create mode 100644 external/flint-2.4.3/fmpq_poly/exp_series.c create mode 100644 external/flint-2.4.3/fmpq_poly/fit_length.c create mode 100644 external/flint-2.4.3/fmpq_poly/fprint.c create mode 100644 external/flint-2.4.3/fmpq_poly/fprint_pretty.c create mode 100644 external/flint-2.4.3/fmpq_poly/fread.c create mode 100644 external/flint-2.4.3/fmpq_poly/gcd.c create mode 100644 external/flint-2.4.3/fmpq_poly/get_coeff_fmpq.c create mode 100644 external/flint-2.4.3/fmpq_poly/get_coeff_mpq.c create mode 100644 external/flint-2.4.3/fmpq_poly/get_slice.c create mode 100644 external/flint-2.4.3/fmpq_poly/get_str.c create mode 100644 external/flint-2.4.3/fmpq_poly/get_str_pretty.c create mode 100644 external/flint-2.4.3/fmpq_poly/init.c create mode 100644 external/flint-2.4.3/fmpq_poly/integral.c create mode 100644 external/flint-2.4.3/fmpq_poly/interpolate_fmpz_vec.c create mode 100644 external/flint-2.4.3/fmpq_poly/inv.c create mode 100644 external/flint-2.4.3/fmpq_poly/inv_series_newton.c create mode 100644 external/flint-2.4.3/fmpq_poly/invsqrt_series.c create mode 100644 external/flint-2.4.3/fmpq_poly/is_canonical.c create mode 100644 external/flint-2.4.3/fmpq_poly/is_monic.c create mode 100644 external/flint-2.4.3/fmpq_poly/is_squarefree.c create mode 100644 external/flint-2.4.3/fmpq_poly/lcm.c create mode 100644 external/flint-2.4.3/fmpq_poly/log_series.c create mode 100644 external/flint-2.4.3/fmpq_poly/make_monic.c create mode 100644 external/flint-2.4.3/fmpq_poly/mul.c create mode 100644 external/flint-2.4.3/fmpq_poly/mullow.c create mode 100644 external/flint-2.4.3/fmpq_poly/neg.c create mode 100644 external/flint-2.4.3/fmpq_poly/normalise.c create mode 100644 external/flint-2.4.3/fmpq_poly/pow.c create mode 100644 external/flint-2.4.3/fmpq_poly/powers_clear.c create mode 100644 external/flint-2.4.3/fmpq_poly/powers_precompute.c create mode 100644 external/flint-2.4.3/fmpq_poly/primitive_part.c create mode 100644 external/flint-2.4.3/fmpq_poly/randtest.c create mode 100644 external/flint-2.4.3/fmpq_poly/realloc.c create mode 100644 external/flint-2.4.3/fmpq_poly/rem.c create mode 100644 external/flint-2.4.3/fmpq_poly/rem_powers_precomp.c create mode 100644 external/flint-2.4.3/fmpq_poly/rescale.c create mode 100644 external/flint-2.4.3/fmpq_poly/resultant.c create mode 100644 external/flint-2.4.3/fmpq_poly/reverse.c create mode 100644 external/flint-2.4.3/fmpq_poly/revert_series.c create mode 100644 external/flint-2.4.3/fmpq_poly/revert_series_lagrange.c create mode 100644 external/flint-2.4.3/fmpq_poly/revert_series_lagrange_fast.c create mode 100644 external/flint-2.4.3/fmpq_poly/revert_series_newton.c create mode 100644 external/flint-2.4.3/fmpq_poly/scalar_div_fmpq.c create mode 100644 external/flint-2.4.3/fmpq_poly/scalar_div_fmpz.c create mode 100644 external/flint-2.4.3/fmpq_poly/scalar_div_mpq.c create mode 100644 external/flint-2.4.3/fmpq_poly/scalar_div_mpz.c create mode 100644 external/flint-2.4.3/fmpq_poly/scalar_div_si.c create mode 100644 external/flint-2.4.3/fmpq_poly/scalar_div_ui.c create mode 100644 external/flint-2.4.3/fmpq_poly/scalar_mul_fmpq.c create mode 100644 external/flint-2.4.3/fmpq_poly/scalar_mul_fmpz.c create mode 100644 external/flint-2.4.3/fmpq_poly/scalar_mul_mpq.c create mode 100644 external/flint-2.4.3/fmpq_poly/scalar_mul_mpz.c create mode 100644 external/flint-2.4.3/fmpq_poly/scalar_mul_si.c create mode 100644 external/flint-2.4.3/fmpq_poly/scalar_mul_ui.c create mode 100644 external/flint-2.4.3/fmpq_poly/set.c create mode 100644 external/flint-2.4.3/fmpq_poly/set_array_mpq.c create mode 100644 external/flint-2.4.3/fmpq_poly/set_coeff_fmpq.c create mode 100644 external/flint-2.4.3/fmpq_poly/set_coeff_fmpz.c create mode 100644 external/flint-2.4.3/fmpq_poly/set_coeff_mpq.c create mode 100644 external/flint-2.4.3/fmpq_poly/set_coeff_mpz.c create mode 100644 external/flint-2.4.3/fmpq_poly/set_coeff_si.c create mode 100644 external/flint-2.4.3/fmpq_poly/set_coeff_ui.c create mode 100644 external/flint-2.4.3/fmpq_poly/set_fmpq.c create mode 100644 external/flint-2.4.3/fmpq_poly/set_fmpz.c create mode 100644 external/flint-2.4.3/fmpq_poly/set_fmpz_poly.c create mode 100644 external/flint-2.4.3/fmpq_poly/set_length.c create mode 100644 external/flint-2.4.3/fmpq_poly/set_mpq.c create mode 100644 external/flint-2.4.3/fmpq_poly/set_mpz.c create mode 100644 external/flint-2.4.3/fmpq_poly/set_si.c create mode 100644 external/flint-2.4.3/fmpq_poly/set_str.c create mode 100644 external/flint-2.4.3/fmpq_poly/set_ui.c create mode 100644 external/flint-2.4.3/fmpq_poly/shift_left.c create mode 100644 external/flint-2.4.3/fmpq_poly/shift_right.c create mode 100644 external/flint-2.4.3/fmpq_poly/sin_series.c create mode 100644 external/flint-2.4.3/fmpq_poly/sinh_series.c create mode 100644 external/flint-2.4.3/fmpq_poly/sqrt_series.c create mode 100644 external/flint-2.4.3/fmpq_poly/sub.c create mode 100644 external/flint-2.4.3/fmpq_poly/swap.c create mode 100644 external/flint-2.4.3/fmpq_poly/tan_series.c create mode 100644 external/flint-2.4.3/fmpq_poly/tanh_series.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-add.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-asin_series.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-asinh_series.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-atan_series.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-atanh_series.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-cmp.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-compose.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-compose_series.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-compose_series_brent_kung.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-compose_series_horner.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-content.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-cos_series.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-cosh_series.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-derivative.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-div.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-div_series.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-divrem.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-evaluate_fmpq.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-evaluate_fmpz.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-evaluate_mpq.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-evaluate_mpz.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-exp_series.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-gcd.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-get_set_coeff_fmpq.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-get_set_coeff_fmpz.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-get_set_coeff_mpq.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-get_set_coeff_mpz.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-get_set_coeff_si.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-get_set_coeff_ui.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-get_set_str.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-get_slice.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-init_realloc_clear.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-integral.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-interpolate_fmpz_vec.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-inv.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-inv_series_newton.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-invsqrt_series.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-is_squarefree.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-lcm.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-log_series.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-make_monic.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-mul.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-mullow.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-neg.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-pow.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-primitive_part.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-print_read.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-rem.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-rem_powers_precomp.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-rescale.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-resultant.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-reverse.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-revert_series.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-revert_series_lagrange.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-revert_series_lagrange_fast.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-revert_series_newton.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-scalar_div_fmpq.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-scalar_div_fmpz.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-scalar_div_mpq.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-scalar_div_mpz.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-scalar_div_si.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-scalar_div_ui.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-scalar_mul_fmpq.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-scalar_mul_fmpz.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-scalar_mul_mpq.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-scalar_mul_mpz.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-scalar_mul_si.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-scalar_mul_ui.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-set_array_mpq.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-set_equal.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-shift_left_right.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-sin_series.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-sinh_series.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-sqrt_series.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-sub.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-swap.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-tan_series.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-tanh_series.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-xgcd.c create mode 100644 external/flint-2.4.3/fmpq_poly/test/t-zero.c create mode 100644 external/flint-2.4.3/fmpq_poly/xgcd.c create mode 100644 external/flint-2.4.3/fmpq_poly/zero.c create mode 100644 external/flint-2.4.3/fmpq_polyxx.h create mode 100644 external/flint-2.4.3/fmpqxx.h create mode 100644 external/flint-2.4.3/fmpz-conversions-gc.in create mode 100644 external/flint-2.4.3/fmpz-conversions-reentrant.in create mode 100644 external/flint-2.4.3/fmpz-conversions-single.in create mode 100644 external/flint-2.4.3/fmpz-conversions.h create mode 100644 external/flint-2.4.3/fmpz.h create mode 100644 external/flint-2.4.3/fmpz/CRT_ui.c create mode 100644 external/flint-2.4.3/fmpz/abs.c create mode 100644 external/flint-2.4.3/fmpz/abs_fits_ui.c create mode 100644 external/flint-2.4.3/fmpz/abs_lbound_ui_2exp.c create mode 100644 external/flint-2.4.3/fmpz/abs_ubound_ui_2exp.c create mode 100644 external/flint-2.4.3/fmpz/add.c create mode 100644 external/flint-2.4.3/fmpz/add_ui.c create mode 100644 external/flint-2.4.3/fmpz/addmul.c create mode 100644 external/flint-2.4.3/fmpz/addmul_ui.c create mode 100644 external/flint-2.4.3/fmpz/and.c create mode 100644 external/flint-2.4.3/fmpz/bin_uiui.c create mode 100644 external/flint-2.4.3/fmpz/bit_pack.c create mode 100644 external/flint-2.4.3/fmpz/bit_unpack.c create mode 100644 external/flint-2.4.3/fmpz/bits.c create mode 100644 external/flint-2.4.3/fmpz/cdiv_q.c create mode 100644 external/flint-2.4.3/fmpz/cdiv_q_2exp.c create mode 100644 external/flint-2.4.3/fmpz/cdiv_q_si.c create mode 100644 external/flint-2.4.3/fmpz/cdiv_q_ui.c create mode 100644 external/flint-2.4.3/fmpz/clear_readonly.c create mode 100644 external/flint-2.4.3/fmpz/clog.c create mode 100644 external/flint-2.4.3/fmpz/clog_ui.c create mode 100644 external/flint-2.4.3/fmpz/clrbit.c create mode 100644 external/flint-2.4.3/fmpz/cmp.c create mode 100644 external/flint-2.4.3/fmpz/cmp_si.c create mode 100644 external/flint-2.4.3/fmpz/cmp_ui.c create mode 100644 external/flint-2.4.3/fmpz/cmpabs.c create mode 100644 external/flint-2.4.3/fmpz/comb_clear.c create mode 100644 external/flint-2.4.3/fmpz/comb_init.c create mode 100644 external/flint-2.4.3/fmpz/combit.c create mode 100644 external/flint-2.4.3/fmpz/complement.c create mode 100644 external/flint-2.4.3/fmpz/divexact.c create mode 100644 external/flint-2.4.3/fmpz/divexact_si.c create mode 100644 external/flint-2.4.3/fmpz/divexact_ui.c create mode 100644 external/flint-2.4.3/fmpz/divisible.c create mode 100644 external/flint-2.4.3/fmpz/divisible_si.c create mode 100644 external/flint-2.4.3/fmpz/dlog.c create mode 100644 external/flint-2.4.3/fmpz/doc/fmpz.txt create mode 100644 external/flint-2.4.3/fmpz/doc/reentrant.txt create mode 100644 external/flint-2.4.3/fmpz/doc/single.txt create mode 100644 external/flint-2.4.3/fmpz/equal.c create mode 100644 external/flint-2.4.3/fmpz/equal_si.c create mode 100644 external/flint-2.4.3/fmpz/equal_ui.c create mode 100644 external/flint-2.4.3/fmpz/fac_ui.c create mode 100644 external/flint-2.4.3/fmpz/fdiv_q.c create mode 100644 external/flint-2.4.3/fmpz/fdiv_q_2exp.c create mode 100644 external/flint-2.4.3/fmpz/fdiv_q_si.c create mode 100644 external/flint-2.4.3/fmpz/fdiv_q_ui.c create mode 100644 external/flint-2.4.3/fmpz/fdiv_qr.c create mode 100644 external/flint-2.4.3/fmpz/fdiv_qr_preinvn.c create mode 100644 external/flint-2.4.3/fmpz/fdiv_r.c create mode 100644 external/flint-2.4.3/fmpz/fdiv_r_2exp.c create mode 100644 external/flint-2.4.3/fmpz/fdiv_ui.c create mode 100644 external/flint-2.4.3/fmpz/fib_ui.c create mode 100644 external/flint-2.4.3/fmpz/fits_si.c create mode 100644 external/flint-2.4.3/fmpz/flog.c create mode 100644 external/flint-2.4.3/fmpz/flog_ui.c create mode 100644 external/flint-2.4.3/fmpz/fmpz.c create mode 100644 external/flint-2.4.3/fmpz/fprint.c create mode 100644 external/flint-2.4.3/fmpz/fread.c create mode 100644 external/flint-2.4.3/fmpz/gcd.c create mode 100644 external/flint-2.4.3/fmpz/gcdinv.c create mode 100644 external/flint-2.4.3/fmpz/get_d.c create mode 100644 external/flint-2.4.3/fmpz/get_d_2exp.c create mode 100644 external/flint-2.4.3/fmpz/get_mpz.c create mode 100644 external/flint-2.4.3/fmpz/get_si.c create mode 100644 external/flint-2.4.3/fmpz/get_str.c create mode 100644 external/flint-2.4.3/fmpz/get_ui.c create mode 100644 external/flint-2.4.3/fmpz/init2.c create mode 100644 external/flint-2.4.3/fmpz/init_set_readonly.c create mode 100644 external/flint-2.4.3/fmpz/inlines.c create mode 100644 external/flint-2.4.3/fmpz/inp_raw.c create mode 100644 external/flint-2.4.3/fmpz/invmod.c create mode 100644 external/flint-2.4.3/fmpz/is_prime_pseudosquare.c create mode 100644 external/flint-2.4.3/fmpz/is_probabprime.c create mode 100644 external/flint-2.4.3/fmpz/is_square.c create mode 100644 external/flint-2.4.3/fmpz/jacobi.c create mode 100644 external/flint-2.4.3/fmpz/lcm.c create mode 100644 external/flint-2.4.3/fmpz/link/fmpz_gc.c create mode 100644 external/flint-2.4.3/fmpz/link/fmpz_reentrant.c create mode 100644 external/flint-2.4.3/fmpz/link/fmpz_single.c create mode 100644 external/flint-2.4.3/fmpz/mod.c create mode 100644 external/flint-2.4.3/fmpz/mod_ui.c create mode 100644 external/flint-2.4.3/fmpz/mpz_clear_readonly.c create mode 100644 external/flint-2.4.3/fmpz/mpz_init_set_readonly.c create mode 100644 external/flint-2.4.3/fmpz/mul.c create mode 100644 external/flint-2.4.3/fmpz/mul_2exp.c create mode 100644 external/flint-2.4.3/fmpz/mul_si.c create mode 100644 external/flint-2.4.3/fmpz/mul_si_tdiv_q_2exp.c create mode 100644 external/flint-2.4.3/fmpz/mul_tdiv_q_2exp.c create mode 100644 external/flint-2.4.3/fmpz/mul_ui.c create mode 100644 external/flint-2.4.3/fmpz/multi_CRT_ui.c create mode 100644 external/flint-2.4.3/fmpz/multi_mod_ui.c create mode 100644 external/flint-2.4.3/fmpz/or.c create mode 100644 external/flint-2.4.3/fmpz/out_raw.c create mode 100644 external/flint-2.4.3/fmpz/popcnt.c create mode 100644 external/flint-2.4.3/fmpz/pow_ui.c create mode 100644 external/flint-2.4.3/fmpz/powm.c create mode 100644 external/flint-2.4.3/fmpz/powm_ui.c create mode 100644 external/flint-2.4.3/fmpz/preinvn_clear.c create mode 100644 external/flint-2.4.3/fmpz/preinvn_init.c create mode 100644 external/flint-2.4.3/fmpz/print.c create mode 100644 external/flint-2.4.3/fmpz/profile/p-fdiv_qr_preinvn.c create mode 100644 external/flint-2.4.3/fmpz/randbits.c create mode 100644 external/flint-2.4.3/fmpz/randm.c create mode 100644 external/flint-2.4.3/fmpz/randtest.c create mode 100644 external/flint-2.4.3/fmpz/randtest_mod.c create mode 100644 external/flint-2.4.3/fmpz/read.c create mode 100644 external/flint-2.4.3/fmpz/remove.c create mode 100644 external/flint-2.4.3/fmpz/rfac_ui.c create mode 100644 external/flint-2.4.3/fmpz/rfac_uiui.c create mode 100644 external/flint-2.4.3/fmpz/root.c create mode 100644 external/flint-2.4.3/fmpz/set.c create mode 100644 external/flint-2.4.3/fmpz/set_d.c create mode 100644 external/flint-2.4.3/fmpz/set_mpz.c create mode 100644 external/flint-2.4.3/fmpz/set_str.c create mode 100644 external/flint-2.4.3/fmpz/setbit.c create mode 100644 external/flint-2.4.3/fmpz/sgn.c create mode 100644 external/flint-2.4.3/fmpz/size.c create mode 100644 external/flint-2.4.3/fmpz/sizeinbase.c create mode 100644 external/flint-2.4.3/fmpz/sqrt.c create mode 100644 external/flint-2.4.3/fmpz/sqrtmod.c create mode 100644 external/flint-2.4.3/fmpz/sqrtrem.c create mode 100644 external/flint-2.4.3/fmpz/sub.c create mode 100644 external/flint-2.4.3/fmpz/sub_ui.c create mode 100644 external/flint-2.4.3/fmpz/submul.c create mode 100644 external/flint-2.4.3/fmpz/submul_ui.c create mode 100644 external/flint-2.4.3/fmpz/tdiv_q.c create mode 100644 external/flint-2.4.3/fmpz/tdiv_q_2exp.c create mode 100644 external/flint-2.4.3/fmpz/tdiv_q_si.c create mode 100644 external/flint-2.4.3/fmpz/tdiv_q_ui.c create mode 100644 external/flint-2.4.3/fmpz/tdiv_qr.c create mode 100644 external/flint-2.4.3/fmpz/tdiv_ui.c create mode 100644 external/flint-2.4.3/fmpz/test/t-abs.c create mode 100644 external/flint-2.4.3/fmpz/test/t-abs_fits_ui.c create mode 100644 external/flint-2.4.3/fmpz/test/t-abs_lbound_ui_2exp.c create mode 100644 external/flint-2.4.3/fmpz/test/t-abs_ubound_ui_2exp.c create mode 100644 external/flint-2.4.3/fmpz/test/t-add.c create mode 100644 external/flint-2.4.3/fmpz/test/t-add_ui.c create mode 100644 external/flint-2.4.3/fmpz/test/t-addmul.c create mode 100644 external/flint-2.4.3/fmpz/test/t-addmul_ui.c create mode 100644 external/flint-2.4.3/fmpz/test/t-and.c create mode 100644 external/flint-2.4.3/fmpz/test/t-bin_uiui.c create mode 100644 external/flint-2.4.3/fmpz/test/t-bit_pack.c create mode 100644 external/flint-2.4.3/fmpz/test/t-bits.c create mode 100644 external/flint-2.4.3/fmpz/test/t-cdiv_q.c create mode 100644 external/flint-2.4.3/fmpz/test/t-cdiv_q_2exp.c create mode 100644 external/flint-2.4.3/fmpz/test/t-cdiv_q_si.c create mode 100644 external/flint-2.4.3/fmpz/test/t-cdiv_q_ui.c create mode 100644 external/flint-2.4.3/fmpz/test/t-clog.c create mode 100644 external/flint-2.4.3/fmpz/test/t-clog_ui.c create mode 100644 external/flint-2.4.3/fmpz/test/t-cmp.c create mode 100644 external/flint-2.4.3/fmpz/test/t-cmp_si.c create mode 100644 external/flint-2.4.3/fmpz/test/t-cmp_ui.c create mode 100644 external/flint-2.4.3/fmpz/test/t-cmpabs.c create mode 100644 external/flint-2.4.3/fmpz/test/t-comb_init_clear.c create mode 100644 external/flint-2.4.3/fmpz/test/t-combit.c create mode 100644 external/flint-2.4.3/fmpz/test/t-complement.c create mode 100644 external/flint-2.4.3/fmpz/test/t-crt_ui.c create mode 100644 external/flint-2.4.3/fmpz/test/t-divexact.c create mode 100644 external/flint-2.4.3/fmpz/test/t-divexact2_uiui.c create mode 100644 external/flint-2.4.3/fmpz/test/t-divexact_si.c create mode 100644 external/flint-2.4.3/fmpz/test/t-divexact_ui.c create mode 100644 external/flint-2.4.3/fmpz/test/t-divisible.c create mode 100644 external/flint-2.4.3/fmpz/test/t-divisible_si.c create mode 100644 external/flint-2.4.3/fmpz/test/t-dlog.c create mode 100644 external/flint-2.4.3/fmpz/test/t-equal.c create mode 100644 external/flint-2.4.3/fmpz/test/t-equal_si.c create mode 100644 external/flint-2.4.3/fmpz/test/t-equal_ui.c create mode 100644 external/flint-2.4.3/fmpz/test/t-fac_ui.c create mode 100644 external/flint-2.4.3/fmpz/test/t-fdiv_q.c create mode 100644 external/flint-2.4.3/fmpz/test/t-fdiv_q_2exp.c create mode 100644 external/flint-2.4.3/fmpz/test/t-fdiv_q_si.c create mode 100644 external/flint-2.4.3/fmpz/test/t-fdiv_q_ui.c create mode 100644 external/flint-2.4.3/fmpz/test/t-fdiv_qr.c create mode 100644 external/flint-2.4.3/fmpz/test/t-fdiv_qr_preinvn.c create mode 100644 external/flint-2.4.3/fmpz/test/t-fdiv_r.c create mode 100644 external/flint-2.4.3/fmpz/test/t-fdiv_r_2exp.c create mode 100644 external/flint-2.4.3/fmpz/test/t-fdiv_ui.c create mode 100644 external/flint-2.4.3/fmpz/test/t-fib_ui.c create mode 100644 external/flint-2.4.3/fmpz/test/t-fits_si.c create mode 100644 external/flint-2.4.3/fmpz/test/t-flog.c create mode 100644 external/flint-2.4.3/fmpz/test/t-flog_ui.c create mode 100644 external/flint-2.4.3/fmpz/test/t-fmpz.c create mode 100644 external/flint-2.4.3/fmpz/test/t-fmpz_cleanup.c create mode 100644 external/flint-2.4.3/fmpz/test/t-gcd.c create mode 100644 external/flint-2.4.3/fmpz/test/t-gcdinv.c create mode 100644 external/flint-2.4.3/fmpz/test/t-get_d.c create mode 100644 external/flint-2.4.3/fmpz/test/t-get_d_2exp.c create mode 100644 external/flint-2.4.3/fmpz/test/t-get_mpz.c create mode 100644 external/flint-2.4.3/fmpz/test/t-get_si.c create mode 100644 external/flint-2.4.3/fmpz/test/t-get_str.c create mode 100644 external/flint-2.4.3/fmpz/test/t-get_ui.c create mode 100644 external/flint-2.4.3/fmpz/test/t-init2.c create mode 100644 external/flint-2.4.3/fmpz/test/t-init_set.c create mode 100644 external/flint-2.4.3/fmpz/test/t-init_set_readonly.c create mode 100644 external/flint-2.4.3/fmpz/test/t-init_set_ui.c create mode 100644 external/flint-2.4.3/fmpz/test/t-invmod.c create mode 100644 external/flint-2.4.3/fmpz/test/t-is_even.c create mode 100644 external/flint-2.4.3/fmpz/test/t-is_prime_pseudosquare.c create mode 100644 external/flint-2.4.3/fmpz/test/t-is_square.c create mode 100644 external/flint-2.4.3/fmpz/test/t-jacobi.c create mode 100644 external/flint-2.4.3/fmpz/test/t-lcm.c create mode 100644 external/flint-2.4.3/fmpz/test/t-mod.c create mode 100644 external/flint-2.4.3/fmpz/test/t-mod_ui.c create mode 100644 external/flint-2.4.3/fmpz/test/t-mpz_init_set_readonly.c create mode 100644 external/flint-2.4.3/fmpz/test/t-mul.c create mode 100644 external/flint-2.4.3/fmpz/test/t-mul2_uiui.c create mode 100644 external/flint-2.4.3/fmpz/test/t-mul_2exp.c create mode 100644 external/flint-2.4.3/fmpz/test/t-mul_si.c create mode 100644 external/flint-2.4.3/fmpz/test/t-mul_si_tdiv_q_2exp.c create mode 100644 external/flint-2.4.3/fmpz/test/t-mul_tdiv_q_2exp.c create mode 100644 external/flint-2.4.3/fmpz/test/t-mul_ui.c create mode 100644 external/flint-2.4.3/fmpz/test/t-multi_CRT_ui.c create mode 100644 external/flint-2.4.3/fmpz/test/t-multi_CRT_ui_unsigned.c create mode 100644 external/flint-2.4.3/fmpz/test/t-neg.c create mode 100644 external/flint-2.4.3/fmpz/test/t-neg_ui.c create mode 100644 external/flint-2.4.3/fmpz/test/t-neg_uiui.c create mode 100644 external/flint-2.4.3/fmpz/test/t-or.c create mode 100644 external/flint-2.4.3/fmpz/test/t-out_inp_raw.c create mode 100644 external/flint-2.4.3/fmpz/test/t-popcnt.c create mode 100644 external/flint-2.4.3/fmpz/test/t-pow_ui.c create mode 100644 external/flint-2.4.3/fmpz/test/t-powm.c create mode 100644 external/flint-2.4.3/fmpz/test/t-powm_ui.c create mode 100644 external/flint-2.4.3/fmpz/test/t-print_read.c create mode 100644 external/flint-2.4.3/fmpz/test/t-remove.c create mode 100644 external/flint-2.4.3/fmpz/test/t-rfac_ui.c create mode 100644 external/flint-2.4.3/fmpz/test/t-rfac_uiui.c create mode 100644 external/flint-2.4.3/fmpz/test/t-root.c create mode 100644 external/flint-2.4.3/fmpz/test/t-set.c create mode 100644 external/flint-2.4.3/fmpz/test/t-set_ui_smod.c create mode 100644 external/flint-2.4.3/fmpz/test/t-set_uiui.c create mode 100644 external/flint-2.4.3/fmpz/test/t-setbit.c create mode 100644 external/flint-2.4.3/fmpz/test/t-sgn.c create mode 100644 external/flint-2.4.3/fmpz/test/t-size.c create mode 100644 external/flint-2.4.3/fmpz/test/t-sizeinbase.c create mode 100644 external/flint-2.4.3/fmpz/test/t-sqrt.c create mode 100644 external/flint-2.4.3/fmpz/test/t-sqrtmod.c create mode 100644 external/flint-2.4.3/fmpz/test/t-sqrtrem.c create mode 100644 external/flint-2.4.3/fmpz/test/t-sub.c create mode 100644 external/flint-2.4.3/fmpz/test/t-sub_ui.c create mode 100644 external/flint-2.4.3/fmpz/test/t-submul.c create mode 100644 external/flint-2.4.3/fmpz/test/t-submul_ui.c create mode 100644 external/flint-2.4.3/fmpz/test/t-swap.c create mode 100644 external/flint-2.4.3/fmpz/test/t-tdiv_q.c create mode 100644 external/flint-2.4.3/fmpz/test/t-tdiv_q_2exp.c create mode 100644 external/flint-2.4.3/fmpz/test/t-tdiv_q_si.c create mode 100644 external/flint-2.4.3/fmpz/test/t-tdiv_q_ui.c create mode 100644 external/flint-2.4.3/fmpz/test/t-tdiv_qr.c create mode 100644 external/flint-2.4.3/fmpz/test/t-tdiv_ui.c create mode 100644 external/flint-2.4.3/fmpz/test/t-tstbit.c create mode 100644 external/flint-2.4.3/fmpz/test/t-val2.c create mode 100644 external/flint-2.4.3/fmpz/test/t-xgcd.c create mode 100644 external/flint-2.4.3/fmpz/test/t-xgcd_partial.c create mode 100644 external/flint-2.4.3/fmpz/test/t-xor.c create mode 100644 external/flint-2.4.3/fmpz/tstbit.c create mode 100644 external/flint-2.4.3/fmpz/val2.c create mode 100644 external/flint-2.4.3/fmpz/xgcd.c create mode 100644 external/flint-2.4.3/fmpz/xgcd_partial.c create mode 100644 external/flint-2.4.3/fmpz/xor.c create mode 100644 external/flint-2.4.3/fmpz_factor.h create mode 100644 external/flint-2.4.3/fmpz_factor/append_ui.c create mode 100644 external/flint-2.4.3/fmpz_factor/clear.c create mode 100644 external/flint-2.4.3/fmpz_factor/doc/fmpz_factor.txt create mode 100644 external/flint-2.4.3/fmpz_factor/expand.c create mode 100644 external/flint-2.4.3/fmpz_factor/expand_iterative.c create mode 100644 external/flint-2.4.3/fmpz_factor/expand_multiexp.c create mode 100644 external/flint-2.4.3/fmpz_factor/extend_factor_ui.c create mode 100644 external/flint-2.4.3/fmpz_factor/factor.c create mode 100644 external/flint-2.4.3/fmpz_factor/factor_pp1.c create mode 100644 external/flint-2.4.3/fmpz_factor/factor_si.c create mode 100644 external/flint-2.4.3/fmpz_factor/factor_trial_range.c create mode 100644 external/flint-2.4.3/fmpz_factor/fit_length.c create mode 100644 external/flint-2.4.3/fmpz_factor/init.c create mode 100644 external/flint-2.4.3/fmpz_factor/print.c create mode 100644 external/flint-2.4.3/fmpz_factor/profile/p-factor_pp1.c create mode 100644 external/flint-2.4.3/fmpz_factor/set_length.c create mode 100644 external/flint-2.4.3/fmpz_factor/test/t-factor.c create mode 100644 external/flint-2.4.3/fmpz_factor/test/t-factor_pp1.c create mode 100644 external/flint-2.4.3/fmpz_factorxx.h create mode 100644 external/flint-2.4.3/fmpz_mat.h create mode 100644 external/flint-2.4.3/fmpz_mat/CRT_ui.c create mode 100644 external/flint-2.4.3/fmpz_mat/add.c create mode 100644 external/flint-2.4.3/fmpz_mat/charpoly.c create mode 100644 external/flint-2.4.3/fmpz_mat/clear.c create mode 100644 external/flint-2.4.3/fmpz_mat/det.c create mode 100644 external/flint-2.4.3/fmpz_mat/det_bareiss.c create mode 100644 external/flint-2.4.3/fmpz_mat/det_bound.c create mode 100644 external/flint-2.4.3/fmpz_mat/det_cofactor.c create mode 100644 external/flint-2.4.3/fmpz_mat/det_divisor.c create mode 100644 external/flint-2.4.3/fmpz_mat/det_modular.c create mode 100644 external/flint-2.4.3/fmpz_mat/det_modular_accelerated.c create mode 100644 external/flint-2.4.3/fmpz_mat/det_modular_given_divisor.c create mode 100644 external/flint-2.4.3/fmpz_mat/doc/fmpz_mat.txt create mode 100644 external/flint-2.4.3/fmpz_mat/equal.c create mode 100644 external/flint-2.4.3/fmpz_mat/fflu.c create mode 100644 external/flint-2.4.3/fmpz_mat/find_pivot_any.c create mode 100644 external/flint-2.4.3/fmpz_mat/fprint.c create mode 100644 external/flint-2.4.3/fmpz_mat/fread.c create mode 100644 external/flint-2.4.3/fmpz_mat/get_nmod_mat.c create mode 100644 external/flint-2.4.3/fmpz_mat/init.c create mode 100644 external/flint-2.4.3/fmpz_mat/init_set.c create mode 100644 external/flint-2.4.3/fmpz_mat/inv.c create mode 100644 external/flint-2.4.3/fmpz_mat/is_zero.c create mode 100644 external/flint-2.4.3/fmpz_mat/max_bits.c create mode 100644 external/flint-2.4.3/fmpz_mat/mul.c create mode 100644 external/flint-2.4.3/fmpz_mat/mul_classical.c create mode 100644 external/flint-2.4.3/fmpz_mat/mul_classical_inline.c create mode 100644 external/flint-2.4.3/fmpz_mat/mul_multi_mod.c create mode 100644 external/flint-2.4.3/fmpz_mat/multi_CRT_ui.c create mode 100644 external/flint-2.4.3/fmpz_mat/multi_mod_ui.c create mode 100644 external/flint-2.4.3/fmpz_mat/neg.c create mode 100644 external/flint-2.4.3/fmpz_mat/nullspace.c create mode 100644 external/flint-2.4.3/fmpz_mat/one.c create mode 100644 external/flint-2.4.3/fmpz_mat/pow.c create mode 100644 external/flint-2.4.3/fmpz_mat/profile/p-det.c create mode 100644 external/flint-2.4.3/fmpz_mat/profile/p-mul.c create mode 100644 external/flint-2.4.3/fmpz_mat/randajtai.c create mode 100644 external/flint-2.4.3/fmpz_mat/randbits.c create mode 100644 external/flint-2.4.3/fmpz_mat/randdet.c create mode 100644 external/flint-2.4.3/fmpz_mat/randintrel.c create mode 100644 external/flint-2.4.3/fmpz_mat/randntrulike.c create mode 100644 external/flint-2.4.3/fmpz_mat/randntrulike2.c create mode 100644 external/flint-2.4.3/fmpz_mat/randops.c create mode 100644 external/flint-2.4.3/fmpz_mat/randpermdiag.c create mode 100644 external/flint-2.4.3/fmpz_mat/randrank.c create mode 100644 external/flint-2.4.3/fmpz_mat/randsimdioph.c create mode 100644 external/flint-2.4.3/fmpz_mat/randtest.c create mode 100644 external/flint-2.4.3/fmpz_mat/randtest_unsigned.c create mode 100644 external/flint-2.4.3/fmpz_mat/rank.c create mode 100644 external/flint-2.4.3/fmpz_mat/rref.c create mode 100644 external/flint-2.4.3/fmpz_mat/rref_mod.c create mode 100644 external/flint-2.4.3/fmpz_mat/scalar_addmul_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_mat/scalar_addmul_nmod_mat_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_mat/scalar_addmul_nmod_mat_ui.c create mode 100644 external/flint-2.4.3/fmpz_mat/scalar_addmul_si.c create mode 100644 external/flint-2.4.3/fmpz_mat/scalar_addmul_ui.c create mode 100644 external/flint-2.4.3/fmpz_mat/scalar_divexact_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_mat/scalar_divexact_si.c create mode 100644 external/flint-2.4.3/fmpz_mat/scalar_divexact_ui.c create mode 100644 external/flint-2.4.3/fmpz_mat/scalar_mod_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_mat/scalar_mul_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_mat/scalar_mul_si.c create mode 100644 external/flint-2.4.3/fmpz_mat/scalar_mul_ui.c create mode 100644 external/flint-2.4.3/fmpz_mat/scalar_submul_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_mat/scalar_submul_si.c create mode 100644 external/flint-2.4.3/fmpz_mat/scalar_submul_ui.c create mode 100644 external/flint-2.4.3/fmpz_mat/set.c create mode 100644 external/flint-2.4.3/fmpz_mat/set_nmod_mat.c create mode 100644 external/flint-2.4.3/fmpz_mat/set_nmod_mat_unsigned.c create mode 100644 external/flint-2.4.3/fmpz_mat/solve.c create mode 100644 external/flint-2.4.3/fmpz_mat/solve_bound.c create mode 100644 external/flint-2.4.3/fmpz_mat/solve_cramer.c create mode 100644 external/flint-2.4.3/fmpz_mat/solve_dixon.c create mode 100644 external/flint-2.4.3/fmpz_mat/solve_fflu.c create mode 100644 external/flint-2.4.3/fmpz_mat/solve_fflu_precomp.c create mode 100644 external/flint-2.4.3/fmpz_mat/sqr.c create mode 100644 external/flint-2.4.3/fmpz_mat/sub.c create mode 100644 external/flint-2.4.3/fmpz_mat/swap.c create mode 100644 external/flint-2.4.3/fmpz_mat/test/t-CRT_ui.c create mode 100644 external/flint-2.4.3/fmpz_mat/test/t-CRT_ui_unsigned.c create mode 100644 external/flint-2.4.3/fmpz_mat/test/t-add_sub.c create mode 100644 external/flint-2.4.3/fmpz_mat/test/t-charpoly.c create mode 100644 external/flint-2.4.3/fmpz_mat/test/t-det.c create mode 100644 external/flint-2.4.3/fmpz_mat/test/t-det_bound.c create mode 100644 external/flint-2.4.3/fmpz_mat/test/t-det_divisor.c create mode 100644 external/flint-2.4.3/fmpz_mat/test/t-det_modular.c create mode 100644 external/flint-2.4.3/fmpz_mat/test/t-det_modular_accelerated.c create mode 100644 external/flint-2.4.3/fmpz_mat/test/t-entry.c create mode 100644 external/flint-2.4.3/fmpz_mat/test/t-equal.c create mode 100644 external/flint-2.4.3/fmpz_mat/test/t-get_nmod_mat.c create mode 100644 external/flint-2.4.3/fmpz_mat/test/t-init_clear.c create mode 100644 external/flint-2.4.3/fmpz_mat/test/t-inv.c create mode 100644 external/flint-2.4.3/fmpz_mat/test/t-is_empty.c create mode 100644 external/flint-2.4.3/fmpz_mat/test/t-is_square.c create mode 100644 external/flint-2.4.3/fmpz_mat/test/t-is_zero.c create mode 100644 external/flint-2.4.3/fmpz_mat/test/t-max_bits.c create mode 100644 external/flint-2.4.3/fmpz_mat/test/t-mul.c create mode 100644 external/flint-2.4.3/fmpz_mat/test/t-mul_classical.c create mode 100644 external/flint-2.4.3/fmpz_mat/test/t-mul_multi_mod.c create mode 100644 external/flint-2.4.3/fmpz_mat/test/t-multi_CRT_ui.c create mode 100644 external/flint-2.4.3/fmpz_mat/test/t-multi_CRT_ui_unsigned.c create mode 100644 external/flint-2.4.3/fmpz_mat/test/t-nullspace.c create mode 100644 external/flint-2.4.3/fmpz_mat/test/t-one.c create mode 100644 external/flint-2.4.3/fmpz_mat/test/t-pow.c create mode 100644 external/flint-2.4.3/fmpz_mat/test/t-print_read.c create mode 100644 external/flint-2.4.3/fmpz_mat/test/t-rank.c create mode 100644 external/flint-2.4.3/fmpz_mat/test/t-rref.c create mode 100644 external/flint-2.4.3/fmpz_mat/test/t-rref_mod.c create mode 100644 external/flint-2.4.3/fmpz_mat/test/t-scalar_addmul_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_mat/test/t-scalar_addmul_nmod_mat_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_mat/test/t-scalar_addmul_nmod_mat_ui.c create mode 100644 external/flint-2.4.3/fmpz_mat/test/t-scalar_addmul_si.c create mode 100644 external/flint-2.4.3/fmpz_mat/test/t-scalar_addmul_ui.c create mode 100644 external/flint-2.4.3/fmpz_mat/test/t-scalar_mod_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_mat/test/t-scalar_mul_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_mat/test/t-scalar_mul_si.c create mode 100644 external/flint-2.4.3/fmpz_mat/test/t-scalar_mul_ui.c create mode 100644 external/flint-2.4.3/fmpz_mat/test/t-solve.c create mode 100644 external/flint-2.4.3/fmpz_mat/test/t-solve_bound.c create mode 100644 external/flint-2.4.3/fmpz_mat/test/t-solve_cramer.c create mode 100644 external/flint-2.4.3/fmpz_mat/test/t-solve_dixon.c create mode 100644 external/flint-2.4.3/fmpz_mat/test/t-sqr.c create mode 100644 external/flint-2.4.3/fmpz_mat/test/t-trace.c create mode 100644 external/flint-2.4.3/fmpz_mat/test/t-transpose.c create mode 100644 external/flint-2.4.3/fmpz_mat/test/t-zero.c create mode 100644 external/flint-2.4.3/fmpz_mat/trace.c create mode 100644 external/flint-2.4.3/fmpz_mat/transpose.c create mode 100644 external/flint-2.4.3/fmpz_mat/zero.c create mode 100644 external/flint-2.4.3/fmpz_matxx.h create mode 100644 external/flint-2.4.3/fmpz_mod_poly.h create mode 100644 external/flint-2.4.3/fmpz_mod_poly/add.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/clear.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/compose_divconquer.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/compose_horner.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/compose_mod.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/compose_mod_brent_kung.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/compose_mod_brent_kung_precomp_preinv.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/compose_mod_brent_kung_preinv.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/compose_mod_horner.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/derivative.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/div_basecase.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/div_newton_n_preinv.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/divrem_basecase.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/divrem_divconquer.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/divrem_divconquer_recursive.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/divrem_f.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/divrem_newton_n_preinv.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/doc/fmpz_mod_poly.txt create mode 100644 external/flint-2.4.3/fmpz_mod_poly/evaluate_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/evaluate_fmpz_vec.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/evaluate_fmpz_vec_fast.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/evaluate_fmpz_vec_iter.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/fit_length.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/fprint.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/fread.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/gcd_euclidean.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/gcd_euclidean_f.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/gcdinv.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/get_fmpz_poly.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/init.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/inv_series_newton.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/invmod.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/make_monic.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/mul.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/mullow.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/mulmod.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/mulmod_preinv.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/neg.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/normalise.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/pow.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/pow_trunc.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/pow_trunc_binexp.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/powmod_fmpz_binexp.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/powmod_fmpz_binexp_preinv.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/powmod_ui_binexp.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/powmod_ui_binexp_preinv.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/powmod_x_fmpz_preinv.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/profile/p-invert.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/profile/p-mul.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/profile/p-tree.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/radix.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/randtest.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/realloc.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/rem_basecase.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/remove.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/reverse.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/scalar_mul_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/set.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/set_coeff_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/set_coeff_ui.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/set_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/set_fmpz_poly.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/shift_left.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/shift_right.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/sqr.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/sub.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/swap.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/test/t-add.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/test/t-compose_divconquer.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/test/t-compose_horner.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/test/t-compose_mod.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/test/t-compose_mod_brent_kung.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/test/t-compose_mod_brent_kung_precomp_preinv.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/test/t-compose_mod_brent_kung_preinv.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/test/t-compose_mod_horner.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/test/t-derivative.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/test/t-div_basecase.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/test/t-div_newton_n_preinv.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/test/t-divrem_basecase.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/test/t-divrem_divconquer.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/test/t-divrem_f.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/test/t-divrem_newton_n_preinv.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/test/t-evaluate_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/test/t-evaluate_fmpz_vec_fast.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/test/t-gcd_euclidean.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/test/t-gcd_euclidean_f.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/test/t-gcdinv.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/test/t-get_set_fmpz_poly.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/test/t-init_realloc_clear.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/test/t-inv_series_newton.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/test/t-invmod.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/test/t-mul.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/test/t-mullow.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/test/t-mulmod.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/test/t-mulmod_preinv.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/test/t-neg.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/test/t-pow_trunc.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/test/t-pow_trunc_binexp.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/test/t-powmod_fmpz_binexp.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/test/t-powmod_fmpz_binexp_preinv.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/test/t-powmod_ui_binexp.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/test/t-powmod_ui_binexp_preinv.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/test/t-powmod_x_fmpz_preinv.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/test/t-print_read.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/test/t-radix.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/test/t-rem_basecase.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/test/t-scalar_mul_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/test/t-set_equal.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/test/t-shift_left_right.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/test/t-sub.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/test/t-swap.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/test/t-xgcd.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/test/t-xgcd_euclidean.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/test/t-zero.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/tree.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/xgcd_euclidean.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly/zero_coeffs.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly_factor.h create mode 100644 external/flint-2.4.3/fmpz_mod_poly_factor/clear.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly_factor/concat.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly_factor/doc/fmpz_mod_poly_factor.txt create mode 100644 external/flint-2.4.3/fmpz_mod_poly_factor/factor.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly_factor/factor_berlekamp.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly_factor/factor_cantor_zassenhaus.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly_factor/factor_distinct_deg.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly_factor/factor_equal_deg.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly_factor/factor_equal_deg_prob.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly_factor/factor_kaltofen_shoup.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly_factor/factor_squarefree.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly_factor/fit_length.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly_factor/init.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly_factor/insert.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly_factor/is_irreducible.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly_factor/is_irreducible_ddf.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly_factor/is_irreducible_rabin.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly_factor/is_squarefree.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly_factor/pow.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly_factor/print.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly_factor/profile/p-factor.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly_factor/realloc.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly_factor/set.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly_factor/test/t-factor.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly_factor/test/t-factor_berlekamp.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly_factor/test/t-factor_cantor_zassenhaus.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly_factor/test/t-factor_distinct_deg.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly_factor/test/t-factor_equal_deg_prob.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly_factor/test/t-factor_kaltofen_shoup.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly_factor/test/t-factor_squarefree.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly_factor/test/t-is_irreducible.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly_factor/test/t-is_irreducible_ddf.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly_factor/test/t-is_irreducible_rabin.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly_factor/test/t-is_squarefree.c create mode 100644 external/flint-2.4.3/fmpz_mod_poly_factorxx.h create mode 100644 external/flint-2.4.3/fmpz_mod_polyxx.h create mode 100644 external/flint-2.4.3/fmpz_poly.h create mode 100644 external/flint-2.4.3/fmpz_poly/2norm.c create mode 100644 external/flint-2.4.3/fmpz_poly/2norm_normalised_bits.c create mode 100644 external/flint-2.4.3/fmpz_poly/CRT_ui.c create mode 100644 external/flint-2.4.3/fmpz_poly/add.c create mode 100644 external/flint-2.4.3/fmpz_poly/bit_pack.c create mode 100644 external/flint-2.4.3/fmpz_poly/bit_unpack.c create mode 100644 external/flint-2.4.3/fmpz_poly/bound_roots.c create mode 100644 external/flint-2.4.3/fmpz_poly/clear.c create mode 100644 external/flint-2.4.3/fmpz_poly/compose.c create mode 100644 external/flint-2.4.3/fmpz_poly/compose_divconquer.c create mode 100644 external/flint-2.4.3/fmpz_poly/compose_horner.c create mode 100644 external/flint-2.4.3/fmpz_poly/compose_series.c create mode 100644 external/flint-2.4.3/fmpz_poly/compose_series_brent_kung.c create mode 100644 external/flint-2.4.3/fmpz_poly/compose_series_horner.c create mode 100644 external/flint-2.4.3/fmpz_poly/content.c create mode 100644 external/flint-2.4.3/fmpz_poly/derivative.c create mode 100644 external/flint-2.4.3/fmpz_poly/div.c create mode 100644 external/flint-2.4.3/fmpz_poly/div_basecase.c create mode 100644 external/flint-2.4.3/fmpz_poly/div_divconquer.c create mode 100644 external/flint-2.4.3/fmpz_poly/div_divconquer_recursive.c create mode 100644 external/flint-2.4.3/fmpz_poly/div_preinv.c create mode 100644 external/flint-2.4.3/fmpz_poly/div_root.c create mode 100644 external/flint-2.4.3/fmpz_poly/div_series.c create mode 100644 external/flint-2.4.3/fmpz_poly/divides.c create mode 100644 external/flint-2.4.3/fmpz_poly/divrem.c create mode 100644 external/flint-2.4.3/fmpz_poly/divrem_basecase.c create mode 100644 external/flint-2.4.3/fmpz_poly/divrem_divconquer.c create mode 100644 external/flint-2.4.3/fmpz_poly/divrem_divconquer_recursive.c create mode 100644 external/flint-2.4.3/fmpz_poly/divrem_preinv.c create mode 100644 external/flint-2.4.3/fmpz_poly/divremlow_divconquer_recursive.c create mode 100644 external/flint-2.4.3/fmpz_poly/doc/fmpz_poly.txt create mode 100644 external/flint-2.4.3/fmpz_poly/equal.c create mode 100644 external/flint-2.4.3/fmpz_poly/evaluate_divconquer_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_poly/evaluate_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_poly/evaluate_fmpz_vec.c create mode 100644 external/flint-2.4.3/fmpz_poly/evaluate_horner_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_poly/evaluate_horner_mpq.c create mode 100644 external/flint-2.4.3/fmpz_poly/evaluate_mod.c create mode 100644 external/flint-2.4.3/fmpz_poly/evaluate_mpq.c create mode 100644 external/flint-2.4.3/fmpz_poly/fit_length.c create mode 100644 external/flint-2.4.3/fmpz_poly/fprint.c create mode 100644 external/flint-2.4.3/fmpz_poly/fprint_pretty.c create mode 100644 external/flint-2.4.3/fmpz_poly/fread.c create mode 100644 external/flint-2.4.3/fmpz_poly/fread_pretty.c create mode 100644 external/flint-2.4.3/fmpz_poly/gcd.c create mode 100644 external/flint-2.4.3/fmpz_poly/gcd_heuristic.c create mode 100644 external/flint-2.4.3/fmpz_poly/gcd_modular.c create mode 100644 external/flint-2.4.3/fmpz_poly/gcd_subresultant.c create mode 100644 external/flint-2.4.3/fmpz_poly/get_coeff_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_poly/get_coeff_si.c create mode 100644 external/flint-2.4.3/fmpz_poly/get_coeff_ui.c create mode 100644 external/flint-2.4.3/fmpz_poly/get_nmod_poly.c create mode 100644 external/flint-2.4.3/fmpz_poly/get_str.c create mode 100644 external/flint-2.4.3/fmpz_poly/get_str_pretty.c create mode 100644 external/flint-2.4.3/fmpz_poly/hensel_build_tree.c create mode 100644 external/flint-2.4.3/fmpz_poly/hensel_continue_lift.c create mode 100644 external/flint-2.4.3/fmpz_poly/hensel_lift.c create mode 100644 external/flint-2.4.3/fmpz_poly/hensel_lift_once.c create mode 100644 external/flint-2.4.3/fmpz_poly/hensel_lift_only_inverse.c create mode 100644 external/flint-2.4.3/fmpz_poly/hensel_lift_tree.c create mode 100644 external/flint-2.4.3/fmpz_poly/hensel_lift_tree_recursive.c create mode 100644 external/flint-2.4.3/fmpz_poly/hensel_lift_without_inverse.c create mode 100644 external/flint-2.4.3/fmpz_poly/hensel_start_lift.c create mode 100644 external/flint-2.4.3/fmpz_poly/init.c create mode 100644 external/flint-2.4.3/fmpz_poly/interpolate_fmpz_vec.c create mode 100644 external/flint-2.4.3/fmpz_poly/inv_series_newton.c create mode 100644 external/flint-2.4.3/fmpz_poly/is_squarefree.c create mode 100644 external/flint-2.4.3/fmpz_poly/lcm.c create mode 100644 external/flint-2.4.3/fmpz_poly/monomial_to_newton.c create mode 100644 external/flint-2.4.3/fmpz_poly/mul.c create mode 100644 external/flint-2.4.3/fmpz_poly/mul_KS.c create mode 100644 external/flint-2.4.3/fmpz_poly/mul_SS.c create mode 100644 external/flint-2.4.3/fmpz_poly/mul_classical.c create mode 100644 external/flint-2.4.3/fmpz_poly/mul_karatsuba.c create mode 100644 external/flint-2.4.3/fmpz_poly/mulhigh_classical.c create mode 100644 external/flint-2.4.3/fmpz_poly/mulhigh_karatsuba_n.c create mode 100644 external/flint-2.4.3/fmpz_poly/mulhigh_n.c create mode 100644 external/flint-2.4.3/fmpz_poly/mullow.c create mode 100644 external/flint-2.4.3/fmpz_poly/mullow_KS.c create mode 100644 external/flint-2.4.3/fmpz_poly/mullow_SS.c create mode 100644 external/flint-2.4.3/fmpz_poly/mullow_classical.c create mode 100644 external/flint-2.4.3/fmpz_poly/mullow_karatsuba_n.c create mode 100644 external/flint-2.4.3/fmpz_poly/mulmid_classical.c create mode 100644 external/flint-2.4.3/fmpz_poly/neg.c create mode 100644 external/flint-2.4.3/fmpz_poly/newton_to_monomial.c create mode 100644 external/flint-2.4.3/fmpz_poly/normalise.c create mode 100644 external/flint-2.4.3/fmpz_poly/pow.c create mode 100644 external/flint-2.4.3/fmpz_poly/pow_addchains.c create mode 100644 external/flint-2.4.3/fmpz_poly/pow_binexp.c create mode 100644 external/flint-2.4.3/fmpz_poly/pow_binomial.c create mode 100644 external/flint-2.4.3/fmpz_poly/pow_multinomial.c create mode 100644 external/flint-2.4.3/fmpz_poly/pow_small.c create mode 100644 external/flint-2.4.3/fmpz_poly/pow_trunc.c create mode 100644 external/flint-2.4.3/fmpz_poly/powers_clear.c create mode 100644 external/flint-2.4.3/fmpz_poly/powers_precompute.c create mode 100644 external/flint-2.4.3/fmpz_poly/preinvert.c create mode 100644 external/flint-2.4.3/fmpz_poly/primitive_part.c create mode 100644 external/flint-2.4.3/fmpz_poly/product_roots_fmpz_vec.c create mode 100644 external/flint-2.4.3/fmpz_poly/profile/bm-div_divconquer.c create mode 100644 external/flint-2.4.3/fmpz_poly/profile/p-compose.c create mode 100644 external/flint-2.4.3/fmpz_poly/profile/p-mul.c create mode 100644 external/flint-2.4.3/fmpz_poly/profile/p-mul_triangle.c create mode 100644 external/flint-2.4.3/fmpz_poly/profile/p-pow.c create mode 100644 external/flint-2.4.3/fmpz_poly/profile/p-pow_binomial.c create mode 100644 external/flint-2.4.3/fmpz_poly/profile/p-rem_powers_precomp.c create mode 100644 external/flint-2.4.3/fmpz_poly/pseudo_div.c create mode 100644 external/flint-2.4.3/fmpz_poly/pseudo_divrem_basecase.c create mode 100644 external/flint-2.4.3/fmpz_poly/pseudo_divrem_cohen.c create mode 100644 external/flint-2.4.3/fmpz_poly/pseudo_divrem_divconquer.c create mode 100644 external/flint-2.4.3/fmpz_poly/pseudo_rem.c create mode 100644 external/flint-2.4.3/fmpz_poly/pseudo_rem_cohen.c create mode 100644 external/flint-2.4.3/fmpz_poly/randtest.c create mode 100644 external/flint-2.4.3/fmpz_poly/realloc.c create mode 100644 external/flint-2.4.3/fmpz_poly/rem.c create mode 100644 external/flint-2.4.3/fmpz_poly/rem_basecase.c create mode 100644 external/flint-2.4.3/fmpz_poly/rem_powers_precomp.c create mode 100644 external/flint-2.4.3/fmpz_poly/resultant.c create mode 100644 external/flint-2.4.3/fmpz_poly/reverse.c create mode 100644 external/flint-2.4.3/fmpz_poly/revert_series.c create mode 100644 external/flint-2.4.3/fmpz_poly/revert_series_lagrange.c create mode 100644 external/flint-2.4.3/fmpz_poly/revert_series_lagrange_fast.c create mode 100644 external/flint-2.4.3/fmpz_poly/revert_series_newton.c create mode 100644 external/flint-2.4.3/fmpz_poly/scalar_addmul_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_poly/scalar_divexact_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_poly/scalar_divexact_si.c create mode 100644 external/flint-2.4.3/fmpz_poly/scalar_divexact_ui.c create mode 100644 external/flint-2.4.3/fmpz_poly/scalar_fdiv_2exp.c create mode 100644 external/flint-2.4.3/fmpz_poly/scalar_fdiv_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_poly/scalar_fdiv_si.c create mode 100644 external/flint-2.4.3/fmpz_poly/scalar_fdiv_ui.c create mode 100644 external/flint-2.4.3/fmpz_poly/scalar_mul_2exp.c create mode 100644 external/flint-2.4.3/fmpz_poly/scalar_mul_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_poly/scalar_mul_si.c create mode 100644 external/flint-2.4.3/fmpz_poly/scalar_mul_ui.c create mode 100644 external/flint-2.4.3/fmpz_poly/scalar_submul_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_poly/scalar_tdiv_2exp.c create mode 100644 external/flint-2.4.3/fmpz_poly/scalar_tdiv_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_poly/scalar_tdiv_si.c create mode 100644 external/flint-2.4.3/fmpz_poly/scalar_tdiv_ui.c create mode 100644 external/flint-2.4.3/fmpz_poly/set.c create mode 100644 external/flint-2.4.3/fmpz_poly/set_coeff_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_poly/set_coeff_si.c create mode 100644 external/flint-2.4.3/fmpz_poly/set_coeff_ui.c create mode 100644 external/flint-2.4.3/fmpz_poly/set_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_poly/set_mpz.c create mode 100644 external/flint-2.4.3/fmpz_poly/set_nmod_poly.c create mode 100644 external/flint-2.4.3/fmpz_poly/set_nmod_poly_unsigned.c create mode 100644 external/flint-2.4.3/fmpz_poly/set_si.c create mode 100644 external/flint-2.4.3/fmpz_poly/set_str.c create mode 100644 external/flint-2.4.3/fmpz_poly/set_ui.c create mode 100644 external/flint-2.4.3/fmpz_poly/shift_left.c create mode 100644 external/flint-2.4.3/fmpz_poly/shift_right.c create mode 100644 external/flint-2.4.3/fmpz_poly/signature.c create mode 100644 external/flint-2.4.3/fmpz_poly/sqr.c create mode 100644 external/flint-2.4.3/fmpz_poly/sqr_KS.c create mode 100644 external/flint-2.4.3/fmpz_poly/sqr_classical.c create mode 100644 external/flint-2.4.3/fmpz_poly/sqr_karatsuba.c create mode 100644 external/flint-2.4.3/fmpz_poly/sqrlow.c create mode 100644 external/flint-2.4.3/fmpz_poly/sqrlow_KS.c create mode 100644 external/flint-2.4.3/fmpz_poly/sqrlow_classical.c create mode 100644 external/flint-2.4.3/fmpz_poly/sqrlow_karatsuba_n.c create mode 100644 external/flint-2.4.3/fmpz_poly/sqrt.c create mode 100644 external/flint-2.4.3/fmpz_poly/sqrt_classical.c create mode 100644 external/flint-2.4.3/fmpz_poly/sub.c create mode 100644 external/flint-2.4.3/fmpz_poly/swap.c create mode 100644 external/flint-2.4.3/fmpz_poly/taylor_shift.c create mode 100644 external/flint-2.4.3/fmpz_poly/taylor_shift_divconquer.c create mode 100644 external/flint-2.4.3/fmpz_poly/taylor_shift_horner.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-2norm_normalised_bits.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-CRT_ui.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-CRT_ui_unsigned.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-add.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-bit_pack.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-bound_roots.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-compose.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-compose_divconquer.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-compose_horner.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-compose_series.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-compose_series_brent_kung.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-compose_series_horner.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-content.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-derivative.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-div_basecase.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-div_divconquer.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-div_preinv.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-div_root.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-div_series.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-divides.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-divrem_basecase.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-divrem_divconquer.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-divrem_preinv.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-equal_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-evaluate_divconquer_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-evaluate_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-evaluate_horner_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-evaluate_horner_mpq.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-evaluate_mod.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-gcd.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-gcd_heuristic.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-gcd_modular.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-gcd_subresultant.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-get_coeff_ptr.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-get_nmod_poly.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-get_set_coeff_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-get_set_coeff_mpz.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-get_set_coeff_si.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-get_set_coeff_ui.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-get_set_str.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-get_str.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-get_str_pretty.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-hensel_lift.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-hensel_lift_once.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-hensel_lift_without_only_inverse.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-hensel_start_continue_lift.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-init_realloc_clear.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-interpolate_fmpz_vec.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-inv_series_newton.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-is_squarefree.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-lcm.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-mul.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-mul_KS.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-mul_SS.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-mul_classical.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-mul_karatsuba.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-mulhigh_classical.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-mulhigh_karatsuba_n.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-mulhigh_n.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-mullow.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-mullow_KS.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-mullow_SS.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-mullow_classical.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-mullow_karatsuba_n.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-mulmid_classical.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-neg.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-newton_to_monomial.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-pow.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-pow_addchains.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-pow_binexp.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-pow_binomial.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-pow_multinomial.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-pow_trunc.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-primitive_part.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-print_read.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-print_read_pretty.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-product_roots_fmpz_vec.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-pseudo_div.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-pseudo_divrem_basecase.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-pseudo_divrem_cohen.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-pseudo_divrem_divconquer.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-pseudo_rem.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-pseudo_rem_cohen.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-rem_basecase.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-rem_powers_precomp.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-resultant.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-reverse.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-revert_series.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-revert_series_lagrange.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-revert_series_lagrange_fast.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-revert_series_newton.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-scalar_addmul_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-scalar_divexact_mpz.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-scalar_fdiv_mpz.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-scalar_mul_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-scalar_mul_mpz.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-scalar_mul_si.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-scalar_mul_ui.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-scalar_submul_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-set_equal.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-set_fmpz_equal.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-set_mpz_equal.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-set_si_equal.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-set_ui_equal.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-shift_left_right.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-signature.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-sqr.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-sqr_KS.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-sqr_classical.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-sqr_karatsuba.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-sqrlow.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-sqrlow_KS.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-sqrlow_classical.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-sqrlow_karatsuba_n.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-sqrt.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-sub.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-swap.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-taylor_shift.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-taylor_shift_divconquer.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-taylor_shift_horner.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-xgcd_modular.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-zero.c create mode 100644 external/flint-2.4.3/fmpz_poly/test/t-zero_coeffs.c create mode 100644 external/flint-2.4.3/fmpz_poly/xgcd_modular.c create mode 100644 external/flint-2.4.3/fmpz_poly/zero_coeffs.c create mode 100644 external/flint-2.4.3/fmpz_poly_factor.h create mode 100644 external/flint-2.4.3/fmpz_poly_factor/clear.c create mode 100644 external/flint-2.4.3/fmpz_poly_factor/concat.c create mode 100644 external/flint-2.4.3/fmpz_poly_factor/doc/fmpz_poly_factor.txt create mode 100644 external/flint-2.4.3/fmpz_poly_factor/factor_squarefree.c create mode 100644 external/flint-2.4.3/fmpz_poly_factor/factor_zassenhaus.c create mode 100644 external/flint-2.4.3/fmpz_poly_factor/factor_zassenhaus_recombination.c create mode 100644 external/flint-2.4.3/fmpz_poly_factor/fit_length.c create mode 100644 external/flint-2.4.3/fmpz_poly_factor/init.c create mode 100644 external/flint-2.4.3/fmpz_poly_factor/insert.c create mode 100644 external/flint-2.4.3/fmpz_poly_factor/print.c create mode 100644 external/flint-2.4.3/fmpz_poly_factor/realloc.c create mode 100644 external/flint-2.4.3/fmpz_poly_factor/set.c create mode 100644 external/flint-2.4.3/fmpz_poly_factor/test/t-factor_squarefree.c create mode 100644 external/flint-2.4.3/fmpz_poly_factor/test/t-factor_zassenhaus.c create mode 100644 external/flint-2.4.3/fmpz_poly_factorxx.h create mode 100644 external/flint-2.4.3/fmpz_poly_mat.h create mode 100644 external/flint-2.4.3/fmpz_poly_mat/add.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/clear.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/det.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/det_fflu.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/det_interpolate.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/doc/fmpz_poly_mat.txt create mode 100644 external/flint-2.4.3/fmpz_poly_mat/equal.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/evaluate_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/fflu.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/find_pivot_any.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/find_pivot_partial.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/init.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/init_set.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/inv.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/is_one.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/is_zero.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/max_bits.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/max_length.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/mul.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/mul_KS.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/mul_classical.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/mullow.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/neg.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/nullspace.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/one.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/pow.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/pow_trunc.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/print.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/prod.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/randtest.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/randtest_sparse.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/randtest_unsigned.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/rank.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/rref.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/scalar_mul_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/scalar_mul_fmpz_poly.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/set.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/solve.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/solve_fflu.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/solve_fflu_precomp.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/sqr.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/sqr_KS.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/sqr_classical.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/sqrlow.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/sub.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/swap.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/test/t-add.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/test/t-det.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/test/t-det_interpolate.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/test/t-init_clear.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/test/t-inv.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/test/t-mul.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/test/t-mul_KS.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/test/t-mullow.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/test/t-neg.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/test/t-nullspace.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/test/t-one.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/test/t-pow.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/test/t-pow_trunc.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/test/t-prod.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/test/t-rank.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/test/t-rref.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/test/t-solve_fflu.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/test/t-sqr.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/test/t-sqr_KS.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/test/t-sqrlow.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/test/t-sub.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/test/t-trace.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/test/t-zero.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/trace.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/transpose.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/truncate.c create mode 100644 external/flint-2.4.3/fmpz_poly_mat/zero.c create mode 100644 external/flint-2.4.3/fmpz_poly_matxx.h create mode 100644 external/flint-2.4.3/fmpz_poly_q.h create mode 100644 external/flint-2.4.3/fmpz_poly_q/add.c create mode 100644 external/flint-2.4.3/fmpz_poly_q/addmul.c create mode 100644 external/flint-2.4.3/fmpz_poly_q/canonicalise.c create mode 100644 external/flint-2.4.3/fmpz_poly_q/clear.c create mode 100644 external/flint-2.4.3/fmpz_poly_q/derivative.c create mode 100644 external/flint-2.4.3/fmpz_poly_q/div.c create mode 100644 external/flint-2.4.3/fmpz_poly_q/doc/fmpz_poly_q.txt create mode 100644 external/flint-2.4.3/fmpz_poly_q/evaluate.c create mode 100644 external/flint-2.4.3/fmpz_poly_q/get_str.c create mode 100644 external/flint-2.4.3/fmpz_poly_q/get_str_pretty.c create mode 100644 external/flint-2.4.3/fmpz_poly_q/init.c create mode 100644 external/flint-2.4.3/fmpz_poly_q/inv.c create mode 100644 external/flint-2.4.3/fmpz_poly_q/is_canonical.c create mode 100644 external/flint-2.4.3/fmpz_poly_q/mul.c create mode 100644 external/flint-2.4.3/fmpz_poly_q/pow.c create mode 100644 external/flint-2.4.3/fmpz_poly_q/print.c create mode 100644 external/flint-2.4.3/fmpz_poly_q/print_pretty.c create mode 100644 external/flint-2.4.3/fmpz_poly_q/randtest.c create mode 100644 external/flint-2.4.3/fmpz_poly_q/scalar_div_mpq.c create mode 100644 external/flint-2.4.3/fmpz_poly_q/scalar_div_mpz.c create mode 100644 external/flint-2.4.3/fmpz_poly_q/scalar_div_si.c create mode 100644 external/flint-2.4.3/fmpz_poly_q/scalar_mul_mpq.c create mode 100644 external/flint-2.4.3/fmpz_poly_q/scalar_mul_mpz.c create mode 100644 external/flint-2.4.3/fmpz_poly_q/scalar_mul_si.c create mode 100644 external/flint-2.4.3/fmpz_poly_q/set.c create mode 100644 external/flint-2.4.3/fmpz_poly_q/set_si.c create mode 100644 external/flint-2.4.3/fmpz_poly_q/set_str.c create mode 100644 external/flint-2.4.3/fmpz_poly_q/sub.c create mode 100644 external/flint-2.4.3/fmpz_poly_q/submul.c create mode 100644 external/flint-2.4.3/fmpz_poly_q/swap.c create mode 100644 external/flint-2.4.3/fmpz_poly_q/test/t-add.c create mode 100644 external/flint-2.4.3/fmpz_poly_q/test/t-addmul.c create mode 100644 external/flint-2.4.3/fmpz_poly_q/test/t-all.c create mode 100644 external/flint-2.4.3/fmpz_poly_q/test/t-derivative.c create mode 100644 external/flint-2.4.3/fmpz_poly_q/test/t-div.c create mode 100644 external/flint-2.4.3/fmpz_poly_q/test/t-evaluate.c create mode 100644 external/flint-2.4.3/fmpz_poly_q/test/t-init_clear.c create mode 100644 external/flint-2.4.3/fmpz_poly_q/test/t-inv.c create mode 100644 external/flint-2.4.3/fmpz_poly_q/test/t-mul.c create mode 100644 external/flint-2.4.3/fmpz_poly_q/test/t-neg.c create mode 100644 external/flint-2.4.3/fmpz_poly_q/test/t-pow.c create mode 100644 external/flint-2.4.3/fmpz_poly_q/test/t-scalar_div_mpq.c create mode 100644 external/flint-2.4.3/fmpz_poly_q/test/t-scalar_div_mpz.c create mode 100644 external/flint-2.4.3/fmpz_poly_q/test/t-scalar_div_si.c create mode 100644 external/flint-2.4.3/fmpz_poly_q/test/t-scalar_mul_mpq.c create mode 100644 external/flint-2.4.3/fmpz_poly_q/test/t-scalar_mul_mpz.c create mode 100644 external/flint-2.4.3/fmpz_poly_q/test/t-scalar_mul_si.c create mode 100644 external/flint-2.4.3/fmpz_poly_q/test/t-set_equal.c create mode 100644 external/flint-2.4.3/fmpz_poly_q/test/t-set_si_equal.c create mode 100644 external/flint-2.4.3/fmpz_poly_q/test/t-sub.c create mode 100644 external/flint-2.4.3/fmpz_poly_q/test/t-submul.c create mode 100644 external/flint-2.4.3/fmpz_poly_q/test/t-swap.c create mode 100644 external/flint-2.4.3/fmpz_poly_q/test/t-zero.c create mode 100644 external/flint-2.4.3/fmpz_poly_qxx.h create mode 100644 external/flint-2.4.3/fmpz_polyxx.h create mode 100644 external/flint-2.4.3/fmpz_vec.h create mode 100644 external/flint-2.4.3/fmpz_vec/add.c create mode 100644 external/flint-2.4.3/fmpz_vec/clear.c create mode 100644 external/flint-2.4.3/fmpz_vec/content.c create mode 100644 external/flint-2.4.3/fmpz_vec/doc/fmpz_vec.txt create mode 100644 external/flint-2.4.3/fmpz_vec/equal.c create mode 100644 external/flint-2.4.3/fmpz_vec/fprint.c create mode 100644 external/flint-2.4.3/fmpz_vec/fread.c create mode 100644 external/flint-2.4.3/fmpz_vec/get_fft.c create mode 100644 external/flint-2.4.3/fmpz_vec/get_nmod_vec.c create mode 100644 external/flint-2.4.3/fmpz_vec/height.c create mode 100644 external/flint-2.4.3/fmpz_vec/height_index.c create mode 100644 external/flint-2.4.3/fmpz_vec/init.c create mode 100644 external/flint-2.4.3/fmpz_vec/is_zero.c create mode 100644 external/flint-2.4.3/fmpz_vec/lcm.c create mode 100644 external/flint-2.4.3/fmpz_vec/max_bits.c create mode 100644 external/flint-2.4.3/fmpz_vec/max_bits_ref.c create mode 100644 external/flint-2.4.3/fmpz_vec/max_limbs.c create mode 100644 external/flint-2.4.3/fmpz_vec/neg.c create mode 100644 external/flint-2.4.3/fmpz_vec/prod.c create mode 100644 external/flint-2.4.3/fmpz_vec/randtest.c create mode 100644 external/flint-2.4.3/fmpz_vec/scalar_addmul_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_vec/scalar_addmul_si.c create mode 100644 external/flint-2.4.3/fmpz_vec/scalar_addmul_si_2exp.c create mode 100644 external/flint-2.4.3/fmpz_vec/scalar_divexact_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_vec/scalar_divexact_si.c create mode 100644 external/flint-2.4.3/fmpz_vec/scalar_divexact_ui.c create mode 100644 external/flint-2.4.3/fmpz_vec/scalar_fdiv_q_2exp.c create mode 100644 external/flint-2.4.3/fmpz_vec/scalar_fdiv_q_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_vec/scalar_fdiv_q_si.c create mode 100644 external/flint-2.4.3/fmpz_vec/scalar_fdiv_q_ui.c create mode 100644 external/flint-2.4.3/fmpz_vec/scalar_fdiv_r_2exp.c create mode 100644 external/flint-2.4.3/fmpz_vec/scalar_mod_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_vec/scalar_mul_2exp.c create mode 100644 external/flint-2.4.3/fmpz_vec/scalar_mul_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_vec/scalar_mul_si.c create mode 100644 external/flint-2.4.3/fmpz_vec/scalar_mul_ui.c create mode 100644 external/flint-2.4.3/fmpz_vec/scalar_smod_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_vec/scalar_submul_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_vec/scalar_submul_si.c create mode 100644 external/flint-2.4.3/fmpz_vec/scalar_submul_si_2exp.c create mode 100644 external/flint-2.4.3/fmpz_vec/scalar_tdiv_q_2exp.c create mode 100644 external/flint-2.4.3/fmpz_vec/scalar_tdiv_q_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_vec/scalar_tdiv_q_si.c create mode 100644 external/flint-2.4.3/fmpz_vec/scalar_tdiv_q_ui.c create mode 100644 external/flint-2.4.3/fmpz_vec/set.c create mode 100644 external/flint-2.4.3/fmpz_vec/set_fft.c create mode 100644 external/flint-2.4.3/fmpz_vec/set_nmod_vec.c create mode 100644 external/flint-2.4.3/fmpz_vec/sort.c create mode 100644 external/flint-2.4.3/fmpz_vec/sub.c create mode 100644 external/flint-2.4.3/fmpz_vec/sum.c create mode 100644 external/flint-2.4.3/fmpz_vec/swap.c create mode 100644 external/flint-2.4.3/fmpz_vec/test/t-add.c create mode 100644 external/flint-2.4.3/fmpz_vec/test/t-content.c create mode 100644 external/flint-2.4.3/fmpz_vec/test/t-get_set_fft.c create mode 100644 external/flint-2.4.3/fmpz_vec/test/t-get_set_nmod_vec.c create mode 100644 external/flint-2.4.3/fmpz_vec/test/t-height.c create mode 100644 external/flint-2.4.3/fmpz_vec/test/t-height_index.c create mode 100644 external/flint-2.4.3/fmpz_vec/test/t-init_clear.c create mode 100644 external/flint-2.4.3/fmpz_vec/test/t-is_zero.c create mode 100644 external/flint-2.4.3/fmpz_vec/test/t-lcm.c create mode 100644 external/flint-2.4.3/fmpz_vec/test/t-max_bits.c create mode 100644 external/flint-2.4.3/fmpz_vec/test/t-max_limbs.c create mode 100644 external/flint-2.4.3/fmpz_vec/test/t-neg.c create mode 100644 external/flint-2.4.3/fmpz_vec/test/t-prod.c create mode 100644 external/flint-2.4.3/fmpz_vec/test/t-scalar_addmul_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_vec/test/t-scalar_addmul_si.c create mode 100644 external/flint-2.4.3/fmpz_vec/test/t-scalar_addmul_si_2exp.c create mode 100644 external/flint-2.4.3/fmpz_vec/test/t-scalar_divexact_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_vec/test/t-scalar_divexact_si.c create mode 100644 external/flint-2.4.3/fmpz_vec/test/t-scalar_divexact_ui.c create mode 100644 external/flint-2.4.3/fmpz_vec/test/t-scalar_fdiv_q_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_vec/test/t-scalar_mod_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_vec/test/t-scalar_mul_2exp.c create mode 100644 external/flint-2.4.3/fmpz_vec/test/t-scalar_mul_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_vec/test/t-scalar_mul_si.c create mode 100644 external/flint-2.4.3/fmpz_vec/test/t-scalar_mul_ui.c create mode 100644 external/flint-2.4.3/fmpz_vec/test/t-scalar_smod_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_vec/test/t-scalar_submul_fmpz.c create mode 100644 external/flint-2.4.3/fmpz_vec/test/t-scalar_submul_si.c create mode 100644 external/flint-2.4.3/fmpz_vec/test/t-scalar_submul_si_2exp.c create mode 100644 external/flint-2.4.3/fmpz_vec/test/t-set_equal.c create mode 100644 external/flint-2.4.3/fmpz_vec/test/t-sub.c create mode 100644 external/flint-2.4.3/fmpz_vec/test/t-sum.c create mode 100644 external/flint-2.4.3/fmpz_vec/test/t-swap.c create mode 100644 external/flint-2.4.3/fmpz_vec/test/t-zero.c create mode 100644 external/flint-2.4.3/fmpz_vec/zero.c create mode 100644 external/flint-2.4.3/fmpz_vecxx.h create mode 100644 external/flint-2.4.3/fmpzxx.h create mode 100644 external/flint-2.4.3/fprintf.c create mode 100644 external/flint-2.4.3/fq.h create mode 100644 external/flint-2.4.3/fq/Makefile create mode 100644 external/flint-2.4.3/fq/add.c create mode 100644 external/flint-2.4.3/fq/bit_pack.c create mode 100644 external/flint-2.4.3/fq/bit_unpack.c create mode 100644 external/flint-2.4.3/fq/ctx_clear.c create mode 100644 external/flint-2.4.3/fq/ctx_init.c create mode 100644 external/flint-2.4.3/fq/ctx_init_conway.c create mode 100644 external/flint-2.4.3/fq/ctx_init_modulus.c create mode 100644 external/flint-2.4.3/fq/ctx_randtest.c create mode 100644 external/flint-2.4.3/fq/doc/fq.txt create mode 100644 external/flint-2.4.3/fq/frobenius.c create mode 100644 external/flint-2.4.3/fq/get_str.c create mode 100644 external/flint-2.4.3/fq/get_str_pretty.c create mode 100644 external/flint-2.4.3/fq/inv.c create mode 100644 external/flint-2.4.3/fq/mul.c create mode 100644 external/flint-2.4.3/fq/mul_fmpz.c create mode 100644 external/flint-2.4.3/fq/mul_si.c create mode 100644 external/flint-2.4.3/fq/mul_ui.c create mode 100644 external/flint-2.4.3/fq/neg.c create mode 100644 external/flint-2.4.3/fq/norm.c create mode 100644 external/flint-2.4.3/fq/pow.c create mode 100644 external/flint-2.4.3/fq/pow_ui.c create mode 100644 external/flint-2.4.3/fq/profile/p-inv.c create mode 100644 external/flint-2.4.3/fq/profile/p-mul.c create mode 100644 external/flint-2.4.3/fq/profile/p-reduce.c create mode 100644 external/flint-2.4.3/fq/pth_root.c create mode 100644 external/flint-2.4.3/fq/randtest.c create mode 100644 external/flint-2.4.3/fq/sqr.c create mode 100644 external/flint-2.4.3/fq/sub.c create mode 100644 external/flint-2.4.3/fq/sub_one.c create mode 100644 external/flint-2.4.3/fq/test/t-add.c create mode 100644 external/flint-2.4.3/fq/test/t-ctx_init.c create mode 100644 external/flint-2.4.3/fq/test/t-frobenius.c create mode 100644 external/flint-2.4.3/fq/test/t-inv.c create mode 100644 external/flint-2.4.3/fq/test/t-mul.c create mode 100644 external/flint-2.4.3/fq/test/t-mul_fmpz.c create mode 100644 external/flint-2.4.3/fq/test/t-mul_si.c create mode 100644 external/flint-2.4.3/fq/test/t-mul_ui.c create mode 100644 external/flint-2.4.3/fq/test/t-neg.c create mode 100644 external/flint-2.4.3/fq/test/t-norm.c create mode 100644 external/flint-2.4.3/fq/test/t-pow.c create mode 100644 external/flint-2.4.3/fq/test/t-pth_root.c create mode 100644 external/flint-2.4.3/fq/test/t-sqr.c create mode 100644 external/flint-2.4.3/fq/test/t-sub.c create mode 100644 external/flint-2.4.3/fq/test/t-trace.c create mode 100644 external/flint-2.4.3/fq/trace.c create mode 100644 external/flint-2.4.3/fq_mat.h create mode 100644 external/flint-2.4.3/fq_mat/add.c create mode 100644 external/flint-2.4.3/fq_mat/clear.c create mode 100644 external/flint-2.4.3/fq_mat/doc/fq_mat.txt create mode 100644 external/flint-2.4.3/fq_mat/equal.c create mode 100644 external/flint-2.4.3/fq_mat/fprint.c create mode 100644 external/flint-2.4.3/fq_mat/init.c create mode 100644 external/flint-2.4.3/fq_mat/init_set.c create mode 100644 external/flint-2.4.3/fq_mat/is_zero.c create mode 100644 external/flint-2.4.3/fq_mat/lu.c create mode 100644 external/flint-2.4.3/fq_mat/lu_classical.c create mode 100644 external/flint-2.4.3/fq_mat/lu_recursive.c create mode 100644 external/flint-2.4.3/fq_mat/mul.c create mode 100644 external/flint-2.4.3/fq_mat/mul_KS.c create mode 100644 external/flint-2.4.3/fq_mat/mul_classical.c create mode 100644 external/flint-2.4.3/fq_mat/neg.c create mode 100644 external/flint-2.4.3/fq_mat/profile/p-mul.c create mode 100644 external/flint-2.4.3/fq_mat/randops.c create mode 100644 external/flint-2.4.3/fq_mat/randpermdiag.c create mode 100644 external/flint-2.4.3/fq_mat/randrank.c create mode 100644 external/flint-2.4.3/fq_mat/randtest.c create mode 100644 external/flint-2.4.3/fq_mat/randtril.c create mode 100644 external/flint-2.4.3/fq_mat/randtriu.c create mode 100644 external/flint-2.4.3/fq_mat/rref.c create mode 100644 external/flint-2.4.3/fq_mat/set.c create mode 100644 external/flint-2.4.3/fq_mat/solve_tril.c create mode 100644 external/flint-2.4.3/fq_mat/solve_tril_classical.c create mode 100644 external/flint-2.4.3/fq_mat/solve_tril_recursive.c create mode 100644 external/flint-2.4.3/fq_mat/solve_triu.c create mode 100644 external/flint-2.4.3/fq_mat/solve_triu_classical.c create mode 100644 external/flint-2.4.3/fq_mat/solve_triu_recursive.c create mode 100644 external/flint-2.4.3/fq_mat/sub.c create mode 100644 external/flint-2.4.3/fq_mat/submul.c create mode 100644 external/flint-2.4.3/fq_mat/swap.c create mode 100644 external/flint-2.4.3/fq_mat/test/t-add_sub.c create mode 100644 external/flint-2.4.3/fq_mat/test/t-equal.c create mode 100644 external/flint-2.4.3/fq_mat/test/t-is_zero.c create mode 100644 external/flint-2.4.3/fq_mat/test/t-lu_classical.c create mode 100644 external/flint-2.4.3/fq_mat/test/t-lu_recursive.c create mode 100644 external/flint-2.4.3/fq_mat/test/t-mul.c create mode 100644 external/flint-2.4.3/fq_mat/test/t-mul_KS.c create mode 100644 external/flint-2.4.3/fq_mat/test/t-rref.c create mode 100644 external/flint-2.4.3/fq_mat/test/t-solve_tril.c create mode 100644 external/flint-2.4.3/fq_mat/test/t-solve_tril_classical.c create mode 100644 external/flint-2.4.3/fq_mat/test/t-solve_tril_recursive.c create mode 100644 external/flint-2.4.3/fq_mat/test/t-solve_triu.c create mode 100644 external/flint-2.4.3/fq_mat/test/t-solve_triu_classical.c create mode 100644 external/flint-2.4.3/fq_mat/test/t-solve_triu_recursive.c create mode 100644 external/flint-2.4.3/fq_mat/test/t-submul.c create mode 100644 external/flint-2.4.3/fq_mat/test/t-zero.c create mode 100644 external/flint-2.4.3/fq_mat/window_clear.c create mode 100644 external/flint-2.4.3/fq_mat/window_init.c create mode 100644 external/flint-2.4.3/fq_mat/zero.c create mode 100644 external/flint-2.4.3/fq_mat_templates.h create mode 100644 external/flint-2.4.3/fq_mat_templates/add.c create mode 100644 external/flint-2.4.3/fq_mat_templates/clear.c create mode 100644 external/flint-2.4.3/fq_mat_templates/equal.c create mode 100644 external/flint-2.4.3/fq_mat_templates/fprint.c create mode 100644 external/flint-2.4.3/fq_mat_templates/init.c create mode 100644 external/flint-2.4.3/fq_mat_templates/init_set.c create mode 100644 external/flint-2.4.3/fq_mat_templates/is_zero.c create mode 100644 external/flint-2.4.3/fq_mat_templates/lu.c create mode 100644 external/flint-2.4.3/fq_mat_templates/lu_classical.c create mode 100644 external/flint-2.4.3/fq_mat_templates/lu_recursive.c create mode 100644 external/flint-2.4.3/fq_mat_templates/mul.c create mode 100644 external/flint-2.4.3/fq_mat_templates/mul_KS.c create mode 100644 external/flint-2.4.3/fq_mat_templates/mul_classical.c create mode 100644 external/flint-2.4.3/fq_mat_templates/neg.c create mode 100644 external/flint-2.4.3/fq_mat_templates/profile/p-mul.c create mode 100644 external/flint-2.4.3/fq_mat_templates/randops.c create mode 100644 external/flint-2.4.3/fq_mat_templates/randpermdiag.c create mode 100644 external/flint-2.4.3/fq_mat_templates/randrank.c create mode 100644 external/flint-2.4.3/fq_mat_templates/randtest.c create mode 100644 external/flint-2.4.3/fq_mat_templates/randtril.c create mode 100644 external/flint-2.4.3/fq_mat_templates/randtriu.c create mode 100644 external/flint-2.4.3/fq_mat_templates/rref.c create mode 100644 external/flint-2.4.3/fq_mat_templates/set.c create mode 100644 external/flint-2.4.3/fq_mat_templates/solve_tril.c create mode 100644 external/flint-2.4.3/fq_mat_templates/solve_tril_classical.c create mode 100644 external/flint-2.4.3/fq_mat_templates/solve_tril_recursive.c create mode 100644 external/flint-2.4.3/fq_mat_templates/solve_triu.c create mode 100644 external/flint-2.4.3/fq_mat_templates/solve_triu_classical.c create mode 100644 external/flint-2.4.3/fq_mat_templates/solve_triu_recursive.c create mode 100644 external/flint-2.4.3/fq_mat_templates/sub.c create mode 100644 external/flint-2.4.3/fq_mat_templates/submul.c create mode 100644 external/flint-2.4.3/fq_mat_templates/swap.c create mode 100644 external/flint-2.4.3/fq_mat_templates/test/t-add_sub.c create mode 100644 external/flint-2.4.3/fq_mat_templates/test/t-equal.c create mode 100644 external/flint-2.4.3/fq_mat_templates/test/t-is_zero.c create mode 100644 external/flint-2.4.3/fq_mat_templates/test/t-lu_classical.c create mode 100644 external/flint-2.4.3/fq_mat_templates/test/t-lu_recursive.c create mode 100644 external/flint-2.4.3/fq_mat_templates/test/t-mul.c create mode 100644 external/flint-2.4.3/fq_mat_templates/test/t-mul_KS.c create mode 100644 external/flint-2.4.3/fq_mat_templates/test/t-rref.c create mode 100644 external/flint-2.4.3/fq_mat_templates/test/t-solve_tril.c create mode 100644 external/flint-2.4.3/fq_mat_templates/test/t-solve_tril_classical.c create mode 100644 external/flint-2.4.3/fq_mat_templates/test/t-solve_tril_recursive.c create mode 100644 external/flint-2.4.3/fq_mat_templates/test/t-solve_triu.c create mode 100644 external/flint-2.4.3/fq_mat_templates/test/t-solve_triu_classical.c create mode 100644 external/flint-2.4.3/fq_mat_templates/test/t-solve_triu_recursive.c create mode 100644 external/flint-2.4.3/fq_mat_templates/test/t-submul.c create mode 100644 external/flint-2.4.3/fq_mat_templates/test/t-zero.c create mode 100644 external/flint-2.4.3/fq_mat_templates/window_clear.c create mode 100644 external/flint-2.4.3/fq_mat_templates/window_init.c create mode 100644 external/flint-2.4.3/fq_mat_templates/zero.c create mode 100644 external/flint-2.4.3/fq_nmod.h create mode 100644 external/flint-2.4.3/fq_nmod/add.c create mode 100644 external/flint-2.4.3/fq_nmod/bit_pack.c create mode 100644 external/flint-2.4.3/fq_nmod/bit_unpack.c create mode 100644 external/flint-2.4.3/fq_nmod/ctx_clear.c create mode 100644 external/flint-2.4.3/fq_nmod/ctx_init.c create mode 100644 external/flint-2.4.3/fq_nmod/ctx_init_conway.c create mode 100644 external/flint-2.4.3/fq_nmod/ctx_init_modulus.c create mode 100644 external/flint-2.4.3/fq_nmod/ctx_randtest.c create mode 100644 external/flint-2.4.3/fq_nmod/doc/fq_nmod.txt create mode 100644 external/flint-2.4.3/fq_nmod/frobenius.c create mode 100644 external/flint-2.4.3/fq_nmod/get_str.c create mode 100644 external/flint-2.4.3/fq_nmod/get_str_pretty.c create mode 100644 external/flint-2.4.3/fq_nmod/inv.c create mode 100644 external/flint-2.4.3/fq_nmod/mul.c create mode 100644 external/flint-2.4.3/fq_nmod/mul_fmpz.c create mode 100644 external/flint-2.4.3/fq_nmod/mul_si.c create mode 100644 external/flint-2.4.3/fq_nmod/mul_ui.c create mode 100644 external/flint-2.4.3/fq_nmod/neg.c create mode 100644 external/flint-2.4.3/fq_nmod/norm.c create mode 100644 external/flint-2.4.3/fq_nmod/pow.c create mode 100644 external/flint-2.4.3/fq_nmod/pth_root.c create mode 100644 external/flint-2.4.3/fq_nmod/randtest.c create mode 100644 external/flint-2.4.3/fq_nmod/sqr.c create mode 100644 external/flint-2.4.3/fq_nmod/sub.c create mode 100644 external/flint-2.4.3/fq_nmod/sub_one.c create mode 100644 external/flint-2.4.3/fq_nmod/test/t-add.c create mode 100644 external/flint-2.4.3/fq_nmod/test/t-ctx_init.c create mode 100644 external/flint-2.4.3/fq_nmod/test/t-frobenius.c create mode 100644 external/flint-2.4.3/fq_nmod/test/t-inv.c create mode 100644 external/flint-2.4.3/fq_nmod/test/t-mul.c create mode 100644 external/flint-2.4.3/fq_nmod/test/t-mul_fmpz.c create mode 100644 external/flint-2.4.3/fq_nmod/test/t-mul_si.c create mode 100644 external/flint-2.4.3/fq_nmod/test/t-mul_ui.c create mode 100644 external/flint-2.4.3/fq_nmod/test/t-neg.c create mode 100644 external/flint-2.4.3/fq_nmod/test/t-norm.c create mode 100644 external/flint-2.4.3/fq_nmod/test/t-pow.c create mode 100644 external/flint-2.4.3/fq_nmod/test/t-pth_root.c create mode 100644 external/flint-2.4.3/fq_nmod/test/t-sqr.c create mode 100644 external/flint-2.4.3/fq_nmod/test/t-sub.c create mode 100644 external/flint-2.4.3/fq_nmod/test/t-trace.c create mode 100644 external/flint-2.4.3/fq_nmod/trace.c create mode 100644 external/flint-2.4.3/fq_nmod_mat.h create mode 100644 external/flint-2.4.3/fq_nmod_mat/add.c create mode 100644 external/flint-2.4.3/fq_nmod_mat/clear.c create mode 100644 external/flint-2.4.3/fq_nmod_mat/doc/fq_nmod_mat.txt create mode 100644 external/flint-2.4.3/fq_nmod_mat/equal.c create mode 100644 external/flint-2.4.3/fq_nmod_mat/fprint.c create mode 100644 external/flint-2.4.3/fq_nmod_mat/init.c create mode 100644 external/flint-2.4.3/fq_nmod_mat/init_set.c create mode 100644 external/flint-2.4.3/fq_nmod_mat/is_zero.c create mode 100644 external/flint-2.4.3/fq_nmod_mat/lu.c create mode 100644 external/flint-2.4.3/fq_nmod_mat/lu_classical.c create mode 100644 external/flint-2.4.3/fq_nmod_mat/lu_recursive.c create mode 100644 external/flint-2.4.3/fq_nmod_mat/mul.c create mode 100644 external/flint-2.4.3/fq_nmod_mat/mul_KS.c create mode 100644 external/flint-2.4.3/fq_nmod_mat/mul_classical.c create mode 100644 external/flint-2.4.3/fq_nmod_mat/neg.c create mode 100644 external/flint-2.4.3/fq_nmod_mat/randops.c create mode 100644 external/flint-2.4.3/fq_nmod_mat/randpermdiag.c create mode 100644 external/flint-2.4.3/fq_nmod_mat/randrank.c create mode 100644 external/flint-2.4.3/fq_nmod_mat/randtest.c create mode 100644 external/flint-2.4.3/fq_nmod_mat/randtril.c create mode 100644 external/flint-2.4.3/fq_nmod_mat/randtriu.c create mode 100644 external/flint-2.4.3/fq_nmod_mat/rref.c create mode 100644 external/flint-2.4.3/fq_nmod_mat/set.c create mode 100644 external/flint-2.4.3/fq_nmod_mat/solve_tril.c create mode 100644 external/flint-2.4.3/fq_nmod_mat/solve_tril_classical.c create mode 100644 external/flint-2.4.3/fq_nmod_mat/solve_tril_recursive.c create mode 100644 external/flint-2.4.3/fq_nmod_mat/solve_triu.c create mode 100644 external/flint-2.4.3/fq_nmod_mat/solve_triu_classical.c create mode 100644 external/flint-2.4.3/fq_nmod_mat/solve_triu_recursive.c create mode 100644 external/flint-2.4.3/fq_nmod_mat/sub.c create mode 100644 external/flint-2.4.3/fq_nmod_mat/submul.c create mode 100644 external/flint-2.4.3/fq_nmod_mat/swap.c create mode 100644 external/flint-2.4.3/fq_nmod_mat/test/t-add_sub.c create mode 100644 external/flint-2.4.3/fq_nmod_mat/test/t-equal.c create mode 100644 external/flint-2.4.3/fq_nmod_mat/test/t-is_zero.c create mode 100644 external/flint-2.4.3/fq_nmod_mat/test/t-lu_classical.c create mode 100644 external/flint-2.4.3/fq_nmod_mat/test/t-lu_recursive.c create mode 100644 external/flint-2.4.3/fq_nmod_mat/test/t-mul.c create mode 100644 external/flint-2.4.3/fq_nmod_mat/test/t-mul_KS.c create mode 100644 external/flint-2.4.3/fq_nmod_mat/test/t-rref.c create mode 100644 external/flint-2.4.3/fq_nmod_mat/test/t-solve_tril.c create mode 100644 external/flint-2.4.3/fq_nmod_mat/test/t-solve_tril_classical.c create mode 100644 external/flint-2.4.3/fq_nmod_mat/test/t-solve_tril_recursive.c create mode 100644 external/flint-2.4.3/fq_nmod_mat/test/t-solve_triu.c create mode 100644 external/flint-2.4.3/fq_nmod_mat/test/t-solve_triu_classical.c create mode 100644 external/flint-2.4.3/fq_nmod_mat/test/t-solve_triu_recursive.c create mode 100644 external/flint-2.4.3/fq_nmod_mat/test/t-submul.c create mode 100644 external/flint-2.4.3/fq_nmod_mat/test/t-zero.c create mode 100644 external/flint-2.4.3/fq_nmod_mat/window_clear.c create mode 100644 external/flint-2.4.3/fq_nmod_mat/window_init.c create mode 100644 external/flint-2.4.3/fq_nmod_mat/zero.c create mode 100644 external/flint-2.4.3/fq_nmod_poly.h create mode 100644 external/flint-2.4.3/fq_nmod_poly/add.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/clear.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/compose.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/compose_divconquer.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/compose_horner.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/compose_mod.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/compose_mod_brent_kung.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/compose_mod_brent_kung_precomp_preinv.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/compose_mod_brent_kung_preinv.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/compose_mod_horner.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/compose_mod_horner_preinv.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/compose_mod_preinv.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/deflate.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/deflation.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/derivative.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/div_basecase.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/div_newton_n_preinv.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/divides.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/divrem_basecase.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/divrem_divconquer.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/divrem_divconquer_recursive.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/divrem_newton_n_preinv.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/doc/fq_nmod_poly.txt create mode 100644 external/flint-2.4.3/fq_nmod_poly/equal.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/evaluate_fq.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/fit_length.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/fprint.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/fprint_pretty.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/gcd_euclidean.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/gen.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/get_coeff.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/get_str.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/get_str_pretty.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/hamming_weight.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/inflate.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/init.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/inv_series_newton.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/make_monic.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/mul.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/mul_KS.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/mul_classical.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/mullow.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/mullow_KS.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/mullow_classical.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/mulmod.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/mulmod_preinv.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/neg.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/normalise.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/one.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/pow.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/powmod_fmpz_binexp.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/powmod_fmpz_binexp_preinv.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/powmod_fmpz_sliding_preinv.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/powmod_ui_binexp.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/powmod_ui_binexp_preinv.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/powmod_x_fmpz_preinv.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/profile/p-factor_kaltofen_shoup_vs_fq_poly.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/profile/p-factor_xnpxp1.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/profile/p-is_irreducible.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/profile/p-iterated_frobenius.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/profile/p-iterated_frobenius_table.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/profile/p-mullow.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/randtest.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/randtest_irreducible.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/randtest_monic.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/realloc.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/remove.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/reverse.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/scalar_addmul_fq.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/scalar_mul_fq.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/scalar_submul_fq.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/set.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/set_coeff.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/set_fq.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/shift_left.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/shift_right.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/sqr.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/sqr_KS.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/sqr_classical.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/sub.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/swap.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/test/t-add.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/test/t-compose.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/test/t-compose_divconquer.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/test/t-compose_horner.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/test/t-compose_mod.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/test/t-compose_mod_brent_kung.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/test/t-compose_mod_brent_kung_preinv.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/test/t-compose_mod_horner.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/test/t-compose_mod_horner_preinv.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/test/t-compose_mod_preinv.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/test/t-deflate.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/test/t-derivative.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/test/t-div_basecase.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/test/t-div_newton_n_preinv.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/test/t-divides.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/test/t-divrem_basecase.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/test/t-divrem_divconquer.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/test/t-divrem_newton_n_preinv.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/test/t-evaluate_fq.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/test/t-gcd_euclidean.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/test/t-get_str.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/test/t-get_str_pretty.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/test/t-hamming_weight.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/test/t-inflate.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/test/t-inv_series_newton.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/test/t-make_monic.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/test/t-mul.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/test/t-mul_KS.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/test/t-mul_classical.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/test/t-mullow.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/test/t-mullow_KS.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/test/t-mullow_classical.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/test/t-mulmod.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/test/t-mulmod_preinv.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/test/t-neg.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/test/t-pow.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/test/t-powmod_fmpz_binexp.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/test/t-powmod_fmpz_binexp_preinv.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/test/t-powmod_fmpz_sliding_preinv.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/test/t-powmod_ui_binexp.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/test/t-powmod_ui_binexp_preinv.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/test/t-powmod_x_fmpz_preinv.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/test/t-randtest_irreducible.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/test/t-scalar_addmul_fq.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/test/t-scalar_mul_fq.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/test/t-scalar_submul_fq.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/test/t-shift_left_right.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/test/t-sqr.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/test/t-sqr_KS.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/test/t-sqr_classical.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/test/t-sub.c create mode 100644 external/flint-2.4.3/fq_nmod_poly/truncate.c create mode 100644 external/flint-2.4.3/fq_nmod_poly_factor.h create mode 100644 external/flint-2.4.3/fq_nmod_poly_factor/clear.c create mode 100644 external/flint-2.4.3/fq_nmod_poly_factor/concat.c create mode 100644 external/flint-2.4.3/fq_nmod_poly_factor/doc/fq_nmod_poly_factor.txt create mode 100644 external/flint-2.4.3/fq_nmod_poly_factor/factor.c create mode 100644 external/flint-2.4.3/fq_nmod_poly_factor/factor_berlekamp.c create mode 100644 external/flint-2.4.3/fq_nmod_poly_factor/factor_cantor_zassenhaus.c create mode 100644 external/flint-2.4.3/fq_nmod_poly_factor/factor_distinct_deg.c create mode 100644 external/flint-2.4.3/fq_nmod_poly_factor/factor_equal_deg.c create mode 100644 external/flint-2.4.3/fq_nmod_poly_factor/factor_equal_deg_prob.c create mode 100644 external/flint-2.4.3/fq_nmod_poly_factor/factor_kaltofen_shoup.c create mode 100644 external/flint-2.4.3/fq_nmod_poly_factor/factor_squarefree.c create mode 100644 external/flint-2.4.3/fq_nmod_poly_factor/fit_length.c create mode 100644 external/flint-2.4.3/fq_nmod_poly_factor/init.c create mode 100644 external/flint-2.4.3/fq_nmod_poly_factor/insert.c create mode 100644 external/flint-2.4.3/fq_nmod_poly_factor/is_irreducible.c create mode 100644 external/flint-2.4.3/fq_nmod_poly_factor/is_irreducible_ben_or.c create mode 100644 external/flint-2.4.3/fq_nmod_poly_factor/is_irreducible_ddf.c create mode 100644 external/flint-2.4.3/fq_nmod_poly_factor/is_squarefree.c create mode 100644 external/flint-2.4.3/fq_nmod_poly_factor/iterated_frobenius_preinv.c create mode 100644 external/flint-2.4.3/fq_nmod_poly_factor/pow.c create mode 100644 external/flint-2.4.3/fq_nmod_poly_factor/print.c create mode 100644 external/flint-2.4.3/fq_nmod_poly_factor/print_pretty.c create mode 100644 external/flint-2.4.3/fq_nmod_poly_factor/realloc.c create mode 100644 external/flint-2.4.3/fq_nmod_poly_factor/set.c create mode 100644 external/flint-2.4.3/fq_nmod_poly_factor/test/t-factor.c create mode 100644 external/flint-2.4.3/fq_nmod_poly_factor/test/t-factor_berlekamp.c create mode 100644 external/flint-2.4.3/fq_nmod_poly_factor/test/t-factor_cantor_zassenhaus.c create mode 100644 external/flint-2.4.3/fq_nmod_poly_factor/test/t-factor_distinct_deg.c create mode 100644 external/flint-2.4.3/fq_nmod_poly_factor/test/t-factor_equal_deg_prob.c create mode 100644 external/flint-2.4.3/fq_nmod_poly_factor/test/t-factor_kaltofen_shoup.c create mode 100644 external/flint-2.4.3/fq_nmod_poly_factor/test/t-factor_squarefree.c create mode 100644 external/flint-2.4.3/fq_nmod_poly_factor/test/t-is_irreducible.c create mode 100644 external/flint-2.4.3/fq_nmod_poly_factor/test/t-is_irreducible_ben_or.c create mode 100644 external/flint-2.4.3/fq_nmod_poly_factor/test/t-is_irreducible_ddf.c create mode 100644 external/flint-2.4.3/fq_nmod_poly_factor/test/t-is_squarefree.c create mode 100644 external/flint-2.4.3/fq_nmod_poly_factor/test/t-iterated_frobenius_preinv.c create mode 100644 external/flint-2.4.3/fq_nmod_vec.h create mode 100644 external/flint-2.4.3/fq_nmod_vec/add.c create mode 100644 external/flint-2.4.3/fq_nmod_vec/clear.c create mode 100644 external/flint-2.4.3/fq_nmod_vec/doc/fq_nmod_vec.txt create mode 100644 external/flint-2.4.3/fq_nmod_vec/dot.c create mode 100644 external/flint-2.4.3/fq_nmod_vec/equal.c create mode 100644 external/flint-2.4.3/fq_nmod_vec/fprint.c create mode 100644 external/flint-2.4.3/fq_nmod_vec/init.c create mode 100644 external/flint-2.4.3/fq_nmod_vec/is_zero.c create mode 100644 external/flint-2.4.3/fq_nmod_vec/neg.c create mode 100644 external/flint-2.4.3/fq_nmod_vec/randtest.c create mode 100644 external/flint-2.4.3/fq_nmod_vec/scalar_addmul_fq.c create mode 100644 external/flint-2.4.3/fq_nmod_vec/scalar_submul_fq.c create mode 100644 external/flint-2.4.3/fq_nmod_vec/set.c create mode 100644 external/flint-2.4.3/fq_nmod_vec/sub.c create mode 100644 external/flint-2.4.3/fq_nmod_vec/swap.c create mode 100644 external/flint-2.4.3/fq_nmod_vec/test/t-add.c create mode 100644 external/flint-2.4.3/fq_nmod_vec/test/t-is_zero.c create mode 100644 external/flint-2.4.3/fq_nmod_vec/test/t-neg.c create mode 100644 external/flint-2.4.3/fq_nmod_vec/test/t-sub.c create mode 100644 external/flint-2.4.3/fq_nmod_vec/test/t-swap.c create mode 100644 external/flint-2.4.3/fq_nmod_vec/test/t-zero.c create mode 100644 external/flint-2.4.3/fq_nmod_vec/zero.c create mode 100644 external/flint-2.4.3/fq_poly.h create mode 100644 external/flint-2.4.3/fq_poly/Makefile create mode 100644 external/flint-2.4.3/fq_poly/add.c create mode 100644 external/flint-2.4.3/fq_poly/clear.c create mode 100644 external/flint-2.4.3/fq_poly/compose.c create mode 100644 external/flint-2.4.3/fq_poly/compose_divconquer.c create mode 100644 external/flint-2.4.3/fq_poly/compose_horner.c create mode 100644 external/flint-2.4.3/fq_poly/compose_mod.c create mode 100644 external/flint-2.4.3/fq_poly/compose_mod_brent_kung.c create mode 100644 external/flint-2.4.3/fq_poly/compose_mod_brent_kung_precomp_preinv.c create mode 100644 external/flint-2.4.3/fq_poly/compose_mod_brent_kung_preinv.c create mode 100644 external/flint-2.4.3/fq_poly/compose_mod_horner.c create mode 100644 external/flint-2.4.3/fq_poly/compose_mod_horner_preinv.c create mode 100644 external/flint-2.4.3/fq_poly/compose_mod_preinv.c create mode 100644 external/flint-2.4.3/fq_poly/deflate.c create mode 100644 external/flint-2.4.3/fq_poly/deflation.c create mode 100644 external/flint-2.4.3/fq_poly/derivative.c create mode 100644 external/flint-2.4.3/fq_poly/div_basecase.c create mode 100644 external/flint-2.4.3/fq_poly/div_newton_n_preinv.c create mode 100644 external/flint-2.4.3/fq_poly/divides.c create mode 100644 external/flint-2.4.3/fq_poly/divrem_basecase.c create mode 100644 external/flint-2.4.3/fq_poly/divrem_divconquer.c create mode 100644 external/flint-2.4.3/fq_poly/divrem_divconquer_recursive.c create mode 100644 external/flint-2.4.3/fq_poly/divrem_newton_n_preinv.c create mode 100644 external/flint-2.4.3/fq_poly/doc/fq_poly.txt create mode 100644 external/flint-2.4.3/fq_poly/equal.c create mode 100644 external/flint-2.4.3/fq_poly/evaluate_fq.c create mode 100644 external/flint-2.4.3/fq_poly/fit_length.c create mode 100644 external/flint-2.4.3/fq_poly/fprint.c create mode 100644 external/flint-2.4.3/fq_poly/fprint_pretty.c create mode 100644 external/flint-2.4.3/fq_poly/gcd_euclidean.c create mode 100644 external/flint-2.4.3/fq_poly/gen.c create mode 100644 external/flint-2.4.3/fq_poly/get_coeff.c create mode 100644 external/flint-2.4.3/fq_poly/get_str.c create mode 100644 external/flint-2.4.3/fq_poly/get_str_pretty.c create mode 100644 external/flint-2.4.3/fq_poly/hamming_weight.c create mode 100644 external/flint-2.4.3/fq_poly/inflate.c create mode 100644 external/flint-2.4.3/fq_poly/init.c create mode 100644 external/flint-2.4.3/fq_poly/inv_series_newton.c create mode 100644 external/flint-2.4.3/fq_poly/make_monic.c create mode 100644 external/flint-2.4.3/fq_poly/mul.c create mode 100644 external/flint-2.4.3/fq_poly/mul_KS.c create mode 100644 external/flint-2.4.3/fq_poly/mul_classical.c create mode 100644 external/flint-2.4.3/fq_poly/mul_reorder.c create mode 100644 external/flint-2.4.3/fq_poly/mullow.c create mode 100644 external/flint-2.4.3/fq_poly/mullow_KS.c create mode 100644 external/flint-2.4.3/fq_poly/mullow_classical.c create mode 100644 external/flint-2.4.3/fq_poly/mulmod.c create mode 100644 external/flint-2.4.3/fq_poly/mulmod_preinv.c create mode 100644 external/flint-2.4.3/fq_poly/neg.c create mode 100644 external/flint-2.4.3/fq_poly/normalise.c create mode 100644 external/flint-2.4.3/fq_poly/one.c create mode 100644 external/flint-2.4.3/fq_poly/pow.c create mode 100644 external/flint-2.4.3/fq_poly/powmod_fmpz_binexp.c create mode 100644 external/flint-2.4.3/fq_poly/powmod_fmpz_binexp_preinv.c create mode 100644 external/flint-2.4.3/fq_poly/powmod_fmpz_sliding_preinv.c create mode 100644 external/flint-2.4.3/fq_poly/powmod_ui_binexp.c create mode 100644 external/flint-2.4.3/fq_poly/powmod_ui_binexp_preinv.c create mode 100644 external/flint-2.4.3/fq_poly/powmod_x_fmpz_preinv.c create mode 100644 external/flint-2.4.3/fq_poly/profile/p-compose_mod.c create mode 100644 external/flint-2.4.3/fq_poly/profile/p-compose_mod_preinv.c create mode 100644 external/flint-2.4.3/fq_poly/profile/p-factor_xnpxp1.c create mode 100644 external/flint-2.4.3/fq_poly/profile/p-is_irreducible.c create mode 100644 external/flint-2.4.3/fq_poly/profile/p-iterated_frobenius.c create mode 100644 external/flint-2.4.3/fq_poly/profile/p-iterated_frobenius_table.c create mode 100644 external/flint-2.4.3/fq_poly/profile/p-mulmod.c create mode 100644 external/flint-2.4.3/fq_poly/randtest.c create mode 100644 external/flint-2.4.3/fq_poly/randtest_irreducible.c create mode 100644 external/flint-2.4.3/fq_poly/randtest_monic.c create mode 100644 external/flint-2.4.3/fq_poly/realloc.c create mode 100644 external/flint-2.4.3/fq_poly/remove.c create mode 100644 external/flint-2.4.3/fq_poly/reverse.c create mode 100644 external/flint-2.4.3/fq_poly/scalar_addmul_fq.c create mode 100644 external/flint-2.4.3/fq_poly/scalar_mul_fq.c create mode 100644 external/flint-2.4.3/fq_poly/scalar_submul_fq.c create mode 100644 external/flint-2.4.3/fq_poly/set.c create mode 100644 external/flint-2.4.3/fq_poly/set_coeff.c create mode 100644 external/flint-2.4.3/fq_poly/set_fq.c create mode 100644 external/flint-2.4.3/fq_poly/shift_left.c create mode 100644 external/flint-2.4.3/fq_poly/shift_right.c create mode 100644 external/flint-2.4.3/fq_poly/sqr.c create mode 100644 external/flint-2.4.3/fq_poly/sqr_KS.c create mode 100644 external/flint-2.4.3/fq_poly/sqr_classical.c create mode 100644 external/flint-2.4.3/fq_poly/sqr_reorder.c create mode 100644 external/flint-2.4.3/fq_poly/sub.c create mode 100644 external/flint-2.4.3/fq_poly/swap.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-add.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-compose.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-compose_divconquer.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-compose_horner.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-compose_mod.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-compose_mod_brent_kung.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-compose_mod_brent_kung_preinv.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-compose_mod_horner.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-compose_mod_horner_preinv.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-compose_mod_preinv.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-deflate.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-derivative.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-div_basecase.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-div_newton_n_preinv.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-divides.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-divrem_basecase.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-divrem_divconquer.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-divrem_newton_n_preinv.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-evaluate_fq.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-gcd_euclidean.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-get_str.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-get_str_pretty.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-hamming_weight.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-inflate.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-inv_series_newton.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-make_monic.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-mul.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-mul_KS.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-mul_classical.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-mul_reorder.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-mullow.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-mullow_KS.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-mullow_classical.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-mulmod.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-mulmod_preinv.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-neg.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-pow.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-powmod_fmpz_binexp.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-powmod_fmpz_binexp_preinv.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-powmod_fmpz_sliding_preinv.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-powmod_ui_binexp.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-powmod_ui_binexp_preinv.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-powmod_x_fmpz_preinv.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-randtest_irreducible.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-scalar_addmul_fq.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-scalar_mul_fq.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-scalar_submul_fq.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-shift_left_right.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-sqr.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-sqr_KS.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-sqr_classical.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-sqr_reorder.c create mode 100644 external/flint-2.4.3/fq_poly/test/t-sub.c create mode 100644 external/flint-2.4.3/fq_poly/truncate.c create mode 100644 external/flint-2.4.3/fq_poly_factor.h create mode 100644 external/flint-2.4.3/fq_poly_factor/clear.c create mode 100644 external/flint-2.4.3/fq_poly_factor/concat.c create mode 100644 external/flint-2.4.3/fq_poly_factor/doc/fq_poly_factor.txt create mode 100644 external/flint-2.4.3/fq_poly_factor/factor.c create mode 100644 external/flint-2.4.3/fq_poly_factor/factor_berlekamp.c create mode 100644 external/flint-2.4.3/fq_poly_factor/factor_cantor_zassenhaus.c create mode 100644 external/flint-2.4.3/fq_poly_factor/factor_distinct_deg.c create mode 100644 external/flint-2.4.3/fq_poly_factor/factor_equal_deg.c create mode 100644 external/flint-2.4.3/fq_poly_factor/factor_equal_deg_prob.c create mode 100644 external/flint-2.4.3/fq_poly_factor/factor_kaltofen_shoup.c create mode 100644 external/flint-2.4.3/fq_poly_factor/factor_squarefree.c create mode 100644 external/flint-2.4.3/fq_poly_factor/fit_length.c create mode 100644 external/flint-2.4.3/fq_poly_factor/init.c create mode 100644 external/flint-2.4.3/fq_poly_factor/insert.c create mode 100644 external/flint-2.4.3/fq_poly_factor/is_irreducible.c create mode 100644 external/flint-2.4.3/fq_poly_factor/is_irreducible_ben_or.c create mode 100644 external/flint-2.4.3/fq_poly_factor/is_irreducible_ddf.c create mode 100644 external/flint-2.4.3/fq_poly_factor/is_squarefree.c create mode 100644 external/flint-2.4.3/fq_poly_factor/iterated_frobenius_preinv.c create mode 100644 external/flint-2.4.3/fq_poly_factor/pow.c create mode 100644 external/flint-2.4.3/fq_poly_factor/print.c create mode 100644 external/flint-2.4.3/fq_poly_factor/print_pretty.c create mode 100644 external/flint-2.4.3/fq_poly_factor/realloc.c create mode 100644 external/flint-2.4.3/fq_poly_factor/set.c create mode 100644 external/flint-2.4.3/fq_poly_factor/test/t-factor.c create mode 100644 external/flint-2.4.3/fq_poly_factor/test/t-factor_berlekamp.c create mode 100644 external/flint-2.4.3/fq_poly_factor/test/t-factor_cantor_zassenhaus.c create mode 100644 external/flint-2.4.3/fq_poly_factor/test/t-factor_distinct_deg.c create mode 100644 external/flint-2.4.3/fq_poly_factor/test/t-factor_equal_deg_prob.c create mode 100644 external/flint-2.4.3/fq_poly_factor/test/t-factor_kaltofen_shoup.c create mode 100644 external/flint-2.4.3/fq_poly_factor/test/t-factor_squarefree.c create mode 100644 external/flint-2.4.3/fq_poly_factor/test/t-is_irreducible.c create mode 100644 external/flint-2.4.3/fq_poly_factor/test/t-is_irreducible_ben_or.c create mode 100644 external/flint-2.4.3/fq_poly_factor/test/t-is_irreducible_ddf.c create mode 100644 external/flint-2.4.3/fq_poly_factor/test/t-is_squarefree.c create mode 100644 external/flint-2.4.3/fq_poly_factor/test/t-iterated_frobenius_preinv.c create mode 100644 external/flint-2.4.3/fq_poly_factor_templates.h create mode 100644 external/flint-2.4.3/fq_poly_factor_templates/clear.c create mode 100644 external/flint-2.4.3/fq_poly_factor_templates/concat.c create mode 100644 external/flint-2.4.3/fq_poly_factor_templates/factor.c create mode 100644 external/flint-2.4.3/fq_poly_factor_templates/factor_berlekamp.c create mode 100644 external/flint-2.4.3/fq_poly_factor_templates/factor_cantor_zassenhaus.c create mode 100644 external/flint-2.4.3/fq_poly_factor_templates/factor_distinct_deg.c create mode 100644 external/flint-2.4.3/fq_poly_factor_templates/factor_equal_deg.c create mode 100644 external/flint-2.4.3/fq_poly_factor_templates/factor_equal_deg_prob.c create mode 100644 external/flint-2.4.3/fq_poly_factor_templates/factor_kaltofen_shoup.c create mode 100644 external/flint-2.4.3/fq_poly_factor_templates/factor_squarefree.c create mode 100644 external/flint-2.4.3/fq_poly_factor_templates/fit_length.c create mode 100644 external/flint-2.4.3/fq_poly_factor_templates/init.c create mode 100644 external/flint-2.4.3/fq_poly_factor_templates/insert.c create mode 100644 external/flint-2.4.3/fq_poly_factor_templates/is_irreducible.c create mode 100644 external/flint-2.4.3/fq_poly_factor_templates/is_irreducible_ben_or.c create mode 100644 external/flint-2.4.3/fq_poly_factor_templates/is_irreducible_ddf.c create mode 100644 external/flint-2.4.3/fq_poly_factor_templates/is_squarefree.c create mode 100644 external/flint-2.4.3/fq_poly_factor_templates/iterated_frobenius_preinv.c create mode 100644 external/flint-2.4.3/fq_poly_factor_templates/pow.c create mode 100644 external/flint-2.4.3/fq_poly_factor_templates/print.c create mode 100644 external/flint-2.4.3/fq_poly_factor_templates/print_pretty.c create mode 100644 external/flint-2.4.3/fq_poly_factor_templates/realloc.c create mode 100644 external/flint-2.4.3/fq_poly_factor_templates/set.c create mode 100644 external/flint-2.4.3/fq_poly_factor_templates/test/t-factor.c create mode 100644 external/flint-2.4.3/fq_poly_factor_templates/test/t-factor_berlekamp.c create mode 100644 external/flint-2.4.3/fq_poly_factor_templates/test/t-factor_cantor_zassenhaus.c create mode 100644 external/flint-2.4.3/fq_poly_factor_templates/test/t-factor_distinct_deg.c create mode 100644 external/flint-2.4.3/fq_poly_factor_templates/test/t-factor_equal_deg_prob.c create mode 100644 external/flint-2.4.3/fq_poly_factor_templates/test/t-factor_kaltofen_shoup.c create mode 100644 external/flint-2.4.3/fq_poly_factor_templates/test/t-factor_squarefree.c create mode 100644 external/flint-2.4.3/fq_poly_factor_templates/test/t-is_irreducible.c create mode 100644 external/flint-2.4.3/fq_poly_factor_templates/test/t-is_irreducible_ben_or.c create mode 100644 external/flint-2.4.3/fq_poly_factor_templates/test/t-is_irreducible_ddf.c create mode 100644 external/flint-2.4.3/fq_poly_factor_templates/test/t-is_squarefree.c create mode 100644 external/flint-2.4.3/fq_poly_factor_templates/test/t-iterated_frobenius_preinv.c create mode 100644 external/flint-2.4.3/fq_poly_templates.h create mode 100644 external/flint-2.4.3/fq_poly_templates/add.c create mode 100644 external/flint-2.4.3/fq_poly_templates/clear.c create mode 100644 external/flint-2.4.3/fq_poly_templates/compose.c create mode 100644 external/flint-2.4.3/fq_poly_templates/compose_divconquer.c create mode 100644 external/flint-2.4.3/fq_poly_templates/compose_horner.c create mode 100644 external/flint-2.4.3/fq_poly_templates/compose_mod.c create mode 100644 external/flint-2.4.3/fq_poly_templates/compose_mod_brent_kung.c create mode 100644 external/flint-2.4.3/fq_poly_templates/compose_mod_brent_kung_precomp_preinv.c create mode 100644 external/flint-2.4.3/fq_poly_templates/compose_mod_brent_kung_preinv.c create mode 100644 external/flint-2.4.3/fq_poly_templates/compose_mod_horner.c create mode 100644 external/flint-2.4.3/fq_poly_templates/compose_mod_horner_preinv.c create mode 100644 external/flint-2.4.3/fq_poly_templates/compose_mod_preinv.c create mode 100644 external/flint-2.4.3/fq_poly_templates/deflate.c create mode 100644 external/flint-2.4.3/fq_poly_templates/deflation.c create mode 100644 external/flint-2.4.3/fq_poly_templates/derivative.c create mode 100644 external/flint-2.4.3/fq_poly_templates/div_basecase.c create mode 100644 external/flint-2.4.3/fq_poly_templates/div_newton_n_preinv.c create mode 100644 external/flint-2.4.3/fq_poly_templates/divides.c create mode 100644 external/flint-2.4.3/fq_poly_templates/divrem_basecase.c create mode 100644 external/flint-2.4.3/fq_poly_templates/divrem_divconquer.c create mode 100644 external/flint-2.4.3/fq_poly_templates/divrem_divconquer_recursive.c create mode 100644 external/flint-2.4.3/fq_poly_templates/divrem_newton_n_preinv.c create mode 100644 external/flint-2.4.3/fq_poly_templates/equal.c create mode 100644 external/flint-2.4.3/fq_poly_templates/evaluate_fq.c create mode 100644 external/flint-2.4.3/fq_poly_templates/fit_length.c create mode 100644 external/flint-2.4.3/fq_poly_templates/fprint.c create mode 100644 external/flint-2.4.3/fq_poly_templates/fprint_pretty.c create mode 100644 external/flint-2.4.3/fq_poly_templates/gcd_euclidean.c create mode 100644 external/flint-2.4.3/fq_poly_templates/gen.c create mode 100644 external/flint-2.4.3/fq_poly_templates/get_coeff.c create mode 100644 external/flint-2.4.3/fq_poly_templates/get_str.c create mode 100644 external/flint-2.4.3/fq_poly_templates/get_str_pretty.c create mode 100644 external/flint-2.4.3/fq_poly_templates/hamming_weight.c create mode 100644 external/flint-2.4.3/fq_poly_templates/inflate.c create mode 100644 external/flint-2.4.3/fq_poly_templates/init.c create mode 100644 external/flint-2.4.3/fq_poly_templates/inv_series_newton.c create mode 100644 external/flint-2.4.3/fq_poly_templates/make_monic.c create mode 100644 external/flint-2.4.3/fq_poly_templates/mul.c create mode 100644 external/flint-2.4.3/fq_poly_templates/mul_KS.c create mode 100644 external/flint-2.4.3/fq_poly_templates/mul_classical.c create mode 100644 external/flint-2.4.3/fq_poly_templates/mul_reorder.c create mode 100644 external/flint-2.4.3/fq_poly_templates/mullow.c create mode 100644 external/flint-2.4.3/fq_poly_templates/mullow_KS.c create mode 100644 external/flint-2.4.3/fq_poly_templates/mullow_classical.c create mode 100644 external/flint-2.4.3/fq_poly_templates/mulmod.c create mode 100644 external/flint-2.4.3/fq_poly_templates/mulmod_preinv.c create mode 100644 external/flint-2.4.3/fq_poly_templates/neg.c create mode 100644 external/flint-2.4.3/fq_poly_templates/normalise.c create mode 100644 external/flint-2.4.3/fq_poly_templates/one.c create mode 100644 external/flint-2.4.3/fq_poly_templates/pow.c create mode 100644 external/flint-2.4.3/fq_poly_templates/powmod_fmpz_binexp.c create mode 100644 external/flint-2.4.3/fq_poly_templates/powmod_fmpz_binexp_preinv.c create mode 100644 external/flint-2.4.3/fq_poly_templates/powmod_fmpz_sliding_preinv.c create mode 100644 external/flint-2.4.3/fq_poly_templates/powmod_ui_binexp.c create mode 100644 external/flint-2.4.3/fq_poly_templates/powmod_ui_binexp_preinv.c create mode 100644 external/flint-2.4.3/fq_poly_templates/powmod_x_fmpz_preinv.c create mode 100644 external/flint-2.4.3/fq_poly_templates/profile/p-factor_xnpxp1.c create mode 100644 external/flint-2.4.3/fq_poly_templates/profile/p-is_irreducible.c create mode 100644 external/flint-2.4.3/fq_poly_templates/profile/p-iterated_frobenius.c create mode 100644 external/flint-2.4.3/fq_poly_templates/profile/p-iterated_frobenius_table.c create mode 100644 external/flint-2.4.3/fq_poly_templates/profile/p-mullow.c create mode 100644 external/flint-2.4.3/fq_poly_templates/profile/p-sqr.c create mode 100644 external/flint-2.4.3/fq_poly_templates/randtest.c create mode 100644 external/flint-2.4.3/fq_poly_templates/randtest_irreducible.c create mode 100644 external/flint-2.4.3/fq_poly_templates/randtest_monic.c create mode 100644 external/flint-2.4.3/fq_poly_templates/realloc.c create mode 100644 external/flint-2.4.3/fq_poly_templates/remove.c create mode 100644 external/flint-2.4.3/fq_poly_templates/reverse.c create mode 100644 external/flint-2.4.3/fq_poly_templates/scalar_addmul_fq.c create mode 100644 external/flint-2.4.3/fq_poly_templates/scalar_mul_fq.c create mode 100644 external/flint-2.4.3/fq_poly_templates/scalar_submul_fq.c create mode 100644 external/flint-2.4.3/fq_poly_templates/set.c create mode 100644 external/flint-2.4.3/fq_poly_templates/set_coeff.c create mode 100644 external/flint-2.4.3/fq_poly_templates/set_fq.c create mode 100644 external/flint-2.4.3/fq_poly_templates/shift_left.c create mode 100644 external/flint-2.4.3/fq_poly_templates/shift_right.c create mode 100644 external/flint-2.4.3/fq_poly_templates/sqr.c create mode 100644 external/flint-2.4.3/fq_poly_templates/sqr_KS.c create mode 100644 external/flint-2.4.3/fq_poly_templates/sqr_classical.c create mode 100644 external/flint-2.4.3/fq_poly_templates/sqr_reorder.c create mode 100644 external/flint-2.4.3/fq_poly_templates/sub.c create mode 100644 external/flint-2.4.3/fq_poly_templates/swap.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-add.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-compose.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-compose_divconquer.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-compose_horner.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-compose_mod.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-compose_mod_brent_kung.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-compose_mod_brent_kung_preinv.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-compose_mod_horner.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-compose_mod_horner_preinv.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-compose_mod_preinv.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-deflate.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-derivative.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-div_basecase.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-div_newton_n_preinv.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-divides.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-divrem_basecase.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-divrem_divconquer.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-divrem_newton_n_preinv.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-evaluate_fq.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-gcd_euclidean.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-get_str.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-get_str_pretty.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-hamming_weight.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-inflate.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-inv_series_newton.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-make_monic.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-mul.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-mul_KS.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-mul_classical.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-mul_reorder.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-mullow.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-mullow_KS.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-mullow_classical.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-mulmod.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-mulmod_preinv.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-neg.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-pow.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-powmod_fmpz_binexp.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-powmod_fmpz_binexp_preinv.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-powmod_fmpz_sliding_preinv.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-powmod_ui_binexp.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-powmod_ui_binexp_preinv.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-powmod_x_fmpz_preinv.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-randtest_irreducible.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-scalar_addmul_fq.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-scalar_mul_fq.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-scalar_submul_fq.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-shift_left_right.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-sqr.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-sqr_KS.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-sqr_classical.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-sqr_reorder.c create mode 100644 external/flint-2.4.3/fq_poly_templates/test/t-sub.c create mode 100644 external/flint-2.4.3/fq_poly_templates/truncate.c create mode 100644 external/flint-2.4.3/fq_templates/test/t-add.c create mode 100644 external/flint-2.4.3/fq_templates/test/t-ctx_init.c create mode 100644 external/flint-2.4.3/fq_templates/test/t-frobenius.c create mode 100644 external/flint-2.4.3/fq_templates/test/t-inv.c create mode 100644 external/flint-2.4.3/fq_templates/test/t-mul.c create mode 100644 external/flint-2.4.3/fq_templates/test/t-mul_fmpz.c create mode 100644 external/flint-2.4.3/fq_templates/test/t-mul_si.c create mode 100644 external/flint-2.4.3/fq_templates/test/t-mul_ui.c create mode 100644 external/flint-2.4.3/fq_templates/test/t-neg.c create mode 100644 external/flint-2.4.3/fq_templates/test/t-norm.c create mode 100644 external/flint-2.4.3/fq_templates/test/t-pow.c create mode 100644 external/flint-2.4.3/fq_templates/test/t-pth_root.c create mode 100644 external/flint-2.4.3/fq_templates/test/t-sqr.c create mode 100644 external/flint-2.4.3/fq_templates/test/t-sub.c create mode 100644 external/flint-2.4.3/fq_templates/test/t-trace.c create mode 100644 external/flint-2.4.3/fq_vec.h create mode 100644 external/flint-2.4.3/fq_vec/add.c create mode 100644 external/flint-2.4.3/fq_vec/clear.c create mode 100644 external/flint-2.4.3/fq_vec/doc/fq_vec.txt create mode 100644 external/flint-2.4.3/fq_vec/dot.c create mode 100644 external/flint-2.4.3/fq_vec/equal.c create mode 100644 external/flint-2.4.3/fq_vec/fprint.c create mode 100644 external/flint-2.4.3/fq_vec/init.c create mode 100644 external/flint-2.4.3/fq_vec/is_zero.c create mode 100644 external/flint-2.4.3/fq_vec/neg.c create mode 100644 external/flint-2.4.3/fq_vec/randtest.c create mode 100644 external/flint-2.4.3/fq_vec/scalar_addmul_fq.c create mode 100644 external/flint-2.4.3/fq_vec/scalar_submul_fq.c create mode 100644 external/flint-2.4.3/fq_vec/set.c create mode 100644 external/flint-2.4.3/fq_vec/sub.c create mode 100644 external/flint-2.4.3/fq_vec/swap.c create mode 100644 external/flint-2.4.3/fq_vec/test/t-add.c create mode 100644 external/flint-2.4.3/fq_vec/test/t-is_zero.c create mode 100644 external/flint-2.4.3/fq_vec/test/t-neg.c create mode 100644 external/flint-2.4.3/fq_vec/test/t-sub.c create mode 100644 external/flint-2.4.3/fq_vec/test/t-swap.c create mode 100644 external/flint-2.4.3/fq_vec/test/t-zero.c create mode 100644 external/flint-2.4.3/fq_vec/zero.c create mode 100644 external/flint-2.4.3/fq_vec_templates.h create mode 100644 external/flint-2.4.3/fq_vec_templates/add.c create mode 100644 external/flint-2.4.3/fq_vec_templates/clear.c create mode 100644 external/flint-2.4.3/fq_vec_templates/dot.c create mode 100644 external/flint-2.4.3/fq_vec_templates/equal.c create mode 100644 external/flint-2.4.3/fq_vec_templates/fprint.c create mode 100644 external/flint-2.4.3/fq_vec_templates/init.c create mode 100644 external/flint-2.4.3/fq_vec_templates/is_zero.c create mode 100644 external/flint-2.4.3/fq_vec_templates/neg.c create mode 100644 external/flint-2.4.3/fq_vec_templates/randtest.c create mode 100644 external/flint-2.4.3/fq_vec_templates/scalar_addmul_fq.c create mode 100644 external/flint-2.4.3/fq_vec_templates/scalar_submul_fq.c create mode 100644 external/flint-2.4.3/fq_vec_templates/set.c create mode 100644 external/flint-2.4.3/fq_vec_templates/sub.c create mode 100644 external/flint-2.4.3/fq_vec_templates/swap.c create mode 100644 external/flint-2.4.3/fq_vec_templates/test/t-add.c create mode 100644 external/flint-2.4.3/fq_vec_templates/test/t-is_zero.c create mode 100644 external/flint-2.4.3/fq_vec_templates/test/t-neg.c create mode 100644 external/flint-2.4.3/fq_vec_templates/test/t-sub.c create mode 100644 external/flint-2.4.3/fq_vec_templates/test/t-swap.c create mode 100644 external/flint-2.4.3/fq_vec_templates/test/t-zero.c create mode 100644 external/flint-2.4.3/fq_vec_templates/zero.c create mode 100644 external/flint-2.4.3/fq_zech.h create mode 100644 external/flint-2.4.3/fq_zech/add.c create mode 100644 external/flint-2.4.3/fq_zech/bit_pack.c create mode 100644 external/flint-2.4.3/fq_zech/bit_unpack.c create mode 100644 external/flint-2.4.3/fq_zech/clear.c create mode 100644 external/flint-2.4.3/fq_zech/ctx_clear.c create mode 100644 external/flint-2.4.3/fq_zech/ctx_init.c create mode 100644 external/flint-2.4.3/fq_zech/ctx_randtest.c create mode 100644 external/flint-2.4.3/fq_zech/doc/fq_zech.txt create mode 100644 external/flint-2.4.3/fq_zech/frobenius.c create mode 100644 external/flint-2.4.3/fq_zech/get_fq_nmod.c create mode 100644 external/flint-2.4.3/fq_zech/get_str.c create mode 100644 external/flint-2.4.3/fq_zech/get_str_pretty.c create mode 100644 external/flint-2.4.3/fq_zech/inv.c create mode 100644 external/flint-2.4.3/fq_zech/mul.c create mode 100644 external/flint-2.4.3/fq_zech/mul_fmpz.c create mode 100644 external/flint-2.4.3/fq_zech/mul_si.c create mode 100644 external/flint-2.4.3/fq_zech/mul_ui.c create mode 100644 external/flint-2.4.3/fq_zech/neg.c create mode 100644 external/flint-2.4.3/fq_zech/norm.c create mode 100644 external/flint-2.4.3/fq_zech/pow.c create mode 100644 external/flint-2.4.3/fq_zech/pth_root.c create mode 100644 external/flint-2.4.3/fq_zech/randtest.c create mode 100644 external/flint-2.4.3/fq_zech/set_fmpz.c create mode 100644 external/flint-2.4.3/fq_zech/set_fq_nmod.c create mode 100644 external/flint-2.4.3/fq_zech/sqr.c create mode 100644 external/flint-2.4.3/fq_zech/sub.c create mode 100644 external/flint-2.4.3/fq_zech/sub_one.c create mode 100644 external/flint-2.4.3/fq_zech/test/t-add.c create mode 100644 external/flint-2.4.3/fq_zech/test/t-ctx_init.c create mode 100644 external/flint-2.4.3/fq_zech/test/t-frobenius.c create mode 100644 external/flint-2.4.3/fq_zech/test/t-get_set_fq_nmod.c create mode 100644 external/flint-2.4.3/fq_zech/test/t-inv.c create mode 100644 external/flint-2.4.3/fq_zech/test/t-mul.c create mode 100644 external/flint-2.4.3/fq_zech/test/t-mul_fmpz.c create mode 100644 external/flint-2.4.3/fq_zech/test/t-mul_ui.c create mode 100644 external/flint-2.4.3/fq_zech/test/t-neg.c create mode 100644 external/flint-2.4.3/fq_zech/test/t-norm.c create mode 100644 external/flint-2.4.3/fq_zech/test/t-pow.c create mode 100644 external/flint-2.4.3/fq_zech/test/t-sqr.c create mode 100644 external/flint-2.4.3/fq_zech/test/t-sub.c create mode 100644 external/flint-2.4.3/fq_zech/test/t-trace.c create mode 100644 external/flint-2.4.3/fq_zech/trace.c create mode 100644 external/flint-2.4.3/fq_zech_mat.h create mode 100644 external/flint-2.4.3/fq_zech_mat/add.c create mode 100644 external/flint-2.4.3/fq_zech_mat/clear.c create mode 100644 external/flint-2.4.3/fq_zech_mat/doc/fq_zech_mat.txt create mode 100644 external/flint-2.4.3/fq_zech_mat/equal.c create mode 100644 external/flint-2.4.3/fq_zech_mat/fprint.c create mode 100644 external/flint-2.4.3/fq_zech_mat/init.c create mode 100644 external/flint-2.4.3/fq_zech_mat/init_set.c create mode 100644 external/flint-2.4.3/fq_zech_mat/is_zero.c create mode 100644 external/flint-2.4.3/fq_zech_mat/lu.c create mode 100644 external/flint-2.4.3/fq_zech_mat/lu_classical.c create mode 100644 external/flint-2.4.3/fq_zech_mat/lu_recursive.c create mode 100644 external/flint-2.4.3/fq_zech_mat/mul.c create mode 100644 external/flint-2.4.3/fq_zech_mat/mul_KS.c create mode 100644 external/flint-2.4.3/fq_zech_mat/mul_classical.c create mode 100644 external/flint-2.4.3/fq_zech_mat/neg.c create mode 100644 external/flint-2.4.3/fq_zech_mat/randops.c create mode 100644 external/flint-2.4.3/fq_zech_mat/randpermdiag.c create mode 100644 external/flint-2.4.3/fq_zech_mat/randrank.c create mode 100644 external/flint-2.4.3/fq_zech_mat/randtest.c create mode 100644 external/flint-2.4.3/fq_zech_mat/randtril.c create mode 100644 external/flint-2.4.3/fq_zech_mat/randtriu.c create mode 100644 external/flint-2.4.3/fq_zech_mat/rref.c create mode 100644 external/flint-2.4.3/fq_zech_mat/set.c create mode 100644 external/flint-2.4.3/fq_zech_mat/solve_tril.c create mode 100644 external/flint-2.4.3/fq_zech_mat/solve_tril_classical.c create mode 100644 external/flint-2.4.3/fq_zech_mat/solve_tril_recursive.c create mode 100644 external/flint-2.4.3/fq_zech_mat/solve_triu.c create mode 100644 external/flint-2.4.3/fq_zech_mat/solve_triu_classical.c create mode 100644 external/flint-2.4.3/fq_zech_mat/solve_triu_recursive.c create mode 100644 external/flint-2.4.3/fq_zech_mat/sub.c create mode 100644 external/flint-2.4.3/fq_zech_mat/submul.c create mode 100644 external/flint-2.4.3/fq_zech_mat/swap.c create mode 100644 external/flint-2.4.3/fq_zech_mat/test/t-add_sub.c create mode 100644 external/flint-2.4.3/fq_zech_mat/test/t-equal.c create mode 100644 external/flint-2.4.3/fq_zech_mat/test/t-is_zero.c create mode 100644 external/flint-2.4.3/fq_zech_mat/test/t-lu_classical.c create mode 100644 external/flint-2.4.3/fq_zech_mat/test/t-lu_recursive.c create mode 100644 external/flint-2.4.3/fq_zech_mat/test/t-mul.c create mode 100644 external/flint-2.4.3/fq_zech_mat/test/t-mul_KS.c create mode 100644 external/flint-2.4.3/fq_zech_mat/test/t-rref.c create mode 100644 external/flint-2.4.3/fq_zech_mat/test/t-solve_tril.c create mode 100644 external/flint-2.4.3/fq_zech_mat/test/t-solve_tril_classical.c create mode 100644 external/flint-2.4.3/fq_zech_mat/test/t-solve_tril_recursive.c create mode 100644 external/flint-2.4.3/fq_zech_mat/test/t-solve_triu.c create mode 100644 external/flint-2.4.3/fq_zech_mat/test/t-solve_triu_classical.c create mode 100644 external/flint-2.4.3/fq_zech_mat/test/t-solve_triu_recursive.c create mode 100644 external/flint-2.4.3/fq_zech_mat/test/t-submul.c create mode 100644 external/flint-2.4.3/fq_zech_mat/test/t-zero.c create mode 100644 external/flint-2.4.3/fq_zech_mat/window_clear.c create mode 100644 external/flint-2.4.3/fq_zech_mat/window_init.c create mode 100644 external/flint-2.4.3/fq_zech_mat/zero.c create mode 100644 external/flint-2.4.3/fq_zech_poly.h create mode 100644 external/flint-2.4.3/fq_zech_poly/add.c create mode 100644 external/flint-2.4.3/fq_zech_poly/clear.c create mode 100644 external/flint-2.4.3/fq_zech_poly/compose.c create mode 100644 external/flint-2.4.3/fq_zech_poly/compose_divconquer.c create mode 100644 external/flint-2.4.3/fq_zech_poly/compose_horner.c create mode 100644 external/flint-2.4.3/fq_zech_poly/compose_mod.c create mode 100644 external/flint-2.4.3/fq_zech_poly/compose_mod_brent_kung.c create mode 100644 external/flint-2.4.3/fq_zech_poly/compose_mod_brent_kung_precomp_preinv.c create mode 100644 external/flint-2.4.3/fq_zech_poly/compose_mod_brent_kung_preinv.c create mode 100644 external/flint-2.4.3/fq_zech_poly/compose_mod_horner.c create mode 100644 external/flint-2.4.3/fq_zech_poly/compose_mod_horner_preinv.c create mode 100644 external/flint-2.4.3/fq_zech_poly/compose_mod_preinv.c create mode 100644 external/flint-2.4.3/fq_zech_poly/deflate.c create mode 100644 external/flint-2.4.3/fq_zech_poly/deflation.c create mode 100644 external/flint-2.4.3/fq_zech_poly/derivative.c create mode 100644 external/flint-2.4.3/fq_zech_poly/div_basecase.c create mode 100644 external/flint-2.4.3/fq_zech_poly/div_newton_n_preinv.c create mode 100644 external/flint-2.4.3/fq_zech_poly/divides.c create mode 100644 external/flint-2.4.3/fq_zech_poly/divrem_basecase.c create mode 100644 external/flint-2.4.3/fq_zech_poly/divrem_divconquer.c create mode 100644 external/flint-2.4.3/fq_zech_poly/divrem_divconquer_recursive.c create mode 100644 external/flint-2.4.3/fq_zech_poly/divrem_newton_n_preinv.c create mode 100644 external/flint-2.4.3/fq_zech_poly/doc/fq_zech_poly.txt create mode 100644 external/flint-2.4.3/fq_zech_poly/equal.c create mode 100644 external/flint-2.4.3/fq_zech_poly/evaluate_fq.c create mode 100644 external/flint-2.4.3/fq_zech_poly/fit_length.c create mode 100644 external/flint-2.4.3/fq_zech_poly/fprint.c create mode 100644 external/flint-2.4.3/fq_zech_poly/fprint_pretty.c create mode 100644 external/flint-2.4.3/fq_zech_poly/gcd_euclidean.c create mode 100644 external/flint-2.4.3/fq_zech_poly/gen.c create mode 100644 external/flint-2.4.3/fq_zech_poly/get_coeff.c create mode 100644 external/flint-2.4.3/fq_zech_poly/get_str.c create mode 100644 external/flint-2.4.3/fq_zech_poly/get_str_pretty.c create mode 100644 external/flint-2.4.3/fq_zech_poly/hamming_weight.c create mode 100644 external/flint-2.4.3/fq_zech_poly/inflate.c create mode 100644 external/flint-2.4.3/fq_zech_poly/init.c create mode 100644 external/flint-2.4.3/fq_zech_poly/inv_series_newton.c create mode 100644 external/flint-2.4.3/fq_zech_poly/make_monic.c create mode 100644 external/flint-2.4.3/fq_zech_poly/mul.c create mode 100644 external/flint-2.4.3/fq_zech_poly/mul_KS.c create mode 100644 external/flint-2.4.3/fq_zech_poly/mul_classical.c create mode 100644 external/flint-2.4.3/fq_zech_poly/mullow.c create mode 100644 external/flint-2.4.3/fq_zech_poly/mullow_KS.c create mode 100644 external/flint-2.4.3/fq_zech_poly/mullow_classical.c create mode 100644 external/flint-2.4.3/fq_zech_poly/mulmod.c create mode 100644 external/flint-2.4.3/fq_zech_poly/mulmod_preinv.c create mode 100644 external/flint-2.4.3/fq_zech_poly/neg.c create mode 100644 external/flint-2.4.3/fq_zech_poly/normalise.c create mode 100644 external/flint-2.4.3/fq_zech_poly/one.c create mode 100644 external/flint-2.4.3/fq_zech_poly/pow.c create mode 100644 external/flint-2.4.3/fq_zech_poly/powmod_fmpz_binexp.c create mode 100644 external/flint-2.4.3/fq_zech_poly/powmod_fmpz_binexp_preinv.c create mode 100644 external/flint-2.4.3/fq_zech_poly/powmod_fmpz_sliding_preinv.c create mode 100644 external/flint-2.4.3/fq_zech_poly/powmod_ui_binexp.c create mode 100644 external/flint-2.4.3/fq_zech_poly/powmod_ui_binexp_preinv.c create mode 100644 external/flint-2.4.3/fq_zech_poly/powmod_x_fmpz_preinv.c create mode 100644 external/flint-2.4.3/fq_zech_poly/profile/p-factor_kaltofen_shoup_vs_fq_nmod_poly.c create mode 100644 external/flint-2.4.3/fq_zech_poly/profile/p-factor_vs_fq_nmod.c create mode 100644 external/flint-2.4.3/fq_zech_poly/profile/p-factor_xnpxp1.c create mode 100644 external/flint-2.4.3/fq_zech_poly/profile/p-is_irreducible.c create mode 100644 external/flint-2.4.3/fq_zech_poly/profile/p-iterated_frobenius.c create mode 100644 external/flint-2.4.3/fq_zech_poly/profile/p-iterated_frobenius_table.c create mode 100644 external/flint-2.4.3/fq_zech_poly/profile/p-mullow.c create mode 100644 external/flint-2.4.3/fq_zech_poly/profile/p-sqr.c create mode 100644 external/flint-2.4.3/fq_zech_poly/randtest.c create mode 100644 external/flint-2.4.3/fq_zech_poly/randtest_irreducible.c create mode 100644 external/flint-2.4.3/fq_zech_poly/randtest_monic.c create mode 100644 external/flint-2.4.3/fq_zech_poly/realloc.c create mode 100644 external/flint-2.4.3/fq_zech_poly/remove.c create mode 100644 external/flint-2.4.3/fq_zech_poly/reverse.c create mode 100644 external/flint-2.4.3/fq_zech_poly/scalar_addmul_fq.c create mode 100644 external/flint-2.4.3/fq_zech_poly/scalar_mul_fq.c create mode 100644 external/flint-2.4.3/fq_zech_poly/scalar_submul_fq.c create mode 100644 external/flint-2.4.3/fq_zech_poly/set.c create mode 100644 external/flint-2.4.3/fq_zech_poly/set_coeff.c create mode 100644 external/flint-2.4.3/fq_zech_poly/set_fq.c create mode 100644 external/flint-2.4.3/fq_zech_poly/shift_left.c create mode 100644 external/flint-2.4.3/fq_zech_poly/shift_right.c create mode 100644 external/flint-2.4.3/fq_zech_poly/sqr.c create mode 100644 external/flint-2.4.3/fq_zech_poly/sqr_KS.c create mode 100644 external/flint-2.4.3/fq_zech_poly/sqr_classical.c create mode 100644 external/flint-2.4.3/fq_zech_poly/sub.c create mode 100644 external/flint-2.4.3/fq_zech_poly/swap.c create mode 100644 external/flint-2.4.3/fq_zech_poly/test/t-add.c create mode 100644 external/flint-2.4.3/fq_zech_poly/test/t-compose.c create mode 100644 external/flint-2.4.3/fq_zech_poly/test/t-compose_divconquer.c create mode 100644 external/flint-2.4.3/fq_zech_poly/test/t-compose_horner.c create mode 100644 external/flint-2.4.3/fq_zech_poly/test/t-compose_mod.c create mode 100644 external/flint-2.4.3/fq_zech_poly/test/t-compose_mod_brent_kung.c create mode 100644 external/flint-2.4.3/fq_zech_poly/test/t-compose_mod_brent_kung_preinv.c create mode 100644 external/flint-2.4.3/fq_zech_poly/test/t-compose_mod_horner.c create mode 100644 external/flint-2.4.3/fq_zech_poly/test/t-compose_mod_horner_preinv.c create mode 100644 external/flint-2.4.3/fq_zech_poly/test/t-compose_mod_preinv.c create mode 100644 external/flint-2.4.3/fq_zech_poly/test/t-deflate.c create mode 100644 external/flint-2.4.3/fq_zech_poly/test/t-derivative.c create mode 100644 external/flint-2.4.3/fq_zech_poly/test/t-div_basecase.c create mode 100644 external/flint-2.4.3/fq_zech_poly/test/t-div_newton_n_preinv.c create mode 100644 external/flint-2.4.3/fq_zech_poly/test/t-divides.c create mode 100644 external/flint-2.4.3/fq_zech_poly/test/t-divrem_basecase.c create mode 100644 external/flint-2.4.3/fq_zech_poly/test/t-divrem_divconquer.c create mode 100644 external/flint-2.4.3/fq_zech_poly/test/t-divrem_newton_n_preinv.c create mode 100644 external/flint-2.4.3/fq_zech_poly/test/t-evaluate_fq.c create mode 100644 external/flint-2.4.3/fq_zech_poly/test/t-gcd_euclidean.c create mode 100644 external/flint-2.4.3/fq_zech_poly/test/t-get_str.c create mode 100644 external/flint-2.4.3/fq_zech_poly/test/t-get_str_pretty.c create mode 100644 external/flint-2.4.3/fq_zech_poly/test/t-hamming_weight.c create mode 100644 external/flint-2.4.3/fq_zech_poly/test/t-inflate.c create mode 100644 external/flint-2.4.3/fq_zech_poly/test/t-inv_series_newton.c create mode 100644 external/flint-2.4.3/fq_zech_poly/test/t-make_monic.c create mode 100644 external/flint-2.4.3/fq_zech_poly/test/t-mul.c create mode 100644 external/flint-2.4.3/fq_zech_poly/test/t-mul_KS.c create mode 100644 external/flint-2.4.3/fq_zech_poly/test/t-mul_classical.c create mode 100644 external/flint-2.4.3/fq_zech_poly/test/t-mullow.c create mode 100644 external/flint-2.4.3/fq_zech_poly/test/t-mullow_KS.c create mode 100644 external/flint-2.4.3/fq_zech_poly/test/t-mullow_classical.c create mode 100644 external/flint-2.4.3/fq_zech_poly/test/t-mulmod.c create mode 100644 external/flint-2.4.3/fq_zech_poly/test/t-mulmod_preinv.c create mode 100644 external/flint-2.4.3/fq_zech_poly/test/t-neg.c create mode 100644 external/flint-2.4.3/fq_zech_poly/test/t-pow.c create mode 100644 external/flint-2.4.3/fq_zech_poly/test/t-powmod_fmpz_binexp.c create mode 100644 external/flint-2.4.3/fq_zech_poly/test/t-powmod_fmpz_binexp_preinv.c create mode 100644 external/flint-2.4.3/fq_zech_poly/test/t-powmod_fmpz_sliding_preinv.c create mode 100644 external/flint-2.4.3/fq_zech_poly/test/t-powmod_ui_binexp.c create mode 100644 external/flint-2.4.3/fq_zech_poly/test/t-powmod_ui_binexp_preinv.c create mode 100644 external/flint-2.4.3/fq_zech_poly/test/t-powmod_x_fmpz_preinv.c create mode 100644 external/flint-2.4.3/fq_zech_poly/test/t-randtest_irreducible.c create mode 100644 external/flint-2.4.3/fq_zech_poly/test/t-scalar_addmul_fq.c create mode 100644 external/flint-2.4.3/fq_zech_poly/test/t-scalar_mul_fq.c create mode 100644 external/flint-2.4.3/fq_zech_poly/test/t-scalar_submul_fq.c create mode 100644 external/flint-2.4.3/fq_zech_poly/test/t-shift_left_right.c create mode 100644 external/flint-2.4.3/fq_zech_poly/test/t-sqr.c create mode 100644 external/flint-2.4.3/fq_zech_poly/test/t-sqr_KS.c create mode 100644 external/flint-2.4.3/fq_zech_poly/test/t-sqr_classical.c create mode 100644 external/flint-2.4.3/fq_zech_poly/test/t-sub.c create mode 100644 external/flint-2.4.3/fq_zech_poly/truncate.c create mode 100644 external/flint-2.4.3/fq_zech_poly_factor.h create mode 100644 external/flint-2.4.3/fq_zech_poly_factor/clear.c create mode 100644 external/flint-2.4.3/fq_zech_poly_factor/concat.c create mode 100644 external/flint-2.4.3/fq_zech_poly_factor/doc/fq_zech_poly_factor.txt create mode 100644 external/flint-2.4.3/fq_zech_poly_factor/factor.c create mode 100644 external/flint-2.4.3/fq_zech_poly_factor/factor_berlekamp.c create mode 100644 external/flint-2.4.3/fq_zech_poly_factor/factor_cantor_zassenhaus.c create mode 100644 external/flint-2.4.3/fq_zech_poly_factor/factor_distinct_deg.c create mode 100644 external/flint-2.4.3/fq_zech_poly_factor/factor_equal_deg.c create mode 100644 external/flint-2.4.3/fq_zech_poly_factor/factor_equal_deg_prob.c create mode 100644 external/flint-2.4.3/fq_zech_poly_factor/factor_kaltofen_shoup.c create mode 100644 external/flint-2.4.3/fq_zech_poly_factor/factor_squarefree.c create mode 100644 external/flint-2.4.3/fq_zech_poly_factor/fit_length.c create mode 100644 external/flint-2.4.3/fq_zech_poly_factor/init.c create mode 100644 external/flint-2.4.3/fq_zech_poly_factor/insert.c create mode 100644 external/flint-2.4.3/fq_zech_poly_factor/is_irreducible.c create mode 100644 external/flint-2.4.3/fq_zech_poly_factor/is_irreducible_ben_or.c create mode 100644 external/flint-2.4.3/fq_zech_poly_factor/is_irreducible_ddf.c create mode 100644 external/flint-2.4.3/fq_zech_poly_factor/is_squarefree.c create mode 100644 external/flint-2.4.3/fq_zech_poly_factor/iterated_frobenius_preinv.c create mode 100644 external/flint-2.4.3/fq_zech_poly_factor/pow.c create mode 100644 external/flint-2.4.3/fq_zech_poly_factor/print.c create mode 100644 external/flint-2.4.3/fq_zech_poly_factor/print_pretty.c create mode 100644 external/flint-2.4.3/fq_zech_poly_factor/realloc.c create mode 100644 external/flint-2.4.3/fq_zech_poly_factor/set.c create mode 100644 external/flint-2.4.3/fq_zech_poly_factor/test/t-factor.c create mode 100644 external/flint-2.4.3/fq_zech_poly_factor/test/t-factor_berlekamp.c create mode 100644 external/flint-2.4.3/fq_zech_poly_factor/test/t-factor_cantor_zassenhaus.c create mode 100644 external/flint-2.4.3/fq_zech_poly_factor/test/t-factor_distinct_deg.c create mode 100644 external/flint-2.4.3/fq_zech_poly_factor/test/t-factor_equal_deg_prob.c create mode 100644 external/flint-2.4.3/fq_zech_poly_factor/test/t-factor_kaltofen_shoup.c create mode 100644 external/flint-2.4.3/fq_zech_poly_factor/test/t-factor_squarefree.c create mode 100644 external/flint-2.4.3/fq_zech_poly_factor/test/t-is_irreducible.c create mode 100644 external/flint-2.4.3/fq_zech_poly_factor/test/t-is_irreducible_ben_or.c create mode 100644 external/flint-2.4.3/fq_zech_poly_factor/test/t-is_irreducible_ddf.c create mode 100644 external/flint-2.4.3/fq_zech_poly_factor/test/t-is_squarefree.c create mode 100644 external/flint-2.4.3/fq_zech_poly_factor/test/t-iterated_frobenius_preinv.c create mode 100644 external/flint-2.4.3/fq_zech_vec.h create mode 100644 external/flint-2.4.3/fq_zech_vec/add.c create mode 100644 external/flint-2.4.3/fq_zech_vec/clear.c create mode 100644 external/flint-2.4.3/fq_zech_vec/doc/fq_zech_vec.txt create mode 100644 external/flint-2.4.3/fq_zech_vec/dot.c create mode 100644 external/flint-2.4.3/fq_zech_vec/equal.c create mode 100644 external/flint-2.4.3/fq_zech_vec/fprint.c create mode 100644 external/flint-2.4.3/fq_zech_vec/init.c create mode 100644 external/flint-2.4.3/fq_zech_vec/is_zero.c create mode 100644 external/flint-2.4.3/fq_zech_vec/neg.c create mode 100644 external/flint-2.4.3/fq_zech_vec/randtest.c create mode 100644 external/flint-2.4.3/fq_zech_vec/scalar_addmul_fq.c create mode 100644 external/flint-2.4.3/fq_zech_vec/scalar_submul_fq.c create mode 100644 external/flint-2.4.3/fq_zech_vec/set.c create mode 100644 external/flint-2.4.3/fq_zech_vec/sub.c create mode 100644 external/flint-2.4.3/fq_zech_vec/swap.c create mode 100644 external/flint-2.4.3/fq_zech_vec/test/t-add.c create mode 100644 external/flint-2.4.3/fq_zech_vec/test/t-is_zero.c create mode 100644 external/flint-2.4.3/fq_zech_vec/test/t-neg.c create mode 100644 external/flint-2.4.3/fq_zech_vec/test/t-sub.c create mode 100644 external/flint-2.4.3/fq_zech_vec/test/t-swap.c create mode 100644 external/flint-2.4.3/fq_zech_vec/test/t-zero.c create mode 100644 external/flint-2.4.3/fq_zech_vec/zero.c create mode 100644 external/flint-2.4.3/fscanf.c create mode 100644 external/flint-2.4.3/gmpcompat.h create mode 100644 external/flint-2.4.3/gpl-2.0.txt create mode 100644 external/flint-2.4.3/interfaces/NTL-interface.cpp create mode 100644 external/flint-2.4.3/interfaces/doc/interfaces.txt create mode 100644 external/flint-2.4.3/interfaces/test/t-NTL-interface.cpp create mode 100644 external/flint-2.4.3/long_extras.h create mode 100644 external/flint-2.4.3/long_extras/doc/long_extras.txt create mode 100644 external/flint-2.4.3/long_extras/randint.c create mode 100644 external/flint-2.4.3/long_extras/randtest.c create mode 100644 external/flint-2.4.3/long_extras/sizeinbase.c create mode 100644 external/flint-2.4.3/long_extras/test/t-sizeinbase.c create mode 100644 external/flint-2.4.3/longlong.h create mode 100644 external/flint-2.4.3/memory_manager.c create mode 100644 external/flint-2.4.3/mpfr_mat.h create mode 100644 external/flint-2.4.3/mpfr_mat/clear.c create mode 100644 external/flint-2.4.3/mpfr_mat/doc/mpfr_mat.txt create mode 100644 external/flint-2.4.3/mpfr_mat/init.c create mode 100644 external/flint-2.4.3/mpfr_mat/test/t-init_clear.c create mode 100644 external/flint-2.4.3/mpfr_poly.h create mode 100644 external/flint-2.4.3/mpfr_vec.h create mode 100644 external/flint-2.4.3/mpfr_vec/add.c create mode 100644 external/flint-2.4.3/mpfr_vec/clear.c create mode 100644 external/flint-2.4.3/mpfr_vec/doc/mpfr_vec.txt create mode 100644 external/flint-2.4.3/mpfr_vec/init.c create mode 100644 external/flint-2.4.3/mpfr_vec/scalar_mul_2exp.c create mode 100644 external/flint-2.4.3/mpfr_vec/scalar_mul_mpfr.c create mode 100644 external/flint-2.4.3/mpfr_vec/scalar_product.c create mode 100644 external/flint-2.4.3/mpfr_vec/set.c create mode 100644 external/flint-2.4.3/mpfr_vec/test/t-init_clear.c create mode 100644 external/flint-2.4.3/mpfr_vec/zero.c create mode 100644 external/flint-2.4.3/mpn_extras.h create mode 100644 external/flint-2.4.3/mpn_extras/debug.c create mode 100644 external/flint-2.4.3/mpn_extras/divides.c create mode 100644 external/flint-2.4.3/mpn_extras/divrem_preinv1.c create mode 100644 external/flint-2.4.3/mpn_extras/divrem_preinvn.c create mode 100644 external/flint-2.4.3/mpn_extras/doc/mpn_extras.txt create mode 100644 external/flint-2.4.3/mpn_extras/factor_trial.c create mode 100644 external/flint-2.4.3/mpn_extras/gcd_full.c create mode 100644 external/flint-2.4.3/mpn_extras/harmonic.c create mode 100644 external/flint-2.4.3/mpn_extras/mod_preinvn.c create mode 100644 external/flint-2.4.3/mpn_extras/mulmod_2expp1_basecase.c create mode 100644 external/flint-2.4.3/mpn_extras/mulmod_preinv1.c create mode 100644 external/flint-2.4.3/mpn_extras/mulmod_preinvn.c create mode 100644 external/flint-2.4.3/mpn_extras/preinv1.c create mode 100644 external/flint-2.4.3/mpn_extras/preinvn.c create mode 100644 external/flint-2.4.3/mpn_extras/profile/p-mulmod_preinvn.c create mode 100644 external/flint-2.4.3/mpn_extras/remove_2exp.c create mode 100644 external/flint-2.4.3/mpn_extras/remove_power.c create mode 100644 external/flint-2.4.3/mpn_extras/test/t-divides.c create mode 100644 external/flint-2.4.3/mpn_extras/test/t-divrem_preinv1.c create mode 100644 external/flint-2.4.3/mpn_extras/test/t-divrem_preinvn.c create mode 100644 external/flint-2.4.3/mpn_extras/test/t-gcd_full.c create mode 100644 external/flint-2.4.3/mpn_extras/test/t-mod_preinvn.c create mode 100644 external/flint-2.4.3/mpn_extras/test/t-mulmod_2expp1.c create mode 100644 external/flint-2.4.3/mpn_extras/test/t-mulmod_preinv1.c create mode 100644 external/flint-2.4.3/mpn_extras/test/t-mulmod_preinvn.c create mode 100644 external/flint-2.4.3/mpn_extras/test/t-remove_2exp.c create mode 100644 external/flint-2.4.3/mpn_extras/test/t-remove_power.c create mode 100644 external/flint-2.4.3/nmod_mat.h create mode 100644 external/flint-2.4.3/nmod_mat/add.c create mode 100644 external/flint-2.4.3/nmod_mat/addmul.c create mode 100644 external/flint-2.4.3/nmod_mat/clear.c create mode 100644 external/flint-2.4.3/nmod_mat/det.c create mode 100644 external/flint-2.4.3/nmod_mat/doc/nmod_mat.txt create mode 100644 external/flint-2.4.3/nmod_mat/equal.c create mode 100644 external/flint-2.4.3/nmod_mat/init.c create mode 100644 external/flint-2.4.3/nmod_mat/init_set.c create mode 100644 external/flint-2.4.3/nmod_mat/inv.c create mode 100644 external/flint-2.4.3/nmod_mat/is_zero.c create mode 100644 external/flint-2.4.3/nmod_mat/lu.c create mode 100644 external/flint-2.4.3/nmod_mat/lu_classical.c create mode 100644 external/flint-2.4.3/nmod_mat/lu_recursive.c create mode 100644 external/flint-2.4.3/nmod_mat/mul.c create mode 100644 external/flint-2.4.3/nmod_mat/mul_classical.c create mode 100644 external/flint-2.4.3/nmod_mat/mul_strassen.c create mode 100644 external/flint-2.4.3/nmod_mat/neg.c create mode 100644 external/flint-2.4.3/nmod_mat/nullspace.c create mode 100644 external/flint-2.4.3/nmod_mat/print_pretty.c create mode 100644 external/flint-2.4.3/nmod_mat/profile/p-mul.c create mode 100644 external/flint-2.4.3/nmod_mat/randfull.c create mode 100644 external/flint-2.4.3/nmod_mat/randops.c create mode 100644 external/flint-2.4.3/nmod_mat/randpermdiag.c create mode 100644 external/flint-2.4.3/nmod_mat/randrank.c create mode 100644 external/flint-2.4.3/nmod_mat/randtest.c create mode 100644 external/flint-2.4.3/nmod_mat/randtril.c create mode 100644 external/flint-2.4.3/nmod_mat/randtriu.c create mode 100644 external/flint-2.4.3/nmod_mat/rank.c create mode 100644 external/flint-2.4.3/nmod_mat/rref.c create mode 100644 external/flint-2.4.3/nmod_mat/scalar_mul.c create mode 100644 external/flint-2.4.3/nmod_mat/set.c create mode 100644 external/flint-2.4.3/nmod_mat/solve.c create mode 100644 external/flint-2.4.3/nmod_mat/solve_tril.c create mode 100644 external/flint-2.4.3/nmod_mat/solve_tril_classical.c create mode 100644 external/flint-2.4.3/nmod_mat/solve_tril_recursive.c create mode 100644 external/flint-2.4.3/nmod_mat/solve_triu.c create mode 100644 external/flint-2.4.3/nmod_mat/solve_triu_classical.c create mode 100644 external/flint-2.4.3/nmod_mat/solve_triu_recursive.c create mode 100644 external/flint-2.4.3/nmod_mat/solve_vec.c create mode 100644 external/flint-2.4.3/nmod_mat/sub.c create mode 100644 external/flint-2.4.3/nmod_mat/submul.c create mode 100644 external/flint-2.4.3/nmod_mat/test/t-add.c create mode 100644 external/flint-2.4.3/nmod_mat/test/t-addmul.c create mode 100644 external/flint-2.4.3/nmod_mat/test/t-det.c create mode 100644 external/flint-2.4.3/nmod_mat/test/t-init_clear.c create mode 100644 external/flint-2.4.3/nmod_mat/test/t-inv.c create mode 100644 external/flint-2.4.3/nmod_mat/test/t-lu_classical.c create mode 100644 external/flint-2.4.3/nmod_mat/test/t-lu_recursive.c create mode 100644 external/flint-2.4.3/nmod_mat/test/t-mul.c create mode 100644 external/flint-2.4.3/nmod_mat/test/t-mul_strassen.c create mode 100644 external/flint-2.4.3/nmod_mat/test/t-neg.c create mode 100644 external/flint-2.4.3/nmod_mat/test/t-nullspace.c create mode 100644 external/flint-2.4.3/nmod_mat/test/t-rank.c create mode 100644 external/flint-2.4.3/nmod_mat/test/t-rref.c create mode 100644 external/flint-2.4.3/nmod_mat/test/t-scalar_mul.c create mode 100644 external/flint-2.4.3/nmod_mat/test/t-solve.c create mode 100644 external/flint-2.4.3/nmod_mat/test/t-solve_tril.c create mode 100644 external/flint-2.4.3/nmod_mat/test/t-solve_tril_classical.c create mode 100644 external/flint-2.4.3/nmod_mat/test/t-solve_tril_recursive.c create mode 100644 external/flint-2.4.3/nmod_mat/test/t-solve_triu.c create mode 100644 external/flint-2.4.3/nmod_mat/test/t-solve_triu_classical.c create mode 100644 external/flint-2.4.3/nmod_mat/test/t-solve_triu_recursive.c create mode 100644 external/flint-2.4.3/nmod_mat/test/t-solve_vec.c create mode 100644 external/flint-2.4.3/nmod_mat/test/t-submul.c create mode 100644 external/flint-2.4.3/nmod_mat/test/t-trace.c create mode 100644 external/flint-2.4.3/nmod_mat/test/t-transpose.c create mode 100644 external/flint-2.4.3/nmod_mat/trace.c create mode 100644 external/flint-2.4.3/nmod_mat/transpose.c create mode 100644 external/flint-2.4.3/nmod_mat/window_clear.c create mode 100644 external/flint-2.4.3/nmod_mat/window_init.c create mode 100644 external/flint-2.4.3/nmod_mat/zero.c create mode 100644 external/flint-2.4.3/nmod_matxx.h create mode 100644 external/flint-2.4.3/nmod_poly.h create mode 100644 external/flint-2.4.3/nmod_poly/KS2_pack.c create mode 100644 external/flint-2.4.3/nmod_poly/KS2_reduce.c create mode 100644 external/flint-2.4.3/nmod_poly/KS2_unpack.c create mode 100644 external/flint-2.4.3/nmod_poly/add.c create mode 100644 external/flint-2.4.3/nmod_poly/asin_series.c create mode 100644 external/flint-2.4.3/nmod_poly/asinh_series.c create mode 100644 external/flint-2.4.3/nmod_poly/atan_series.c create mode 100644 external/flint-2.4.3/nmod_poly/atanh_series.c create mode 100644 external/flint-2.4.3/nmod_poly/bit_pack.c create mode 100644 external/flint-2.4.3/nmod_poly/bit_unpack.c create mode 100644 external/flint-2.4.3/nmod_poly/clear.c create mode 100644 external/flint-2.4.3/nmod_poly/compose.c create mode 100644 external/flint-2.4.3/nmod_poly/compose_divconquer.c create mode 100644 external/flint-2.4.3/nmod_poly/compose_horner.c create mode 100644 external/flint-2.4.3/nmod_poly/compose_mod.c create mode 100644 external/flint-2.4.3/nmod_poly/compose_mod_brent_kung.c create mode 100644 external/flint-2.4.3/nmod_poly/compose_mod_brent_kung_precomp_preinv.c create mode 100644 external/flint-2.4.3/nmod_poly/compose_mod_brent_kung_preinv.c create mode 100644 external/flint-2.4.3/nmod_poly/compose_mod_horner.c create mode 100644 external/flint-2.4.3/nmod_poly/compose_series.c create mode 100644 external/flint-2.4.3/nmod_poly/compose_series_brent_kung.c create mode 100644 external/flint-2.4.3/nmod_poly/compose_series_divconquer.c create mode 100644 external/flint-2.4.3/nmod_poly/compose_series_horner.c create mode 100644 external/flint-2.4.3/nmod_poly/cos_series.c create mode 100644 external/flint-2.4.3/nmod_poly/cosh_series.c create mode 100644 external/flint-2.4.3/nmod_poly/deflate.c create mode 100644 external/flint-2.4.3/nmod_poly/deflation.c create mode 100644 external/flint-2.4.3/nmod_poly/derivative.c create mode 100644 external/flint-2.4.3/nmod_poly/div.c create mode 100644 external/flint-2.4.3/nmod_poly/div_basecase.c create mode 100644 external/flint-2.4.3/nmod_poly/div_divconquer.c create mode 100644 external/flint-2.4.3/nmod_poly/div_divconquer_recursive.c create mode 100644 external/flint-2.4.3/nmod_poly/div_newton.c create mode 100644 external/flint-2.4.3/nmod_poly/div_newton_n_preinv.c create mode 100644 external/flint-2.4.3/nmod_poly/div_root.c create mode 100644 external/flint-2.4.3/nmod_poly/div_series.c create mode 100644 external/flint-2.4.3/nmod_poly/divrem.c create mode 100644 external/flint-2.4.3/nmod_poly/divrem_basecase.c create mode 100644 external/flint-2.4.3/nmod_poly/divrem_divconquer.c create mode 100644 external/flint-2.4.3/nmod_poly/divrem_divconquer_recursive.c create mode 100644 external/flint-2.4.3/nmod_poly/divrem_newton.c create mode 100644 external/flint-2.4.3/nmod_poly/divrem_newton_n_preinv.c create mode 100644 external/flint-2.4.3/nmod_poly/divrem_q0.c create mode 100644 external/flint-2.4.3/nmod_poly/divrem_q1.c create mode 100644 external/flint-2.4.3/nmod_poly/doc/nmod_poly.txt create mode 100644 external/flint-2.4.3/nmod_poly/evaluate_fmpz.c create mode 100644 external/flint-2.4.3/nmod_poly/evaluate_nmod.c create mode 100644 external/flint-2.4.3/nmod_poly/evaluate_nmod_vec.c create mode 100644 external/flint-2.4.3/nmod_poly/evaluate_nmod_vec_fast.c create mode 100644 external/flint-2.4.3/nmod_poly/evaluate_nmod_vec_iter.c create mode 100644 external/flint-2.4.3/nmod_poly/exp_series.c create mode 100644 external/flint-2.4.3/nmod_poly/exp_series_basecase.c create mode 100644 external/flint-2.4.3/nmod_poly/exp_series_monomial_ui.c create mode 100644 external/flint-2.4.3/nmod_poly/fit_length.c create mode 100644 external/flint-2.4.3/nmod_poly/fread.c create mode 100644 external/flint-2.4.3/nmod_poly/gcd.c create mode 100644 external/flint-2.4.3/nmod_poly/gcd_euclidean.c create mode 100644 external/flint-2.4.3/nmod_poly/gcd_hgcd.c create mode 100644 external/flint-2.4.3/nmod_poly/gcdinv.c create mode 100644 external/flint-2.4.3/nmod_poly/get_str.c create mode 100644 external/flint-2.4.3/nmod_poly/hgcd.c create mode 100644 external/flint-2.4.3/nmod_poly/inflate.c create mode 100644 external/flint-2.4.3/nmod_poly/init.c create mode 100644 external/flint-2.4.3/nmod_poly/init2.c create mode 100644 external/flint-2.4.3/nmod_poly/integral.c create mode 100644 external/flint-2.4.3/nmod_poly/interpolate_nmod_vec.c create mode 100644 external/flint-2.4.3/nmod_poly/interpolate_nmod_vec_barycentric.c create mode 100644 external/flint-2.4.3/nmod_poly/interpolate_nmod_vec_fast.c create mode 100644 external/flint-2.4.3/nmod_poly/interpolate_nmod_vec_newton.c create mode 100644 external/flint-2.4.3/nmod_poly/inv_series_basecase.c create mode 100644 external/flint-2.4.3/nmod_poly/inv_series_newton.c create mode 100644 external/flint-2.4.3/nmod_poly/invmod.c create mode 100644 external/flint-2.4.3/nmod_poly/invsqrt_series.c create mode 100644 external/flint-2.4.3/nmod_poly/log_series.c create mode 100644 external/flint-2.4.3/nmod_poly/log_series_monomial_ui.c create mode 100644 external/flint-2.4.3/nmod_poly/make_monic.c create mode 100644 external/flint-2.4.3/nmod_poly/mul.c create mode 100644 external/flint-2.4.3/nmod_poly/mul_KS.c create mode 100644 external/flint-2.4.3/nmod_poly/mul_KS2.c create mode 100644 external/flint-2.4.3/nmod_poly/mul_KS4.c create mode 100644 external/flint-2.4.3/nmod_poly/mul_classical.c create mode 100644 external/flint-2.4.3/nmod_poly/mulhigh.c create mode 100644 external/flint-2.4.3/nmod_poly/mulhigh_classical.c create mode 100644 external/flint-2.4.3/nmod_poly/mullow.c create mode 100644 external/flint-2.4.3/nmod_poly/mullow_KS.c create mode 100644 external/flint-2.4.3/nmod_poly/mullow_classical.c create mode 100644 external/flint-2.4.3/nmod_poly/mulmod.c create mode 100644 external/flint-2.4.3/nmod_poly/mulmod_preinv.c create mode 100644 external/flint-2.4.3/nmod_poly/neg.c create mode 100644 external/flint-2.4.3/nmod_poly/pow.c create mode 100644 external/flint-2.4.3/nmod_poly/pow_binexp.c create mode 100644 external/flint-2.4.3/nmod_poly/pow_trunc.c create mode 100644 external/flint-2.4.3/nmod_poly/pow_trunc_binexp.c create mode 100644 external/flint-2.4.3/nmod_poly/powmod_mpz_binexp.c create mode 100644 external/flint-2.4.3/nmod_poly/powmod_mpz_binexp_preinv.c create mode 100644 external/flint-2.4.3/nmod_poly/powmod_ui_binexp.c create mode 100644 external/flint-2.4.3/nmod_poly/powmod_ui_binexp_preinv.c create mode 100644 external/flint-2.4.3/nmod_poly/powmod_x_ui_preinv.c create mode 100644 external/flint-2.4.3/nmod_poly/product_roots_nmod_vec.c create mode 100644 external/flint-2.4.3/nmod_poly/profile/p-gcd.c create mode 100644 external/flint-2.4.3/nmod_poly/profile/p-mul.c create mode 100644 external/flint-2.4.3/nmod_poly/profile/p-mulmod.c create mode 100644 external/flint-2.4.3/nmod_poly/randtest.c create mode 100644 external/flint-2.4.3/nmod_poly/realloc.c create mode 100644 external/flint-2.4.3/nmod_poly/rem.c create mode 100644 external/flint-2.4.3/nmod_poly/rem_basecase.c create mode 100644 external/flint-2.4.3/nmod_poly/rem_q1.c create mode 100644 external/flint-2.4.3/nmod_poly/remove.c create mode 100644 external/flint-2.4.3/nmod_poly/resultant_euclidean.c create mode 100644 external/flint-2.4.3/nmod_poly/reverse.c create mode 100644 external/flint-2.4.3/nmod_poly/revert_series.c create mode 100644 external/flint-2.4.3/nmod_poly/revert_series_lagrange.c create mode 100644 external/flint-2.4.3/nmod_poly/revert_series_lagrange_fast.c create mode 100644 external/flint-2.4.3/nmod_poly/revert_series_newton.c create mode 100644 external/flint-2.4.3/nmod_poly/scalar_mul_nmod.c create mode 100644 external/flint-2.4.3/nmod_poly/set_coeff_ui.c create mode 100644 external/flint-2.4.3/nmod_poly/set_str.c create mode 100644 external/flint-2.4.3/nmod_poly/shift_left.c create mode 100644 external/flint-2.4.3/nmod_poly/shift_right.c create mode 100644 external/flint-2.4.3/nmod_poly/sin_series.c create mode 100644 external/flint-2.4.3/nmod_poly/sinh_series.c create mode 100644 external/flint-2.4.3/nmod_poly/sqrt.c create mode 100644 external/flint-2.4.3/nmod_poly/sqrt_series.c create mode 100644 external/flint-2.4.3/nmod_poly/sub.c create mode 100644 external/flint-2.4.3/nmod_poly/tan_series.c create mode 100644 external/flint-2.4.3/nmod_poly/tanh_series.c create mode 100644 external/flint-2.4.3/nmod_poly/taylor_shift.c create mode 100644 external/flint-2.4.3/nmod_poly/taylor_shift_convolution.c create mode 100644 external/flint-2.4.3/nmod_poly/taylor_shift_horner.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-add.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-asin_series.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-asinh_series.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-atan_series.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-atanh_series.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-bit_pack.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-compose.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-compose_divconquer.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-compose_horner.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-compose_mod.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-compose_mod_brent_kung.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-compose_mod_brent_kung_precomp_preinv.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-compose_mod_brent_kung_preinv.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-compose_mod_horner.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-compose_series.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-compose_series_brent_kung.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-compose_series_divconquer.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-compose_series_horner.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-cos_series.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-cosh_series.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-deflate.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-derivative.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-div.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-div_basecase.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-div_divconquer.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-div_newton.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-div_newton_n_preinv.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-div_root.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-div_series.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-divrem.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-divrem_basecase.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-divrem_divconquer.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-divrem_newton.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-divrem_newton_n_preinv.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-evaluate_nmod.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-evaluate_nmod_vec_fast.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-exp_series.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-exp_series_basecase.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-exp_series_monomial_ui.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-fread_print.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-gcd.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-gcd_euclidean.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-gcd_hgcd.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-gcdinv.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-get_set_coeff_ui.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-get_set_str.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-hgcd.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-inflate.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-init_realloc_clear.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-integral.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-interpolate_nmod_vec.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-interpolate_nmod_vec_barycentric.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-interpolate_nmod_vec_fast.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-interpolate_nmod_vec_newton.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-inv_series_basecase.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-inv_series_newton.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-invmod.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-invsqrt_series.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-log_series.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-log_series_monomial_ui.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-make_monic.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-mul.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-mul_KS.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-mul_KS2.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-mul_KS4.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-mul_classical.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-mulhigh.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-mulhigh_classical.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-mullow.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-mullow_KS.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-mullow_classical.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-mulmod.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-mulmod_preinv.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-neg.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-pow.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-pow_binexp.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-pow_trunc.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-pow_trunc_binexp.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-powmod_mpz_binexp.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-powmod_mpz_binexp_preinv.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-powmod_ui_binexp.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-powmod_ui_binexp_preinv.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-powmod_x_ui_binexp.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-product_roots_nmod_vec.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-rem.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-rem_basecase.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-resultant.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-resultant_euclidean.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-reverse.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-revert_series.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-revert_series_lagrange.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-revert_series_lagrange_fast.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-revert_series_newton.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-scalar_mul_nmod.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-shift_left_right.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-sin_series.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-sinh_series.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-sqrt.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-sqrt_series.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-sub.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-tan_series.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-tanh_series.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-taylor_shift.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-taylor_shift_convolution.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-taylor_shift_horner.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-xgcd.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-xgcd_euclidean.c create mode 100644 external/flint-2.4.3/nmod_poly/test/t-xgcd_hgcd.c create mode 100644 external/flint-2.4.3/nmod_poly/tree.c create mode 100644 external/flint-2.4.3/nmod_poly/xgcd.c create mode 100644 external/flint-2.4.3/nmod_poly/xgcd_euclidean.c create mode 100644 external/flint-2.4.3/nmod_poly/xgcd_hgcd.c create mode 100644 external/flint-2.4.3/nmod_poly_factor.h create mode 100644 external/flint-2.4.3/nmod_poly_factor/clear.c create mode 100644 external/flint-2.4.3/nmod_poly_factor/concat.c create mode 100644 external/flint-2.4.3/nmod_poly_factor/doc/nmod_poly_factor.txt create mode 100644 external/flint-2.4.3/nmod_poly_factor/factor.c create mode 100644 external/flint-2.4.3/nmod_poly_factor/factor_berlekamp.c create mode 100644 external/flint-2.4.3/nmod_poly_factor/factor_cantor_zassenhaus.c create mode 100644 external/flint-2.4.3/nmod_poly_factor/factor_distinct_deg.c create mode 100644 external/flint-2.4.3/nmod_poly_factor/factor_equal_deg.c create mode 100644 external/flint-2.4.3/nmod_poly_factor/factor_equal_deg_prob.c create mode 100644 external/flint-2.4.3/nmod_poly_factor/factor_kaltofen_shoup.c create mode 100644 external/flint-2.4.3/nmod_poly_factor/factor_squarefree.c create mode 100644 external/flint-2.4.3/nmod_poly_factor/fit_length.c create mode 100644 external/flint-2.4.3/nmod_poly_factor/init.c create mode 100644 external/flint-2.4.3/nmod_poly_factor/insert.c create mode 100644 external/flint-2.4.3/nmod_poly_factor/is_irreducible.c create mode 100644 external/flint-2.4.3/nmod_poly_factor/is_irreducible_ddf.c create mode 100644 external/flint-2.4.3/nmod_poly_factor/is_irreducible_rabin.c create mode 100644 external/flint-2.4.3/nmod_poly_factor/is_squarefree.c create mode 100644 external/flint-2.4.3/nmod_poly_factor/pow.c create mode 100644 external/flint-2.4.3/nmod_poly_factor/print.c create mode 100644 external/flint-2.4.3/nmod_poly_factor/profile/p-factor.c create mode 100644 external/flint-2.4.3/nmod_poly_factor/profile/p-factorbench.c create mode 100644 external/flint-2.4.3/nmod_poly_factor/realloc.c create mode 100644 external/flint-2.4.3/nmod_poly_factor/set.c create mode 100644 external/flint-2.4.3/nmod_poly_factor/test/t-factor.c create mode 100644 external/flint-2.4.3/nmod_poly_factor/test/t-factor_berlekamp.c create mode 100644 external/flint-2.4.3/nmod_poly_factor/test/t-factor_cantor_zassenhaus.c create mode 100644 external/flint-2.4.3/nmod_poly_factor/test/t-factor_distinct_deg.c create mode 100644 external/flint-2.4.3/nmod_poly_factor/test/t-factor_kaltofen_shoup.c create mode 100644 external/flint-2.4.3/nmod_poly_factor/test/t-factor_squarefree.c create mode 100644 external/flint-2.4.3/nmod_poly_factor/test/t-is_irreducible.c create mode 100644 external/flint-2.4.3/nmod_poly_factor/test/t-is_irreducible_ddf.c create mode 100644 external/flint-2.4.3/nmod_poly_factor/test/t-is_irreducible_rabin.c create mode 100644 external/flint-2.4.3/nmod_poly_factor/test/t-is_squarefree.c create mode 100644 external/flint-2.4.3/nmod_poly_mat.h create mode 100644 external/flint-2.4.3/nmod_poly_mat/add.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/clear.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/det.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/det_fflu.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/det_interpolate.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/doc/nmod_poly_mat.txt create mode 100644 external/flint-2.4.3/nmod_poly_mat/equal.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/evaluate_nmod.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/fflu.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/find_pivot_any.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/find_pivot_partial.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/init.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/init_set.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/inv.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/is_one.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/is_zero.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/max_length.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/mul.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/mul_KS.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/mul_classical.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/mul_interpolate.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/neg.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/nullspace.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/one.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/pow.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/print.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/randtest.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/randtest_sparse.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/rank.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/rref.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/scalar_mul_nmod.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/scalar_mul_nmod_poly.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/set.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/solve.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/solve_fflu.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/solve_fflu_precomp.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/sqr.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/sqr_KS.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/sqr_classical.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/sqr_interpolate.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/sub.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/swap.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/test/t-add.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/test/t-det.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/test/t-det_interpolate.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/test/t-init_clear.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/test/t-inv.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/test/t-mul.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/test/t-mul_KS.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/test/t-mul_interpolate.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/test/t-neg.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/test/t-nullspace.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/test/t-one.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/test/t-pow.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/test/t-rank.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/test/t-rref.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/test/t-solve_fflu.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/test/t-sqr.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/test/t-sqr_KS.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/test/t-sqr_interpolate.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/test/t-sub.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/test/t-trace.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/test/t-zero.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/trace.c create mode 100644 external/flint-2.4.3/nmod_poly_mat/zero.c create mode 100644 external/flint-2.4.3/nmod_poly_matxx.h create mode 100644 external/flint-2.4.3/nmod_polyxx.h create mode 100644 external/flint-2.4.3/nmod_vec.h create mode 100644 external/flint-2.4.3/nmod_vec/add.c create mode 100644 external/flint-2.4.3/nmod_vec/doc/nmod_vec.txt create mode 100644 external/flint-2.4.3/nmod_vec/dot.c create mode 100644 external/flint-2.4.3/nmod_vec/dot_bound_limbs.c create mode 100644 external/flint-2.4.3/nmod_vec/dot_ptr.c create mode 100644 external/flint-2.4.3/nmod_vec/max_bits.c create mode 100644 external/flint-2.4.3/nmod_vec/neg.c create mode 100644 external/flint-2.4.3/nmod_vec/profile/p-add_sub_neg.c create mode 100644 external/flint-2.4.3/nmod_vec/profile/p-reduce.c create mode 100644 external/flint-2.4.3/nmod_vec/profile/p-scalar_mul.c create mode 100644 external/flint-2.4.3/nmod_vec/randtest.c create mode 100644 external/flint-2.4.3/nmod_vec/reduce.c create mode 100644 external/flint-2.4.3/nmod_vec/scalar_addmul_nmod.c create mode 100644 external/flint-2.4.3/nmod_vec/scalar_mul_nmod.c create mode 100644 external/flint-2.4.3/nmod_vec/sub.c create mode 100644 external/flint-2.4.3/nmod_vec/test/t-add_sub_neg.c create mode 100644 external/flint-2.4.3/nmod_vec/test/t-dot.c create mode 100644 external/flint-2.4.3/nmod_vec/test/t-dot_bound_limbs.c create mode 100644 external/flint-2.4.3/nmod_vec/test/t-dot_ptr.c create mode 100644 external/flint-2.4.3/nmod_vec/test/t-nmod.c create mode 100644 external/flint-2.4.3/nmod_vec/test/t-reduce.c create mode 100644 external/flint-2.4.3/nmod_vec/test/t-scalar_addmul_nmod.c create mode 100644 external/flint-2.4.3/nmod_vec/test/t-scalar_mul_nmod.c create mode 100644 external/flint-2.4.3/nmod_vecxx.h create mode 100644 external/flint-2.4.3/padic.h create mode 100644 external/flint-2.4.3/padic/add.c create mode 100644 external/flint-2.4.3/padic/clear.c create mode 100644 external/flint-2.4.3/padic/ctx_clear.c create mode 100644 external/flint-2.4.3/padic/ctx_init.c create mode 100644 external/flint-2.4.3/padic/div.c create mode 100644 external/flint-2.4.3/padic/doc/padic.txt create mode 100644 external/flint-2.4.3/padic/exp.c create mode 100644 external/flint-2.4.3/padic/exp_balanced.c create mode 100644 external/flint-2.4.3/padic/exp_rectangular.c create mode 100644 external/flint-2.4.3/padic/fprint.c create mode 100644 external/flint-2.4.3/padic/get_fmpq.c create mode 100644 external/flint-2.4.3/padic/get_fmpz.c create mode 100644 external/flint-2.4.3/padic/get_mpq.c create mode 100644 external/flint-2.4.3/padic/get_mpz.c create mode 100644 external/flint-2.4.3/padic/get_str.c create mode 100644 external/flint-2.4.3/padic/init.c create mode 100644 external/flint-2.4.3/padic/inv.c create mode 100644 external/flint-2.4.3/padic/lifts.c create mode 100644 external/flint-2.4.3/padic/log.c create mode 100644 external/flint-2.4.3/padic/log_balanced.c create mode 100644 external/flint-2.4.3/padic/log_rectangular.c create mode 100644 external/flint-2.4.3/padic/log_satoh.c create mode 100644 external/flint-2.4.3/padic/mul.c create mode 100644 external/flint-2.4.3/padic/neg.c create mode 100644 external/flint-2.4.3/padic/pow_si.c create mode 100644 external/flint-2.4.3/padic/profile/p-exp_balanced_2.c create mode 100644 external/flint-2.4.3/padic/profile/p-exp_balanced_p.c create mode 100644 external/flint-2.4.3/padic/profile/p-exp_rectangular.c create mode 100644 external/flint-2.4.3/padic/profile/p-inv.c create mode 100644 external/flint-2.4.3/padic/profile/p-log_balanced.c create mode 100644 external/flint-2.4.3/padic/profile/p-log_rectangular.c create mode 100644 external/flint-2.4.3/padic/profile/p-mul.c create mode 100644 external/flint-2.4.3/padic/profile/p-sqrt.c create mode 100644 external/flint-2.4.3/padic/profile/p-teichmuller.c create mode 100644 external/flint-2.4.3/padic/randtest.c create mode 100644 external/flint-2.4.3/padic/reduce.c create mode 100644 external/flint-2.4.3/padic/set.c create mode 100644 external/flint-2.4.3/padic/set_fmpq.c create mode 100644 external/flint-2.4.3/padic/set_fmpz.c create mode 100644 external/flint-2.4.3/padic/set_mpq.c create mode 100644 external/flint-2.4.3/padic/set_mpz.c create mode 100644 external/flint-2.4.3/padic/set_si.c create mode 100644 external/flint-2.4.3/padic/set_ui.c create mode 100644 external/flint-2.4.3/padic/shift.c create mode 100644 external/flint-2.4.3/padic/sqrt.c create mode 100644 external/flint-2.4.3/padic/sub.c create mode 100644 external/flint-2.4.3/padic/teichmuller.c create mode 100644 external/flint-2.4.3/padic/test/t-add.c create mode 100644 external/flint-2.4.3/padic/test/t-div.c create mode 100644 external/flint-2.4.3/padic/test/t-exp.c create mode 100644 external/flint-2.4.3/padic/test/t-exp_balanced.c create mode 100644 external/flint-2.4.3/padic/test/t-exp_rectangular.c create mode 100644 external/flint-2.4.3/padic/test/t-get_set_fmpz.c create mode 100644 external/flint-2.4.3/padic/test/t-get_set_mpq.c create mode 100644 external/flint-2.4.3/padic/test/t-get_set_mpz.c create mode 100644 external/flint-2.4.3/padic/test/t-get_str.c create mode 100644 external/flint-2.4.3/padic/test/t-inv.c create mode 100644 external/flint-2.4.3/padic/test/t-log.c create mode 100644 external/flint-2.4.3/padic/test/t-log_balanced.c create mode 100644 external/flint-2.4.3/padic/test/t-log_rectangular.c create mode 100644 external/flint-2.4.3/padic/test/t-log_satoh.c create mode 100644 external/flint-2.4.3/padic/test/t-mul.c create mode 100644 external/flint-2.4.3/padic/test/t-neg.c create mode 100644 external/flint-2.4.3/padic/test/t-pow_si.c create mode 100644 external/flint-2.4.3/padic/test/t-randtest.c create mode 100644 external/flint-2.4.3/padic/test/t-shift.c create mode 100644 external/flint-2.4.3/padic/test/t-sqrt.c create mode 100644 external/flint-2.4.3/padic/test/t-sub.c create mode 100644 external/flint-2.4.3/padic/test/t-teichmuller.c create mode 100644 external/flint-2.4.3/padic/test/t-val_fac.c create mode 100644 external/flint-2.4.3/padic/val_fac.c create mode 100644 external/flint-2.4.3/padic_mat.h create mode 100644 external/flint-2.4.3/padic_mat/Makefile create mode 100644 external/flint-2.4.3/padic_mat/add.c create mode 100644 external/flint-2.4.3/padic_mat/canonicalise.c create mode 100644 external/flint-2.4.3/padic_mat/clear.c create mode 100644 external/flint-2.4.3/padic_mat/doc/padic_mat.txt create mode 100644 external/flint-2.4.3/padic_mat/equal.c create mode 100644 external/flint-2.4.3/padic_mat/fprint.c create mode 100644 external/flint-2.4.3/padic_mat/fprint_pretty.c create mode 100644 external/flint-2.4.3/padic_mat/get_entry_padic.c create mode 100644 external/flint-2.4.3/padic_mat/get_fmpq_mat.c create mode 100644 external/flint-2.4.3/padic_mat/init.c create mode 100644 external/flint-2.4.3/padic_mat/is_zero.c create mode 100644 external/flint-2.4.3/padic_mat/mul.c create mode 100644 external/flint-2.4.3/padic_mat/neg.c create mode 100644 external/flint-2.4.3/padic_mat/one.c create mode 100644 external/flint-2.4.3/padic_mat/randtest.c create mode 100644 external/flint-2.4.3/padic_mat/reduce.c create mode 100644 external/flint-2.4.3/padic_mat/scalar_div_fmpz.c create mode 100644 external/flint-2.4.3/padic_mat/scalar_mul_fmpz.c create mode 100644 external/flint-2.4.3/padic_mat/scalar_mul_padic.c create mode 100644 external/flint-2.4.3/padic_mat/set.c create mode 100644 external/flint-2.4.3/padic_mat/set_entry_padic.c create mode 100644 external/flint-2.4.3/padic_mat/set_fmpq_mat.c create mode 100644 external/flint-2.4.3/padic_mat/sub.c create mode 100644 external/flint-2.4.3/padic_mat/swap.c create mode 100644 external/flint-2.4.3/padic_mat/test/t-add.c create mode 100644 external/flint-2.4.3/padic_mat/test/t-get_set_entry_padic.c create mode 100644 external/flint-2.4.3/padic_mat/test/t-get_set_fmpq_mat.c create mode 100644 external/flint-2.4.3/padic_mat/test/t-mul.c create mode 100644 external/flint-2.4.3/padic_mat/test/t-neg.c create mode 100644 external/flint-2.4.3/padic_mat/test/t-scalar_div_fmpz.c create mode 100644 external/flint-2.4.3/padic_mat/test/t-scalar_mul_fmpz.c create mode 100644 external/flint-2.4.3/padic_mat/test/t-scalar_mul_padic.c create mode 100644 external/flint-2.4.3/padic_mat/test/t-sub.c create mode 100644 external/flint-2.4.3/padic_mat/transpose.c create mode 100644 external/flint-2.4.3/padic_mat/zero.c create mode 100644 external/flint-2.4.3/padic_matxx.h create mode 100644 external/flint-2.4.3/padic_poly.h create mode 100644 external/flint-2.4.3/padic_poly/Makefile create mode 100644 external/flint-2.4.3/padic_poly/add.c create mode 100644 external/flint-2.4.3/padic_poly/canonicalise.c create mode 100644 external/flint-2.4.3/padic_poly/clear.c create mode 100644 external/flint-2.4.3/padic_poly/compose.c create mode 100644 external/flint-2.4.3/padic_poly/compose_pow.c create mode 100644 external/flint-2.4.3/padic_poly/derivative.c create mode 100644 external/flint-2.4.3/padic_poly/doc/padic_poly.txt create mode 100644 external/flint-2.4.3/padic_poly/equal.c create mode 100644 external/flint-2.4.3/padic_poly/evaluate_padic.c create mode 100644 external/flint-2.4.3/padic_poly/fit_length.c create mode 100644 external/flint-2.4.3/padic_poly/fprint.c create mode 100644 external/flint-2.4.3/padic_poly/fprint_pretty.c create mode 100644 external/flint-2.4.3/padic_poly/get_coeff_padic.c create mode 100644 external/flint-2.4.3/padic_poly/get_fmpq_poly.c create mode 100644 external/flint-2.4.3/padic_poly/get_fmpz_poly.c create mode 100644 external/flint-2.4.3/padic_poly/init.c create mode 100644 external/flint-2.4.3/padic_poly/inv_series.c create mode 100644 external/flint-2.4.3/padic_poly/is_canonical.c create mode 100644 external/flint-2.4.3/padic_poly/is_reduced.c create mode 100644 external/flint-2.4.3/padic_poly/mul.c create mode 100644 external/flint-2.4.3/padic_poly/neg.c create mode 100644 external/flint-2.4.3/padic_poly/normalise.c create mode 100644 external/flint-2.4.3/padic_poly/pow.c create mode 100644 external/flint-2.4.3/padic_poly/randtest.c create mode 100644 external/flint-2.4.3/padic_poly/realloc.c create mode 100644 external/flint-2.4.3/padic_poly/reduce.c create mode 100644 external/flint-2.4.3/padic_poly/scalar_mul_padic.c create mode 100644 external/flint-2.4.3/padic_poly/set.c create mode 100644 external/flint-2.4.3/padic_poly/set_coeff_padic.c create mode 100644 external/flint-2.4.3/padic_poly/set_fmpq.c create mode 100644 external/flint-2.4.3/padic_poly/set_fmpq_poly.c create mode 100644 external/flint-2.4.3/padic_poly/set_fmpz.c create mode 100644 external/flint-2.4.3/padic_poly/set_fmpz_poly.c create mode 100644 external/flint-2.4.3/padic_poly/set_padic.c create mode 100644 external/flint-2.4.3/padic_poly/set_si.c create mode 100644 external/flint-2.4.3/padic_poly/set_ui.c create mode 100644 external/flint-2.4.3/padic_poly/shift_left.c create mode 100644 external/flint-2.4.3/padic_poly/shift_right.c create mode 100644 external/flint-2.4.3/padic_poly/sub.c create mode 100644 external/flint-2.4.3/padic_poly/swap.c create mode 100644 external/flint-2.4.3/padic_poly/test/t-add.c create mode 100644 external/flint-2.4.3/padic_poly/test/t-compose.c create mode 100644 external/flint-2.4.3/padic_poly/test/t-compose_pow.c create mode 100644 external/flint-2.4.3/padic_poly/test/t-derivative.c create mode 100644 external/flint-2.4.3/padic_poly/test/t-evaluate_padic.c create mode 100644 external/flint-2.4.3/padic_poly/test/t-get_set_fmpq_poly.c create mode 100644 external/flint-2.4.3/padic_poly/test/t-init_realloc_clear.c create mode 100644 external/flint-2.4.3/padic_poly/test/t-inv_series.c create mode 100644 external/flint-2.4.3/padic_poly/test/t-mul.c create mode 100644 external/flint-2.4.3/padic_poly/test/t-neg.c create mode 100644 external/flint-2.4.3/padic_poly/test/t-one.c create mode 100644 external/flint-2.4.3/padic_poly/test/t-pow.c create mode 100644 external/flint-2.4.3/padic_poly/test/t-shift_left_right.c create mode 100644 external/flint-2.4.3/padic_poly/test/t-sub.c create mode 100644 external/flint-2.4.3/padic_poly/test/t-truncate.c create mode 100644 external/flint-2.4.3/padic_poly/test/t-zero.c create mode 100644 external/flint-2.4.3/padic_polyxx.h create mode 100644 external/flint-2.4.3/padicxx.h create mode 100644 external/flint-2.4.3/perm.h create mode 100644 external/flint-2.4.3/perm/doc/perm.txt create mode 100644 external/flint-2.4.3/perm/parity.c create mode 100644 external/flint-2.4.3/perm/randtest.c create mode 100644 external/flint-2.4.3/perm/test/t-compose.c create mode 100644 external/flint-2.4.3/perm/test/t-inv.c create mode 100644 external/flint-2.4.3/perm/test/t-parity.c create mode 100644 external/flint-2.4.3/permxx.h create mode 100644 external/flint-2.4.3/printf.c create mode 100644 external/flint-2.4.3/profile/p-udiv_qrnnd.c create mode 100644 external/flint-2.4.3/profile/p-udiv_qrnnd_preinv.c create mode 100644 external/flint-2.4.3/profile/timings.txt create mode 100644 external/flint-2.4.3/profiler.c create mode 100644 external/flint-2.4.3/profiler.h create mode 100644 external/flint-2.4.3/qadic.h create mode 100644 external/flint-2.4.3/qadic/CPimport.txt create mode 100644 external/flint-2.4.3/qadic/Makefile create mode 100644 external/flint-2.4.3/qadic/ctx_clear.c create mode 100644 external/flint-2.4.3/qadic/ctx_init_conway.c create mode 100644 external/flint-2.4.3/qadic/doc/qadic.txt create mode 100644 external/flint-2.4.3/qadic/exp.c create mode 100644 external/flint-2.4.3/qadic/exp_balanced.c create mode 100644 external/flint-2.4.3/qadic/exp_rectangular.c create mode 100644 external/flint-2.4.3/qadic/fprint_pretty.c create mode 100644 external/flint-2.4.3/qadic/frobenius.c create mode 100644 external/flint-2.4.3/qadic/inv.c create mode 100644 external/flint-2.4.3/qadic/log.c create mode 100644 external/flint-2.4.3/qadic/log_balanced.c create mode 100644 external/flint-2.4.3/qadic/log_rectangular.c create mode 100644 external/flint-2.4.3/qadic/mul.c create mode 100644 external/flint-2.4.3/qadic/norm.c create mode 100644 external/flint-2.4.3/qadic/norm_analytic.c create mode 100644 external/flint-2.4.3/qadic/norm_resultant.c create mode 100644 external/flint-2.4.3/qadic/pow.c create mode 100644 external/flint-2.4.3/qadic/profile/p-exp_balanced.c create mode 100644 external/flint-2.4.3/qadic/profile/p-exp_rectangular.c create mode 100644 external/flint-2.4.3/qadic/profile/p-frobenius.c create mode 100644 external/flint-2.4.3/qadic/profile/p-inv.c create mode 100644 external/flint-2.4.3/qadic/profile/p-log_balanced.c create mode 100644 external/flint-2.4.3/qadic/profile/p-log_rectangular.c create mode 100644 external/flint-2.4.3/qadic/profile/p-mul.c create mode 100644 external/flint-2.4.3/qadic/profile/p-norm_analytic.c create mode 100644 external/flint-2.4.3/qadic/profile/p-norm_resultant.c create mode 100644 external/flint-2.4.3/qadic/profile/p-sqrt.c create mode 100644 external/flint-2.4.3/qadic/profile/p-teichmuller.c create mode 100644 external/flint-2.4.3/qadic/profile/p-trace.c create mode 100644 external/flint-2.4.3/qadic/set_fmpz_poly.c create mode 100644 external/flint-2.4.3/qadic/sqrt.c create mode 100644 external/flint-2.4.3/qadic/teichmuller.c create mode 100644 external/flint-2.4.3/qadic/test/t-add.c create mode 100644 external/flint-2.4.3/qadic/test/t-exp.c create mode 100644 external/flint-2.4.3/qadic/test/t-exp_balanced.c create mode 100644 external/flint-2.4.3/qadic/test/t-exp_rectangular.c create mode 100644 external/flint-2.4.3/qadic/test/t-frobenius.c create mode 100644 external/flint-2.4.3/qadic/test/t-inv.c create mode 100644 external/flint-2.4.3/qadic/test/t-log.c create mode 100644 external/flint-2.4.3/qadic/test/t-log_balanced.c create mode 100644 external/flint-2.4.3/qadic/test/t-log_rectangular.c create mode 100644 external/flint-2.4.3/qadic/test/t-mul.c create mode 100644 external/flint-2.4.3/qadic/test/t-neg.c create mode 100644 external/flint-2.4.3/qadic/test/t-norm.c create mode 100644 external/flint-2.4.3/qadic/test/t-norm_analytic.c create mode 100644 external/flint-2.4.3/qadic/test/t-norm_resultant.c create mode 100644 external/flint-2.4.3/qadic/test/t-pow.c create mode 100644 external/flint-2.4.3/qadic/test/t-sqrt.c create mode 100644 external/flint-2.4.3/qadic/test/t-sub.c create mode 100644 external/flint-2.4.3/qadic/test/t-teichmuller.c create mode 100644 external/flint-2.4.3/qadic/test/t-trace.c create mode 100644 external/flint-2.4.3/qadic/trace.c create mode 100644 external/flint-2.4.3/qadicxx.h create mode 100644 external/flint-2.4.3/qsieve.h create mode 100644 external/flint-2.4.3/qsieve/block_lanczos.c create mode 100644 external/flint-2.4.3/qsieve/doc/qsieve.txt create mode 100644 external/flint-2.4.3/qsieve/ll_clear.c create mode 100644 external/flint-2.4.3/qsieve/ll_collect_relations.c create mode 100644 external/flint-2.4.3/qsieve/ll_compute_poly_data.c create mode 100644 external/flint-2.4.3/qsieve/ll_factor.c create mode 100644 external/flint-2.4.3/qsieve/ll_init.c create mode 100644 external/flint-2.4.3/qsieve/ll_insert_relations.c create mode 100644 external/flint-2.4.3/qsieve/ll_knuth_schroeppel.c create mode 100644 external/flint-2.4.3/qsieve/ll_linalg_init.c create mode 100644 external/flint-2.4.3/qsieve/ll_poly_init.c create mode 100644 external/flint-2.4.3/qsieve/ll_primes_init.c create mode 100644 external/flint-2.4.3/qsieve/ll_square_root.c create mode 100644 external/flint-2.4.3/qsieve/test/t-ll_factor.c create mode 100644 external/flint-2.4.3/qsieve/test/t-ll_knuth_schroeppel.c create mode 100644 external/flint-2.4.3/scanf.c create mode 100644 external/flint-2.4.3/sprintf.c create mode 100644 external/flint-2.4.3/sscanf.c create mode 100644 external/flint-2.4.3/templates.h create mode 100644 external/flint-2.4.3/test/t-add_ssaaaa.c create mode 100644 external/flint-2.4.3/test/t-add_sssaaaaaa.c create mode 100644 external/flint-2.4.3/test/t-count_leading_zeros.c create mode 100644 external/flint-2.4.3/test/t-count_trailing_zeros.c create mode 100644 external/flint-2.4.3/test/t-sdiv_qrnnd.c create mode 100644 external/flint-2.4.3/test/t-smul_ppmm.c create mode 100644 external/flint-2.4.3/test/t-sub_ddmmss.c create mode 100644 external/flint-2.4.3/test/t-udiv_qrnnd.c create mode 100644 external/flint-2.4.3/test/t-udiv_qrnnd_preinv.c create mode 100644 external/flint-2.4.3/test/t-umul_ppmm.c create mode 100644 external/flint-2.4.3/test_helpers.c create mode 100644 external/flint-2.4.3/thread_support.c create mode 100644 external/flint-2.4.3/todo.txt create mode 100644 external/flint-2.4.3/ulong_extras.h create mode 100644 external/flint-2.4.3/ulong_extras/cleanup_primes.c create mode 100644 external/flint-2.4.3/ulong_extras/clog.c create mode 100644 external/flint-2.4.3/ulong_extras/compute_primes.c create mode 100644 external/flint-2.4.3/ulong_extras/discrete_log_bsgs.c create mode 100644 external/flint-2.4.3/ulong_extras/divrem2_precomp.c create mode 100644 external/flint-2.4.3/ulong_extras/doc/ulong_extras.txt create mode 100644 external/flint-2.4.3/ulong_extras/euler_phi.c create mode 100644 external/flint-2.4.3/ulong_extras/factor.c create mode 100644 external/flint-2.4.3/ulong_extras/factor_SQUFOF.c create mode 100644 external/flint-2.4.3/ulong_extras/factor_insert.c create mode 100644 external/flint-2.4.3/ulong_extras/factor_lehman.c create mode 100644 external/flint-2.4.3/ulong_extras/factor_one_line.c create mode 100644 external/flint-2.4.3/ulong_extras/factor_partial.c create mode 100644 external/flint-2.4.3/ulong_extras/factor_power235.c create mode 100644 external/flint-2.4.3/ulong_extras/factor_pp1.c create mode 100644 external/flint-2.4.3/ulong_extras/factor_trial.c create mode 100644 external/flint-2.4.3/ulong_extras/factor_trial_partial.c create mode 100644 external/flint-2.4.3/ulong_extras/factor_trial_range.c create mode 100644 external/flint-2.4.3/ulong_extras/factorial_fast_mod2_preinv.c create mode 100644 external/flint-2.4.3/ulong_extras/factorial_mod2_preinv.c create mode 100644 external/flint-2.4.3/ulong_extras/flog.c create mode 100644 external/flint-2.4.3/ulong_extras/gcd.c create mode 100644 external/flint-2.4.3/ulong_extras/gcdinv.c create mode 100644 external/flint-2.4.3/ulong_extras/invmod.c create mode 100644 external/flint-2.4.3/ulong_extras/is_oddprime_binary.c create mode 100644 external/flint-2.4.3/ulong_extras/is_oddprime_small.c create mode 100644 external/flint-2.4.3/ulong_extras/is_perfect_power235.c create mode 100644 external/flint-2.4.3/ulong_extras/is_prime.c create mode 100644 external/flint-2.4.3/ulong_extras/is_prime_pocklington.c create mode 100644 external/flint-2.4.3/ulong_extras/is_prime_pseudosquare.c create mode 100644 external/flint-2.4.3/ulong_extras/is_probabprime.c create mode 100644 external/flint-2.4.3/ulong_extras/is_probabprime_BPSW.c create mode 100644 external/flint-2.4.3/ulong_extras/is_probabprime_fermat.c create mode 100644 external/flint-2.4.3/ulong_extras/is_probabprime_fibonacci.c create mode 100644 external/flint-2.4.3/ulong_extras/is_probabprime_lucas.c create mode 100644 external/flint-2.4.3/ulong_extras/is_square.c create mode 100644 external/flint-2.4.3/ulong_extras/is_squarefree.c create mode 100644 external/flint-2.4.3/ulong_extras/is_strong_probabprime2_preinv.c create mode 100644 external/flint-2.4.3/ulong_extras/is_strong_probabprime_precomp.c create mode 100644 external/flint-2.4.3/ulong_extras/jacobi.c create mode 100644 external/flint-2.4.3/ulong_extras/ll_mod_preinv.c create mode 100644 external/flint-2.4.3/ulong_extras/lll_mod_preinv.c create mode 100644 external/flint-2.4.3/ulong_extras/mod2_precomp.c create mode 100644 external/flint-2.4.3/ulong_extras/mod2_preinv.c create mode 100644 external/flint-2.4.3/ulong_extras/mod_precomp.c create mode 100644 external/flint-2.4.3/ulong_extras/moebius_mu.c create mode 100644 external/flint-2.4.3/ulong_extras/mulmod2_preinv.c create mode 100644 external/flint-2.4.3/ulong_extras/mulmod_precomp.c create mode 100644 external/flint-2.4.3/ulong_extras/mulmod_preinv.c create mode 100644 external/flint-2.4.3/ulong_extras/nextprime.c create mode 100644 external/flint-2.4.3/ulong_extras/nth_prime.c create mode 100644 external/flint-2.4.3/ulong_extras/nth_prime_bounds.c create mode 100644 external/flint-2.4.3/ulong_extras/pow.c create mode 100644 external/flint-2.4.3/ulong_extras/powmod2_preinv.c create mode 100644 external/flint-2.4.3/ulong_extras/powmod_precomp.c create mode 100644 external/flint-2.4.3/ulong_extras/prime_inverses_arr_readonly.c create mode 100644 external/flint-2.4.3/ulong_extras/prime_pi.c create mode 100644 external/flint-2.4.3/ulong_extras/prime_pi_bounds.c create mode 100644 external/flint-2.4.3/ulong_extras/primes_arr_readonly.c create mode 100644 external/flint-2.4.3/ulong_extras/primes_clear.c create mode 100644 external/flint-2.4.3/ulong_extras/primes_extend_small.c create mode 100644 external/flint-2.4.3/ulong_extras/primes_init.c create mode 100644 external/flint-2.4.3/ulong_extras/primes_jump_after.c create mode 100644 external/flint-2.4.3/ulong_extras/primes_sieve_range.c create mode 100644 external/flint-2.4.3/ulong_extras/primitive_root_prime.c create mode 100644 external/flint-2.4.3/ulong_extras/profile/p-factor.c create mode 100644 external/flint-2.4.3/ulong_extras/profile/p-factor_pp1.c create mode 100644 external/flint-2.4.3/ulong_extras/profile/p-is_probabprime_BPSW.c create mode 100644 external/flint-2.4.3/ulong_extras/profile/p-lll_mod_preinv.c create mode 100644 external/flint-2.4.3/ulong_extras/profile/p-mod2_precomp.c create mode 100644 external/flint-2.4.3/ulong_extras/profile/p-mod2_preinv.c create mode 100644 external/flint-2.4.3/ulong_extras/profile/p-mod_precomp.c create mode 100644 external/flint-2.4.3/ulong_extras/profile/p-mulmod2_preinv.c create mode 100644 external/flint-2.4.3/ulong_extras/profile/p-mulmod_precomp.c create mode 100644 external/flint-2.4.3/ulong_extras/profile/timings.txt create mode 100644 external/flint-2.4.3/ulong_extras/randbits.c create mode 100644 external/flint-2.4.3/ulong_extras/randint.c create mode 100644 external/flint-2.4.3/ulong_extras/randlimb.c create mode 100644 external/flint-2.4.3/ulong_extras/randprime.c create mode 100644 external/flint-2.4.3/ulong_extras/randtest.c create mode 100644 external/flint-2.4.3/ulong_extras/remove.c create mode 100644 external/flint-2.4.3/ulong_extras/remove2_precomp.c create mode 100644 external/flint-2.4.3/ulong_extras/revbin.c create mode 100644 external/flint-2.4.3/ulong_extras/sizeinbase.c create mode 100644 external/flint-2.4.3/ulong_extras/sqrt.c create mode 100644 external/flint-2.4.3/ulong_extras/sqrtmod.c create mode 100644 external/flint-2.4.3/ulong_extras/sqrtmod_primepow.c create mode 100644 external/flint-2.4.3/ulong_extras/sqrtmodn.c create mode 100644 external/flint-2.4.3/ulong_extras/sqrtrem.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-addmod.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-clog.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-compute_primes.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-discrete_log_bsgs.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-divrem2_precomp.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-euler_phi.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-factor.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-factor_SQUFOF.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-factor_lehman.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-factor_one_line.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-factor_partial.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-factor_power235.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-factor_pp1.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-factor_trial.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-factor_trial_partial.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-factor_trial_range.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-factorial_fast_mod2_preinv.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-factorial_mod2_preinv.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-flog.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-gcd.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-gcd_full.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-gcdinv.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-invmod.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-is_oddprime_binary.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-is_oddprime_small.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-is_perfect_power235.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-is_prime.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-is_prime_pocklington.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-is_prime_pseudosquare.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-is_probabprime.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-is_probabprime_BPSW.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-is_probabprime_fermat.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-is_probabprime_fibonacci.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-is_probabprime_lucas.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-is_square.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-is_squarefree.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-is_strong_probabprime2_preinv.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-is_strong_probabprime_precomp.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-jacobi.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-ll_mod_preinv.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-lll_mod_preinv.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-mod2_precomp.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-mod2_preinv.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-mod_precomp.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-moebius_mu.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-mulmod2_preinv.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-mulmod_precomp.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-nextprime.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-nth_prime_bounds.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-pow.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-powmod.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-powmod2.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-powmod2_preinv.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-powmod2_ui_preinv.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-powmod_precomp.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-powmod_ui_precomp.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-prime_pi.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-prime_pi_bounds.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-primes.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-primes_jump_after.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-primitive_root_prime.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-remove.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-remove2_precomp.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-sizeinbase.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-sqrt.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-sqrtmod.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-sqrtmod_primepow.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-sqrtmodn.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-sqrtrem.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-submod.c create mode 100644 external/flint-2.4.3/ulong_extras/test/t-xgcd.c create mode 100644 external/flint-2.4.3/ulong_extras/xgcd.c create mode 100644 external/flint-2.4.3/version.c diff --git a/external/flint-2.4.3/AUTHORS b/external/flint-2.4.3/AUTHORS new file mode 100644 index 0000000..f0aa300 --- /dev/null +++ b/external/flint-2.4.3/AUTHORS @@ -0,0 +1,127 @@ +FLINT has been developed since 2007 by a large number of people. Initially +the library was started by David Harvey and William Hart. Later maintenance +of the library was taken over solely by William Hart. + +The authors of FLINT to date: + +$\bullet$ William Hart -- integer and polynomial arithmetic, factorisation and +primality testing, general infrastructure (supported by EPSRC Grant +EP/G004870/1 and DFG Priority programme SPP1489) + +$\bullet$ Sebastian Pancratz -- polynomial arithmetic over $\Z$, $\Z/n\Z$ and +$\Q$, $p$-adic and $q$-adic arithmetic, including polynomials and matrices +(supported by ERC Grant 204083) + +$\bullet$ Andy Novocin -- LLL, polynomial factorisation over $Z$, polynomial +composition + +$\bullet$ Fredrik Johansson -- matrices, polynomial and power series +arithmetic, special functions (supported by Austrian Science Fund FWF Grant +Y464-N18) + +$\bullet$ Tom Bachmann -- \code{C++} expressions template wrapper, +documentation parser (Google Summer of Code 2013) + +$\bullet$ Mike Hansen -- Finite fields (small and large $\F_q$), +polynomials/matrices over $\F_q$, Finite fields with Zech logarithm +representation, Fast factorisation of polynomials over $\F_q$ (supported by +Macaulay2 developers NSF Grant 1002171) + +$\bullet$ Martin Lee -- Fast factorisation of polynomials over $\Z/n\Z$, +faster Brent-Kung modular composition + +$\bullet$ David Harvey -- Fast Fourier Transform code, \code{zn_poly} for +polynomial arithmetic over $\Z/n\Z$, \code{mpz_poly}, profiling and +graphing code and many other parts of the FLINT library + +$\bullet$ Jan Tuitman -- helped with the $p$-adic interface + +$\bullet$ Jason Papadopoulos -- Block Lanczos code for quadratic sieve and +multiprecision complex root finding code for polynomials. + +$\bullet$ Gonzalo Tornaria -- Theta function module, Montgomery multiplication +and significant contributions to the $\Z[x]$ modular multiplication code. + +$\bullet$ Burcin Erocal -- wrote the primary FLINT wrapper in the SAGE system +(Robert Bradshaw also wrote a preliminary version of this and Martin Albrecht +and others have also contributed to it.) Burcin also contributed by writing +grant applications via his Lmonade organisation to Google. (Supported by DFG +Priority programme SPP1489.) + +$\bullet$ Tom Boothby -- Improved factoring of unsigned longs, detection of +perfect powers + +$\bullet$ Andres Goens -- $\F_q$ module and polynomials over $\F_q$ (supported +by DFG Priority program SPP1489) + +$\bullet$ Lina Kulakova -- factorisation for polynomials over $\F_p$ for large +$p$ (Google Summer of Code 2012) + +$\bullet$ Thomas DuBuisson -- logical ops for fmpz module, patches to the build +system + +$\bullet$ Jean-Pierre Flori -- many build system patches and Sage integration + +$\bullet$ Frithjof Schulze -- some fmpz functions and various patches + +$\bullet$ Curtis Bright -- numerous patches including 32 bit support + +$\bullet$ Daniel Woodhouse -- Contributed an implementation of multivariate +multiplication over $\Z/n\Z$ and used this to implement a fast ``saturation'' +algorithm for Laurent polynomials. (Funded by Alessio Corti and Tom Coates +at Imperial College) + +$\bullet$ Tomasz Lechowski -- Contributed some NTL and Pari polynomial +profiling code and researched algorithms for polynomials over finite fields. +(Funded by the Nuffield Foundation) + +$\bullet$ Daniel Scott -- Researched lazy and relaxed algorithms of Joris van +der Hoeven. (Funded by Warwick University's Undergraduate Research Scholars +Scheme) + +$\bullet$ David Howden -- Wrote code for computing Bernoulli numbers mod many +primes, including fast polynomial multiplication over $\Z/p\Z$ specifically for +the task. (Funded by Warwick University's Undergraduate Research Scholars +Scheme) + +$\bullet$ Daniel Ellam -- Helped design a module for $p$-adic arithmetic for +FLINT. (Funded by Warwick University's Undergraduate Research Scholars Scheme) + +$\bullet$ Richard Howell-Peak -- Wrote polynomial factorisation and +irreducibility testing code for polynomials over $\Z/p\Z$. (Funded by Warwick +University's Undergraduate Research Scholars Scheme) + +$\bullet$ Peter Shrimpton -- Wrote code for a basic prime sieve, +Pocklington-Lehmer, Lucas, Fibonacci, BSPW and $n-1$ primality tests and a +Weiferich prime search. (Funded by the Nuffield Foundation) + +$\bullet$ Patches and bug reports have been made by Michael Abshoff, +Didier Deshommes, Craig Citro, Timothy Abbot, Carl Witty, Gonzalo Tornaria, +Jaap Spies, Kiran Kedlaya, William Stein, Kate Minola, Didier Deshommes, Robert +Bradshaw, Serge Torres, Dan Grayson, Martin Lee, Bob Smith, Antony Vennard, +Fr\'{e}d\'{e}ric Chyzak, Julien Puydt, Dana Jacobsen, Michael Jacobson Jr., +Mike Stillman, Jan Englehardt, Jean-Pierre Flori, Jeroen Demeyer, Shi Bai, +Qingwen Guan, Frithjof Schulze, Robert Baillie, Oleksandr Motsak, Hans +Schoenemann, Janko Boehm, Ahmed Soliman, Francois Bissey and others. + +$\bullet$ In addition Michael Abshoff, William Stein and Robert Bradshaw have +contributed to the build system of FLINT. + +$\bullet$ Michael Abshoff deserves special recognition for his help in +resolving a number of difficult build issues which came to light as FLINT was +incorporated into SAGE and for bringing numerous bugs to the attention of the +FLINT maintainers. Michael regularly checked FLINT for memory leaks and +corruption, which directly led to numerous issues being identified early! +He also helped with setting up various pieces of infrastructure for the FLINT +project. + +$\bullet$ Numerous people have contributed to wrapping FLINT in Sage and +debugging, including Mike Hansen, Jean-Pierre Flori, Burcin Erocal, Robert +Bradshaw, Martin Albrecht, Sebastian Pancratz, Fredrik Johansson, Jeroen +Demeyer and Leif Lionhardy, amongst others. + +Some code (notably \code{longlong.h} and \code{clz_tab.c}) has been used from +the GMP library, whose main author is Torbjorn Granlund. + +FLINT 2 was a complete rewrite from scratch which began in about 2010. + diff --git a/external/flint-2.4.3/INSTALL b/external/flint-2.4.3/INSTALL new file mode 100644 index 0000000..8515b7c --- /dev/null +++ b/external/flint-2.4.3/INSTALL @@ -0,0 +1,26 @@ +Instructions on intalling flint 2 +--------------------------------- + +FLINT 2 follows a standard format for installation: + +./configure +make +make check +make install + +However, this assumes that MPIR and MPFR are already installed on your system in +/usr/local. If the libraries are not in this location you must specify where +they are by passing their location to configure. It also assumes you wish to +install FLINT 2 at the prefix /usr/local. If not you must pass the prefix (the +directory containing lib and include subdirectories into which FLINT will be +installed) to configure: + +./configure --with-mpir=/home/user1/mpir-2.1.1/ --with-mpfr=/usr --prefix=/usr + +Note that the FLINT configure system can handle MPIR/MPFR as installed (in lib +and include dirs) at some location, or as source builds (built from source and +not installed). + +For further configure and make options, please refer to the FLINT 2 +documentation. + diff --git a/external/flint-2.4.3/Makefile b/external/flint-2.4.3/Makefile new file mode 100644 index 0000000..6ceaf0c --- /dev/null +++ b/external/flint-2.4.3/Makefile @@ -0,0 +1,254 @@ +# This file is autogenerated by ./configure -- do not edit! + +SHELL=/bin/sh + +FLINT_STATIC=1 +FLINT_SHARED=0 +FLINT_LIB=libflint.so +EXEEXT= +PREFIX=/usr + +WANT_NTL=0 + +FLINT_CPIMPORT_DIR=/usr/share/flint +FLINT_CPIMPORT=/usr/share/flint/CPimport.txt + +INCS=-I$(CURDIR) -I/usr/include -I/usr/include +LIBS=-L$(CURDIR) -L/usr/lib -L/usr/lib -lflint -lpthread -lmpfr -lgmp -lm +LIBS2=-L$(CURDIR) -L/usr/lib -L/usr/lib -lpthread -lmpfr -lgmp -lm + +CC=gcc +CXX=g++ +AR=ar + +CFLAGS=-ansi -pedantic -Wall -O2 -funroll-loops -g -mpopcnt -DFLINT_CPIMPORT=\"/usr/share/flint/CPimport.txt\" +ABI_FLAG= +PIC_FLAG=-fPIC +EXTRA_SHARED_FLAGS= + +DLPATH=LD_LIBRARY_PATH +DLPATH_ADD=$(CURDIR):/usr/lib:/usr/lib +EXTENSIONS= +EXTRA_BUILD_DIRS= + +ifdef $(DLPATH) + $(DLPATH):=$($(DLPATH)):$(DLPATH_ADD) +else + $(DLPATH):=$(DLPATH_ADD) +endif + +QUIET_CC = @echo ' ' CC ' ' $@; +QUIET_CXX = @echo ' ' CXX ' ' $@; +QUIET_AR = @echo ' ' AR ' ' $@; + +AT=@ + +BUILD_DIRS = ulong_extras long_extras perm fmpz fmpz_vec fmpz_poly \ + fmpq_poly fmpz_mat mpfr_vec mpfr_mat nmod_vec nmod_poly \ + nmod_poly_factor arith mpn_extras nmod_mat fmpq fmpq_mat padic \ + fmpz_poly_q fmpz_poly_mat nmod_poly_mat fmpz_mod_poly \ + fmpz_mod_poly_factor fmpz_factor fmpz_poly_factor fft qsieve \ + double_extras padic_poly padic_mat qadic \ + fq fq_vec fq_mat fq_poly fq_poly_factor\ + fq_nmod fq_nmod_vec fq_nmod_mat fq_nmod_poly fq_nmod_poly_factor \ + fq_zech fq_zech_vec fq_zech_mat fq_zech_poly fq_zech_poly_factor \ + $(EXTRA_BUILD_DIRS) + +TEMPLATE_DIRS = fq_vec_templates fq_mat_templates fq_poly_templates \ + fq_poly_factor_templates + +export + +SOURCES = printf.c fprintf.c sprintf.c scanf.c fscanf.c sscanf.c clz_tab.c memory_manager.c version.c profiler.c thread_support.c +LIB_SOURCES = $(wildcard $(patsubst %, %/*.c, $(BUILD_DIRS))) $(patsubst %, %/*.c, $(TEMPLATE_DIRS)) + +HEADERS = $(patsubst %, %.h, $(BUILD_DIRS)) NTL-interface.h flint.h longlong.h config.h gmpcompat.h fft_tuning.h fmpz-conversions.h profiler.h templates.h $(patsubst %, %.h, $(TEMPLATE_DIRS)) + +OBJS = $(patsubst %.c, build/%.o, $(SOURCES)) +LIB_OBJS = $(patsubst %, build/%/*.o, $(BUILD_DIRS)) + +LOBJS = $(patsubst %.c, build/%.lo, $(SOURCES)) +LIB_LOBJS = $(patsubst %, build/%/*.lo, $(BUILD_DIRS)) +MOD_LOBJS = $(patsubst %, build/%.lo, $(BUILD_DIRS)) + +EXMP_SOURCES = $(wildcard examples/*.c) +EXMPS = $(patsubst %.c, %, $(EXMP_SOURCES)) + +TEST_SOURCES = $(wildcard test/*.c) +TESTS = $(patsubst %.c, build/%$(EXEEXT), $(TEST_SOURCES)) + +PROF_SOURCES = $(wildcard profile/*.c) +PROFS = $(patsubst %.c, %$(EXEEXT), $(PROF_SOURCES)) + +TUNE_SOURCES = $(wildcard tune/*.c) +TUNE = $(patsubst %.c, %$(EXEEXT), $(TUNE_SOURCES)) + +EXT_SOURCES = $(foreach ext, $(EXTENSIONS), $(foreach dir, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), $(wildcard $(ext)/$(dir)/*.c))) +EXT_TEST_SOURCES = $(foreach ext, $(EXTENSIONS), $(foreach dir, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), $(wildcard $(ext)/$(dir)/test/t-*.c))) +EXT_TUNE_SOURCES = $(foreach ext, $(EXTENSIONS), $(foreach dir, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), $(wildcard $(ext)/$(dir)/tune/*.c))) +EXT_PROF_SOURCES = $(foreach ext, $(EXTENSIONS), $(foreach dir, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), $(wildcard $(ext)/$(dir)/profile/p-*.c))) +EXT_OBJS = $(foreach ext, $(EXTENSIONS), $(foreach dir, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), build/$(dir).lo)) +EXT_HEADERS = $(foreach ext, $(EXTENSIONS), $(wildcard $(ext)/*.h)) + +all: library + +quiet: library + +verbose: + $(MAKE) AT= QUIET_CC= QUIET_CXX= QUIET_AR= + +clean: + $(AT)$(foreach dir, $(BUILD_DIRS), BUILD_DIR=../build/$(dir); export BUILD_DIR; MOD_DIR=$(dir); export MOD_DIR; $(MAKE) -f ../Makefile.subdirs -C $(dir) clean || exit $$?;) + $(AT)$(foreach ext, $(EXTENSIONS), $(foreach dir, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), BUILD_DIR=$(CURDIR)/build/$(dir); export BUILD_DIR; MOD_DIR=$(dir); export MOD_DIR; $(MAKE) -f $(CURDIR)/Makefile.subdirs -C $(ext)/$(dir) clean || exit $$?;)) + rm -rf test_helpers.o profiler.o + rm -f $(OBJS) $(LOBJS) $(TESTS) $(PROFS) $(EXMPS) $(FLINT_LIB) libflint.a + rm -rf build + +distclean: clean + rm -f config.h fft_tuning.h fmpz-conversions.h Makefile fmpz/fmpz.c + +dist: + git archive --format tar --prefix flint-2.4.2/ flint-2.4 > ../flint-2.4.2.tar; gzip ../flint-2.4.2.tar + +profile: library $(PROF_SOURCES) $(EXT_PROF_SOURCES) build/profiler.o + mkdir -p build/profile +ifndef MOD + $(AT)$(foreach prog, $(PROFS), $(CC) $(ABI_FLAG) -std=c99 -O2 -g $(INCS) $(prog).c build/profiler.o -o build/$(prog) $(LIBS) || exit $$?;) + $(AT)$(foreach dir, $(BUILD_DIRS), mkdir -p build/$(dir)/profile; BUILD_DIR=../build/$(dir); export BUILD_DIR; $(MAKE) -f ../Makefile.subdirs -C $(dir) profile || exit $$?;) + $(AT)$(foreach ext, $(EXTENSIONS), $(foreach dir, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), mkdir -p build/$(dir)/profile; BUILD_DIR=$(CURDIR)/build/$(dir); export BUILD_DIR; MOD_DIR=$(dir); export MOD_DIR; $(MAKE) -f $(CURDIR)/Makefile.subdirs -C $(ext)/$(dir) profile || exit $$?;)) +else + $(AT)$(foreach dir, $(MOD), mkdir -p build/$(dir)/profile; BUILD_DIR=../build/$(dir); export BUILD_DIR; $(MAKE) -f ../Makefile.subdirs -C $(dir) profile || exit $$?;) +endif + +tune: library $(TUNE_SOURCES) $(EXT_TUNE_SOURCES) + mkdir -p build/tune + $(AT)$(foreach prog, $(TUNE), $(CC) $(CFLAGS) $(INCS) $(prog).c -o build/$(prog) $(LIBS) || exit $$?;) + $(AT)$(foreach dir, $(BUILD_DIRS), mkdir -p build/$(dir)/tune; BUILD_DIR=../build/$(dir); export BUILD_DIR; $(MAKE) -f ../Makefile.subdirs -C $(dir) tune || exit $$?;) + $(AT)$(foreach ext, $(EXTENSIONS), $(foreach dir, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), mkdir -p build/$(dir)/tune; BUILD_DIR=$(CURDIR)/build/$(dir); export BUILD_DIR; MOD_DIR=$(dir); export MOD_DIR; $(MAKE) -f $(CURDIR)/Makefile.subdirs -C $(ext)/$(dir) tune || exit $$?;)) + +examples: library $(EXMP_SOURCES) + mkdir -p build/examples + $(AT)$(foreach prog, $(EXMPS), $(CC) $(CFLAGS) $(INCS) $(prog).c -o build/$(prog) $(LIBS) || exit $$?;) + +$(FLINT_LIB): $(LOBJS) $(LIB_SOURCES) $(EXT_SOURCES) $(HEADERS) $(EXT_HEADERS) | build build/interfaces + $(AT)$(foreach ext, $(EXTENSIONS), $(foreach dir, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), mkdir -p build/$(dir); BUILD_DIR=$(CURDIR)/build/$(dir); export BUILD_DIR; MOD_DIR=$(dir); export MOD_DIR; $(MAKE) -f $(CURDIR)/Makefile.subdirs -C $(ext)/$(dir) shared || exit $$?;)) + $(AT)$(foreach dir, $(BUILD_DIRS), mkdir -p build/$(dir); BUILD_DIR=../build/$(dir); export BUILD_DIR; MOD_DIR=$(dir); export MOD_DIR; $(MAKE) -f ../Makefile.subdirs -C $(dir) shared || exit $$?;) + $(AT)if [ "$(WANT_NTL)" -eq "1" ]; then \ + $(MAKE) build/interfaces/NTL-interface.lo; \ + $(CXX) $(ABI_FLAG) -shared $(EXTRA_SHARED_FLAGS) build/interfaces/NTL-interface.lo $(LOBJS) $(MOD_LOBJS) $(EXT_OBJS) $(LIBS2) -o $(FLINT_LIB); \ + fi + $(AT)if [ "$(WANT_NTL)" -ne "1" ]; then \ + $(CC) $(ABI_FLAG) -shared $(EXTRA_SHARED_FLAGS) $(LOBJS) $(MOD_LOBJS) $(EXT_OBJS) $(LIBS2) -o $(FLINT_LIB); \ + fi + +libflint.a: $(OBJS) $(LIB_SOURCES) $(EXT_SOURCES) $(HEADERS) $(EXT_HEADERS) | build build/interfaces + $(AT)$(foreach ext, $(EXTENSIONS), $(foreach dir, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), mkdir -p build/$(dir); BUILD_DIR=$(CURDIR)/build/$(dir); export BUILD_DIR; MOD_DIR=$(dir); export MOD_DIR; $(MAKE) -f $(CURDIR)/Makefile.subdirs -C $(ext)/$(dir) static || exit $$?;)) + $(AT)$(foreach dir, $(BUILD_DIRS), mkdir -p build/$(dir); BUILD_DIR=../build/$(dir); export BUILD_DIR; MOD_DIR=$(dir); export MOD_DIR; $(MAKE) -f ../Makefile.subdirs -C $(dir) static || exit $$?;) + $(AT)if [ "$(FLINT_SHARED)" -eq "0" ]; then \ + touch test/t-*.c; \ + $(foreach dir, $(BUILD_DIRS), touch $(dir)/test/t-*.c;) \ + $(foreach ext, $(EXTENSIONS), $(foreach mod, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), touch $(ext)/$(mod)/test/t-*.c;)) \ + fi + $(AT)if [ "$(WANT_NTL)" -eq "1" ]; then \ + $(MAKE) build/interfaces/NTL-interface.o; \ + $(AR) rcs libflint.a build/interfaces/NTL-interface.o; \ + fi + $(QUIET_AR) $(AR) rcs libflint.a $(OBJS); + $(AT)$(foreach mod, $(BUILD_DIRS), $(AR) rcs libflint.a build/$(mod)/*.o || exit $$?;) + $(AT)$(foreach ext, $(EXTENSIONS), $(foreach mod, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), $(AR) rcs libflint.a build/$(mod)/*.o || exit $$?;)) + +library: + $(AT)if [ "$(FLINT_SHARED)" -eq "1" ]; then \ + $(MAKE) shared; \ + fi + $(AT)if [ "$(FLINT_STATIC)" -eq "1" ]; then \ + $(MAKE) static; \ + fi + +shared: $(FLINT_LIB) + +static: libflint.a + +tests: library test_helpers.o $(TESTS) + $(AT)$(foreach dir, $(BUILD_DIRS), mkdir -p build/$(dir)/test; BUILD_DIR=../build/$(dir); export BUILD_DIR; $(MAKE) -f ../Makefile.subdirs -C $(dir) tests || exit $$?;) + $(AT)$(foreach ext, $(EXTENSIONS), $(foreach dir, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), mkdir -p build/$(dir)/test; BUILD_DIR=$(CURDIR)/build/$(dir); export BUILD_DIR; MOD_DIR=$(dir); export MOD_DIR; $(MAKE) -f $(CURDIR)/Makefile.subdirs -C $(ext)/$(dir) tests || exit $$?;)) + mkdir -p build/interfaces/test + $(AT)if [ "$(WANT_NTL)" -eq "1" ]; then \ + $(MAKE) build/interfaces/test/t-NTL-interface; \ + fi + +check: library test_helpers.o +ifndef MOD + $(AT)$(MAKE) $(TESTS) + $(AT)$(foreach prog, $(TESTS), $(prog) || exit $$?;) + $(AT)$(foreach ext, $(EXTENSIONS), $(foreach dir, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), mkdir -p build/$(dir)/test; BUILD_DIR=$(CURDIR)/build/$(dir); export BUILD_DIR; MOD_DIR=$(dir); export MOD_DIR; $(MAKE) -f $(CURDIR)/Makefile.subdirs -C $(ext)/$(dir) check || exit $$?;)) + $(AT)$(foreach dir, $(BUILD_DIRS), mkdir -p build/$(dir)/test; BUILD_DIR=../build/$(dir); export BUILD_DIR; $(MAKE) -f ../Makefile.subdirs -C $(dir) check || exit $$?;) + mkdir -p build/interfaces/test + $(AT)if [ "$(WANT_NTL)" -eq "1" ]; then \ + $(MAKE) build/interfaces/test/t-NTL-interface; \ + build/interfaces/test/t-NTL-interface; \ + fi +else + $(AT)$(foreach dir, $(MOD), test ! -d $(dir) || mkdir -p build/$(dir)/test; BUILD_DIR=../build/$(dir); export BUILD_DIR; test ! -d $(dir) || $(MAKE) -f ../Makefile.subdirs -C $(dir) check || exit $$?;) + $(AT)$(foreach ext, $(EXTENSIONS), $(AT)$(foreach dir, $(MOD), MOD_DIR=$(dir); export MOD_DIR; test ! -d $(ext)/$(dir) || mkdir -p build/$(dir)/test; BUILD_DIR=$(CURDIR)/build/$(dir); export BUILD_DIR; test ! -d $(ext)/$(dir) || $(MAKE) -f $(CURDIR)/Makefile.subdirs -C $(ext)/$(dir) check || exit $$?;)) +endif + +valgrind: library +ifndef MOD + $(AT)$(foreach dir, $(BUILD_DIRS), mkdir -p build/$(dir)/test; BUILD_DIR=../build/$(dir); export BUILD_DIR; $(MAKE) -f ../Makefile.subdirs -C $(dir) valgrind || exit $$?;) + $(AT)$(foreach ext, $(EXTENSIONS), $(foreach dir, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), mkdir -p build/$(dir)/test; BUILD_DIR=$(CURDIR)/build/$(dir); export BUILD_DIR; MOD_DIR=$(dir); export MOD_DIR; $(MAKE) -f $(CURDIR)/Makefile.subdirs -C $(ext)/$(dir) valgrind || exit $$?;)) +else + $(AT)$(foreach dir, $(MOD), mkdir -p build/$(dir)/test; BUILD_DIR=../build/$(dir); export BUILD_DIR; $(MAKE) -f ../Makefile.subdirs -C $(dir) valgrind || exit $$?;) +endif + +install: library + mkdir -p $(DESTDIR)$(PREFIX)/lib + mkdir -p $(DESTDIR)$(PREFIX)/include/flint + $(AT)if [ "$(FLINT_SHARED)" -eq "1" ]; then \ + cp $(FLINT_LIB) $(DESTDIR)$(PREFIX)/lib; \ + fi + $(AT)if [ "$(FLINT_STATIC)" -eq "1" ]; then \ + cp libflint.a $(DESTDIR)$(PREFIX)/lib; \ + fi + cp $(HEADERS) $(DESTDIR)$(PREFIX)/include/flint + $(AT)if [ ! -z $(EXT_HEADERS) ]; then \ + cp $(EXT_HEADERS) $(DESTDIR)$(PREFIX)/include/flint; \ + fi + mkdir -p $(DESTDIR)$(FLINT_CPIMPORT_DIR) + cp qadic/CPimport.txt $(DESTDIR)$(FLINT_CPIMPORT_DIR) + mkdir -p $(DESTDIR)$(PREFIX)/include/flint/flintxx + cp flintxx/*.h $(DESTDIR)$(PREFIX)/include/flint/flintxx + cp *xx.h $(DESTDIR)$(PREFIX)/include/flint + +build: + mkdir -p build + +build/%.lo: %.c $(HEADERS) | build + $(QUIET_CC) $(CC) $(PIC_FLAG) $(CFLAGS) $(INCS) -c $< -o $@; + +build/%.o: %.c $(HEADERS) | build + $(QUIET_CC) $(CC) $(CFLAGS) $(INCS) -c $< -o $@; + +build/test/%$(EXEEXT): test/%.c $(HEADERS) | build/test + $(QUIET_CC) $(CC) $(CFLAGS) $(INCS) $< -o $@ $(LIBS) + +build/test: + mkdir -p build/test + +build/interfaces: + mkdir -p build/interfaces + +build/interfaces/NTL-interface.lo: interfaces/NTL-interface.cpp NTL-interface.h + $(QUIET_CXX) $(CXX) $(PIC_FLAG) $(CFLAGS) $(INCS) -c $< -o $@; + +build/interfaces/NTL-interface.o: interfaces/NTL-interface.cpp NTL-interface.h + $(QUIET_CXX) $(CXX) $(CFLAGS) $(INCS) -c $< -o $@; + +build/interfaces/test/t-NTL-interface$(EXEEXT): interfaces/test/t-NTL-interface.cpp + $(QUIET_CXX) $(CXX) $(CFLAGS) $(INCS) $< build/interfaces/NTL-interface.o -o $@ $(LIBS); + +print-%: + @echo '$*=$($*)' + +.PHONY: profile library shared static clean examples tune check tests distclean dist install all valgrind + diff --git a/external/flint-2.4.3/Makefile.in b/external/flint-2.4.3/Makefile.in new file mode 100644 index 0000000..25e2246 --- /dev/null +++ b/external/flint-2.4.3/Makefile.in @@ -0,0 +1,221 @@ +ifdef $(DLPATH) + $(DLPATH):=$($(DLPATH)):$(DLPATH_ADD) +else + $(DLPATH):=$(DLPATH_ADD) +endif + +QUIET_CC = @echo ' ' CC ' ' $@; +QUIET_CXX = @echo ' ' CXX ' ' $@; +QUIET_AR = @echo ' ' AR ' ' $@; + +AT=@ + +BUILD_DIRS = ulong_extras long_extras perm fmpz fmpz_vec fmpz_poly \ + fmpq_poly fmpz_mat mpfr_vec mpfr_mat nmod_vec nmod_poly \ + nmod_poly_factor arith mpn_extras nmod_mat fmpq fmpq_mat padic \ + fmpz_poly_q fmpz_poly_mat nmod_poly_mat fmpz_mod_poly \ + fmpz_mod_poly_factor fmpz_factor fmpz_poly_factor fft qsieve \ + double_extras padic_poly padic_mat qadic \ + fq fq_vec fq_mat fq_poly fq_poly_factor\ + fq_nmod fq_nmod_vec fq_nmod_mat fq_nmod_poly fq_nmod_poly_factor \ + fq_zech fq_zech_vec fq_zech_mat fq_zech_poly fq_zech_poly_factor \ + $(EXTRA_BUILD_DIRS) + +TEMPLATE_DIRS = fq_vec_templates fq_mat_templates fq_poly_templates \ + fq_poly_factor_templates + +export + +SOURCES = printf.c fprintf.c sprintf.c scanf.c fscanf.c sscanf.c clz_tab.c memory_manager.c version.c profiler.c thread_support.c +LIB_SOURCES = $(wildcard $(patsubst %, %/*.c, $(BUILD_DIRS))) $(patsubst %, %/*.c, $(TEMPLATE_DIRS)) + +HEADERS = $(patsubst %, %.h, $(BUILD_DIRS)) NTL-interface.h flint.h longlong.h config.h gmpcompat.h fft_tuning.h fmpz-conversions.h profiler.h templates.h $(patsubst %, %.h, $(TEMPLATE_DIRS)) + +OBJS = $(patsubst %.c, build/%.o, $(SOURCES)) +LIB_OBJS = $(patsubst %, build/%/*.o, $(BUILD_DIRS)) + +LOBJS = $(patsubst %.c, build/%.lo, $(SOURCES)) +LIB_LOBJS = $(patsubst %, build/%/*.lo, $(BUILD_DIRS)) +MOD_LOBJS = $(patsubst %, build/%.lo, $(BUILD_DIRS)) + +EXMP_SOURCES = $(wildcard examples/*.c) +EXMPS = $(patsubst %.c, %, $(EXMP_SOURCES)) + +TEST_SOURCES = $(wildcard test/*.c) +TESTS = $(patsubst %.c, build/%$(EXEEXT), $(TEST_SOURCES)) + +PROF_SOURCES = $(wildcard profile/*.c) +PROFS = $(patsubst %.c, %$(EXEEXT), $(PROF_SOURCES)) + +TUNE_SOURCES = $(wildcard tune/*.c) +TUNE = $(patsubst %.c, %$(EXEEXT), $(TUNE_SOURCES)) + +EXT_SOURCES = $(foreach ext, $(EXTENSIONS), $(foreach dir, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), $(wildcard $(ext)/$(dir)/*.c))) +EXT_TEST_SOURCES = $(foreach ext, $(EXTENSIONS), $(foreach dir, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), $(wildcard $(ext)/$(dir)/test/t-*.c))) +EXT_TUNE_SOURCES = $(foreach ext, $(EXTENSIONS), $(foreach dir, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), $(wildcard $(ext)/$(dir)/tune/*.c))) +EXT_PROF_SOURCES = $(foreach ext, $(EXTENSIONS), $(foreach dir, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), $(wildcard $(ext)/$(dir)/profile/p-*.c))) +EXT_OBJS = $(foreach ext, $(EXTENSIONS), $(foreach dir, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), build/$(dir).lo)) +EXT_HEADERS = $(foreach ext, $(EXTENSIONS), $(wildcard $(ext)/*.h)) + +all: library + +quiet: library + +verbose: + $(MAKE) AT= QUIET_CC= QUIET_CXX= QUIET_AR= + +clean: + $(AT)$(foreach dir, $(BUILD_DIRS), BUILD_DIR=../build/$(dir); export BUILD_DIR; MOD_DIR=$(dir); export MOD_DIR; $(MAKE) -f ../Makefile.subdirs -C $(dir) clean || exit $$?;) + $(AT)$(foreach ext, $(EXTENSIONS), $(foreach dir, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), BUILD_DIR=$(CURDIR)/build/$(dir); export BUILD_DIR; MOD_DIR=$(dir); export MOD_DIR; $(MAKE) -f $(CURDIR)/Makefile.subdirs -C $(ext)/$(dir) clean || exit $$?;)) + rm -rf test_helpers.o profiler.o + rm -f $(OBJS) $(LOBJS) $(TESTS) $(PROFS) $(EXMPS) $(FLINT_LIB) libflint.a + rm -rf build + +distclean: clean + rm -f config.h fft_tuning.h fmpz-conversions.h Makefile fmpz/fmpz.c + +dist: + git archive --format tar --prefix flint-2.4.2/ flint-2.4 > ../flint-2.4.2.tar; gzip ../flint-2.4.2.tar + +profile: library $(PROF_SOURCES) $(EXT_PROF_SOURCES) build/profiler.o + mkdir -p build/profile +ifndef MOD + $(AT)$(foreach prog, $(PROFS), $(CC) $(ABI_FLAG) -std=c99 -O2 -g $(INCS) $(prog).c build/profiler.o -o build/$(prog) $(LIBS) || exit $$?;) + $(AT)$(foreach dir, $(BUILD_DIRS), mkdir -p build/$(dir)/profile; BUILD_DIR=../build/$(dir); export BUILD_DIR; $(MAKE) -f ../Makefile.subdirs -C $(dir) profile || exit $$?;) + $(AT)$(foreach ext, $(EXTENSIONS), $(foreach dir, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), mkdir -p build/$(dir)/profile; BUILD_DIR=$(CURDIR)/build/$(dir); export BUILD_DIR; MOD_DIR=$(dir); export MOD_DIR; $(MAKE) -f $(CURDIR)/Makefile.subdirs -C $(ext)/$(dir) profile || exit $$?;)) +else + $(AT)$(foreach dir, $(MOD), mkdir -p build/$(dir)/profile; BUILD_DIR=../build/$(dir); export BUILD_DIR; $(MAKE) -f ../Makefile.subdirs -C $(dir) profile || exit $$?;) +endif + +tune: library $(TUNE_SOURCES) $(EXT_TUNE_SOURCES) + mkdir -p build/tune + $(AT)$(foreach prog, $(TUNE), $(CC) $(CFLAGS) $(INCS) $(prog).c -o build/$(prog) $(LIBS) || exit $$?;) + $(AT)$(foreach dir, $(BUILD_DIRS), mkdir -p build/$(dir)/tune; BUILD_DIR=../build/$(dir); export BUILD_DIR; $(MAKE) -f ../Makefile.subdirs -C $(dir) tune || exit $$?;) + $(AT)$(foreach ext, $(EXTENSIONS), $(foreach dir, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), mkdir -p build/$(dir)/tune; BUILD_DIR=$(CURDIR)/build/$(dir); export BUILD_DIR; MOD_DIR=$(dir); export MOD_DIR; $(MAKE) -f $(CURDIR)/Makefile.subdirs -C $(ext)/$(dir) tune || exit $$?;)) + +examples: library $(EXMP_SOURCES) + mkdir -p build/examples + $(AT)$(foreach prog, $(EXMPS), $(CC) $(CFLAGS) $(INCS) $(prog).c -o build/$(prog) $(LIBS) || exit $$?;) + +$(FLINT_LIB): $(LOBJS) $(LIB_SOURCES) $(EXT_SOURCES) $(HEADERS) $(EXT_HEADERS) | build build/interfaces + $(AT)$(foreach ext, $(EXTENSIONS), $(foreach dir, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), mkdir -p build/$(dir); BUILD_DIR=$(CURDIR)/build/$(dir); export BUILD_DIR; MOD_DIR=$(dir); export MOD_DIR; $(MAKE) -f $(CURDIR)/Makefile.subdirs -C $(ext)/$(dir) shared || exit $$?;)) + $(AT)$(foreach dir, $(BUILD_DIRS), mkdir -p build/$(dir); BUILD_DIR=../build/$(dir); export BUILD_DIR; MOD_DIR=$(dir); export MOD_DIR; $(MAKE) -f ../Makefile.subdirs -C $(dir) shared || exit $$?;) + $(AT)if [ "$(WANT_NTL)" -eq "1" ]; then \ + $(MAKE) build/interfaces/NTL-interface.lo; \ + $(CXX) $(ABI_FLAG) -shared $(EXTRA_SHARED_FLAGS) build/interfaces/NTL-interface.lo $(LOBJS) $(MOD_LOBJS) $(EXT_OBJS) $(LIBS2) -o $(FLINT_LIB); \ + fi + $(AT)if [ "$(WANT_NTL)" -ne "1" ]; then \ + $(CC) $(ABI_FLAG) -shared $(EXTRA_SHARED_FLAGS) $(LOBJS) $(MOD_LOBJS) $(EXT_OBJS) $(LIBS2) -o $(FLINT_LIB); \ + fi + +libflint.a: $(OBJS) $(LIB_SOURCES) $(EXT_SOURCES) $(HEADERS) $(EXT_HEADERS) | build build/interfaces + $(AT)$(foreach ext, $(EXTENSIONS), $(foreach dir, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), mkdir -p build/$(dir); BUILD_DIR=$(CURDIR)/build/$(dir); export BUILD_DIR; MOD_DIR=$(dir); export MOD_DIR; $(MAKE) -f $(CURDIR)/Makefile.subdirs -C $(ext)/$(dir) static || exit $$?;)) + $(AT)$(foreach dir, $(BUILD_DIRS), mkdir -p build/$(dir); BUILD_DIR=../build/$(dir); export BUILD_DIR; MOD_DIR=$(dir); export MOD_DIR; $(MAKE) -f ../Makefile.subdirs -C $(dir) static || exit $$?;) + $(AT)if [ "$(FLINT_SHARED)" -eq "0" ]; then \ + touch test/t-*.c; \ + $(foreach dir, $(BUILD_DIRS), touch $(dir)/test/t-*.c;) \ + $(foreach ext, $(EXTENSIONS), $(foreach mod, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), touch $(ext)/$(mod)/test/t-*.c;)) \ + fi + $(AT)if [ "$(WANT_NTL)" -eq "1" ]; then \ + $(MAKE) build/interfaces/NTL-interface.o; \ + $(AR) rcs libflint.a build/interfaces/NTL-interface.o; \ + fi + $(QUIET_AR) $(AR) rcs libflint.a $(OBJS); + $(AT)$(foreach mod, $(BUILD_DIRS), $(AR) rcs libflint.a build/$(mod)/*.o || exit $$?;) + $(AT)$(foreach ext, $(EXTENSIONS), $(foreach mod, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), $(AR) rcs libflint.a build/$(mod)/*.o || exit $$?;)) + +library: + $(AT)if [ "$(FLINT_SHARED)" -eq "1" ]; then \ + $(MAKE) shared; \ + fi + $(AT)if [ "$(FLINT_STATIC)" -eq "1" ]; then \ + $(MAKE) static; \ + fi + +shared: $(FLINT_LIB) + +static: libflint.a + +tests: library test_helpers.o $(TESTS) + $(AT)$(foreach dir, $(BUILD_DIRS), mkdir -p build/$(dir)/test; BUILD_DIR=../build/$(dir); export BUILD_DIR; $(MAKE) -f ../Makefile.subdirs -C $(dir) tests || exit $$?;) + $(AT)$(foreach ext, $(EXTENSIONS), $(foreach dir, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), mkdir -p build/$(dir)/test; BUILD_DIR=$(CURDIR)/build/$(dir); export BUILD_DIR; MOD_DIR=$(dir); export MOD_DIR; $(MAKE) -f $(CURDIR)/Makefile.subdirs -C $(ext)/$(dir) tests || exit $$?;)) + mkdir -p build/interfaces/test + $(AT)if [ "$(WANT_NTL)" -eq "1" ]; then \ + $(MAKE) build/interfaces/test/t-NTL-interface; \ + fi + +check: library test_helpers.o +ifndef MOD + $(AT)$(MAKE) $(TESTS) + $(AT)$(foreach prog, $(TESTS), $(prog) || exit $$?;) + $(AT)$(foreach ext, $(EXTENSIONS), $(foreach dir, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), mkdir -p build/$(dir)/test; BUILD_DIR=$(CURDIR)/build/$(dir); export BUILD_DIR; MOD_DIR=$(dir); export MOD_DIR; $(MAKE) -f $(CURDIR)/Makefile.subdirs -C $(ext)/$(dir) check || exit $$?;)) + $(AT)$(foreach dir, $(BUILD_DIRS), mkdir -p build/$(dir)/test; BUILD_DIR=../build/$(dir); export BUILD_DIR; $(MAKE) -f ../Makefile.subdirs -C $(dir) check || exit $$?;) + mkdir -p build/interfaces/test + $(AT)if [ "$(WANT_NTL)" -eq "1" ]; then \ + $(MAKE) build/interfaces/test/t-NTL-interface; \ + build/interfaces/test/t-NTL-interface; \ + fi +else + $(AT)$(foreach dir, $(MOD), test ! -d $(dir) || mkdir -p build/$(dir)/test; BUILD_DIR=../build/$(dir); export BUILD_DIR; test ! -d $(dir) || $(MAKE) -f ../Makefile.subdirs -C $(dir) check || exit $$?;) + $(AT)$(foreach ext, $(EXTENSIONS), $(AT)$(foreach dir, $(MOD), MOD_DIR=$(dir); export MOD_DIR; test ! -d $(ext)/$(dir) || mkdir -p build/$(dir)/test; BUILD_DIR=$(CURDIR)/build/$(dir); export BUILD_DIR; test ! -d $(ext)/$(dir) || $(MAKE) -f $(CURDIR)/Makefile.subdirs -C $(ext)/$(dir) check || exit $$?;)) +endif + +valgrind: library +ifndef MOD + $(AT)$(foreach dir, $(BUILD_DIRS), mkdir -p build/$(dir)/test; BUILD_DIR=../build/$(dir); export BUILD_DIR; $(MAKE) -f ../Makefile.subdirs -C $(dir) valgrind || exit $$?;) + $(AT)$(foreach ext, $(EXTENSIONS), $(foreach dir, $(patsubst $(ext)/%.h, %, $(wildcard $(ext)/*.h)), mkdir -p build/$(dir)/test; BUILD_DIR=$(CURDIR)/build/$(dir); export BUILD_DIR; MOD_DIR=$(dir); export MOD_DIR; $(MAKE) -f $(CURDIR)/Makefile.subdirs -C $(ext)/$(dir) valgrind || exit $$?;)) +else + $(AT)$(foreach dir, $(MOD), mkdir -p build/$(dir)/test; BUILD_DIR=../build/$(dir); export BUILD_DIR; $(MAKE) -f ../Makefile.subdirs -C $(dir) valgrind || exit $$?;) +endif + +install: library + mkdir -p $(DESTDIR)$(PREFIX)/lib + mkdir -p $(DESTDIR)$(PREFIX)/include/flint + $(AT)if [ "$(FLINT_SHARED)" -eq "1" ]; then \ + cp $(FLINT_LIB) $(DESTDIR)$(PREFIX)/lib; \ + fi + $(AT)if [ "$(FLINT_STATIC)" -eq "1" ]; then \ + cp libflint.a $(DESTDIR)$(PREFIX)/lib; \ + fi + cp $(HEADERS) $(DESTDIR)$(PREFIX)/include/flint + $(AT)if [ ! -z $(EXT_HEADERS) ]; then \ + cp $(EXT_HEADERS) $(DESTDIR)$(PREFIX)/include/flint; \ + fi + mkdir -p $(DESTDIR)$(FLINT_CPIMPORT_DIR) + cp qadic/CPimport.txt $(DESTDIR)$(FLINT_CPIMPORT_DIR) + mkdir -p $(DESTDIR)$(PREFIX)/include/flint/flintxx + cp flintxx/*.h $(DESTDIR)$(PREFIX)/include/flint/flintxx + cp *xx.h $(DESTDIR)$(PREFIX)/include/flint + +build: + mkdir -p build + +build/%.lo: %.c $(HEADERS) | build + $(QUIET_CC) $(CC) $(PIC_FLAG) $(CFLAGS) $(INCS) -c $< -o $@; + +build/%.o: %.c $(HEADERS) | build + $(QUIET_CC) $(CC) $(CFLAGS) $(INCS) -c $< -o $@; + +build/test/%$(EXEEXT): test/%.c $(HEADERS) | build/test + $(QUIET_CC) $(CC) $(CFLAGS) $(INCS) $< -o $@ $(LIBS) + +build/test: + mkdir -p build/test + +build/interfaces: + mkdir -p build/interfaces + +build/interfaces/NTL-interface.lo: interfaces/NTL-interface.cpp NTL-interface.h + $(QUIET_CXX) $(CXX) $(PIC_FLAG) $(CFLAGS) $(INCS) -c $< -o $@; + +build/interfaces/NTL-interface.o: interfaces/NTL-interface.cpp NTL-interface.h + $(QUIET_CXX) $(CXX) $(CFLAGS) $(INCS) -c $< -o $@; + +build/interfaces/test/t-NTL-interface$(EXEEXT): interfaces/test/t-NTL-interface.cpp + $(QUIET_CXX) $(CXX) $(CFLAGS) $(INCS) $< build/interfaces/NTL-interface.o -o $@ $(LIBS); + +print-%: + @echo '$*=$($*)' + +.PHONY: profile library shared static clean examples tune check tests distclean dist install all valgrind + diff --git a/external/flint-2.4.3/Makefile.subdirs b/external/flint-2.4.3/Makefile.subdirs new file mode 100644 index 0000000..6aa91ef --- /dev/null +++ b/external/flint-2.4.3/Makefile.subdirs @@ -0,0 +1,89 @@ +QUIET_CC = @echo ' ' CC ' ' $@; + +AT=@ + +SOURCES = $(wildcard *.c) + +HEADERS = $(wildcard ../*.h) +TEST_HEADERS = $(wildcard *.h) + +OBJS = $(patsubst %.c, $(BUILD_DIR)/$(MOD_DIR)_%.o, $(SOURCES)) + +LOBJS = $(patsubst %.c, $(BUILD_DIR)/%.lo, $(SOURCES)) +MOD_LOBJ = $(BUILD_DIR)/../$(MOD_DIR).lo + +TEST_SOURCES = $(wildcard test/*.c) +TESTXX_SOURCES = $(wildcard test/*.cpp) + +PROF_SOURCES = $(wildcard profile/*.c) + +TUNE_SOURCES = $(wildcard tune/*.c) + +TESTS = $(patsubst %.c, $(BUILD_DIR)/%$(EXEEXT), $(TEST_SOURCES)) \ + $(patsubst %.cpp, $(BUILD_DIR)/%$(EXEEXT), $(TESTXX_SOURCES)) + +TESTS_RUN = $(patsubst %, %_RUN, $(TESTS)) + +VALGRIND_RUN = $(patsubst %, %_VALGRIND_RUN, $(TESTS)) + +PROFS = $(patsubst %.c, $(BUILD_DIR)/%$(EXEEXT), $(PROF_SOURCES)) + +TUNE = $(patsubst %.c, %$(EXEEXT), $(TUNE_SOURCES)) + +all: shared static + +shared: $(MOD_LOBJ) + +static: $(OBJS) + +profile: $(PROFS) + +-include $(patsubst %, %.d, $(PROFS)) + +$(BUILD_DIR)/profile/%$(EXEEXT): profile/%.c $(BUILD_DIR)/../profiler.o + $(QUIET_CC) $(CC) $(ABI_FLAG) -O2 -std=c99 -g $(INCS) $< ../build/profiler.o -o $@ $(LIBS) -MMD -MP -MF $@.d -MT "$@" -MT "$@.d" + +tune: $(TUNE_SOURCES) $(HEADERS) + $(AT)$(foreach prog, $(TUNE), $(CC) $(CFLAGS) $(INCS) $(prog).c -o $(BUILD_DIR)/$(prog) $(LIBS) || exit $$?;) + +-include $(OBJS:.o=.d) + +$(BUILD_DIR)/$(MOD_DIR)_%.o: %.c + $(QUIET_CC) $(CC) $(CFLAGS) $(INCS) -c $< -o $@ -MMD -MP -MF "$(BUILD_DIR)/$(MOD_DIR)_$*.d" -MT "$(BUILD_DIR)/$(MOD_DIR)_$*.d" -MT "$@" + +$(MOD_LOBJ): $(LOBJS) + $(QUIET_CC) $(CC) $(ABI_FLAG) -Wl,-r $^ -o $@ -nostdlib + +-include $(LOBJS:.lo=.d) + +$(BUILD_DIR)/%.lo: %.c + $(QUIET_CC) $(CC) $(PIC_FLAG) $(CFLAGS) $(INCS) -c $< -o $@ -MMD -MP -MF "$(BUILD_DIR)/$*.d" -MT "$(BUILD_DIR)/$*.d" -MT "$@" + +clean: + rm -rf $(BUILD_DIR) $(MOD_LOBJ) + +tests: $(TESTS) + +check: tests $(TESTS_RUN) + +valgrind: tests $(VALGRIND_RUN) + +-include $(patsubst %, %.d, $(TESTS)) + +ifeq ($(FLINT_SHARED), 0) +$(BUILD_DIR)/test/%$(EXEEXT): $(BUILD_DIR)/../../libflint.a +endif + +$(BUILD_DIR)/test/%$(EXEEXT): test/%.c $(BUILD_DIR)/../../test_helpers.o + $(QUIET_CC) $(CC) $(CFLAGS) $(INCS) $< $(BUILD_DIR)/../../test_helpers.o -o $@ $(LIBS) -MMD -MP -MF $@.d -MT "$@" -MT "$@.d" + +$(BUILD_DIR)/test/%$(EXEEXT): test/%.cpp $(BUILD_DIR)/../../test_helpers.o + $(QUIET_CC) $(CXX) $(CFLAGS) $(INCS) $< $(BUILD_DIR)/../../test_helpers.o -o $@ $(LIBS) -MMD -MP -MF $@.d -MT "$@" -MT "$@.d" + +%_RUN: % + @$< + +%_VALGRIND_RUN: % + valgrind --track-origins=yes --leak-check=full --show-reachable=yes --log-file="$*.valgrind" $< + +.PHONY: profile tune clean check tests all shared static valgrind %_RUN %_VALGRIND_RUN diff --git a/external/flint-2.4.3/NEWS b/external/flint-2.4.3/NEWS new file mode 100644 index 0000000..0ae5a24 --- /dev/null +++ b/external/flint-2.4.3/NEWS @@ -0,0 +1,1102 @@ +v 1.0 -- 2-Dec-07 : + + * First version of FLINT, includes fmpz_poly, fmpz and mpQS + +v 1.0.1 -- 7-Dec-07 : + + * Fixed a bug in _fmpz_poly_maxbits1 on 32 bit machines, reported by Michael Abshoff and Carl Witty + * Removed some instances of u_int64_t and replaced them with uint64_t, reported by Michael Abshoff + * Replaced sys/types.h with stdint.h + * Added FLINT macros to documentation + * Corrected numerous typos in documentation + +v 1.0.2 -- 10-Dec-07 + + * Rewrote tuning code for integer multiplication functions, making it more robust and fixing a bug + which showed up on 32 bit machines (reported by Michael Abshoff and Jaap Spies). Factored the tuning + code out into a number of macros. + +v 1.0.3 -- 16-Dec-07 + + * Fixed a bug in the polynomial memory managment code which caused a segfault + * Fixed a bug in the pseudo division code which caused a block overrun + +v 1.0.4 -- 04-Jan-08 + + * Fixed a bug in the bernoulli_zmod example program and associated polynomial zmod code which caused memory corruption. + * Fixed a bug in the fmpz-test code which manifested on 32 bit machines, reported by David Harvey. + * Fixed some bugs in the pari profiling code. + +v 1.0.5 -- 05-Jan-08 + + * Fixed some inline issues which cause problems because of the C99 inline rules (reported by David Harvey). + * Fixed a makefile issue reported (and solved) by David Harvey when *not* linking against NTL. + +v 1.0.6 -- 17-Jan-08 + + * Fixed an issue with FLINT_BIT_COUNT on certain machines (probably due to arithmetic shift issues) + +v 1.0.7 -- 22-Jan-08 + + * Made F_mpn_mul binary compatible with the way mpn_mul *operates* in practice. + +v 1.0.8 -- 15-Feb-08 + + * Fixed a bug in fmpz_poly_right_shift (reported by Kiran Kedlaya) + +v 1.0.9 -- 11-Mar-08 + + * Fixed a memory allocation bug in fmpz_poly_power + +v 1.0.10 -- 16-Jun-08: + + * integer gcd (this just wraps the GMP gcd code) + * polynomial content + * convert to and from FLINT and NTL integers and polynomials + * get a coefficient of a polynomial efficiently as a read only mpz_t + * print polynomials in a prettified format with a specified variable + +v 1.0.11 -- 9-Jul-08 + + * Fixed a bug in z_ll_mod_precomp on ia64 (reported by Michael Abshoff and William Stein) + +v 1.0.12 -- 11-Jul-08 + * Removed some Opteron tuning flags which cause illegal instruction errors on Pentium4 + * Fixed numerous memory leaks in fmpz_poly test code + * Fixed memory leak in fmpz_poly_power_trunc_n + * Fixed major memory leaks in fmpz_poly_xgcd_modular + * Rewrote __fmpz_poly_mul_karatrunc_recursive and _fmpz_poly_mul_karatsuba_trunc to "prove code" and got rid of some dirty memory issues + * Fixed some potential illegal memory accesses to do with cache prefetching in fmpz_poly.c + +v 1.0.13 -- 13-Jul-08 + * Fixed memory leaks and dirty memory issues in test code for numerous modules. + * Removed further issues with cache prefetching in mpn_extras.c + +v 1.0.14 -- 23-Sep-08 + * Update long_extras and test code for the sake of new quadratic sieve (new functions in long_extras remain undocumented) + * Removed many bugs from tinyQS and mpQS and joined them into a single program for factoring integers + +v 1.0.15 -- 15-Oct-08 + * Fixed a bug which causes a segfault when setting a coefficient of the zero polynomial to zero + * Fixed build bug in longlong.h on s390 platform + +v 1.0.16 -- 22-Oct-08 + * Fixed a segfault when trying to truncate a polynomial to an longer length than it currently is, with the function fmpz_poly_truncate (reported by Craig Citro) + +v 1.0.17 -- 30-Nov-08 + * Fixed a segfault caused by left shifting of polynomials with zero limbs allocated in division and pseudo division functions. + * Fixed a bound used in fmpz_gcd_modular to use a proven bound + * Fixed a bug in fmpz_poly-profile where the top bit of random coefficients of n bits was always set + +v 1.0.18 -- 05-Dec-08 + * Fixed another bug in the fmpz_poly_set_coeff_* functions which resulted in dirty coefficients + +v 1.0.19 -- 12-Dec-08 + * Fixed a bug in z_remove_precomp + +v 1.0.20 -- 13-Dec-08 + * Fixed some bugs in conversion of zmod_poly's to and from strings + +v 1.0.21 -- 25-Dec-08 + * Fixed the Christmas bug reported by Michael Abshoff which causes a test failure in fmpz_poly_gcd_modular and a hang in fmpz_poly_invmod_modular on 32 bit machines + +v 1.1.0 -- 21-Dec-08 (some of the following features were previewed in FLINT 1.0.11): + + * integer gcd (this just wraps the GMP gcd code) + * polynomial content + * primitive part + * convert to and from FLINT and NTL integers and polynomials + * get a coefficient of a polynomial efficiently as a read only mpz_t + * print polynomials in a prettified format with a specified variable + * Sped up integer multiplication + * Convert to and from zmod_polys from fmpz_polys + * Chinese remainder for fmpz_polys + * Leading coeff macro + * Euclidean norm of polynomials + * Exact division testing of polynomials + * Polynomial GCD (subresultant, heuristic, modular) + * Modular inversion of polynomials + * Resultant + * XGCD (Pohst-Zassenhaus) + * Multimodular polynomial multiplication + * Rewritten karatsuba_trunc function + * Rewritten division functions + * Polynomial derivative + * Polynomial evaluation + * Polynomial composition + * Addition and subtraction of zmod_polys + * Sped up multiplication of zmod_polys + * Extended multiplication of zmod_polys to allow up to 63 bit moduli + * zmod_poly subpolynomials + * zmod_poly reverse + * Truncated multiplication for zmod_polys (left, right, classical and KS) + * Scalar multiplication + * Division for zmod_polys (divrem and div, classical, divide and conquer and newton) + * Series inversion for zmod_polys + * Series division for zmod_polys + * Resultant for zmod_polys + * GCD for zmod_polys including half-gcd + * Inversion modulo a polynomial for zmod_polys + * XGCD for zmod_polys + * Squarefree factorisation for zmod_polys + * Berlekamp factorisation for zmod_polys + * Irreducibility testing for zmod_polys + * Derivative for zmod_polys + * Middle product for zmod_polys (sped up newton division) + * addmod, submod and divmod for ulongs + * Sped up limb sized integer square root + * Partial factoring of ulongs + * z_randbits + * Pocklington-Lehmer primality testing + * BSPW pseudo-primality testing + * Fermat pseudo-primality testing + * Fast Legendre symbol computation + * Chinese remainder for fmpzs + * Square root with remainder for fmpzs + * Left and right shift for fmpzs + * Reduction modulo a ulong for fmpzs + * Montgomery redc, mulmod, divmod and mod for fmpzs + * Multimodular reduction and CRT for fmpzs + * fmpz_mulmod and fmpz_divmod + * fmpz_invert for inversion modulo an fmpz + * Dramatically sped up gcd for small fmpzs + * Computation of 1D, 2D and some 3D theta functions + * Example program for multiplying theta functions + * Test code now times test functions + * Quick and dirty timing function for profiler + * Tiny quadratic sieve for small one and two limb integers + * Completely rewritten self initialising multiple polynomial quadratic sieve + * Build fix for 64 bit OSX dylibs (reported by Michael Abshoff) + +v 1.1.1 -- 11-Feb-09 + + * Fixed bugs in _fmpz_poly_scalar_mul_fmpz, fmpz_poly_gcd_heuristic and fmpz_poly_gcd_subresultant and fixed bugs in test__fmpz_poly_scalar_div_fmpz, test_fmpz_poly_scalar_div_fmpz and test_fmpz_poly_scalar_div_mpz. + +v 1.1.2 -- 1-Mar-09 + + * Fixed some memory allocation slowdowns and bugs in fmpz_poly division and pseudo division functions (reported by William Stein). + +v 1.1.3 -- 1-Mar-09 + + * Inserted some missing return values in zmod_poly test code. + +v 1.2.0 -- 10-Mar-09 + + * made memory manager, fmpz and fmpz_poly threadsafe + * Code for running tests in parallel (not activated) + * Sped up fmpz_poly_scalar_div_ui/si when scalar is 1/-1 + * Parallelise _fmpz_poly_mul_modular + * fmpz_mul_modular_packed to pack coefficients to the byte before running _fmpz_poly_mul_modular + * fmpz_poly_pseudo_rem_cohen (not documented) + * special case for leading coeff 1/-1 in fmpz_poly_pseudo_divrem_basecase + * removed a memory allocation bug which caused a massive slowdown in fmpz_poly_pseudo_divrem_basecase + * fmpz_poly_pseudo_rem_basecase (not documented) + * fmpz_poly_pseudo_rem (not asymptotically fast) + * fmpz_poly_signature (not asymptotically fast) + * basic fmpz_poly_is_squarefree function + * included zn_poly in trunk and made FLINT build zn_poly as part of its build process + * switched to using zn_poly for polynomial multiplication, newton inversion, scalar multiplication in zmod_poly + * Integer cube root of word sized integers + * Fibonacci pseudoprime test + * BSPW probable prime test + * n - 1 primality test + * Complete implementation of z_issquarefree + * Significantly improved the thetaproduct example program. + * Fixed bug in fmpz_poly_byte_pack which is triggered when trying to pack into fields a multiple of 8 bytes (could cause a segfault) + * Fixed a bug in fmpz_poly_pseudo_divrem (relied on an uninitialised poly to have length 0) + * Fixed bug in fmpz_multi_CRT_ui (could segfault) + * Fixed bug in fmpz_multi_mod_ui (could segfault) + * Fixed memory leak in zmod_poly_factor_squarefree + * Fixed memory leak in zmod_poly_from_string + +v 1.2.1 -- 14-Mar-09 + + * Removed some FLINT 2.0 code which was interfering with the build of the NTL-interface + * Removed an omp.h from fmpz_poly.c. + +v 1.2.2 -- 20-Mar-09 + + * Fixed a memory leak in zmod_poly_factor + * Fixed zmod_poly-profile build + +v 1.2.3 -- 31-Mar-09 + + * Fixed bugs in all fmpz_poly evaluation functions, identified by Burcin Erocal. + +v 1.2.4 -- 4-Apr-09 + + * Defined THREAD to be blank on Apple CC and __thread for thread local storage on other gcc's (where it's defined) + * #undef ulong in profiler.h where time.h and other system time headers are included (both reported by M. Abshoff) + +v 1.2.5 -- 18-Apr-09 + + * Upgraded to zn_poly-0.9 to avoid a serious error in squaring of large polynomials over Z/nZ + +v 1.3.0 -- 09-Jun-09 + + * Added new code for checking 2nd, 3rd and 5th roots + * Fixed a bug in z_factor + * Connected quadratic sieve for factoring large ulongs + * Added one line factor algorithm + * constructed best of breed factor algorithm + * Fixed termination conditions for z_intcuberoot and z_intfifthroot which were broken + * Added some code for special cases which cause infinite loops in cuberoot and fifthroot + * Went back to ceil(pow(n, 0.33333333)) and ceil(pow(n, 0.2)) for initial guesses in cube and fifth root functions as these were about 50% faster than sqrt(n) and sqrt(sqrt(n)) respectively. + * Added test code for z_intfifthroot + * Added test code for z_factor_235power + * Fixed some uninitialised data found by valgrind in intcuberoot and intfifthroot + * Fixed multiply defined PRIME_COUNT in long_extras-test + * Got rid of gotos in some functions in long_extras + * Knocked optimisation level back to -O2 because it miscompiles on sage.math + * Changed tables to use uint64_t's instead of ulongs which are not 64 bits on a 32 bit machine + * Only checked MAX_HOLF on 64 bit machine + * Changed MAX_SQUFOF to WORD(-1) + * Check constant 0x3FFFFFFFFUL only on a 64 bit machine + * Fixed a bug in z_oddprime_lt_4096 on 32 bit machines + * Fixed some TLS issues with Cygwin + * Fixed some typos in makefile + * Fixed a wrong path in fmpz.c + +v 1.4.0 -- 06-Jul-09 + + * Sped up zmod_poly division in case where operands are the same length + * Sped up zmod_poly division in case where operands have lengths differing by 1 + * Fixed a bug in zmod_poly_gcd for polynomials of zero length + * Sped up zmod_poly_gcd considerably (both euclidean and half gcd) + * Sped up zmod_poly_gcd_invert and zmod_poly_xgcd considerably + * Made zmod_poly_gcd_invert and zmod_poly_xgcd asymptotically fast + * Made zmod_poly_resultant asymptotically fast + * Added optimised zmod_poly_rem function + * Fixed a divide by zero bug in zmod_poly_factor_berlekamp + * Added test code for z_factor_tinyQS and z_factor_HOLF + * Fixed many bugs in the z_factor code, tinyQS and mpQS + * Corrected numerous typos in the documentation and added missing descriptions + * Added F_mpz_cmp function + * Added documentation to the manual for the new F_mpz module + +v 1.5.0 -- 22-Sep-09 + + * Added multimodular reduction and CRT to F_mpz module + * Fixed some bugs in F_mpz module and numerous bugs in test code + * Added zmod_poly_compose + * Added zmod_poly_evaluate + * Added functions for reduced evaluation and composition to fmpz_poly module (contributed by Burcin Erocal) + * Fixed bugs in the primality tests in long_extras + * Removed all polynomial multimodular multiplication functions + * Added new thetaproduct code used in the 1 trillion triangles computation + * Fixed a severe bug in the fmpz_poly_pseudo_div function reported by Sebastian Pancratz + * Added fmpz_comb_temp_init/clear functions + * Fixed a normalisation buglet in fmpz_poly_pack_bytes + * Added F_mpz_pow_ui function (contributed by Andy Novocin) + * Fixed a severe bug in the FFT reported by William Stein and Mariah Lennox (fix contributed by David Harvey) + * Removed some memory leaks from F_mpz test code + * Fixed bug in zmod_poly_evaluate test code + +v 1.6.0 -- 24-Dec-10 + + Bugs: + ==== + + * Fixed a memory leak in mpz_poly_to_string_pretty + * Fixed a bug inherited from an old version of fpLLL + * Makefile to respect CC and CXX + * Fixed bug in F_mpz_set_si + * Fixed bug in F_mpz_equal + * Most for loops to C90 standard (for easier MSVC porting) + * Better Cygwin support + * Fixed a bug in zmod_poly_resultant + * Fixed bug in F_mpz_mul_KS/2 + * Fixed bug in tinyQS + * Worked around some known bugs in older GMP/MPIR's + + Major new functionality + ======================= + * F_mpz_poly_factor_zassenhaus + * F_mpz_poly_factor (incl. fmpz_poly_factor wrapper) using new vH-N approach + (see the paper of van Hoeij and Novocin and the paper of van Hoeij, Novocin + and Hart) + * Implementation of new CLD bounds function for polynomial factors + (see the paper of van Hoeij, Novocin and Hart + * Restartable Hensel lifting + * Heuristic LLL implementations using doubles and mpfr + * LLL implementations optimised for knapsack lattices + * New (probably subquadratic) LLL implementation (ULLL) + * zmod_poly_factor_cantor_zassenhaus + * New F_mpz_mod_poly module for polynomials over Z/pZ for multiprec. p + + Some of the other new functions added + ===================================== + + F_mpz: + + * F_mpz_gcd + * F_mpz_smod + * F_mpz_mod_preinv + * F_mpz_fdiv_qr + * F_mpz_get/set_mpfr/2exp + * F_mpz_sscanf + * F_mpz_set_d + + F_mpz_poly: + + * read F_mpz_poly to_string/from_string/fprint/print/fread/pretty + * F_mpz_poly_to/from_zmod_poly + * F_mpz_poly_scalar_div_exact + * F_mpz_poly_smod + * F_mpz_poly_derivative, F_mpz_poly_content, F_mpz_poly_eval_horner_d/2exp + * F_mpz_poly_scalar_abs + * F_mpz_poly_set_d_2exp + * F_mpz_poly_div/divrem + * F_mpz_poly_gcd + * F_mpz_poly_is_squarefree + * F_mpz_poly_factor_squarefree + * F_mpz_poly_mul_trunc_left + * F_mpz_poly_pseudo_div + * F_mpz_poly_set_coeff + * F_mpz_poly_pow_ui + * Inflation/deflation trick for factorisation + + zmod_poly: + + * Inflation/deflation trick for factorisation + + mpz_mat: + + * mpz_mat_from_string/to_string/fprint/fread/pretty + + mpq_mat: + + * mpq_mat_init/clear + * Gramm-schmidt Orthogonalisation + + F_mpz_mat: + + * F_mpz_mat_print/fprint/fread/pretty + * F_mpz_mat_mul_classical + * F_mpz_mat_max_bits/2 + * F_mpz_mat_scalar_mul/div_2exp + * F_mpz_mat_col_equal + * F_mpz_mat_smod + * F_mpz_vec_scalar_product/norm + * F_mpz_vec_add/submul_ui/si/F_mpz/2exp + + zmod_mat: + + * classical multiplication + * strassen multiplication + * scalar multiplication + * zmod_mat_equal + * zmod_mat_add/sub + * zmod_mat_addmul_classical + + d_mat: + + * d_vec_norm, d_vec_scalar_product + + mpfr_mat: + + * mpfr_vec_scalar_product/norm + +v 2.0 -- 16 Jan 2011 + N.B: FLINT 2 is a complete rewrite of flint from scratch + It includes the following modules: + +ulong_extras: (word sized integers and modular arithmetic) + * random numbers (randint, randbits, randprime, randint) + * powering + * reverse binary + * mod, divrem, mulmod all with precomputed inverses + * gcd, invgcd, xgcd + * jacobi symbols + * addmod, submod, invmod, powmod + * prime sieve, nextprime, prime-pi, nth-prime + * primality testing (small, binary search, Pocklington-Lehmer, Pseudosquare) + * probably prime tests (strong base-a, Fermat, Fibonacci, BPSW, Lucas) + * sqrt, sqrtrem, is-square, perfect-power (2,3,5) + * remove, is-squarefree + * factorisation (trial-range, trial, power (2,3,5), one-line, SQUFOF) + * Moebius mu, Euler phi + +fmpz: (memory managed multiple precision integers) + * memory management (init, clear) + * random numbers (randbits, randm) + * conversion to and from long, ulong, doubles, mpz's, strings + * read/write to file, stdin, stdout + * sizeinbase, bits, size, sgn, swap, set, zero + * cmp, cmp-ui, cmpabs, equal, is-zero, is-one + * neg, abs, add, add-ui, sub, sub-ui, mul, mul-si, mul-ui, mul-2exp + * addmul, addmul-ui, submul, submul-ui + * cdiv-q, cdiv-q-si, cdiv-q-ui + * fdiv-q, fdiv-q-si, fdiv-q-ui, fdiv-qr, fdiv-q-2exp + * tdiv-q, tdiv-q-si + * divexact, divexact-si, divexact-ui + * mod, mod-ui + * powering + * sqrt, sqrt-rem + * factorial + * gcd, invmod + * bit-pack, bit-unpack + * multimodular reduction, CRT + +fmpz_vec: (vectors over fmpz's) + * memory management (init, clear) + * random vectors + * max-bits, max-limbs + * read/write to file/stdin/stdout + * set, swap, zero, neg + * equal, is-zero + * sort + * add, sub + * scalar multiplication by fmpz, ulong, long, 2exp + * exact division by fmpz, long, ulong + * fdiv-q by fmpz, long, ulong, 2exp + * tdiv-q by fmpq, long, ulong + * addmul by fmpz, long, long by 2exp + * submul by fmpz, long, long by 2exp + * Gaussian content + +fmpz_poly: (polys over fmpz's) + * memory management (init, realloc, fit-length, clear) + * random polys + * normalise, set-length, truncate + * length, degree, max-limbs, max-bits + * set, set-si, set-ui, set-fmpz, set-str + * get-str, get-str-pretty + * zero, one, zero-coeffs + * swap, reverse + * get/set coeffs from fmpz, long, ulong + * get-coeff-ptr, lead + * equal, is-zero + * add, sub + * scalar multiplication by fmpz, long, ulong + * scalar addmul/submul by fmpz + * scalar fdiv by fmpz, long, ulong + * scalar tdiv by fmpz, long, ulong + * scalar divexact by fmpz, long, ulong + * bit pack, bit unpack + * multiplication (classical, karatsuba, KS) + * mullow (classical, karatsuba, KS) + * mulhigh (classical, karatsuba) + * middle product (classical) + * powering (small, binary exponent, binomial, multinomial, addition chains) + * truncated powering (binary exponent) + * shift left/right + * euclidean norm + * gcd (subresultant) + * resultant + * content, primitive part + * divrem (basecase, divide-and-conquer) + * div (basecase, divide-and-conquer) + * rem (basecase) + * invert series (basecase, Newton) + * div series + * pseudo divrem (basecase, divide-and-conquer, Cohen) + * rem (Cohen) + * div + * evaluate (Horner) at fmpz, mpq, a mod n + * composition (Horner, divide-and-conquer) + * signature + * read/write to file/stdin/stdout + +fmpq_poly: (polynomials over Q stored as poly over fmpz with fmpz denominator) + * memory management (init, realloc, fit-length, clear) + * random polys + * set-length, canonicalise, normalise, truncate + * is-canonical, length, degree + * reference to numerator, denominator + * set, set-si, set-ui, set-fmpz, set-mpz, set-mpq + * set-array-mpq, set-str + * get-str, get-str-pretty + * zero, neg, swap + * invert + * set coefficient to mpq, long, ulong, fmpz, mpz + * get coefficient as mpq + * equal, cmp, is-one, is-zero + * add, sub + * scalar multiplication by long, ulong, fmpz, mpq + * scalar division by fmpz, long, ulong, mpq + * multiplication, mullow + * powering + * shift left/right + * divrem, div, rem + * invert series (Newton iteration) + * divide series + * derivative + * evaluate at fmpz, mpq + * composition, scale by constant + * content, primitive part + * make-monic, is-monic + * is-squarefree + * read/write to file/stdin/stdout + +nmod_vec: (vectors over Z/nZ for n fitting in a machine word) + * memory management (init/clear) + * macros for efficient reduction of 1, 2 and 3 limb integers mod n + * macro for addmul mod n + * add/sub/neg individual coefficients mod n + * random vectors + * set, zero, swap + * reduce, max-bits + * equal + * add, sub, neg + * scalar multiplication by a value reduced mod n + * scalar addmul by a value reduced mod n + +nmod_poly: (polynomials over Z/nZ for n fitting in a machine word) + * memory management (init, realloc, fit-length, clear) + * random polys + * normalise, truncate + * length, degree, modulus, max-bits + * set, swap, zero, reverse + * get/set coefficients as ulongs, strings + * read/write to file, stdin, stdout + * equal, is-zero + * shift left/right + * add, sub, neg + * scalar multiplication by a value reduced mod n + * make-monic + * bit pack, bit unpack + * multiplication (classical, KS) + * mullow (classical, KS) + * mulhigh (classical) + * powering (binary exponent) + * pow-trunc (binary exponent) + * divrem (basecase, divide-and-conquer, Newton iteration) + * div (basecase, divide-and-conquer, Newton iteration) + * invert series (basecase, Newton iteration) + * divide series (Newton iteration) + * derivative + * evaluation at a value taken mod n + * composition (Horner, divide-and-conquer) + * gcd (euclidean) + +fmpz_mat: (matrices over fmpz's) + * memory management (init, clear) + * random matrices (bits, integer relations, simultaneous diophantine equations + NTRU-like, ajtai, permutation of rows and cols of a diagonal matrix, random + of given rank, random of given determinant, random elementary operations) + * set, init-set, swap, entry pointer + * write to file or stdout + * equal + * transpose + * multiplication (classical, multimodular) + * inverse + * determinant + * row reduce (Gaussian and Gauss-Jordan fraction-free elimination) + * rank + * solve Ax = b, solve AX = B + * fraction free LU decomposition + +nmod_mat: (matrices over Z/nZ for n fitting in a machine word) + * memory management (init, clear) + * random matrices (uniform, full, permutations of diagonal matrix, random of + given rank, random elementary operations) + * set, equal + * print to stdout + * add + * transpose + * multiplication (classical, Strassen, A*B^T) + * row reduction (Gaussian and Gauss-Jordan) + * determinant + * rank + * solve (Ax = b, AX = B, solve with precomputed LU) + * invert + +arith: (arithmetic functions) + * Bernoulli numbers + * Bernoulli polynomials + * primorials (product of primes up to n) + * harmonic numbers + * Stirling numbers + * Euler phi function + * Moebius mu function + * Sigma (sum of powers of divisors) + * Ramanujan tau function + + +examples: (example programs) + * compute coefficients of q-series of Delta function + +mpfr_vec: (vectors over mpfr reals) + * memory management (init, clear) + * add + * set, zero + * scalar multiplication by mpfr, 2exp + * scalar product + +mpfr_mat: (matrices over mpfr reals) + * memory management (init, clear) + +v 2.1 -- 9 Mar 2011 + +fmpz +---- + * Simplified interface for fast multimodular reduction and CRT reconstruction + * Fixed segmentation fault in fmpz_multi_mod_ui when the input exceeds the product of the moduli + * Added simple incremental CRT functions (fmpz_CRT_ui, fmpz_CRT_ui_unsigned) to complement the existing fast ones + * Added example programs for CRT + * Added random number generators designed for testing modular code (fmpz_randtest_mod, fmpz_randtest_mod_signed) + * Added fmpz_fdiv_ui for remainder on division by an ulong + * Added fmpz_bin_uiui for computing binomial coefficients + * Added fmpz_mul2_uiui and fmpz_divexact2_uiui for multiplying or dividing an fmpz by a pair of ulongs (efficiently when their product fits in a single limb) + +fmpz_mat +-------- + * Added utility functions for basic arithmetic and creating unit matrices + * Added multimodular determinant computation (certified or heuristic) + * Added support for computing right nullspaces (fmpz_mat_kernel). Fast only for small matrices. + * Some internal code cleanup and various small fixes + +nmod_mat +-------- + * Faster Gaussian elimination for small moduli + * Faster determinants + * Faster matrix inversion and nonsingular solving + +nmod_poly +--------- + * Added nmod_poly_integral for computing integrals + * Added fast square root and inverse square root of power series + * Added fast transcendental functions of power series (log, exp, sin, cos, tan, sinh, cosh, tanh, asin, atan, asinh, atanh) + * Made nmod_poly_inv_series_newton more memory efficient + +fmpq_poly +--------- + * Added fmpq_poly_integral for computing integrals + * Added fast transcendental functions of power series (log, exp, sin, cos, tan, sinh, cosh, tanh, asin, atan, asinh, atanh) + +arith +----- + * Made computation of vectors of Bernoulli numbers faster + * Added fast computation of single Bernoulli numbers + * Added a separate function for computing denominators of Bernoulli numbers + * Added fast computation of Bell numbers (vector and single) + * Added fast computation of Euler numbers (vector and single) + * Added fast computation of Euler polynomials + * Added fast computation of Swinnerton-Dyer polynomials + * Added fast computation of Legendre polynomials + * Added fast vector computation of the partition function + * Added fast vector computation of Landau's function + +ulong_extras +------------ + * Added a function for computing factorials mod n + +build system +------------ + * Added support for building static and shared libraries + * All object files and test/profile/example binaries now build in separate build directory + +documentation +------------- + * Large number of corrections + +v 2.2 -- 4 Jun 2011 + +fmpq (multiprecision rational numbers) +-------------------------------------- + * Basic arithmetic functions + * Utility functions + * Rational reconstruction + * Functions for enumerating the rationals + +fmpq_mat (matrices over Q) +-------------------------- + * Basic arithmetic functions + * Utility functions + * Fast multiplication + * Classical and fraction-free reduced row echelon form + * Determinants + * Fast non-singular solving + +fmpz_poly_mat (matrices over Z[x] +--------------------------------- + * Basic arithmetic functions + * Utility functions + * Fraction-free row reduction and determinants + * Fast determinants (experimental) + +fmpz_mat +-------- + * Added more utility functions (scalar multiplication, etc) + * Added Dixon's p-adic algorithm (used by fast nonsingular rational system + solving) + * Added reduced row echelon form + * Added conversions between fmpz_mat and nmod_mat + * Added CRT functions for fmpz_mats + * Faster matrix multiplication for small to medium dimensions + +longlong.h +---------- + * Added x86 assembly macros for accumulating sums of two limb operands + +nmod_mat +-------- + * Sped up arithmetic for moduli close to FLINT_BITS + +arith +----- + * Changed interface of various functions to use new fmpq type + +fmpz +---- + * Added fmpz_set_ui_mod + * Inlined fmpz_neg, fmpz_set_si, fmpz_set_ui for better performance + * Added fmpz_lcm + * Small performance improvement to fmpz_CRT_ui + +fmpz_vec +-------- + * Added _fmpz_vec_lcm + +fmpz_poly_q (rational functions over Q, modeled as quotients of fmpz_polys) +--------------------------------------------------------------------------- + * Basic arithmetic functions + * Conversion and IO functions + * Evaluation + +padic (p-adic numbers -- experimental) +------------------------------------- + * Basic arithmetic + * Data conversion and IO + * Inverse and square root using Newton iteration + * Teichmuller lifts (not optimised) + * p-adic exponential function (not optimised) + +fmpz_poly +--------- + * Added fmpz_poly_gcd_modular (and fmpz_poly_gcd wrapper) + * Added fmpz_poly_xgcd_modular (and fmpz_poly_xgcd wrapper) + * Added conversions between fmpz_poly and nmod_poly + * Added CRT functions + * Added multipoint evaluation and interpolation + +nmod_poly +--------- + * Added nmod_poly_xgcd_euclidean (and nmod_poly_xgcd wrapper) + * nmod_poly_gcd wrapper + +mpn_extras +---------- + * Added MPN_NORM and MPN_SWAP macros. + * Added mpn_gcd_full to remove some of the restrictions from the usual mpn_gcd + +build fixes +------------ + * fixed make install to create nonexistent dirs (reported by Serge Torres) + * -L use /usr instead of /usr/local by default (reported by Serge Torres) + * guards for system headers because of flint's use of ulong + +v 2.3 -- 1 Jul 2012 + +general +------- + * many changes to the build system + * added NTL interface + * switched to custom memory allocation functions flint_malloc etc + * in addition to the entries below, fixed a large number of memory leaks, + problems with the test code, and bugs in corner cases of various functions + * added _fmpz_cleanup_mpz_content as an alternative to _fmpz_cleanup + * support MinGW32 + * support Cygwin + * bugfix on ia64 + * support sparc32/sparc64 + * support OSX + * support Solaris, NetBSD, OpenBSD, etc (if bash, GNU Make present) + +ulong_extras +------------ + * implemented the improved Lehman algorithm + * added n_jacobi_unsigned to allow n > WORD_MAX + * fixed n_sqrtmod for n > WORD_MAX + * fixed bug causing n_sqrtmod to hang + * added sublinear algorithm for computing factorials mod p + * added n_sqrtmod_primepow, n_sqrtmodn and associated functions for + computing square roots modulo composite integers + * fixed bugs in n_is_prime_pocklington + * fixed UWORD_MAX case in powmod and powmod2 + * fixed problems with the random number generators + * fixed rare bug in n_mod_precomp + * fixed rare bug in n_is_prime_pseudosquare + +long_extras +----------- + * added z_sizeinbase + +qsieve +------ + * new module implementing a quadratic sieve for numbers up to two limbs + +fft +--- + * new module providing an efficient Schoenhage-Strassen FFT + +longlong +-------- + * added assembly code for ia64 and ARM + * fixed bug in fallback version of add_sssaaaaaa + +fmpz +---- + * added fmpz_fib_ui + * added double precision natural logarithm + * added fmpz_val2 for 2-valuation + * added mul_2exp, div_2exp, cdiv_q_2exp, tdiv_q_2exp, fdiv_r, fdiv_r_2exp, + tdiv_ui, mul_tdiv_q_2exp + * added get_d/set_d + * added fmpz_divisible, divisible_si + * optimised fmpz_powm and fmpz_powm_ui + * added clog, clog_ui, flog, flog_ui for computing logarithms + * added abs_lbound_ui_2exp, ubound_ui_2exp + * added fmpz_rfac_ui and fmpz_rfac_uiui for rising factorials + * added functions to obtain read-only fmpz_t's from mpz_t's + * added fmpz_init_set, init_set_ui + * added fmpz_gcdinv + * added fmpz_is_square + * added fmpz_tstbit, setbit, clrbit, complement, combit, and, or, xor, popcnt + * added a sign flag for CRT instead of using separate methods + * fixed bugs in fmpz_sqrtmod + * fixed a bug in fmpz_bit_unpack that could cause corruption of the global + fmpz array when compiled in single mode + * fixed a bug in fmpz_sub_ui that could cause memory corruption + +fmpz_vec +-------- + * added functions for obtaining the largest absolute value coefficient + * added functions for computing the sum and product of an integer vector + * made max_bits much faster + * added _fmpz_vec_mod_fmpz + * made randtest produce sparse output + +fmpz_poly +--------- + * added fmpz_poly_sqr, fmpz_poly_sqrlow for squaring a polynomial + * added fmpz_poly_lcm + * made multipoint interpolation faster by using the Newton basis + * added a function for fast division by a linear polynomial + * added power series composition (classical and Brent-Kung) + * added power series reversion (classical, Newton, fast Lagrange) + * added a function for obtaining the largest absolute value coefficient + * fixed quadratic memory usage and stack overflow when performing + unbalanced division or pseudo division using the divconquer algorithm + * fixed a bug in poly_zero_coeffs + * fixed a bug in xgcd_modular + * allowing +/-1 in the constant term of power series inversion + * fixed aliasing bug in divrem + * added restartable Hensel lifting and associated utility functions + * fixed rem, which used to only call the basecase algorithm + * fixed pseudo_divrem, which used to only call the basecase algorithm + * implemented Schoenhage-Strassen multiplication (mul_SS, mullow_SS) + and enabled this by default + * fixed a bug in the heuristic GCD algorithm + * added functions for Newton basis conversion + * added functions for fast Taylor shift + * added fmpz_poly_sqrt implementing a basecase algorithm + * added scalar mul_2exp, fdiv_2exp, tdiv_2exp + * made randtest produce sparse output + * added fmpz_poly_equal_fmpz + * improved performance by always using basecase multiplicatio + when one polynomial is short + * improved algorithm selection for fmpz_poly_gcd + * fixed several bugs in gcd_modular + * improved performance of gcd_modular + +fmpz_poly_factor +---------------- + * new module for factorisation of fmpz_polys + * added a naive implementation of the Zassenhaus algorithm + +fmpz_mod_poly +------------- + * new module for polynomials modulo over Z/nZ for arbitrary-precision n + * multiplication, powering + * classical and divconquer division + * series inversion + * Euclidean GCD and XGCD + * invmod + * radix conversion + * divconquer composition + * GCD and division functions that test invertibility of the + leading coefficient + +fmpz_mat +-------- + * added det_divisor for computing a random divisor of the determinant + * faster determinant computation using divisor trick + * faster determinant computation by using multimodular updates + * fixed n x 0 x m product not zeroing the result + * various interface improvements + * faster implementation of Cramer's rule for multiple right hand sides + * added fmpz_mat_fread and read + * added multi CRT/mod functions + * added trace + +fmpz_poly_mat +------------- + * fixed n x 0 x m product not zeroing the result + * added inverse + * added rank computation + * added reduced row echelon form and nullspace computation + * added more utility functions + * added squaring and exponentiation + * added balanced product of a sequence of matrices + * added truncate, mullow, sqrlow, pow_trunc + * added trace + +fmpz_factor +----------- + * new module providing interface for integer factorisation + * fast expansion of a factored integer + +fmpq +---- + * cleaned up and improved performance of rational reconstruction code + * allow separate numerator and denominator bounds for rational + reconstruction + * added continued fraction expansion + * added functions for summation using binary splitting + * added fmpq_swap + * added fmpq_print, fmpq_get_str + * added fmpq_pow_si + * added functions to obtain read-only fmpq_t's from mpq_t's + * added fmpq_cmp + +fmpq_mat +-------- + * fixed n x 0 x m product not zeroing the result + * added fmpq_mat_transpose + * added trace + +fmpq_poly +--------- + * improved speed of multipoint interpolation using _fmpz_poly_div_root + * fmpq_poly: added power series composition (classical and Brent-Kung) + * fmpq_poly: added power series reversion (classical, Newton, fast Lagrange) + * fixed bug wherein set_array_mpq modified the input + * added gcd, xgcd, lcm, resultant + * added fmpq_poly_set_fmpq + * added fmpq_poly_get_slice, fmpq_poly_reverse + * fixed aliasing bug in divrem + * changed some functions to use FLINT scalar types instead of MPIR data types + * added fmpq_poly_get_numerator + +nmod_poly +--------- + * implemented the half gcd algorithm for subquadratic gcd and xgcd + * added multipoint evaluation and interpolation + * added asymptotically fast multipoint evaluation and interpolation + * added a function for forming the product of linear factors + * added a function for fast division by a linear polynomial + * added power series composition (classical and Brent-Kung) + * added power series reversion (classical, Newton, fast Lagrange) + * added nmod_poly_mulmod, powmod and related functions + (ported from flint1) + * added squarefree, irreducibility tests (ported from flint1) + * added Berlekamp and Cantor-Zassenhaus factoring (ported from flint1) + * fixed quadratic memory usage and stack overflow when performing + unbalanced division using the divconquer algorithm + * added compose_series_divconquer + * added resultant + * fixed aliasing bug in divrem + * added rem functions + * added divrem_q0, q1 for special cases of division + * added functions for fast Taylor shift + * added nmod_poly_sqrt + * made fread read the modulus from the file + * made randtest produce sparse output + * fixed bug in xgcd_euclidean with scalar inputs + +nmod_vec +-------- + * added functions and macros for computing dot products + * made randtest produce sparse output + +nmod_mat +-------- + * added addmul/submul functions + * asymptotically fast solving of triangular systems + * asymptotically fast LUP decomposition + * asymptotically fast determinant and rank computation + * asymptotically fast reduced row echelon form and nullspace + * asymptotically fast nonsingular solving + * asymptotically fast inverse + * tidied some interfaces + * fixed n x 0 x m product not zeroing the result + * added trace + * made multiplication faster for tiny moduli by means of bit packing + +nmod_poly_mat +------------- + * new module for matrices over Z/nZ[x], with similar + functionality as the fmpz_poly_mat module + * determinant, rank, solving, reduced echelon form, nullspace + * fraction-free Gaussian elimination + * multiplication using bit packing + * multiplication using evaluation-interpolation + * determinant using evaluation-interpolation + +padic +----- + * restructured and improved much of the code + * added padic_log + * improved log and exp using rectangular splitting + * added asymptotically fast log and exp based on binary splitting + +perm +---- + * added the perm module for permutation matrices + * computing the parity of a permutation + * inverting a permutation + +arith +----- + * added generation of cyclotomic polynomials + * added functions for evaluating Dedekind sums + * fast computation of the partition function + * added a function for factoring a Hardy-Ramanujan-Rademacher + type exponential sum + * added Chebyshev polynomials T and U + * added computation of the minimal polynomial of cos(2pi/n) + * added asymptotically fast high-precision approximation of zeta(n) + * added asymptotically fast computation of Euler's constant + * added new algorithms and functions for computing Bell numbers + * fast computation of pi (adapting code written by Hanhong Xue) + * added functions for computing the number of sum of squares + representations of an integer + * renamed functions to have an arith_ prefix + +v 2.4 -- 20 Nov 2013 + + * C++ expressions template wrapper + * Fast factorisation of polynomials over Z/nZ + * improved p-adics + * polynomials/matrices over p-adics + * qadics + * Finite fields (small and large F_q), polynomials/matrices over F_q + * Finite fields with Zech logarithm representation + * Fast factorisation of polynomials over F_q + * Faster Brent-Kung modular composition + * New prime sieving code + * Lambert-W function + * Precomputed inverses for polynomials and large integers + * Williams' P+1 integer factoring algorithm + * Harvey's KS2/KS4 polynomial multiplication + * Faster primality testing up to 64 bits + * Support for Cygwin64 and MinGW64 + * Support for Clang + * Support for GMP + * Support for Boehm-Demers-Weiser GC + * Support for flint extension modules + +v 2.4.1 -- 2 Jan 2014 + + * Fixed a bug in the NTL interface tests (reported by Francois Bissey) + +v 2.4.2 -- 11 Mar 2014 + + * Fix bug in ARM assembly + +v 2.4.3 -- 01 Apr 2014 + + * Fix a linker issue on Mac OSX. + diff --git a/external/flint-2.4.3/NTL-interface.h b/external/flint-2.4.3/NTL-interface.h new file mode 100644 index 0000000..826c145 --- /dev/null +++ b/external/flint-2.4.3/NTL-interface.h @@ -0,0 +1,172 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + NTL-interface.h: Header file for NTL-interface.cpp + + Copyright (C) 2007 William Hart + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#ifndef FLINT_NTL_INT_H +#define FLINT_NTL_INT_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpz_mod_poly.h" +#include "fq.h" +#include "fq_poly.h" + +NTL_CLIENT + +#ifdef __cplusplus +extern "C" { +#endif + +/* + Converts an NTL ZZ to an fmpz_t. + + Assumes the fmpz_t has already been allocated to have sufficient space. +*/ +void fmpz_set_ZZ(fmpz_t rop, const ZZ& op); + +/* + Converts an fmpz_t to an NTL ZZ. Allocation is automatically handled. + */ +void fmpz_get_ZZ(ZZ& rop, const fmpz_t op); + + +/* + Converts an NTL ZZ_p to an fmpz_t. + + Assumes the fmpz_t has already been allocated to have sufficient space. +*/ +void fmpz_set_ZZ_p(fmpz_t rop, const ZZ_p& op); + +/* + Converts an fmpz_t to an NTL ZZ_p. Allocation is automatically handled. + */ +void fmpz_get_ZZ_p(ZZ_p& rop, const fmpz_t op); + +/* + Converts an NTL zz_p to an fmpz_t. +*/ +void fmpz_set_zz_p(fmpz_t rop, const zz_p& op); + +/* + Converts an fmpz_t to an NTL zz_p. + */ +void fmpz_get_zz_p(zz_p& rop, const fmpz_t op); + +/* + Converts an fmpz_poly_t to an NTL ZZX. +*/ + void fmpz_poly_get_ZZX(ZZX& rop, const fmpz_poly_t op); + +/* + Converts an NTL ZZX to an fmpz_poly_t. +*/ + void fmpz_poly_set_ZZX(fmpz_poly_t rop, const ZZX& op); + +/* + Converts an fmpz_mod_poly_t to an NTL ZZ_pX. +*/ +void fmpz_mod_poly_get_ZZ_pX(ZZ_pX& rop, const fmpz_mod_poly_t op); + +/* + Converts an NTL ZZ_pX to an fmpz_poly_t. +*/ +void fmpz_mod_poly_set_ZZ_pX(fmpz_mod_poly_t rop, const ZZ_pX& op); + +/* + Converts an fq_t to an NTL ZZ_pE. +*/ +void fq_get_ZZ_pE(ZZ_pE& rop, const fq_t op, const fq_ctx_t ctx); + +/* + Converts an NTL ZZ_pE to an fq_t. +*/ +void fq_set_ZZ_pE(fq_t rop, const ZZ_pE& op, const fq_ctx_t ctx); + + +/* + Converts an fq_poly_t to an NTL ZZ_pEX. +*/ +void fq_poly_get_ZZ_pEX(ZZ_pEX& rop, const fq_poly_t op, const fq_ctx_t ctx); + +/* + Converts an NTL ZZ_pEX to an fq_poly_t. +*/ +void fq_poly_set_ZZ_pEX(fq_poly_t rop, const ZZ_pEX& op, const fq_ctx_t ctx); + +/* + Converts an fmpz_mod_poly_t to an NTL zz_pX. +*/ +void fmpz_mod_poly_get_zz_pX(zz_pX& rop, const fmpz_mod_poly_t op); + +/* + Converts an NTL zz_pX to an fmpz_poly_t. +*/ +void fmpz_mod_poly_set_zz_pX(fmpz_mod_poly_t rop, const zz_pX& op); + +/* + Converts an fq_t to an NTL zz_pE. +*/ +void fq_get_zz_pE(zz_pE& rop, const fq_t op, const fq_ctx_t ctx); + +/* + Converts an NTL zz_pE to an fq_t. +*/ +void fq_set_zz_pE(fq_t rop, const zz_pE& op, const fq_ctx_t ctx); + + +/* + Converts an fq_poly_t to an NTL zz_pEX. +*/ +void fq_poly_get_zz_pEX(zz_pEX& rop, const fq_poly_t op, const fq_ctx_t ctx); + +/* + Converts an NTL zz_pEX to an fq_poly_t. +*/ +void fq_poly_set_zz_pEX(fq_poly_t rop, const zz_pEX& op, const fq_ctx_t ctx); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/external/flint-2.4.3/README b/external/flint-2.4.3/README new file mode 100644 index 0000000..1becc16 --- /dev/null +++ b/external/flint-2.4.3/README @@ -0,0 +1,15 @@ +FLINT 2 +======= + +FLINT (Fast Library for Number Theory) is a C library in support of computations +in number theory. It's also a research project into algorithms in number theory. + +FLINT 2 is a complete rewrite of the FLINT library from scratch. It includes +much cleaner code and in many cases much faster algorithms and implementations. + +At this stage FLINT consists mainly of fast integer and polynomial +arithmetic and linear algebra. In the future it is planned that FLINT will +contain algorithms for algebraic number theory and other number theoretic +functionality. + +William Hart -- 16 Jan 2011. diff --git a/external/flint-2.4.3/arith.h b/external/flint-2.4.3/arith.h new file mode 100644 index 0000000..7f15e64 --- /dev/null +++ b/external/flint-2.4.3/arith.h @@ -0,0 +1,242 @@ +/*============================================================================ + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +===============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010-2012 Fredrik Johansson + +******************************************************************************/ + +#ifndef ARITH_H +#define ARITH_H + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mat.h" +#include "fmpz_poly.h" +#include "fmpq_poly.h" +#include "fmpq.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/* MPFR extras ***************************************************************/ + +void mpfr_zeta_inv_euler_product(mpfr_t res, ulong s, int char_4); +void mpfr_pi_chudnovsky(mpfr_t res, mpfr_rnd_t rnd); + +/* Various arithmetic functions **********************************************/ + +void arith_primorial(fmpz_t res, slong n); + +void _arith_harmonic_number(fmpz_t num, fmpz_t den, slong n); +void arith_harmonic_number(fmpq_t x, slong n); + +void arith_ramanujan_tau(fmpz_t res, const fmpz_t n); +void arith_ramanujan_tau_series(fmpz_poly_t res, slong n); + +void arith_divisors(fmpz_poly_t res, const fmpz_t n); +void arith_divisor_sigma(fmpz_t res, const fmpz_t n, ulong k); + +int arith_moebius_mu(const fmpz_t n); + +void arith_euler_phi(fmpz_t res, const fmpz_t n); + +/* Stirling numbers **********************************************************/ + +void arith_stirling_number_1u(fmpz_t s, slong n, slong k); +void arith_stirling_number_1(fmpz_t s, slong n, slong k); +void arith_stirling_number_2(fmpz_t s, slong n, slong k); + +void arith_stirling_number_1u_vec(fmpz * row, slong n, slong klen); +void arith_stirling_number_1_vec(fmpz * row, slong n, slong klen); +void arith_stirling_number_2_vec(fmpz * row, slong n, slong klen); + +void arith_stirling_number_1u_vec_next(fmpz * row, + const fmpz * prev, slong n, slong klen); +void arith_stirling_number_1_vec_next(fmpz * row, + const fmpz * prev, slong n, slong klen); +void arith_stirling_number_2_vec_next(fmpz * row, + const fmpz * prev, slong n, slong klen); + +void arith_stirling_matrix_1u(fmpz_mat_t mat); +void arith_stirling_matrix_1(fmpz_mat_t mat); +void arith_stirling_matrix_2(fmpz_mat_t mat); + +/* Bell numbers **************************************************************/ + +#if FLINT64 +#define BELL_NUMBER_TAB_SIZE 26 +#else +#define BELL_NUMBER_TAB_SIZE 16 +#endif + +extern const mp_limb_t bell_number_tab[]; + +double arith_bell_number_size(ulong n); + +void arith_bell_number(fmpz_t b, ulong n); +void arith_bell_number_bsplit(fmpz_t res, ulong n); +void arith_bell_number_multi_mod(fmpz_t res, ulong n); + +void arith_bell_number_vec(fmpz * b, slong n); +void arith_bell_number_vec_recursive(fmpz * b, slong n); +void arith_bell_number_vec_multi_mod(fmpz * b, slong n); + +mp_limb_t arith_bell_number_nmod(ulong n, nmod_t mod); + +void arith_bell_number_nmod_vec(mp_ptr b, slong n, nmod_t mod); +void arith_bell_number_nmod_vec_recursive(mp_ptr b, slong n, nmod_t mod); +void arith_bell_number_nmod_vec_series(mp_ptr b, slong n, nmod_t mod); + + +/* Euler numbers *************************************************************/ + +#if FLINT64 +#define SMALL_EULER_LIMIT 25 +#else +#define SMALL_EULER_LIMIT 15 +#endif + +static const mp_limb_t euler_number_small[] = { + UWORD(1), UWORD(1), UWORD(5), UWORD(61), UWORD(1385), UWORD(50521), UWORD(2702765), + UWORD(199360981), +#if FLINT64 + UWORD(19391512145), UWORD(2404879675441), UWORD(370371188237525), + UWORD(69348874393137901), UWORD(15514534163557086905) +#endif +}; + +double arith_euler_number_size(ulong n); + +void arith_euler_number_vec(fmpz * res, slong n); + +void _arith_euler_number_zeta(fmpz_t res, ulong n); +void arith_euler_number(fmpz_t res, ulong n); + +void arith_euler_polynomial(fmpq_poly_t poly, ulong n); + +/* Bernoulli numbers *********************************************************/ + +#if FLINT64 +#define BERNOULLI_SMALL_NUMER_LIMIT 35 +#else +#define BERNOULLI_SMALL_NUMER_LIMIT 27 +#endif + +static const slong _bernoulli_numer_small[] = { + WORD(1), WORD(1), WORD(-1), WORD(1), WORD(-1), WORD(5), WORD(-691), WORD(7), WORD(-3617), WORD(43867), WORD(-174611), WORD(854513), + WORD(-236364091), WORD(8553103), +#if FLINT64 + WORD(-23749461029), WORD(8615841276005), WORD(-7709321041217), WORD(2577687858367) +#endif +}; + +void _arith_bernoulli_number(fmpz_t num, fmpz_t den, ulong n); +void arith_bernoulli_number(fmpq_t x, ulong n); + +void _arith_bernoulli_number_vec(fmpz * num, fmpz * den, slong n); +void arith_bernoulli_number_vec(fmpq * num, slong n); + +void arith_bernoulli_number_denom(fmpz_t den, ulong n); +double arith_bernoulli_number_size(ulong n); + +void arith_bernoulli_polynomial(fmpq_poly_t poly, ulong n); + +void _arith_bernoulli_number_zeta(fmpz_t num, fmpz_t den, ulong n); +void _arith_bernoulli_number_vec_multi_mod(fmpz * num, fmpz * den, slong n); +void _arith_bernoulli_number_vec_recursive(fmpz * num, fmpz * den, slong n); +void _arith_bernoulli_number_vec_zeta(fmpz * num, fmpz * den, slong n); + +/* Cyclotomic polynomials ****************************************************/ + +void _arith_cyclotomic_polynomial(fmpz * a, ulong n, mp_ptr factors, + slong num_factors, ulong phi); +void arith_cyclotomic_polynomial(fmpz_poly_t poly, ulong n); + +void _arith_cos_minpoly(fmpz * coeffs, slong d, ulong n); +void arith_cos_minpoly(fmpz_poly_t poly, ulong n); + +/* Hypergeometric polynomials ************************************************/ + +void arith_legendre_polynomial(fmpq_poly_t poly, ulong n); +void arith_chebyshev_t_polynomial(fmpz_poly_t poly, ulong n); +void arith_chebyshev_u_polynomial(fmpz_poly_t poly, ulong n); + +/* Swinnerton-Dyer polynomials ***********************************************/ + +void arith_swinnerton_dyer_polynomial(fmpz_poly_t poly, ulong n); + +/* Landau function ***********************************************************/ + +void arith_landau_function_vec(fmpz * res, slong len); + +/* Dedekind sums *************************************************************/ + +void arith_dedekind_sum_naive(fmpq_t s, const fmpz_t h, const fmpz_t k); +double arith_dedekind_sum_coprime_d(double h, double k); +void arith_dedekind_sum_coprime_large(fmpq_t s, const fmpz_t h, const fmpz_t k); +void arith_dedekind_sum_coprime(fmpq_t s, const fmpz_t h, const fmpz_t k); +void arith_dedekind_sum(fmpq_t s, const fmpz_t h, const fmpz_t k); + +/* Exponential sums **********************************************************/ + +typedef struct +{ + int n; + int prefactor; + mp_limb_t sqrt_p; + mp_limb_t sqrt_q; + mp_limb_signed_t cos_p[FLINT_BITS]; + mp_limb_t cos_q[FLINT_BITS]; +} trig_prod_struct; + +typedef trig_prod_struct trig_prod_t[1]; + +static __inline__ +void trig_prod_init(trig_prod_t sum) +{ + sum->n = 0; + sum->prefactor = 1; + sum->sqrt_p = 1; + sum->sqrt_q = 1; +} + +void arith_hrr_expsum_factored(trig_prod_t prod, mp_limb_t k, mp_limb_t n); + +/* Number of partitions ******************************************************/ + +void arith_number_of_partitions_nmod_vec(mp_ptr res, slong len, nmod_t mod); +void arith_number_of_partitions_vec(fmpz * res, slong len); +void arith_number_of_partitions_mpfr(mpfr_t x, ulong n); +void arith_number_of_partitions(fmpz_t x, ulong n); + +/* Number of sums of squares representations *********************************/ + +void arith_sum_of_squares(fmpz_t r, ulong k, const fmpz_t n); +void arith_sum_of_squares_vec(fmpz * r, ulong k, slong n); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/flint-2.4.3/arith/bell_number.c b/external/flint-2.4.3/arith/bell_number.c new file mode 100644 index 0000000..31a4190 --- /dev/null +++ b/external/flint-2.4.3/arith/bell_number.c @@ -0,0 +1,37 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "arith.h" + +void +arith_bell_number(fmpz_t b, ulong n) +{ + if (n < BELL_NUMBER_TAB_SIZE) + fmpz_set_ui(b, bell_number_tab[n]); + else if (n < 5000) + arith_bell_number_bsplit(b, n); + else + arith_bell_number_multi_mod(b, n); +} diff --git a/external/flint-2.4.3/arith/bell_number_bsplit.c b/external/flint-2.4.3/arith/bell_number_bsplit.c new file mode 100644 index 0000000..217ffa9 --- /dev/null +++ b/external/flint-2.4.3/arith/bell_number_bsplit.c @@ -0,0 +1,124 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "arith.h" + + +static slong +_bell_series_cutoff(slong n) +{ + double N, log_N, log_pow, log_fac; + + N = n; + log_N = (N==0 ? 0 : log(N)); + log_pow = n * log_N; + log_fac = N*log_N - N; + while (log_pow - log_fac >= -2) + { + N++; + log_N = log(N); + log_pow = n * log_N; + log_fac += log_N; + } + return N; +} + +static void +_mpz_bell_bsplit(mpz_t P, mpz_t Q, slong a, slong b, slong n, slong bmax) +{ + if (b - a < 20) + { + mpz_t u; + slong k; + mpz_init(u); + flint_mpz_set_ui(P, UWORD(0)); + flint_mpz_set_ui(Q, UWORD(0)); + flint_mpz_set_ui(Q, (b - 1 == bmax) ? UWORD(1) : b); + for (k = b - 1; k >= a; k--) + { + flint_mpz_set_ui(u, k); + flint_mpz_pow_ui(u, u, n); + mpz_addmul(P, Q, u); + if (k != a) + flint_mpz_mul_ui(Q, Q, k); + } + mpz_clear(u); + } + else + { + slong m; + mpz_t P1, Q2; + m = (a + b) / 2; + mpz_init(P1); + mpz_init(Q2); + _mpz_bell_bsplit(P1, Q, a, m, n, bmax); + _mpz_bell_bsplit(P, Q2, m, b, n, bmax); + mpz_mul(Q, Q, Q2); + mpz_addmul(P, P1, Q2); + mpz_clear(P1); + mpz_clear(Q2); + } +} + +void +arith_bell_number_bsplit(fmpz_t b, ulong n) +{ + slong N; + mp_bitcnt_t prec; + mpz_t P, Q; + mpfr_t Pf, Qf, E, one; + + N = _bell_series_cutoff(n); + + mpz_init(P); + mpz_init(Q); + + _mpz_bell_bsplit(P, Q, 1, N + 1, n, N); + + prec = mpz_sizeinbase(P, 2) - mpz_sizeinbase(Q, 2) + 10; + + mpfr_init2(Pf, prec); + mpfr_init2(Qf, prec); + mpfr_init2(E, prec); + mpfr_init2(one, 2); + + mpfr_set_z(Pf, P, GMP_RNDN); + mpfr_set_z(Qf, Q, GMP_RNDN); + mpfr_set_ui(one, 1, GMP_RNDN); + mpfr_exp(E, one, GMP_RNDN); + mpfr_mul(Qf, Qf, E, GMP_RNDN); + mpfr_div(Pf, Pf, Qf, GMP_RNDN); + mpfr_get_z(P, Pf, GMP_RNDN); + + fmpz_set_mpz(b, P); + + mpfr_clear(one); + mpfr_clear(Pf); + mpfr_clear(Qf); + mpfr_clear(E); + mpz_clear(P); + mpz_clear(Q); +} diff --git a/external/flint-2.4.3/arith/bell_number_multi_mod.c b/external/flint-2.4.3/arith/bell_number_multi_mod.c new file mode 100644 index 0000000..11a924a --- /dev/null +++ b/external/flint-2.4.3/arith/bell_number_multi_mod.c @@ -0,0 +1,65 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "arith.h" + +void +arith_bell_number_multi_mod(fmpz_t res, ulong n) +{ + fmpz_comb_temp_t temp; + fmpz_comb_t comb; + nmod_t mod; + mp_ptr primes, residues; + slong k, num_primes; + mp_bitcnt_t size, prime_bits; + + size = arith_bell_number_size(n); + prime_bits = FLINT_BITS - 1; + num_primes = (size + prime_bits - 1) / prime_bits; + + primes = flint_malloc(num_primes * sizeof(mp_limb_t)); + residues = flint_malloc(num_primes * sizeof(mp_limb_t)); + + primes[0] = n_nextprime(UWORD(1) << prime_bits, 0); + for (k = 1; k < num_primes; k++) + primes[k] = n_nextprime(primes[k-1], 0); + + for (k = 0; k < num_primes; k++) + { + nmod_init(&mod, primes[k]); + residues[k] = arith_bell_number_nmod(n, mod); + } + + fmpz_comb_init(comb, primes, num_primes); + fmpz_comb_temp_init(temp, comb); + + fmpz_multi_CRT_ui(res, residues, comb, temp, 0); + + fmpz_comb_clear(comb); + fmpz_comb_temp_clear(temp); + + flint_free(primes); + flint_free(residues); +} diff --git a/external/flint-2.4.3/arith/bell_number_nmod.c b/external/flint-2.4.3/arith/bell_number_nmod.c new file mode 100644 index 0000000..ec3a3eb --- /dev/null +++ b/external/flint-2.4.3/arith/bell_number_nmod.c @@ -0,0 +1,110 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "arith.h" + +const mp_limb_t bell_number_tab[] = +{ + UWORD(1), UWORD(1), UWORD(2), UWORD(5), UWORD(15), UWORD(52), UWORD(203), UWORD(877), UWORD(4140), UWORD(21147), UWORD(115975), + UWORD(678570), UWORD(4213597), UWORD(27644437), UWORD(190899322), UWORD(1382958545), +#if FLINT64 + UWORD(10480142147), UWORD(82864869804), UWORD(682076806159), UWORD(5832742205057), + UWORD(51724158235372), UWORD(474869816156751), UWORD(4506715738447323), + UWORD(44152005855084346), UWORD(445958869294805289), + UWORD(4638590332229999353), +#endif +}; + +static const char bell_mod_2[3] = {1, 1, 0}; +static const char bell_mod_3[13] = {1, 1, 2, 2, 0, 1, 2, 1, 0, 0, 1, 0, 1}; + +mp_limb_t +arith_bell_number_nmod(ulong n, nmod_t mod) +{ + mp_limb_t s, t, u; + mp_ptr facs, pows; + slong i, j; + + if (n < BELL_NUMBER_TAB_SIZE) + return n_mod2_preinv(bell_number_tab[n], mod.n, mod.ninv); + + if (mod.n == 2) return bell_mod_2[n % 3]; + if (mod.n == 3) return bell_mod_3[n % 13]; + + if (mod.n <= n) + { + mp_ptr bvec = flint_malloc(sizeof(mp_limb_t) * (n + 1)); + arith_bell_number_nmod_vec_recursive(bvec, n + 1, mod); + s = bvec[n]; + flint_free(bvec); + return s; + } + + /* Compute inverse factorials */ + /* We actually compute (n! / i!) and divide out (n!)^2 at the end */ + facs = flint_malloc(sizeof(mp_limb_t) * (n + 1)); + facs[n] = 1; + for (i = n - 1; i >= 0; i--) + facs[i] = n_mulmod2_preinv(facs[i + 1], i + 1, mod.n, mod.ninv); + + /* Compute powers */ + pows = flint_calloc(n + 1, sizeof(mp_limb_t)); + pows[0] = n_powmod2_ui_preinv(0, n, mod.n, mod.ninv); + pows[1] = n_powmod2_ui_preinv(1, n, mod.n, mod.ninv); + + for (i = 2; i <= n; i++) + { + if (pows[i] == 0) + pows[i] = n_powmod2_ui_preinv(i, n, mod.n, mod.ninv); + + for (j = 2; j <= i && i * j <= n; j++) + if (pows[i * j] == 0) + pows[i * j] = n_mulmod2_preinv(pows[i], + pows[j], mod.n, mod.ninv); + } + + for (s = t = i = 0; i <= n; i++) + { + if (i % 2 == 0) + t = n_addmod(t, facs[i], mod.n); + else + t = n_submod(t, facs[i], mod.n); + + u = pows[n - i]; + u = n_mulmod2_preinv(u, facs[n - i], mod.n, mod.ninv); + u = n_mulmod2_preinv(u, t, mod.n, mod.ninv); + s = n_addmod(s, u, mod.n); + } + + /* Remove (n!)^2 */ + u = n_invmod(facs[0], mod.n); + u = n_mulmod2_preinv(u, u, mod.n, mod.ninv); + s = n_mulmod2_preinv(s, u, mod.n, mod.ninv); + + flint_free(facs); + flint_free(pows); + + return s; +} diff --git a/external/flint-2.4.3/arith/bell_number_nmod_vec.c b/external/flint-2.4.3/arith/bell_number_nmod_vec.c new file mode 100644 index 0000000..1180363 --- /dev/null +++ b/external/flint-2.4.3/arith/bell_number_nmod_vec.c @@ -0,0 +1,35 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "arith.h" + +void +arith_bell_number_nmod_vec(mp_ptr b, slong n, nmod_t mod) +{ + if (n < 2000 || mod.n <= n) + arith_bell_number_nmod_vec_recursive(b, n, mod); + else + arith_bell_number_nmod_vec_series(b, n, mod); +} diff --git a/external/flint-2.4.3/arith/bell_number_nmod_vec_recursive.c b/external/flint-2.4.3/arith/bell_number_nmod_vec_recursive.c new file mode 100644 index 0000000..59a9651 --- /dev/null +++ b/external/flint-2.4.3/arith/bell_number_nmod_vec_recursive.c @@ -0,0 +1,56 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "arith.h" + +void +arith_bell_number_nmod_vec_recursive(mp_ptr b, slong n, nmod_t mod) +{ + slong i, k; + mp_ptr t; + + if (n < BELL_NUMBER_TAB_SIZE) + { + for (i = 0; i < n; i++) + b[i] = n_mod2_preinv(bell_number_tab[i], mod.n, mod.ninv); + return; + } + + n -= 1; + t = _nmod_vec_init(n); + + t[0] = b[0] = b[1] = 1; + + for (i = 1; i < n; i++) + { + t[i] = t[0]; + for (k = i; k > 0; k--) + t[k - 1] = n_addmod(t[k - 1], t[k], mod.n); + + b[i + 1] = t[0]; + } + + _nmod_vec_clear(t); +} diff --git a/external/flint-2.4.3/arith/bell_number_nmod_vec_series.c b/external/flint-2.4.3/arith/bell_number_nmod_vec_series.c new file mode 100644 index 0000000..8939380 --- /dev/null +++ b/external/flint-2.4.3/arith/bell_number_nmod_vec_series.c @@ -0,0 +1,62 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "arith.h" + +void +arith_bell_number_nmod_vec_series(mp_ptr res, slong n, nmod_t mod) +{ + mp_limb_t fac, c; + mp_ptr tmp; + slong k; + + if (n < 1) + return; + + tmp = flint_malloc(sizeof(mp_limb_t) * n); + + /* Divide by factorials */ + fac = n_factorial_mod2_preinv(n-1, mod.n, mod.ninv); + c = n_invmod(fac, mod.n); + + for (k = n - 1; k > 0; k--) + { + tmp[k] = c; + c = n_mulmod2_preinv(c, k, mod.n, mod.ninv); + } + tmp[0] = UWORD(0); + + _nmod_poly_exp_series(res, tmp, n, mod); + + /* Multiply by factorials */ + c = UWORD(1); + for (k = 1; k < n; k++) + { + c = n_mulmod2_preinv(c, k, mod.n, mod.ninv); + res[k] = n_mulmod2_preinv(res[k], c, mod.n, mod.ninv); + } + + flint_free(tmp); +} diff --git a/external/flint-2.4.3/arith/bell_number_size.c b/external/flint-2.4.3/arith/bell_number_size.c new file mode 100644 index 0000000..85a01a0 --- /dev/null +++ b/external/flint-2.4.3/arith/bell_number_size.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" + +double +arith_bell_number_size(ulong n) +{ + if (n == 0) + return 2; + + return n * log(0.792 * n/log(n+1)) * 1.44269504088896 + 2; +} diff --git a/external/flint-2.4.3/arith/bell_number_vec.c b/external/flint-2.4.3/arith/bell_number_vec.c new file mode 100644 index 0000000..47ae571 --- /dev/null +++ b/external/flint-2.4.3/arith/bell_number_vec.c @@ -0,0 +1,35 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "arith.h" + +void +arith_bell_number_vec(fmpz * res, slong n) +{ + if (n < 5000) + arith_bell_number_vec_recursive(res, n); + else + arith_bell_number_vec_multi_mod(res, n); +} diff --git a/external/flint-2.4.3/arith/bell_number_vec_multi_mod.c b/external/flint-2.4.3/arith/bell_number_vec_multi_mod.c new file mode 100644 index 0000000..7ee4a35 --- /dev/null +++ b/external/flint-2.4.3/arith/bell_number_vec_multi_mod.c @@ -0,0 +1,105 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "nmod_poly.h" +#include "arith.h" + +#define CRT_MAX_RESOLUTION 16 + +void +arith_bell_number_vec_multi_mod(fmpz * res, slong n) +{ + fmpz_comb_t comb[CRT_MAX_RESOLUTION]; + fmpz_comb_temp_t temp[CRT_MAX_RESOLUTION]; + mp_ptr primes, residues; + mp_ptr * polys; + nmod_t mod; + slong i, j, k, num_primes, num_primes_k, resolution; + mp_bitcnt_t size, prime_bits; + + if (n < 1) + return; + + resolution = FLINT_MAX(1, FLINT_MIN(CRT_MAX_RESOLUTION, n / 16)); + + size = arith_bell_number_size(n); + prime_bits = FLINT_BITS - 1; + num_primes = (size + prime_bits - 1) / prime_bits; + + primes = flint_malloc(num_primes * sizeof(mp_limb_t)); + residues = flint_malloc(num_primes * sizeof(mp_limb_t)); + polys = flint_malloc(num_primes * sizeof(mp_ptr)); + + /* Compute Bell numbers mod p */ + primes[0] = n_nextprime(UWORD(1)<num_primes >= num_primes_k) + break; + } + num_primes_k = comb[i]->num_primes; + for (j = 0; j < num_primes_k; j++) + residues[j] = polys[j][k]; + fmpz_multi_CRT_ui(res + k, residues, comb[i], temp[i], 0); + } + + /* Cleanup */ + for (k = 0; k < num_primes; k++) + _nmod_vec_clear(polys[k]); + + for (i = 0; i < resolution; i++) + { + fmpz_comb_temp_clear(temp[i]); + fmpz_comb_clear(comb[i]); + } + + flint_free(primes); + flint_free(residues); + flint_free(polys); +} diff --git a/external/flint-2.4.3/arith/bell_number_vec_recursive.c b/external/flint-2.4.3/arith/bell_number_vec_recursive.c new file mode 100644 index 0000000..0e947ea --- /dev/null +++ b/external/flint-2.4.3/arith/bell_number_vec_recursive.c @@ -0,0 +1,57 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "arith.h" + +void +arith_bell_number_vec_recursive(fmpz * b, slong n) +{ + slong i, k; + fmpz * t; + + if (n < BELL_NUMBER_TAB_SIZE) + { + for (i = 0; i < n; i++) + fmpz_set_ui(b + i, bell_number_tab[i]); + return; + } + + n -= 1; + t = _fmpz_vec_init(n); + + fmpz_one(t); + fmpz_one(b); + fmpz_one(b + 1); + + for (i = 1; i < n; i++) + { + fmpz_set(t + i, t); + for (k = i; k > 0; k--) + fmpz_add(t + k - 1, t + k - 1, t + k); + fmpz_set(b + i + 1, t); + } + + _fmpz_vec_clear(t, n); +} diff --git a/external/flint-2.4.3/arith/bernoulli_number.c b/external/flint-2.4.3/arith/bernoulli_number.c new file mode 100644 index 0000000..62bfd92 --- /dev/null +++ b/external/flint-2.4.3/arith/bernoulli_number.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "arith.h" + +void _arith_bernoulli_number(fmpz_t num, fmpz_t den, ulong n) +{ + _arith_bernoulli_number_zeta(num, den, n); +} + +void arith_bernoulli_number(fmpq_t x, ulong n) +{ + _arith_bernoulli_number(fmpq_numref(x), fmpq_denref(x), n); +} diff --git a/external/flint-2.4.3/arith/bernoulli_number_denom.c b/external/flint-2.4.3/arith/bernoulli_number_denom.c new file mode 100644 index 0000000..75421a6 --- /dev/null +++ b/external/flint-2.4.3/arith/bernoulli_number_denom.c @@ -0,0 +1,80 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "arith.h" + +#define BERNOULLI_DENOM_MAX_SMALL 178 + +#if FLINT64 +#define __u32 unsigned int +#else +#define __u32 mp_limb_t +#endif + +static const __u32 __bernoulli_denom_small[] = +{ + UWORD(1), UWORD(6), UWORD(30), UWORD(42), UWORD(30), UWORD(66), UWORD(2730), UWORD(6), UWORD(510), UWORD(798), UWORD(330), + UWORD(138), UWORD(2730), UWORD(6), UWORD(870), UWORD(14322), UWORD(510), UWORD(6), UWORD(1919190), UWORD(6), UWORD(13530), + UWORD(1806), UWORD(690), UWORD(282), UWORD(46410), UWORD(66), UWORD(1590), UWORD(798), UWORD(870), UWORD(354), + UWORD(56786730), UWORD(6), UWORD(510), UWORD(64722), UWORD(30), UWORD(4686), UWORD(140100870), UWORD(6), UWORD(30), + UWORD(3318), UWORD(230010), UWORD(498), UWORD(3404310), UWORD(6), UWORD(61410), UWORD(272118), UWORD(1410), UWORD(6), + UWORD(4501770), UWORD(6), UWORD(33330), UWORD(4326), UWORD(1590), UWORD(642), UWORD(209191710), UWORD(1518), + UWORD(1671270), UWORD(42), UWORD(1770), UWORD(6), UWORD(2328255930), UWORD(6), UWORD(30), UWORD(4357878), UWORD(510), + UWORD(8646), UWORD(4206930), UWORD(6), UWORD(4110), UWORD(274386), UWORD(679470), UWORD(6), UWORD(2381714790), + UWORD(6), UWORD(4470), UWORD(2162622), UWORD(30), UWORD(138), UWORD(1794590070), UWORD(6), UWORD(230010), + UWORD(130074), UWORD(2490), UWORD(1002), UWORD(3404310), UWORD(66), UWORD(5190), UWORD(2478), UWORD(1043970), + UWORD(1074), +}; + +void arith_bernoulli_number_denom(fmpz_t den, ulong n) +{ + slong i; + mp_limb_t p; + const mp_limb_t * primes; + + if (n % 2 == 1) + { + fmpz_set_ui(den, 1 + (n == 1)); + } + else if (n <= BERNOULLI_DENOM_MAX_SMALL) + { + fmpz_set_ui(den, __bernoulli_denom_small[n / 2]); + } + else + { + n_prime_pi_bounds(&p, &p, n); + primes = n_primes_arr_readonly(p + 1); + + fmpz_set_ui(den, UWORD(6)); + for (i = 2; i < n; i++) + { + p = primes[i]; + if (p - 1 > n) + break; + if (n % (p - 1) == 0) + fmpz_mul_ui(den, den, p); + } + } +} diff --git a/external/flint-2.4.3/arith/bernoulli_number_size.c b/external/flint-2.4.3/arith/bernoulli_number_size.c new file mode 100644 index 0000000..bc2ccd8 --- /dev/null +++ b/external/flint-2.4.3/arith/bernoulli_number_size.c @@ -0,0 +1,41 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "arith.h" + +double arith_bernoulli_number_size(ulong n) +{ + double x; + + /* |B_n| < 2 */ + if (n <= 14) + return 1.0; + + x = 2 + (n + 1) * log(n + 1) * 1.44269504088897; /* 1/log(2) */ + x -= n * 4.0941911703612822; /* log2(2*pi*e) */ + + return x + 2; +} diff --git a/external/flint-2.4.3/arith/bernoulli_number_vec.c b/external/flint-2.4.3/arith/bernoulli_number_vec.c new file mode 100644 index 0000000..5d55140 --- /dev/null +++ b/external/flint-2.4.3/arith/bernoulli_number_vec.c @@ -0,0 +1,59 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "arith.h" + +void _arith_bernoulli_number_vec(fmpz * num, fmpz * den, slong n) +{ + if (n < 700) + _arith_bernoulli_number_vec_recursive(num, den, n); + else if (n < 3900) + _arith_bernoulli_number_vec_zeta(num, den, n); + else + _arith_bernoulli_number_vec_multi_mod(num, den, n); +} + +void arith_bernoulli_number_vec(fmpq * x, slong n) +{ + fmpz * num, * den; + slong i; + + if (n <= 0) + return; + + num = _fmpz_vec_init(n * 2); + den = num + n; + + _arith_bernoulli_number_vec(num, den, n); + + for (i = 0; i < n; i++) + { + fmpz_swap(num + i, fmpq_numref(x + i)); + fmpz_swap(den + i, fmpq_denref(x + i)); + } + + _fmpz_vec_clear(num, n * 2); +} + diff --git a/external/flint-2.4.3/arith/bernoulli_number_vec_multi_mod.c b/external/flint-2.4.3/arith/bernoulli_number_vec_multi_mod.c new file mode 100644 index 0000000..561d741 --- /dev/null +++ b/external/flint-2.4.3/arith/bernoulli_number_vec_multi_mod.c @@ -0,0 +1,150 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "arith.h" + +static void +__bernoulli_number_vec_mod_p(mp_ptr res, mp_ptr tmp, const fmpz * den, + slong m, nmod_t mod) +{ + mp_limb_t fac, c, t; + slong k; + + /* x^2/(cosh(x)-1) = \sum_{k=0}^{\infty} 2(1-2k)/(2k)! B_2k x^(2k) */ + + /* Divide by factorials */ + fac = n_factorial_mod2_preinv(2*m, mod.n, mod.ninv); + c = n_invmod(fac, mod.n); + for (k = m - 1; k >= 0; k--) + { + tmp[k] = c; + c = n_mulmod2_preinv(c, (2*k+1)*(2*k+2), mod.n, mod.ninv); + } + + _nmod_poly_inv_series(res, tmp, m, mod); + res[0] = UWORD(1); + + /* N_(2k) = -1 * D_(2k) * (2k)! / (2k-1) */ + c = n_negmod(UWORD(1), mod.n); + for (k = 1; k < m; k++) + { + t = fmpz_fdiv_ui(den + 2*k, mod.n); + t = n_mulmod2_preinv(c, t, mod.n, mod.ninv); + res[k] = n_mulmod2_preinv(res[k], t, mod.n, mod.ninv); + c = n_mulmod2_preinv(c, 2*(k+1)*(2*k-1), mod.n, mod.ninv); + } +} + +#define CRT_MAX_RESOLUTION 16 + +void _arith_bernoulli_number_vec_multi_mod(fmpz * num, fmpz * den, slong n) +{ + fmpz_comb_t comb[CRT_MAX_RESOLUTION]; + fmpz_comb_temp_t temp[CRT_MAX_RESOLUTION]; + mp_limb_t * primes; + mp_limb_t * residues; + mp_ptr * polys; + mp_ptr temppoly; + nmod_t mod; + slong i, j, k, m, num_primes, num_primes_k, resolution; + mp_bitcnt_t size, prime_bits; + + if (n < 1) + return; + + for (i = 0; i < n; i++) + arith_bernoulli_number_denom(den + i, i); + + /* Number of nonzero entries (apart from B_1) */ + m = (n + 1) / 2; + resolution = FLINT_MAX(1, FLINT_MIN(CRT_MAX_RESOLUTION, m / 16)); + + /* Note that the denominators must be accounted for */ + size = arith_bernoulli_number_size(n) + _fmpz_vec_max_bits(den, n) + 2; + + prime_bits = FLINT_BITS - 1; + num_primes = (size + prime_bits - 1) / prime_bits; + + primes = flint_malloc(num_primes * sizeof(mp_limb_t)); + residues = flint_malloc(num_primes * sizeof(mp_limb_t)); + polys = flint_malloc(num_primes * sizeof(mp_ptr)); + + /* Compute Bernoulli numbers mod p */ + primes[0] = n_nextprime(UWORD(1)< 1) + fmpz_set_si(num + 1, WORD(-1)); + for (k = 3; k < n; k += 2) + fmpz_zero(num + k); + + /* Reconstruction */ + for (k = 0; k < n; k += 2) + { + size = arith_bernoulli_number_size(k) + fmpz_bits(den + k) + 2; + /* Use only as large a comb as needed */ + num_primes_k = (size + prime_bits - 1) / prime_bits; + for (i = 0; i < resolution; i++) + { + if (comb[i]->num_primes >= num_primes_k) + break; + } + num_primes_k = comb[i]->num_primes; + for (j = 0; j < num_primes_k; j++) + residues[j] = polys[j][k / 2]; + fmpz_multi_CRT_ui(num + k, residues, comb[i], temp[i], 1); + } + + /* Cleanup */ + for (k = 0; k < num_primes; k++) + _nmod_vec_clear(polys[k]); + _nmod_vec_clear(temppoly); + for (i = 0; i < resolution; i++) + { + fmpz_comb_temp_clear(temp[i]); + fmpz_comb_clear(comb[i]); + } + + flint_free(primes); + flint_free(residues); + flint_free(polys); +} diff --git a/external/flint-2.4.3/arith/bernoulli_number_vec_recursive.c b/external/flint-2.4.3/arith/bernoulli_number_vec_recursive.c new file mode 100644 index 0000000..bdac4a2 --- /dev/null +++ b/external/flint-2.4.3/arith/bernoulli_number_vec_recursive.c @@ -0,0 +1,165 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "arith.h" + +static void +__ramanujan_even_common_denom(fmpz * num, fmpz * den, slong start, slong n) +{ + fmpz_t t, c, d, cden; + slong j, k, m, mcase; + int prodsize; + + if (start >= n) + return; + + fmpz_init(t); + fmpz_init(c); + fmpz_init(d); + fmpz_init(cden); + + /* Common denominator */ + arith_primorial(cden, n + 1); + + start += start % 2; + + /* Convert initial values to common denominator */ + for (k = 0; k < start; k += 2) + { + fmpz_divexact(t, cden, den + k); + fmpz_mul(num + k, num + k, t); + } + + /* Ramanujan's recursive formula */ + for (m = start; m < n; m += 2) + { + mcase = m % 6; + + fmpz_mul_ui(num + m, cden, m + UWORD(3)); + fmpz_divexact_ui(num + m, num + m, UWORD(3)); + + if (mcase == 4) + { + fmpz_neg(num + m, num + m); + fmpz_divexact_ui(num + m, num + m, UWORD(2)); + } + + /* All factors are strictly smaller than m + 4; choose prodsize such + that (m + 4)^prodsize fits in an slong. */ + { +#if FLINT64 + if (m < WORD(1444)) prodsize = 6; + else if (m < WORD(2097148)) prodsize = 3; + else if (m < WORD(3037000495)) prodsize = 2; /* not very likely... */ + else abort(); +#else + if (m < WORD(32)) prodsize = 6; + else if (m < WORD(1286)) prodsize = 3; + else if (m < WORD(46336)) prodsize = 2; + else abort(); +#endif + } + + /* c = t = binomial(m+3, m) */ + fmpz_set_ui(t, m + UWORD(1)); + fmpz_mul_ui(t, t, m + UWORD(2)); + fmpz_mul_ui(t, t, m + UWORD(3)); + fmpz_divexact_ui(t, t, UWORD(6)); + fmpz_set(c, t); + + for (j = 6; j <= m; j += 6) + { + slong r = m - j; + + /* c = binomial(m+3, m-j); */ + switch (prodsize) + { + case 2: + fmpz_mul_ui(c, c, (r+6)*(r+5)); + fmpz_mul_ui(c, c, (r+4)*(r+3)); + fmpz_mul_ui(c, c, (r+2)*(r+1)); + fmpz_set_ui(d, (j+0)*(j+3)); + fmpz_mul_ui(d, d, (j-2)*(j+2)); + fmpz_mul_ui(d, d, (j-1)*(j+1)); + fmpz_divexact(c, c, d); + break; + + case 3: + fmpz_mul_ui(c, c, (r+6)*(r+5)*(r+4)); + fmpz_mul_ui(c, c, (r+3)*(r+2)*(r+1)); + fmpz_set_ui(d, (j+0)*(j+3)*(j-2)); + fmpz_mul_ui(d, d, (j+2)*(j-1)*(j+1)); + fmpz_divexact(c, c, d); + break; + + case 6: + fmpz_mul_ui(c, c, (r+6)*(r+5)*(r+4)*(r+3)*(r+2)*(r+1)); + fmpz_divexact_ui(c, c, (j+0)*(j+3)*(j-2)*(j+2)*(j-1)*(j+1)); + break; + } + + fmpz_submul(num + m, c, num + (m - j)); + } + fmpz_divexact(num + m, num + m, t); + } + + /* Convert to separate denominators */ + for (k = 0; k < n; k += 2) + { + arith_bernoulli_number_denom(den + k, k); + fmpz_divexact(t, cden, den + k); + fmpz_divexact(num + k, num + k, t); + } + + fmpz_clear(t); + fmpz_clear(c); + fmpz_clear(d); + fmpz_clear(cden); +} + +void _arith_bernoulli_number_vec_recursive(fmpz * num, fmpz * den, slong n) +{ + slong i, start; + fmpz_t t; + fmpz_t d; + + fmpz_init(t); + fmpz_init(d); + + start = FLINT_MIN(BERNOULLI_SMALL_NUMER_LIMIT, n); + + /* Initial values */ + for (i = 0; i < start; i += 2) + _arith_bernoulli_number(num + i, den + i, i); + + __ramanujan_even_common_denom(num, den, start, n); + + /* Odd values */ + for (i = 1; i < n; i += 2) + _arith_bernoulli_number(num + i, den + i, i); + + fmpz_clear(d); + fmpz_clear(t); +} diff --git a/external/flint-2.4.3/arith/bernoulli_number_vec_zeta.c b/external/flint-2.4.3/arith/bernoulli_number_vec_zeta.c new file mode 100644 index 0000000..5bfe847 --- /dev/null +++ b/external/flint-2.4.3/arith/bernoulli_number_vec_zeta.c @@ -0,0 +1,35 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "arith.h" + +void _arith_bernoulli_number_vec_zeta(fmpz * num, fmpz * den, slong n) +{ + slong i; + + /* Go backwards to exploit MPFR cache for pi */ + for (i = n - 1; i >= 0; i--) + _arith_bernoulli_number_zeta(num + i, den + i, i); +} diff --git a/external/flint-2.4.3/arith/bernoulli_number_zeta.c b/external/flint-2.4.3/arith/bernoulli_number_zeta.c new file mode 100644 index 0000000..00db83a --- /dev/null +++ b/external/flint-2.4.3/arith/bernoulli_number_zeta.c @@ -0,0 +1,87 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "arith.h" + +void _arith_bernoulli_number_zeta(fmpz_t num, fmpz_t den, ulong n) +{ + mpz_t r; + mpfr_t t, u, z, pi; + mp_bitcnt_t prec, pi_prec; + + arith_bernoulli_number_denom(den, n); + + if (n % 2) + { + fmpz_set_si(num, -(n == 1)); + return; + } + + if (n < BERNOULLI_SMALL_NUMER_LIMIT) + { + fmpz_set_si(num, _bernoulli_numer_small[n / 2]); + return; + } + + prec = arith_bernoulli_number_size(n) + fmpz_bits(den); + prec += 10 + 2*FLINT_BIT_COUNT(n); + pi_prec = prec; + + mpz_init(r); + mpfr_init2(t, prec); + mpfr_init2(u, prec); + mpfr_init2(z, prec); + mpfr_init2(pi, pi_prec); + + /* t = 2 * n! / (2*pi)^n */ + flint_mpz_fac_ui(r, n); + mpfr_set_z(t, r, GMP_RNDN); + mpfr_mul_2exp(t, t, 1, GMP_RNDN); + mpfr_const_pi(pi, GMP_RNDN); + mpfr_mul_2exp(pi, pi, 1, GMP_RNDN); + mpfr_pow_ui(pi, pi, n, GMP_RNDN); + mpfr_div(t, t, pi, GMP_RNDN); + + /* t = t / zeta(n) */ + mpfr_zeta_inv_euler_product(z, n, 0); + mpfr_div(t, t, z, GMP_RNDN); + + /* round numerator */ + fmpz_get_mpz(r, den); + mpfr_mul_z(t, t, r, GMP_RNDN); + mpfr_round(t, t); + mpfr_get_z(r, t, GMP_RNDN); + fmpz_set_mpz(num, r); + + if (n % 4 == 0) + fmpz_neg(num, num); + + mpz_clear(r); + mpfr_clear(t); + mpfr_clear(u); + mpfr_clear(z); + mpfr_clear(pi); +} + diff --git a/external/flint-2.4.3/arith/bernoulli_polynomial.c b/external/flint-2.4.3/arith/bernoulli_polynomial.c new file mode 100644 index 0000000..a01ff3a --- /dev/null +++ b/external/flint-2.4.3/arith/bernoulli_polynomial.c @@ -0,0 +1,73 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "arith.h" + +void arith_bernoulli_polynomial(fmpq_poly_t poly, ulong n) +{ + fmpz_t t; + fmpz * den; + slong k; + + if (n == 0) + { + fmpq_poly_set_ui(poly, UWORD(1)); + return; + } + + fmpq_poly_fit_length(poly, n + 1); + + fmpz_init(t); + den = _fmpz_vec_init(n + 1); + + _arith_bernoulli_number_vec(poly->coeffs, den, n + 1); + + /* Multiply the odd term by binomial(n,1) = n */ + fmpz_mul_ui(poly->coeffs + 1, poly->coeffs + 1, n); + + /* Multiply even terms by binomial coefficients */ + fmpz_one(t); + for (k = 2; k <= n; k += 2) + { + fmpz_mul2_uiui(t, t, n-k+1, n-k+2); + fmpz_divexact2_uiui(t, t, k, k-1); + fmpz_mul(poly->coeffs + k, poly->coeffs + k, t); + } + + /* Convert to common denominator */ + arith_primorial(poly->den, n + 2); + for (k = 0; k <= n; k++) + { + fmpz_mul(poly->coeffs + k, poly->coeffs+k, poly->den); + fmpz_divexact(poly->coeffs + k, poly->coeffs + k, den + k); + } + + _fmpz_poly_reverse(poly->coeffs, poly->coeffs, n + 1, n + 1); + _fmpq_poly_set_length(poly, n + 1); + fmpq_poly_canonicalise(poly); + + _fmpz_vec_clear(den, n + 1); + fmpz_clear(t); +} diff --git a/external/flint-2.4.3/arith/chebyshev_t_polynomial.c b/external/flint-2.4.3/arith/chebyshev_t_polynomial.c new file mode 100644 index 0000000..f9bc024 --- /dev/null +++ b/external/flint-2.4.3/arith/chebyshev_t_polynomial.c @@ -0,0 +1,72 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "arith.h" + +void +_arith_chebyshev_t_polynomial(fmpz * coeffs, ulong n) +{ + slong k, i, d, m; + + d = n % 2; + + fmpz_zero(coeffs); + fmpz_set_ui(coeffs + d, d ? n : 1); + if (n % 4 >= 2) + fmpz_neg(coeffs + d, coeffs + d); + + m = n / 2; + + for (k = 1; k <= m; k++) + { + i = 2 * k + d; + fmpz_mul2_uiui(coeffs + i, coeffs + i - 2, 4*(m-k+1), n+k-m-1); + fmpz_divexact2_uiui(coeffs + i, coeffs + i, n+2*k-2*m-1, n+2*k-2*m); + fmpz_neg(coeffs + i, coeffs + i); + fmpz_zero(coeffs + i - 1); + } +} + +void +arith_chebyshev_t_polynomial(fmpz_poly_t poly, ulong n) +{ + if (n == 0) + { + fmpz_poly_set_ui(poly, UWORD(1)); + return; + } + + fmpz_poly_fit_length(poly, n + 1); + + if (n == 1) + { + fmpz_zero(poly->coeffs); + fmpz_one(poly->coeffs + 1); + } + else + _arith_chebyshev_t_polynomial(poly->coeffs, n); + + _fmpz_poly_set_length(poly, n + 1); +} diff --git a/external/flint-2.4.3/arith/chebyshev_u_polynomial.c b/external/flint-2.4.3/arith/chebyshev_u_polynomial.c new file mode 100644 index 0000000..48f9308 --- /dev/null +++ b/external/flint-2.4.3/arith/chebyshev_u_polynomial.c @@ -0,0 +1,72 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "arith.h" + +void +_arith_chebyshev_u_polynomial(fmpz * coeffs, ulong n) +{ + slong k, i, d, m; + + d = n % 2; + + fmpz_zero(coeffs); + fmpz_set_ui(coeffs + d, d ? n + 1 : 1); + if (n % 4 >= 2) + fmpz_neg(coeffs + d, coeffs + d); + + m = n / 2; + + for (k = 1; k <= m; k++) + { + i = 2 * k + d; + fmpz_mul2_uiui(coeffs + i, coeffs + i - 2, 4*(m-k+1), n+k-m); + fmpz_divexact2_uiui(coeffs + i, coeffs + i, n+2*k-2*m-1, n+2*k-2*m); + fmpz_neg(coeffs + i, coeffs + i); + fmpz_zero(coeffs + i - 1); + } +} + +void +arith_chebyshev_u_polynomial(fmpz_poly_t poly, ulong n) +{ + if (n == 0) + { + fmpz_poly_set_ui(poly, UWORD(1)); + return; + } + + fmpz_poly_fit_length(poly, n + 1); + + if (n == 1) + { + fmpz_zero(poly->coeffs); + fmpz_set_ui(poly->coeffs + 1, UWORD(2)); + } + else + _arith_chebyshev_u_polynomial(poly->coeffs, n); + + _fmpz_poly_set_length(poly, n + 1); +} diff --git a/external/flint-2.4.3/arith/cyclotomic_cos_polynomial.c b/external/flint-2.4.3/arith/cyclotomic_cos_polynomial.c new file mode 100644 index 0000000..8f937fb --- /dev/null +++ b/external/flint-2.4.3/arith/cyclotomic_cos_polynomial.c @@ -0,0 +1,268 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "arith.h" + +#define MAX_32BIT 58 + +static const int lookup_table[MAX_32BIT][28] = +{ + {-1, 1}, {1, 1}, {1, 2}, {0, 1}, {-1, 2, 4}, {-1, 2}, + {-1, -4, 4, 8}, {-1, 0, 2}, {1, -6, 0, 8}, {-1, -2, 4}, + {1, 6, -12, -32, 16, 32}, {-3, 0, 4}, {-1, 6, 24, -32, -80, 32, 64}, + {1, -4, -4, 8}, {1, 8, -16, -8, 16}, {1, 0, -8, 0, 8}, + {1, -8, -40, 80, 240, -192, -448, 128, 256}, {-1, -6, 0, 8}, + {1, 10, -40, -160, 240, 672, -448, -1024, 256, 512}, {5, 0, -20, 0, 16}, + {1, -16, 32, 48, -96, -32, 64}, {-1, 6, 12, -32, -16, 32}, + {-1, -12, 60, 280, -560, -1792, 1792, 4608, -2304, -5120, 1024, 2048}, + {1, 0, -16, 0, 16}, {-1, 10, 100, -40, -800, 32, 2240, 0, -2560, 0, + 1024}, {-1, -6, 24, 32, -80, -32, 64}, + {1, 18, 0, -240, 0, 864, 0, -1152, 0, 512}, {-7, 0, 56, 0, -112, 0, 64}, + {-1, 14, 112, -448, -2016, 4032, 13440, -15360, -42240, 28160, 67584, + -24576, -53248, 8192, 16384}, {1, -8, -16, 8, 16}, + {-1, -16, 112, 672, -2016, -8064, 13440, 42240, -42240, -112640, 67584, + 159744, -53248, -114688, 16384, 32768}, + {1, 0, -32, 0, 160, 0, -256, 0, 128}, + {1, -24, 48, 344, -688, -1088, 2176, 1280, -2560, -512, 1024}, + {1, 8, -40, -80, 240, 192, -448, -128, 256}, + {1, 16, -160, -368, 1760, 2272, -7232, -5504, 13824, 5632, -12288, + -2048, 4096}, {-3, 0, 36, 0, -96, 0, 64}, + {-1, 18, 180, -960, -5280, 14784, 59136, -101376, -329472, 366080, + 1025024, -745472, -1863680, 860160, 1966080, -524288, -1114112, 131072, + 262144}, {-1, 10, 40, -160, -240, 672, 448, -1024, -256, 512}, + {1, 24, -48, -632, 1264, 3296, -6592, -6784, 13568, 6144, -12288, -2048, + 4096}, {1, 0, -48, 0, 304, 0, -512, 0, 256}, + {1, -20, -220, 1320, 7920, -25344, -109824, 219648, 768768, -1025024, + -3075072, 2795520, 7454720, -4587520, -11141120, 4456448, 10027008, + -2359296, -4980736, 524288, 1048576}, {1, 16, 32, -48, -96, 32, 64}, + {1, 22, -220, -1760, 7920, 41184, -109824, -439296, 768768, 2562560, + -3075072, -8945664, 7454720, 19496960, -11141120, -26738688, 10027008, + 22413312, -4980736, -10485760, 1048576, 2097152}, + {-11, 0, 220, 0, -1232, 0, 2816, 0, -2816, 0, 1024}, + {1, -24, -144, 248, 1680, -864, -7168, 1152, 13824, -512, -12288, 0, + 4096}, {1, -12, -60, 280, 560, -1792, -1792, 4608, 2304, -5120, -1024, + 2048}, {-1, -24, 264, 2288, -11440, -64064, 192192, 823680, -1647360, + -5857280, 8200192, 25346048, -25346048, -70189056, 50135040, 127008768, + -63504384, -149422080, 49807360, 110100480, -22020096, -46137344, + 4194304, 8388608}, {1, 0, -64, 0, 320, 0, -512, 0, 256}, + {-1, 28, 196, -2968, -3136, 66304, 18816, -658816, -53760, 3587584, + 78848, -11741184, -57344, 24084480, 16384, -31195136, 0, 24772608, 0, + -11010048, 0, 2097152}, {-1, -10, 100, 40, -800, -32, 2240, 0, -2560, + 0, 1024}, {1, 32, -64, -1504, 3008, 16832, -33664, -76288, 152576, + 173568, -347136, -210944, 421888, 131072, -262144, -32768, 65536}, + {13, 0, -364, 0, 2912, 0, -9984, 0, 16640, 0, -13312, 0, 4096}, + {-1, 26, 364, -2912, -21840, 96096, 512512, -1464320, -6223360, + 12446720, 44808192, -65175552, -206389248, 222265344, 635043840, + -508035072, -1333592064, 784465920, 1917583360, -807403520, + -1857028096, 530579456, 1157627904, -201326592, -419430400, 33554432, + 67108864}, {-1, 18, 0, -240, 0, 864, 0, -1152, 0, 512}, + {1, 24, -432, -1208, 15216, 28064, -185024, -263424, 1149184, 1250304, + -4177920, -3356672, 9375744, 5324800, -13123584, -4947968, 11141120, + 2490368, -5242880, -524288, 1048576}, + {1, 0, -96, 0, 1376, 0, -6656, 0, 13568, 0, -12288, 0, 4096}, + {1, -40, 80, 2120, -4240, -31648, 63296, 194432, -388864, -613376, + 1226752, 1087488, -2174976, -1097728, 2195456, 589824, -1179648, + -131072, 262144}, {-1, -14, 112, 448, -2016, -4032, 13440, 15360, + -42240, -28160, 67584, 24576, -53248, -8192, 16384} +}; + +/* The coefficients in 2^d * \prod_{i=1}^d (x - cos(a_i)) are + easily bounded using the binomial theorem. */ +static slong +magnitude_bound(slong d) +{ + slong res; + fmpz_t t; + fmpz_init(t); + fmpz_bin_uiui(t, d, d / 2); + res = fmpz_bits(t); + fmpz_clear(t); + return FLINT_ABS(res) + d; +} + +static void +fmpz_mul_or_div_2exp(fmpz_t x, fmpz_t y, slong s) +{ + if (s >= 0) + fmpz_mul_2exp(x, y, s); + else + fmpz_fdiv_q_2exp(x, y, -s); +} + + +/* Balanced product of linear factors (x+alpha_i) using + fixed-point arithmetic with prec bits */ +static void +balanced_product(fmpz * c, fmpz * alpha, slong len, slong prec) +{ + if (len == 1) + { + fmpz_one(c + 1); + fmpz_mul_2exp(c + 1, c + 1, prec); + fmpz_set(c, alpha); + } + else if (len == 2) + { + fmpz_mul(c, alpha, alpha + 1); + fmpz_fdiv_q_2exp(c, c, prec); + fmpz_add(c + 1, alpha, alpha + 1); + fmpz_one(c + 2); + fmpz_mul_2exp(c + 2, c + 2, prec); + } + else + { + fmpz *L, *R; + slong i, m; + + m = len / 2; + L = _fmpz_vec_init(len + 2); + R = L + m + 1; + + balanced_product(L, alpha, m, prec); + balanced_product(R, alpha + m, len - m, prec); + _fmpz_poly_mul(c, R, len - m + 1, L, m + 1); + + for (i = 0; i < len + 1; i++) + fmpz_fdiv_q_2exp(c + i, c + i, prec); + + _fmpz_vec_clear(L, len + 2); + } +} + +void +_arith_cos_minpoly(fmpz * coeffs, slong d, ulong n) +{ + slong i, j; + fmpz * alpha; + fmpz_t half; + mpfr_t t, u; + mp_bitcnt_t prec; + slong exp; + + if (n <= MAX_32BIT) + { + for (i = 0; i <= d; i++) + fmpz_set_si(coeffs + i, lookup_table[n - 1][i]); + return; + } + + /* Direct formula for odd primes > 3 */ + if (n_is_prime(n)) + { + slong s = (n - 1) / 2; + + switch (s % 4) + { + case 0: + fmpz_set_si(coeffs, WORD(1)); + fmpz_set_si(coeffs + 1, -s); + break; + case 1: + fmpz_set_si(coeffs, WORD(1)); + fmpz_set_si(coeffs + 1, s + 1); + break; + case 2: + fmpz_set_si(coeffs, WORD(-1)); + fmpz_set_si(coeffs + 1, s); + break; + case 3: + fmpz_set_si(coeffs, WORD(-1)); + fmpz_set_si(coeffs + 1, -s - 1); + break; + } + + for (i = 2; i <= s; i++) + { + slong b = (s - i) % 2; + fmpz_mul2_uiui(coeffs + i, coeffs + i - 2, s+i-b, s+2-b-i); + fmpz_divexact2_uiui(coeffs + i, coeffs + i, i, i-1); + fmpz_neg(coeffs + i, coeffs + i); + } + + return; + } + + prec = magnitude_bound(d) + 5 + FLINT_BIT_COUNT(d); + + alpha = _fmpz_vec_init(d); + fmpz_init(half); + mpfr_init2(t, prec); + mpfr_init2(u, prec); + + fmpz_one(half); + fmpz_mul_2exp(half, half, prec - 1); + mpfr_const_pi(t, prec); + mpfr_div_ui(t, t, n, MPFR_RNDN); + + for (i = j = 0; j < d; i++) + { + if (n_gcd(n, i) == 1) + { + mpfr_mul_ui(u, t, 2 * i, MPFR_RNDN); + mpfr_cos(u, u, MPFR_RNDN); + mpfr_neg(u, u, MPFR_RNDN); + exp = mpfr_get_z_2exp(_fmpz_promote(alpha + j), u); + _fmpz_demote_val(alpha + j); + fmpz_mul_or_div_2exp(alpha + j, alpha + j, exp + prec); + j++; + } + } + + balanced_product(coeffs, alpha, d, prec); + + /* Scale and round */ + for (i = 0; i < d + 1; i++) + { + slong r = d; + if ((n & (n - 1)) == 0) + r--; + fmpz_mul_2exp(coeffs + i, coeffs + i, r); + fmpz_add(coeffs + i, coeffs + i, half); + fmpz_fdiv_q_2exp(coeffs + i, coeffs + i, prec); + } + + fmpz_clear(half); + mpfr_clear(t); + mpfr_clear(u); + _fmpz_vec_clear(alpha, d); +} + +void +arith_cos_minpoly(fmpz_poly_t poly, ulong n) +{ + if (n == 0) + { + fmpz_poly_set_ui(poly, UWORD(1)); + } + else + { + slong d = (n <= 2) ? 1 : n_euler_phi(n) / 2; + + fmpz_poly_fit_length(poly, d + 1); + _arith_cos_minpoly(poly->coeffs, d, n); + _fmpz_poly_set_length(poly, d + 1); + } +} diff --git a/external/flint-2.4.3/arith/cyclotomic_polynomial.c b/external/flint-2.4.3/arith/cyclotomic_polynomial.c new file mode 100644 index 0000000..15c451b --- /dev/null +++ b/external/flint-2.4.3/arith/cyclotomic_polynomial.c @@ -0,0 +1,160 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "arith.h" + +void +_arith_cyclotomic_polynomial(fmpz * a, ulong n, mp_ptr factors, + slong num_factors, ulong phi) +{ + slong i, k; + int small; + ulong D; + + D = phi / 2; + + /* Phi_p(x) = 1 + x + x^2 + ... + x^{p-1} */ + if (num_factors == 1) + { + for (i = 0; i <= D; i++) + fmpz_one(a + i); + return; + } + + /* Phi_{2n}(x) = Phi_n(-x)*/ + if (factors[0] == UWORD(2)) + { + _arith_cyclotomic_polynomial(a, n / 2, factors + 1, + num_factors - 1, phi); + for (i = 1; i <= D; i += 2) + fmpz_neg(a + i, a + i); + return; + } + + fmpz_one(a); + for (i = 1; i <= D; i++) + fmpz_zero(a + i); + + /* Coefficients are guaranteed not to overflow an fmpz */ + small = (num_factors == 2) || /* Always +1/0/-1*/ + (n < WORD(10163195)) || /* At most 27 bits */ + (FLINT_BITS == 64 && n < WORD(169828113)); /* At most 60 bits */ + + /* Iterate over all divisors of n */ + for (k = 0; k < (WORD(1) << num_factors); k++) + { + int mu; + ulong d; + + mu = (num_factors & 1) ? -1 : 1; + d = WORD(1); + for (i = 0; i < num_factors; i++) + { + if ((k >> i) & 1) + { + d *= factors[i]; + mu = -mu; + } + } + + /* Multiply by (x^d - 1)^{\mu(n/d)} */ + if (small) + { + if (mu == 1) + for (i = D; i >= d; i--) a[i] -= a[i - d]; + else + for (i = d; i <= D; i++) a[i] += a[i - d]; + } + else + { + if (mu == 1) + for (i = D; i >= d; i--) fmpz_sub(a + i, a + i, a + i - d); + else + for (i = d; i <= D; i++) fmpz_add(a + i, a + i, a + i - d); + } + } +} + +void +arith_cyclotomic_polynomial(fmpz_poly_t poly, ulong n) +{ + n_factor_t factors; + slong i, j; + ulong s, phi; + + if (n <= 2) + { + if (n == 0) + { + fmpz_poly_set_ui(poly, UWORD(1)); + } + else + { + fmpz_poly_fit_length(poly, 2); + fmpz_set_si(poly->coeffs, (n == 1) ? WORD(-1) : WORD(1)); + fmpz_set_si(poly->coeffs + 1, WORD(1)); + _fmpz_poly_set_length(poly, 2); + } + return; + } + + /* Write n = q * s where q is squarefree, compute the factors of q, + and compute phi(s) which determines the degree of the polynomial. */ + n_factor_init(&factors); + n_factor(&factors, n, 1); + s = phi = UWORD(1); + for (i = 0; i < factors.num; i++) + { + phi *= factors.p[i] - 1; + while (factors.exp[i] > 1) + { + s *= factors.p[i]; + factors.exp[i]--; + } + } + + fmpz_poly_fit_length(poly, phi * s + 1); + + /* Evaluate lower half of Phi_s(x) */ + _arith_cyclotomic_polynomial(poly->coeffs, n / s, + factors.p, factors.num, phi); + + /* Palindromic extension */ + for (i = 0; i < (phi + 1) / 2; i++) + fmpz_set(poly->coeffs + phi - i, poly->coeffs + i); + + /* Stretch */ + if (s != 1) + { + for (i = phi; i > 0; i--) + { + fmpz_set(poly->coeffs + i*s, poly->coeffs + i); + for (j = 1; j < s; j++) + fmpz_zero(poly->coeffs + i*s - j); + } + } + + _fmpz_poly_set_length(poly, phi * s + 1); +} diff --git a/external/flint-2.4.3/arith/dedekind_cosine_sum_factored.c b/external/flint-2.4.3/arith/dedekind_cosine_sum_factored.c new file mode 100644 index 0000000..be8285d --- /dev/null +++ b/external/flint-2.4.3/arith/dedekind_cosine_sum_factored.c @@ -0,0 +1,307 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "arith.h" + +static const int mod4_tab[8] = { 2, 1, 3, 0, 0, 3, 1, 2 }; + +static const int gcd24_tab[24] = { + 24, 1, 2, 3, 4, 1, 6, 1, 8, 3, 2, 1, + 12, 1, 2, 3, 8, 1, 6, 1, 4, 3, 2, 1 +}; + +static mp_limb_t +n_sqrtmod_2exp(mp_limb_t a, int k) +{ + mp_limb_t x; + int i; + + if (a == 0 || k == 0) + return 0; + + if (k == 1) + return 1; + + if (k == 2) + { + if (a == 1) + return 1; + return 0; + } + + x = 1; + for (i = 3; i < k; i++) + x += (a - x * x) / 2; + + if (k < FLINT_BITS) + x &= ((UWORD(1) << k) - 1); + + return x; +} + +static mp_limb_t +n_sqrtmod_ppow(mp_limb_t a, mp_limb_t p, int k, mp_limb_t pk, mp_limb_t pkinv) +{ + mp_limb_t r, t; + int i; + + r = n_sqrtmod(a, p); + if (r == 0) + return r; + + i = 1; + while (i < k) + { + t = n_mulmod2_preinv(r, r, pk, pkinv); + t = n_submod(t, a, pk); + t = n_mulmod2_preinv(t, n_invmod(n_addmod(r, r, pk), pk), pk, pkinv); + r = n_submod(r, t, pk); + i *= 2; + } + + return r; +} + +void +trigprod_mul_prime_power(trig_prod_t prod, mp_limb_t k, mp_limb_t n, + mp_limb_t p, int exp) +{ + mp_limb_t m, mod, inv; + + if (k <= 3) + { + if (k == 0) + { + prod->prefactor = 0; + } + else if (k == 2 && (n % 2 == 1)) + { + prod->prefactor *= -1; + } + else if (k == 3) + { + switch (n % 3) + { + case 0: + prod->prefactor *= 2; + prod->cos_p[prod->n] = 1; + prod->cos_q[prod->n] = 18; + break; + case 1: + prod->prefactor *= -2; + prod->cos_p[prod->n] = 7; + prod->cos_q[prod->n] = 18; + break; + case 2: + prod->prefactor *= -2; + prod->cos_p[prod->n] = 5; + prod->cos_q[prod->n] = 18; + break; + } + prod->n++; + } + return; + } + + /* Power of 2 */ + if (p == 2) + { + mod = 8 * k; + inv = n_preinvert_limb(mod); + + m = n_submod(1, n_mod2_preinv(24 * n, mod, inv), mod); + m = n_sqrtmod_2exp(m, exp + 3); + m = n_mulmod2_preinv(m, n_invmod(3, mod), mod, inv); + + prod->prefactor *= n_jacobi(-1, m); + if (exp % 2 == 1) + prod->prefactor *= -1; + prod->sqrt_p *= k; + prod->cos_p[prod->n] = (mp_limb_signed_t)(k - m); + prod->cos_q[prod->n] = 2 * k; + prod->n++; + return; + } + + /* Power of 3 */ + if (p == 3) + { + mod = 3 * k; + inv = n_preinvert_limb(mod); + + m = n_submod(1, n_mod2_preinv(24 * n, mod, inv), mod); + m = n_sqrtmod_ppow(m, p, exp + 1, mod, inv); + m = n_mulmod2_preinv(m, n_invmod(8, mod), mod, inv); + + prod->prefactor *= (2 * n_jacobi_unsigned(m, 3)); + if (exp % 2 == 0) + prod->prefactor *= -1; + prod->sqrt_p *= k; + prod->sqrt_q *= 3; + prod->cos_p[prod->n] = (mp_limb_signed_t)(3 * k - 8 * m); + prod->cos_q[prod->n] = 6 * k; + prod->n++; + return; + } + + /* Power of prime greater than 3 */ + inv = n_preinvert_limb(k); + m = n_submod(1, n_mod2_preinv(24 * n, k, inv), k); + + if (m % p == 0) + { + if (exp == 1) + { + prod->prefactor *= n_jacobi(3, k); + prod->sqrt_p *= k; + } + else + prod->prefactor = 0; + return; + } + + m = n_sqrtmod_ppow(m, p, exp, k, inv); + + if (m == 0) + { + prod->prefactor = 0; + return; + } + + prod->prefactor *= 2; + prod->prefactor *= n_jacobi(3, k); + prod->sqrt_p *= k; + prod->cos_p[prod->n] = 4 * n_mulmod2_preinv(m, n_invmod(24, k), k, inv); + prod->cos_q[prod->n] = k; + prod->n++; +} + +/* +Solve (k2^2 * d2 * e) * n1 = (d2 * e * n + (k2^2 - 1) / d1) mod k2 + +TODO: test this on 32 bit +*/ +static mp_limb_t +solve_n1(mp_limb_t n, mp_limb_t k1, mp_limb_t k2, + mp_limb_t d1, mp_limb_t d2, mp_limb_t e) +{ + mp_limb_t inv, n1, u, t[2]; + + inv = n_preinvert_limb(k1); + + umul_ppmm(t[1], t[0], k2, k2); + sub_ddmmss(t[1], t[0], t[1], t[0], UWORD(0), UWORD(1)); + mpn_divrem_1(t, 0, t, 2, d1); + + n1 = n_ll_mod_preinv(t[1], t[0], k1, inv); + n1 = n_mod2_preinv(n1 + d2*e*n, k1, inv); + + u = n_mulmod2_preinv(k2, k2, k1, inv); + u = n_invmod(u * d2 * e, k1); + n1 = n_mulmod2_preinv(n1, u, k1, inv); + + return n1; +} + + +void +arith_hrr_expsum_factored(trig_prod_t prod, mp_limb_t k, mp_limb_t n) +{ + n_factor_t fac; + int i; + + if (k <= 1) + { + prod->prefactor = k; + return; + } + + n_factor_init(&fac); + n_factor(&fac, k, 0); + + /* Repeatedly factor A_k(n) into A_k1(n1)*A_k2(n2) with k1, k2 coprime */ + for (i = 0; i + 1 < fac.num && prod->prefactor != 0; i++) + { + mp_limb_t p, k1, k2, inv, n1, n2; + + p = fac.p[i]; + + /* k = 2 * k1 with k1 odd */ + if (p == UWORD(2) && fac.exp[i] == 1) + { + k2 = k / 2; + inv = n_preinvert_limb(k2); + + n2 = n_invmod(32, k2); + n2 = n_mulmod2_preinv(n2, + n_mod2_preinv(8*n + 1, k2, inv), k2, inv); + n1 = ((k2 % 8 == 3) || (k2 % 8 == 5)) ^ (n & 1); + + trigprod_mul_prime_power(prod, 2, n1, 2, 1); + k = k2; + n = n2; + } + /* k = 4 * k1 with k1 odd */ + else if (p == UWORD(2) && fac.exp[i] == 2) + { + k2 = k / 4; + inv = n_preinvert_limb(k2); + + n2 = n_invmod(128, k2); + n2 = n_mulmod2_preinv(n2, + n_mod2_preinv(8*n + 5, k2, inv), k2, inv); + n1 = (n + mod4_tab[(k2 / 2) % 8]) % 4; + + trigprod_mul_prime_power(prod, 4, n1, 2, 2); + prod->prefactor *= -1; + k = k2; + n = n2; + } + /* k = k1 * k2 with k1 odd or divisible by 8 */ + else + { + mp_limb_t d1, d2, e; + + k1 = n_pow(fac.p[i], fac.exp[i]); + k2 = k / k1; + + d1 = gcd24_tab[k1 % 24]; + d2 = gcd24_tab[k2 % 24]; + e = 24 / (d1 * d2); + + n1 = solve_n1(n, k1, k2, d1, d2, e); + n2 = solve_n1(n, k2, k1, d2, d1, e); + + trigprod_mul_prime_power(prod, k1, n1, fac.p[i], fac.exp[i]); + k = k2; + n = n2; + } + } + + if (fac.num != 0 && prod->prefactor != 0) + trigprod_mul_prime_power(prod, k, n, + fac.p[fac.num - 1], fac.exp[fac.num - 1]); + +} diff --git a/external/flint-2.4.3/arith/dedekind_sum.c b/external/flint-2.4.3/arith/dedekind_sum.c new file mode 100644 index 0000000..090f66a --- /dev/null +++ b/external/flint-2.4.3/arith/dedekind_sum.c @@ -0,0 +1,84 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "arith.h" + +void +arith_dedekind_sum(fmpq_t s, const fmpz_t h, const fmpz_t k) +{ + if (fmpz_cmp_ui(k, UWORD(2)) <= 0 || fmpz_is_zero(h) || fmpz_equal(h, k)) + { + fmpq_zero(s); + } + else if (fmpz_sgn(h) < 0) + { + fmpz_t t; + fmpz_init(t); + fmpz_neg(t, h); + arith_dedekind_sum(s, t, k); + fmpq_neg(s, s); + fmpz_clear(t); + } + else + { + fmpz_t t, u, q; + + fmpz_init(t); + fmpz_init(u); + fmpz_init(q); + + fmpz_gcd(q, h, k); + fmpz_divexact(t, h, q); + fmpz_divexact(u, k, q); + + if (fmpz_cmp(t, u) > 0) + { + fmpq_t r; + fmpq_init(r); + + /* r = (1 + h(h-3k) + k^2) / (12hk) */ + fmpz_mul_ui(fmpq_numref(r), u, UWORD(3)); + fmpz_sub(fmpq_numref(r), t, fmpq_numref(r)); + fmpz_mul(fmpq_numref(r), fmpq_numref(r), t); + fmpz_addmul(fmpq_numref(r), u, u); + fmpz_add_ui(fmpq_numref(r), fmpq_numref(r), UWORD(1)); + fmpz_mul(fmpq_denref(r), t, u); + fmpz_mul_ui(fmpq_denref(r), fmpq_denref(r), UWORD(12)); + fmpq_canonicalise(r); + arith_dedekind_sum_coprime(s, u, t); + fmpq_sub(s, r, s); + + fmpq_clear(r); + } + else + { + arith_dedekind_sum_coprime(s, t, u); + } + + fmpz_clear(t); + fmpz_clear(u); + fmpz_clear(q); + } +} diff --git a/external/flint-2.4.3/arith/dedekind_sum_coprime.c b/external/flint-2.4.3/arith/dedekind_sum_coprime.c new file mode 100644 index 0000000..40f3216 --- /dev/null +++ b/external/flint-2.4.3/arith/dedekind_sum_coprime.c @@ -0,0 +1,54 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "arith.h" + +/* Small enough that a numerical computation is safe */ +#define DOUBLE_CUTOFF (UWORD(1) << 21) + +void +arith_dedekind_sum_coprime(fmpq_t s, const fmpz_t h, const fmpz_t k) +{ + if (fmpz_cmp_ui(k, DOUBLE_CUTOFF) < 0) + { + double t; + + t = arith_dedekind_sum_coprime_d(*h, *k) * (6 * (*k)); + + /* Round to nearest after truncation */ + if (t > 0) + t += 0.5; + else + t -= 0.5; + + fmpz_set_d(fmpq_numref(s), t); + fmpz_set_ui(fmpq_denref(s), UWORD(6) * (*k)); + fmpq_canonicalise(s); + } + else + { + arith_dedekind_sum_coprime_large(s, h, k); + } +} diff --git a/external/flint-2.4.3/arith/dedekind_sum_coprime_d.c b/external/flint-2.4.3/arith/dedekind_sum_coprime_d.c new file mode 100644 index 0000000..ba09625 --- /dev/null +++ b/external/flint-2.4.3/arith/dedekind_sum_coprime_d.c @@ -0,0 +1,57 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "arith.h" + +double +arith_dedekind_sum_coprime_d(double h, double k) +{ + double a, b, t, s, sign; + + if (k <= 2) + return 0.0; + + a = k; + b = h; + s = 0.0; + sign = 1.0; + + while (b > 0) + { + s += sign * (1.0 + a*a + b*b) / (a * b); + t = fmod(a, b); + a = b; + b = t; + sign = -sign; + } + + s *= (1./12); + + if (sign < 0) + s -= 0.25; + + return s; +} diff --git a/external/flint-2.4.3/arith/dedekind_sum_coprime_large.c b/external/flint-2.4.3/arith/dedekind_sum_coprime_large.c new file mode 100644 index 0000000..0934888 --- /dev/null +++ b/external/flint-2.4.3/arith/dedekind_sum_coprime_large.c @@ -0,0 +1,96 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "arith.h" + +void +arith_dedekind_sum_coprime_large(fmpq_t s, const fmpz_t h, const fmpz_t k) +{ + fmpz_t sigma, p, pp, hh, kk, a, t; + + int sign; + + if (fmpz_cmp_ui(k, UWORD(2)) <= 0) + { + fmpq_zero(s); + return; + } + + sign = 1; + + fmpz_init(sigma); + fmpz_init(hh); + fmpz_init(kk); + fmpz_init(p); + fmpz_init(pp); + fmpz_init(a); + fmpz_init(t); + + fmpz_set_ui(p, UWORD(1)); + fmpz_set(hh, h); + fmpz_set(kk, k); + + while (!fmpz_is_zero(hh)) + { + fmpz_fdiv_qr(a, t, kk, hh); + + if (sign == 1) + fmpz_add(sigma, sigma, a); + else + fmpz_sub(sigma, sigma, a); + + sign = -sign; + + /* kk, hh = hh, kk mod hh */ + fmpz_swap(kk, hh); + fmpz_swap(hh, t); + + /* p, pp = a*p + pp, p */ + fmpz_addmul(pp, a, p); + fmpz_swap(p, pp); + } + + if (sign < 0) + fmpz_sub_ui(sigma, sigma, UWORD(3)); + + /* s = (sigma + (h - p*s) / p) / 12 */ + if (sign < 0) + fmpz_add(fmpq_numref(s), h, pp); + else + fmpz_sub(fmpq_numref(s), h, pp); + + fmpz_addmul(fmpq_numref(s), sigma, p); + fmpz_mul_ui(fmpq_denref(s), p, UWORD(12)); + + _fmpq_canonicalise(fmpq_numref(s), fmpq_denref(s)); + + fmpz_clear(sigma); + fmpz_clear(hh); + fmpz_clear(kk); + fmpz_clear(p); + fmpz_clear(pp); + fmpz_clear(a); + fmpz_clear(t); +} diff --git a/external/flint-2.4.3/arith/dedekind_sum_naive.c b/external/flint-2.4.3/arith/dedekind_sum_naive.c new file mode 100644 index 0000000..f3fb317 --- /dev/null +++ b/external/flint-2.4.3/arith/dedekind_sum_naive.c @@ -0,0 +1,82 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "arith.h" + +void +arith_dedekind_sum_naive(fmpq_t s, const fmpz_t h, const fmpz_t k) +{ + fmpz_t i, j, q1, r1, q2, r2; + + if (fmpz_is_zero(k)) + { + fmpq_zero(s); + return; + } + + fmpz_init(i); + fmpz_init(j); + fmpz_init(q1); + fmpz_init(r1); + fmpz_init(q2); + fmpz_init(r2); + + fmpz_zero(fmpq_numref(s)); + + for (fmpz_one(i); fmpz_cmp(i, k) < 0; fmpz_add_ui(i, i, 1)) + { + fmpz_fdiv_qr(q1, r1, i, k); + if (fmpz_is_zero(r1)) + continue; + + fmpz_mul(j, h, i); + fmpz_fdiv_qr(q2, r2, j, k); + if (fmpz_is_zero(r2)) + continue; + + fmpz_mul(q1, q1, k); + fmpz_sub(q1, i, q1); + fmpz_mul_ui(q1, q1, 2); + fmpz_sub(q1, q1, k); + + fmpz_mul(q2, q2, k); + fmpz_sub(q2, j, q2); + fmpz_mul_ui(q2, q2, 2); + fmpz_sub(q2, q2, k); + + fmpz_addmul(fmpq_numref(s), q1, q2); + } + + fmpz_mul(fmpq_denref(s), k, k); + fmpz_mul_ui(fmpq_denref(s), fmpq_denref(s), 4); + fmpq_canonicalise(s); + + fmpz_clear(i); + fmpz_clear(j); + fmpz_clear(q1); + fmpz_clear(r1); + fmpz_clear(q2); + fmpz_clear(r2); +} diff --git a/external/flint-2.4.3/arith/divisor_sigma.c b/external/flint-2.4.3/arith/divisor_sigma.c new file mode 100644 index 0000000..f2632a1 --- /dev/null +++ b/external/flint-2.4.3/arith/divisor_sigma.c @@ -0,0 +1,87 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include "arith.h" +#include "fmpz.h" + +/* note: destroys factors! */ +void +_arith_divisor_sigma(fmpz_t res, const fmpz_factor_t factors, ulong k) +{ + slong i; + fmpz * p; + fmpz_t r; + + fmpz_one(res); + + if (factors->num == 0) + return; + + fmpz_init(r); + + if (k == 0) + { + for (i = 0; i < factors->num; i++) + { + fmpz_set_ui(r, factors->exp[i] + UWORD(1)); + fmpz_mul(res, res, r); + } + return; + } + else + { + for (i = 0; i < factors->num; i++) + { + p = factors->p + i; + fmpz_set(p, factors->p + i); + fmpz_pow_ui(p, p, k); + fmpz_pow_ui(r, p, factors->exp[i] + UWORD(1)); + fmpz_sub_ui(r, r, UWORD(1)); + fmpz_sub_ui(p, p, UWORD(1)); + fmpz_divexact(p, r, p); + } + + _fmpz_vec_prod(res, factors->p, factors->num); + } + + fmpz_clear(r); +} + +void +arith_divisor_sigma(fmpz_t res, const fmpz_t n, ulong k) +{ + fmpz_factor_t factors; + + if (fmpz_is_zero(n)) + { + fmpz_zero(res); + return; + } + + fmpz_factor_init(factors); + fmpz_factor(factors, n); + _arith_divisor_sigma(res, factors, k); + fmpz_factor_clear(factors); +} diff --git a/external/flint-2.4.3/arith/divisors.c b/external/flint-2.4.3/arith/divisors.c new file mode 100644 index 0000000..ebc4907 --- /dev/null +++ b/external/flint-2.4.3/arith/divisors.c @@ -0,0 +1,165 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include "arith.h" +#include "fmpz.h" + +#define FLINT_NUM_TINY_DIVISORS FLINT_BITS + +const int FLINT_TINY_DIVISORS_SIZE[FLINT_NUM_TINY_DIVISORS] = { + 0,1,2,2,3,2,4,2,4,3,4,2,6,2,4,4,5,2,6,2,6,4,4,2,8,3,4,4,6,2,8,2, +#if FLINT64 + 6,4,4,4,9,2,4,4,8,2,8,2,6,6,4,2,10,3,6,4,6,2,8,4,8,4,4,2,12,2,4,6 +#endif +}; + +const ulong FLINT_TINY_DIVISORS_LOOKUP[FLINT_NUM_TINY_DIVISORS] = { + UWORD(0x0),UWORD(0x2),UWORD(0x6),0xaUL,UWORD(0x16),UWORD(0x22),0x4eUL,UWORD(0x82),UWORD(0x116),0x20aUL, + UWORD(0x426),UWORD(0x802),0x105eUL,UWORD(0x2002),UWORD(0x4086),0x802aUL,UWORD(0x10116),UWORD(0x20002), + 0x4024eUL,UWORD(0x80002),UWORD(0x100436),0x20008aUL,UWORD(0x400806),UWORD(0x800002), + 0x100115eUL,UWORD(0x2000022),UWORD(0x4002006),0x800020aUL,UWORD(0x10004096),UWORD(0x20000002), + 0x4000846eUL,UWORD(0x80000002), +#if FLINT64 + UWORD(0x100010116),0x20000080aUL,UWORD(0x400020006),UWORD(0x8000000a2),0x100004125eUL, + UWORD(0x2000000002),UWORD(0x4000080006),0x800000200aUL,UWORD(0x10000100536), + UWORD(0x20000000002),0x400002040ceUL,UWORD(0x80000000002),UWORD(0x100000400816), + 0x20000000822aUL,UWORD(0x400000800006),UWORD(0x800000000002),0x100000101115eUL, + UWORD(0x2000000000082),UWORD(0x4000002000426),0x800000002000aUL,UWORD(0x10000004002016), + UWORD(0x20000000000002),0x4000000804024eUL,UWORD(0x80000000000822), + UWORD(0x100000010004196),0x20000000008000aUL,UWORD(0x400000020000006), + UWORD(0x800000000000002),0x100000004010947eUL,UWORD(0x2000000000000002), + UWORD(0x4000000080000006),0x800000000020028aUL +#endif +}; + + +void +_arith_divisors(fmpz *res, slong size, fmpz_factor_t factors) +{ + slong i; + slong *exp = flint_malloc(sizeof(slong) * factors->num); + slong *exp_max = flint_malloc(sizeof(slong) * factors->num); + fmpz *powers = _fmpz_vec_init(factors->num); + fmpz_t d; + + for (i = 0; i < factors->num; i++) + { + exp[i] = 0; + fmpz_set(powers + i, factors->p + i); + exp_max[i] = factors->exp[i]; + fmpz_pow_ui(powers + i, powers + i, exp_max[i]); + } + + fmpz_init(d); + fmpz_one(res); + fmpz_one(d); + res++; + + i = 0; + while (1) + { + while (1) + { + if (i == factors->num) + goto all_done; + if (exp[i] < exp_max[i]) + { + exp[i]++; + fmpz_mul(d, d, factors->p + i); + i = 0; + break; + } + else + { + exp[i] = 0; + fmpz_divexact(d, d, powers+i); + i += 1; + } + } + fmpz_set(res, d); + res++; + } + + all_done: + fmpz_clear(d); + flint_free(exp); + flint_free(exp_max); + _fmpz_vec_clear(powers, factors->num); +} + + +void +_arith_divisors_tiny(fmpz_poly_t res, slong n) +{ + slong size; + slong i, k; + + size = FLINT_TINY_DIVISORS_SIZE[n]; + + fmpz_poly_fit_length(res, size); + i = 0; + for (k = 1; k <= n; k++) + { + if (FLINT_TINY_DIVISORS_LOOKUP[n] & (UWORD(1) << k)) + { + fmpz_poly_set_coeff_si(res, i, k); + i++; + } + } + _fmpz_poly_set_length(res, size); + return; +} + +void +arith_divisors(fmpz_poly_t res, const fmpz_t n) +{ + slong i, size, m; + fmpz_factor_t factors; + + if (!COEFF_IS_MPZ(*n)) + { + m = fmpz_get_si(n); + if (-FLINT_NUM_TINY_DIVISORS < m && m < FLINT_NUM_TINY_DIVISORS) + { + _arith_divisors_tiny(res, FLINT_ABS(m)); + return; + } + } + + fmpz_factor_init(factors); + fmpz_factor(factors, n); + + /* TODO: check for overflow for huge n */ + size = 1; + for (i = 0; i < factors->num; i++) + size *= factors->exp[i] + 1; + + fmpz_poly_fit_length(res, size); + _arith_divisors(res->coeffs, size, factors); + _fmpz_poly_set_length(res, size); + _fmpz_vec_sort(res->coeffs, size); + + fmpz_factor_clear(factors); +} diff --git a/external/flint-2.4.3/arith/doc/arith.txt b/external/flint-2.4.3/arith/doc/arith.txt new file mode 100644 index 0000000..75aab37 --- /dev/null +++ b/external/flint-2.4.3/arith/doc/arith.txt @@ -0,0 +1,876 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Fredrik Johansson + +******************************************************************************/ + +******************************************************************************* + + Primorials + +******************************************************************************* + +void arith_primorial(fmpz_t res, slong n) + + Sets \code{res} to ``$n$ primorial'' or $n \#$, the product of all prime + numbers less than or equal to $n$. + +******************************************************************************* + + Harmonic numbers + +******************************************************************************* + +void _arith_harmonic_number(fmpz_t num, fmpz_t den, slong n) + + Sets \code{(num, den)} to the reduced numerator and denominator of + the $n$-th harmonic number $H_n = 1 + 1/2 + 1/3 + \dotsb + 1/n$. The + result is zero if $n \leq 0$. + + Table lookup is used for $H_n$ whose numerator and denominator + fit in single limb. For larger $n$, the function + \code{flint_mpn_harmonic_odd_balanced()} is used. + +void arith_harmonic_number(fmpq_t x, slong n) + + Sets \code{x} to the $n$-th harmonic number. This function is + equivalent to \code{_arith_harmonic_number} apart from the output + being a single \code{fmpq_t} variable. + +******************************************************************************* + + Stirling numbers + +******************************************************************************* + +void arith_stirling_number_1u(fmpz_t s, slong n, slong k) + +void arith_stirling_number_1(fmpz_t s, slong n, slong k) + +void arith_stirling_number_2(fmpz_t s, slong n, slong k) + + Sets $s$ to $S(n,k)$ where $S(n,k)$ denotes an unsigned Stirling + number of the first kind $|S_1(n, k)|$, a signed Stirling number + of the first kind $S_1(n, k)$, or a Stirling number of the second + kind $S_2(n, k)$. The Stirling numbers are defined using the + generating functions + \begin{align*} + x_{(n)} & = \sum_{k=0}^n S_1(n,k) x^k \\ + x^{(n)} & = \sum_{k=0}^n |S_1(n,k)| x^k \\ + x^n & = \sum_{k=0}^n S_2(n,k) x_{(k)} + \end{align*} + where $x_{(n)} = x(x-1)(x-2) \dotsm (x-n+1)$ is a falling factorial + and $x^{(n)} = x(x+1)(x+2) \dotsm (x+n-1)$ is a rising factorial. + $S(n,k)$ is taken to be zero if $n < 0$ or $k < 0$. + + These three functions are useful for computing isolated Stirling + numbers efficiently. To compute a range of numbers, the vector or + matrix versions should generally be used. + +void arith_stirling_number_1u_vec(fmpz * row, slong n, slong klen) +void arith_stirling_number_1_vec(fmpz * row, slong n, slong klen) +void arith_stirling_number_2_vec(fmpz * row, slong n, slong klen) + + Computes the row of Stirling numbers + \code{S(n,0), S(n,1), S(n,2), ..., S(n,klen-1)}. + + To compute a full row, this function can be called with + \code{klen = n+1}. It is assumed that \code{klen} is at most $n + 1$. + +void arith_stirling_number_1u_vec_next(fmpz * row, fmpz * prev, slong n, + slong klen) + +void arith_stirling_number_1_vec_next(fmpz * row, fmpz * prev, slong n, + slong klen) + +void arith_stirling_number_2_vec_next(fmpz * row, fmpz * prev, slong n, + slong klen) + + Given the vector \code{prev} containing a row of Stirling numbers + \code{S(n-1,0), S(n-1,1), S(n-1,2), ..., S(n-1,klen-1)}, computes + and stores in the row argument + \code{S(n,0), S(n,1), S(n,2), ..., S(n,klen-1)}. + + If \code{klen} is greater than \code{n}, the output ends with + \code{S(n,n) = 1} followed by \code{S(n,n+1) = S(n,n+2) = ... = 0}. + In this case, the input only needs to have length \code{n-1}; + only the input entries up to \code{S(n-1,n-2)} are read. + + The \code{row} and \code{prev} arguments are permitted to be the + same, meaning that the row will be updated in-place. + +void arith_stirling_matrix_1u(fmpz_mat_t mat) +void arith_stirling_matrix_1(fmpz_mat_t mat) +void arith_stirling_matrix_2(fmpz_mat_t mat) + + For an arbitrary $m$-by-$n$ matrix, writes the truncation of the + infinite Stirling number matrix + + \begin{lstlisting} + row 0 : S(0,0) + row 1 : S(1,0), S(1,1) + row 2 : S(2,0), S(2,1), S(2,2) + row 3 : S(3,0), S(3,1), S(3,2), S(3,3) + \end{lstlisting} + + up to row $m-1$ and column $n-1$ inclusive. The upper triangular + part of the matrix is zeroed. + + For any $n$, the $S_1$ and $S_2$ matrices thus obtained are + inverses of each other. + +******************************************************************************* + + Bell numbers + +******************************************************************************* + +void arith_bell_number(fmpz_t b, ulong n) + + Sets $b$ to the Bell number $B_n$, defined as the + number of partitions of a set with $n$ members. Equivalently, + $B_n = \sum_{k=0}^n S_2(n,k)$ where $S_2(n,k)$ denotes a Stirling number + of the second kind. + + This function automatically selects between table lookup, binary + splitting, and the multimodular algorithm. + +void arith_bell_number_bsplit(fmpz_t res, ulong n) + + Computes the Bell number $B_n$ by evaluating a precise truncation of + the series $B_n = e^{-1} \sum_{k=0}^{\infty} \frac{k^n}{k!}$ using + binary splitting. + +void arith_bell_number_multi_mod(fmpz_t res, ulong n) + + Computes the Bell number $B_n$ using a multimodular algorithm. + + This function evaluates the Bell number modulo several limb-size + primes using\\ \code{arith_bell_number_nmod} and reconstructs the integer + value using the fast Chinese remainder algorithm. + A bound for the number of needed primes is computed using + \code{arith_bell_number_size}. + +void arith_bell_number_vec(fmpz * b, slong n) + + Sets $b$ to the vector of Bell numbers $B_0, B_1, \ldots, B_{n-1}$ + inclusive. Automatically switches between the \code{recursive} + and \code{multi_mod} algorithms depending on the size of $n$. + +void arith_bell_number_vec_recursive(fmpz * b, slong n) + + Sets $b$ to the vector of Bell numbers $B_0, B_1, \ldots, B_{n-1}$ + inclusive. This function uses table lookup if $B_{n-1}$ fits in a + single word, and a standard triangular recurrence otherwise. + +void arith_bell_number_vec_multi_mod(fmpz * b, slong n) + + Sets $b$ to the vector of Bell numbers $B_0, B_1, \ldots, B_{n-1}$ + inclusive. + + This function evaluates the Bell numbers modulo several limb-size + primes using\\ \code{arith_bell_number_nmod_vec} and reconstructs the + integer values using the fast Chinese remainder algorithm. + A bound for the number of needed primes is computed using + \code{arith_bell_number_size}. + +mp_limb_t bell_number_nmod(ulong n, nmod_t mod) + + Computes the Bell number $B_n$ modulo a prime $p$ given by \code{mod} + + After handling special cases, we use the formula + + $$B_n = \sum_{k=0}^n \frac{(n-k)^n}{(n-k)!} + \sum_{j=0}^k \frac{(-1)^j}{j!}.$$ + + We arrange the operations in such a way that we only have to + multiply (and not divide) in the main loop. As a further optimisation, + we use sieving to reduce the number of powers that need to be + evaluated. This results in $O(n)$ memory usage. + + The divisions by factorials require $n > p$, so we fall back to + calling\\ \code{bell_number_nmod_vec_recursive} and reading off the + last entry when $p \le n$. + +void arith_bell_number_nmod_vec(mp_ptr b, slong n, nmod_t mod) + + Sets $b$ to the vector of Bell numbers $B_0, B_1, \ldots, B_{n-1}$ + inclusive modulo a prime $p$ given by \code{mod}. Automatically + switches between the \code{recursive} and \code{series} algorithms + depending on the size of $n$ and whether $p$ is large enough for the + series algorithm to work. + +void arith_bell_number_nmod_vec_recursive(mp_ptr b, slong n, nmod_t mod) + + Sets $b$ to the vector of Bell numbers $B_0, B_1, \ldots, B_{n-1}$ + inclusive modulo a prime $p$ given by \code{mod}. This function uses + table lookup if $B_{n-1}$ fits in a single word, and a standard + triangular recurrence otherwise. + +void arith_bell_number_nmod_vec_series(mp_ptr b, slong n, nmod_t mod) + + Sets $b$ to the vector of Bell numbers $B_0, B_1, \ldots, B_{n-1}$ + inclusive modulo a prime $p$ given by \code{mod}. This function + expands the exponential generating function + $$\sum_{k=0}^{\infty} \frac{B_n}{n!} x^n = \exp(e^x-1).$$ + We require that $p \ge n$. + +double arith_bell_number_size(ulong n) + + Returns $b$ such that $B_n < 2^{\lfloor b \rfloor}$, using the inequality + $$B_n < \left(\frac{0.792n}{\log(n+1)}\right)^n$$ + which is given in \cite{BerTas2010}. + +******************************************************************************* + + Bernoulli numbers and polynomials + +******************************************************************************* + +void _arith_bernoulli_number(fmpz_t num, fmpz_t den, ulong n) + + Sets \code{(num, den)} to the reduced numerator and denominator + of the $n$-th Bernoulli number. As presently implemented, + this function simply calls\\ \code{_arith_bernoulli_number_zeta}. + +void arith_bernoulli_number(fmpq_t x, ulong n) + + Sets \code{x} to the $n$-th Bernoulli number. This function is + equivalent to\\ \code{_arith_bernoulli_number} apart from the output + being a single \code{fmpq_t} variable. + +void _arith_bernoulli_number_vec(fmpz * num, fmpz * den, slong n) + + Sets the elements of \code{num} and \code{den} to the reduced + numerators and denominators of the Bernoulli numbers + $B_0, B_1, B_2, \ldots, B_{n-1}$ inclusive. This function automatically + chooses between the \code{recursive}, \code{zeta} and \code{multi_mod} + algorithms according to the size of $n$. + +void arith_bernoulli_number_vec(fmpq * x, slong n) + + Sets the \code{x} to the vector of Bernoulli numbers + $B_0, B_1, B_2, \ldots, B_{n-1}$ inclusive. This function is + equivalent to \code{_arith_bernoulli_number_vec} apart + from the output being a single \code{fmpq} vector. + +void arith_bernoulli_number_denom(fmpz_t den, ulong n) + + Sets \code{den} to the reduced denominator of the $n$-th + Bernoulli number $B_n$. For even $n$, the denominator is computed + as the product of all primes $p$ for which $p - 1$ divides $n$; + this property is a consequence of the von Staudt-Clausen theorem. + For odd $n$, the denominator is trivial (\code{den} is set to 1 whenever + $B_n = 0$). The initial sequence of values smaller than $2^{32}$ are + looked up directly from a table. + +double arith_bernoulli_number_size(ulong n) + + Returns $b$ such that $|B_n| < 2^{\lfloor b \rfloor}$, using the inequality + $$|B_n| < \frac{4 n!}{(2\pi)^n}$$ and $n! \le (n+1)^{n+1} e^{-n}$. + No special treatment is given to odd $n$. Accuracy is not guaranteed + if $n > 10^{14}$. + +void arith_bernoulli_polynomial(fmpq_poly_t poly, ulong n) + + Sets \code{poly} to the Bernoulli polynomial of degree $n$, + $B_n(x) = \sum_{k=0}^n \binom{n}{k} B_k x^{n-k}$ where $B_k$ + is a Bernoulli number. This function basically calls + \code{arith_bernoulli_number_vec} and then rescales the coefficients + efficiently. + +void _arith_bernoulli_number_zeta(fmpz_t num, fmpz_t den, ulong n) + + Sets \code{(num, den)} to the reduced numerator and denominator + of the $n$-th Bernoulli number. + + This function first computes the exact denominator and a bound + for the size of the numerator. It then computes an approximation + of $|B_n| = 2n! \zeta(n) / (2 \pi)^n$ as a floating-point number + and multiplies by the denominator to to obtain a real number + that rounds to the exact numerator. For tiny $n$, the numerator + is looked up from a table to avoid unnecessary overhead. + +void _arith_bernoulli_number_vec_recursive(fmpz * num, fmpz * den, slong n) + + Sets the elements of \code{num} and \code{den} to the reduced + numerators and denominators of $B_0, B_1, B_2, \ldots, B_{n-1}$ + inclusive. + + The first few entries are computed using \code{arith_bernoulli_number}, + and then Ramanujan's recursive formula expressing $B_m$ as a sum over + $B_k$ for $k$ congruent to $m$ modulo 6 is applied repeatedly. + + To avoid costly GCDs, the numerators are transformed internally + to a common denominator and all operations are performed using + integer arithmetic. This makes the algorithm fast for small $n$, + say $n < 1000$. The common denominator is calculated directly + as the primorial of $n + 1$. + + %[1] http://en.wikipedia.org/w/index.php? + % title=Bernoulli_number&oldid=405938876 + +void _arith_bernoulli_number_vec_zeta(fmpz * num, fmpz * den, slong n) + + Sets the elements of \code{num} and \code{den} to the reduced + numerators and denominators of $B_0, B_1, B_2, \ldots, B_{n-1}$ + inclusive. Uses repeated direct calls to\\ + \code{_arith_bernoulli_number_zeta}. + +void _arith_bernoulli_number_vec_multi_mod(fmpz * num, fmpz * den, slong n) + + Sets the elements of \code{num} and \code{den} to the reduced + numerators and denominators of $B_0, B_1, B_2, \ldots, B_{n-1}$ + inclusive. Uses the generating function + + $$\frac{x^2}{\cosh(x)-1} = \sum_{k=0}^{\infty} + \frac{(2-4k) B_{2k}}{(2k)!} x^{2k}$$ + + which is evaluated modulo several limb-size primes using \code{nmod_poly} + arithmetic to yield the numerators of the Bernoulli numbers after + multiplication by the denominators and CRT reconstruction. This formula, + given (incorrectly) in \citep{BuhlerCrandallSompolski1992}, saves about + half of the time compared to the usual generating function $x/(e^x-1)$ + since the odd terms vanish. + +******************************************************************************* + + Euler numbers and polynomials + + Euler numbers are the integers $E_n$ defined by + $$\frac{1}{\cosh(t)} = \sum_{n=0}^{\infty} \frac{E_n}{n!} t^n.$$ + With this convention, the odd-indexed numbers are zero and the even + ones alternate signs, viz. + $E_0, E_1, E_2, \ldots = 1, 0, -1, 0, 5, 0, -61, 0, 1385, 0, \ldots$. + The corresponding Euler polynomials are defined by + $$\frac{2e^{xt}}{e^t+1} = \sum_{n=0}^{\infty} \frac{E_n(x)}{n!} t^n.$$ + +******************************************************************************* + +void arith_euler_number(fmpz_t res, ulong n) + + Sets \code{res} to the Euler number $E_n$. Currently calls + \code{_arith_euler_number_zeta}. + +void arith_euler_number_vec(fmpz * res, slong n) + + Computes the Euler numbers $E_0, E_1, \dotsc, E_{n-1}$ for $n \geq 0$ + and stores the result in \code{res}, which must be an initialised + \code{fmpz} vector of sufficient size. + + This function evaluates the even-index $E_k$ modulo several limb-size + primes using the generating function and \code{nmod_poly} arithmetic. + A tight bound for the number of needed primes is computed using + \code{arith_euler_number_size}, and the final integer values are recovered + using balanced CRT reconstruction. + +double arith_euler_number_size(ulong n) + + Returns $b$ such that $|E_n| < 2^{\lfloor b \rfloor}$, using the inequality + $$|E_n| < \frac{2^{n+2} n!}{\pi^{n+1}}$$ and $n! \le (n+1)^{n+1} e^{-n}$. + No special treatment is given to odd $n$. + Accuracy is not guaranteed if $n > 10^{14}$. + +void euler_polynomial(fmpq_poly_t poly, ulong n) + + Sets \code{poly} to the Euler polynomial $E_n(x)$. Uses the formula + $$E_n(x) = \frac{2}{n+1}\left(B_{n+1}(x) - + 2^{n+1}B_{n+1}\left(\frac{x}{2}\right)\right),$$ + with the Bernoulli polynomial $B_{n+1}(x)$ evaluated once + using \code{bernoulli_polynomial} and then rescaled. + +void _arith_euler_number_zeta(fmpz_t res, ulong n) + + Sets \code{res} to the Euler number $E_n$. For even $n$, this function + uses the relation $$|E_n| = \frac{2^{n+2} n!}{\pi^{n+1}} L(n+1)$$ + where $L(n+1)$ denotes the Dirichlet $L$-function with character + $\chi = \{ 0, 1, 0, -1 \}$. + +******************************************************************************* + + Legendre polynomials + +******************************************************************************* + +void arith_legendre_polynomial(fmpq_poly_t poly, ulong n) + + Sets \code{poly} to the $n$-th Legendre polynomial + $$P_n(x) = \frac{1}{2^n n!} \frac{d^n}{dx^n} \left[ + \left(x^2-1\right)^n \right].$$ + The coefficients are calculated using a hypergeometric recurrence. + To improve performance, the common denominator is computed in one step + and the coefficients are evaluated using integer arithmetic. The + denominator is given by + $\gcd(n!,2^n) = 2^{\lfloor n/2 \rfloor + \lfloor n/4 \rfloor + \ldots}.$ + +void arith_chebyshev_t_polynomial(fmpz_poly_t poly, ulong n) + + Sets \code{poly} to the Chebyshev polynomial of the first kind $T_n(x)$, + defined formally by $T_n(x) = \cos(n \cos^{-1}(x))$. The coefficients are + calculated using a hypergeometric recurrence. + +void arith_chebyshev_u_polynomial(fmpz_poly_t poly, ulong n) + + Sets \code{poly} to the Chebyshev polynomial of the first kind $U_n(x)$, + which satisfies $(n+1) U_n(x) = T'_{n+1}(x)$. + The coefficients are calculated using a hypergeometric recurrence. + +******************************************************************************* + + Multiplicative functions + +******************************************************************************* + +void arith_euler_phi(fmpz_t res, const fmpz_t n) + + Sets \code{res} to the Euler totient function $\phi(n)$, counting the + number of positive integers less than or equal to $n$ that are coprime + to $n$. + +int arith_moebius_mu(const fmpz_t n) + + Computes the Moebius function $\mu(n)$, which is defined as $\mu(n) = 0$ + if $n$ has a prime factor of multiplicity greater than $1$, $\mu(n) = -1$ + if $n$ has an odd number of distinct prime factors, and $\mu(n) = 1$ if + $n$ has an even number of distinct prime factors. By convention, + $\mu(0) = 0$. + +void arith_divisor_sigma(fmpz_t res, const fmpz_t n, ulong k) + + Sets \code{res} to $\sigma_k(n)$, the sum of $k$th powers of all + divisors of $n$. + +void arith_divisors(fmpz_poly_t res, const fmpz_t n) + + Set the coefficients of the polynomial \code{res} to the divisors of $n$, + including $1$ and $n$ itself, in ascending order. + +void arith_ramanujan_tau(fmpz_t res, const fmpz_t n) + + Sets \code{res} to the Ramanujan tau function $\tau(n)$ which is the + coefficient of $q^n$ in the series expansion of + $f(q) = q \prod_{k \geq 1} \bigl(1 - q^k\bigr)^{24}$. + + We factor $n$ and use the identity $\tau(pq) = \tau(p) \tau(q)$ + along with the recursion + $\tau(p^{r+1}) = \tau(p) \tau(p^r) - p^{11} \tau(p^{r-1})$ + for prime powers. + + The base values $\tau(p)$ are obtained using the function + \code{arith_ramanujan_tau_series()}. Thus the speed of + \code{arith_ramanujan_tau()} depends on the largest prime factor of $n$. + + Future improvement: optimise this function for small $n$, which + could be accomplished using a lookup table or by calling + \code{arith_ramanujan_tau_series()} directly. + +void arith_ramanujan_tau_series(fmpz_poly_t res, slong n) + + Sets \code{res} to the polynomial with coefficients + $\tau(0),\tau(1), \dotsc, \tau(n-1)$, giving the initial $n$ terms + in the series expansion of + $f(q) = q \prod_{k \geq 1} \bigl(1-q^k\bigr)^{24}$. + + We use the theta function identity + + \begin{equation*} + f(q) = q \Biggl( \sum_{k \geq 0} (-1)^k (2k+1) q^{k(k+1)/2} \Biggr)^8 + \end{equation*} + + which is evaluated using three squarings. The first squaring is done + directly since the polynomial is very sparse at this point. + + +******************************************************************************* + + Cyclotomic polynomials + +******************************************************************************* + +void _arith_cyclotomic_polynomial(fmpz * a, ulong n, mp_ptr factors, + slong num_factors, ulong phi) + + Sets \code{a} to the lower half of the cyclotomic polynomial $\Phi_n(x)$, + given $n \ge 3$ which must be squarefree. + + A precomputed array containing the prime factors of $n$ must be provided, + as well as the value of the Euler totient function $\phi(n)$ as \code{phi}. + If $n$ is even, 2 must be the first factor in the list. + + The degree of $\Phi_n(x)$ is exactly $\phi(n)$. Only the low + $(\phi(n) + 1) / 2$ coefficients are written; the high coefficients + can be obtained afterwards by copying the low coefficients + in reverse order, since $\Phi_n(x)$ is a palindrome for $n \ne 1$. + + We use the sparse power series algorithm described as Algorithm 4 + \cite{ArnoldMonagan2011}. The algorithm is based on the identity + + $$\Phi_n(x) = \prod_{d|n} (x^d - 1)^{\mu(n/d)}.$$ + + Treating the polynomial as a power series, the multiplications and + divisions can be done very cheaply using repeated additions and + subtractions. The complexity is $O(2^k \phi(n))$ where $k$ is the + number of prime factors in $n$. + + To improve efficiency for small $n$, we treat the \code{fmpz} + coefficients as machine integers when there is no risk of overflow. + The following bounds are given in Table 6 of \cite{ArnoldMonagan2011}: + + For $n < 10163195$, the largest coefficient in any $\Phi_n(x)$ + has 27 bits, so machine arithmetic is safe on 32 bits. + + For $n < 169828113$, the largest coefficient in any $\Phi_n(x)$ + has 60 bits, so machine arithmetic is safe on 64 bits. + + Further, the coefficients are always $\pm 1$ or 0 if there are + exactly two prime factors, so in this case machine arithmetic can be + used as well. + + Finally, we handle two special cases: if there is exactly one prime + factor $n = p$, then $\Phi_n(x) = 1 + x + x^2 + \ldots + x^{n-1}$, + and if $n = 2m$, we use $\Phi_n(x) = \Phi_m(-x)$ to fall back + to the case when $n$ is odd. + +void arith_cyclotomic_polynomial(fmpz_poly_t poly, ulong n) + + Sets \code{poly} to the $n$th cyclotomic polynomial, defined as + + $$\Phi_n(x) = \prod_{\omega} (x-\omega)$$ + + where $\omega$ runs over all the $n$th primitive roots of unity. + + We factor $n$ into $n = qs$ where $q$ is squarefree, + and compute $\Phi_q(x)$. Then $\Phi_n(x) = \Phi_q(x^s)$. + +void _arith_cos_minpoly(fmpz * coeffs, slong d, ulong n) + + For $n \ge 1$, sets \code{(coeffs, d+1)} to the minimal polynomial + $\Psi_n(x)$ of $\cos(2 \pi / n)$, scaled to have integer coefficients + by multiplying by $2^d$ ($2^{d-1}$ when $n$ is a power of two). + + The polynomial $\Psi_n(x)$ is described in \cite{WaktinsZeitlin1993}. + As proved in that paper, the roots of $\Psi_n(x)$ for $n \ge 3$ are + $\cos(2 \pi k / n)$ where $0 \le k < d$ and where $\gcd(k, n) = 1$. + + To calculate $\Psi_n(x)$, we compute the roots numerically with MPFR + and use a balanced product tree to form a polynomial with fixed-point + coefficients, i.e. an approximation of $2^p 2^d \Psi_n(x)$. + + To determine the precision $p$, we note that the coefficients + in $\prod_{i=1}^d (x - \alpha)$ can be bounded by the central + coefficient in the binomial expansion of $(x+1)^d$. + + When $n$ is an odd prime, we use a direct formula for the coefficients + (\url{http://mathworld.wolfram.com/TrigonometryAngles.html}). + +void arith_cos_minpoly(fmpz_poly_t poly, ulong n) + + Sets \code{poly} to the minimal polynomial $\Psi_n(x)$ of + $\cos(2 \pi / n)$, scaled to have integer coefficients. This + polynomial has degree 1 if $n = 1$ or $n = 2$, and + degree $\phi(n) / 2$ otherwise. + + We allow $n = 0$ and define $\Psi_0 = 1$. + + +******************************************************************************* + + Swinnerton-Dyer polynomials + +******************************************************************************* + +void arith_swinnerton_dyer_polynomial(fmpz_poly_t poly, ulong n) + + Sets \code{poly} to the Swinnerton-Dyer polynomial $S_n$, defined as + the integer polynomial + $$S_n = \prod (x \pm \sqrt{2} \pm \sqrt{3} + \pm \sqrt{5} \pm \ldots \pm \sqrt{p_n})$$ + where $p_n$ denotes the $n$-th prime number and all combinations + of signs are taken. This polynomial has degree $2^n$ and is + irreducible over the integers. + + +******************************************************************************* + + Landau's function + +******************************************************************************* + +void arith_landau_function_vec(fmpz * res, slong len) + + Computes the first \code{len} values of Landau's function $g(n)$ + starting with $g(0)$. Landau's function gives the largest order + of an element of the symmetric group $S_n$. + + Implements the ``basic algorithm'' given in + \cite{DelegliseNicolasZimmermann2009}. The running time is + $O(n^{3/2} / \sqrt{\log n})$. + + +******************************************************************************* + + Dedekind sums + + Most of the definitions and relations used in the following section + are given by Apostol \cite{Apostol1997}. The Dedekind sum $s(h,k)$ is + defined for all integers $h$ and $k$ as + + $$s(h,k) = \sum_{i=1}^{k-1} \left(\left(\frac{i}{k}\right)\right) + \left(\left(\frac{hi}{k}\right)\right)$$ + + where + + $$((x))=\begin{cases} + x-\lfloor x\rfloor-1/2 &\mbox{if } + x\in\mathbb{Q}\setminus\mathbb{Z}\\ + 0 &\mbox{if }x\in\mathbb{Z}. + \end{cases}$$ + + If $0 < h < k$ and $(h,k) = 1$, this reduces to + + $$s(h,k) = \sum_{i=1}^{k-1} \frac{i}{k} + \left(\frac{hi}{k}-\left\lfloor\frac{hi}{k}\right\rfloor + -\frac{1}{2}\right).$$ + + The main formula for evaluating the series above is the following. + Letting $r_0 = k$, $r_1 = h$, $r_2, r_3, \ldots, r_n, r_{n+1} = 1$ + be the remainder sequence in the Euclidean algorithm for + computing GCD of $h$ and $k$, + + $$s(h,k) = \frac{1-(-1)^n}{8} - \frac{1}{12} \sum_{i=1}^{n+1} + (-1)^i \left(\frac{1+r_i^2+r_{i-1}^2}{r_i r_{i-1}}\right).$$ + + Writing $s(h,k) = p/q$, some useful properties employed are + $|s| < k / 12$, $q | 6k$ and $2|p| < k^2$. + +******************************************************************************* + +void arith_dedekind_sum_naive(fmpq_t s, const fmpz_t h, const fmpz_t k) + + Computes $s(h,k)$ for arbitrary $h$ and $k$ using a straightforward + implementation of the defining sum using \code{fmpz} arithmetic. + This function is slow except for very small $k$ and is mainly + intended to be used for testing purposes. + +double arith_dedekind_sum_coprime_d(double h, double k) + + Returns an approximation of $s(h,k)$ computed by evaluating the + remainder sequence sum using double-precision arithmetic. + Assumes that $0 < h < k$ and $(h,k) = 1$, and that $h$, $k$ and + their remainders can be represented exactly as doubles, e.g. + $k < 2^{53}$. + + We give a rough error analysis with IEEE double precision arithmetic, + assuming $2 k^2 < 2^{53}$. By assumption, the terms in the sum evaluate + exactly apart from the division. Thus each term is bounded in magnitude + by $2k$ and its absolute error is bounded by $k 2^{-52}$. + By worst-case analysis of the Euclidean algorithm, we also know that + no more than 40 terms will be added. + + It follows that the absolute error is at most $C k 2^{-53}$ for + some constant $C$. If we multiply the output by $6 k$ in order + to obtain an integer numerator, the order of magnitude of the error + is around $6 C k^2 2^{-53}$, so rounding to the nearest integer gives + a correct numerator whenever $k < 2^{26-d}$ for some small number of + guard bits $d$. A computation has shown that $d = 5$ is sufficient, + i.e. this function can be used for exact computation when + $k < 2^{21} \approx 2 \times 10^6$. This bound can likely be improved. + +void arith_dedekind_sum_coprime_large(fmpq_t s, const fmpz_t h, const fmpz_t k) + + Computes $s(h,k)$ for $h$ and $k$ satisfying $0 \le h \le k$ and + $(h,k) = 1$. This function effectively evaluates the remainder + sequence sum using \code{fmpz} arithmetic, without optimising for + any special cases. To avoid rational arithmetic, we use + the integer algorithm of Knuth \cite{Knuth1977}. + +void arith_dedekind_sum_coprime(fmpq_t s, const fmpz_t h, const fmpz_t k) + + Computes $s(h,k)$ for $h$ and $k$ satisfying $0 \le h \le k$ + and $(h,k) = 1$. + + This function calls \code{arith_dedekind_sum_coprime_d} if $k$ is small + enough for a double-precision estimate of the sum to yield a correct + numerator upon multiplication by $6k$ and rounding to the nearest integer. + Otherwise, it calls \code{arith_dedekind_sum_coprime_large}. + +void arith_dedekind_sum(fmpq_t s, const fmpz_t h, const fmpz_t k) + + Computes $s(h,k)$ for arbitrary $h$ and $k$. If the caller + can guarantee $0 < h < k$ and $(h,k) = 1$ ahead of time, it is always + cheaper to call \code{arith_dedekind_sum_coprime}. + + This function uses the following identities to reduce the general + case to the situation where $0 < h < k$ and $(h,k) = 1$: + If $k \le 2$ or $h = 0$, $s(h,k) = 0$. + If $h < 0$, $s(h,k) = -s(-h,k)$. + For any $q > 0$, $s(qh,qk) = s(h,k)$. + If $0 < k < h$ and $(h,k) = 1$, + $s(h,k) = (1+h(h-3k)+k^2) / (12hk) - t(k,h).$ + +******************************************************************************* + + Number of partitions + +******************************************************************************* + +void arith_number_of_partitions_vec(fmpz * res, slong len) + + Computes first \code{len} values of the partition function $p(n)$ + starting with $p(0)$. Uses inversion of Euler's pentagonal series. + +void arith_number_of_partitions_nmod_vec(mp_ptr res, slong len, nmod_t mod) + + Computes first \code{len} values of the partition function $p(n)$ + starting with $p(0)$, modulo the modulus defined by \code{mod}. + Uses inversion of Euler's pentagonal series. + +void arith_hrr_expsum_factored(trig_prod_t prod, mp_limb_t k, mp_limb_t n) + + Symbolically evaluates the exponential sum + + $$A_k(n) = \sum_{h=0}^{k-1} + \exp\left(\pi i \left[ s(h,k) - \frac{2hn}{k}\right]\right)$$ + + appearing in the Hardy-Ramanujan-Rademacher formula, where $s(h,k)$ is a + Dedekind sum. + + Rather than evaluating the sum naively, we factor $A_k(n)$ into a + product of cosines based on the prime factorisation of $k$. This + process is based on the identities given in \cite{Whiteman1956}. + + The special \code{trig_prod_t} structure \code{prod} represents a + product of cosines of rational arguments, multiplied by an algebraic + prefactor. It must be pre-initialised with \code{trig_prod_init}. + + This function assumes that $24k$ and $24n$ do not overflow a single limb. + If $n$ is larger, it can be pre-reduced modulo $k$, since $A_k(n)$ + only depends on the value of $n \bmod k$. + +void arith_number_of_partitions_mpfr(mpfr_t x, ulong n) + + Sets the pre-initialised MPFR variable $x$ to the exact value of $p(n)$. + The value is computed using the Hardy-Ramanujan-Rademacher formula. + + The precision of $x$ will be changed to allow $p(n)$ to be represented + exactly. The interface of this function may be updated in the future + to allow computing an approximation of $p(n)$ to smaller precision. + + The Hardy-Ramanujan-Rademacher formula is given with error bounds + in \cite{Rademacher1937}. We evaluate it in the form + + $$p(n) = \sum_{k=1}^N B_k(n) U(C/k) + R(n,N)$$ + + where + + $$U(x) = \cosh(x) + \frac{\sinh(x)}{x}, + \quad C = \frac{\pi}{6} \sqrt{24n-1}$$ + + $$B_k(n) = \sqrt{\frac{3}{k}} \frac{4}{24n-1} A_k(n)$$ + + and where $A_k(n)$ is a certain exponential sum. The remainder satisfies + + $$|R(n,N)| < \frac{44 \pi^2}{225 \sqrt{3}} N^{-1/2} + + \frac{\pi \sqrt{2}}{75} \left(\frac{N}{n-1}\right)^{1/2} + \sinh\left(\pi \sqrt{\frac{2}{3}} \frac{\sqrt{n}}{N} \right).$$ + + We choose $N$ such that $|R(n,N)| < 0.25$, and a working precision + at term $k$ such that the absolute error of the term is expected to be + less than $0.25 / N$. We also use a summation variable with increased + precision, essentially making additions exact. Thus the sum of errors + adds up to less than 0.5, giving the correct value of $p(n)$ when + rounding to the nearest integer. + + The remainder estimate at step $k$ provides an upper bound for the size + of the $k$-th term. We add $\log_2 N$ bits to get low bits in the terms + below $0.25 / N$ in magnitude. + + Using \code{arith_hrr_expsum_factored}, each $B_k(n)$ evaluation + is broken down to a product of cosines of exact rational multiples + of $\pi$. We transform all angles to $(0, \pi/4)$ for optimal accuracy. + + Since the evaluation of each term involves only $O(\log k)$ multiplications + and evaluations of trigonometric functions of small angles, the + relative rounding error is at most a few bits. We therefore just add + an additional $\log_2 (C/k)$ bits for the $U(x)$ when $x$ is large. + The cancellation of terms in $U(x)$ is of no concern, since Rademacher's + bound allows us to terminate before $x$ becomes small. + + This analysis should be performed in more detail to give a rigorous + error bound, but the precision currently implemented is almost + certainly sufficient, not least considering that Rademacher's + remainder bound significantly overshoots the actual values. + + To improve performance, we switch to doubles when the working precision + becomes small enough. We also use a separate accumulator variable + which gets added to the main sum periodically, in order to avoid + costly updates of the full-precision result when $n$ is large. + +void arith_number_of_partitions(fmpz_t x, ulong n) + + Sets $x$ to $p(n)$, the number of ways that $n$ can be written + as a sum of positive integers without regard to order. + + This function uses a lookup table for $n < 128$ (where $p(n) < 2^{32}$), + and otherwise calls \code{arith_number_of_partitions_mpfr}. + +******************************************************************************* + + Sums of squares + +******************************************************************************* + +void arith_sum_of_squares(fmpz_t r, ulong k, const fmpz_t n) + + Sets $r$ to the number of ways $r_k(n)$ in which $n$ can be represented + as a sum of $k$ squares. + + If $k = 2$ or $k = 4$, we write $r_k(n)$ as a divisor sum. + + Otherwise, we either recurse on $k$ or compute the theta function + expansion up to $O(x^{n+1})$ and read off the last coefficient. + This is generally optimal. + +void arith_sum_of_squares_vec(fmpz * r, ulong k, slong n) + + For $i = 0, 1, \ldots, n-1$, sets $r_i$ to the number of + representations of $i$ a sum of $k$ squares, $r_k(i)$. + This effectively computes the $q$-expansion of $\vartheta_3(q)$ + raised to the $k$th power, i.e. + + $$\vartheta_3^k(q) = \left( \sum_{i=-\infty}^{\infty} q^{i^2} \right)^k.$$ + + +******************************************************************************* + + MPFR extras + +******************************************************************************* + +void mpfr_pi_chudnovsky(mpfr_t x, mpfr_rnd_t rnd) + + Sets \code{x} to $\pi$, rounded in the direction \code{rnd}. + + Uses the Chudnovsky algorithm, which typically is about four times + faster than the MPFR default function. As currently implemented, the + value is not cached for repeated use. + diff --git a/external/flint-2.4.3/arith/euler_number.c b/external/flint-2.4.3/arith/euler_number.c new file mode 100644 index 0000000..58bf324 --- /dev/null +++ b/external/flint-2.4.3/arith/euler_number.c @@ -0,0 +1,31 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "arith.h" + +void arith_euler_number(fmpz_t res, ulong n) +{ + _arith_euler_number_zeta(res, n); +} diff --git a/external/flint-2.4.3/arith/euler_number_size.c b/external/flint-2.4.3/arith/euler_number_size.c new file mode 100644 index 0000000..dbbeba5 --- /dev/null +++ b/external/flint-2.4.3/arith/euler_number_size.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "arith.h" + +double arith_euler_number_size(ulong n) +{ + double x; + + x = n + 2; + x += ((n + 1) * log(n + 1) - n) * 1.44269504088897; /* 1/log(2) */ + x -= 1.6514961294723*(n+1); /* log2(pi) */ + + return x + 2; +} diff --git a/external/flint-2.4.3/arith/euler_number_vec.c b/external/flint-2.4.3/arith/euler_number_vec.c new file mode 100644 index 0000000..8a6e013 --- /dev/null +++ b/external/flint-2.4.3/arith/euler_number_vec.c @@ -0,0 +1,147 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "arith.h" + +/* Computes length-m vector containing |E_{2k}| */ +static void +__euler_number_vec_mod_p(mp_ptr res, mp_ptr tmp, slong m, nmod_t mod) +{ + mp_limb_t fac, c; + slong k; + + /* Divide by factorials */ + fac = n_factorial_mod2_preinv(2*(m-1), mod.n, mod.ninv); + c = n_invmod(fac, mod.n); + for (k = m - 1; k >= 0; k--) + { + tmp[k] = c; + c = n_mulmod2_preinv(c, (2*k)*(2*k-1), mod.n, mod.ninv); + } + + _nmod_poly_inv_series(res, tmp, m, mod); + + /* Multiply by factorials */ + c = UWORD(1); + for (k = 0; k < m; k++) + { + res[k] = n_mulmod2_preinv(res[k], c, mod.n, mod.ninv); + c = n_mulmod2_preinv(c, (2*k+1)*(2*k+2), mod.n, mod.ninv); + c = n_negmod(c, mod.n); + } +} + +#define CRT_MAX_RESOLUTION 16 + +void __euler_number_vec_multi_mod(fmpz * res, slong n) +{ + fmpz_comb_t comb[CRT_MAX_RESOLUTION]; + fmpz_comb_temp_t temp[CRT_MAX_RESOLUTION]; + mp_limb_t * primes; + mp_limb_t * residues; + mp_ptr * polys; + mp_ptr temppoly; + nmod_t mod; + slong i, j, k, m, num_primes, num_primes_k, resolution; + mp_bitcnt_t size, prime_bits; + + if (n < 1) + return; + + /* Number of nonzero entries */ + m = (n + 1) / 2; + + resolution = FLINT_MAX(1, FLINT_MIN(CRT_MAX_RESOLUTION, m / 16)); + + size = arith_euler_number_size(n); + prime_bits = FLINT_BITS - 1; + num_primes = (size + prime_bits - 1) / prime_bits; + + primes = flint_malloc(num_primes * sizeof(mp_limb_t)); + residues = flint_malloc(num_primes * sizeof(mp_limb_t)); + polys = flint_malloc(num_primes * sizeof(mp_ptr)); + + /* Compute Euler numbers mod p */ + primes[0] = n_nextprime(UWORD(1)<num_primes >= num_primes_k) + break; + } + num_primes_k = comb[i]->num_primes; + for (j = 0; j < num_primes_k; j++) + residues[j] = polys[j][k / 2]; + fmpz_multi_CRT_ui(res + k, residues, comb[i], temp[i], 0); + if (k % 4) + fmpz_neg(res + k, res + k); + } + + /* Cleanup */ + for (k = 0; k < num_primes; k++) + _nmod_vec_clear(polys[k]); + _nmod_vec_clear(temppoly); + for (i = 0; i < resolution; i++) + { + fmpz_comb_temp_clear(temp[i]); + fmpz_comb_clear(comb[i]); + } + + flint_free(primes); + flint_free(residues); + flint_free(polys); +} + +void arith_euler_number_vec(fmpz * res, slong n) +{ + __euler_number_vec_multi_mod(res, n); +} diff --git a/external/flint-2.4.3/arith/euler_number_zeta.c b/external/flint-2.4.3/arith/euler_number_zeta.c new file mode 100644 index 0000000..6dbc58e --- /dev/null +++ b/external/flint-2.4.3/arith/euler_number_zeta.c @@ -0,0 +1,80 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "arith.h" + +void _arith_euler_number_zeta(fmpz_t res, ulong n) +{ + mpz_t r; + mpfr_t t, z, pi; + mp_bitcnt_t prec, pi_prec; + + if (n % 2) + { + fmpz_zero(res); + return; + } + + if (n < SMALL_EULER_LIMIT) + { + fmpz_set_ui(res, euler_number_small[n / 2]); + if (n % 4 == 2) + fmpz_neg(res, res); + return; + } + + prec = arith_euler_number_size(n) + 10; + pi_prec = prec + FLINT_BIT_COUNT(n); + + mpz_init(r); + mpfr_init2(t, prec); + mpfr_init2(z, prec); + mpfr_init2(pi, pi_prec); + + flint_mpz_fac_ui(r, n); + mpfr_set_z(t, r, GMP_RNDN); + mpfr_mul_2exp(t, t, n + 2, GMP_RNDN); + + /* pi^(n + 1) * L(n+1) */ + mpfr_zeta_inv_euler_product(z, n + 1, 1); + mpfr_const_pi(pi, GMP_RNDN); + mpfr_pow_ui(pi, pi, n + 1, GMP_RNDN); + mpfr_mul(z, z, pi, GMP_RNDN); + + mpfr_div(t, t, z, GMP_RNDN); + + /* round */ + mpfr_round(t, t); + mpfr_get_z(r, t, GMP_RNDN); + fmpz_set_mpz(res, r); + + if (n % 4 == 2) + fmpz_neg(res, res); + + mpz_clear(r); + mpfr_clear(t); + mpfr_clear(z); + mpfr_clear(pi); +} diff --git a/external/flint-2.4.3/arith/euler_phi.c b/external/flint-2.4.3/arith/euler_phi.c new file mode 100644 index 0000000..f144501 --- /dev/null +++ b/external/flint-2.4.3/arith/euler_phi.c @@ -0,0 +1,67 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz.h" +#include "arith.h" + +void arith_euler_phi(fmpz_t res, const fmpz_t n) +{ + fmpz_factor_t factors; + fmpz_t t; + ulong exp; + slong i; + + if (fmpz_sgn(n) <= 0) + { + fmpz_zero(res); + return; + } + + if (fmpz_abs_fits_ui(n)) + { + fmpz_set_ui(res, n_euler_phi(fmpz_get_ui(n))); + return; + } + + fmpz_factor_init(factors); + fmpz_factor(factors, n); + fmpz_one(res); + + fmpz_init(t); + for (i = 0; i < factors->num; i++) + { + fmpz_sub_ui(t, factors->p + i, UWORD(1)); + fmpz_mul(res, res, t); + exp = factors->exp[i]; + if (exp != 1) + { + fmpz_pow_ui(t, factors->p + i, exp - UWORD(1)); + fmpz_mul(res, res, t); + } + } + + fmpz_clear(t); + fmpz_factor_clear(factors); +} diff --git a/external/flint-2.4.3/arith/euler_polynomial.c b/external/flint-2.4.3/arith/euler_polynomial.c new file mode 100644 index 0000000..b56f476 --- /dev/null +++ b/external/flint-2.4.3/arith/euler_polynomial.c @@ -0,0 +1,53 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "arith.h" + +void arith_euler_polynomial(fmpq_poly_t poly, ulong n) +{ + fmpz_t t; + slong k; + + if (n == 0) + { + fmpq_poly_set_ui(poly, UWORD(1)); + return; + } + + arith_bernoulli_polynomial(poly, n + 1); + + fmpz_init(t); + fmpz_set_si(t, WORD(-2)); + for (k = n; k >= 0; k--) + { + fmpz_mul(poly->coeffs + k, poly->coeffs + k, t); + fmpz_mul_ui(t, t, UWORD(2)); + fmpz_sub_ui(t, t, UWORD(2)); + } + fmpz_zero(poly->coeffs + n + 1); + fmpz_mul_ui(poly->den, poly->den, n + 1); + fmpq_poly_canonicalise(poly); + fmpz_clear(t); +} diff --git a/external/flint-2.4.3/arith/harmonic_number.c b/external/flint-2.4.3/arith/harmonic_number.c new file mode 100644 index 0000000..d50c78d --- /dev/null +++ b/external/flint-2.4.3/arith/harmonic_number.c @@ -0,0 +1,124 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include "mpn_extras.h" +#include "arith.h" + +#if FLINT64 +#define FLINT_HARMONIC_MAX_TINY 46 +#else +#define FLINT_HARMONIC_MAX_TINY 24 +#endif + +const mp_limb_t FLINT_HARMONIC_TINY_P[] = +{ + UWORD(0), UWORD(1), UWORD(3), UWORD(11), UWORD(25), UWORD(137), UWORD(49), UWORD(363), UWORD(761), UWORD(7129), UWORD(7381), + UWORD(83711), UWORD(86021), UWORD(1145993), UWORD(1171733), UWORD(1195757), UWORD(2436559), UWORD(42142223), + UWORD(14274301), UWORD(275295799), UWORD(55835135), UWORD(18858053), UWORD(19093197), UWORD(444316699), + UWORD(1347822955), +#if FLINT64 + UWORD(34052522467), UWORD(34395742267), UWORD(312536252003), UWORD(315404588903), + UWORD(9227046511387), UWORD(9304682830147), UWORD(290774257297357), UWORD(586061125622639), + UWORD(53676090078349), UWORD(54062195834749), UWORD(54437269998109), UWORD(54801925434709), + UWORD(2040798836801833), UWORD(2053580969474233), UWORD(2066035355155033), + UWORD(2078178381193813), UWORD(85691034670497533), UWORD(12309312989335019), + UWORD(532145396070491417), UWORD(5884182435213075787), UWORD(5914085889685464427), + UWORD(5943339269060627227), +#endif +}; + +const mp_limb_t FLINT_HARMONIC_TINY_Q[] = +{ + UWORD(1), UWORD(1), UWORD(2), UWORD(6), UWORD(12), UWORD(60), UWORD(20), UWORD(140), UWORD(280), UWORD(2520), UWORD(2520), + UWORD(27720), UWORD(27720), UWORD(360360), UWORD(360360), UWORD(360360), UWORD(720720), UWORD(12252240), + UWORD(4084080), UWORD(77597520), UWORD(15519504), UWORD(5173168), UWORD(5173168), UWORD(118982864), + UWORD(356948592), +#if FLINT64 + UWORD(8923714800), UWORD(8923714800), UWORD(80313433200), UWORD(80313433200), UWORD(2329089562800), + UWORD(2329089562800), UWORD(72201776446800), UWORD(144403552893600), UWORD(13127595717600), + UWORD(13127595717600), UWORD(13127595717600), UWORD(13127595717600), UWORD(485721041551200), + UWORD(485721041551200), UWORD(485721041551200), UWORD(485721041551200), + UWORD(19914562703599200), UWORD(2844937529085600), UWORD(122332313750680800), + UWORD(1345655451257488800), UWORD(1345655451257488800), UWORD(1345655451257488800), +#endif +}; + +static void +_mpq_harmonic_odd_balanced(fmpz_t num, fmpz_t den, slong n) +{ + mpz_t p, q; + + mp_ptr t, v; + mp_size_t ts, vs; + slong size; + + if (n <= 0) + { + fmpz_zero(num); + fmpz_one(den); + return; + } + + /* TODO: we could avoid the copying/allocation overhead when there + is guaranteed to be sufficient space in res already */ + + size = FLINT_BIT_COUNT(n) * (n+2) + 2*FLINT_BITS; + mpz_init2(p, size); + mpz_init2(q, size); + t = p->_mp_d; + v = q->_mp_d; + + flint_mpn_harmonic_odd_balanced(t, &ts, v, &vs, 1, n+1, n, 1); + p->_mp_size = ts; + q->_mp_size = vs; + + fmpz_set_mpz(num, p); + fmpz_set_mpz(den, q); + + mpz_clear(p); + mpz_clear(q); + + _fmpq_canonicalise(num, den); +} + +void _arith_harmonic_number(fmpz_t num, fmpz_t den, slong n) +{ + n = FLINT_MAX(n, 0); + + if (n <= FLINT_HARMONIC_MAX_TINY) + { + fmpz_set_ui(num, FLINT_HARMONIC_TINY_P[n]); + fmpz_set_ui(den, FLINT_HARMONIC_TINY_Q[n]); + } + else + { + _mpq_harmonic_odd_balanced(num, den, n); + } +} + +void arith_harmonic_number(fmpq_t x, slong n) +{ + _arith_harmonic_number(fmpq_numref(x), fmpq_denref(x), n); +} diff --git a/external/flint-2.4.3/arith/landau_function_vec.c b/external/flint-2.4.3/arith/landau_function_vec.c new file mode 100644 index 0000000..fb46d4d --- /dev/null +++ b/external/flint-2.4.3/arith/landau_function_vec.c @@ -0,0 +1,68 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "arith.h" + +void arith_landau_function_vec(fmpz * res, slong len) +{ + mp_limb_t p, pmax; + mp_limb_t pk, pkhi; + fmpz_t a; + ulong k, n; + + if (len < 1) + return; + + for (k = 0; k < len; k++) + fmpz_one(res + k); + + pmax = 1.328 * sqrt(len*log(len) + 1); + + fmpz_init(a); + + for (p = UWORD(2); p <= pmax; p = n_nextprime(p, 0)) + { + for (n = len - 1; n >= p; n--) + { + pk = p; + pkhi = UWORD(0); + + for (k = 1; k <= len; k++) + { + if (pk > n || pkhi) + break; + + fmpz_mul_ui(a, res + n - pk, pk); + if (fmpz_cmp(res + n, a) < 0) + fmpz_set(res + n, a); + + umul_ppmm(pkhi, pk, pk, p); + } + } + } + + fmpz_clear(a); +} diff --git a/external/flint-2.4.3/arith/legendre_polynomial.c b/external/flint-2.4.3/arith/legendre_polynomial.c new file mode 100644 index 0000000..b1df92b --- /dev/null +++ b/external/flint-2.4.3/arith/legendre_polynomial.c @@ -0,0 +1,97 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "arith.h" + +static __inline__ void __legendre_denom(fmpz_t den, ulong n) +{ + ulong d, k; + d = k = n >> 1; + + while (k) + { + k >>= 1; + d += k; + } + + fmpz_one(den); + fmpz_mul_2exp(den, den, d); +} + +void _arith_legendre_polynomial(fmpz * coeffs, fmpz_t den, ulong n) +{ + fmpz * r; + int odd; + slong k; + ulong L; + + L = n / 2; + odd = n % 2; + + r = coeffs + odd; + + __legendre_denom(den, n); + + fmpz_bin_uiui(r, n, L); + fmpz_mul(r, r, den); + if (odd) + fmpz_mul_ui(r, r, L + 1); + fmpz_fdiv_q_2exp(r, r, 2*L); + if (L % 2) + fmpz_neg(r, r); + + for (k = 1; k <= L; k++) + { + fmpz_mul2_uiui(r + 2, r, L + 1 - k, 2*k + 2*L - 1 + 2*odd); + fmpz_divexact2_uiui(r + 2, r + 2, k, 2*k - 1 + 2*odd); + fmpz_neg(r + 2, r + 2); + r += 2; + } + + for (k = 1 - odd; k < n; k += 2) + fmpz_zero(coeffs + k); +} + +void arith_legendre_polynomial(fmpq_poly_t poly, ulong n) +{ + if (n == 0) + { + fmpq_poly_set_ui(poly, UWORD(1)); + return; + } + + fmpq_poly_fit_length(poly, n + 1); + + if (n == 1) + { + fmpz_zero(poly->coeffs); + fmpz_one(poly->coeffs + 1); + fmpz_one(poly->den); + } + else + _arith_legendre_polynomial(poly->coeffs, poly->den, n); + + _fmpq_poly_set_length(poly, n + 1); +} diff --git a/external/flint-2.4.3/arith/moebius_mu.c b/external/flint-2.4.3/arith/moebius_mu.c new file mode 100644 index 0000000..0d896e7 --- /dev/null +++ b/external/flint-2.4.3/arith/moebius_mu.c @@ -0,0 +1,56 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz.h" +#include "arith.h" + +int arith_moebius_mu(const fmpz_t n) +{ + fmpz_factor_t factors; + slong i; + int mu; + + if (fmpz_abs_fits_ui(n)) + return n_moebius_mu(fmpz_get_ui(n)); + + fmpz_factor_init(factors); + fmpz_factor(factors, n); + + mu = 1; + for (i = 0; i < factors->num; i++) + { + if (factors->exp[i] != UWORD(1)) + { + mu = 0; + break; + } + } + + if (factors->num % 2) + mu = -mu; + + fmpz_factor_clear(factors); + return mu; +} diff --git a/external/flint-2.4.3/arith/number_of_partitions.c b/external/flint-2.4.3/arith/number_of_partitions.c new file mode 100644 index 0000000..20ba4a5 --- /dev/null +++ b/external/flint-2.4.3/arith/number_of_partitions.c @@ -0,0 +1,70 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "arith.h" + +/* This nice round number precisely fits on 32 bits */ +#define NUMBER_OF_SMALL_PARTITIONS 128 + +const unsigned int +partitions_lookup[NUMBER_OF_SMALL_PARTITIONS] = +{ + UWORD(1),UWORD(1),UWORD(2),UWORD(3),UWORD(5),UWORD(7),UWORD(11),UWORD(15),UWORD(22),UWORD(30),UWORD(42),UWORD(56),UWORD(77),UWORD(101),UWORD(135), + UWORD(176),UWORD(231),UWORD(297),UWORD(385),UWORD(490),UWORD(627),UWORD(792),UWORD(1002),UWORD(1255),UWORD(1575),UWORD(1958), + UWORD(2436),UWORD(3010),UWORD(3718),UWORD(4565),UWORD(5604),UWORD(6842),UWORD(8349),UWORD(10143),UWORD(12310),UWORD(14883), + UWORD(17977),UWORD(21637),UWORD(26015),UWORD(31185),UWORD(37338),UWORD(44583),UWORD(53174),UWORD(63261),UWORD(75175), + UWORD(89134),UWORD(105558),UWORD(124754),UWORD(147273),UWORD(173525),UWORD(204226),UWORD(239943),UWORD(281589), + UWORD(329931),UWORD(386155),UWORD(451276),UWORD(526823),UWORD(614154),UWORD(715220),UWORD(831820),UWORD(966467), + UWORD(1121505),UWORD(1300156),UWORD(1505499),UWORD(1741630),UWORD(2012558),UWORD(2323520),UWORD(2679689), + UWORD(3087735),UWORD(3554345),UWORD(4087968),UWORD(4697205),UWORD(5392783),UWORD(6185689),UWORD(7089500), + UWORD(8118264),UWORD(9289091),UWORD(10619863),UWORD(12132164),UWORD(13848650),UWORD(15796476),UWORD(18004327), + UWORD(20506255),UWORD(23338469),UWORD(26543660),UWORD(30167357),UWORD(34262962),UWORD(38887673), + UWORD(44108109),UWORD(49995925),UWORD(56634173),UWORD(64112359),UWORD(72533807),UWORD(82010177), + UWORD(92669720),UWORD(104651419),UWORD(118114304),UWORD(133230930),UWORD(150198136),UWORD(169229875), + UWORD(190569292),UWORD(214481126),UWORD(241265379),UWORD(271248950),UWORD(304801365),UWORD(342325709), + UWORD(384276336),UWORD(431149389),UWORD(483502844),UWORD(541946240),UWORD(607163746),UWORD(679903203), + UWORD(761002156),UWORD(851376628),UWORD(952050665),UWORD(1064144451),UWORD(1188908248),UWORD(1327710076), + UWORD(1482074143),UWORD(1653668665),UWORD(1844349560),UWORD(2056148051),UWORD(2291320912), + UWORD(2552338241),UWORD(2841940500),UWORD(3163127352),UWORD(3519222692),UWORD(3913864295) +}; + +void +arith_number_of_partitions(fmpz_t x, ulong n) +{ + if (n < NUMBER_OF_SMALL_PARTITIONS) + { + fmpz_set_ui(x, partitions_lookup[n]); + } + else + { + mpfr_t t; + mpfr_init(t); + arith_number_of_partitions_mpfr(t, n); + mpfr_get_z(_fmpz_promote(x), t, MPFR_RNDN); + _fmpz_demote_val(x); + mpfr_clear(t); + } +} diff --git a/external/flint-2.4.3/arith/number_of_partitions_mpfr.c b/external/flint-2.4.3/arith/number_of_partitions_mpfr.c new file mode 100644 index 0000000..753fb9d --- /dev/null +++ b/external/flint-2.4.3/arith/number_of_partitions_mpfr.c @@ -0,0 +1,539 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + + Inspired by code written for Sage by Jonathan Bober. + +******************************************************************************/ + +#include +#include "arith.h" + +#define DOUBLE_PREC 53 +#define PI 3.141592653589793238462643 +#define INV_LOG2 (1.44269504088896340735992468 + 1e-12) +#define HRR_A (1.1143183348516376904 + 1e-12) /* 44*pi^2/(225*sqrt(3)) */ +#define HRR_B (0.0592384391754448833 + 1e-12) /* pi*sqrt(2)/75 */ +#define HRR_C (2.5650996603237281911 + 1e-12) /* pi*sqrt(2/3) */ +#define HRR_D (1.2424533248940001551 + 1e-12) /* log(2) + log(3)/2 */ + + +#define PI_USE_CHUDNOVSKY 1 +#define PI_CHUDNOVSKY_CUTOFF 1000000 + +#define VERBOSE 0 + + +static double +partitions_remainder_bound(double n, double terms) +{ + return HRR_A/sqrt(terms) + + HRR_B*sqrt(terms/(n-1)) * sinh(HRR_C * sqrt(n)/terms); +} + +/* Crude upper bound, sufficient to estimate the precision */ +static double +log_sinh(double x) +{ + if (x > 4) + return x; + else + return log(x) + x*x*(1/6.); +} + +static double +partitions_remainder_bound_log2(double n, double N) +{ + double t1, t2; + + t1 = log(HRR_A) - 0.5*log(N); + t2 = log(HRR_B) + 0.5*(log(N) - log(n-1)) + log_sinh(HRR_C * sqrt(n)/N); + + return (FLINT_MAX(t1, t2) + 1) * INV_LOG2; +} + +slong +partitions_needed_terms(ulong n) +{ + slong N; + for (N = 1; partitions_remainder_bound_log2(n, N) > 10; N++); + for ( ; partitions_remainder_bound(n, N) > (n > 1500 ? 0.25 : 1); N++); + return N; +} + +static double +partitions_term_bound(double n, double k) +{ + return ((PI*sqrt(24*n-1) / (6.0*k)) + HRR_D - log(24.0*n-1) + 0.5*log(k)) * INV_LOG2; +} + +/* Bound number of prime factors in k */ +static mp_limb_t primorial_tab[] = { + 1, 2, 6, 30, 210, 2310, 30030, 510510, 9699690, 223092870, +#if FLINT64 + UWORD(6469693230), UWORD(200560490130), UWORD(7420738134810), UWORD(304250263527210), + UWORD(13082761331670030), UWORD(614889782588491410) +#endif +}; + +static __inline__ int +bound_primes(ulong k) +{ + int i; + + for (i = 0; i < sizeof(primorial_tab) / sizeof(mp_limb_t); i++) + if (k <= primorial_tab[i]) + return i; + + return i; +} + + +static __inline__ slong +log2_ceil(double x) +{ + /* ceil(log2(n)) = bitcount(n-1); + this is too large if x is a power of two */ + return FLINT_BIT_COUNT((slong) x); +} + +static slong +partitions_prec_bound(ulong n, slong k, slong N) +{ + slong prec; + + prec = partitions_term_bound(n, k); + prec += log2_ceil(8 * N * (26 * (sqrt(n) / k) + 7 * bound_primes(k) + 22)); + + return prec; +} + +double +cos_pi_pq(mp_limb_signed_t p, mp_limb_signed_t q) +{ + /* Force 0 <= p < q */ + p = FLINT_ABS(p); + p %= (2 * q); + if (p >= q) + p = 2 * q - p; + + if (4 * p <= q) + return cos(p * PI / q); + else if (4 * p < 3 * q) + return sin((q - 2*p) * PI / (2 * q)); + else + return -cos((q - p) * PI / q); +} + +void +mpfr_sqrt_z(mpfr_t x, mpz_t z, mpfr_rnd_t rnd) +{ + if (mpz_fits_ulong_p(z)) + mpfr_sqrt_ui(x, flint_mpz_get_ui(z), rnd); + else + { + mpfr_set_z(x, z, rnd); + mpfr_sqrt(x, x, rnd); + } +} + +void +mpfr_set_fmpz(mpfr_t c, const fmpz_t b) +{ + if (COEFF_IS_MPZ(*b)) + mpfr_set_z(c, COEFF_TO_PTR(*b), MPFR_RNDN); + else + mpfr_set_si(c, *b, MPFR_RNDN); +} + +void +mpfr_mul_fmpz(mpfr_t c, mpfr_srcptr a, const fmpz_t b) +{ + if (COEFF_IS_MPZ(*b)) + mpfr_mul_z(c, a, COEFF_TO_PTR(*b), MPFR_RNDN); + else + mpfr_mul_si(c, a, *b, MPFR_RNDN); +} + +void +mpfr_add_fmpz(mpfr_t c, mpfr_srcptr a, const fmpz_t b) +{ + if (COEFF_IS_MPZ(*b)) + mpfr_add_z(c, a, COEFF_TO_PTR(*b), MPFR_RNDN); + else + mpfr_add_si(c, a, *b, MPFR_RNDN); +} + + +void +_fmpz_poly_evaluate_mpfr(mpfr_t res, const fmpz * f, slong len, + const mpfr_t a) +{ + if (len == 0) + mpfr_set_ui(res, 0, MPFR_RNDN); + else if (len == 1) + mpfr_set_fmpz(res, f); + else + { + slong i = len - 1; + mpfr_t t; + mpfr_init2(t, mpfr_get_prec(res)); + mpfr_set_fmpz(res, f + i); + for (i = len - 2; i >= 0; i--) + { + mpfr_mul(t, res, a, MPFR_RNDN); + mpfr_add_fmpz(res, t, f + i); + } + mpfr_clear(t); + } +} + +void +fmpz_poly_evaluate_mpfr(mpfr_t res, const fmpz_poly_t f, const mpfr_t a) +{ + if (res == a) + { + mpfr_t t; + mpfr_init2(t, mpfr_get_prec(res)); + _fmpz_poly_evaluate_mpfr(t, f->coeffs, f->length, a); + mpfr_swap(res, t); + mpfr_clear(t); + } + else + { + _fmpz_poly_evaluate_mpfr(res, f->coeffs, f->length, a); + } +} + +void +findroot(mpfr_t x, fmpz_poly_t poly, double x0) +{ + slong i; + slong prec, initial_prec, target_prec, guard_bits; + slong precs[FLINT_BITS]; + fmpz_poly_t poly2; + mpfr_t t, u, xn; + + initial_prec = 48; + target_prec = mpfr_get_prec(x) + 32; + + mpfr_init2(t, 53); + mpfr_init2(u, 53); + mpfr_init2(xn, 53); + mpfr_set_d(xn, x0, MPFR_RNDN); + + fmpz_poly_init(poly2); + fmpz_poly_derivative(poly2, poly); + guard_bits = fmpz_poly_max_bits(poly2); + guard_bits = FLINT_ABS(guard_bits); + + for (i = 0, prec = target_prec; prec >= initial_prec; i++) + { + precs[i] = prec; + prec = prec / 2 + 8; + } + + for (i--; i >= 0; i--) + { + mpfr_set_prec(t, precs[i] + guard_bits); + mpfr_set_prec(u, precs[i] + guard_bits); + mpfr_prec_round(xn, precs[i], MPFR_RNDN); + fmpz_poly_evaluate_mpfr(t, poly, xn); + fmpz_poly_evaluate_mpfr(u, poly2, xn); + mpfr_div(t, t, u, MPFR_RNDN); + mpfr_sub(xn, xn, t, MPFR_RNDN); + } + + mpfr_set(x, xn, MPFR_RNDN); + + fmpz_poly_clear(poly2); + mpfr_clear(t); + mpfr_clear(u); + mpfr_clear(xn); +} + +void cos_minpoly(fmpz_poly_t poly, slong p, slong q) +{ + if (p % 2 == 0) + arith_cos_minpoly(poly, q); + else + arith_cos_minpoly(poly, 2 * q); +} + +int use_newton(slong prec, slong q) +{ + if (q < 250 && prec > 400 + 4*q*q) + return 1; + return 0; +} + +void mpfr_cos_pi_pq(mpfr_t t, mp_limb_signed_t p, mp_limb_signed_t q) +{ + /* Force 0 <= p < q */ + p = FLINT_ABS(p); + p %= (2 * q); + if (p >= q) + p = 2 * q - p; + + if (use_newton(mpfr_get_prec(t), q)) + { + fmpz_poly_t poly; + slong d; + fmpz_poly_init(poly); + d = n_gcd(q, p); + q /= d; + p /= d; + cos_minpoly(poly, p, q); + findroot(t, poly, cos(3.1415926535897932385 * p / q)); + fmpz_poly_clear(poly); + } + else + { + mpfr_const_pi(t, MPFR_RNDN); + + if (4 * p <= q) + { + mpfr_mul_si(t, t, p, MPFR_RNDN); + mpfr_div_ui(t, t, q, MPFR_RNDN); + mpfr_cos(t, t, MPFR_RNDN); + } + else if (4 * p < 3 * q) + { + mpfr_mul_si(t, t, q - 2*p, MPFR_RNDN); + mpfr_div_ui(t, t, 2 * q, MPFR_RNDN); + mpfr_sin(t, t, MPFR_RNDN); + } + else + { + mpfr_mul_si(t, t, q - p, MPFR_RNDN); + mpfr_div_ui(t, t, q, MPFR_RNDN); + mpfr_cos(t, t, MPFR_RNDN); + mpfr_neg(t, t, MPFR_RNDN); + } + } +} + +void +eval_trig_prod(mpfr_t sum, trig_prod_t prod) +{ + int i; + + if (prod->prefactor == 0) + { + mpfr_set_ui(sum, UWORD(0), MPFR_RNDN); + return; + } + + if (mpfr_get_prec(sum) <= DOUBLE_PREC) + { + double s; + s = prod->prefactor * sqrt((double)prod->sqrt_p/(double)prod->sqrt_q); + for (i = 0; i < prod->n; i++) + s *= cos_pi_pq(prod->cos_p[i], prod->cos_q[i]); + mpfr_set_d(sum, s, MPFR_RNDN); + } + else + { + mp_limb_t v; + mpfr_t t; + + mpfr_init2(t, mpfr_get_prec(sum)); + mpfr_set_si(sum, prod->prefactor, MPFR_RNDN); + v = n_gcd_full(prod->sqrt_p, prod->sqrt_q); + prod->sqrt_p /= v; + prod->sqrt_q /= v; + + if (prod->sqrt_p != 1) + { + mpfr_sqrt_ui(t, prod->sqrt_p, MPFR_RNDN); + mpfr_mul(sum, sum, t, MPFR_RNDN); + } + + if (prod->sqrt_q != 1) + { + mpfr_sqrt_ui(t, prod->sqrt_q, MPFR_RNDN); + mpfr_div(sum, sum, t, MPFR_RNDN); + } + + for (i = 0; i < prod->n; i++) + { + mpfr_cos_pi_pq(t, prod->cos_p[i], prod->cos_q[i]); + mpfr_mul(sum, sum, t, MPFR_RNDN); + } + + mpfr_clear(t); + } +} + +void +sinh_cosh_divk_precomp(mpfr_t sh, mpfr_t ch, mpfr_t ex, slong k) +{ + mpfr_t t; + mpfr_root(ch, ex, k, MPFR_RNDN); + /* The second term doesn't need full precision, + but this doesn't affect performance that much... */ + mpfr_init2(t, mpfr_get_prec(ch)); + mpfr_ui_div(t, 1, ch, MPFR_RNDN); + mpfr_sub(sh, ch, t, MPFR_RNDN); + mpfr_add(ch, ch, t, MPFR_RNDN); + mpfr_div_2exp(ch, ch, 1, MPFR_RNDN); + mpfr_div_2exp(sh, sh, 1, MPFR_RNDN); + mpfr_clear(t); +} + + +void +_arith_number_of_partitions_mpfr(mpfr_t x, ulong n, slong N0, slong N) +{ + trig_prod_t prod; + mpfr_t acc, C, t1, t2, t3, t4, exp1; + mpz_t n24; + double Cd; + slong k; + slong prec, guard_bits; +#if VERBOSE + timeit_t t0; +#endif + + if (n <= 2) + { + mpfr_set_ui(x, FLINT_MAX(1, n), MPFR_RNDN); + return; + } + + /* Compute initial precision */ + guard_bits = 2 * FLINT_BIT_COUNT(N) + 32; + prec = partitions_remainder_bound_log2(n, N0) + guard_bits; + prec = FLINT_MAX(prec, DOUBLE_PREC); + + mpfr_set_prec(x, prec); + mpfr_init2(acc, prec); + mpfr_init2(C, prec); + mpfr_init2(t1, prec); + mpfr_init2(t2, prec); + mpfr_init2(t3, prec); + mpfr_init2(t4, prec); + + mpfr_set_ui(x, 0, MPFR_RNDN); + mpfr_set_ui(acc, 0, MPFR_RNDN); + + mpz_init(n24); + flint_mpz_set_ui(n24, n); + flint_mpz_mul_ui(n24, n24, 24); + flint_mpz_sub_ui(n24, n24, 1); + +#if VERBOSE + timeit_start(t0); +#endif + + /* C = (pi/6)*sqrt(24*n-1) */ + + if (PI_USE_CHUDNOVSKY && prec > PI_CHUDNOVSKY_CUTOFF) + mpfr_pi_chudnovsky(t1, MPFR_RNDN); + else + mpfr_const_pi(t1, MPFR_RNDN); + + mpfr_sqrt_z(t2, n24, MPFR_RNDN); + mpfr_mul(t1, t1, t2, MPFR_RNDN); + mpfr_div_ui(C, t1, 6, MPFR_RNDN); + Cd = mpfr_get_d(C, MPFR_RNDN); + + mpfr_init2(exp1, prec); + mpfr_exp(exp1, C, prec); + +#if VERBOSE + timeit_stop(t0); + flint_printf("TERM 1: %wd ms\n", t0->cpu); +#endif + + for (k = N0; k <= N; k++) + { + trig_prod_init(prod); + arith_hrr_expsum_factored(prod, k, n % k); + + if (prod->prefactor != 0) + { + if (prec > DOUBLE_PREC) + { + prec = partitions_prec_bound(n, k, N); + + mpfr_set_prec(t1, prec); + mpfr_set_prec(t2, prec); + mpfr_set_prec(t3, prec); + mpfr_set_prec(t4, prec); + } + + /* Compute A_k(n) * sqrt(3/k) * 4 / (24*n-1) */ + prod->prefactor *= 4; + prod->sqrt_p *= 3; + prod->sqrt_q *= k; + eval_trig_prod(t1, prod); + mpfr_div_z(t1, t1, n24, MPFR_RNDN); + + /* Multiply by (cosh(z) - sinh(z)/z) where z = C / k */ + if (prec <= DOUBLE_PREC) + { + double z = Cd / k; + mpfr_mul_d(t1, t1, cosh(z) - sinh(z)/z, MPFR_RNDN); + } + else + { + mpfr_div_ui(t2, C, k, MPFR_RNDN); + + if (k < 35) + sinh_cosh_divk_precomp(t3, t4, exp1, k); + else + mpfr_sinh_cosh(t3, t4, t2, MPFR_RNDN); + + mpfr_div(t3, t3, t2, MPFR_RNDN); + mpfr_sub(t2, t4, t3, MPFR_RNDN); + mpfr_mul(t1, t1, t2, MPFR_RNDN); + } + + /* Add to accumulator */ + mpfr_add(acc, acc, t1, MPFR_RNDN); + if (mpfr_get_prec(acc) > 2 * prec + 32) + { + mpfr_add(x, x, acc, MPFR_RNDN); + mpfr_set_prec(acc, prec + 32); + mpfr_set_ui(acc, 0, MPFR_RNDN); + } + } + } + + mpfr_add(x, x, acc, MPFR_RNDN); + + mpz_clear(n24); + mpfr_clear(acc); + mpfr_clear(exp1); + mpfr_clear(C); + mpfr_clear(t1); + mpfr_clear(t2); + mpfr_clear(t3); + mpfr_clear(t4); +} + +void +arith_number_of_partitions_mpfr(mpfr_t x, ulong n) +{ + _arith_number_of_partitions_mpfr(x, n, 1, partitions_needed_terms(n)); +} diff --git a/external/flint-2.4.3/arith/number_of_partitions_nmod_vec.c b/external/flint-2.4.3/arith/number_of_partitions_nmod_vec.c new file mode 100644 index 0000000..9bfb608 --- /dev/null +++ b/external/flint-2.4.3/arith/number_of_partitions_nmod_vec.c @@ -0,0 +1,61 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "arith.h" + +void +arith_number_of_partitions_nmod_vec(mp_ptr res, slong len, nmod_t mod) +{ + mp_ptr tmp; + mp_limb_t r; + slong k, n; + + r = mod.n - UWORD(1); + + if (len < 1) + return; + + tmp = _nmod_vec_init(len); + _nmod_vec_zero(tmp, len); + + tmp[0] = UWORD(1); + + for (n = k = 1; n + 4*k + 2 < len; k += 2) + { + tmp[n] = r; + tmp[n + k] = r; + tmp[n + 3*k + 1] = UWORD(1); + tmp[n + 4*k + 2] = UWORD(1); + n += 6*k + 5; + } + + if (n < len) tmp[n] = r; + if (n + k < len) tmp[n + k] = r; + if (n + 3*k + 1 < len) tmp[n + 3*k + 1] = WORD(1); + + _nmod_poly_inv_series(res, tmp, len, mod); + + _nmod_vec_clear(tmp); +} diff --git a/external/flint-2.4.3/arith/number_of_partitions_vec.c b/external/flint-2.4.3/arith/number_of_partitions_vec.c new file mode 100644 index 0000000..7e4e448 --- /dev/null +++ b/external/flint-2.4.3/arith/number_of_partitions_vec.c @@ -0,0 +1,57 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "arith.h" + +void +arith_number_of_partitions_vec(fmpz * res, slong len) +{ + fmpz * tmp; + slong k, n; + + if (len < 1) + return; + + tmp = _fmpz_vec_init(len); + + tmp[0] = WORD(1); + + for (n = k = 1; n + 4*k + 2 < len; k += 2) + { + tmp[n] = WORD(-1); + tmp[n + k] = WORD(-1); + tmp[n + 3*k + 1] = WORD(1); + tmp[n + 4*k + 2] = WORD(1); + n += 6*k + 5; + } + + if (n < len) tmp[n] = WORD(-1); + if (n + k < len) tmp[n + k] = WORD(-1); + if (n + 3*k + 1 < len) tmp[n + 3*k + 1] = WORD(1); + + _fmpz_poly_inv_series(res, tmp, len); + + _fmpz_vec_clear(tmp, len); +} diff --git a/external/flint-2.4.3/arith/pi_chudnovsky.c b/external/flint-2.4.3/arith/pi_chudnovsky.c new file mode 100644 index 0000000..6be00fd --- /dev/null +++ b/external/flint-2.4.3/arith/pi_chudnovsky.c @@ -0,0 +1,653 @@ +/* Pi computation using Chudnovsky's algortithm. + + * Copyright 2002, 2005 Hanhong Xue (macroxue at yahoo dot com) + + * Modified 2005 by Torbjorn Granlund (tege at swox dot com) to allow more than + 2G digits to be computed. Modified 2009 by Torbjorn Granlund for GMPbench. + + * Modified 2011 by Fredrik Johansson to make reentrant and adapt for + use in FLINT. + + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include "arith.h" + +#define A 13591409 +#define B 545140134 +#define C 640320 +#define D 12 + +#define BITS_PER_DIGIT 3.32192809488736234787 +#define DIGITS_PER_ITER 14.1816474627254776555 +#define DOUBLE_PREC 53 + +#define min(x,y) ((x)<(y)?(x):(y)) +#define max(x,y) ((x)>(y)?(x):(y)) + +typedef struct { + ulong max_facs; + ulong num_facs; + ulong *fac; + ulong *pow; +} fac_t[1]; + +typedef struct { + slong fac; + slong pow; + slong nxt; +} sieve_t; + +typedef struct +{ + sieve_t *sieve; + slong sieve_size; + fac_t ftmp, fmul; + mpz_t gcd; + mpz_t *pstack, *qstack, *gstack; + fac_t *fpstack, *fgstack; + slong top; +} +pi_state_struct; + +typedef pi_state_struct pi_state[1]; + +#define INIT_FACS 32 + +#define p1 (state->pstack[state->top]) +#define q1 (state->qstack[state->top]) +#define g1 (state->gstack[state->top]) +#define fp1 (state->fpstack[state->top]) +#define fg1 (state->fgstack[state->top]) + +#define p2 (state->pstack[state->top+1]) +#define q2 (state->qstack[state->top+1]) +#define g2 (state->gstack[state->top+1]) +#define fp2 (state->fpstack[state->top+1]) +#define fg2 (state->fgstack[state->top+1]) + +/* r = sqrt(x) */ +void +my_sqrt_ui(pi_state state, mpf_t t1, mpf_t t2, mpf_t r, ulong x) +{ + ulong prec, bits, prec0; + + prec0 = mpf_get_prec(r); + + if (prec0 <= DOUBLE_PREC) + { + mpf_set_d(r, sqrt(x)); + return; + } + + bits = 0; + for (prec = prec0; prec > DOUBLE_PREC; ) + { + int bit = prec&1; + prec = (prec+bit)/2; + bits = bits*2+bit; + } + + mpf_set_prec_raw(t1, DOUBLE_PREC); + mpf_set_d(t1, 1/sqrt(x)); + + while (prec < prec0) + { + prec *=2; + if (prec < prec0) + { + /* t1 = t1+t1*(1-x*t1*t1)/2; */ + mpf_set_prec_raw(t2, prec); + mpf_mul(t2, t1, t1); /* half x half -> full */ + mpf_mul_ui(t2, t2, x); + mpf_ui_sub(t2, 1, t2); + mpf_set_prec_raw(t2, prec/2); + mpf_div_2exp(t2, t2, 1); + mpf_mul(t2, t2, t1); /* half x half -> half */ + mpf_set_prec_raw(t1, prec); + mpf_add(t1, t1, t2); + } + else + { + break; + } + prec -= (bits&1); + bits /=2; + } + + /* t2=x*t1, t1 = t2+t1*(x-t2*t2)/2; */ + mpf_set_prec_raw(t2, prec0/2); + mpf_mul_ui(t2, t1, x); + mpf_mul(r, t2, t2); /* half x half -> full */ + mpf_ui_sub(r, x, r); + mpf_mul(t1, t1, r); /* half x half -> half */ + mpf_div_2exp(t1, t1, 1); + mpf_add(r, t1, t2); +} + +/* r = y/x WARNING: r cannot be the same as y. */ +void +my_div(pi_state state, mpf_t t1, mpf_t t2, mpf_t r, mpf_t y, mpf_t x) +{ + ulong prec, bits, prec0; + + prec0 = mpf_get_prec(r); + + if (prec0 <= DOUBLE_PREC) + { + mpf_set_d(r, mpf_get_d(y) / mpf_get_d(x)); + return; + } + + bits = 0; + for (prec = prec0; prec > DOUBLE_PREC; ) + { + int bit = prec & 1; + prec = (prec + bit) / 2; + bits = bits*2 + bit; + } + + mpf_set_prec_raw(t1, DOUBLE_PREC); + mpf_ui_div(t1, 1, x); + + while (prec < prec0) + { + prec *= 2; + if (prec < prec0) + { + /* t1 = t1+t1*(1-x*t1); */ + mpf_set_prec_raw(t2, prec); + mpf_mul(t2, x, t1); /* full x half -> full */ + mpf_ui_sub(t2, 1, t2); + mpf_set_prec_raw(t2, prec/2); + mpf_mul(t2, t2, t1); /* half x half -> half */ + mpf_set_prec_raw(t1, prec); + mpf_add(t1, t1, t2); + } + else + { + prec = prec0; + /* t2=y*t1, t1 = t2+t1*(y-x*t2); */ + mpf_set_prec_raw(t2, prec / 2); + mpf_mul(t2, t1, y); /* half x half -> half */ + mpf_mul(r, x, t2); /* full x half -> full */ + mpf_sub(r, y, r); + mpf_mul(t1, t1, r); /* half x half -> half */ + mpf_add(r, t1, t2); + break; + } + prec -= (bits & 1); + bits /= 2; + } +} + +/*///////////////////////////////////////////////////////////////////////////*/ + + + +static __inline__ void +fac_reset(fac_t f) +{ + f[0].num_facs = 0; +} + +static __inline__ void +fac_init_size(fac_t f, slong s) +{ + if (s < INIT_FACS) + s = INIT_FACS; + + f[0].fac = flint_malloc(s*sizeof(ulong)*2); + f[0].pow = f[0].fac + s; + f[0].max_facs = s; + + fac_reset(f); +} + +static __inline__ void +fac_init(fac_t f) +{ + fac_init_size(f, INIT_FACS); +} + +static __inline__ void +fac_clear(fac_t f) +{ + flint_free(f[0].fac); +} + +static __inline__ void +fac_resize(fac_t f, slong s) +{ + if (f[0].max_facs < s) + { + fac_clear(f); + fac_init_size(f, s); + } +} + +/* f = base^pow */ +static __inline__ void +fac_set_bp(pi_state state, fac_t f, ulong base, slong pow) +{ + slong i; + assert(basesieve_size); + for (i=0, base/=2; base>0; i++, base = state->sieve[base].nxt) + { + f[0].fac[i] = state->sieve[base].fac; + f[0].pow[i] = state->sieve[base].pow*pow; + } + f[0].num_facs = i; + assert(i<=f[0].max_facs); +} + +/* r = f*g */ +static __inline__ void +fac_mul2(pi_state state, fac_t r, fac_t f, fac_t g) +{ + slong i, j, k; + + for (i=j=k=0; ifmul, f[0].num_facs + g[0].num_facs); + fac_mul2(state, state->fmul, f, g); + tmp[0] = f[0]; + f[0] = state->fmul[0]; + state->fmul[0] = tmp[0]; +} + +/* f *= base^pow */ +static __inline__ void +fac_mul_bp(pi_state state, fac_t f, ulong base, ulong pow) +{ + fac_set_bp(state, state->ftmp, base, pow); + fac_mul(state, f, state->ftmp); +} + +/* remove factors of power 0 */ +static __inline__ void +fac_compact(fac_t f) +{ + slong i, j; + for (i=0, j=0; i0) + { + if (j < i) + { + f[0].fac[j] = f[0].fac[i]; + f[0].pow[j] = f[0].pow[i]; + } + j++; + } + } + f[0].num_facs = j; +} + +/* convert factorized form to number */ +void +bs_mul(pi_state state, mpz_t r, slong a, slong b) +{ + slong i, j; + if (b-a<=32) + { + flint_mpz_set_ui(r, 1); + for (i=a; ifmul[0].pow[i]; j++) + flint_mpz_mul_ui(r, r, state->fmul[0].fac[i]); + } + else + { + mpz_t r2; + mpz_init(r2); + bs_mul(state, r2, a, (a+b)/2); + bs_mul(state, r, (a+b)/2, b); + mpz_mul(r, r, r2); + mpz_clear(r2); + } +} + + +/* f /= gcd(f,g), g /= gcd(f,g) */ +void +fac_remove_gcd(pi_state state, mpz_t p, fac_t fp, mpz_t g, fac_t fg) +{ + slong i, j, k, c; + + fac_resize(state->fmul, min(fp->num_facs, fg->num_facs)); + + for (i=j=k=0; i < fp->num_facs && j < fg->num_facs; ) + { + if (fp->fac[i] == fg->fac[j]) + { + c = min(fp->pow[i], fg->pow[j]); + fp->pow[i] -= c; + fg->pow[j] -= c; + state->fmul->fac[k] = fp->fac[i]; + state->fmul->pow[k] = c; + i++; j++; k++; + } + else if (fp->fac[i] < fg->fac[j]) + { + i++; + } + else + { + j++; + } + } + + state->fmul->num_facs = k; + assert(k <= state->fmul->max_facs); + + if (state->fmul->num_facs) + { + bs_mul(state, state->gcd, 0, state->fmul->num_facs); + + mpz_divexact(p, p, state->gcd); + mpz_divexact(g, g, state->gcd); + + fac_compact(fp); + fac_compact(fg); + } +} + +/*///////////////////////////////////////////////////////////////////////////*/ + + + + + +/* binary splitting */ +void +bs(pi_state state, ulong a, ulong b, + unsigned gflag, slong level) +{ + ulong i, mid; + + if (b - a == 1) + { + /* + g(b-1,b) = (6b-5)(2b-1)(6b-1) + p(b-1,b) = b^3 * C^3 / 24 + q(b-1,b) = (-1)^b*g(b-1,b)*(A+Bb). + */ + flint_mpz_set_ui(p1, b); + flint_mpz_mul_ui(p1, p1, b); + flint_mpz_mul_ui(p1, p1, b); + flint_mpz_mul_ui(p1, p1, (C/24)*(C/24)); + flint_mpz_mul_ui(p1, p1, C*24); + + flint_mpz_set_ui(g1, 2*b-1); + flint_mpz_mul_ui(g1, g1, 6*b-1); + flint_mpz_mul_ui(g1, g1, 6*b-5); + + flint_mpz_set_ui(q1, b); + flint_mpz_mul_ui(q1, q1, B); + flint_mpz_add_ui(q1, q1, A); + mpz_mul (q1, q1, g1); + + if (b%2) + mpz_neg(q1, q1); + + i=b; + while ((i&1)==0) i>>=1; + + fac_set_bp(state, fp1, i, 3); /* b^3 */ + fac_mul_bp(state, fp1, 3*5*23*29, 3); + fp1[0].pow[0]--; + + fac_set_bp(state, fg1, 2*b-1, 1); /* 2b-1 */ + fac_mul_bp(state, fg1, 6*b-1, 1); /* 6b-1 */ + fac_mul_bp(state, fg1, 6*b-5, 1); /* 6b-5 */ + } + else + { + /* + p(a,b) = p(a,m) * p(m,b) + g(a,b) = g(a,m) * g(m,b) + q(a,b) = q(a,m) * p(m,b) + q(m,b) * g(a,m) + */ + mid = a+(b-a)*0.5224; /* tuning parameter */ + bs(state, a, mid, 1, level+1); + + state->top++; + bs(state, mid, b, gflag, level+1); + state->top--; + + if (level>=4) { /* tuning parameter */ + fac_remove_gcd(state, p2, fp2, g1, fg1); + } + + mpz_mul(p1, p1, p2); + mpz_mul(q1, q1, p2); + mpz_mul(q2, q2, g1); + mpz_add(q1, q1, q2); + fac_mul(state, fp1, fp2); + + if (gflag) + { + mpz_mul(g1, g1, g2); + fac_mul(state, fg1, fg2); + } + } +} + +void +build_sieve(pi_state state, slong n, sieve_t *s) +{ + slong m, i, j, k; + + state->sieve_size = n; + m = (slong)sqrt(n); + memset(s, 0, sizeof(sieve_t)*n/2); + + s[1/2].fac = 1; + s[1/2].pow = 1; + + for (i=3; i<=n; i+=2) + { + if (s[i/2].fac == 0) + { + s[i/2].fac = i; + s[i/2].pow = 1; + if (i <= m) + { + for (j=i*i, k=i/2; j<=n; j+=i+i, k++) + { + if (s[j/2].fac==0) + { + s[j/2].fac = i; + if (s[k].fac == i) + { + s[j/2].pow = s[k].pow + 1; + s[j/2].nxt = s[k].nxt; + } + else + { + s[j/2].pow = 1; + s[j/2].nxt = k; + } + } + } + } + } + } +} + +void +mpfr_pi_chudnovsky(mpfr_t res, mpfr_rnd_t rnd) +{ + mpf_t pi, qi, t1, t2; + mpfr_prec_t prec; + slong i, depth=1, terms; + pi_state state; + + prec = mpfr_get_prec(res) + 64; + terms = prec / (BITS_PER_DIGIT * DIGITS_PER_ITER); + while ((WORD(1)<top = 0; + state->sieve_size = max(3*5*23*29+1, terms*6); + state->sieve = (sieve_t *)flint_malloc(sizeof(sieve_t)*(state->sieve_size)/2); + build_sieve(state, state->sieve_size, state->sieve); + + /* allocate stacks */ + state->pstack = flint_malloc(sizeof(mpz_t)*depth); + state->qstack = flint_malloc(sizeof(mpz_t)*depth); + state->gstack = flint_malloc(sizeof(mpz_t)*depth); + state->fpstack = flint_malloc(sizeof(fac_t)*depth); + state->fgstack = flint_malloc(sizeof(fac_t)*depth); + for (i=0; ipstack[i]); + mpz_init(state->qstack[i]); + mpz_init(state->gstack[i]); + fac_init(state->fpstack[i]); + fac_init(state->fgstack[i]); + } + + mpz_init(state->gcd); + fac_init(state->ftmp); + fac_init(state->fmul); + + /* begin binary splitting process */ + if (terms<=0) + { + flint_mpz_set_ui(p2,1); + flint_mpz_set_ui(q2,0); + flint_mpz_set_ui(g2,1); + } + else + { + bs(state, 0,terms,0,0); + } + + /* free some resources */ + flint_free(state->sieve); + + mpz_clear(state->gcd); + fac_clear(state->ftmp); + fac_clear(state->fmul); + + for (i=1; ipstack[i]); + mpz_clear(state->qstack[i]); + mpz_clear(state->gstack[i]); + fac_clear(state->fpstack[i]); + fac_clear(state->fgstack[i]); + } + + mpz_clear(state->gstack[0]); + fac_clear(state->fpstack[0]); + fac_clear(state->fgstack[0]); + + flint_free(state->gstack); + flint_free(state->fpstack); + flint_free(state->fgstack); + + /* + p*(C/D)*sqrt(C) + pi = ----------------- + (q+A*p) + */ + + flint_mpz_addmul_ui(q1, p1, A); + flint_mpz_mul_ui(p1, p1, C/D); + + mpf_init2(pi, prec); + mpf_set_z(pi, p1); + mpz_clear(p1); + + mpf_init2(qi, prec); + mpf_set_z(qi, q1); + mpz_clear(q1); + + flint_free(state->pstack); + flint_free(state->qstack); + + /* initialize temp float variables for sqrt & div */ + mpf_init2(t1, prec); + mpf_init2(t2, prec); + + /* final step */ + my_div(state, t1, t2, qi, pi, qi); + my_sqrt_ui(state, t1, t2, pi, C); + mpf_mul(qi, qi, pi); + + mpfr_set_f(res, qi, rnd); + + /* free float resources */ + mpf_clear(pi); + mpf_clear(qi); + + mpf_clear(t1); + mpf_clear(t2); +} diff --git a/external/flint-2.4.3/arith/primorial.c b/external/flint-2.4.3/arith/primorial.c new file mode 100644 index 0000000..3c4355a --- /dev/null +++ b/external/flint-2.4.3/arith/primorial.c @@ -0,0 +1,151 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include "arith.h" + +#if FLINT64 +#define LARGEST_ULONG_PRIMORIAL 52 +#else +#define LARGEST_ULONG_PRIMORIAL 28 +#endif + +/* Only those with odd index */ +const ulong ULONG_PRIMORIALS[] = +{ + UWORD(6),UWORD(30),UWORD(210),UWORD(210),UWORD(2310),UWORD(30030),UWORD(30030),UWORD(510510),UWORD(9699690),UWORD(9699690), + UWORD(223092870),UWORD(223092870),UWORD(223092870) +#if FLINT64 + ,UWORD(6469693230),UWORD(200560490130),UWORD(200560490130),UWORD(200560490130),UWORD(7420738134810), + UWORD(7420738134810),UWORD(304250263527210),UWORD(13082761331670030),UWORD(13082761331670030), + UWORD(614889782588491410), UWORD(614889782588491410), UWORD(614889782588491410) +#endif +}; + + +#define PROD_LIMBS_DIRECT_CUTOFF 50 + +mp_size_t mpn_prod_limbs_direct(mp_limb_t * result, const mp_limb_t * factors, + mp_size_t n) +{ + mp_size_t k, len; + mp_limb_t top; + if (n < 1) + { + result[0] = UWORD(1); + return 1; + } + result[0] = factors[0]; + len = 1; + for (k=1; k_mp_d, primes, pi, bits); + mpz_ptr->_mp_size = len; +} diff --git a/external/flint-2.4.3/arith/profile/p-bernoulli.c b/external/flint-2.4.3/arith/profile/p-bernoulli.c new file mode 100644 index 0000000..dca6271 --- /dev/null +++ b/external/flint-2.4.3/arith/profile/p-bernoulli.c @@ -0,0 +1,120 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright 2009 William Hart + Copyright 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "profiler.h" +#include "flint.h" +#include "fmpz_mat.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "arith.h" + +typedef struct +{ + ulong n; + int algorithm; +} bernoulli_vec_t; + + +void sample(void * arg, ulong count) +{ + fmpz * num; + fmpz * den; + bernoulli_vec_t * params = (bernoulli_vec_t *) arg; + ulong n = params->n; + slong i; + int algorithm = params->algorithm; + + num = _fmpz_vec_init(n); + den = _fmpz_vec_init(n); + + prof_start(); + + for (i = 0; i < count; i++) + { + if (algorithm == 0) + { + _arith_bernoulli_number_vec_recursive(num, den, n); + } + else if (algorithm == 1) + { + _arith_bernoulli_number_vec_multi_mod(num, den, n); + } + else if (algorithm == 2) + { + _arith_bernoulli_number_vec_zeta(num, den, n); + mpfr_free_cache(); + } + } + + prof_stop(); + + _fmpz_vec_clear(num, n); + _fmpz_vec_clear(den, n); +} + +int main(void) +{ + double min_recursive, min_multi_mod, min_zeta, max; + bernoulli_vec_t params; + slong n; + + flint_printf("n / recursive / multi_mod / zeta / best [times in us]\n"); + + for (n = 2; n <= 10000; n = (slong) ((double) n * 1.2) + 1) + { + params.n = n; + + if (n < 1500) + { + params.algorithm = 0; + prof_repeat(&min_recursive, &max, sample, ¶ms); + } + else + min_recursive = 0.0; + + params.algorithm = 1; + prof_repeat(&min_multi_mod, &max, sample, ¶ms); + + params.algorithm = 2; + prof_repeat(&min_zeta, &max, sample, ¶ms); + + flint_printf("%wd %.2f %.2f %.2f ", + n, min_recursive, min_multi_mod, min_zeta); + + if (min_recursive && min_recursive < min_multi_mod && \ + min_recursive < min_zeta) + flint_printf("(recursive)\n"); + else if (min_multi_mod < min_zeta) + flint_printf("(multi_mod)\n"); + else + flint_printf("(zeta)\n"); + } + + return 0; +} diff --git a/external/flint-2.4.3/arith/ramanujan_tau.c b/external/flint-2.4.3/arith/ramanujan_tau.c new file mode 100644 index 0000000..aa10ada --- /dev/null +++ b/external/flint-2.4.3/arith/ramanujan_tau.c @@ -0,0 +1,120 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz.h" +#include "arith.h" + +void arith_ramanujan_tau_series(fmpz_poly_t res, slong n) +{ + slong j, k, jv, kv; + fmpz_t tmp; + fmpz_poly_fit_length(res, n); + _fmpz_vec_zero(res->coeffs, n); + _fmpz_poly_set_length(res, n); + fmpz_init(tmp); + for (j = jv = 0; jv < n; jv += ++j) + { + fmpz_set_ui(tmp, 2*j+1); + for (k = kv = 0; jv + kv < n; kv += ++k) + { + if ((j+k) & 1) + fmpz_submul_ui(res->coeffs + jv+kv, tmp, 2*k+1); + else + fmpz_addmul_ui(res->coeffs + jv+kv, tmp, 2*k+1); + } + } + fmpz_poly_sqrlow(res, res, n-1); + fmpz_poly_sqrlow(res, res, n-1); + fmpz_poly_shift_left(res, res, 1); + fmpz_clear(tmp); +} + +void _arith_ramanujan_tau(fmpz_t res, fmpz_factor_t factors) +{ + fmpz_poly_t poly; + fmpz_t tau_p, p_11, next, this, prev; + slong k, r; + ulong max_prime; + + max_prime = UWORD(1); + for (k = 0; k < factors->num; k++) + { + /* TODO: handle overflow properly */ + max_prime = FLINT_MAX(max_prime, fmpz_get_ui(factors->p + k)); + } + + fmpz_poly_init(poly); + arith_ramanujan_tau_series(poly, max_prime + 1); + + fmpz_one(res); + fmpz_init(tau_p); + fmpz_init(p_11); + fmpz_init(next); + fmpz_init(this); + fmpz_init(prev); + + for (k = 0; k < factors->num; k++) + { + ulong p = fmpz_get_ui(factors->p + k); + + fmpz_set(tau_p, poly->coeffs + p); + fmpz_set_ui(p_11, p); + fmpz_pow_ui(p_11, p_11, 11); + fmpz_one(prev); + fmpz_set(this, tau_p); + + for (r = 1; r < factors->exp[k]; r++) + { + fmpz_mul(next, tau_p, this); + fmpz_submul(next, p_11, prev); + fmpz_set(prev, this); + fmpz_set(this, next); + } + fmpz_mul(res, res, this); + } + + fmpz_clear(tau_p); + fmpz_clear(p_11); + fmpz_clear(next); + fmpz_clear(this); + fmpz_clear(prev); + fmpz_poly_clear(poly); +} + +void arith_ramanujan_tau(fmpz_t res, const fmpz_t n) +{ + fmpz_factor_t factors; + + if (fmpz_sgn(n) <= 0) + { + fmpz_zero(res); + return; + } + + fmpz_factor_init(factors); + fmpz_factor(factors, n); + _arith_ramanujan_tau(res, factors); + fmpz_factor_clear(factors); +} diff --git a/external/flint-2.4.3/arith/stirling1.c b/external/flint-2.4.3/arith/stirling1.c new file mode 100644 index 0000000..35a4fb0 --- /dev/null +++ b/external/flint-2.4.3/arith/stirling1.c @@ -0,0 +1,138 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include "arith.h" + +static void +_rising_factorial(fmpz * res, slong a, slong b, slong trunc) +{ + const slong span = b - a; + + switch (span) + { + case 0: + fmpz_one(res); + break; + case 1: + fmpz_set_ui(res, a); + if (trunc > 1) fmpz_one(res+1); + break; + case 2: + fmpz_set_ui(res, a); + fmpz_mul_ui(res, res, a + UWORD(1)); + if (trunc > 1) + { + fmpz_set_ui(res+1, 2*a + UWORD(1)); + if (trunc > 2) fmpz_one(res+2); + } + break; + case 3: + fmpz_set_ui(res, a); + fmpz_mul_ui(res, res, a + UWORD(1)); + fmpz_mul_ui(res, res, a + UWORD(2)); + if (trunc > 1) + { + fmpz_set_ui(res+1, 3*a); + fmpz_mul_ui(res+1, res+1, a + UWORD(2)); + fmpz_add_ui(res+1, res+1, 2); + if (trunc > 2) + { + fmpz_set_ui(res+2, 3*(a+1)); + if (trunc > 3) + fmpz_one(res+3); + } + } + break; + default: + { + const slong mid = (a + b) / 2; + const int chk = (b - a + 1 < trunc); /* i.e. nprod < trunc */ + const slong nleft = chk ? mid - a + 1 : trunc; + const slong nright = chk ? b - mid + 1 : trunc; + + fmpz *left = _fmpz_vec_init(nleft); + fmpz *right = _fmpz_vec_init(nright); + + _rising_factorial(left, a, mid, trunc); + _rising_factorial(right, mid, b, trunc); + + if (chk) + _fmpz_poly_mul(res, right, nright, left, nleft); + else + _fmpz_poly_mullow(res, left, nleft, right, nright, trunc); + + _fmpz_vec_clear(left, nleft); + _fmpz_vec_clear(right, nright); + } + } +} + +void +arith_stirling_number_1u(fmpz_t s, slong n, slong k) +{ + /* Various special cases + TODO: factorials, binomial coefficients, harmonic numbers ... */ + if (k < 1) + { + fmpz_set_ui(s, (n == 0) & (k == 0)); + } + if (k >= n) + { + fmpz_set_ui(s, n == k); + } + else + { + fmpz *tmp = _fmpz_vec_init(k+1); + _rising_factorial(tmp, 0, n, k+1); + fmpz_set(s, tmp+k); + _fmpz_vec_clear(tmp, k+1); + } +} + +void +arith_stirling_number_1(fmpz_t s, slong n, slong k) +{ + arith_stirling_number_1u(s, n, k); + if ((n + k) % 2) + fmpz_neg(s, s); +} + +void +arith_stirling_number_1u_vec(fmpz * row, slong n, slong klen) +{ + if (klen > 0) + _rising_factorial(row, 0, n, klen); +} + +void +arith_stirling_number_1_vec(fmpz * row, slong n, slong klen) +{ + slong k; + + arith_stirling_number_1u_vec(row, n, klen); + + for (k = (n + 1) % 2; k < klen; k += 2) + fmpz_neg(row + k, row + k); +} diff --git a/external/flint-2.4.3/arith/stirling2.c b/external/flint-2.4.3/arith/stirling2.c new file mode 100644 index 0000000..bbcd286 --- /dev/null +++ b/external/flint-2.4.3/arith/stirling2.c @@ -0,0 +1,134 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include "arith.h" + +static __inline__ void +_fmpz_addmul_alt(fmpz_t s, fmpz_t t, fmpz_t u, int parity) +{ + if (parity % 2) + fmpz_submul(s, t, u); + else + fmpz_addmul(s, t, u); +} + +static void +_fmpz_stirling2_powsum(fmpz_t s, slong n, slong k) +{ + fmpz_t t, u; + fmpz * bc; + slong j, m, max_bc; + + fmpz_init(t); + fmpz_init(u); + max_bc = (k+1) / 2; + + bc = _fmpz_vec_init(max_bc + 1); + fmpz_one(bc); + for (j = 1; j <= max_bc; j++) + { + fmpz_set(bc+j, bc+j-1); + fmpz_mul_ui(bc+j, bc+j, k+1-j); + fmpz_divexact_ui(bc+j, bc+j, j); + } + + fmpz_zero(s); + for (j = 1; j <= k; j += 2) + { + fmpz_set_ui(u, j); + fmpz_pow_ui(u, u, n); + m = j; + /* Process each m = 2^p * j */ + while (1) + { + if (m > max_bc) + _fmpz_addmul_alt(s, bc+k-m, u, k + m); + else + _fmpz_addmul_alt(s, bc+m, u, k + m); + m *= 2; + if (m > k) + break; + fmpz_mul_2exp(u, u, n); + } + } + + _fmpz_vec_clear(bc, max_bc + 1); + fmpz_fac_ui(t, k); + fmpz_divexact(s, s, t); + fmpz_clear(t); + fmpz_clear(u); +} + +void +arith_stirling_number_2(fmpz_t s, slong n, slong k) +{ + if (n < 0 || k < 0 || k > n) + { + fmpz_zero(s); + return; + } + + /* Topmost diagonals */ + if (k >= n - 1) + { + if (k == n) + fmpz_one(s); + else /* k == n - 1 */ + { + /* S(n,n-1) = binomial(n,2) */ + fmpz_set_ui(s, n); + fmpz_mul_ui(s, s, n-1); + fmpz_divexact_ui(s, s, UWORD(2)); + } + return; + } + + /* Leftmost columns */ + if (k <= 2) + { + if (k < 2) + fmpz_set_ui(s, k); + else + { + /* S(n,2) = 2^(n-1)-1 */ + fmpz_one(s); + fmpz_mul_2exp(s, s, n-1); + fmpz_sub_ui(s, s, UWORD(1)); + } + return; + } + + _fmpz_stirling2_powsum(s, n, k); +} + +void +arith_stirling_number_2_vec(fmpz * row, slong n, slong klen) +{ + slong m; + + for (m = 0; m <= n; m++) + arith_stirling_number_2_vec_next(row, row, m, klen); +} + diff --git a/external/flint-2.4.3/arith/stirlingmat.c b/external/flint-2.4.3/arith/stirlingmat.c new file mode 100644 index 0000000..3566d92 --- /dev/null +++ b/external/flint-2.4.3/arith/stirlingmat.c @@ -0,0 +1,119 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2013 Fredrik Johansson + +******************************************************************************/ + +#include "arith.h" + +void arith_stirling_number_1u_vec_next(fmpz * row, + const fmpz * prev, slong n, slong klen) +{ + slong k; + + if (klen > n) fmpz_one(row + n); + if (n != 0 && klen != 0) fmpz_zero(row); + + for (k = FLINT_MIN(n, klen) - 1; k >= 1; k--) + { + fmpz_mul_ui(row + k, prev + k, n - UWORD(1)); + fmpz_add(row + k, prev + k - 1, row + k); + } + + for (k = n + 1; k < klen; k++) + fmpz_zero(row + k); +} + +void arith_stirling_number_1_vec_next(fmpz * row, + const fmpz * prev, slong n, slong klen) +{ + slong k; + + if (klen > n) fmpz_one(row + n); + if (n != 0 && klen != 0) fmpz_zero(row); + + for (k = FLINT_MIN(n, klen) - 1; k >= 1; k--) + { + fmpz_mul_ui(row + k, prev + k, n - UWORD(1)); + fmpz_sub(row + k, prev + k - 1, row + k); + } + + for (k = n + 1; k < klen; k++) + fmpz_zero(row + k); +} + +void arith_stirling_number_2_vec_next(fmpz * row, + const fmpz * prev, slong n, slong klen) +{ + slong k; + + if (klen > n) fmpz_one(row + n); + if (n != 0 && klen != 0) fmpz_zero(row); + + for (k = FLINT_MIN(n, klen) - 1; k >= 1; k--) + { + fmpz_mul_ui(row + k, prev + k, k); + fmpz_add(row + k, prev + k - 1, row + k); + } + + for (k = n + 1; k < klen; k++) + fmpz_zero(row + k); +} + +void +arith_stirling_matrix_1u(fmpz_mat_t mat) +{ + slong n; + + if (fmpz_mat_is_empty(mat)) + return; + + for (n = 0; n < mat->r; n++) + arith_stirling_number_1u_vec_next(mat->rows[n], + mat->rows[n - (n != 0)], n, mat->c); +} + +void +arith_stirling_matrix_1(fmpz_mat_t mat) +{ + slong n; + + if (fmpz_mat_is_empty(mat)) + return; + + for (n = 0; n < mat->r; n++) + arith_stirling_number_1_vec_next(mat->rows[n], + mat->rows[n - (n != 0)], n, mat->c); +} + +void +arith_stirling_matrix_2(fmpz_mat_t mat) +{ + slong n; + + if (fmpz_mat_is_empty(mat)) + return; + + for (n = 0; n < mat->r; n++) + arith_stirling_number_2_vec_next(mat->rows[n], + mat->rows[n - (n != 0)], n, mat->c); +} diff --git a/external/flint-2.4.3/arith/sum_of_squares.c b/external/flint-2.4.3/arith/sum_of_squares.c new file mode 100644 index 0000000..582c982 --- /dev/null +++ b/external/flint-2.4.3/arith/sum_of_squares.c @@ -0,0 +1,137 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz.h" +#include "arith.h" + +static void +sum_of_two_squares(fmpz_t r, const fmpz_t n) +{ + fmpz_factor_t fac; + slong i; + + fmpz_factor_init(fac); + fmpz_factor(fac, n); + fmpz_one(r); + + for (i = 0; i < fac->num; i++) + { + const int res = fmpz_fdiv_ui(fac->p + i, 4); + + if (res == 1) + { + fac->exp[i]++; + fmpz_mul_ui(r, r, fac->exp[i]); + } + else if (res == 3) + { + if (fac->exp[i] % 2) + { + fmpz_zero(r); + break; + } + } + } + + fmpz_mul_ui(r, r, 4); + fmpz_factor_clear(fac); +} + +static void +sum_of_four_squares(fmpz_t r, const fmpz_t n) +{ + const mp_bitcnt_t v = fmpz_val2(n); + + if (v == 0) + { + arith_divisor_sigma(r, n, 1); + fmpz_mul_ui(r, r, 8); + } + else + { + fmpz_tdiv_q_2exp(r, n, v); + arith_divisor_sigma(r, r, 1); + fmpz_mul_ui(r, r, 24); + } +} + +static void +sum_of_squares_recursive(fmpz_t r, slong k, ulong n) +{ + fmpz_t t, u; + slong i, j; + + fmpz_init(t); + fmpz_init(u); + fmpz_zero(r); + + for (i = j = 0; j <= n; i++) + { + fmpz_set_ui(u, n - j); + arith_sum_of_squares(t, k - 1, u); + + if (j > 0) + fmpz_mul_ui(t, t, 2); + fmpz_add(r, r, t); + + j += 2 * i + 1; + } + + fmpz_clear(t); + fmpz_clear(u); +} + +static void +sum_of_squares_series(fmpz_t r, ulong k, slong n) +{ + fmpz * t; + + t = _fmpz_vec_init(n + 1); + arith_sum_of_squares_vec(t, k, n + 1); + fmpz_set(r, t + n); + _fmpz_vec_clear(t, n + 1); +} + +void +arith_sum_of_squares(fmpz_t r, ulong k, const fmpz_t n) +{ + if (fmpz_sgn(n) <= 0 || k == 0) + fmpz_set_ui(r, fmpz_is_zero(n) != 0); + else if (k == 1) + fmpz_set_ui(r, 2 * (fmpz_is_square(n) != 0)); + else if (k == 2) + sum_of_two_squares(r, n); + else if (k == 4) + sum_of_four_squares(r, n); + else if (k == 3 || k == 5) + sum_of_squares_recursive(r, k, fmpz_get_ui(n)); + else if (fmpz_fits_si(n)) + sum_of_squares_series(r, k, fmpz_get_ui(n)); + else + { + flint_printf("Exception (arith_sum_of_squares). n is too large.\n"); + abort(); + } +} diff --git a/external/flint-2.4.3/arith/sum_of_squares_vec.c b/external/flint-2.4.3/arith/sum_of_squares_vec.c new file mode 100644 index 0000000..a24e4e7 --- /dev/null +++ b/external/flint-2.4.3/arith/sum_of_squares_vec.c @@ -0,0 +1,108 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "arith.h" + +static void +theta3_qexp(fmpz * r, slong n) +{ + slong i, j; + + _fmpz_vec_zero(r, n); + + for (i = j = 0; j < n; i++) + { + fmpz_set_ui(r + j, i == 0 ? 1 : 2); + j += 1 + 2*i; + } +} + +static void +theta3_qexp_squared(fmpz * r, slong n) +{ + slong i, j, x, y; + + _fmpz_vec_zero(r, n); + + for (x = i = 0; x < n; i++) + { + for (y = j = 0; x + y < n; j++) + { + fmpz_add_ui(r + x + y, r + x + y, (x ? 2 : 1) * (y ? 2 : 1)); + y += 2 * j + 1; + } + x += 2 * i + 1; + } +} + +void +arith_sum_of_squares_vec(fmpz * r, ulong k, slong n) +{ + if (k == 0 || n <= 1) + { + _fmpz_vec_zero(r, n); + if (n > 0) + fmpz_set_ui(r, 1); + } + else if (k == 1) + { + theta3_qexp(r, n); + } + else if (k == 2) + { + theta3_qexp_squared(r, n); + } + else if (k % 2 == 0) + { + fmpz * t = _fmpz_vec_init(n); + + theta3_qexp_squared(t, n); + _fmpz_poly_pow_trunc(r, t, k / 2, n); + _fmpz_vec_clear(t, n); + } + else + { + fmpz *t, *u; + t = _fmpz_vec_init(n); + u = _fmpz_vec_init(n); + + theta3_qexp_squared(t, n); + + if (k == 3) + { + theta3_qexp(u, n); + _fmpz_poly_mullow(r, t, n, u, n, n); + } + else + { + _fmpz_poly_pow_trunc(u, t, (k - 1) / 2, n); + theta3_qexp(t, n); + _fmpz_poly_mullow(r, t, n, u, n, n); + } + + _fmpz_vec_clear(t, n); + _fmpz_vec_clear(u, n); + } +} diff --git a/external/flint-2.4.3/arith/swinnerton_dyer_polynomial.c b/external/flint-2.4.3/arith/swinnerton_dyer_polynomial.c new file mode 100644 index 0000000..d2d1545 --- /dev/null +++ b/external/flint-2.4.3/arith/swinnerton_dyer_polynomial.c @@ -0,0 +1,138 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + + Inspired by a Sage implementation written by William Stein. + +******************************************************************************/ + +#include +#include "arith.h" + + +/* Bound coefficients using (x + u)^(2^n) and the binomial + coefficients. TODO: this is about 2x too large... */ +static slong __bound_prec(ulong n) +{ + slong i; + double u, N; + + N = UWORD(1) << n; + + /* u = (sum of square roots)^(2^n) */ + u = 0; + for (i = 0; i < n; i++) + u += sqrt(n_nth_prime(1 + i)); + u = N * log(u) * 1.44269504088897; + + /* Central binomial coefficient C(N,N/2) < 2^N / sqrt(3*N/2) */ + u += N - 0.5*(n-1) - 0.792481250360578; /* log(sqrt(3)) */ + + return u; +} + +void arith_swinnerton_dyer_polynomial(fmpz_poly_t poly, ulong n) +{ + fmpz *square_roots, *T, *tmp1, *tmp2, *tmp3; + fmpz_t one; + slong i, j, k, N; + slong prec; + + if (n == 0) + { + fmpz_poly_zero(poly); + fmpz_poly_set_coeff_ui(poly, 1, UWORD(1)); + return; + } + + N = WORD(1) << n; + + prec = __bound_prec(n); + /* flint_printf("prec: %wd\n", prec); */ + + fmpz_poly_fit_length(poly, N + 1); + T = poly->coeffs; + + fmpz_init(one); + fmpz_one(one); + fmpz_mul_2exp(one, one, prec); + + square_roots = _fmpz_vec_init(n); + tmp1 = flint_malloc((N/2 + 1) * sizeof(fmpz)); + tmp2 = flint_malloc((N/2 + 1) * sizeof(fmpz)); + tmp3 = _fmpz_vec_init(N); + + for (i = 0; i < n; i++) + { + fmpz_set_ui(square_roots + i, n_nth_prime(i + 1)); + fmpz_mul_2exp(square_roots + i, square_roots + i, 2 * prec); + fmpz_sqrt(square_roots + i, square_roots + i); + } + + /* Build linear factors */ + for (i = 0; i < N; i++) + { + fmpz_zero(T + i); + for (j = 0; j < n; j++) + { + if ((i >> j) & 1) + fmpz_add(T + i, T + i, square_roots + j); + else + fmpz_sub(T + i, T + i, square_roots + j); + } + } + + /* For each level... */ + for (i = 0; i < n; i++) + { + slong stride = UWORD(1) << i; + + for (j = 0; j < N; j += 2*stride) + { + for (k = 0; k < stride; k++) + { + tmp1[k] = T[j + k]; + tmp2[k] = T[j + stride + k]; + } + tmp1[stride] = *one; + tmp2[stride] = *one; + + _fmpz_poly_mullow(tmp3, tmp1, stride + 1, tmp2, stride + 1, 2*stride); + _fmpz_vec_scalar_fdiv_q_2exp(T + j, tmp3, 2*stride, prec); + } + } + + /* Round */ + fmpz_fdiv_q_2exp(one, one, 1); + for (i = 0; i < N; i++) + fmpz_add(T + i, T + i, one); + + _fmpz_vec_scalar_fdiv_q_2exp(T, T, N, prec); + fmpz_one(T + (UWORD(1) << n)); + _fmpz_poly_set_length(poly, N + 1); + + _fmpz_vec_clear(square_roots, n); + flint_free(tmp1); + flint_free(tmp2); + _fmpz_vec_clear(tmp3, UWORD(1) << n); + fmpz_clear(one); +} diff --git a/external/flint-2.4.3/arith/test/t-bell_number.c b/external/flint-2.4.3/arith/test/t-bell_number.c new file mode 100644 index 0000000..53e509b --- /dev/null +++ b/external/flint-2.4.3/arith/test/t-bell_number.c @@ -0,0 +1,120 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "arith.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" + +int main(void) +{ + fmpz * b1; + fmpz * b2; + slong n, k; + + const slong maxn = 400; + + FLINT_TEST_INIT(state); + + flint_printf("bell_number...."); + fflush(stdout); + + b1 = _fmpz_vec_init(maxn); + + /* Consistency test */ + for (n = 0; n < maxn; n++) + arith_bell_number(b1 + n, n); + + for (n = 0; n < maxn; n++) + { + b2 = _fmpz_vec_init(n); + arith_bell_number_vec(b2, n); + + if (!_fmpz_vec_equal(b1, b2, n)) + { + flint_printf("FAIL:\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + _fmpz_vec_clear(b2, n); + } + + /* Compare with B_n = sum of Stirling numbers of 2nd kind */ + for (n = 0; n < 1000; n += (n < 50) ? + 1 : n/4) + { + b2 = _fmpz_vec_init(n+1); + + arith_stirling_number_2_vec(b2, n, n+1); + + for (k = 1; k <= n; k++) + fmpz_add(b2, b2, b2 + k); + + arith_bell_number(b1, n); + + if (!fmpz_equal(b1, b2)) + { + flint_printf("FAIL:\n"); + flint_printf("n = %wd\n", n); + fmpz_print(b1); + flint_printf("\n"); + fmpz_print(b2); + flint_printf("\n"); + abort(); + } + + /* Also check nmod value */ + { + nmod_t mod; + mp_limb_t bb; + + nmod_init(&mod, n_randtest_prime(state, 0)); + bb = arith_bell_number_nmod(n, mod); + + if (fmpz_fdiv_ui(b1, mod.n) != bb) + { + flint_printf("FAIL:\n"); + flint_printf("n = %wd\n", n); + fmpz_print(b1); + flint_printf("\n"); + flint_printf("should be %wu mod %wu\n", bb, mod.n); + abort(); + } + } + + _fmpz_vec_clear(b2, n+1); + } + + _fmpz_vec_clear(b1, maxn); + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/arith/test/t-bell_number_multi_mod.c b/external/flint-2.4.3/arith/test/t-bell_number_multi_mod.c new file mode 100644 index 0000000..2233675 --- /dev/null +++ b/external/flint-2.4.3/arith/test/t-bell_number_multi_mod.c @@ -0,0 +1,72 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "arith.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" + +int main(void) +{ + slong i; + + FLINT_TEST_INIT(state); + + flint_printf("bell_number_multi_mod...."); + fflush(stdout); + + for (i = 0; i < 100; i++) + { + slong n; + fmpz_t b1, b2; + + fmpz_init(b1); + fmpz_init(b2); + + n = n_randint(state, 500); + + arith_bell_number_bsplit(b1, n); + arith_bell_number_multi_mod(b2, n); + + if (!fmpz_equal(b1, b2)) + { + flint_printf("FAIL:\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + fmpz_clear(b1); + fmpz_clear(b2); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/arith/test/t-bell_number_nmod.c b/external/flint-2.4.3/arith/test/t-bell_number_nmod.c new file mode 100644 index 0000000..7de82cb --- /dev/null +++ b/external/flint-2.4.3/arith/test/t-bell_number_nmod.c @@ -0,0 +1,77 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "arith.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" + +int main(void) +{ + slong i, j; + + FLINT_TEST_INIT(state); + + flint_printf("bell_number_nmod...."); + fflush(stdout); + + for (i = 0; i < 10; i++) + { + mp_ptr b; + slong n; + nmod_t mod; + mp_limb_t p; + + n = n_randint(state, 1000); + p = n_randtest_prime(state, 0); + + nmod_init(&mod, p); + + b = _nmod_vec_init(n + 1); + arith_bell_number_nmod_vec(b, n + 1, mod); + + for (j = 0; j <= n; j++) + { + mp_limb_t u = arith_bell_number_nmod(j, mod); + + if (u != b[j]) + { + flint_printf("FAIL: p = %wu, i = %wd\n", p, j); + abort(); + } + } + + _nmod_vec_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/arith/test/t-bell_number_nmod_vec.c b/external/flint-2.4.3/arith/test/t-bell_number_nmod_vec.c new file mode 100644 index 0000000..f52ed4d --- /dev/null +++ b/external/flint-2.4.3/arith/test/t-bell_number_nmod_vec.c @@ -0,0 +1,78 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "arith.h" +#include "nmod_vec.h" +#include "ulong_extras.h" + +int main(void) +{ + mp_ptr b1, b2; + slong n; + + const slong maxn = 3000; + + FLINT_TEST_INIT(state); + + flint_printf("bell_number_nmod_vec...."); + fflush(stdout); + + b1 = _nmod_vec_init(maxn); + b2 = _nmod_vec_init(maxn); + + for (n = 0; n < maxn; n += (n < 50) ? + 1 : n/4) + { + nmod_t mod; + mp_limb_t p; + + do { + p = n_randtest_prime(state, 0); + } while (p < n); + + nmod_init(&mod, p); + + arith_bell_number_nmod_vec_recursive(b1, n, mod); + arith_bell_number_nmod_vec_series(b2, n, mod); + + if (!_nmod_vec_equal(b1, b2, n)) + { + flint_printf("FAIL:\n"); + flint_printf("n = %wd\n", n); + abort(); + } + } + + _nmod_vec_clear(b1); + _nmod_vec_clear(b2); + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/arith/test/t-bell_number_vec.c b/external/flint-2.4.3/arith/test/t-bell_number_vec.c new file mode 100644 index 0000000..eef34fd --- /dev/null +++ b/external/flint-2.4.3/arith/test/t-bell_number_vec.c @@ -0,0 +1,69 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "arith.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" + +int main(void) +{ + fmpz * b1; + fmpz * b2; + slong n; + + const slong maxn = 1000; + + FLINT_TEST_INIT(state); + + flint_printf("bell_number_vec...."); + fflush(stdout); + + b1 = _fmpz_vec_init(maxn); + b2 = _fmpz_vec_init(maxn); + + for (n = 0; n < maxn; n += (n < 50) ? + 1 : n/4) + { + arith_bell_number_vec_recursive(b1, n); + arith_bell_number_vec_multi_mod(b2, n); + + if (!_fmpz_vec_equal(b1, b2, n)) + { + flint_printf("FAIL:\n"); + flint_printf("n = %wd\n", n); + abort(); + } + } + + _fmpz_vec_clear(b1, maxn); + _fmpz_vec_clear(b2, maxn); + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/arith/test/t-bernoulli_number.c b/external/flint-2.4.3/arith/test/t-bernoulli_number.c new file mode 100644 index 0000000..c7238d3 --- /dev/null +++ b/external/flint-2.4.3/arith/test/t-bernoulli_number.c @@ -0,0 +1,120 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "arith.h" +#include "profiler.h" +#include "fmpz.h" +#include "fmpz_mat.h" +#include "fmpq_poly.h" +#include "fmpq.h" + +int main() +{ + fmpz * num1; + fmpz * den1; + fmpz_t num2; + fmpz_t den2; + slong n, N; + + FLINT_TEST_INIT(state); + + flint_printf("bernoulli_number...."); + fflush(stdout); + + N = 4000; + + num1 = _fmpz_vec_init(N); + den1 = _fmpz_vec_init(N); + fmpz_init(num2); + fmpz_init(den2); + + _arith_bernoulli_number_vec_multi_mod(num1, den1, N); + + for (n = 0; n < N; n++) + { + _arith_bernoulli_number(num2, den2, n); + + if (!fmpz_equal(num1 + n, num2)) + { + flint_printf("FAIL: n = %wd, numerator\n", n); + flint_printf("vec: "); fmpz_print(num1 + n); flint_printf("\n"); + flint_printf("single: "); fmpz_print(num2); flint_printf("\n"); + abort(); + } + + if (!fmpz_equal(den1 + n, den2)) + { + flint_printf("FAIL: n = %wd, denominator\n", n); + flint_printf("vec: "); fmpz_print(den1 + n); flint_printf("\n"); + flint_printf("single: "); fmpz_print(den2); flint_printf("\n"); + abort(); + } + } + + /* Check non underscore versions */ + do + { + slong N = 100; + fmpq * x; + fmpq_t t; + + fmpq_init(t); + x = flint_malloc(sizeof(fmpq) * N); + + for (n = 0; n < N; n++) + fmpq_init(x + n); + + arith_bernoulli_number_vec(x, N); + for (n = 0; n < N; n++) + { + arith_bernoulli_number(t, n); + if (!fmpq_equal(x + n, t)) + { + flint_printf("FAIL!: n = %wd\n", n); + abort(); + } + } + + for (n = 0; n < N; n++) + fmpq_clear(x + n); + flint_free(x); + fmpq_clear(t); + + } while (0); + + _fmpz_vec_clear(num1, N); + _fmpz_vec_clear(den1, N); + fmpz_clear(num2); + fmpz_clear(den2); + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/arith/test/t-bernoulli_number_denom.c b/external/flint-2.4.3/arith/test/t-bernoulli_number_denom.c new file mode 100644 index 0000000..843824d --- /dev/null +++ b/external/flint-2.4.3/arith/test/t-bernoulli_number_denom.c @@ -0,0 +1,67 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "arith.h" +#include "fmpz.h" +#include "ulong_extras.h" + +int main() +{ + fmpz_t s, t; + slong n; + + FLINT_TEST_INIT(state); + + flint_printf("bernoulli_number_denom...."); + fflush(stdout); + + fmpz_init(s); + fmpz_init(t); + + for (n = 0; n < 1000; n++) + { + arith_bernoulli_number_denom(t, n); + fmpz_addmul_ui(s, t, n_nth_prime(n+1)); + } + + fmpz_set_str(t, "34549631155954474103407159", 10); + + if (!fmpz_equal(s, t)) + { + flint_printf("FAIL: Hash disagrees with known value\n"); + abort(); + } + + fmpz_clear(s); + fmpz_clear(t); + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/arith/test/t-bernoulli_number_vec.c b/external/flint-2.4.3/arith/test/t-bernoulli_number_vec.c new file mode 100644 index 0000000..4d28c43 --- /dev/null +++ b/external/flint-2.4.3/arith/test/t-bernoulli_number_vec.c @@ -0,0 +1,102 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "arith.h" +#include "profiler.h" +#include "fmpz.h" +#include "fmpz_mat.h" +#include "fmpq_poly.h" + + +int main() +{ + fmpz * num1; + fmpz * num2; + fmpz * num3; + fmpz * den1; + fmpz * den2; + fmpz * den3; + slong i, n, N; + + FLINT_TEST_INIT(state); + + flint_printf("bernoulli_number_vec...."); + fflush(stdout); + + N = 2000; + + num1 = _fmpz_vec_init(N); + num2 = _fmpz_vec_init(N); + num3 = _fmpz_vec_init(N); + den1 = _fmpz_vec_init(N); + den2 = _fmpz_vec_init(N); + den3 = _fmpz_vec_init(N); + + for (n = 0; n < N; n += (n<100) ? 1 : n/3) + { + _arith_bernoulli_number_vec_recursive(num1, den1, n); + _arith_bernoulli_number_vec_multi_mod(num2, den2, n); + _arith_bernoulli_number_vec_zeta(num3, den3, n); + + for (i = 0; i < n; i++) + { + if (!fmpz_equal(num1 + i, num2 + i) || + !fmpz_equal(num1 + i, num3 + i)) + { + flint_printf("FAIL: n = %wd, numerator of B_%wd\n", n, i); + flint_printf("recursive: "); fmpz_print(num1 + i); flint_printf("\n"); + flint_printf("multi_mod: "); fmpz_print(num2 + i); flint_printf("\n"); + flint_printf("zeta: "); fmpz_print(num3 + i); flint_printf("\n"); + abort(); + } + + if (!fmpz_equal(den1 + i, den2 + i) || + !fmpz_equal(den1 + i, den3 + i)) + { + flint_printf("FAIL: n = %wd, denominator of B_%wd\n", n, i); + flint_printf("recursive: "); fmpz_print(den1 + i); flint_printf("\n"); + flint_printf("multi_mod: "); fmpz_print(den2 + i); flint_printf("\n"); + flint_printf("zeta: "); fmpz_print(den3 + i); flint_printf("\n"); + abort(); + } + } + } + + _fmpz_vec_clear(num1, N); + _fmpz_vec_clear(num2, N); + _fmpz_vec_clear(num3, N); + _fmpz_vec_clear(den1, N); + _fmpz_vec_clear(den2, N); + _fmpz_vec_clear(den3, N); + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/arith/test/t-bernoulli_polynomial.c b/external/flint-2.4.3/arith/test/t-bernoulli_polynomial.c new file mode 100644 index 0000000..4f2bd01 --- /dev/null +++ b/external/flint-2.4.3/arith/test/t-bernoulli_polynomial.c @@ -0,0 +1,89 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "arith.h" +#include "profiler.h" +#include "fmpz.h" +#include "fmpz_mat.h" +#include "fmpq_poly.h" + + +int main() +{ + fmpq_poly_t P, Q; + mpz_t t; + + slong k, n; + + FLINT_TEST_INIT(state); + + flint_printf("bernoulli_polynomial...."); + fflush(stdout); + + for (n = 0; n <= 100; n++) + { + fmpq_poly_init(P); + fmpq_poly_init(Q); + + mpz_init(t); + + for (k = 0; k <= n; k++) + { + arith_bernoulli_polynomial(P, k); + flint_mpz_bin_uiui(t, n+1, k); + fmpq_poly_scalar_mul_mpz(P, P, t); + fmpq_poly_add(Q, Q, P); + } + + fmpq_poly_scalar_div_ui(Q, Q, n+1); + mpz_clear(t); + + fmpq_poly_zero(P); + fmpq_poly_set_coeff_ui(P, n, UWORD(1)); + + if (!fmpq_poly_equal(P, Q)) + { + flint_printf("ERROR: sum up to n = %wd did not add to x^n\n", n); + flint_printf("Sum: "); + fmpq_poly_print_pretty(Q, "x"); + flint_printf("\nExpected: "); + fmpq_poly_print_pretty(P, "x"); + flint_printf("\n"); + abort(); + } + + fmpq_poly_clear(P); + fmpq_poly_clear(Q); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/arith/test/t-chebyshev_t_polynomial.c b/external/flint-2.4.3/arith/test/t-chebyshev_t_polynomial.c new file mode 100644 index 0000000..44429f7 --- /dev/null +++ b/external/flint-2.4.3/arith/test/t-chebyshev_t_polynomial.c @@ -0,0 +1,82 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "arith.h" +#include "fmpz.h" +#include "fmpz_poly.h" + + +int main() +{ + fmpz_poly_t T0, T1, T2, t; + slong n; + + FLINT_TEST_INIT(state); + + flint_printf("chebyshev_t_polynomial...."); + fflush(stdout); + + fmpz_poly_init(T0); + fmpz_poly_init(T1); + fmpz_poly_init(T2); + fmpz_poly_init(t); + + arith_chebyshev_t_polynomial(T0, 0); + arith_chebyshev_t_polynomial(T1, 1); + + for (n = 2; n <= 500; n++) + { + arith_chebyshev_t_polynomial(T2, n); + + /* Verify T_{n+1} = 2 x T_n - T_{n-1} */ + fmpz_poly_scalar_mul_ui(t, T1, UWORD(2)); + fmpz_poly_shift_left(t, t, 1); + fmpz_poly_sub(t, t, T0); + + if (!fmpz_poly_equal(t, T2)) + { + flint_printf("FAIL: n = %wd\n", n); + flint_printf("t: "); fmpz_poly_print_pretty(t, "x"); flint_printf("\n"); + flint_printf("T2: "); fmpz_poly_print_pretty(T2, "x"); flint_printf("\n"); + abort(); + } + + fmpz_poly_swap(T0, T1); + fmpz_poly_swap(T1, T2); + } + + fmpz_poly_clear(T0); + fmpz_poly_clear(T1); + fmpz_poly_clear(T2); + fmpz_poly_clear(t); + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/arith/test/t-chebyshev_u_polynomial.c b/external/flint-2.4.3/arith/test/t-chebyshev_u_polynomial.c new file mode 100644 index 0000000..4e494cd --- /dev/null +++ b/external/flint-2.4.3/arith/test/t-chebyshev_u_polynomial.c @@ -0,0 +1,72 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "arith.h" +#include "fmpz.h" +#include "fmpz_poly.h" + + +int main() +{ + fmpz_poly_t T, U; + + slong n; + + FLINT_TEST_INIT(state); + + flint_printf("chebyshev_u_polynomial...."); + fflush(stdout); + + fmpz_poly_init(T); + fmpz_poly_init(U); + + for (n = 0; n <= 500; n++) + { + arith_chebyshev_u_polynomial(U, n); + arith_chebyshev_t_polynomial(T, n + 1); + fmpz_poly_derivative(T, T); + fmpz_poly_scalar_divexact_ui(T, T, n + 1); + + if (!fmpz_poly_equal(T, U)) + { + flint_printf("FAIL: n = %wd\n", n); + flint_printf("T: "); fmpz_poly_print_pretty(T, "x"); flint_printf("\n"); + flint_printf("U: "); fmpz_poly_print_pretty(U, "x"); flint_printf("\n"); + abort(); + } + + } + + fmpz_poly_clear(T); + fmpz_poly_clear(U); + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/arith/test/t-cyclotomic_cos_polynomial.c b/external/flint-2.4.3/arith/test/t-cyclotomic_cos_polynomial.c new file mode 100644 index 0000000..00546e8 --- /dev/null +++ b/external/flint-2.4.3/arith/test/t-cyclotomic_cos_polynomial.c @@ -0,0 +1,129 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "arith.h" +#include "fmpz.h" +#include "fmpz_poly.h" + + +/* +Generated with Mathematica: +Table[Mod[MinimalPolynomial[Cos[2 Pi/n]][1337], 31337], {n,1,500}] +*/ + +static const short testdata[] = { + 1, + 1336, 1338, 2675, 1337, 8113, 2673, 6283, 2719, 29508, 2765, 6949, + 5437, 2788, 26742, 25554, 26194, 29376, 29506, 30945, 15614, 8957, + 16643, 9263, 21050, 30556, 10533, 1570, 11562, 3988, 16546, 26642, 4041, + 3581, 109, 9839, 27175, 11691, 1460, 28287, 18369, 16503, 3184, 13336, + 23083, 12495, 3246, 14160, 8081, 5301, 8652, 28989, 24149, 17733, 1568, + 4800, 28863, 29280, 13741, 30919, 29819, 28584, 8913, 550, 6207, 13930, + 23373, 12644, 15265, 27975, 30386, 1603, 15894, 22276, 3138, 11610, + 2208, 515, 30817, 23050, 4333, 25031, 13615, 5116, 18609, 25490, 14555, + 22663, 8425, 21751, 19293, 3, 10688, 26829, 14467, 1426, 12413, 5305, + 25377, 27164, 3711, + 9613, 22340, 7457, 3704, 1795, 22877, 31060, 17472, 11317, 22274, + 11036, 7796, 27242, 22174, 3663, 10507, 16599, 18192, 15208, 7257, 7022, + 10810, 27891, 18495, 7032, 11383, 20768, 27351, 31089, 27723, 10486, + 2075, 25298, 20531, 28548, 25342, 6510, 20657, 15608, 5534, 22145, + 30150, 25222, 12128, 389, 21860, 9631, 4536, 4704, 3677, 27282, 26668, + 20784, 15684, 12847, 1307, 10586, 24355, 27553, 10952, 8886, 25029, + 29278, 29964, 17943, 1006, 5895, 11466, 16679, 17500, 5414, 3420, 17644, + 5165, 6255, 2807, 30577, 26277, 14032, 2425, 13945, 27988, 17437, 28204, + 11853, 12265, 8097, 24919, 10703, 18081, 19121, 23364, 14035, 2382, + 1722, 21617, 11863, 27682, 8538, 26401, + 1487, 14570, 14213, 18315, 30244, 14611, 25421, 13954, 29802, + 29118, 5788, 7547, 9710, 21645, 17858, 20672, 2295, 21286, 7217, 30405, + 5090, 22674, 5747, 5809, 13789, 16385, 23732, 12258, 10944, 14669, 2043, + 1453, 13510, 12422, 24073, 3025, 28094, 2770, 9198, 27411, 24736, 28958, + 23508, 27897, 17838, 10690, 5375, 29469, 22458, 9466, 28541, 16308, + 20491, 10320, 9836, 673, 26630, 20819, 25687, 19263, 16620, 28683, + 30268, 1113, 26632, 18450, 17555, 20121, 18083, 12796, 26659, 9788, + 10448, 2828, 29753, 26653, 13636, 6270, 10398, 16224, 1481, 1153, 26387, + 17835, 19289, 2683, 1937, 16760, 14372, 12632, 15716, 12423, 24202, + 14543, 10763, 27059, 437, 18647, 17133, 27774, + 2039, 3931, 7737, 20470, 11068, 26238, 28463, 22610, 28349, 23819, + 22780, 4101, 13218, 12878, 25048, 25163, 11032, 10129, 2571, 9319, + 11708, 6704, 19105, 11593, 24863, 26090, 15235, 18038, 22056, 19624, + 12066, 9798, 16508, 22376, 15776, 10595, 28391, 18898, 11645, 16655, + 19391, 11364, 28198, 4348, 6653, 11962, 22652, 18750, 22125, 21504, + 23718, 25662, 6768, 24234, 29605, 8280, 5246, 23064, 1360, 21538, 4374, + 8186, 7540, 24091, 3017, 23007, 12000, 11289, 8698, 22118, 5505, 18535, + 29647, 15878, 4416, 8598, 13062, 8878, 9674, 5066, 17770, 24888, 20643, + 1345, 22570, 1363, 3710, 18429, 11731, 14885, 12983, 18600, 26334, + 27101, 17858, 22221, 2471, 911, 12033, 2824, + 6354, 984, 28507, 3521, 17963, 6558, 11166, 24004, 24367, 8572, + 19198, 6937, 15220, 13122, 3540, 589, 17503, 14073, 14954, 26020, 12974, + 20684, 19844, 17852, 1097, 10831, 23848, 7013, 15683, 15954, 22290, + 30257, 15807, 22775, 13607, 9428, 30055, 11607, 30426, 2579, 340, 29747, + 25213, 28551, 5705, 15704, 10625, 16932, 3215, 16716, 6698, 21470, + 29839, 511, 23506, 4338, 30506, 18038, 20430, 20586, 18225, 7721, 15812, + 3140, 22149, 4949, 8125, 9897, 6323, 20612, 2012, 23744, 9414, 16497, + 5557, 5225, 8518, 30549, 21805, 5692, 25222, 16326, 22995, 27432, 16385, + 23506, 9911, 23131, 3880, 30647, 13222, 10416, 5619, 2078, 9411, 12398, + 22772, 7328, 17932, 19965, + -1 +}; + + +int main() +{ + fmpz_poly_t p; + slong n; + + FLINT_TEST_INIT(state); + + flint_printf("cyclotomic_cos_polynomial...."); + fflush(stdout); + + fmpz_poly_init(p); + + for (n = 0; testdata[n] != -1; n++) + { + mp_limb_t y; + arith_cos_minpoly(p, n); + y = fmpz_poly_evaluate_mod(p, 1337, 31337); + + if (y != testdata[n]) + { + flint_printf("FAIL: n = %wd\n", n); + flint_printf("y = %wu\n", y); + flint_printf("\n"); + abort(); + } + } + + fmpz_poly_clear(p); + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/arith/test/t-cyclotomic_polynomial.c b/external/flint-2.4.3/arith/test/t-cyclotomic_polynomial.c new file mode 100644 index 0000000..87d4eb4 --- /dev/null +++ b/external/flint-2.4.3/arith/test/t-cyclotomic_polynomial.c @@ -0,0 +1,145 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "arith.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +void cyclotomic_naive(fmpz_poly_t poly, ulong n) +{ + fmpz_poly_t t; + slong d; + + fmpz_poly_init(t); + + fmpz_poly_set_ui(poly, UWORD(1)); + for (d = 1; d <= n; d++) + { + if (n % d == 0) + { + if (n_moebius_mu(n / d) == 1) + { + fmpz_poly_zero(t); + fmpz_poly_set_coeff_si(t, d, 1); + fmpz_poly_set_coeff_si(t, 0, -1); + fmpz_poly_mul(poly, poly, t); + } + } + } + + for (d = 1; d <= n; d++) + { + if (n % d == 0) + { + if (n_moebius_mu(n / d) == -1) + { + fmpz_poly_zero(t); + fmpz_poly_set_coeff_si(t, d, 1); + fmpz_poly_set_coeff_si(t, 0, -1); + fmpz_poly_div(poly, poly, t); + } + } + } + + fmpz_poly_clear(t); +} + +int main() +{ + fmpz_poly_t A, B; + slong n; + + FLINT_TEST_INIT(state); + + flint_printf("cyclotomic_polynomial...."); + fflush(stdout); + + for (n = 0; n <= 1000; n++) + { + fmpz_poly_init(A); + fmpz_poly_init(B); + + arith_cyclotomic_polynomial(A, n); + cyclotomic_naive(B, n); + + if (!fmpz_poly_equal(A, B)) + { + flint_printf("FAIL: wrong value of Phi_%wd(x)\n", n); + flint_printf("Computed:\n"); + fmpz_poly_print_pretty(A, "x"); + flint_printf("\n\nExpected:\n"); + fmpz_poly_print_pretty(B, "x"); + flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(A); + fmpz_poly_clear(B); + } + + /* We verify the first value that does not fit on 32 bits. + This exercises the slow path at least on a 32 bit system. + Testing the 64 bit value is a bit too much to do by default + as it requires ~2 GB of memory and takes a few minutes. */ + { + fmpz_t h, ref; + + const ulong nn = UWORD(10163195); + /* const ulong nn = UWORD(169828113); 64-bit case */ + + fmpz_init(h); + fmpz_init(ref); + fmpz_set_str(ref, "1376877780831", 10); + /* fmpz_set_str(ref, "31484567640915734941", 10); 64-bit case */ + + fmpz_poly_init(A); + arith_cyclotomic_polynomial(A, UWORD(10163195)); + fmpz_poly_height(h, A); + + if (!fmpz_equal(h, ref)) + { + flint_printf("Bad computation of Phi_%wd(x)\n", nn); + flint_printf("Computed height:\n"); + fmpz_print(h); + flint_printf("\nExpected height:\n"); + fmpz_print(ref); + flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(A); + fmpz_clear(h); + fmpz_clear(ref); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/arith/test/t-dedekind_sum.c b/external/flint-2.4.3/arith/test/t-dedekind_sum.c new file mode 100644 index 0000000..2beb749 --- /dev/null +++ b/external/flint-2.4.3/arith/test/t-dedekind_sum.c @@ -0,0 +1,192 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq.h" +#include "arith.h" +#include "ulong_extras.h" +#include "math.h" + +/* + The results in the following random test cases were computed with the + naive implementation. Doing a live comparison with large values against + the naive implementation would take too much time. +*/ +static const slong testdata[][4] = +{ + /* h, k, p/q */ + {WORD(20816815), WORD(29229), WORD(-10669), WORD(87687)}, + {WORD(-481962612), WORD(709105), WORD(-910639), WORD(141821)}, + {WORD(-70965), WORD(3384), WORD(1785), WORD(752)}, + {WORD(1899905), WORD(6657), WORD(-43795), WORD(5706)}, + {WORD(-1893), WORD(511167), WORD(-3411568), WORD(170389)}, + {WORD(1417295), WORD(10180), WORD(3543), WORD(4072)}, + {WORD(-1149), WORD(9350), WORD(6971), WORD(9350)}, + {WORD(-15520), WORD(22977640), WORD(-70331425), WORD(574441)}, + {WORD(3339), WORD(9873153), WORD(270746882), WORD(1097017)}, + {WORD(470645896), WORD(71754), WORD(-21713), WORD(107631)}, + {WORD(1153), WORD(1332403), WORD(258755243), WORD(2664806)}, + {WORD(-501576), WORD(292801), WORD(269095), WORD(292801)}, + {WORD(1861), WORD(34440), WORD(-723059), WORD(206640)}, + {WORD(-4278761), WORD(239321), WORD(791947), WORD(239321)}, + {WORD(9414763), WORD(30776409), WORD(-93285463), WORD(92329227)}, + {WORD(4872687), WORD(2199), WORD(146), WORD(733)}, + {WORD(-22349505), WORD(60581653), WORD(27694241), WORD(60581653)}, + {WORD(85739724), WORD(9289), WORD(961), WORD(2654)}, + {WORD(-5616), WORD(124023), WORD(-31447), WORD(41341)}, + {WORD(99382204), WORD(1378843), WORD(-2537405), WORD(2757686)}, + {WORD(1903), WORD(15842), WORD(102), WORD(89)}, + {WORD(-907226), WORD(5818), WORD(5608), WORD(2909)}, + {WORD(-948920), WORD(4768), WORD(-4815), WORD(1192)}, + {WORD(-352220914), WORD(15390287), WORD(-171358081), WORD(30780574)}, + {WORD(-159206), WORD(3028284), WORD(12921745), WORD(4542426)}, + {WORD(61951448), WORD(1624), WORD(-341), WORD(406)}, + {WORD(-49167), WORD(2092), WORD(-32915), WORD(4184)}, + {WORD(-20878222), WORD(586303210), WORD(-530581301), WORD(293151605)}, + {WORD(-1435637), WORD(3483), WORD(-4787), WORD(20898)}, + {WORD(-1129797), WORD(171620), WORD(238211), WORD(68648)}, + {WORD(-177095), WORD(2914), WORD(1132), WORD(1457)}, + {WORD(-343227551), WORD(1509), WORD(-3289), WORD(4527)}, + {WORD(57497376), WORD(1351), WORD(373), WORD(2702)}, + {WORD(3350543), WORD(5771893), WORD(-51196457), WORD(5771893)}, + {WORD(-44408), WORD(1670), WORD(367), WORD(1670)}, + {WORD(-4139), WORD(59959), WORD(-286689), WORD(119918)}, + {WORD(7397588), WORD(16695), WORD(-41627), WORD(20034)}, + {WORD(-78900791), WORD(10792), WORD(-30905), WORD(21584)}, + {WORD(-1204294), WORD(10134), WORD(-8945), WORD(30402)}, + {WORD(27649424), WORD(57014291), WORD(731583513), WORD(114028582)}, + {WORD(3275043), WORD(436410815), WORD(2018428417), WORD(174564326)}, +#if FLINT64 /* skip on 32 bit only because of the literals */ + {WORD(61247), WORD(81381215), WORD(3622491319), WORD(32552486)}, + {WORD(-52118), WORD(125095621), WORD(-24931204413), WORD(125095621)}, + {WORD(201446493), WORD(951783261), WORD(2467429915), WORD(634522174)}, + {WORD(176112), WORD(72187934), WORD(2692844825), WORD(72187934)}, + {WORD(1272), WORD(8722219), WORD(9972821075), WORD(17444438)}, +#endif + {0, 0, 0, 0} +}; + +int main(void) +{ + fmpz_t hh, kk; + fmpq_t s1, s2; + slong i, h, k; + + FLINT_TEST_INIT(state); + + flint_printf("dedekind_sum...."); + fflush(stdout); + + fmpz_init(hh); + fmpz_init(kk); + fmpq_init(s1); + fmpq_init(s2); + + for (k = -200; k < 200; k++) + { + for (h = -200; h < 200; h++) + { + fmpz_set_si(hh, h); + fmpz_set_si(kk, k); + + arith_dedekind_sum(s1, hh, kk); + arith_dedekind_sum_naive(s2, hh, kk); + + if (!fmpq_equal(s1, s2)) + { + flint_printf("FAIL:\n"); + flint_printf("s(%wd,%wd)\n", h, k); + flint_printf("s1: "); fmpq_print(s1); flint_printf("\n"); + flint_printf("s2: "); fmpq_print(s2); flint_printf("\n"); + abort(); + } + } + } + + /* Test large values, 10-30 bits */ + for (i = 0; testdata[i][0] != 0; i++) + { + h = testdata[i][0]; + k = testdata[i][1]; + + fmpz_set_si(hh, h); + fmpz_set_si(kk, k); + + arith_dedekind_sum(s1, hh, kk); + + fmpz_set_si(fmpq_numref(s2), testdata[i][2]); + fmpz_set_si(fmpq_denref(s2), testdata[i][3]); + + if (!fmpq_equal(s1, s2)) + { + flint_printf("FAIL:\n"); + flint_printf("s(%wd,%wd)\n", h, k); + flint_printf("s1: "); fmpq_print(s1); flint_printf("\n"); + flint_printf("s2: "); fmpq_print(s2); flint_printf("\n"); + abort(); + } + } + + /* Check a large value computed with Pari */ + fmpz_set_ui(hh, 1); + fmpz_mul_2exp(hh, hh, 1000); + fmpz_add_ui(hh, hh, 1); + fmpz_set_ui(kk, 1); + fmpz_mul_2exp(kk, kk, 1001); + fmpz_add_ui(kk, kk, 1); + + arith_dedekind_sum(s1, hh, kk); + if ((fmpz_fdiv_ui(fmpq_numref(s1), 1000000000) != 906445312) || + (fmpz_fdiv_ui(fmpq_denref(s1), 1000000000) != 8416259)) + { + flint_printf("Wrong large value:\n"); + fmpq_print(s1); + flint_printf("\n"); + abort(); + } + + + /* Just check that nothing crashes with bignums */ + for (i = 0; i < 1000; i++) + { + fmpz_randtest(hh, state, 300); + fmpz_randtest(kk, state, 300); + + arith_dedekind_sum(s1, hh, kk); + } + + fmpz_clear(hh); + fmpz_clear(kk); + fmpq_clear(s1); + fmpq_clear(s2); + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/arith/test/t-dedekind_sum_coprime_d.c b/external/flint-2.4.3/arith/test/t-dedekind_sum_coprime_d.c new file mode 100644 index 0000000..13d1afc --- /dev/null +++ b/external/flint-2.4.3/arith/test/t-dedekind_sum_coprime_d.c @@ -0,0 +1,86 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq.h" +#include "arith.h" +#include "ulong_extras.h" +#include "math.h" + +int main(void) +{ + double s1, s2f; + fmpz_t hh, kk; + fmpq_t s2; + slong h, k; + + FLINT_TEST_INIT(state); + + flint_printf("dedekind_sum_coprime_d...."); + fflush(stdout); + + fmpz_init(hh); + fmpz_init(kk); + fmpq_init(s2); + + for (k = 0; k < 300; k++) + { + for (h = 0; h <= k; h++) + { + if (n_gcd(k, h) == 1) + { + fmpz_set_si(hh, h); + fmpz_set_si(kk, k); + + s1 = arith_dedekind_sum_coprime_d(h, k); + arith_dedekind_sum_naive(s2, hh, kk); + + s2f = ((double)fmpz_get_si(fmpq_numref(s2))) / + fmpz_get_si(fmpq_denref(s2)); + + if (fabs(s1 - s2f) > 1e-10) + { + flint_printf("FAIL:\n"); + flint_printf("s(%wd,%wd)\n", h, k); + flint_printf("s1: %.20f\n", s1); + flint_printf("s2: %.20f\n", s2f); + flint_printf("Exact: "); fmpq_print(s2); flint_printf("\n"); + abort(); + } + } + } + } + + fmpz_clear(hh); + fmpz_clear(kk); + fmpq_clear(s2); + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/arith/test/t-dedekind_sum_coprime_large.c b/external/flint-2.4.3/arith/test/t-dedekind_sum_coprime_large.c new file mode 100644 index 0000000..afeeed5 --- /dev/null +++ b/external/flint-2.4.3/arith/test/t-dedekind_sum_coprime_large.c @@ -0,0 +1,83 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq.h" +#include "arith.h" +#include "ulong_extras.h" +#include "math.h" + +int main(void) +{ + fmpz_t hh, kk; + fmpq_t s1, s2; + slong h, k; + + FLINT_TEST_INIT(state); + + flint_printf("dedekind_sum_coprime_large...."); + fflush(stdout); + + fmpz_init(hh); + fmpz_init(kk); + fmpq_init(s1); + fmpq_init(s2); + + for (k = 0; k < 300; k++) + { + for (h = 0; h <= k; h++) + { + if (n_gcd(k, h) == 1) + { + fmpz_set_si(hh, h); + fmpz_set_si(kk, k); + + arith_dedekind_sum_coprime_large(s1, hh, kk); + arith_dedekind_sum_naive(s2, hh, kk); + + if (!fmpq_equal(s1, s2)) + { + flint_printf("FAIL:\n"); + flint_printf("s(%wd,%wd)\n", h, k); + flint_printf("s1: "); fmpq_print(s1); flint_printf("\n"); + flint_printf("s2: "); fmpq_print(s2); flint_printf("\n"); + abort(); + } + } + } + } + + fmpz_clear(hh); + fmpz_clear(kk); + fmpq_clear(s1); + fmpq_clear(s2); + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/arith/test/t-divisor_sigma.c b/external/flint-2.4.3/arith/test/t-divisor_sigma.c new file mode 100644 index 0000000..77e6293 --- /dev/null +++ b/external/flint-2.4.3/arith/test/t-divisor_sigma.c @@ -0,0 +1,94 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz_poly.h" +#include "fmpz.h" +#include "arith.h" +#include "ulong_extras.h" + +void fmpz_sigma_naive(fmpz_t x, ulong n, ulong k) +{ + slong i = 0; + + fmpz_t t; + fmpz_poly_t p; + fmpz_init(t); + fmpz_poly_init(p); + fmpz_set_ui(t, n); + arith_divisors(p, t); + + fmpz_zero(x); + for (i = 0; i < p->length; i++) + { + fmpz_poly_get_coeff_fmpz(t, p, i); + fmpz_pow_ui(t, t, k); + fmpz_add(x, x, t); + } + + fmpz_clear(t); + fmpz_poly_clear(p); +} + +int main(void) +{ + fmpz_t m, a, b; + slong n, k; + + FLINT_TEST_INIT(state); + + flint_printf("divisor_sigma...."); + fflush(stdout); + + fmpz_init(a); + fmpz_init(b); + fmpz_init(m); + + for (n = 0; n < 5000; n++) + { + for (k = 0; k < 10; k++) + { + fmpz_set_ui(m, n); + arith_divisor_sigma(a, m, k); + fmpz_sigma_naive(b, n, k); + if (!fmpz_equal(a, b)) + { + flint_printf("FAIL:\n"); + flint_printf("wrong value for n=%wd, k=%wd\n", n, k); + abort(); + } + } + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(m); + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/arith/test/t-divisors.c b/external/flint-2.4.3/arith/test/t-divisors.c new file mode 100644 index 0000000..ee05527 --- /dev/null +++ b/external/flint-2.4.3/arith/test/t-divisors.c @@ -0,0 +1,86 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz_poly.h" +#include "arith.h" +#include "ulong_extras.h" + +void arith_divisors_naive(fmpz_poly_t p, slong n) +{ + slong k; + slong i = 0; + + n = FLINT_ABS(n); + + fmpz_poly_zero(p); + for (k = 1; k <= n; k++) + { + if (n % k == 0) + { + fmpz_poly_set_coeff_si(p, i, k); + i++; + } + } +} + +int main(void) +{ + fmpz_t t; + fmpz_poly_t a, b; + slong n; + + FLINT_TEST_INIT(state); + + flint_printf("divisors...."); + fflush(stdout); + + fmpz_init(t); + fmpz_poly_init(a); + fmpz_poly_init(b); + + for (n = -1000; n < 1000; n++) + { + fmpz_set_si(t, n); + arith_divisors(a, t); + arith_divisors_naive(b, n); + if (!fmpz_poly_equal(a, b)) + { + flint_printf("FAIL:\n"); + flint_printf("wrong value for n=%wd\n", n); + abort(); + } + } + + fmpz_clear(t); + fmpz_poly_clear(a); + fmpz_poly_clear(b); + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/arith/test/t-euler_number_vec.c b/external/flint-2.4.3/arith/test/t-euler_number_vec.c new file mode 100644 index 0000000..bd11c4b --- /dev/null +++ b/external/flint-2.4.3/arith/test/t-euler_number_vec.c @@ -0,0 +1,81 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "arith.h" +#include "profiler.h" +#include "fmpz.h" +#include "fmpz_vec.h" + + +int main() +{ + fmpz * r; + fmpz_t s, t; + slong k, n; + + FLINT_TEST_INIT(state); + + flint_printf("euler_number_vec...."); + fflush(stdout); + + for (n = 2; n <= 3000; n += (n<100) ? 2 : n/3) + { + n += n % 2; + r = _fmpz_vec_init(n + 1); + fmpz_init(s); + fmpz_init(t); + + arith_euler_number_vec(r, n + 1); + + /* sum binomial(n,k) E_k = 0 */ + fmpz_set_ui(t, UWORD(1)); + for (k = 0; k <= n; k++) + { + fmpz_addmul(s, r + k, t); + fmpz_mul_ui(t, t, n - k); + fmpz_divexact_ui(t, t, k + 1); + } + + if (!fmpz_is_zero(s)) + { + flint_printf("ERROR: sum over 0,...,n = %wd\n", n); + _fmpz_vec_print(r, n + 1); + abort(); + } + + fmpz_clear(s); + fmpz_clear(t); + _fmpz_vec_clear(r, n + 1); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/arith/test/t-euler_number_zeta.c b/external/flint-2.4.3/arith/test/t-euler_number_zeta.c new file mode 100644 index 0000000..06f1424 --- /dev/null +++ b/external/flint-2.4.3/arith/test/t-euler_number_zeta.c @@ -0,0 +1,74 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "arith.h" +#include "profiler.h" +#include "fmpz.h" +#include "fmpz_mat.h" +#include "fmpq_poly.h" + + +int main() +{ + fmpz * ress; + fmpz_t res; + slong n, N; + + FLINT_TEST_INIT(state); + + flint_printf("euler_number_zeta...."); + fflush(stdout); + + N = 3000; + + ress = _fmpz_vec_init(N); + arith_euler_number_vec(ress, N); + + for (n = 0; n < N; n++) + { + fmpz_init(res); + + arith_euler_number(res, n); + if (!fmpz_equal(res, ress + n)) + { + flint_printf("FAIL: n = %wd\n", n); + flint_printf("Value: "); fmpz_print(res); flint_printf("\n"); + abort(); + } + + fmpz_clear(res); + } + + _fmpz_vec_clear(ress, N); + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/arith/test/t-euler_phi.c b/external/flint-2.4.3/arith/test/t-euler_phi.c new file mode 100644 index 0000000..929e618 --- /dev/null +++ b/external/flint-2.4.3/arith/test/t-euler_phi.c @@ -0,0 +1,118 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "arith.h" +#include "ulong_extras.h" +#include "profiler.h" + + +int main(void) +{ + slong i; + ulong n; + fmpz_t x, y, z; + FLINT_TEST_INIT(state); + + flint_printf("euler_phi...."); + fflush(stdout); + + fmpz_init(x); + fmpz_init(y); + fmpz_init(z); + + + for (i = 0; i < 100; i++) + { + fmpz_set_ui(x, i); + arith_euler_phi(y, x); + arith_euler_phi(x, x); + fmpz_set_ui(z, n_euler_phi(i)); + if (!fmpz_equal(x, y) || !fmpz_equal(x, z)) + { + flint_printf("FAIL: %wd\n", i); + abort(); + } + } + + /* Aliasing test */ + for (i = 0; i < 1000; i++) + { + fmpz_randtest(x, state, FLINT_BITS); + fmpz_randtest(y, state, 5); + fmpz_pow_ui(y, y, n_randtest(state) % 100); + fmpz_mul(x, x, y); + fmpz_set(z, x); + arith_euler_phi(y, x); + arith_euler_phi(x, x); + if (!fmpz_equal(x, y)) + { + flint_printf("FAIL: "); + fmpz_print(z); + flint_printf("\n"); + abort(); + } + } + + /* Power of a single prime, phi(p^n) = (p-1) * p^(n-1) */ + for (i = 0; i < 100; i++) + { + n = (n_randtest(state) % 100) + 1; + fmpz_set_ui(x, n_nth_prime(i+1)); + fmpz_pow_ui(x, x, n); + arith_euler_phi(x, x); + fmpz_set_ui(y, n_nth_prime(i+1)); + fmpz_pow_ui(y, y, n-1); + fmpz_mul_ui(y, y, n_nth_prime(i+1)-1); + if (!fmpz_equal(x, y)) + { + flint_printf("FAIL: %wu ^ %wu\n", n_nth_prime(i+1), n); + } + } + + /* Something nontrivial */ + fmpz_set_str(x, "10426024348053113487152988625265848110501553295256578345594388516660144", 10); + fmpz_set_str(y, "2265085829098571747262267425315881590169106756213617459200000000000000", 10); + arith_euler_phi(x, x); + if (!fmpz_equal(x, y)) + { + flint_printf("FAIL: special test value\n"); + abort(); + } + + + + fmpz_clear(x); + fmpz_clear(y); + fmpz_clear(z); + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/arith/test/t-euler_polynomial.c b/external/flint-2.4.3/arith/test/t-euler_polynomial.c new file mode 100644 index 0000000..ee90d38 --- /dev/null +++ b/external/flint-2.4.3/arith/test/t-euler_polynomial.c @@ -0,0 +1,93 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "arith.h" +#include "profiler.h" +#include "fmpz.h" +#include "fmpz_mat.h" +#include "fmpq_poly.h" + + +int main() +{ + fmpq_poly_t P, Q; + mpz_t t; + + slong k, n; + + FLINT_TEST_INIT(state); + + flint_printf("euler_polynomial...."); + fflush(stdout); + + for (n = 0; n <= 100; n++) + { + fmpq_poly_init(P); + fmpq_poly_init(Q); + + mpz_init(t); + + for (k = 0; k < n; k++) + { + arith_euler_polynomial(P, k); + flint_mpz_bin_uiui(t, n, k); + fmpq_poly_scalar_mul_mpz(P, P, t); + fmpq_poly_add(Q, Q, P); + } + + fmpq_poly_scalar_div_ui(Q, Q, 2); + + arith_euler_polynomial(P, n); + fmpq_poly_add(Q, Q, P); + + mpz_clear(t); + + fmpq_poly_zero(P); + fmpq_poly_set_coeff_ui(P, n, UWORD(1)); + + if (!fmpq_poly_equal(P, Q)) + { + flint_printf("ERROR: sum up to n = %wd did not add to x^n\n", n); + flint_printf("Sum: "); + fmpq_poly_print_pretty(Q, "x"); + flint_printf("\nExpected: "); + fmpq_poly_print_pretty(P, "x"); + flint_printf("\n"); + abort(); + } + + fmpq_poly_clear(P); + fmpq_poly_clear(Q); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/arith/test/t-harmonic.c b/external/flint-2.4.3/arith/test/t-harmonic.c new file mode 100644 index 0000000..3b4ecd2 --- /dev/null +++ b/external/flint-2.4.3/arith/test/t-harmonic.c @@ -0,0 +1,154 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010,2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "arith.h" +#include "fmpz.h" +#include "fmpq.h" +#include "ulong_extras.h" +#include "profiler.h" + + +void numerical_test(fmpq_t res, slong n, double ans) +{ + const double tol = 1e-13; + double err; + + mpq_t tmp; + mpq_init(tmp); + + arith_harmonic_number(res, n); + fmpq_get_mpq(tmp, res); + err = mpq_get_d(tmp) - ans; + err = FLINT_ABS(err); + + if (err > tol) + { + flint_printf("FAIL: %wd %.16f %.16f\n", n, mpq_get_d(tmp), ans); + abort(); + } + + mpq_clear(tmp); +} + +void +mpq_harmonic_balanced(mpq_t res, slong a, slong b) +{ + slong k; + mpq_t t; + + mpq_init(t); + + if (b - a < 50) + { + flint_mpq_set_ui(res, 0, UWORD(1)); + for (k = a; k <= b; k++) + { + flint_mpq_set_ui(t, UWORD(1), k); + mpq_add(res, res, t); + } + } + else + { + mpq_harmonic_balanced(res, a, (a+b)/2); + mpq_harmonic_balanced(t, (a+b)/2+1, b); + mpq_add(res, res, t); + } + + mpq_clear(t); +} + + +int main(void) +{ + slong i; + mpq_t x, y; + fmpq_t t; + + FLINT_TEST_INIT(state); + + flint_printf("harmonic_number...."); + fflush(stdout); + + fmpq_init(t); + mpq_init(x); + mpq_init(y); + + for (i = -2; i < 1000; i++) + { + mpq_harmonic_balanced(x, 1, i); + arith_harmonic_number(t, i); + fmpq_get_mpq(y, t); + + if (!mpq_equal(x, y)) + { + flint_printf("FAIL: %wd\n", i); + abort(); + } + } + + numerical_test(t, 1000, 7.4854708605503449127); + numerical_test(t, 1001, 7.4864698615493459117); + numerical_test(t, 1002, 7.4874678655413618797); + numerical_test(t, 1003, 7.4884648745144426375); + + numerical_test(t, 10000, 9.7876060360443822642); + numerical_test(t, 10001, 9.7877060260453821642); + numerical_test(t, 10002, 9.7878060060493813643); + numerical_test(t, 10003, 9.7879059760583786652); + numerical_test(t, 10004, 9.7880059360743722677); + + numerical_test(t, 20000, 10.480728217229327573); + numerical_test(t, 30000, 10.886184992119899362); + numerical_test(t, 40000, 11.173862897945522882); + numerical_test(t, 50000, 11.397003949278482638); + numerical_test(t, 60000, 11.579323839415955783); + numerical_test(t, 70000, 11.733473328773164956); + numerical_test(t, 80000, 11.867003828544530692); + numerical_test(t, 90000, 11.984786169759202469); + + numerical_test(t, 100000, 12.090146129863427947); + numerical_test(t, 100001, 12.090156129763428947); + numerical_test(t, 100002, 12.090166129563432947); + numerical_test(t, 100003, 12.090176129263441947); + numerical_test(t, 100004, 12.090186128863457946); + + numerical_test(t, 300000, 13.188755085205611713); + numerical_test(t, 500000, 13.699580042305528322); + numerical_test(t, 700000, 14.036051993212618803); + numerical_test(t, 900000, 14.287366262763433338); + + mpq_clear(x); + mpq_clear(y); + fmpq_clear(t); + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/arith/test/t-landau_function_vec.c b/external/flint-2.4.3/arith/test/t-landau_function_vec.c new file mode 100644 index 0000000..3cd3146 --- /dev/null +++ b/external/flint-2.4.3/arith/test/t-landau_function_vec.c @@ -0,0 +1,70 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "arith.h" +#include "fmpz_vec.h" + +static const mp_limb_t known[] = { + 1, 1, 2, 3, 4, 6, 6, 12, 15, 20, 30, 30, 60, 60, 84, 105, 140, 210, + 210, 420, 420, 420, 420, 840, 840, 1260, 1260, 1540, 2310, 2520, + 4620, 4620, 5460, 5460, 9240, 9240, 13860, 13860, 16380, 16380, + 27720, 30030, 32760, 60060, 60060, 60060, 60060, 120120 +}; + +int main(void) +{ + fmpz * res; + slong k, n; + + FLINT_TEST_INIT(state); + + flint_printf("landau_function_vec...."); + fflush(stdout); + + n = 45; + res = _fmpz_vec_init(n); + arith_landau_function_vec(res, n); + + for (k = 0; k < n; k++) + { + if (fmpz_cmp_ui(res + k, known[k])) + { + flint_printf("FAIL:\n"); + flint_printf("k = %wd, res[k] = %wd, expected: %wd\n", + k, fmpz_get_si(res + k), known[k]); + abort(); + } + } + + _fmpz_vec_clear(res, n); + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/arith/test/t-legendre_polynomial.c b/external/flint-2.4.3/arith/test/t-legendre_polynomial.c new file mode 100644 index 0000000..c792af0 --- /dev/null +++ b/external/flint-2.4.3/arith/test/t-legendre_polynomial.c @@ -0,0 +1,86 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "arith.h" +#include "profiler.h" +#include "fmpz.h" +#include "fmpz_mat.h" +#include "fmpq_poly.h" + + +int main() +{ + fmpq_poly_t Pn, Pn1, Pn2, R; + + slong n; + + FLINT_TEST_INIT(state); + + flint_printf("legendre_polynomial...."); + fflush(stdout); + + fmpq_poly_init(Pn); + fmpq_poly_init(Pn1); + fmpq_poly_init(Pn2); + fmpq_poly_init(R); + + fmpq_poly_set_ui(Pn, UWORD(1)); + fmpq_poly_set_coeff_ui(Pn1, 1, UWORD(1)); + + for (n = 0; n <= 500; n++) + { + arith_legendre_polynomial(R, n); + + if (!fmpq_poly_equal(Pn, R)) + { + flint_printf("FAIL: n = %wd\n", n); + flint_printf("Direct: "); fmpq_poly_print_pretty(R, "x"); flint_printf("\n"); + flint_printf("Recur.: "); fmpq_poly_print_pretty(Pn, "x"); flint_printf("\n"); + abort(); + } + + fmpq_poly_shift_left(Pn2, Pn1, 1); + fmpq_poly_scalar_mul_ui(Pn2, Pn2, 2*n + 3); + fmpq_poly_scalar_mul_si(Pn, Pn, -(n+1)); + fmpq_poly_add(Pn2, Pn2, Pn); + fmpq_poly_scalar_div_ui(Pn2, Pn2, n+2); + + fmpq_poly_swap(Pn, Pn1); + fmpq_poly_swap(Pn1, Pn2); + } + + fmpq_poly_clear(Pn); + fmpq_poly_clear(Pn1); + fmpq_poly_clear(Pn2); + fmpq_poly_clear(R); + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/arith/test/t-moebius_mu.c b/external/flint-2.4.3/arith/test/t-moebius_mu.c new file mode 100644 index 0000000..c07347d --- /dev/null +++ b/external/flint-2.4.3/arith/test/t-moebius_mu.c @@ -0,0 +1,98 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "arith.h" +#include "ulong_extras.h" +#include "profiler.h" + + +void check(fmpz_t n, int expected) +{ + int mu; + + mu = arith_moebius_mu(n); + if (mu != expected) + { + flint_printf("FAIL:"); + fmpz_print(n); + flint_printf("\n"); + } +} + +int main(void) +{ + fmpz_t x; + ulong p; + slong i, j, k, l; + FLINT_TEST_INIT(state); + + flint_printf("moebius_mu...."); + fflush(stdout); + + fmpz_init(x); + + for (i = -1000; i < 1000; i++) + { + fmpz_set_si(x, i); + check(x, n_moebius_mu(FLINT_ABS(i))); + } + + for (i = 0; i < 1000; i++) + { + fmpz_set_ui(x, 1); + /* Product of some primes */ + k = n_randtest(state) % 10; + l = n_randtest(state) % 10; + for (j = 0; j < k; j++) + { + l += (n_randtest(state) % 10) + 1; + fmpz_mul_ui(x, x, n_nth_prime(l+1)); + } + + check(x, (k % 2 ? -1 : 1)); + fmpz_neg(x, x); + + check(x, (k % 2 ? -1 : 1)); + fmpz_abs(x, x); + + /* No longer square-free */ + p = n_nth_prime(n_randtest(state) % 100 + 1); + fmpz_mul_ui(x, x, p*p); + check(x, 0); + } + + fmpz_clear(x); + + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/arith/test/t-number_of_partitions.c b/external/flint-2.4.3/arith/test/t-number_of_partitions.c new file mode 100644 index 0000000..212bc2f --- /dev/null +++ b/external/flint-2.4.3/arith/test/t-number_of_partitions.c @@ -0,0 +1,160 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "arith.h" +#include "ulong_extras.h" + +/* Values mod 10^9 generated with Sage */ +static const ulong testdata[][2] = +{ + {100000, 421098519}, + {100001, 33940350}, + {100002, 579731933}, + {100003, 625213730}, + {100004, 539454200}, + {100005, 69672418}, + {100006, 865684292}, + {100007, 641916724}, + {100008, 36737908}, + {100009, 293498270}, + {100010, 177812057}, + {100011, 756857293}, + {100012, 950821113}, + {100013, 824882014}, + {100014, 533894560}, + {100015, 660734788}, + {100016, 835912257}, + {100017, 302982816}, + {100018, 468609888}, + {100019, 221646940}, + {1000000, 104673818}, + {1000001, 980212296}, + {1000002, 709795681}, + {1000003, 530913758}, + {1000004, 955452980}, + {1000005, 384388683}, + {1000006, 138665072}, + {1000007, 144832602}, + {1000008, 182646067}, + {1000009, 659145045}, + {1000010, 17911162}, + {1000011, 606326324}, + {1000012, 99495156}, + {1000013, 314860251}, + {1000014, 497563335}, + {1000015, 726842109}, + {1000016, 301469541}, + {1000017, 227491620}, + {1000018, 704160927}, + {1000019, 995311980}, + {10000000, 677288980}, + {10000001, 433805210}, + {10000002, 365406948}, + {10000003, 120899894}, + {10000004, 272822040}, + {10000005, 71938624}, + {10000006, 637670808}, + {10000007, 766947591}, + {10000008, 980210244}, + {10000009, 965734705}, + {10000010, 187411691}, + {10000011, 485652153}, + {10000012, 825498761}, + {10000013, 895802660}, + {10000014, 152775845}, + {10000015, 791493402}, + {10000016, 299640598}, + {10000017, 383615481}, + {10000018, 378922331}, + {10000019, 37059200}, + {100000000, 836637702}, + {100000001, 66421565}, + {100000002, 747849093}, + {100000003, 465329748}, + {100000004, 166747980}, + {0, 0}, +}; + +int main(void) +{ + fmpz_t p; + fmpz * v; + + slong i; + + FLINT_TEST_INIT(state); + + flint_printf("number_of_partitions...."); + fflush(stdout); + + fmpz_init(p); + v = _fmpz_vec_init(3000); + + arith_number_of_partitions_vec(v, 3000); + + for (i = 0; i < 3000; i++) + { + arith_number_of_partitions(p, i); + if (!fmpz_equal(p, v + i)) + { + flint_printf("FAIL:\n"); + flint_printf("p(%wd) does not agree with power series\n", i); + flint_printf("Computed p(%wd): ", i); fmpz_print(p); flint_printf("\n"); + flint_printf("Expected: "); fmpz_print(v + i); flint_printf("\n"); + abort(); + } + } + + _fmpz_vec_clear(v, 3000); + + for (i = 0; testdata[i][0] != 0; i++) + { + arith_number_of_partitions(p, testdata[i][0]); + + if (fmpz_fdiv_ui(p, 1000000000) != testdata[i][1]) + { + flint_printf("FAIL:\n"); + flint_printf("p(%wd) does not agree with known value mod 10^9\n", + testdata[i][0]); + flint_printf("Computed: %wu\n", fmpz_fdiv_ui(p, 1000000000)); + flint_printf("Expected: %wu\n", testdata[i][1]); + abort(); + } + } + + fmpz_clear(p); + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/arith/test/t-number_of_partitions_vec.c b/external/flint-2.4.3/arith/test/t-number_of_partitions_vec.c new file mode 100644 index 0000000..f6a8406 --- /dev/null +++ b/external/flint-2.4.3/arith/test/t-number_of_partitions_vec.c @@ -0,0 +1,120 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "arith.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" +#include "profiler.h" +#include "nmod_vec.h" + +int main(void) +{ + fmpz * p; + mp_ptr pmod; + slong k, n; + + const slong maxn = 1000; + + FLINT_TEST_INIT(state); + + flint_printf("number_of_partitions_vec...."); + fflush(stdout); + + p = _fmpz_vec_init(maxn); + pmod = _nmod_vec_init(maxn); + + for (n = 0; n < maxn; n += (n < 50) ? + 1 : n/4) + { + fmpz_t s, t; + nmod_t mod; + nmod_init(&mod, n_randtest_prime(state, 0)); + + arith_number_of_partitions_vec(p, n); + arith_number_of_partitions_nmod_vec(pmod, n, mod); + + for (k = 0; k < n; k++) + { + if (fmpz_fdiv_ui(p + k, mod.n) != pmod[k]) + { + flint_printf("FAIL:\n"); + flint_printf("n = %wd, k = %wd\n", n, k); + abort(); + } + } + + if (n > 1) + { + fmpz_init(s); + fmpz_init(t); + + for (k = 1; k < n; k++) + { + slong j; + + j = n - 1 - k*(3*k - 1)/2; + if (j >= 0) + fmpz_set(t, p + j); + else + fmpz_zero(t); + + j = n - 1 - k*(3*k + 1)/2; + if (j >= 0) + fmpz_add(t, t, p + j); + + if (k % 2) + fmpz_add(s, s, t); + else + fmpz_sub(s, s, t); + } + + if (!fmpz_equal(s, p + n - 1)) + { + flint_printf("FAIL:\n"); + flint_printf("n = %wd\n", n); + fmpz_print(s); + flint_printf("\n"); + fmpz_print(p + n - 1); + flint_printf("\n"); + abort(); + } + + fmpz_clear(s); + fmpz_clear(t); + } + } + + _fmpz_vec_clear(p, maxn); + _nmod_vec_clear(pmod); + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/arith/test/t-pi_chudnovsky.c b/external/flint-2.4.3/arith/test/t-pi_chudnovsky.c new file mode 100644 index 0000000..911b793 --- /dev/null +++ b/external/flint-2.4.3/arith/test/t-pi_chudnovsky.c @@ -0,0 +1,66 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "arith.h" +#include "ulong_extras.h" + + +int main(void) +{ + slong k; + + FLINT_TEST_INIT(state); + + flint_printf("pi_chudnovsky...."); + fflush(stdout); + + for (k = 2; k < 20; k++) + { + mpfr_t x, y; + + mpfr_init2(x, WORD(1) << k); + mpfr_init2(y, WORD(1) << k); + + mpfr_const_pi(x, MPFR_RNDN); + mpfr_pi_chudnovsky(y, MPFR_RNDN); + + if (!mpfr_equal_p(x, y)) + { + flint_printf("FAIL:\n"); + flint_printf("Wrong value at prec = %wd\n", WORD(1) << k); + abort(); + } + + mpfr_clear(x); + mpfr_clear(y); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/arith/test/t-primorial.c b/external/flint-2.4.3/arith/test/t-primorial.c new file mode 100644 index 0000000..cbebe13 --- /dev/null +++ b/external/flint-2.4.3/arith/test/t-primorial.c @@ -0,0 +1,69 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "arith.h" +#include "ulong_extras.h" + + +int main(void) +{ + ulong k; + fmpz_t x; + fmpz_t y; + + FLINT_TEST_INIT(state); + + flint_printf("primorial...."); + fflush(stdout); + + fmpz_init(x); + fmpz_init(y); + fmpz_set_ui(y, 1); + + for (k = 0; k < 10000; k++) + { + arith_primorial(x, k); + if (n_is_prime(k)) + fmpz_mul_ui(y, y, k); + if (!fmpz_equal(x, y)) + { + flint_printf("FAIL:\n"); + flint_printf("primorial of %wu disagrees with direct product\n", k); + fmpz_print(x); + flint_printf("\n"); + abort(); + } + } + + fmpz_clear(x); + fmpz_clear(y); + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/arith/test/t-ramanujan_tau.c b/external/flint-2.4.3/arith/test/t-ramanujan_tau.c new file mode 100644 index 0000000..8b29625 --- /dev/null +++ b/external/flint-2.4.3/arith/test/t-ramanujan_tau.c @@ -0,0 +1,172 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "arith.h" +#include "ulong_extras.h" + +void check_value(slong n, char *ans) +{ + fmpz_t x, y; + fmpz_init(x); + fmpz_init(y); + fmpz_set_si(y, n); + arith_ramanujan_tau(x, y); + fmpz_set_str(y, ans, 10); + if (!fmpz_equal(x,y)) + { + flint_printf("FAIL:\n"); + flint_printf("tau(%wd) gave ", n); + fmpz_print(x); + flint_printf(", expected %s\n", ans); + abort(); + } + fmpz_clear(x); + fmpz_clear(y); +} + +void consistency_check(slong n) +{ + fmpz_poly_t p; + fmpz_t x, y; + slong k; + + fmpz_poly_init(p); + fmpz_init(x); + fmpz_init(y); + + arith_ramanujan_tau_series(p, n); + if (p->length != n && !(n == 1 && p->length == 0)) + { + flint_printf("FAIL:\n"); + flint_printf("wrong length of polynomial %wd\n", n); + abort(); + } + + for (k=0; k +#include +#include +#include +#include "flint.h" +#include "arith.h" +#include "fmpz_vec.h" +#include "fmpz_mat.h" +#include "ulong_extras.h" +#include "profiler.h" + +int main(void) +{ + fmpz_mat_t mat, mat2, mat3; + + fmpz * row; + fmpz_t s; + + slong n, k, mm, nn; + + const slong maxn = 40; + + FLINT_TEST_INIT(state); + + flint_printf("stirling...."); + fflush(stdout); + + fmpz_init(s); + + for (mm = 0; mm < maxn / 2; mm++) + { + /* Consistency test for stirling1u */ + + for (nn = 0; nn < maxn; nn++) + { + fmpz_mat_init(mat, mm, nn); + arith_stirling_matrix_1u(mat); + + for (n = 0; n < mm; n++) + { + for (k = 0; k < nn; k++) + { + row = _fmpz_vec_init(k); + arith_stirling_number_1u_vec(row, n, k); + if (!_fmpz_vec_equal(row, mat->rows[n], k)) + { + flint_printf("stirling1u mat != vec "); + flint_printf("nn,n,k=%wd,%wd,%wd\n", nn, n, k); + flint_printf("mat: "); + _fmpz_vec_print(mat->rows[n], k); + flint_printf("\nvec: "); + _fmpz_vec_print(row, k); + abort(); + } + _fmpz_vec_clear(row, k); + + arith_stirling_number_1u(s, n, k); + if (!fmpz_equal(mat->rows[n]+k, s)) + { + flint_printf("stirling1u mat != single "); + flint_printf("nn,n,k=%wd,%wd,%wd\n", nn, n, k); + flint_printf("mat: "); + fmpz_print(mat->rows[n]+k); + flint_printf("\nsingle: "); + fmpz_print(s); + abort(); + } + } + } + + fmpz_mat_clear(mat); + } + + /* Consistency test for stirling1 */ + for (nn = 0; nn < maxn; nn++) + { + fmpz_mat_init(mat, mm, nn); + arith_stirling_matrix_1(mat); + + for (n = 0; n < mm; n++) + { + for (k = 0; k < nn; k++) + { + row = _fmpz_vec_init(k); + arith_stirling_number_1_vec(row, n, k); + if (!_fmpz_vec_equal(row, mat->rows[n], k)) + { + flint_printf("stirling1 mat != vec "); + flint_printf("nn,n,k=%wd,%wd,%wd\n", nn, n, k); + flint_printf("mat: "); + _fmpz_vec_print(mat->rows[n], k); + flint_printf("\nvec: "); + _fmpz_vec_print(row, k); + abort(); + } + _fmpz_vec_clear(row, k); + + arith_stirling_number_1(s, n, k); + if (!fmpz_equal(mat->rows[n]+k, s)) + { + flint_printf("stirling1 mat != single "); + flint_printf("nn,n,k=%wd,%wd,%wd\n", nn, n, k); + flint_printf("mat: "); + fmpz_print(mat->rows[n]+k); + flint_printf("\nsingle: "); + fmpz_print(s); + abort(); + } + } + } + + fmpz_mat_clear(mat); + } + + /* Consistency test for stirling2 */ + for (nn = 0; nn < maxn; nn++) + { + fmpz_mat_init(mat, mm, nn); + arith_stirling_matrix_2(mat); + + for (n = 0; n < mm; n++) + { + for (k = 0; k < nn; k++) + { + row = _fmpz_vec_init(k); + arith_stirling_number_2_vec(row, n, k); + if (!_fmpz_vec_equal(row, mat->rows[n], k)) + { + flint_printf("stirling2 mat != vec "); + flint_printf("nn,n,k=%wd,%wd,%wd\n", nn, n, k); + flint_printf("mat: "); + _fmpz_vec_print(mat->rows[n], k); + flint_printf("\nvec: "); + _fmpz_vec_print(row, k); + abort(); + } + _fmpz_vec_clear(row, k); + + arith_stirling_number_2(s, n, k); + if (!fmpz_equal(mat->rows[n]+k, s)) + { + flint_printf("stirling2 mat != single "); + flint_printf("nn,n,k=%wd,%wd,%wd\n", nn, n, k); + flint_printf("mat: "); + fmpz_print(mat->rows[n]+k); + flint_printf("\nsingle: "); + fmpz_print(s); + abort(); + } + } + } + + fmpz_mat_clear(mat); + } + + } + + /* Matrix inverse test */ + for (nn = 1; nn < 50; nn++) + { + fmpz_mat_init(mat, nn, nn); + fmpz_mat_init(mat2, nn, nn); + fmpz_mat_init(mat3, nn, nn); + + arith_stirling_matrix_1(mat); + arith_stirling_matrix_2(mat2); + fmpz_mat_mul(mat3, mat, mat2); + + for (n = 0; n < nn; n++) + { + for (k = 0; k < nn; k++) + { + if (fmpz_get_ui(mat3->rows[n]+k) != (n == k)) + { + flint_printf("not identity matrix: %wd, %wd, %wd\n", nn, n, k); + abort(); + } + } + } + fmpz_mat_clear(mat); + fmpz_mat_clear(mat2); + fmpz_mat_clear(mat3); + } + + fmpz_clear(s); + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/arith/test/t-sum_of_squares.c b/external/flint-2.4.3/arith/test/t-sum_of_squares.c new file mode 100644 index 0000000..cc6424e --- /dev/null +++ b/external/flint-2.4.3/arith/test/t-sum_of_squares.c @@ -0,0 +1,88 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "arith.h" +#include "fmpz_vec.h" + +#define N 10 + +static const fmpz known[N][N] = { + {1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 2, 0, 0, 2, 0, 0, 0, 0, 2}, + {1, 4, 4, 0, 4, 8, 0, 0, 4, 4}, + {1, 6, 12, 8, 6, 24, 24, 0, 12, 30}, + {1, 8, 24, 32, 24, 48, 96, 64, 24, 104}, + {1, 10, 40, 80, 90, 112, 240, 320, 200, 250}, + {1, 12, 60, 160, 252, 312, 544, 960, 1020, 876}, + {1, 14, 84, 280, 574, 840, 1288, 2368, 3444, 3542}, + {1, 16, 112, 448, 1136, 2016, 3136, 5504, 9328, 12112}, + {1, 18, 144, 672, 2034, 4320, 7392, 12672, 22608, 34802} +}; + +int main(void) +{ + fmpz * r; + fmpz_t t; + slong i, j; + + FLINT_TEST_INIT(state); + + flint_printf("sum_of_squares...."); + fflush(stdout); + + r = _fmpz_vec_init(N); + fmpz_init(t); + + for (i = 0; i < N; i++) + { + arith_sum_of_squares_vec(r, i, N); + + for (j = 0; j < N; j++) + { + fmpz_set_ui(t, j); + arith_sum_of_squares(t, i, t); + + if (!fmpz_equal(t, r + j) || !fmpz_equal(t, known[i] + j)) + { + flint_printf("FAIL:\n"); + flint_printf("i, j = %wd, %wd, r[j] = %wd, r(j) = %wd, " + "expected: %wd\n", + i, j, fmpz_get_si(r + j), fmpz_get_si(t), known[i][j]); + abort(); + } + } + } + + _fmpz_vec_clear(r, N); + fmpz_clear(t); + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/arith/test/t-swinnerton_dyer_polynomial.c b/external/flint-2.4.3/arith/test/t-swinnerton_dyer_polynomial.c new file mode 100644 index 0000000..5a70fd0 --- /dev/null +++ b/external/flint-2.4.3/arith/test/t-swinnerton_dyer_polynomial.c @@ -0,0 +1,80 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "arith.h" +#include "profiler.h" +#include "fmpz.h" +#include "fmpz_mat.h" +#include "fmpq_poly.h" + +static const mp_limb_t known_values[] = +{ + UWORD(2147483629), + UWORD(1073742093), + UWORD(1342248677), + UWORD(3319936736), + UWORD(2947821228), + UWORD(1019513834), + UWORD(3324951530), + UWORD(1995039408), + UWORD(3505683295), + UWORD(3567639420), + UWORD(394942914) +}; + +int main() +{ + fmpz_poly_t S; + mp_limb_t r; + slong n; + + FLINT_TEST_INIT(state); + + flint_printf("swinnerton_dyer_polynomial...."); + fflush(stdout); + + for (n = 0; n <= 10; n++) + { + fmpz_poly_init(S); + arith_swinnerton_dyer_polynomial(S, n); + r = fmpz_poly_evaluate_mod(S, UWORD(2147483629), UWORD(4294967291)); + + if (r != known_values[n]) + { + flint_printf("ERROR: wrong evaluation of S_%wd\n", n); + abort(); + } + + fmpz_poly_clear(S); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/arith/zeta_inv_euler_product.c b/external/flint-2.4.3/arith/zeta_inv_euler_product.c new file mode 100644 index 0000000..e0b249e --- /dev/null +++ b/external/flint-2.4.3/arith/zeta_inv_euler_product.c @@ -0,0 +1,107 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "arith.h" + +void mpfr_zeta_inv_euler_product(mpfr_t res, ulong s, int char_4) +{ + mpz_t z, x, y, r; + mp_limb_t p; + slong prec, powprec, yexp, shift; + + mpz_init(x); + mpz_init(y); + mpz_init(z); + mpz_init(r); + + prec = mpfr_get_prec(res) + 32 + 2*FLINT_BIT_COUNT(s); + + flint_mpz_set_ui(z, UWORD(1)); + mpz_mul_2exp(z, z, prec); + + if (!char_4) + { + flint_mpz_set_ui(r, UWORD(1)); + mpz_mul_2exp(r, r, prec - s); + mpz_sub(z, z, r); + } + + p = UWORD(3); + + while (1) + { + slong i; + powprec = prec - s*log(p)*1.4426950408889634 + 1; + + /* flint_printf("prime %wu, powprec %wd\n", p, powprec); */ + + if (powprec < 5) + break; + + flint_mpz_set_ui(x, p); + flint_mpz_set_ui(y, UWORD(1)); + yexp = 0; + + /* Slow equivalent: flint_mpz_pow_ui(y, x, s) */ + flint_mpz_set_ui(y, p); + for (i = FLINT_BIT_COUNT(s) - 2; i >= 0; i--) + { + mpz_mul(y, y, y); + yexp += yexp; + shift = mpz_sizeinbase(y, 2) - powprec - 4; + if (shift >= 0) + { + mpz_tdiv_q_2exp(y, y, shift); + yexp += shift; + } + + if (s & (UWORD(1)<= 0) + mpz_tdiv_q_2exp(r, z, shift); + else + mpz_mul_2exp(r, z, -shift); + + mpz_tdiv_q(r, r, y); + + if (char_4 && (p % 4 == 3)) + mpz_add(z, z, r); + else + mpz_sub(z, z, r); + + p = n_nextprime(p, 0); + } + + mpfr_set_z_2exp(res, z, -prec, GMP_RNDN); + + mpz_clear(x); + mpz_clear(y); + mpz_clear(z); + mpz_clear(r); +} diff --git a/external/flint-2.4.3/arithxx.h b/external/flint-2.4.3/arithxx.h new file mode 100644 index 0000000..006972c --- /dev/null +++ b/external/flint-2.4.3/arithxx.h @@ -0,0 +1,339 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#ifndef ARITHXX_H +#define ARITHXX_H + +#include "arith.h" + +#include "fmpq_polyxx.h" +#include "fmpqxx.h" +#include "fmpz_matxx.h" +#include "fmpz_vecxx.h" +#include "fmpzxx.h" +#include "nmod_vecxx.h" + +// TODO namespace arith? +// TODO arith_hrr_expsum_factored +// TODO codegen / vector improvements + +namespace flint { +namespace detail { +template +inline typename T::wrapped_traits::data_srcref_t extract_data(const T& t, + typename mp::enable_if >::type* = 0) +{ + return t._data().inner; +} +template +inline typename T::wrapped_traits::data_ref_t extract_data(T& t, + typename mp::enable_if >::type* = 0) +{ + return t._data().inner; +} +template +const T& extract_data(const T& t, + typename mp::disable_if >::type* = 0) +{ + return t; +} +template +typename T::arrayref_t extract_data(T& t, + typename mp::disable_if >::type* = 0, + typename mp::enable_if, + rules::FMPQ_VECXX_COND_S > >::type* = 0) +{ + return t._array(); +} +} +#define ARITHXX_DEFINE_UNOP(name, Return, Cond) \ +FLINT_DEFINE_UNOP(name) \ +namespace rules { \ +FLINT_DEFINE_UNARY_EXPR_COND(name##_op, Return, Cond, \ + arith_##name(detail::extract_data(to), detail::extract_data(from))) \ +} +#define ARITHXX_DEFINE_BINOP(name, Return, Cond1, Cond2) \ +FLINT_DEFINE_BINOP(name) \ +namespace rules { \ +FLINT_DEFINE_BINARY_EXPR_COND2(name##_op, Return, Cond1, Cond2, \ + arith_##name(detail::extract_data(to), detail::extract_data(e1), \ + detail::extract_data(e2))) \ +} + +namespace at { +template struct slong : traits::fits_into_slong { }; +template struct ulong : traits::is_unsigned_integer { }; +} // at + +ARITHXX_DEFINE_UNOP(primorial, fmpzxx, at::slong) +ARITHXX_DEFINE_UNOP(harmonic_number, fmpqxx, at::slong) +ARITHXX_DEFINE_BINOP(stirling_number_1u, fmpzxx, at::slong, at::slong) +ARITHXX_DEFINE_BINOP(stirling_number_1, fmpzxx, at::slong, at::slong) +ARITHXX_DEFINE_BINOP(stirling_number_2, fmpzxx, at::slong, at::slong) +ARITHXX_DEFINE_BINOP(stirling_number_1u_vec, fmpz_vecxx, at::slong, at::slong) +ARITHXX_DEFINE_BINOP(stirling_number_1_vec, fmpz_vecxx, at::slong, at::slong) +ARITHXX_DEFINE_BINOP(stirling_number_2_vec, fmpz_vecxx, at::slong, at::slong) +FLINT_DEFINE_BINOP(stirling_number_1u_vec_next) +FLINT_DEFINE_BINOP(stirling_number_1_vec_next) +FLINT_DEFINE_BINOP(stirling_number_2_vec_next) +FLINT_DEFINE_BINOP(stirling_matrix_1u) +FLINT_DEFINE_BINOP(stirling_matrix_1) +FLINT_DEFINE_BINOP(stirling_matrix_2) + +namespace vectors { +template<> +struct outsize +{ + template + static unsigned get(const Expr& e) {return e._data().second();} +}; +template<> struct outsize + : outsize { }; +template<> struct outsize + : outsize { }; + +template<> +struct outsize +{ + template + static unsigned get(const Expr& e) + { + slong r = e._data().first().size(); + if(r == e._data().second()) + return r + 1; + return r; + } +}; +template<> struct outsize + : outsize { }; +template<> struct outsize + : outsize { }; +} // vectors + +namespace matrices { +template<> +struct outsize +{ + template + static slong rows(const Expr& e) {return e._data().first();} + template + static slong cols(const Expr& e) {return e._data().second();} +}; +template<> struct outsize + : outsize { }; +template<> struct outsize + : outsize { }; +} // matrices + +namespace rules { +FLINT_DEFINE_BINARY_EXPR_COND2(stirling_number_1u_vec_next_op, fmpz_vecxx, + FMPZ_VECXX_COND_S, at::slong, + arith_stirling_number_1u_vec_next(to._array(), e1._array(), e2, + e1.size() + (e1.size() == e2))) +FLINT_DEFINE_BINARY_EXPR_COND2(stirling_number_1_vec_next_op, fmpz_vecxx, + FMPZ_VECXX_COND_S, at::slong, + arith_stirling_number_1_vec_next(to._array(), e1._array(), e2, + e1.size() + (e1.size() == e2))) +FLINT_DEFINE_BINARY_EXPR_COND2(stirling_number_2_vec_next_op, fmpz_vecxx, + FMPZ_VECXX_COND_S, at::slong, + arith_stirling_number_2_vec_next(to._array(), e1._array(), e2, + e1.size() + (e1.size() == e2))) + +FLINT_DEFINE_BINARY_EXPR_COND2(stirling_matrix_1u_op, fmpz_matxx, + at::slong, at::slong, arith_stirling_matrix_1u(to._mat())) +FLINT_DEFINE_BINARY_EXPR_COND2(stirling_matrix_1_op, fmpz_matxx, + at::slong, at::slong, arith_stirling_matrix_1(to._mat())) +FLINT_DEFINE_BINARY_EXPR_COND2(stirling_matrix_2_op, fmpz_matxx, + at::slong, at::slong, arith_stirling_matrix_2(to._mat())) +} // rules + +ARITHXX_DEFINE_UNOP(bell_number, fmpzxx, at::ulong) +ARITHXX_DEFINE_UNOP(bell_number_bsplit, fmpzxx, at::ulong) +ARITHXX_DEFINE_UNOP(bell_number_multi_mod, fmpzxx, at::ulong) +ARITHXX_DEFINE_UNOP(bell_number_vec, fmpz_vecxx, at::slong) +ARITHXX_DEFINE_UNOP(bell_number_vec_recursive, fmpz_vecxx, at::slong) +ARITHXX_DEFINE_UNOP(bell_number_vec_multi_mod, fmpz_vecxx, at::slong) +FLINT_DEFINE_BINOP(bell_number_nmod) +FLINT_DEFINE_BINOP(bell_number_nmod_vec) +FLINT_DEFINE_BINOP(bell_number_nmod_vec_recursive) +FLINT_DEFINE_BINOP(bell_number_nmod_vec_series) + +namespace vectors { +template<> +struct outsize +{ + template static unsigned get(const Expr& e) + {return e._data().first();} +}; +template<> struct outsize + : outsize { }; +template<> struct outsize + : outsize { }; +template<> struct outsize + : outsize { }; +template<> struct outsize + : outsize { }; +template<> struct outsize + : outsize { }; +} // vectors + +namespace at { +template struct nmod : mp::or_, + mp::equal_types > { }; +} // at + +#define NMODXX_DEFINE_FIND_CTX_BY_OP(exprname, eval) \ +namespace traits { \ +template \ +struct has_nmodxx_ctx< exprname, Data> > : mp::true_ { }; \ +} \ +namespace detail { \ +template \ +struct get_nmodxx_ctx > \ +{ \ + template \ + static nmodxx_ctx_srcref get(const T& e) {return eval;} \ +}; \ +} +#define FLINTXX_COMMA() , +NMODXX_DEFINE_FIND_CTX_BY_OP(nmodxx_expression +struct outsize +{ + template static unsigned get(const Expr& e) + {return e._data().first();} +}; +} // vectors + +ARITHXX_DEFINE_UNOP(euler_number, fmpzxx, at::ulong) +ARITHXX_DEFINE_UNOP(euler_number_vec, fmpz_vecxx, at::ulong) +ARITHXX_DEFINE_UNOP(euler_polynomial, fmpq_polyxx, at::ulong) + +namespace vectors { +template<> struct outsize + : outsize { }; +} + +ARITHXX_DEFINE_UNOP(legendre_polynomial, fmpq_polyxx, at::ulong) +ARITHXX_DEFINE_UNOP(chebyshev_t_polynomial, fmpz_polyxx, at::ulong) +ARITHXX_DEFINE_UNOP(chebyshev_u_polynomial, fmpz_polyxx, at::ulong) +ARITHXX_DEFINE_UNOP(euler_phi, fmpzxx, FMPZXX_COND_S) +ARITHXX_DEFINE_BINOP(divisor_sigma, fmpzxx, FMPZXX_COND_S, at::ulong) +ARITHXX_DEFINE_UNOP(divisors, fmpz_polyxx, FMPZXX_COND_S) +ARITHXX_DEFINE_UNOP(ramanujan_tau, fmpzxx, FMPZXX_COND_S) +ARITHXX_DEFINE_UNOP(ramanujan_tau_series, fmpz_polyxx, at::slong) +ARITHXX_DEFINE_UNOP(cyclotomic_polynomial, fmpz_polyxx, at::ulong) +ARITHXX_DEFINE_UNOP(cos_minpoly, fmpz_polyxx, at::ulong) +ARITHXX_DEFINE_UNOP(swinnerton_dyer_polynomial, fmpz_polyxx, at::ulong) +ARITHXX_DEFINE_UNOP(landau_function_vec, fmpz_vecxx, at::slong) + +namespace vectors { +template<> struct outsize + : outsize { }; +} + +ARITHXX_DEFINE_BINOP(dedekind_sum_naive, fmpqxx, + FMPZXX_COND_S, FMPZXX_COND_S) +ARITHXX_DEFINE_BINOP(dedekind_sum_coprime_large, fmpqxx, + FMPZXX_COND_S, FMPZXX_COND_S) +ARITHXX_DEFINE_BINOP(dedekind_sum_coprime, fmpqxx, + FMPZXX_COND_S, FMPZXX_COND_S) +ARITHXX_DEFINE_BINOP(dedekind_sum, fmpqxx, + FMPZXX_COND_S, FMPZXX_COND_S) + +ARITHXX_DEFINE_UNOP(number_of_partitions_vec, fmpz_vecxx, at::slong) +ARITHXX_DEFINE_UNOP(number_of_partitions, fmpzxx, at::ulong) +FLINT_DEFINE_BINOP(number_of_partitions_nmod_vec) + +namespace vectors { +template<> struct outsize + : outsize { }; +template<> struct outsize + : outsize { }; +} + +NMODXX_DEFINE_FIND_CTX_BY_OP(vector_expression struct outsize + : outsize { }; +} + +inline double bell_number_size(ulong n) {return arith_bell_number_size(n);} +inline double bernoulli_number_size(ulong n) + {return arith_bernoulli_number_size(n);} +inline double euler_number_size(ulong n) {return arith_euler_number_size(n);} +inline double dedekind_sum_coprime_d(double h, double k) + {return arith_dedekind_sum_coprime_d(h, k);} + +template +inline typename mp::enable_if, int>::type moebius_mu( + const Fmpz& n) +{ + return arith_moebius_mu(n.evaluate()._fmpz()); +} +} // flint + +#endif diff --git a/external/flint-2.4.3/clz_tab.c b/external/flint-2.4.3/clz_tab.c new file mode 100644 index 0000000..41c9066 --- /dev/null +++ b/external/flint-2.4.3/clz_tab.c @@ -0,0 +1,45 @@ +/* __clz_tab -- support for longlong.h + +Copyright 1991, 1993, 1994, 1996, 1997, 2000, 2001 Free Software Foundation, +Inc. + + This file is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or (at your + option) any later version. + + This file 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 Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this file; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. + +*/ + +/* + N.B: This file has been adapted from code found in GMP 4.2.1. +*/ + +#include "longlong.h" + +#ifdef NEED_CLZ_TAB + +const +unsigned char __flint_clz_tab[128] = +{ + 1,2,3,3,4,4,4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8 +}; + +#endif + +int dummy_fn_to_prevent_ISOC_warning(void) +{ + return 0; +} diff --git a/external/flint-2.4.3/code_conventions.txt b/external/flint-2.4.3/code_conventions.txt new file mode 100644 index 0000000..3e9b08a --- /dev/null +++ b/external/flint-2.4.3/code_conventions.txt @@ -0,0 +1,109 @@ +Code conventions +================ + +Language dialect +---------------- + +For greater portability, the code should be ANSI C compatible where possible. +We note the following exceptions: + + - Inlined functions, inlined assembly. We define alternative keywords + __asm__ and __inline__ in flint.h so that gcc allows compiling with + the flags "-ansi -pendatic" nonetheless. + +Primitive types +--------------- + +Depending on the main interpretation of the value of a variable, where +possible the following primitive datatype should be used: + + | bit counts up to a single limb | ulong | + | bit counts, multiprecision | mp_bitcnt_t | + | byte counts (strings) | size_t | + | limb counts in multiprecision integers | mp_size_t | + | limbs (unsigned/signed) | mp_limb_t/ mp_limb_signed_t | + | mp_limb_t arrays | mp_ptr/ mp_srcptr | + | ui/ si function constants | ulong/ slong | + | exponents (unsigned/signed) | ulong/ slong | + | polynomial lengths | slong | + | number of indeterminates | slong | + | row/ column indices | slong | + | precision for mpfr types | mpfr_prec_t | + +The typical definitions of these in terms of primitive types are: + + | mp_bitcnt_t | ulong, or ulong long | + | mp_size_t | long, or long long | + | mp_limb_t | ulong, or ulong long | + | mp_ptr | mp_limb_t * | + | mp_srcptr | const mp_limb_t * | + | slong | long or long long | + | ulong | ulong or ulong long | + +Use of const +------------ + +Input parameters to functions should be marked const in the following cases: + +* complex types that are passed by reference, e.g. fmpz_poly_t + +They should not be used on output parameters or for simple types or simple +structs which are passed by value and not reference, e.g. nmod_t. + +Random functions +---------------- + +When writing functions which produce random values the order of operands should +follow one of the following: + +if the function returns its random value, the state comes first, e.g: + +a = n_randint(state, n) + +if the function sets its first argument to a random value, the state +comes second, e.g. + +nmod_poly_randtest(poly, state, len, bits) + +Conversion functions +-------------------- + +When naming functions which convert between objects of different modules, use +the convention module1_get_module2 and module1_set_module2, where module1 is +notionally the more complex of the two modules. E.g. fmpz_poly_get_nmod_poly. +The set function should set an object of module1 to the value of an object of +module2, and the get function should do the opposite. + +Code formatting +--------------- + +The C code should follow the style produced by the following call to "indent", + + indent -bap -blf -bli0 -cbi0 -cdw -cli4 -cs -i4 -l79 -nbad -nbc -nce -npcs -nprs -nut -pmt -psl -saf -sai -saw -sbi0 -ss -ts4 + +which is explained as follows: + + -bap Force blank lines after procedure bodies + -blf Put braces on line following function definition line + -bli0 Indent braces 0 spaces + -cbi0 Indent braces after a case label 0 spaces + -cdw Cuddle while of do {} while + -cli4 Case label indent of 4 spaces + -cs Put a space after a cast operator + -i4 Set indentation level to 4 spaces + -l79 Set maximum line length for non-comment lines to 79 + -nbad Do not force blank lines after declarations + -nbc Do not force newlines after commas in declarations + -nce Do not cuddle else + -npcs Do not put a space after the function in function calls + -nprs Do not put a space after every ( and before every ) + -nut Use spaces instead of tabs + -pmt Preserve access and modificaion times on output files + -psl Put the type of a procedure on the line before its name + -saf Put a space before each for + -sai Space after each for + -saw Space after every while + -sbi0 Indent braces of a struct, union or enum 0 spaces + -ss On one-line for and while statements, for a blank before ; + -ts4 Set tab size to 4 spaces + diff --git a/external/flint-2.4.3/config.h b/external/flint-2.4.3/config.h new file mode 100644 index 0000000..b50f38a --- /dev/null +++ b/external/flint-2.4.3/config.h @@ -0,0 +1,8 @@ +/* This file is autogenerated by ./configure -- do not edit! */ +#define POPCNT_INTRINSICS +#define HAVE_BLAS 0 +#define HAVE_TLS 1 +#define HAVE_PTHREAD 1 +#define HAVE_GC 0 +#define FLINT_REENTRANT 0 +#define WANT_ASSERT 0 diff --git a/external/flint-2.4.3/configure b/external/flint-2.4.3/configure new file mode 100755 index 0000000..4f25e1b --- /dev/null +++ b/external/flint-2.4.3/configure @@ -0,0 +1,647 @@ +#!/bin/sh + +# (C) 2007, Robert Bradshaw, William Hart, William Stein, Michael Abshoff +# (C) 2011, William Hart +# (C) 2012, William Hart, Jean-Pierre Flori, Thomas DuBuisson +# (C) 2012, Jan Engelhardt + +PREFIX="/usr/local" +GMP_DIR="/usr/local" +MPFR_DIR="/usr/local" +NTL_DIR="/usr/local" +GC_DIR="/usr/local" +BLAS_DIR="/usr/local" +WANT_NTL=0 +WANT_BLAS=0 +SHARED=1 +STATIC=1 +TLS=1 +PTHREAD=1 +REENTRANT=0 +WANT_GC=0 +WANT_TLS=0 +WANT_CXX=0 +ASSERT=0 +BUILD= +EXTENSIONS= +EXT_MODS= +EXTRA_BUILD= + +FLINT_CPIMPORT_DIR="$PREFIX/share/flint" +FLINT_CPIMPORT="$FLINT_CPIMPORT_DIR/CPimport.txt" + +usage() +{ + echo "Usage: ./configure " + echo " where may be" + echo " -h display usage information" + echo " where may be:" + echo " --prefix= Specify path to installation location (default: /usr/local)" + echo " --with-mpir= Specify location of MPIR (default: /usr/local)" + echo " --with-gmp= Specify location of GMP (default: /usr/local)" + echo " --with-mpfr= Specify location of MPFR (default: /usr/local)" + echo " --with-blas[=] Use BLAS and specify its location (default: /usr/local)" + echo " --without-blas Do not use BLAS (default)" + echo " --with-ntl[=] Build NTL interface and specify its location (default: /usr/local)" + echo " --without-ntl Do not build NTL interface (default)" + echo " --extensions= Specify location of extension modules" + echo " --build=arch-os Specify architecture/OS combination rather than use values from uname -m/-s" + echo " --enable-shared Build a shared library (default)" + echo " --disable-shared Do not build a shared library" + echo " --enable-static Build a static library (default)" + echo " --disable-static Do not build a static library" + echo " --single Faster [non-reentrant if tls or pthread not used] version of library (default)" + echo " --reentrant Build fully reentrant [with or without tls, with pthread] version of library" + echo " --with-gc= GC safe build with path to gc" + echo " --enable-pthread Use pthread (default)" + echo " --disable-pthread Do not use pthread" + echo " --enable-tls Use thread-local storage (default)" + echo " --disable-tls Do not use thread-local storage" + echo " --enable-assert Enable use of asserts (use for debug builds only)" + echo " --disable-assert Disable use of asserts (default)" + echo " --enable-cxx Enable C++ wrapper tests" + echo " --disable-cxx Disable C++ wrapper tests (default)" + echo " CC= Use the C compiler with the given name (default: gcc)" + echo " CXX= Use the C++ compiler with the given name (default: g++)" + echo " AR= Use the AR library builder with the given name (default: ar)" + echo " CFLAGS= Pass the given flags to the compiler" + echo " ABI=[32|64] Tell the compiler to use given ABI (default: empty)" +} + +while [ "$1" != "" ]; do + PARAM=`echo $1 | sed 's/=.*//'` + VALUE=`echo $1 | sed 's/[^=]*//; s/=//'` + case "$PARAM" in + -h|--help) + usage + exit 0 + ;; + --with-mpir|--with-gmp) + GMP_DIR="$VALUE" + ;; + --with-mpfr) + MPFR_DIR="$VALUE" + ;; + --with-ntl) + WANT_NTL=1 + if [ ! -z "$VALUE" ]; then + NTL_DIR="$VALUE" + fi + ;; + --without-ntl) + WANT_NTL=0 + ;; + --with-blas) + WANT_BLAS=1 + if [ ! -z "$VALUE" ]; then + BLAS_DIR="$VALUE" + fi + ;; + --without-blas) + WANT_BLAS=0 + ;; + --extensions) + EXTENSIONS="$VALUE" + ;; + --build) + BUILD="$VALUE" + ;; + --prefix) + PREFIX=$VALUE + FLINT_CPIMPORT_DIR="$PREFIX/share/flint" + FLINT_CPIMPORT="$FLINT_CPIMPORT_DIR/CPimport.txt" + ;; + --enable-shared) + SHARED=1 + ;; + --disable-shared) + SHARED=0 + ;; + --enable-static) + STATIC=1 + ;; + --disable-static) + STATIC=0 + ;; + --single) + REENTRANT=0 + ;; + --reentrant) + REENTRANT=1 + ;; + --with-gc) + WANT_GC=1 + if [ ! -z "$VALUE" ]; then + GC_DIR="$VALUE" + fi + ;; + --enable-pthread) + PTHREAD=1 + ;; + --disable-pthread) + PTHREAD=0 + ;; + --enable-tls) + TLS=1 + WANT_TLS=1;; + --disable-tls) + TLS=0 + ;; + --enable-assert) + ASSERT=1 + ;; + --disable-assert) + ASSERT=0 + ;; + --enable-cxx) + WANT_CXX=1 + ;; + --disable-cxx) + WANT_CXX=0 + ;; + AR) + AR="$VALUE" + ;; + CC) + CC="$VALUE" + ;; + CXX) + CXX="$VALUE" + ;; + CFLAGS) + CFLAGS="$VALUE" + ;; + ABI) + ABI="$VALUE" + ;; + *) + usage + exit 1 + ;; + esac + shift +done + +#find dependencies + +LIBS="m" + +if [ -d "${GMP_DIR}/lib" ]; then + GMP_LIB_DIR="${GMP_DIR}/lib" + GMP_INC_DIR="${GMP_DIR}/include" +elif [ -d "${GMP_DIR}/lib64" ]; then + GMP_LIB_DIR="${GMP_DIR}/lib64" + GMP_INC_DIR="${GMP_DIR}/include" +elif [ -d "${GMP_DIR}/.libs" ]; then + GMP_LIB_DIR="${GMP_DIR}/.libs" + GMP_INC_DIR="${GMP_DIR}" +else + echo "Invalid GMP directory" + exit 1 +fi +LIB_DIRS="${LIB_DIRS} ${GMP_LIB_DIR}" +INC_DIRS="${INC_DIRS} ${GMP_INC_DIR}" +LIBS="${LIBS} gmp" + +if [ -d "${MPFR_DIR}/lib" ]; then + MPFR_LIB_DIR="${MPFR_DIR}/lib" + MPFR_INC_DIR="${MPFR_DIR}/include" +elif [ -d "${MPFR_DIR}/lib64" ]; then + MPFR_LIB_DIR="${MPFR_DIR}/lib64" + MPFR_INC_DIR="${MPFR_DIR}/include" +elif [ -d "${MPFR_DIR}/.libs" ]; then + MPFR_LIB_DIR="${MPFR_DIR}/.libs" + MPFR_INC_DIR="${MPFR_DIR}" +elif [ -d "${MPFR_DIR}/src/.libs" ]; then + MPFR_LIB_DIR="${MPFR_DIR}/src/.libs" + MPFR_INC_DIR="${MPFR_DIR}/src" +else + echo "Invalid MPFR directory" + exit 1 +fi +LIB_DIRS="${LIB_DIRS} ${MPFR_LIB_DIR}" +INC_DIRS="${INC_DIRS} ${MPFR_INC_DIR}" +LIBS="${LIBS} mpfr" + +#configure extra libraries + +if [ "$WANT_NTL" = "1" ]; then + if [ -d "${NTL_DIR}/lib" ]; then + NTL_LIB_DIR="${NTL_DIR}/lib" + NTL_INC_DIR="${NTL_DIR}/include" + elif [ -d "${NTL_DIR}/lib64" ]; then + NTL_LIB_DIR="${NTL_DIR}/lib64" + NTL_INC_DIR="${NTL_DIR}/include" + else + echo "Invalid NTL directory" + exit 1 + fi + EXTRA_INC_DIRS="${EXTRA_INC_DIRS} ${NTL_INC_DIR}" + EXTRA_LIB_DIRS="${EXTRA_LIB_DIRS} ${NTL_LIB_DIR}" + EXTRA_LIBS="${EXTRA_LIBS} ntl" +fi + +if [ "$WANT_BLAS" = "1" ]; then + if [ -d "${BLAS_DIR}" ]; then + BLAS_LIB_DIR="${BLAS_DIR}" + BLAS_INC_DIR="${BLAS_DIR}" + else + echo "Invalid BLAS directory" + exit 1 + fi + EXTRA_INC_DIRS="${EXTRA_INC_DIRS} ${BLAS_INC_DIR}" + EXTRA_LIB_DIRS="${EXTRA_LIB_DIRS} ${BLAS_LIB_DIR}" + EXTRA_LIBS="${EXTRA_LIBS} openblas" +fi +CONFIG_BLAS="#define HAVE_BLAS ${WANT_BLAS}" + +if [ "$WANT_GC" = "1" ]; then + if [ -d "${GC_DIR}" ]; then + GC_LIB_DIR="${GC_DIR}/lib" + GC_INC_DIR="${GC_DIR}/include" + else + echo "Invalid GC directory" + exit 1 + fi + EXTRA_INC_DIRS="${EXTRA_INC_DIRS} ${GC_INC_DIR}" + EXTRA_LIB_DIRS="${EXTRA_LIB_DIRS} ${GC_LIB_DIR}" + EXTRA_LIBS="${EXTRA_LIBS} gc" +fi +CONFIG_GC="#define HAVE_GC ${WANT_GC}" + +# defaults for CC, CXX and AR + +if [ -z "$CC" ]; then + CC=gcc +fi + +if [ -z "$CXX" ]; then + CXX=g++ +fi + +if [ -z "$AR" ]; then + AR=ar +fi + +#handle gc and reentrant flags + +if [ "$WANT_GC" = "1" ]; then + TLS=0 + if [ "$WANT_TLS" = "1" ]; then + echo "****WARNING**** GC does not support TLS....disabling TLS" + fi + cp fmpz/link/fmpz_gc.c fmpz/fmpz.c + cp fmpz-conversions-gc.in fmpz-conversions.h +else + if [ "$REENTRANT" = "1" ]; then + cp fmpz/link/fmpz_reentrant.c fmpz/fmpz.c + cp fmpz-conversions-reentrant.in fmpz-conversions.h + else + cp fmpz/link/fmpz_single.c fmpz/fmpz.c + cp fmpz-conversions-single.in fmpz-conversions.h + fi +fi +# Architecture handler + +KERNEL=`uname` + +if [ -z "$BUILD" ]; then + ARCH=`uname -m` + + if [ "$(uname | cut -d_ -f1)" = "MINGW32" ]; then + if [ "$ABI" = "64" ]; then + OS="MINGW64" + else + OS="MINGW32" + fi + elif [ "$(uname | cut -d_ -f1)" = "CYGWIN" ]; then + if [ "$ARCH" = "x86_64" ]; then + if [ "$ABI" = "32" ]; then + OS="CYGWIN32" + else + OS="CYGWIN64" + ABI="64" + fi + else + OS="CYGWIN32" + fi + else + OS=`uname -s` + fi +else + ARCH=`echo "$BUILD" | cut -d- -f1` + OS=`echo "$BUILD" | cut -d- -f2` +fi + +case "$ARCH" in + x86_64 | amd64) + MACHINE="x86_64";; + x86 | i*86 | pc) + MACHINE="x86";; + ia64) + MACHINE="ia64";; + sparc | sun4*) + MACHINE="sparc";; + sparc64) + MACHINE="sparc64";; + ppc64 | powerpc64) + MACHINE="ppc64";; + ppc | powerpc | [P|p]ower*) + MACHINE="ppc";; + *) + MACHINE="unknown";; +esac + +#ABI flag +if [ "$ABI" = "32" ]; then + ABI_FLAG="-m32" + case "$MACHINE" in + x86_64) + MACHINE="x86";; + sparc64) + MACHINE="sparc";; + ppc64) + MACHINE="ppc";; + *) + ;; + esac +elif [ "$ABI" = "64" ]; then + ABI_FLAG="-m64" + if [ "$MACHINE" = "sparc" ]; then + MACHINE="sparc64" + fi + if [ "$MACHINE" = "x86" ]; then + MACHINE="x86_64" + fi +fi + +if [ "$MACHINE" = "sparc" ] || [ "$MACHINE" = "sparc64" ]; then + if [ "$CC" = "gcc" ]; then + CC="gcc -mno-relax" + fi +fi + +echo "Configuring...${MACHINE}-${OS}" + +#name for FLINT shared library + +if [ -z "$FLINT_LIB" ]; then + case "$OS" in + Darwin) + FLINT_LIB="libflint.dylib" + EXTRA_SHARED_FLAGS="-install_name $PREFIX/lib/$FLINT_LIB";; + CYGWIN* | MINGW*) + FLINT_LIB="libflint.dll";; + *) + FLINT_LIB="libflint.so";; + esac +fi + +#extension for executables + +if [ -z "$EXEEXT" ]; then + case "$OS" in + CYGWIN* | MINGW*) + EXEEXT=".exe";; + *) + EXEEXT="";; + esac +fi + +#don't build both shared and static lib on MinGW and Cygwin + +case "$OS" in + CYGWIN* | MINGW*) + if [ "$STATIC" = "1" ] && [ "$SHARED" = "1" ]; then + echo "Building both static and shared versions of MPIR/GMP on $OS is currently" + echo "unsupported, and so is it for MPFR and FLINT." + echo "You should pass --disable-shared or --disable-static to configure" + echo "depending on the versions of MPIR/GMP and MPFR you built." + exit 1 + fi + ;; + *) + ;; +esac + +#select fft_tuning parameters + +case "$MACHINE" in + x86_64 | ia64 | sparc64 | ppc64) + cp fft_tuning64.in fft_tuning.h;; + *) + cp fft_tuning32.in fft_tuning.h;; +esac + +#test for popcnt flag and set needed CFLAGS + +mkdir -p build +rm -f build/test-popcnt > /dev/null 2>&1 +MSG="Testing __builtin_popcountl..." +printf "%s" "$MSG" +echo "int main(int argc, char ** argv) { +#if defined(_WIN64) +return __builtin_popcountll(argc) == 100; +#else +return __builtin_popcountl(argc) == 100; +#endif +}" > build/test-popcnt.c +$CC build/test-popcnt.c -o ./build/test-popcnt > /dev/null 2>&1 +if [ $? -eq 0 ]; then + printf "%s\n" "yes" + CONFIG_POPCNT_INTRINSICS="#define POPCNT_INTRINSICS" + + if [ "$MACHINE" = "x86_64" ]; then + MSG="Testing native popcount..." + printf "%s" "$MSG" + touch build/test-popcnt.c + rm build/test-popcnt + $CC -mpopcnt build/test-popcnt.c -o ./build/test-popcnt > /dev/null 2>&1 + build/test-popcnt > /dev/null 2>&1 + if [ $? -eq 0 ]; then + printf "%s\n" "yes" + POPCNT_FLAG="-mpopcnt" + else + printf "%s\n" "no" + fi + rm -f build/test-popcnt{,.c} + #in case -mpopcnt is not available, the test program will use an illegal + #instruction and that will print out something on stderr when the if + #construction is exited, whence the following "2> /dev/null" + fi 2> /dev/null +else + rm -f build/test-popcnt.c + printf "%s\n" "no" +fi + +#defaults for CFLAGS + +if [ -z "$CFLAGS" ]; then + if [ "$OS" = "MINGW64" ]; then + CFLAGS="-O2 -funroll-loops -g $POPCNT_FLAG $ABI_FLAG" + elif [ "$OS" = "CYGWIN64" ]; then + CFLAGS="-O2 -funroll-loops -g -D _WIN64 $POPCNT_FLAG $ABI_FLAG" + else + CFLAGS="-ansi -pedantic -Wall -O2 -funroll-loops -g $POPCNT_FLAG $ABI_FLAG" + fi +fi + +#Conway polynomials database + +CFLAGS="$CFLAGS -DFLINT_CPIMPORT=\\\"$FLINT_CPIMPORT\\\"" + +#this is needed on PPC G5 and does not hurt on other OS Xes + +if [ "$KERNEL" = Darwin ]; then + CFLAGS="-fno-common $CFLAGS" +fi + +#PIC flag + +if [ -z "$PIC_FLAG" ]; then + case "$OS" in + CYGWIN* | MINGW*) + ;; + *) + PIC_FLAG="-fPIC";; + esac +fi + +#test support for thread-local storage + +CONFIG_TLS="#define HAVE_TLS 0" + +if [ "$TLS" = "1" ]; then + mkdir -p build + rm -f build/test-tls > /dev/null 2>&1 + MSG="Testing __thread..." + printf "%s" "$MSG" + echo "__thread int x = 42; int main(int argc, char ** argv) { return x != 42; }" > build/test-tls.c + $CC build/test-tls.c -o ./build/test-tls > /dev/null 2>&1 + if [ $? -eq 0 ]; then + build/test-tls > /dev/null 2>&1 + if [ $? -eq 0 ]; then + printf "%s\n" "yes" + CONFIG_TLS="#define HAVE_TLS 1" + else + printf "%s\n" "no" + fi + rm -f build/test-tls{,.c} + else + rm -f build/test-tls.c + printf "%s\n" "no" + #build-tls can segfault on systems where tls is not available + fi 2> /dev/null +fi + +#pthread configuration + +CONFIG_PTHREAD="#define HAVE_PTHREAD ${PTHREAD}" + +if [ "$PTHREAD" = "1" ]; then + LIBS="${LIBS} pthread" +fi + +#pocess external modules + +EXTRA_INC_DIRS="${EXTRA_INC_DIRS} ${EXTENSIONS}" + +#include paths + +INCS="-I\$(CURDIR)" +for INC_DIR in ${INC_DIRS} ${EXTRA_INC_DIRS}; do + INCS="${INCS} -I${INC_DIR}" +done + +#library paths + +LLIBS="-L\$(CURDIR)" +for LIB_DIR in ${LIB_DIRS} ${EXTRA_LIB_DIRS}; do + LLIBS="${LLIBS} -L${LIB_DIR}" +done + +#linker params + +for LIB in ${EXTRA_LIBS} ${LIBS}; do + lLIBS2="-l${LIB} ${lLIBS2}" +done +lLIBS="-lflint $lLIBS2" +LIBS2="$LLIBS $lLIBS2" +LIBS="$LLIBS $lLIBS" + +#paths for dynamic linker + +case "$OS" in + CYGWIN* | MINGW*) + DLPATH="PATH";; + Darwin) + DLPATH="DYLD_LIBRARY_PATH";; + sparc) + DLPATH="LD_LIBRARY_PATH32";; + sparc64) + DLPATH="LD_LIBRARY_PATH64";; + *) + DLPATH="LD_LIBRARY_PATH";; +esac + +DLPATH_ADD="\$(CURDIR)" +for LIB_DIR in ${LIB_DIRS} ${EXTRA_LIB_DIRS}; do + DLPATH_ADD="${DLPATH_ADD}:${LIB_DIR}" +done + +#cxx + +if [ "$WANT_CXX" = "1" ]; then + EXTRA_BUILD="$EXTRA_BUILD flintxx" +fi + +#write out config.h + +echo "/* This file is autogenerated by ./configure -- do not edit! */" > config.h +echo "$CONFIG_POPCNT_INTRINSICS" >> config.h +echo "$CONFIG_BLAS" >> config.h +echo "$CONFIG_TLS" >> config.h +echo "$CONFIG_PTHREAD" >> config.h +echo "$CONFIG_GC" >> config.h +echo "#define FLINT_REENTRANT $REENTRANT" >> config.h +echo "#define WANT_ASSERT $ASSERT" >> config.h + +#write out Makefile + +echo "# This file is autogenerated by ./configure -- do not edit!" > Makefile +echo "" >> Makefile +echo "SHELL=/bin/sh" >> Makefile +echo "" >> Makefile +echo "FLINT_STATIC=$STATIC" >> Makefile +echo "FLINT_SHARED=$SHARED" >> Makefile +echo "FLINT_LIB=$FLINT_LIB" >> Makefile +echo "EXEEXT=$EXEEXT" >> Makefile +echo "PREFIX=$PREFIX" >> Makefile +echo "" >> Makefile +echo "WANT_NTL=$WANT_NTL" >> Makefile +echo "" >> Makefile +echo "FLINT_CPIMPORT_DIR=$FLINT_CPIMPORT_DIR" >> Makefile +echo "FLINT_CPIMPORT=$FLINT_CPIMPORT" >> Makefile +echo "" >> Makefile +echo "INCS=$INCS" >> Makefile +echo "LIBS=$LIBS" >> Makefile +echo "LIBS2=$LIBS2" >> Makefile +echo "" >> Makefile +echo "CC=$CC" >> Makefile +echo "CXX=$CXX" >> Makefile +echo "AR=$AR" >> Makefile +echo "" >> Makefile +echo "CFLAGS=$CFLAGS" >> Makefile +echo "ABI_FLAG=$ABI_FLAG" >> Makefile +echo "PIC_FLAG=$PIC_FLAG" >> Makefile +echo "EXTRA_SHARED_FLAGS=$EXTRA_SHARED_FLAGS" >> Makefile +echo "" >> Makefile +echo "DLPATH=$DLPATH" >> Makefile +echo "DLPATH_ADD=$DLPATH_ADD" >> Makefile +echo "EXTENSIONS=$EXTENSIONS" >> Makefile +echo "EXTRA_BUILD_DIRS=$EXTRA_BUILD" >> Makefile +echo "" >> Makefile + +cat Makefile.in >> Makefile + +echo "FLINT was successfully configured." diff --git a/external/flint-2.4.3/doc/longlong.txt b/external/flint-2.4.3/doc/longlong.txt new file mode 100644 index 0000000..50e3d11 --- /dev/null +++ b/external/flint-2.4.3/doc/longlong.txt @@ -0,0 +1,140 @@ +/*============================================================================= + + longlong.h -- 64 bit arithetic + + This file is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + This file 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 Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this file; see the file COPYING.LIB. If not, write + to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 1991, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001, + 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2009 William Hart + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +******************************************************************************* + + Auxiliary asm macros + +******************************************************************************* + +umul_ppmm(high_prod, low_prod, multipler, multiplicand) + + Multiplies two single limb integers \code{MULTIPLER} and + \code{MULTIPLICAND}, and generates a two limb product in + \code{HIGH_PROD} and \code{LOW_PROD}. + +smul_ppmm(high_prod, low_prod, multipler, multiplicand) + + As for \code{umul_ppmm()} but the numbers are signed. + +udiv_qrnnd(quotient, remainder, high_numerator, low_numerator, denominator) + + Divides an unsigned integer, composed by the limb integers + \code{HIGH_NUMERATOR} and\\ \code{LOW_NUMERATOR}, by \code{DENOMINATOR} + and places the quotient in \code{QUOTIENT} and the remainder in + \code{REMAINDER}. \code{HIGH_NUMERATOR} must be less than + \code{DENOMINATOR} for correct operation. + +sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator, denominator) + + As for \code{udiv_qrnnd()} but the numbers are signed. The quotient is + rounded towards $0$. Note that as the quotient is signed it must lie in + the range $[-2^63, 2^63)$. + +count_leading_zeros(count, x) + + Counts the number of zero-bits from the msb to the first non-zero bit + in the limb \code{x}. This is the number of steps \code{x} needs to + be shifted left to set the msb. If \code{x} is $0$ then count is + undefined. + +count_trailing_zeros(count, x) + + As for \code{count_leading_zeros()}, but counts from the least + significant end. If \code{x} is zero then count is undefined. + +add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1, + high_addend_2, low_addend_2) + + Adds two limb integers, composed by \code{HIGH_ADDEND_1} and + \code{LOW_ADDEND_1}, and\\ \code{HIGH_ADDEND_2} and \code{LOW_ADDEND_2}, + respectively. The result is placed in \code{HIGH_SUM} and + \code{LOW_SUM}. Overflow, i.e.\ carry out, is not stored anywhere, + and is lost. + +add_sssaaaaaa(high_sum, mid_sum, low_sum, high_addend_1, mid_addend_1, + low_addend_1, high_addend_2, mid_addend_2, low_addend_2) + + Adds two three limb integers. Carry out is lost. + +sub_ddmmss(high_difference, low_difference, high_minuend, low_minuend, + high_subtrahend, low_subtrahend) + + Subtracts two limb integers, composed by \code{HIGH_MINUEND_1} and + \code{LOW_MINUEND_1}, and \code{HIGH_SUBTRAHEND_2} and + \code{LOW_SUBTRAHEND_2}, respectively. The result is placed in\\ + \code{HIGH_DIFFERENCE} and \code{LOW_DIFFERENCE}. Overflow, i.e.\ + carry out is not stored anywhere, and is lost. + +invert_limb(invxl, xl) + + Computes an approximate inverse \code{invxl} of the limb \code{xl}, + with an implicit leading~$1$. More formally it computes + \begin{lstlisting}[language=c] + invxl = (B^2 - B*x - 1)/x = (B^2 - 1)/x - B + \end{lstlisting} + + Note that $x$ must be normalised, i.e.\ with msb set. This inverse + makes use of the following theorem of Torbjorn Granlund and Peter + Montgomery~\citep[Lemma~8.1]{GraMon1994}: + + Let $d$ be normalised, $d < B$, i.e.\ it fits in a word, and suppose + that $m d < B^2 \leq (m+1) d$. Let $0 \leq n \leq B d - 1$. Write + $n = n_2 B + n_1 B/2 + n_0$ with $n_1 = 0$ or $1$ and $n_0 < B/2$. + Suppose $q_1 B + q_0 = n_2 B + (n_2 + n_1) (m - B) + n_1 (d-B/2) + n_0$ + and $0 \leq q_0 < B$. Then $0 \leq q_1 < B$ and $0 \leq n - q_1 d < 2 d$. + + In the theorem, $m$ is the inverse of $d$. If we let + \code{m = invxl + B} and $d = x$ we have $m d = B^2 - 1 < B^2$ and + $(m+1) x = B^2 + d - 1 \geq B^2$. + + The theorem is often applied as follows: note that $n_0$ and $n_1 (d-B/2)$ + are both less than $B/2$. Also note that $n_1 (m-B) < B$. Thus the sum of + all these terms contributes at most $1$ to $q_1$. We are left with + $n_2 B + n_2 (m-B)$. But note that $(m-B)$ is precisely our precomputed + inverse \code{invxl}. If we write $q_1 B + q_0 = n_2 B + n_2 (m-B)$, + then from the theorem, we have $0 \leq n - q_1 d < 3 d$, i.e.\ the + quotient is out by at most $2$ and is always either correct or too small. + +udiv_qrnnd_preinv(q, r, nh, nl, d, di) + + As for \code{udiv_qrnnd()} but takes a precomputed inverse \code{di} as + computed by \code{invert_limb()}. The algorithm, in terms of the theorem + above, is: + + \begin{lstlisting}[language=c] + nadj = n1*(d-B/2) + n0 + xh, xl = (n2+n1)*(m-B) + xh, xl += nadj + n2*B ( xh, xl = n2*B + (n2+n1)*(m-B) + n1*(d-B/2) + n0 ) + _q1 = B - xh - 1 + xh, xl = _q1*d + nh, nl - B*d = nh, nl - q1*d - d so that xh = 0 or -1 + r = xl + xh*d where xh is 0 if q1 is off by 1, otherwise -1 + q = xh - _q1 = xh + 1 + n2 + \end{lstlisting} + diff --git a/external/flint-2.4.3/doc/profiler.txt b/external/flint-2.4.3/doc/profiler.txt new file mode 100644 index 0000000..095e808 --- /dev/null +++ b/external/flint-2.4.3/doc/profiler.txt @@ -0,0 +1,167 @@ +******************************************************************************* + + Timer based on the cycle counter + +******************************************************************************* + +void timeit_start(timeit_t t) +void timeit_stop(timeit_t t) + + Gives wall and user time - useful for parallel programming. + + Example usage: + \begin{lstlisting}[language=c] + timeit_t t0; + + // ... + + timeit_start(t0); + + // do stuff, take some time + + timeit_stop(t0); + + flint_printf("cpu = %wd ms wall = %wd ms\n", t0->cpu, t0->wall); + \end{lstlisting} + +void start_clock(int n) +void stop_clock(int n) +double get_clock(int n) + + Gives time based on cycle counter. + + First one must ensure the processor speed in cycles per second + is set correctly in \code{profiler.h}, in the macro definition + \code{#define FLINT_CLOCKSPEED}. + + One can access the cycle counter directly by \code{get_cycle_counter()} + which returns the current cycle counter as a \code{double}. + + A sample usage of clocks is: + \begin{lstlisting}[language=c] + init_all_clocks(); + + start_clock(n); + + // do something + + stop_clock(n); + + flint_printf("Time in seconds is %f.3\n", get_clock(n)); + \end{lstlisting} + where \code{n} is a clock number (from 0-19 by default). The number of + clocks can be changed by altering \code{FLINT_NUM_CLOCKS}. One can also + initialise an individual clock with \code{init_clock(n)}. + +******************************************************************************* + + Framework for repeatedly sampling a single target + +******************************************************************************* + +void prof_repeat(double *min, double *max, profile_target_t target, + ulong count) + + Allows one to automatically time a given function. Here is a sample usage: + + Suppose one has a function one wishes to profile: + \begin{lstlisting}[language=c] + void myfunc(ulong a, ulong b); + \end{lstlisting} + One creates a struct for passing arguments to our function: + \begin{lstlisting}[language=c] + typedef struct + { + ulong a, b; + } myfunc_t; + \end{lstlisting} + a sample function: + \begin{lstlisting}[language=c] + void sample_myfunc(void * arg, ulong count) + { + myfunc_t * params = (myfunc_t *) arg; + + ulong a = params->a; + ulong b = params->b; + + for (ulong i = 0; i < count; i++) + { + prof_start(); + myfunc(a, b); + prof_stop(); + } + } + \end{lstlisting} + Then we do the profile + \begin{lstlisting}[language=c] + double min, max; + + myfunc_t params; + + params.a = 3; + params.b = 4; + + prof_repeat(&min, &max, sample_myfunc, ¶ms); + + flint_printf("Min time is %lf.3s, max time is %lf.3s\n", min, max); + \end{lstlisting} + + If either of the first two parameters to \code{prof_repeat} are + \code{NULL}, that value is not stored. + + One may set the minimum time in microseconds for a timing run by + adjusting\\ \code{DURATION_THRESHOLD} and one may set a target duration + in microseconds by adjusting \code{DURATION_TARGET} in \code{profiler.h}. + +******************************************************************************* + + Memory usage + +******************************************************************************* + +void get_memory_usage(meminfo_t meminfo) + + Obtains information about the memory usage of the current process. + The meminfo object contains the slots \code{size} (virtual memory size), + \code{peak} (peak virtual memory size), \code{rss} (resident set size), + \code{hwm} (peak resident set size). The values are stored in kilobytes + (1024 bytes). This function currently only works on Linux. + +******************************************************************************* + + Simple profiling macros + +******************************************************************************* + +macro TIMEIT_REPEAT(timer, reps) +macro TIMEIT_END_REPEAT(timer, reps) + + Repeatedly runs the code between the \code{TIMEIT_REPEAT} and the + \code{TIMEIT_END_REPEAT} markers, automatically increasing the number of + repetitions until the elapsed time exceeds the timer resolution. + The macro takes as input a predefined \code{timeit_t} object + and an integer variable to hold the number of repetitions. + +macro TIMEIT_START +macro TIMEIT_STOP + + Repeatedly runs the code between the \code{TIMEIT_START} and the + \code{TIMEIT_STOP} + markers, automatically increasing the number of repetitions until the + elapsed time exceeds the timer resolution, and then prints the average + elapsed cpu and wall time for a single repetition. + +macro TIMEIT_ONCE_START +macro TIMEIT_ONCE_STOP + + Runs the code between the \code{TIMEIT_ONCE_START} and the + \code{TIMEIT_ONCE_STOP} + markers exactly once and then prints the elapsed cpu and wall time. + This does not give a precise measurement if the elapsed time is short + compared to the timer resolution. + +macro SHOW_MEMORY_USAGE + + Retrieves memory usage information via \code{get_memory_usage} + and prints the results. + diff --git a/external/flint-2.4.3/double_extras.h b/external/flint-2.4.3/double_extras.h new file mode 100644 index 0000000..87af8b6 --- /dev/null +++ b/external/flint-2.4.3/double_extras.h @@ -0,0 +1,68 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 DOUBLE_EXTRAS_H +#define DOUBLE_EXTRAS_H + +#undef ulong +#define ulong ulongxx /* interferes with system includes */ +#include +#undef ulong +#include +#include +#include "flint.h" + +#define ulong mp_limb_t + +#ifdef __cplusplus + extern "C" { +#endif + +#define D_BITS 53 +#define D_EPS 2.2204460492503130808e-16 +#define D_INF HUGE_VAL +#define D_NAN (HUGE_VAL - HUGE_VAL) + +double d_randtest(flint_rand_t state); + +static __inline__ double +d_polyval(const double * poly, int len, double x) +{ + double t; + int i; + + for (t = poly[len-1], i = len-2; i >= 0; i--) + t = poly[i] + x * t; + + return t; +} + +double d_lambertw(double x); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/flint-2.4.3/double_extras/doc/double_extras.txt b/external/flint-2.4.3/double_extras/doc/double_extras.txt new file mode 100644 index 0000000..1b3be89 --- /dev/null +++ b/external/flint-2.4.3/double_extras/doc/double_extras.txt @@ -0,0 +1,71 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Fredrik Johansson + +******************************************************************************/ + +******************************************************************************* + + Random functions + +******************************************************************************* + +double d_randtest(flint_rand_t state) + + Returns a random number in the interval $[0.5, 1)$. + + +******************************************************************************* + + Arithmetic + +******************************************************************************* + +double d_polyval(const double * poly, int len, double x) + + Uses Horner's rule to evaluate the the polynomial defined by the given + \code{len} coefficients. Requires that \code{len} is nonzero. + + +******************************************************************************* + + Special functions + +******************************************************************************* + +double d_lambertw(double x) + + Computes the principal branch of the Lambert W function, solving + the equation $x = W(x) \exp(W(x))$. If $x < -1/e$, the solution is + complex, and NaN is returned. + + Depending on the magnitude of $x$, we start from a piecewise rational + approximation or a zeroth-order truncation of the asymptotic expansion + at infinity, and perform 0, 1 or 2 iterations with Halley's + method to obtain full accuracy. + + A test of $10^7$ random inputs showed a maximum relative error smaller + than 0.95 times \code{DBL_EPSILON} ($2^{-52}$) for positive $x$. + Accuracy for negative $x$ is slightly worse, and can grow to + about 10 times \code{DBL_EPSILON} close to $-1/e$. + However, accuracy may be worse depending on compiler flags and + the accuracy of the system libm functions. diff --git a/external/flint-2.4.3/double_extras/lambertw.c b/external/flint-2.4.3/double_extras/lambertw.c new file mode 100644 index 0000000..03481f0 --- /dev/null +++ b/external/flint-2.4.3/double_extras/lambertw.c @@ -0,0 +1,168 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 "double_extras.h" + +#define POLY(p, x) d_polyval((p), sizeof(p) / sizeof(double), (x)) + +static const double pol1[4] = { + 0.2278634396856248853716, 0.6685854654191353381433, + 0.4670475452404395343887, 0.061184972065242761167 }; + +static const double pol2[5] = { + 0.2278636537503804204913, 0.8964421845409468074626, + 1.0217927151592500702475, 0.34513102625055769873401, + 0.020801230123523916719604 }; + +static const double pol3[6] = { + 0.00005767860320327097931, 0.029896654795890461899563, + 0.0378739044968912982585405, 0.00971957088414193124615358, + 0.000488576886695502361566636, 1.150549466178344373015667e-6 }; + +static const double pol4[5] = { + 0.030306172539339585635388, 0.066596680780796068408204, + 0.035483738872057375987452, 0.00506436278851840340711316, + 0.0001465263028844943142786722 }; + +static const double pol5[6] = { + 0.00048233868073637531461, 0.004268700087824343609188, + 0.00127714949974214706149789, 0.0000799706171559085390983949, + 1.186347211803672341928371e-6, 2.943454067276155504308283e-9 }; + +static const double pol6[6] = { + 0.00553288881087242781512, 0.0043904877060733941697614, + 0.00069354549834088964895342, 0.0000288257440032545960408328, + 3.01054066921000066105342e-7, 4.94316029290773314755549e-10 }; + +static const double pol7[4] = { + -0.93011683587619427070, -2.9702322028603227386, + -2.0759083419960793148, -0.042485660005713612806 }; + +static const double pol8[4] = { + 0.93011683587619458392, 4.3654074566738568022, + 6.1437079650412473506, 2.4613195056093927345 }; + +static const double pol9[11] = { + -1.0000000000000000000, 2.3316439815971242034, + -1.8121878856393634902, 1.9366311144923597554, + -2.3535512018816145168, 3.0668589010506319129, + -4.1753356002581771389, 5.8580237298747741488, + -8.4010322175239773710, 12.250753501314460424, + -18.100697012472442755 }; + +static const double pol10[6] = { + -5.1972986075163593071, -37.478686466672907613, + -96.155193004929291698, -102.23856988136744607, + -37.181958033133170210, -0.48504976999675644134 }; + +static const double pol11[6] = { + 5.1972986074950082685, 45.274634378414741754, 150.20768172029114131, + 233.88699813222871981, 167.13313463159765859, 42.171248374042409414 }; + + +/* avoid overflows in the formula when x is close to 2^EMAX */ +#define RESCALE 1.1102230246251565404e-16 + +static double +halley(double x, double w) +{ + double t, u, v; + + /* exp() does not overflow, since w is an underestimate + when the asymptotic series is used */ + t = exp(w) * RESCALE; + u = 2*w + 2; + v = w*t - x * RESCALE; + t = w - u*v / (u*t*(w+1) - (w+2)*v); + + return t; +} + +/* this should be exactly 6627126856707895 * 2^(-54) ~= + 0.36787944117144228, which + is the most negative double in the domain */ +#define ONE_OVER_E ldexp(6627126856707895.0, -54) + +/* difference from -1/e */ +#define CORRECTION 4.3082397558469466e-17 + +double +d_lambertw(double x) +{ + double t, u, w; + + if (x == 0.0 || x != x || x == D_INF) + return x; + + if (x < 0.0) + { + /* complex result */ + if (x < -ONE_OVER_E) + return D_NAN; + /* close to zero */ + else if (x > -1e-9) + return x - x * x; + /* close to the singularity at -1/e */ + else if (x + ONE_OVER_E < 0.0003) + return POLY(pol9, sqrt((x + ONE_OVER_E) + CORRECTION)); + + /* otherwise get initial value for Halley iteration */ + if (x + ONE_OVER_E < 0.04) + w = POLY(pol9, sqrt((x + ONE_OVER_E) + CORRECTION)); + else + w = x * (1.0 + x * POLY(pol10, x) / POLY(pol11, x)); + } + else + { + /* close to zero */ + if (x <= 0.03125) + { + if (x < 1e-9) + return x - x * x; + else + return x * (1.0 + x * POLY(pol7, x) / POLY(pol8, x)); + } + + /* get initial value for Halley iteration */ + if (x <= 1.0) + w = x * POLY(pol1, x) / POLY(pol2, x); + else if (x <= 6.0) + w = POLY(pol3, x) / POLY(pol4, x); + else if (x <= 40.0) + w = POLY(pol5, x) / POLY(pol6, x); + else + { + /* asymptotic series */ + t = log(x); + u = log(t); + w = (2*t*t*t - 2*(1+(t-1)*t)*u + u*u)/(2*t*t); + /* one extra refinement */ + if (x < 1e15) + w = halley(x, w); + } + } + + return halley(x, w); +} diff --git a/external/flint-2.4.3/double_extras/randtest.c b/external/flint-2.4.3/double_extras/randtest.c new file mode 100644 index 0000000..9fc25c6 --- /dev/null +++ b/external/flint-2.4.3/double_extras/randtest.c @@ -0,0 +1,54 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 "double_extras.h" +#include "ulong_extras.h" + +#define EXP_MINUS_32 2.3283064365386962891e-10 +#define EXP_MINUS_64 5.42101086242752217e-20 + +double +d_randtest(flint_rand_t state) +{ + mp_limb_t m1, m2; + double t; + + if (FLINT_BITS == 64) + { + m1 = n_randlimb(state) | (UWORD(1) << (FLINT_BITS - 1)); + + t = ((double) m1) * EXP_MINUS_64; + } + else + { + m1 = n_randlimb(state) | (UWORD(1) << (FLINT_BITS - 1)); + m2 = n_randlimb(state); + + t = ((double) m1) * EXP_MINUS_32 + + ((double) m2) * EXP_MINUS_64; + } + + return t; +} diff --git a/external/flint-2.4.3/double_extras/test/t-lambertw.c b/external/flint-2.4.3/double_extras/test/t-lambertw.c new file mode 100644 index 0000000..b13d42d --- /dev/null +++ b/external/flint-2.4.3/double_extras/test/t-lambertw.c @@ -0,0 +1,160 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 +#include +#include +#include +#include "ulong_extras.h" +#include "double_extras.h" + +#define ONE_OVER_E ldexp(6627126856707895.0, -54) + +int +main() +{ + double x, w, tol; + slong iter, prec = 70; + mpfr_t xx, ww, wnew, t, u, v, p, q, max_err; + + FLINT_TEST_INIT(state); + + flint_printf("lambertw...."); + fflush(stdout); + + + + mpfr_init2(xx, prec); + mpfr_init2(ww, prec); + mpfr_init2(wnew, prec); + mpfr_init2(t, prec); + mpfr_init2(u, prec); + mpfr_init2(v, prec); + mpfr_init2(p, prec); + mpfr_init2(q, prec); + mpfr_init2(max_err, prec); + mpfr_set_ui(max_err, 0, MPFR_RNDN); + + for (iter = 0; iter < 10000 * flint_test_multiplier(); iter++) + { + x = d_randtest(state); + + switch (n_randint(state, 3)) + { + /* singularity near -1/e */ + case 0: + x = ldexp(x, -n_randint(state, -DBL_MIN_EXP+1)); + x = -ONE_OVER_E + x; + tol = 50 * DBL_EPSILON; + break; + /* negative, not close to -1/e */ + case 1: + x = d_randtest(state); + x = ldexp(x, -n_randint(state, -DBL_MIN_EXP+1)); + x = x * -(1./4); + tol = 2 * DBL_EPSILON; + break; + /* positive */ + default: + x = d_randtest(state); + x = ldexp(x, (int) n_randint(state, DBL_MAX_EXP-DBL_MIN_EXP-1) + + DBL_MIN_EXP); + tol = 2 * DBL_EPSILON; + break; + } + + w = d_lambertw(x); + + mpfr_set_d(xx, x, MPFR_RNDN); + mpfr_set_d(ww, w, MPFR_RNDN); + + /* t = exp(w) */ + mpfr_exp(t, ww, MPFR_RNDN); + + /* u = 2*w + 2 */ + mpfr_mul_ui(u, ww, 2, MPFR_RNDN); + mpfr_add_ui(u, u, 2, MPFR_RNDN); + + /* v = w*t - x */ + mpfr_mul(v, t, ww, MPFR_RNDN); + mpfr_sub(v, v, xx, MPFR_RNDN); + + /* p = u * v */ + mpfr_mul(p, u, v, MPFR_RNDN); + + /* q = (u*t*(w+1) - (w+2)*v) */ + mpfr_mul(q, u, t, MPFR_RNDN); + mpfr_add_ui(t, ww, 1, MPFR_RNDN); + mpfr_mul(q, q, t, MPFR_RNDN); + + mpfr_add_ui(t, ww, 2, MPFR_RNDN); + mpfr_mul(t, t, v, MPFR_RNDN); + mpfr_sub(q, q, t, MPFR_RNDN); + + /* wnew = w - p / q */ + mpfr_div(p, p, q, MPFR_RNDN); + mpfr_sub(wnew, ww, p, MPFR_RNDN); + + /* relative error */ + mpfr_sub(t, ww, wnew, MPFR_RNDA); + mpfr_div(t, t, wnew, MPFR_RNDA); + mpfr_abs(t, t, MPFR_RNDA); + + if (mpfr_get_d(t, MPFR_RNDA) > tol) + { + flint_printf("FAIL\n"); + flint_printf("x = %.17g, w = %.17g, error = %g\n", x, w, + mpfr_get_d(t, MPFR_RNDA)); + abort(); + } + +#if 0 + if (mpfr_cmp(t, max_err) > 0) + { + flint_printf("new record: "); + flint_printf("x=%.20g w=%.20g wnew=%.20g relative error: %g\n", + x, w, mpfr_get_d(wnew, MPFR_RNDN), mpfr_get_d(t, MPFR_RNDN)); + mpfr_set(max_err, t, MPFR_RNDN); + } +#endif + + } + + mpfr_clear(xx); + mpfr_clear(ww); + mpfr_clear(wnew); + mpfr_clear(t); + mpfr_clear(u); + mpfr_clear(v); + mpfr_clear(p); + mpfr_clear(q); + mpfr_clear(max_err); + + mpfr_free_cache(); + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/examples/crt.c b/external/flint-2.4.3/examples/crt.c new file mode 100644 index 0000000..cfde25e --- /dev/null +++ b/external/flint-2.4.3/examples/crt.c @@ -0,0 +1,78 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +/* + Demo FLINT program for incremental multimodular reduction and + reconstruction using the Chinese Remainder Theorem. +*/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "ulong_extras.h" + +int main(int argc, char* argv[]) +{ + slong i, bit_bound; + mp_limb_t prime, res; + fmpz_t x, y, prod; + + if (argc != 2) + { + flint_printf("Syntax: crt \n"); + return EXIT_FAILURE; + } + + fmpz_init(x); + fmpz_init(y); + fmpz_init(prod); + + fmpz_set_str(x, argv[1], 10); + bit_bound = fmpz_bits(x) + 2; + + fmpz_zero(y); + fmpz_one(prod); + + prime = 0; + for (i = 0; fmpz_bits(prod) < bit_bound; i++) + { + prime = n_nextprime(prime, 0); + res = fmpz_fdiv_ui(x, prime); + fmpz_CRT_ui(y, y, prod, res, prime, 1); + + flint_printf("residue mod %wu = %wu; reconstruction = ", prime, res); + fmpz_print(y); + flint_printf("\n"); + + fmpz_mul_ui(prod, prod, prime); + } + + fmpz_clear(x); + fmpz_clear(y); + fmpz_clear(prod); + + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/examples/crt.cpp b/external/flint-2.4.3/examples/crt.cpp new file mode 100644 index 0000000..cc03560 --- /dev/null +++ b/external/flint-2.4.3/examples/crt.cpp @@ -0,0 +1,68 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2013 Tom Bachmann (C++ adaptation) + +******************************************************************************/ + +/* + Demo FLINT program for incremental multimodular reduction and + reconstruction using the Chinese Remainder Theorem. +*/ + +#include +#include "fmpzxx.h" +#include "ulong_extras.h" + +using namespace flint; + +int main(int argc, char* argv[]) +{ + if (argc != 2) + { + flint_printf("Syntax: crt \n"); + return EXIT_FAILURE; + } + + fmpzxx x(argv[1]); + slong bit_bound = bits(x) + 2; + + fmpzxx y(0); + fmpzxx prod(1); + + mp_limb_t prime = 0; + for (unsigned i = 0; bits(prod) < bit_bound; i++) + { + prime = n_nextprime(prime, 0); + + ulong res = (x % prime).to(); + y = y.CRT(prod, res, prime, true); + + std::cout << "residue mod " << prime << " = " << res; + std::cout << "; reconstruction = " << y << '\n'; + + prod *= prime; + } + + return 0; +} + diff --git a/external/flint-2.4.3/examples/delta_qexp.c b/external/flint-2.4.3/examples/delta_qexp.c new file mode 100644 index 0000000..7b4e41c --- /dev/null +++ b/external/flint-2.4.3/examples/delta_qexp.c @@ -0,0 +1,69 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Harvey, William Hart + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +/* + Demo FLINT program for computing the q-expansion of the delta function. +*/ + +#include +#include +#include + +#include "flint.h" +#include "fmpz.h" +#include "arith.h" + +int main(int argc, char* argv[]) +{ + fmpz_t c, n; + slong N = 0; + + if (argc == 2) + N = atol(argv[1]); + + if (argc != 2 || N < 1) + { + flint_printf("Syntax: delta_qexp \n"); + flint_printf("where is the (positive) number of terms to compute\n"); + return EXIT_FAILURE; + } + + fmpz_init(c); + fmpz_init(n); + + fmpz_set_si(n, N); + arith_ramanujan_tau(c, n); + + flint_printf("Coefficient of q^%wd is ", N); + fmpz_print(c); + flint_printf("\n"); + + fmpz_clear(c); + fmpz_clear(n); + + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/examples/delta_qexp.cpp b/external/flint-2.4.3/examples/delta_qexp.cpp new file mode 100644 index 0000000..8d76d65 --- /dev/null +++ b/external/flint-2.4.3/examples/delta_qexp.cpp @@ -0,0 +1,59 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Harvey, William Hart + Copyright (C) 2010 Sebastian Pancratz + Copyright (C) 2013 Tom Bachmann (C++ adaptation) + +******************************************************************************/ + +/* + Demo FLINT program for computing the q-expansion of the delta function. +*/ + +#include +#include +#include "fmpzxx.h" +#include "arithxx.h" + +using namespace flint; +using namespace std; + +int main(int argc, char* argv[]) +{ + slong N = 0; + + if (argc == 2) + N = atol(argv[1]); + + if (argc != 2 || N < 1) + { + flint_printf("Syntax: delta_qexp \n"); + flint_printf("where is the (positive) number of terms to compute\n"); + return 1; + } + + std::cout << "Coefficient of q^" << N << " is " + << ramanujan_tau(fmpzxx(N)) << '\n'; + + return 0; +} + diff --git a/external/flint-2.4.3/examples/fmpq_poly.c b/external/flint-2.4.3/examples/fmpq_poly.c new file mode 100644 index 0000000..28d9256 --- /dev/null +++ b/external/flint-2.4.3/examples/fmpq_poly.c @@ -0,0 +1,57 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +/* + Simple example demonstrating the use of the fmpq_poly module. + */ + +#include +#include + +#include "fmpq_poly.h" + +int main(int argc, char* argv[]) +{ + char *str, *strf, *strg; + fmpq_poly_t f, g; + + fmpq_poly_init(f); + fmpq_poly_init(g); + fmpq_poly_set_str(f, "2 1/2 3/5"); + fmpq_poly_set_str(g, "4 1/3 2 3/2 -1/2"); + strf = fmpq_poly_get_str_pretty(f, "t"); + strg = fmpq_poly_get_str_pretty(g, "t"); + fmpq_poly_mul(f, f, g); + str = fmpq_poly_get_str_pretty(f, "t"); + flint_printf("(%s) * (%s) = %s\n", strf, strg, str); + flint_free(str); + flint_free(strf); + flint_free(strg); + fmpq_poly_clear(f); + fmpq_poly_clear(g); + + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/examples/fmpq_poly.cpp b/external/flint-2.4.3/examples/fmpq_poly.cpp new file mode 100644 index 0000000..b33707d --- /dev/null +++ b/external/flint-2.4.3/examples/fmpq_poly.cpp @@ -0,0 +1,45 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Tom Bachmann (C++ adaptation) + +******************************************************************************/ + +/* + Simple example demonstrating the use of the fmpq_polyxx module. + */ + +#include "fmpq_polyxx.h" +#include + +using namespace flint; + +int main(int argc, char* argv[]) +{ + fmpq_polyxx f("2 1/2 3/5"); + fmpq_polyxx g("4 1/3 2 3/2 -1/2"); + + std::cout << '(' << f.pretty("t") << ") * (" << g.pretty("t") + << " = " << (f*g).pretty("t") << '\n'; + + return 0; +} diff --git a/external/flint-2.4.3/examples/fmpz_mod_poly.c b/external/flint-2.4.3/examples/fmpz_mod_poly.c new file mode 100644 index 0000000..e4b642a --- /dev/null +++ b/external/flint-2.4.3/examples/fmpz_mod_poly.c @@ -0,0 +1,56 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +/* + Example program for the fmpz_mod_poly module. +*/ + +#include +#include +#include + +#include "flint.h" +#include "fmpz_mod_poly.h" + +int main(int argc, char* argv[]) +{ + fmpz_t n; + fmpz_mod_poly_t x, y; + + fmpz_init_set_ui(n, 7); + fmpz_mod_poly_init(x, n); + fmpz_mod_poly_init(y, n); + fmpz_mod_poly_set_coeff_ui(x, 3, 5); + fmpz_mod_poly_set_coeff_ui(x, 0, 6); + fmpz_mod_poly_sqr(y, x); + fmpz_mod_poly_print(x); flint_printf("\n"); + fmpz_mod_poly_print(y); flint_printf("\n"); + fmpz_mod_poly_clear(x); + fmpz_mod_poly_clear(y); + fmpz_clear(n); + + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/examples/fmpz_mod_poly.cpp b/external/flint-2.4.3/examples/fmpz_mod_poly.cpp new file mode 100644 index 0000000..ae93086 --- /dev/null +++ b/external/flint-2.4.3/examples/fmpz_mod_poly.cpp @@ -0,0 +1,49 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2013 Tom Bachmann (C++ adaptation) + +******************************************************************************/ + +/* + Example program for the fmpz_mod_poly module. +*/ + +#include +#include + +using namespace std; +using namespace flint; + +int main(int argc, char* argv[]) +{ + fmpzxx n(7); + fmpz_mod_polyxx x(n); + x.set_coeff(3, 5); + x.set_coeff(0, 6); + + print(x);flint_printf("\n"); + print(x.sqr());flint_printf("\n"); + + return 0; +} + diff --git a/external/flint-2.4.3/examples/fmpz_poly_factor_zassenhaus.c b/external/flint-2.4.3/examples/fmpz_poly_factor_zassenhaus.c new file mode 100644 index 0000000..d14b0c3 --- /dev/null +++ b/external/flint-2.4.3/examples/fmpz_poly_factor_zassenhaus.c @@ -0,0 +1,73 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Andy Novocin + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +/* + Example program demonstrating the Zassenhaus factoring algorithm. +*/ + +#include + +#include "flint.h" +#include "fmpz_poly.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int main(void) +{ + fmpz_poly_t f; + fmpz_poly_factor_t facs; + + fmpz_poly_init(f); + fmpz_poly_factor_init(facs); + + if (0) + { + FILE *polyfile; + polyfile = fopen("examples/fmpz_poly_hensel_P1", "r"); + + if (!polyfile) + { + flint_printf("Error. Could not read P1 from file.\n"); + abort(); + } + fmpz_poly_fread(polyfile, f); + } + + fmpz_poly_set_str(f, "63 1 1 1 -4 -7 -2 -6 -3 -7 18 7 25 -11 95 36 21 16 69 56 35 36 32 33 26 -26 -15 -14 -53 -96 67 72 -67 40 -79 -116 -452 -312 -260 -29 -1393 327 69 -28 -241 230 -54 -309 -125 -74 -450 -69 -3 66 -27 73 68 50 -63 -1290 372 31 -16 2"); + + fmpz_poly_factor_zassenhaus(facs, f); + + flint_printf("Polynomial:\n"); + fmpz_poly_print(f); + flint_printf("\nFactorisation:\n"); + fmpz_poly_factor_print(facs); + + fmpz_poly_clear(f); + fmpz_poly_factor_clear(facs); + + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/examples/fmpz_poly_factor_zassenhaus.cpp b/external/flint-2.4.3/examples/fmpz_poly_factor_zassenhaus.cpp new file mode 100644 index 0000000..ff8ebd5 --- /dev/null +++ b/external/flint-2.4.3/examples/fmpz_poly_factor_zassenhaus.cpp @@ -0,0 +1,63 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Andy Novocin + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +/* + Example program demonstrating the Zassenhaus factoring algorithm. +*/ + +#include +#include "fmpz_polyxx.h" + +using namespace flint; +using namespace std; + +int main() +{ + fmpz_polyxx f; + + if (0) + { + // NB: this does not seem to work in the C version + + FILE *polyfile; + polyfile = fopen("examples/fmpz_poly_hensel_P1", "r"); + + if (!polyfile) + { + flint_printf("Error. Could not read P1 from file.\n"); + abort(); + } + read(polyfile, f); + } + else + f = "63 1 1 1 -4 -7 -2 -6 -3 -7 18 7 25 -11 95 36 21 16 69 56 35 36 32 33 26 -26 -15 -14 -53 -96 67 72 -67 40 -79 -116 -452 -312 -260 -29 -1393 327 69 -28 -241 230 -54 -309 -125 -74 -450 -69 -3 66 -27 73 68 50 -63 -1290 372 31 -16 2"; + + flint_printf("Polynomial:\n");print(f); + flint_printf("\nFactorisation:\n");print(factor_zassenhaus(f)); + + return 0; +} + diff --git a/external/flint-2.4.3/examples/fmpz_poly_hensel_P1 b/external/flint-2.4.3/examples/fmpz_poly_hensel_P1 new file mode 100644 index 0000000..aa0dcfe --- /dev/null +++ b/external/flint-2.4.3/examples/fmpz_poly_hensel_P1 @@ -0,0 +1 @@ +157 2757808487144838302895430769948248417729237108863869417509479459915767341323330697211864790593685466362642868685686280572196434680273380283012145961103760692626213505149801403142032630867205290294889677921852958863296316098679545758264555461523658710938789459422476508285713011640130252486568573874403279248369585169539213650618995126951019719642265868631105857663880266888615740687129117228288314207488263153874611799588864 0 0 0 0 0 -216322796837555313021432683645937044292921028613383407157804069297831574640998740656489092120685008467028608331849579265535298919026656996120638521170849310580349430742714282458612690837924997423939358531519250439003103809474194653867052412730011984853274391208927747745495001768576577005852099658803085546514828589578330785402902514368037827033046816681733696103002335485194130317912396254882191766550071245537280 0 0 0 0 0 -461037645433479417894020721333520318742787637796222824861773705209889273869538158383427629416696554307900636877857163108477972707536277062193762789904663727290361284224373517600871057249998734207159849953758589691456457289461969382313561313225919667846650484354465287838669574263259013740628682955721862333944942797610117714349319340424888849377188433375019685712170554798874566289464703683278915239936 0 0 0 0 0 -3006606488311441089896683017688393310181237526393515483185168180454254753097973363635722407434487318654611062408549655477030250215182281891825672566995224009864674440632939039163270907351880438387976862382953630127475285232095605983810246580601204355061953631934206101782233808526261885763004588113518320634896519093555011110157604966440212309535525594054654293518320014613131809110622208 0 0 0 0 0 -21667646451621122746329554641562526144092633323312599411016990419323105385099476066414168972485002571354506235276444763858199439264635997569307854261698326829531703857487029929169587379456251270438809123403197975344780862412222180332148184540879408846734261457232407592147312924337495632438881306066500258566449544033936294138097409605834038606201765458164323353573757812736 0 0 0 0 0 -36008946342647299345277533676465042992542509358162091707911485884063199188678585181307031154064029716715217548592392000646414311357113983560970141370451913098200635822787067067854257570327208938999696955706264073506673179971102683350614122127866850451153062491787093182867397127538003924258331826086311209206145468869911581822662684689775342390081444166762496 0 0 0 0 0 64738333885402706154009400777843384948514403975131509466836736265603889387062685884838924226241494383359395885853573043385536386037715829201209541872597706855188799653603478660006394706968635342978467902539925660331269747297563569373972862258677268612185384308671129076702627081272278586910256050615727493523124564910427355844022903201664598016 0 0 0 0 0 -26515019326962174180142979909852192000598024025005741295940640978614198820508372895246811842900425977352727727321855043342564236181262669572054649107156675328942799346600624572167621155490882477365676272092450671794375283335841074839674104033802419109510303627230113525211458922561813524476132216574712854465367040031027145736192 0 0 0 0 0 7206103572192660713378206441635342218917489717304647992423853713271386261468915707872924405011212678144586363155710573280556474140830016874081726445858124315662916567493737199217110913142452405975457031642733926038866594546019867393529529573884911052196182095293632879922014565430281245217054716156649445034819584 0 0 0 0 0 -1781067445792627012203411699914789751917558964317719007317246424900608235475797721781459407143458070618250900401160717537304193257391576912113861254338589725654811524225989470856639467420913364918958248936121424237401680876071173527822994467656057208698530802400487646077493116544189557449970155520 0 0 0 0 0 257785868023252499546719038629025522238370895088838886132974669167861057091364847664488796999614147085642953811171182098166013025545859882309438475565596820726130902460185426222014793570631782686609398943162320798462220946658785090792728810983258963716578939056822038673472371032064 0 0 0 0 0 -11784090207202014162295386617819122580975749672866993427537075993392758066192465164322165415699997447946113816444451865902475946080059998736123233932142195687596120620775313704725043713670267057116323795251403918781211539279372041111665200731953898028103168618921984 0 0 0 0 0 -516024270178733628499623062311311909026630748206142586718438261050317424310047984113834321775600080026192071968298564681207899012445940514128285818475704941072871032892579017242172498256146144732370397366971600828731748910067376163611390633039626240 0 0 0 0 0 30082639005203703587384390914836066417375929216836277495255127429645641088564854026651642629932602536304239256338883055950342516352052967456427931536708936701164689433642079716822865825451517411212445927909524063734481575283370491904 0 0 0 0 0 -473470234117762253449114353073575227253051133950080887048220406201777923641087656057923908627860421347898111116275922195546977433176120962969045561381814949718893972897291028710748149921273892963880265171252944044032 0 0 0 0 0 1716231160060069630599685050354626175015068955757203109707649882577572773165548338611188714799775273882912731234014004123562719620912869622981185312386637525543829470533595866145631607760885722906624 0 0 0 0 0 29097610765037817861202663659325678575900946766272112229562997159720733072202069362200879071525561150306287386997432893787696445551277644983772558101666007653602762940659581050683392 0 0 0 0 0 -359926316046483943753279829287876608460021803187136100943332906260813526077725113393005907399350257834664287535635450778981949557310768189387775714926393025942781952 0 0 0 0 0 1585164055408008634764541421847990628448201383564778254157208549989039915612818011950714697494640213070044956331618331201033480861222528629063286784 0 0 0 0 0 -2786147914453983786915822775172002754752542153742435684470657396691295332282129004399822009077517014397168296974400680697863864320 0 0 0 0 0 -38152084257499719867416104314045082135545017120806331924723488759543432766463641099223031913762482060169052160 0 0 0 0 0 6156765507729276548165940166182211314235431893392787456381452344509549569751736679901247307776 0 0 0 0 0 -6689833869884920066141475743520535508680559052015304499397212203049103130624 0 0 0 0 0 2000741892753026115892243757690184900091769801141945106432 0 0 0 0 0 -50111580155260460844584241578962989056 0 0 0 0 0 -28293184124737694080 0 0 0 0 0 1 diff --git a/external/flint-2.4.3/examples/fmpz_poly_q.c b/external/flint-2.4.3/examples/fmpz_poly_q.c new file mode 100644 index 0000000..68c3a9e --- /dev/null +++ b/external/flint-2.4.3/examples/fmpz_poly_q.c @@ -0,0 +1,61 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +/* + Simple example demonstrating the use of the fmpz_poly_q module. + */ + +#include +#include +#include + +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpz_poly_q.h" + +int main(int argc, char* argv[]) +{ + char *str, *strf, *strg; + fmpz_poly_q_t f, g; + + fmpz_poly_q_init(f); + fmpz_poly_q_init(g); + fmpz_poly_q_set_str(f, "2 1 3/1 2"); + fmpz_poly_q_set_str(g, "1 3/2 2 7"); + strf = fmpz_poly_q_get_str_pretty(f, "t"); + strg = fmpz_poly_q_get_str_pretty(g, "t"); + fmpz_poly_q_mul(f, f, g); + str = fmpz_poly_q_get_str_pretty(f, "t"); + flint_printf("%s * %s = %s\n", strf, strg, str); + flint_free(str); + flint_free(strf); + flint_free(strg); + fmpz_poly_q_clear(f); + fmpz_poly_q_clear(g); + + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/examples/fmpz_poly_q.cpp b/external/flint-2.4.3/examples/fmpz_poly_q.cpp new file mode 100644 index 0000000..99c8315 --- /dev/null +++ b/external/flint-2.4.3/examples/fmpz_poly_q.cpp @@ -0,0 +1,44 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2013 Tom Bachmann (C++ adaptation) + +******************************************************************************/ + +/* + Simple example demonstrating the use of the fmpz_poly_q module. + */ + +#include +#include "fmpz_poly_qxx.h" + +using namespace flint; +using namespace std; + +int main(int argc, char* argv[]) +{ + fmpz_poly_qxx f("2 1 3/1 2"), g("1 3/2 2 7"); + std::cout << f.pretty("t") << " * " << g.pretty("t") + << " = " << (f*g).pretty("t") << '\n'; + return 0; +} + diff --git a/external/flint-2.4.3/examples/fooxx.cpp b/external/flint-2.4.3/examples/fooxx.cpp new file mode 100644 index 0000000..041aade --- /dev/null +++ b/external/flint-2.4.3/examples/fooxx.cpp @@ -0,0 +1,365 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +/* + Demo FLINTXX header to illustrate flintxx extension. +*/ + +/////////////////////////////////////////////////////////////////////////////// +// FAKE C DATA TYPE +// (This would normally reside in foo.h.) +/////////////////////////////////////////////////////////////////////////////// + +#ifndef FOO_H +#define FOO_H +#include + +extern "C" { // usually only #ifdef __cplusplus etc +typedef slong foo; +typedef slong foo_t[1]; + +static __inline__ void foo_init(foo_t f) +{ + *f = 0l; +} + +static __inline__ void foo_clear(foo_t f) +{ +} + +static __inline__ void foo_set(foo_t to, const foo_t from) +{ + *to = *from; +} + +static __inline__ void foo_set_si(foo_t f, slong e) +{ + *f = e; +} + +static __inline__ void foo_add(foo_t to, const foo_t e1, const foo_t e2) +{ + *to = *e1 + *e2; +} + +static __inline__ void foo_add_si(foo_t to, const foo_t e1, slong e2) +{ + *to = *e1 + e2; +} + +static __inline__ int foo_cmp(const foo_t e1, const foo_t e2) +{ + if(*e1 == *e2) + return 0; + return *e1 > *e2 ? 1 : -1; +} + +static __inline__ int foo_is_zero(const foo_t f) +{ + return *f == 0; +} + +static __inline__ void foo_magic(foo_t to, const foo_t from) +{ + *to = 2 * (*from) + 1; +} +} + +#endif + +/////////////////////////////////////////////////////////////////////////////// +// C++ wrapper +// (This would normally reside in fooxx.h.) +/////////////////////////////////////////////////////////////////////////////// + +#ifndef FOOXX_H +#define FOOXX_H + +#include + +#include "flintxx/expression.h" +#include "flintxx/flint_classes.h" + +namespace flint { +// fooxx_expression is an "all-purpose" expression template class. In +// principle, both Operation and Data can be arbitrary types (Data has to be +// copy constructible), but in this generality the objects will be not much +// use. In practice, Operation is an empty type, which is just used as a "tag", +// and Data is a rather primitive type holding essentially just some payload. +// Even more practically speaking, the only instantiations the FLINT developer +// should have have to make explicitly are when Operation is +// operations::immediate. +// The flintxx library will create other instantiations automatically, with +// more complicated Data arguments, and different Operation-s. +template +class fooxx_expression + +// In order for the flintxx library to do its work, your class must derive from +// flint::expression. If your class has just two template parameters Operation +// and Data, then the following line is sufficient. + : public expression, Operation, Data> +{ +public: + + // This line is formulaic, and just makes the base class available. + // The typedef is used by the FLINTXX_DEFINE_* macros below, and is + // necessary because of namespace injection bugs in gcc<4.5. + typedef expression, + Operation, Data> base_t; + + // The next two lines are formulaic, and most likely required in any + // concrete class. + FLINTXX_DEFINE_BASICS(fooxx_expression) + FLINTXX_DEFINE_CTORS(fooxx_expression) + + // This line enables reference types for your class. The second argument is + // the underlying C type (note this is foo, not foo_t). The third argument + // is the name under which to make the underlying C type available. + // All of fooxx, fooxx_ref and fooxx_srcref will have methods _foo() which + // can be used to manipulate the underlying C data type. + FLINTXX_DEFINE_C_REF(fooxx_expression, foo, _foo) + + // Now custom methods can be added. The typical pattern is to call a C + // function with argument this->evaluate()._foo(). The evaluate() method is + // inherited from the expression class (this is why it needs to be + // qualified by "this"). It obtains a reference to self if self is an + // immediate object, and otherwise evaluates self into a temporary + // immediate object. + // If you leave out the evaluate() step, then the method will only work + // on immediates (which may be desirable). + bool is_zero() const {return foo_is_zero(this->evaluate()._foo());} +}; + +// This is formulaic. The class fooxx will be an instantiation of +// fooxx_expression, with Operation operations::immediate and Data +// detail::foo_data. We need to forward-declare this because of cyclic +// dependencies among the immediate types (e.g. fooxx_srcref can be +// constructed from fooxx, and vice versa). +namespace detail { +struct foo_data; +} + +// This line just carries out the plan of definition of fooxx explained above. +typedef fooxx_expression fooxx; + +// If you want reference types (i.e. if you had FLINTXX_DEFINE_C_REF above), +// these lines are again formulaic. +typedef fooxx_expression > fooxx_ref; +typedef fooxx_expression > fooxx_srcref; + +namespace detail { + +// We now define the actual immediate Data type. This is not just foo_t (the +// underlying C data type), because want it to behave nicely "in a C++ world". +struct foo_data +{ + // In general, your data type can contain members and member types in any + // way you want. However, to work with the automatic reference type system, + // the following three lines are necessary. + foo_t inner; + typedef foo_t& data_ref_t; + typedef const foo_t& data_srcref_t; + + // Default constructor. If this is not provided, fooxx will not be default + // constructible (this is OK but requires some additional care, see e.g. + // padicxx). + foo_data() {foo_init(inner);} + + // Destructor. You most likely want this. + ~foo_data() {foo_clear(inner);} + + // Copy constructor. You must provide this. + foo_data(const foo_data& o) + { + foo_init(inner); + foo_set(inner, o.inner); + } + + // Instantiation from srcref. This is basically the same as the copy, + // constructor, but unfortunately has to be repeated. This also takes care + // of instantiation from ref, since ref->srcref is an implicit conversion + // path. + foo_data(fooxx_srcref r) + { + foo_init(inner); + foo_set(inner, r._foo()); + } + + // Now you can add more constructors, or in fact any methods you like. + // This one allows constructing fooxx directly from long, int, + // unsigned short etc. + template + foo_data(T t, + typename mp::enable_if >::type* = 0) + { + foo_init(inner); + foo_set_si(inner, t); + } +}; +} // detail + +// By now our data type is instantiable, but nothing can be done with it. +// The flintxx library would be able to create expression templates involving +// fooxx, but will not do so because it has no way of evaluating them. We +// need to provides evaluation (and other) *rules* to the library. These +// (have to) live in namespace flint::rules. +// +// All possible rules are defined in flintxx/rules.h. + +namespace rules { + +// These two lines are convenient, are not formulaic except that they are used +// in all code below. +#define FOOXX_COND_S FLINTXX_COND_S(fooxx) +#define FOOXX_COND_T FLINTXX_COND_T(fooxx) + +// Define a conditional assignment rule. The general pattern is +// +// FLINT_DEFINE_DOIT_COND2(name, cond1, cond2, eval). +// +// This will define a "doit" rule for "name", which takes one input and +// one output argument. The result looks something like +// +// template +// struct assignment and cond2 are satisfied> +// { +// static void doit(T& to, const U& from) +// eval; +// }; +// +// In our case, we are defining an assignment rule, i.e. an explanation on +// how to execute operator=. If the right hand side is an expression template, +// flintxx will automatically evaluate it first. Thus we need only treat the +// case where the LHS is fmpzxx or fmpzxx_ref, and the RHS is fmpzxx, fmpzxx_ref +// or fmpzxx_srcref. This is precisely what the conditions FOOXX_COND_T +// and FOOXX_COND_S (conditions "fooxx target" and "fooxx source") mean. +FLINT_DEFINE_DOIT_COND2(assignment, FOOXX_COND_T, FOOXX_COND_S, + foo_set(to._foo(), from._foo())) + +// This line defines assignment of integral PODs to fooxx. Since the underlying +// C library only defines fooxx_set_si, we can only safely allow this if the +// right hand side can always be losslessly converted into a signed long, +// so we use the condition traits::fits_into_slong. Traits are defined all +// throughout flintxx, but the most general purpose ones (like fits_into_slong, +// is_unsigned_integer etc) can be found in flintxx/traits.h +FLINT_DEFINE_DOIT_COND2(assignment, FOOXX_COND_T, traits::fits_into_slong, + foo_set_si(to._foo(), from, 1)) + +// We now define evaluation rules. In full generality, the rule evaluation<...> +// can be used to define how to evaluate any kind of expression. But this is +// difficult to use. Moreover, much evaluation logic is shared among most +// data types. For example, to evaluate an expression like a + b + c, +// one typically first has to evaluate (say) a + b into a temporary t, and then +// evaluate t + c. The only step that is specific to fooxx here is how to +// add two immediates. +// For this reason, flintxx has special convenience forms of the evaluation +// rule, called binary and unary expressions. Defining a binary expression +// f(x, y) tells flintxx how to evaluate operation "f" on types "x" and "y", +// typically immediates. Then flintxx will figure out how to evaluate the +// arguments into temporaries first etc. +// There is a common special case, when f(x, y) is always the same as f(y, x), +// even though x and y may be of different types. Letting flintxx know of this +// avoids defining the rule both ways round. +// +// Here we define a commutative binary expression rule, for operation "plus", +// to be executed on to objects of types T and U, both satisfying FOOXX_COND_S. +// The result is to be of type foooxx (the second argument). +// In this case the types are fully symmetric, so we could have used +// FLINT_DEFINE_BINARY_EXPR_COND2 without adverse effects. +// +// The eval statement should have the effect of to = e1 + e2. +FLINT_DEFINE_CBINARY_EXPR_COND2(plus, fooxx, FOOXX_COND_S, FOOXX_COND_S, + foo_add(to._foo(), e1._foo(), e2._foo())) + +// Addation of fooxx and PODs. This time CBINARY instead of BINARY is vital. +FLINT_DEFINE_CBINARY_EXPR_COND2(plus, fooxx, FOOXX_COND_S, + traits::fits_into_slong, + foo_add_si(to._foo(), e1._foo(), e2)) + +// Next we define relational operators. A convenient way of doing so is using +// a "cmp" function, which is handily provided by the underlying C library. +// This has a somewhat peculiar signature, so cannot be defined using one of +// the standard macros. However, it comes up with many actual FLINT data types, +// so we have a special FLINTXX macro just for defining cmp. +FLINTXX_DEFINE_CMP(fooxx, foo_cmp(e1._foo(), e2._foo())) + +// Now we define a rule how to print fooxx. There is no macro for this, because +// normally instead we define conversion to string, and flintxx takes care of +// printing. However, the C library for fooxx provides neither printing nor +// conversion to string, so we have to do our own implementation. +template +struct print >::type> +{ + static void doit(const T& i, std::ostream& o) + { + o << *i._foo(); + } +}; +} // rules + +// By now fooxx is a pretty passable wrapper type. In fact the only thing left +// to do is to expose foo_magic. This is a special function which can be +// executed on instances of foo, and yields another instance of foo. It is +// essentially just another unary expression, just with an unusual name, so +// this is how we treat it. + +// This line introduces a new type of unary operation, called "magic_op", +// together with a function flint::magic(T), which creates expression templates +// with this new operation. In principle, any expression template data type is +// now allowed to define rules how to performa magic on itself. +FLINT_DEFINE_UNOP(magic) + +// Finally, we need to explain how to perform magic on flintxx. This is again +// a rule. +namespace rules { + +// The pattern should be familiar by now. +FLINT_DEFINE_UNARY_EXPR_COND(magic_op, fooxx, FOOXX_COND_S, + foo_magic(to._foo(), from._foo())) +} // rules +} // flint + +#endif + +/////////////////////////////////////////////////////////////////////////////// +// Example program +/////////////////////////////////////////////////////////////////////////////// + +using namespace flint; + +int +main() +{ + fooxx a, b(4); + fooxx_ref ar(a); + fooxx_srcref br(b); + + ar = 1 + br + 1; // a=6 + std::cout << magic(a + (-1)) << '\n'; // 2*(6-1)+1 = 11 + + return 0; +} diff --git a/external/flint-2.4.3/examples/fq_poly.c b/external/flint-2.4.3/examples/fq_poly.c new file mode 100644 index 0000000..f438483 --- /dev/null +++ b/external/flint-2.4.3/examples/fq_poly.c @@ -0,0 +1,160 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +/* + Demo FLINT program to demonstrate some use of the fq_poly module. +*/ + +#include + +#include "fq_poly.h" + +int main(void) +{ + fmpz_t p; + long d, i; + fq_ctx_t ctx; + clock_t c0, c1; + double c; + fq_poly_t f, g, h; + + FLINT_TEST_INIT(state); + + fq_poly_init(f, ctx); + fq_poly_init(g, ctx); + fq_poly_init(h, ctx); + + printf("Polynomial multiplication over GF(q)\n"); + printf("------------------------------------\n"); + + { + printf("1) Two length-10,000 polynomials over GF(3^2)\n"); + + fmpz_init_set_ui(p, 3); + d = 2; + fq_ctx_init_conway(ctx, p, d, "X"); + + fq_poly_randtest(g, state, 10000, ctx); + fq_poly_randtest(h, state, 10000, ctx); + + c0 = clock(); + fq_poly_mul_classical(f, g, h, ctx); + c1 = clock(); + c = (double) (c1 - c0) / CLOCKS_PER_SEC; + printf("Classical: %fs\n", c); + + c0 = clock(); + for (i = 0; i < 100; i++) + fq_poly_mul_reorder(f, g, h, ctx); + c1 = clock(); + c = (double) (c1 - c0) / CLOCKS_PER_SEC; + printf("Reorder: %fms\n", 10 * c); + + c0 = clock(); + for (i = 0; i < 100; i++) + fq_poly_mul_KS(f, g, h, ctx); + c1 = clock(); + c = (double) (c1 - c0) / CLOCKS_PER_SEC; + printf("KS: %fms\n", 10 * c); + + fq_ctx_clear(ctx); + fmpz_clear(p); + } + { + printf("2) Two length-500 polynomials over GF(3^263)\n"); + + fmpz_init_set_ui(p, 3); + d = 263; + fq_ctx_init_conway(ctx, p, d, "X"); + + fq_poly_randtest(g, state, 500, ctx); + fq_poly_randtest(h, state, 500, ctx); + + c0 = clock(); + fq_poly_mul_classical(f, g, h, ctx); + c1 = clock(); + c = (double) (c1 - c0) / CLOCKS_PER_SEC; + printf("Classical: %fs\n", c); + + c0 = clock(); + fq_poly_mul_reorder(f, g, h, ctx); + c1 = clock(); + c = (double) (c1 - c0) / CLOCKS_PER_SEC; + printf("Reorder: %fs\n", c); + + c0 = clock(); + for (i = 0; i < 100; i++) + fq_poly_mul_KS(f, g, h, ctx); + c1 = clock(); + c = (double) (c1 - c0) / CLOCKS_PER_SEC; + printf("KS: %fms\n", 10 * c); + + fq_ctx_clear(ctx); + fmpz_clear(p); + } + { + printf("3) Two length-5 polynomials over GF(109987^4)\n"); + + fmpz_init_set_ui(p, 109987); + d = 4; + fq_ctx_init_conway(ctx, p, d, "X"); + + fq_poly_randtest(g, state, 4, ctx); + fq_poly_randtest(h, state, 4, ctx); + + c0 = clock(); + for (i = 0; i < 1000 * 100; i++) + fq_poly_mul_classical(f, g, h, ctx); + c1 = clock(); + c = (double) (c1 - c0) / CLOCKS_PER_SEC; + printf("Classical: %f\xb5s\n", 10 * c); + + c0 = clock(); + for (i = 0; i < 1000 * 100; i++) + fq_poly_mul_reorder(f, g, h, ctx); + c1 = clock(); + c = (double) (c1 - c0) / CLOCKS_PER_SEC; + printf("Reorder: %f\xb5s\n", 10 * c); + + c0 = clock(); + for (i = 0; i < 1000 * 100; i++) + fq_poly_mul_KS(f, g, h, ctx); + c1 = clock(); + c = (double) (c1 - c0) / CLOCKS_PER_SEC; + printf("KS: %f\xb5s\n", 10 * c); + + fq_ctx_clear(ctx); + fmpz_clear(p); + } + + fq_poly_clear(f, ctx); + fq_poly_clear(g, ctx); + fq_poly_clear(h, ctx); + FLINT_TEST_CLEANUP(state); + + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/examples/multi_crt.c b/external/flint-2.4.3/examples/multi_crt.c new file mode 100644 index 0000000..3c5d8b0 --- /dev/null +++ b/external/flint-2.4.3/examples/multi_crt.c @@ -0,0 +1,103 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +/* + Demo FLINT program for balanced multimodular reduction and + reconstruction using the Chinese Remainder Theorem. +*/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "ulong_extras.h" + +int main(int argc, char* argv[]) +{ + slong i; + fmpz_t x, y; + + /* Data needed by multi CRT functions */ + fmpz_comb_t comb; + fmpz_comb_temp_t comb_temp; + + mp_limb_t * primes; + mp_limb_t * residues; + + slong num_primes; + + if (argc != 3) + { + flint_printf("Syntax: crt \n"); + return EXIT_FAILURE; + } + + num_primes = atoi(argv[2]); + + if (num_primes < 1) + { + flint_printf("Requires num_primes >= 1\n"); + return EXIT_FAILURE; + } + + fmpz_init(x); + fmpz_init(y); + + fmpz_set_str(x, argv[1], 10); + + primes = flint_malloc(num_primes * sizeof(mp_limb_t)); + residues = flint_malloc(num_primes * sizeof(mp_limb_t)); + + primes[0] = 2; + for (i = 1; i < num_primes; i++) + primes[i] = n_nextprime(primes[i-1], 0); + + fmpz_comb_init(comb, primes, num_primes); + fmpz_comb_temp_init(comb_temp, comb); + + /* Reduce modulo all primes */ + fmpz_multi_mod_ui(residues, x, comb, comb_temp); + + /* Reconstruct */ + fmpz_multi_CRT_ui(y, residues, comb, comb_temp, 1); + + for (i = 0; i < num_primes; i++) + flint_printf("residue mod %wu = %wu\n", primes[i], residues[i]); + + flint_printf("reconstruction = "); + fmpz_print(y); + flint_printf("\n"); + + fmpz_clear(x); + fmpz_clear(y); + + fmpz_comb_temp_clear(comb_temp); + fmpz_comb_clear(comb); + + flint_free(residues); + flint_free(primes); + + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/examples/multi_crt.cpp b/external/flint-2.4.3/examples/multi_crt.cpp new file mode 100644 index 0000000..07e3396 --- /dev/null +++ b/external/flint-2.4.3/examples/multi_crt.cpp @@ -0,0 +1,73 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2013 Tom Bachmann (C++ adaptation) + +******************************************************************************/ + +/* + Demo FLINT program for balanced multimodular reduction and + reconstruction using the Chinese Remainder Theorem. +*/ + +#include +#include +#include "fmpzxx.h" +#include "ulong_extras.h" + +using namespace flint; + +int main(int argc, char* argv[]) +{ + if (argc != 3) + { + std::cerr << "Syntax: crt \n"; + return 1; + } + + slong num_primes = atoi(argv[2]); + + if (num_primes < 1) + { + std::cerr << "Requires num_primes >= 1\n"; + return 2; + } + + fmpzxx x(argv[1]); + + std::vector primes(num_primes), residues(num_primes); + primes[0] = 2; + for (unsigned i = 1; i < num_primes; i++) + primes[i] = n_nextprime(primes[i-1], 0); + + fmpz_combxx comb(primes); + multi_mod(residues, x, comb); + + for (unsigned i = 0; i < num_primes; i++) + std::cout << "residue mod " << primes[i] + << " = " << residues[i] << '\n'; + + std::cout << "reconstruction = " << multi_CRT(residues, comb, true) + << '\n'; + + return 0; +} diff --git a/external/flint-2.4.3/examples/padic.c b/external/flint-2.4.3/examples/padic.c new file mode 100644 index 0000000..5e18b12 --- /dev/null +++ b/external/flint-2.4.3/examples/padic.c @@ -0,0 +1,164 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +/* + Demo FLINT program to demonstrate some use of the padic module. +*/ + +#include +#include +#include + +#include "flint.h" +#include "padic.h" + +int main(void) +{ + fmpz_t p; + padic_ctx_t ctx; + + char *str; + padic_t x, y; + + flint_printf("Output:\n\n"); + + /* Case 1 */ + flint_printf("Positive integer: x = 127 mod 7^10\n"); + + fmpz_init(p); + fmpz_set_ui(p, 7); + padic_ctx_init(ctx, p, 8, 12, PADIC_TERSE); + + padic_init2(x, 10); + padic_set_ui(x, 127, ctx); + + ctx->mode = PADIC_TERSE; + str = padic_get_str(NULL, x, ctx); + flint_printf("print: "), padic_print(x, ctx), flint_printf("\n"); + flint_printf("get_str: %s\n", str); + flint_free(str); + + ctx->mode = PADIC_SERIES; + str = padic_get_str(NULL, x, ctx); + flint_printf("print: "), padic_print(x, ctx), flint_printf("\n"); + flint_printf("get_str: %s\n", str); + flint_free(str); + + ctx->mode = PADIC_VAL_UNIT; + str = padic_get_str(NULL, x, ctx); + flint_printf("print: "), padic_print(x, ctx), flint_printf("\n"); + flint_printf("get_str: %s\n", str); + flint_free(str); + + padic_clear(x); + + padic_ctx_clear(ctx); + fmpz_clear(p); + + /* Case 2 */ + flint_printf("Positive integer larger than p^N: x = 1057 mod 2^10\n"); + + fmpz_init(p); + fmpz_set_ui(p, 2); + padic_ctx_init(ctx, p, 10, 12, PADIC_TERSE); + + padic_init2(x, 10); + padic_set_ui(x, 1057, ctx); + + ctx->mode = PADIC_TERSE; + str = padic_get_str(NULL, x, ctx); + flint_printf("print: "), padic_print(x, ctx), flint_printf("\n"); + flint_printf("get_str: %s\n", str); + flint_free(str); + + ctx->mode = PADIC_SERIES; + str = padic_get_str(NULL, x, ctx); + flint_printf("print: "), padic_print(x, ctx), flint_printf("\n"); + flint_printf("get_str: %s\n", str); + flint_free(str); + + ctx->mode = PADIC_VAL_UNIT; + str = padic_get_str(NULL, x, ctx); + flint_printf("print: "), padic_print(x, ctx), flint_printf("\n"); + flint_printf("get_str: %s\n", str); + flint_free(str); + + padic_clear(x); + + padic_ctx_clear(ctx); + fmpz_clear(p); + + /* Case 3 */ + flint_printf("Negative integer: x = -127 mod 3^10\n"); + + fmpz_init(p); + fmpz_set_ui(p, 3); + padic_ctx_init(ctx, p, 10, 12, PADIC_TERSE); + + padic_init2(x, 10); + padic_set_si(x, -127, ctx); + + ctx->mode = PADIC_TERSE; + str = padic_get_str(NULL, x, ctx); + flint_printf("print: "), padic_print(x, ctx), flint_printf("\n"); + flint_printf("get_str: %s\n", str); + flint_free(str); + + ctx->mode = PADIC_VAL_UNIT; + str = padic_get_str(NULL, x, ctx); + flint_printf("print: "), padic_print(x, ctx), flint_printf("\n"); + flint_printf("get_str: %s\n", str); + flint_free(str); + + padic_clear(x); + + padic_ctx_clear(ctx); + fmpz_clear(p); + + /* Log */ + flint_printf("Log of 7380996 mod 5^20\n"); + + fmpz_init(p); + fmpz_set_ui(p, 5); + padic_ctx_init(ctx, p, 10, 25, PADIC_SERIES); + + padic_init(x); + padic_init(y); + padic_set_ui(x, 7380996, ctx); + + padic_log(y, x, ctx); + + flint_printf("x = "), padic_print(x, ctx), flint_printf("\n"); + flint_printf("y = "), padic_print(y, ctx), flint_printf("\n"); + + padic_clear(x); + padic_clear(y); + + padic_ctx_clear(ctx); + fmpz_clear(p); + + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/examples/padic.cpp b/external/flint-2.4.3/examples/padic.cpp new file mode 100644 index 0000000..5eaa78c --- /dev/null +++ b/external/flint-2.4.3/examples/padic.cpp @@ -0,0 +1,116 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2013 Tom Bachmann (C++ adaptation) + +******************************************************************************/ + +/* + Demo FLINT program to demonstrate some use of the padic module. +*/ + +#include +#include "padicxx.h" + +using namespace flint; +using namespace std; + +int main() +{ + std::cout << "Output:\n\n"; + + // Case 1 + { + std::cout << "Positive integer: x = 127 mod 7^10\n"; + fmpzxx p(7); + padicxx_ctx ctx(p, 8, 12, PADIC_TERSE); + padicxx x = padicxx::from_QQ(127, ctx, 10); + + ctx.mode() = PADIC_TERSE; + std::cout << "print: ";print(x);std::cout << '\n'; + std::cout << "get_str: " << x.to_string() << '\n'; + + ctx.mode() = PADIC_SERIES; + std::cout << "print: ";print(x);std::cout << '\n'; + std::cout << "get_str: " << x.to_string() << '\n'; + + ctx.mode() = PADIC_VAL_UNIT; + std::cout << "print: ";print(x);std::cout << '\n'; + std::cout << "get_str: " << x.to_string() << '\n'; + } + + // Case 2 + { + std::cout << "Positive integer larger than p^N: x = 1057 mod 2^10\n"; + fmpzxx p(2); + padicxx_ctx ctx(p, 10, 12, PADIC_TERSE); + padicxx x = padicxx::from_QQ(1057, ctx, 10); + + ctx.mode() = PADIC_TERSE; + std::cout << "print: ";print(x);std::cout << '\n'; + std::cout << "get_str: " << x.to_string() << '\n'; + + ctx.mode() = PADIC_SERIES; + std::cout << "print: ";print(x);std::cout << '\n'; + std::cout << "get_str: " << x.to_string() << '\n'; + + ctx.mode() = PADIC_VAL_UNIT; + std::cout << "print: ";print(x);std::cout << '\n'; + std::cout << "get_str: " << x.to_string() << '\n'; + } + + // Case 3 + { + std::cout << "Negative integer: x = -127 mod 3^10\n"; + fmpzxx p(3); + padicxx_ctx ctx(p, 10, 12, PADIC_TERSE); + padicxx x = padicxx::from_QQ(-127, ctx, 10); + + ctx.mode() = PADIC_TERSE; + std::cout << "print: ";print(x);std::cout << '\n'; + std::cout << "get_str: " << x.to_string() << '\n'; + + ctx.mode() = PADIC_SERIES; + std::cout << "print: ";print(x);std::cout << '\n'; + std::cout << "get_str: " << x.to_string() << '\n'; + + ctx.mode() = PADIC_VAL_UNIT; + std::cout << "print: ";print(x);std::cout << '\n'; + std::cout << "get_str: " << x.to_string() << '\n'; + } + + // Log + { + std::cout << "Log of 7380996 mod 5^20\n"; + fmpzxx p(5); + padicxx_ctx ctx(p, 10, 25, PADIC_SERIES); + + padicxx x = padicxx::from_QQ(7380996, ctx); + padicxx y(log(x)); + + std::cout << "x = " << x << '\n'; + std::cout << "y = " << y << '\n'; + } + + return 0; +} + diff --git a/external/flint-2.4.3/examples/partitions.c b/external/flint-2.4.3/examples/partitions.c new file mode 100644 index 0000000..7850c58 --- /dev/null +++ b/external/flint-2.4.3/examples/partitions.c @@ -0,0 +1,30 @@ +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "arith.h" + +int +main(int argc, char * argv[]) +{ + fmpz_t x; + ulong n; + + if (argc != 2) + { + flint_printf("usage: partitions n\n"); + return 1; + } + + flint_sscanf(argv[1], "%wu", &n); + + flint_printf("p(%wu) = \n", n); + + fmpz_init(x); + arith_number_of_partitions(x, n); + fmpz_print(x); + flint_printf("\n"); + fmpz_clear(x); + + return 0; +} diff --git a/external/flint-2.4.3/examples/partitions.cpp b/external/flint-2.4.3/examples/partitions.cpp new file mode 100644 index 0000000..e34af8b --- /dev/null +++ b/external/flint-2.4.3/examples/partitions.cpp @@ -0,0 +1,24 @@ +#include +#include +#include "arithxx.h" +#include "fmpzxx.h" + +using namespace flint; +using namespace std; + +int +main(int argc, char * argv[]) +{ + if (argc != 2) + { + std::cerr << "usage: partitions n\n"; + return 1; + } + + ulong n; + flint_sscanf(argv[1], "%wu", &n); + + std::cout << "p(" << n << ") =\n" << number_of_partitions(n) << '\n'; + + return 0; +} diff --git a/external/flint-2.4.3/examples/primegen.c b/external/flint-2.4.3/examples/primegen.c new file mode 100644 index 0000000..a789b13 --- /dev/null +++ b/external/flint-2.4.3/examples/primegen.c @@ -0,0 +1,69 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(int argc, char* argv[]) +{ + n_primes_t iter; + mp_limb_t p, N; + + if (argc < 2) + { + flint_printf("primegen N - print all primes <= N\n"); + flint_printf("primegen -c N - generate the primes but just count them\n"); + return EXIT_FAILURE; + } + + N = strtoul(argv[argc-1], NULL, 10); + if (N == UWORD_MAX) + { + flint_printf("N must be smaller than %wu\n", UWORD_MAX); + return EXIT_FAILURE; + } + + if (argc == 3) + { + ulong count = 0; + n_primes_init(iter); + while ((p = n_primes_next(iter)) <= N) + count++; + n_primes_clear(iter); + flint_printf("pi(%wu) = %wu\n", N, count); + } + else + { + n_primes_init(iter); + while ((p = n_primes_next(iter)) <= N) + flint_printf("%wu\n", p); + n_primes_clear(iter); + } + + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/examples/qadic.c b/external/flint-2.4.3/examples/qadic.c new file mode 100644 index 0000000..d841c9e --- /dev/null +++ b/external/flint-2.4.3/examples/qadic.c @@ -0,0 +1,174 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2013 Sebastian Pancratz + +******************************************************************************/ + +/* + Demo FLINT program to demonstrate some use of the qadic module. +*/ + +#include +#include + +#include "qadic.h" + +int main(void) +{ + fmpz_t p; + slong d, N; + qadic_ctx_t ctx; + + qadic_t a, b, c; + + int ans; + + /*************************************************************************/ + + fmpz_t e = {WORD(4)}; + fmpz_t nine = {WORD(9)}; + + fmpz_init_set_ui(p, 3); + d = 2; + N = 5; + qadic_ctx_init_conway(ctx, p, d, 0, N, "a", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + qadic_init2(c, N); + + flint_printf("Compute a power and a sum\n"); + padic_poly_fit_length(a, 2); + fmpz_one(a->coeffs + 0); + fmpz_set_ui(a->coeffs + 1, 2); + a->val = 0; + _padic_poly_set_length(a, 2); + + qadic_print_pretty(a, ctx); flint_printf("\n"); + + qadic_pow(a, a, e, ctx); + padic_poly_set_ui(b, 3249, &ctx->pctx); + qadic_add(c, a, b, ctx); + + qadic_print_pretty(a, ctx); flint_printf("\n"); + qadic_print_pretty(b, ctx); flint_printf("\n"); + qadic_print_pretty(c, ctx); flint_printf("\n"); + flint_printf("\n"); + + flint_printf("Compute a Teichmuller lift\n"); + padic_poly_fit_length(a, 2); + fmpz_one(a->coeffs + 0); + fmpz_set_ui(a->coeffs + 1, 2); + a->val = 0; + _padic_poly_set_length(a, 2); + + qadic_teichmuller(b, a, ctx); + qadic_pow(c, b, nine, ctx); + + qadic_print_pretty(a, ctx); flint_printf("\n"); + qadic_print_pretty(b, ctx); flint_printf("\n"); + qadic_print_pretty(c, ctx); flint_printf("\n"); + flint_printf("\n"); + + flint_printf("Compute an inverse\n"); + qadic_set(a, b, ctx); + qadic_inv(b, a, ctx); + qadic_mul(c, a, b, ctx); + + qadic_print_pretty(a, ctx); flint_printf("\n"); + qadic_print_pretty(b, ctx); flint_printf("\n"); + qadic_print_pretty(c, ctx); flint_printf("\n"); + flint_printf("\n"); + + qadic_clear(a); + qadic_clear(b); + qadic_clear(c); + + qadic_ctx_clear(ctx); + fmpz_clear(p); + + /*************************************************************************/ + + flint_printf("Compute a Frobenius image\n"); + + fmpz_init_set_ui(p, 3); + d = 2; + N = 5; + qadic_ctx_init_conway(ctx, p, d, 0, N, "X", PADIC_TERSE); + + qadic_init2(a, N); + qadic_init2(b, N); + + padic_poly_fit_length(a, 2); + a->coeffs[0] = WORD(78); + a->coeffs[1] = WORD(45); + a->val = 0; + _padic_poly_set_length(a, 2); + + qadic_frobenius(b, a, 1, ctx); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("Context:\n"), qadic_ctx_print(ctx); + flint_printf("\n"); + + qadic_clear(a); + qadic_clear(b); + + qadic_ctx_clear(ctx); + fmpz_clear(p); + + /*************************************************************************/ + + flint_printf("Compute a square root\n"); + + fmpz_init_set_ui(p, 2); + d = 3; + N = 2; + qadic_ctx_init_conway(ctx, p, d, 0, N, "X", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + + padic_poly_fit_length(a, d); + a->coeffs[0] = WORD(1); + a->coeffs[1] = WORD(3); + a->coeffs[2] = WORD(1); + a->val = 0; + _padic_poly_set_length(a, d); + + ans = qadic_sqrt(b, a, ctx); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("ans = %d\n", ans); + flint_printf("Context:\n"), qadic_ctx_print(ctx); + flint_printf("\n"); + + qadic_clear(a); + qadic_clear(b); + + qadic_ctx_clear(ctx); + fmpz_clear(p); + + + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/examples/radix.c b/external/flint-2.4.3/examples/radix.c new file mode 100644 index 0000000..3d5ed48 --- /dev/null +++ b/external/flint-2.4.3/examples/radix.c @@ -0,0 +1,139 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +/* + Demo FLINT program to demonstrate some use of the + function fmpz_mod_poly_radix() for radix conversion + over $\mathbf{Z}/n \mathbf{Z}$. +*/ + +#include +#include +#include +#include + +#include "flint.h" +#include "fmpz_mod_poly.h" + +int main(void) +{ + const slong n = 12376; + const slong N = n / 26; + + clock_t c0, c1; + double c; + + slong i; + fmpz_t a, m; + fmpz_mod_poly_t A, B, r, t; + fmpz_mod_poly_radix_t S; + fmpz_mod_poly_struct **b; + + FLINT_TEST_INIT(state); + + fmpz_init(a); + fmpz_init(m); + + fmpz_set_ui(m, 17); + fmpz_pow_ui(m, m, 26); + + fmpz_mod_poly_init(A, m); + fmpz_mod_poly_init(B, m); + fmpz_mod_poly_init(r, m); + fmpz_mod_poly_init(t, m); + + fmpz_mod_poly_set_coeff_ui(A, 3, 5); + fmpz_mod_poly_set_coeff_ui(A, 4, 4); + + fmpz_mod_poly_set_coeff_ui(B, 0, 1); + fmpz_mod_poly_set_coeff_ui(B, 2, 1); + fmpz_mod_poly_set_coeff_ui(B, 3, 5); + fmpz_mod_poly_set_coeff_ui(B, 4, 1); + fmpz_mod_poly_set_coeff_ui(B, 5, 5); + fmpz_mod_poly_set_coeff_ui(B, 8, 8); + fmpz_mod_poly_set_coeff_ui(B, 9, 8); + fmpz_mod_poly_set_coeff_ui(B, 10, 5); + fmpz_mod_poly_set_coeff_ui(B, 12, 6); + fmpz_mod_poly_set_coeff_ui(B, 13, 1); + + fmpz_mod_poly_pow(r, A, 3); + fmpz_set_ui(a, 4); + fmpz_mod_poly_scalar_mul_fmpz(r, r, a); + + fmpz_mod_poly_pow(t, B, 2); + fmpz_set_ui(a, 27); + fmpz_mod_poly_scalar_mul_fmpz(t, t, a); + + fmpz_mod_poly_add(r, r, t); + + b = flint_malloc((N + 1) * sizeof(fmpz_mod_poly_struct *)); + for (i = 0; i <= N; i++) + { + b[i] = flint_malloc(sizeof(fmpz_mod_poly_struct)); + fmpz_mod_poly_init(b[i], m); + } + + fmpz_mod_poly_randtest(t, state, n + 1); + + flint_printf("Radix conversion\n"); + flint_printf("----------------\n"); + flint_printf(" Degree of the radix: %wd\n", fmpz_mod_poly_degree(r)); + flint_printf(" Bit size of the modulus: %wd\n", (slong) fmpz_bits(fmpz_mod_poly_modulus(r))); + flint_printf(" Degree of the input: %wd\n", fmpz_mod_poly_degree(t)); + + c0 = clock(); + fmpz_mod_poly_radix_init(S, r, n + 1); + c1 = clock(); + c = (double) (c1 - c0) / CLOCKS_PER_SEC; + + flint_printf(" Precomputation: %fs\n", c); + + c0 = clock(); + fmpz_mod_poly_radix(b, t, S); + c1 = clock(); + c = (double) (c1 - c0) / CLOCKS_PER_SEC; + + flint_printf(" Conversion: %fs\n", c); + + fmpz_clear(a); + fmpz_clear(m); + fmpz_mod_poly_clear(A); + fmpz_mod_poly_clear(B); + fmpz_mod_poly_clear(r); + fmpz_mod_poly_clear(t); + fmpz_mod_poly_radix_clear(S); + + for (i = 0; i <= N; i++) + { + fmpz_mod_poly_clear(b[i]); + flint_free(b[i]); + } + flint_free(b); + + flint_randclear(state); + + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/examples/radix.cpp b/external/flint-2.4.3/examples/radix.cpp new file mode 100644 index 0000000..2c8a63c --- /dev/null +++ b/external/flint-2.4.3/examples/radix.cpp @@ -0,0 +1,94 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Tom Bachmann (C++ adaptation) + +******************************************************************************/ + +/* + Demo FLINT program to demonstrate some use of the + function fmpz_mod_poly_radix() for radix conversion + over $\mathbf{Z}/n \mathbf{Z}$. +*/ + +#include +#include +#include "fmpz_mod_polyxx.h" + +using namespace std; +using namespace flint; + +int main(void) +{ + const slong n = 12376; + const slong N = n / 26; + + frandxx state; + + fmpzxx m(17); + m = m.pow(26u); + + fmpz_mod_polyxx A(m), B(m); + + A.set_coeff(3, 5); + A.set_coeff(4, 4); + + B.set_coeff(0, 1); + B.set_coeff(2, 1); + B.set_coeff(3, 5); + B.set_coeff(4, 1); + B.set_coeff(5, 5); + B.set_coeff(8, 8); + B.set_coeff(9, 8); + B.set_coeff(10, 5); + B.set_coeff(12, 6); + B.set_coeff(13, 1); + + fmpz_mod_polyxx r(A.pow(3u) * fmpzxx(4) + B.pow(2u) * fmpzxx(27)); + + fmpz_mod_poly_vecxx b(N + 1, m); + + fmpz_mod_polyxx t = fmpz_mod_polyxx::randtest(m, state, n + 1); + + flint_printf("Radix conversion\n"); + flint_printf("----------------\n"); + flint_printf(" Degree of the radix: %wd\n", r.degree()); + flint_printf(" Bit size of the modulus: %wd\n", (slong) bits(r.modulus())); + flint_printf(" Degree of the input: %wd\n", t.degree()); + + clock_t c0 = clock(); + fmpz_mod_poly_radixxx S(r, n + 1); + clock_t c1 = clock(); + double c = (double) (c1 - c0) / CLOCKS_PER_SEC; + + flint_printf(" Precomputation: %fs\n", c); + + c0 = clock(); + b = t.radix(S); + c1 = clock(); + c = (double) (c1 - c0) / CLOCKS_PER_SEC; + + flint_printf(" Conversion: %fs\n", c); + + return 0; +} + diff --git a/external/flint-2.4.3/examples/stirling_matrix.c b/external/flint-2.4.3/examples/stirling_matrix.c new file mode 100644 index 0000000..153ae85 --- /dev/null +++ b/external/flint-2.4.3/examples/stirling_matrix.c @@ -0,0 +1,76 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +/* + Demo FLINT program for generating Stirling number matrices + and inverting them. +*/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mat.h" +#include "arith.h" + +int main(int argc, char* argv[]) +{ + slong n; + fmpz_mat_t S1, S2, P; + + if (argc != 2) + { + flint_printf("Syntax: stirling_matrix \n"); + return EXIT_FAILURE; + } + + n = atoi(argv[1]); + + fmpz_mat_init(S1, n, n); + fmpz_mat_init(S2, n, n); + fmpz_mat_init(P, n, n); + + arith_stirling_matrix_1(S1); + arith_stirling_matrix_2(S2); + fmpz_mat_mul(P, S1, S2); + + flint_printf("S1 [Stirling numbers of 1st kind]:\n"); + fmpz_mat_print_pretty(S1); + flint_printf("\n\n"); + + flint_printf("S2 [Stirling numbers of 2nd kind]:\n"); + fmpz_mat_print_pretty(S2); + flint_printf("\n\n"); + + flint_printf("S1 * S2:\n"); + fmpz_mat_print_pretty(P); + flint_printf("\n\n"); + + fmpz_mat_clear(S1); + fmpz_mat_clear(S2); + fmpz_mat_clear(P); + + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/examples/stirling_matrix.cpp b/external/flint-2.4.3/examples/stirling_matrix.cpp new file mode 100644 index 0000000..fc50576 --- /dev/null +++ b/external/flint-2.4.3/examples/stirling_matrix.cpp @@ -0,0 +1,65 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2013 Tom Bachmann (C++ adaptation) + +******************************************************************************/ + +/* + Demo FLINT program for generating Stirling number matrices + and inverting them. +*/ + +#include +#include "fmpz_matxx.h" +#include "fmpzxx.h" +#include "arithxx.h" + +using namespace std; +using namespace flint; + +int main(int argc, char* argv[]) +{ + if (argc != 2) + { + flint_printf("Syntax: stirling_matrix \n"); + return 1; + } + + slong n = atoi(argv[1]); + + fmpz_matxx S1(stirling_matrix_1(n, n)), S2(stirling_matrix_2(n, n)); + + flint_printf("S1 [Stirling numbers of 1st kind]:\n"); + print_pretty(S1); + flint_printf("\n\n"); + + flint_printf("S2 [Stirling numbers of 2nd kind]:\n"); + print_pretty(S2); + flint_printf("\n\n"); + + flint_printf("S1 * S2:\n"); + print_pretty(S1*S2); + flint_printf("\n\n"); + + return 0; +} diff --git a/external/flint-2.4.3/fft.h b/external/flint-2.4.3/fft.h new file mode 100644 index 0000000..965a1c3 --- /dev/null +++ b/external/flint-2.4.3/fft.h @@ -0,0 +1,289 @@ +/* mul_fft -- radix 2 fft routines for MPIR. + +Copyright 2009, 2011 William Hart. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY William Hart ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL William Hart OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those of the +authors and should not be interpreted as representing official policies, either expressed +or implied, of William Hart. + +*/ + +/****************************************************************************** + + Copyright (C) 2009, 2011 William Hart + +******************************************************************************/ + +#ifndef FFT_H +#define FFT_H + +#undef ulong +#define ulong ulongxx /* interferes with system includes */ +#include +#include +#undef ulong + +#include +#define ulong mp_limb_t +#include "flint.h" +#include "mpn_extras.h" + +#ifdef __cplusplus + extern "C" { +#endif + +#if defined(__MPIR_VERSION) + +#if !defined(__MPIR_RELEASE ) || __MPIR_RELEASE < 20600 +#define mpn_sumdiff_n __MPN(sumdiff_n) +extern +mp_limb_t mpn_sumdiff_n(mp_ptr, mp_ptr, mp_srcptr, mp_srcptr, mp_size_t); +#endif + +#else + +static __inline__ mp_limb_t +mpn_sumdiff_n(mp_ptr s, mp_ptr d, mp_srcptr x, mp_srcptr y, mp_size_t n) +{ + mp_limb_t ret; + mp_ptr t; + + if (n == 0) + return 0; + + if ((s == x && d == y) || (s == y && d == x)) + { + t = flint_malloc(n * sizeof(mp_limb_t)); + ret = mpn_sub_n(t, x, y, n); + ret += 2 * mpn_add_n(s, x, y, n); + flint_mpn_copyi(d, t, n); + flint_free(t); + return ret; + } + + if (s == x || s == y) + { + ret = mpn_sub_n(d, x, y, n); + ret += 2 * mpn_add_n(s, x, y, n); + return ret; + } + + ret = 2 * mpn_add_n(s, x, y, n); + ret += mpn_sub_n(d, x, y, n); + return ret; +} + +#endif + +#define fft_sumdiff(t, u, r, s, n) \ + (n == 0 ? 0 : mpn_sumdiff_n(t, u, r, s, n)) + + +#define SWAP_PTRS(xx, yy) \ + do { \ + mp_limb_t * __ptr = xx; \ + xx = yy; \ + yy = __ptr; \ + } while (0) + +/* used for generating random values mod p in test code */ +#define random_fermat(nn, state, limbs) \ + do { \ + if (n_randint(state, 10) == 0) { \ + flint_mpn_zero(nn, limbs); \ + nn[limbs] = 1; \ + } else { \ + if (n_randint(state, 2) == 0) \ + flint_mpn_rrandom(nn, state->gmp_state, limbs); \ + else \ + flint_mpn_urandomb(nn, state->gmp_state, limbs*FLINT_BITS); \ + nn[limbs] = n_randint(state, 1024); \ + } \ + if (n_randint(state, 2)) \ + nn[limbs] = -nn[limbs]; \ + } while (0) + +static __inline__ +void mpn_addmod_2expp1_1(mp_limb_t * r, mp_size_t limbs, mp_limb_signed_t c) +{ + mp_limb_t sum = r[0] + c; + + /* check if adding c would cause a carry to propagate */ + if ((mp_limb_signed_t)(sum ^ r[0]) >= 0) + r[0] = sum; + else + { + if (c >= 0) mpn_add_1(r, r, limbs + 1, c); + else mpn_sub_1(r, r, limbs + 1, -c); + } +} + +void fft_combine_limbs(mp_limb_t * res, mp_limb_t ** poly, slong length, + mp_size_t coeff_limbs, mp_size_t output_limbs, mp_size_t total_limbs); + +void fft_combine_bits(mp_limb_t * res, mp_limb_t ** poly, slong length, + mp_bitcnt_t bits, mp_size_t output_limbs, mp_size_t total_limbs); + +mp_size_t fft_split_limbs(mp_limb_t ** poly, mp_srcptr limbs, + mp_size_t total_limbs, mp_size_t coeff_limbs, mp_size_t output_limbs); + +mp_size_t fft_split_bits(mp_limb_t ** poly, mp_srcptr limbs, + mp_size_t total_limbs, mp_bitcnt_t bits, mp_size_t output_limbs); + +void fermat_to_mpz(mpz_t m, mp_limb_t * i, mp_size_t limbs); + +void mpn_normmod_2expp1(mp_limb_t * t, mp_size_t limbs); + +void butterfly_lshB(mp_limb_t * t, mp_limb_t * u, mp_limb_t * i1, + mp_limb_t * i2, mp_size_t limbs, mp_size_t x, mp_size_t y); + +void butterfly_rshB(mp_limb_t * t, mp_limb_t * u, mp_limb_t * i1, + mp_limb_t * i2, mp_size_t limbs, mp_size_t x, mp_size_t y); + +void mpn_mul_2expmod_2expp1(mp_limb_t * t, + mp_limb_t * i1, mp_size_t limbs, mp_bitcnt_t d); + +void mpn_div_2expmod_2expp1(mp_limb_t * t, + mp_limb_t * i1, mp_size_t limbs, mp_bitcnt_t d); + +void fft_adjust(mp_limb_t * r, mp_limb_t * i1, + mp_size_t i, mp_size_t limbs, mp_bitcnt_t w); + +void fft_butterfly(mp_limb_t * s, mp_limb_t * t, mp_limb_t * i1, + mp_limb_t * i2, mp_size_t i, mp_size_t limbs, mp_bitcnt_t w); + +void ifft_butterfly(mp_limb_t * s, mp_limb_t * t, mp_limb_t * i1, + mp_limb_t * i2, mp_size_t i, mp_size_t limbs, mp_bitcnt_t w); + +void fft_radix2(mp_limb_t ** ii, + mp_size_t n, mp_bitcnt_t w, mp_limb_t ** t1, mp_limb_t ** t2); + +void fft_truncate1(mp_limb_t ** ii, mp_size_t n, mp_bitcnt_t w, + mp_limb_t ** t1, mp_limb_t ** t2, mp_size_t trunc); + +void fft_truncate(mp_limb_t ** ii, mp_size_t n, mp_bitcnt_t w, + mp_limb_t ** t1, mp_limb_t ** t2, mp_size_t trunc); + +void ifft_radix2(mp_limb_t ** ii, mp_size_t n, + mp_bitcnt_t w, mp_limb_t ** t1, mp_limb_t ** t2); + +void ifft_truncate1(mp_limb_t ** ii, mp_size_t n, mp_bitcnt_t w, + mp_limb_t ** t1, mp_limb_t ** t2, mp_size_t trunc); + +void ifft_truncate(mp_limb_t ** ii, mp_size_t n, mp_bitcnt_t w, + mp_limb_t ** t1, mp_limb_t ** t2, mp_size_t trunc); + +void fft_butterfly_sqrt2(mp_limb_t * s, mp_limb_t * t, + mp_limb_t * i1, mp_limb_t * i2, mp_size_t i, + mp_size_t limbs, mp_bitcnt_t w, mp_limb_t * temp); + +void ifft_butterfly_sqrt2(mp_limb_t * s, mp_limb_t * t, mp_limb_t * i1, + mp_limb_t * i2, mp_size_t i, mp_size_t limbs, mp_bitcnt_t w, mp_limb_t * temp); + +void fft_adjust_sqrt2(mp_limb_t * r, mp_limb_t * i1, + mp_size_t i, mp_size_t limbs, mp_bitcnt_t w, mp_limb_t * temp); + +void fft_truncate_sqrt2(mp_limb_t ** ii, mp_size_t n, mp_bitcnt_t w, + mp_limb_t ** t1, mp_limb_t ** t2, mp_limb_t ** temp, mp_size_t trunc); + +void ifft_truncate_sqrt2(mp_limb_t ** ii, mp_size_t n, mp_bitcnt_t w, + mp_limb_t ** t1, mp_limb_t ** t2, mp_limb_t ** temp, mp_size_t trunc); + +void mul_truncate_sqrt2(mp_ptr r1, mp_srcptr i1, mp_size_t n1, + mp_srcptr i2, mp_size_t n2, mp_bitcnt_t depth, mp_bitcnt_t w); + +void fft_butterfly_twiddle(mp_limb_t * u, mp_limb_t * v, + mp_limb_t * s, mp_limb_t * t, mp_size_t limbs, mp_bitcnt_t b1, mp_bitcnt_t b2); + +void ifft_butterfly_twiddle(mp_limb_t * u, mp_limb_t * v, + mp_limb_t * s, mp_limb_t * t, mp_size_t limbs, mp_bitcnt_t b1, mp_bitcnt_t b2); + +void fft_radix2_twiddle(mp_limb_t ** ii, mp_size_t is, + mp_size_t n, mp_bitcnt_t w, mp_limb_t ** t1, mp_limb_t ** t2, + mp_size_t ws, mp_size_t r, mp_size_t c, mp_size_t rs); + +void ifft_radix2_twiddle(mp_limb_t ** ii, mp_size_t is, + mp_size_t n, mp_bitcnt_t w, mp_limb_t ** t1, mp_limb_t ** t2, + mp_size_t ws, mp_size_t r, mp_size_t c, mp_size_t rs); + +void fft_truncate1_twiddle(mp_limb_t ** ii, mp_size_t is, + mp_size_t n, mp_bitcnt_t w, mp_limb_t ** t1, mp_limb_t ** t2, + mp_size_t ws, mp_size_t r, mp_size_t c, mp_size_t rs, mp_size_t trunc); + +void ifft_truncate1_twiddle(mp_limb_t ** ii, mp_size_t is, + mp_size_t n, mp_bitcnt_t w, mp_limb_t ** t1, mp_limb_t ** t2, + mp_size_t ws, mp_size_t r, mp_size_t c, mp_size_t rs, mp_size_t trunc); + +void fft_mfa_truncate_sqrt2(mp_limb_t ** ii, mp_size_t n, + mp_bitcnt_t w, mp_limb_t ** t1, mp_limb_t ** t2, + mp_limb_t ** temp, mp_size_t n1, mp_size_t trunc); + +void ifft_mfa_truncate_sqrt2(mp_limb_t ** ii, mp_size_t n, + mp_bitcnt_t w, mp_limb_t ** t1, mp_limb_t ** t2, + mp_limb_t ** temp, mp_size_t n1, mp_size_t trunc); + +void mul_mfa_truncate_sqrt2(mp_ptr r1, mp_srcptr i1, mp_size_t n1, + mp_srcptr i2, mp_size_t n2, mp_bitcnt_t depth, mp_bitcnt_t w); + +void fft_mfa_truncate_sqrt2_outer(mp_limb_t ** ii, mp_size_t n, + mp_bitcnt_t w, mp_limb_t ** t1, mp_limb_t ** t2, + mp_limb_t ** temp, mp_size_t n1, mp_size_t trunc); + +void fft_mfa_truncate_sqrt2_inner(mp_limb_t ** ii, mp_limb_t ** jj, + mp_size_t n, mp_bitcnt_t w, mp_limb_t ** t1, mp_limb_t ** t2, + mp_limb_t ** temp, mp_size_t n1, mp_size_t trunc, mp_limb_t * tt); + +void ifft_mfa_truncate_sqrt2_outer(mp_limb_t ** ii, mp_size_t n, + mp_bitcnt_t w, mp_limb_t ** t1, mp_limb_t ** t2, + mp_limb_t ** temp, mp_size_t n1, mp_size_t trunc); + +void fft_negacyclic(mp_limb_t ** ii, mp_size_t n, mp_bitcnt_t w, + mp_limb_t ** t1, mp_limb_t ** t2, mp_limb_t ** temp); + +void ifft_negacyclic(mp_limb_t ** ii, mp_size_t n, mp_bitcnt_t w, + mp_limb_t ** t1, mp_limb_t ** t2, mp_limb_t ** temp); + +void fft_naive_convolution_1(mp_limb_t * r, mp_limb_t * ii, + mp_limb_t * jj, mp_size_t m); + +void _fft_mulmod_2expp1(mp_limb_t * r1, mp_limb_t * i1, mp_limb_t * i2, + mp_size_t r_limbs, mp_bitcnt_t depth, mp_bitcnt_t w); + +slong fft_adjust_limbs(mp_size_t limbs); + +void fft_mulmod_2expp1(mp_limb_t * r, mp_limb_t * i1, mp_limb_t * i2, + mp_size_t n, mp_size_t w, mp_limb_t * tt); + +void flint_mpn_mul_fft_main(mp_ptr r1, mp_srcptr i1, mp_size_t n1, + mp_srcptr i2, mp_size_t n2); + +void fft_convolution(mp_limb_t ** ii, mp_limb_t ** jj, slong depth, + slong limbs, slong trunc, mp_limb_t ** t1, + mp_limb_t ** t2, mp_limb_t ** s1, mp_limb_t * tt); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/external/flint-2.4.3/fft/README b/external/flint-2.4.3/fft/README new file mode 100644 index 0000000..2780ce8 --- /dev/null +++ b/external/flint-2.4.3/fft/README @@ -0,0 +1,296 @@ +FFT Integer Multiplication code +=============================== + +License: BSD + +(Note the FLINT library of which this is a part is overall GPL v2+ and the +latest version of GMP/MPIR on which this currently depends is XYXYXYXYPL v3+. But +the files in this implementation of the FFT are individually licensed BSD.) + +Introduction +------------ + +Many bignum libraries and programming languages do not contain fast code for +multiplication of huge integers. It is important to have this when computing +millions of digits of Pi, multiplying polynomials using Kronecker segmentation +(or the Schoenhage-Strassen technique using an FFT directly) and a variety of +other problems. + +Here we introduce fast FFT code for multiplication of huge integers. + +Currently the code depends on GMP/MPIR, however, any sufficiently well +developed bignum library should have equivalent primitives for bignums. (There +is also a dependence on the flint function n_revbin, which is found in the +ulong_extras directory of flint -- I hereby license it under the BSD +license as per the remainder of the FFT implementation.) + +To use the FFT for multiplying large integers, one needs to use the function +flint_mpn_mul_fft_main as documented in the doc directory. This relies on tuning +values supplied in fft_tuning.h in the top level source directory. + +Features: +-------- + +* Cache friendly up to huge transforms (integers of billions of bits) +* Truncated -- no uglytwit performance jumps at power of 2 lengths and no problem + with unbalanced multiplications +* Extremely fast +* Easy to tune +* Truncated FFT/IFFT functions can be used for polynomial multiplication + +Performance Data +---------------- + +Here are timings for multiplication of two integers of the given number of +bits, comparing MPIR 2.4.0, this code and GMP 5.0.2 respectively. The timings +are for varying numbers of iterations as specified. The timings were done on +a 2.2GHz AMD K10-2 Mangy Cours machine. + +The tuning values used are specified in the final two columns. + +The first part of the table uses mul_truncate_sqrt2, the second half uses +mul_mfa_truncate_sqrt2. + +bits iters mpir this gmp n w + +195840 1000 1.149s 1.105s 0.997s 7 16 +261120 1000 1.483s 1.415s 1.396s 7 16 +391296 100 0.261s 0.248s 0.282s 8 8 +521728 100 0.344s 0.315s 0.411s 8 8 +782592 100 0.577s 0.539s 0.628s 9 4 +1043456 100 0.706s 0.688s 0.848s 9 4 +1569024 100 1.229s 1.153s 1.317s 9 8 + +2092032 100 1.543s 1.440s 2.765s 9 8 +3127296 10 0.283s 0.266s 0.408s 11 1 +4169728 10 0.357s 0.335s 0.543s 11 1 +6273024 10 0.621s 0.597s 0.843s 11 2 +8364032 10 0.831s 0.742s 1.156s 11 2 +12539904 10 1.441s 1.394s 1.798s 12 1 +16719872 1 0.230s 0.205s 0.288s 12 1 +25122816 1 0.379s 0.336s 0.434s 12 2 +33497088 1 0.524s 0.428s 0.646s 12 2 +50245632 1 0.833s 0.693s 1.035s 13 1 +66994176 1 1.596s 0.896s 1.358s 13 1 +100577280 1 1.906s 1.552s 2.177s 13 2 +134103040 1 2.784s 2.076s 2.984s 13 2 +201129984 1 3.971s 3.158s 4.536s 14 1 +268173312 1 5.146s 4.137s 5.781s 14 1 +402456576 1 7.548s 6.443s 9.867s 14 2 +536608768 1 9.841s 8.365s 12.71s 14 2 +804913152 1 15.48s 13.29s 20.06s 15 1 +1073217536 1 21.17s 17.16s 27.19s 15 1 +1610219520 1 31.64s 28.60s 43.37s 15 2 +2146959360 1 43.25s 37.02s 57.66s 15 2 +3220340736 1 70.14s 58.09s 92.94s 16 1 +4293787648 1 96.00s 74.26s 146.1s 16 1 +6441566208 1 150.2s 131.1s 217.5s 16 2 +8588754944 1 208.4s 175.0s 312.8s 16 2 +12883132416 1 327.4s 278.6s 447.7s 17 1 +17177509888 1 485.0s 360.ss 614.2s 17 1 + + +Additional tuning +----------------- + +Technically one should tune the values that appear in fft_tuning.h. The +mulmod_2expp1 tuning array indices correspond to (n, w) pairs starting +at n = 12, w = 1. The values in the array should be nonnegative and less +than 6. The length of the array is given by FFT_N_NUM. The cutoff +FFT_MULMOD_2EXPP1_CUTOFF should also be tuned. It must be bigger than +128. The function that these values tunes is in the file mulmod_2expp1.c. +See the corresponding test function for an example of how to call it. + +The fft tuning array indices correspond to (n, w) pairs starting at +n = 6, w = 1. The values in the array should be nonnegative and less +than 6. The function that is tuned is in the file mpn_mul_fft_main.c. +See the corresponding test function for an example of how to call it. +The function implementation itself is the best reference for which +inputs will use which table entries. + +Strategy +-------- + +Let's suppose we wish to compute a convolution of length 2n where n is a power of 2. We do this with a standard Fermat transform with coefficients mod p = 2^wn + 1. Note 2^w is a 2n-th root of unity. + +We assume wn is divisible by GMP_LIMB_BITS (either 32 or 64). In practice n is always divisible by this constant. + +Write l = wn/GMP_LIMB_BITS. Each coeff is stored in a block of l+1 limbs in twos complement form. We accumulate carries in the top limb meaning reduction mod p does not need to be done after an addition or subtraction. + +Coefficients are also accessed via one level of indirection so that coefficients can be swapped by swapping pointers. + +A couple of extra temporary coefficients are allocated for operations which cannot be done entirely in-place. + +1. Efficient butterflies + +The FFT butterfly step is: + +[a{i}, b{i}] => [a{i}+b{i}, z^i*(a{i}-b{i})] + +We use MPIR's sumdiff to simultaneously perform the addition and subtraction. The multiplication by z^i is a shift by iw bits which we decompose into a shift by b bits and x limbs. The output is written in a location with an offset of x limbs. To handle the wraparound we split the operation into two parts. Finally we shift by the remaining b bits. An additional negation needs to occur when i >= n as nw = -1 mod p. + +The IFFT butterfly is: + +[a{i}, b{i}] => [a{i}+z^-i*b{i}, a{i}-z^-i*b{i}] + +We first decompose iw into b bits and x limbs. We perform the bit shift first, in-place. Then we use sumdiff, this time reading at an offset of x limbs, splitting the operation into two parts as before. + +2. Cache locality + +We use the Matrix Fourier Algorithm. To perform an FFT of length m = RC we: + + * Split the coefficients into R rows of C columns + * Perform a length R FFT on each column, i.e. with an input stride of C + * Multiply each coefficient by z^{r*c} where z = exp(2*Pi*I/m), +note z corresponds to a shift of w bits + * Perform a length C FFT on each row, i.e. with an input stride of 1 + * Transpose the matrix of coefficients + +To perform an IFFT we complete the steps in reverse, using IFFT's instead of FFT's. + +We set R, C to be both around sqrt(m) to minimise the maximum size of FFT which is in cache at any one time. When the FFT is followed by the IFFT as in the convolution we do not perform the transposes of the matrix coefficients as they cancel each other out. + +We do not perform the twiddles by z^{rc} in a separate pass over the data. We combine them with the length R FFT's and IFFT's. They are combined with the butterflies at the very bottom level of the FFT's and IFFT's. They essentially cost nothing as they just increase the bit shifts already being performed. + +The algorithm expects the FFT's to output their coefficients in reverse binary order, thus we have to revbin the coefficient order after the column FFTs and before the column IFFTs. + +3. Truncation + +When performing a convolution where we know that many of the output coefficients will be zero (this happens when multiplying integers that are not of an optimal split-into-a-nice-power-of-two length) we can use Van der Hoeven's truncated FFT. + +There are two cases: a) less than or equal to half of the FFT output coeffs +are non-zero and b) more than half the coefficients are non-zero: + +a) A 0 0 0 + +b) A A A 0 + +In the first case, the first layer of the FFT would do nothing. As we +only care about the left half, we recurse on only the left half A 0, +ignoring the remaining zeros. + +In the second case we compute the first layer of the FFT. We then do +an ordinary FFT on the left half and recurse with a truncated FFT on +the right half. + +Of course we need to be careful in that the first layer of the FFT +will have replaced our zeroes with non-zero coefficients, so we don't +recurse to the above two cases. + +We start instead with an FFT with non-zero coefficients (labelled B). + +A B B B + +or + +A A A B + +But the cases can be dealt with in a similar way to the cases where +there are zeros. The saving comes in that we repeatedly ignore +coefficients on the right hand side when they are all past the +truncation point. + +The IFFT is slightly more involved. We know that we are going to +*end up with* zeroes on the right hand side. We start with the results +of the pointwise mults, though we do not perform all the pointwise +mults. If we are going to end up with c zeroes, we do not perform the +last c pointwise mults. + +So we want our IFFT to get to + +A A A 0 + +starting from + +P P P ? + +Again there are two cases, depending on how many zeros we will end up with: + +a) A 0 0 0 + +b) A A A 0 + +In case (a) , by working backwards from what we know we will get, the +next to last level must be + +A/2 0 (A/2)~ 0 where ~ is the opposite of the twiddle that will be +applied by the IFFT butterfly. + +But I can compute the LHS, A/2 0, simply by recursing on the truncated +IFFT. Then it is just a matter of multiplying by 2 to get A 0 which is +what I was after. + +In case (b) an ordinary IFFT can compute the left hand of the +penultimate layer, as we have all the necessary pointwise mults for +that. + +A A A 0 +B B ? ? + +The right hand side we compute by recursing on the truncated IFFT. But +we don't know what the final question mark is. To get it we have to +reverse the steps of the IFFT to find it. As we have the second B we +can compute the second A simply by performing some IFFT butterflies. +Now we can compute the second ? by reversing the IFFT butterflies. So +we are left with: + +A A' A 0' +B' B' ? C' + +where I wrote a dash on the coefficients we actually now know. + +Now we can recurse using the truncated IFFT on the right hand side. + +Although the coefficients C' are not zero, the principles are the same +and we split into two cases as above. + +This allows us to get the question mark, yielding: + +A A' A 0' +B' B' C' C' + +and clearly now we can compute the A's we don't know from the known +coefficients. + +To combine the MFA with truncation we simply truncate at one level of the MFA, i.e. set the truncation length to be a multiple of the length of the inner FFT's. When we are at the lower levels computing row FFT's we don't compute those which lie past the truncation point. + +We need to take care to perform the right pointwise mults because we do not transpose the matrix or output coefficients in revbin order. + +4. Negacyclic convolution + +The pointwise multiplications mod p are somtimes large enough to make use of an FFT. For this purpose we use a negacyclic convolution which naturally performs integer multiplication mod p. + +If we do this naively we break up into coefficients whose sizes are multiples of half the negacyclic FFT lengths. This becomes inefficient. + +In order to get around this we must perform two multiplications, one via a negacyclic FFT with big coefficients and one naively with very small coefficients and CRT them together. This gives more flexibility in the size of coefficients we use in the negacyclic FFT allowing the large pointwise multication mod p to be done efficiently (not implemented yet). + +5. Sqrt 2 trick + +In the ring Z/pZ where p = 2^S + 1 the value 2^(2S/4)-2^(S/4) is a +square root of 2. This allows us to perform a convolution of twice +the length without twice the cost. To perform the operations we need +to be able to perform twiddles by powers of sqrt2. These are decomposed +and the operations are combined as much as possible with the +multiplications by powers of 2. + +Acknowledgements +---------------- + +"Matters Computational: ideas, algorithms and source code", by Jorg +Arndt, see http://www.jjj.de/fxt/fxtbook.pdf + +"Primes numbers: a computational perspective", by Richard Crandall and +Carl Pomerance, 2nd ed., 2005, Springer. + +"A GMP-based implementation of Schonhage-Strassen's Large Integer +Multiplication Algorithm" by Pierrick Gaudry, Alexander Kruppa and +Paul Zimmermann, ISAAC 2007 proceedings, pp 167-174. See +http://www.loria.fr/~gaudry/publis/issac07.pdf + +"Multidigit multiplication for mathematicians" by Dan Bernstein (to +appear). see http://cr.yp.to/papers/m3.pdf + +"A cache-friendly truncated FFT" by David Harvey, Theor. Comput. Sci. 410 (2009), 2649.2658. See http://web.maths.unsw.edu.au/~davidharvey/papers/cache-trunc-fft/ + +"The truncated Fourier transform and applications" by Joris van der Hoeven, J. Gutierrez, editor, Proc. ISSAC 2004, pages 290.296, Univ. of Cantabria, Santander, Spain, July 4.7 2004. + diff --git a/external/flint-2.4.3/fft/adjust.c b/external/flint-2.4.3/fft/adjust.c new file mode 100644 index 0000000..510ede5 --- /dev/null +++ b/external/flint-2.4.3/fft/adjust.c @@ -0,0 +1,55 @@ +/* + +Copyright 2009, 2011 William Hart. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY William Hart ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL William Hart OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those of the +authors and should not be interpreted as representing official policies, either expressed +or implied, of William Hart. + +*/ + +#include "gmp.h" +#include "flint.h" +#include "fft.h" + +void fft_adjust(mp_limb_t * r, mp_limb_t * i1, mp_size_t i, mp_size_t limbs, mp_bitcnt_t w) +{ + mp_bitcnt_t b1; + mp_limb_t cy; + mp_size_t x; + + b1 = i*w; + x = b1/FLINT_BITS; + b1 = b1%FLINT_BITS; + + if (x) + { + flint_mpn_copyi(r + x, i1, limbs - x); + r[limbs] = 0; + cy = mpn_neg_n(r, i1 + limbs - x, x); + mpn_addmod_2expp1_1(r + x, limbs - x, -i1[limbs]); + mpn_sub_1(r + x, r + x, limbs - x + 1, cy); + mpn_mul_2expmod_2expp1(r, r, limbs, b1); + } else + mpn_mul_2expmod_2expp1(r, i1, limbs, b1); +} diff --git a/external/flint-2.4.3/fft/adjust_sqrt2.c b/external/flint-2.4.3/fft/adjust_sqrt2.c new file mode 100644 index 0000000..1ad3bc6 --- /dev/null +++ b/external/flint-2.4.3/fft/adjust_sqrt2.c @@ -0,0 +1,86 @@ +/* + +Copyright 2009, 2011 William Hart. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY William Hart ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL William Hart OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those of the +authors and should not be interpreted as representing official policies, either expressed +or implied, of William Hart. + +*/ + +#include "gmp.h" +#include "flint.h" +#include "fft.h" + +void fft_adjust_sqrt2(mp_limb_t * r, mp_limb_t * i1, + mp_size_t i, mp_size_t limbs, mp_bitcnt_t w, mp_limb_t * temp) +{ + mp_bitcnt_t wn = limbs*FLINT_BITS; + mp_limb_t cy; + mp_size_t j = i/2, k = w/2; + mp_size_t y; + mp_bitcnt_t b1; + int negate = 0; + + b1 = j + wn/4 + i*k; + if (b1 >= wn) + { + negate = 1; + b1 -= wn; + } + y = b1/FLINT_BITS; + b1 = b1%FLINT_BITS; + + /* multiply by 2^{j + wn/4 + i*k} */ + if (y) + { + flint_mpn_copyi(temp + y, i1, limbs - y); + cy = mpn_neg_n(temp, i1 + limbs - y, y); + temp[limbs] = 0; + mpn_addmod_2expp1_1(temp + y, limbs - y, -i1[limbs]); + mpn_sub_1(temp + y, temp + y, limbs - y + 1, cy); + mpn_mul_2expmod_2expp1(r, temp, limbs, b1); + } else + mpn_mul_2expmod_2expp1(r, i1, limbs, b1); + + /* multiply by 2^{wn/2} */ + y = limbs/2; + cy = 0; + + flint_mpn_copyi(temp + y, r, limbs - y); + temp[limbs] = 0; + if (y) cy = mpn_neg_n(temp, r + limbs - y, y); + mpn_addmod_2expp1_1(temp + y, limbs - y, -r[limbs]); + mpn_sub_1(temp + y, temp + y, limbs - y + 1, cy); + + /* shift by an additional half limb (rare) */ + if (limbs & 1) + mpn_mul_2expmod_2expp1(temp, temp, limbs, FLINT_BITS/2); + + /* subtract */ + if (negate) + mpn_sub_n(r, r, temp, limbs + 1); + else + mpn_sub_n(r, temp, r, limbs + 1); +} + diff --git a/external/flint-2.4.3/fft/butterfly_lshB.c b/external/flint-2.4.3/fft/butterfly_lshB.c new file mode 100644 index 0000000..5e5fad7 --- /dev/null +++ b/external/flint-2.4.3/fft/butterfly_lshB.c @@ -0,0 +1,117 @@ +/* + +Copyright 2009, 2011 William Hart. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY William Hart ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL William Hart OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those of the +authors and should not be interpreted as representing official policies, either expressed +or implied, of William Hart. + +*/ + +#include "gmp.h" +#include "flint.h" +#include "fft.h" + +void butterfly_lshB(mp_limb_t * t, mp_limb_t * u, mp_limb_t * i1, + mp_limb_t * i2, mp_size_t limbs, mp_size_t x, mp_size_t y) +{ + mp_limb_t cy, cy1, cy2; + + if (x == 0) + { + if (y == 0) + cy = fft_sumdiff(t + x, u + y, i1, i2, limbs + 1); + else + { + cy = fft_sumdiff(t, u + y, i1, i2, limbs - y); + u[limbs] = -(cy&1); + cy1 = cy>>1; + cy = fft_sumdiff(t + limbs - y, u, i2 + limbs - y, i1 + limbs - y, y); + t[limbs] = cy>>1; + mpn_add_1(t + limbs - y, t + limbs - y, y + 1, cy1); + cy1 = -(cy&1) + (i2[limbs] - i1[limbs]); + mpn_addmod_2expp1_1(u + y, limbs - y, cy1); + cy1 = -(i1[limbs] + i2[limbs]); + mpn_addmod_2expp1_1(t, limbs, cy1); + } + } else if (y == 0) + { + cy = fft_sumdiff(t + x, u, i1, i2, limbs - x); + t[limbs] = cy>>1; + cy1 = cy&1; + cy = fft_sumdiff(t, u + limbs - x, i1 + limbs - x, i2 + limbs - x, x); + cy2 = mpn_neg_n(t, t, x); + u[limbs] = -(cy&1); + mpn_sub_1(u + limbs - x, u + limbs - x, x + 1, cy1); + cy1 = -(cy>>1) - cy2; + cy1 -= (i1[limbs] + i2[limbs]); + mpn_addmod_2expp1_1(t + x, limbs - x, cy1); + cy1 = (i2[limbs] - i1[limbs]); + mpn_addmod_2expp1_1(u, limbs, cy1); + } else if (x > y) + { + cy = fft_sumdiff(t + x, u + y, i1, i2, limbs - x); + t[limbs] = cy>>1; + cy1 = cy&1; + cy = fft_sumdiff(t, u + y + limbs - x, i1 + limbs - x, i2 + limbs - x, x - y); + cy2 = mpn_neg_n(t, t, x - y); + u[limbs] = -(cy&1); + mpn_sub_1(u + y + limbs - x, u + y + limbs - x, x - y + 1, cy1); + cy1 = (cy>>1) + cy2; + cy = fft_sumdiff(t + x - y, u, i2 + limbs - y, i1 + limbs - y, y); + cy2 = mpn_neg_n(t + x - y, t + x - y, y); + cy1 = -(cy>>1) - mpn_sub_1(t + x - y, t + x - y, y, cy1) - cy2; + cy1 -= (i1[limbs] + i2[limbs]); + mpn_addmod_2expp1_1(t + x, limbs - x, cy1); + cy1 = -(cy&1) + (i2[limbs] - i1[limbs]); + mpn_addmod_2expp1_1(u + y, limbs - y, cy1); + } else if (x < y) + { + cy = fft_sumdiff(t + x, u + y, i1, i2, limbs - y); + u[limbs] = -(cy&1); + cy1 = cy>>1; + cy = fft_sumdiff(t + x + limbs - y, u, i2 + limbs - y, i1 + limbs - y, y - x); + t[limbs] = cy>>1; + mpn_add_1(t + x + limbs - y, t + x + limbs - y, y - x + 1, cy1); + cy1 = cy&1; + cy = fft_sumdiff(t, u + y - x, i2 + limbs - x, i1 + limbs - x, x); + cy1 = -(cy&1) - mpn_sub_1(u + y - x, u + y - x, x, cy1); + cy1 += (i2[limbs] - i1[limbs]); + mpn_addmod_2expp1_1(u + y, limbs - y, cy1); + cy2 = mpn_neg_n(t, t, x); + cy1 = -(cy>>1) - (i1[limbs] + i2[limbs]) - cy2; + mpn_addmod_2expp1_1(t + x, limbs - x, cy1); + } else /* x == y */ + { + cy = fft_sumdiff(t + x, u + x, i1, i2, limbs - x); + t[limbs] = cy>>1; + u[limbs] = -(cy&1); + cy = fft_sumdiff(t, u, i2 + limbs - x, i1 + limbs - x, x); + cy2 = mpn_neg_n(t, t, x); + cy1 = -(cy>>1) - (i1[limbs] + i2[limbs]) - cy2; + mpn_addmod_2expp1_1(t + x, limbs - x, cy1); + cy1 = -(cy&1) + i2[limbs] - i1[limbs]; + mpn_addmod_2expp1_1(u + x, limbs - x, cy1); + } +} + diff --git a/external/flint-2.4.3/fft/butterfly_rshB.c b/external/flint-2.4.3/fft/butterfly_rshB.c new file mode 100644 index 0000000..5c95c85 --- /dev/null +++ b/external/flint-2.4.3/fft/butterfly_rshB.c @@ -0,0 +1,105 @@ +/* + +Copyright 2009, 2011 William Hart. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY William Hart ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL William Hart OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those of the +authors and should not be interpreted as representing official policies, either expressed +or implied, of William Hart. + +*/ + +#include "gmp.h" +#include "flint.h" +#include "fft.h" + +void butterfly_rshB(mp_limb_t * t, mp_limb_t * u, mp_limb_t * i1, + mp_limb_t * i2, mp_size_t limbs, mp_size_t x, mp_size_t y) +{ + mp_limb_t cy, cy1, cy2, cy3; + + if (x == 0) + { + if (y == 0) + { + cy = fft_sumdiff(t, u, i1, i2, limbs + 1); + } else /* y != 0 */ + { + cy = fft_sumdiff(t, u, i1, i2 + y, limbs - y); + cy1 = (cy>>1); + cy2 = -(cy&1); + cy = fft_sumdiff(u + limbs - y, t + limbs - y, i1 + limbs - y, i2, y); + u[limbs] = (cy>>1) + i1[limbs]; + t[limbs] = i1[limbs] - (cy&1); + mpn_addmod_2expp1_1(t + limbs - y, y, cy1 + i2[limbs]); + mpn_addmod_2expp1_1(u + limbs - y, y, cy2 - i2[limbs]); + } + } else if (y == 0) /* x != 0 */ + { + cy = fft_sumdiff(t, u, i1 + x, i2, limbs - x); + cy1 = (cy>>1); + cy2 = -(cy&1); + cy3 = mpn_neg_n(i1, i1, x); + cy = fft_sumdiff(t + limbs - x, u + limbs - x, i1, i2 + limbs - x, x); + u[limbs] = -cy3 - (cy&1) - i2[limbs]; + t[limbs] = -cy3 + i2[limbs] + (cy>>1); + mpn_addmod_2expp1_1(t + limbs - x, x, cy1 + i1[limbs]); + mpn_addmod_2expp1_1(u + limbs - x, x, cy2 + i1[limbs]); + } else if (x == y) + { + cy = fft_sumdiff(t, u, i1 + x, i2 + x, limbs - x); + cy1 = (cy>>1); + cy2 = -(cy&1); + cy = fft_sumdiff(t + limbs - x, u + limbs - x, i2, i1, x); + cy3 = mpn_neg_n(t + limbs - x, t + limbs - x, x); + u[limbs] = -(cy&1); + t[limbs] = -(cy>>1) - cy3; + mpn_addmod_2expp1_1(t + limbs - x, x, cy1 + i1[limbs] + i2[limbs]); + mpn_addmod_2expp1_1(u + limbs - x, x, cy2 + i1[limbs] - i2[limbs]); + } else if (x > y) + { + cy = fft_sumdiff(t + limbs - y, u + limbs - y, i2, i1 + x - y, y); + cy3 = mpn_neg_n(t + limbs - y, t + limbs - y, y); + t[limbs] = -(cy>>1) - cy3; + u[limbs] = -(cy&1); + cy3 = mpn_neg_n(i1, i1, x - y); + cy = fft_sumdiff(t + limbs - x, u + limbs - x, i1, i2 + limbs - x + y, x - y); + mpn_addmod_2expp1_1(t + limbs - y, y, (cy>>1) + i2[limbs] - cy3); + mpn_addmod_2expp1_1(u + limbs - y, y, -(cy&1) - i2[limbs] - cy3); + cy = fft_sumdiff(t, u, i1 + x, i2 + y, limbs - x); + mpn_addmod_2expp1_1(t + limbs - x, x, (cy>>1) + i1[limbs]); + mpn_addmod_2expp1_1(u + limbs - x, x, -(cy&1) + i1[limbs]); + } else /* x < y */ + { + cy = fft_sumdiff(t + limbs - x, u + limbs - x, i2 + y - x, i1, x); + cy3 = mpn_neg_n(t + limbs - x, t + limbs - x, x); + t[limbs] = -(cy>>1) - cy3; + u[limbs] = -(cy&1); + cy3 = mpn_neg_n(i2, i2, y - x); + cy = fft_sumdiff(t + limbs - y, u + limbs - y, i1 + limbs - y + x, i2, y - x); + mpn_addmod_2expp1_1(t + limbs - x, x, (cy>>1) + i1[limbs] - cy3); + mpn_addmod_2expp1_1(u + limbs - x, x, -(cy&1) + i1[limbs] + cy3); + cy = fft_sumdiff(t, u, i1 + x, i2 + y, limbs - y); + mpn_addmod_2expp1_1(t + limbs - y, y, (cy>>1) + i2[limbs]); + mpn_addmod_2expp1_1(u + limbs - y, y, -(cy&1) - i2[limbs]); + } +} diff --git a/external/flint-2.4.3/fft/combine_bits.c b/external/flint-2.4.3/fft/combine_bits.c new file mode 100644 index 0000000..f153e71 --- /dev/null +++ b/external/flint-2.4.3/fft/combine_bits.c @@ -0,0 +1,114 @@ +/* + +Copyright 2009, 2011 William Hart. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY William Hart ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL William Hart OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those of the +authors and should not be interpreted as representing official policies, either expressed +or implied, of William Hart. + +*/ + +#include "stdlib.h" +#include "gmp.h" +#include "flint.h" +#include "fft.h" + +void fft_combine_limbs(mp_limb_t * res, mp_limb_t ** poly, slong length, + mp_size_t coeff_limbs, mp_size_t output_limbs, mp_size_t total_limbs) +{ + mp_size_t skip, i; + + for (skip = 0, i = 0; i < length && skip + output_limbs + 1 <= total_limbs; i++, skip += coeff_limbs) + mpn_add(res + skip, res + skip, output_limbs + 1, poly[i], output_limbs); + + while ((skip < total_limbs) && (i < length)) + { + mpn_add(res + skip, res + skip, total_limbs - skip, poly[i], FLINT_MIN(total_limbs - skip, output_limbs)); + + i++; + + skip += coeff_limbs; + } +} + +void fft_combine_bits(mp_limb_t * res, mp_limb_t ** poly, slong length, + mp_bitcnt_t bits, mp_size_t output_limbs, mp_size_t total_limbs) +{ + mp_bitcnt_t shift_bits, top_bits = ((FLINT_BITS - 1) & bits); + mp_size_t coeff_limbs, i; + mp_limb_t * temp, * limb_ptr, * end; + + if (top_bits == 0) + { + fft_combine_limbs(res, poly, length, bits/FLINT_BITS, output_limbs, total_limbs); + return; + } + + coeff_limbs = (bits/FLINT_BITS) + 1; + temp = flint_malloc((output_limbs + 1)*sizeof(mp_limb_t)); + shift_bits = 0; + limb_ptr = res; + end = res + total_limbs; + + for (i = 0; i < length && limb_ptr + output_limbs + 1 < end; i++) + { + if (shift_bits) + { + mpn_lshift(temp, poly[i], output_limbs + 1, shift_bits); + mpn_add_n(limb_ptr, limb_ptr, temp, output_limbs + 1); + } else + mpn_add(limb_ptr, limb_ptr, output_limbs + 1, poly[i], output_limbs); + + shift_bits += top_bits; + limb_ptr += (coeff_limbs - 1); + + if (shift_bits >= FLINT_BITS) + { + limb_ptr++; + shift_bits -= FLINT_BITS; + } + } + + while (limb_ptr < end && i < length) + { + if (shift_bits) + { + mpn_lshift(temp, poly[i], output_limbs + 1, shift_bits); + mpn_add_n(limb_ptr, limb_ptr, temp, end - limb_ptr); + } else + mpn_add_n(limb_ptr, limb_ptr, poly[i], end - limb_ptr); + + shift_bits += top_bits; + limb_ptr += (coeff_limbs - 1); + + if (shift_bits >= FLINT_BITS) + { + limb_ptr++; + shift_bits -= FLINT_BITS; + } + + i++; + } + + flint_free(temp); +} diff --git a/external/flint-2.4.3/fft/convolution.c b/external/flint-2.4.3/fft/convolution.c new file mode 100644 index 0000000..6a672e9 --- /dev/null +++ b/external/flint-2.4.3/fft/convolution.c @@ -0,0 +1,84 @@ +/* + +Copyright 2008-2011 William Hart. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY William Hart ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL William Hart OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those of the +authors and should not be interpreted as representing official policies, either expressed +or implied, of William Hart. + +*/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" +#include "fft.h" + +void fft_convolution(mp_limb_t ** ii, mp_limb_t ** jj, slong depth, + slong limbs, slong trunc, mp_limb_t ** t1, + mp_limb_t ** t2, mp_limb_t ** s1, mp_limb_t * tt) +{ + slong n = (WORD(1)<> as arithmetic shift right */ + +void mpn_div_2expmod_2expp1(mp_limb_t * t, mp_limb_t * i1, mp_size_t limbs, mp_bitcnt_t d) +{ + mp_limb_t lo; + mp_limb_t * ptr; + mp_limb_signed_t hi; + + if (d == 0) + { + if (t != i1) + flint_mpn_copyi(t, i1, limbs + 1); + } else + { + hi = i1[limbs]; + lo = mpn_rshift(t, i1, limbs + 1, d); + t[limbs] = (hi >> d); + ptr = t + limbs - 1; + sub_ddmmss(ptr[1], ptr[0], ptr[1], ptr[0], (mp_limb_t) 0, lo); + } +} diff --git a/external/flint-2.4.3/fft/doc/fft.txt b/external/flint-2.4.3/fft/doc/fft.txt new file mode 100644 index 0000000..5996f86 --- /dev/null +++ b/external/flint-2.4.3/fft/doc/fft.txt @@ -0,0 +1,658 @@ +/* +Copyright 2009, 2011 William Hart. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY William Hart ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL William Hart OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those of the +authors and should not be interpreted as representing official policies, either expressed +or implied, of William Hart. +*/ + +/****************************************************************************** + + Copyright (C) 2011 William Hart + +******************************************************************************/ + +******************************************************************************* + + Split/combine FFT coefficients + +******************************************************************************* + +mp_size_t fft_split_limbs(mp_limb_t ** poly, mp_srcptr limbs, + mp_size_t total_limbs, mp_size_t coeff_limbs, mp_size_t output_limbs) + + Split an integer \code{(limbs, total_limbs)} into coefficients of length + \code{coeff_limbs} limbs and store as the coefficients of \code{poly} + which are assumed to have space for \code{output_limbs + 1} limbs per + coefficient. The coefficients of the polynomial do not need to be zeroed + before calling this function, however the number of coefficients written + is returned by the function and any coefficients beyond this point are + not touched. + +mp_size_t fft_split_bits(mp_limb_t ** poly, mp_srcptr limbs, + mp_size_t total_limbs, mp_bitcnt_t bits, mp_size_t output_limbs) + + Split an integer \code{(limbs, total_limbs)} into coefficients of the + given number of \code{bits} and store as the coefficients of \code{poly} + which are assumed to have space for \code{output_limbs + 1} limbs per + coefficient. The coefficients of the polynomial do not need to be zeroed + before calling this function, however the number of coefficients written + is returned by the function and any coefficients beyond this point are + not touched. + +void fft_combine_limbs(mp_limb_t * res, mp_limb_t ** poly, slong length, + mp_size_t coeff_limbs, mp_size_t output_limbs, mp_size_t total_limbs) + + Evaluate the polynomial \code{poly} of the given \code{length} at + \code{B^coeff_limbs}, where \code{B = 2^FLINT_BITS}, and add the + result to the integer \code{(res, total_limbs)} throwing away any bits + that exceed the given number of limbs. The polynomial coefficients are + assumed to have at least \code{output_limbs} limbs each, however any + additional limbs are ignored. + + If the integer is initially zero the result will just be the evaluation + of the polynomial. + +void fft_combine_bits(mp_limb_t * res, mp_limb_t ** poly, slong length, + mp_bitcnt_t bits, mp_size_t output_limbs, mp_size_t total_limbs) + + Evaluate the polynomial \code{poly} of the given \code{length} at + \code{2^bits} and add the result to the integer + \code{(res, total_limbs)} throwing away any bits that exceed the given + number of limbs. The polynomial coefficients are assumed to have at least + \code{output_limbs} limbs each, however any additional limbs are ignored. + If the integer is initially zero the result will just be the evaluation + of the polynomial. + +******************************************************************************* + + Test helper functions + +******************************************************************************* + +void fermat_to_mpz(mpz_t m, mp_limb_t * i, mp_size_t limbs) + + Convert the Fermat number \code{(i, limbs)} modulo \code{B^limbs + 1} to + an \code{mpz_t m}. Assumes \code{m} has been initialised. This function + is used only in test code. + +******************************************************************************* + + Arithmetic modulo a generalised Fermat number + +******************************************************************************* + +void mpn_addmod_2expp1_1(mp_limb_t * r, mp_size_t limbs, mp_limb_signed_t c) + + Adds the signed limb \code{c} to the generalised fermat number \code{r} + modulo \code{B^limbs + 1}. The compiler should be able to inline + this for the case that there is no overflow from the first limb. + +void mpn_normmod_2expp1(mp_limb_t * t, mp_size_t limbs) + + Given \code{t} a signed integer of \code{limbs + 1} limbs in twos + complement format, reduce \code{t} to the corresponding value modulo the + generalised Fermat number \code{B^limbs + 1}, where + \code{B = 2^FLINT_BITS}. + +void mpn_mul_2expmod_2expp1(mp_limb_t * t, + mp_limb_t * i1, mp_size_t limbs, mp_bitcnt_t d) + + Given \code{i1} a signed integer of \code{limbs + 1} limbs in twos + complement format reduced modulo \code{B^limbs + 1} up to some + overflow, compute \code{t = i1*2^d} modulo $p$. The result will not + necessarily be fully reduced. The number of bits \code{d} must be + nonnegative and less than \code{FLINT_BITS}. Aliasing is permitted. + +void mpn_div_2expmod_2expp1(mp_limb_t * t, + mp_limb_t * i1, mp_size_t limbs, mp_bitcnt_t d) + + Given \code{i1} a signed integer of \code{limbs + 1} limbs in twos + complement format reduced modulo \code{B^limbs + 1} up to some + overflow, compute \code{t = i1/2^d} modulo $p$. The result will not + necessarily be fully reduced. The number of bits \code{d} must be + nonnegative and less than \code{FLINT_BITS}. Aliasing is permitted. + + +******************************************************************************* + + Generic butterflies + +******************************************************************************* + +void fft_adjust(mp_limb_t * r, mp_limb_t * i1, + mp_size_t i, mp_size_t limbs, mp_bitcnt_t w) + + Set \code{r} to \code{i1} times $z^i$ modulo \code{B^limbs + 1} where + $z$ corresponds to multiplication by $2^w$. This can be thought of as part + of a butterfly operation. We require $0 \leq i < n$ where $nw =$ + \code{limbs*FLINT_BITS}. Aliasing is not supported. + +void fft_adjust_sqrt2(mp_limb_t * r, mp_limb_t * i1, + mp_size_t i, mp_size_t limbs, mp_bitcnt_t w, mp_limb_t * temp) + + Set \code{r} to \code{i1} times $z^i$ modulo \code{B^limbs + 1} where + $z$ corresponds to multiplication by $\sqrt{2}^w$. This can be thought of + as part of a butterfly operation. We require $0 \leq i < 2*n$ and odd + where $nw =$ \code{limbs*FLINT_BITS}. + +void butterfly_lshB(mp_limb_t * t, mp_limb_t * u, mp_limb_t * i1, + mp_limb_t * i2, mp_size_t limbs, mp_size_t x, mp_size_t y) + + We are given two integers \code{i1} and \code{i2} modulo + \code{B^limbs + 1} which are not necessarily normalised. We compute + \code{t = (i1 + i2)*B^x} and \code{u = (i1 - i2)*B^y} modulo $p$. Aliasing + between inputs and outputs is not permitted. We require \code{x} and + \code{y} to be less than \code{limbs} and nonnegative. + +void butterfly_rshB(mp_limb_t * t, mp_limb_t * u, mp_limb_t * i1, + mp_limb_t * i2, mp_size_t limbs, mp_size_t x, mp_size_t y) + + We are given two integers \code{i1} and \code{i2} modulo + \code{B^limbs + 1} which are not necessarily normalised. We compute + \code{t = (i1 + i2)/B^x} and \code{u = (i1 - i2)/B^y} modulo $p$. Aliasing + between inputs and outputs is not permitted. We require \code{x} and + \code{y} to be less than \code{limbs} and nonnegative. + +******************************************************************************* + + Radix 2 transforms + +******************************************************************************* + +void fft_butterfly(mp_limb_t * s, mp_limb_t * t, mp_limb_t * i1, + mp_limb_t * i2, mp_size_t i, mp_size_t limbs, mp_bitcnt_t w) + + Set \code{s = i1 + i2}, \code{t = z1^i*(i1 - i2)} modulo + \code{B^limbs + 1} where \code{z1 = exp(Pi*I/n)} corresponds to + multiplication by $2^w$. Requires $0 \leq i < n$ where $nw =$ + \code{limbs*FLINT_BITS}. + +void ifft_butterfly(mp_limb_t * s, mp_limb_t * t, mp_limb_t * i1, + mp_limb_t * i2, mp_size_t i, mp_size_t limbs, mp_bitcnt_t w) + + Set \code{s = i1 + z1^i*i2}, \code{t = i1 - z1^i*i2} modulo + \code{B^limbs + 1} where\\ \code{z1 = exp(-Pi*I/n)} corresponds to + division by $2^w$. Requires $0 \leq i < 2n$ where $nw =$ + \code{limbs*FLINT_BITS}. + +void fft_radix2(mp_limb_t ** ii, + mp_size_t n, mp_bitcnt_t w, mp_limb_t ** t1, mp_limb_t ** t2) + + The radix 2 DIF FFT works as follows: + + Input: \code{[i0, i1, ..., i(m-1)]}, for $m = 2n$ a power of $2$. + + Output: \code{[r0, r1, ..., r(m-1)]}\\ \code{ = FFT[i0, i1, ..., i(m-1)]}. + + Algorithm: + + $\bullet$ Recursively compute \code{[r0, r2, r4, ...., r(m-2)]}\\ + \code{= FFT[i0+i(m/2), i1+i(m/2+1), ..., i(m/2-1)+i(m-1)]} + + $\bullet$ Let \code{[t0, t1, ..., t(m/2-1)]}\\ + \code{= [i0-i(m/2), i1-i(m/2+1), ..., i(m/2-1)-i(m-1)]} + + $\bullet$ Let \code{[u0, u1, ..., u(m/2-1)]}\\ + \code{= [z1^0*t0, z1^1*t1, ..., z1^(m/2-1)*t(m/2-1)]} + where \code{z1 = exp(2*Pi*I/m)} corresponds to multiplication + by $2^w$. + + $\bullet$ Recursively compute \code{[r1, r3, ..., r(m-1)]}\\ + \code{= FFT[u0, u1, ..., u(m/2-1)]} + + The parameters are as follows: + + $\bullet$ \code{2*n} is the length of the input and output + arrays + + $\bullet$ $w$ is such that $2^w$ is an $2n$-th root of unity + in the ring $\mathbb{Z}/p\mathbb{Z}$ that we are working in, + i.e. $p = 2^{wn} + 1$ (here $n$ is divisible by + \code{GMP_LIMB_BITS}) + + $\bullet$ \code{ii} is the array of inputs (each input is an + array of limbs of length \code{wn/GMP_LIMB_BITS + 1} (the + extra limbs being a "carry limb"). Outputs are written + in-place. + + We require $nw$ to be at least 64 and the two temporary space pointers to + point to blocks of size \code{n*w + FLINT_BITS} bits. + +void fft_truncate(mp_limb_t ** ii, mp_size_t n, mp_bitcnt_t w, + mp_limb_t ** t1, mp_limb_t ** t2, mp_size_t trunc) + + As for \code{fft_radix2} except that only the first \code{trunc} + coefficients of the output are computed and the input is regarded as + having (implied) zero coefficients from coefficient \code{trunc} onwards. + The coefficients must exist as the algorithm needs to use this extra + space, but their value is irrelevant. The value of \code{trunc} must be + divisible by 2. + +void fft_truncate1(mp_limb_t ** ii, mp_size_t n, mp_bitcnt_t w, + mp_limb_t ** t1, mp_limb_t ** t2, mp_size_t trunc) + + As for \code{fft_radix2} except that only the first \code{trunc} + coefficients of the output are computed. The transform still needs all + $2n$ input coefficients to be specified. + +void ifft_radix2(mp_limb_t ** ii, + mp_size_t n, mp_bitcnt_t w, mp_limb_t ** t1, mp_limb_t ** t2) + + The radix 2 DIF IFFT works as follows: + + Input: \code{[i0, i1, ..., i(m-1)]}, for $m = 2n$ a power of $2$. + + Output: \code{[r0, r1, ..., r(m-1)]}\\ + \code{ = IFFT[i0, i1, ..., i(m-1)]}. + + Algorithm: + + $\bullet$ Recursively compute \code{[s0, s1, ...., s(m/2-1)]}\\ + \code{= IFFT[i0, i2, ..., i(m-2)]} + + $\bullet$ Recursively compute \code{[t(m/2), t(m/2+1), ..., t(m-1)]}\\ + \code{= IFFT[i1, i3, ..., i(m-1)]} + + $\bullet$ Let \code{[r0, r1, ..., r(m/2-1)]}\\ + \code{= [s0+z1^0*t0, s1+z1^1*t1, ..., s(m/2-1)+z1^(m/2-1)*t(m/2-1)]} + where \code{z1 = exp(-2*Pi*I/m)} corresponds to division by $2^w$. + + $\bullet$ Let \code{[r(m/2), r(m/2+1), ..., r(m-1)]}\\ + \code{= [s0-z1^0*t0, s1-z1^1*t1, ..., s(m/2-1)-z1^(m/2-1)*t(m/2-1)]} + + The parameters are as follows: + + $\bullet$ \code{2*n} is the length of the input and output + arrays + + $\bullet$ $w$ is such that $2^w$ is an $2n$-th root of unity + in the ring $\mathbb{Z}/p\mathbb{Z}$ that we are working in, + i.e. $p = 2^{wn} + 1$ (here $n$ is divisible by + \code{GMP_LIMB_BITS}) + + $\bullet$ \code{ii} is the array of inputs (each input is an + array of limbs of length \code{wn/GMP_LIMB_BITS + 1} (the + extra limbs being a "carry limb"). Outputs are written + in-place. + + We require $nw$ to be at least 64 and the two temporary space pointers + to point to blocks of size \code{n*w + FLINT_BITS} bits. + +void ifft_truncate(mp_limb_t ** ii, mp_size_t n, mp_bitcnt_t w, + mp_limb_t ** t1, mp_limb_t ** t2, mp_size_t trunc) + + As for \code{ifft_radix2} except that the output is assumed to have + zeros from coefficient trunc onwards and only the first trunc + coefficients of the input are specified. The remaining coefficients need + to exist as the extra space is needed, but their value is irrelevant. + The value of \code{trunc} must be divisible by 2. + + Although the implementation does not require it, we assume for simplicity + that \code{trunc} is greater than $n$. The algorithm begins by computing + the inverse transform of the first $n$ coefficients of the input array. + The unspecified coefficients of the second half of the array are then + written: coefficient \code{trunc + i} is computed as a twist of + coefficient \code{i} by a root of unity. The values of these coefficients + are then equal to what they would have been if the inverse transform of + the right hand side of the input array had been computed with full data + from the start. The function \code{ifft_truncate1} is then called on the + entire right half of the input array with this auxilliary data filled in. + Finally a single layer of the IFFT is completed on all the coefficients + up to \code{trunc} being careful to note that this involves doubling the + coefficients from \code{trunc - n} up to \code{n}. + +void ifft_truncate1(mp_limb_t ** ii, mp_size_t n, mp_bitcnt_t w, + mp_limb_t ** t1, mp_limb_t ** t2, mp_size_t trunc) + + Computes the first \code{trunc} coefficients of the radix 2 inverse + transform assuming the first \code{trunc} coefficients are given and that + the remaining coefficients have been set to the value they would have if + an inverse transform had already been applied with full data. + + The algorithm is the same as for \code{ifft_truncate} except that the + coefficients from \code{trunc} onwards after the inverse transform are + not inferred to be zero but the supplied values. + +void fft_butterfly_sqrt2(mp_limb_t * s, mp_limb_t * t, + mp_limb_t * i1, mp_limb_t * i2, mp_size_t i, + mp_size_t limbs, mp_bitcnt_t w, mp_limb_t * temp) + + Let $w = 2k + 1$, $i = 2j + 1$. Set \code{s = i1 + i2}, + \code{t = z1^i*(i1 - i2)} modulo \code{B^limbs + 1} where + \code{z1^2 = exp(Pi*I/n)} corresponds to multiplication by $2^w$. Requires + $0 \leq i < 2n$ where $nw =$ \code{limbs*FLINT_BITS}. + + Here \code{z1} corresponds to multiplication by $2^k$ then multiplication + by\\ \code{(2^(3nw/4) - 2^(nw/4))}. We see \code{z1^i} corresponds to + multiplication by \code{(2^(3nw/4) - 2^(nw/4))*2^(j+ik)}. + + We first multiply by \code{2^(j + ik + wn/4)} then multiply by an + additional \code{2^(nw/2)} and subtract. + +void ifft_butterfly_sqrt2(mp_limb_t * s, mp_limb_t * t, mp_limb_t * i1, + mp_limb_t * i2, mp_size_t i, mp_size_t limbs, + mp_bitcnt_t w, mp_limb_t * temp) + + Let $w = 2k + 1$, $i = 2j + 1$. Set \code{s = i1 + z1^i*i2}, + \code{t = i1 - z1^i*i2} modulo \code{B^limbs + 1} where + \code{z1^2 = exp(-Pi*I/n)} corresponds to division by $2^w$. Requires + $0 \leq i < 2n$ where $nw =$ \code{limbs*FLINT_BITS}. + + Here \code{z1} corresponds to division by $2^k$ then division by + \code{(2^(3nw/4) - 2^(nw/4))}. We see \code{z1^i} corresponds to division + by \code{(2^(3nw/4) - 2^(nw/4))*2^(j+ik)} which is the same as division + by \code{2^(j+ik + 1)} then multiplication by + \code{(2^(3nw/4) - 2^(nw/4))}. + + Of course, division by \code{2^(j+ik + 1)} is the same as multiplication + by \code{2^(2*wn - j - ik - 1)}. The exponent is positive as + $i \leq 2*n$, $j < n$, $k < w/2$. + + We first multiply by \code{2^(2*wn - j - ik - 1 + wn/4)} then multiply by + an additional \code{2^(nw/2)} and subtract. + +void fft_truncate_sqrt2(mp_limb_t ** ii, mp_size_t n, mp_bitcnt_t w, + mp_limb_t ** t1, mp_limb_t ** t2, mp_limb_t ** temp, mp_size_t trunc) + + As per \code{fft_truncate} except that the transform is twice the usual + length, i.e. length $4n$ rather than $2n$. This is achieved by making use + of twiddles by powers of a square root of 2, not powers of 2 in the first + layer of the transform. + + We require $nw$ to be at least 64 and the three temporary space pointers + to point to blocks of size \code{n*w + FLINT_BITS} bits. + +void ifft_truncate_sqrt2(mp_limb_t ** ii, mp_size_t n, mp_bitcnt_t w, + mp_limb_t ** t1, mp_limb_t ** t2, mp_limb_t ** temp, mp_size_t trunc) + + As per \code{ifft_truncate} except that the transform is twice the usual + length, i.e. length $4n$ instead of $2n$. This is achieved by making use + of twiddles by powers of a square root of 2, not powers of 2 in the final + layer of the transform. + + We require $nw$ to be at least 64 and the three temporary space pointers + to point to blocks of size \code{n*w + FLINT_BITS} bits. + +******************************************************************************* + + Matrix Fourier Transforms + +******************************************************************************* + +void fft_butterfly_twiddle(mp_limb_t * u, mp_limb_t * v, + mp_limb_t * s, mp_limb_t * t, mp_size_t limbs, + mp_bitcnt_t b1, mp_bitcnt_t b2) + + Set \code{u = 2^b1*(s + t)}, \code{v = 2^b2*(s - t)} modulo + \code{B^limbs + 1}. This is used to compute + \code{u = 2^(ws*tw1)*(s + t)},\\ \code{v = 2^(w+ws*tw2)*(s - t)} in the + matrix fourier algorithm, i.e. effectively computing an ordinary butterfly + with additional twiddles by \code{z1^rc} for row $r$ and column $c$ of the + matrix of coefficients. Aliasing is not allowed. + +void ifft_butterfly_twiddle(mp_limb_t * u, mp_limb_t * v, + mp_limb_t * s, mp_limb_t * t, mp_size_t limbs, + mp_bitcnt_t b1, mp_bitcnt_t b2) + + Set \code{u = s/2^b1 + t/2^b1)}, \code{v = s/2^b1 - t/2^b1} modulo + \code{B^limbs + 1}. This is used to compute + \code{u = 2^(-ws*tw1)*s + 2^(-ws*tw2)*t)},\\ + \code{v = 2^(-ws*tw1)*s + 2^(-ws*tw2)*t)} in the matrix fourier algorithm, + i.e. effectively computing an ordinary butterfly with additional twiddles + by \code{z1^(-rc)} for row $r$ and column $c$ of the matrix of + coefficients. Aliasing is not allowed. + +void fft_radix2_twiddle(mp_limb_t ** ii, mp_size_t is, + mp_size_t n, mp_bitcnt_t w, mp_limb_t ** t1, mp_limb_t ** t2, + mp_size_t ws, mp_size_t r, mp_size_t c, mp_size_t rs) + + As for \code{fft_radix2} except that the coefficients are spaced by + \code{is} in the array \code{ii} and an additional twist by \code{z^c*i} + is applied to each coefficient where $i$ starts at $r$ and increases by + \code{rs} as one moves from one coefficient to the next. Here \code{z} + corresponds to multiplication by \code{2^ws}. + +void ifft_radix2_twiddle(mp_limb_t ** ii, mp_size_t is, + mp_size_t n, mp_bitcnt_t w, mp_limb_t ** t1, mp_limb_t ** t2, + mp_size_t ws, mp_size_t r, mp_size_t c, mp_size_t rs) + + As for \code{ifft_radix2} except that the coefficients are spaced by + \code{is} in the array \code{ii} and an additional twist by + \code{z^(-c*i)} is applied to each coefficient where $i$ starts at $r$ + and increases by \code{rs} as one moves from one coefficient to the next. + Here \code{z} corresponds to multiplication by \code{2^ws}. + +void fft_truncate1_twiddle(mp_limb_t ** ii, mp_size_t is, + mp_size_t n, mp_bitcnt_t w, mp_limb_t ** t1, mp_limb_t ** t2, + mp_size_t ws, mp_size_t r, mp_size_t c, mp_size_t rs, mp_size_t trunc) + + As per \code{fft_radix2_twiddle} except that the transform is truncated + as per\\ \code{fft_truncate1}. + +void ifft_truncate1_twiddle(mp_limb_t ** ii, mp_size_t is, + mp_size_t n, mp_bitcnt_t w, mp_limb_t ** t1, mp_limb_t ** t2, + mp_size_t ws, mp_size_t r, mp_size_t c, mp_size_t rs, mp_size_t trunc) + + As per \code{ifft_radix2_twiddle} except that the transform is truncated + as per\\ \code{ifft_truncate1}. + +void fft_mfa_truncate_sqrt2(mp_limb_t ** ii, mp_size_t n, + mp_bitcnt_t w, mp_limb_t ** t1, mp_limb_t ** t2, + mp_limb_t ** temp, mp_size_t n1, mp_size_t trunc) + + This is as per the \code{fft_truncate_sqrt2} function except that the + matrix fourier algorithm is used for the left and right FFTs. The total + transform length is $4n$ where \code{n = 2^depth} so that the left and + right transforms are both length $2n$. We require \code{trunc > 2*n} and + that \code{trunc} is divisible by \code{2*n1} (explained below). + + The matrix fourier algorithm, which is applied to each transform of length + $2n$, works as follows. We set \code{n1} to a power of 2 about the square + root of $n$. The data is then thought of as a set of \code{n2} rows each + with \code{n1} columns (so that \code{n1*n2 = 2n}). + + The length $2n$ transform is then computed using a whole pile of short + transforms. These comprise \code{n1} column transforms of length \code{n2} + followed by some twiddles by roots of unity (namely \code{z^rc} where $r$ + is the row and $c$ the column within the data) followed by \code{n2} + row transforms of length \code{n1}. Along the way the data needs to be + rearranged due to the fact that the short transforms output the data in + binary reversed order compared with what is needed. + + The matrix fourier algorithm provides better cache locality by decomposing + the long length $2n$ transforms into many transforms of about the square + root of the original length. + + For better cache locality the sqrt2 layer of the full length $4n$ + transform is folded in with the column FFTs performed as part of the first + matrix fourier algorithm on the left half of the data. + + The second half of the data requires a truncated version of the matrix + fourier algorithm. This is achieved by truncating to an exact multiple of + the row length so that the row transforms are full length. Moreover, the + column transforms will then be truncated transforms and their truncated + length needs to be a multiple of 2. This explains the condition on + \code{trunc} given above. + + To improve performance, the extra twiddles by roots of unity are combined + with the butterflies performed at the last layer of the column transforms. + + We require $nw$ to be at least 64 and the three temporary space pointers + to point to blocks of size \code{n*w + FLINT_BITS} bits. + +void ifft_mfa_truncate_sqrt2(mp_limb_t ** ii, mp_size_t n, + mp_bitcnt_t w, mp_limb_t ** t1, mp_limb_t ** t2, + mp_limb_t ** temp, mp_size_t n1, mp_size_t trunc) + + This is as per the \code{ifft_truncate_sqrt2} function except that the + matrix fourier algorithm is used for the left and right IFFTs. The total + transform length is $4n$ where \code{n = 2^depth} so that the left and + right transforms are both length $2n$. We require \code{trunc > 2*n} and + that \code{trunc} is divisible by \code{2*n1}. + + We set \code{n1} to a power of 2 about the square root of $n$. + + As per the matrix fourier FFT the sqrt2 layer is folded into the the + final column IFFTs for better cache locality and the extra twiddles that + occur in the matrix fourier algorithm are combined with the butterflied + performed at the first layer of the final column transforms. + + We require $nw$ to be at least 64 and the three temporary space pointers + to point to blocks of size \code{n*w + FLINT_BITS} bits. + +void fft_mfa_truncate_sqrt2_outer(mp_limb_t ** ii, mp_size_t n, + mp_bitcnt_t w, mp_limb_t ** t1, mp_limb_t ** t2, + mp_limb_t ** temp, mp_size_t n1, mp_size_t trunc) + + Just the outer layers of \code{fft_mfa_truncate_sqrt2}. + +void fft_mfa_truncate_sqrt2_inner(mp_limb_t ** ii, mp_limb_t ** jj, + mp_size_t n, mp_bitcnt_t w, mp_limb_t ** t1, mp_limb_t ** t2, + mp_limb_t ** temp, mp_size_t n1, mp_size_t trunc, mp_limb_t * tt) + + The inner layers of \code{fft_mfa_truncate_sqrt2} and + \code{ifft_mfa_truncate_sqrt2} combined with pointwise mults. + +void ifft_mfa_truncate_sqrt2_outer(mp_limb_t ** ii, mp_size_t n, + mp_bitcnt_t w, mp_limb_t ** t1, mp_limb_t ** t2, + mp_limb_t ** temp, mp_size_t n1, mp_size_t trunc) + + The outer layers of \code{ifft_mfa_truncate_sqrt2} combined with + normalisation. + +******************************************************************************* + + Negacyclic multiplication + +******************************************************************************* + +void fft_negacyclic(mp_limb_t ** ii, mp_size_t n, mp_bitcnt_t w, + mp_limb_t ** t1, mp_limb_t ** t2, mp_limb_t ** temp) + + As per \code{fft_radix2} except that it performs a sqrt2 negacyclic + transform of length $2n$. This is the same as the radix 2 transform + except that the $i$-th coefficient of the input is first multiplied by + $\sqrt{2}^{iw}$. + + We require $nw$ to be at least 64 and the two temporary space pointers to + point to blocks of size \code{n*w + FLINT_BITS} bits. + +void ifft_negacyclic(mp_limb_t ** ii, mp_size_t n, mp_bitcnt_t w, + mp_limb_t ** t1, mp_limb_t ** t2, mp_limb_t ** temp) + + As per \code{ifft_radix2} except that it performs a sqrt2 negacyclic + inverse transform of length $2n$. This is the same as the radix 2 inverse + transform except that the $i$-th coefficient of the output is finally + divided by $\sqrt{2}^{iw}$. + + We require $nw$ to be at least 64 and the two temporary space pointers to + point to blocks of size \code{n*w + FLINT_BITS} bits. + +void fft_naive_convolution_1(mp_limb_t * r, mp_limb_t * ii, + mp_limb_t * jj, mp_size_t m) + + Performs a naive negacyclic convolution of \code{ii} with \code{jj}, + both of length $m$ and sets $r$ to the result. This is essentially + multiplication of polynomials modulo $x^m + 1$. + +void _fft_mulmod_2expp1(mp_limb_t * r1, mp_limb_t * i1, mp_limb_t * i2, + mp_size_t r_limbs, mp_bitcnt_t depth, mp_bitcnt_t w) + + Multiply \code{i1} by \code{i2} modulo \code{B^r_limbs + 1} where + \code{r_limbs = nw/FLINT_BITS} with \code{n = 2^depth}. Uses the + negacyclic FFT convolution CRT'd with a 1 limb naive convolution. We + require that \code{depth} and \code{w} have been selected as per the + wrapper \code{fft_mulmod_2expp1} below. + +slong fft_adjust_limbs(mp_size_t limbs) + + Given a number of limbs, returns a new number of limbs (no more than + the next power of 2) which will work with the Nussbaumer code. It is only + necessary to make this adjustment if + \code{limbs > FFT_MULMOD_2EXPP1_CUTOFF}. + +void fft_mulmod_2expp1(mp_limb_t * r, mp_limb_t * i1, mp_limb_t * i2, + mp_size_t n, mp_size_t w, mp_limb_t * tt) + + As per \code{_fft_mulmod_2expp1} but with a tuned cutoff below which more + classical methods are used for the convolution. The temporary space is + required to fit \code{n*w + FLINT_BITS} bits. There are no restrictions + on $n$, but if \code{limbs = n*w/FLINT_BITS} then if \code{limbs} exceeds + \code{FFT_MULMOD_2EXPP1_CUTOFF} the function \code{fft_adjust_limbs} must + be called to increase the number of limbs to an appropriate value. + +******************************************************************************* + + Integer multiplication + +******************************************************************************* + +void mul_truncate_sqrt2(mp_ptr r1, mp_srcptr i1, mp_size_t n1, + mp_srcptr i2, mp_size_t n2, mp_bitcnt_t depth, mp_bitcnt_t w) + + Integer multiplication using the radix 2 truncated sqrt2 transforms. + + Set \code{(r1, n1 + n2)} to the product of \code{(i1, n1)} by + \code{(i2, n2)}. This is achieved through an FFT convolution of length at + most \code{2^(depth + 2)} with coefficients of size $nw$ bits where + \code{n = 2^depth}. We require \code{depth >= 6}. The input data is + broken into chunks of data not exceeding \code{(nw - (depth + 1))/2} + bits. If breaking the first integer into chunks of this size results in + \code{j1} coefficients and breaking the second integer results in + \code{j2} chunks then \code{j1 + j2 - 1 <= 2^(depth + 2)}. + + If \code{n = 2^depth} then we require $nw$ to be at least 64. + +void mul_mfa_truncate_sqrt2(mp_ptr r1, mp_srcptr i1, mp_size_t n1, + mp_srcptr i2, mp_size_t n2, mp_bitcnt_t depth, mp_bitcnt_t w) + + As for \code{mul_truncate_sqrt2} except that the cache friendly matrix + fourier algorithm is used. + + If \code{n = 2^depth} then we require $nw$ to be at least 64. Here we + also require $w$ to be $2^i$ for some $i \geq 0$. + +void flint_mpn_mul_fft_main(mp_ptr r1, mp_srcptr i1, mp_size_t n1, + mp_srcptr i2, mp_size_t n2) + + The main integer multiplication routine. Sets \code{(r1, n1 + n2)} to + \code{(i1, n1)} times \code{(i2, n2)}. We require \code{n1 >= n2 > 0}. + +******************************************************************************* + + Convolution + +******************************************************************************* + +void fft_convolution(mp_limb_t ** ii, mp_limb_t ** jj, slong depth, + slong limbs, slong trunc, mp_limb_t ** t1, + mp_limb_t ** t2, mp_limb_t ** s1, mp_limb_t * tt) + + Perform an FFT convolution of \code{ii} with \code{jj}, both of length + \code{4*n} where \code{n = 2^depth}. Assume that all but the first + \code{trunc} coefficients of the output (placed in \code{ii}) are zero. + Each coefficient is taken modulo \code{B^limbs + 1}. The temporary + spaces \code{t1}, \code{t2} and \code{s1} must have \code{limbs + 1} + limbs of space and \code{tt} must have \code{2*(limbs + 1)} of free + space. diff --git a/external/flint-2.4.3/fft/fermat_to_mpz.c b/external/flint-2.4.3/fft/fermat_to_mpz.c new file mode 100644 index 0000000..3b9d6d0 --- /dev/null +++ b/external/flint-2.4.3/fft/fermat_to_mpz.c @@ -0,0 +1,55 @@ +/* + +Copyright 2009, 2011 William Hart. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY William Hart ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL William Hart OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those of the +authors and should not be interpreted as representing official policies, either expressed +or implied, of William Hart. + +*/ + +#include "gmp.h" +#include "flint.h" +#include "fft.h" + +void fermat_to_mpz(mpz_t m, mp_limb_t * i, mp_size_t limbs) +{ + mp_limb_signed_t hi; + + mpz_realloc(m, limbs + 1); + flint_mpn_copyi(m->_mp_d, i, limbs + 1); + hi = i[limbs]; + if (hi < WORD(0)) + { + mpn_neg_n(m->_mp_d, m->_mp_d, limbs + 1); + m->_mp_size = limbs + 1; + while ((m->_mp_size) && (!m->_mp_d[m->_mp_size - 1])) + m->_mp_size--; + m->_mp_size = -m->_mp_size; + } else + { + m->_mp_size = limbs + 1; + while ((m->_mp_size) && (!m->_mp_d[m->_mp_size - 1])) + m->_mp_size--; + } +} diff --git a/external/flint-2.4.3/fft/fft_mfa_truncate_sqrt2.c b/external/flint-2.4.3/fft/fft_mfa_truncate_sqrt2.c new file mode 100644 index 0000000..007bda0 --- /dev/null +++ b/external/flint-2.4.3/fft/fft_mfa_truncate_sqrt2.c @@ -0,0 +1,325 @@ +/* + +Copyright 2009, 2011 William Hart. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY William Hart ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL William Hart OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those of the +authors and should not be interpreted as representing official policies, either expressed +or implied, of William Hart. + +*/ + +#include "gmp.h" +#include "flint.h" +#include "ulong_extras.h" +#include "fft.h" + +void fft_butterfly_twiddle(mp_limb_t * u, mp_limb_t * v, + mp_limb_t * s, mp_limb_t * t, mp_size_t limbs, mp_bitcnt_t b1, mp_bitcnt_t b2) +{ + mp_limb_t nw = limbs*FLINT_BITS; + mp_size_t x, y; + int negate1 = 0; + int negate2 = 0; + + if (b1 >= nw) + { + negate2 = 1; + b1 -= nw; + } + x = b1/FLINT_BITS; + b1 = b1%FLINT_BITS; + + if (b2 >= nw) + { + negate1 = 1; + b2 -= nw; + } + y = b2/FLINT_BITS; + b2 = b2%FLINT_BITS; + + butterfly_lshB(u, v, s, t, limbs, x, y); + mpn_mul_2expmod_2expp1(u, u, limbs, b1); + if (negate2) mpn_neg_n(u, u, limbs + 1); + mpn_mul_2expmod_2expp1(v, v, limbs, b2); + if (negate1) mpn_neg_n(v, v, limbs + 1); +} + +void fft_radix2_twiddle(mp_limb_t ** ii, mp_size_t is, + mp_size_t n, mp_bitcnt_t w, mp_limb_t ** t1, mp_limb_t ** t2, + mp_size_t ws, mp_size_t r, mp_size_t c, mp_size_t rs) +{ + mp_size_t i; + mp_size_t limbs = (w*n)/FLINT_BITS; + + if (n == 1) + { + mp_size_t tw1 = r*c; + mp_size_t tw2 = tw1 + rs*c; + fft_butterfly_twiddle(*t1, *t2, ii[0], ii[is], limbs, tw1*ws, tw2*ws); + + SWAP_PTRS(ii[0], *t1); + SWAP_PTRS(ii[is], *t2); + + return; + } + + for (i = 0; i < n; i++) + { + fft_butterfly(*t1, *t2, ii[i*is], ii[(n+i)*is], i, limbs, w); + + SWAP_PTRS(ii[i*is], *t1); + SWAP_PTRS(ii[(n+i)*is], *t2); + } + + fft_radix2_twiddle(ii, is, n/2, 2*w, t1, t2, ws, r, c, 2*rs); + fft_radix2_twiddle(ii+n*is, is, n/2, 2*w, t1, t2, ws, r + rs, c, 2*rs); +} + +void fft_truncate1_twiddle(mp_limb_t ** ii, mp_size_t is, + mp_size_t n, mp_bitcnt_t w, mp_limb_t ** t1, mp_limb_t ** t2, + mp_size_t ws, mp_size_t r, mp_size_t c, mp_size_t rs, mp_size_t trunc) +{ + mp_size_t i; + mp_size_t limbs = (w*n)/FLINT_BITS; + + if (trunc == 2*n) + fft_radix2_twiddle(ii, is, n, w, t1, t2, ws, r, c, rs); + else if (trunc <= n) + { + for (i = 0; i < n; i++) + mpn_add_n(ii[i*is], ii[i*is], ii[(i+n)*is], limbs + 1); + + fft_truncate1_twiddle(ii, is, n/2, 2*w, t1, t2, ws, r, c, 2*rs, trunc); + } else + { + for (i = 0; i < n; i++) + { + fft_butterfly(*t1, *t2, ii[i*is], ii[(n+i)*is], i, limbs, w); + + SWAP_PTRS(ii[i*is], *t1); + SWAP_PTRS(ii[(n+i)*is], *t2); + } + + fft_radix2_twiddle(ii, is, n/2, 2*w, t1, t2, ws, r, c, 2*rs); + fft_truncate1_twiddle(ii + n*is, is, n/2, 2*w, + t1, t2, ws, r + rs, c, 2*rs, trunc - n); + } +} + +void fft_mfa_truncate_sqrt2(mp_limb_t ** ii, mp_size_t n, + mp_bitcnt_t w, mp_limb_t ** t1, mp_limb_t ** t2, + mp_limb_t ** temp, mp_size_t n1, mp_size_t trunc) +{ + mp_size_t i, j, s; + mp_size_t n2 = (2*n)/n1; + mp_size_t trunc2 = (trunc - 2*n)/n1; + mp_size_t limbs = (n*w)/FLINT_BITS; + mp_bitcnt_t depth = 0; + mp_bitcnt_t depth2 = 0; + + while ((UWORD(1)< w bits + */ + + fft_radix2_twiddle(ii + i, n1, n2/2, w*n1, t1, t2, w, 0, i, 1); + for (j = 0; j < n2; j++) + { + mp_size_t s = n_revbin(j, depth); + if (j < s) SWAP_PTRS(ii[i+j*n1], ii[i+s*n1]); + } + } + + /* FFTs on rows */ + for (i = 0; i < n2; i++) + { + fft_radix2(ii + i*n1, n1/2, w*n2, t1, t2); + for (j = 0; j < n1; j++) + { + mp_size_t t = n_revbin(j, depth2); + if (j < t) SWAP_PTRS(ii[i*n1+j], ii[i*n1+t]); + } + } + + /* second half matrix fourier FFT : n2 rows, n1 cols */ + ii += 2*n; + + /* FFTs on columns */ + for (i = 0; i < n1; i++) + { + /* + FFT of length n2 on column i, applying z^{r*i} for rows going up in steps + of 1 starting at row 0, where z => w bits + */ + + fft_truncate1_twiddle(ii + i, n1, n2/2, w*n1, t1, t2, w, 0, i, 1, trunc2); + for (j = 0; j < n2; j++) + { + mp_size_t s = n_revbin(j, depth); + if (j < s) SWAP_PTRS(ii[i+j*n1], ii[i+s*n1]); + } + } + + /* FFTs on relevant rows */ + for (s = 0; s < trunc2; s++) + { + i = n_revbin(s, depth); + fft_radix2(ii + i*n1, n1/2, w*n2, t1, t2); + + for (j = 0; j < n1; j++) + { + mp_size_t t = n_revbin(j, depth2); + if (j < t) SWAP_PTRS(ii[i*n1+j], ii[i*n1+t]); + } + } +} + +void fft_mfa_truncate_sqrt2_outer(mp_limb_t ** ii, mp_size_t n, + mp_bitcnt_t w, mp_limb_t ** t1, mp_limb_t ** t2, + mp_limb_t ** temp, mp_size_t n1, mp_size_t trunc) +{ + mp_size_t i, j; + mp_size_t n2 = (2*n)/n1; + mp_size_t trunc2 = (trunc - 2*n)/n1; + mp_size_t limbs = (n*w)/FLINT_BITS; + mp_bitcnt_t depth = 0; + mp_bitcnt_t depth2 = 0; + + while ((UWORD(1)< w bits + */ + + fft_radix2_twiddle(ii + i, n1, n2/2, w*n1, t1, t2, w, 0, i, 1); + for (j = 0; j < n2; j++) + { + mp_size_t s = n_revbin(j, depth); + if (j < s) SWAP_PTRS(ii[i+j*n1], ii[i+s*n1]); + } + } + + /* second half matrix fourier FFT : n2 rows, n1 cols */ + ii += 2*n; + + /* FFTs on columns */ + for (i = 0; i < n1; i++) + { + /* + FFT of length n2 on column i, applying z^{r*i} for rows going up in steps + of 1 starting at row 0, where z => w bits + */ + + fft_truncate1_twiddle(ii + i, n1, n2/2, w*n1, t1, t2, w, 0, i, 1, trunc2); + for (j = 0; j < n2; j++) + { + mp_size_t s = n_revbin(j, depth); + if (j < s) SWAP_PTRS(ii[i+j*n1], ii[i+s*n1]); + } + } +} diff --git a/external/flint-2.4.3/fft/fft_mfa_truncate_sqrt2_inner.c b/external/flint-2.4.3/fft/fft_mfa_truncate_sqrt2_inner.c new file mode 100644 index 0000000..7974e1b --- /dev/null +++ b/external/flint-2.4.3/fft/fft_mfa_truncate_sqrt2_inner.c @@ -0,0 +1,91 @@ +/* + +Copyright 2009, 2011 William Hart. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY William Hart ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL William Hart OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those of the +authors and should not be interpreted as representing official policies, either expressed +or implied, of William Hart. + +*/ + +#include "gmp.h" +#include "flint.h" +#include "ulong_extras.h" +#include "fft.h" + +void fft_mfa_truncate_sqrt2_inner(mp_limb_t ** ii, mp_limb_t ** jj, mp_size_t n, + mp_bitcnt_t w, mp_limb_t ** t1, mp_limb_t ** t2, + mp_limb_t ** temp, mp_size_t n1, mp_size_t trunc, mp_limb_t * tt) +{ + mp_size_t i, j, s; + mp_size_t n2 = (2*n)/n1; + mp_size_t trunc2 = (trunc - 2*n)/n1; + mp_size_t limbs = (n*w)/FLINT_BITS; + mp_bitcnt_t depth = 0; + mp_bitcnt_t depth2 = 0; + + while ((UWORD(1)<= wn) + { + negate = 1; + b1 -= wn; + } + y = b1/FLINT_BITS; + b1 = b1%FLINT_BITS; + + /* sumdiff and multiply by 2^{j + wn/4 + i*k} */ + butterfly_lshB(s, t, i1, i2, limbs, 0, y); + mpn_mul_2expmod_2expp1(t, t, limbs, b1); + + /* multiply by 2^{wn/2} */ + y = limbs/2; + + flint_mpn_copyi(temp + y, t, limbs - y); + temp[limbs] = 0; + if (y) cy = mpn_neg_n(temp, t + limbs - y, y); + mpn_addmod_2expp1_1(temp + y, limbs - y, -t[limbs]); + mpn_sub_1(temp + y, temp + y, limbs - y + 1, cy); + + /* shift by an additional half limb (rare) */ + if (limbs & 1) + mpn_mul_2expmod_2expp1(temp, temp, limbs, FLINT_BITS/2); + + /* subtract */ + if (negate) + mpn_sub_n(t, t, temp, limbs + 1); + else + mpn_sub_n(t, temp, t, limbs + 1); +} + +void fft_truncate_sqrt2(mp_limb_t ** ii, mp_size_t n, mp_bitcnt_t w, + mp_limb_t ** t1, mp_limb_t ** t2, mp_limb_t ** temp, mp_size_t trunc) +{ + mp_size_t i; + mp_size_t limbs = (w*n)/GMP_LIMB_BITS; + + if ((w & 1) == 0) + { + fft_truncate(ii, 2*n, w/2, t1, t2, trunc); + return; + } + + for (i = 0; i < trunc - 2*n; i++) + { + fft_butterfly(*t1, *t2, ii[i], ii[2*n+i], i/2, limbs, w); + + SWAP_PTRS(ii[i], *t1); + SWAP_PTRS(ii[i+2*n], *t2); + + i++; + + fft_butterfly_sqrt2(*t1, *t2, ii[i], ii[2*n+i], i, limbs, w, *temp); + + SWAP_PTRS(ii[i], *t1); + SWAP_PTRS(ii[2*n+i], *t2); + } + + for (i = trunc - 2*n; i < 2*n; i++) + { + fft_adjust(ii[i+2*n], ii[i], i/2, limbs, w); + + i++; + + fft_adjust_sqrt2(ii[i+2*n], ii[i], i, limbs, w, *temp); + } + + fft_radix2(ii, n, w, t1, t2); + fft_truncate1(ii + 2*n, n, w, t1, t2, trunc - 2*n); +} diff --git a/external/flint-2.4.3/fft/ifft_mfa_truncate_sqrt2.c b/external/flint-2.4.3/fft/ifft_mfa_truncate_sqrt2.c new file mode 100644 index 0000000..7bedccd --- /dev/null +++ b/external/flint-2.4.3/fft/ifft_mfa_truncate_sqrt2.c @@ -0,0 +1,370 @@ +/* + +Copyright 2009, 2011 William Hart. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY William Hart ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL William Hart OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those of the +authors and should not be interpreted as representing official policies, either expressed +or implied, of William Hart. + +*/ + +#include "gmp.h" +#include "flint.h" +#include "ulong_extras.h" +#include "fft.h" + +void ifft_butterfly_twiddle(mp_limb_t * u, mp_limb_t * v, + mp_limb_t * s, mp_limb_t * t, mp_size_t limbs, mp_bitcnt_t b1, mp_bitcnt_t b2) +{ + mp_limb_t nw = limbs*FLINT_BITS; + mp_size_t x, y; + int negate1 = 0; + int negate2 = 0; + + if (b1 >= nw) + { + negate1 = 1; + b1 -= nw; + } + x = b1/FLINT_BITS; + b1 = b1%FLINT_BITS; + + if (b2 >= nw) + { + negate2 = 1; + b2 -= nw; + } + y = b2/FLINT_BITS; + b2 = b2%FLINT_BITS; + + if (negate1) mpn_neg_n(s, s, limbs + 1); + mpn_div_2expmod_2expp1(s, s, limbs, b1); + if (negate2) mpn_neg_n(t, t, limbs + 1); + mpn_div_2expmod_2expp1(t, t, limbs, b2); + butterfly_rshB(u, v, s, t, limbs, x, y); +} + +void ifft_radix2_twiddle(mp_limb_t ** ii, mp_size_t is, + mp_size_t n, mp_bitcnt_t w, mp_limb_t ** t1, mp_limb_t ** t2, + mp_size_t ws, mp_size_t r, mp_size_t c, mp_size_t rs) +{ + mp_size_t i; + mp_size_t limbs = (w*n)/FLINT_BITS; + + if (n == 1) + { + mp_size_t tw1, tw2; + tw1 = r*c; + tw2 = tw1 + rs*c; + ifft_butterfly_twiddle(*t1, *t2, ii[0], ii[is], limbs, tw1*ws, tw2*ws); + + SWAP_PTRS(ii[0], *t1); + SWAP_PTRS(ii[is], *t2); + + return; + } + + ifft_radix2_twiddle(ii, is, n/2, 2*w, t1, t2, ws, r, c, 2*rs); + ifft_radix2_twiddle(ii+n*is, is, n/2, 2*w, t1, t2, ws, r + rs, c, 2*rs); + + for (i = 0; i < n; i++) + { + ifft_butterfly(*t1, *t2, ii[i*is], ii[(n+i)*is], i, limbs, w); + + SWAP_PTRS(ii[i*is], *t1); + SWAP_PTRS(ii[(n+i)*is], *t2); + } +} + +void ifft_truncate1_twiddle(mp_limb_t ** ii, mp_size_t is, + mp_size_t n, mp_bitcnt_t w, mp_limb_t ** t1, mp_limb_t ** t2, + mp_size_t ws, mp_size_t r, mp_size_t c, mp_size_t rs, mp_size_t trunc) +{ + mp_size_t i; + mp_size_t limbs = (w*n)/FLINT_BITS; + + if (trunc == 2*n) + ifft_radix2_twiddle(ii, is, n, w, t1, t2, ws, r, c, rs); + else if (trunc <= n) + { + for (i = trunc; i < n; i++) + { + mpn_add_n(ii[i*is], ii[i*is], ii[(i+n)*is], limbs + 1); + mpn_div_2expmod_2expp1(ii[i*is], ii[i*is], limbs, 1); + } + + ifft_truncate1_twiddle(ii, is, n/2, 2*w, t1, t2, ws, r, c, 2*rs, trunc); + + for (i = 0; i < trunc; i++) + { +#if HAVE_ADDSUB_N + mpn_addsub_n(ii[i*is], ii[i*is], ii[i*is], ii[(n+i)*is], limbs + 1); +#else + mpn_add_n(ii[i*is], ii[i*is], ii[i*is], limbs + 1); + mpn_sub_n(ii[i*is], ii[i*is], ii[(n+i)*is], limbs + 1); +#endif + } + } else + { + ifft_radix2_twiddle(ii, is, n/2, 2*w, t1, t2, ws, r, c, 2*rs); + + for (i = trunc - n; i < n; i++) + { + mpn_sub_n(ii[(i+n)*is], ii[i*is], ii[(i+n)*is], limbs + 1); + fft_adjust(*t1, ii[(i+n)*is], i, limbs, w); + mpn_add_n(ii[i*is], ii[i*is], ii[(i+n)*is], limbs + 1); + SWAP_PTRS(ii[(i+n)*is], *t1); + } + + ifft_truncate1_twiddle(ii + n*is, is, n/2, 2*w, t1, t2, ws, r + rs, c, 2*rs, trunc - n); + + for (i = 0; i < trunc - n; i++) + { + ifft_butterfly(*t1, *t2, ii[i*is], ii[(n+i)*is], i, limbs, w); + + SWAP_PTRS(ii[i*is], *t1); + SWAP_PTRS(ii[(n+i)*is], *t2); + } + } +} + +void ifft_mfa_truncate_sqrt2(mp_limb_t ** ii, mp_size_t n, mp_bitcnt_t w, + mp_limb_t ** t1, mp_limb_t ** t2, mp_limb_t ** temp, mp_size_t n1, mp_size_t trunc) +{ + mp_size_t i, j, s; + mp_size_t n2 = (2*n)/n1; + mp_size_t trunc2 = (trunc - 2*n)/n1; + mp_bitcnt_t depth = 0; + mp_bitcnt_t depth2 = 0; + mp_bitcnt_t limbs = (w*n)/FLINT_BITS; + + while ((UWORD(1)< w bits + */ + ifft_radix2_twiddle(ii + i, n1, n2/2, w*n1, t1, t2, w, 0, i, 1); + } + + /* second half IFFT : n2 rows, n1 cols */ + ii += 2*n; + + /* row IFFTs */ + for (s = 0; s < trunc2; s++) + { + i = n_revbin(s, depth); + for (j = 0; j < n1; j++) + { + mp_size_t t = n_revbin(j, depth2); + if (j < t) SWAP_PTRS(ii[i*n1+j], ii[i*n1+t]); + } + + ifft_radix2(ii + i*n1, n1/2, w*n2, t1, t2); + } + + /* column IFFTs with relevant sqrt2 layer butterflies combined */ + for (i = 0; i < n1; i++) + { + for (j = 0; j < trunc2; j++) + { + mp_size_t s = n_revbin(j, depth); + if (j < s) SWAP_PTRS(ii[i+j*n1], ii[i+s*n1]); + } + + for ( ; j < n2; j++) + { + mp_size_t u = i + j*n1; + if (w & 1) + { + if (i & 1) + fft_adjust_sqrt2(ii[i + j*n1], ii[u - 2*n], u, limbs, w, *temp); + else + fft_adjust(ii[i + j*n1], ii[u - 2*n], u/2, limbs, w); + } else + fft_adjust(ii[i + j*n1], ii[u - 2*n], u, limbs, w/2); + } + + /* + IFFT of length n2 on column i, applying z^{r*i} for rows going up in steps + of 1 starting at row 0, where z => w bits + */ + ifft_truncate1_twiddle(ii + i, n1, n2/2, w*n1, t1, t2, w, 0, i, 1, trunc2); + + /* relevant components of final sqrt2 layer of IFFT */ + if (w & 1) + { + for (j = i; j < trunc - 2*n; j+=n1) + { + if (j & 1) + ifft_butterfly_sqrt2(*t1, *t2, ii[j - 2*n], ii[j], j, limbs, w, *temp); + else + ifft_butterfly(*t1, *t2, ii[j - 2*n], ii[j], j/2, limbs, w); + + SWAP_PTRS(ii[j-2*n], *t1); + SWAP_PTRS(ii[j], *t2); + } + } else + { + for (j = i; j < trunc - 2*n; j+=n1) + { + ifft_butterfly(*t1, *t2, ii[j - 2*n], ii[j], j, limbs, w/2); + + SWAP_PTRS(ii[j-2*n], *t1); + SWAP_PTRS(ii[j], *t2); + } + } + + for (j = trunc + i - 2*n; j < 2*n; j+=n1) + mpn_add_n(ii[j - 2*n], ii[j - 2*n], ii[j - 2*n], limbs + 1); + } +} + +void ifft_mfa_truncate_sqrt2_outer(mp_limb_t ** ii, mp_size_t n, mp_bitcnt_t w, + mp_limb_t ** t1, mp_limb_t ** t2, mp_limb_t ** temp, mp_size_t n1, mp_size_t trunc) +{ + mp_size_t i, j; + mp_size_t n2 = (2*n)/n1; + mp_size_t trunc2 = (trunc - 2*n)/n1; + mp_bitcnt_t depth = 0; + mp_bitcnt_t depth2 = 0; + mp_bitcnt_t limbs = (w*n)/FLINT_BITS; + + while ((UWORD(1)< w bits + */ + ifft_radix2_twiddle(ii + i, n1, n2/2, w*n1, t1, t2, w, 0, i, 1); + } + + /* second half IFFT : n2 rows, n1 cols */ + ii += 2*n; + + /* column IFFTs with relevant sqrt2 layer butterflies combined */ + for (i = 0; i < n1; i++) + { + for (j = 0; j < trunc2; j++) + { + mp_size_t s = n_revbin(j, depth); + if (j < s) SWAP_PTRS(ii[i+j*n1], ii[i+s*n1]); + } + + for ( ; j < n2; j++) + { + mp_size_t u = i + j*n1; + if (w & 1) + { + if (i & 1) + fft_adjust_sqrt2(ii[i + j*n1], ii[u - 2*n], u, limbs, w, *temp); + else + fft_adjust(ii[i + j*n1], ii[u - 2*n], u/2, limbs, w); + } else + fft_adjust(ii[i + j*n1], ii[u - 2*n], u, limbs, w/2); + } + + /* + IFFT of length n2 on column i, applying z^{r*i} for rows going up in steps + of 1 starting at row 0, where z => w bits + */ + ifft_truncate1_twiddle(ii + i, n1, n2/2, w*n1, t1, t2, w, 0, i, 1, trunc2); + + /* relevant components of final sqrt2 layer of IFFT */ + if (w & 1) + { + for (j = i; j < trunc - 2*n; j+=n1) + { + if (j & 1) + ifft_butterfly_sqrt2(*t1, *t2, ii[j - 2*n], ii[j], j, limbs, w, *temp); + else + ifft_butterfly(*t1, *t2, ii[j - 2*n], ii[j], j/2, limbs, w); + + SWAP_PTRS(ii[j-2*n], *t1); + SWAP_PTRS(ii[j], *t2); + } + } else + { + for (j = i; j < trunc - 2*n; j+=n1) + { + ifft_butterfly(*t1, *t2, ii[j - 2*n], ii[j], j, limbs, w/2); + + SWAP_PTRS(ii[j-2*n], *t1); + SWAP_PTRS(ii[j], *t2); + } + } + + for (j = trunc + i - 2*n; j < 2*n; j+=n1) + mpn_add_n(ii[j - 2*n], ii[j - 2*n], ii[j - 2*n], limbs + 1); + + for (j = 0; j < trunc2; j++) + { + mp_size_t t = j*n1 + i; + mpn_div_2expmod_2expp1(ii[t], ii[t], limbs, depth + depth2 + 1); + mpn_normmod_2expp1(ii[t], limbs); + } + + for (j = 0; j < n2; j++) + { + mp_size_t t = j*n1 + i - 2*n; + mpn_div_2expmod_2expp1(ii[t], ii[t], limbs, depth + depth2 + 1); + mpn_normmod_2expp1(ii[t], limbs); + } + } +} diff --git a/external/flint-2.4.3/fft/ifft_negacyclic.c b/external/flint-2.4.3/fft/ifft_negacyclic.c new file mode 100644 index 0000000..f253b38 --- /dev/null +++ b/external/flint-2.4.3/fft/ifft_negacyclic.c @@ -0,0 +1,92 @@ +/* + +Copyright 2009, 2011 William Hart. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY William Hart ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL William Hart OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those of the +authors and should not be interpreted as representing official policies, either expressed +or implied, of William Hart. + +*/ + +#include "gmp.h" +#include "flint.h" +#include "fft.h" + +void ifft_negacyclic(mp_limb_t ** ii, mp_size_t n, mp_bitcnt_t w, + mp_limb_t ** t1, mp_limb_t ** t2, mp_limb_t ** temp) +{ + mp_size_t i; + mp_size_t limbs = (w*n)/FLINT_BITS; + + ifft_radix2(ii, n/2, 2*w, t1, t2); + ifft_radix2(ii+n, n/2, 2*w, t1, t2); + + if (w & 1) + { + for (i = 0; i < n; i++) + { + ifft_butterfly(*t1, *t2, ii[i], ii[n+i], i, limbs, w); + SWAP_PTRS(ii[i], *t1); + SWAP_PTRS(ii[n+i], *t2); + + fft_adjust(*t1, ii[i], n - i/2, limbs, w); + mpn_neg_n(*t1, *t1, limbs + 1); + SWAP_PTRS(ii[i], *t1); + + fft_adjust(*t2, ii[n+i], n - (n+i)/2, limbs, w); + mpn_neg_n(*t2, *t2, limbs + 1); + SWAP_PTRS(ii[n+i], *t2); + + i++; + + ifft_butterfly(*t1, *t2, ii[i], ii[n+i], i, limbs, w); + SWAP_PTRS(ii[i], *t1); + SWAP_PTRS(ii[n+i], *t2); + + fft_adjust_sqrt2(*t1, ii[i], 2*n-i, limbs, w, *temp); + mpn_neg_n(*t1, *t1, limbs + 1); + SWAP_PTRS(ii[i], *t1); + + fft_adjust_sqrt2(*t2, ii[n+i], n-i, limbs, w, *temp); + mpn_neg_n(*t2, *t2, limbs + 1); + SWAP_PTRS(ii[n+i], *t2); + } + } else + { + for (i = 0; i < n; i++) + { + ifft_butterfly(*t1, *t2, ii[i], ii[n+i], i, limbs, w); + SWAP_PTRS(ii[i], *t1); + SWAP_PTRS(ii[n+i], *t2); + + fft_adjust(*t1, ii[i], 2*n-i, limbs, w/2); + mpn_neg_n(*t1, *t1, limbs + 1); + SWAP_PTRS(ii[i], *t1); + + fft_adjust(*t2, ii[n+i], n-i, limbs, w/2); + mpn_neg_n(*t2, *t2, limbs + 1); + SWAP_PTRS(ii[n+i], *t2); + } + } +} + diff --git a/external/flint-2.4.3/fft/ifft_radix2.c b/external/flint-2.4.3/fft/ifft_radix2.c new file mode 100644 index 0000000..7486e9a --- /dev/null +++ b/external/flint-2.4.3/fft/ifft_radix2.c @@ -0,0 +1,75 @@ +/* + +Copyright 2009, 2011 William Hart. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY William Hart ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL William Hart OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those of the +authors and should not be interpreted as representing official policies, either expressed +or implied, of William Hart. + +*/ + +#include "gmp.h" +#include "flint.h" +#include "fft.h" + +void ifft_butterfly(mp_limb_t * s, mp_limb_t * t, mp_limb_t * i1, + mp_limb_t * i2, mp_size_t i, mp_size_t limbs, mp_bitcnt_t w) +{ + mp_size_t y; + mp_bitcnt_t b1; + + b1 = i*w; + y = b1/FLINT_BITS; + b1 = b1%FLINT_BITS; + + mpn_div_2expmod_2expp1(i2, i2, limbs, b1); + butterfly_rshB(s, t, i1, i2, limbs, 0, y); +} + +void ifft_radix2(mp_limb_t ** ii, mp_size_t n, + mp_bitcnt_t w, mp_limb_t ** t1, mp_limb_t ** t2) +{ + mp_size_t i; + mp_size_t limbs = (w*n)/FLINT_BITS; + + if (n == 1) + { + ifft_butterfly(*t1, *t2, ii[0], ii[1], 0, limbs, w); + + SWAP_PTRS(ii[0], *t1); + SWAP_PTRS(ii[1], *t2); + + return; + } + + ifft_radix2(ii, n/2, 2*w, t1, t2); + ifft_radix2(ii+n, n/2, 2*w, t1, t2); + + for (i = 0; i < n; i++) + { + ifft_butterfly(*t1, *t2, ii[i], ii[n+i], i, limbs, w); + + SWAP_PTRS(ii[i], *t1); + SWAP_PTRS(ii[n+i], *t2); + } +} diff --git a/external/flint-2.4.3/fft/ifft_truncate.c b/external/flint-2.4.3/fft/ifft_truncate.c new file mode 100644 index 0000000..15b0f2d --- /dev/null +++ b/external/flint-2.4.3/fft/ifft_truncate.c @@ -0,0 +1,120 @@ +/* + +Copyright 2009, 2011 William Hart. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY William Hart ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL William Hart OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those of the +authors and should not be interpreted as representing official policies, either expressed +or implied, of William Hart. + +*/ + +#include "gmp.h" +#include "flint.h" +#include "fft.h" + +void ifft_truncate1(mp_limb_t ** ii, mp_size_t n, mp_bitcnt_t w, + mp_limb_t ** t1, mp_limb_t ** t2, mp_size_t trunc) +{ + mp_size_t i; + mp_size_t limbs = (w*n)/FLINT_BITS; + + if (trunc == 2*n) + ifft_radix2(ii, n, w, t1, t2); + else if (trunc <= n) + { + for (i = trunc; i < n; i++) + { + mpn_add_n(ii[i], ii[i], ii[i+n], limbs + 1); + mpn_div_2expmod_2expp1(ii[i], ii[i], limbs, 1); + } + + ifft_truncate1(ii, n/2, 2*w, t1, t2, trunc); + + for (i = 0; i < trunc; i++) + { +#if HAVE_ADDSUB_N + mpn_addsub_n(ii[i], ii[i], ii[i], ii[n+i], limbs + 1); +#else + mpn_add_n(ii[i], ii[i], ii[i], limbs + 1); + mpn_sub_n(ii[i], ii[i], ii[n+i], limbs + 1); +#endif + } + } else + { + ifft_radix2(ii, n/2, 2*w, t1, t2); + + for (i = trunc - n; i < n; i++) + { + mpn_sub_n(ii[i+n], ii[i], ii[i+n], limbs + 1); + fft_adjust(*t1, ii[i+n], i, limbs, w); + mpn_add_n(ii[i], ii[i], ii[i+n], limbs + 1); + SWAP_PTRS(ii[i+n], *t1); + } + + ifft_truncate1(ii+n, n/2, 2*w, t1, t2, trunc - n); + + for (i = 0; i < trunc - n; i++) + { + ifft_butterfly(*t1, *t2, ii[i], ii[n+i], i, limbs, w); + + SWAP_PTRS(ii[i], *t1); + SWAP_PTRS(ii[n+i], *t2); + } + } +} + +void ifft_truncate(mp_limb_t ** ii, mp_size_t n, mp_bitcnt_t w, + mp_limb_t ** t1, mp_limb_t ** t2, mp_size_t trunc) +{ + mp_size_t i; + mp_size_t limbs = (w*n)/GMP_LIMB_BITS; + + if (trunc == 2*n) + ifft_radix2(ii, n, w, t1, t2); + else if (trunc <= n) + { + ifft_truncate(ii, n/2, 2*w, t1, t2, trunc); + + for (i = 0; i < trunc; i++) + mpn_add_n(ii[i], ii[i], ii[i], limbs + 1); + } else + { + ifft_radix2(ii, n/2, 2*w, t1, t2); + + for (i = trunc - n; i < n; i++) + fft_adjust(ii[i+n], ii[i], i, limbs, w); + + ifft_truncate1(ii+n, n/2, 2*w, t1, t2, trunc - n); + + for (i = 0; i < trunc - n; i++) + { + ifft_butterfly(*t1, *t2, ii[i], ii[n+i], i, limbs, w); + + SWAP_PTRS(ii[i], *t1); + SWAP_PTRS(ii[n+i], *t2); + } + + for (i = trunc - n; i < n; i++) + mpn_add_n(ii[i], ii[i], ii[i], limbs + 1); + } +} diff --git a/external/flint-2.4.3/fft/ifft_truncate_sqrt2.c b/external/flint-2.4.3/fft/ifft_truncate_sqrt2.c new file mode 100644 index 0000000..876d19f --- /dev/null +++ b/external/flint-2.4.3/fft/ifft_truncate_sqrt2.c @@ -0,0 +1,121 @@ +/* + +Copyright 2009, 2011 William Hart. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY William Hart ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL William Hart OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those of the +authors and should not be interpreted as representing official policies, either expressed +or implied, of William Hart. + +*/ + +#include "gmp.h" +#include "flint.h" +#include "fft.h" + +void ifft_butterfly_sqrt2(mp_limb_t * s, mp_limb_t * t, mp_limb_t * i1, + mp_limb_t * i2, mp_size_t i, mp_size_t limbs, mp_bitcnt_t w, mp_limb_t * temp) +{ + mp_bitcnt_t wn = limbs*FLINT_BITS; + mp_limb_t cy = 0; + mp_size_t j = i/2, k = w/2; + mp_size_t y2, y; + mp_size_t b1; + int negate = 1; + + b1 = wn - j - i*k - 1 + wn/4; + if (b1 >= wn) + { + negate = 0; + b1 -= wn; + } + y2 = b1/GMP_LIMB_BITS; + b1 = b1%GMP_LIMB_BITS; + + /* multiply by small part of 2^{2*wn - j - ik - 1 + wn/4} */ + if (b1) mpn_mul_2expmod_2expp1(i2, i2, limbs, b1); + + /* multiply by 2^{wn/2} */ + y = limbs/2; + + flint_mpn_copyi(temp + y, i2, limbs - y); + temp[limbs] = 0; + if (y) cy = mpn_neg_n(temp, i2 + limbs - y, y); + mpn_addmod_2expp1_1(temp + y, limbs - y, -i2[limbs]); + mpn_sub_1(temp + y, temp + y, limbs - y + 1, cy); + + /* shift by an additional half limb (rare) */ + if (limbs & 1) + mpn_mul_2expmod_2expp1(temp, temp, limbs, FLINT_BITS/2); + + /* subtract and negate... */ + if (negate) mpn_sub_n(i2, temp, i2, limbs + 1); + else mpn_sub_n(i2, i2, temp, limbs + 1); + + /* ...negate and shift **left** by y2 limbs (i.e. shift right by + (size - y2) limbs) and sumdiff */ + butterfly_rshB(s, t, i1, i2, limbs, 0, limbs - y2); +} + +void ifft_truncate_sqrt2(mp_limb_t ** ii, mp_size_t n, mp_bitcnt_t w, + mp_limb_t ** t1, mp_limb_t ** t2, mp_limb_t ** temp, mp_size_t trunc) +{ + mp_size_t i; + mp_size_t limbs = (w*n)/FLINT_BITS; + + if ((w & 1) == 0) + { + ifft_truncate(ii, 2*n, w/2, t1, t2, trunc); + return; + } + + ifft_radix2(ii, n, w, t1, t2); + + for (i = trunc - 2*n; i < 2*n; i++) + { + fft_adjust(ii[i+2*n], ii[i], i/2, limbs, w); + + i++; + + fft_adjust_sqrt2(ii[i+2*n], ii[i], i, limbs, w, *temp); + } + + ifft_truncate1(ii + 2*n, n, w, t1, t2, trunc - 2*n); + + for (i = 0; i < trunc - 2*n; i++) + { + ifft_butterfly(*t1, *t2, ii[i], ii[2*n+i], i/2, limbs, w); + + SWAP_PTRS(ii[i], *t1); + SWAP_PTRS(ii[2*n+i], *t2); + + i++; + + ifft_butterfly_sqrt2(*t1, *t2, ii[i], ii[2*n+i], i, limbs, w, *temp); + + SWAP_PTRS(ii[i], *t1); + SWAP_PTRS(ii[2*n+i], *t2); + } + + for (i = trunc - 2*n; i < 2*n; i++) + mpn_add_n(ii[i], ii[i], ii[i], limbs + 1); +} diff --git a/external/flint-2.4.3/fft/mul_2expmod_2expp1.c b/external/flint-2.4.3/fft/mul_2expmod_2expp1.c new file mode 100644 index 0000000..83b215f --- /dev/null +++ b/external/flint-2.4.3/fft/mul_2expmod_2expp1.c @@ -0,0 +1,55 @@ +/* + +Copyright 2009, 2011 William Hart. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY William Hart ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL William Hart OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those of the +authors and should not be interpreted as representing official policies, either expressed +or implied, of William Hart. + +*/ + +#include "gmp.h" +#include "flint.h" +#include "fft.h" + +/* WARNING: relies on GCC's handling of >> as arithmetic shift right */ + +void mpn_mul_2expmod_2expp1(mp_limb_t * t, mp_limb_t * i1, mp_size_t limbs, mp_bitcnt_t d) +{ + mp_limb_signed_t hi1, hi2; + + if (d == 0) + { + if (t != i1) + flint_mpn_copyi(t, i1, limbs + 1); + } else + { + hi1 = ((mp_limb_signed_t) i1[limbs] >> (GMP_LIMB_BITS - d)); + mpn_lshift(t, i1, limbs + 1, d); + hi2 = t[limbs]; + t[limbs] = 0; + mpn_sub_1(t, t, limbs + 1, hi2); + mpn_addmod_2expp1_1(t + 1, limbs - 1, -hi1); + } +} + diff --git a/external/flint-2.4.3/fft/mul_fft_main.c b/external/flint-2.4.3/fft/mul_fft_main.c new file mode 100644 index 0000000..46eaac7 --- /dev/null +++ b/external/flint-2.4.3/fft/mul_fft_main.c @@ -0,0 +1,105 @@ +/* + +Copyright 2009, 2011 William Hart. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY William Hart ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL William Hart OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those of the +authors and should not be interpreted as representing official policies, either expressed +or implied, of William Hart. + +*/ + +#include "gmp.h" +#include "flint.h" +#include "fft.h" +#include "ulong_extras.h" +#include "fft_tuning.h" + +static int fft_tuning_table[5][2] = FFT_TAB; + +void flint_mpn_mul_fft_main(mp_ptr r1, mp_srcptr i1, mp_size_t n1, + mp_srcptr i2, mp_size_t n2) +{ + mp_size_t off, depth = 6; + mp_size_t w = 1; + mp_size_t n = ((mp_size_t) 1 << depth); + mp_bitcnt_t bits = (n*w - (depth+1))/2; + + mp_bitcnt_t bits1 = n1*FLINT_BITS; + mp_bitcnt_t bits2 = n2*FLINT_BITS; + + mp_size_t j1 = (bits1 - 1)/bits + 1; + mp_size_t j2 = (bits2 - 1)/bits + 1; + + FLINT_ASSERT(n1 > 0); + FLINT_ASSERT(n2 > 0); + FLINT_ASSERT(j1 + j2 - 1 > 2*n); + + while (j1 + j2 - 1 > 4*n) /* find initial n, w */ + { + if (w == 1) w = 2; + else + { + depth++; + w = 1; + n *= 2; + } + + bits = (n*w - (depth+1))/2; + j1 = (bits1 - 1)/bits + 1; + j2 = (bits2 - 1)/bits + 1; + } + + if (depth < 11) + { + mp_size_t wadj = 1; + + off = fft_tuning_table[depth - 6][w - 1]; /* adjust n and w */ + depth -= off; + n = ((mp_size_t) 1 << depth); + w *= ((mp_size_t) 1 << (2*off)); + + if (depth < 6) wadj = ((mp_size_t) 1 << (6 - depth)); + + if (w > wadj) + { + do { /* see if a smaller w will work */ + w -= wadj; + bits = (n*w - (depth+1))/2; + j1 = (bits1 - 1)/bits + 1; + j2 = (bits2 - 1)/bits + 1; + } while (j1 + j2 - 1 <= 4*n && w > wadj); + w += wadj; + } + + mul_truncate_sqrt2(r1, i1, n1, i2, n2, depth, w); + } else + { + if (j1 + j2 - 1 <= 3*n) + { + depth--; + w *= 3; + } + mul_mfa_truncate_sqrt2(r1, i1, n1, i2, n2, depth, w); + } +} + diff --git a/external/flint-2.4.3/fft/mul_mfa_truncate_sqrt2.c b/external/flint-2.4.3/fft/mul_mfa_truncate_sqrt2.c new file mode 100644 index 0000000..9ca0e72 --- /dev/null +++ b/external/flint-2.4.3/fft/mul_mfa_truncate_sqrt2.c @@ -0,0 +1,102 @@ +/* + +Copyright 2009, 2011 William Hart. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY William Hart ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL William Hart OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those of the +authors and should not be interpreted as representing official policies, either expressed +or implied, of William Hart. + +*/ + +#include "gmp.h" +#include "flint.h" +#include "fft.h" +#include "ulong_extras.h" + +void mul_mfa_truncate_sqrt2(mp_ptr r1, mp_srcptr i1, mp_size_t n1, + mp_srcptr i2, mp_size_t n2, mp_bitcnt_t depth, mp_bitcnt_t w) +{ + mp_size_t n = (UWORD(1)< +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fft.h" + +int +main(void) +{ + mp_size_t iters; + + FLINT_TEST_INIT(state); + + flint_printf("mul_fft_main...."); + fflush(stdout); + + + _flint_rand_init_gmp(state); + + iters = 1; + + { + mp_size_t int_limbs = 1000000; + mp_size_t j; + mp_limb_t * i1, *i2, *r1, *r2; + + flint_printf("bits = %wd\n", int_limbs*FLINT_BITS); + + i1 = flint_malloc(6*int_limbs*sizeof(mp_limb_t)); + i2 = i1 + int_limbs; + r1 = i2 + int_limbs; + r2 = r1 + 2*int_limbs; + + flint_mpn_urandomb(i1, state->gmp_state, int_limbs*FLINT_BITS); + flint_mpn_urandomb(i2, state->gmp_state, int_limbs*FLINT_BITS); + + for (j = 0; j < iters; j++) + //mpn_mul(r2, i1, int_limbs, i2, int_limbs); + flint_mpn_mul_fft_main(r1, i1, int_limbs, i2, int_limbs); + + flint_free(i1); + } + + flint_randclear(state); + + flint_printf("done\n"); + return 0; +} diff --git a/external/flint-2.4.3/fft/profile/p-mul_mfa_truncate_sqrt2.c b/external/flint-2.4.3/fft/profile/p-mul_mfa_truncate_sqrt2.c new file mode 100644 index 0000000..907f29a --- /dev/null +++ b/external/flint-2.4.3/fft/profile/p-mul_mfa_truncate_sqrt2.c @@ -0,0 +1,87 @@ +/* + +Copyright 2009, 2011 William Hart. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY William Hart ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL William Hart OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those of the +authors and should not be interpreted as representing official policies, either expressed +or implied, of William Hart. + +*/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fft.h" + +int +main(void) +{ + mp_bitcnt_t depth, w; + mp_size_t iters, j; + double truncation; + + FLINT_TEST_INIT(state); + + flint_printf("mul_mfa_truncate_sqrt2...."); + fflush(stdout); + + + _flint_rand_init_gmp(state); + + depth = 13; + w = 2; + iters = 1; + truncation = 0.5; + + { + mp_size_t n = (UWORD(1)<gmp_state, int_limbs*FLINT_BITS); + flint_mpn_urandomb(i2, state->gmp_state, int_limbs*FLINT_BITS); + + for (j = 0; j < iters; j++) + mul_mfa_truncate_sqrt2(r1, i1, int_limbs, i2, int_limbs, depth, w); + //mpn_mul(r2, i1, int_limbs, i2, int_limbs); + + flint_free(i1); + } + + flint_randclear(state); + + flint_printf("done\n"); + return 0; +} diff --git a/external/flint-2.4.3/fft/profile/p-mul_truncate_sqrt2.c b/external/flint-2.4.3/fft/profile/p-mul_truncate_sqrt2.c new file mode 100644 index 0000000..40fc899 --- /dev/null +++ b/external/flint-2.4.3/fft/profile/p-mul_truncate_sqrt2.c @@ -0,0 +1,87 @@ +/* + +Copyright 2009, 2011 William Hart. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY William Hart ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL William Hart OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those of the +authors and should not be interpreted as representing official policies, either expressed +or implied, of William Hart. + +*/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fft.h" + +int +main(void) +{ + mp_bitcnt_t depth, w; + mp_size_t iters, j; + double truncation; + + FLINT_TEST_INIT(state); + + flint_printf("mul_truncate_sqrt2...."); + fflush(stdout); + + + _flint_rand_init_gmp(state); + + depth = 13; + w = 1; + iters = 1; + truncation = 1.0; + + { + mp_size_t n = (UWORD(1)<gmp_state, int_limbs*FLINT_BITS); + flint_mpn_urandomb(i2, state->gmp_state, int_limbs*FLINT_BITS); + + //mpn_mul(r2, i1, int_limbs, i2, int_limbs); + for (j = 0; j < iters; j++) + mul_truncate_sqrt2(r1, i1, int_limbs, i2, int_limbs, depth, w); + + flint_free(i1); + } + + flint_randclear(state); + + flint_printf("done\n"); + return 0; +} diff --git a/external/flint-2.4.3/fft/split_bits.c b/external/flint-2.4.3/fft/split_bits.c new file mode 100644 index 0000000..7fcac57 --- /dev/null +++ b/external/flint-2.4.3/fft/split_bits.c @@ -0,0 +1,110 @@ +/* + +Copyright 2009, 2011 William Hart. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY William Hart ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL William Hart OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those of the +authors and should not be interpreted as representing official policies, either expressed +or implied, of William Hart. + +*/ + +#include "gmp.h" +#include "flint.h" +#include "fft.h" + +mp_size_t fft_split_limbs(mp_limb_t ** poly, mp_srcptr limbs, + mp_size_t total_limbs, mp_size_t coeff_limbs, mp_size_t output_limbs) +{ + mp_size_t i, skip, length = (total_limbs - 1)/coeff_limbs + 1; + + for (skip = 0, i = 0; skip + coeff_limbs <= total_limbs; skip += coeff_limbs, i++) + { + flint_mpn_zero(poly[i], output_limbs + 1); + flint_mpn_copyi(poly[i], limbs + skip, coeff_limbs); + } + + if (i < length) + flint_mpn_zero(poly[i], output_limbs + 1); + + if (total_limbs > skip) + flint_mpn_copyi(poly[i], limbs + skip, total_limbs - skip); + + return length; +} + +mp_size_t fft_split_bits(mp_limb_t ** poly, mp_srcptr limbs, + mp_size_t total_limbs, mp_bitcnt_t bits, mp_size_t output_limbs) +{ + mp_size_t i, coeff_limbs, limbs_left, length = (FLINT_BITS*total_limbs - 1)/bits + 1; + mp_bitcnt_t shift_bits, top_bits = ((FLINT_BITS - 1) & bits); + mp_srcptr limb_ptr; + mp_limb_t mask; + + if (top_bits == 0) + return fft_split_limbs(poly, limbs, total_limbs, bits/FLINT_BITS, output_limbs); + + coeff_limbs = (bits/FLINT_BITS) + 1; + mask = (WORD(1)<= FLINT_BITS) + { + limb_ptr++; + poly[i][coeff_limbs - 1] += (limb_ptr[0] << (FLINT_BITS - (shift_bits - top_bits))); + shift_bits -= FLINT_BITS; + } + + poly[i][coeff_limbs - 1] &= mask; + + } + } + + flint_mpn_zero(poly[i], output_limbs + 1); + + limbs_left = total_limbs - (limb_ptr - limbs); + + if (!shift_bits) + flint_mpn_copyi(poly[i], limb_ptr, limbs_left); + else + mpn_rshift(poly[i], limb_ptr, limbs_left, shift_bits); + + return length; +} + diff --git a/external/flint-2.4.3/fft/test/t-adjust.c b/external/flint-2.4.3/fft/test/t-adjust.c new file mode 100644 index 0000000..e5c7d04 --- /dev/null +++ b/external/flint-2.4.3/fft/test/t-adjust.c @@ -0,0 +1,127 @@ +/* + +Copyright 2009, 2011 William Hart. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY William Hart ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL William Hart OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those of the +authors and should not be interpreted as representing official policies, either expressed +or implied, of William Hart. + +*/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fft.h" + +/* set p = 2^wn + 1 */ +void set_p(mpz_t p, mp_size_t n, mp_bitcnt_t w) +{ + flint_mpz_set_ui(p, 1); + mpz_mul_2exp(p, p, n*w); + flint_mpz_add_ui(p, p, 1); +} + +void ref_adjust(mpz_t r, mpz_t i1, mpz_t p, mp_size_t i, mp_size_t w) +{ + mpz_mul_2exp(r, i1, w*i); + mpz_mod(r, r, p); +} + +int +main(void) +{ + mp_size_t c, bits, j, k, n, w, limbs; + mpz_t p, m2a, m2b, mn1; + mp_limb_t * nn1, * r1; + + FLINT_TEST_INIT(state); + + flint_printf("adjust...."); + fflush(stdout); + + + _flint_rand_init_gmp(state); + + mpz_init(p); + mpz_init(m2a); + mpz_init(m2b); + mpz_init(mn1); + + for (bits = FLINT_BITS; bits < 20*FLINT_BITS; bits += FLINT_BITS) + { + for (j = 1; j < 10; j++) + { + for (k = 1; k <= FLINT_BITS; k <<= 1) + { + n = bits/k; + w = j*k; + + limbs = (n*w)/FLINT_BITS; + + for (c = 0; c < n; c++) + { + set_p(p, n, w); + + nn1 = flint_malloc((limbs+1)*sizeof(mp_limb_t)); + r1 = flint_malloc((limbs+1)*sizeof(mp_limb_t)); + + random_fermat(nn1, state, limbs); + fermat_to_mpz(mn1, nn1, limbs); + ref_adjust(m2a, mn1, p, c, w); + + fft_adjust(r1, nn1, c, limbs, w); + fermat_to_mpz(m2b, r1, limbs); + + mpz_mod(m2a, m2a, p); + mpz_mod(m2b, m2b, p); + + if (mpz_cmp(m2a, m2a) != 0) + { + flint_printf("FAIL:\n"); + flint_printf("adjust error a\n"); + flint_printf("limbs = %wd\n", limbs); + flint_printf("n = %wd, w = %wd, c = %wd\n", n, w, c); + gmp_printf("want %Zx\n\n", m2a); + gmp_printf("got %Zx\n", m2b); + abort(); + } + + flint_free(nn1); + flint_free(r1); + } + } + } + } + + mpz_clear(p); + mpz_clear(m2a); + mpz_clear(m2b); + mpz_clear(mn1); + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fft/test/t-adjust_sqrt2.c b/external/flint-2.4.3/fft/test/t-adjust_sqrt2.c new file mode 100644 index 0000000..d87df90 --- /dev/null +++ b/external/flint-2.4.3/fft/test/t-adjust_sqrt2.c @@ -0,0 +1,137 @@ +/* + +Copyright 2009, 2011 William Hart. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY William Hart ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL William Hart OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those of the +authors and should not be interpreted as representing official policies, either expressed +or implied, of William Hart. + +*/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "mpn_extras.h" +#include "fft.h" + + +/* set p = 2^wn + 1 */ +void set_p(mpz_t p, mp_size_t n, mp_bitcnt_t w) +{ + flint_mpz_set_ui(p, 1); + mpz_mul_2exp(p, p, n*w); + flint_mpz_add_ui(p, p, 1); +} + +void ref_adjust_sqrt2(mpz_t r, mpz_t i1, mpz_t p, mp_size_t i, mp_size_t limbs, mp_size_t w) +{ + mpz_mul_2exp(r, i1, (w/2)*i + i/2); + if (i & 1) + { + mpz_mul_2exp(i1, r, 3*limbs*FLINT_BITS/4); + mpz_mul_2exp(r, r, limbs*FLINT_BITS/4); + mpz_sub(r, i1, r); + } + mpz_mod(r, r, p); +} + +int +main(void) +{ + mp_size_t c, bits, j, k, n, w, limbs; + mpz_t p, m2a, m2b, mn1; + mp_limb_t * nn1, * r1, * temp; + + FLINT_TEST_INIT(state); + + flint_printf("adjust_sqrt2...."); + fflush(stdout); + + + _flint_rand_init_gmp(state); + + mpz_init(p); + mpz_init(m2a); + mpz_init(m2b); + mpz_init(mn1); + + for (bits = FLINT_BITS; bits < 20*FLINT_BITS; bits += FLINT_BITS) + { + for (j = 1; j < 10; j++) + { + for (k = 1; k <= FLINT_BITS; k <<= 1) + { + n = bits/k; + w = j*k; + + limbs = (n*w)/FLINT_BITS; + + for (c = 1; c < 2*n; c+=2) + { + set_p(p, n, w); + + nn1 = flint_malloc((limbs+1)*sizeof(mp_limb_t)); + r1 = flint_malloc((limbs+1)*sizeof(mp_limb_t)); + temp = flint_malloc((limbs+1)*sizeof(mp_limb_t)); + + random_fermat(nn1, state, limbs); + fermat_to_mpz(mn1, nn1, limbs); + ref_adjust_sqrt2(m2a, mn1, p, c, limbs, w); + + fft_adjust_sqrt2(r1, nn1, c, limbs, w, temp); + fermat_to_mpz(m2b, r1, limbs); + + mpz_mod(m2a, m2a, p); + mpz_mod(m2b, m2b, p); + + if (mpz_cmp(m2a, m2b) != 0) + { + flint_printf("FAIL:\n"); + flint_printf("adjust_sqrt2 error a\n"); + flint_printf("limbs = %wd\n", limbs); + flint_printf("n = %wd, w = %wd, c = %wd\n", n, w, c); + gmp_printf("want %Zx\n\n", m2a); + gmp_printf("got %Zx\n", m2b); + abort(); + } + + flint_free(temp); + flint_free(nn1); + flint_free(r1); + } + } + } + } + + mpz_clear(p); + mpz_clear(m2a); + mpz_clear(m2b); + mpz_clear(mn1); + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fft/test/t-butterfly.c b/external/flint-2.4.3/fft/test/t-butterfly.c new file mode 100644 index 0000000..bde6878 --- /dev/null +++ b/external/flint-2.4.3/fft/test/t-butterfly.c @@ -0,0 +1,226 @@ +/* + +Copyright 2009, 2011 William Hart. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY William Hart ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL William Hart OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those of the +authors and should not be interpreted as representing official policies, either expressed +or implied, of William Hart. + +*/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "mpn_extras.h" +#include "fft.h" + +/* set p = 2^wn + 1 */ +void set_p(mpz_t p, mp_size_t n, mp_bitcnt_t w) +{ + flint_mpz_set_ui(p, 1); + mpz_mul_2exp(p, p, n*w); + flint_mpz_add_ui(p, p, 1); +} + +void ref_fft_butterfly(mpz_t s, mpz_t t, mpz_t i1, mpz_t i2, + mpz_t p, mp_size_t i, mp_size_t w) +{ + mpz_add(s, i1, i2); + mpz_sub(t, i1, i2); + mpz_mul_2exp(t, t, i*w); + mpz_mod(s, s, p); + mpz_mod(t, t, p); +} + +void ref_ifft_butterfly(mpz_t s, mpz_t t, mpz_t i1, mpz_t i2, + mpz_t p, mp_size_t i, mp_size_t n, mp_size_t w) +{ + mpz_mul_2exp(i2, i2, 2*n*w - i*w); + mpz_add(s, i1, i2); + mpz_sub(t, i1, i2); + mpz_mod(s, s, p); + mpz_mod(t, t, p); +} + +int +main(void) +{ + mp_size_t c, bits, j, k, n, w, limbs; + mpz_t p, ma, mb, m2a, m2b, mn1, mn2; + mp_limb_t * nn1, * nn2, * r1, * r2; + + FLINT_TEST_INIT(state); + + flint_printf("fft/ifft_butterfly...."); + fflush(stdout); + + + _flint_rand_init_gmp(state); + + mpz_init(p); + mpz_init(ma); + mpz_init(mb); + mpz_init(m2a); + mpz_init(m2b); + mpz_init(mn1); + mpz_init(mn2); + + for (bits = FLINT_BITS; bits < 20*FLINT_BITS; bits += FLINT_BITS) + { + for (j = 1; j < 10; j++) + { + for (k = 1; k <= FLINT_BITS; k <<= 1) + { + n = bits/k; + w = j*k; + + limbs = (n*w)/FLINT_BITS; + + for (c = 0; c < n; c++) + { + nn1 = flint_malloc((limbs + 1)*sizeof(mp_limb_t)); + nn2 = flint_malloc((limbs + 1)*sizeof(mp_limb_t)); + r1 = flint_malloc((limbs + 1)*sizeof(mp_limb_t)); + r2 = flint_malloc((limbs + 1)*sizeof(mp_limb_t)); + random_fermat(nn1, state, limbs); + random_fermat(nn2, state, limbs); + + fermat_to_mpz(mn1, nn1, limbs); + fermat_to_mpz(mn2, nn2, limbs); + set_p(p, n, w); + + fft_butterfly(r1, r2, nn1, nn2, c, limbs, w); + fermat_to_mpz(m2a, r1, limbs); + fermat_to_mpz(m2b, r2, limbs); + + mpz_mod(m2a, m2a, p); + mpz_mod(m2b, m2b, p); + ref_fft_butterfly(ma, mb, mn1, mn2, p, c, w); + + if (mpz_cmp(ma, m2a) != 0) + { + flint_printf("FAIL:\n"); + flint_printf("fft_butterfly error a\n"); + flint_printf("limbs = %wd\n", limbs); + flint_printf("n = %wd, w = %wd, k = %wd, c = %wd\n", n, w, k, c); + gmp_printf("want %Zx\n\n", ma); + gmp_printf("got %Zx\n", m2a); + abort(); + } + if (mpz_cmp(mb, m2b) != 0) + { + flint_printf("FAIL:\n"); + flint_printf("fft_butterfly error b\n"); + flint_printf("limbs = %wd\n", limbs); + flint_printf("n = %wd, w = %wd, k = %wd, c = %wd\n", n, w, k, c); + gmp_printf("want %Zx\n\n", mb); + gmp_printf("got %Zx\n", m2b); + abort(); + } + + flint_free(nn1); + flint_free(nn2); + flint_free(r1); + flint_free(r2); + } + } + } + } + + for (bits = FLINT_BITS; bits < 20*FLINT_BITS; bits += FLINT_BITS) + { + for (j = 1; j < 10; j++) + { + for (k = 1; k <= FLINT_BITS; k <<= 1) + { + n = bits/k; + w = j*k; + + limbs = (n*w)/FLINT_BITS; + + for (c = 0; c < n; c++) + { + nn1 = flint_malloc((limbs + 1)*sizeof(mp_limb_t)); + nn2 = flint_malloc((limbs + 1)*sizeof(mp_limb_t)); + r1 = flint_malloc((limbs + 1)*sizeof(mp_limb_t)); + r2 = flint_malloc((limbs + 1)*sizeof(mp_limb_t)); + random_fermat(nn1, state, limbs); + random_fermat(nn2, state, limbs); + + fermat_to_mpz(mn1, nn1, limbs); + fermat_to_mpz(mn2, nn2, limbs); + set_p(p, n, w); + + ifft_butterfly(r1, r2, nn1, nn2, c, limbs, w); + fermat_to_mpz(m2a, r1, limbs); + fermat_to_mpz(m2b, r2, limbs); + + mpz_mod(m2a, m2a, p); + mpz_mod(m2b, m2b, p); + ref_ifft_butterfly(ma, mb, mn1, mn2, p, c, n, w); + + if (mpz_cmp(ma, m2a) != 0) + { + flint_printf("FAIL:\n"); + flint_printf("ifft_butterfly error a\n"); + flint_printf("limbs = %wd\n", limbs); + flint_printf("n = %wd, w = %wd, k = %wd, c = %wd\n", n, w, k, c); + gmp_printf("want %Zx\n\n", ma); + gmp_printf("got %Zx\n", m2a); + abort(); + } + if (mpz_cmp(mb, m2b) != 0) + { + flint_printf("FAIL:\n"); + flint_printf("ifft_butterfly error b\n"); + flint_printf("limbs = %wd\n", limbs); + flint_printf("n = %wd, w = %wd, k = %wd, c = %wd\n", n, w, k, c); + gmp_printf("want %Zx\n\n", mb); + gmp_printf("got %Zx\n", m2b); + abort(); + } + + flint_free(nn1); + flint_free(nn2); + flint_free(r1); + flint_free(r2); + } + } + } + } + + mpz_clear(p); + mpz_clear(ma); + mpz_clear(mb); + mpz_clear(m2a); + mpz_clear(m2b); + mpz_clear(mn1); + mpz_clear(mn2); + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fft/test/t-butterfly_lshB.c b/external/flint-2.4.3/fft/test/t-butterfly_lshB.c new file mode 100644 index 0000000..ae4a2ac --- /dev/null +++ b/external/flint-2.4.3/fft/test/t-butterfly_lshB.c @@ -0,0 +1,159 @@ +/* + +Copyright 2009, 2011 William Hart. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY William Hart ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL William Hart OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those of the +authors and should not be interpreted as representing official policies, either expressed +or implied, of William Hart. + +*/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "mpn_extras.h" +#include "fft.h" + +/* set p = 2^wn + 1 */ +void set_p(mpz_t p, mp_size_t n, mp_bitcnt_t w) +{ + flint_mpz_set_ui(p, 1); + mpz_mul_2exp(p, p, n*w); + flint_mpz_add_ui(p, p, 1); +} + +void ref_butterfly_lshB(mpz_t t, mpz_t u, mpz_t i1, mpz_t i2, + mpz_t p, mp_size_t x, mp_size_t y) +{ + mpz_add(t, i1, i2); + mpz_sub(u, i1, i2); + mpz_mul_2exp(t, t, x*GMP_LIMB_BITS); + mpz_mul_2exp(u, u, y*GMP_LIMB_BITS); + mpz_mod(t, t, p); + mpz_mod(u, u, p); +} + +int +main(void) +{ + mp_size_t c, bits, j, k, x, y, n, w, limbs; + mpz_t p, ma, mb, m2a, m2b, mn1, mn2; + mp_limb_t * nn1, * nn2, * r1, * r2; + + FLINT_TEST_INIT(state); + + flint_printf("butterfly_lshB...."); + fflush(stdout); + + + _flint_rand_init_gmp(state); + + mpz_init(p); + mpz_init(ma); + mpz_init(mb); + mpz_init(m2a); + mpz_init(m2b); + mpz_init(mn1); + mpz_init(mn2); + + for (bits = FLINT_BITS; bits < 20*FLINT_BITS; bits += FLINT_BITS) + { + for (j = 1; j < 10; j++) + { + for (k = 1; k <= FLINT_BITS; k <<= 1) + { + n = bits/k; + w = j*k; + + limbs = (n*w)/FLINT_BITS; + + for (c = 0; c < limbs; c++) + { + x = n_randint(state, limbs); + y = n_randint(state, limbs); + + nn1 = flint_malloc((limbs + 1)*sizeof(mp_limb_t)); + nn2 = flint_malloc((limbs + 1)*sizeof(mp_limb_t)); + r1 = flint_malloc((limbs + 1)*sizeof(mp_limb_t)); + r2 = flint_malloc((limbs + 1)*sizeof(mp_limb_t)); + flint_mpn_rrandom(nn1, state->gmp_state, limbs); + random_fermat(nn1, state, limbs); + random_fermat(nn2, state, limbs); + + fermat_to_mpz(mn1, nn1, limbs); + fermat_to_mpz(mn2, nn2, limbs); + set_p(p, n, w); + + butterfly_lshB(r1, r2, nn1, nn2, limbs, x, y); + fermat_to_mpz(m2a, r1, limbs); + fermat_to_mpz(m2b, r2, limbs); + + mpz_mod(m2a, m2a, p); + mpz_mod(m2b, m2b, p); + ref_butterfly_lshB(ma, mb, mn1, mn2, p, x, y); + + if (mpz_cmp(ma, m2a) != 0) + { + flint_printf("FAIL:\n"); + flint_printf("butterfly_lshB error a\n"); + flint_printf("x = %wd, y = %wd, limbs = %wd\n", x, y, limbs); + flint_printf("n = %wd, w = %wd, k = %wd, c = %wd\n", n, w, k, c); + gmp_printf("want %Zx\n\n", ma); + gmp_printf("got %Zx\n", m2a); + abort(); + } + if (mpz_cmp(mb, m2b) != 0) + { + flint_printf("FAIL:\n"); + flint_printf("butterfly_lshB error b\n"); + flint_printf("x = %wd, y = %wd, limbs = %wd\n", x, y, limbs); + flint_printf("n = %wd, w = %wd, k = %wd, c = %wd\n", n, w, k, c); + gmp_printf("want %Zx\n\n", mb); + gmp_printf("got %Zx\n", m2b); + abort(); + } + + flint_free(nn1); + flint_free(nn2); + flint_free(r1); + flint_free(r2); + } + } + } + } + + mpz_clear(p); + mpz_clear(ma); + mpz_clear(mb); + mpz_clear(m2a); + mpz_clear(m2b); + mpz_clear(mn1); + mpz_clear(mn2); + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fft/test/t-butterfly_rshB.c b/external/flint-2.4.3/fft/test/t-butterfly_rshB.c new file mode 100644 index 0000000..de0ac56 --- /dev/null +++ b/external/flint-2.4.3/fft/test/t-butterfly_rshB.c @@ -0,0 +1,173 @@ +/* + +Copyright 2009, 2011 William Hart. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY William Hart ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL William Hart OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those of the +authors and should not be interpreted as representing official policies, either expressed +or implied, of William Hart. + +*/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "mpn_extras.h" +#include "fft.h" + +/* set p = 2^wn + 1 */ +void set_p(mpz_t p, mp_size_t n, mp_bitcnt_t w) +{ + flint_mpz_set_ui(p, 1); + mpz_mul_2exp(p, p, n*w); + flint_mpz_add_ui(p, p, 1); +} + +void ref_butterfly_rshB(mpz_t t, mpz_t u, mpz_t i1, mpz_t i2, + mpz_t p, mp_size_t x, mp_size_t y) +{ + mpz_t mult1, mult2; + + mpz_init(mult1); + mpz_init(mult2); + + flint_mpz_set_ui(mult1, 1); + mpz_mul_2exp(mult1, mult1, x*FLINT_BITS); + mpz_invert(mult1, mult1, p); + flint_mpz_set_ui(mult2, 1); + mpz_mul_2exp(mult2, mult2, y*FLINT_BITS); + mpz_invert(mult2, mult2, p); + mpz_mul(mult1, mult1, i1); + mpz_mul(mult2, mult2, i2); + mpz_add(t, mult1, mult2); + mpz_sub(u, mult1, mult2); + mpz_mod(t, t, p); + mpz_mod(u, u, p); + + mpz_clear(mult1); + mpz_clear(mult2); +} + +int +main(void) +{ + mp_size_t c, bits, j, k, x, y, n, w, limbs; + mpz_t p, ma, mb, m2a, m2b, mn1, mn2; + mp_limb_t * nn1, * nn2, * r1, * r2; + + FLINT_TEST_INIT(state); + + flint_printf("butterfly_rshB...."); + fflush(stdout); + + + _flint_rand_init_gmp(state); + + mpz_init(p); + mpz_init(ma); + mpz_init(mb); + mpz_init(m2a); + mpz_init(m2b); + mpz_init(mn1); + mpz_init(mn2); + + for (bits = FLINT_BITS; bits < 20*FLINT_BITS; bits += FLINT_BITS) + { + for (j = 1; j < 10; j++) + { + for (k = 1; k <= FLINT_BITS; k <<= 1) + { + n = bits/k; + w = j*k; + + limbs = (n*w)/FLINT_BITS; + + for (c = 0; c < limbs; c++) + { + x = n_randint(state, limbs); + y = n_randint(state, limbs); + + nn1 = flint_malloc((limbs + 1)*sizeof(mp_limb_t)); + nn2 = flint_malloc((limbs + 1)*sizeof(mp_limb_t)); + r1 = flint_malloc((limbs + 1)*sizeof(mp_limb_t)); + r2 = flint_malloc((limbs + 1)*sizeof(mp_limb_t)); + flint_mpn_rrandom(nn1, state->gmp_state, limbs); + random_fermat(nn1, state, limbs); + random_fermat(nn2, state, limbs); + + fermat_to_mpz(mn1, nn1, limbs); + fermat_to_mpz(mn2, nn2, limbs); + set_p(p, n, w); + + butterfly_rshB(r1, r2, nn1, nn2, limbs, x, y); + fermat_to_mpz(m2a, r1, limbs); + fermat_to_mpz(m2b, r2, limbs); + + mpz_mod(m2a, m2a, p); + mpz_mod(m2b, m2b, p); + ref_butterfly_rshB(ma, mb, mn1, mn2, p, x, y); + + if (mpz_cmp(ma, m2a) != 0) + { + flint_printf("FAIL:\n"); + flint_printf("butterfly_rshB error a\n"); + flint_printf("x = %wd, y = %wd, limbs = %wd\n", x, y, limbs); + flint_printf("n = %wd, w = %wd, k = %wd, c = %wd\n", n, w, k, c); + gmp_printf("want %Zx\n\n", ma); + gmp_printf("got %Zx\n", m2a); + abort(); + } + if (mpz_cmp(mb, m2b) != 0) + { + flint_printf("FAIL:\n"); + flint_printf("butterfly_rshB error b\n"); + flint_printf("x = %wd, y = %wd, limbs = %wd\n", x, y, limbs); + flint_printf("n = %wd, w = %wd, k = %wd, c = %wd\n", n, w, k, c); + gmp_printf("want %Zx\n\n", mb); + gmp_printf("got %Zx\n", m2b); + abort(); + } + + flint_free(nn1); + flint_free(nn2); + flint_free(r1); + flint_free(r2); + } + } + } + } + + mpz_clear(p); + mpz_clear(ma); + mpz_clear(mb); + mpz_clear(m2a); + mpz_clear(m2b); + mpz_clear(mn1); + mpz_clear(mn2); + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fft/test/t-butterfly_sqrt2.c b/external/flint-2.4.3/fft/test/t-butterfly_sqrt2.c new file mode 100644 index 0000000..577e636 --- /dev/null +++ b/external/flint-2.4.3/fft/test/t-butterfly_sqrt2.c @@ -0,0 +1,238 @@ +/* + +Copyright 2009, 2011 William Hart. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY William Hart ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL William Hart OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those of the +authors and should not be interpreted as representing official policies, either expressed +or implied, of William Hart. + +*/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "mpn_extras.h" +#include "fft.h" + +/* set p = 2^wn + 1 */ +void set_p(mpz_t p, mp_size_t n, mp_bitcnt_t w) +{ + flint_mpz_set_ui(p, 1); + mpz_mul_2exp(p, p, n*w); + flint_mpz_add_ui(p, p, 1); +} + +void ref_fft_butterfly_sqrt2(mpz_t s, mpz_t t, mpz_t i1, mpz_t i2, + mpz_t p, mp_size_t i, mp_size_t limbs, mp_size_t w) +{ + mpz_sub(t, i1, i2); + mpz_mul_2exp(t, t, i*(w/2) + i/2); + mpz_mul_2exp(s, t, 3*limbs*FLINT_BITS/4); + mpz_mul_2exp(t, t, limbs*FLINT_BITS/4); + mpz_sub(t, s, t); + mpz_add(s, i1, i2); + mpz_mod(s, s, p); + mpz_mod(t, t, p); +} + +void ref_ifft_butterfly_sqrt2(mpz_t s, mpz_t t, mpz_t i1, mpz_t i2, + mpz_t p, mp_size_t i, mp_size_t n, mp_size_t limbs, mp_size_t w) +{ + mpz_mul_2exp(s, i2, 2*n*w - i*(w/2) - 1 - i/2); + mpz_mul_2exp(t, s, 3*limbs*FLINT_BITS/4); + mpz_mul_2exp(s, s, limbs*FLINT_BITS/4); + mpz_sub(i2, t, s); + mpz_add(s, i1, i2); + mpz_sub(t, i1, i2); + mpz_mod(s, s, p); + mpz_mod(t, t, p); +} + +int +main(void) +{ + mp_size_t c, bits, j, k, n, w, limbs; + mpz_t p, ma, mb, m2a, m2b, mn1, mn2; + mp_limb_t * nn1, * nn2, * r1, * r2, * temp; + + FLINT_TEST_INIT(state); + + flint_printf("fft/ifft_butterfly_sqrt2...."); + fflush(stdout); + + + _flint_rand_init_gmp(state); + + mpz_init(p); + mpz_init(ma); + mpz_init(mb); + mpz_init(m2a); + mpz_init(m2b); + mpz_init(mn1); + mpz_init(mn2); + + for (bits = FLINT_BITS; bits < 20*FLINT_BITS; bits += FLINT_BITS) + { + for (j = 1; j < 10; j++) + { + for (k = 1; k <= FLINT_BITS; k <<= 1) + { + n = bits/k; + w = j*k; + + if ((w & 1) == 0) continue; /* w must be odd here */ + + limbs = (n*w)/FLINT_BITS; + + for (c = 1; c < 2*n; c+=2) + { + nn1 = flint_malloc((limbs + 1)*sizeof(mp_limb_t)); + nn2 = flint_malloc((limbs + 1)*sizeof(mp_limb_t)); + temp = flint_malloc((limbs + 1)*sizeof(mp_limb_t)); + r1 = flint_malloc((limbs + 1)*sizeof(mp_limb_t)); + r2 = flint_malloc((limbs + 1)*sizeof(mp_limb_t)); + random_fermat(nn1, state, limbs); + random_fermat(nn2, state, limbs); + + fermat_to_mpz(mn1, nn1, limbs); + fermat_to_mpz(mn2, nn2, limbs); + set_p(p, n, w); + + fft_butterfly_sqrt2(r1, r2, nn1, nn2, c, limbs, w, temp); + fermat_to_mpz(m2a, r1, limbs); + fermat_to_mpz(m2b, r2, limbs); + + mpz_mod(m2a, m2a, p); + mpz_mod(m2b, m2b, p); + ref_fft_butterfly_sqrt2(ma, mb, mn1, mn2, p, c, limbs, w); + + if (mpz_cmp(ma, m2a) != 0) + { + flint_printf("FAIL:\n"); + flint_printf("fft_butterfly_sqrt2 error a\n"); + flint_printf("limbs = %wd\n", limbs); + flint_printf("n = %wd, w = %wd, k = %wd, c = %wd\n", n, w, k, c); + gmp_printf("want %Zx\n\n", ma); + gmp_printf("got %Zx\n", m2a); + abort(); + } + if (mpz_cmp(mb, m2b) != 0) + { + flint_printf("FAIL:\n"); + flint_printf("fft_butterfly_sqrt2 error b\n"); + flint_printf("limbs = %wd\n", limbs); + flint_printf("n = %wd, w = %wd, k = %wd, c = %wd\n", n, w, k, c); + gmp_printf("want %Zx\n\n", mb); + gmp_printf("got %Zx\n", m2b); + abort(); + } + + flint_free(temp); + flint_free(nn1); + flint_free(nn2); + flint_free(r1); + flint_free(r2); + } + } + } + } + + for (bits = FLINT_BITS; bits < 20*FLINT_BITS; bits += FLINT_BITS) + { + for (j = 1; j < 10; j++) + { + for (k = 1; k <= FLINT_BITS; k <<= 1) + { + n = bits/k; + w = j*k; + if ((w & 1) == 0) continue; /* w must be odd here */ + + limbs = (n*w)/FLINT_BITS; + + for (c = 1; c < 2*n; c+=2) + { + nn1 = flint_malloc((limbs + 1)*sizeof(mp_limb_t)); + nn2 = flint_malloc((limbs + 1)*sizeof(mp_limb_t)); + temp = flint_malloc((limbs + 1)*sizeof(mp_limb_t)); + r1 = flint_malloc((limbs + 1)*sizeof(mp_limb_t)); + r2 = flint_malloc((limbs + 1)*sizeof(mp_limb_t)); + random_fermat(nn1, state, limbs); + random_fermat(nn2, state, limbs); + + fermat_to_mpz(mn1, nn1, limbs); + fermat_to_mpz(mn2, nn2, limbs); + set_p(p, n, w); + + ifft_butterfly_sqrt2(r1, r2, nn1, nn2, c, limbs, w, temp); + fermat_to_mpz(m2a, r1, limbs); + fermat_to_mpz(m2b, r2, limbs); + + mpz_mod(m2a, m2a, p); + mpz_mod(m2b, m2b, p); + ref_ifft_butterfly_sqrt2(ma, mb, mn1, mn2, p, c, n, limbs, w); + + if (mpz_cmp(ma, m2a) != 0) + { + flint_printf("FAIL:\n"); + flint_printf("ifft_butterfly_sqrt2 error a\n"); + flint_printf("limbs = %wd\n", limbs); + flint_printf("n = %wd, w = %wd, k = %wd, c = %wd\n", n, w, k, c); + gmp_printf("want %Zx\n\n", ma); + gmp_printf("got %Zx\n", m2a); + abort(); + } + if (mpz_cmp(mb, m2b) != 0) + { + flint_printf("FAIL:\n"); + flint_printf("ifft_butterfly_sqrt2 error b\n"); + flint_printf("limbs = %wd\n", limbs); + flint_printf("n = %wd, w = %wd, k = %wd, c = %wd\n", n, w, k, c); + gmp_printf("want %Zx\n\n", mb); + gmp_printf("got %Zx\n", m2b); + abort(); + } + flint_free(temp); + flint_free(nn1); + flint_free(nn2); + flint_free(r1); + flint_free(r2); + } + } + } + } + + mpz_clear(p); + mpz_clear(ma); + mpz_clear(mb); + mpz_clear(m2a); + mpz_clear(m2b); + mpz_clear(mn1); + mpz_clear(mn2); + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fft/test/t-butterfly_twiddle.c b/external/flint-2.4.3/fft/test/t-butterfly_twiddle.c new file mode 100644 index 0000000..94654bb --- /dev/null +++ b/external/flint-2.4.3/fft/test/t-butterfly_twiddle.c @@ -0,0 +1,232 @@ +/* + +Copyright 2009, 2011 William Hart. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY William Hart ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL William Hart OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those of the +authors and should not be interpreted as representing official policies, either expressed +or implied, of William Hart. + +*/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fft.h" + +/* set p = 2^wn + 1 */ +void set_p(mpz_t p, mp_size_t n, mp_bitcnt_t w) +{ + flint_mpz_set_ui(p, 1); + mpz_mul_2exp(p, p, n*w); + flint_mpz_add_ui(p, p, 1); +} + +void ref_fft_butterfly_twiddle(mpz_t s, mpz_t t, mpz_t i1, mpz_t i2, + mpz_t p, mp_size_t i, mp_size_t w, mp_bitcnt_t b1, mp_bitcnt_t b2) +{ + mpz_add(s, i1, i2); + mpz_sub(t, i1, i2); + mpz_mul_2exp(s, s, b1); + mpz_mul_2exp(t, t, b2); + mpz_mod(s, s, p); + mpz_mod(t, t, p); +} + +void ref_ifft_butterfly_twiddle(mpz_t s, mpz_t t, mpz_t i1, mpz_t i2, + mpz_t p, mp_size_t i, mp_size_t n, mp_size_t w, mp_bitcnt_t b1, mp_bitcnt_t b2) +{ + mpz_mul_2exp(i1, i1, 2*n*w - b1); + mpz_mul_2exp(i2, i2, 2*n*w - b2); + mpz_add(s, i1, i2); + mpz_sub(t, i1, i2); + mpz_mod(s, s, p); + mpz_mod(t, t, p); +} + +int +main(void) +{ + mp_size_t c, bits, j, k, n, w, limbs; + mpz_t p, ma, mb, m2a, m2b, mn1, mn2; + mp_limb_t * nn1, * nn2, * r1, * r2; + mp_bitcnt_t b1, b2; + + FLINT_TEST_INIT(state); + + flint_printf("fft/ifft_butterfly_twiddle...."); + fflush(stdout); + + + _flint_rand_init_gmp(state); + + mpz_init(p); + mpz_init(ma); + mpz_init(mb); + mpz_init(m2a); + mpz_init(m2b); + mpz_init(mn1); + mpz_init(mn2); + + for (bits = FLINT_BITS; bits < 20*FLINT_BITS; bits += FLINT_BITS) + { + for (j = 1; j < 10; j++) + { + for (k = 1; k <= FLINT_BITS; k <<= 1) + { + n = bits/k; + w = j*k; + + limbs = (n*w)/FLINT_BITS; + + for (c = 0; c < n; c++) + { + b1 = n_randint(state, n*w); + b2 = n_randint(state, n*w); + nn1 = flint_malloc((limbs + 1)*sizeof(mp_limb_t)); + nn2 = flint_malloc((limbs + 1)*sizeof(mp_limb_t)); + r1 = flint_malloc((limbs + 1)*sizeof(mp_limb_t)); + r2 = flint_malloc((limbs + 1)*sizeof(mp_limb_t)); + random_fermat(nn1, state, limbs); + random_fermat(nn2, state, limbs); + + fermat_to_mpz(mn1, nn1, limbs); + fermat_to_mpz(mn2, nn2, limbs); + set_p(p, n, w); + + fft_butterfly_twiddle(r1, r2, nn1, nn2, limbs, b1, b2); + fermat_to_mpz(m2a, r1, limbs); + fermat_to_mpz(m2b, r2, limbs); + + mpz_mod(m2a, m2a, p); + mpz_mod(m2b, m2b, p); + ref_fft_butterfly_twiddle(ma, mb, mn1, mn2, p, c, w, b1, b2); + + if (mpz_cmp(ma, m2a) != 0) + { + flint_printf("FAIL:\n"); + flint_printf("fft_butterfly_twiddle error a\n"); + flint_printf("limbs = %wd\n", limbs); + flint_printf("n = %wd, w = %wd, k = %wd, c = %wd\n", n, w, k, c); + gmp_printf("want %Zx\n\n", ma); + gmp_printf("got %Zx\n", m2a); + abort(); + } + if (mpz_cmp(mb, m2b) != 0) + { + flint_printf("FAIL:\n"); + flint_printf("fft_butterfly_twiddle error b\n"); + flint_printf("limbs = %wd\n", limbs); + flint_printf("n = %wd, w = %wd, k = %wd, c = %wd\n", n, w, k, c); + gmp_printf("want %Zx\n\n", mb); + gmp_printf("got %Zx\n", m2b); + abort(); + } + + flint_free(nn1); + flint_free(nn2); + flint_free(r1); + flint_free(r2); + } + } + } + } + + for (bits = FLINT_BITS; bits < 20*FLINT_BITS; bits += FLINT_BITS) + { + for (j = 1; j < 10; j++) + { + for (k = 1; k <= FLINT_BITS; k <<= 1) + { + n = bits/k; + w = j*k; + + limbs = (n*w)/FLINT_BITS; + + for (c = 0; c < n; c++) + { + b1 = n_randint(state, n*w); + b2 = n_randint(state, n*w); + nn1 = flint_malloc((limbs + 1)*sizeof(mp_limb_t)); + nn2 = flint_malloc((limbs + 1)*sizeof(mp_limb_t)); + r1 = flint_malloc((limbs + 1)*sizeof(mp_limb_t)); + r2 = flint_malloc((limbs + 1)*sizeof(mp_limb_t)); + random_fermat(nn1, state, limbs); + random_fermat(nn2, state, limbs); + + fermat_to_mpz(mn1, nn1, limbs); + fermat_to_mpz(mn2, nn2, limbs); + set_p(p, n, w); + + ifft_butterfly_twiddle(r1, r2, nn1, nn2, limbs, b1, b2); + fermat_to_mpz(m2a, r1, limbs); + fermat_to_mpz(m2b, r2, limbs); + + mpz_mod(m2a, m2a, p); + mpz_mod(m2b, m2b, p); + ref_ifft_butterfly_twiddle(ma, mb, mn1, mn2, p, c, n, w, b1, b2); + + if (mpz_cmp(ma, m2a) != 0) + { + flint_printf("FAIL:\n"); + flint_printf("ifft_butterfly_twiddle error a\n"); + flint_printf("limbs = %wd\n", limbs); + flint_printf("n = %wd, w = %wd, k = %wd, c = %wd\n", n, w, k, c); + gmp_printf("want %Zx\n\n", ma); + gmp_printf("got %Zx\n", m2a); + abort(); + } + if (mpz_cmp(mb, m2b) != 0) + { + flint_printf("FAIL:\n"); + flint_printf("ifft_butterfly_twiddle error b\n"); + flint_printf("limbs = %wd\n", limbs); + flint_printf("n = %wd, w = %wd, k = %wd, c = %wd\n", n, w, k, c); + gmp_printf("want %Zx\n\n", mb); + gmp_printf("got %Zx\n", m2b); + abort(); + } + + flint_free(nn1); + flint_free(nn2); + flint_free(r1); + flint_free(r2); + } + } + } + } + + mpz_clear(p); + mpz_clear(ma); + mpz_clear(mb); + mpz_clear(m2a); + mpz_clear(m2b); + mpz_clear(mn1); + mpz_clear(mn2); + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fft/test/t-div_2expmod_2expp1.c b/external/flint-2.4.3/fft/test/t-div_2expmod_2expp1.c new file mode 100644 index 0000000..15ff125 --- /dev/null +++ b/external/flint-2.4.3/fft/test/t-div_2expmod_2expp1.c @@ -0,0 +1,121 @@ +/* + +Copyright 2009, 2011 William Hart. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY William Hart ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL William Hart OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those of the +authors and should not be interpreted as representing official policies, either expressed +or implied, of William Hart. + +*/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fft.h" + +/* set p = 2^wn + 1 */ +void set_p(mpz_t p, mp_size_t n, mp_bitcnt_t w) +{ + flint_mpz_set_ui(p, 1); + mpz_mul_2exp(p, p, n*w); + flint_mpz_add_ui(p, p, 1); +} + +int +main(void) +{ + mp_bitcnt_t bits; + mp_size_t j, k, n, w, limbs, d; + mp_limb_t * nn, * r; + mpz_t p, m1, m2, mn1, mn2; + + FLINT_TEST_INIT(state); + + flint_printf("div_2expmod_2expp1...."); + fflush(stdout); + + + _flint_rand_init_gmp(state); + + mpz_init(m1); + mpz_init(m2); + mpz_init(mn1); + mpz_init(mn2); + mpz_init(p); + + /* normalisation mod p = 2^wn + 1 where B divides nw and n is a power of 2 */ + for (bits = FLINT_BITS; bits < 16*FLINT_BITS; bits += FLINT_BITS) + { + for (j = 1; j < 32; j++) + { + for (k = 1; k <= FLINT_BITS; k <<= 1) + { + for (d = 0; d < FLINT_BITS; d++) + { + n = bits/k; + w = j*k; + limbs = (n*w)/GMP_LIMB_BITS; + + nn = flint_malloc((limbs + 1)*sizeof(mp_limb_t)); + r = flint_malloc((limbs + 1)*sizeof(mp_limb_t)); + random_fermat(nn, state, limbs); + fermat_to_mpz(mn1, nn, limbs); + set_p(p, n, w); + + mpn_div_2expmod_2expp1(r, nn, limbs, d); + fermat_to_mpz(m2, r, limbs); + mpz_mod(m2, m2, p); + + mpz_mod(m1, mn1, p); + mpz_mul_2exp(m2, m2, d); + mpz_mod(m2, m2, p); + + if (mpz_cmp(m1, m2) != 0) + { + flint_printf("FAIL:\n"); + flint_printf("mpn_div_2expmod_2expp1 error\n"); + gmp_printf("want %Zx\n\n", m1); + gmp_printf("got %Zx\n", m2); + abort(); + } + + flint_free(nn); + flint_free(r); + } + } + } + } + + mpz_clear(mn2); + mpz_clear(mn1); + mpz_clear(m2); + mpz_clear(m1); + mpz_clear(p); + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fft/test/t-fft_ifft_mfa_truncate_sqrt2.c b/external/flint-2.4.3/fft/test/t-fft_ifft_mfa_truncate_sqrt2.c new file mode 100644 index 0000000..3b8425c --- /dev/null +++ b/external/flint-2.4.3/fft/test/t-fft_ifft_mfa_truncate_sqrt2.c @@ -0,0 +1,114 @@ +/* + +Copyright 2009, 2011 William Hart. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY William Hart ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL William Hart OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those of the +authors and should not be interpreted as representing official policies, either expressed +or implied, of William Hart. + +*/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fft.h" + +int +main(void) +{ + mp_bitcnt_t depth, w; + + FLINT_TEST_INIT(state); + + flint_printf("fft/ifft_mfa_truncate_sqrt2...."); + fflush(stdout); + + + _flint_rand_init_gmp(state); + + for (depth = 6; depth <= 13; depth++) + { + for (w = 1; w <= 5; w++) + { + mp_size_t n = (UWORD(1)< +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fft.h" + +int +main(void) +{ + mp_bitcnt_t depth, w; + + FLINT_TEST_INIT(state); + + flint_printf("fft/ifft_negacyclic...."); + fflush(stdout); + + + _flint_rand_init_gmp(state); + + for (depth = 6; depth <= 12; depth++) + { + for (w = 1; w <= 5; w++) + { + mp_size_t n = (UWORD(1)< +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fft.h" + +int +main(void) +{ + mp_bitcnt_t depth, w; + + FLINT_TEST_INIT(state); + + flint_printf("fft/ifft_radix2...."); + fflush(stdout); + + + _flint_rand_init_gmp(state); + + for (depth = 6; depth <= 12; depth++) + { + for (w = 1; w <= 5; w++) + { + mp_size_t n = (UWORD(1)< +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fft.h" + +int +main(void) +{ + mp_bitcnt_t depth, w; + + FLINT_TEST_INIT(state); + + flint_printf("fft/ifft_truncate...."); + fflush(stdout); + + + _flint_rand_init_gmp(state); + + for (depth = 6; depth <= 12; depth++) + { + for (w = 1; w <= 5; w++) + { + mp_size_t n = (UWORD(1)< +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fft.h" + +int +main(void) +{ + mp_bitcnt_t depth, w; + + FLINT_TEST_INIT(state); + + flint_printf("fft/ifft_truncate_sqrt2...."); + fflush(stdout); + + + _flint_rand_init_gmp(state); + + for (depth = 6; depth <= 12; depth++) + { + for (w = 1; w <= 5; w++) + { + mp_size_t n = (UWORD(1)< +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fft.h" + +/* set p = 2^wn + 1 */ +void set_p(mpz_t p, mp_size_t n, mp_bitcnt_t w) +{ + flint_mpz_set_ui(p, 1); + mpz_mul_2exp(p, p, n*w); + flint_mpz_add_ui(p, p, 1); +} + +int +main(void) +{ + mp_bitcnt_t bits; + mp_size_t j, k, n, w, limbs, d; + mp_limb_t * nn, * r; + mpz_t p, m1, m2, mn1, mn2; + + FLINT_TEST_INIT(state); + + flint_printf("mul_2expmod_2expp1...."); + fflush(stdout); + + + _flint_rand_init_gmp(state); + + mpz_init(m1); + mpz_init(m2); + mpz_init(mn1); + mpz_init(mn2); + mpz_init(p); + + /* normalisation mod p = 2^wn + 1 where B divides nw and n is a power of 2 */ + for (bits = FLINT_BITS; bits < 16*FLINT_BITS; bits += FLINT_BITS) + { + for (j = 1; j < 32; j++) + { + for (k = 1; k <= FLINT_BITS; k <<= 1) + { + for (d = 0; d < FLINT_BITS; d++) + { + n = bits/k; + w = j*k; + limbs = (n*w)/GMP_LIMB_BITS; + + nn = flint_malloc((limbs + 1)*sizeof(mp_limb_t)); + r = flint_malloc((limbs + 1)*sizeof(mp_limb_t)); + random_fermat(nn, state, limbs); + fermat_to_mpz(mn1, nn, limbs); + set_p(p, n, w); + + mpn_mul_2expmod_2expp1(r, nn, limbs, d); + fermat_to_mpz(m2, r, limbs); + mpz_mod(m2, m2, p); + + mpz_mod(m1, mn1, p); + mpz_mul_2exp(m1, m1, d); + mpz_mod(m1, m1, p); + + if (mpz_cmp(m1, m2) != 0) + { + flint_printf("FAIL:\n"); + flint_printf("mpn_mul_2expmod_2expp1 error\n"); + gmp_printf("want %Zx\n\n", m1); + gmp_printf("got %Zx\n", m2); + abort(); + } + + flint_free(nn); + flint_free(r); + } + } + } + } + + mpz_clear(mn2); + mpz_clear(mn1); + mpz_clear(m2); + mpz_clear(m1); + mpz_clear(p); + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fft/test/t-mul_fft_main.c b/external/flint-2.4.3/fft/test/t-mul_fft_main.c new file mode 100644 index 0000000..e9d2bb8 --- /dev/null +++ b/external/flint-2.4.3/fft/test/t-mul_fft_main.c @@ -0,0 +1,116 @@ +/* + +Copyright 2009, 2011 William Hart. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY William Hart ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL William Hart OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those of the +authors and should not be interpreted as representing official policies, either expressed +or implied, of William Hart. + +*/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fft.h" + +int +main(void) +{ + mp_bitcnt_t depth, w; + + FLINT_TEST_INIT(state); + + flint_printf("mul_fft_main...."); + fflush(stdout); + + + _flint_rand_init_gmp(state); + + for (depth = 6; depth <= 13; depth++) + { + for (w = 1; w <= 3 - (depth >= 12); w++) + { + int iter = 1 + 200*(depth <= 8) + 80*(depth <= 9) + 10*(depth <= 10), i; + + for (i = 0; i < iter; i++) + { + mp_size_t n = (UWORD(1)<= b2 */ + { + mp_size_t t = n1; + mp_bitcnt_t tb = b1; + n1 = n2; + b1 = b2; + n2 = t; + b2 = tb; + } + + i1 = flint_malloc(3*(n1 + n2)*sizeof(mp_limb_t)); + i2 = i1 + n1; + r1 = i2 + n2; + r2 = r1 + n1 + n2; + + flint_mpn_urandomb(i1, state->gmp_state, b1); + flint_mpn_urandomb(i2, state->gmp_state, b2); + + mpn_mul(r2, i1, n1, i2, n2); + flint_mpn_mul_fft_main(r1, i1, n1, i2, n2); + + for (j = 0; j < n1 + n2; j++) + { + if (r1[j] != r2[j]) + { + flint_printf("error in limb %wd, %wx != %wx\n", j, r1[j], r2[j]); + abort(); + } + } + + flint_free(i1); + } + } + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fft/test/t-mul_mfa_truncate_sqrt2.c b/external/flint-2.4.3/fft/test/t-mul_mfa_truncate_sqrt2.c new file mode 100644 index 0000000..001a4c3 --- /dev/null +++ b/external/flint-2.4.3/fft/test/t-mul_mfa_truncate_sqrt2.c @@ -0,0 +1,126 @@ +/* + +Copyright 2009, 2011 William Hart. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY William Hart ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL William Hart OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those of the +authors and should not be interpreted as representing official policies, either expressed +or implied, of William Hart. + +*/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fft.h" + +int +main(void) +{ + mp_bitcnt_t depth, w; + + FLINT_TEST_INIT(state); + + flint_printf("mul_mfa_truncate_sqrt2...."); + fflush(stdout); + + + _flint_rand_init_gmp(state); + + for (depth = 6; depth <= 13; depth++) + { + for (w = 1; w <= 3 - (depth >= 12); w++) + { + mp_size_t n = (UWORD(1)<= 12); w++) + { + mp_size_t n = (UWORD(1)< +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fft.h" + +int +main(void) +{ + mp_bitcnt_t depth, w; + + FLINT_TEST_INIT(state); + + flint_printf("mul_truncate_sqrt2...."); + fflush(stdout); + + + _flint_rand_init_gmp(state); + + for (depth = 6; depth <= 12; depth++) + { + for (w = 1; w <= 5; w++) + { + mp_size_t n = (UWORD(1)< +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fft.h" + +int +main(void) +{ + mp_bitcnt_t depth, w; + int iters; + + FLINT_TEST_INIT(state); + + flint_printf("mulmod_2expp1...."); + fflush(stdout); + + + _flint_rand_init_gmp(state); + + for (iters = 0; iters < 100; iters++) + { + for (depth = 6; depth <= 18; depth++) + { + for (w = 1; w <= 2; w++) + { + mp_size_t n = (UWORD(1)< +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fft.h" + +/* set p = 2^wn + 1 */ +void set_p(mpz_t p, mp_size_t n, mp_bitcnt_t w) +{ + flint_mpz_set_ui(p, 1); + mpz_mul_2exp(p, p, n*w); + flint_mpz_add_ui(p, p, 1); +} + +int +main(void) +{ + mp_bitcnt_t bits; + mp_size_t j, k, n, w, limbs; + mp_limb_t * nn; + mpz_t p, m1, m2; + + FLINT_TEST_INIT(state); + + flint_printf("normmod_2expp1...."); + fflush(stdout); + + + _flint_rand_init_gmp(state); + + mpz_init(m1); + mpz_init(m2); + mpz_init(p); + + /* normalisation mod p = 2^wn + 1 where B divides nw and n is a power of 2 */ + for (bits = FLINT_BITS; bits < 32*FLINT_BITS; bits += FLINT_BITS) + { + for (j = 1; j < 32; j++) + { + for (k = 1; k <= GMP_NUMB_BITS; k <<= 1) + { + n = bits/k; + w = j*k; + limbs = (n*w)/GMP_LIMB_BITS; + + nn = flint_malloc((limbs + 1)*sizeof(mp_limb_t)); + random_fermat(nn, state, limbs); + fermat_to_mpz(m1, nn, limbs); + set_p(p, n, w); + + mpn_normmod_2expp1(nn, limbs); + fermat_to_mpz(m2, nn, limbs); + mpz_mod(m1, m1, p); + + if (mpz_cmp(m1, m2) != 0) + { + flint_printf("FAIL:\n"); + flint_printf("mpn_normmod_2expp1 error\n"); + gmp_printf("want %Zx\n\n", m1); + gmp_printf("got %Zx\n", m2); + abort(); + } + + flint_free(nn); + } + } + } + + mpz_clear(m2); + mpz_clear(m1); + mpz_clear(p); + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fft/test/t-split_combine_bits.c b/external/flint-2.4.3/fft/test/t-split_combine_bits.c new file mode 100644 index 0000000..4d42cf9 --- /dev/null +++ b/external/flint-2.4.3/fft/test/t-split_combine_bits.c @@ -0,0 +1,95 @@ +/* + +Copyright 2009, 2011 William Hart. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY William Hart ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL William Hart OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those of the +authors and should not be interpreted as representing official policies, either expressed +or implied, of William Hart. + +*/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fft.h" + +int +main(void) +{ + int i; + mp_size_t j; + + FLINT_TEST_INIT(state); + + flint_printf("split/combine_bits...."); + fflush(stdout); + + + _flint_rand_init_gmp(state); + + for (i = 0; i < 10000; i++) + { + mp_size_t total_limbs = n_randint(state, 1000) + 1; + mp_limb_t * in = flint_malloc(total_limbs*sizeof(mp_limb_t)); + mp_limb_t * out = flint_calloc(total_limbs, sizeof(mp_limb_t)); + + mp_bitcnt_t bits = n_randint(state, 200) + 1; + mp_size_t limbs = (2*bits - 1)/FLINT_BITS + 1; + slong length = (total_limbs*FLINT_BITS - 1)/bits + 1; + + mp_limb_t ** poly; + poly = flint_malloc(length*sizeof(mp_limb_t *)); + for (j = 0; j < length; j++) + poly[j] = flint_malloc((limbs + 1)*sizeof(mp_limb_t)); + + flint_mpn_urandomb(in, state->gmp_state, total_limbs*FLINT_BITS); + + fft_split_bits(poly, in, total_limbs, bits, limbs); + fft_combine_bits(out, poly, length, bits, limbs, total_limbs); + + for (j = 0; j < total_limbs; j++) + { + if (in[j] != out[j]) + { + flint_printf("FAIL:\n"); + flint_printf("Error in limb %wd, %wu != %wu\n", j, in[j], out[j]); + abort(); + } + } + + flint_free(in); + flint_free(out); + + for (j = 0; j < length; j++) + flint_free(poly[j]); + + flint_free(poly); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fft/tune/tune-fft.c b/external/flint-2.4.3/fft/tune/tune-fft.c new file mode 100644 index 0000000..8695b1a --- /dev/null +++ b/external/flint-2.4.3/fft/tune/tune-fft.c @@ -0,0 +1,200 @@ +/* + +Copyright 2009, 2011 William Hart. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other materials + provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY William Hart ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL William Hart OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those of the +authors and should not be interpreted as representing official policies, either expressed +or implied, of William Hart. + +*/ + +#include +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fft.h" + +int +main(void) +{ + mp_bitcnt_t depth, w, depth1, w1; + clock_t start, end; + double elapsed; + double best = 0.0; + mp_size_t best_off, off, best_d, best_w; + + FLINT_TEST_INIT(state); + + flint_printf("/* fft_tuning.h -- autogenerated by tune-fft */\n\n"); + flint_printf("#ifndef FFT_TUNING_H\n"); + flint_printf("#define FFT_TUNING_H\n\n"); + flint_printf("#include \"gmp.h\"\n\n"); + flint_printf("#define FFT_TAB \\\n"); + fflush(stdout); + + + _flint_rand_init_gmp(state); + + flint_printf(" { "); fflush(stdout); + for (depth = 6; depth <= 10; depth++) + { + flint_printf("{ "); fflush(stdout); + for (w = 1; w <= 2; w++) + { + int iters = 100*((mp_size_t) 1 << (3*(10 - depth)/2)), i; + + mp_size_t n = (UWORD(1)<gmp_state, b1); + flint_mpn_urandomb(i2, state->gmp_state, b2); + + best_off = -1; + + for (off = 0; off <= 4; off++) + { + start = clock(); + for (i = 0; i < iters; i++) + mul_truncate_sqrt2(r1, i1, n1, i2, n2, depth - off, w*((mp_size_t)1 << (off*2))); + end = clock(); + + elapsed = ((double) (end - start)) / CLOCKS_PER_SEC; + + if (elapsed < best || best_off == -1) + { + best_off = off; + best = elapsed; + } + } + + flint_printf("%wd", best_off); + if (w != 2) flint_printf(","); + flint_printf(" "); fflush(stdout); + + flint_free(i1); + } + flint_printf("}"); + if (depth != 10) flint_printf(","); + flint_printf(" "); fflush(stdout); + } + + flint_printf("}\n\n"); + + best_d = 12; + best_w = 1; + best_off = -1; + + flint_printf("#define MULMOD_TAB \\\n"); + fflush(stdout); + flint_printf(" { "); fflush(stdout); + for (depth = 12; best_off != 1 ; depth++) + { + for (w = 1; w <= 2; w++) + { + int iters, i; + mp_size_t n = (UWORD(1)<gmp_state, int_limbs*FLINT_BITS); + flint_mpn_urandomb(i2, state->gmp_state, int_limbs*FLINT_BITS); + i1[int_limbs] = 0; + i2[int_limbs] = 0; + + depth1 = FLINT_CLOG2(bits); + depth1 = depth1/2; + + w1 = bits/(UWORD(1)<<(2*depth1)); + + best_off = -1; + + for (off = 0; off <= 4; off++) + { + start = clock(); + for (i = 0; i < iters; i++) + _fft_mulmod_2expp1(r1, i1, i2, int_limbs, depth1 - off, w1*((mp_size_t)1 << (off*2))); + end = clock(); + + elapsed = ((double) (end - start)) / CLOCKS_PER_SEC; + + if (best_off == -1 || elapsed < best) + { + best_off = off; + best = elapsed; + } + } + + start = clock(); + for (i = 0; i < iters; i++) + flint_mpn_mulmod_2expp1_basecase(r1, i1, i2, 0, bits, tt); + end = clock(); + + elapsed = ((double) (end - start)) / CLOCKS_PER_SEC; + if (elapsed < best) + { + best_d = depth + (w == 2); + best_w = w + 1 - 2*(w == 2); + } + + flint_printf("%wd", best_off); + if (w != 2) flint_printf(", "); fflush(stdout); + + flint_free(i1); + } + flint_printf(", "); fflush(stdout); + } + flint_printf("1 }\n\n"); + + flint_printf("#define FFT_N_NUM %wd\n\n", 2*(depth - 12) + 1); + + flint_printf("#define FFT_MULMOD_2EXPP1_CUTOFF %wd\n\n", ((mp_limb_t) 1 << best_d)*best_w/(2*FLINT_BITS)); + + flint_randclear(state); + + flint_printf("#endif\n"); + return 0; +} diff --git a/external/flint-2.4.3/fft_tuning.h b/external/flint-2.4.3/fft_tuning.h new file mode 100644 index 0000000..f7f94da --- /dev/null +++ b/external/flint-2.4.3/fft_tuning.h @@ -0,0 +1,19 @@ +/* fft_tuning.h -- autogenerated by tune-fft */ + +#ifndef FFT_TUNING_H +#define FFT_TUNING_H + +#include "gmp.h" + +#define FFT_TAB \ + { { 4, 4 }, { 4, 3 }, { 3, 2 }, { 2, 1 }, { 2, 1 } } + +#define MULMOD_TAB \ + { 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 1, 1 } + +#define FFT_N_NUM 19 + +#define FFT_MULMOD_2EXPP1_CUTOFF 128 + +#endif + diff --git a/external/flint-2.4.3/fft_tuning32.in b/external/flint-2.4.3/fft_tuning32.in new file mode 100644 index 0000000..27ff431 --- /dev/null +++ b/external/flint-2.4.3/fft_tuning32.in @@ -0,0 +1,19 @@ +/* fft_tuning.h -- autogenerated by tune-fft */ + +#ifndef FFT_TUNING_H +#define FFT_TUNING_H + +#include "gmp.h" + +#define FFT_TAB \ + { { 3, 3 }, { 3, 2 }, { 2, 1 }, { 2, 1 }, { 0, 0 } } + +#define MULMOD_TAB \ + { 4, 3, 3, 3, 3, 2, 2, 2, 3, 2, 2, 2, 2, 1, 1 } + +#define FFT_N_NUM 15 + +#define FFT_MULMOD_2EXPP1_CUTOFF 256 + +#endif + diff --git a/external/flint-2.4.3/fft_tuning64.in b/external/flint-2.4.3/fft_tuning64.in new file mode 100644 index 0000000..f7f94da --- /dev/null +++ b/external/flint-2.4.3/fft_tuning64.in @@ -0,0 +1,19 @@ +/* fft_tuning.h -- autogenerated by tune-fft */ + +#ifndef FFT_TUNING_H +#define FFT_TUNING_H + +#include "gmp.h" + +#define FFT_TAB \ + { { 4, 4 }, { 4, 3 }, { 3, 2 }, { 2, 1 }, { 2, 1 } } + +#define MULMOD_TAB \ + { 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 1, 1 } + +#define FFT_N_NUM 19 + +#define FFT_MULMOD_2EXPP1_CUTOFF 128 + +#endif + diff --git a/external/flint-2.4.3/flint.h b/external/flint-2.4.3/flint.h new file mode 100644 index 0000000..cf64ccc --- /dev/null +++ b/external/flint-2.4.3/flint.h @@ -0,0 +1,339 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#ifndef FLINT_H +#define FLINT_H + +#undef ulong +#define ulong ulongxx /* ensure vendor doesn't typedef ulong */ +#include /* for BSD define */ +#include +#include +#include +#include /* for alloca on FreeBSD */ +#if !defined(BSD) && !defined(__MINGW64__) && !defined(__MINGW32__) +/* MinGW and FreeBSD have alloca, but not alloca.h */ +#include +#endif +#if defined(__MINGW32__) +#include /* for alloca on MinGW */ +#endif +#include "limits.h" +#include "longlong.h" +#include "config.h" +#undef ulong + +#if HAVE_GC +#include "gc.h" +#endif + +#if WANT_ASSERT +#include +#endif + +#ifdef __cplusplus + extern "C" { +#endif + +/* flint version number */ + +#define __FLINT_VERSION 2 +#define __FLINT_VERSION_MINOR 4 +#define __FLINT_VERSION_PATCHLEVEL 3 +#define FLINT_VERSION "2.4.3" +#define __FLINT_RELEASE (__FLINT_VERSION * 10000 + \ + __FLINT_VERSION_MINOR * 100 + \ + __FLINT_VERSION_PATCHLEVEL) + +/* + Check mpir and mpfr version numbers +*/ +#if __GNU_MP_VERSION < 5 +#error GMP 5.0.0 or MPIR 2.6.0 or later are required +#endif + +#if MPFR_VERSION_MAJOR < 3 +#error MPFR 3.0.0 or later is required +#endif + +/* + We define alternative key words for "asm" and "inline", allowing + the code to be compiled with the "-ansi" flag under GCC + */ +#ifndef __GNUC__ + #define __asm__ asm + #define __inline__ inline +#endif + +extern char version[]; + +#define ulong mp_limb_t +#define slong mp_limb_signed_t + +void * flint_malloc(size_t size); +void * flint_realloc(void * ptr, size_t size); +void * flint_calloc(size_t num, size_t size); +void flint_free(void * ptr); + +typedef void (*flint_cleanup_function_t)(void); +void flint_register_cleanup_function(flint_cleanup_function_t cleanup_function); +void flint_cleanup(void); + +#if defined(_WIN64) +#define WORD_FMT "%ll" +#define WORD(xx) (xx##LL) +#define UWORD(xx) (xx##ULL) +#define UWORD_MAX ULLONG_MAX +#define UWORD_MIN ULLONG_MIN +#define WORD_MAX LLONG_MAX +#define WORD_MIN LLONG_MIN +#else +#define WORD_FMT "%l" +#define WORD(xx) (xx##L) +#define UWORD(xx) (xx##UL) +#define UWORD_MAX ULONG_MAX +#define UWORD_MIN ULONG_MIN +#define WORD_MAX LONG_MAX +#define WORD_MIN LONG_MIN +#endif + +#if GMP_LIMB_BITS == 64 + #define FLINT_BITS 64 + #define FLINT_D_BITS 53 + #define FLINT64 1 +#else + #define FLINT_BITS 32 + #define FLINT_D_BITS 31 +#endif + +#define mp_bitcnt_t ulong + +#if HAVE_TLS +#define FLINT_TLS_PREFIX __thread +#else +#define FLINT_TLS_PREFIX +#endif + +int flint_get_num_threads(void); +void flint_set_num_threads(int num_threads); + +int flint_test_multiplier(void); + +typedef struct +{ + gmp_randstate_t gmp_state; + int gmp_init; + mp_limb_t __randval; + mp_limb_t __randval2; +} flint_rand_s; + +typedef flint_rand_s flint_rand_t[1]; + +static __inline__ +void flint_randinit(flint_rand_t state) +{ + state->gmp_init = 0; +#if FLINT64 + state->__randval = UWORD(13845646450878251009); + state->__randval2 = UWORD(13142370077570254774); +#else + state->__randval = UWORD(4187301858); + state->__randval2 = UWORD(3721271368); +#endif +} + +static __inline__ +void _flint_rand_init_gmp(flint_rand_t state) +{ + if (!state->gmp_init) + { + gmp_randinit_default(state->gmp_state); + state->gmp_init = 1; + } +} + +static __inline__ +void flint_randclear(flint_rand_t state) +{ + if (state->gmp_init) + gmp_randclear(state->gmp_state); +} + +#if HAVE_GC +#define FLINT_GC_INIT() GC_init() +#else +#define FLINT_GC_INIT() +#endif + +#define FLINT_TEST_INIT(xxx) \ + flint_rand_t xxx; \ + FLINT_GC_INIT(); \ + flint_randinit(xxx) + +#define FLINT_TEST_CLEANUP(xxx) \ + flint_randclear(xxx); \ + flint_cleanup(); + +/* + We define this here as there is no mpfr.h + */ +typedef __mpfr_struct mpfr; + +#if WANT_ASSERT +#define FLINT_ASSERT(param) assert(param) +#else +#define FLINT_ASSERT(param) +#endif + +#define FLINT_MAX(x, y) ((x) > (y) ? (x) : (y)) +#define FLINT_MIN(x, y) ((x) > (y) ? (y) : (x)) +#define FLINT_ABS(x) ((slong)(x) < 0 ? (-(x)) : (x)) + +#define MP_PTR_SWAP(x, y) \ + do { \ + mp_limb_t * __txxx; \ + __txxx = x; \ + x = y; \ + y = __txxx; \ + } while (0) + +#define r_shift(in, shift) \ + ((shift == FLINT_BITS) ? WORD(0) : ((in) >> (shift))) + +#define l_shift(in, shift) \ + ((shift == FLINT_BITS) ? WORD(0) : ((in) << (shift))) + +#ifdef NEED_CLZ_TAB +extern const unsigned char __flint_clz_tab[128]; +#endif + +static __inline__ +unsigned int FLINT_BIT_COUNT(mp_limb_t x) +{ + unsigned int zeros = FLINT_BITS; + if (x) count_leading_zeros(zeros, x); + return FLINT_BITS - zeros; +} + +#define FLINT_FLOG2(k) (FLINT_BIT_COUNT(k) - 1) + +#define FLINT_CLOG2(k) FLINT_BIT_COUNT((k) - 1) + +#define flint_mpn_zero(xxx, nnn) \ + do \ + { \ + slong ixxx; \ + for (ixxx = 0; ixxx < (nnn); ixxx++) \ + (xxx)[ixxx] = UWORD(0); \ + } while (0) + +#define flint_mpn_copyi(xxx, yyy, nnn) \ + do { \ + slong ixxx; \ + for (ixxx = 0; ixxx < (nnn); ixxx++) \ + (xxx)[ixxx] = (yyy)[ixxx]; \ + } while (0) + +#define flint_mpn_copyd(xxx, yyy, nnn) \ + do { \ + slong ixxx; \ + for (ixxx = nnn - 1; ixxx >= 0; ixxx--) \ + (xxx)[ixxx] = (yyy)[ixxx]; \ + } while (0) + +#define flint_mpn_store(xxx, nnn, yyy) \ + do \ + { \ + slong ixxx; \ + for (ixxx = 0; ixxx < nnn; ixxx++) \ + (xxx)[ixxx] = yyy; \ + } while (0) + +/* compatibility between gmp and mpir */ +#ifndef mpn_com_n +#define mpn_com_n mpn_com +#endif + +#ifndef mpn_neg_n +#define mpn_neg_n mpn_neg +#endif + +#ifndef mpn_tdiv_q +/* substitute for mpir's mpn_tdiv_q */ +static __inline__ +void mpn_tdiv_q(mp_ptr qp, + mp_srcptr np, mp_size_t nn, + mp_srcptr dp, mp_size_t dn) + { + mp_ptr _scratch = (mp_ptr) flint_malloc(dn * sizeof(mp_limb_t)); + mpn_tdiv_qr(qp, _scratch, 0, np, nn, dp, dn); + flint_free(_scratch); + } +#endif + +/* temporary allocation */ +#define TMP_INIT \ + typedef struct __tmp_struct { \ + void * block; \ + struct __tmp_struct * next; \ + } __tmp_t; \ + __tmp_t * __tmp_root; \ + __tmp_t * __tpx + +#define TMP_START \ + __tmp_root = NULL + +#define TMP_ALLOC(size) \ + ((size) > 8192 ? \ + (__tpx = alloca(sizeof(__tmp_t)), \ + __tpx->next = __tmp_root, \ + __tmp_root = __tpx, \ + __tpx->block = flint_malloc(size)) : \ + alloca(size)) + +#define TMP_END \ + while (__tmp_root) { \ + flint_free(__tmp_root->block); \ + __tmp_root = __tmp_root->next; \ + } + +int parse_fmt(int * floating, const char * fmt); + +size_t flint_printf(const char * str, ...); /* flint version of printf */ +size_t flint_fprintf(FILE * f, const char * str, ...); /* flint version of fprintf */ +size_t flint_sprintf(char * s, const char * str, ...); /* flint version of sprintf */ + +int flint_scanf(const char * str, ...); /* flint version of scanf */ +int flint_fscanf(FILE * f, const char * str, ...); /* flint version of fscanf */ +int flint_sscanf(const char * s, const char * str, ...); /* flint version of sscanf */ + +#include "gmpcompat.h" + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/external/flint-2.4.3/flint.supp b/external/flint-2.4.3/flint.supp new file mode 100644 index 0000000..e93a11e --- /dev/null +++ b/external/flint-2.4.3/flint.supp @@ -0,0 +1,16 @@ +{ + MPIR_MUL + Memcheck:Addr8 + fun:__gmpn_copyi + fun:__gmpn_mul + fun:_fmpz_poly_mul_KS +} + +{ + MPIR_MUL_N + Memcheck:Addr8 + fun:__gmpn_copyi + fun:__gmpn_mul_n + fun:_fmpz_poly_mul_KS +} + diff --git a/external/flint-2.4.3/flintxx.h b/external/flint-2.4.3/flintxx.h new file mode 100644 index 0000000..b2aecff --- /dev/null +++ b/external/flint-2.4.3/flintxx.h @@ -0,0 +1,26 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +// empty and only here to make the build system happy diff --git a/external/flint-2.4.3/flintxx/default_rules.h b/external/flint-2.4.3/flintxx/default_rules.h new file mode 100644 index 0000000..797c2b5 --- /dev/null +++ b/external/flint-2.4.3/flintxx/default_rules.h @@ -0,0 +1,395 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +// This file contains default rule implementations + +#ifndef CXX_DEFAULT_RULES_H +#define CXX_DEFAULT_RULES_H + +#include "mp.h" +#include "expression.h" // because we want to reuse binary_op_helper etc +#include "expression_traits.h" +#include "evaluation_tools.h" + +namespace flint { +namespace rules { +// Composite binary operators +// These rules implement binary operators by implementing both arguments +// separately, then performing the operation on the evaluated types by +// instantiating the appropriate rule again. +// +// Hence to evaluate expressions like a + (b + c), it suffices to write +// rules for composition of two immediates. + +namespace rdetail { + +template +struct can_evaluate_tuple : traits::is_implemented< + typename mp::find_evaluation::type, true>::type> { }; +template +struct should_evaluate_tuple : can_evaluate_tuple { }; +template +struct should_evaluate_tuple >::type> : mp::false_ { }; + +template +struct binary_should_enable +{ + typedef mp::enable_if::type> > enable; +}; +} + +template +struct evaluation >::type> +{ + typedef tools::evaluate_n evn_t; + typedef typename evn_t::evtup_t evtup_t; + typedef typename evn_t::temporaries_t temporaries_t; + typedef typename mp::find_evaluation< + Op, evtup_t, result_is_temporary>::type rule_t; + typedef typename rule_t::return_t return_t; + + template + static void doit(const Data& input, temporaries_t temps, Return* output) + { + evn_t ev(input, temps); + rule_t::doit(ev.gettuple(), empty_tuple(), output); + } +}; + +// Automatically invoke binary_expression or commutative_binary_expression +namespace rdetail { +template +struct inverted_binary_expression +{ + typedef commutative_binary_expression wrapped_t; + typedef typename wrapped_t::return_t return_t; + template + static void doit(Return& to, const Expr1& e1, const Expr2& e2) + { + return wrapped_t::doit(to, e2, e1); + } +}; + +template class BE, + class Data1, class Op, class Data2> +struct binary_expr_helper +{ + typedef typename traits::basetype::type data1_t; + typedef typename traits::basetype::type data2_t; + typedef BE wrapped_t; + typedef typename wrapped_t::return_t return_t; + typedef empty_tuple temporaries_t; + typedef typename mp::make_tuple::type data_t; + template + static void doit(const data_t& input, temporaries_t temps, Return* output) + { + wrapped_t::doit(*output, input.first(), input.second()); + } +}; +} // rdetail + +template +struct evaluation< + Op, tuple >, result_is_temporary, 0, + typename mp::enable_if< + mp::and_< + traits::is_immediate::type>, + mp::and_< + traits::is_immediate::type>, + mp::or_< + traits::is_implemented::type, + Op, + typename traits::basetype::type + > >, + mp::or_< + traits::is_implemented::type, + Op, + typename traits::basetype::type + > >, + traits::is_implemented::type, + Op, + typename traits::basetype::type + > > + > + > + > + > + >::type> + : mp::if_< + traits::is_implemented::type, + Op, + typename traits::basetype::type + > >, + rdetail::binary_expr_helper, + typename mp::if_< + traits::is_implemented::type, + Op, + typename traits::basetype::type + > >, + rdetail::binary_expr_helper< + commutative_binary_expression, Data1, Op, Data2>, + rdetail::binary_expr_helper< + rdetail::inverted_binary_expression, Data1, Op, Data2> + >::type + >::type +{ }; + + +// Automatically invoke unary_expression +template +struct evaluation, result_is_temporary, 0, + typename mp::enable_if< + traits::is_implemented< + unary_expression::type> > >::type> +{ + typedef unary_expression::type> wrapped_t; + typedef typename wrapped_t::return_t return_t; + typedef empty_tuple temporaries_t; + typedef typename mp::make_tuple::type data_t; + template + static void doit(const data_t& input, temporaries_t temps, Return* output) + { + wrapped_t::doit(*output, input.head); + } +}; + + +// Automatically invoke threeary_expression +template +struct evaluation > >, + result_is_temporary, 0, + typename mp::enable_if< + traits::is_implemented< + threeary_expression::type, + typename traits::basetype::type, + typename traits::basetype::type> > >::type> +{ + typedef threeary_expression::type, + typename traits::basetype::type, + typename traits::basetype::type> wrapped_t; + typedef typename wrapped_t::return_t return_t; + typedef empty_tuple temporaries_t; + typedef typename mp::make_tuple::type data_t; + template + static void doit(const data_t& input, temporaries_t temps, Return* output) + { + wrapped_t::doit(*output, mp::tuple_get::get(input), + mp::tuple_get::get(input), + mp::tuple_get::get(input)); + } +}; +// Automatically invoke fourary_expression +template +struct evaluation > > >, + result_is_temporary, 0, + typename mp::enable_if< + traits::is_implemented< + fourary_expression::type, + typename traits::basetype::type, + typename traits::basetype::type, + typename traits::basetype::type> > >::type> +{ + typedef fourary_expression::type, + typename traits::basetype::type, + typename traits::basetype::type, + typename traits::basetype::type> wrapped_t; + typedef typename wrapped_t::return_t return_t; + typedef empty_tuple temporaries_t; + typedef typename mp::make_tuple::type data_t; + template + static void doit(const data_t& input, temporaries_t temps, Return* output) + { + wrapped_t::doit(*output, mp::tuple_get::get(input), + mp::tuple_get::get(input), + mp::tuple_get::get(input), + mp::tuple_get::get(input)); + } +}; +// Automatically invoke fiveary_expression +template +struct evaluation > > > >, + result_is_temporary, 0, + typename mp::enable_if< + traits::is_implemented< + fiveary_expression::type, + typename traits::basetype::type, + typename traits::basetype::type, + typename traits::basetype::type, + typename traits::basetype::type> > >::type> +{ + typedef fiveary_expression::type, + typename traits::basetype::type, + typename traits::basetype::type, + typename traits::basetype::type, + typename traits::basetype::type> wrapped_t; + typedef typename wrapped_t::return_t return_t; + typedef empty_tuple temporaries_t; + typedef typename mp::make_tuple::type data_t; + template + static void doit(const data_t& input, temporaries_t temps, Return* output) + { + wrapped_t::doit(*output, mp::tuple_get::get(input), + mp::tuple_get::get(input), + mp::tuple_get::get(input), + mp::tuple_get::get(input), + mp::tuple_get::get(input)); + } +}; +// Automatically invoke sixary_expression +template +struct evaluation > > > > >, + result_is_temporary, 0, + typename mp::enable_if< + traits::is_implemented< + sixary_expression::type, + typename traits::basetype::type, + typename traits::basetype::type, + typename traits::basetype::type, + typename traits::basetype::type, + typename traits::basetype::type> > >::type> +{ + typedef sixary_expression::type, + typename traits::basetype::type, + typename traits::basetype::type, + typename traits::basetype::type, + typename traits::basetype::type, + typename traits::basetype::type> wrapped_t; + typedef typename wrapped_t::return_t return_t; + typedef empty_tuple temporaries_t; + typedef typename mp::make_tuple::type data_t; + template + static void doit(const data_t& input, temporaries_t temps, Return* output) + { + wrapped_t::doit(*output, mp::tuple_get::get(input), + mp::tuple_get::get(input), + mp::tuple_get::get(input), + mp::tuple_get::get(input), + mp::tuple_get::get(input), + mp::tuple_get::get(input)); + } +}; +// Automatically invoke sevenary_expression +template +struct evaluation > > > > > >, + result_is_temporary, 0, + typename mp::enable_if< + traits::is_implemented< + sevenary_expression::type, + typename traits::basetype::type, + typename traits::basetype::type, + typename traits::basetype::type, + typename traits::basetype::type, + typename traits::basetype::type, + typename traits::basetype::type> > >::type> +{ + typedef sevenary_expression::type, + typename traits::basetype::type, + typename traits::basetype::type, + typename traits::basetype::type, + typename traits::basetype::type, + typename traits::basetype::type, + typename traits::basetype::type> wrapped_t; + typedef typename wrapped_t::return_t return_t; + typedef empty_tuple temporaries_t; + typedef typename mp::make_tuple::type data_t; + template + static void doit(const data_t& input, temporaries_t temps, Return* output) + { + wrapped_t::doit(*output, mp::tuple_get::get(input), + mp::tuple_get::get(input), + mp::tuple_get::get(input), + mp::tuple_get::get(input), + mp::tuple_get::get(input), + mp::tuple_get::get(input), + mp::tuple_get::get(input)); + } +}; + +// Instantiating temporaries + +namespace rdetail { +template +struct evaluated_type_pred +{ + template + struct type : mp::equal_types< + typename tools::evaluation_helper::type, T> { }; +}; +} + +template +struct use_default_temporary_instantiation : mp::true_ { }; + +template +struct instantiate_temporaries +{ + static T get(const Expr& e) + { + return T(); + } +}; + +template +struct instantiate_temporaries, + traits::is_expression, + tools::has_subexpr, Expr> > >::type> +{ + static T get(const Expr& e) + { + return tools::find_subexpr >(e) + .create_temporary(); + } +}; + +} // rules +} // flint + + +#endif diff --git a/external/flint-2.4.3/flintxx/doc/Makefile b/external/flint-2.4.3/flintxx/doc/Makefile new file mode 100644 index 0000000..d6f7c37 --- /dev/null +++ b/external/flint-2.4.3/flintxx/doc/Makefile @@ -0,0 +1,4 @@ +include LaTeX.mk + +design: design.pdf + evince $< diff --git a/external/flint-2.4.3/flintxx/doc/design.tex b/external/flint-2.4.3/flintxx/doc/design.tex new file mode 100644 index 0000000..29c0323 --- /dev/null +++ b/external/flint-2.4.3/flintxx/doc/design.tex @@ -0,0 +1,423 @@ +% vim:spell spelllang=en_us textwidth=75 + +\documentclass{scrartcl} +\usepackage[utf8]{inputenc} +\usepackage{amsfonts} + +\title{A generic expression template library for arithmetic data types} +\author{Tom Bachmann\footnote{\texttt{e\_mc\_h2@web.de}}} + +\begin{document} +\maketitle + +\section*{Introduction} + + This note describes the design I plan to implement this summer for a c++ +wrapper for the FLINT library\footnote{\texttt{www.flintlib.org}}. + +Any kinds of comments are appreciated. + +\emph{Added after the summer}: this document turned out to be reasonably +accurate. I updated it slightly to reflect what was actually done. + +\paragraph{Overview} +In first approximation, FLINT implements arithmetic operations on and +representations of elements of specific rings, \emph{with unlimited +precision}. The implemented rings include $\mathbb{Z}, \mathbb{Q}, +\mathbb{Z}[X], \mathbb{Z}[X_{ij}], \mathbb{F}_q[X], \mathbb{Z}/n\mathbb{Z}$ +and similar ones. FLINT is written in C, so arithmetic operations look like +\texttt{fmpz\_add(target, source1, source2)}. In crude terms, this note +describes how to write a C++ wrapper, allowing us to turn the above +expression into \texttt{target = source1 + source2}. + + +\section*{Objectives} + +The wrapper library has to satisfy a number of competing objectives: + +\begin{description} +\item[Performance] Whenever feasible, the C++ code should compile down into + equivalent C code which is as close in performance to hand-written code as + possible. +\item[Portability] The library should be usable on as many different + compilers and compiler versions as possible. +\item[Easy extensibility] It should be straightforward for FLINT developers + (which may only know C) to extend the wrapper library to add a new data + type. +\item[Completeness] The wrapper library should expose all FLINT C + functions. +\end{description} + +There are also the following secondary objectives: + +\begin{itemize} +\item If possible, the library should be sufficiently generic to be used by + other open source projects seeking to create a C++ wrapper. +\item If possible, the wrapper should anticipate and/or facilitate + generics. +\item The wrapper should allow for further layers of abstraction, e.g. to + provide an NTL-compatible interface. +\end{itemize} + + +\section*{Design} + +In order to meet the above goals, we have made the following decisions. +Performance will be achieved using expression templates, following the +C++98 standard. To improve diagnostics, we will use static assert +frequently (in C++98 mode we use standard implementations, in C++11 mode we +use the language internal one). There will be no automatic casts. The +wrapper library will be split clearly into FLINT-specific and generic +parts. + +\subsection*{Overview} + +Consider an expression like \texttt{fmpz a = b + c * d}. In an expression +template library, this consists of two stages. The first is expression +template \emph{parsing}, and the second is \emph{execution}. +The expression \texttt{b + c +* d} results in a temporary object, the type of which encodes the +operations performed, and the state of which consists of references to the +arguments \texttt{b}, \texttt{c} and \texttt{d}. The assignment then +triggers the execution. This means the library figures out how to most +efficiently evaluate the expression. In general, this may require the +allocation of a temporary \texttt{t}, and then executing \texttt{t = c * +d}, \texttt{a = b + t}. In the case of a newly initialized \texttt{a} as +here, we can avoid \texttt{t} and use \texttt{a} as a temporary. +Additionally, for some data types the C library may support addmul-type +operations, so we can compile down to a single C call. + +\subsection*{Expression template representation and execution} + +In order to facilitate reuse and extensibility, we decouple and modularize +the steps explained above. The main expression template class has +declaration as follows: + +\begin{verbatim} +template +class Expression +... +\end{verbatim} + +The template argument \texttt{Operation} specifies which operation is to be +executed (for example ``plus'', ``times'' or even ``exp''), whereas +\texttt{Data} encodes the actual data required to perform the operation. +Part of the body of the class could look like this: + +\begin{verbatim} +{ +protected: + Data data; + +public: + typedef Operation op_t; + typedef Data data_t; + + explicit Expression(Data d) : data (d) {}; + + template + typename Derived::template type > + operator+(const Right& r) + { + return Derived::template type >( + Pair(*this, r); + } +}; +\end{verbatim} + +There are a few peculiarities to note. Firstly \texttt{Plus} is just +an empty type, which simply serves as a tag. Secondly \texttt{Pair} is just +what it sounds like (essentially \texttt{std::pair}). But more importantly, +the template parameter \texttt{Derived} is used to automatically wrap +expression templates into a convenience derived class. It could look like +this: + +\begin{verbatim} +template +struct derived +{ + template + struct type + : Expression + { + template + explicit type(const T& t) : Expression(t) {} + + void foo() {Policy();} + }; +}; +\end{verbatim} + +We still have not reached the type the user is actually going to +instantiate. For this, we can use a special type of operation that +signifies an immediate data. For example: + +\begin{verbatim} +typedef derived::type Fmpz; +\end{verbatim} + +All the indirection allows us to have instances of \texttt{Fmpz} come with a member +function \texttt{foo} which is customised by the ``StandardPolicy''. Note +that currently there are no non-trivial constructors or destructors for +Fmpz. These can be injected either via traits (see below), or via member +template enabling. + +Next, we describe the execution stage. For this, we extend the +\texttt{Expression} class by an assignment operator, which uses a traits +library to run the execution. A simple version might look like this: + +\begin{verbatim} +template<...> class Expression +{ +... + template + typename Derived::template type& operator=(const Other& o) + { + typedef traits::evaluate evaluator; + traits::assign::doit( + *this, evaluator::doit(o)); + } +}; + +namespace traits { +template struct evaluate; + +template +struct evaluate_helper; + +template +struct evaluate::type > +{ + typedef evaluate_helper helper; + typedef typename helper::return_type return_type; + + template + return_type doit(const T& t){return helper::doit(t.data());} +}; + +template<> +struct evaluate_helper > +{ + typedef Fmpz return_type; + Fmpz doit(const Pair& data) + { + ... + } +}; + +template +struct evaluate_helper > +{ + typedef evaluate leval_t; + typedef evaluate reval_t; + typedef evaluate_helper > eh_t; + typedef typename eh_t::return_type return_type; + return_type doit(const Pair& data) + { + leval_t::return_type t1 = leval_t::doit(data.left.data()); + reval_t::return_type t2 = reval_t::doit(data.right.data()); + return eh_t::doit(make_pair(t1, t2)); + } +}; +} +\end{verbatim} + +This code can evaluate arbitrary additions of Fmpz. It should be extended +to use three argument add, etc. + +\subsection*{Temporary allocation} + +The above design is functional, but results in unnecessarily many +temporaries. Instead, ... + +\subsection*{Conflict resolution for traits} + +A common problem with partial template specialisation is that instantiation +can fail completely if no partial order can be established. I propose two +ways around this: conditional template enabling, and a priority system. By +conditional template enabling I mean the equivalent of +\texttt{boost.enable\_if}. By a priority system, I mean adding an +additional integer template parameter \texttt{priority}, and having most +traits only enable themselves if the priority is a certain fixed number. +Then, using SFINAE techniques, we can iterate through the priorities and +use the highest-priority match. + +This latter technique has the desirable property of being easy to +understand and use by non-experts. + +\section*{Future plans} + +The following sections contain deliberations about things which I did not +manage to work on this summer. + +\subsection*{Class structure for (FLINT) generics} + +Corresponding to any ring (or sometimes module), +there will be two classes: the \emph{context} +representing the ring itself, and the \emph{element} representing elements +of the ring. Contexts are immutable, but elements are usually not. Often +the context will be essentially empty (e.g. for $\mathbb{Z}$), but +sometimes it may hold data common to all elements, e.g. the modulus $n$ of +$\mathbb{Z}/n\mathbb{Z}.$ Every element instance holds a reference to a +context. In general arithmetic operations are only supported if the +contexts agree, but this is not usually checked. + +We also differentiate between \emph{primitive +types}, \emph{compound types} and \emph{specialised types}. The primitive +types such as $\mathbb{Z}, \mathbb{Q}_p$ +are the building blocks and are atomic from the point of view of this +wrapper. Compound types such as $A[T]$ (for any ring $A$) or $Frac(A)$ (for +domains $A$) are built from primitive and compound types. They have +implementations of arithmetic operations in terms of operations in $A,$ and +so are generic. Finally the specialised types are versions of compound +types with particular arithmetic implementations tailored to the particular +type, e.g. $\mathbb{Z}[T]$ (where multiplication can be implemented using +polynomial reconstruction and multiplication in $\mathbb{Z}$). + +For the initial implementation, the generic types will not come with +arithmetic implementations. Instead I will focus on wrapping all the +particular implementations in FLINT. + +Tables \ref{tab:primitive-types}, \ref{tab:compound-types} and +\ref{tab:specialised-types} list the primitive, compound, and specialised +types of the FLINT wrapper. + +\begin{table}[h] +\begin{center} +\begin{tabular}{cc} +FLINT name & representing \\ +\hline +fmpz & $\mathbb{Z}$ \\ +padic & $\mathbb{Q}_p$ (to fixed accuracy) \\ +ulong & $\mathbb{Z}/2^{s}\mathbb{Z}$ (where $s$ is the machine wordsize) \\ +\end{tabular} +\end{center} +\caption{Primitive types for the FLINT wrapper.} +\label{tab:primitive-types} +\end{table} + +\begin{table}[h] +\begin{center} +\begin{tabular}{cc} +wrapper name & representing \\ +\hline +poly & $A[T]$ \\ +fraction & $Frac(A)$ ($A$ a domain) \\ +PIquotient & $A/aA$ \\ +vector (not actually a ring) & $A^n$ (with $n$ large) \\ +matrix (not always a ring) & $n \times m$ matrices over $A$ (with $m, n$ large) \\ +\end{tabular} +\end{center} +\caption{Compound types for the FLINT wrapper.} +\label{tab:compound-types} +\end{table} + +A potential later addition could be fixed-size vectors and matrices with +automatically unrolled operations. + +\begin{table}[h] +\begin{center} +\begin{tabular}{cc} +FLINT name & specialising compound type \\ +\hline +fmpq & \texttt{fraction} \\ +fmpz\_poly\_q & \texttt{fraction>} \\ +\\ +``mod'' & \texttt{PIquotient} \\ +nmod & \texttt{PIquotient} \\ +\\ +fmpz\_poly & \texttt{poly} \\ +fmpq\_poly & \texttt{poly} \\ +nmod\_poly & \texttt{poly} \\ +fmpz\_mod\_poly & \texttt{poly } \\ +\\ +fmpz\_vec & \texttt{vector} \\ +nmod\_vec & \texttt{vector>} \\ +\\ +fmpz\_mat & \texttt{matrix} \\ +fmpq\_mat & \texttt{matrix>} \\ +fmpz\_poly\_mat & \texttt{matrix>} \\ +nmod\_mat & \texttt{matrix>} \\ +nmod\_poly\_mat & \texttt{matrix>>} +\end{tabular} +\end{center} +\caption{Specialised types for the FLINT wrapper.} +\label{tab:specialised-types} +\end{table} + +\subsection*{Wrapper class with additional member functions} + +The above design already allows for members on every type. But suppose I +want to add a class \texttt{Tmpz} which behaves much +like \texttt{Fmpz}, except that it has different member functions. That is, +suppose I want to create a drop-in replacement for some other library, +leveraging the flint backend. This can be done as follows (in the +simplified notation without temporary avoidance): + +\begin{verbatim} +struct derived2 +{ + template + struct type + : Expression + { + template + explicit type(const T& t) : Expression(t) {} + + void bar() {} + } +}; +typedef derived2::type Tmpz; + +namespace traits { +template +struct convert; + +template +struct convert +{ + typedef derived::template type::return_type> return_type; + template + return_type doit(const T& t) + { + return return_type(convert::doit(t.data())); + } +}; + +template<> +struct convert +{ + typedef Fmpz return_type; + + template + return_type doit(const T& t) + { + return t.data(); + } +} + +template +struct evaluate > +{ + typedef convert > eh2_t; + typedef evaluate::return_type ev_t; + typedef ev_t::return_type return_type; + template + return_type doit(const T& t) + { + return ev_t::doit(eh2_t::doit(t)); + } +}; +} +\end{verbatim} + +That is to say, evaluation of Tmpz first converts the expression template +into the Fmpz equivalent (this does not incur any cost), then evaluates the +Fmpz, and then (using the implementation of assign not shown) wraps into +Tmpz again. The beauty of this approach is that the underlying type is +never leaked accidentally to the user, yet still all the optimizations for +FLINT expression templates apply. + +\end{document} diff --git a/external/flint-2.4.3/flintxx/doc/flintxx.txt b/external/flint-2.4.3/flintxx/doc/flintxx.txt new file mode 100644 index 0000000..e87f083 --- /dev/null +++ b/external/flint-2.4.3/flintxx/doc/flintxx.txt @@ -0,0 +1,4772 @@ +/*============================================================================= +vim: spell spelllang=en textwidth=79 + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + + TODO: split this file up? + +******************************************************************************/ + +******************************************************************************* + + flint\_exception + + This is the main exception type used by the flintxx library. It derives + from \code{std::domain_error}. As such its main method is \code{what()}, + yielding an English language description of the problem encountered. + +******************************************************************************* + +******************************************************************************* + + frandxx + + The type \code{frandxx} wraps \code{flint_rand_t} and takes care of + initialising and clearing random states. It is defined in + \code{flintxx/frandxx.h}. Note that this type is not copyable. + +******************************************************************************* + +frandxx::frandxx() + + Initialize random state. + +flint_rand_t& frandxx::_data() +const flint_rand_t& frandxx::_data() const + + Obtain a reference to the underlying C random state. + + +******************************************************************************* + + ltuple + + Lazy tuples are implemented in \code{flintxx/ltuple.h}. They are used + throughout flintxx to emulate functions with several return values. + + This header automatically creates a static instance of + \code{flint::detail::IGNORED_TYPE}. It is accessible in namespace flint, + under the name \code{FLINT_LTUPLE_PLACEHOLDER_NAME}, which defaults to + \code{_}. See \code{ltupleref} documentation for how to use this. + +******************************************************************************* + +Ltuple ltupleref(T1& t1, ..., Tn& tn) + + Construct an ltuple of references, binding to the arguments \code{t1}, + \dots, \code{tn}. Instances of \code{flint::detail::IGNORED_TYPE} can be + used as placeholders. + Currently $n \le 4$. + +Ltuple ltuple(const T1& t1, ..., const Tn& tn) + + Construct an ltuple containing copies of \code{t1}, \dots, \code{tn}. + Currently \code{n \le 4}. + +Tk_expr Ltuple_expr::get() const + + If \code{Tk} is an expression template type, then the \code{get()} + method returns a lazy expression evaluating to the kth element of the + (potentially lazy) ltuple. + + If \code{Tk} is not an expression template type, this method evaluates the + ltuple, and returns the kth entry. + + On ltuple immediates, reference versions are also available, which can + be used to manipulate the entries. + +******************************************************************************* + + permxx + + Permutations are mostly used by row reduction algorithms. Even though we + support limited arithmetic on them (e.g. composition), permutations are not + implemented as expression templates. + + \code{permxx} wraps the C interface \code{perm} operating on \code{slong*}. + +******************************************************************************* + +permxx::permxx(slong n) +static permxx permxx::one(slong n) + + Initialize an identity permutation on the set $[n] = \{0, 1, \dots, n-1\}$. + +static permxx permxx::randtest(slong n) + + Generate a random permutation on $[n]$. See \code{_perm_randtest}. + +bool permxx::operator==(const permxx&) +bool permxx::operator!=(const permxx&) + +slong permxx::size() const + + Return the size of the set being permuted ($n$ in the constructors). + +slong& operator[](slong i) +slong operator[](slong i) const + + Return the image of $i$ under the permutation. + +permxx permxx::operator*(const permxx&) +permxx compose(const permxx& p1, const permxx& p2) + + Compute the composition of two permutations. See \code{_perm_compose}. + +void permxx::set_inv(const permxx& o) + + Set self to the inverse permutation of \code{o}. + +permxx permxx::inv() const +permxx inv(const permxx&) + + Return the inverse permutation. + +int print(const permxx&) + + + +******************************************************************************* + + fmpzxx + +******************************************************************************* + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + C++ particulars ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_expr::unary operation() const + + The following unary functions are made available as member functions: + \code{sqrt}, \code{abs}. + +Fmpz_expr::binary operation(??) const + + The following binary functions are made available as member functions: + \code{cdiv_q}, \code{divexact}, \code{fdiv_qr}, \code{fdiv_r}, + \code{fdiv_r_2exp}, \code{gcd}, \code{gcdinv}, \code{invmod}, \code{lcm}, + \code{negmod}, \code{pow}, \code{rfac}, \code{root}, \code{sqrtmod}, + \code{tdiv_q}, \code{tdiv_q_2exp}, \code{tdiv_qr}, \code{xgcd}. + +Fmpz_expr::ternary operation(??, ??) const + + The following ternary functions are made available as member functions: + \code{divexact2}, \code{mul2}, \code{mul_tdiv_q_2exp}, \code{powm}. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Memory management ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +fmpzxx::fmpzxx() + + Initialize to zero. + +fmpzxx::fmpzxx(const char*) +fmpzxx::fmpzxx(T:is_integer) + + Initialize from a primitive data type. See \code{fmpz_set_str}, + \code{fmpz_set_si} and \code{fmpz_set_ui}. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Random generation ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +static fmpzxx fmpzxx::randbits(frandxx& state) + +static fmpzxx fmpzxx::randtest(frandxx& state) + +static fmpzxx fmpzxx::randtest_unsigned(frandxx& state) + +static fmpzxx fmpzxx::randtest_not_zero(frandxx& state) + +static fmpzxx fmpzxx::randm(frandxx& state, Fmpz_expr m) + +static fmpzxx fmpzxx::randtest_mod(frandxx& state, Fmpz_expr m) + +static fmpzxx fmpzxx::randtest_mod_signed(frandxx& state, Fmpz_expr m) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Conversion ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +std::string Fmpz_expr::to_string(int base = 10) const + + Convert self into a \code{string}. See \code{fmpz_get_str}. + +slong Fmpz_expr::to() const + + Convert self to \code{slong}. See \code{fmpz_get_si}. + +slong Fmpz_expr::to() const + + Convert self to \code{ulong}. See \code{fmpz_get_si}. + +double Fmpz_expr::to() const + + Convert self to \code{double}. See \code{fmpz_get_d}. + +double Fmpz_expr::get_d_2exp(long& exp) const + +Fmpz_target Fmpz_target::operator=(const char*) +Fmpz_target Fmpz_target::operator=(T:is_integer) + + See \code{fmpz_set_str}, \code{fmpz_set_ui} and \code{fmpz_set_si}. + +void Fmpz_target::set_ui_smod(mp_limb_t x, mv_limb_t m) + +void Fmpz_target::set_uiui(mp_limb_t x, mv_limb_t m) + +void Fmpz_target::neg_uiui(mp_limb_t x, mv_limb_t m) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Input and output ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +int print(Fmpz_expr) +int print(FILE*, Fmpz_expr) +int read(Fmpz_target) +int read(FILE*, Fmpz_target) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Basic properties and manipulation ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +size_t Fmpz_expr::sizeinbase(int) const +size_t sizeinbase(Fmpz_expr, int) +mp_bitcnt_t Fmpz_expr::bits() const +mp_bitcnt_t bits(Fmpz_expr) +mp_bitcnt_t Fmpz_expr::size() const +mp_bitcnt_t size(Fmpz_expr) +mp_bitcnt_t Fmpz_expr::val2() const +mp_bitcnt_t val2(Fmpz_expr) +int Fmpz_expr::sign() const +int sign(Fmpz_expr) + +void Fmpz_target::set_zero() +void Fmpz_target::set_one() + +bool Fmpz_expr::abs_fits_ui() const +bool Fmpz_expr::fits_si() const + +void Fmpz_target::setbit(ulong) +bool Fmpz_expr::tstbit(ulong) const + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Comparision + + Relational operators \code{<=}, \code{>} + etc are overloaded, where \code{e1} and \code{e2} can be any + combination of \code{Fmpz_expr} and + \code{T:is_integer}. + See \code{fmpz_cmp}, \code{fmpz_cmp_si} and \code{fmpz_cmp_ui}. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +bool Fmpz_expr::is_zero() const + + Return if this expression evaluates to zero. + +bool Fmpz_expr::is_one() const + + Return if this expression evaluates to one. + +bool Fmpz_expr::is_pm1() const + + Return if this expression evaluates to $\pm 1$. + +bool Fmpz_expr::is_even() const + + Return if this expression evaluates to an even integer. + +bool Fmpz_expr::is_odd() const + + Return if the expression evaluates to an odd integer. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Basic arithmetic + + Arithmetic operators \code{+}, \code{-}, \code{*}, \code{/}, \code{%}, + \code{<<} and \code{>>} are overloaded. See the \code{fmpz} documentation + for which argument types are allowed. Symmetric operators with asymmetric + type arguments can be used in either order, even if this is not exposed in + the C interface. + + The shift operators wrap \code{fmpz_fdiv_q_2exp} and \code{fmpz_mul_2exp}. + The division operators use \code{fmpz_fdiv}. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_expr abs(Fmpz_expr) + +Fmpz_expr mul2_uiui(Fmpz_expr g, ulong x, ulong y) + +Fmpz_expr cdiv_q(Fmpz_expr, Fmpz_expr) +Fmpz_expr cdiv_q(Fmpz_expr, T:is_integer) + +Fmpz_expr tdiv_q(Fmpz_expr, Fmpz_expr) +Fmpz_expr tdiv_q(Fmpz_expr, T:is_integer) + +Fmpz_expr divexact(Fmpz_expr, Fmpz_expr) +Fmpz_expr divexact(Fmpz_expr, T:is_integer) + +Fmpz_expr fdiv_r(Fmpz_expr, Fmpz_expr) + +Fmpz_expr tdiv_q_2exp(Fmpz_expr, T:is_unsigned_integer) + +Fmpz_expr fdiv_r_2exp(Fmpz_expr, T:is_unsigned_integer) + +Fmpz_expr divexact2(Fmpz_expr g, ulong x, ulong y) + +Fmpz_expr mul_tdiv_q_2exp(Fmpz_expr g, Fmpz_expr x, ulong exp) +Fmpz_expr mul_tdiv_q_2exp(Fmpz_expr g, long x, ulong exp) + +Ltuple_expr fdiv_qr(Fmpz_expr g, Fmpz_expr h) +Ltuple_expr tdiv_qr(Fmpz_expr g, Fmpz_expr h) + +bool Fmpz_expr::divisible(Fmpz_expr) const +bool Fmpz_expr::divisible(T:fits_into_slong) const +bool divisible(Fmpz_expr n, Fmpz_expr d) +bool divisible(Fmpz_expr n, T:fits_into_slong d) + + Return if $d$ divides $n$. See \code{fmpz_divisible}. + +Fmpz_expr powm(Fmpz_expr g, ulong e, Fmpz_expr m) +Fmpz_expr powm(Fmpz_expr g, Fmpz_expr e, Fmpz_expr m) + +Fmpz_expr pow(Fmpz_expr, T:is_unsigned_integer) + +long clog(Fmpz_expr x, Fmpz_expr b) +long clog(Fmpz_expr x, ulong b) + +long flog(Fmpz_expr x, Fmpz_expr b) +long flog(Fmpz_expr x, ulong b) + +double dlog(Fmpz_expr x) + +long Fmpz_expr::clog(Fmpz_expr) const +long Fmpz_expr::clog(T:is_unsigned_integer) const + +long Fmpz_expr::flog(Fmpz_expr) const +long Fmpz_expr::flog(T:is_unsigned_integer) const + +double Fmpz_expr::dlog() const + +Ltuple_expr sqrtmod(Fmpz_expr a, Fmpz_expr b) + + \code{ltupleref(b, N) = sqrtmod(A, B)} has the same effect as + \code{b = fmpz_sqrtmod(n, a, b)}, where \code{n, a, b} are the underlying + \code{fmpz_t} of \code{N, A, B}. + +Ltuple_expr sqrtrem(Fmpz_expr g) + +Fmpz_expr sqrt(Fmpz_expr) + +bool Fmpz_expr::is_square() const + + Return if this expression evaluates to a square integer. + +Fmpz_expr root(Fmpz_expr, T:fits_into_slong) + +Fmpz_expr rfac(Fmpz_expr, T:is_unsigned_integer) + +Fmpz_expr fac(T:is_unsigned_integer) + +Fmpz_expr fib(T:is_unsigned_integer) + +Fmpz_expr bin(T:is_unsigned_integer, U:is_unsigned_integer) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Greatest common divisor ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Ltuple_expr gcdinv(Fmpz_expr f, Fmpz_expr g) + +Ltuple_expr xgcd(Fmpz_expr f, Fmpz_expr g) + +Fmpz_expr gcd(Fmpz_expr, Fmpz_expr) + +Fmpz_expr lcm(Fmpz_expr, Fmpz_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Modular arithmetic ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Ltuple_expr remove(Fmpzxx a, Fmpzxx b) + +int jacobi(Fmpz_expr a, Fmpz_expr p) +int Fmpz_expr::jacobi(Fmpz_expr) const + +Fmpz_expr invmod(Fmpz_expr, Fmpz_expr) + +Fmpz_expr negmod(Fmpz_expr, Fmpz_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Bit packing and unpacking + + Beware that argument orders are different relative to the C interface, to + facilitate default arguments. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +static Fmpz_expr fmpzxx::bit_unpack(const vector& v, + mp_bitcnt_t bits, mp_bitcnt_t shift = 0, + int negate = 0, bool borrow = false) +static Fmpz_expr fmpzxx::bit_unpack_unsigned(const vector& v, + mp_bitcnt_t bits, mp_bitcnt_t shift = 0) + + Unpack an \code{fmpzxx} from \code{v}. + +bool bit_pack(std::vector& v, mp_bitcnt_t bits, Fmpz_expr, + mp_bitcnt_t shift = 0, int negate = 0, bool borrow = false) + + Pack an \code{fmpzxx} to \code{v}. The vector \code{v} is required to be of + sufficient size. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Logic operations + + Binary logic operators \code{& | ^} (and, or, xor) are also overloaded + (implemented when both arguments are \code{Fmpz_expr}). ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +void Fmpz_target::clrbit(ulong i) + +void Fmpz_target::combit(ulong i) + +int Fmpz_expr::popcnt() const + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Chinese remaindering ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_expr Fmpz_expr::CRT(Fmpz_expr, T:is_unsigned_integer, + T:is_unsigned_integer, bool) const +Fmpz_expr CRT(Fmpz_expr, Fmpz_expr, T:is_unsigned_integer, + T:is_unsigned_integer, bool) + + See \code{fmpz_CRT_ui}. + +fmpz_combxx::fmpz_combxx(const std::vector& primes) + + The class \code{fmpz_combxx} wraps both \code{fmpz_comb_t} and + \code{fmpz_comb_temp_t}. The argument \code{primes} is the vector of moduli + to use, and must not be deallocated before the newly constructed + \code{fmpz_combxx}. Note that the internal \code{fmpz_comb_temp_t} + structure may be modified even on constant instances of \code{fmpz_combxx}. + +void multi_mod(std::vector& out, Fmpz_expr in, const fmpz_combxx& + comb) + + Reduce \code{in} modulo the primes stored in \code{comb}, and store the + results in \code{out}. The vector \code{out} must have sufficient size, and + its size will not be changed. + +Fmpz_expr multi_CRT(const std::vector& residues, const fmpz_combxx + comb, bool sign) + + Reconstruct an integer from its residues. See \code{fmpz_multi_CRT_ui}. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Primality testing ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +bool Fmpz_expr::is_probabprime() const + +bool Fmpz_expr::is_prime_pseudosquare() const + + +******************************************************************************* + + fmpz\_factorxx + +******************************************************************************* + +fmpz_factorxx::fmpz_factorxx() + + Initialise an empty factorisation. + +fmpz_factorxx::fmpz_factorxx(const fmpz_factorxx& o) + + Copy a factorisation. + +bool fmpz_factorxx::operator==(const fmpz_factorxx&) + + Compare two factorisations. + +ulong fmpz_factorxx::size() const + + Return the number of stored factors. + +ulong fmpz_factorxx::exp(slong i) const +ulong& fmpz_factorxx::exp(slong i) + + Obtain the exponent of the ith factor. + +fmpzxx_srcref fmpz_factorxx::p(slong i) const +fmpzxx_ref fmpz_factorxx::p(slong i) + + Obtain the ith factor. + +int fmpz_factorxx::sign() const +int& fmpz_factorxx::sign() + + Obtain the sign of the factored expression. + +void fmpz_factorxx::set_factor(Fmpz_expr) +void fmpz_factorxx::set_factor(T:fits_into_slong) +bool fmpz_factorxx::set_factor_trial_range(Fmpz_expr, ulong, ulong) +bool fmpz_factorxx::set_factor_pp1(Fmpz_expr, ulong, ulong, ulong) + + Factorise an integer and store its factors. See \code{fmpz_factor} etc. + +Fmpz_expr fmpz_factorxx::expand() const +Fmpz_expr fmpz_factorxx::expand_iterative() const +Fmpz_expr fmpz_factorxx::expand_multiexp() const + +fmpz_factorxx factor(Fmpz_expr) +fmpz_factorxx factor(T:fits_into_slong) +Ltuple_expr factor_trial_range(Fmpz_expr) +fmpz_factorxx factor_pp1(Fmpz_expr) + +void print(const fmpz_factorxx&) + + +******************************************************************************* + + fmpz\_matxx + + The class \code{fmpz_matxx} wraps \code{fmpz_mat_t}, and so represents + matrices with coefficients in $\mathbb{Z}$. + + Owing to the design of \code{fmpz_mat_t}, the use of \code{fmpz_matxx} + has a number of peculiarities. + \begin{itemize} + \item Matrix assignment does not automatically resize. This also includes + assigning (and thus evaluating) a lazy expression to an ordinary + matrix. As a consequence, the evaluation code cannot use temporary + merging, and may thus create more temporaries than a similar expression + involving non-matrices. + \item Several functions operating on \code{fmpz_mat_t} do not allow + aliasing. The flintxx layer just passes expressions on to the C layer, + so it is the responsibility of the user to avoid aliasing where it is + disallowed. Note that since no temporary merging is used with matrices, + aliases are never introduced by the evaluation code. + \end{itemize} + +******************************************************************************* + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Not yet split into subsections ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +slong Fmpz_mat_expr::rank() const + +Fmpz_expr Fmpz_mat_expr::det_modular_given_divisor( + Fmpz_mat_expr, Fmpz_expr) const + + See \code{fmpz_mat_det_modular_given_divisor}. + +Fmpz_mat_target Fmpz_mat_target::operator=(T:fits_into_slong) +Fmpz_mat_target Fmpz_mat_target::operator=(const char*) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + C++ particulars ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +slong Fmpz_mat_expr::rows() const +slong Fmpz_mat_expr::cols() const + + Obtain the number of rows/columns in this matrix. These functions never + cause evaluation (the matrix size is computed from the operations in the + expression template and the size of the input matrices). + +Fmpz_mat_expr::unary operation() const + + The following unary functions are made available as member functions: + \code{sqr}, \code{charpoly}, \code{det}, + \code{det_bareiss}, \code{det_bound}, \code{det_cofactor}, + \code{det_divisor}, \code{trace}, \code{transpose}. + +Fmpz_mat_expr::binary operation(??) const + + The following binary functions are made available as member functions: + \code{det_modular}, \code{det_modular_accelerated}, \code{divexact}, + \code{mul_classical}, \code{mul_multi_mod}, \code{pow}, + code{solve}, \code{solve_bound}, + \code{solve_cramer}, \code{solve_dixon}, \code{solve_fflu}. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Memory management ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +fmpz_matxx::fmpz_matxx(slong i, slong j) + + Allocate a matrix of size $i \times j$. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Basic assignment and manipulation ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +?? Fmpz_mat_expr::at(T:fits_into_slong, U:fits_into_slong) const + + Unified coefficient access to the matrix entries. + +void Fmpq_mat_target::set_zero() +void Fmpq_mat_target::set_one() +static fmpq_matxx fmpq_matxx::zero(slong rows, slong cols) +static fmpq_matxx fmpq_matxx::one(slong rows, slong cols) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Input and output ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +print(Fmpz_mat_expr) +print(FILE*, Fmpz_mat_expr) +print_pretty(Fmpz_mat_expr) +print_pretty(FILE*, Fmpz_mat_expr) +read(Fmpz_mat_target) +read(FILE*, Fmpz_mat_target) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Comparison + + The overloaded operator \code{==} can be used for equality testing. + Additionally, we have the following functions. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +bool Fmpz_mat_expr::is_zero() const +bool Fmpz_mat_expr::is_empty() const +bool Fmpz_mat_expr::is_quare() const + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Conversion ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +static fmpz_matxx fmpz_matxx::lift(Nmod_mat_expr) +static fmpz_matxx fmpz_matxx::lift_unsigned(Nmod_mat_expr) + + See \code{fmpz_mat_set_nmod_mat} and \code{fmpz_mat_set_nmod_mat_unsigned}. + +static fmpz_matxx fmpz_matxx::reduce(Fmpq_mat_expr, Fmz_expr) + + See \code{fmpq_mat_get_fmpz_mat_mod_fmpz}. + +static fmpz_matxx fmpz_matxx::from_integral_fraction(Fmpq_mat_expr) +void Fmpz_mat_target::set_integral_fraction(Fmpq_mat_expr) + + See \code{fmpq_mat_get_fmpz_mat}. Raises \code{flint_exception} if the + argument has non-integer entries. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Randomisation ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +void Fmpz_mat_target::set_randbits(frandxx& state, mp_bitcnt_t bits) +void Fmpz_mat_target::set_randtest(frandxx& state, mp_bitcnt_t bits) +void Fmpz_mat_target::set_randintrel(frandxx& state, mp_bitcnt_t bits) +void Fmpz_mat_target::set_randsimdioph(frandxx& state, mp_bitcnt_t bits, + mp_bitcount_t bits2) +void Fmpz_mat_target::set_randtrulike(frandxx& state, mp_bitcnt_t bits, + ulong q) +void Fmpz_mat_target::set_randtrulike2(frandxx& state, mp_bitcnt_t bits, + ulong q) +void Fmpz_mat_target::set_randajtai(frandxx& state, mp_bitcnt_t bits, + double alpha) +void Fmpz_mat_target::set_randrank(frandxx& state, slong rank, + mp_bitcnt_t bits) +void Fmpz_mat_target::set_randdet(frandxx& state, Fmpz_expr d) + + See \code{fmpz_mat_randbits} etc. + +static fmpz_matxx fmpz_matxx::randbits(slong r, slong c, + frandxx& state, mp_bitcnt_t bits) +static fmpz_matxx fmpz_matxx::randtest(slong r, slong c, + frandxx& state, mp_bitcnt_t bits) +static fmpz_matxx fmpz_matxx::randintrel(slong r, slong c, + frandxx& state, mp_bitcnt_t bits) +static fmpz_matxx fmpz_matxx::randsimdioph(slong r, slong c, + frandxx& state, mp_bitcnt_t bits, mp_bitcount_t bits2) +static fmpz_matxx fmpz_matxx::randtrulike(slong r, slong c, + frandxx& state, mp_bitcnt_t bits, ulong q) +static fmpz_matxx fmpz_matxx::randtrulike2(slong r, slong c, + frandxx& state, mp_bitcnt_t bits, ulong q) +static fmpz_matxx fmpz_matxx::randajtai(slong r, slong c, + frandxx& state, mp_bitcnt_t bits, double alpha) +static fmpz_matxx fmpz_matxx::randrank(slong r, slong c, + frandxx& state, slong rank, mp_bitcnt_t bits) +static fmpz_matxx fmpz_matxx::randdet(slong r, slong c, + frandxx& state, Fmpz_expr d) + + Static versions of the above, where the first two arguments specify the + dimensions of the matrix. + +int Fmpz_mat_target::set_randpermdiag(frandxx& state, Vec v) + + See \code{fmpz_mat_randpermdiag}. The type \code{vec} must have methods + \code{_array()} and \code{size()} similar to \code{fmpz_vecxx}. + +void Fmpz_mat_target::apply_randops(frandxx& state, slong count) + + See \code{fmpz_mat_randops}. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Transpose ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_expr transpose(Fmpz_mat_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Modular reduction and reconstruction + + To reduce a single matrix modulo a word-sized modulus, see + \code{nmod_matxx::reduce}. + + We use a special class \code{nmod_mat_vector} to represent a vector of + matrices reduced with respect to differing moduli. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_mat_expr Fmpz_mat_expr::CRT(Fmpz_expr, Nmod_mat_expr, bool) +Fmpz_mat_expr CRT(Fmpz_mat_expr, Fmpz_expr, Nmod_mat_expr, bool) + + See \code{fmpz_mat_CRT_ui}. + +nmod_mat_vector::nmod_mat_vector(slong rows, slong cols, + const std::vector& primes) + + Initialize a vector of matrices with dimensions given by \code{rows}, + \code{cols} and moduli given by \code{primes}. + +nmod_matxx_ref nmod_mat_vector::operator[](std::size_t idx) +nmod_matxx_srcref nmod_mat_vector::operator[](std::size_t idx) const + + Obtain a reference to one of the stored matrices. + +std::size_t nmod_mat_vector::size() const + + Obtain the number of stored matrices. + +void nmod_mat_vector::set_multi_mod(Fmpz_mat_expr m) + + Reduce \code{m} modulo each of the primes stored in this vector, and store + the results. See \code{fmpz_mat_multi_mod_ui}. + +void nmod_mat_vector::set_multi_mod_precomp(Fmpz_mat_expr m, + const fmpz_combxx& comb) + + Reduce \code{m} modulo each of the primes stored in this vector, and store + the results. Use precomputed data in \code{comp}. + See \code{fmpz_mat_multi_mod_ui_precomp}. + +nmod_mat_vector multi_mod(Fmpz_mat_expr m, const std::vector& + primes) +nmod_mat_vector multi_mod_precomp(Fmpz_mat_expr m, + const std::vector& primes, const fmpz_combxx& comb) + + Convenience functions combining the allocation of memory and modular + reduction. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Arithmetic + + The overloaded operators \code{+ - *} can be used for ordinary + matrix-matrix and matrix-scalar arithmetic. Additionally, we provide the + following functions. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_mat_expr divexact(Fmpz_mat_expr, Fmpz_expr) +Fmpz_mat_expr divexact(Fmpz_mat_expr, T:is_integer) + +Fmpz_mat_expr mul_classical(Fmpz_mat_expr, Fmpz_mat_expr) +Fmpz_mat_expr mul_multi_mod(Fmpz_mat_expr, Fmpz_mat_expr) + +Fmpz_expr sqr(Fmpz_mat_expr) +Fmpz_mat_expr pow(Fmpz_mat_expr, T:is_unsigned_integer) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Inverse ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Ltuple_expr inv(Fmpz_mat_expr) + + \code{ltupleref(b, M, D) = inv(A)} has the same effect as + \code{b = fmpz_mat_inv(m, d, a)}, where \code{m, d, a} are the underlying C + objects corresponding to \code{M, D, A}. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Trace ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_mat_expr trace(Fmpz_mat_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Determinant ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_expr det(Fmpz_mat_expr) +Fmpz_expr det_cofactor(Fmpz_mat_expr) +Fmpz_expr det_bareiss(Fmpz_mat_expr) +Fmpz_expr det_divisor(Fmpz_mat_expr) +Fmpz_expr det_bound(Fmpz_mat_expr) +Fmpz_expr det_modular(Fmpz_mat_expr, bool proved) +Fmpz_expr det_modular_accelerated(Fmpz_mat_expr, bool proved) +Fmpz_expr det_modular_given_divisor(Fmpz_mat_expr, Fmpz_expr, bool proved) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Characteristic polynomial ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_poly_expr charpoly(Fmpz_mat_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Rank ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +slong rank(Fmpz_mat_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Non-singular solving ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Ltuple_expr solve( + Fmpz_mat_expr B, Fmpz_mat_expr X) +Ltuple_expr solve_dixon( + Fmpz_mat_expr B, Fmpz_mat_expr X) +Ltuple_expr solve_cramer( + Fmpz_mat_expr B, Fmpz_mat_expr X) +Ltuple_expr solve_fflu( + Fmpz_mat_expr B, Fmpz_mat_expr X) + + \code{ltupleref(w, M, D) = solve(B, X)} has the same effect as + \code{w = fmpz_mat_solve(m, d, b, x)}, where \code{m, d, b, x} are the + underlying C objects corresponding to \code{M, D, B, X}. + Similarly for the other functions. + +Ltuple_expr solve_bound( + Fmpz_mat_expr B, Fmpz_mat_expr X) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Row reduction + + Beware that compared to the C interface, the flintxx row reduction + interface changes some argument orders. This is to facilitate default + arguments. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +slong find_pivot_any(Fmpz_mat_expr, slong, slong, slong) + + See \code{fmpz_mat_find_pivot_any}. + +Ltuple_expr fflu(Fmpz_mat_expr A, permxx* perm = 0, + bool rankcheck = false) + + See \code{fmpz_mat_fflu}. + +Ltuple_expr rref(Fmpz_mat_expr A) + + See \code{fmpz_mat_rref}. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Modular gaussian elimination ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +slong Fmpz_mat_target::set_rref_mod(Fmpz_expr n, permxx* perm = 0) + + See \code{fmpz_mat_rref_mod}. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Nullspace ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Ltuple_expr nullspace(Fmpz_mat_expr A) + + \code{ltupleref(n, B) = nullspace(A)} has the same effect as + \code{n = fmpz_mat_nullspace(b, a)}, where \code{b, a} are the underlying + \code{fmpz_mat_t} corresponding to \code{B, A}. + + + +******************************************************************************* + + fmpz\_polyxx + +******************************************************************************* + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + C++ particulars ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_poly_expr::unary operation() const + + The following unary functions are made available as member functions: + \code{derivative}, \code{primitive_part}, \code{sqr}, \code{sqr_classical}, + \code{sqr_karatsuba}, \code{sqr_KS}, \code{sqrt}, \code{sqrt_classical}, + \code{content}, \code{height}, \code{bound_roots}, \code{twonorm}. + +Fmpz_poly_expr::binary operation(??) const + + The following binary functions are made available as member functions: + \code{compose_divconquer}, \code{compose_horner}, \code{div_basecase}, + \code{div_divconquer}, \code{divexact}, \code{divrem}, + \code{divrem_basecase}, \code{divrem_divconquer}, \code{div_root}, + \code{evaluate_divconquer}, \code{evaluate_horner}, \code{fdiv_2exp}, + \code{gcd}, \code{gcd_heuristic}, \code{gcd_modular}, + \code{gcd_subresultant}, \code{inv_series}, \code{inv_series_newton}, + \code{lcm}, \code{mul_2exp}, \code{mul_classical}, \code{mul_karatsuba}, + \code{mul_KS}, \code{mulmid_classical}, \code{mul_SS}, + \code{shift_left}, \code{shift_right}, \code{pow}, + \code{pow_addchains}, \code{pow_binexp}, \code{pow_binomial}, + \code{pow_multinomial}, \code{pseudo_div}, \code{pseudo_divrem}, + \code{pseudo_divrem_basecase}, \code{pseudo_divrem_cohen}, + \code{pseudo_divrem_divconquer}, \code{pseudo_rem}, + \code{pseudo_rem_cohen}, \code{resultant}, \code{reverse}, + \code{revert_series}, \code{revert_series_lagrange}, + \code{revert_series_lagrange_fast}, \code{revert_series_newton}, + \code{smod}, \code{sqrlow}, \code{sqrlow_classical}, + \code{sqrlow_karatsuba_n}, \code{sqrlow_KS}, \code{taylor_shift}, + \code{taylor_shift_horner}, \code{taylor_shift_divconquer}, \code{tdiv}, + \code{tdiv_2exp}, \code{xgcd}, \code{xgcd_modular}, \code{divides}. + +Fmpz_poly_expr::ternary operation(??, ??) const + + The following ternary functions are made available as member functions: + \code{compose_series}, \code{compose_series_brent_kung}, + \code{compose_horner}, \code{div_series}, \code{mulhigh_classical}, + \code{mulhigh_karatsuba_n}, \code{mulhigh_n}, \code{mullow}, + \code{mullow_classical}, \code{mullow_karatsuba_n}, \code{mullow_KS}, + \code{mullow_SS}, \code{pow_trunc}. + +Fmpz_poly_expr Fmpz_poly_expr::operator()(Fmpz_poly_expr) const +Fmpz_poly_expr Fmpz_poly_expr::operator()(Fmpz_expr) const + + Overloaded \code{operator()} for evaluation or composition. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Memory management ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +fmpz_polyxx::fmpz_polyxx() + +fmpz_polyxx::fmpz_polyxx(slong alloc) + + See \code{fmpz_poly_init2}. + +fmpz_polyxx::fmpz_polyxx(const char* str) + + See \code{fmpz_poly_set_str}. + +void Fmpz_poly_target realloc(slong alloc) +void Fmpz_poly_target::fit_length(slong len) + +void Fmpz_poly_target::_normalise() +void Fmpz_poly_target::_set_length(slong len) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Polynomial parameters ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +slong Fmpz_poly_expr::length() const +slong Fmpz_poly_expr::degree() const + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Assignment and basic manipulation ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_poly_target Fmpz_poly_target::operator=(T:is_integer) +Fmpz_poly_target Fmpz_poly_target::operator=(Fmpz_expr) +Fmpz_poly_target Fmpz_poly_target::operator=(const char*) + +std::string Fmpz_poly_expr::to_string() const + +std::string Fmpz_poly_expr::pretty(const char* x) const + + See \code{fmpz_poly_get_str_pretty}. + +void Fmpz_poly_target::set_zero() +void Fmpz_poly_target::set_one() +static fmpz_polyxx fmpz_polyxx::zero() +static fmpz_polyxx fmpz_polyxx::one() + +void Fmpz_poly_target::zero_coeffs(slong i, slong j) + +Fmpz_poly_expr reverse(Fmpz_poly_expr, T:fits_into_slong) + +void Fmpz_poly_target::truncate(slong) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Randomisation ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +static fmpz_polyxx fmpz_polyxx::randtest( + frandxx& state, slong len, mp_bitcnt_t bits) +static fmpz_polyxx fmpz_polyxx::randtest_unsigned( + frandxx& state, slong len, mp_bitcnt_t bits) +static fmpz_polyxx fmpz_polyxx::randtest_not_zero( + frandxx& state, slong len, mp_bitcnt_t bits) + + See \code{fmpz_poly_randtest} etc. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Getting and setting coefficients ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_expr Fmpz_poly_expr::get_coeff(slong n) + + Obtain coefficient $n$ of the polynomial. It is valid to call this with $n$ + greater than the degree, in which case zero is returned. + +void Fmpz_poly_target::set_coeff(slong n, Fmpz_expr) +void Fmpz_poly_target::set_coeff(slong n, T:is_integer) + +?? Fmpz_poly_expr::coeff(slong n) const + + Unified coefficient access for coefficient $n$. + The result is undefined if $n$ is + greater than the degree of the polynomial (or negative). + + If the leading coefficient of the polynomial is set to zero in this way, a + call to \code{_normalise} is necessary. + +?? Fmpz_poly_expr::lead() const + + Unified coefficient access for the leading coefficient. + The result is undefined if + the length of the polynomial is zero. + + If this is used to set the leading coefficient to zero, + call to \code{_normalise} is necessary. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Comparison + + As usual, \code{fmpz_polyxx} can be compared using \code{operator==}. + Additionally, the following functions are provided. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +bool Fmpz_poly_expr::is_one() const +bool Fmpz_poly_expr::is_zero() const +bool Fmpz_poly_expr::is_unit() const + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Addition and subtraction + + The overloaded operators \code{+ -} can be used for addition, subtraction + and negation. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Scalar multiplication and division + + The overloaded operators \code{* /} can be used for scalar multiplication + and division, and the operator \code{\%} for remaindering. + For finer control, the following functions are provided. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_poly_expr mul_2exp(Fmpz_poly_expr, T:is_unsigned_integer) +Fmpz_poly_expr fdiv_2exp(Fmpz_poly_expr, T:is_unsigned_integer) + +Fmpz_poly_expr tdiv(Fmpz_poly_expr, Fmpz_expr) +Fmpz_poly_expr tdiv(Fmpz_poly_expr, T:is_integer) +Fmpz_poly_expr divexact(Fmpz_poly_expr, Fmpz_expr) +Fmpz_poly_expr divexact(Fmpz_poly_expr, T:is_integer) + +Fmpz_poly_expr smod(Fmpz_poly_expr, Fmpz_expr) + + See \code{fmpz_poly_scalar_smod_fmpz}. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Bit packing ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_expr bit_pack(Fmpz_poly_expr, T:fits_into_mp_bitcnt_t) +static Fmpz_poly_expr fmpz_polyxx::bit_unpack(Fmpz_expr, T:fits_into_mp_bitcnt_t) +static Fmpz_poly_expr fmpz_polyxx::bit_unpack_unsigned( + Fmpz_expr, traits::fits_into_mp_bitcnt_t) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Multiplication + + The overloaded operator \code{*} can also be used for poly-poly + multiplication. Additionally, the following functions are provided. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_poly_expr mul_classical(Fmpz_poly_expr, Fmpz_poly_expr) +Fmpz_poly_expr mulmid_classical(Fmpz_poly_expr, Fmpz_poly_expr) +Fmpz_poly_expr mul_karatsuba(Fmpz_poly_expr, Fmpz_poly_expr) +Fmpz_poly_expr mul_SS(Fmpz_poly_expr, Fmpz_poly_expr) +Fmpz_poly_expr mul_KS(Fmpz_poly_expr, Fmpz_poly_expr) + +Fmpz_poly_expr mullow(Fmpz_poly_expr, Fmpz_poly_expr, slong) +Fmpz_poly_expr mullow_classical(Fmpz_poly_expr, Fmpz_poly_expr, slong) +Fmpz_poly_expr mullow_karatsuba_n(Fmpz_poly_expr, Fmpz_poly_expr, slong) +Fmpz_poly_expr mullow_KS(Fmpz_poly_expr, Fmpz_poly_expr, slong) +Fmpz_poly_expr mullow_SS(Fmpz_poly_expr, Fmpz_poly_expr, slong) + +Fmpz_poly_expr mulhigh_n(Fmpz_poly_expr, Fmpz_poly_expr, slong) +Fmpz_poly_expr mulhigh_classical(Fmpz_poly_expr, Fmpz_poly_expr, slong) +Fmpz_poly_expr mulhigh_karatsuba_n(Fmpz_poly_expr, Fmpz_poly_expr, slong) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Squaring ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_poly_expr sqr(Fmpz_poly_expr) +Fmpz_poly_expr sqr_KS(Fmpz_poly_expr) +Fmpz_poly_expr sqr_karatsuba(Fmpz_poly_expr) +Fmpz_poly_expr sqr_classical(Fmpz_poly_expr) + +Fmpz_poly_expr sqrlow(Fmpz_poly_expr, T:fits_into_slong n) +Fmpz_poly_expr sqrlow_classical(Fmpz_poly_expr, T:fits_into_slong n) +Fmpz_poly_expr sqrlow_KS(Fmpz_poly_expr, T:fits_into_slong n) +Fmpz_poly_expr sqrlow_karatsuba_n(Fmpz_poly_expr, T:fits_into_slong n) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Powering ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_poly_expr pow(Fmpz_poly_expr, T:is_unsigned_integer) +Fmpz_poly_expr pow_multinomial(Fmpz_poly_expr, T:is_unsigned_integer) +Fmpz_poly_expr pow_binomial(Fmpz_poly_expr, T:is_unsigned_integer) +Fmpz_poly_expr pow_binexp(Fmpz_poly_expr, T:is_unsigned_integer) +Fmpz_poly_expr pow_addchains(Fmpz_poly_expr, T:is_unsigned_integer) +Fmpz_poly_expr pow_trunc(Fmpz_poly_expr, ulong e, slong n) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Shifting ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_poly_expr shift_left(Fmpz_poly_expr, T:fits_into_slong) +Fmpz_poly_expr shift_right(Fmpz_poly_expr, T:fits_into_slong) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Bit sizes and norms ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_expr height(Fmpz_poly_expr) +Fmpz_expr twonorm(Fmpz_poly_expr) + +ulong Fmpz_poly_expr::max_limbs() const +slong Fmpz_poly_expr::max_bits() const + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Greatest common divisor ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_poly_expr gcd(Fmpz_poly_expr, Fmpz_poly_expr) +Fmpz_poly_expr gcd_subresultant(Fmpz_poly_expr, Fmpz_poly_expr) +Fmpz_poly_expr gcd_heuristic(Fmpz_poly_expr, Fmpz_poly_expr) +Fmpz_poly_expr gcd_modular(Fmpz_poly_expr, Fmpz_poly_expr) +Fmpz_poly_expr lcm(Fmpz_poly_expr, Fmpz_poly_expr) + +Ltuple_expr xgcd(Fmpz_poly_expr f, + Fmpz_poly_expr g) +Ltuple_expr xgcd_modular(Fmpz_poly_expr f, + Fmpz_poly_expr g) + + \code{ltupleref(N, Q, R) = xgcd(F, G)} has the same effect as + \code{fmpz_poly_xgcd(n, q, r, f, g)} where \code{n, q, r, f, g} are the + underlying C objects. + +Fmpz_expr resultant(Fmpz_poly_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Gaussian content ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_expr content(Fmpz_poly_expr) +Fmpz_poly_expr primitive_part(Fmpz_poly_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Square-free ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +bool Fmpz_poly_expr::is_squarefree() const + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Euclidean division + + The overloaded operators \code{/ %} can be used for euclidean division and + remainder. Additionally, the following functions are provided. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_poly_expr div_basecase(Fmpz_poly_expr, Fmpz_poly_expr) +Fmpz_poly_expr div_divconquer(Fmpz_poly_expr, Fmpz_poly_expr) +Fmpz_poly_expr rem_basecase(Fmpz_poly_expr, Fmpz_poly_expr) + +Ltuple_expr divrem(Fmpz_poly_expr A, Fmpz_poly_expr B) +Ltuple_expr divrem_basecase(Fmpz_poly_expr A, + Fmpz_poly_expr B) +Ltuple_expr divrem_divconquer( + Fmpz_poly_expr A, Fmpz_poly_expr B) + + \code{ltupleref(Q, R) = divrem(A, B)} has the same effect as + \code{fmpz_poly_divrem(q, r, a, b)}, where \code{q, r, a, b} are the + underlying \code{fmpz_poly_t} corresponding to \code{Q, R, A, B}. + +Fmpz_poly_expr div_root(Fmpz_poly_expr, Fmpz_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Divisibility testing ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Ltuple_expr divides(Fmpz_poly_expr A, Fmpz_poly_expr B) + + \code{ltupleref(d, Q) = divides(A, B)} sets \code{d} to \code{true} + and \code{Q} to \code{B/A} if \code{A} divides \code{B}, and else sets + \code{d} to \code{false}. See \code{fmpz_poly_divides}. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Power series division ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_poly_expr inv_series_newton(Fmpz_poly_expr, T:fits_into_slong) +Fmpz_poly_expr inv_series(Fmpz_poly_expr, T:fits_into_slong) +Fmpz_poly_expr div_series(Fmpz_poly_expr, Fmpz_poly_expr, slong n) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Pseudo division ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Ltuple_expr pseudo_divrem( + Fmpz_poly_expr A, Fmpz_poly_expr B) +Ltuple_expr pseudo_divrem_basecase( + Fmpz_poly_expr A, Fmpz_poly_expr B) +Ltuple_expr pseudo_divrem_divconquer( + Fmpz_poly_expr A, Fmpz_poly_expr B) + + \code{ltupleref(Q, R, d) = pseudo_divrem(A, B)} has the same effect as\\ + \code{fmpz_poly_pseudo_divrem(q, r, &d, a, b)}, where \code{q, r, a, b} are + the underlying \code{fmpz_poly_t} corresponding to \code{Q, R, A, B}. + +Ltuple_expr pseudo_divrem_cohen(Fmpz_poly_expr A, + Fmpz_poly_expr B) + + \code{ltupleref(Q, R) = pseudo_divrem_cohen(A, B)} has the same effect as\\ + \code{fmpz_poly_pseudo_divrem_cohen(q, r, a, b)}, where \code{q, r, a, b} + are the underlying \code{fmpz_poly_t} corresponding to \code{Q, R, A, B}. + +Ltuple_expr pseudo_div(Fmpz_poly_expr A, Fmpz_poly_expr B) +Ltuple_expr pseudo_rem(Fmpz_poly_expr A, Fmpz_poly_expr B) + + \code{ltupleref(Q, d) = pseudo_div(A, B)} has the same effect as + \code{fmpz_poly_pseudo_div(q, &d, a, b)}, where \code{q, a, b} are the + underlying \code{fmpz_poly_t} corresponding to \code{Q, A, B}. + +Fmpz_poly_expr pseudorem_cohen(Fmpz_poly_expr, Fmpz_poly_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Derivative ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_poly_expr derivative(Fmpz_poly_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Evaluation + + The overloaded \code{operator()} can be used for evaluation. Additionally, + the following functions are provided. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_expr evaluate(Fmpz_poly_expr, Fmpz_expr) +Fmpz_vec_expr evaluate(Fmpz_poly_expr, Fmpz_vec_expr) +Fmpz_expr evaluate_horner(Fmpz_poly_expr, Fmpz_expr) +Fmpz_expr evaluate_divconquer(Fmpz_poly_expr, Fmpz_expr) + +mp_limb_t evaluate_mod(Fmpz_poly_expr p, mp_limb_t x, mp_limb_t n) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Interpolation ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +static Fmpz_poly_expr fmpz_polyxx::interpolate( + Fmpz_vec_expr xs, Fmpz_vec_expr ys) + + See \code{fmpz_poly_interpolate_fmpz_vec}. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Composition. + + The overloaded \code{operator()} can be used for composition. Additionally, + the following functions are provided. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_poly_expr compose(Fmpz_poly_expr, Fmpz_poly_expr) +Fmpz_poly_expr compose_horner(Fmpz_poly_expr, Fmpz_poly_expr) +Fmpz_poly_expr compose_divconquer(Fmpz_poly_expr, Fmpz_poly_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Taylor shift ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_poly_expr taylor_shift(Fmpz_poly_expr, Fmpz_expr) +Fmpz_poly_expr taylor_shift_horner(Fmpz_poly_expr, Fmpz_expr) +Fmpz_poly_expr taylor_shift_divconquer(Fmpz_poly_expr, Fmpz_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Power series composition ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_poly_expr compose_series(Fmpz_poly_expr, Fmpz_poly_expr, slong) +Fmpz_poly_expr compose_series_horner(Fmpz_poly_expr, Fmpz_poly_expr, slong) +Fmpz_poly_expr compose_series_brent_kung(Fmpz_poly_expr, Fmpz_poly_expr, slong) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Power series reversion ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_poly_expr revert_series(Fmpz_poly_expr, T:fits_into_slong) +Fmpz_poly_expr revert_series_newton(Fmpz_poly_expr, T:fits_into_slong) +Fmpz_poly_expr revert_series_lagrange(Fmpz_poly_expr, T:fits_into_slong) +Fmpz_poly_expr revert_series_lagrange_fast(Fmpz_poly_expr, T:fits_into_slong) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Square root ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_poly_expr sqrt(Fmpz_poly_expr p) +Fmpz_poly_expr sqrt_classical(Fmpz_poly_expr p) + + Compute the square root of \code{p}, provided \code{p} is a perfect square. + Else raise \code{flint_exception}. See \code{fmpz_poly_sqrt}. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Signature ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +void Fmpz_poly_expr::signature(slong& r1, slong& r2) const + + See \code{fmpz_poly_signature}. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Hensel lifting ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Ltuple_expr hensel_lift( + Fmpz_poly_expr f, Fmpz_poly_expr g, Fmpz_poly_expr h, + Fmpz_poly_expr a, Fmpz_poly_expr b, + Fmpz_expr p, Fmpz_expr p1) +Ltuple_expr hensel_lift_without_inverse( + Fmpz_poly_expr f, Fmpz_poly_expr g, Fmpz_poly_expr h, + Fmpz_poly_expr a, Fmpz_poly_expr b, + Fmpz_expr p, Fmpz_expr p1) +Ltuple_expr hensel_lift_only_inverse( + Fmpz_poly_expr G, Fmpz_poly_expr H, + Fmpz_poly_expr a, Fmpz_poly_expr b, + Fmpz_expr p, Fmpz_expr p1) + + See \code{fmpz_poly_hensel_lift} etc. + +fmpz_poly_factorxx::set_hensel_lift_once(Fmpz_poly_expr, const + nmod_poly_factorxx&, slong) +fmpz_poly_factorxx hensel_lift_once(Fmpz_poly_expr, + const nmod_poly_factorxx&, slong) + + See \code{fmpz_poly_hensel_lift_once}. Note that these two + functions are defined in the \code{fmpz_factorxx} module. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Input and output ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +print(Fmpz_poly_expr) +print(FILE*, Fmpz_poly_expr) +print_pretty(Fmpz_poly_expr, const char* var) +print_pretty(FILE*, Fmpz_poly_expr, const char* var) +read(Fmpz_poly_target) +read(FILE*, Fmpz_poly_target) +read_pretty(Fmpz_poly_target, const char* var) +read_pretty(FILE*, Fmpz_poly_target, const char* var) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Modular reduction and reconstruction + + For modular reduction, see \code{nmod_polyxx::reduce}. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_poly_expr Fmpz_poly_expr::CRT(Fmpz_expr, Nmod_poly_expr, bool) +Fmpz_poly_expr CRT(Fmpz_poly_expr, Fmpz_expr, Nmod_poly_expr, bool) + + See \code{fmpz_poly_CRT_ui}. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Products ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +static Fmpz_poly_expr fmpz_polyxx::product_roots(Fmpz_vec_expr xs) + + See \code{fmpz_poly_product_roots_fmpz_vec}. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Roots ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_expr bound_roots(Fmpz_poly_expr p) + + +******************************************************************************* + + fmpz\_poly\_factorxx + +******************************************************************************* + +bool fmpz_poly_factorxx::operator==(const fmpz_poly_factorxx&) + + Compare two factorisations. + +ulong fmpz_poly_factorxx::size() const + + Return the number of stored factors. + +slong fmpz_poly_factorxx::exp(slong i) const +slong& fmpz_poly_factorxx::exp(slong i) + + Obtain the exponent of the ith factor. + +fmpz_polyxx_srcref fmpz_poly_factorxx::p(slong i) const +fmpz_polyxx_ref fmpz_poly_factorxx::p(slong i) + + Obtain the ith factor. + +fmpzxx_srcref fmpz_poly_factorxx::content() const +fmpzxx_ref fmpz_poly_factorxx::content() + + Obtain the content of the factorised polynomial. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Memory management ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +fmpz_poly_factorxx::fmpz_poly_factorxx() +explicit fmpz_poly_factorxx::fmpz_poly_factorxx(slong alloc) + + Initialise an empty factorisation. + +fmpz_poly_factorxx::fmpz_poly_factorxx(const fmpz_poly_factorxx& o) + + Copy a factorisation. + +void fmpz_poly_factorxx::realloc(slong a) +void fmpz_poly_factorxx::fit_length(slong a) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Manipulating factors ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +void fmpz_poly_factorxx::insert(Fmpz_poly_expr p, slong e) +void fmpz_poly_factorxx::concat(const fmpz_poly_factorxx&) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Factoring algorithms ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +void fmpz_poly_factorxx::set_factor_squarefree(Fmpz_poly_expr p) +void fmpz_poly_factorxx::set_factor_zassenhaus(Fmpz_poly_expr p) +void fmpz_poly_factorxx::set_factor_zassenhaus_recombination( + const fmpz_poly_factorxx& lifted_fac, Fmpz_poly_expr F, + Fmpz_expr P, slong exp) + +fmpz_poly_factorxx::factor_squarefree(Fmpz_poly_expr) +fmpz_poly_factorxx::factor_zassenhaus(Fmpz_poly_expr) + + + +******************************************************************************* + + fmpqxx + +******************************************************************************* + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + C++ particulars ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +?? Fmpq_expr::num() const +?? Fmpq_expr::den() const + + Unified coefficient access to numerator and denominator. If this is used to + modify the object, a call to \code{canonicalise()} may be necessary. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Memory management ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +fmpqxx::fmqxx() + + Initialize to zero. + +fmpqxx::fmpqxx(Fmpz_src num, Fmpz_src den) +fmpqxx::fmpqxx(T:fits_into_slong num, U:is_unsigned_integer den) + + Initialize from numerator \code{num} and denominator \code{den}. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Canonicalisation ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +void Fmpq_target::canonicalise() +bool Fmpq_src::is_canonical() const + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Basic assignment ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpq_expr Fmpq_expr::abs() const +Fmpq_expr abs(Fmpq_expr) + +void Fmpq_target::set_zero() +void Fmpq_target::set_one() +static fmpqxx fmpqxx::zero() +static fmpqxx fmpqxx::one() + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Comparison + + The overloaded relational operators can be used for comparison. + Additionally, we have the following functions. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +bool Fmpq_expr::is_zero() const +bool Fmpq_expr::is_one() const +int Fmpq_expr::sgn() const +mp_bitcnt_t Fmpq_expr::height_bits() const +Fmpz_expr Fmpq_expr::height() const + +mp_bitcnt_t height_bits(Fmpq_expr) +Fmpq_expr height(Fmpq_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Conversion + + Conversion can be done using the assignment operator, and through the + following functions. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +static fmpqxx fmpqxx::frac(const T& t, const U& u) + + Same as \code{fmpqxx res;res.set_frac(t, u)}. + +static fmpqxx fmpqxx::integer(const T& t) + + Same as \code{fmpqxx res;res.set_integer(t)}. + +void Fmpq_target::set_frac(const T& t, const U& u) + + \code{f.set_frac(t, u)} has the same effect as + \code{f.num() = t;f.den() = u;f.canonicalise()}. + +void Fmpq_target::set_integer(const T& t) + + \code{f.set_integer(t)} has the same effect as + \code{f.num() = t;f.den() = 1u}; + +std::string Fmpq_expr::to_string(int base = 10) const + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Input and output ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +int print(Fmpq_expr) +int print(FILE*, Fmpq_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Random number generation ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +static fmpqxx fmpqxx::randbits(frandxx& state) + +static fmpqxx fmpqxx::randtest(frandxx& state) + +static fmpqxx fmpqxx::randtest_not_zero(frandxx& state) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Arithmetic + + The overloaded operators \code{+ - * /} can be used for arithmetic. + Additionally, we provide the following functions. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpq_expr Fmpq_expr::inv() const +Fmpq_expr Fmpq_expr::pow(T:fits_into_slong) const +Fmpq_expr inv(Fmpq_expr) +Fmpq_expr pow(Fmpq_expr, T:fits_into_slong) + +Fmpq_expr operator<<(Fmpq_expr, T:is_integer) +Fmpq_expr operator>>(Fmpq_expr, T:is_integer) + + Shift operators are overloaded. See \code{fmpq_div_2exp} and + \code{fmpq_mul_2exp}. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Modular reduction and rational reconstruction ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpq_expr operator%(Fmpq_expr, Fmpz_expr) + + See \code{fmpq_mod_fmpz}. + The modular reduction operator may raise a \code{flint_exception} if + modular inversion is not possible. + +static Fmpq_expr fmpqxx::reconstruct(Fmpz_expr a, Fmpz_expr m, Fmpz_expr N, + Fmpz_expr D) +static Fmpq_expr fmpqxx::reconstruct(Fmpz_expr a, Fmpz_expr m) + + Rational reconstruction. May raise a \code{flint_exception} if + reconstruction is not possible. See \code{fmpq_reconstruct_fmpz} and + \code{fmpq_reconstruct_fmpz2}. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Rational enumeration ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpq_expr Fmpq_expr::next_minimal() const +Fmpq_expr Fmpq_expr::next_signed_minimal() const +Fmpq_expr Fmpq_expr::next_calkin_wilf() const +Fmpq_expr Fmpq_expr::next_signed_calkin_wilf() const + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Continued fractions ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +slong Fmpq_expr::cfrac_bound() const + +template void Fmpq_target::set_cfrac(const Vec& v, slong n) + + Set value to a partial fraction expansion. The same conventions apply to + \code{v} as in the constructor. + +template static fmpqxx fmpqxx::from_cfrac(const Vec& v, slong n) + + Initialize from a partial fraction expansion. \code{v} must be an instance + of a class which provides a method \code{_array()} that returns (a + pointer to) an array of \code{fmpz}. One such class is \code{fmpz_vecxx}. + The array must have size (at least) \code{n}. + + + +******************************************************************************* + + fmpq\_matxx + + The class \code{fmpq_matxx} wraps \code{fmpq_mat_t}. + Like \code{fmpz_matxx}, many operations on \code{fmpq_matxx} do not support + aliasing. The details can be found in the documentation of + \code{fmpq_mat_t}. Since \code{fmpq_matxx} does not use temporary merging, + evaluation of subexpressions never creates new aliases. + +******************************************************************************* + +Fmpq_mat_expr::unary operation() const + + The following unary functions are made available as member functions: + \code{inv}, \code{transpose}, \code{det}, \code{trace}, + \code{numden_entrywise}, \code{numden_rowwise}, \code{numden_colwise}, + \code{numden_matwise}, \code{num_rowwise}. + +Fmpq_mat_expr::binary operation(??) const + + The following binary functions are made available as member functions: + \code{solve_dixon}, \code{solve_fraction_free}, \code{mul_cleared}, + \code{mul_direct}. + +Fmpq_mat_expr operator?(??, ??) + + Arithmetic operators \code{+ - * /} are overloaded when provided by + \code{fmpq_mat_t}. + +Fmpq_mat_expr operator-(Fmpq_mat_expr) + + The unary negation operator is overloaded. + +Fmpq_mat_target Fmpq_mat_target::operator=(Fmpz_mat_expr) + + See \code{fmpq_mat_set_fmpz_mat}. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Memory management ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +fmpq_matxx::fmpq_matxx(slong m, slong n) + + See \code{fmpq_mat_init}. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Input and output ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +int print(Fmpq_mat_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Entry access ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +?? Fmpq_mat_expr::at(slong, slong) const + + Unified coefficient access to the entries of the matrix. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Basic assignment ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpq_mat_expr transpose(Fmpq_poly_mat_expr) + +void Fmpq_mat_target::set_zero() +void Fmpq_mat_target::set_one() +static fmpq_matxx fmpq_matxx::zero(slong rows, slong cols) +static fmpq_matxx fmpq_matxx::one(slong rows, slong cols) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Random matrix generation ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +void Fmpq_mat_target::set_randtest(frandxx& state, slong len, mp_bitcnt_t) +static fmpq_matxx fmpq_matxx::randtest(slong rows, slong cols, frandxx& state, + slong len, mp_bitcnt_t) +void Fmpq_mat_target::set_randtest_unsigned(frandxx& state, slong len, + mp_bitcnt_t) +static fmpq_matxx fmpq_matxx::randtest_unsigned(slong rows, slong cols, + frandxx& state, slong len, mp_bitcnt_t) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Special matrices ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +void Fmpq_target::set_hilbert_matrix() + +Fmpq_mat_expr hilbert_matrix(slong m, slong n) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Basic properties ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +bool Fmpq_mat_expr::is_zero() const +bool Fmpq_mat_expr::is_empty() const +bool Fmpq_mat_expr::is_square() const +bool Fmpq_mat_expr::is_integral() const + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Integer matrix conversion ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +static fmpq_matxx fmpq_matxx::frac(Fmpz_mat_expr, Fmpz_expr) +void Fmpq_mat_target::set_frac(Fmpz_mat_expr, Fmpz_expr) + + See \code{fmpq_mat_set_fmpz_mat_div_fmpz}. + +static fmpq_matxx fmpq_matxx::integer_matrix(Fmpz_mat_expr) + + See \code{fmpq_mat_set_fmpz_mat}. + +Fmpz_mat_expr num_rowwise(Fmpq_mat_expr) + + This has the effect of calling \code{fmpq_mat_get_fmpz_mat_rowwise} with + second argument \code{NULL}. + +Ltuple_expr numden_entrywise(Fmpq_mat_expr) + + See \code{fmpq_mat_get_fmpz_mat_entrywise}. + +Ltuple_expr numden_matwise(Fmpq_mat_expr) + + See \code{fmpq_mat_get_fmpz_mat_matwise}. + +Ltuple_expr numden_rowwise(Fmpq_mat_expr) + + See \code{fmpq_mat_get_fmpz_mat_rowwise}. + +Ltuple_expr numden_colwise(Fmpq_mat_expr) + + See \code{fmpq_mat_get_fmpz_mat_colwise}. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Modular reduction and rational reconstruction + + To reduce an \code{fmpq_matxx} modulo an \code{fmpzxx} to get an + \code{fmpz_matxx}, see \code{fmpz_matxx::reduce}. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +static fmpq_matxx fmpq_matxx::reconstruct(Fmpz_mat_expr, Fmpz_expr) + + See \code{fmpq_mat_set_fmpz_mat_mod_fmpz}. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Matrix multiplication + + The overloaded \code{operator*} can be used for matrix multiplication. + Finer control can be obtained using the following functions. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpq_mat_expr mul_direct(Fmpq_mat_expr, Fmpq_mat_expr) +Fmpq_mat_expr mul_cleared(Fmpq_mat_expr, Fmpq_mat_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Trace ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpq_expr trace(Fmpq_mat_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Determinant ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpq_expr det(Fmpq_mat_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Nonsingular solving ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpq_mat_expr solve_dixon(Fmpq_mat_expr B, Fmpq_mat_expr X) +Fmpq_mat_expr solve_fraction_free(Fmpq_mat_expr B, Fmpq_mat_expr X) + + See \code{fmpq_mat_solve_dixon} and \code{fmpq_mat_solve_fraction_free}. + Raises \code{flint_exception} if $B$ is singular. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Inverse ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpq_mat_expr inv(Fmpq_mat_expr A) + + Compute the inverse of the square matrix $A$. Raises \code{flint_exception} + if $A$ is singular. The modulus is required to be prime. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Echelon form ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +bool Fmpq_mat_target::pivot(slong r, slong c, permxx* perm = 0) + + See \code{fmpq_mat_pivot}. + +Ltuple_expr rref(Fmpq_mat_expr) +Ltuple_expr rref_classical(Fmpq_mat_expr) +Ltuple_expr rref_fraction_free(Fmpq_mat_expr) + + See \code{fmpq_mat_rref} etc. + + + +******************************************************************************* + + fmpq\_polyxx + +******************************************************************************* + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + C++ particulars ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpq_poly_expr Fmpq_poly_expr::operator()(Fmpq_poly_expr) const +Fmpq_poly_expr Fmpq_poly_expr::operator()(Fmpq_expr) const + + Overloaded \code{operator()} for evaluation or composition. + +Fmpq_poly_expr::unary operation() const + + The following unary functions are made available as member functions: + \code{derivative}, \code{integral}, \code{inv}, \code{make_monic}, + \code{primitive_part}, \code{content}. + +Fmpq_poly_expr::binary operation(??) const + + The following binary functions are made available as member functions: + \code{asinh_series}, \code{asin_series}, \code{atanh_series}, + \code{atan_series}, \code{cosh_series}, \code{cos_series}, \code{divrem}, + \code{exp_series}, \code{gcd}, \code{inv_series}, \code{inv_series_newton}, + \code{lcm}, \code{log_series}, \code{pow}, \code{resultant}, + \code{reverse}, \code{revert_series}, \code{revert_series_lagrange}, + \code{revert_series_lagrange_fast}, \code{revert_series_newton}, + \code{sinh_series}, \code{tanh_series}, \code{tan_series}, \code{xgcd}, + \code{rescale},\\ + \code{shift_left}, \code{shift_right}. + +Fmpq_poly_expr::ternary operation(??, ??) const + + The following ternary functions are made available as member functions: + \code{compose_series}, \code{compose_series_brent_kung}, + \code{compose_series_horner}, \code{div_series}, \code{mullow}. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Memory management ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +fmpq_polyxx::fmpq_polyxx() + +fmpq_polyxx::fmpq_polyxx(slong alloc) + + See \code{fmpq_poly_init2}. + +fmpq_polyxx::fmpq_polyxx(const char* str) + + See \code{fmpq_poly_set_str}. + +void Fmpq_poly_target realloc(slong alloc) +void Fmpq_poly_target::fit_length(slong len) +void Fmpq_poly_target::_normalise() +void Fmpq_poly_target::_set_length(slong len) +void Fmpq_poly_target::canonicalise() +bool Fmpq_poly_src::is_canonical() const + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Polynomial parameters ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +slong Fmpq_poly_expr::length() const +slong Fmpq_poly_expr::degree() const + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Accessing the numerator and denominator ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +fmzqxx_ref Fmpq_poly_target::get_coeff_numref(slong n) +fmzqxx_srcref Fmpq_poly_src::get_coeff_numref(slong n) const + + Obtain a reference to the numerator of coefficient $n$. + The result is undefined if $n$ is + greater than the degree of the polynomial (or negative). + If this is used to modify the object, a call to \code{canonicalise()} may + be necessary. + (No unified access, see \code{get_coeff}.) + +?? Fmpq_poly_expr::den() const + + Unified coefficient access to the denominator of the polynomial. + If this is used to modify the object, a call to \code{canonicalise()} may + be necessary. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Random testing ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +static fmpq_polyxx fmpq_polyxx::randtest( + frandxx& state, slong len, mp_bitcnt_t bits) +static fmpq_polyxx fmpq_polyxx::randtest_unsigned( + frandxx& state, slong len, mp_bitcnt_t bits) +static fmpq_polyxx fmpq_polyxx::randtest_not_zero( + frandxx& state, slong len, mp_bitcnt_t bits) + + See \code{fmpq_poly_randtest} etc. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Assignment ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpq_poly_target Fmpq_poly_target::operator=(T:is_integer) +Fmpq_poly_target Fmpq_poly_target::operator=(Fmpq_expr) +Fmpq_poly_target Fmpq_poly_target::operator=(Fmpz_expr) +Fmpq_poly_target Fmpq_poly_target::operator=(Fmpz_poly_expr) +Fmpq_poly_target Fmpq_poly_target::operator=(const char*) + +void Fmpq_poly_target::set_zero() +void Fmpq_poly_target::set_one() +static fmpq_polyxx fmpq_polyxx::zero() +static fmpq_polyxx fmpq_polyxx::one() + +Fmpq_poly_expr inv(Fmpq_poly_expr) + +static fmpq_polyxx fmpq_polyxx::get_slice(Fmpq_poly_expr, slong i, slong j) +void Fmpq_poly_target::truncate(slong) + +Fmpq_poly_expr reverse(Fmpq_poly_expr, T:fits_into_slong) + +std::string Fmpq_poly_expr::pretty(const char* x) const + + See \code{fmpq_poly_get_str_pretty}. + +std::string Fmpq_poly_expr::to_string() const + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Getting and setting coefficients ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpqxx_expr Fmpq_poly_expr::get_coeff(slong n) const + +void Fmpq_poly_target::set_coeff(slong n, Fmpz_expr) +void Fmpq_poly_target::set_coeff(slong n, Fmpq_expr) +void Fmpq_poly_target::set_coeff(slong n, T:is_integer) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Comparison + + The overloaded operators \code{== != >= >} etc. can be used for comparison. + Additionally, we have the following functions. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +bool Fmpq_poly_expr::is_one() const +bool Fmpq_poly_expr::is_zero() const + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Arithmetic + + The overloaded operators \code{* / + -} can be used for both + polynomial-polynomial and polynomial-scalar arithmetic. Additionally, we + provide the following functions. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpq_poly_expr mullow(Fmpq_poly_expr, Fmpq_poly_expr, slong) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Powering ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpq_poly_expr pow(Fmpq_poly_expr, T:is_unsigned_integer) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Shifting ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpq_poly_expr shift_left(Fmpq_poly_expr, T:fits_into_slong) +Fmpq_poly_expr shift_right(Fmpq_poly_expr, T:fits_into_slong) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Euclidean division + + The overloaded operators \code{/ %} can be used for euclidean division and + remainder. Additionally, we have the following functions. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Ltuple_expr divrem(Fmpq_poly_expr A, Fmpq_poly_expr B) + + \code{ltupleref(Q, R) = divrem(A, B)} has the same effect as + \code{fmpq_poly_divrem(q, r, a, b)} where \code{q, r, a, b} are the + underlying \code{fmpq_poly_t} corresponding to \code{Q, R, A, B}. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Power series division ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpq_poly_expr inv_series_newton(Fmpq_poly_expr, T:fits_into_slong) +Fmpq_poly_expr inv_series(Fmpq_poly_expr, T:fits_into_slong) +Fmpq_poly_expr div_series(Fmpq_poly_expr, Fmpq_poly_expr, slong n) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Greatest common divisor ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpq_poly_expr gcd(Fmpq_poly_expr, Fmpq_poly_expr) +Fmpq_poly_expr lcm(Fmpq_poly_expr, Fmpq_poly_expr) + +Ltuple_expr xgcd( + Fmpq_poly_expr f, Fmpq_poly_expr g) + + \code{ltupleref(G, S, T) = xgcd(A, B)} has the same effect as + \code{fmpq_poly_xgcd(g, s, t, a, b)}, where \code{g, s, t, a, b} denote the + underlying \code{fmpq_poly_t} corresponding to \code{G, S, T, A, B}. + +Fmpq_expr resultant(Fmpq_poly_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Derivative and integral ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpq_poly_expr derivative(Fmpq_poly_expr) +Fmpq_poly_expr integral(Fmpq_poly_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Square roots ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpq_poly_expr sqrt_series(Fmpq_poly_expr, T:fits_into_slong) +Fmpq_poly_expr invsqrt_series(Fmpq_poly_expr, T:fits_into_slong) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Transcendental functions ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpq_poly_expr exp_series(Fmpq_poly_expr, T:fits_into_slong) +Fmpq_poly_expr log_series(Fmpq_poly_expr, T:fits_into_slong) +Fmpq_poly_expr atan_series(Fmpq_poly_expr, T:fits_into_slong) +Fmpq_poly_expr atanh_series(Fmpq_poly_expr, T:fits_into_slong) +Fmpq_poly_expr asin_series(Fmpq_poly_expr, T:fits_into_slong) +Fmpq_poly_expr asinh_series(Fmpq_poly_expr, T:fits_into_slong) +Fmpq_poly_expr tan_series(Fmpq_poly_expr, T:fits_into_slong) +Fmpq_poly_expr sin_series(Fmpq_poly_expr, T:fits_into_slong) +Fmpq_poly_expr cos_series(Fmpq_poly_expr, T:fits_into_slong) +Fmpq_poly_expr sinh_series(Fmpq_poly_expr, T:fits_into_slong) +Fmpq_poly_expr cosh_series(Fmpq_poly_expr, T:fits_into_slong) +Fmpq_poly_expr tanh_series(Fmpq_poly_expr, T:fits_into_slong) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Evaluation + + The overloaded \code{operator()} can be used for evaluation. Additionally + we have the following. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpq_expr evaluate(Fmpq_poly_expr, Fmpq_expr) +Fmpq_expr evaluate(Fmpq_poly_expr, Fmpz_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Interpolation ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +static Fmpq_poly_expr fmpq_polyxx::interpolate( + Fmpz_vec_expr xs, Fmpz_vec_expr ys) + + See \code{fmpq_poly_interpolate_fmpq_vec}. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Composition ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpq_poly_expr compose(Fmpq_poly_expr, Fmpq_poly_expr) + +Fmpq_poly_expr rescale(Fmpq_poly_expr, Fmpq_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Power series composition ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpq_poly_expr compose_series(Fmpq_poly_expr, Fmpq_poly_expr, slong) +Fmpq_poly_expr compose_series_horner(Fmpq_poly_expr, Fmpq_poly_expr, slong) +Fmpq_poly_expr compose_series_brent_kung(Fmpq_poly_expr, Fmpq_poly_expr, slong) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Power series reversion ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpq_poly_expr revert_series(Fmpq_poly_expr, T:fits_into_slong) +Fmpq_poly_expr revert_series_newton(Fmpq_poly_expr, T:fits_into_slong) +Fmpq_poly_expr revert_series_lagrange(Fmpq_poly_expr, T:fits_into_slong) +Fmpq_poly_expr revert_series_lagrange_fast(Fmpq_poly_expr, T:fits_into_slong) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Gaussian content ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpq_expr content(Fmpq_poly_expr) +Fmpq_poly_expr primitive_part(Fmpq_poly_expr) +bool Fmpq_poly_expr::is_monic() const +Fmpq_poly_expr make_monic(Fmpq_poly_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Square-free ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +bool Fmpq_poly_expr::is_squarefree() const + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Input and output ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +print(Fmpq_poly_expr) +print(FILE*, Fmpq_poly_expr) +print_pretty(Fmpq_poly_expr, const char* var) +print_pretty(FILE*, Fmpq_poly_expr, const char* var) +read(Fmpq_poly_target) +read(FILE*, Fmpq_poly_target) + + +******************************************************************************* + + fmpz\_poly\_qxx + +******************************************************************************* + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Memory management ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +fmpz_poly_qxx::fmpz_poly_qxx() + +fmpz_poly_qxx::fmpz_poly_qxx(const char*) + + See \code{fmpz_poly_q_set_str}. + +void Fmpz_poly_q_target::canonicalise() +bool Fmpz_poly_q_src::is_canonical() const + +?? Fmpz_poly_q_expr::num() const +?? Fmpz_poly_q_expr::den() const + + Unified coefficient access to the numerator or denominator of the rational + function. If this is used for modification, a call to \code{canonicalise()} + may be necessary. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Randomisation ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +static fmpz_poly_qxx fmpz_poly_qxx::randtest(frandxx& state, + slong len1, mp_bitcnt_t bits1, slong len2, mp_bitcnt_t bits2) +static fmpz_poly_qxx fmpz_poly_qxx::randtest_not_zero(frandxx& state, + slong len1, mp_bitcnt_t bits1, slong len2, mp_bitcnt_t bits2) + + See \code{fmpz_poly_q_randtest} etc. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Assignment ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_poly_q_target Fmpz_poly_q_target::operator=(T:fits_into_slong) + +void Fmpz_poly_q_target::set_zero() +void Fmpz_poly_q_target::set_one() +static fmpz_poly_qxx fmpz_poly_qxx::zero() +static fmpz_poly_qxx fmpz_poly_qxx::one() + +Fmpz_poly_q_expr inv(Fmpz_poly_q_expr) +Fmpz_poly_q_expr Fmpz_poly_q_expr::inv() const + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Comparison + + The overloaded operator \code{==} can be used for comparison. Additionally, + we have the following functions. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +bool Fmpz_poly_q_expr::is_one() const +bool Fmpz_poly_q_expr::is_zero() const + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Powering ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_poly_q_expr pow(Fmpz_poly_q_expr, T:is_unsigned_integer) +Fmpz_poly_q_expr Fmpz_poly_q_expr::pow(T:is_unsigned_integer) const + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Derivative ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_poly_q_expr Fmpz_poly_q_expr::derivative() const +Fmpz_poly_q_expr derivative(Fmpz_poly_q_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Input and output ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_poly_q_target Fmpz_poly_q_target::operator=(const char*) + + See \code{fmpz_poly_q_set_str}. + +std::string Fmpz_poly_q_expr::to_string() const + + See \code{fmpz_poly_q_get_str}. + +std::string Fmpz_poly_q_expr::pretty(const char* x) const + + See \code{fmpz_poly_q_get_str_pretty}. + +int print(Fmpz_poly_q_expr) +int print_pretty(Fmpz_poly_q_expr, const char* var) + + + +******************************************************************************* + + fmpz\_poly\_matxx + + The class \code{fmpz_poly_matxx} wraps \code{fmpz_poly_mat_t}, and so + represents matrices with coefficients in $\mathbb{Z}[X]$. Its usage is + similar to \code{fmpz_matxx} in most regards. + +******************************************************************************* + +Fmpz_poly_mat_expr::unary operation() const + + The following unary functions are made available as member functions: + \code{det}, \code{det_fflu}, \code{det_interpolate}, \code{trace}, + \code{sqr}, \code{sqr_classical}, \code{sqr_KS}, + \code{transpose}. + +Fmpz_poly_mat_expr::binary operation(??) const + + The following binary functions are made available as member functions: + \code{solve}, \code{solve_fflu}, \code{mul_classical}, + \code{mul_interpolate}, \code{mul_KS}, \code{pow}, \code{sqrlow}. + +Fmpz_poly_mat_expr::three operation(??) const + + The following threeary functions are made available as member functions: + \code{mullow}, \code{pow_trunc}. + +Fmpz_mat_expr Fmpz_poly_mat_expr::operator()(Fmpz_expr) const + + \code{operator()} is overloaded for matrix evaluation. + +Fmpz_poly_mat_expr operator?(??, ??) + + Arithmetic operators \code{+ - *} are overloaded when provided by + \code{fmpz_poly_mat_t}. + +Fmpz_poly_mat_expr operator-(Fmpz_poly_mat_expr) + + The unary negation operator is overloaded. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Input and output ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +int print_pretty(Fmpz_poly_mat_expr, const char* x) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Basic properties ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +slong Fmpz_poly_mat_expr::rows() const +slong Fmpz_poly_mat_expr::cols() const + + Obtain the number of rows/columns in this matrix. These functions never + cause evaluation (the matrix size is computed from the operations in the + expression template and the size of the input matrices). + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Basic assignment and manipulation ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +?? Fmpz_poly_mat_expr::at(T:fits_into_slong, U:fits_into_slong) const + + Unified coefficient access to the matrix entries. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Standard matrices ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +void Fmpz_poly_mat_target::set_zero() +void Fmpz_poly_mat_target::set_one() +static fmpz_poly_matxx fmpz_poly_matxx::zero(slong rows, slong cols) +static fmpz_poly_matxx fmpz_poly_matxx::one(slong rows, slong cols) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Random matrix generation ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +void Fmpz_poly_mat_target::set_randtest(frandxx& state, slong len, mp_bitcnt_t) +void Fmpz_poly_mat_target::set_randtest_unsigned(frandxx& state, slong len, + mp_bitcnt_t) +void Fmpz_poly_mat_target::set_randtest_sparse(frandxx& state, slong len, + mp_bitcnt_t, float) +static fmpz_poly_matxx fmpz_poly_matxx::randtest(slong rows, slong cols, + frandxx&, slong len, mp_bitcnt_t) +static fmpz_poly_matxx fmpz_poly_matxx::randtest_unsigned(slong rows, + slong cols, frandxx&, slong len, mp_bitcnt_t) +static fmpz_poly_matxx fmpz_poly_matxx::randtest_sparse(slong rows, slong cols, + frandxx&, slong len, mp_bitcnt_t, float density) + + See \code{fmpz_poly_mat_randtest} etc. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Basic comparison and properties ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +bool Fmpz_poly_mat_expr::is_zero() const +bool Fmpz_poly_mat_expr::is_one() const +bool Fmpz_poly_mat_expr::is_empty() const +bool Fmpz_poly_mat_expr::is_square() const + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Norms ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +slong Fmpz_poly_mat_expr::max_length() const +slong Fmpz_poly_mat_expr::max_bits() const + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Transpose ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_poly_mat_expr transpose(Fmpz_poly_mat_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Arithmetic + + Basic arithmetic is most easily done using the overloaded operators + \code{+ * -}. Finer control can be obtained using the following functions. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_mat_expr mul_classical(Fmpz_mat_expr, Fmpz_mat_expr) +Fmpz_mat_expr mul_KS(Fmpz_mat_expr, Fmpz_mat_expr) +Fmpz_poly_mat_expr mullow(Fmpz_poly_mat_expr, Fmpz_poly_mat_expr, slong) +Fmpz_poly_mat_expr sqr(Fmpz_poly_mat_expr) +Fmpz_poly_mat_expr sqr_KS(Fmpz_poly_mat_expr) +Fmpz_poly_mat_expr sqr_classical(Fmpz_poly_mat_expr) +Fmpz_poly_mat_expr sqrlow(Fmpz_poly_mat_expr, T:fits_into_slong n) + +Fmpz_poly_mat_expr pow(Fmpz_poly_mat_expr, T:is_unsigned_integer) +Fmpz_poly_mat_expr pow_trunc(Fmpz_poly_mat_expr, T:is_unsigned_integer, + T:fits_into_slong) +Fmpz_poly_mat_expr prod(Fmpz_poly_mat_vec_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Row reduction + + Beware that compared to the C interface, the flintxx row reduction + interface changes some argument orders. This is to facilitate default + arguments. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +slong find_pivot_any(Fmpz_poly_mat_expr, slong, slong, slong) + + See \code{fmpz_poly_mat_find_pivot_any}. + +slong find_pivot_partial(Fmpz_poly_mat_expr, slong, slong, slong) + + See \code{fmpz_poly_mat_find_pivot_partial}. + +Ltuple_expr fflu(Fmpz_poly_mat_expr A, + permxx* perm = 0, bool rankcheck = false) + + See \code{fmpz_poly_mat_fflu}. + +Ltuple_expr rref(Fmpz_poly_mat_expr A) + + See \code{fmpz_poly_mat_rref}. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Trace ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_poly_expr trace(Fmpz_poly_mat_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Determinant and rank ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_poly_expr det(Fmpz_poly_mat_expr) +Fmpz_poly_expr det_fflu(Fmpz_poly_mat_expr) +Fmpz_poly_expr det_interpolate(Fmpz_poly_mat_expr) +slong rank(Fmpz_poly_mat_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Inverse ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Ltuple_expr inv(Fmpz_poly_mat_expr) + + \code{ltupleref(b, M, D) = inv(A)} has the same effect as + \code{b = fmpz_poly_mat_inv(m, d, a)}, where \code{m, d, a} are the underlying C + objects corresponding to \code{M, D, A}. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Nullspace ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Ltuple_expr nullspace(Fmpz_poly_mat_expr A) + + \code{ltupleref(n, B) = nullspace(A)} has the same effect as\\ + \code{n = fmpz_poly_mat_nullspace(b, a)}, where \code{b, a} are the underlying + \code{fmpz_poly_mat_t} corresponding to \code{B, A}. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Solving ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Ltuple_expr solve( + Fmpz_poly_mat_expr B, Fmpz_poly_mat_expr X) +Ltuple_expr solve_fflu( + Fmpz_poly_mat_expr B, Fmpz_poly_mat_expr X) +Ltuple_expr solve_fflu_precomp( + const permxx&, Fmpz_poly_mat_expr B, Fmpz_poly_mat_expr FFLU, + Fmpz_poly_mat_expr X) + + \code{ltupleref(w, M, D) = solve(B, X)} has the same effect as\\ + \code{w = fmpz_poly_mat_solve(m, d, b, x)}, where \code{m, d, b, x} are the + underlying C objects corresponding to \code{M, D, B, X}. + Similarly for the other functions. + + + +******************************************************************************* + + nmodxx + + The class \code{nmodxx} encapsulates the use of \code{mp_limb_t} together + with \code{nmod_t} for doing arithmetic modulo a word-sized integer. It is + defined in \code{nmod_vecxx.h}. + + The C++ equivalent to \code{nmod_t} is \code{nmodxx_ctx}. There is a + reference version\\ + \code{nmodxx_ctx_srcref}. + + The C++ equivalent to \code{mp_limb_t} in this context is \code{nmodxx}. + Immediate \code{nmodxx} expressions store both an \code{mp_limb_t} and an + \code{nmodxx_ctx_srcref}. + + The most common ways to construct \code{nmodxx} are using the static member + functions \code{nmodxx::red} and \code{nmodxx::make_nored}. For + convenience, \code{operator%} is overloaded with right hand side + \code{nmodxx_ctx} (or \code{nmodxx_ctx_srcref}) to call \code{nmodxx::red}. + + Just like when \code{mp_limb_t} is passed to \code{nmod_t} operations, the + limb stored in \code{nmodxx} is assumed to be reduced, and under this + assumption, all computations yield reduced data. + + It is assumed that any expression of \code{nmodxx} involves only one + modulus, so that all contexts are interchangeable. + +******************************************************************************* + +explicit nmodxx_ctx::nmodxx_ctx(mp_limb_t n) + + Initialise a new context for operations modulo $n$. + +nmodxx_ctx_srcref::nmodxx_ctx_srcref(const nmodxx_ctx&) + + Initialise a reference to an \code{nmodxx_ctx}. + +static nmodxx_ctx_srcref::make(const nmod_t& nm) + + Initialise a reference pointing to an \code{nmod_t}. + +const nmod_t& nmodxx_ctx::_nmod() const +const nmod_t& nmodxx_ctx_srcref::_nmod() const + + Obtain a reference to the underlying \code{nmod_t}. + +mp_limb_t nmodxx_ctx::n() const +mp_limb_t nmodxx_ctx_srcref::n() const + + Obtain the modulus stored in this context. + +nmodxx::nmodxx(nmodxx_ctx_srcref ctx) + + Initialise an \code{nmodxx} to zero. + +static nmodxx nmodxx::make_nored(mp_limb_t n, nmodxx_ctx_srcref ctx) + + Initialise an \code{nmodxx} to $n$, performing no reductions. + +static nmodxx nmodxx::red(mp_limb_t n, nmodxx_ctx_srcref ctx) +static nmodxx nmodxx::red(Fmpz_expr n, nmodxx_ctx_srcref ctx) +static nmodxx nmodxx::red(Fmpq_expr n, nmodxx_ctx_srcref ctx) + + Initialise an \code{nmodxx} to the reduction of $n$. + +static nmodxx_ref nmodxx_ref::make(mp_limb_t& l, nmodxx_ctx_srcref c) +static nmodxx_srcref nmodxx_srcref::make(const mp_limb_t&, nmodxx_ctx_srcref) + + Obtain a flintxx reference object pointing to \code{l}, which is + interpreted as a limb reduced modulo \code{c}. + +void Nmod_target::reduce() + + Reduce the stored limb. + +void Nmod_target::set_nored(mp_limb_t n) + + Set the stored limb to $n$. + +std::string Nmod_expr::to_string() const + + Convert self into a string of the form ``a mod b''. + +mp_limb_t Nmod_expr::to() const + + Obtain the stored limb. + +nmodxx_ctx_srcref Nmod_expr::estimate_ctx() const + + Obtain the context of any immediate subexpression. (By our homogeneity + assumptions, the result of this operation does not depend on the + subexpression chosen.) + +Nmod_expr Nmod_expr::inv() const +Nmod_expr Nmod_expr::pow(T:is_unsigned_integer) const + +Nmod_expr operator??(Nmod_expr, Nmod_expr) + + Arithmetic operators \code{+ - * /} are overloaded for nmod expressions. + +Nmod_expr operator-(Nmod_expr) +Nmod_expr pow(Nmod_expr, T:is_unsigned_integer) +Nmod_expr inv(Nmod_expr) + + + +******************************************************************************* + + nmod\_polyxx + + The class \code{nmod_polyxx} wraps \code{nmod_poly_t}. Like \code{nmodxx}, + instances of \code{nmod_polyxx} always have an associated \code{nmodxx_ctx} + storing the operating modulus. No expression may involve more than one + modulus at a time. + + In order to reduce convert a \code{fmpz_polyxx} or \code{fmpq_polyxx} to + \code{nmod_polyxx}, see the \code{reduce} method of \code{fmpz_polyxx} or + \code{fmpq_polyxx}, respectively. + +******************************************************************************* + +nmodxx_ctx_srcref Nmod_poly_expr::estimate_ctx() const + + Obtain the relevant context. This never causes evaluation. + +Nmod_poly_expr::unary operation() const + + The following unary functions are made available as member functions: + \code{derivative}, \code{integral}, \code{make_monic}, \code{sqrt}. + +Nmod_poly_expr::binary operation() const + + The following binary functions are made available as member functions:\\ + \code{compose_divconquer}, \code{compose_horner}, \code{div_basecase},\\ + \code{div_divconquer}, \code{div_newton}, \code{divrem},\\ + \code{divrem_basecase}, \code{divrem_divconquer},\\ + \code{divrem_newton}, \code{div_root}, \code{evaluate_fast},\\ + \code{evaluate_iter}, \code{gcd}, \code{gcd_euclidean}, \code{gcd_hgcd},\\ + \code{inv_series}, \code{inv_series_basecase}, \code{inv_series_newton},\\ + \code{invsqrt_series}, \code{mul_classical}, \code{mul_KS},\\ + \code{shift_left}, \code{shift_right}, \code{pow},\\ + \code{pow_binexp}, \code{rem_basecase}, \code{resultant},\\ + \code{resultant_euclidean}, \code{reverse}, \code{revert_series},\\ + \code{revert_series_lagrange}, \code{revert_series_lagrange_fast},\\ + \code{revert_series_newton}, \code{sqrt_series}, \code{taylor_shift},\\ + \code{taylor_shift_convolution}, \code{taylor_shift_horner}, \code{xgcd},\\ + \code{xgcd_euclidean}, \code{xgcd_hgcd}, \code{log_series},\\ + \code{exp_series}, \code{exp_series_basecase}, \code{atan_series},\\ + \code{atanh_series}, \code{asin_series}, \code{asinh_series},\\ + \code{sin_series}, \code{cos_series}, \code{tan_series},\\ + \code{sinh_series}, \code{cosh_series}, \code{tanh_series}. + +Nmod_poly_expr Nmod_poly_expr::inflate(T:is_unsigned_integer) const + + \code{See inflate}. + +Nmod_poly_expr Nmod_poly_expr::deflate(T:is_unsigned_integer) const + + \code{See deflate}. + +Nmod_poly_expr::ternary operation(??, ??) const + + The following ternary functions are made available as member functions:\\ + \code{compose_mod}, \code{compose_mod_horner},\\ + \code{compose_series_brent_kung}, \code{compose_series},\\ + \code{compose_series_brent_kung}, \code{compose_series_divconquer},\\ + \code{compose_series_horner}, \code{div_newton_n_preinv},\\ + \code{divrem_newton_n_preinv}, \code{div_series}, \code{mulhigh},\\ + \code{mulhigh_classical}, \code{mullow}, \code{mullow_classical},\\ + \code{mullow_KS}, \code{mulmod}, \code{powmod_binexp}, \code{pow_trunc},\\ + \code{pow_trunc_binexp}. + +Nmod_poly_expr::fourary operation(??, ??, ??) const + + The following functions of four arguments + are made available as member functions: + \code{compose_mod_brent_kung_preinv}, \code{mulmod_preinv}, + \code{powmod_binexp_preinv}. + +Nmod_poly_expr Nmod_poly_expr::operator()(Nmod_poly_expr) const +Nmod_expr Nmod_poly_expr::operator()(Nmod_expr) const +Nmod_vec_expr Nmod_poly_expr::operator()(Nmod_vec_expr) const + + The \code{operator()} is overloaded for evaluation or composition, + depending on the argument. + +Nmod_poly_expr operator?(??, ??) + + Arithmetic operators \code{+ - * / %} are overloaded when provided by + \code{nmod_poly_t}. + +Nmod_poly_expr operator-(Nmod_poly_expr) + + The unary negation operator is overloaded. + +Nmod_poly_target Nmod_poly_target::operator=(const char*) + + See \code{nmod_poly_set_str}. Raises \code{flint_exception} if the string + is malformed. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Conversion ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +static nmod_polyxx nmod_polyxx::reduce(Fmpz_mod_poly_expr, nmodxx_ctx_srcref) +static nmod_polyxx nmod_polyxx::reduce(Fmpq_mod_poly_expr, nmodxx_ctx_srcref) +static nmod_polyxx nmod_polyxx::reduce(Fmpz_mod_poly_expr, mp_limb_t) +static nmod_polyxx nmod_polyxx::reduce(Fmpq_mod_poly_expr, mp_limb_t) + + See \code{fmpz_poly_get_nmod_poly}. + +static nmod_polyxx nmod_polyxx::from_ground(Nmod_expr e) +static nmod_polyxx nmod_polyxx::from_ground(mp_limb_t e, nmodxx_ctx_srcref c) + + Consider $e \in \mathbb{Z}/n\mathbb{Z}$ as an element of + $\mathbb{Z}/n\mathbb{Z}[X]$. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Input and output ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +print(Nmod_poly_expr) +print(FILE*, Nmod_poly_expr) +read(Nmod_poly_target) +read(FILE*, Nmod_poly_target) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Memory management ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +nmod_polyxx::nmod_polyxx(mp_limb_t modulus) +nmod_polyxx::nmod_polyxx(mp_limb_t modulus, slong alloc) +nmod_polyxx::nmod_polyxx(nmodxx_ctx_srcref ctx) +nmod_polyxx::nmod_polyxx(nmodxx_ctx_srcref ctx, slong alloc) + + Instantiate \code{nmod_polyxx} relative to some modulus. If the second + argument is provided, space is allocated for \code{alloc} coefficients. + +nmod_polyxx::nmod_polyxx(const char* str) + + Instantiate \code{nmod_polyxx} from a string representation. The modulus is + parsed (second integer in the string) and the polynomial is initialised + with this modulus, then \code{nmod_poly_set_str} is called. Raises + \code{flint_exception} if the string is malformed. + +static nmod_polyxx nmod_polyxx::zero(mp_limb_t n) +static nmod_polyxx nmod_polyxx::one(mp_limb_t n) + +void Nmod_poly_target realloc(slong alloc) +void Nmod_poly_target::fit_length(slong len) +void Nmod_poly_target::_normalise() + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Polynomial properties ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +sslong Nmod_poly_expr::length() const +sslong Nmod_poly_expr::degree() const +sslong Nmod_poly_expr::max_bits() const +mp_limb_t Nmod_poly_expr::modulus() const + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Assignment and basic manipulation ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +void Nmod_poly_target::truncate(slong) +void Nmod_poly_target::set_zero() +void Nmod_poly_target::set_one() + +Nmod_poly_expr reverse(Nmod_poly_expr, T:fits_into_slong) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Randomisation ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +void Nmod_target::set_randtest(frandxx& state, slong len) +void Nmod_target::set_randtest_irreducible(frandxx& state, slong len) +static nmod_polyxx nmod_polyxx::randtest(mp_limb_t n, + frandxx& state, slong len) +static nmod_polyxx nmod_polyxx::randtest_irreducible(mp_limb_t n, + frandxx& state, slong len) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Getting and setting coefficients ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Nmodxx_expr Nmod_poly_expr::get_coeff(slong n) const +void Nmod_target::set_coeff(slong i, Nmodxx_expr) +void Nmod_target::set_coeff(slong i, mp_limb_t) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Input and output ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +std::string Nmod_poly_expr::to_string() const + +std::ostream& operator<<(std::ostream&, Nmod_poly_expr) + + Output to streams is done by first converting to string. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Comparison ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +bool Nmod_poly_expr::is_one() const +bool Nmod_poly_expr::is_zero() const + +bool operator==(Nmod_poly_expr, Nmod_poly_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Scalar multiplication and division + + Scalar multiplication is provided via overloaded \code{operator*}. + Additionally, the following functions are implemented: ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Nmod_poly_expr make_monic(Nmod_poly_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Bit packing and unpacking ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_expr Nmod_poly_expr::bit_pack(T:fits_into_mp_bitcnt_t) const +static nmod_polyxx nmod_polyxx::bit_unpack( + Fmpz_expr, T:fits_into_mp_bitcnt_t) const + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Multiplication + + Basic multiplication is provided via overloaded \code{operator*}. Finer + control can be obtained using the following functions. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Nmod_poly_expr mul_classical(Nmod_poly_expr, Nmod_poly_expr) +Nmod_poly_expr mul_KS(Nmod_poly_expr, Nmod_poly_expr) + +Nmod_poly_expr mullow(Nmod_poly_expr, Nmod_poly_expr, slong) +Nmod_poly_expr mullow_classical(Nmod_poly_expr, Nmod_poly_expr, slong) +Nmod_poly_expr mullow_KS(Nmod_poly_expr, Nmod_poly_expr, slong) +Nmod_poly_expr mulhigh(Nmod_poly_expr, Nmod_poly_expr, slong) +Nmod_poly_expr mulhigh_classical(Nmod_poly_expr, Nmod_poly_expr, slong) + +Nmod_poly_expr mulmod(Nmod_poly_expr, Nmod_poly_expr, Nmod_poly_expr) +Nmod_poly_expr mulmod_preinv(Nmod_poly_expr, Nmod_poly_expr, Nmod_poly_expr, + Nmod_poly_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Powering ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Nmod_poly_expr pow(Nmod_poly_expr, T:is_unsigned_integer) +Nmod_poly_expr pow_binexp(Nmod_poly_expr, T:is_unsigned_integer) +Nmod_poly_expr pow_trunc(Nmod_poly_expr, T:is_unsigned_integer, + T:fits_into_slong) +Nmod_poly_expr pow_trunc_binexp(Nmod_poly_expr, T:is_unsigned_integer, + T:fits_into_slong) +Nmod_poly_expr powmod_binexp(Nmod_poly_expr, T:is_unsigned_integer, + Nmod_poly_expr) +Nmod_poly_expr powmod_binexp_preinv(Nmod_poly_expr, T:is_unsigned_integer, + Nmod_poly_expr, Nmod_poly_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Division + + Basic division and remainder is provided by overloaded \code{operator/} and + \code{operator%}. Finer control can be obtained using the following + functions. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Ltuple_expr divrem(Nmod_poly_expr A, Nmod_poly_expr B) +Ltuple_expr divrem_basecase(Nmod_poly_expr A, + Nmod_poly_expr B) +Ltuple_expr divrem_divconquer( + Nmod_poly_expr A, Nmod_poly_expr B) +Ltuple_expr divrem_newton( + Nmod_poly_expr A, Nmod_poly_expr B) +Ltuple_expr divrem_newton_n_preinv( + Nmod_poly_expr A, Nmod_poly_expr B) + +Nmod_poly_expr div_basecase(Nmod_poly_expr, Nmod_poly_expr) +Nmod_poly_expr div_divconquer(Nmod_poly_expr, Nmod_poly_expr) +Nmod_poly_expr div_newton(Nmod_poly_expr, Nmod_poly_expr) +Nmod_poly_expr div_newton_n_preinv(Nmod_poly_expr, Nmod_poly_expr, + Nmod_poly_expr) + +Nmod_poly_expr rem_basecase(Nmod_poly_expr, Nmod_poly_expr) + +Nmod_poly_expr inv_series(Nmod_poly_expr, T:fits_into_slong) +Nmod_poly_expr inv_series_basecase(Nmod_poly_expr, T:fits_into_slong) +Nmod_poly_expr inv_series_newton(Nmod_poly_expr, T:fits_into_slong) + +Nmod_poly_expr div_series(Nmod_poly_expr, Nmod_poly_expr, slong n) + +Nmod_poly_expr div_root(Nmod_poly_expr, Nmod_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Derivative and integral ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Nmod_poly_expr derivative(Nmod_poly_expr) +Nmod_poly_expr integral(Nmod_poly_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Evaluation + + Basic evaluation and multipoint evaluation can be achieved using the + overloaded \code{operator()}. Finer control can be obtained using the + following functions. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Nmod_expr evaluate(Nmod_poly_expr, Nmod_expr) +Nmod_vec_expr evaluate(Nmod_poly_expr, Nmod_vec_expr) +Nmod_vec_expr evaluate_fast(Nmod_poly_expr, Nmod_vec_expr) +Nmod_vec_expr evaluate_iter(Nmod_poly_expr, Nmod_vec_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Interpolation ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +static Nmod_poly_expr fmpz_polyxx::interpolate( + Nmod_vec_expr xs, Nmod_vec_expr ys) +static Nmod_poly_expr fmpz_polyxx::interpolate_barycentric( + Nmod_vec_expr xs, Nmod_vec_expr ys) +static Nmod_poly_expr fmpz_polyxx::interpolate_fast( + Nmod_vec_expr xs, Nmod_vec_expr ys) +static Nmod_poly_expr fmpz_polyxx::interpolate_newton( + Nmod_vec_expr xs, Nmod_vec_expr ys) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Composition + + Basic composition can be achieved with the overloaded \code{operator()}. + Finer control can be obtained using the following functions. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Nmod_poly_expr compose(Nmod_poly_expr, Nmod_poly_expr) +Nmod_poly_expr compose_horner(Nmod_poly_expr, Nmod_poly_expr) +Nmod_poly_expr compose_divconquer(Nmod_poly_expr, Nmod_poly_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Taylor Shift ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Nmod_poly_expr taylor_shift(Nmod_poly_expr, Nmod_expr) +Nmod_poly_expr taylor_shift_horner(Nmod_poly_expr, Nmod_expr) +Nmod_poly_expr taylor_shift_convolution(Nmod_poly_expr, Nmod_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Modular composition ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Nmod_poly_expr compose_mod(Nmod_poly_expr, Nmod_poly_expr, Nmod_poly_expr) +Nmod_poly_expr compose_mod_horner(Nmod_poly_expr, Nmod_poly_expr, + Nmod_poly_expr) +Nmod_poly_expr compose_mod_divconquer(Nmod_poly_expr, Nmod_poly_expr, + Nmod_poly_expr) +Nmod_poly_expr compose_mod_brent_kung(Nmod_poly_expr, Nmod_poly_expr, + Nmod_poly_expr) +Nmod_poly_expr compose_mod_brent_kung_preinv(Nmod_poly_expr, Nmod_poly_expr, + Nmod_poly_expr, Nmod_poly_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Greatest common divisor ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Nmod_poly_expr gcd(Nmod_poly_expr, Nmod_poly_expr) +Nmod_poly_expr gcd_euclidean(Nmod_poly_expr, Nmod_poly_expr) +Nmod_poly_expr gcd_hgcd(Nmod_poly_expr, Nmod_poly_expr) + +Ltuple_expr xgcd( + Nmod_poly_expr, Nmod_poly_expr) +Ltuple_expr xgcd_euclidean( + Nmod_poly_expr, Nmod_poly_expr) +Ltuple_expr xgcd_hgcd( + Nmod_poly_expr, Nmod_poly_expr) + +Nmod_expr resultant(Nmod_poly_expr, Nmod_poly_expr) +Nmod_expr resultant_euclidean(Nmod_poly_expr, Nmod_poly_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Power series composition ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Nmod_poly_expr compose_series(Nmod_poly_expr, Nmod_poly_expr, slong) +Nmod_poly_expr compose_series_horner(Nmod_poly_expr, Nmod_poly_expr, slong) +Nmod_poly_expr compose_series_brent_kung(Nmod_poly_expr, Nmod_poly_expr, slong) +Nmod_poly_expr compose_series_divconquer(Nmod_poly_expr, Nmod_poly_expr, slong) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Power series reversion ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Nmod_poly_expr revert_series(Nmod_poly_expr, T:fits_into_slong) +Nmod_poly_expr revert_series_newton(Nmod_poly_expr, T:fits_into_slong) +Nmod_poly_expr revert_series_lagrange(Nmod_poly_expr, T:fits_into_slong) +Nmod_poly_expr revert_series_lagrange_fast(Nmod_poly_expr, T:fits_into_slong) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Square roots ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Nmod_poly_expr sqrt_series(Nmod_poly_expr, T:fits_into_slong) +Nmod_poly_expr invsqrt_series(Nmod_poly_expr, T:fits_into_slong) + +Nmod_poly_expr sqrt_series(Nmod_poly_expr p) + + Compute the square root of $p$. Raises \code{flint_exception} if $p$ is not + a perfect square. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Transcendental functions ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Nmod_poly_expr exp_series(Nmod_poly_expr, T:fits_into_slong) +Nmod_poly_expr log_series(Nmod_poly_expr, T:fits_into_slong) +Nmod_poly_expr atan_series(Nmod_poly_expr, T:fits_into_slong) +Nmod_poly_expr atanh_series(Nmod_poly_expr, T:fits_into_slong) +Nmod_poly_expr asin_series(Nmod_poly_expr, T:fits_into_slong) +Nmod_poly_expr asinh_series(Nmod_poly_expr, T:fits_into_slong) +Nmod_poly_expr tan_series(Nmod_poly_expr, T:fits_into_slong) +Nmod_poly_expr sin_series(Nmod_poly_expr, T:fits_into_slong) +Nmod_poly_expr cos_series(Nmod_poly_expr, T:fits_into_slong) +Nmod_poly_expr sinh_series(Nmod_poly_expr, T:fits_into_slong) +Nmod_poly_expr cosh_series(Nmod_poly_expr, T:fits_into_slong) +Nmod_poly_expr tanh_series(Nmod_poly_expr, T:fits_into_slong) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Products ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +static Nmod_poly_expr fmpz_polyxx::product_roots(Nmod_vec_expr xs) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Inflation and deflation ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Nmod_poly_expr inflate(Nmod_poly_expr, T:is_unsigned_integer) +Nmod_poly_expr deflate(Nmod_poly_expr, T:is_unsigned_integer) + +uslong Nmod_poly_expr::deflation() const + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Factorisation ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +bool Nmod_poly_expr::is_squarefree() const +bool Nmod_poly_expr::is_irreducible() const +sslong Nmod_poly_target::remove(Nmod_poly_expr) + +nmod_poly_factorxx::nmod_poly_factorxx() + + Initialise an empty factorisation. + +nmod_poly_factorxx::nmod_poly_factorxx(const nmod_poly_factorxx& o) + + Copy a factorisation. + +bool nmod_poly_factorxx::operator==(const nmod_poly_factorxx&) + + Compare two factorisations. + +ulong nmod_poly_factorxx::size() const + + Return the number of stored factors. + +slong nmod_poly_factorxx::exp(slong i) const +slong& nmod_poly_factorxx::exp(slong i) + + Obtain the exponent of the ith factor. + +nmod_polyxx_srcref nmod_poly_factorxx::p(slong i) const +nmod_polyxx_ref nmod_poly_factorxx::p(slong i) + + Obtain the ith factor. + +void nmod_poly_factorxx::realloc(slong a) +void nmod_poly_factorxx::fit_length(slong a) +void nmod_poly_factorxx::insert(Nmod_poly_expr p, slong e) +void nmod_poly_factorxx::concat(const nmod_poly_factorxx&) + +void nmod_poly_factorxx::set_factor(Nmod_poly_expr) +void nmod_poly_factorxx::set_factor_cantor_zassenhaus(Nmod_poly_expr) +void nmod_poly_factorxx::set_factor_berlekamp(Nmod_poly_expr) +void nmod_poly_factorxx::set_factor_kaltofen_shoup(Nmod_poly_expr) +void nmod_poly_factorxx::set_factor_with_cantor_zassenhaus(Nmod_poly_expr) +void nmod_poly_factorxx::set_factor_with_berlekamp(Nmod_poly_expr) +void nmod_poly_factorxx::set_factor_with_kaltofen_shoup(Nmod_poly_expr) +void nmod_poly_factorxx::set_factor_squarefree(Nmod_poly_expr) + + Factorise a polynomial and store its factors. See \code{nmod_poly_factor} etc. + +void nmod_poly_factorxx::set_factor_equal_deg_probab(frandxx&, Nmod_poly_expr, + slong) +void nmod_poly_factorxx::set_factor_equal_deg(Nmod_poly_expr, slong) + + See \code{nmod_poly_factor_equal_deg_prob} and + \code{nmod_poly_factor_equal_deg}. + +void nmod_poly_factorxx::set_factor_distinct_deg(Nmod_poly_expr p, + std::vector& degs) + + See \code{nmod_poly_factor_distinct_deg}. Note that \code{degs} must have + sufficient size to hold all factors. The size of \code{degs} is not + modified. + +nmod_poly_factorxx factor(Nmod_poly_expr) +nmod_poly_factorxx factor_cantor_zassenhaus(Nmod_poly_expr) +nmod_poly_factorxx factor_berlekamp(Nmod_poly_expr) +nmod_poly_factorxx factor_kaltofen_shoup(Nmod_poly_expr) +nmod_poly_factorxx factor_with_cantor_zassenhaus(Nmod_poly_expr) +nmod_poly_factorxx factor_with_berlekamp(Nmod_poly_expr) +nmod_poly_factorxx factor_with_kaltofen_shoup(Nmod_poly_expr) +nmod_poly_factorxx factor_squarefree(Nmod_poly_expr) + + +******************************************************************************* + + nmod\_matxx + + The class \code{nmod_matxx} wraps \code{nmod_mat_t}. Like \code{nmodxx}, + instances of \code{nmod_matxx} always have an associated \code{nmodxx_ctx} + storing the operating modulus. No expression may involve more than one + modulus at a time. + + Like \code{fmpz_matxx}, many operations on \code{nmod_matxx} do not support + aliasing. The details can be found in the documentation of + \code{nmod_mat_t}. Since \code{nmod_matxx} does not use temporary merging, + evaluation of subexpressions never creates new aliases. + +******************************************************************************* + +nmodxx_ctx_srcref Nmod_mat_expr::estimate_ctx() const + + Obtain the relevant context. This never causes evaluation. + +Nmod_mat_expr::unary operation() const + + The following unary functions are made available as member functions: + \code{inv}, \code{transpose}, \code{trace}, \code{det}. + +Nmod_mat_expr::binary operation(??) const + + The following binary functions are made available as member functions: + \code{solve}, \code{mul_classical}, \code{mul_strassen}. + +Nmod_mat_expr::ternary operation(??, ??) const + + The following ternary functions are made available as member functions: + \code{solve_tril}, \code{solve_tril_recursive}, + \code{solve_tril_classical}, \code{solve_triu}, + \code{solve_triu_recursive}, \code{solve_triu_classical}. + +Nmod_mat_expr operator?(??, ??) + + Arithmetic operators \code{+ - *} are overloaded when provided by + \code{nmod_mat_t}. + +Nmod_mat_expr operator-(Nmod_mat_expr) + + The unary negation operator is overloaded. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Conversion ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +static nmod_matxx::reduce(Fmpz_mat_expr, mp_limb_t modulus) + + See \code{fmpz_mat_get_nmod_mat}. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Input and output ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +int print(Nmod_mat_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Memory management ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +nmod_matxx::nmod_matxx(slong m, slong n, mp_limb_t modulus) + + See \code{nmod_mat_init}. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Basic properties and manipulation ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +?? Nmod_mat_expr::at(T:fits_into_slong, U:fits_into_slong) const + + Unified coefficient access to the matrix entries. + +sslong Nmod_mat_expr::rows() const +sslong Nmod_mat_expr::cols() const + + Obtain the number of rows/columns in this matrix. These functions never + cause evaluation (the matrix size is computed from the operations in the + expression template and the size of the input matrices). + +bool Nmod_mat_expr::is_zero() const +bool Nmod_mat_expr::is_empty() const +bool Nmod_mat_expr::is_square() const +mp_limb_t Nmod_mat_expr::modulus() const + +void Nmod_mat_target::set_zero() +static nmod_matxx nmod_matxx::zero(slong rows, slong cols, mp_limb_t modulus) + + See \code{nmod_mat_zero}. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Random matrix generation ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +void Nmod_mat_target::set_randtest(frandxx&) +void Nmod_mat_target::set_randfull(frandxx&) +void Nmod_mat_target::set_randrank(frandxx&, slong rank) +void Nmod_mat_target::set_randtril(frandxx&, bool unit) +void Nmod_mat_target::set_randtriu(frandxx&, bool unit) + + See \code{nmod_mat_randtest} etc. + +static nmod_matxx nmod_matxx::randtest(slong rows, slong cols, mp_limb_t M, + frandxx&) +static nmod_matxx nmod_matxx::randfull(slong rows, slong cols, mp_limb_t M, + frandxx&) +static nmod_matxx nmod_matxx::randrank(slong rows, slong cols, mp_limb_t M, + frandxx&, slong rank) +static nmod_matxx nmod_matxx::randtril(slong rows, slong cols, mp_limb_t M, + frandxx&, bool unit) +static nmod_matxx nmod_matxx::randtriu(slong rows, slong cols, mp_limb_t M, + frandxx&, bool unit) + + Static versions of the above. + +int Nmod_mat_target::set_randpermdiag(frandxx&, const Vec& v) + + \code{M.set_randpermdiag(Rand, V)} has the same effect as + \code{nmod_mat_randpermdiag(m, rand, V._array(), V.size())}, where \code{m} + and \code{rand} are the underlying C structs corresponding to \code{M} and + \code{Rand}. + + One possibility for Vec is \code{nmod_vecxx}. + +void Nmod_target::apply_randops(frandxx&, slong count) + + See \code{nmod_mat_randops}. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Transpose ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Nmod_mat_expr transpose(Nmod_mat_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Matrix multiplication + + The overloaded \code{operator*} can be used for both matrix-matrix and + matrix-scalar multiplication. Finer control can be obtained with the + following functions. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Nmod_mat_expr mul_classical(Nmod_mat_expr, Nmod_mat_expr) +Nmod_mat_expr mul_strassen(Nmod_mat_expr, Nmod_mat_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Trace ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Nmod_expr trace(Nmod_mat_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Determinant and rank ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Nmod_expr det(Nmod_mat_expr) +slong rank(Nmod_mat_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Inverse ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Nmod_mat_expr inv(Nmod_mat_expr A) + + Compute the inverse of the square matrix $A$. Raises \code{flint_exception} + if $A$ is singular. The modulus is required to be prime. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Triangular solving ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Nmod_mat_expr solve_triu(Nmod_mat_expr, Nmod_mat_expr, bool unit) +Nmod_mat_expr solve_triu_classical(Nmod_mat_expr, Nmod_mat_expr, bool unit) +Nmod_mat_expr solve_triu_recursive(Nmod_mat_expr, Nmod_mat_expr, bool unit) +Nmod_mat_expr solve_tril(Nmod_mat_expr, Nmod_mat_expr, bool unit) +Nmod_mat_expr solve_tril_classical(Nmod_mat_expr, Nmod_mat_expr, bool unit) +Nmod_mat_expr solve_tril_recursive(Nmod_mat_expr, Nmod_mat_expr, bool unit) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Non-singular square solving ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Nmod_mat_expr solve(Nmod_mat_expr B, Nmod_mat_expr X) +Nmod_vec_expr solve(Nmod_mat_expr B, Nmod_vec_expr X) + + See \code{nmod_mat_solve} and \code{nmod_mat_solve_vec}. + Raises \code{flint_exception} if $B$ is singular. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + LU decomposition ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Tuple Nmod_mat_target::set_lu(bool rank_check = false) +Tuple Nmod_mat_target::set_lu_classical(bool rank_check = false) +Tuple Nmod_mat_target::set_lu_recursive(bool rank_check = false) + + See \code{nmod_mat_lu} etc. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Reduced row echelon form ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +void Nmod_mat_target::set_rref() + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Nullspace ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Ltuple_expr nullspace(Nmod_mat_expr) + + + +******************************************************************************* + + nmod\_poly\_matxx + + The class \code{nmod_poly_matxx} wraps \code{nmod_poly_mat_t}. + Like \code{nmod_matxx}, + instances of \code{nmod_poly_matxx} always have an associated + \code{nmodxx_ctx} storing the operating modulus. + No expression may involve more than one modulus at a time. + + Contrary to \code{nmod_poly_mat_t}, it is \emph{not} valid to use instances + of \code{nmod_poly_matxx} with zero rows or columns. + + Like \code{fmpz_matxx}, many operations on \code{nmod_poly_matxx} do not support + aliasing. The details can be found in the documentation of + \code{nmod_poly_mat_t}. Since \code{nmod_poly_matxx} + does not use temporary merging, + evaluation of subexpressions never creates new aliases. + +******************************************************************************* + +nmodxx_ctx_srcref Nmod_poly_mat_expr::estimate_ctx() const + + Obtain the relevant context. This never causes evaluation. + +Nmod_poly_mat_expr::unary operation() const + + The following unary functions are made available as member functions: + \code{det}, \code{det_fflu}, \code{det_interpolate}, \code{trace}, + \code{sqr}, \code{sqr_classical}, \code{sqr_interpolate}, \code{sqr_KS}, + \code{transpose}. + +Nmod_poly_mat_expr::binary operation(??) const + + The following binary functions are made available as member functions: + \code{solve}, \code{solve_fflu}, \code{mul_classical}, + \code{mul_interpolate}, \code{mul_KS}, \code{pow}. + +Nmod_mat_expr Nmod_poly_mat_expr::operator()(Nmod_expr) const + + \code{operator()} is overloaded for matrix evaluation. + +Nmod_poly_mat_expr operator?(??, ??) + + Arithmetic operators \code{+ - *} are overloaded when provided by + \code{nmod_poly_mat_t}. + +Nmod_poly_mat_expr operator-(Nmod_poly_mat_expr) + + The unary negation operator is overloaded. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Input and output ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +int print_pretty(Nmod_poly_mat_expr, const char*) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Memory management ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +nmod_poly_matxx::nmod_poly_matxx(slong m, slong n, mp_limb_t modulus) + + See \code{nmod_poly_mat_init}. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Basic assignment and manipulation ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +?? Nmod_poly_mat_expr::at(T:fits_into_slong, U:fits_into_slong) const + + Unified coefficient access to the matrix entries. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Standard matrices ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +static nmod_poly_matxx nmod_poly_matxx::zero(slong rows, slong cols, + mp_limb_t n) +static nmod_poly_matxx nmod_poly_matxx::one(slong rows, slong cols, + mp_limb_t n) +void Nmod_poly_mat_target::set_zero() +void Nmod_poly_mat_target::set_one() + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Random matrix generation ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +void Nmod_poly_mat_target::set_randtest(frandxx&, slong) +void Nmod_poly_mat_target::set_randtest_sparse(frandxx&, slong, float) +static nmod_poly_matxx nmod_poly_matxx::randtest(slong rows, slong cols, + mp_limb_t n, slong len) +static nmod_poly_matxx nmod_poly_matxx::randtest_sparse(slong rows, slong cols, + mp_limb_t n, slong len, float density) + + See \code{nmod_poly_mat_randtest} etc. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Basic comparison and properties ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +sslong Nmod_poly_mat_expr::rows() const +sslong Nmod_poly_mat_expr::cols() const + + Obtain the number of rows/columns in this matrix. These functions never + cause evaluation (the matrix size is computed from the operations in the + expression template and the size of the input matrices). + +bool Nmod_poly_mat_expr::is_zero() const +bool Nmod_poly_mat_expr::is_one() const +bool Nmod_poly_mat_expr::is_empty() const +bool Nmod_poly_mat_expr::is_square() const +mp_limb_t Nmod_poly_mat_expr::modulus() const + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Norms ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +sslong Nmod_poly_mat_expr::max_length() const + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Arithmetic + + The overloaded operators \code{+ - *} + can be used for both matrix-matrix and + matrix-scalar multiplication, and matrix-matrix addition/subtraction. + Finer control can be obtained with the + following functions. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Nmod_poly_mat_expr mul_classical(Nmod_poly_mat_expr, Nmod_poly_mat_expr) +Nmod_poly_mat_expr mul_interpolate(Nmod_poly_mat_expr, Nmod_poly_mat_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Row reduction + + Beware that compared to the C interface, the flintxx row reduction + interface changes some argument orders. This is to facilitate default + arguments. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +slong find_pivot_any(Nmod_poly_mat_expr, slong, slong, slong) + + See \code{nmod_poly_mat_find_pivot_any}. + +slong find_pivot_partial(Nmod_poly_mat_expr, slong, slong, slong) + + See \code{nmod_poly_mat_find_pivot_partial}. + +Ltuple_expr fflu(Nmod_poly_mat_expr A, + permxx* perm = 0, bool rankcheck = false) + + See \code{nmod_poly_mat_fflu}. + +Ltuple_expr rref(Nmod_poly_mat_expr A) + + See \code{nmod_poly_mat_rref}. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Transpose ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Nmod_poly_mat_expr transpose(Nmod_poly_mat_expr A) + + Compute the transpose of $A$. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Trace ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Nmod_poly_expr trace(Nmod_poly_mat_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Determinant and rank ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Nmod_poly_expr det(Nmod_poly_mat_expr) +Nmod_poly_expr det_fflu(Nmod_poly_mat_expr) +Nmod_poly_expr det_interpolate(Nmod_poly_mat_expr) +slong rank(Nmod_poly_mat_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Inverse ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Ltuple_expr inv(Nmod_poly_mat_expr A) + + \code{ltupleref(worked, M, P) = inv(A)} has the same effect as + \code{worked = nmod_poly_mat_inv(m, p, a)}, where \code{m, p, a} are the C + structs underlying \code{M, P, A}. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Nullspace ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Ltuple_expr nullspace(Nmod_poly_mat_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Solving ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Ltuple_expr solve(Nmod_poly_mat_expr, + Nmod_poly_mat_expr) +Ltuple_expr solve_fflu(Nmod_poly_mat_expr, + Nmod_poly_mat_expr) +Ltuple_expr solve_fflu_precomp( + const permxx&, Nmod_poly_mat_expr B, Nmod_poly_mat_expr FFLU, + Nmod_poly_mat_expr X) + + \code{ltupleref(worked, M, P) = solve(A, X)} has the same effect as + \code{worked = nmod_poly_mat_solve(m, p, a, x)}, where \code{m, p, a, x} + are the C structs underlying \code{M, P, A, X}. + + + +******************************************************************************* + + fmpz\_mod\_polyxx + +******************************************************************************* + +Fmpz_mod_poly_expr::unary operation() const + + The following unary functions are made available as member functions: + \code{derivative}, \code{integral}, \code{make_monic}, \code{sqr}. + +Fmpz_mod_poly_expr::binary operation() const + + The following binary functions are made available as member functions:\\ + \code{compose_divconquer}, \code{compose_horner}, \code{div_basecase},\\ + \code{div_divconquer}, \code{div_newton}, \code{divrem},\\ + \code{divrem_basecase}, \code{divrem_divconquer},\\ + \code{divrem}, \code{divrem_f},\\ + \code{gcd}, \code{gcd_euclidean}, \code{gcd_euclidean_f}, \code{gcd_f},\\ + \code{gcdinv}, \code{invmod}, \code{inv_series_newton},\\ + \code{shift_left}, \code{shift_right}, \code{pow},\\ + \code{rem_basecase}, \code{xgcd}, \code{xgcd_euclidean}. + +Fmpz_mod_poly_expr::ternary operation(??, ??) const + + The following ternary functions are made available as member functions:\\ + \code{compose_mod}, \code{compose_mod_horner},\\ + \code{compose_series_brent_kung}, \code{mullow},\\ + \code{mulmod}, \code{powmod_binexp}, \code{pow_trunc},\\ + \code{pow_trunc_binexp}. + +Fmpz_mod_poly_expr Fmpz_mod_poly_expr::operator()(Fmpz_mod_poly_expr) const +Fmpz_mod_expr Fmpz_mod_poly_expr::operator()(Fmpz_mod_expr) const + + The \code{operator()} is overloaded for evaluation or composition, + depending on the argument. + +Fmpz_mod_poly_expr operator?(??, ??) + + Arithmetic operators \code{+ - * %} are overloaded when provided by + \code{nmod_poly_t}. + +Fmpz_mod_poly_expr operator-(Fmpz_mod_poly_expr) + + The unary negation operator is overloaded. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Input and output ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +print(Fmpz_mod_poly_expr) +print(FILE*, Fmpz_mod_poly_expr) +print_pretty(Fmpz_mod_poly_expr, const char* var) +print_pretty(FILE*, Fmpz_mod_poly_expr, const char* var) +read(Fmpz_mod_poly_target) +read(FILE*, Fmpz_mod_poly_target) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Memory management ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +fmpz_mod_polyxx::fmpz_mod_polyxx(Fmpz_expr n) +fmpz_mod_polyxx::fmpz_mod_polyxx(Fmpz_expr n, slong alloc) + +void Fmpz_mod_poly_target realloc(slong alloc) +void Fmpz_mod_poly_target::fit_length(slong len) +void Fmpz_mod_poly_target::_normalise() +void Fmpz_mod_poly_target::truncate(slong) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Randomisation ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +void Fmpz_mod_poly_mat_target::set_randtest(frandxx&, slong) +void Fmpz_mod_poly_mat_target::set_randtest_irreducible(frandxx&, slong) +void Fmpz_mod_poly_mat_target::set_randtest_not_zero(frandxx&, slong) + + See \code{fmpz_mod_poly_randtest}, etc. + +static fmpz_mod_polyxx fmpz_mod_polyxx::randtest(Fmpz_expr, frandx&, slong) +static fmpz_mod_polyxx fmpz_mod_polyxx::randtest_not_zero(Fmpz_expr, + frandx&, slong) +static fmpz_mod_polyxx fmpz_mod_polyxx::randtest_irreducible(Fmpz_expr, + frandx&, slong) + + Static versions of the above. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Attributes ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +fmpzxx_srcref Fmpz_mod_poly_mat_expr::modulus() const + + Obtain the relevant modulus. This never causes evaluation. + +slong Fmpz_mod_poly_expr::length() const +slong Fmpz_mod_poly_expr::degree() const + +?? Fmpz_mod_poly_expr::lead() const + + Unified coefficient access for the leading coefficient. + The result is undefined if the length of the polynomial is zero. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Assignment and swap ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +void Fmpz_mod_poly_target::zero_coeffs(slong i, slong j) +void Fmpz_mod_poly_target::set_zero() + +static fmpz_mod_polyxx fmpz_mod_polyxx::zero(Fmpz_expr m) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Conversion ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_mod_poly_target Fmpz_mod_poly_target::operator=(T:is_unsigned_integer) +Fmpz_mod_poly_target Fmpz_mod_poly_target::operator=(Fmpz_expr) +Fmpz_mod_poly_target Fmpz_mod_poly_target::operator=(Fmpz_poly_expr) + + See \code{fmpz_mod_poly_set_ui}, \code{fmpz_mod_poly_set_fmpz} and + \code{fmpz_mod_poly_set_fmpz_poly}. + +Fmpz_poly_expr Fmpz_mod_poly_expr::to() const + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Comparison ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +bool Fmpz_mod_poly_expr::is_zero() const + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Getting and setting coefficients ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_expr Fmpz_mod_poly_expr::get_coeff(slong n) const +void Fmpz_mod_target::set_coeff(slong i, Fmpz_expr) +void Fmpz_mod_target::set_coeff(slong i, T:is_unsigned_integer) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Shifting ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_mod_poly_expr shift_left(Fmpz_mod_poly_expr, T:fits_into_slong) +Fmpz_mod_poly_expr shift_right(Fmpz_mod_poly_expr, T:fits_into_slong) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Multiplication + + The overloaded \code{operator*} can be used for both poly-poly and + poly-scalar multiplication. Finer control can be obtained using the + following functions. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_mod_poly_expr mullow(Fmpz_mod_poly_expr, Fmpz_mod_poly_expr, slong) +Fmpz_mod_poly_expr sqr(Fmpz_mod_poly_expr) +Fmpz_mod_poly_expr mulmod(Fmpz_mod_poly_expr, + Fmpz_mod_poly_expr, Fmpz_mod_poly_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Powering ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_mod_poly_expr pow(Fmpz_mod_poly_expr, T:is_unsigned_integer) +Fmpz_mod_poly_expr pow_binexp(Fmpz_mod_poly_expr, T:is_unsigned_integer) +Fmpz_mod_poly_expr pow_trunc(Fmpz_mod_poly_expr, T:is_unsigned_integer, + T:fits_into_slong) +Fmpz_mod_poly_expr pow_trunc_binexp(Fmpz_mod_poly_expr, T:is_unsigned_integer, + T:fits_into_slong) +Fmpz_mod_poly_expr powmod_binexp(Fmpz_mod_poly_expr, T:is_unsigned_integer, + Fmpz_mod_poly_expr) +Fmpz_mod_poly_expr powmod_binexp(Fmpz_mod_poly_expr, Fmpz_expr, + Fmpz_mod_poly_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Division + + The overloaded operators \code{/ %} can be used for division and remainder. + Finer control can be obtained using the following functions. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Ltuple_expr divrem( + Fmpz_mod_poly_expr A, Fmpz_mod_poly_expr B) +Ltuple_expr divrem_basecase( + Fmpz_mod_poly_expr A, Fmpz_mod_poly_expr B) +Ltuple_expr divrem_divconquer( + Fmpz_mod_poly_expr A, Fmpz_mod_poly_expr B) +Ltuple_expr divrem_f( + Fmpz_mod_poly_expr A, Fmpz_mod_poly_expr B) + +Fmpz_mod_poly_expr div_basecase(Fmpz_mod_poly_expr, Fmpz_mod_poly_expr) +Fmpz_mod_poly_expr rem_basecase(Fmpz_mod_poly_expr, Fmpz_mod_poly_expr) +Fmpz_mod_poly_expr rem(Fmpz_mod_poly_expr, Fmpz_mod_poly_expr) + +slong Fmpz_mod_poly_target::remove(Fmpz_mod_poly_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Power series inversion ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_mod_poly_expr inv_series_newton(Fmpz_mod_poly_expr, T:fits_into_slong) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Greatest common divisor ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_mod_poly_expr gcd(Fmpz_mod_poly_expr, Fmpz_mod_poly_expr) +Fmpz_mod_poly_expr gcd_euclidean(Fmpz_mod_poly_expr, Fmpz_mod_poly_expr) + +Ltuple_expr xgcd( + Fmpz_mod_poly_expr, Fmpz_mod_poly_expr) +Ltuple_expr xgcd_euclidean( + Fmpz_mod_poly_expr, Fmpz_mod_poly_expr) +Ltuple_expr gcdinv( + Fmpz_mod_poly_expr, Fmpz_mod_poly_expr) + +Ltuple_expr gcd_f(Fmpz_mod_poly_expr, + Fmpz_mod_poly_expr) +Ltuple_expr gcd_euclidean_f(Fmpz_mod_poly_expr, + Fmpz_mod_poly_expr) + +Fmpz_mod_poly_expr invmod(Fmpz_mod_poly_expr f, Fmpz_mod_poly_expr g) + + See \code{fmpz_mod_poly_invmod}. Raises \code{flint_exception} if $f$ and + $g$ are not coprime. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Derivative ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_mod_poly_expr derivative(Fmpz_mod_poly_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Evaluation ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_mod_expr evaluate(Fmpz_mod_poly_expr, Fmpz_mod_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Composition + + Basic composition can be achieved with the overloaded \code{operator()}. + Finer control can be obtained using the following functions. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_mod_poly_expr compose(Fmpz_mod_poly_expr, Fmpz_mod_poly_expr) +Fmpz_mod_poly_expr compose_horner(Fmpz_mod_poly_expr, Fmpz_mod_poly_expr) +Fmpz_mod_poly_expr compose_divconquer(Fmpz_mod_poly_expr, Fmpz_mod_poly_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Modular composition ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_mod_poly_expr compose_mod(Fmpz_mod_poly_expr, + Fmpz_mod_poly_expr, Fmpz_mod_poly_expr) +Fmpz_mod_poly_expr compose_mod_horner(Fmpz_mod_poly_expr, Fmpz_mod_poly_expr, + Fmpz_mod_poly_expr) +Fmpz_mod_poly_expr compose_mod_divconquer(Fmpz_mod_poly_expr, Fmpz_mod_poly_expr, + Fmpz_mod_poly_expr) +Fmpz_mod_poly_expr compose_mod_brent_kung(Fmpz_mod_poly_expr, Fmpz_mod_poly_expr, + Fmpz_mod_poly_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Radix conversion ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +fmpz_mod_poly_radixxx::fmpz_mod_poly_radixxx(Fmpz_poly_expr, slong deg) + + Initialise temporary data for radix conversion. + See \code{fmpz_mod_poly_radix_init}. + +Fmpz_mod_poly_vec_expr Fmpz_mod_poly_expr::radix(const fmpz_mod_poly_radxxx&) +Fmpz_mod_poly_vec_expr radix(Fmpz_mod_poly_expr F, const fmpz_mod_poly_radxxx&) + + Perform radix conversion. See \code{fmpz_mod_poly_radix}. + Note that computing the output vector size requires knowing the degree of + \code{F}. In the current implementation, this will result in evaluating + \code{F} twice. In order to avoid this, pass in \code{F} in evaluated form, + or do not form expressions requiring temporaries. + + +******************************************************************************* + + fmpz\_mod\_poly\_factorxx + +******************************************************************************* +bool Fmpz_mod_poly_expr::is_squarefree() const +bool Fmpz_mod_poly_expr::is_irreducible() const +bool Fmpz_mod_poly_expr::is_irreducible_ddf() const +bool Fmpz_mod_poly_expr::is_irreducible_rabin() const +slong Fmpz_mod_poly_target::remove(Fmpz_mod_poly_expr) + +fmpz_mod_poly_factorxx::nmod_poly_factorxx() + + Initialise an empty factorisation. + +fmpz_mod_poly_factorxx::nmod_poly_factorxx(const nmod_poly_factorxx& o) + + Copy a factorisation. + +bool fmpz_mod_poly_factorxx::operator==(const nmod_poly_factorxx&) + + Compare two factorisations. + +ulong fmpz_mod_poly_factorxx::size() const + + Return the number of stored factors. + +slong fmpz_mod_poly_factorxx::exp(slong i) const +slong& fmpz_mod_poly_factorxx::exp(slong i) + + Obtain the exponent of the ith factor. + +fmpz_mod_polyxx_srcref nmod_poly_factorxx::p(slong i) const +fmpz_mod_polyxx_ref nmod_poly_factorxx::p(slong i) + + Obtain the ith factor. + +void fmpz_mod_poly_factorxx::realloc(slong a) +void fmpz_mod_poly_factorxx::fit_length(slong a) +void fmpz_mod_poly_factorxx::insert(Fmpz_mod_poly_expr p, slong e) +void fmpz_mod_poly_factorxx::concat(const nmod_poly_factorxx&) + +void fmpz_mod_poly_factorxx::set_factor(Fmpz_mod_poly_expr) +void fmpz_mod_poly_factorxx::set_factor_cantor_zassenhaus(Fmpz_mod_poly_expr) +void fmpz_mod_poly_factorxx::set_factor_berlekamp(Fmpz_mod_poly_expr) +void fmpz_mod_poly_factorxx::set_factor_kaltofen_shoup(Fmpz_mod_poly_expr) +void fmpz_mod_poly_factorxx::set_factor_squarefree(Fmpz_mod_poly_expr) + + Factorise a polynomial and store its factors. See \code{fmpz_mod_poly_factor} etc. + +void fmpz_mod_poly_factorxx::set_factor_equal_deg_probab(frandxx&, Fmpz_mod_poly_expr, + slong) +void fmpz_mod_poly_factorxx::set_factor_equal_deg(Fmpz_mod_poly_expr, slong) + + See \code{fmpz_mod_poly_factor_equal_deg_prob} and + \code{fmpz_mod_poly_factor_equal_deg}. + +void fmpz_mod_poly_factorxx::set_factor_distinct_deg(Fmpz_mod_poly_expr p, + std::vector& degs) + + See \code{fmpz_mod_poly_factor_distinct_deg}. Note that \code{degs} must have + sufficient size to hold all factors. The size of \code{degs} is not + modified. + +fmpz_mod_poly_factorxx factor(Fmpz_mod_poly_expr) +fmpz_mod_poly_factorxx factor_cantor_zassenhaus(Fmpz_mod_poly_expr) +fmpz_mod_poly_factorxx factor_berlekamp(Fmpz_mod_poly_expr) +fmpz_mod_poly_factorxx factor_kaltofen_shoup(Fmpz_mod_poly_expr) +fmpz_mod_poly_factorxx factor_squarefree(Fmpz_mod_poly_expr) + + + + + +******************************************************************************* + + padicxx + + The type \code{padicxx} wraps the C interface \code{padic_t}, and the type + \code{padicxx_ctx} wraps \code{padic_ctx_t}. + + Evaluating composite expressions requires temporary objects, which must be + initialised to a certain precision and with a certain context. The padicxx + library employs the following rules: + + \begin{itemize} + \item In any compound expression, there must only be one context involved. + \item Temporary objects are initialised to the maximum precision of any + subexpression. + \end{itemize} + + In most use cases, all objects in a compound expression have the same + precision, and so temporary expressions are evaluated to this precision. If + you need temporary subexpressions to be evaluated to higher precision, the + \code{toN} method can be used on immediates to increase their effective + precision, thus (potentially) increasing the precision of intermediates. + +******************************************************************************* + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Context ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +padicxx_ctx::padicxx_ctx(Fmpz_src p, slong min, slong max, padic_print_mode mode) + + Initialize a padic context. See \code{padic_ctx_init}. + +padic_ctx_t& padicxx_ctx::_ctx() const + + Obtain a reference to the underlying C data structure. + Note that this reference is mutable even if the instance of + \code{padicxx_ctx} it + is obtained from is not. This is because the context contains data which is + not user-visible, and the C functions change them. + + If this is called on a constant instance of \code{padicxx_ctx}, you must + ensure that no user-visible state is changed. + +padic_print_mode& padicxx_ctx::mode() +padic_print_mode padicxx_ctx::mode() const + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + C++ particulars ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +padicxx_ctx_srcref Padic_src::get_ctx() const +padic_ctx_t& Padic_src::_ctx() const + + Obtain a reference to the context of this instance. + +padicxx_ctx_srcref Padic_expr::estimate_ctx() const + + Obtain a reference to a context occurring in a subexpression. As per the + first rule in the introduction to this section, all such contexts are the + same by definition. + +Padic_expr::unary operation() const + + The following unary functions are made available as member functions: + \code{exp}, \code{exp_balanced}, \code{exp_rectangular}, \code{inv}, + \code{log}, \code{log_balanced}, \code{log_satoh}, \code{sqrt}, + \code{teichmuller}. + +Padic_expr Padic_expr::pow(T:fits_into_slong) const + +padicxx_srcref Padic_src::toN(sslong N) const + + Obtain a new version of the operand, with changed effective precision. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Input and output ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +int print(Padic_expr) +int print(FILE*, Padic_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Data structures ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_expr Padic_expr::unit() const + + See \code{padic_unit}. + +slong Padic_expr::val() const +slong& Padic_target::val() + +slong Padic_expr::prec() const +slong& Padic_target::prec() + + Obtain the precision of this instance. See \code{padic_prec}. + Note that this never requires evaluation. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Memory management ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +padicxx::padicxx(padicxx_ctx_srcref) + + Initialize padic number to default precision. See \code{padic_init}. + +padicxx::padicxx(padicxx_ctx_srcref c, slong N) + + Initialize padic number to precision $N$. See \code{padic_init2}. + +void Padic_target::reduce() + + See \code{padic_reduce}. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Randomisation ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +static padicxx padicxx::randtest(frandxx& state, padicxx_ctx_srcref ctx, + slong prec = PADIC_DEFAULT_PREC) + +static padicxx padicxx::randtest_int(frandxx& state, padicxx_ctx_srcref ctx, + slong prec = PADIC_DEFAULT_PREC) + +static padicxx padicxx::randtest_not_zero(frandxx& state, + padicxx_ctx_srcref ctx, slong prec = PADIC_DEFAULT_PREC) + + Obtain a random padic number of precision \code{prec}. See + \code{padic_randtest}, \code{padic_randtest_int} and + \code{padic_randtest_not_zero}. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Conversion ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Padic_target Padic_target::operator=(T:is_integer) +Padic_target Padic_target::operator=(Fmpz_expr) +Padic_target Padic_target::operator=(Fmpq_expr) + +padicxx padicxx::from_QQ(Fmpq_expr, padicxx_ctx_srcref) +padicxx padicxx::from_QQ(Fmpz_expr, padicxx_ctx_srcref) +padicxx padicxx::from_QQ(T:is_integer, padicxx_ctx_srcref) +padicxx padicxx::from_QQ(Fmpq_expr, padicxx_ctx_srcref, sslong N) +padicxx padicxx::from_QQ(Fmpz_expr, padicxx_ctx_srcref, sslong N) +padicxx padicxx::from_QQ(T:is_integer, padicxx_ctx_srcref, sslong N) + +void Padic_target::set_zero() +void Padic_target::set_one() + +padicxx padicxx::zero(padicxx_ctx_srcref) +padicxx padicxx::zero(padicxx_ctx_srcref, sslong N) +padicxx padicxx::one(padicxx_ctx_srcref) +padicxx padicxx::one(padicxx_ctx_srcref, sslong N) + +bool Padic_expr::is_zero() const +bool Padic_expr::is_one() const + +fmpzxx Padic_expr::to() const + + Convert self to \code{fmpzxx}, if possible. See \code{padic_get_fmpz}. + +fmpqxx Padic_expr::to() const + + Convert self to \code{fmpqxx}. See \code{padic_get_fmpz}. + +std::string Fmpz_expr::to_string() const + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Arithmetic operations + + The overloaded operators \code{+ - * / << >>} can be used for arithmetic + operations, provided these are implemented for \code{padic_t}. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Padic_expr inv(Padic_expr) + +Padic_expr sqrt(Padic_expr) + + Compute square root. May raise \code{flint_exception} if no square root + exists. See \code{padic_sqrt}. + +Padic_expr pow(Padic_expr, T:fits_into_slong) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Exponential ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Padic_expr exp(Padic_expr) +Padic_expr exp_rectangular(Padic_expr) +Padic_expr exp_balanced(Padic_expr) + + Compute the exponential function. These may raise \code{flint_exception}s if the + series do not converge. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Logarithm ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Padic_expr log(Padic_expr) +Padic_expr log_rectangular(Padic_expr) +Padic_expr log_balanced(Padic_expr) +Padic_expr log_satoh(Padic_expr) + + Compute the logarithm function. These may raise \code{flint_exception}s if the + series do not converge. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Special functions ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Padic_expr teichmuller(Padic_expr) + +Fmpz_expr padic_val_fac(Fmpz_expr, Fmpz_expr) +ulong padic_val_fac(T:is_unsigned_integer, Fmpz_expr) + + + +******************************************************************************* + + padic\_polyxx + + The type \code{padic_polyxx} wraps \code{padic_poly}. Like \code{padicxx}, + every instance of \code{padic_polyxx} contains a reference to a context + \code{padicxx_ctx}, and stores its own precision. The same rules regarding + temporary expressions apply to \code{padic_polyxx} as to \code{padicxx}. + +******************************************************************************* + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + C++ particulars ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +padicxx_ctx_srcref Padic_poly_src::get_ctx() const +padic_ctx_t& Padic_poly_src::_ctx() const + + Obtain a reference to the context of this instance. + +padicxx_ctx_srcref Padic_poly_expr::estimate_ctx() const + + Obtain a reference to a context occurring in a subexpression. + +Padic_poly_expr::unary operation() const + + The following unary functions are made available as member functions: + \code{derivative}. + +Padic_poly_expr::binary operation() const + + The following binary functions are made available as member functions: + \code{pow}, \code{compose_pow}, \code{inv_series}, \code{shift_left}, + \code{shift_right}. + +padic_polyxx_srcref Padic_poly_src::toN(sslong N) const + + Obtain a new version of the operand, with changed effective precision. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Input and output ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +int print(Padic_expr) +int print(FILE*, Padic_expr) +int print_pretty(Padic_expr, const char*) +int print_pretty(FILE*, Padic_expr, const char*) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Memory management ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +padic_polyxx::padic_polyxx(padicxx_ctx_srcref) + + Initialise to zero. See \code{padic_poly_init}. + +padic_polyxx::padic_polyxx(padicxx_ctx_srcref, slong prec, slong alloc = 0) + + See \code{padic_poly_init2}. + +void Padic_poly_target realloc(slong alloc) +void Padic_poly_target::fit_length(slong len) +void Padic_poly_target::canonicalise() +void Padic_poly_target::reduce() +void Padic_poly_target::truncate(slong) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Polynomial parameters ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +slong Padic_poly_expr::length() const +slong Padic_poly_expr::degree() const + +slong Padic_expr::val() const +slong& Padic_target::val() + +slong Padic_expr::prec() const +slong& Padic_target::prec() + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Randomisation ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +static padic_polyxx padic_polyxx::randtest(frandxx& state, padicxx_ctx_srcref ctx, + slong len, + slong prec = PADIC_DEFAULT_PREC) + +static padic_polyxx padic_polyxx::randtest_val(frandxx& state, padicxx_ctx_srcref ctx, + slong len, slong val, + slong prec = PADIC_DEFAULT_PREC) + +static padic_polyxx padic_polyxx::randtest_not_zero(frandxx& state, + slong len, + padicxx_ctx_srcref ctx, slong prec = PADIC_DEFAULT_PREC) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Assignment an basic manipulation + + The overloaded \code{operator=} can be used for assignments. Additionally, + we provide the following functions. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +padic_polyxx padic_polyxx::from_QQ(T:is_integer, padicxx_ctx_srcref, sslong N) +padic_polyxx padic_polyxx::from_QQ(Fmpz_expr, padicxx_ctx_srcref, sslong N) +padic_polyxx padic_polyxx::from_QQ(Fmpq_expr, padicxx_ctx_srcref, sslong N) +padic_polyxx padic_polyxx::from_QQ(T:is_integer, padicxx_ctx_srcref) +padic_polyxx padic_polyxx::from_QQ(Fmpz_expr, padicxx_ctx_srcref) +padic_polyxx padic_polyxx::from_QQ(Fmpq_expr, padicxx_ctx_srcref) +padic_polyxx padic_polyxx::from_QQX(Fmpz_poly_expr, padicxx_ctx_srcref, sslong N) +padic_polyxx padic_polyxx::from_QQX(Fmpq_poly_expr, padicxx_ctx_srcref, sslong N) +padic_polyxx padic_polyxx::from_QQX(Fmpz_poly_expr, padicxx_ctx_srcref) +padic_polyxx padic_polyxx::from_QQX(Fmpz_poly_expr, padicxx_ctx_srcref) +padic_polyxx padic_polyxx::from_ground(Padic_expr) + +fmpz_polyxx Padic_poly_expr::to() const + + Convert to an integer polynomial. Raises \code{flint_exception} if the + polynomial is not p-adically integral. See \code{padic_poly_get_fmpz_poly}. + +fmpq_polyxx Padic_poly_expr::to() const + + See \code{padic_poly_get_fmpq_poly}. + +padic_polyxx padic_polyxx::zero(const padic_polyxx_ctx&) +padic_polyxx padic_polyxx::zero(const padic_polyxx_ctx&, sslong N) +padic_polyxx padic_polyxx::one(const padic_polyxx_ctx&) +padic_polyxx padic_polyxx::one(const padic_polyxx_ctx&, sslong N) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Getting and setting coefficients ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Padic_expr Padic_poly_expr::get_coeff(slong n) const +void Padic_poly_target::set_coeff(slong i, Padic_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Comparison + + The overloaded \code{operator==} can be used for comparison. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +bool Padic_poly_expr::is_zero() const +bool Padic_poly_expr::is_one() const + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Arithmetic + + The overloaded operators \code{+ - *} can be used for arithmetic. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Powering ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Padic_poly_expr pow(Padic_poly_expr, T:fits_into_slong) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Series inversion ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Padic_poly_expr inv_series_newton(Padic_poly_expr, T:fits_into_slong) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Derivative ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Padic_poly_expr derivative(Padic_poly_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Shifting ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Padic_poly_expr shift_left(Padic_poly_expr, T:fits_into_slong) +Padic_poly_expr shift_right(Padic_poly_expr, T:fits_into_slong) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Evaluation and composition + + The overloaded \code{operator()} can be used for both evaluation and + composition. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Padic_expr evaluate(Padic_poly_expr, Padic_expr) +Padic_poly_expr compose(Padic_poly_expr, Padic_poly_expr) +Padic_poly_expr compose_pow(Padic_poly_expr, T:fits_into_slong) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Testing ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +bool Padic_poly_src::is_canonical() const +bool Padic_poly_src::is_reduced() const + + + + +******************************************************************************* + + padic\_matxx + + The type \code{padic_matxx} wraps \code{padic_mat}. Like \code{padicxx}, + every instance of \code{padic_matxx} contains a reference to a context + \code{padicxx_ctx}, and stores its own precision. The same rules regarding + temporary expressions apply to \code{padic_matxx} as to \code{padicxx}. + +******************************************************************************* + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + C++ particulars ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +padicxx_ctx_srcref Padic_mat_src::get_ctx() const +padic_ctx_t& Padic_mat_src::_ctx() const + + Obtain a reference to the context of this instance. + +padicxx_ctx_srcref Padic_mat_expr::estimate_ctx() const + + Obtain a reference to a context occurring in a subexpression. + +padic_matxx_srcref Padic_mat_src::toN(sslong N) const + + Obtain a new version of the operand, with changed effective precision. + +slong Padic_mat_expr::rows() const +slong Padic_mat_expr::cols() const + + Obtain the number of rows/columns of this matrix. This never evaluates. + +slong Padic_mat_expr::val() const +slong& Padic_mat_target::val() + +Padic_mat_expr Padic_mat_expr::transpose() const + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Input and output ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +int print(Padic_mat_expr) +int print(FILE*, Padic_mat_expr) +int print_pretty(Padic_mat_expr) +int print_pretty(FILE*, Padic_mat_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Memory management ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +padic_matxx::padic_matxx(padicxx_ctx_srcref, slong rows, slong cols) + + See \code{padic_mat_init}. + +padic_matxx::padic_matxx(padicxx_ctx_srcref, slong rows, slong cols, slong prec) + + See \code{padic_mat_init2}. + +void Padic_mat_target::canonicalise() +void Padic_mat_target::reduce() +bool Padic_mat_src::is_canonical() const +bool Padic_mat_src::is_reduced() const +bool Padic_mat_src::is_square() const +bool Padic_mat_src::is_empty() const + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Basic assignment + + Overloaded \code{operatior=} can be used for assignment. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +void Padic_mat_target::set_zero() +void Padic_mat_target::set_one() +padic_matxx padic_matxx::zero(padicxx_ctx_srcref) +padic_matxx padic_matxx::zero(padicxx_ctx_srcref, sslong N) +padic_matxx padic_matxx::one(padicxx_ctx_srcref) +padic_matxx padic_matxx::one(padicxx_ctx_srcref, sslong N) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Conversion + + Converting from a \code{fmpq_matxx} can be done using \code{operator=}, or + the following functions. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +padic_matxx padic_matxx::from_QQ(Fmpq_mat_expr, padicxx_ctx_srcref) +fmpq_matxx Padic_mat_expr::to() const + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Entries ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +?? Padic_mat_expr::at(slong i, slong j) + + Unified coefficient access to the underlying integer matrix. See + \code{padic_mat_entry}. + +Fmpz_expr Padic_mat_expr::get_entry(slong i, slong j) +void Padic_mat_target::set_entry(slong i, slong j, Padic_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Comparison + + Overloaded \code{operator==} can be used for comparison. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +bool Padic_mat_expr::is_zero() const + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Random matrix generation ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +static padic_polyxx padic_polyxx::randtest(slong rows, slong cols, + frandxx& state, padicxx_ctx_srcref ctx, slong prec = PADIC_DEFAULT_PREC) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Transpose ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Padic_mat_expr transpose(Padic_mat_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Arithmetic + + Overloaded operators \code{+ - * /} can be used for arithmetic. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + + + +******************************************************************************* + + qadicxx + + The type \code{qadicxx} wraps the C interface \code{qadic_t}, and the type + \code{qadicxx_ctx} wraps \code{qadic_ctx_t}. + + Evaluating composite expressions requires temporary objects, which must be + initialised to a certain precision and with a certain context. The same + rules apply as for \code{padicxx}. + +******************************************************************************* + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Context ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +qadicxx_ctx::qadicxx_ctx(Fmpz_src p, sslong min, slong max, + padic_print_mode mode, const char* var = "x") + + Initialize a qadic context. See \code{qadic_ctx_init_conway}. + +qadic_ctx_t& qadicxx_ctx::_ctx() const + + Obtain a reference to the underlying C data structure. + Note that this reference is mutable even if the instance of + \code{qadicxx_ctx} it + is obtained from is not. This is because the context contains data which is + not user-visible, and the C functions change them. + + If this is called on a constant instance of \code{qadicxx_ctx}, you must + ensure that no user-visible state is changed. + +padicxx_ctx_srcref qadicxx_ctx::pctx() const + + Obtain a reference to the underlying padic context. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + C++ particulars ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +padicxx_ctx_srcref Qadic_src::get_ctx() const +const qadicxx_ctx& Qadic_src::get_qctx() const +qadic_ctx_t& Qadic_src::_ctx() const + + Obtain a reference to the context of this instance. + +const qadicxx_ctx& Qadic_expr::estimate_ctx() const + + Obtain a reference to a context occurring in a subexpression. As per the + first rule in the introduction to this section, all such contexts are the + same by definition. + +Qadic_expr::unary operation() const + + The following unary functions are made available as member functions: + \code{exp}, \code{exp_balanced}, \code{exp_rectangular}, \code{inv}, + \code{log}, \code{log_balanced}, \code{teichmuller}, \code{trace}, + \code{norm}, \code{norm_analytic}, \code{norm_resultant}. + +Qadic_expr Qadic_expr::pow(Fmpz_expr) const +Qadic_expr Qadic_expr::frobenius(T:fits_into_slong) const + +qadicxx_srcref Qadic_src::toN(sslong N) const + + Obtain a new version of the operand, with changed effective precision. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Data structures ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +int print_pretty(Qadic_expr) +int print_pretty(FILE*, Qadic_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Data structures ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +slong Qadic_expr::val() const + +slong Qadic_expr::prec() const + + Obtain the precision of this instance. See \code{qadic_prec}. + Note that this never requires evaluation. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Memory management ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +qadicxx::qadicxx(const qadicxx_ctx&) + + Initialize qadic number to default precision. See \code{qadic_init}. + +qadicxx::qadicxx(const qadicxx_ctx& c, slong N) + + Initialize qadic number to precision $N$. See \code{qadic_init2}. + +void Qadic_target::reduce() + + See \code{qadic_reduce}. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Randomisation ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +static qadicxx qadicxx::randtest(frandxx& state, const qadicxx_ctx& ctx, + slong prec = PADIC_DEFAULT_PREC) + +static qadicxx qadicxx::randtest_int(frandxx& state, slong val, + const qadicxx_ctx& ctx, slong prec = PADIC_DEFAULT_PREC) + +static qadicxx qadicxx::randtest_val(frandxx& state, const qadicxx_ctx& ctx, + slong prec = PADIC_DEFAULT_PREC) + +static qadicxx qadicxx::randtest_not_zero(frandxx& state, + const qadicxx_ctx& ctx, slong prec = PADIC_DEFAULT_PREC) + + Obtain a random qadic number of precision \code{prec}. See + \code{qadic_randtest}, \code{qadic_randtest_int} and + \code{qadic_randtest_not_zero}. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Conversion ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Qadic_target Qadic_target::operator=(T:is_unsigned_integer) +Qadic_target Qadic_target::operator=(Padic_expr) + +qadicxx qadicxx::from_ground(Padic_expr, const qadicxx_ctx&) + +void Qadic_target::set_zero() +void Qadic_target::set_one() +void Qadic_target::set_gen(const qadicxx_ctx&) + +qadicxx qadicxx::zero(const qadicxx_ctx&) +qadicxx qadicxx::zero(const qadicxx_ctx&, sslong N) +qadicxx qadicxx::one(const qadicxx_ctx&) +qadicxx qadicxx::one(const qadicxx_ctx&, sslong N) +qadicxx qadicxx::gen(const qadicxx_ctx&) +qadicxx qadicxx::gen(const qadicxx_ctx&, sslong N) + +bool Qadic_expr::is_zero() const +bool Qadic_expr::is_one() const + +padicxx Qadic_expr::to() const + + Convert self to \code{padicxx}, if possible. See \code{qadic_get_padic}. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Arithmetic operations + + The overloaded operators \code{+ - * / << >>} can be used for arithmetic + operations, provided these are implemented for \code{qadic_t}. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Qadic_expr inv(Qadic_expr) + +Qadic_expr pow(Qadic_expr, Fmpz_expr) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Exponential ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Qadic_expr exp(Qadic_expr) +Qadic_expr exp_rectangular(Qadic_expr) +Qadic_expr exp_balanced(Qadic_expr) + + Compute the exponential function. These may raise \code{flint_exception}s + if the series do not converge. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Logarithm ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Qadic_expr log(Qadic_expr) +Qadic_expr log_balanced(Qadic_expr) + + Compute the logarithm function. These may raise \code{flint_exception}s + if the series do not converge. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Special functions ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Qadic_expr teichmuller(Qadic_expr) +Padic_expr trace(Qadic_expr) +Padic_expr norm(Qadic_expr) +Padic_expr norm_analytic(Qadic_expr) +Padic_expr norm_resultant(Qadic_expr) + + + + +******************************************************************************* + + arithxx + + The \code{arithxx} module wraps the \code{arith} module, i.e. provides + functions for computing number theoretic functions. + +******************************************************************************* + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Primorials ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_expr primorial(T:fits_into_slong) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Harmonic numbers ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpq_expr harmonic_number(T:fits_into_slong) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Stirling numbers ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_expr stirling_number_1u(T:fits_into_slong, T:fits_into_slong) +Fmpz_expr stirling_number_1(T:fits_into_slong, T:fits_into_slong) +Fmpz_expr stirling_number_2(T:fits_into_slong, T:fits_into_slong) + +Fmpz_vec_expr stirling_number_1u_vec(T:fits_into_slong, T:fits_into_slong) +Fmpz_vec_expr stirling_number_1_vec(T:fits_into_slong, T:fits_into_slong) +Fmpz_vec_expr stirling_number_2_vec(T:fits_into_slong, T:fits_into_slong) + +Fmpz_vec_expr stirling_number_1u_vec_next(Fmpz_vec_expr v, T:fits_into_slong n) +Fmpz_vec_expr stirling_number_1_vec_next(Fmpz_vec_expr v, T:fits_into_slong n) +Fmpz_vec_expr stirling_number_2_vec_next(Fmpz_vec_expr v, T:fits_into_slong n) + + Given the vector $v$ of length $k$, compute the next vector of Stirling + numbers. The size of the new vector is $k + 1$ if $k = n$, and else $k$. + + See \code{arith_stirling_number_1u_vec_next} etc. + +Fmpz_mat_expr stirling_matrix_1u(T:fits_into_slong m, T:fits_into_slong) +Fmpz_mat_expr stirling_matrix_1(T:fits_into_slong m, T:fits_into_slong) +Fmpz_mat_expr stirling_matrix_2(T:fits_into_slong m, T:fits_into_slong) + + Compute an $m \times n$ Stirling matrix. + + See \code{arith_stirling_matrix_1u} etc. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Bell numbers ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_expr bell_number(T:is_unsigned_integer) +Fmpz_expr bell_number_bsplit(T:is_unsigned_integer) +Fmpz_expr bell_number_multi_mod(T:is_unsigned_integer) +Fmpz_vec_expr bell_number_vec(T:is_unsigned_integer) +Fmpz_vec_expr bell_number_vec_recursive(T:is_unsigned_integer) +Fmpz_vec_expr bell_number_vec_multi_mod(T:is_unsigned_integer) + +Nmod_expr bell_number_nmod(T:is_unsigned_integer, Nmodxx_ctx_src) +Nmod_vec_expr bell_number_nmod_vec(T:is_unsigned_integer, Nmodxx_ctx_src) +Nmod_vec_expr bell_number_nmod_vec_recursive(T:is_unsigned_integer, + Nmodxx_ctx_src) +Nmod_vec_expr bell_number_nmod_vec_series(T:is_unsigned_integer, Nmodxx_ctx_src) + +double bell_number_size(ulong n) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Bernoulli numbers and polynomials ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpq_expr bernoulli_number(T:is_unsigned_integer) +Fmpq_vec_expr bernoulli_number_vec(T:fits_into_slong) +Fmpz_expr bernoulli_number_denom(T:is_unsigned_integer) +double bernoulli_number_size(ulong) +Fmpq_poly_expr bernoulli_polynomial(T:is_unsigned_integer) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Euler numbers and polynomials ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpq_expr euler_number(T:is_unsigned_integer) +Fmpq_vec_expr euler_number_vec(T:fits_into_slong) +double euler_number_size(ulong) +Fmpq_poly_expr euler_polynomial(T:is_unsigned_integer) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Legendre polynomials ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpq_poly_expr legendre_polynomial(T:is_unsigned_integer) +Fmpz_poly_expr chebyshev_t_polynomial(T:is_unsigned_integer) +Fmpz_poly_expr chebyshev_u_polynomial(T:is_unsigned_integer) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Multiplicative functions ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_expr euler_phi(Fmpz_expr) +int moebius_mu(Fmpz_expr) +Fmpz_expr divisor_sigma(Fmpz_expr, ulong) +Fmpz_poly_expr divisors(Fmpz_expr) +Fmpz_expr ramanujan_tau(Fmpz_expr) +Fmpz_poly_expr ramanujan_tau_series(T:fits_into_slong) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Cyclotomic polynomials ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_poly_expr cyclotomic_polynomial(T:is_unsigned_integer) +Fmpz_poly_expr cos_minpoly(T:is_unsigned_integer) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Swinnerton-Dyer polynomials ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_poly_expr swinnerton_dyer_polynomial(T:is_unsigned_integer) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Landau's function ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_vec_expr landau_function_vec(T:is_unsigned_integer) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Dedekind sums ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_expr dedekind_sum_naive(Fmpz_expr, Fmpz_expr) +Fmpz_expr dedekind_sum_coprime_large(Fmpz_expr, Fmpz_expr) +Fmpz_expr dedekind_sum_coprime(Fmpz_expr, Fmpz_expr) +Fmpz_expr dedekind_sum(Fmpz_expr, Fmpz_expr) +double dedekind_sum_d(double, double) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Number of partitions ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_vec_expr number_of_partitions_vec(T:fits_into_slong) +Nmod_vec_expr number_of_partitions_nmod_vec(T:fits_into_slong) +Fmpz_expr number_of_partitions(T:is_unsigned_integer) + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Sums of squares ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Fmpz_expr sum_of_squares(T:is_unsigned_integer, Fmpz_expr) +Fmpz_vec_expr sum_of_squares(T:is_unsigned_integer, T:fits_into_slong) diff --git a/external/flint-2.4.3/flintxx/doc/genericxx.txt b/external/flint-2.4.3/flintxx/doc/genericxx.txt new file mode 100644 index 0000000..ad45866 --- /dev/null +++ b/external/flint-2.4.3/flintxx/doc/genericxx.txt @@ -0,0 +1,478 @@ +/*============================================================================= +vim: spell spelllang=en textwidth=79 + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +******************************************************************************* + + Rules and standard methods + + A typical expression template class begins with the following lines of code: + + \begin{lstlisting}[language=c++] + template + class some_expression + : public expression, Operation, Data> + { + // ... + }; + \end{lstlisting} + + We document here methods this class inherits from its base, and how they + relate to rules. + + There are the following public typedefs: + + \begin{description} + \item[ev\_traits\_t] A specialisation of \code{detail::evaluation_traits}. + Used to compute the rule for evaluation. + \item[derived\_t] The specialised derived class. + \item[evaluated\_t] The resulting type of evaluating this expression. + \item[evaluation\_return\_t] The return type of \code{evaluate()}. This + differs from the above for immediates, where evaluation returns a + reference instead of a copy. + \item[data\_t] The same as \code{Data}. + \item[operation\_t] The same as \code{Operation}. + \end{description} + +******************************************************************************* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Standard methods ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +data_t& some_expression::_data() +const data_t& some_expression::_data() const + + Obtain the data related to this expression template. + +evaluated_t some_expression::create_temporary() const + + Default instantiate a temporary. Override this if your class is not default + instantiable. + +template T some_expression::to() const + + Convert self to type \code{T} (after evaluating). Uses + \code{rules::conversion}. + +void some_expression::print(std::ostream& o) const + + Print self to \code{o}. Uses \code{rules::print} or + \code{rules::to_string}. + +int some_expression::print(FILE* f = stdout) const + + Print self to \code{f}. Uses \code{rules::cprint}. + +int some_expression::print_pretty(FILE* f = stdout) const + + Print self to \code{f}. Uses \code{rules::print_pretty}. + +template int some_expression::print_pretty(const T& extra, + FILE* f = stdout) const + + Print self to \code{f}. Uses \code{rules::print_pretty} with two arguments. + +int some_expression::read(FILE* f = stdin) + + Read self from \code{f}. Uses \code{rules::read}. + +const evaluation_return_t some_expression::evaluate() const + + Evaluate self. + +template void some_expression::set(const T& t) + + Assign \code{t} to self. Uses evaluation and/or \code{rules::assignment}. + +template bool some_expression::equals(const T& t) const + + Determine if \code{t} is equal to self. Uses \code{rules::equals} or + \code{rules::cmp}. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Global functions + + In addition to member functions, flintxx also provides a number of global + functions. In general these operate on sets of arguments at least one of + which derives from \code{expression}, and are conditionally enabled only if + the relevant operation is implemented (via a rule). ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +template std::ostream& operator<<(std::ostream& o, const Expr& e) + + Print \code{e} to \code{o}. Uses the member \code{print}. + +template bool operator==(const Expr1&, const Expr2&) +template bool operator!=(const Expr1&, const Expr2&) + + Compare two expressions. Uses the member \code{equals}. + +template bool operator??(const Expr1&, const Expr2&) + + Relational operators \code{< > <= =>} are implemented using + \code{rules::cmp}. + +template ?? operator??(const Expr1&, const Expr2&) + + Arithmetic operators \code{+ - * / % & | ^ << >>} are implemented + by constructing new expression templates with operation + \code{operations::plus} etc. + +template ?? operator??(const Expr1&) + + Unary operators \code{- ~} are implemented by constructing new expression + templates with operation \code{operations::negate} and + \code{operations::complement}. + +template ?? operator?=(const Expr1&, const Expr2&) + + Arithmetic-assignment operators \code{+= -= *= /= %= |= &= ^=}. + +template int print(const Expr1&) +template int print(FILE*f, const Expr1&) +template int print_pretty(const Expr1&) +template int print_pretty(FILE*f, const Expr1&) +template int print_pretty(const Expr1&, const T& extra) +template int print_pretty(FILE*f, const Expr1&, + const T& extra) + + Forward to member. + +template void swap(Expr1& e1, Expr2& e2) + + Swap \code{e1} and \code{e2} using \code{rules::swap}. Note that via ADL, + this can be used by STL containers. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + flintxx classes + + The flint wrapper classes share some other common interfaces. These have to + be enabled using the convenience macros in \code{flintxx/flint_classes.h} + (q.v.). Here \code{accessname} and \code{ctype} are specified via the + macros. For e.g. \code{fmpz_polyxx} these are \code{_poly} and + \code{fmpz_poly_struct}. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +?? some_expression::accessname() +?? some_expression::accessname() const + + Obtain a reference to the underlying C struct. This is only available on + immediate expressions. + +some_expression_ref::some_expression_ref(some_expression&) +some_expression_srcref::some_expression_srcref(const some_expression&) +some_expression_srcref::some_expression_srcref(some_expression_ref) + + Build a reference type. Note that these are \emph{implicit} constructors. + +static some_expression_ref some_expression_ref::make(ctype*) +static some_expression_srcref some_expression_srcref::make(const ctype*) + + Build a reference type from a pointer to the underlying C struct. + + +******************************************************************************* + + Convenience macros + +******************************************************************************* + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + flintxx/rules.h ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +FLINT_DEFINE_GET2(name, totype, fromtype1, fromtype2, eval) + + Specialise a getter called \code{name}, which takes arguments \code{e1} of + type \code{fromtype1} and \code{e2} of type \code{fromtype2}. It returns + \code{totype} by executing \code{eval}. + +FLINT_DEFINE_GET(name, totype, fromtype, eval) + + Same as \code{FLINT_DEFINE_GET2(name, totype, fromtype, fromtype, eval)}. + +FLINT_DEFINE_GET_COND(name, totye, cond, eval) + + Specialise a getter called \code{name}, which takes an argument \code{from} + of type \code{T:cond} It returns \code{totype} by + executing \code{eval}. + +FLINT_DEFINE_DOIT(name, totype, fromtype, eval) + + Specialise a doit rule called \code{name}, which takes arguments + \code{to} of type \code{totype&} and \code{from} of type + \code{const fromtype&}, and executes \code{eval}. + +FLINT_DEFINE_DOIT_COND(name, totype, cond, eval) + + Same as above, but takes \code{const T& from} for any \code{T:cond}. + +FLINT_DEFINE_DOIT_COND2(name, cond1, cond2, eval) + + Same as \code{FLINT_DEFINE_DOIT_COND}, but takes \code{T& to} and + \code{const U& from} for any \code{T} satisfying \code{cond1} and + \code{U} satisfying \code{cond2}. + +FLINT_DEFINE_PRINT_COND(cond, eval) + + Specialise the \code{cprint} rule. This takes a arguments \code{FILE* to} + and \code{const T& from} for any \code{T:cond}. It + prints \code{from} to \code{to} and returns \code{int} by executing + \code{eval}. + +FLINT_DEFINE_PRINT_PRETTY_COND(cond, eval) + + Same as above, but with \code{print_pretty} instead of \code{cprint}. + +FLINT_DEFINE_PRINT_PRETTY_COND2(cond, extratype, eval) + + Same as above, but takes an additional argument \code{extratype extra}. + Useful e.g. when printing polynomials and taking an extra variable name. + +FLINT_DEFINE_READ_COND(cond, eval) + + Specialise the \code{read} rule. This takes a arguments \code{FILE* from} + and \code{T& to} for any \code{T:cond}. It + reads \code{to} from \code{from} and returns \code{int} by executing + \code{eval}. + +FLINT_DEFINE_UNARY_EXPR_(name, rtype, type, eval) + + Specialise the unary expression rule for \code{operations::name} with + nominal return type \code{rtype}. It takes + arguments \code{V& to} and \code{const type& from}. Here \code{V} is any + type which \code{rtype} can be evaluated into. Executes \code{eval}. + +FLINT_DEFINE_UNARY_EXPR(name, type, eval) + + Same as \code{FLINT_DEFINE_UNARY_EXPR_(name, type, type, eval)}. + +FLINT_DEFINE_BINARY_EXPR2(name, rtype, type1, type2, eval) + + Specialise the binary expression rule for \code{operations::name} of + nominal return type \code{rtype}, and arguments \code{type1} and + \code{type2}. + +FLINT_DEFINE_BINARY_EXPR(name, type, eval) + + Same as \code{FLINT_DEFINE_BINARY_EXPR2(name, type, type, type, eval)}. + +FLINT_DEFINE_CBINARY_EXPR(name, type, eval) + + Same as above, but with \code{commutative_binary_expression} instead of + \code{binary_expression}. + +FLINT_DEFINE_BINARY_EXPR_COND(name, type, cond, eval) +FLINT_DEFINE_CBINARY_EXPR_COND(name, type, cond, eval) + + Specialise the (commutative) binary expression rule for + \code{operations::name} of nominal return type \code{type}, and arguments + \code{type} and \code{T:cond}. + +FLINT_DEFINE_BINARY_EXPR_COND2(name, rettype, cond1, cond2, eval) +FLINT_DEFINE_CBINARY_EXPR_COND2(name, rettype, cond1, cond2, eval) + + Specialise the (commutative) binary expression rule for + \code{operations::name} of nominal return type \code{rettype}, and arguments + \code{T:cond1} and \code{U:cond2}. + +FLINT_DEFINE_THREEARY_EXPR_COND3(name, rettype, cond1, cond2, cond3, eval) +FLINT_DEFINE_FOURARY_EXPR_COND4(name, retttype, cond1 ... cond4, eval) +FLINT_DEFINE_FIVEARY_EXPR_COND5(name, rettype, cond1 ... cond5, eval) +FLINT_DEFINE_SIXARY_EXPR_COND6(name, rettype, cond1 ... cond6, eval) +FLINT_DEFINE_SEVENARY_EXPR_COND7(name, rettype, cond1 ... cond7, eval) + + Specialise higher order rules, similarly to the above. + +FLINT_DEFINE_THREEARY_EXPR(name, retttype, T1, T2, T3, eval) + + Specialise a threeary expression rule unconditionally. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + flintxx/expression.h ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +FLINT_DEFINE_UNNOP(name) +FLINT_DEFINE_BINOP(name) +FLINT_DEFINE_THREEARY(name) +FLINT_DEFINE_FOURARY(name) +FLINT_DEFINE_FIVEARY(name) +FLINT_DEFINE_SIXARY(name) +FLINT_DEFINE_SEVENARY(name) + + Introduce a new n-ary operation \code{operations::##name##_op} and make it + available. This has to be called in namespace \code{flint}. + +FLINT_DEFINE_UNNOP_HERE(name) +FLINT_DEFINE_BINOP_HERE(name) +FLINT_DEFINE_THREEARY_HERE(name) +FLINT_DEFINE_FOURARY_HERE(name) +FLINT_DEFINE_FIVEARY_HERE(name) +FLINT_DEFINE_SIXARY_HERE(name) +FLINT_DEFINE_SEVENARY_HERE(name) + + Make the n-ary operation \code{operations::##name##_op} available in the + current namespace. + +FLINT_DEFINE_THREEARY_HERE_2DEFAULT(name, type1, val1, type2, val2) + + Make the threeary operation \code{name} available in current namespace, + but with only two arguments, the second of which is of type \code{type1} and + defaults to \code{val1}, and the third argument always (implicitly) of type + \code{type2} and value \code{val2}. + The suggested usage of this macro is to first call + \code{FLINT_DEFINE_THREEARY_HERE} (or \code{FLINT_DEFINE_THREEARY}), + and then call \code{FLINT_DEFINE_THREEARY_HERE_2DEFAULT}. The effect will be an + operation which can be invoked with 1, 2 or 3 arguments. + +FLINT_UNOP_ENABLE_RETTYPE(name, T1) +FLINT_BINOP_ENABLE_RETTYPE(name, T1, T2) +FLINT_THREEARY_ENABLE_RETTYPE(name, T1, T2, T3) +FLINT_FOURARY_ENABLE_RETTYPE(name, T1, T2, T3, T4) +FLINT_FIVEARY_ENABLE_RETTYPE(name, T1, T2, T3, T4, T5) +FLINT_SIXARY_ENABLE_RETTYPE(name, T1, T2, T3, T4, T5, T6) +FLINT_SEVENARY_ENABLE_RETTYPE(name, T1, T2, T3, T4, T5, T6, T7) + + Obtain the resulting type of invoking \code{name} with arguments of types + \code{T1}, ..., \code{Tn} if this is possible. Otherwise results in an + (SFINAE) error. + +FLINT_UNOP_BUILD_RETTYPE(name, rettype, T) + + Obtain the resulting type (i.e. expression template) of invoking + \code{name} with argument type \code{T}, assuming the nominal return type + is \code{rettype}. This version is sometimes necessary to break cyclic + dependencies. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + flintxx/flint\_classes.h ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +FLINTXX_DEFINE_BASICS(name) + + Add standard constructors (forwarded to \code{data_t}, and implicit ones + for reference types). Here \code{name} is the name of the expression + template class. + +FLINTXX_DEFINE_C_REF(name, ctype, accessname) + + Enable the reference types scheme. + +FLINTXX_DEFINE_FORWARD_STATIC(funcname) + + Add a statically forwarded constructor (similar to \code{make} for + reference types) which invokes a static constructor of the same name of + \code{data_t}. + +FLINTXX_DEFINE_MEMBER_UNOP_RTYPE(rettype, name) + + Add a no-argument member function which applies self to the lazy function + \code{name}, where \code{name} has nominal return type \code{rettype}. + (The return type has to be specified to break circular dependencies.) + +FLINTXX_DEFINE_MEMBER_UNOP(name) + + Same as above, but where the nominal return type is the (evaluated type of + the) current expression template class. + +FLINTXX_DEFINE_MEMBER_BINOP(name) +FLINTXX_DEFINE_MEMBER_3OP(name) +FLINTXX_DEFINE_MEMBER_4OP(name) +FLINTXX_DEFINE_MEMBER_5OP(name) + + Add a member function which \code{n-1} arguments, the result of which is to + invoke \code{name} on self and the arguments (in that order). + +FLINTXX_COND_S(Base) +FLINTXX_COND_T(Base) + + Expands to a condition (which can be passed to e.g. + \code{FLINT_DEFINE_CBINARY_EXPR_COND2}) appropriate for testing a + source/target of type \code{Base}. + +FLINTXX_DEFINE_TO_STR(Base, eval) + + Add a \code{to_string} rule which works well with the \code{*_get_str} + functions in FLINT. + +FLINTXX_DEFINE_SWAP(Base, eval) + + Add a swap rule. + +FLINTXX_DEFINE_CONVERSION_TMP(totype, Base, eval) + + Define a conversion rule from \code{Base} to \code{totype}, which + default-constructs a temporary object \code{to} of type \code{totype}, + then executes \code{eval}, and then returns \code{to}. + +FLINTXX_DEFINE_CMP(Base, eval) +FLINTXX_DEFINE_EQUALS(Base, eval) + + Define a cmp/equality rule. + +FLINTXX_DEFINE_ASSIGN_STR(Base, eval) + + Define a string assignment rule (used by many polynomial classes). + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + flintxx/matrix.h ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +FLINTXX_DEFINE_MATRIX_METHODS(Traits) + + Inside a matrix expression template class definition, given the unified + access traits \code{Traits} appropriate for this class, define the standard + methods \code{rows, cols, create_temporary}. + +FLINTXX_DEFINE_TEMPORARY_RULES(Matrix) + + Given a matrix expression template class \code{Matrix}, define appropriate + temporary instantiation rule, disable temporary merging, etc. + +******************************************************************************* + + Helper functions + +******************************************************************************* + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + flintxx/flint\_exception.h ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +void execution_check(bool worked, const std::string& where, + const std::string& context) + + If \code{worked} is true, do nothing. Else raise a \code{flint_exception} + with message \code{context + " computation failed: " + where}. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + permxx.h ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +slong* maybe_perm_data(permxx* p) + + Return \code{0} if \code{p == 0}, and else the underlying data. + It is helpful to use this together with \code{traits::is_maybe_perm} as + condition. diff --git a/external/flint-2.4.3/flintxx/dummy.c b/external/flint-2.4.3/flintxx/dummy.c new file mode 100644 index 0000000..db37770 --- /dev/null +++ b/external/flint-2.4.3/flintxx/dummy.c @@ -0,0 +1,2 @@ +/* Just here to please the build system. */ +void __do_nothing() {/* stop warning */} diff --git a/external/flint-2.4.3/flintxx/evaluation_tools.h b/external/flint-2.4.3/flintxx/evaluation_tools.h new file mode 100644 index 0000000..2169d42 --- /dev/null +++ b/external/flint-2.4.3/flintxx/evaluation_tools.h @@ -0,0 +1,1114 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +// This file contains helpers for evaluating expression templates. + +#ifndef CXX_EVALUATION_TOOLS_H +#define CXX_EVALUATION_TOOLS_H + +#include + +#include "../flint.h" // FLINT_MAX and FLINT_MIN + +#include "expression_traits.h" +#include "mp.h" +#include "rules.h" +#include "tuple.h" + +namespace flint { +namespace mp { +// Find the highest-priority implemented evaluation rule, if any. +// TODO move to tools? +template +struct find_evaluation +{ +private: + typedef rules::evaluation r2; + typedef rules::evaluation r1; + typedef rules::evaluation r0; + + typedef traits::is_implemented i2; + typedef traits::is_implemented i1; + typedef traits::is_implemented i0; + +public: + typedef typename mp::select, r2, + mp::and_v, r1, + mp::and_v, r0 + >::type type; +}; +} // mp + +namespace tools { +namespace tdetail { +template +struct cmp_invert +{ + static int get(const T& t, const U& u) + { + return -rules::cmp::get(u, t); + } +}; +} + +// A version of the cmp rule which tries both argument orders +template +struct symmetric_cmp + : mp::if_ >, + rules::cmp, + typename mp::if_ >, + tdetail::cmp_invert, + rules::UNIMPLEMENTED + >::type + >::type { }; + +// A version of equals which uses cmp if possible +namespace tdetail { +template +struct equals_using_cmp_ : rules::UNIMPLEMENTED { }; +template +struct equals_using_cmp_ > >::type> +{ + static bool get(const T& t, const U& u) + { + return tools::symmetric_cmp::get(t, u) == 0; + } +}; +} // tdetail +template +struct equals_using_cmp + : mp::if_ >, + rules::equals, tdetail::equals_using_cmp_ >::type { }; + +// Automatic printing if to_string is implemented +namespace tdetail { +template +struct print_using_str_ : rules::UNIMPLEMENTED { }; +template +struct print_using_str_ > >::type> +{ + static void doit(const T& v, std::ostream& o) + { + int base = 10; + std::ios_base::fmtflags ff = o.flags(); + if(ff & o.hex) + base = 16; + if(ff & o.oct) + base = 8; + o << v.to_string(base); + } +}; +} // tdetail +template +struct print_using_str + : mp::if_ >, + rules::print, tdetail::print_using_str_ >::type { }; + +// Finding a subexpression of precsribed type +namespace tdetail { +template +struct find_subexpr_helper2; + +template +struct find_subexpr_helper +{ + typedef find_subexpr_helper2 fsh; + typedef typename fsh::rtype rtype; + static const bool val = fsh::val; + static rtype get(const Expr& e) {return fsh::get(e._data());} +}; + +template +struct find_subexpr_helper >::type> +{ + static const bool val = true; + typedef const Expr& rtype; + static rtype get(rtype t) {return t;} +}; + +template +struct find_subexpr_helper, + mp::not_ > > >::type> +{ + static const bool val = false; + typedef void rtype; +}; + +template +struct find_subexpr_helper2 +{ + typedef find_subexpr_helper2 fsh; + typedef typename fsh::rtype rtype; + static const bool val = fsh::val; + static rtype get(const Data& d) {return fsh::get(d.tail);} +}; + +template +struct find_subexpr_helper2, + typename mp::enable_if::type> >::type> +{ + static const bool val = true; + typedef typename traits::basetype::type head_t; + typedef find_subexpr_helper fsh; + typedef typename fsh::rtype rtype; + static rtype get(const tuple& d) {return fsh::get(d.head);} +}; + +template +struct find_subexpr_helper2 +{ + static const bool val = false; + typedef void rtype; +}; +} // tdetail + +// A predicate which applies if the argument type equals T. +template +struct equal_types_pred +{ + template struct type : mp::equal_types { }; +}; + +// Given an expression template Expr, traverse the tree of data arguments +// until an argument matching the predicate Pred is found. Here pred must have +// a member template "type" performing the boolean computation. +// See equal_types_pred for an example. +// If there is no matching subexpression, a compile time error will be +// encountered. +// The current implementation performs depth-first search. +template +inline typename tdetail::find_subexpr_helper::rtype +find_subexpr(const Expr& e) +{ + return tdetail::find_subexpr_helper::get(e); +} + +// Find a subexpression of type T. +template +inline const T& find_subexpr_T(const Expr& e) +{ + return find_subexpr >(e); +} + +// Boolean computation to determine if find_subexpr above will work. +template +struct has_subexpr + : tdetail::find_subexpr_helper { }; + + +// A helper to invoke htuples::fill with instantiate_temporaries +namespace tdetail { +template +struct fill_tmps_helper +{ + const Expr& expr; + fill_tmps_helper(const Expr& e) : expr(e) {}; + + template + T create() const {return rules::instantiate_temporaries::get(expr);} +}; +} // tdetail +template +tdetail::fill_tmps_helper temporaries_filler(const Expr& e) +{ + return tdetail::fill_tmps_helper(e); +} + + +// A helper to "evaluate" a single term, independend of whether or not it is +// actually an expression template +template +struct evaluation_helper +{ + typedef typename traits::basetype::type type; + typedef typename traits::forwarding::type ftype; + typedef ftype etype; + static ftype get(const type& t) {return t;} + + typedef empty_tuple temporaries_t; +}; + +template +struct evaluation_helper >::type> +{ + typedef typename T::evaluated_t type; + typedef const typename T::evaluated_t& ftype; + typedef type etype; + static type get(const T& t) {return t.evaluate();} + + typedef typename T::ev_traits_t::temp_rule_t::temporaries_t temporaries_t; +}; + + +/////////////////////////////////////////////////////////////////////////// +// Helper to evaluate n terms +/////////////////////////////////////////////////////////////////////////// +// The template argument is an arbitrary argument tuple +template +struct evaluate_n; + +// Count the number of non-immediate terms in arguments +template +struct count_nonimm +{ + static const unsigned val = + traits::is_lazy_expr::val + + count_nonimm::val; +}; +template<> +struct count_nonimm +{ + static const unsigned val = 0; +}; + +template +struct evaluated_args_tuple +{ + typedef typename tools::evaluation_helper::ftype evt; + typedef typename evaluated_args_tuple::type tail_t; + typedef tuple type; +}; +template<> +struct evaluated_args_tuple +{ + typedef empty_tuple type; +}; + +namespace tdetail { +// Unoptimized evaluation (in order) +// The constructor sets up any local temporaries (coming from non-merging). +// Then init does the actual computation. Note that init chains at the end +// (in contrast to construction), so we do evaluate in order. +template +struct evaluate_n_unopt +{ + // case where head is immediate + typedef evaluate_n_unopt next_t; + + typedef typename next_t::temporaries_t temporaries_t; + typedef typename Args::head_t headr_t; + + next_t next; + headr_t res; + + headr_t gethead() const + { + return res; + } + + void init(const Args& args, temporaries_t temps) + { + next.init(args.tail, temps); + } + evaluate_n_unopt(const Args& args) + : next(args.tail), res(args.head) {} +}; +template<> +struct evaluate_n_unopt +{ + // basecase + typedef empty_tuple temporaries_t; + + void init(empty_tuple, empty_tuple) {} + evaluate_n_unopt(empty_tuple) {} +}; +template +struct evaluate_n_unopt, + mp::not_ > > >::type> +{ + // Case with non-merging lazy head + typedef evaluate_n_unopt next_t; + typedef typename Args::head_t expr_t; + typedef typename expr_t::ev_traits_t::temp_rule_t rule_t; + typedef typename rule_t::return_t tmp_t; + typedef mp::merge_tuple merger; + + typedef typename merger::type temporaries_t; + typedef typename traits::forwarding::type headr_t; + + next_t next; + tmp_t tmp; + + headr_t gethead() const + { + return tmp; + } + + evaluate_n_unopt(const Args& args) + : next(args.tail), tmp( + rules::instantiate_temporaries::get(args.head)) + {} + void init(const Args& args, temporaries_t temps) + { + rule_t::doit(args.head._data(), merger::get_first(temps), &tmp); + next.init(args.tail, merger::get_second(temps)); + } +}; +template +struct evaluate_n_unopt, + traits::use_temporary_merging< + typename Args::head_t::evaluated_t> > >::type> +{ + // Case with merging lazy head + typedef evaluate_n_unopt next_t; + typedef typename Args::head_t expr_t; + typedef typename expr_t::ev_traits_t::temp_rule_t rule_t; + typedef typename rule_t::return_t tmp_t; + typedef mp::merge_tuple > merger; + + typedef typename merger::type temporaries_t; + typedef typename traits::forwarding::type headr_t; + + next_t next; + tmp_t* tmp; + + headr_t gethead() const + { + return *tmp; + } + + evaluate_n_unopt(const Args& args) + : next(args.tail) {} + void init(const Args& args, temporaries_t temps) + { + tmp = merger::get_second(temps).head; + rule_t::doit(args.head._data(), merger::get_first(temps), tmp); + next.init(args.tail, merger::get_second(temps).tail); + } +}; + +template +struct unopt_get +{ + typedef unopt_get getn; + typedef typename getn::type type; + static type get(const evaluate_n_unopt& e) {return getn::get(e.next);} +}; +template +struct unopt_get +{ + typedef evaluate_n_unopt evalt; + typedef typename evalt::headr_t type; + static type get(const evalt& e) {return e.gethead();} +}; + +template +struct unopt_gettuple +{ + typedef unopt_gettuple next; + typedef evaluate_n_unopt eval_t; + + typedef tuple type; + static type get(const eval_t& e) + { + return type(e.gethead(), next::get(e.next)); + } +}; +template<> +struct unopt_gettuple +{ + typedef empty_tuple type; + template + static type get(const T&) {return empty_tuple();} +}; + +// Optimized case with precisely two non-immediates +template +struct evaluate_n_2_analyze +{ + typedef evaluate_n_2_analyze next; + static const unsigned first = next::first + 1; + static const unsigned second = next::second + 1; +}; +template +struct evaluate_n_2_analyze >::type> +{ + typedef evaluate_n_2_analyze next; + static const unsigned first = 0; + static const unsigned second = next::second + 1; +}; +template +struct evaluate_n_2_analyze >::type> +{ + static const unsigned first = 0; + static const unsigned second = 0; +}; + +template +struct evaluate_2; +// Case where neither is immediate, no merging +template +struct evaluate_2, + traits::is_lazy_expr, + mp::not_ >, + mp::not_ > + > >::type> +{ +private: + typedef typename Expr1::ev_traits_t::temp_rule_t rule1_t; + typedef typename Expr2::ev_traits_t::temp_rule_t rule2_t; + +public: + typedef typename rule1_t::return_t return1_t; + typedef typename rule2_t::return_t return2_t; + +private: + typedef typename rule1_t::temporaries_t temporaries1_t; + typedef typename rule2_t::temporaries_t temporaries2_t; + + typedef mp::merge_tuple merger; + return1_t tmp1; + return2_t tmp2; + +public: + typedef typename merger::type temporaries_t; + + evaluate_2(temporaries_t temps, const Expr1& e1, const Expr2& e2) + : tmp1(rules::instantiate_temporaries::get(e1)), + tmp2(rules::instantiate_temporaries::get(e2)) + { + rule1_t::doit(e1._data(), merger::get_first(temps), &tmp1); + rule2_t::doit(e2._data(), merger::get_second(temps), &tmp2); + } + + const return1_t& get1() const {return tmp1;} + const return2_t& get2() const {return tmp2;} +}; + +// Case where neither is immediate, first has merging, second does not +template +struct evaluate_2, + traits::is_lazy_expr, + traits::use_temporary_merging, + mp::not_ > + > >::type> +{ +private: + typedef typename Expr1::ev_traits_t::temp_rule_t rule1_t; + typedef typename Expr2::ev_traits_t::temp_rule_t rule2_t; + +public: + typedef typename rule1_t::return_t return1_t; + typedef typename rule2_t::return_t return2_t; + +private: + typedef typename rule1_t::temporaries_t temporaries1_t; + typedef typename rule2_t::temporaries_t temporaries2_t; + + typedef mp::merge_tuple::type, + temporaries1_t> merger1; + typedef mp::merge_tuple merger2; + return2_t tmp2; + return1_t* ret1; + +public: + typedef typename merger2::type temporaries_t; + + evaluate_2(temporaries_t temps, const Expr1& e1, const Expr2& e2) + : tmp2(rules::instantiate_temporaries::get(e2)) + { + rule2_t::doit(e2._data(), merger2::get_second(temps), &tmp2); + ret1 = merger1::get_first(merger2::get_first(temps)).head; + rule1_t::doit(e1._data(), + merger1::get_second(merger2::get_first(temps)), ret1); + } + + const return1_t& get1() const {return *ret1;} + const return2_t& get2() const {return tmp2;} +}; + +// Case where neither is immediate, second has merging, first does not +template +struct evaluate_2, + traits::is_lazy_expr, + traits::use_temporary_merging, + mp::not_ > + > >::type> +{ + // XXX this is copy-paste from above case where right is immediate +private: + typedef evaluate_2 ev2_t; + ev2_t ev2; + +public: + typedef typename ev2_t::return1_t return2_t; + typedef typename ev2_t::return2_t return1_t; + typedef typename ev2_t::temporaries_t temporaries_t; + + evaluate_2(temporaries_t temps, const Expr1& e1, const Expr2& e2) + : ev2(temps, e2, e1) {}; + const return1_t& get1() const {return ev2.get2();} + const return2_t& get2() const {return ev2.get1();} +}; + +// Case where neither is immediate, all merging +template +struct evaluate_2, + traits::is_lazy_expr, + traits::use_temporary_merging, + traits::use_temporary_merging > >::type> +{ +private: + typedef typename Expr1::ev_traits_t::temp_rule_t rule1_t; + typedef typename Expr2::ev_traits_t::temp_rule_t rule2_t; + +public: + typedef typename rule1_t::return_t return1_t; + typedef typename rule2_t::return_t return2_t; + +private: + typedef typename rule1_t::temporaries_t temporaries1_t; + typedef typename rule2_t::temporaries_t temporaries2_t; + + template + friend struct evaluate_2; + + // We can either evaluate the Expr1 first and then Expr2, or the other + // way round. We would like to choose the most efficient strategy. + // Since we have no access to other metrics, we compare the number of + // temporaries required (see typedef of doit below). + + struct doit_1 + { + typedef mp::merge_tuple::type, + temporaries2_t> merger2; + typedef mp::merge_tuple, + temporaries1_t> merger1; + typedef typename merger1::type temporaries_t; + + static void init(temporaries_t temps, const Expr1& e1, const Expr2& e2, + return1_t*& ret1, return2_t*& ret2) + { + temporaries1_t temps1 = merger1::get_second(temps); + temporaries2_t temps2 = + merger2::get_second(merger1::get_first(temps).tail); + ret1 = merger1::get_first(temps).head; + ret2 = + merger2::get_first(merger1::get_first(temps).tail).head; + rule1_t::doit(e1._data(), temps1, ret1); + rule2_t::doit(e2._data(), temps2, ret2); + } + }; + + struct doit_2 + { + typedef typename evaluate_2::doit_1 doit_other; + typedef typename doit_other::temporaries_t temporaries_t; + + static void init(temporaries_t temps, const Expr1& e1, const Expr2& e2, + return1_t*& ret1, return2_t*& ret2) + { + doit_other::init(temps, e2, e1, ret2, ret1); + } + }; + + typedef typename mp::if_v< + (doit_1::temporaries_t::len <= doit_2::temporaries_t::len), + doit_1, doit_2>::type doit; + + return1_t* ret1; + return2_t* ret2; + +public: + typedef typename doit::temporaries_t temporaries_t; + + evaluate_2(temporaries_t temps, const Expr1& e1, const Expr2& e2) + { + doit::init(temps, e1, e2, ret1, ret2); + } + + const return1_t& get1() const {return *ret1;} + const return2_t& get2() const {return *ret2;} +}; + +template +struct evaluate_n_2_get +{ + template + static typename mp::tuple_get::type get(const Args& args, + const First&, const Second&) + { + return mp::tuple_get::get(args); + } +}; +template +struct evaluate_n_2_get +{ + template + static const First& get(const Args&, const First& f, const Second&) + { + return f; + } +}; +template +struct evaluate_n_2_get +{ + template + static const Second& get(const Args&, const First&, const Second& s) + { + return s; + } +}; + +template +struct evaluate_n_2_gettuple +{ + template + static Tuple get(const T& t) + { + return Tuple(t.template get(), + evaluate_n_2_gettuple::get(t)); + } +}; +template +struct evaluate_n_2_gettuple +{ + template + static empty_tuple get(const T&) {return empty_tuple();} +}; +} // tdetail + +template +struct evaluate_n +{ + typedef tdetail::evaluate_n_unopt eval_t; + typedef typename eval_t::temporaries_t temporaries_t; + typedef typename tdetail::unopt_gettuple::type evtup_t; + + eval_t eval; + + evaluate_n(const Args& args, temporaries_t temps) + : eval(args) + { + eval.init(args, temps); + } + + template + typename tdetail::unopt_get::type get() const + { + return tdetail::unopt_get::get(eval); + } + + evtup_t gettuple() const + { + return tdetail::unopt_gettuple::get(eval); + } +}; + +template +struct evaluate_n::val == 2>::type> +{ + typedef tdetail::evaluate_n_2_analyze analysis; + static const unsigned first = analysis::first; + static const unsigned second = analysis::second; + + typedef mp::tuple_get getfirst; + typedef mp::tuple_get getsecond; + typedef typename getfirst::type first_t; + typedef typename getsecond::type second_t; + + typedef tdetail::evaluate_2 ev_t; + typedef typename ev_t::temporaries_t temporaries_t; + const Args& args; + ev_t ev; + + evaluate_n(const Args& a, temporaries_t temps) + : args(a), ev(temps, getfirst::get(a), getsecond::get(a)) {} + + typedef typename evaluated_args_tuple::type evtup_t; + + template + typename mp::tuple_get::type get() const + { + return tdetail::evaluate_n_2_get::get( + args, ev.get1(), ev.get2()); + } + + evtup_t gettuple() const + { + return tdetail::evaluate_n_2_gettuple::get(*this); + } +}; + + +/////////////////////////////////////////////////////////////////////////// +// Helper to evaluate three homogeneous terms +/////////////////////////////////////////////////////////////////////////// +// +// Evaluation using ternary operators is actually surprisingly hard. +// Consider e.g. a + b*c. The number of temporaries needed for this depends +// on whether or not b, c are immediates, and on the numbers of temporaries +// needed for each non-immediate expression. +namespace tdetail { +// This struct deals with the difficulties in whether b or c might be +// immediate. +template +struct ternary_hhelper; +// To be specialised below. +} // tdetail + +// The following struct can be used to simplify writing evaluation rules which +// use ternary operations (addmul, submul). +// +// In the situation of a + b*c, the optimization can be applied if +// - the result goes to a temporary (i.e. we can write to it prematurely) +// - a is not an immediate +// - a, b, c are of the same type, and addmul is available for this type +// If so, one needs to evaluate a into the return location and b, c into +// temporaries; after that addmul can be applied. +// +// The ternary_helper facilitates both the checking if we are in the right +// situation and the intermediate evaluations. Instantiate it with +// "T" being your ground type (for which addmul is implemented), "Left" the type +// of a, "Right1" the type of b and "Right2" the type of c. +// Then the member enable::type can be used in SFINAE situations to +// conditionally enable a template only if we are in the addmul situation. +// The member type "temporaries_t" and static member function "doit" can be used +// to evaluate the intermediate terms. +// +// It may sometimes be useful to preclude a certain type of expression for a. +// (E.g. one needs rules for both a + b*c and b*c + a, but then which of these +// applies to b*c + a*d?) To do this, pass the operation you want to exclude in +// "disable_op". +// +// NOTE: in the current implementation, ternary_helper only works with +// *homogeneous* expressions. These are defined to be expressions evaluating to +// type T, which only need temporaries of type T. +// This condition is included in the checks done by the enable member type. +// NOTE: This implementation does not honor use_temporary_merging! +// +template +struct ternary_helper { }; +template +struct ternary_helper, + traits::is_expression::type>, + traits::is_expression::type> > >::type> +{ + typedef typename traits::basetype::type right1_t; + typedef typename traits::basetype::type right2_t; + + typedef typename Left::ev_traits_t::temp_rule_t evl; + typedef tools::evaluation_helper evhr1; + typedef tools::evaluation_helper evhr2; + typedef mp::enable_if, + traits::is_homogeneous_tuple, + traits::is_homogeneous_tuple, + traits::is_homogeneous_tuple< + typename mp::make_tuple< + typename evl::return_t, + typename evhr1::type, + typename evhr2::type>::type, T>, + mp::not_ > + > > enable; + + typedef tdetail::ternary_hhelper::val, + traits::is_immediate::val> inner; + typedef typename inner::temporaries_t temporaries_t; + + // evaluate left into res, rigth1 and right2 to arbitrary location, + // set toright1, toright2 to these locations + static void doit(const Left& left, const right1_t& right1, + const right2_t& right2, temporaries_t temps, T* res, + const T*& toright1, const T*& toright2) + { + inner::doit(left, right1, right2, temps, res, toright1, toright2); + } +}; + +namespace tdetail { +// Case where both are immediate. +template +struct ternary_hhelper +{ + typedef typename Left::ev_traits_t::temp_rule_t evl; + static const unsigned norig = evl::temporaries_t::len; + static const unsigned ntemps = FLINT_MAX(norig, 1); + typedef typename mp::make_homogeneous_tuple::type + temporaries_t; + + static void doit(const Left& left, const right1_t& right1, + const right2_t& right2, temporaries_t temps, T* res, + const T*& toright1, const T*& toright2) + { + evl::doit(left._data(), mp::htuples::extract(temps), res); + toright1 = &right1; + toright2 = &right2; + } +}; + +// If c is immediate but b is not, there are still two subcases. +// Let t1 be the number of temporaries needed to evaluate a, and +// t2 the number for b. If t1 >= t2, then we need to evaluate a first. +// Otherwise b. +// In any case, the number of temporaries is at least two (for the two return +// values), and generically equal to the maximum of t1 and t2. If however +// t1 == t2, then we need an additional temporary. +template +struct ternary_hhelper_1imm; +// Case where t1 >= t2 +template +struct ternary_hhelper_1imm +{ + typedef typename Left::ev_traits_t::temp_rule_t evl; + typedef typename right1_t::ev_traits_t::temp_rule_t evr; + static const unsigned t1 = evl::temporaries_t::len; + static const unsigned t2 = evr::temporaries_t::len; + // t1 >= t2 + + template + static void doit(const Left& left, const right1_t& right1, + Temps temps, T* res, + const T*& toright1) + { + evl::doit(left._data(), mp::htuples::extract(temps), res); + typename Temps::tail_t nores = mp::htuples::removeres(temps, res); + evr::doit(right1._data(), + mp::htuples::extract(nores), nores.head); + toright1 = nores.head; + } +}; +// Case where t1 < t2 +template +struct ternary_hhelper_1imm +{ + typedef typename Left::ev_traits_t::temp_rule_t evl; + typedef typename right1_t::ev_traits_t::temp_rule_t evr; + static const unsigned t1 = evl::temporaries_t::len; + static const unsigned t2 = evr::temporaries_t::len; + // t1 < t2 + + template + static void doit(const Left& left, const right1_t& right1, + Temps temps, T* res, + const T*& toright1) + { + typedef typename Temps::tail_t tail_t; + tail_t nores = mp::htuples::removeres(temps, res); + evr::doit(right1._data(), + mp::htuples::extract(temps), nores.head); + toright1 = nores.head; + evl::doit(left._data(), + mp::htuples::extract(tail_t(res, nores.tail)), res); + } +}; +// Case where c is immediate. +template +struct ternary_hhelper +{ + typedef typename Left::ev_traits_t::temp_rule_t evl; + typedef tools::evaluation_helper evhr1; + static const unsigned t1 = evl::temporaries_t::len; + static const unsigned t2 = evhr1::temporaries_t::len; + static const unsigned ntemps = FLINT_MAX(2, FLINT_MAX(t1, t2) + (t1 == t2)); + + typedef ternary_hhelper_1imm= t2> thh1; + typedef typename mp::make_homogeneous_tuple::type + temporaries_t; + + static void doit(const Left& left, const right1_t& right1, + const right2_t& right2, temporaries_t temps, T* res, + const T*& toright1, const T*& toright2) + { + toright2 = &right2; + thh1::doit(left, right1, temps, res, toright1); + } +}; + +// Case where b is immediate. +template +struct ternary_hhelper +{ + typedef ternary_hhelper thh; + typedef typename thh::temporaries_t temporaries_t; + + static void doit(const Left& left, const right1_t& right1, + const right2_t& right2, temporaries_t temps, T* res, + const T*& toright1, const T*& toright2) + { + thh::doit(left, right2, right1, temps, res, toright2, toright1); + } +}; + +// Case where neither is immediate. +template +struct ternary_hhelper +{ + typedef typename Left::ev_traits_t::temp_rule_t evl; + typedef typename right1_t::ev_traits_t::temp_rule_t evr1; + typedef typename right2_t::ev_traits_t::temp_rule_t evr2; + static const unsigned t1 = evl::temporaries_t::len; + static const unsigned t2 = evr1::temporaries_t::len; + static const unsigned t3 = evr2::temporaries_t::len; + + // m1, m2, m3 is t1, t2, t3 reordered s.t. m1 >= m2 >= m3 + static const unsigned m1 = FLINT_MAX(t1, FLINT_MAX(t2, t3)); + static const unsigned m3 = FLINT_MIN(t1, FLINT_MIN(t2, t3)); + static const unsigned m2 = t1 + t2 + t3 - m1 - m3; + + // The following is obtained by case analysis + static const unsigned ntemps = + (t1 == t2 && t2 == t3) ? FLINT_MAX(3, t1+2) : // all equal + ((m1 > m2 && m2 > m3) ? FLINT_MAX(3, m1) : // all distinct + (m1 == m2 ? FLINT_MAX(m1+1, 3) // first two equal + : FLINT_MAX(m1, FLINT_MAX(m2+2, 3)))); // second two equal + typedef typename mp::make_homogeneous_tuple::type + temporaries_t; + + struct resaccess + { + T* res; + resaccess(T* r) : res(r) {}; + + template + typename Temps::tail_t doit(const Data& d, Temps temps) + { + Eval::doit(d, + mp::htuples::extract(temps), + res); + return mp::htuples::extract(temps); + } + }; + struct toaccess + { + const T*& right; + toaccess(const T*& r) : right(r) {}; + + template + typename Temps::tail_t doit(const Data& d, Temps temps) + { + Eval::doit(d, + mp::htuples::extract(temps), + temps.head); + right = temps.head; + return temps.tail; + } + }; + + struct doit_really + { + template + static void doit(const E1& e1, const E2& e2, + const E3& e3, temporaries_t temps, + A1 a1, A2 a2, A3 a3) + { + typedef typename E1::ev_traits_t::temp_rule_t ev1; + typedef typename E2::ev_traits_t::temp_rule_t ev2; + typedef typename E3::ev_traits_t::temp_rule_t ev3; + a3.template doit(e3._data(), + a2.template doit(e2._data(), + a1.template doit(e1._data(), temps))); + } + }; + struct dont_doit + { + template + static void doit(const E1& e1, const E2& e2, + const E3& e3, temporaries_t temps, + A1 a1, A2 a2, A3 a3) + { + } + }; + + template + static void doit_sort(const E1& e1, const E2& e2, + const E3& e3, temporaries_t temps, + A1 a1, A2 a2, A3 a3) + { + typedef typename E1::ev_traits_t::temp_rule_t ev1; + typedef typename E2::ev_traits_t::temp_rule_t ev2; + typedef typename E3::ev_traits_t::temp_rule_t ev3; + static const unsigned u1 = ev1::temporaries_t::len; + static const unsigned u2 = ev2::temporaries_t::len; + static const unsigned u3 = ev3::temporaries_t::len; + + if(u1 < u2) + return doit_sort(e2, e1, e3, temps, a2, a1, a3); + if(u2 < u3) + return doit_sort(e1, e3, e2, temps, a1, a3, a2); + + // If we reach this point, u1 >= u2 >= u3. + // However, even if this is not the case, the following line (and + // everything it instantiates) still has to compile. + mp::if_v<(u1 >= u2 && u2 >= u3), doit_really, dont_doit>::type::doit( + e1, e2, e3, temps, a1, a2, a3); + } + + static void doit(const Left& left, const right1_t& right1, + const right2_t& right2, temporaries_t temps, T* res, + const T*& toright1, const T*& toright2) + { + // We re-order the temporaries in such a way that res is at the + // very end. When evaluating things in the correct order, it is then + // always correct to take temporaries from the front, and drop them + // from the front. + temporaries_t temps_reordered = mp::concat_tuple< + typename temporaries_t::tail_t, + typename mp::make_tuple::type>::doit( + mp::htuples::removeres(temps, res), + mp::make_tuple::make(res)); + doit_sort(left, right1, right2, temps_reordered, + resaccess(res), toaccess(toright1), toaccess(toright2)); + } +}; +} // tdetail + +// A helper condition for use with FLINT_DEFINE_*_COND? +template +struct is_bool : mp::equal_types { }; +} // tools +} // flint + +#endif diff --git a/external/flint-2.4.3/flintxx/expression.h b/external/flint-2.4.3/flintxx/expression.h new file mode 100644 index 0000000..c8fdf0e --- /dev/null +++ b/external/flint-2.4.3/flintxx/expression.h @@ -0,0 +1,961 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#ifndef CXX_EXPRESSION_H +#define CXX_EXPRESSION_H + +// TODO +// * static asserts + +#include +#include +#include + +#include "evaluation_tools.h" +#include "expression_traits.h" +#include "mp.h" +#include "rules.h" +#include "traits.h" +#include "tuple.h" + +namespace flint { +namespace detail { +// Helper traits used by the "expression" class, in particular the evaluate() +// method. This is the general (i.e. non-immediate) case, +// which requires actual work. +template +struct evaluation_traits +{ + typedef typename Expr::derived_t derived_t; + typedef typename mp::find_evaluation< + Operation, Data, false>::type rule_t; + typedef typename mp::find_evaluation< + Operation, Data, true>::type temp_rule_t; + typedef typename rule_t::return_t evaluation_return_t; + typedef evaluation_return_t evaluated_t; + + static evaluation_return_t evaluate(const derived_t& from) + { + evaluated_t res = + rules::instantiate_temporaries::get(from); + evaluate_into_fresh(res, from); + return res; + } + + template + static void evaluate_into(T& to, const derived_t& from) + { + typedef mp::back_tuple back_t; + typename back_t::type temps_backing = + mp::htuples::fill( + tools::temporaries_filler(from)); + typename rule_t::temporaries_t temps; + back_t::init(temps, temps_backing, 0); + rule_t::doit(from._data(), temps, &to); + } + + static void evaluate_into_fresh(evaluation_return_t& to, const derived_t& from) + { + typedef mp::back_tuple< + typename temp_rule_t::temporaries_t, + evaluation_return_t + > back_t; + typename back_t::type temps_backing = + mp::htuples::fill( + tools::temporaries_filler(from)); + typename temp_rule_t::temporaries_t temps; + back_t::init(temps, temps_backing, &to); + temp_rule_t::doit(from._data(), temps, &to); + } +}; + +// This is the special case of an immediate argument, where "evaluation" is +// at most assignment. +template +struct evaluation_traits +{ + typedef typename Expr::derived_t derived_t; + typedef typename Expr::derived_t evaluated_t; + typedef evaluated_t& evaluation_return_t; + + static evaluated_t& evaluate(derived_t& d) {return d;} + static const evaluated_t& evaluate(const derived_t& d) {return d;} + + template + static void evaluate_into(T& to, const derived_t& from) + { + rules::assignment::doit(to, from); + } + + static void evaluate_into_fresh(derived_t& to, const derived_t& from) + { + evaluate_into(to, from); + } +}; +} // detail + +// The main expression template class. +// +// The argument Derived must have the following form: +// struct derived +// { +// template +// struct type +// { +// typedef XYZ result; +// }; +// }; +// See derived_wrapper below for a common example. +// +// Note that, while Data does not have to be default constructible, +// it *does* need to be copy-constructible, and have a working destructor. +template +class expression +{ +private: + Data data; + +protected: + explicit expression(const Data& d) : data(d) {} + +public: + // internal -- see is_expression implementation. + typedef void IS_EXPRESSION_MARKER; + + typedef detail::evaluation_traits ev_traits_t; + typedef typename Derived::template type::result derived_t; + typedef typename ev_traits_t::evaluated_t evaluated_t; + typedef typename ev_traits_t::evaluation_return_t evaluation_return_t; + typedef Data data_t; + typedef Operation operation_t; + +private: + derived_t& downcast() {return *static_cast(this);} + const derived_t& downcast() const + { + return *static_cast(this); + } + + // Some helpers for initialization, since it is not possible to + // conditionally enable constructors in C++98 + template + static data_t get_data(const T& t, + typename mp::disable_if >::type* = 0) + { + return data_t(t); + } + template + static data_t get_data(T& t, + typename mp::disable_if >::type* = 0) + { + return data_t(t); + } + template + static data_t get_data(const T& t, + typename mp::enable_if >::type* = 0, + typename mp::disable_if< + mp::equal_types >::type* = 0) + { + return data_t(t.evaluate()); + } + template + static data_t get_data(const T& t, + typename mp::enable_if >::type* = 0, + typename mp::enable_if< + mp::equal_types >::type* = 0) + { + return data_t(t.evaluate()._data()); + } + + // Invoke the data copy constructor when appropriate + static data_t get_data(const derived_t& o) + { + return data_t(o._data()); + } + static data_t get_data(derived_t& o) + { + return data_t(o._data()); + } + + // Having the empty constructor here delays its instantiation, and allows + // compiling even if data is *not* default constructible. + static data_t get_data() {return data_t();} + +public: + // forwarded constructors + template + explicit expression(const T& t) + : data(get_data(t)) {} + + template + explicit expression(T& t) + : data(get_data(t)) {} + + template + expression(const T& t, const U& u) + : data(t, u) {} + template + expression(T& t, const U& u) + : data(t, u) {} + + template + expression(const T& t, const U& u, const V& v) + : data(t, u, v) {} + template + expression(T& t, const U& u, const V& v) + : data(t, u, v) {} + template + expression(const T& t, const U& u, const V& v, const W& w) + : data(t, u, v, w) {} + template + expression(T& t, const U& u, const V& v, const W& w) + : data(t, u, v, w) {} + + expression() : data(get_data()) {} + + expression& operator=(const expression& o) + { + this->set(o.downcast()); + return *this; + } + + // See rules::instantiate_temporaries for explanation. + evaluated_t create_temporary() const + { + return evaluated_t(); + } + + Data& _data() {return data;} + const Data& _data() const {return data;} + + void print(std::ostream& o) const + { + tools::print_using_str::doit(evaluate(), o); + } + + std::string to_string(int base = 10) const + { + return rules::to_string::get(evaluate(), base); + } + + template + T to() const + { + return rules::conversion::get(evaluate()); + } + + int print(FILE* f = stdout) const + { + return rules::cprint::doit(f, evaluate()); + } + int print_pretty(FILE* f = stdout) const + { + return rules::print_pretty::doit(f, evaluate()); + } + template + int print_pretty(const T& extra, FILE* f = stdout) const + { + return rules::print_pretty::doit(f, evaluate(), extra); + } + int read(FILE* f = stdin) + { + return rules::read::doit(f, downcast()); + } + + typename traits::make_const::type evaluate() const + { + return ev_traits_t::evaluate(downcast()); + } + evaluation_return_t evaluate() {return ev_traits_t::evaluate(downcast());} + + template + void set(const T& t, + typename mp::enable_if >::type* = 0, + typename mp::enable_if >::type* = 0) + { + T::ev_traits_t::evaluate_into(downcast(), t); + } + template + void set(const T& t, + typename mp::enable_if >::type* = 0, + typename mp::disable_if >::type* = 0) + { + rules::assignment::doit( + downcast(), t.evaluate()); + } + template + void set(const T& t, + typename mp::disable_if >::type* = 0) + { + rules::assignment::doit(downcast(), t); + } + + template + bool equals(const T& t, + typename mp::enable_if >::type* = 0) const + { + return equals(t.evaluate()); + } + template + bool equals(const T& t, + typename mp::disable_if >::type* = 0) const + { + return tools::equals_using_cmp::get(evaluate(), t); + } + + template + struct make_helper + { + typedef typename Derived::template type::result type; + static type make(const NData& ndata) + { + return type(ndata); + } + }; +}; + +// If your expression template is of the form +// template +// class my_expression ... +// then derived_wrapper is a valid argument for Derived in +// the expression class above. +template class Derived> +struct derived_wrapper +{ + template + struct type + { + typedef Derived result; + }; +}; + +// If your expression template is of the form +// template +// class my_expression2 ... +// where Extra is some extra information which should be passed on unchanged, +// then derived_wrapper2 is a valid argument for Derived +// in the expression class above. +template class Derived, class Extra> +struct derived_wrapper2 +{ + template + struct type + { + typedef Derived result; + }; +}; + + +// operators + +namespace detail { +// These traits determine how arguments of an expression template are stored. +// E.g. (e1 + e2) yields a new expression template with a two-argument tuple +// as Data. If e1 is an immediate, then we want to (usually) store it by +// reference, to avoid copies. If not, we can just store by value (since +// copying e1 just copies the references anyway) and avoid indirection. +// (Similarly for e2.) +template +struct storage_traits + : mp::if_< + traits::is_immediate, + typename traits::forwarding::type, + Expr + > { }; +// See tuple.h. +template<> +struct storage_traits {typedef detail::UNUSED type;}; + +template +struct nary_op_helper_step2 +{ + typedef typename ev_t::return_t Expr; + typedef typename Expr::template make_helper make_helper; + typedef typename make_helper::type return_t; +}; +template +struct nary_op_helper_step2 +{ + struct return_t { }; + struct make_helper { }; +}; + +// Helper to determine the return type of an expression, where Data is already +// the correct tuple type. +// The step1/step2 splitting above is necessary to avoid compiler errors in +// case there is not actually any rule. +template +struct nary_op_helper +{ + typedef typename mp::find_evaluation::type ev_t; + typedef nary_op_helper_step2 nohs2; + typedef typename nohs2::return_t return_t; + typedef typename nohs2::make_helper make_helper; + + typedef traits::is_implemented cond; + typedef mp::enable_if enable; +}; + +template +struct nary_op_helper_maker + : nary_op_helper +{ + typedef Maker maker; +}; + +#define FLINTXX_NARY_OP_HELPER_MACRO(arg) typename storage_traits< arg >::type + +// nary_op_helper invokes nary_op_helper with the correct +// tuple type as argument. +template +struct nary_op_helper2 + : nary_op_helper_maker > +{ + typedef nary_op_helper2 noh2; + static typename noh2::return_t make(FLINTXX_MAKE_TUPLE_FUNC_ARGS) + { + return noh2::make_helper::make(noh2::maker::make( + FLINTXX_MAKE_TUPLE_FUNC_ARG_NAMES)); + } +}; + +// Special casing for binary operators. +template +struct binary_op_helper + : nary_op_helper2 +{ }; + +// Special casing for unary operations. +template +struct unary_op_helper : nary_op_helper2 { }; + +// For unary member operators, determining the return type the normal way can +// lead to cyclic dependencies. See FLINTXX_DEFINE_MEMBER_UNOP_RTYPE. +template +struct unary_op_helper_with_rettype +{ + typedef mp::make_tuple::type> maker; + typedef typename Ret::template make_helper< + Op, typename maker::type>::type return_t; +}; + +// Common helper for implementing comparison operators. +template +struct order_op_helper +{ + typedef typename tools::evaluation_helper::type ev1_t; + typedef typename tools::evaluation_helper::type ev2_t; + typedef tools::symmetric_cmp scmp; + + typedef mp::enable_if< + mp::and_< + traits::is_implemented, + mp::or_< + traits::is_expression, + traits::is_expression + > + >, + bool> enable; + + static int get(const Expr1& e1, const Expr2& e2) + { + return scmp::get(tools::evaluation_helper::get(e1), + tools::evaluation_helper::get(e2)); + } +}; +} // detail + +template +inline typename mp::enable_if, std::ostream&>::type +operator<<(std::ostream& o, const Expr& e) +{ + e.print(o); + return o; +} + +template +inline typename mp::enable_if, bool>::type +operator==(const Expr1& e1, const Expr2& e2) +{ + return e1.equals(e2); +} + +template +inline typename mp::enable_if >, + traits::is_expression >, + bool>::type +operator==(const Expr1& e1, const Expr2& e2) +{ + return e2.equals(e1); +} + +template +inline typename mp::enable_if, + traits::is_expression >, + bool>::type +operator!=(const Expr1& e1, const Expr2& e2) +{ + return !(e1 == e2); +} + +template +inline typename detail::order_op_helper::enable::type +operator<(const Expr1& e1, const Expr2& e2) +{ + return detail::order_op_helper::get(e1, e2) < 0; +} + +template +inline typename detail::order_op_helper::enable::type +operator<=(const Expr1& e1, const Expr2& e2) +{ + return detail::order_op_helper::get(e1, e2) <= 0; +} + +template +inline typename detail::order_op_helper::enable::type +operator>(const Expr1& e1, const Expr2& e2) +{ + return detail::order_op_helper::get(e1, e2) > 0; +} + +template +inline typename detail::order_op_helper::enable::type +operator>=(const Expr1& e1, const Expr2& e2) +{ + return detail::order_op_helper::get(e1, e2) >= 0; +} + +template +inline typename detail::binary_op_helper< + Expr1, operations::plus, Expr2>::enable::type +operator+(const Expr1& e1, const Expr2& e2) +{ + return detail::binary_op_helper::make(e1, e2); +} + +template +inline typename detail::binary_op_helper< + Expr1, operations::minus, Expr2>::enable::type +operator-(const Expr1& e1, const Expr2& e2) +{ + return detail::binary_op_helper::make(e1, e2); +} + +template +inline typename detail::binary_op_helper< + Expr1, operations::times, Expr2>::enable::type +operator*(const Expr1& e1, const Expr2& e2) +{ + return detail::binary_op_helper::make(e1, e2); +} + +template +inline typename detail::binary_op_helper< + Expr1, operations::divided_by, Expr2>::enable::type +operator/(const Expr1& e1, const Expr2& e2) +{ + return detail::binary_op_helper::make(e1, e2); +} + +template +inline typename detail::binary_op_helper< + Expr1, operations::modulo, Expr2>::enable::type +operator%(const Expr1& e1, const Expr2& e2) +{ + return detail::binary_op_helper::make(e1, e2); +} + +template +inline typename detail::binary_op_helper< + Expr1, operations::binary_and, Expr2>::enable::type +operator&(const Expr1& e1, const Expr2& e2) +{ + return detail::binary_op_helper::make(e1, e2); +} + +template +inline typename detail::binary_op_helper< + Expr1, operations::binary_or, Expr2>::enable::type +operator|(const Expr1& e1, const Expr2& e2) +{ + return detail::binary_op_helper::make(e1, e2); +} + +template +inline typename detail::binary_op_helper< + Expr1, operations::binary_xor, Expr2>::enable::type +operator^(const Expr1& e1, const Expr2& e2) +{ + return detail::binary_op_helper::make(e1, e2); +} + +template +inline typename detail::binary_op_helper< + Expr1, operations::shift, Expr2>::enable::type +operator<<(const Expr1& e1, const Expr2& e2) +{ + return detail::binary_op_helper::make(e1, e2); +} + +template +inline typename detail::binary_op_helper< + Expr1, operations::shift, Expr2>::enable::type +operator>>(const Expr1& e1, const Expr2& e2) +{ + return detail::binary_op_helper::make(e1, -e2); +} + +template +inline typename detail::unary_op_helper::enable::type +operator-(const Expr& e) +{ + return detail::unary_op_helper::make(e); +} + +template +inline typename detail::unary_op_helper::enable::type +operator~(const Expr& e) +{ + return detail::unary_op_helper::make(e); +} + +template +inline typename mp::enable_if, Expr1&>::type +operator+=(Expr1& e1, const Expr2& e2) +{ + e1.set(e1 + e2); + return e1; +} + +template +inline typename mp::enable_if, Expr1&>::type +operator-=(Expr1& e1, const Expr2& e2) +{ + e1.set(e1 - e2); + return e1; +} + +template +inline typename mp::enable_if, Expr1&>::type +operator*=(Expr1& e1, const Expr2& e2) +{ + e1.set(e1 * e2); + return e1; +} + +template +inline typename mp::enable_if, Expr1&>::type +operator/=(Expr1& e1, const Expr2& e2) +{ + e1.set(e1 / e2); + return e1; +} + +template +inline typename mp::enable_if, Expr1&>::type +operator%=(Expr1& e1, const Expr2& e2) +{ + e1.set(e1 % e2); + return e1; +} + +template +inline typename mp::enable_if, Expr1&>::type +operator|=(Expr1& e1, const Expr2& e2) +{ + e1.set(e1 | e2); + return e1; +} + +template +inline typename mp::enable_if, Expr1&>::type +operator&=(Expr1& e1, const Expr2& e2) +{ + e1.set(e1 & e2); + return e1; +} + +template +inline typename mp::enable_if, Expr1&>::type +operator^=(Expr1& e1, const Expr2& e2) +{ + e1.set(e1 ^ e2); + return e1; +} + +// c-style IO +template +typename mp::enable_if >, int>::type +print(const T& t) +{ + return t.print(); +} +template +typename mp::enable_if >, int>::type +print(FILE* f, const T& t) +{ + return t.print(f); +} +template +typename mp::enable_if >, int>::type +print_pretty(const T& t, const U& extra) +{ + return t.print_pretty(extra); +} +template +typename mp::enable_if >, int>::type +print_pretty(FILE* f, const T& t, const U& extra) +{ + return t.print_pretty(extra, f); +} +template +typename mp::enable_if >, int>::type +print_pretty(const T& t) +{ + return t.print_pretty(); +} +template +typename mp::enable_if >, int>::type +print_pretty(FILE* f, const T& t) +{ + return t.print_pretty(f); +} +template +typename mp::enable_if >, int>::type +read(T& t) +{ + return t.read(); +} +template +typename mp::enable_if >, int>::type +read(FILE* f, T& t) +{ + return t.read(f); +} + +// TODO move to std? +template +inline typename mp::enable_if > >::type swap(Expr1& e1, Expr2& e2) +{ + rules::swap::doit(e1, e2); +} +} + +// TODO remove this? +#include "default_rules.h" + + +//////////////////////////////////////////////////////////////////////// +// HELPER MACROS +//////////////////////////////////////////////////////////////////////// + +// To be called in any namespace + +// Make the binary operation "name" available in current namespace +#define FLINT_DEFINE_BINOP_HERE(name) \ +template \ +inline typename ::flint::detail::binary_op_helper<\ + T1, ::flint::operations::name##_op, T2>::enable::type \ +name(const T1& t1, const T2& t2) \ +{ \ + return ::flint::detail::binary_op_helper< \ + T1, ::flint::operations::name##_op, T2>::make(t1, t2); \ +} + +// Make the unary operation "name" available in current namespace +#define FLINT_DEFINE_UNOP_HERE(name) \ +template \ +inline typename ::flint::detail::unary_op_helper<\ + ::flint::operations::name##_op, T1>::enable::type \ +name(const T1& t1) \ +{ \ + return ::flint::detail::unary_op_helper< ::flint::operations::name##_op, T1>::make(t1); \ +} + +// Make the threeary operation "name" available in current namespace +#define FLINT_DEFINE_THREEARY_HERE(name) \ +template \ +inline typename ::flint::detail::nary_op_helper2<\ + ::flint::operations::name##_op, T1, T2, T3>::enable::type \ +name(const T1& t1, const T2& t2, const T3& t3) \ +{ \ + return ::flint::detail::nary_op_helper2< \ + ::flint::operations::name##_op, T1, T2, T3>::make(t1, t2, t3); \ +} + +// Make the threeary operation "name" available in current namespace, +// but with only two arguments, the second of which is of type type1 and +// defaults to val1, and the third argument always (implicitly) of type type2 +// and value val2. +// The suggested usage of this macro is to first call FLINT_DEFINE_THREEARY_HERE, +// and then call FLINT_DEFINE_THREEARY_HERE_2DEFAULT. The effect will be an +// operation which can be invoked with 1, 2 or 3 arguments. +#define FLINT_DEFINE_THREEARY_HERE_2DEFAULT(name, type1, val1, type2, val2) \ +template \ +inline typename ::flint::detail::nary_op_helper2<\ + ::flint::operations::name##_op, T1, type1, type2 >::enable::type \ +name(const T1& t1, type1 t2 = val1) \ +{ \ + return ::flint::detail::nary_op_helper2< \ + ::flint::operations::name##_op, T1, type1, type2>::make(t1, t2, val2); \ +} + +// Make the fourary operation "name" available in current namespace +#define FLINT_DEFINE_FOURARY_HERE(name) \ +template \ +inline typename ::flint::detail::nary_op_helper2<\ + ::flint::operations::name##_op, T1, T2, T3, T4>::enable::type \ +name(const T1& t1, const T2& t2, const T3& t3, const T4& t4) \ +{ \ + return ::flint::detail::nary_op_helper2< \ + ::flint::operations::name##_op, T1, T2, T3, T4>::make(t1, t2, t3, t4); \ +} + +// Make the fiveary operation "name" available in current namespace +#define FLINT_DEFINE_FIVEARY_HERE(name) \ +template \ +inline typename ::flint::detail::nary_op_helper2<\ + ::flint::operations::name##_op, T1, T2, T3, T4, T5>::enable::type \ +name(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5) \ +{ \ + return ::flint::detail::nary_op_helper2< \ + ::flint::operations::name##_op, T1, T2, T3, T4, T5>::make(t1, t2, t3, t4, t5); \ +} + +// Make the sixary operation "name" available in current namespace +#define FLINT_DEFINE_SIXARY_HERE(name) \ +template \ +inline typename ::flint::detail::nary_op_helper2<\ + ::flint::operations::name##_op, T1, T2, T3, T4, T5, T6>::enable::type \ +name(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, const T6& t6) \ +{ \ + return ::flint::detail::nary_op_helper2< \ + ::flint::operations::name##_op, T1, T2, T3, T4, T5, T6>::make(t1, t2, t3, t4, t5, t6); \ +} + +// Make the sevenary operation "name" available in current namespace +#define FLINT_DEFINE_SEVENARY_HERE(name) \ +template \ +inline typename ::flint::detail::nary_op_helper2<\ + ::flint::operations::name##_op, T1, T2, T3, T4, T5, T6, T7>::enable::type \ +name(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, const T6& t6, const T7& t7) \ +{ \ + return ::flint::detail::nary_op_helper2< \ + ::flint::operations::name##_op, T1, T2, T3, T4, T5, T6, T7>::make(t1, t2, t3, t4, t5, t6, t7); \ +} + +// This set of macros should be called in namespace flint. + +// Introduce a new binary operation called "name" +// NB: because of ADL bugs in g++ <= 4.4, the operation tag is called "name_op", +// whereas the function corresponding to it is just called "name" +#define FLINT_DEFINE_BINOP(name) \ +namespace operations { \ +struct name##_op { }; \ +} \ +FLINT_DEFINE_BINOP_HERE(name) + +// This macro can be used to conditionally enable a function, and is mostly +// used for forwarding. +// A typical usage is +// template +// FLINT_BINOP_ENABLE_RETTYPE(myop, T, U) myop_other(const T& t, const U& u) +// { +// // perhaps something more interesting +// return myop(t, u); +// } +#define FLINT_BINOP_ENABLE_RETTYPE(name, T1, T2) \ + typename detail::binary_op_helper::enable::type + +// Introduce a new unary operation called "name" +#define FLINT_DEFINE_UNOP(name) \ +namespace operations { \ +struct name##_op { }; \ +} \ +FLINT_DEFINE_UNOP_HERE(name) + +#define FLINT_UNOP_ENABLE_RETTYPE(name, T) \ + typename detail::unary_op_helper::return_t + +// See FLINTXX_DEFINE_MEMBER_UNOP_RTYPE +#define FLINT_UNOP_BUILD_RETTYPE(name, rettype, T) \ + typename detail::unary_op_helper_with_rettype::return_t + +#define FLINT_DEFINE_THREEARY(name) \ +namespace operations { \ +struct name##_op { }; \ +} \ +FLINT_DEFINE_THREEARY_HERE(name) + +#define FLINT_THREEARY_ENABLE_RETTYPE(name, T1, T2, T3) \ + typename detail::nary_op_helper2::enable::type + +#define FLINT_DEFINE_FOURARY(name) \ +namespace operations { \ +struct name##_op { }; \ +} \ +FLINT_DEFINE_FOURARY_HERE(name) + +#define FLINT_FOURARY_ENABLE_RETTYPE(name, T1, T2, T3, T4) \ + typename detail::nary_op_helper2::enable::type + +#define FLINT_DEFINE_FIVEARY(name) \ +namespace operations { \ +struct name##_op { }; \ +} \ +FLINT_DEFINE_FIVEARY_HERE(name) + +#define FLINT_FIVEARY_ENABLE_RETTYPE(name, T1, T2, T3, T4, T5) \ + typename detail::nary_op_helper2::enable::type + +#define FLINT_DEFINE_SIXARY(name) \ +namespace operations { \ +struct name##_op { }; \ +} \ +FLINT_DEFINE_SIXARY_HERE(name) + +#define FLINT_DEFINE_SEVENARY(name) \ +namespace operations { \ +struct name##_op { }; \ +} \ +FLINT_DEFINE_SEVENARY_HERE(name) + +#endif diff --git a/external/flint-2.4.3/flintxx/expression_traits.h b/external/flint-2.4.3/flintxx/expression_traits.h new file mode 100644 index 0000000..93c2937 --- /dev/null +++ b/external/flint-2.4.3/flintxx/expression_traits.h @@ -0,0 +1,109 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +// This file contains helpers recognising expression templates + +#ifndef CXX_EXPRESSION_TRAITS_H +#define CXX_EXPRESSION_TRAITS_H + +#include "mp.h" +#include "traits.h" + +namespace flint { +namespace operations { +// These are the operation tags the expression class creates directly. + +// unary operations +struct immediate { }; +struct negate { }; +struct complement { }; + +// binary operations +struct plus { }; +struct minus { }; +struct times { }; +struct divided_by { }; +struct modulo { }; +struct shift { }; // left +struct binary_and { }; +struct binary_or { }; +struct binary_xor { }; +} // operations + +namespace traits { +template +struct is_expression : mp::false_ { }; +template +struct is_expression : mp::true_ { }; + +template +struct _is_immediate_expr + : _is_convertible< + typename basetype::type::operation_t, + operations::immediate + > +{ }; + +// Compute if T is an expression, with operation "immediate" +template +struct is_immediate_expr : _is_immediate_expr { }; +template +struct is_immediate_expr > >::type> + : mp::false_ { }; + +// Compute if T is an immediate expression, *or not an expression at all* +template +struct is_immediate + : mp::or_ >, is_immediate_expr > { }; + +// Compute if T is a non-immediate expression +template +struct is_lazy_expr + : mp::and_, mp::not_ > > { }; + +// Compute if Expr is an expression with prescribed evaluated type "T" +template +struct is_T_expr + : mp::equal_types { }; +template +struct is_T_expr >::type> + : false_ { }; + +// Decide if an expressing yielding From can be directly evaluated into To. +// To be further specialised! +template +struct can_evaluate_into : mp::false_ { }; +template +struct can_evaluate_into : mp::true_ { }; + +// Decide if we should use temporary merging +template +struct use_temporary_merging : mp::true_ { }; +} // traits +} // flint + +#endif diff --git a/external/flint-2.4.3/flintxx/flint_classes.h b/external/flint-2.4.3/flintxx/flint_classes.h new file mode 100644 index 0000000..eac2d1a --- /dev/null +++ b/external/flint-2.4.3/flintxx/flint_classes.h @@ -0,0 +1,760 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +// Helpers to define concrete subclasses of expression. +// Contrary to other parts of this library, they are tailored very +// specifically towards FLINT. + +#include "flint.h" +#include "mp.h" +#include "expression.h" +#include "expression_traits.h" +#include "evaluation_tools.h" +#include "tuple.h" + +#ifndef CXX_FLINT_CLASSES_H +#define CXX_FLINT_CLASSES_H + +// Flint classes distinguish themselves from "ordinary" expression template +// classes by a public typedef IS_FLINT_CLASS (see also FLINTXX_DEFINE_BASICS +// below). Most functionality in this header disables itself when used on a +// non-flint class. + +// For all flint classes, Data of immediates must have typedefs data_ref_t and +// data_srcref_t. + +// The immediates of any flint class come in three "flavours": ordinary, ref +// and srcref. Most of the classes below are used to convert these flavours. +// In order for this to work, the expression template class must contain a +// public typedef c_base_t which is the underlying "basic" C type (so not the +// length one array that is usually used), e.g. fmpz_poly_struct. Conversion to +// reference type then yields expression templates which have Data set to +// ref_data or srcref_data. These implementation work as +// long as all data is stored in c_base_t. If not (e.g. for padic, where there +// is an additional reference to the context), ref_data and srcref_data have to +// be specialised appropriately. + +namespace flint { +namespace flint_classes { +template +struct ref_data +{ + typedef void IS_REF_OR_CREF; + typedef Wrapped wrapped_t; + + typedef Inner* data_ref_t; + typedef const Inner* data_srcref_t; + + Inner* inner; + + ref_data(Wrapped& o) : inner(o._data().inner) {} + + static ref_data make(Inner* f) {return ref_data(f);} + +private: + ref_data(Inner* fp) : inner(fp) {} +}; + +template +struct srcref_data +{ + typedef void IS_REF_OR_CREF; + typedef Wrapped wrapped_t; + + typedef const Inner* data_ref_t; + typedef const Inner* data_srcref_t; + + const Inner* inner; + + srcref_data(const Wrapped& o) : inner(o._data().inner) {} + srcref_data(Ref o) : inner(o._data().inner) {} + + static srcref_data make(const Inner* f) {return srcref_data(f);} + +private: + srcref_data(const Inner* fp) : inner(fp) {} +}; + +// Helper to determine if T is a flint class. +template struct is_flint_class : mp::false_ { }; +template +struct is_flint_class : mp::true_ { }; + +// From a lazy or immediate flint expression, obtain the evaluated +// non-reference type. +// Examples: fmpzxx -> fmpzxx +// fmpzxx_ref -> fmpzxx +// fmpzxx + fmpzxx -> fmpzxx +template +struct to_nonref {typedef typename T::evaluated_t type;}; + +template +struct to_nonref +{ + typedef typename T::data_t::wrapped_t type; +}; + +template +struct c_base_t +{ + typedef typename T::c_base_t type; +}; + +// Given a lazy or non-lazy flint expression, obtain th evaluated reference +// type. +// Examples: fmpzxx -> fmpzxx_ref +// fmpzxx_ref -> fmpzxx_ref +// fmpzxx + fmpzxx -> fmpzxx_ref +template +struct to_ref +{ + typedef typename T::template make_helper::type, typename c_base_t::type> >::type type; +}; +// Similarly for srcref. +template +struct to_srcref +{ + typedef typename T::template make_helper::type, typename to_ref::type, + typename c_base_t::type> >::type type; +}; + +// Compute if Ref if the reference type belonging to compare. +// Examples: fmpzxx_ref, fmpzxx + fmpzxx -> true_ +// fmpzxx_srcref, fmpzxx -> false_ +template +struct is_ref : mp::equal_types::type> { }; + +// Similarly for srcref. +template +struct is_srcref : mp::equal_types::type> { }; + +// Similarly for non-ref. +template +struct is_nonref : mp::equal_types::type > { }; + +// Flint classes allow implicit conversion only in very special situations. +// This template determines when. Currently, it is used exclusively to allow +// implicit conversion to reference types. +template +struct enableimplicit : mp::false_ { }; + +template +struct enableimplicit, is_flint_class + > >::type> + : mp::and_< + traits::is_immediate_expr, + traits::is_immediate_expr, + mp::or_< + mp::and_, is_nonref >, + mp::and_, is_nonref >, + mp::and_, is_ref > + > > { }; + +// Helper template which allows accessing data_(src)ref_t on immediates, +// without causing a compiler error on non-immediates. +// The main use for this are the _fmpz(), _fmpq() etc methods, which only +// work on immediates (but are defined on all instances). +template +struct maybe_data_ref +{ + typedef void data_ref_t; + typedef void data_srcref_t; +}; +template +struct maybe_data_ref >::type> +{ + typedef typename Expr::data_t::data_ref_t data_ref_t; + typedef typename Expr::data_t::data_srcref_t data_srcref_t; +}; + +// If Base is a non-ref flint class, determine if T is a source operand +// (i.e. non-ref, ref or srcref type belong to Base) +// Examples: fmpzxx, fmpzxx_srcref -> true +// fmpzxx, fmpzxx -> true +// fmpzxx, fmpqxx -> false +template +struct is_source : mp::false_ { }; +template +struct is_source, is_flint_class > >::type> + : mp::or_, is_ref, is_srcref > { }; + +// Same with target (i.e. disallow srcref). +template +struct is_target : mp::false_ { }; +template +struct is_target, is_flint_class > >::type> + : mp::or_, is_ref > { }; + +// Predicate version of the above. Useful for FLINT_DEFINE_*_COND. +// See FLINTXX_COND_S and FLINTXX_COND_T +template +struct is_source_base +{ + template struct type : is_source { }; +}; +template +struct is_target_base +{ + template struct type : is_target { }; +}; + +// Helper for implementing x += y*z etc +template +struct ternary_assign_helper +{ + typedef typename mp::make_tuple::type tup_t; + typedef tools::evaluate_n ev2_t; + typedef typename ev2_t::temporaries_t temporaries_t; + typedef mp::back_tuple back_t; + + typename back_t::type backing; + ev2_t ev2; + + static temporaries_t backtemps(typename back_t::type& backing) + { + temporaries_t temps; + back_t::init(temps, backing); + return temps; + } + + ternary_assign_helper(const tup_t& tup) + : backing(mp::htuples::fill( + tools::temporaries_filler( + tup.first()+tup.second() /* XXX */))), + ev2(tup, backtemps(backing)) {} + const T& getleft() {return ev2.template get<0>();} + const T& getright() {return ev2.template get<1>();} +}; + +template +struct enable_ternary_assign + : mp::enable_if::type, T>, + traits::is_T_expr::type, T> >, T&> { }; + +// convenience helper +template struct is_Base : mp::or_< + traits::is_T_expr, + is_source > { }; +} // flint_classes + +namespace traits { +// Enable evaluation into reference types. See can_evaluate_into in +// expression_traits.h. +// XXX why do we need to disable the case where T, U are equal? +// Is not more special? +template +struct can_evaluate_into, + flint_classes::is_flint_class, + mp::not_ > > >::type> + : flint_classes::is_ref { }; +} // traits + + +namespace detail { +template +struct should_enable_extra_ternop : mp::false_ { }; +template +struct should_enable_extra_ternop >::type> + : mp::equal_types::type>::type> { }; +} // detail + +// We add additional overloads for when the LHS is a reference type. The +// problem is that the standard overloads take LHS via reference, and rvalues +// (such as coming from fmpz_polyxx::get_coeff()) +// cannot bind to this. In this case instead objects should be taken by value. +// However, this will make the overload ambiguous. Hence we take by const +// reference and then make an additional copy. +template +inline typename mp::enable_if, Expr1>::type +operator+=(const Expr1& e1, const Expr2& e2) +{ + Expr1(e1).set(e1 + e2); + return e1; +} +template +inline typename mp::enable_if, Expr1>::type +operator-=(const Expr1& e1, const Expr2& e2) +{ + Expr1(e1).set(e1 - e2); + return e1; +} +template +inline typename mp::enable_if, Expr1>::type +operator*=(const Expr1& e1, const Expr2& e2) +{ + Expr1(e1).set(e1 * e2); + return e1; +} +template +inline typename mp::enable_if, Expr1>::type +operator/=(const Expr1& e1, const Expr2& e2) +{ + Expr1(e1).set(e1 / e2); + return e1; +} +template +inline typename mp::enable_if, Expr1>::type +operator%=(const Expr1& e1, const Expr2& e2) +{ + Expr1(e1).set(e1 % e2); + return e1; +} +template +inline typename mp::enable_if, Expr1>::type +operator<<=(const Expr1& e1, const Expr2& e2) +{ + Expr1(e1).set(e1 << e2); + return e1; +} +template +inline typename mp::enable_if, Expr1>::type +operator>>=(const Expr1& e1, const Expr2& e2) +{ + Expr1(e1).set(e1 >> e2); + return e1; +} +} // flint + +// macros that help defining flint classes + +#define FLINTXX_DEFINE_BASICS_NOFLINTCLASS(name) \ +public: \ + typedef typename base_t::evaluated_t evaluated_t; \ + \ + template \ + struct doimplicit \ + : flint_classes::enableimplicit { }; \ + \ + template \ + name& operator=(const T& t) \ + { \ + this->set(t); \ + return *this; \ + } \ + \ +protected: \ + explicit name(const Data& d) : base_t(d) {} \ + \ + template \ + friend class expression; + +// all flint classes should have this +#define FLINTXX_DEFINE_BASICS(name) \ +public: \ + typedef void IS_FLINT_CLASS; \ + FLINTXX_DEFINE_BASICS_NOFLINTCLASS(name) \ + +// all flint classes should have this +#define FLINTXX_DEFINE_CTORS(name) \ +public: \ + name() : base_t() {} \ + template \ + explicit name(const T& t, \ + typename mp::disable_if >::type* = 0) \ + : base_t(t) {} \ + template \ + explicit name(T& t, \ + typename mp::disable_if >::type* = 0) \ + : base_t(t) {} \ + template \ + name(const T& t, \ + typename mp::enable_if >::type* = 0) \ + : base_t(t) {} \ + template \ + name(T& t, \ + typename mp::enable_if >::type* = 0) \ + : base_t(t) {} \ + template \ + name(const T& t, const U& u) : base_t(t, u) {} \ + template \ + name(T& t, const U& u) : base_t(t, u) {} \ + template \ + name(const T& t, const U& u, const V& v) : base_t(t, u, v) {} \ + template \ + name(T& t, const U& u, const V& v) : base_t(t, u, v) {} \ + template \ + name(const T& t, const U& u, const V& v, const W& w) \ + : base_t(t, u, v, w) {} \ + template \ + name(T& t, const U& u, const V& v, const W& w) \ + : base_t(t, u, v, w) {} + +// Enable the flint reference type scheme. This typedefs c_base_t to ctype, +// and adds the data access wrapper (like _fmpz(), _fmpq()) called accessname. +// It also provides reference constructors from C types. +// All flint classes should have this. +#define FLINTXX_DEFINE_C_REF(name, ctype, accessname) \ +public: \ + typedef ctype c_base_t; \ + typedef flint_classes::maybe_data_ref wrapped_traits; \ + typename wrapped_traits::data_ref_t accessname() \ + { \ + return this->_data().inner; \ + } \ + typename wrapped_traits::data_srcref_t accessname() const \ + { \ + return this->_data().inner; \ + } \ + \ + /* These only make sense with the reference types */ \ + template \ + static name make(T& f) \ + { \ + return name(Data::make(f)); \ + } \ + template \ + static name make(const T& f) \ + { \ + return name(Data::make(f)); \ + } \ + template \ + static name make(T& f, const U& u) \ + { \ + return name(Data::make(f, u)); \ + } \ + template \ + static name make(const T& f, const U& u) \ + { \ + return name(Data::make(f, u)); \ + } \ + template \ + static name make(const T& f, const U& u, const V& v) \ + { \ + return name(Data::make(f, u, v)); \ + } + +// Add a statically forwarded constructor called name. (Forwarded to data_t). +#define FLINTXX_DEFINE_FORWARD_STATIC(name) \ + template \ + static typename base_t::derived_t name(const T& f) \ + { \ + return typename base_t::derived_t(Data::name(f)); \ + } \ + template \ + static typename base_t::derived_t name(const T& f, const U& u) \ + { \ + return typename base_t::derived_t(Data::name(f, u)); \ + } + +// Add a static randomisation function. +// XXX this is not really useful because the arguments are often different. +#define FLINTXX_DEFINE_RANDFUNC(CBase, name) \ +static CBase##xx_expression name(frandxx& state, mp_bitcnt_t bits) \ +{ \ + CBase##xx_expression res; \ + CBase##_##name(res._data().inner, state._data(), bits); \ + return res; \ +} + +// Add a forwarded unary operation to the class. Suppose there is a unary +// operation foo() which returns my_typeA, and takes an argument of type +// my_typeB. Now on instances my_typeB, you want to write x.bar() for foo(x). +// Then add FLINTXX_DEFINE_MEMBER_UNOP_RTYPE_(my_typeA, bar, foo) to my_typeB. +// +// XXX due to circular definition problems, this cannot use the usual +// unary_op_helper type approach, and the unop must return the same type +// of expression +#define FLINTXX_DEFINE_MEMBER_UNOP_RTYPE_(rettype, name, funcname) \ +FLINT_UNOP_BUILD_RETTYPE(funcname, rettype, typename base_t::derived_t) \ +name() const \ +{ \ + return flint::funcname(*this); \ +} + +// Convenience version when name==funcname +#define FLINTXX_DEFINE_MEMBER_UNOP_RTYPE(rettype, name) \ + FLINTXX_DEFINE_MEMBER_UNOP_RTYPE_(rettype, name, name) + +// Convenience version when rettype==argtype +#define FLINTXX_DEFINE_MEMBER_UNOP_(name, funcname) \ + FLINTXX_DEFINE_MEMBER_UNOP_RTYPE_(typename base_t::derived_t, name, funcname) + +// Convenience version when rettype==argtype and name==funcname +#define FLINTXX_DEFINE_MEMBER_UNOP(name) FLINTXX_DEFINE_MEMBER_UNOP_(name, name) + +// Add a forwarded binary operation. It is not necessary to specify the return +// type. +#define FLINTXX_DEFINE_MEMBER_BINOP_(name, funcname) \ +template \ +typename detail::binary_op_helper::enable::type \ +name(const T& t) const \ +{ \ + return flint::funcname(*this, t); \ +} + +// Convenience version when funcname==name. +#define FLINTXX_DEFINE_MEMBER_BINOP(name) \ + FLINTXX_DEFINE_MEMBER_BINOP_(name, name) + +#define FLINTXX_DEFINE_MEMBER_3OP_(name, funcname) \ +template \ +typename detail::nary_op_helper2::enable::type \ +name(const T& t, const U& u) const \ +{ \ + return flint::funcname(*this, t, u); \ +} + +#define FLINTXX_DEFINE_MEMBER_3OP(name) \ + FLINTXX_DEFINE_MEMBER_3OP_(name, name) + +#define FLINTXX_DEFINE_MEMBER_4OP_(name, funcname) \ +template \ +typename detail::nary_op_helper2::enable::type \ +name(const T& t, const U& u, const V& v) const \ +{ \ + return flint::funcname(*this, t, u, v); \ +} + +#define FLINTXX_DEFINE_MEMBER_4OP(name) \ + FLINTXX_DEFINE_MEMBER_4OP_(name, name) + +#define FLINTXX_DEFINE_MEMBER_5OP_(name, funcname) \ +template \ +typename detail::nary_op_helper2::enable::type \ +name(const T& t, const U& u, const V& v, const W& w) const \ +{ \ + return flint::funcname(*this, t, u, v, w); \ +} + +#define FLINTXX_DEFINE_MEMBER_5OP(name) \ + FLINTXX_DEFINE_MEMBER_5OP_(name, name) + +// Helper macros for FLINT_DEFINE_*_COND?. +#define FLINTXX_COND_S(Base) flint_classes::is_source_base::template type +#define FLINTXX_COND_T(Base) flint_classes::is_target_base::template type + +// Convenience rules. These all take a Base class as argument, and will +// automatically apply to the related reference types as well. + +// Add a to_string() conversion rule, empolying the common flint idiom where +// the string is allocated by the to_string function. +#define FLINTXX_DEFINE_TO_STR(Base, eval) \ +template \ +struct to_string >::type> \ +{ \ + static std::string get(const T& from, int base) \ + { \ + char* str = eval; \ + std::string res(str); \ + flint_free(str); \ + return res; \ + } \ +}; + +// Add a swap rule. +#define FLINTXX_DEFINE_SWAP(Base, eval) \ +template \ +struct swap, FLINTXX_COND_T(Base) > >::type> \ +{ \ + static void doit(T& e1, U& e2) \ + { \ + eval; \ + } \ +}; + +// Define a conversion rule through a default-constructed temporary object. +#define FLINTXX_DEFINE_CONVERSION_TMP(totype, Base, eval) \ +template \ +struct conversion >::type> \ +{ \ + static totype get(const T& from) \ + { \ + totype to; \ + eval; \ + return to; \ + } \ +}; + +// Define a cmp rule. +#define FLINTXX_DEFINE_CMP(Base, eval) \ +template \ +struct cmp, \ + FLINTXX_COND_S(Base) > >::type> \ +{ \ + static int get(const T& e1, const U& e2) \ + { \ + return eval; \ + } \ +}; + +// Define an equals rule. +#define FLINTXX_DEFINE_EQUALS(Base, eval) \ +template \ +struct equals, FLINTXX_COND_S(Base) > >::type> \ +{ \ + static bool get(const T& e1, const U& e2) \ + { \ + return eval; \ + } \ +}; + +// Define a string assignment rule (c/f many polynomial classes). +#define FLINTXX_DEFINE_ASSIGN_STR(Base, eval) \ +template \ +struct assignment, traits::is_string > >::type> \ +{ \ + static void doit(T& to, const char* from) \ + { \ + eval; \ + } \ +}; + +#define FLINTXX_UNADORNED_MAKETYPES(Base, left, op, right) \ + Base##_expression< op, tuple< left, tuple< right, empty_tuple> > > + +// Optimized evaluation rules using ternary arithmetic (addmul, submul) +// NB: this has to be called in namespace flint, not flint::rules! +#define FLINTXX_DEFINE_TERNARY(Base, addmuleval, submuleval, maketypes) \ +namespace rules { \ +/* a +- b*c */ \ +template \ +struct evaluation, \ + mp::equal_types >, \ + empty_tuple>::type> >, \ + true, 1, \ + typename tools::ternary_helper::enable::type> \ +{ \ + /* Helpful for testing. */ \ + static const unsigned TERNARY_OP_MARKER = 0; \ + \ + typedef Base return_t; \ + typedef tools::ternary_helper th; \ + typedef typename th::temporaries_t temporaries_t; \ + typedef tuple > data_t; \ + static const bool is_add = mp::equal_types::val; \ + \ + static void doit(const data_t& input, temporaries_t temps, return_t* res) \ + { \ + const Base* left = 0; \ + const Base* right = 0; \ + th::doit(input.first(), input.second()._data().first(), \ + input.second()._data().second(), temps, res, right, left); \ + const Base& e1 = *left; \ + const Base& e2 = *right; \ + Base& to = *res; \ + if(is_add) \ + { \ + addmuleval; \ + } \ + else \ + { \ + submuleval; \ + } \ + } \ +}; \ + \ +/* b*c + a */ \ +template \ +struct evaluation >, \ + true, 1, \ + typename tools::ternary_helper::enable::type> \ +{ \ + /* Helpful for testing. */ \ + static const unsigned TERNARY_OP_MARKER = 0; \ + \ + typedef Base return_t; \ + typedef tools::ternary_helper th; \ + typedef typename th::temporaries_t temporaries_t; \ + typedef tuple > data_t; \ + \ + static void doit(const data_t& input, temporaries_t temps, return_t* res) \ + { \ + const Base* left = 0; \ + const Base* right = 0; \ + th::doit(input.second(), input.first()._data().first(), \ + input.first()._data().second(), temps, res, right, left); \ + const Base& e1 = *left; \ + const Base& e2 = *right; \ + Base& to = *res; \ + addmuleval; \ + } \ +}; \ +} /* rules */ \ + \ +/* TODO enable these with references on left hand side(?) */ \ +/* a += b*c */ \ +template \ +inline typename flint_classes::enable_ternary_assign::type \ +operator+=(Base& to, \ + const maketypes(Base, Right1, operations::times, Right2)& other) \ +{ \ + flint_classes::ternary_assign_helper tah( \ + other._data()); \ + const Base& e1 = tah.getleft(); \ + const Base& e2 = tah.getright(); \ + addmuleval; \ + return to; \ +} \ + \ +/* a -= b*c */ \ +template \ +inline typename flint_classes::enable_ternary_assign::type \ +operator-=(Base& to, \ + const maketypes(Base, Right1, operations::times, Right2)& other) \ +{ \ + flint_classes::ternary_assign_helper tah( \ + other._data()); \ + const Base& e1 = tah.getleft(); \ + const Base& e2 = tah.getright(); \ + submuleval; \ + return to; \ +} + +#endif diff --git a/external/flint-2.4.3/flintxx/flint_exception.h b/external/flint-2.4.3/flintxx/flint_exception.h new file mode 100644 index 0000000..99d3707 --- /dev/null +++ b/external/flint-2.4.3/flintxx/flint_exception.h @@ -0,0 +1,55 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#ifndef FLINTXX_FLINT_EXCEPTION_H +#define FLINTXX_FLINT_EXCEPTION_H + +#include +#include + +namespace flint { +// This is the common flintxx exception class, which is raised whenever the +// C++ layer diagnoses a problem. +// Note that the C layer will sometimes abort() with a message (in this case +// no exception is thrown). +class flint_exception + : public std::domain_error // ? +{ +public: + flint_exception(const std::string& what) + : std::domain_error("FLINT: " + what) {} +}; + +// Helper function. If worked is true, does nothing, else raises +// flint_exception. +inline void execution_check(bool worked, const std::string& where, + const std::string& context) +{ + if(!worked) + throw flint_exception(context + " computation failed: " + where); +} +} // flint + +#endif diff --git a/external/flint-2.4.3/flintxx/forwarding.h b/external/flint-2.4.3/flintxx/forwarding.h new file mode 100644 index 0000000..9f883bf --- /dev/null +++ b/external/flint-2.4.3/flintxx/forwarding.h @@ -0,0 +1,234 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#ifndef CXX_FORWARDING_H +#define CXX_FORWARDING_H + +#include +#include + +#include "evaluation_tools.h" +#include "mp.h" +#include "rules.h" +#include "tuple.h" + +// XXX This file is UNFINISHED. It is/was meant to use for extending flintxx by +// compisition, in particular for the NTL wrapper. +// Ask Tom (e_mc_h2@web.de) if you want to use it. + +namespace flint { +namespace forwarding { +// Specialise this to enable forwarding of your class. +template +struct enable : mp::false_ { }; +} // forwarding + +namespace rules { + +template +struct print::underlying_t> > >::type> +{ + static void doit(const T& t, std::ostream& o) + { + typedef typename forwarding::enable et; + print::doit(et::get_underlying(t), o); + } +}; + +template +struct to_string::underlying_t> > >::type> +{ + static std::string get(const T& t, int base) + { + typedef typename forwarding::enable et; + return to_string::get( + et::get_underlying(t), base); + } +}; + +namespace rdetail { +template +struct maybe_forward +{ + typedef T underlying_t; + static const T& get_underlying(const T& t) {return t;} + static T& get_underlying(T& t) {return t;} +}; +template +struct maybe_forward >::type> + : forwarding::enable { }; + +template class Wrapped, class T, class U> +struct fwd_enable2 + : mp::enable_if::underlying_t, + typename maybe_forward::underlying_t, + void> >, + mp::or_< + typename forwarding::enable, + typename forwarding::enable > > > +{ + typedef Wrapped< + typename maybe_forward::underlying_t, + typename maybe_forward::underlying_t, + void> wrapped_t; +}; +} // rdetail + +template +struct assignment::type> +{ + static void doit(T& t, const U& u) + { + rdetail::fwd_enable2::wrapped_t::doit( + rdetail::maybe_forward::get_underlying(t), + rdetail::maybe_forward::get_underlying(u)); + } +}; + +template +struct cmp::type> +{ + static int get(const T& t, const U& u) + { + return rdetail::fwd_enable2::wrapped_t::get( + rdetail::maybe_forward::get_underlying(t), + rdetail::maybe_forward::get_underlying(u)); + } +}; + +template +struct equals::type> +{ + static bool get(const T& t, const U& u) + { + return rdetail::fwd_enable2::wrapped_t::get( + rdetail::maybe_forward::get_underlying(t), + rdetail::maybe_forward::get_underlying(u)); + } +}; + +template +struct conversion::underlying_t> > >::type> +{ + static T get(const U& u) + { + return conversion::underlying_t>::get( + forwarding::enable::get_underlying(u)); + } +}; + +// TODO automatically convert fwd to fwd ? + +// TODO instantiate_temporaries ? + + +namespace rdetail { +template +struct needs_forwarding : mp::false_ { }; + +template +struct needs_forwarding : forwarding::enable { }; + +template +struct needs_forwarding > + : mp::or_, needs_forwarding > { }; + +template +struct translate +{ + typedef Data type; + static type doit(const Data& d) {return d;} +}; + +template +struct translate +{ + typedef maybe_forward fw; + typedef typename fw::underlying_t type; + static type doit(const Wrapped& d) + { + return fw::get_underlying(d); + } +}; + +template +struct translate > +{ + typedef translate htranslator; + typedef translate ttranslator; + typedef tuple type; + static type doit(const tuple& d) + { + return type(htranslator::doit(d.head), ttranslator::doit(d.tail)); + } +}; + +template +struct can_forward +{ + typedef rdetail::translate translator; + typedef typename translator::type translated_t; + typedef typename mp::find_evaluation< + Op, translated_t, result_is_temporary>::type rule_t; + static const bool val = traits::is_implemented::val; +}; + +template +struct can_forward >::type> +{ + static const bool val = false; +}; +} + +template +struct evaluation >::type> +{ + typedef rdetail::translate translator; + typedef typename translator::type translated_t; + typedef typename mp::find_evaluation< + Op, translated_t, result_is_temporary>::type rule_t; + + typedef typename rule_t::temporaries_t temporaries_t; + // TODO repackaging + typedef typename rule_t::return_t return_t; + + static void doit(const Data& input, temporaries_t temps, return_t* output) + { + rule_t::doit(translator::doit(input), temps, output); + } +}; + +} //rules +} // flint + +#endif diff --git a/external/flint-2.4.3/flintxx/frandxx.h b/external/flint-2.4.3/flintxx/frandxx.h new file mode 100644 index 0000000..e2cf706 --- /dev/null +++ b/external/flint-2.4.3/flintxx/frandxx.h @@ -0,0 +1,52 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#ifndef CXX_FRANDXX_H +#define CXX_FRANDXX_H + +#include "../flint.h" + +// This class contains a first-class wrapper of flint_rand_t. +// Note that frandxx is not copyable. + +namespace flint { +class frandxx +{ +private: + flint_rand_t inner; + + // not copyable + frandxx(const frandxx&); + +public: + frandxx() {flint_randinit(inner);} + ~frandxx() {flint_randclear(inner);} + + flint_rand_t& _data() {return inner;} + const flint_rand_t& _data() const {return inner;} +}; +} // flint + +#endif diff --git a/external/flint-2.4.3/flintxx/ltuple.h b/external/flint-2.4.3/flintxx/ltuple.h new file mode 100644 index 0000000..8785589 --- /dev/null +++ b/external/flint-2.4.3/flintxx/ltuple.h @@ -0,0 +1,424 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +// Lazy tuple class (for use in expression templates) +// Note that assignment and comparison are performed elementwise, and types +// need not match (even for equality) as long as the operations can be performed +// on underlying types. + +#ifndef FLINTXX_LTUPLE_H +#define FLINTXX_LTUPLE_H + +#ifndef FLINT_LTUPLE_PLACEHOLDER_NAME +#define FLINT_LTUPLE_PLACEHOLDER_NAME _ +#endif + +#include "expression.h" +#include "tuple.h" + +namespace flint { +// For lazy get, this operation type is created. +namespace operations { +template struct ltuple_get_op { }; +} // operations + +namespace detail { +// Empty marker type +struct INSTANTIATE_FROM_TUPLE { }; + +// Traits for the ltuple expression template get<> operation. If the ltuple is +// an immediate, return references. Else if the return type is an expression +// template, return an expression template. Otherwise, evaluate the ltuple and +// return a copy of the entry. +template +struct ltuple_get_traits +{ + typedef unary_op_helper, Expr> uoh; + typedef typename uoh::return_t type; + typedef type ctype; + static type get(const Expr& e) + { + return uoh::make(e); + } +}; + +template +struct ltuple_get_traits +{ + typedef mp::tuple_get getter; + typedef typename getter::type btype; + typedef typename traits::forwarding::type ctype; + typedef typename traits::reference::type type; + + static type get(Expr& t) + { + return getter::get(t._data().inner); + } + static ctype get(const Expr& t) + { + return getter::get(t._data().inner); + } +}; + +template +struct ltuple_get_traits >, + mp::not_::type> > + > >::type> +{ + typedef mp::tuple_get getter; + typedef typename getter::type type; + typedef type ctype; + + static type get(const Expr& t) + { + return getter::get(t.evaluate()._data().inner); + } +}; + +// Instances of this can be passed to ltuple[ref]() and will be replaced by +// temporaries of the right type before assigment. +struct IGNORED_TYPE { }; +template +struct ltuple_instantiate_ignored_types; +} // detail + +// The ltuple expression template class. Underlying is a tuple type. +template +class ltuple_expression + : public expression, + Operation, Data> +{ +public: + typedef expression, + Operation, Data> base_t; + // internal + typedef void IS_LTUPLE_EXPRESSION; + + typedef Underlying underlying_t; + + ltuple_expression() {} + + template + ltuple_expression(detail::INSTANTIATE_FROM_TUPLE i, const T& t) + : base_t(i, t) {} + + template + ltuple_expression& operator=(const T& t) + { + detail::ltuple_instantiate_ignored_types< + ltuple_expression, T> inst(*this, t); + inst.set(t); + return *this; + } + + template + typename detail::ltuple_get_traits::type get() + { + return detail::ltuple_get_traits< + n, Underlying, Operation, Data, ltuple_expression>::get(*this); + } + template + typename detail::ltuple_get_traits::ctype + get() const + { + return detail::ltuple_get_traits< + n, Underlying, Operation, Data, ltuple_expression>::get(*this); + } + + typename base_t::evaluated_t create_temporary() const + { + return typename base_t::evaluated_t(detail::INSTANTIATE_FROM_TUPLE(), + mp::htuples::fill(tools::temporaries_filler(*this))); + } + +protected: + explicit ltuple_expression(const Data& d) : base_t(d) {} + + template + friend class expression; +}; + +namespace detail { +template +struct ltuple_data +{ + Underlying inner; + + ltuple_data() {} + + template + ltuple_data(INSTANTIATE_FROM_TUPLE, const T& t) : inner(t) {} +}; + +template struct to_ref : traits::reference { }; +template struct to_srcref + : traits::reference::type> { }; + +templateclass Transform, class Tuple> +struct transform_tuple +{ + typedef tuple::type, + typename transform_tuple::type> + type; +}; +templateclass Transform> +struct transform_tuple +{ + typedef empty_tuple type; +}; +} // detail + +// Helper for building ltuple types. +template +struct make_ltuple +{ + typedef ltuple_expression > type; + + typedef typename detail::transform_tuple::type + Underlying_ref; + typedef typename detail::transform_tuple::type + Underlying_srcref; + + typedef ltuple_expression > ref_type; + typedef ltuple_expression > srcref_type; +}; + +namespace traits { +template +struct is_ltuple_expr : mp::false_ { }; +template +struct is_ltuple_expr + : mp::true_ { }; + +// enable evaluation directly into tuple +template +struct can_evaluate_into, + is_ltuple_expr, mp::not_ > + > >::type> : mp::true_ { }; +} // traits + +namespace detail { +template +struct ltuple_instantiate_ignored_types +{ + // degenerate case: To is not a tuple + Ltuple& saved; + ltuple_instantiate_ignored_types(Ltuple& s, const To&) : saved(s) {} + void set(const To& to) {saved.set(to);} +}; +template +struct tuple_instantiate_ignored +{ + typedef tuple_instantiate_ignored next_t; + typedef typename traits::reference::type ref_t; + typedef tuple type; + next_t next; + ref_t ref; + + template + tuple_instantiate_ignored(ToTuple& to, const From& from) + : next(to.tail, from), ref(to.head) {} + + type get() + { + return type(ref, next.get()); + } +}; +template<> +struct tuple_instantiate_ignored +{ + typedef empty_tuple type; + template + tuple_instantiate_ignored(empty_tuple, const F&) {} + empty_tuple get() {return empty_tuple();} +}; +template +struct tuple_instantiate_ignored< + tuple, tuple > +{ + typedef tuple_instantiate_ignored next_t; + typedef typename traits::reference::type ref_t; + typedef tuple type; + next_t next; + From tmp; + + template + tuple_instantiate_ignored(ToTuple& to, const FromExpr& from) + : next(to.tail, from), + tmp(rules::instantiate_temporaries::get(from)) {} + + type get() + { + return type(tmp, next.get()); + } +}; +template +struct ltuple_instantiate_ignored_types >::type> +{ + typedef tuple_instantiate_ignored< + typename Ltuple::underlying_t, typename T::underlying_t> tii_t; + tii_t tii; + ltuple_instantiate_ignored_types(Ltuple& l, const T& t) + : tii(l._data().inner, t) {} + void set(const T& t) + { + typename make_ltuple::type(INSTANTIATE_FROM_TUPLE(), + tii.get()).set(t); + } +}; +} + +namespace rules { +template +struct assignment, + traits::is_ltuple_expr > >::type> +{ + static void doit(Tuple1& to, const Tuple2& from) + { + to._data().inner.set(from._data().inner); + } +}; + +template +struct equals, + traits::is_ltuple_expr > >::type> +{ + static bool get(const Tuple1& to, const Tuple2& from) + { + return to._data().inner.equals_elementwise(from._data().inner); + } +}; + +template +struct unary_expression, Tuple, + typename mp::enable_if, + traits::is_immediate > >::type> +{ + typedef typename mp::tuple_get::type + return_t; + template + static void doit(R& to, const Tuple& from) + { + to = from.template get(); + } +}; +} // rules + +// TODO we would really like variadic templates / lvalue references here + +// Helpers to build ltuples from (references to) arguments. + +template +inline typename make_ltuple::type>::type +ltuple(const T& t) +{ + return typename make_ltuple::type>::type( + detail::INSTANTIATE_FROM_TUPLE(), + mp::make_tuple::make(t)); +} +template +inline typename make_ltuple::type>::type +ltuple(const T& t, const U& u) +{ + return typename make_ltuple::type>::type( + detail::INSTANTIATE_FROM_TUPLE(), + mp::make_tuple::make(t, u)); +} + +template +inline typename make_ltuple::type>::type +ltuple(const T& t, const U& u, const V& v) +{ + return typename make_ltuple::type>::type( + detail::INSTANTIATE_FROM_TUPLE(), + mp::make_tuple::make(t, u, v)); +} +template +inline typename make_ltuple::type>::type +ltuple(const T& t, const U& u, const V& v, const W& w) +{ + return typename make_ltuple::type>::type( + detail::INSTANTIATE_FROM_TUPLE(), + mp::make_tuple::make(t, u, v, w)); +} +template +inline typename make_ltuple::type>::type +ltupleref(T& t) +{ + return typename make_ltuple::type>::type( + detail::INSTANTIATE_FROM_TUPLE(), + mp::make_tuple::make(t)); +} +template +inline typename make_ltuple::type>::type +ltupleref(T& t, U& u) +{ + return typename make_ltuple::type>::type( + detail::INSTANTIATE_FROM_TUPLE(), + mp::make_tuple::make(t, u)); +} +template +inline typename make_ltuple::type>::type +ltupleref(T& t, U& u, V& v) +{ + return typename make_ltuple::type>::type( + detail::INSTANTIATE_FROM_TUPLE(), + mp::make_tuple::make(t, u, v)); +} +template +inline typename make_ltuple::type>::type +ltupleref(T& t, U& u, V& v, W& w) +{ + return typename make_ltuple::type>::type( + detail::INSTANTIATE_FROM_TUPLE(), + mp::make_tuple::make(t, u, v, w)); +} + +// static placeholder +static detail::IGNORED_TYPE FLINT_LTUPLE_PLACEHOLDER_NAME; + +namespace detail { +void remove_compiler_warning( + detail::IGNORED_TYPE* = &FLINT_LTUPLE_PLACEHOLDER_NAME); +} // detail +} // flint + +#endif diff --git a/external/flint-2.4.3/flintxx/matrix.h b/external/flint-2.4.3/flintxx/matrix.h new file mode 100644 index 0000000..97c8d24 --- /dev/null +++ b/external/flint-2.4.3/flintxx/matrix.h @@ -0,0 +1,462 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +// Common code shared among matrix classes + +#ifndef FLINTXX_MATRIX_H +#define FLINTXX_MATRIX_H + +#include "flint_classes.h" +#include "mp.h" +#include "rules.h" +#include "stdmath.h" +#include "ltuple.h" +#include "traits.h" +#include "tuple.h" +#include "../permxx.h" + +namespace flint { +FLINT_DEFINE_BINOP(solve) +FLINT_DEFINE_BINOP(solve_fflu) +FLINT_DEFINE_THREEARY(mat_at) +FLINT_DEFINE_THREEARY(solve_fflu_precomp) +FLINT_DEFINE_UNOP(charpoly) +FLINT_DEFINE_UNOP(det) +FLINT_DEFINE_UNOP(det_fflu) +FLINT_DEFINE_UNOP(det_interpolate) +FLINT_DEFINE_UNOP(nullspace) +FLINT_DEFINE_UNOP(rref) +FLINT_DEFINE_UNOP(trace) +FLINT_DEFINE_UNOP(transpose) + +FLINT_DEFINE_THREEARY(fflu) +FLINT_DEFINE_THREEARY_HERE_2DEFAULT(fflu, permxx*, 0, bool, false) + +template struct matrix_traits : rules::UNIMPLEMENTED { }; +// override this for the non-reference type of your choice +// { +// template static slong rows(const M&); +// template static slong cols(const M&); +// template static ??? at(const M&, slong, slong); +// template static ??? at(M&, slong, slong); +// }; +namespace traits { +template struct is_mat : is_implemented< + matrix_traits::type> > { }; +template struct is_mat >::type> + : mp::false_ { }; +} // traits +namespace matrices { +namespace mdetail { +// Some helper traits used below. +template struct second_is_mat_data : mp::false_ { }; +template +struct second_is_mat_data > > + : traits::is_mat::type> { }; +template struct second_is_mat + : second_is_mat_data { }; + +template +struct both_mat : mp::and_< + traits::is_mat< + typename traits::basetype::type>, + traits::is_mat< + typename traits::basetype::type> + > { }; + +// A more convenient way to obtain the traits associated to a non-immediate +// or non-nonref expression. +template struct immediate_traits + : matrix_traits::type> { }; +} // mdetail + +// For matrix expressions to create temporaries, it is necessary to know the +// dimensions of the result of a computation. This is a generic implementation, +// which assumes that the output dimensions are the same as the dimensions of +// the first argument, which is assumed to be a matrix, except if there are +// precisely two arguments only the second of which is a matrix, in which case +// we assume its the dimension of that. +// This implementation works correctly in many cases, e.g. matrix-addition or +// matrix-scalar multiplication. +template +struct outsize_generic +{ + template + static slong rows(const Mat& m, + typename mp::disable_if >::type* = 0) + { + return m._data().head.rows(); + } + template + static slong cols(const Mat& m, + typename mp::disable_if >::type* = 0) + { + return m._data().head.cols(); + } + + template + static slong rows(const Mat& m, + typename mp::enable_if >::type* = 0) + { + return m._data().tail.head.rows(); + } + template + static slong cols(const Mat& m, + typename mp::enable_if >::type* = 0) + { + return m._data().tail.head.cols(); + } +}; + +// This is the expression template used for computing the dimensions of an +// operation. Without further specialisation, it is just the generic +// implementation described above. +// If you introduce a new operation where the generic implementation is +// incorrect, you must specialise this template. +template +struct outsize : outsize_generic { }; + +// Specialise immediates, where the dimensions are stored with the object. +template<> +struct outsize +{ + template + static slong rows(const Mat& m) + { + return mdetail::immediate_traits::rows(m); + } + template + static slong cols(const Mat& m) + { + return mdetail::immediate_traits::cols(m); + } +}; + +// Specialise multiplication. For matrix-matrix multiplication, use +// the usual formula. For matrix-scalar multiplication, use the generic +// implementation. +template<> +struct outsize +{ + template + static slong rows(const Mat& m, + typename mp::enable_if >::type* = 0) + { + return m._data().head.rows(); + } + template + static slong cols(const Mat& m, + typename mp::enable_if >::type* = 0) + { + return m._data().tail.head.cols(); + } + + template + static slong rows(const Mat& m, + typename mp::disable_if >::type* = 0) + { + return outsize_generic::rows(m); + } + template + static slong cols(const Mat& m, + typename mp::disable_if >::type* = 0) + { + return outsize_generic::cols(m); + } +}; +// Any particular multipication algorithm also has to be specialised. +template<> +struct outsize + : outsize { }; + +// Specialise transpose. +template<> +struct outsize +{ + template + static slong rows(const Mat& m) + { + return m._data().head.cols(); + } + template + static slong cols(const Mat& m) + { + return m._data().head.rows(); + } +}; + +// Specialise nullspace. Note that the nullspace computation functions in +// flint return a matrix the columns of which span the nullspace. Since the +// nullity is not known in advance in general, we have to allocate a square +// matrix. +template<> +struct outsize +{ + template + static slong rows(const Mat& m) + { + return m._data().head.cols(); + } + template + static slong cols(const Mat& m) + { + return m._data().head.cols(); + } +}; + +// This is a bit of a hack. Matrix operations returning a tuple typically +// only return one matrix. We key outsize on the inner operation to find out +// the dimensions. So e.g. solve(A, X).get<1>() (say) will invoke outsize +// with ltuple_get_op<1> as argument, which then invokes outsize with solve_op +// and (A, X) as argument. +template +struct outsize > +{ + template + static slong rows(const Mat& m) + { + return outsize< + typename Mat::data_t::head_t::operation_t>::rows(m._data().head); + } + template + static slong cols(const Mat& m) + { + return outsize< + typename Mat::data_t::head_t::operation_t>::cols(m._data().head); + } +}; + +// This is not actually a matrix expression, but called by the above ... +template<> +struct outsize +{ + template + static slong rows(const Mat& m) + { + return m._data().second().rows(); + } + template + static slong cols(const Mat& m) + { + return m._data().second().cols(); + } +}; +template<> struct outsize + : outsize { }; +template<> +struct outsize +{ + template + static slong rows(const Mat& m) + { + return m._data().tail.second().rows(); + } + template + static slong cols(const Mat& m) + { + return m._data().tail.second().cols(); + } +}; + +namespace mdetail { +struct base_traits +{ + template + static slong rows(const M& m) + { + return matrices::outsize::rows(m); + } + template + static slong cols(const M& m) + { + return matrices::outsize::cols(m); + } +}; +} // mdetail + +// These traits classes are useful for implementing unified coefficient access. +// See fmpz_matxx etc for example usage. +template +struct generic_traits : mdetail::base_traits +{ + template + struct at + { + typedef FLINT_THREEARY_ENABLE_RETTYPE(mat_at, Mat, T, U) + entry_ref_t; + typedef entry_ref_t entry_srcref_t; + + static entry_srcref_t get(const Mat& m, T i, U j) + { + return mat_at(m, i, j); + } + }; +}; + +template +struct generic_traits_srcref : mdetail::base_traits +{ + template + struct at + { + typedef Srcref entry_ref_t; + typedef Srcref entry_srcref_t; + + template + static Srcref get(M m, T i, U j) + { + return mdetail::immediate_traits::at(m, i, j); + } + }; +}; + +template +struct generic_traits_ref : mdetail::base_traits +{ + template + struct at + { + typedef Ref entry_ref_t; + typedef Ref entry_srcref_t; + + template + static Ref get(M m, T i, U j) + { + return mdetail::immediate_traits::at(m, i, j); + } + }; +}; + +template +struct generic_traits_nonref : mdetail::base_traits +{ + template + struct at + { + typedef Ref entry_ref_t; + typedef Srcref entry_srcref_t; + + template + static Ref get(M& m, T i, U j) + { + return mdetail::immediate_traits::at(m, i, j); + } + + template + static Srcref get(const M& m, T i, U j) + { + return mdetail::immediate_traits::at(m, i, j); + } + }; +}; +} // matrices + +// immediate functions +template +inline typename mp::enable_if, slong>::type +rank(const Mat& m) +{ + return m.rank(); +} + +template +inline typename mp::enable_if, slong>::type +find_pivot_any(const Mat& m, slong start, slong end, slong c) +{ + return m.find_pivot_any(start, end, c); +} + +template +inline typename mp::enable_if, slong>::type +find_pivot_partial(const Mat& m, slong start, slong end, slong c) +{ + return m.find_pivot_partial(start, end, c); +} +} // flint + +// Define rows(), cols(), create_temporary() and at() methods. +// For this to work, Traits must behave like the above generic traits. +// Also your matrix class must have a static create_temporary_rowscols function. +// See fmpz_mat for an example. +#define FLINTXX_DEFINE_MATRIX_METHODS(Traits) \ +template \ +typename Traits::template at::entry_ref_t at(T i, U j) \ + {return Traits::template at::get(*this, i, j);} \ +template \ +typename Traits::template at::entry_srcref_t at(T i, U j) const \ + {return Traits::template at::get(*this, i, j);} \ +\ +slong rows() const {return Traits::rows(*this);} \ +slong cols() const {return Traits::cols(*this);} \ +evaluated_t create_temporary() const \ +{ \ + return create_temporary_rowscols(*this, rows(), cols()); \ +} + +// Disable temporary merging. Requires create_temporary_rowscols. +// TODO do we really need the ltuple code everywhere? +#define FLINTXX_DEFINE_TEMPORARY_RULES(Matrix) \ +namespace traits { \ +template<> struct use_temporary_merging : mp::false_ { }; \ +} /* traits */ \ +namespace rules { \ +template \ +struct use_default_temporary_instantiation : mp::false_ { }; \ +template \ +struct instantiate_temporaries >::type> \ +{ \ + /* The only case where this should ever happen is if Expr is an ltuple */ \ + /* TODO static assert this */ \ + static Matrix get(const Expr& e) \ + { \ + typedef typename Expr::operation_t op_t; \ + return Matrix::create_temporary_rowscols(e, \ + matrices::outsize::rows(e), \ + matrices::outsize::cols(e)); \ + } \ +}; \ +template \ +struct instantiate_temporaries >::type> \ +{ \ + static Matrix get(const Expr& e) \ + { \ + return e.create_temporary(); \ + } \ +}; \ +} /* rules */ + +// Add a fflu() member function to the matrix class. +#define FLINTXX_DEFINE_MEMBER_FFLU \ +template typename detail::nary_op_helper2::enable::type \ +fflu(permxx* p, const T& t) const \ +{ \ + return flint::fflu(*this, p, t); \ +} + +#endif diff --git a/external/flint-2.4.3/flintxx/mp.h b/external/flint-2.4.3/flintxx/mp.h new file mode 100644 index 0000000..c54067f --- /dev/null +++ b/external/flint-2.4.3/flintxx/mp.h @@ -0,0 +1,139 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#ifndef CXX_MP_H +#define CXX_MP_H + +namespace flint { +namespace mp { +///////////////////////////////// +// BASIC METAPROGRAMMING HELPERS +///////////////////////////////// +// Most of these helpers *compute* something. In this case, they have a static +// static const member "val" storing the result of the computation. The +// arguments of the computation are template parameters, and are usually *not* +// PODs, but instead themselves types with a static constant "val" member. +// See value_of, true_ and false_ for how to pass in explicit values to your +// computation. + +// Wrap the boolean value "v" into the static const member "val". +template struct value_of { static const bool val = v; }; + +// Boolean inputs for computations. +struct true_ : value_of { }; +struct false_ : value_of { }; + +// Compute if two input *types* (not values!) are equal. +template +struct equal_types : false_ { }; +template +struct equal_types : true_ { }; + +// Compute logical negation of the input value. +template +struct not_ : value_of { }; + +// Compute logical and of the input values. +template +struct and_ : and_ > { }; + +template +struct and_ : value_of { }; + +template +struct and_v : and_ > { }; + +// Compute logical or of the input values. +template +struct or_ : or_ > { }; + +template +struct or_ : value_of { }; + +// Compute V1 or V2, depending on C +template +struct if_v {typedef V1 type;}; +template +struct if_v {typedef V2 type;}; + +template +struct if_ : if_v { }; + +// Choose a value depending on a sequence of conditions. +// This has he same meaning as +// int select(bool c1 = false, bool c2 = false, bool c3 = false) +// { +// if(c1) +// return v1; +// if(c2) +// return v2; +// if(c3) +// return v3; +// return d; +// } +template +struct select : if_::type> { }; + +template +struct select {typedef D type;}; + +// Conditional template enabling helper. (See below for explanation.) +template +struct enable_if_v +{ + typedef U type; + static const int val = 0; +}; +template +struct enable_if_v { }; + +// Conditional template enabling. +// +// These two helpers (enable_if and disable_if) can be used wherever the +// SFINAE rule applies to conditionally enable or disable template +// specialisations. +// +// If T evaluaties to true, then enable_if has a member typedef "type", which +// is the parameter U, and also a static const int member val (of zero). +// If on the other hand T evaluates to false, then enable_if is empty. +// The meaning of T is reversed for disable_if. +// See e.g. [0] or the tests for how to use this. +// +// [0] http://www.boost.org/doc/libs/1_53_0/libs/utility/enable_if.html +// +template +struct enable_if : public enable_if_v { }; +template +struct disable_if : public enable_if, U> { }; + +struct empty { }; +} // mp +} // flint + +#endif diff --git a/external/flint-2.4.3/flintxx/rules.h b/external/flint-2.4.3/flintxx/rules.h new file mode 100644 index 0000000..db35c6f --- /dev/null +++ b/external/flint-2.4.3/flintxx/rules.h @@ -0,0 +1,453 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +// This file contains the definitions of all rules used by the expression class. +// (Some generally useful implementations can be found in default_rules.h.) +// This file also contains some helper traits, metaprogramming tools and macros. + +#ifndef CXX_RULES_H +#define CXX_RULES_H + +#include "mp.h" +#include "traits.h" + +namespace flint { +namespace rules { +struct no_op +{ + template + static void doit(const U&) {} +}; + +struct UNIMPLEMENTED +{ + static const bool unimplemented_marker = true; +}; + +template +struct print : UNIMPLEMENTED { }; + +template +struct to_string : UNIMPLEMENTED { }; +// static std::string get(const T&, int base) + +template +struct assignment : UNIMPLEMENTED { }; + +// C-style cmp. +template +struct cmp : UNIMPLEMENTED { }; + +// Rule for equals. Implemented in terms of cmp by default. +template +struct equals : UNIMPLEMENTED { }; + +// Rule for type conversion. +template +struct conversion +{ + static To get(const From& from) + { + return To(from); + } +}; + +// Rule for c-style printing +template +struct cprint : UNIMPLEMENTED { }; +// static int doit(FILE*, const T&) + +template +struct print_pretty : UNIMPLEMENTED { }; +// static int doit(FILE*, const T&) + +template +struct read : UNIMPLEMENTED { }; +// static int doit(FILE*, T&) + +// Rule for swapping +template +struct swap : UNIMPLEMENTED { }; + +// If result_is_temporary is true, then the result coincides with the +// first temporary (provided these have the same type) +// Priorities 2, 1, 0 can be used to resolve conflicts. +template< + class Op, class Data, + bool result_is_temporary, + unsigned priority, + class Enable = void> +struct evaluation : UNIMPLEMENTED { }; +//{ +// typedef X return_t; +// typedef Y temporaries_t; // a tuple of *pointers* +// static void doit(const T& input, temporaries_t temps, return_t* output); +//}; + +// Instantiate temporaries for evaluation. The default implementation does the +// following: +// - find a subexpression t of e which evaluates to type T +// -- return t.create_temporary() +// - if no such subexpression can be found, return T() +// Additionally, the expression class implements a version of create_temporary +// which just returns T(), so if your class is default constructible, +// everything works automatically. +template +struct instantiate_temporaries; +//{ +// static T get(const Expr& e); +//}; + +// Convenience helpers, instantiate by evaluation if necessary +// (needs default rules) +template +struct binary_expression : UNIMPLEMENTED { }; +// typedef X return_t; +// static void doit(return_t& to, const T&, const U&); +template +struct commutative_binary_expression : UNIMPLEMENTED { }; +// similarly + +template +struct unary_expression : UNIMPLEMENTED { }; +// similarly + +// Rules for more arguments. +template +struct threeary_expression : UNIMPLEMENTED { }; +template +struct fourary_expression : UNIMPLEMENTED { }; +template +struct fiveary_expression : UNIMPLEMENTED { }; +template +struct sixary_expression : UNIMPLEMENTED { }; +template +struct sevenary_expression : UNIMPLEMENTED { }; +} // rules + + +/////////////////////////////////////////////////////////////////////////////////// +// HELPER TRAITS +/////////////////////////////////////////////////////////////////////////////////// + +namespace traits { +// Compute if the rule T is implemented. +template +struct is_implemented : mp::not_<_is_convertible > { }; +} // traits +} // flint + + +/////////////////////////////////////////////////////////////////////////////////// +// HELPER MACROS +/////////////////////////////////////////////////////////////////////////////////// + +// These macros should be called in namespace flint::rules +// In general the easiest way to find out what they do is to read the +// definition directly. + +// Specialise a getter called "name". The getter has one argument called "from" +// of type "fromtype", and "eval" which should yield "totype". +#define FLINT_DEFINE_GET2(name, totype, fromtype1, fromtype2, eval) \ +template<> \ +struct name \ +{ \ + static totype get(const fromtype1& e1, const fromtype2& e2) \ + { \ + return eval; \ + } \ +}; + +#define FLINT_DEFINE_GET(name, totype, fromtype, eval) \ + FLINT_DEFINE_GET2(name, totype, fromtype, fromtype, eval) + +#define FLINT_DEFINE_GET_COND(name, totype, cond, eval) \ +template \ +struct name >::type> \ +{ \ + static totype get(const T& from) \ + { \ + return eval; \ + } \ +}; + +// Specialise a doit rule called "name" +#define FLINT_DEFINE_DOIT(name, totype, fromtype, eval) \ +template<> \ +struct name \ +{ \ + static void doit(totype& to, const fromtype& from) \ + { \ + eval; \ + } \ +}; + +// Specialise a doit rule called "name" which yields totype. It will +// accept any type "T" which satisfies "cond". +#define FLINT_DEFINE_DOIT_COND(name, totype, cond, eval) \ +template \ +struct name >::type> \ +{ \ + static void doit(totype& to, const T& from) \ + { \ + eval; \ + } \ +}; + +#define FLINT_DEFINE_DOIT_COND2(name, cond1, cond2, eval) \ +template \ +struct name, cond2 > >::type> \ +{ \ + static void doit(T& to, const U& from) \ + { \ + eval; \ + } \ +}; + +#define FLINT_DEFINE_PRINT_COND_(name, cond, eval) \ +template \ +struct name >::type> \ +{ \ + static int doit(FILE* to, const T& from) \ + { \ + return eval; \ + } \ +}; +#define FLINT_DEFINE_READ_COND_(name, cond, eval) \ +template \ +struct name >::type> \ +{ \ + static int doit(FILE* from, T& to) \ + { \ + return eval; \ + } \ +}; +#define FLINT_DEFINE_PRINT_COND(cond, eval) \ + FLINT_DEFINE_PRINT_COND_(cprint, cond, eval) +#define FLINT_DEFINE_PRINT_PRETTY_COND(cond, eval) \ + FLINT_DEFINE_PRINT_COND_(print_pretty, cond, eval) +#define FLINT_DEFINE_READ_COND(cond, eval) \ + FLINT_DEFINE_READ_COND_(read, cond, eval) +#define FLINT_DEFINE_PRINT_PRETTY_COND_2(cond, extratype, eval) \ +template \ +struct print_pretty >::type> \ +{ \ + static int doit(FILE* to, const T& from, extratype extra) \ + { \ + return eval; \ + } \ +}; + +// Specialise the unary expression rule type->type. +#define FLINT_DEFINE_UNARY_EXPR_(name, rtype, type, eval) \ +template<> \ +struct unary_expression \ +{ \ + typedef rtype return_t; \ + template \ + static void doit(V& to, const type& from) \ + { \ + eval; \ + } \ +}; + +#define FLINT_DEFINE_UNARY_EXPR(name, type, eval) \ + FLINT_DEFINE_UNARY_EXPR_(name, type, type, eval) + +#define FLINT_DEFINE_UNARY_EXPR_COND(name, ret_type, cond, eval) \ +template \ +struct unary_expression >::type> \ +{ \ + typedef ret_type return_t; \ + template \ + static void doit(V& to, const T& from) \ + { \ + eval; \ + } \ +}; + +// Specialise the binary expression rule (type, type) -> type +#define FLINT_DEFINE_BINARY_EXPR2(name, rtype, type1, type2, eval) \ +template<> \ +struct binary_expression \ +{ \ + typedef rtype return_t; \ + template \ + static void doit(V& to, const type1& e1, const type2& e2) \ + { \ + eval; \ + } \ +}; + +#define FLINT_DEFINE_BINARY_EXPR(name, type, eval) \ + FLINT_DEFINE_BINARY_EXPR2(name, type, type, type, eval) + +// Specialise the commutative binary expression rule (type, type) -> type +#define FLINT_DEFINE_CBINARY_EXPR(name, type, eval) \ +template<> \ +struct commutative_binary_expression \ +{ \ + typedef type return_t; \ + template \ + static void doit(V& to, const type& e1, const type& e2) \ + { \ + eval; \ + } \ +}; + +// Specialise the commutative binary expression rule (Type, T) -> Type, +// where T must satisfy "cond". +#define FLINT_DEFINE_CBINARY_EXPR_COND(name, Type, cond, eval) \ +template \ +struct commutative_binary_expression >::type> \ +{ \ + typedef Type return_t; \ + template \ + static void doit(V& to, const Type& e1, const T& e2) \ + { \ + eval; \ + } \ +}; + +#define FLINT_DEFINE_CBINARY_EXPR_COND2(name, rettype, cond1, cond2, eval) \ +template \ +struct commutative_binary_expression, cond2 > >::type> \ +{ \ + typedef rettype return_t; \ + template \ + static void doit(V& to, const T& e1, const U& e2) \ + { \ + eval; \ + } \ +}; + +// Specialise the (non-commutative) binary expression rule (Type, T) -> Type, +// where T must satisfy "cond". +#define FLINT_DEFINE_BINARY_EXPR_COND(name, Type, cond, eval) \ +template \ +struct binary_expression >::type> \ +{ \ + typedef Type return_t; \ + template \ + static void doit(V& to, const Type& e1, const T& e2) \ + { \ + eval; \ + } \ +}; + +#define FLINT_DEFINE_BINARY_EXPR_COND2(name, rettype, cond1, cond2, eval) \ +template \ +struct binary_expression, cond2 > >::type> \ +{ \ + typedef rettype return_t; \ + template \ + static void doit(V& to, const T& e1, const U& e2) \ + { \ + eval; \ + } \ +}; + +#define FLINT_DEFINE_THREEARY_EXPR_COND3(name, rettype, cond1, cond2, cond3, eval) \ +template \ +struct threeary_expression, cond2 , cond3 > >::type> \ +{ \ + typedef rettype return_t; \ + template \ + static void doit(R& to, const T& e1, const U& e2, const V& e3) \ + { \ + eval; \ + } \ +}; +#define FLINT_DEFINE_THREEARY_EXPR(name, rettype, T1, T2, T3, eval) \ +template<> \ +struct threeary_expression \ +{ \ + typedef rettype return_t; \ + template \ + static void doit(R& to, const T1& e1, const T2& e2, const T3& e3) \ + { \ + eval; \ + } \ +}; + +#define FLINT_DEFINE_FOURARY_EXPR_COND4(name, rettype, cond1, cond2, cond3, cond4, eval) \ +template \ +struct fourary_expression, cond2 , cond3 , cond4 > >::type> \ +{ \ + typedef rettype return_t; \ + template \ + static void doit(R& to, const T& e1, const U& e2, const V& e3, const W& e4) \ + { \ + eval; \ + } \ +}; + +#define FLINT_DEFINE_FIVEARY_EXPR_COND5(name, rettype, cond1, cond2, cond3, cond4, cond5, eval) \ +template \ +struct fiveary_expression, cond2 , cond3 , cond4 , cond5 > >::type> \ +{ \ + typedef rettype return_t; \ + template \ + static void doit(R& to, const T& e1, const U& e2, const V& e3, const W& e4, const X& e5) \ + { \ + eval; \ + } \ +}; + +#define FLINT_DEFINE_SIXARY_EXPR_COND6(name, rettype, cond1, cond2, cond3, cond4, cond5, cond6, eval) \ +template \ +struct sixary_expression, cond2 , cond3 , cond4 , cond5 , cond6 > >::type> \ +{ \ + typedef rettype return_t; \ + template \ + static void doit(R& to, const T& e1, const U& e2, const V& e3, const W& e4, const X& e5, const Y& e6) \ + { \ + eval; \ + } \ +}; + +#define FLINT_DEFINE_SEVENARY_EXPR_COND7(name, rettype, cond1, cond2, cond3, cond4, cond5, cond6, cond7, eval) \ +template \ +struct sevenary_expression, cond2 , cond3 , cond4 , cond5 , cond6, cond7 > >::type> \ +{ \ + typedef rettype return_t; \ + template \ + static void doit(R& to, const T& e1, const U& e2, const V& e3, const W& e4, const X& e5, const Y& e6, const Z& e7) \ + { \ + eval; \ + } \ +}; + +#endif diff --git a/external/flint-2.4.3/flintxx/stdmath.h b/external/flint-2.4.3/flintxx/stdmath.h new file mode 100644 index 0000000..805a418 --- /dev/null +++ b/external/flint-2.4.3/flintxx/stdmath.h @@ -0,0 +1,153 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#ifndef FLINT_CXX_STDMATH_H +#define FLINT_CXX_STDMATH_H + +#include "expression.h" +#include "expression_traits.h" + +// This file defines lazy operations which are used by several different flint +// classes. + +namespace flint { +FLINT_DEFINE_BINOP(pow) +FLINT_DEFINE_BINOP(pow_binexp) +FLINT_DEFINE_BINOP(root) + +FLINT_DEFINE_UNOP(abs) +FLINT_DEFINE_UNOP(exp) +FLINT_DEFINE_UNOP(log) +FLINT_DEFINE_UNOP(sqrt) +FLINT_DEFINE_UNOP(inv) + +FLINT_DEFINE_UNOP(sqr) +FLINT_DEFINE_UNOP(sqr_classical) +FLINT_DEFINE_UNOP(sqr_KS) + +FLINT_DEFINE_UNOP(height) + +FLINT_DEFINE_BINOP(divexact) +FLINT_DEFINE_BINOP(divrem) +FLINT_DEFINE_BINOP(fdiv_2exp) +FLINT_DEFINE_BINOP(mul_2exp) +FLINT_DEFINE_BINOP(mul_classical) +FLINT_DEFINE_BINOP(mul_KS) +FLINT_DEFINE_BINOP(tdiv) +FLINT_DEFINE_BINOP(tdiv_2exp) + +FLINT_DEFINE_THREEARY(mulhigh) +FLINT_DEFINE_THREEARY(mulhigh_classical) +FLINT_DEFINE_THREEARY(mullow) +FLINT_DEFINE_THREEARY(mullow_classical) +FLINT_DEFINE_THREEARY(mullow_KS) + +FLINT_DEFINE_BINOP(smod) // "symmetric" % + +// poly functions +FLINT_DEFINE_BINOP(compose) +FLINT_DEFINE_BINOP(compose_divconquer) +FLINT_DEFINE_BINOP(compose_horner) +FLINT_DEFINE_BINOP(div_basecase) +FLINT_DEFINE_BINOP(div_divconquer) +FLINT_DEFINE_BINOP(divrem_basecase) +FLINT_DEFINE_BINOP(divrem_divconquer) +FLINT_DEFINE_BINOP(div_root) +FLINT_DEFINE_BINOP(evaluate) +FLINT_DEFINE_BINOP(bit_pack) +FLINT_DEFINE_BINOP(shift_left) +FLINT_DEFINE_BINOP(shift_right) +FLINT_DEFINE_BINOP(rem_basecase) +FLINT_DEFINE_BINOP(resultant) +FLINT_DEFINE_BINOP(reverse) +FLINT_DEFINE_BINOP(taylor_shift) +FLINT_DEFINE_BINOP(taylor_shift_horner) + +FLINT_DEFINE_UNOP(content) +FLINT_DEFINE_UNOP(derivative) +FLINT_DEFINE_UNOP(integral) +FLINT_DEFINE_UNOP(make_monic) +FLINT_DEFINE_UNOP(twonorm) +FLINT_DEFINE_UNOP(bound_roots) +FLINT_DEFINE_UNOP(primitive_part) + +FLINT_DEFINE_BINOP(inv_series) +FLINT_DEFINE_BINOP(inv_series_newton) +FLINT_DEFINE_BINOP(revert_series) +FLINT_DEFINE_BINOP(revert_series_lagrange) +FLINT_DEFINE_BINOP(revert_series_lagrange_fast) +FLINT_DEFINE_BINOP(revert_series_newton) + +FLINT_DEFINE_BINOP(sqrt_series) +FLINT_DEFINE_BINOP(invsqrt_series) +FLINT_DEFINE_BINOP(exp_series) +FLINT_DEFINE_BINOP(log_series) +FLINT_DEFINE_BINOP(atan_series) +FLINT_DEFINE_BINOP(atanh_series) +FLINT_DEFINE_BINOP(asin_series) +FLINT_DEFINE_BINOP(asinh_series) +FLINT_DEFINE_BINOP(tan_series) +FLINT_DEFINE_BINOP(sin_series) +FLINT_DEFINE_BINOP(cos_series) +FLINT_DEFINE_BINOP(sinh_series) +FLINT_DEFINE_BINOP(cosh_series) +FLINT_DEFINE_BINOP(tanh_series) + +FLINT_DEFINE_THREEARY(compose_series) +FLINT_DEFINE_THREEARY(compose_series_brent_kung) +FLINT_DEFINE_THREEARY(compose_series_divconquer) +FLINT_DEFINE_THREEARY(compose_series_horner) +FLINT_DEFINE_THREEARY(div_series) +FLINT_DEFINE_THREEARY(pow_trunc) +FLINT_DEFINE_THREEARY(pow_trunc_binexp) + +FLINT_DEFINE_BINOP(compeval) + +// matrix functions in flintxx/matrix.h + +// chinese remaindering +FLINT_DEFINE_FIVEARY(CRT) +FLINT_DEFINE_FOURARY_HERE(CRT) // four argument version +FLINT_DEFINE_THREEARY(multi_CRT) +FLINT_DEFINE_BINOP_HERE(multi_CRT) // two argument version + +// implementation of compeval +namespace rules { +// implementation of compeval +// TODO do at level of "struct evaluation" instead? +template +struct binary_expression >, + traits::is_implemented > + > >::type> + : mp::if_< + traits::is_implemented >, + binary_expression, + binary_expression >::type { }; +} // rules +} // flint + +#endif diff --git a/external/flint-2.4.3/flintxx/test/helpers.h b/external/flint-2.4.3/flintxx/test/helpers.h new file mode 100644 index 0000000..978cc02 --- /dev/null +++ b/external/flint-2.4.3/flintxx/test/helpers.h @@ -0,0 +1,199 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ +#ifndef CXX_TEST_HELPERS_H +#define CXX_TEST_HELPERS_H + +#include +#include +#include +#include +#include + +#include "flintxx/flint_classes.h" + +#ifndef EXIT_STATEMENT +#define EXIT_STATEMENT std::exit(1) +#endif + +#define tassert(expr) do \ +{ \ + if (!(expr)) \ + { \ + std::cout << "FAIL\n" __FILE__ ":" << __LINE__ << ": assertion " #expr " failed\n"; \ + EXIT_STATEMENT; \ + } \ +} while (0) + +// Whether or not the compiler is good enough to compile all of t-mpz.cpp +// in reasonable time and space. +#ifndef HAVE_FAST_COMPILER +#ifdef __clang__ +// clang 3.4 works; let's suppose all work until someone complains +#define HAVE_FAST_COMPILER 1 +#elif defined(__GNUC__) +// gcc 4.7.3 is good enough, supposedly all higher ones are too +#define HAVE_FAST_COMPILER \ + (__GNUC__ >= 4 && \ + ((__GNUC_MINOR__ == 7 && __GNUC_PATCHLEVEL__ >= 3) \ + || (__GNUC_MINOR__ > 7))) +#else +#define HAVE_FAST_COMPILER 0 +#endif +#endif + +// Count the number of temporaries needed to evaluate an expression of type T +template +unsigned count_temporaries(const T&) +{ + return T::ev_traits_t::rule_t::temporaries_t::len; +} + +template +bool typed_equals(const T&, const U&) +{ + return false; +} + +template +bool typed_equals(const T& a, const T& b) +{ + return a == b; +} + +#define _assert_exception(expr, type) do \ +{ \ + bool exception_occurred = false; \ + try \ + { \ + expr; \ + } \ + catch(const type&) \ + { \ + exception_occurred = true; \ + } \ + if(!exception_occurred) \ + { \ + std::cout << "FAIL\n" __FILE__ ":" << __LINE__ \ + << ": expression did not cause an exception: " #expr " \n"; \ + EXIT_STATEMENT; \ + } \ +} while(0) + +#define assert_exception(expr) _assert_exception(expr, flint_exception) + +template +void test_print_read(const T& t) +{ +#if !defined (__WIN32) && !defined (__CYGWIN__) + T tmp(t); tmp.set_zero(); + FILE * f = std::fopen("test_print_read", "w+"); + tassert(f); + print(f, t+t); + std::fflush(f); + std::fclose(f); + + f = std::fopen("test_print_read", "r"); + typename flint::flint_classes::to_ref::type tmpref(tmp); + tassert(read(f, tmpref) > 0); + tassert(t+t == tmp); + tassert(std::remove("test_print_read") == 0); +#endif +} + +template +void test_print_read_pretty(const T& t) +{ +#if !defined (__WIN32) && !defined (__CYGWIN__) + T tmp(t); tmp.set_zero(); + FILE * f = std::fopen("test_print_read", "w+"); + tassert(f); + print_pretty(f, t+t, "x"); + std::fflush(f); + std::fclose(f); + + f = std::fopen("test_print_read", "r"); + char* rvar; + typename flint::flint_classes::to_ref::type tmpref(tmp); + tassert(read_pretty(f, tmpref, &rvar) > 0); + tassert(t+t == tmp); + tassert(std::remove("test_print_read") == 0); + flint_free(rvar); +#endif +} + +inline std::string readfile(const char* name) +{ + std::ifstream t(name); + return std::string(std::istreambuf_iterator(t), + std::istreambuf_iterator()); +} + +template +void tassert_fprint(const T& t, const char* expected) +{ +#if !defined (__WIN32) && !defined (__CYGWIN__) + FILE * f = std::fopen("test_fprint", "w+"); + tassert(f); + print(f, t); + std::fflush(f); + std::fclose(f); + + tassert(readfile("test_fprint") == expected); + tassert(std::remove("test_fprint") == 0); +#endif +} + +template +void tassert_fprint_pretty(const T& t, const U& extra, const char* expected) +{ +#if !defined (__WIN32) && !defined (__CYGWIN__) + FILE * f = std::fopen("test_fprint_pretty", "w+"); + tassert(f); + print_pretty(f, t, extra); + std::fflush(f); + std::fclose(f); + + tassert(readfile("test_fprint_pretty") == expected); + tassert(std::remove("test_fprint_pretty") == 0); +#endif +} + +template +void tassert_fprint_pretty(const T& t, const char* expected) +{ +#if !defined (__WIN32) && !defined (__CYGWIN__) + FILE * f = std::fopen("test_fprint_pretty", "w+"); + tassert(f); + print_pretty(f, t); + std::fflush(f); + std::fclose(f); + + tassert(readfile("test_fprint_pretty") == expected); + tassert(std::remove("test_fprint_pretty") == 0); +#endif +} + + +#endif diff --git a/external/flint-2.4.3/flintxx/test/make-compiler-errors-report.sh b/external/flint-2.4.3/flintxx/test/make-compiler-errors-report.sh new file mode 100755 index 0000000..4a8c373 --- /dev/null +++ b/external/flint-2.4.3/flintxx/test/make-compiler-errors-report.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +CC=$1 +TESTS=$2 +FLAGS="-Wall -pedantic" +TMPF="/tmp/make-report.tmp" + +# make sure we are in the test directory +cd $(dirname $0) + +if [ "$CC" = "" ] ; then + CC=g++ +fi + +if [ "$TESTS" = "" ] ; then + TESTS="TEST_FMPZXX_INIT_WRONG TEST_FMPZXX_INIT_2 TEST_FMPZXX_ASSIGN_WRONG TEST_FMPZXX_CONVERT_WRONG TEST_FMPZXX_REF_INIT_WRONG_1 TEST_FMPZXX_REF_INIT_WRONG_2 TEST_FMPZXX_SRCREF_ASSIGN TEST_FMPZXX_ARITH_WRONG TEST_FMPZXX_ARITH_WRONG_DEEP TEST_FMPZXX_ARITHFUNC_WRONG_NARGS TEST_FMPZXX_ARITHFUNC_WRONG_TYPE TEST_FMPZXX_ARITHFUNC_WRONG_TYPE2 TEST_PADICXX_FORGET_EVAL" +fi + +INCS=$(make -C ../../ print-INCS | grep 'INCS=' | sed 's/^INCS=//') + +for test in $TESTS ; do + echo $test + $CC -E $INCS $FLAGS t-compiler-errors.cc -D$test -DEXTRACTING_SAMPLE \ + | grep -v '^#' | sed 's/^ //' + $CC -c -o /dev/null $INCS $FLAGS t-compiler-errors.cc -D$test 2>$TMPF + echo "Compiler error output is $(cat $TMPF | wc -l) line(s), $(cat $TMPF | wc -c) characters" + echo "------START COMPILER ERROR OUTPUT-------" + cat $TMPF + echo "------END COMPILER ERROR OUTPUT---------" + echo + echo +done diff --git a/external/flint-2.4.3/flintxx/test/myint.h b/external/flint-2.4.3/flintxx/test/myint.h new file mode 100644 index 0000000..4f0236e --- /dev/null +++ b/external/flint-2.4.3/flintxx/test/myint.h @@ -0,0 +1,458 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#ifndef CXX_TEST_MYINT_H +#define CXX_TEST_MYINT_H CXX_TEST_MYINT_H + +#include +#include + +#include "flintxx/expression.h" + +namespace flint { +template +class my_expression + : public expression, Operation, Data> +{ +public: + my_expression() {}; + template + explicit my_expression(const T& t) + : expression, + Operation, Data>(t) {} + + template + my_expression& operator=(const T& t) + { + this->set(t); + return *this; + } + +protected: + explicit my_expression(const Data& d) + : expression, + Operation, Data>(d) {} + + template + friend class flint::expression; +}; + +struct data +{ + int payload; + bool* destroyed; + int extra; + + data() : payload(-1), destroyed(0), extra(42) {} + + ~data() + { + if(destroyed) + *destroyed = true; + } + + data(const data& d) + : payload(d.payload), destroyed(0), extra(1) {} + data(int i) + : payload(i), destroyed(0), extra(2) {} + data(char i) + : payload(i), destroyed(0), extra(3) {} +}; + +typedef my_expression myint; + +template +class my_expression2 + : public expression, Operation, Data> +{ +public: + // cannot have a default constructor + + typedef expression, + Operation, Data> base_t; + typedef typename base_t::evaluated_t evaluated_t; + + template + explicit my_expression2(const T& t) + : base_t(t) {} + + template + explicit my_expression2(T& t) + : base_t(t) {} + + template + my_expression2& operator=(const T& t) + { + this->set(t); + return *this; + } + + evaluated_t create_temporary() const + { + return evaluated_t(WORD(0)); + } + +protected: + explicit my_expression2(const Data& d) + : base_t(d) {} + + template + friend class flint::expression; +}; + +struct longref_data; +struct longcref_data; +struct long_data; +typedef my_expression2 mylong; +typedef my_expression2 mylong_ref; +typedef my_expression2 mylong_cref; + +namespace traits { +template<> struct can_evaluate_into : mp::true_ { }; +} + +struct long_data +{ + slong payload; + // no default constructor + long_data(slong d) : payload(d) {} + long_data(const myint& m) : payload(m._data().payload) {} + + long_data(const mylong_ref&); + long_data(const mylong_cref&); +}; + +struct longref_data +{ + slong& payload; + + longref_data(mylong& l) : payload(l._data().payload) {} +}; + +struct longcref_data +{ + const slong& payload; + + longcref_data(const mylong& l) : payload(l._data().payload) {} + longcref_data(mylong_ref lr) : payload(lr._data().payload) {} +}; + +inline long_data::long_data(const mylong_ref& mlr) : payload(mlr._data().payload) {} +inline long_data::long_data(const mylong_cref& mlr) : payload(mlr._data().payload) {} + +namespace mylong_traits { +template struct is_source : mp::false_ { }; +template struct is_target : mp::false_ { }; + +template<> struct is_source : mp::true_ { }; +template<> struct is_source : mp::true_ { }; +template<> struct is_source : mp::true_ { }; +template<> struct is_target : mp::true_ { }; +template<> struct is_target : mp::true_ { }; +} + + +FLINT_DEFINE_FOURARY(fourary_test) +FLINT_DEFINE_FIVEARY(fiveary_test) +FLINT_DEFINE_SIXARY(sixary_test) +FLINT_DEFINE_SEVENARY(sevenary_test) + +namespace rules { +FLINT_DEFINE_FOURARY_EXPR_COND4(fourary_test_op, myint, + traits::is_integer, traits::is_integer, traits::is_integer, traits::is_integer, + to._data().payload = e1 + e2 + e3 + e4) +FLINT_DEFINE_FIVEARY_EXPR_COND5(fiveary_test_op, myint, + traits::is_integer, traits::is_integer, traits::is_integer, + traits::is_integer, traits::is_integer, + to._data().payload = e1 + e2 + e3 + e4 + e5) +FLINT_DEFINE_SIXARY_EXPR_COND6(sixary_test_op, myint, + traits::is_integer, traits::is_integer, traits::is_integer, + traits::is_integer, traits::is_integer, traits::is_integer, + to._data().payload = e1 + e2 + e3 + e4 + e5 + e6) +FLINT_DEFINE_SEVENARY_EXPR_COND7(sevenary_test_op, myint, + traits::is_integer, traits::is_integer, traits::is_integer, + traits::is_integer, traits::is_integer, traits::is_integer, + traits::is_integer, + to._data().payload = e1 + e2 + e3 + e4 + e5 + e6 + e7) + +template<> +struct print +{ + static void doit(const myint& v, std::ostream& o) + { + o << v._data().payload; + } +}; + +template<> +struct assignment +{ + static void doit(myint& to, const myint& from) + { + to._data().payload = from._data().payload; + to._data().extra = 4; + } +}; + +template<> +struct assignment +{ + static void doit(myint& to, slong from) + { + to._data().payload = from; + to._data().extra = 5; + } +}; + +template<> +struct to_string +{ + static std::string get(const myint& i, int base /* ignored */) + { + std::ostringstream oss; + oss << i; + return oss.str(); + } +}; + +template<> +struct equals +{ + static bool get(const myint& i1, const myint& i2) + { + return i1._data().payload == i2._data().payload; + } +}; + +template<> +struct equals +{ + static bool get(const myint& i1, int i2) + { + return i1._data().payload == i2; + } +}; + +template<> +struct conversion +{ + static int get(const myint& from) + { + return from._data().payload; + } +}; + +template<> +struct swap +{ + static void doit(myint& e1, myint& e2) + { + int tmp; + tmp = e1._data().payload; + e1._data().payload = e2._data().payload; + e2._data().payload = tmp; + e1._data().extra = 1234; + e2._data().extra = 1234; + } +}; + +template<> +struct commutative_binary_expression +{ + typedef myint return_t; + static void doit(myint& to, const myint& a1, const myint& a2) + { + to._data().payload = a1._data().payload + a2._data().payload; + } +}; + +template +struct commutative_binary_expression, operations::plus>::type, + T> +{ + typedef myint return_t; + static void doit(myint& to, const myint& a1, T a2) + { + to._data().payload = a1._data().payload + a2; + } +}; + +template<> +struct commutative_binary_expression +{ + typedef myint return_t; + static void doit(myint& to, const myint& a1, const myint& a2) + { + to._data().payload = a1._data().payload * a2._data().payload; + } +}; + +template<> +struct binary_expression +{ + typedef myint return_t; + static void doit(myint& to, const myint& a1, const myint& a2) + { + to._data().payload = a1._data().payload - a2._data().payload; + } +}; + +template<> +struct binary_expression +{ + typedef myint return_t; + static void doit(myint& to, const myint& a1, const myint& a2) + { + to._data().payload = a1._data().payload / a2._data().payload; + } +}; + +template<> +struct binary_expression +{ + typedef myint return_t; + static void doit(myint& to, const myint& a1, const myint& a2) + { + to._data().payload = a1._data().payload % a2._data().payload; + } +}; + +template<> +struct binary_expression +{ + typedef myint return_t; + static void doit(myint& to, const myint& a1, int a2) + { + if (a2 >= 0) + to._data().payload = a1._data().payload << a2; + else + to._data().payload = a1._data().payload >> (-a2); + } +}; + +template<> +struct unary_expression +{ + typedef myint return_t; + static void doit(myint& to, const myint& from) + { + to._data().payload = - from._data().payload; + } +}; + + +///////////////////////////////////////////////////////////////////////////// +// Minimal rules for mylong +///////////////////////////////////////////////////////////////////////////// + +template +struct equals, mylong_traits::is_source > >::type> +{ + static bool get(const T& i1, const U& i2) + { + return i1._data().payload == i2._data().payload; + } +}; + +template +struct equals >::type> +{ + static bool get(const T& i1, slong i2) + { + return i1._data().payload == i2; + } +}; + +template +struct commutative_binary_expression, + mylong_traits::is_source >, + operations::plus>::type, U> +{ + typedef mylong return_t; + + template + static void doit(V& to, const T& a1, const U& a2) + { + to._data().payload = a1._data().payload + a2._data().payload; + } +}; + +template +struct commutative_binary_expression, myint>::type, operations::plus, U> +{ + typedef mylong return_t; + + template + static void doit(V& to, const myint& a1, const U& a2) + { + to._data().payload = a1._data().payload + a2._data().payload; + } +}; + +template +struct assignment, mylong_traits::is_source > >::type> +{ + static void doit(T& to, const U& from) + { + to._data().payload = from._data().payload; + } +}; + +template +struct assignment >::type> +{ + static void doit(T& to, slong from) + { + to._data().payload = from; + } +}; + +template +struct assignment >::type> +{ + static void doit(T& to, const myint& from) + { + to._data().payload = from._data().payload; + } +}; + +FLINT_DEFINE_READ_COND(mylong_traits::is_target, + flint_fscanf(from, "%wd", &to._data().payload)) +FLINT_DEFINE_PRINT_COND(mylong_traits::is_source, + flint_fprintf(to, "%wd", from._data().payload)) +FLINT_DEFINE_PRINT_PRETTY_COND(mylong_traits::is_source, + flint_fprintf(to, "<%wd>", from._data().payload)) +} // rules +} // flint + +#endif diff --git a/external/flint-2.4.3/flintxx/test/t-arithxx.cpp b/external/flint-2.4.3/flintxx/test/t-arithxx.cpp new file mode 100644 index 0000000..fe15f3b --- /dev/null +++ b/external/flint-2.4.3/flintxx/test/t-arithxx.cpp @@ -0,0 +1,237 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#include + +#include "arithxx.h" + +#include "helpers.h" + +using namespace flint; + +void +test_stirling() +{ +#define STIRLING(func, matfunc, n, k) \ +{\ + tassert(func##_vec(n, k).size() == k); \ + fmpz_vecxx v1(func##_vec(n, k).evaluate() /* test temporary alloc */); \ + for(slong i = 0;i < v1.size();++i) \ + tassert(v1[i] == func(n, i)); \ + tassert(func##_vec_next(func##_vec(n, k), n+1).size() == k); \ + fmpz_vecxx v2(func##_vec_next(v1, n+1)); \ + for(slong i = 0;i < v2.size();++i) \ + tassert(v2[i] == func(n+1, i)); \ + fmpz_vecxx v3(func##_vec(n, n+1)); \ + fmpz_vecxx v4(func##_vec_next(v3, n+1)); \ + tassert(v4.size() == n+2 && v3.size() == n+1); \ + for(slong i = 0;i < v4.size();++i) \ + tassert(v4[i] == func(n+1, i)); \ + tassert(matfunc(n, k).rows() == n && matfunc(n, k).cols() == k); \ + fmpz_matxx M(matfunc(n, k).evaluate() /* test temporaries */); \ + for(slong i = 0;i < M.rows();++i) \ + for(slong j = 0;j < M.cols();++j) \ + tassert(M.at(i, j) == func(i, j)); \ +} +STIRLING(stirling_number_1u, stirling_matrix_1u, 10, 6) +STIRLING(stirling_number_1, stirling_matrix_1, 10, 6) +STIRLING(stirling_number_2, stirling_matrix_2, 10, 6) +} + +void +test_bell() +{ + tassert(bell_number_vec(10).size() == 10); + fmpz_vecxx v(bell_number_vec(10)); + tassert(v == bell_number_vec_recursive(10)); + tassert(v == bell_number_vec_multi_mod(10)); + for(slong i = 0;i < v.size();++i) + tassert(v[i] == bell_number(static_cast(i))); + tassert(bell_number(10u) == bell_number_bsplit(10u)); + tassert(bell_number(10u) == bell_number_multi_mod(10u)); + + nmodxx_ctx p(1031); + tassert(bell_number_nmod(10u, p) == nmodxx::red(bell_number(10u), p)); + nmod_vecxx v2(bell_number_nmod_vec(10u, p)); + tassert(v2.size() == 10); + for(slong i = 0;i < v2.size();++i) + tassert(v2[i] == nmodxx::red(v[i], p)); + + tassert(v2 == bell_number_nmod_vec_series(10u, p)); + tassert(v2 == bell_number_nmod_vec_recursive(10u, p)); + + tassert(fmpzxx(2).pow( + static_cast (bell_number_size(10u))) + > bell_number(10u)); +} + +void +test_bernoulli() +{ + tassert(bernoulli_number(10u).den() == bernoulli_number_denom(10u)); + tassert(fmpqxx(2, 1u).pow( + static_cast (bernoulli_number_size(10u))) + > bernoulli_number(10u)); + fmpq_polyxx poly(bernoulli_polynomial(10u)); + tassert(poly.degree() == 10); + for(slong i = 0;i < poly.length();++i) + tassert(poly.get_coeff(i) + == fmpqxx(bin(10u, (unsigned) i)*bernoulli_number(10u - (unsigned) i))); + tassert(bernoulli_number_vec(10u).size() == 10); + for(unsigned i = 0;i < 10;++i) + tassert(bernoulli_number_vec(10u)[i] == bernoulli_number(i)); +} + +void +test_euler() +{ + tassert(fmpzxx(2).pow( + static_cast (euler_number_size(10u))) + > euler_number(10u)); + fmpq_polyxx poly(euler_polynomial(10u)); + tassert(poly.degree() == 10); + tassert(poly(fmpqxx(1, 2u))*fmpqxx(2, 1u).pow(10) + == fmpqxx(euler_number(10u).evaluate(), fmpzxx(1))); + tassert(euler_number_vec(10u).size() == 10); + for(unsigned i = 0;i < 10;++i) + tassert(euler_number_vec(10u)[i] == euler_number(i)); +} + +void +test_legendre() +{ + const unsigned short N = 10; + fmpq_polyxx f; f = "3 -1 0 1"; + f = f.pow(N); + for(unsigned i = 0;i < N;++i) + f = f.derivative(); + tassert(legendre_polynomial(N) + == f * fmpqxx(fmpzxx(1), (fmpzxx(2).pow(N)*fac(N)).evaluate())); + + fmpq_polyxx x; x = "2 0 1"; + f = chebyshev_t_polynomial(N); + f = f(cos_series(x, N)); + f.truncate(N); + tassert(f == cos_series(N*x, N)); + tassert(chebyshev_u_polynomial(N)*(N + 1) + == chebyshev_t_polynomial(N+1u).derivative()); +} + +void +test_multiplicative() +{ + fmpzxx p(1031); + tassert(euler_phi(p) == p-1u); + tassert(moebius_mu(p) == -1); + tassert(divisor_sigma(p, 4u) == 1u + p.pow(4u)); + tassert(divisors(p).to_string() == "2 1 " + p.to_string()); + + fmpz_polyxx q, one; + q = "2 0 1"; + one = "1 1"; + fmpz_polyxx res(q * (one - q).pow(24u) * (one - q*q).pow(24u)); + for(unsigned i = 3;i < 10;++i) + res *= (one - q.pow(i)).pow(24u); + res.truncate(10); + tassert(res == ramanujan_tau_series(10)); + for(int i = 0;i < 10;++i) + tassert(ramanujan_tau_series(i+1).get_coeff(i) + == ramanujan_tau(fmpzxx(i))); +} + +void +test_polys() +{ + // just very basic tests ... + ulong N = 1234; + tassert(cyclotomic_polynomial(N).degree() == euler_phi(fmpzxx(N))); + tassert(cos_minpoly(N).degree() == euler_phi(fmpzxx(N))/2); + + tassert(swinnerton_dyer_polynomial(8u).degree() == fmpzxx(2).pow(8u)); +} + +void +test_dedekind() +{ + frandxx state; + fmpzxx h = fmpzxx::randtest_unsigned(state, 10); + fmpzxx k = fmpzxx::randtest_unsigned(state, 10); + tassert(dedekind_sum_naive(h, k) == dedekind_sum(h, k)); + k /= gcd(h, k); + tassert(dedekind_sum_coprime_large(h, k) == dedekind_sum(h, k)); + tassert(dedekind_sum_coprime(h, k) == dedekind_sum(h, k)); + // untested: dedekind_sum_coprime_d +} + +void +test_number_of_partitions() +{ + unsigned short N = 15; + nmodxx_ctx p(1031); + fmpz_vecxx v1(number_of_partitions_vec(N)); + nmod_vecxx v2(number_of_partitions_nmod_vec(N, p)); + tassert(v1.size() == v2.size() && v1.size() == N); + for(unsigned i = 0;i < N;++i) + { + tassert(v1[i] == number_of_partitions(i)); + tassert(nmodxx::red(v1[i], p) == v2[i]); + } +} + +void +test_sum_of_squares() +{ + unsigned short N = 15; + fmpz_vecxx v(sum_of_squares_vec(7u, N)); + tassert(v.size() == N); + for(unsigned i = 0;i < N;++i) + tassert(v[i] == sum_of_squares(7u, fmpzxx(i))); +} + +int +main() +{ + std::cout << "arithxx...."; + + tassert(primorial(4) == 2*3); + tassert(harmonic_number(3) + == fmpqxx(1, 1u) + fmpqxx(1, 2u) + fmpqxx(1, 3u)); + + test_stirling(); + test_bell(); + test_bernoulli(); + test_euler(); + test_legendre(); + test_multiplicative(); + test_polys(); + test_dedekind(); + test_number_of_partitions(); + test_sum_of_squares(); + + tassert(landau_function_vec(9)[8] == 15); + + std::cout << "PASS\n"; + return 0; +} diff --git a/external/flint-2.4.3/flintxx/test/t-codegen.cpp b/external/flint-2.4.3/flintxx/test/t-codegen.cpp new file mode 100644 index 0000000..39d4892 --- /dev/null +++ b/external/flint-2.4.3/flintxx/test/t-codegen.cpp @@ -0,0 +1,833 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#include +#include +#include +#include +#include +#include + + +// whether or not the compiler suppors __attribute__(__optimize__(..)) +#ifndef HAVE_OPTIMIZE_ATTRIBUTE +#ifdef __GNUC__ +#define HAVE_OPTIMIZE_ATTRIBUTE (__GNUC__ >= 4 && __GNUC_MINOR__ >= 4) +#else +#define HAVE_OPTIMIZE_ATTRIBUTE 0 +#endif +#endif + +#ifndef DO_CODEGEN_CHECKS +#if !HAVE_OPTIMIZE_ATTRIBUTE +#define DO_CODEGEN_CHECKS 0 +#elif defined(__GNUC__) +// XXX this will need tweaking - look here if things break +// b/c of compiler versions +#define DO_CODEGEN_CHECKS \ + (__GNUC__ == 4 && __GNUC_MINOR__ == 7 && __GNUC_PATCHLEVEL__ == 3 \ + && __x86_64__) +#else +#define DO_CODEGEN_CHECKS 0 +#endif +#endif + +#if !DO_CODEGEN_CHECKS +#define EXIT_STATEMENT throw skippable_exception("did not expect pass anyway") +#endif + +#include +#include + +// Exception class to indicate that this test cannot proceed, e.g. because +// binutils is not installed or because we cannot interpret the disassembled +// code. +// This should not cause the test to fail, since it is not portable. +class skippable_exception + : public std::runtime_error +{ +public: + skippable_exception(const std::string& n) : std::runtime_error(n) {} +}; + +#include "flintxx/test/helpers.h" + +#include "fmpz_matxx.h" +#include "fmpz_polyxx.h" +#include "fmpzxx.h" +#include "nmod_matxx.h" +#include "nmod_polyxx.h" +#include "nmod_vecxx.h" + +#include "flintxx/tuple.h" +#include "flintxx/vector.h" + +// Run a command and recver the output. +std::string exec(const std::string& cmd) +{ + FILE* pipe = popen(cmd.c_str(), "r"); + if (!pipe) + throw skippable_exception("cannot execute command" + cmd); + char buffer[128]; + std::string result = ""; + while(!feof(pipe)) + { + if(fgets(buffer, 128, pipe) != NULL) + result += buffer; + } + pclose(pipe); + return result; +} + +// Disassembled a function contained in the binary "program". +std::string disass(const char* program, const std::string& function) +{ + std::string all = exec(std::string("objdump -d ") + program); + std::string marker = "<" + function + ">:"; + std::size_t start = all.find(marker); + if(start == std::string::npos) + throw skippable_exception("cannot find function " + function); + all = all.substr(start + marker.size()); + std::size_t len = all.find("\n\n"); + if(len == std::string::npos) + throw skippable_exception("cannot find end of function " + function); + return all.substr(0, len); +} + +std::vector& +split(const std::string &s, char delim, std::vector& elems) +{ + std::stringstream ss(s); + std::string item; + while (std::getline(ss, item, delim)) + { + elems.push_back(item); + } + return elems; +} +std::vector lines(const std::string& input) +{ + std::vector result; + return split(input, '\n', result); +} + +// Strip addresses from disassembly, to allow comparison. E.g. +// +// 401790: 45 0f be c9 movsbl %r9b,%r9d +// 401794: 44 89 07 mov %r8d,(%rdi) +// +// --> +// +// movsbl %r9b,%r9d +// mov %r8d,(%rdi) +// +std::string stripaddr(const std::string& input) +{ + std::string result; + std::vector ls = lines(input); + for(unsigned i = 0;i < ls.size();++i) + { + if(ls[i] == "") + continue; + std::size_t pos = ls[i].find(":\t"); + if(pos == std::string::npos) + result += ls[i]; + else + { + std::string tmp = ls[i].substr(pos+2); + pos = tmp.find("\t"); + if(pos == std::string::npos) + result += tmp; + result += tmp.substr(pos+1); + } + result += '\n'; + } + return result; +} + +std::string stripnop(const std::string& input) +{ + std::string result; + std::vector ls = lines(input); + for(unsigned i = 0;i < ls.size();++i) + { + if(ls[i].find("\tnop") != std::string::npos) + continue; + result += ls[i]; + result += '\n'; + } + return result; +} + +// Count the number of occurrences of a substring. +int count(const std::string& str, const std::string& sub) +{ + if(sub.length() == 0) + return 0; + int count = 0; + for(size_t offset = str.find(sub); offset != std::string::npos; + offset = str.find(sub, offset + sub.length())) + ++count; + return count; +} + +// Check if two quantities are equal up to a certain percentage of error. +template +bool fuzzy_equals(T v1, T v2, double perc) +{ + double d1 = double(v1); + double d2 = double(v2); + return d1*(1-perc) <= d2 && d2 <= d1*(1+perc); +} + +using namespace flint; +using namespace mp; + +typedef make_vector_n::type fmpzxx_vector; + +extern "C" { +#if HAVE_OPTIMIZE_ATTRIBUTE +#define DEFINE_FUNC(name, args) \ +void name args __attribute__((__optimize__("no-exceptions"))); \ +void name args +#else +#define DEFINE_FUNC(name, args) \ +void name args +#endif + +DEFINE_FUNC(test_tuple_merge_1, + (int& o1, int& o2, int& o3, int i1, slong i2, char i3, int i4)) +{ + typedef make_tuple make3; + typedef make_tuple make2; + typedef merge_tuple merge; + merge::type merged; // + merged.head = i3; + merged.tail.head = i1; + merged.tail.tail.head = i2; + merged.tail.tail.tail.head = i4; + make3::type extract = merge::get_first(merged); + o1 = extract.head; // i2 + o2 = extract.tail.head; // i1 + o3 = extract.tail.tail.head; // i3 +} + +DEFINE_FUNC(test_tuple_merge_2, + (int& o1, int& o2, int& o3, int i1, slong i2, char i3, int i4)) +{ + o1 = i2; + o2 = i1; + o3 = i3; +} + +DEFINE_FUNC(test_tuple_concat_1, + (tuple::type>& out, + const make_tuple::type& in1, + const make_tuple::type& in2)) +{ + out = concat_tuple< + make_tuple::type, + make_tuple::type + >::doit(in1, in2); +} + +DEFINE_FUNC(test_tuple_concat_2, + (tuple::type>& out, + const make_tuple::type& in1, + const make_tuple::type& in2)) +{ + out.head = in1.head; + out.tail.head = in1.tail.head; + out.tail.tail.head = in2.head; + out.tail.tail.tail.head = in2.tail.head; +} + +DEFINE_FUNC(test_tuple_back_1, + (make_tuple::type& out, int i1, slong i2, char i3)) +{ + typedef make_tuple::type type; + type pointers; + back_tuple::init(pointers, out, 0); + *pointers.head = i1; + *pointers.tail.head = i2; + *pointers.tail.tail.head = i3; +} + +DEFINE_FUNC(test_tuple_back_2, + (make_tuple::type& out, int i1, slong i2, char i3)) +{ + out.head = i1; + out.tail.head = i2; + out.tail.tail.head = i3; +} + +DEFINE_FUNC(test_tuple_extract_1, + (make_homogeneous_tuple::type& out, + const make_homogeneous_tuple::type& in)) +{ + out = htuples::extract<4>(in); +} + +DEFINE_FUNC(test_tuple_extract_2, + (make_homogeneous_tuple::type& out, + const make_homogeneous_tuple::type& in)) +{ + out.head = in.head; + out.tail.head = in.tail.head; + out.tail.tail.head = in.tail.tail.head; + out.tail.tail.tail.head = in.tail.tail.tail.head; +} + +DEFINE_FUNC(test_tuple_removeres_1, + (make_homogeneous_tuple::type& out, int in1, int in2)) +{ + make_homogeneous_tuple::type tmp = + make_tuple::make(1, in1, in2); + out = htuples::removeres(tmp, 1); +} + +DEFINE_FUNC(test_tuple_removeres_2, + (make_homogeneous_tuple::type& out, int in1, int in2)) +{ + out.head = in1; + out.tail.head = in2; +} + + +DEFINE_FUNC(test_fmpzxx_symadd_1, + (fmpzxx& out, const fmpzxx& a, const fmpzxx& b, const fmpzxx& c, const fmpzxx& d)) +{ + out = ((a + b) + (c + d)) + ((a + c) + (b + d)); +} + +DEFINE_FUNC(test_fmpzxx_symadd_2, + (fmpzxx& out, const fmpzxx& a, const fmpzxx& b, const fmpzxx& c, const fmpzxx& d)) +{ + fmpz_t tmp1, tmp2, tmp3; + fmpz_init(tmp1); + fmpz_init(tmp2); + fmpz_init(tmp3); + + fmpz_add(tmp1, a._fmpz(), b._fmpz()); + fmpz_add(tmp2, c._fmpz(), d._fmpz()); + fmpz_add(tmp3, tmp1, tmp2); + fmpz_add(tmp1, a._fmpz(), c._fmpz()); + fmpz_add(tmp2, b._fmpz(), d._fmpz()); + fmpz_add(tmp1, tmp1, tmp2); + fmpz_add(out._fmpz(), tmp1, tmp3); + + fmpz_clear(tmp1); + fmpz_clear(tmp2); + fmpz_clear(tmp3); +} + +DEFINE_FUNC(test_fmpzxx_asymadd_1, + (fmpzxx& out, const fmpzxx& a, const fmpzxx& b, const fmpzxx& c, const fmpzxx& d)) +{ + out = (a + (((b + (c + (a + b))) + c) + d)); +} + +DEFINE_FUNC(test_fmpzxx_asymadd_2, + (fmpzxx& out, const fmpzxx& a, const fmpzxx& b, const fmpzxx& c, const fmpzxx& d)) +{ + fmpz_t tmp; + fmpz_init(tmp); + + fmpz_add(tmp, a._fmpz(), b._fmpz()); + fmpz_add(tmp, c._fmpz(), tmp); + fmpz_add(tmp, b._fmpz(), tmp); + fmpz_add(tmp, tmp, c._fmpz()); + fmpz_add(tmp, tmp, d._fmpz()); + fmpz_add(out._fmpz(), a._fmpz(), tmp); + + fmpz_clear(tmp); +} + +DEFINE_FUNC(test_fmpzxx_asymadd_3, + (fmpzxx& out, const fmpzxx& a, const fmpzxx& b, const fmpzxx& c, const fmpzxx& d)) +{ + out = a + b + c + a + b + c + d; +} + +DEFINE_FUNC(test_fmpzxx_ternary_1, + (fmpzxx& out, const fmpzxx& a, const fmpzxx& b, const fmpzxx& c, const fmpzxx& d)) +{ + out = a + ((a+b) + c*d); +} + +DEFINE_FUNC(test_fmpzxx_ternary_2, + (fmpzxx& out, const fmpzxx& a, const fmpzxx& b, const fmpzxx& c, const fmpzxx& d)) +{ + fmpz_t tmp; + fmpz_init(tmp); + + fmpz_add(tmp, a._fmpz(), b._fmpz()); + fmpz_addmul(tmp, c._fmpz(), d._fmpz()); + fmpz_add(out._fmpz(), a._fmpz(), tmp); + + fmpz_clear(tmp); +} + +DEFINE_FUNC(test_fmpzxx_ternary_3, + (fmpzxx& out, const fmpzxx& a, const fmpzxx& b, const fmpzxx& c, const fmpzxx& d)) +{ + out = a + ((a+b) + ((c+a) + (a+d))*d); +} + +DEFINE_FUNC(test_fmpzxx_ternary_4, + (fmpzxx& out, const fmpzxx& a, const fmpzxx& b, const fmpzxx& c, const fmpzxx& d)) +{ + fmpz_t tmp1, tmp2; + fmpz_init(tmp1);fmpz_init(tmp2); + + fmpz_add(tmp1, c._fmpz(), a._fmpz()); + fmpz_add(tmp2, a._fmpz(), d._fmpz()); + fmpz_add(tmp1, tmp1, tmp2); + fmpz_add(tmp2, a._fmpz(), b._fmpz()); + fmpz_addmul(tmp2, tmp1, d._fmpz()); + fmpz_add(out._fmpz(), a._fmpz(), tmp2); + + fmpz_clear(tmp1);fmpz_clear(tmp2); +} + +DEFINE_FUNC(test_fmpzxx_ternary_5, + (fmpzxx& out, const fmpzxx& a, const fmpzxx& b, const fmpzxx& c, const fmpzxx& d)) +{ + out += a*b; +} + +DEFINE_FUNC(test_fmpzxx_ternary_6, + (fmpzxx& out, const fmpzxx& a, const fmpzxx& b, const fmpzxx& c, const fmpzxx& d)) +{ + fmpz_addmul(out._fmpz(), a._fmpz(), b._fmpz()); +} + +DEFINE_FUNC(test_fmpzxx_ternary_7, + (fmpzxx& out, const fmpzxx& a, const fmpzxx& b, const fmpzxx& c, const fmpzxx& d)) +{ + out += a*(b+c); +} + +DEFINE_FUNC(test_fmpzxx_ternary_8, + (fmpzxx& out, const fmpzxx& a, const fmpzxx& b, const fmpzxx& c, const fmpzxx& d)) +{ + fmpz_t tmp; fmpz_init(tmp); + fmpz_add(tmp, b._fmpz(), c._fmpz()); + fmpz_addmul(out._fmpz(), a._fmpz(), tmp); + fmpz_clear(tmp); +} + +DEFINE_FUNC(test_fmpzxx_ternary_9, + (fmpzxx& out, const fmpzxx& a, const fmpzxx& b, const fmpzxx& c, const fmpzxx& d)) +{ + out += (a+d)*(b+c); +} + +DEFINE_FUNC(test_fmpzxx_ternary_10, + (fmpzxx& out, const fmpzxx& a, const fmpzxx& b, const fmpzxx& c, const fmpzxx& d)) +{ + fmpz_t tmp1, tmp2; fmpz_init(tmp1); fmpz_init(tmp2); + fmpz_add(tmp1, b._fmpz(), c._fmpz()); + fmpz_add(tmp2, a._fmpz(), d._fmpz()); + fmpz_addmul(out._fmpz(), tmp1, tmp2); + fmpz_clear(tmp1); fmpz_clear(tmp2); +} + +DEFINE_FUNC(test_fmpzxx_ref_1, + (fmpzxx_ref out, fmpzxx_srcref in1, fmpzxx_srcref in2)) +{ + out = in1 + in2; +} + +DEFINE_FUNC(test_fmpzxx_ref_2, + (fmpzxx_ref out, fmpzxx_srcref in1, fmpzxx_srcref in2)) +{ + fmpz_add(out._fmpz(), in1._fmpz(), in2._fmpz()); +} + +DEFINE_FUNC(test_fmpzxx_ltuple_comp_1, + (bool& out, const fmpzxx& in1, const fmpzxx& in2)) +{ + out = (ltupleref(in1, in2) == ltuple(1, 2)); +} + +DEFINE_FUNC(test_fmpzxx_ltuple_comp_2, + (bool& out, const fmpzxx& in1, const fmpzxx& in2)) +{ + out = ((fmpz_cmp_si(in1._fmpz(), 1) == 0) + && (fmpz_cmp_si(in2._fmpz(), 2) == 0)); +} + +DEFINE_FUNC(test_fmpzxx_vec_1, + (fmpzxx_vector& out, const fmpzxx_vector& in1, const fmpzxx_vector& in2)) +{ + out = in1 + in2; +} + +DEFINE_FUNC(test_fmpzxx_vec_2, + (fmpz* out, const fmpz* in1, const fmpz* in2)) +{ + fmpz_add(out + 0, in1 + 0, in2 + 0); + fmpz_add(out + 1, in1 + 1, in2 + 1); + fmpz_add(out + 2, in1 + 2, in2 + 2); + fmpz_add(out + 3, in1 + 3, in2 + 3); + fmpz_add(out + 4, in1 + 4, in2 + 4); + fmpz_add(out + 5, in1 + 5, in2 + 5); + fmpz_add(out + 6, in1 + 6, in2 + 6); + fmpz_add(out + 7, in1 + 7, in2 + 7); + fmpz_add(out + 8, in1 + 8, in2 + 8); + fmpz_add(out + 9, in1 + 9, in2 + 9); +} + + +DEFINE_FUNC(test_fmpz_matxx_1, + (fmpzxx& to, const fmpz_matxx& A)) +{ + to = trace(transpose(A)*A); +} +DEFINE_FUNC(test_fmpz_matxx_2, + (fmpzxx& to, const fmpz_matxx& A)) +{ + fmpz_mat_t tmp1, tmp2; + fmpz_mat_init(tmp1, fmpz_mat_nrows(A._mat()), fmpz_mat_ncols(A._mat())); + fmpz_mat_init(tmp2, fmpz_mat_ncols(A._mat()), fmpz_mat_ncols(A._mat())); + fmpz_mat_transpose(tmp1, A._mat()); + fmpz_mat_mul(tmp1, tmp2, A._mat()); + fmpz_mat_trace(to._fmpz(), tmp2); + fmpz_mat_clear(tmp1); + fmpz_mat_clear(tmp2); +} + +DEFINE_FUNC(test_fmpz_matxx_manip_1, + (fmpz_matxx& A)) +{ + A.at(0, 0) += 2u; +} + +DEFINE_FUNC(test_fmpz_matxx_manip_2, + (fmpz_matxx& A)) +{ + fmpz_add_ui(fmpz_mat_entry(A._mat(), 0, 0), + fmpz_mat_entry(A._mat(), 0, 0), 2u); +} + + +DEFINE_FUNC(test_fmpz_polyxx_divrem_1, + (fmpz_polyxx& A, fmpz_polyxx& B, + const fmpz_polyxx& f, const fmpz_polyxx& g)) +{ + ltupleref(A, B) = divrem(f, g); +} +DEFINE_FUNC(test_fmpz_polyxx_divrem_2, + (fmpz_polyxx& A, fmpz_polyxx& B, + const fmpz_polyxx& f, const fmpz_polyxx& g)) +{ + fmpz_poly_divrem(A._poly(), B._poly(), f._poly(), g._poly()); +} + +DEFINE_FUNC(test_fmpz_polyxx_divrem_3, + (fmpz_polyxx& A, + const fmpz_polyxx& f, const fmpz_polyxx& g)) +{ + ltupleref(A, _) = divrem(f, g); +} +DEFINE_FUNC(test_fmpz_polyxx_divrem_4, + (fmpz_polyxx& A, + const fmpz_polyxx& f, const fmpz_polyxx& g)) +{ + fmpz_poly_t tmp; + fmpz_poly_init(tmp); + fmpz_poly_divrem(A._poly(), tmp, f._poly(), g._poly()); + fmpz_poly_clear(tmp); +} + +DEFINE_FUNC(test_nmodxx_1, + (mp_limb_t& to, mp_limb_t a_, mp_limb_t b_, nmod_t nm)) +{ + nmodxx_ctx_srcref ctx = nmodxx_ctx_srcref::make(nm); + nmodxx a = nmodxx::make_nored(a_, ctx); + nmodxx b = nmodxx::make_nored(b_, ctx); + to = inv((a + b) * (a * b)).to(); +} +DEFINE_FUNC(test_nmodxx_2, + (mp_limb_t& to, mp_limb_t a, mp_limb_t b, nmod_t nm)) +{ + mp_limb_t tmp1, tmp2; + tmp1 = nmod_add(a, b, nm); + tmp2 = nmod_mul(a, b, nm); + tmp1 = nmod_mul(tmp1, tmp2, nm); + tmp1 = nmod_inv(tmp1, nm); + to = tmp1; +} + + +DEFINE_FUNC(test_nmod_polyxx_1, + (nmod_polyxx& to, const nmod_polyxx& p1, const nmod_polyxx& p2)) +{ + to = (p1*p1) + (p2*p2); +} + +DEFINE_FUNC(test_nmod_polyxx_2, + (nmod_polyxx& to, const nmod_polyxx& p1, const nmod_polyxx& p2)) +{ + nmod_poly_t tmp1, tmp2; + nmod_poly_init_preinv(tmp1, p1.modulus(), p1.estimate_ctx()._nmod().ninv); + nmod_poly_init_preinv(tmp2, p1.modulus(), p1.estimate_ctx()._nmod().ninv); + + nmod_poly_mul(tmp1, p1._poly(), p1._poly()); + nmod_poly_mul(tmp2, p2._poly(), p2._poly()); + nmod_poly_add(to._poly(), tmp1, tmp2); + + nmod_poly_clear(tmp1); + nmod_poly_clear(tmp2); +} + +DEFINE_FUNC(test_nmod_polyxx_3, + (nmod_polyxx& to, const nmod_polyxx& p1, const nmod_polyxx& p2)) +{ + to = ((p1*p1) + (p2*p2)) + ((p1*p2) + (p2*p1)); +} +DEFINE_FUNC(test_nmod_polyxx_4, + (nmod_polyxx& to, const nmod_polyxx& p1, const nmod_polyxx& p2)) +{ + nmod_poly_t tmp1, tmp2, tmp3; + nmod_poly_init_preinv(tmp1, p1.modulus(), p1.estimate_ctx()._nmod().ninv); + nmod_poly_init_preinv(tmp2, p1.modulus(), p1.estimate_ctx()._nmod().ninv); + nmod_poly_init_preinv(tmp3, p1.modulus(), p1.estimate_ctx()._nmod().ninv); + + nmod_poly_mul(tmp1, p1._poly(), p1._poly()); + nmod_poly_mul(tmp2, p2._poly(), p2._poly()); + nmod_poly_add(tmp1, tmp1, tmp2); + nmod_poly_mul(tmp2, p1._poly(), p2._poly()); + nmod_poly_mul(tmp3, p2._poly(), p1._poly()); + nmod_poly_add(tmp2, tmp2, tmp3); + nmod_poly_add(to._poly(), tmp1, tmp2); + + nmod_poly_clear(tmp1); + nmod_poly_clear(tmp2); + nmod_poly_clear(tmp3); +} + +DEFINE_FUNC(test_nmod_matxx_1, + (nmodxx& to, const nmod_matxx& A)) +{ + to = trace(transpose(A)*A); +} +DEFINE_FUNC(test_nmod_matxx_2, + (nmodxx& to, const nmod_matxx& A)) +{ + nmod_mat_t tmp1, tmp2; + nmod_mat_init(tmp1, nmod_mat_nrows(A._mat()), nmod_mat_ncols(A._mat()), + A.modulus()); + nmod_mat_init(tmp2, nmod_mat_ncols(A._mat()), nmod_mat_ncols(A._mat()), + A.modulus()); + nmod_mat_transpose(tmp1, A._mat()); + nmod_mat_mul(tmp1, tmp2, A._mat()); + nmod_mat_clear(tmp1); + to.set_nored(nmod_mat_trace(tmp2)); + nmod_mat_clear(tmp2); +} +} // extern "C" + +// Global variable, initialized by main. +const char* program = 0; + +void +test_tuple() +{ + std::string ass1 = disass(program, "test_tuple_merge_1"); + std::string ass2 = disass(program, "test_tuple_merge_2"); + // XXX is this deterministic? + tassert(stripaddr(ass1) == stripaddr(ass2)); + + ass1 = disass(program, "test_tuple_concat_1"); + ass2 = disass(program, "test_tuple_concat_2"); + tassert(count(ass1, "\n") == count(ass2, "\n")); + tassert(count(ass1, "mov") == count(ass2, "mov")); + tassert(count(ass1, "call") == count(ass2, "call")); // 0 + + ass1 = disass(program, "test_tuple_back_1"); + ass2 = disass(program, "test_tuple_back_2"); + // XXX is this deterministic? + tassert(stripaddr(ass1) == stripaddr(ass2)); + + ass1 = disass(program, "test_tuple_extract_1"); + ass2 = disass(program, "test_tuple_extract_2"); + tassert(count(ass1, "\n") == count(ass2, "\n")); + tassert(count(ass1, "mov") == count(ass2, "mov")); + tassert(count(ass1, "call") == count(ass2, "call")); // 0 + + ass1 = disass(program, "test_tuple_removeres_1"); + ass2 = disass(program, "test_tuple_removeres_2"); + // XXX is this deterministic? + tassert(stripaddr(ass1) == stripaddr(ass2)); +} + +void +test_fmpzxx() +{ + std::string ass1 = disass(program, "test_fmpzxx_symadd_1"); + std::string ass2 = disass(program, "test_fmpzxx_symadd_2"); + tassert(count(ass1, "call") == count(ass2, "call")); + tassert(fuzzy_equals(count(stripnop(ass1), "\n"), + count(stripnop(ass2), "\n"), 0.1)); + + ass1 = disass(program, "test_fmpzxx_asymadd_1"); + ass2 = disass(program, "test_fmpzxx_asymadd_2"); + std::string ass3 = disass(program, "test_fmpzxx_asymadd_3"); + tassert(count(ass1, "call") == count(ass2, "call")); + tassert(count(ass1, "mov") == count(ass2, "mov")); + tassert(count(ass3, "call") == count(ass2, "call")); + tassert(count(ass3, "mov") == count(ass2, "mov")); + + // This is probably not the best idea. + // (Actually the same code is generated, up to jump targets, register names + // and addresses.) + tassert(count(ass1, "\n") == count(ass2, "\n")); + tassert(count(ass3, "\n") == count(ass2, "\n")); + + ass1 = disass(program, "test_fmpzxx_ternary_1"); + ass2 = disass(program, "test_fmpzxx_ternary_2"); + tassert(count(ass1, "call") == count(ass2, "call")); + tassert(count(ass1, "mov") == count(ass2, "mov")); + tassert(count(ass1, "\n") == count(ass2, "\n")); // XXX + + ass1 = disass(program, "test_fmpzxx_ternary_3"); + ass2 = disass(program, "test_fmpzxx_ternary_4"); + tassert(count(ass1, "call") == count(ass2, "call")); + tassert(count(ass1, "je") == count(ass2, "je")); + tassert(count(ass1, "jmp") == count(ass2, "jmp")); + tassert(fuzzy_equals(count(ass1, "mov") + count(ass1, "lea"), + count(ass2, "mov") + count(ass2, "lea"), 0.1)); + tassert(fuzzy_equals(count(ass1, "\n"), count(ass2, "\n"), 0.1)); + + ass1 = disass(program, "test_fmpzxx_ternary_6"); + ass2 = disass(program, "test_fmpzxx_ternary_5"); + tassert(count(ass1, "\n") == count(ass2, "\n")); // XXX + + ass1 = disass(program, "test_fmpzxx_ternary_7"); + ass2 = disass(program, "test_fmpzxx_ternary_8"); + tassert(count(ass1, "call") == count(ass2, "call")); + // NB: ass1 is actually shorter?!? + tassert(fuzzy_equals(count(ass1, "\n"), count(ass2, "\n"), 0.1)); + + ass1 = disass(program, "test_fmpzxx_ternary_9"); + ass2 = disass(program, "test_fmpzxx_ternary_10"); + tassert(count(ass1, "call") == count(ass2, "call")); + // NB: ass1 is actually shorter?!? + tassert(fuzzy_equals(count(ass1, "\n"), count(ass2, "\n"), 0.1)); + + ass1 = disass(program, "test_fmpzxx_ref_1"); + ass2 = disass(program, "test_fmpzxx_ref_2"); + tassert(count(ass1, "\n") == count(ass2, "\n")); + ass1 = disass(program, "test_fmpzxx_ltuple_comp_1"); + ass2 = disass(program, "test_fmpzxx_ltuple_comp_2"); + tassert(count(ass1, "\n") == count(ass2, "\n")); +} + +void +test_vector() +{ + std::string ass1 = disass(program, "test_fmpzxx_vec_1"); + std::string ass2 = disass(program, "test_fmpzxx_vec_2"); + tassert(stripaddr(ass1) == stripaddr(ass2)); +} + +void +test_mat() +{ + std::string ass1 = disass(program, "test_fmpz_matxx_1"); + std::string ass2 = disass(program, "test_fmpz_matxx_2"); + tassert(count(ass1, "call") == count(ass2, "call")); + tassert(fuzzy_equals(count(stripnop(ass1), "\n"), + count(stripnop(ass2), "\n"), 0.1)); + + ass1 = disass(program, "test_fmpz_matxx_manip_1"); + ass2 = disass(program, "test_fmpz_matxx_manip_2"); + tassert(count(ass1, "call") == count(ass2, "call")); // 1 + tassert(count(ass1, "\n") == count(ass2, "\n")); +} + +void +test_poly() +{ + std::string ass1 = disass(program, "test_fmpz_polyxx_divrem_1"); + std::string ass2 = disass(program, "test_fmpz_polyxx_divrem_2"); + tassert(stripaddr(ass1) == stripaddr(ass2)); + + ass1 = disass(program, "test_fmpz_polyxx_divrem_1"); + ass2 = disass(program, "test_fmpz_polyxx_divrem_2"); + tassert(count(ass1, "call") == count(ass2, "call")); + tassert(fuzzy_equals(count(ass1, "\n"), count(ass2, "\n"), 0.1)); +} + +void +test_nmod() +{ + std::string ass1 = disass(program, "test_nmodxx_1"); + std::string ass2 = disass(program, "test_nmodxx_2"); + tassert(stripaddr(ass1) == stripaddr(ass2)); + + ass1 = disass(program, "test_nmod_polyxx_1"); + ass2 = disass(program, "test_nmod_polyxx_2"); + tassert(fuzzy_equals(count(ass1, "\n"), count(ass2, "\n"), 0.2)); + tassert(count(ass1, "call") == count(ass2, "call")); + + ass1 = disass(program, "test_nmod_polyxx_3"); + ass2 = disass(program, "test_nmod_polyxx_4"); + tassert(fuzzy_equals(count(stripnop(ass1), "\n"), + count(stripnop(ass2), "\n"), 0.2)); + tassert(count(ass1, "call") == count(ass2, "call")); + + ass1 = disass(program, "test_nmod_matxx_1"); + ass2 = disass(program, "test_nmod_matxx_2"); + tassert(fuzzy_equals(count(stripnop(ass1), "\n"), + count(stripnop(ass2), "\n"), 0.05)); + tassert(count(ass1, "call") == count(ass2, "call")); +} + +int +main(int argc, char** argv) +{ + std::cout << "codegen...."; + program = argv[0]; + try + { + test_tuple(); + test_fmpzxx(); + test_vector(); + test_mat(); + test_poly(); + test_nmod(); + } + catch(skippable_exception e) + { + std::cout << "SKIP (" << e.what() << ")\n"; + return 0; + } + std::cout << "PASS" << std::endl; + return 0; +} + diff --git a/external/flint-2.4.3/flintxx/test/t-compiler-errors.cc b/external/flint-2.4.3/flintxx/test/t-compiler-errors.cc new file mode 100644 index 0000000..010ac66 --- /dev/null +++ b/external/flint-2.4.3/flintxx/test/t-compiler-errors.cc @@ -0,0 +1,130 @@ +#ifndef EXTRACTING_SAMPLE +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +// This file does not actually meant compile. It is used to check compiler error +// outputs. NB: File extension .cc to stop the build system from trying to compile +// this. + +#include "fmpzxx.h" +#ifdef TEST_PADICXX_FORGET_EVAL +#include "padicxx.h" +#endif + +struct newtype { }; + +using namespace flint; + +int +main() +{ +#endif // EXTRACTING_SAMPLE +#ifdef TEST_FMPZXX_INIT_WRONG + { + newtype n; + fmpzxx a(n); + } +#endif +#ifdef TEST_FMPZXX_INIT_2 + { + fmpzxx a(3, 4); + } +#endif +#ifdef TEST_FMPZXX_ASSIGN_WRONG + { + fmpzxx a; + newtype n; + a = n; + } +#endif +#ifdef TEST_FMPZXX_CONVERT_WRONG + { + fmpzxx a; + a.to(); + } +#endif +#ifdef TEST_FMPZXX_REF_INIT_WRONG_1 + { + const fmpzxx a; + fmpzxx_ref ar(a); + } +#endif +#ifdef TEST_FMPZXX_REF_INIT_WRONG_2 + { + const fmpzxx a; + fmpzxx_srcref asr(a); + fmpzxx_ref ar(asr); + } +#endif +#ifdef TEST_FMPZXX_SRCREF_ASSIGN + { + fmpzxx a; + fmpzxx_srcref b(a); + b = a; + } +#endif +#ifdef TEST_FMPZXX_ARITH_WRONG + { + fmpzxx a; + newtype n; + a + n; + } +#endif +#ifdef TEST_FMPZXX_ARITH_WRONG_DEEP + { + fmpzxx a; + newtype n; + a + (a*a + (a / n) + a)*a; + } +#endif +#ifdef TEST_FMPZXX_ARITHFUNC_WRONG_NARGS + { + fmpzxx a; + gcd(a); + } +#endif +#ifdef TEST_FMPZXX_ARITHFUNC_WRONG_TYPE + { + newtype n; + dlog(n); + } +#endif +#ifdef TEST_FMPZXX_ARITHFUNC_WRONG_TYPE2 + { + fmpzxx a; + fac(a); + } +#endif +#ifdef TEST_PADICXX_FORGET_EVAL + { + padicxx_ctx ctx(fmpzxx(5), 1, 2, PADIC_TERSE); + padicxx a(ctx); + (a + a).unit(); + } +#endif +#ifndef EXTRACTING_SAMPLE + // TODO: assignment through tuple with wrong type +} +#endif diff --git a/external/flint-2.4.3/flintxx/test/t-expression.cpp b/external/flint-2.4.3/flintxx/test/t-expression.cpp new file mode 100644 index 0000000..ba87743 --- /dev/null +++ b/external/flint-2.4.3/flintxx/test/t-expression.cpp @@ -0,0 +1,394 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#include + +#include "flintxx/expression.h" +#include "flintxx/tuple.h" + +#include "flintxx/test/helpers.h" +#include "flintxx/test/myint.h" + +using namespace flint; +using namespace mp; +using namespace traits; + +void +test_initialization() +{ + myint a; + tassert(a._data().payload == -1 && a._data().extra == 42); + + a._data().payload = 17; + myint b = a; + tassert(b._data().payload == 17); + + myint c(8); + tassert(c._data().payload == 8 && c._data().extra == 2); + + myint d('a'); + tassert(d._data().payload == 'a' && d._data().extra == 3); + + myint e(c + c); + tassert(e._data().payload == 16); +} + +void +test_destruction() +{ + bool destroyed = false; + { + myint a; + a._data().destroyed = &destroyed; + } + tassert(destroyed); +} + +void +test_printing() +{ + std::ostringstream o; + myint a(4); + o << a; + tassert(o.str() == "4"); +} + +void +test_assignment() +{ + myint a; + myint b(43); + a = b; + tassert(a._data().payload == 43); + tassert(a._data().extra == 4); + + a = WORD(44); + tassert(a._data().payload == 44 && a._data().extra == 5); + + mylong c(0); + c = a + b; + tassert(c == WORD(87)); +} + +void +test_swap() +{ + myint a(2), b(3); + swap(a, b); + tassert(a == 3 && b == 2 && a._data().extra == 1234); +} + +void +test_traits() +{ + typedef myint immediate_expression; + typedef int immediate_nonexpression; + typedef my_expression< + operations::plus, + make_tuple::type + > lazy_expression; + + tassert(is_expression::val == true); + tassert(is_expression::val == false); + tassert(is_expression::val == true); + + tassert(is_immediate_expr::val == true); + tassert(is_immediate_expr::val == false); + tassert(is_immediate_expr::val == false); + + tassert(is_immediate::val == true); + tassert(is_immediate::val == true); + tassert(is_immediate::val == false); + + tassert(is_lazy_expr::val == false); + tassert(is_lazy_expr::val == false); + tassert(is_lazy_expr::val == true); + tassert(is_lazy_expr::val == false); +} + +void +test_equals() +{ + myint a(3); + myint b(4); + myint c(3); + + tassert(a != b); + tassert(a == c); + + tassert(a == 3); + tassert(3 == a); + + tassert(a != 4); + tassert(4 != a); + + tassert((a + b) == (a + 4)); +} + +void +test_arithmetic() +{ + myint a(3); + myint b(4); + myint c(7); + myint d(1); + myint e(2); + + tassert((a + b).evaluate() == 7); + tassert(a + b == c); + tassert(a + b == 7); + + tassert(a - b == -1); + tassert(a * b == 12); + tassert(c / e == 3); + tassert(c % e == 1); + tassert(-a == -3); + + // Test arithmetic with immediates + tassert(a + 4 == 7); + tassert(4 + a == 7); + tassert(a + WORD(4) == 7); + tassert(4u + a == 7); + + // Test composite arithmetic + tassert((a + 1) + (b + 2) == 10); + tassert((a + d) + (b + 2) == 10); + tassert((a + d) + (b + e) == 10); + tassert((3 + d) + (b + e) == 10); + tassert((3 + d) + (4 + e) == 10); + + tassert(a + (b + c) == 14); + tassert(3 + (b + c) == 14); + tassert(3 + (4 + c) == 14); + tassert(3 + (b + 7) == 14); + tassert(a + (b + 7) == 14); + + tassert((b + c) + a == 14); + tassert((b + c) + 3 == 14); + tassert((4 + c) + 3== 14); + tassert((b + 7) + 3== 14); + tassert((b + 7) + a== 14); + + // test combining unary and binary arithmetic + tassert(-(-a) == 3); + tassert(-(a - b) == b - a); + tassert(-((-a) + (-b)) == a + b); + + // Test mixed arithmetic + mylong al(WORD(3)); + mylong bl(WORD(4)); + mylong cl(WORD(7)); + + tassert(al + bl == cl); + tassert(al + bl == WORD(7)); + tassert(al + b == WORD(7)); + tassert(a + bl == WORD(7)); + tassert((a + bl) + cl == WORD(14)); + tassert((a + b) + cl == WORD(14)); + tassert((al + b) + c == WORD(14)); + tassert(cl + (a + bl) == WORD(14)); + tassert(cl + (a + b) == WORD(14)); + tassert(c + (al + b) == WORD(14)); + tassert((a + bl) + (cl + d) == WORD(15)); + tassert((a + bl) + (c + d) == WORD(15)); + + tassert((a << 2) == 12); + tassert(((a << 2) >> 2) == a); +} + +void +test_conversion() +{ + myint a(4); + mylong b(WORD(4)); + tassert(typed_equals(a.to(), 4)); + tassert(typed_equals(a.to(), b)); + tassert(typed_equals((a + a).to(), 8)); +} + +void +test_assignment_arith() +{ + myint a(1); + myint b(2); + a += b; + tassert(a == 3 && b == 2); + a += a*b; + tassert(a == 9); + a += 1; + tassert(a == 10); +} + +template +bool is_subexpr(const Expr& e) +{ + return tools::has_subexpr, Expr>::val; +} +void +test_tools() +{ + typedef tools::equal_types_pred intpred; + myint a(1); + mylong b(WORD(2)); + tassert(tools::find_subexpr(a) == 1); + tassert(tools::find_subexpr(a + b) == 1); + tassert(tools::find_subexpr_T(a + b) == WORD(2)); + tassert(tools::find_subexpr(b + (a + 2) + b) == 1); + tassert(is_subexpr(a+b)); + tassert(!is_subexpr(a+a)); +} + +void +test_temporaries() +{ + myint a(1); +#define T2 ((a + a) + (a + a)) +#define T3 (T2 + T2) + tassert(count_temporaries(T2) == 2); + tassert(count_temporaries(T3) == 3); + tassert(count_temporaries(T3 + T2) == 3); + tassert(count_temporaries(T2 + T3) == 3); +} + +void +test_references() +{ + mylong a(4); + mylong_ref ar(a); + mylong_cref acr(a); + tassert(a == ar); + tassert(a == acr); + tassert(ar == acr); + tassert(ar == WORD(4) && acr == WORD(4)); + + ar = WORD(5); + tassert(a == WORD(5) && acr == WORD(5) && ar == WORD(5)); + + mylong b(6); + ar = b; + tassert(a == b); + + mylong_cref bcr(b); + b = WORD(7); + ar = bcr; + tassert(a == b); + + a = WORD(4); + b = WORD(5); + tassert(a + bcr == WORD(9)); + tassert(ar + bcr == WORD(9)); + a = acr + b; + tassert(a == WORD(9)); + ar = acr + bcr; + tassert(a == WORD(14)); + + a = WORD(4); + tassert((a + a) + bcr == WORD(13)); + tassert((acr + acr) + b == WORD(13)); + tassert(((a + bcr) + acr + (ar + bcr)) + ((a + a) + (bcr + bcr)) == WORD(40)); + a = ((a + bcr) + acr + (ar + bcr)) + ((a + a) + (bcr + bcr)); + tassert(a == WORD(40)); + a = WORD(4); + ar = ((a + bcr) + acr + (ar + bcr)) + ((a + a) + (bcr + bcr)); + tassert(a == WORD(40)); +} + +struct S { }; +S operator+(const S& s, const S&) {return s;} +S operator-(const S&s) {return s;} +template +S operator*(const S& s, const T&) {return s;} +void +test_unrelated_overload() +{ + // Test a bug in our operator overloading logic which used to not allow + // this to compile. + S s; + s = s + s; + s = -s; + s = s * (myint(5) + myint(5)); +} + +void +test_multiary() +{ + tassert(fourary_test(1, 2, 3, 4) == myint(1 + 2 + 3 + 4)); + tassert(fiveary_test(1, 2, 3, 4, 5u) == 1 + 2 + 3 + 4 + 5); + tassert(sixary_test(1, 2, 3, 4, 5, 6) == 1 + 2 + 3 + 4 + 5 + 6); + tassert(sevenary_test(1, 2, 3, 4, 5, 6, 7) == 1 + 2 + 3 + 4 + 5 + 6 + 7); +} + +void +test_cstyle_io() +{ +#if !defined (__WIN32) && !defined (__CYGWIN__) + mylong c(17), d(0); + FILE * f = std::fopen("expression_test", "w+"); + tassert(f); + print(f, c); + std::fprintf(f, "\n"); + print_pretty(f, c); + std::fflush(f); + std::fclose(f); + + f = std::fopen("expression_test", "r"); + tassert(read(f, d) > 0); + tassert(d == c); + d = WORD(0); + tassert(std::fscanf(f, "\n") == 0); + fclose(f); + tassert(std::remove("expression_test") == 0); +#endif +} + +int +main() +{ + std::cout << "expression...."; + + test_traits(); + test_initialization(); + test_destruction(); + test_printing(); + test_assignment(); + test_swap(); + test_equals(); + test_arithmetic(); + test_conversion(); + test_assignment_arith(); + test_tools(); + test_temporaries(); + test_references(); + test_multiary(); + test_cstyle_io(); + + test_unrelated_overload(); + + std::cout << "PASS" << std::endl; + + // TODO test that certain things *don't* compile? + + return 0; +} diff --git a/external/flint-2.4.3/flintxx/test/t-flint_classes.cpp b/external/flint-2.4.3/flintxx/test/t-flint_classes.cpp new file mode 100644 index 0000000..389324b --- /dev/null +++ b/external/flint-2.4.3/flintxx/test/t-flint_classes.cpp @@ -0,0 +1,75 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#include +#include "flintxx/test/helpers.h" +#include "fmpzxx.h" + +using namespace flint; + +void +test_traits() +{ + using namespace flint_classes; + tassert((mp::equal_types::type, fmpzxx>::val)); + tassert((mp::equal_types::type, fmpzxx>::val)); + tassert((mp::equal_types::type, fmpzxx>::val)); + tassert((mp::equal_types::type, fmpzxx_ref>::val)); + tassert((mp::equal_types::type, fmpzxx_srcref>::val)); + tassert((mp::equal_types::type, fmpzxx_ref>::val)); + tassert((is_ref::val)); + tassert((is_ref::val)); + tassert((!is_ref::val)); + tassert((!is_ref::val)); + tassert((is_srcref::val)); + tassert((!is_srcref::val)); + tassert((!is_srcref::val)); + tassert(is_nonref::val); + tassert(!is_nonref::val); + tassert(!is_nonref::val); +} + + +fmpzxx_ref make_ref(fmpzxx& a) {return fmpzxx_ref(a);} +void +test_ref_lvalues() +{ + fmpzxx a(1); + fmpzxx_ref b(a); + b *= 2; + make_ref(a) *= 2; + tassert(a == 4); +} + +int +main() +{ + std::cout << "flint_classes...."; + + test_traits(); + test_ref_lvalues(); + + std::cout << "PASS" << std::endl; +} diff --git a/external/flint-2.4.3/flintxx/test/t-fmpq_matxx.cpp b/external/flint-2.4.3/flintxx/test/t-fmpq_matxx.cpp new file mode 100644 index 0000000..9064917 --- /dev/null +++ b/external/flint-2.4.3/flintxx/test/t-fmpq_matxx.cpp @@ -0,0 +1,340 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#include +#include +#include + +#include "fmpq_matxx.h" +#include "flintxx/test/helpers.h" + +using namespace flint; + +void +test_init() +{ + fmpq_matxx A(3, 4); + tassert(A.rows() == 3 && A.cols() == 4); + tassert(A.at(0, 0).is_zero()); + A.at(0, 0) = 1; + + fmpq_matxx B(A); + tassert(B.rows() == 3 && B.cols() == 4); + tassert(B.at(0, 0).is_one()); + B.at(0, 0) = 0; + tassert(A.at(0, 0).is_one()); + + tassert(fmpq_matxx::zero(3, 4).is_zero()); + fmpq_matxx eye = fmpq_matxx::one(4, 4); + for(slong i = 0;i < eye.rows();++i) + for(slong j = 0;j < eye.cols();++j) + tassert(eye.at(i, j) == fmpqxx::integer(int(i == j))); +} + +void +test_assignment() +{ + frandxx state; + fmpz_matxx A = fmpz_matxx::randtest(3, 4, state, 10); + fmpq_matxx Aq(A.rows(), A.cols()); + Aq = A; + tassert(Aq == fmpq_matxx::integer_matrix(A)); +} + +void +test_conversion() +{ + frandxx state; + fmpz_matxx A = fmpz_matxx::randtest(3, 4, state, 10); + fmpq_matxx Aq = fmpq_matxx::integer_matrix(A); + tassert(Aq.rows() == A.rows() && Aq.cols() == A.cols()); + for(slong i = 0;i < A.rows();++i) + for(slong j = 0;j < A.cols();++j) + tassert(Aq.at(i, j) == fmpqxx::integer(A.at(i, j))); + tassert(A == fmpz_matxx::from_integral_fraction(Aq)); + Aq.at(0, 0) = fmpqxx::frac(1, 2); + assert_exception(fmpz_matxx::from_integral_fraction(Aq)); + + tassert(Aq.numden_entrywise().get<0>().rows() == A.rows() + && Aq.numden_entrywise().get<0>().cols() == A.cols() + && Aq.numden_entrywise().get<1>().rows() == A.rows() + && Aq.numden_entrywise().get<1>().cols() == A.cols()); + + tassert(Aq.numden_matwise().get<0>().rows() == A.rows() + && Aq.numden_matwise().get<0>().cols() == A.cols()); + + tassert(Aq.numden_rowwise().get<0>().rows() == A.rows() + && Aq.numden_rowwise().get<0>().cols() == A.cols() + && Aq.numden_rowwise().get<1>().size() == A.rows()); + + tassert(Aq.numden_colwise().get<0>().rows() == A.rows() + && Aq.numden_colwise().get<0>().cols() == A.cols() + && Aq.numden_colwise().get<1>().size() == A.cols()); + + fmpz_matxx den(A.rows(), A.cols()); + for(slong i = 0;i < A.rows();++i) + for(slong j = 0;j < A.cols();++j) + den.at(i, j) = 1u; + den.at(0, 0) = 2u; + + A.at(0, 0) = 1; + tassert(Aq.numden_entrywise() == ltupleref(A, den)); + tassert(Aq.num_rowwise().at(0, 0) == 1); + tassert(Aq.num_colwise().at(0, 0) == 1); + tassert(Aq.numden_matwise().get<1>() == 2); + + fmpz_vecxx rowdens(A.rows()); + rowdens[0] = 2; + for(slong i = 1;i < A.rows();++i) + rowdens[i] = 1; + for(slong i = 1;i < A.cols();++i) + A.at(0, i) *= 2; + tassert(Aq.numden_rowwise() == ltupleref(A, rowdens)); + tassert(Aq.numden_colwise().get<1>()[0] == 2); +} + +template +bool has_explicit_temporaries(const Expr&) +{ + return Expr::ev_traits_t::rule_t::temporaries_t::len != 0; +} +void +test_arithmetic() +{ + fmpq_matxx A(10, 10); + fmpq_matxx v(10, 1); + for(int i = 0;i < 10;++i) + v.at(i, 0) = i; + + fmpzxx two(2); + tassert(transpose(v).rows() == 1); + tassert(v.transpose().cols() == 10); + tassert((two*v).rows() == 10); + tassert((v*two).rows() == 10); + tassert((v*transpose(v)).rows() == 10 && (v*transpose(v)).cols() == 10); + + tassert(!has_explicit_temporaries(trace(transpose(v)))); + tassert(!has_explicit_temporaries(trace(A + v*transpose(v)))); + tassert(!has_explicit_temporaries(A + v*transpose(v))); + tassert(!has_explicit_temporaries(trace((v*transpose(v) + A)))); + tassert(!has_explicit_temporaries(trace(v*transpose(v) + v*transpose(v)))); + tassert(!has_explicit_temporaries(v*transpose(v) + v*transpose(v))); + + tassert(trace(transpose(v)).is_zero()); + tassert(trace(A + v*transpose(v)) == fmpqxx(285, 1u)); + tassert(trace(v*transpose(v) + A) == fmpqxx(285, 1u)); + tassert(trace(v*transpose(v) + v*transpose(v)) == fmpqxx(2*285, 1u)); + tassert(trace((A+A)*(two + two)).is_zero()); + + for(int i = 0;i < 10; ++i) + for(int j = 0; j < 10; ++j) + A.at(i, j) = i*j; + tassert(A == v*transpose(v)); + tassert(A != transpose(v)*v); + A.at(0, 0) = 15; + tassert(A != v*transpose(v)); + + A.at(0, 0) = 0; + for(unsigned i = 0;i < 10; ++i) + for(unsigned j = 0; j < 10; ++j) + A.at(i, j) *= two; + tassert(A == v*transpose(v) + v*transpose(v)); + tassert(A - v*transpose(v) == v*transpose(v)); + tassert(((-A) + A).is_zero()); + tassert((A + A).at(0, 0) == A.at(0, 0) + A.at(0, 0)); + + tassert((A + A) == A*two); + tassert((two*A) / two == A); + + frandxx state; + A.set_randtest(state, 15); + fmpz_matxx B(A.rows(), A.cols()); + B.set_randtest(state, 15); + fmpq_matxx C(A.rows(), A.cols()); + for(slong i = 0;i < A.rows();++i) + for(slong j = 0;j < A.cols();++j) + C.at(i, j).num() = B.at(i, j); + tassert(C*A == B*A && A*C == A*B); + tassert(C.mul_direct(A) == C*A && C.mul_cleared(A) == C*A); +} + +void +test_functions() +{ + fmpq_matxx A(2, 3), B(2, 2), empty(0, 15); + B.at(0, 0) = 1; + tassert(A.is_zero() && !A.is_empty() && !A.is_square()); + tassert(!B.is_zero() == B.is_square()); + tassert(empty.is_zero() && empty.is_empty()); + + // transpose tested in arithmetic + // mul tested in arithmetic + // trace tested in arithmetic + + tassert(hilbert_matrix(4, 6).rows() == 4); + tassert(hilbert_matrix(4, 6).cols() == 6); + A.set_hilbert_matrix(); + fmpq_matxx H(hilbert_matrix(2, 3)); + tassert(A == H); + for(slong i = 0;i < A.rows();++i) + for(slong j = 0;j < A.rows();++j) + tassert(A.at(i, j).num() == 1 && A.at(i, j).den() == i + j + 1); + + tassert(A.is_integral() == false); + + frandxx rand; + fmpz_matxx Bp(B.rows(), B.cols()); + Bp.set_randtest(rand, 10); + for(slong i = 0;i < B.rows();++i) + for(slong j = 0;j < B.rows();++j) + B.at(i, j) = fmpqxx(Bp.at(i, j), fmpzxx(1)); + tassert(B.det().num() == Bp.det() && B.det().den() == 1); + + B.at(0, 0) = fmpqxx::randtest_not_zero(rand, 10); + B.at(0, 1) = 0; + B.at(1, 0) = fmpqxx::randtest(rand, 10); + B.at(1, 1) = fmpqxx::randtest_not_zero(rand, 10); + + tassert(B*B.solve_fraction_free(A) == A); + tassert(B*B.solve_dixon(A) == A); + fmpq_matxx eye(B.rows(), B.cols()); + for(slong i = 0;i < B.rows();++i) + eye.at(i, i) = 1; + tassert(B*B.inv() == eye); + + assert_exception(fmpq_matxx(2, 2).solve_fraction_free(A).evaluate()); + assert_exception(fmpq_matxx(2, 2).solve_dixon(A).evaluate()); + + // make sure this compiles + if(0) + print(B); +} + +void +test_extras() +{ + fmpq_matxx A(10, 10), B(10, 10); + frandxx rand; + A.set_randtest(rand, 15); + B.set_randtest(rand, 15); + A.at(0, 0) = B.at(0, 0) + fmpqxx(1, 1u); + + fmpq_matxx_srcref Asr(A); + fmpq_matxx_ref Br(B); + + tassert((A + A) + (B + B) == (Asr + Asr) + (Br + Br)); + + Br = Asr; + tassert(A == B); + + fmpq_matxx C(Asr); + tassert(C == A); + C.at(0, 0) += fmpqxx(2, 1u); + tassert(C != A); +} + +void +test_randomisation() +{ + frandxx rand; + fmpq_matxx A(2, 2); + A.set_randbits(rand, 5); + tassert(height(A.at(0, 0)) <= 31); + A.set_randtest(rand, 5); + tassert(height(A.at(0, 0)) <= 31); + + frandxx rand2, rand3; + A.set_randbits(rand2, 5); + tassert(A == fmpq_matxx::randbits(2, 2, rand3, 5)); + A.set_randtest(rand2, 5); + tassert(A == fmpq_matxx::randtest(2, 2, rand3, 5)); +} + +void +test_reduction_reconstruction() +{ + fmpq_matxx A(4, 7); + frandxx state; + A.set_randtest(state, 4); + fmpzxx M(UWORD(123457891)); + fmpz_matxx Ar = fmpz_matxx::reduce(A, M); + tassert(Ar.rows() == A.rows() && Ar.cols() == A.cols()); + for(slong i = 0;i < A.rows();++i) + for(slong j = 0;j < A.cols();++j) + tassert(Ar.at(i, j) == A.at(i, j) % M); + + tassert(A == fmpq_matxx::reconstruct(Ar, M)); + // TODO test exception +} + +void +test_row_reduction() +{ + frandxx state; + fmpq_matxx A = fmpq_matxx::randtest(5, 5, state, 15); + slong rank1, rank2; + permxx p1(5), p2(5); + fmpq_matxx res1(A.rows(), A.cols()), res2(A.rows(), A.cols()); + + fmpq_matxx B(A); + tassert(B.pivot(1, 1, &p1) == fmpq_mat_pivot(p1._data(), A._mat(), 1, 1)); + tassert(A == B); + + ltupleref(rank1, res1) = rref(A); + rank2 = fmpq_mat_rref(res2._mat(), A._mat()); + tassert(rank1 == rank2 && res1 == res2); + + tassert(rref_classical(A) == rref(A) && rref_fraction_free(A) == rref(A)); +} + +void +test_unified_access() +{ + fmpq_matxx A(2, 2); + const fmpq_matxx& Ar = A; + const fmpq_matxx_ref Ar2(A); + Ar2.at(0, 0) = fmpqxx::one(); + tassert(Ar.at(0, 0).is_one()); +} + +int +main() +{ + std::cout << "fmpq_matxx...."; + + test_init(); + test_assignment(); + test_conversion(); + test_arithmetic(); + test_functions(); + test_extras(); + test_randomisation(); + test_reduction_reconstruction(); + test_row_reduction(); + test_unified_access(); + + std::cout << "PASS" << std::endl; + return 0; +} diff --git a/external/flint-2.4.3/flintxx/test/t-fmpq_polyxx.cpp b/external/flint-2.4.3/flintxx/test/t-fmpq_polyxx.cpp new file mode 100644 index 0000000..513c0ef --- /dev/null +++ b/external/flint-2.4.3/flintxx/test/t-fmpq_polyxx.cpp @@ -0,0 +1,327 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#include +#include +#include + +#include "fmpq_polyxx.h" + +#include "flintxx/test/helpers.h" + +using namespace flint; + +void +test_init() +{ + fmpq_polyxx p(10); + tassert(p.length() == 0); + tassert(fmpq_polyxx::zero().is_zero()); + tassert(fmpq_polyxx::one().is_one()); +} + +void +test_manipulation() +{ + fmpq_polyxx p, q; + p.set_coeff(5, 17); + p.den() = 2; + tassert(p.degree() == 5); + q.set_coeff(5, fmpqxx(17, 2u)); + tassert((q + fmpq_polyxx()).get_coeff(5) == fmpqxx(17, 2u)); + p.set_coeff(0, fmpzxx(1)); + q.get_coeff_numref(0) = 2; + tassert(p == q); + tassert(q.is_canonical()); + + tassert(p.length() == 6); + + p.realloc(0); + tassert(p.is_zero() && !p.is_one()); + p.set_coeff(0, 1); + tassert(p.is_one()); + + tassert((p*q).den() == 2); +} + +void +test_assignment() +{ + fmpq_polyxx p, q; + p = 1; + tassert(p.is_one()); + q = UWORD(0); + tassert(q.is_zero()); + tassert(p != q); + p = q; + tassert(p == q); + + p = "4 0 0 0 1"; + q.set_coeff(3, 1); + tassert(p == q); + tassert(p == fmpq_polyxx("4 0 0 0 1")); + + // TODO XXX this does not always fail? + //assert_exception(p = "4 1 2"); + assert_exception(p = "2 1 2"); + assert_exception(fmpq_polyxx("2 1 2")); + + fmpz_polyxx pz; + pz = 1; + p = pz; + tassert(p.is_one()); + + p = fmpzxx(0); + tassert(p.is_zero()); + p = fmpqxx(1, UWORD(1)); + tassert(p.is_one()); +} + +void +test_conversion() +{ + fmpq_polyxx p; + p.set_coeff(3, fmpqxx(1, 2u)); + tassert(p.to_string() == "4 0 0 0 1/2"); + tassert(p.pretty("x") == "1/2*x^3"); +} + +void +test_arithmetic() +{ + fmpq_polyxx p, q; + p = 1; + q = 2; + tassert(p < q); + p.set_coeff(1, 1); + tassert(q < p); + + p = -2; + tassert(p == -q); + q = fmpqxx(-1, 2u); + tassert(inv(p) == q); + + p = 1; + q = "4 0 0 0 1"; + tassert((p + q).to_string() == "4 1 0 0 1"); + tassert((p - q).to_string() == "4 1 0 0 -1"); + tassert((-p).to_string() == "1 -1"); + + fmpzxx two(2); + fmpqxx twoq(2, 1u); + tassert(two * q == 2 * q && 2u * q == q * 2 && twoq * q == 2 * q + && (two * q).to_string() == "4 0 0 0 2"); + q *= 2; + tassert(q / two == q / 2u && q / 2 == q / two && q / twoq == q / 2u && + (q / two).to_string() == "4 0 0 0 1"); + // q == "4 0 0 0 2" + + q.set_coeff(1, 17); // q == "4 0 17 0 2" + + p = "3 1 0 1"; + tassert((p*q).to_string() == "6 0 17 0 19 0 2"); + + tassert((p*q) / p == q); + tassert(p + q % q == p); + + fmpqxx five(5, 1u), one(1, 1u); + tassert(p(one + one) == five); + tassert(p(fmpzxx(2)) == five); + q = "3 0 0 1"; + tassert(p(q).to_string() == "5 1 0 0 0 1"); + tassert(p(q) == compose(p, q)); + tassert(p(one) == evaluate(p, one)); + tassert(p(fmpzxx(1)) == evaluate(p, fmpzxx(1))); +} + +// Won't compile if the expression is not done using addmul +template +bool is_ternary(const T&) +{ + return T::ev_traits_t::temp_rule_t::TERNARY_OP_MARKER + 1; +} + +// test stuff which we should get automatically - addmul, references etc +void +test_extras() +{ + // TODO addmul when implemented + + // forwarded member functions + fmpq_polyxx f, g; + f = "4 1 2 3 4"; + g = "5 0 4 3 2 1"; + tassert(g.exp_series(10) == exp_series(g, 10)); + tassert(f.make_monic() == make_monic(f)); + tassert(f.derivative() == derivative(f)); + tassert(f.content() == content(f)); + tassert(f.divrem(g) == divrem(f, g)); + tassert(f.compose_series(g, 5) == compose_series(f, g, 5)); +} + +void +test_functions() +{ + fmpq_polyxx f, g, res, x; + x = "2 0 1"; + + f.set_coeff(5, 1); + f.set_coeff(0, 1); + tassert(fmpq_polyxx::get_slice(f, 0, 5).is_one()); + f.truncate(3); + tassert(f.is_one()); + + f = "4 1 2 3 4"; + g = "5 5 4 3 2 1"; + res = f*g; res.truncate(4); + tassert(res == mullow(f, g, 4)); + + tassert(reverse(g, 5).to_string() == "5 1 2 3 4 5"); + + tassert(pow(f, 5u) == f*f*f*f*f); + tassert(shift_left(f, 5) == f*pow(x, 5u)); + tassert(f == shift_right(shift_left(f, 5), 5)); + + fmpq_polyxx Q, R; + ltupleref(Q, R) = divrem(g, f); + tassert(Q*f + R == g); + + f = "2 1 -1"; + tassert(inv_series(f, 10).to_string() == "10 1 1 1 1 1 1 1 1 1 1"); + tassert(inv_series_newton(f, 20) == inv_series(f, 20)); + tassert(div_series(g, f, 10) * f % pow(x, 10u) == g); + + f = "4 2 0 0 1"; + g = "5 1 2 3 4 5"; + tassert(resultant(f, g) == fmpqxx(1797, 1u)); + tassert(gcd(f, g).is_one()); + tassert(lcm(f, g) == f*g / 5); + + fmpq_polyxx r, s, extra; + ltupleref(extra, r, s) = xgcd(f, g); + tassert(extra.is_one() && (r*f + s*g).is_one()); + + res = "6 0 1 1 1 1 1"; + tassert(derivative(res) == g); + tassert(integral(g) == res); + + tassert(pow(sqrt_series(g, 10), 2u) % pow(x, 7u) == g); + tassert((pow(invsqrt_series(g, 10), 2u)*g % pow(x, 7u)).is_one()); + + tassert(rescale(f, fmpqxx(2, 1u)).to_string() == "4 2 0 0 8"); + + fmpq_polyxx inner;inner = "3 0 -1 5"; + res = g(inner); res.truncate(10); + tassert(compose_series(g, inner, 10) == res); + tassert(compose_series_horner(g, inner, 10) == res); + tassert(compose_series_brent_kung(g, inner, 10) == res); + + res = "2 0 1"; + tassert(compose_series(inner, revert_series(inner, 10), 10) == res); + tassert(compose_series(inner, revert_series_lagrange(inner, 10), 10) + == res); + tassert(compose_series(inner, revert_series_lagrange_fast(inner, 10), 10) + == res); + tassert(compose_series(inner, revert_series_newton(inner, 10), 10) == res); + + tassert(content(2*g) == fmpqxx(2, 1u)); + tassert(primitive_part(2*g) == g); + + tassert(f.is_monic() && !g.is_monic()); + tassert(make_monic(2*f) == f); + tassert((4*g).is_squarefree());tassert(!(g*g).is_squarefree()); + + // test static functions + frandxx state; + tassert(fmpq_polyxx::randtest(state, 4, 10).length() <= 4); + tassert(fmpq_polyxx::randtest_unsigned(state, 4, 10).get_coeff_numref(0) >= 0); + tassert(fmpq_polyxx::randtest_not_zero(state, 4, 10).is_zero() == false); + + fmpz_vecxx xs(3), ys(3); + xs[0] = 0; xs[1] = 1; xs[2] = -1; + ys[0] = 0; ys[1] = 1; ys[2] = 1; + tassert(fmpq_polyxx::interpolate(xs, ys).to_string() == "3 0 0 1"); +} + +void +test_transcendental_series() +{ + fmpq_polyxx x, xp1; + x = "2 0 1"; + xp1 = "2 1 1"; + tassert(log_series(xp1, 5).to_string() == "5 0 1 -1/2 1/3 -1/4"); + tassert(atan_series(x, 5).to_string() == "4 0 1 0 -1/3"); + tassert(atanh_series(x, 5).to_string() == "4 0 1 0 1/3"); + tassert(asin_series(x, 5).to_string() == "4 0 1 0 1/6"); + tassert(asinh_series(x, 5).to_string() == "4 0 1 0 -1/6"); + + tassert(log_series(exp_series(x, 10), 10) % pow(x, 10u) == x); + tassert(sin_series(asin_series(x, 10), 10) % pow(x, 10u) == x); + tassert(tan_series(atan_series(x, 10), 10) % pow(x, 10u) == x); + tassert(sinh_series(asinh_series(x, 10), 10) % pow(x, 10u) == x); + tassert(((pow(cos_series(x, 10), 2u) + + pow(sin_series(x, 10), 2u)) % pow(x, 10u)).is_one()); + tassert(((pow(cosh_series(x, 10), 2u) + - pow(sinh_series(x, 10), 2u)) % pow(x, 10u)).is_one()); +} + +void +test_printing() +{ + frandxx state; + fmpq_polyxx f = fmpq_polyxx::randtest(state, 4, 10); + test_print_read(f); + f = "2 3 1"; + tassert_fprint_pretty(f, "x", "x+3"); +} + +void +test_unified_access() +{ + fmpq_polyxx f; + const fmpq_polyxx& g = f; + tassert(g.den().is_one()); +} + +int +main() +{ + std::cout << "fmpq_polyxx...."; + + test_init(); + test_manipulation(); + test_assignment(); + test_conversion(); + test_arithmetic(); + test_functions(); + test_transcendental_series(); + test_extras(); + test_printing(); + test_unified_access(); + + std::cout << "PASS" << std::endl; + return 0; +} + diff --git a/external/flint-2.4.3/flintxx/test/t-fmpqxx.cpp b/external/flint-2.4.3/flintxx/test/t-fmpqxx.cpp new file mode 100644 index 0000000..c5c26db --- /dev/null +++ b/external/flint-2.4.3/flintxx/test/t-fmpqxx.cpp @@ -0,0 +1,248 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#include +#include +#include + +#include "fmpqxx.h" +#include "fmpz_vecxx.h" + +#include "flintxx/test/helpers.h" + +using namespace flint; + +void +test_init() +{ + fmpqxx a, b = fmpqxx::frac(6, fmpzxx(10)), + c = fmpqxx::frac((unsigned short)6, 10u); + + tassert(a.num() == 0 && a.den() == 1); + tassert(b.num() == 3 && b.den() == 5); + tassert(c.num() == 3 && c.den() == 5); + + a.num() = -2; + a.den() = 4; + tassert(!a.is_canonical()); + a.canonicalise(); + tassert(a.num() == -1 && a.den() == 2); + + tassert(fmpqxx::frac("4", 2) == fmpqxx::integer(-fmpzxx(-2))); + + tassert(fmpqxx::zero().is_zero() && fmpqxx::one().is_one()); +} + +void +test_assignment() +{ + fmpqxx a; + fmpqxx b = fmpqxx::frac("100000000000000000000", "100000000000000000001"); + fmpqxx c(b); + a = b; + tassert(a == b && c == b); + tassert(a.num()._fmpz()[0] != b.num()._fmpz()[0]); + tassert(a.den()._fmpz()[0] != b.den()._fmpz()[0]); + tassert(c.num()._fmpz()[0] != b.num()._fmpz()[0]); + tassert(c.den()._fmpz()[0] != b.den()._fmpz()[0]); + + a = 7; + tassert(a.num() == 7 && a.den() == 1); + a = (unsigned short)8; + tassert(a.num() == 8 && a.den() == 1); +} + +void +test_conversion() +{ + fmpqxx a = fmpqxx::frac(3, 5); + tassert(a.to_string() == "3/5"); + tassert(a.to_string(5) == "3/10"); + + std::ostringstream oss; + oss << a; + tassert(oss.str() == "3/5"); + + tassert((a + a).num() == 6); + tassert((a * a).den() == 25); +} + +void test_order() +{ + fmpqxx a(0, 1u), b(1, 1u); + tassert(a < b); + tassert(a <= a); + tassert(b > a); + tassert(b >= b); + tassert(a == a); + tassert(a != b); +} + +void +test_arithmetic() +{ + fmpqxx a(3, 5u), b(2, 7u); + fmpzxx c(2); + + tassert(a + b == fmpqxx::frac(3*7 + 2*5, 35u)); + tassert(a * b == fmpqxx::frac(6, 35u)); + tassert(a - b == fmpqxx::frac(3*7 - 5*2, 35u)); + tassert(a / b == fmpqxx::frac(3*7, 10u)); + + tassert((a+a) * (c+c) == fmpqxx::frac(24, 5u)); + tassert(c * a == fmpqxx::frac(6, 5u)); + tassert(a / c == fmpqxx::frac(3, 10u)); + + tassert(-a == fmpqxx::frac(-3, 5u)); + + tassert(((a << 5) >> 4) == fmpzxx(2)*a); +} + +// Won't compile if the expression is not done using addmul +template +bool is_ternary(const T&) +{ + return T::ev_traits_t::temp_rule_t::TERNARY_OP_MARKER + 1; +} + +// test stuff which we should get automatically - addmul, references etc +void +test_extras() +{ + fmpqxx a(3, 5u), b(2, 7u), c(3, 1u); + tassert(is_ternary((a+a) - b*c)); + tassert(is_ternary(b*c + (a+a))); + tassert((a+a) - b*c == fmpqxx::frac(6*7 - 5*6, 5u*7u)); + tassert(b*c + (a+a) == fmpqxx::frac(6*7 + 5*6, 5u*7u)); + + fmpqxx_ref ar(a); + fmpqxx_srcref asr(a); + tassert(a == ar && ar == asr); + ar = 3; + tassert(a == c && asr == c); + + tassert((-a) + a == fmpqxx::frac(0, 0u)); + + tassert(a.pow(3) == pow(a, 3)); + tassert(a.height() == height(a)); +} + +void +test_functions() +{ + fmpqxx a(-3, 5u); + + // test lazy functions + tassert(abs(a) == -a); + tassert(height(a) == 5); + tassert(a % fmpzxx(7) == 5); + assert_exception((a % fmpzxx(5)).evaluate()); + + // test immediate functions + tassert(height_bits(a) == 3); + tassert((inv(a)*a).is_one()); + tassert(sgn(a) == -1 && sgn(-a) == 1 && sgn(fmpqxx::frac(0, 0u)) == 0); + + // test member functions + const fmpqxx zero(0, 0u), one(1, 1u); + tassert(zero.is_zero() && !zero.is_one()); + tassert(!one.is_zero() && one.is_one()); + tassert(pow(a, -3) == inv(a*a*a)); + tassert(zero.next_minimal().next_minimal().next_minimal() == fmpqxx::frac(2, 1u)); + tassert(zero.next_signed_minimal().next_signed_minimal() == fmpqxx::frac(-1, 1u)); + tassert(zero.next_calkin_wilf().next_calkin_wilf() == fmpqxx::frac(1, 2u)); + tassert(zero.next_signed_calkin_wilf().next_signed_calkin_wilf() + == fmpqxx::frac(-1, 1u)); + + // test static member functions + frandxx rand; + tassert(abs(fmpqxx::randbits(rand, 5).den()) <= 31); + // NB: rand stuff comes from a single macro, no need for further testing + tassert(a == fmpqxx::reconstruct( + a % fmpzxx(41), fmpzxx(41), fmpzxx(3), fmpzxx(5))); + assert_exception(fmpqxx::reconstruct( + a % fmpzxx(7), fmpzxx(7), fmpzxx(1), fmpzxx(1)).evaluate()); + tassert(a == fmpqxx::reconstruct(a % fmpzxx(71), fmpzxx(71))); + assert_exception(fmpqxx::reconstruct(a % fmpzxx(7), fmpzxx(7)).evaluate()); + + // test partial fractions + fmpz_vecxx v(5); + fmpqxx tmp(7, 5u); + fmpqxx rem; + tassert(tmp == fmpqxx::from_cfrac(v, get_cfrac(v, rem, tmp))); + tassert(rem.is_zero()); + tassert(3 <= tmp.cfrac_bound()); + + // test swap + a = 1; + fmpqxx b(zero); + swap(a, b); + tassert(a.is_zero() && b.is_one()); + + tassert_fprint(fmpqxx::frac(7, 29), "7/29"); +} + +void +test_vector() +{ + fmpq_vecxx v1(10), v2(10), v3(1); + tassert(v1 == v2); + tassert(v1 != v3); + v1[0] = fmpqxx::frac(1, 1u); + tassert(v1 != v2); + v2[0] = v1[0]; + tassert(v1 == v2); +} + +void +test_unified_access() +{ + fmpqxx a = fmpqxx::frac(1, 2); + const fmpqxx& b = a; + tassert(b.num() == 1); + const fmpqxx_ref c(a); + c.num() = 3; + tassert(c.num() == 3); +} + +int +main() +{ + std::cout << "fmpqxx...."; + + test_init(); + test_assignment(); + test_conversion(); + test_order(); + test_arithmetic(); + test_functions(); + test_extras(); + test_vector(); + test_unified_access(); + + std::cout << "PASS" << std::endl; + return 0; +} + diff --git a/external/flint-2.4.3/flintxx/test/t-fmpz_matxx.cpp b/external/flint-2.4.3/flintxx/test/t-fmpz_matxx.cpp new file mode 100644 index 0000000..30f271b --- /dev/null +++ b/external/flint-2.4.3/flintxx/test/t-fmpz_matxx.cpp @@ -0,0 +1,304 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#include +#include +#include + +#include "fmpz_matxx.h" +#include "fmpz_vecxx.h" +#include "flintxx/test/helpers.h" + +using namespace flint; + +void +test_init() +{ + fmpz_matxx A(3, 4); + tassert(A.rows() == 3 && A.cols() == 4); + tassert(A.at(0, 0) == 0); + A.at(0, 0) = 1; + + fmpz_matxx B(A); + tassert(B.rows() == 3 && B.cols() == 4); + tassert(B.at(0, 0) == 1); + B.at(0, 0) = 0; + tassert(A.at(0, 0) == 1); + + tassert(fmpz_matxx::zero(3, 4).is_zero()); + fmpz_matxx eye = fmpz_matxx::one(4, 4); + for(slong i = 0;i < eye.rows();++i) + for(slong j = 0;j < eye.cols();++j) + tassert(eye.at(i, j) == int(i == j)); +} + +template +bool has_explicit_temporaries(const Expr&) +{ + return Expr::ev_traits_t::rule_t::temporaries_t::len != 0; +} +template +bool compare_temporaries(const Expr&) +{ + return mp::equal_types::val; +} +void +test_arithmetic() +{ + fmpz_matxx A(10, 10); + fmpz_matxx v(10, 1); + for(unsigned i = 0;i < 10;++i) + v.at(i, 0) = i; + + tassert(transpose(v).rows() == 1); + tassert(v.transpose().cols() == 10); + tassert((2*v).rows() == 10); + tassert((v*2).rows() == 10); + tassert((v*transpose(v)).rows() == 10 && (v*transpose(v)).cols() == 10); + tassert(mul_classical(v, transpose(v)).rows() == 10); + tassert(mul_multi_mod(v, transpose(v)).cols() == 10); + + tassert(!has_explicit_temporaries(trace(transpose(v)))); + tassert(!has_explicit_temporaries(trace(A + v*transpose(v)))); + tassert(!has_explicit_temporaries(A + v*transpose(v))); + tassert(!has_explicit_temporaries(trace((v*transpose(v) + A)))); + tassert(!has_explicit_temporaries(trace(v*transpose(v) + v*transpose(v)))); + tassert(!has_explicit_temporaries(v*transpose(v) + v*transpose(v))); + tassert((compare_temporaries >( + ((A+A)*(fmpzxx(1)+fmpzxx(1)))))); + + tassert(trace(transpose(v)) == 0); + tassert(trace(A + v*transpose(v)) == 285); + tassert(trace(v*transpose(v) + A) == 285); + tassert(trace(v*transpose(v) + v*transpose(v)) == 2*285); + tassert(trace((A+A)*(fmpzxx(1) + fmpzxx(1))) == 0); + + for(unsigned i = 0;i < 10; ++i) + for(unsigned j = 0; j < 10; ++j) + A.at(i, j) = i*j; + tassert(A == v*transpose(v)); + tassert(A != transpose(v)*v); + A.at(0, 0) = 15; + tassert(A != v*transpose(v)); + + A.at(0, 0) = 0; + for(unsigned i = 0;i < 10; ++i) + for(unsigned j = 0; j < 10; ++j) + A.at(i, j) *= 2; + tassert(A == v*transpose(v) + v*transpose(v)); + tassert(A - v*transpose(v) == v*transpose(v)); + tassert(((-A) + A).is_zero()); + tassert((A + A).at(0, 0) == A.at(0, 0) + A.at(0, 0)); + + tassert((A + A) == 2*A && A*2 == A*2u && fmpzxx(2)*A == 2u*A); + tassert((2*A).divexact(2) == A); + tassert((2*A).divexact(2u) == A); + tassert((2*A).divexact(fmpzxx(2)) == A); +} + +void +test_functions() +{ + fmpz_matxx A(2, 3), B(2, 2), empty(0, 15); + B.at(0, 0) = 1; + tassert(A.is_zero() && !A.is_empty() && !A.is_square()); + tassert(!B.is_zero() == B.is_square()); + tassert(empty.is_zero() && empty.is_empty()); + + // transpose tested in arithmetic + // mul tested in arithmetic + // trace tested in arithmetic + + frandxx rand; + A.set_randtest(rand, 10); + B.set_randtest(rand, 10); + tassert(B*A == mul_classical(B, A)); + tassert(B*A == mul_multi_mod(B, A)); + + tassert(sqr(B) == B*B); + tassert(B.sqr().sqr() == pow(B, 4u)); + + B.set_randrank(rand, 1, 10); + tassert(!inv(B).get<0>()); + + B.set_randdet(rand, fmpzxx(2*3*5)); + tassert(B.det() == 2*3*5); + fmpz_matxx Binv(2, 2); bool worked; fmpzxx d; + ltupleref(worked, Binv, d) = inv(B); + tassert(worked && d.divisible(fmpzxx(2*3*5))); + fmpz_matxx eye(2, 2);eye.at(0, 0) = 1;eye.at(1, 1) = 1; + tassert((Binv * B).divexact(d) == eye); + + B.set_randdet(rand, fmpzxx(105)); + tassert(B.det() == B.det_bareiss()); + tassert(B.det() == B.det_cofactor()); + tassert(abs(B.det()) <= B.det_bound()); + tassert(B.det().divisible(B.det_divisor())); + tassert(B.det() == B.det_modular(true)); + tassert(B.det() == B.det_modular_accelerated(true)); + tassert(B.det() == B.det_modular_given_divisor(fmpzxx(1), true)); + + tassert(B.charpoly().get_coeff(0) == B.det()); + tassert(charpoly(B).get_coeff(1) == -B.trace()); + tassert(charpoly(B).lead() == 1); + + A.set_randrank(rand, 2, 10); + tassert(rank(A) == 2); + + fmpz_matxx X(2, 3); + ltupleref(worked, X, d) = solve(B, A); + tassert(worked == true && (B*X).divexact(d) == A); + ltupleref(worked, X, d) = B.solve_fflu(A); + tassert(worked == true && (B*X).divexact(d) == A); + ltupleref(worked, X, d) = B.solve_cramer(A); + tassert(worked == true && (B*X).divexact(d) == A); + tassert(solve(B, A).get<1>() == X); + + slong nullity;fmpz_matxx C(3, 3); + tassert(nullspace(A).get<1>().rows() == 3); + tassert(nullspace(A).get<1>().cols() == 3); + ltupleref(nullity, C) = nullspace(A); + tassert(nullity == 3 - rank(A)); + tassert(C.rank() == nullity); + tassert((A*C).is_zero()); + + // TODO test solve_dixon, solve_bound +} + +void +test_extras() +{ + fmpz_matxx A(10, 10), B(10, 10); + frandxx rand; + A.set_randtest(rand, 15); + B.set_randtest(rand, 15); + A.at(0, 0) = B.at(0, 0) + 1u; + + fmpz_matxx_srcref Asr(A); + fmpz_matxx_ref Br(B); + + tassert((A + A) + (B + B) == (Asr + Asr) + (Br + Br)); + + Br = Asr; + tassert(A == B); + + fmpz_matxx C(Asr); + tassert(C == A); + C.at(0, 0) += 2u; + tassert(C != A); +} + +void +test_randomisation() +{ + frandxx rand; + fmpz_matxx A = fmpz_matxx::randbits(2, 2, rand, 5); + tassert(abs(A.at(0, 0)) <= 31 && abs(A.at(0, 0)) >= 16); + A.set_randtest(rand, 5); + tassert(abs(A.at(0, 0)) <= 31); + fmpz_matxx::randtest(2, 2, rand, 5); + + fmpz_matxx B(2, 3); + B.set_randintrel(rand, 5); + tassert(abs(B.at(0, 0)) <= 31); + + A.set_randsimdioph(rand, 5, 6); + tassert(A.at(0, 0) == 64 && abs(A.at(0, 1)) <= 31); + tassert(A.at(1, 0) == 0 && A.at(1, 1) == 32); + + // TODO set_randntrulike, set_randntrulike2, set_randajtai + + fmpz_vecxx v(2);v[0] = 5;v[1] = 7; + A.set_randpermdiag(rand, v); + tassert(A.at(0, 0) + A.at(0, 1) + A.at(1, 0) + A.at(1, 1) == 5 + 7); + + A.set_randrank(rand, 1, 5); + tassert(abs(A.at(0, 0)) <= 31 && A.rank() == 1); + tassert(rank(fmpz_matxx::randrank(5, 6, rand, 3, 10)) == 3); + A.apply_randops(rand, 17); + tassert(abs(A.at(0, 0)) <= 31 && A.rank() == 1); + + A.set_randdet(rand, fmpzxx(17)); + tassert(det(A) == 17); + tassert(fmpz_matxx::randdet(5, 5, rand, fmpzxx(123)).det() == 123); +} + +void +test_row_reduction() +{ + frandxx state; + fmpz_matxx A = fmpz_matxx::randtest(5, 5, state, 15); + slong rank1, rank2; + fmpzxx den1, den2; + fmpz_matxx res1(A.rows(), A.cols()), res2(A.rows(), A.cols()); + + tassert(find_pivot_any(A, 2, 4, 1) + == fmpz_mat_find_pivot_any(A._mat(), 2, 4, 1)); + tassert(A.fflu(0, false).get<1>().rows() == A.rows()); + permxx p1(5), p2(5); + ltupleref(rank1, res1, den1) = fflu(A, &p1); + rank2 = fmpz_mat_fflu(res2._mat(), den2._fmpz(), p2._data(), + A._mat(), false); + tassert(rank1 == rank2 && res1 == res2 && p1 == p2 && den1 == den2); + tassert(rank1 == A.fflu(0, false).get<0>()); + + ltupleref(rank1, res1, den1) = rref(A); + rank2 = fmpz_mat_rref(res2._mat(), den2._fmpz(), A._mat()); + tassert(rank1 == rank2 && res1 == res2 && den1 == den2); + + fmpz_matxx B(A); + fmpzxx n(1031); + A.set_rref_mod(n, &p1); + fmpz_mat_rref_mod(p2._data(), B._mat(), n._fmpz()); + tassert(A == B && p1 == p2); +} + +void +test_printing() +{ + frandxx rand; + fmpz_matxx A = fmpz_matxx::randtest(2, 2, rand, 5); + test_print_read(A); + A.set_one(); + tassert_fprint_pretty(A, "[[1 0]\n[0 1]\n]"); +} + +int +main() +{ + std::cout << "fmpz_matxx...."; + + test_init(); + test_arithmetic(); + test_functions(); + test_extras(); + test_randomisation(); + test_row_reduction(); + test_printing(); + + std::cout << "PASS" << std::endl; + return 0; +} diff --git a/external/flint-2.4.3/flintxx/test/t-fmpz_mod_polyxx.cpp b/external/flint-2.4.3/flintxx/test/t-fmpz_mod_polyxx.cpp new file mode 100644 index 0000000..83ad354 --- /dev/null +++ b/external/flint-2.4.3/flintxx/test/t-fmpz_mod_polyxx.cpp @@ -0,0 +1,394 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#include +#include +#include + +#include "fmpz_mod_polyxx.h" + +#include "flintxx/test/helpers.h" + +using namespace flint; + +void +test_init() +{ + fmpz_mod_polyxx p(fmpzxx(2003)); + tassert(p.length() == 0); + tassert(p.modulus() == 2003); + tassert(fmpz_mod_polyxx::zero(fmpzxx(2003)).is_zero()); +} + +void +test_manipulation() +{ + fmpzxx M(1031); + fmpz_mod_polyxx p(M), q(M); + p.set_coeff(5, 17u + M); + tassert(p.degree() == 5); + q.set_coeff(5, fmpzxx(16) + fmpzxx(1)); + tassert((q + fmpz_mod_polyxx(M)).get_coeff(5) == 17); + p.set_coeff(0, 1); + tassert(p != q); + p.set_coeff(0, 0); + tassert(p == q); + + tassert((p + p).lead() == 2*p.lead()); + + q.lead() = 0; + q._normalise(); + tassert(q.is_zero()); + + p.realloc(0); + tassert(p.is_zero()); +} + +void +test_assignment() +{ + fmpzxx M(31); + fmpz_mod_polyxx p(M), q(M); + p.set_coeff(0, 1); + tassert(p != q); + p = q; + tassert(p == q); +} + +void +test_conversion() +{ + fmpzxx M(1031); + fmpz_mod_polyxx p(M); + + p = 4u + 1031; + tassert(p.length() == 1 && p.get_coeff(0) == 4); + + p = fmpzxx(5) + M; + tassert(p.length() == 1 && p.get_coeff(0) == 5); + + frandxx rand; + fmpz_polyxx P = fmpz_polyxx::randtest(rand, 10, 20); + p = P; + for(slong i = 0;i < P.length();++i) + tassert(P.get_coeff(i) % M == p.get_coeff(i)); + fmpz_polyxx Pp = p.to(); + for(slong i = 0;i < P.length();++i) + tassert(P.get_coeff(i) % M == Pp.get_coeff(i)); +} + +void +test_arithmetic() +{ + fmpzxx M(1031); + fmpz_mod_polyxx g(M), h(M); + g.set_coeff(0, 17); h.set_coeff(0, 15u + M); + tassert((g + h).get_coeff(0) == 15 + 17); + + frandxx state; + g.set_randtest(state, 10); + h.set_randtest(state, 10); + + tassert(((-g) + g).is_zero()); + tassert(g - h == g + (-h)); + + tassert(g*fmpzxx(3) == g + g + g); + tassert(g.make_monic() == g*g.lead().invmod(M)); + + fmpz_mod_polyxx f(M);f = 15u; + tassert(f*g == fmpzxx(15)*g); + + f = h*g;f.truncate(7); + tassert(f == mullow(h, g, 7)); + + f = h / g; + tassert(f*g + (h % g) == h); + tassert(((h*g) % h).is_zero()); + + f.set_randtest(state, 10); + tassert(h.mulmod(g, f) == ((h*g) % f)); + + fmpz_mod_polyxx X(M);X.set_coeff(1, 1); + fmpz_mod_polyxx one(M);one.set_coeff(0, 1); + f = X*X + one; + fmpzxx x(7); + tassert(evaluate(f, x) == x*x + 1u); + tassert(f(x) == evaluate(f, x)); + + fmpz_mod_polyxx seven(M); + seven.set_coeff(0, x); + tassert(compose(f, seven).get_coeff(0) == f(x)); + tassert(f(seven).length() == 1); +} + +void +test_functions() +{ + fmpzxx M(1031); + fmpz_mod_polyxx g(M), res(M); + + g.set_coeff(5, 15); + + g.truncate(3); + tassert(g.is_zero()); + + g.set_coeff(15, 1); + fmpz_mod_polyxx one(M);one = 1u; + tassert(g.shift_right(15) == one); + tassert(g.shift_right(15).shift_left(15) == g); + + frandxx rand; + g.set_randtest(rand, 15); + tassert(g.length() <= 15); + g.set_randtest_irreducible(rand, 15); + tassert(g.length() <= 15); + g.set_randtest_not_zero(rand, 15); + tassert(g.length() <= 15 && !g.is_zero()); + + g.set_coeff(15, 1); + g.zero_coeffs(14, 15); + tassert(g.get_coeff(14) == 0); + + + // multiplication, division, modulo tested in arithmetic + + tassert(g.pow(3u) == g*g*g); + + res = g.pow(15u);res.truncate(12); + tassert(res == g.pow_trunc(15u, 12)); + tassert(res == g.pow_trunc_binexp(15u, 12)); + + fmpz_mod_polyxx f(M);f.set_randtest(rand, 10); + res = g.pow(10u) % f; + tassert(res == g.powmod_binexp(10u, f)); + tassert(res == g.powmod_binexp(fmpzxx(10), f)); + + fmpz_mod_polyxx tmp(M); + ltupleref(res, tmp) = f.gcdinv(g); + tassert(res == gcd(f, g) && tmp*f % g == res); + + g.set_randtest_irreducible(rand, 5); + tassert(f.invmod(g)*f % g == one); + assert_exception((f*g).invmod(g).evaluate()); + + res = g*f; + res.remove(f); + tassert(res == g); + + fmpz_polyxx lift; + lift = "5 1 1 1 1 1"; + res = lift; + tassert(res.derivative().to().to_string() == "4 1 2 3 4"); + + tassert(f.divrem(g) == ltuple(f / g, f % g)); + tassert(f.divrem_basecase(g) == f.divrem(g)); + tassert(f.divrem_divconquer(g) == f.divrem(g)); + tassert(f.divrem_f(g) == ltuple(1, f / g, f % g)); + + tassert(f.div_basecase(g) == f / g); + tassert(f.rem_basecase(g) == f % g); + + f.set_coeff(0, 17); + res = f*f.inv_series_newton(15);res.truncate(15); + tassert(res == one); + + tassert(f(g) == f.compose_divconquer(g)); + tassert(f(g) == f.compose_horner(g)); + + fmpz_mod_polyxx h(M); + h.set_randtest(rand, 15); + tassert(f.compose_mod(g, h) == f(g) % h); + tassert(f.compose_mod(g, h) == f.compose_mod_horner(g, h)); + tassert(f.compose_mod(g, h) == f.compose_mod_brent_kung(g, h)); + + h.set_randtest_irreducible(rand, 12); + tassert(h.gcd(f) == one); + tassert(f.gcd_euclidean(f) == f.make_monic()); + tassert(f.gcd_f(g) == ltuple(1, f.gcd(g))); + tassert(f.gcd_euclidean_f(g) == ltuple(1, f.gcd(g))); + + fmpz_mod_polyxx R(M), S(M); + ltupleref(res, R, S) = f.xgcd(g); + tassert(res == R*f + S*g && res == gcd(f, g)); + tassert(f.xgcd(g) == f.xgcd_euclidean(g)); + +} + +bool equiv_fac(const fmpz_mod_poly_factorxx& fac1, + const fmpz_mod_poly_factorxx& fac2) +{ + tassert(fac1.size() == 2); + if(fac1.exp(0) == fac1.exp(1)) + { + if(fac2.exp(0) != fac1.exp(0) || fac2.exp(1) != fac1.exp(0)) + return false; + return (fac1.p(0) == fac2.p(0) && fac1.p(1) == fac2.p(1)) + || (fac1.p(1) == fac2.p(0) && fac1.p(0) == fac2.p(1)); + } + if(fac1.size() != fac2.size()) + return false; + if(fac1.exp(0) == fac2.exp(0)) + return fac1.exp(1) == fac2.exp(1) + && fac1.p(0) == fac2.p(0) + && fac1.p(1) == fac2.p(1); + else + return fac1.exp(0) == fac2.exp(1) + && fac1.exp(1) == fac2.exp(0) + && fac1.p(0) == fac2.p(1) + && fac1.p(1) == fac2.p(0); +} +void +test_factoring() +{ + fmpzxx M(1031); + fmpz_mod_polyxx f(M), g(M); + frandxx state; + f.set_randtest_irreducible(state, 4); f = f.make_monic(); + g.set_randtest_irreducible(state, 5); g = g.make_monic(); + + fmpz_mod_poly_factorxx fac = factor(f*f*g); + tassert(fac.size() == 2); + if(fac.exp(0) == 1) + { + tassert(fac.p(0) == g); + tassert(fac.p(1) == f && fac.exp(1) == 2); + } + else + { + tassert(fac.p(0) == f && fac.exp(0) == 2); + tassert(fac.p(1) == g && fac.exp(1) == 1); + } + + fmpz_mod_poly_factorxx fac2;fac2 = fac;fac2.pow(2); + fac.insert(g, 1); + fac.insert(f, 2); + tassert(fac == fac2); + + fmpz_mod_polyxx prod(f*f*f*g*g); + fac = factor(prod); + tassert(equiv_fac(fac, factor_cantor_zassenhaus(prod))); + tassert(equiv_fac(factor(f*g), factor_berlekamp(f*g))); + tassert(equiv_fac(fac, factor_kaltofen_shoup(prod))); + + std::vector degs(2); + fac.realloc(0);fac.set_factor_distinct_deg(f*g, degs); + tassert(degs.size() == 2); + tassert((degs[0] == f.degree() && degs[1] == g.degree()) + || (degs[1] == f.degree() && degs[0] == g.degree())); + + tassert(f.is_irreducible() && f.is_irreducible_ddf() + && f.is_irreducible_rabin()); + tassert(f.is_squarefree()); + // TODO test set_factor_equal_deg* + + if(0) + print(fac); // test this compiles +} + +void +test_randomisation() +{ + frandxx state, state2; + fmpzxx M(1031); + fmpz_mod_polyxx p(M); + + p.set_randtest(state, 10); + tassert(p == fmpz_mod_polyxx::randtest(M, state2, 10)); + p.set_randtest_irreducible(state, 10); + tassert(p == fmpz_mod_polyxx::randtest_irreducible(M, state2, 10)); + p.set_randtest_not_zero(state, 10); + tassert(p == fmpz_mod_polyxx::randtest_not_zero(M, state2, 10)); +} + +void +test_radix() +{ + fmpzxx M(1031); + fmpz_mod_poly_vecxx v1(10, M), v2(10, M); + v1[0].set_coeff(7, 1); + tassert(v1 != v2); + fmpz_mod_poly_vecxx v3(v1); + tassert(v3 == v1); + v3[0].set_coeff(1, 1); + tassert(v3 != v1); + v2[0].set_coeff(7, 1); + tassert(v1 == v2); + + frandxx rand; + fmpz_mod_polyxx F = fmpz_mod_polyxx::randtest(M, rand, 10); + fmpz_mod_polyxx R = fmpz_mod_polyxx::randtest(M, rand, 3); + fmpz_mod_poly_vecxx b(F.degree() / R.degree() + 1, M); + fmpz_mod_poly_radixxx rad(R, 15); + b = F.radix(rad); + tassert(b == F.radix(rad)); + + fmpz_mod_polyxx f(M); + for(slong i = 0;i < b.size();++i) + f += b[i]*R.pow(static_cast(i)); + tassert(f == F); +} + +void +test_printing() +{ + frandxx state; + fmpz_mod_polyxx f = fmpz_mod_polyxx::randtest(fmpzxx(7), state, 4); + test_print_read(f); + f.set_zero(); + f.set_coeff(0, 3); + f.set_coeff(1, 1); + tassert_fprint_pretty(f, "x", "x+3"); +} + +void +test_unified_access() +{ + fmpz_mod_polyxx p(fmpzxx(1031)); + p.set_coeff(0, 1); + const fmpz_mod_polyxx& q = p; + tassert(q.lead() == 1); +} + +int +main() +{ + std::cout << "fmpz_mod_polyxx...."; + + test_init(); + test_manipulation(); + test_assignment(); + test_conversion(); + test_arithmetic(); + test_functions(); + test_factoring(); + test_randomisation(); + test_radix(); + test_printing(); + test_unified_access(); + + std::cout << "PASS" << std::endl; + return 0; +} + diff --git a/external/flint-2.4.3/flintxx/test/t-fmpz_poly_matxx.cpp b/external/flint-2.4.3/flintxx/test/t-fmpz_poly_matxx.cpp new file mode 100644 index 0000000..39eae5e --- /dev/null +++ b/external/flint-2.4.3/flintxx/test/t-fmpz_poly_matxx.cpp @@ -0,0 +1,292 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#include +#include +#include + +#include "fmpz_poly_matxx.h" +#include "flintxx/test/helpers.h" + +using namespace flint; + +void +test_init() +{ + fmpz_poly_matxx A(3, 4); + tassert(A.rows() == 3 && A.cols() == 4); + tassert(A.at(0, 0) == fmpz_polyxx::from_ground(0)); + A.at(0, 0) = fmpz_polyxx::from_ground(1); + + fmpz_poly_matxx B(A); + tassert(B.rows() == 3 && B.cols() == 4); + tassert(B.at(0, 0) == fmpz_polyxx::from_ground(1)); + B.at(0, 0) = fmpz_polyxx::from_ground(0); + tassert(A.at(0, 0) == fmpz_polyxx::from_ground(1)); + + tassert(fmpz_poly_matxx::zero(3, 3).is_zero()); + tassert(fmpz_poly_matxx::one(3, 3).is_one()); +} + +template +bool has_explicit_temporaries(const Expr&) +{ + return Expr::ev_traits_t::rule_t::temporaries_t::len != 0; +} +void +test_arithmetic() +{ + fmpz_poly_matxx A(10, 10); + fmpz_poly_matxx v(10, 1); + for(unsigned i = 0;i < 10;++i) + v.at(i, 0) = fmpz_polyxx::from_ground(i); + + tassert(transpose(v).rows() == 1); + tassert(v.transpose().cols() == 10); + tassert((fmpzxx(2)*v).rows() == 10); + tassert((v*fmpzxx(2)).rows() == 10); + tassert((v*transpose(v)).rows() == 10 + && (v*transpose(v)).cols() == 10); + tassert(mul_classical(v, transpose(v)).rows() == 10); + tassert(mul_KS(v, transpose(v)).cols() == 10); + + tassert(!has_explicit_temporaries(trace(transpose(v)))); + tassert(!has_explicit_temporaries(trace(A + v*transpose(v)))); + tassert(!has_explicit_temporaries(A + v*transpose(v))); + tassert(!has_explicit_temporaries(trace((v*transpose(v) + A)))); + tassert(!has_explicit_temporaries(trace(v*transpose(v) + v*transpose(v)))); + tassert(!has_explicit_temporaries(v*transpose(v) + v*transpose(v))); + + tassert((transpose(v)).trace() == fmpz_polyxx::from_ground(0)); + tassert(trace(A + v*transpose(v)) == fmpz_polyxx::from_ground(285)); + tassert(trace(v*transpose(v) + A) == fmpz_polyxx::from_ground(285)); + tassert(trace(v*transpose(v) + v*transpose(v)) + == fmpz_polyxx::from_ground(2*285)); + tassert(trace((A+A)*(fmpz_polyxx(1) + fmpz_polyxx(1))).is_zero()); + + for(unsigned i = 0;i < 10; ++i) + for(unsigned j = 0; j < 10; ++j) + A.at(i, j) = fmpz_polyxx::from_ground(i*j); + tassert(A == v*transpose(v)); + tassert(A != transpose(v)*v); + A.at(0, 0) = fmpz_polyxx::from_ground(15); + tassert(A != v*transpose(v)); + + A.at(0, 0) = fmpz_polyxx::from_ground(0); + for(unsigned i = 0;i < 10; ++i) + for(unsigned j = 0; j < 10; ++j) + A.at(i, j) *= 2; + tassert(A == v*transpose(v) + v*transpose(v)); + tassert(A - v*transpose(v) == v*transpose(v)); + tassert(((-A) + A).is_zero()); + tassert((A + A).at(0, 0) == A.at(0, 0) + A.at(0, 0)); + + tassert((A + A) == fmpzxx(2)*A && fmpz_polyxx::from_ground(2)*A == (A + A)); + + frandxx rand; + fmpzxx x(17); + A.set_randtest(rand, 3, 5); + fmpz_matxx B(A.rows(), A.cols()); + B = A(x); + for(slong i = 0;i < A.rows();++i) + for(slong j = 0;j < A.cols();++j) + tassert(B.at(i, j) == A.at(i, j)(x)); + tassert(A(x) == evaluate(A, x)); +} + +void +test_functions() +{ + fmpz_poly_matxx A(2, 3), B(2, 2), empty(0, 15); + B.at(0, 0) = fmpz_polyxx::from_ground(1); + tassert(A.is_zero() && !A.is_empty() && !A.is_square() && !A.is_one()); + tassert(!B.is_zero() == B.is_square()); + tassert(empty.is_zero() && empty.is_empty()); + + // transpose tested in arithmetic + // mul tested in arithmetic + // trace tested in arithmetic + + A.at(0, 0).set_coeff(35, 17); + tassert(A.max_length() == 36); + tassert(A.max_bits() == 5); + + frandxx rand; + A.set_randtest(rand, 4, 10); + B.set_randtest(rand, 4, 10); + tassert(B*A == B.mul_classical(A)); + tassert(B*A == B.mul_KS(A)); + + fmpz_poly_matxx tmp(B*A); + tmp.truncate(3); + tassert(tmp == B.mullow(A, 3)); + + tassert(sqr(B) == B*B); + tassert(B.sqr().sqr() == pow(B, 4u)); + tassert(B.sqrlow(3) == B.mullow(B, 3)); + tmp = pow(B, 5u); + tmp.truncate(7); + tassert(tmp == B.pow_trunc(5u, 7)); + + B.set_randtest(rand, 4, 10); + tassert(B.det() == B.det_fflu()); + tassert(B.det()(fmpzxx(123)) == B(fmpzxx(123)).det()); + tassert(B.det() == B.det_interpolate()); + + fmpz_matxx Bp(2, 2); + Bp.set_randdet(rand, fmpzxx(2*3*5)); + tassert(fmpz_poly_matxx::from_ground(Bp).det() + == fmpz_polyxx::from_ground(2*3*5)); + + fmpz_poly_matxx C(3, 3); + C.at(0, 0).set_coeff(0, 1); + C.at(1, 1).set_coeff(0, 1); + tassert(rank(C) == 2); + + Bp.set_randrank(rand, 1, 10); + B = fmpz_poly_matxx::from_ground(Bp); + tassert(!inv(B).get<0>()); + Bp.set_randrank(rand, 2, 10); + B = fmpz_poly_matxx::from_ground(Bp); + fmpz_poly_matxx Binv(2, 2); bool worked; fmpz_polyxx d; + ltupleref(worked, Binv, d) = inv(B); + tassert(worked); + fmpz_poly_matxx eye(2, 2); + eye.at(0, 0).set_coeff(0, 1);eye.at(1, 1).set_coeff(0, 1); + tassert(eye.is_one()); + tassert(Binv * B == d*eye); + + fmpz_poly_matxx X(2, 3); + ltupleref(worked, X, d) = solve(B, A); + tassert(worked == true && (B*X) == A*d); + ltupleref(worked, X, d) = B.solve_fflu(A); + tassert(worked == true && (B*X) == A*d); + tassert(solve(B, A).get<1>() == X); + + permxx perm(B.rows()); + tassert(solve_fflu_precomp(perm, B.fflu(&perm, false).get<1>().evaluate(), A) + == B.solve_fflu(A).get<1>()); + + slong nullity; + tassert(nullspace(A).get<1>().rows() == 3); + tassert(nullspace(A).get<1>().cols() == 3); + ltupleref(nullity, C) = nullspace(A); + tassert(nullity == 3 - rank(A)); + tassert(C.rank() == nullity); + tassert((A*C).is_zero()); + + if(0) + print_pretty(A, "x"); // make sure this compiles +} + +void +test_extras() +{ + fmpz_poly_matxx A(2, 2); + A.at(0, 0).set_coeff(0, 1); + + fmpz_poly_matxx_srcref Asr(A); + const fmpz_poly_matxx& Acr = A; + tassert(A.at(0, 0) == Acr.at(0, 0)); + tassert(A.at(0, 0) == Asr.at(0, 0)); +} + +void +test_randomisation() +{ + frandxx rand, rand2; + fmpz_poly_matxx A(2, 2); + A.set_randtest(rand, 4, 5); + tassert(abs(A.at(0, 0).get_coeff(0)) <= 31); + tassert(A == fmpz_poly_matxx::randtest(2, 2, rand2, 4, 5)); + A.set_randtest_unsigned(rand, 4, 5); + tassert(A.at(0, 0).get_coeff(0) >= 0); + tassert(A == fmpz_poly_matxx::randtest_unsigned(2, 2, rand2, 4, 5)); + A.set_randtest_sparse(rand, 4, 5, 0.5); + tassert(abs(fmpz_polyxx_get_coeff(A.at(0, 0), 0)) <= 31); + tassert(A == fmpz_poly_matxx::randtest_sparse(2, 2, rand2, 4, 5, 0.5)); +} + +void +test_row_reduction() +{ + frandxx state; + fmpz_poly_matxx A = fmpz_poly_matxx::randtest(5, 5, state, 7, 15); + slong rank1, rank2; + fmpz_polyxx den1, den2; + fmpz_poly_matxx res1(A.rows(), A.cols()), res2(A.rows(), A.cols()); + + tassert(find_pivot_any(A, 2, 4, 1) + == fmpz_poly_mat_find_pivot_any(A._mat(), 2, 4, 1)); + tassert(find_pivot_partial(A, 2, 4, 1) + == fmpz_poly_mat_find_pivot_partial(A._mat(), 2, 4, 1)); + tassert(A.fflu(0, false).get<1>().rows() == A.rows()); + permxx p1(5), p2(5); + ltupleref(rank1, res1, den1) = fflu(A, &p1); + rank2 = fmpz_poly_mat_fflu(res2._mat(), den2._poly(), p2._data(), + A._mat(), false); + tassert(rank1 == rank2 && res1 == res2 && p1 == p2 && den1 == den2); + tassert(rank1 == A.fflu(0, false).get<0>()); + + ltupleref(rank1, res1, den1) = rref(A); + rank2 = fmpz_poly_mat_rref(res2._mat(), den2._poly(), A._mat()); + tassert(rank1 == rank2 && res1 == res2 && p1 == p2 && den1 == den2); +} + +void +test_prod() +{ + fmpz_poly_mat_vecxx v1(10, 3, 3), v2(10, 3, 3), v3(9, 3, 3), v4(v1); + tassert(v1 == v2); + tassert(v1 != v3); + v1[0].at(0, 0).set_coeff(0, 7u); + tassert(v1 != v4); + + frandxx rand; + fmpz_poly_matxx prod = fmpz_poly_matxx::one(3, 3); + for(slong i = 0;i < v1.size();++i) + { + v1[i].set_randtest(rand, 4, 17); + prod *= v1[i]; + } + tassert(flint::prod(v1) == prod); +} + +int +main() +{ + std::cout << "fmpz_poly_matxx...."; + + test_init(); + test_arithmetic(); + test_functions(); + test_extras(); + test_randomisation(); + test_row_reduction(); + test_prod(); + + std::cout << "PASS" << std::endl; + return 0; +} diff --git a/external/flint-2.4.3/flintxx/test/t-fmpz_poly_qxx.cpp b/external/flint-2.4.3/flintxx/test/t-fmpz_poly_qxx.cpp new file mode 100644 index 0000000..3fba9a9 --- /dev/null +++ b/external/flint-2.4.3/flintxx/test/t-fmpz_poly_qxx.cpp @@ -0,0 +1,178 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#include +#include +#include + +#include "fmpz_poly_qxx.h" + +#include "flintxx/test/helpers.h" + +using namespace flint; + +void +test_manipulation() +{ + fmpz_poly_qxx f; + f.num() = "3 0 1 1"; + f.den() = "3 0 -1 1"; + tassert(!f.is_canonical()); + f.canonicalise(); + tassert(f.num().to_string() == "2 1 1"); + tassert(f.den().to_string() == "2 -1 1"); + + tassert(fmpz_poly_qxx::zero().is_zero()); + tassert(fmpz_poly_qxx::one().is_one()); +} + +void +test_assignment_conversion() +{ + fmpz_poly_qxx f, g; + f = 1; + tassert(f.is_one()); + g = 0; + f = g; + tassert(f.is_zero()); + tassert(f.to_string() == "0"); + + f = "4 1 0 0 1"; + tassert(f.num().to_string() == "4 1 0 0 1"); + tassert(f.den().to_string() == "1 1"); + + f.den() = "2 -1 1"; + tassert(f.to_string() == "4 1 0 0 1/2 -1 1"); + g = "4 1 0 0 1/2 -1 1"; + tassert(f == g); + tassert(f == fmpz_poly_qxx("4 1 0 0 1/2 -1 1")); + + tassert(f.pretty("x") == "(x^3+1)/(x-1)"); +} + +void +test_arithmetic() +{ + fmpz_poly_qxx f, g; + g = "4 1 0 0 1/2 -1 1"; + f = "1 1"; + + tassert((f + g).to_string() == "4 0 1 0 1/2 -1 1"); + tassert((g - f).to_string() == "4 2 -1 0 1/2 -1 1"); + tassert(g - f == g + (-f)); + tassert(inv(g).to_string() == "2 -1 1/4 1 0 0 1"); + + tassert(2 * g == g * 2); + f = 2*g; + tassert(f.num() == 2*g.num() && f.den() == g.den()); + f /= 2; + tassert(f == g); + + f = "1 1"; + tassert((f*g).num() == f.num()*g.num()); + tassert((f*g).den() == f.den()*g.den()); + tassert((f/g).num() == f.num()*g.den()); + tassert((f/g).den() == f.den()*g.num()); +} + +// Won't compile if the expression is not done using addmul +template +bool is_ternary(const T&) +{ + return T::ev_traits_t::temp_rule_t::TERNARY_OP_MARKER + 1; +} + +// test stuff which we should get automatically - addmul, references etc +void +test_extras() +{ + // TODO +} + +void +test_functions() +{ + fmpz_poly_qxx f; + tassert(f.is_zero() && !f.is_one()); + f.num() = 1; + tassert(f.is_one()); + + f = "4 1 0 0 1/2 -1 1"; + tassert(pow(f, 4u) == f*f*f*f); + + tassert(derivative(f).to_string() == "4 -1 0 -3 2/3 1 -2 1"); + + // test static methods + frandxx rand; + tassert(fmpz_poly_qxx::randtest(rand, 10, 8, 10, 8).num().degree() < 10); + tassert(fmpz_poly_qxx::randtest(rand, 10, 8, 10, 8).den().degree() < 10); + tassert(flog(height(fmpz_poly_qxx::randtest( + rand, 10, 8, 10, 8).num()), 2u) < 8); + tassert(flog(height(fmpz_poly_qxx::randtest( + rand, 10, 8, 10, 8).den()), 2u) < 8); + tassert(!fmpz_poly_qxx::randtest_not_zero(rand, 10, 8, 10, 8).is_zero()); + + tassert(f.derivative() == derivative(f)); + tassert(f.inv() == inv(f)); + tassert(f.pow(7u) == pow(f, 7u)); +} + +void +test_printing() +{ + if(0) + { + // make sure these compile + fmpz_poly_qxx f; + print(f); + print_pretty(f, "x"); + } +} + +void +test_unified_access() +{ + fmpz_poly_qxx a; + const fmpz_poly_qxx& b = a; + tassert(b.num().is_zero() && b.den().is_one()); +} + +int +main() +{ + std::cout << "fmpz_poly_qxx...."; + + test_manipulation(); + test_assignment_conversion(); + test_arithmetic(); + test_functions(); + test_extras(); + test_printing(); + test_unified_access(); + + std::cout << "PASS" << std::endl; + return 0; +} + diff --git a/external/flint-2.4.3/flintxx/test/t-fmpz_polyxx.cpp b/external/flint-2.4.3/flintxx/test/t-fmpz_polyxx.cpp new file mode 100644 index 0000000..2b8c111 --- /dev/null +++ b/external/flint-2.4.3/flintxx/test/t-fmpz_polyxx.cpp @@ -0,0 +1,492 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#include +#include +#include + +#include "fmpz_polyxx.h" +#include "nmod_polyxx.h" + +#include "flintxx/test/helpers.h" + +using namespace flint; + +void +test_init() +{ + fmpz_polyxx p(10); + tassert(p.length() == 0); + + tassert(fmpz_polyxx::zero().is_zero()); + tassert(fmpz_polyxx::one().is_one()); +} + +void +test_manipulation() +{ + fmpz_polyxx p, q; + tassert(p.get_coeff(5) == 0); + p.set_coeff(5, 17); + tassert(p.degree() == 5); + q.set_coeff(5, 17u); + p.set_coeff(0, fmpzxx(1)); + q.coeff(0) = 1; + tassert(p == q); + + tassert(p.lead() == 17); + tassert(p.length() == 6); + + p.zero_coeffs(0, 6); + tassert(p.is_zero() && !p.is_one() && !p.is_unit()); + p.set_coeff(0, 1); + tassert(p.is_one() && p.is_unit()); + p.set_coeff(0, -1); + tassert(p.is_unit()); + + const fmpz_polyxx pc = p; + tassert(p.get_coeff(0) == pc.get_coeff(0)); + tassert((p*q).coeff(0) == p.get_coeff(0)*q.get_coeff(0)); + tassert((p*q).lead() == p.lead()*q.lead()); +} + +void +test_assignment() +{ + fmpz_polyxx p, q; + p = 1; + tassert(p.is_one()); + q = UWORD(0); + tassert(q.is_zero()); + tassert(p != q); + p = q; + tassert(p == q); + p = "4 0 0 0 1"; + q.set_coeff(3, 1); + tassert(p == q); + + // TODO XXX this does not always fail? + //assert_exception(p = "4 1 2"); + assert_exception(p = "2 1 2"); +} + +void +test_conversion() +{ + fmpz_polyxx p; + p.set_coeff(3, 1); + tassert(p.to_string() == "4 0 0 0 1"); + tassert(p.pretty("x") == "x^3"); + + tassert(p == fmpz_polyxx("4 0 0 0 1")); +} + +void +test_arithmetic() +{ + fmpz_polyxx p, q; + p = 1; + q = "4 0 0 0 1"; + tassert((p + q).to_string() == "4 1 0 0 1"); + tassert((p - q).to_string() == "4 1 0 0 -1"); + tassert((-p).to_string() == "1 -1"); + + fmpzxx two(2); + tassert(two * q == 2 * q && 2u * q == q * 2 + && (two * q).to_string() == "4 0 0 0 2"); + q *= 2; + tassert(q / two == q / 2u && q / 2 == q / two && + (q / two).to_string() == "4 0 0 0 1"); + // q == "4 0 0 0 2" + + q.set_coeff(1, 17); // q == "4 0 17 0 2" + tassert((q % fmpzxx(5)).to_string() == "4 0 2 0 2"); + + p = "3 1 0 1"; + tassert((p*q).to_string() == "6 0 17 0 19 0 2"); + + tassert((p*q) / p == q); + tassert(p + q % q == p); + + tassert(p(fmpzxx(1) + fmpzxx(1)) == 5); + q = "3 0 0 1"; + tassert(p(q).to_string() == "5 1 0 0 0 1"); +} + +// Won't compile if the expression is not done using addmul +template +bool is_ternary(const T&) +{ + return T::ev_traits_t::temp_rule_t::TERNARY_OP_MARKER + 1; +} + +// test stuff which we should get automatically - addmul, references etc +void +test_extras() +{ + // TODO addmul when we have it +} + +ulong pow(ulong base, ulong exp) +{ + ulong res = 1; + while(exp-- > 0) + res *= base; + return base; +} + +void +test_functions() +{ + // test swap + fmpz_polyxx p, q; + p = 1; q = 0; + swap(p, q); + tassert(p.is_zero() && q.is_one()); + // p = 0, q = 1 + + fmpz_polyxx f, g, xp1; + f = "4 2 0 0 1"; // f = x^3 + 2 + g = "5 1 2 3 4 5"; + xp1 = "2 1 1"; + fmpzxx two(2); + + // test lazy functions + tassert(reverse(q, 4).pretty("x") == "x^3"); + tassert(mul_2exp(f, 3u) == f * 8); + tassert(f == fdiv_2exp(mul_2exp(f, 3u), 3u)); + tassert(tdiv(-f, two) == tdiv(-f, 2) && tdiv(-f, 2) == tdiv(-f, 2u) + && tdiv(-f, two).to_string() == "4 -1 0 0 0"); + tassert(f == divexact(2*f, two) && f == divexact(2*f, 2u) + && f == divexact(2*f, 2)); + tassert(-f == tdiv_2exp(-8*f - q, 3u)); + tassert(smod(5*f, fmpzxx(3)).to_string() == "4 1 0 0 -1"); + tassert(f == fmpz_polyxx::bit_unpack(bit_pack(f, 10u), 10u)); + tassert(f == fmpz_polyxx::bit_unpack_unsigned(bit_pack(f, 10u), 10u)); + + tassert(mul_classical(f, g) == f*g); + tassert(mul_karatsuba(f, g) == f*g); + tassert(mul_SS(f, g) == f*g); + tassert(mul_KS(f, g) == f*g); + + fmpz_polyxx res; res = f*g; res.truncate(3); + tassert(mullow_classical(f, g, 3) == res); + tassert(mullow_karatsuba_n(f, g, 3) == res); + tassert(mullow_KS(f, g, 3) == res); + tassert(mullow_SS(f, g, 3) == res); + tassert(mullow(f, g, 3) == res); + + res = f*g; res.zero_coeffs(0, 5); + tassert(mulhigh_classical(f, g, 5) == res); + tassert(mulhigh_karatsuba_n(f, g, 6) == res); + res = mulhigh_n(f, g, 5); + res.zero_coeffs(0, 5); + tassert(res == mulhigh_classical(f, g, 5)); + + tassert(mulmid_classical(g, f).to_string() == "2 9 12"); + + tassert(sqr(f) == f*f); + tassert(sqr_KS(f) == f*f); + tassert(sqr_karatsuba(f) == f*f); + tassert(sqr_classical(f) == f*f); + + res = sqr(f);res.truncate(4); + tassert(sqrlow(f, 4) == res); + tassert(sqrlow_KS(f, 4) == res); + tassert(sqrlow_karatsuba_n(f, 4) == res); + tassert(sqrlow_classical(f, 4) == res); + + tassert(pow(f, 3u) == f*f*f); + tassert(pow_multinomial(f, 3u) == f*f*f); + tassert(pow_binexp(f, 3u) == f*f*f); + tassert(pow_addchains(f, 3u) == f*f*f); + res = pow(f, 10u); + res.truncate(10); + tassert(pow_trunc(f, 10u, 10) == res); + fmpz_polyxx binomial; + binomial = "2 1 2"; + tassert(pow_binomial(binomial, 3u) == binomial*binomial*binomial); + + fmpz_polyxx x; x = "2 0 1"; + tassert(shift_left(f, 5) == f*pow(x, 5u)); + tassert(shift_right(shift_left(f, 5), 5) == f); + + tassert(height(g) == 5); + tassert(twonorm(g) == 7); + + tassert(resultant(f, g) == 1797); + tassert(gcd(f, g).is_one()); + tassert(gcd_subresultant(f, g).is_one()); + tassert(gcd_heuristic(f, g).is_one()); + tassert(gcd_modular(f, g).is_one()); + + fmpz_polyxx r, s;fmpzxx number; + res = 1797; + ltupleref(number, r, s) = xgcd(f, g); + tassert(r*f + s*g == res && number == 1797); + r = 0; s = 0; number = 0; + ltupleref(number, r, s) = xgcd_modular(f, g); + tassert(r*f + s*g == res && number == 1797); + + tassert(lcm(f, g) == f*g); + + tassert(content(2*g) == 2); + tassert(primitive_part(2*g) == g); + + tassert(div_basecase(f*g, g) == f); + tassert(div_divconquer(f*g, g) == f); + tassert(rem_basecase(f + g, g) == f); + res = 1; + tassert(div_root(f*(x - res), fmpzxx(1)) == f); + + tassert(inv_series(xp1, 5).to_string() == "5 1 -1 1 -1 1"); + tassert(inv_series(xp1, 10) == inv_series_newton(xp1, 10)); + + tassert(derivative(xp1).is_one()); + + tassert((compose(xp1, f) - f).is_one()); + tassert((compose_divconquer(xp1, f) - f).is_one()); + tassert((compose_horner(xp1, f) - f).is_one()); + tassert(evaluate(xp1, fmpzxx(1)) == 2); + tassert(evaluate_horner(xp1, fmpzxx(1)) == 2); + tassert(evaluate_divconquer(xp1, fmpzxx(1)) == 2); + tassert(evaluate_mod(xp1, 1u, 10u) == 2); + + fmpz_vecxx xs(3), ys(3); + xs[0] = 0; xs[1] = 1; xs[2] = 2; + ys[0] = 1; ys[1] = 2; ys[2] = 3; + tassert(evaluate(xp1, xs) == ys); + + tassert(f(xp1) == taylor_shift(f, fmpzxx(1))); + tassert(f(xp1) == taylor_shift_horner(f, fmpzxx(1))); + tassert(f(xp1) == taylor_shift_divconquer(f, fmpzxx(1))); + + fmpz_polyxx inner;inner = "3 0 -1 5"; + res = g(inner); res.truncate(10); + tassert(compose_series(g, inner, 10) == res); + tassert(compose_series_horner(g, inner, 10) == res); + tassert(compose_series_brent_kung(g, inner, 10) == res); + + res = "2 0 1"; + tassert(compose_series(inner, revert_series(inner, 10), 10) == res); + tassert(compose_series(inner, revert_series_lagrange(inner, 10), 10) + == res); + tassert(compose_series(inner, revert_series_lagrange_fast(inner, 10), 10) + == res); + tassert(compose_series(inner, revert_series_newton(inner, 10), 10) == res); + + tassert(sqrt(f*f) == f); + tassert(sqrt_classical(f*f) == f); + assert_exception(sqrt(f*f + xp1).evaluate()); + assert_exception(sqrt_classical(f*f + xp1).evaluate()); + + res = "5 32 0 0 0 1"; + tassert(bound_roots(res) >= 2); + + // test immediate functions + p.set_coeff(3, 1); + p.truncate(2); + tassert(p.is_zero()); + tassert(f.max_limbs() == 1); + tassert(g.max_bits() == 3); + + r = 0; s = 0; + ltupleref(r, s) = divrem(g, f); + tassert(r*f + s == g); + tassert(r.to_string() == "2 4 5"); + r = 0; s = 0; + ltupleref(r, s) = divrem_basecase(g, f); + tassert(r*f + s == g); + tassert(r.to_string() == "2 4 5"); + r = 0; s = 0; + ltupleref(r, s) = divrem_divconquer(g, f); + tassert(r*f + s == g); + tassert(r.to_string() == "2 4 5"); + + bool does_divide; + ltupleref(does_divide, res) = divides(f*g, g); + tassert(does_divide && res == f); + + tassert(div_series(f, xp1, 10) * xp1 % pow(x, 10u) == f); + + f *= 2; + ulong d = 0; + ltupleref(r, s, d) = pseudo_divrem(g, f); + tassert(r*f + s == g*pow(2, d)); + r = 0; r = 0; d = 0; + ltupleref(r, s, d) = pseudo_divrem_basecase(g, f); + tassert(r*f + s == g*pow(2, d)); + r = 0; r = 0; d = 0; + ltupleref(r, s, d) = pseudo_divrem_divconquer(g, f); + tassert(r*f + s == g*pow(2, d)); + + tassert(pseudo_div(g, f).get<0>() == r); + tassert(pseudo_rem(g, f).get<0>() == s); + + r = 0; r = 0; + ltupleref(r, s) = pseudo_divrem_cohen(g, f); + tassert(r*f + s == g*4); + tassert(pseudo_rem_cohen(g, f).to_string() == "3 -28 -32 12"); + + f = "4 1 0 0 1"; + slong r1, r2; + f.signature(r1, r2); + tassert(r1 == 1 && r2 == 1); + + // test static functions + frandxx state; + tassert(fmpz_polyxx::randtest(state, 4, 10).length() <= 4); + tassert(fmpz_polyxx::randtest_unsigned(state, 4, 10).get_coeff(0) >= 0); + tassert(fmpz_polyxx::randtest_not_zero(state, 4, 10).is_zero() == false); + tassert(fmpz_polyxx::interpolate(xs, ys) == xp1); + + xs[0] = 0;xs[1] = -1; xs[2] = -1; + tassert(fmpz_polyxx::product_roots(xs) == x*xp1*xp1); +} + +void +test_member_functions() +{ + // just a sample, since they all come from macros + fmpz_polyxx f, g; + f = "4 2 0 0 1"; + g = "5 1 2 3 4 5"; + + tassert(f.bit_pack(17u) == bit_pack(f, 17u)); + tassert(f.divrem(g) == divrem(f, g)); + tassert(f.derivative() == derivative(f)); + tassert(f.bound_roots() == bound_roots(f)); + tassert(f.content() == content(f)); + tassert(f.pow_trunc(15u, 10) == pow_trunc(f, 15u, 10)); +} + +void +test_factoring() +{ + fmpz_polyxx f, g; + // two irreducible polynomials + f = "4 1 17 0 1"; + g = "6 2 0 2 0 0 1"; + + // TODO are these deterministic? + fmpz_poly_factorxx f1, f2; + f1.insert(f, 1); + f2.insert(g, 2); + f1.content() = 7; + f1.concat(f2); + + tassert(f1 == factor_zassenhaus(7*f*g*g)); + + f1.realloc(0); + f1.insert(f, 1); + f1.insert(g, 2); + f1.content() = 1; + tassert(f1 == factor_squarefree(f*g*g)); + + // TODO test set_factor_zassenhaus_recombination + + if(0) + print(f1); // make sure this compiles +} + +void +test_hensel() +{ + mp_limb_t pl = 1031; + frandxx state; + nmod_polyxx gl(nmod_polyxx::randtest_irreducible(pl, state, 5).make_monic()); + nmod_polyxx hl(nmod_polyxx::randtest_irreducible(pl, state, 6).make_monic()); + while(gl.length() != 5) + gl = nmod_polyxx::randtest_irreducible(pl, state, 5).make_monic(); + while(hl.length() != 5) + hl = nmod_polyxx::randtest_irreducible(pl, state, 5).make_monic(); + nmod_polyxx al(pl), bl(pl); + ltupleref(_, al, bl) = xgcd(gl, hl); + tassert((al*gl + bl*hl).is_one()); + + fmpz_polyxx f = fmpz_polyxx::lift(gl*hl); + fmpz_polyxx g = fmpz_polyxx::lift(gl); + fmpz_polyxx h = fmpz_polyxx::lift(hl); + fmpz_polyxx a = fmpz_polyxx::lift(al); + fmpz_polyxx b = fmpz_polyxx::lift(bl); + + fmpz_polyxx G, H, A, B; + fmpzxx p(pl), p1(1031); + tassert(((f - g*h) % p).is_zero()); + + //ltupleref(G, H, A, B) = hensel_lift(f, g, h, a, b, p, p1); + fmpz_poly_hensel_lift(G._poly(), H._poly(), A._poly(), B._poly(), f._poly(), g._poly(), h._poly(), a._poly(), b._poly(), p._fmpz(), p1._fmpz()); + tassert(((f - G*H) % (p1*p)).is_zero()); + tassert(((A*G + B*H) % (p1*p)).is_one()); + + tassert(ltupleref(G, H) == hensel_lift_without_inverse(f, g, h, a, b, p, p1)); + tassert(ltupleref(A, B) == hensel_lift_only_inverse(G, H, a, b, p, p1)); + + nmod_poly_factorxx local_fac = factor(gl*hl); + fmpz_poly_factorxx lifted_fac = hensel_lift_once(f, local_fac, 3); + tassert(lifted_fac.size() == 2 + && lifted_fac.exp(0) == 1 && lifted_fac.exp(1) == 1); + tassert(((lifted_fac.p(0)*lifted_fac.p(1) - f) % p.pow(3u)).is_zero()); +} + +void +test_printing() +{ + frandxx state; + fmpz_polyxx f = fmpz_polyxx::randtest(state, 4, 10); + test_print_read(f); + test_print_read_pretty(f); +} + +void +test_unified_access() +{ + fmpz_polyxx a = fmpz_polyxx::from_ground(1); + const fmpz_polyxx& b = a; + tassert(b.lead() == 1 && b.coeff(0) == 1); +} + +int +main() +{ + std::cout << "fmpz_polyxx...."; + + test_init(); + test_manipulation(); + test_assignment(); + test_conversion(); + test_arithmetic(); + test_functions(); + test_member_functions(); + test_extras(); + test_factoring(); + test_hensel(); + test_printing(); + test_unified_access(); + + std::cout << "PASS" << std::endl; + return 0; +} + diff --git a/external/flint-2.4.3/flintxx/test/t-fmpzxx.cpp b/external/flint-2.4.3/flintxx/test/t-fmpzxx.cpp new file mode 100644 index 0000000..035b293 --- /dev/null +++ b/external/flint-2.4.3/flintxx/test/t-fmpzxx.cpp @@ -0,0 +1,615 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ +#include +#include +#include + +#include "fmpzxx.h" +#include "flintxx/test/helpers.h" + +#if !HAVE_FAST_COMPILER +#warning "Some tests are disabled because your compiler is slow." +#endif + +using namespace flint; + +void +test_printing() +{ + fmpzxx a(31); + + tassert(a.to_string() == "31"); + tassert(a.to_string(2) == "11111"); + + std::ostringstream oss; + oss << a << '\n' << std::oct << a << '\n' + << std::hex << a << '\n' << std::dec << a; + tassert(oss.str() == "31\n37\n1f\n31"); + + fmpzxx b(-15); + tassert((a + b).to_string() == "16"); + + char astr[] = "15"; + tassert(fmpzxx(astr) == 15); +} + +void +test_order() +{ + fmpzxx a(0); + fmpzxx b(1); + fmpzxx c(0); + fmpzxx d(-1); + +#define TO(xzero, zero, one, mone) \ + tassert(xzero == zero); \ + tassert(xzero != one); \ + tassert(!(xzero == one)); \ + tassert(!(xzero != zero)); \ + tassert(xzero < one); \ + tassert(xzero <= one); \ + tassert(xzero <= zero); \ + tassert(!(xzero < zero)); \ + tassert(!(xzero <= mone)); \ + tassert(xzero > mone); \ + tassert(xzero >= mone); \ + tassert(xzero >= zero); \ + tassert(!(xzero > zero)); \ + tassert(!(xzero >= one)); + + TO(a, c, b, d); + TO(a, 0, 1, -1); + TO(a, 0u, 1u, -1); + TO(a, (signed short)(0), (signed short)(1), (signed short)(-1)); + TO(a, (unsigned short)(0), (unsigned short)(1), -1); + TO(a, WORD(0), WORD(1), WORD(-1)); + TO(0, c, b, d); + TO(0u, c, b, d); + TO(WORD(0), c, b, d); + TO((short)0, c, b, d); + TO((unsigned short)0, c, b, d); +} + +void +test_conversion() +{ + fmpzxx a(4); + tassert(a.to() == 4); + tassert(a.to() == 4); + tassert(a.to() == 4.0); + // NB: to_string is tested in test_printing +} + +void +test_initialisation_assignment() +{ + fmpzxx a(4), b(WORD(4)), c(4u), d("4"); + fmpzxx e(a); + fmpzxx f, g, h, i; + f = 4; + g = WORD(4); + h = 4u; + i = fmpzxx("4"); + tassert(a == b && a == c&& a == d && a == e && a == f && a == g && a == h + && a == i); + + // test deep copying of fmpzxx with more than one digit + a = fmpzxx("100000000000000000000"); + b = a; + tassert(a._fmpz()[0] != b._fmpz()[0]); + fmpzxx j(a); + tassert(a._fmpz()[0] != j._fmpz()[0]); + tassert(a == b && a == j); + + // just here to test our assumptions on data format + tassert(c._fmpz()[0] == d._fmpz()[0]); + + // some more exotic "assignments" + a.set_ui_smod(15, 16); + tassert(a == -1); + a.set_uiui(27, 15); + tassert(a % (fmpzxx(1) << FLINT_BITS) == 15); + tassert((a >> FLINT_BITS) == 27); + b.neg_uiui(27, 15); + tassert(b == -a); +} + +void +test_arithmetic() +{ +#define TAC(seven, three) \ + tassert(seven + three == 10); \ + tassert(seven * three == 21); + +#define TA(seven, three) \ + TAC(seven, three); \ + tassert(seven - three == 4); \ + tassert(seven / three == 2); \ + tassert(seven % three == 1) + + TA(fmpzxx(7), fmpzxx(3)); + TA(fmpzxx(7), 3u); + TAC(UWORD(7), fmpzxx(3)); + + // test signed builtins (only div and mul) + tassert(-7 * fmpzxx(3) == -21); + tassert(fmpzxx(7) * (WORD(-3)) == -21); + tassert(fmpzxx(21) / -3 == -7); + + // test composite arithmetic + fmpzxx a(3), b(7); + tassert(3*(a + b) - (b + (a - 4u)) + ((-(a - b)) % (b / 2)) == 25); + + // test unary minus + tassert(-a == -3); + + // test assignment arithmetic +#define TAA(op, res) \ + { \ + fmpzxx tmp1(10), tmp2(10), tmp3(10); \ + fmpzxx three(3); \ + tmp1 op three; \ + tmp2 op 3u; \ + tmp3 op three*1; \ + tassert(tmp1 == res); \ + tassert(tmp2 == res); \ + tassert(tmp3 == res); \ + } + TAA(+=, 13); + TAA(*=, 30); + TAA(/=, 3); + TAA(%=, 1); + + // shifting + tassert((fmpzxx(1) << 10) == 1024); + tassert((fmpzxx(1024) >> 9) == 2); + + // binary logic + tassert((fmpzxx(1) | fmpzxx(2)) == 3); + tassert((fmpzxx(3) & fmpzxx(5)) == 1); + tassert((fmpzxx(17) ^ fmpzxx(23)) == (UWORD(17) ^ UWORD(23))); + tassert(~fmpzxx(17) == ~WORD(17)); +} + +void +test_functions() +{ + fmpzxx a(2); + fmpzxx b(16); + fmpzxx_srcref c(a); + + tassert(sgn(a) == 1); + tassert(size(b) == 1); + tassert(val2(b) == 4); + tassert(bits(b) == 5); + tassert(sizeinbase(b, 2) == 5); + tassert(b.tstbit(0) == false); + + tassert(pow(a, 4u) == 16); + tassert(root(b, 4) == 2); + tassert(root(b, (unsigned short)4) == 2); + tassert(sqrt(b) == 4); + tassert(sqrt(a) == 1); + tassert(rfac(a, 3u) == 2*3*4); + tassert(a + fac(4u) == 2 + 4*3*2); + tassert(fib(4u) == 3); + tassert(bin(4u, 2u) == 6); + tassert(abs(a) == a); + tassert(gcd(a, b) == 2); + tassert(lcm(a, b) == 16); + fmpzxx p(31); + tassert((invmod(b % p, p) * b) % p == 1); + tassert((negmod(b % p, p) + b) % p == 0); + + fmpzxx mb(-b); + fmpzxx three(3); + tassert(cdiv_q(mb, three) == -5); + tassert(fdiv_r(mb, three) == 2); + tassert(tdiv_q(mb, three) == -5); + tassert(cdiv_q(mb, 3) == -5); + tassert(tdiv_q(mb, 3) == -5); + tassert(cdiv_q(mb, 3u) == -5); + tassert(tdiv_q(mb, 3u) == -5); + tassert(tdiv_q_2exp(mb, 2u) == -4); + tassert(fdiv_r_2exp(mb, 2u) == 0); + tassert(divexact(b, a) == 8 && divexact(b, 2) == 8 && divexact(b, 2u) == 8); + + // check a composite expression + tassert(2u + sqrt(a + a) == 4); + + // check immediate functions + tassert(divisible(b, a + a)); + tassert(divisible(b, a + a + 2u) == false); + tassert(divisible(a + a, (unsigned short)2)); + tassert(divisible(-a + b, 3) == false); + tassert(divisible(c, a) == true); + + fmpzxx f(15); + tassert(clog(f, a) == 4 && clog(f, 2u) == 4); + tassert(flog(f, a) == 3 && flog(f, 2u) == 3); + tassert(2.7 < dlog(f) && dlog(f) < 2.8); + + tassert(mul2(a, 15u, 16u) == a*15*16); + tassert(divexact2(b, 2u, 2u) == 4); + tassert(powm(a, 4u, fmpzxx(5)) == 1); + tassert(powm(a, fmpzxx(4), fmpzxx(5)) == 1); + tassert(mul_tdiv_q_2exp(a, fmpzxx(-3), 2u) == -1); + tassert(mul_tdiv_q_2exp(a, -3, 2u) == -1); + + fmpzxx q(1), rem(2); + tassert(fdiv_qr(b, a) == ltuple(8, 0)); + tassert(tdiv_qr(b, a) == ltuple(8, 0)); + + bool worked; + ltupleref(worked, q) = sqrtmod(fmpzxx(4), fmpzxx(5)); + tassert(worked && (q == 2 || q == 3)); + tassert(sqrtrem(fmpzxx(5)) == ltuple(2, 1)); + // TODO gcdinv, xgcd + + // check member functions + slong exp = 0; + double d = fmpzxx(3).get_d_2exp(exp); + double r = d * (WORD(1) << exp); + tassert(r >= 2.9 && r <= 3.1); + fmpzxx one(1), mone(-1), zero(0), two(2); + tassert(one.is_one() && one.is_pm1() && one.is_odd() && + !one.is_even() && !one.is_zero()); + tassert(!zero.is_one() && !zero.is_pm1() && zero.is_zero()); + tassert(mone.is_pm1()); + tassert(two.is_even() && !two.is_odd()); + tassert(one.is_square() && !two.is_square()); + tassert(jacobi(b, p) == 1); + tassert(p.is_probabprime()); + tassert(p.is_prime_pseudosquare()); + + tassert((3*b).remove(a) == ltuple(4, 3)); + + a = 17; + a.clrbit(0); + tassert(a == 16); + a.combit(1); + tassert(a == 18); + tassert(a.popcnt() == 2); + + + frandxx rand; + mp_bitcnt_t bits = 123; // some extra space in two words + std::vector arr(bits / FLINT_BITS + 2); + fmpzxx tostore = fmpzxx::randtest_unsigned(rand, bits); + bit_pack(arr, bits, tostore); + tassert(tostore == fmpzxx::bit_unpack_unsigned(arr, bits)); + tassert(tostore == fmpzxx::bit_unpack(arr, bits).get<1>()); +} + +void +test_member_functions() +{ + // NB: only a sample, since these are done by macros anyway + fmpzxx a(2), b(3); + tassert((a*b).divisible(b)); + tassert((a*b).divisible(3)); + tassert(b.flog(3u) == 1); + tassert(a.clog(a) == 1); + tassert(a.rfac(3u) == rfac(a, 3u)); + tassert(a.gcd(b) == gcd(a, b)); + tassert(a.lcm(b) == lcm(a, b)); + tassert(a.cdiv_q(b) == cdiv_q(a, b)); + tassert(a.mul2(3u, 4u) == mul2(a, 3u, 4u)); + tassert(a.sqrtmod(b) == sqrtmod(a, b)); + tassert(b.sqrt() == sqrt(b)); +} + +template +void assert_is_fmpzxx(const T&) +{ + tassert(traits::is_fmpzxx::val); +} +struct newtype {typedef void data_ref_t; typedef void data_srcref_t;}; +void +test_traits() +{ + tassert(traits::is_fmpzxx::val == true); + tassert(traits::is_fmpzxx::val == false); + assert_is_fmpzxx(fmpzxx(1) + fmpzxx(2)); + // the following does not even compile: + //tassert((traits::is_fmpzxx >::val == false)); +} + +template +unsigned count_temporaries2(const T&) +{ + return T::ev_traits_t::temp_rule_t::temporaries_t::len + // this term is always zero, but causes compiler error + // if we are not actually in the ternary case + + T::ev_traits_t::temp_rule_t::TERNARY_OP_MARKER; +} + +void +test_temporaries() +{ + fmpzxx a, b, c; + tassert(count_temporaries(a + b) == 0); + tassert(count_temporaries(a + b + c + a + b + c) == 1); + tassert(count_temporaries(((a / c) + (b % a)) / ((b + c) + (c / a))) == 3); + tassert(count_temporaries((a/b) + (a/c) + (b/c) + (c/b)) == 2); + tassert(count_temporaries2((a*b) + (a*c) + (b*c) + (c*b)) == 1); + + // test a bug in evaluate_2 (if addmul is used on the right, this can + // be done with two temporaries, else need three) + tassert(count_temporaries(((a+b)+(a+c)) + (((a+c) + a*c))) == 2); +} + +void +test_ternary() +{ + fmpzxx b(2), c(3), d(4); + +#define T0 fac(4u) +#define T1 (b + b + b) +#define T2 (T1 + T1) +#define T3 (T2 + T2) +#define T4 (T3 + T3) + + // The inner struct is a trickery to get gcc to free some of its data + // structures. It reduces the resident set by 50%, and compile time by 75%. +#define TT3(m1, m2, m3, ntemps) \ + do{ struct inner { static void doit() { \ + fmpzxx b(2), c(3), d(4); \ + tassert(count_temporaries2(m1 + m2*m3) == ntemps); \ + tassert(b + (m1 + m2*m3) == 2 + m1.to() + m2.to()*m3.to()); \ + tassert(count_temporaries2(m1 + m3*m2) == ntemps); \ + tassert(b + (m1 + m3*m2) == 2 + m1.to() + m2.to()*m3.to()); \ + \ + tassert(count_temporaries2(m2*m3 + m1) == ntemps); \ + tassert(b + (m2*m3 + m1) == 2 + m1.to() + m2.to()*m3.to()); \ + tassert(count_temporaries2(m1 + m3*m2) == ntemps); \ + tassert(b + (m3*m2 + m1) == 2 + m1.to() + m2.to()*m3.to()); \ + \ + tassert(count_temporaries2(m1 - m2*m3) == ntemps); \ + tassert(b + (m1 - m2*m3) == 2 + m1.to() - m2.to()*m3.to()); \ + tassert(count_temporaries2(m1 - m3*m2) == ntemps); \ + tassert(b + (m1 - m3*m2) == 2 + m1.to() - m2.to()*m3.to()); \ + } }; inner::doit();} while(0) +#define TT(m1, m2, ntemps) TT3(m1, m2, d, ntemps) + + TT(T0, c, 1); + TT(T1, c, 1); + TT(T2, c, 2); + TT(T3, c, 3); + + TT(T0, T0, 2); + TT(T0, T1, 2); + TT(T0, T2, 2); + TT(T0, T3, 3); + +#if HAVE_FAST_COMPILER + TT(T1, T0, 2); + TT(T1, T1, 2); + TT(T1, T2, 2); + TT(T1, T3, 3); + + TT(T2, T0, 2); + TT(T2, T1, 2); + TT(T2, T2, 3); + TT(T2, T3, 3); + + TT(T3, T0, 3); + TT(T3, T1, 3); + TT(T3, T2, 3); + TT(T3, T3, 4); + + // NB: TT3 is symmetric in m2 and m3 +#define TT6(m1, m2, m3, ntemps) \ + TT3(m1, m2, m3, ntemps); \ + TT3(m2, m1, m3, ntemps); \ + TT3(m3, m1, m2, ntemps); + + TT6(fac(2u), fac(3u), fac(4u), 3); + TT6(T1, T2, T3, 3); + TT6(T1, T2, T4, 4); + TT6(T1, (d+d+d) /* T1' */, T4, 4); + TT6(T0, fac(2u), T2, 3); + TT6(T0, T1, (d+d+d), 3); + TT6(T1, T3, (T2 + T1) /* T3' */, 3); +#endif +} + +void +test_ternary_assigments() +{ + fmpzxx a(2), b(3), c(4); + tassert((a += b*c) == 14); + tassert(a == 14); + tassert((a -= b*c) == 2); + tassert(a == 2); + + tassert((a += (b+b)*c) == 26); + tassert((a -= (b+b)*c) == 2); + tassert((a += c*(b+b)) == 26); + tassert((a -= c*(b+b)) == 2); + + tassert((a += (b+b)*(c+c)) == 50); + tassert((a -= (b+b)*(c+c)) == 2); + + // Make sure that the general rule kicks + tassert((a += 3*c) == 14); + tassert((a -= 3*c) == 2); +} + +bool +try_implicit_conversion(fmpzxx_ref, const fmpzxx_ref&, + fmpzxx_srcref, const fmpzxx_srcref&, fmpzxx_srcref, const fmpzxx_srcref&) +{ + return true; +} +void +test_references() +{ + fmpzxx a(2), b(3); + fmpzxx_ref ar(a); + fmpzxx_srcref acr(a), bcr(b); + + tassert(ar == 2 && bcr == 3 && ar == acr && ar == a); + + // test assignments + fmpzxx d(ar); + a = 4; + tassert(ar == 4 && acr == 4 && d == 2); + ar = 2; + tassert(a == 2); + + // test some arithmetic + tassert(a + bcr == 5); + tassert(acr + bcr == 5); + tassert(ar + 3u == 5); + tassert(a < bcr && ar < b && acr < bcr); + tassert(rfac(acr, 1u) == 2); + + ar = bin(4u, 2u); tassert(acr == 6); + tassert(acr.to() == WORD(6)); + tassert(ar.to_string() == "6"); + ar += b; + ar += bcr; + tassert(a == 12); + + // test conversion of reference types + tassert(try_implicit_conversion(a, a, a, a, ar, ar)); + tassert((!traits::_is_convertible::val)); + tassert((!traits::_is_convertible::val)); + tassert((!traits::_is_convertible::val)); + + // test creation from C types + fmpzxx_ref ar2 = fmpzxx_ref::make(a._fmpz()); + fmpzxx_srcref acr2 = fmpzxx_srcref::make(acr._fmpz()); + a = 7; + tassert(ar2 == 7 && acr2 == 7); + + // test swapping + a = 2; + b = 3; + swap(b, ar); + tassert(a == 3 && b == 2); + // make sure ADL is preferred over the general version in std + using namespace std; + swap(b, b); +} + +void +test_randomisation() +{ + frandxx rand; + tassert(abs(fmpzxx::randbits(rand, 5)) <= 31); + tassert(abs(fmpzxx::randbits(rand, 5)) >= 16); + tassert(abs(fmpzxx::randtest(rand, 5)) <= 31); + tassert(fmpzxx::randtest_unsigned(rand, 5) <= 31); + tassert(fmpzxx::randtest_unsigned(rand, 5) >= 0); + tassert(fmpzxx::randtest_not_zero(rand, 5) != 0); + fmpzxx thirty(30); + tassert(fmpzxx::randm(rand, thirty) >= 0); + tassert(fmpzxx::randm(rand, thirty) <= 29); + tassert(fmpzxx::randtest_mod(rand, thirty) >= 0); + tassert(fmpzxx::randtest_mod(rand, thirty) <= 29); + tassert(fmpzxx::randtest_mod_signed(rand, thirty) > -15); + tassert(fmpzxx::randtest_mod_signed(rand, thirty) <= 15); +} + +void +test_factoring() +{ + fmpz_factorxx f;f = factor(-2*3*5); + tassert(f.size() == 3); + tassert(f.sign() == -1); + tassert(f.p(0) == 2 && f.exp(0) == 1); + tassert(f.p(1) == 3 && f.exp(1) == 1); + tassert(f.p(2) == 5 && f.exp(2) == 1); + tassert(f == factor(fmpzxx(-2*3*5))); + tassert(f == fmpz_factorxx(f)); + tassert(f == factor_trial_range(fmpzxx(-2*3*5), 0u, 2u).get<1>()); + tassert(factor_trial_range(fmpzxx(-2*3*5), 0u, 2u).get<0>()); + + tassert(f.expand() == -2*3*5); + tassert(f.expand() == f.expand_iterative()); + tassert(f.expand() == f.expand_multiexp()); + + if(0) + print(f); // make sure this compiles +} + +void +test_crt() +{ + frandxx rand; + fmpzxx x = fmpzxx::randtest_unsigned(rand, 25); + std::vector primes; + primes.push_back(1031); + primes.push_back(1033); + primes.push_back(1039); + + fmpz_combxx comb(primes); + std::vector residues(primes.size()); + multi_mod(residues, x, comb); + + fmpzxx prod(1); + fmpzxx res; + for(unsigned i = 0;i < primes.size();++i) + { + tassert(residues[i] == x % primes[i]); + res = res.CRT(prod, residues[i], primes[i], false); + prod *= primes[i]; + } + tassert(res == x); + + res = multi_CRT(residues, comb, false); + tassert(res == x); +} + +int +main() +{ + std::cout << "fmpzxx...."; + + test_printing(); + test_order(); + test_conversion(); + test_initialisation_assignment(); + test_arithmetic(); + test_functions(); + test_member_functions(); + test_traits(); + test_temporaries(); + test_ternary(); + test_ternary_assigments(); + test_references(); + test_randomisation(); + test_factoring(); + test_crt(); + test_print_read(fmpzxx(-17)); + + // TODO test that certain things *don't* compile? + // TODO test enable_all_fmpzxx + + std::cout << "PASS" << std::endl; +} diff --git a/external/flint-2.4.3/flintxx/test/t-forwarding.cpp b/external/flint-2.4.3/flintxx/test/t-forwarding.cpp new file mode 100644 index 0000000..4531d5a --- /dev/null +++ b/external/flint-2.4.3/flintxx/test/t-forwarding.cpp @@ -0,0 +1,165 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +// XXX NOTE: the forwarding code was never completed, and neither was this +// test file. + +#include +#include + +#include "flintxx/forwarding.h" + +#include "flintxx/test/myint.h" +#include "flintxx/test/helpers.h" + +using namespace flint; + +template +class forwarded_expression + : public expression, Operation, Data> +{ +public: + forwarded_expression() {}; + template + explicit forwarded_expression(const T& t) + : expression, + Operation, Data>(t) {} + + template + forwarded_expression& operator=(const T& t) + { + this->set(t); + return *this; + } + +protected: + explicit forwarded_expression(const Data& d) + : expression, + Operation, Data>(d) {} + + template + friend class ::flint::expression; +}; + +struct hide_myint +{ + myint i; + template + hide_myint(const T& t) : i(t) {} + hide_myint() {} +}; + +typedef forwarded_expression fwint; + +namespace flint { +namespace forwarding { +template<> +struct enable + : mp::true_ +{ + typedef myint underlying_t; + static const myint& get_underlying(const fwint& fwd) + { + return fwd._data().i; + } + static myint& get_underlying(fwint& fwd) + { + return fwd._data().i; + } +}; + +} +} + +void +test_print() +{ + fwint fwd(4); + std::ostringstream oss; + oss << fwd; + tassert(oss.str() == "4"); +} + +void +test_assignment() +{ + fwint f1, f2(4); + + f1 = WORD(3); // TODO understand why "3" seems to lead to circular dependency + tassert(f1 == 3); + + f1 = f2; + tassert(f1 == 4); +} + +void +test_equals() +{ + fwint f1(4), f2(5); + myint m1(4); + + tassert(f1 == f1); + tassert(f1 != f2); + tassert(f1 == 4); + tassert(5 != f1); + tassert(f1 == m1); + tassert(m1 != f2); +} + +void +test_conversion() +{ + fwint a(4); + + tassert(typed_equals(a.to(), 4)); +} + +void +test_evaluation() +{ + fwint a(4); + myint b(5); + + tassert(typed_equals((a + a).evaluate(), myint(8))); + tassert(a + b == 9); + tassert(a + 6 == 10); + tassert((a + 6) + b == 15); +} + +int +main() +{ + std::cout << "forwarding...."; + + test_print(); + test_assignment(); + // TODO test cmp + test_equals(); + test_conversion(); + test_evaluation(); + + std::cout << "PASS" << std::endl; + return 0; +} diff --git a/external/flint-2.4.3/flintxx/test/t-ltuple.cpp b/external/flint-2.4.3/flintxx/test/t-ltuple.cpp new file mode 100644 index 0000000..3e5d923 --- /dev/null +++ b/external/flint-2.4.3/flintxx/test/t-ltuple.cpp @@ -0,0 +1,192 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#include "flintxx/ltuple.h" +#include "fmpzxx.h" + +#include "flintxx/test/helpers.h" +#include "flintxx/test/myint.h" + +using namespace flint; + +void +test_traits() +{ + tassert(!traits::is_ltuple_expr::val); + tassert(!traits::is_ltuple_expr::val); +} + +namespace flint { +typedef make_ltuple::type>::type fmpzxxint_pair; +typedef make_ltuple::type>::type mylongint_pair; +FLINT_DEFINE_BINOP(make_lazy_test) +namespace rules { +FLINT_DEFINE_BINARY_EXPR_COND2(make_lazy_test_op, fmpzxxint_pair, + FMPZXX_COND_S, traits::is_signed_integer, + to.template get<0>() = e1;to.template get<1>() = e2) +FLINT_DEFINE_BINARY_EXPR2(make_lazy_test_op, mylongint_pair, + mylong, int, + to.template get<0>() = e1;to.template get<1>() = e2) +} +} + +void +test_equals() +{ + typedef mp::make_tuple maker; + typedef mp::make_tuple refmaker; + typedef mp::make_tuple srcrefmaker; + typedef make_ltuple lmaker; + typedef make_ltuple lrefmaker; + typedef make_ltuple lsrcrefmaker; + + fmpzxx f; + int a = 12345; + lmaker::type ltuple(detail::INSTANTIATE_FROM_TUPLE(), + maker::make(fmpzxx(1), 2)); + lrefmaker::ref_type lref(detail::INSTANTIATE_FROM_TUPLE(), refmaker::make(f, a)); + lsrcrefmaker::srcref_type lsrcref(detail::INSTANTIATE_FROM_TUPLE(), srcrefmaker::make( + ltuple._data().inner.head, ltuple._data().inner.tail.head)); + + tassert(ltuple == ltuple); + tassert(ltuple != lref); + tassert(ltuple == lsrcref); + tassert(lref != lsrcref); + f = 1; + a = 2; + tassert(ltuple == lref); + tassert(lref == lsrcref); + + tassert(ltuple == make_lazy_test(fmpzxx(1), 2)); +} + +void +test_assignment() +{ + typedef mp::make_tuple maker; + typedef mp::make_tuple refmaker; + typedef mp::make_tuple srcrefmaker; + typedef make_ltuple lmaker; + + fmpzxx f; + int a; + lmaker::type ltuple(detail::INSTANTIATE_FROM_TUPLE(), + maker::make(fmpzxx(1), 2)); + lmaker::ref_type lref(detail::INSTANTIATE_FROM_TUPLE(), refmaker::make(f, a)); + lref = ltuple; + tassert(f == 1 && a == 2); + + f = 0; + a = 0; + lmaker::srcref_type lsrcref(detail::INSTANTIATE_FROM_TUPLE(), srcrefmaker::make( + ltuple._data().inner.head, ltuple._data().inner.tail.head)); + ltuple._data().inner.head = 17; + lref = lsrcref; + tassert(f == 17 && a == 2); + + f = 3; + a = 4; + ltuple = lref; + tassert(ltuple._data().inner.head == 3 + && ltuple._data().inner.tail.head == 4); + + lref = make_lazy_test(fmpzxx(17), 18); + tassert(f == 17 && a == 18); +} + +void +test_ltupleref() +{ + fmpzxx a, b; + int c; + + ltupleref(c) = ltuple(2); + tassert(c == 2); + + ltupleref(a, c) = ltuple(fmpzxx(3), 4); + tassert(a == 3 && c == 4); + + // test assignment with type conversion + ltupleref(a, b, c) = ltuple(1, 2, 4u); + tassert(a == 1 && b == 2 && c == 4); + + // test assignment with c-style references + ltuple(fmpzxx_ref(a)) = ltuple(b); + tassert(a == 2); +} + +template +bool is_lazy(const T&) +{ + return traits::is_lazy_expr::val; +} +void +test_get() +{ + fmpzxx a(1); int b = 2; + tassert(ltuple(a, b).get<0>() == a && ltuple(a, b).get<1>() == b); + ltupleref(a, b).get<0>() = 17; + ltupleref(a, b).get<1>() = 15; + tassert(a == 17 && b == 15); + tassert(make_lazy_test(a, 3).get<0>() == 17); + tassert(is_lazy(make_lazy_test(a, 3).get<0>())); + tassert(make_lazy_test(a, 3).get<1>() == 3); +} + +void +test_placeholder() +{ + fmpzxx a; int b; + ltupleref(a, _) = make_lazy_test(fmpzxx(17), 5); + tassert(a == 17); + ltupleref(_, b) = make_lazy_test(fmpzxx(18), 6); + tassert(b == 6 && a == 17); + ltupleref(_, _) = make_lazy_test(fmpzxx(1), 2); + tassert(b == 6 && a == 17); +} + +void +test_create_temporaries() +{ + tassert(make_lazy_test(mylong(1), 2).get<0>() == mylong(1)); +} + +int +main() +{ + std::cout << "ltuple...."; + + test_traits(); + test_equals(); + test_assignment(); + test_ltupleref(); + test_get(); + test_placeholder(); + test_create_temporaries(); + + std::cout << "PASS" << std::endl; + + return 0; +} diff --git a/external/flint-2.4.3/flintxx/test/t-mp.cpp b/external/flint-2.4.3/flintxx/test/t-mp.cpp new file mode 100644 index 0000000..96106f5 --- /dev/null +++ b/external/flint-2.4.3/flintxx/test/t-mp.cpp @@ -0,0 +1,133 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#include "flintxx/test/helpers.h" +#include "flintxx/mp.h" + +using namespace flint; +using namespace mp; + +void +test_equal_types() +{ + tassert((equal_types::val)); + tassert((!equal_types::val)); +} + +void +test_logic() +{ + tassert(not_::val == false); + tassert(not_::val == true); + + tassert((and_::val == true)); + tassert((and_::val == false)); + tassert((and_::val == false)); + + tassert((and_v::val == true)); + tassert((and_v::val == false)); + tassert((and_v::val == false)); + + tassert((or_::val == true)); + tassert((or_::val == true)); + tassert((or_::val == false)); + + tassert((and_::val == true)); + tassert((and_::val == false)); + tassert((and_::val == false)); + tassert((and_::val == false)); +} + +template +typename enable_if, int>::type test_enable_if_1(T) +{ + return 0; +} +template +typename disable_if, int>::type test_enable_if_1(T) +{ + return 1; +} +template +int test_enable_if_2(T, typename enable_if >::type* = 0) +{ + return 0; +} +template +int test_enable_if_2(T, typename disable_if >::type* = 0) +{ + return 1; +} + +void +test_enable_if() +{ + tassert(test_enable_if_1(int(1)) == 0); + tassert(test_enable_if_1(unsigned(1)) == 1); + tassert(test_enable_if_2(int(1)) == 0); + tassert(test_enable_if_2(unsigned(1)) == 1); +} + +void +test_if() +{ + tassert((equal_types::type, int>::val)); + tassert((equal_types::type, slong>::val)); + + typedef mp::select s1; + tassert((equal_types::val)); + + typedef mp::select s2; + tassert((equal_types::val)); + + typedef mp::select s3; + tassert((equal_types::val)); + + typedef mp::select s4; + tassert((equal_types::val)); + + typedef mp::select s5; + tassert((equal_types::val)); + + typedef mp::select s6; + tassert((equal_types::val)); + + typedef mp::select s7; + tassert((equal_types::val)); +} + +int +main() +{ + std::cout << "mp...."; + + test_equal_types(); + test_logic(); + test_enable_if(); + test_if(); + + std::cout << "PASS" << std::endl; + return 0; +} diff --git a/external/flint-2.4.3/flintxx/test/t-nmod_matxx.cpp b/external/flint-2.4.3/flintxx/test/t-nmod_matxx.cpp new file mode 100644 index 0000000..a626d0c --- /dev/null +++ b/external/flint-2.4.3/flintxx/test/t-nmod_matxx.cpp @@ -0,0 +1,327 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#include + +#include "nmod_matxx.h" + +#include "flintxx/test/helpers.h" + +using namespace flint; + +void +test_init() +{ + mp_limb_t M = 1039; + nmod_matxx A(3, 4, M); + nmodxx_ctx_srcref ctx = A.estimate_ctx(); + tassert(ctx.n() == M); + tassert((A + A).modulus() == M); + tassert(A.rows() == 3 && A.cols() == 4); + tassert(A.at(0, 0) == nmodxx::red(0, ctx)); + A.at(0, 0) = nmodxx::red(1, ctx); + + nmod_matxx B(A); + tassert(A == B); + tassert(B.rows() == 3 && B.cols() == 4); + tassert(B.at(0, 0) == nmodxx::red(1, ctx)); + B.at(0, 0) = nmodxx::red(0, ctx); + tassert(A.at(0, 0) == nmodxx::red(1, ctx)); + tassert(A != B); + + B = A; + tassert(A == B); + + A.set_zero(); + tassert(A.is_zero() && A == nmod_matxx::zero(A.rows(), A.cols(), A.modulus())); +} + +template +bool has_explicit_temporaries(const Expr&) +{ + return Expr::ev_traits_t::rule_t::temporaries_t::len != 0; +} +void +test_arithmetic() +{ + mp_limb_t M = 1039; + nmod_matxx A(10, 10, M); + nmod_matxx v(10, 1, M); + nmodxx_ctx_srcref ctx = A.estimate_ctx(); + for(unsigned i = 0;i < 10;++i) + v.at(i, 0) = nmodxx::red(i, ctx); + nmodxx two = nmodxx::red(2, ctx); + + tassert(transpose(v).rows() == 1); + tassert(v.transpose().cols() == 10); + tassert((two*v).rows() == 10); + tassert((v*two).rows() == 10); + tassert((v*transpose(v)).rows() == 10 && (v*transpose(v)).cols() == 10); + + tassert(!has_explicit_temporaries(trace(transpose(v)))); + tassert(!has_explicit_temporaries(trace(A + v*transpose(v)))); + tassert(!has_explicit_temporaries(A + v*transpose(v))); + tassert(!has_explicit_temporaries(trace((v*transpose(v) + A)))); + tassert(!has_explicit_temporaries(trace(v*transpose(v) + v*transpose(v)))); + tassert(!has_explicit_temporaries(v*transpose(v) + v*transpose(v))); + + tassert(trace(transpose(v)) == nmodxx::red(0, ctx)); + tassert(trace(A + v*transpose(v)) == nmodxx::red(285, ctx)); + tassert(trace(v*transpose(v) + A) == nmodxx::red(285, ctx)); + tassert(trace(v*transpose(v) + v*transpose(v)) == nmodxx::red(2*285, ctx)); + tassert(trace((A+A)*(nmodxx::red(1, ctx) + nmodxx::red(1, ctx))) + == nmodxx::red(0, ctx)); + + for(unsigned i = 0;i < 10; ++i) + for(unsigned j = 0; j < 10; ++j) + A.at(i, j) = nmodxx::red(i*j, ctx); + tassert(A == v*transpose(v)); + tassert(A != transpose(v)*v); + A.at(0, 0) = nmodxx::red(15, ctx); + tassert(A != v*transpose(v)); + + A.at(0, 0) = nmodxx::red(0, ctx); + for(unsigned i = 0;i < 10; ++i) + for(unsigned j = 0; j < 10; ++j) + A.at(i, j) *= two; + tassert(A == v*transpose(v) + v*transpose(v)); + tassert(A - v*transpose(v) == v*transpose(v)); + tassert(((-A) + A).is_zero()); + tassert((A + A).at(0, 0) == A.at(0, 0) + A.at(0, 0)); +} + +void +test_functions() +{ + mp_limb_t M = 1031; + nmod_matxx A(2, 3, M), B(2, 2, M), empty(0, 15, M); + nmodxx_ctx_srcref ctx = A.estimate_ctx(); + B.at(0, 0) = nmodxx::red(1, ctx); + tassert(A.is_zero() && !A.is_empty() && !A.is_square()); + tassert(!B.is_zero() == B.is_square()); + tassert(empty.is_zero() && empty.is_empty()); + + // transpose tested in arithmetic + // mul tested in arithmetic + // trace tested in arithmetic + + frandxx rand; + A.set_randtest(rand); + B.set_randtest(rand); + tassert(B*A == B.mul_classical(A)); + tassert(B*A == B.mul_strassen(A)); + + B.set_randrank(rand, 1); + tassert(B.det() == nmodxx::red(0, ctx)); + B.set_randrank(rand, 2); + tassert(B.det() != nmodxx::red(0, ctx)); + + B.set_randrank(rand, 1); + assert_exception(B.inv().evaluate()); + + B.set_randrank(rand, 2); + nmod_matxx eye(2, 2, M); + eye.at(0, 0) = nmodxx::red(1, ctx);eye.at(1, 1) = nmodxx::red(1, ctx); + tassert(B.inv() * B == eye); + + A.set_randrank(rand, 2); + tassert(rank(A) == 2); + + B.set_randtril(rand, false); + tassert(B*B.solve_tril(A, false) == A); + tassert(B.solve_tril_classical(A, false) == B.solve_tril(A, false)); + tassert(B.solve_tril_recursive(A, false) == B.solve_tril(A, false)); + B.set_randtriu(rand, true); + tassert(B*B.solve_triu(A, true) == A); + tassert(B.solve_triu_classical(A, true) == B.solve_triu(A, true)); + tassert(B.solve_triu_recursive(A, true) == B.solve_triu(A, true)); + + B.set_randrank(rand, 2); + tassert(B*B.solve(A) == A); + nmod_vecxx X(2, ctx); X[0] = nmodxx::red(1, ctx); X[1] = nmodxx::red(2, ctx); + X = B.solve(X); + tassert(B.at(0, 0)*X[0] + B.at(0, 1) * X[1] == nmodxx::red(1, ctx)); + tassert(B.at(1, 0)*X[0] + B.at(1, 1) * X[1] == nmodxx::red(2, ctx)); + + B.set_randrank(rand, 1); + assert_exception(B.solve(A).evaluate()); + assert_exception(B.solve(X).evaluate()); + + slong nullity;nmod_matxx C(3, 3, M); + tassert(nullspace(A).get<1>().rows() == 3); + tassert(nullspace(A).get<1>().cols() == 3); + ltupleref(nullity, C) = nullspace(A); + tassert(nullity == 3 - rank(A)); + tassert(C.rank() == nullity); + tassert((A*C).is_zero()); + + A.set_rref(); + tassert(A.at(1, 0) == nmodxx::red(0, ctx)); +} + +void +test_randomisation() +{ + frandxx rand; + mp_limb_t M = 1031; + nmod_matxx A(2, 2, M); + nmodxx_ctx_srcref ctx = A.estimate_ctx(); + + // not really anything we can test about these ... + // just make sure the call works + A.set_randtest(rand); + A.set_randfull(rand); + + + nmod_vecxx v(2, ctx);v[0] = nmodxx::red(5, ctx);v[1] = nmodxx::red(7, ctx); + A.set_randpermdiag(rand, v); + tassert(A.at(0, 0) + A.at(0, 1) + A.at(1, 0) + A.at(1, 1) + == nmodxx::red(5 + 7, ctx)); + + A.set_randrank(rand, 1); + tassert(A.rank() == 1); + A.apply_randops(rand, 17); + tassert(A.rank() == 1); + + A.set_randtril(rand, true); + tassert(A.at(0, 0) == nmodxx::red(1, ctx)); + tassert(A.at(1, 1) == nmodxx::red(1, ctx)); + tassert(A.at(0, 1) == nmodxx::red(0, ctx)); + + A.set_randtriu(rand, false); + tassert(A.at(1, 0) == nmodxx::red(0, ctx)); + + frandxx rand2, rand3; + nmod_matxx B(2, 2, M); + + B.set_randtest(rand2); + tassert(B == nmod_matxx::randtest(2, 2, M, rand3)); + B.set_randfull(rand2); + tassert(B == nmod_matxx::randfull(2, 2, M, rand3)); + B.set_randrank(rand2, 1); + tassert(B == nmod_matxx::randrank(2, 2, M, rand3, 1)); + B.set_randtril(rand2, false); + tassert(B == nmod_matxx::randtril(2, 2, M, rand3, false)); + B.set_randtriu(rand2, false); + tassert(B == nmod_matxx::randtriu(2, 2, M, rand3, false)); + B.set_randpermdiag(rand2, v); + tassert(B == nmod_matxx::randpermdiag(2, 2, M, rand3, v)); +} + +void +test_reduction_reconstruction() +{ + std::vector primes; + primes.push_back(1031); + primes.push_back(1033); + primes.push_back(1039); + mp_limb_t M = primes[0]; + + frandxx rand; + fmpz_matxx A(5, 7);A.set_randtest(rand, 8); + nmod_matxx Ap = nmod_matxx::reduce(A, M); + nmodxx_ctx_srcref ctx = Ap.estimate_ctx(); + tassert(Ap.rows() == A.rows() && Ap.cols() == A.cols()); + for(slong i = 0;i < A.rows();++i) + for(slong j = 0;j < A.cols();++j) + tassert(Ap.at(i, j) == nmodxx::red(A.at(i, j), ctx)); + tassert(A == fmpz_matxx::lift(Ap)); + + for(slong i = 0;i < A.rows();++i) + for(slong j = 0;j < A.cols();++j) + A.at(i, j) = abs(A.at(i, j)); + tassert(A == fmpz_matxx::lift_unsigned(nmod_matxx::reduce(A, M))); + + nmod_mat_vector v1(A.rows(), A.cols(), primes); + nmod_mat_vector v2(v1); + tassert(v1 == v2); + v2[0].at(0, 0) += nmodxx::red(1, ctx); + tassert(v2[0].at(0, 0) != v1[0].at(0, 0)); + tassert(v1 != v2); + v2 = v1; + tassert(v1 == v2); + + A.set_randtest(rand, 25); + for(unsigned i = 0;i < primes.size();++i) + v1[i] = nmod_matxx::reduce(A, primes[i]); + tassert(v1 == multi_mod(A, primes)); + + fmpz_combxx comb(primes); + tassert(multi_mod(A, primes) == multi_mod_precomp(A, primes, comb)); + + fmpzxx prod(1); + fmpz_matxx res(A.rows(), A.cols()); + for(unsigned i = 0;i < primes.size();++i) + { + res = res.CRT(prod, v1[i], true); + prod *= primes[i]; + } + tassert(res == A); + tassert(res == multi_CRT(v1, true)); + tassert(res == multi_CRT_precomp(v1, comb, true)); +} + +void +test_lu() +{ + frandxx rand; + nmod_matxx A = nmod_matxx::randtest(5, 5, 1031, rand); + nmod_matxx B1(A), B2(A); + nmod_matxx::lu_rt res = B1.set_lu(); + permxx perm(5); + slong rank = nmod_mat_lu(perm._data(), B2._mat(), false); + tassert(B1 == B2 && rank == res.first() && perm == res.second()); + + B1 = A; B2 = A; + tassert(B1.set_lu_classical() == B2.set_lu() && B1 == B2); + + B1 = A; B2 = A; + tassert(B1.set_lu_recursive() == B2.set_lu() && B1 == B2); +} + +void +test_printing() +{ + if(0) + print_pretty(nmod_matxx::zero(2, 2, 7)); // make sure this compiles +} + +int +main() +{ + std::cout << "nmod_matxx...."; + + test_init(); + test_arithmetic(); + test_functions(); + test_randomisation(); + test_reduction_reconstruction(); + test_lu(); + test_printing(); + + std::cout << "PASS" << std::endl; + return 0; +} + diff --git a/external/flint-2.4.3/flintxx/test/t-nmod_poly_matxx.cpp b/external/flint-2.4.3/flintxx/test/t-nmod_poly_matxx.cpp new file mode 100644 index 0000000..8230f8d --- /dev/null +++ b/external/flint-2.4.3/flintxx/test/t-nmod_poly_matxx.cpp @@ -0,0 +1,279 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#include + +#include "nmod_poly_matxx.h" + +#include "flintxx/test/helpers.h" + +using namespace flint; + +void +test_init() +{ + mp_limb_t M = 1039; + nmod_poly_matxx A(3, 4, M); + nmodxx_ctx_srcref ctx = A.estimate_ctx(); + tassert(ctx.n() == M); + tassert((A + A).modulus() == M); + tassert(A.rows() == 3 && A.cols() == 4); + tassert(A.at(0, 0) == nmod_polyxx::from_ground(0, ctx)); + A.at(0, 0) = nmod_polyxx::from_ground(1, ctx); + + nmod_poly_matxx B(A); + tassert(A == B); + tassert(B.rows() == 3 && B.cols() == 4); + tassert(B.at(0, 0) == nmod_polyxx::from_ground(1, ctx)); + B.at(0, 0) = nmod_polyxx::from_ground(0, ctx); + tassert(A.at(0, 0) == nmod_polyxx::from_ground(1, ctx)); + tassert(A != B); + + B = A; + tassert(A == B); + + frandxx state; + nmod_matxx C(A.rows(), A.cols(), A.modulus()); + C.set_randtest(state); + A = nmod_poly_matxx::from_ground(C); + for(slong i = 0;i < A.rows();++i) + for(slong j = 0;j < A.cols();++j) + tassert(A.at(i, j) == nmod_polyxx::from_ground(C.at(i, j))); + + tassert(nmod_poly_matxx::zero(2, 2, M).is_zero() + && nmod_poly_matxx::one(2, 2, M).is_one()); +} + +template +bool has_explicit_temporaries(const Expr&) +{ + return Expr::ev_traits_t::rule_t::temporaries_t::len != 0; +} +void +test_arithmetic() +{ + mp_limb_t M = 1039; + nmod_poly_matxx A(10, 10, M); + nmod_poly_matxx v(10, 1, M); + nmodxx_ctx_srcref ctx = A.estimate_ctx(); + for(unsigned i = 0;i < 10;++i) + v.at(i, 0) = nmod_polyxx::from_ground(i, ctx); + nmod_polyxx two = nmod_polyxx::from_ground(2, ctx); + + tassert(transpose(v).rows() == 1); + tassert(v.transpose().cols() == 10); + tassert((two*v).rows() == 10); + tassert((v*two).rows() == 10); + tassert((v*transpose(v)).rows() == 10 && (v*transpose(v)).cols() == 10); + + tassert(!has_explicit_temporaries(trace(transpose(v)))); + tassert(!has_explicit_temporaries(trace(A + v*transpose(v)))); + tassert(!has_explicit_temporaries(A + v*transpose(v))); + tassert(!has_explicit_temporaries(trace((v*transpose(v) + A)))); + tassert(!has_explicit_temporaries(trace(v*transpose(v) + v*transpose(v)))); + tassert(!has_explicit_temporaries(v*transpose(v) + v*transpose(v))); + + tassert(trace(transpose(v)) == nmod_polyxx::from_ground(0, ctx)); + tassert(trace(A + v*transpose(v)) == nmod_polyxx::from_ground(285, ctx)); + tassert(trace(v*transpose(v) + A) == nmod_polyxx::from_ground(285, ctx)); + tassert(trace(v*transpose(v) + v*transpose(v)) + == nmod_polyxx::from_ground(2*285, ctx)); + tassert(trace((A+A)*(nmod_polyxx::from_ground(1, ctx) + + nmod_polyxx::from_ground(1, ctx))) + == nmod_polyxx::from_ground(0, ctx)); + + for(unsigned i = 0;i < 10; ++i) + for(unsigned j = 0; j < 10; ++j) + A.at(i, j) = nmod_polyxx::from_ground(i*j, ctx); + tassert(A == v*transpose(v)); + tassert(A != transpose(v)*v); + A.at(0, 0) = nmod_polyxx::from_ground(15, ctx); + tassert(A != v*transpose(v)); + + A.at(0, 0) = nmod_polyxx::from_ground(0, ctx); + for(unsigned i = 0;i < 10; ++i) + for(unsigned j = 0; j < 10; ++j) + A.at(i, j) *= two; + tassert(A == v*transpose(v) + v*transpose(v)); + tassert(A - v*transpose(v) == v*transpose(v)); + tassert(((-A) + A).is_zero()); + tassert((A + A).at(0, 0) == A.at(0, 0) + A.at(0, 0)); + + tassert(A * nmodxx::red(17, ctx) == A * nmod_polyxx::from_ground(17, ctx)); + + frandxx rand; + nmodxx x = nmodxx::red(17, ctx); + A.set_randtest(rand, 5); + nmod_matxx B(A.rows(), A.cols(), M); + B = A(x); + for(slong i = 0;i < A.rows();++i) + for(slong j = 0;j < A.cols();++j) + tassert(B.at(i, j) == A.at(i, j)(x)); + tassert(A(x) == evaluate(A, x)); +} + +void +test_functions() +{ + mp_limb_t M = 1031; + nmod_poly_matxx A(2, 3, M), B(2, 2, M), empty(0, 15, M); + nmodxx_ctx_srcref ctx = A.estimate_ctx(); + B.at(0, 0) = nmod_polyxx::from_ground(1, ctx); + tassert(A.is_zero() && !A.is_empty() && !A.is_square() && !A.is_one()); + tassert(!B.is_zero() == B.is_square()); + tassert(empty.is_zero() && empty.is_empty()); + B.at(1, 1) = B.at(0, 0); + tassert(B.is_one()); + + // transpose tested in arithmetic + // mul tested in arithmetic + // trace tested in arithmetic + + A.at(0, 0).set_coeff(35, 1); + tassert(A.max_length() == 36); + + frandxx rand; + A.set_randtest(rand, 5); + B.set_randtest(rand, 5); + tassert(B*A == B.mul_classical(A)); + tassert(B*A == B.mul_KS(A)); + tassert(B*A == B.mul_interpolate(A)); + + tassert(B.sqr() == B*B); + tassert(B.sqr_classical() == B*B); + tassert(B.sqr_KS() == B*B); + tassert(B.sqr_interpolate() == B*B); + + tassert(B.pow(5u) == B*B.sqr().sqr()); + + nmod_matxx Bp(B.rows(), B.cols(), B.modulus()); + Bp.set_randrank(rand, 1); + tassert(nmod_poly_matxx::from_ground(Bp).det().is_zero()); + Bp.set_randrank(rand, 2); + tassert(nmod_poly_matxx::from_ground(Bp).det() + == nmod_polyxx::from_ground(Bp.det())); + + Bp.set_randrank(rand, 1); + tassert(inv(nmod_poly_matxx::from_ground(Bp)).get<0>() == false); + + Bp.set_randrank(rand, 2); + bool worked;nmod_polyxx den(B.modulus()); + ltupleref(worked, B, den) = inv(nmod_poly_matxx::from_ground(Bp)); + tassert(worked && B*nmod_poly_matxx::from_ground(Bp)*A == A*den); + + tassert(rank(B) == 2); + + Bp.set_randrank(rand, 1); + tassert(nmod_poly_matxx::from_ground(Bp).solve(A).get<0>() == false); + Bp.set_randrank(rand, 2); + nmod_poly_matxx P(A.rows(), A.cols(), A.modulus()); + ltupleref(worked, P, den) = nmod_poly_matxx::from_ground(Bp).solve(A); + tassert(worked && nmod_poly_matxx::from_ground(Bp)*P == A*den); + B = nmod_poly_matxx::from_ground(Bp); + tassert(B.solve(A) == B.solve_fflu(A)); + + permxx perm(B.rows()); + tassert(solve_fflu_precomp(perm, B.fflu(&perm, false).get<1>().evaluate(), A) + == B.solve_fflu(A).get<1>()); + + Bp.set_randtest(rand); + B = nmod_poly_matxx::from_ground(Bp); + slong nullity;nmod_poly_matxx C(2, 2, M); + tassert(nullspace(B).get<1>().rows() == 2); + tassert(nullspace(B).get<1>().cols() == 2); + ltupleref(nullity, C) = nullspace(B); + tassert(nullity == 2 - rank(B)); + tassert(C.rank() == nullity); + tassert((B*C).is_zero()); + + B.set_zero();tassert(B.is_zero()); +} + +void +test_randomisation() +{ + frandxx rand, rand2; + mp_limb_t M = 1031; + nmod_poly_matxx A(2, 2, M); + + A.set_randtest(rand, 17); + tassert(A.at(0, 0).length() <= 17); + tassert(A == nmod_poly_matxx::randtest(2, 2, M, rand2, 17)); + A.set_randtest_sparse(rand, 17, 0.5); + tassert(A.at(0, 0).length() <= 17); + tassert(A == nmod_poly_matxx::randtest_sparse(2, 2, M, rand2, 17, 0.5)); +} + +void +test_row_reduction() +{ + frandxx state; + nmod_poly_matxx A = nmod_poly_matxx::randtest(5, 5, 1031, state, 7); + slong rank1, rank2; + nmod_polyxx den1(A.modulus()), den2(A.modulus()); + nmod_poly_matxx res1(A.rows(), A.cols(), A.modulus()); + nmod_poly_matxx res2(res1); + + tassert(find_pivot_any(A, 2, 4, 1) + == nmod_poly_mat_find_pivot_any(A._mat(), 2, 4, 1)); + tassert(find_pivot_partial(A, 2, 4, 1) + == nmod_poly_mat_find_pivot_partial(A._mat(), 2, 4, 1)); + tassert(A.fflu(0, false).get<1>().rows() == A.rows()); + permxx p1(5), p2(5); + ltupleref(rank1, res1, den1) = fflu(A, &p1); + rank2 = nmod_poly_mat_fflu(res2._mat(), den2._poly(), p2._data(), + A._mat(), false); + tassert(rank1 == rank2 && res1 == res2 && p1 == p2 && den1 == den2); + tassert(rank1 == A.fflu(0, false).get<0>()); + + ltupleref(rank1, res1, den1) = rref(A); + rank2 = nmod_poly_mat_rref(res2._mat(), den2._poly(), A._mat()); + tassert(rank1 == rank2 && res1 == res2 && p1 == p2 && den1 == den2); +} + + +void +test_printing() +{ + if(0) + print_pretty(nmod_poly_matxx::zero(2, 2, 7), "x"); // make sure this compiles +} + +int +main() +{ + std::cout << "nmod_poly_matxx...."; + + test_init(); + test_arithmetic(); + test_functions(); + test_randomisation(); + test_row_reduction(); + test_printing(); + + std::cout << "PASS" << std::endl; + return 0; +} + diff --git a/external/flint-2.4.3/flintxx/test/t-nmod_polyxx.cpp b/external/flint-2.4.3/flintxx/test/t-nmod_polyxx.cpp new file mode 100644 index 0000000..1873198 --- /dev/null +++ b/external/flint-2.4.3/flintxx/test/t-nmod_polyxx.cpp @@ -0,0 +1,522 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#include +#include +#include + +#include "fmpq_polyxx.h" +#include "fmpz_polyxx.h" +#include "nmod_polyxx.h" + +#include "flintxx/test/helpers.h" + +using namespace flint; + +void +test_init() +{ + nmod_polyxx p(10); + tassert(p.length() == 0); + tassert(p.modulus() == 10); + + nmodxx_ctx_srcref ctx = p.estimate_ctx(); + tassert(p == nmod_polyxx::from_ground(nmodxx::red(0, ctx))); + p.set_coeff(0, 1); + tassert(p == nmod_polyxx::from_ground( + (nmodxx::red(1, ctx)) + (nmodxx::red(0, ctx)))); + + tassert(nmod_polyxx::zero(13).is_zero() && nmod_polyxx::one(13).is_one()); +} + +void +test_manipulation() +{ + mp_limb_t M = 31; + nmod_polyxx p(M), q(M); + nmodxx_ctx_srcref ctx = p.estimate_ctx(); + p.set_coeff(5, 17 + M); + tassert(p.degree() == 5); + q.set_coeff(5, nmodxx::red(17, ctx)); + tassert((q + nmod_polyxx(M)).get_coeff(5) == + nmodxx::red(17, ctx)); + p.set_coeff(0, nmodxx::red(1, ctx)); + tassert(p != q); + p.set_coeff(0, 0); + tassert(p == q); + + tassert(p.length() == 6); + + p.realloc(0); + tassert(p.is_zero() && !p.is_one()); + p.set_coeff(0, 1); + tassert(p.is_one()); +} + +void +test_assignment() +{ + mp_limb_t M = 31; + nmod_polyxx p(M), q(M); + p.set_coeff(0, 1); + tassert(p != q); + p = q; + tassert(p == q); + + p = "4 31 0 0 0 1"; + q.set_coeff(3, 1); + tassert(p == q); + + tassert(p == nmod_polyxx("4 31 0 0 0 1")); + + // TODO XXX this does not always fail? + //assert_exception(p = "2 1 2"); + assert_exception(p = "2 x 2"); + assert_exception(nmod_polyxx("2 x 2")); +} + +void +test_conversion() +{ + nmod_polyxx p(31); + p.set_coeff(3, 1); + tassert(p.to_string() == "4 31 0 0 0 1"); +} + +void +test_arithmetic() +{ + mp_limb_t M = 31; + nmod_polyxx g(M), h(M); + nmodxx_ctx_srcref ctx = g.estimate_ctx(); + g.set_coeff(0, 17); h.set_coeff(0, 15); + tassert((g + h).get_coeff(0) == nmodxx::red(15 + 17, ctx)); + + frandxx state; + g.set_randtest(state, 10); + h.set_randtest(state, 10); + + tassert(((-g) + g).is_zero()); + tassert(g - h == g + (-h)); + + tassert(g*nmodxx::red(3, ctx) == g + g + g); + tassert(g.make_monic() == g*inv(g.get_coeff(g.degree()))); + + nmod_polyxx f(M);f.set_coeff(0, 15); + tassert(f*g == nmodxx::red(15, ctx)*g); + tassert(h.mul_classical(g) == h.mul_KS(g) && h.mul_KS(g) == h*g); + + f = h*g;f.truncate(7); + tassert(f == mullow(h, g, 7)); + tassert(f == h.mullow_KS(g, 7)); + tassert(f == h.mullow_classical(g, 7)); + + f = (h*g).shift_right(7); + tassert(f == h.mulhigh(g, 7).shift_right(7)); + tassert(f == h.mulhigh_classical(g, 7).shift_right(7)); + + f = h / g; + tassert(f*g + (h % g) == h); + tassert(((h*g) % h).is_zero()); + + f.set_randtest(state, 10); + g %= f; + h %= f; + tassert(h.mulmod(g, f) == ((h*g) % f)); + tassert(h.mulmod(g, f) == h.mulmod_preinv(g, f, + f.reverse(f.length()).inv_series(f.length()))); + + + f = "3 31 1 0 1"; + nmodxx x = nmodxx::red(7, ctx); + tassert(evaluate(f, x) == x*x + nmodxx::red(1, ctx)); + f.realloc(0);f.set_coeff(31, 1); + tassert(evaluate(f, x) == x); + tassert(f(x) == x); + + nmod_polyxx seven(M); + seven.set_coeff(0, x); + tassert(compose(f, seven).get_coeff(0) == f(x)); + tassert(f(seven).length() == 1); + + nmod_vecxx vec1(2, ctx), vec2(2, ctx); + vec1[0] = nmodxx::red(7, ctx); vec1[1] = nmodxx::red(15, ctx); + vec2[0] = f(vec1[0]); vec2[1] = f(vec1[1]); + tassert(f(vec1) == vec2); +} + +void +test_functions() +{ + mp_limb_t M = 31; + nmod_polyxx g(M); + nmodxx_ctx_srcref ctx = g.estimate_ctx(); + + g.set_coeff(5, 15); + tassert(g.max_bits() == 4); + + g.truncate(3); + tassert(g.is_zero()); + + g.set_coeff(15, 1); + tassert(g.shift_right(15).is_one()); + tassert(g.shift_right(15).shift_left(15) == g); + + frandxx rand; + g.set_randtest(rand, 15); + tassert(g.length() <= 15); + g.set_randtest_irreducible(rand, 15); + tassert(g.length() <= 15); + tassert(g.is_squarefree()); + tassert(g.is_irreducible()); + + tassert(g == nmod_polyxx::bit_unpack(g.bit_pack(5u), 5u, ctx)); + + // multiplication, division, modulo tested in arithmetic + + tassert(g.pow(3u) == g*g*g); + tassert(g.pow(5u) == g.pow_binexp(5u)); + + nmod_polyxx res(g.pow(15u));res.truncate(12); + tassert(res == g.pow_trunc(15u, 12)); + tassert(res == g.pow_trunc_binexp(15u, 12)); + + nmod_polyxx f(M);f.set_randtest(rand, 10); + res = g.pow(10u) % f; + tassert(res == g.powmod_binexp(10u, f)); + tassert(res == g.powmod_binexp_preinv(10u, f, + f.reverse(f.length()).inv_series(f.length()))); + + res = "5 31 1 1 1 1 1"; + tassert(res.derivative().to_string() == "4 31 1 2 3 4"); + tassert(g.integral().derivative() == g); + + tassert(f.divrem(g) == ltuple(f / g, f % g)); + tassert(f.divrem_basecase(g) == f.divrem(g)); + tassert(f.divrem_divconquer(g) == f.divrem(g)); + + tassert(f.div_basecase(g) == f / g); + tassert(f.div_divconquer(g) == f / g); + + tassert(f.rem_basecase(g) == f % g); + + f.set_coeff(0, 17); // non-zero mod 31, so a unit + res = f*f.inv_series(15);res.truncate(15); + tassert(res.is_one()); + tassert(f.inv_series(15) == f.inv_series_basecase(15)); + tassert(f.inv_series(15) == f.inv_series_newton(15)); + + res = g * f.inv_series(15);res.truncate(15); + tassert(g.div_series(f, 15) == res); + + f.set_coeff(f.degree(), 12); // unit + tassert(g.div_newton(f) == g / f); + tassert(g.divrem_newton(f) == g.divrem(f)); + tassert(g.divrem(f) == g.divrem_newton_n_preinv(f, + f.reverse(f.length()).inv_series(f.length()))); + tassert(g /f == g.div_newton_n_preinv(f, + f.reverse(f.length()).inv_series(f.length()))); + + res = "2 31 5 1"; + tassert(f.div_root(-nmodxx::red(5, ctx)) == f / res); + + nmod_vecxx v(10, ctx); + _nmod_vec_randtest(v._array(), rand._data(), v.size(), ctx._nmod()); + tassert(f.evaluate_fast(v) == f(v)); + tassert(f.evaluate_iter(v) == f(v)); + + nmod_vecxx xs(10, ctx); + for(int i = 0;i < xs.size();++i) + xs[i] = nmodxx::red(i, ctx); + res = nmod_polyxx::interpolate(xs, v); + tassert(res.degree() < xs.size()); + for(int i = 0;i < xs.size();++i) + tassert(res(xs[i]) == v[i]); + tassert(nmod_polyxx::interpolate_fast(xs, v) == res); + tassert(nmod_polyxx::interpolate_newton(xs, v) == res); + tassert(nmod_polyxx::interpolate_barycentric(xs, v) == res); + + tassert(f(g) == f.compose_divconquer(g)); + tassert(f(g) == f.compose_horner(g)); + + res = "2 31 7 1"; + tassert(f(res) == f.taylor_shift(nmodxx::red(7, ctx))); + tassert(f(res) == f.taylor_shift_horner(nmodxx::red(7, ctx))); + tassert(f(res) == f.taylor_shift_convolution(nmodxx::red(7, ctx))); + + nmod_polyxx h(M); + h.set_randtest(rand, 15); + tassert(f.compose_mod(g, h) == f(g) % h); + tassert(f.compose_mod(g, h) == f.compose_mod_horner(g, h)); + tassert(f.compose_mod(g, h) == f.compose_mod_brent_kung(g, h)); + tassert(f.compose_mod(g, h) == f.compose_mod_brent_kung_preinv(g, h, + h.reverse(h.length()).inv_series(h.length()))); + + h.set_randtest_irreducible(rand, 12); + tassert(h.gcd(f).is_one()); + tassert(f.gcd_euclidean(f) == f.make_monic()); + tassert(f.gcd_hgcd(g) == f.gcd(g)); + + nmod_polyxx R(M), S(M); + ltupleref(res, R, S) = f.xgcd(g); + tassert(res == R*f + S*g && res == gcd(f, g)); + tassert(f.xgcd(g) == f.xgcd_hgcd(g)); + tassert(f.xgcd(g) == f.xgcd_euclidean(g)); + + fmpz_polyxx lift1 = fmpz_polyxx::randtest(rand, 10, 6); + fmpz_polyxx lift2 = fmpz_polyxx::randtest(rand, 10, 6); + lift1.set_coeff(10, 1); + lift2.set_coeff(10, 1); + f = nmod_polyxx::reduce(lift1, ctx); + for(int i = 0;i < f.length();++i) + tassert(f.get_coeff(i) == nmodxx::red(lift1.get_coeff(i), ctx)); + + g = nmod_polyxx::reduce(lift2, ctx); + tassert(f.resultant(g) == nmodxx::red(lift1.resultant(lift2), ctx)); + tassert(f.resultant(g) == f.resultant_euclidean(g)); + + g.set_coeff(0, 0); + res = f(g); res.truncate(15); + tassert(f.compose_series(g, 15) == res); + tassert(f.compose_series_horner(g, 15) == res); + tassert(f.compose_series_brent_kung(g, 15) == res); + tassert(f.compose_series_divconquer(g, 15) == res); + + res = "2 31 0 1"; + g.set_coeff(1, 17); // unit + tassert(g.compose_series(g.revert_series(15), 15) == res); + tassert(g.revert_series_newton(15) == g.revert_series(15)); + tassert(g.revert_series_lagrange(15) == g.revert_series(15)); + tassert(g.revert_series_lagrange_fast(15) == g.revert_series(15)); + + f.set_coeff(0, 1); + tassert(f.sqrt_series(15).pow_trunc(2u, 15) == f); + tassert(f.invsqrt_series(15).pow_trunc(2u, 15) == f.inv_series(15)); + + tassert((f*f).sqrt() == f); + res = "1 31 1"; + assert_exception((f*f + res).sqrt().evaluate()); + + f = nmod_polyxx::product_roots(xs); + tassert(f.degree() == xs.size()); + for(int i = 0;i < xs.size();++i) + tassert(f(nmodxx::red(i, ctx)).to() == 0); + + res = "2 31 0 1"; + tassert(f.inflate(5u) == f(res.pow(5u))); + tassert(f.inflate(5u).deflate(5u) == f); + tassert(f.inflate(5u).deflation() >= 5); + tassert(f.deflate(f.deflation()).deflation() == 1); + + g.set_randtest_irreducible(rand, 4); + f.set_randtest_irreducible(rand, 5); + res = f*g*g; + tassert(res.remove(g) == 2 && res == f); +} + +void +test_transcendental_functions() +{ + frandxx state; + mp_limb_t M = 1031; // prime + nmod_polyxx f(M); + nmodxx_ctx_srcref ctx = f.estimate_ctx(); + fmpq_polyxx lift = fmpq_polyxx::randtest(state, 10, 9); + lift.set_coeff(0, 0); + f = nmod_polyxx::reduce(lift, ctx); + for(int i = 0;i < f.length();++i) + tassert(f.get_coeff(i) == nmodxx::red(lift.get_coeff(i), ctx)); + + tassert(f.exp_series(15) == nmod_polyxx::reduce(lift.exp_series(15), ctx)); + tassert(f.atan_series(15) == nmod_polyxx::reduce(lift.atan_series(15), ctx)); + tassert(f.atanh_series(15) == nmod_polyxx::reduce(lift.atanh_series(15), ctx)); + tassert(f.asin_series(15) == nmod_polyxx::reduce(lift.asin_series(15), ctx)); + tassert(f.asinh_series(15) == nmod_polyxx::reduce(lift.asinh_series(15), ctx)); + tassert(f.sin_series(15) == nmod_polyxx::reduce(lift.sin_series(15), ctx)); + tassert(f.cos_series(15) == nmod_polyxx::reduce(lift.cos_series(15), ctx)); + tassert(f.tan_series(15) == nmod_polyxx::reduce(lift.tan_series(15), ctx)); + tassert(f.sinh_series(15) == nmod_polyxx::reduce(lift.sinh_series(15), ctx)); + tassert(f.cosh_series(15) == nmod_polyxx::reduce(lift.cosh_series(15), ctx)); + tassert(f.tanh_series(15) == nmod_polyxx::reduce(lift.tanh_series(15), ctx)); + + tassert(f.exp_series_basecase(15) == f.exp_series(15)); + + f.set_coeff(0, 1); lift.set_coeff(0, 1); + tassert(f.log_series(15) == nmod_polyxx::reduce(lift.log_series(15), ctx)); + + f.realloc(0); + nmodxx a = nmodxx::red(7, ctx); + f.set_coeff(5, a); + tassert(f.exp_series(15) == exp_series_monomial(a, 5u, 15)); + f.set_coeff(0, 1); + tassert(f.log_series(15) == log_series_monomial(a, 5u, 15)); +} + +// test stuff which we should get automatically - addmul, references etc +void +test_extras() +{ + // TODO +} + +bool equiv_fac(const nmod_poly_factorxx& fac1, const nmod_poly_factorxx& fac2) +{ + tassert(fac1.size() == 2); + if(fac1.exp(0) == fac1.exp(1)) + { + if(fac2.exp(0) != fac1.exp(0) || fac2.exp(1) != fac1.exp(0)) + return false; + return (fac1.p(0) == fac2.p(0) && fac1.p(1) == fac2.p(1)) + || (fac1.p(1) == fac2.p(0) && fac1.p(0) == fac2.p(1)); + } + if(fac1.size() != fac2.size()) + return false; + if(fac1.exp(0) == fac2.exp(0)) + return fac1.exp(1) == fac2.exp(1) + && fac1.p(0) == fac2.p(0) + && fac1.p(1) == fac2.p(1); + else + return fac1.exp(0) == fac2.exp(1) + && fac1.exp(1) == fac2.exp(0) + && fac1.p(0) == fac2.p(1) + && fac1.p(1) == fac2.p(0); +} +void +test_factoring() +{ + mp_limb_t M = 1031; + nmod_polyxx f(M), g(M); + frandxx state; + f.set_randtest_irreducible(state, 4); f = f.make_monic(); + g.set_randtest_irreducible(state, 5); g = g.make_monic(); + + nmod_poly_factorxx fac = factor(f*f*g); + tassert(fac.size() == 2); + if(fac.exp(0) == 1) + { + tassert(fac.p(0) == g); + tassert(fac.p(1) == f && fac.exp(1) == 2); + } + else + { + tassert(fac.p(0) == f && fac.exp(0) == 2); + tassert(fac.p(1) == g && fac.exp(1) == 1); + } + + nmod_poly_factorxx fac2;fac2 = fac;fac2.pow(2); + fac.insert(g, 1); + fac.insert(f, 2); + tassert(fac == fac2); + + nmod_polyxx prod(f*f*f*g*g); + fac = factor(prod); + tassert(equiv_fac(fac, factor_cantor_zassenhaus(prod))); + tassert(equiv_fac(factor(f*g), factor_berlekamp(f*g))); + tassert(equiv_fac(fac, factor_kaltofen_shoup(prod))); + tassert(equiv_fac(fac, factor_with_cantor_zassenhaus(prod))); + tassert(equiv_fac(fac, factor_with_berlekamp(prod))); + tassert(equiv_fac(fac, factor_with_kaltofen_shoup(prod))); + + std::vector degs(2); + fac.realloc(0);fac.set_factor_distinct_deg(f*g, degs); + tassert(degs.size() == 2); + tassert((degs[0] == f.degree() && degs[1] == g.degree()) + || (degs[1] == f.degree() && degs[0] == g.degree())); + + // TODO test set_factor_equal_deg* + + if(0) + print(fac); // make sure this compiles +} + +void +test_reduction_reconstruction() +{ + std::vector primes; + primes.push_back(1031); + primes.push_back(1033); + primes.push_back(1039); + mp_limb_t M = primes[0]; + nmodxx_ctx ctx(M); + + frandxx rand; + fmpz_polyxx A = fmpz_polyxx::randtest(rand, 10, 8); + nmod_polyxx Ap = nmod_polyxx::reduce(A, ctx); + for(slong i = 0;i < A.length();++i) + tassert(Ap.get_coeff(i) == nmodxx::red(A.get_coeff(i), ctx)); + tassert(A == fmpz_polyxx::lift(Ap)); + + for(slong i = 0;i < A.length();++i) + A.coeff(i) = abs(A.coeff(i)); + tassert(A == fmpz_polyxx::lift_unsigned(nmod_polyxx::reduce(A, ctx))); + + A = fmpz_polyxx::randtest(rand, 10, 25); + + fmpzxx prod(1); + fmpz_polyxx res; + for(unsigned i = 0;i < primes.size();++i) + { + res = res.CRT(prod, nmod_polyxx::reduce(A, primes[i]), true); + prod *= primes[i]; + } + tassert(res == A); +} + +void +test_randomisation() +{ + frandxx state1, state2; + mp_limb_t N = 1031; + nmod_polyxx p(N); + p.set_randtest(state1, 7); + tassert(p == nmod_polyxx::randtest(N, state2, 7)); + p.set_randtest_irreducible(state1, 7); + tassert(p == nmod_polyxx::randtest_irreducible(N, state2, 7)); +} + +int +main() +{ + std::cout << "nmod_polyxx...."; + + test_init(); + test_manipulation(); + test_assignment(); + test_conversion(); + test_arithmetic(); + test_functions(); + test_transcendental_functions(); + test_extras(); + test_factoring(); + test_reduction_reconstruction(); + test_randomisation(); + + frandxx rand; + test_print_read(nmod_polyxx::randtest(7, rand, 5)); + + std::cout << "PASS" << std::endl; + return 0; +} + diff --git a/external/flint-2.4.3/flintxx/test/t-nmod_vecxx.cpp b/external/flint-2.4.3/flintxx/test/t-nmod_vecxx.cpp new file mode 100644 index 0000000..65a3fb3 --- /dev/null +++ b/external/flint-2.4.3/flintxx/test/t-nmod_vecxx.cpp @@ -0,0 +1,157 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#include + +#include "nmod_vecxx.h" +#include "flintxx/ltuple.h" +#include "flintxx/test/helpers.h" + +using namespace flint; + +bool test_conv(nmodxx_ctx_srcref) {return true;} +void +test_init() +{ + nmodxx_ctx c(31); + tassert(test_conv(c)); + tassert(c.n() == 31); + + nmodxx a = nmodxx::make_nored(65, c); + tassert(a._limb() == 65); + a.reduce(); + tassert(a._limb() == (65 % 31)); + + nmodxx b = nmodxx::red(65, c); + tassert(b._limb() == a._limb()); + + tassert(a == b); + nmodxx zero(c); + tassert(zero != a); + + a = zero; + tassert(a == zero); + + tassert(nmodxx::red(65, c) == nmodxx::red(fmpzxx(65), c)); + tassert(nmodxx::red(3, c)/nmodxx::red(2, c) + == nmodxx::red(fmpqxx(3, 2u), c)); +} + +void +test_conversion() +{ + nmodxx_ctx c(31); + nmodxx a = nmodxx::red(65, c); + tassert(a.to() == a._limb()); + tassert(a.to_string() == "3 mod 31"); +} + +void +test_arithmetic() +{ + nmodxx_ctx c(31); + nmodxx a = nmodxx::red(65, c); + nmodxx b = nmodxx::red(21, c); + + tassert(a + b == nmodxx::red(65 + 21, c)); + tassert((a + b).estimate_ctx() == a._ctx()); + tassert((-a) + a == nmodxx::red(0, c)); + tassert(b + (-a) == b - a); + tassert(nmodxx::red(3, c) * a == a + a + a); + tassert((a / b) * b == a); + tassert(inv(b) == nmodxx::red(1, c) / b); + tassert(pow(a, 4u) == a*a*a*a); + + tassert(b.inv() == inv(b)); + tassert(a.pow(4u) == pow(a, 4u)); +} + +void +test_references() +{ + nmodxx_ctx c(31); + nmodxx a = nmodxx::red(17, c); + nmodxx b = nmodxx::red(19, c); + nmodxx_ref ar(a); + nmodxx_srcref bsr(b); + tassert(a == ar); + tassert(bsr != ar); + ar = nmodxx::red(19, c); + tassert(a == bsr); + tassert(ar + bsr + a == nmodxx::red(3, c) * b); + + nmodxx_ref ar2 = nmodxx_ref::make(a._limb(), a.estimate_ctx()); + nmodxx_srcref asr2 = nmodxx_srcref::make(a._limb(), a.estimate_ctx()); + ar2 = nmodxx::red(4, c); + tassert(asr2 == nmodxx::red(4, c)); +} + +void +test_vec() +{ + nmodxx_ctx c(31); + nmod_vecxx v1(10, c), v2(10, c); + for(slong i = 0;i < (slong) v1.size();++i) + { + v1[i] = nmodxx::red(0, c); + v2[i] = nmodxx::red(0, c); + } + tassert(v1 == v2); + v1[0] = nmodxx::red(15, c); + tassert(v1 != v2); + tassert(v1 + v2 == v1); +} + +namespace flint { +typedef make_ltuple::type>::type ltup_t; +FLINT_DEFINE_UNOP(make_lazy_test) +namespace rules { +FLINT_DEFINE_UNARY_EXPR_COND(make_lazy_test_op, ltup_t, NMOD_VECXX_COND_S, + to.template get<0>() = from[0]) +} +} +void +test_temporaries() +{ + nmodxx_ctx ctx(17); + nmod_vecxx v(1, ctx);v[0] = nmodxx::red(7, ctx); + tassert(make_lazy_test(v).get<0>() == v[0]); +} + +int +main() +{ + std::cout << "nmod_vecxx...."; + + test_init(); + test_conversion(); + test_arithmetic(); + test_references(); + test_vec(); + test_temporaries(); + + std::cout << "PASS" << std::endl; + return 0; +} diff --git a/external/flint-2.4.3/flintxx/test/t-padic_matxx.cpp b/external/flint-2.4.3/flintxx/test/t-padic_matxx.cpp new file mode 100644 index 0000000..5ac6f25 --- /dev/null +++ b/external/flint-2.4.3/flintxx/test/t-padic_matxx.cpp @@ -0,0 +1,214 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#include + +#include "padic_matxx.h" +#include "flintxx/test/helpers.h" + +using namespace flint; + +padicxx_ctx ctx(fmpzxx(5), 10, 20, PADIC_TERSE); + +void +test_init() +{ + padic_matxx a(ctx, 5, 7, 20); + tassert(a.get_ctx()._ctx() == &ctx._ctx()[0]); + tassert(a.prec() == 20); + tassert(a.rows() == 5 && a.cols() == 7); + + padic_matxx c(a); + tassert(a == c); + + padic_matxx b(ctx, 3, 4, 30); + tassert((a + b).estimate_ctx()._ctx() == &ctx._ctx()[0]); + tassert((a + b).prec() == 30); + + tassert((a + b).create_temporary().prec() == 30); + padic_matxx d((a + b).create_temporary()); + tassert(d.get_ctx()._ctx() == &ctx._ctx()[0]); + tassert(d.prec() == 30); + + padic_matxx e(a + b); + tassert(e.prec() == 30); + + tassert(padic_matxx::zero(ctx, 5, 7).is_zero() + && padic_matxx::zero(ctx, 5, 7, 25).is_zero()); + + a.prec() = 25; + tassert(a.prec() == 25); + a.val() = 17; + tassert(a.val() == 17); + + padic_matxx eye = padic_matxx::one(ctx, 3, 3); + for(slong i = 0;i < eye.rows();++i) + for(slong j = 0;j < eye.cols();++j) + if(i == j) + tassert(eye.get_entry(i, j).is_one()); + else + tassert(eye.get_entry(i, j).is_zero()); +} + +void +test_manipulation() +{ + padic_matxx a(ctx, 5, 7); + tassert(a.at(0, 0) == 0); + padic_matxx b(a); + b.set_entry(0, 0, padicxx::one(ctx)); + tassert(a != b); + b /= fmpzxx(5); + tassert(b.at(0, 0) == 1); + b.at(0, 0) = 2; + tassert((b / fmpzxx(5)).val() == -2); + tassert(b.get_entry(0, 0) == padicxx::from_QQ(fmpqxx::frac(2, 5), ctx)); + tassert(b.get_entry(0, 0) + == (b + padic_matxx::zero(ctx, 5, 7)).get_entry(0, 0)); +} + +void +test_assignment() +{ + padic_matxx a(ctx, 3, 7), b(ctx, 3, 7); + b.set_entry(0, 0, padicxx::from_QQ(3, ctx)); + tassert(a != b); + + fmpq_matxx M(3, 7); + b = M; + tassert(a == b); + tassert(b.to() == M); +} + +template +bool has_explicit_temporaries(const Expr&) +{ + return Expr::ev_traits_t::rule_t::temporaries_t::len != 0; +} +void +test_arithmetic() +{ + frandxx state; + + padic_matxx v(ctx, 1, 10); + padic_matxx A(ctx, 10, 10); + + tassert(!has_explicit_temporaries(transpose(transpose(v)))); + tassert(!has_explicit_temporaries(transpose(A + v*transpose(v)))); + tassert(!has_explicit_temporaries(A + v*transpose(v))); + tassert(!has_explicit_temporaries(transpose((v*transpose(v) + A)))); + tassert(!has_explicit_temporaries(transpose(v*transpose(v) + v*transpose(v)))); + tassert(!has_explicit_temporaries(v*transpose(v) + v*transpose(v))); + + fmpz_matxx a = fmpz_matxx::randtest(4, 4, state, 10); + fmpz_matxx b = fmpz_matxx::randtest(4, 4, state, 10); + fmpq_matxx aq(4, 4);aq = a; + fmpq_matxx bq(4, 4);bq = b; + padic_matxx ap = padic_matxx::from_QQ(aq, ctx); + padic_matxx bp = padic_matxx::from_QQ(bq, ctx); + + tassert(ap + bp == padic_matxx::from_QQ(aq + bq, ctx)); + tassert(ap - bp == padic_matxx::from_QQ(aq - bq, ctx)); + tassert(ap * bp == padic_matxx::from_QQ(aq * bq, ctx)); + tassert(-ap == padic_matxx::from_QQ(-aq, ctx)); + + fmpzxx s = fmpzxx::randtest(state, 15); + tassert(ap * s == padic_matxx::from_QQ(aq * s, ctx)); + ltupleref(_, s) = s.remove(ctx.get_p()); + tassert(ap / s == padic_matxx::from_QQ(aq / s, ctx)); +} + +void +test_functions() +{ + frandxx state; + padic_matxx A = padic_matxx::randtest(3, 4, state, ctx); + padic_matxx B(A.transpose()); + for(slong i = 0;i < B.rows();++i) + for(slong j = 0;j < B.cols();++j) + tassert(B.get_entry(i, j) == A.get_entry(j, i)); + + tassert(!A.is_square() && !A.is_empty()); +} + +// test stuff which we should get automatically - references etc +void +test_extras() +{ + padic_matxx a(ctx, 2, 2); + padic_matxx b(ctx, 2, 2); + a.set_entry(0, 0, padicxx::from_QQ(3, ctx)); + b.set_entry(0, 1, padicxx::from_QQ(2, ctx)); + + padic_matxx_ref ar(a); + padic_matxx_srcref asr(a); + tassert(a == ar && ar == asr); + + tassert(ar + asr == a + a); + tassert(padic_matxx(ar) == ar); + tassert(padic_matxx(asr) == ar); + + ar.set_entry(0, 0, padicxx::from_QQ(1, ctx)); + tassert(a.get_entry(0, 0).is_one()); +} + +void +test_prec() +{ + padic_matxx a(ctx, 2, 2, 5), b(ctx, 2, 2, 7); + padic_matxx_ref ar(a); + padic_matxx_srcref br(b); + + tassert((a + a).prec() == 5); + tassert((a + ar).prec() == 5); + tassert((a + b).prec() == 7); + tassert((a + br).prec() == 7); + tassert((a.toN(15) + br.toN(10)).prec() == 15); +} + +void +test_printing() +{ + tassert_fprint(padic_matxx::one(ctx, 2, 2), "2 2 1 0 0 1"); + tassert_fprint_pretty(padic_matxx::one(ctx, 2, 2), "[[1 0]\n[0 1]]"); +} + +int +main() +{ + std::cout << "padic_matxx...."; + + test_init(); + test_manipulation(); + test_assignment(); + test_arithmetic(); + test_functions(); + test_extras(); + test_prec(); + test_printing(); + + std::cout << "PASS" << std::endl; + return 0; +} diff --git a/external/flint-2.4.3/flintxx/test/t-padic_polyxx.cpp b/external/flint-2.4.3/flintxx/test/t-padic_polyxx.cpp new file mode 100644 index 0000000..b3b7ef0 --- /dev/null +++ b/external/flint-2.4.3/flintxx/test/t-padic_polyxx.cpp @@ -0,0 +1,219 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#include + +#include "padic_polyxx.h" +#include "flintxx/test/helpers.h" + +using namespace flint; + +padicxx_ctx ctx(fmpzxx(5), 10, 20, PADIC_TERSE); + +void +test_init() +{ + padic_polyxx a(ctx, 20); + tassert(a.get_ctx()._ctx() == ctx._ctx()); + tassert(a.prec() == 20); + + padic_polyxx c(a); + tassert(a == c); + + padic_polyxx b(ctx, 30); + tassert((a + b).estimate_ctx()._ctx() == ctx._ctx()); + tassert((a + b).prec() == 30); + + tassert((a + b).create_temporary().prec() == 30); + padic_polyxx d((a + b).create_temporary()); + tassert(d.get_ctx()._ctx() == ctx._ctx()); + tassert(d.prec() == 30); + + padic_polyxx e(a + b); + tassert(e.prec() == 30); + + tassert(padic_polyxx::zero(ctx).is_zero() + && padic_polyxx::zero(ctx, 25).is_zero()); + tassert(padic_polyxx::one(ctx).is_one() + && padic_polyxx::one(ctx, 25).is_one()); + + a.prec() = 25; + tassert(a.prec() == 25); + a.val() = 17; + tassert(a.val() == 17); +} + +void +test_assignment() +{ + padic_polyxx a(ctx, 20), b(ctx, 20); + ulong o1 = 1; + slong o2 = 1; + fmpzxx o3(1); + fmpqxx o4 = fmpqxx::integer(o3); + fmpz_polyxx o5 = fmpz_polyxx::from_ground(o3); + fmpq_polyxx o6;o6.set_coeff(0, o4); + + a = o1;tassert(a.is_one());a = 0; + a = o2;tassert(a.is_one());a = 0; + a = o3;tassert(a.is_one());a = 0; + a = o4;tassert(a.is_one());a = 0; + a = o5;tassert(a.is_one());a = 0; + a = o6;tassert(a.is_one()); + + tassert(a != b); + a = b; + tassert(a == b); + + a = padicxx::from_QQ(1, ctx);tassert(a.is_one()); +} + +void +test_conversion() +{ + tassert(padic_polyxx::from_QQ(1, ctx).is_one()); + tassert(padic_polyxx::from_QQX(fmpz_polyxx::from_ground(1), ctx).is_one()); + tassert(padic_polyxx::from_ground(padicxx::one(ctx)).is_one()); + + frandxx state; + fmpz_polyxx f = fmpz_polyxx::randtest_unsigned(state, 5, 10); + tassert(padic_polyxx::from_QQX(f, ctx, 100).to() == f); + fmpq_polyxx fq;fq = f; + tassert(padic_polyxx::from_QQX(f, ctx, 100).to() == fq); +} + +void +test_arithmetic() +{ + frandxx state; + padicxx a = padicxx::randtest(state, ctx); + padicxx b = padicxx::randtest(state, ctx); + padic_polyxx ap = padic_polyxx::from_ground(a); + padic_polyxx bp = padic_polyxx::from_ground(b); + + tassert(ap + bp == padic_polyxx::from_ground(a + b)); + tassert(ap - bp == padic_polyxx::from_ground(a - b)); + tassert(ap * bp == padic_polyxx::from_ground(a * b)); + tassert(-ap == padic_polyxx::from_ground(-a)); + tassert(ap * b == padic_polyxx::from_ground(a * b)); +} + +void +test_functions() +{ + frandxx state; + + padic_polyxx p = padic_polyxx::randtest(state, 4, ctx, 25); + tassert(p.pow(3u) == p*p*p); + tassert(p.degree() == 3); + tassert(p.length() == 4); + tassert(p.val() + 1 == (p*padicxx::from_QQ(5, ctx, 25)).val()); + + fmpz_polyxx F1 = fmpz_polyxx::randtest(state, 5, 10); + fmpz_polyxx F2 = fmpz_polyxx::randtest(state, 5, 10); + padic_polyxx f1 = padic_polyxx::from_QQX(F1, ctx); + padic_polyxx f2 = padic_polyxx::from_QQX(F2, ctx); + tassert(f1.derivative() == padic_polyxx::from_QQX(F1.derivative(), ctx)); + tassert(compose(f1, f2) == padic_polyxx::from_QQX(F1(F2), ctx)); + tassert(f1(f2) == compose(f1, f2)); + + fmpzxx X = fmpzxx::randtest(state, 10); + padicxx x = padicxx::from_QQ(X, ctx); + tassert(f1(x) == padicxx::from_QQ(F1(X), ctx)); + + tassert(f1.shift_left(5) == padic_polyxx::from_QQX(F1.shift_left(5), ctx)); + tassert(f1.shift_right(2) + == padic_polyxx::from_QQX(F1.shift_right(2), ctx)); + + F1.set_coeff(0, 1); + f1 = padic_polyxx::from_QQX(F1, ctx); + tassert(f1.inv_series(10) == padic_polyxx::from_QQX(F1.inv_series(10), ctx)); + + f2.set_zero(); + f2.set_coeff(1, padicxx::one(ctx)); + tassert(p.compose_pow(5) == p(f2.pow(5u))); + + tassert(!padic_polyxx::randtest_not_zero(state, 5, ctx).is_zero()); + tassert(padic_polyxx::randtest_val(state, 5, 5, ctx).val() == 5); +} + +// test stuff which we should get automatically - references etc +void +test_extras() +{ + padic_polyxx a = padic_polyxx::from_QQ(fmpqxx(3, 5u), ctx); + padic_polyxx b = padic_polyxx::from_QQ(fmpqxx(3, 1u), ctx); + + padic_polyxx_ref ar(a); + padic_polyxx_srcref asr(a); + tassert(a == ar && ar == asr); + ar = 3; + tassert(a == b && asr == b); + + tassert(ar + asr == a + a); + tassert(padic_polyxx(ar) == ar); + tassert(padic_polyxx(asr) == ar); +} + +void +test_prec() +{ + padic_polyxx a(ctx, 5), b(ctx, 7); + padic_polyxx_ref ar(a); + padic_polyxx_srcref br(b); + + tassert((a + a).prec() == 5); + tassert((a + ar).prec() == 5); + tassert((a + b).prec() == 7); + tassert((a + br).prec() == 7); + tassert((a.toN(15) + br.toN(10)).prec() == 15); +} + +void +test_printing() +{ + padic_polyxx p(ctx); + p.set_coeff(2, padicxx::one(ctx)); + tassert_fprint(p, "3 0 0 1"); + tassert_fprint_pretty(p, "x", "x^2"); +} + +int +main() +{ + std::cout << "padic_polyxx...."; + + test_init(); + test_assignment(); + test_conversion(); + test_arithmetic(); + test_functions(); + test_extras(); + test_prec(); + test_printing(); + + std::cout << "PASS" << std::endl; + return 0; +} diff --git a/external/flint-2.4.3/flintxx/test/t-padicxx.cpp b/external/flint-2.4.3/flintxx/test/t-padicxx.cpp new file mode 100644 index 0000000..9bf9c4b --- /dev/null +++ b/external/flint-2.4.3/flintxx/test/t-padicxx.cpp @@ -0,0 +1,241 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#include +#include +#include + +#include "padicxx.h" +#include "flintxx/test/helpers.h" + +using namespace flint; + +void +test_init() +{ + padicxx_ctx ctx(fmpzxx(5), 10, 20, PADIC_TERSE); + tassert(ctx.get_p() == 5); + + padicxx a(ctx, 20); + tassert(a.prec() == 20); + + padicxx c(a); + tassert(a == c); + + padicxx b(ctx, 30); + tassert((a + b).prec() == 30); + + tassert((a + b).create_temporary().prec() == 30); + padicxx d((a + b).create_temporary()); + tassert(d.prec() == 30); + + padicxx e(a + b); + tassert(e.prec() == 30); + + tassert(padicxx::zero(ctx).is_zero() && padicxx::zero(ctx, 25).is_zero()); + tassert(padicxx::one(ctx).is_one() && padicxx::one(ctx, 25).is_one()); + + a.prec() = 25; + tassert(a.prec() == 25); + a.val() = 17; + tassert(a.val() == 17); + + padicxx zero = padicxx::zero(ctx); + tassert(zero.unit() == 0); + tassert((zero + zero).unit() == 0); + tassert((zero + zero).val() == 0); +} + +void +test_assignment() +{ + padicxx_ctx ctx(fmpzxx(5), 10, 20, PADIC_TERSE); + padicxx a(ctx, 20), b(ctx, 20); + fmpzxx c(17); fmpqxx d(17, 1u); + + a = 17; tassert(a != b); + b = 17; tassert(a == b); + b = 0; tassert(a != b); + b = UWORD(17); tassert(a == b); + b = 0; b = c; tassert(a == b); + b = 0; b = fmpzxx_ref(c); tassert(a == b); + b = 0; b = fmpzxx_srcref(c); tassert(a == b); + b = 0; b = d; tassert(a == b); +} + +void +test_conversion() +{ + padicxx_ctx ctx(fmpzxx(5), 10, 20, PADIC_TERSE); + padicxx_ctx ctx2(fmpzxx(5), 10, 20, PADIC_VAL_UNIT); + + padicxx a(ctx), b(ctx2); + a = 15; b = 15; + tassert(a.to_string() == "15"); + tassert(b.to_string() == "3*5"); + + tassert(a.to() == 15); + tassert(a.to() == fmpqxx(15, 1u)); + + std::ostringstream oss; + oss << a << ' ' << b; + tassert(oss.str() == "15 3*5"); +} + +template +padicxx make_padic(const T& t, slong prec = PADIC_DEFAULT_PREC) +{ + static padicxx_ctx ctx(fmpzxx(5), 10, 20, PADIC_TERSE); + return padicxx::from_QQ(t, ctx, prec); +} +template +bool fuzzy_equals(const T& t, const U& u) +{ + slong prec = std::min(t.prec(), u.prec()) - 5; + padicxx a(t.estimate_ctx(), prec); a = t; + padicxx b(t.estimate_ctx(), prec); b = u; + return a == b; +} +void +test_arithmetic() +{ + fmpqxx af(17, 25u), bf(5, 27u); + padicxx a(make_padic(af)); + padicxx b(make_padic(bf)); + + tassert(fuzzy_equals(a + b, make_padic(af + bf))); + tassert(fuzzy_equals(a * b, make_padic(af * bf))); + tassert(fuzzy_equals(a / b, make_padic(af / bf))); + tassert(fuzzy_equals(a - b, make_padic(af - bf))); + tassert(fuzzy_equals(a << 2, make_padic(af * fmpzxx(25)))); + tassert(fuzzy_equals(a >> 2, make_padic(af / fmpzxx(25)))); + tassert(-a == make_padic(-af)); +} + +void +test_functions() +{ + padicxx_ctx ctx(fmpzxx(5), 10, 20, PADIC_TERSE); + + padicxx a(make_padic(fmpqxx(14, 25u))); + tassert(fuzzy_equals(a, pow(sqrt(a), 2))); + + assert_exception(sqrt(make_padic(fmpqxx(2, 1u))).evaluate()); + + fmpqxx cf(14*5, 1u); + padicxx c = make_padic(fmpqxx(14*5, 1u)); + tassert(fuzzy_equals(log(exp(c)), c)); + tassert(exp(c) == exp_rectangular(c) && exp(c) == exp_balanced(c)); + c = exp(c); + tassert(log(c) == log_satoh(c) && log(c) == log_balanced(c) + && log(c) == log_rectangular(c)); + + padicxx b(make_padic(fmpqxx(14, 17u))); + tassert((inv(b)*b).is_one()); + + padicxx two(make_padic(fmpqxx(2, 1u))); + padicxx tl(teichmuller(two)); + tassert(pow(tl, 4).is_one() && (tl - two).val() > 0); + + // TODO test reduce + + // test padic_val_fac functions + tassert(padic_val_fac(fmpzxx(26), fmpzxx(5)) == 6); + tassert(padic_val_fac(26u, fmpzxx(5)) == 6); + + // test randomisation + frandxx rand; + tassert(padicxx::randtest(rand, ctx, 5).val() < 5 + && padicxx::randtest(rand, ctx, 5).val() >= -1); + tassert(padicxx::randtest(rand, ctx, -5).val() < -5 + && padicxx::randtest(rand, ctx, -5).val() >= -6); + tassert(!padicxx::randtest_not_zero(rand, ctx, 5).is_zero()); + tassert(padicxx::randtest_int(rand, ctx, -5).is_zero()); + + padicxx ap(a), bp(b); + swap(a, b); + tassert(a == bp && b == ap); + + // test members (just a sample, since from macros) + tassert(b.inv() == inv(b)); + tassert(b.pow(7) == pow(b, 7)); +} + +// test stuff which we should get automatically - references etc +void +test_extras() +{ + padicxx a(make_padic(fmpqxx(3, 5u))); + padicxx b(make_padic(fmpqxx(3, 1u))); + + padicxx_ref ar(a); + padicxx_srcref asr(a); + tassert(a == ar && ar == asr); + ar = 3; + tassert(a == b && asr == b); + + tassert(ar + asr == a + a); + tassert(padicxx(ar) == ar); + tassert(padicxx(asr) == ar); +} + +void +test_prec() +{ + padicxx_ctx ctx(fmpzxx(5), 10, 20, PADIC_TERSE); + padicxx a(ctx, 5), b(ctx, 7); + padicxx_ref ar(a); + padicxx_srcref br(b); + + tassert((a + a).prec() == 5); + tassert((a + ar).prec() == 5); + tassert((a + b).prec() == 7); + tassert((a + br).prec() == 7); + tassert((a.toN(15) + br.toN(10)).prec() == 15); +} + +void +test_printing() +{ + tassert_fprint(make_padic(0), "0"); +} + +int +main() +{ + std::cout << "padicxx...."; + + test_init(); + test_assignment(); + test_conversion(); + test_arithmetic(); + test_functions(); + test_extras(); + test_prec(); + test_printing(); + + std::cout << "PASS" << std::endl; + return 0; +} diff --git a/external/flint-2.4.3/flintxx/test/t-permxx.cpp b/external/flint-2.4.3/flintxx/test/t-permxx.cpp new file mode 100644 index 0000000..c09439f --- /dev/null +++ b/external/flint-2.4.3/flintxx/test/t-permxx.cpp @@ -0,0 +1,68 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ +#include + +#include "permxx.h" +#include "flintxx/test/helpers.h" + +using namespace flint; + +int +main() +{ + std::cout << "permxxxx...."; + + permxx p1(10), p2(10); + p1[0] = 1;p1[1] = 0; + tassert(p1 != p2); + p1 = p2; + tassert(p1 == p2); + permxx p3(p2); + p2[1] = 0; + p2[0] = 1; + tassert(p1 != p2); + tassert(p3 != p2); + + tassert(parity(p2) == 1); + + frandxx state; + p1 = permxx::randtest(10, state); + tassert(p1*inv(p1) == permxx::one(10)); + p2 = permxx::randtest(10, state); + tassert(p1*p2 == compose(p1, p2)); + p3 = p1*p2; + p1 *= p2; + tassert(p1 == p3); + + tassert(maybe_perm_data(&p1) == p1._data()); + tassert(maybe_perm_data(0) == 0); + + if(0) + print(p1); // make sure this compiles + + std::cout << "PASS" << std::endl; + + return 0; +} diff --git a/external/flint-2.4.3/flintxx/test/t-qadicxx.cpp b/external/flint-2.4.3/flintxx/test/t-qadicxx.cpp new file mode 100644 index 0000000..19eb4b1 --- /dev/null +++ b/external/flint-2.4.3/flintxx/test/t-qadicxx.cpp @@ -0,0 +1,207 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#include +#include +#include + +#include "qadicxx.h" +#include "flintxx/test/helpers.h" + +// This is a test in itself: used to not compile. +#include "padic_polyxx.h" + +using namespace flint; + +void +test_init() +{ + qadicxx_ctx ctx(fmpzxx(5), 3, 10, 20, PADIC_TERSE); + + qadicxx a(ctx, 20); + tassert(&a.get_qctx() == &ctx); + tassert(a.prec() == 20); + + qadicxx c(a); + tassert(a == c); + + qadicxx b(ctx, 30); + tassert(&(a + b).estimate_ctx() == &ctx); + tassert((a + b).prec() == 30); + + tassert((a + b).create_temporary().prec() == 30); + qadicxx d((a + b).create_temporary()); + tassert(&d.get_qctx() == &ctx); + tassert(d.prec() == 30); + + qadicxx e(a + b); + tassert(e.prec() == 30); + + tassert(qadicxx::zero(ctx).is_zero() && qadicxx::zero(ctx, 25).is_zero()); + tassert(qadicxx::one(ctx).is_one() && qadicxx::one(ctx, 25).is_one()); + + qadicxx zero = qadicxx::zero(ctx); + tassert((zero + zero).val() == 0); +} + +void +test_assignment() +{ + qadicxx_ctx ctx(fmpzxx(5), 3, 10, 20, PADIC_TERSE); + qadicxx a(ctx, 20), b(ctx, 20); + + a = 17u; tassert(a != b); + b = 17u; tassert(a == b); +} + +void +test_conversion() +{ + qadicxx_ctx ctx(fmpzxx(5), 3, 10, 20, PADIC_TERSE); + + frandxx state; + padicxx p = padicxx::randtest(state, ctx.pctx()); + qadicxx a = qadicxx::from_ground(ctx, p); + tassert(a.to() == p); + assert_exception(qadicxx::gen(ctx).to()); +} + +void +test_arithmetic() +{ + qadicxx_ctx ctx(fmpzxx(5), 3, 10, 20, PADIC_TERSE); + frandxx state; + padicxx pa = padicxx::randtest(state, ctx.pctx()); + padicxx pb = padicxx::randtest(state, ctx.pctx()); + qadicxx qa = qadicxx::from_ground(ctx, pa); + qadicxx qb = qadicxx::from_ground(ctx, pb); + + tassert((qa + qb).to() == pa + pb); + tassert((qa - qb).to() == pa - pb); + tassert((qa * qb).to() == pa * pb); + tassert((-qa).to() == -pa); +} + +void +test_functions() +{ + qadicxx_ctx ctx(fmpzxx(5), 3, 10, 20, PADIC_TERSE); + frandxx state; + padicxx pa = padicxx::randtest_not_zero(state, ctx.pctx()); + padicxx pb(padicxx::randtest_int(state, ctx.pctx()) + * padicxx::from_QQ(5*5*5, ctx.pctx())); + qadicxx qa = qadicxx::from_ground(ctx, pa); + qadicxx qb = qadicxx::from_ground(ctx, pb); + qadicxx qc = qadicxx::randtest_val(state, 5, ctx); + + tassert(qa.inv().to() == pa.inv()); + tassert(qc.pow(fmpzxx(3)) == qc*qc*qc); + + tassert(qb.exp().to() == pb.exp()); + tassert(qc.exp() == qc.exp_rectangular()); + tassert(qc.exp() == qc.exp_balanced()); + + tassert((qadicxx::one(ctx) + qb).log().to() + == (padicxx::one(ctx.pctx()) + pb).log()); + qc += qadicxx::one(ctx); + tassert(qc.log() == qc.log_balanced()); + + qadicxx res(ctx, PADIC_DEFAULT_PREC); + qadic_frobenius(res._qadic(), qc._qadic(), 3, ctx._ctx()); + tassert(res == qc.frobenius(3)); + + qadic_teichmuller(res._qadic(), qc._qadic(), ctx._ctx()); + tassert(res == qc.teichmuller()); + + padicxx resp(ctx.pctx(), PADIC_DEFAULT_PREC); + qadic_trace(resp._padic(), qc._qadic(), ctx._ctx()); + tassert(resp == qc.trace()); + + qadic_norm(resp._padic(), qc._qadic(), ctx._ctx()); + tassert(resp == qc.norm()); + tassert(qc.norm() == qc.norm_analytic()); + tassert(qc.norm() == qc.norm_resultant()); +} + +// test stuff which we should get automatically - references etc +void +test_extras() +{ + qadicxx_ctx ctx(fmpzxx(5), 3, 10, 20, PADIC_TERSE); + qadicxx a(ctx); + qadicxx b(ctx);b = 3u; + + qadicxx_ref ar(a); + qadicxx_srcref asr(a); + tassert(a == ar && ar == asr); + ar = 3u; + tassert(a == b && asr == b); + + tassert(ar + asr == a + a); + tassert(qadicxx(ar) == ar); + tassert(qadicxx(asr) == ar); +} + +void +test_prec() +{ + qadicxx_ctx ctx(fmpzxx(5), 3, 10, 20, PADIC_TERSE); + qadicxx a(ctx, 5), b(ctx, 7); + qadicxx_ref ar(a); + qadicxx_srcref br(b); + + tassert((a + a).prec() == 5); + tassert((a + ar).prec() == 5); + tassert((a + b).prec() == 7); + tassert((a + br).prec() == 7); + tassert((a.toN(15) + br.toN(10)).prec() == 15); +} + +void +test_printing() +{ + qadicxx_ctx ctx(fmpzxx(5), 3, 10, 20, PADIC_TERSE); + if(0) + print(ctx); // make sure this compiles + tassert_fprint_pretty(qadicxx::gen(ctx).pow(fmpzxx(2)), "x^2"); +} + +int +main() +{ + std::cout << "qadicxx...."; + + test_init(); + test_assignment(); + test_conversion(); + test_arithmetic(); + test_functions(); + test_extras(); + test_prec(); + test_printing(); + + std::cout << "PASS" << std::endl; + return 0; +} diff --git a/external/flint-2.4.3/flintxx/test/t-traits.cpp b/external/flint-2.4.3/flintxx/test/t-traits.cpp new file mode 100644 index 0000000..15bfea5 --- /dev/null +++ b/external/flint-2.4.3/flintxx/test/t-traits.cpp @@ -0,0 +1,136 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#include "flintxx/test/helpers.h" +#include "flintxx/traits.h" +#include "flintxx/mp.h" + +using namespace flint; +using namespace traits; + +struct newtype { }; + +void +test_integrality() +{ + tassert(is_signed_integer::val == true); + tassert(is_signed_integer::val == true); + tassert(is_signed_integer::val == true); + tassert(is_signed_integer::val == false); + tassert(is_signed_integer::val == false); + tassert(is_signed_integer::val == false); + tassert(is_signed_integer::val == false); + + tassert(is_unsigned_integer::val == true); + tassert(is_unsigned_integer::val == true); + tassert(is_unsigned_integer::val == true); + tassert(is_unsigned_integer::val == false); + tassert(is_unsigned_integer::val == false); + tassert(is_unsigned_integer::val == false); + tassert(is_unsigned_integer::val == false); + + tassert(is_integer::val == true); + tassert(is_integer::val == true); + tassert(is_integer::val == true); + tassert(is_integer::val == true); + tassert(is_integer::val == true); + tassert(is_integer::val == true); + tassert(is_integer::val == false); + + tassert(is_string::val == false); + tassert(is_string::val == true); + tassert(is_string::val == true); + tassert(is_string::val == true); + + tassert(fits_into_slong::val == true); + tassert(fits_into_slong::val == true); + tassert(fits_into_slong::val == false); + tassert(fits_into_slong::val == true); + tassert(fits_into_slong::val == true); + tassert(fits_into_slong::val == true); + tassert(fits_into_slong::val == true); + tassert(fits_into_slong::val == false); + + typedef void function_type(int, int); + tassert(fits_into_slong::val == false); +} + +void +test_manipulation() +{ + using mp::equal_types; + + tassert((equal_types::type, int>::val)); + tassert((equal_types::type, newtype&>::val)); + tassert((equal_types::type, + const newtype&>::val)); + tassert((equal_types::type, + const newtype&>::val)); + + tassert((equal_types::type, int&>::val)); + tassert((equal_types::type, newtype&>::val)); + tassert((equal_types::type, const slong&>::val)); + tassert((equal_types::type, const int&>::val)); + + tassert((equal_types::type, const int>::val)); + tassert((equal_types::type, const newtype&>::val)); + tassert((equal_types::type, const slong>::val)); + tassert((equal_types::type, const int&>::val)); + + tassert((equal_types::type, int>::val)); + tassert((equal_types::type, newtype>::val)); + tassert((equal_types::type, slong>::val)); + tassert((equal_types::type, int>::val)); + tassert((equal_types::type, int*>::val)); +} + +class super { }; +class sub : public super { }; + +void +test_convertibility() +{ + tassert((_is_convertible::val == true)); + tassert((_is_convertible::val == false)); + tassert((_is_convertible::val == false)); + tassert((_is_convertible::val == true)); + tassert((_is_convertible::val == true)); + + // Test the HACK. + tassert((_is_convertible::val == false)); +} + +int +main() +{ + std::cout << "traits...."; + + test_integrality(); + test_manipulation(); + test_convertibility(); + + std::cout << "PASS" << std::endl; + return 0; +} diff --git a/external/flint-2.4.3/flintxx/test/t-tuple.cpp b/external/flint-2.4.3/flintxx/test/t-tuple.cpp new file mode 100644 index 0000000..8919986 --- /dev/null +++ b/external/flint-2.4.3/flintxx/test/t-tuple.cpp @@ -0,0 +1,417 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#include + +#include "flintxx/test/helpers.h" +#include "flintxx/tuple.h" +#include "flintxx/mp.h" + +using namespace flint; +using namespace mp; +using namespace traits; + +void +test_make() +{ + typedef make_tuple make3; + typedef make_tuple make2; + typedef make_tuple make1; + + tassert((equal_types< + make3::type, + tuple > > + >::val)); + tassert((equal_types< + make2::type, + tuple > + >::val)); + tassert((equal_types >::val)); + tassert(make3::type::len == 3); + tassert(make2::type::len == 2); + tassert(make1::type::len == 1); + + make3::type tup = make3::make(1, 'b', 3); + tassert(tup.head == 1); + tassert(tup.tail.head == 'b'); + tassert(tup.tail.tail.head == 3); + tup.first() = 2; + tassert(tup.head == 2); + tassert(tup.second() == 'b'); + + make2::type pair = make2::make(1, 'b'); + tassert(pair.first() == 1); + tassert(pair.second() == 'b'); + + make1::type singleton = make1::make(1); + tassert(singleton.first() == 1); + + typedef make_tuple makeref; + tassert((equal_types::val)); + int a = 4; + makeref::type reftup = makeref::make(a, a); + tassert(reftup.head == 4); + a = 5; + tassert(reftup.second() == 5); +} + +template +struct type_n +{ + int payload; + type_n(int p) : payload(p) {}; +}; +template +struct type_n +{ + int payload; + type_n(int p) : payload(p) {}; + type_n() {}; +}; + +void +test_back() +{ + typedef type_n<0> A; + typedef type_n<1> B; + typedef type_n<2> C; + typedef type_n<3> D; + + typedef make_tuple make3; + typedef make_tuple make3p; + typedef make_tuple make2A; + typedef make_tuple make2B; + + typedef back_tuple backvoid; + typedef back_tuple backD; + typedef back_tuple backA; + typedef back_tuple backB; + + tassert((equal_types::val)); + tassert((equal_types::val)); + tassert((equal_types::val)); + tassert((equal_types::val)); + + make3::type backing = make3::make(1, 2, 3); + make3p::type pointers; + backvoid::init(pointers, backing, 0); + tassert(pointers.first()->payload == 1); + backing.second() = 4; + tassert(pointers.second()->payload == 4); + + A ret = 4; + make2A::type backing2 = make2A::make(1, 2); + backA::init(pointers, backing2, &ret); + tassert(pointers.first()->payload == 4); + tassert(pointers.second()->payload == 1); + ret.payload = 5; + backing2.head.payload = 6; + tassert(pointers.first()->payload == 5); + tassert(pointers.second()->payload == 6); + + // Test some corner cases. + tassert((equal_types::type, empty_tuple>::val)); + typedef tuple tup1_t; + tassert((equal_types::type, empty_tuple>::val)); +} + +void +test_concat() +{ + typedef type_n<0> A; + typedef type_n<1> B; + typedef type_n<2> C; + typedef type_n<3> D; + typedef type_n<4> E; + + typedef make_tuple make1st; + typedef make_tuple make2nd; + + typedef concat_tuple concater; + tassert((equal_types< + concater::type, + tuple > > + >::val)); + + concater::type concated = concater::type(0, + tuple >(1, + tuple(2, make2nd::make(3, 4)))); + make2nd::type second = concater::get_second(concated); + tassert(second.first().payload == 3); + tassert(second.second().payload == 4); + make1st::type first = concater::get_first(concated); + tassert(first.first().payload == 0); + tassert(first.second().payload == 1); + tassert(first.tail.second().payload == 2); + + first.first().payload = 17; + second.first().payload = 18; + concated = concater::doit(first, second); + tassert(concated.first().payload == 17); + tassert(concated.tail.tail.tail.head.payload == 18); + + // Test a few corner cases. + tassert((equal_types< + concat_tuple::type, + empty_tuple + >::val)); + typedef tuple tup1_t; + tassert((equal_types< + concat_tuple::type, + tup1_t + >::val)); + tassert((equal_types< + concat_tuple::type, + tup1_t + >::val)); +} + +namespace flint{ +namespace detail +{ +template +struct fillit +{ + static void doit(T& t, int start) + { + t.head.payload = start; + detail::fillit::doit(t.tail, ++start); + } +}; + +template<> +struct fillit +{ + static void doit(empty_tuple e, int start) + { + } +}; + +template +struct values +{ + static void doit(const T& t, std::set& values) + { + values.insert(t.head.payload); + detail::values::doit(t.tail, values); + } +}; + +template<> +struct values +{ + static void doit(empty_tuple e, std::set& values) + { + } +}; +} +} + +template +void fillit(T& t, int start = 1) +{ + detail::fillit::doit(t, start); +} + +template +std::set values(const T& t) +{ + std::set ret; + detail::values::doit(t, ret); + return ret; +} + +void +test_merge() +{ + typedef type_n<0, true> A; + typedef type_n<1, true> B; + typedef type_n<2, true> C; + typedef type_n<3, true> D; + typedef type_n<4, true> E; + + // Test that merging tuples and + // yields something of length n, and that the constitutents can be + // recovered. Also do other order. +#define TEST32n(T1, T2, T3, U1, U2, n) \ + { \ + typedef make_tuple m1; \ + typedef make_tuple m2; \ + typedef merge_tuple merge1; \ + typedef merge_tuple merge2; \ + tassert(merge1::type::len == n); \ + tassert(merge2::type::len == n); \ + merge1::type merged1; \ + { \ + fillit(merged1); \ + m1::type n1 = merge1::get_first(merged1); \ + m2::type n2 = merge1::get_second(merged1); \ + std::set vals1 = values(n1), vals2 = values(n2); \ + vals1.insert(vals2.begin(), vals2.end()); \ + tassert(vals1.size() == n); \ + } \ + merge2::type merged2; \ + { \ + fillit(merged2); \ + m2::type n2 = merge2::get_first(merged2); \ + m1::type n1 = merge2::get_second(merged2); \ + std::set vals1 = values(n1), vals2 = values(n2); \ + vals1.insert(vals2.begin(), vals2.end()); \ + tassert(vals1.size() == n); \ + } \ + } + + TEST32n(A, B, C, A, B, 3); + TEST32n(A, B, C, B, A, 3); + TEST32n(A, B, C, A, C, 3); + TEST32n(A, B, C, C, A, 3); + TEST32n(A, B, C, C, B, 3); + TEST32n(A, B, C, B, C, 3); + TEST32n(A, A, A, A, A, 3); + + TEST32n(A, B, C, A, D, 4); + TEST32n(A, B, C, B, D, 4); + TEST32n(A, B, C, C, D, 4); + TEST32n(A, B, C, D, A, 4); + TEST32n(A, B, C, D, B, 4); + TEST32n(A, B, C, D, C, 4); + TEST32n(A, A, A, A, B, 4); + + TEST32n(A, B, C, D, E, 5); + TEST32n(A, A, A, B, B, 5); + + typedef merge_tuple emptymerge; + tassert((equal_types::val)); + + typedef merge_tuple::type, empty_tuple> anothermerge; + tassert(anothermerge::type::len == 2); +} + +void +test_traits() +{ + tassert((is_homogeneous_tuple::type, int>::val + == true)); + tassert((is_homogeneous_tuple::type, int>::val + == false)); + + tassert(is_tuple::val == true); + tassert(is_tuple::type>::val == true); + tassert((is_tuple::type>::val == true)); + tassert(is_tuple::val == false); +} + +struct filler +{ + template + T create() const + { + if(mp::equal_types::val) + return 1; + return 0; + } +}; +void +test_htuples() +{ + tassert((equal_types::type, + make_homogeneous_tuple::type>::val)); + + typedef make_tuple maker; + maker::type tpl = maker::make(1, 2, 3); + + tassert(htuples::extract<1>(tpl) == make_tuple::make(1)); + tassert((htuples::extract<2>(tpl) == make_tuple::make(1, 2))); + tassert((htuples::extract<3>(tpl) == make_tuple::make(1, 2, 3))); + + typedef make_tuple make2; + tassert(htuples::removeres(tpl, 1) == make2::make(2, 3)); + tassert(htuples::removeres(tpl, 2) == make2::make(1, 3)); + tassert(htuples::removeres(tpl, 3) == make2::make(1, 2)); + tassert(htuples::removeres(tpl, 4) == make2::make(1, 2)); + + typedef make_tuple maker3; + tassert((maker3::make(0, 1, 0) == htuples::fill(filler()))); +} + +void +test_get() +{ + typedef make_tuple::type tuple_t; + int a, b; + tuple_t t(17, make_tuple::type(a, + make_tuple::type(b, empty_tuple()))); + + tassert((equal_types::type>::val)); + tassert((equal_types::type>::val)); + tassert((equal_types::type>::val)); + + tassert((tuple_get::get(t) == 17)); + tuple_get::get(t) = 42; + b = 3; + tassert((tuple_get::get(t) == 3)); + tassert(a == 42); + + const tuple_t ct(t); + tuple_get::get(ct) = 17; + tassert((tuple_get::get(ct) == 17)); +} + +void +test_set() +{ + make_tuple::type tup; + tup.set(make_tuple::make(1, 2, 3)); + tassert((tup == make_tuple::make(1, 2, 3))); +} + +void +test_equals_elementwise() +{ + tassert((make_tuple::make(1, 2, 3).equals_elementwise( + make_tuple::make(1, 2, 3)))); + tassert((!make_tuple::make(0, 2, 3).equals_elementwise( + make_tuple::make(1, 2, 3)))); +} + +int +main() +{ + std::cout << "tuple...."; + + test_make(); + test_back(); + test_concat(); + test_merge(); + test_traits(); + test_htuples(); + test_get(); + test_set(); + test_equals_elementwise(); + + std::cout << "PASS" << std::endl; + return 0; +} + diff --git a/external/flint-2.4.3/flintxx/test/t-vector.cpp b/external/flint-2.4.3/flintxx/test/t-vector.cpp new file mode 100644 index 0000000..6f355fc --- /dev/null +++ b/external/flint-2.4.3/flintxx/test/t-vector.cpp @@ -0,0 +1,105 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#include + +#include "flintxx/vector.h" + +#include "flintxx/test/helpers.h" +#include "flintxx/test/myint.h" +#include "fmpz_vecxx.h" + +using namespace flint; + +template +struct tuple_has + : mp::or_< + mp::equal_types, + tuple_has > { }; +template +struct tuple_has : mp::false_ { }; + +template +bool has_vector_temporaries(const Expr& e) +{ + return tuple_has::val; +} + +template +void test(const Vec& original, const char* str = "(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)") +{ + Vec v(original); + Vec w(original); + Vec u(original); + Vec x(original); + for(slong i = 0;i < (slong) v.size();++i) + { + v[i] = i; + w[i] = WORD(0); + u[i] = 2*i; + x[i] = 8*i; + } + tassert(v.to_string() == str); + tassert(v == v); + tassert(v != w); + + tassert(u == v + v); + tassert(v == v + w); + tassert(x == ((v + v) + (v + v)) + ((v + v) + (v + v))); + tassert((v + w)[0] == v[0] + w[0]); + + if(!mp::equal_types::val) + tassert(!has_vector_temporaries( + ((v + v) + (v + v)) + ((v + v) + (v + v)))); +} + +// b/c generic vector has no assignment implementation ... +void +test_fmpz_vecxx() +{ + fmpz_vecxx a(10), b(10); + a[0] = 1; + tassert(a != b); + a = b; + tassert(a == b); +} + +int +main() +{ + std::cout << "vector...."; + + typedef make_vector::type intvec; + typedef make_vector_n::type intvec10; + + test(intvec(10)); + test(intvec10()); + test(fmpz_vecxx(10), "10 0 1 2 3 4 5 6 7 8 9"); + test_fmpz_vecxx(); + + std::cout << "PASS" << std::endl; + + return 0; +} diff --git a/external/flint-2.4.3/flintxx/traits.h b/external/flint-2.4.3/flintxx/traits.h new file mode 100644 index 0000000..9686204 --- /dev/null +++ b/external/flint-2.4.3/flintxx/traits.h @@ -0,0 +1,144 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#ifndef CXX_TRAITS_H +#define CXX_TRAITS_H + +// only for true_/false_ +#include "mp.h" + +namespace flint { +namespace detail { +template +struct wrap +{ + T t; +}; +} // detail + +namespace traits { +/////////////////////// +// BASIC TYPE TRAITS +/////////////////////// +// These helpers can be used to manipulate and inquire type information. +// For example, given an arbitrary type T, one might be interested in knowing +// if it is an integral type (int, short, ulong, etc). +// +// This file contains generic traits, not specific to FLINT. + +using mp::true_; +using mp::false_; + +// Compute if T belongs to the signed integer types. +template struct is_signed_integer : false_ { }; +template<> struct is_signed_integer : true_ { }; +template<> struct is_signed_integer : true_ { }; +template<> struct is_signed_integer : true_ { }; +template<> struct is_signed_integer : true_ { }; + +// Compute if T belongs to the unsigned integer types. +template struct is_unsigned_integer : false_ { }; +template<> struct is_unsigned_integer : true_ { }; +template<> struct is_unsigned_integer : true_ { }; +template<> struct is_unsigned_integer : true_ { }; +template<> struct is_unsigned_integer : true_ { }; + +// Compute if T belongs to the signed or unsigned integer types +template struct is_integer + : mp::or_, is_signed_integer > { }; + +// Compute if T can always losslessly be converted into an slong +template struct fits_into_slong : mp::false_ { }; +template +struct fits_into_slong >::type> + : mp::or_< + is_signed_integer, + mp::and_v< + is_unsigned_integer, + sizeof(T) < sizeof(slong) + > + > { }; + +template struct fits_into_mp_bitcnt_t : is_unsigned_integer { }; + +// Compute if T is like const char* +template struct is_string : mp::false_ { }; +template<> struct is_string : mp::true_ { }; +template<> struct is_string : mp::true_ { }; +template struct is_string : mp::true_ { }; +template struct is_string : mp::true_ { }; + +// Compute a type appropriate for forwarding T. This is just the appropriate +// constant reference type (but avoids things like const (int&)&, which cause +// syntax errors. +template struct forwarding {typedef const T& type;}; +template struct forwarding {typedef T& type;}; +template struct forwarding {typedef const T& type;}; + +template +struct forwarding >::type> +{ + typedef T type; +}; +template struct forwarding {typedef T* type;}; +template<> struct forwarding {typedef bool type;}; + +// Compute a type appropriate for referencing. Usually T&. +template struct reference {typedef T& type;}; +template struct reference {typedef T& type;}; +template struct reference {typedef const T& type;}; + +// Add a constant qualification. In particular, turn T& into const T&. +template struct make_const {typedef const T type;}; +template struct make_const {typedef const T& type;}; + +// Strip const and reference type annotations. This does *not* strip pointers! +template struct basetype {typedef T type;}; +template struct basetype {typedef T type;}; +template struct basetype {typedef T type;}; +template struct basetype {typedef T type;}; + +struct no { int data[2]; }; +typedef int yes; +template detail::wrap fakeinstance(); + +// use with care +template +struct _is_convertible +{ +private: + static yes test(...) {return yes();} + static no test(To) {return no();} +public: + static const bool val = (sizeof(test(fakeinstance().t)) != sizeof(yes)); +}; + +// XXX HACK +template +struct _is_convertible : false_ { }; +} // traits +} // flint + +#endif diff --git a/external/flint-2.4.3/flintxx/traits_fwd.h b/external/flint-2.4.3/flintxx/traits_fwd.h new file mode 100644 index 0000000..1ee5daa --- /dev/null +++ b/external/flint-2.4.3/flintxx/traits_fwd.h @@ -0,0 +1,41 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#ifndef FLINTXX_TRAITS_FWD_H +#define FLINTXX_TRAITS_FWD_H + +// Use this to break cyclic dependencies, by forward-declaring traits. + +namespace flint { +namespace traits { +template struct is_fmpz_matxx; +template struct is_fmpq_matxx; +template struct is_fmpz_polyxx; +template struct is_nmod_matxx; +template struct is_nmod_polyxx; +} // traits +} // flint + +#endif diff --git a/external/flint-2.4.3/flintxx/tuple.h b/external/flint-2.4.3/flintxx/tuple.h new file mode 100644 index 0000000..da23356 --- /dev/null +++ b/external/flint-2.4.3/flintxx/tuple.h @@ -0,0 +1,650 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#ifndef CXX_TUPLE_H +#define CXX_TUPLE_H + +#include "traits.h" + +namespace flint { +/////////////////////////// +// A general tuple class. +/////////////////////////// +// This simply stores a head and a tail. Conventionally, tuples a built by +// nesting the tail. The last entry should be an empty_tuple (see below). +// So e.g. a pair of integers would be tuple >. +// +// There are some helpers in the mp namespace below. +namespace detail { +struct FILLIT { }; +} // detail +namespace mp { +namespace htuples { +// Filling of tuples +template +Tuple fill(const Filler& f) +{ + return Tuple(detail::FILLIT(), f); +} +} // htuples +} // mp + +template +struct tuple +{ + Head head; + Tail tail; + + typedef Head head_t; + typedef Tail tail_t; + static const unsigned len = 1 + Tail::len; + + // Obtain a reference to head (convenience name for pairs). + typename traits::reference::type first() {return head;} + typename traits::forwarding::type first() const {return head;} + + // Obtain a reference to the head of the tail (convenience name for pairs). + typename traits::reference::type + second() {return tail.head;} + typename traits::forwarding::type + second() const {return tail.head;} + + tuple() {}; + tuple(typename traits::forwarding::type h, + typename traits::forwarding::type t) + : head(h), tail(t) + { + } + + bool operator==(const tuple& other) + { + return head == other.head && tail == other.tail; + } + + template + void set(const T& t) + { + head = t.head; + tail.set(t.tail); + } + template + void set(T& t) + { + head = t.head; + tail.set(t.tail); + } + + template + bool equals_elementwise(const T& t) const + { + return head == t.head && tail.equals_elementwise(t.tail); + } + +private: + template + tuple(detail::FILLIT fillit, const Filler& f) + : head(f.template create()), tail(fillit, f) + { + } + + template + friend Tuple mp::htuples::fill(const Filler&); + template + friend struct tuple; +}; + +struct empty_tuple +{ + struct empty { }; + typedef empty head_t; + typedef empty tail_t; + empty head; + empty tail; + static const unsigned len = 0; + + bool operator==(const empty_tuple&) {return true;} + + empty_tuple() {} + + void set(empty_tuple) {} + bool equals_elementwise(empty_tuple) const {return true;} + +private: + template + empty_tuple(detail::FILLIT fillit, const Filler& f) + { + } + + template + friend Tuple mp::htuples::fill(const Filler&); + template + friend struct tuple; +}; + +namespace detail { +typedef void UNUSED; + +template +struct maybe_forwarding +{ + typedef typename traits::forwarding::type type; + static type default_value(); +}; +template<> +struct maybe_forwarding +{ + typedef UNUSED* type; + static type default_value() {return 0;} +}; +} +namespace mp { +// Helper to conveniently define tuple types, and marshall objects into +// tuples. +// Typical usage: +// typedef make_tuple maker; +// maker::type my_tuple = maker::make(1, 'a', WORD(2)); +// TODO this would be a prime use for variadic templates ... +#define FLINTXX_MAKE_TUPLE_TEMPLATE_ARGS \ + class T1 = detail::UNUSED, class T2 = detail::UNUSED, \ + class T3 = detail::UNUSED, class T4 = detail::UNUSED, \ + class T5 = detail::UNUSED, class T6 = detail::UNUSED, \ + class T7 = detail::UNUSED, class T8 = detail::UNUSED +#define FLINTXX_MAKE_TUPLE_FUNC_ARGS \ + typename detail::maybe_forwarding::type t1 \ + = detail::maybe_forwarding::default_value(), \ + typename detail::maybe_forwarding::type t2 \ + = detail::maybe_forwarding::default_value(), \ + typename detail::maybe_forwarding::type t3 \ + = detail::maybe_forwarding::default_value(), \ + typename detail::maybe_forwarding::type t4 \ + = detail::maybe_forwarding::default_value(), \ + typename detail::maybe_forwarding::type t5 \ + = detail::maybe_forwarding::default_value(), \ + typename detail::maybe_forwarding::type t6 \ + = detail::maybe_forwarding::default_value(), \ + typename detail::maybe_forwarding::type t7 \ + = detail::maybe_forwarding::default_value(), \ + typename detail::maybe_forwarding::type t8 \ + = detail::maybe_forwarding::default_value() +#define FLINTXX_MAKE_TUPLE_TYPES_APPLYMACRO(func) \ + func(T1), func(T2), func(T3), func(T4), \ + func(T5), func(T6), func(T7), func(T8) +#define FLINTXX_MAKE_TUPLE_FUNC_ARG_NAMES t1, t2, t3, t4, t5, t6, t7, t8 +template +struct make_tuple +{ + typedef make_tuple next; + typedef typename next::type tail_t; + typedef tuple type; + static type make(FLINTXX_MAKE_TUPLE_FUNC_ARGS) + { + return type(t1, next::make(t2, t3, t4, t5, t6, t7, t8)); + } +}; +template<> +struct make_tuple +{ + typedef detail::UNUSED* T; + typedef empty_tuple type; + // g++-4.4 bolts if we use (...), even though all arguments are PODs + static empty_tuple make(T=0, T=0, T=0, T=0, T=0, T=0, T=0, T=0) + {return empty_tuple();} +}; + + +// Indexified access +template +struct tuple_get +{ + typedef tuple_get nget; + typedef typename nget::type type; + + static typename traits::forwarding::type get(const Tuple& t) + { + return nget::get(t.tail); + } + static typename traits::reference::type get(Tuple& t) + { + return nget::get(t.tail); + } +}; + +template +struct tuple_get +{ + typedef typename Tuple::head_t type; + static typename traits::forwarding::type get(const Tuple& t) + { + return t.head; + } + static typename traits::reference::type get(Tuple& t) + { + return t.head; + } +}; + +// Create a tuple backing a tuple of points. +// That is to say, given a tuple like , +// compute a backing tuple type . +// +// If one of the types in the tuple is Return*, do not back it +// and instead feed it in separately. I.e. if Return is A*, then type +// will be just . +// +// The static member init(to, from, ret) can be used to initalize the tuple +// of pointers "to" to point to its backing in "from" and "ret". +template +struct back_tuple; + +// General case: non-empty tuple , and Return type cannot be +// merged in. +template +struct back_tuple, Return> +{ + typedef tuple::type> type; + static void init(tuple& to, type& from, Return* ret = 0) + { + back_tuple::init(to.tail, from.tail, ret); + to.head = &from.head; + } +}; + +// Merging case: non-empty tuple , and Return is Head* +template +struct back_tuple, Head> +{ + typedef typename back_tuple::type type; + static void init(tuple& to, type& from, Head* ret = 0) + { + to.head = ret; + back_tuple::init(to.tail, from, 0 /* unused */ ); + } +}; + +// Base case: empty tuple; nothing to do. +template +struct back_tuple +{ + typedef empty_tuple type; + static void init(empty_tuple& to, type& from, Return* ret = 0) + { + } +}; + +// Helper to concatenate two tuples. +// +// This has one member type, and three static member functions get_second, +// get_first and doit. +// "type" is a tuple type which can store the data of both Tuple1 and Tuple2. +// Then, given an element of type "type", get_first and get_second can be used +// to fill types Tuple1 and Tuple2. Note that get_second can return a constant +// reference, whereas get_first has to do copying. +// (But these copies should usually be inlined and optimized away by the +// compiler.) +// +// Example: Tuple1 = , Tuple2 = . +// Then type = +// get_second(t) = t.tail.tail.tail +// get_first(t) = tuple(t.head, tuple(t.tail.head, tuple( +// t.tail.tail.head, empty_tuple()))); +// +template +struct concat_tuple; + +// Degenerate case: Tuple1 is empty. +template +struct concat_tuple +{ + typedef Tuple2 type; + static const Tuple2& get_second(const Tuple2& t) {return t;} + static empty_tuple get_first(const Tuple2& t) {return empty_tuple();} + + static type doit(const empty_tuple& t1, const Tuple2& t2) {return t2;} +}; +// General case: non-empty Tuple1. +template +struct concat_tuple, Tuple2> +{ + typedef tuple::type> type; + static const Tuple2& get_second(const type& t) + { + return concat_tuple::get_second(t.tail); + } + static tuple get_first(const type& o) + { + return tuple( + o.head, + concat_tuple::get_first(o.tail)); + } + static type doit(const tuple& t1, const Tuple2& t2) + { + return type(t1.head, concat_tuple::doit(t1.tail, t2)); + } +}; + + +// Merging of tuples +// +// This takes two tuples, and computes a tuple type which can store either. +// As usual, the extraction functions require copying which can be amortized +// by the compiler. +// +template +struct merge_tuple; +//{ +// typedef XYZ type; +// Tuple1 get_first(const type& type); +// Tuple2 get_second(const type& type); +//}; + +// General case +// NB: tail is *always* a sub-tuple of the second argument! +template +struct merge_tuple, Tuple2> +{ +public: + typedef merge_tuple comp1; + typedef merge_tuple, typename comp1::tail_t> comp2; + typedef concat_tuple concater; + +public: + typedef typename concater::type type; + + // This is the part of type into which we can still merge. + typedef typename comp2::tail_t tail_t; + + typedef typename concat_tuple< + typename comp1::used_t, + typename comp2::used_t + >::type used_t; + +private: + static typename comp1::type get_tail(const type& input) + { + typedef concat_tuple< + typename comp1::used_t, + typename comp1::tail_t + > myconcat; + return myconcat::doit(concater::get_first(input), + comp2::get_second(concater::get_second(input))); + } + +public: + static tuple get_first(const type& input) + { + Head h = comp2::get_first(concater::get_second(input)).first(); + return tuple(h, comp1::get_first(get_tail(input))); + } + + static Tuple2 get_second(const type& input) + { + return comp1::get_second(get_tail(input)); + } +}; + +// First argument a singleton, no merging +template +struct merge_tuple, tuple > +{ +private: + typedef merge_tuple, Tail> comp; + typedef concat_tuple< + typename comp::used_t, + tuple + > concater; + +public: + typedef typename comp::used_t used_t; + typedef tuple tail_t; + typedef typename concater::type type; + +private: + static typename comp::type get_tail(const type& input) + { + typedef concat_tuple< + typename comp::used_t, + typename comp::tail_t + > myconcat; + return myconcat::doit(concater::get_first(input), + concater::get_second(input).tail); + } + +public: + static tuple get_first(const type& input) + { + return comp::get_first(get_tail(input)); + } + + static tuple get_second(const type& input) + { + return tuple( + concater::get_second(input).head, + comp::get_second(get_tail(input))); + } +}; + +// First argument a singleton, with merging +template +struct merge_tuple, tuple > +{ + typedef tuple type; + typedef tuple used_t; + typedef Tail tail_t; + + static tuple get_first(const type& input) + { + return make_tuple::make(input.head); + } + + static tuple get_second(const type& input) + { + return input; + } +}; + +// Termination case 1 +template +struct merge_tuple +{ + typedef Tuple2 type; + typedef type tail_t; + typedef empty_tuple used_t; + + static empty_tuple get_first(const type& input) + { + return empty_tuple(); + } + + static Tuple2 get_second(const type& input) + { + return input; + } +}; + +// It seems like this code path is unnecessary and in fact ambiguous. +// I am fairly convinced by now this is correct. +// However, in case issues ever come up, it seemed useful to me to retain this. +// -- Tom Bachmann (15/10/2013) +#if 0 +// Termination case 2 +template +struct merge_tuple +{ + typedef Tuple1 type; + typedef type tail_t; + typedef empty_tuple used_t; + + static Tuple1 get_first(const type& input) + { + return input; + } + + static empty_tuple get_second(const type& input) + { + return empty_tuple(); + } +}; +#endif + +// Termination case 3 +template +struct merge_tuple, empty_tuple> +{ + typedef tuple type; + typedef empty_tuple tail_t; + // NB: we "use" T here - it cannot be merged into it any longer! + typedef type used_t; + + static empty_tuple get_second(const type& input) + { + return empty_tuple(); + } + + static tuple get_first(const type& input) + { + return input; + } +}; + +// Termination case 4 +template<> +struct merge_tuple +{ + typedef empty_tuple type; + typedef empty_tuple tail_t; + typedef empty_tuple used_t; + + static empty_tuple get_first(const type& input) {return empty_tuple();} + static empty_tuple get_second(const type& input) {return empty_tuple();} +}; + + +// Creation and manipulation of homogeneous tuples + +// Build a tuple type of "n" repetitions of "T". +template +struct make_homogeneous_tuple +{ + typedef tuple::type> type; +}; +template +struct make_homogeneous_tuple +{ + typedef empty_tuple type; +}; + +namespace htuples { +namespace hdetail { +template +struct extract_helper +{ + typedef typename Tuple::head_t T; + typedef typename Tuple::tail_t tail_t; + typedef typename make_homogeneous_tuple::type ht; + + static ht get_noskip(const Tuple& tuple) + { + return ht(tuple.head, + extract_helper::get_noskip( + tuple.tail)); + } +}; +template +struct extract_helper<0, Tuple> +{ + static empty_tuple get_noskip(const Tuple&) {return empty_tuple();} +}; + +template +struct remove_helper +{ + static const unsigned n = Tuple::len; + typedef typename Tuple::tail_t tail_t; + typedef typename Tuple::head_t T; + static tail_t get(const Tuple& tuple, T res) + { + if(tuple.head == res) + return tuple.tail; + return tail_t(tuple.head, remove_helper::get(tuple.tail, res)); + } +}; +template +struct remove_helper > +{ + static empty_tuple get(const tuple&, T) + { + return empty_tuple(); + } +}; +} // hdetail + +// Extract the first "n" values from the *homogeneous* tuple "tuple". +template +inline typename make_homogeneous_tuple::type extract( + const Tuple& tuple) +{ + return hdetail::extract_helper::get_noskip(tuple); +} + +// Remove one element from the *homogeneous* tuple "tuple", if possible "res". +// Example: +// t1 = (1, 2, 3, 4) +// t2 = (1, 1, 1, 1) +// t3 = (2, 3, 4, 5) +// +// removeres(t1, 1) -> (2, 3, 4) +// removeres(t2, 1) -> (1, 1, 1) +// removeres(t3, 1) -> (2, 3, 4) or any other three element subset +template +inline typename Tuple::tail_t +removeres(const Tuple& tuple, typename Tuple::head_t res) +{ + return hdetail::remove_helper::get(tuple, res); +} +} // htuples +} // mp + +namespace traits { +// Compute if "Tuple" is of the form (U, U, .. U), or empty. +template +struct is_homogeneous_tuple : mp::and_< + is_homogeneous_tuple, + mp::equal_types > { }; +template +struct is_homogeneous_tuple : true_ { }; + +// Compute if T is a tuple +template +struct is_tuple : false_ { }; +template +struct is_tuple > : true_ { }; +template<> +struct is_tuple : true_ { }; +} +} // flint + +#endif diff --git a/external/flint-2.4.3/flintxx/vector.h b/external/flint-2.4.3/flintxx/vector.h new file mode 100644 index 0000000..17cbc5d --- /dev/null +++ b/external/flint-2.4.3/flintxx/vector.h @@ -0,0 +1,461 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +// Sketch of a generic vector class. + +#ifndef CXX_VECTOR_H +#define CXX_VECTOR_H + +#include +#include + +#include "expression.h" +#include "evaluation_tools.h" +#include "ltuple.h" +#include "mp.h" + +namespace flint { +FLINT_DEFINE_BINOP(vector_at) + +template +class vector_expression; + +namespace detail { +template +struct vector_wrapper : derived_wrapper2 { }; + +template +struct vector_at_traits +{ + typedef FLINT_BINOP_ENABLE_RETTYPE(vector_at, Expr, Idx) ref_t; + typedef ref_t cref_t; + static ref_t at(const Expr& v, Idx i) + {return vector_at(v, i);} +}; +template +struct vector_at_traits + : Traits { }; +} + +template +class vector_expression + : public expression, Operation, Data> +{ +public: + typedef expression, + Operation, Data> base_t; + typedef typename Underlying_traits::ref_t ref_t; + typedef typename Underlying_traits::cref_t cref_t; + typedef typename Underlying_traits::idx_t idx_t; + typedef typename Underlying_traits::underlying_t underlying_t; + typedef typename Underlying_traits::arrayref_t arrayref_t; + typedef typename Underlying_traits::arraysrcref_t arraysrcref_t; + + vector_expression() {} + + template + explicit vector_expression(const T& t) : base_t(t) {} + template + vector_expression(const T& t, const U& u) : base_t(t, u) {} + template + vector_expression(const T& t, const U& u, const V& v) + : base_t(t, u, v) {} + + template + vector_expression& operator=(const T& t) + { + this->set(t); + return *this; + } + + template + typename detail::vector_at_traits::ref_t operator[](Idx idx) + { + return detail::vector_at_traits::at(*this, idx); + } + template + typename detail::vector_at_traits::cref_t operator[](Idx idx) const + { + return detail::vector_at_traits::at(*this, idx); + } + + idx_t size() const {return Underlying_traits::size(*this);} + + arrayref_t _array() {return Underlying_traits::array(*this);} + arraysrcref_t _array() const {return Underlying_traits::array(*this);} + + typename base_t::evaluated_t create_temporary() const + { + return Underlying_traits::create_temporary(*this); + } + +protected: + explicit vector_expression(const Data& d) : base_t(d) {} + + template + friend class expression; +}; + +namespace vectors { +// Similar to matrices, the size of a vector expression has to be known in +// order to allocate temporary objects. In this case, the generic +// implementation looks for any vector immediate subexpression and returs its +// size. This makes sense since mixing vectors of differing sizes usually makes +// no sense. +// Thus specialisation is usually only necessary in constructor-like operations, +// which do not involve vector immediates. +template +struct outsize +{ + template + static unsigned get(const Expr& e) + { + return tools::find_subexpr_T(e)._data().size; + } +}; + +// Hack for ltuple_get, similar to the matrices case. +template +struct outsize > +{ + template + static unsigned get(const Expr& e) + { + return outsize::get( + e._data().head); + } +}; +} + +namespace detail { +template +struct basic_vector_traits +{ + typedef unsigned idx_t; + typedef Ref ref_t; + typedef const Cref cref_t; + typedef T underlying_t; + typedef ArrayT* arrayref_t; + typedef const ArrayT* arraysrcref_t; + + template + static ref_t at(Expr& e, unsigned i) + { + return e.evaluate()._data().array[i]; + } + + template + static cref_t at(const Expr& e, unsigned i) + { + return e.evaluate()._data().array[i]; + } + + template + static arrayref_t array(Expr& e) + { + return e.evaluate()._data().array; + } + + template + static arraysrcref_t array(const Expr& e) + { + return e.evaluate()._data().array; + } +}; +template +struct rtfixed_size_traits + : basic_vector_traits +{ + template + static unsigned size(const Expr& e) + { + return vectors::outsize::get(e); + } + + template + static typename Expr::evaluated_t create_temporary(const Expr& e) + { + return typename Expr::evaluated_t(e.size()); + } +}; +template +struct fixed_size_traits + : basic_vector_traits +{ + template + static unsigned size(const Expr& e) + { + return Expr::evaluated_t::data_t::size; + } + + template + static typename Expr::evaluated_t create_temporary(const Expr& e) + { + return typename Expr::evaluated_t(); + } +}; + +template +struct wrapped_vector_traits + : rtfixed_size_traits +{ + typedef Size idx_t; + + template + static Ref at(Expr& e, idx_t i) + { + return e.evaluate()._data().at(i); + } + + template + static Cref at(const Expr& e, idx_t i) + { + return e.evaluate()._data().at(i); + } +}; + +template +struct rtfixed_size_data +{ + const unsigned size; + T* array; + + rtfixed_size_data(unsigned n) + : size(n), array(new T[n]) {} + ~rtfixed_size_data() {delete[] array;} + + rtfixed_size_data(const rtfixed_size_data& o) + : size(o.size) + { + // TODO this is very non-optimal ... (?) + array = new T[size]; + for(unsigned i = 0;i < size;++i) + { + array[i] = o.array[i]; + } + } +}; +template +struct fixed_size_data +{ + static const unsigned size = n; + T array[n]; +}; +} // detail + +template +struct make_vector +{ + typedef vector_expression, + operations::immediate, detail::rtfixed_size_data > type; +}; +template +struct make_vector_n +{ + typedef vector_expression, + operations::immediate, detail::fixed_size_data > type; +}; + +template +struct enable_vector_rules : mp::false_ { }; + +template +struct enable_vector_rules< + vector_expression > + : mp::true_ { }; + +namespace rules { +// temporary allocation inside ltuples +template +struct instantiate_temporaries, + vector_expression > +{ + typedef ltuple_expression Expr; + typedef vector_expression T; + static T get(const Expr& e) + { + return T(vectors::outsize::get(e)); + } +}; + +template +struct binary_expression, + operations::vector_at_op, T> +{ + typedef typename Traits::underlying_t return_t; + template + static void doit(V& to, + const vector_expression& v, + T i) + { + to = Traits::at(v, i); + } +}; + + +template +struct to_string, + traits::is_implemented > > >::type> +{ + static std::string get(const Expr& e, int base) + { + // TODO inefficient + std::string res = "("; + for(typename Expr::idx_t i = 0;i < e.size();++i) + { + res += e[i].to_string(); + if(i != e.size() - 1) + res += ", "; + } + res += ")"; + return res; + } +}; + +template +struct equals >::type> +{ + static bool get(const Expr& e1, const Expr& e2) + { + if(e1.size() != e2.size()) + return false; + for(typename Expr::idx_t i = 0;i < e1.size();++i) + if(e1[i] != e2[i]) + return false; + return true; + } +}; + +namespace rvdetail { +template +struct translate_data; + +template +struct translate_expr +{ + typedef translate_data trdata_t; + typedef typename Expr::underlying_t ul_t; + typedef typename ul_t::template make_helper< + typename Expr::operation_t, typename trdata_t::type> make_helper; + typedef typename make_helper::type type; + + template + static type make(const Expr& e, Idx idx) + { + return make_helper::make(trdata_t::make(e._data(), idx)); + } +}; + +template +struct translate_expr >::type> +{ + typedef typename Expr::cref_t type; + + template + static type make(const Expr& e, Idx idx) + { + return e[idx]; + } +}; + +template +struct translate_data > +{ + typedef translate_expr::type> trexpr; + typedef translate_data trtail; + typedef tuple type; + + template + static type make(const tuple& e, Idx idx) + { + return type(trexpr::make(e.head, idx), trtail::make(e.tail, idx)); + } +}; +template<> +struct translate_data +{ + typedef empty_tuple type; + template + static type make(empty_tuple, Idx) {return empty_tuple();} +}; + +template +struct enable_evaluation : mp::false_ {typedef void vector_t;}; + +template +struct enable_evaluation::type> >::type> + : enable_vector_rules::type::evaluated_t> +{ + typedef typename traits::basetype::type::evaluated_t vector_t; +}; +template +struct enable_evaluation > + : mp::and_, enable_evaluation > +{ + typedef typename enable_evaluation::vector_t vector_t; +}; +template<> +struct enable_evaluation + : mp::true_ { }; +} //rvdetail + +// TODO this is a bit greedy .. +template +struct evaluation >::type> +{ + typedef rvdetail::translate_data translator; + typedef typename translator::type trdata_t; + typedef typename mp::find_evaluation< + Op, trdata_t, result_is_temporary>::type rule_t; + typedef typename rvdetail::enable_evaluation::vector_t vector_t; + typedef typename vector_t::evaluated_t return_t; // TODO + typedef typename rule_t::temporaries_t temporaries_t; + typedef typename rule_t::return_t trreturn_t; + + template + static void doit(const Data& input, temporaries_t temps, Return* output) + { + for(typename return_t::idx_t i = 0;i < output->size();++i) + { + rule_t::doit(translator::make(input, i), temps, &((*output)[i])); + } + } +}; + +// TODO scalar multiplication etc +} // rules +} // flint +#endif diff --git a/external/flint-2.4.3/fmpq.h b/external/flint-2.4.3/fmpq.h new file mode 100644 index 0000000..0e0a51e --- /dev/null +++ b/external/flint-2.4.3/fmpq.h @@ -0,0 +1,316 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#ifndef FMPQ_H +#define FMPQ_H + +#undef ulong +#define ulong ulongxx /* interferes with system includes */ +#include +#undef ulong + +#include +#include +#define ulong mp_limb_t +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + + +#ifdef __cplusplus + extern "C" { +#endif + +typedef struct +{ + fmpz num; + fmpz den; +} +fmpq; + +typedef fmpq fmpq_t[1]; + +#define fmpq_numref(__x) (&(__x)->num) +#define fmpq_denref(__y) (&(__y)->den) + + +static __inline__ void fmpq_init(fmpq_t x) +{ + x->num = WORD(0); + x->den = WORD(1); +} + +static __inline__ void fmpq_clear(fmpq_t x) +{ + fmpz_clear(fmpq_numref(x)); + fmpz_clear(fmpq_denref(x)); +} + +static __inline__ fmpq * _fmpq_vec_init(slong n) +{ + fmpq * v = (fmpq *) flint_malloc(sizeof(fmpq) * n); + slong i; + + for (i = 0; i < n; i++) + fmpq_init(v + i); + + return v; +} + +static __inline__ void _fmpq_vec_clear(fmpq * vec, slong n) +{ + _fmpz_vec_clear((fmpz *) vec, 2 * n); +} + +static __inline__ void fmpq_zero(fmpq_t res) +{ + fmpz_zero(fmpq_numref(res)); + fmpz_one(fmpq_denref(res)); +} + +static __inline__ void fmpq_one(fmpq_t res) +{ + fmpz_one(fmpq_numref(res)); + fmpz_one(fmpq_denref(res)); +} + +static __inline__ int fmpq_equal(const fmpq_t x, const fmpq_t y) +{ + return fmpz_equal(fmpq_numref(x), fmpq_numref(y)) && + fmpz_equal(fmpq_denref(x), fmpq_denref(y)); +} + +static __inline__ int fmpq_sgn(const fmpq_t x) +{ + return fmpz_sgn(fmpq_numref(x)); +} + +static __inline__ int fmpq_is_zero(const fmpq_t x) +{ + return fmpz_is_zero(fmpq_numref(x)); +} + +static __inline__ int fmpq_is_one(const fmpq_t x) +{ + return fmpz_is_one(fmpq_numref(x)) && fmpz_is_one(fmpq_denref(x)); +} + +static __inline__ void fmpq_set(fmpq_t dest, const fmpq_t src) +{ + fmpz_set(fmpq_numref(dest), fmpq_numref(src)); + fmpz_set(fmpq_denref(dest), fmpq_denref(src)); +} + +static __inline__ void fmpq_swap(fmpq_t op1, fmpq_t op2) +{ + fmpz_swap(fmpq_numref(op1), fmpq_numref(op2)); + fmpz_swap(fmpq_denref(op1), fmpq_denref(op2)); +} + +static __inline__ void fmpq_neg(fmpq_t dest, const fmpq_t src) +{ + fmpz_neg(fmpq_numref(dest), fmpq_numref(src)); + fmpz_set(fmpq_denref(dest), fmpq_denref(src)); +} + +static __inline__ void fmpq_abs(fmpq_t dest, const fmpq_t src) +{ + fmpz_abs(fmpq_numref(dest), fmpq_numref(src)); + fmpz_set(fmpq_denref(dest), fmpq_denref(src)); +} + +int _fmpq_cmp(const fmpz_t p, const fmpz_t q, const fmpz_t r, const fmpz_t s); + +int fmpq_cmp(const fmpq_t x, const fmpq_t y); + +void _fmpq_canonicalise(fmpz_t num, fmpz_t den); + +void fmpq_canonicalise(fmpq_t res); + +int _fmpq_is_canonical(const fmpz_t num, const fmpz_t den); + +int fmpq_is_canonical(const fmpq_t x); + + +void _fmpq_set_si(fmpz_t rnum, fmpz_t rden, slong p, ulong q); + +void fmpq_set_si(fmpq_t res, slong p, ulong q); + + +void fmpq_set_fmpz_frac(fmpq_t res, const fmpz_t p, const fmpz_t q); + + +static __inline__ void fmpq_set_mpq(fmpq_t dest, const mpq_t src) +{ + fmpz_set_mpz(fmpq_numref(dest), mpq_numref(src)); + fmpz_set_mpz(fmpq_denref(dest), mpq_denref(src)); +} + +static __inline__ void fmpq_get_mpq(mpq_t dest, const fmpq_t src) +{ + fmpz_get_mpz(mpq_numref(dest), fmpq_numref(src)); + fmpz_get_mpz(mpq_denref(dest), fmpq_denref(src)); +} + +int fmpq_get_mpfr(mpfr_t r, const fmpq_t x, mpfr_rnd_t rnd); + +void flint_mpq_init_set_readonly(mpq_t z, const fmpq_t f); + +void flint_mpq_clear_readonly(mpq_t z); + +void fmpq_init_set_readonly(fmpq_t f, const mpq_t z); + +void fmpq_clear_readonly(fmpq_t f); + +char * _fmpq_get_str(char * str, int b, const fmpz_t num, const fmpz_t den); + +char * fmpq_get_str(char * str, int b, const fmpq_t x); + +void _fmpq_fprint(FILE * file, const fmpz_t num, const fmpz_t den); + +void fmpq_fprint(FILE * file, const fmpq_t x); + +static __inline__ void _fmpq_print(const fmpz_t num, const fmpz_t den) +{ + _fmpq_fprint(stdout, num, den); +} + +static __inline__ void fmpq_print(const fmpq_t x) +{ + fmpq_fprint(stdout, x); +} + +void _fmpq_randtest(fmpz_t num, fmpz_t den, flint_rand_t state, mp_bitcnt_t bits); + +void fmpq_randtest(fmpq_t res, flint_rand_t state, mp_bitcnt_t bits); + +void fmpq_randtest_not_zero(fmpq_t res, flint_rand_t state, mp_bitcnt_t bits); + +void _fmpq_randbits(fmpz_t num, fmpz_t den, flint_rand_t state, mp_bitcnt_t bits); + +void fmpq_randbits(fmpq_t res, flint_rand_t state, mp_bitcnt_t bits); + + + +void _fmpq_add(fmpz_t rnum, fmpz_t rden, const fmpz_t op1num, + const fmpz_t op1den, const fmpz_t op2num, const fmpz_t op2den); + +void fmpq_add(fmpq_t res, const fmpq_t op1, const fmpq_t op2); + + +void _fmpq_sub(fmpz_t rnum, fmpz_t rden, const fmpz_t op1num, + const fmpz_t op1den, const fmpz_t op2num, const fmpz_t op2den); + +void fmpq_sub(fmpq_t res, const fmpq_t op1, const fmpq_t op2); + + +void _fmpq_mul(fmpz_t rnum, fmpz_t rden, const fmpz_t op1num, + const fmpz_t op1den, const fmpz_t op2num, const fmpz_t op2den); + +void fmpq_mul(fmpq_t res, const fmpq_t op1, const fmpq_t op2); + + +void fmpq_mul_fmpz(fmpq_t res, const fmpq_t op, const fmpz_t x); + +void _fmpq_pow_si(fmpz_t rnum, fmpz_t rden, + const fmpz_t opnum, const fmpz_t opden, slong e); + +void fmpq_pow_si(fmpq_t rop, const fmpq_t op, slong e); + + +void _fmpq_addmul(fmpz_t rnum, fmpz_t rden, const fmpz_t op1num, + const fmpz_t op1den, const fmpz_t op2num, const fmpz_t op2den); + +void fmpq_addmul(fmpq_t res, const fmpq_t op1, const fmpq_t op2); + + +void _fmpq_submul(fmpz_t rnum, fmpz_t rden, const fmpz_t op1num, + const fmpz_t op1den, const fmpz_t op2num, const fmpz_t op2den); + +void fmpq_submul(fmpq_t res, const fmpq_t op1, const fmpq_t op2); + + +void fmpq_inv(fmpq_t dest, const fmpq_t src); + +void fmpq_div(fmpq_t res, const fmpq_t op1, const fmpq_t op2); + +void fmpq_div_fmpz(fmpq_t res, const fmpq_t op, const fmpz_t x); + + +void fmpq_mul_2exp(fmpq_t res, const fmpq_t x, mp_bitcnt_t exp); + +void fmpq_div_2exp(fmpq_t res, const fmpq_t x, mp_bitcnt_t exp); + + +int _fmpq_mod_fmpz(fmpz_t res, const fmpz_t num, const fmpz_t den, const fmpz_t mod); + +int fmpq_mod_fmpz(fmpz_t res, const fmpq_t x, const fmpz_t mod); + +int _fmpq_reconstruct_fmpz(fmpz_t num, fmpz_t den, const fmpz_t a, const fmpz_t m); + +int fmpq_reconstruct_fmpz(fmpq_t res, const fmpz_t a, const fmpz_t m); + +int _fmpq_reconstruct_fmpz_2(fmpz_t n, fmpz_t d, + const fmpz_t a, const fmpz_t m, const fmpz_t N, const fmpz_t D); + +int fmpq_reconstruct_fmpz_2(fmpq_t res, const fmpz_t a, const fmpz_t m, + const fmpz_t N, const fmpz_t D); + +mp_bitcnt_t fmpq_height_bits(const fmpq_t x); + +void fmpq_height(fmpz_t height, const fmpq_t x); + +void _fmpq_next_calkin_wilf(fmpz_t rnum, fmpz_t rden, + const fmpz_t num, const fmpz_t den); + +void fmpq_next_calkin_wilf(fmpq_t res, const fmpq_t x); + +void _fmpq_next_signed_calkin_wilf(fmpz_t rnum, fmpz_t rden, + const fmpz_t num, const fmpz_t den); + +void fmpq_next_signed_calkin_wilf(fmpq_t res, const fmpq_t x); + +void _fmpq_next_minimal(fmpz_t rnum, fmpz_t rden, + const fmpz_t num, const fmpz_t den); + +void fmpq_next_minimal(fmpq_t res, const fmpq_t x); + +void _fmpq_next_signed_minimal(fmpz_t rnum, fmpz_t rden, + const fmpz_t num, const fmpz_t den); + +void fmpq_next_signed_minimal(fmpq_t res, const fmpq_t x); + +slong fmpq_get_cfrac(fmpz * c, fmpq_t rem, const fmpq_t x, slong n); + +void fmpq_set_cfrac(fmpq_t x, const fmpz * c, slong n); + +slong fmpq_cfrac_bound(const fmpq_t x); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/flint-2.4.3/fmpq/add.c b/external/flint-2.4.3/fmpq/add.c new file mode 100644 index 0000000..d9806df --- /dev/null +++ b/external/flint-2.4.3/fmpq/add.c @@ -0,0 +1,155 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq.h" + +void +_fmpq_add(fmpz_t rnum, fmpz_t rden, const fmpz_t p, const fmpz_t q, + const fmpz_t r, const fmpz_t s) +{ + fmpz_t g, a, b, t, u; + + /* Same denominator */ + if (fmpz_equal(q, s)) + { + fmpz_add(rnum, p, r); + + /* Both are integers */ + if (fmpz_is_one(q)) + { + fmpz_set(rden, q); + } + else + { + fmpz_init(g); + fmpz_gcd(g, rnum, q); + + if (fmpz_is_one(g)) + { + fmpz_set(rden, q); + } + else + { + fmpz_divexact(rnum, rnum, g); + fmpz_divexact(rden, q, g); + } + fmpz_clear(g); + } + return; + } + + /* p/q is an integer */ + if (fmpz_is_one(q)) + { + fmpz_init(t); + fmpz_mul(t, p, s); + fmpz_add(rnum, t, r); + fmpz_set(rden, s); + fmpz_clear(t); + return; + } + + /* r/s is an integer */ + if (fmpz_is_one(s)) + { + fmpz_init(t); + fmpz_mul(t, r, q); + fmpz_add(rnum, t, p); + fmpz_set(rden, q); + fmpz_clear(t); + return; + } + + /* + We want to compute p/q + r/s where the inputs are already + in canonical form. + + If q and s are coprime, then (p*s + q*r, q*s) is in canonical form. + + Otherwise, let g = gcd(q, s) with q = g*a, s = g*b. Then the sum + is given by ((p*b + r*a) / (a*b)) / g. + + As above, (p*b + r*a) / (a*b) is in canonical form, and g has + no common factor with a*b. Thus we only need to reduce (p*b + r*a, g). + If the gcd is 1, the reduced denominator is g*a*b = q*b. + */ + fmpz_init(g); + fmpz_gcd(g, q, s); + + if (fmpz_is_one(g)) + { + fmpz_init(t); + fmpz_init(u); + + fmpz_mul(t, p, s); + fmpz_mul(u, q, r); + fmpz_add(rnum, t, u); + fmpz_mul(rden, q, s); + + fmpz_clear(t); + fmpz_clear(u); + } + else + { + fmpz_init(a); + fmpz_init(b); + fmpz_init(t); + fmpz_init(u); + + fmpz_divexact(a, q, g); + fmpz_divexact(b, s, g); + + fmpz_mul(t, p, b); + fmpz_mul(u, r, a); + fmpz_add(rnum, t, u); + + fmpz_gcd(t, rnum, g); + + if (fmpz_is_one(t)) + { + fmpz_mul(rden, q, b); + } + else + { + fmpz_divexact(rnum, rnum, t); + fmpz_divexact(g, q, t); + fmpz_mul(rden, g, b); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(t); + fmpz_clear(u); + } + + fmpz_clear(g); +} + +void fmpq_add(fmpq_t res, const fmpq_t op1, const fmpq_t op2) +{ + _fmpq_add(fmpq_numref(res), fmpq_denref(res), + fmpq_numref(op1), fmpq_denref(op1), + fmpq_numref(op2), fmpq_denref(op2)); +} diff --git a/external/flint-2.4.3/fmpq/addmul.c b/external/flint-2.4.3/fmpq/addmul.c new file mode 100644 index 0000000..e38da30 --- /dev/null +++ b/external/flint-2.4.3/fmpq/addmul.c @@ -0,0 +1,49 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq.h" + +void +_fmpq_addmul(fmpz_t rnum, fmpz_t rden, const fmpz_t op1num, const fmpz_t op1den, + const fmpz_t op2num, const fmpz_t op2den) +{ + fmpz_t u, v; + + fmpz_init(u); + fmpz_init(v); + + _fmpq_mul(u, v, op1num, op1den, op2num, op2den); + _fmpq_add(rnum, rden, rnum, rden, u, v); + + fmpz_clear(u); + fmpz_clear(v); +} + +void fmpq_addmul(fmpq_t res, const fmpq_t op1, const fmpq_t op2) +{ + _fmpq_addmul(fmpq_numref(res), fmpq_denref(res), + fmpq_numref(op1), fmpq_denref(op1), + fmpq_numref(op2), fmpq_denref(op2)); +} diff --git a/external/flint-2.4.3/fmpq/canonicalise.c b/external/flint-2.4.3/fmpq/canonicalise.c new file mode 100644 index 0000000..90e0da3 --- /dev/null +++ b/external/flint-2.4.3/fmpq/canonicalise.c @@ -0,0 +1,62 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq.h" + +void _fmpq_canonicalise(fmpz_t num, fmpz_t den) +{ + fmpz_t u; + + if (fmpz_is_one(den)) + return; + + if (fmpz_is_zero(num)) + { + fmpz_one(den); + return; + } + + fmpz_init(u); + fmpz_gcd(u, num, den); + + if (!fmpz_is_one(u)) + { + fmpz_divexact(num, num, u); + fmpz_divexact(den, den, u); + } + + fmpz_clear(u); + + if (fmpz_sgn(den) < 0) + { + fmpz_neg(num, num); + fmpz_neg(den, den); + } +} + +void fmpq_canonicalise(fmpq_t res) +{ + _fmpq_canonicalise(fmpq_numref(res), fmpq_denref(res)); +} diff --git a/external/flint-2.4.3/fmpq/cfrac_bound.c b/external/flint-2.4.3/fmpq/cfrac_bound.c new file mode 100644 index 0000000..2600905 --- /dev/null +++ b/external/flint-2.4.3/fmpq/cfrac_bound.c @@ -0,0 +1,37 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq.h" + +#define ONE_OVER_LOG2_PHI (1.44042009041255648 + 1e-13) + +slong +fmpq_cfrac_bound(const fmpq_t x) +{ + if (fmpz_is_one(fmpq_denref(x))) + return 1; + + return fmpz_bits(fmpq_denref(x)) * ONE_OVER_LOG2_PHI + 2; +} diff --git a/external/flint-2.4.3/fmpq/clear_readonly.c b/external/flint-2.4.3/fmpq/clear_readonly.c new file mode 100644 index 0000000..14b186a --- /dev/null +++ b/external/flint-2.4.3/fmpq/clear_readonly.c @@ -0,0 +1,33 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpq.h" + +void fmpq_clear_readonly(fmpq_t f) +{ + fmpz_clear_readonly(fmpq_numref(f)); + fmpz_clear_readonly(fmpq_denref(f)); +} + diff --git a/external/flint-2.4.3/fmpq/cmp.c b/external/flint-2.4.3/fmpq/cmp.c new file mode 100644 index 0000000..0112bec --- /dev/null +++ b/external/flint-2.4.3/fmpq/cmp.c @@ -0,0 +1,81 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 "fmpq.h" + +int +_fmpq_cmp(const fmpz_t p, const fmpz_t q, const fmpz_t r, const fmpz_t s) +{ + int s1, s2, res; + mp_bitcnt_t bp, bq, br, bs; + fmpz_t t, u; + + if (fmpz_equal(q, s)) + return fmpz_cmp(p, r); + + s1 = fmpz_sgn(p); + s2 = fmpz_sgn(r); + + if (s1 != s2) + return s1 < s2 ? -1 : 1; + + if (s1 == 0) + return -s2; + + if (s2 == 0) + return -s1; + + bp = fmpz_bits(p); + bq = fmpz_bits(q); + br = fmpz_bits(r); + bs = fmpz_bits(s); + + if (bp + bs + 1 < br + bq) + return -s1; + + if (bp + bs > br + bq + 1) + return s1; + + fmpz_init(t); + fmpz_init(u); + + fmpz_mul(t, p, s); + fmpz_mul(u, q, r); + + res = fmpz_cmp(t, u); + + fmpz_clear(t); + fmpz_clear(u); + + return res; +} + +int +fmpq_cmp(const fmpq_t x, const fmpq_t y) +{ + return _fmpq_cmp(fmpq_numref(x), fmpq_denref(x), + fmpq_numref(y), fmpq_denref(y)); +} + diff --git a/external/flint-2.4.3/fmpq/div.c b/external/flint-2.4.3/fmpq/div.c new file mode 100644 index 0000000..9037e31 --- /dev/null +++ b/external/flint-2.4.3/fmpq/div.c @@ -0,0 +1,64 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpq.h" + +void +_fmpq_div(fmpz_t rnum, fmpz_t rden, const fmpz_t op1num, const fmpz_t op1den, + const fmpz_t op2num, const fmpz_t op2den) +{ + fmpz_t t, u; + + fmpz_init(t); + fmpz_init(u); + fmpz_set(t, op2den); + fmpz_set(u, op2num); + + _fmpq_mul(rnum, rden, op1num, op1den, t, u); + + fmpz_clear(t); + fmpz_clear(u); + + if (fmpz_sgn(rden) < 0) + { + fmpz_neg(rnum, rnum); + fmpz_neg(rden, rden); + } +} + +void fmpq_div(fmpq_t res, const fmpq_t op1, const fmpq_t op2) +{ + if (fmpq_is_zero(op2)) + { + flint_printf("Exception (fmpq_div). Division by zero.\n"); + abort(); + } + + _fmpq_div(fmpq_numref(res), fmpq_denref(res), + fmpq_numref(op1), fmpq_denref(op1), + fmpq_numref(op2), fmpq_denref(op2)); +} + diff --git a/external/flint-2.4.3/fmpq/div_2exp.c b/external/flint-2.4.3/fmpq/div_2exp.c new file mode 100644 index 0000000..8f9b203 --- /dev/null +++ b/external/flint-2.4.3/fmpq/div_2exp.c @@ -0,0 +1,49 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq.h" + +void fmpq_div_2exp(fmpq_t res, const fmpq_t x, mp_bitcnt_t exp) +{ + if (fmpq_is_zero(x) || exp == 0) + { + fmpq_set(res, x); + } + else + { + mp_bitcnt_t v = fmpz_val2(fmpq_numref(x)); + + if (exp <= v) + { + fmpz_fdiv_q_2exp(fmpq_numref(res), fmpq_numref(x), exp); + fmpz_set(fmpq_denref(res), fmpq_denref(x)); + } + else + { + fmpz_fdiv_q_2exp(fmpq_numref(res), fmpq_numref(x), v); + fmpz_mul_2exp(fmpq_denref(res), fmpq_denref(x), exp - v); + } + } +} diff --git a/external/flint-2.4.3/fmpq/div_fmpz.c b/external/flint-2.4.3/fmpq/div_fmpz.c new file mode 100644 index 0000000..6c08473 --- /dev/null +++ b/external/flint-2.4.3/fmpq/div_fmpz.c @@ -0,0 +1,46 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpq.h" + +void fmpq_div_fmpz(fmpq_t res, const fmpq_t op, const fmpz_t x) +{ + fmpz_t y; + + fmpz_init(y); + fmpz_one(y); + + _fmpq_mul(fmpq_numref(res), fmpq_denref(res), + fmpq_numref(op), fmpq_denref(op), y, x); + + fmpz_clear(y); + + if (fmpz_sgn(fmpq_denref(res)) < 0) + { + fmpz_neg(fmpq_numref(res), fmpq_numref(res)); + fmpz_neg(fmpq_denref(res), fmpq_denref(res)); + } +} + diff --git a/external/flint-2.4.3/fmpq/doc/fmpq.txt b/external/flint-2.4.3/fmpq/doc/fmpq.txt new file mode 100644 index 0000000..35e21fe --- /dev/null +++ b/external/flint-2.4.3/fmpq/doc/fmpq.txt @@ -0,0 +1,594 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + + +******************************************************************************* + + Memory management + +******************************************************************************* + +void fmpq_init(fmpq_t x) + + Initialises the \code{fmpq_t} variable \code{x} for use. Its value + is set to 0. + +void fmpq_clear(fmpq_t x) + + Clears the \code{fmpq_t} variable \code{x}. To use the variable again, + it must be re-initialised with \code{fmpq_init}. + +fmpq * _fmpq_vec_init(slong n) + + Initialises a vector of \code{fmpq} values of length $n$ and sets + all values to 0. This is equivalent to generating a \code{fmpz} vector + of length $2n$ with \code{_fmpz_vec_init} and setting all denominators + to 1. + +void _fmpq_vec_clear(fmpq * vec, slong n) + + Frees an \code{fmpq} vector. + +******************************************************************************* + + Canonicalisation + +******************************************************************************* + +void fmpq_canonicalise(fmpq_t res) + + Puts \code{res} in canonical form: the numerator and denominator are + reduced to lowest terms, and the denominator is made positive. + If the numerator is zero, the denominator is set to one. + + If the denominator is zero, the outcome of calling this function is + undefined, regardless of the value of the numerator. + +void _fmpq_canonicalise(fmpz_t num, fmpz_t den) + + Does the same thing as \code{fmpq_canonicalise}, but for numerator + and denominator given explicitly as \code{fmpz_t} variables. Aliasing + of \code{num} and \code{den} is not allowed. + +int fmpq_is_canonical(const fmpq_t x) + + Returns nonzero if \code{fmpq_t} x is in canonical form + (as produced by \code{fmpq_canonicalise}), and zero otherwise. + +int _fmpq_is_canonical(const fmpz_t num, const fmpz_t den) + + Does the same thing as \code{fmpq_is_canonical}, but for numerator + and denominator given explicitly as \code{fmpz_t} variables. + +******************************************************************************* + + Basic assignment + +******************************************************************************* + +void fmpq_set(fmpq_t dest, const fmpq_t src) + + Sets \code{dest} to a copy of \code{src}. No canonicalisation + is performed. + +void fmpq_swap(fmpq_t op1, fmpq_t op2) + + Swaps the two rational numbers \code{op1} and \code{op2}. + +void fmpq_neg(fmpq_t dest, const fmpq_t src) + + Sets \code{dest} to the additive inverse of \code{src}. + +void fmpq_abs(fmpq_t dest, const fmpq_t src) + + Sets \code{dest} to the absolute value of \code{src}. + +void fmpq_zero(fmpq_t res) + + Sets the value of \code{res} to 0. + +void fmpq_one(fmpq_t res) + + Sets the value of \code{res} to $1$. + +******************************************************************************* + + Comparison + +******************************************************************************* + +int fmpq_is_zero(const fmpq_t res) + + Returns nonzero if \code{res} has value 0, and returns zero otherwise. + +int fmpq_is_one(const fmpq_t res) + + Returns nonzero if \code{res} has value $1$, and returns zero otherwise. + +int fmpq_equal(const fmpq_t x, const fmpq_t y) + + Returns nonzero if \code{x} and \code{y} are equal, and zero otherwise. + Assumes that \code{x} and \code{y} are both in canonical form. + +int fmpq_sgn(const fmpq_t x) + + Returns the sign of the rational number $x$. + +int fmpq_cmp(const fmpq_t x, const fmpq_t y) + + Returns negative if $x < y$, zero if $x = y$, and positive if $x > y$. + +void fmpq_height(fmpz_t height, const fmpq_t x) + + Sets \code{height} to the height of $x$, defined as the larger of + the absolute values of the numerator and denominator of $x$. + +mp_bitcnt_t fmpq_height_bits(const fmpq_t x) + + Returns the number of bits in the height of $x$. + +******************************************************************************* + + Conversion + +******************************************************************************* + +void fmpq_set_fmpz_frac(fmpq_t res, const fmpz_t p, const fmpz_t q) + + Sets \code{res} to the canonical form of the fraction \code{p / q}. + This is equivalent to assigning the numerator and denominator + separately and calling \code{fmpq_canonicalise}. + +void fmpq_set_si(fmpq_t res, slong p, ulong q) + + Sets \code{res} to the canonical form of the fraction \code{p / q}. + +void _fmpq_set_si(fmpz_t rnum, fmpz_t rden, slong p, ulong q) + + Sets \code{(rnum, rden)} to the canonical form of the fraction + \code{p / q}. \code{rnum} and \code{rden} may not be aliased. + +void fmpq_set_mpq(fmpq_t dest, const mpq_t src) + + Sets the value of \code{dest} to that of the \code{mpq_t} variable + \code{src}. + +void fmpq_get_mpq(mpq_t dest, const fmpq_t src) + + Sets the value of \code{dest} + +int fmpq_get_mpfr(mpfr_t dest, const fmpq_t src, mpfr_rnd_t rnd) + + Sets the MPFR variable \code{dest} to the value of \code{src}, + rounded to the nearest representable binary floating-point value + in direction \code{rnd}. Returns the sign of the rounding, + according to MPFR conventions. + +char * _fmpq_get_str(char * str, int b, const fmpz_t num, const fmpz_t den) + +char * fmpq_get_str(char * str, int b, const fmpq_t x) + + Prints the string representation of $x$ in base $b \in [2, 36]$ + to a suitable buffer. + + If \code{str} is not \code{NULL}, this is used as the buffer and + also the return value. If \code{str} is \code{NULL}, allocates + sufficient space and returns a pointer to the string. + +void flint_mpq_init_set_readonly(mpq_t z, const fmpq_t f) + + Sets the unitialised \code{mpq_t} $z$ to the value of the + readonly \code{fmpq_t} $f$. + + Note that it is assumed that $f$ does not change during + the lifetime of $z$. + + The rational $z$ has to be cleared by a call to + \code{flint_mpq_clear_readonly()}. + + The suggested use of the two functions is as follows: + \begin{lstlisting}[language=C] + fmpq_t f; + ... + { + mpq_t z; + + flint_mpq_init_set_readonly(z, f); + foo(..., z); + flint_mpq_clear_readonly(z); + } + \end{lstlisting} + + This provides a convenient function for user code, only + requiring to work with the types \code{fmpq_t} and \code{mpq_t}. + +void flint_mpq_clear_readonly(mpq_t z) + + Clears the readonly \code{mpq_t} $z$. + +void fmpq_init_set_readonly(fmpq_t f, const mpq_t z) + + Sets the uninitialised \code{fmpq_t} $f$ to a readonly + version of the rational $z$. + + Note that the value of $z$ is assumed to remain constant + throughout the lifetime of $f$. + + The \code{fmpq_t} $f$ has to be cleared by calling the + function \code{fmpq_clear_readonly()}. + + The suggested use of the two functions is as follows: + \begin{lstlisting}[language=C] + mpq_t z; + ... + { + fmpq_t f; + + fmpq_init_set_readonly(f, z); + foo(..., f); + fmpq_clear_readonly(f); + } + \end{lstlisting} + +void fmpq_clear_readonly(fmpq_t f) + + Clears the readonly \code{fmpq_t} $f$. + +******************************************************************************* + + Input and output + +******************************************************************************* + +void fmpq_fprint(FILE * file, const fmpq_t x) + + Prints \code{x} as a fraction to the stream \code{file}. + The numerator and denominator are printed verbatim as integers, + with a forward slash (/) printed in between. + +void _fmpq_fprint(FILE * file, const fmpz_t num, const fmpz_t den) + + Does the same thing as \code{fmpq_fprint}, but for numerator + and denominator given explicitly as \code{fmpz_t} variables. + +void fmpq_print(const fmpq_t x) + + Prints \code{x} as a fraction. The numerator and denominator are + printed verbatim as integers, with a forward slash (/) printed in + between. + +void _fmpq_print(const fmpz_t num, const fmpz_t den) + + Does the same thing as \code{fmpq_print}, but for numerator + and denominator given explicitly as \code{fmpz_t} variables. + +******************************************************************************* + + Random number generation + +******************************************************************************* + +void fmpq_randtest(fmpq_t res, flint_rand_t state, mp_bitcnt_t bits) + + Sets \code{res} to a random value, with numerator and denominator + having up to \code{bits} bits. The fraction will be in canonical + form. This function has an increased probability of generating + special values which are likely to trigger corner cases. + +void _fmpq_randtest(fmpz_t num, fmpz_t den, flint_rand_t state, + mp_bitcnt_t bits) + + Does the same thing as \code{fmpq_randtest}, but for numerator + and denominator given explicitly as \code{fmpz_t} variables. Aliasing + of \code{num} and \code{den} is not allowed. + +void fmpq_randtest_not_zero(fmpq_t res, flint_rand_t state, mp_bitcnt_t bits) + + As per \code{fmpq_randtest}, but the result will not be $0$. + If \code{bits} is set to $0$, an exception will result. + +void fmpq_randbits(fmpq_t res, flint_rand_t state, mp_bitcnt_t bits) + + Sets \code{res} to a random value, with numerator and denominator + both having exactly \code{bits} bits before canonicalisation, + and then puts \code{res} in canonical form. Note that as a result + of the canonicalisation, the resulting numerator and denominator can + be slightly smaller than \code{bits} bits. + +void _fmpq_randbits(fmpz_t num, fmpz_t den, flint_rand_t state, + mp_bitcnt_t bits) + + Does the same thing as \code{fmpq_randbits}, but for numerator + and denominator given explicitly as \code{fmpz_t} variables. Aliasing + of \code{num} and \code{den} is not allowed. + + +******************************************************************************* + + Arithmetic + +******************************************************************************* + + +void fmpq_add(fmpq_t res, const fmpq_t op1, const fmpq_t op2) + +void fmpq_sub(fmpq_t res, const fmpq_t op1, const fmpq_t op2) + +void fmpq_mul(fmpq_t res, const fmpq_t op1, const fmpq_t op2) + +void fmpq_div(fmpq_t res, const fmpq_t op1, const fmpq_t op2) + + Sets \code{res} respectively to \code{op1 + op2}, \code{op1 - op2}, + \code{op1 * op2}, or \code{op1 / op2}. Assumes that the inputs + are in canonical form, and produces output in canonical form. + Division by zero results in an error. + Aliasing between any combination of the variables is allowed. + +void _fmpq_add(fmpz_t rnum, fmpz_t rden, const fmpz_t op1num, + const fmpz_t op1den, const fmpz_t op2num, const fmpz_t op2den) + +void _fmpq_sub(fmpz_t rnum, fmpz_t rden, const fmpz_t op1num, + const fmpz_t op1den, const fmpz_t op2num, const fmpz_t op2den) + +void _fmpq_mul(fmpz_t rnum, fmpz_t rden, const fmpz_t op1num, + const fmpz_t op1den, const fmpz_t op2num, const fmpz_t op2den) + +void _fmpq_div(fmpz_t rnum, fmpz_t rden, const fmpz_t op1num, + const fmpz_t op1den, const fmpz_t op2num, const fmpz_t op2den) + + Sets \code{(rnum, rden)} to the canonical form of the sum, + difference, product or quotient respectively of the fractions + represented by \code{(op1num, op1den)} and \code{(op2num, op2den)}. + Aliasing between any combination of the variables is allowed, + whilst no numerator is aliased with a denominator. + +void fmpq_addmul(fmpq_t res, const fmpq_t op1, const fmpq_t op2) + +void fmpq_submul(fmpq_t res, const fmpq_t op1, const fmpq_t op2) + + Sets \code{res} to \code{res + op1 * op2} or \code{res - op1 * op2} + respectively, placing the result in canonical form. Aliasing + between any combination of the variables is allowed. + +void _fmpq_addmul(fmpz_t rnum, fmpz_t rden, const fmpz_t op1num, + const fmpz_t op1den, const fmpz_t op2num, const fmpz_t op2den) + +void _fmpq_submul(fmpz_t rnum, fmpz_t rden, const fmpz_t op1num, + const fmpz_t op1den, const fmpz_t op2num, const fmpz_t op2den) + + Sets \code{(rnum, rden)} to the canonical form of the fraction + \code{(rnum, rden)} + \code{(op1num, op1den)} * \code{(op2num, op2den)} or + \code{(rnum, rden)} - \code{(op1num, op1den)} * \code{(op2num, op2den)} + respectively. Aliasing between any combination of the variables is allowed, + whilst no numerator is aliased with a denominator. + +void fmpq_inv(fmpq_t dest, const fmpq_t src) + + Sets \code{dest} to \code{1 / src}. The result is placed in canonical + form, assuming that \code{src} is already in canonical form. + +void _fmpq_pow_si(fmpz_t rnum, fmpz_t rden, + const fmpz_t opnum, const fmpz_t opden, slong e); + +void fmpq_pow_si(fmpq_t res, const fmpq_t op, slong e); + + Sets \code{res} to \code{op} raised to the power~$e$, where~$e$ + is a \code{slong}. If $e$ is $0$ and \code{op} is $0$, then + \code{res} will be set to $1$. + +void fmpq_mul_fmpz(fmpq_t res, const fmpq_t op, const fmpz_t x) + + Sets \code{res} to the product of the rational number \code{op} + and the integer \code{x}. + +void fmpq_div_fmpz(fmpq_t res, const fmpq_t op, const fmpz_t x) + + Sets \code{res} to the quotient of the rational number \code{op} + and the integer \code{x}. + +void fmpq_mul_2exp(fmpq_t res, const fmpq_t x, mp_bitcnt_t exp) + + Sets \code{res} to \code{x} multiplied by \code{2^exp}. + +void fmpq_div_2exp(fmpq_t res, const fmpq_t x, mp_bitcnt_t exp) + + Sets \code{res} to \code{x} divided by \code{2^exp}. + +******************************************************************************* + + Modular reduction and rational reconstruction + +******************************************************************************* + +int _fmpq_mod_fmpz(fmpz_t res, + const fmpz_t num, const fmpz_t den, const fmpz_t mod) + +int fmpq_mod_fmpz(fmpz_t res, const fmpq_t x, const fmpz_t mod) + + Sets the integer \code{res} to the residue $a$ of + $x = n/d$ = \code{(num, den)} modulo the positive integer $m$ = \code{mod}, + defined as the $0 \le a < m$ satisfying $n \equiv a d \pmod m$. + If such an $a$ exists, 1 will be returned, otherwise 0 will + be returned. + +int _fmpq_reconstruct_fmpz_2(fmpz_t n, fmpz_t d, const fmpz_t a, + const fmpz_t m, const fmpz_t N, const fmpz_t D) + +int fmpq_reconstruct_fmpz_2(fmpq_t res, const fmpz_t a, const fmpz_t m, + const fmpz_t N, const fmpz_t D) + + Reconstructs a rational number from its residue $a$ modulo $m$. + + Given a modulus $m > 1$, a residue $0 \le a < m$, and positive $N, D$ + satisfying $2ND < m$, this function attempts to find a fraction $n/d$ with + $0 \le |n| \le N$ and $0 < d \le D$ such that $\gcd(n,d) = 1$ and + $n \equiv ad \pmod m$. If a solution exists, then it is also unique. + The function returns 1 if successful, and 0 to indicate that no solution + exists. + +int _fmpq_reconstruct_fmpz(fmpz_t n, fmpz_t d, const fmpz_t a, + const fmpz_t m) + +int fmpq_reconstruct_fmpz(fmpq_t res, const fmpz_t a, const fmpz_t m) + + Reconstructs a rational number from its residue $a$ modulo $m$, + returning 1 if successful and 0 if no solution exists. + Uses the balanced bounds $N = D = \lfloor\sqrt{m/2}\rfloor$. + + +******************************************************************************* + + Rational enumeration + +******************************************************************************* + +void _fmpq_next_minimal(fmpz_t rnum, fmpz_t rden, + const fmpz_t num, const fmpz_t den) + +void fmpq_next_minimal(fmpq_t res, const fmpq_t x) + + Given $x$ which is assumed to be nonnegative and in canonical form, sets + \code{res} to the next rational number in the sequence obtained by + enumerating all positive denominators $q$, for each $q$ enumerating + the numerators $1 \le p < q$ in order and generating both $p/q$ and $q/p$, + but skipping all $\gcd(p,q) \ne 1$. Starting with zero, this generates + every nonnegative rational number once and only once, with the first + few entries being: + + $$0, 1, 1/2, 2, 1/3, 3, 2/3, 3/2, 1/4, 4, 3/4, 4/3, 1/5, 5, 2/5, \ldots.$$ + + This enumeration produces the rational numbers in order of + minimal height. It has the disadvantage of being somewhat slower to + compute than the Calkin-Wilf enumeration. + +void _fmpq_next_signed_minimal(fmpz_t rnum, fmpz_t rden, + const fmpz_t num, const fmpz_t den) + +void fmpq_next_signed_minimal(fmpq_t res, const fmpq_t x) + + Given a signed rational number $x$ assumed to be in canonical form, sets + \code{res} to the next element in the minimal-height sequence + generated by \code{fmpq_next_minimal} but with negative numbers + interleaved: + + $$0, 1, -1, 1/2, -1/2, 2, -2, 1/3, -1/3, \ldots.$$ + + Starting with zero, this generates every rational number once + and only once, in order of minimal height. + +void _fmpq_next_calkin_wilf(fmpz_t rnum, fmpz_t rden, + const fmpz_t num, const fmpz_t den) + +void fmpq_next_calkin_wilf(fmpq_t res, const fmpq_t x) + + Given $x$ which is assumed to be nonnegative and in canonical form, sets + \code{res} to the next number in the breadth-first traversal of the + Calkin-Wilf tree. Starting with zero, this generates every nonnegative + rational number once and only once, with the first few entries being: + + $$0, 1, 1/2, 2, 1/3, 3/2, 2/3, 3, 1/4, 4/3, 3/5, 5/2, 2/5, \ldots.$$ + + Despite the appearance of the initial entries, the Calkin-Wilf + enumeration does not produce the rational numbers in order of height: + some small fractions will appear late in the sequence. This order + has the advantage of being faster to produce than the minimal-height + order. + +void _fmpq_next_signed_calkin_wilf(fmpz_t rnum, fmpz_t rden, + const fmpz_t num, const fmpz_t den) + +void fmpq_next_signed_calkin_wilf(fmpq_t res, const fmpq_t x) + + Given a signed rational number $x$ assumed to be in canonical form, sets + \code{res} to the next element in the Calkin-Wilf sequence with + negative numbers interleaved: + + $$0, 1, -1, 1/2, -1/2, 2, -2, 1/3, -1/3, \ldots.$$ + + Starting with zero, this generates every rational number once + and only once, but not in order of minimal height. + +******************************************************************************* + + Continued fractions + +******************************************************************************* + +slong fmpq_get_cfrac(fmpz * c, fmpq_t rem, const fmpq_t x, slong n) + + Generates up to $n$ terms of the (simple) continued fraction expansion + of $x$, writing the coefficients to the vector $c$ and the remainder $r$ + to the \code{rem} variable. The return value is the number $k$ of + generated terms. The output satisfies: + + $$ + x = c_0 + \cfrac{1}{c_1 + \cfrac{1}{c_2 + + \cfrac{1}{ \ddots + \cfrac{1}{c_{k-1} + r }}}} + $$ + + If $r$ is zero, the continued fraction expansion is complete. + If $r$ is nonzero, $1/r$ can be passed back as input to generate + $c_k, c_{k+1}, \ldots$. Calls to \code{fmpq_get_cfrac} can therefore + be chained to generate the continued fraction incrementally, + extracting any desired number of coefficients at a time. + + In general, a rational number has exactly two continued fraction + expansions. By convention, we generate the shorter one. The longer + expansion can be obtained by replacing the last coefficient + $a_{k-1}$ by the pair of coefficients $a_{k-1} - 1, 1$. + + As a special case, the continued fraction expansion of zero consists + of a single zero (and not the empty sequence). + + This function implements a simple algorithm, performing repeated + divisions. The running time is quadratic. + +void fmpq_set_cfrac(fmpq_t x, const fmpz * c, slong n) + + Sets $x$ to the value of the continued fraction + + $$ + x = c_0 + \cfrac{1}{c_1 + \cfrac{1}{c_2 + + \cfrac{1}{ \ddots + \cfrac{1}{c_{n-1}}}}} + $$ + + where all $c_i$ except $c_0$ should be nonnegative. + It is assumed that $n > 0$. + + For large $n$, this function implements a subquadratic algorithm. + The convergents are given by a chain product of 2 by 2 matrices. + This product is split in half recursively to balance the size + of the coefficients. + +slong fmpq_cfrac_bound(const fmpq_t x) + + Returns an upper bound for the number of terms in the continued + fraction expansion of $x$. The computed bound is not necessarily sharp. + + We use the fact that the smallest denominator + that can give a continued fraction of length $n$ is the Fibonacci + number $F_{n+1}$. + diff --git a/external/flint-2.4.3/fmpq/fprint.c b/external/flint-2.4.3/fmpq/fprint.c new file mode 100644 index 0000000..c7a6c8f --- /dev/null +++ b/external/flint-2.4.3/fmpq/fprint.c @@ -0,0 +1,46 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpq.h" + +void _fmpq_fprint(FILE * file, const fmpz_t num, const fmpz_t den) +{ + if (fmpz_is_one(den)) + { + fmpz_fprint(file, num); + } + else + { + fmpz_fprint(file, num); + fputc('/', file); + fmpz_fprint(file, den); + } +} + +void fmpq_fprint(FILE * file, const fmpq_t x) +{ + _fmpq_fprint(file, &x->num, &x->den); +} diff --git a/external/flint-2.4.3/fmpq/get_cfrac.c b/external/flint-2.4.3/fmpq/get_cfrac.c new file mode 100644 index 0000000..46798e9 --- /dev/null +++ b/external/flint-2.4.3/fmpq/get_cfrac.c @@ -0,0 +1,54 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq.h" + +slong +fmpq_get_cfrac(fmpz * c, fmpq_t rem, const fmpq_t x, slong n) +{ + fmpz_t p, q; + slong i; + + fmpz_init(p); + fmpz_init(q); + + fmpz_set(p, fmpq_numref(x)); + fmpz_set(q, fmpq_denref(x)); + + for (i = 0; i < n && !fmpz_is_zero(q); i++) + { + fmpz_fdiv_qr(c + i, p, p, q); + fmpz_swap(p, q); + } + + fmpz_set(fmpq_numref(rem), q); + fmpz_set(fmpq_denref(rem), p); + fmpq_canonicalise(rem); + + fmpz_clear(p); + fmpz_clear(q); + + return i; +} diff --git a/external/flint-2.4.3/fmpq/get_mpfr.c b/external/flint-2.4.3/fmpq/get_mpfr.c new file mode 100644 index 0000000..e2ae7c8 --- /dev/null +++ b/external/flint-2.4.3/fmpq/get_mpfr.c @@ -0,0 +1,62 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq.h" + +int +fmpq_get_mpfr(mpfr_t r, const fmpq_t x, mpfr_rnd_t rnd) +{ + __mpq_struct mpq; + fmpz p, q; + mp_limb_t pp, qq; + + p = *fmpq_numref(x); + q = *fmpq_denref(x); + + if (p == 0) + return mpfr_set_ui(r, 0, rnd); + + if (COEFF_IS_MPZ(p)) + mpq._mp_num = *COEFF_TO_PTR(p); + else + { + pp = FLINT_ABS(p); + mpq._mp_num._mp_alloc = 1; + mpq._mp_num._mp_size = (p < 0) ? -1 : 1; + mpq._mp_num._mp_d = &pp; + } + + if (COEFF_IS_MPZ(q)) + mpq._mp_den = *COEFF_TO_PTR(q); + else + { + qq = q; + mpq._mp_den._mp_alloc = 1; + mpq._mp_den._mp_size = 1; + mpq._mp_den._mp_d = &qq; + } + + return mpfr_set_q(r, &mpq, rnd); +} diff --git a/external/flint-2.4.3/fmpq/get_str.c b/external/flint-2.4.3/fmpq/get_str.c new file mode 100644 index 0000000..c1e4516 --- /dev/null +++ b/external/flint-2.4.3/fmpq/get_str.c @@ -0,0 +1,63 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpq.h" + +char * _fmpq_get_str(char * str, int b, const fmpz_t num, const fmpz_t den) +{ + char *s; + + if (str == NULL) + { + str = flint_malloc(fmpz_sizeinbase(num, b) + fmpz_sizeinbase(den, b) + 3); + + if (str == NULL) + { + flint_printf("Exception (_fmpq_get_str). Not enough memory.\n"); + abort(); + } + } + + fmpz_get_str(str, b, num); + + if (!fmpz_is_one(den)) + { + s = str; + while (*s != '\0') + s++; + + *s = '/'; + s++; + fmpz_get_str(s, b, den); + } + + return str; +} + +char * fmpq_get_str(char * str, int b, const fmpq_t f) +{ + return _fmpq_get_str(str, b, fmpq_numref(f), fmpq_denref(f)); +} + diff --git a/external/flint-2.4.3/fmpq/height.c b/external/flint-2.4.3/fmpq/height.c new file mode 100644 index 0000000..911dad4 --- /dev/null +++ b/external/flint-2.4.3/fmpq/height.c @@ -0,0 +1,35 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq.h" + +void +fmpq_height(fmpz_t height, const fmpq_t x) +{ + if (fmpz_cmpabs(fmpq_numref(x), fmpq_denref(x)) < 0) + fmpz_abs(height, fmpq_denref(x)); + else + fmpz_abs(height, fmpq_numref(x)); +} diff --git a/external/flint-2.4.3/fmpq/height_bits.c b/external/flint-2.4.3/fmpq/height_bits.c new file mode 100644 index 0000000..8b65675 --- /dev/null +++ b/external/flint-2.4.3/fmpq/height_bits.c @@ -0,0 +1,37 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq.h" + +mp_bitcnt_t +fmpq_height_bits(const fmpq_t x) +{ + mp_bitcnt_t a, b; + + a = fmpz_bits(fmpq_numref(x)); + b = fmpz_bits(fmpq_denref(x)); + + return FLINT_MAX(a, b); +} diff --git a/external/flint-2.4.3/fmpq/init_set_readonly.c b/external/flint-2.4.3/fmpq/init_set_readonly.c new file mode 100644 index 0000000..8f93349 --- /dev/null +++ b/external/flint-2.4.3/fmpq/init_set_readonly.c @@ -0,0 +1,33 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpq.h" + +void fmpq_init_set_readonly(fmpq_t f, const mpq_t z) +{ + fmpz_init_set_readonly(fmpq_numref(f), mpq_numref(z)); + fmpz_init_set_readonly(fmpq_denref(f), mpq_denref(z)); +} + diff --git a/external/flint-2.4.3/fmpq/inv.c b/external/flint-2.4.3/fmpq/inv.c new file mode 100644 index 0000000..a9edf4e --- /dev/null +++ b/external/flint-2.4.3/fmpq/inv.c @@ -0,0 +1,46 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq.h" + +void fmpq_inv(fmpq_t dest, const fmpq_t src) +{ + fmpz tmp; + + if (dest != src) + { + fmpq_set(dest, src); + } + + tmp = dest->num; + dest->num = dest->den; + dest->den = tmp; + + if (fmpz_sgn(&dest->den) < 0) + { + fmpz_neg(&dest->den, &dest->den); + fmpz_neg(&dest->num, &dest->num); + } +} diff --git a/external/flint-2.4.3/fmpq/is_canonical.c b/external/flint-2.4.3/fmpq/is_canonical.c new file mode 100644 index 0000000..98cf027 --- /dev/null +++ b/external/flint-2.4.3/fmpq/is_canonical.c @@ -0,0 +1,47 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq.h" + +int _fmpq_is_canonical(const fmpz_t num, const fmpz_t den) +{ + fmpz_t u; + int result; + + if (fmpz_is_one(den)) return 1; + if (fmpz_sgn(den) <= 0) return 0; + if (fmpz_is_zero(num)) return fmpz_is_one(den); + + fmpz_init(u); + fmpz_gcd(u, num, den); + result = fmpz_is_one(u); + fmpz_clear(u); + return result; +} + +int fmpq_is_canonical(const fmpq_t x) +{ + return _fmpq_is_canonical(fmpq_numref(x), fmpq_denref(x)); +} diff --git a/external/flint-2.4.3/fmpq/mod_fmpz.c b/external/flint-2.4.3/fmpq/mod_fmpz.c new file mode 100644 index 0000000..e75ebc7 --- /dev/null +++ b/external/flint-2.4.3/fmpq/mod_fmpz.c @@ -0,0 +1,47 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq.h" + +int +_fmpq_mod_fmpz(fmpz_t res, const fmpz_t num, const fmpz_t den, const fmpz_t mod) +{ + int result; + fmpz_t tmp; + + fmpz_init(tmp); + result = fmpz_invmod(tmp, den, mod); + fmpz_mul(tmp, tmp, num); + fmpz_mod(res, tmp, mod); + fmpz_clear(tmp); + + return result; +} + +int fmpq_mod_fmpz(fmpz_t res, const fmpq_t x, const fmpz_t mod) +{ + return _fmpq_mod_fmpz(res, fmpq_numref(x), fmpq_denref(x), mod); +} + diff --git a/external/flint-2.4.3/fmpq/mpq_clear_readonly.c b/external/flint-2.4.3/fmpq/mpq_clear_readonly.c new file mode 100644 index 0000000..74a5fb6 --- /dev/null +++ b/external/flint-2.4.3/fmpq/mpq_clear_readonly.c @@ -0,0 +1,33 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpq.h" + +void flint_mpq_clear_readonly(mpq_t z) +{ + flint_mpz_clear_readonly(mpq_numref(z)); + flint_mpz_clear_readonly(mpq_denref(z)); +} + diff --git a/external/flint-2.4.3/fmpq/mpq_init_set_readonly.c b/external/flint-2.4.3/fmpq/mpq_init_set_readonly.c new file mode 100644 index 0000000..92056db --- /dev/null +++ b/external/flint-2.4.3/fmpq/mpq_init_set_readonly.c @@ -0,0 +1,33 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpq.h" + +void flint_mpq_init_set_readonly(mpq_t z, const fmpq_t f) +{ + flint_mpz_init_set_readonly(mpq_numref(z), fmpq_numref(f)); + flint_mpz_init_set_readonly(mpq_denref(z), fmpq_denref(f)); +} + diff --git a/external/flint-2.4.3/fmpq/mul.c b/external/flint-2.4.3/fmpq/mul.c new file mode 100644 index 0000000..36b61de --- /dev/null +++ b/external/flint-2.4.3/fmpq/mul.c @@ -0,0 +1,105 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq.h" + +void +_fmpq_mul(fmpz_t rnum, fmpz_t rden, const fmpz_t op1num, const fmpz_t op1den, + const fmpz_t op2num, const fmpz_t op2den) +{ + /* Common special cases: squaring, same denominator (e.g. both integers) */ + if (((op1num == op2num) && (op1den == op2den)) || + fmpz_equal(op1den, op2den)) + { + fmpz_mul(rnum, op1num, op2num); + fmpz_mul(rden, op1den, op2den); + } + /* Exactly one argument is an integer */ + else if (fmpz_is_one(op1den)) + { + fmpz_t t, x; + fmpz_init(t); + fmpz_init(x); + + fmpz_gcd(t, op1num, op2den); + fmpz_divexact(x, op1num, t); + fmpz_mul(rnum, x, op2num); + fmpz_divexact(t, op2den, t); + fmpz_mul(rden, op1den, t); + + fmpz_clear(t); + fmpz_clear(x); + } + else if (fmpz_is_one(op2den)) + { + fmpz_t t, x; + fmpz_init(t); + fmpz_init(x); + + fmpz_gcd(t, op2num, op1den); + fmpz_divexact(x, op2num, t); + fmpz_mul(rnum, x, op1num); + fmpz_divexact(t, op1den, t); + fmpz_mul(rden, op2den, t); + + fmpz_clear(t); + fmpz_clear(x); + } + else + { + fmpz_t t, u, x, y; + + fmpz_init(t); + fmpz_init(u); + fmpz_init(x); + fmpz_init(y); + + fmpz_gcd(t, op1num, op2den); + fmpz_gcd(u, op1den, op2num); + + fmpz_divexact(x, op1num, t); + fmpz_divexact(y, op2num, u); + + fmpz_mul(rnum, x, y); + + fmpz_divexact(x, op1den, u); + fmpz_divexact(y, op2den, t); + + fmpz_mul(rden, x, y); + + fmpz_clear(t); + fmpz_clear(u); + fmpz_clear(x); + fmpz_clear(y); + } +} + + +void fmpq_mul(fmpq_t res, const fmpq_t op1, const fmpq_t op2) +{ + _fmpq_mul(fmpq_numref(res), fmpq_denref(res), + fmpq_numref(op1), fmpq_denref(op1), + fmpq_numref(op2), fmpq_denref(op2)); +} diff --git a/external/flint-2.4.3/fmpq/mul_2exp.c b/external/flint-2.4.3/fmpq/mul_2exp.c new file mode 100644 index 0000000..6e8fb48 --- /dev/null +++ b/external/flint-2.4.3/fmpq/mul_2exp.c @@ -0,0 +1,49 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq.h" + +void fmpq_mul_2exp(fmpq_t res, const fmpq_t x, mp_bitcnt_t exp) +{ + if (fmpq_is_zero(x) || exp == 0) + { + fmpq_set(res, x); + } + else + { + mp_bitcnt_t v = fmpz_val2(fmpq_denref(x)); + + if (exp <= v) + { + fmpz_set(fmpq_numref(res), fmpq_numref(x)); + fmpz_fdiv_q_2exp(fmpq_denref(res), fmpq_denref(x), exp); + } + else + { + fmpz_mul_2exp(fmpq_numref(res), fmpq_numref(x), exp - v); + fmpz_fdiv_q_2exp(fmpq_denref(res), fmpq_denref(x), v); + } + } +} diff --git a/external/flint-2.4.3/fmpq/mul_fmpz.c b/external/flint-2.4.3/fmpq/mul_fmpz.c new file mode 100644 index 0000000..70aefd8 --- /dev/null +++ b/external/flint-2.4.3/fmpq/mul_fmpz.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpq.h" + +void fmpq_mul_fmpz(fmpq_t res, const fmpq_t op, const fmpz_t x) +{ + fmpz_t y; + + fmpz_init(y); + fmpz_one(y); + + _fmpq_mul(fmpq_numref(res), fmpq_denref(res), + fmpq_numref(op), fmpq_denref(op), x, y); + + fmpz_clear(y); +} diff --git a/external/flint-2.4.3/fmpq/next_calkin_wilf.c b/external/flint-2.4.3/fmpq/next_calkin_wilf.c new file mode 100644 index 0000000..012c463 --- /dev/null +++ b/external/flint-2.4.3/fmpq/next_calkin_wilf.c @@ -0,0 +1,68 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq.h" + +void +_fmpq_next_calkin_wilf(fmpz_t rnum, fmpz_t rden, + const fmpz_t num, const fmpz_t den) +{ + fmpz n, d; + + n = *num; + d = *den; + + if (!COEFF_IS_MPZ(n) && !COEFF_IS_MPZ(d)) + { + /* This does not overflow, as the larger part at most doubles */ + fmpz_set_ui(rnum, d); + fmpz_set_ui(rden, d*(n / d) + d - (n % d)); + } + else + { + fmpz_t q, r, t; + + fmpz_init(q); + fmpz_init(r); + fmpz_init(t); + + fmpz_fdiv_qr(q, r, num, den); + fmpz_set(rnum, den); + fmpz_mul(t, q, den); + fmpz_add(rden, t, den); + fmpz_sub(rden, rden, r); + + fmpz_clear(q); + fmpz_clear(r); + fmpz_clear(t); + } +} + +void +fmpq_next_calkin_wilf(fmpq_t res, const fmpq_t x) +{ + _fmpq_next_calkin_wilf(fmpq_numref(res), fmpq_denref(res), + fmpq_numref(x), fmpq_denref(x)); +} diff --git a/external/flint-2.4.3/fmpq/next_minimal.c b/external/flint-2.4.3/fmpq/next_minimal.c new file mode 100644 index 0000000..fcaf2ef --- /dev/null +++ b/external/flint-2.4.3/fmpq/next_minimal.c @@ -0,0 +1,99 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq.h" + +void +_fmpq_next_minimal(fmpz_t rnum, fmpz_t rden, + const fmpz_t num, const fmpz_t den) +{ + fmpz p, q; + + p = *num; + q = *den; + + if (!COEFF_IS_MPZ(p) && !COEFF_IS_MPZ(q)) + { + if (p < q && p) + { + *rnum = q; + *rden = p; + return; + } + + while (q < p) + { + q++; + if (n_gcd(p, q) == 1) + { + *rnum = q; + *rden = p; + return; + } + } + + *rnum = 1; + fmpz_set_ui(rden, p + 1); + } + else + { + fmpz_t t; + + if (fmpz_cmp(num, den) < 0) + { + fmpz_set(rnum, num); + fmpz_set(rden, den); + fmpz_swap(rnum, rden); + return; + } + + fmpz_init(t); + fmpz_set(rnum, num); + fmpz_set(rden, den); + + while (fmpz_cmp(rden, rnum) < 0) + { + fmpz_add_ui(rden, rden, UWORD(1)); + fmpz_gcd(t, rden, rnum); + if (fmpz_is_one(t)) + { + fmpz_swap(rnum, rden); + fmpz_clear(t); + return; + } + } + + fmpz_add_ui(rden, rden, UWORD(1)); + fmpz_one(rnum); + fmpz_clear(t); + } +} + +void +fmpq_next_minimal(fmpq_t res, const fmpq_t x) +{ + _fmpq_next_minimal(fmpq_numref(res), fmpq_denref(res), + fmpq_numref(x), fmpq_denref(x)); +} diff --git a/external/flint-2.4.3/fmpq/next_signed_calkin_wilf.c b/external/flint-2.4.3/fmpq/next_signed_calkin_wilf.c new file mode 100644 index 0000000..50f7cac --- /dev/null +++ b/external/flint-2.4.3/fmpq/next_signed_calkin_wilf.c @@ -0,0 +1,49 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq.h" + +void +_fmpq_next_signed_calkin_wilf(fmpz_t rnum, fmpz_t rden, + const fmpz_t num, const fmpz_t den) +{ + if (fmpz_sgn(num) > 0) + { + fmpz_neg(rnum, num); + fmpz_set(rden, den); + } + else + { + fmpz_neg(rnum, num); + _fmpq_next_calkin_wilf(rnum, rden, rnum, den); + } +} + +void +fmpq_next_signed_calkin_wilf(fmpq_t res, const fmpq_t x) +{ + _fmpq_next_signed_calkin_wilf(fmpq_numref(res), fmpq_denref(res), + fmpq_numref(x), fmpq_denref(x)); +} diff --git a/external/flint-2.4.3/fmpq/next_signed_minimal.c b/external/flint-2.4.3/fmpq/next_signed_minimal.c new file mode 100644 index 0000000..8bdb2cb --- /dev/null +++ b/external/flint-2.4.3/fmpq/next_signed_minimal.c @@ -0,0 +1,49 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq.h" + +void +_fmpq_next_signed_minimal(fmpz_t rnum, fmpz_t rden, + const fmpz_t num, const fmpz_t den) +{ + if (fmpz_sgn(num) > 0) + { + fmpz_neg(rnum, num); + fmpz_set(rden, den); + } + else + { + fmpz_neg(rnum, num); + _fmpq_next_minimal(rnum, rden, rnum, den); + } +} + +void +fmpq_next_signed_minimal(fmpq_t res, const fmpq_t x) +{ + _fmpq_next_signed_minimal(fmpq_numref(res), fmpq_denref(res), + fmpq_numref(x), fmpq_denref(x)); +} diff --git a/external/flint-2.4.3/fmpq/pow_si.c b/external/flint-2.4.3/fmpq/pow_si.c new file mode 100644 index 0000000..ab7fcf6 --- /dev/null +++ b/external/flint-2.4.3/fmpq/pow_si.c @@ -0,0 +1,68 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpq.h" + +void _fmpq_pow_si(fmpz_t rnum, fmpz_t rden, + const fmpz_t opnum, const fmpz_t opden, slong e) +{ + if (e >= 0) + { + fmpz_pow_ui(rnum, opnum, e); + fmpz_pow_ui(rden, opden, e); + } + else + { + if (rnum == opnum) + { + fmpz t; + + fmpz_pow_ui(rnum, opnum, -e); + fmpz_pow_ui(rden, opden, -e); + + t = *rnum; + *rnum = *rden; + *rden = t; + } + else + { + fmpz_pow_ui(rden, opnum, -e); + fmpz_pow_ui(rnum, opden, -e); + } + + if (fmpz_sgn(rden) < 0) + { + fmpz_neg(rnum, rnum); + fmpz_neg(rden, rden); + } + } +} + +void fmpq_pow_si(fmpq_t rop, const fmpq_t op, slong e) +{ + _fmpq_pow_si(fmpq_numref(rop), fmpq_denref(rop), + fmpq_numref(op), fmpq_denref(op), e); +} + diff --git a/external/flint-2.4.3/fmpq/randbits.c b/external/flint-2.4.3/fmpq/randbits.c new file mode 100644 index 0000000..9bba03f --- /dev/null +++ b/external/flint-2.4.3/fmpq/randbits.c @@ -0,0 +1,43 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq.h" + +void +_fmpq_randbits(fmpz_t num, fmpz_t den, flint_rand_t state, mp_bitcnt_t bits) +{ + fmpz_randbits(num, state, bits); + + do { + fmpz_randbits(den, state, bits); + } while (fmpz_is_zero(den)); + + _fmpq_canonicalise(num, den); +} + +void fmpq_randbits(fmpq_t res, flint_rand_t state, mp_bitcnt_t bits) +{ + _fmpq_randbits(fmpq_numref(res), fmpq_denref(res), state, bits); +} diff --git a/external/flint-2.4.3/fmpq/randtest.c b/external/flint-2.4.3/fmpq/randtest.c new file mode 100644 index 0000000..244a968 --- /dev/null +++ b/external/flint-2.4.3/fmpq/randtest.c @@ -0,0 +1,81 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq.h" + +void +_fmpq_randtest(fmpz_t num, fmpz_t den, flint_rand_t state, mp_bitcnt_t bits) +{ + mp_limb_t x = n_randlimb(state); + + fmpz_randtest(num, state, bits); + fmpz_randtest_not_zero(den, state, bits); + + switch (x % 16) + { + case 0: + fmpz_set_si(num, 1); + break; + case 1: + fmpz_set_si(num, -1); + break; + case 2: + fmpz_set_si(num, 2); + break; + case 3: + fmpz_set_si(num, -2); + break; + } + + switch ((x / 16) % 16) + { + case 0: + fmpz_set_si(den, 1); + break; + case 2: + fmpz_set_si(den, 2); + break; + } + + _fmpq_canonicalise(num, den); +} + +void fmpq_randtest(fmpq_t res, flint_rand_t state, mp_bitcnt_t bits) +{ + _fmpq_randtest(fmpq_numref(res), fmpq_denref(res), state, bits); +} + +void fmpq_randtest_not_zero(fmpq_t f, flint_rand_t state, mp_bitcnt_t bits) +{ + if (bits == 0) + { + flint_printf("Exception (fmpq_randtest_not_zero). bits == 0.\n"); + abort(); + } + + do { + fmpq_randtest(f, state, bits); + } while (fmpq_is_zero(f)); +} diff --git a/external/flint-2.4.3/fmpq/reconstruct_fmpz.c b/external/flint-2.4.3/fmpq/reconstruct_fmpz.c new file mode 100644 index 0000000..f622935 --- /dev/null +++ b/external/flint-2.4.3/fmpq/reconstruct_fmpz.c @@ -0,0 +1,116 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq.h" + +#define ROT(u,v,t) \ + do { fmpz _t = *u; *u = *v; *v = *t; *t = _t; } while (0); + +int +_fmpq_reconstruct_fmpz_2(fmpz_t n, fmpz_t d, + const fmpz_t a, const fmpz_t m, const fmpz_t N, const fmpz_t D) +{ + fmpz_t q, r, s, t; + int success = 0; + + /* Quickly identify small integers */ + if (fmpz_cmp(a, N) <= 0) + { + fmpz_set(n, a); + fmpz_one(d); + return 1; + } + fmpz_sub(n, a, m); + if (fmpz_cmpabs(n, N) <= 0) + { + fmpz_one(d); + return 1; + } + + fmpz_init(q); + fmpz_init(r); + fmpz_init(s); + fmpz_init(t); + + fmpz_set(r, m); fmpz_zero(s); + fmpz_set(n, a); fmpz_one(d); + + while (fmpz_cmpabs(n, N) > 0) + { + fmpz_fdiv_q(q, r, n); + fmpz_mul(t, q, n); fmpz_sub(t, r, t); ROT(r, n, t); + fmpz_mul(t, q, d); fmpz_sub(t, s, t); ROT(s, d, t); + } + + if (fmpz_sgn(d) < 0) + { + fmpz_neg(n, n); + fmpz_neg(d, d); + } + + if (fmpz_cmp(d, D) <= 0) + { + fmpz_gcd(t, n, d); + success = fmpz_is_one(t); + } + + fmpz_clear(q); + fmpz_clear(r); + fmpz_clear(s); + fmpz_clear(t); + + return success; +} + +int +fmpq_reconstruct_fmpz_2(fmpq_t res, const fmpz_t a, const fmpz_t m, + const fmpz_t N, const fmpz_t D) +{ + return _fmpq_reconstruct_fmpz_2(fmpq_numref(res), + fmpq_denref(res), a, m, N, D); +} + +int +_fmpq_reconstruct_fmpz(fmpz_t n, fmpz_t d, + const fmpz_t a, const fmpz_t m) +{ + fmpz_t N; + int result; + + fmpz_init(N); + fmpz_fdiv_q_2exp(N, m, 1); + fmpz_sqrt(N, N); + result = _fmpq_reconstruct_fmpz_2(n, d, a, m, N, N); + fmpz_clear(N); + + return result; +} + +int +fmpq_reconstruct_fmpz(fmpq_t res, const fmpz_t a, const fmpz_t m) +{ + return _fmpq_reconstruct_fmpz(fmpq_numref(res), + fmpq_denref(res), a, m); +} diff --git a/external/flint-2.4.3/fmpq/set_cfrac.c b/external/flint-2.4.3/fmpq/set_cfrac.c new file mode 100644 index 0000000..a78175d --- /dev/null +++ b/external/flint-2.4.3/fmpq/set_cfrac.c @@ -0,0 +1,96 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq.h" +#include "fmpz_mat.h" + +void +_fmpq_set_cfrac_basecase(fmpz_t p, fmpz_t t, fmpz_t q, fmpz_t u, + const fmpz * c, slong n) +{ + slong i; + + fmpz_set(p, c); + fmpz_one(q); + fmpz_one(t); + fmpz_zero(u); + + for (i = 1; i < n; i++) + { + fmpz_addmul(t, c + i, p); + fmpz_addmul(u, c + i, q); + fmpz_swap(t, p); + fmpz_swap(u, q); + } +} + +void +_fmpq_set_cfrac_divconquer(fmpz_mat_t P, const fmpz * c, slong n) +{ + if (n < 32) + { + _fmpq_set_cfrac_basecase( + fmpz_mat_entry(P, 0, 0), fmpz_mat_entry(P, 0, 1), + fmpz_mat_entry(P, 1, 0), fmpz_mat_entry(P, 1, 1), c, n); + } + else + { + fmpz_mat_t L, R; + slong m = n / 2; + + fmpz_mat_init(L, 2, 2); + fmpz_mat_init(R, 2, 2); + + _fmpq_set_cfrac_divconquer(L, c, m); + _fmpq_set_cfrac_divconquer(R, c + m, n - m); + fmpz_mat_mul_classical(P, L, R); /* Should be Strassen */ + + fmpz_mat_clear(L); + fmpz_mat_clear(R); + } +} + +void +fmpq_set_cfrac(fmpq_t x, const fmpz * c, slong n) +{ + if (n <= 64) + { + fmpz_t t, u; + fmpz_init(t); + fmpz_init(u); + _fmpq_set_cfrac_basecase(fmpq_numref(x), t, fmpq_denref(x), u, c, n); + fmpz_clear(t); + fmpz_clear(u); + } + else + { + fmpz_mat_t P; + fmpz_mat_init(P, 2, 2); + _fmpq_set_cfrac_divconquer(P, c, n); + fmpz_set(fmpq_numref(x), fmpz_mat_entry(P, 0, 0)); + fmpz_set(fmpq_denref(x), fmpz_mat_entry(P, 1, 0)); + fmpz_mat_clear(P); + } +} diff --git a/external/flint-2.4.3/fmpq/set_fmpz_frac.c b/external/flint-2.4.3/fmpq/set_fmpz_frac.c new file mode 100644 index 0000000..c3aa999 --- /dev/null +++ b/external/flint-2.4.3/fmpq/set_fmpz_frac.c @@ -0,0 +1,74 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpq.h" + +void +fmpq_set_fmpz_frac(fmpq_t res, const fmpz_t p, const fmpz_t q) +{ + if (fmpz_is_zero(p)) + { + fmpq_zero(res); + } + else if (fmpz_is_pm1(q) || fmpz_is_pm1(p)) + { + if (fmpz_sgn(q) < 0) + { + fmpz_neg(fmpq_numref(res), p); + fmpz_neg(fmpq_denref(res), q); + } + else + { + fmpz_set(fmpq_numref(res), p); + fmpz_set(fmpq_denref(res), q); + } + } + else + { + fmpz_t t; + + fmpz_init(t); + fmpz_gcd(t, p, q); + + if (fmpz_is_one(t)) + { + fmpz_set(fmpq_numref(res), p); + fmpz_set(fmpq_denref(res), q); + } + else + { + fmpz_divexact(fmpq_numref(res), p, t); + fmpz_divexact(fmpq_denref(res), q, t); + } + + if (fmpz_sgn(fmpq_denref(res)) < 0) + { + fmpz_neg(fmpq_numref(res), fmpq_numref(res)); + fmpz_neg(fmpq_denref(res), fmpq_denref(res)); + } + + fmpz_clear(t); + } +} diff --git a/external/flint-2.4.3/fmpq/set_si.c b/external/flint-2.4.3/fmpq/set_si.c new file mode 100644 index 0000000..a95c977 --- /dev/null +++ b/external/flint-2.4.3/fmpq/set_si.c @@ -0,0 +1,54 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq.h" + +void _fmpq_set_si(fmpz_t rnum, fmpz_t rden, slong p, ulong q) +{ + if (q == 1 || p == 0) + { + fmpz_set_si(rnum, p); + fmpz_one(rden); + } + else + { + ulong r = n_gcd_full(p < 0 ? (-(ulong) p) : (ulong) p, q); + + if (p < 0) + { + fmpz_set_ui(rnum, (-(ulong) p) / r); + fmpz_neg(rnum, rnum); + } + else + fmpz_set_si(rnum, p / r); + + fmpz_set_ui(rden, q / r); + } +} + +void fmpq_set_si(fmpq_t res, slong p, ulong q) +{ + _fmpq_set_si(fmpq_numref(res), fmpq_denref(res), p, q); +} diff --git a/external/flint-2.4.3/fmpq/sub.c b/external/flint-2.4.3/fmpq/sub.c new file mode 100644 index 0000000..6989673 --- /dev/null +++ b/external/flint-2.4.3/fmpq/sub.c @@ -0,0 +1,142 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq.h" + +void +_fmpq_sub(fmpz_t rnum, fmpz_t rden, const fmpz_t p, const fmpz_t q, + const fmpz_t r, const fmpz_t s) +{ + fmpz_t g, a, b, t, u; + + /* Same denominator */ + if (fmpz_equal(q, s)) + { + fmpz_sub(rnum, p, r); + + /* Both are integers */ + if (fmpz_is_one(q)) + { + fmpz_set(rden, q); + } + else + { + fmpz_init(g); + fmpz_gcd(g, rnum, q); + + if (fmpz_is_one(g)) + { + fmpz_set(rden, q); + } + else + { + fmpz_divexact(rnum, rnum, g); + fmpz_divexact(rden, q, g); + } + fmpz_clear(g); + } + return; + } + + /* p/q is an integer */ + if (fmpz_is_one(q)) + { + fmpz_init(t); + fmpz_mul(t, p, s); + fmpz_sub(rnum, t, r); + fmpz_set(rden, s); + fmpz_clear(t); + return; + } + + /* r/s is an integer */ + if (fmpz_is_one(s)) + { + fmpz_init(t); + fmpz_mul(t, r, q); + fmpz_sub(rnum, p, t); + fmpz_set(rden, q); + fmpz_clear(t); + return; + } + + fmpz_init(g); + fmpz_gcd(g, q, s); + + if (fmpz_is_one(g)) + { + fmpz_init(t); + fmpz_init(u); + + fmpz_mul(t, p, s); + fmpz_mul(u, q, r); + fmpz_sub(rnum, t, u); + fmpz_mul(rden, q, s); + + fmpz_clear(t); + fmpz_clear(u); + } + else + { + fmpz_init(a); + fmpz_init(b); + fmpz_init(t); + fmpz_init(u); + + fmpz_divexact(a, q, g); + fmpz_divexact(b, s, g); + + fmpz_mul(t, p, b); + fmpz_mul(u, r, a); + fmpz_sub(rnum, t, u); + + fmpz_gcd(t, rnum, g); + + if (fmpz_is_one(t)) + { + fmpz_mul(rden, q, b); + } + else + { + fmpz_divexact(rnum, rnum, t); + fmpz_divexact(g, q, t); + fmpz_mul(rden, g, b); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(t); + fmpz_clear(u); + } + + fmpz_clear(g); +} + +void fmpq_sub(fmpq_t res, const fmpq_t op1, const fmpq_t op2) +{ + _fmpq_sub(fmpq_numref(res), fmpq_denref(res), + fmpq_numref(op1), fmpq_denref(op1), + fmpq_numref(op2), fmpq_denref(op2)); +} diff --git a/external/flint-2.4.3/fmpq/submul.c b/external/flint-2.4.3/fmpq/submul.c new file mode 100644 index 0000000..4a7e249 --- /dev/null +++ b/external/flint-2.4.3/fmpq/submul.c @@ -0,0 +1,49 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq.h" + +void +_fmpq_submul(fmpz_t rnum, fmpz_t rden, const fmpz_t op1num, const fmpz_t op1den, + const fmpz_t op2num, const fmpz_t op2den) +{ + fmpz_t u, v; + + fmpz_init(u); + fmpz_init(v); + + _fmpq_mul(u, v, op1num, op1den, op2num, op2den); + _fmpq_sub(rnum, rden, rnum, rden, u, v); + + fmpz_clear(u); + fmpz_clear(v); +} + +void fmpq_submul(fmpq_t res, const fmpq_t op1, const fmpq_t op2) +{ + _fmpq_submul(fmpq_numref(res), fmpq_denref(res), + fmpq_numref(op1), fmpq_denref(op1), + fmpq_numref(op2), fmpq_denref(op2)); +} diff --git a/external/flint-2.4.3/fmpq/test/t-abs.c b/external/flint-2.4.3/fmpq/test/t-abs.c new file mode 100644 index 0000000..2891910 --- /dev/null +++ b/external/flint-2.4.3/fmpq/test/t-abs.c @@ -0,0 +1,113 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 Tom Bachmann (adapt for fmpq) + +******************************************************************************/ + +#include +#include +#include +#include "fmpq.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("abs...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpq_t a, b; + mpq_t c, d; + + fmpq_init(a); + fmpq_init(b); + mpq_init(c); + mpq_init(d); + + fmpq_randtest(a, state, 200); + + fmpq_get_mpq(c, a); + + fmpq_abs(b, a); + mpq_abs(c, c); + + fmpq_get_mpq(d, b); + + result = (mpq_cmp(c, d) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("c = %Qd, d = %Qd\n", c, d); + abort(); + } + + fmpq_clear(a); + fmpq_clear(b); + mpq_clear(c); + mpq_clear(d); + } + + /* Check aliasing */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpq_t a; + mpq_t c, d; + + fmpq_init(a); + mpq_init(c); + mpq_init(d); + + fmpq_randtest(a, state, 200); + + fmpq_get_mpq(c, a); + + fmpq_abs(a, a); + mpq_abs(c, c); + + fmpq_get_mpq(d, a); + + result = (mpq_cmp(c, d) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("c = %Qd, d = %Qd\n", c, d); + abort(); + } + + fmpq_clear(a); + mpq_clear(c); + mpq_clear(d); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} + diff --git a/external/flint-2.4.3/fmpq/test/t-add.c b/external/flint-2.4.3/fmpq/test/t-add.c new file mode 100644 index 0000000..b22652e --- /dev/null +++ b/external/flint-2.4.3/fmpq/test/t-add.c @@ -0,0 +1,194 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("add...."); + fflush(stdout); + + /* x = y + z */ + for (i = 0; i < 10000; i++) + { + fmpq_t x, y, z; + mpq_t X, Y, Z; + + fmpq_init(x); + fmpq_init(y); + fmpq_init(z); + mpq_init(X); + mpq_init(Y); + mpq_init(Z); + + fmpq_randtest(x, state, 200); + fmpq_randtest(y, state, 200); + fmpq_randtest(z, state, 200); + + fmpq_get_mpq(X, x); + fmpq_get_mpq(Y, y); + fmpq_get_mpq(Z, z); + + fmpq_add(x, y, z); + + if (!fmpq_is_canonical(x)) + { + flint_printf("FAIL: result not canonical!\n"); + abort(); + } + + mpq_add(X, Y, Z); + fmpq_get_mpq(Y, x); + + if (!mpq_equal(X, Y)) + { + flint_printf("FAIL: fmpq_add(x,y,z) != mpq_add(X,Y,Z)\n"); + flint_printf("x = "); + fmpq_print(x); + flint_printf("\ny = "); + fmpq_print(y); + flint_printf("\nz = "); + fmpq_print(z); + flint_printf("\n"); + abort(); + } + + fmpq_clear(x); + fmpq_clear(y); + fmpq_clear(z); + + mpq_clear(X); + mpq_clear(Y); + mpq_clear(Z); + } + + /* x = x + y */ + for (i = 0; i < 10000; i++) + { + fmpq_t x, y; + mpq_t X, Y; + + fmpq_init(x); + fmpq_init(y); + mpq_init(X); + mpq_init(Y); + + fmpq_randtest(x, state, 200); + fmpq_randtest(y, state, 200); + + fmpq_get_mpq(X, x); + fmpq_get_mpq(Y, y); + + fmpq_add(x, x, y); + + if (!fmpq_is_canonical(x)) + { + flint_printf("FAIL: result not canonical!\n"); + abort(); + } + + mpq_add(X, X, Y); + fmpq_get_mpq(Y, x); + + if (!mpq_equal(X, Y)) + { + flint_printf("FAIL: fmpq_add(x,x,y) != mpq_add(X,X,Y)\n"); + flint_printf("x = "); + fmpq_print(x); + flint_printf("\ny = "); + fmpq_print(y); + flint_printf("\n"); + abort(); + } + + fmpq_clear(x); + fmpq_clear(y); + + mpq_clear(X); + mpq_clear(Y); + } + + /* x = y + x */ + for (i = 0; i < 10000; i++) + { + fmpq_t x, y; + mpq_t X, Y; + + fmpq_init(x); + fmpq_init(y); + mpq_init(X); + mpq_init(Y); + + fmpq_randtest(x, state, 200); + fmpq_randtest(y, state, 200); + + fmpq_get_mpq(X, x); + fmpq_get_mpq(Y, y); + + fmpq_add(x, y, x); + + if (!fmpq_is_canonical(x)) + { + flint_printf("FAIL: result not canonical!\n"); + abort(); + } + + mpq_add(X, Y, X); + fmpq_get_mpq(Y, x); + + if (!mpq_equal(X, Y)) + { + flint_printf("FAIL: fmpq_add(x,y,x) != mpq_add(X,Y,X)\n"); + flint_printf("x = "); + fmpq_print(x); + flint_printf("\ny = "); + fmpq_print(y); + flint_printf("\n"); + abort(); + } + + fmpq_clear(x); + fmpq_clear(y); + + mpq_clear(X); + mpq_clear(Y); + } + + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq/test/t-addmul.c b/external/flint-2.4.3/fmpq/test/t-addmul.c new file mode 100644 index 0000000..4ed1eef --- /dev/null +++ b/external/flint-2.4.3/fmpq/test/t-addmul.c @@ -0,0 +1,203 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq.h" + +void mpq_addmul(mpq_t x, mpq_t y, mpq_t z) +{ + mpq_t t; + mpq_init(t); + mpq_mul(t, y, z); + mpq_add(x, x, t); + mpq_clear(t); +} + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("addmul...."); + fflush(stdout); + + /* x += y * z */ + for (i = 0; i < 10000; i++) + { + fmpq_t x, y, z; + mpq_t X, Y, Z; + + fmpq_init(x); + fmpq_init(y); + fmpq_init(z); + mpq_init(X); + mpq_init(Y); + mpq_init(Z); + + fmpq_randtest(x, state, 200); + fmpq_randtest(y, state, 200); + fmpq_randtest(z, state, 200); + + fmpq_get_mpq(X, x); + fmpq_get_mpq(Y, y); + fmpq_get_mpq(Z, z); + + fmpq_addmul(x, y, z); + + if (!fmpq_is_canonical(x)) + { + flint_printf("FAIL: result not canonical!\n"); + abort(); + } + + mpq_addmul(X, Y, Z); + fmpq_get_mpq(Y, x); + + if (!mpq_equal(X, Y)) + { + flint_printf("FAIL: fmpq_addmul(x,y,z) != mpq_addmul(X,Y,Z)\n"); + flint_printf("x = "); + fmpq_print(x); + flint_printf("\ny = "); + fmpq_print(y); + flint_printf("\nz = "); + fmpq_print(z); + flint_printf("\n"); + abort(); + } + + fmpq_clear(x); + fmpq_clear(y); + fmpq_clear(z); + + mpq_clear(X); + mpq_clear(Y); + mpq_clear(Z); + } + + /* x += x * y */ + for (i = 0; i < 10000; i++) + { + fmpq_t x, y; + mpq_t X, Y; + + fmpq_init(x); + fmpq_init(y); + mpq_init(X); + mpq_init(Y); + + fmpq_randtest(x, state, 200); + fmpq_randtest(y, state, 200); + + fmpq_get_mpq(X, x); + fmpq_get_mpq(Y, y); + + fmpq_addmul(x, x, y); + + if (!fmpq_is_canonical(x)) + { + flint_printf("FAIL: result not canonical!\n"); + abort(); + } + + mpq_addmul(X, X, Y); + fmpq_get_mpq(Y, x); + + if (!mpq_equal(X, Y)) + { + flint_printf("FAIL: fmpq_addmul(x,x,y) != mpq_addmul(X,X,Y)\n"); + flint_printf("x = "); + fmpq_print(x); + flint_printf("\ny = "); + fmpq_print(y); + flint_printf("\n"); + abort(); + } + + fmpq_clear(x); + fmpq_clear(y); + + mpq_clear(X); + mpq_clear(Y); + } + + /* x += y * x */ + for (i = 0; i < 10000; i++) + { + fmpq_t x, y; + mpq_t X, Y; + + fmpq_init(x); + fmpq_init(y); + mpq_init(X); + mpq_init(Y); + + fmpq_randtest(x, state, 200); + fmpq_randtest(y, state, 200); + + fmpq_get_mpq(X, x); + fmpq_get_mpq(Y, y); + + fmpq_addmul(x, y, x); + + if (!fmpq_is_canonical(x)) + { + flint_printf("FAIL: result not canonical!\n"); + abort(); + } + + mpq_addmul(X, Y, X); + fmpq_get_mpq(Y, x); + + if (!mpq_equal(X, Y)) + { + flint_printf("FAIL: fmpq_addmul(x,y,x) != mpq_addmul(X,Y,X)\n"); + flint_printf("x = "); + fmpq_print(x); + flint_printf("\ny = "); + fmpq_print(y); + flint_printf("\n"); + abort(); + } + + fmpq_clear(x); + fmpq_clear(y); + + mpq_clear(X); + mpq_clear(Y); + } + + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq/test/t-canonicalise.c b/external/flint-2.4.3/fmpq/test/t-canonicalise.c new file mode 100644 index 0000000..be3c0ca --- /dev/null +++ b/external/flint-2.4.3/fmpq/test/t-canonicalise.c @@ -0,0 +1,113 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("canonicalise...."); + fflush(stdout); + + for (i = 0; i < 10000; i++) + { + fmpq_t x; + fmpz_t mult; + + fmpq_init(x); + fmpq_randtest(x, state, 200); + + if (!fmpq_is_canonical(x)) + { + flint_printf("FAIL: expected fmpq_randtest output to be canonical\n"); + fmpq_print(x); + flint_printf("\n"); + abort(); + } + + fmpz_init(mult); + fmpz_randtest_not_zero(mult, state, 200); + fmpz_add_ui(mult, mult, UWORD(1)); + + fmpz_mul(&x->num, &x->num, mult); + fmpz_mul(&x->den, &x->den, mult); + + if (fmpq_is_canonical(x)) + { + flint_printf("FAIL: expected fmpq_is_canonical to detect common factor\n"); + fmpq_print(x); + flint_printf("\n"); + abort(); + } + + fmpq_canonicalise(x); + + if (!fmpq_is_canonical(x)) + { + flint_printf("FAIL: result not canonical after calling fmpq_canonicalise\n"); + fmpq_print(x); + flint_printf("\n"); + abort(); + } + + fmpz_neg(&x->den, &x->den); + + if (fmpq_is_canonical(x)) + { + flint_printf("FAIL: negative denominator reported as being canonical\n"); + fmpq_print(x); + flint_printf("\n"); + abort(); + } + + fmpq_canonicalise(x); + + if (!fmpq_is_canonical(x)) + { + flint_printf("FAIL: result not canonical after calling fmpq_canonicalise\n"); + fmpq_print(x); + flint_printf("\n"); + abort(); + } + + fmpz_clear(mult); + fmpq_clear(x); + } + + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq/test/t-cfrac_bound.c b/external/flint-2.4.3/fmpq/test/t-cfrac_bound.c new file mode 100644 index 0000000..cad4c50 --- /dev/null +++ b/external/flint-2.4.3/fmpq/test/t-cfrac_bound.c @@ -0,0 +1,86 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("cfrac_bound...."); + fflush(stdout); + + for (i = 0; i < 10000; i++) + { + fmpq_t x, r; + fmpz * c; + slong n, bound; + + fmpq_init(x); + fmpq_init(r); + + /* Test worst case (quotient of Fibonacci numbers) */ + if (n_randint(state, 50) == 1) + { + slong v = 1 + n_randint(state, 1000); + fmpz_fib_ui(fmpq_numref(x), v + 1); + fmpz_fib_ui(fmpq_denref(x), v); + } + else + { + fmpq_randtest(x, state, 1 + n_randint(state, 1000)); + } + + bound = fmpq_cfrac_bound(x); + c = _fmpz_vec_init(bound + 10); + n = fmpq_get_cfrac(c, r, x, bound); + + if (n > bound) + { + flint_printf("FAIL: length=%wd > bound=%wd\n", n, bound); + abort(); + } + + _fmpz_vec_clear(c, bound + 10); + fmpq_clear(x); + fmpq_clear(r); + } + + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq/test/t-cmp.c b/external/flint-2.4.3/fmpq/test/t-cmp.c new file mode 100644 index 0000000..8a2369b --- /dev/null +++ b/external/flint-2.4.3/fmpq/test/t-cmp.c @@ -0,0 +1,93 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("cmp...."); + fflush(stdout); + + for (i = 0; i < 10000; i++) + { + fmpq_t x, y; + mpq_t X, Y; + int c1, c2; + + fmpq_init(x); + fmpq_init(y); + mpq_init(X); + mpq_init(Y); + + fmpq_randtest(x, state, 200); + fmpq_randtest(y, state, 200); + + fmpq_get_mpq(X, x); + fmpq_get_mpq(Y, y); + + c1 = fmpq_cmp(x, y); + c2 = mpq_cmp(X, Y); + + if (c1 < 0) c1 = -1; + if (c1 > 0) c1 = 1; + + if (c2 < 0) c2 = -1; + if (c2 > 0) c2 = 1; + + if (c1 != c2) + { + flint_printf("FAIL\n"); + flint_printf("x = "); + fmpq_print(x); + flint_printf("\ny = "); + fmpq_print(y); + flint_printf("\ncmp(x,y) = %d, cmp(X,Y) = %d\n", c1, c2); + abort(); + } + + fmpq_clear(x); + fmpq_clear(y); + + mpq_clear(X); + mpq_clear(Y); + } + + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} + diff --git a/external/flint-2.4.3/fmpq/test/t-div.c b/external/flint-2.4.3/fmpq/test/t-div.c new file mode 100644 index 0000000..9e7c522 --- /dev/null +++ b/external/flint-2.4.3/fmpq/test/t-div.c @@ -0,0 +1,208 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("div...."); + fflush(stdout); + + /* x = y * z */ + for (i = 0; i < 10000; i++) + { + fmpq_t x, y, z; + mpq_t X, Y, Z; + + fmpq_init(x); + fmpq_init(y); + fmpq_init(z); + mpq_init(X); + mpq_init(Y); + mpq_init(Z); + + fmpq_randtest(x, state, 200); + fmpq_randtest(y, state, 200); + do { fmpq_randtest(z, state, 200); } while (fmpq_is_zero(z)); + + fmpq_get_mpq(X, x); + fmpq_get_mpq(Y, y); + fmpq_get_mpq(Z, z); + + fmpq_div(x, y, z); + + if (!fmpq_is_canonical(x)) + { + flint_printf("FAIL: result not canonical!\n"); + fmpq_print(x); + flint_printf("\n"); + fmpq_print(y); + flint_printf("\n"); + fmpq_print(z); + flint_printf("\n"); + abort(); + } + + mpq_div(X, Y, Z); + fmpq_get_mpq(Y, x); + + if (!mpq_equal(X, Y)) + { + flint_printf("FAIL: fmpq_div(x,y,z) != mpq_div(X,Y,Z)\n"); + flint_printf("x = "); + fmpq_print(x); + flint_printf("\ny = "); + fmpq_print(y); + flint_printf("\nz = "); + fmpq_print(z); + flint_printf("\n"); + abort(); + } + + fmpq_clear(x); + fmpq_clear(y); + fmpq_clear(z); + + mpq_clear(X); + mpq_clear(Y); + mpq_clear(Z); + } + + /* x = x / y */ + for (i = 0; i < 10000; i++) + { + fmpq_t x, y; + mpq_t X, Y; + + fmpq_init(x); + fmpq_init(y); + mpq_init(X); + mpq_init(Y); + + fmpq_randtest(x, state, 200); + do { fmpq_randtest(y, state, 200); } while (fmpq_is_zero(y)); + + fmpq_get_mpq(X, x); + fmpq_get_mpq(Y, y); + + fmpq_div(x, x, y); + + if (!fmpq_is_canonical(x)) + { + flint_printf("FAIL: result not canonical!\n"); + fmpq_print(x); + flint_printf("\n"); + fmpq_print(y); + flint_printf("\n"); + abort(); + } + + mpq_div(X, X, Y); + fmpq_get_mpq(Y, x); + + if (!mpq_equal(X, Y)) + { + flint_printf("FAIL: fmpq_div(x,x,y) != mpq_div(X,X,Y)\n"); + flint_printf("x = "); + fmpq_print(x); + flint_printf("\ny = "); + fmpq_print(y); + flint_printf("\n"); + abort(); + } + + fmpq_clear(x); + fmpq_clear(y); + + mpq_clear(X); + mpq_clear(Y); + } + + /* x = y / x */ + for (i = 0; i < 10000; i++) + { + fmpq_t x, y; + mpq_t X, Y; + + fmpq_init(x); + fmpq_init(y); + mpq_init(X); + mpq_init(Y); + + do { fmpq_randtest(x, state, 200); } while (fmpq_is_zero(x)); + fmpq_randtest(y, state, 200); + + fmpq_get_mpq(X, x); + fmpq_get_mpq(Y, y); + + fmpq_div(x, y, x); + + if (!fmpq_is_canonical(x)) + { + flint_printf("FAIL: result not canonical!\n"); + fmpq_print(x); + flint_printf("\n"); + fmpq_print(y); + flint_printf("\n"); + abort(); + } + + mpq_div(X, Y, X); + fmpq_get_mpq(Y, x); + + if (!mpq_equal(X, Y)) + { + flint_printf("FAIL: fmpq_div(x,y,x) != mpq_div(X,Y,X)\n"); + flint_printf("x = "); + fmpq_print(x); + flint_printf("\ny = "); + fmpq_print(y); + flint_printf("\n"); + abort(); + } + + fmpq_clear(x); + fmpq_clear(y); + + mpq_clear(X); + mpq_clear(Y); + } + + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq/test/t-div_2exp.c b/external/flint-2.4.3/fmpq/test/t-div_2exp.c new file mode 100644 index 0000000..82221cb --- /dev/null +++ b/external/flint-2.4.3/fmpq/test/t-div_2exp.c @@ -0,0 +1,154 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("div_2exp...."); + fflush(stdout); + + /* x = y * 2^exp */ + for (i = 0; i < 10000; i++) + { + fmpq_t x, y; + mpq_t X, Y; + mp_bitcnt_t c; + + fmpq_init(x); + fmpq_init(y); + mpq_init(X); + mpq_init(Y); + + fmpq_randtest(x, state, 200); + fmpq_randtest(y, state, 200); + + if (n_randint(state, 5) == 0) + fmpz_mul_2exp(fmpq_numref(y), fmpq_numref(y), n_randint(state, 200)); + else if (n_randint(state, 5) == 0) + fmpz_mul_2exp(fmpq_denref(y), fmpq_denref(y), n_randint(state, 200)); + fmpq_canonicalise(y); + + c = n_randint(state, 200); + fmpq_div_2exp(x, y, c); + + if (!fmpq_is_canonical(x)) + { + flint_printf("FAIL: result not canonical!\n"); + flint_printf("x = "); + fmpq_print(x); + flint_printf("\ny = "); + fmpq_print(y); + flint_printf("\nc = %wu\n", c); + abort(); + } + + fmpq_get_mpq(X, x); + fmpq_get_mpq(Y, y); + mpq_div_2exp(X, Y, c); + fmpq_get_mpq(Y, x); + + if (!mpq_equal(X, Y)) + { + flint_printf("FAIL: fmpq_div_2exp(x,y,c) != mpq_div_2exp(X,Y,c)\n"); + flint_printf("x = "); + fmpq_print(x); + flint_printf("\ny = "); + fmpq_print(y); + flint_printf("\n"); + abort(); + } + + fmpq_clear(x); + fmpq_clear(y); + mpq_clear(X); + mpq_clear(Y); + } + + /* y = y * 2^exp */ + for (i = 0; i < 10000; i++) + { + fmpq_t x, y; + mp_bitcnt_t c; + + fmpq_init(x); + fmpq_init(y); + + fmpq_randtest(x, state, 200); + fmpq_randtest(y, state, 200); + + if (n_randint(state, 5) == 0) + fmpz_mul_2exp(fmpq_numref(y), fmpq_numref(y), n_randint(state, 200)); + else if (n_randint(state, 5) == 0) + fmpz_mul_2exp(fmpq_denref(y), fmpq_denref(y), n_randint(state, 200)); + fmpq_canonicalise(y); + + c = n_randint(state, 200); + fmpq_div_2exp(x, y, c); + fmpq_div_2exp(y, y, c); + + if (!fmpq_is_canonical(y)) + { + flint_printf("FAIL: result not canonical!\n"); + flint_printf("x = "); + fmpq_print(x); + flint_printf("\ny = "); + fmpq_print(y); + flint_printf("\nc = %wu\n", c); + abort(); + } + + if (!fmpq_equal(x, y)) + { + flint_printf("FAIL: fmpq_div_2exp(x,y,c) != fmpq_div_2exp(y,y,c)\n"); + flint_printf("x = "); + fmpq_print(x); + flint_printf("\ny = "); + fmpq_print(y); + flint_printf("\nc = %wu\n", c); + abort(); + } + + fmpq_clear(x); + fmpq_clear(y); + } + + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq/test/t-div_fmpz.c b/external/flint-2.4.3/fmpq/test/t-div_fmpz.c new file mode 100644 index 0000000..8dfae1a --- /dev/null +++ b/external/flint-2.4.3/fmpq/test/t-div_fmpz.c @@ -0,0 +1,112 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("div_fmpz...."); + fflush(stdout); + + /* Aliasing x = x/z */ + for (i = 0; i < 10000; i++) + { + fmpq_t x, y; + fmpz_t z; + + fmpq_init(x); + fmpq_init(y); + fmpz_init(z); + + fmpq_randtest(x, state, 200); + while (fmpz_is_zero(z)) + fmpz_randtest(z, state, 200); + + fmpq_div_fmpz(y, x, z); + fmpq_div_fmpz(x, x, z); + + result = (fmpq_is_canonical(x) && fmpq_is_canonical(y) && fmpq_equal(x, y)); + if (!result) + { + flint_printf("FAIL (alias):\n"); + flint_printf("x = "), fmpq_print(x), flint_printf("\n"); + flint_printf("y = "), fmpq_print(y), flint_printf("\n"); + flint_printf("z = "), fmpz_print(z), flint_printf("\n"); + abort(); + } + + fmpq_clear(x); + fmpq_clear(y); + fmpz_clear(z); + } + + /* Compare with fmpq_div */ + for (i = 0; i < 10000; i++) + { + fmpq_t x, y, z; + + fmpq_init(x); + fmpq_init(y); + fmpq_init(z); + + fmpq_randtest(x, state, 200); + while (fmpq_is_zero(z)) + fmpz_randtest(fmpq_numref(z), state, 200); + + fmpq_div_fmpz(y, x, fmpq_numref(z)); + fmpq_div(x, x, z); + + result = (fmpq_is_canonical(x) && fmpq_is_canonical(y) && fmpq_equal(x, y)); + if (!result) + { + flint_printf("FAIL (cmp):\n"); + flint_printf("x = "), fmpq_print(x), flint_printf("\n"); + flint_printf("y = "), fmpq_print(y), flint_printf("\n"); + flint_printf("z = "), fmpq_print(z), flint_printf("\n"); + abort(); + } + + fmpq_clear(x); + fmpq_clear(y); + fmpq_clear(z); + } + + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/fmpq/test/t-get_cfrac.c b/external/flint-2.4.3/fmpq/test/t-get_cfrac.c new file mode 100644 index 0000000..2fdf67e --- /dev/null +++ b/external/flint-2.4.3/fmpq/test/t-get_cfrac.c @@ -0,0 +1,103 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("get_cfrac...."); + fflush(stdout); + + for (i = 0; i < 10000; i++) + { + fmpq_t x, r; + fmpz *c1, *c2; + slong n1, n2, bound; + + fmpq_init(x); + fmpq_init(r); + + fmpq_randtest(x, state, 1 + n_randint(state, 1000)); + bound = fmpq_cfrac_bound(x); + + c1 = _fmpz_vec_init(bound); + c2 = _fmpz_vec_init(bound); + + n1 = fmpq_get_cfrac(c1, r, x, bound); + + if (!fmpq_is_zero(r)) + { + flint_printf("FAIL: expected zero remainder\n"); + abort(); + } + + /* Test chaining */ + n2 = 0; + while (1) + { + n2 += fmpq_get_cfrac(c2 + n2, x, x, n_randint(state, 10)); + if (fmpq_is_zero(x)) + break; + fmpq_inv(x, x); + } + + if (n1 != n2) + { + flint_printf("FAIL: n1 = %wd, n2 = %wd\n", n1, n2); + abort(); + } + + if (!_fmpz_vec_equal(c1, c2, n1)) + { + flint_printf("FAIL: vectors not equal\n"); + _fmpz_vec_print(c1, n1); flint_printf("\n"); + _fmpz_vec_print(c2, n2); flint_printf("\n"); + abort(); + } + + _fmpz_vec_clear(c1, bound); + _fmpz_vec_clear(c2, bound); + fmpq_clear(x); + fmpq_clear(r); + } + + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq/test/t-get_mpfr.c b/external/flint-2.4.3/fmpq/test/t-get_mpfr.c new file mode 100644 index 0000000..7ef3874 --- /dev/null +++ b/external/flint-2.4.3/fmpq/test/t-get_mpfr.c @@ -0,0 +1,96 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + flint_printf("get_mpfr...."); + fflush(stdout); + + for (i = 0; i < 10000; i++) + { + fmpq_t x; mpq_t y; + mpfr_t f1, f2; + int r1, r2; + mpfr_rnd_t rnd; + + fmpq_init(x); + mpq_init(y); + + mpfr_init2(f1, 2 + n_randint(state, 1000)); + mpfr_init2(f2, mpfr_get_prec(f1)); + + fmpq_randtest(x, state, 2 + n_randint(state, 1000)); + fmpq_get_mpq(y, x); + + switch (n_randint(state, 5)) + { + case 0: rnd = MPFR_RNDZ; break; + case 1: rnd = MPFR_RNDD; break; + case 2: rnd = MPFR_RNDU; break; + case 3: rnd = MPFR_RNDA; break; + default: rnd = MPFR_RNDN; break; + } + + r1 = fmpq_get_mpfr(f1, x, rnd); + r2 = mpfr_set_q(f2, y, rnd); + + if (r1 != r2 || !mpfr_equal_p(f1, f2)) + { + flint_printf("FAIL\n"); + fmpq_print(x); flint_printf("\n"); + flint_printf("r1 = %d, r2 = %d\n", r1, r2); + flint_printf("\nf1: \n"); + mpfr_out_str(stdout, 10, 0, f1, MPFR_RNDN); + flint_printf("\n\nf1: \n"); + mpfr_out_str(stdout, 10, 0, f2, MPFR_RNDN); + flint_printf("\n\n"); + abort(); + } + + fmpq_clear(x); + mpq_clear(y); + mpfr_clear(f1); + mpfr_clear(f2); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq/test/t-get_str.c b/external/flint-2.4.3/fmpq/test/t-get_str.c new file mode 100644 index 0000000..de3ec14 --- /dev/null +++ b/external/flint-2.4.3/fmpq/test/t-get_str.c @@ -0,0 +1,92 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" +#include "fmpq.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("get_str...."); + fflush(stdout); + + + + for (i = 0; i < 100000; i++) + { + fmpq_t a; + mpq_t b; + int base, j; + char *str1, *str2; + + fmpq_init(a); + mpq_init(b); + fmpq_randtest(a, state, 200); + base = (int) (n_randint(state, 31) + 2); + + fmpq_get_mpq(b, a); + + str1 = fmpq_get_str(NULL, base, a); + str2 = mpq_get_str(NULL, base, b); + result = (strlen(str1) == strlen(str2)); + if (result) + { + for (j = 0; result && j < strlen(str1); j++) + if (str1[j] != str2[j]) + result = 0; + } + + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("b = %Qd\n", b); + flint_printf("base = %d\n", base); + flint_printf("str1 = %s\n, str2 = %s\n", str1, str2); + abort(); + } + + flint_free(str1); + flint_free(str2); + + fmpq_clear(a); + mpq_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} + diff --git a/external/flint-2.4.3/fmpq/test/t-height.c b/external/flint-2.4.3/fmpq/test/t-height.c new file mode 100644 index 0000000..263b2b0 --- /dev/null +++ b/external/flint-2.4.3/fmpq/test/t-height.c @@ -0,0 +1,75 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("height...."); + fflush(stdout); + + for (i = 0; i < 10000; i++) + { + fmpq_t x; + fmpz_t h; + mp_bitcnt_t b; + + fmpz_init(h); + fmpq_init(x); + fmpq_randtest(x, state, 200); + + fmpq_height(h, x); + b = fmpq_height_bits(x); + + if (!fmpz_bits(h) == b) + { + flint_printf("FAIL!\n"); + flint_printf("x: "); + fmpq_print(x); + flint_printf("\nh: "); + fmpz_print(h); + flint_printf("\nb: %wd\n", b); + } + + fmpq_clear(x); + fmpz_clear(h); + } + + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq/test/t-init_set_readonly.c b/external/flint-2.4.3/fmpq/test/t-init_set_readonly.c new file mode 100644 index 0000000..3698a2d --- /dev/null +++ b/external/flint-2.4.3/fmpq/test/t-init_set_readonly.c @@ -0,0 +1,126 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "long_extras.h" +#include "fmpz.h" +#include "fmpq.h" + +int main(void) +{ + int i; + FLINT_TEST_INIT(state); + + flint_printf("init_set_readonly...."); + fflush(stdout); + + + + /* Create some small fmpq rationals, clear the mpq_t */ + for (i = 0; i < 100000; i++) + { + fmpq_t f; + mpq_t z; + + fmpq_init(f); + fmpq_randtest(f, state, FLINT_BITS - 2); + + mpq_init(z); + fmpq_get_mpq(z, f); + + { + fmpq_t g; + + fmpq_init_set_readonly(g, z); + fmpq_clear_readonly(g); + } + + mpq_clear(z); + } + + /* Create some small fmpq ratioals, do *not* clear the mpq_t */ + for (i = 0; i < 100000; i++) + { + fmpq_t f; + mpq_t z; + + fmpq_init(f); + fmpq_randtest(f, state, FLINT_BITS - 2); + + mpq_init(z); + fmpq_get_mpq(z, f); + + { + fmpq_t g; + + fmpq_init_set_readonly(g, z); + } + + mpq_clear(z); + } + + /* Create some more fmpq rationals */ + for (i = 0; i < 100000; i++) + { + fmpq_t f; + mpq_t z; + + fmpq_init(f); + fmpq_randtest(f, state, 2 * FLINT_BITS); + mpq_init(z); + fmpq_get_mpq(z, f); + + { + fmpq_t g, h; + + fmpq_init_set_readonly(g, z); + fmpq_init(h); + fmpq_set_mpq(h, z); + + if (!fmpq_equal(g, h)) + { + flint_printf("FAIL:\n\n"); + flint_printf("g = "), fmpq_print(g), flint_printf("\n"); + flint_printf("h = "), fmpq_print(h), flint_printf("\n"); + gmp_printf("z = %Qd\n", z); + } + + fmpq_clear_readonly(g); + fmpq_clear(h); + } + + fmpq_clear(f); + mpq_clear(z); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} + diff --git a/external/flint-2.4.3/fmpq/test/t-inv.c b/external/flint-2.4.3/fmpq/test/t-inv.c new file mode 100644 index 0000000..c9a8f83 --- /dev/null +++ b/external/flint-2.4.3/fmpq/test/t-inv.c @@ -0,0 +1,156 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("inv...."); + fflush(stdout); + + /* x = y * z */ + for (i = 0; i < 10000; i++) + { + fmpq_t x, y, z; + mpq_t X, Y, Z, YY, ZZ; + + fmpq_init(x); + fmpq_init(y); + fmpq_init(z); + mpq_init(X); + mpq_init(Y); + mpq_init(Z); + mpq_init(YY); + mpq_init(ZZ); + + fmpq_randtest(x, state, 200); + fmpq_randtest(y, state, 200); + do { fmpq_randtest(z, state, 200); } while (fmpq_is_zero(z)); + + fmpq_get_mpq(X, x); + fmpq_get_mpq(Y, y); + fmpq_get_mpq(Z, z); + + fmpq_inv(y, z); + fmpq_inv(x, y); + + if (!fmpq_equal(x, z)) + { + flint_printf("FAIL: applying inv twice did not give back the input!\n"); + abort(); + } + + if (!fmpq_is_canonical(y) || !fmpq_is_canonical(x)) + { + flint_printf("FAIL: result not canonical!\n"); + abort(); + } + + mpq_inv(Y, Z); + mpq_inv(X, Z); + + fmpq_get_mpq(YY, y); + fmpq_get_mpq(ZZ, z); + + if (!mpq_equal(Y, YY) || !mpq_equal(Z, ZZ)) + { + flint_printf("FAIL: fmpq_inv != mpq_inv\n"); + flint_printf("x = "); + fmpq_print(x); + flint_printf("\ny = "); + fmpq_print(y); + flint_printf("\nz = "); + fmpq_print(z); + flint_printf("\n"); + abort(); + } + + fmpq_clear(x); + fmpq_clear(y); + fmpq_clear(z); + + mpq_clear(X); + mpq_clear(Y); + mpq_clear(Z); + mpq_clear(YY); + mpq_clear(ZZ); + } + + /* Check aliasing */ + for (i = 0; i < 10000; i++) + { + fmpq_t x; + mpq_t X, Y; + + fmpq_init(x); + mpq_init(X); + mpq_init(Y); + + do { fmpq_randtest(x, state, 200); } while (fmpq_is_zero(x)); + + fmpq_get_mpq(X, x); + + fmpq_inv(x, x); + + if (!fmpq_is_canonical(x)) + { + flint_printf("FAIL: result not canonical!\n"); + abort(); + } + + mpq_inv(X, X); + fmpq_get_mpq(Y, x); + + if (!mpq_equal(X, Y)) + { + flint_printf("FAIL: fmpq_mul(x,x,y) != mpq_mul(X,X,Y)\n"); + flint_printf("x = "); + fmpq_print(x); + flint_printf("\n"); + abort(); + } + + fmpq_clear(x); + + mpq_clear(X); + mpq_clear(Y); + } + + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq/test/t-mpq_init_set_readonly.c b/external/flint-2.4.3/fmpq/test/t-mpq_init_set_readonly.c new file mode 100644 index 0000000..4e4dee5 --- /dev/null +++ b/external/flint-2.4.3/fmpq/test/t-mpq_init_set_readonly.c @@ -0,0 +1,104 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "long_extras.h" +#include "fmpz.h" +#include "fmpq.h" + +int main(void) +{ + int i; + FLINT_TEST_INIT(state); + + flint_printf("mpq_init_set_readonly...."); + fflush(stdout); + + + + /* Create some small fmpq rationals, clear the mpq_t */ + for (i = 0; i < 100000; i++) + { + fmpq_t f; + mpq_t z; + + fmpq_init(f); + fmpq_randtest(f, state, FLINT_BITS - 2); + + flint_mpq_init_set_readonly(z, f); + flint_mpq_clear_readonly(z); + } + + /* Create some large fmpq rationals, do not clear the mpq_t */ + for (i = 0; i < 100000; i++) + { + fmpq_t f; + mpq_t z; + + fmpq_init(f); + fmpq_randtest(f, state, 2 * FLINT_BITS); + + if (COEFF_IS_MPZ(*fmpq_numref(f)) && COEFF_IS_MPZ(*(fmpq_denref(f)))) + { + flint_mpq_init_set_readonly(z, f); + } + + fmpq_clear(f); + } + + /* Create some more fmpq rationals */ + for (i = 0; i < 100000; i++) + { + fmpq_t f, g; + mpq_t z; + + fmpq_init(f); + fmpq_init(g); + fmpq_randtest(f, state, 2 * FLINT_BITS); + + flint_mpq_init_set_readonly(z, f); + fmpq_set_mpq(g, z); + + if (!fmpq_equal(f, g)) + { + flint_printf("FAIL:\n\n"); + flint_printf("f = "), fmpq_print(f), flint_printf("\n"); + flint_printf("g = "), fmpq_print(g), flint_printf("\n"); + gmp_printf("z = %Qd\n", z); + } + + fmpq_clear(f); + fmpq_clear(g); + flint_mpq_clear_readonly(z); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq/test/t-mul.c b/external/flint-2.4.3/fmpq/test/t-mul.c new file mode 100644 index 0000000..08ef898 --- /dev/null +++ b/external/flint-2.4.3/fmpq/test/t-mul.c @@ -0,0 +1,194 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("mul...."); + fflush(stdout); + + /* x = y * z */ + for (i = 0; i < 10000; i++) + { + fmpq_t x, y, z; + mpq_t X, Y, Z; + + fmpq_init(x); + fmpq_init(y); + fmpq_init(z); + mpq_init(X); + mpq_init(Y); + mpq_init(Z); + + fmpq_randtest(x, state, 200); + fmpq_randtest(y, state, 200); + fmpq_randtest(z, state, 200); + + fmpq_get_mpq(X, x); + fmpq_get_mpq(Y, y); + fmpq_get_mpq(Z, z); + + fmpq_mul(x, y, z); + + if (!fmpq_is_canonical(x)) + { + flint_printf("FAIL: result not canonical!\n"); + abort(); + } + + mpq_mul(X, Y, Z); + fmpq_get_mpq(Y, x); + + if (!mpq_equal(X, Y)) + { + flint_printf("FAIL: fmpq_mul(x,y,z) != mpq_mul(X,Y,Z)\n"); + flint_printf("x = "); + fmpq_print(x); + flint_printf("\ny = "); + fmpq_print(y); + flint_printf("\nz = "); + fmpq_print(z); + flint_printf("\n"); + abort(); + } + + fmpq_clear(x); + fmpq_clear(y); + fmpq_clear(z); + + mpq_clear(X); + mpq_clear(Y); + mpq_clear(Z); + } + + /* x = x * y */ + for (i = 0; i < 10000; i++) + { + fmpq_t x, y; + mpq_t X, Y; + + fmpq_init(x); + fmpq_init(y); + mpq_init(X); + mpq_init(Y); + + fmpq_randtest(x, state, 200); + fmpq_randtest(y, state, 200); + + fmpq_get_mpq(X, x); + fmpq_get_mpq(Y, y); + + fmpq_mul(x, x, y); + + if (!fmpq_is_canonical(x)) + { + flint_printf("FAIL: result not canonical!\n"); + abort(); + } + + mpq_mul(X, X, Y); + fmpq_get_mpq(Y, x); + + if (!mpq_equal(X, Y)) + { + flint_printf("FAIL: fmpq_mul(x,x,y) != mpq_mul(X,X,Y)\n"); + flint_printf("x = "); + fmpq_print(x); + flint_printf("\ny = "); + fmpq_print(y); + flint_printf("\n"); + abort(); + } + + fmpq_clear(x); + fmpq_clear(y); + + mpq_clear(X); + mpq_clear(Y); + } + + /* x = y * x */ + for (i = 0; i < 10000; i++) + { + fmpq_t x, y; + mpq_t X, Y; + + fmpq_init(x); + fmpq_init(y); + mpq_init(X); + mpq_init(Y); + + fmpq_randtest(x, state, 200); + fmpq_randtest(y, state, 200); + + fmpq_get_mpq(X, x); + fmpq_get_mpq(Y, y); + + fmpq_mul(x, y, x); + + if (!fmpq_is_canonical(x)) + { + flint_printf("FAIL: result not canonical!\n"); + abort(); + } + + mpq_mul(X, Y, X); + fmpq_get_mpq(Y, x); + + if (!mpq_equal(X, Y)) + { + flint_printf("FAIL: fmpq_mul(x,y,x) != mpq_mul(X,Y,X)\n"); + flint_printf("x = "); + fmpq_print(x); + flint_printf("\ny = "); + fmpq_print(y); + flint_printf("\n"); + abort(); + } + + fmpq_clear(x); + fmpq_clear(y); + + mpq_clear(X); + mpq_clear(Y); + } + + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq/test/t-mul_2exp.c b/external/flint-2.4.3/fmpq/test/t-mul_2exp.c new file mode 100644 index 0000000..053a071 --- /dev/null +++ b/external/flint-2.4.3/fmpq/test/t-mul_2exp.c @@ -0,0 +1,154 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("mul_2exp...."); + fflush(stdout); + + /* x = y * 2^exp */ + for (i = 0; i < 10000; i++) + { + fmpq_t x, y; + mpq_t X, Y; + mp_bitcnt_t c; + + fmpq_init(x); + fmpq_init(y); + mpq_init(X); + mpq_init(Y); + + fmpq_randtest(x, state, 200); + fmpq_randtest(y, state, 200); + + if (n_randint(state, 5) == 0) + fmpz_mul_2exp(fmpq_numref(y), fmpq_numref(y), n_randint(state, 200)); + else if (n_randint(state, 5) == 0) + fmpz_mul_2exp(fmpq_denref(y), fmpq_denref(y), n_randint(state, 200)); + fmpq_canonicalise(y); + + c = n_randint(state, 200); + fmpq_mul_2exp(x, y, c); + + if (!fmpq_is_canonical(x)) + { + flint_printf("FAIL: result not canonical!\n"); + flint_printf("x = "); + fmpq_print(x); + flint_printf("\ny = "); + fmpq_print(y); + flint_printf("\nc = %wu\n", c); + abort(); + } + + fmpq_get_mpq(X, x); + fmpq_get_mpq(Y, y); + mpq_mul_2exp(X, Y, c); + fmpq_get_mpq(Y, x); + + if (!mpq_equal(X, Y)) + { + flint_printf("FAIL: fmpq_mul_2exp(x,y,c) != mpq_mul_2exp(X,Y,c)\n"); + flint_printf("x = "); + fmpq_print(x); + flint_printf("\ny = "); + fmpq_print(y); + flint_printf("\n"); + abort(); + } + + fmpq_clear(x); + fmpq_clear(y); + mpq_clear(X); + mpq_clear(Y); + } + + /* y = y * 2^exp */ + for (i = 0; i < 10000; i++) + { + fmpq_t x, y; + mp_bitcnt_t c; + + fmpq_init(x); + fmpq_init(y); + + fmpq_randtest(x, state, 200); + fmpq_randtest(y, state, 200); + + if (n_randint(state, 5) == 0) + fmpz_mul_2exp(fmpq_numref(y), fmpq_numref(y), n_randint(state, 200)); + else if (n_randint(state, 5) == 0) + fmpz_mul_2exp(fmpq_denref(y), fmpq_denref(y), n_randint(state, 200)); + fmpq_canonicalise(y); + + c = n_randint(state, 200); + fmpq_mul_2exp(x, y, c); + fmpq_mul_2exp(y, y, c); + + if (!fmpq_is_canonical(y)) + { + flint_printf("FAIL: result not canonical!\n"); + flint_printf("x = "); + fmpq_print(x); + flint_printf("\ny = "); + fmpq_print(y); + flint_printf("\nc = %wu\n", c); + abort(); + } + + if (!fmpq_equal(x, y)) + { + flint_printf("FAIL: fmpq_mul_2exp(x,y,c) != fmpq_mul_2exp(y,y,c)\n"); + flint_printf("x = "); + fmpq_print(x); + flint_printf("\ny = "); + fmpq_print(y); + flint_printf("\nc = %wu\n", c); + abort(); + } + + fmpq_clear(x); + fmpq_clear(y); + } + + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq/test/t-mul_fmpz.c b/external/flint-2.4.3/fmpq/test/t-mul_fmpz.c new file mode 100644 index 0000000..56f0f35 --- /dev/null +++ b/external/flint-2.4.3/fmpq/test/t-mul_fmpz.c @@ -0,0 +1,110 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("mul_fmpz...."); + fflush(stdout); + + /* Aliasing x = x*z */ + for (i = 0; i < 10000; i++) + { + fmpq_t x, y; + fmpz_t z; + + fmpq_init(x); + fmpq_init(y); + fmpz_init(z); + + fmpq_randtest(x, state, 200); + fmpz_randtest(z, state, 200); + + fmpq_mul_fmpz(y, x, z); + fmpq_mul_fmpz(x, x, z); + + result = (fmpq_is_canonical(x) && fmpq_is_canonical(y) && fmpq_equal(x, y)); + if (!result) + { + flint_printf("FAIL (alias):\n"); + flint_printf("x = "), fmpq_print(x), flint_printf("\n"); + flint_printf("y = "), fmpq_print(y), flint_printf("\n"); + flint_printf("z = "), fmpz_print(z), flint_printf("\n"); + abort(); + } + + fmpq_clear(x); + fmpq_clear(y); + fmpz_clear(z); + } + + /* Compare with fmpq_mul */ + for (i = 0; i < 10000; i++) + { + fmpq_t x, y, z; + + fmpq_init(x); + fmpq_init(y); + fmpq_init(z); + + fmpq_randtest(x, state, 200); + fmpz_randtest(fmpq_numref(z), state, 200); + + fmpq_mul_fmpz(y, x, fmpq_numref(z)); + fmpq_mul(x, x, z); + + result = (fmpq_is_canonical(x) && fmpq_is_canonical(y) && fmpq_equal(x, y)); + if (!result) + { + flint_printf("FAIL (cmp):\n"); + flint_printf("x = "), fmpq_print(x), flint_printf("\n"); + flint_printf("y = "), fmpq_print(y), flint_printf("\n"); + flint_printf("z = "), fmpq_print(z), flint_printf("\n"); + abort(); + } + + fmpq_clear(x); + fmpq_clear(y); + fmpq_clear(z); + } + + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/fmpq/test/t-next_calkin_wilf.c b/external/flint-2.4.3/fmpq/test/t-next_calkin_wilf.c new file mode 100644 index 0000000..036c6d7 --- /dev/null +++ b/external/flint-2.4.3/fmpq/test/t-next_calkin_wilf.c @@ -0,0 +1,119 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq.h" + +int +main(void) +{ + slong i; + fmpq_t r, ans; + + FLINT_TEST_INIT(state); + + flint_printf("next_calkin_wilf...."); + fflush(stdout); + + fmpq_init(r); + fmpq_init(ans); + + fmpq_set_si(r, 0, 1); + fmpq_set_si(ans, 191, 1287); + for (i = 0; i < 1000000; i++) + fmpq_next_calkin_wilf(r, r); + + if (!fmpq_equal(r, ans)) + { + flint_printf("FAIL: enum from 0\n"); + fmpq_print(r); + flint_printf("\n"); + fmpq_print(ans); + flint_printf("\n"); + abort(); + } + + fmpq_set_si(r, 0, 1); + fmpq_set_si(ans, -191, 1096); + for (i = 0; i < 1000000; i++) + fmpq_next_signed_calkin_wilf(r, r); + + if (!fmpq_equal(r, ans)) + { + flint_printf("FAIL: signed enum from 0\n"); + fmpq_print(r); + flint_printf("\n"); + fmpq_print(ans); + flint_printf("\n"); + abort(); + } + + + fmpz_set_str(fmpq_numref(r), "18446744073709551615", 10); + fmpz_set_str(fmpq_denref(r), "18446744073709551616", 10); + fmpz_set_str(fmpq_numref(ans), "18538977794078099355206", 10); + fmpz_set_str(fmpq_denref(ans), "22062305912156623710275", 10); + for (i = 0; i < 1000000; i++) + fmpq_next_calkin_wilf(r, r); + + if (!fmpq_equal(r, ans)) + { + flint_printf("FAIL: enum from 2^64\n"); + fmpq_print(r); + flint_printf("\n"); + fmpq_print(ans); + flint_printf("\n"); + abort(); + } + + fmpz_set_str(fmpq_numref(r), "18446744073709551615", 10); + fmpz_set_str(fmpq_denref(r), "18446744073709551616", 10); + fmpz_set_str(fmpq_numref(ans), "15015649675999575000951", 10); + fmpz_set_str(fmpq_denref(ans), "18538977794078099356211", 10); + for (i = 0; i < 1000000; i++) + fmpq_next_signed_calkin_wilf(r, r); + + if (!fmpq_equal(r, ans)) + { + flint_printf("FAIL: signed enum from 2^64\n"); + fmpq_print(r); + flint_printf("\n"); + fmpq_print(ans); + flint_printf("\n"); + abort(); + } + + + fmpq_clear(r); + fmpq_clear(ans); + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq/test/t-next_minimal.c b/external/flint-2.4.3/fmpq/test/t-next_minimal.c new file mode 100644 index 0000000..6b5269e --- /dev/null +++ b/external/flint-2.4.3/fmpq/test/t-next_minimal.c @@ -0,0 +1,119 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq.h" + +int +main(void) +{ + slong i; + fmpq_t r, ans; + + FLINT_TEST_INIT(state); + + flint_printf("next_minimal...."); + fflush(stdout); + + fmpq_init(r); + fmpq_init(ans); + + fmpq_set_si(r, 0, 1); + fmpq_set_si(ans, 289, 1283); + for (i = 0; i < 1000000; i++) + fmpq_next_minimal(r, r); + + if (!fmpq_equal(r, ans)) + { + flint_printf("FAIL: enum from 0\n"); + fmpq_print(r); + flint_printf("\n"); + fmpq_print(ans); + flint_printf("\n"); + abort(); + } + + fmpq_set_si(r, 0, 1); + fmpq_set_si(ans, -471, 907); + for (i = 0; i < 1000000; i++) + fmpq_next_signed_minimal(r, r); + + if (!fmpq_equal(r, ans)) + { + flint_printf("FAIL: signed enum from 0\n"); + fmpq_print(r); + flint_printf("\n"); + fmpq_print(ans); + flint_printf("\n"); + abort(); + } + + + fmpz_set_str(fmpq_numref(r), "36893488147419102231", 10); + fmpz_set_str(fmpq_denref(r), "36893488147419103232", 10); + fmpz_set_str(fmpq_numref(ans), "830822", 10); + fmpz_set_str(fmpq_denref(ans), "36893488147419103233", 10); + for (i = 0; i < 1000000; i++) + fmpq_next_minimal(r, r); + + if (!fmpq_equal(r, ans)) + { + flint_printf("FAIL: enum from 2^65\n"); + fmpq_print(r); + flint_printf("\n"); + fmpq_print(ans); + flint_printf("\n"); + abort(); + } + + fmpz_set_str(fmpq_numref(r), "36893488147419102231", 10); + fmpz_set_str(fmpq_denref(r), "36893488147419103232", 10); + fmpz_set_str(fmpq_numref(ans), "414994", 10); + fmpz_set_str(fmpq_denref(ans), "36893488147419103233", 10); + for (i = 0; i < 1000000; i++) + fmpq_next_signed_minimal(r, r); + + if (!fmpq_equal(r, ans)) + { + flint_printf("FAIL: signed enum from 2^65\n"); + fmpq_print(r); + flint_printf("\n"); + fmpq_print(ans); + flint_printf("\n"); + abort(); + } + + + fmpq_clear(r); + fmpq_clear(ans); + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq/test/t-one.c b/external/flint-2.4.3/fmpq/test/t-one.c new file mode 100644 index 0000000..cb0a396 --- /dev/null +++ b/external/flint-2.4.3/fmpq/test/t-one.c @@ -0,0 +1,104 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("one...."); + fflush(stdout); + + /* x == 1 * x */ + for (i = 0; i < 10000; i++) + { + fmpq_t x, y, z; + + fmpq_init(x); + fmpq_init(y); + fmpq_init(z); + + fmpq_randtest(x, state, 200); + fmpq_one(y); + + fmpq_mul(z, y, x); + + result = fmpq_is_canonical(z) && fmpq_equal(x, z); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("x = "), fmpq_print(x), flint_printf("\n"); + flint_printf("y = "), fmpq_print(y), flint_printf("\n"); + flint_printf("z = "), fmpq_print(z), flint_printf("\n"); + abort(); + } + + fmpq_clear(x); + fmpq_clear(y); + fmpq_clear(z); + } + + /* x/x == 1 */ + for (i = 0; i < 10000; i++) + { + fmpq_t x, y; + + fmpq_init(x); + fmpq_init(y); + + while (fmpq_is_zero(x)) + fmpq_randtest(x, state, 200); + + fmpq_div(y, x, x); + + result = fmpq_is_canonical(y) && fmpq_is_one(y); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("x = "), fmpq_print(x), flint_printf("\n"); + flint_printf("y = "), fmpq_print(y), flint_printf("\n"); + abort(); + } + + fmpq_clear(x); + fmpq_clear(y); + } + + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/fmpq/test/t-pow_si.c b/external/flint-2.4.3/fmpq/test/t-pow_si.c new file mode 100644 index 0000000..a6268ee --- /dev/null +++ b/external/flint-2.4.3/fmpq/test/t-pow_si.c @@ -0,0 +1,122 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "long_extras.h" +#include "ulong_extras.h" +#include "fmpq.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("pow_si...."); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 100000; i++) + { + fmpq_t a, b, c; + slong e; + + fmpq_init(a); + fmpq_init(b); + fmpq_init(c); + + fmpq_randtest(a, state, 100); + fmpq_set(b, a); + + e = z_randint(state, 20); + + fmpq_pow_si(c, b, e); + fmpq_pow_si(b, b, e); + + result = fmpq_equal(b, c); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpq_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpq_print(b), flint_printf("\n\n"); + flint_printf("c = "), fmpq_print(c), flint_printf("\n\n"); + flint_printf("e = %wd\n", e); + abort(); + } + + fmpq_clear(a); + fmpq_clear(b); + fmpq_clear(c); + } + + /* Compare with repeated multiplication */ + for (i = 0; i < 10000; i++) + { + fmpq_t a, b, c; + slong j, e; + + fmpq_init(a); + fmpq_init(b); + fmpq_init(c); + + fmpq_randtest(a, state, 50); + + e = z_randint(state, 20); + + fmpq_pow_si(b, a, e); + + fmpq_one(c); + for (j = 0; j < FLINT_ABS(e); j++) + fmpq_mul(c, c, a); + if (e < 0) + fmpq_inv(c, c); + + result = fmpq_equal(b, c); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpq_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpq_print(b), flint_printf("\n\n"); + flint_printf("c = "), fmpq_print(c), flint_printf("\n\n"); + flint_printf("e = %wd\n", e); + abort(); + } + + fmpq_clear(a); + fmpq_clear(b); + fmpq_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq/test/t-reconstruct_fmpz.c b/external/flint-2.4.3/fmpq/test/t-reconstruct_fmpz.c new file mode 100644 index 0000000..1ad224b --- /dev/null +++ b/external/flint-2.4.3/fmpq/test/t-reconstruct_fmpz.c @@ -0,0 +1,121 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq.h" +#include "profiler.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("reconstruct_fmpz...."); + fflush(stdout); + + for (i = 0; i < 10000; i++) + { + int result; + int modresult; + int special_case; + fmpq_t x, y; + fmpz_t mod; + fmpz_t res; + mpz_t tmp; + + fmpq_init(x); + fmpq_init(y); + fmpz_init(mod); + fmpz_init(res); + mpz_init(tmp); + + fmpq_randtest(x, state, 100); + + /* Modulus m >= 2*max(|n|,d)^2 */ + if (fmpz_cmpabs(&x->num, &x->den) >= 0) + fmpz_mul(mod, &x->num, &x->num); + else + fmpz_mul(mod, &x->den, &x->den); + fmpz_mul_2exp(mod, mod, 1); + + /* Next prime greater than or equal */ + fmpz_get_mpz(tmp, mod); + flint_mpz_sub_ui(tmp, tmp, UWORD(1)); + mpz_nextprime(tmp, tmp); + fmpz_set_mpz(mod, tmp); + + modresult = fmpq_mod_fmpz(res, x, mod); + result = fmpq_reconstruct_fmpz(y, res, mod); + + /* Special case: both 1 and -1 have residue 1 mod 2. + There's probably no particular reason to disallow this. */ + special_case = (fmpz_cmp_ui(mod, UWORD(2)) == 0 && + fmpz_get_si(&x->num) == WORD(-1) && + fmpz_cmp_ui(&x->den, UWORD(1)) == 0); + if (special_case) + { + if (!modresult || !result || + !fmpz_is_one(&y->num) || !fmpz_is_one(&y->den)) + { + flint_printf("FAIL: special case: -1 mod 2\n"); + abort(); + } + } + else if (!modresult || !result || !fmpq_equal(x, y)) + { + flint_printf("FAIL: reconstruction failed\n"); + flint_printf("input = "); + fmpq_print(x); + flint_printf("\nmodulus = "); + fmpz_print(mod); + flint_printf("\nresidue = "); + fmpz_print(res); + flint_printf("\nreconstructed = "); + fmpq_print(y); + flint_printf("\nfmpq_mod_fmpz return value = %d", modresult); + flint_printf("\nfmpq_reconstruct_fmpz return value = %d", result); + flint_printf("\n"); + abort(); + } + + fmpq_clear(x); + fmpq_clear(y); + fmpz_clear(mod); + fmpz_clear(res); + mpz_clear(tmp); + } + + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq/test/t-reconstruct_fmpz_2.c b/external/flint-2.4.3/fmpq/test/t-reconstruct_fmpz_2.c new file mode 100644 index 0000000..c38bc45 --- /dev/null +++ b/external/flint-2.4.3/fmpq/test/t-reconstruct_fmpz_2.c @@ -0,0 +1,139 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq.h" +#include "profiler.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("reconstruct_fmpz_2...."); + fflush(stdout); + + for (i = 0; i < 10000; i++) + { + int result; + int modresult; + int special_case; + fmpq_t x, y; + fmpz_t mod, res, N, D, t; + mpz_t tmp; + + fmpq_init(x); + fmpq_init(y); + fmpz_init(mod); + fmpz_init(res); + fmpz_init(N); + fmpz_init(D); + fmpz_init(t); + mpz_init(tmp); + + fmpq_randtest(x, state, 100); + + fmpz_abs(N, fmpq_numref(x)); + fmpz_set(D, fmpq_denref(x)); + + /* Randomly generate larger bounds */ + if (n_randint(state, 2)) + { + fmpz_randtest_not_zero(t, state, 100); + fmpz_abs(t, t); + fmpz_mul(N, N, t); + } + if (n_randint(state, 2)) + { + fmpz_randtest_not_zero(t, state, 100); + fmpz_abs(t, t); + fmpz_mul(D, D, t); + } + + fmpz_mul(mod, N, D); + fmpz_mul_ui(mod, mod, UWORD(2)); + /* Next prime greater than or equal */ + fmpz_get_mpz(tmp, mod); + flint_mpz_sub_ui(tmp, tmp, UWORD(1)); + mpz_nextprime(tmp, tmp); + fmpz_set_mpz(mod, tmp); + + modresult = fmpq_mod_fmpz(res, x, mod); + result = fmpq_reconstruct_fmpz_2(y, res, mod, N, D); + + /* Special case: both 1 and -1 have residue 1 mod 2. + There's probably no particular reason to disallow this. */ + special_case = (fmpz_cmp_ui(mod, UWORD(2)) == 0 && + fmpz_get_si(&x->num) == WORD(-1) && + fmpz_cmp_ui(&x->den, UWORD(1)) == 0); + + if (special_case) + { + if (!modresult || !result || + !fmpz_is_one(&y->num) || !fmpz_is_one(&y->den)) + { + flint_printf("FAIL: special case: -1 mod 2\n"); + abort(); + } + } + else if (!modresult || !result || !fmpq_equal(x, y)) + { + flint_printf("FAIL: reconstruction failed\n"); + flint_printf("input = "); + fmpq_print(x); + flint_printf("\nmodulus = "); + fmpz_print(mod); + flint_printf("\nresidue = "); + fmpz_print(res); + flint_printf("\nreconstructed = "); + fmpq_print(y); + flint_printf("\nfmpq_mod_fmpz return value = %d", modresult); + flint_printf("\nfmpq_reconstruct_fmpz return value = %d", result); + flint_printf("\n"); + abort(); + } + + fmpq_clear(x); + fmpq_clear(y); + fmpz_clear(mod); + fmpz_clear(res); + fmpz_clear(N); + fmpz_clear(D); + fmpz_clear(t); + mpz_clear(tmp); + } + + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq/test/t-set_cfrac.c b/external/flint-2.4.3/fmpq/test/t-set_cfrac.c new file mode 100644 index 0000000..4bb92e2 --- /dev/null +++ b/external/flint-2.4.3/fmpq/test/t-set_cfrac.c @@ -0,0 +1,83 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("set_cfrac...."); + fflush(stdout); + + for (i = 0; i < 10000; i++) + { + fmpq_t x, y, r; + fmpz * c; + slong n, bound; + + fmpq_init(x); + fmpq_init(y); + fmpq_init(r); + + fmpq_randtest(x, state, 1 + n_randint(state, 1000)); + bound = fmpq_cfrac_bound(x); + + c = _fmpz_vec_init(bound); + + n = fmpq_get_cfrac(c, r, x, bound); + fmpq_set_cfrac(y, c, n); + + if (!fmpq_equal(x, y)) + { + flint_printf("FAIL: x != y\n"); + flint_printf("x = "); fmpq_print(x); flint_printf("\n"); + flint_printf("y = "); fmpq_print(y); flint_printf("\n"); + flint_printf("c = "); _fmpz_vec_print(c, n); flint_printf("\n\n"); + abort(); + } + + _fmpz_vec_clear(c, bound); + fmpq_clear(x); + fmpq_clear(y); + fmpq_clear(r); + } + + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq/test/t-set_fmpz_frac.c b/external/flint-2.4.3/fmpq/test/t-set_fmpz_frac.c new file mode 100644 index 0000000..37101ce --- /dev/null +++ b/external/flint-2.4.3/fmpq/test/t-set_fmpz_frac.c @@ -0,0 +1,85 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("set_fmpz_frac...."); + fflush(stdout); + + for (i = 0; i < 10000; i++) + { + fmpq_t x, y; + fmpz_t p, q; + + fmpq_init(x); + fmpq_init(y); + fmpz_init(p); + fmpz_init(q); + + fmpz_randtest(p, state, 100); + fmpz_randtest_not_zero(q, state, 100); + + fmpq_set_fmpz_frac(x, p, q); + + fmpz_set(fmpq_numref(y), p); + fmpz_set(fmpq_denref(y), q); + fmpq_canonicalise(y); + + if (!fmpq_is_canonical(x) || !fmpq_equal(x, y)) + { + flint_printf("FAIL"); + flint_printf("p: "); fmpz_print(p); flint_printf("\n"); + flint_printf("q: "); fmpz_print(q); flint_printf("\n"); + flint_printf("x: "); fmpq_print(x); flint_printf("\n"); + flint_printf("y: "); fmpq_print(y); flint_printf("\n"); + abort(); + } + + fmpq_clear(x); + fmpq_clear(y); + fmpz_clear(p); + fmpz_clear(q); + } + + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq/test/t-set_si.c b/external/flint-2.4.3/fmpq/test/t-set_si.c new file mode 100644 index 0000000..b8de636 --- /dev/null +++ b/external/flint-2.4.3/fmpq/test/t-set_si.c @@ -0,0 +1,87 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("set_si...."); + fflush(stdout); + + for (i = 0; i < 10000; i++) + { + fmpq_t x, y; + fmpz_t p, q; + slong P, Q; + + fmpq_init(x); + fmpq_init(y); + fmpz_init(p); + fmpz_init(q); + + P = z_randtest(state); + Q = n_randtest_not_zero(state); + + fmpz_set_si(p, P); + fmpz_set_ui(q, Q); + + fmpq_set_fmpz_frac(x, p, q); + fmpq_set_si(y, P, Q); + + if (!fmpq_is_canonical(y) || !fmpq_equal(x, y)) + { + flint_printf("FAIL"); + flint_printf("p: "); fmpz_print(p); flint_printf("\n"); + flint_printf("q: "); fmpz_print(q); flint_printf("\n"); + flint_printf("x: "); fmpq_print(x); flint_printf("\n"); + flint_printf("y: "); fmpq_print(y); flint_printf("\n"); + abort(); + } + + fmpq_clear(x); + fmpq_clear(y); + fmpz_clear(p); + fmpz_clear(q); + } + + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq/test/t-sub.c b/external/flint-2.4.3/fmpq/test/t-sub.c new file mode 100644 index 0000000..98456f0 --- /dev/null +++ b/external/flint-2.4.3/fmpq/test/t-sub.c @@ -0,0 +1,194 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("sub...."); + fflush(stdout); + + /* x = y - z */ + for (i = 0; i < 10000; i++) + { + fmpq_t x, y, z; + mpq_t X, Y, Z; + + fmpq_init(x); + fmpq_init(y); + fmpq_init(z); + mpq_init(X); + mpq_init(Y); + mpq_init(Z); + + fmpq_randtest(x, state, 200); + fmpq_randtest(y, state, 200); + fmpq_randtest(z, state, 200); + + fmpq_get_mpq(X, x); + fmpq_get_mpq(Y, y); + fmpq_get_mpq(Z, z); + + fmpq_sub(x, y, z); + + if (!fmpq_is_canonical(x)) + { + flint_printf("FAIL: result not canonical!\n"); + abort(); + } + + mpq_sub(X, Y, Z); + fmpq_get_mpq(Y, x); + + if (!mpq_equal(X, Y)) + { + flint_printf("FAIL: fmpq_sub(x,y,z) != mpq_sub(X,Y,Z)\n"); + flint_printf("x = "); + fmpq_print(x); + flint_printf("\ny = "); + fmpq_print(y); + flint_printf("\nz = "); + fmpq_print(z); + flint_printf("\n"); + abort(); + } + + fmpq_clear(x); + fmpq_clear(y); + fmpq_clear(z); + + mpq_clear(X); + mpq_clear(Y); + mpq_clear(Z); + } + + /* x = x - y */ + for (i = 0; i < 10000; i++) + { + fmpq_t x, y; + mpq_t X, Y; + + fmpq_init(x); + fmpq_init(y); + mpq_init(X); + mpq_init(Y); + + fmpq_randtest(x, state, 200); + fmpq_randtest(y, state, 200); + + fmpq_get_mpq(X, x); + fmpq_get_mpq(Y, y); + + fmpq_sub(x, x, y); + + if (!fmpq_is_canonical(x)) + { + flint_printf("FAIL: result not canonical!\n"); + abort(); + } + + mpq_sub(X, X, Y); + fmpq_get_mpq(Y, x); + + if (!mpq_equal(X, Y)) + { + flint_printf("FAIL: fmpq_sub(x,x,y) != mpq_sub(X,X,Y)\n"); + flint_printf("x = "); + fmpq_print(x); + flint_printf("\ny = "); + fmpq_print(y); + flint_printf("\n"); + abort(); + } + + fmpq_clear(x); + fmpq_clear(y); + + mpq_clear(X); + mpq_clear(Y); + } + + /* x = y - x */ + for (i = 0; i < 10000; i++) + { + fmpq_t x, y; + mpq_t X, Y; + + fmpq_init(x); + fmpq_init(y); + mpq_init(X); + mpq_init(Y); + + fmpq_randtest(x, state, 200); + fmpq_randtest(y, state, 200); + + fmpq_get_mpq(X, x); + fmpq_get_mpq(Y, y); + + fmpq_sub(x, y, x); + + if (!fmpq_is_canonical(x)) + { + flint_printf("FAIL: result not canonical!\n"); + abort(); + } + + mpq_sub(X, Y, X); + fmpq_get_mpq(Y, x); + + if (!mpq_equal(X, Y)) + { + flint_printf("FAIL: fmpq_sub(x,y,x) != mpq_sub(X,Y,X)\n"); + flint_printf("x = "); + fmpq_print(x); + flint_printf("\ny = "); + fmpq_print(y); + flint_printf("\n"); + abort(); + } + + fmpq_clear(x); + fmpq_clear(y); + + mpq_clear(X); + mpq_clear(Y); + } + + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq/test/t-submul.c b/external/flint-2.4.3/fmpq/test/t-submul.c new file mode 100644 index 0000000..6dab444 --- /dev/null +++ b/external/flint-2.4.3/fmpq/test/t-submul.c @@ -0,0 +1,203 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq.h" + +void mpq_submul(mpq_t x, mpq_t y, mpq_t z) +{ + mpq_t t; + mpq_init(t); + mpq_mul(t, y, z); + mpq_sub(x, x, t); + mpq_clear(t); +} + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("submul...."); + fflush(stdout); + + /* x -= y * z */ + for (i = 0; i < 10000; i++) + { + fmpq_t x, y, z; + mpq_t X, Y, Z; + + fmpq_init(x); + fmpq_init(y); + fmpq_init(z); + mpq_init(X); + mpq_init(Y); + mpq_init(Z); + + fmpq_randtest(x, state, 200); + fmpq_randtest(y, state, 200); + fmpq_randtest(z, state, 200); + + fmpq_get_mpq(X, x); + fmpq_get_mpq(Y, y); + fmpq_get_mpq(Z, z); + + fmpq_submul(x, y, z); + + if (!fmpq_is_canonical(x)) + { + flint_printf("FAIL: result not canonical!\n"); + abort(); + } + + mpq_submul(X, Y, Z); + fmpq_get_mpq(Y, x); + + if (!mpq_equal(X, Y)) + { + flint_printf("FAIL: fmpq_submul(x,y,z) != mpq_submul(X,Y,Z)\n"); + flint_printf("x = "); + fmpq_print(x); + flint_printf("\ny = "); + fmpq_print(y); + flint_printf("\nz = "); + fmpq_print(z); + flint_printf("\n"); + abort(); + } + + fmpq_clear(x); + fmpq_clear(y); + fmpq_clear(z); + + mpq_clear(X); + mpq_clear(Y); + mpq_clear(Z); + } + + /* x -= x * y */ + for (i = 0; i < 10000; i++) + { + fmpq_t x, y; + mpq_t X, Y; + + fmpq_init(x); + fmpq_init(y); + mpq_init(X); + mpq_init(Y); + + fmpq_randtest(x, state, 200); + fmpq_randtest(y, state, 200); + + fmpq_get_mpq(X, x); + fmpq_get_mpq(Y, y); + + fmpq_submul(x, x, y); + + if (!fmpq_is_canonical(x)) + { + flint_printf("FAIL: result not canonical!\n"); + abort(); + } + + mpq_submul(X, X, Y); + fmpq_get_mpq(Y, x); + + if (!mpq_equal(X, Y)) + { + flint_printf("FAIL: fmpq_submul(x,x,y) != mpq_submul(X,X,Y)\n"); + flint_printf("x = "); + fmpq_print(x); + flint_printf("\ny = "); + fmpq_print(y); + flint_printf("\n"); + abort(); + } + + fmpq_clear(x); + fmpq_clear(y); + + mpq_clear(X); + mpq_clear(Y); + } + + /* x -= y * x */ + for (i = 0; i < 10000; i++) + { + fmpq_t x, y; + mpq_t X, Y; + + fmpq_init(x); + fmpq_init(y); + mpq_init(X); + mpq_init(Y); + + fmpq_randtest(x, state, 200); + fmpq_randtest(y, state, 200); + + fmpq_get_mpq(X, x); + fmpq_get_mpq(Y, y); + + fmpq_submul(x, y, x); + + if (!fmpq_is_canonical(x)) + { + flint_printf("FAIL: result not canonical!\n"); + abort(); + } + + mpq_submul(X, Y, X); + fmpq_get_mpq(Y, x); + + if (!mpq_equal(X, Y)) + { + flint_printf("FAIL: fmpq_submul(x,y,x) != mpq_submul(X,Y,X)\n"); + flint_printf("x = "); + fmpq_print(x); + flint_printf("\ny = "); + fmpq_print(y); + flint_printf("\n"); + abort(); + } + + fmpq_clear(x); + fmpq_clear(y); + + mpq_clear(X); + mpq_clear(Y); + } + + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_mat.h b/external/flint-2.4.3/fmpq_mat.h new file mode 100644 index 0000000..42c9cc6 --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat.h @@ -0,0 +1,193 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#ifndef FMPQ_MAT_H +#define FMPQ_MAT_H + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mat.h" +#include "fmpq.h" + +#ifdef __cplusplus + extern "C" { +#endif + +typedef struct +{ + fmpq * entries; + slong r; + slong c; + fmpq ** rows; +} fmpq_mat_struct; + +typedef fmpq_mat_struct fmpq_mat_t[1]; + +#define fmpq_mat_entry(mat,i,j) ((mat)->rows[(i)] + (j)) +#define fmpq_mat_entry_num(mat,i,j) ((fmpz *)(&((*fmpq_mat_entry(mat,i,j)).num))) +#define fmpq_mat_entry_den(mat,i,j) ((fmpz *)(&((*fmpq_mat_entry(mat,i,j)).den))) + +#define fmpq_mat_nrows(mat) ((mat)->r) +#define fmpq_mat_ncols(mat) ((mat)->c) + +void fmpq_mat_init(fmpq_mat_t mat, slong rows, slong cols); + +void fmpq_mat_clear(fmpq_mat_t mat); + + +void fmpq_mat_print(const fmpq_mat_t mat); + +/* Random matrix generation **************************************************/ + +void fmpq_mat_randbits(fmpq_mat_t mat, flint_rand_t state, mp_bitcnt_t bits); + +void fmpq_mat_randtest(fmpq_mat_t mat, flint_rand_t state, mp_bitcnt_t bits); + +/* Special matrices **********************************************************/ + +void fmpq_mat_hilbert_matrix(fmpq_mat_t mat); + +/* Basic assignment **********************************************************/ + +void fmpq_mat_set(fmpq_mat_t dest, const fmpq_mat_t src); + +void fmpq_mat_zero(fmpq_mat_t mat); + +void fmpq_mat_one(fmpq_mat_t mat); + +void fmpq_mat_transpose(fmpq_mat_t rop, const fmpq_mat_t op); + +/* Addition, scalar multiplication ******************************************/ + +void fmpq_mat_add(fmpq_mat_t mat, const fmpq_mat_t mat1, const fmpq_mat_t mat2); + +void fmpq_mat_sub(fmpq_mat_t mat, const fmpq_mat_t mat1, const fmpq_mat_t mat2); + +void fmpq_mat_neg(fmpq_mat_t rop, const fmpq_mat_t op); + +void fmpq_mat_scalar_mul_fmpz(fmpq_mat_t rop, const fmpq_mat_t op, const fmpz_t x); + +void fmpq_mat_scalar_div_fmpz(fmpq_mat_t rop, const fmpq_mat_t op, const fmpz_t x); + +/* Basic comparison and properties *******************************************/ + +int fmpq_mat_equal(const fmpq_mat_t mat1, const fmpq_mat_t mat2); + +int fmpq_mat_is_integral(const fmpq_mat_t mat); + +int fmpq_mat_is_zero(const fmpq_mat_t mat); + +static __inline__ int +fmpq_mat_is_empty(const fmpq_mat_t mat) +{ + return (mat->r == 0) || (mat->c == 0); +} + +static __inline__ int +fmpq_mat_is_square(const fmpq_mat_t mat) +{ + return (mat->r == mat->c); +} + +/* Integer matrix conversion *************************************************/ + +int fmpq_mat_get_fmpz_mat(fmpz_mat_t dest, const fmpq_mat_t mat); + +void fmpq_mat_get_fmpz_mat_entrywise(fmpz_mat_t num, fmpz_mat_t den, + const fmpq_mat_t mat); + +void fmpq_mat_get_fmpz_mat_matwise(fmpz_mat_t num, fmpz_t den, + const fmpq_mat_t mat); + +void fmpq_mat_get_fmpz_mat_rowwise(fmpz_mat_t num, fmpz * den, + const fmpq_mat_t mat); + +void fmpq_mat_get_fmpz_mat_colwise(fmpz_mat_t num, fmpz * den, + const fmpq_mat_t mat); + +void fmpq_mat_get_fmpz_mat_rowwise_2(fmpz_mat_t num, fmpz_mat_t num2, + fmpz * den, const fmpq_mat_t mat, const fmpq_mat_t mat2); + +void fmpq_mat_get_fmpz_mat_mod_fmpz(fmpz_mat_t dest, const fmpq_mat_t mat, + const fmpz_t mod); + +void fmpq_mat_set_fmpz_mat(fmpq_mat_t dest, const fmpz_mat_t src); + +void fmpq_mat_set_fmpz_mat_div_fmpz(fmpq_mat_t X, const fmpz_mat_t Xmod, + const fmpz_t div); + +int fmpq_mat_set_fmpz_mat_mod_fmpz(fmpq_mat_t X, const fmpz_mat_t Xmod, + const fmpz_t mod); + +/* Matrix multiplication *****************************************************/ + +void fmpq_mat_mul_direct(fmpq_mat_t C, const fmpq_mat_t A, const fmpq_mat_t B); + +void fmpq_mat_mul_cleared(fmpq_mat_t C, const fmpq_mat_t A, + const fmpq_mat_t B); + +void fmpq_mat_mul(fmpq_mat_t C, const fmpq_mat_t A, const fmpq_mat_t B); + +void fmpq_mat_mul_fmpz_mat(fmpq_mat_t C, const fmpq_mat_t A, + const fmpz_mat_t B); + +void fmpq_mat_mul_r_fmpz_mat(fmpq_mat_t C, const fmpz_mat_t A, + const fmpq_mat_t B); + +/* Trace *********************************************************************/ + +void fmpq_mat_trace(fmpq_t trace, const fmpq_mat_t mat); + +/* Determinant ***************************************************************/ + +void fmpq_mat_det(fmpq_t det, const fmpq_mat_t mat); + +/* Nonsingular solving *******************************************************/ + +int fmpq_mat_solve_fraction_free(fmpq_mat_t X, const fmpq_mat_t A, + const fmpq_mat_t B); + +int fmpq_mat_solve_dixon(fmpq_mat_t X, const fmpq_mat_t A, const fmpq_mat_t B); + +/* Inverse *******************************************************************/ + +int fmpq_mat_inv(fmpq_mat_t B, const fmpq_mat_t A); + +/* Echelon form **************************************************************/ + +int fmpq_mat_pivot(slong * perm, fmpq_mat_t mat, slong r, slong c); + +slong fmpq_mat_rref_classical(fmpq_mat_t B, const fmpq_mat_t A); + +slong fmpq_mat_rref_fraction_free(fmpq_mat_t B, const fmpq_mat_t A); + +slong fmpq_mat_rref(fmpq_mat_t B, const fmpq_mat_t A); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/flint-2.4.3/fmpq_mat/add.c b/external/flint-2.4.3/fmpq_mat/add.c new file mode 100644 index 0000000..659af95 --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/add.c @@ -0,0 +1,37 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpq_mat.h" + +void fmpq_mat_add(fmpq_mat_t mat, const fmpq_mat_t mat1, const fmpq_mat_t mat2) +{ + slong i, j; + + for (i = 0; i < mat->r; i++) + for (j = 0; j < mat->c; j++) + fmpq_add(fmpq_mat_entry(mat, i, j), + fmpq_mat_entry(mat1, i, j), fmpq_mat_entry(mat2, i, j)); +} + diff --git a/external/flint-2.4.3/fmpq_mat/clear.c b/external/flint-2.4.3/fmpq_mat/clear.c new file mode 100644 index 0000000..34280f7 --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/clear.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq_mat.h" + +void fmpq_mat_clear(fmpq_mat_t mat) +{ + if (mat->entries) + { + slong i; + + for (i = 0; i < mat->r * mat->c; i++) + fmpq_clear(mat->entries + i); + + flint_free(mat->entries); + flint_free(mat->rows); + } +} diff --git a/external/flint-2.4.3/fmpq_mat/det.c b/external/flint-2.4.3/fmpq_mat/det.c new file mode 100644 index 0000000..7c72efa --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/det.c @@ -0,0 +1,73 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq_mat.h" + +void fmpq_mat_det(fmpq_t det, const fmpq_mat_t mat) +{ + slong n = mat->r; + + if (n == 0) + { + fmpq_set_si(det, WORD(1), WORD(1)); + return; + } + else if (n == 1) + { + fmpq_set(det, fmpq_mat_entry(mat, 0, 0)); + } + else if (n == 2) + { + fmpq_t t; + fmpq_init(t); + + fmpq_mul(t, fmpq_mat_entry(mat, 0, 0), fmpq_mat_entry(mat, 1, 1)); + fmpq_submul(t, fmpq_mat_entry(mat, 0, 1), fmpq_mat_entry(mat, 1, 0)); + + fmpq_set(det, t); + fmpq_clear(t); + } + else + { + fmpz_mat_t num; + fmpz * den; + slong i; + + fmpz_mat_init(num, mat->r, mat->c); + den = _fmpz_vec_init(mat->r); + + fmpq_mat_get_fmpz_mat_rowwise(num, den, mat); + fmpz_mat_det(&det->num, num); + + fmpz_one(&det->den); + for (i = 0; i < mat->r; i++) + fmpz_mul(&det->den, &det->den, den + i); + + fmpq_canonicalise(det); + + fmpz_mat_clear(num); + _fmpz_vec_clear(den, mat->r); + } +} diff --git a/external/flint-2.4.3/fmpq_mat/doc/fmpq_mat.txt b/external/flint-2.4.3/fmpq_mat/doc/fmpq_mat.txt new file mode 100644 index 0000000..c4fcf1b --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/doc/fmpq_mat.txt @@ -0,0 +1,428 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + + +******************************************************************************* + + Memory management + +******************************************************************************* + +void fmpq_mat_init(fmpq_mat_t mat, slong rows, slong cols) + + Initialises a matrix with the given number of rows and columns for use. + +void fmpq_mat_clear(fmpq_mat_t mat) + + Frees all memory associated with the matrix. The matrix must be + reinitialised if it is to be used again. + +******************************************************************************* + + Entry access + +******************************************************************************* + +MACRO fmpq_mat_entry(mat,i,j) + + Gives a reference to the entry at row \code{i} and column \code{j}. + The reference can be passed as an input or output variable to any + \code{fmpq} function for direct manipulation of the matrix element. + No bounds checking is performed. + +MACRO fmpq_mat_entry_num(mat,i,j) + + Gives a reference to the numerator of the entry at row \code{i} and + column \code{j}. The reference can be passed as an input or output + variable to any \code{fmpz} function for direct manipulation of the + matrix element. No bounds checking is performed. + +MACRO fmpq_mat_entry_den(mat,i,j) + + Gives a reference to the denominator of the entry at row \code{i} and + column \code{j}. The reference can be passed as an input or output + variable to any \code{fmpz} function for direct manipulation of the + matrix element. No bounds checking is performed. + +******************************************************************************* + + Basic assignment + +******************************************************************************* + +void fmpq_mat_set(fmpq_mat_t dest, const fmpq_mat_t src) + + Sets the entries in \code{dest} to the same values as in \code{src}, + assuming the two matrices have the same dimensions. + +void fmpq_mat_zero(fmpq_mat_t mat) + + Sets \code{mat} to the zero matrix. + +void fmpq_mat_one(fmpq_mat_t mat) + + Let $m$ be the minimum of the number of rows and columns + in the matrix \code{mat}. This function sets the first + $m \times m$ block to the identity matrix, and the remaining + block to zero. + +void fmpq_mat_transpose(fmpq_mat_t rop, const fmpq_mat_t op) + + Sets the matrix \code{rop} to the tranpose of the matrix \code{op}, + assuming that their dimensios are compatible. + +******************************************************************************* + + Addition, scalar multiplication + +******************************************************************************* + +void fmpq_mat_add(fmpq_mat_t mat, + const fmpq_mat_t mat1, const fmpq_mat_t mat2) + + Sets \code{mat} to the sum of \code{mat1} and \code{mat2}, + assuming that all three matrices have the same dimensions. + +void fmpq_mat_sub(fmpq_mat_t mat, + const fmpq_mat_t mat1, const fmpq_mat_t mat2) + + Sets \code{mat} to the difference of \code{mat1} and \code{mat2}, + assuming that all three matrices have the same dimensions. + +void fmpq_mat_neg(fmpq_mat_t rop, const fmpq_mat_t op) + + Sets \code{rop} to the negative of \code{op}, assuming that + the two matrices have the same dimensions. + +void fmpq_mat_scalar_mul_fmpz(fmpq_mat_t rop, + const fmpq_mat_t op, const fmpz_t x) + + Sets \code{rop} to \code{op} multiplied by the integer $x$, + assuming that the two matrices have the same dimensions. + + Note that the integer $x$ may not be aliased with any part of + the entries of \code{rop}. + +void fmpq_mat_scalar_div_fmpz(fmpq_mat_t rop, + const fmpq_mat_t op, const fmpz_t x) + + Sets \code{rop} to \code{op} divided by the integer $x$, + assuming that the two matrices have the same dimensions + and that $x$ is non-zero. + + Note that the integer $x$ may not be aliased with any part of + the entries of \code{rop}. + +******************************************************************************* + + Input and output + +******************************************************************************* + +void fmpq_mat_print(const fmpq_mat_t mat) + + Prints the matrix \code{mat} to standard output. + +******************************************************************************* + + Random matrix generation + +******************************************************************************* + +void fmpq_mat_randbits(fmpq_mat_t mat, flint_rand_t state, mp_bitcnt_t bits) + + This is equivalent to applying \code{fmpq_randbits} to all entries + in the matrix. + +void fmpq_mat_randtest(fmpq_mat_t mat, flint_rand_t state, mp_bitcnt_t bits) + + This is equivalent to applying \code{fmpq_randtest} to all entries + in the matrix. + +******************************************************************************* + + Special matrices + +******************************************************************************* + +void fmpq_mat_hilbert_matrix(fmpq_mat_t mat) + + Sets \code{mat} to a Hilbert matrix of the given size. That is, + the entry at row $i$ and column $j$ is set to $1/(i+j+1)$. + +******************************************************************************* + + Basic comparison and properties + +******************************************************************************* + +int fmpq_mat_equal(const fmpq_mat_t mat1, const fmpq_mat_t mat2) + + Returns nonzero if \code{mat1} and \code{mat2} have the same shape and + all their entries agree, and returns zero otherwise. Assumes the + entries in both \code{mat1} and \code{mat2} are in canonical form. + +int fmpq_mat_is_integral(const fmpq_mat_t mat) + + Returns nonzero if all entries in \code{mat} are integer-valued, and + returns zero otherwise. Assumes that the entries in \code{mat} + are in canonical form. + +int fmpq_mat_is_zero(const fmpq_mat_t mat) + + Returns nonzero if all entries in \code{mat} are zero, and returns + zero otherwise. + +int fmpq_mat_is_empty(const fmpq_mat_t mat) + + Returns a non-zero value if the number of rows or the number of + columns in \code{mat} is zero, and otherwise returns + zero. + +int fmpq_mat_is_square(const fmpq_mat_t mat) + + Returns a non-zero value if the number of rows is equal to the + number of columns in \code{mat}, and otherwise returns zero. + + +******************************************************************************* + + Integer matrix conversion + +******************************************************************************* + +int fmpq_mat_get_fmpz_mat(fmpz_mat_t dest, const fmpq_mat_t mat) + + Sets \code{dest} to \code{mat} and returns nonzero if all entries + in \code{mat} are integer-valued. If not all entries in \code{mat} + are integer-valued, sets \code{dest} to an undefined matrix + and returns zero. Assumes that the entries in \code{mat} are + in canonical form. + +void fmpq_mat_get_fmpz_mat_entrywise(fmpz_mat_t num, fmpz_mat_t den, + const fmpq_mat_t mat) + + Sets the integer matrices \code{num} and \code{den} respectively + to the numerators and denominators of the entries in \code{mat}. + +void fmpq_mat_get_fmpz_mat_matwise(fmpz_mat_t num, fmpz_t den, + const fmpq_mat_t mat) + + Converts all entries in \code{mat} to a common denominator, + storing the rescaled numerators in \code{num} and the + denominator in \code{den}. The denominator will be minimal + if the entries in \code{mat} are in canonical form. + +void fmpq_mat_get_fmpz_mat_rowwise(fmpz_mat_t num, fmpz * den, + const fmpq_mat_t mat) + + Clears denominators in \code{mat} row by row. The rescaled + numerators are written to \code{num}, and the denominator + of row \code{i} is written to position \code{i} in \code{den} + which can be a preinitialised \code{fmpz} vector. Alternatively, + \code{NULL} can be passed as the \code{den} variable, in which + case the denominators will not be stored. + +void fmpq_mat_get_fmpz_mat_rowwise_2(fmpz_mat_t num, fmpz_mat_t num2, + fmpz * den, const fmpq_mat_t mat, const fmpq_mat_t mat2) + + Clears denominators row by row of both \code{mat} and \code{mat2}, + writing the respective numerators to \code{num} and \code{num2}. + This is equivalent to concatenating \code{mat} and \code{mat2} + horizontally, calling \code{fmpq_mat_get_fmpz_mat_rowwise}, + and extracting the two submatrices in the result. + +void fmpq_mat_get_fmpz_mat_colwise(fmpz_mat_t num, fmpz * den, + const fmpq_mat_t mat) + + Clears denominators in \code{mat} column by column. The rescaled + numerators are written to \code{num}, and the denominator + of column \code{i} is written to position \code{i} in \code{den} + which can be a preinitialised \code{fmpz} vector. Alternatively, + \code{NULL} can be passed as the \code{den} variable, in which + case the denominators will not be stored. + +void fmpq_mat_set_fmpz_mat(fmpq_mat_t dest, const fmpz_mat_t src) + + Sets \code{dest} to \code{src}. + +void fmpq_mat_set_fmpz_mat_div_fmpz(fmpq_mat_t mat, const fmpz_mat_t num, + const fmpz_t den) + + Sets \code{mat} to the integer matrix \code{num} divided by the + common denominator \code{den}. + +******************************************************************************* + + Modular reduction and rational reconstruction + +******************************************************************************* + +void fmpq_mat_get_fmpz_mat_mod_fmpz(fmpz_mat_t dest, const fmpq_mat_t mat, + const fmpz_t mod) + + Sets each entry in \code{dest} to the corresponding entry in \code{mat}, + reduced modulo \code{mod}. + +int fmpq_mat_set_fmpz_mat_mod_fmpz(fmpq_mat_t X, const fmpz_mat_t Xmod, + const fmpz_t mod) + + Set \code{X} to the entrywise rational reconstruction integer matrix + \code{Xmod} modulo \code{mod}, and returns nonzero if the reconstruction + is successful. If rational reconstruction fails for any element, + returns zero and sets the entries in \code{X} to undefined values. + +******************************************************************************* + + Matrix multiplication + +******************************************************************************* + +void fmpq_mat_mul_direct(fmpq_mat_t C, const fmpq_mat_t A, const fmpq_mat_t B) + + Sets \code{C} to the matrix product \code{AB}, computed + naively using rational arithmetic. This is typically very slow and + should only be used in circumstances where clearing denominators + would consume too much memory. + +void fmpq_mat_mul_cleared(fmpq_mat_t C, const fmpq_mat_t A, + const fmpq_mat_t B) + + Sets \code{C} to the matrix product \code{AB}, computed + by clearing denominators and multiplying over the integers. + +void fmpq_mat_mul(fmpq_mat_t C, const fmpq_mat_t A, const fmpq_mat_t B) + + Sets \code{C} to the matrix product \code{AB}. This + simply calls \code{fmpq_mat_mul_cleared}. + +void fmpq_mat_mul_fmpz_mat(fmpq_mat_t C, const fmpq_mat_t A, + const fmpz_mat_t B) + + Sets \code{C} to the matrix product \code{AB}, with \code{B} + an integer matrix. This function works efficiently by clearing + denominators of \code{A}. + +void fmpq_mat_mul_r_fmpz_mat(fmpq_mat_t C, const fmpz_mat_t A, + const fmpq_mat_t B) + + Sets \code{C} to the matrix product \code{AB}, with \code{A} + an integer matrix. This function works efficiently by clearing + denominators of \code{B}. + +******************************************************************************* + + Trace + +******************************************************************************* + +void fmpq_mat_trace(fmpq_t trace, const fmpq_mat_t mat) + + Computes the trace of the matrix, i.e. the sum of the entries on + the main diagonal. The matrix is required to be square. + +******************************************************************************* + + Determinant + +******************************************************************************* + +void fmpq_mat_det(fmpq_t det, const fmpq_mat_t mat) + + Sets \code{det} to the determinant of \code{mat}. In the general case, + the determinant is computed by clearing denominators and computing a + determinant over the integers. Matrices of size 0, 1 or 2 are handled + directly. + +******************************************************************************* + + Nonsingular solving + +******************************************************************************* + +int fmpq_mat_solve_fraction_free(fmpq_mat_t X, const fmpq_mat_t A, + const fmpq_mat_t B) + + Solves \code{AX = B} for nonsingular \code{A} by clearing denominators + and solving the rescaled system over the integers using a fraction-free + algorithm. This is usually the fastest algorithm for small systems. + Returns nonzero if \code{X} is nonsingular or if the right hand side + is empty, and zero otherwise. + +int fmpq_mat_solve_dixon(fmpq_mat_t X, const fmpq_mat_t A, const fmpq_mat_t B) + + Solves \code{AX = B} for nonsingular \code{A} by clearing denominators + and solving the rescaled system over the integers using Dixon's algorithm. + The rational solution matrix is generated using rational reconstruction. + This is usually the fastest algorithm for large systems. + Returns nonzero if \code{X} is nonsingular or if the right hand side + is empty, and zero otherwise. + +******************************************************************************* + + Inverse + +******************************************************************************* + +int fmpq_mat_inv(fmpq_mat_t B, const fmpq_mat_t A) + + Sets \code{B} to the inverse matrix of \code{A} and returns nonzero. + Returns zero if \code{A} is singular. \code{A} must be a square matrix. + + +******************************************************************************* + + Echelon form + +******************************************************************************* + +int fmpq_mat_pivot(slong * perm, fmpq_mat_t mat, slong r, slong c) + + Helper function for row reduction. Returns 1 if the entry of \code{mat} + at row $r$ and column $c$ is nonzero. Otherwise searches for a nonzero + entry in the same column among rows $r+1, r+2, \ldots$. If a nonzero + entry is found at row $s$, swaps rows $r$ and $s$ and the corresponding + entries in \code{perm} (unless \code{NULL}) and returns -1. If no + nonzero pivot entry is found, leaves the inputs unchanged and returns 0. + +slong fmpq_mat_rref_classical(fmpq_mat_t B, const fmpq_mat_t A) + + Sets \code{B} to the reduced row echelon form of \code{A} and returns + the rank. Performs Gauss-Jordan elimination directly over the rational + numbers. This algorithm is usually inefficient and is mainly intended + to be used for testing purposes. + +slong fmpq_mat_rref_fraction_free(fmpq_mat_t B, const fmpq_mat_t A) + + Sets \code{B} to the reduced row echelon form of \code{A} and returns + the rank. Clears denominators and performs fraction-free Gauss-Jordan + elimination using \code{fmpz_mat} functions. + +slong fmpq_mat_rref(fmpq_mat_t B, const fmpq_mat_t A) + + Sets \code{B} to the reduced row echelon form of \code{A} and returns + the rank. This function automatically chooses between the classical and + fraction-free algorithms depending on the size of the matrix. + diff --git a/external/flint-2.4.3/fmpq_mat/equal.c b/external/flint-2.4.3/fmpq_mat/equal.c new file mode 100644 index 0000000..bb2b2d0 --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/equal.c @@ -0,0 +1,48 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq_mat.h" + +int +fmpq_mat_equal(const fmpq_mat_t mat1, const fmpq_mat_t mat2) +{ + slong i, j; + + if (mat1->r != mat2->r || mat1->c != mat2->c) + return 0; + + for (i = 0; i < mat1->r; i++) + { + for (j = 0; j < mat1->c; j++) + { + if (!fmpq_equal(fmpq_mat_entry(mat1, i, j), + fmpq_mat_entry(mat2, i, j))) + return 0; + } + } + + return 1; +} + diff --git a/external/flint-2.4.3/fmpq_mat/get_fmpz_mat.c b/external/flint-2.4.3/fmpq_mat/get_fmpz_mat.c new file mode 100644 index 0000000..298f381 --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/get_fmpz_mat.c @@ -0,0 +1,45 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq_mat.h" + +int +fmpq_mat_get_fmpz_mat(fmpz_mat_t dest, const fmpq_mat_t mat) +{ + slong i, j; + + for (i = 0; i < mat->r; i++) + { + for (j = 0; j < mat->c; j++) + { + if (fmpz_is_one(fmpq_mat_entry_den(mat, i, j))) + fmpz_set(fmpz_mat_entry(dest, i, j), + fmpq_mat_entry_num(mat, i, j)); + else + return 0; + } + } + return 1; +} diff --git a/external/flint-2.4.3/fmpq_mat/get_fmpz_mat_colwise.c b/external/flint-2.4.3/fmpq_mat/get_fmpz_mat_colwise.c new file mode 100644 index 0000000..f93928b --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/get_fmpz_mat_colwise.c @@ -0,0 +1,71 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq_mat.h" + +void +fmpq_mat_get_fmpz_mat_colwise(fmpz_mat_t num, fmpz * den, const fmpq_mat_t mat) +{ + fmpz_t t, lcm; + slong i, j; + + if (fmpq_mat_is_empty(mat)) + return; + + fmpz_init(t); + fmpz_init(lcm); + + for (j = 0; j < mat->c; j++) + { + /* Compute common denominator of column */ + fmpz_set(lcm, fmpq_mat_entry_den(mat, 0, j)); + + for (i = 1; i < mat->r; i++) + fmpz_lcm(lcm, lcm, fmpq_mat_entry_den(mat, i, j)); + + if (den != NULL) + fmpz_set(den + j, lcm); + + /* Rescale numerators in column */ + if (fmpz_is_one(lcm)) + { + for (i = 0; i < mat->r; i++) + fmpz_set(fmpz_mat_entry(num, i, j), + fmpq_mat_entry_num(mat, i, j)); + } + else + { + for (i = 0; i < mat->r; i++) + { + fmpz_divexact(t, lcm, fmpq_mat_entry_den(mat, i, j)); + fmpz_mul(fmpz_mat_entry(num, i, j), + fmpq_mat_entry_num(mat, i, j), t); + } + } + } + + fmpz_clear(t); + fmpz_clear(lcm); +} diff --git a/external/flint-2.4.3/fmpq_mat/get_fmpz_mat_entrywise.c b/external/flint-2.4.3/fmpq_mat/get_fmpz_mat_entrywise.c new file mode 100644 index 0000000..46ebd09 --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/get_fmpz_mat_entrywise.c @@ -0,0 +1,42 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq_mat.h" + +void +fmpq_mat_get_fmpz_mat_entrywise(fmpz_mat_t num, fmpz_mat_t den, + const fmpq_mat_t mat) +{ + slong i, j; + + for (i = 0; i < mat->r; i++) + { + for (j = 0; j < mat->c; j++) + { + fmpz_set(fmpz_mat_entry(num, i, j), fmpq_mat_entry_num(mat, i, j)); + fmpz_set(fmpz_mat_entry(den, i, j), fmpq_mat_entry_den(mat, i, j)); + } + } +} diff --git a/external/flint-2.4.3/fmpq_mat/get_fmpz_mat_matwise.c b/external/flint-2.4.3/fmpq_mat/get_fmpz_mat_matwise.c new file mode 100644 index 0000000..ad58a32 --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/get_fmpz_mat_matwise.c @@ -0,0 +1,69 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq_mat.h" + +void +fmpq_mat_get_fmpz_mat_matwise(fmpz_mat_t num, fmpz_t den, const fmpq_mat_t mat) +{ + fmpz_t t, lcm; + slong i, j; + + if (fmpq_mat_is_empty(mat)) + return; + + fmpz_init(t); + fmpz_init(lcm); + fmpz_one(lcm); + + /* Compute common denominator of matrix */ + for (i = 0; i < mat->r; i++) + for (j = 0; j < mat->c; j++) + fmpz_lcm(lcm, lcm, fmpq_mat_entry_den(mat, i, j)); + + fmpz_set(den, lcm); + + for (i = 0; i < mat->r; i++) + { + for (j = 0; j < mat->c; j++) + { + /* Rescale numerators */ + if (fmpz_is_one(lcm)) + { + fmpz_set(fmpz_mat_entry(num, i, j), + fmpq_mat_entry_num(mat, i, j)); + } + else + { + fmpz_divexact(t, lcm, fmpq_mat_entry_den(mat, i, j)); + fmpz_mul(fmpz_mat_entry(num, i, j), + fmpq_mat_entry_num(mat, i, j), t); + } + } + } + + fmpz_clear(t); + fmpz_clear(lcm); +} diff --git a/external/flint-2.4.3/fmpq_mat/get_fmpz_mat_mod_fmpz.c b/external/flint-2.4.3/fmpq_mat/get_fmpz_mat_mod_fmpz.c new file mode 100644 index 0000000..2f3d3eb --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/get_fmpz_mat_mod_fmpz.c @@ -0,0 +1,43 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq_mat.h" + +/* TODO: we may want to clear denominators to avoid expensive invmods */ +void +fmpq_mat_get_fmpz_mat_mod_fmpz(fmpz_mat_t dest, const fmpq_mat_t mat, + const fmpz_t mod) +{ + slong i, j; + + for (i = 0; i < mat->r; i++) + { + for (j = 0; j < mat->c; j++) + { + fmpq_mod_fmpz(fmpz_mat_entry(dest, i, j), + fmpq_mat_entry(mat, i, j), mod); + } + } +} diff --git a/external/flint-2.4.3/fmpq_mat/get_fmpz_mat_rowwise.c b/external/flint-2.4.3/fmpq_mat/get_fmpz_mat_rowwise.c new file mode 100644 index 0000000..618030a --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/get_fmpz_mat_rowwise.c @@ -0,0 +1,97 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq_mat.h" + +void +_fmpq_mat_get_fmpz_mat_rowwise(fmpz_mat_struct ** num, fmpz * den, + const fmpq_mat_struct ** mat, slong n) +{ + fmpz_t t, lcm; + slong i, j, k; + + if (fmpq_mat_is_empty(mat[0])) + return; + + fmpz_init(t); + fmpz_init(lcm); + + for (i = 0; i < mat[0]->r; i++) + { + /* Compute common denominator of row */ + fmpz_set(lcm, fmpq_mat_entry_den(mat[0], i, 0)); + + for (k = 0; k < n; k++) + for (j = (k == 0); j < mat[k]->c; j++) + fmpz_lcm(lcm, lcm, fmpq_mat_entry_den(mat[k], i, j)); + + if (den != NULL) + fmpz_set(den + i, lcm); + + for (k = 0; k < n; k++) + { + /* Rescale numerators in row */ + if (fmpz_is_one(lcm)) + { + for (j = 0; j < mat[k]->c; j++) + fmpz_set(fmpz_mat_entry(num[k], i, j), + fmpq_mat_entry_num(mat[k], i, j)); + } + else + { + for (j = 0; j < mat[k]->c; j++) + { + fmpz_divexact(t, lcm, fmpq_mat_entry_den(mat[k], i, j)); + fmpz_mul(fmpz_mat_entry(num[k], i, j), + fmpq_mat_entry_num(mat[k], i, j), t); + } + } + } + } + + fmpz_clear(t); + fmpz_clear(lcm); +} + +void +fmpq_mat_get_fmpz_mat_rowwise(fmpz_mat_t num, fmpz * den, const fmpq_mat_t mat) +{ + _fmpq_mat_get_fmpz_mat_rowwise(&num, den, &mat, 1); +} + +void +fmpq_mat_get_fmpz_mat_rowwise_2(fmpz_mat_t num, fmpz_mat_t num2, fmpz * den, + const fmpq_mat_t mat, const fmpq_mat_t mat2) +{ + fmpz_mat_struct * nums[2]; + fmpq_mat_struct * mats[2]; + + nums[0] = num; + nums[1] = num2; + mats[0] = (fmpq_mat_struct *) mat; + mats[1] = (fmpq_mat_struct *) mat2; + + _fmpq_mat_get_fmpz_mat_rowwise(nums, den, (const fmpq_mat_struct **) mats, 2); +} diff --git a/external/flint-2.4.3/fmpq_mat/hilbert_matrix.c b/external/flint-2.4.3/fmpq_mat/hilbert_matrix.c new file mode 100644 index 0000000..4879c05 --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/hilbert_matrix.c @@ -0,0 +1,35 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq_mat.h" + +void fmpq_mat_hilbert_matrix(fmpq_mat_t mat) +{ + slong i, j; + + for (i = 0; i < mat->r; i++) + for (j = 0; j < mat->c; j++) + fmpq_set_si(fmpq_mat_entry(mat, i, j), 1, i + j + 1); +} diff --git a/external/flint-2.4.3/fmpq_mat/init.c b/external/flint-2.4.3/fmpq_mat/init.c new file mode 100644 index 0000000..4e2ddad --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/init.c @@ -0,0 +1,49 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq_mat.h" + +void fmpq_mat_init(fmpq_mat_t mat, slong rows, slong cols) +{ + if ((rows) && (cols)) + { + slong i; + mat->entries = (fmpq *) flint_calloc(rows * cols, sizeof(fmpq)); + mat->rows = (fmpq **) flint_malloc(rows * sizeof(fmpq *)); + + /* Set denominators */ + for (i = 0; i < rows * cols; i++) + mat->entries[i].den = WORD(1); + + for (i = 0; i < rows; i++) + mat->rows[i] = mat->entries + i * cols; + } + else + mat->entries = NULL; + + mat->r = rows; + mat->c = cols; +} diff --git a/external/flint-2.4.3/fmpq_mat/inv.c b/external/flint-2.4.3/fmpq_mat/inv.c new file mode 100644 index 0000000..c5f42c7 --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/inv.c @@ -0,0 +1,110 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq_mat.h" + +int fmpq_mat_inv(fmpq_mat_t B, const fmpq_mat_t A) +{ + slong n = A->r; + + if (n == 0) + { + return 1; + } + else if (n == 1) + { + if (fmpq_is_zero(fmpq_mat_entry(A, 0, 0))) + return 0; + fmpq_inv(fmpq_mat_entry(B, 0, 0), fmpq_mat_entry(A, 0, 0)); + return 1; + } + else if (n == 2) + { + fmpq_t d; + int success; + + fmpq_init(d); + + fmpq_mul(d, fmpq_mat_entry(A, 0, 0), fmpq_mat_entry(A, 1, 1)); + fmpq_submul(d, fmpq_mat_entry(A, 0, 1), fmpq_mat_entry(A, 1, 0)); + success = !fmpq_is_zero(d); + + if (success) + { + fmpq_t t00, t01, t10, t11; + fmpq_inv(d, d); + + fmpq_init(t00); + fmpq_init(t01); + fmpq_init(t10); + fmpq_init(t11); + + fmpq_mul(t00, fmpq_mat_entry(A, 1, 1), d); + fmpq_mul(t01, fmpq_mat_entry(A, 0, 1), d); + fmpq_mul(t10, fmpq_mat_entry(A, 1, 0), d); + fmpq_mul(t11, fmpq_mat_entry(A, 0, 0), d); + + fmpq_set(fmpq_mat_entry(B, 0, 0), t00); + fmpq_neg(fmpq_mat_entry(B, 0, 1), t01); + fmpq_neg(fmpq_mat_entry(B, 1, 0), t10); + fmpq_set(fmpq_mat_entry(B, 1, 1), t11); + + fmpq_clear(t00); + fmpq_clear(t01); + fmpq_clear(t10); + fmpq_clear(t11); + } + + fmpq_clear(d); + return success; + } + else + { + fmpz_mat_t Aclear, Bclear, I; + fmpz * den; + slong i; + int success; + + fmpz_mat_init(Aclear, n, n); + fmpz_mat_init(Bclear, n, n); + fmpz_mat_init(I, n, n); + den = _fmpz_vec_init(n); + + fmpq_mat_get_fmpz_mat_rowwise(Aclear, den, A); + for (i = 0; i < n; i++) + fmpz_set(fmpz_mat_entry(I, i, i), den + i); + + success = fmpz_mat_solve(Bclear, den, Aclear, I); + if (success) + fmpq_mat_set_fmpz_mat_div_fmpz(B, Bclear, den); + + fmpz_mat_clear(Aclear); + fmpz_mat_clear(Bclear); + fmpz_mat_clear(I); + _fmpz_vec_clear(den, A->r); + + return success; + } +} diff --git a/external/flint-2.4.3/fmpq_mat/is_integral.c b/external/flint-2.4.3/fmpq_mat/is_integral.c new file mode 100644 index 0000000..3099c36 --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/is_integral.c @@ -0,0 +1,42 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq_mat.h" + +int fmpq_mat_is_integral(const fmpq_mat_t mat) +{ + slong i, j; + + for (i = 0; i < mat->r; i++) + { + for (j = 0; j < mat->c; j++) + { + if (!fmpz_is_one(fmpq_mat_entry_den(mat, i, j))) + return 0; + } + } + + return 1; +} diff --git a/external/flint-2.4.3/fmpq_mat/is_zero.c b/external/flint-2.4.3/fmpq_mat/is_zero.c new file mode 100644 index 0000000..6859ff5 --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/is_zero.c @@ -0,0 +1,42 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq_mat.h" + +int fmpq_mat_is_zero(const fmpq_mat_t mat) +{ + slong i, j; + + for (i = 0; i < mat->r; i++) + { + for (j = 0; j < mat->c; j++) + { + if (!fmpq_is_zero(fmpq_mat_entry(mat, i, j))) + return 0; + } + } + + return 1; +} diff --git a/external/flint-2.4.3/fmpq_mat/mul.c b/external/flint-2.4.3/fmpq_mat/mul.c new file mode 100644 index 0000000..028a496 --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/mul.c @@ -0,0 +1,32 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq_mat.h" + +void fmpq_mat_mul(fmpq_mat_t C, const fmpq_mat_t A, const fmpq_mat_t B) +{ + /* This is faster except maybe for 1x1 or 2x2 matrices */ + fmpq_mat_mul_cleared(C, A, B); +} diff --git a/external/flint-2.4.3/fmpq_mat/mul_cleared.c b/external/flint-2.4.3/fmpq_mat/mul_cleared.c new file mode 100644 index 0000000..381c730 --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/mul_cleared.c @@ -0,0 +1,67 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq_mat.h" + +void fmpq_mat_mul_cleared(fmpq_mat_t C, const fmpq_mat_t A, const fmpq_mat_t B) +{ + slong i, j; + + fmpz_mat_t Aclear; + fmpz_mat_t Bclear; + fmpz_mat_t Cclear; + + fmpz * Aden; + fmpz * Bden; + + fmpz_mat_init(Aclear, A->r, A->c); + fmpz_mat_init(Bclear, B->r, B->c); + fmpz_mat_init(Cclear, A->r, B->c); + + Aden = _fmpz_vec_init(A->r); + Bden = _fmpz_vec_init(B->c); + + fmpq_mat_get_fmpz_mat_rowwise(Aclear, Aden, A); + fmpq_mat_get_fmpz_mat_colwise(Bclear, Bden, B); + + fmpz_mat_mul(Cclear, Aclear, Bclear); + + for (i = 0; i < C->r; i++) + { + for (j = 0; j < C->c; j++) + { + fmpz_set(fmpq_mat_entry_num(C, i, j), fmpz_mat_entry(Cclear, i, j)); + fmpz_mul(fmpq_mat_entry_den(C, i, j), Aden + i, Bden + j); + fmpq_canonicalise(fmpq_mat_entry(C, i, j)); + } + } + + fmpz_mat_clear(Aclear); + fmpz_mat_clear(Bclear); + fmpz_mat_clear(Cclear); + + _fmpz_vec_clear(Aden, A->r); + _fmpz_vec_clear(Bden, B->c); +} diff --git a/external/flint-2.4.3/fmpq_mat/mul_direct.c b/external/flint-2.4.3/fmpq_mat/mul_direct.c new file mode 100644 index 0000000..24b8d29 --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/mul_direct.c @@ -0,0 +1,60 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq_mat.h" + +void fmpq_mat_mul_direct(fmpq_mat_t C, const fmpq_mat_t A, const fmpq_mat_t B) +{ + slong i, j, k; + + if (A == C || B == C) + { + flint_printf("Exception (fmpq_mat_mul_direct). Aliasing not implemented.\n"); + abort(); + } + + if (A->c == 0) + { + fmpq_mat_zero(C); + return; + } + + for (i = 0; i < A->r; i++) + { + for (j = 0; j < B->c; j++) + { + fmpq_mul(fmpq_mat_entry(C, i, j), + fmpq_mat_entry(A, i, 0), + fmpq_mat_entry(B, 0, j)); + + for (k = 1; k < A->c; k++) + { + fmpq_addmul(fmpq_mat_entry(C, i, j), + fmpq_mat_entry(A, i, k), + fmpq_mat_entry(B, k, j)); + } + } + } +} diff --git a/external/flint-2.4.3/fmpq_mat/mul_fmpz_mat.c b/external/flint-2.4.3/fmpq_mat/mul_fmpz_mat.c new file mode 100644 index 0000000..1c9d648 --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/mul_fmpz_mat.c @@ -0,0 +1,60 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq_mat.h" + +void +fmpq_mat_mul_fmpz_mat(fmpq_mat_t C, const fmpq_mat_t A, const fmpz_mat_t B) +{ + slong i, j; + + fmpz_mat_t Aclear; + fmpz_mat_t Cclear; + + fmpz * Aden; + + fmpz_mat_init(Aclear, A->r, A->c); + fmpz_mat_init(Cclear, A->r, B->c); + + Aden = _fmpz_vec_init(A->r); + + fmpq_mat_get_fmpz_mat_rowwise(Aclear, Aden, A); + fmpz_mat_mul(Cclear, Aclear, B); + + for (i = 0; i < C->r; i++) + { + for (j = 0; j < C->c; j++) + { + fmpz_set(fmpq_mat_entry_num(C, i, j), fmpz_mat_entry(Cclear, i, j)); + fmpz_set(fmpq_mat_entry_den(C, i, j), Aden + i); + fmpq_canonicalise(fmpq_mat_entry(C, i, j)); + } + } + + fmpz_mat_clear(Aclear); + fmpz_mat_clear(Cclear); + + _fmpz_vec_clear(Aden, A->r); +} diff --git a/external/flint-2.4.3/fmpq_mat/mul_r_fmpz_mat.c b/external/flint-2.4.3/fmpq_mat/mul_r_fmpz_mat.c new file mode 100644 index 0000000..15d3472 --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/mul_r_fmpz_mat.c @@ -0,0 +1,60 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq_mat.h" + +void +fmpq_mat_mul_r_fmpz_mat(fmpq_mat_t C, const fmpz_mat_t A, const fmpq_mat_t B) +{ + slong i, j; + + fmpz_mat_t Bclear; + fmpz_mat_t Cclear; + + fmpz * Bden; + + fmpz_mat_init(Bclear, B->r, B->c); + fmpz_mat_init(Cclear, A->r, B->c); + + Bden = _fmpz_vec_init(B->c); + + fmpq_mat_get_fmpz_mat_colwise(Bclear, Bden, B); + fmpz_mat_mul(Cclear, A, Bclear); + + for (i = 0; i < C->r; i++) + { + for (j = 0; j < C->c; j++) + { + fmpz_set(fmpq_mat_entry_num(C, i, j), fmpz_mat_entry(Cclear, i, j)); + fmpz_set(fmpq_mat_entry_den(C, i, j), Bden + j); + fmpq_canonicalise(fmpq_mat_entry(C, i, j)); + } + } + + fmpz_mat_clear(Bclear); + fmpz_mat_clear(Cclear); + + _fmpz_vec_clear(Bden, B->c); +} diff --git a/external/flint-2.4.3/fmpq_mat/neg.c b/external/flint-2.4.3/fmpq_mat/neg.c new file mode 100644 index 0000000..34a1373 --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/neg.c @@ -0,0 +1,37 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpq_mat.h" + +void fmpq_mat_neg(fmpq_mat_t rop, const fmpq_mat_t op) +{ + slong i, j; + + for (i = 0; i < op->r; i++) + for (j = 0; j < op->c; j++) + fmpq_neg(fmpq_mat_entry(rop, i, j), + fmpq_mat_entry(op, i, j)); +} + diff --git a/external/flint-2.4.3/fmpq_mat/one.c b/external/flint-2.4.3/fmpq_mat/one.c new file mode 100644 index 0000000..ef3e549 --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/one.c @@ -0,0 +1,41 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpq_mat.h" + +void fmpq_mat_one(fmpq_mat_t mat) +{ + slong i, j, min; + + for (i = 0; i < mat->r; i++) + for (j = 0; j < mat->c; j++) + fmpq_zero(fmpq_mat_entry(mat, i, j)); + + min = FLINT_MIN(mat->r, mat->c); + + for (i = 0; i < min; i++) + fmpq_one(fmpq_mat_entry(mat, i, i)); +} + diff --git a/external/flint-2.4.3/fmpq_mat/pivot.c b/external/flint-2.4.3/fmpq_mat/pivot.c new file mode 100644 index 0000000..8f12313 --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/pivot.c @@ -0,0 +1,55 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq_mat.h" + +int +fmpq_mat_pivot(slong * perm, fmpq_mat_t mat, slong r, slong c) +{ + slong t, j; + fmpq * u; + + if (!fmpq_is_zero(fmpq_mat_entry(mat, r, c))) + return 1; + + for (j = r + 1; j < mat->r; j++) + { + if (!fmpq_is_zero(fmpq_mat_entry(mat, j, c))) + { + if (perm) + { + t = perm[j]; + perm[j] = perm[r]; + perm[r] = t; + } + + u = mat->rows[j]; + mat->rows[j] = mat->rows[r]; + mat->rows[r] = u; + return -1; + } + } + return 0; +} diff --git a/external/flint-2.4.3/fmpq_mat/print.c b/external/flint-2.4.3/fmpq_mat/print.c new file mode 100644 index 0000000..ab0bf76 --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/print.c @@ -0,0 +1,46 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq_mat.h" + +void fmpq_mat_print(const fmpq_mat_t mat) +{ + slong i, j; + + flint_printf("<%wd x %wd matrix over Q>\n", mat->r, mat->c); + + for (i = 0; i < mat->r; i++) + { + flint_printf("["); + for (j = 0; j < mat->c; j++) + { + fmpq_print(fmpq_mat_entry(mat, i, j)); + if (j + 1 < mat->c) + flint_printf(", "); + } + flint_printf("]\n"); + } + flint_printf("\n"); +} diff --git a/external/flint-2.4.3/fmpq_mat/randbits.c b/external/flint-2.4.3/fmpq_mat/randbits.c new file mode 100644 index 0000000..129e6c4 --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/randbits.c @@ -0,0 +1,35 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq_mat.h" + +void fmpq_mat_randbits(fmpq_mat_t mat, flint_rand_t state, mp_bitcnt_t bits) +{ + slong i, j; + + for (i = 0; i < mat->r; i++) + for (j = 0; j < mat->c; j++) + fmpq_randbits(fmpq_mat_entry(mat,i,j), state, bits); +} diff --git a/external/flint-2.4.3/fmpq_mat/randtest.c b/external/flint-2.4.3/fmpq_mat/randtest.c new file mode 100644 index 0000000..4d392ac --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/randtest.c @@ -0,0 +1,35 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq_mat.h" + +void fmpq_mat_randtest(fmpq_mat_t mat, flint_rand_t state, mp_bitcnt_t bits) +{ + slong i, j; + + for (i = 0; i < mat->r; i++) + for (j = 0; j < mat->c; j++) + fmpq_randtest(fmpq_mat_entry(mat,i,j), state, bits); +} diff --git a/external/flint-2.4.3/fmpq_mat/rref.c b/external/flint-2.4.3/fmpq_mat/rref.c new file mode 100644 index 0000000..ae3a53c --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/rref.c @@ -0,0 +1,35 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq_mat.h" + +slong +fmpq_mat_rref(fmpq_mat_t B, const fmpq_mat_t A) +{ + if (A->r <= 2 || A->c <= 2) + return fmpq_mat_rref_classical(B, A); + else + return fmpq_mat_rref_fraction_free(B, A); +} diff --git a/external/flint-2.4.3/fmpq_mat/rref_classical.c b/external/flint-2.4.3/fmpq_mat/rref_classical.c new file mode 100644 index 0000000..a1b646d --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/rref_classical.c @@ -0,0 +1,86 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq_mat.h" + +slong +fmpq_mat_rref_classical(fmpq_mat_t B, const fmpq_mat_t A) +{ + slong m, n, i, j, pivot_row, pivot_col, rank; + + m = A->r; + n = A->c; + + if (m == 0 || n == 0) + return 0; + + if (A != B) + fmpq_mat_set(B, A); + + rank = 0; + pivot_row = 0; + pivot_col = 0; + + while (pivot_row < m && pivot_col < n) + { + if (!fmpq_mat_pivot(NULL, B, pivot_row, pivot_col)) + { + pivot_col++; + continue; + } + + rank++; + + /* Scale row to have 1 as leading entry */ + for (j = pivot_col + 1; j < n; j++) + { + fmpq_div(fmpq_mat_entry(B, pivot_row, j), + fmpq_mat_entry(B, pivot_row, j), + fmpq_mat_entry(B, pivot_row, pivot_col)); + } + + /* Eliminate rows above and below */ + for (i = 0; i < m; i++) + { + if (i == pivot_row || + fmpq_is_zero(fmpq_mat_entry(B, i, pivot_col))) + continue; + + for (j = pivot_col + 1; j < n; j++) + fmpq_submul(fmpq_mat_entry(B, i, j), + fmpq_mat_entry(B, pivot_row, j), + fmpq_mat_entry(B, i, pivot_col)); + } + + /* Clear pivot column */ + for (i = 0; i < m; i++) + fmpq_set_si(fmpq_mat_entry(B, i, pivot_col), i == pivot_row, 1); + + pivot_row++; + pivot_col++; + } + + return rank; +} diff --git a/external/flint-2.4.3/fmpq_mat/rref_fraction_free.c b/external/flint-2.4.3/fmpq_mat/rref_fraction_free.c new file mode 100644 index 0000000..7d41ba0 --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/rref_fraction_free.c @@ -0,0 +1,53 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq_mat.h" + +slong +fmpq_mat_rref_fraction_free(fmpq_mat_t B, const fmpq_mat_t A) +{ + fmpz_mat_t Aclear; + fmpz_t den; + slong rank; + + if (fmpq_mat_is_empty(A)) + return 0; + + fmpz_mat_init(Aclear, A->r, A->c); + fmpq_mat_get_fmpz_mat_rowwise(Aclear, NULL, A); + fmpz_init(den); + + rank = fmpz_mat_rref(Aclear, den, Aclear); + + if (rank == 0) + fmpq_mat_zero(B); + else + fmpq_mat_set_fmpz_mat_div_fmpz(B, Aclear, den); + + fmpz_mat_clear(Aclear); + fmpz_clear(den); + + return rank; +} diff --git a/external/flint-2.4.3/fmpq_mat/scalar_div_fmpz.c b/external/flint-2.4.3/fmpq_mat/scalar_div_fmpz.c new file mode 100644 index 0000000..a6d2c20 --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/scalar_div_fmpz.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpq_mat.h" + +void fmpq_mat_scalar_div_fmpz(fmpq_mat_t rop, + const fmpq_mat_t op, const fmpz_t x) +{ + slong i, j; + + for (i = 0; i < op->r; i++) + for (j = 0; j < op->c; j++) + fmpq_div_fmpz(fmpq_mat_entry(rop, i, j), + fmpq_mat_entry(op, i, j), x); +} + diff --git a/external/flint-2.4.3/fmpq_mat/scalar_mul_fmpz.c b/external/flint-2.4.3/fmpq_mat/scalar_mul_fmpz.c new file mode 100644 index 0000000..4bf05b6 --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/scalar_mul_fmpz.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpq_mat.h" + +void fmpq_mat_scalar_mul_fmpz(fmpq_mat_t rop, + const fmpq_mat_t op, const fmpz_t x) +{ + slong i, j; + + for (i = 0; i < op->r; i++) + for (j = 0; j < op->c; j++) + fmpq_mul_fmpz(fmpq_mat_entry(rop, i, j), + fmpq_mat_entry(op, i, j), x); +} + diff --git a/external/flint-2.4.3/fmpq_mat/set.c b/external/flint-2.4.3/fmpq_mat/set.c new file mode 100644 index 0000000..4fb5c94 --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/set.c @@ -0,0 +1,35 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq_mat.h" + +void fmpq_mat_set(fmpq_mat_t dest, const fmpq_mat_t src) +{ + slong i, j; + + for (i = 0; i < src->r; i++) + for (j = 0; j < src->c; j++) + fmpq_set(fmpq_mat_entry(dest,i,j), fmpq_mat_entry(src,i,j)); +} diff --git a/external/flint-2.4.3/fmpq_mat/set_fmpz_mat.c b/external/flint-2.4.3/fmpq_mat/set_fmpz_mat.c new file mode 100644 index 0000000..88c3eed --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/set_fmpz_mat.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq_mat.h" + +void fmpq_mat_set_fmpz_mat(fmpq_mat_t dest, const fmpz_mat_t src) +{ + slong i, j; + + for (i = 0; i < src->r; i++) + { + for (j = 0; j < src->c; j++) + { + fmpz_set(fmpq_mat_entry_num(dest, i, j), fmpz_mat_entry(src, i, j)); + fmpz_one(fmpq_mat_entry_den(dest, i, j)); + } + } +} diff --git a/external/flint-2.4.3/fmpq_mat/set_fmpz_mat_div_fmpz.c b/external/flint-2.4.3/fmpq_mat/set_fmpz_mat_div_fmpz.c new file mode 100644 index 0000000..8536230 --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/set_fmpz_mat_div_fmpz.c @@ -0,0 +1,69 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq_mat.h" + +void +fmpq_mat_set_fmpz_mat_div_fmpz(fmpq_mat_t X, const fmpz_mat_t Xnum, + const fmpz_t den) +{ + slong i, j; + + if (fmpz_is_one(den)) + { + fmpq_mat_set_fmpz_mat(X, Xnum); + } + else if (*den == WORD(-1)) + { + fmpz_t t; + fmpz_init(t); + fmpz_set(t, den); + + for (i = 0; i < Xnum->r; i++) + { + for (j = 0; j < Xnum->c; j++) + { + fmpz_neg(fmpq_mat_entry_num(X, i, j), + fmpz_mat_entry(Xnum, i, j)); + fmpz_one(fmpq_mat_entry_den(X, i, j)); + } + } + + fmpz_clear(t); + } + else + { + for (i = 0; i < Xnum->r; i++) + { + for (j = 0; j < Xnum->c; j++) + { + fmpz_set(fmpq_mat_entry_num(X, i, j), + fmpz_mat_entry(Xnum, i, j)); + fmpz_set(fmpq_mat_entry_den(X, i, j), den); + fmpq_canonicalise(fmpq_mat_entry(X, i, j)); + } + } + } +} diff --git a/external/flint-2.4.3/fmpq_mat/set_fmpz_mat_mod_fmpz.c b/external/flint-2.4.3/fmpq_mat/set_fmpz_mat_mod_fmpz.c new file mode 100644 index 0000000..9c531c1 --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/set_fmpz_mat_mod_fmpz.c @@ -0,0 +1,76 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq_mat.h" + +int +fmpq_mat_set_fmpz_mat_mod_fmpz(fmpq_mat_t X, + const fmpz_mat_t Xmod, const fmpz_t mod) +{ + fmpz_t num, den, t, u, d; + slong i, j; + + int success = 1; + + fmpz_init(num); + fmpz_init(den); + fmpz_init(d); + fmpz_init(t); + fmpz_init(u); + + fmpz_one(d); + + for (i = 0; i < Xmod->r; i++) + { + for (j = 0; j < Xmod->c; j++) + { + /* TODO: handle various special cases efficiently; zeros, + small integers, etc. */ + fmpz_mul(t, d, fmpz_mat_entry(Xmod, i, j)); + fmpz_fdiv_qr(u, t, t, mod); + + success = _fmpq_reconstruct_fmpz(num, den, t, mod); + + fmpz_mul(den, den, d); + fmpz_set(d, den); + + if (!success) + goto cleanup; + + fmpz_set(fmpq_mat_entry_num(X, i, j), num); + fmpz_set(fmpq_mat_entry_den(X, i, j), den); + fmpq_canonicalise(fmpq_mat_entry(X, i, j)); + } + } + +cleanup: + fmpz_clear(num); + fmpz_clear(den); + fmpz_clear(d); + fmpz_clear(t); + fmpz_clear(u); + + return success; +} diff --git a/external/flint-2.4.3/fmpq_mat/solve_dixon.c b/external/flint-2.4.3/fmpq_mat/solve_dixon.c new file mode 100644 index 0000000..91b585a --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/solve_dixon.c @@ -0,0 +1,53 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq_mat.h" + +int +fmpq_mat_solve_dixon(fmpq_mat_t X, const fmpq_mat_t A, const fmpq_mat_t B) +{ + fmpz_mat_t Anum; + fmpz_mat_t Bnum; + fmpz_mat_t Xnum; + fmpz_t mod; + int success; + + fmpz_mat_init(Anum, A->r, A->c); + fmpz_mat_init(Bnum, B->r, B->c); + fmpz_mat_init(Xnum, B->r, B->c); + fmpz_init(mod); + + fmpq_mat_get_fmpz_mat_rowwise_2(Anum, Bnum, NULL, A, B); + success = fmpz_mat_solve_dixon(Xnum, mod, Anum, Bnum); + if (success) + success = fmpq_mat_set_fmpz_mat_mod_fmpz(X, Xnum, mod); + + fmpz_mat_clear(Anum); + fmpz_mat_clear(Bnum); + fmpz_mat_clear(Xnum); + fmpz_clear(mod); + + return success; +} diff --git a/external/flint-2.4.3/fmpq_mat/solve_fraction_free.c b/external/flint-2.4.3/fmpq_mat/solve_fraction_free.c new file mode 100644 index 0000000..207e5bb --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/solve_fraction_free.c @@ -0,0 +1,55 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq_mat.h" + +int +fmpq_mat_solve_fraction_free(fmpq_mat_t X, const fmpq_mat_t A, + const fmpq_mat_t B) +{ + fmpz_mat_t Anum; + fmpz_mat_t Bnum; + fmpz_mat_t Xnum; + fmpz_t den; + int success; + + fmpz_mat_init(Anum, A->r, A->c); + fmpz_mat_init(Bnum, B->r, B->c); + fmpz_mat_init(Xnum, B->r, B->c); + fmpz_init(den); + + fmpq_mat_get_fmpz_mat_rowwise_2(Anum, Bnum, NULL, A, B); + success = fmpz_mat_solve(Xnum, den, Anum, Bnum); + + if (success) + fmpq_mat_set_fmpz_mat_div_fmpz(X, Xnum, den); + + fmpz_mat_clear(Anum); + fmpz_mat_clear(Bnum); + fmpz_mat_clear(Xnum); + fmpz_clear(den); + + return success; +} diff --git a/external/flint-2.4.3/fmpq_mat/sub.c b/external/flint-2.4.3/fmpq_mat/sub.c new file mode 100644 index 0000000..99cf367 --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/sub.c @@ -0,0 +1,37 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpq_mat.h" + +void fmpq_mat_sub(fmpq_mat_t mat, const fmpq_mat_t mat1, const fmpq_mat_t mat2) +{ + slong i, j; + + for (i = 0; i < mat->r; i++) + for (j = 0; j < mat->c; j++) + fmpq_sub(fmpq_mat_entry(mat, i, j), + fmpq_mat_entry(mat1, i, j), fmpq_mat_entry(mat2, i, j)); +} + diff --git a/external/flint-2.4.3/fmpq_mat/test/t-add.c b/external/flint-2.4.3/fmpq_mat/test/t-add.c new file mode 100644 index 0000000..f258a92 --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/test/t-add.c @@ -0,0 +1,171 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpq.h" +#include "fmpq_mat.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("add...."); + fflush(stdout); + + /* Aliasing, B = B + C */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_mat_t A, B, C; + + slong m, n, bits; + + m = n_randint(state, 10); + n = n_randint(state, 10); + + bits = 1 + n_randint(state, 100); + + fmpq_mat_init(A, m, n); + fmpq_mat_init(B, m, n); + fmpq_mat_init(C, m, n); + + fmpq_mat_randtest(B, state, bits); + fmpq_mat_randtest(C, state, bits); + + fmpq_mat_add(A, B, C); + fmpq_mat_add(B, B, C); + + result = fmpq_mat_equal(A, B); + if (!result) + { + flint_printf("FAIL (B = B + C):\n"); + flint_printf("A:\n"); + fmpq_mat_print(A); + flint_printf("B:\n"); + fmpq_mat_print(B); + flint_printf("C:\n"); + fmpq_mat_print(C); + abort(); + } + + fmpq_mat_clear(A); + fmpq_mat_clear(B); + fmpq_mat_clear(C); + } + + /* Aliasing, C = B + C */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_mat_t A, B, C; + + slong m, n, bits; + + m = n_randint(state, 10); + n = n_randint(state, 10); + + bits = 1 + n_randint(state, 100); + + fmpq_mat_init(A, m, n); + fmpq_mat_init(B, m, n); + fmpq_mat_init(C, m, n); + + fmpq_mat_randtest(B, state, bits); + fmpq_mat_randtest(C, state, bits); + + fmpq_mat_add(A, B, C); + fmpq_mat_add(C, B, C); + + result = fmpq_mat_equal(A, C); + if (!result) + { + flint_printf("FAIL (C = B + C):\n"); + flint_printf("A:\n"); + fmpq_mat_print(A); + flint_printf("B:\n"); + fmpq_mat_print(B); + flint_printf("C:\n"); + fmpq_mat_print(C); + abort(); + } + + fmpq_mat_clear(A); + fmpq_mat_clear(B); + fmpq_mat_clear(C); + } + + /* A + B == B + A */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_mat_t A, B, C, D; + + slong m, n, bits; + + m = n_randint(state, 10); + n = n_randint(state, 10); + + bits = 1 + n_randint(state, 100); + + fmpq_mat_init(A, m, n); + fmpq_mat_init(B, m, n); + fmpq_mat_init(C, m, n); + fmpq_mat_init(D, m, n); + + fmpq_mat_randtest(A, state, bits); + fmpq_mat_randtest(B, state, bits); + + fmpq_mat_add(C, A, B); + fmpq_mat_add(D, B, A); + + result = fmpq_mat_equal(C, D); + if (!result) + { + flint_printf("FAIL (A + B == B + A):\n"); + flint_printf("A:\n"); + fmpq_mat_print(A); + flint_printf("B:\n"); + fmpq_mat_print(B); + flint_printf("C:\n"); + fmpq_mat_print(C); + flint_printf("D:\n"); + fmpq_mat_print(D); + abort(); + } + + fmpq_mat_clear(A); + fmpq_mat_clear(B); + fmpq_mat_clear(C); + fmpq_mat_clear(D); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fmpq_mat/test/t-det.c b/external/flint-2.4.3/fmpq_mat/test/t-det.c new file mode 100644 index 0000000..bd1483f --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/test/t-det.c @@ -0,0 +1,105 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpq.h" +#include "fmpq_mat.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("det...."); + fflush(stdout); + + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_mat_t A, B, C; + fmpq_t a, b, ab, c; + + slong n, bits; + + n = n_randint(state, 10); + bits = 1 + n_randint(state, 100); + + fmpq_mat_init(A, n, n); + fmpq_mat_init(B, n, n); + fmpq_mat_init(C, n, n); + + fmpq_init(a); + fmpq_init(b); + fmpq_init(ab); + fmpq_init(c); + + fmpq_mat_randtest(A, state, bits); + fmpq_mat_randtest(B, state, bits); + fmpq_mat_mul(C, A, B); + + fmpq_mat_det(a, A); + fmpq_mat_det(b, B); + fmpq_mat_det(c, C); + + fmpq_mul(ab, a, b); + + if (!fmpq_equal(ab, c)) + { + flint_printf("FAIL!\n"); + flint_printf("A:\n"); + fmpq_mat_print(A); + flint_printf("B:\n"); + fmpq_mat_print(B); + flint_printf("C:\n"); + fmpq_mat_print(C); + flint_printf("\ndet(A):\n"); + fmpq_print(a); + flint_printf("\ndet(B):\n"); + fmpq_print(b); + flint_printf("\ndet(C):\n"); + fmpq_print(c); + abort(); + } + + fmpq_clear(a); + fmpq_clear(b); + fmpq_clear(ab); + fmpq_clear(c); + + fmpq_mat_clear(A); + fmpq_mat_clear(B); + fmpq_mat_clear(C); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} + diff --git a/external/flint-2.4.3/fmpq_mat/test/t-init_clear.c b/external/flint-2.4.3/fmpq_mat/test/t-init_clear.c new file mode 100644 index 0000000..d68d53f --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/test/t-init_clear.c @@ -0,0 +1,66 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpq.h" +#include "fmpq_mat.h" + + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("init/clear...."); + fflush(stdout); + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_mat_t a; + slong j, k; + slong rows = n_randint(state, 100); + slong cols = n_randint(state, 100); + + fmpq_mat_init(a, rows, cols); + + for (j = 0; j < rows; j++) + for (k = 0; k < cols; k++) + fmpq_zero(fmpq_mat_entry(a, j, k)); + + fmpq_mat_clear(a); + } + + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_mat/test/t-inv.c b/external/flint-2.4.3/fmpq_mat/test/t-inv.c new file mode 100644 index 0000000..4b57cef --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/test/t-inv.c @@ -0,0 +1,191 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpq.h" +#include "fmpq_mat.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("inv...."); + fflush(stdout); + + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_mat_t A, B, C; + fmpq_t d; + + int success1, success2; + slong n, bits; + + n = n_randint(state, 10); + bits = 1 + n_randint(state, 100); + + fmpq_mat_init(A, n, n); + fmpq_mat_init(B, n, n); + fmpq_mat_init(C, n, n); + + fmpq_init(d); + + /* XXX: replace with a randtest function */ + { + slong k; + + for (k = 0; (k < 100) && fmpq_is_zero(d); k++) + { + fmpq_mat_randtest(A, state, bits); + fmpq_mat_det(d, A); + } + if (fmpq_is_zero(d)) + { + fmpq_mat_one(A); + } + } + + fmpq_clear(d); + + success1 = fmpq_mat_inv(B, A); + success2 = fmpq_mat_inv(C, B); + + if (!fmpq_mat_equal(A, C) || !success1 || !success2) + { + flint_printf("FAIL!\n"); + flint_printf("A:\n"); + fmpq_mat_print(A); + flint_printf("B:\n"); + fmpq_mat_print(B); + flint_printf("C:\n"); + fmpq_mat_print(C); + abort(); + } + + fmpq_mat_clear(A); + fmpq_mat_clear(B); + fmpq_mat_clear(C); + } + + /* Test aliasing */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + fmpq_mat_t A, B; + fmpq_t d; + + int success1, success2; + slong n, bits; + + n = n_randint(state, 10); + bits = 1 + n_randint(state, 100); + + fmpq_mat_init(A, n, n); + fmpq_mat_init(B, n, n); + + fmpq_init(d); + + /* XXX: replace with a randtest function */ + do { + fmpq_mat_randtest(A, state, bits); + fmpq_mat_det(d, A); + } while (fmpq_is_zero(d)); + + fmpq_clear(d); + + success1 = fmpq_mat_inv(B, A); + success2 = fmpq_mat_inv(A, A); + + if (!fmpq_mat_equal(A, B) || !success1 || !success2) + { + flint_printf("FAIL!\n"); + flint_printf("A:\n"); + fmpq_mat_print(A); + flint_printf("B:\n"); + fmpq_mat_print(B); + abort(); + } + + fmpq_mat_clear(A); + fmpq_mat_clear(B); + } + + /* Test singular matrices */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + slong n, r, b, d; + fmpq_mat_t A, B; + fmpz_mat_t M; + fmpz_t den; + int success; + + n = n_randint(state, 10); + + fmpz_init(den); + + for (r = 0; r < n; r++) + { + b = 1 + n_randint(state, 10) * n_randint(state, 10); + d = n_randint(state, 2*n*n + 1); + + fmpz_mat_init(M, n, n); + fmpq_mat_init(A, n, n); + fmpq_mat_init(B, n, n); + + fmpz_mat_randrank(M, state, r, b); + + if (i % 2 == 0) + fmpz_mat_randops(M, state, d); + + fmpz_randtest_not_zero(den, state, b); + fmpq_mat_set_fmpz_mat_div_fmpz(A, M, den); + + success = fmpq_mat_inv(B, A); + + if (success) + { + flint_printf("FAIL:\n"); + flint_printf("matrix reported as invertible:\n"); + fmpq_mat_print(A); + abort(); + } + + fmpz_mat_clear(M); + fmpq_mat_clear(A); + fmpq_mat_clear(B); + } + + fmpz_clear(den); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_mat/test/t-is_integral.c b/external/flint-2.4.3/fmpq_mat/test/t-is_integral.c new file mode 100644 index 0000000..d2065be --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/test/t-is_integral.c @@ -0,0 +1,89 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpq.h" +#include "fmpq_mat.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("is_integral...."); + fflush(stdout); + + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_mat_t A; + fmpz_mat_t B; + slong n, m; + + m = n_randint(state, 10); + n = n_randint(state, 10); + + fmpq_mat_init(A, m, n); + fmpz_mat_init(B, m, n); + + fmpz_mat_randtest(B, state, 10); + fmpq_mat_set_fmpz_mat(A, B); + + if (!fmpq_mat_is_integral(A)) + { + flint_printf("FAIL\n"); + abort(); + } + + if (m && n) + { + slong i, j; + i = n_randint(state, m); + j = n_randint(state, n); + + fmpq_set_si(fmpq_mat_entry(A, i, j), 1, 2); + + if (fmpq_mat_is_integral(A)) + { + flint_printf("FAIL\n"); + abort(); + } + } + + + fmpq_mat_clear(A); + fmpz_mat_clear(B); + } + + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_mat/test/t-mul.c b/external/flint-2.4.3/fmpq_mat/test/t-mul.c new file mode 100644 index 0000000..a0741d4 --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/test/t-mul.c @@ -0,0 +1,92 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpq.h" +#include "fmpq_mat.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("mul...."); + fflush(stdout); + + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_mat_t A, B, C, D; + + slong m, n, k, bits; + + m = n_randint(state, 10); + n = n_randint(state, 10); + k = n_randint(state, 10); + + bits = 1 + n_randint(state, 100); + + fmpq_mat_init(A, m, k); + fmpq_mat_init(B, k, n); + fmpq_mat_init(C, m, n); + fmpq_mat_init(D, m, n); + + fmpq_mat_randtest(A, state, bits); + fmpq_mat_randtest(B, state, bits); + fmpq_mat_randtest(C, state, bits); /* noise in output */ + + fmpq_mat_mul_direct(C, A, B); + fmpq_mat_mul_cleared(D, A, B); + + result = fmpq_mat_equal(C, D); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"); + fmpq_mat_print(A); + flint_printf("B:\n"); + fmpq_mat_print(B); + flint_printf("C:\n"); + fmpq_mat_print(C); + flint_printf("D:\n"); + fmpq_mat_print(D); + abort(); + } + + fmpq_mat_clear(A); + fmpq_mat_clear(B); + fmpq_mat_clear(C); + fmpq_mat_clear(D); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fmpq_mat/test/t-neg.c b/external/flint-2.4.3/fmpq_mat/test/t-neg.c new file mode 100644 index 0000000..6fe1ccb --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/test/t-neg.c @@ -0,0 +1,118 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpq.h" +#include "fmpq_mat.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("neg...."); + fflush(stdout); + + /* Aliasing */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_mat_t A, B; + + slong m, n, bits; + + m = n_randint(state, 10); + n = n_randint(state, 10); + + bits = 1 + n_randint(state, 100); + + fmpq_mat_init(A, m, n); + fmpq_mat_init(B, m, n); + + fmpq_mat_randtest(B, state, bits); + + fmpq_mat_neg(A, B); + fmpq_mat_neg(B, B); + + result = fmpq_mat_equal(A, B); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"); + fmpq_mat_print(A); + flint_printf("B:\n"); + fmpq_mat_print(B); + abort(); + } + + fmpq_mat_clear(A); + fmpq_mat_clear(B); + } + + /* --A == A */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_mat_t A, B; + + slong m, n, bits; + + m = n_randint(state, 10); + n = n_randint(state, 10); + + bits = 1 + n_randint(state, 100); + + fmpq_mat_init(A, m, n); + fmpq_mat_init(B, m, n); + + fmpq_mat_randtest(B, state, bits); + + fmpq_mat_neg(A, B); + fmpq_mat_neg(A, A); + + result = fmpq_mat_equal(A, B); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"); + fmpq_mat_print(A); + flint_printf("B:\n"); + fmpq_mat_print(B); + abort(); + } + + fmpq_mat_clear(A); + fmpq_mat_clear(B); + } + + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fmpq_mat/test/t-one.c b/external/flint-2.4.3/fmpq_mat/test/t-one.c new file mode 100644 index 0000000..029a3f5 --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/test/t-one.c @@ -0,0 +1,91 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpq.h" +#include "fmpq_mat.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("one...."); + fflush(stdout); + + /* 1 * A == A * 1 == A */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_mat_t A, B, C, I; + + slong n, bits; + + n = n_randint(state, 10); + + bits = 1 + n_randint(state, 100); + + fmpq_mat_init(A, n, n); + fmpq_mat_init(B, n, n); + fmpq_mat_init(C, n, n); + fmpq_mat_init(I, n, n); + + fmpq_mat_randtest(A, state, bits); + fmpq_mat_one(I); + + fmpq_mat_mul(B, I, A); + fmpq_mat_mul(C, A, I); + + result = fmpq_mat_equal(A, B) && fmpq_mat_equal(A, C); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"); + fmpq_mat_print(A); + flint_printf("B:\n"); + fmpq_mat_print(B); + flint_printf("C:\n"); + fmpq_mat_print(C); + flint_printf("I:\n"); + fmpq_mat_print(I); + abort(); + } + + fmpq_mat_clear(A); + fmpq_mat_clear(B); + fmpq_mat_clear(C); + fmpq_mat_clear(I); + } + + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fmpq_mat/test/t-rref.c b/external/flint-2.4.3/fmpq_mat/test/t-rref.c new file mode 100644 index 0000000..562518a --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/test/t-rref.c @@ -0,0 +1,117 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpq.h" +#include "fmpq_mat.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("rref...."); + fflush(stdout); + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + slong m, n, r, rank, b, d; + fmpq_mat_t A, B, C; + fmpz_mat_t M; + fmpz_t den; + + m = n_randint(state, 10); + n = n_randint(state, 10); + + fmpz_init(den); + + for (r = 0; r <= FLINT_MIN(m,n); r++) + { + b = 1 + n_randint(state, 10) * n_randint(state, 10); + d = n_randint(state, 2*m*n + 1); + + fmpz_mat_init(M, m, n); + fmpq_mat_init(A, m, n); + fmpq_mat_init(B, m, n); + fmpq_mat_init(C, m, n); + + fmpz_mat_randrank(M, state, r, b); + + if (i % 2 == 0) + fmpz_mat_randops(M, state, d); + + fmpz_randtest_not_zero(den, state, b); + fmpq_mat_set_fmpz_mat_div_fmpz(A, M, den); + + rank = fmpq_mat_rref_classical(B, A); + if (r != rank) + { + flint_printf("FAIL:\n"); + flint_printf("fmpq_mat_rref_classical: wrong rank!\n"); + fmpq_mat_print(A); + flint_printf("\nrank: %wd computed: %wd\n", r, rank); + abort(); + } + + rank = fmpq_mat_rref_fraction_free(C, A); + if (r != rank) + { + flint_printf("FAIL:\n"); + flint_printf("fmpq_mat_rref_fraction_free: wrong rank!\n"); + abort(); + } + + if (!fmpq_mat_equal(B, C)) + { + flint_printf("FAIL:\n"); + flint_printf("different results!\n"); + flint_printf("A:\n"); + fmpq_mat_print(A); + flint_printf("\nB:\n"); + fmpq_mat_print(B); + flint_printf("\nC:\n"); + fmpq_mat_print(C); + abort(); + } + + fmpz_mat_clear(M); + fmpq_mat_clear(A); + fmpq_mat_clear(B); + fmpq_mat_clear(C); + } + + fmpz_clear(den); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_mat/test/t-scalar_div_fmpz.c b/external/flint-2.4.3/fmpq_mat/test/t-scalar_div_fmpz.c new file mode 100644 index 0000000..63d725a --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/test/t-scalar_div_fmpz.c @@ -0,0 +1,131 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpq.h" +#include "fmpq_mat.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("scalar_div_fmpz...."); + fflush(stdout); + + /* Aliasing */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_mat_t A, B; + fmpz_t x; + + slong m, n, bits; + + m = n_randint(state, 10); + n = n_randint(state, 10); + + bits = 1 + n_randint(state, 100); + + fmpq_mat_init(A, m, n); + fmpq_mat_init(B, m, n); + fmpz_init(x); + + fmpq_mat_randtest(B, state, bits); + fmpz_randtest_not_zero(x, state, bits); + + fmpq_mat_scalar_div_fmpz(A, B, x); + fmpq_mat_scalar_div_fmpz(B, B, x); + + result = fmpq_mat_equal(A, B); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"), fmpq_mat_print(A); + flint_printf("B:\n"), fmpq_mat_print(B); + abort(); + } + + fmpq_mat_clear(A); + fmpq_mat_clear(B); + fmpz_clear(x); + } + + /* (A + B) / x == A / x + B / x */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_mat_t A, B, C, D; + fmpz_t x; + + slong m, n, bits; + + m = n_randint(state, 10); + n = n_randint(state, 10); + + bits = 1 + n_randint(state, 100); + + fmpq_mat_init(A, m, n); + fmpq_mat_init(B, m, n); + fmpq_mat_init(C, m, n); + fmpq_mat_init(D, m, n); + fmpz_init(x); + + fmpq_mat_randtest(A, state, bits); + fmpq_mat_randtest(B, state, bits); + fmpz_randtest_not_zero(x, state, bits); + + fmpq_mat_scalar_div_fmpz(C, A, x); + fmpq_mat_scalar_div_fmpz(D, B, x); + fmpq_mat_add(D, C, D); + + fmpq_mat_add(C, A, B); + fmpq_mat_scalar_div_fmpz(C, C, x); + + result = fmpq_mat_equal(C, D); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"), fmpq_mat_print(A); + flint_printf("B:\n"), fmpq_mat_print(B); + abort(); + } + + fmpq_mat_clear(A); + fmpq_mat_clear(B); + fmpq_mat_clear(C); + fmpq_mat_clear(D); + fmpz_clear(x); + } + + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fmpq_mat/test/t-scalar_mul_fmpz.c b/external/flint-2.4.3/fmpq_mat/test/t-scalar_mul_fmpz.c new file mode 100644 index 0000000..71314fc --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/test/t-scalar_mul_fmpz.c @@ -0,0 +1,131 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpq.h" +#include "fmpq_mat.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("scalar_mul_fmpz...."); + fflush(stdout); + + /* Aliasing */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_mat_t A, B; + fmpz_t x; + + slong m, n, bits; + + m = n_randint(state, 10); + n = n_randint(state, 10); + + bits = 1 + n_randint(state, 100); + + fmpq_mat_init(A, m, n); + fmpq_mat_init(B, m, n); + fmpz_init(x); + + fmpq_mat_randtest(B, state, bits); + fmpz_randtest(x, state, bits); + + fmpq_mat_scalar_mul_fmpz(A, B, x); + fmpq_mat_scalar_mul_fmpz(B, B, x); + + result = fmpq_mat_equal(A, B); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"), fmpq_mat_print(A); + flint_printf("B:\n"), fmpq_mat_print(B); + abort(); + } + + fmpq_mat_clear(A); + fmpq_mat_clear(B); + fmpz_clear(x); + } + + /* (A + B) * x == A * x + B * x */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_mat_t A, B, C, D; + fmpz_t x; + + slong m, n, bits; + + m = n_randint(state, 10); + n = n_randint(state, 10); + + bits = 1 + n_randint(state, 100); + + fmpq_mat_init(A, m, n); + fmpq_mat_init(B, m, n); + fmpq_mat_init(C, m, n); + fmpq_mat_init(D, m, n); + fmpz_init(x); + + fmpq_mat_randtest(A, state, bits); + fmpq_mat_randtest(B, state, bits); + fmpz_randtest(x, state, bits); + + fmpq_mat_scalar_mul_fmpz(C, A, x); + fmpq_mat_scalar_mul_fmpz(D, B, x); + fmpq_mat_add(D, C, D); + + fmpq_mat_add(C, A, B); + fmpq_mat_scalar_mul_fmpz(C, C, x); + + result = fmpq_mat_equal(C, D); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"), fmpq_mat_print(A); + flint_printf("B:\n"), fmpq_mat_print(B); + abort(); + } + + fmpq_mat_clear(A); + fmpq_mat_clear(B); + fmpq_mat_clear(C); + fmpq_mat_clear(D); + fmpz_clear(x); + } + + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fmpq_mat/test/t-solve_dixon.c b/external/flint-2.4.3/fmpq_mat/test/t-solve_dixon.c new file mode 100644 index 0000000..a4f6f26 --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/test/t-solve_dixon.c @@ -0,0 +1,142 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpq.h" +#include "fmpq_mat.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("solve_dixon...."); + fflush(stdout); + + /* Solve nonsingular systems */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_mat_t A, B, X, AX; + fmpq_t d; + int success; + slong n, m, bits; + + n = n_randint(state, 10); + m = n_randint(state, 10); + bits = 1 + n_randint(state, 100); + + fmpq_mat_init(A, n, n); + fmpq_mat_init(B, n, m); + fmpq_mat_init(X, n, m); + fmpq_mat_init(AX, n, m); + + fmpq_init(d); + /* XXX: replace with a randtest function */ + do { + fmpq_mat_randtest(A, state, bits); + fmpq_mat_det(d, A); + } while (fmpq_is_zero(d)); + fmpq_clear(d); + + fmpq_mat_randtest(B, state, bits); + + success = fmpq_mat_solve_dixon(X, A, B); + fmpq_mat_mul(AX, A, X); + + if (!fmpq_mat_equal(AX, B) || !success) + { + flint_printf("FAIL!\n"); + flint_printf("success: %d\n", success); + flint_printf("A:\n"); + fmpq_mat_print(A); + flint_printf("B:\n"); + fmpq_mat_print(B); + flint_printf("X:\n"); + fmpq_mat_print(X); + flint_printf("AX:\n"); + fmpq_mat_print(AX); + abort(); + } + + fmpq_mat_clear(A); + fmpq_mat_clear(B); + fmpq_mat_clear(X); + fmpq_mat_clear(AX); + } + + /* Check singular systems */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_mat_t A, B, X; + fmpz_mat_t M; + fmpz_t den; + slong n, m, bits; + int success; + + n = 1 + n_randint(state, 10); + m = 1 + n_randint(state, 10); + bits = 1 + n_randint(state, 100); + + fmpz_init(den); + fmpz_mat_init(M, n, n); + fmpz_mat_randrank(M, state, n_randint(state, n), bits); + if (i % 2) + fmpz_mat_randops(M, state, n_randint(state, 2*m*n + 1)); + fmpz_randtest_not_zero(den, state, bits); + fmpq_mat_init(A, n, n); + fmpq_mat_set_fmpz_mat_div_fmpz(A, M, den); + + fmpq_mat_init(B, n, m); + fmpq_mat_randtest(B, state, bits); + fmpq_mat_init(X, n, m); + + success = fmpq_mat_solve_dixon(X, A, B); + + if (success != 0) + { + flint_printf("FAIL!\n"); + flint_printf("Expected success = 0\n"); + fmpq_mat_print(A); + flint_printf("\n"); + abort(); + } + + fmpq_mat_clear(A); + fmpq_mat_clear(B); + fmpq_mat_clear(X); + fmpz_mat_clear(M); + fmpz_clear(den); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_mat/test/t-solve_fraction_free.c b/external/flint-2.4.3/fmpq_mat/test/t-solve_fraction_free.c new file mode 100644 index 0000000..86235a1 --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/test/t-solve_fraction_free.c @@ -0,0 +1,143 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpq.h" +#include "fmpq_mat.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("solve_fraction_free...."); + fflush(stdout); + + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_mat_t A, B, X, AX; + fmpq_t d; + int success; + + slong n, m, bits; + + n = n_randint(state, 10); + m = n_randint(state, 10); + bits = 1 + n_randint(state, 100); + + fmpq_mat_init(A, n, n); + fmpq_mat_init(B, n, m); + fmpq_mat_init(X, n, m); + fmpq_mat_init(AX, n, m); + + fmpq_init(d); + /* XXX: replace with a randtest function */ + do { + fmpq_mat_randtest(A, state, bits); + fmpq_mat_det(d, A); + } while (fmpq_is_zero(d)); + fmpq_clear(d); + + fmpq_mat_randtest(B, state, bits); + + success = fmpq_mat_solve_fraction_free(X, A, B); + fmpq_mat_mul(AX, A, X); + + if (!fmpq_mat_equal(AX, B) || !success) + { + flint_printf("FAIL!\n"); + flint_printf("success: %d\n", success); + flint_printf("A:\n"); + fmpq_mat_print(A); + flint_printf("B:\n"); + fmpq_mat_print(B); + flint_printf("X:\n"); + fmpq_mat_print(X); + flint_printf("AX:\n"); + fmpq_mat_print(AX); + abort(); + } + + fmpq_mat_clear(A); + fmpq_mat_clear(B); + fmpq_mat_clear(X); + fmpq_mat_clear(AX); + } + + /* Check singular systems */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_mat_t A, B, X; + fmpz_mat_t M; + fmpz_t den; + slong n, m, bits; + int success; + + n = 1 + n_randint(state, 10); + m = 1 + n_randint(state, 10); + bits = 1 + n_randint(state, 100); + + fmpz_init(den); + fmpz_mat_init(M, n, n); + fmpz_mat_randrank(M, state, n_randint(state, n), bits); + if (i % 2) + fmpz_mat_randops(M, state, n_randint(state, 2*m*n + 1)); + fmpz_randtest_not_zero(den, state, bits); + fmpq_mat_init(A, n, n); + fmpq_mat_set_fmpz_mat_div_fmpz(A, M, den); + + fmpq_mat_init(B, n, m); + fmpq_mat_randtest(B, state, bits); + fmpq_mat_init(X, n, m); + + success = fmpq_mat_solve_fraction_free(X, A, B); + + if (success != 0) + { + flint_printf("FAIL!\n"); + flint_printf("Expected success = 0\n"); + fmpq_mat_print(A); + flint_printf("\n"); + abort(); + } + + fmpq_mat_clear(A); + fmpq_mat_clear(B); + fmpq_mat_clear(X); + fmpz_mat_clear(M); + fmpz_clear(den); + } + + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_mat/test/t-sub.c b/external/flint-2.4.3/fmpq_mat/test/t-sub.c new file mode 100644 index 0000000..de13088 --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/test/t-sub.c @@ -0,0 +1,173 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpq.h" +#include "fmpq_mat.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("sub...."); + fflush(stdout); + + /* Aliasing, B = B - C */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_mat_t A, B, C; + + slong m, n, bits; + + m = n_randint(state, 10); + n = n_randint(state, 10); + + bits = 1 + n_randint(state, 100); + + fmpq_mat_init(A, m, n); + fmpq_mat_init(B, m, n); + fmpq_mat_init(C, m, n); + + fmpq_mat_randtest(B, state, bits); + fmpq_mat_randtest(C, state, bits); + + fmpq_mat_sub(A, B, C); + fmpq_mat_sub(B, B, C); + + result = fmpq_mat_equal(A, B); + if (!result) + { + flint_printf("FAIL (B = B - C):\n"); + flint_printf("A:\n"); + fmpq_mat_print(A); + flint_printf("B:\n"); + fmpq_mat_print(B); + flint_printf("C:\n"); + fmpq_mat_print(C); + abort(); + } + + fmpq_mat_clear(A); + fmpq_mat_clear(B); + fmpq_mat_clear(C); + } + + /* Aliasing, C = B - C */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_mat_t A, B, C; + + slong m, n, bits; + + m = n_randint(state, 10); + n = n_randint(state, 10); + + bits = 1 + n_randint(state, 100); + + fmpq_mat_init(A, m, n); + fmpq_mat_init(B, m, n); + fmpq_mat_init(C, m, n); + + fmpq_mat_randtest(B, state, bits); + fmpq_mat_randtest(C, state, bits); + + fmpq_mat_sub(A, B, C); + fmpq_mat_sub(C, B, C); + + result = fmpq_mat_equal(A, C); + if (!result) + { + flint_printf("FAIL (C = B - C):\n"); + flint_printf("A:\n"); + fmpq_mat_print(A); + flint_printf("B:\n"); + fmpq_mat_print(B); + flint_printf("C:\n"); + fmpq_mat_print(C); + abort(); + } + + fmpq_mat_clear(A); + fmpq_mat_clear(B); + fmpq_mat_clear(C); + } + + /* A - B == -(B - A) */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_mat_t A, B, C, D; + + slong m, n, bits; + + m = n_randint(state, 10); + n = n_randint(state, 10); + + bits = 1 + n_randint(state, 100); + + fmpq_mat_init(A, m, n); + fmpq_mat_init(B, m, n); + fmpq_mat_init(C, m, n); + fmpq_mat_init(D, m, n); + + fmpq_mat_randtest(A, state, bits); + fmpq_mat_randtest(B, state, bits); + + fmpq_mat_sub(C, A, B); + fmpq_mat_sub(D, B, A); + fmpq_mat_neg(D, D); + + result = fmpq_mat_equal(C, D); + if (!result) + { + flint_printf("FAIL (A + B == B + A):\n"); + flint_printf("A:\n"); + fmpq_mat_print(A); + flint_printf("B:\n"); + fmpq_mat_print(B); + flint_printf("C:\n"); + fmpq_mat_print(C); + flint_printf("D:\n"); + fmpq_mat_print(D); + abort(); + } + + fmpq_mat_clear(A); + fmpq_mat_clear(B); + fmpq_mat_clear(C); + fmpq_mat_clear(D); + } + + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fmpq_mat/test/t-trace.c b/external/flint-2.4.3/fmpq_mat/test/t-trace.c new file mode 100644 index 0000000..9302bb2 --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/test/t-trace.c @@ -0,0 +1,96 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpq.h" +#include "fmpq_mat.h" +#include "ulong_extras.h" + +int +main(void) +{ + slong i; + FLINT_TEST_INIT(state); + + flint_printf("trace...."); + fflush(stdout); + + + + /* Test trace(AB) = trace(BA) */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_mat_t A, B, AB, BA; + fmpq_t trab, trba; + slong m, n; + + m = n_randint(state, 10); + n = n_randint(state, 10); + + fmpq_mat_init(A, m, n); + fmpq_mat_init(B, n, m); + fmpq_mat_init(AB, m, m); + fmpq_mat_init(BA, n, n); + + fmpq_init(trab); + fmpq_init(trba); + + fmpq_mat_randtest(A, state, 1 + n_randint(state, 100)); + fmpq_mat_randtest(B, state, 1 + n_randint(state, 100)); + + fmpq_mat_mul(AB, A, B); + fmpq_mat_mul(BA, B, A); + + fmpq_mat_trace(trab, AB); + fmpq_mat_trace(trba, BA); + + if (!fmpq_equal(trab, trba)) + { + flint_printf("FAIL:\n"); + fmpq_mat_print(A), flint_printf("\n"); + fmpq_mat_print(B), flint_printf("\n"); + fmpq_mat_print(AB), flint_printf("\n"); + fmpq_mat_print(BA), flint_printf("\n"); + flint_printf("tr(AB): "), fmpq_print(trab), flint_printf("\n"); + flint_printf("tr(BA): "), fmpq_print(trba), flint_printf("\n"); + abort(); + } + + fmpq_mat_clear(A); + fmpq_mat_clear(B); + fmpq_mat_clear(AB); + fmpq_mat_clear(BA); + fmpq_clear(trab); + fmpq_clear(trba); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_mat/test/t-transpose.c b/external/flint-2.4.3/fmpq_mat/test/t-transpose.c new file mode 100644 index 0000000..1123af4 --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/test/t-transpose.c @@ -0,0 +1,124 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpq.h" +#include "fmpq_mat.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("transpose...."); + fflush(stdout); + + /* Aliasing, B = B^t */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_mat_t A, B, C; + + slong m, n, bits; + + m = n_randint(state, 10); + n = m; + + bits = 1 + n_randint(state, 100); + + fmpq_mat_init(A, m, n); + fmpq_mat_init(B, m, n); + fmpq_mat_init(C, m, n); + + fmpq_mat_randtest(A, state, bits); + fmpq_mat_set(B, A); + + fmpq_mat_transpose(C, B); + fmpq_mat_transpose(B, B); + + result = fmpq_mat_equal(B, C); + if (!result) + { + flint_printf("FAIL (B = B^t):\n"); + flint_printf("A:\n"); + fmpq_mat_print(A); + flint_printf("B:\n"); + fmpq_mat_print(B); + flint_printf("C:\n"); + fmpq_mat_print(C); + abort(); + } + + fmpq_mat_clear(A); + fmpq_mat_clear(B); + fmpq_mat_clear(C); + } + + /* ((B^t)^t) == B */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_mat_t A, B; + + slong m, n, bits; + + m = n_randint(state, 10); + n = m; + + bits = 1 + n_randint(state, 100); + + fmpq_mat_init(A, m, n); + fmpq_mat_init(B, m, n); + + fmpq_mat_randtest(A, state, bits); + + fmpq_mat_transpose(B, A); + fmpq_mat_transpose(B, B); + + result = fmpq_mat_equal(A, B); + if (!result) + { + flint_printf("FAIL ((B^t)^t == B):\n"); + flint_printf("A:\n"); + fmpq_mat_print(A); + flint_printf("B:\n"); + fmpq_mat_print(B); + abort(); + } + + fmpq_mat_clear(A); + fmpq_mat_clear(B); + } + + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/fmpq_mat/trace.c b/external/flint-2.4.3/fmpq_mat/trace.c new file mode 100644 index 0000000..09e1c32 --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/trace.c @@ -0,0 +1,41 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq_mat.h" + +void +fmpq_mat_trace(fmpq_t trace, const fmpq_mat_t mat) +{ + slong i, n = fmpq_mat_nrows(mat); + + if (n == 0) + fmpq_zero(trace); + else + { + fmpq_set(trace, fmpq_mat_entry(mat, 0, 0)); + for (i = 1; i < n; i++) + fmpq_add(trace, trace, fmpq_mat_entry(mat, i, i)); + } +} diff --git a/external/flint-2.4.3/fmpq_mat/transpose.c b/external/flint-2.4.3/fmpq_mat/transpose.c new file mode 100644 index 0000000..5be6c25 --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/transpose.c @@ -0,0 +1,47 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpq_mat.h" + +void fmpq_mat_transpose(fmpq_mat_t rop, const fmpq_mat_t op) +{ + slong i, j; + + if (rop == op) + { + for (i = 0; i < rop->r; i++) + for (j = 0; j < i; j++) + fmpq_swap(fmpq_mat_entry(rop, i, j), + fmpq_mat_entry(rop, j, i)); + } + else + { + for (i = 0; i < rop->r; i++) + for (j = 0; j < rop->c; j++) + fmpq_set(fmpq_mat_entry(rop, i, j), + fmpq_mat_entry(op, j, i)); + } +} + diff --git a/external/flint-2.4.3/fmpq_mat/zero.c b/external/flint-2.4.3/fmpq_mat/zero.c new file mode 100644 index 0000000..c4973ad --- /dev/null +++ b/external/flint-2.4.3/fmpq_mat/zero.c @@ -0,0 +1,35 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpq_mat.h" + +void fmpq_mat_zero(fmpq_mat_t mat) +{ + slong i, j; + + for (i = 0; i < mat->r; i++) + for (j = 0; j < mat->c; j++) + fmpq_zero(fmpq_mat_entry(mat, i, j)); +} diff --git a/external/flint-2.4.3/fmpq_matxx.h b/external/flint-2.4.3/fmpq_matxx.h new file mode 100644 index 0000000..e9fe2f8 --- /dev/null +++ b/external/flint-2.4.3/fmpq_matxx.h @@ -0,0 +1,478 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#ifndef FMPQ_MATXX_H +#define FMPQ_MATXX_H FMPQ_MATXX_H + +#include "fmpq_mat.h" + +#include "fmpqxx.h" +#include "fmpz_matxx.h" +#include "fmpz_vecxx.h" + +#include "flintxx/ltuple.h" +#include "flintxx/matrix.h" + +// TODO wrap entry_num, entry_den? +// TODO numden_rowwise_2 +// TODO rref members + +namespace flint { +FLINT_DEFINE_BINOP(hilbert_matrix) +FLINT_DEFINE_BINOP(mul_direct) +FLINT_DEFINE_BINOP(mul_cleared) +FLINT_DEFINE_BINOP(solve_fraction_free) + +FLINT_DEFINE_UNOP(numden_colwise) +FLINT_DEFINE_UNOP(numden_entrywise) +FLINT_DEFINE_UNOP(numden_matwise) +FLINT_DEFINE_UNOP(numden_rowwise) +FLINT_DEFINE_UNOP(num_rowwise) +FLINT_DEFINE_UNOP(num_colwise) + +FLINT_DEFINE_UNOP(rref_classical) +FLINT_DEFINE_UNOP(rref_fraction_free) + +namespace detail { +template +struct fmpq_matxx_traits : matrices::generic_traits { }; + +typedef make_ltuple::type>::type + fmpq_matxx_numden_entrywise_rt; +typedef make_ltuple::type>::type + fmpq_matxx_numden_matwise_rt; +typedef make_ltuple::type>::type + fmpq_matxx_numden_rowwise_rt; +typedef fmpq_matxx_numden_rowwise_rt fmpq_matxx_numden_colwise_rt; +} // detail + +template +class fmpq_matxx_expression + : public expression, Operation, Data> +{ +public: + typedef expression, + Operation, Data> base_t; + typedef detail::fmpq_matxx_traits traits_t; + + FLINTXX_DEFINE_BASICS(fmpq_matxx_expression) + FLINTXX_DEFINE_CTORS(fmpq_matxx_expression) + FLINTXX_DEFINE_C_REF(fmpq_matxx_expression, fmpq_mat_struct, _mat) + + template + static evaluated_t create_temporary_rowscols( + const Expr&, slong rows, slong cols) + { + return evaluated_t(rows, cols); + } + FLINTXX_DEFINE_MATRIX_METHODS(traits_t) + + template + static fmpq_matxx_expression reconstruct(const Fmpz_mat& mat, const Fmpz& mod, + typename mp::enable_if >::type* = 0, + typename mp::enable_if >::type* = 0) + { + fmpq_matxx_expression res(mat.rows(), mat.cols()); + res.set_reconstruct(mat, mod); + return res; + } + template + static fmpq_matxx_expression frac(const Fmpz_mat& num, const Fmpz& den, + typename mp::enable_if >::type* = 0, + typename mp::enable_if >::type* = 0) + { + fmpq_matxx_expression res(num.rows(), num.cols()); + res.set_frac(num, den); + return res; + } + template + static fmpq_matxx_expression integer_matrix(const Fmpz_mat& mat, + typename mp::enable_if >::type* = 0) + { + fmpq_matxx_expression res(mat.rows(), mat.cols()); + res = mat; + return res; + } + + static fmpq_matxx_expression randbits(slong rows, slong cols, + frandxx& state, mp_bitcnt_t bits) + { + fmpq_matxx_expression res(rows, cols); + res.set_randbits(state, bits); + return res; + } + static fmpq_matxx_expression randtest(slong rows, slong cols, + frandxx& state, mp_bitcnt_t bits) + { + fmpq_matxx_expression res(rows, cols); + res.set_randtest(state, bits); + return res; + } + + static fmpq_matxx_expression zero(slong rows, slong cols) + {return fmpq_matxx_expression(rows, cols);} + static fmpq_matxx_expression one(slong rows, slong cols) + { + fmpq_matxx_expression res(rows, cols); + res.set_one(); + return res; + } + + // these only make sense with targets + void set_randbits(frandxx& state, mp_bitcnt_t bits) + {fmpq_mat_randbits(_mat(), state._data(), bits);} + void set_randtest(frandxx& state, mp_bitcnt_t bits) + {fmpq_mat_randtest(_mat(), state._data(), bits);} + void set_hilbert_matrix() + {fmpq_mat_hilbert_matrix(_mat());} + void set_zero() + {fmpq_mat_zero(_mat());} + void set_one() + {fmpq_mat_one(_mat());} + + template + void set_frac(const Fmpz_mat& num, const Fmpz& den, + typename mp::enable_if >::type* = 0, + typename mp::enable_if >::type* = 0) + { + fmpq_mat_set_fmpz_mat_div_fmpz(num.evaluate()._mat(), + den.evaluate()._fmpz()); + } + template + void set_reconstruct(const Fmpz_mat& mat, const Fmpz& mod, + typename mp::enable_if >::type* = 0, + typename mp::enable_if >::type* = 0) + { + execution_check(fmpq_mat_set_fmpz_mat_mod_fmpz( + _mat(), mat.evaluate()._mat(), mod.evaluate()._fmpz()), + "reconstruct", "fmpq_matxx"); + } + + bool pivot(slong r, slong c, permxx* perm = 0) + {return fmpq_mat_pivot(maybe_perm_data(perm), _mat(), r, c);} + + // these cause evaluation + slong rank() const {return fmpq_mat_rank(this->evaluate()._mat());} + bool is_zero() const {return fmpq_mat_is_zero(this->evaluate()._mat());} + bool is_empty() const {return fmpq_mat_is_empty(this->evaluate()._mat());} + bool is_square() const {return fmpq_mat_is_square(this->evaluate()._mat());} + bool is_integral() const + {return fmpq_mat_is_integral(this->evaluate()._mat());} + + // forwarded lazy ops + FLINTXX_DEFINE_MEMBER_UNOP(inv) + FLINTXX_DEFINE_MEMBER_UNOP(transpose) + FLINTXX_DEFINE_MEMBER_UNOP_RTYPE(fmpqxx, det) + FLINTXX_DEFINE_MEMBER_UNOP_RTYPE(fmpqxx, trace) + + FLINTXX_DEFINE_MEMBER_UNOP_RTYPE(detail::fmpq_matxx_numden_entrywise_rt, + numden_entrywise) + FLINTXX_DEFINE_MEMBER_UNOP_RTYPE(detail::fmpq_matxx_numden_matwise_rt, + numden_matwise) + FLINTXX_DEFINE_MEMBER_UNOP_RTYPE(detail::fmpq_matxx_numden_rowwise_rt, + numden_rowwise) + FLINTXX_DEFINE_MEMBER_UNOP_RTYPE(detail::fmpq_matxx_numden_colwise_rt, + numden_colwise) + FLINTXX_DEFINE_MEMBER_UNOP_RTYPE_(fmpz_matxx, num_rowwise, + num_rowwise) + FLINTXX_DEFINE_MEMBER_UNOP_RTYPE_(fmpz_matxx, num_colwise, + num_colwise) + + FLINTXX_DEFINE_MEMBER_BINOP(mul_cleared) + FLINTXX_DEFINE_MEMBER_BINOP(mul_direct) + FLINTXX_DEFINE_MEMBER_BINOP(solve_dixon) + FLINTXX_DEFINE_MEMBER_BINOP(solve_fraction_free) +}; + +namespace detail { +struct fmpq_mat_data; +} // detail + +typedef fmpq_matxx_expression fmpq_matxx; +typedef fmpq_matxx_expression > fmpq_matxx_ref; +typedef fmpq_matxx_expression > fmpq_matxx_srcref; + +template<> +struct matrix_traits +{ + template static slong rows(const M& m) + { + return fmpq_mat_nrows(m._mat()); + } + template static slong cols(const M& m) + { + return fmpq_mat_ncols(m._mat()); + } + + template static fmpqxx_srcref at(const M& m, slong i, slong j) + { + return fmpqxx_srcref::make(fmpq_mat_entry(m._mat(), i, j)); + } + template static fmpqxx_ref at(M& m, slong i, slong j) + { + return fmpqxx_ref::make(fmpq_mat_entry(m._mat(), i, j)); + } +}; + +namespace detail { +template<> +struct fmpq_matxx_traits + : matrices::generic_traits_srcref { }; +template<> +struct fmpq_matxx_traits + : matrices::generic_traits_ref { }; +template<> struct fmpq_matxx_traits + : matrices::generic_traits_nonref { }; + +struct fmpq_mat_data +{ + typedef fmpq_mat_t& data_ref_t; + typedef const fmpq_mat_t& data_srcref_t; + + fmpq_mat_t inner; + + fmpq_mat_data(slong m, slong n) + { + fmpq_mat_init(inner, m, n); + } + + fmpq_mat_data(const fmpq_mat_data& o) + { + fmpq_mat_init(inner, fmpq_mat_nrows(o.inner), fmpq_mat_ncols(o.inner)); + fmpq_mat_set(inner, o.inner); + } + + fmpq_mat_data(fmpq_matxx_srcref o) + { + fmpq_mat_init(inner, o.rows(), o.cols()); + fmpq_mat_set(inner, o._data().inner); + } + + ~fmpq_mat_data() {fmpq_mat_clear(inner);} +}; +} // detail + +#define FMPQ_MATXX_COND_S FLINTXX_COND_S(fmpq_matxx) +#define FMPQ_MATXX_COND_T FLINTXX_COND_T(fmpq_matxx) + +namespace traits { +template struct is_fmpq_matxx + : flint_classes::is_Base { }; +} // traits +namespace mp { +template +struct all_fmpq_matxx : mp::and_, all_fmpq_matxx > { }; +template +struct all_fmpq_matxx : traits::is_fmpq_matxx { }; + +template +struct enable_all_fmpq_matxx + : mp::enable_if, Out> { }; +} // mp + +namespace matrices { +template<> +struct outsize + : outsize { }; +template<> +struct outsize + : outsize { }; + +template<> struct outsize + : outsize { }; + +template<> +struct outsize +{ + template + static slong rows(const Expr& e) {return e._data().first();} + template + static slong cols(const Expr& e) {return e._data().second();} +}; + +template<> +struct outsize +{ + template + static slong rows(const Expr& e) {return e._data().first().rows();} + template + static slong cols(const Expr& e) {return e._data().first().cols();} +}; +template<> struct outsize + : outsize { }; +template<> struct outsize + : outsize { }; +template<> struct outsize + : outsize { }; +template<> struct outsize + : outsize { }; +template<> struct outsize + : outsize { }; +} // matrices + +namespace vectors { +template<> +struct outsize +{ + template + static unsigned get(const Expr& e) + { + return e._data().first().rows(); + } +}; +template<> +struct outsize +{ + template + static unsigned get(const Expr& e) + { + return e._data().first().cols(); + } +}; +} // vectors + +// temporary instantiation stuff +FLINTXX_DEFINE_TEMPORARY_RULES(fmpq_matxx) + +namespace rules { +FLINT_DEFINE_DOIT_COND2(assignment, FMPQ_MATXX_COND_T, FMPQ_MATXX_COND_S, + fmpq_mat_set(to._mat(), from._mat())) +FLINT_DEFINE_DOIT_COND2(assignment, FMPQ_MATXX_COND_T, FMPZ_MATXX_COND_S, + fmpq_mat_set_fmpz_mat(to._mat(), from._mat())) + +FLINTXX_DEFINE_SWAP(fmpq_matxx, fmpq_mat_swap(e1._mat(), e2._mat())) + +FLINTXX_DEFINE_EQUALS(fmpq_matxx, fmpq_mat_equal(e1._mat(), e2._mat())) + +FLINT_DEFINE_PRINT_COND(FMPQ_MATXX_COND_S, (fmpq_mat_print(from._mat()), 1)) + +FLINT_DEFINE_BINARY_EXPR_COND2(times, fmpq_matxx, + FMPQ_MATXX_COND_S, FMPQ_MATXX_COND_S, + fmpq_mat_mul(to._mat(), e1._mat(), e2._mat())) +FLINT_DEFINE_BINARY_EXPR_COND2(times, fmpq_matxx, + FMPZ_MATXX_COND_S, FMPQ_MATXX_COND_S, + fmpq_mat_mul_r_fmpz_mat(to._mat(), e1._mat(), e2._mat())) +FLINT_DEFINE_BINARY_EXPR_COND2(times, fmpq_matxx, + FMPQ_MATXX_COND_S, FMPZ_MATXX_COND_S, + fmpq_mat_mul_fmpz_mat(to._mat(), e1._mat(), e2._mat())) +FLINT_DEFINE_CBINARY_EXPR_COND2(times, fmpq_matxx, + FMPQ_MATXX_COND_S, FMPZXX_COND_S, + fmpq_mat_scalar_mul_fmpz(to._mat(), e1._mat(), e2._fmpz())) +FLINT_DEFINE_BINARY_EXPR_COND2(divided_by, fmpq_matxx, + FMPQ_MATXX_COND_S, FMPZXX_COND_S, + fmpq_mat_scalar_div_fmpz(to._mat(), e1._mat(), e2._fmpz())) +FLINT_DEFINE_BINARY_EXPR_COND2(mul_direct_op, fmpq_matxx, + FMPQ_MATXX_COND_S, FMPQ_MATXX_COND_S, + fmpq_mat_mul_direct(to._mat(), e1._mat(), e2._mat())) +FLINT_DEFINE_BINARY_EXPR_COND2(mul_cleared_op, fmpq_matxx, + FMPQ_MATXX_COND_S, FMPQ_MATXX_COND_S, + fmpq_mat_mul_cleared(to._mat(), e1._mat(), e2._mat())) + +FLINT_DEFINE_BINARY_EXPR_COND2(plus, fmpq_matxx, + FMPQ_MATXX_COND_S, FMPQ_MATXX_COND_S, + fmpq_mat_add(to._mat(), e1._mat(), e2._mat())) +FLINT_DEFINE_BINARY_EXPR_COND2(minus, fmpq_matxx, + FMPQ_MATXX_COND_S, FMPQ_MATXX_COND_S, + fmpq_mat_sub(to._mat(), e1._mat(), e2._mat())) + +FLINT_DEFINE_UNARY_EXPR_COND(negate, fmpq_matxx, FMPQ_MATXX_COND_S, + fmpq_mat_neg(to._mat(), from._mat())) + +FLINT_DEFINE_UNARY_EXPR_COND(transpose_op, fmpq_matxx, FMPQ_MATXX_COND_S, + fmpq_mat_transpose(to._mat(), from._mat())) +FLINT_DEFINE_UNARY_EXPR_COND(trace_op, fmpqxx, FMPQ_MATXX_COND_S, + fmpq_mat_trace(to._fmpq(), from._mat())) + +FLINT_DEFINE_THREEARY_EXPR_COND3(mat_at_op, fmpqxx, + FMPQ_MATXX_COND_S, traits::fits_into_slong, traits::fits_into_slong, + fmpq_set(to._fmpq(), fmpq_mat_entry(e1._mat(), e2, e3))) + +FLINT_DEFINE_BINARY_EXPR_COND2(hilbert_matrix_op, fmpq_matxx, + traits::fits_into_slong, traits::fits_into_slong, + to.set_hilbert_matrix()) + +FLINT_DEFINE_UNARY_EXPR_COND(det_op, fmpqxx, FMPQ_MATXX_COND_S, + fmpq_mat_det(to._fmpq(), from._mat())) + +FLINT_DEFINE_BINARY_EXPR_COND2(solve_fraction_free_op, fmpq_matxx, + FMPQ_MATXX_COND_S, FMPQ_MATXX_COND_S, + execution_check(fmpq_mat_solve_fraction_free( + to._mat(), e1._mat(), e2._mat()), + "solve", "fmpq_mat")) +FLINT_DEFINE_BINARY_EXPR_COND2(solve_dixon_op, fmpq_matxx, + FMPQ_MATXX_COND_S, FMPQ_MATXX_COND_S, + execution_check(fmpq_mat_solve_dixon(to._mat(), e1._mat(), e2._mat()), + "solve", "fmpq_mat")) +FLINT_DEFINE_UNARY_EXPR_COND(inv_op, fmpq_matxx, FMPQ_MATXX_COND_S, + execution_check(fmpq_mat_inv(to._mat(), from._mat()), + "inv", "fmpq_mat")) + +FLINT_DEFINE_UNARY_EXPR_COND(num_rowwise_op, fmpz_matxx, + FMPQ_MATXX_COND_S, + fmpq_mat_get_fmpz_mat_rowwise(to._mat(), 0, from._mat())) +FLINT_DEFINE_UNARY_EXPR_COND(num_colwise_op, fmpz_matxx, + FMPQ_MATXX_COND_S, + fmpq_mat_get_fmpz_mat_colwise(to._mat(), 0, from._mat())) +FLINT_DEFINE_UNARY_EXPR_COND(numden_entrywise_op, + detail::fmpq_matxx_numden_entrywise_rt, FMPQ_MATXX_COND_S, + fmpq_mat_get_fmpz_mat_entrywise(to.template get<0>()._mat(), + to.template get<1>()._mat(), from._mat())) +FLINT_DEFINE_UNARY_EXPR_COND(numden_matwise_op, + detail::fmpq_matxx_numden_matwise_rt, FMPQ_MATXX_COND_S, + fmpq_mat_get_fmpz_mat_matwise(to.template get<0>()._mat(), + to.template get<1>()._fmpz(), from._mat())) +FLINT_DEFINE_UNARY_EXPR_COND(numden_rowwise_op, + detail::fmpq_matxx_numden_rowwise_rt, FMPQ_MATXX_COND_S, + fmpq_mat_get_fmpz_mat_rowwise(to.template get<0>()._mat(), + to.template get<1>()._array(), from._mat())) +FLINT_DEFINE_UNARY_EXPR_COND(numden_colwise_op, + detail::fmpq_matxx_numden_colwise_rt, FMPQ_MATXX_COND_S, + fmpq_mat_get_fmpz_mat_colwise(to.template get<0>()._mat(), + to.template get<1>()._array(), from._mat())) + +namespace rdetail { +typedef make_ltuple::type>::type + fmpq_matxx_rref_rt; +} + +FLINT_DEFINE_UNARY_EXPR_COND(rref_op, rdetail::fmpq_matxx_rref_rt, + FMPQ_MATXX_COND_S, + to.template get<0>() = + fmpq_mat_rref(to.template get<1>()._mat(), from._mat())) +FLINT_DEFINE_UNARY_EXPR_COND(rref_classical_op, rdetail::fmpq_matxx_rref_rt, + FMPQ_MATXX_COND_S, + to.template get<0>() = + fmpq_mat_rref_classical(to.template get<1>()._mat(), from._mat())) +FLINT_DEFINE_UNARY_EXPR_COND(rref_fraction_free_op, rdetail::fmpq_matxx_rref_rt, + FMPQ_MATXX_COND_S, + to.template get<0>() = + fmpq_mat_rref_fraction_free(to.template get<1>()._mat(), from._mat())) +} // rules +} // flint + +#endif + diff --git a/external/flint-2.4.3/fmpq_poly.h b/external/flint-2.4.3/fmpq_poly.h new file mode 100644 index 0000000..b5e8bce --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly.h @@ -0,0 +1,737 @@ +/*============================================================================ + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 William Hart + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#ifndef FMPQ_POLY_H +#define FMPQ_POLY_H + +#include +#include "fmpz.h" +#include "fmpq.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" +#include "flint.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/* Type definitions ********************************************************/ + +typedef struct +{ + fmpz * coeffs; + fmpz_t den; + slong alloc; + slong length; +} fmpq_poly_struct; + +typedef fmpq_poly_struct fmpq_poly_t[1]; + +typedef struct +{ + fmpq_poly_struct * powers; + slong len; +} fmpq_poly_powers_precomp_struct; + +typedef fmpq_poly_powers_precomp_struct fmpq_poly_powers_precomp_t[1]; + +#define WEAK_CANONICALISE_CUTOFF 25600 + +/* Memory management *******************************************************/ + +void fmpq_poly_init(fmpq_poly_t poly); + +void fmpq_poly_init2(fmpq_poly_t poly, slong alloc); + +void fmpq_poly_realloc(fmpq_poly_t poly, slong alloc); + +void fmpq_poly_fit_length(fmpq_poly_t poly, slong len); + +void _fmpq_poly_set_length(fmpq_poly_t poly, slong len); + +void fmpq_poly_clear(fmpq_poly_t poly); + +void _fmpq_poly_normalise(fmpq_poly_t poly); + +/* Accessing numerator and denominator *************************************/ + +#define fmpq_poly_numref(poly) ((poly)->coeffs) + +#define fmpq_poly_denref(poly) ((poly)->den) + +static __inline__ void +fmpq_poly_get_numerator(fmpz_poly_t res, const fmpq_poly_t poly) +{ + fmpz_poly_fit_length(res, poly->length); + _fmpz_vec_set(res->coeffs, poly->coeffs, poly->length); + _fmpz_poly_set_length(res, poly->length); +} + +/* Canonicalisation *************************************/ + +void _fmpq_poly_canonicalise(fmpz * rpoly, fmpz_t den, slong len); + +void fmpq_poly_canonicalise(fmpq_poly_t poly); + +int _fmpq_poly_is_canonical(const fmpz * poly, const fmpz_t den, slong len); + +int fmpq_poly_is_canonical(const fmpq_poly_t poly); + +/* Polynomial parameters ***************************************************/ + +static __inline__ +slong fmpq_poly_degree(const fmpq_poly_t poly) +{ + return poly->length - 1; +} + +static __inline__ +slong fmpq_poly_length(const fmpq_poly_t poly) +{ + return poly->length; +} + +/* Randomisation ***********************************************************/ + +void fmpq_poly_randtest(fmpq_poly_t f, flint_rand_t state, + slong len, mp_bitcnt_t bits_in); + +void fmpq_poly_randtest_unsigned(fmpq_poly_t f, flint_rand_t state, + slong len, mp_bitcnt_t bits_in); + +void fmpq_poly_randtest_not_zero(fmpq_poly_t f, flint_rand_t state, + slong len, mp_bitcnt_t bits_in); + +/* Assignment and basic manipulation ***************************************/ + +void fmpq_poly_set(fmpq_poly_t poly1, const fmpq_poly_t poly2); + +void fmpq_poly_set_si(fmpq_poly_t poly, slong x); + +void fmpq_poly_set_ui(fmpq_poly_t poly, ulong x); + +void fmpq_poly_set_fmpz(fmpq_poly_t poly, const fmpz_t x); + +void fmpq_poly_set_fmpq(fmpq_poly_t poly, const fmpq_t x); + +void fmpq_poly_set_mpz(fmpq_poly_t poly, const mpz_t x); + +void fmpq_poly_set_mpq(fmpq_poly_t poly, const mpq_t x); + +void fmpq_poly_set_fmpz_poly(fmpq_poly_t rop, const fmpz_poly_t op); + +void _fmpq_poly_set_array_mpq(fmpz * poly, fmpz_t den, const mpq_t * a, slong n); + +void fmpq_poly_set_array_mpq(fmpq_poly_t poly, const mpq_t * a, slong n); + +int _fmpq_poly_set_str(fmpz * poly, fmpz_t den, const char * str); + +int fmpq_poly_set_str(fmpq_poly_t poly, const char * str); + +char * fmpq_poly_get_str(const fmpq_poly_t poly); + +char * fmpq_poly_get_str_pretty(const fmpq_poly_t poly, const char * var); + +void fmpq_poly_zero(fmpq_poly_t poly); + +static __inline__ void fmpq_poly_one(fmpq_poly_t poly) +{ + fmpq_poly_fit_length(poly, 1); + _fmpq_poly_set_length(poly, 1); + fmpz_one(poly->coeffs); + fmpz_one(poly->den); +} + +void fmpq_poly_neg(fmpq_poly_t poly1, const fmpq_poly_t poly2); + +void fmpq_poly_inv(fmpq_poly_t poly1, const fmpq_poly_t poly2); + +void fmpq_poly_swap(fmpq_poly_t poly1, fmpq_poly_t poly2); + +static __inline__ +void fmpq_poly_truncate(fmpq_poly_t poly, slong n) +{ + if (poly->length > n) + { + slong i; + for (i = n; i < poly->length; i++) + _fmpz_demote(poly->coeffs + i); + poly->length = n; + fmpq_poly_canonicalise(poly); + } +} + +void fmpq_poly_get_slice(fmpq_poly_t rop, + const fmpq_poly_t op, slong i, slong j); + +void fmpq_poly_reverse(fmpq_poly_t res, const fmpq_poly_t poly, slong n); + +/* Getting and setting coefficients ****************************************/ + +void fmpq_poly_get_coeff_fmpq(fmpq_t x, const fmpq_poly_t poly, slong n); + +void fmpq_poly_get_coeff_mpq(mpq_t x, const fmpq_poly_t poly, slong n); + +void fmpq_poly_set_coeff_si(fmpq_poly_t poly, slong n, slong x); + +void fmpq_poly_set_coeff_ui(fmpq_poly_t poly, slong n, ulong x); + +void fmpq_poly_set_coeff_fmpz(fmpq_poly_t poly, slong n, const fmpz_t x); + +void fmpq_poly_set_coeff_fmpq(fmpq_poly_t poly, slong n, const fmpq_t x); + +void fmpq_poly_set_coeff_mpz(fmpq_poly_t poly, slong n, const mpz_t x); + +void fmpq_poly_set_coeff_mpq(fmpq_poly_t poly, slong n, const mpq_t x); + +/* Comparison **************************************************************/ + +int fmpq_poly_equal(const fmpq_poly_t poly1, const fmpq_poly_t poly2); + +int fmpq_poly_cmp(const fmpq_poly_t left, const fmpq_poly_t right); + +static __inline__ +int fmpq_poly_is_zero(const fmpq_poly_t poly) +{ + return poly->length == WORD(0); +} + +static __inline__ +int fmpq_poly_is_one(const fmpq_poly_t poly) +{ + return (poly->length == WORD(1)) && (fmpz_equal(poly->coeffs, poly->den)); +} + +/* Addition and subtraction ************************************************/ + +void _fmpq_poly_add(fmpz * rpoly, fmpz_t rden, + const fmpz * poly1, const fmpz_t den1, slong len1, + const fmpz * poly2, const fmpz_t den2, slong len2); + +void fmpq_poly_add(fmpq_poly_t res, + const fmpq_poly_t poly1, const fmpq_poly_t poly2); + +void _fmpq_poly_add_can(fmpz * rpoly, fmpz_t rden, + const fmpz * poly1, const fmpz_t den1, slong len1, + const fmpz * poly2, const fmpz_t den2, slong len2, int can); + +void fmpq_poly_add_can(fmpq_poly_t res, + const fmpq_poly_t poly1, const fmpq_poly_t poly2, int can); + +void _fmpq_poly_sub(fmpz * rpoly, fmpz_t rden, + const fmpz * poly1, const fmpz_t den1, slong len1, + const fmpz * poly2, const fmpz_t den2, slong len2); + +void fmpq_poly_sub(fmpq_poly_t res, + const fmpq_poly_t poly1, const fmpq_poly_t poly2); + +void _fmpq_poly_sub_can(fmpz * rpoly, fmpz_t rden, + const fmpz * poly1, const fmpz_t den1, slong len1, + const fmpz * poly2, const fmpz_t den2, slong len2, int can); + +void fmpq_poly_sub_can(fmpq_poly_t res, + const fmpq_poly_t poly1, const fmpq_poly_t poly2, int can); + +/* Scalar multiplication and division **************************************/ + +void _fmpq_poly_scalar_mul_si(fmpz * rpoly, fmpz_t rden, + const fmpz * poly, const fmpz_t den, slong len, slong c); + +void _fmpq_poly_scalar_mul_ui(fmpz * rpoly, fmpz_t rden, + const fmpz * poly, const fmpz_t den, slong len, ulong c); + +void _fmpq_poly_scalar_mul_fmpz(fmpz * rpoly, fmpz_t rden, + const fmpz * poly, const fmpz_t den, slong len, const fmpz_t c); + +void _fmpq_poly_scalar_mul_fmpq(fmpz * rpoly, fmpz_t rden, const fmpz * poly, + const fmpz_t den, slong len, const fmpz_t r, const fmpz_t s); + +void fmpq_poly_scalar_mul_si(fmpq_poly_t rop, const fmpq_poly_t op, slong c); + +void fmpq_poly_scalar_mul_ui(fmpq_poly_t rop, const fmpq_poly_t op, ulong c); + +void fmpq_poly_scalar_mul_fmpz(fmpq_poly_t rop, + const fmpq_poly_t op, const fmpz_t c); + +void fmpq_poly_scalar_mul_fmpq(fmpq_poly_t rop, + const fmpq_poly_t op, const fmpq_t c); + +void fmpq_poly_scalar_mul_mpz(fmpq_poly_t rop, + const fmpq_poly_t op, const mpz_t c); + +void fmpq_poly_scalar_mul_mpq(fmpq_poly_t rop, + const fmpq_poly_t op, const mpq_t c); + +void _fmpq_poly_scalar_div_si(fmpz * rpoly, fmpz_t rden, + const fmpz * poly, const fmpz_t den, slong len, slong c); + +void _fmpq_poly_scalar_div_ui(fmpz * rpoly, fmpz_t rden, + const fmpz * poly, const fmpz_t den, slong len, ulong c); + +void _fmpq_poly_scalar_div_fmpz(fmpz * rpoly, fmpz_t rden, + const fmpz * poly, const fmpz_t den, slong len, const fmpz_t c); + +void _fmpq_poly_scalar_div_fmpq(fmpz * rpoly, fmpz_t rden, const fmpz * poly, + const fmpz_t den, slong len, const fmpz_t r, const fmpz_t s); + +void fmpq_poly_scalar_div_si(fmpq_poly_t rop, const fmpq_poly_t op, slong c); + +void fmpq_poly_scalar_div_ui(fmpq_poly_t rop, const fmpq_poly_t op, ulong c); + +void fmpq_poly_scalar_div_fmpz(fmpq_poly_t rop, + const fmpq_poly_t op, const fmpz_t c); + +void fmpq_poly_scalar_div_fmpq(fmpq_poly_t rop, + const fmpq_poly_t op, const fmpq_t c); + +void fmpq_poly_scalar_div_mpz(fmpq_poly_t rop, + const fmpq_poly_t op, const mpz_t c); + +void fmpq_poly_scalar_div_mpq(fmpq_poly_t rop, + const fmpq_poly_t op, const mpq_t c); + +/* Multiplication **********************************************************/ + +void _fmpq_poly_mul(fmpz * rpoly, fmpz_t rden, + const fmpz * poly1, const fmpz_t den1, slong len1, + const fmpz * poly2, const fmpz_t den2, slong len2); + +void fmpq_poly_mul(fmpq_poly_t res, + const fmpq_poly_t poly1, const fmpq_poly_t poly2); + +void _fmpq_poly_mullow(fmpz * rpoly, fmpz_t rden, + const fmpz * poly1, const fmpz_t den1, slong len1, + const fmpz * poly2, const fmpz_t den2, slong len2, slong n); + +void fmpq_poly_mullow(fmpq_poly_t res, + const fmpq_poly_t poly1, const fmpq_poly_t poly2, slong n); + +static __inline__ +void fmpq_poly_addmul(fmpq_poly_t rop, const fmpq_poly_t op1, const fmpq_poly_t op2) +{ + fmpq_poly_t t; + + fmpq_poly_init(t); + fmpq_poly_mul(t, op1, op2); + fmpq_poly_add(rop, rop, t); + fmpq_poly_clear(t); +} + +static __inline__ +void fmpq_poly_submul(fmpq_poly_t rop, const fmpq_poly_t op1, const fmpq_poly_t op2) +{ + fmpq_poly_t t; + + fmpq_poly_init(t); + fmpq_poly_mul(t, op1, op2); + fmpq_poly_sub(rop, rop, t); + fmpq_poly_clear(t); +} + +/* Powering ****************************************************************/ + +void _fmpq_poly_pow(fmpz * rpoly, fmpz_t rden, const fmpz * poly, + const fmpz_t den, slong len, ulong e); + +void fmpq_poly_pow(fmpq_poly_t rpoly, const fmpq_poly_t poly, ulong e); + +/* Shifting ****************************************************************/ + +void fmpq_poly_shift_left(fmpq_poly_t res, const fmpq_poly_t poly, slong n); + +void fmpq_poly_shift_right(fmpq_poly_t res, const fmpq_poly_t poly, slong n); + +/* Euclidean division ******************************************************/ + +void _fmpq_poly_divrem(fmpz * Q, fmpz_t q, fmpz * R, fmpz_t r, + const fmpz * A, const fmpz_t a, slong lenA, + const fmpz * B, const fmpz_t b, slong lenB, const fmpz_preinvn_t inv); + +void fmpq_poly_divrem(fmpq_poly_t Q, fmpq_poly_t R, + const fmpq_poly_t poly1, const fmpq_poly_t poly2); + +void _fmpq_poly_div(fmpz * Q, fmpz_t q, + const fmpz * A, const fmpz_t a, slong lenA, + const fmpz * B, const fmpz_t b, slong lenB, const fmpz_preinvn_t inv); + +void fmpq_poly_div(fmpq_poly_t Q, + const fmpq_poly_t poly1, const fmpq_poly_t poly2); + +void _fmpq_poly_rem(fmpz * R, fmpz_t r, + const fmpz * A, const fmpz_t a, slong lenA, + const fmpz * B, const fmpz_t b, slong lenB, const fmpz_preinvn_t inv); + +void fmpq_poly_rem(fmpq_poly_t R, + const fmpq_poly_t poly1, const fmpq_poly_t poly2); + +/* Precomputed inverse *****************************************************/ + +fmpq_poly_struct * _fmpq_poly_powers_precompute(const fmpz * B, + const fmpz_t denB, slong len); + +void fmpq_poly_powers_precompute(fmpq_poly_powers_precomp_t pinv, + fmpq_poly_t poly); + +void _fmpq_poly_powers_clear(fmpq_poly_struct * powers, slong len); + +void fmpq_poly_powers_clear(fmpq_poly_powers_precomp_t pinv); + +void _fmpq_poly_rem_powers_precomp(fmpz * A, fmpz_t denA, slong m, + const fmpz * B, const fmpz_t denB, slong n, + fmpq_poly_struct * const powers); + +void fmpq_poly_rem_powers_precomp(fmpq_poly_t R, const fmpq_poly_t A, + const fmpq_poly_t B, const fmpq_poly_powers_precomp_t B_inv); + +/* Power series division ***************************************************/ + +void _fmpq_poly_inv_series_newton(fmpz * Qinv, fmpz_t Qinvden, + const fmpz * Q, const fmpz_t Qden, slong n); + +void fmpq_poly_inv_series_newton(fmpq_poly_t Qinv, const fmpq_poly_t Q, slong n); + +static __inline__ void +_fmpq_poly_inv_series(fmpz * Qinv, fmpz_t Qinvden, + const fmpz * Q, const fmpz_t Qden, slong n) +{ + _fmpq_poly_inv_series_newton(Qinv, Qinvden, Q, Qden, n); +} + +static __inline__ void +fmpq_poly_inv_series(fmpq_poly_t Qinv, const fmpq_poly_t Q, slong n) +{ + fmpq_poly_inv_series_newton(Qinv, Q, n); +} + +void _fmpq_poly_div_series(fmpz * Q, fmpz_t denQ, + const fmpz * A, const fmpz_t denA, + const fmpz * B, const fmpz_t denB, slong n); + +void fmpq_poly_div_series(fmpq_poly_t Q, const fmpq_poly_t A, + const fmpq_poly_t B, slong n); + +/* Greatest common divisor **************************************************/ + +void _fmpq_poly_gcd(fmpz *G, fmpz_t denG, + const fmpz *A, slong lenA, const fmpz *B, slong lenB); + +void fmpq_poly_gcd(fmpq_poly_t G, const fmpq_poly_t A, const fmpq_poly_t B); + +void _fmpq_poly_xgcd(fmpz *G, fmpz_t denG, + fmpz *S, fmpz_t denS, fmpz *T, fmpz_t denT, + const fmpz *A, const fmpz_t denA, slong lenA, + const fmpz *B, const fmpz_t denB, slong lenB); + +void fmpq_poly_xgcd(fmpq_poly_t G, fmpq_poly_t S, fmpq_poly_t T, + const fmpq_poly_t A, const fmpq_poly_t B); + +void _fmpq_poly_lcm(fmpz *G, fmpz_t denG, + const fmpz *A, slong lenA, const fmpz *B, slong lenB); + +void fmpq_poly_lcm(fmpq_poly_t L, const fmpq_poly_t A, const fmpq_poly_t B); + +void _fmpq_poly_resultant(fmpz_t rnum, fmpz_t rden, + const fmpz *poly1, const fmpz_t den1, slong len1, + const fmpz *poly2, const fmpz_t den2, slong len2); + +void fmpq_poly_resultant(fmpq_t r, const fmpq_poly_t f, const fmpq_poly_t g); + +/* Derivative and integral *************************************************/ + +void _fmpq_poly_derivative(fmpz * rpoly, fmpz_t rden, + const fmpz * poly, const fmpz_t den, slong len); + +void fmpq_poly_derivative(fmpq_poly_t res, const fmpq_poly_t poly); + +void _fmpq_poly_integral(fmpz * rpoly, fmpz_t rden, + const fmpz * poly, const fmpz_t den, slong len); + +void fmpq_poly_integral(fmpq_poly_t res, const fmpq_poly_t poly); + +/* Square roots ************************************************************/ + +void _fmpq_poly_invsqrt_series(fmpz * rpoly, fmpz_t rden, + const fmpz * poly, const fmpz_t den, slong n); + +void fmpq_poly_invsqrt_series(fmpq_poly_t res, const fmpq_poly_t poly, slong n); + +void _fmpq_poly_sqrt_series(fmpz * rpoly, fmpz_t rden, + const fmpz * poly, const fmpz_t den, slong n); + +void fmpq_poly_sqrt_series(fmpq_poly_t res, const fmpq_poly_t poly, slong n); + + +/* Transcendental functions ************************************************/ + +void _fmpq_poly_log_series(fmpz * g, fmpz_t gden, + const fmpz * f, const fmpz_t fden, slong n); + +void fmpq_poly_log_series(fmpq_poly_t res, const fmpq_poly_t f, slong n); + +void _fmpq_poly_exp_series(fmpz * g, fmpz_t gden, + const fmpz * h, const fmpz_t hden, slong n); + +void fmpq_poly_exp_series(fmpq_poly_t res, const fmpq_poly_t poly, slong n); + +void _fmpq_poly_atan_series(fmpz * g, fmpz_t gden, + const fmpz * h, const fmpz_t hden, slong n); + +void fmpq_poly_atan_series(fmpq_poly_t res, const fmpq_poly_t poly, slong n); + +void _fmpq_poly_atanh_series(fmpz * g, fmpz_t gden, + const fmpz * h, const fmpz_t hden, slong n); + +void fmpq_poly_atanh_series(fmpq_poly_t res, const fmpq_poly_t poly, slong n); + +void _fmpq_poly_asin_series(fmpz * g, fmpz_t gden, + const fmpz * h, const fmpz_t hden, slong n); + +void fmpq_poly_asin_series(fmpq_poly_t res, const fmpq_poly_t poly, slong n); + +void _fmpq_poly_asinh_series(fmpz * g, fmpz_t gden, + const fmpz * h, const fmpz_t hden, slong n); + +void fmpq_poly_asinh_series(fmpq_poly_t res, const fmpq_poly_t poly, slong n); + +void _fmpq_poly_tan_series(fmpz * g, fmpz_t gden, + const fmpz * h, const fmpz_t hden, slong n); + +void fmpq_poly_tan_series(fmpq_poly_t res, const fmpq_poly_t poly, slong n); + +void _fmpq_poly_sin_series(fmpz * g, fmpz_t gden, + const fmpz * h, const fmpz_t hden, slong n); + +void fmpq_poly_sin_series(fmpq_poly_t res, const fmpq_poly_t poly, slong n); + +void _fmpq_poly_cos_series(fmpz * g, fmpz_t gden, + const fmpz * h, const fmpz_t hden, slong n); + +void fmpq_poly_cos_series(fmpq_poly_t res, const fmpq_poly_t poly, slong n); + +void _fmpq_poly_sinh_series(fmpz * g, fmpz_t gden, + const fmpz * h, const fmpz_t hden, slong n); + +void fmpq_poly_sinh_series(fmpq_poly_t res, const fmpq_poly_t poly, slong n); + +void _fmpq_poly_cosh_series(fmpz * g, fmpz_t gden, + const fmpz * h, const fmpz_t hden, slong n); + +void fmpq_poly_cosh_series(fmpq_poly_t res, const fmpq_poly_t poly, slong n); + +void _fmpq_poly_tanh_series(fmpz * g, fmpz_t gden, + const fmpz * h, const fmpz_t hden, slong n); + +void fmpq_poly_tanh_series(fmpq_poly_t res, const fmpq_poly_t poly, slong n); + +/* Evaluation **************************************************************/ + +void _fmpq_poly_evaluate_fmpz(fmpz_t rnum, fmpz_t rden, const fmpz * poly, + const fmpz_t den, slong len, const fmpz_t a); + +void fmpq_poly_evaluate_fmpz(fmpq_t res, const fmpq_poly_t poly, + const fmpz_t a); + +void +_fmpq_poly_evaluate_fmpq(fmpz_t rnum, fmpz_t rden, + const fmpz * poly, const fmpz_t den, slong len, + const fmpz_t anum, const fmpz_t aden); + +void +fmpq_poly_evaluate_fmpq(fmpq_t res, const fmpq_poly_t poly, const fmpq_t a); + +void fmpq_poly_evaluate_mpz(mpq_t res, const fmpq_poly_t poly, const mpz_t a); + +void fmpq_poly_evaluate_mpq(mpq_t res, const fmpq_poly_t poly, const mpq_t a); + +/* Interpolation ************************************************************/ + +void +_fmpq_poly_interpolate_fmpz_vec(fmpz * poly, fmpz_t den, + const fmpz * xs, const fmpz * ys, slong n); + +void +fmpq_poly_interpolate_fmpz_vec(fmpq_poly_t poly, + const fmpz * xs, const fmpz * ys, slong n); + +/* Composition *************************************************************/ + +void _fmpq_poly_compose(fmpz * res, fmpz_t den, + const fmpz * poly1, const fmpz_t den1, slong len1, + const fmpz * poly2, const fmpz_t den2, slong len2); + +void fmpq_poly_compose(fmpq_poly_t res, + const fmpq_poly_t poly1, const fmpq_poly_t poly2); + +void _fmpq_poly_rescale(fmpz * res, fmpz_t denr, const fmpz * poly, + const fmpz_t den, slong len, const fmpz_t xnum, const fmpz_t xden); + +void fmpq_poly_rescale(fmpq_poly_t res, + const fmpq_poly_t poly, const fmpq_t x); + +/* Power series composition ************************************************/ + +void +_fmpq_poly_compose_series_horner(fmpz * res, fmpz_t den, const fmpz * poly1, + const fmpz_t den1, slong len1, const fmpz * poly2, + const fmpz_t den2, slong len2, slong n); + +void +fmpq_poly_compose_series_horner(fmpq_poly_t res, + const fmpq_poly_t poly1, const fmpq_poly_t poly2, slong n); + +void +_fmpq_poly_compose_series_brent_kung(fmpz * res, fmpz_t den, + const fmpz * poly1, const fmpz_t den1, slong len1, + const fmpz * poly2, const fmpz_t den2, slong len2, slong n); + +void +fmpq_poly_compose_series_brent_kung(fmpq_poly_t res, + const fmpq_poly_t poly1, const fmpq_poly_t poly2, slong n); + +void +_fmpq_poly_compose_series(fmpz * res, fmpz_t den, + const fmpz * poly1, const fmpz_t den1, slong len1, + const fmpz * poly2, const fmpz_t den2, slong len2, slong n); + +void +fmpq_poly_compose_series(fmpq_poly_t res, + const fmpq_poly_t poly1, const fmpq_poly_t poly2, slong n); + +/* Power series reversion ************************************************/ + +void +_fmpq_poly_revert_series_lagrange(fmpz * res, fmpz_t den, + const fmpz * poly1, const fmpz_t den1, slong n); + +void +fmpq_poly_revert_series_lagrange(fmpq_poly_t res, + const fmpq_poly_t poly, slong n); + +void +_fmpq_poly_revert_series_lagrange_fast(fmpz * res, fmpz_t den, + const fmpz * poly1, const fmpz_t den1, slong n); + +void +fmpq_poly_revert_series_lagrange_fast(fmpq_poly_t res, + const fmpq_poly_t poly, slong n); + +void +_fmpq_poly_revert_series_newton(fmpz * res, fmpz_t den, + const fmpz * poly1, const fmpz_t den1, slong n); + +void +fmpq_poly_revert_series_newton(fmpq_poly_t res, + const fmpq_poly_t poly, slong n); + +void +_fmpq_poly_revert_series(fmpz * res, fmpz_t den, + const fmpz * poly1, const fmpz_t den1, slong n); + +void +fmpq_poly_revert_series(fmpq_poly_t res, + const fmpq_poly_t poly, slong n); + +/* Gaussian content ********************************************************/ + +void _fmpq_poly_content(fmpq_t res, + const fmpz * poly, const fmpz_t den, slong len); + +void fmpq_poly_content(fmpq_t res, const fmpq_poly_t poly); + +void _fmpq_poly_primitive_part(fmpz * rpoly, fmpz_t rden, + const fmpz * poly, const fmpz_t den, slong len); + +void fmpq_poly_primitive_part(fmpq_poly_t res, const fmpq_poly_t poly); + +int _fmpq_poly_is_monic(const fmpz * poly, const fmpz_t den, slong len); + +int fmpq_poly_is_monic(const fmpq_poly_t poly); + +void _fmpq_poly_make_monic(fmpz * rpoly, fmpz_t rden, + const fmpz * poly, const fmpz_t den, slong len); + +void fmpq_poly_make_monic(fmpq_poly_t res, const fmpq_poly_t poly); + +/* Square-free *************************************************************/ + +int fmpq_poly_is_squarefree(const fmpq_poly_t poly); + +/* Input and output *********************************************************/ + +int fmpq_poly_debug(const fmpq_poly_t poly); + +int _fmpq_poly_fprint(FILE * file, + const fmpz * poly, const fmpz_t den, slong len); + +int fmpq_poly_fprint(FILE * file, const fmpq_poly_t poly); + +int _fmpq_poly_fprint_pretty(FILE * file, + const fmpz *poly, const fmpz_t den, slong len, + const char * x); + +int fmpq_poly_fprint_pretty(FILE * file, + const fmpq_poly_t poly, const char * var); + +static __inline__ +int _fmpq_poly_print(const fmpz * poly, const fmpz_t den, slong len) +{ + return _fmpq_poly_fprint(stdout, poly, den, len); +} + +static __inline__ +int fmpq_poly_print(const fmpq_poly_t poly) +{ + return fmpq_poly_fprint(stdout, poly); +} + +static __inline__ +int _fmpq_poly_print_pretty(const fmpz *poly, const fmpz_t den, slong len, + const char * x) +{ + return _fmpq_poly_fprint_pretty(stdout, poly, den, len, x); +} + +static __inline__ +int fmpq_poly_print_pretty(const fmpq_poly_t poly, const char * var) +{ + return fmpq_poly_fprint_pretty(stdout, poly, var); +} + +int fmpq_poly_fread(FILE * file, fmpq_poly_t poly); + +static __inline__ +int fmpq_poly_read(fmpq_poly_t poly) +{ + return fmpq_poly_fread(stdin, poly); +} + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/external/flint-2.4.3/fmpq_poly/add.c b/external/flint-2.4.3/fmpq_poly/add.c new file mode 100644 index 0000000..5dce5be --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/add.c @@ -0,0 +1,154 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpq_poly.h" + +void _fmpq_poly_add_can(fmpz * rpoly, fmpz_t rden, + const fmpz * poly1, const fmpz_t den1, slong len1, + const fmpz * poly2, const fmpz_t den2, slong len2, int can) +{ + slong max = FLINT_MAX(len1, len2); + slong min = FLINT_MIN(len1, len2); + + fmpz_t d; + fmpz_init(d); + fmpz_one(d); + if (*den1 != WORD(1) && *den2 != WORD(1)) + fmpz_gcd(d, den1, den2); + + if (*d == WORD(1)) + { + _fmpz_vec_scalar_mul_fmpz(rpoly, poly1, len1, den2); + _fmpz_vec_scalar_addmul_fmpz(rpoly, poly2, min, den1); + if (len1 < len2) + _fmpz_vec_scalar_mul_fmpz(rpoly + min, poly2 + min, max - min, den1); + fmpz_mul(rden, den1, den2); + } + else + { + fmpz_t den11; + fmpz_t den22; + fmpz_init(den11); + fmpz_init(den22); + fmpz_divexact(den11, den1, d); + fmpz_divexact(den22, den2, d); + + _fmpz_vec_scalar_mul_fmpz(rpoly, poly1, len1, den22); + _fmpz_vec_scalar_addmul_fmpz(rpoly, poly2, len2, den11); + if (len1 < len2) + _fmpz_vec_scalar_mul_fmpz(rpoly + min, poly2 + min, max - min, den11); + + if (_fmpz_vec_is_zero(rpoly, max)) + fmpz_one(rden); + else + { + if (can) + { + fmpz_t e; + fmpz_init(e); + _fmpz_vec_content(e, rpoly, max); + if (*e != WORD(1)) + fmpz_gcd(e, e, d); + + if (*e == WORD(1)) + fmpz_mul(rden, den1, den22); + else + { + _fmpz_vec_scalar_divexact_fmpz(rpoly, rpoly, max, e); + fmpz_divexact(den11, den1, e); + fmpz_mul(rden, den11, den22); + } + fmpz_clear(e); + } else + fmpz_mul(rden, den1, den22); + } + fmpz_clear(den11); + fmpz_clear(den22); + } + fmpz_clear(d); +} + +void _fmpq_poly_add(fmpz * rpoly, fmpz_t rden, + const fmpz * poly1, const fmpz_t den1, slong len1, + const fmpz * poly2, const fmpz_t den2, slong len2) +{ + _fmpq_poly_add_can(rpoly, rden, poly1, den1, len1, poly2, den2, len2, 1); +} + +void fmpq_poly_add_can(fmpq_poly_t res, const fmpq_poly_t poly1, + const fmpq_poly_t poly2, int can) +{ + slong len1 = poly1->length, len2, max; + + if (poly1 == poly2) /* Set res = 2 * poly1 */ + { + fmpz_t rem; + fmpz_init(rem); + fmpz_mod_ui(rem, poly1->den, 2); + + fmpq_poly_fit_length(res, len1); + _fmpq_poly_set_length(res, len1); + + if (*rem == UWORD(0)) + { + _fmpz_vec_set(res->coeffs, poly1->coeffs, len1); + fmpz_fdiv_q_2exp(res->den, poly1->den, 1); + } + else + { + _fmpz_vec_scalar_mul_2exp(res->coeffs, poly1->coeffs, len1, 1); + fmpz_set(res->den, poly1->den); + } + fmpz_clear(rem); + return; + } + + len2 = poly2->length; + max = FLINT_MAX(len1, len2); + fmpq_poly_fit_length(res, max); + + if (res != poly2) + _fmpq_poly_add_can(res->coeffs, res->den, + poly1->coeffs, poly1->den, len1, + poly2->coeffs, poly2->den, len2, can); + else + _fmpq_poly_add_can(res->coeffs, res->den, + poly2->coeffs, poly2->den, len2, + poly1->coeffs, poly1->den, len1, can); + + _fmpq_poly_set_length(res, max); + _fmpq_poly_normalise(res); +} + +void fmpq_poly_add(fmpq_poly_t res, const fmpq_poly_t poly1, + const fmpq_poly_t poly2) +{ + fmpq_poly_add_can(res, poly1, poly2, 1); +} + diff --git a/external/flint-2.4.3/fmpq_poly/asin_series.c b/external/flint-2.4.3/fmpq_poly/asin_series.c new file mode 100644 index 0000000..77c38be --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/asin_series.c @@ -0,0 +1,101 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpq_poly.h" + +void +_fmpq_poly_asin_series(fmpz * g, fmpz_t gden, + const fmpz * h, const fmpz_t hden, slong n) +{ + fmpz * t; + fmpz * u; + fmpz_t tden; + fmpz_t uden; + + t = _fmpz_vec_init(n); + u = _fmpz_vec_init(n); + fmpz_init(tden); + fmpz_init(uden); + + /* asin(h(x)) = integral(h'(x)/sqrt(1-h(x)^2)) */ + _fmpq_poly_mullow(u, uden, h, hden, n, h, hden, n, n); + _fmpz_vec_neg(u, u, n); + fmpz_set(u, uden); /* u += 1 */ + _fmpq_poly_invsqrt_series(t, tden, u, uden, n); + _fmpq_poly_derivative(u, uden, h, hden, n); + _fmpq_poly_mullow(g, gden, t, tden, n, u, uden, n, n); + _fmpq_poly_integral(g, gden, g, gden, n); + + _fmpz_vec_clear(t, n); + _fmpz_vec_clear(u, n); + fmpz_clear(tden); + fmpz_clear(uden); +} + + +void +fmpq_poly_asin_series(fmpq_poly_t res, const fmpq_poly_t f, slong n) +{ + fmpz * f_coeffs; + slong flen = f->length; + + if (flen && !fmpz_is_zero(f->coeffs)) + { + flint_printf("Exception (fmpq_poly_asin_series): Constant term != 0.\n"); + abort(); + } + + if (flen == 0 || n < 2) + { + fmpq_poly_zero(res); + return; + } + + fmpq_poly_fit_length(res, n); + + if (flen < n) + { + f_coeffs = _fmpz_vec_init(n); + _fmpz_vec_set(f_coeffs, f->coeffs, flen); + } + else + { + f_coeffs = f->coeffs; + } + + _fmpq_poly_asin_series(res->coeffs, res->den, f_coeffs, f->den, n); + + if (flen < n) + { + _fmpz_vec_clear(f_coeffs, n); + } + + _fmpq_poly_set_length(res, n); + _fmpq_poly_normalise(res); +} diff --git a/external/flint-2.4.3/fmpq_poly/asinh_series.c b/external/flint-2.4.3/fmpq_poly/asinh_series.c new file mode 100644 index 0000000..9838835 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/asinh_series.c @@ -0,0 +1,100 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpq_poly.h" + +void +_fmpq_poly_asinh_series(fmpz * g, fmpz_t gden, + const fmpz * h, const fmpz_t hden, slong n) +{ + fmpz * t; + fmpz * u; + fmpz_t tden; + fmpz_t uden; + + t = _fmpz_vec_init(n); + u = _fmpz_vec_init(n); + fmpz_init(tden); + fmpz_init(uden); + + /* asinh(h(x)) = integral(h'(x)/sqrt(1+h(x)^2)) */ + _fmpq_poly_mullow(u, uden, h, hden, n, h, hden, n, n); + fmpz_set(u, uden); /* u += 1 */ + _fmpq_poly_invsqrt_series(t, tden, u, uden, n); + _fmpq_poly_derivative(u, uden, h, hden, n); + _fmpq_poly_mullow(g, gden, t, tden, n, u, uden, n, n); + _fmpq_poly_integral(g, gden, g, gden, n); + + _fmpz_vec_clear(t, n); + _fmpz_vec_clear(u, n); + fmpz_clear(tden); + fmpz_clear(uden); +} + + +void +fmpq_poly_asinh_series(fmpq_poly_t res, const fmpq_poly_t f, slong n) +{ + fmpz * f_coeffs; + slong flen = f->length; + + if (flen && !fmpz_is_zero(f->coeffs)) + { + flint_printf("Exception (fmpq_poly_asinh_series): Constant term != 0.\n"); + abort(); + } + + if (flen == 0 || n < 2) + { + fmpq_poly_zero(res); + return; + } + + fmpq_poly_fit_length(res, n); + + if (flen < n) + { + f_coeffs = _fmpz_vec_init(n); + _fmpz_vec_set(f_coeffs, f->coeffs, flen); + } + else + { + f_coeffs = f->coeffs; + } + + _fmpq_poly_asinh_series(res->coeffs, res->den, f_coeffs, f->den, n); + + if (flen < n) + { + _fmpz_vec_clear(f_coeffs, n); + } + + _fmpq_poly_set_length(res, n); + _fmpq_poly_normalise(res); +} diff --git a/external/flint-2.4.3/fmpq_poly/atan_series.c b/external/flint-2.4.3/fmpq_poly/atan_series.c new file mode 100644 index 0000000..46d3c6b --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/atan_series.c @@ -0,0 +1,99 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpq_poly.h" + +void +_fmpq_poly_atan_series(fmpz * g, fmpz_t gden, + const fmpz * h, const fmpz_t hden, slong n) +{ + fmpz * t; + fmpz * u; + fmpz_t tden; + fmpz_t uden; + + t = _fmpz_vec_init(n); + u = _fmpz_vec_init(n); + fmpz_init(tden); + fmpz_init(uden); + + /* atan(h(x)) = integral(h'(x)/(1+h(x)^2)) */ + _fmpq_poly_mullow(u, uden, h, hden, n, h, hden, n, n); + fmpz_set(u, uden); /* u += 1 */ + _fmpq_poly_derivative(t, tden, h, hden, n); + _fmpq_poly_div_series(g, gden, t, tden, u, uden, n); + _fmpq_poly_integral(g, gden, g, gden, n); + + _fmpz_vec_clear(t, n); + _fmpz_vec_clear(u, n); + fmpz_clear(tden); + fmpz_clear(uden); +} + + +void +fmpq_poly_atan_series(fmpq_poly_t res, const fmpq_poly_t f, slong n) +{ + fmpz * f_coeffs; + slong flen = f->length; + + if (flen && !fmpz_is_zero(f->coeffs)) + { + flint_printf("Exception (fmpq_poly_atan_series): Constant term != 0.\n"); + abort(); + } + + if (flen == 0 || n < 2) + { + fmpq_poly_zero(res); + return; + } + + fmpq_poly_fit_length(res, n); + + if (flen < n) + { + f_coeffs = _fmpz_vec_init(n); + _fmpz_vec_set(f_coeffs, f->coeffs, flen); + } + else + { + f_coeffs = f->coeffs; + } + + _fmpq_poly_atan_series(res->coeffs, res->den, f_coeffs, f->den, n); + + if (flen < n) + { + _fmpz_vec_clear(f_coeffs, n); + } + + _fmpq_poly_set_length(res, n); + _fmpq_poly_normalise(res); +} diff --git a/external/flint-2.4.3/fmpq_poly/atanh_series.c b/external/flint-2.4.3/fmpq_poly/atanh_series.c new file mode 100644 index 0000000..d79d1f2 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/atanh_series.c @@ -0,0 +1,100 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpq_poly.h" + +void +_fmpq_poly_atanh_series(fmpz * g, fmpz_t gden, + const fmpz * h, const fmpz_t hden, slong n) +{ + fmpz * t; + fmpz * u; + fmpz_t tden; + fmpz_t uden; + + t = _fmpz_vec_init(n); + u = _fmpz_vec_init(n); + fmpz_init(tden); + fmpz_init(uden); + + /* atanh(h(x)) = integral(h'(x)/(1-h(x)^2)) */ + _fmpq_poly_mullow(u, uden, h, hden, n, h, hden, n, n); + _fmpz_vec_neg(u, u, n); + fmpz_set(u, uden); /* u += 1 */ + _fmpq_poly_derivative(t, tden, h, hden, n); + _fmpq_poly_div_series(g, gden, t, tden, u, uden, n); + _fmpq_poly_integral(g, gden, g, gden, n); + + _fmpz_vec_clear(t, n); + _fmpz_vec_clear(u, n); + fmpz_clear(tden); + fmpz_clear(uden); +} + + +void +fmpq_poly_atanh_series(fmpq_poly_t res, const fmpq_poly_t f, slong n) +{ + fmpz * f_coeffs; + slong flen = f->length; + + if (flen && !fmpz_is_zero(f->coeffs)) + { + flint_printf("Exception (fmpq_poly_atanh_series): Constant term != 0.\n"); + abort(); + } + + if (flen == 0 || n < 2) + { + fmpq_poly_zero(res); + return; + } + + fmpq_poly_fit_length(res, n); + + if (flen < n) + { + f_coeffs = _fmpz_vec_init(n); + _fmpz_vec_set(f_coeffs, f->coeffs, flen); + } + else + { + f_coeffs = f->coeffs; + } + + _fmpq_poly_atanh_series(res->coeffs, res->den, f_coeffs, f->den, n); + + if (flen < n) + { + _fmpz_vec_clear(f_coeffs, n); + } + + _fmpq_poly_set_length(res, n); + _fmpq_poly_normalise(res); +} diff --git a/external/flint-2.4.3/fmpq_poly/canonicalise.c b/external/flint-2.4.3/fmpq_poly/canonicalise.c new file mode 100644 index 0000000..bc463ef --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/canonicalise.c @@ -0,0 +1,70 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpq_poly.h" + +void _fmpq_poly_canonicalise(fmpz * poly, fmpz_t den, slong len) +{ + if (*den == WORD(1)) + return; + + if (*den == WORD(-1)) + { + _fmpz_vec_neg(poly, poly, len); + fmpz_one(den); + } + else if (len == 0) + { + fmpz_one(den); + } + else + { + fmpz_t gcd; + fmpz_init(gcd); + _fmpz_vec_content(gcd, poly, len); + if (*gcd != WORD(1)) + fmpz_gcd(gcd, gcd, den); + if (fmpz_sgn(den) < 0) + fmpz_neg(gcd, gcd); + if (*gcd != WORD(1)) + { + _fmpz_vec_scalar_divexact_fmpz(poly, poly, len, gcd); + fmpz_divexact(den, den, gcd); + } + fmpz_clear(gcd); + } +} + +void fmpq_poly_canonicalise(fmpq_poly_t poly) +{ + _fmpq_poly_normalise(poly); + _fmpq_poly_canonicalise(poly->coeffs, poly->den, poly->length); +} + diff --git a/external/flint-2.4.3/fmpq_poly/clear.c b/external/flint-2.4.3/fmpq_poly/clear.c new file mode 100644 index 0000000..6f7b650 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/clear.c @@ -0,0 +1,44 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" + +void fmpq_poly_clear(fmpq_poly_t poly) +{ + if (poly->coeffs) + { + slong i; + for (i = 0; i < poly->alloc; i++) + _fmpz_demote(poly->coeffs + i); + flint_free(poly->coeffs); + } + fmpz_clear(poly->den); +} + diff --git a/external/flint-2.4.3/fmpq_poly/cmp.c b/external/flint-2.4.3/fmpq_poly/cmp.c new file mode 100644 index 0000000..961b0be --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/cmp.c @@ -0,0 +1,101 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpq_poly.h" + +int _fmpq_poly_cmp(const fmpz * lpoly, const fmpz_t lden, + const fmpz * rpoly, const fmpz_t rden, slong len) +{ + int ans; + slong i = len - 1; + fmpz_t lcoeff, rcoeff; + + if (fmpz_equal(lden, rden)) + { + while (i && fmpz_equal(lpoly + i, rpoly + i)) + i--; + ans = fmpz_cmp(lpoly + i, rpoly + i); + } + else if (*lden == WORD(1)) /* Here rden exceeds 1 */ + { + fmpz_init(lcoeff); + fmpz_mul(lcoeff, lpoly + i, rden); + while (i && fmpz_equal(lcoeff, rpoly + i)) + fmpz_mul(lcoeff, lpoly + (--i), rden); + ans = fmpz_cmp(lcoeff, rpoly + i); + fmpz_clear(lcoeff); + } + else if (*rden == WORD(1)) /* Here lden exceeds 1 */ + { + fmpz_init(rcoeff); + fmpz_mul(rcoeff, rpoly + i, lden); + while (i && fmpz_equal(rcoeff, lpoly + i)) + fmpz_mul(rcoeff, rpoly + (--i), lden); + ans = fmpz_cmp(lpoly + i, rcoeff); + fmpz_clear(rcoeff); + } + else /* Here both lden, rden exceed 1 */ + { + fmpz_init(lcoeff); + fmpz_init(rcoeff); + fmpz_mul(lcoeff, lpoly + i, rden); + fmpz_mul(rcoeff, rpoly + i, lden); + while (i && fmpz_equal(lcoeff, rcoeff)) + { + i--; + fmpz_mul(lcoeff, lpoly + i, rden); + fmpz_mul(rcoeff, rpoly + i, lden); + } + ans = fmpz_cmp(lcoeff, rcoeff); + fmpz_clear(lcoeff); + fmpz_clear(rcoeff); + } + return ans; +} + +int fmpq_poly_cmp(const fmpq_poly_t left, const fmpq_poly_t right) +{ + slong len1, len2; + + if (left == right) + return 0; + + len1 = left->length; + len2 = right->length; + + if (len1 < len2) + return -1; + else if (len1 > len2) + return 1; + else if (len1 == 0) + return 0; + else + return _fmpq_poly_cmp(left->coeffs, left->den, right->coeffs, right->den, len1); +} + diff --git a/external/flint-2.4.3/fmpq_poly/compose.c b/external/flint-2.4.3/fmpq_poly/compose.c new file mode 100644 index 0000000..61d7a3e --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/compose.c @@ -0,0 +1,116 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" +#include "fmpq_poly.h" + +void +_fmpq_poly_compose(fmpz * res, fmpz_t den, const fmpz * poly1, const fmpz_t den1, + slong len1, const fmpz * poly2, const fmpz_t den2, slong len2) +{ + if (*den2 == WORD(1)) + { + _fmpz_poly_compose(res, poly1, len1, poly2, len2); + fmpz_set(den, den1); + _fmpq_poly_canonicalise(res, den, (len1 - WORD(1)) * (len2 - WORD(1)) + WORD(1)); + } + else + { + fmpz_t one; + fmpz * v = _fmpz_vec_init(len1); + fmpz_init(one); + fmpz_one(one); + + _fmpq_poly_rescale(v, den, poly1, den1, len1, one, den2); + _fmpz_poly_compose(res, v, len1, poly2, len2); + _fmpq_poly_canonicalise(res, den, (len1 - WORD(1)) * (len2 - WORD(1)) + WORD(1)); + + fmpz_clear(one); + _fmpz_vec_clear(v, len1); + } +} + +void +fmpq_poly_compose(fmpq_poly_t res, + const fmpq_poly_t poly1, const fmpq_poly_t poly2) +{ + const slong len1 = poly1->length; + const slong len2 = poly2->length; + slong lenr; + + if (len1 == WORD(0)) + { + fmpq_poly_zero(res); + return; + } + if (len1 == WORD(1) || len2 == WORD(0)) + { + fmpq_poly_fit_length(res, 1); + fmpz_set(res->coeffs, poly1->coeffs); + fmpz_set(res->den, poly1->den); + { + fmpz_t d; + fmpz_init(d); + fmpz_gcd(d, res->coeffs, res->den); + if (*d != WORD(1)) + { + fmpz_divexact(res->coeffs, res->coeffs, d); + fmpz_divexact(res->den, res->den, d); + } + fmpz_clear(d); + } + _fmpq_poly_set_length(res, 1); + _fmpq_poly_normalise(res); + return; + } + + lenr = (len1 - WORD(1)) * (len2 - WORD(1)) + WORD(1); + + if ((res != poly1) && (res != poly2)) + { + fmpq_poly_fit_length(res, lenr); + _fmpq_poly_compose(res->coeffs, res->den, + poly1->coeffs, poly1->den, len1, + poly2->coeffs, poly2->den, len2); + _fmpq_poly_set_length(res, lenr); + _fmpq_poly_normalise(res); + } + else + { + fmpq_poly_t t; + fmpq_poly_init2(t, lenr); + _fmpq_poly_compose(t->coeffs, t->den, + poly1->coeffs, poly1->den, len1, + poly2->coeffs, poly2->den, len2); + _fmpq_poly_set_length(t, lenr); + _fmpq_poly_normalise(t); + fmpq_poly_swap(res, t); + fmpq_poly_clear(t); + } +} diff --git a/external/flint-2.4.3/fmpq_poly/compose_series.c b/external/flint-2.4.3/fmpq_poly/compose_series.c new file mode 100644 index 0000000..f6a94ed --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/compose_series.c @@ -0,0 +1,114 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" +#include "fmpq_poly.h" + +void +_fmpq_poly_compose_series(fmpz * res, fmpz_t den, const fmpz * poly1, + const fmpz_t den1, slong len1, const fmpz * poly2, + const fmpz_t den2, slong len2, slong n) +{ + if (len1 <= 20) + _fmpq_poly_compose_series_horner(res, den, poly1, den1, len1, + poly2, den2, len2, n); + else + _fmpq_poly_compose_series_brent_kung(res, den, poly1, den1, len1, + poly2, den2, len2, n); +} + +void +fmpq_poly_compose_series(fmpq_poly_t res, + const fmpq_poly_t poly1, const fmpq_poly_t poly2, slong n) +{ + slong len1 = poly1->length; + slong len2 = poly2->length; + slong lenr; + + if (len2 != 0 && !fmpz_is_zero(poly2->coeffs)) + { + flint_printf("Exception (fmpq_poly_compose_series). Inner polynomial \n" + "must have zero constant term,\n"); + abort(); + } + + if (len1 == 0 || n == 0) + { + fmpq_poly_zero(res); + return; + } + + if (len2 == 0 || len1 == 1) + { + fmpq_poly_fit_length(res, 1); + fmpz_set(res->coeffs, poly1->coeffs); + fmpz_set(res->den, poly1->den); + { + fmpz_t d; + fmpz_init(d); + fmpz_gcd(d, res->coeffs, res->den); + if (!fmpz_is_one(d)) + { + fmpz_divexact(res->coeffs, res->coeffs, d); + fmpz_divexact(res->den, res->den, d); + } + fmpz_clear(d); + } + _fmpq_poly_set_length(res, 1); + _fmpq_poly_normalise(res); + 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)) + { + fmpq_poly_fit_length(res, lenr); + _fmpq_poly_compose_series(res->coeffs, res->den, + poly1->coeffs, poly1->den, len1, + poly2->coeffs, poly2->den, len2, lenr); + _fmpq_poly_set_length(res, lenr); + _fmpq_poly_normalise(res); + } + else + { + fmpq_poly_t t; + fmpq_poly_init2(t, lenr); + _fmpq_poly_compose_series(t->coeffs, t->den, + poly1->coeffs, poly1->den, len1, + poly2->coeffs, poly2->den, len2, lenr); + _fmpq_poly_set_length(t, lenr); + _fmpq_poly_normalise(t); + fmpq_poly_swap(res, t); + fmpq_poly_clear(t); + } +} diff --git a/external/flint-2.4.3/fmpq_poly/compose_series_brent_kung.c b/external/flint-2.4.3/fmpq_poly/compose_series_brent_kung.c new file mode 100644 index 0000000..07e638d --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/compose_series_brent_kung.c @@ -0,0 +1,235 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" +#include "fmpq_poly.h" +#include "fmpq.h" +#include "fmpq_mat.h" +#include "ulong_extras.h" + +static void +_fmpq_mat_get_row(fmpz * rnum, fmpz_t den, fmpq_mat_t A, slong i) +{ + slong j; + fmpz_t t; + fmpz_init(t); + fmpz_one(den); + + for (j = 0; j < fmpq_mat_ncols(A); j++) + fmpz_lcm(den, den, fmpq_mat_entry_den(A, i, j)); + + for (j = 0; j < fmpq_mat_ncols(A); j++) + { + fmpz_divexact(t, den, fmpq_mat_entry_den(A, i, j)); + fmpz_mul(rnum + j, fmpq_mat_entry_num(A, i, j), t); + } + + fmpz_clear(t); +} + + +void +_fmpq_poly_compose_series_brent_kung(fmpz * res, fmpz_t den, const fmpz * poly1, + const fmpz_t den1, slong len1, const fmpz * poly2, + const fmpz_t den2, slong len2, slong n) +{ + fmpq_mat_t A, B, C; + fmpz_t tden, uden, hden; + fmpz *t, *u, *h, *swap; + slong i, j, m; + + if (fmpz_is_one(den2)) + { + _fmpz_poly_compose_series(res, poly1, len1, poly2, len2, n); + fmpz_set(den, den1); + _fmpq_poly_canonicalise(res, den, n); + return; + } + + if (n == 1) + { + fmpz_set(res, poly1); + fmpz_set(den, den1); + _fmpq_poly_canonicalise(res, den, 1); + return; + } + + m = n_sqrt(n) + 1; + + fmpq_mat_init(A, m, n); + fmpq_mat_init(B, m, m); + fmpq_mat_init(C, m, n); + + fmpz_init(tden); + fmpz_init(uden); + fmpz_init(hden); + h = _fmpz_vec_init(n); + t = _fmpz_vec_init(n); + u = _fmpz_vec_init(n); + + /* Set rows of B to the segments of poly1 */ + for (i = 0; i < len1; i++) + { + fmpz_set(fmpq_mat_entry_num(B, i / m, i % m), poly1 + i); + fmpz_set(fmpq_mat_entry_den(B, i / m, i % m), den1); + fmpq_canonicalise(fmpq_mat_entry(B, i / m, i % m)); + } + + /* Set rows of A to powers of poly2 */ + fmpq_set_si(fmpq_mat_entry(A, 0, 0), WORD(1), WORD(1)); + + for (i = 0; i < len2; i++) + { + fmpz_set(fmpq_mat_entry_num(A, 1, i), poly2 + i); + fmpz_set(fmpq_mat_entry_den(A, 1, i), den2); + fmpq_canonicalise(fmpq_mat_entry(A, 1, i)); + } + + _fmpz_vec_set(h, poly2, len2); + fmpz_set(hden, den2); + + for (i = 2; i < m; i++) + { + _fmpq_poly_mullow(t, tden, h, hden, n, poly2, den2, len2, n); + _fmpq_poly_canonicalise(t, tden, n); + + for (j = 0; j < n; j++) + { + fmpz_set(fmpq_mat_entry_num(A, i, j), t + j); + fmpz_set(fmpq_mat_entry_den(A, i, j), tden); + fmpq_canonicalise(fmpq_mat_entry(A, i, j)); + } + swap = t; t = h; h = swap; + fmpz_swap(hden, tden); + } + + /* Compute h = poly2 ^ m */ + _fmpq_poly_mullow(t, tden, h, hden, n, poly2, den2, len2, n); + _fmpq_poly_canonicalise(t, tden, n); + swap = t; t = h; h = swap; + fmpz_swap(hden, tden); + + /* Matrix multiply */ + fmpq_mat_mul(C, B, A); + fmpq_mat_clear(A); + fmpq_mat_clear(B); + + /* Evaluate block composition using the Horner scheme */ + _fmpq_mat_get_row(res, den, C, m - 1); + + for (i = m - 2; i >= 0; i--) + { + _fmpq_poly_mullow(t, tden, res, den, n, h, hden, n, n); + /* we could canonicalise t here, but it does not seem to make + much of a difference */ + _fmpq_mat_get_row(u, uden, C, i); + _fmpq_poly_add(res, den, t, tden, n, u, uden, n); + } + + _fmpq_poly_canonicalise(res, den, n); + + fmpq_mat_clear(C); + + _fmpz_vec_clear(t, n); + _fmpz_vec_clear(u, n); + _fmpz_vec_clear(h, n); + fmpz_clear(tden); + fmpz_clear(uden); + fmpz_clear(hden); +} + +void +fmpq_poly_compose_series_brent_kung(fmpq_poly_t res, + const fmpq_poly_t poly1, const fmpq_poly_t poly2, slong n) +{ + slong len1 = poly1->length; + slong len2 = poly2->length; + slong lenr; + + if (len2 != 0 && !fmpz_is_zero(poly2->coeffs)) + { + flint_printf("Exception (fmpq_poly_compose_series_brent_kung). \n" + "Inner polynomial must have zero constant term.\n"); + abort(); + } + + if (len1 == 0 || n == 0) + { + fmpq_poly_zero(res); + return; + } + + if (len2 == 0 || len1 == 1) + { + fmpq_poly_fit_length(res, 1); + fmpz_set(res->coeffs, poly1->coeffs); + fmpz_set(res->den, poly1->den); + { + fmpz_t d; + fmpz_init(d); + fmpz_gcd(d, res->coeffs, res->den); + if (!fmpz_is_one(d)) + { + fmpz_divexact(res->coeffs, res->coeffs, d); + fmpz_divexact(res->den, res->den, d); + } + fmpz_clear(d); + } + _fmpq_poly_set_length(res, 1); + _fmpq_poly_normalise(res); + 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)) + { + fmpq_poly_fit_length(res, lenr); + _fmpq_poly_compose_series_brent_kung(res->coeffs, res->den, + poly1->coeffs, poly1->den, len1, + poly2->coeffs, poly2->den, len2, lenr); + _fmpq_poly_set_length(res, lenr); + _fmpq_poly_normalise(res); + } + else + { + fmpq_poly_t t; + fmpq_poly_init2(t, lenr); + _fmpq_poly_compose_series_brent_kung(t->coeffs, t->den, + poly1->coeffs, poly1->den, len1, + poly2->coeffs, poly2->den, len2, lenr); + _fmpq_poly_set_length(t, lenr); + _fmpq_poly_normalise(t); + fmpq_poly_swap(res, t); + fmpq_poly_clear(t); + } +} diff --git a/external/flint-2.4.3/fmpq_poly/compose_series_horner.c b/external/flint-2.4.3/fmpq_poly/compose_series_horner.c new file mode 100644 index 0000000..94455c7 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/compose_series_horner.c @@ -0,0 +1,161 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" +#include "fmpq_poly.h" + +void +_fmpq_poly_compose_series_horner(fmpz * res, fmpz_t den, const fmpz * poly1, + const fmpz_t den1, slong len1, const fmpz * poly2, + const fmpz_t den2, slong len2, slong n) +{ + if (fmpz_is_one(den2)) + { + _fmpz_poly_compose_series(res, poly1, len1, poly2, len2, n); + fmpz_set(den, den1); + _fmpq_poly_canonicalise(res, den, n); + } + else if (n == 1) + { + fmpz_set(res, poly1); + fmpz_set(den, den1); + _fmpq_poly_canonicalise(res, den, 1); + } + else + { + slong i = len1 - 1; + slong lenr; + fmpz_t tden; + fmpz * t = _fmpz_vec_init(n); + fmpz_init(tden); + + _fmpz_vec_zero(res, n); + + lenr = len2; + _fmpq_poly_scalar_mul_fmpz(res, den, poly2, den2, len2, poly1 + i); + _fmpq_poly_scalar_div_fmpz(res, den, res, den, len2, den1); + i--; + + _fmpq_poly_add(res, den, res, den, len2, poly1 + i, den1, 1); + _fmpq_poly_canonicalise(res, den, lenr); + + while (i > 0) + { + i--; + if (lenr + len2 - 1 < n) + { + _fmpq_poly_mul(t, tden, res, den, lenr, poly2, den2, len2); + lenr = lenr + len2 - 1; + } + else + { + _fmpq_poly_mullow(t, tden, res, den, lenr, + poly2, den2, len2, n); + lenr = n; + } + _fmpq_poly_canonicalise(t, tden, lenr); + _fmpq_poly_add(res, den, t, tden, lenr, poly1 + i, den1, 1); + } + + _fmpq_poly_canonicalise(res, den, n); + + _fmpz_vec_clear(t, n); + fmpz_clear(tden); + } +} + +void +fmpq_poly_compose_series_horner(fmpq_poly_t res, + const fmpq_poly_t poly1, const fmpq_poly_t poly2, slong n) +{ + slong len1 = poly1->length; + slong len2 = poly2->length; + slong lenr; + + if (len2 != 0 && !fmpz_is_zero(poly2->coeffs)) + { + flint_printf("Exception (fmpq_poly_compose_series_horner). Inner polynomial \n" + "must have zero constant term.\n"); + abort(); + } + + if (len1 == 0 || n == 0) + { + fmpq_poly_zero(res); + return; + } + + if (len2 == 0 || len1 == 1) + { + fmpq_poly_fit_length(res, 1); + fmpz_set(res->coeffs, poly1->coeffs); + fmpz_set(res->den, poly1->den); + { + fmpz_t d; + fmpz_init(d); + fmpz_gcd(d, res->coeffs, res->den); + if (!fmpz_is_one(d)) + { + fmpz_divexact(res->coeffs, res->coeffs, d); + fmpz_divexact(res->den, res->den, d); + } + fmpz_clear(d); + } + _fmpq_poly_set_length(res, 1); + _fmpq_poly_normalise(res); + 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)) + { + fmpq_poly_fit_length(res, lenr); + _fmpq_poly_compose_series_horner(res->coeffs, res->den, + poly1->coeffs, poly1->den, len1, + poly2->coeffs, poly2->den, len2, lenr); + _fmpq_poly_set_length(res, lenr); + _fmpq_poly_normalise(res); + } + else + { + fmpq_poly_t t; + fmpq_poly_init2(t, lenr); + _fmpq_poly_compose_series_horner(t->coeffs, t->den, + poly1->coeffs, poly1->den, len1, + poly2->coeffs, poly2->den, len2, lenr); + _fmpq_poly_set_length(t, lenr); + _fmpq_poly_normalise(t); + fmpq_poly_swap(res, t); + fmpq_poly_clear(t); + } +} diff --git a/external/flint-2.4.3/fmpq_poly/content.c b/external/flint-2.4.3/fmpq_poly/content.c new file mode 100644 index 0000000..017843a --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/content.c @@ -0,0 +1,43 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpq_poly.h" + +void _fmpq_poly_content(fmpq_t res, const fmpz * poly, + const fmpz_t den, slong len) +{ + _fmpz_poly_content(fmpq_numref(res), poly, len); + fmpz_set(fmpq_denref(res), den); +} + +void fmpq_poly_content(fmpq_t res, const fmpq_poly_t poly) +{ + _fmpq_poly_content(res, poly->coeffs, poly->den, poly->length); +} + diff --git a/external/flint-2.4.3/fmpq_poly/cos_series.c b/external/flint-2.4.3/fmpq_poly/cos_series.c new file mode 100644 index 0000000..1253c83 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/cos_series.c @@ -0,0 +1,112 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpq_poly.h" + +void +_fmpq_poly_cos_series(fmpz * g, fmpz_t gden, + const fmpz * h, const fmpz_t hden, slong n) +{ + fmpz * t; + fmpz * u; + fmpz_t tden; + fmpz_t uden; + + t = _fmpz_vec_init(n); + u = _fmpz_vec_init(n); + fmpz_init(tden); + fmpz_init(uden); + + /* cos(x) = (1-tan(x/2)^2)/(1+tan(x/2)^2) */ + fmpz_mul_ui(uden, hden, UWORD(2)); + _fmpq_poly_tan_series(t, tden, h, uden, n); + _fmpq_poly_mullow(u, uden, t, tden, n, t, tden, n, n); + + _fmpq_poly_canonicalise(u, uden, n); + _fmpz_vec_neg(t, u, n); + fmpz_set(tden, uden); + fmpz_set(t, tden); + fmpz_set(u, uden); + + _fmpq_poly_div_series(g, gden, t, tden, u, uden, n); + _fmpq_poly_canonicalise(g, gden, n); + + _fmpz_vec_clear(t, n); + _fmpz_vec_clear(u, n); + fmpz_clear(tden); + fmpz_clear(uden); +} + +void +fmpq_poly_cos_series(fmpq_poly_t res, const fmpq_poly_t f, slong n) +{ + fmpz * f_coeffs; + slong flen = f->length; + + if (f->length == 0) + { + fmpq_poly_set_ui(res, UWORD(1)); + return; + } + + if (!fmpz_is_zero(f->coeffs)) + { + flint_printf("Exception (fmpq_poly_cos_series). Constant term != 0."); + abort(); + } + + if (n < 2) + { + if (n == 0) fmpq_poly_zero(res); + if (n == 1) fmpq_poly_set_ui(res, UWORD(1)); + return; + } + + fmpq_poly_fit_length(res, n); + + if (flen < n) + { + f_coeffs = _fmpz_vec_init(n); + _fmpz_vec_set(f_coeffs, f->coeffs, flen); + } + else + { + f_coeffs = f->coeffs; + } + + _fmpq_poly_cos_series(res->coeffs, res->den, f_coeffs, f->den, n); + + if (flen < n) + { + _fmpz_vec_clear(f_coeffs, n); + } + + _fmpq_poly_set_length(res, n); + _fmpq_poly_normalise(res); +} diff --git a/external/flint-2.4.3/fmpq_poly/cosh_series.c b/external/flint-2.4.3/fmpq_poly/cosh_series.c new file mode 100644 index 0000000..48d6dbb --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/cosh_series.c @@ -0,0 +1,112 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpq_poly.h" + +void +_fmpq_poly_cosh_series(fmpz * g, fmpz_t gden, + const fmpz * h, const fmpz_t hden, slong n) +{ + fmpz * t; + fmpz_t tden; + + t = _fmpz_vec_init(n); + fmpz_init(tden); + + /* cosh(x) = (exp(x)+exp(-x))/2 */ + _fmpq_poly_exp_series(g, gden, h, hden, n); + _fmpq_poly_inv_series(t, tden, g, gden, n); + _fmpq_poly_add(g, gden, g, gden, n, t, tden, n); + _fmpq_poly_scalar_div_ui(g, gden, g, gden, n, UWORD(2)); + _fmpq_poly_canonicalise(g, gden, n); + + _fmpz_vec_clear(t, n); + fmpz_clear(tden); +} + +void fmpq_poly_cosh_series(fmpq_poly_t res, const fmpq_poly_t poly, slong n) +{ + fmpz *copy; + int alloc; + + if (poly->length == 0) + { + fmpq_poly_set_ui(res, UWORD(1)); + return; + } + + if (!fmpz_is_zero(poly->coeffs)) + { + flint_printf("Exception (fmpq_poly_cosh_series): Constant term != 0.\n"); + abort(); + } + + if (n < 2) + { + if (n == 0) fmpq_poly_zero(res); + if (n == 1) fmpq_poly_set_ui(res, UWORD(1)); + return; + } + + if (poly->length >= n) + { + copy = poly->coeffs; + alloc = 0; + } + else + { + slong i; + copy = (fmpz *) flint_malloc(n * sizeof(fmpz)); + for (i = 0; i < poly->length; i++) + copy[i] = poly->coeffs[i]; + for ( ; i < n; i++) + copy[i] = 0; + alloc = 1; + } + + if (res != poly) + { + fmpq_poly_fit_length(res, n); + _fmpq_poly_cosh_series(res->coeffs, res->den, copy, poly->den, n); + } + else + { + fmpq_poly_t t; + fmpq_poly_init2(t, n); + _fmpq_poly_cosh_series(t->coeffs, t->den, copy, poly->den, n); + fmpq_poly_swap(res, t); + fmpq_poly_clear(t); + } + + _fmpq_poly_set_length(res, n); + _fmpq_poly_normalise(res); + + if (alloc) + flint_free(copy); +} diff --git a/external/flint-2.4.3/fmpq_poly/debug.c b/external/flint-2.4.3/fmpq_poly/debug.c new file mode 100644 index 0000000..bcc787e --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/debug.c @@ -0,0 +1,48 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpq_poly.h" + +int fmpq_poly_debug(const fmpq_poly_t poly) +{ + slong i; + + flint_printf("{alloc: %wd, length: %wd, coeffs:", poly->alloc, poly->length); + for (i = 0; i < poly->alloc; i++) + { + flint_printf(" "); + fmpz_print(poly->coeffs + i); + } + flint_printf(", den: "); + fmpz_print(poly->den); + flint_printf("}"); + + return 1; +} + diff --git a/external/flint-2.4.3/fmpq_poly/derivative.c b/external/flint-2.4.3/fmpq_poly/derivative.c new file mode 100644 index 0000000..88ae8d8 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/derivative.c @@ -0,0 +1,53 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpq_poly.h" + +void _fmpq_poly_derivative(fmpz * rpoly, fmpz_t rden, + const fmpz * poly, const fmpz_t den, slong len) +{ + _fmpz_poly_derivative(rpoly, poly, len); + fmpz_set(rden, den); + _fmpq_poly_canonicalise(rpoly, rden, len - 1); +} + +void fmpq_poly_derivative(fmpq_poly_t res, const fmpq_poly_t poly) +{ + slong len = poly->length; + if (len < 2) + { + fmpq_poly_zero(res); + return; + } + + fmpq_poly_fit_length(res, len - 1); + _fmpq_poly_derivative(res->coeffs, res->den, poly->coeffs, poly->den, len); + _fmpq_poly_set_length(res, len - 1); +} + diff --git a/external/flint-2.4.3/fmpq_poly/div.c b/external/flint-2.4.3/fmpq_poly/div.c new file mode 100644 index 0000000..450fef8 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/div.c @@ -0,0 +1,127 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpq_poly.h" + +void _fmpq_poly_div(fmpz * Q, fmpz_t q, + const fmpz * A, const fmpz_t a, slong lenA, + const fmpz * B, const fmpz_t b, slong lenB, const fmpz_preinvn_t inv) +{ + slong lenQ = lenA - lenB + 1; + ulong d; + const fmpz * lead = B + (lenB - 1); + + if (lenB == 1) + { + _fmpq_poly_scalar_div_fmpq(Q, q, A, a, lenA, B, b); + return; + } + + /* + From pseudo division over Z we have + lead^d * A = Q * B + R + and thus + {A, a} = {b * Q, a * lead^d} * {B, b} + {R, a * lead^d}. + */ + _fmpz_poly_pseudo_div(Q, &d, A, lenA, B, lenB, inv); + + /* 1. lead^d == +-1. {Q, q} = {b Q, a} up to sign */ + if (d == UWORD(0) || *lead == WORD(1) || *lead == WORD(-1)) + { + fmpz_one(q); + _fmpq_poly_scalar_mul_fmpz(Q, q, Q, q, lenQ, b); + _fmpq_poly_scalar_div_fmpz(Q, q, Q, q, lenQ, a); + + if (*lead == WORD(-1) && d % UWORD(2)) + _fmpz_vec_neg(Q, Q, lenQ); + } + /* 2. lead^d != +-1. {Q, q} = {b Q, a lead^d} */ + else + { + /* + TODO: Improve this. Clearly we do not need to compute + den = a lead^d in many cases, but can determine the GCD from + lead alone already. + */ + fmpz_t den; + fmpz_init(den); + fmpz_pow_ui(den, lead, d); + fmpz_mul(den, a, den); + + fmpz_one(q); + _fmpq_poly_scalar_mul_fmpz(Q, q, Q, q, lenQ, b); + _fmpq_poly_scalar_div_fmpz(Q, q, Q, q, lenQ, den); + + fmpz_clear(den); + } +} + +void fmpq_poly_div(fmpq_poly_t Q, + const fmpq_poly_t poly1, const fmpq_poly_t poly2) +{ + slong lenA, lenB, lenQ; + + if (fmpq_poly_is_zero(poly2)) + { + flint_printf("Exception (fmpq_poly_div). Division by zero.\n"); + abort(); + } + + if (poly1->length < poly2->length) + { + fmpq_poly_zero(Q); + return; + } + + /* Deal with aliasing */ + if (Q == poly1 || Q == poly2) + { + fmpq_poly_t tempQ; + fmpq_poly_init(tempQ); + fmpq_poly_div(tempQ, poly1, poly2); + fmpq_poly_swap(Q, tempQ); + fmpq_poly_clear(tempQ); + return; + } + + + lenA = poly1->length; + lenB = poly2->length; + lenQ = lenA - lenB + 1; + + fmpq_poly_fit_length(Q, lenQ); + + _fmpq_poly_div(Q->coeffs, Q->den, + poly1->coeffs, poly1->den, poly1->length, + poly2->coeffs, poly2->den, poly2->length, NULL); + + _fmpq_poly_set_length(Q, lenQ); +} + diff --git a/external/flint-2.4.3/fmpq_poly/div_series.c b/external/flint-2.4.3/fmpq_poly/div_series.c new file mode 100644 index 0000000..ed4e09f --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/div_series.c @@ -0,0 +1,103 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpq_poly.h" + +void +_fmpq_poly_div_series(fmpz * Q, fmpz_t denQ, + const fmpz * A, const fmpz_t denA, + const fmpz * B, const fmpz_t denB, slong n) +{ + fmpz * C = _fmpz_vec_init(n + 1); + fmpz * denC = C + n; + + _fmpq_poly_inv_series(C, denC, B, denB, n); + _fmpq_poly_mullow(Q, denQ, A, denA, n, C, denC, n, n); + + _fmpz_vec_clear(C, n + 1); +} + +void fmpq_poly_div_series(fmpq_poly_t Q, const fmpq_poly_t A, + const fmpq_poly_t B, slong n) +{ + fmpz *a, *b; + ulong flags = UWORD(0); /* 2^0 for a, 2^1 for b */ + + if (Q == A) + { + fmpq_poly_t t; + fmpq_poly_init2(t, n); + fmpq_poly_div_series(t, A, B, n); + fmpq_poly_swap(Q, t); + fmpq_poly_clear(t); + return; + } + + fmpq_poly_fit_length(Q, n); + + if (A->length >= n) + { + a = A->coeffs; + } + else + { + slong i; + a = (fmpz *) flint_malloc(n * sizeof(fmpz)); + for (i = 0; i < A->length; i++) + a[i] = A->coeffs[i]; + flint_mpn_zero((mp_ptr) a + A->length, n - A->length); + flags |= UWORD(1); + } + + if (B->length >= n) + { + b = B->coeffs; + } + else + { + slong i; + b = (fmpz *) flint_malloc(n * sizeof(fmpz)); + for (i = 0; i < B->length; i++) + b[i] = B->coeffs[i]; + flint_mpn_zero((mp_ptr) b + B->length, n - B->length); + flags |= UWORD(2); + } + + _fmpq_poly_div_series(Q->coeffs, Q->den, a, A->den, b, B->den, n); + + _fmpq_poly_set_length(Q, n); + fmpq_poly_canonicalise(Q); + + if ((flags & UWORD(1))) + flint_free(a); + if ((flags & UWORD(2))) + flint_free(b); +} + diff --git a/external/flint-2.4.3/fmpq_poly/divrem.c b/external/flint-2.4.3/fmpq_poly/divrem.c new file mode 100644 index 0000000..e3f4f3d --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/divrem.c @@ -0,0 +1,179 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpq_poly.h" + +void _fmpq_poly_divrem(fmpz * Q, fmpz_t q, fmpz * R, fmpz_t r, + const fmpz * A, const fmpz_t a, slong lenA, + const fmpz * B, const fmpz_t b, slong lenB, const fmpz_preinvn_t inv) +{ + slong lenQ = lenA - lenB + 1; + slong lenR = lenB - 1; + ulong d; + const fmpz * lead = B + (lenB - 1); + + if (lenB == 1) + { + _fmpq_poly_scalar_div_fmpq(Q, q, A, a, lenA, B, b); + fmpz_one(r); + return; + } + + /* + From pseudo division over Z we have + lead^d * A = Q * B + R + and thus + {A, a} = {b * Q, a * lead^d} * {B, b} + {R, a * lead^d}. + */ + _fmpz_poly_pseudo_divrem(Q, R, &d, A, lenA, B, lenB, inv); + + /* Determine the actual length of R */ + for ( ; lenR != 0 && fmpz_is_zero(R + (lenR - 1)); lenR--) ; + + /* 1. lead^d == +-1. {Q, q} = {b Q, a}, {R, r} = {R, a} up to sign */ + if (d == UWORD(0) || *lead == WORD(1) || *lead == WORD(-1)) + { + fmpz_one(q); + _fmpq_poly_scalar_mul_fmpz(Q, q, Q, q, lenQ, b); + _fmpq_poly_scalar_div_fmpz(Q, q, Q, q, lenQ, a); + + fmpz_one(r); + if (lenR > 0) + _fmpq_poly_scalar_div_fmpz(R, r, R, r, lenR, a); + + if (*lead == WORD(-1) && d % UWORD(2)) + { + _fmpz_vec_neg(Q, Q, lenQ); + _fmpz_vec_neg(R, R, lenR); + } + } + /* 2. lead^d != +-1. {Q, q} = {b Q, a lead^d}, {R, r} = {R, a lead^d} */ + else + { + /* + TODO: Improve this. Clearly we do not need to compute + den = a lead^d in many cases, but can determine the GCD from + lead alone already. + */ + fmpz_t den; + fmpz_init(den); + fmpz_pow_ui(den, lead, d); + fmpz_mul(den, a, den); + + fmpz_one(q); + _fmpq_poly_scalar_mul_fmpz(Q, q, Q, q, lenQ, b); + _fmpq_poly_scalar_div_fmpz(Q, q, Q, q, lenQ, den); + + fmpz_one(r); + if (lenR > 0) + _fmpq_poly_scalar_div_fmpz(R, r, R, r, lenR, den); + + fmpz_clear(den); + } +} + +void fmpq_poly_divrem(fmpq_poly_t Q, fmpq_poly_t R, + const fmpq_poly_t poly1, const fmpq_poly_t poly2) +{ + slong lenA, lenB, lenQ, lenR; + + if (fmpq_poly_is_zero(poly2)) + { + flint_printf("Exception (fmpq_poly_divrem). Division by zero.\n"); + abort(); + } + if (Q == R) + { + flint_printf("Exception (fmpq_poly_divrem). Output arguments aliased.\n"); + abort(); + } + + /* Deal with the various other cases of aliasing. */ + if (R == poly1 || R == poly2) + { + if (Q == poly1 || Q == poly2) + { + fmpq_poly_t tempQ, tempR; + fmpq_poly_init(tempQ); + fmpq_poly_init(tempR); + fmpq_poly_divrem(tempQ, tempR, poly1, poly2); + fmpq_poly_swap(Q, tempQ); + fmpq_poly_swap(R, tempR); + fmpq_poly_clear(tempQ); + fmpq_poly_clear(tempR); + return; + } + else + { + fmpq_poly_t tempR; + fmpq_poly_init(tempR); + fmpq_poly_divrem(Q, tempR, poly1, poly2); + fmpq_poly_swap(R, tempR); + fmpq_poly_clear(tempR); + return; + } + } + else + { + if (Q == poly1 || Q == poly2) + { + fmpq_poly_t tempQ; + fmpq_poly_init(tempQ); + fmpq_poly_divrem(tempQ, R, poly1, poly2); + fmpq_poly_swap(Q, tempQ); + fmpq_poly_clear(tempQ); + return; + } + } + + if (poly1->length < poly2->length) + { + fmpq_poly_set(R, poly1); + fmpq_poly_zero(Q); + return; + } + + lenA = poly1->length; + lenB = poly2->length; + lenQ = lenA - lenB + 1; + lenR = lenB - 1; + + fmpq_poly_fit_length(Q, lenQ); + fmpq_poly_fit_length(R, lenA); /* XXX: Need at least that much space */ + + _fmpq_poly_divrem(Q->coeffs, Q->den, R->coeffs, R->den, + poly1->coeffs, poly1->den, poly1->length, + poly2->coeffs, poly2->den, poly2->length, NULL); + + _fmpq_poly_set_length(Q, lenQ); + _fmpq_poly_set_length(R, lenR); + _fmpq_poly_normalise(R); +} + diff --git a/external/flint-2.4.3/fmpq_poly/doc/fmpq_poly.txt b/external/flint-2.4.3/fmpq_poly/doc/fmpq_poly.txt new file mode 100644 index 0000000..59eb39d --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/doc/fmpq_poly.txt @@ -0,0 +1,1657 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 William Hart + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +******************************************************************************* + + Memory management + +******************************************************************************* + +void fmpq_poly_init(fmpq_poly_t poly) + + Initialises the polynomial for use. The length is set to zero. + +void fmpq_poly_init2(fmpq_poly_t poly, slong alloc) + + Initialises the polynomial with space for at least \code{alloc} + coefficients and set the length to zero. The \code{alloc} coefficients + are all set to zero. + +void fmpq_poly_realloc(fmpq_poly_t poly, slong alloc) + + Reallocates the given polynomial to have space for \code{alloc} + coefficients. If \code{alloc} is zero then the polynomial is cleared + and then reinitialised. If the current length is greater than + \code{alloc} then \code{poly} is first truncated to length + \code{alloc}. Note that this might leave the rational polynomial in + non-canonical form. + +void fmpq_poly_fit_length(fmpq_poly_t poly, slong len) + + If \code{len} is greater than the number of coefficients currently + allocated, then the polynomial is reallocated to have space for at + least \code{len} coefficients. No data is lost when calling this + function. The function efficiently deals with the case where + \code{fit_length()} is called many times in small increments by at + least doubling the number of allocated coefficients when \code{len} + is larger than the number of coefficients currently allocated. + +void _fmpq_poly_set_length(fmpq_poly_t poly, slong len) + + Sets the length of the numerator polynomial to \code{len}, demoting + coefficients beyond the new length. Note that this method does + not guarantee that the rational polynomial is in canonical form. + +void fmpq_poly_clear(fmpq_poly_t poly) + + Clears the given polynomial, releasing any memory used. The polynomial + must be reinitialised in order to be used again. + +void _fmpq_poly_normalise(fmpq_poly_t poly) + + Sets the length of \code{poly} so that the top coefficient is + non-zero. If all coefficients are zero, the length is set to zero. + Note that this function does not guarantee the coprimality of the + numerator polynomial and the integer denominator. + +void _fmpq_poly_canonicalise(fmpz * poly, fmpz_t den, slong len) + + Puts \code{(poly, den)} of length \code{len} into canonical form. + + It is assumed that the array \code{poly} contains a non-zero entry in + position \code{len - 1} whenever \code{len > 0}. Assumes that \code{den} + is non-zero. + +void fmpq_poly_canonicalise(fmpq_poly_t poly) + + Puts the polynomial \code{poly} into canonical form. Firstly, the length + is set to the actual length of the numerator polynomial. For non-zero + polynomials, it is then ensured that the numerator and denominator are + coprime and that the denominator is positive. The canonical form of the + zero polynomial is a zero numerator polynomial and a one denominator. + +int _fmpq_poly_is_canonical(const fmpz * poly, const fmpz_t den, slong len) + + Returns whether the polynomial is in canonical form. + +int fmpq_poly_is_canonical(const fmpq_poly_t poly) + + Returns whether the polynomial is in canonical form. + +******************************************************************************* + + Polynomial parameters + +******************************************************************************* + +slong fmpq_poly_degree(const fmpq_poly_t poly) + + Returns the degree of \code{poly}, which is one less than its length, as + a \code{slong}. + +slong fmpq_poly_length(const fmpq_poly_t poly) + + Returns the length of \code{poly}. + +******************************************************************************* + + Accessing the numerator and denominator + +******************************************************************************* + +fmpz * fmpq_poly_numref(fmpq_poly_t poly) + + Returns a reference to the numerator polynomial as an array. + + Note that, because of a delayed initialisation approach, this might + be \code{NULL} for zero polynomials. This situation can be salvaged + by calling either \code{fmpq_poly_fit_length()} or + \code{fmpq_poly_realloc()}. + + This function is implemented as a macro returning \code{(poly)->coeffs}. + +fmpz_t fmpq_poly_denref(fmpq_poly_t poly) + + Returns a reference to the denominator as a \code{fmpz_t}. The integer + is guaranteed to be properly initialised. + + This function is implemented as a macro returning \code{(poly)->den}. + +******************************************************************************* + + Random testing + + The functions \code{fmpq_poly_randtest_foo()} provide random + polynomials suitable for testing. On an integer level, this + means that long strings of zeros and ones in the binary + representation are favoured as well as the special absolute + values $0$, $1$, \code{COEFF_MAX}, and \code{WORD_MAX}. On a + polynomial level, the integer numerator has a reasonable chance + to have a non-trivial content. + +******************************************************************************* + +void fmpq_poly_randtest(fmpq_poly_t f, flint_rand_t state, + slong len, mp_bitcnt_t bits) + + Sets $f$ to a random polynomial with coefficients up to the given + length and where each coefficient has up to the given number of bits. + The coefficients are signed randomly. One must call + \code{flint_randinit()} before calling this function. + +void fmpq_poly_randtest_unsigned(fmpq_poly_t f, flint_rand_t state, + slong len, mp_bitcnt_t bits) + + Sets $f$ to a random polynomial with coefficients up to the given length + and where each coefficient has up to the given number of bits. One must + call \code{flint_randinit()} before calling this function. + +void fmpq_poly_randtest_not_zero(fmpq_poly_t f, flint_rand_t state, + slong len, mp_bitcnt_t bits) + + As for \code{fmpq_poly_randtest()} except that \code{len} and \code{bits} + may not be zero and the polynomial generated is guaranteed not to be the + zero polynomial. One must call \code{flint_randinit()} before calling + this function. + +******************************************************************************* + + Assignment, swap, negation + +******************************************************************************* + +void fmpq_poly_set(fmpq_poly_t poly1, const fmpq_poly_t poly2) + + Sets \code{poly1} to equal \code{poly2}. + +void fmpq_poly_set_si(fmpq_poly_t poly, slong x) + + Sets \code{poly} to the integer $x$. + +void fmpq_poly_set_ui(fmpq_poly_t poly, ulong x) + + Sets \code{poly} to the integer $x$. + +void fmpq_poly_set_fmpz(fmpq_poly_t poly, const fmpz_t x) + + Sets \code{poly} to the integer $x$. + +void fmpq_poly_set_fmpq(fmpq_poly_t poly, const fmpq_t x) + + Sets \code{poly} to the rational $x$, which is assumed to be + given in lowest terms. + +void fmpq_poly_set_mpz(fmpq_poly_t poly, const mpz_t x) + + Sets \code{poly} to the integer $x$. + +void fmpq_poly_set_mpq(fmpq_poly_t poly, const mpq_t x) + + Sets \code{poly} to the rational $x$, which is assumed to be + given in lowest terms. + +void fmpq_poly_set_fmpz_poly(fmpq_poly_t rop, const fmpz_poly_t op) + + Sets the rational polynomial \code{rop} to the same value + as the integer polynomial \code{op}. + +void _fmpq_poly_set_array_mpq(fmpz * poly, fmpz_t den, + const mpq_t * a, slong n) + + Sets \code{(poly, den)} to the polynomial given by the + first $n \geq 1$ coefficients in the array $a$, from lowest + degree to highest degree. + + The result is only guaranteed to be in lowest terms if all + input coefficients are given in lowest terms. + +void fmpq_poly_set_array_mpq(fmpq_poly_t poly, const mpq_t * a, slong n) + + Sets \code{poly} to the polynomial with coefficients as given in the + array $a$ of length $n \geq 0$, from lowest degree to highest degree. + + The result is only guaranteed to be in canonical form if all + input coefficients are given in lowest terms. + +int _fmpq_poly_set_str(fmpz * poly, fmpz_t den, const char * str) + + Sets \code{(poly, den)} to the polynomial specified by the null-terminated + string \code{str}. + + The result is only guaranteed to be in lowest terms if all + coefficients in the input string are in lowest terms. + + Returns $0$ if no error occurred. Otherwise, returns a non-zero value, + in which case the resulting value of \code{(poly, den)} is undefined. + If \code{str} is not null-terminated, calling this method might result + in a segmentation fault. + +int fmpq_poly_set_str(fmpq_poly_t poly, const char * str) + + Sets \code{poly} to the polynomial specified by the null-terminated + string \code{str}. + + The result is only guaranteed to be in canonical for if all + coefficients in the input string are in lowest terms. + + Returns $0$ if no error occurred. Otherwise, returns a non-zero + value, in which case the resulting value of \code{poly} is undefined. + If \code{str} is not null-terminated, calling this method might result + in a segmentation fault. + +char * fmpq_poly_get_str(const fmpq_poly_t poly) + + Returns the string representation of \code{poly}. + +char * fmpq_poly_get_str_pretty(const fmpq_poly_t poly, const char * var) + + Returns the pretty representation of \code{poly}, using the + null-terminated string \code{var} not equal to \code{"\0"} as + the variable name. + +void fmpq_poly_zero(fmpq_poly_t poly) + + Sets \code{poly} to zero. + +void fmpq_poly_one(fmpq_poly_t poly) + + Sets \code{poly} to the constant polynomial $1$. + +void fmpq_poly_neg(fmpq_poly_t poly1, const fmpq_poly_t poly2) + + Sets \code{poly1} to the additive inverse of \code{poly2}. + +void fmpq_poly_inv(fmpq_poly_t poly1, const fmpq_poly_t poly2) + + Sets \code{poly1} to the multiplicative inverse of \code{poly2} + if possible. Otherwise, if \code{poly2} is not a unit, leaves + \code{poly1} unmodified and calls \code{abort()}. + +void fmpq_poly_swap(fmpq_poly_t poly1, fmpq_poly_t poly2) + + Efficiently swaps the polynomials \code{poly1} and \code{poly2}. + +void fmpq_poly_truncate(fmpq_poly_t poly, slong n) + + If the current length of \code{poly} is greater than $n$, it is + truncated to the given length. Discarded coefficients are demoted, + but they are not necessarily set to zero. + +void fmpq_poly_get_slice(fmpq_poly_t rop, + const fmpq_poly_t op, slong i, slong j) + + Returns the slice with coefficients from $x^i$ (including) to + $x^j$ (excluding). + +void fmpq_poly_reverse(fmpq_poly_t res, const fmpq_poly_t poly, slong n) + + This function considers the polynomial \code{poly} to be of length $n$, + notionally truncating and zero padding if required, and reverses + the result. Since the function normalises its result \code{res} may be + of length less than $n$. + +******************************************************************************* + + Getting and setting coefficients + +******************************************************************************* + +void fmpq_poly_get_coeff_fmpq(fmpq_t x, const fmpq_poly_t poly, slong n) + + Retrieves the $n$th coefficient of \code{poly}, in lowest terms. + +void fmpq_poly_get_coeff_mpq(mpq_t x, const fmpq_poly_t poly, slong n) + + Retrieves the $n$th coefficient of \code{poly}, in lowest terms. + +void fmpq_poly_set_coeff_si(fmpq_poly_t poly, slong n, slong x) + + Sets the $n$th coefficient in \code{poly} to the integer $x$. + +void fmpq_poly_set_coeff_ui(fmpq_poly_t poly, slong n, ulong x) + + Sets the $n$th coefficient in \code{poly} to the integer $x$. + +void fmpq_poly_set_coeff_fmpz(fmpq_poly_t poly, slong n, const fmpz_t x) + + Sets the $n$th coefficient in \code{poly} to the integer $x$. + +void fmpq_poly_set_coeff_fmpq(fmpq_poly_t poly, slong n, const fmpq_t x) + + Sets the $n$th coefficient in \code{poly} to the rational $x$. + +void fmpq_poly_set_coeff_mpz(fmpq_poly_t rop, slong n, const mpz_t x) + + Sets the $n$th coefficient in \code{poly} to the integer $x$. + +void fmpq_poly_set_coeff_mpq(fmpq_poly_t rop, slong n, const mpq_t x) + + Sets the $n$th coefficient in \code{poly} to the rational~$x$, + which is expected to be provided in lowest terms. + +******************************************************************************* + + Comparison + +******************************************************************************* + +int fmpq_poly_equal(const fmpq_poly_t poly1, const fmpq_poly_t poly2) + + Returns $1$ if \code{poly1} is equal to \code{poly2}, + otherwise returns~$0$. + +int _fmpq_poly_cmp(const fmpz * lpoly, const fmpz_t lden, + const fmpz * rpoly, const fmpz_t rden, slong len) + + Compares two non-zero polynomials, assuming they have the same length + \code{len > 0}. + + The polynomials are expected to be provided in canonical form. + +int fmpq_poly_cmp(const fmpq_poly_t left, const fmpq_poly_t right) + + Compares the two polynomials \code{left} and \code{right}. + + Compares the two polynomials \code{left} and \code{right}, returning + $-1$, $0$, or $1$ as \code{left} is less than, equal to, or greater + than \code{right}. The comparison is first done by the degree, and + then, in case of a tie, by the individual coefficients from highest + to lowest. + +int fmpq_poly_is_one(const fmpq_poly_t poly) + + Returns $1$ if \code{poly} is the constant polynomial~$1$, otherwise + returns $0$. + +int fmpq_poly_is_zero(const fmpq_poly_t poly) + + Returns $1$ if \code{poly} is the zero polynomial, otherwise returns $0$. + +******************************************************************************* + + Addition and subtraction + +******************************************************************************* + +void _fmpq_poly_add(fmpz * rpoly, fmpz_t rden, + const fmpz * poly1, const fmpz_t den1, slong len1, + const fmpz * poly2, const fmpz_t den2, slong len2) + + Forms the sum \code{(rpoly, rden)} of \code{(poly1, den1, len1)} and + \code{(poly2, den2, len2)}, placing the result into canonical form. + + Assumes that \code{rpoly} is an array of length the maximum of + \code{len1} and \code{len2}. The input operands are assumed to + be in canonical form and are also allowed to be of length~$0$. + + \code{(rpoly, rden)} and \code{(poly1, den1)} may be aliased, + but \code{(rpoly, rden)} and \code{(poly2, den2)} may \emph{not} + be aliased. + +void _fmpq_poly_add_can(fmpz * rpoly, fmpz_t rden, + const fmpz * poly1, const fmpz_t den1, slong len1, + const fmpz * poly2, const fmpz_t den2, slong len2, int can) + + As per \code{_fmpq_poly_add} except that one can specify whether to + canonicalise the output or not. This function is intended to be used with + weak canonicalisation to prevent explosion in memory usage. It exists for + performance reasons. + +void fmpq_poly_add(fmpq_poly_t res, fmpq_poly poly1, fmpq_poly poly2) + + Sets \code{res} to the sum of \code{poly1} and \code{poly2}, using + Henrici's algorithm. + +void fmpq_poly_add_can(fmpq_poly_t res, fmpq_poly poly1, + fmpq_poly poly2, int can) + + As per \code{fmpq_poly_add} except that one can specify whether to + canonicalise the output or not. This function is intended to be used with + weak canonicalisation to prevent explosion in memory usage. It exists for + performance reasons. + +void _fmpq_poly_sub(fmpz * rpoly, fmpz_t rden, + const fmpz * poly1, const fmpz_t den1, slong len1, + const fmpz * poly2, const fmpz_t den2, slong len2) + + Forms the difference \code{(rpoly, rden)} of \code{(poly1, den1, len1)} + and \code{(poly2, den2, len2)}, placing the result into canonical form. + + Assumes that \code{rpoly} is an array of length the maximum of + \code{len1} and \code{len2}. The input operands are assumed to be in + canonical form and are also allowed to be of length~$0$. + + \code{(rpoly, rden)} and \code{(poly1, den1, len1)} may be aliased, + but \code{(rpoly, rden)} and \code{(poly2, den2, len2)} may \emph{not} be + aliased. + +void _fmpq_poly_sub_can(fmpz * rpoly, fmpz_t rden, + const fmpz * poly1, const fmpz_t den1, slong len1, + const fmpz * poly2, const fmpz_t den2, slong len2, int can) + + As per \code{_fmpq_poly_sub} except that one can specify whether to + canonicalise the output or not. This function is intended to be used with + weak canonicalisation to prevent explosion in memory usage. It exists for + performance reasons. + +void fmpq_poly_sub(fmpq_poly_t res, fmpq_poly poly1, fmpq_poly poly2) + + Sets \code{res} to the difference of \code{poly1} and \code{poly2}, + using Henrici's algorithm. + +void fmpq_poly_sub_can(fmpq_poly_t res, fmpq_poly poly1, + fmpq_poly poly2, int can) + + As per \code{_fmpq_poly_sub} except that one can specify whether to + canonicalise the output or not. This function is intended to be used with + weak canonicalisation to prevent explosion in memory usage. It exists for + performance reasons. + +******************************************************************************* + + Scalar multiplication and division + +******************************************************************************* + +void _fmpq_poly_scalar_mul_si(fmpz * rpoly, fmpz_t rden, + const fmpz * poly, const fmpz_t den, slong len, slong c) + + Sets \code{(rpoly, rden, len)} to the product of $c$ of + \code{(poly, den, len)}. + + If the input is normalised, then so is the output, provided it is + non-zero. If the input is in lowest terms, then so is the output. + However, even if neither of these conditions are met, the result + will be (mathematically) correct. + + Supports exact aliasing between \code{(rpoly, den)} + and \code{(poly, den)}. + +void _fmpq_poly_scalar_mul_ui(fmpz * rpoly, fmpz_t rden, + const fmpz * poly, const fmpz_t den, slong len, ulong c) + + Sets \code{(rpoly, rden, len)} to the product of $c$ of + \code{(poly, den, len)}. + + If the input is normalised, then so is the output, provided it is + non-zero. If the input is in lowest terms, then so is the output. + However, even if neither of these conditions are met, the result + will be (mathematically) correct. + + Supports exact aliasing between \code{(rpoly, den)} + and \code{(poly, den)}. + +void _fmpq_poly_scalar_mul_fmpz(fmpz * rpoly, fmpz_t rden, + const fmpz * poly, const fmpz_t den, slong len, const fmpz_t c) + + Sets \code{(rpoly, rden, len)} to the product of $c$ of + \code{(poly, den, len)}. + + If the input is normalised, then so is the output, provided it is + non-zero. If the input is in lowest terms, then so is the output. + However, even if neither of these conditions are met, the result + will be (mathematically) correct. + + Supports exact aliasing between \code{(rpoly, den)} + and \code{(poly, den)}. + +void _fmpq_poly_scalar_mul_fmpq(fmpz * rpoly, fmpz_t rden, const fmpz * poly, + const fmpz_t den, slong len, const fmpz_t r, const fmpz_t s) + + Sets \code{(rpoly, rden)} to the product of $r/s$ and + \code{(poly, den, len)}, in lowest terms. + + Assumes that \code{(poly, den, len)} and $r/s$ are provided in lowest + terms. Assumes that \code{rpoly} is an array of length \code{len}. + Supports aliasing of \code{(rpoly, den)} and \code{(poly, den)}. + The \code{fmpz_t}'s $r$ and $s$ may not be part of \code{(rpoly, rden)}. + +void fmpq_poly_scalar_mul_si(fmpq_poly_t rop, const fmpq_poly_t op, slong c) + + Sets \code{rop} to $c$ times \code{op}. + +void fmpq_poly_scalar_mul_ui(fmpq_poly_t rop, const fmpq_poly_t op, ulong c) + + Sets \code{rop} to $c$ times \code{op}. + +void fmpq_poly_scalar_mul_fmpz(fmpq_poly_t rop, + const fmpq_poly_t op, const fmpz_t c) + + Sets \code{rop} to $c$ times \code{op}. Assumes that the \code{fmpz_t c} + is not part of \code{rop}. + +void fmpq_poly_scalar_mul_fmpq(fmpq_poly_t rop, + const fmpq_poly_t op, const mpq_t c) + + Sets \code{rop} to $c$ times \code{op}. + +void fmpq_poly_scalar_mul_mpz(fmpq_poly_t rop, + const fmpq_poly_t op, const mpz_t c) + + Sets \code{rop} to $c$ times \code{op}. + +void fmpq_poly_scalar_mul_mpq(fmpq_poly_t rop, + const fmpq_poly_t op, const fmpq_t c) + + Sets \code{rop} to $c$ times \code{op}. + +void _fmpq_poly_scalar_div_fmpz(fmpz * rpoly, fmpz_t rden, const fmpz * poly, + const fmpz_t den, slong len, const fmpz_t c) + + Sets \code{(rpoly, rden, len)} to \code{(poly, den, len)} divided by $c$, + in lowest terms. + + Assumes that \code{len} is positive. Assumes that $c$ is non-zero. + Supports aliasing between \code{(rpoly, rden)} and \code{(poly, den)}. + Assumes that $c$ is not part of \code{(rpoly, rden)}. + +void _fmpq_poly_scalar_div_si(fmpz * rpoly, fmpz_t rden, const fmpz * poly, + const fmpz_t den, slong len, slong c) + + Sets \code{(rpoly, rden, len)} to \code{(poly, den, len)} divided by $c$, + in lowest terms. + + Assumes that \code{len} is positive. Assumes that $c$ is non-zero. + Supports aliasing between \code{(rpoly, rden)} and \code{(poly, den)}. + +void _fmpq_poly_scalar_div_ui(fmpz * rpoly, fmpz_t rden, const fmpz * poly, + const fmpz_t den, slong len, ulong c) + + Sets \code{(rpoly, rden, len)} to \code{(poly, den, len)} divided by $c$, + in lowest terms. + + Assumes that \code{len} is positive. Assumes that $c$ is non-zero. + Supports aliasing between \code{(rpoly, rden)} and \code{(poly, den)}. + +void _fmpq_poly_scalar_div_fmpq(fmpz * rpoly, fmpz_t rden, const fmpz * poly, + const fmpz_t den, slong len, const fmpz_t r, const fmpz_t s) + + Sets \code{(rpoly, rden, len)} to \code{(poly, den, len)} divided by $r/s$, + in lowest terms. + + Assumes that \code{len} is positive. Assumes that $r/s$ is non-zero and + in lowest terms. Supports aliasing between \code{(rpoly, rden)} and + \code{(poly, den)}. The \code{fmpz_t}'s $r$ and $s$ may not be part of + \code{(rpoly, poly)}. + +void fmpq_poly_scalar_div_si(fmpq_poly_t rop, const fmpq_poly_t op, slong c) + +void fmpq_poly_scalar_div_ui(fmpq_poly_t rop, const fmpq_poly_t op, ulong c); + +void fmpq_poly_scalar_div_fmpz(fmpq_poly_t rop, + const fmpq_poly_t op, const fmpz_t c); + +void fmpq_poly_scalar_div_fmpq(fmpq_poly_t rop, + const fmpq_poly_t op, const fmpq_t c); + +void fmpq_poly_scalar_div_mpz(fmpq_poly_t rop, + const fmpq_poly_t op, const mpz_t c); + +void fmpq_poly_scalar_div_mpq(fmpq_poly_t rop, + const fmpq_poly_t op, const mpq_t c); + +******************************************************************************* + + Multiplication + +******************************************************************************* + +void _fmpq_poly_mul(fmpz * rpoly, fmpz_t rden, + const fmpz * poly1, const fmpz_t den1, slong len1, + const fmpz * poly2, const fmpz_t den2, slong len2) + + Sets \code{(rpoly, rden, len1 + len2 - 1)} to the product of + \code{(poly1, den1, len1)} and \code{(poly2, den2, len2)}. If the + input is provided in canonical form, then so is the output. + + Assumes \code{len1 >= len2 > 0}. Allows zero-padding in the input. + Does not allow aliasing between the inputs and outputs. + +void fmpq_poly_mul(fmpq_poly_t res, + const fmpq_poly_t poly1, const fmpq_poly_t poly2) + + Sets \code{res} to the product of \code{poly1} and \code{poly2}. + +void _fmpq_poly_mullow(fmpz * rpoly, fmpz_t rden, + const fmpz * poly1, const fmpz_t den1, slong len1, + const fmpz * poly2, const fmpz_t den2, slong len2, + slong n) + + Sets \code{(rpoly, rden, n)} to the low $n$ coefficients of + \code{(poly1, den1)} and \code{(poly2, den2)}. The output is + not guaranteed to be in canonical form. + + Assumes \code{len1 >= len2 > 0} and \code{0 < n <= len1 + len2 - 1}. + Allows for zero-padding in the inputs. Does not allow aliasing between + the inputs and outputs. + +void fmpq_poly_mullow(fmpq_poly_t res, + const fmpq_poly_t poly1, const fmpq_poly_t poly2, slong n) + + Sets \code{res} to the product of \code{poly1} and \code{poly2}, + truncated to length~$n$. + +void fmpq_poly_addmul(fmpq_poly_t rop, const fmpq_poly_t op1, + const fmpq_poly_t op2) + + Adds the product of \code{op1} and \code{op2} to \code{rop}. + +void fmpq_poly_submul(fmpq_poly_t rop, const fmpq_poly_t op1, + const fmpq_poly_t op2) + + Subtracts the product of \code{op1} and \code{op2} from \code{rop}. + +******************************************************************************* + + Powering + +******************************************************************************* + +void _fmpq_poly_pow(fmpz * rpoly, fmpz_t rden, + const fmpz * poly, const fmpz_t den, slong len, ulong e) + + Sets \code{(rpoly, rden)} to \code{(poly, den)^e}, assuming + \code{e, len > 0}. Assumes that \code{rpoly} is an array of + length at least \code{e * (len - 1) + 1}. Supports aliasing + of \code{(rpoly, den)} and \code{(poly, den)}. + +void fmpq_poly_pow(fmpq_poly_t res, const fmpq_poly_t poly, ulong e) + + Sets \code{res} to \code{pow^e}, where the only special case $0^0$ is + defined as $1$. + +******************************************************************************* + + Shifting + +******************************************************************************* + +void fmpz_poly_shift_left(fmpz_poly_t res, const fmpz_poly_t poly, slong n) + + Set \code{res} to \code{poly} shifted left by $n$ coefficients. Zero + coefficients are inserted. + +void fmpz_poly_shift_right(fmpz_poly_t res, const fmpz_poly_t poly, slong n) + + Set \code{res} to \code{poly} shifted right by $n$ coefficients. + If $n$ is equal to or greater than the current length of \code{poly}, + \code{res} is set to the zero polynomial. + +******************************************************************************* + + Euclidean division + +******************************************************************************* + +void _fmpq_poly_divrem(fmpz * Q, fmpz_t q, fmpz * R, fmpz_t r, + const fmpz * A, const fmpz_t a, slong lenA, + const fmpz * B, const fmpz_t b, slong lenB, const fmpz_preinvn_t inv) + + Finds the quotient \code{(Q, q)} and remainder \code{(R, r)} of the + Euclidean division of \code{(A, a)} by \code{(B, b)}. + + Assumes that \code{lenA >= lenB > 0}. Assumes that $R$ has space for + \code{lenA} coefficients, although only the bottom \code{lenB - 1} will + carry meaningful data on exit. Supports no aliasing between the two + outputs, or between the inputs and the outputs. + + An optional precomputed inverse of the leading coefficient of $B$ from + \code{fmpz_preinvn_init} can be supplied. Otherwise \code{inv} should be + \code{NULL}. + +void fmpq_poly_divrem(fmpq_poly_t Q, fmpq_poly_t R, + const fmpq_poly_t poly1, const fmpq_poly_t poly2) + + Finds the quotient $Q$ and remainder $R$ of the Euclidean division of + \code{poly1} by \code{poly2}. + +void _fmpq_poly_div(fmpz * Q, fmpz_t q, + const fmpz * A, const fmpz_t a, slong lenA, + const fmpz * B, const fmpz_t b, slong lenB, const fmpz_preinvn_t inv) + + Finds the quotient \code{(Q, q)} of the Euclidean division + of \code{(A, a)} by \code{(B, b)}. + + Assumes that \code{lenA >= lenB > 0}. Supports no aliasing + between the inputs and the outputs. + + An optional precomputed inverse of the leading coefficient of $B$ from + \code{fmpz_preinvn_init} can be supplied. Otherwise \code{inv} should be + \code{NULL}. + +void fmpq_poly_div(fmpq_poly_t Q, + const fmpq_poly_t poly1, const fmpq_poly_t poly2) + + Finds the quotient $Q$ and remainder $R$ of the Euclidean division + of \code{poly1} by \code{poly2}. + +void _fmpq_poly_rem(fmpz * R, fmpz_t r, + const fmpz * A, const fmpz_t a, slong lenA, + const fmpz * B, const fmpz_t b, slong lenB, const fmpz_preinvn_t inv) + + Finds the remainder \code{(R, r)} of the Euclidean division + of \code{(A, a)} by \code{(B, b)}. + + Assumes that \code{lenA >= lenB > 0}. Supports no aliasing between + the inputs and the outputs. + + An optional precomputed inverse of the leading coefficient of $B$ from + \code{fmpz_preinvn_init} can be supplied. Otherwise \code{inv} should be + \code{NULL}. + +void fmpq_poly_rem(fmpq_poly_t R, + const fmpq_poly_t poly1, const fmpq_poly_t poly2) + + Finds the remainder $R$ of the Euclidean division + of \code{poly1} by \code{poly2}. + +******************************************************************************* + + Euclidean division + +******************************************************************************* + +fmpq_poly_struct * _fmpq_poly_powers_precompute(const fmpz * B, + const fmpz_t denB, slong len) + + Computes \code{2*len - 1} powers of $x$ modulo the polynomial $B$ of + the given length. This is used as a kind of precomputed inverse in + the remainder routine below. + +void fmpq_poly_powers_precompute(fmpq_poly_powers_precomp_t pinv, + fmpq_poly_t poly) + Computes \code{2*len - 1} powers of $x$ modulo the polynomial $B$ of + the given length. This is used as a kind of precomputed inverse in + the remainder routine below. + +void _fmpq_poly_powers_clear(fmpq_poly_struct * powers, slong len) + + Clean up resources used by precomputed powers which have been computed + by\\ + \code{_fmpq_poly_powers_precompute}. + +void fmpq_poly_powers_clear(fmpq_poly_powers_precomp_t pinv) + + Clean up resources used by precomputed powers which have been computed + by\\ + \code{fmpq_poly_powers_precompute}. + +void _fmpq_poly_rem_powers_precomp(fmpz * A, fmpz_t denA, slong m, + const fmpz * B, const fmpz_t denB, slong n, + const fmpq_poly_struct * const powers) + + Set $A$ to the remainder of $A$ divide $B$ given precomputed powers mod $B$ + provided by \code{_fmpq_poly_powers_precompute}. No aliasing is allowed. + + This function is only faster if $m \leq 2*n - 1$. + + The output of this function is \emph{not} canonicalised. + +void fmpq_poly_rem_powers_precomp(fmpq_poly_t R, const fmpq_poly_t A, + const fmpq_poly_t B, const fmpq_poly_powers_precomp_t B_inv) + + Set $R$ to the remainder of $A$ divide $B$ given precomputed powers mod $B$ + provided by \code{fmpq_poly_powers_precompute}. + + This function is only faster if \code{A->length <= 2*B->length - 1}. + + The output of this function is \emph{not} canonicalised. + +******************************************************************************* + + Power series division + +******************************************************************************* + +void _fmpq_poly_inv_series_newton(fmpz * rpoly, fmpz_t rden, + const fmpz * poly, const fmpz_t den, slong n) + + Computes the first $n$ terms of the inverse power series of + \code{poly} using Newton iteration. + + The result is produced in canonical form. + + Assumes that $n \geq 1$, that \code{poly} has length at least~$n$ + and non-zero constant term. Does not support aliasing. + +void fmpq_poly_inv_series_newton(fmpq_poly_t res, + const fmpq_poly_t poly, slong n) + + Computes the first $n$ terms of the inverse power series + of \code{poly} using Newton iteration, assuming that \code{poly} + has non-zero constant term and $n \geq 1$. + +void _fmpq_poly_inv_series(fmpz * rpoly, fmpz_t rden, + const fmpz * poly, const fmpz_t den, slong n) + + Computes the first $n$ terms of the inverse power series of \code{poly}. + + Assumes that $n \geq 1$, that \code{poly} has length at least~$n$ and + non-zero constant term. Does not support aliasing. + +void fmpq_poly_inv_series(fmpq_poly_t res, const fmpq_poly_t poly, slong n) + + Computes the first $n$ terms of the inverse power series of \code{poly}, + assuming that \code{poly} has non-zero constant term and $n \geq 1$. + +void _fmpq_poly_div_series(fmpz * Q, fmpz_t denQ, + const fmpz * A, const fmpz_t denA, + const fmpz * B, const fmpz_t denB, slong n) + + Divides \code{(A, denA, n)} by \code{(B, denB, n)} as power series + over $\Q$, assuming $B$ has non-zero constant term and $n \geq 1$. + + Supports no aliasing other than that of \code{(Q, denQ, n)} + and \code{(B, denB, n)}. + + This function does not ensure that the numerator and denominator + are coprime on exit. + +void fmpq_poly_div_series(fmpq_poly_t Q, const fmpq_poly_t A, + const fmpq_poly_t B, slong n) + + Performs power series division in $\Q[[x]] / (x^n)$. The function + considers the polynomials $A$ and $B$ as power series of length~$n$ + starting with the constant terms. The function assumes that $B$ has + non-zero constant term and $n \geq 1$. + +******************************************************************************* + + Greatest common divisor + +******************************************************************************* + +void _fmpq_poly_gcd(fmpz *G, fmpz_t denG, + const fmpz *A, slong lenA, const fmpz *B, slong lenB) + + Computes the monic greatest common divisor $G$ of $A$ and $B$. + + Assumes that $G$ has space for $\len(B)$ coefficients, + where $\len(A) \geq \len(B) > 0$. + + Aliasing between the output and input arguments is not supported. + + Does not support zero-padding. + +void fmpq_poly_gcd(fmpq_poly_t G, const fmpq_poly_t A, const fmpq_poly_t B) + + Computes the monic greatest common divisor $G$ of $A$ and $B$. + + In the the special case when $A = B = 0$, sets $G = 0$. + +void _fmpq_poly_xgcd(fmpz *G, fmpz_t denG, + fmpz *S, fmpz_t denS, fmpz *T, fmpz_t denT, + const fmpz *A, const fmpz_t denA, slong lenA, + const fmpz *B, const fmpz_t denB, slong lenB) + + Computes polynomials $G$, $S$, and $T$ such that + $G = \gcd(A, B) = S A + T B$, where $G$ is the monic + greatest common divisor of $A$ and $B$. + + Assumes that $G$, $S$, and $T$ have space for $\len(B)$, + $\len(B)$, and $\len(A)$ coefficients, respectively, + where it is also assumed that $\len(A) \geq \len(B) > 0$. + + Does not support zero padding of the input arguments. + +void fmpq_poly_xgcd(fmpq_poly_t G, fmpz_poly_t S, fmpz_poly_t T, + const fmpq_poly_t A, const fmpq_poly_t B) + + Computes polynomials $G$, $S$, and $T$ such that + $G = \gcd(A, B) = S A + T B$, where $G$ is the monic + greatest common divisor of $A$ and $B$. + + Corner cases are handled as follows. If $A = B = 0$, returns + $G = S = T = 0$. If $A \neq 0$, $B = 0$, returns the suitable + scalar multiple of $G = A$, $S = 1$, and $T = 0$. The case + when $A = 0$, $B \neq 0$ is handled similarly. + +void _fmpq_poly_lcm(fmpz *L, fmpz_t denL, + const fmpz *A, slong lenA, const fmpz *B, slong lenB) + + Computes the monic least common multiple $L$ of $A$ and $B$. + + Assumes that $L$ has space for $\len(A) + \len(B) - 1$ coefficients, + where $\len(A) \geq \len(B) > 0$. + + Aliasing between the output and input arguments is not supported. + + Does not support zero-padding. + +void fmpq_poly_lcm(fmpq_poly_t L, const fmpq_poly_t A, const fmpq_poly_t B) + + Computes the monic least common multiple $L$ of $A$ and $B$. + + In the special case when $A = B = 0$, sets $L = 0$. + +void _fmpq_poly_resultant(fmpz_t rnum, fmpz_t rden, + const fmpz *poly1, const fmpz_t den1, slong len1, + const fmpz *poly2, const fmpz_t den2, slong len2) + + Sets \code{(rnum, rden)} to the resultant of the two input + polynomials. + + Assumes that \code{len1 >= len2 > 0}. Does not support zero-padding + of the input polynomials. Does not support aliasing of the input and + output arguments. + +void fmpq_poly_resultant(fmpq_t r, const fmpq_poly_t f, const fmpq_poly_t g) + + Returns the resultant of $f$ and $g$. + + Enumerating the roots of $f$ and $g$ over $\bar{\mathbf{Q}}$ as + $r_1, \dotsc, r_m$ and $s_1, \dotsc, s_n$, respectively, and + letting $x$ and $y$ denote the leading coefficients, the resultant + is defined as + \begin{equation*} + x^{\deg(f)} y^{\deg(g)} \prod_{1 \leq i, j \leq n} (r_i - s_j). + \end{equation*} + + We handle special cases as follows: if one of the polynomials is zero, + the resultant is zero. Note that otherwise if one of the polynomials is + constant, the last term in the above expression is the empty product. + +******************************************************************************* + + Derivative and integral + +******************************************************************************* + +void _fmpq_poly_derivative(fmpz * rpoly, fmpz_t rden, + const fmpz * poly, const fmpz_t den, slong len) + + Sets \code{(rpoly, rden, len - 1)} to the derivative of + \code{(poly, den, len)}. Does nothing if \code{len <= 1}. + Supports aliasing between the two polynomials. + +void fmpq_poly_derivative(fmpq_poly_t res, const fmpq_poly_t poly) + + Sets \code{res} to the derivative of \code{poly}. + +void _fmpq_poly_integral(fmpz * rpoly, fmpz_t rden, + const fmpz * poly, const fmpz_t den, slong len) + + Sets \code{(rpoly, rden, len)} to the integral of + \code{(poly, den, len - 1)}. Assumes \code{len >= 0}. + Supports aliasing between the two polynomials. + +void fmpq_poly_integral(fmpq_poly_t res, const fmpq_poly_t poly) + + Sets \code{res} to the integral of \code{poly}. The constant + term is set to zero. In particular, the integral of the zero + polynomial is the zero polynomial. + +******************************************************************************* + + Square roots + +******************************************************************************* + +void _fmpq_poly_sqrt_series(fmpz * g, fmpz_t gden, + const fmpz * f, const fmpz_t fden, slong n) + + Sets \code{(g, gden, n)} to the series expansion of the + square root of \code{(f, fden, n)}. Assumes \code{n > 0} and + that \code{(f, fden, n)} has constant term 1. + Does not support aliasing between the input and output polynomials. + +void fmpq_poly_sqrt_series(fmpq_poly_t res, const fmpq_poly_t f, slong n) + + Sets \code{res} to the series expansion of the square root of \code{f} + to order \code{n > 1}. Requires \code{f} to have constant term 1. + +void _fmpq_poly_invsqrt_series(fmpz * g, fmpz_t gden, + const fmpz * f, const fmpz_t fden, slong n) + + Sets \code{(g, gden, n)} to the series expansion of the inverse + square root of \code{(f, fden, n)}. Assumes \code{n > 0} and + that \code{(f, fden, n)} has constant term 1. + Does not support aliasing between the input and output polynomials. + +void fmpq_poly_invsqrt_series(fmpq_poly_t res, const fmpq_poly_t f, slong n) + + Sets \code{res} to the series expansion of the inverse square root of + \code{f} to order \code{n > 0}. Requires \code{f} to have constant term 1. + +******************************************************************************* + + Transcendental functions + +******************************************************************************* + +void _fmpq_poly_log_series(fmpz * g, fmpz_t gden, + const fmpz * f, const fmpz_t fden, slong n) + + Sets \code{(g, gden, n)} to the series expansion of the + logarithm of \code{(f, fden, n)}. Assumes \code{n > 0} and + that \code{(f, fden, n)} has constant term 1. + Supports aliasing between the input and output polynomials. + +void fmpq_poly_log_series(fmpq_poly_t res, const fmpq_poly_t f, slong n) + + Sets \code{res} to the series expansion of the logarithm of \code{f} + to order \code{n > 0}. Requires \code{f} to have constant term 1. + +void _fmpq_poly_exp_series(fmpz * g, fmpz_t gden, + const fmpz * h, const fmpz_t hden, slong n) + + Sets \code{(g, gden, n)} to the series expansion of the + exponential function of \code{(f, fden, n)}. Assumes \code{n > 0} and + that \code{(f, fden, n)} has constant term 0. + Does not support aliasing between the input and output polynomials. + +void fmpq_poly_exp_series(fmpq_poly_t res, const fmpq_poly_t h, slong n) + + Sets \code{res} to the series expansion of the exponential function + of \code{f} to order \code{n > 0}. Requires \code{f} to have + constant term 0. + +void _fmpq_poly_atan_series(fmpz * g, fmpz_t gden, + const fmpz * f, const fmpz_t fden, slong n) + + Sets \code{(g, gden, n)} to the series expansion of the + inverse tangent of \code{(f, fden, n)}. Assumes \code{n > 0} and + that \code{(f, fden, n)} has constant term 0. + Supports aliasing between the input and output polynomials. + +void fmpq_poly_atan_series(fmpq_poly_t res, const fmpq_poly_t f, slong n) + + Sets \code{res} to the series expansion of the inverse tangent of \code{f} + to order \code{n > 0}. Requires \code{f} to have constant term 0. + +void _fmpq_poly_atanh_series(fmpz * g, fmpz_t gden, + const fmpz * f, const fmpz_t fden, slong n) + + Sets \code{(g, gden, n)} to the series expansion of the inverse + hyperbolic tangent of \code{(f, fden, n)}. Assumes \code{n > 0} and + that \code{(f, fden, n)} has constant term 0. + Supports aliasing between the input and output polynomials. + +void fmpq_poly_atanh_series(fmpq_poly_t res, const fmpq_poly_t f, slong n) + + Sets \code{res} to the series expansion of the inverse hyperbolic + tangent of \code{f} to order \code{n > 0}. Requires \code{f} to have + constant term 0. + +void _fmpq_poly_asin_series(fmpz * g, fmpz_t gden, + const fmpz * f, const fmpz_t fden, slong n) + + Sets \code{(g, gden, n)} to the series expansion of the + inverse sine of \code{(f, fden, n)}. Assumes \code{n > 0} and + that \code{(f, fden, n)} has constant term 0. + Supports aliasing between the input and output polynomials. + +void fmpq_poly_asin_series(fmpq_poly_t res, const fmpq_poly_t f, slong n) + + Sets \code{res} to the series expansion of the inverse sine of \code{f} + to order \code{n > 0}. Requires \code{f} to have constant term 0. + +void _fmpq_poly_asinh_series(fmpz * g, fmpz_t gden, + const fmpz * f, const fmpz_t fden, slong n) + + Sets \code{(g, gden, n)} to the series expansion of the inverse + hyperbolic sine of \code{(f, fden, n)}. Assumes \code{n > 0} and + that \code{(f, fden, n)} has constant term 0. + Supports aliasing between the input and output polynomials. + +void fmpq_poly_asinh_series(fmpq_poly_t res, const fmpq_poly_t f, slong n) + + Sets \code{res} to the series expansion of the inverse hyperbolic + sine of \code{f} to order \code{n > 0}. Requires \code{f} to have + constant term 0. + +void _fmpq_poly_tan_series(fmpz * g, fmpz_t gden, + const fmpz * h, const fmpz_t hden, slong n) + + Sets \code{(g, gden, n)} to the series expansion of the + tangent function of \code{(f, fden, n)}. Assumes \code{n > 0} and + that \code{(f, fden, n)} has constant term 0. + Does not support aliasing between the input and output polynomials. + +void fmpq_poly_tan_series(fmpq_poly_t res, const fmpq_poly_t h, slong n) + + Sets \code{res} to the series expansion of the tangent function + of \code{f} to order \code{n > 0}. Requires \code{f} to have + constant term 0. + +void _fmpq_poly_sin_series(fmpz * g, fmpz_t gden, + const fmpz * f, const fmpz_t fden, slong n) + + Sets \code{(g, gden, n)} to the series expansion of the + sine of \code{(f, fden, n)}. Assumes \code{n > 0} and + that \code{(f, fden, n)} has constant term 0. + Supports aliasing between the input and output polynomials. + +void fmpq_poly_sin_series(fmpq_poly_t res, const fmpq_poly_t f, slong n) + + Sets \code{res} to the series expansion of the sine of \code{f} + to order \code{n > 0}. Requires \code{f} to have constant term 0. + +void _fmpq_poly_cos_series(fmpz * g, fmpz_t gden, + const fmpz * f, const fmpz_t fden, slong n) + + Sets \code{(g, gden, n)} to the series expansion of the + cosine of \code{(f, fden, n)}. Assumes \code{n > 0} and + that \code{(f, fden, n)} has constant term 0. + Supports aliasing between the input and output polynomials. + +void fmpq_poly_cos_series(fmpq_poly_t res, const fmpq_poly_t f, slong n) + + Sets \code{res} to the series expansion of the cosine of \code{f} + to order \code{n > 0}. Requires \code{f} to have constant term 0. + +void _fmpq_poly_sinh_series(fmpz * g, fmpz_t gden, + const fmpz * f, const fmpz_t fden, slong n) + + Sets \code{(g, gden, n)} to the series expansion of the + hyperbolic sine of \code{(f, fden, n)}. Assumes \code{n > 0} and + that \code{(f, fden, n)} has constant term 0. + Does not support aliasing between the input and output polynomials. + +void fmpq_poly_sinh_series(fmpq_poly_t res, const fmpq_poly_t f, slong n) + + Sets \code{res} to the series expansion of the hyperbolic sine of \code{f} + to order \code{n > 0}. Requires \code{f} to have constant term 0. + +void _fmpq_poly_cosh_series(fmpz * g, fmpz_t gden, + const fmpz * f, const fmpz_t fden, slong n) + + Sets \code{(g, gden, n)} to the series expansion of the hyperbolic + cosine of \code{(f, fden, n)}. Assumes \code{n > 0} and + that \code{(f, fden, n)} has constant term 0. + Does not support aliasing between the input and output polynomials. + +void fmpq_poly_cosh_series(fmpq_poly_t res, const fmpq_poly_t f, slong n) + + Sets \code{res} to the series expansion of the hyperbolic cosine of + \code{f} to order \code{n > 0}. Requires \code{f} to have constant term 0. + +void _fmpq_poly_tanh_series(fmpz * g, fmpz_t gden, + const fmpz * f, const fmpz_t fden, slong n) + + Sets \code{(g, gden, n)} to the series expansion of the + hyperbolic tangent of \code{(f, fden, n)}. Assumes \code{n > 0} and + that \code{(f, fden, n)} has constant term 0. + Does not support aliasing between the input and output polynomials. + +void fmpq_poly_tanh_series(fmpq_poly_t res, const fmpq_poly_t f, slong n) + + Sets \code{res} to the series expansion of the hyperbolic tangent of + \code{f} to order \code{n > 0}. Requires \code{f} to have constant term 0. + +******************************************************************************* + + Evaluation + +******************************************************************************* + +void _fmpq_poly_evaluate_fmpz(fmpz_t rnum, fmpz_t rden, const fmpz * poly, + const fmpz_t den, slong len, const fmpz_t a) + + Evaluates the polynomial \code{(poly, den, len)} at the integer $a$ and + sets \code{(rnum, rden)} to the result in lowest terms. + +void fmpq_poly_evaluate_fmpz(fmpq_t res, const fmpq_poly_t poly, + const fmpz_t a) + + Evaluates the polynomial \code{poly} at the integer $a$ and sets + \code{res} to the result. + +void _fmpq_poly_evaluate_fmpq(fmpz_t rnum, fmpz_t rden, + const fmpz * poly, const fmpz_t den, slong len, + const fmpz_t anum, const fmpz_t aden) + + Evaluates the polynomial \code{(poly, den, len)} at the rational + \code{(anum, aden)} and sets \code{(rnum, rden)} to the result in + lowest terms. Aliasing between \code{(rnum, rden)} and + \code{(anum, aden)} is not supported. + +void fmpq_poly_evaluate_fmpq(fmpq_t res, + const fmpq_poly_t poly, const fmpq_t a) + + Evaluates the polynomial \code{poly} at the rational $a$ and + sets \code{res} to the result. + +void fmpq_poly_evaluate_mpz(mpq_t res, const fmpq_poly_t poly, const mpz_t a) + + Evaluates the polynomial \code{poly} at the integer $a$ of type + \code{mpz} and sets \code{res} to the result. + +void fmpq_poly_evaluate_mpq(mpq_t res, const fmpq_poly_t poly, const mpq_t a) + + Evaluates the polynomial \code{poly} at the rational $a$ of type + \code{mpq} and sets \code{res} to the result. + +******************************************************************************* + + Interpolation + +******************************************************************************* + +void +_fmpq_poly_interpolate_fmpz_vec(fmpz * poly, fmpz_t den, + const fmpz * xs, const fmpz * ys, slong n) + + Sets \code{poly} / \code{den} to the unique interpolating polynomial of + degree at most $n - 1$ satisfying $f(x_i) = y_i$ for every pair $x_i, y_i$ + in \code{xs} and \code{ys}. + + The vector \code{poly} must have room for \code{n+1} coefficients, + even if the interpolating polynomial is shorter. + Aliasing of \code{poly} or \code{den} with any other argument is not + allowed. + + It is assumed that the $x$ values are distinct. + + This function uses a simple $O(n^2)$ implementation of Lagrange + interpolation, clearing denominators to avoid working with fractions. + It is currently not designed to be efficient for large $n$. + +fmpq_poly_interpolate_fmpz_vec(fmpq_poly_t poly, + const fmpz * xs, const fmpz * ys, slong n) + + Sets \code{poly} to the unique interpolating polynomial of degree + at most $n - 1$ satisfying $f(x_i) = y_i$ for every pair $x_i, y_i$ + in \code{xs} and \code{ys}. It is assumed that the $x$ values are distinct. + +******************************************************************************* + + Composition + +******************************************************************************* + +void _fmpq_poly_compose(fmpz * res, fmpz_t den, + const fmpz * poly1, const fmpz_t den1, slong len1, + const fmpz * poly2, const fmpz_t den2, slong len2) + + Sets \code{(res, den)} to the composition of \code{(poly1, den1, len1)} + and \code{(poly2, den2, len2)}, assuming \code{len1, len2 > 0}. + + Assumes that \code{res} has space for \code{(len1 - 1) * (len2 - 1) + 1} + coefficients. Does not support aliasing. + +void fmpq_poly_compose(fmpq_poly_t res, + const fmpq_poly_t poly1, const fmpq_poly_t poly2) + + Sets \code{res} to the composition of \code{poly1} and \code{poly2}. + +void _fmpq_poly_rescale(fmpz * res, fmpz_t denr, const fmpz * poly, + const fmpz_t den, slong len, const fmpz_t anum, const fmpz_t aden) + + Sets \code{(res, denr, len)} to \code{(poly, den, len)} with the + indeterminate rescaled by \code{(anum, aden)}. + + Assumes that \code{len > 0} and that \code{(anum, aden)} is non-zero and + in lowest terms. Supports aliasing between \code{(res, denr, len)} and + \code{(poly, den, len)}. + +void fmpz_poly_rescale(fmpq_poly_t res, + const fmpq_poly_t poly, const fmpq_t a) + + Sets \code{res} to \code{poly} with the indeterminate rescaled by $a$. + +******************************************************************************* + + Power series composition + +******************************************************************************* + +void _fmpq_poly_compose_series_horner(fmpz * res, fmpz_t den, + const fmpz * poly1, const fmpz_t den1, slong len1, const fmpz * poly2, + const fmpz_t den2, slong len2, slong n) + + Sets \code{(res, den, n)} to the composition of + \code{(poly1, den1, len1)} and \code{(poly2, den2, len2)} modulo $x^n$, + where the constant term of \code{poly2} is required to be zero. + + Assumes that \code{len1, len2, n > 0}, that \code{len1, len2 <= n}, + that \code{(len1-1) * (len2-1) + 1 <= n}, and that \code{res} has + space for \code{n} coefficients. Does not support aliasing between any + of the inputs and the output. + + This implementation uses the Horner scheme. + The default \code{fmpz_poly} composition algorithm is automatically + used when the composition can be performed over the integers. + +void fmpq_poly_compose_series_horner(fmpq_poly_t res, + const fmpq_poly_t poly1, const fmpq_poly_t poly2, slong n) + + Sets \code{res} to the composition of \code{poly1} and \code{poly2} + modulo $x^n$, where the constant term of \code{poly2} is required + to be zero. + + This implementation uses the Horner scheme. + The default \code{fmpz_poly} composition algorithm is automatically + used when the composition can be performed over the integers. + +void _fmpq_poly_compose_series_brent_kung(fmpz * res, fmpz_t den, + const fmpz * poly1, const fmpz_t den1, slong len1, const fmpz * poly2, + const fmpz_t den2, slong len2, slong n) + + Sets \code{(res, den, n)} to the composition of + \code{(poly1, den1, len1)} and \code{(poly2, den2, len2)} modulo $x^n$, + where the constant term of \code{poly2} is required to be zero. + + Assumes that \code{len1, len2, n > 0}, that \code{len1, len2 <= n}, + that \code{(len1-1) * (len2-1) + 1 <= n}, and that \code{res} has + space for \code{n} coefficients. Does not support aliasing between any + of the inputs and the output. + + This implementation uses Brent-Kung algorithm 2.1 \cite{BrentKung1978}. + The default \code{fmpz_poly} composition algorithm is automatically + used when the composition can be performed over the integers. + +void fmpq_poly_compose_series_brent_kung(fmpq_poly_t res, + const fmpq_poly_t poly1, const fmpq_poly_t poly2, slong n) + + Sets \code{res} to the composition of \code{poly1} and \code{poly2} + modulo $x^n$, where the constant term of \code{poly2} is required + to be zero. + + This implementation uses Brent-Kung algorithm 2.1 \cite{BrentKung1978}. + The default \code{fmpz_poly} composition algorithm is automatically + used when the composition can be performed over the integers. + +void _fmpq_poly_compose_series(fmpz * res, fmpz_t den, const fmpz * poly1, + const fmpz_t den1, slong len1, const fmpz * poly2, + const fmpz_t den2, slong len2, slong n) + + Sets \code{(res, den, n)} to the composition of + \code{(poly1, den1, len1)} and \code{(poly2, den2, len2)} modulo $x^n$, + where the constant term of \code{poly2} is required to be zero. + + Assumes that \code{len1, len2, n > 0}, that \code{len1, len2 <= n}, + that \code{(len1-1) * (len2-1) + 1 <= n}, and that \code{res} has + space for \code{n} coefficients. Does not support aliasing between any + of the inputs and the output. + + This implementation automatically switches between the Horner scheme + and Brent-Kung algorithm 2.1 depending on the size of the inputs. + The default \code{fmpz_poly} composition algorithm is automatically + used when the composition can be performed over the integers. + +void fmpq_poly_compose_series(fmpq_poly_t res, + const fmpq_poly_t poly1, const fmpq_poly_t poly2, slong n) + + Sets \code{res} to the composition of \code{poly1} and \code{poly2} + modulo $x^n$, where the constant term of \code{poly2} is required + to be zero. + + This implementation automatically switches between the Horner scheme + and Brent-Kung algorithm 2.1 depending on the size of the inputs. + The default \code{fmpz_poly} composition algorithm is automatically + used when the composition can be performed over the integers. + +******************************************************************************* + + Power series reversion + +******************************************************************************* + +void _fmpq_poly_revert_series_lagrange(fmpz * res, fmpz_t den, + const fmpz * poly1, const fmpz_t den1, slong n) + + Sets \code{(res, den)} to the power series reversion of + \code{(poly1, den1)} modulo $x^n$, where the input has + length $n$ (possibly being zero-padded). + + The constant term of \code{poly2} is required to be zero and + the linear term is required to be nonzero. Assumes that $n > 0$. + Does not support aliasing between any of the inputs and the output. + + This implementation uses the Lagrange inversion formula. + The default \code{fmpz_poly} reversion algorithm is automatically + used when the reversion can be performed over the integers. + +void fmpq_poly_revert_series_lagrange(fmpq_poly_t res, + const fmpq_poly_t poly, slong n) + + Sets \code{res} to the power series reversion of \code{poly1} modulo $x^n$. + The constant term of \code{poly2} is required to be zero and + the linear term is required to be nonzero. + + This implementation uses the Lagrange inversion formula. + The default \code{fmpz_poly} reversion algorithm is automatically + used when the reversion can be performed over the integers. + +void _fmpq_poly_revert_series_lagrange_fast(fmpz * res, fmpz_t den, + const fmpz * poly1, const fmpz_t den1, slong n) + + Sets \code{(res, den)} to the power series reversion of + \code{(poly1, den1)} modulo $x^n$, where the input has + length $n$ (possibly being zero-padded). + + The constant term of \code{poly2} is required to be zero and + the linear term is required to be nonzero. Assumes that $n > 0$. + Does not support aliasing between any of the inputs and the output. + + This implementation uses a reduced-complexity implementation + of the Lagrange inversion formula. + The default \code{fmpz_poly} reversion algorithm is automatically + used when the reversion can be performed over the integers. + +void fmpq_poly_revert_series_lagrange_fast(fmpq_poly_t res, + const fmpq_poly_t poly, slong n) + + Sets \code{res} to the power series reversion of \code{poly1} modulo $x^n$. + The constant term of \code{poly2} is required to be zero and + the linear term is required to be nonzero. + + This implementation uses a reduced-complexity implementation + of the Lagrange inversion formula. + The default \code{fmpz_poly} reversion algorithm is automatically + used when the reversion can be performed over the integers. + +void _fmpq_poly_revert_series_newton(fmpz * res, fmpz_t den, + const fmpz * poly1, const fmpz_t den1, slong n) + + Sets \code{(res, den)} to the power series reversion of + \code{(poly1, den1)} modulo $x^n$, where the input has + length $n$ (possibly being zero-padded). + + The constant term of \code{poly2} is required to be zero and + the linear term is required to be nonzero. Assumes that $n > 0$. + Does not support aliasing between any of the inputs and the output. + + This implementation uses Newton iteration. + The default \code{fmpz_poly} reversion algorithm is automatically + used when the reversion can be performed over the integers. + +void fmpq_poly_revert_series_newton(fmpq_poly_t res, + const fmpq_poly_t poly, slong n) + + Sets \code{res} to the power series reversion of \code{poly1} modulo $x^n$. + The constant term of \code{poly2} is required to be zero and + the linear term is required to be nonzero. + + This implementation uses Newton iteration. + The default \code{fmpz_poly} reversion algorithm is automatically + used when the reversion can be performed over the integers. + +void _fmpq_poly_revert_series(fmpz * res, fmpz_t den, + const fmpz * poly1, const fmpz_t den1, slong n) + + Sets \code{(res, den)} to the power series reversion of + \code{(poly1, den1)} modulo $x^n$, where the input has + length $n$ (possibly being zero-padded). + + The constant term of \code{poly2} is required to be zero and + the linear term is required to be nonzero. Assumes that $n > 0$. + Does not support aliasing between any of the inputs and the output. + + This implementation defaults to using Newton iteration. + The default \code{fmpz_poly} reversion algorithm is automatically + used when the reversion can be performed over the integers. + +void fmpq_poly_revert_series(fmpq_poly_t res, const fmpq_poly_t poly, slong n) + + Sets \code{res} to the power series reversion of \code{poly1} modulo $x^n$. + The constant term of \code{poly2} is required to be zero and + the linear term is required to be nonzero. + + This implementation defaults to using Newton iteration. + The default \code{fmpz_poly} reversion algorithm is automatically + used when the reversion can be performed over the integers. + +******************************************************************************* + + Gaussian content + +******************************************************************************* + +void _fmpq_poly_content(fmpq_t res, + const fmpz * poly, const fmpz_t den, slong len) + + Sets \code{res} to the content of \code{(poly, den, len)}. + If \code{len == 0}, sets \code{res} to zero. + +void fmpq_poly_content(fmpq_t res, const fmpq_poly_t poly) + + Sets \code{res} to the content of \code{poly}. The content of the zero + polynomial is defined to be zero. + +void _fmpq_poly_primitive_part(fmpz * rpoly, fmpz_t rden, + const fmpz * poly, const fmpz_t den, slong len) + + Sets \code{(rpoly, rden, len)} to the primitive part, with non-negative + leading coefficient, of \code{(poly, den, len)}. Assumes that + \code{len > 0}. Supports aliasing between the two polynomials. + +void fmpq_poly_primitive_part(fmpq_poly_t res, const fmpq_poly_t poly) + + Sets \code{res} to the primitive part, with non-negative leading + coefficient, of \code{poly}. + +int _fmpq_poly_is_monic(const fmpz * poly, const fmpz_t den, slong len) + + Returns whether the polynomial \code{(poly, den, len)} is monic. + The zero polynomial is not monic by definition. + +int fmpq_poly_is_monic(const fmpq_poly_t poly) + + Returns whether the polynomial \code{poly} is monic. The zero + polynomial is not monic by definition. + +void _fmpq_poly_make_monic(fmpz * rpoly, fmpz_t rden, + const fmpz * poly, const fmpz_t den, slong len) + + Sets \code{(rpoly, rden, len)} to the monic scalar multiple of + \code{(poly, den, len)}. Assumes that \code{len > 0}. Supports + aliasing between the two polynomials. + +void fmpq_poly_make_monic(fmpq_poly_t res, const fmpq_poly_t poly) + + Sets \code{res} to the monic scalar multiple of \code{poly} whenever + \code{poly} is non-zero. If \code{poly} is the zero polynomial, sets + \code{res} to zero. + +******************************************************************************* + + Square-free + +******************************************************************************* + +int fmpq_poly_is_squarefree(const fmpq_poly_t poly) + + Returns whether the polynomial \code{poly} is square-free. A non-zero + polynomial is defined to be square-free if it has no non-unit square + factors. We also define the zero polynomial to be square-free. + +******************************************************************************* + + Input and output + +******************************************************************************* + +int _fmpq_poly_print(const fmpz * poly, const fmpz_t den, slong len) + + Prints the polynomial \code{(poly, den, len)} to \code{stdout}. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + +int fmpq_poly_print(const fmpq_poly_t poly) + + Prints the polynomial to \code{stdout}. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + +int _fmpq_poly_print_pretty(const fmpz *poly, const fmpz_t den, slong len, + const char * x) + +int fmpq_poly_print_pretty(const fmpq_poly_t poly, const char * var) + + Prints the pretty representation of \code{poly} to \code{stdout}, using + the null-terminated string \code{var} not equal to \code{"\0"} as the + variable name. + + In the current implementation always returns~$1$. + +int _fmpq_poly_fprint(FILE * file, + const fmpz * poly, const fmpz_t den, slong len) + + Prints the polynomial \code{(poly, den, len)} to the stream \code{file}. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + +int fmpq_poly_fprint(FILE * file, const fmpq_poly_t poly) + + Prints the polynomial to the stream \code{file}. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + +int _fmpq_poly_fprint_pretty(FILE * file, + const fmpz *poly, const fmpz_t den, slong len, + const char * x) + +int fmpq_poly_print_pretty(const fmpq_poly_t poly, const char * var) + + Prints the pretty representation of \code{poly} to \code{stdout}, using + the null-terminated string \code{var} not equal to \code{"\0"} as the + variable name. + + In the current implementation, always returns~$1$. + +int fmpq_poly_read(fmpq_poly_t poly) + + Reads a polynomial from \code{stdin}, storing the result + in \code{poly}. + + In case of success, returns a positive number. In case of failure, + returns a non-positive value. + +int fmpq_poly_fread(FILE * file, fmpq_poly_t poly) + + Reads a polynomial from the stream \code{file}, storing the result + in \code{poly}. + + In case of success, returns a positive number. In case of failure, + returns a non-positive value. + diff --git a/external/flint-2.4.3/fmpq_poly/equal.c b/external/flint-2.4.3/fmpq_poly/equal.c new file mode 100644 index 0000000..164be16 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/equal.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpq_poly.h" + +int fmpq_poly_equal(const fmpq_poly_t poly1, const fmpq_poly_t poly2) +{ + return (poly1->length == poly2->length) + && (fmpz_equal(poly1->den, poly2->den)) + && (_fmpz_vec_equal(poly1->coeffs, poly2->coeffs, poly1->length)); +} + diff --git a/external/flint-2.4.3/fmpq_poly/evaluate_fmpq.c b/external/flint-2.4.3/fmpq_poly/evaluate_fmpq.c new file mode 100644 index 0000000..27adc98 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/evaluate_fmpq.c @@ -0,0 +1,73 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpq_poly.h" +#include "fmpq.h" + +void +_fmpq_poly_evaluate_fmpq(fmpz_t rnum, fmpz_t rden, + const fmpz * poly, const fmpz_t den, slong len, + const fmpz_t anum, const fmpz_t aden) +{ + fmpz_t d; + + _fmpz_poly_evaluate_horner_mpq(rnum, rden, poly, len, anum, aden); + fmpz_mul(rden, rden, den); + + fmpz_init(d); + fmpz_gcd(d, rnum, rden); + if (*d != WORD(1)) + { + fmpz_divexact(rnum, rnum, d); + fmpz_divexact(rden, rden, d); + } + fmpz_clear(d); +} + +void +fmpq_poly_evaluate_fmpq(fmpq_t res, const fmpq_poly_t poly, const fmpq_t a) +{ + if (res != a) + { + _fmpq_poly_evaluate_fmpq(fmpq_numref(res), fmpq_denref(res), + poly->coeffs, poly->den, poly->length, + fmpq_numref(a), fmpq_denref(a)); + } + else + { + fmpq_t t; + + fmpq_init(t); + fmpq_set(t, a); + fmpq_poly_evaluate_fmpq(res, poly, t); + fmpq_clear(t); + } +} + diff --git a/external/flint-2.4.3/fmpq_poly/evaluate_fmpz.c b/external/flint-2.4.3/fmpq_poly/evaluate_fmpz.c new file mode 100644 index 0000000..42d0255 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/evaluate_fmpz.c @@ -0,0 +1,60 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpq_poly.h" + +void +_fmpq_poly_evaluate_fmpz(fmpz_t rnum, fmpz_t rden, const fmpz * poly, + const fmpz_t den, slong len, const fmpz_t a) +{ + fmpz_t d; + + _fmpz_poly_evaluate_horner_fmpz(rnum, poly, len, a); + + fmpz_init(d); + fmpz_gcd(d, rnum, den); + if (*d != WORD(1)) + { + fmpz_divexact(rnum, rnum, d); + fmpz_divexact(rden, den, d); + } + else + { + fmpz_set(rden, den); + } + fmpz_clear(d); +} + +void +fmpq_poly_evaluate_fmpz(fmpq_t res, const fmpq_poly_t poly, const fmpz_t a) +{ + _fmpq_poly_evaluate_fmpz(fmpq_numref(res), fmpq_denref(res), + poly->coeffs, poly->den, poly->length, a); +} + diff --git a/external/flint-2.4.3/fmpq_poly/evaluate_mpq.c b/external/flint-2.4.3/fmpq_poly/evaluate_mpq.c new file mode 100644 index 0000000..46fd07a --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/evaluate_mpq.c @@ -0,0 +1,46 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpq_poly.h" +#include "fmpq.h" + +void +fmpq_poly_evaluate_mpq(mpq_t res, const fmpq_poly_t poly, const mpq_t a) +{ + fmpq_t r, b; + + fmpq_init(r); + fmpq_init(b); + fmpq_set_mpq(b, a); + fmpq_poly_evaluate_fmpq(r, poly, b); + fmpq_get_mpq(res, r); + fmpq_clear(r); + fmpq_clear(b); +} diff --git a/external/flint-2.4.3/fmpq_poly/evaluate_mpz.c b/external/flint-2.4.3/fmpq_poly/evaluate_mpz.c new file mode 100644 index 0000000..8972bd8 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/evaluate_mpz.c @@ -0,0 +1,46 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpq_poly.h" +#include "fmpq.h" + +void fmpq_poly_evaluate_mpz(mpq_t res, const fmpq_poly_t poly, const mpz_t a) +{ + fmpq_t r; + fmpz_t b; + + fmpq_init(r); + fmpz_init(b); + fmpz_set_mpz(b, a); + fmpq_poly_evaluate_fmpz(r, poly, b); + fmpq_get_mpq(res, r); + fmpq_clear(r); + fmpz_clear(b); +} diff --git a/external/flint-2.4.3/fmpq_poly/exp_series.c b/external/flint-2.4.3/fmpq_poly/exp_series.c new file mode 100644 index 0000000..6b90c34 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/exp_series.c @@ -0,0 +1,131 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpq_poly.h" + + +void +_fmpq_poly_exp_series(fmpz * g, fmpz_t gden, + const fmpz * h, const fmpz_t hden, slong n) +{ + slong m; + fmpz * t, * u; + fmpz_t tden, uden; + + if (n < 2) + { + fmpz_one(g); + fmpz_one(gden); + return; + } + + m = (n + 1) / 2; + _fmpq_poly_exp_series(g, gden, h, hden, m); + _fmpz_vec_zero(g + m, n - m); + + t = _fmpz_vec_init(n); + u = _fmpz_vec_init(n); + fmpz_init(tden); + fmpz_init(uden); + + _fmpq_poly_log_series(t, tden, g, gden, n); + _fmpq_poly_sub(t, tden, t, tden, n, h, hden, n); + /* TODO: half of product is redundant! */ + _fmpq_poly_mullow(u, uden, g, gden, n, t, tden, n, n); + _fmpq_poly_sub(g, gden, g, gden, n, u, uden, n); + _fmpq_poly_canonicalise(g, gden, n); + + fmpz_clear(tden); + fmpz_clear(uden); + _fmpz_vec_clear(t, n); + _fmpz_vec_clear(u, n); +} + +void fmpq_poly_exp_series(fmpq_poly_t res, const fmpq_poly_t poly, slong n) +{ + fmpz *copy; + int alloc; + + if (poly->length == 0) + { + fmpq_poly_set_ui(res, UWORD(1)); + return; + } + + if (!fmpz_is_zero(poly->coeffs)) + { + flint_printf("Exception (fmpq_poly_exp_series). Constant term != 0.\n"); + abort(); + } + + if (n < 2) + { + if (n == 0) fmpq_poly_zero(res); + if (n == 1) fmpq_poly_set_ui(res, UWORD(1)); + return; + } + + if (poly->length >= n) + { + copy = poly->coeffs; + alloc = 0; + } + else + { + slong i; + copy = (fmpz *) flint_malloc(n * sizeof(fmpz)); + for (i = 0; i < poly->length; i++) + copy[i] = poly->coeffs[i]; + for ( ; i < n; i++) + copy[i] = 0; + alloc = 1; + } + + if (res != poly) + { + fmpq_poly_fit_length(res, n); + _fmpq_poly_exp_series(res->coeffs, res->den, copy, poly->den, n); + } + else + { + fmpq_poly_t t; + fmpq_poly_init2(t, n); + _fmpq_poly_exp_series(t->coeffs, t->den, copy, poly->den, n); + fmpq_poly_swap(res, t); + fmpq_poly_clear(t); + } + + _fmpq_poly_set_length(res, n); + _fmpq_poly_normalise(res); + + if (alloc) + flint_free(copy); +} + diff --git a/external/flint-2.4.3/fmpq_poly/fit_length.c b/external/flint-2.4.3/fmpq_poly/fit_length.c new file mode 100644 index 0000000..8f2d383 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/fit_length.c @@ -0,0 +1,42 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" + +void fmpq_poly_fit_length(fmpq_poly_t poly, slong len) +{ + if (len > poly->alloc) + { + /* At least double the number of allocated coefficients */ + if (len < 2 * poly->alloc) + len = 2 * poly->alloc; + fmpq_poly_realloc(poly, len); + } +} + diff --git a/external/flint-2.4.3/fmpq_poly/fprint.c b/external/flint-2.4.3/fmpq_poly/fprint.c new file mode 100644 index 0000000..fe0294c --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/fprint.c @@ -0,0 +1,96 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include + +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpq_poly.h" + +/* + Recall the return value conventions for fputc (of type int) + + ``If there are no errors, the same character that has been written is + returned. If an error occurs, EOF is returned and the error indicator + is set'' + + where the EOF macro expands to a negative int, and flint_fprintf (of type int) + + ``On success, the total number of characters written is returned. + On failure, a negative number is returned.'' + */ + +int +_fmpq_poly_fprint(FILE * file, const fmpz * poly, const fmpz_t den, slong len) +{ + int r; + slong i; + fmpz_t n, d, g; + + fmpz_init(n); + fmpz_init(d); + fmpz_init(g); + + r = flint_fprintf(file, "%li", len); + if ((len > 0) && (r > 0)) + { + r = fputc(' ', file); + for (i = 0; (i < len) && (r > 0); i++) + { + r = fputc(' ', file); + if (r > 0) + { + fmpz_gcd(g, poly + i, den); + fmpz_divexact(n, poly + i, g); + fmpz_divexact(d, den, g); + if (*d == WORD(1)) + r = fmpz_fprint(file, n); + else + { + r = fmpz_fprint(file, n); + if (r > 0) + r = fputc('/', file); + if (r > 0) + r = fmpz_fprint(file, d); + } + } + } + } + + fmpz_clear(n); + fmpz_clear(d); + fmpz_clear(g); + + return r; +} + +int fmpq_poly_fprint(FILE * file, const fmpq_poly_t poly) +{ + return _fmpq_poly_fprint(file, poly->coeffs, poly->den, poly->length); +} + diff --git a/external/flint-2.4.3/fmpq_poly/fprint_pretty.c b/external/flint-2.4.3/fmpq_poly/fprint_pretty.c new file mode 100644 index 0000000..dd5a86f --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/fprint_pretty.c @@ -0,0 +1,184 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include +#include + +#include "fmpq_poly.h" + +/* + Macro wrapping _fmpq_fprint(file, x, y), ensuring that the printed + rational is in lowest terms. Assumes that y > 0. + */ + +#define __fmpq_fprint(x,y) \ +do { \ + fmpz_gcd(g, x, y); \ + if (fmpz_is_one(g)) \ + { \ + _fmpq_fprint(file, x, y); \ + } \ + else \ + { \ + fmpz_divexact(n, x, g); \ + fmpz_divexact(d, y, g); \ + _fmpq_fprint(file, n, d); \ + } \ +} while (0) + +/* checks if x/y == 1, where (x, y) need not be in lowest terms */ +#define __fmpq_is_one(x,y) fmpz_equal((x), (y)) + +/* checks if x/y == +/- 1, where (x, y) need not be in lowest terms */ +#define __fmpq_is_pm1(x,y) (fmpz_cmpabs((x),(y)) == 0) + +int _fmpq_poly_fprint_pretty(FILE * file, + const fmpz *poly, const fmpz_t den, slong len, + const char * x) +{ + fmpz_t n, d, g; + + fmpz_init(n); + fmpz_init(d); + fmpz_init(g); + + if (len == 0) + { + fputc('0', file); + } + else if (len == 1) + { + _fmpq_fprint(file, poly + 0, den); + } + else if (len == 2) + { + if (__fmpq_is_one(poly + 1, den)) + { + flint_fprintf(file, "%s", x); + } + else if (__fmpq_is_pm1(poly + 1, den)) + { + flint_fprintf(file, "-%s", x); + } + else + { + __fmpq_fprint(poly + 1, den); + flint_fprintf(file, "*%s", x); + } + + if (fmpz_sgn(poly + 0) > 0) + { + flint_fprintf(file, "+"); + __fmpq_fprint(poly + 0, den); + } + else if (fmpz_sgn(poly + 0) < 0) + { + __fmpq_fprint(poly + 0, den); + } + } + else /* len >= 3 */ + { + slong i = len - 1; /* i >= 2 */ + { + if (__fmpq_is_one(poly + i, den)) + flint_fprintf(file, "%s^%wd", x, i); + else if (__fmpq_is_pm1(poly + i, den)) + flint_fprintf(file, "-%s^%wd", x, i); + else + { + __fmpq_fprint(poly + i, den); + flint_fprintf(file, "*%s^%wd", x, i); + } + --i; + } + + for (; i > 1; --i) + { + if (poly[i] == 0) + continue; + + if (__fmpq_is_one(poly + i, den)) + flint_fprintf(file, "+%s^%wd", x, i); + else if (__fmpq_is_pm1(poly + i, den)) + flint_fprintf(file, "-%s^%wd", x, i); + else + { + if (fmpz_sgn(poly + i) > 0) + { + fputc('+', file); + } + __fmpq_fprint(poly + i, den); + flint_fprintf(file, "*%s^%wd", x, i); + } + } + + if (poly[1]) + { + if (__fmpq_is_one(poly + 1, den)) + { + fputc('+', file); + fputs(x, file); + } + else if (__fmpq_is_pm1(poly + 1, den)) + { + fputc('-', file); + fputs(x, file); + } + else + { + if (fmpz_sgn(poly + 1) > 0) + { + fputc('+', file); + } + __fmpq_fprint(poly + 1, den); + fputc('*', file); + fputs(x, file); + } + } + if (*(poly)) + { + if (fmpz_sgn(poly) > 0) + { + fputc('+', file); + } + __fmpq_fprint(poly + 0, den); + } + } + + fmpz_clear(n); + fmpz_clear(d); + fmpz_clear(g); + + return 1; +} + +#undef __fmpq_fprint + +int fmpq_poly_fprint_pretty(FILE * file, + const fmpq_poly_t poly, const char * var) +{ + return _fmpq_poly_fprint_pretty(file, poly->coeffs, poly->den, poly->length, var); +} + diff --git a/external/flint-2.4.3/fmpq_poly/fread.c b/external/flint-2.4.3/fmpq_poly/fread.c new file mode 100644 index 0000000..6299527 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/fread.c @@ -0,0 +1,71 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpq_poly.h" + +int fmpq_poly_fread(FILE * file, fmpq_poly_t poly) +{ + int r; + slong i, len; + mpz_t t; + mpq_t *a; + + mpz_init(t); + r = mpz_inp_str(t, file, 10); + if (r == 0) + { + mpz_clear(t); + return 0; + } + if (!mpz_fits_slong_p(t)) + { + flint_printf("Exception (fmpz_poly_fread). Length does not fit into a slong.\n"); + abort(); + } + len = flint_mpz_get_si(t); + mpz_clear(t); + + a = flint_malloc(len * sizeof(mpq_t)); + for (i = 0; i < len; i++) + mpq_init(a[i]); + + for (i = 0; (i < len) && r; i++) + r = mpq_inp_str(a[i], file, 10); + + if (r > 0) + fmpq_poly_set_array_mpq(poly, (const mpq_t *) a, len); + + for (i = 0; i < len; i++) + mpq_clear(a[i]); + flint_free(a); + + return r; +} + diff --git a/external/flint-2.4.3/fmpq_poly/gcd.c b/external/flint-2.4.3/fmpq_poly/gcd.c new file mode 100644 index 0000000..73e51cc --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/gcd.c @@ -0,0 +1,146 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" +#include "fmpq_poly.h" + +void _fmpq_poly_gcd(fmpz *G, fmpz_t denG, + const fmpz *A, slong lenA, const fmpz *B, slong lenB) +{ + if (lenA == 1) /* lenA == lenB == 1 */ + { + fmpz_one(G); + fmpz_one(denG); + } + else + { + fmpz *primA, *primB; + fmpz_t s, t; + slong lenG; + + fmpz_init(s); + fmpz_init(t); + + _fmpz_vec_content(s, A, lenA); + _fmpz_vec_content(t, B, lenB); + + /* Set primA, primB to the primitive multiples of A, B */ + if (fmpz_is_one(s)) + { + if (fmpz_is_one(t)) + { + primA = (fmpz *) A; + primB = (fmpz *) B; + } + else + { + primA = (fmpz *) A; + primB = _fmpz_vec_init(lenB); + _fmpz_vec_scalar_divexact_fmpz(primB, B, lenB, t); + } + } + else + { + if (fmpz_is_one(s)) + { + primA = _fmpz_vec_init(lenA); + primB = (fmpz *) B; + _fmpz_vec_scalar_divexact_fmpz(primA, A, lenA, s); + } + else + { + primA = _fmpz_vec_init(lenA + lenB); + primB = primA + lenA; + _fmpz_vec_scalar_divexact_fmpz(primA, A, lenA, s); + _fmpz_vec_scalar_divexact_fmpz(primB, B, lenB, t); + } + } + + _fmpz_poly_gcd(G, primA, lenA, primB, lenB); + + for (lenG = lenB - 1; !G[lenG]; lenG--) ; + lenG++; + + fmpz_set(denG, G + (lenG - 1)); + + if (A != primA) + _fmpz_vec_clear(primA, lenA + (B != primB) * lenB); + else if (B != primB) + _fmpz_vec_clear(primB, lenB); + + fmpz_clear(s); + fmpz_clear(t); + } +} + +void fmpq_poly_gcd(fmpq_poly_t G, const fmpq_poly_t A, const fmpq_poly_t B) +{ + if (A->length < B->length) + { + fmpq_poly_gcd(G, B, A); + } + else + { + slong lenA = A->length, lenB = B->length; + + if (lenA == 0) /* lenA = lenB = 0 */ + { + fmpq_poly_zero(G); + } + else if (lenB == 0) /* lenA > lenB = 0 */ + { + fmpq_poly_make_monic(G, A); + } + else /* lenA >= lenB >= 1 */ + { + if (G == A || G == B) + { + fmpq_poly_t t; + fmpq_poly_init2(t, lenB); + + _fmpq_poly_gcd(t->coeffs, t->den, A->coeffs, A->length, + B->coeffs, B->length); + + fmpq_poly_swap(t, G); + fmpq_poly_clear(t); + } + else + { + fmpq_poly_fit_length(G, lenB); + + _fmpq_poly_gcd(G->coeffs, G->den, A->coeffs, A->length, + B->coeffs, B->length); + } + + _fmpq_poly_set_length(G, lenB); + _fmpq_poly_normalise(G); + } + } +} + diff --git a/external/flint-2.4.3/fmpq_poly/get_coeff_fmpq.c b/external/flint-2.4.3/fmpq_poly/get_coeff_fmpq.c new file mode 100644 index 0000000..08ce873 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/get_coeff_fmpq.c @@ -0,0 +1,46 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq.h" +#include "fmpq_poly.h" + +void fmpq_poly_get_coeff_fmpq(fmpq_t x, const fmpq_poly_t poly, slong n) +{ + if (n >= poly->length) /* Coefficient is beyond the end of poly */ + { + fmpq_zero(x); + return; + } + + fmpz_set(fmpq_numref(x), poly->coeffs + n); + fmpz_set(fmpq_denref(x), poly->den); + fmpq_canonicalise(x); +} + diff --git a/external/flint-2.4.3/fmpq_poly/get_coeff_mpq.c b/external/flint-2.4.3/fmpq_poly/get_coeff_mpq.c new file mode 100644 index 0000000..0afbebc --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/get_coeff_mpq.c @@ -0,0 +1,45 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" + +void fmpq_poly_get_coeff_mpq(mpq_t x, const fmpq_poly_t poly, slong n) +{ + if (n >= poly->length) /* Coefficient is beyond the end of poly */ + { + flint_mpq_set_si(x, 0, 1); + return; + } + + fmpz_get_mpz(mpq_numref(x), poly->coeffs + n); + fmpz_get_mpz(mpq_denref(x), poly->den); + mpq_canonicalize(x); +} + diff --git a/external/flint-2.4.3/fmpq_poly/get_slice.c b/external/flint-2.4.3/fmpq_poly/get_slice.c new file mode 100644 index 0000000..c90ef92 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/get_slice.c @@ -0,0 +1,64 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpq_poly.h" + +void fmpq_poly_get_slice(fmpq_poly_t rop, const fmpq_poly_t op, slong i, slong j) +{ + i = FLINT_MAX(i, 0); + j = FLINT_MIN(j, op->length); + + if (i < j) + { + slong k; + + if (rop == op) + { + for (k = 0; k < i; k++) + fmpz_zero(rop->coeffs + k); + for (k = j; k < rop->length; k++) + fmpz_zero(rop->coeffs + k); + fmpq_poly_canonicalise(rop); + } + else + { + fmpq_poly_fit_length(rop, j); + _fmpq_poly_set_length(rop, j); + + _fmpz_vec_set(rop->coeffs + i, op->coeffs + i, j - i); + fmpz_set(rop->den, op->den); + fmpq_poly_canonicalise(rop); + } + } + else + { + fmpq_poly_zero(rop); + } +} + diff --git a/external/flint-2.4.3/fmpq_poly/get_str.c b/external/flint-2.4.3/fmpq_poly/get_str.c new file mode 100644 index 0000000..1f48342 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/get_str.c @@ -0,0 +1,92 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" + +char * fmpq_poly_get_str(const fmpq_poly_t poly) +{ + slong i; + size_t j; + size_t len; /* Upper bound on the length */ + size_t denlen; /* Size of the denominator in base 10 */ + mpz_t z; + mpq_t q; + char * str; + + if (poly->length == 0) + { + str = (char *) flint_malloc(2 * sizeof(char)); + str[0] = '0'; + str[1] = '\0'; + return str; + } + + mpz_init(z); + if (*poly->den == WORD(1)) + { + denlen = 0; + } + else + { + fmpz_get_mpz(z, poly->den); + denlen = mpz_sizeinbase(z, 10); + } + len = (size_t) ceil(log10((double) (poly->length + 1))) + (size_t) 2; + for (i = 0; i < poly->length; i++) + { + fmpz_get_mpz(z, poly->coeffs + i); + len += mpz_sizeinbase(z, 10) + (size_t) 1; + if (mpz_sgn(z)) + len += denlen + (size_t) 2; + } + + mpq_init(q); + str = (char *) flint_malloc(len * sizeof(char)); + + j = flint_sprintf(str, "%li", poly->length); + str[j++] = ' '; + for (i = 0; i < poly->length; i++) + { + str[j++] = ' '; + fmpz_get_mpz(mpq_numref(q), poly->coeffs + i); + fmpz_get_mpz(mpq_denref(q), poly->den); + mpq_canonicalize(q); + mpq_get_str(str + j, 10, q); + j += strlen(str + j); + } + + mpq_clear(q); + mpz_clear(z); + + return str; +} + diff --git a/external/flint-2.4.3/fmpq_poly/get_str_pretty.c b/external/flint-2.4.3/fmpq_poly/get_str_pretty.c new file mode 100644 index 0000000..8791514 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/get_str_pretty.c @@ -0,0 +1,218 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" + +char * _fmpq_poly_get_str_pretty(const fmpz *poly, const fmpz_t den, slong len, + const char *var) +{ + slong i; + size_t j; + size_t size; /* Upper bound on the length */ + size_t densize; /* Size of the denominator in base 10 */ + size_t varsize; /* Length of the variable name */ + mpz_t z; /* op->den (if this is not 1) */ + mpq_t q; + char *str; + + if (len == 0) /* Zero polynomial */ + { + str = flint_malloc(2); + str[0] = '0'; + str[1] = '\0'; + return str; + } + if (len == 1) /* Constant polynomials */ + { + mpq_init(q); + fmpz_get_mpz(mpq_numref(q), poly); + fmpz_get_mpz(mpq_denref(q), den); + mpq_canonicalize(q); + str = mpq_get_str(NULL, 10, q); + mpq_clear(q); + return str; + } + if (len == 2) /* Linear polynomials */ + { + mpq_t a0, a1; + size_t size0, size1; + + mpq_init(a0); + mpq_init(a1); + + fmpz_get_mpz(mpq_numref(a0), poly); + fmpz_get_mpz(mpq_denref(a0), den); + mpq_canonicalize(a0); + fmpz_get_mpz(mpq_numref(a1), poly + 1); + fmpz_get_mpz(mpq_denref(a1), den); + mpq_canonicalize(a1); + + size0 = mpz_sizeinbase(mpq_numref(a0), 10) + + mpz_sizeinbase(mpq_denref(a0), 10) + 1; + size1 = mpz_sizeinbase(mpq_numref(a1), 10) + + mpz_sizeinbase(mpq_denref(a1), 10) + 1; + size = size0 + 1 + strlen(var) + 1 + size1 + 1; + str = flint_malloc(size); + + if (flint_mpq_cmp_si(a1, 1, 1) == 0) + { + if (mpq_sgn(a0) == 0) + gmp_sprintf(str, "%s", var); + else if (mpq_sgn(a0) > 0) + gmp_sprintf(str, "%s+%Qd", var, a0); + else /* mpq_sgn(a0) < 0 */ + gmp_sprintf(str, "%s%Qd", var, a0); + } + else if (flint_mpq_cmp_si(a1, -1, 1) == 0) + { + if (mpq_sgn(a0) == 0) + gmp_sprintf(str, "-%s", var); + else if (mpq_sgn(a0) > 0) + gmp_sprintf(str, "-%s+%Qd", var, a0); + else /* mpq_sgn(a0) < 0 */ + gmp_sprintf(str, "-%s%Qd", var, a0); + } + else + { + if (mpq_sgn(a0) == 0) + gmp_sprintf(str, "%Qd*%s", a1, var); + else if (mpq_sgn(a0) > 0) + gmp_sprintf(str, "%Qd*%s+%Qd", a1, var, a0); + else /* mpq_sgn(a0) < 0 */ + gmp_sprintf(str, "%Qd*%s%Qd", a1, var, a0); + } + + mpq_clear(a0); + mpq_clear(a1); + + return str; + } + + varsize = strlen(var); + + /* Copy the denominator into an mpz_t */ + mpz_init(z); + if (*den == WORD(1)) + { + densize = 0; + } + else + { + fmpz_get_mpz(z, den); + densize = mpz_sizeinbase(z, 10); + } + + /* Estimate the length */ + size = 0; + for (i = 0; i < len; i++) + { + fmpz_get_mpz(z, poly + i); + size += mpz_sizeinbase(z, 10); /* Numerator */ + if (mpz_sgn(z) != 0) size += 1 + densize; /* Denominator and / */ + size += 3; /* Operator and ws */ + size += 1 + varsize + 1; /* *, x and ^ */ + size += (size_t) ceil(log10((double) (i + 1))); /* Exponent */ + } + + mpq_init(q); + str = flint_malloc(size); + + j = 0; + + /* Print the leading term */ + fmpz_get_mpz(mpq_numref(q), poly + (len - 1)); + fmpz_get_mpz(mpq_denref(q), den); + mpq_canonicalize(q); + + if (flint_mpq_cmp_si(q, 1, 1) != 0) + { + if (flint_mpq_cmp_si(q, -1, 1) == 0) + str[j++] = '-'; + else + { + mpq_get_str(str, 10, q); + j += strlen(str + j); + str[j++] = '*'; + } + } + j += flint_sprintf(str + j, "%s", var); + str[j++] = '^'; + j += flint_sprintf(str + j, "%li", len - 1); + + i = len - 1; + while (i) + { + i--; + + if (fmpz_is_zero(poly + i)) + continue; + + fmpz_get_mpz(mpq_numref(q), poly + i); + fmpz_get_mpz(mpq_denref(q), den); + mpq_canonicalize(q); + + str[j++] = ' '; + if (mpq_sgn(q) < 0) + { + mpq_abs(q, q); + str[j++] = '-'; + } + else + str[j++] = '+'; + str[j++] = ' '; + + mpq_get_str(str + j, 10, q); + j += strlen(str + j); + + if (i > 0) + { + str[j++] = '*'; + j += flint_sprintf(str + j, "%s", var); + if (i > 1) + { + str[j++] = '^'; + j += flint_sprintf(str + j, "%li", i); + } + } + } + + mpq_clear(q); + mpz_clear(z); + return str; +} + +char * fmpq_poly_get_str_pretty(const fmpq_poly_t poly, const char * var) +{ + return _fmpq_poly_get_str_pretty(poly->coeffs, poly->den, poly->length, + var); +} + diff --git a/external/flint-2.4.3/fmpq_poly/init.c b/external/flint-2.4.3/fmpq_poly/init.c new file mode 100644 index 0000000..1ca98cc --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/init.c @@ -0,0 +1,52 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" + +void fmpq_poly_init(fmpq_poly_t poly) +{ + poly->coeffs = NULL; + fmpz_init(poly->den); + fmpz_one(poly->den); + poly->alloc = 0; + poly->length = 0; +} + +void fmpq_poly_init2(fmpq_poly_t poly, slong alloc) +{ + /* Allocate space for alloc small coeffs */ + poly->coeffs = (alloc ? (fmpz *) flint_calloc(alloc, sizeof(fmpz)) : NULL); + + fmpz_init(poly->den); + fmpz_one(poly->den); + poly->alloc = alloc; + poly->length = 0; +} + diff --git a/external/flint-2.4.3/fmpq_poly/integral.c b/external/flint-2.4.3/fmpq_poly/integral.c new file mode 100644 index 0000000..66c000a --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/integral.c @@ -0,0 +1,74 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpq_poly.h" + +void _fmpq_poly_integral(fmpz * rpoly, fmpz_t rden, + const fmpz * poly, const fmpz_t den, slong len) +{ + slong k; + fmpz_t t; + + fmpz_init(t); + fmpz_one(t); + + for (k = len - 1; k > 0; k--) + { + fmpz_mul(rpoly + k, poly + k - 1, t); + fmpz_mul_ui(t, t, k); + } + + fmpz_mul(rden, den, t); + + fmpz_set_ui(t, UWORD(2)); + for (k = 3; k < len; k++) + { + fmpz_mul(rpoly + k, rpoly + k, t); + fmpz_mul_ui(t, t, k); + } + + fmpz_zero(rpoly); + _fmpq_poly_canonicalise(rpoly, rden, len); + fmpz_clear(t); +} + +void fmpq_poly_integral(fmpq_poly_t res, const fmpq_poly_t poly) +{ + slong len = poly->length; + + if (len == 0) + { + fmpq_poly_zero(res); + return; + } + + fmpq_poly_fit_length(res, len + 1); + _fmpq_poly_integral(res->coeffs, res->den, poly->coeffs, poly->den, len + 1); + _fmpq_poly_set_length(res, len + 1); +} diff --git a/external/flint-2.4.3/fmpq_poly/interpolate_fmpz_vec.c b/external/flint-2.4.3/fmpq_poly/interpolate_fmpz_vec.c new file mode 100644 index 0000000..9228691 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/interpolate_fmpz_vec.c @@ -0,0 +1,123 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" +#include "fmpq_poly.h" + + +void +_fmpq_poly_interpolate_fmpz_vec(fmpz * poly, fmpz_t den, + const fmpz * xs, const fmpz * ys, slong n) +{ + fmpz *P, *Q, *w; + fmpz_t t; + + slong i, j; + + /* Constant */ + if (n == 1) + { + fmpz_set(poly, ys); + fmpz_one(den); + return; + } + + /* Linear */ + if (n == 2) + { + fmpz_sub(den, xs, xs + 1); + fmpz_sub(poly + 1, ys, ys + 1); + fmpz_mul(poly, xs, ys + 1); + fmpz_submul(poly, xs + 1, ys); + return; + } + + fmpz_init(t); + + P = _fmpz_vec_init(n + 1); + Q = _fmpz_vec_init(n); + w = _fmpz_vec_init(n); + + /* P = (x-x[0])*(x-x[1])*...*(x-x[n-1]) */ + _fmpz_poly_product_roots_fmpz_vec(P, xs, n); + + /* Weights */ + for (i = 0; i < n; i++) + { + fmpz_one(w + i); + for (j = 0; j < n; j++) + { + if (i != j) + { + fmpz_sub(t, xs + i, xs + j); + fmpz_mul(w + i, w + i, t); + } + } + } + + _fmpz_vec_zero(poly, n); + _fmpz_vec_lcm(den, w, n); + + for (i = 0; i < n; i++) + { + /* Q = P / (x - x[i]) */ + _fmpz_poly_div_root(Q, P, n + 1, xs + i); + + /* result += Q * weight(i) */ + fmpz_divexact(t, den, w + i); + fmpz_mul(t, t, ys + i); + _fmpz_vec_scalar_addmul_fmpz(poly, Q, n, t); + } + + _fmpz_vec_clear(P, n + 1); + _fmpz_vec_clear(Q, n); + _fmpz_vec_clear(w, n); + fmpz_clear(t); +} + +void +fmpq_poly_interpolate_fmpz_vec(fmpq_poly_t poly, + const fmpz * xs, const fmpz * ys, slong n) +{ + if (n == 0) + { + fmpq_poly_zero(poly); + } + else if (n == 1) + { + fmpq_poly_set_fmpz(poly, ys); + } + else + { + fmpq_poly_fit_length(poly, n); + _fmpq_poly_interpolate_fmpz_vec(poly->coeffs, poly->den, xs, ys, n); + _fmpq_poly_set_length(poly, n); + fmpq_poly_canonicalise(poly); + } +} diff --git a/external/flint-2.4.3/fmpq_poly/inv.c b/external/flint-2.4.3/fmpq_poly/inv.c new file mode 100644 index 0000000..5c2c3dc --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/inv.c @@ -0,0 +1,65 @@ +/*============================================================================ + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" + +void fmpq_poly_inv(fmpq_poly_t poly1, const fmpq_poly_t poly2) +{ + if (poly2->length != 1) + { + flint_printf("Exception (fmpq_poly_inv). poly2 is not invertible.\n"); + abort(); + } + + if (poly1 == poly2) + { + fmpz_swap(poly1->coeffs, poly1->den); + if (fmpz_sgn(poly1->den) < 0) + { + fmpz_neg(poly1->coeffs, poly1->coeffs); + fmpz_neg(poly1->den, poly1->den); + } + } + else + { + fmpq_poly_fit_length(poly1, 1); + if (fmpz_sgn(poly2->coeffs) > 0) + { + fmpz_set(poly1->coeffs, poly2->den); + fmpz_set(poly1->den, poly2->coeffs); + } + else + { + fmpz_neg(poly1->coeffs, poly2->den); + fmpz_neg(poly1->den, poly2->coeffs); + } + _fmpq_poly_set_length(poly1, 1); + } +} + diff --git a/external/flint-2.4.3/fmpq_poly/inv_series_newton.c b/external/flint-2.4.3/fmpq_poly/inv_series_newton.c new file mode 100644 index 0000000..1dfd120 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/inv_series_newton.c @@ -0,0 +1,147 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" +#include "fmpq_poly.h" + +#define FMPQ_POLY_INV_NEWTON_CUTOFF 32 + +void +_fmpq_poly_inv_series_newton(fmpz * Qinv, fmpz_t Qinvden, + const fmpz * Q, const fmpz_t Qden, slong n) +{ + if (n == 1) + { + if (fmpz_sgn(Q) > 0) + { + fmpz_set(Qinv, Qden); + fmpz_set(Qinvden, Q); + } + else + { + fmpz_neg(Qinv, Qden); + fmpz_neg(Qinvden, Q); + } + } + else + { + const slong alloc = FLINT_MAX(n, 3 * FMPQ_POLY_INV_NEWTON_CUTOFF); + slong *a, i, m; + fmpz *W, *Wden; + + W = _fmpz_vec_init(alloc + 1); + Wden = W + alloc; + + for (i = 1; (WORD(1) << i) < n; i++) ; + + a = (slong *) flint_malloc(i * sizeof(slong)); + a[i = 0] = n; + while (n >= FMPQ_POLY_INV_NEWTON_CUTOFF) + a[++i] = (n = (n + 1) / 2); + + /* Base case */ + { + fmpz *rev = W + 2 * FMPQ_POLY_INV_NEWTON_CUTOFF; + + _fmpz_poly_reverse(rev, Q, n, n); + _fmpz_vec_zero(W, 2*n - 2); + fmpz_one(W + (2*n - 2)); + fmpz_one(Wden); + + _fmpq_poly_div(Qinv, Qinvden, W, Wden, 2*n - 1, rev, Qden, n, NULL); + _fmpq_poly_canonicalise(Qinv, Qinvden, n); + + _fmpz_poly_reverse(Qinv, Qinv, n, n); + } + + for (i--; i >= 0; i--) + { + m = n; + n = a[i]; + + _fmpz_poly_mullow(W, Q, n, Qinv, m, n); + fmpz_mul(Wden, Qden, Qinvden); + + _fmpz_poly_mullow(Qinv + m, Qinv, m, W + m, n - m, n - m); + fmpz_mul(Qinvden, Qinvden, Wden); + _fmpz_vec_scalar_mul_fmpz(Qinv, Qinv, m, Wden); + + _fmpz_vec_neg(Qinv + m, Qinv + m, n - m); + + _fmpq_poly_canonicalise(Qinv, Qinvden, n); + } + + _fmpz_vec_clear(W, alloc + 1); + flint_free(a); + } +} + +void fmpq_poly_inv_series_newton(fmpq_poly_t Qinv, const fmpq_poly_t Q, slong n) +{ + fmpz *copy; + int alloc; + + if (Q->length >= n) + { + copy = Q->coeffs; + alloc = 0; + } + else + { + slong i; + copy = (fmpz *) flint_malloc(n * sizeof(fmpz)); + for (i = 0; i < Q->length; i++) + copy[i] = Q->coeffs[i]; + for ( ; i < n; i++) + copy[i] = 0; + alloc = 1; + } + + if (Qinv != Q) + { + fmpq_poly_fit_length(Qinv, n); + _fmpq_poly_inv_series_newton(Qinv->coeffs, Qinv->den, copy, Q->den, n); + } + else + { + fmpq_poly_t t; + fmpq_poly_init2(t, n); + _fmpq_poly_inv_series_newton(t->coeffs, t->den, copy, Q->den, n); + fmpq_poly_swap(Qinv, t); + fmpq_poly_clear(t); + } + + _fmpq_poly_set_length(Qinv, n); + fmpq_poly_canonicalise(Qinv); + + if (alloc) + flint_free(copy); +} + diff --git a/external/flint-2.4.3/fmpq_poly/invsqrt_series.c b/external/flint-2.4.3/fmpq_poly/invsqrt_series.c new file mode 100644 index 0000000..ea414cc --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/invsqrt_series.c @@ -0,0 +1,133 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" +#include "fmpq_poly.h" + + +void +_fmpq_poly_invsqrt_series(fmpz * rpoly, fmpz_t rden, + const fmpz * poly, const fmpz_t den, slong n) +{ + slong m; + fmpz * t, * u; + fmpz_t tden, uden; + + if (n == 1) + { + fmpz_one(rpoly); + fmpz_one(rden); + return; + } + + m = (n + 1) / 2; + + _fmpq_poly_invsqrt_series(rpoly, rden, poly, den, m); + + fmpz_init(tden); + fmpz_init(uden); + t = _fmpz_vec_init(n); + u = _fmpz_vec_init(n); + + _fmpz_vec_zero(rpoly + m, n - m); + + _fmpq_poly_mul(t, tden, rpoly, rden, m, rpoly, rden, m); + if (2*m - 1 < n) + fmpz_zero(t + n - 1); + + _fmpq_poly_mullow(u, uden, t, tden, n, rpoly, rden, n, n); + _fmpq_poly_mullow(t, tden, u, uden, n, poly, den, n, n); + _fmpz_vec_neg(t + m, t + m, n - m); + _fmpz_vec_zero(t, m); + fmpz_mul_ui(tden, tden, UWORD(2)); + _fmpq_poly_canonicalise(t, tden, n); + + _fmpq_poly_add(rpoly, rden, rpoly, rden, m, t, tden, n); + + fmpz_clear(tden); + fmpz_clear(uden); + _fmpz_vec_clear(t, n); + _fmpz_vec_clear(u, n); +} + +void fmpq_poly_invsqrt_series(fmpq_poly_t res, const fmpq_poly_t poly, slong n) +{ + fmpz *copy; + int alloc; + + if (poly->length < 1 || !fmpz_equal(poly->coeffs, poly->den)) + { + flint_printf("Exception (fmpq_poly_invsqrt_series). Constant term != 1.\n"); + abort(); + } + + if (n < 1) + { + fmpq_poly_zero(res); + return; + } + + if (poly->length >= n) + { + copy = poly->coeffs; + alloc = 0; + } + else + { + slong i; + copy = (fmpz *) flint_malloc(n * sizeof(fmpz)); + for (i = 0; i < poly->length; i++) + copy[i] = poly->coeffs[i]; + for ( ; i < n; i++) + copy[i] = 0; + alloc = 1; + } + + if (res != poly) + { + fmpq_poly_fit_length(res, n); + _fmpq_poly_invsqrt_series(res->coeffs, res->den, copy, poly->den, n); + } + else + { + fmpq_poly_t t; + fmpq_poly_init2(t, n); + _fmpq_poly_invsqrt_series(t->coeffs, t->den, copy, poly->den, n); + fmpq_poly_swap(res, t); + fmpq_poly_clear(t); + } + + _fmpq_poly_set_length(res, n); + fmpq_poly_canonicalise(res); + + if (alloc) + flint_free(copy); +} diff --git a/external/flint-2.4.3/fmpq_poly/is_canonical.c b/external/flint-2.4.3/fmpq_poly/is_canonical.c new file mode 100644 index 0000000..fed9d83 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/is_canonical.c @@ -0,0 +1,64 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpq_poly.h" + +int _fmpq_poly_is_canonical(const fmpz * poly, const fmpz_t den, slong len) +{ + if (len) + { + int ans; + fmpz_t c; + + if (fmpz_is_zero(poly + len - 1)) + return 0; + + if (fmpz_sgn(den) < 0) + return 0; + + fmpz_init(c); + _fmpz_poly_content(c, poly, len); + fmpz_gcd(c, c, den); + ans = (*c == WORD(1)); + fmpz_clear(c); + + return ans; + } + else + { + return (*den == WORD(1)); + } +} + +int fmpq_poly_is_canonical(const fmpq_poly_t poly) +{ + return _fmpq_poly_is_canonical(poly->coeffs, poly->den, poly->length); +} + diff --git a/external/flint-2.4.3/fmpq_poly/is_monic.c b/external/flint-2.4.3/fmpq_poly/is_monic.c new file mode 100644 index 0000000..ffe23b0 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/is_monic.c @@ -0,0 +1,41 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpq_poly.h" + +int _fmpq_poly_is_monic(const fmpz * poly, const fmpz_t den, slong len) +{ + return (len > 0) && fmpz_equal(poly + (len - 1), den); +} + +int fmpq_poly_is_monic(const fmpq_poly_t poly) +{ + return _fmpq_poly_is_monic(poly->coeffs, poly->den, poly->length); +} + diff --git a/external/flint-2.4.3/fmpq_poly/is_squarefree.c b/external/flint-2.4.3/fmpq_poly/is_squarefree.c new file mode 100644 index 0000000..e5eb628 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/is_squarefree.c @@ -0,0 +1,37 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" +#include "fmpq_poly.h" + +int fmpq_poly_is_squarefree(const fmpq_poly_t poly) +{ + return _fmpz_poly_is_squarefree(poly->coeffs, poly->length); +} + diff --git a/external/flint-2.4.3/fmpq_poly/lcm.c b/external/flint-2.4.3/fmpq_poly/lcm.c new file mode 100644 index 0000000..126e2f5 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/lcm.c @@ -0,0 +1,138 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" +#include "fmpq_poly.h" + +void _fmpq_poly_lcm(fmpz *L, fmpz_t denL, + const fmpz *A, slong lenA, const fmpz *B, slong lenB) +{ + if (lenA == 1) /* lenA == lenB == 1 */ + { + fmpz_one(L); + fmpz_one(denL); + } + else + { + fmpz *copyA, *copyB; + fmpz_t s, t; + slong lenL; + + fmpz_init(s); + fmpz_init(t); + + _fmpz_vec_content(s, A, lenA); + _fmpz_vec_content(t, B, lenB); + + if (fmpz_is_one(s)) + { + if (fmpz_is_one(t)) + { + copyA = (fmpz *) A; + copyB = (fmpz *) B; + } + else + { + copyA = (fmpz *) A; + copyB = _fmpz_vec_init(lenB); + _fmpz_vec_scalar_divexact_fmpz(copyB, B, lenB, t); + } + } + else + { + if (fmpz_is_one(s)) + { + copyA = _fmpz_vec_init(lenA); + copyB = (fmpz *) B; + _fmpz_vec_scalar_divexact_fmpz(copyA, A, lenA, s); + } + else + { + copyA = _fmpz_vec_init(lenA + lenB); + copyB = copyA + lenA; + _fmpz_vec_scalar_divexact_fmpz(copyA, A, lenA, s); + _fmpz_vec_scalar_divexact_fmpz(copyB, B, lenB, t); + } + } + + _fmpz_poly_lcm(L, copyA, lenA, copyB, lenB); + + for (lenL = lenA + lenB - 2; !L[lenL]; lenL--) ; + lenL++; + + fmpz_set(denL, L + (lenL - 1)); + + if (A != copyA) + _fmpz_vec_clear(copyA, lenA + (B != copyB) * lenB); + else if (B != copyB) + _fmpz_vec_clear(copyB, lenB); + + fmpz_clear(s); + fmpz_clear(t); + } +} + +void fmpq_poly_lcm(fmpq_poly_t L, const fmpq_poly_t A, const fmpq_poly_t B) +{ + slong lenA = A->length, lenB = B->length, lenL = lenA + lenB - 1; + + if (lenA == 0 || lenB == 0) + { + fmpq_poly_zero(L); + return; + } + + if (L == A || L == B) + { + fmpq_poly_t t; + fmpq_poly_init2(t, lenL); + if (lenA >= lenB) + _fmpq_poly_lcm(t->coeffs, t->den, A->coeffs, A->length, + B->coeffs, B->length); + else + _fmpq_poly_lcm(t->coeffs, t->den, B->coeffs, B->length, + A->coeffs, A->length); + fmpq_poly_swap(t, L); + fmpq_poly_clear(t); + } + else + { + fmpq_poly_fit_length(L, lenL); + if (lenA >= lenB) + _fmpq_poly_lcm(L->coeffs, L->den, A->coeffs, A->length, + B->coeffs, B->length); + else + _fmpq_poly_lcm(L->coeffs, L->den, B->coeffs, B->length, + A->coeffs, A->length); + } + + _fmpq_poly_set_length(L, lenL); + _fmpq_poly_normalise(L); +} + diff --git a/external/flint-2.4.3/fmpq_poly/log_series.c b/external/flint-2.4.3/fmpq_poly/log_series.c new file mode 100644 index 0000000..cda1b3e --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/log_series.c @@ -0,0 +1,96 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpq_poly.h" + +void _fmpq_poly_log_series(fmpz * g, fmpz_t gden, + const fmpz * f, const fmpz_t fden, slong n) +{ + fmpz * f_diff; + fmpz * f_inv; + fmpz_t f_diff_den; + fmpz_t f_inv_den; + + f_diff = _fmpz_vec_init(n); + f_inv = _fmpz_vec_init(n); + fmpz_init(f_diff_den); + fmpz_init(f_inv_den); + + _fmpq_poly_derivative(f_diff, f_diff_den, f, fden, n); + _fmpq_poly_inv_series(f_inv, f_inv_den, f, fden, n); + _fmpq_poly_mullow(g, gden, f_diff, f_diff_den, n - 1, f_inv, f_inv_den, n - 1, n - 1); + _fmpq_poly_integral(g, gden, g, gden, n); + + _fmpz_vec_clear(f_diff, n); + _fmpz_vec_clear(f_inv, n); + fmpz_clear(f_diff_den); + fmpz_clear(f_inv_den); +} + + +void +fmpq_poly_log_series(fmpq_poly_t res, const fmpq_poly_t f, slong n) +{ + fmpz * f_coeffs; + slong flen = f->length; + + if (flen < 1 || !fmpz_equal(f->coeffs, f->den)) + { + flint_printf("Exception (fmpq_poly_log_series). Constant term != 1.\n"); + abort(); + } + + if (flen == 1 || n < 2) + { + fmpq_poly_zero(res); + return; + } + + fmpq_poly_fit_length(res, n); + + if (flen < n) + { + f_coeffs = _fmpz_vec_init(n); + _fmpz_vec_set(f_coeffs, f->coeffs, flen); + } + else + { + f_coeffs = f->coeffs; + } + + _fmpq_poly_log_series(res->coeffs, res->den, f_coeffs, f->den, n); + + if (flen < n) + { + _fmpz_vec_clear(f_coeffs, n); + } + + _fmpq_poly_set_length(res, n); + _fmpq_poly_normalise(res); +} diff --git a/external/flint-2.4.3/fmpq_poly/make_monic.c b/external/flint-2.4.3/fmpq_poly/make_monic.c new file mode 100644 index 0000000..f1fc8f0 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/make_monic.c @@ -0,0 +1,53 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpq_poly.h" + +void _fmpq_poly_make_monic(fmpz * rpoly, fmpz_t rden, + const fmpz * poly, const fmpz_t den, slong len) +{ + _fmpz_poly_primitive_part(rpoly, poly, len); + fmpz_set(rden, rpoly + (len - 1)); +} + +void fmpq_poly_make_monic(fmpq_poly_t res, const fmpq_poly_t poly) +{ + slong len = poly->length; + if (len == 0) + { + fmpq_poly_zero(res); + return; + } + + fmpq_poly_fit_length(res, len); + _fmpq_poly_set_length(res, len); + + _fmpq_poly_make_monic(res->coeffs, res->den, poly->coeffs, poly->den, len); +} + diff --git a/external/flint-2.4.3/fmpq_poly/mul.c b/external/flint-2.4.3/fmpq_poly/mul.c new file mode 100644 index 0000000..818f38c --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/mul.c @@ -0,0 +1,115 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" +#include "fmpq_poly.h" + +void _fmpq_poly_mul(fmpz * rpoly, fmpz_t rden, + const fmpz * poly1, const fmpz_t den1, slong len1, + const fmpz * poly2, const fmpz_t den2, slong len2) +{ + fmpz_t gcd1; /* GCD( poly1, den2 ) */ + fmpz_t gcd2; /* GCD( poly2, den1 ) */ + fmpz_init(gcd1); + fmpz_init(gcd2); + fmpz_one(gcd1); + fmpz_one(gcd2); + + if (*den2 != WORD(1)) + { + _fmpz_vec_content(gcd1, poly1, len1); + if (*gcd1 != WORD(1)) + fmpz_gcd(gcd1, gcd1, den2); + } + if (*den1 != WORD(1)) + { + _fmpz_vec_content(gcd2, poly2, len2); + if (*gcd2 != WORD(1)) + fmpz_gcd(gcd2, gcd2, den1); + } + + /* + TODO: If gcd1 and gcd2 are very large compared to the degrees of + poly1 and poly2, we might want to create copies of the polynomials + and divide out the common factors *before* the multiplication. + */ + + _fmpz_poly_mul(rpoly, poly1, len1, poly2, len2); + fmpz_mul(rden, den1, den2); + + if ((*gcd1 != WORD(1)) | (*gcd2 != WORD(1))) + { + fmpz_t g; + fmpz_init(g); + fmpz_mul(g, gcd1, gcd2); + _fmpz_vec_scalar_divexact_fmpz(rpoly, rpoly, len1 + len2 - 1, g); + fmpz_divexact(rden, rden, g); + fmpz_clear(g); + } + + fmpz_clear(gcd1); + fmpz_clear(gcd2); +} + +void fmpq_poly_mul(fmpq_poly_t res, const fmpq_poly_t poly1, const fmpq_poly_t poly2) +{ + slong len; + + if (poly1->length == 0 || poly2->length == 0) + { + fmpq_poly_zero(res); + return; + } + + len = poly1->length + poly2->length - 1; + + if (res == poly2 || res == poly1) + { + fmpq_poly_t t; + fmpq_poly_init2(t, len); + fmpq_poly_mul(t, poly1, poly2); + fmpq_poly_swap(res, t); + fmpq_poly_clear(t); + return; + } + + fmpq_poly_fit_length(res, len); + + if (poly1->length >= poly2->length) + _fmpq_poly_mul(res->coeffs, res->den, + poly1->coeffs, poly1->den, poly1->length, + poly2->coeffs, poly2->den, poly2->length); + else + _fmpq_poly_mul(res->coeffs, res->den, + poly2->coeffs, poly2->den, poly2->length, + poly1->coeffs, poly1->den, poly1->length); + + _fmpq_poly_set_length(res, len); +} + diff --git a/external/flint-2.4.3/fmpq_poly/mullow.c b/external/flint-2.4.3/fmpq_poly/mullow.c new file mode 100644 index 0000000..b056c4f --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/mullow.c @@ -0,0 +1,82 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" +#include "fmpq_poly.h" + +void +_fmpq_poly_mullow(fmpz * rpoly, fmpz_t rden, + const fmpz * poly1, const fmpz_t den1, slong len1, + const fmpz * poly2, const fmpz_t den2, slong len2, slong n) +{ + _fmpz_poly_mullow(rpoly, poly1, len1, poly2, len2, n); + fmpz_mul(rden, den1, den2); +} + +void +fmpq_poly_mullow(fmpq_poly_t res, + const fmpq_poly_t poly1, const fmpq_poly_t poly2, slong n) +{ + const slong len1 = poly1->length; + const slong len2 = poly2->length; + slong lenr; + + if (len1 == 0 || len2 == 0 || n == 0) + { + fmpq_poly_zero(res); + return; + } + + if (res == poly1 || res == poly2) + { + fmpq_poly_t t; + fmpq_poly_init2(t, n); + fmpq_poly_mullow(t, poly1, poly2, n); + fmpq_poly_swap(res, t); + fmpq_poly_clear(t); + return; + } + + lenr = len1 + len2 - 1; + if (n > lenr) + n = lenr; + + fmpq_poly_fit_length(res, n); + if (len1 >= len2) + _fmpq_poly_mullow(res->coeffs, res->den, + poly1->coeffs, poly1->den, len1, + poly2->coeffs, poly2->den, len2, n); + else + _fmpq_poly_mullow(res->coeffs, res->den, + poly2->coeffs, poly2->den, len2, + poly1->coeffs, poly1->den, len1, n); + _fmpq_poly_set_length(res, n); + fmpq_poly_canonicalise(res); +} diff --git a/external/flint-2.4.3/fmpq_poly/neg.c b/external/flint-2.4.3/fmpq_poly/neg.c new file mode 100644 index 0000000..1c04691 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/neg.c @@ -0,0 +1,46 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +*****************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpq_poly.h" + +void fmpq_poly_neg(fmpq_poly_t poly1, const fmpq_poly_t poly2) +{ + if (poly1 == poly2) + { + _fmpz_vec_neg(poly1->coeffs, poly2->coeffs, poly2->length); + } + else + { + fmpq_poly_fit_length(poly1, poly2->length); + _fmpz_vec_neg(poly1->coeffs, poly2->coeffs, poly2->length); + _fmpq_poly_set_length(poly1, poly2->length); + fmpz_set(poly1->den, poly2->den); + } +} + diff --git a/external/flint-2.4.3/fmpq_poly/normalise.c b/external/flint-2.4.3/fmpq_poly/normalise.c new file mode 100644 index 0000000..34bfbb0 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/normalise.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" + +void _fmpq_poly_normalise(fmpq_poly_t poly) +{ + slong i; + for (i = poly->length - 1; (i >= 0) && !poly->coeffs[i]; i--) ; + poly->length = i + 1; +} + diff --git a/external/flint-2.4.3/fmpq_poly/pow.c b/external/flint-2.4.3/fmpq_poly/pow.c new file mode 100644 index 0000000..620093c --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/pow.c @@ -0,0 +1,72 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpq_poly.h" + +void _fmpq_poly_pow(fmpz * rpoly, fmpz_t rden, + const fmpz * poly, const fmpz_t den, slong len, ulong e) +{ + _fmpz_poly_pow(rpoly, poly, len, e); + fmpz_pow_ui(rden, den, e); +} + +void fmpq_poly_pow(fmpq_poly_t res, const fmpq_poly_t poly, ulong e) +{ + slong len = poly->length, rlen; + + if (e == 0) + { + fmpq_poly_set_ui(res, 1); + return; + } + if (len == 0) + { + fmpq_poly_zero(res); + return; + } + + rlen = (slong) e * (len - WORD(1)) + WORD(1); + + if (res != poly) + { + fmpq_poly_fit_length(res, rlen); + _fmpq_poly_pow(res->coeffs, res->den, poly->coeffs, poly->den, len, e); + _fmpq_poly_set_length(res, rlen); + } + else + { + fmpq_poly_t t; + fmpq_poly_init2(t, rlen); + _fmpq_poly_pow(t->coeffs, t->den, poly->coeffs, poly->den, len, e); + _fmpq_poly_set_length(t, rlen); + fmpq_poly_swap(res, t); + fmpq_poly_clear(t); + } +} + diff --git a/external/flint-2.4.3/fmpq_poly/powers_clear.c b/external/flint-2.4.3/fmpq_poly/powers_clear.c new file mode 100644 index 0000000..662d080 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/powers_clear.c @@ -0,0 +1,46 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpq_poly.h" + +void +_fmpq_poly_powers_clear(fmpq_poly_struct * powers, slong len) +{ + slong i; + for (i = 0; i < 2*len - 1; i++) + fmpq_poly_clear(powers + i); + + flint_free(powers); +} + +void +fmpq_poly_powers_clear(fmpq_poly_powers_precomp_t pinv) +{ + _fmpq_poly_powers_clear(pinv->powers, pinv->len); +} diff --git a/external/flint-2.4.3/fmpq_poly/powers_precompute.c b/external/flint-2.4.3/fmpq_poly/powers_precompute.c new file mode 100644 index 0000000..d33fd9b --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/powers_precompute.c @@ -0,0 +1,83 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpq_poly.h" + +fmpq_poly_struct * +_fmpq_poly_powers_precompute(const fmpz * B, const fmpz_t denB, slong len) +{ + slong i; + fmpq_poly_struct * powers = flint_malloc(sizeof(fmpq_poly_struct)*(2*len - 1)); + fmpq_poly_t pow, p; + + fmpq_poly_init2(pow, len); + fmpq_poly_one(pow); + fmpq_poly_init2(p, len - 1); + + for (i = 0; i < 2*len - 1; i++) + { + fmpq_poly_init(powers + i); + + if (pow->length == len) /* reduce pow mod B */ + { + fmpz_mul(fmpq_poly_denref(p), B + len - 1, fmpq_poly_denref(pow)); + _fmpz_vec_scalar_mul_fmpz(fmpq_poly_numref(p), B, len - 1, + fmpq_poly_numref(pow) + len - 1); + _fmpq_poly_set_length(p, len - 1); + _fmpq_poly_normalise(p); + fmpq_poly_canonicalise(p); + fmpq_poly_sub(pow, pow, p); + _fmpq_poly_set_length(pow, len - 1); + _fmpq_poly_normalise(pow); + fmpq_poly_canonicalise(pow); + } + + fmpq_poly_set(powers + i, pow); + fmpq_poly_shift_left(pow, pow, 1); + } + + fmpq_poly_clear(pow); + fmpq_poly_clear(p); + + return powers; +} + +void fmpq_poly_powers_precompute(fmpq_poly_powers_precomp_t pinv, + fmpq_poly_t poly) +{ + if (poly->length == 0) + { + flint_printf("Exception (fmpz_poly_powers_precompute). Division by zero.\n"); + abort(); + } + + pinv->powers = _fmpq_poly_powers_precompute(fmpq_poly_numref(poly), + fmpq_poly_denref(poly), poly->length); + pinv->len = poly->length; +} diff --git a/external/flint-2.4.3/fmpq_poly/primitive_part.c b/external/flint-2.4.3/fmpq_poly/primitive_part.c new file mode 100644 index 0000000..1462d62 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/primitive_part.c @@ -0,0 +1,56 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpq_poly.h" + +void _fmpq_poly_primitive_part(fmpz * rpoly, fmpz_t rden, + const fmpz * poly, const fmpz_t den, slong len) +{ + _fmpz_poly_primitive_part(rpoly, poly, len); + fmpz_one(rden); +} + +void fmpq_poly_primitive_part(fmpq_poly_t res, const fmpq_poly_t poly) +{ + const slong len = poly->length; + + if (len == 0) + { + fmpq_poly_zero(res); + } + else + { + fmpq_poly_fit_length(res, len); + _fmpq_poly_set_length(res, len); + + _fmpq_poly_primitive_part(res->coeffs, res->den, + poly->coeffs, poly->den, len); + } +} + diff --git a/external/flint-2.4.3/fmpq_poly/randtest.c b/external/flint-2.4.3/fmpq_poly/randtest.c new file mode 100644 index 0000000..fb2863a --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/randtest.c @@ -0,0 +1,126 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include + +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +void fmpq_poly_randtest(fmpq_poly_t poly, flint_rand_t state, + slong len, mp_bitcnt_t bits) +{ + ulong m; + + m = n_randlimb(state); + + fmpq_poly_fit_length(poly, len); + _fmpq_poly_set_length(poly, len); + + if (m & UWORD(1)) + { + _fmpz_vec_randtest(poly->coeffs, state, len, bits); + } + else + { + fmpz_t x; + + fmpz_init(x); + fmpz_randtest(x, state, bits / 2); + _fmpz_vec_randtest(poly->coeffs, state, len, (bits + 1) / 2); + _fmpz_vec_scalar_mul_fmpz(poly->coeffs, poly->coeffs, len, x); + fmpz_clear(x); + } + + if (m & UWORD(2)) + { + fmpz_randtest_not_zero(poly->den, state, FLINT_MAX(bits, 1)); + fmpz_abs(poly->den, poly->den); + fmpq_poly_canonicalise(poly); + } + else + { + fmpz_one(poly->den); + _fmpq_poly_normalise(poly); + } +} + +void fmpq_poly_randtest_unsigned(fmpq_poly_t poly, flint_rand_t state, + slong len, mp_bitcnt_t bits) +{ + ulong m; + + m = n_randlimb(state); + + fmpq_poly_fit_length(poly, len); + _fmpq_poly_set_length(poly, len); + + if (m & UWORD(1)) + { + _fmpz_vec_randtest_unsigned(poly->coeffs, state, len, bits); + } + else + { + fmpz_t x; + + fmpz_init(x); + fmpz_randtest_unsigned(x, state, bits / 2); + _fmpz_vec_randtest_unsigned(poly->coeffs, state, len, (bits + 1) / 2); + _fmpz_vec_scalar_mul_fmpz(poly->coeffs, poly->coeffs, len, x); + fmpz_clear(x); + } + + if (m & UWORD(2)) + { + fmpz_randtest_not_zero(poly->den, state, FLINT_MAX(bits, 1)); + fmpz_abs(poly->den, poly->den); + fmpq_poly_canonicalise(poly); + } + else + { + fmpz_one(poly->den); + _fmpq_poly_normalise(poly); + } +} + +void fmpq_poly_randtest_not_zero(fmpq_poly_t f, flint_rand_t state, + slong len, mp_bitcnt_t bits) +{ + if ((bits == 0) | (len == 0)) + { + flint_printf("Exception (fmpq_poly_randtest_not_zeo). bits == 0.\n"); + abort(); + } + + fmpq_poly_randtest(f, state, len, bits); + if (f->length == 0) + fmpq_poly_set_ui(f, 1); +} + diff --git a/external/flint-2.4.3/fmpq_poly/realloc.c b/external/flint-2.4.3/fmpq_poly/realloc.c new file mode 100644 index 0000000..1bc7937 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/realloc.c @@ -0,0 +1,65 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" + +void fmpq_poly_realloc(fmpq_poly_t poly, slong alloc) +{ + if (alloc == 0) /* Clear up, reinitialise */ + { + fmpq_poly_clear(poly); + fmpq_poly_init(poly); + return; + } + + if (poly->alloc) /* Realloc */ + { + if (poly->length > alloc) /* Reduce the size */ + { + slong i; + for (i = alloc; i < poly->length; i++) + _fmpz_demote(poly->coeffs + i); + poly->length = alloc; + _fmpq_poly_normalise(poly); + } + poly->coeffs = (fmpz *) flint_realloc(poly->coeffs, alloc * sizeof(fmpz)); + if (poly->alloc < alloc) + { + flint_mpn_zero((mp_ptr) (poly->coeffs + poly->alloc), alloc - poly->alloc); + } + } + else /* Nothing allocated, do it now */ + { + poly->coeffs = (fmpz *) flint_calloc(alloc, sizeof(fmpz)); + } + + poly->alloc = alloc; +} + diff --git a/external/flint-2.4.3/fmpq_poly/rem.c b/external/flint-2.4.3/fmpq_poly/rem.c new file mode 100644 index 0000000..5f53588 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/rem.c @@ -0,0 +1,131 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpq_poly.h" + +void _fmpq_poly_rem(fmpz * R, fmpz_t r, + const fmpz * A, const fmpz_t a, slong lenA, + const fmpz * B, const fmpz_t b, slong lenB, const fmpz_preinvn_t inv) +{ + slong lenR; + ulong d; + const fmpz * lead = B + (lenB - 1); + + if (lenB == 1) + { + fmpz_one(r); + return; + } + + /* + From pseudo division over Z we have + lead^d * A = Q * B + R + and thus + {A, a} = {b * Q, a * lead^d} * {B, b} + {R, a * lead^d}. + */ + _fmpz_poly_pseudo_rem(R, &d, A, lenA, B, lenB, inv); + + /* Determine the actual length of R */ + for (lenR = lenB - 2; lenR >= 0 && !R[lenR]; lenR--) ; + lenR++; + + /* 1. lead^d == +-1. {R, r} = {R, a} up to sign */ + if (d == UWORD(0) || *lead == WORD(1) || *lead == WORD(-1)) + { + fmpz_one(r); + if (lenR > 0) + _fmpq_poly_scalar_div_fmpz(R, r, R, r, lenR, a); + + if (*lead == WORD(-1) && d % UWORD(2)) + _fmpz_vec_neg(R, R, lenR); + } + /* 2. lead^d != +-1. {R, r} = {R, a lead^d} */ + else + { + /* + TODO: Improve this. Clearly we do not need to compute + den = a lead^d in many cases, but can determine the GCD from + lead alone already. + */ + fmpz_t den; + fmpz_init(den); + fmpz_pow_ui(den, lead, d); + fmpz_mul(den, a, den); + + fmpz_one(r); + if (lenR > 0) + _fmpq_poly_scalar_div_fmpz(R, r, R, r, lenR, den); + + fmpz_clear(den); + } +} + +void fmpq_poly_rem(fmpq_poly_t R, + const fmpq_poly_t poly1, const fmpq_poly_t poly2) +{ + slong lenA, lenB, lenR; + + if (fmpq_poly_is_zero(poly2)) + { + flint_printf("Exception (fmpq_poly_rem). Division by zero.\n"); + abort(); + } + + if (poly1->length < poly2->length) + { + fmpq_poly_set(R, poly1); + return; + } + + /* Deal with aliasing */ + if (R == poly1 || R == poly2) + { + fmpq_poly_t tempR; + fmpq_poly_init(tempR); + fmpq_poly_rem(tempR, poly1, poly2); + fmpq_poly_swap(R, tempR); + fmpq_poly_clear(tempR); + return; + } + + lenA = poly1->length; + lenB = poly2->length; + lenR = lenB - 1; + + fmpq_poly_fit_length(R, lenA); /* XXX: Need at least that much space */ + + _fmpq_poly_rem(R->coeffs, R->den, + poly1->coeffs, poly1->den, poly1->length, + poly2->coeffs, poly2->den, poly2->length, NULL); + + _fmpq_poly_set_length(R, lenR); + _fmpq_poly_normalise(R); +} + diff --git a/external/flint-2.4.3/fmpq_poly/rem_powers_precomp.c b/external/flint-2.4.3/fmpq_poly/rem_powers_precomp.c new file mode 100644 index 0000000..d41dae8 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/rem_powers_precomp.c @@ -0,0 +1,123 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpq_poly.h" + +void _fmpq_poly_rem_powers_precomp(fmpz * A, fmpz_t denA, slong m, + const fmpz * B, const fmpz_t denB, slong n, + fmpq_poly_struct * const powers) +{ + slong i; + fmpq_poly_t prod; + fmpz_t den; + + if (m >= 2*n) /* TODO: make this case use the precomputed squares */ + { + fmpz * R = _fmpz_vec_init(m); + fmpz_init(den); + + _fmpz_vec_set(R, A, m); + fmpz_set(den, denA); + + _fmpq_poly_rem(A, denA, R, den, m, B, denB, n, NULL); + + _fmpz_vec_clear(R, m); + fmpz_clear(den); + + return; + } + + if (m < n) + return; + + fmpz_init(den); + + fmpq_poly_init2(prod, n - 1); + fmpz_set(den, denA); + + for (i = n - 1; i < m; i++) + { + _fmpz_vec_scalar_mul_fmpz(fmpq_poly_numref(prod), + fmpq_poly_numref(powers + i), powers[i].length, A + i); + fmpz_mul(fmpq_poly_denref(prod), fmpq_poly_denref(powers + i), den); + _fmpq_poly_add_can(A, denA, A, denA, n - 1, fmpq_poly_numref(prod), + fmpq_poly_denref(prod), powers[i].length, 0); + } + + fmpq_poly_clear(prod); + fmpz_clear(den); +} + +void +fmpq_poly_rem_powers_precomp(fmpq_poly_t R, const fmpq_poly_t A, + const fmpq_poly_t B, const fmpq_poly_powers_precomp_t B_inv) +{ + fmpq_poly_t tR; + fmpz * r, * d; + slong len1 = A->length, len2 = B->length; + + if (len1 < len2) + { + fmpq_poly_set(R, A); + return; + } + + if (R == B) + { + fmpq_poly_init2(tR, len1); + r = fmpq_poly_numref(tR); + d = fmpq_poly_denref(tR); + } + else + { + fmpq_poly_fit_length(R, len1); + r = fmpq_poly_numref(R); + d = fmpq_poly_denref(R); + } + + if (R == B || R != A) + { + _fmpz_vec_set(r, fmpq_poly_numref(A), len1); + fmpz_set(d, fmpq_poly_denref(A)); + } + + _fmpq_poly_rem_powers_precomp(r, d, len1, fmpq_poly_numref(B), + fmpq_poly_denref(B), len2, B_inv->powers); + + if (R == B) + { + _fmpq_poly_set_length(tR, len2 - 1); + fmpq_poly_swap(tR, R); + fmpq_poly_clear(tR); + } + else + _fmpq_poly_set_length(R, len2 - 1); + + _fmpq_poly_normalise(R); +} diff --git a/external/flint-2.4.3/fmpq_poly/rescale.c b/external/flint-2.4.3/fmpq_poly/rescale.c new file mode 100644 index 0000000..2ed42f6 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/rescale.c @@ -0,0 +1,92 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" +#include "fmpq_poly.h" + +void +_fmpq_poly_rescale(fmpz * res, fmpz_t denr, + const fmpz * poly, const fmpz_t den, slong len, + const fmpz_t xnum, const fmpz_t xden) +{ + if (len < WORD(2)) + { + if (res != poly) + { + _fmpz_vec_set(res, poly, len); + fmpz_set(denr, den); + } + } + else + { + slong i; + fmpz_t t; + + fmpz_init(t); + + fmpz_one(t); + fmpz_set(res, poly); + for (i = WORD(1); i < len; i++) + { + fmpz_mul(t, t, xnum); + fmpz_mul(res + i, poly + i, t); + } + fmpz_one(t); + for (i = len - WORD(2); i >= WORD(0); i--) + { + fmpz_mul(t, t, xden); + fmpz_mul(res + i, res + i, t); + } + fmpz_mul(denr, den, t); + + fmpz_clear(t); + + _fmpq_poly_canonicalise(res, denr, len); + } +} + +void fmpq_poly_rescale(fmpq_poly_t res, const fmpq_poly_t poly, const fmpq_t x) +{ + if (fmpq_is_zero(x)) + { + fmpq_poly_zero(res); + } + else if (poly->length < WORD(2)) + { + fmpq_poly_set(res, poly); + } + else + { + fmpq_poly_fit_length(res, poly->length); + _fmpq_poly_rescale(res->coeffs, res->den, + poly->coeffs, poly->den, poly->length, + fmpq_numref(x), fmpq_denref(x)); + _fmpq_poly_set_length(res, poly->length); + } +} diff --git a/external/flint-2.4.3/fmpq_poly/resultant.c b/external/flint-2.4.3/fmpq_poly/resultant.c new file mode 100644 index 0000000..fdf339c --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/resultant.c @@ -0,0 +1,164 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpq_poly.h" + +void _fmpq_poly_resultant(fmpz_t rnum, fmpz_t rden, + const fmpz *poly1, const fmpz_t den1, slong len1, + const fmpz *poly2, const fmpz_t den2, slong len2) +{ + if (len2 == 1) + { + if (len1 == 1) + { + fmpz_one(rnum); + fmpz_one(rden); + } + else if (len1 == 2) + { + fmpz_set(rnum, poly2); + fmpz_set(rden, den2); + } + else + { + fmpz_pow_ui(rnum, poly2, len1 - 1); + if (fmpz_is_one(den2)) + { + fmpz_one(rden); + } + else + { + fmpz_pow_ui(rden, den2, len1 - 1); + } + } + } + else /* len1 >= len2 >= 2 */ + { + fmpz_t c1, c2; + fmpz *prim1, *prim2, *g; + slong lenG = len2; + + fmpz_init(c1); + fmpz_init(c2); + + _fmpz_vec_content(c1, poly1, len1); + _fmpz_vec_content(c2, poly2, len2); + + prim1 = _fmpz_vec_init(len1); + prim2 = _fmpz_vec_init(len2); + g = _fmpz_vec_init(len2); + + _fmpz_vec_scalar_divexact_fmpz(prim1, poly1, len1, c1); + _fmpz_vec_scalar_divexact_fmpz(prim2, poly2, len2, c2); + + _fmpz_poly_gcd(g, prim1, len1, prim2, len2); + FMPZ_VEC_NORM(g, lenG); + + if (lenG > 1) + { + fmpz_zero(rnum); + fmpz_one(rden); + } + else /* prim1, prim2 are coprime */ + { + fmpz_t t; + + fmpz_init(t); + _fmpz_poly_resultant(rnum, prim1, len1, prim2, len2); + + if (!fmpz_is_one(c1)) + { + fmpz_pow_ui(t, c1, len2 - 1); + fmpz_mul(rnum, rnum, t); + } + if (!fmpz_is_one(c2)) + { + fmpz_pow_ui(t, c2, len1 - 1); + fmpz_mul(rnum, rnum, t); + } + + if (fmpz_is_one(den1)) + { + if (fmpz_is_one(den2)) + fmpz_one(rden); + else + fmpz_pow_ui(rden, den2, len1 - 1); + } + else + { + if (fmpz_is_one(den2)) + fmpz_pow_ui(rden, den1, len2 - 1); + else + { + fmpz_pow_ui(rden, den1, len2 - 1); + fmpz_pow_ui(t, den2, len1 - 1); + fmpz_mul(rden, rden, t); + } + } + _fmpq_canonicalise(rnum, rden); + fmpz_clear(t); + } + + fmpz_clear(c1); + fmpz_clear(c2); + _fmpz_vec_clear(prim1, len1); + _fmpz_vec_clear(prim2, len2); + _fmpz_vec_clear(g, len2); + } +} + +void fmpq_poly_resultant(fmpq_t r, const fmpq_poly_t f, const fmpq_poly_t g) +{ + const slong len1 = f->length; + const slong len2 = g->length; + + if (len1 == 0 || len2 == 0) + { + fmpq_zero(r); + } + else + { + if (len1 >= len2) + { + _fmpq_poly_resultant(fmpq_numref(r), fmpq_denref(r), + f->coeffs, f->den, len1, + g->coeffs, g->den, len2); + } + else + { + _fmpq_poly_resultant(fmpq_numref(r), fmpq_denref(r), + g->coeffs, g->den, len2, + f->coeffs, f->den, len1); + + if (((len1 | len2) & WORD(1)) == WORD(0)) + fmpq_neg(r, r); + } + } +} + diff --git a/external/flint-2.4.3/fmpq_poly/reverse.c b/external/flint-2.4.3/fmpq_poly/reverse.c new file mode 100644 index 0000000..3bab843 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/reverse.c @@ -0,0 +1,49 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpq_poly.h" + +void fmpq_poly_reverse(fmpq_poly_t res, const fmpq_poly_t poly, slong n) +{ + slong len = FLINT_MIN(n, poly->length); + + if (len == 0) + { + fmpq_poly_zero(res); + return; + } + + fmpq_poly_fit_length(res, n); + _fmpz_poly_reverse(res->coeffs, poly->coeffs, len, n); + fmpz_set(res->den, poly->den); + _fmpq_poly_set_length(res, n); + + fmpq_poly_canonicalise(res); +} + diff --git a/external/flint-2.4.3/fmpq_poly/revert_series.c b/external/flint-2.4.3/fmpq_poly/revert_series.c new file mode 100644 index 0000000..bb7ddae --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/revert_series.c @@ -0,0 +1,99 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpq_poly.h" + +void +_fmpq_poly_revert_series(fmpz * Qinv, fmpz_t den, + const fmpz * Q, const fmpz_t Qden, slong n) +{ + _fmpq_poly_revert_series_lagrange_fast(Qinv, den, Q, Qden, n); +} + + +void +fmpq_poly_revert_series(fmpq_poly_t res, + const fmpq_poly_t poly, slong n) +{ + fmpz *copy; + int alloc; + + if (poly->length < 2 || !fmpz_is_zero(poly->coeffs) + || fmpz_is_zero(poly->coeffs + 1)) + { + flint_printf("Exception (fmpq_poly_revert_series). Input must have \n" + "zero constant term and nonzero coefficient of x^1.\n"); + abort(); + } + + if (n < 2) + { + fmpq_poly_zero(res); + return; + } + + if (poly->length >= n) + { + copy = poly->coeffs; + alloc = 0; + } + else + { + slong i; + copy = (fmpz *) flint_malloc(n * sizeof(fmpz)); + for (i = 0; i < poly->length; i++) + copy[i] = poly->coeffs[i]; + for ( ; i < n; i++) + copy[i] = 0; + alloc = 1; + } + + if (res != poly) + { + fmpq_poly_fit_length(res, n); + _fmpq_poly_revert_series(res->coeffs, + res->den, copy, poly->den, n); + } + else + { + fmpq_poly_t t; + fmpq_poly_init2(t, n); + _fmpq_poly_revert_series(t->coeffs, + t->den, copy, poly->den, n); + fmpq_poly_swap(res, t); + fmpq_poly_clear(t); + } + + _fmpq_poly_set_length(res, n); + _fmpq_poly_normalise(res); + + if (alloc) + flint_free(copy); +} diff --git a/external/flint-2.4.3/fmpq_poly/revert_series_lagrange.c b/external/flint-2.4.3/fmpq_poly/revert_series_lagrange.c new file mode 100644 index 0000000..178b728 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/revert_series_lagrange.c @@ -0,0 +1,180 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpq_poly.h" + + +static void +_set_vec(fmpz * rnum, fmpz_t den, + const fmpz * xnum, const fmpz * xden, slong len) +{ + slong j; + fmpz_t t; + fmpz_init(t); + fmpz_one(den); + + for (j = 0; j < len; j++) + fmpz_lcm(den, den, xden + j); + + for (j = 0; j < len; j++) + { + fmpz_divexact(t, den, xden + j); + fmpz_mul(rnum + j, xnum + j, t); + } + + fmpz_clear(t); +} + +void +_fmpq_poly_revert_series_lagrange(fmpz * Qinv, fmpz_t den, + const fmpz * Q, const fmpz_t Qden, slong n) +{ + slong i; + fmpz *R, *S, *T, *dens, *tmp; + fmpz_t Rden, Sden, Tden; + + if (fmpz_is_one(Qden) && (n > 1) && fmpz_is_pm1(Q + 1)) + { + _fmpz_poly_revert_series(Qinv, Q, n); + fmpz_one(den); + } + else if (n <= 2) + { + fmpz_zero(Qinv); + if (n == 2) + { + fmpz_set(Qinv + 1, Qden); + fmpz_set(den, Q + 1); + _fmpq_poly_canonicalise(Qinv, den, 2); + } + } + else + { + dens = _fmpz_vec_init(n); + R = _fmpz_vec_init(n - 1); + S = _fmpz_vec_init(n - 1); + T = _fmpz_vec_init(n - 1); + fmpz_init(Rden); + fmpz_init(Sden); + fmpz_init(Tden); + + fmpz_zero(Qinv); + fmpz_one(dens); + fmpz_set(Qinv + 1, Qden); + fmpz_set(dens + 1, Q + 1); + + _fmpq_poly_inv_series(R, Rden, Q + 1, Qden, n - 1); + _fmpq_poly_canonicalise(R, Rden, n - 1); + + _fmpz_vec_set(S, R, n - 1); + fmpz_set(Sden, Rden); + + for (i = 2; i < n; i++) + { + _fmpq_poly_mullow(T, Tden, S, Sden, n - 1, R, Rden, n - 1, n - 1); + _fmpq_poly_canonicalise(T, Tden, n - 1); + fmpz_set(Qinv + i, T + i - 1); + fmpz_mul_ui(dens + i, Tden, i); + tmp = S; S = T; T = tmp; + fmpz_swap(Sden, Tden); + } + + _set_vec(Qinv, den, Qinv, dens, n); + _fmpq_poly_canonicalise(Qinv, den, n); + + _fmpz_vec_clear(R, n - 1); + _fmpz_vec_clear(S, n - 1); + _fmpz_vec_clear(T, n - 1); + _fmpz_vec_clear(dens, n); + fmpz_clear(Rden); + fmpz_clear(Sden); + fmpz_clear(Tden); + } +} + +void +fmpq_poly_revert_series_lagrange(fmpq_poly_t res, + const fmpq_poly_t poly, slong n) +{ + fmpz *copy; + int alloc; + + if (poly->length < 2 || !fmpz_is_zero(poly->coeffs) + || fmpz_is_zero(poly->coeffs + 1)) + { + flint_printf("Exception (fmpq_poly_revert_series_lagrange). Input must have \n" + "zero constant term and nonzero coefficient of x^1.\n"); + abort(); + } + + if (n < 2) + { + fmpq_poly_zero(res); + return; + } + + if (poly->length >= n) + { + copy = poly->coeffs; + alloc = 0; + } + else + { + slong i; + copy = (fmpz *) flint_malloc(n * sizeof(fmpz)); + for (i = 0; i < poly->length; i++) + copy[i] = poly->coeffs[i]; + for ( ; i < n; i++) + copy[i] = 0; + alloc = 1; + } + + if (res != poly) + { + fmpq_poly_fit_length(res, n); + _fmpq_poly_revert_series_lagrange(res->coeffs, + res->den, copy, poly->den, n); + } + else + { + fmpq_poly_t t; + fmpq_poly_init2(t, n); + _fmpq_poly_revert_series_lagrange(t->coeffs, + t->den, copy, poly->den, n); + fmpq_poly_swap(res, t); + fmpq_poly_clear(t); + } + + _fmpq_poly_set_length(res, n); + _fmpq_poly_normalise(res); + + if (alloc) + flint_free(copy); +} diff --git a/external/flint-2.4.3/fmpq_poly/revert_series_lagrange_fast.c b/external/flint-2.4.3/fmpq_poly/revert_series_lagrange_fast.c new file mode 100644 index 0000000..ea168ca --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/revert_series_lagrange_fast.c @@ -0,0 +1,218 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + + +/* pointer to (x/Q)^i */ +#define Ri(ii) (R + (n-1)*((ii)-1)) +#define Rdeni(ii) (Rden + ii - 1) + +static void +_set_vec(fmpz * rnum, fmpz_t den, + const fmpz * xnum, const fmpz * xden, slong len) +{ + slong j; + fmpz_t t; + fmpz_init(t); + fmpz_one(den); + + for (j = 0; j < len; j++) + fmpz_lcm(den, den, xden + j); + + for (j = 0; j < len; j++) + { + fmpz_divexact(t, den, xden + j); + fmpz_mul(rnum + j, xnum + j, t); + } + + fmpz_clear(t); +} + +void +_fmpq_poly_revert_series_lagrange_fast(fmpz * Qinv, fmpz_t den, + const fmpz * Q, const fmpz_t Qden, slong n) +{ + slong i, j, k, m; + fmpz *R, *Rden, *S, *T, *dens, *tmp; + fmpz_t Sden, Tden, t; + + if (fmpz_is_one(Qden) && (n > 1) && fmpz_is_pm1(Q + 1)) + { + _fmpz_poly_revert_series(Qinv, Q, n); + fmpz_one(den); + return; + } + + if (n <= 2) + { + fmpz_zero(Qinv); + if (n == 2) + { + fmpz_set(Qinv + 1, Qden); + fmpz_set(den, Q + 1); + _fmpq_poly_canonicalise(Qinv, den, 2); + } + return; + } + + m = n_sqrt(n); + + fmpz_init(t); + dens = _fmpz_vec_init(n); + R = _fmpz_vec_init((n - 1) * m); + S = _fmpz_vec_init(n - 1); + T = _fmpz_vec_init(n - 1); + Rden = _fmpz_vec_init(m); + fmpz_init(Sden); + fmpz_init(Tden); + + fmpz_zero(Qinv); + fmpz_one(dens); + + _fmpq_poly_inv_series(Ri(1), Rdeni(1), Q + 1, Qden, n - 1); + _fmpq_poly_canonicalise(Ri(1), Rdeni(1), n - 1); + + for (i = 2; i <= m; i++) + { + _fmpq_poly_mullow(Ri(i), Rdeni(i), Ri(i-1), Rdeni(i-1), n - 1, + Ri(1), Rdeni(1), n - 1, n - 1); + _fmpq_poly_canonicalise(Ri(i), Rdeni(i), n - 1); + } + + for (i = 1; i < m; i++) + { + fmpz_set(Qinv + i, Ri(i) + i - 1); + fmpz_mul_ui(dens + i, Rdeni(i), i); + } + + _fmpz_vec_set(S, Ri(m), n - 1); + fmpz_set(Sden, Rdeni(m)); + + for (i = m; i < n; i += m) + { + fmpz_set(Qinv + i, S + i - 1); + fmpz_mul_ui(dens + i, Sden, i); + + for (j = 1; j < m && i + j < n; j++) + { + fmpz_mul(t, S + 0, Ri(j) + i + j - 1); + + for (k = 1; k <= i + j - 1; k++) + fmpz_addmul(t, S + k, Ri(j) + i + j - 1 - k); + + fmpz_set(Qinv + i + j, t); + fmpz_mul(dens + i + j, Sden, Rdeni(j)); + fmpz_mul_ui(dens + i + j, dens + i + j, i + j); + } + + if (i + 1 < n) + { + _fmpq_poly_mullow(T, Tden, S, Sden, n - 1, + Ri(m), Rdeni(m), n - 1, n - 1); + _fmpq_poly_canonicalise(T, Tden, n - 1); + fmpz_swap(Tden, Sden); + tmp = S; S = T; T = tmp; + } + } + + _set_vec(Qinv, den, Qinv, dens, n); + _fmpq_poly_canonicalise(Qinv, den, n); + + fmpz_clear(t); + _fmpz_vec_clear(dens, n); + _fmpz_vec_clear(R, (n - 1) * m); + _fmpz_vec_clear(S, n - 1); + _fmpz_vec_clear(T, n - 1); + _fmpz_vec_clear(Rden, m); + fmpz_clear(Sden); + fmpz_clear(Tden); +} + +void +fmpq_poly_revert_series_lagrange_fast(fmpq_poly_t res, + const fmpq_poly_t poly, slong n) +{ + fmpz *copy; + int alloc; + + if (poly->length < 2 || !fmpz_is_zero(poly->coeffs) + || fmpz_is_zero(poly->coeffs + 1)) + { + flint_printf("Exception (fmpq_poly_revert_series_lagrange_fast). Input must \n" + "have zero constant term and nonzero coefficient of x^1.\n"); + abort(); + } + + if (n < 2) + { + fmpq_poly_zero(res); + return; + } + + if (poly->length >= n) + { + copy = poly->coeffs; + alloc = 0; + } + else + { + slong i; + copy = (fmpz *) flint_malloc(n * sizeof(fmpz)); + for (i = 0; i < poly->length; i++) + copy[i] = poly->coeffs[i]; + for ( ; i < n; i++) + copy[i] = 0; + alloc = 1; + } + + if (res != poly) + { + fmpq_poly_fit_length(res, n); + _fmpq_poly_revert_series_lagrange_fast(res->coeffs, + res->den, copy, poly->den, n); + } + else + { + fmpq_poly_t t; + fmpq_poly_init2(t, n); + _fmpq_poly_revert_series_lagrange_fast(t->coeffs, + t->den, copy, poly->den, n); + fmpq_poly_swap(res, t); + fmpq_poly_clear(t); + } + + _fmpq_poly_set_length(res, n); + _fmpq_poly_normalise(res); + + if (alloc) + flint_free(copy); +} diff --git a/external/flint-2.4.3/fmpq_poly/revert_series_newton.c b/external/flint-2.4.3/fmpq_poly/revert_series_newton.c new file mode 100644 index 0000000..a8e2501 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/revert_series_newton.c @@ -0,0 +1,162 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpq_poly.h" + + +#define FLINT_REVERSE_NEWTON_CUTOFF 4 + +void +_fmpq_poly_revert_series_newton(fmpz * Qinv, fmpz_t den, + const fmpz * Q, const fmpz_t Qden, slong n) +{ + if (fmpz_is_one(Qden) && (n > 1) && fmpz_is_pm1(Q + 1)) + { + _fmpz_poly_revert_series(Qinv, Q, n); + fmpz_one(den); + } + else if (n <= 2) + { + fmpz_zero(Qinv); + if (n == 2) + { + fmpz_set(Qinv + 1, Qden); + fmpz_set(den, Q + 1); + _fmpq_poly_canonicalise(Qinv, den, 2); + } + } + else + { + slong *a, i, k; + fmpz *T, *U, *V; + fmpz_t Tden, Uden, Vden; + + T = _fmpz_vec_init(n); + U = _fmpz_vec_init(n); + V = _fmpz_vec_init(n); + fmpz_init(Tden); + fmpz_init(Uden); + fmpz_init(Vden); + + k = n; + for (i = 1; (WORD(1) << i) < k; i++); + a = (slong *) flint_malloc(i * sizeof(slong)); + a[i = 0] = k; + while (k >= FLINT_REVERSE_NEWTON_CUTOFF) + a[++i] = (k = (k + 1) / 2); + + _fmpq_poly_revert_series_lagrange(Qinv, den, Q, Qden, k); + _fmpz_vec_zero(Qinv + k, n - k); + + for (i--; i >= 0; i--) + { + k = a[i]; + _fmpq_poly_compose_series(T, Tden, Q, Qden, k, Qinv, den, k, k); + _fmpq_poly_derivative(U, Uden, T, Tden, k); fmpz_zero(U + k - 1); + fmpz_zero(T + 1); + _fmpq_poly_div_series(V, Vden, T, Tden, U, Uden, k); + _fmpq_poly_canonicalise(V, Vden, k); + _fmpq_poly_derivative(T, Tden, Qinv, den, k); + _fmpq_poly_mullow(U, Uden, V, Vden, k, T, Tden, k, k); + _fmpq_poly_sub(Qinv, den, Qinv, den, k, U, Uden, k); + } + + _fmpq_poly_canonicalise(Qinv, den, n); + + flint_free(a); + _fmpz_vec_clear(T, n); + _fmpz_vec_clear(U, n); + _fmpz_vec_clear(V, n); + fmpz_clear(Tden); + fmpz_clear(Uden); + fmpz_clear(Vden); + } +} + + +void +fmpq_poly_revert_series_newton(fmpq_poly_t res, + const fmpq_poly_t poly, slong n) +{ + fmpz *copy; + int alloc; + + if (poly->length < 2 || !fmpz_is_zero(poly->coeffs) + || fmpz_is_zero(poly->coeffs + 1)) + { + flint_printf("Exception (fmpq_poly_revert_series_newton). Input must have \n" + "zero constant term and nonzero coefficient of x^1.\n"); + abort(); + } + + if (n < 2) + { + fmpq_poly_zero(res); + return; + } + + if (poly->length >= n) + { + copy = poly->coeffs; + alloc = 0; + } + else + { + slong i; + copy = (fmpz *) flint_malloc(n * sizeof(fmpz)); + for (i = 0; i < poly->length; i++) + copy[i] = poly->coeffs[i]; + for ( ; i < n; i++) + copy[i] = 0; + alloc = 1; + } + + if (res != poly) + { + fmpq_poly_fit_length(res, n); + _fmpq_poly_revert_series_newton(res->coeffs, + res->den, copy, poly->den, n); + } + else + { + fmpq_poly_t t; + fmpq_poly_init2(t, n); + _fmpq_poly_revert_series_newton(t->coeffs, + t->den, copy, poly->den, n); + fmpq_poly_swap(res, t); + fmpq_poly_clear(t); + } + + _fmpq_poly_set_length(res, n); + _fmpq_poly_normalise(res); + + if (alloc) + flint_free(copy); +} diff --git a/external/flint-2.4.3/fmpq_poly/scalar_div_fmpq.c b/external/flint-2.4.3/fmpq_poly/scalar_div_fmpq.c new file mode 100644 index 0000000..ab9ec54 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/scalar_div_fmpq.c @@ -0,0 +1,129 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpq_poly.h" + +void _fmpq_poly_scalar_div_fmpq(fmpz * rpoly, fmpz_t rden, + const fmpz * poly, const fmpz_t den, slong len, + const fmpz_t r, const fmpz_t s) +{ + fmpz_t gcd1; /* GCD( poly, r ) */ + fmpz_t gcd2; /* GCD( s, den ) */ + fmpz_init(gcd1); + fmpz_init(gcd2); + fmpz_one(gcd1); + fmpz_one(gcd2); + if (*r != WORD(1)) + { + _fmpz_vec_content(gcd1, poly, len); + if (*gcd1 != WORD(1)) + fmpz_gcd(gcd1, gcd1, r); + } + if (*den != WORD(1) && *s != WORD(1)) + fmpz_gcd(gcd2, s, den); + + if (*gcd1 == WORD(1)) + { + if (*gcd2 == WORD(1)) + { + _fmpz_vec_scalar_mul_fmpz(rpoly, poly, len, s); + fmpz_mul(rden, den, r); + } + else + { + fmpz_t s2; + fmpz_init(s2); + fmpz_divexact(s2, s, gcd2); + _fmpz_vec_scalar_mul_fmpz(rpoly, poly, len, s2); + fmpz_divexact(rden, den, gcd2); + fmpz_mul(rden, rden, r); + fmpz_clear(s2); + } + } + else + { + fmpz_t r2; + fmpz_init(r2); + fmpz_divexact(r2, r, gcd1); + if (*gcd2 == WORD(1)) + { + _fmpz_vec_scalar_divexact_fmpz(rpoly, poly, len, gcd1); + _fmpz_vec_scalar_mul_fmpz(rpoly, rpoly, len, s); + fmpz_mul(rden, den, r2); + } + else + { + fmpz_t s2; + fmpz_init(s2); + fmpz_divexact(s2, s, gcd2); + _fmpz_vec_scalar_divexact_fmpz(rpoly, poly, len, gcd1); + _fmpz_vec_scalar_mul_fmpz(rpoly, rpoly, len, s2); + fmpz_divexact(rden, den, gcd2); + fmpz_mul(rden, rden, r2); + fmpz_clear(s2); + } + fmpz_clear(r2); + } + + if (_fmpz_vec_is_zero(rpoly, len)) + fmpz_one(rden); + if (fmpz_sgn(rden) < 0) + { + _fmpz_vec_neg(rpoly, rpoly, len); + fmpz_neg(rden, rden); + } + + fmpz_clear(gcd1); + fmpz_clear(gcd2); +} + +void fmpq_poly_scalar_div_fmpq(fmpq_poly_t rop, const fmpq_poly_t op, const fmpq_t c) +{ + if (fmpq_is_zero(c)) + { + flint_printf("Exception (fmpq_poly_scalar_div_fmpq). Division by zero.\n"); + abort(); + } + + if (fmpq_poly_is_zero(op)) + { + fmpq_poly_zero(rop); + } + else + { + fmpq_poly_fit_length(rop, op->length); + _fmpq_poly_set_length(rop, op->length); + + _fmpq_poly_scalar_div_fmpq(rop->coeffs, rop->den, + op->coeffs, op->den, op->length, + fmpq_numref(c), fmpq_denref(c)); + } +} + diff --git a/external/flint-2.4.3/fmpq_poly/scalar_div_fmpz.c b/external/flint-2.4.3/fmpq_poly/scalar_div_fmpz.c new file mode 100644 index 0000000..ec4dc58 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/scalar_div_fmpz.c @@ -0,0 +1,86 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpq_poly.h" + +void _fmpq_poly_scalar_div_fmpz(fmpz * rpoly, fmpz_t rden, const fmpz * poly, + const fmpz_t den, slong len, const fmpz_t c) +{ + if (*c == WORD(1)) + { + if (rpoly != poly) + { + _fmpz_vec_set(rpoly, poly, len); + fmpz_set(rden, den); + } + } + else if (*c == WORD(-1)) + { + _fmpz_vec_neg(rpoly, poly, len); + fmpz_set(rden, den); + } + else + { + fmpz_t d; + fmpz_init(d); + _fmpz_vec_content(d, poly, len); + fmpz_gcd(d, d, c); + + if (fmpz_sgn(c) < 0) + fmpz_neg(d, d); + _fmpz_vec_scalar_divexact_fmpz(rpoly, poly, len, d); + fmpz_divexact(d, c, d); + fmpz_mul(rden, den, d); + + fmpz_clear(d); + } +} + +void fmpq_poly_scalar_div_fmpz(fmpq_poly_t rop, const fmpq_poly_t op, const fmpz_t c) +{ + if (*c == WORD(0)) + { + flint_printf("Exception (fmpq_poly_scalar_div_fmpz). Division by zero.\n"); + abort(); + } + + if (fmpq_poly_is_zero(op)) + { + fmpq_poly_zero(rop); + return; + } + + fmpq_poly_fit_length(rop, op->length); + _fmpq_poly_set_length(rop, op->length); + + _fmpq_poly_scalar_div_fmpz(rop->coeffs, rop->den, + op->coeffs, op->den, op->length, c); +} + diff --git a/external/flint-2.4.3/fmpq_poly/scalar_div_mpq.c b/external/flint-2.4.3/fmpq_poly/scalar_div_mpq.c new file mode 100644 index 0000000..2af47eb --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/scalar_div_mpq.c @@ -0,0 +1,41 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpq_poly.h" + +void fmpq_poly_scalar_div_mpq(fmpq_poly_t rop, const fmpq_poly_t op, const mpq_t c) +{ + fmpq_t f; + + fmpq_init_set_readonly(f, c); + fmpq_poly_scalar_div_fmpq(rop, op, f); + fmpq_clear_readonly(f); +} + diff --git a/external/flint-2.4.3/fmpq_poly/scalar_div_mpz.c b/external/flint-2.4.3/fmpq_poly/scalar_div_mpz.c new file mode 100644 index 0000000..a08fb2b --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/scalar_div_mpz.c @@ -0,0 +1,41 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpq_poly.h" + +void fmpq_poly_scalar_div_mpz(fmpq_poly_t rop, const fmpq_poly_t op, const mpz_t c) +{ + fmpz_t f; + + fmpz_init_set_readonly(f, c); + fmpq_poly_scalar_div_fmpz(rop, op, f); + fmpz_clear_readonly(f); +} + diff --git a/external/flint-2.4.3/fmpq_poly/scalar_div_si.c b/external/flint-2.4.3/fmpq_poly/scalar_div_si.c new file mode 100644 index 0000000..ab7d3e2 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/scalar_div_si.c @@ -0,0 +1,99 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpq_poly.h" + +void _fmpq_poly_scalar_div_si(fmpz * rpoly, fmpz_t rden, const fmpz * poly, + const fmpz_t den, slong len, slong c) +{ + if (c == 1) + { + if (rpoly != poly) + { + _fmpz_vec_set(rpoly, poly, len); + fmpz_set(rden, den); + } + } + else if (c == -1) + { + _fmpz_vec_neg(rpoly, poly, len); + fmpz_set(rden, den); + } + else + { + fmpz_t d, f; + + fmpz_init(d); + fmpz_init(f); + + fmpz_set_si(f, c); + _fmpz_vec_content(d, poly, len); + fmpz_gcd(d, d, f); + + if (c > 0) + { + _fmpz_vec_scalar_divexact_fmpz(rpoly, poly, len, d); + fmpz_mul_si(rden, den, c / fmpz_get_si(d)); + } + else + { + ulong q = (- (ulong) c) / fmpz_get_ui(d); + + fmpz_neg(d, d); + _fmpz_vec_scalar_divexact_fmpz(rpoly, poly, len, d); + fmpz_mul_ui(rden, den, q); + } + + fmpz_clear(d); + fmpz_clear(f); + } +} + +void fmpq_poly_scalar_div_si(fmpq_poly_t rop, const fmpq_poly_t op, slong c) +{ + if (c == WORD(0)) + { + flint_printf("Exception (fmpq_poly_scalar_div_si). Division by zero.\n"); + abort(); + } + + if (fmpq_poly_is_zero(op)) + { + fmpq_poly_zero(rop); + return; + } + + fmpq_poly_fit_length(rop, op->length); + _fmpq_poly_set_length(rop, op->length); + + _fmpq_poly_scalar_div_si(rop->coeffs, rop->den, + op->coeffs, op->den, op->length, c); +} + diff --git a/external/flint-2.4.3/fmpq_poly/scalar_div_ui.c b/external/flint-2.4.3/fmpq_poly/scalar_div_ui.c new file mode 100644 index 0000000..b676a5c --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/scalar_div_ui.c @@ -0,0 +1,81 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpq_poly.h" + +void _fmpq_poly_scalar_div_ui(fmpz * rpoly, fmpz_t rden, const fmpz * poly, + const fmpz_t den, slong len, ulong c) +{ + if (c == UWORD(1)) + { + if (rpoly != poly) + _fmpz_vec_set(rpoly, poly, len); + fmpz_set(rden, den); + } + else + { + fmpz_t d, fc; + ulong ud; + fmpz_init(d); + fmpz_init(fc); + _fmpz_vec_content(d, poly, len); + fmpz_set_ui(fc, c); + fmpz_gcd(d, d, fc); + ud = fmpz_get_ui(d); /* gcd of d and c fits into a ulong */ + + _fmpz_vec_scalar_divexact_ui(rpoly, poly, len, ud); + fmpz_mul_ui(rden, den, c / ud); + + fmpz_clear(d); + fmpz_clear(fc); + } +} + +void fmpq_poly_scalar_div_ui(fmpq_poly_t rop, const fmpq_poly_t op, ulong c) +{ + if (c == UWORD(0)) + { + flint_printf("Exception (fmpq_poly_scalar_div_ui). Division by zero.\n"); + abort(); + } + + if (fmpq_poly_is_zero(op)) + { + fmpq_poly_zero(rop); + return; + } + + fmpq_poly_fit_length(rop, op->length); + _fmpq_poly_set_length(rop, op->length); + + _fmpq_poly_scalar_div_ui(rop->coeffs, rop->den, + op->coeffs, op->den, op->length, c); +} + diff --git a/external/flint-2.4.3/fmpq_poly/scalar_mul_fmpq.c b/external/flint-2.4.3/fmpq_poly/scalar_mul_fmpq.c new file mode 100644 index 0000000..e365b89 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/scalar_mul_fmpq.c @@ -0,0 +1,126 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpq_poly.h" + +void _fmpq_poly_scalar_mul_fmpq(fmpz * rpoly, fmpz_t rden, + const fmpz * poly, const fmpz_t den, slong len, + const fmpz_t r, const fmpz_t s) +{ + fmpz_t gcd1; /* GCD( poly, s ) */ + fmpz_t gcd2; /* GCD( r, den ) */ + + if (fmpz_is_zero(r)) + { + _fmpz_vec_zero(rpoly, len); + fmpz_one(rden); + return; + } + + fmpz_init(gcd1); + fmpz_init(gcd2); + fmpz_one(gcd1); + fmpz_one(gcd2); + if (*s != WORD(1)) + { + _fmpz_vec_content(gcd1, poly, len); + if (*gcd1 != WORD(1)) + fmpz_gcd(gcd1, gcd1, s); + } + if (*den != WORD(1) && *r != WORD(1)) + fmpz_gcd(gcd2, r, den); + + if (*gcd1 == WORD(1)) + { + if (*gcd2 == WORD(1)) + { + _fmpz_vec_scalar_mul_fmpz(rpoly, poly, len, r); + fmpz_mul(rden, den, s); + } + else + { + fmpz_t r2; + fmpz_init(r2); + fmpz_divexact(r2, r, gcd2); + _fmpz_vec_scalar_mul_fmpz(rpoly, poly, len, r2); + fmpz_divexact(rden, den, gcd2); + fmpz_mul(rden, rden, s); + fmpz_clear(r2); + } + } + else + { + fmpz_t s2; + fmpz_init(s2); + fmpz_divexact(s2, s, gcd1); + if (*gcd2 == WORD(1)) + { + _fmpz_vec_scalar_divexact_fmpz(rpoly, poly, len, gcd1); + _fmpz_vec_scalar_mul_fmpz(rpoly, rpoly, len, r); + fmpz_mul(rden, den, s2); + } + else + { + fmpz_t r2; + fmpz_init(r2); + fmpz_divexact(r2, r, gcd2); + _fmpz_vec_scalar_divexact_fmpz(rpoly, poly, len, gcd1); + _fmpz_vec_scalar_mul_fmpz(rpoly, rpoly, len, r2); + fmpz_divexact(rden, den, gcd2); + fmpz_mul(rden, rden, s2); + fmpz_clear(r2); + } + fmpz_clear(s2); + } + + fmpz_clear(gcd1); + fmpz_clear(gcd2); +} + +void fmpq_poly_scalar_mul_fmpq(fmpq_poly_t rop, const fmpq_poly_t op, const fmpq_t c) +{ + if (fmpz_is_one(fmpq_denref(c))) + { + fmpq_poly_scalar_mul_fmpz(rop, op, fmpq_numref(c)); + } + else if (fmpq_is_zero(c) || fmpq_poly_is_zero(op)) + { + fmpq_poly_zero(rop); + } + else + { + fmpq_poly_fit_length(rop, op->length); + _fmpq_poly_set_length(rop, op->length); + + _fmpq_poly_scalar_mul_fmpq(rop->coeffs, rop->den, + op->coeffs, op->den, op->length, + fmpq_numref(c), fmpq_denref(c)); + } +} + diff --git a/external/flint-2.4.3/fmpq_poly/scalar_mul_fmpz.c b/external/flint-2.4.3/fmpq_poly/scalar_mul_fmpz.c new file mode 100644 index 0000000..bb82291 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/scalar_mul_fmpz.c @@ -0,0 +1,80 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpq_poly.h" + +void _fmpq_poly_scalar_mul_fmpz(fmpz * rpoly, fmpz_t rden, + const fmpz * poly, const fmpz_t den, slong len, + const fmpz_t c) +{ + fmpz_t gcd; /* GCD( den, c ) */ + + if (fmpz_is_zero(c)) + { + _fmpz_vec_zero(rpoly, len); + fmpz_one(rden); + return; + } + + fmpz_init(gcd); + fmpz_one(gcd); + if (*c != WORD(1)) + fmpz_gcd(gcd, c, den); + if (*gcd == WORD(1)) + { + _fmpz_vec_scalar_mul_fmpz(rpoly, poly, len, c); + fmpz_set(rden, den); + } + else + { + fmpz_t c2; + fmpz_init(c2); + fmpz_divexact(c2, c, gcd); + _fmpz_vec_scalar_mul_fmpz(rpoly, poly, len, c2); + fmpz_divexact(rden, den, gcd); + fmpz_clear(c2); + } + fmpz_clear(gcd); +} + +void fmpq_poly_scalar_mul_fmpz(fmpq_poly_t rop, const fmpq_poly_t op, const fmpz_t c) +{ + if (fmpz_is_zero(c) || fmpq_poly_is_zero(op)) + { + fmpq_poly_zero(rop); + return; + } + + fmpq_poly_fit_length(rop, op->length); + _fmpq_poly_set_length(rop, op->length); + + _fmpq_poly_scalar_mul_fmpz(rop->coeffs, rop->den, + op->coeffs, op->den, op->length, c); +} + diff --git a/external/flint-2.4.3/fmpq_poly/scalar_mul_mpq.c b/external/flint-2.4.3/fmpq_poly/scalar_mul_mpq.c new file mode 100644 index 0000000..90525ea --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/scalar_mul_mpq.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpq_poly.h" + +void fmpq_poly_scalar_mul_mpq(fmpq_poly_t rop, const fmpq_poly_t op, const mpq_t c) +{ + fmpq_t f; + + fmpq_init_set_readonly(f, c); + fmpq_poly_scalar_mul_fmpq(rop, op, f); + fmpq_clear_readonly(f); +} + diff --git a/external/flint-2.4.3/fmpq_poly/scalar_mul_mpz.c b/external/flint-2.4.3/fmpq_poly/scalar_mul_mpz.c new file mode 100644 index 0000000..318bd3d --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/scalar_mul_mpz.c @@ -0,0 +1,41 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpq_poly.h" + +void +fmpq_poly_scalar_mul_mpz(fmpq_poly_t rop, const fmpq_poly_t op, const mpz_t c) +{ + fmpz_t f; + + fmpz_init_set_readonly(f, c); + fmpq_poly_scalar_mul_fmpz(rop, op, f); + fmpz_clear_readonly(f); +} + diff --git a/external/flint-2.4.3/fmpq_poly/scalar_mul_si.c b/external/flint-2.4.3/fmpq_poly/scalar_mul_si.c new file mode 100644 index 0000000..bd04243 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/scalar_mul_si.c @@ -0,0 +1,86 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpq_poly.h" + +void _fmpq_poly_scalar_mul_si(fmpz * rpoly, fmpz_t rden, + const fmpz * poly, const fmpz_t den, slong len, + slong c) +{ + fmpz_t gcd; /* GCD( den, c ) */ + + if (c == 0) + { + _fmpz_vec_zero(rpoly, len); + fmpz_one(rden); + return; + } + + fmpz_init(gcd); + fmpz_set_si(gcd, c); + fmpz_gcd(gcd, gcd, den); + if (*gcd == WORD(1)) + { + _fmpz_vec_scalar_mul_si(rpoly, poly, len, c); + fmpz_set(rden, den); + } + else + { + if (c > WORD_MIN || fmpz_cmp_ui(gcd, - (ulong) WORD_MIN)) + { + slong g = fmpz_get_si(gcd); + + _fmpz_vec_scalar_mul_si(rpoly, poly, len, c / g); + fmpz_divexact_si(rden, den, g); + } + else + { + _fmpz_vec_neg(rpoly, poly, len); + fmpz_divexact_ui(rden, den, - (ulong) WORD_MIN); + } + } + fmpz_clear(gcd); +} + +void fmpq_poly_scalar_mul_si(fmpq_poly_t rop, const fmpq_poly_t op, slong c) +{ + if (c == 0 || fmpq_poly_is_zero(op)) + { + fmpq_poly_zero(rop); + return; + } + + fmpq_poly_fit_length(rop, op->length); + _fmpq_poly_set_length(rop, op->length); + + _fmpq_poly_scalar_mul_si(rop->coeffs, rop->den, + op->coeffs, op->den, op->length, c); +} + diff --git a/external/flint-2.4.3/fmpq_poly/scalar_mul_ui.c b/external/flint-2.4.3/fmpq_poly/scalar_mul_ui.c new file mode 100644 index 0000000..2b4aa60 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/scalar_mul_ui.c @@ -0,0 +1,77 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpq_poly.h" + +void _fmpq_poly_scalar_mul_ui(fmpz * rpoly, fmpz_t rden, + const fmpz * poly, const fmpz_t den, slong len, + ulong c) +{ + fmpz_t gcd; /* GCD( den, c ) */ + + if (c == 0) + { + _fmpz_vec_zero(rpoly, len); + fmpz_one(rden); + return; + } + + fmpz_init(gcd); + fmpz_set_ui(gcd, c); + fmpz_gcd(gcd, gcd, den); + if (*gcd == WORD(1)) + { + _fmpz_vec_scalar_mul_ui(rpoly, poly, len, c); + fmpz_set(rden, den); + } + else + { + ulong gcd2 = fmpz_get_ui(gcd); + ulong c2 = c / gcd2; + _fmpz_vec_scalar_mul_ui(rpoly, poly, len, c2); + fmpz_fdiv_q_ui(rden, den, gcd2); + } + fmpz_clear(gcd); +} + +void fmpq_poly_scalar_mul_ui(fmpq_poly_t rop, const fmpq_poly_t op, ulong c) +{ + if (c == 0 || fmpq_poly_is_zero(op)) + { + fmpq_poly_zero(rop); + return; + } + + fmpq_poly_fit_length(rop, op->length); + _fmpq_poly_set_length(rop, op->length); + + _fmpq_poly_scalar_mul_ui(rop->coeffs, rop->den, + op->coeffs, op->den, op->length, c); +} + diff --git a/external/flint-2.4.3/fmpq_poly/set.c b/external/flint-2.4.3/fmpq_poly/set.c new file mode 100644 index 0000000..0a7eb01 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/set.c @@ -0,0 +1,46 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" + +void fmpq_poly_set(fmpq_poly_t poly1, const fmpq_poly_t poly2) +{ + if (poly1 != poly2) + { + slong i, len = poly2->length; + + fmpq_poly_fit_length(poly1, len); + for (i = 0; i < len; i++) + fmpz_set(poly1->coeffs + i, poly2->coeffs + i); + _fmpq_poly_set_length(poly1, len); + + fmpz_set(poly1->den, poly2->den); + } +} + diff --git a/external/flint-2.4.3/fmpq_poly/set_array_mpq.c b/external/flint-2.4.3/fmpq_poly/set_array_mpq.c new file mode 100644 index 0000000..eab32c2 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/set_array_mpq.c @@ -0,0 +1,72 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpq_poly.h" + +void +_fmpq_poly_set_array_mpq(fmpz * poly, fmpz_t den, const mpq_t * a, slong n) +{ + slong i; + mpz_t d, t; + + flint_mpz_init_set_ui(d, 1); + mpz_init(t); + for (i = 0; i < n; i++) + { + mpz_lcm(d, d, mpq_denref(a[i])); + } + + for (i = 0; i < n; i++) + { + __mpz_struct *ptr = _fmpz_promote(poly + i); + + mpz_divexact(t, d, mpq_denref(a[i])); + mpz_mul(ptr, mpq_numref(a[i]), t); + _fmpz_demote_val(poly + i); + } + + fmpz_set_mpz(den, d); + mpz_clear(d); + mpz_clear(t); +} + +void fmpq_poly_set_array_mpq(fmpq_poly_t poly, const mpq_t * a, slong n) +{ + if (n == 0) + { + fmpq_poly_zero(poly); + } + else + { + fmpq_poly_fit_length(poly, n); + _fmpq_poly_set_array_mpq(poly->coeffs, poly->den, a, n); + _fmpq_poly_set_length(poly, n); + _fmpq_poly_normalise(poly); + } +} diff --git a/external/flint-2.4.3/fmpq_poly/set_coeff_fmpq.c b/external/flint-2.4.3/fmpq_poly/set_coeff_fmpq.c new file mode 100644 index 0000000..6f11591 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/set_coeff_fmpq.c @@ -0,0 +1,99 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include + +#include "flint.h" +#include "fmpz.h" +#include "fmpq.h" +#include "fmpz_vec.h" +#include "fmpq_poly.h" + +void fmpq_poly_set_coeff_fmpq(fmpq_poly_t poly, slong n, const fmpq_t x) +{ + slong len = poly->length; + const int replace = (n < len && !fmpz_is_zero(poly->coeffs + n)); + + if (!replace && fmpq_is_zero(x)) + return; + + if (n + 1 > len) + { + fmpq_poly_fit_length(poly, n + 1); + _fmpq_poly_set_length(poly, n + 1); + flint_mpn_zero((mp_ptr) poly->coeffs + len, (n + 1) - len); + len = n + 1; + } + + if (replace) + { + fmpz_t c; + + fmpz_init(c); + + fmpz_zero(poly->coeffs + n); + _fmpz_poly_content(c, poly->coeffs, len); + _fmpz_vec_scalar_mul_fmpz(poly->coeffs, poly->coeffs, len, fmpq_denref(x)); + fmpz_mul(c, c, fmpq_denref(x)); + + fmpz_mul(poly->coeffs + n, fmpq_numref(x), poly->den); + fmpz_gcd(c, c, poly->coeffs + n); + fmpz_mul(poly->den, poly->den, fmpq_denref(x)); + + if (!fmpz_is_one(c)) + fmpz_gcd(c, c, poly->den); + if (!fmpz_is_one(c)) + { + _fmpz_vec_scalar_divexact_fmpz(poly->coeffs, poly->coeffs, len, c); + fmpz_divexact(poly->den, poly->den, c); + } + + _fmpq_poly_normalise(poly); + fmpz_clear(c); + } + else + { + fmpz_t d, t; + + fmpz_init(d); + fmpz_init(t); + + fmpz_gcd(d, poly->den, fmpq_denref(x)); + fmpz_divexact(t, fmpq_denref(x), d); + + _fmpz_vec_scalar_mul_fmpz(poly->coeffs, poly->coeffs, len, t); + fmpz_set(poly->coeffs + n, fmpq_numref(x)); + fmpz_mul(poly->coeffs + n, poly->coeffs + n, poly->den); + fmpz_divexact(poly->coeffs + n, poly->coeffs + n, d); + + fmpz_mul(poly->den, poly->den, t); + + fmpz_clear(d); + fmpz_clear(t); + } +} + diff --git a/external/flint-2.4.3/fmpq_poly/set_coeff_fmpz.c b/external/flint-2.4.3/fmpq_poly/set_coeff_fmpz.c new file mode 100644 index 0000000..f5aae36 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/set_coeff_fmpz.c @@ -0,0 +1,61 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" + +void fmpq_poly_set_coeff_fmpz(fmpq_poly_t poly, slong n, const fmpz_t x) +{ + slong len = poly->length; + const int replace = (n < len && !fmpz_is_zero(poly->coeffs + n)); + + if (!replace && fmpz_is_zero(x)) + return; + + if (n + 1 > len) + { + fmpq_poly_fit_length(poly, n + 1); + _fmpq_poly_set_length(poly, n + 1); + flint_mpn_zero((mp_ptr) poly->coeffs + len, (n + 1) - len); + } + + if (*poly->den == WORD(1)) + { + fmpz_set(poly->coeffs + n, x); + if (replace) + _fmpq_poly_normalise(poly); + } + else + { + fmpz_mul(poly->coeffs + n, poly->den, x); + if (replace) + fmpq_poly_canonicalise(poly); + } +} + diff --git a/external/flint-2.4.3/fmpq_poly/set_coeff_mpq.c b/external/flint-2.4.3/fmpq_poly/set_coeff_mpq.c new file mode 100644 index 0000000..bf2b9e1 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/set_coeff_mpq.c @@ -0,0 +1,43 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 William Hart + +******************************************************************************/ + +#include +#include + +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpq_poly.h" + +void fmpq_poly_set_coeff_mpq(fmpq_poly_t poly, slong n, const mpq_t x) +{ + fmpq_t f; + + fmpq_init_set_readonly(f, x); + fmpq_poly_set_coeff_fmpq(poly, n, f); + fmpq_clear_readonly(f); +} + diff --git a/external/flint-2.4.3/fmpq_poly/set_coeff_mpz.c b/external/flint-2.4.3/fmpq_poly/set_coeff_mpz.c new file mode 100644 index 0000000..d2a0d44 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/set_coeff_mpz.c @@ -0,0 +1,41 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" + +void fmpq_poly_set_coeff_mpz(fmpq_poly_t poly, slong n, const mpz_t x) +{ + fmpz_t f; + + fmpz_init_set_readonly(f, x); + fmpq_poly_set_coeff_fmpz(poly, n, f); + fmpz_clear_readonly(f); +} + diff --git a/external/flint-2.4.3/fmpq_poly/set_coeff_si.c b/external/flint-2.4.3/fmpq_poly/set_coeff_si.c new file mode 100644 index 0000000..28970c6 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/set_coeff_si.c @@ -0,0 +1,62 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 William Hart + +******************************************************************************/ + +#include +#include + +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" + +void fmpq_poly_set_coeff_si(fmpq_poly_t poly, slong n, slong x) +{ + slong len = poly->length; + const int replace = (n < len && !fmpz_is_zero(poly->coeffs + n)); + + if (!replace && (x == WORD(0))) + return; + + if (n + 1 > len) + { + fmpq_poly_fit_length(poly, n + 1); + _fmpq_poly_set_length(poly, n + 1); + flint_mpn_zero((mp_ptr) poly->coeffs + len, (n + 1) - len); + } + + if (*poly->den == WORD(1)) + { + fmpz_set_si(poly->coeffs + n, x); + if (replace) + _fmpq_poly_normalise(poly); + } + else + { + fmpz_mul_si(poly->coeffs + n, poly->den, x); + if (replace) + fmpq_poly_canonicalise(poly); + } +} + diff --git a/external/flint-2.4.3/fmpq_poly/set_coeff_ui.c b/external/flint-2.4.3/fmpq_poly/set_coeff_ui.c new file mode 100644 index 0000000..4037bf3 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/set_coeff_ui.c @@ -0,0 +1,62 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 William Hart + +******************************************************************************/ + +#include +#include + +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" + +void fmpq_poly_set_coeff_ui(fmpq_poly_t poly, slong n, ulong x) +{ + slong len = poly->length; + const int replace = (n < len && !fmpz_is_zero(poly->coeffs + n)); + + if (!replace && (x == UWORD(0))) + return; + + if (n + 1 > len) + { + fmpq_poly_fit_length(poly, n + 1); + _fmpq_poly_set_length(poly, n + 1); + flint_mpn_zero((mp_ptr) poly->coeffs + len, (n + 1) - len); + } + + if (*poly->den == WORD(1)) + { + fmpz_set_ui(poly->coeffs + n, x); + if (replace) + _fmpq_poly_normalise(poly); + } + else + { + fmpz_mul_ui(poly->coeffs + n, poly->den, x); + if (replace) + fmpq_poly_canonicalise(poly); + } +} + diff --git a/external/flint-2.4.3/fmpq_poly/set_fmpq.c b/external/flint-2.4.3/fmpq_poly/set_fmpq.c new file mode 100644 index 0000000..ee9c080 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/set_fmpq.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" + +void fmpq_poly_set_fmpq(fmpq_poly_t poly, const fmpq_t x) +{ + fmpq_poly_fit_length(poly, 1); + fmpz_set(poly->coeffs, fmpq_numref(x)); + fmpz_set(poly->den, fmpq_denref(x)); + _fmpq_poly_set_length(poly, 1); + _fmpq_poly_normalise(poly); +} + diff --git a/external/flint-2.4.3/fmpq_poly/set_fmpz.c b/external/flint-2.4.3/fmpq_poly/set_fmpz.c new file mode 100644 index 0000000..fe75040 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/set_fmpz.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" + +void fmpq_poly_set_fmpz(fmpq_poly_t poly, const fmpz_t x) +{ + fmpq_poly_fit_length(poly, 1); + fmpz_set(poly->coeffs, x); + fmpz_one(poly->den); + _fmpq_poly_set_length(poly, 1); + _fmpq_poly_normalise(poly); +} + diff --git a/external/flint-2.4.3/fmpq_poly/set_fmpz_poly.c b/external/flint-2.4.3/fmpq_poly/set_fmpz_poly.c new file mode 100644 index 0000000..7a84de3 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/set_fmpz_poly.c @@ -0,0 +1,46 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpq_poly.h" + +void fmpq_poly_set_fmpz_poly(fmpq_poly_t rop, const fmpz_poly_t op) +{ + if (fmpz_poly_is_zero(op)) + { + fmpq_poly_zero(rop); + } + else + { + fmpq_poly_fit_length(rop, fmpz_poly_length(op)); + _fmpq_poly_set_length(rop, fmpz_poly_length(op)); + _fmpz_vec_set(rop->coeffs, op->coeffs, rop->length); + fmpz_one(rop->den); + } +} + diff --git a/external/flint-2.4.3/fmpq_poly/set_length.c b/external/flint-2.4.3/fmpq_poly/set_length.c new file mode 100644 index 0000000..d748d70 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/set_length.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" + +void _fmpq_poly_set_length(fmpq_poly_t poly, slong len) +{ + slong i; + for (i = len; i < poly->length; i++) + _fmpz_demote(poly->coeffs + i); + poly->length = len; +} + diff --git a/external/flint-2.4.3/fmpq_poly/set_mpq.c b/external/flint-2.4.3/fmpq_poly/set_mpq.c new file mode 100644 index 0000000..98648e9 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/set_mpq.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" + +void fmpq_poly_set_mpq(fmpq_poly_t poly, const mpq_t x) +{ + fmpq_poly_fit_length(poly, 1); + fmpz_set_mpz(poly->coeffs, mpq_numref(x)); + fmpz_set_mpz(poly->den, mpq_denref(x)); + _fmpq_poly_set_length(poly, 1); + _fmpq_poly_normalise(poly); +} + diff --git a/external/flint-2.4.3/fmpq_poly/set_mpz.c b/external/flint-2.4.3/fmpq_poly/set_mpz.c new file mode 100644 index 0000000..4b488af --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/set_mpz.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" + +void fmpq_poly_set_mpz(fmpq_poly_t poly, const mpz_t x) +{ + fmpq_poly_fit_length(poly, 1); + fmpz_set_mpz(poly->coeffs, x); + fmpz_one(poly->den); + _fmpq_poly_set_length(poly, 1); + _fmpq_poly_normalise(poly); +} + diff --git a/external/flint-2.4.3/fmpq_poly/set_si.c b/external/flint-2.4.3/fmpq_poly/set_si.c new file mode 100644 index 0000000..ee7b0be --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/set_si.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" + +void fmpq_poly_set_si(fmpq_poly_t poly, slong x) +{ + fmpq_poly_fit_length(poly, 1); + fmpz_set_si(poly->coeffs, x); + fmpz_one(poly->den); + _fmpq_poly_set_length(poly, 1); + _fmpq_poly_normalise(poly); +} + diff --git a/external/flint-2.4.3/fmpq_poly/set_str.c b/external/flint-2.4.3/fmpq_poly/set_str.c new file mode 100644 index 0000000..c7c7c88 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/set_str.c @@ -0,0 +1,137 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpq_poly.h" + +int +_fmpq_poly_set_str(fmpz * poly, fmpz_t den, const char * str) +{ + char * w; + slong i, len; + mpq_t * a; + + len = atol(str); + if (len < 0) + return -1; + if (len == 0) + { + fmpz_one(den); + return 0; + } + + a = (mpq_t *) flint_malloc(len * sizeof(mpq_t)); + + while (*str++ != ' ') + ; + + /* Find maximal gap between spaces and allocate w */ + { + const char * s = str; + slong max; + for (max = 0; *s != '\0';) + { + slong cur; + for (s++, cur = 1; *s != ' ' && *s != '\0'; s++, cur++) ; + if (max < cur) + max = cur; + } + + w = (char *) flint_malloc((max + 1) * sizeof(char)); + } + + for (i = 0; i < len; i++) + { + char * v; + int ans; + + for (str++, v = w; *str != ' ' && *str != '\0';) + *v++ = *str++; + *v = '\0'; + mpq_init(a[i]); + ans = mpq_set_str(a[i], w, 10); + + /* If the format is not correct, clear up and return -1 */ + if (ans) + { + int j; + for (j = 0; j <= i; j++) + mpq_clear(a[j]); + flint_free(a); + flint_free(w); + return -1; + } + } + + _fmpq_poly_set_array_mpq(poly, den, (const mpq_t *) a, len); + + for (i = 0; i < len; i++) + mpq_clear(a[i]); + flint_free(a); + flint_free(w); + + return 0; +} + +int +fmpq_poly_set_str(fmpq_poly_t poly, const char * str) +{ + int ans; + slong len; + + len = atol(str); + if (len < 0) + return -1; + if (len == 0) + { + fmpq_poly_zero(poly); + return 0; + } + + fmpq_poly_fit_length(poly, len); + + ans = _fmpq_poly_set_str(poly->coeffs, poly->den, str); + + if (ans == 0) + { + _fmpq_poly_set_length(poly, len); + _fmpq_poly_normalise(poly); + } + else + { + _fmpz_vec_zero(poly->coeffs, len); + fmpz_one(poly->den); + _fmpq_poly_set_length(poly, 0); + } + + return ans; +} diff --git a/external/flint-2.4.3/fmpq_poly/set_ui.c b/external/flint-2.4.3/fmpq_poly/set_ui.c new file mode 100644 index 0000000..31929b0 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/set_ui.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" + +void fmpq_poly_set_ui(fmpq_poly_t poly, ulong x) +{ + fmpq_poly_fit_length(poly, 1); + fmpz_set_ui(poly->coeffs, x); + fmpz_one(poly->den); + _fmpq_poly_set_length(poly, 1); + _fmpq_poly_normalise(poly); +} + diff --git a/external/flint-2.4.3/fmpq_poly/shift_left.c b/external/flint-2.4.3/fmpq_poly/shift_left.c new file mode 100644 index 0000000..f59e25a --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/shift_left.c @@ -0,0 +1,52 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpq_poly.h" + +void +fmpq_poly_shift_left(fmpq_poly_t res, const fmpq_poly_t poly, slong n) +{ + if (n == 0) + { + fmpq_poly_set(res, poly); + return; + } + if (poly->length == 0) + { + fmpq_poly_zero(res); + return; + } + + fmpq_poly_fit_length(res, poly->length + n); + + _fmpz_poly_shift_left(res->coeffs, poly->coeffs, poly->length, n); + fmpz_set(res->den, poly->den); + + _fmpq_poly_set_length(res, poly->length + n); +} diff --git a/external/flint-2.4.3/fmpq_poly/shift_right.c b/external/flint-2.4.3/fmpq_poly/shift_right.c new file mode 100644 index 0000000..aa47d27 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/shift_right.c @@ -0,0 +1,53 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpq_poly.h" + +void +fmpq_poly_shift_right(fmpq_poly_t res, const fmpq_poly_t poly, slong n) +{ + if (n == 0) + { + fmpq_poly_set(res, poly); + return; + } + if (poly->length <= n) + { + fmpq_poly_zero(res); + return; + } + + fmpq_poly_fit_length(res, poly->length - n); + + _fmpz_poly_shift_right(res->coeffs, poly->coeffs, poly->length, n); + fmpz_set(res->den, poly->den); + + _fmpq_poly_set_length(res, poly->length - n); + fmpq_poly_canonicalise(res); +} diff --git a/external/flint-2.4.3/fmpq_poly/sin_series.c b/external/flint-2.4.3/fmpq_poly/sin_series.c new file mode 100644 index 0000000..2660355 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/sin_series.c @@ -0,0 +1,103 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpq_poly.h" + +void +_fmpq_poly_sin_series(fmpz * g, fmpz_t gden, + const fmpz * h, const fmpz_t hden, slong n) +{ + fmpz * t; + fmpz * u; + fmpz_t tden; + fmpz_t uden; + + t = _fmpz_vec_init(n); + u = _fmpz_vec_init(n); + fmpz_init(tden); + fmpz_init(uden); + + /* sin(x) = 2*tan(x/2)/(1+tan(x/2)^2) */ + fmpz_mul_ui(uden, hden, UWORD(2)); + _fmpq_poly_tan_series(t, tden, h, uden, n); + + _fmpq_poly_mullow(u, uden, t, tden, n, t, tden, n, n); + fmpz_set(u, uden); + _fmpq_poly_canonicalise(u, uden, n); + + _fmpq_poly_div_series(g, gden, t, tden, u, uden, n); + _fmpq_poly_scalar_mul_ui(g, gden, g, gden, n, UWORD(2)); + _fmpq_poly_canonicalise(g, gden, n); + + _fmpz_vec_clear(t, n); + _fmpz_vec_clear(u, n); + fmpz_clear(tden); + fmpz_clear(uden); +} + +void +fmpq_poly_sin_series(fmpq_poly_t res, const fmpq_poly_t f, slong n) +{ + fmpz * f_coeffs; + slong flen = f->length; + + if (flen && !fmpz_is_zero(f->coeffs)) + { + flint_printf("Exception (fmpq_poly_sin_series). Constant term != 0.\n"); + abort(); + } + + if (flen == 0 || n < 2) + { + fmpq_poly_zero(res); + return; + } + + fmpq_poly_fit_length(res, n); + + if (flen < n) + { + f_coeffs = _fmpz_vec_init(n); + _fmpz_vec_set(f_coeffs, f->coeffs, flen); + } + else + { + f_coeffs = f->coeffs; + } + + _fmpq_poly_sin_series(res->coeffs, res->den, f_coeffs, f->den, n); + + if (flen < n) + { + _fmpz_vec_clear(f_coeffs, n); + } + + _fmpq_poly_set_length(res, n); + _fmpq_poly_normalise(res); +} diff --git a/external/flint-2.4.3/fmpq_poly/sinh_series.c b/external/flint-2.4.3/fmpq_poly/sinh_series.c new file mode 100644 index 0000000..2004c8c --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/sinh_series.c @@ -0,0 +1,112 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpq_poly.h" + +void +_fmpq_poly_sinh_series(fmpz * g, fmpz_t gden, + const fmpz * h, const fmpz_t hden, slong n) +{ + fmpz * t; + fmpz_t tden; + + t = _fmpz_vec_init(n); + fmpz_init(tden); + + /* sinh(x) = (exp(x)-exp(-x))/2 */ + _fmpq_poly_exp_series(g, gden, h, hden, n); + _fmpq_poly_inv_series(t, tden, g, gden, n); + _fmpq_poly_sub(g, gden, g, gden, n, t, tden, n); + _fmpq_poly_scalar_div_ui(g, gden, g, gden, n, UWORD(2)); + _fmpq_poly_canonicalise(g, gden, n); + + _fmpz_vec_clear(t, n); + fmpz_clear(tden); +} + +void fmpq_poly_sinh_series(fmpq_poly_t res, const fmpq_poly_t poly, slong n) +{ + fmpz *copy; + int alloc; + + if (poly->length == 0) + { + fmpq_poly_zero(res); + return; + } + + if (!fmpz_is_zero(poly->coeffs)) + { + flint_printf("Exception (fmpq_poly_sinh_series). Constant term != 0.\n"); + abort(); + } + + if (n < 2) + { + fmpq_poly_zero(res); + return; + } + + if (poly->length >= n) + { + copy = poly->coeffs; + alloc = 0; + } + else + { + slong i; + copy = (fmpz *) flint_malloc(n * sizeof(fmpz)); + for (i = 0; i < poly->length; i++) + copy[i] = poly->coeffs[i]; + for ( ; i < n; i++) + copy[i] = 0; + alloc = 1; + } + + if (res != poly) + { + fmpq_poly_fit_length(res, n); + _fmpq_poly_sinh_series(res->coeffs, res->den, copy, poly->den, n); + } + else + { + fmpq_poly_t t; + fmpq_poly_init2(t, n); + _fmpq_poly_sinh_series(t->coeffs, t->den, copy, poly->den, n); + fmpq_poly_swap(res, t); + fmpq_poly_clear(t); + } + + _fmpq_poly_set_length(res, n); + _fmpq_poly_normalise(res); + + if (alloc) + flint_free(copy); +} + diff --git a/external/flint-2.4.3/fmpq_poly/sqrt_series.c b/external/flint-2.4.3/fmpq_poly/sqrt_series.c new file mode 100644 index 0000000..e6b2467 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/sqrt_series.c @@ -0,0 +1,102 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" +#include "fmpq_poly.h" + + +void +_fmpq_poly_sqrt_series(fmpz * rpoly, fmpz_t rden, + const fmpz * poly, const fmpz_t den, slong n) +{ + fmpz * t; + fmpz_t tden; + t = _fmpz_vec_init(n); + fmpz_init(tden); + _fmpq_poly_invsqrt_series(t, tden, poly, den, n); + _fmpq_poly_mullow(rpoly, rden, t, tden, n, poly, den, n, n); + _fmpz_vec_clear(t, n); + fmpz_clear(tden); +} + +void fmpq_poly_sqrt_series(fmpq_poly_t res, const fmpq_poly_t poly, slong n) +{ + fmpz *copy; + int alloc; + + if (poly->length < 1 || !fmpz_equal(poly->coeffs, poly->den)) + { + flint_printf("Exception (fmpq_poly_sqrt_series). Constant term != 1.\n"); + abort(); + } + + if (n < 1) + { + fmpq_poly_zero(res); + return; + } + + if (poly->length >= n) + { + copy = poly->coeffs; + alloc = 0; + } + else + { + slong i; + copy = (fmpz *) flint_malloc(n * sizeof(fmpz)); + for (i = 0; i < poly->length; i++) + copy[i] = poly->coeffs[i]; + for ( ; i < n; i++) + copy[i] = 0; + alloc = 1; + } + + if (res != poly) + { + fmpq_poly_fit_length(res, n); + _fmpq_poly_sqrt_series(res->coeffs, res->den, copy, poly->den, n); + } + else + { + fmpq_poly_t t; + fmpq_poly_init2(t, n); + _fmpq_poly_sqrt_series(t->coeffs, t->den, copy, poly->den, n); + fmpq_poly_swap(res, t); + fmpq_poly_clear(t); + } + + _fmpq_poly_set_length(res, n); + fmpq_poly_canonicalise(res); + + if (alloc) + flint_free(copy); +} diff --git a/external/flint-2.4.3/fmpq_poly/sub.c b/external/flint-2.4.3/fmpq_poly/sub.c new file mode 100644 index 0000000..3e2d79f --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/sub.c @@ -0,0 +1,146 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpq_poly.h" + +void _fmpq_poly_sub_can(fmpz * rpoly, fmpz_t rden, + const fmpz * poly1, const fmpz_t den1, slong len1, + const fmpz * poly2, const fmpz_t den2, slong len2, int can) +{ + slong max = FLINT_MAX(len1, len2); + slong min = FLINT_MIN(len1, len2); + + fmpz_t d; + fmpz_init(d); + fmpz_one(d); + if (*den1 != WORD(1) && *den2 != WORD(1)) + fmpz_gcd(d, den1, den2); + + if (*d == WORD(1)) + { + _fmpz_vec_scalar_mul_fmpz(rpoly, poly1, len1, den2); + _fmpz_vec_scalar_submul_fmpz(rpoly, poly2, min, den1); + if (len1 < len2) + { + _fmpz_vec_scalar_mul_fmpz(rpoly + min, poly2 + min, max - min, den1); + _fmpz_vec_neg(rpoly + min, rpoly + min, max - min); + } + fmpz_mul(rden, den1, den2); + } + else + { + fmpz_t den11; + fmpz_t den22; + fmpz_init(den11); + fmpz_init(den22); + fmpz_divexact(den11, den1, d); + fmpz_divexact(den22, den2, d); + + _fmpz_vec_scalar_mul_fmpz(rpoly, poly1, len1, den22); + _fmpz_vec_scalar_submul_fmpz(rpoly, poly2, len2, den11); + if (len1 < len2) + { + _fmpz_vec_scalar_mul_fmpz(rpoly + min, poly2 + min, max - min, den11); + _fmpz_vec_neg(rpoly + min, rpoly + min, max - min); + } + + if (_fmpz_vec_is_zero(rpoly, max)) + fmpz_one(rden); + else + { + if (can) + { + fmpz_t e; + fmpz_init(e); + _fmpz_vec_content(e, rpoly, max); + if (*e != WORD(1)) + fmpz_gcd(e, e, d); + + if (*e == WORD(1)) + fmpz_mul(rden, den1, den22); + else + { + _fmpz_vec_scalar_divexact_fmpz(rpoly, rpoly, max, e); + fmpz_divexact(den11, den1, e); + fmpz_mul(rden, den11, den22); + } + fmpz_clear(e); + } else + fmpz_mul(rden, den1, den22); + } + fmpz_clear(den11); + fmpz_clear(den22); + } + fmpz_clear(d); +} + +void _fmpq_poly_sub(fmpz * rpoly, fmpz_t rden, + const fmpz * poly1, const fmpz_t den1, slong len1, + const fmpz * poly2, const fmpz_t den2, slong len2) +{ + _fmpq_poly_sub_can(rpoly, rden, poly1, den1, len1, poly2, den2, len2, 1); +} + +void fmpq_poly_sub_can(fmpq_poly_t res, const fmpq_poly_t poly1, + const fmpq_poly_t poly2, int can) +{ + slong len1, len2, max; + + if (poly1 == poly2) + { + fmpq_poly_zero(res); + return; + } + + len1 = poly1->length; + len2 = poly2->length; + max = FLINT_MAX(poly1->length, poly2->length); + fmpq_poly_fit_length(res, max); + + if (res != poly2) + _fmpq_poly_sub_can(res->coeffs, res->den, + poly1->coeffs, poly1->den, len1, + poly2->coeffs, poly2->den, len2, can); + else + { + _fmpq_poly_sub_can(res->coeffs, res->den, + poly2->coeffs, poly2->den, len2, + poly1->coeffs, poly1->den, len1, can); + _fmpz_vec_neg(res->coeffs, res->coeffs, max); + } + + _fmpq_poly_set_length(res, max); + _fmpq_poly_normalise(res); +} + +void fmpq_poly_sub(fmpq_poly_t res, const fmpq_poly_t poly1, + const fmpq_poly_t poly2) +{ + fmpq_poly_sub_can(res, poly1, poly2, 1); +} diff --git a/external/flint-2.4.3/fmpq_poly/swap.c b/external/flint-2.4.3/fmpq_poly/swap.c new file mode 100644 index 0000000..859cfe6 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/swap.c @@ -0,0 +1,51 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" + +void fmpq_poly_swap(fmpq_poly_t poly1, fmpq_poly_t poly2) +{ + slong t; + fmpz * tptr; + + t = poly1->length; + poly1->length = poly2->length; + poly2->length = t; + + t = poly1->alloc; + poly1->alloc = poly2->alloc; + poly2->alloc = t; + + tptr = poly1->coeffs; + poly1->coeffs = poly2->coeffs; + poly2->coeffs = tptr; + + fmpz_swap(poly1->den, poly2->den); +} + diff --git a/external/flint-2.4.3/fmpq_poly/tan_series.c b/external/flint-2.4.3/fmpq_poly/tan_series.c new file mode 100644 index 0000000..66e91ea --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/tan_series.c @@ -0,0 +1,141 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpq_poly.h" + +void +_fmpq_poly_tan_series(fmpz * g, fmpz_t gden, + const fmpz * h, const fmpz_t hden, slong n) +{ + slong m; + fmpz * t, * u, * v; + fmpz_t tden, uden, vden; + + if (n <= 3) + { + if (n >= 1) fmpz_set(g + 0, h + 0); + if (n >= 2) fmpz_set(g + 1, h + 1); + if (n == 3) fmpz_set(g + 2, h + 2); + fmpz_set(gden, hden); + _fmpq_poly_canonicalise(g, gden, n); + return; + } + + m = (n + 1) / 2; + + _fmpq_poly_tan_series(g, gden, h, hden, m); + _fmpz_vec_zero(g + m, n - m); + + t = _fmpz_vec_init(n); + u = _fmpz_vec_init(n); + v = _fmpz_vec_init(n); + fmpz_init(tden); + fmpz_init(uden); + fmpz_init(vden); + + _fmpq_poly_mul(u, uden, g, gden, m, g, gden, m); + fmpz_set(u, uden); /* u += 1 */ + if (2*m - 1 < n) + fmpz_zero(u + n - 1); + + _fmpq_poly_atan_series(t, tden, g, gden, n); + _fmpq_poly_sub(t, tden, t, tden, n, h, hden, n); + _fmpq_poly_mullow(v + m, vden, u, uden, n, t + m, tden, n - m, n - m); + _fmpq_poly_sub(g, gden, g, gden, m, v, vden, n); + _fmpq_poly_canonicalise(g, gden, n); + + fmpz_clear(tden); + fmpz_clear(uden); + fmpz_clear(vden); + _fmpz_vec_clear(t, n); + _fmpz_vec_clear(u, n); + _fmpz_vec_clear(v, n); +} + +void fmpq_poly_tan_series(fmpq_poly_t res, const fmpq_poly_t poly, slong n) +{ + fmpz *copy; + int alloc; + + if (poly->length == 0) + { + fmpq_poly_zero(res); + return; + } + + if (!fmpz_is_zero(poly->coeffs)) + { + flint_printf("Exception (fmpq_poly_tan_series). Constant term != 0.\n"); + abort(); + } + + if (n < 2) + { + fmpq_poly_zero(res); + return; + } + + if (poly->length >= n) + { + copy = poly->coeffs; + alloc = 0; + } + else + { + slong i; + copy = (fmpz *) flint_malloc(n * sizeof(fmpz)); + for (i = 0; i < poly->length; i++) + copy[i] = poly->coeffs[i]; + for ( ; i < n; i++) + copy[i] = 0; + alloc = 1; + } + + if (res != poly) + { + fmpq_poly_fit_length(res, n); + _fmpq_poly_tan_series(res->coeffs, res->den, copy, poly->den, n); + } + else + { + fmpq_poly_t t; + fmpq_poly_init2(t, n); + _fmpq_poly_tan_series(t->coeffs, t->den, copy, poly->den, n); + fmpq_poly_swap(res, t); + fmpq_poly_clear(t); + } + + _fmpq_poly_set_length(res, n); + _fmpq_poly_normalise(res); + + if (alloc) + flint_free(copy); +} + diff --git a/external/flint-2.4.3/fmpq_poly/tanh_series.c b/external/flint-2.4.3/fmpq_poly/tanh_series.c new file mode 100644 index 0000000..9bc9b3a --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/tanh_series.c @@ -0,0 +1,101 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpq_poly.h" + +void +_fmpq_poly_tanh_series(fmpz * g, fmpz_t gden, + const fmpz * h, const fmpz_t hden, slong n) +{ + fmpz * t; + fmpz * u; + fmpz_t tden; + fmpz_t uden; + + t = _fmpz_vec_init(n); + u = _fmpz_vec_init(n); + fmpz_init(tden); + fmpz_init(uden); + + /* tanh(x) = (exp(2x)-1)/(exp(2x)+1) */ + _fmpq_poly_scalar_mul_ui(t, tden, h, hden, n, UWORD(2)); + _fmpq_poly_exp_series(u, uden, t, tden, n); + _fmpz_vec_set(t, u, n); + fmpz_set(tden, uden); + fmpz_zero(t); /* t[0] = 0 */ + fmpz_mul_ui(u, uden, UWORD(2)); /* u[0] = 2 */ + _fmpq_poly_div_series(g, gden, t, tden, u, uden, n); + _fmpq_poly_canonicalise(g, gden, n); + + _fmpz_vec_clear(t, n); + _fmpz_vec_clear(u, n); + fmpz_clear(tden); + fmpz_clear(uden); +} + +void +fmpq_poly_tanh_series(fmpq_poly_t res, const fmpq_poly_t f, slong n) +{ + fmpz * f_coeffs; + slong flen = f->length; + + if (flen && !fmpz_is_zero(f->coeffs)) + { + flint_printf("Exception (fmpq_poly_tanh_series). Constant term != 0.\n"); + abort(); + } + + if (flen == 0 || n < 2) + { + fmpq_poly_zero(res); + return; + } + + fmpq_poly_fit_length(res, n); + + if (flen < n) + { + f_coeffs = _fmpz_vec_init(n); + _fmpz_vec_set(f_coeffs, f->coeffs, flen); + } + else + { + f_coeffs = f->coeffs; + } + + _fmpq_poly_tanh_series(res->coeffs, res->den, f_coeffs, f->den, n); + + if (flen < n) + { + _fmpz_vec_clear(f_coeffs, n); + } + + _fmpq_poly_set_length(res, n); + _fmpq_poly_normalise(res); +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-add.c b/external/flint-2.4.3/fmpq_poly/test/t-add.c new file mode 100644 index 0000000..a48895b --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-add.c @@ -0,0 +1,113 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + ulong cflags = UWORD(0); + + FLINT_TEST_INIT(state); + + flint_printf("add...."); + fflush(stdout); + + /* Check aliasing of a and c */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, c; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(c); + fmpq_poly_randtest(a, state, n_randint(state, 100), 200); + fmpq_poly_randtest(b, state, n_randint(state, 100), 200); + + fmpq_poly_add(c, a, b); + fmpq_poly_add(a, a, b); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(c) ? 0 : 2; + result = (fmpq_poly_equal(a, c) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + fmpq_poly_debug(c), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(c); + } + + /* Check aliasing of b and c */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, c; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(c); + fmpq_poly_randtest(a, state, n_randint(state, 100), 200); + fmpq_poly_randtest(b, state, n_randint(state, 100), 200); + + fmpq_poly_add(c, a, b); + fmpq_poly_add(b, a, b); + + cflags |= fmpq_poly_is_canonical(b) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(c) ? 0 : 2; + result = (fmpq_poly_equal(b, c) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + fmpq_poly_debug(c), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-asin_series.c b/external/flint-2.4.3/fmpq_poly/test/t-asin_series.c new file mode 100644 index 0000000..80448c7 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-asin_series.c @@ -0,0 +1,128 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + ulong cflags = UWORD(0); + + FLINT_TEST_INIT(state); + + flint_printf("asin_series...."); + fflush(stdout); + + /* Check aliasing of a and c */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b; + slong n = n_randint(state, 50) + 1; + + fmpq_poly_init(a); + fmpq_poly_init(b); + + fmpq_poly_randtest_not_zero(a, state, n_randint(state, 50) + 1, 50); + fmpq_poly_set_coeff_ui(a, 0, UWORD(0)); + + fmpq_poly_canonicalise(a); + + fmpq_poly_asin_series(b, a, n); + fmpq_poly_asin_series(a, a, n); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(b) ? 0 : 2; + result = (fmpq_poly_equal(a, b) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + } + + /* Check asin(A) = atan(A/sqrt(1-A^2)) */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + fmpq_poly_t A, B, asinA, atanB; + slong n = n_randint(state, 80) + 1; + + fmpq_poly_init(A); + fmpq_poly_init(B); + fmpq_poly_init(asinA); + fmpq_poly_init(atanB); + + fmpq_poly_randtest_not_zero(A, state, n_randint(state, 80) + 1, 80); + fmpq_poly_set_coeff_ui(A, 0, UWORD(0)); + + fmpq_poly_mullow(B, A, A, n); + fmpq_poly_neg(B, B); + fmpq_poly_set_coeff_ui(B, 0, UWORD(1)); + fmpq_poly_invsqrt_series(B, B, n); + fmpq_poly_mullow(B, A, B, n); + + fmpq_poly_asin_series(asinA, A, n); + fmpq_poly_atan_series(atanB, B, n); + + cflags |= fmpq_poly_is_canonical(asinA) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(atanB) ? 0 : 2; + result = (fmpq_poly_equal(asinA, atanB) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("A = "), fmpq_poly_debug(A), flint_printf("\n\n"); + flint_printf("B = "), fmpq_poly_debug(B), flint_printf("\n\n"); + flint_printf("asin(A) = "), fmpq_poly_debug(asinA), flint_printf("\n\n"); + flint_printf("atan(B) = "), fmpq_poly_debug(atanB), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(A); + fmpq_poly_clear(B); + fmpq_poly_clear(asinA); + fmpq_poly_clear(atanB); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-asinh_series.c b/external/flint-2.4.3/fmpq_poly/test/t-asinh_series.c new file mode 100644 index 0000000..c9a9b41 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-asinh_series.c @@ -0,0 +1,127 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + ulong cflags = UWORD(0); + + FLINT_TEST_INIT(state); + + flint_printf("asinh_series...."); + fflush(stdout); + + /* Check aliasing of a and c */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b; + slong n = n_randint(state, 50) + 1; + + fmpq_poly_init(a); + fmpq_poly_init(b); + + fmpq_poly_randtest_not_zero(a, state, n_randint(state, 50) + 1, 50); + fmpq_poly_set_coeff_ui(a, 0, UWORD(0)); + + fmpq_poly_canonicalise(a); + + fmpq_poly_asinh_series(b, a, n); + fmpq_poly_asinh_series(a, a, n); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(b) ? 0 : 2; + result = (fmpq_poly_equal(a, b) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + } + + /* Check asinh(A) = atanh(A/sqrt(1+A^2)) */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + fmpq_poly_t A, B, asinhA, atanhB; + slong n = n_randint(state, 80) + 1; + + fmpq_poly_init(A); + fmpq_poly_init(B); + fmpq_poly_init(asinhA); + fmpq_poly_init(atanhB); + + fmpq_poly_randtest_not_zero(A, state, n_randint(state, 80) + 1, 80); + fmpq_poly_set_coeff_ui(A, 0, UWORD(0)); + + fmpq_poly_mullow(B, A, A, n); + fmpq_poly_set_coeff_ui(B, 0, UWORD(1)); + fmpq_poly_invsqrt_series(B, B, n); + fmpq_poly_mullow(B, A, B, n); + + fmpq_poly_asinh_series(asinhA, A, n); + fmpq_poly_atanh_series(atanhB, B, n); + + cflags |= fmpq_poly_is_canonical(asinhA) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(atanhB) ? 0 : 2; + result = (fmpq_poly_equal(asinhA, atanhB) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("A = "), fmpq_poly_debug(A), flint_printf("\n\n"); + flint_printf("B = "), fmpq_poly_debug(B), flint_printf("\n\n"); + flint_printf("asinh(A) = "), fmpq_poly_debug(asinhA), flint_printf("\n\n"); + flint_printf("atanh(B) = "), fmpq_poly_debug(atanhB), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(A); + fmpq_poly_clear(B); + fmpq_poly_clear(asinhA); + fmpq_poly_clear(atanhB); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-atan_series.c b/external/flint-2.4.3/fmpq_poly/test/t-atan_series.c new file mode 100644 index 0000000..b3dcbb7 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-atan_series.c @@ -0,0 +1,132 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + ulong cflags = UWORD(0); + + FLINT_TEST_INIT(state); + + flint_printf("atan_series...."); + fflush(stdout); + + /* Check aliasing of a and c */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b; + slong n = n_randint(state, 50) + 1; + + fmpq_poly_init(a); + fmpq_poly_init(b); + + fmpq_poly_randtest_not_zero(a, state, n_randint(state, 50) + 1, 50); + fmpq_poly_set_coeff_ui(a, 0, UWORD(0)); + + fmpq_poly_canonicalise(a); + + fmpq_poly_atan_series(b, a, n); + fmpq_poly_atan_series(a, a, n); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(b) ? 0 : 2; + result = (fmpq_poly_equal(a, b) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + } + + /* Check 2*atan(A) = atan(2*A/(1-A^2)) */ + for (i = 0; i < 40 * flint_test_multiplier(); i++) + { + fmpq_poly_t A, B, atanA, atanB; + slong n = n_randint(state, 80) + 1; + + fmpq_poly_init(A); + fmpq_poly_init(B); + fmpq_poly_init(atanA); + fmpq_poly_init(atanB); + + fmpq_poly_randtest_not_zero(A, state, n_randint(state, 80) + 1, 80); + fmpq_poly_set_coeff_ui(A, 0, UWORD(0)); + + fmpq_poly_randtest_not_zero(B, state, n_randint(state, 80) + 1, 80); + fmpq_poly_set_coeff_ui(B, 0, UWORD(0)); + + fmpq_poly_mullow(B, A, A, n); + fmpq_poly_neg(B, B); + fmpq_poly_set_coeff_ui(B, 0, UWORD(1)); + fmpq_poly_div_series(B, A, B, n); + fmpq_poly_add(B, B, B); + + fmpq_poly_atan_series(atanA, A, n); + fmpq_poly_atan_series(atanB, B, n); + fmpq_poly_add(atanA, atanA, atanA); + + cflags |= fmpq_poly_is_canonical(atanA) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(atanB) ? 0 : 2; + result = (fmpq_poly_equal(atanA, atanB) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("A = "), fmpq_poly_debug(A), flint_printf("\n\n"); + flint_printf("B = "), fmpq_poly_debug(B), flint_printf("\n\n"); + flint_printf("2*atan(A) = "), fmpq_poly_debug(atanA), flint_printf("\n\n"); + flint_printf("atan(B) = "), fmpq_poly_debug(atanB), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(A); + fmpq_poly_clear(B); + fmpq_poly_clear(atanA); + fmpq_poly_clear(atanB); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-atanh_series.c b/external/flint-2.4.3/fmpq_poly/test/t-atanh_series.c new file mode 100644 index 0000000..dd3c64b --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-atanh_series.c @@ -0,0 +1,131 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + ulong cflags = UWORD(0); + + FLINT_TEST_INIT(state); + + flint_printf("atanh_series...."); + fflush(stdout); + + /* Check aliasing of a and c */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b; + slong n = n_randint(state, 50) + 1; + + fmpq_poly_init(a); + fmpq_poly_init(b); + + fmpq_poly_randtest_not_zero(a, state, n_randint(state, 50) + 1, 50); + fmpq_poly_set_coeff_ui(a, 0, UWORD(0)); + + fmpq_poly_canonicalise(a); + + fmpq_poly_atanh_series(b, a, n); + fmpq_poly_atanh_series(a, a, n); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(b) ? 0 : 2; + result = (fmpq_poly_equal(a, b) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + } + + /* Check 2*atanh(A) = atanh(2*A/(1+A^2)) */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + fmpq_poly_t A, B, atanhA, atanhB; + slong n = n_randint(state, 80) + 1; + + fmpq_poly_init(A); + fmpq_poly_init(B); + fmpq_poly_init(atanhA); + fmpq_poly_init(atanhB); + + fmpq_poly_randtest_not_zero(A, state, n_randint(state, 80) + 1, 80); + fmpq_poly_set_coeff_ui(A, 0, UWORD(0)); + + fmpq_poly_randtest_not_zero(B, state, n_randint(state, 80) + 1, 80); + fmpq_poly_set_coeff_ui(B, 0, UWORD(0)); + + fmpq_poly_mullow(B, A, A, n); + fmpq_poly_set_coeff_ui(B, 0, UWORD(1)); + fmpq_poly_div_series(B, A, B, n); + fmpq_poly_add(B, B, B); + + fmpq_poly_atanh_series(atanhA, A, n); + fmpq_poly_atanh_series(atanhB, B, n); + fmpq_poly_add(atanhA, atanhA, atanhA); + + cflags |= fmpq_poly_is_canonical(atanhA) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(atanhB) ? 0 : 2; + result = (fmpq_poly_equal(atanhA, atanhB) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("A = "), fmpq_poly_debug(A), flint_printf("\n\n"); + flint_printf("B = "), fmpq_poly_debug(B), flint_printf("\n\n"); + flint_printf("2*atanh(A) = "), fmpq_poly_debug(atanhA), flint_printf("\n\n"); + flint_printf("atanh(B) = "), fmpq_poly_debug(atanhB), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(A); + fmpq_poly_clear(B); + fmpq_poly_clear(atanhA); + fmpq_poly_clear(atanhB); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-cmp.c b/external/flint-2.4.3/fmpq_poly/test/t-cmp.c new file mode 100644 index 0000000..a26cf89 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-cmp.c @@ -0,0 +1,126 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("cmp...."); + fflush(stdout); + + + + /* Check aliasing */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t f; + + fmpq_poly_init(f); + fmpq_poly_randtest(f, state, n_randint(state, 100), 200); + + result = (fmpq_poly_cmp(f, f) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(f), flint_printf("\n"); + abort(); + } + + fmpq_poly_clear(f); + } + + /* + Check transitivity, i.e. f <= g <= h implies f <= h, that is + NOT (f <= g <= h) OR f <= h + */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t f, g, h; + + fmpq_poly_init(f); + fmpq_poly_init(g); + fmpq_poly_init(h); + fmpq_poly_randtest(f, state, n_randint(state, 100), 200); + fmpq_poly_randtest(g, state, n_randint(state, 100), 200); + fmpq_poly_randtest(h, state, n_randint(state, 100), 200); + + result = !(fmpq_poly_cmp(f, g) <= 0) || !(fmpq_poly_cmp(g, h) <= 0) + || (fmpq_poly_cmp(f, h) <= 0); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(f), flint_printf("\n"); + fmpq_poly_debug(g), flint_printf("\n"); + fmpq_poly_debug(h), flint_printf("\n"); + abort(); + } + + fmpq_poly_clear(f); + fmpq_poly_clear(g); + fmpq_poly_clear(h); + } + + /* Check that <, ==, or > */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t f, g; + + fmpq_poly_init(f); + fmpq_poly_init(g); + fmpq_poly_randtest(f, state, n_randint(state, 100), 200); + fmpq_poly_randtest(g, state, n_randint(state, 100), 200); + + result = (fmpq_poly_cmp(f, g) < 0) || (fmpq_poly_equal(f, g)) + || (fmpq_poly_cmp(f, g) > 0); + + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(f), flint_printf("\n"); + fmpq_poly_debug(g), flint_printf("\n"); + flint_printf("cmp(f,g) = %d\n", fmpq_poly_cmp(f, g)); + abort(); + } + + fmpq_poly_clear(f); + fmpq_poly_clear(g); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-compose.c b/external/flint-2.4.3/fmpq_poly/test/t-compose.c new file mode 100644 index 0000000..1090c89 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-compose.c @@ -0,0 +1,161 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + ulong cflags = UWORD(0); + + FLINT_TEST_INIT(state); + + flint_printf("compose...."); + fflush(stdout); + + /* Check aliasing of the first argument */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + fmpq_poly_t f, g, h; + + fmpq_poly_init(f); + fmpq_poly_init(g); + fmpq_poly_init(h); + fmpq_poly_randtest(g, state, n_randint(state, 50), 100); + fmpq_poly_randtest(h, state, n_randint(state, 20), 50); + + fmpq_poly_compose(f, g, h); + fmpq_poly_compose(g, g, h); + + cflags |= fmpq_poly_is_canonical(f) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(g) ? 0 : 2; + result = (fmpq_poly_equal(f, g) && !cflags); + if (!result) + { + flint_printf("FAIL (aliasing 1):\n"); + fmpq_poly_debug(f), flint_printf("\n\n"); + fmpq_poly_debug(g), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(f); + fmpq_poly_clear(g); + fmpq_poly_clear(h); + } + + /* Check aliasing of the second argument */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + fmpq_poly_t f, g, h; + + fmpq_poly_init(f); + fmpq_poly_init(g); + fmpq_poly_init(h); + fmpq_poly_randtest(g, state, n_randint(state, 50), 100); + fmpq_poly_randtest(h, state, n_randint(state, 20), 50); + + fmpq_poly_compose(f, g, h); + fmpq_poly_compose(h, g, h); + + cflags |= fmpq_poly_is_canonical(f) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(h) ? 0 : 2; + result = (fmpq_poly_equal(f, h) && !cflags); + if (!result) + { + flint_printf("FAIL (aliasing 2):\n"); + fmpq_poly_debug(f), flint_printf("\n\n"); + fmpq_poly_debug(h), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(f); + fmpq_poly_clear(g); + fmpq_poly_clear(h); + } + + /* Compare with the naive method for g(h(t)) */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + fmpq_poly_t f, g, h, s, t, u; + mpq_t c; + slong k; + + fmpq_poly_init(f); + fmpq_poly_init(g); + fmpq_poly_init(h); + fmpq_poly_init(s); + fmpq_poly_init(t); + fmpq_poly_init(u); + mpq_init(c); + fmpq_poly_randtest(g, state, n_randint(state, 20), 65); + fmpq_poly_randtest(h, state, n_randint(state, 20), 65); + + fmpq_poly_zero(s); + fmpq_poly_set_ui(t, UWORD(1)); + for (k = WORD(0); k < g->length; k++) + { + fmpq_poly_get_coeff_mpq(c, g, k); + fmpq_poly_scalar_mul_mpq(u, t, c); + fmpq_poly_add(s, s, u); + fmpq_poly_mul(t, t, h); + } + + fmpq_poly_compose(f, g, h); + + result = (fmpq_poly_equal(f, s)); + if (!result) + { + flint_printf("FAIL (compare with naive):\n"); + flint_printf("g = "), fmpq_poly_debug(g), flint_printf("\n\n"); + flint_printf("h = "), fmpq_poly_debug(h), flint_printf("\n\n"); + flint_printf("f = "), fmpq_poly_debug(f), flint_printf("\n\n"); + flint_printf("s = "), fmpq_poly_debug(s), flint_printf("\n\n"); + abort(); + } + + fmpq_poly_clear(f); + fmpq_poly_clear(g); + fmpq_poly_clear(h); + fmpq_poly_clear(s); + fmpq_poly_clear(t); + fmpq_poly_clear(u); + mpq_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-compose_series.c b/external/flint-2.4.3/fmpq_poly/test/t-compose_series.c new file mode 100644 index 0000000..8a5345c --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-compose_series.c @@ -0,0 +1,152 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("compose_series...."); + fflush(stdout); + + + + /* Check aliasing of the first argument */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + fmpq_poly_t f, g, h; + slong n; + + fmpq_poly_init(f); + fmpq_poly_init(g); + fmpq_poly_init(h); + fmpq_poly_randtest(g, state, n_randint(state, 40), 80); + fmpq_poly_randtest(h, state, n_randint(state, 20), 50); + fmpq_poly_set_coeff_ui(h, 0, 0); + n = n_randint(state, 20); + + fmpq_poly_compose_series(f, g, h, n); + fmpq_poly_compose_series(g, g, h, n); + + result = (fmpq_poly_equal(f, g)); + if (!result) + { + flint_printf("FAIL (aliasing 1):\n"); + fmpq_poly_print(f), flint_printf("\n\n"); + fmpq_poly_print(g), flint_printf("\n\n"); + abort(); + } + + fmpq_poly_clear(f); + fmpq_poly_clear(g); + fmpq_poly_clear(h); + } + + /* Check aliasing of the second argument */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + fmpq_poly_t f, g, h; + slong n; + + fmpq_poly_init(f); + fmpq_poly_init(g); + fmpq_poly_init(h); + fmpq_poly_randtest(g, state, n_randint(state, 40), 80); + fmpq_poly_randtest(h, state, n_randint(state, 20), 50); + fmpq_poly_set_coeff_ui(h, 0, 0); + n = n_randint(state, 20); + + fmpq_poly_compose_series(f, g, h, n); + fmpq_poly_compose_series(h, g, h, n); + + result = (fmpq_poly_equal(f, h)); + if (!result) + { + flint_printf("FAIL (aliasing 2):\n"); + fmpq_poly_print(f), flint_printf("\n\n"); + fmpq_poly_print(h), flint_printf("\n\n"); + abort(); + } + + fmpq_poly_clear(f); + fmpq_poly_clear(g); + fmpq_poly_clear(h); + } + + /* Compare with compose */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + fmpq_poly_t f, g, h, s, t; + slong n; + + fmpq_poly_init(f); + fmpq_poly_init(g); + fmpq_poly_init(h); + fmpq_poly_init(s); + fmpq_poly_init(t); + fmpq_poly_randtest(g, state, n_randint(state, 40), 80); + fmpq_poly_randtest(h, state, n_randint(state, 20), 50); + fmpq_poly_set_coeff_ui(h, 0, 0); + n = n_randint(state, 20); + + fmpq_poly_compose(s, g, h); + fmpq_poly_truncate(s, n); + fmpq_poly_compose_series(f, g, h, n); + + result = (fmpq_poly_equal(f, s)); + if (!result) + { + flint_printf("FAIL (comparison):\n"); + flint_printf("n = %wd\n", n); + flint_printf("g = "), fmpq_poly_print(g), flint_printf("\n\n"); + flint_printf("h = "), fmpq_poly_print(h), flint_printf("\n\n"); + flint_printf("f = "), fmpq_poly_print(f), flint_printf("\n\n"); + flint_printf("s = "), fmpq_poly_print(s), flint_printf("\n\n"); + abort(); + } + + fmpq_poly_clear(f); + fmpq_poly_clear(g); + fmpq_poly_clear(h); + fmpq_poly_clear(s); + fmpq_poly_clear(t); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-compose_series_brent_kung.c b/external/flint-2.4.3/fmpq_poly/test/t-compose_series_brent_kung.c new file mode 100644 index 0000000..341f5bc --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-compose_series_brent_kung.c @@ -0,0 +1,152 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("compose_series_brent_kung...."); + fflush(stdout); + + + + /* Check aliasing of the first argument */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + fmpq_poly_t f, g, h; + slong n; + + fmpq_poly_init(f); + fmpq_poly_init(g); + fmpq_poly_init(h); + fmpq_poly_randtest(g, state, n_randint(state, 40), 80); + fmpq_poly_randtest(h, state, n_randint(state, 20), 50); + fmpq_poly_set_coeff_ui(h, 0, 0); + n = n_randint(state, 20); + + fmpq_poly_compose_series_brent_kung(f, g, h, n); + fmpq_poly_compose_series_brent_kung(g, g, h, n); + + result = (fmpq_poly_equal(f, g)); + if (!result) + { + flint_printf("FAIL (aliasing 1):\n"); + fmpq_poly_print(f), flint_printf("\n\n"); + fmpq_poly_print(g), flint_printf("\n\n"); + abort(); + } + + fmpq_poly_clear(f); + fmpq_poly_clear(g); + fmpq_poly_clear(h); + } + + /* Check aliasing of the second argument */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + fmpq_poly_t f, g, h; + slong n; + + fmpq_poly_init(f); + fmpq_poly_init(g); + fmpq_poly_init(h); + fmpq_poly_randtest(g, state, n_randint(state, 40), 80); + fmpq_poly_randtest(h, state, n_randint(state, 20), 50); + fmpq_poly_set_coeff_ui(h, 0, 0); + n = n_randint(state, 20); + + fmpq_poly_compose_series_brent_kung(f, g, h, n); + fmpq_poly_compose_series_brent_kung(h, g, h, n); + + result = (fmpq_poly_equal(f, h)); + if (!result) + { + flint_printf("FAIL (aliasing 2):\n"); + fmpq_poly_print(f), flint_printf("\n\n"); + fmpq_poly_print(h), flint_printf("\n\n"); + abort(); + } + + fmpq_poly_clear(f); + fmpq_poly_clear(g); + fmpq_poly_clear(h); + } + + /* Compare with compose */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + fmpq_poly_t f, g, h, s, t; + slong n; + + fmpq_poly_init(f); + fmpq_poly_init(g); + fmpq_poly_init(h); + fmpq_poly_init(s); + fmpq_poly_init(t); + fmpq_poly_randtest(g, state, n_randint(state, 40), 80); + fmpq_poly_randtest(h, state, n_randint(state, 20), 50); + fmpq_poly_set_coeff_ui(h, 0, 0); + n = n_randint(state, 20); + + fmpq_poly_compose(s, g, h); + fmpq_poly_truncate(s, n); + fmpq_poly_compose_series_brent_kung(f, g, h, n); + + result = (fmpq_poly_equal(f, s)); + if (!result) + { + flint_printf("FAIL (comparison):\n"); + flint_printf("n = %wd\n", n); + flint_printf("g = "), fmpq_poly_print(g), flint_printf("\n\n"); + flint_printf("h = "), fmpq_poly_print(h), flint_printf("\n\n"); + flint_printf("f = "), fmpq_poly_print(f), flint_printf("\n\n"); + flint_printf("s = "), fmpq_poly_print(s), flint_printf("\n\n"); + abort(); + } + + fmpq_poly_clear(f); + fmpq_poly_clear(g); + fmpq_poly_clear(h); + fmpq_poly_clear(s); + fmpq_poly_clear(t); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-compose_series_horner.c b/external/flint-2.4.3/fmpq_poly/test/t-compose_series_horner.c new file mode 100644 index 0000000..4e53549 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-compose_series_horner.c @@ -0,0 +1,152 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("compose_series_horner...."); + fflush(stdout); + + + + /* Check aliasing of the first argument */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + fmpq_poly_t f, g, h; + slong n; + + fmpq_poly_init(f); + fmpq_poly_init(g); + fmpq_poly_init(h); + fmpq_poly_randtest(g, state, n_randint(state, 40), 80); + fmpq_poly_randtest(h, state, n_randint(state, 20), 50); + fmpq_poly_set_coeff_ui(h, 0, 0); + n = n_randint(state, 20); + + fmpq_poly_compose_series_horner(f, g, h, n); + fmpq_poly_compose_series_horner(g, g, h, n); + + result = (fmpq_poly_equal(f, g)); + if (!result) + { + flint_printf("FAIL (aliasing 1):\n"); + fmpq_poly_print(f), flint_printf("\n\n"); + fmpq_poly_print(g), flint_printf("\n\n"); + abort(); + } + + fmpq_poly_clear(f); + fmpq_poly_clear(g); + fmpq_poly_clear(h); + } + + /* Check aliasing of the second argument */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + fmpq_poly_t f, g, h; + slong n; + + fmpq_poly_init(f); + fmpq_poly_init(g); + fmpq_poly_init(h); + fmpq_poly_randtest(g, state, n_randint(state, 40), 80); + fmpq_poly_randtest(h, state, n_randint(state, 20), 50); + fmpq_poly_set_coeff_ui(h, 0, 0); + n = n_randint(state, 20); + + fmpq_poly_compose_series_horner(f, g, h, n); + fmpq_poly_compose_series_horner(h, g, h, n); + + result = (fmpq_poly_equal(f, h)); + if (!result) + { + flint_printf("FAIL (aliasing 2):\n"); + fmpq_poly_print(f), flint_printf("\n\n"); + fmpq_poly_print(h), flint_printf("\n\n"); + abort(); + } + + fmpq_poly_clear(f); + fmpq_poly_clear(g); + fmpq_poly_clear(h); + } + + /* Compare with compose */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + fmpq_poly_t f, g, h, s, t; + slong n; + + fmpq_poly_init(f); + fmpq_poly_init(g); + fmpq_poly_init(h); + fmpq_poly_init(s); + fmpq_poly_init(t); + fmpq_poly_randtest(g, state, n_randint(state, 40), 80); + fmpq_poly_randtest(h, state, n_randint(state, 20), 50); + fmpq_poly_set_coeff_ui(h, 0, 0); + n = n_randint(state, 20); + + fmpq_poly_compose(s, g, h); + fmpq_poly_truncate(s, n); + fmpq_poly_compose_series_horner(f, g, h, n); + + result = (fmpq_poly_equal(f, s)); + if (!result) + { + flint_printf("FAIL (comparison):\n"); + flint_printf("n = %wd\n", n); + flint_printf("g = "), fmpq_poly_print(g), flint_printf("\n\n"); + flint_printf("h = "), fmpq_poly_print(h), flint_printf("\n\n"); + flint_printf("f = "), fmpq_poly_print(f), flint_printf("\n\n"); + flint_printf("s = "), fmpq_poly_print(s), flint_printf("\n\n"); + abort(); + } + + fmpq_poly_clear(f); + fmpq_poly_clear(g); + fmpq_poly_clear(h); + fmpq_poly_clear(s); + fmpq_poly_clear(t); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-content.c b/external/flint-2.4.3/fmpq_poly/test/t-content.c new file mode 100644 index 0000000..542dcd9 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-content.c @@ -0,0 +1,91 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("content...."); + fflush(stdout); + + + + /* Check that content(a f) = abs(a) content(f) */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t f, g; + fmpq_t a, b, c; + + fmpq_poly_init(f); + fmpq_poly_init(g); + + fmpq_init(a); + fmpq_init(b); + fmpq_init(c); + + fmpq_poly_randtest_not_zero(f, state, n_randint(state, 100) + 1, 100); + fmpq_randtest_not_zero(a, state, 100); + + fmpq_poly_scalar_mul_fmpq(g, f, a); + fmpq_poly_content(b, g); + fmpq_poly_content(c, f); + fmpq_mul(c, a, c); + fmpq_abs(c, c); + + result = (fmpq_equal(b, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_print(f), flint_printf("\n\n"); + fmpq_poly_print(g), flint_printf("\n\n"); + fmpq_print(a), flint_printf("\n\n"); + fmpq_print(b), flint_printf("\n\n"); + fmpq_print(c), flint_printf("\n\n"); + abort(); + } + + fmpq_poly_clear(f); + fmpq_poly_clear(g); + fmpq_clear(a); + fmpq_clear(b); + fmpq_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-cos_series.c b/external/flint-2.4.3/fmpq_poly/test/t-cos_series.c new file mode 100644 index 0000000..fa1786d --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-cos_series.c @@ -0,0 +1,129 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + ulong cflags = UWORD(0); + + FLINT_TEST_INIT(state); + + flint_printf("cos_series...."); + fflush(stdout); + + /* Check aliasing of a and c */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b; + slong n = n_randint(state, 50) + 1; + + fmpq_poly_init(a); + fmpq_poly_init(b); + + fmpq_poly_randtest_not_zero(a, state, n_randint(state, 50) + 1, 50); + fmpq_poly_set_coeff_ui(a, 0, UWORD(0)); + + fmpq_poly_canonicalise(a); + + fmpq_poly_cos_series(b, a, n); + fmpq_poly_cos_series(a, a, n); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(b) ? 0 : 2; + result = (fmpq_poly_equal(a, b) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + } + + /* Check 1-cos(A)^2 = sin(A)^2 */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + fmpq_poly_t A, cosA, sinA, B, C, one; + slong n = n_randint(state, 80) + 1; + + fmpq_poly_init(A); + fmpq_poly_init(cosA); + fmpq_poly_init(sinA); + fmpq_poly_init(B); + fmpq_poly_init(C); + fmpq_poly_init(one); + + fmpq_poly_randtest_not_zero(A, state, n_randint(state, 60) + 1, 80); + fmpq_poly_set_coeff_ui(A, 0, UWORD(0)); + + fmpq_poly_cos_series(cosA, A, n); + fmpq_poly_sin_series(sinA, A, n); + fmpq_poly_mullow(B, cosA, cosA, n); + fmpq_poly_set_coeff_ui(one, 0, UWORD(1)); + fmpq_poly_sub(B, one, B); + fmpq_poly_mullow(C, sinA, sinA, n); + + cflags |= fmpq_poly_is_canonical(cosA) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(sinA) ? 0 : 2; + result = (fmpq_poly_equal(B, C) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("A = "), fmpq_poly_debug(A), flint_printf("\n\n"); + flint_printf("cos(A) = "), fmpq_poly_debug(cosA), flint_printf("\n\n"); + flint_printf("sin(A) = "), fmpq_poly_debug(sinA), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(A); + fmpq_poly_clear(cosA); + fmpq_poly_clear(sinA); + fmpq_poly_clear(B); + fmpq_poly_clear(C); + fmpq_poly_clear(one); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-cosh_series.c b/external/flint-2.4.3/fmpq_poly/test/t-cosh_series.c new file mode 100644 index 0000000..1217172 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-cosh_series.c @@ -0,0 +1,129 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + ulong cflags = UWORD(0); + + FLINT_TEST_INIT(state); + + flint_printf("cosh_series...."); + fflush(stdout); + + /* Check aliasing of a and c */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b; + slong n = n_randint(state, 50) + 1; + + fmpq_poly_init(a); + fmpq_poly_init(b); + + fmpq_poly_randtest_not_zero(a, state, n_randint(state, 50) + 1, 50); + fmpq_poly_set_coeff_ui(a, 0, UWORD(0)); + + fmpq_poly_canonicalise(a); + + fmpq_poly_cosh_series(b, a, n); + fmpq_poly_cosh_series(a, a, n); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(b) ? 0 : 2; + result = (fmpq_poly_equal(a, b) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + } + + /* Check cosh(A)^2-1 = sinh(A)^2 */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + fmpq_poly_t A, coshA, sinhA, B, C, one; + slong n = n_randint(state, 80) + 1; + + fmpq_poly_init(A); + fmpq_poly_init(coshA); + fmpq_poly_init(sinhA); + fmpq_poly_init(B); + fmpq_poly_init(C); + fmpq_poly_init(one); + + fmpq_poly_randtest_not_zero(A, state, n_randint(state, 60) + 1, 80); + fmpq_poly_set_coeff_ui(A, 0, UWORD(0)); + + fmpq_poly_cosh_series(coshA, A, n); + fmpq_poly_sinh_series(sinhA, A, n); + fmpq_poly_mullow(B, coshA, coshA, n); + fmpq_poly_set_coeff_ui(one, 0, UWORD(1)); + fmpq_poly_sub(B, B, one); + fmpq_poly_mullow(C, sinhA, sinhA, n); + + cflags |= fmpq_poly_is_canonical(coshA) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(sinhA) ? 0 : 2; + result = (fmpq_poly_equal(B, C) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("A = "), fmpq_poly_debug(A), flint_printf("\n\n"); + flint_printf("cosh(A) = "), fmpq_poly_debug(coshA), flint_printf("\n\n"); + flint_printf("sinh(A) = "), fmpq_poly_debug(sinhA), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(A); + fmpq_poly_clear(coshA); + fmpq_poly_clear(sinhA); + fmpq_poly_clear(B); + fmpq_poly_clear(C); + fmpq_poly_clear(one); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-derivative.c b/external/flint-2.4.3/fmpq_poly/test/t-derivative.c new file mode 100644 index 0000000..6d95d37 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-derivative.c @@ -0,0 +1,146 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + ulong cflags = UWORD(0); + + FLINT_TEST_INIT(state); + + flint_printf("derivative...."); + fflush(stdout); + + /* Check aliasing */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_randtest(a, state, n_randint(state, 100), 200); + + fmpq_poly_derivative(b, a); + fmpq_poly_derivative(a, a); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(b) ? 0 : 2; + result = (fmpq_poly_equal(a, b) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + } + + /* Check constants have derivative zero */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_randtest(a, state, n_randint(state, 2), 200); + + fmpq_poly_derivative(b, a); + + cflags |= fmpq_poly_is_canonical(b) ? 0 : 1; + result = fmpq_poly_is_zero(b) && !cflags; + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + } + + /* Check (f g)' = f' g + f g' */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, c, d, lhs, rhs; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(c); + fmpq_poly_init(d); + fmpq_poly_init(lhs); + fmpq_poly_init(rhs); + fmpq_poly_randtest(a, state, n_randint(state, 100), 200); + fmpq_poly_randtest(b, state, n_randint(state, 100), 200); + + fmpq_poly_mul(lhs, a, b); + fmpq_poly_derivative(lhs, lhs); + fmpq_poly_derivative(c, a); + fmpq_poly_derivative(d, b); + fmpq_poly_mul(c, c, b); + fmpq_poly_mul(d, a, d); + fmpq_poly_add(rhs, c, d); + + cflags |= fmpq_poly_is_canonical(lhs) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(rhs) ? 0 : 2; + result = fmpq_poly_equal(lhs, rhs) && !cflags; + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(c); + fmpq_poly_clear(d); + fmpq_poly_clear(lhs); + fmpq_poly_clear(rhs); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-div.c b/external/flint-2.4.3/fmpq_poly/test/t-div.c new file mode 100644 index 0000000..03c7ff5 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-div.c @@ -0,0 +1,152 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + ulong cflags = UWORD(0); + + FLINT_TEST_INIT(state); + + flint_printf("div...."); + fflush(stdout); + + /* Check aliasing of q and a */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, q; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(q); + fmpq_poly_randtest(a, state, n_randint(state, 50), 200); + fmpq_poly_randtest_not_zero(b, state, n_randint(state, 50) + 1, 200); + + fmpq_poly_div(q, a, b); + fmpq_poly_div(a, a, b); + + cflags |= fmpq_poly_is_canonical(q) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(a) ? 0 : 2; + result = (fmpq_poly_equal(q, a) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("q = "), fmpq_poly_debug(q), flint_printf("\n\n"); + flint_printf("a = "), fmpq_poly_debug(a), flint_printf("\n\n"); + flint_printf("b = "), fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(q); + } + + /* Check aliasing of q and b */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, q; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(q); + fmpq_poly_randtest(a, state, n_randint(state, 50), 200); + fmpq_poly_randtest_not_zero(b, state, n_randint(state, 50) + 1, 200); + + fmpq_poly_div(q, a, b); + fmpq_poly_div(b, a, b); + + cflags |= fmpq_poly_is_canonical(q) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(b) ? 0 : 2; + result = (fmpq_poly_equal(q, b) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("q = "), fmpq_poly_debug(q), flint_printf("\n\n"); + flint_printf("a = "), fmpq_poly_debug(a), flint_printf("\n\n"); + flint_printf("b = "), fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(q); + } + + /* Compare with divrem */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, q, q2, r; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(q); + fmpq_poly_init(q2); + fmpq_poly_init(r); + fmpq_poly_randtest(a, state, n_randint(state, 50), 200); + fmpq_poly_randtest_not_zero(b, state, n_randint(state, 50) + 1, 200); + + fmpq_poly_divrem(q, r, a, b); + fmpq_poly_div(q2, a, b); + + cflags |= fmpq_poly_is_canonical(q) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(q2) ? 0 : 2; + result = (fmpq_poly_equal(q, q2) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpq_poly_debug(a), flint_printf("\n\n"); + flint_printf("b = "), fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("q = "), fmpq_poly_debug(q), flint_printf("\n\n"); + flint_printf("r = "), fmpq_poly_debug(r), flint_printf("\n\n"); + flint_printf("q2 = "), fmpq_poly_debug(q2), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(q); + fmpq_poly_clear(q2); + fmpq_poly_clear(r); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-div_series.c b/external/flint-2.4.3/fmpq_poly/test/t-div_series.c new file mode 100644 index 0000000..748b8db --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-div_series.c @@ -0,0 +1,161 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + ulong cflags = UWORD(0); + + FLINT_TEST_INIT(state); + + flint_printf("div_series...."); + fflush(stdout); + + /* Check aliasing q and a */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, q; + slong n = n_randint(state, 50) + 1; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(q); + + fmpq_poly_randtest(a, state, n_randint(state, 50) + 1, 80); + fmpq_poly_randtest_not_zero(b, state, n_randint(state, 50) + 1, 80); + fmpq_poly_set_coeff_ui(b, 0, 1); + + fmpq_poly_div_series(q, a, b, n); + fmpq_poly_div_series(a, a, b, n); + + cflags |= fmpq_poly_is_canonical(q) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(a) ? 0 : 2; + result = (fmpq_poly_equal(q, a)) && !cflags; + if (!result) + { + flint_printf("FAIL (alias q and a):\n"); + flint_printf("a = "), fmpq_poly_debug(a), flint_printf("\n\n"); + flint_printf("b = "), fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("q = "), fmpq_poly_debug(q), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(q); + } + + /* Check aliasing q and b */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, q; + slong n = n_randint(state, 50) + 1; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(q); + + fmpq_poly_randtest(a, state, n_randint(state, 50) + 1, 80); + fmpq_poly_randtest_not_zero(b, state, n_randint(state, 50) + 1, 80); + fmpq_poly_set_coeff_ui(b, 0, 1); + + fmpq_poly_div_series(q, a, b, n); + fmpq_poly_div_series(b, a, b, n); + + cflags |= fmpq_poly_is_canonical(q) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(b) ? 0 : 2; + result = (fmpq_poly_equal(q, b)) && !cflags; + if (!result) + { + flint_printf("FAIL (alias q and b):\n"); + flint_printf("a = "), fmpq_poly_debug(a), flint_printf("\n\n"); + flint_printf("b = "), fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("q = "), fmpq_poly_debug(q), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(q); + } + + /* Check that Q * B == A */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, p, q; + slong n = n_randint(state, 50) + 1; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(p); + fmpq_poly_init(q); + + fmpq_poly_randtest(a, state, n_randint(state, 50) + 1, 80); + fmpq_poly_randtest_not_zero(b, state, n_randint(state, 50) + 1, 80); + fmpq_poly_set_coeff_ui(b, 0, 1); + + fmpq_poly_div_series(q, a, b, n); + fmpq_poly_mullow(p, q, b, n); + + fmpq_poly_truncate(a, n); + + cflags |= fmpq_poly_is_canonical(q) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(p) ? 0 : 2; + cflags |= fmpq_poly_is_canonical(a) ? 0 : 4; + result = (fmpq_poly_equal(p, a)) && !cflags; + if (!result) + { + flint_printf("FAIL (check Q * B = A):\n"); + flint_printf("a = "), fmpq_poly_debug(a), flint_printf("\n\n"); + flint_printf("b = "), fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("p = "), fmpq_poly_debug(p), flint_printf("\n\n"); + flint_printf("q = "), fmpq_poly_debug(q), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(p); + fmpq_poly_clear(q); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-divrem.c b/external/flint-2.4.3/fmpq_poly/test/t-divrem.c new file mode 100644 index 0000000..4f2190d --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-divrem.c @@ -0,0 +1,169 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + ulong cflags = UWORD(0); + + FLINT_TEST_INIT(state); + + flint_printf("divrem...."); + fflush(stdout); + + /* Check aliasing of {q,r} and {a,b} */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpq_poly_t A, B; + fmpq_poly_t a, b, q, r; + + fmpq_poly_init(A); + fmpq_poly_init(B); + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(q); + fmpq_poly_init(r); + + fmpq_poly_randtest(A, state, n_randint(state, 50), 200); + fmpq_poly_randtest_not_zero(B, state, n_randint(state, 50) + 1, 200); + fmpq_poly_set(a, A); + fmpq_poly_set(b, B); + + fmpq_poly_divrem(q, r, a, b); + fmpq_poly_divrem(a, b, a, b); + + cflags |= fmpq_poly_is_canonical(q) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(a) ? 0 : 2; + result = (fmpq_poly_equal(q, a)) && (fmpq_poly_equal(r, b)) && !cflags; + if (!result) + { + flint_printf("FAIL (aliasing {q,r} and {a,b}):\n\n"); + flint_printf("A = "), fmpq_poly_debug(A), flint_printf("\n\n"); + flint_printf("B = "), fmpq_poly_debug(B), flint_printf("\n\n"); + flint_printf("q = "), fmpq_poly_debug(q), flint_printf("\n\n"); + flint_printf("r = "), fmpq_poly_debug(r), flint_printf("\n\n"); + flint_printf("a = "), fmpq_poly_debug(a), flint_printf("\n\n"); + flint_printf("b = "), fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(A); + fmpq_poly_clear(B); + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(q); + fmpq_poly_clear(r); + } + + /* Check aliasing of {q,r} and {b,a} */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, q, r; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(q); + fmpq_poly_init(r); + fmpq_poly_randtest(a, state, n_randint(state, 50), 200); + fmpq_poly_randtest_not_zero(b, state, n_randint(state, 50) + 1, 200); + + fmpq_poly_divrem(q, r, a, b); + fmpq_poly_divrem(b, a, a, b); + + cflags |= fmpq_poly_is_canonical(q) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(b) ? 0 : 2; + result = (fmpq_poly_equal(q, b)) && (fmpq_poly_equal(r, a)) && !cflags; + if (!result) + { + flint_printf("FAIL (aliasing of {q,r} and {b,a}):\n\n"); + flint_printf("q = "), fmpq_poly_debug(q), flint_printf("\n\n"); + flint_printf("r = "), fmpq_poly_debug(r), flint_printf("\n\n"); + flint_printf("a = "), fmpq_poly_debug(a), flint_printf("\n\n"); + flint_printf("b = "), fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(q); + fmpq_poly_clear(r); + } + + /* check a = q b + r */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, q, r, rhs; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(q); + fmpq_poly_init(r); + fmpq_poly_init(rhs); + fmpq_poly_randtest(a, state, n_randint(state, 50), 200); + fmpq_poly_randtest_not_zero(b, state, n_randint(state, 50) + 1, 200); + + fmpq_poly_divrem(q, r, a, b); + fmpq_poly_mul(rhs, q, b); + fmpq_poly_add(rhs, rhs, r); + + cflags |= fmpq_poly_is_canonical(q) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(rhs) ? 0 : 2; + result = fmpq_poly_equal(a, rhs) && !cflags; + if (!result) + { + flint_printf("FAIL (a == q b + r):\n\n"); + flint_printf("a = "), fmpq_poly_debug(a), flint_printf("\n\n"); + flint_printf("b = "), fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("q = "), fmpq_poly_debug(q), flint_printf("\n\n"); + flint_printf("r = "), fmpq_poly_debug(r), flint_printf("\n\n"); + flint_printf("q b + r = "), fmpq_poly_debug(rhs), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(q); + fmpq_poly_clear(r); + fmpq_poly_clear(rhs); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-evaluate_fmpq.c b/external/flint-2.4.3/fmpq_poly/test/t-evaluate_fmpq.c new file mode 100644 index 0000000..75ea5f1 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-evaluate_fmpq.c @@ -0,0 +1,181 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("evaluate_fmpq...."); + fflush(stdout); + + + + /* Check aliasing */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + fmpq_t x, y; + fmpq_poly_t f; + + fmpz_init(a); + fmpz_init(b); + fmpq_init(x); + fmpq_init(y); + fmpq_poly_init(f); + fmpq_poly_randtest(f, state, n_randint(state, 80), 100); + fmpz_randtest(a, state, 80); + fmpz_randtest_not_zero(b, state, 80); + fmpz_set(fmpq_numref(x), a); + fmpz_set(fmpq_denref(x), a); + fmpq_canonicalise(x); + + fmpq_poly_evaluate_fmpq(y, f, x); + fmpq_poly_evaluate_fmpq(x, f, x); + + result = (fmpq_equal(x, y)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_print(a), flint_printf("\n\n"); + fmpz_print(b), flint_printf("\n\n"); + fmpq_poly_debug(f), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpq_clear(x); + fmpq_clear(y); + fmpq_poly_clear(f); + } + + /* Check that (f+g)(a) = f(a) + g(a) */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + fmpq_t x, y, z; + fmpq_poly_t f, g; + + fmpz_init(a); + fmpz_init(b); + fmpq_init(x); + fmpq_init(y); + fmpq_init(z); + fmpq_poly_init(f); + fmpq_poly_init(g); + fmpq_poly_randtest(f, state, n_randint(state, 80), 100); + fmpq_poly_randtest(g, state, n_randint(state, 80), 100); + fmpz_randtest(a, state, 80); + fmpz_randtest_not_zero(b, state, 80); + fmpz_set(fmpq_numref(x), a); + fmpz_set(fmpq_denref(x), a); + fmpq_canonicalise(x); + + fmpq_poly_evaluate_fmpq(y, f, x); + fmpq_poly_evaluate_fmpq(z, g, x); + fmpq_add(y, y, z); + fmpq_poly_add(f, f, g); + fmpq_poly_evaluate_fmpq(z, f, x); + + result = (fmpq_equal(y, z)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_print(a), flint_printf("\n\n"); + fmpz_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpq_clear(x); + fmpq_clear(y); + fmpq_clear(z); + fmpq_poly_clear(f); + fmpq_poly_clear(g); + } + + /* Check that (f*g)(a) = f(a) * g(a) */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + fmpq_t x, y, z; + fmpq_poly_t f, g; + + fmpz_init(a); + fmpz_init(b); + fmpq_init(x); + fmpq_init(y); + fmpq_init(z); + fmpq_poly_init(f); + fmpq_poly_init(g); + fmpq_poly_randtest(f, state, n_randint(state, 50), 80); + fmpq_poly_randtest(g, state, n_randint(state, 50), 80); + fmpz_randtest(a, state, 80); + fmpz_randtest_not_zero(b, state, 80); + fmpz_set(fmpq_numref(x), a); + fmpz_set(fmpq_denref(x), a); + fmpq_canonicalise(x); + + fmpq_poly_evaluate_fmpq(y, f, x); + fmpq_poly_evaluate_fmpq(z, g, x); + fmpq_mul(y, y, z); + fmpq_poly_mul(f, f, g); + fmpq_poly_evaluate_fmpq(z, f, x); + + result = (fmpq_equal(y, z)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_print(a), flint_printf("\n\n"); + fmpz_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpq_clear(x); + fmpq_clear(y); + fmpq_clear(z); + fmpq_poly_clear(f); + fmpq_poly_clear(g); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-evaluate_fmpz.c b/external/flint-2.4.3/fmpq_poly/test/t-evaluate_fmpz.c new file mode 100644 index 0000000..adc454b --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-evaluate_fmpz.c @@ -0,0 +1,130 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("evaluate_fmpz...."); + fflush(stdout); + + + + /* Check that (f+g)(a) = f(a) + g(a) */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_t a; + fmpq_poly_t f, g, h; + fmpq_t x, y; + + fmpq_init(x); + fmpq_init(y); + fmpz_init(a); + fmpq_poly_init(f); + fmpq_poly_init(g); + fmpq_poly_init(h); + fmpq_poly_randtest(f, state, n_randint(state, 100), 200); + fmpq_poly_randtest(g, state, n_randint(state, 100), 200); + fmpz_randtest(a, state, n_randint(state, 100)); + + fmpq_poly_evaluate_fmpz(x, f, a); + fmpq_poly_evaluate_fmpz(y, g, a); + fmpq_add(x, x, y); + fmpq_poly_add(h, f, g); + fmpq_poly_evaluate_fmpz(y, h, a); + + result = (fmpq_equal(x, y)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("f = "), fmpq_poly_debug(f), flint_printf("\n"); + flint_printf("g = "), fmpq_poly_debug(g), flint_printf("\n"); + flint_printf("a = "), fmpz_print(a), flint_printf("\n"); + flint_printf("f(a) + g(a) = "), fmpq_print(x), flint_printf("\n\n"); + flint_printf("(f + g)(a) = "), fmpq_print(y), flint_printf("\n\n"); + abort(); + } + + fmpq_clear(x); + fmpq_clear(y); + fmpz_clear(a); + fmpq_poly_clear(f); + fmpq_poly_clear(g); + fmpq_poly_clear(h); + } + + /* Check that (f*g)(a) = f(a) * g(a) */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_t a; + fmpq_poly_t f, g; + fmpq_t x, y; + + fmpq_init(x); + fmpq_init(y); + fmpz_init(a); + fmpq_poly_init(f); + fmpq_poly_init(g); + fmpq_poly_randtest(f, state, n_randint(state, 100), 200); + fmpq_poly_randtest(g, state, n_randint(state, 100), 200); + fmpz_randtest(a, state, n_randint(state, 100)); + + fmpq_poly_evaluate_fmpz(x, f, a); + fmpq_poly_evaluate_fmpz(y, g, a); + fmpq_mul(x, x, y); + fmpq_poly_mul(f, f, g); + fmpq_poly_evaluate_fmpz(y, f, a); + + result = (fmpq_equal(x, y)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_print(a), flint_printf("\n\n"); + abort(); + } + + fmpq_clear(x); + fmpq_clear(y); + fmpz_clear(a); + fmpq_poly_clear(f); + fmpq_poly_clear(g); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-evaluate_mpq.c b/external/flint-2.4.3/fmpq_poly/test/t-evaluate_mpq.c new file mode 100644 index 0000000..5ec44be --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-evaluate_mpq.c @@ -0,0 +1,181 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("evaluate_mpq...."); + fflush(stdout); + + + + /* Check aliasing */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpq_t x, y; + fmpq_poly_t f; + + fmpz_init(a); + fmpz_init(b); + mpq_init(x); + mpq_init(y); + fmpq_poly_init(f); + fmpq_poly_randtest(f, state, n_randint(state, 80), 100); + fmpz_randtest(a, state, 80); + fmpz_randtest_not_zero(b, state, 80); + fmpz_get_mpz(mpq_numref(x), a); + fmpz_get_mpz(mpq_denref(x), b); + mpq_canonicalize(x); + + fmpq_poly_evaluate_mpq(y, f, x); + fmpq_poly_evaluate_mpq(x, f, x); + + result = (mpq_equal(x, y)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_print(a), flint_printf("\n\n"); + fmpz_print(b), flint_printf("\n\n"); + fmpq_poly_debug(f), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + mpq_clear(x); + mpq_clear(y); + fmpq_poly_clear(f); + } + + /* Check that (f+g)(a) = f(a) + g(a) */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpq_t x, y, z; + fmpq_poly_t f, g; + + fmpz_init(a); + fmpz_init(b); + mpq_init(x); + mpq_init(y); + mpq_init(z); + fmpq_poly_init(f); + fmpq_poly_init(g); + fmpq_poly_randtest(f, state, n_randint(state, 80), 100); + fmpq_poly_randtest(g, state, n_randint(state, 80), 100); + fmpz_randtest(a, state, 80); + fmpz_randtest_not_zero(b, state, 80); + fmpz_get_mpz(mpq_numref(x), a); + fmpz_get_mpz(mpq_denref(x), b); + mpq_canonicalize(x); + + fmpq_poly_evaluate_mpq(y, f, x); + fmpq_poly_evaluate_mpq(z, g, x); + mpq_add(y, y, z); + fmpq_poly_add(f, f, g); + fmpq_poly_evaluate_mpq(z, f, x); + + result = (mpq_equal(y, z)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_print(a), flint_printf("\n\n"); + fmpz_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + mpq_clear(x); + mpq_clear(y); + mpq_clear(z); + fmpq_poly_clear(f); + fmpq_poly_clear(g); + } + + /* Check that (f*g)(a) = f(a) * g(a) */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpq_t x, y, z; + fmpq_poly_t f, g; + + fmpz_init(a); + fmpz_init(b); + mpq_init(x); + mpq_init(y); + mpq_init(z); + fmpq_poly_init(f); + fmpq_poly_init(g); + fmpq_poly_randtest(f, state, n_randint(state, 50), 80); + fmpq_poly_randtest(g, state, n_randint(state, 50), 80); + fmpz_randtest(a, state, 80); + fmpz_randtest_not_zero(b, state, 80); + fmpz_get_mpz(mpq_numref(x), a); + fmpz_get_mpz(mpq_denref(x), b); + mpq_canonicalize(x); + + fmpq_poly_evaluate_mpq(y, f, x); + fmpq_poly_evaluate_mpq(z, g, x); + mpq_mul(y, y, z); + fmpq_poly_mul(f, f, g); + fmpq_poly_evaluate_mpq(z, f, x); + + result = (mpq_equal(y, z)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_print(a), flint_printf("\n\n"); + fmpz_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + mpq_clear(x); + mpq_clear(y); + mpq_clear(z); + fmpq_poly_clear(f); + fmpq_poly_clear(g); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-evaluate_mpz.c b/external/flint-2.4.3/fmpq_poly/test/t-evaluate_mpz.c new file mode 100644 index 0000000..0aed441 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-evaluate_mpz.c @@ -0,0 +1,142 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("evaluate_mpz...."); + fflush(stdout); + + + + /* Check that (f+g)(a) = f(a) + g(a) */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_t a; + fmpq_t x; + mpz_t b; + mpq_t y, z; + fmpq_poly_t f, g; + + fmpz_init(a); + fmpq_init(x); + mpz_init(b); + mpq_init(y); + mpq_init(z); + fmpq_poly_init(f); + fmpq_poly_init(g); + fmpq_poly_randtest(f, state, n_randint(state, 80), 100); + fmpq_poly_randtest(g, state, n_randint(state, 80), 100); + fmpz_randtest(a, state, 80); + fmpz_get_mpz(b, a); + + fmpq_poly_evaluate_mpz(y, f, b); + fmpq_poly_evaluate_mpz(z, g, b); + mpq_add(y, y, z); + fmpq_poly_add(f, f, g); + fmpq_poly_evaluate_mpz(z, f, b); + + result = (mpq_equal(y, z)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_print(a), flint_printf("\n\n"); + gmp_printf("y = %Qd\n\n", y); + gmp_printf("z = %Qd\n\n", z); + abort(); + } + + fmpz_clear(a); + fmpq_clear(x); + mpz_clear(b); + mpq_clear(y); + mpq_clear(z); + fmpq_poly_clear(f); + fmpq_poly_clear(g); + } + + /* Check that (f*g)(a) = f(a) * g(a) */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_t a; + fmpq_t x; + mpz_t b; + mpq_t y, z; + fmpq_poly_t f, g; + + fmpz_init(a); + fmpq_init(x); + mpz_init(b); + mpq_init(y); + mpq_init(z); + fmpq_poly_init(f); + fmpq_poly_init(g); + fmpq_poly_randtest(f, state, n_randint(state, 50), 80); + fmpq_poly_randtest(g, state, n_randint(state, 50), 80); + fmpz_randtest(a, state, 80); + fmpz_get_mpz(b, a); + + fmpq_poly_evaluate_mpz(y, f, b); + fmpq_poly_evaluate_mpz(z, g, b); + mpq_mul(y, y, z); + fmpq_poly_mul(f, f, g); + fmpq_poly_evaluate_mpz(z, f, b); + + result = (mpq_equal(y, z)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_print(a), flint_printf("\n\n"); + gmp_printf("y = %Qd\n\n", y); + gmp_printf("z = %Qd\n\n", z); + abort(); + } + + fmpz_clear(a); + fmpq_clear(x); + mpz_clear(b); + mpq_clear(y); + mpq_clear(z); + fmpq_poly_clear(f); + fmpq_poly_clear(g); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-exp_series.c b/external/flint-2.4.3/fmpq_poly/test/t-exp_series.c new file mode 100644 index 0000000..cc73ee2 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-exp_series.c @@ -0,0 +1,137 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + ulong cflags = UWORD(0); + + FLINT_TEST_INIT(state); + + flint_printf("exp_series...."); + fflush(stdout); + + /* Check aliasing of a and c */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b; + slong n = n_randint(state, 50) + 1; + + fmpq_poly_init(a); + fmpq_poly_init(b); + + fmpq_poly_randtest_not_zero(a, state, n_randint(state, 50) + 1, 50); + fmpq_poly_set_coeff_ui(a, 0, UWORD(0)); + + fmpq_poly_canonicalise(a); + + fmpq_poly_exp_series(b, a, n); + fmpq_poly_exp_series(a, a, n); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(b) ? 0 : 2; + result = (fmpq_poly_equal(a, b) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + } + + /* Check exp(a+b) = exp(a) * exp(b) */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, ab, expa, expb, expab, expa_expb; + slong n = n_randint(state, 80) + 1; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(ab); + fmpq_poly_init(expa); + fmpq_poly_init(expb); + fmpq_poly_init(expab); + fmpq_poly_init(expa_expb); + + fmpq_poly_randtest_not_zero(a, state, n_randint(state, 60) + 1, 80); + fmpq_poly_set_coeff_ui(a, 0, UWORD(0)); + + fmpq_poly_randtest_not_zero(b, state, n_randint(state, 60) + 1, 80); + fmpq_poly_set_coeff_ui(b, 0, UWORD(0)); + + fmpq_poly_add(ab, a, b); + + fmpq_poly_exp_series(expab, ab, n); + fmpq_poly_exp_series(expa, a, n); + fmpq_poly_exp_series(expb, b, n); + fmpq_poly_mullow(expa_expb, expa, expb, n); + + cflags |= fmpq_poly_is_canonical(expa) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(expb) ? 0 : 2; + cflags |= fmpq_poly_is_canonical(expab) ? 0 : 4; + result = (fmpq_poly_equal(expab, expa_expb) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpq_poly_debug(a), flint_printf("\n\n"); + flint_printf("b = "), fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("exp(a) = "), fmpq_poly_debug(expa), flint_printf("\n\n"); + flint_printf("exp(b) = "), fmpq_poly_debug(expb), flint_printf("\n\n"); + flint_printf("exp(ab) = "), fmpq_poly_debug(expab), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(ab); + fmpq_poly_clear(expa); + fmpq_poly_clear(expb); + fmpq_poly_clear(expab); + fmpq_poly_clear(expa_expb); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-gcd.c b/external/flint-2.4.3/fmpq_poly/test/t-gcd.c new file mode 100644 index 0000000..185da5a --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-gcd.c @@ -0,0 +1,270 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int cflags = 0, i, result; + FLINT_TEST_INIT(state); + + flint_printf("gcd...."); + fflush(stdout); + + + + /* Check aliasing of a and c */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, c; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(c); + fmpq_poly_randtest(a, state, n_randint(state, 100), 100); + fmpq_poly_randtest(b, state, n_randint(state, 100), 100); + + fmpq_poly_gcd(c, a, b); + fmpq_poly_gcd(a, a, b); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(c) ? 0 : 2; + result = (fmpq_poly_equal(a, c) && !cflags); + if (!result) + { + flint_printf("FAIL (aliasing a, c):\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + fmpq_poly_debug(c), flint_printf("\n\n"); + flint_printf("cflags = %d\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(c); + } + + /* Check aliasing of b and c */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, c; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(c); + fmpq_poly_randtest(a, state, n_randint(state, 100), 100); + fmpq_poly_randtest(b, state, n_randint(state, 100), 100); + + fmpq_poly_gcd(c, a, b); + fmpq_poly_gcd(b, a, b); + + cflags |= fmpq_poly_is_canonical(b) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(c) ? 0 : 2; + result = (fmpq_poly_equal(b, c) && !cflags); + if (!result) + { + flint_printf("FAIL (aliasing b, c):\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + fmpq_poly_debug(c), flint_printf("\n\n"); + flint_printf("cflags = %d\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(c); + } + + /* Generic case when a, b are most likely co-prime ***********************/ + + /* Verify commutativity and that c is monic */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, c; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(c); + fmpq_poly_randtest(a, state, n_randint(state, 100), 100); + fmpq_poly_randtest(b, state, n_randint(state, 100), 100); + + fmpq_poly_gcd(c, a, b); + fmpq_poly_gcd(a, b, a); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(c) ? 0 : 2; + result = (fmpq_poly_equal(a, c) && !cflags + && (fmpq_poly_is_zero(c) || fmpq_poly_is_monic(c))); + if (!result) + { + flint_printf("FAIL (commutativity #1):\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + fmpq_poly_debug(c), flint_printf("\n\n"); + flint_printf("cflags = %d\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(c); + } + + /* Verify that GCD(a, b) divides a, b */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, c, r1, r2; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(c); + fmpq_poly_init(r1); + fmpq_poly_init(r2); + fmpq_poly_randtest(a, state, n_randint(state, 100), 100); + fmpq_poly_randtest(b, state, n_randint(state, 100), 100); + + fmpq_poly_gcd(c, a, b); + if (!fmpq_poly_is_zero(c)) + { + fmpq_poly_rem(r1, a, c); + fmpq_poly_rem(r2, b, c); + } + + result = fmpq_poly_is_zero(r1) && fmpq_poly_is_zero(r2); + if (!result) + { + flint_printf("FAIL (division #1):\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + fmpq_poly_debug(c), flint_printf("\n\n"); + flint_printf("cflags = %d\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(c); + fmpq_poly_clear(r1); + fmpq_poly_clear(r2); + } + + /* Case when a, b are not co-prime ***************************************/ + + /* Verify commutativity and that c is monic */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, c, t; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(c); + fmpq_poly_init(t); + fmpq_poly_randtest(a, state, n_randint(state, 100), 100); + fmpq_poly_randtest(b, state, n_randint(state, 100), 100); + fmpq_poly_randtest(t, state, n_randint(state, 50), 20); + fmpq_poly_mul(a, a, t); + fmpq_poly_mul(b, b, t); + + fmpq_poly_gcd(c, a, b); + fmpq_poly_gcd(a, b, a); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(c) ? 0 : 2; + result = (fmpq_poly_equal(a, c) && !cflags + && (fmpq_poly_is_zero(c) || fmpq_poly_is_monic(c))); + if (!result) + { + flint_printf("FAIL (commutativity #2):\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + fmpq_poly_debug(c), flint_printf("\n\n"); + flint_printf("cflags = %d\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(c); + fmpq_poly_clear(t); + } + + /* Verify that GCD(a, b) divides a, b */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, c, r1, r2, t; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(c); + fmpq_poly_init(r1); + fmpq_poly_init(r2); + fmpq_poly_init(t); + fmpq_poly_randtest(a, state, n_randint(state, 100), 100); + fmpq_poly_randtest(b, state, n_randint(state, 100), 100); + fmpq_poly_randtest(t, state, n_randint(state, 50), 20); + fmpq_poly_mul(a, a, t); + fmpq_poly_mul(b, b, t); + + fmpq_poly_gcd(c, a, b); + if (!fmpq_poly_is_zero(c)) + { + fmpq_poly_rem(r1, a, c); + fmpq_poly_rem(r2, b, c); + } + + result = fmpq_poly_is_zero(r1) && fmpq_poly_is_zero(r2); + if (!result) + { + flint_printf("FAIL (division #2):\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + fmpq_poly_debug(c), flint_printf("\n\n"); + flint_printf("cflags = %d\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(c); + fmpq_poly_clear(r1); + fmpq_poly_clear(r2); + fmpq_poly_clear(t); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} + diff --git a/external/flint-2.4.3/fmpq_poly/test/t-get_set_coeff_fmpq.c b/external/flint-2.4.3/fmpq_poly/test/t-get_set_coeff_fmpq.c new file mode 100644 index 0000000..b834bf8 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-get_set_coeff_fmpq.c @@ -0,0 +1,90 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ + +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, j, result; + ulong cflags = UWORD(0); + + FLINT_TEST_INIT(state); + + flint_printf("get/set_coeff_fmpq...."); + fflush(stdout); + + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpq_poly_t a; + fmpq_t x, y; + slong coeff, len; + + fmpq_poly_init(a); + fmpq_init(x); + fmpq_init(y); + len = (slong) (n_randint(state, 100) + 1); + + for (j = 0; j < 50; j++) + { + fmpq_randtest(x, state, 200); + coeff = (slong) n_randint(state, len); + fmpq_poly_set_coeff_fmpq(a, coeff, x); + fmpq_poly_get_coeff_fmpq(y, a, coeff); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + result = (fmpq_equal(x, y) && !cflags); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), fmpq_poly_debug(a), flint_printf("\n\n"); + flint_printf("coeff = %wd\n\n", coeff); + flint_printf("len = %wd\n\n", len); + flint_printf("cflags = %wu\n\n", cflags); + flint_printf("x = "), fmpq_print(x), flint_printf("\n"); + flint_printf("y = "), fmpq_print(y), flint_printf("\n"); + abort(); + } + } + + fmpq_clear(x); + fmpq_clear(y); + fmpq_poly_clear(a); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-get_set_coeff_fmpz.c b/external/flint-2.4.3/fmpq_poly/test/t-get_set_coeff_fmpz.c new file mode 100644 index 0000000..7cef87b --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-get_set_coeff_fmpz.c @@ -0,0 +1,98 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, j, result; + ulong cflags = UWORD(0); + + mpq_t n1, n2; + + FLINT_TEST_INIT(state); + + flint_printf("get/set_coeff_fmpz...."); + fflush(stdout); + + mpq_init(n1); + mpq_init(n2); + + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_poly_t a; + fmpz_t x1, x2; + slong coeff, len; + + fmpq_poly_init(a); + fmpz_init(x1); + fmpz_init(x2); + len = (slong) (n_randint(state, 100) + 1); + + for (j = 0; j < 100; j++) + { + fmpz_randtest(x1, state, 200); + fmpz_get_mpz(mpq_numref(n1), x1); + flint_mpz_set_si(mpq_denref(n1), 1); + coeff = (slong) n_randint(state, len); + fmpq_poly_set_coeff_fmpz(a, coeff, x1); + fmpq_poly_get_coeff_mpq(n2, a, coeff); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + result = (mpq_equal(n1, n2) && !cflags); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), fmpq_poly_debug(a), flint_printf("\n\n"); + flint_printf("coeff = %wd\n\n", coeff); + flint_printf("len = %wd\n\n", len); + flint_printf("cflags = %wu\n\n", cflags); + gmp_printf("n1 = %Qd\n\n", n1); + gmp_printf("n2 = %Qd\n\n", n2); + abort(); + } + } + + fmpz_clear(x1); + fmpz_clear(x2); + fmpq_poly_clear(a); + } + + mpq_clear(n1); + mpq_clear(n2); + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-get_set_coeff_mpq.c b/external/flint-2.4.3/fmpq_poly/test/t-get_set_coeff_mpq.c new file mode 100644 index 0000000..4705b48 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-get_set_coeff_mpq.c @@ -0,0 +1,102 @@ + +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, j, result; + ulong cflags = UWORD(0); + + mpq_t n1, n2; + + FLINT_TEST_INIT(state); + + flint_printf("get/set_coeff_mpq...."); + fflush(stdout); + + mpq_init(n1); + mpq_init(n2); + + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpq_poly_t a; + fmpz_t xnum, xden; + slong coeff, len; + + fmpq_poly_init(a); + fmpz_init(xnum); + fmpz_init(xden); + len = (slong) (n_randint(state, 100) + 1); + + for (j = 0; j < 50; j++) + { + fmpz_randtest(xnum, state, 200); + fmpz_randtest_not_zero(xden, state, 200); + fmpz_get_mpz(mpq_numref(n1), xnum); + fmpz_get_mpz(mpq_denref(n1), xden); + mpq_canonicalize(n1); + coeff = (slong) n_randint(state, len); + fmpq_poly_set_coeff_mpq(a, coeff, n1); + fmpq_poly_get_coeff_mpq(n2, a, coeff); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + result = (mpq_equal(n1, n2) && !cflags); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), fmpq_poly_debug(a), flint_printf("\n\n"); + flint_printf("coeff = %wd\n\n", coeff); + flint_printf("len = %wd\n\n", len); + flint_printf("cflags = %wu\n\n", cflags); + gmp_printf("n1 = %Qd\n\n", n1); + gmp_printf("n2 = %Qd\n\n", n2); + abort(); + } + } + + fmpz_clear(xnum); + fmpz_clear(xden); + fmpq_poly_clear(a); + } + + mpq_clear(n1); + mpq_clear(n2); + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-get_set_coeff_mpz.c b/external/flint-2.4.3/fmpq_poly/test/t-get_set_coeff_mpz.c new file mode 100644 index 0000000..d16b6c8 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-get_set_coeff_mpz.c @@ -0,0 +1,97 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, j, result; + ulong cflags = UWORD(0); + + mpq_t n1, n2; + + FLINT_TEST_INIT(state); + + flint_printf("get/set_coeff_mpz...."); + fflush(stdout); + + mpq_init(n1); + mpq_init(n2); + + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_poly_t a; + fmpz_t x1, x2; + slong coeff, len; + + fmpq_poly_init(a); + fmpz_init(x1); + fmpz_init(x2); + len = (slong) (n_randint(state, 100) + 1); + + for (j = 0; j < 100; j++) + { + fmpz_randtest(x1, state, 200); + fmpz_get_mpz(mpq_numref(n1), x1); + flint_mpz_set_si(mpq_denref(n1), 1); + coeff = (slong) n_randint(state, len); + fmpq_poly_set_coeff_mpz(a, coeff, mpq_numref(n1)); + fmpq_poly_get_coeff_mpq(n2, a, coeff); + + result = (mpq_equal(n1, n2)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), fmpq_poly_debug(a), flint_printf("\n\n"); + flint_printf("coeff = %wd\n\n", coeff); + flint_printf("len = %wd\n\n", len); + flint_printf("cflags = %wu\n\n", cflags); + gmp_printf("n1 = %Qd\n\n", n1); + gmp_printf("n2 = %Qd\n\n", n2); + abort(); + } + } + + fmpz_clear(x1); + fmpz_clear(x2); + fmpq_poly_clear(a); + } + + mpq_clear(n1); + mpq_clear(n2); + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-get_set_coeff_si.c b/external/flint-2.4.3/fmpq_poly/test/t-get_set_coeff_si.c new file mode 100644 index 0000000..d1a97f5 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-get_set_coeff_si.c @@ -0,0 +1,91 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpq_poly.h" +#include "long_extras.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, j, result; + ulong cflags = UWORD(0); + + slong n; + mpq_t n_mpq; + FLINT_TEST_INIT(state); + + + flint_printf("get/set_coeff_si...."); + fflush(stdout); + + mpq_init(n_mpq); + + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_poly_t a; + slong coeff, len; + + fmpq_poly_init(a); + len = (slong) n_randint(state, 100) + 1; + + for (j = 0; j < 1000; j++) + { + n = z_randtest(state); + coeff = n_randint(state, len); + fmpq_poly_set_coeff_si(a, coeff, n); + fmpq_poly_get_coeff_mpq(n_mpq, a, coeff); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + result = (flint_mpz_cmp_ui(mpq_denref(n_mpq), 1) == 0 + && flint_mpz_cmp_si(mpq_numref(n_mpq), n) == 0 + && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpq_poly_debug(a), flint_printf("\n"); + flint_printf("len = %wd\n", len); + flint_printf("coeff = %wd\n", coeff); + flint_printf("cflags = %wu\n", cflags); + flint_printf("n = %wd\n", n); + gmp_printf("n_mpq = %Qd\n", n_mpq); + abort(); + } + } + fmpq_poly_clear(a); + } + + + mpq_clear(n_mpq); + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-get_set_coeff_ui.c b/external/flint-2.4.3/fmpq_poly/test/t-get_set_coeff_ui.c new file mode 100644 index 0000000..f6d228d --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-get_set_coeff_ui.c @@ -0,0 +1,90 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, j, result; + ulong cflags = UWORD(0); + + ulong n; + mpq_t n_mpq; + + FLINT_TEST_INIT(state); + + flint_printf("get/set_coeff_ui...."); + fflush(stdout); + + mpq_init(n_mpq); + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_poly_t a; + slong coeff, len; + + fmpq_poly_init(a); + len = (slong) (n_randint(state, 100) + 1); + fmpq_poly_randtest(a, state, len, 100); + + for (j = 0; j < 1000; j++) + { + n = n_randtest(state); + coeff = n_randint(state, len); + fmpq_poly_set_coeff_ui(a, coeff, n); + fmpq_poly_get_coeff_mpq(n_mpq, a, coeff); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + result = (flint_mpz_cmp_ui(mpq_denref(n_mpq), 1) == 0 + && flint_mpz_cmp_ui(mpq_numref(n_mpq), n) == 0 + && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpq_poly_debug(a), flint_printf("\n"); + flint_printf("len = %wd\n", len); + flint_printf("coeff = %wd\n", coeff); + flint_printf("cflags = %wu\n", cflags); + flint_printf("n = %wu\n", n); + gmp_printf("n_mpq = %Qd\n", n_mpq); + abort(); + } + } + + fmpq_poly_clear(a); + } + mpq_clear(n_mpq); + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-get_set_str.c b/external/flint-2.4.3/fmpq_poly/test/t-get_set_str.c new file mode 100644 index 0000000..e7f7333 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-get_set_str.c @@ -0,0 +1,80 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + ulong cflags = UWORD(0); + + FLINT_TEST_INIT(state); + + flint_printf("get_set_str...."); + fflush(stdout); + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + int ans; + char * str; + fmpq_poly_t f, g; + + fmpq_poly_init(f); + fmpq_poly_init(g); + fmpq_poly_randtest(f, state, n_randint(state, 100), 200); + + str = fmpq_poly_get_str(f); + ans = fmpq_poly_set_str(g, str); + + cflags |= fmpq_poly_is_canonical(f) ? 0 : 1; + result = (ans == 0 && fmpq_poly_equal(f, g) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("f = "), fmpq_poly_debug(f), flint_printf("\n\n"); + flint_printf("g = "), fmpq_poly_debug(g), flint_printf("\n\n"); + flint_printf("ans = %d\n\n", ans); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(f); + fmpq_poly_clear(g); + flint_free(str); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-get_slice.c b/external/flint-2.4.3/fmpq_poly/test/t-get_slice.c new file mode 100644 index 0000000..e158183 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-get_slice.c @@ -0,0 +1,157 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + ulong cflags = UWORD(0); + + FLINT_TEST_INIT(state); + + flint_printf("get_slice...."); + fflush(stdout); + + /* Check aliasing of a and b */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, c; + slong j1, j2; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(c); + fmpq_poly_randtest(a, state, n_randint(state, 100), 200); + fmpq_poly_set(b, a); + + j1 = n_randint(state, 100); + j2 = n_randint(state, 100); + + fmpq_poly_get_slice(c, b, j1, j2); + fmpq_poly_get_slice(b, b, j1, j2); + + cflags |= fmpq_poly_is_canonical(b) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(c) ? 0 : 2; + result = (fmpq_poly_equal(b, c) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + fmpq_poly_debug(c), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(c); + } + + /* Check slice with i >= j is zero */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b; + slong j1, j2; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_randtest(a, state, n_randint(state, 100), 200); + + j2 = n_randint(state, 60); + j1 = j2 + n_randint(state, 60); + + fmpq_poly_get_slice(b, a, j1, j2); + + cflags |= fmpq_poly_is_canonical(b) ? 0 : 1; + result = (fmpq_poly_is_zero(b) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + } + + /* Check transitivity when j1 <= k1 <= k2 <= j2 */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, c, d; + slong j1, j2, k1, k2; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(c); + fmpq_poly_init(d); + fmpq_poly_randtest(a, state, n_randint(state, 100), 200); + + j1 = n_randint(state, 20); + k1 = j1 + n_randint(state, 20); + k2 = k1 + n_randint(state, 20); + j2 = k2 + n_randint(state, 20); + + fmpq_poly_get_slice(b, a, j1, j2); + fmpq_poly_get_slice(c, b, k1, k2); + fmpq_poly_get_slice(d, a, k1, k2); + + cflags |= fmpq_poly_is_canonical(b) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(c) ? 0 : 2; + cflags |= fmpq_poly_is_canonical(d) ? 0 : 4; + result = (fmpq_poly_equal(c, d) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + fmpq_poly_debug(c), flint_printf("\n\n"); + fmpq_poly_debug(d), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(c); + fmpq_poly_clear(d); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-init_realloc_clear.c b/external/flint-2.4.3/fmpq_poly/test/t-init_realloc_clear.c new file mode 100644 index 0000000..0947233 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-init_realloc_clear.c @@ -0,0 +1,75 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + flint_printf("init/init2/realloc/clear...."); + fflush(stdout); + + + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a; + + fmpq_poly_init2(a, n_randint(state, 100)); + fmpq_poly_clear(a); + } + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a; + + fmpq_poly_init2(a, n_randint(state, 100)); + fmpq_poly_realloc(a, n_randint(state, 100)); + fmpq_poly_clear(a); + } + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a; + + fmpq_poly_init(a); + fmpq_poly_randtest(a, state, n_randint(state, 100), 200); + fmpq_poly_clear(a); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-integral.c b/external/flint-2.4.3/fmpq_poly/test/t-integral.c new file mode 100644 index 0000000..7421a90 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-integral.c @@ -0,0 +1,109 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + ulong cflags = UWORD(0); + + FLINT_TEST_INIT(state); + + flint_printf("integral...."); + fflush(stdout); + + /* Check aliasing */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_randtest(a, state, n_randint(state, 100), 200); + + fmpq_poly_integral(b, a); + fmpq_poly_integral(a, a); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(b) ? 0 : 2; + result = (fmpq_poly_equal(a, b) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + } + + /* Check inverse of fmpq_poly_derivative */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, c; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(c); + fmpq_poly_randtest(a, state, n_randint(state, 100), 200); + + fmpq_poly_integral(b, a); + fmpq_poly_derivative(c, b); + + cflags |= fmpq_poly_is_canonical(b) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(c) ? 0 : 2; + result = fmpq_poly_equal(a, c) && !cflags; + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-interpolate_fmpz_vec.c b/external/flint-2.4.3/fmpq_poly/test/t-interpolate_fmpz_vec.c new file mode 100644 index 0000000..0ecaddb --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-interpolate_fmpz_vec.c @@ -0,0 +1,97 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + flint_printf("interpolate_fmpz_vec...."); + fflush(stdout); + + + + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_poly_t P; + fmpz *x, *y, *z; + fmpq_t q; + slong j, n, bits; + + n = n_randint(state, 50); + bits = n_randint(state, 100); + + x = _fmpz_vec_init(n); + y = _fmpz_vec_init(n); + z = _fmpz_vec_init(n); + + fmpq_poly_init(P); + + for (j = 0; j < n; j++) + fmpz_set_si(x + j, -n/2 + j); + + _fmpz_vec_randtest(y, state, n, bits); + + fmpq_poly_interpolate_fmpz_vec(P, x, y, n); + + fmpq_init(q); + for (j = 0; j < n; j++) + { + fmpq_poly_evaluate_fmpz(q, P, x + j); + fmpz_set(z + j, fmpq_numref(q)); + + if (!fmpz_equal(z + j, y + j) || !fmpz_is_one(fmpq_denref(q))) + { + flint_printf("FAIL:\n"); + flint_printf("x:\n"); _fmpz_vec_print(x, n); flint_printf("\n\n"); + flint_printf("y:\n"); _fmpz_vec_print(y, n); flint_printf("\n\n"); + flint_printf("P:\n"); fmpq_poly_print(P), flint_printf("\n\n"); + abort(); + } + } + fmpq_clear(q); + + fmpq_poly_clear(P); + _fmpz_vec_clear(x, n); + _fmpz_vec_clear(y, n); + _fmpz_vec_clear(z, n); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-inv.c b/external/flint-2.4.3/fmpq_poly/test/t-inv.c new file mode 100644 index 0000000..8f577e4 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-inv.c @@ -0,0 +1,80 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + ulong cflags = UWORD(0); + + FLINT_TEST_INIT(state); + + flint_printf("inv...."); + fflush(stdout); + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, c; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(c); + fmpq_poly_randtest_not_zero(a, state, 1, 200); + + fmpq_poly_inv(b, a); + fmpq_poly_inv(c, b); + + cflags |= fmpq_poly_is_canonical(b) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(c) ? 0 : 2; + result = (fmpq_poly_equal(a, c) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + fmpq_poly_debug(c), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-inv_series_newton.c b/external/flint-2.4.3/fmpq_poly/test/t-inv_series_newton.c new file mode 100644 index 0000000..2cc5d20 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-inv_series_newton.c @@ -0,0 +1,124 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + ulong cflags = UWORD(0); + + FLINT_TEST_INIT(state); + + flint_printf("inv_series_newton...."); + fflush(stdout); + + /* Check aliasing of a and c */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b; + slong n = n_randint(state, 50) + 1; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_randtest_not_zero(a, state, n_randint(state, 50) + 1, 50); + fmpz_randtest_not_zero(a->coeffs, state, 50); + fmpq_poly_canonicalise(a); + + fmpq_poly_inv_series_newton(b, a, n); + fmpq_poly_inv_series_newton(a, a, n); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(b) ? 0 : 2; + result = (fmpq_poly_equal(a, b) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + } + + /* Check Q^{-1} * Q is congruent 1 mod t^n */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, c, one; + slong n = n_randint(state, 80) + 1; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(c); + fmpq_poly_init(one); + + fmpq_poly_randtest_not_zero(a, state, n_randint(state, 80) + 1, 80); + fmpz_randtest_not_zero(a->coeffs, state, 80); + fmpq_poly_canonicalise(a); + + fmpq_poly_fit_length(one, 1); + fmpz_set_ui(one->coeffs, 1); + one->length = 1; + + fmpq_poly_inv_series_newton(b, a, n); + fmpq_poly_mul(c, a, b); + fmpq_poly_truncate(c, n); + + cflags |= fmpq_poly_is_canonical(b) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(c) ? 0 : 2; + result = (fmpq_poly_equal(c, one) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpq_poly_debug(a), flint_printf("\n\n"); + flint_printf("b = "), fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("c = "), fmpq_poly_debug(c), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(c); + fmpq_poly_clear(one); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-invsqrt_series.c b/external/flint-2.4.3/fmpq_poly/test/t-invsqrt_series.c new file mode 100644 index 0000000..e1a46a3 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-invsqrt_series.c @@ -0,0 +1,120 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + ulong cflags = UWORD(0); + + FLINT_TEST_INIT(state); + + flint_printf("invsqrt_series...."); + fflush(stdout); + + /* Check aliasing of a and c */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b; + slong n = n_randint(state, 50) + 1; + + fmpq_poly_init(a); + fmpq_poly_init(b); + + fmpq_poly_randtest_not_zero(a, state, n_randint(state, 50) + 1, 50); + fmpq_poly_set_coeff_ui(a, 0, UWORD(1)); + + fmpq_poly_canonicalise(a); + + fmpq_poly_invsqrt_series(b, a, n); + fmpq_poly_invsqrt_series(a, a, n); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(b) ? 0 : 2; + result = (fmpq_poly_equal(a, b) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + } + + /* Check 1/((1/sqrt(a))^2) = a */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, c; + slong n = n_randint(state, 80) + 1; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(c); + + fmpq_poly_randtest_not_zero(a, state, n_randint(state, 80) + 1, 80); + fmpq_poly_set_coeff_ui(a, 0, UWORD(1)); + + fmpq_poly_invsqrt_series(b, a, n); + fmpq_poly_mullow(c, b, b, n); + fmpq_poly_inv_series(c, c, n); + fmpq_poly_truncate(a, n); + + cflags |= fmpq_poly_is_canonical(b) ? 0 : 1; + result = (fmpq_poly_equal(c, a) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpq_poly_debug(a), flint_printf("\n\n"); + flint_printf("b = "), fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("c = "), fmpq_poly_debug(c), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-is_squarefree.c b/external/flint-2.4.3/fmpq_poly/test/t-is_squarefree.c new file mode 100644 index 0000000..9568fb9 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-is_squarefree.c @@ -0,0 +1,135 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("is_squarefree...."); + fflush(stdout); + + + + /* Check that polynomials of degree <= 1 are square-free */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpq_poly_t f; + + fmpq_poly_init(f); + fmpq_poly_randtest(f, state, n_randint(state, 2), 100); + + result = (fmpq_poly_is_squarefree(f)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(f), flint_printf("\n"); + abort(); + } + + fmpq_poly_clear(f); + } + + /* Check that a^2 f is not square-free */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, f; + + fmpq_poly_init(a); + fmpq_poly_randtest_not_zero(a, state, n_randint(state, 20) + 1, 40); + if (a->length < 2) + { + fmpq_poly_clear(a); + continue; + } + fmpq_poly_init(f); + fmpq_poly_randtest_not_zero(f, state, n_randint(state, 20) + 1, 40); + + fmpq_poly_mul(a, a, a); + fmpq_poly_mul(f, a, f); + + result = (!fmpq_poly_is_squarefree(f)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(f), flint_printf("\n"); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(f); + } + + /* Check that f + N*(x^M + 1) is square-free, for N >> f, M > deg(f) */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, f; + fmpz_t N; + + fmpq_poly_init(a); + fmpq_poly_set_coeff_si(a, 0, WORD(1)); + fmpq_poly_set_coeff_si(a, n_randint(state, 20), WORD(1)); + if (a->length < 2) + { + fmpq_poly_clear(a); + continue; + } + fmpq_poly_init(f); + fmpq_poly_randtest(f, state, a->length - 2, 40); + + fmpz_init_set_ui(N, UWORD(1)); + fmpz_mul_2exp(N, N, 45 + a->length); + + fmpq_poly_scalar_mul_fmpz(a, a, N); + fmpq_poly_add(f, a, f); + + result = fmpq_poly_is_squarefree(f); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(f), flint_printf("\n"); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(f); + fmpz_clear(N); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-lcm.c b/external/flint-2.4.3/fmpq_poly/test/t-lcm.c new file mode 100644 index 0000000..c28915f --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-lcm.c @@ -0,0 +1,265 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int cflags = 0, i, result; + FLINT_TEST_INIT(state); + + flint_printf("lcm...."); + fflush(stdout); + + + + /* Check aliasing of a and c */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, c; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(c); + fmpq_poly_randtest(a, state, n_randint(state, 100), 100); + fmpq_poly_randtest(b, state, n_randint(state, 100), 100); + + fmpq_poly_lcm(c, a, b); + fmpq_poly_lcm(a, a, b); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(c) ? 0 : 2; + result = (fmpq_poly_equal(a, c) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + fmpq_poly_debug(c), flint_printf("\n\n"); + flint_printf("cflags = %d\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(c); + } + + /* Check aliasing of b and c */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, c; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(c); + fmpq_poly_randtest(a, state, n_randint(state, 100), 100); + fmpq_poly_randtest(b, state, n_randint(state, 100), 100); + + fmpq_poly_lcm(c, a, b); + fmpq_poly_lcm(b, a, b); + + cflags |= fmpq_poly_is_canonical(b) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(c) ? 0 : 2; + result = (fmpq_poly_equal(b, c) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + fmpq_poly_debug(c), flint_printf("\n\n"); + flint_printf("cflags = %d\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(c); + } + + /* Generic case when a, b are most likely co-prime ***********************/ + + /* Verify commutativity and that c is monic */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, c; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(c); + fmpq_poly_randtest(a, state, n_randint(state, 100), 100); + fmpq_poly_randtest(b, state, n_randint(state, 100), 100); + + fmpq_poly_lcm(c, a, b); + fmpq_poly_lcm(a, b, a); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(c) ? 0 : 2; + result = (fmpq_poly_equal(a, c) && !cflags + && (fmpq_poly_is_zero(c) || fmpq_poly_is_monic(c))); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + fmpq_poly_debug(c), flint_printf("\n\n"); + flint_printf("cflags = %d\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(c); + } + + /* Verify that LCM(a, b) GCD(a, b) == a b */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, lcm, gcd; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(lcm); + fmpq_poly_init(gcd); + fmpq_poly_randtest(a, state, n_randint(state, 100), 100); + fmpq_poly_randtest(b, state, n_randint(state, 100), 100); + + fmpq_poly_lcm(lcm, a, b); + fmpq_poly_gcd(gcd, a, b); + fmpq_poly_mul(lcm, lcm, gcd); + fmpq_poly_mul(a, a, b); + fmpq_poly_make_monic(a, a); + + result = fmpq_poly_equal(lcm, a); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + fmpq_poly_debug(lcm), flint_printf("\n\n"); + fmpq_poly_debug(gcd), flint_printf("\n\n"); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(lcm); + fmpq_poly_clear(gcd); + } + + /* Case when a, b are not co-prime ***************************************/ + + /* Verify commutativity and that c is monic */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, c, t; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(c); + fmpq_poly_init(t); + fmpq_poly_randtest(a, state, n_randint(state, 100), 100); + fmpq_poly_randtest(b, state, n_randint(state, 100), 100); + fmpq_poly_randtest(t, state, n_randint(state, 50), 20); + fmpq_poly_mul(a, a, t); + fmpq_poly_mul(b, b, t); + + fmpq_poly_lcm(c, a, b); + fmpq_poly_lcm(a, b, a); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(c) ? 0 : 2; + result = (fmpq_poly_equal(a, c) && !cflags + && (fmpq_poly_is_zero(c) || fmpq_poly_is_monic(c))); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + fmpq_poly_debug(c), flint_printf("\n\n"); + flint_printf("cflags = %d\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(c); + fmpq_poly_clear(t); + } + + /* Verify that LCM(a, b) GCD(a, b) == a b */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, lcm, gcd, t; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(lcm); + fmpq_poly_init(gcd); + fmpq_poly_init(t); + fmpq_poly_randtest(a, state, n_randint(state, 100), 100); + fmpq_poly_randtest(b, state, n_randint(state, 100), 100); + fmpq_poly_randtest(t, state, n_randint(state, 50), 20); + fmpq_poly_mul(a, a, t); + fmpq_poly_mul(b, b, t); + + fmpq_poly_lcm(lcm, a, b); + fmpq_poly_gcd(gcd, a, b); + fmpq_poly_mul(lcm, lcm, gcd); + fmpq_poly_mul(a, a, b); + fmpq_poly_make_monic(a, a); + + result = fmpq_poly_equal(lcm, a); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + fmpq_poly_debug(lcm), flint_printf("\n\n"); + fmpq_poly_debug(gcd), flint_printf("\n\n"); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(lcm); + fmpq_poly_clear(gcd); + fmpq_poly_clear(t); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} + + diff --git a/external/flint-2.4.3/fmpq_poly/test/t-log_series.c b/external/flint-2.4.3/fmpq_poly/test/t-log_series.c new file mode 100644 index 0000000..96c7f53 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-log_series.c @@ -0,0 +1,137 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + ulong cflags = UWORD(0); + + FLINT_TEST_INIT(state); + + flint_printf("log_series...."); + fflush(stdout); + + /* Check aliasing of a and c */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b; + slong n = n_randint(state, 50) + 1; + + fmpq_poly_init(a); + fmpq_poly_init(b); + + fmpq_poly_randtest_not_zero(a, state, n_randint(state, 50) + 1, 50); + fmpq_poly_set_coeff_ui(a, 0, UWORD(1)); + + fmpq_poly_canonicalise(a); + + fmpq_poly_log_series(b, a, n); + fmpq_poly_log_series(a, a, n); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(b) ? 0 : 2; + result = (fmpq_poly_equal(a, b) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + } + + /* Check log(a*b) = log(a) + log(b) */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, ab, loga, logb, logab, loga_logb; + slong n = n_randint(state, 80) + 1; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(ab); + fmpq_poly_init(loga); + fmpq_poly_init(logb); + fmpq_poly_init(logab); + fmpq_poly_init(loga_logb); + + fmpq_poly_randtest_not_zero(a, state, n_randint(state, 80) + 1, 80); + fmpq_poly_set_coeff_ui(a, 0, UWORD(1)); + + fmpq_poly_randtest_not_zero(b, state, n_randint(state, 80) + 1, 80); + fmpq_poly_set_coeff_ui(b, 0, UWORD(1)); + + fmpq_poly_mullow(ab, a, b, n); + + fmpq_poly_log_series(logab, ab, n); + fmpq_poly_log_series(loga, a, n); + fmpq_poly_log_series(logb, b, n); + fmpq_poly_add(loga_logb, loga, logb); + + cflags |= fmpq_poly_is_canonical(loga) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(logb) ? 0 : 2; + cflags |= fmpq_poly_is_canonical(logab) ? 0 : 4; + result = (fmpq_poly_equal(logab, loga_logb) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpq_poly_debug(a), flint_printf("\n\n"); + flint_printf("b = "), fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("log(a) = "), fmpq_poly_debug(loga), flint_printf("\n\n"); + flint_printf("log(b) = "), fmpq_poly_debug(logb), flint_printf("\n\n"); + flint_printf("log(ab) = "), fmpq_poly_debug(logab), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(ab); + fmpq_poly_clear(loga); + fmpq_poly_clear(logb); + fmpq_poly_clear(logab); + fmpq_poly_clear(loga_logb); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-make_monic.c b/external/flint-2.4.3/fmpq_poly/test/t-make_monic.c new file mode 100644 index 0000000..0da5e1f --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-make_monic.c @@ -0,0 +1,101 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + ulong cflags = UWORD(0); + + FLINT_TEST_INIT(state); + + flint_printf("make_monic/is_monic...."); + fflush(stdout); + + /* Check aliasing */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t f, g; + + fmpq_poly_init(f); + fmpq_poly_init(g); + fmpq_poly_randtest(f, state, n_randint(state, 100), 200); + + fmpq_poly_make_monic(g, f); + fmpq_poly_make_monic(f, f); + + cflags |= fmpq_poly_is_canonical(f) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(g) ? 0 : 2; + result = (fmpq_poly_equal(f, g) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(f), flint_printf("\n\n"); + fmpq_poly_debug(g), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(f); + fmpq_poly_clear(g); + } + + /* Check that the result of "monic" has "is_monic" return 1 */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t f; + + fmpq_poly_init(f); + fmpq_poly_randtest_not_zero(f, state, n_randint(state, 100) + 1, 200); + + fmpq_poly_make_monic(f, f); + + cflags |= fmpq_poly_is_canonical(f) ? 0 : 1; + result = (fmpq_poly_is_monic(f) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(f), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(f); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-mul.c b/external/flint-2.4.3/fmpq_poly/test/t-mul.c new file mode 100644 index 0000000..bde788c --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-mul.c @@ -0,0 +1,152 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + ulong cflags = UWORD(0); + + FLINT_TEST_INIT(state); + + flint_printf("mul...."); + fflush(stdout); + + /* Check aliasing of a and b */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, c; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(c); + fmpq_poly_randtest(b, state, n_randint(state, 50), 500); + fmpq_poly_randtest(c, state, n_randint(state, 50), 500); + + fmpq_poly_mul(a, b, c); + fmpq_poly_mul(b, b, c); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(b) ? 0 : 2; + result = (fmpq_poly_equal(a, b) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(c); + } + + /* Check aliasing of a and c */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, c; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(c); + fmpq_poly_randtest(b, state, n_randint(state, 50), 500); + fmpq_poly_randtest(c, state, n_randint(state, 50), 500); + + fmpq_poly_mul(a, b, c); + fmpq_poly_mul(c, b, c); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(c) ? 0 : 2; + result = (fmpq_poly_equal(a, c) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(c), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(c); + } + + /* Check (b*c)+(b*d) = b*(c+d) */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpq_poly_t a1, a2, b, c, d; + + fmpq_poly_init(a1); + fmpq_poly_init(a2); + fmpq_poly_init(b); + fmpq_poly_init(c); + fmpq_poly_init(d); + fmpq_poly_randtest(b, state, n_randint(state, 100), 500); + fmpq_poly_randtest(c, state, n_randint(state, 100), 500); + fmpq_poly_randtest(d, state, n_randint(state, 100), 500); + + fmpq_poly_mul(a1, b, c); + fmpq_poly_mul(a2, b, d); + fmpq_poly_add(a1, a1, a2); + + fmpq_poly_add(c, c, d); + fmpq_poly_mul(a2, b, c); + + cflags |= fmpq_poly_is_canonical(a1) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(a2) ? 0 : 2; + result = (fmpq_poly_equal(a1, a2) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(a1), flint_printf("\n\n"); + fmpq_poly_debug(a2), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a1); + fmpq_poly_clear(a2); + fmpq_poly_clear(b); + fmpq_poly_clear(c); + fmpq_poly_clear(d); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-mullow.c b/external/flint-2.4.3/fmpq_poly/test/t-mullow.c new file mode 100644 index 0000000..d54eb68 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-mullow.c @@ -0,0 +1,84 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + ulong cflags = UWORD(0); + + FLINT_TEST_INIT(state); + + flint_printf("mullow...."); + fflush(stdout); + + /* Compare with truncated product of a and b */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, c; + slong trunc; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(c); + trunc = n_randint(state, 50); + fmpq_poly_randtest(b, state, trunc, 200); + fmpq_poly_randtest(c, state, trunc, 200); + + fmpq_poly_mullow(a, b, c, trunc); + fmpq_poly_mul(b, b, c); + fmpq_poly_truncate(b, trunc); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(b) ? 0 : 2; + result = (fmpq_poly_equal(a, b) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-neg.c b/external/flint-2.4.3/fmpq_poly/test/t-neg.c new file mode 100644 index 0000000..058f5b5 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-neg.c @@ -0,0 +1,80 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + ulong cflags = UWORD(0); + + FLINT_TEST_INIT(state); + + flint_printf("neg...."); + fflush(stdout); + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, c; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(c); + fmpq_poly_randtest(a, state, n_randint(state, 100), 200); + + fmpq_poly_neg(b, a); + fmpq_poly_neg(c, b); + + cflags |= fmpq_poly_is_canonical(b) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(c) ? 0 : 2; + result = (fmpq_poly_equal(a, c) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + fmpq_poly_debug(c), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-pow.c b/external/flint-2.4.3/fmpq_poly/test/t-pow.c new file mode 100644 index 0000000..bc5590c --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-pow.c @@ -0,0 +1,127 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + ulong cflags = UWORD(0); + + FLINT_TEST_INIT(state); + + flint_printf("pow...."); + fflush(stdout); + + /* Check aliasing of a and b */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b; + ulong exp; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_randtest(b, state, n_randint(state, 10), 100); + + exp = (ulong) n_randtest(state) % UWORD(20); + + fmpq_poly_pow(a, b, exp); + fmpq_poly_pow(b, b, exp); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(b) ? 0 : 2; + result = (fmpq_poly_equal(a, b) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("exp = %wu\n", exp); + flint_printf("a = "), fmpq_poly_debug(a), flint_printf("\n\n"); + flint_printf("b = "), fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + } + + /* Compare with repeated multiplications by the base */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, c; + ulong exp; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(c); + fmpq_poly_randtest(b, state, n_randint(state, 10), 100); + + exp = (ulong) n_randtest(state) % UWORD(20); + + fmpq_poly_pow(a, b, exp); + + if (exp == 0) + { + fmpq_poly_set_ui(c, 1); + } + else + { + ulong j; + fmpq_poly_set(c, b); + + for (j = 1; j < exp; j++) + fmpq_poly_mul(c, c, b); + } + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + result = (fmpq_poly_equal(a, c) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("exp = %wu\n", exp); + flint_printf("a = "), fmpq_poly_debug(a), flint_printf("\n\n"); + flint_printf("c = "), fmpq_poly_debug(c), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-primitive_part.c b/external/flint-2.4.3/fmpq_poly/test/t-primitive_part.c new file mode 100644 index 0000000..8102838 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-primitive_part.c @@ -0,0 +1,124 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + ulong cflags = UWORD(0); + + FLINT_TEST_INIT(state); + + flint_printf("primitive_part...."); + fflush(stdout); + + /* Check aliasing */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t f, g; + fmpq_t x; + + fmpq_init(x); + fmpq_poly_init(f); + fmpq_poly_init(g); + fmpq_poly_randtest(f, state, n_randint(state, 100), 200); + fmpq_randtest(x, state, 100); + + fmpq_poly_scalar_mul_fmpq(f, f, x); + + fmpq_poly_primitive_part(g, f); + fmpq_poly_primitive_part(f, f); + + cflags |= fmpq_poly_is_canonical(f) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(g) ? 0 : 2; + result = (fmpq_poly_equal(f, g) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(f), flint_printf("\n\n"); + fmpq_poly_debug(g), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_clear(x); + fmpq_poly_clear(f); + fmpq_poly_clear(g); + } + + /* Check that content(f) primitive_part(f) = +- f */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t f, g; + fmpq_t x, y; + + fmpq_init(x); + fmpq_init(y); + fmpq_poly_init(f); + fmpq_poly_init(g); + fmpq_poly_randtest(f, state, n_randint(state, 100), 200); + fmpq_randtest(x, state, 100); + + fmpq_poly_scalar_mul_fmpq(f, f, x); + + fmpq_poly_content(y, f); + fmpq_poly_primitive_part(g, f); + fmpq_poly_scalar_mul_fmpq(g, g, y); + + if (!fmpq_poly_is_zero(f) && fmpz_sgn(f->coeffs + (f->length - 1)) < 0) + fmpq_poly_neg(g, g); + + cflags |= fmpq_poly_is_canonical(f) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(g) ? 0 : 2; + result = (fmpq_poly_equal(f, g) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(f), flint_printf("\n\n"); + fmpq_poly_debug(g), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_clear(x); + fmpq_clear(y); + fmpq_poly_clear(f); + fmpq_poly_clear(g); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-print_read.c b/external/flint-2.4.3/fmpq_poly/test/t-print_read.c new file mode 100644 index 0000000..784f2e1 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-print_read.c @@ -0,0 +1,270 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + + +#include +#include +#include +#include +#include + +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpq_poly.h" + +#if !defined (__WIN32) || defined(__CYGWIN__) + +/* + The function fdopen is declared in stdio.h. It is POSIX.1 compliant, + but not ANSI compliant. The following line enables compilation with + the "-ansi" flag. + */ +extern FILE * fdopen(int fildes, const char *mode); + +int main(void) +{ + int i, j, n = 1000, result; + + FILE *in, *out; + int fd[2]; + pid_t childpid; + + FLINT_TEST_INIT(state); + + flint_printf("print/ read...."); + fflush(stdout); + + /* Randomise n polynomials, write to and read from a pipe */ + { + fmpq_poly_t *a; + + a = flint_malloc(n * sizeof(fmpq_poly_t)); + for (i = 0; i < n; i++) + { + fmpq_poly_init(a[i]); + fmpq_poly_randtest(a[i], state, 100, 100); + } + + if (pipe(fd)) + { + flint_printf("FAIL:\n"); + flint_printf("Failed to set-up the pipe.\n"); + abort(); + } + + if((childpid = fork()) == -1) + { + flint_printf("FAIL:\n"); + flint_printf("Failed to fork the process.\n"); + abort(); + } + + if(childpid == 0) /* Child process */ + { + int r; + + close(fd[0]); + out = fdopen(fd[1], "w"); + if (out == NULL) + { + flint_printf("FAIL:\n"); + flint_printf("Could not open output file at the pipe.\n"); + abort(); + } + + for (j = 0; j < n; j++) + { + r = fmpq_poly_fprint(out, a[j]); + if ((j < n - 1) && (r > 0)) + r = flint_fprintf(out, "\n"); + + if (r <= 0) + { + flint_printf("FAIL:\n"); + flint_printf("Write error.\n"); + abort(); + } + } + + fclose(out); + exit(0); + } + else /* Parent process */ + { + int r; + fmpq_poly_t t; + + close(fd[1]); + in = fdopen(fd[0], "r"); + if (in == NULL) + { + flint_printf("FAIL:\n"); + flint_printf("Could not open input file at the pipe.\n"); + abort(); + } + + fmpq_poly_init(t); + + i = 0; + while (!feof(in)) + { + r = fmpq_poly_fread(in, t); + if (r <= 0) + { + flint_printf("FAIL:\n"); + flint_printf("Read error.\n"); + abort(); + } + + result = fmpq_poly_equal(t, a[i]); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a[i] = "), fmpq_poly_debug(a[i]), flint_printf("\n"); + flint_printf("t = "), fmpq_poly_debug(t), flint_printf("\n"); + abort(); + } + + ++i; + } + + fmpq_poly_clear(t); + fclose(in); + } + + if (i != n) + { + flint_printf("FAIL:\n"); + flint_printf("Only %d out of %d objects were processed.\n", i, n); + abort(); + } + + for (i = 0; i < n; i++) + fmpq_poly_clear(a[i]); + flint_free(a); + } + + /* Write bad data to a pipe and read it */ + { + char str[5] = {'b', 'l', 'a', 'h', '\0'}; + + if (pipe(fd)) + { + flint_printf("FAIL:\n"); + flint_printf("Failed to set-up the pipe.\n"); + abort(); + } + + if((childpid = fork()) == -1) + { + flint_printf("FAIL:\n"); + flint_printf("Failed to fork the process.\n"); + abort(); + } + + if(childpid == 0) /* Child process */ + { + int r; + + close(fd[0]); + out = fdopen(fd[1], "w"); + if (out == NULL) + { + flint_printf("FAIL:\n"); + flint_printf("Could not open output file at the pipe.\n"); + abort(); + } + + r = flint_fprintf(out, "blah"); + if (r <= 0) + { + flint_printf("FAIL:\n"); + flint_printf("Write error.\n"); + abort(); + } + + fclose(out); + exit(0); + } + else /* Parent process */ + { + int r; + fmpq_poly_t t; + + close(fd[1]); + in = fdopen(fd[0], "r"); + if (in == NULL) + { + flint_printf("FAIL:\n"); + flint_printf("Could not open input file at the pipe.\n"); + abort(); + } + + fmpq_poly_init(t); + + i = 0; + while (!feof(in)) + { + r = fmpq_poly_fread(in, t); + if (r > 0) + { + flint_printf("FAIL:\n"); + flint_printf("r = %d\n", r); + abort(); + } + ++i; + } + + fmpq_poly_clear(t); + fclose(in); + } + + /* For {'b','l','a','h','\0'} we expect 5 reads */ + if (i != 5) + { + flint_printf("FAIL:\n"); + flint_printf("Carried out %d reads, but \"%s\" has only 4 characters.\n", i, str); + abort(); + } + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + +#else + +int main(void) +{ + flint_printf("print/ read...."); + fflush(stdout); + flint_printf("SKIPPED\n"); + return EXIT_SUCCESS; +} + +#endif diff --git a/external/flint-2.4.3/fmpq_poly/test/t-rem.c b/external/flint-2.4.3/fmpq_poly/test/t-rem.c new file mode 100644 index 0000000..678625f --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-rem.c @@ -0,0 +1,152 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + ulong cflags = UWORD(0); + + FLINT_TEST_INIT(state); + + flint_printf("rem...."); + fflush(stdout); + + /* Check aliasing of r and a */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, r; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(r); + fmpq_poly_randtest(a, state, n_randint(state, 50), 200); + fmpq_poly_randtest_not_zero(b, state, n_randint(state, 50) + 1, 200); + + fmpq_poly_rem(r, a, b); + fmpq_poly_rem(a, a, b); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(r) ? 0 : 2; + result = (fmpq_poly_equal(r, a) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("r = "), fmpq_poly_debug(r), flint_printf("\n\n"); + flint_printf("a = "), fmpq_poly_debug(a), flint_printf("\n\n"); + flint_printf("b = "), fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(r); + } + + /* Check aliasing of r and b */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, r; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(r); + fmpq_poly_randtest(a, state, n_randint(state, 50), 200); + fmpq_poly_randtest_not_zero(b, state, n_randint(state, 50) + 1, 200); + + fmpq_poly_rem(r, a, b); + fmpq_poly_rem(b, a, b); + + cflags |= fmpq_poly_is_canonical(b) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(r) ? 0 : 2; + result = (fmpq_poly_equal(r, b) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("r = "), fmpq_poly_debug(r), flint_printf("\n\n"); + flint_printf("a = "), fmpq_poly_debug(a), flint_printf("\n\n"); + flint_printf("b = "), fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(r); + } + + /* Compare with divrem */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, q, r, r2; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(q); + fmpq_poly_init(r); + fmpq_poly_init(r2); + fmpq_poly_randtest(a, state, n_randint(state, 50), 200); + fmpq_poly_randtest_not_zero(b, state, n_randint(state, 50) + 1, 200); + + fmpq_poly_divrem(q, r, a, b); + fmpq_poly_rem(r2, a, b); + + cflags |= fmpq_poly_is_canonical(q) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(r2) ? 0 : 2; + result = (fmpq_poly_equal(r, r2) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpq_poly_debug(a), flint_printf("\n\n"); + flint_printf("b = "), fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("q = "), fmpq_poly_debug(q), flint_printf("\n\n"); + flint_printf("r = "), fmpq_poly_debug(r), flint_printf("\n\n"); + flint_printf("r2 = "), fmpq_poly_debug(r2), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(q); + fmpq_poly_clear(r); + fmpq_poly_clear(r2); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-rem_powers_precomp.c b/external/flint-2.4.3/fmpq_poly/test/t-rem_powers_precomp.c new file mode 100644 index 0000000..d5d0fbf --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-rem_powers_precomp.c @@ -0,0 +1,162 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + ulong cflags = UWORD(0); + + FLINT_TEST_INIT(state); + + flint_printf("rem_powers_precomp...."); + fflush(stdout); + + /* Check aliasing of q and a */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, r; + fmpq_poly_powers_precomp_t binv; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(r); + fmpq_poly_randtest(a, state, n_randint(state, 50), 100); + fmpq_poly_randtest_not_zero(b, state, n_randint(state, 50) + 1, 100); + + fmpq_poly_powers_precompute(binv, b); + + fmpq_poly_rem_powers_precomp(r, a, b, binv); + fmpq_poly_rem_powers_precomp(a, a, b, binv); + + result = (fmpq_poly_equal(r, a)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("r = "), fmpq_poly_debug(r), flint_printf("\n\n"); + flint_printf("a = "), fmpq_poly_debug(a), flint_printf("\n\n"); + flint_printf("b = "), fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_powers_clear(binv); + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(r); + } + + /* Check aliasing of q and b */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, r; + fmpq_poly_powers_precomp_t binv; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(r); + fmpq_poly_randtest(a, state, n_randint(state, 50), 100); + fmpq_poly_randtest_not_zero(b, state, n_randint(state, 50) + 1, 100); + + fmpq_poly_powers_precompute(binv, b); + + fmpq_poly_rem_powers_precomp(r, a, b, binv); + fmpq_poly_rem_powers_precomp(b, a, b, binv); + + result = (fmpq_poly_equal(r, b)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("r = "), fmpq_poly_debug(r), flint_printf("\n\n"); + flint_printf("a = "), fmpq_poly_debug(a), flint_printf("\n\n"); + flint_printf("b = "), fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_powers_clear(binv); + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(r); + } + + /* Compare with divrem */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, q, r2, r; + fmpq_poly_powers_precomp_t binv; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(q); + fmpq_poly_init(r2); + fmpq_poly_init(r); + fmpq_poly_randtest(a, state, n_randint(state, 50), 100); + fmpq_poly_randtest_not_zero(b, state, n_randint(state, 50) + 1, 100); + + fmpq_poly_powers_precompute(binv, b); + + fmpq_poly_divrem(q, r, a, b); + fmpq_poly_rem_powers_precomp(r2, a, b, binv); + fmpq_poly_canonicalise(r2); + + result = (fmpq_poly_equal(r, r2)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpq_poly_debug(a), flint_printf("\n\n"); + flint_printf("b = "), fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("q = "), fmpq_poly_debug(q), flint_printf("\n\n"); + flint_printf("r = "), fmpq_poly_debug(r), flint_printf("\n\n"); + flint_printf("r2 = "), fmpq_poly_debug(r2), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_powers_clear(binv); + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(q); + fmpq_poly_clear(r2); + fmpq_poly_clear(r); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-rescale.c b/external/flint-2.4.3/fmpq_poly/test/t-rescale.c new file mode 100644 index 0000000..f85ec9b --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-rescale.c @@ -0,0 +1,117 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + ulong cflags = UWORD(0); + + FLINT_TEST_INIT(state); + + flint_printf("rescale...."); + fflush(stdout); + + /* Check aliasing */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_poly_t f, g; + fmpq_t a; + + fmpq_poly_init(f); + fmpq_poly_init(g); + fmpq_poly_randtest(f, state, n_randint(state, 100), 100); + + fmpq_init(a); + fmpq_randtest(a, state, 100); + + fmpq_poly_rescale(g, f, a); + fmpq_poly_rescale(f, f, a); + + cflags |= fmpq_poly_is_canonical(f) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(g) ? 0 : 2; + result = (fmpq_poly_equal(f, g) && !cflags); + if (!result) + { + flint_printf("FAIL (aliasing):\n"); + fmpq_poly_debug(f), flint_printf("\n\n"); + fmpq_poly_debug(g), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(f); + fmpq_poly_clear(g); + fmpq_clear(a); + } + + /* Check that rescaling by a and then by 1/a is the identity */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_poly_t f, g; + fmpq_t a; + + fmpq_poly_init(f); + fmpq_poly_init(g); + fmpq_poly_randtest(f, state, n_randint(state, 100), 100); + + fmpq_init(a); + fmpq_randtest_not_zero(a, state, 100); + + fmpq_poly_rescale(g, f, a); + fmpq_inv(a, a); + fmpq_poly_rescale(g, g, a); + + cflags |= fmpq_poly_is_canonical(f) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(g) ? 0 : 2; + result = (fmpq_poly_equal(f, g) && !cflags); + if (!result) + { + flint_printf("FAIL (composition of a and 1/a):\n"); + fmpq_poly_debug(f), flint_printf("\n\n"); + fmpq_poly_debug(g), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(f); + fmpq_poly_clear(g); + fmpq_clear(a); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-resultant.c b/external/flint-2.4.3/fmpq_poly/test/t-resultant.c new file mode 100644 index 0000000..e7c78a3 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-resultant.c @@ -0,0 +1,188 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +#pragma GCC diagnostic ignored "-Woverlength-strings" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("resultant...."); + fflush(stdout); + + + + /* Check res(f, g) == (-1)^(deg f deg g) res(g, f) */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpq_poly_t f, g; + fmpq_t x, y; + + fmpq_poly_init(f); + fmpq_poly_init(g); + fmpq_init(x); + fmpq_init(y); + + fmpq_poly_randtest(f, state, n_randint(state, 60), 60); + fmpq_poly_randtest(g, state, n_randint(state, 60), 60); + + fmpq_poly_resultant(x, f, g); + fmpq_poly_resultant(y, g, f); + if ((fmpq_poly_degree(f) * fmpq_poly_degree(g)) % 2) + fmpq_neg(y, y); + + result = fmpq_equal(x, y); + if (!result) + { + flint_printf("FAIL (res(f,g) == (-1)^(m * n) res(g, f)):\n"); + flint_printf("f = "), fmpq_poly_print(f), flint_printf("\n\n"); + flint_printf("g = "), fmpq_poly_print(g), flint_printf("\n\n"); + flint_printf("x = "), fmpq_print(x), flint_printf("\n\n"); + flint_printf("y = "), fmpq_print(y), flint_printf("\n\n"); + abort(); + } + + fmpq_poly_clear(f); + fmpq_poly_clear(g); + fmpq_clear(x); + fmpq_clear(y); + } + + /* Check res(f h, g) == res(f, g) res(h, g) */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpq_poly_t f, g, h; + fmpq_t x, y, z; + + fmpq_poly_init(f); + fmpq_poly_init(g); + fmpq_poly_init(h); + fmpq_init(x); + fmpq_init(y); + fmpq_init(z); + + fmpq_poly_randtest(f, state, n_randint(state, 60), 60); + fmpq_poly_randtest(g, state, n_randint(state, 60), 60); + fmpq_poly_randtest(h, state, n_randint(state, 60), 60); + + fmpq_poly_resultant(y, f, g); + fmpq_poly_resultant(z, h, g); + fmpq_mul(y, y, z); + fmpq_poly_mul(f, f, h); + fmpq_poly_resultant(x, f, g); + + result = fmpq_equal(x, y); + if (!result) + { + flint_printf("FAIL (res(f h, g) == res(f, g) res(h, g)):\n"); + flint_printf("f = "), fmpq_poly_print(f), flint_printf("\n\n"); + flint_printf("g = "), fmpq_poly_print(g), flint_printf("\n\n"); + flint_printf("h = "), fmpq_poly_print(h), flint_printf("\n\n"); + flint_printf("x = "), fmpq_print(x), flint_printf("\n\n"); + flint_printf("y = "), fmpq_print(y), flint_printf("\n\n"); + abort(); + } + + fmpq_poly_clear(f); + fmpq_poly_clear(g); + fmpq_poly_clear(h); + fmpq_clear(x); + fmpq_clear(y); + fmpq_clear(z); + } + + /* fredrik's test case */ + { + fmpq_poly_t f, g; + fmpq_t x, y; + int result; + + fmpq_poly_init(f); + fmpq_poly_init(g); + fmpq_init(x); + fmpq_init(y); + + fmpq_poly_set_str(f, "49 16702090503 -23810415210 7561766512 801950253" + " 56796743 40735271 -15934 820601 -2712604160 -1577466 0 0 -7967 0" + " 0 0 -14491973 0 6566138489 -55769 0 130523361 4071137 15934" + " -501921 -59067338 63860755253 23924901 -15934 -262911 -7967" + " -4389817 0 185876611072 58470888545 130523361 -63736 -130618965" + " -39835 0 7967 0 55769 -7967 103571 111298990 47802 -3808226" + " -3800259"); + + fmpq_poly_set_str(g, "59 -458395/219902324736 151585/4581298432" + " 112595/219902324736 -2016245/54975581184 0 35/73300774912 0" + " -234880919/219902324736 7/219902324736 -7/1278501888" + " -6055/109951162368 7/27487790592 -504623/73300774912" + " 53673977/219902324736 0 611667/73300774912 -497/13743895296" + " 0 -6265/219902324736 2446675/73300774912 2345/219902324736" + " -371/73300774912 -427/6871947648 -3758096377/219902324736" + " 20595995/109951162368 -256459/73300774912 0 33690223/73300774912" + " -229369/219902324736 93205/219902324736 -7/107374182" + " -133/219902324736 -665/13743895296 -146503/219902324736 0" + " 7/219902324736 66633/73300774912 -855190385/219902324736" + " 229355/219902324736 0 161/219902324736 887299/219902324736" + " -427/7582838784 -611667/18325193728 -7/5114007552 833/54975581184" + " -7/109951162368 -5402264413/219902324736 7/5114007552 35/9162596864" + " 1133545/219902324736 -151319/73300774912 0 7/219902324736" + " 7/54975581184 0 -10367/109951162368 7/54975581184 -161/109951162368"); + + fmpq_poly_resultant(x, f, g); + fmpq_poly_resultant(y, g, f); + + if ((fmpq_poly_degree(f) * fmpq_poly_degree(g)) % 2) + fmpq_neg(y, y); + + result = fmpq_equal(x, y); + if (!result) + { + flint_printf("FAIL (res(f,g) == (-1)^(m * n) res(g, f)):\n"); + flint_printf("x = "), fmpq_print(x), flint_printf("\n\n"); + flint_printf("y = "), fmpq_print(y), flint_printf("\n\n"); + abort(); + } + + fmpq_poly_clear(f); + fmpq_poly_clear(g); + fmpq_clear(x); + fmpq_clear(y); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} + diff --git a/external/flint-2.4.3/fmpq_poly/test/t-reverse.c b/external/flint-2.4.3/fmpq_poly/test/t-reverse.c new file mode 100644 index 0000000..56110be --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-reverse.c @@ -0,0 +1,115 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("reverse...."); + fflush(stdout); + + + + /* Aliasing */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b; + slong n; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_randtest(b, state, n_randint(state, 100), 200); + n = n_randint(state, 150); + + fmpq_poly_reverse(a, b, n); + fmpq_poly_reverse(b, b, n); + + result = (fmpq_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("n = %wd\n", n); + flint_printf("a = "), fmpq_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpq_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + } + + /* Correctness (?) */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b; + slong j, len, n; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_randtest(b, state, n_randint(state, 100), 200); + n = n_randint(state, 150); + + len = FLINT_MIN(n, b->length); + if (len) + { + fmpq_poly_fit_length(a, n); + for (j = 0; j < len; j++) + fmpz_set(a->coeffs + (n - len) + j, b->coeffs + (len - 1 - j)); + fmpz_set(a->den, b->den); + _fmpq_poly_set_length(a, n); + fmpq_poly_canonicalise(a); + } + + fmpq_poly_reverse(b, b, n); + + result = (fmpq_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("n = %wd\n", n); + flint_printf("a = "), fmpq_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpq_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-revert_series.c b/external/flint-2.4.3/fmpq_poly/test/t-revert_series.c new file mode 100644 index 0000000..f15eae4 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-revert_series.c @@ -0,0 +1,121 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("revert_series...."); + fflush(stdout); + + + + /* Check aliasing */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + fmpq_poly_t f, g; + slong n; + + fmpq_poly_init(f); + fmpq_poly_init(g); + do { + fmpq_poly_randtest(g, state, n_randint(state, 50), 1+n_randint(state,100)); + } while (fmpq_poly_length(g) < 2 || fmpz_is_zero(g->coeffs + 1)); + fmpq_poly_set_coeff_ui(g, 0, 0); + n = n_randint(state, 50); + + fmpq_poly_revert_series(f, g, n); + fmpq_poly_revert_series(g, g, n); + + result = (fmpq_poly_equal(f, g)); + if (!result) + { + flint_printf("FAIL (aliasing):\n"); + fmpq_poly_print(f), flint_printf("\n\n"); + fmpq_poly_print(g), flint_printf("\n\n"); + abort(); + } + + fmpq_poly_clear(f); + fmpq_poly_clear(g); + } + + /* Check f(f^(-1)) = id */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + fmpq_poly_t f, g, h; + slong n; + + fmpq_poly_init(f); + fmpq_poly_init(g); + fmpq_poly_init(h); + do { + if (n_randint(state, 20) == 0) + fmpq_poly_randtest(g, state, + n_randint(state, 50), 1); + else + fmpq_poly_randtest(g, state, + n_randint(state, 50), 1+n_randint(state,100)); + } while (fmpq_poly_length(g) < 2 || fmpz_is_zero(g->coeffs + 1)); + fmpq_poly_set_coeff_ui(g, 0, 0); + n = n_randint(state, 50); + + fmpq_poly_revert_series(f, g, n); + fmpq_poly_compose_series(h, g, f, n); + + result = ((n <= 1 && fmpq_poly_is_zero(h)) || + (h->length == 2 && fmpz_is_zero(h->coeffs + 0) && + fmpz_is_one(h->coeffs + 1))); + if (!result) + { + flint_printf("FAIL (comparison):\n"); + fmpq_poly_print(f), flint_printf("\n\n"); + fmpq_poly_print(g), flint_printf("\n\n"); + fmpq_poly_print(h), flint_printf("\n\n"); + abort(); + } + + fmpq_poly_clear(f); + fmpq_poly_clear(g); + fmpq_poly_clear(h); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-revert_series_lagrange.c b/external/flint-2.4.3/fmpq_poly/test/t-revert_series_lagrange.c new file mode 100644 index 0000000..019b484 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-revert_series_lagrange.c @@ -0,0 +1,121 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("revert_series_lagrange...."); + fflush(stdout); + + + + /* Check aliasing */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + fmpq_poly_t f, g; + slong n; + + fmpq_poly_init(f); + fmpq_poly_init(g); + do { + fmpq_poly_randtest(g, state, n_randint(state, 50), 1+n_randint(state,100)); + } while (fmpq_poly_length(g) < 2 || fmpz_is_zero(g->coeffs + 1)); + fmpq_poly_set_coeff_ui(g, 0, 0); + n = n_randint(state, 50); + + fmpq_poly_revert_series_lagrange(f, g, n); + fmpq_poly_revert_series_lagrange(g, g, n); + + result = (fmpq_poly_equal(f, g)); + if (!result) + { + flint_printf("FAIL (aliasing):\n"); + fmpq_poly_print(f), flint_printf("\n\n"); + fmpq_poly_print(g), flint_printf("\n\n"); + abort(); + } + + fmpq_poly_clear(f); + fmpq_poly_clear(g); + } + + /* Check f(f^(-1)) = id */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + fmpq_poly_t f, g, h; + slong n; + + fmpq_poly_init(f); + fmpq_poly_init(g); + fmpq_poly_init(h); + do { + if (n_randint(state, 20) == 0) + fmpq_poly_randtest(g, state, + n_randint(state, 50), 1); + else + fmpq_poly_randtest(g, state, + n_randint(state, 50), 1+n_randint(state,100)); + } while (fmpq_poly_length(g) < 2 || fmpz_is_zero(g->coeffs + 1)); + fmpq_poly_set_coeff_ui(g, 0, 0); + n = n_randint(state, 50); + + fmpq_poly_revert_series_lagrange(f, g, n); + fmpq_poly_compose_series(h, g, f, n); + + result = ((n <= 1 && fmpq_poly_is_zero(h)) || + (h->length == 2 && fmpz_is_zero(h->coeffs + 0) && + fmpz_is_one(h->coeffs + 1))); + if (!result) + { + flint_printf("FAIL (comparison):\n"); + fmpq_poly_print(f), flint_printf("\n\n"); + fmpq_poly_print(g), flint_printf("\n\n"); + fmpq_poly_print(h), flint_printf("\n\n"); + abort(); + } + + fmpq_poly_clear(f); + fmpq_poly_clear(g); + fmpq_poly_clear(h); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-revert_series_lagrange_fast.c b/external/flint-2.4.3/fmpq_poly/test/t-revert_series_lagrange_fast.c new file mode 100644 index 0000000..8ccead4 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-revert_series_lagrange_fast.c @@ -0,0 +1,121 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("revert_series_lagrange_fast...."); + fflush(stdout); + + + + /* Check aliasing */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + fmpq_poly_t f, g; + slong n; + + fmpq_poly_init(f); + fmpq_poly_init(g); + do { + fmpq_poly_randtest(g, state, n_randint(state, 50), 1+n_randint(state,100)); + } while (fmpq_poly_length(g) < 2 || fmpz_is_zero(g->coeffs + 1)); + fmpq_poly_set_coeff_ui(g, 0, 0); + n = n_randint(state, 50); + + fmpq_poly_revert_series_lagrange_fast(f, g, n); + fmpq_poly_revert_series_lagrange_fast(g, g, n); + + result = (fmpq_poly_equal(f, g)); + if (!result) + { + flint_printf("FAIL (aliasing):\n"); + fmpq_poly_print(f), flint_printf("\n\n"); + fmpq_poly_print(g), flint_printf("\n\n"); + abort(); + } + + fmpq_poly_clear(f); + fmpq_poly_clear(g); + } + + /* Check f(f^(-1)) = id */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + fmpq_poly_t f, g, h; + slong n; + + fmpq_poly_init(f); + fmpq_poly_init(g); + fmpq_poly_init(h); + do { + if (n_randint(state, 20) == 0) + fmpq_poly_randtest(g, state, + n_randint(state, 50), 1); + else + fmpq_poly_randtest(g, state, + n_randint(state, 50), 1+n_randint(state,100)); + } while (fmpq_poly_length(g) < 2 || fmpz_is_zero(g->coeffs + 1)); + fmpq_poly_set_coeff_ui(g, 0, 0); + n = n_randint(state, 50); + + fmpq_poly_revert_series_lagrange_fast(f, g, n); + fmpq_poly_compose_series(h, g, f, n); + + result = ((n <= 1 && fmpq_poly_is_zero(h)) || + (h->length == 2 && fmpz_is_zero(h->coeffs + 0) && + fmpz_is_one(h->coeffs + 1))); + if (!result) + { + flint_printf("FAIL (comparison):\n"); + fmpq_poly_print(f), flint_printf("\n\n"); + fmpq_poly_print(g), flint_printf("\n\n"); + fmpq_poly_print(h), flint_printf("\n\n"); + abort(); + } + + fmpq_poly_clear(f); + fmpq_poly_clear(g); + fmpq_poly_clear(h); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-revert_series_newton.c b/external/flint-2.4.3/fmpq_poly/test/t-revert_series_newton.c new file mode 100644 index 0000000..34e9a68 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-revert_series_newton.c @@ -0,0 +1,121 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("revert_series_newton...."); + fflush(stdout); + + + + /* Check aliasing */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + fmpq_poly_t f, g; + slong n; + + fmpq_poly_init(f); + fmpq_poly_init(g); + do { + fmpq_poly_randtest(g, state, n_randint(state, 50), 1+n_randint(state,100)); + } while (fmpq_poly_length(g) < 2 || fmpz_is_zero(g->coeffs + 1)); + fmpq_poly_set_coeff_ui(g, 0, 0); + n = n_randint(state, 50); + + fmpq_poly_revert_series_newton(f, g, n); + fmpq_poly_revert_series_newton(g, g, n); + + result = (fmpq_poly_equal(f, g)); + if (!result) + { + flint_printf("FAIL (aliasing):\n"); + fmpq_poly_print(f), flint_printf("\n\n"); + fmpq_poly_print(g), flint_printf("\n\n"); + abort(); + } + + fmpq_poly_clear(f); + fmpq_poly_clear(g); + } + + /* Check f(f^(-1)) = id */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + fmpq_poly_t f, g, h; + slong n; + + fmpq_poly_init(f); + fmpq_poly_init(g); + fmpq_poly_init(h); + do { + if (n_randint(state, 20) == 0) + fmpq_poly_randtest(g, state, + n_randint(state, 50), 1); + else + fmpq_poly_randtest(g, state, + n_randint(state, 50), 1+n_randint(state,100)); + } while (fmpq_poly_length(g) < 2 || fmpz_is_zero(g->coeffs + 1)); + fmpq_poly_set_coeff_ui(g, 0, 0); + n = n_randint(state, 50); + + fmpq_poly_revert_series_newton(f, g, n); + fmpq_poly_compose_series(h, g, f, n); + + result = ((n <= 1 && fmpq_poly_is_zero(h)) || + (h->length == 2 && fmpz_is_zero(h->coeffs + 0) && + fmpz_is_one(h->coeffs + 1))); + if (!result) + { + flint_printf("FAIL (comparison):\n"); + fmpq_poly_print(f), flint_printf("\n\n"); + fmpq_poly_print(g), flint_printf("\n\n"); + fmpq_poly_print(h), flint_printf("\n\n"); + abort(); + } + + fmpq_poly_clear(f); + fmpq_poly_clear(g); + fmpq_poly_clear(h); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-scalar_div_fmpq.c b/external/flint-2.4.3/fmpq_poly/test/t-scalar_div_fmpq.c new file mode 100644 index 0000000..488daa1 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-scalar_div_fmpq.c @@ -0,0 +1,176 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "long_extras.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + ulong cflags = UWORD(0); + FLINT_TEST_INIT(state); + + flint_printf("scalar_div_fmpq...."); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b; + fmpq_t z; + + fmpq_init(z); + fmpq_randtest_not_zero(z, state, 100); + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_randtest(a, state, n_randint(state, 100), 200); + + fmpq_poly_scalar_div_fmpq(b, a, z); + fmpq_poly_scalar_div_fmpq(a, a, z); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(b) ? 0 : 2; + result = (fmpq_poly_equal(a, b) && !cflags); + if (!result) + { + flint_printf("FAIL (aliasing):\n\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + fmpq_print(z), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_clear(z); + fmpq_poly_clear(a); + fmpq_poly_clear(b); + } + + /* Check that (a / n1) / n2 == a / (n1 * n2) */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, lhs, rhs; + fmpq_t z1, z2, z; + + fmpq_init(z1); + fmpq_init(z2); + fmpq_init(z); + + fmpq_randtest_not_zero(z1, state, 100); + fmpq_randtest_not_zero(z2, state, 100); + fmpq_mul(z, z1, z2); + + fmpq_poly_init(a); + fmpq_poly_init(lhs); + fmpq_poly_init(rhs); + fmpq_poly_randtest(a, state, n_randint(state, 100), 200); + + fmpq_poly_scalar_div_fmpq(lhs, a, z1); + fmpq_poly_scalar_div_fmpq(lhs, lhs, z2); + fmpq_poly_scalar_div_fmpq(rhs, a, z); + + cflags |= fmpq_poly_is_canonical(lhs) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(rhs) ? 0 : 2; + result = (fmpq_poly_equal(lhs, rhs) && !cflags); + if (!result) + { + flint_printf("FAIL (a / n1 / n2):\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_print(z1), flint_printf("\n\n"); + fmpq_print(z2), flint_printf("\n\n"); + fmpq_print(z), flint_printf("\n\n"); + fmpq_poly_debug(lhs), flint_printf("\n\n"); + fmpq_poly_debug(rhs), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_clear(z1); + fmpq_clear(z2); + fmpq_clear(z); + fmpq_poly_clear(a); + fmpq_poly_clear(lhs); + fmpq_poly_clear(rhs); + } + + /* Check that (a + b) / n == a/n + b/n */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, lhs, rhs; + fmpq_t z; + + fmpq_init(z); + fmpq_randtest_not_zero(z, state, 100); + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(lhs); + fmpq_poly_init(rhs); + fmpq_poly_randtest(a, state, n_randint(state, 100), 200); + fmpq_poly_randtest(b, state, n_randint(state, 100), 200); + + fmpq_poly_scalar_div_fmpq(lhs, a, z); + fmpq_poly_scalar_div_fmpq(rhs, b, z); + fmpq_poly_add(rhs, lhs, rhs); + fmpq_poly_add(lhs, a, b); + fmpq_poly_scalar_div_fmpq(lhs, lhs, z); + + cflags |= fmpq_poly_is_canonical(lhs) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(rhs) ? 0 : 2; + result = (fmpq_poly_equal(lhs, rhs) && !cflags); + if (!result) + { + flint_printf("FAIL ((a + b) / n):\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + fmpq_print(z), flint_printf("\n\n"); + fmpq_poly_debug(lhs), flint_printf("\n\n"); + fmpq_poly_debug(rhs), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_clear(z); + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(lhs); + fmpq_poly_clear(rhs); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-scalar_div_fmpz.c b/external/flint-2.4.3/fmpq_poly/test/t-scalar_div_fmpz.c new file mode 100644 index 0000000..da24ac7 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-scalar_div_fmpz.c @@ -0,0 +1,216 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "long_extras.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + ulong cflags = UWORD(0); + + FLINT_TEST_INIT(state); + + flint_printf("scalar_div_fmpz...."); + fflush(stdout); + + /* Check aliasing of a and b */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b; + fmpz_t n; + + fmpz_init(n); + fmpz_randtest_not_zero(n, state, 200); + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_randtest(a, state, n_randint(state, 100), 200); + + fmpq_poly_scalar_div_fmpz(b, a, n); + fmpq_poly_scalar_div_fmpz(a, a, n); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(b) ? 0 : 2; + result = (fmpq_poly_equal(a, b) && !cflags); + if (!result) + { + flint_printf("FAIL (aliasing):\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + fmpz_print(n); + abort(); + } + + fmpz_clear(n); + fmpq_poly_clear(a); + fmpq_poly_clear(b); + } + + /* Compare with fmpq_poly_scalar_mul_si */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, c; + fmpz_t n1; + slong n; + + n = z_randtest_not_zero(state); + fmpz_init(n1); + fmpz_set_si(n1, n); + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(c); + fmpq_poly_randtest(a, state, n_randint(state, 100), 200); + + fmpq_poly_scalar_div_fmpz(b, a, n1); + fmpq_poly_scalar_div_si(c, a, n); + + cflags |= fmpq_poly_is_canonical(b) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(c) ? 0 : 2; + result = (fmpq_poly_equal(b, c) && !cflags); + if (!result) + { + flint_printf("FAIL (comparison with _si):\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpz_print(n1), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + fmpq_poly_debug(c), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpz_clear(n1); + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(c); + } + + /* Check that (a / n1) / n2 == a / (n1 * n2) */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, lhs, rhs; + fmpz_t n1, n2, n; + + fmpz_init(n1); + fmpz_init(n2); + fmpz_init(n); + + fmpz_randtest_not_zero(n1, state, 100); + fmpz_randtest_not_zero(n2, state, 100); + fmpz_mul(n, n1, n2); + + fmpq_poly_init(a); + fmpq_poly_init(lhs); + fmpq_poly_init(rhs); + fmpq_poly_randtest(a, state, n_randint(state, 100), 200); + + fmpq_poly_scalar_div_fmpz(lhs, a, n1); + fmpq_poly_scalar_div_fmpz(lhs, lhs, n2); + fmpq_poly_scalar_div_fmpz(rhs, a, n); + + cflags |= fmpq_poly_is_canonical(lhs) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(rhs) ? 0 : 2; + result = (fmpq_poly_equal(lhs, rhs) && !cflags); + if (!result) + { + flint_printf("FAIL (a / n1 / n2):\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpz_print(n1), flint_printf("\n\n"); + fmpz_print(n2), flint_printf("\n\n"); + fmpz_print(n), flint_printf("\n\n"); + fmpq_poly_debug(lhs), flint_printf("\n\n"); + fmpq_poly_debug(rhs), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpz_clear(n1); + fmpz_clear(n2); + fmpz_clear(n); + fmpq_poly_clear(a); + fmpq_poly_clear(lhs); + fmpq_poly_clear(rhs); + } + + /* Check that (a + b) / n == a/n + b/n */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, lhs, rhs; + fmpz_t n; + + fmpz_init(n); + + fmpz_randtest_not_zero(n, state, 100); + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(lhs); + fmpq_poly_init(rhs); + fmpq_poly_randtest(a, state, n_randint(state, 100), 200); + fmpq_poly_randtest(b, state, n_randint(state, 100), 200); + + fmpq_poly_scalar_div_fmpz(lhs, a, n); + fmpq_poly_scalar_div_fmpz(rhs, b, n); + fmpq_poly_add(rhs, lhs, rhs); + fmpq_poly_add(lhs, a, b); + fmpq_poly_scalar_div_fmpz(lhs, lhs, n); + + cflags |= fmpq_poly_is_canonical(lhs) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(rhs) ? 0 : 2; + result = (fmpq_poly_equal(lhs, rhs) && !cflags); + if (!result) + { + flint_printf("FAIL ((a + b) / n):\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + fmpz_print(n), flint_printf("\n\n"); + fmpq_poly_debug(lhs), flint_printf("\n\n"); + fmpq_poly_debug(rhs), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpz_clear(n); + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(lhs); + fmpq_poly_clear(rhs); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-scalar_div_mpq.c b/external/flint-2.4.3/fmpq_poly/test/t-scalar_div_mpq.c new file mode 100644 index 0000000..8b043a0 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-scalar_div_mpq.c @@ -0,0 +1,208 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "long_extras.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + ulong cflags = UWORD(0); + FLINT_TEST_INIT(state); + + flint_printf("scalar_div_mpq...."); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b; + fmpz_t r, s; + mpq_t z; + + mpq_init(z); + fmpz_init(r); + fmpz_init(s); + fmpz_randtest_not_zero(r, state, 100); + fmpz_randtest_not_zero(s, state, 100); + fmpz_get_mpz(mpq_numref(z), r); + fmpz_get_mpz(mpq_denref(z), s); + mpq_canonicalize(z); + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_randtest(a, state, n_randint(state, 100), 200); + + fmpq_poly_scalar_div_mpq(b, a, z); + fmpq_poly_scalar_div_mpq(a, a, z); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(b) ? 0 : 2; + result = (fmpq_poly_equal(a, b) && !cflags); + if (!result) + { + flint_printf("FAIL (aliasing):\n\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + gmp_printf("z = %Qd\n\n", z); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + mpq_clear(z); + fmpz_clear(r); + fmpz_clear(s); + fmpq_poly_clear(a); + fmpq_poly_clear(b); + } + + /* Check that (a / n1) / n2 == a / (n1 * n2) */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, lhs, rhs; + fmpz_t r, s; + mpq_t z1, z2, z; + + fmpz_init(r); + fmpz_init(s); + mpq_init(z1); + mpq_init(z2); + mpq_init(z); + + fmpz_randtest_not_zero(r, state, 100); + fmpz_randtest_not_zero(s, state, 100); + fmpz_get_mpz(mpq_numref(z1), r); + fmpz_get_mpz(mpq_denref(z1), s); + mpq_canonicalize(z1); + fmpz_randtest_not_zero(r, state, 100); + fmpz_randtest_not_zero(s, state, 100); + fmpz_get_mpz(mpq_numref(z2), r); + fmpz_get_mpz(mpq_denref(z2), s); + mpq_canonicalize(z2); + mpq_mul(z, z1, z2); + + fmpq_poly_init(a); + fmpq_poly_init(lhs); + fmpq_poly_init(rhs); + fmpq_poly_randtest(a, state, n_randint(state, 100), 200); + + fmpq_poly_scalar_div_mpq(lhs, a, z1); + fmpq_poly_scalar_div_mpq(lhs, lhs, z2); + fmpq_poly_scalar_div_mpq(rhs, a, z); + + cflags |= fmpq_poly_is_canonical(lhs) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(rhs) ? 0 : 2; + result = (fmpq_poly_equal(lhs, rhs) && !cflags); + if (!result) + { + flint_printf("FAIL (a / n1 / n2):\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + gmp_printf("z1 = %Qd\n\n", z1); + gmp_printf("z2 = %Qd\n\n", z2); + gmp_printf("z = %Qd\n\n", z); + fmpq_poly_debug(lhs), flint_printf("\n\n"); + fmpq_poly_debug(rhs), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + mpq_clear(z1); + mpq_clear(z2); + mpq_clear(z); + fmpz_clear(r); + fmpz_clear(s); + fmpq_poly_clear(a); + fmpq_poly_clear(lhs); + fmpq_poly_clear(rhs); + } + + /* Check that (a + b) / n == a/n + b/n */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, lhs, rhs; + fmpz_t r, s; + mpq_t z; + + fmpz_init(r); + fmpz_init(s); + mpq_init(z); + + fmpz_randtest_not_zero(r, state, 100); + fmpz_randtest_not_zero(s, state, 100); + fmpz_get_mpz(mpq_numref(z), r); + fmpz_get_mpz(mpq_denref(z), s); + mpq_canonicalize(z); + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(lhs); + fmpq_poly_init(rhs); + fmpq_poly_randtest(a, state, n_randint(state, 100), 200); + fmpq_poly_randtest(b, state, n_randint(state, 100), 200); + + fmpq_poly_scalar_div_mpq(lhs, a, z); + fmpq_poly_scalar_div_mpq(rhs, b, z); + fmpq_poly_add(rhs, lhs, rhs); + fmpq_poly_add(lhs, a, b); + fmpq_poly_scalar_div_mpq(lhs, lhs, z); + + cflags |= fmpq_poly_is_canonical(lhs) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(rhs) ? 0 : 2; + result = (fmpq_poly_equal(lhs, rhs) && !cflags); + if (!result) + { + flint_printf("FAIL ((a + b) / n):\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + gmp_printf("z = %Qd\n\n", z); + fmpq_poly_debug(lhs), flint_printf("\n\n"); + fmpq_poly_debug(rhs), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + mpq_clear(z); + fmpz_clear(r); + fmpz_clear(s); + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(lhs); + fmpq_poly_clear(rhs); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-scalar_div_mpz.c b/external/flint-2.4.3/fmpq_poly/test/t-scalar_div_mpz.c new file mode 100644 index 0000000..ce8499d --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-scalar_div_mpz.c @@ -0,0 +1,230 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "long_extras.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + ulong cflags = UWORD(0); + + FLINT_TEST_INIT(state); + + flint_printf("scalar_div_mpz...."); + fflush(stdout); + + /* Check aliasing of a and b */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b; + fmpz_t n; + mpz_t m; + + fmpz_init(n); + mpz_init(m); + fmpz_randtest_not_zero(n, state, 200); + fmpz_get_mpz(m, n); + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_randtest(a, state, n_randint(state, 100), 200); + + fmpq_poly_scalar_div_mpz(b, a, m); + fmpq_poly_scalar_div_mpz(a, a, m); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(b) ? 0 : 2; + result = (fmpq_poly_equal(a, b) && !cflags); + if (!result) + { + flint_printf("FAIL (aliasing):\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + fmpz_print(n); + abort(); + } + + fmpz_clear(n); + mpz_clear(m); + fmpq_poly_clear(a); + fmpq_poly_clear(b); + } + + /* Compare with fmpq_poly_scalar_mul_si */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, c; + mpz_t n1; + slong n; + + n = z_randtest_not_zero(state); + mpz_init(n1); + flint_mpz_set_si(n1, n); + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(c); + fmpq_poly_randtest(a, state, n_randint(state, 100), 200); + + fmpq_poly_scalar_div_mpz(b, a, n1); + fmpq_poly_scalar_div_si(c, a, n); + + cflags |= fmpq_poly_is_canonical(b) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(c) ? 0 : 2; + result = (fmpq_poly_equal(b, c) && !cflags); + if (!result) + { + flint_printf("FAIL (comparison with _si):\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + flint_printf("%wd", n), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + fmpq_poly_debug(c), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + mpz_clear(n1); + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(c); + } + + /* Check that (a / n1) / n2 == a / (n1 * n2) */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, lhs, rhs; + fmpz_t n1, n2; + mpz_t m1, m2, m; + + fmpz_init(n1); + fmpz_init(n2); + mpz_init(m1); + mpz_init(m2); + mpz_init(m); + + fmpz_randtest_not_zero(n1, state, 100); + fmpz_randtest_not_zero(n2, state, 100); + fmpz_get_mpz(m1, n1); + fmpz_get_mpz(m2, n2); + mpz_mul(m, m1, m2); + + fmpq_poly_init(a); + fmpq_poly_init(lhs); + fmpq_poly_init(rhs); + fmpq_poly_randtest(a, state, n_randint(state, 100), 200); + + fmpq_poly_scalar_div_mpz(lhs, a, m1); + fmpq_poly_scalar_div_mpz(lhs, lhs, m2); + fmpq_poly_scalar_div_mpz(rhs, a, m); + + cflags |= fmpq_poly_is_canonical(lhs) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(rhs) ? 0 : 2; + result = (fmpq_poly_equal(lhs, rhs) && !cflags); + if (!result) + { + flint_printf("FAIL (a / n1 / n2):\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpz_print(n1), flint_printf("\n\n"); + fmpz_print(n2), flint_printf("\n\n"); + fmpq_poly_debug(lhs), flint_printf("\n\n"); + fmpq_poly_debug(rhs), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpz_clear(n1); + fmpz_clear(n2); + mpz_clear(m1); + mpz_clear(m2); + mpz_clear(m); + fmpq_poly_clear(a); + fmpq_poly_clear(lhs); + fmpq_poly_clear(rhs); + } + + /* Check that (a + b) / n == a/n + b/n */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, lhs, rhs; + fmpz_t n; + mpz_t m; + + fmpz_init(n); + mpz_init(m); + + fmpz_randtest_not_zero(n, state, 100); + fmpz_get_mpz(m, n); + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(lhs); + fmpq_poly_init(rhs); + fmpq_poly_randtest(a, state, n_randint(state, 100), 200); + fmpq_poly_randtest(b, state, n_randint(state, 100), 200); + + fmpq_poly_scalar_div_mpz(lhs, a, m); + fmpq_poly_scalar_div_mpz(rhs, b, m); + fmpq_poly_add(rhs, lhs, rhs); + fmpq_poly_add(lhs, a, b); + fmpq_poly_scalar_div_mpz(lhs, lhs, m); + + cflags |= fmpq_poly_is_canonical(lhs) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(rhs) ? 0 : 2; + result = (fmpq_poly_equal(lhs, rhs) && !cflags); + if (!result) + { + flint_printf("FAIL ((a + b) / n):\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + fmpz_print(n), flint_printf("\n\n"); + fmpq_poly_debug(lhs), flint_printf("\n\n"); + fmpq_poly_debug(rhs), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpz_clear(n); + mpz_clear(m); + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(lhs); + fmpq_poly_clear(rhs); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-scalar_div_si.c b/external/flint-2.4.3/fmpq_poly/test/t-scalar_div_si.c new file mode 100644 index 0000000..e808984 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-scalar_div_si.c @@ -0,0 +1,160 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include + +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "long_extras.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + ulong cflags = UWORD(0); + + FLINT_TEST_INIT(state); + + flint_printf("scalar_div_si...."); + fflush(stdout); + + /* Check aliasing of a and b */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b; + slong n; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_randtest(a, state, n_randint(state, 100), 200); + n = z_randtest_not_zero(state); + + fmpq_poly_scalar_div_si(b, a, n); + fmpq_poly_scalar_div_si(a, a, n); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(b) ? 0 : 2; + result = (fmpq_poly_equal(a, b) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + } + + /* Compare with fmpq_poly_scalar_div_ui */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b; + ulong n; + + n = n_randtest_not_zero(state); + if (n > WORD_MAX) + n >>= 1; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_randtest(a, state, n_randint(state, 100), 200); + + fmpq_poly_scalar_div_ui(b, a, n); + fmpq_poly_scalar_div_si(a, a, n); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(b) ? 0 : 2; + result = (fmpq_poly_equal(a, b) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + } + + /* Check (a / n1) / n2 == a / (n1 * n2) */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, c; + slong n1, n2; + ulong m; + + while ((n1 = (slong) n_randbits(state, FLINT_BITS / 2)) == 0) ; + while ((n2 = (slong) n_randbits(state, FLINT_BITS / 2 - 1)) == 0) ; + + m = n_randlimb(state); + if (m & UWORD(1)) + n1 = -n1; + if (m & UWORD(2)) + n2 = -n2; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(c); + fmpq_poly_randtest(a, state, n_randint(state, 100), 200); + + fmpq_poly_scalar_div_si(b, a, n1); + fmpq_poly_scalar_div_si(c, b, n2); + fmpq_poly_scalar_div_si(b, a, n1 * n2); + + cflags |= fmpq_poly_is_canonical(b) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(c) ? 0 : 2; + result = (fmpq_poly_equal(b, c) && !cflags); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("n1 = %wu, n2 = %wu:\n\n", n1, n2); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + fmpq_poly_debug(c), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-scalar_div_ui.c b/external/flint-2.4.3/fmpq_poly/test/t-scalar_div_ui.c new file mode 100644 index 0000000..b992d5a --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-scalar_div_ui.c @@ -0,0 +1,118 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + ulong cflags = UWORD(0); + + FLINT_TEST_INIT(state); + + flint_printf("scalar_div_ui...."); + fflush(stdout); + + /* Check aliasing of a and b */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b; + ulong n = n_randtest_not_zero(state); + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_randtest(a, state, n_randint(state, 100), 200); + + fmpq_poly_scalar_div_ui(b, a, n); + fmpq_poly_scalar_div_ui(a, a, n); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(b) ? 0 : 2; + result = (fmpq_poly_equal(a, b) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + } + + /* Check (a / n1) / n2 = a / (n1 * n2) */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, c; + ulong n1 = n_randbits(state, FLINT_BITS / 2); + ulong n2 = n_randbits(state, FLINT_BITS / 2); + if (n1 == UWORD(0)) + n1 = UWORD(1); + if (n2 == UWORD(0)) + n2 = UWORD(1); + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(c); + fmpq_poly_randtest(a, state, n_randint(state, 100), 200); + + fmpq_poly_scalar_div_ui(b, a, n1); + fmpq_poly_scalar_div_ui(c, b, n2); + fmpq_poly_scalar_div_ui(b, a, n1 * n2); + + cflags |= fmpq_poly_is_canonical(b) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(c) ? 0 : 2; + result = (fmpq_poly_equal(b, c) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf(" n1 = %wu, n2 = %wu:\n\n", n1, n2); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + fmpq_poly_debug(c), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-scalar_mul_fmpq.c b/external/flint-2.4.3/fmpq_poly/test/t-scalar_mul_fmpq.c new file mode 100644 index 0000000..9d3c0f0 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-scalar_mul_fmpq.c @@ -0,0 +1,179 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "long_extras.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + ulong cflags = UWORD(0); + FLINT_TEST_INIT(state); + + flint_printf("scalar_mul_fmpq...."); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b; + fmpq_t z; + + fmpq_init(z); + fmpq_randtest(z, state, 100); + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_randtest(a, state, n_randint(state, 100), 200); + + fmpq_poly_scalar_mul_fmpq(b, a, z); + fmpq_poly_scalar_mul_fmpq(a, a, z); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(b) ? 0 : 2; + result = (fmpq_poly_equal(a, b) && !cflags); + if (!result) + { + flint_printf("FAIL (aliasing):\n\n"); + flint_printf("a = "), fmpq_poly_debug(a), flint_printf("\n\n"); + flint_printf("b = "), fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("z = "), fmpq_print(z), flint_printf("\n\n"); + gmp_printf("z = %Qd\n\n", z); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_clear(z); + fmpq_poly_clear(a); + fmpq_poly_clear(b); + } + + /* Check that (a * n1) * n2 == a * (n1 * n2) */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, lhs, rhs; + fmpq_t z1, z2, z; + + fmpq_init(z1); + fmpq_init(z2); + fmpq_init(z); + + fmpq_randtest(z1, state, 100); + fmpq_randtest(z2, state, 100); + + fmpq_mul(z, z1, z2); + + fmpq_poly_init(a); + fmpq_poly_init(lhs); + fmpq_poly_init(rhs); + fmpq_poly_randtest(a, state, n_randint(state, 100), 200); + + fmpq_poly_scalar_mul_fmpq(lhs, a, z1); + fmpq_poly_scalar_mul_fmpq(lhs, lhs, z2); + fmpq_poly_scalar_mul_fmpq(rhs, a, z); + + cflags |= fmpq_poly_is_canonical(lhs) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(rhs) ? 0 : 2; + result = (fmpq_poly_equal(lhs, rhs) && !cflags); + if (!result) + { + flint_printf("FAIL (a * n1 * n2):\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + flint_printf("z1 = "), fmpq_print(z1), flint_printf("\n\n"); + flint_printf("z2 = "), fmpq_print(z2), flint_printf("\n\n"); + flint_printf("z = "), fmpq_print(z), flint_printf("\n\n"); + fmpq_poly_debug(lhs), flint_printf("\n\n"); + fmpq_poly_debug(rhs), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_clear(z1); + fmpq_clear(z2); + fmpq_clear(z); + fmpq_poly_clear(a); + fmpq_poly_clear(lhs); + fmpq_poly_clear(rhs); + } + + /* Check that (a + b) * n == a*n + b*n */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, lhs, rhs; + fmpq_t z; + + fmpq_init(z); + + fmpq_randtest(z, state, 100); + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(lhs); + fmpq_poly_init(rhs); + fmpq_poly_randtest(a, state, n_randint(state, 100), 200); + fmpq_poly_randtest(b, state, n_randint(state, 100), 200); + + fmpq_poly_scalar_mul_fmpq(lhs, a, z); + fmpq_poly_scalar_mul_fmpq(rhs, b, z); + fmpq_poly_add(rhs, lhs, rhs); + fmpq_poly_add(lhs, a, b); + fmpq_poly_scalar_mul_fmpq(lhs, lhs, z); + + cflags |= fmpq_poly_is_canonical(lhs) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(rhs) ? 0 : 2; + result = (fmpq_poly_equal(lhs, rhs) && !cflags); + if (!result) + { + flint_printf("FAIL ((a + b) / n):\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("z = "), fmpq_print(z), flint_printf("\n\n"); + fmpq_poly_debug(lhs), flint_printf("\n\n"); + fmpq_poly_debug(rhs), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_clear(z); + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(lhs); + fmpq_poly_clear(rhs); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-scalar_mul_fmpz.c b/external/flint-2.4.3/fmpq_poly/test/t-scalar_mul_fmpz.c new file mode 100644 index 0000000..1c92dc5 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-scalar_mul_fmpz.c @@ -0,0 +1,160 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "long_extras.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + ulong cflags = UWORD(0); + + FLINT_TEST_INIT(state); + + flint_printf("scalar_mul_fmpz...."); + fflush(stdout); + + /* Check aliasing of a and b */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b; + fmpz_t n; + + fmpz_init(n); + fmpz_randtest(n, state, 200); + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_randtest(a, state, n_randint(state, 100), n_randint(state, 200)); + + fmpq_poly_scalar_mul_fmpz(b, a, n); + fmpq_poly_scalar_mul_fmpz(a, a, n); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(b) ? 0 : 2; + result = (fmpq_poly_equal(a, b) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpz_clear(n); + fmpq_poly_clear(a); + fmpq_poly_clear(b); + } + + /* Check that n (a + b) == na + nb */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, lhs, rhs; + fmpz_t n; + + fmpz_init(n); + fmpz_randtest(n, state, 200); + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(lhs); + fmpq_poly_init(rhs); + fmpq_poly_randtest(a, state, n_randint(state, 100), n_randint(state, 200)); + fmpq_poly_randtest(b, state, n_randint(state, 100), n_randint(state, 200)); + + fmpq_poly_scalar_mul_fmpz(lhs, a, n); + fmpq_poly_scalar_mul_fmpz(rhs, b, n); + fmpq_poly_add(rhs, lhs, rhs); + fmpq_poly_add(lhs, a, b); + fmpq_poly_scalar_mul_fmpz(lhs, lhs, n); + + cflags |= fmpq_poly_is_canonical(lhs) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(rhs) ? 0 : 2; + result = (fmpq_poly_equal(lhs, rhs) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpz_clear(n); + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(lhs); + fmpq_poly_clear(rhs); + } + + /* Compare with fmpq_poly_scalar_mul_si */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b; + fmpz_t n1; + slong n; + + n = z_randtest(state); + fmpz_init(n1); + fmpz_set_si(n1, n); + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_randtest(a, state, n_randint(state, 100), n_randint(state, 200)); + + fmpq_poly_scalar_mul_fmpz(b, a, n1); + fmpq_poly_scalar_mul_si(a, a, n); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(b) ? 0 : 2; + result = (fmpq_poly_equal(a, b) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpz_clear(n1); + fmpq_poly_clear(a); + fmpq_poly_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-scalar_mul_mpq.c b/external/flint-2.4.3/fmpq_poly/test/t-scalar_mul_mpq.c new file mode 100644 index 0000000..8635243 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-scalar_mul_mpq.c @@ -0,0 +1,208 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "long_extras.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + ulong cflags = UWORD(0); + FLINT_TEST_INIT(state); + + flint_printf("scalar_mul_mpq...."); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b; + fmpz_t r, s; + mpq_t z; + + mpq_init(z); + fmpz_init(r); + fmpz_init(s); + fmpz_randtest(r, state, 100); + fmpz_randtest_not_zero(s, state, 100); + fmpz_get_mpz(mpq_numref(z), r); + fmpz_get_mpz(mpq_denref(z), s); + mpq_canonicalize(z); + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_randtest(a, state, n_randint(state, 100), 200); + + fmpq_poly_scalar_mul_mpq(b, a, z); + fmpq_poly_scalar_mul_mpq(a, a, z); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(b) ? 0 : 2; + result = (fmpq_poly_equal(a, b) && !cflags); + if (!result) + { + flint_printf("FAIL (aliasing):\n\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + gmp_printf("z = %Qd\n\n", z); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + mpq_clear(z); + fmpz_clear(r); + fmpz_clear(s); + fmpq_poly_clear(a); + fmpq_poly_clear(b); + } + + /* Check that (a * n1) * n2 == a * (n1 * n2) */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, lhs, rhs; + fmpz_t r, s; + mpq_t z1, z2, z; + + fmpz_init(r); + fmpz_init(s); + mpq_init(z1); + mpq_init(z2); + mpq_init(z); + + fmpz_randtest(r, state, 100); + fmpz_randtest_not_zero(s, state, 100); + fmpz_get_mpz(mpq_numref(z1), r); + fmpz_get_mpz(mpq_denref(z1), s); + mpq_canonicalize(z1); + fmpz_randtest(r, state, 100); + fmpz_randtest_not_zero(s, state, 100); + fmpz_get_mpz(mpq_numref(z2), r); + fmpz_get_mpz(mpq_denref(z2), s); + mpq_canonicalize(z2); + mpq_mul(z, z1, z2); + + fmpq_poly_init(a); + fmpq_poly_init(lhs); + fmpq_poly_init(rhs); + fmpq_poly_randtest(a, state, n_randint(state, 100), 200); + + fmpq_poly_scalar_mul_mpq(lhs, a, z1); + fmpq_poly_scalar_mul_mpq(lhs, lhs, z2); + fmpq_poly_scalar_mul_mpq(rhs, a, z); + + cflags |= fmpq_poly_is_canonical(lhs) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(rhs) ? 0 : 2; + result = (fmpq_poly_equal(lhs, rhs) && !cflags); + if (!result) + { + flint_printf("FAIL (a * n1 * n2):\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + gmp_printf("z1 = %Qd\n\n", z1); + gmp_printf("z2 = %Qd\n\n", z2); + gmp_printf("z = %Qd\n\n", z); + fmpq_poly_debug(lhs), flint_printf("\n\n"); + fmpq_poly_debug(rhs), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + mpq_clear(z1); + mpq_clear(z2); + mpq_clear(z); + fmpz_clear(r); + fmpz_clear(s); + fmpq_poly_clear(a); + fmpq_poly_clear(lhs); + fmpq_poly_clear(rhs); + } + + /* Check that (a + b) * n == a*n + b*n */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, lhs, rhs; + fmpz_t r, s; + mpq_t z; + + fmpz_init(r); + fmpz_init(s); + mpq_init(z); + + fmpz_randtest(r, state, 100); + fmpz_randtest_not_zero(s, state, 100); + fmpz_get_mpz(mpq_numref(z), r); + fmpz_get_mpz(mpq_denref(z), s); + mpq_canonicalize(z); + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(lhs); + fmpq_poly_init(rhs); + fmpq_poly_randtest(a, state, n_randint(state, 100), 200); + fmpq_poly_randtest(b, state, n_randint(state, 100), 200); + + fmpq_poly_scalar_mul_mpq(lhs, a, z); + fmpq_poly_scalar_mul_mpq(rhs, b, z); + fmpq_poly_add(rhs, lhs, rhs); + fmpq_poly_add(lhs, a, b); + fmpq_poly_scalar_mul_mpq(lhs, lhs, z); + + cflags |= fmpq_poly_is_canonical(lhs) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(rhs) ? 0 : 2; + result = (fmpq_poly_equal(lhs, rhs) && !cflags); + if (!result) + { + flint_printf("FAIL ((a + b) / n):\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + gmp_printf("z = %Qd\n\n", z); + fmpq_poly_debug(lhs), flint_printf("\n\n"); + fmpq_poly_debug(rhs), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + mpq_clear(z); + fmpz_clear(r); + fmpz_clear(s); + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(lhs); + fmpq_poly_clear(rhs); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-scalar_mul_mpz.c b/external/flint-2.4.3/fmpq_poly/test/t-scalar_mul_mpz.c new file mode 100644 index 0000000..a0811da --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-scalar_mul_mpz.c @@ -0,0 +1,168 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "long_extras.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + ulong cflags = UWORD(0); + + FLINT_TEST_INIT(state); + + flint_printf("scalar_mul_mpz...."); + fflush(stdout); + + /* Check aliasing of a and b */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b; + fmpz_t n; + mpz_t m; + + fmpz_init(n); + mpz_init(m); + fmpz_randtest(n, state, 200); + fmpz_get_mpz(m, n); + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_randtest(a, state, n_randint(state, 100), n_randint(state, 200)); + + fmpq_poly_scalar_mul_mpz(b, a, m); + fmpq_poly_scalar_mul_mpz(a, a, m); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(b) ? 0 : 2; + result = (fmpq_poly_equal(a, b) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpz_clear(n); + mpz_clear(m); + fmpq_poly_clear(a); + fmpq_poly_clear(b); + } + + /* Check that n (a + b) == na + nb */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, lhs, rhs; + fmpz_t n; + mpz_t m; + + fmpz_init(n); + mpz_init(m); + fmpz_randtest(n, state, 200); + fmpz_get_mpz(m, n); + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(lhs); + fmpq_poly_init(rhs); + fmpq_poly_randtest(a, state, n_randint(state, 100), n_randint(state, 200)); + fmpq_poly_randtest(b, state, n_randint(state, 100), n_randint(state, 200)); + + fmpq_poly_scalar_mul_mpz(lhs, a, m); + fmpq_poly_scalar_mul_mpz(rhs, b, m); + fmpq_poly_add(rhs, lhs, rhs); + fmpq_poly_add(lhs, a, b); + fmpq_poly_scalar_mul_mpz(lhs, lhs, m); + + cflags |= fmpq_poly_is_canonical(lhs) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(rhs) ? 0 : 2; + result = (fmpq_poly_equal(lhs, rhs) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpz_clear(n); + mpz_clear(m); + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(lhs); + fmpq_poly_clear(rhs); + } + + /* Compare with fmpq_poly_scalar_mul_si */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b; + mpz_t n1; + slong n; + + n = z_randtest(state); + mpz_init(n1); + flint_mpz_set_si(n1, n); + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_randtest(a, state, n_randint(state, 100), n_randint(state, 200)); + + fmpq_poly_scalar_mul_mpz(b, a, n1); + fmpq_poly_scalar_mul_si(a, a, n); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(b) ? 0 : 2; + result = (fmpq_poly_equal(a, b) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + mpz_clear(n1); + fmpq_poly_clear(a); + fmpq_poly_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-scalar_mul_si.c b/external/flint-2.4.3/fmpq_poly/test/t-scalar_mul_si.c new file mode 100644 index 0000000..c078db8 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-scalar_mul_si.c @@ -0,0 +1,152 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "long_extras.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + ulong cflags = UWORD(0); + + FLINT_TEST_INIT(state); + + flint_printf("scalar_mul_si...."); + fflush(stdout); + + /* Check aliasing of a and b */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b; + slong n = z_randtest(state); + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_randtest(a, state, n_randint(state, 100), n_randint(state, 200)); + + fmpq_poly_scalar_mul_si(b, a, n); + fmpq_poly_scalar_mul_si(a, a, n); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(b) ? 0 : 2; + result = (fmpq_poly_equal(a, b) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + } + + /* Compare with fmpq_poly_scalar_mul_ui */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b; + ulong n = n_randbits(state, FLINT_BITS - 1); + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_randtest(a, state, n_randint(state, 100), n_randint(state, 200)); + + fmpq_poly_scalar_mul_ui(b, a, n); + fmpq_poly_scalar_mul_si(a, a, n); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(b) ? 0 : 2; + result = (fmpq_poly_equal(a, b) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + } + + /* Check n2 * (n1 a) == (n1*n2) a */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, c; + slong n1, n2; + ulong m; + + n1 = (slong) n_randbits(state, FLINT_BITS / 2); + n2 = (slong) n_randbits(state, FLINT_BITS / 2 - 1); + m = n_randlimb(state); + if (m & UWORD(1)) + n1 = -n1; + if (m & UWORD(2)) + n2 = -n2; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(c); + fmpq_poly_randtest(a, state, n_randint(state, 100), n_randint(state, 200)); + + fmpq_poly_scalar_mul_si(b, a, n1); + fmpq_poly_scalar_mul_si(c, b, n2); + fmpq_poly_scalar_mul_si(b, a, n1 * n2); + + cflags |= fmpq_poly_is_canonical(b) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(c) ? 0 : 2; + result = (fmpq_poly_equal(b, c) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("n1 = %wu, n2 = %wu:\n\n", n1, n2); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + fmpq_poly_debug(c), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-scalar_mul_ui.c b/external/flint-2.4.3/fmpq_poly/test/t-scalar_mul_ui.c new file mode 100644 index 0000000..33b9a43 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-scalar_mul_ui.c @@ -0,0 +1,154 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + ulong cflags = UWORD(0); + + FLINT_TEST_INIT(state); + + flint_printf("scalar_mul_ui...."); + fflush(stdout); + + /* Check aliasing of a and b */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b; + ulong n = n_randtest(state); + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_randtest(a, state, n_randint(state, 100), n_randint(state, 200)); + + fmpq_poly_scalar_mul_ui(b, a, n); + fmpq_poly_scalar_mul_ui(a, a, n); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(b) ? 0 : 2; + result = (fmpq_poly_equal(a, b) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + } + + /* Check that (a + b) * n == a * n + b * n */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, lhs, rhs; + ulong n = n_randtest(state); + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(lhs); + fmpq_poly_init(rhs); + fmpq_poly_randtest(a, state, n_randint(state, 100), n_randint(state, 200)); + fmpq_poly_randtest(b, state, n_randint(state, 100), n_randint(state, 200)); + + fmpq_poly_scalar_mul_ui(lhs, a, n); + fmpq_poly_scalar_mul_ui(rhs, b, n); + fmpq_poly_add(rhs, lhs, rhs); + fmpq_poly_add(lhs, a, b); + fmpq_poly_scalar_mul_ui(lhs, lhs, n); + + cflags |= fmpq_poly_is_canonical(lhs) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(rhs) ? 0 : 2; + result = (fmpq_poly_equal(lhs, rhs) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("%li\n\n", n); + fmpq_poly_debug(lhs), flint_printf("\n\n"); + fmpq_poly_debug(rhs), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(lhs); + fmpq_poly_clear(rhs); + } + + /* Check (a * n1) * n2 = a * (n1 * n2) */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, c; + ulong n1 = n_randbits(state, FLINT_BITS / 2); + ulong n2 = n_randbits(state, FLINT_BITS / 2); + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(c); + fmpq_poly_randtest(a, state, n_randint(state, 100), n_randint(state, 200)); + + fmpq_poly_scalar_mul_ui(b, a, n1); + fmpq_poly_scalar_mul_ui(c, b, n2); + fmpq_poly_scalar_mul_ui(b, a, n1 * n2); + + cflags |= fmpq_poly_is_canonical(b) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(c) ? 0 : 2; + result = (fmpq_poly_equal(b, c) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("n1 = %wu, n2 = %wu:\n\n", n1, n2); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + fmpq_poly_debug(c), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-set_array_mpq.c b/external/flint-2.4.3/fmpq_poly/test/t-set_array_mpq.c new file mode 100644 index 0000000..1f02d74 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-set_array_mpq.c @@ -0,0 +1,86 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + ulong cflags = UWORD(0); + + FLINT_TEST_INIT(state); + + flint_printf("set_array_mpq...."); + fflush(stdout); + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + slong j, n = 100; + fmpq_poly_t f, g; + mpq_t * a; + + a = (mpq_t *) flint_malloc(n * sizeof(mpq_t)); + for (j = 0; j < n; j++) + mpq_init(a[j]); + + fmpq_poly_init(f); + fmpq_poly_init(g); + fmpq_poly_randtest(f, state, n_randint(state, n), 200); + for (j = 0; j < f->length; j++) + fmpq_poly_get_coeff_mpq(a[j], f, j); + + fmpq_poly_set_array_mpq(g, (const mpq_t *) a, n); + + cflags |= fmpq_poly_is_canonical(g) ? 0 : 1; + result = (fmpq_poly_equal(f, g) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("f = "), fmpq_poly_debug(f), flint_printf("\n\n"); + flint_printf("g = "), fmpq_poly_debug(g), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(f); + fmpq_poly_clear(g); + for (j = 0; j < n; j++) + mpq_clear(a[j]); + flint_free(a); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-set_equal.c b/external/flint-2.4.3/fmpq_poly/test/t-set_equal.c new file mode 100644 index 0000000..381118e --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-set_equal.c @@ -0,0 +1,121 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("set/equal...."); + fflush(stdout); + + + + /* equal polynomials */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_randtest(a, state, n_randint(state, 100), 200); + + fmpq_poly_set(b, a); + + result = (fmpq_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpq_poly_debug(a), flint_printf("\n"); + flint_printf("alloc = %wd\nlength = %wd\n\n", a->alloc, a->length); + flint_printf("b = "), fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("alloc = %wd\nlength = %wd\n\n", b->alloc, b->length); + flint_printf("equal(a, b) = %d\n", result); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + } + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b; + slong coeff = (slong) n_randint(state, 100); + mpq_t x1, x2; + fmpz_t x1fmpz; + + mpq_init(x1); + mpq_init(x2); + fmpz_init(x1fmpz); + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_randtest(a, state, n_randint(state, 100), 200); + + fmpq_poly_set(b, a); + + fmpq_poly_get_coeff_mpq(x2, b, coeff); + do + { + fmpz_randtest(x1fmpz, state, 200); + fmpz_get_mpz(mpq_numref(x1), x1fmpz); + flint_mpz_set_si(mpq_denref(x1), 1); + } while (mpq_equal(x1, x2)); + fmpq_poly_set_coeff_mpq(b, coeff, x1); + + result = (!fmpq_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpq_poly_debug(a), flint_printf("\n"); + flint_printf("alloc = %wd\nlength = %wd\n\n", a->alloc, a->length); + flint_printf("b = "), fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("alloc = %wd\nlength = %wd\n\n", b->alloc, b->length); + flint_printf("!equal(a, b) = %d\n", result); + abort(); + } + + mpq_clear(x1); + mpq_clear(x2); + fmpz_clear(x1fmpz); + fmpq_poly_clear(a); + fmpq_poly_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-shift_left_right.c b/external/flint-2.4.3/fmpq_poly/test/t-shift_left_right.c new file mode 100644 index 0000000..77b0ec6 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-shift_left_right.c @@ -0,0 +1,142 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + ulong cflags = UWORD(0); + + FLINT_TEST_INIT(state); + + flint_printf("shift_left/right...."); + fflush(stdout); + + /* Check aliasing of a and b for left shift */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b; + slong shift = (slong) n_randint(state, 100); + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_randtest(a, state, n_randint(state, 100), 200); + + fmpq_poly_shift_left(b, a, shift); + fmpq_poly_shift_left(a, a, shift); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(b) ? 0 : 2; + result = (fmpq_poly_equal(a, b) && !cflags); + if (!result) + { + flint_printf("FAIL:\n\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + } + + /* Check aliasing of a and b for right shift */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b; + slong shift; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_randtest_not_zero(a, state, n_randint(state, 100) + 1, 200); + + shift = (slong) n_randint(state, a->length); + + fmpq_poly_shift_right(b, a, shift); + fmpq_poly_shift_right(a, a, shift); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(b) ? 0 : 2; + result = (fmpq_poly_equal(a, b) && !cflags); + if (!result) + { + flint_printf("FAIL:\n\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + } + + /* Check shift left then right does nothing */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, c; + slong shift = (slong) n_randint(state, 100); + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(c); + fmpq_poly_randtest(a, state, n_randint(state, 100), 200); + + fmpq_poly_shift_left(b, a, shift); + fmpq_poly_shift_right(c, b, shift); + + cflags |= fmpq_poly_is_canonical(b) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(c) ? 0 : 2; + result = (fmpq_poly_equal(c, a) && !cflags); + if (!result) + { + flint_printf("FAIL:\n\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + fmpq_poly_debug(c), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-sin_series.c b/external/flint-2.4.3/fmpq_poly/test/t-sin_series.c new file mode 100644 index 0000000..2a200a7 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-sin_series.c @@ -0,0 +1,120 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + ulong cflags = UWORD(0); + + FLINT_TEST_INIT(state); + + flint_printf("sin_series...."); + fflush(stdout); + + /* Check aliasing of a and c */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b; + slong n = n_randint(state, 50) + 1; + + fmpq_poly_init(a); + fmpq_poly_init(b); + + fmpq_poly_randtest_not_zero(a, state, n_randint(state, 50) + 1, 50); + fmpq_poly_set_coeff_ui(a, 0, UWORD(0)); + + fmpq_poly_canonicalise(a); + + fmpq_poly_sin_series(b, a, n); + fmpq_poly_sin_series(a, a, n); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(b) ? 0 : 2; + result = (fmpq_poly_equal(a, b) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + } + + /* Check asin(sin(a)) = a */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, sina, asinsina; + slong n = n_randint(state, 80) + 1; + + fmpq_poly_init(a); + fmpq_poly_init(sina); + fmpq_poly_init(asinsina); + + fmpq_poly_randtest_not_zero(a, state, n_randint(state, 60) + 1, 80); + fmpq_poly_set_coeff_ui(a, 0, UWORD(0)); + + fmpq_poly_sin_series(sina, a, n); + fmpq_poly_asin_series(asinsina, sina, n); + fmpq_poly_truncate(a, n); + + cflags |= fmpq_poly_is_canonical(sina) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(asinsina) ? 0 : 2; + result = (fmpq_poly_equal(asinsina, a) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpq_poly_debug(a), flint_printf("\n\n"); + flint_printf("sin(a) = "), fmpq_poly_debug(sina), flint_printf("\n\n"); + flint_printf("asin(sin(a)) = "), fmpq_poly_debug(asinsina), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(sina); + fmpq_poly_clear(asinsina); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-sinh_series.c b/external/flint-2.4.3/fmpq_poly/test/t-sinh_series.c new file mode 100644 index 0000000..a1d12ac --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-sinh_series.c @@ -0,0 +1,120 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + ulong cflags = UWORD(0); + + FLINT_TEST_INIT(state); + + flint_printf("sinh_series...."); + fflush(stdout); + + /* Check aliasing of a and c */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b; + slong n = n_randint(state, 50) + 1; + + fmpq_poly_init(a); + fmpq_poly_init(b); + + fmpq_poly_randtest_not_zero(a, state, n_randint(state, 50) + 1, 50); + fmpq_poly_set_coeff_ui(a, 0, UWORD(0)); + + fmpq_poly_canonicalise(a); + + fmpq_poly_sinh_series(b, a, n); + fmpq_poly_sinh_series(a, a, n); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(b) ? 0 : 2; + result = (fmpq_poly_equal(a, b) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + } + + /* Check asinh(sinh(a)) = a */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, sinha, asinhsinha; + slong n = n_randint(state, 80) + 1; + + fmpq_poly_init(a); + fmpq_poly_init(sinha); + fmpq_poly_init(asinhsinha); + + fmpq_poly_randtest_not_zero(a, state, n_randint(state, 60) + 1, 80); + fmpq_poly_set_coeff_ui(a, 0, UWORD(0)); + + fmpq_poly_sinh_series(sinha, a, n); + fmpq_poly_asinh_series(asinhsinha, sinha, n); + fmpq_poly_truncate(a, n); + + cflags |= fmpq_poly_is_canonical(sinha) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(asinhsinha) ? 0 : 2; + result = (fmpq_poly_equal(asinhsinha, a) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpq_poly_debug(a), flint_printf("\n\n"); + flint_printf("sinh(a) = "), fmpq_poly_debug(sinha), flint_printf("\n\n"); + flint_printf("asinh(sinh(a)) = "), fmpq_poly_debug(asinhsinha), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(sinha); + fmpq_poly_clear(asinhsinha); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-sqrt_series.c b/external/flint-2.4.3/fmpq_poly/test/t-sqrt_series.c new file mode 100644 index 0000000..07b4e13 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-sqrt_series.c @@ -0,0 +1,119 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + ulong cflags = UWORD(0); + + FLINT_TEST_INIT(state); + + flint_printf("sqrt_series...."); + fflush(stdout); + + /* Check aliasing of a and c */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b; + slong n = n_randint(state, 50) + 1; + + fmpq_poly_init(a); + fmpq_poly_init(b); + + fmpq_poly_randtest_not_zero(a, state, n_randint(state, 50) + 1, 50); + fmpq_poly_set_coeff_ui(a, 0, UWORD(1)); + + fmpq_poly_canonicalise(a); + + fmpq_poly_sqrt_series(b, a, n); + fmpq_poly_sqrt_series(a, a, n); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(b) ? 0 : 2; + result = (fmpq_poly_equal(a, b) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + } + + /* Check sqrt(a)^2 = a */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, c; + slong n = n_randint(state, 80) + 1; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(c); + + fmpq_poly_randtest_not_zero(a, state, n_randint(state, 80) + 1, 80); + fmpq_poly_set_coeff_ui(a, 0, UWORD(1)); + + fmpq_poly_sqrt_series(b, a, n); + fmpq_poly_mullow(c, b, b, n); + fmpq_poly_truncate(a, n); + + cflags |= fmpq_poly_is_canonical(b) ? 0 : 1; + result = (fmpq_poly_equal(c, a) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpq_poly_debug(a), flint_printf("\n\n"); + flint_printf("b = "), fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("c = "), fmpq_poly_debug(c), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-sub.c b/external/flint-2.4.3/fmpq_poly/test/t-sub.c new file mode 100644 index 0000000..883fa0f --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-sub.c @@ -0,0 +1,150 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + ulong cflags = UWORD(0); + + FLINT_TEST_INIT(state); + + flint_printf("sub...."); + fflush(stdout); + + /* Check a - b = a + neg(b) */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, c, d; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(c); + fmpq_poly_init(d); + fmpq_poly_randtest(a, state, n_randint(state, 100), 200); + fmpq_poly_randtest(b, state, n_randint(state, 100), 200); + + fmpq_poly_sub(c, a, b); + fmpq_poly_neg(b, b); + fmpq_poly_add(d, a, b); + + cflags |= fmpq_poly_is_canonical(c) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(d) ? 0 : 2; + result = (fmpq_poly_equal(c, d) && !cflags); + if (!result) + { + flint_printf("FAIL:\n\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + fmpq_poly_debug(c), flint_printf("\n\n"); + fmpq_poly_debug(d), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(c); + fmpq_poly_clear(d); + } + + /* Check aliasing of a and c */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, c; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(c); + fmpq_poly_randtest(a, state, n_randint(state, 100), 200); + fmpq_poly_randtest(b, state, n_randint(state, 100), 200); + + fmpq_poly_sub(c, a, b); + fmpq_poly_sub(a, a, b); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(c) ? 0 : 2; + result = (fmpq_poly_equal(a, c) && !cflags); + if (!result) + { + flint_printf("FAIL:\n\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + fmpq_poly_debug(c), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(c); + } + + /* Check aliasing of b and c */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, c; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(c); + fmpq_poly_randtest(a, state, n_randint(state, 100), 200); + fmpq_poly_randtest(b, state, n_randint(state, 100), 200); + + fmpq_poly_sub(c, a, b); + fmpq_poly_sub(b, a, b); + + cflags |= fmpq_poly_is_canonical(b) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(c) ? 0 : 2; + result = (fmpq_poly_equal(b, c) && !cflags); + if (!result) + { + flint_printf("FAIL:\n\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + fmpq_poly_debug(c), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-swap.c b/external/flint-2.4.3/fmpq_poly/test/t-swap.c new file mode 100644 index 0000000..8c04865 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-swap.c @@ -0,0 +1,78 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("swap...."); + fflush(stdout); + + + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, c; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(c); + fmpq_poly_randtest(a, state, n_randint(state, 100), 200); + fmpq_poly_randtest(b, state, n_randint(state, 100), 200); + + fmpq_poly_set(c, b); + fmpq_poly_swap(a, b); + + result = (fmpq_poly_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + fmpq_poly_debug(c), flint_printf("\n\n"); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-tan_series.c b/external/flint-2.4.3/fmpq_poly/test/t-tan_series.c new file mode 100644 index 0000000..e235539 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-tan_series.c @@ -0,0 +1,120 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + ulong cflags = UWORD(0); + + FLINT_TEST_INIT(state); + + flint_printf("tan_series...."); + fflush(stdout); + + /* Check aliasing of a and c */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b; + slong n = n_randint(state, 50) + 1; + + fmpq_poly_init(a); + fmpq_poly_init(b); + + fmpq_poly_randtest_not_zero(a, state, n_randint(state, 50) + 1, 50); + fmpq_poly_set_coeff_ui(a, 0, UWORD(0)); + + fmpq_poly_canonicalise(a); + + fmpq_poly_tan_series(b, a, n); + fmpq_poly_tan_series(a, a, n); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(b) ? 0 : 2; + result = (fmpq_poly_equal(a, b) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + } + + /* Check atan(tan(a)) = a */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, tana, atantana; /* but what is an atantana? */ + slong n = n_randint(state, 80) + 1; + + fmpq_poly_init(a); + fmpq_poly_init(tana); + fmpq_poly_init(atantana); + + fmpq_poly_randtest_not_zero(a, state, n_randint(state, 60) + 1, 80); + fmpq_poly_set_coeff_ui(a, 0, UWORD(0)); + + fmpq_poly_tan_series(tana, a, n); + fmpq_poly_atan_series(atantana, tana, n); + fmpq_poly_truncate(a, n); + + cflags |= fmpq_poly_is_canonical(tana) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(atantana) ? 0 : 2; + result = (fmpq_poly_equal(atantana, a) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpq_poly_debug(a), flint_printf("\n\n"); + flint_printf("tan(a) = "), fmpq_poly_debug(tana), flint_printf("\n\n"); + flint_printf("atan(tan(a)) = "), fmpq_poly_debug(atantana), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(tana); + fmpq_poly_clear(atantana); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-tanh_series.c b/external/flint-2.4.3/fmpq_poly/test/t-tanh_series.c new file mode 100644 index 0000000..c018baa --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-tanh_series.c @@ -0,0 +1,120 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + ulong cflags = UWORD(0); + + FLINT_TEST_INIT(state); + + flint_printf("tanh_series...."); + fflush(stdout); + + /* Check aliasing of a and c */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b; + slong n = n_randint(state, 50) + 1; + + fmpq_poly_init(a); + fmpq_poly_init(b); + + fmpq_poly_randtest_not_zero(a, state, n_randint(state, 50) + 1, 50); + fmpq_poly_set_coeff_ui(a, 0, UWORD(0)); + + fmpq_poly_canonicalise(a); + + fmpq_poly_tanh_series(b, a, n); + fmpq_poly_tanh_series(a, a, n); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(b) ? 0 : 2; + result = (fmpq_poly_equal(a, b) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + } + + /* Check atanh(tanh(a)) = a */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, tanha, atanhtanha; + slong n = n_randint(state, 80) + 1; + + fmpq_poly_init(a); + fmpq_poly_init(tanha); + fmpq_poly_init(atanhtanha); + + fmpq_poly_randtest_not_zero(a, state, n_randint(state, 60) + 1, 80); + fmpq_poly_set_coeff_ui(a, 0, UWORD(0)); + + fmpq_poly_tanh_series(tanha, a, n); + fmpq_poly_atanh_series(atanhtanha, tanha, n); + fmpq_poly_truncate(a, n); + + cflags |= fmpq_poly_is_canonical(tanha) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(atanhtanha) ? 0 : 2; + result = (fmpq_poly_equal(atanhtanha, a) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpq_poly_debug(a), flint_printf("\n\n"); + flint_printf("tanh(a) = "), fmpq_poly_debug(tanha), flint_printf("\n\n"); + flint_printf("atanh(tanh(a)) = "), fmpq_poly_debug(atanhtanha), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(tanha); + fmpq_poly_clear(atanhtanha); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/test/t-xgcd.c b/external/flint-2.4.3/fmpq_poly/test/t-xgcd.c new file mode 100644 index 0000000..1764981 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-xgcd.c @@ -0,0 +1,228 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02160-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int cflags = 0, i, result; + FLINT_TEST_INIT(state); + + flint_printf("xgcd...."); + fflush(stdout); + + + + /* Generic case, where a and b are coprime *******************************/ + + /* Verify d == s a + t b */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, d, e, f, s, t; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(d); + fmpq_poly_init(e); + fmpq_poly_init(f); + fmpq_poly_init(s); + fmpq_poly_init(t); + fmpq_poly_randtest(a, state, n_randint(state, 60), 80); + fmpq_poly_randtest(b, state, n_randint(state, 60), 80); + + fmpq_poly_xgcd(d, s, t, a, b); + fmpq_poly_mul(e, s, a); + fmpq_poly_mul(f, t, b); + fmpq_poly_add(e, e, f); + + cflags |= fmpq_poly_is_canonical(d) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(s) ? 0 : 2; + cflags |= fmpq_poly_is_canonical(t) ? 0 : 4; + result = (fmpq_poly_equal(d, e) && !cflags); + if (!result) + { + flint_printf("FAIL (correctness #1):\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + fmpq_poly_debug(d), flint_printf("\n\n"); + fmpq_poly_debug(s), flint_printf("\n\n"); + fmpq_poly_debug(t), flint_printf("\n\n"); + flint_printf("cflags = %d\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(d); + fmpq_poly_clear(e); + fmpq_poly_clear(f); + fmpq_poly_clear(s); + fmpq_poly_clear(t); + } + + /* Verify consistency with GCD */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, d, s, t; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(d); + fmpq_poly_init(s); + fmpq_poly_init(t); + fmpq_poly_randtest(a, state, n_randint(state, 60), 80); + fmpq_poly_randtest(b, state, n_randint(state, 60), 80); + + fmpq_poly_xgcd(d, s, t, a, b); + fmpq_poly_gcd(a, a, b); + + cflags |= fmpq_poly_is_canonical(d) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(s) ? 0 : 2; + cflags |= fmpq_poly_is_canonical(t) ? 0 : 4; + result = (fmpq_poly_equal(d, a) && !cflags); + if (!result) + { + flint_printf("FAIL (GCD #1):\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + fmpq_poly_debug(d), flint_printf("\n\n"); + fmpq_poly_debug(s), flint_printf("\n\n"); + fmpq_poly_debug(t), flint_printf("\n\n"); + flint_printf("cflags = %d\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(d); + fmpq_poly_clear(s); + fmpq_poly_clear(t); + } + + /* Generic case when a, b are most likely co-prime ***********************/ + + /* Verify d == s a + t b */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, d, s, t, z; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(d); + fmpq_poly_init(s); + fmpq_poly_init(t); + fmpq_poly_init(z); + fmpq_poly_randtest(a, state, n_randint(state, 60), 80); + fmpq_poly_randtest(b, state, n_randint(state, 60), 80); + fmpq_poly_randtest(z, state, n_randint(state, 20), 20); + fmpq_poly_mul(a, a, z); + fmpq_poly_mul(b, b, z); + + fmpq_poly_xgcd(d, s, t, a, b); + fmpq_poly_mul(a, s, a); + fmpq_poly_mul(b, t, b); + fmpq_poly_add(a, a, b); + + cflags |= fmpq_poly_is_canonical(d) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(s) ? 0 : 2; + cflags |= fmpq_poly_is_canonical(t) ? 0 : 4; + result = (fmpq_poly_equal(d, a) && !cflags); + if (!result) + { + flint_printf("FAIL (correctness #2):\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + fmpq_poly_debug(d), flint_printf("\n\n"); + fmpq_poly_debug(s), flint_printf("\n\n"); + fmpq_poly_debug(t), flint_printf("\n\n"); + flint_printf("cflags = %d\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(d); + fmpq_poly_clear(s); + fmpq_poly_clear(t); + fmpq_poly_clear(z); + } + + /* Verify consistency with GCD */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b, d, s, t, z; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_init(d); + fmpq_poly_init(s); + fmpq_poly_init(t); + fmpq_poly_init(z); + fmpq_poly_randtest(a, state, n_randint(state, 60), 80); + fmpq_poly_randtest(b, state, n_randint(state, 60), 80); + fmpq_poly_randtest(z, state, n_randint(state, 20), 20); + fmpq_poly_mul(a, a, z); + fmpq_poly_mul(b, b, z); + + fmpq_poly_xgcd(d, s, t, a, b); + fmpq_poly_gcd(a, a, b); + + cflags |= fmpq_poly_is_canonical(d) ? 0 : 1; + cflags |= fmpq_poly_is_canonical(s) ? 0 : 2; + cflags |= fmpq_poly_is_canonical(t) ? 0 : 4; + result = (fmpq_poly_equal(d, a) && !cflags); + if (!result) + { + flint_printf("FAIL (GCD #2):\n"); + fmpq_poly_debug(a), flint_printf("\n\n"); + fmpq_poly_debug(b), flint_printf("\n\n"); + fmpq_poly_debug(d), flint_printf("\n\n"); + fmpq_poly_debug(s), flint_printf("\n\n"); + fmpq_poly_debug(t), flint_printf("\n\n"); + flint_printf("cflags = %d\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(d); + fmpq_poly_clear(s); + fmpq_poly_clear(t); + fmpq_poly_clear(z); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} + diff --git a/external/flint-2.4.3/fmpq_poly/test/t-zero.c b/external/flint-2.4.3/fmpq_poly/test/t-zero.c new file mode 100644 index 0000000..eaf375d --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/test/t-zero.c @@ -0,0 +1,75 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + ulong cflags = UWORD(0); + + FLINT_TEST_INIT(state); + + flint_printf("zero...."); + fflush(stdout); + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpq_poly_t a, b; + + fmpq_poly_init(a); + fmpq_poly_init(b); + fmpq_poly_randtest(a, state, n_randint(state, 100), 200); + + fmpq_poly_zero(a); + + cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; + result = (fmpq_poly_equal(a, b) && !cflags); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpq_poly_debug(a), flint_printf("\n\n"); + flint_printf("b = "), fmpq_poly_debug(b), flint_printf("\n\n"); + flint_printf("cflags = %wu\n\n", cflags); + abort(); + } + + fmpq_poly_clear(a); + fmpq_poly_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpq_poly/xgcd.c b/external/flint-2.4.3/fmpq_poly/xgcd.c new file mode 100644 index 0000000..8d606e1 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/xgcd.c @@ -0,0 +1,248 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" +#include "fmpq_poly.h" + +void _fmpq_poly_xgcd(fmpz *G, fmpz_t denG, + fmpz *S, fmpz_t denS, fmpz *T, fmpz_t denT, + const fmpz *A, const fmpz_t denA, slong lenA, + const fmpz *B, const fmpz_t denB, slong lenB) +{ + int alloc = 0; + fmpz *primA, *primB, *C, *D; + fmpz_t cA, cB; + slong lenG, lenC, lenD; + + fmpz_init(cA); + fmpz_init(cB); + + _fmpz_vec_content(cA, A, lenA); + _fmpz_vec_content(cB, B, lenB); + + if (fmpz_is_one(cA)) + { + if (fmpz_is_one(cB)) + { + primA = (fmpz *) A; + primB = (fmpz *) B; + } + else + { + alloc |= 1; + primA = (fmpz *) A; + primB = _fmpz_vec_init(lenB); + _fmpz_vec_scalar_divexact_fmpz(primB, B, lenB, cB); + } + } + else + { + if (fmpz_is_one(cA)) + { + alloc |= 2; + primA = _fmpz_vec_init(lenA); + primB = (fmpz *) B; + _fmpz_vec_scalar_divexact_fmpz(primA, A, lenA, cA); + } + else + { + alloc |= 3; + primA = _fmpz_vec_init(lenA + lenB); + primB = primA + lenA; + _fmpz_vec_scalar_divexact_fmpz(primA, A, lenA, cA); + _fmpz_vec_scalar_divexact_fmpz(primB, B, lenB, cB); + } + } + + _fmpz_poly_gcd(G, primA, lenA, primB, lenB); + + for (lenG = lenB - 1; !G[lenG]; lenG--) ; + lenG++; + + if (lenG > 1) + { + alloc |= 4; + lenC = lenA - lenG + 1; + lenD = lenB - lenG + 1; + C = _fmpz_vec_init(lenC + lenD); + D = C + lenC; + _fmpz_poly_div(C, primA, lenA, G, lenG); + _fmpz_poly_div(D, primB, lenB, G, lenG); + } + else + { + lenC = lenA; + lenD = lenB; + C = primA; + D = primB; + } + + _fmpz_poly_xgcd(denG, S, T, C, lenC, D, lenD); + + if (!fmpz_is_one(denA)) + _fmpz_vec_scalar_mul_fmpz(S, S, lenD, denA); + fmpz_mul(cA, cA, denG); + fmpz_mul(denS, cA, G + (lenG - 1)); + + if (!fmpz_is_one(denB)) + _fmpz_vec_scalar_mul_fmpz(T, T, lenC, denB); + fmpz_mul(cB, cB, denG); + fmpz_mul(denT, cB, G + (lenG - 1)); + + _fmpz_vec_zero(S + lenD, lenB - lenD); + _fmpz_vec_zero(T + lenC, lenA - lenC); + + _fmpq_poly_canonicalise(S, denS, lenD); + _fmpq_poly_canonicalise(T, denT, lenC); + + fmpz_set(denG, G + (lenG - 1)); + + if ((alloc & 3) == 1) + _fmpz_vec_clear(primB, lenB); + else if ((alloc & 3) == 2) + _fmpz_vec_clear(primA, lenA); + else if ((alloc & 3) == 3) + _fmpz_vec_clear(primA, lenA + lenB); + + if ((alloc & 4)) + _fmpz_vec_clear(C, lenC + lenD); + + fmpz_clear(cA); + fmpz_clear(cB); +} + +void fmpq_poly_xgcd(fmpq_poly_t G, fmpq_poly_t S, fmpq_poly_t T, + const fmpq_poly_t A, const fmpq_poly_t B) +{ + if (G == S || G == T || S == T) + { + flint_printf("Exception (fmpq_poly_xgcd). Output arguments aliased.\n"); + abort(); + } + + if (A->length < B->length) + { + fmpq_poly_xgcd(G, T, S, B, A); + } else + { + slong lenA = A->length, lenB = B->length, lenG = lenB; + + if (lenA == 0) /* lenA = lenB = 0 */ + { + fmpq_poly_zero(G); + fmpq_poly_zero(S); + fmpq_poly_zero(T); + } + else if (lenB == 0) /* lenA > lenB = 0 */ + { + fmpq_poly_make_monic(G, A); + fmpq_poly_zero(T); + fmpq_poly_fit_length(S, 1); + _fmpq_poly_set_length(S, 1); + if (fmpz_sgn(A->coeffs + (lenA - 1)) > 0) + { + fmpz_set(S->coeffs, A->den); + fmpz_set(S->den, A->coeffs + (lenA - 1)); + } + else + { + fmpz_neg(S->coeffs, A->den); + fmpz_neg(S->den, A->coeffs + (lenA - 1)); + } + fmpq_poly_canonicalise(S); + } + else if (lenB == 1) /* lenA >= lenB = 1 */ + { + fmpq_poly_set_ui(G, 1); + fmpq_poly_zero(S); + fmpq_poly_fit_length(T, 1); + _fmpq_poly_set_length(T, 1); + if (fmpz_sgn(B->coeffs) > 0) + { + fmpz_set(T->coeffs, B->den); + fmpz_set(T->den, B->coeffs); + } + else + { + fmpz_neg(T->coeffs, B->den); + fmpz_neg(T->den, B->coeffs); + } + } + else /* lenA >= lenB >= 2 */ + { + /* Aliasing */ + if (G == A || G == B) + { + fmpq_poly_t tG; + + fmpq_poly_init2(tG, lenG); + fmpq_poly_xgcd(tG, S, T, A, B); + fmpq_poly_swap(tG, G); + fmpq_poly_clear(tG); + } + else if (S == A || S == B) + { + fmpq_poly_t tS; + + fmpq_poly_init2(tS, lenB); + fmpq_poly_xgcd(G, tS, T, A, B); + fmpq_poly_swap(tS, S); + fmpq_poly_clear(tS); + } + else if (T == A || T == B) + { + fmpq_poly_t tT; + + fmpq_poly_init2(tT, lenA); + fmpq_poly_xgcd(G, S, tT, A, B); + fmpq_poly_swap(tT, T); + fmpq_poly_clear(tT); + } + else /* no aliasing */ + { + + fmpq_poly_fit_length(G, lenG); + fmpq_poly_fit_length(S, lenB); + fmpq_poly_fit_length(T, lenA); + + _fmpq_poly_xgcd(G->coeffs, G->den, S->coeffs, S->den, T->coeffs, T->den, + A->coeffs, A->den, lenA, B->coeffs, B->den, lenB); + + _fmpq_poly_set_length(G, lenG); + _fmpq_poly_set_length(S, lenB); + _fmpq_poly_set_length(T, lenA); + + _fmpq_poly_normalise(G); + _fmpq_poly_normalise(S); + _fmpq_poly_normalise(T); + } + } + } +} + diff --git a/external/flint-2.4.3/fmpq_poly/zero.c b/external/flint-2.4.3/fmpq_poly/zero.c new file mode 100644 index 0000000..b10f3a6 --- /dev/null +++ b/external/flint-2.4.3/fmpq_poly/zero.c @@ -0,0 +1,37 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +*****************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpq_poly.h" + +void fmpq_poly_zero(fmpq_poly_t poly) +{ + _fmpq_poly_set_length(poly, 0); + fmpz_one(poly->den); +} + diff --git a/external/flint-2.4.3/fmpq_polyxx.h b/external/flint-2.4.3/fmpq_polyxx.h new file mode 100644 index 0000000..13089fd --- /dev/null +++ b/external/flint-2.4.3/fmpq_polyxx.h @@ -0,0 +1,568 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#ifndef FMPQ_POLYXX_H +#define FMPQ_POLYXX_H + +#include +#include + +#include "flint.h" +#include "fmpq_poly.h" + +#include "fmpqxx.h" + +#include "flintxx/expression.h" +#include "flintxx/flint_classes.h" +#include "flintxx/traits.h" + +// TODO exhibit this as a specialisation of a generic poly +// TODO lazy version of numref? + +namespace flint { +// function "declarations" +FLINT_DEFINE_BINOP(fmpq_polyxx_get_coeff) +FLINT_DEFINE_BINOP(fmpq_polyxx_interpolate) +FLINT_DEFINE_UNOP(fmpq_polyxx_den) + +// TODO move to stdmath? + +// TODO move to stdmath? +FLINT_DEFINE_BINOP(rescale) + +namespace detail { +template +struct fmpq_poly_traits +{ + typedef FLINT_UNOP_BUILD_RETTYPE(fmpq_polyxx_den, fmpzxx, Poly) coeff_ref_t; + typedef coeff_ref_t coeff_srcref_t; + + static coeff_srcref_t den(const Poly& p) {return fmpq_polyxx_den(p);} +}; +} // detail + +template +class fmpq_polyxx_expression + : public expression, + Operation, Data> +{ +public: + typedef expression, + Operation, Data> base_t; + typedef detail::fmpq_poly_traits poly_traits_t; + typedef typename poly_traits_t::coeff_ref_t coeff_ref_t; + typedef typename poly_traits_t::coeff_srcref_t coeff_srcref_t; + + FLINTXX_DEFINE_BASICS(fmpq_polyxx_expression) + FLINTXX_DEFINE_CTORS(fmpq_polyxx_expression) + FLINTXX_DEFINE_C_REF(fmpq_polyxx_expression, fmpq_poly_struct, _poly) + + // static methods which only make sense with fmpq_polyxx + static fmpq_polyxx_expression randtest(frandxx& state, slong len, + mp_bitcnt_t bits) + { + fmpq_polyxx_expression res; + fmpq_poly_randtest(res._poly(), state._data(), len, bits); + return res; + } + static fmpq_polyxx_expression randtest_unsigned(frandxx& state, slong len, + mp_bitcnt_t bits) + { + fmpq_polyxx_expression res; + fmpq_poly_randtest_unsigned(res._poly(), state._data(), len, bits); + return res; + } + static fmpq_polyxx_expression randtest_not_zero(frandxx& state, slong len, + mp_bitcnt_t bits) + { + fmpq_polyxx_expression res; + fmpq_poly_randtest_not_zero(res._poly(), state._data(), len, bits); + return res; + } + + // TODO make lazy + // TODO perhaps as member function (non-static?) + template + static fmpq_polyxx_expression get_slice(const Poly& p, slong i, slong j) + { + fmpq_polyxx_expression res; + fmpq_poly_get_slice(res._poly(), p.evaluate()._poly(), i, j); + return res; + } + + template + static FLINT_BINOP_ENABLE_RETTYPE(fmpq_polyxx_interpolate, + Fmpq_vec1, Fmpq_vec2) + interpolate(const Fmpq_vec1& xs, const Fmpq_vec2& ys) + { + return fmpq_polyxx_interpolate(xs, ys); + } + + static fmpq_polyxx_expression zero() {return fmpq_polyxx_expression();} + static fmpq_polyxx_expression one() + { + fmpq_polyxx_expression res; + res.set_one(); + return res; + } + + // These only make sense with immediates + void realloc(slong alloc) {fmpq_poly_realloc(_poly(), alloc);} + void fit_length(slong len) {fmpq_poly_fit_length(_poly(), len);} + void _normalise() {_fmpq_poly_normalise(_poly());} + void _set_length(slong len) {_fmpq_poly_set_length(_poly(), len);} + void canonicalise() {fmpq_poly_canonicalise(_poly());} + bool is_canonical() const {return fmpq_poly_is_canonical(_poly());} + void set_zero() {fmpq_poly_zero(_poly());} + void set_one() {fmpq_poly_one(_poly());} + + coeff_ref_t get_coeff_numref(slong n) + { + return coeff_ref_t::make(fmpq_poly_numref(_poly()) + n); + } + coeff_srcref_t get_coeff_numref(slong n) const + { + return coeff_srcref_t::make(fmpq_poly_numref(_poly()) + n); + } + coeff_ref_t den() {return poly_traits_t::den(*this);} + coeff_srcref_t den() const {return poly_traits_t::den(*this);} + + // These only make sense with target immediates + template + typename mp::enable_if >::type + set_coeff(slong n, const Fmpz& x) + { + fmpq_poly_set_coeff_fmpz(_poly(), n, x.evaluate()._fmpz()); + } + template + typename mp::enable_if >::type + set_coeff(slong n, const Fmpq& x) + { + fmpq_poly_set_coeff_fmpq(_poly(), n, x.evaluate()._fmpq()); + } + template + typename mp::enable_if >::type + set_coeff(slong n, T x) + { + fmpq_poly_set_coeff_si(_poly(), n, x); + } + template + typename mp::enable_if >::type + set_coeff(slong n, T x) + { + fmpq_poly_set_coeff_ui(_poly(), n, x); + } + + void truncate(slong n) {fmpq_poly_truncate(_poly(), n);} + + // These cause evaluation + slong length() const {return fmpq_poly_length(this->evaluate()._poly());} + slong degree() const {return fmpq_poly_degree(this->evaluate()._poly());} + bool is_one() const {return fmpq_poly_is_one(this->evaluate()._poly());} + bool is_zero() const {return fmpq_poly_is_zero(this->evaluate()._poly());} + bool is_monic() const {return fmpq_poly_is_monic(this->evaluate()._poly());} + bool is_squarefree() const + {return fmpq_poly_is_squarefree(this->evaluate()._poly());} + + std::string pretty(const char* x) const + { + char* str = fmpq_poly_get_str_pretty(this->evaluate()._poly(), x); + std::string res(str); + flint_free(str); + return res; + } + + // lazy members + FLINTXX_DEFINE_MEMBER_BINOP_(operator(), compeval) + + template // NB: template to instantiate lazily + FLINT_BINOP_ENABLE_RETTYPE( + fmpq_polyxx_get_coeff, fmpq_polyxx_expression, Slong) + get_coeff(const Slong& n) const + { + return fmpq_polyxx_get_coeff(*this, n); + } + + FLINTXX_DEFINE_MEMBER_3OP(compose_series) + FLINTXX_DEFINE_MEMBER_3OP(compose_series_brent_kung) + FLINTXX_DEFINE_MEMBER_3OP(compose_series_horner) + FLINTXX_DEFINE_MEMBER_3OP(div_series) + FLINTXX_DEFINE_MEMBER_3OP(mullow) + FLINTXX_DEFINE_MEMBER_BINOP(asinh_series) + FLINTXX_DEFINE_MEMBER_BINOP(asin_series) + FLINTXX_DEFINE_MEMBER_BINOP(atanh_series) + FLINTXX_DEFINE_MEMBER_BINOP(atan_series) + FLINTXX_DEFINE_MEMBER_BINOP(cosh_series) + FLINTXX_DEFINE_MEMBER_BINOP(cos_series) + FLINTXX_DEFINE_MEMBER_BINOP(divrem) + FLINTXX_DEFINE_MEMBER_BINOP(exp_series) + FLINTXX_DEFINE_MEMBER_BINOP(gcd) + FLINTXX_DEFINE_MEMBER_BINOP(inv_series) + FLINTXX_DEFINE_MEMBER_BINOP(inv_series_newton) + FLINTXX_DEFINE_MEMBER_BINOP(invsqrt_series) + FLINTXX_DEFINE_MEMBER_BINOP(lcm) + FLINTXX_DEFINE_MEMBER_BINOP(log_series) + FLINTXX_DEFINE_MEMBER_BINOP(pow) + FLINTXX_DEFINE_MEMBER_BINOP_(rescale, rescale) + FLINTXX_DEFINE_MEMBER_BINOP(resultant) + FLINTXX_DEFINE_MEMBER_BINOP(reverse) + FLINTXX_DEFINE_MEMBER_BINOP(revert_series) + FLINTXX_DEFINE_MEMBER_BINOP(revert_series_lagrange) + FLINTXX_DEFINE_MEMBER_BINOP(revert_series_lagrange_fast) + FLINTXX_DEFINE_MEMBER_BINOP(revert_series_newton) + FLINTXX_DEFINE_MEMBER_BINOP_(shift_left, shift_left) + FLINTXX_DEFINE_MEMBER_BINOP_(shift_right, shift_right) + FLINTXX_DEFINE_MEMBER_BINOP(sinh_series) + FLINTXX_DEFINE_MEMBER_BINOP(sin_series) + FLINTXX_DEFINE_MEMBER_BINOP(sqrt_series) + FLINTXX_DEFINE_MEMBER_BINOP(tanh_series) + FLINTXX_DEFINE_MEMBER_BINOP(tan_series) + FLINTXX_DEFINE_MEMBER_BINOP(xgcd) + FLINTXX_DEFINE_MEMBER_UNOP(derivative) + FLINTXX_DEFINE_MEMBER_UNOP(integral) + FLINTXX_DEFINE_MEMBER_UNOP(inv) + FLINTXX_DEFINE_MEMBER_UNOP(make_monic) + FLINTXX_DEFINE_MEMBER_UNOP(primitive_part) + FLINTXX_DEFINE_MEMBER_UNOP_RTYPE(fmpqxx, content) +}; + +namespace detail { +struct fmpq_poly_data; +} + +typedef fmpq_polyxx_expression + fmpq_polyxx; +typedef fmpq_polyxx_expression > + fmpq_polyxx_ref; +typedef fmpq_polyxx_expression > + fmpq_polyxx_srcref; + +namespace detail { +template<> +struct fmpq_poly_traits +{ + typedef fmpzxx_srcref coeff_ref_t; + typedef fmpzxx_srcref coeff_srcref_t; + template static coeff_srcref_t den(const P& p) + {return coeff_srcref_t::make(fmpq_poly_denref(p._poly()));} +}; +template<> +struct fmpq_poly_traits +{ + typedef fmpzxx_ref coeff_ref_t; + typedef fmpzxx_ref coeff_srcref_t; + template + static coeff_ref_t den(P p) + {return coeff_ref_t::make(fmpq_poly_denref(p._poly()));} +}; +template<> +struct fmpq_poly_traits +{ + typedef fmpzxx_ref coeff_ref_t; + typedef fmpzxx_srcref coeff_srcref_t; + template + static coeff_ref_t den(P& p) + {return coeff_ref_t::make(fmpq_poly_denref(p._poly()));} + template + static coeff_srcref_t den(const P& p) + {return coeff_srcref_t::make(fmpq_poly_denref(p._poly()));} +}; + +struct fmpq_poly_data +{ + fmpq_poly_t inner; + typedef fmpq_poly_t& data_ref_t; + typedef const fmpq_poly_t& data_srcref_t; + + fmpq_poly_data() {fmpq_poly_init(inner);} + ~fmpq_poly_data() {fmpq_poly_clear(inner);} + + fmpq_poly_data(const fmpq_poly_data& o) + { + fmpq_poly_init(inner); + fmpq_poly_set(inner, o.inner); + } + + fmpq_poly_data(fmpq_polyxx_srcref r) + { + fmpq_poly_init(inner); + fmpq_poly_set(inner, r._poly()); + } + + fmpq_poly_data(slong alloc) + { + fmpq_poly_init2(inner, alloc); + } + + fmpq_poly_data(const char* str) + { + fmpq_poly_init(inner); + execution_check(!fmpq_poly_set_str(inner, str), + "construct from string", "fmpq_polyxx"); + } +}; +} // detail + +namespace traits { +template struct is_fmpq_polyxx : mp::or_< + traits::is_T_expr, + flint_classes::is_source > { }; +} // traits +namespace mp { +template +struct all_fmpq_polyxx : mp::and_, all_fmpq_polyxx > { }; +template +struct all_fmpq_polyxx : traits::is_fmpq_polyxx { }; + +template +struct enable_all_fmpq_polyxx + : mp::enable_if, Out> { }; +} // mp +} // flint + +// here to deal with circular dependencies... +#include "fmpz_polyxx.h" + +namespace flint { +namespace rules { +#define FMPQ_POLYXX_COND_S FLINTXX_COND_S(fmpq_polyxx) +#define FMPQ_POLYXX_COND_T FLINTXX_COND_T(fmpq_polyxx) + +FLINT_DEFINE_DOIT_COND2(assignment, FMPQ_POLYXX_COND_T, FMPQ_POLYXX_COND_S, + fmpq_poly_set(to._poly(), from._poly())) +FLINT_DEFINE_DOIT_COND2(assignment, FMPQ_POLYXX_COND_T, + traits::is_signed_integer, fmpq_poly_set_si(to._poly(), from)) +FLINT_DEFINE_DOIT_COND2(assignment, FMPQ_POLYXX_COND_T, + traits::is_unsigned_integer, fmpq_poly_set_ui(to._poly(), from)) +FLINT_DEFINE_DOIT_COND2(assignment, FMPQ_POLYXX_COND_T, FMPZXX_COND_S, + fmpq_poly_set_fmpz(to._poly(), from._fmpz())) +FLINT_DEFINE_DOIT_COND2(assignment, FMPQ_POLYXX_COND_T, FMPQXX_COND_S, + fmpq_poly_set_fmpq(to._poly(), from._fmpq())) +FLINT_DEFINE_DOIT_COND2(assignment, FMPQ_POLYXX_COND_T, FMPZ_POLYXX_COND_S, + fmpq_poly_set_fmpz_poly(to._poly(), from._poly())) + +FLINTXX_DEFINE_ASSIGN_STR(fmpq_polyxx, execution_check( + !fmpq_poly_set_str(to._poly(), from), "assign string", "fmpq_polyxx")) + +FLINTXX_DEFINE_TO_STR(fmpq_polyxx, fmpq_poly_get_str(from._poly())) +FLINTXX_DEFINE_SWAP(fmpq_polyxx, fmpq_poly_swap(e1._poly(), e2._poly())) + +FLINT_DEFINE_PRINT_COND(FMPQ_POLYXX_COND_S, fmpq_poly_fprint(to, from._poly())) +FLINT_DEFINE_PRINT_PRETTY_COND_2(FMPQ_POLYXX_COND_S, const char*, + fmpq_poly_fprint_pretty(to, from._poly(), extra)) +FLINT_DEFINE_READ_COND(FMPQ_POLYXX_COND_T, fmpq_poly_fread(from, to._poly())) + +FLINT_DEFINE_BINARY_EXPR_COND2(reverse_op, fmpq_polyxx, + FMPQ_POLYXX_COND_S, traits::fits_into_slong, + fmpq_poly_reverse(to._poly(), e1._poly(), e2)) + +FLINTXX_DEFINE_CMP(fmpq_polyxx, fmpq_poly_cmp(e1._poly(), e2._poly())) + +FLINT_DEFINE_UNARY_EXPR_COND(negate, fmpq_polyxx, FMPQ_POLYXX_COND_S, + fmpq_poly_neg(to._poly(), from._poly())) +FLINT_DEFINE_UNARY_EXPR_COND(inv_op, fmpq_polyxx, FMPQ_POLYXX_COND_S, + fmpq_poly_inv(to._poly(), from._poly())) + +FLINT_DEFINE_BINARY_EXPR_COND2(fmpq_polyxx_get_coeff_op, fmpqxx, + FMPQ_POLYXX_COND_S, traits::fits_into_slong, + fmpq_poly_get_coeff_fmpq(to._fmpq(), e1._poly(), e2)) + +FLINT_DEFINE_BINARY_EXPR_COND2(plus, fmpq_polyxx, + FMPQ_POLYXX_COND_S, FMPQ_POLYXX_COND_S, + fmpq_poly_add(to._poly(), e1._poly(), e2._poly())) +FLINT_DEFINE_BINARY_EXPR_COND2(minus, fmpq_polyxx, + FMPQ_POLYXX_COND_S, FMPQ_POLYXX_COND_S, + fmpq_poly_sub(to._poly(), e1._poly(), e2._poly())) + +FLINT_DEFINE_CBINARY_EXPR_COND2(times, fmpq_polyxx, + FMPQ_POLYXX_COND_S, FMPZXX_COND_S, + fmpq_poly_scalar_mul_fmpz(to._poly(), e1._poly(), e2._fmpz())) +FLINT_DEFINE_CBINARY_EXPR_COND2(times, fmpq_polyxx, + FMPQ_POLYXX_COND_S, FMPQXX_COND_S, + fmpq_poly_scalar_mul_fmpq(to._poly(), e1._poly(), e2._fmpq())) +FLINT_DEFINE_CBINARY_EXPR_COND2(times, fmpq_polyxx, + FMPQ_POLYXX_COND_S, traits::is_signed_integer, + fmpq_poly_scalar_mul_si(to._poly(), e1._poly(), e2)) +FLINT_DEFINE_CBINARY_EXPR_COND2(times, fmpq_polyxx, + FMPQ_POLYXX_COND_S, traits::is_unsigned_integer, + fmpq_poly_scalar_mul_ui(to._poly(), e1._poly(), e2)) + +FLINT_DEFINE_CBINARY_EXPR_COND2(divided_by, fmpq_polyxx, + FMPQ_POLYXX_COND_S, FMPQXX_COND_S, + fmpq_poly_scalar_div_fmpq(to._poly(), e1._poly(), e2._fmpq())) +FLINT_DEFINE_CBINARY_EXPR_COND2(divided_by, fmpq_polyxx, + FMPQ_POLYXX_COND_S, FMPZXX_COND_S, + fmpq_poly_scalar_div_fmpz(to._poly(), e1._poly(), e2._fmpz())) +FLINT_DEFINE_BINARY_EXPR_COND2(divided_by, fmpq_polyxx, + FMPQ_POLYXX_COND_S, traits::is_unsigned_integer, + fmpq_poly_scalar_div_ui(to._poly(), e1._poly(), e2)) +FLINT_DEFINE_BINARY_EXPR_COND2(divided_by, fmpq_polyxx, + FMPQ_POLYXX_COND_S, traits::is_signed_integer, + fmpq_poly_scalar_div_si(to._poly(), e1._poly(), e2)) + +FLINT_DEFINE_BINARY_EXPR_COND2(times, fmpq_polyxx, + FMPQ_POLYXX_COND_S, FMPQ_POLYXX_COND_S, + fmpq_poly_mul(to._poly(), e1._poly(), e2._poly())) + +FLINT_DEFINE_BINARY_EXPR_COND2(pow_op, fmpq_polyxx, + FMPQ_POLYXX_COND_S, traits::is_unsigned_integer, + fmpq_poly_pow(to._poly(), e1._poly(), e2)) + +FLINT_DEFINE_BINARY_EXPR_COND2(shift_left_op, fmpq_polyxx, + FMPQ_POLYXX_COND_S, traits::fits_into_slong, + fmpq_poly_shift_left(to._poly(), e1._poly(), e2)) +FLINT_DEFINE_BINARY_EXPR_COND2(shift_right_op, fmpq_polyxx, + FMPQ_POLYXX_COND_S, traits::fits_into_slong, + fmpq_poly_shift_right(to._poly(), e1._poly(), e2)) + +FLINT_DEFINE_BINARY_EXPR_COND2(divided_by, fmpq_polyxx, + FMPQ_POLYXX_COND_S, FMPQ_POLYXX_COND_S, + fmpq_poly_div(to._poly(), e1._poly(), e2._poly())) +FLINT_DEFINE_BINARY_EXPR_COND2(modulo, fmpq_polyxx, + FMPQ_POLYXX_COND_S, FMPQ_POLYXX_COND_S, + fmpq_poly_rem(to._poly(), e1._poly(), e2._poly())) + +FLINT_DEFINE_BINARY_EXPR_COND2(inv_series_newton_op, fmpq_polyxx, + FMPQ_POLYXX_COND_S, traits::fits_into_slong, + fmpq_poly_inv_series_newton(to._poly(), e1._poly(), e2)) +FLINT_DEFINE_BINARY_EXPR_COND2(inv_series_op, fmpq_polyxx, + FMPQ_POLYXX_COND_S, traits::fits_into_slong, + fmpq_poly_inv_series(to._poly(), e1._poly(), e2)) + +FLINT_DEFINE_BINARY_EXPR_COND2(gcd_op, fmpq_polyxx, + FMPQ_POLYXX_COND_S, FMPQ_POLYXX_COND_S, + fmpq_poly_gcd(to._poly(), e1._poly(), e2._poly())) +FLINT_DEFINE_BINARY_EXPR_COND2(lcm_op, fmpq_polyxx, + FMPQ_POLYXX_COND_S, FMPQ_POLYXX_COND_S, + fmpq_poly_lcm(to._poly(), e1._poly(), e2._poly())) +FLINT_DEFINE_BINARY_EXPR_COND2(resultant_op, fmpqxx, + FMPQ_POLYXX_COND_S, FMPQ_POLYXX_COND_S, + fmpq_poly_resultant(to._fmpq(), e1._poly(), e2._poly())) + +FLINT_DEFINE_UNARY_EXPR_COND(derivative_op, fmpq_polyxx, FMPQ_POLYXX_COND_S, + fmpq_poly_derivative(to._poly(), from._poly())) +FLINT_DEFINE_UNARY_EXPR_COND(integral_op, fmpq_polyxx, FMPQ_POLYXX_COND_S, + fmpq_poly_integral(to._poly(), from._poly())) + +#define FMPQ_POLYXX_DEFINE_SERIES(name) \ +FLINT_DEFINE_BINARY_EXPR_COND2(name##_series_op, fmpq_polyxx, \ + FMPQ_POLYXX_COND_S, traits::fits_into_slong, \ + fmpq_poly_##name##_series(to._poly(), e1._poly(), e2)) +FMPQ_POLYXX_DEFINE_SERIES(sqrt) +FMPQ_POLYXX_DEFINE_SERIES(invsqrt) +FMPQ_POLYXX_DEFINE_SERIES(exp) +FMPQ_POLYXX_DEFINE_SERIES(log) +FMPQ_POLYXX_DEFINE_SERIES(atan) +FMPQ_POLYXX_DEFINE_SERIES(atanh) +FMPQ_POLYXX_DEFINE_SERIES(asin) +FMPQ_POLYXX_DEFINE_SERIES(asinh) +FMPQ_POLYXX_DEFINE_SERIES(tan) +FMPQ_POLYXX_DEFINE_SERIES(sin) +FMPQ_POLYXX_DEFINE_SERIES(cos) +FMPQ_POLYXX_DEFINE_SERIES(sinh) +FMPQ_POLYXX_DEFINE_SERIES(cosh) +FMPQ_POLYXX_DEFINE_SERIES(tanh) + +FLINT_DEFINE_BINARY_EXPR_COND2(evaluate_op, fmpqxx, + FMPQ_POLYXX_COND_S, FMPQXX_COND_S, + fmpq_poly_evaluate_fmpq(to._fmpq(), e1._poly(), e2._fmpq())) +FLINT_DEFINE_BINARY_EXPR_COND2(evaluate_op, fmpqxx, + FMPQ_POLYXX_COND_S, FMPZXX_COND_S, + fmpq_poly_evaluate_fmpz(to._fmpq(), e1._poly(), e2._fmpz())) +FLINT_DEFINE_BINARY_EXPR_COND2(compose_op, fmpq_polyxx, + FMPQ_POLYXX_COND_S, FMPQ_POLYXX_COND_S, + fmpq_poly_compose(to._poly(), e1._poly(), e2._poly())) + +FLINT_DEFINE_BINARY_EXPR_COND2(fmpq_polyxx_interpolate_op, fmpq_polyxx, + FMPZ_VECXX_COND_S, FMPZ_VECXX_COND_S, + fmpq_poly_interpolate_fmpz_vec(to._poly(), e1._data().array, + e2._data().array, e2.size())) + +FLINT_DEFINE_BINARY_EXPR_COND2(rescale_op, fmpq_polyxx, + FMPQ_POLYXX_COND_S, FMPQXX_COND_S, + fmpq_poly_rescale(to._poly(), e1._poly(), e2._fmpq())) + +FLINT_DEFINE_BINARY_EXPR_COND2(revert_series_op, fmpq_polyxx, + FMPQ_POLYXX_COND_S, traits::fits_into_slong, + fmpq_poly_revert_series(to._poly(), e1._poly(), e2)) + +FLINT_DEFINE_BINARY_EXPR_COND2(revert_series_lagrange_op, fmpq_polyxx, + FMPQ_POLYXX_COND_S, traits::fits_into_slong, + fmpq_poly_revert_series_lagrange(to._poly(), e1._poly(), e2)) + +FLINT_DEFINE_BINARY_EXPR_COND2(revert_series_lagrange_fast_op, fmpq_polyxx, + FMPQ_POLYXX_COND_S, traits::fits_into_slong, + fmpq_poly_revert_series_lagrange_fast(to._poly(), e1._poly(), e2)) + +FLINT_DEFINE_BINARY_EXPR_COND2(revert_series_newton_op, fmpq_polyxx, + FMPQ_POLYXX_COND_S, traits::fits_into_slong, + fmpq_poly_revert_series_newton(to._poly(), e1._poly(), e2)) + +FLINT_DEFINE_UNARY_EXPR_COND(content_op, fmpqxx, FMPQ_POLYXX_COND_S, + fmpq_poly_content(to._fmpq(), from._poly())) +FLINT_DEFINE_UNARY_EXPR_COND(primitive_part_op, fmpq_polyxx, FMPQ_POLYXX_COND_S, + fmpq_poly_primitive_part(to._poly(), from._poly())) + +FLINT_DEFINE_UNARY_EXPR_COND(make_monic_op, fmpq_polyxx, FMPQ_POLYXX_COND_S, + fmpq_poly_make_monic(to._poly(), from._poly())) + +FLINT_DEFINE_UNARY_EXPR_COND(fmpq_polyxx_den_op, fmpzxx, FMPQ_POLYXX_COND_S, + fmpz_set(to._fmpz(), fmpq_poly_denref(from._poly()))) + +namespace rdetail { +typedef make_ltuple::type>::type fmpq_polyxx_triple; +typedef make_ltuple::type>::type fmpq_polyxx_pair; +} // rdetail + +FLINT_DEFINE_BINARY_EXPR_COND2(xgcd_op, rdetail::fmpq_polyxx_triple, + FMPQ_POLYXX_COND_S, FMPQ_POLYXX_COND_S, + fmpq_poly_xgcd(to.template get<0>()._poly(), to.template get<1>()._poly(), + to.template get<2>()._poly(), e1._poly(), e2._poly())) +FLINT_DEFINE_BINARY_EXPR_COND2(divrem_op, rdetail::fmpq_polyxx_pair, + FMPQ_POLYXX_COND_S, FMPQ_POLYXX_COND_S, + fmpq_poly_divrem(to.template get<0>()._poly(), to.template get<1>()._poly(), + e1._poly(), e2._poly())) + +#define FMPQ_POLYXX_DEFINE_SERIES_FUNC(name) \ +FLINT_DEFINE_THREEARY_EXPR_COND3(name##_op, fmpq_polyxx, \ + FMPQ_POLYXX_COND_S, FMPQ_POLYXX_COND_S, traits::fits_into_slong, \ + fmpq_poly_##name(to._poly(), e1._poly(), e2._poly(), e3)) +FMPQ_POLYXX_DEFINE_SERIES_FUNC(mullow) +FMPQ_POLYXX_DEFINE_SERIES_FUNC(div_series) +FMPQ_POLYXX_DEFINE_SERIES_FUNC(compose_series) +FMPQ_POLYXX_DEFINE_SERIES_FUNC(compose_series_brent_kung) +FMPQ_POLYXX_DEFINE_SERIES_FUNC(compose_series_horner) +} // rules + +// NB: fmpq_poly addmul is just done by hand currently, no need to wrap that .. + +} // flint + +#endif diff --git a/external/flint-2.4.3/fmpqxx.h b/external/flint-2.4.3/fmpqxx.h new file mode 100644 index 0000000..e1d8c42 --- /dev/null +++ b/external/flint-2.4.3/fmpqxx.h @@ -0,0 +1,471 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#ifndef CXX_FMPQXX_H +#define CXX_FMPQXX_H + +#include + +#include "fmpq.h" + +#include "flintxx/expression.h" +#include "flintxx/flint_classes.h" +#include "flintxx/flint_exception.h" +#include "flintxx/frandxx.h" +#include "fmpzxx.h" + +// TODO exhibit this as a specialisation of a generic fraction +// TODO summation + +namespace flint { +// function "declarations" +FLINT_DEFINE_BINOP(fmpqxx_reconstruct) +FLINT_DEFINE_FOURARY_HERE(fmpqxx_reconstruct) // four argument version +FLINT_DEFINE_UNOP(fmpqxx_next_minimal) +FLINT_DEFINE_UNOP(fmpqxx_next_signed_minimal) +FLINT_DEFINE_UNOP(fmpqxx_next_calkin_wilf) +FLINT_DEFINE_UNOP(fmpqxx_next_signed_calkin_wilf) +FLINT_DEFINE_UNOP(fmpqxx_num) +FLINT_DEFINE_UNOP(fmpqxx_den) + +namespace detail { +template +struct fmpq_traits { + typedef FLINT_UNOP_BUILD_RETTYPE(fmpqxx_num, fmpzxx, Fmpq) numreturn_t; + typedef FLINT_UNOP_BUILD_RETTYPE(fmpqxx_den, fmpzxx, Fmpq) denreturn_t; + typedef numreturn_t cnumreturn_t; + typedef denreturn_t cdenreturn_t; + static numreturn_t num(const Fmpq& f) {return fmpqxx_num(f);} + static denreturn_t den(const Fmpq& f) {return fmpqxx_den(f);} +}; +} + +template +class fmpqxx_expression + : public expression, Operation, Data> +{ +public: + typedef expression, + Operation, Data> base_t; + + FLINTXX_DEFINE_BASICS(fmpqxx_expression) + FLINTXX_DEFINE_CTORS(fmpqxx_expression) + FLINTXX_DEFINE_C_REF(fmpqxx_expression, fmpq, _fmpq) + + // static methods which only make sense with fmpqxx + FLINTXX_DEFINE_RANDFUNC(fmpq, randbits) + FLINTXX_DEFINE_RANDFUNC(fmpq, randtest) + FLINTXX_DEFINE_RANDFUNC(fmpq, randtest_not_zero) + + template + static fmpqxx_expression from_cfrac(const Vec& v, slong n) + { + fmpqxx_expression res; + res.set_cfrac(v, n); + return res; + } + + // TODO does this make more sense as standalone function? + template + static FLINT_BINOP_ENABLE_RETTYPE(fmpqxx_reconstruct, Fmpz1, Fmpz2) + reconstruct(const Fmpz1& a, const Fmpz2& m) + { + return fmpqxx_reconstruct(a, m); + } + template + static FLINT_FOURARY_ENABLE_RETTYPE(fmpqxx_reconstruct, + Fmpz1, Fmpz2, Fmpz3, Fmpz4) + reconstruct(const Fmpz1& a, const Fmpz2& m, const Fmpz3& N, const Fmpz4& D) + { + return fmpqxx_reconstruct(a, m, N, D); + } + + template + void set_frac(const F1& f1, const F2& f2) + { + num() = f1; + den() = f2; + canonicalise(); + } + template + static fmpqxx_expression frac(const F1& f1, const F2& f2) + { + fmpqxx_expression res; + res.set_frac(f1, f2); + return res; + } + + template + void set_integer(const T& t) + { + num() = t; + den() = 1u; + } + template + static fmpqxx_expression integer(const T& t) + { + fmpqxx_expression res; + res.set_integer(t); + return res; + } + + static fmpqxx_expression zero(){return fmpqxx_expression();} + static fmpqxx_expression one() + { + fmpqxx_expression res; + res.set_one(); + return res; + } + + // These only make sense with immediates + void canonicalise() {fmpq_canonicalise(_fmpq());} + bool is_canonical() const {return fmpq_is_canonical(_fmpq());} + void set_zero() {fmpq_zero(_fmpq());} + void set_one() {fmpq_one(_fmpq());} + + template + void set_cfrac(const Vec& v, slong n) + { + fmpq_set_cfrac(this->_fmpq(), v._array(), n); + } + + // Numerator and denominator access + typedef detail::fmpq_traits traits_t; + typename traits_t::numreturn_t num() {return traits_t::num(*this);} + typename traits_t::cnumreturn_t num() const {return traits_t::num(*this);} + typename traits_t::denreturn_t den() {return traits_t::den(*this);} + typename traits_t::cdenreturn_t den() const + {return traits_t::den(*this);} + + // These cause evaluation + bool is_zero() const {return fmpq_is_zero(this->evaluate()._fmpq());} + bool is_one() const {return fmpq_is_one(this->evaluate()._fmpq());} + // TODO make this only work on immediates? + slong cfrac_bound() const {return fmpq_cfrac_bound(this->evaluate()._fmpq());} + int sgn() const {return fmpq_sgn(this->evaluate()._fmpq());} + mp_bitcnt_t height_bits() const + {return fmpq_height_bits(this->evaluate()._fmpq());} + + FLINTXX_DEFINE_MEMBER_UNOP_(next_minimal, fmpqxx_next_minimal) + FLINTXX_DEFINE_MEMBER_UNOP_(next_signed_minimal, fmpqxx_next_signed_minimal) + FLINTXX_DEFINE_MEMBER_UNOP_(next_calkin_wilf, fmpqxx_next_calkin_wilf) + FLINTXX_DEFINE_MEMBER_UNOP_(next_signed_calkin_wilf, + fmpqxx_next_signed_calkin_wilf) + + // forwarded member functions + FLINTXX_DEFINE_MEMBER_UNOP(abs) + FLINTXX_DEFINE_MEMBER_UNOP(inv) + FLINTXX_DEFINE_MEMBER_UNOP_RTYPE(fmpzxx, height) + FLINTXX_DEFINE_MEMBER_BINOP(pow) +}; + +namespace detail { +struct fmpq_data; +} + +typedef fmpqxx_expression fmpqxx; +typedef fmpqxx_expression > fmpqxx_ref; +typedef fmpqxx_expression > fmpqxx_srcref; + +namespace detail { +template<> +struct fmpq_traits +{ + typedef fmpzxx_srcref numreturn_t; + typedef fmpzxx_srcref cnumreturn_t; + typedef fmpzxx_srcref denreturn_t; + typedef fmpzxx_srcref cdenreturn_t; + template + static cnumreturn_t num(T f) + {return cnumreturn_t::make(fmpq_numref(f._fmpq()));} + template + static cnumreturn_t den(T f) + {return cnumreturn_t::make(fmpq_denref(f._fmpq()));} +}; +template<> +struct fmpq_traits +{ + typedef fmpzxx_ref numreturn_t; + typedef fmpzxx_ref denreturn_t; + typedef fmpzxx_ref cnumreturn_t; + typedef fmpzxx_ref cdenreturn_t; + template + static cnumreturn_t num(T f) + {return cnumreturn_t::make(fmpq_numref(f._fmpq()));} + template + static cnumreturn_t den(T f) + {return cnumreturn_t::make(fmpq_denref(f._fmpq()));} +}; +template<> struct fmpq_traits +{ + typedef fmpzxx_ref numreturn_t; + typedef fmpzxx_ref denreturn_t; + typedef fmpzxx_srcref cnumreturn_t; + typedef fmpzxx_srcref cdenreturn_t; + template + static cnumreturn_t num(const T& f) + {return cnumreturn_t::make(fmpq_numref(f._fmpq()));} + template + static cnumreturn_t den(const T& f) + {return cnumreturn_t::make(fmpq_denref(f._fmpq()));} + template + static numreturn_t num(T& f) + {return numreturn_t::make(fmpq_numref(f._fmpq()));} + template + static numreturn_t den(T& f) + {return numreturn_t::make(fmpq_denref(f._fmpq()));} +}; + +struct fmpq_data +{ + fmpq_t inner; + typedef fmpq_t& data_ref_t; + typedef const fmpq_t& data_srcref_t; + + fmpq_data() {fmpq_init(inner);} + ~fmpq_data() {fmpq_clear(inner);} + + fmpq_data(const fmpq_data& o) + { + fmpq_init(inner); + fmpq_set(inner, o.inner); + } + + fmpq_data(fmpqxx_srcref r) + { + fmpq_init(inner); + fmpq_set(inner, r._fmpq()); + } + + fmpq_data(fmpzxx_srcref num, fmpzxx_srcref den) + { + fmpq_init(inner); + fmpq_set_fmpz_frac(inner, num._fmpz(), den._fmpz()); + } + + template + fmpq_data(T num, U den, + typename mp::enable_if >::type* = 0, + typename mp::enable_if >::type* = 0) + { + fmpq_init(inner); + fmpq_set_si(inner, num, den); + } +}; +} // detail + +// TODO macroize? +namespace traits { +template struct is_fmpqxx : mp::or_< + traits::is_T_expr, + flint_classes::is_source > { }; +} // traits + +namespace rules { +#define FMPQXX_COND_S FLINTXX_COND_S(fmpqxx) +#define FMPQXX_COND_T FLINTXX_COND_T(fmpqxx) + +FLINT_DEFINE_DOIT_COND2(assignment, FMPQXX_COND_T, FMPQXX_COND_S, + fmpq_set(to._fmpq(), from._fmpq())) +FLINT_DEFINE_DOIT_COND2(assignment, FMPQXX_COND_T, traits::fits_into_slong, + fmpq_set_si(to._fmpq(), from, 1)) +// TODO mpq, mpfr? + +FLINTXX_DEFINE_TO_STR(fmpqxx, fmpq_get_str(0, base, from._fmpq())) +FLINTXX_DEFINE_CMP(fmpqxx, fmpq_cmp(e1._fmpq(), e2._fmpq())) +FLINTXX_DEFINE_SWAP(fmpqxx, fmpq_swap(e1._fmpq(), e2._fmpq())) + +FLINT_DEFINE_PRINT_COND(FMPQXX_COND_S, (fmpq_fprint(to, from._fmpq()), 1)) + +FLINT_DEFINE_CBINARY_EXPR_COND2(plus, fmpqxx, FMPQXX_COND_S, FMPQXX_COND_S, + fmpq_add(to._fmpq(), e1._fmpq(), e2._fmpq())) +FLINT_DEFINE_CBINARY_EXPR_COND2(minus, fmpqxx, FMPQXX_COND_S, FMPQXX_COND_S, + fmpq_sub(to._fmpq(), e1._fmpq(), e2._fmpq())) +FLINT_DEFINE_CBINARY_EXPR_COND2(times, fmpqxx, FMPQXX_COND_S, FMPQXX_COND_S, + fmpq_mul(to._fmpq(), e1._fmpq(), e2._fmpq())) +FLINT_DEFINE_CBINARY_EXPR_COND2(divided_by, fmpqxx, FMPQXX_COND_S, + FMPQXX_COND_S, fmpq_div(to._fmpq(), e1._fmpq(), e2._fmpq())) +FLINT_DEFINE_CBINARY_EXPR_COND2(times, fmpqxx, FMPQXX_COND_S, FMPZXX_COND_S, + fmpq_mul_fmpz(to._fmpq(), e1._fmpq(), e2._fmpz())) +FLINT_DEFINE_BINARY_EXPR_COND2(divided_by, fmpqxx, FMPQXX_COND_S, FMPZXX_COND_S, + fmpq_div_fmpz(to._fmpq(), e1._fmpq(), e2._fmpz())) + +FLINT_DEFINE_UNARY_EXPR_COND(negate, fmpqxx, FMPQXX_COND_S, + fmpq_neg(to._fmpq(), from._fmpq())) + +FLINT_DEFINE_BINARY_EXPR_COND2(modulo, fmpzxx, FMPQXX_COND_S, FMPZXX_COND_S, + execution_check(fmpq_mod_fmpz(to._fmpz(), e1._fmpq(), e2._fmpz()), + "modular inversion", "fmpq")) + +// TODO macroize? +namespace rdetail { +template +void fmpqxx_shift(Fmpq1& to, const Fmpq2& from, T howmuch) +{ + if(howmuch < 0) + fmpq_div_2exp(to._fmpq(), from._fmpq(), -howmuch); + else + fmpq_mul_2exp(to._fmpq(), from._fmpq(), howmuch); +} +} // rdetail +FLINT_DEFINE_BINARY_EXPR_COND2(shift, fmpqxx, + FMPQXX_COND_S, traits::is_integer, + rdetail::fmpqxx_shift(to, e1, e2)) +} // rules + +FLINTXX_DEFINE_TERNARY(fmpqxx, + fmpq_addmul(to._fmpq(), e1._fmpq(), e2._fmpq()), + fmpq_submul(to._fmpq(), e1._fmpq(), e2._fmpq()), + FLINTXX_UNADORNED_MAKETYPES) + +// immediate functions +template +inline typename mp::enable_if, mp_bitcnt_t>::type +height_bits(const Fmpq& f) +{ + return f.height_bits(); +} + +// TODO maybe as a member function? +template +inline typename mp::enable_if, + FMPQXX_COND_T >, + int>::type +get_cfrac(Vec& v, Fmpq1& rem, const Fmpq2& x) +{ + return fmpq_get_cfrac(v._array(), rem._fmpq(), x.evaluate()._fmpq(), + v.size()); +} +// TODO also set_cfrac? c/f fmpqxx::set_cfrac ... + +template +inline typename mp::enable_if, int>::type +sgn(const Fmpq& f) +{ + return f.sgn(); +} + +namespace rules { +FLINT_DEFINE_UNARY_EXPR_COND(abs_op, fmpqxx, FMPQXX_COND_S, + fmpq_abs(to._fmpq(), from._fmpq())) +FLINT_DEFINE_UNARY_EXPR_COND(height_op, fmpzxx, FMPQXX_COND_S, + fmpq_height(to._fmpz(), from._fmpq())) +FLINT_DEFINE_UNARY_EXPR_COND(inv_op, fmpqxx, FMPQXX_COND_S, + fmpq_inv(to._fmpq(), from._fmpq())) +FLINT_DEFINE_UNARY_EXPR_COND(fmpqxx_next_minimal_op, fmpqxx, FMPQXX_COND_S, + fmpq_next_minimal(to._fmpq(), from._fmpq())) +FLINT_DEFINE_UNARY_EXPR_COND(fmpqxx_next_signed_minimal_op, fmpqxx, FMPQXX_COND_S, + fmpq_next_signed_minimal(to._fmpq(), from._fmpq())) +FLINT_DEFINE_UNARY_EXPR_COND(fmpqxx_next_calkin_wilf_op, fmpqxx, FMPQXX_COND_S, + fmpq_next_calkin_wilf(to._fmpq(), from._fmpq())) +FLINT_DEFINE_UNARY_EXPR_COND(fmpqxx_next_signed_calkin_wilf_op, fmpqxx, FMPQXX_COND_S, + fmpq_next_signed_calkin_wilf(to._fmpq(), from._fmpq())) + +FLINT_DEFINE_UNARY_EXPR_COND(fmpqxx_num_op, fmpzxx, FMPQXX_COND_S, + fmpz_set(to._fmpz(), fmpq_numref(from._fmpq()))) +FLINT_DEFINE_UNARY_EXPR_COND(fmpqxx_den_op, fmpzxx, FMPQXX_COND_S, + fmpz_set(to._fmpz(), fmpq_denref(from._fmpq()))) + +// TODO should this throw a different exception type? +FLINT_DEFINE_BINARY_EXPR_COND2(fmpqxx_reconstruct_op, fmpqxx, + FMPZXX_COND_S, FMPZXX_COND_S, + execution_check(fmpq_reconstruct_fmpz( + to._fmpq(), e1._fmpz(), e2._fmpz()), + "rational reconstruction", "fmpq")) +FLINT_DEFINE_FOURARY_EXPR_COND4(fmpqxx_reconstruct_op, fmpqxx, + FMPZXX_COND_S, FMPZXX_COND_S, FMPZXX_COND_S, FMPZXX_COND_S, + execution_check(fmpq_reconstruct_fmpz_2( + to._fmpq(), e1._fmpz(), e2._fmpz(), e3._fmpz(), e4._fmpz()), + "rational reconstruction (v2)", "fmpq")) + + +FLINT_DEFINE_BINARY_EXPR_COND2(pow_op, fmpqxx, + FMPQXX_COND_S, traits::fits_into_slong, + fmpq_pow_si(to._fmpq(), e1._fmpq(), e2)) +} + +} // flint + +// fmpq_vecxx + +#include "flintxx/vector.h" + +namespace flint { +namespace detail { +struct fmpq_vector_data +{ + slong size; + fmpq* array; + + fmpq_vector_data(slong n) + : size(n), array(_fmpq_vec_init(n)) {} + + ~fmpq_vector_data() {_fmpq_vec_clear(array, size);} + + fmpq_vector_data(const fmpq_vector_data& o) + : size(o.size), array(_fmpq_vec_init(o.size)) + { + for(slong i = 0;i < size;++i) + fmpq_set(array + i, o.array + i); + } + + fmpqxx_ref at(slong i) {return fmpqxx_ref::make(array + i);} + fmpqxx_srcref at(slong i) const {return fmpqxx_srcref::make(array + i);} +}; +} // detail + +typedef vector_expression< + detail::wrapped_vector_traits, + operations::immediate, + detail::fmpq_vector_data> fmpq_vecxx; + +template<> +struct enable_vector_rules : mp::false_ { }; + +namespace detail { +inline bool fmpq_vec_equal(const fmpq* v1, const fmpq* v2, slong n) +{ + for(slong i = 0;i < n;++i) + if(!fmpq_equal(v1+i, v2+i)) + return false; + return true; +} +} +namespace rules { +// TODO hack to make code look like references are implemented +template struct FMPQ_VECXX_COND_S : mp::equal_types { }; +#define FMPQ_VECXX_COND_T FMPQ_VECXX_COND_S + +// TODO references +FLINT_DEFINE_GET(equals, bool, fmpq_vecxx, + e1.size() == e2.size() + && detail::fmpq_vec_equal(e1._data().array, e2._data().array, e1.size())) +} // rules +} // flint + +#endif diff --git a/external/flint-2.4.3/fmpz-conversions-gc.in b/external/flint-2.4.3/fmpz-conversions-gc.in new file mode 100644 index 0000000..a0d9cbd --- /dev/null +++ b/external/flint-2.4.3/fmpz-conversions-gc.in @@ -0,0 +1,10 @@ +#ifndef FMPZ_CONVERSIONS_H +#define FMPZ_CONVERSIONS_H + +/* turn a pointer to an __mpz_struct into a fmpz_t */ +#define PTR_TO_COEFF(x) (((ulong) (x) >> 2) | (WORD(1) << (FLINT_BITS - 2))) + +/* turns an fmpz into a pointer to an mpz */ +#define COEFF_TO_PTR(x) ((__mpz_struct *) ((x) << 2)) + +#endif /* FMPZ_CONVERSIONS_H */ diff --git a/external/flint-2.4.3/fmpz-conversions-reentrant.in b/external/flint-2.4.3/fmpz-conversions-reentrant.in new file mode 100644 index 0000000..a0d9cbd --- /dev/null +++ b/external/flint-2.4.3/fmpz-conversions-reentrant.in @@ -0,0 +1,10 @@ +#ifndef FMPZ_CONVERSIONS_H +#define FMPZ_CONVERSIONS_H + +/* turn a pointer to an __mpz_struct into a fmpz_t */ +#define PTR_TO_COEFF(x) (((ulong) (x) >> 2) | (WORD(1) << (FLINT_BITS - 2))) + +/* turns an fmpz into a pointer to an mpz */ +#define COEFF_TO_PTR(x) ((__mpz_struct *) ((x) << 2)) + +#endif /* FMPZ_CONVERSIONS_H */ diff --git a/external/flint-2.4.3/fmpz-conversions-single.in b/external/flint-2.4.3/fmpz-conversions-single.in new file mode 100644 index 0000000..a0d9cbd --- /dev/null +++ b/external/flint-2.4.3/fmpz-conversions-single.in @@ -0,0 +1,10 @@ +#ifndef FMPZ_CONVERSIONS_H +#define FMPZ_CONVERSIONS_H + +/* turn a pointer to an __mpz_struct into a fmpz_t */ +#define PTR_TO_COEFF(x) (((ulong) (x) >> 2) | (WORD(1) << (FLINT_BITS - 2))) + +/* turns an fmpz into a pointer to an mpz */ +#define COEFF_TO_PTR(x) ((__mpz_struct *) ((x) << 2)) + +#endif /* FMPZ_CONVERSIONS_H */ diff --git a/external/flint-2.4.3/fmpz-conversions.h b/external/flint-2.4.3/fmpz-conversions.h new file mode 100644 index 0000000..a0d9cbd --- /dev/null +++ b/external/flint-2.4.3/fmpz-conversions.h @@ -0,0 +1,10 @@ +#ifndef FMPZ_CONVERSIONS_H +#define FMPZ_CONVERSIONS_H + +/* turn a pointer to an __mpz_struct into a fmpz_t */ +#define PTR_TO_COEFF(x) (((ulong) (x) >> 2) | (WORD(1) << (FLINT_BITS - 2))) + +/* turns an fmpz into a pointer to an mpz */ +#define COEFF_TO_PTR(x) ((__mpz_struct *) ((x) << 2)) + +#endif /* FMPZ_CONVERSIONS_H */ diff --git a/external/flint-2.4.3/fmpz.h b/external/flint-2.4.3/fmpz.h new file mode 100644 index 0000000..4991961 --- /dev/null +++ b/external/flint-2.4.3/fmpz.h @@ -0,0 +1,678 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#ifndef FMPZ_H +#define FMPZ_H + +#undef ulong +#define ulong ulongxx/* interferes with system includes */ +#include +#include +#undef ulong + +#include +#define ulong mp_limb_t + +#include "flint.h" +#include "nmod_vec.h" +#include "fmpz-conversions.h" + + +#ifdef __cplusplus + extern "C" { +#endif + +typedef slong fmpz; +typedef fmpz fmpz_t[1]; + +typedef gmp_randstate_t fmpz_randstate_t; + +extern __mpz_struct * fmpz_arr; +extern gmp_randstate_t fmpz_randstate; + +typedef struct +{ + mp_ptr dinv; + slong n; + mp_bitcnt_t norm; +} fmpz_preinvn_struct; + +typedef fmpz_preinvn_struct fmpz_preinvn_t[1]; + +/* maximum positive value a small coefficient can have */ +#define COEFF_MAX ((WORD(1) << (FLINT_BITS - 2)) - WORD(1)) + +/* minimum negative value a small coefficient can have */ +#define COEFF_MIN (-((WORD(1) << (FLINT_BITS - 2)) - WORD(1))) + +#define COEFF_IS_MPZ(x) (((x) >> (FLINT_BITS - 2)) == WORD(1)) /* is x a pointer not an integer */ + +__mpz_struct * _fmpz_new_mpz(void); + +void _fmpz_clear_mpz(fmpz f); + +void _fmpz_cleanup_mpz_content(void); + +void _fmpz_cleanup(void); + +__mpz_struct * _fmpz_promote(fmpz_t f); + +__mpz_struct * _fmpz_promote_val(fmpz_t f); + +static __inline__ +void _fmpz_demote(fmpz_t f) +{ + if (COEFF_IS_MPZ(*f)) + { + _fmpz_clear_mpz(*f); + (*f) = WORD(0); + } +} + +void _fmpz_demote_val(fmpz_t f); + +void _fmpz_init_readonly_mpz(fmpz_t f, const mpz_t z); + +void _fmpz_clear_readonly_mpz(mpz_t); + +static __inline__ +void fmpz_init(fmpz_t f) +{ + (*f) = WORD(0); +} + +void fmpz_init2(fmpz_t f, ulong limbs); + +static __inline__ +void fmpz_init_set(fmpz_t f, const fmpz_t g) +{ + if (!COEFF_IS_MPZ(*g)) + { + *f = *g; + } + else + { + __mpz_struct *ptr; + + ptr = _fmpz_new_mpz(); + *f = PTR_TO_COEFF(ptr); + mpz_set(ptr, COEFF_TO_PTR(*g)); + } +} + +static __inline__ +void fmpz_init_set_ui(fmpz_t f, ulong g) +{ + if (g <= COEFF_MAX) + { + *f = g; + } + else + { + __mpz_struct *ptr; + + ptr = _fmpz_new_mpz(); + *f = PTR_TO_COEFF(ptr); + flint_mpz_set_ui(ptr, g); + } +} + +static __inline__ +void fmpz_clear(fmpz_t f) +{ + _fmpz_demote(f); +} + +void fmpz_randbits(fmpz_t f, flint_rand_t state, mp_bitcnt_t bits); + +void fmpz_randm(fmpz_t f, flint_rand_t state, const fmpz_t m); + +void fmpz_randtest(fmpz_t f, flint_rand_t state, mp_bitcnt_t bits); + +void fmpz_randtest_unsigned(fmpz_t f, flint_rand_t state, mp_bitcnt_t bits); + +void fmpz_randtest_not_zero(fmpz_t f, flint_rand_t state, mp_bitcnt_t bits); + +void fmpz_randtest_mod(fmpz_t f, flint_rand_t state, const fmpz_t m); + +void fmpz_randtest_mod_signed(fmpz_t f, flint_rand_t state, const fmpz_t m); + +slong fmpz_get_si(const fmpz_t f); + +ulong fmpz_get_ui(const fmpz_t f); + +static __inline__ void +fmpz_set_si(fmpz_t f, slong val) +{ + if (val < COEFF_MIN || val > COEFF_MAX) /* val is large */ + { + __mpz_struct *mpz_coeff = _fmpz_promote(f); + flint_mpz_set_si(mpz_coeff, val); + } + else + { + _fmpz_demote(f); + *f = val; /* val is small */ + } +} + +static __inline__ void +fmpz_set_ui(fmpz_t f, ulong val) +{ + if (val > COEFF_MAX) /* val is large */ + { + __mpz_struct *mpz_coeff = _fmpz_promote(f); + flint_mpz_set_ui(mpz_coeff, val); + } + else + { + _fmpz_demote(f); + *f = val; /* val is small */ + } +} + +static __inline__ void +fmpz_neg_ui(fmpz_t f, ulong val) +{ + if (val > COEFF_MAX) + { + __mpz_struct *mpz_coeff = _fmpz_promote(f); + flint_mpz_set_ui(mpz_coeff, val); + mpz_neg(mpz_coeff, mpz_coeff); + } + else + { + _fmpz_demote(f); + *f = -(slong) val; + } +} + +static __inline__ void +fmpz_set_uiui(fmpz_t f, mp_limb_t hi, mp_limb_t lo) +{ + if (hi == 0) + { + fmpz_set_ui(f, lo); + } + else + { + __mpz_struct *z = _fmpz_promote(f); + if (z->_mp_alloc < 2) + mpz_realloc2(z, 2 * FLINT_BITS); + z->_mp_d[0] = lo; + z->_mp_d[1] = hi; + z->_mp_size = 2; + } +} + +static __inline__ void +fmpz_neg_uiui(fmpz_t f, mp_limb_t hi, mp_limb_t lo) +{ + if (hi == 0) + { + fmpz_neg_ui(f, lo); + } + else + { + __mpz_struct *z = _fmpz_promote(f); + if (z->_mp_alloc < 2) + mpz_realloc2(z, 2 * FLINT_BITS); + z->_mp_d[0] = lo; + z->_mp_d[1] = hi; + z->_mp_size = -2; + } +} + +void fmpz_get_mpz(mpz_t x, const fmpz_t f); + +void fmpz_set_mpz(fmpz_t f, const mpz_t x); + +double fmpz_get_d(const fmpz_t f); + +void fmpz_set_d(fmpz_t f, double c); + +int fmpz_set_str(fmpz_t f, const char * str, int b); + +void flint_mpz_init_set_readonly(mpz_t z, const fmpz_t f); + +void flint_mpz_clear_readonly(mpz_t z); + +void fmpz_init_set_readonly(fmpz_t f, const mpz_t z); + +void fmpz_clear_readonly(fmpz_t f); + +int fmpz_abs_fits_ui(const fmpz_t f); + +int fmpz_fits_si(const fmpz_t f); + +static __inline__ +void fmpz_zero(fmpz_t f) +{ + _fmpz_demote(f); + (*f) = WORD(0); +} + +static __inline__ +void fmpz_one(fmpz_t f) +{ + if (COEFF_IS_MPZ(*f)) + { + _fmpz_clear_mpz(*f); + } + *f = WORD(1); +} + +static __inline__ +int fmpz_is_zero(const fmpz_t f) +{ + return (*f == 0); +} + +static __inline__ +int fmpz_is_one(const fmpz_t f) +{ + return (*f == 1); +} + +static __inline__ +int fmpz_is_pm1(const fmpz_t f) +{ + return (*f == 1 || *f == -1); +} + +void fmpz_set(fmpz_t f, const fmpz_t g); + +int fmpz_equal(const fmpz_t f, const fmpz_t g); + +int fmpz_equal_si(const fmpz_t f, slong g); + +int fmpz_equal_ui(const fmpz_t f, ulong g); + +int fmpz_read(fmpz_t f); + +int fmpz_fread(FILE * file, fmpz_t f); + +size_t fmpz_inp_raw( fmpz_t x, FILE *fin ); + +int fmpz_print(const fmpz_t x); + +int fmpz_fprint(FILE * file, const fmpz_t x); + +size_t fmpz_out_raw( FILE *fout, const fmpz_t x ); + +size_t fmpz_sizeinbase(const fmpz_t f, int b); + +char * fmpz_get_str(char * str, int b, const fmpz_t f); + +static __inline__ +void fmpz_swap(fmpz_t f, fmpz_t g) +{ + if (f != g) /* swapping required */ + { + fmpz t = *f; + *f = *g; + *g = t; + } +} + +int fmpz_cmp(const fmpz_t f, const fmpz_t g); + +int fmpz_cmp_ui(const fmpz_t f, ulong g); + +int fmpz_cmp_si(const fmpz_t f, slong g); + +int fmpz_cmpabs(const fmpz_t f, const fmpz_t g); + +static __inline__ +int fmpz_is_even(const fmpz_t f) +{ + if (!COEFF_IS_MPZ(*f)) + { + return !((*f) & WORD(1)); + } + else + { + return mpz_even_p(COEFF_TO_PTR(*f)); + } +} + +static __inline__ +int fmpz_is_odd(const fmpz_t f) +{ + if (!COEFF_IS_MPZ(*f)) + { + return ((*f) & WORD(1)); + } + else + { + return mpz_odd_p(COEFF_TO_PTR(*f)); + } +} + +mp_size_t fmpz_size(const fmpz_t f); + +int fmpz_sgn(const fmpz_t f); + +mp_bitcnt_t fmpz_bits(const fmpz_t f); + +mp_bitcnt_t fmpz_val2(const fmpz_t x); + +static __inline__ void +fmpz_neg(fmpz_t f1, const fmpz_t f2) +{ + if (!COEFF_IS_MPZ(*f2)) /* coeff is small */ + { + fmpz t = -*f2; /* Need to save value in case of aliasing */ + _fmpz_demote(f1); + *f1 = t; + } + else /* coeff is large */ + { + /* No need to retain value in promotion, as if aliased, both already large */ + __mpz_struct *mpz_ptr = _fmpz_promote(f1); + mpz_neg(mpz_ptr, COEFF_TO_PTR(*f2)); + } +} + +void fmpz_abs(fmpz_t f1, const fmpz_t f2); + +void fmpz_add(fmpz_t f, const fmpz_t g, const fmpz_t h); + +void fmpz_sub(fmpz_t f, const fmpz_t g, const fmpz_t h); + +void fmpz_mul_ui(fmpz_t f, const fmpz_t g, ulong x); + +void fmpz_mul_si(fmpz_t f, const fmpz_t g, slong x); + +void fmpz_mul(fmpz_t f, const fmpz_t g, const fmpz_t h); + +void fmpz_mul_2exp(fmpz_t f, const fmpz_t g, ulong exp); + +void fmpz_add_ui(fmpz_t f, const fmpz_t g, ulong x); + +void fmpz_sub_ui(fmpz_t f, const fmpz_t g, ulong x); + +void fmpz_addmul_ui(fmpz_t f, const fmpz_t g, ulong x); + +void fmpz_submul_ui(fmpz_t f, const fmpz_t g, ulong x); + +void fmpz_addmul(fmpz_t f, const fmpz_t g, const fmpz_t h); + +void fmpz_submul(fmpz_t f, const fmpz_t g, const fmpz_t h); + +void fmpz_pow_ui(fmpz_t f, const fmpz_t g, ulong exp); + +void fmpz_powm_ui(fmpz_t f, const fmpz_t g, ulong exp, const fmpz_t m); + +void fmpz_powm(fmpz_t f, const fmpz_t g, const fmpz_t e, const fmpz_t m); + +void fmpz_setbit(fmpz_t f, ulong i); + +int fmpz_tstbit(const fmpz_t f, ulong i); + +void fmpz_clrbit(fmpz_t f, ulong i); + +void fmpz_complement(fmpz_t r, const fmpz_t f); + +void fmpz_combit(fmpz_t f, ulong i); + +void fmpz_and(fmpz_t r, const fmpz_t a, const fmpz_t b); + +void fmpz_or(fmpz_t r, const fmpz_t a, const fmpz_t b); + +void fmpz_xor(fmpz_t r, const fmpz_t a, const fmpz_t b); + +mp_bitcnt_t fmpz_popcnt(const fmpz_t c); + +double fmpz_dlog(const fmpz_t x); +slong fmpz_flog(const fmpz_t x, const fmpz_t b); +slong fmpz_flog_ui(const fmpz_t x, ulong b); +slong fmpz_clog(const fmpz_t x, const fmpz_t b); +slong fmpz_clog_ui(const fmpz_t x, ulong b); + +int fmpz_sqrtmod(fmpz_t b, const fmpz_t a, const fmpz_t p); + +void fmpz_sqrt(fmpz_t f, const fmpz_t g); + +int fmpz_is_square(const fmpz_t f); + +void fmpz_root(fmpz_t r, const fmpz_t f, slong n); + +void fmpz_sqrtrem(fmpz_t f, fmpz_t r, const fmpz_t g); + +ulong fmpz_fdiv_ui(const fmpz_t g, ulong h); + +ulong fmpz_mod_ui(fmpz_t f, const fmpz_t g, ulong h); + +void fmpz_mod(fmpz_t f, const fmpz_t g, const fmpz_t h); + +static __inline__ void +fmpz_negmod(fmpz_t r, const fmpz_t a, const fmpz_t mod) +{ + if (fmpz_is_zero(a)) + fmpz_zero(r); + else + fmpz_sub(r, mod, a); +} + +void fmpz_gcd(fmpz_t f, const fmpz_t g, const fmpz_t h); + +void fmpz_lcm(fmpz_t f, const fmpz_t g, const fmpz_t h); + +void fmpz_gcdinv(fmpz_t d, fmpz_t a, const fmpz_t f, const fmpz_t g); + +void fmpz_xgcd(fmpz_t d, fmpz_t a, fmpz_t b, const fmpz_t f, const fmpz_t g); + +void fmpz_xgcd_partial(fmpz_t co2, fmpz_t co1, + fmpz_t r2, fmpz_t r1, const fmpz_t L); + +int fmpz_invmod(fmpz_t f, const fmpz_t g, const fmpz_t h); + +int fmpz_jacobi(const fmpz_t a, const fmpz_t p); + +slong _fmpz_remove(fmpz_t x, const fmpz_t f, double finv); + +slong fmpz_remove(fmpz_t rop, const fmpz_t op, const fmpz_t f); + +void fmpz_divexact(fmpz_t f, const fmpz_t g, const fmpz_t h); + +void fmpz_divexact_si(fmpz_t f, const fmpz_t g, slong h); + +void fmpz_divexact_ui(fmpz_t f, const fmpz_t g, ulong h); + +int fmpz_divisible(const fmpz_t f, const fmpz_t g); + +int fmpz_divisible_si(const fmpz_t f, slong g); + +void fmpz_cdiv_q(fmpz_t f, const fmpz_t g, const fmpz_t h); + +void fmpz_cdiv_q_si(fmpz_t f, const fmpz_t g, slong h); + +void fmpz_cdiv_q_ui(fmpz_t f, const fmpz_t g, ulong h); + +void fmpz_cdiv_q_2exp(fmpz_t f, const fmpz_t g, ulong exp); + +void fmpz_fdiv_qr(fmpz_t f, fmpz_t s, const fmpz_t g, const fmpz_t h); + +void fmpz_fdiv_qr_preinvn(fmpz_t f, fmpz_t s, const fmpz_t g, + const fmpz_t h, const fmpz_preinvn_t inv); + +void fmpz_fdiv_q(fmpz_t f, const fmpz_t g, const fmpz_t h); + +void fmpz_fdiv_r(fmpz_t f, const fmpz_t g, const fmpz_t h); + +void fmpz_fdiv_q_ui(fmpz_t f, const fmpz_t g, ulong h); + +void fmpz_fdiv_q_si(fmpz_t f, const fmpz_t g, slong h); + +void fmpz_fdiv_q_2exp(fmpz_t f, const fmpz_t g, ulong exp); + +void fmpz_fdiv_r_2exp(fmpz_t f, const fmpz_t g, ulong exp); + +void fmpz_tdiv_q(fmpz_t f, const fmpz_t g, const fmpz_t h); + +void fmpz_tdiv_qr(fmpz_t f, fmpz_t s, const fmpz_t g, const fmpz_t h); + +void fmpz_tdiv_q_ui(fmpz_t f, const fmpz_t g, ulong h); + +void fmpz_tdiv_q_si(fmpz_t f, const fmpz_t g, slong h); + +ulong fmpz_tdiv_ui(const fmpz_t g, ulong h); + +void fmpz_tdiv_q_2exp(fmpz_t f, const fmpz_t g, ulong exp); + +void fmpz_preinvn_init(fmpz_preinvn_t inv, fmpz_t f); + +void fmpz_preinvn_clear(fmpz_preinvn_t inv); + +double fmpz_get_d_2exp(slong * exp, const fmpz_t f); + +static __inline__ void +fmpz_mul2_uiui(fmpz_t f, const fmpz_t g, ulong h1, ulong h2) +{ + mp_limb_t hi, lo; + + umul_ppmm(hi, lo, h1, h2); + if (!hi) + { + fmpz_mul_ui(f, g, lo); + } + else + { + fmpz_mul_ui(f, g, h1); + fmpz_mul_ui(f, f, h2); + } +} + +static __inline__ void +fmpz_divexact2_uiui(fmpz_t f, const fmpz_t g, ulong h1, ulong h2) +{ + mp_limb_t hi, lo; + + umul_ppmm(hi, lo, h1, h2); + if (!hi) + { + fmpz_divexact_ui(f, g, lo); + } + else + { + fmpz_divexact_ui(f, g, h1); + fmpz_divexact_ui(f, f, h2); + } +} + +void fmpz_mul_tdiv_q_2exp(fmpz_t f, const fmpz_t g, const fmpz_t h, ulong exp); + +void fmpz_mul_si_tdiv_q_2exp(fmpz_t f, const fmpz_t g, slong x, ulong exp); + +void fmpz_fac_ui(fmpz_t f, ulong n); + +void fmpz_fib_ui(fmpz_t f, ulong n); + +void fmpz_bin_uiui(fmpz_t res, ulong n, ulong k); + +void _fmpz_rfac_ui(fmpz_t r, const fmpz_t x, ulong a, ulong b); + +void fmpz_rfac_ui(fmpz_t r, const fmpz_t x, ulong n); + +void fmpz_rfac_uiui(fmpz_t r, ulong x, ulong n); + +int fmpz_bit_pack(mp_ptr arr, mp_bitcnt_t shift, mp_bitcnt_t bits, + const fmpz_t coeff, int negate, int borrow); + +int fmpz_bit_unpack(fmpz_t coeff, mp_srcptr arr, mp_bitcnt_t shift, + mp_bitcnt_t bits, int negate, int borrow); + +void fmpz_bit_unpack_unsigned(fmpz_t coeff, mp_srcptr arr, + mp_bitcnt_t shift, mp_bitcnt_t bits); + +void _fmpz_CRT_ui_precomp(fmpz_t out, const fmpz_t r1, const fmpz_t m1, + ulong r2, ulong m2, mp_limb_t m2inv, const fmpz_t m1m2, mp_limb_t c, + int sign); + +void fmpz_CRT_ui(fmpz_t out, const fmpz_t r1, const fmpz_t m1, + ulong r2, ulong m2, int sign); + +#define FLINT_FMPZ_LOG_MULTI_MOD_CUTOFF 2 + +typedef struct +{ + const mp_limb_t * primes; + slong num_primes; + slong n; /* we have 2^n >= num_primes > 2^(n-1) */ + fmpz ** comb; /* Array of arrays of products */ + fmpz ** res; /* successive residues r_i^-1 mod r_{i+1} for pairs r_i, r_{i+1} */ + nmod_t * mod; +} +fmpz_comb_struct; + +typedef struct +{ + slong n; + fmpz ** comb_temp; + fmpz_t temp; + fmpz_t temp2; +} +fmpz_comb_temp_struct; + +typedef fmpz_comb_struct fmpz_comb_t[1]; +typedef fmpz_comb_temp_struct fmpz_comb_temp_t[1]; + +void fmpz_comb_temp_init(fmpz_comb_temp_t temp, const fmpz_comb_t comb); +void fmpz_comb_temp_clear(fmpz_comb_temp_t temp); + +void fmpz_comb_init(fmpz_comb_t comb, mp_srcptr primes, slong num_primes); +void fmpz_comb_clear(fmpz_comb_t comb); + +void fmpz_multi_mod_ui(mp_limb_t * out, const fmpz_t in, + const fmpz_comb_t comb, fmpz_comb_temp_t temp); + +void fmpz_multi_CRT_ui(fmpz_t output, mp_srcptr residues, + const fmpz_comb_t comb, fmpz_comb_temp_t temp, int sign); + +static __inline__ void fmpz_set_ui_smod(fmpz_t f, mp_limb_t x, mp_limb_t m) +{ + if (x <= m / 2) + fmpz_set_ui(f, x); + else + fmpz_set_si(f, x - m); +} + +mp_limb_t fmpz_abs_ubound_ui_2exp(slong * exp, const fmpz_t x, int bits); + +mp_limb_t fmpz_abs_lbound_ui_2exp(slong * exp, const fmpz_t x, int bits); + +int fmpz_is_probabprime(const fmpz_t p); + +int fmpz_is_prime_pseudosquare(const fmpz_t n); + +#ifdef __cplusplus +} +#endif + +#include "fmpz_factor.h" + +#endif + diff --git a/external/flint-2.4.3/fmpz/CRT_ui.c b/external/flint-2.4.3/fmpz/CRT_ui.c new file mode 100644 index 0000000..1d57974 --- /dev/null +++ b/external/flint-2.4.3/fmpz/CRT_ui.c @@ -0,0 +1,100 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +void +_fmpz_CRT_ui_precomp(fmpz_t out, const fmpz_t r1, const fmpz_t m1, ulong r2, + ulong m2, mp_limb_t m2inv, const fmpz_t m1m2, mp_limb_t c, int sign) +{ + mp_limb_t r1mod, s; + fmpz_t r1normal; + fmpz_t tmp; + + fmpz_init(tmp); + + /* FIXME: assume r1 moved to [0, m1); add tests for this */ + if (fmpz_sgn(r1) < 0) + { + fmpz_init(r1normal); + fmpz_add(r1normal, r1, m1); + } + else + { + *r1normal = *r1; + } + + r1mod = fmpz_fdiv_ui(r1normal, m2); + s = n_submod(r2, r1mod, m2); + s = n_mulmod2_preinv(s, c, m2, m2inv); + fmpz_mul_ui(tmp, m1, s); + fmpz_add(tmp, tmp, r1normal); + + if (fmpz_sgn(r1) < 0) + fmpz_clear(r1normal); + + if (sign) + { + fmpz_sub(out, tmp, m1m2); + if (fmpz_cmpabs(tmp, out) <= 0) + fmpz_set(out, tmp); + } + else + { + fmpz_set(out, tmp); + } + + fmpz_clear(tmp); +} + +void fmpz_CRT_ui(fmpz_t out, const fmpz_t r1, const fmpz_t m1, + ulong r2, ulong m2, int sign) +{ + mp_limb_t c; + fmpz_t m1m2; + + c = fmpz_fdiv_ui(m1, m2); + c = n_invmod(c, m2); + + if (c == 0) + { + flint_printf("Exception (fmpz_CRT_ui). m1 not invertible modulo m2.\n"); + abort(); + } + + fmpz_init(m1m2); + fmpz_mul_ui(m1m2, m1, m2); + + _fmpz_CRT_ui_precomp(out, r1, m1, r2, m2, n_preinvert_limb(m2), + m1m2, c, sign); + + fmpz_clear(m1m2); +} diff --git a/external/flint-2.4.3/fmpz/abs.c b/external/flint-2.4.3/fmpz/abs.c new file mode 100644 index 0000000..43af457 --- /dev/null +++ b/external/flint-2.4.3/fmpz/abs.c @@ -0,0 +1,48 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +void +fmpz_abs(fmpz_t f1, const fmpz_t f2) +{ + if (!COEFF_IS_MPZ(*f2)) /* coeff is small */ + { + fmpz t = FLINT_ABS(*f2); /* Need to save value in case of aliasing */ + + _fmpz_demote(f1); + + *f1 = t; + } + else /* coeff is large */ + { + /* No need to retain value in promotion, as if aliased, both already large */ + __mpz_struct *mpz_ptr = _fmpz_promote(f1); + mpz_abs(mpz_ptr, COEFF_TO_PTR(*f2)); + } +} diff --git a/external/flint-2.4.3/fmpz/abs_fits_ui.c b/external/flint-2.4.3/fmpz/abs_fits_ui.c new file mode 100644 index 0000000..d01941f --- /dev/null +++ b/external/flint-2.4.3/fmpz/abs_fits_ui.c @@ -0,0 +1,37 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +fmpz_abs_fits_ui(const fmpz_t f) +{ + if (!COEFF_IS_MPZ(*f)) + return 1; + return FLINT_ABS(COEFF_TO_PTR(*f)->_mp_size) <= 1; +} diff --git a/external/flint-2.4.3/fmpz/abs_lbound_ui_2exp.c b/external/flint-2.4.3/fmpz/abs_lbound_ui_2exp.c new file mode 100644 index 0000000..7720ec1 --- /dev/null +++ b/external/flint-2.4.3/fmpz/abs_lbound_ui_2exp.c @@ -0,0 +1,87 @@ +/*============================================================================ + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +mp_limb_t +fmpz_abs_lbound_ui_2exp(slong * exp, const fmpz_t x, int bits) +{ + mp_limb_t m; + slong shift, e, size; + fmpz c = *x; + + if (!COEFF_IS_MPZ(c)) + { + m = FLINT_ABS(c); + e = 0; + } + else + { + __mpz_struct * z = COEFF_TO_PTR(c); + size = z->_mp_size; + size = FLINT_ABS(size); + e = (size - 1) * FLINT_BITS; + + if (size == 1) + { + m = z->_mp_d[0]; + } + else /* there are two or more limbs */ + { + /* top limb (which must be nonzero) */ + m = z->_mp_d[size - 1]; + + count_leading_zeros(shift, m); + shift = FLINT_BITS - shift - bits; + e += shift; + + if (shift >= 0) + { + m >>= shift; + } + else + { + /* read a second limb to get an accurate value */ + mp_limb_t m2 = z->_mp_d[size - 2]; + m = (m << (-shift)) | (m2 >> (FLINT_BITS + shift)); + } + + *exp = e; + return m; + } + } + + count_leading_zeros(shift, m); + e += FLINT_BITS - shift - bits; + if (e >= 0) + m >>= e; + else + m <<= (-e); + *exp = e; + return m; +} diff --git a/external/flint-2.4.3/fmpz/abs_ubound_ui_2exp.c b/external/flint-2.4.3/fmpz/abs_ubound_ui_2exp.c new file mode 100644 index 0000000..cd31bd8 --- /dev/null +++ b/external/flint-2.4.3/fmpz/abs_ubound_ui_2exp.c @@ -0,0 +1,112 @@ +/*============================================================================ + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +mp_limb_t +fmpz_abs_ubound_ui_2exp(slong * exp, const fmpz_t x, int bits) +{ + mp_limb_t m; + slong shift, e, size; + fmpz c = *x; + + if (!COEFF_IS_MPZ(c)) + { + m = FLINT_ABS(c); + e = 0; + } + else + { + /* mpz */ + __mpz_struct * z = COEFF_TO_PTR(c); + size = z->_mp_size; + size = FLINT_ABS(size); + e = (size - 1) * FLINT_BITS; + + if (size == 1) + { + m = z->_mp_d[0]; + } + else /* there are two or more limbs */ + { + /* top limb (which must be nonzero) */ + m = z->_mp_d[size - 1]; + + count_leading_zeros(shift, m); + shift = FLINT_BITS - shift - bits; + e += shift; + + if (shift >= 0) + { + /* round up */ + m = (m >> shift) + 1; + } + else + { + /* read a second limb to get an accurate value */ + mp_limb_t m2 = z->_mp_d[size - 2]; + m = (m << (-shift)) | (m2 >> (FLINT_BITS + shift)); + /* round up */ + m++; + } + + /* adding 1 caused overflow to the next power of two */ + if ((m & (m - UWORD(1))) == UWORD(0)) + { + m = UWORD(1) << (bits - 1); + e++; + } + + *exp = e; + return m; + } + } + + /* single limb, adjust */ + count_leading_zeros(shift, m); + e = FLINT_BITS - shift - bits; + + if (e >= 0) + { + m = (m >> e) + 1; + + /* overflowed to next power of two */ + if ((m & (m - 1)) == UWORD(0)) + { + m = UWORD(1) << (bits - 1); + e++; + } + } + else + { + m <<= (-e); + } + + *exp = e; + return m; +} diff --git a/external/flint-2.4.3/fmpz/add.c b/external/flint-2.4.3/fmpz/add.c new file mode 100644 index 0000000..8fe1ca8 --- /dev/null +++ b/external/flint-2.4.3/fmpz/add.c @@ -0,0 +1,69 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +void fmpz_add(fmpz_t f, const fmpz_t g, const fmpz_t h) +{ + fmpz c1 = *g; + fmpz c2 = *h; + + if (!COEFF_IS_MPZ(c1)) /* g is small */ + { + if (!COEFF_IS_MPZ(c2)) /* both inputs are small */ + { + fmpz_set_si(f, c1 + c2); + } else /* g is small, h is large */ + { + __mpz_struct * mpz3 = _fmpz_promote(f); /* g is saved and h is large */ + __mpz_struct * mpz2 = COEFF_TO_PTR(c2); + if (c1 < WORD(0)) flint_mpz_sub_ui(mpz3, mpz2, -c1); + else flint_mpz_add_ui(mpz3, mpz2, c1); + _fmpz_demote_val(f); /* may have cancelled */ + } + } + else + { + if (!COEFF_IS_MPZ(c2)) /* g is large, h is small */ + { + __mpz_struct * mpz3 = _fmpz_promote(f); /* h is saved and g is large */ + __mpz_struct * mpz1 = COEFF_TO_PTR(c1); + if (c2 < WORD(0)) flint_mpz_sub_ui(mpz3, mpz1, -c2); + else flint_mpz_add_ui(mpz3, mpz1, c2); + _fmpz_demote_val(f); /* may have cancelled */ + } + else /* g and h are large */ + { + __mpz_struct * mpz3 = _fmpz_promote(f); /* aliasing means f is already large */ + __mpz_struct * mpz1 = COEFF_TO_PTR(c1); + __mpz_struct * mpz2 = COEFF_TO_PTR(c2); + mpz_add(mpz3, mpz1, mpz2); + _fmpz_demote_val(f); /* may have cancelled */ + } + } +} diff --git a/external/flint-2.4.3/fmpz/add_ui.c b/external/flint-2.4.3/fmpz/add_ui.c new file mode 100644 index 0000000..b9e44c6 --- /dev/null +++ b/external/flint-2.4.3/fmpz/add_ui.c @@ -0,0 +1,58 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +void fmpz_add_ui(fmpz_t f, const fmpz_t g, ulong x) +{ + fmpz c = *g; + + if (!COEFF_IS_MPZ(c)) /* g is small */ + { + mp_limb_t sum[2]; + if (c >= WORD(0)) /* both operands non-negative */ + { + add_ssaaaa(sum[1], sum[0], 0, c, 0, x); + fmpz_set_uiui(f, sum[1], sum[0]); + } + else /* coeff is negative, x positive */ + { + if (-c > x) + fmpz_set_si(f, x + c); /* can't overflow as g is small and x smaller */ + else + fmpz_set_ui(f, x + c); /* won't be negative and has to be less than x */ + } + } + else + { + __mpz_struct * mpz_ptr2 = _fmpz_promote(f); /* g is already large */ + __mpz_struct * mpz_ptr = COEFF_TO_PTR(c); + flint_mpz_add_ui(mpz_ptr2, mpz_ptr, x); + _fmpz_demote_val(f); /* cancellation may have occurred */ + } +} diff --git a/external/flint-2.4.3/fmpz/addmul.c b/external/flint-2.4.3/fmpz/addmul.c new file mode 100644 index 0000000..fd27f33 --- /dev/null +++ b/external/flint-2.4.3/fmpz/addmul.c @@ -0,0 +1,58 @@ +/*============================================================================ + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +void fmpz_addmul(fmpz_t f, const fmpz_t g, const fmpz_t h) +{ + fmpz c1, c2; + __mpz_struct * mpz_ptr; + + c1 = *g; + + if (!COEFF_IS_MPZ(c1)) /* g is small */ + { + if (c1 < WORD(0)) fmpz_submul_ui(f, h, -c1); + else fmpz_addmul_ui(f, h, c1); + return; + } + + c2 = *h; + + if (!COEFF_IS_MPZ(c2)) /* h is small */ + { + if (c2 < WORD(0)) fmpz_submul_ui(f, g, -c2); + else fmpz_addmul_ui(f, g, c2); + return; + } + + /* both g and h are large */ + mpz_ptr = _fmpz_promote_val(f); + mpz_addmul(mpz_ptr, COEFF_TO_PTR(c1), COEFF_TO_PTR(c2)); + _fmpz_demote_val(f); /* cancellation may have occurred */ +} diff --git a/external/flint-2.4.3/fmpz/addmul_ui.c b/external/flint-2.4.3/fmpz/addmul_ui.c new file mode 100644 index 0000000..fbac3da --- /dev/null +++ b/external/flint-2.4.3/fmpz/addmul_ui.c @@ -0,0 +1,109 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +void +fmpz_addmul_ui(fmpz_t f, const fmpz_t g, ulong x) +{ + fmpz c1, r; + + c1 = *g; + if ((x == 0) || (c1 == 0)) /* product is zero */ + return; + + r = *f; + if (r == 0) + { + fmpz_mul_ui(f, g, x); /* we are adding product to 0 */ + return; + } + + if (x == UWORD(1)) /* special case, adding g*1 to f */ + { + fmpz_add(f, f, g); + return; + } + + if (c1 == UWORD(1)) /* special case, adding 1*x to f */ + { + fmpz_add_ui(f, f, x); + return; + } + + if (!COEFF_IS_MPZ(c1)) /* c1 is small */ + { + mp_limb_t prod[2]; + ulong uc1 = FLINT_ABS(c1); + + umul_ppmm(prod[1], prod[0], uc1, x); /* compute product */ + + if (prod[1] == 0) /* product fits in one limb */ + { + if (c1 < WORD(0)) + fmpz_sub_ui(f, f, prod[0]); + else + fmpz_add_ui(f, f, prod[0]); + return; + } + else if ((prod[1] == 1) && (!COEFF_IS_MPZ(r)) && ((r ^ c1) < WORD(0))) + { + /* + only chance at cancellation is if product is one bit past + a limb and res is small and opposite sign to this product + */ + ulong ur = FLINT_ABS(r); + if (ur > prod[0]) /* cancellation will occur */ + { + fmpz_set_ui(f, prod[0] - ur); + if (r > WORD(0)) + fmpz_neg(f, f); + return; + } + } + + /* + in all remaining cases res is either big already, + or will be big in the end + */ + { + __mpz_struct * mpz_ptr = _fmpz_promote_val(f); + mpz_t temp; /* set up a temporary, cheap mpz_t to contain prod */ + temp->_mp_d = prod; + temp->_mp_size = (c1 < WORD(0) ? -2 : 2); + mpz_add(mpz_ptr, mpz_ptr, temp); + _fmpz_demote_val(f); /* cancellation may have occurred */ + } + } + else /* c1 is large */ + { + __mpz_struct * mpz_ptr = _fmpz_promote_val(f); + flint_mpz_addmul_ui(mpz_ptr, COEFF_TO_PTR(c1), x); + _fmpz_demote_val(f); /* cancellation may have occurred */ + } +} diff --git a/external/flint-2.4.3/fmpz/and.c b/external/flint-2.4.3/fmpz/and.c new file mode 100644 index 0000000..1da7e4a --- /dev/null +++ b/external/flint-2.4.3/fmpz/and.c @@ -0,0 +1,69 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Thomas M. DuBuisson + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +void fmpz_and(fmpz_t f, const fmpz_t g, const fmpz_t h) +{ + fmpz c1,c2; + c1 = *g; + c2 = *h; + if(!COEFF_IS_MPZ(c1)) + { + if(!COEFF_IS_MPZ(c2)) /* both inputs are small */ + { + fmpz_set_si(f, c1 & c2); + } else /* g is small, h is large */ + { + mpz_t tmp; + __mpz_struct *mpz3 = _fmpz_promote(f); + flint_mpz_init_set_si(tmp, c1); + mpz_and(mpz3, COEFF_TO_PTR(c2), tmp); + _fmpz_demote_val(f); + mpz_clear(tmp); + } + } else + { + if(!COEFF_IS_MPZ(c2)) /* g is large, h is small */ + { + mpz_t tmp; + __mpz_struct *mpz3 = _fmpz_promote(f); + flint_mpz_init_set_si(tmp, c2); + mpz_and(mpz3, COEFF_TO_PTR(c1), tmp); + _fmpz_demote_val(f); + mpz_clear(tmp); + } else /* g and h are large */ + { + __mpz_struct * mpz3 = _fmpz_promote(f); + __mpz_struct * mpz1 = COEFF_TO_PTR(c1); + __mpz_struct * mpz2 = COEFF_TO_PTR(c2); + mpz_and(mpz3, mpz1, mpz2); + _fmpz_demote_val(f); + } + } +} diff --git a/external/flint-2.4.3/fmpz/bin_uiui.c b/external/flint-2.4.3/fmpz/bin_uiui.c new file mode 100644 index 0000000..b9bab2b --- /dev/null +++ b/external/flint-2.4.3/fmpz/bin_uiui.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +/* TODO: speedup for small n,k */ +void fmpz_bin_uiui(fmpz_t res, ulong n, ulong k) +{ + __mpz_struct * t = _fmpz_promote(res); + flint_mpz_bin_uiui(t, n, k); + _fmpz_demote_val(res); +} diff --git a/external/flint-2.4.3/fmpz/bit_pack.c b/external/flint-2.4.3/fmpz/bit_pack.c new file mode 100644 index 0000000..73d01bd --- /dev/null +++ b/external/flint-2.4.3/fmpz/bit_pack.c @@ -0,0 +1,185 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" + +int +fmpz_bit_pack(mp_ptr arr, mp_bitcnt_t shift, mp_bitcnt_t bits, + const fmpz_t coeff, int negate, int borrow) +{ + mp_limb_t save = arr[0]; + fmpz c = *coeff; + int sign = fmpz_sgn(coeff); + mp_limb_t cy; + ulong limbs = (shift + bits) / FLINT_BITS; + ulong rem_bits = (shift + bits) % FLINT_BITS; + mp_limb_t mask; + ulong size; + + if (sign == 0) /* special case, deal with zero (store -borrow) */ + { + if (borrow) + { + /* store -1 shifted and add save back in */ + arr[0] = ((~(mp_limb_t) 0) << shift) + save; + + /* com remaining limbs */ + if (limbs > 1) + flint_mpn_store(arr + 1, limbs - 1, ~(mp_limb_t) 0); + + /* com remaining bits */ + if (limbs) + { + if (rem_bits) + arr[limbs] = (((mp_limb_t) 1) << rem_bits) - (mp_limb_t) 1; + } + else + { + /* mask off final limb */ + mask = (((mp_limb_t) 1) << rem_bits) - (mp_limb_t) 1; + arr[limbs] &= mask; + } + + } + return borrow; + } + + /* + Let |c| = b. If c is -ve and negate == 0 or c is positive and negate is 1 + we want -b - borrow. + + If c is +ve and negate is 0 or c is negative and negate == 1, we want + b - borrow. + */ + if ((sign ^ negate) < 0) /* -b - borrow = com(b) + 1 - borrow */ + { + if (!COEFF_IS_MPZ(c)) + { + /* compute d = -b - borrow */ + mp_limb_t d = (c < WORD(0) ? c - borrow : -c - borrow); + + /* store d << shift and add save back into place */ + arr[0] = (d << shift) + save; + + /* store carry from d<> (FLINT_BITS - shift)) + + ((~(mp_limb_t) 0) << shift); + else + arr[1] = ~(mp_limb_t) 0; + } + + size = 2; + } + else + { + __mpz_struct * ptr = COEFF_TO_PTR(c); + size = FLINT_ABS(ptr->_mp_size); + + /* complement coefficient into arr */ + mpn_com_n(arr, ptr->_mp_d, size); + + /* deal with +1 - borrow */ + if (!borrow) + mpn_add_1(arr, arr, size, 1); /* cannot be a carry, else we com'd 0 */ + + /* shift into place */ + if (shift) + { + cy = mpn_lshift(arr, arr, size, shift); + if (limbs + (rem_bits != 0) > size) + arr[size++] = ((~(mp_limb_t) 0) << shift) + cy; + } + + /* add back in saved bits from start of field */ + arr[0] += save; + } + + if (limbs >= size) + { + /* com any additional limbs */ + if (limbs > size) + flint_mpn_store(arr + size, limbs - size, ~(mp_limb_t) 0); + + /* com remaining bits */ + if (rem_bits) + arr[limbs] = (((mp_limb_t) 1) << rem_bits) - (mp_limb_t) 1; + } + else + { + /* mask off final limb */ + mask = (((mp_limb_t) 1) << rem_bits) - (mp_limb_t) 1; + arr[limbs] &= mask; + } + return 1; + } + else /* b - borrow */ + { + if (!COEFF_IS_MPZ(c)) + { + /* compute d = b - borrow */ + mp_limb_t d = (c < WORD(0) ? -c - borrow : c - borrow); + + /* store d< 1) + { + if (shift) + arr[1] = (d >> (FLINT_BITS - shift)); + } + } + else + { + __mpz_struct *ptr = COEFF_TO_PTR(c); + size = FLINT_ABS(ptr->_mp_size); + + /* shift into place */ + if (shift) + { + cy = mpn_lshift(arr, ptr->_mp_d, size, shift); + if (cy) + arr[size++] = cy; + } + else + flint_mpn_copyi(arr, ptr->_mp_d, size); + + /* deal with - borrow */ + if (borrow) + mpn_sub_1(arr, arr, size, ((mp_limb_t) 1) << shift); + + /* add back in saved bits from start of field */ + arr[0] += save; + } + + return 0; + } +} diff --git a/external/flint-2.4.3/fmpz/bit_unpack.c b/external/flint-2.4.3/fmpz/bit_unpack.c new file mode 100644 index 0000000..4620537 --- /dev/null +++ b/external/flint-2.4.3/fmpz/bit_unpack.c @@ -0,0 +1,222 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" + +int +fmpz_bit_unpack(fmpz_t coeff, mp_srcptr arr, mp_bitcnt_t shift, + mp_bitcnt_t bits, int negate, int borrow) +{ + mp_limb_t mask, sign; + ulong limbs = (shift + bits) / FLINT_BITS; + ulong rem_bits = (shift + bits) % FLINT_BITS; + + /* determine if field is positive or negative */ + if (rem_bits) + sign = ((((mp_limb_t) 1) << (rem_bits - 1)) & arr[limbs]); + else + sign = ((((mp_limb_t) 1) << (FLINT_BITS - 1)) & arr[limbs - 1]); + + if (bits <= FLINT_BITS - 2) /* fits into a small coeff */ + { + _fmpz_demote(coeff); + + /* mask for the given number of bits */ + mask = (((mp_limb_t) 1) << bits) - (mp_limb_t) 1; + + if (limbs + (rem_bits != 0) > 1) /* field crosses a limb boundary */ + (*coeff) = + ((arr[0] >> shift) + (arr[1] << (FLINT_BITS - shift))) & mask; + else /* field is in first limb only, mask it */ + (*coeff) = (arr[0] >> shift) & mask; + + /* sign extend */ + if (sign) + (*coeff) += ((~(mp_limb_t) 0) << bits); + + /* determine whether we need to return a borrow */ + sign = (*coeff < (mp_limb_signed_t) 0 ? (mp_limb_t) 1 : (mp_limb_t) 0); + + /* deal with borrow */ + if (borrow) + { + (*coeff)++; + if ((*coeff) > COEFF_MAX) + { + fmpz v = *coeff; + *coeff = 0; + fmpz_set_ui(coeff, v); + } + } + + /* negate the coeff if necessary */ + if (negate) + fmpz_neg(coeff, coeff); + + return (sign != (mp_limb_t) 0); + } + else /* large coefficient */ + { + __mpz_struct * mpz_ptr; + mp_limb_t * p; + ulong l, b; + + mpz_ptr = _fmpz_promote(coeff); + + /* the number of limbs to hold the bitfield _including_ b extra bits */ + l = (bits - 1) / FLINT_BITS + 1; + b = bits % FLINT_BITS; + + /* allocate space for l limbs only */ + mpz_realloc(mpz_ptr, l); + p = mpz_ptr->_mp_d; + + /* shift in l limbs */ + if (shift) + mpn_rshift(p, arr, l, shift); + else + flint_mpn_copyi(p, arr, l); + + /* shift in any rem_bits that weren't already shifted */ + if (limbs + (rem_bits != 0) > l) + p[l - 1] += (arr[limbs] << (FLINT_BITS - shift)); + + /* mask off the last limb, if not full */ + if (b) + { + mask = (((mp_limb_t) 1) << b) - (mp_limb_t) 1; + p[l - 1] &= mask; + } + + if (sign != (mp_limb_t) 0) + { + /* sign extend */ + if (b) + p[l - 1] += ((~(mp_limb_t) 0) << b); + + /* negate */ + mpn_com_n(p, p, l); + if (!borrow) + mpn_add_1(p, p, l, 1); + + /* normalise */ + while (l && (p[l - 1] == (mp_limb_t) 0)) + l--; + + mpz_ptr->_mp_size = -l; + + sign = 1; + } + else + { + /* deal with borrow */ + if (borrow) + mpn_add_1(p, p, l, 1); + + /* normalise */ + while (l && (p[l - 1] == (mp_limb_t) 0)) + l--; + + mpz_ptr->_mp_size = l; + sign = 0; + } + + /* negate if required */ + if (negate) + mpz_neg(mpz_ptr, mpz_ptr); + + /* coeff may fit in a small */ + _fmpz_demote_val(coeff); + + return sign; + } +} + +void +fmpz_bit_unpack_unsigned(fmpz_t coeff, mp_srcptr arr, + mp_bitcnt_t shift, mp_bitcnt_t bits) +{ + ulong limbs = (shift + bits) / FLINT_BITS; + ulong rem_bits = (shift + bits) % FLINT_BITS; + mp_limb_t mask; + + if (bits <= FLINT_BITS - 2) /* fits into a small coeff */ + { + _fmpz_demote(coeff); + + /* mask for the given number of bits */ + mask = (((mp_limb_t) 1) << bits) - (mp_limb_t) 1; + + if (limbs + (rem_bits != 0) > 1) /* field crosses a limb boundary */ + (*coeff) = + ((arr[0] >> shift) + (arr[1] << (FLINT_BITS - shift))) & mask; + else /* field is in first limb only, mask it */ + (*coeff) = (arr[0] >> shift) & mask; + } + else /* large coefficient */ + { + __mpz_struct * mpz_ptr; + mp_limb_t * p; + ulong l, b; + + mpz_ptr = _fmpz_promote(coeff); + + /* the number of limbs to hold the bitfield _including_ b extra bits */ + l = (bits - 1) / FLINT_BITS + 1; + b = bits % FLINT_BITS; + + /* allocate space for l limbs only */ + mpz_realloc(mpz_ptr, l); + p = mpz_ptr->_mp_d; + + /* shift in l limbs */ + if (shift) + mpn_rshift(p, arr, l, shift); + else + flint_mpn_copyi(p, arr, l); + + /* shift in any rem_bits that weren't already shifted */ + if (limbs + (rem_bits != 0) > l) + p[l - 1] += (arr[limbs] << (FLINT_BITS - shift)); + + /* mask off the last limb, if not full */ + if (b) + { + mask = (((mp_limb_t) 1) << b) - (mp_limb_t) 1; + p[l - 1] &= mask; + } + + /* normalise */ + while (l && (p[l - 1] == (mp_limb_t) 0)) + l--; + + mpz_ptr->_mp_size = l; + + /* coeff may fit in a small */ + _fmpz_demote_val(coeff); + } +} diff --git a/external/flint-2.4.3/fmpz/bits.c b/external/flint-2.4.3/fmpz/bits.c new file mode 100644 index 0000000..913f8a4 --- /dev/null +++ b/external/flint-2.4.3/fmpz/bits.c @@ -0,0 +1,37 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +mp_bitcnt_t fmpz_bits(const fmpz_t f) +{ + fmpz d = *f; + + if (!COEFF_IS_MPZ(d)) return FLINT_BIT_COUNT(FLINT_ABS(d)); + else return mpz_sizeinbase(COEFF_TO_PTR(d), 2); +} diff --git a/external/flint-2.4.3/fmpz/cdiv_q.c b/external/flint-2.4.3/fmpz/cdiv_q.c new file mode 100644 index 0000000..19856f9 --- /dev/null +++ b/external/flint-2.4.3/fmpz/cdiv_q.c @@ -0,0 +1,87 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" + +void +fmpz_cdiv_q(fmpz_t f, const fmpz_t g, const fmpz_t h) +{ + fmpz c1 = *g; + fmpz c2 = *h; + + if (fmpz_is_zero(h)) + { + flint_printf("Exception (fmpz_cdiv_q). Division by zero.\n"); + abort(); + } + + if (!COEFF_IS_MPZ(c1)) /* g is small */ + { + if (!COEFF_IS_MPZ(c2)) /* h is also small */ + { + fmpz q = c1 / c2; /* compute C quotient */ + fmpz r = c1 - c2 * q; /* compute remainder */ + + if (r && ((c2 ^ r) > WORD(0))) /* r != 0, c2 and r same sign */ + ++q; + + fmpz_set_si(f, q); + } + else /* h is large and g is small */ + { + if ((c1 < WORD(0) && fmpz_sgn(h) < 0) || (c1 > WORD(0) && fmpz_sgn(h) > 0)) /* signs are the same */ + fmpz_one(f); /* quotient is positive, round up to one */ + else + fmpz_zero(f); /* quotient is zero, or negative, round up to zero */ + } + } + else /* g is large */ + { + __mpz_struct * mpz_ptr = _fmpz_promote(f); + + if (!COEFF_IS_MPZ(c2)) /* h is small */ + { + if (c2 > 0) /* h > 0 */ + { + flint_mpz_cdiv_q_ui(mpz_ptr, COEFF_TO_PTR(c1), c2); + } + else + { + flint_mpz_fdiv_q_ui(mpz_ptr, COEFF_TO_PTR(c1), -c2); + mpz_neg(mpz_ptr, mpz_ptr); + } + } + else /* both are large */ + { + mpz_cdiv_q(mpz_ptr, COEFF_TO_PTR(c1), COEFF_TO_PTR(c2)); + } + _fmpz_demote_val(f); /* division by h may result in small value */ + } +} diff --git a/external/flint-2.4.3/fmpz/cdiv_q_2exp.c b/external/flint-2.4.3/fmpz/cdiv_q_2exp.c new file mode 100644 index 0000000..704e262 --- /dev/null +++ b/external/flint-2.4.3/fmpz/cdiv_q_2exp.c @@ -0,0 +1,46 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +void fmpz_cdiv_q_2exp(fmpz_t f, const fmpz_t g, ulong exp) +{ + fmpz d = *g; + + if (!COEFF_IS_MPZ(d)) /* g is small */ + { + fmpz_set_si(f, -((-d) >> FLINT_MIN(exp, FLINT_BITS - 2))); + } + else /*g is large */ + { + __mpz_struct * mpz_ptr = _fmpz_promote(f); /* g is already large */ + mpz_cdiv_q_2exp(mpz_ptr, COEFF_TO_PTR(d), exp); + _fmpz_demote_val(f); /* division may make value small */ + } +} diff --git a/external/flint-2.4.3/fmpz/cdiv_q_si.c b/external/flint-2.4.3/fmpz/cdiv_q_si.c new file mode 100644 index 0000000..ce79225 --- /dev/null +++ b/external/flint-2.4.3/fmpz/cdiv_q_si.c @@ -0,0 +1,69 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" + +void +fmpz_cdiv_q_si(fmpz_t f, const fmpz_t g, slong h) +{ + fmpz c1 = *g; + slong c2 = h; + + if (h == 0) + { + flint_printf("Exception (fmpz_cdiv_q_si). Division by zero.\n"); + abort(); + } + + if (!COEFF_IS_MPZ(c1)) /* g is small */ + { + fmpz q = c1 / c2; /* compute C quotient */ + fmpz r = c1 - c2 * q; /* compute remainder */ + + if (r && ((c1 ^ c2) > WORD(0))) + ++q; + + fmpz_set_si(f, q); + } + else /* g is large */ + { + __mpz_struct *mpz_ptr = _fmpz_promote(f); + + if (c2 > 0) + { + flint_mpz_cdiv_q_ui(mpz_ptr, COEFF_TO_PTR(c1), c2); + } + else + { + flint_mpz_fdiv_q_ui(mpz_ptr, COEFF_TO_PTR(c1), -(ulong) c2); + mpz_neg(mpz_ptr, mpz_ptr); + } + _fmpz_demote_val(f); /* division by h may result in small value */ + } +} diff --git a/external/flint-2.4.3/fmpz/cdiv_q_ui.c b/external/flint-2.4.3/fmpz/cdiv_q_ui.c new file mode 100644 index 0000000..3c44600 --- /dev/null +++ b/external/flint-2.4.3/fmpz/cdiv_q_ui.c @@ -0,0 +1,69 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" + +void +fmpz_cdiv_q_ui(fmpz_t f, const fmpz_t g, ulong h) +{ + fmpz c1 = *g; + ulong c2 = h; + + if (h == 0) + { + flint_printf("Exception: division by zero in fmpz_cdiv_q_ui\n"); + abort(); + } + + if (!COEFF_IS_MPZ(c1)) /* g is small */ + { + if (c1 > 0) + { + ulong q = c1 / c2; + ulong r = c1 - c2 * q; + + if (r) + ++q; + + fmpz_set_ui(f, q); + } + else + { + fmpz_set_si(f, - (((ulong) -c1) / c2)); + } + } + else /* g is large */ + { + __mpz_struct *mpz_ptr = _fmpz_promote(f); + + flint_mpz_cdiv_q_ui(mpz_ptr, COEFF_TO_PTR(c1), c2); + _fmpz_demote_val(f); /* division by h may result in small value */ + } +} diff --git a/external/flint-2.4.3/fmpz/clear_readonly.c b/external/flint-2.4.3/fmpz/clear_readonly.c new file mode 100644 index 0000000..2d38ca5 --- /dev/null +++ b/external/flint-2.4.3/fmpz/clear_readonly.c @@ -0,0 +1,41 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" + +void fmpz_clear_readonly(fmpz_t f) +{ + if (COEFF_IS_MPZ(*f)) + { + __mpz_struct *ptr = COEFF_TO_PTR(*f); + + mpz_init(ptr); + _fmpz_clear_mpz(*f); + *f = WORD(0); + } +} + diff --git a/external/flint-2.4.3/fmpz/clog.c b/external/flint-2.4.3/fmpz/clog.c new file mode 100644 index 0000000..9884fea --- /dev/null +++ b/external/flint-2.4.3/fmpz/clog.c @@ -0,0 +1,78 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "ulong_extras.h" + +slong +fmpz_clog(const fmpz_t n, const fmpz_t b) +{ + fmpz_t t; + int sign; + slong r; + + if (fmpz_is_one(n)) + return 0; + + if (!COEFF_IS_MPZ(*b)) + return fmpz_clog_ui(n, *b); + + if (fmpz_cmp(n, b) <= 0) + return 1; + + r = fmpz_dlog(n) / fmpz_dlog(b); + + fmpz_init(t); + fmpz_pow_ui(t, b, r); + sign = fmpz_cmp(t, n); + + /* Adjust down */ + if (sign > 0) + { + while (sign > 0) + { + fmpz_divexact(t, t, b); + sign = fmpz_cmp(t, n); + r--; + } + r += (sign != 0); + } + /* Adjust up */ + else if (sign < 0) + { + while (sign < 0) + { + fmpz_mul(t, t, b); + sign = fmpz_cmp(t, n); + r++; + } + } + + fmpz_clear(t); + return r; +} diff --git a/external/flint-2.4.3/fmpz/clog_ui.c b/external/flint-2.4.3/fmpz/clog_ui.c new file mode 100644 index 0000000..4c5bcf7 --- /dev/null +++ b/external/flint-2.4.3/fmpz/clog_ui.c @@ -0,0 +1,89 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "ulong_extras.h" + +slong +fmpz_clog_ui(const fmpz_t n, ulong b) +{ + fmpz_t t; + int sign; + slong r; + + if (fmpz_is_one(n)) + return 0; + + if (b == 2) + { + fmpz_init(t); + fmpz_sub_ui(t, n, 1); + r = fmpz_bits(t); + fmpz_clear(t); + return r; + } + + if (!COEFF_IS_MPZ(*n)) + return n_clog(*n, b); + + if (fmpz_cmp_ui(n, b) <= 0) + return 1; + + r = fmpz_dlog(n) / log(b); + + fmpz_init(t); + fmpz_set_ui(t, b); + fmpz_pow_ui(t, t, r); + sign = fmpz_cmp(t, n); + + /* Adjust down */ + if (sign > 0) + { + while (sign > 0) + { + fmpz_divexact_ui(t, t, b); + sign = fmpz_cmp(t, n); + r--; + } + r += (sign != 0); + } + /* Adjust up */ + else if (sign < 0) + { + while (sign < 0) + { + fmpz_mul_ui(t, t, b); + sign = fmpz_cmp(t, n); + r++; + } + } + + fmpz_clear(t); + return r; +} diff --git a/external/flint-2.4.3/fmpz/clrbit.c b/external/flint-2.4.3/fmpz/clrbit.c new file mode 100644 index 0000000..2634e24 --- /dev/null +++ b/external/flint-2.4.3/fmpz/clrbit.c @@ -0,0 +1,46 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz.h" + +void fmpz_clrbit(fmpz_t f, ulong i) +{ + if (!COEFF_IS_MPZ(*f)) + { + if (i < FLINT_BITS - 2) + { + *f &= ~(WORD(1) << i); + } + /* i >= FLINT_BITS --> nop */ + } + else + { + __mpz_struct *ptr = COEFF_TO_PTR(*f); + + mpz_clrbit(ptr, i); + _fmpz_demote_val(f); + } +} + diff --git a/external/flint-2.4.3/fmpz/cmp.c b/external/flint-2.4.3/fmpz/cmp.c new file mode 100644 index 0000000..9fe973b --- /dev/null +++ b/external/flint-2.4.3/fmpz/cmp.c @@ -0,0 +1,61 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/***************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +fmpz_cmp(const fmpz_t f, const fmpz_t g) +{ + int sign; + + if (f == g) + return 0; /* aliased inputs */ + + if (!COEFF_IS_MPZ(*f)) + { + if (!COEFF_IS_MPZ(*g)) + { + return (*f < *g ? -1 : *f > *g); + } + else /* f is small, g is large */ + { + sign = mpz_sgn(COEFF_TO_PTR(*g)); + return (*f >= 0 && sign < 0) ? 1 : -sign; + } + } + else + { + if (!COEFF_IS_MPZ(*g)) /* f is large, and g is small */ + { + sign = mpz_sgn(COEFF_TO_PTR(*f)); + return (*g >= 0 && sign < 0) ? -1 : sign; + } + else + return mpz_cmp(COEFF_TO_PTR(*f), COEFF_TO_PTR(*g)); + } +} diff --git a/external/flint-2.4.3/fmpz/cmp_si.c b/external/flint-2.4.3/fmpz/cmp_si.c new file mode 100644 index 0000000..5c74cba --- /dev/null +++ b/external/flint-2.4.3/fmpz/cmp_si.c @@ -0,0 +1,41 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +fmpz_cmp_si(const fmpz_t f, slong g) +{ + fmpz c = *f; + + if (!COEFF_IS_MPZ(c)) /* f is small */ + return c < g ? -1 : c > g; + else /* f is large */ + return flint_mpz_cmp_si(COEFF_TO_PTR(c), g); +} diff --git a/external/flint-2.4.3/fmpz/cmp_ui.c b/external/flint-2.4.3/fmpz/cmp_ui.c new file mode 100644 index 0000000..8054000 --- /dev/null +++ b/external/flint-2.4.3/fmpz/cmp_ui.c @@ -0,0 +1,45 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/***************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +fmpz_cmp_ui(const fmpz_t f, ulong g) +{ + fmpz c = *f; + + if (!COEFF_IS_MPZ(c)) /* f is small */ + { + if (c < WORD(0) || g > COEFF_MAX) + return -1; + else + return c < (slong) g ? -1 : c > (slong) g; + } + else /* f is large */ + return flint_mpz_cmp_ui(COEFF_TO_PTR(c), g); +} diff --git a/external/flint-2.4.3/fmpz/cmpabs.c b/external/flint-2.4.3/fmpz/cmpabs.c new file mode 100644 index 0000000..77df1c4 --- /dev/null +++ b/external/flint-2.4.3/fmpz/cmpabs.c @@ -0,0 +1,51 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int fmpz_cmpabs(const fmpz_t f, const fmpz_t g) +{ + if (f == g) return 0; /* aliased inputs */ + + if (!COEFF_IS_MPZ(*f)) + { + if (!COEFF_IS_MPZ(*g)) + { + mp_limb_t uf = FLINT_ABS(*f); + mp_limb_t ug = FLINT_ABS(*g); + + return (uf < ug ? -1 : (uf > ug)); + } + else return -1; + } + else + { + if (!COEFF_IS_MPZ(*g)) return 1; /* f is large, so if g isn't... */ + else return mpz_cmpabs(COEFF_TO_PTR(*f), COEFF_TO_PTR(*g)); + } +} diff --git a/external/flint-2.4.3/fmpz/comb_clear.c b/external/flint-2.4.3/fmpz/comb_clear.c new file mode 100644 index 0000000..4f8cb33 --- /dev/null +++ b/external/flint-2.4.3/fmpz/comb_clear.c @@ -0,0 +1,79 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" +#include "fmpz_vec.h" + + +void fmpz_comb_temp_clear(fmpz_comb_temp_t temp) +{ + slong n, i, j; + + n = temp->n; + j = (WORD(1) << (n - 1)); + + for (i = 0; i < n; i++) + { + _fmpz_vec_clear(temp->comb_temp[i], j); + j /= 2; + } + + flint_free(temp->comb_temp); + + fmpz_clear(temp->temp); + fmpz_clear(temp->temp2); +} + +void +fmpz_comb_clear(fmpz_comb_t comb) +{ + slong i, j, n; + + n = comb->n; + + /* Size of top level */ + j = (WORD(1) << (n - 1)); + + /* Clear arrays at each level */ + for (i = 0; i < n; i++) + { + _fmpz_vec_clear(comb->comb[i], j); + _fmpz_vec_clear(comb->res[i], j); + j /= 2; + } + + if (n) + { + flint_free(comb->comb); + flint_free(comb->res); + } + + flint_free(comb->mod); +} diff --git a/external/flint-2.4.3/fmpz/comb_init.c b/external/flint-2.4.3/fmpz/comb_init.c new file mode 100644 index 0000000..85b8f27 --- /dev/null +++ b/external/flint-2.4.3/fmpz/comb_init.c @@ -0,0 +1,157 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" +#include "nmod_vec.h" +#include "fmpz_vec.h" + + +void fmpz_comb_temp_init(fmpz_comb_temp_t temp, const fmpz_comb_t comb) +{ + slong n, i, j; + + /* Allocate space for comb_temp */ + temp->n = n = comb->n; + temp->comb_temp = (fmpz **) flint_malloc(n * sizeof(fmpz *)); + + j = (WORD(1) << (n - 1)); + for (i = 0; i < n; i++) + { + temp->comb_temp[i] = _fmpz_vec_init(j); + j /= 2; + } + + fmpz_init(temp->temp); + fmpz_init(temp->temp2); +} + +void +fmpz_comb_init(fmpz_comb_t comb, mp_srcptr primes, slong num_primes) +{ + slong i, j; + slong n, num; + ulong log_comb, log_res; + fmpz_t temp, temp2; + + comb->primes = primes; + comb->num_primes = num_primes; + + n = FLINT_BIT_COUNT(num_primes); + comb->n = n; + + /* Create nmod_poly modulus information */ + comb->mod = (nmod_t *) flint_malloc(sizeof(nmod_t) * num_primes); + for (i = 0; i < num_primes; i++) + nmod_init(&comb->mod[i], primes[i]); + + /* Nothing to do */ + if (n == 0) + return; + + /* Allocate space for comb and res */ + comb->comb = (fmpz **) flint_malloc(n * sizeof(fmpz *)); + comb->res = (fmpz **) flint_malloc(n * sizeof(fmpz *)); + + /* Size of top level */ + j = (WORD(1) << (n - 1)); + + /* Initialise arrays at each level */ + for (i = 0; i < n; i++) + { + comb->comb[i] = _fmpz_vec_init(j); + comb->res[i] = _fmpz_vec_init(j); + j /= 2; + } + + /* Compute products of pairs of primes and place in comb */ + for (i = 0, j = 0; i + 2 <= num_primes; i += 2, j++) + { + fmpz_set_ui(comb->comb[0] + j, primes[i]); + fmpz_mul_ui(comb->comb[0] + j, comb->comb[0] + j, primes[i+1]); + } + + /* In case number of primes is odd */ + if (i < num_primes) + { + fmpz_set_ui(comb->comb[0] + j, primes[i]); + i += 2; + j++; + } + + /* Set the rest of the entries on that row of the comb to 1 */ + num = (WORD(1) << n); + for (; i < num; i += 2, j++) + { + fmpz_one(comb->comb[0] + j); + } + + /* Compute rest of comb by multiplying in pairs */ + log_comb = 1; + num /= 2; + while (num >= 2) + { + for (i = 0, j = 0; i < num; i += 2, j++) + { + fmpz_mul(comb->comb[log_comb] + j, comb->comb[log_comb-1] + i, + comb->comb[log_comb-1] + i + 1); + } + log_comb++; + num /= 2; + } + + /* Compute inverses from pairs of primes */ + fmpz_init(temp); + fmpz_init(temp2); + + for (i = 0, j = 0; i + 2 <= num_primes; i += 2, j++) + { + fmpz_set_ui(temp, primes[i]); + fmpz_set_ui(temp2, primes[i+1]); + fmpz_invmod(comb->res[0] + j, temp, temp2); + } + + fmpz_clear(temp); + fmpz_clear(temp2); + + /* Compute remaining inverses, each level + combining pairs from the level below */ + log_res = 1; + num = (WORD(1) << (n - 1)); + + while (log_res < n) + { + for (i = 0, j = 0; i < num; i += 2, j++) + { + fmpz_invmod(comb->res[log_res] + j, comb->comb[log_res-1] + i, + comb->comb[log_res-1] + i + 1); + } + log_res++; + num /= 2; + } +} diff --git a/external/flint-2.4.3/fmpz/combit.c b/external/flint-2.4.3/fmpz/combit.c new file mode 100644 index 0000000..bb823c7 --- /dev/null +++ b/external/flint-2.4.3/fmpz/combit.c @@ -0,0 +1,50 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz.h" + +void fmpz_combit(fmpz_t f, ulong i) +{ + if (!COEFF_IS_MPZ(*f)) + { + if (i < FLINT_BITS - 2) + { + *f ^= (WORD(1) << i); + } + else /* i >= FLINT_BITS */ + { + __mpz_struct *ptr = _fmpz_promote_val(f); + mpz_combit(ptr, i); + _fmpz_demote_val(f); + } + } + else + { + __mpz_struct *ptr = COEFF_TO_PTR(*f); + mpz_combit(ptr, i); + _fmpz_demote_val(f); + } +} + diff --git a/external/flint-2.4.3/fmpz/complement.c b/external/flint-2.4.3/fmpz/complement.c new file mode 100644 index 0000000..625d9e1 --- /dev/null +++ b/external/flint-2.4.3/fmpz/complement.c @@ -0,0 +1,55 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Thomas M. DuBuisson + +******************************************************************************/ + +#include "fmpz.h" + +void fmpz_complement(fmpz_t r, const fmpz_t f) +{ + if (!COEFF_IS_MPZ(*f)) /* f is small */ + { + slong res = ~(*f); + fmpz_set_si(r, res); + } else /* f is big */ + { + if(r != f) { /* not aliased */ + __mpz_struct *ptr, *ptr2; + ptr = _fmpz_promote(r); + ptr2 = COEFF_TO_PTR(*f); + mpz_com(ptr, ptr2); + _fmpz_demote_val(r); + } else { /* alaised */ + fmpz_t tmp; + __mpz_struct *ptr, *ptr2; + fmpz_init(tmp); + ptr = _fmpz_promote(tmp); + ptr2 = COEFF_TO_PTR(*f); + mpz_com(ptr, ptr2); + _fmpz_demote_val(tmp); + fmpz_set(r,tmp); + fmpz_clear(tmp); + } + } +} + diff --git a/external/flint-2.4.3/fmpz/divexact.c b/external/flint-2.4.3/fmpz/divexact.c new file mode 100644 index 0000000..505a825 --- /dev/null +++ b/external/flint-2.4.3/fmpz/divexact.c @@ -0,0 +1,74 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +void +fmpz_divexact(fmpz_t f, const fmpz_t g, const fmpz_t h) +{ + fmpz c1 = *g; + fmpz c2 = *h; + + if (fmpz_is_zero(h)) + { + flint_printf("Exception (fmpz_divexact). Division by zero.\n"); + abort(); + } + + if (!COEFF_IS_MPZ(c1)) /* g is small, h must be also or division isn't exact */ + { + fmpz_set_si(f, c1 / c2); + } + else /* g is large */ + { + __mpz_struct * mpz_ptr = _fmpz_promote(f); + + if (!COEFF_IS_MPZ(c2)) /* h is small */ + { + if (c2 > 0) /* h > 0 */ + { + flint_mpz_divexact_ui(mpz_ptr, COEFF_TO_PTR(c1), c2); + _fmpz_demote_val(f); /* division by h may result in small value */ + } + else + { + flint_mpz_divexact_ui(mpz_ptr, COEFF_TO_PTR(c1), -c2); + _fmpz_demote_val(f); /* division by h may result in small value */ + + fmpz_neg(f, f); + } + } + else /* both are large */ + { + mpz_divexact(mpz_ptr, COEFF_TO_PTR(c1), COEFF_TO_PTR(c2)); + _fmpz_demote_val(f); /* division by h may result in small value */ + } + } +} diff --git a/external/flint-2.4.3/fmpz/divexact_si.c b/external/flint-2.4.3/fmpz/divexact_si.c new file mode 100644 index 0000000..6232247 --- /dev/null +++ b/external/flint-2.4.3/fmpz/divexact_si.c @@ -0,0 +1,64 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +void fmpz_divexact_si(fmpz_t f, const fmpz_t g, slong h) +{ + fmpz c1 = *g; + + if (h == 0) + { + flint_printf("Exception (fmpz_divexact_si). Division by zero.\n"); + abort(); + } + + if (!COEFF_IS_MPZ(c1)) /* g is small */ + { + fmpz_set_si(f, c1 / h); + } + else /* g is large */ + { + __mpz_struct * mpz_ptr = _fmpz_promote(f); + + if (h > 0) + { + flint_mpz_divexact_ui(mpz_ptr, COEFF_TO_PTR(c1), h); + _fmpz_demote_val(f); /* division by h may result in small value */ + } + else + { + flint_mpz_divexact_ui(mpz_ptr, COEFF_TO_PTR(c1), -h); + _fmpz_demote_val(f); /* division by h may result in small value */ + fmpz_neg(f, f); + } + } +} diff --git a/external/flint-2.4.3/fmpz/divexact_ui.c b/external/flint-2.4.3/fmpz/divexact_ui.c new file mode 100644 index 0000000..da528e0 --- /dev/null +++ b/external/flint-2.4.3/fmpz/divexact_ui.c @@ -0,0 +1,55 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +void fmpz_divexact_ui(fmpz_t f, const fmpz_t g, ulong h) +{ + fmpz c1 = *g; + + if (h == 0) + { + flint_printf("Exception (fmpz_divexact_ui). Division by zero.\n"); + abort(); + } + + if (!COEFF_IS_MPZ(c1)) /* g is small */ + { + fmpz_set_si(f, c1 / (slong) h); + } + else /* g is large */ + { + __mpz_struct * mpz_ptr = _fmpz_promote(f); + + flint_mpz_divexact_ui(mpz_ptr, COEFF_TO_PTR(c1), h); + _fmpz_demote_val(f); /* division by h may result in small value */ + } +} diff --git a/external/flint-2.4.3/fmpz/divisible.c b/external/flint-2.4.3/fmpz/divisible.c new file mode 100644 index 0000000..3c0b44a --- /dev/null +++ b/external/flint-2.4.3/fmpz/divisible.c @@ -0,0 +1,64 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int fmpz_divisible(const fmpz_t x, const fmpz_t p) +{ + fmpz y = *x; + fmpz q = *p; + + if (y == WORD(0)) + { + return 1; + } + + if (!COEFF_IS_MPZ(y)) + { + if (!COEFF_IS_MPZ(q)) + { + return !(y % q); + } + else + { + return 0; + } + } + else + { + if (!COEFF_IS_MPZ(q)) + { + return flint_mpz_divisible_ui_p(COEFF_TO_PTR(y), q); + } + else + { + return mpz_divisible_p(COEFF_TO_PTR(y), COEFF_TO_PTR(q)); + } + } +} + diff --git a/external/flint-2.4.3/fmpz/divisible_si.c b/external/flint-2.4.3/fmpz/divisible_si.c new file mode 100644 index 0000000..008812c --- /dev/null +++ b/external/flint-2.4.3/fmpz/divisible_si.c @@ -0,0 +1,49 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int fmpz_divisible_si(const fmpz_t x, slong p) +{ + fmpz y = *x; + + if (y == WORD(0)) + { + return 1; + } + + if (!COEFF_IS_MPZ(y)) + { + return !(y % p); + } + else + { + return flint_mpz_divisible_ui_p(COEFF_TO_PTR(y), p); + } +} + diff --git a/external/flint-2.4.3/fmpz/dlog.c b/external/flint-2.4.3/fmpz/dlog.c new file mode 100644 index 0000000..1d6bfc4 --- /dev/null +++ b/external/flint-2.4.3/fmpz/dlog.c @@ -0,0 +1,52 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "ulong_extras.h" + +double +fmpz_dlog(const fmpz_t x) +{ + if (!COEFF_IS_MPZ(*x)) + { + return log(*x); + } + else + { + double s; + slong e; + +#if defined(__MPIR_VERSION) + s = mpz_get_d_2exp(&e, COEFF_TO_PTR(*x)); +#else + s = mpz_get_d_2exp((long *) &e, COEFF_TO_PTR(*x)); +#endif + + return log(s) + e * 0.69314718055994530942; + } +} diff --git a/external/flint-2.4.3/fmpz/doc/fmpz.txt b/external/flint-2.4.3/fmpz/doc/fmpz.txt new file mode 100644 index 0000000..4a0afcc --- /dev/null +++ b/external/flint-2.4.3/fmpz/doc/fmpz.txt @@ -0,0 +1,1155 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Sebastian Pancratz + +******************************************************************************/ + +******************************************************************************* + + Memory management + +******************************************************************************* + +void fmpz_init(fmpz_t f) + + A small \code{fmpz_t} is initialised, i.e.\ just a \code{slong}. + The value is set to zero. + +void fmpz_init2(fmpz_t f, ulong limbs) + + Initialises the given \code{fmpz_t} to have space for the given + number of limbs. + + If \code{limbs} is zero then a small \code{fmpz_t} is allocated, + i.e.\ just a \code{slong}. The value is also set to zero. It is + not necessary to call this function except to save time. A call + to \code{fmpz_init} will do just fine. + +void fmpz_clear(fmpz_t f) + + Clears the given \code{fmpz_t}, releasing any memory associated + with it, either back to the stack or the OS, depending on + whether the reentrant or non-reentrant version of FLINT is built. + +void fmpz_init_set(fmpz_t f, const fmpz_t g) + + Initialises $f$ and sets it to the value of $g$. + +void fmpz_init_set_ui(fmpz_t f, ulong g) + + Initialises $f$ and sets it to the value of $g$. + +******************************************************************************* + + Random generation + + For thread-safety, the randomisation methods take as one of their + parameters an object of type \code{flint_rand_t}. Before calling + any of the randomisation functions such an object first has to be + initialised with a call to \code{flint_randinit()}. When one is + finished generating random numbers, one should call + \code{flint_randclear()} to clean up. + +******************************************************************************* + +void fmpz_randbits(fmpz_t f, flint_rand_t state, mp_bitcnt_t bits) + + Generates a random signed integer whose absolute value has the given + number of bits. + +void fmpz_randtest(fmpz_t f, flint_rand_t state, mp_bitcnt_t bits) + + Generates a random signed integer whose absolute value has a number + of bits which is random from $0$ up to \code{bits} inclusive. + +void fmpz_randtest_unsigned(fmpz_t f, flint_rand_t state, mp_bitcnt_t bits) + + Generates a random unsigned integer whose value has a number + of bits which is random from $0$ up to \code{bits} inclusive. + +void fmpz_randtest_not_zero(fmpz_t f, flint_rand_t state, mp_bitcnt_t bits) + + As per \code{fmpz_randtest}, but the result will not be $0$. + If \code{bits} is set to $0$, an exception will result. + +void fmpz_randm(fmpz_t f, flint_rand_t state, const fmpz_t m) + + Generates a random integer in the range $0$ to $m - 1$ inclusive. + +void fmpz_randtest_mod(fmpz_t f, flint_rand_t state, const fmpz_t m) + + Generates a random integer in the range $0$ to $m - 1$ inclusive, + with an increased probability of generating values close to + the endpoints. + +void fmpz_randtest_mod_signed(fmpz_t f, flint_rand_t state, const fmpz_t m) + + Generates a random integer in the range $(-m/2, m/2]$, with an + increased probability of generating values close to the + endpoints or close to zero. + + +******************************************************************************* + + Conversion + +******************************************************************************* + +slong fmpz_get_si(const fmpz_t f) + + Returns $f$ as a \code{slong}. The result is undefined + if $f$ does not fit into a \code{slong}. + +ulong fmpz_get_ui(const fmpz_t f) + + Returns $f$ as an \code{ulong}. The result is undefined + if $f$ does not fit into an \code{ulong} or is negative. + +void fmpz_set_d(fmpz_t f, double c) + + Sets $f$ to the \code{double} $c$, rounding down towards zero if + the value of $c$ is fractional. The outcome is undefined if $c$ is + infinite, not-a-number, or subnormal. + +double fmpz_get_d(const fmpz_t f) + + Returns $f$ as a \code{double}, rounding down towards zero if + \code{f} cannot be represented exactly. The outcome is undefined + if \code{f} is too large to fit in the normal range of a double. + +double fmpz_get_d_2exp(slong * exp, const fmpz_t f) + + Returns $f$ as a normalized \code{double} along with a $2$-exponent + \code{exp}, i.e.\ if $r$ is the return value then \code{f = r * 2^exp}, + to within 1 ULP. + +void fmpz_get_mpz(mpz_t x, const fmpz_t f) + + Sets the \code{mpz_t} $x$ to the same value as $f$. + +char * fmpz_get_str(char * str, int b, const fmpz_t f) + + Returns the representation of $f$ in base~$b$, which can vary + between $2$ and $62$, inclusive. + + If \code{str} is \code{NULL}, the result string is allocated by + the function. Otherwise, it is up to the caller to ensure that + the allocated block of memory is sufficiently large. + +void fmpz_set_si(fmpz_t f, slong val) + + Sets $f$ to the given \code{slong} value. + +void fmpz_set_ui(fmpz_t f, ulong val) + + Sets $f$ to the given \code{ulong} value. + +void fmpz_neg_ui(fmpz_t f, ulong val) + + Sets $f$ to the given \code{ulong} value, and then negates $f$. + +void fmpz_set_uiui(fmpz_t f, mp_limb_t hi, mp_limb_t lo) + + Sets $f$ to \code{lo}, plus \code{hi} shifted to the left by + \code{FLINT_BITS}. + +void fmpz_neg_uiui(fmpz_t f, mp_limb_t hi, mp_limb_t lo) + + Sets $f$ to \code{lo}, plus \code{hi} shifted to the left by + \code{FLINT_BITS}, and then negates $f$. + +void fmpz_set_mpz(fmpz_t f, const mpz_t x) + + Sets $f$ to the given \code{mpz_t} value. + +int fmpz_set_str(fmpz_t f, const char * str, int b) + + Sets $f$ to the value given in the null-terminated string \code{str}, + in base~$b$. The base~$b$ can vary between $2$ and $62$, inclusive. + Returns $0$ if the string contains a valid input and $-1$ otherwise. + +void fmpz_set_ui_smod(fmpz_t f, mp_limb_t x, mp_limb_t m) + + Sets $f$ to the signed remainder $y \equiv x \bmod m$ satisfying + $-m/2 < y \leq m/2$, given $x$ which is assumed to satisfy + $0 \leq x < m$. + +void flint_mpz_init_set_readonly(mpz_t z, const fmpz_t f) + + Sets the unitialised \code{mpz_t} $z$ to the value of the + readonly \code{fmpz_t} $f$. + + Note that it is assumed that $f$ does not change during + the lifetime of $z$. + + The integer $z$ has to be cleared by a call to + \code{flint_mpz_clear_readonly()}. + + The suggested use of the two functions is as follows: + \begin{lstlisting}[language=C] + fmpz_t f; + ... + { + mpz_t z; + + flint_mpz_init_set_readonly(z, f); + foo(..., z); + flint_mpz_clear_readonly(z); + } + \end{lstlisting} + + This provides a convenient function for user code, only + requiring to work with the types \code{fmpz_t} and \code{mpz_t}. + + In critical code, the following approach may be favourable: + \begin{lstlisting}[language=C] + fmpz_t f; + ... + { + __mpz_struct *z; + + z = _fmpz_promote_val(f); + foo(..., z); + _fmpz_demote_val(f); + } + \end{lstlisting} + +void flint_mpz_clear_readonly(mpz_t z) + + Clears the readonly \code{mpz_t} $z$. + +void fmpz_init_set_readonly(fmpz_t f, const mpz_t z) + + Sets the uninitialised \code{fmpz_t} $f$ to a readonly + version of the integer $z$. + + Note that the value of $z$ is assumed to remain constant + throughout the lifetime of $f$. + + The \code{fmpz_t} $f$ has to be cleared by calling the + function \code{fmpz_clear_readonly()}. + + The suggested use of the two functions is as follows: + \begin{lstlisting}[language=C] + mpz_t z; + ... + { + fmpz_t f; + + fmpz_init_set_readonly(f, z); + foo(..., f); + fmpz_clear_readonly(f); + } + \end{lstlisting} + +void fmpz_clear_readonly(fmpz_t f) + + Clears the readonly \code{fmpz_t} $f$. + +******************************************************************************* + + Input and output + +******************************************************************************* + +int fmpz_read(fmpz_t f) + + Reads a multiprecision integer from \code{stdin}. The format is + an optional minus sign, followed by one or more digits. The + first digit should be non-zero unless it is the only digit. + + In case of success, returns a positive number. In case of failure, + returns a non-positive number. + + This convention is adopted in light of the return values of + \code{scanf} from the standard library and \code{mpz_inp_str} + from MPIR. + +int fmpz_fread(FILE * file, fmpz_t f) + + Reads a multiprecision integer from the stream \code{file}. The + format is an optional minus sign, followed by one or more digits. + The first digit should be non-zero unless it is the only digit. + + In case of success, returns a positive number. In case of failure, + returns a non-positive number. + + This convention is adopted in light of the return values of + \code{scanf} from the standard library and \code{mpz_inp_str} + from MPIR. + +size_t fmpz_inp_raw( fmpz_t x, FILE *fin ) + + Reads a multiprecision integer from the stream \code{file}. The + format is raw binary format write by \code{fmpz_out_raw}. + + In case of success, return a posivitive number, indicating number of bytes read. + In case of failure 0. + + This function calls the \code{mpz_inp_raw} function in library gmp. So that it + can read the raw data writen by \code{mpz_inp_raw} directly. + +int fmpz_print(fmpz_t x) + + Prints the value $x$ to \code{stdout}, without a carriage return(CR). + The value is printed as either~$0$, the decimal digits of a + positive integer, or a minus sign followed by the digits of + a negative integer. + + In case of success, returns a positive number. In case of failure, + returns a non-positive number. + + This convention is adopted in light of the return values of + \code{flint_printf} from the standard library and \code{mpz_out_str} + from MPIR. + +int fmpz_fprint(FILE * file, fmpz_t x) + + Prints the value $x$ to \code{file}, without a carriage return(CR). + The value is printed as either~$0$, the decimal digits of a + positive integer, or a minus sign followed by the digits of + a negative integer. + + In case of success, returns a positive number. In case of failure, + returns a non-positive number. + + This convention is adopted in light of the return values of + \code{flint_printf} from the standard library and \code{mpz_out_str} + from MPIR. + +size_t fmpz_out_raw( FILE *fout, const fmpz_t x ) + + Writes the value $x$ to \code{file}. + The value is writen in raw binary format. The integer is written in + portable format, with 4 bytes of size information, and that many bytes + of linbs. Both the size and the limbs are written in decreasing + significance order (i.e., in big-endian). + + The output can be read with \code{fmpz_inp_raw}. + + In case of success, return a positive number, indicating number of bytes written. + In case of failure, return 0. + + The output of this can also be read by \code{mpz_inp_raw} from GMP >= 2, + Since this function calls the \code{mpz_inp_raw} function in library gmp. + + +******************************************************************************* + + Basic properties and manipulation + +******************************************************************************* + +size_t fmpz_sizeinbase(const fmpz_t f, int b) + + Returns the size of the absolute value of $f$ in base~$b$, measured in + numbers of digits. The base~$b$ can be between $2$ and $62$, inclusive. + +mp_bitcnt_t fmpz_bits(const fmpz_t f) + + Returns the number of bits required to store the absolute + value of $f$. If $f$ is $0$ then $0$ is returned. + +mp_size_t fmpz_size(const fmpz_t f) + + Returns the number of limbs required to store the absolute + value of $f$. If $f$ is zero then $0$ is returned. + +int fmpz_sgn(const fmpz_t f) + + Returns $-1$ if the sign of $f$ is negative, $+1$ if it is positive, + otherwise returns $0$. + +mp_bitcnt_t fmpz_val2(const fmpz_t f) + + Returns the exponent of the largest power of two dividing $f$, or + equivalently the number of trailing zeros in the binary expansion of $f$. + If $f$ is zero then $0$ is returned. + +void fmpz_swap(fmpz_t f, fmpz_t g) + + Efficiently swaps $f$ and $g$. No data is copied. + +void fmpz_set(fmpz_t f, const fmpz_t g) + + Sets $f$ to the same value as $g$. + +void fmpz_zero(fmpz_t f) + + Sets $f$ to zero. + +void fmpz_one(fmpz_t f) + + Sets $f$ to one. + +int fmpz_abs_fits_ui(const fmpz_t f) + + Returns whether the absolute value of $f$ + fits into an \code{ulong}. + +int fmpz_fits_si(const fmpz_t f) + + Returns whether the value of $f$ fits into a \code{slong}. + +void fmpz_setbit(fmpz_t f, ulong i) + + Sets bit index~$i$ of $f$. + +int fmpz_tstbit(const fmpz_t f, ulong i) + + Test bit index~$i$ of $f$ and return $0$ or $1$, accordingly. + +mp_limb_t fmpz_abs_lbound_ui_2exp(slong * exp, const fmpz_t x, int bits) + + For nonzero $x$, returns a mantissa $m$ with exactly \code{bits} bits and + sets \code{exp} to an exponent $e$, such that $|x| \ge m 2^e$. The number + of bits must be between 1 and \code{FLINT_BITS} inclusive. + The mantissa is guaranteed to be correctly rounded. + +mp_limb_t fmpz_abs_ubound_ui_2exp(slong * exp, const fmpz_t x, int bits) + + For nonzero $x$, returns a mantissa $m$ with exactly \code{bits} bits + and sets \code{exp} to an exponent $e$, such that $|x| \le m 2^e$. + The number of bits must be between 1 and \code{FLINT_BITS} inclusive. + The mantissa is either correctly rounded or one unit too large + (possibly meaning that the exponent is one too large, + if the mantissa is a power of two). + +******************************************************************************* + + Comparison + +******************************************************************************* + +int fmpz_cmp(const fmpz_t f, const fmpz_t g) + + Returns a negative value if $f < g$, positive value if $g < f$, + otherwise returns $0$. + +int fmpz_cmp_ui(const fmpz_t f, ulong g) + + Returns a negative value if $f < g$, positive value if $g < f$, + otherwise returns $0$. + +int fmpz_cmp_si(const fmpz_t f, slong g) + + Returns a negative value if $f < g$, positive value if $g < f$, + otherwise returns $0$. + +int fmpz_cmpabs(const fmpz_t f, const fmpz_t g) + + Returns a negative value if $\abs{f} < \abs{g}$, positive value if + $\abs{g} < \abs{f}$, otherwise returns $0$. + +int fmpz_equal(const fmpz_t f, const fmpz_t g) + + Returns $1$ if $f$ is equal to $g$, otherwise returns $0$. + +int fmpz_equal_ui(const fmpz_t f, ulong g) + + Returns $1$ if $f$ is equal to $g$, otherwise returns $0$. + +int fmpz_equal_si(const fmpz_t f, slong g) + + Returns $1$ if $f$ is equal to $g$, otherwise returns $0$. + +int fmpz_is_zero(const fmpz_t f) + + Returns $1$ if $f$ is $0$, otherwise returns $0$. + +int fmpz_is_one(const fmpz_t f) + + Returns $1$ if $f$ is equal to one, otherwise returns $0$. + +int fmpz_is_pm1(const fmpz_t f) + + Returns $1$ if $f$ is equal to one or minus one, otherwise returns + $0$. + +int fmpz_is_even(const fmpz_t f) + + Returns whether the integer $f$ is even. + +int fmpz_is_odd(const fmpz_t f) + + Returns whether the integer $f$ is odd. + +******************************************************************************* + + Basic arithmetic + +******************************************************************************* + +void fmpz_neg(fmpz_t f1, const fmpz_t f2) + + Sets $f_1$ to $-f_2$. + +void fmpz_abs(fmpz_t f1, const fmpz_t f2) + + Sets $f_1$ to the absolute value of $f_2$. + +void fmpz_add(fmpz_t f, const fmpz_t g, const fmpz_t h) + + Sets $f$ to $g + h$. + +void fmpz_add_ui(fmpz_t f, const fmpz_t g, ulong x) + + Sets $f$ to $g + x$ where $x$ is an \code{ulong}. + +void fmpz_sub(fmpz_t f, const fmpz_t g, const fmpz_t h) + + Sets $f$ to $g - h$. + +void fmpz_sub_ui(fmpz_t f, const fmpz_t g, ulong x) + + Sets $f$ to $g - x$ where $x$ is an \code{ulong}. + +void fmpz_mul(fmpz_t f, const fmpz_t g, const fmpz_t h) + + Sets $f$ to $g \times h$. + +void fmpz_mul_si(fmpz_t f, const fmpz_t g, slong x) + + Sets $f$ to $g \times x$ where $x$ is a \code{slong}. + +void fmpz_mul_ui(fmpz_t f, const fmpz_t g, ulong x) + + Sets $f$ to $g \times x$ where $x$ is an \code{ulong}. + +void fmpz_mul2_uiui(fmpz_t f, const fmpz_t g, ulong x, ulong y) + + Sets $f$ to $g \times x \times y$ where $x$ and $y$ are of type + \code{ulong}. + +void fmpz_mul_2exp(fmpz_t f, const fmpz_t g, ulong e) + + Sets $f$ to $g \times 2^e$. + +void fmpz_addmul(fmpz_t f, const fmpz_t g, const fmpz_t h) + + Sets $f$ to $f + g \times h$. + +void fmpz_addmul_ui(fmpz_t f, const fmpz_t g, ulong x) + + Sets $f$ to $f + g \times x$ where $x$ is an \code{ulong}. + +void fmpz_submul(fmpz_t f, const fmpz_t g, const fmpz_t h) + + Sets $f$ to $f - g \times h$. + +void fmpz_submul_ui(fmpz_t f, const fmpz_t g, ulong x) + + Sets $f$ to $f - g \times x$ where $x$ is an \code{ulong}. + +void fmpz_cdiv_q(fmpz_t f, const fmpz_t g, const fmpz_t h) + + Sets $f$ to the quotient of $g$ by $h$, rounding up towards + infinity. If $h$ is $0$ an exception is raised. + +void fmpz_cdiv_q_si(fmpz_t f, const fmpz_t g, slong h) + + Sets $f$ to the quotient of $g$ by $h$, rounding up towards + infinity. If $h$ is $0$ an exception is raised. + +void fmpz_cdiv_q_ui(fmpz_t f, const fmpz_t g, ulong h) + + Sets $f$ to the quotient of $g$ by $h$, rounding up towards + infinity. If $h$ is $0$ an exception is raised. + +void fmpz_fdiv_q_2exp(fmpz_t f, const fmpz_t g, ulong exp) + + Sets $f$ to $g$ divided by \code{2^exp}, rounding down + towards minus infinity. + +void fmpz_fdiv_q(fmpz_t f, const fmpz_t g, const fmpz_t h) + + Sets $f$ to the quotient of $g$ by $h$, rounding down towards + minus infinity. If $h$ is $0$ an exception is raised. + +void fmpz_fdiv_q_si(fmpz_t f, const fmpz_t g, slong h) + + Set $f$ to the quotient of $g$ by $h$, rounding down towards + minus infinity. If $h$ is $0$ an exception is raised. + +void fmpz_fdiv_q_ui(fmpz_t f, const fmpz_t g, ulong h) + + Set $f$ to the quotient of $g$ by $h$, rounding down towards + minus infinity. If $h$ is $0$ an exception is raised. + +void fmpz_fdiv_qr(fmpz_t f, fmpz_t s, const fmpz_t g, const fmpz_t h) + + Sets $f$ to the quotient of $g$ by $h$, rounding down towards + minus infinity and $s$ to the remainder. If $h$ is $0$ an exception + is raised. + +void fmpz_fdiv_r(fmpz_t f, const fmpz_t g, const fmpz_t h) + + Sets $f$ to the remainder from dividing $g$ by $h$ and rounding + the quotient down towards minus infinity. If $h$ is $0$ an exception + is raised. + +void fmpz_fdiv_q_2exp(fmpz_t f, const fmpz_t g, ulong exp) + + Sets $f$ to $g$ divided by \code{2^exp}, rounding down towards + minus infinity. + +void fmpz_fdiv_r_2exp(fmpz_t f, const fmpz_t g, ulong exp) + + Sets $f$ to the remainder of $g$ upon division by \code{2^exp}, + where the remainder is non-negative. + +void fmpz_tdiv_q(fmpz_t f, const fmpz_t g, const fmpz_t h) + + Sets $f$ to the quotient of $g$ by $h$, rounding down towards + zero. If $h$ is $0$ an exception is raised. + +void fmpz_tdiv_qr(fmpz_t f, fmpz_t s, const fmpz_t g, const fmpz_t h) + + Sets $f$ to the quotient of $g$ by $h$, rounding down towards + zero and $s$ to the remainder. If $h$ is $0$ an exception + is raised. + +void fmpz_tdiv_q_si(fmpz_t f, const fmpz_t g, slong h) + + Set $f$ to the quotient of $g$ by $h$, rounding down towards + zero. If $h$ is $0$ an exception is raised. + +void fmpz_tdiv_q_ui(fmpz_t f, const fmpz_t g, ulong h) + + Set $f$ to the quotient of $g$ by $h$, rounding down towards + zero. If $h$ is $0$ an exception is raised. + +ulong fmpz_tdiv_ui(const fmpz_t g, ulong h) + + Returns the absolute value of the remainder from dividing $g$ + by $h$, rounding towards zero. If $h$ is $0$ an exception is + raised. + +void fmpz_tdiv_q_2exp(fmpz_t f, const fmpz_t g, ulong exp) + + Sets $f$ to $g$ divided by \code{2^exp}, rounding down towards + zero. + +void fmpz_divexact(fmpz_t f, const fmpz_t g, const fmpz_t h) + + Sets $f$ to the quotient of $g$ and $h$, assuming that the + division is exact, i.e.\ $g$ is a multiple of $h$. If $h$ + is $0$ an exception is raised. + +void fmpz_divexact_si(fmpz_t f, const fmpz_t g, slong h) + + Sets $f$ to the quotient of $g$ and $h$, assuming that the + division is exact, i.e.\ $g$ is a multiple of $h$. If $h$ + is $0$ an exception is raised. + +void fmpz_divexact_ui(fmpz_t f, const fmpz_t g, ulong h) + + Sets $f$ to the quotient of $g$ and $h$, assuming that the + division is exact, i.e.\ $g$ is a multiple of $h$. If $h$ + is $0$ an exception is raised. + +void fmpz_divexact2_uiui(fmpz_t f, const fmpz_t g, ulong x, ulong y) + + Sets $f$ to the quotient of $g$ and $h = x \times y$, assuming that + the division is exact, i.e.\ $g$ is a multiple of $h$. + If $x$ or $y$ is $0$ an exception is raised. + +int fmpz_divisible(const fmpz_t f, const fmpz_t g) + + Returns whether $f$ is divisible by $g > 0$. + +int fmpz_divisible_si(const fmpz_t f, slong g) + + Returns whether $f$ is divisible by $g > 0$. + +void fmpz_mod(fmpz_t f, const fmpz_t g, const fmpz_t h) + + Sets $f$ to the remainder of $g$ divided by $h$. The remainder + is always taken to be positive. + +ulong fmpz_mod_ui(fmpz_t f, const fmpz_t g, ulong x) + + Sets $f$ to $g$ reduced modulo $x$ where $x$ is an + \code{ulong}. If $x$ is $0$ an exception will result. + +ulong fmpz_fdiv_ui(const fmpz_t g, ulong x) + + Returns the remainder of $g$ modulo $x$ where $x$ is an + \code{ulong}, without changing $g$. If $x$ is $0$ an + exception will result. + +void fmpz_preinvn_init(fmpz_preinvn_t inv, fmpz_t f) + + Compute a precomputed inverse \code{inv} of \code{f} for use in the + \code{preinvn} functions listed below. + +void fmpz_preinvn_clear(fmpz_preinvn_t inv) + + Clean up the resources used by a precomputed inverse created with the + \code{fmpz_preinvn_init} function. + +void fmpz_fdiv_qr_preinvn(fmpz_t f, fmpz_t s, const fmpz_t g, + const fmpz_t h, const fmpz_preinvn_t hinv) + + As per \code{fmpz_fdiv_qr}, but takes a precomputed inverse \code{hinv} + of $h$ constructed using \code{fmpz_preinvn}. + + This function will be faster than \code{fmpz_fdiv_qr_preinvn} when the + number of limbs of $h$ is at least \code{PREINVN_CUTOFF}. + +void fmpz_pow_ui(fmpz_t f, const fmpz_t g, ulong x) + + Sets $f$ to $g^x$ where $x$ is an \code{ulong}. If + $x$ is $0$ and $g$ is $0$, then $f$ will be set to $1$. + +void fmpz_powm_ui(fmpz_t f, const fmpz_t g, ulong e, const fmpz_t m) + + Sets $f$ to $g^e \bmod{m}$. If $e = 0$, sets $f$ to $1$. + + Assumes that $m \neq 0$, raises an \code{abort} signal otherwise. + +void fmpz_powm(fmpz_t f, const fmpz_t g, const fmpz_t e, const fmpz_t m) + + Sets $f$ to $g^e \bmod{m}$. If $e = 0$, sets $f$ to $1$. + + Assumes that $m \neq 0$, raises an \code{abort} signal otherwise. + +slong fmpz_clog(const fmpz_t x, const fmpz_t b) + +slong fmpz_clog_ui(const fmpz_t x, ulong b) + + Returns $\ceil{\log_b x}$. + + Assumes that $x \geq 1$ and $b \geq 2$ and that + the return value fits into a signed \code{slong}. + +slong fmpz_flog(const fmpz_t x, const fmpz_t b) + +slong fmpz_flog_ui(const fmpz_t x, ulong b) + + Returns $\floor{\log_b x}$. + + Assumes that $x \geq 1$ and $b \geq 2$ and that + the return value fits into a signed \code{slong}. + +double fmpz_dlog(const fmpz_t x) + + Returns a double precision approximation of the + natural logarithm of $x$. + + The accuracy depends on the implementation of the floating-point + logarithm provided by the C standard library. The result can + typically be expected to have a relative error no greater than 1-2 bits. + +int fmpz_sqrtmod(fmpz_t b, const fmpz_t a, const fmpz_t p) + + Returns whether $a$ is a quadratic residue or zero modulo $p$ + and sets $b$ to a square root of $a$ if this is the case. + +void fmpz_sqrt(fmpz_t f, const fmpz_t g) + + Sets $f$ to the integer part of the square root of $g$, where + $g$ is assumed to be non-negative. If $g$ is negative, an exception + is raised. + +void fmpz_sqrtrem(fmpz_t f, fmpz_t r, const fmpz_t g) + + Sets $f$ to the integer part of the square root of $g$, where $g$ is + assumed to be non-negative, and sets $r$ to the remainder, that is, + the difference $g - f^2$. If $g$ is negative, an exception is raised. + The behaviour is undefined if $f$ and $r$ are aliases. + +int fmpz_is_square(const fmpz_t f) + + Returns nonzero if $f$ is a perfect square and zero otherwise. + +void fmpz_root(fmpz_t r, const fmpz_t f, slong n) + + Set $r$ to the integer part of the $n$-th root of $f$. Requires that + $n > 0$ and that if $n$ is even then $f$ be non-negative, otherwise an + exception is raised. + +void fmpz_fac_ui(fmpz_t f, ulong n) + + Sets $f$ to the factorial $n!$ where $n$ is an \code{ulong}. + +void fmpz_fib_ui(fmpz_t f, ulong n) + + Sets $f$ to the Fibonacci number $F_n$ where $n$ is an + \code{ulong}. + +void fmpz_bin_uiui(fmpz_t f, ulong n, ulong k) + + Sets $f$ to the binomial coefficient ${n \choose k}$. + +void fmpz_rfac_ui(fmpz_t r, const fmpz_t x, ulong k) + + Sets $r$ to the rising factorial $x (x+1) (x+2) \cdots (x+k-1)$. + +void fmpz_rfac_uiui(fmpz_t r, ulong x, ulong k) + + Sets $r$ to the rising factorial $x (x+1) (x+2) \cdots (x+k-1)$. + +void fmpz_mul_tdiv_q_2exp(fmpz_t f, const fmpz_t g, const fmpz_t h, ulong exp) + + Sets $f$ to the product $g$ and $h$ divided by \code{2^exp}, rounding + down towards zero. + +void fmpz_mul_si_tdiv_q_2exp(fmpz_t f, const fmpz_t g, slong x, ulong exp) + + Sets $f$ to the product $g$ and $x$ divided by \code{2^exp}, rounding + down towards zero. + + +******************************************************************************* + + Greatest common divisor + +******************************************************************************* + +void fmpz_gcd(fmpz_t f, const fmpz_t g, const fmpz_t h) + + Sets $f$ to the greatest common divisor of $g$ and $h$. The + result is always positive, even if one of $g$ and $h$ is + negative. + +void fmpz_lcm(fmpz_t f, const fmpz_t g, const fmpz_t h) + + Sets $f$ to the least common multiple of $g$ and $h$. The + result is always nonnegative, even if one of $g$ and $h$ is + negative. + +void fmpz_gcdinv(fmpz_t d, fmpz_t a, const fmpz_t f, const fmpz_t g) + + Given integers $f, g$ with $0 \leq f < g$, computes the + greatest common divisor $d = \gcd(f, g)$ and the modular + inverse $a = f^{-1} \pmod{g}$, whenever $f \neq 0$. + + Assumes that $d$ and $a$ are not aliased. + +void fmpz_xgcd(fmpz_t d, fmpz_t a, fmpz_t b, const fmpz_t f, const fmpz_t g) + + Computes the extended GCD of $f$ and $g$, i.e. values $a$ and $b$ + such that $af + bg = d$, where $d = \gcd(f, g)$. + + Assumes that $d$ is not aliased with $a$ or $b$ and that $a$ and $b$ + are not aliased. + +void fmpz_xgcd_partial(fmpz_t co2, fmpz_t co1, + fmpz_t r2, fmpz_t r1, const fmpz_t L) + + This function is an implementation of Lehmer extended GCD with early + termination, as used in the \code{qfb} module. It terminates early when + remainders fall below the specified bound. The initial values \code{r1} + and \code{r2} are treated as successive remainders in the Euclidean + algorithm and are replaced with the last two remainders computed. The + values \code{co1} and \code{co2} are the last two cofactors and satisfy + the identity \code{co2*r1 - co1*r2 == +/- r2_orig} upon termination, where + \code{r2_orig} is the starting value of \code{r2} supplied, and \code{r1} + and \code{r2} are the final values. + + Aliasing of inputs is not allowed. Similarly aliasing of inputs and outputs + is not allowed. + +******************************************************************************* + + Modular arithmetic + +******************************************************************************* + +slong _fmpz_remove(fmpz_t x, const fmpz_t f, double finv) + + Removes all factors $f$ from $x$ and returns the number of such. + + Assumes that $x$ is non-zero, that $f > 1$ and that \code{finv} + is the precomputed \code{double} inverse of $f$ whenever $f$ is + a small integer and $0$ otherwise. + + Does not support aliasing. + +slong fmpz_remove(fmpz_t rop, const fmpz_t op, const fmpz_t f) + + Remove all occurrences of the factor $f > 1$ from the + integer \code{op} and sets \code{rop} to the resulting + integer. + + If \code{op} is zero, sets \code{rop} to \code{op} and + returns $0$. + + Returns an \code{abort} signal if any of the assumptions + are violated. + +int fmpz_invmod(fmpz_t f, const fmpz_t g, const fmpz_t h) + + Sets $f$ to the inverse of $g$ modulo $h$. The value of $h$ may + not be $0$ otherwise an exception results. If the inverse exists + the return value will be non-zero, otherwise the return value will + be $0$ and the value of $f$ undefined. + +void fmpz_negmod(fmpz_t f, const fmpz_t g, const fmpz_t h) + + Sets $f$ to $-g \pmod{h}$, assuming $g$ is reduced modulo $h$. + +int fmpz_jacobi(const fmpz_t a, const fmpz_t p); + + Computes the Jacobi symbol of $a$ modulo $p$, where $p$ is a prime + and $a$ is reduced modulo $p$. + +******************************************************************************* + + Bit packing and unpacking + +******************************************************************************* + +int fmpz_bit_pack(mp_limb_t * arr, mp_bitcnt_t shift, + mp_bitcnt_t bits, fmpz_t coeff, int negate, int borrow) + + Shifts the given coefficient to the left by \code{shift} bits and adds + it to the integer in \code{arr} in a field of the given number of bits. + + \begin{lstlisting} + shift bits -------------- + + X X X C C C C 0 0 0 0 0 0 0 + \end{lstlisting} + + An optional borrow of~$1$ can be subtracted from \code{coeff} before + it is packed. If \code{coeff} is negative after the borrow, then a + borrow will be returned by the function. + + The value of \code{shift} is assumed to be less than \code{FLINT_BITS}. + All but the first \code{shift} bits of \code{arr} are assumed to be zero + on entry to the function. + + The value of \code{coeff} may also be optionally (and notionally) negated + before it is used, by setting the \code{negate} parameter to $-1$. + +int fmpz_bit_unpack(fmpz_t coeff, mp_limb_t * arr, + mp_bitcnt_t shift, mp_bitcnt_t bits, int negate, int borrow) + + A bit field of the given number of bits is extracted from \code{arr}, + starting after \code{shift} bits, and placed into \code{coeff}. An + optional borrow of~$1$ may be added to the coefficient. If the result + is negative, a borrow of $1$ is returned. Finally, the resulting + \code{coeff} may be negated by setting the \code{negate} parameter to $-1$. + + The value of \code{shift} is expected to be less than \code{FLINT_BITS}. + +void fmpz_bit_unpack_unsigned(fmpz_t coeff, + const mp_limb_t * arr, mp_bitcnt_t shift, mp_bitcnt_t bits) + + A bit field of the given number of bits is extracted from \code{arr}, + starting after \code{shift} bits, and placed into \code{coeff}. + + The value of \code{shift} is expected to be less than \code{FLINT_BITS}. + +******************************************************************************* + + Logic Operations + +******************************************************************************* + +void fmpz_complement(fmpz_t r, const fmpz_t f) + + The variable \code{r} is set to the ones-complement of \code{f}. + +void fmpz_clrbit(fmpz_t f, ulong i) + + Sets the \code{i}th bit in \code{f} to zero. + +void fmpz_combit(fmpz_t f, ulong i) + + Complements the \code{i}th bit in \code{f}. + +void fmpz_and(fmpz_t r, const fmpz_t a, const fmpz_t b) + + Sets \code{r} to the bit-wise logical \code{and} of \code{a} and \code{b}. + +void fmpz_or(fmpz_t r, const fmpz_t a, const fmpz_t b) + + Sets \code{r} to the bit-wise logical (inclusive) \code{or} of + \code{a} and \code{b}. + +void fmpz_xor(fmpz_t r, const fmpz_t a, const fmpz_t b) + + Sets \code{r} to the bit-wise logical exclusive \code{or} of + \code{a} and \code{b}. + +int fmpz_popcnt(const fmpz_t a) + + Returns the number of '1' bits in the given Z (aka Hamming weight or + population count). + The return value is undefined if the input is negative. + +******************************************************************************* + + Chinese remaindering + + The following functions can be used to reconstruct an integer from its + residues modulo a set of small (word-size) prime numbers. The first two + functions, \code{fmpz_CRT_ui} and \code{fmpz_CRT_ui_unsigned}, are easy + to use and allow building the result one residue at a time, which is + useful when the number of needed primes is not known in advance. + + The remaining functions support performing the modular reductions and + reconstruction using balanced subdivision. This greatly improves + efficiency for large integers but assumes that the basis of primes is + known in advance. The user must precompute a \code{comb} + structure and temporary working space with \code{fmpz_comb_init} and + \code{fmpz_comb_temp_init}, and free this data afterwards. + + For simple demonstration programs showing how to use the CRT functions, + see \code{crt.c} and \code{multi_crt.c} in the \code{examples} + directory. + +******************************************************************************* + +void fmpz_CRT_ui(fmpz_t out, fmpz_t r1, fmpz_t m1, ulong r2, ulong m2, + int sign) + + Uses the Chinese Remainder Theorem to compute the unique integer + $0 \le x < M$ (if sign = 0) or $-M/2 < x \le M/2$ (if sign = 1) + congruent to $r_1$ modulo $m_1$ and $r_2$ modulo $m_2$, + where where $M = m_1 \times m_2$. The result $x$ is stored in \code{out}. + + It is assumed that $m_1$ and $m_2$ are positive integers greater + than $1$ and coprime. + + If sign = 0, it is assumed that $0 \le r_1 < m_1$ and $0 \le r_2 < m_2$. + Otherwise, it is assumed that $-m_1 \le r_1 < m_1$ and $0 \le r_2 < m_2$. + +void fmpz_multi_mod_ui(mp_limb_t * out, const fmpz_t in, + const fmpz_comb_t comb, fmpz_comb_temp_t temp) + + Reduces the multiprecision integer \code{in} modulo each of the primes + stored in the \code{comb} structure. The array \code{out} will be filled + with the residues modulo these primes. The structure \code{temp} is + temporary space which must be provided by \code{fmpz_comb_temp_init} and + cleared by \code{fmpz_comb_temp_clear}. + +void fmpz_multi_CRT_ui_unsigned(fmpz_t output, const mp_limb_t * residues, + const fmpz_comb_t comb, fmpz_comb_temp_t temp) + + This function takes a set of residues modulo the list of primes + contained in the \code{comb} structure and reconstructs the unique + unsigned multiprecision integer modulo the product of the primes + which has these residues modulo the corresponding primes. The structure + \code{temp} is temporary space which must be provided by + \code{fmpz_comb_temp_init} and cleared by \code{fmpz_comb_temp_clear}. + +void fmpz_multi_CRT_ui(fmpz_t output, mp_srcptr residues, + const fmpz_comb_t comb, fmpz_comb_temp_t temp) + + This function takes a set of residues modulo the list of primes + contained in the \code{comb} structure and reconstructs a multiprecision + integer modulo the product of the primes which has + these residues modulo the corresponding primes. + + If $N$ is the product of all the primes then \code{out} is normalised to + be in the range $[0, N)$ if sign = 0 and the range $[-(N-1)/2, N/2]$ + if sign = 1. The array \code{temp} is temporary + space which must be provided by \code{fmpz_comb_temp_init} and + cleared by \code{fmpz_comb_temp_clear}. + +void fmpz_comb_init(fmpz_comb_t comb, mp_srcptr primes, slong num_primes) + + Initialises a \code{comb} structure for multimodular reduction and + recombination. The array \code{primes} is assumed to contain + \code{num_primes} primes each of \code{FLINT_BITS - 1} bits. Modular + reductions and recombinations will be done modulo this list of primes. + The \code{primes} array must not be \code{free}'d until the \code{comb} + structure is no longer required and must be cleared by the user. + +void fmpz_comb_temp_init(fmpz_comb_temp_t temp, const fmpz_comb_t comb) + + Creates temporary space to be used by multimodular and CRT functions + based on an initialised \code{comb} structure. + +void fmpz_comb_clear(fmpz_comb_t comb) + + Clears the given \code{comb} structure, releasing any memory it uses. + +void fmpz_comb_temp_clear(fmpz_comb_temp_t temp) + + Clears temporary space \code{temp} used by multimodular and CRT functions + using the given \code{comb} structure. + +******************************************************************************* + + Primality testing + +******************************************************************************* + +int fmpz_is_probabprime(const fmpz_t p) + + Performs some trial division and then some probabilistic primality tests. + If $p$ is definitely composite, the function returns $0$, otherwise it + is declared probably prime, i.e. prime for most practical purposes, and + the function returns $1$. The chance of declaring a composite prime is + very small. + + Subsequent calls to the same function do not increase the probability of + the number being prime. + +int fmpz_is_prime_pseudosquare(const fmpz_t n) + + Return $0$ is $n$ is composite. If $n$ is too large (greater than about + $94$ bits) the function fails silently and returns $-1$, otherwise, if + $n$ is proven prime by the pseudosquares method, return $1$. + + Tests if $n$ is a prime according to~\citep[Theorem~2.7]{LukPatWil1996}. + + % "Some results on pseudosquares" by Lukes, Patterson and Williams, + % Math. Comp. vol 65, No. 213. pp 361-372. See + % http://www.ams.org/mcom/1996-65-213/S0025-5718-96-00678-3/ + % S0025-5718-96-00678-3.pdf + + We first factor $N$ using trial division up to some limit $B$. + In fact, the number of primes used in the trial factoring is at + most \code{FLINT_PSEUDOSQUARES_CUTOFF}. + + Next we compute $N/B$ and find the next pseudosquare $L_p$ above + this value, using a static table as per + \url{http://research.att.com/~njas/sequences/b002189.txt}. + + As noted in the text, if $p$ is prime then Step~3 will pass. This + test rejects many composites, and so by this time we suspect + that $p$ is prime. If $N$ is $3$ or $7$ modulo $8$, we are done, + and $N$ is prime. + + We now run a probable prime test, for which no known + counterexamples are known, to reject any composites. We then + proceed to prove $N$ prime by executing Step~4. In the case that + $N$ is $1$ modulo $8$, if Step~4 fails, we extend the number of primes + $p_i$ at Step~3 and hope to find one which passes Step~4. We take + the test one past the largest $p$ for which we have pseudosquares + $L_p$ tabulated, as this already corresponds to the next $L_p$ which + is bigger than $2^{64}$ and hence larger than any prime we might be + testing. + + As explained in the text, Condition~4 cannot fail if $N$ is prime. + + The possibility exists that the probable prime test declares a + composite prime. However in that case an error is printed, as + that would be of independent interest. + diff --git a/external/flint-2.4.3/fmpz/doc/reentrant.txt b/external/flint-2.4.3/fmpz/doc/reentrant.txt new file mode 100644 index 0000000..1c3d581 --- /dev/null +++ b/external/flint-2.4.3/fmpz/doc/reentrant.txt @@ -0,0 +1,110 @@ +/*============================================================================ + + Copyright (C) 2009 William Hart + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +===============================================================================*/ + +link/fmpz_reentrant.c <-- fmpz.c + + If this version of fmpz.c is used (e.g. if the configure option + \code{--reentrant} is used), then the fmpz module is threadsafe, though + a little slower when using integers which are larger than + \code{FLINT_BITS - 2} bits. + +fmpz + + an fmpz is implemented as an slong. When its second most significant bit + is 0 the fmpz represents an ordinary slong integer whose absolute + value is at most FLINT_BITS - 2 bits. + + When the second most significant bit is 1 then the value represents a + pointer (the pointer is shifted right 2 bits and the second msb is set + to 1 - this relies on the fact that malloc always allocates memory + blocks on a 4 or 8 byte boundary). + +fmpz_t + + an array of length 1 of fmpz's. This is used to pass fmpz's around by + reference without fuss, similar to the way mpz_t's work. + +COEFF_MAX + + the largest (positive) value an fmpz can be if just an slong + +COEFF_MIN + + the smallest (negative) value an fmpz can be if just an slong + +fmpz PTR_TO_COEFF(__mpz_struct * ptr) + + a macro to convert an mpz_t (or more generally any __mpz_struct *) to an + fmpz (shifts the pointer right by 2 and sets the second most significant + bit). + +__mpz_struct * COEFF_TO_PTR(fmpz f) + + a macro to convert an fmpz which represents a pointer into an actual + pointer to an __mpz_struct (i.e. to an mpz_t) + +int COEFF_IS_MPZ(fmpz f) + + a macro which returns 1 if f represents an mpz_t, otherwise 0 is returned. + +__mpz_struct * _fmpz_new_mpz(void) + + initialises a new mpz_t and returns a pointer to it. This is only used + internally. + +void _fmpz_clear_mpz(fmpz f) + + clears the mpz_t "pointed to" by the fmpz f. This is only used internally. + +void _fmpz_cleanup_mpz_content() + + this function does nothing in the reentrant version of fmpz. + +void _fmpz_cleanup() + + this function does nothing in the reentrant version of fmpz. + +__mpz_struct * _fmpz_promote(fmpz_t f) + + if f doesn't represent an mpz_t, initialise one and associate it to f. + +__mpz_struct * _fmpz_promote_val(fmpz_t f) + + if f doesn't represent an mpz_t, initialise one and associate it to f, but + preserve the value of f. + +void _fmpz_demote(fmpz_t f) + + if f represents an mpz_t clear it and make f just represent an slong. + +void _fmpz_demote_val(fmpz_t f) + + if f represents an mpz_t and its value will fit in an slong, preserve the + value in f which we make to represent an slong, and clear the mpz_t. + + + + + + + + diff --git a/external/flint-2.4.3/fmpz/doc/single.txt b/external/flint-2.4.3/fmpz/doc/single.txt new file mode 100644 index 0000000..b513821 --- /dev/null +++ b/external/flint-2.4.3/fmpz/doc/single.txt @@ -0,0 +1,117 @@ +/*============================================================================ + + Copyright (C) 2009 William Hart + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +===============================================================================*/ + +link/fmpz_single.c <-- fmpz.c + + By default, this version of fmpz.c is used (it is copied into place + by configure). In this case the fmpz module is not threadsafe, though + a little faster when using integers which are larger than + \code{FLINT_BITS - 2} bits. It stores a growing cache of unused mpz's + which can be rationed out as needed. + +fmpz + + an fmpz is implemented as an slong. When its second most significant bit + is 0 the fmpz represents an ordinary slong integer whose absolute + value is at most FLINT_BITS - 2 bits. + + When the second most significant bit is 1 then the value represents a + pointer (the pointer is shifted right 2 bits and the second msb is set + to 1 - this relies on the fact that malloc always allocates memory + blocks on a 4 or 8 byte boundary). + +fmpz_t + + an array of length 1 of fmpz's. This is used to pass fmpz's around by + reference without fuss, similar to the way mpz_t's work. + +COEFF_MAX + + the largest (positive) value an fmpz can be if just an slong + +COEFF_MIN + + the smallest (negative) value an fmpz can be if just an slong + +fmpz PTR_TO_COEFF(__mpz_struct * ptr) + + a macro to convert an mpz_t (or more generally any __mpz_struct *) to an + fmpz (shifts the pointer right by 2 and sets the second most significant + bit). + +__mpz_struct * COEFF_TO_PTR(fmpz f) + + a macro to convert an fmpz which represents a pointer into an actual + pointer to an __mpz_struct (i.e. to an mpz_t) + +int COEFF_IS_MPZ(fmpz f) + + a macro which returns 1 if f represents an mpz_t, otherwise 0 is returned. + +__mpz_struct * _fmpz_new_mpz(void) + + initialises a new mpz_t and returns a pointer to it. If an mpz is available + in the internal cache of mpz's, fmpz_unused_arr, such an mpz is returned, + otherwise MPZ_BLOCK more mpz's are allocated and placed into the internal + cache and one of these returned. This is only used internally. + +void _fmpz_clear_mpz(fmpz f) + + relinquished the mpz associated to f to the internal cache of unused mpz's, + fmpz_unused_arr. This is only used internally. + +void _fmpz_cleanup() + + cleans up the internal stack of mpz's, clearing any unused mpz's. + +void _fmpz_cleanup_mpz_content() + + Cleans up the internal stack of mpz's, freeing all allocated limb data, + but does not free the main arrays of mpz structs. Unlike _fmpz_cleanup, + it is safe to use fmpz_clear on any remaining fmpz's after + this function has been called. + +__mpz_struct * _fmpz_promote(fmpz_t f) + + if f doesn't represent an mpz_t, initialise one and associate it to f. + +__mpz_struct * _fmpz_promote_val(fmpz_t f) + + if f doesn't represent an mpz_t, initialise one and associate it to f, but + preserve the value of f. + +void _fmpz_demote(fmpz_t f) + + if f represents an mpz_t clear it and make f just represent an slong. + +void _fmpz_demote_val(fmpz_t f) + + if f represents an mpz_t and its value will fit in an slong, preserve the + value in f which we make to represent an slong, and clear the mpz_t. + + + + + + + + diff --git a/external/flint-2.4.3/fmpz/equal.c b/external/flint-2.4.3/fmpz/equal.c new file mode 100644 index 0000000..db24d8f --- /dev/null +++ b/external/flint-2.4.3/fmpz/equal.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int fmpz_equal(const fmpz_t f, const fmpz_t g) +{ + if (f == g) return 1; /* aliased inputs */ + + if (!COEFF_IS_MPZ(*f)) return (*f == *g); /* if f is large it can't be equal to g */ + else if (!COEFF_IS_MPZ(*g)) return 0; /* f is large, so if g isn't... */ + else return (mpz_cmp(COEFF_TO_PTR(*f), COEFF_TO_PTR(*g)) == 0); +} diff --git a/external/flint-2.4.3/fmpz/equal_si.c b/external/flint-2.4.3/fmpz/equal_si.c new file mode 100644 index 0000000..c9cea6d --- /dev/null +++ b/external/flint-2.4.3/fmpz/equal_si.c @@ -0,0 +1,35 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/***************************************************************************** + + Copyright (C) 2010, 2012 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz.h" +#include "ulong_extras.h" + +int fmpz_equal_si(const fmpz_t f, slong g) +{ + fmpz c = *f; + + return !COEFF_IS_MPZ(c) ? (c == g) : !flint_mpz_cmp_si(COEFF_TO_PTR(c), g); +} diff --git a/external/flint-2.4.3/fmpz/equal_ui.c b/external/flint-2.4.3/fmpz/equal_ui.c new file mode 100644 index 0000000..282eecc --- /dev/null +++ b/external/flint-2.4.3/fmpz/equal_ui.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/***************************************************************************** + + Copyright (C) 2010, 2012 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz.h" +#include "ulong_extras.h" + +int fmpz_equal_ui(const fmpz_t f, ulong g) +{ + fmpz c = *f; + + return !COEFF_IS_MPZ(c) ? ((c >= 0) & (c == g)) : + !flint_mpz_cmp_ui(COEFF_TO_PTR(c), g); +} diff --git a/external/flint-2.4.3/fmpz/fac_ui.c b/external/flint-2.4.3/fmpz/fac_ui.c new file mode 100644 index 0000000..99c5a83 --- /dev/null +++ b/external/flint-2.4.3/fmpz/fac_ui.c @@ -0,0 +1,56 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +#if FLINT64 +#define FLINT_NUM_TINY_FACTORIALS 21 +#else +#define FLINT_NUM_TINY_FACTORIALS 13 +#endif + +const mp_limb_t flint_tiny_factorials[] = +{ + UWORD(1), UWORD(1), UWORD(2), UWORD(6), UWORD(24), UWORD(120), UWORD(720), UWORD(5040), UWORD(40320), UWORD(362880), + UWORD(3628800), UWORD(39916800), UWORD(479001600), +#if FLINT64 + UWORD(6227020800), UWORD(87178291200), UWORD(1307674368000), UWORD(20922789888000), + UWORD(355687428096000), UWORD(6402373705728000), UWORD(121645100408832000), + UWORD(2432902008176640000), +#endif +}; + +void fmpz_fac_ui(fmpz_t f, ulong n) +{ + if (n < FLINT_NUM_TINY_FACTORIALS) + fmpz_set_ui(f, flint_tiny_factorials[n]); + else + flint_mpz_fac_ui(_fmpz_promote(f), n); +} diff --git a/external/flint-2.4.3/fmpz/fdiv_q.c b/external/flint-2.4.3/fmpz/fdiv_q.c new file mode 100644 index 0000000..e9c9ff8 --- /dev/null +++ b/external/flint-2.4.3/fmpz/fdiv_q.c @@ -0,0 +1,87 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" + +void +fmpz_fdiv_q(fmpz_t f, const fmpz_t g, const fmpz_t h) +{ + fmpz c1 = *g; + fmpz c2 = *h; + + if (fmpz_is_zero(h)) + { + flint_printf("Exception (fmpz_fdiv_q). Division by zero.\n"); + abort(); + } + + if (!COEFF_IS_MPZ(c1)) /* g is small */ + { + if (!COEFF_IS_MPZ(c2)) /* h is also small */ + { + fmpz q = c1 / c2; /* compute C quotient */ + fmpz r = c1 - c2 * q; /* compute remainder */ + + if (r && (c2 ^ r) < WORD(0)) + --q; + + fmpz_set_si(f, q); + } + else /* h is large and g is small */ + { + if ((c1 > WORD(0) && fmpz_sgn(h) < 0) || (c1 < WORD(0) && fmpz_sgn(h) > 0)) /* signs are the same */ + fmpz_set_si(f, WORD(-1)); /* quotient is negative, round down to minus one */ + else + fmpz_zero(f); + } + } + else /* g is large */ + { + __mpz_struct *mpz_ptr = _fmpz_promote(f); + + if (!COEFF_IS_MPZ(c2)) /* h is small */ + { + if (c2 > 0) /* h > 0 */ + { + flint_mpz_fdiv_q_ui(mpz_ptr, COEFF_TO_PTR(c1), c2); + } + else + { + flint_mpz_cdiv_q_ui(mpz_ptr, COEFF_TO_PTR(c1), -c2); + mpz_neg(mpz_ptr, mpz_ptr); + } + } + else /* both are large */ + { + mpz_fdiv_q(mpz_ptr, COEFF_TO_PTR(c1), COEFF_TO_PTR(c2)); + } + _fmpz_demote_val(f); /* division by h may result in small value */ + } +} diff --git a/external/flint-2.4.3/fmpz/fdiv_q_2exp.c b/external/flint-2.4.3/fmpz/fdiv_q_2exp.c new file mode 100644 index 0000000..a65305a --- /dev/null +++ b/external/flint-2.4.3/fmpz/fdiv_q_2exp.c @@ -0,0 +1,45 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +void fmpz_fdiv_q_2exp(fmpz_t f, const fmpz_t g, ulong exp) +{ + fmpz d = *g; + + if (!COEFF_IS_MPZ(d)) /* g is small */ + { + fmpz_set_si(f, d>>FLINT_MIN(exp, FLINT_BITS - 2)); + } + else /*g is large */ + { + __mpz_struct * mpz_ptr = _fmpz_promote(f); /* g is already large */ + mpz_fdiv_q_2exp(mpz_ptr, COEFF_TO_PTR(d), exp); + _fmpz_demote_val(f); /* division may make value small */ + } +} diff --git a/external/flint-2.4.3/fmpz/fdiv_q_si.c b/external/flint-2.4.3/fmpz/fdiv_q_si.c new file mode 100644 index 0000000..1295c28 --- /dev/null +++ b/external/flint-2.4.3/fmpz/fdiv_q_si.c @@ -0,0 +1,70 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +void +fmpz_fdiv_q_si(fmpz_t f, const fmpz_t g, slong h) +{ + fmpz c1 = *g; + slong c2 = h; + + if (h == 0) + { + flint_printf("Exception (fmpq_fdiv_q_si). Division by zero.\n"); + abort(); + } + + if (!COEFF_IS_MPZ(c1)) /* g is small */ + { + fmpz q = c1 / c2; /* compute C quotient */ + fmpz r = c1 - c2 * q; /* compute remainder */ + + if (r && ((c1 ^ c2) < 0)) + --q; + + fmpz_set_si(f, q); + } + else /* g is large */ + { + __mpz_struct *mpz_ptr = _fmpz_promote(f); + + if (c2 > 0) + { + flint_mpz_fdiv_q_ui(mpz_ptr, COEFF_TO_PTR(c1), c2); + } + else + { + flint_mpz_cdiv_q_ui(mpz_ptr, COEFF_TO_PTR(c1), -(ulong) c2); + mpz_neg(mpz_ptr, mpz_ptr); + } + _fmpz_demote_val(f); /* division by h may result in small value */ + } +} diff --git a/external/flint-2.4.3/fmpz/fdiv_q_ui.c b/external/flint-2.4.3/fmpz/fdiv_q_ui.c new file mode 100644 index 0000000..28b3745 --- /dev/null +++ b/external/flint-2.4.3/fmpz/fdiv_q_ui.c @@ -0,0 +1,69 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" + +void +fmpz_fdiv_q_ui(fmpz_t f, const fmpz_t g, ulong h) +{ + fmpz c1 = *g; + ulong c2 = h; + + if (h == 0) + { + flint_printf("Exception (fmpz_fdiv_q_ui). Division by zero.\n"); + abort(); + } + + if (!COEFF_IS_MPZ(c1)) /* g is small */ + { + if (c1 > 0) + { + fmpz_set_ui(f, c1 / c2); + } + else + { + ulong q = ((ulong) -c1) / c2; + ulong r = ((ulong) -c1) - c2 * q; + + if (r) + ++q; + + fmpz_set_si(f, - (slong) q); + } + } + else /* g is large */ + { + __mpz_struct *mpz_ptr = _fmpz_promote(f); + + flint_mpz_fdiv_q_ui(mpz_ptr, COEFF_TO_PTR(c1), c2); + _fmpz_demote_val(f); /* division by h may result in small value */ + } +} diff --git a/external/flint-2.4.3/fmpz/fdiv_qr.c b/external/flint-2.4.3/fmpz/fdiv_qr.c new file mode 100644 index 0000000..4658dc0 --- /dev/null +++ b/external/flint-2.4.3/fmpz/fdiv_qr.c @@ -0,0 +1,107 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +void +fmpz_fdiv_qr(fmpz_t f, fmpz_t s, const fmpz_t g, const fmpz_t h) +{ + fmpz c1 = *g; + fmpz c2 = *h; + + if (fmpz_is_zero(h)) + { + flint_printf("Exception (fmpz_fdiv_q). Division by zero.\n"); + abort(); + } + + if (!COEFF_IS_MPZ(c1)) /* g is small */ + { + if (!COEFF_IS_MPZ(c2)) /* h is also small */ + { + fmpz q = c1 / c2; /* compute C quotient */ + fmpz r = c1 - c2 * q; /* compute remainder */ + + if ((c2 > WORD(0) && r < WORD(0)) || (c2 < WORD(0) && r > WORD(0))) + { + q--; /* q cannot overflow as remainder implies |c2| != 1 */ + r += c2; + } + + fmpz_set_si(f, q); + fmpz_set_si(s, r); + } + else /* h is large and g is small */ + { + if (c1 == WORD(0)) + { + fmpz_set_ui(f, WORD(0)); /* g is zero */ + fmpz_set_si(s, c1); + } + else if ((c1 < WORD(0) && fmpz_sgn(h) < 0) || (c1 > WORD(0) && fmpz_sgn(h) > 0)) /* signs are the same */ + { + fmpz_zero(f); /* quotient is positive, round down to zero */ + fmpz_set_si(s, c1); + } + else + { + fmpz_add(s, g, h); + fmpz_set_si(f, WORD(-1)); /* quotient is negative, round down to minus one */ + } + } + } + else /* g is large */ + { + __mpz_struct *mpz_ptr, *mpz_ptr2; + + _fmpz_promote(f); /* must not hang on to ptr whilst promoting s */ + mpz_ptr2 = _fmpz_promote(s); + mpz_ptr = COEFF_TO_PTR(*f); + + if (!COEFF_IS_MPZ(c2)) /* h is small */ + { + if (c2 > 0) /* h > 0 */ + { + flint_mpz_fdiv_qr_ui(mpz_ptr, mpz_ptr2, COEFF_TO_PTR(c1), c2); + } + else + { + flint_mpz_cdiv_qr_ui(mpz_ptr, mpz_ptr2, COEFF_TO_PTR(c1), -c2); + mpz_neg(mpz_ptr, mpz_ptr); + } + } + else /* both are large */ + { + mpz_fdiv_qr(mpz_ptr, mpz_ptr2, COEFF_TO_PTR(c1), COEFF_TO_PTR(c2)); + } + _fmpz_demote_val(f); /* division by h may result in small value */ + _fmpz_demote_val(s); /* division by h may result in small value */ + } +} diff --git a/external/flint-2.4.3/fmpz/fdiv_qr_preinvn.c b/external/flint-2.4.3/fmpz/fdiv_qr_preinvn.c new file mode 100644 index 0000000..ddf0b77 --- /dev/null +++ b/external/flint-2.4.3/fmpz/fdiv_qr_preinvn.c @@ -0,0 +1,226 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright 1991, 1993-1996, 2000, 2001, 2005 Free Software Foundation, Inc. + Copyright (C) 2013 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "longlong.h" +#include "ulong_extras.h" +#include "mpn_extras.h" +#include "fmpz.h" + +/* these functions were adapted from similar functions in an old version of GMP */ +void _mpz_tdiv_qr_preinvn(mpz_ptr q, mpz_ptr r, + mpz_srcptr a, mpz_srcptr d, const fmpz_preinvn_t inv) +{ + slong size1 = a->_mp_size, size2 = d->_mp_size; + ulong usize1 = FLINT_ABS(size1); + ulong usize2 = FLINT_ABS(size2); + ulong qsize = usize1 - usize2 + 1; + int nm = (inv->norm != 0); + TMP_INIT; + + mp_ptr qp, rp, ap, dp, tp, sp; + + if (r->_mp_alloc < usize1 + nm) + mpz_realloc2(r, (usize1 + nm)*FLINT_BITS); + + if (usize1 < usize2) /* special case preinv code can't deal with */ + { + mpz_set(r, a); /* remainder equals numerator */ + q->_mp_size = 0; /* quotient is zero */ + + return; + } + + if (q->_mp_alloc < qsize + nm) + mpz_realloc2(q, (qsize + nm)*FLINT_BITS); + + dp = d->_mp_d; + ap = a->_mp_d; + qp = q->_mp_d; + rp = r->_mp_d; + + TMP_START; + if ((r == d || q == d) && !nm) /* we have alias with d */ + { + tp = TMP_ALLOC(usize2*FLINT_BITS); + mpn_copyi(tp, dp, usize2); + dp = tp; + } + + if (r == a || q == a) /* we have alias with a */ + { + tp = TMP_ALLOC(usize1*FLINT_BITS); + mpn_copyi(tp, ap, usize1); + ap = tp; + } + + /* + TODO: speedup mpir's mullow and mulhigh and use in + flint_mpn_divrem_preinvn so we can remove this first + case here + */ + if (usize2 == 2 || (usize2 > 15 && usize2 < 120)) + mpn_tdiv_qr(qp, rp, 0, ap, usize1, dp, usize2); + else { + if (nm) { + tp = TMP_ALLOC(usize2*FLINT_BITS); + mpn_lshift(tp, dp, usize2, inv->norm); + dp = tp; + + rp[usize1] = mpn_lshift(rp, ap, usize1, inv->norm); + if (rp[usize1] != 0) usize1++, qsize++; + sp = rp; + } else + sp = ap; + + qp[qsize - 1] = flint_mpn_divrem_preinvn(qp, rp, sp, usize1, dp, usize2, inv->dinv); + + if (nm) + mpn_rshift(rp, rp, usize2, inv->norm); + } + + qsize -= (qp[qsize - 1] == 0); + MPN_NORM(rp, usize2); + + q->_mp_size = ((size1 ^ size2) < 0 ? -qsize : qsize); + r->_mp_size = (size1 < 0 ? -usize2 : usize2); + + TMP_END; +} + +void _mpz_fdiv_qr_preinvn(mpz_ptr q, mpz_ptr r, + mpz_srcptr a, mpz_srcptr d, const fmpz_preinvn_t inv) +{ + slong size1 = a->_mp_size; + slong size2 = d->_mp_size; + ulong usize2 = FLINT_ABS(size2); + mpz_t t; + TMP_INIT; + + TMP_START; + if (q == d || r == d) /* we need d later, so make sure it doesn't alias */ + { + t->_mp_d = TMP_ALLOC(usize2*FLINT_BITS); + t->_mp_size = d->_mp_size; + t->_mp_alloc = d->_mp_alloc; + mpn_copyi(t->_mp_d, d->_mp_d, usize2); + d = t; + } + + _mpz_tdiv_qr_preinvn(q, r, a, d, inv); + + if ((size1 ^ size2) < 0 && r->_mp_size != 0) + { + flint_mpz_sub_ui(q, q, 1); + mpz_add(r, r, d); + } + + TMP_END; +} + +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009, 2013 William Hart + +******************************************************************************/ + +void +fmpz_fdiv_qr_preinvn(fmpz_t f, fmpz_t s, const fmpz_t g, + const fmpz_t h, const fmpz_preinvn_t inv) +{ + fmpz c1 = *g; + fmpz c2 = *h; + + if (fmpz_is_zero(h)) + { + flint_printf("Exception (fmpz_fdiv_q). Division by zero.\n"); + abort(); + } + + if (!COEFF_IS_MPZ(c1)) /* g is small */ + { + if (!COEFF_IS_MPZ(c2)) /* h is also small */ + fmpz_fdiv_qr(f, s, g, h); + else /* h is large and g is small */ + { + if (c1 == WORD(0)) + { + fmpz_set_ui(f, WORD(0)); /* g is zero */ + fmpz_set_si(s, c1); + } + else if ((c1 < WORD(0) && fmpz_sgn(h) < 0) || (c1 > WORD(0) && fmpz_sgn(h) > 0)) /* signs are the same */ + { + fmpz_zero(f); /* quotient is positive, round down to zero */ + fmpz_set_si(s, c1); + } + else + { + fmpz_add(s, g, h); + fmpz_set_si(f, WORD(-1)); /* quotient is negative, round down to minus one */ + } + } + } + else /* g is large */ + { + __mpz_struct *mpz_ptr, *mpz_ptr2; + + if (!COEFF_IS_MPZ(c2)) /* h is small */ + fmpz_fdiv_qr(f, s, g, h); + else + { + _fmpz_promote(f); /* must not hang on to ptr whilst promoting s */ + mpz_ptr2 = _fmpz_promote(s); + mpz_ptr = COEFF_TO_PTR(*f); + + _mpz_fdiv_qr_preinvn(mpz_ptr, mpz_ptr2, COEFF_TO_PTR(c1), COEFF_TO_PTR(c2), inv); + + _fmpz_demote_val(f); /* division by h may result in small value */ + _fmpz_demote_val(s); /* division by h may result in small value */ + } + } +} diff --git a/external/flint-2.4.3/fmpz/fdiv_r.c b/external/flint-2.4.3/fmpz/fdiv_r.c new file mode 100644 index 0000000..af60a85 --- /dev/null +++ b/external/flint-2.4.3/fmpz/fdiv_r.c @@ -0,0 +1,95 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" + +void +fmpz_fdiv_r(fmpz_t f, const fmpz_t g, const fmpz_t h) +{ + fmpz c1 = *g; + fmpz c2 = *h; + + if (fmpz_is_zero(h)) + { + flint_printf("Exception (fmpz_fdiv_r). Division by zero.\n"); + abort(); + } + + if (!COEFF_IS_MPZ(c1)) /* g is small */ + { + if (!COEFF_IS_MPZ(c2)) /* h is also small */ + { + fmpz q = c1 / c2; /* compute C quotient */ + fmpz r = c1 - c2 * q; /* compute remainder */ + + if ((c2 > WORD(0) && r < WORD(0)) || (c2 < WORD(0) && r > WORD(0))) + r += c2; + + fmpz_set_si(f, r); + } + else /* h is large and g is small */ + { + if (c1 == WORD(0)) + { + fmpz_set_si(f, c1); + } + else if ((c1 < WORD(0) && fmpz_sgn(h) < 0) || (c1 > WORD(0) && fmpz_sgn(h) > 0)) /* signs are the same */ + { + fmpz_set_si(f, c1); + } + else + { + fmpz_add(f, g, h); + } + } + } + else /* g is large */ + { + __mpz_struct * mpz_ptr = _fmpz_promote(f); + + if (!COEFF_IS_MPZ(c2)) /* h is small */ + { + if (c2 > 0) /* h > 0 */ + { + flint_mpz_fdiv_r_ui(mpz_ptr, COEFF_TO_PTR(c1), c2); + } + else + { + flint_mpz_cdiv_r_ui(mpz_ptr, COEFF_TO_PTR(c1), -c2); + } + } + else /* both are large */ + { + mpz_fdiv_r(mpz_ptr, COEFF_TO_PTR(c1), COEFF_TO_PTR(c2)); + } + _fmpz_demote_val(f); /* division by h may result in small value */ + } +} diff --git a/external/flint-2.4.3/fmpz/fdiv_r_2exp.c b/external/flint-2.4.3/fmpz/fdiv_r_2exp.c new file mode 100644 index 0000000..20fe228 --- /dev/null +++ b/external/flint-2.4.3/fmpz/fdiv_r_2exp.c @@ -0,0 +1,65 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +void fmpz_fdiv_r_2exp(fmpz_t f, const fmpz_t g, ulong exp) +{ + fmpz d = *g; + + if (!COEFF_IS_MPZ(d)) /* g is small */ + { + if (d >= 0) + { + fmpz_set_ui(f, exp < (FLINT_BITS - 2) ? d & ((WORD(1) << exp) - 1) : d); + } + else + { + if (exp <= FLINT_BITS - 2) + { + fmpz_set_ui(f, d & ((WORD(1) << exp) - 1)); + } + else + { + __mpz_struct * mpz_ptr = _fmpz_promote(f); + + flint_mpz_set_ui(mpz_ptr, 1); + mpz_mul_2exp(mpz_ptr, mpz_ptr, exp); + flint_mpz_sub_ui(mpz_ptr, mpz_ptr, -d); + } + } + } + else /*g is large */ + { + __mpz_struct * mpz_ptr = _fmpz_promote(f); /* g is already large */ + mpz_fdiv_r_2exp(mpz_ptr, COEFF_TO_PTR(d), exp); + _fmpz_demote_val(f); /* division may make value small */ + } +} + diff --git a/external/flint-2.4.3/fmpz/fdiv_ui.c b/external/flint-2.4.3/fmpz/fdiv_ui.c new file mode 100644 index 0000000..7f90602 --- /dev/null +++ b/external/flint-2.4.3/fmpz/fdiv_ui.c @@ -0,0 +1,62 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +ulong +fmpz_fdiv_ui(const fmpz_t g, ulong h) +{ + fmpz c1 = *g; + ulong r; + + if (h == UWORD(0)) + { + flint_printf("Exception (fmpz_fdiv_ui). Division by 0.\n"); + abort(); + } + + if (!COEFF_IS_MPZ(c1)) /* g is small */ + { + if (c1 < WORD(0)) + { + r = h - (-c1 % h); /* C doesn't correctly handle negative mods */ + if (r == h) + r = 0; + } + else + r = c1 % h; + + return r; + } + else /* g is large */ + { + return flint_mpz_fdiv_ui(COEFF_TO_PTR(c1), h); + } +} diff --git a/external/flint-2.4.3/fmpz/fib_ui.c b/external/flint-2.4.3/fmpz/fib_ui.c new file mode 100644 index 0000000..5478e6f --- /dev/null +++ b/external/flint-2.4.3/fmpz/fib_ui.c @@ -0,0 +1,70 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +#if FLINT64 +#define NUM_SMALL_FIB 94 +#else +#define NUM_SMALL_FIB 48 +#endif + +static const mp_limb_t small_fib[NUM_SMALL_FIB] = +{ + 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, + 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393, + 196418, 317811, 514229, 832040, 1346269, 2178309, 3524578, 5702887, + 9227465, 14930352, 24157817, 39088169, 63245986, 102334155, + 165580141, 267914296, 433494437, 701408733, 1134903170, 1836311903, + UWORD(2971215073), +#if FLINT64 + UWORD(4807526976), UWORD(7778742049), UWORD(12586269025), UWORD(20365011074), UWORD(32951280099), + UWORD(53316291173), UWORD(86267571272), UWORD(139583862445), UWORD(225851433717), + UWORD(365435296162), UWORD(591286729879), UWORD(956722026041), 1548008755920, + UWORD(2504730781961), UWORD(4052739537881), UWORD(6557470319842), 10610209857723, + UWORD(17167680177565), UWORD(27777890035288), UWORD(44945570212853), 72723460248141, + UWORD(117669030460994), UWORD(190392490709135), UWORD(308061521170129), 498454011879264, + UWORD(806515533049393), UWORD(1304969544928657), UWORD(2111485077978050), + UWORD(3416454622906707), UWORD(5527939700884757), UWORD(8944394323791464), + UWORD(14472334024676221), UWORD(23416728348467685), UWORD(37889062373143906), + UWORD(61305790721611591), UWORD(99194853094755497), UWORD(160500643816367088), + UWORD(259695496911122585), UWORD(420196140727489673), UWORD(679891637638612258), + UWORD(1100087778366101931), UWORD(1779979416004714189), UWORD(2880067194370816120), + UWORD(4660046610375530309), UWORD(7540113804746346429), UWORD(12200160415121876738) +#endif +}; + +void fmpz_fib_ui(fmpz_t f, ulong n) +{ + if (n < NUM_SMALL_FIB) + fmpz_set_ui(f, small_fib[n]); + else + flint_mpz_fib_ui(_fmpz_promote(f), n); +} diff --git a/external/flint-2.4.3/fmpz/fits_si.c b/external/flint-2.4.3/fmpz/fits_si.c new file mode 100644 index 0000000..e9d85d8 --- /dev/null +++ b/external/flint-2.4.3/fmpz/fits_si.c @@ -0,0 +1,92 @@ +/* int mpz_fits_X_p (mpz_t z) -- test whether z fits signed type X. + +Copyright 1997, 2000, 2001, 2002 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or (at your +option) any later version. + +The GNU MP Library 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +MA 02110-1301, USA. */ + +#include +#include "flint.h" +#include "fmpz.h" + +#if defined(_WIN64) + +#define FLINT_UI_MAX ((mp_limb_t)(~(mp_limb_t)0)) +#define FLINT_UI_HIBIT (FLINT_UI_MAX ^ (FLINT_UI_MAX >> 1)) +#define FLINT_SI_MAX ((mp_limb_signed_t)(FLINT_UI_MAX ^ FLINT_UI_HIBIT)) +#define FLINT_SI_MIN ((mp_limb_signed_t)FLINT_UI_HIBIT) + +int +flint_mpz_fits_si_p(mpz_srcptr z) +{ + mp_size_t n = z->_mp_size; + mp_ptr p = z->_mp_d; + mp_limb_t limb = p[0]; + + if (n == 0) + return 1; + if (n == 1) + return limb <= FLINT_SI_MAX; + if (n == -1) + return limb <= - (mp_limb_t) FLINT_SI_MIN; + return 0; +} + +#endif + +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2013 William Hart + +******************************************************************************/ + +int fmpz_fits_si(const fmpz_t f) +{ + if (!COEFF_IS_MPZ(*f)) + { + return 1; + } + else + { +#if defined(_WIN64) + return flint_mpz_fits_si_p(COEFF_TO_PTR(*f)); +#else + return mpz_fits_slong_p(COEFF_TO_PTR(*f)); +#endif + } +} + diff --git a/external/flint-2.4.3/fmpz/flog.c b/external/flint-2.4.3/fmpz/flog.c new file mode 100644 index 0000000..b181588 --- /dev/null +++ b/external/flint-2.4.3/fmpz/flog.c @@ -0,0 +1,80 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "ulong_extras.h" + +slong +fmpz_flog(const fmpz_t n, const fmpz_t b) +{ + fmpz_t t; + int sign; + slong r; + + if (fmpz_is_one(n)) + return 0; + + if (!COEFF_IS_MPZ(*b)) + return fmpz_flog_ui(n, *b); + + sign = fmpz_cmp(n, b); + if (sign <= 0) + return (sign == 0) ? 1 : 0; + + r = fmpz_dlog(n) / fmpz_dlog(b); + + fmpz_init(t); + fmpz_pow_ui(t, b, r); + sign = fmpz_cmp(t, n); + + /* Adjust down */ + if (sign > 0) + { + while (sign > 0) + { + fmpz_divexact(t, t, b); + sign = fmpz_cmp(t, n); + r--; + } + } + /* Adjust up */ + else if (sign < 0) + { + while (1) + { + fmpz_mul(t, t, b); + if (fmpz_cmp(t, n) <= 0) + r++; + else + break; + } + } + + fmpz_clear(t); + return r; +} + diff --git a/external/flint-2.4.3/fmpz/flog_ui.c b/external/flint-2.4.3/fmpz/flog_ui.c new file mode 100644 index 0000000..943c7a2 --- /dev/null +++ b/external/flint-2.4.3/fmpz/flog_ui.c @@ -0,0 +1,85 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "ulong_extras.h" + +slong +fmpz_flog_ui(const fmpz_t n, ulong b) +{ + fmpz_t t; + int sign; + slong r; + + if (fmpz_is_one(n)) + return 0; + + if (b == 2) + return fmpz_bits(n) - 1; + + if (!COEFF_IS_MPZ(*n)) + return n_flog(*n, b); + + sign = fmpz_cmp_ui(n, b); + if (sign <= 0) + return (sign == 0) ? 1 : 0; + + r = fmpz_dlog(n) / log(b); + + fmpz_init(t); + fmpz_set_ui(t, b); + fmpz_pow_ui(t, t, r); + sign = fmpz_cmp(t, n); + + /* Adjust down */ + if (sign > 0) + { + while (sign > 0) + { + fmpz_divexact_ui(t, t, b); + sign = fmpz_cmp(t, n); + r--; + } + } + /* Adjust up */ + else if (sign < 0) + { + while (1) + { + fmpz_mul_ui(t, t, b); + if (fmpz_cmp(t, n) <= 0) + r++; + else + break; + } + } + + fmpz_clear(t); + return r; +} diff --git a/external/flint-2.4.3/fmpz/fmpz.c b/external/flint-2.4.3/fmpz/fmpz.c new file mode 100644 index 0000000..c315dcf --- /dev/null +++ b/external/flint-2.4.3/fmpz/fmpz.c @@ -0,0 +1,159 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" + +/* Always free larger mpz's to avoid wasting too much heap space */ +#define FLINT_MPZ_MAX_CACHE_LIMBS 64 + +/* The number of new mpz's allocated at a time */ +#define MPZ_BLOCK 64 + +FLINT_TLS_PREFIX __mpz_struct ** mpz_free_arr = NULL; +FLINT_TLS_PREFIX ulong mpz_free_num = 0; +FLINT_TLS_PREFIX ulong mpz_free_alloc = 0; + +__mpz_struct * _fmpz_new_mpz(void) +{ + if (mpz_free_num != 0) + { + return mpz_free_arr[--mpz_free_num]; + } + else + { + __mpz_struct * z = flint_malloc(sizeof(__mpz_struct)); + mpz_init(z); + return z; + } +} + +void _fmpz_clear_mpz(fmpz f) +{ + __mpz_struct * ptr = COEFF_TO_PTR(f); + + if (ptr->_mp_alloc > FLINT_MPZ_MAX_CACHE_LIMBS) + mpz_realloc2(ptr, 1); + + if (mpz_free_num == mpz_free_alloc) + { + mpz_free_alloc = FLINT_MAX(64, mpz_free_alloc * 2); + mpz_free_arr = flint_realloc(mpz_free_arr, mpz_free_alloc * sizeof(__mpz_struct *)); + } + + mpz_free_arr[mpz_free_num++] = ptr; +} + +void _fmpz_cleanup_mpz_content(void) +{ + ulong i; + + for (i = 0; i < mpz_free_num; i++) + { + mpz_clear(mpz_free_arr[i]); + flint_free(mpz_free_arr[i]); + } + + mpz_free_num = mpz_free_alloc = 0; +} + +void _fmpz_cleanup(void) +{ + _fmpz_cleanup_mpz_content(); + flint_free(mpz_free_arr); + mpz_free_arr = NULL; +} + +__mpz_struct * _fmpz_promote(fmpz_t f) +{ + if (!COEFF_IS_MPZ(*f)) /* f is small so promote it first */ + { + __mpz_struct * mpz_ptr = _fmpz_new_mpz(); + (*f) = PTR_TO_COEFF(mpz_ptr); + return mpz_ptr; + } + else /* f is large already, just return the pointer */ + return COEFF_TO_PTR(*f); +} + +__mpz_struct * _fmpz_promote_val(fmpz_t f) +{ + fmpz c = (*f); + if (!COEFF_IS_MPZ(c)) /* f is small so promote it */ + { + __mpz_struct * mpz_ptr = _fmpz_new_mpz(); + (*f) = PTR_TO_COEFF(mpz_ptr); + flint_mpz_set_si(mpz_ptr, c); + return mpz_ptr; + } + else /* f is large already, just return the pointer */ + return COEFF_TO_PTR(c); +} + +void _fmpz_demote_val(fmpz_t f) +{ + __mpz_struct * mpz_ptr = COEFF_TO_PTR(*f); + int size = mpz_ptr->_mp_size; + + if (size == 1 || size == -1) + { + ulong uval = mpz_ptr->_mp_d[0]; + + if (uval <= (ulong) COEFF_MAX) + { + _fmpz_clear_mpz(*f); + *f = size * (fmpz) uval; + } + } + else if (size == 0) /* value is 0 */ + { + _fmpz_clear_mpz(*f); + *f = 0; + } + + /* don't do anything if value has to be multi precision */ +} + +void _fmpz_init_readonly_mpz(fmpz_t f, const mpz_t z) +{ + __mpz_struct *ptr; + *f = WORD(0); + ptr = _fmpz_promote(f); + + mpz_clear(ptr); + *ptr = *z; +} + +void _fmpz_clear_readonly_mpz(mpz_t z) +{ + if (((z->_mp_size == 1 || z->_mp_size == -1) && (z->_mp_d[0] <= COEFF_MAX)) + || (z->_mp_size == 0)) + { + mpz_clear(z); + } + +} diff --git a/external/flint-2.4.3/fmpz/fprint.c b/external/flint-2.4.3/fmpz/fprint.c new file mode 100644 index 0000000..66614de --- /dev/null +++ b/external/flint-2.4.3/fmpz/fprint.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include + +#include "fmpz.h" + +int fmpz_fprint(FILE * file, const fmpz_t x) +{ + if (!COEFF_IS_MPZ(*x)) + return flint_fprintf(file, "%wd", *x); + else + return (int) mpz_out_str(file, 10, COEFF_TO_PTR(*x)); +} + diff --git a/external/flint-2.4.3/fmpz/fread.c b/external/flint-2.4.3/fmpz/fread.c new file mode 100644 index 0000000..0787193 --- /dev/null +++ b/external/flint-2.4.3/fmpz/fread.c @@ -0,0 +1,45 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" + +int +fmpz_fread(FILE * file, fmpz_t f) +{ + mpz_t t; + size_t r; + + mpz_init(t); + r = mpz_inp_str(t, file, 10); + fmpz_set_mpz(f, t); + mpz_clear(t); + + return (r > 0) ? 1 : 0; +} + diff --git a/external/flint-2.4.3/fmpz/gcd.c b/external/flint-2.4.3/fmpz/gcd.c new file mode 100644 index 0000000..7a7051a --- /dev/null +++ b/external/flint-2.4.3/fmpz/gcd.c @@ -0,0 +1,85 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +ulong +z_gcd(slong a, slong b) +{ + ulong ua = FLINT_ABS(a); + ulong ub = FLINT_ABS(b); + + return n_gcd_full(ua, ub); +} + +void +fmpz_gcd(fmpz_t f, const fmpz_t g, const fmpz_t h) +{ + fmpz c1 = *g; + fmpz c2 = *h; + + if (fmpz_is_zero(g)) + { + fmpz_abs(f, h); + return; + } + + if (fmpz_is_zero(h)) + { + fmpz_abs(f, g); + return; + } + + if (!COEFF_IS_MPZ(c1)) /* g is small */ + { + if (!COEFF_IS_MPZ(c2)) /* h is also small */ + { + fmpz_set_si(f, z_gcd(c1, c2)); + } + else /* h is large, but g is small */ + { + fmpz c2d = fmpz_fdiv_ui(h, FLINT_ABS(c1)); + fmpz_set_si(f, z_gcd(c1, c2d)); + } + } + else + { + if (!COEFF_IS_MPZ(c2)) /* h is small, but g is large */ + { + fmpz c1d = fmpz_fdiv_ui(g, FLINT_ABS(c2)); + fmpz_set_si(f, z_gcd(c2, c1d)); + } + else /* g and h are both large */ + { + __mpz_struct *mpz_ptr = _fmpz_promote(f); /* aliasing fine as g, h already large */ + + mpz_gcd(mpz_ptr, COEFF_TO_PTR(c1), COEFF_TO_PTR(c2)); + _fmpz_demote_val(f); /* gcd may be small */ + } + } +} diff --git a/external/flint-2.4.3/fmpz/gcdinv.c b/external/flint-2.4.3/fmpz/gcdinv.c new file mode 100644 index 0000000..c5ef3b9 --- /dev/null +++ b/external/flint-2.4.3/fmpz/gcdinv.c @@ -0,0 +1,74 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +void fmpz_gcdinv(fmpz_t d, fmpz_t a, const fmpz_t f, const fmpz_t g) +{ + if (fmpz_is_zero(f)) + { + fmpz_set(d, g); + return; + } + + if (!COEFF_IS_MPZ(*g)) /* g is small, hence f is small */ + { + if (COEFF_IS_MPZ(*d)) + _fmpz_demote_val(d); + if (COEFF_IS_MPZ(*a)) + _fmpz_demote_val(a); + + *d = n_gcdinv((mp_limb_t *) a, *f, *g); + } + else /* g is large */ + { + _fmpz_promote_val(d); + _fmpz_promote_val(a); + + if (!COEFF_IS_MPZ(*f)) /* f is small */ + { + mpz_t fptr; + + fptr->_mp_alloc = 1; + fptr->_mp_size = 1; + fptr->_mp_d = (mp_limb_t *) f; + + mpz_gcdext(COEFF_TO_PTR(*d), COEFF_TO_PTR(*a), NULL, + fptr, COEFF_TO_PTR(*g)); + } + else /* f is large */ + { + mpz_gcdext(COEFF_TO_PTR(*d), COEFF_TO_PTR(*a), NULL, + COEFF_TO_PTR(*f), COEFF_TO_PTR(*g)); + } + + _fmpz_demote_val(d); + _fmpz_demote_val(a); + } +} + diff --git a/external/flint-2.4.3/fmpz/get_d.c b/external/flint-2.4.3/fmpz/get_d.c new file mode 100644 index 0000000..960897e --- /dev/null +++ b/external/flint-2.4.3/fmpz/get_d.c @@ -0,0 +1,67 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +#if FLINT64 /* 2^53 */ +#define DOUBLE_MAX WORD(9007199254740992) +#define DOUBLE_MIN WORD(-9007199254740992) +#else +#define DOUBLE_MAX COEFF_MAX +#define DOUBLE_MIN COEFF_MIN +#endif + +extern double __gmpn_get_d(mp_limb_t *, size_t, size_t, slong); + +double +fmpz_get_d(const fmpz_t f) +{ + fmpz c = *f; + + if (c >= DOUBLE_MIN && c <= DOUBLE_MAX) + { + return (double) c; + } + else if (!COEFF_IS_MPZ(c)) + { + mp_limb_t d; + + if (c > 0) + { + d = c; + return __gmpn_get_d(&d, 1, 1, 0); + } + else + { + d = -c; + return __gmpn_get_d(&d, 1, -1, 0); + } + } + else + return mpz_get_d(COEFF_TO_PTR(c)); +} diff --git a/external/flint-2.4.3/fmpz/get_d_2exp.c b/external/flint-2.4.3/fmpz/get_d_2exp.c new file mode 100644 index 0000000..7aa9aa8 --- /dev/null +++ b/external/flint-2.4.3/fmpz/get_d_2exp.c @@ -0,0 +1,60 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2009 Andy Novocin + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +extern double __gmpn_get_d(mp_limb_t *, size_t, size_t, slong); + +double +fmpz_get_d_2exp(slong *exp, const fmpz_t f) +{ + fmpz d = *f; + + if (!COEFF_IS_MPZ(d)) + { + ulong d_abs; + if (d == WORD(0)) + { + (*exp) = WORD(0); + return 0.0; + } + d_abs = FLINT_ABS(d); + (*exp) = FLINT_BIT_COUNT(d_abs); + if (d < WORD(0)) + return __gmpn_get_d((mp_limb_t *) &d_abs, WORD(1), WORD(-1), -*exp); + else + return __gmpn_get_d((mp_limb_t *) &d, WORD(1), WORD(1), -*exp); + } + else +#if defined(__MPIR_VERSION) + return mpz_get_d_2exp(exp, COEFF_TO_PTR(d)); +#else + return mpz_get_d_2exp((long *) exp, COEFF_TO_PTR(d)); +#endif +} diff --git a/external/flint-2.4.3/fmpz/get_mpz.c b/external/flint-2.4.3/fmpz/get_mpz.c new file mode 100644 index 0000000..c02b19e --- /dev/null +++ b/external/flint-2.4.3/fmpz/get_mpz.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +void +fmpz_get_mpz(mpz_t x, const fmpz_t f) +{ + if (!COEFF_IS_MPZ(*f)) + flint_mpz_set_si(x, *f); /* set x to small value */ + else + mpz_set(x, COEFF_TO_PTR(*f)); /* set x to large value */ +} diff --git a/external/flint-2.4.3/fmpz/get_si.c b/external/flint-2.4.3/fmpz/get_si.c new file mode 100644 index 0000000..f1b4778 --- /dev/null +++ b/external/flint-2.4.3/fmpz/get_si.c @@ -0,0 +1,35 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +slong +fmpz_get_si(const fmpz_t f) +{ + return (!COEFF_IS_MPZ(*f) ? *f : flint_mpz_get_si(COEFF_TO_PTR(*f))); +} diff --git a/external/flint-2.4.3/fmpz/get_str.c b/external/flint-2.4.3/fmpz/get_str.c new file mode 100644 index 0000000..dfa02e8 --- /dev/null +++ b/external/flint-2.4.3/fmpz/get_str.c @@ -0,0 +1,48 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +char * fmpz_get_str(char * str, int b, const fmpz_t f) +{ + if (!COEFF_IS_MPZ(*f)) + { + mpz_t z; + + flint_mpz_init_set_si(z, *f); + str = mpz_get_str(str, b, z); + mpz_clear(z); + } + else + { + str = mpz_get_str(str, b, COEFF_TO_PTR(*f)); + } + + return str; +} + diff --git a/external/flint-2.4.3/fmpz/get_ui.c b/external/flint-2.4.3/fmpz/get_ui.c new file mode 100644 index 0000000..2a70021 --- /dev/null +++ b/external/flint-2.4.3/fmpz/get_ui.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +ulong +fmpz_get_ui(const fmpz_t f) +{ + if (!COEFF_IS_MPZ(*f)) /*value is small */ + return (*f < WORD(0) ? -*f : *f); + else /* value is large */ + return flint_mpz_get_ui(COEFF_TO_PTR(*f)); +} diff --git a/external/flint-2.4.3/fmpz/init2.c b/external/flint-2.4.3/fmpz/init2.c new file mode 100644 index 0000000..573118e --- /dev/null +++ b/external/flint-2.4.3/fmpz/init2.c @@ -0,0 +1,44 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +void +fmpz_init2(fmpz_t f, ulong limbs) +{ + if (limbs) + { + __mpz_struct *mpz_ptr = _fmpz_new_mpz(); + *f = PTR_TO_COEFF(mpz_ptr); + _mpz_realloc(mpz_ptr, limbs); + } + else + { + (*f) = WORD(0); + } +} diff --git a/external/flint-2.4.3/fmpz/init_set_readonly.c b/external/flint-2.4.3/fmpz/init_set_readonly.c new file mode 100644 index 0000000..5bd478a --- /dev/null +++ b/external/flint-2.4.3/fmpz/init_set_readonly.c @@ -0,0 +1,49 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" + +void fmpz_init_set_readonly(fmpz_t f, const mpz_t z) +{ + if (z->_mp_size == 1 && z->_mp_d[0] <= COEFF_MAX) + { + *f = z->_mp_d[0]; + } + else if (z->_mp_size == -1 && z->_mp_d[0] <= COEFF_MAX) + { + *f = -(z->_mp_d[0]); + } + else if (z->_mp_size) + { + _fmpz_init_readonly_mpz(f, z); + } + else + { + *f = WORD(0); + } +} + diff --git a/external/flint-2.4.3/fmpz/inlines.c b/external/flint-2.4.3/fmpz/inlines.c new file mode 100644 index 0000000..50f8562 --- /dev/null +++ b/external/flint-2.4.3/fmpz/inlines.c @@ -0,0 +1,73 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#define ulong ulongxx /* interferes with system includes */ +#include +#undef ulong +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +fmpz * __new_fmpz() +{ + return flint_calloc(sizeof(fmpz), 1); +} + +void __free_fmpz(fmpz * f) +{ + _fmpz_demote(f); + flint_free(f); +} + +void __fmpz_set_si(fmpz_t f, slong val) +{ + if (val < COEFF_MIN || val > COEFF_MAX) /* val is large */ + { + __mpz_struct *mpz_coeff = _fmpz_promote(f); + flint_mpz_set_si(mpz_coeff, val); + } + else + { + _fmpz_demote(f); + *f = val; /* val is small */ + } +} + +void __fmpz_set_ui(fmpz_t f, ulong val) +{ + if (val > COEFF_MAX) /* val is large */ + { + __mpz_struct *mpz_coeff = _fmpz_promote(f); + flint_mpz_set_ui(mpz_coeff, val); + } + else + { + _fmpz_demote(f); + *f = val; /* val is small */ + } +} + + diff --git a/external/flint-2.4.3/fmpz/inp_raw.c b/external/flint-2.4.3/fmpz/inp_raw.c new file mode 100644 index 0000000..af18b5c --- /dev/null +++ b/external/flint-2.4.3/fmpz/inp_raw.c @@ -0,0 +1,41 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Qingwen GUAN + +******************************************************************************/ + + +#include "fmpz.h" + +size_t fmpz_inp_raw( fmpz_t x, FILE *fin ) +{ + mpz_t v; + size_t size; + + mpz_init( v ); + size = mpz_inp_raw( v, fin ); + fmpz_set_mpz( x, v ); + mpz_clear( v ); + + return size; +} + diff --git a/external/flint-2.4.3/fmpz/invmod.c b/external/flint-2.4.3/fmpz/invmod.c new file mode 100644 index 0000000..a0cf601 --- /dev/null +++ b/external/flint-2.4.3/fmpz/invmod.c @@ -0,0 +1,127 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +ulong +z_gcdinv(ulong * inv, slong a, ulong b) +{ + ulong g, ua = FLINT_ABS(a); + + if (ua >= b) + ua %= b; + + g = n_gcdinv(inv, ua, b); + + if (a < WORD(0)) + *inv = n_submod(UWORD(0), *inv, b); + + return g; +} + +int +fmpz_invmod(fmpz_t f, const fmpz_t g, const fmpz_t h) +{ + fmpz c1 = *g; + fmpz c2 = *h; + int val; + + if (fmpz_is_zero(h)) + { + flint_printf("Exception (fmpz_invmod). Division by zero.\n"); + abort(); + } + + if (!COEFF_IS_MPZ(c1)) /* g is small */ + { + if (!COEFF_IS_MPZ(c2)) /* h is also small */ + { + ulong inv, gcd; + if (c2 < WORD(0)) + c2 = -c2; + if (c2 == WORD(1)) + return 0; /* special case not handled by n_invmod */ + gcd = z_gcdinv(&inv, c1, c2); + + return (gcd == UWORD(1) ? fmpz_set_si(f, inv), 1 : 0); + } + else /* h is large and g is small */ + { + __mpz_struct temp; /* put g into a temporary mpz_t */ + __mpz_struct *mpz_ptr; + + if (c1 < WORD(0)) + { + c1 = -c1; + temp._mp_d = (mp_limb_t *) & c1; + temp._mp_size = -1; + } + else if (c1 == WORD(0)) + temp._mp_size = 0; + else + { + temp._mp_d = (mp_limb_t *) & c1; + temp._mp_size = 1; + } + + mpz_ptr = _fmpz_promote(f); + val = mpz_invert(mpz_ptr, &temp, COEFF_TO_PTR(c2)); + _fmpz_demote_val(f); /* inverse mod h may result in small value */ + + return val; + } + } + else /* g is large */ + { + if (!COEFF_IS_MPZ(c2)) /* h is small */ + { + ulong gcd, inv, r; + if (c2 < WORD(0)) + c2 = -c2; + if (c2 == WORD(1)) + return 0; /* special case not handled by z_gcd_invert */ + /* reduce g mod h first */ + + r = flint_mpz_fdiv_ui(COEFF_TO_PTR(c1), c2); + + gcd = z_gcdinv(&inv, r, c2); + + return (gcd == UWORD(1) ? fmpz_set_si(f, inv), 1 : 0); + } + else /* both are large */ + { + __mpz_struct *mpz_ptr = _fmpz_promote(f); + val = mpz_invert(mpz_ptr, COEFF_TO_PTR(c1), COEFF_TO_PTR(c2)); + _fmpz_demote_val(f); /* reduction mod h may result in small value */ + + return val; + } + } +} diff --git a/external/flint-2.4.3/fmpz/is_prime_pseudosquare.c b/external/flint-2.4.3/fmpz/is_prime_pseudosquare.c new file mode 100644 index 0000000..089fc64 --- /dev/null +++ b/external/flint-2.4.3/fmpz/is_prime_pseudosquare.c @@ -0,0 +1,357 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009, 2012 William Hart + +******************************************************************************/ + +#define ulong ulongxx /* interferes with system includes */ +#include +#include +#undef ulong +#define ulong mp_limb_t +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +#ifndef FLINT64 +mp_limb_t flint_fmpz_pseudosquares[][3] = +{ + { 17, 0, 0 }, + { 73, 0, 0 }, + { 241, 0, 0 }, + { 1009, 0, 0 }, + { 2641, 0, 0 }, + { 8089, 0, 0 }, + { 18001, 0, 0 }, + { 53881, 0, 0 }, + { 87481, 0, 0 }, + { 117049, 0, 0 }, + { 515761, 0, 0 }, + { 1083289, 0, 0 }, + { 3206641, 0, 0 }, + { 3818929, 0, 0 }, + { 9257329, 0, 0 }, + { 22000801, 0, 0 }, + { 48473881, 0, 0 }, + { 48473881, 0, 0 }, + { 175244281, 0, 0 }, + { 427733329, 0, 0 }, + { 427733329, 0, 0 }, + { 898716289u, 0, 0 }, + { 2805544681u, 0, 0 }, + { 2805544681u, 0, 0 }, + { 2805544681u, 0, 0 }, + { 1720328849u, 2u, 0 }, + { 2141495009u, 5u, 0 }, + { 3553231785u, 19u, 0 }, + { 3553231785u, 19u, 0 }, + { 2991566689u, 45u, 0 }, + { 2991566689u, 45u, 0 }, + { 2804689073u, 668u, 0 }, + { 2804689073u, 668u, 0 }, + { 2804689073u, 668u, 0 }, + { 46910577u, 6112u, 0 }, + { 46910577u, 6112u, 0 }, + { 1079027281u, 26178u, 0 }, + { 1079027281u, 26178u, 0 }, + { 1079027281u, 26178u, 0 }, + { 3590018425u, 41661u, 0 }, + { 3590018425u, 41661u, 0 }, + { 2746102297u, 162087u, 0 }, + { 2746102297u, 162087u, 0 }, + { 1936779721u, 664710u, 0 }, + { 1070451441u, 1501768u, 0 }, + { 1070451441u, 1501768u, 0 }, + { 2061289617u, 2710474u, 0 }, + { 2061289617u, 2710474u, 0 }, + { 4235760785u, 44382509u, 0 }, + { 2312776601u, 45783875u, 0 }, + { 2678348049u, 165920782u, 0 }, + { 3315991761u, 413007985u, 0 }, + { 1567179849u, 541956877u, 0 }, + { 2273104657u, 1486621767u, 0 }, + { 3796117489u, 1867116582u, 0 }, + { 2425538377u, 2374430322u, 0 }, + { 2425538377u, 2374430322u, 0 }, + { 2425538377u, 2374430322u, 0 }, + { 3763487577u, 3377920039u, 3u }, + { 2972093785u, 1402148275u, 11u }, + { 2785759393u, 3968325740u, 28u }, + { 551239041u, 3335735663u, 50u }, + { 551239041u, 3335735663u, 50u }, + { 732515297u, 554264481u, 116u }, + { 732515297u, 554264481u, 116u }, + { 732515297u, 554264481u, 116u }, + { 2681625681u, 3960593856u, 739u }, + { 2546105329u, 1679561907u, 1875u }, + { 533319201u, 2248012685u, 5393u }, + { 533319201u, 2248012685u, 5393u }, + { 996692113u, 2949507147u, 16011u }, + { 996692113u, 2949507147u, 16011u }, + { 2616068761u, 328479117u, 198156u }, + { 1411295841u, 761797252u, 229581u } +}; +#else +mp_limb_t flint_fmpz_pseudosquares[][2] = +{ + { 17, 0 }, + { 73, 0 }, + { 241, 0 }, + { 1009, 0 }, + { 2641, 0 }, + { 8089, 0 }, + { 18001, 0 }, + { 53881, 0 }, + { 87481, 0 }, + { 117049, 0 }, + { 515761, 0 }, + { 1083289, 0 }, + { 3206641, 0 }, + { 3818929, 0 }, + { 9257329, 0 }, + { 22000801, 0 }, + { 48473881, 0 }, + { 48473881, 0 }, + { 175244281, 0 }, + { 427733329, 0 }, + { 427733329, 0 }, + { 898716289u, 0 }, + { 2805544681u, 0 }, + { 2805544681u, 0 }, + { 2805544681u, 0 }, + { 10310263441u, 0 }, + { 23616331489u, 0 }, + { 85157610409u, 0 }, + { 85157610409u, 0 }, + { 196265095009u, 0 }, + { 196265095009u, 0 }, + { 2871842842801u, 0 }, + { 2871842842801u, 0 }, + { 2871842842801u, 0 }, + { 26250887023729u, 0 }, + { 26250887023729u, 0 }, + { 112434732901969u, 0 }, + { 112434732901969u, 0 }, + { 112434732901969u, 0 }, + { 178936222537081u, 0 }, + { 178936222537081u, 0 }, + { 696161110209049u, 0 }, + { 696161110209049u, 0 }, + { 2854909648103881u, 0 }, + { 6450045516630769u, 0 }, + { 6450045516630769u, 0 }, + { 11641399247947921u, 0 }, + { 11641399247947921u, 0 }, + { 190621428905186449u, 0 }, + { 196640248121928601u, 0 }, + { 712624335095093521u, 0 }, + { 1773855791877850321u, 0 }, + { 2327687064124474441u, 0 }, + { 6384991873059836689u, 0 }, + { 8019204661305419761u, 0 }, + { 10198100582046287689u, 0 }, + { 10198100582046287689u, 0 }, + { 10198100582046287689u, 0 }, + { 14508056099771532121u, 3u }, + { 6022180988239908185u, 11u }, + { 17043829275960758433u, 28u }, + { 14326875581237116289u, 50u }, + { 14326875581237116289u, 50u }, + { 2380547819961928673u, 116u }, + { 2380547819961928673u, 116u }, + { 2380547819961928673u, 116u }, + { 17010621086940159057u, 739u }, + { 7213663464718498801u, 1875u }, + { 9655140963601468961u, 5393u }, + { 9655140963601468961u, 5393u }, + { 12668036736679956625u, 16011u }, + { 12668036736679956625u, 16011u }, + { 1410807067550026393u, 198156u }, + { 3271894284933966433u, 229581u } +}; +#endif + +#define FLINT_NUM_FMPZ_PSEUDOSQUARES 74 + +void fmpz_set_pseudosquare(fmpz_t f, unsigned int i) +{ +#ifndef FLINT64 + if (i < 25) + fmpz_set_ui(f, flint_fmpz_pseudosquares[i][0]); + else if (i < 58) + { + fmpz_set_ui(f, flint_fmpz_pseudosquares[i][1]); + fmpz_mul_2exp(f, f, 32); + fmpz_add_ui(f, f, flint_fmpz_pseudosquares[i][0]); + } else if (i < FLINT_NUM_FMPZ_PSEUDOSQUARES) + { + fmpz_set_ui(f, flint_fmpz_pseudosquares[i][2]); + fmpz_mul_2exp(f, f, 32); + fmpz_add_ui(f, f, flint_fmpz_pseudosquares[i][1]); + fmpz_mul_2exp(f, f, 32); + fmpz_add_ui(f, f, flint_fmpz_pseudosquares[i][1]); + } +#else + if (i < 58) + fmpz_set_ui(f, flint_fmpz_pseudosquares[i][0]); + else if (i < FLINT_NUM_FMPZ_PSEUDOSQUARES) + { + fmpz_set_ui(f, flint_fmpz_pseudosquares[i][1]); + fmpz_mul_2exp(f, f, 64); + fmpz_add_ui(f, f, flint_fmpz_pseudosquares[i][0]); + } +#endif + else + { + flint_printf("Exception (fmpz_set_pseudosquare). Index too large.\n"); + abort(); + } +} + +int fmpz_is_prime_pseudosquare(const fmpz_t n) +{ + unsigned int i, j, m1; + mp_limb_t p, B, mod8; + fmpz_t NB, f, exp, mod, nm1; + int ret; + const mp_limb_t * primes; + + if (fmpz_sgn(n) <= 0) + return 0; + + if (fmpz_size(n) == 1) + return n_is_prime_pseudosquare(fmpz_get_ui(n)); + + primes = n_primes_arr_readonly(FLINT_PSEUDOSQUARES_CUTOFF + 1); + + for (i = 0; i < FLINT_PSEUDOSQUARES_CUTOFF; i++) + { + p = primes[i]; + if (fmpz_fdiv_ui(n, p) == 0) + return 0; + } + + fmpz_init(NB); + fmpz_init(f); + fmpz_init(exp); + fmpz_init(mod); + fmpz_init(nm1); + + B = primes[FLINT_PSEUDOSQUARES_CUTOFF]; + fmpz_sub_ui(nm1, n, 1); + fmpz_fdiv_q_ui(NB, nm1, B); + fmpz_add_ui(NB, NB, 1); + + m1 = 0; + + for (i = 0; i < FLINT_NUM_FMPZ_PSEUDOSQUARES; i++) + { + fmpz_set_pseudosquare(f, i); + if (fmpz_cmp(f, NB) > 0) + break; + } + + if (i == FLINT_NUM_FMPZ_PSEUDOSQUARES) + { + ret = -1; + goto cleanup; + } + + fmpz_fdiv_q_2exp(exp, nm1, 1); + + for (j = 0; j <= i; j++) + { + fmpz_set_ui(mod, primes[j]); + fmpz_powm(mod, mod, exp, n); + if (!fmpz_is_one(mod) && fmpz_cmp(mod, nm1) != 0) + { + ret = 0; + goto cleanup; + } + if (fmpz_cmp(mod, nm1) == 0) + m1 = 1; + } + + mod8 = fmpz_fdiv_ui(n, 8); + + if ((mod8 == 3) || (mod8 == 7)) + { + ret = 1; + goto cleanup; + } + + if (mod8 == 5) + { + fmpz_set_ui(mod, 2); + fmpz_powm(mod, mod, exp, n); + if (fmpz_cmp(mod, nm1) == 0) + { + ret = 1; + goto cleanup; + } + flint_printf("Whoah, "); + fmpz_print(n); + flint_printf("is a probable prime, but not prime, please report!!\n"); + abort(); + } + else + { + if (m1) + { + ret = 1; + goto cleanup; + } + + for (j = i + 1; j < FLINT_NUM_FMPZ_PSEUDOSQUARES + 1; j++) + { + fmpz_set_ui(mod, primes[j]); + fmpz_powm(mod, mod, exp, n); + if (fmpz_cmp(mod, nm1) == 0) + { + ret = 1; + goto cleanup; + } + if (!fmpz_is_one(mod)) + { + flint_printf("Whoah, "); + fmpz_print(n); + flint_printf("is a probable prime, but not prime, please report!!\n"); + abort(); + } + } + flint_printf("Whoah, "); + fmpz_print(n); + flint_printf("is a probable prime, but not prime, please report!!\n"); + abort(); + } + +cleanup: + + fmpz_clear(NB); + fmpz_clear(f); + fmpz_clear(exp); + fmpz_clear(mod); + fmpz_clear(nm1); + + return ret; +} diff --git a/external/flint-2.4.3/fmpz/is_probabprime.c b/external/flint-2.4.3/fmpz/is_probabprime.c new file mode 100644 index 0000000..b8dbfa7 --- /dev/null +++ b/external/flint-2.4.3/fmpz/is_probabprime.c @@ -0,0 +1,48 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +fmpz_is_probabprime(const fmpz_t p) +{ + fmpz c = *p; + + if (fmpz_sgn(p) <= 0) + return 0; + + if (!COEFF_IS_MPZ(c)) + return n_is_probabprime(c); + else + { + int ret; + + ret = (mpz_probab_prime_p(COEFF_TO_PTR(c), 25) != 0); + return ret; + } +} diff --git a/external/flint-2.4.3/fmpz/is_square.c b/external/flint-2.4.3/fmpz/is_square.c new file mode 100644 index 0000000..b07530c --- /dev/null +++ b/external/flint-2.4.3/fmpz/is_square.c @@ -0,0 +1,45 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +fmpz_is_square(const fmpz_t x) +{ + fmpz c = *x; + + if (!COEFF_IS_MPZ(c)) + { + if (c <= 1) + return (c >= 0); + + return n_is_square(c); + } + else + return mpz_perfect_square_p(COEFF_TO_PTR(c)); +} diff --git a/external/flint-2.4.3/fmpz/jacobi.c b/external/flint-2.4.3/fmpz/jacobi.c new file mode 100644 index 0000000..ae5d5b8 --- /dev/null +++ b/external/flint-2.4.3/fmpz/jacobi.c @@ -0,0 +1,60 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +fmpz_jacobi(const fmpz_t a, const fmpz_t p) +{ + fmpz c = *p; + fmpz d = *a; + mpz_t t, u; + int r; + + if (d == 0) + return 0; + + if (c == 2) + return 1; + + if (!COEFF_IS_MPZ(c) && !COEFF_IS_MPZ(d)) + return n_jacobi(d, c); + + if (COEFF_IS_MPZ(c) && COEFF_IS_MPZ(d)) + return mpz_jacobi(COEFF_TO_PTR(d), COEFF_TO_PTR(c)); + + flint_mpz_init_set_readonly(t, a); + flint_mpz_init_set_readonly(u, p); + + r = mpz_jacobi(t, u); + + flint_mpz_clear_readonly(t); + flint_mpz_clear_readonly(u); + + return r; +} diff --git a/external/flint-2.4.3/fmpz/lcm.c b/external/flint-2.4.3/fmpz/lcm.c new file mode 100644 index 0000000..fec74f5 --- /dev/null +++ b/external/flint-2.4.3/fmpz/lcm.c @@ -0,0 +1,59 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" + +void +fmpz_lcm(fmpz_t f, const fmpz_t g, const fmpz_t h) +{ + fmpz_t t; + + if (fmpz_is_zero(g) || fmpz_is_zero(h)) + { + fmpz_zero(f); + return; + } + + if (fmpz_is_pm1(g)) + { + fmpz_abs(f, h); + return; + } + + if (fmpz_is_pm1(h)) + { + fmpz_abs(f, g); + return; + } + + fmpz_init(t); + fmpz_gcd(t, g, h); + fmpz_divexact(t, g, t); + fmpz_mul(f, t, h); + fmpz_abs(f, f); + fmpz_clear(t); +} diff --git a/external/flint-2.4.3/fmpz/link/fmpz_gc.c b/external/flint-2.4.3/fmpz/link/fmpz_gc.c new file mode 100644 index 0000000..640d9f5 --- /dev/null +++ b/external/flint-2.4.3/fmpz/link/fmpz_gc.c @@ -0,0 +1,212 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009, 2013 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" + +#if FLINT_REENTRANT +#include + +static pthread_once_t fmpz_initialised = PTHREAD_ONCE_INIT; +pthread_mutex_t fmpz_lock; +#endif + +/* Always free larger mpz's to avoid wasting too much heap space */ +#define FLINT_MPZ_MAX_CACHE_LIMBS 64 + +/* The number of new mpz's allocated at a time */ +#define MPZ_BLOCK 64 + +/* there's no point using TLS here as GC doesn't support it */ +__mpz_struct ** mpz_free_arr = NULL; +__mpz_struct ** mpz_arr = NULL; +ulong mpz_num = 0; +ulong mpz_alloc = 0; +ulong mpz_free_num = 0; +ulong mpz_free_alloc = 0; + +#if FLINT_REENTRANT +void fmpz_lock_init() +{ + pthread_mutex_init(&fmpz_lock, NULL); +} +#endif + +__mpz_struct * _fmpz_new_mpz(void) +{ + __mpz_struct * z = NULL; + +#if FLINT_REENTRANT + pthread_once(&fmpz_initialised, fmpz_lock_init); + pthread_mutex_lock(&fmpz_lock); +#endif + + if (mpz_free_num != 0) + z = mpz_free_arr[--mpz_free_num]; + else + { + z = flint_malloc(sizeof(__mpz_struct)); + + if (mpz_num == mpz_alloc) /* store pointer to prevent gc cleanup */ + { + mpz_alloc = FLINT_MAX(64, mpz_alloc * 2); + mpz_arr = flint_realloc(mpz_arr, mpz_alloc * sizeof(__mpz_struct *)); + } + mpz_arr[mpz_num++] = z; + + mpz_init(z); + } + +#if FLINT_REENTRANT + pthread_mutex_unlock(&fmpz_lock); +#endif + + return z; +} + +void _fmpz_clear_mpz(fmpz f) +{ + __mpz_struct * ptr = COEFF_TO_PTR(f); + + if (ptr->_mp_alloc > FLINT_MPZ_MAX_CACHE_LIMBS) + mpz_realloc2(ptr, 1); + +#if FLINT_REENTRANT + pthread_mutex_lock(&fmpz_lock); +#endif + + if (mpz_free_num == mpz_free_alloc) + { + mpz_free_alloc = FLINT_MAX(64, mpz_free_alloc * 2); + mpz_free_arr = flint_realloc(mpz_free_arr, mpz_free_alloc * sizeof(__mpz_struct *)); + } + + mpz_free_arr[mpz_free_num++] = ptr; + +#if FLINT_REENTRANT + pthread_mutex_unlock(&fmpz_lock); +#endif +} + +void _fmpz_cleanup_mpz_content(void) +{ + ulong i; + + for (i = 0; i < mpz_free_num; i++) + { + mpz_clear(mpz_free_arr[i]); + flint_free(mpz_free_arr[i]); + } + + /* TODO: remove selected mpz's from mpz_arr too and compact */ + mpz_free_num = mpz_free_alloc = 0; +} + +void _fmpz_cleanup(void) +{ +#if FLINT_REENTRANT + pthread_mutex_lock(&fmpz_lock); +#endif + + _fmpz_cleanup_mpz_content(); + flint_free(mpz_free_arr); + mpz_free_arr = NULL; + +#if FLINT_REENTRANT + pthread_mutex_unlock(&fmpz_lock); +#endif +} + +__mpz_struct * _fmpz_promote(fmpz_t f) +{ + if (!COEFF_IS_MPZ(*f)) /* f is small so promote it first */ + { + __mpz_struct * mpz_ptr = _fmpz_new_mpz(); + (*f) = PTR_TO_COEFF(mpz_ptr); + return mpz_ptr; + } + else /* f is large already, just return the pointer */ + return COEFF_TO_PTR(*f); +} + +__mpz_struct * _fmpz_promote_val(fmpz_t f) +{ + fmpz c = (*f); + if (!COEFF_IS_MPZ(c)) /* f is small so promote it */ + { + __mpz_struct * mpz_ptr = _fmpz_new_mpz(); + (*f) = PTR_TO_COEFF(mpz_ptr); + flint_mpz_set_si(mpz_ptr, c); + return mpz_ptr; + } + else /* f is large already, just return the pointer */ + return COEFF_TO_PTR(c); +} + +void _fmpz_demote_val(fmpz_t f) +{ + __mpz_struct * mpz_ptr = COEFF_TO_PTR(*f); + int size = mpz_ptr->_mp_size; + + if (size == 1 || size == -1) + { + ulong uval = mpz_ptr->_mp_d[0]; + + if (uval <= (ulong) COEFF_MAX) + { + _fmpz_clear_mpz(*f); + *f = size * (fmpz) uval; + } + } + else if (size == 0) /* value is 0 */ + { + _fmpz_clear_mpz(*f); + *f = 0; + } + + /* don't do anything if value has to be multi precision */ +} + +void _fmpz_init_readonly_mpz(fmpz_t f, const mpz_t z) +{ + __mpz_struct *ptr; + *f = WORD(0); + ptr = _fmpz_promote(f); + + mpz_clear(ptr); + *ptr = *z; +} + +void _fmpz_clear_readonly_mpz(mpz_t z) +{ + if (((z->_mp_size == 1 || z->_mp_size == -1) && (z->_mp_d[0] <= COEFF_MAX)) + || (z->_mp_size == 0)) + { + mpz_clear(z); + } + +} diff --git a/external/flint-2.4.3/fmpz/link/fmpz_reentrant.c b/external/flint-2.4.3/fmpz/link/fmpz_reentrant.c new file mode 100644 index 0000000..1b066e5 --- /dev/null +++ b/external/flint-2.4.3/fmpz/link/fmpz_reentrant.c @@ -0,0 +1,111 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" + +__mpz_struct * _fmpz_new_mpz(void) +{ + __mpz_struct * mpz_ptr = (__mpz_struct *) flint_malloc(sizeof(__mpz_struct)); + mpz_init(mpz_ptr); + return mpz_ptr; +} + +void _fmpz_clear_mpz(fmpz f) +{ + mpz_clear(COEFF_TO_PTR(f)); + flint_free(COEFF_TO_PTR(f)); +} + +void _fmpz_cleanup_mpz_content(void) +{ +} + +void _fmpz_cleanup(void) +{ +} + +__mpz_struct * _fmpz_promote(fmpz_t f) +{ + if (!COEFF_IS_MPZ(*f)) /* f is small so promote it first */ + { + __mpz_struct * mpz_ptr = _fmpz_new_mpz(); + *f = PTR_TO_COEFF(mpz_ptr); + return mpz_ptr; + } + else /* f is large already, just return the pointer */ + return COEFF_TO_PTR(*f); +} + +__mpz_struct * _fmpz_promote_val(fmpz_t f) +{ + fmpz c = *f; + if (!COEFF_IS_MPZ(c)) /* f is small so promote it */ + { + __mpz_struct * mpz_ptr = _fmpz_new_mpz(); + *f = PTR_TO_COEFF(mpz_ptr); + flint_mpz_set_si(mpz_ptr, c); + return mpz_ptr; + } + else /* f is large already, just return the pointer */ + return COEFF_TO_PTR(*f); +} + +void _fmpz_demote_val(fmpz_t f) +{ + __mpz_struct * mpz_ptr = COEFF_TO_PTR(*f); + int size = mpz_ptr->_mp_size; + + if (!(((unsigned int) size + 1U) & ~2U)) /* size +-1 */ + { + ulong uval = mpz_ptr->_mp_d[0]; + + if (uval <= (ulong) COEFF_MAX) + { + _fmpz_clear_mpz(*f); + *f = size * (fmpz) uval; + } + } + else if (size == 0) /* value is 0 */ + { + _fmpz_clear_mpz(*f); + *f = 0; + } + + /* don't do anything if value has to be multi precision */ +} + +void _fmpz_init_readonly_mpz(fmpz_t f, const mpz_t z) +{ + __mpz_struct * mpz_ptr = (__mpz_struct *) flint_malloc(sizeof(__mpz_struct)); + *f = PTR_TO_COEFF(mpz_ptr); + *mpz_ptr = *z; +} + +void _fmpz_clear_readonly_mpz(mpz_t z) +{ +} diff --git a/external/flint-2.4.3/fmpz/link/fmpz_single.c b/external/flint-2.4.3/fmpz/link/fmpz_single.c new file mode 100644 index 0000000..c315dcf --- /dev/null +++ b/external/flint-2.4.3/fmpz/link/fmpz_single.c @@ -0,0 +1,159 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" + +/* Always free larger mpz's to avoid wasting too much heap space */ +#define FLINT_MPZ_MAX_CACHE_LIMBS 64 + +/* The number of new mpz's allocated at a time */ +#define MPZ_BLOCK 64 + +FLINT_TLS_PREFIX __mpz_struct ** mpz_free_arr = NULL; +FLINT_TLS_PREFIX ulong mpz_free_num = 0; +FLINT_TLS_PREFIX ulong mpz_free_alloc = 0; + +__mpz_struct * _fmpz_new_mpz(void) +{ + if (mpz_free_num != 0) + { + return mpz_free_arr[--mpz_free_num]; + } + else + { + __mpz_struct * z = flint_malloc(sizeof(__mpz_struct)); + mpz_init(z); + return z; + } +} + +void _fmpz_clear_mpz(fmpz f) +{ + __mpz_struct * ptr = COEFF_TO_PTR(f); + + if (ptr->_mp_alloc > FLINT_MPZ_MAX_CACHE_LIMBS) + mpz_realloc2(ptr, 1); + + if (mpz_free_num == mpz_free_alloc) + { + mpz_free_alloc = FLINT_MAX(64, mpz_free_alloc * 2); + mpz_free_arr = flint_realloc(mpz_free_arr, mpz_free_alloc * sizeof(__mpz_struct *)); + } + + mpz_free_arr[mpz_free_num++] = ptr; +} + +void _fmpz_cleanup_mpz_content(void) +{ + ulong i; + + for (i = 0; i < mpz_free_num; i++) + { + mpz_clear(mpz_free_arr[i]); + flint_free(mpz_free_arr[i]); + } + + mpz_free_num = mpz_free_alloc = 0; +} + +void _fmpz_cleanup(void) +{ + _fmpz_cleanup_mpz_content(); + flint_free(mpz_free_arr); + mpz_free_arr = NULL; +} + +__mpz_struct * _fmpz_promote(fmpz_t f) +{ + if (!COEFF_IS_MPZ(*f)) /* f is small so promote it first */ + { + __mpz_struct * mpz_ptr = _fmpz_new_mpz(); + (*f) = PTR_TO_COEFF(mpz_ptr); + return mpz_ptr; + } + else /* f is large already, just return the pointer */ + return COEFF_TO_PTR(*f); +} + +__mpz_struct * _fmpz_promote_val(fmpz_t f) +{ + fmpz c = (*f); + if (!COEFF_IS_MPZ(c)) /* f is small so promote it */ + { + __mpz_struct * mpz_ptr = _fmpz_new_mpz(); + (*f) = PTR_TO_COEFF(mpz_ptr); + flint_mpz_set_si(mpz_ptr, c); + return mpz_ptr; + } + else /* f is large already, just return the pointer */ + return COEFF_TO_PTR(c); +} + +void _fmpz_demote_val(fmpz_t f) +{ + __mpz_struct * mpz_ptr = COEFF_TO_PTR(*f); + int size = mpz_ptr->_mp_size; + + if (size == 1 || size == -1) + { + ulong uval = mpz_ptr->_mp_d[0]; + + if (uval <= (ulong) COEFF_MAX) + { + _fmpz_clear_mpz(*f); + *f = size * (fmpz) uval; + } + } + else if (size == 0) /* value is 0 */ + { + _fmpz_clear_mpz(*f); + *f = 0; + } + + /* don't do anything if value has to be multi precision */ +} + +void _fmpz_init_readonly_mpz(fmpz_t f, const mpz_t z) +{ + __mpz_struct *ptr; + *f = WORD(0); + ptr = _fmpz_promote(f); + + mpz_clear(ptr); + *ptr = *z; +} + +void _fmpz_clear_readonly_mpz(mpz_t z) +{ + if (((z->_mp_size == 1 || z->_mp_size == -1) && (z->_mp_d[0] <= COEFF_MAX)) + || (z->_mp_size == 0)) + { + mpz_clear(z); + } + +} diff --git a/external/flint-2.4.3/fmpz/mod.c b/external/flint-2.4.3/fmpz/mod.c new file mode 100644 index 0000000..2986d9c --- /dev/null +++ b/external/flint-2.4.3/fmpz/mod.c @@ -0,0 +1,82 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +void +fmpz_mod(fmpz_t f, const fmpz_t g, const fmpz_t h) +{ + fmpz c1 = *g; + fmpz c2 = *h; + + if (!COEFF_IS_MPZ(c1)) /* g is small */ + { + if (!COEFF_IS_MPZ(c2)) /* h is also small */ + { + slong r; + if (c2 < WORD(0)) + c2 = -c2; + if (c1 < WORD(0)) + { + r = c2 - (-c1 % c2); /* C doesn't correctly handle negative mods */ + if (r == c2) + r = 0; + } + else + r = c1 % c2; + + fmpz_set_si(f, r); + } + else /* h is large and g is small */ + { + if (c1 < WORD(0)) + { + fmpz_abs(f, h); + fmpz_sub_ui(f, f, -c1); + } + else + fmpz_set_ui(f, c1); + } + } + else /* g is large */ + { + if (!COEFF_IS_MPZ(c2)) /* h is small */ + { + if (c2 < WORD(0)) + fmpz_set_si(f, flint_mpz_fdiv_ui(COEFF_TO_PTR(c1), -c2)); + else + fmpz_set_ui(f, flint_mpz_fdiv_ui(COEFF_TO_PTR(c1), c2)); + } + else /* both are large */ + { + __mpz_struct *mpz_ptr = _fmpz_promote(f); + mpz_mod(mpz_ptr, COEFF_TO_PTR(c1), COEFF_TO_PTR(c2)); + _fmpz_demote_val(f); /* reduction mod h may result in small value */ + } + } +} diff --git a/external/flint-2.4.3/fmpz/mod_ui.c b/external/flint-2.4.3/fmpz/mod_ui.c new file mode 100644 index 0000000..a6696a5 --- /dev/null +++ b/external/flint-2.4.3/fmpz/mod_ui.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +ulong +fmpz_mod_ui(fmpz_t f, const fmpz_t g, ulong h) +{ + h = fmpz_fdiv_ui(g, h); + fmpz_set_ui(f, h); + return h; +} diff --git a/external/flint-2.4.3/fmpz/mpz_clear_readonly.c b/external/flint-2.4.3/fmpz/mpz_clear_readonly.c new file mode 100644 index 0000000..a74d28e --- /dev/null +++ b/external/flint-2.4.3/fmpz/mpz_clear_readonly.c @@ -0,0 +1,34 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" + +void flint_mpz_clear_readonly(mpz_t z) +{ + _fmpz_clear_readonly_mpz(z); +} + diff --git a/external/flint-2.4.3/fmpz/mpz_init_set_readonly.c b/external/flint-2.4.3/fmpz/mpz_init_set_readonly.c new file mode 100644 index 0000000..cc61ed0 --- /dev/null +++ b/external/flint-2.4.3/fmpz/mpz_init_set_readonly.c @@ -0,0 +1,41 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" + +void flint_mpz_init_set_readonly(mpz_t z, const fmpz_t f) +{ + if (COEFF_IS_MPZ(*f)) + { + *z = *COEFF_TO_PTR(*f); + } + else + { + flint_mpz_init_set_si(z, *f); + } +} + diff --git a/external/flint-2.4.3/fmpz/mul.c b/external/flint-2.4.3/fmpz/mul.c new file mode 100644 index 0000000..c9d83f2 --- /dev/null +++ b/external/flint-2.4.3/fmpz/mul.c @@ -0,0 +1,59 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +void +fmpz_mul(fmpz_t f, const fmpz_t g, const fmpz_t h) +{ + fmpz c1, c2; + __mpz_struct *mpz_ptr; + + c1 = *g; + + if (!COEFF_IS_MPZ(c1)) /* g is small */ + { + fmpz_mul_si(f, h, c1); + return; + } + + c2 = *h; /* save h in case it is aliased with f */ + + if (c2 == WORD(0)) /* special case, h = 0 */ + { + fmpz_zero(f); + return; + } + + mpz_ptr = _fmpz_promote(f); /* h is saved, g is already large */ + + if (!COEFF_IS_MPZ(c2)) /* g is large, h is small */ + flint_mpz_mul_si(mpz_ptr, COEFF_TO_PTR(c1), c2); + else /* c1 and c2 are large */ + mpz_mul(mpz_ptr, COEFF_TO_PTR(c1), COEFF_TO_PTR(c2)); +} diff --git a/external/flint-2.4.3/fmpz/mul_2exp.c b/external/flint-2.4.3/fmpz/mul_2exp.c new file mode 100644 index 0000000..931943c --- /dev/null +++ b/external/flint-2.4.3/fmpz/mul_2exp.c @@ -0,0 +1,60 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +void +fmpz_mul_2exp(fmpz_t f, const fmpz_t g, ulong exp) +{ + fmpz d = *g; + + if (!COEFF_IS_MPZ(d)) /* g is small */ + { + ulong dabs = FLINT_ABS(d); + ulong bits = FLINT_BIT_COUNT(dabs); + if (bits == 0) + { + fmpz_set_si(f, 0); + } + else if (bits + exp <= FLINT_BITS - 2) /* result will fit in small */ + { + fmpz_set_si(f, d << exp); + } + else /* result is large */ + { + __mpz_struct *mpz_ptr = _fmpz_promote(f); /* g is saved */ + flint_mpz_set_si(mpz_ptr, d); + mpz_mul_2exp(mpz_ptr, mpz_ptr, exp); + } + } + else /* g is large */ + { + __mpz_struct *mpz_ptr = _fmpz_promote(f); /* g is already large */ + mpz_mul_2exp(mpz_ptr, COEFF_TO_PTR(d), exp); + } +} diff --git a/external/flint-2.4.3/fmpz/mul_si.c b/external/flint-2.4.3/fmpz/mul_si.c new file mode 100644 index 0000000..0daa659 --- /dev/null +++ b/external/flint-2.4.3/fmpz/mul_si.c @@ -0,0 +1,59 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +void +fmpz_mul_si(fmpz_t f, const fmpz_t g, slong x) +{ + fmpz c2 = *g; + + if (x == 0) + { + fmpz_zero(f); + return; + } + else if (!COEFF_IS_MPZ(c2)) /* c2 is small */ + { + mp_limb_t prod[2]; + mp_limb_t uc2 = FLINT_ABS(c2); + mp_limb_t ux = FLINT_ABS(x); + + /* unsigned limb by limb multiply (assembly for most CPU's) */ + umul_ppmm(prod[1], prod[0], uc2, ux); + if ((c2 ^ x) < WORD(0)) + fmpz_neg_uiui(f, prod[1], prod[0]); + else + fmpz_set_uiui(f, prod[1], prod[0]); + } + else /* c2 is large */ + { + __mpz_struct *mpz_ptr = _fmpz_promote(f); /* ok without val as if aliased both are large */ + flint_mpz_mul_si(mpz_ptr, COEFF_TO_PTR(c2), x); + } +} diff --git a/external/flint-2.4.3/fmpz/mul_si_tdiv_q_2exp.c b/external/flint-2.4.3/fmpz/mul_si_tdiv_q_2exp.c new file mode 100644 index 0000000..8037eb6 --- /dev/null +++ b/external/flint-2.4.3/fmpz/mul_si_tdiv_q_2exp.c @@ -0,0 +1,99 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2012 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +void +fmpz_mul_si_tdiv_q_2exp(fmpz_t f, const fmpz_t g, slong x, ulong exp) +{ + fmpz c2 = *g; + + if (x == 0) + { + fmpz_zero(f); + return; + } + else if (!COEFF_IS_MPZ(c2)) /* c2 is small */ + { + mp_limb_t prod[2]; + mp_limb_t uc2; + mp_limb_t ux; + + if (exp >= 2 * FLINT_BITS) + { + fmpz_zero(f); + return; + } + + uc2 = FLINT_ABS(c2); + ux = FLINT_ABS(x); + + umul_ppmm(prod[1], prod[0], uc2, ux); + + if (exp >= FLINT_BITS) + { + fmpz_set_ui(f, prod[1] >> (exp - FLINT_BITS)); + if ((c2 ^ x) < WORD(0)) + fmpz_neg(f, f); + return; + } + + if (exp != 0) + { + prod[0] = (prod[1] << (FLINT_BITS - exp)) | (prod[0] >> exp); + prod[1] >>= exp; + } + + if (!prod[1]) + { + fmpz_set_ui(f, prod[0]); + if ((c2 ^ x) < WORD(0)) + fmpz_neg(f, f); + return; + } + else /* result takes two limbs */ + { + __mpz_struct *mpz_ptr = _fmpz_promote(f); + + /* two limbs, least significant first, native endian, no +nails, stored in prod */ + mpz_import(mpz_ptr, 2, -1, sizeof(mp_limb_t), 0, 0, prod); + if ((c2 ^ x) < WORD(0)) + mpz_neg(mpz_ptr, mpz_ptr); + } + } + else /* c2 is large */ + { + __mpz_struct *mpz_ptr = _fmpz_promote(f); /* ok without val as + if aliased both are large */ + flint_mpz_mul_si(mpz_ptr, COEFF_TO_PTR(c2), x); + mpz_tdiv_q_2exp(mpz_ptr, mpz_ptr, exp); + _fmpz_demote_val(f); /* value may be small */ + } +} diff --git a/external/flint-2.4.3/fmpz/mul_tdiv_q_2exp.c b/external/flint-2.4.3/fmpz/mul_tdiv_q_2exp.c new file mode 100644 index 0000000..8e3e329 --- /dev/null +++ b/external/flint-2.4.3/fmpz/mul_tdiv_q_2exp.c @@ -0,0 +1,63 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2012 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +void +fmpz_mul_tdiv_q_2exp(fmpz_t f, const fmpz_t g, const fmpz_t h, ulong exp) +{ + fmpz c1, c2; + __mpz_struct *mpz_ptr; + + c1 = *g; + + if (!COEFF_IS_MPZ(c1)) /* g is small */ + { + fmpz_mul_si_tdiv_q_2exp(f, h, c1, exp); + return; + } + + c2 = *h; /* save h in case it is aliased with f */ + + if (c2 == WORD(0)) /* special case, h = 0 */ + { + fmpz_zero(f); + return; + } + + mpz_ptr = _fmpz_promote(f); /* h is saved, g is already large */ + + if (!COEFF_IS_MPZ(c2)) /* g is large, h is small */ + flint_mpz_mul_si(mpz_ptr, COEFF_TO_PTR(c1), c2); + else /* c1 and c2 are large */ + mpz_mul(mpz_ptr, COEFF_TO_PTR(c1), COEFF_TO_PTR(c2)); + + mpz_tdiv_q_2exp(mpz_ptr, mpz_ptr, exp); + _fmpz_demote_val(f); /* division may make value small */ +} diff --git a/external/flint-2.4.3/fmpz/mul_ui.c b/external/flint-2.4.3/fmpz/mul_ui.c new file mode 100644 index 0000000..848a725 --- /dev/null +++ b/external/flint-2.4.3/fmpz/mul_ui.c @@ -0,0 +1,59 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +void +fmpz_mul_ui(fmpz_t f, const fmpz_t g, ulong x) +{ + fmpz c2 = *g; + + if (x == 0) + { + fmpz_zero(f); + return; + } + else if (!COEFF_IS_MPZ(c2)) /* c2 is small */ + { + mp_limb_t prod[2]; + mp_limb_t uc2 = FLINT_ABS(c2); + + /* unsigned limb by limb multiply (assembly for most CPU's) */ + umul_ppmm(prod[1], prod[0], uc2, x); + if (c2 < WORD(0)) + fmpz_neg_uiui(f, prod[1], prod[0]); + else + fmpz_set_uiui(f, prod[1], prod[0]); + } + else /* c2 is large */ + { + /* Promote without val as if aliased both are large */ + __mpz_struct *mpz_ptr = _fmpz_promote(f); + flint_mpz_mul_ui(mpz_ptr, COEFF_TO_PTR(c2), x); + } +} diff --git a/external/flint-2.4.3/fmpz/multi_CRT_ui.c b/external/flint-2.4.3/fmpz/multi_CRT_ui.c new file mode 100644 index 0000000..85bbd6b --- /dev/null +++ b/external/flint-2.4.3/fmpz/multi_CRT_ui.c @@ -0,0 +1,152 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" +#include "nmod_vec.h" + + +void +__fmpz_multi_CRT_ui_sign(fmpz_t output, const fmpz_t input, + const fmpz_comb_t comb, fmpz_t temp) +{ + slong n = comb->n; + slong p; + + if (n == WORD(0)) + { + if (fmpz_is_zero(input)) + { + fmpz_zero(output); + return; + } + + /* XXX: overflow possible? */ + p = comb->primes[0]; + if ((p - (*input)) < (*input)) + fmpz_set_si(output, (slong) ((*input) - p)); + else + fmpz_set_ui(output, (*input)); + return; + } + + fmpz_sub(temp, input, comb->comb[comb->n - 1]); + + if (fmpz_cmpabs(temp, input) <= 0) + fmpz_set(output, temp); + else + fmpz_set(output, input); + + return; +} + +void fmpz_multi_CRT_ui(fmpz_t output, mp_srcptr residues, + const fmpz_comb_t comb, fmpz_comb_temp_t ctemp, int sign) +{ + slong i, j; + slong n = comb->n; + slong num; + slong log_res; + slong num_primes = comb->num_primes; + + fmpz ** comb_temp = ctemp->comb_temp; + fmpz * temp = ctemp->temp; + fmpz * temp2 = ctemp->temp2; + + /* The output is less than a single prime, so just output the result */ + if (num_primes == 1) + { + if (sign) + { + mp_limb_t p = comb->primes[0]; + + if ((p - residues[0]) < residues[0]) + fmpz_set_si(output, residues[0] - p); + else + fmpz_set_ui(output, residues[0]); + } + else + { + fmpz_set_ui(output, residues[0]); + } + return; + } + + /* First layer of reconstruction */ + num = (WORD(1) << n); + + for (i = 0, j = 0; i + 2 <= num_primes; i += 2, j++) + { + fmpz_set_ui(temp, residues[i]); + fmpz_mod_ui(temp2, temp, comb->primes[i+1]); + fmpz_sub_ui(temp2, temp2, residues[i + 1]); + fmpz_neg(temp2, temp2); + fmpz_mul(temp, temp2, comb->res[0] + j); + fmpz_mod_ui(temp2, temp, comb->primes[i+1]); + fmpz_mul_ui(temp, temp2, comb->primes[i]); + fmpz_add_ui(comb_temp[0] + j, temp, residues[i]); + } + + if (i < num_primes) + fmpz_set_ui(comb_temp[0] + j, residues[i]); + + /* Compute other layers of reconstruction */ + num /= 2; + log_res = 1; + + while (log_res < n) + { + for (i = 0, j = 0; i < num; i += 2, j++) + { + if (fmpz_is_one(comb->comb[log_res-1] + i + 1)) + { + if (!fmpz_is_one(comb->comb[log_res-1] + i)) + fmpz_set(comb_temp[log_res] + j, comb_temp[log_res-1] + i); + } + else + { + fmpz_mod(temp2, comb_temp[log_res-1] + i, + comb->comb[log_res-1] + i + 1); + fmpz_sub(temp, comb_temp[log_res-1] + i + 1, temp2); + fmpz_mul(temp2, temp, comb->res[log_res] + j); + fmpz_mod(temp, temp2, comb->comb[log_res-1] + i + 1); + fmpz_mul(temp2, temp, comb->comb[log_res-1] + i); + fmpz_add(comb_temp[log_res] + j, temp2, + comb_temp[log_res-1] + i); + } + } + log_res++; + num /= 2; + } + + /* Write out the output */ + if (sign) + __fmpz_multi_CRT_ui_sign(output, comb_temp[log_res - 1], comb, temp); + else + fmpz_set(output, comb_temp[log_res - 1]); +} diff --git a/external/flint-2.4.3/fmpz/multi_mod_ui.c b/external/flint-2.4.3/fmpz/multi_mod_ui.c new file mode 100644 index 0000000..bc760c8 --- /dev/null +++ b/external/flint-2.4.3/fmpz/multi_mod_ui.c @@ -0,0 +1,116 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" +#include "nmod_vec.h" + +void +fmpz_multi_mod_ui_basecase(mp_limb_t * out, const fmpz_t in, mp_srcptr primes, + slong num_primes) +{ + slong i; + for (i = 0; i < num_primes; i++) + { + out[i] = fmpz_fdiv_ui(in, primes[i]); + } +} + +void +fmpz_multi_mod_ui(mp_limb_t * out, const fmpz_t in, const fmpz_comb_t comb, + fmpz_comb_temp_t temp) +{ + slong i, j; + slong n = comb->n; + slong log_comb; + slong stride; + slong num; + slong num_primes = comb->num_primes; + fmpz ** comb_temp = temp->comb_temp; + + if (num_primes == 1) + { + out[0] = fmpz_fdiv_ui(in, comb->primes[0]); + return; + } + + log_comb = n - 1; + + /* Find level in comb with entries bigger than the input integer */ + log_comb = 0; + if (fmpz_sgn(in) < 0) + { + while ((fmpz_bits(in) >= fmpz_bits(comb->comb[log_comb]) - 1) + && (log_comb < comb->n - 1)) log_comb++; + } + else + { + while (fmpz_cmpabs(in, comb->comb[log_comb]) >= 0 && + (log_comb < comb->n - 1)) + log_comb++; + } + + num = (WORD(1) << (n - log_comb - 1)); + + /* Set each entry of this level of temp to the input integer */ + for (i = 0; i < num; i++) + { + fmpz_set(comb_temp[log_comb] + i, in); + } + + log_comb--; + num *= 2; + + /* Fill in other entries of temp by taking entries of temp + at higher level mod pairs from comb */ + + /* keep going until we reach the basecase */ + while (log_comb > FLINT_FMPZ_LOG_MULTI_MOD_CUTOFF) + { + for (i = 0, j = 0; i < num; i += 2, j++) + { + fmpz_mod(comb_temp[log_comb] + i, comb_temp[log_comb + 1] + j, + comb->comb[log_comb] + i); + fmpz_mod(comb_temp[log_comb] + i + 1, comb_temp[log_comb + 1] + j, + comb->comb[log_comb] + i + 1); + } + num *= 2; + log_comb--; + } + + /* Do basecase */ + num /= 2; + log_comb++; + + stride = (WORD(1) << (log_comb + 1)); + for (i = 0, j = 0; j < num_primes; i++, j += stride) + { + fmpz_multi_mod_ui_basecase(out + j, comb_temp[log_comb] + i, + comb->primes + j, FLINT_MIN(stride, num_primes - j)); + } +} diff --git a/external/flint-2.4.3/fmpz/or.c b/external/flint-2.4.3/fmpz/or.c new file mode 100644 index 0000000..6261581 --- /dev/null +++ b/external/flint-2.4.3/fmpz/or.c @@ -0,0 +1,68 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Thomas M. DuBuisson + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +void fmpz_or(fmpz_t f, const fmpz_t g, const fmpz_t h) +{ + fmpz c1,c2; + c1 = *g; + c2 = *h; + if(!COEFF_IS_MPZ(c1)) + { + if(!COEFF_IS_MPZ(c2)) /* both inputs are small */ + { + fmpz_set_si(f, c1 | c2); + } else /* g is small, h is large */ + { + mpz_t tmp; + __mpz_struct * mpz3 = _fmpz_promote(f); + flint_mpz_init_set_si(tmp,c1); + mpz_ior(mpz3, COEFF_TO_PTR(c2), tmp); + _fmpz_demote_val(f); + mpz_clear(tmp); + } + } else + { + if(!COEFF_IS_MPZ(c2)) /* g is large, h is small */ + { + mpz_t tmp; + __mpz_struct *mpz3 = _fmpz_promote(f); + flint_mpz_init_set_si(tmp,c2); + mpz_ior(mpz3, COEFF_TO_PTR(c1), tmp); + mpz_clear(tmp); + } else /* g and h are large */ + { + __mpz_struct * mpz3 = _fmpz_promote(f); + __mpz_struct * mpz1 = COEFF_TO_PTR(c1); + __mpz_struct * mpz2 = COEFF_TO_PTR(c2); + mpz_ior(mpz3, mpz1, mpz2); + } + } +} + diff --git a/external/flint-2.4.3/fmpz/out_raw.c b/external/flint-2.4.3/fmpz/out_raw.c new file mode 100644 index 0000000..b993db0 --- /dev/null +++ b/external/flint-2.4.3/fmpz/out_raw.c @@ -0,0 +1,42 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Qingwen GUAN + +******************************************************************************/ + + +#include "fmpz.h" + +size_t fmpz_out_raw( FILE *fout, const fmpz_t x ) +{ + mpz_t v; + size_t size; + + mpz_init( v ); + fmpz_get_mpz( v, x ); + size = mpz_out_raw( fout, v ); + mpz_clear( v ); + + return size; +} + + diff --git a/external/flint-2.4.3/fmpz/popcnt.c b/external/flint-2.4.3/fmpz/popcnt.c new file mode 100644 index 0000000..33ed445 --- /dev/null +++ b/external/flint-2.4.3/fmpz/popcnt.c @@ -0,0 +1,42 @@ +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +#ifdef POPCNT_INTRINSICS +static __inline__ mp_bitcnt_t shortCount(slong val) +{ +#if defined(_WIN64) + return __builtin_popcountll(val); +#else + return __builtin_popcountl(val); +#endif +} +#else +/* A naive implementation if neither your processor nor your compiler want to + * do the work. */ +static __inline__ mp_bitcnt_t shortCount(slong val) +{ + mp_bitcnt_t cnt; + for(cnt=0; val; val >>= 1) { + cnt += val & 1; + } + return cnt; +} +#endif + +mp_bitcnt_t fmpz_popcnt(const fmpz_t c) +{ + fmpz c1; + c1 = *c; + if(!COEFF_IS_MPZ(c1)) + { + if(*c < 0) return 0; + else return shortCount(*c); + } else + { + __mpz_struct *t = COEFF_TO_PTR(c1); + if(flint_mpz_cmp_si(t,0) < 0) return 0; + else return mpz_popcount(t); + } +} diff --git a/external/flint-2.4.3/fmpz/pow_ui.c b/external/flint-2.4.3/fmpz/pow_ui.c new file mode 100644 index 0000000..dc81acc --- /dev/null +++ b/external/flint-2.4.3/fmpz/pow_ui.c @@ -0,0 +1,70 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +void +fmpz_pow_ui(fmpz_t f, const fmpz_t g, ulong exp) +{ + fmpz c1; + + if (exp == WORD(0)) + { + fmpz_one(f); + return; + } + + c1 = *g; + + if (!COEFF_IS_MPZ(c1)) /* g is small */ + { + ulong u1 = FLINT_ABS(c1); + ulong bits = FLINT_BIT_COUNT(u1); + if ((bits <= 1) || (exp * bits <= FLINT_BITS - 2)) + { + fmpz_set_ui(f, n_pow(u1, exp)); + } + else + { + __mpz_struct *mpz_ptr = _fmpz_promote_val(f); + + flint_mpz_set_ui(mpz_ptr, u1); + flint_mpz_pow_ui(mpz_ptr, mpz_ptr, exp); + _fmpz_demote_val(f); /* may actually fit into a small after all */ + } + + if ((c1 < WORD(0)) && (exp & 1)) /* sign is -ve if exp odd and g -ve */ + fmpz_neg(f, f); + } + else + { + __mpz_struct *mpz_ptr = _fmpz_promote_val(f); + flint_mpz_pow_ui(mpz_ptr, COEFF_TO_PTR(c1), exp); + /* no need to demote as it can't get smaller */ + } +} diff --git a/external/flint-2.4.3/fmpz/powm.c b/external/flint-2.4.3/fmpz/powm.c new file mode 100644 index 0000000..ecabb12 --- /dev/null +++ b/external/flint-2.4.3/fmpz/powm.c @@ -0,0 +1,87 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "ulong_extras.h" + +void fmpz_powm(fmpz_t f, const fmpz_t g, const fmpz_t e, const fmpz_t m) +{ + if (fmpz_sgn(m) <= 0) + { + flint_printf("Exception (fmpz_powm). Modulus is less than 1.\n"); + abort(); + } + else if (!COEFF_IS_MPZ(*e)) /* e is small */ + { + fmpz_powm_ui(f, g, *e, m); + } + else /* e is large */ + { + if (!COEFF_IS_MPZ(*m)) /* m is small */ + { + ulong g1 = fmpz_fdiv_ui(g, *m); + mpz_t g2, m2; + __mpz_struct *mpz_ptr; + + flint_mpz_init_set_ui(g2, g1); + flint_mpz_init_set_ui(m2, *m); + mpz_ptr = _fmpz_promote(f); + + mpz_powm(mpz_ptr, g2, COEFF_TO_PTR(*e), m2); + + mpz_clear(g2); + mpz_clear(m2); + _fmpz_demote_val(f); + } + else /* m is large */ + { + if (!COEFF_IS_MPZ(*g)) /* g is small */ + { + mpz_t g2; + __mpz_struct *mpz_ptr; + + flint_mpz_init_set_si(g2, *g); + mpz_ptr = _fmpz_promote(f); + + mpz_powm(mpz_ptr, g2, COEFF_TO_PTR(*e), COEFF_TO_PTR(*m)); + + mpz_clear(g2); + _fmpz_demote_val(f); + } + else /* g is large */ + { + __mpz_struct *mpz_ptr = _fmpz_promote(f); + + mpz_powm(mpz_ptr, + COEFF_TO_PTR(*g), COEFF_TO_PTR(*e), COEFF_TO_PTR(*m)); + _fmpz_demote_val(f); + } + } + } +} + diff --git a/external/flint-2.4.3/fmpz/powm_ui.c b/external/flint-2.4.3/fmpz/powm_ui.c new file mode 100644 index 0000000..5db2f9f --- /dev/null +++ b/external/flint-2.4.3/fmpz/powm_ui.c @@ -0,0 +1,111 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "ulong_extras.h" + +void fmpz_powm_ui(fmpz_t f, const fmpz_t g, ulong e, const fmpz_t m) +{ + if (fmpz_sgn(m) <= 0) + { + flint_printf("Exception (fmpz_powm_ui). Modulus is less than 1.\n"); + abort(); + } + + if (fmpz_is_one(m)) + { + fmpz_zero(f); + } + else if (e == 0) + { + fmpz_one(f); + } + else /* e != 0, m > 0 */ + { + fmpz g2 = *g; + fmpz m2 = *m; + + if (!COEFF_IS_MPZ(m2)) /* m is small */ + { + if (!COEFF_IS_MPZ(g2)) /* g is small */ + { + mp_limb_t minv = n_preinvert_limb(m2); + + _fmpz_demote(f); + + if (g2 >= 0) + { + g2 = n_mod2_preinv(g2, m2, minv); + *f = n_powmod2_ui_preinv(g2, e, m2, minv); + } + else + { + g2 = n_mod2_preinv(-g2, m2, minv); + *f = n_powmod2_ui_preinv(g2, e, m2, minv); + if ((e & UWORD(1))) + *f = n_negmod(*f, m2); + } + } + else /* g is large */ + { + __mpz_struct *ptr = _fmpz_promote(f); + mpz_t m3; + + flint_mpz_init_set_ui(m3, m2); + flint_mpz_powm_ui(ptr, COEFF_TO_PTR(g2), e, m3); + mpz_clear(m3); + + _fmpz_demote_val(f); + } + } + else /* m is large */ + { + if (!COEFF_IS_MPZ(g2)) /* g is small */ + { + __mpz_struct *ptr = _fmpz_promote(f); + mpz_t g3; + + flint_mpz_init_set_si(g3, g2); + flint_mpz_powm_ui(ptr, g3, e, COEFF_TO_PTR(m2)); + mpz_clear(g3); + + _fmpz_demote_val(f); + } + else /* g is large */ + { + __mpz_struct *ptr = _fmpz_promote(f); + + flint_mpz_powm_ui(ptr, COEFF_TO_PTR(g2), e, COEFF_TO_PTR(m2)); + + _fmpz_demote_val(f); + } + } + } +} + diff --git a/external/flint-2.4.3/fmpz/preinvn_clear.c b/external/flint-2.4.3/fmpz/preinvn_clear.c new file mode 100644 index 0000000..558df3f --- /dev/null +++ b/external/flint-2.4.3/fmpz/preinvn_clear.c @@ -0,0 +1,34 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +void fmpz_preinvn_clear(fmpz_preinvn_t inv) +{ + flint_free(inv->dinv); +} diff --git a/external/flint-2.4.3/fmpz/preinvn_init.c b/external/flint-2.4.3/fmpz/preinvn_init.c new file mode 100644 index 0000000..f617e18 --- /dev/null +++ b/external/flint-2.4.3/fmpz/preinvn_init.c @@ -0,0 +1,70 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "mpn_extras.h" +#include "fmpz.h" + +void fmpz_preinvn_init(fmpz_preinvn_t inv, fmpz_t f) +{ + fmpz c = *f; + mp_bitcnt_t norm; + mp_ptr t; + + if (c == 0) + { + flint_printf("Exception (fmpz_preinvn_init). Division by zero.\n"); + abort(); + } else if (!COEFF_IS_MPZ(c)) /* c is small */ + { + inv->dinv = flint_malloc(sizeof(mp_limb_t)); + if (c < 0) c = -c; + count_leading_zeros(norm, c); + if (norm) c <<= norm; + flint_mpn_preinvn(inv->dinv, (mp_ptr) &c, 1); + inv->n = 1; + } else /* c is big */ + { + __mpz_struct * mpz_ptr = COEFF_TO_PTR(c); + slong size = FLINT_ABS(mpz_ptr->_mp_size); + inv->dinv = flint_malloc(size*sizeof(mp_limb_t)); + count_leading_zeros(norm, mpz_ptr->_mp_d[size - 1]); + if (norm) + { + t = flint_malloc(size*sizeof(mp_limb_t)); + mpn_lshift(t, mpz_ptr->_mp_d, size, norm); + } else + t = mpz_ptr->_mp_d; + + flint_mpn_preinvn(inv->dinv, t, size); + + inv->n = size; + if (norm) flint_free(t); + } + + inv->norm = norm; +} diff --git a/external/flint-2.4.3/fmpz/print.c b/external/flint-2.4.3/fmpz/print.c new file mode 100644 index 0000000..be33d80 --- /dev/null +++ b/external/flint-2.4.3/fmpz/print.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include + +#include "fmpz.h" + +int fmpz_print(const fmpz_t x) +{ + if (!COEFF_IS_MPZ(*x)) + return flint_printf("%wd", *x); + else + return (int) mpz_out_str(stdout, 10, COEFF_TO_PTR(*x)); +} + diff --git a/external/flint-2.4.3/fmpz/profile/p-fdiv_qr_preinvn.c b/external/flint-2.4.3/fmpz/profile/p-fdiv_qr_preinvn.c new file mode 100644 index 0000000..4e0383e --- /dev/null +++ b/external/flint-2.4.3/fmpz/profile/p-fdiv_qr_preinvn.c @@ -0,0 +1,126 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "profiler.h" +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +typedef struct +{ + slong limbs; + int algo; +} info_t; + +void sample(void * arg, ulong count) +{ + info_t * info = (info_t *) arg; + slong limbs = info->limbs, i, j; + int algo = info->algo; + int scale = 200; + + FLINT_TEST_INIT(state); + + + fmpz_t a, b, c, r; + fmpz_preinvn_t inv; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + fmpz_init(r); + + for (i = 0; i < count; i++) + { + fmpz_randbits(a, state, (2*limbs - 1)*FLINT_BITS); + fmpz_randbits(b, state, limbs*FLINT_BITS); + + fmpz_preinvn_init(inv, b); + + prof_start(); + if (algo == 1) + { + for (j = 0; j < scale; j++) + { + fmpz_fdiv_qr_preinvn(c, r, a, b, inv); + } + } else + { + for (j = 0; j < scale; j++) + { + fmpz_fdiv_qr(c, r, a, b); + } + } + prof_stop(); + } + + fmpz_preinvn_clear(inv); + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + fmpz_clear(r); + flint_randclear(state); +} + +int main(void) +{ + double min, max; + info_t info; + slong k, scale; + + printf("1: With precomputed inverse\n"); + printf("2: Without precomputed inverse\n\n"); + + for (k = 1; k <= 10000; k = (slong) ceil(1.1*k)) + { + info.limbs = k; + info.algo = 1; + + scale = 200; + + prof_repeat(&min, &max, sample, (void *) &info); + + flint_printf("1: limbs %wd, min %.3g ms, max %.3g ms\n", + info.limbs, + ((min/(double)FLINT_CLOCK_SCALE_FACTOR)/scale)/2400000.0, + ((max/(double)FLINT_CLOCK_SCALE_FACTOR)/scale)/2400000.0 + ); + + info.algo = 2; + + prof_repeat(&min, &max, sample, (void *) &info); + + flint_printf("2: limbs %wd, min %.3g ms, max %.3g ms\n\n", + info.limbs, + ((min/(double)FLINT_CLOCK_SCALE_FACTOR)/scale)/2400000.0, + ((max/(double)FLINT_CLOCK_SCALE_FACTOR)/scale)/2400000.0 + ); + } + + return 0; +} diff --git a/external/flint-2.4.3/fmpz/randbits.c b/external/flint-2.4.3/fmpz/randbits.c new file mode 100644 index 0000000..f629659 --- /dev/null +++ b/external/flint-2.4.3/fmpz/randbits.c @@ -0,0 +1,55 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +void +fmpz_randbits(fmpz_t f, flint_rand_t state, mp_bitcnt_t bits) +{ + if (bits <= FLINT_BITS - 2) + { + _fmpz_demote(f); + *f = n_randbits(state, bits); + if (n_randint(state, 2)) + *f = -*f; + } + else + { + __mpz_struct *mpz_ptr = _fmpz_promote(f); + _flint_rand_init_gmp(state); + mpz_urandomb(mpz_ptr, state->gmp_state, bits); + + if (n_randint(state, 2)) + mpz_neg(mpz_ptr, mpz_ptr); + + _fmpz_demote_val(f); + } +} diff --git a/external/flint-2.4.3/fmpz/randm.c b/external/flint-2.4.3/fmpz/randm.c new file mode 100644 index 0000000..a490eb9 --- /dev/null +++ b/external/flint-2.4.3/fmpz/randm.c @@ -0,0 +1,55 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +void +fmpz_randm(fmpz_t f, flint_rand_t state, const fmpz_t m) +{ + mp_bitcnt_t bits = fmpz_bits(m); + int sgn = fmpz_sgn(m); + + if (bits <= FLINT_BITS - 2) + { + _fmpz_demote(f); + *f = (sgn >= 0) ? n_randint(state, *m) : - n_randint(state, -(*m)); + } + else + { + __mpz_struct *mpz_ptr = _fmpz_promote(f); + + _flint_rand_init_gmp(state); + mpz_urandomm(mpz_ptr, state->gmp_state, COEFF_TO_PTR(*m)); + if (sgn < 0) + mpz_neg(mpz_ptr, mpz_ptr); + _fmpz_demote_val(f); + } +} diff --git a/external/flint-2.4.3/fmpz/randtest.c b/external/flint-2.4.3/fmpz/randtest.c new file mode 100644 index 0000000..6722b37 --- /dev/null +++ b/external/flint-2.4.3/fmpz/randtest.c @@ -0,0 +1,93 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include + +#include "flint.h" +#include "fmpz.h" +#include "ulong_extras.h" + +void +fmpz_randtest(fmpz_t f, flint_rand_t state, mp_bitcnt_t bits) +{ + ulong m; + + fmpz_randtest_unsigned(f, state, bits); + + m = n_randlimb(state); + if (m & UWORD(1)) + fmpz_neg(f, f); +} + +void +fmpz_randtest_unsigned(fmpz_t f, flint_rand_t state, mp_bitcnt_t bits) +{ + ulong m; + + m = n_randlimb(state); + bits = n_randint(state, bits + 1); + + if (bits <= FLINT_BITS - 2) + { + _fmpz_demote(f); + if (m & UWORD(3)) + *f = n_randtest_bits(state, bits); + else + { + m >>= 2; + if (bits == 0) + *f = 0; + else if (bits < FLINT_BITS - 2) + *f = m & UWORD(1); + else + *f = COEFF_MAX; + } + } + else + { + __mpz_struct *mpz_ptr = _fmpz_promote(f); + + _flint_rand_init_gmp(state); + mpz_rrandomb(mpz_ptr, state->gmp_state, bits); + _fmpz_demote_val(f); + } +} + +void +fmpz_randtest_not_zero(fmpz_t f, flint_rand_t state, mp_bitcnt_t bits) +{ + if (bits == 0) + { + flint_printf("Exception (fmpz_randtest_not_zero). bits == 0.\n"); + abort(); + } + + fmpz_randtest(f, state, bits); + if (fmpz_is_zero(f)) + fmpz_one(f); +} diff --git a/external/flint-2.4.3/fmpz/randtest_mod.c b/external/flint-2.4.3/fmpz/randtest_mod.c new file mode 100644 index 0000000..b9896de --- /dev/null +++ b/external/flint-2.4.3/fmpz/randtest_mod.c @@ -0,0 +1,73 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "ulong_extras.h" + +void +fmpz_randtest_mod(fmpz_t f, flint_rand_t state, const fmpz_t m) +{ + fmpz_t t; + + fmpz_init(t); + fmpz_randtest_unsigned(t, state, fmpz_bits(m) + 2); + fmpz_mod(t, t, m); + + if (n_randlimb(state) & UWORD(1)) + { + fmpz_sub(t, m, t); + fmpz_sub_ui(t, t, UWORD(1)); + } + + fmpz_set(f, t); + fmpz_clear(t); +} + +void +fmpz_randtest_mod_signed(fmpz_t f, flint_rand_t state, const fmpz_t m) +{ + /* Randomly generate m/2 when included in the range */ + if ((n_randlimb(state) % 32 == 1) && (fmpz_fdiv_ui(m, 2) == 0)) + { + fmpz_fdiv_q_ui(f, m, UWORD(2)); + } + else + { + fmpz_t t; + fmpz_init(t); + fmpz_tdiv_q_ui(t, m, UWORD(2)); + fmpz_randtest_mod(t, state, t); + if (n_randlimb(state) & UWORD(1)) + { + fmpz_neg(t, t); + } + fmpz_set(f, t); + fmpz_clear(t); + } +} diff --git a/external/flint-2.4.3/fmpz/read.c b/external/flint-2.4.3/fmpz/read.c new file mode 100644 index 0000000..08fcf4b --- /dev/null +++ b/external/flint-2.4.3/fmpz/read.c @@ -0,0 +1,44 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" + +int +fmpz_read(fmpz_t f) +{ + mpz_t t; + size_t r; + + mpz_init(t); + r = mpz_inp_str(t, stdin, 10); + fmpz_set_mpz(f, t); + mpz_clear(t); + + return (r > 0) ? 1 : 0; +} diff --git a/external/flint-2.4.3/fmpz/remove.c b/external/flint-2.4.3/fmpz/remove.c new file mode 100644 index 0000000..1be108e --- /dev/null +++ b/external/flint-2.4.3/fmpz/remove.c @@ -0,0 +1,144 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "ulong_extras.h" + +slong _fmpz_remove(fmpz_t x, const fmpz_t f, double finv) +{ + fmpz y = *x; + fmpz q = *f; + + if (!COEFF_IS_MPZ(y)) /* x is small */ + { + if (!COEFF_IS_MPZ(q)) /* f is small */ + { + if (y > 0) + { + return n_remove2_precomp((mp_limb_t *) x, q, finv); + } + else + { + ulong z = - (ulong) y; + slong e = n_remove2_precomp(&z, q, finv); + + if (e > 0) + { + *x = - (slong) z; + } + return e; + } + } + else /* f is large */ + { + return 0; + } + } + else /* x is large */ + { + __mpz_struct *z = COEFF_TO_PTR(y); + + if (!COEFF_IS_MPZ(q)) /* f is small */ + { + if (!flint_mpz_divisible_ui_p(z, q)) + { + return 0; + } + else + { + flint_mpz_divexact_ui(z, z, q); + + if (!flint_mpz_divisible_ui_p(z, q)) + { + _fmpz_demote_val(x); + return 1; + } + else + { + mpz_t r; + slong e; + + flint_mpz_divexact_ui(z, z, q); + flint_mpz_init_set_ui(r, q); + e = 2 + mpz_remove(z, z, r); + mpz_clear(r); + _fmpz_demote_val(x); + + return e; + } + } + } + else /* f is large */ + { + __mpz_struct *r = COEFF_TO_PTR(q); + + if (!mpz_divisible_p(z, r)) + { + return 0; + } + else + { + slong e; + + mpz_divexact(z, z, r); + e = 1 + mpz_remove(z, z, r); + _fmpz_demote_val(x); + return e; + } + } + } +} + +slong fmpz_remove(fmpz_t rop, const fmpz_t op, const fmpz_t f) +{ + double finv; + + if ((fmpz_sgn(f) <= 0) || fmpz_is_one(f)) + { + flint_printf("Exception (fmpz_remove). factor f <= 1.\n"); + abort(); + } + + if (rop == f) + { + slong ans; + fmpz_t t; + + fmpz_init(t); + ans = fmpz_remove(t, op, f); + fmpz_swap(rop, t); + fmpz_clear(t); + + return ans; + } + + finv = (!COEFF_IS_MPZ((*f))) ? n_precompute_inverse(*f) : 0; + + fmpz_set(rop, op); + return _fmpz_remove(rop, f, finv); +} + diff --git a/external/flint-2.4.3/fmpz/rfac_ui.c b/external/flint-2.4.3/fmpz/rfac_ui.c new file mode 100644 index 0000000..94b9bf3 --- /dev/null +++ b/external/flint-2.4.3/fmpz/rfac_ui.c @@ -0,0 +1,134 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +static __inline__ ulong rfac(ulong x, ulong b) +{ + ulong i, c = x; + + for (i = 1; i < b; i++) + c *= x + i; + + return c; +} + +/* Assumes x positive, b > a. b must also be small enough to +avoid integer overflow, which is no problem if the result +is to fit in memory. */ +void +_fmpz_rfac_ui(fmpz_t r, const fmpz_t x, ulong a, ulong b) +{ + if (b - a == 1) + { + fmpz_add_ui(r, x, a); + } + else if ((*x <= COEFF_MAX) && (b - a < 60)) + { + ulong step, bits, factors_per_limb; + ulong y = *x; + + /* Bound size of largest factor */ + bits = FLINT_BIT_COUNT(y + a + b - 1); + + /* The result fits in a single limb */ + if ((b - a) * bits < FLINT_BITS) + step = factors_per_limb = b - a; + else + { + factors_per_limb = FLINT_BITS / bits; + step = FLINT_MIN(b - a, factors_per_limb); + } + + fmpz_set_ui(r, rfac(y + a, step)); + a += step; + + while (a < b) + { + step = FLINT_MIN(b - a, factors_per_limb); + fmpz_mul_ui(r, r, rfac(y + a, step)); + a += step; + } + } + else + { + fmpz_t t, u; + ulong m = (a + b) / 2; + + fmpz_init(t); + fmpz_init(u); + + _fmpz_rfac_ui(t, x, a, m); + _fmpz_rfac_ui(u, x, m, b); + fmpz_mul(r, t, u); + + fmpz_clear(t); + fmpz_clear(u); + } +} + +void +fmpz_rfac_ui(fmpz_t r, const fmpz_t x, ulong n) +{ + if (n == 0) + { + fmpz_one(r); + } + else if (n == 1) + { + fmpz_set(r, x); + } + else if (fmpz_is_zero(x)) + { + fmpz_zero(r); + } + else if (fmpz_sgn(x) < 0) + { + fmpz_t t; + fmpz_init(t); + fmpz_add_ui(t, x, n - 1); + if (fmpz_sgn(t) >= 0) + { + fmpz_zero(r); + } + else + { + fmpz_neg(t, t); + fmpz_rfac_ui(r, t, n); + if (n % 2 == 1) + fmpz_neg(r, r); + } + fmpz_clear(t); + } + else + { + _fmpz_rfac_ui(r, x, 0, n); + } +} diff --git a/external/flint-2.4.3/fmpz/rfac_uiui.c b/external/flint-2.4.3/fmpz/rfac_uiui.c new file mode 100644 index 0000000..13f160a --- /dev/null +++ b/external/flint-2.4.3/fmpz/rfac_uiui.c @@ -0,0 +1,59 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +void +fmpz_rfac_uiui(fmpz_t r, ulong x, ulong n) +{ + if (n == 0) + { + fmpz_one(r); + } + else if (n == 1) + { + fmpz_set_ui(r, x); + } + else if (x == 0) + { + fmpz_zero(r); + } + else if (x <= COEFF_MAX) + { + _fmpz_rfac_ui(r, (fmpz *) &x, 0, n); + } + else + { + fmpz_t tmp; + fmpz_init_set_ui(tmp, x); + fmpz_rfac_ui(r, tmp, n); + fmpz_clear(tmp); + } +} diff --git a/external/flint-2.4.3/fmpz/root.c b/external/flint-2.4.3/fmpz/root.c new file mode 100644 index 0000000..2ed0f1a --- /dev/null +++ b/external/flint-2.4.3/fmpz/root.c @@ -0,0 +1,97 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 William Hart + +******************************************************************************/ + +#define ulong ulongxx /* interferes with system includes */ +#include +#undef ulong +#define ulong mp_limb_t + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +void +fmpz_root(fmpz_t r, const fmpz_t f, slong n) +{ + fmpz c = *f; + + if (n == 0) + { + flint_printf("Exception (fmpz_root). Unable to take 0-th root.\n"); + abort(); + } + + if (n == 1) + { + fmpz_set(r, f); + return; + } + + if (!COEFF_IS_MPZ(c)) /* f is small */ + { + if (n == 2) + { + if (c < WORD(0)) + { + flint_printf("Exception (fmpz_root). Unable to take square root of negative value.\n"); + abort(); + } + + fmpz_set_ui(r, n_sqrt(c)); + } else /* n > 2 */ + { + __mpz_struct mpz2; + __mpz_struct * mpz1; + mp_limb_t cval; + + if (c == 0) + { + fmpz_set_ui(r, 0); + return; + } + + mpz1 = _fmpz_promote(r); + + cval = FLINT_ABS(c); + mpz2._mp_d = &cval; /* mock up an mpz */ + mpz2._mp_size = 1; + if (c < WORD(0)) + mpz2._mp_size = -1; + mpz2._mp_alloc = 1; + + mpz_root(mpz1, &mpz2, n); + + _fmpz_demote_val(r); /* root may be small */ + } + } else /* f is large */ + { + __mpz_struct * mpz2 = COEFF_TO_PTR(c); + __mpz_struct * mpz1 = _fmpz_promote(r); + + mpz_root(mpz1, mpz2, n); + _fmpz_demote_val(r); /* root may be small */ + } +} diff --git a/external/flint-2.4.3/fmpz/set.c b/external/flint-2.4.3/fmpz/set.c new file mode 100644 index 0000000..03b069f --- /dev/null +++ b/external/flint-2.4.3/fmpz/set.c @@ -0,0 +1,47 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +void +fmpz_set(fmpz_t f, const fmpz_t g) +{ + if (f == g) + return; /* aliased inputs */ + + if (!COEFF_IS_MPZ(*g)) /* g is small */ + { + _fmpz_demote(f); + *f = *g; + } + else /* g is large */ + { + __mpz_struct *mpz_ptr = _fmpz_promote(f); + mpz_set(mpz_ptr, COEFF_TO_PTR(*g)); + } +} diff --git a/external/flint-2.4.3/fmpz/set_d.c b/external/flint-2.4.3/fmpz/set_d.c new file mode 100644 index 0000000..772fc10 --- /dev/null +++ b/external/flint-2.4.3/fmpz/set_d.c @@ -0,0 +1,54 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +#if FLINT64 /* 2^53 */ +#define DOUBLE_MAX 9007199254740992.0 +#define DOUBLE_MIN -9007199254740992.0 +#else +#define DOUBLE_MAX COEFF_MAX +#define DOUBLE_MIN COEFF_MIN +#endif + +void +fmpz_set_d(fmpz_t f, double c) +{ + if (c >= DOUBLE_MIN && c <= DOUBLE_MAX) + { + _fmpz_demote(f); + /* guaranteed to fit, since c gets truncated */ + *f = (slong) c; + } + else + { + __mpz_struct * z = _fmpz_promote(f); + mpz_set_d(z, c); + _fmpz_demote_val(f); + } +} diff --git a/external/flint-2.4.3/fmpz/set_mpz.c b/external/flint-2.4.3/fmpz/set_mpz.c new file mode 100644 index 0000000..b148012 --- /dev/null +++ b/external/flint-2.4.3/fmpz/set_mpz.c @@ -0,0 +1,64 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +void +fmpz_set_mpz(fmpz_t f, const mpz_t x) +{ + slong size = (slong) x->_mp_size; + + if (size == WORD(0)) /* x is zero */ + { + fmpz_zero(f); + } + else if (size == WORD(1)) /* x is positive and 1 limb */ + { + fmpz_set_ui(f, flint_mpz_get_ui(x)); + } + else if (size == WORD(-1)) /* x is negative and 1 limb */ + { + ulong uval = flint_mpz_get_ui(x); + if (uval <= COEFF_MAX) /* x is small */ + { + _fmpz_demote(f); + *f = -uval; + } + else /* x is large but one limb */ + { + __mpz_struct *mpz_ptr = _fmpz_promote(f); + flint_mpz_set_ui(mpz_ptr, uval); + mpz_neg(mpz_ptr, mpz_ptr); + } + } + else /* x is more than one limb */ + { + __mpz_struct *mpz_ptr = _fmpz_promote(f); + mpz_set(mpz_ptr, x); + } +} diff --git a/external/flint-2.4.3/fmpz/set_str.c b/external/flint-2.4.3/fmpz/set_str.c new file mode 100644 index 0000000..183c6db --- /dev/null +++ b/external/flint-2.4.3/fmpz/set_str.c @@ -0,0 +1,42 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int fmpz_set_str(fmpz_t f, const char * str, int b) +{ + int ans; + mpz_t copy; + + ans = mpz_init_set_str(copy, (char *) str, b); + if (ans == 0) + fmpz_set_mpz(f, copy); + mpz_clear(copy); + return ans; +} + diff --git a/external/flint-2.4.3/fmpz/setbit.c b/external/flint-2.4.3/fmpz/setbit.c new file mode 100644 index 0000000..eee5e1c --- /dev/null +++ b/external/flint-2.4.3/fmpz/setbit.c @@ -0,0 +1,53 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz.h" + +void fmpz_setbit(fmpz_t f, ulong i) +{ + if (!COEFF_IS_MPZ(*f)) + { + if (i < FLINT_BITS - 2) + { + *f |= (WORD(1) << i); + } + else /* i >= FLINT_BITS - 2 */ + { + __mpz_struct *ptr = _fmpz_promote_val(f); + + mpz_setbit(ptr, i); + _fmpz_demote_val(f); + } + } + else + { + __mpz_struct *ptr = COEFF_TO_PTR(*f); + + mpz_setbit(ptr, i); + + _fmpz_demote_val(f); + } +} + diff --git a/external/flint-2.4.3/fmpz/sgn.c b/external/flint-2.4.3/fmpz/sgn.c new file mode 100644 index 0000000..f27c4d9 --- /dev/null +++ b/external/flint-2.4.3/fmpz/sgn.c @@ -0,0 +1,42 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +fmpz_sgn(const fmpz_t f) +{ + fmpz d = *f; + + if (d == 0) + return 0; + if (!COEFF_IS_MPZ(d)) /* c1 is small */ + return (d > WORD(0) ? 1 : -1); + else + return mpz_sgn(COEFF_TO_PTR(d)); +} diff --git a/external/flint-2.4.3/fmpz/size.c b/external/flint-2.4.3/fmpz/size.c new file mode 100644 index 0000000..65fe1d3 --- /dev/null +++ b/external/flint-2.4.3/fmpz/size.c @@ -0,0 +1,42 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +mp_size_t +fmpz_size(const fmpz_t f) +{ + fmpz d = *f; + + if (d == 0) + return 0; + if (!COEFF_IS_MPZ(d)) + return 1; + else + return mpz_size(COEFF_TO_PTR(d)); +} diff --git a/external/flint-2.4.3/fmpz/sizeinbase.c b/external/flint-2.4.3/fmpz/sizeinbase.c new file mode 100644 index 0000000..fbf4b48 --- /dev/null +++ b/external/flint-2.4.3/fmpz/sizeinbase.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "long_extras.h" + +size_t fmpz_sizeinbase(const fmpz_t f, int b) +{ + fmpz d = *f; + + if (!COEFF_IS_MPZ(d)) + return z_sizeinbase(d, b); + else + return mpz_sizeinbase(COEFF_TO_PTR(d), b); +} + diff --git a/external/flint-2.4.3/fmpz/sqrt.c b/external/flint-2.4.3/fmpz/sqrt.c new file mode 100644 index 0000000..2c4b7bc --- /dev/null +++ b/external/flint-2.4.3/fmpz/sqrt.c @@ -0,0 +1,49 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +void fmpz_sqrt(fmpz_t f, const fmpz_t g) +{ + if (fmpz_sgn(g) < 0) + { + flint_printf("Exception (fmpz_sqrt). g is negative.\n"); + abort(); + } + + if (!COEFF_IS_MPZ(*g)) + fmpz_set_ui(f, n_sqrt(*g)); + else + { + __mpz_struct * mpz_ptr = _fmpz_promote(f); + mpz_sqrt(mpz_ptr, COEFF_TO_PTR(*g)); + _fmpz_demote_val(f); + } +} diff --git a/external/flint-2.4.3/fmpz/sqrtmod.c b/external/flint-2.4.3/fmpz/sqrtmod.c new file mode 100644 index 0000000..3b54f5d --- /dev/null +++ b/external/flint-2.4.3/fmpz/sqrtmod.c @@ -0,0 +1,173 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "ulong_extras.h" + +/* + Assumes that p is an odd prime, and that 0 <= a < p. + Returns 1 if a is a quadratic residue and 0 otherwise. + Does not support aliasing. + */ +static int _fmpz_sqrtmod(mpz_t rop, const mpz_t a, const mpz_t p) +{ + slong i, r, m; + mpz_t p1, k, exp, b, g, bpow, gpow; + + if (mpz_jacobi(a, p) == -1) + return 0; + + if (flint_mpz_congruent_ui_p(p, 3, 4)) + { + mpz_init(exp); + flint_mpz_add_ui(exp, p, 1); + mpz_tdiv_q_2exp(exp, exp, 2); + mpz_powm(rop, a, exp, p); + mpz_clear(exp); + + return 1; + } + + mpz_init(p1); + mpz_init(k); + mpz_init(exp); + mpz_init(b); + mpz_init(g); + mpz_init(bpow); + mpz_init(gpow); + + r = 0; + flint_mpz_sub_ui(p1, p, 1); + do { + mpz_tdiv_q_2exp(p1, p1, 1); + r++; + } while (mpz_even_p(p1)); + + mpz_powm(b, a, p1, p); + + for (flint_mpz_set_ui(k, 2); ; flint_mpz_add_ui(k, k, 1)) + { + if (mpz_jacobi(k, p) == -1) break; + } + + mpz_powm(g, k, p1, p); + + flint_mpz_add_ui(exp, p1, 1); + mpz_tdiv_q_2exp(exp, exp, 1); + mpz_powm(rop, a, exp, p); + + while (flint_mpz_cmp_ui(b, 1)) + { + mpz_set(bpow, b); + m = 0; + do + { + mpz_mul(bpow, bpow, bpow); + mpz_mod(bpow, bpow, p); + m++; + } while (m < r && flint_mpz_cmp_ui(bpow, 1)); + + mpz_set(gpow, g); + for (i = 1; i < r - m; i++) + { + mpz_mul(gpow, gpow, gpow); + mpz_mod(gpow, gpow, p); + } + + mpz_mul(rop, rop, gpow); + mpz_mod(rop, rop, p); + + mpz_mul(g, gpow, gpow); + mpz_mod(g, g, p); + + mpz_mul(b, b, g); + mpz_mod(b, b, p); + + r = m; + } + + mpz_clear(p1); + mpz_clear(k); + mpz_clear(exp); + mpz_clear(b); + mpz_clear(g); + mpz_clear(bpow); + mpz_clear(gpow); + + return mpz_sgn(rop) ? 1 : 0; +} + +int fmpz_sqrtmod(fmpz_t b, const fmpz_t a, const fmpz_t p) +{ + if (b == a || b == p) + { + int ans; + fmpz_t t; + + fmpz_init(t); + ans = fmpz_sqrtmod(t, a, p); + fmpz_swap(b, t); + fmpz_clear(t); + return ans; + } + + fmpz_mod(b, a, p); + + if (fmpz_cmp_ui(b, 1) <= 0) + { + return 1; + } + + if (!COEFF_IS_MPZ(*p)) /* p, and b are small */ + { + mp_limb_t ans; + + ans = n_sqrtmod(*b, *p); + if (ans) + fmpz_set_ui(b, ans); + return ans != 0; + } + else /* p is large */ + { + int ans; + mpz_t t; + __mpz_struct *bptr; + + bptr = _fmpz_promote_val(b); + + mpz_init(t); + ans = _fmpz_sqrtmod(t, bptr, COEFF_TO_PTR(*p)); + mpz_swap(bptr, t); + mpz_clear(t); + + _fmpz_demote_val(b); + + return ans; + } +} + diff --git a/external/flint-2.4.3/fmpz/sqrtrem.c b/external/flint-2.4.3/fmpz/sqrtrem.c new file mode 100644 index 0000000..09ab18e --- /dev/null +++ b/external/flint-2.4.3/fmpz/sqrtrem.c @@ -0,0 +1,58 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +void fmpz_sqrtrem(fmpz_t f, fmpz_t r, const fmpz_t g) +{ + if (fmpz_sgn(g) < 0) + { + flint_printf("Exception (fmpz_sqrtrem). g is negative.\n"); + abort(); + } + + if (!COEFF_IS_MPZ(*g)) + { + if (COEFF_IS_MPZ(*r)) + _fmpz_clear_mpz(*r); + fmpz_set_ui(f, n_sqrtrem((mp_limb_t *) r, *g)); + } + else + { + __mpz_struct * r_mpz_ptr, * f_mpz_ptr; + _fmpz_promote(f); /* must not hang on to pointer whilst promoting */ + r_mpz_ptr = _fmpz_promote(r); + f_mpz_ptr = COEFF_TO_PTR(*f); + + mpz_sqrtrem(f_mpz_ptr, r_mpz_ptr, COEFF_TO_PTR(*g)); + _fmpz_demote_val(f); + _fmpz_demote_val(r); + } +} diff --git a/external/flint-2.4.3/fmpz/sub.c b/external/flint-2.4.3/fmpz/sub.c new file mode 100644 index 0000000..99aaf72 --- /dev/null +++ b/external/flint-2.4.3/fmpz/sub.c @@ -0,0 +1,78 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +void +fmpz_sub(fmpz_t f, const fmpz_t g, const fmpz_t h) +{ + fmpz c1 = *g; + fmpz c2 = *h; + + if (!COEFF_IS_MPZ(c1)) /* g is small */ + { + if (!COEFF_IS_MPZ(c2)) /* both inputs are small */ + { + fmpz_set_si(f, c1 - c2); + } + else /* g is small, h is large */ + { + __mpz_struct *mpz3 = _fmpz_promote(f); /* g is saved and h is large */ + __mpz_struct *mpz2 = COEFF_TO_PTR(c2); + if (c1 < WORD(0)) + { + flint_mpz_add_ui(mpz3, mpz2, -c1); + mpz_neg(mpz3, mpz3); + } + else + flint_mpz_ui_sub(mpz3, c1, mpz2); + _fmpz_demote_val(f); /* may have cancelled */ + } + } + else + { + if (!COEFF_IS_MPZ(c2)) /* g is large, h is small */ + { + __mpz_struct *mpz3 = _fmpz_promote(f); /* h is saved and g is large */ + __mpz_struct *mpz1 = COEFF_TO_PTR(c1); + if (c2 < WORD(0)) + flint_mpz_add_ui(mpz3, mpz1, -c2); + else + flint_mpz_sub_ui(mpz3, mpz1, c2); + _fmpz_demote_val(f); /* may have cancelled */ + } + else /* g and h are large */ + { + __mpz_struct *mpz3 = _fmpz_promote(f); /* aliasing means f is already large */ + __mpz_struct *mpz1 = COEFF_TO_PTR(c1); + __mpz_struct *mpz2 = COEFF_TO_PTR(c2); + mpz_sub(mpz3, mpz1, mpz2); + _fmpz_demote_val(f); /* may have cancelled */ + } + } +} diff --git a/external/flint-2.4.3/fmpz/sub_ui.c b/external/flint-2.4.3/fmpz/sub_ui.c new file mode 100644 index 0000000..34989ca --- /dev/null +++ b/external/flint-2.4.3/fmpz/sub_ui.c @@ -0,0 +1,60 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +void +fmpz_sub_ui(fmpz_t f, const fmpz_t g, ulong x) +{ + fmpz c = *g; + + if (!COEFF_IS_MPZ(c)) /* coeff is small */ + { + mp_limb_t sum[2]; + if (c < WORD(0)) /* g negative, x positive, so difference is negative */ + { + add_ssaaaa(sum[1], sum[0], 0, -c, 0, x); + fmpz_neg_uiui(f, sum[1], sum[0]); + } + else /* coeff is non-negative, x non-negative */ + { + if (x < c) + fmpz_set_ui(f, c - x); /* won't be negative and is smaller than c */ + else + fmpz_neg_ui(f, x - c); /* positive or zero */ + } + } + else + { + __mpz_struct *mpz_ptr, *mpz_ptr2; + mpz_ptr2 = _fmpz_promote(f); /* g is already large */ + mpz_ptr = COEFF_TO_PTR(c); + flint_mpz_sub_ui(mpz_ptr2, mpz_ptr, x); + _fmpz_demote_val(f); /* cancellation may have occurred */ + } +} diff --git a/external/flint-2.4.3/fmpz/submul.c b/external/flint-2.4.3/fmpz/submul.c new file mode 100644 index 0000000..8959311 --- /dev/null +++ b/external/flint-2.4.3/fmpz/submul.c @@ -0,0 +1,59 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +void +fmpz_submul(fmpz_t f, const fmpz_t g, const fmpz_t h) +{ + fmpz c1 = *g; + if (!COEFF_IS_MPZ(c1)) /* g is small */ + { + if (c1 < WORD(0)) + fmpz_addmul_ui(f, h, -c1); + else + fmpz_submul_ui(f, h, c1); + } + else + { + fmpz c2 = *h; + if (!COEFF_IS_MPZ(c2)) /* h is small */ + { + if (c2 < WORD(0)) + fmpz_addmul_ui(f, g, -c2); + else + fmpz_submul_ui(f, g, c2); + } + else /* both g and h are large */ + { + __mpz_struct *mpz_ptr = _fmpz_promote_val(f); + mpz_submul(mpz_ptr, COEFF_TO_PTR(c1), COEFF_TO_PTR(c2)); + _fmpz_demote_val(f); /* cancellation may have occurred */ + } + } +} diff --git a/external/flint-2.4.3/fmpz/submul_ui.c b/external/flint-2.4.3/fmpz/submul_ui.c new file mode 100644 index 0000000..ee4fedf --- /dev/null +++ b/external/flint-2.4.3/fmpz/submul_ui.c @@ -0,0 +1,97 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +void +fmpz_submul_ui(fmpz_t f, const fmpz_t g, ulong x) +{ + fmpz c1 = *g, r; + if ((x == 0) || (c1 == 0)) + return; /* product is zero */ + + r = *f; + if (r == 0) + { + fmpz_mul_ui(f, g, x); /* we are subtracting product from 0 */ + fmpz_neg(f, f); + return; + } + + if (!COEFF_IS_MPZ(c1)) /* c1 is small */ + { + mp_limb_t prod[2]; + ulong uc1 = FLINT_ABS(c1); + + __mpz_struct * mpz_ptr; + mpz_t temp; + + umul_ppmm(prod[1], prod[0], uc1, x); /* compute product */ + + if (prod[1] == 0) /* product fits in one limb */ + { + if (c1 < WORD(0)) + fmpz_add_ui(f, f, prod[0]); + else + fmpz_sub_ui(f, f, prod[0]); + return; + } + else if ((prod[1] == 1) && (!COEFF_IS_MPZ(r)) && ((r ^ c1) >= WORD(0))) + { + /* + only chance at cancellation is if product is one bit past + a limb and f is small and same sign as this product + */ + ulong ur = FLINT_ABS(r); + if (ur > prod[0]) /* cancellation will occur */ + { + fmpz_set_ui(f, prod[0] - ur); + if (r > WORD(0)) + fmpz_neg(f, f); + return; + } + } + + /* + in all remaining cases res is either big already, + or will be big in the end + */ + mpz_ptr = _fmpz_promote_val(f); + /* set up a temporary, cheap mpz_t to contain prod */ + temp->_mp_d = prod; + temp->_mp_size = (c1 < WORD(0) ? -2 : 2); + mpz_sub(mpz_ptr, mpz_ptr, temp); + _fmpz_demote_val(f); /* cancellation may have occurred */ + } + else /* c1 is large */ + { + __mpz_struct *mpz_ptr = _fmpz_promote_val(f); + flint_mpz_submul_ui(mpz_ptr, COEFF_TO_PTR(c1), x); + _fmpz_demote_val(f); /* cancellation may have occurred */ + } +} diff --git a/external/flint-2.4.3/fmpz/tdiv_q.c b/external/flint-2.4.3/fmpz/tdiv_q.c new file mode 100644 index 0000000..46bef18 --- /dev/null +++ b/external/flint-2.4.3/fmpz/tdiv_q.c @@ -0,0 +1,73 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" + +void +fmpz_tdiv_q(fmpz_t f, const fmpz_t g, const fmpz_t h) +{ + fmpz c1 = *g; + fmpz c2 = *h; + + if (fmpz_is_zero(h)) + { + flint_printf("Exception (fmpz_tdiv_q). Division by zero.\n"); + abort(); + } + + if (!COEFF_IS_MPZ(c1)) /* g is small */ + { + if (!COEFF_IS_MPZ(c2)) /* h is also small */ + fmpz_set_si(f, c1 / c2); + else /* h is large */ + fmpz_zero(f); + } + else /* g is large */ + { + __mpz_struct *mpz_ptr = _fmpz_promote(f); + + if (!COEFF_IS_MPZ(c2)) /* h is small */ + { + if (c2 > 0) /* h > 0 */ + { + flint_mpz_tdiv_q_ui(mpz_ptr, COEFF_TO_PTR(c1), c2); + } + else + { + flint_mpz_tdiv_q_ui(mpz_ptr, COEFF_TO_PTR(c1), -c2); + mpz_neg(mpz_ptr, mpz_ptr); + } + } + else /* both are large */ + { + mpz_tdiv_q(mpz_ptr, COEFF_TO_PTR(c1), COEFF_TO_PTR(c2)); + } + _fmpz_demote_val(f); /* division by h may result in small value */ + } +} diff --git a/external/flint-2.4.3/fmpz/tdiv_q_2exp.c b/external/flint-2.4.3/fmpz/tdiv_q_2exp.c new file mode 100644 index 0000000..6fc4b44 --- /dev/null +++ b/external/flint-2.4.3/fmpz/tdiv_q_2exp.c @@ -0,0 +1,51 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +void fmpz_tdiv_q_2exp(fmpz_t f, const fmpz_t g, ulong exp) +{ + fmpz d = *g; + + if (!COEFF_IS_MPZ(d)) /* g is small */ + { + if (d >= 0) + d = d >> FLINT_MIN(exp, FLINT_BITS - 2); + else + d = -((-d) >> FLINT_MIN(exp, FLINT_BITS - 2)); + + fmpz_set_si(f, d); + } + else /*g is large */ + { + __mpz_struct * mpz_ptr = _fmpz_promote(f); /* g is already large */ + mpz_tdiv_q_2exp(mpz_ptr, COEFF_TO_PTR(d), exp); + _fmpz_demote_val(f); /* division may make value small */ + } +} diff --git a/external/flint-2.4.3/fmpz/tdiv_q_si.c b/external/flint-2.4.3/fmpz/tdiv_q_si.c new file mode 100644 index 0000000..63f0825 --- /dev/null +++ b/external/flint-2.4.3/fmpz/tdiv_q_si.c @@ -0,0 +1,64 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +void +fmpz_tdiv_q_si(fmpz_t f, const fmpz_t g, slong h) +{ + fmpz c1 = *g; + slong c2 = h; + + if (h == 0) + { + flint_printf("Exception (fmpz_tdiv_q_si). Division by zero.\n"); + abort(); + } + + if (!COEFF_IS_MPZ(c1)) /* g is small */ + { + fmpz_set_si(f, c1 / c2); + } + else /* g is large */ + { + __mpz_struct *mpz_ptr = _fmpz_promote(f); + + if (c2 > 0) + { + flint_mpz_tdiv_q_ui(mpz_ptr, COEFF_TO_PTR(c1), c2); + } + else + { + flint_mpz_tdiv_q_ui(mpz_ptr, COEFF_TO_PTR(c1), -(ulong) c2); + mpz_neg(mpz_ptr, mpz_ptr); + } + _fmpz_demote_val(f); /* division by h may result in small value */ + } +} diff --git a/external/flint-2.4.3/fmpz/tdiv_q_ui.c b/external/flint-2.4.3/fmpz/tdiv_q_ui.c new file mode 100644 index 0000000..919e6f1 --- /dev/null +++ b/external/flint-2.4.3/fmpz/tdiv_q_ui.c @@ -0,0 +1,66 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +void +fmpz_tdiv_q_ui(fmpz_t f, const fmpz_t g, ulong h) +{ + fmpz c1 = *g; + ulong c2 = h; + + if (h == 0) + { + flint_printf("Exception (fmpz_tdiv_q_ui). Division by zero.\n"); + abort(); + } + + if (!COEFF_IS_MPZ(c1)) /* g is small */ + { + if (c1 > 0) + { + fmpz_set_ui(f, c1 / c2); + } + else + { + ulong q = ((ulong) -c1) / c2; + + fmpz_set_si(f, - (slong) q); + } + } + else /* g is large */ + { + __mpz_struct *mpz_ptr = _fmpz_promote(f); + + flint_mpz_tdiv_q_ui(mpz_ptr, COEFF_TO_PTR(c1), c2); + _fmpz_demote_val(f); /* division by h may result in small value */ + } +} diff --git a/external/flint-2.4.3/fmpz/tdiv_qr.c b/external/flint-2.4.3/fmpz/tdiv_qr.c new file mode 100644 index 0000000..fcc3cb7 --- /dev/null +++ b/external/flint-2.4.3/fmpz/tdiv_qr.c @@ -0,0 +1,88 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +void +fmpz_tdiv_qr(fmpz_t f, fmpz_t s, const fmpz_t g, const fmpz_t h) +{ + fmpz c1 = *g; + fmpz c2 = *h; + + if (fmpz_is_zero(h)) + { + flint_printf("Exception: division by zero in fmpz_tdiv_qr\n"); + abort(); + } + + if (!COEFF_IS_MPZ(c1)) /* g is small */ + { + if (!COEFF_IS_MPZ(c2)) /* h is also small */ + { + fmpz q = c1 / c2; /* compute C quotient */ + fmpz r = c1 - c2 * q; /* compute remainder */ + + fmpz_set_si(f, q); + fmpz_set_si(s, r); + } + else /* h is large and g is small */ + { + fmpz_set_ui(f, WORD(0)); /* g is zero */ + fmpz_set_si(s, c1); + } + } + else /* g is large */ + { + __mpz_struct *mpz_ptr, *mpz_ptr2; + + _fmpz_promote(f); /* must not hang on to ptr whilst promoting s */ + mpz_ptr2 = _fmpz_promote(s); + mpz_ptr = COEFF_TO_PTR(*f); + + if (!COEFF_IS_MPZ(c2)) /* h is small */ + { + if (c2 > 0) /* h > 0 */ + { + flint_mpz_tdiv_qr_ui(mpz_ptr, mpz_ptr2, COEFF_TO_PTR(c1), c2); + } + else + { + flint_mpz_tdiv_qr_ui(mpz_ptr, mpz_ptr2, COEFF_TO_PTR(c1), -c2); + mpz_neg(mpz_ptr, mpz_ptr); + } + } + else /* both are large */ + { + mpz_tdiv_qr(mpz_ptr, mpz_ptr2, COEFF_TO_PTR(c1), COEFF_TO_PTR(c2)); + } + _fmpz_demote_val(f); /* division by h may result in small value */ + _fmpz_demote_val(s); /* division by h may result in small value */ + } +} diff --git a/external/flint-2.4.3/fmpz/tdiv_ui.c b/external/flint-2.4.3/fmpz/tdiv_ui.c new file mode 100644 index 0000000..ca720bd --- /dev/null +++ b/external/flint-2.4.3/fmpz/tdiv_ui.c @@ -0,0 +1,56 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" + +ulong +fmpz_tdiv_ui(const fmpz_t g, ulong h) +{ + fmpz c1 = *g; + + if (h == UWORD(0)) + { + flint_printf("Exception (fmpz_tdiv_ui). Division by 0.\n"); + abort(); + } + + if (!COEFF_IS_MPZ(c1)) /* g is small */ + { + /* We need the absolut value of the remainder and + C 90 guarantees truncation towards zero. */ + if (c1 < WORD(0)) + return -c1 % h; + else + return c1 % h; + } + else /* g is large */ + { + return flint_mpz_tdiv_ui(COEFF_TO_PTR(c1), h); + } +} diff --git a/external/flint-2.4.3/fmpz/test/t-abs.c b/external/flint-2.4.3/fmpz/test/t-abs.c new file mode 100644 index 0000000..149f02b --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-abs.c @@ -0,0 +1,113 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("abs...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t c, d; + + fmpz_init(a); + fmpz_init(b); + mpz_init(c); + mpz_init(d); + + fmpz_randtest(a, state, 200); + + fmpz_get_mpz(c, a); + + fmpz_abs(b, a); + mpz_abs(c, c); + + fmpz_get_mpz(d, b); + + result = (mpz_cmp(c, d) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("c = %Zd, d = %Zd\n", c, d); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + mpz_clear(c); + mpz_clear(d); + } + + /* Check aliasing */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a; + mpz_t c, d; + + fmpz_init(a); + mpz_init(c); + mpz_init(d); + + fmpz_randtest(a, state, 200); + + fmpz_get_mpz(c, a); + + fmpz_abs(a, a); + mpz_abs(c, c); + + fmpz_get_mpz(d, a); + + result = (mpz_cmp(c, d) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("c = %Zd, d = %Zd\n", c, d); + abort(); + } + + fmpz_clear(a); + mpz_clear(c); + mpz_clear(d); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-abs_fits_ui.c b/external/flint-2.4.3/fmpz/test/t-abs_fits_ui.c new file mode 100644 index 0000000..ee659b1 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-abs_fits_ui.c @@ -0,0 +1,91 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +static void check(fmpz_t x, int expected) +{ + if (fmpz_abs_fits_ui(x) != expected) + { + flint_printf("FAIL:\n\n"); + flint_printf("x = "), fmpz_print(x), flint_printf("\n"); + abort(); + } +} + +int +main(void) +{ + slong i; + fmpz_t x; + + FLINT_TEST_INIT(state); + + flint_printf("abs_fits_ui...."); + fflush(stdout); + + fmpz_init(x); + + fmpz_set_si(x, COEFF_MIN); + check(x, 1); + + fmpz_set_si(x, COEFF_MAX); + check(x, 1); + + fmpz_set_ui(x, UWORD_MAX); + check(x, 1); + + fmpz_set_ui(x, UWORD_MAX); + fmpz_neg(x, x); + check(x, 1); + + fmpz_set_ui(x, UWORD_MAX); + fmpz_add_ui(x, x, UWORD(1)); + check(x, 0); + + fmpz_neg(x, x); + check(x, 0); + + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_set_ui(x, UWORD(1)); + fmpz_mul_2exp(x, x, i); + check(x, i < FLINT_BITS); + fmpz_neg(x, x); + check(x, i < FLINT_BITS); + } + + fmpz_clear(x); + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-abs_lbound_ui_2exp.c b/external/flint-2.4.3/fmpz/test/t-abs_lbound_ui_2exp.c new file mode 100644 index 0000000..167c553 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-abs_lbound_ui_2exp.c @@ -0,0 +1,102 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +static mp_limb_t +refimpl(slong * exp, const fmpz_t x, int bits) +{ + fmpz_t t; + slong xbits; + mp_limb_t m; + + xbits = fmpz_bits(x); + + fmpz_init(t); + fmpz_abs(t, x); + + if (xbits >= bits) + fmpz_tdiv_q_2exp(t, t, xbits - bits); + else + fmpz_mul_2exp(t, t, bits - xbits); + + m = fmpz_get_ui(t); + fmpz_clear(t); + + *exp = xbits - bits; + + return m; +} + +int +main(void) +{ + slong iter; + FLINT_TEST_INIT(state); + + flint_printf("abs_lbound_ui_2exp...."); + fflush(stdout); + + + + for (iter = 0; iter < 10000 * flint_test_multiplier(); iter++) + { + fmpz_t x; + slong bits; + slong exp, yexp; + mp_limb_t yman, man; + + fmpz_init(x); + fmpz_randtest_not_zero(x, state, 1 + n_randint(state, 400)); + + bits = 1 + n_randint(state, FLINT_BITS - 1); + + yman = refimpl(&yexp, x, bits); + man = fmpz_abs_lbound_ui_2exp(&exp, x, bits); + + if (FLINT_BIT_COUNT(man) != bits || (man != yman) || (exp != yexp)) + { + flint_printf("FAIL\n"); + flint_printf("bits = %wd, count = %u\n\n", bits, FLINT_BIT_COUNT(man)); + flint_printf("x = "); fmpz_print(x); flint_printf("\n\n"); + flint_printf("bits(x) = %wd\n\n", fmpz_bits(x)); + flint_printf("man = %wu, exp = %wd\n", man, exp); + flint_printf("yman = %wu, yexp = %wd\n", yman, yexp); + abort(); + } + + fmpz_clear(x); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-abs_ubound_ui_2exp.c b/external/flint-2.4.3/fmpz/test/t-abs_ubound_ui_2exp.c new file mode 100644 index 0000000..b999b3f --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-abs_ubound_ui_2exp.c @@ -0,0 +1,139 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + slong iter; + int result; + FLINT_TEST_INIT(state); + + flint_printf("abs_ubound_ui_2exp...."); + fflush(stdout); + + + + for (iter = 0; iter < 10000 * flint_test_multiplier(); iter++) + { + fmpz_t x, y; + slong bits, yexp; + slong exp; + mp_limb_t man; + + fmpz_init(x); + fmpz_init(y); + + fmpz_randtest_not_zero(x, state, 1 + n_randint(state, 400)); + + bits = 1 + n_randint(state, FLINT_BITS - 1); + + /* compute an exactly rounded mantissa */ + fmpz_abs(y, x); + + if (fmpz_is_zero(y)) + { + yexp = 0; + } + else + { + yexp = fmpz_bits(y) - bits; + + if (yexp >= 0) + { + fmpz_cdiv_q_2exp(y, y, yexp); + if (fmpz_bits(y) == bits + 1) + { + fmpz_tdiv_q_2exp(y, y, 1); + yexp--; + } + } + else + { + fmpz_mul_2exp(y, y, -yexp); + } + } + + man = fmpz_abs_ubound_ui_2exp(&exp, x, bits); + + if (FLINT_BIT_COUNT(man) != bits) + { + flint_printf("wrong number of bits!\n"); + flint_printf("bits = %wd, count = %u\n\n", bits, FLINT_BIT_COUNT(man)); + flint_printf("x = "); fmpz_print(x); flint_printf("\n\n"); + flint_printf("bits(x) = %wd\n\n", fmpz_bits(x)); + flint_printf("y = "); fmpz_print(y); flint_printf("\n\n"); + flint_printf("yexp = %wd\n\n", yexp); + flint_printf("man = %wu, exp = %wd\n", man, exp); + abort(); + } + + /* ok if equal */ + result = (fmpz_cmp_ui(y, man) == 0); + + /* ok if mantissa is 1 larger */ + if (!result) + { + result = ((exp == yexp) && (fmpz_cmp_ui(y, man - 1) == 0)); + } + + /* ok if the exact mantissa is 2^r-1 and overflow to 2^r happened */ + if (!result) + { + fmpz_t t; + fmpz_init(t); + fmpz_set_ui(t, man); + fmpz_mul_ui(t, t, 2); + fmpz_sub_ui(t, t, 1); + result = (exp == yexp + 1) && fmpz_equal(t, y); + fmpz_clear(t); + } + + if (!result) + { + flint_printf("different from exact ceiling division\n"); + flint_printf("bits = %wd\n\n", bits); + flint_printf("x = "); fmpz_print(x); flint_printf("\n\n"); + flint_printf("bits(x) = %wd\n\n", fmpz_bits(x)); + flint_printf("y = "); fmpz_print(y); flint_printf(", yexp = %wd\n\n", yexp); + flint_printf("man = %wu, exp = %wd\n", man, exp); + abort(); + } + + fmpz_clear(x); + fmpz_clear(y); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-add.c b/external/flint-2.4.3/fmpz/test/t-add.c new file mode 100644 index 0000000..86843fc --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-add.c @@ -0,0 +1,217 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("add...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c; + mpz_t d, e, f, g; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + fmpz_randtest(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_add(c, a, b); + mpz_add(f, d, e); + + fmpz_get_mpz(g, c); + + result = (mpz_cmp(f, g) == 0); + + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + /* Check aliasing of a and b */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, c; + mpz_t d, f, g; + + fmpz_init(a); + fmpz_init(c); + + mpz_init(d); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + + fmpz_get_mpz(d, a); + + fmpz_add(c, a, a); + mpz_add(f, d, d); + + fmpz_get_mpz(g, c); + + result = (mpz_cmp(f, g) == 0); + + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, f = %Zd, g = %Zd\n", d, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(c); + + mpz_clear(d); + mpz_clear(f); + mpz_clear(g); + } + + /* Test aliasing of a and c */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t d, e, f, g; + + fmpz_init(a); + fmpz_init(b); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + fmpz_randtest(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_add(a, a, b); + mpz_add(f, d, e); + + fmpz_get_mpz(g, a); + + result = (mpz_cmp(f, g) == 0); + + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + /* Test aliasing of b and c */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t d, e, f, g; + + fmpz_init(a); + fmpz_init(b); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + fmpz_randtest(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_add(b, a, b); + mpz_add(f, d, e); + + fmpz_get_mpz(g, b); + + result = (mpz_cmp(f, g) == 0); + + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-add_ui.c b/external/flint-2.4.3/fmpz/test/t-add_ui.c new file mode 100644 index 0000000..612c013 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-add_ui.c @@ -0,0 +1,127 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("add_ui...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t d, e, f; + ulong x; + + fmpz_init(a); + fmpz_init(b); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + + fmpz_randtest(a, state, 200); + + fmpz_get_mpz(d, a); + x = n_randtest(state); + + fmpz_add_ui(b, a, x); + flint_mpz_add_ui(e, d, x); + + fmpz_get_mpz(f, b); + + result = (mpz_cmp(e, f) == 0); + + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, x = %wu\n", d, e, f, x); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + } + + /* Check aliasing of a and b */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a; + mpz_t d, e, f; + ulong x; + + fmpz_init(a); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + + fmpz_randtest(a, state, 200); + + fmpz_get_mpz(d, a); + x = n_randtest(state); + + fmpz_add_ui(a, a, x); + flint_mpz_add_ui(e, d, x); + + fmpz_get_mpz(f, a); + + result = (mpz_cmp(e, f) == 0); + + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, x = %wu\n", d, e, f, x); + abort(); + } + + fmpz_clear(a); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-addmul.c b/external/flint-2.4.3/fmpz/test/t-addmul.c new file mode 100644 index 0000000..d81e59d --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-addmul.c @@ -0,0 +1,217 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("addmul...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c; + mpz_t d, e, f, g; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + fmpz_randtest(b, state, 200); + fmpz_randtest(c, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + fmpz_get_mpz(f, c); + + fmpz_addmul(c, a, b); + mpz_addmul(f, d, e); + + fmpz_get_mpz(g, c); + + result = (mpz_cmp(f, g) == 0); + + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + /* Check aliasing of a and b */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, c; + mpz_t d, f, g; + + fmpz_init(a); + fmpz_init(c); + + mpz_init(d); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + fmpz_randtest(c, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(f, c); + + fmpz_addmul(c, a, a); + mpz_addmul(f, d, d); + + fmpz_get_mpz(g, c); + + result = (mpz_cmp(f, g) == 0); + + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, f = %Zd, g = %Zd\n", d, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(c); + + mpz_clear(d); + mpz_clear(f); + mpz_clear(g); + } + + /* Test aliasing of a and c */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t d, e, f; + + fmpz_init(a); + fmpz_init(b); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + + fmpz_randtest(a, state, 200); + fmpz_randtest(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_addmul(a, a, b); + mpz_addmul(d, d, e); + + fmpz_get_mpz(f, a); + + result = (mpz_cmp(d, f) == 0); + + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd\n", d, e, f); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + } + + /* Test aliasing of b and c */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t d, e, f; + + fmpz_init(a); + fmpz_init(b); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + + fmpz_randtest(a, state, 200); + fmpz_randtest(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_addmul(b, a, b); + mpz_addmul(e, d, e); + + fmpz_get_mpz(f, b); + + result = (mpz_cmp(f, e) == 0); + + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd\n", d, e, f); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-addmul_ui.c b/external/flint-2.4.3/fmpz/test/t-addmul_ui.c new file mode 100644 index 0000000..e0b3b65 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-addmul_ui.c @@ -0,0 +1,127 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("addmul_ui...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t d, e, f; + ulong x; + + fmpz_init(a); + fmpz_init(b); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + + fmpz_randtest(a, state, 200); + fmpz_randtest(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + x = n_randtest(state); + + fmpz_addmul_ui(b, a, x); + flint_mpz_addmul_ui(e, d, x); + + fmpz_get_mpz(f, b); + + result = (mpz_cmp(e, f) == 0); + + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, x = %wu\n", d, e, f, x); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + } + + /* Check aliasing of a and b */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a; + mpz_t d, e; + ulong x; + + fmpz_init(a); + + mpz_init(d); + mpz_init(e); + + fmpz_randtest(a, state, 200); + + fmpz_get_mpz(d, a); + x = n_randtest(state); + + fmpz_addmul_ui(a, a, x); + flint_mpz_addmul_ui(d, d, x); + + fmpz_get_mpz(e, a); + + result = (mpz_cmp(d, e) == 0); + + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, x = %wu\n", d, e, x); + abort(); + } + + fmpz_clear(a); + + mpz_clear(d); + mpz_clear(e); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-and.c b/external/flint-2.4.3/fmpz/test/t-and.c new file mode 100644 index 0000000..4e690b9 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-and.c @@ -0,0 +1,217 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("and...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c; + mpz_t d, e, f, g; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + fmpz_randtest(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_and(c, a, b); + mpz_and(f, d, e); + + fmpz_get_mpz(g, c); + + result = (mpz_cmp(f, g) == 0); + + if (!result) + { + flint_printf("FAIL (no aliasing):\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + /* Check aliasing of a and b */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, c; + mpz_t d, f, g; + + fmpz_init(a); + fmpz_init(c); + + mpz_init(d); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + + fmpz_get_mpz(d, a); + + fmpz_and(c, a, a); + mpz_and(f, d, d); + + fmpz_get_mpz(g, c); + + result = (mpz_cmp(f, g) == 0); + + if (!result) + { + flint_printf("FAIL (a/b alias):\n"); + gmp_printf("d = %Zd, f = %Zd, g = %Zd\n", d, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(c); + + mpz_clear(d); + mpz_clear(f); + mpz_clear(g); + } + + /* Test aliasing of a and c */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t d, e, f, g; + + fmpz_init(a); + fmpz_init(b); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + fmpz_randtest(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_and(a, a, b); + mpz_and(f, d, e); + + fmpz_get_mpz(g, a); + + result = (mpz_cmp(f, g) == 0); + + if (!result) + { + flint_printf("FAIL (a/c alias):\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + /* Test aliasing of b and c */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t d, e, f, g; + + fmpz_init(a); + fmpz_init(b); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + fmpz_randtest(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_and(b, a, b); + mpz_and(f, d, e); + + fmpz_get_mpz(g, b); + + result = (mpz_cmp(f, g) == 0); + + if (!result) + { + flint_printf("FAIL (b/c alias):\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-bin_uiui.c b/external/flint-2.4.3/fmpz/test/t-bin_uiui.c new file mode 100644 index 0000000..fdfe4d9 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-bin_uiui.c @@ -0,0 +1,76 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "ulong_extras.h" + +int +main(void) +{ + slong i; + ulong n, k; + fmpz_t x, y; + mpz_t z; + FLINT_TEST_INIT(state); + + flint_printf("bin_uiui...."); + fflush(stdout); + + + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_init(x); + fmpz_init(y); + mpz_init(z); + + n = n_randint(state, 1000); + k = n_randint(state, 1000); + + fmpz_bin_uiui(x, n, k); + flint_mpz_bin_uiui(z, n, k); + fmpz_set_mpz(y, z); + + if (!fmpz_equal(x, y)) + { + flint_printf("FAIL: n,k = %wu,%wu\n", n, k); + abort(); + } + + fmpz_clear(x); + fmpz_clear(y); + mpz_clear(z); + } + + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-bit_pack.c b/external/flint-2.4.3/fmpz/test/t-bit_pack.c new file mode 100644 index 0000000..7ac3983 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-bit_pack.c @@ -0,0 +1,115 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("bit_pack/bit_unpack...."); + fflush(stdout); + + + + for (i = 0; i < 50000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mp_bitcnt_t bits = n_randint(state, 300) + 1; + ulong space = (300 - 1) / FLINT_BITS + 2; /* 2 to accomodate shift */ + mp_ptr arr = (mp_ptr) flint_calloc(space, sizeof(mp_limb_t)); + mp_bitcnt_t shift = n_randint(state, FLINT_BITS); + int negate = (int) -n_randint(state, 2); + + fmpz_init(a); + fmpz_init(b); + + fmpz_randtest(a, state, bits - 1); /* need one bit for sign */ + + arr[0] = n_randbits(state, shift); + + fmpz_bit_pack(arr, shift, bits, a, negate, 0); + fmpz_bit_unpack(b, arr, shift, bits, negate, 0); + + result = (fmpz_cmp(a, b) == 0); + + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_print(a), flint_printf("\n"); + fmpz_print(b), flint_printf("\n"); + abort(); + } + + flint_free(arr); + fmpz_clear(a); + fmpz_clear(b); + } + + for (i = 0; i < 50000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mp_bitcnt_t bits = n_randint(state, 300) + 1; + ulong space = (300 - 1) / FLINT_BITS + 2; /* 2 to accomodate shift */ + mp_ptr arr = (mp_ptr) flint_calloc(space, sizeof(mp_limb_t)); + mp_bitcnt_t shift = n_randint(state, FLINT_BITS); + + fmpz_init(a); + fmpz_init(b); + + fmpz_randtest_unsigned(a, state, bits); + + arr[0] = n_randbits(state, shift); + + fmpz_bit_pack(arr, shift, bits, a, 0, 0); + fmpz_bit_unpack_unsigned(b, arr, shift, bits); + + result = (fmpz_cmp(a, b) == 0); + + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_print(a), flint_printf("\n"); + fmpz_print(b), flint_printf("\n"); + abort(); + } + + flint_free(arr); + fmpz_clear(a); + fmpz_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-bits.c b/external/flint-2.4.3/fmpz/test/t-bits.c new file mode 100644 index 0000000..a3bac8a --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-bits.c @@ -0,0 +1,76 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("bits...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a; + mpz_t b; + mp_bitcnt_t r1, r2; + + fmpz_init(a); + mpz_init(b); + + fmpz_randtest(a, state, 200); + + fmpz_get_mpz(b, a); + + r1 = fmpz_bits(a); + r2 = mpz_sizeinbase(b, 2); + result = (r1 == r2) || ((r1 == 0) && (r2 == 1)); + + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("b = %Zd\n", b); + abort(); + } + + fmpz_clear(a); + mpz_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-cdiv_q.c b/external/flint-2.4.3/fmpz/test/t-cdiv_q.c new file mode 100644 index 0000000..af75fce --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-cdiv_q.c @@ -0,0 +1,217 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("cdiv_q...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c; + mpz_t d, e, f, g; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + fmpz_randtest_not_zero(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_cdiv_q(c, a, b); + mpz_cdiv_q(f, d, e); + + fmpz_get_mpz(g, c); + + result = (mpz_cmp(f, g) == 0); + + if (!result) + { + flint_printf("FAIL\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + /* Check aliasing of a and b */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, c; + mpz_t d, f, g; + + fmpz_init(a); + fmpz_init(c); + + mpz_init(d); + mpz_init(f); + mpz_init(g); + + fmpz_randtest_not_zero(a, state, 200); + + fmpz_get_mpz(d, a); + + fmpz_cdiv_q(c, a, a); + mpz_cdiv_q(f, d, d); + + fmpz_get_mpz(g, c); + + result = (mpz_cmp(f, g) == 0); + + if (!result) + { + flint_printf("FAIL\n"); + gmp_printf("d = %Zd, f = %Zd, g = %Zd\n", d, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(c); + + mpz_clear(d); + mpz_clear(f); + mpz_clear(g); + } + + /* Test aliasing of a and c */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t d, e, f, g; + + fmpz_init(a); + fmpz_init(b); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + fmpz_randtest_not_zero(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_cdiv_q(a, a, b); + mpz_cdiv_q(f, d, e); + + fmpz_get_mpz(g, a); + + result = (mpz_cmp(f, g) == 0); + + if (!result) + { + flint_printf("FAIL\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + /* Test aliasing of b and c */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t d, e, f, g; + + fmpz_init(a); + fmpz_init(b); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + fmpz_randtest_not_zero(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_cdiv_q(b, a, b); + mpz_cdiv_q(f, d, e); + + fmpz_get_mpz(g, b); + + result = (mpz_cmp(f, g) == 0); + + if (!result) + { + flint_printf("FAIL\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-cdiv_q_2exp.c b/external/flint-2.4.3/fmpz/test/t-cdiv_q_2exp.c new file mode 100644 index 0000000..614302d --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-cdiv_q_2exp.c @@ -0,0 +1,125 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("cdiv_q_2exp...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t d, e, f; + ulong x; + + fmpz_init(a); + fmpz_init(b); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + + fmpz_randtest(a, state, 200); + + fmpz_get_mpz(d, a); + x = n_randint(state, 200); + + fmpz_cdiv_q_2exp(b, a, x); + mpz_cdiv_q_2exp(e, d, x); + + fmpz_get_mpz(f, b); + + result = (mpz_cmp(e, f) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, exp = %wu\n", d, e, f, x); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + } + + /* Check aliasing of a and b */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a; + mpz_t d, e, f; + ulong x; + + fmpz_init(a); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + + fmpz_randtest(a, state, 200); + + fmpz_get_mpz(d, a); + x = n_randint(state, 200); + + fmpz_cdiv_q_2exp(a, a, x); + mpz_cdiv_q_2exp(e, d, x); + + fmpz_get_mpz(f, a); + + result = (mpz_cmp(e, f) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, exp = %wu\n", d, e, f, x); + abort(); + } + + fmpz_clear(a); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-cdiv_q_si.c b/external/flint-2.4.3/fmpz/test/t-cdiv_q_si.c new file mode 100644 index 0000000..7b36ccd --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-cdiv_q_si.c @@ -0,0 +1,131 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("cdiv_q_si...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + slong b; + fmpz_t a, c; + mpz_t d, e, f, g; + + fmpz_init(a); + fmpz_init(c); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + b = z_randtest_not_zero(state); + + fmpz_get_mpz(d, a); + flint_mpz_set_si(e, b); + + fmpz_cdiv_q_si(c, a, b); + mpz_cdiv_q(f, d, e); + + fmpz_get_mpz(g, c); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL (1):\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(c); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + /* Test aliasing of a and c */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + slong b; + fmpz_t a; + mpz_t d, e, f, g; + + fmpz_init(a); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + b = z_randtest_not_zero(state); + + fmpz_get_mpz(d, a); + flint_mpz_set_si(e, b); + + fmpz_cdiv_q_si(a, a, b); + mpz_cdiv_q(f, d, e); + + fmpz_get_mpz(g, a); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL (2):\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-cdiv_q_ui.c b/external/flint-2.4.3/fmpz/test/t-cdiv_q_ui.c new file mode 100644 index 0000000..e6e802b --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-cdiv_q_ui.c @@ -0,0 +1,131 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("cdiv_q_ui...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + ulong b; + fmpz_t a, c; + mpz_t d, e, f, g; + + fmpz_init(a); + fmpz_init(c); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + b = n_randtest_not_zero(state); + + fmpz_get_mpz(d, a); + flint_mpz_set_ui(e, b); + + fmpz_cdiv_q_ui(c, a, b); + mpz_cdiv_q(f, d, e); + + fmpz_get_mpz(g, c); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL (1):\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(c); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + /* Test aliasing of a and c */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + ulong b; + fmpz_t a; + mpz_t d, e, f, g; + + fmpz_init(a); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + b = n_randtest_not_zero(state); + + fmpz_get_mpz(d, a); + flint_mpz_set_ui(e, b); + + fmpz_cdiv_q_ui(a, a, b); + mpz_cdiv_q(f, d, e); + + fmpz_get_mpz(g, a); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL (2):\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-clog.c b/external/flint-2.4.3/fmpz/test/t-clog.c new file mode 100644 index 0000000..dd13458 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-clog.c @@ -0,0 +1,147 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("clog...."); + fflush(stdout); + + + + /* Check aliasing */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a; + slong l; + + fmpz_init(a); + + while (fmpz_cmp_ui(a, 2) < 0) + fmpz_randtest(a, state, 200); + + l = fmpz_clog(a, a); + + result = (l == 1); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpz_print(a), flint_printf("\n"); + flint_printf("l = %wd\n", l); + abort(); + } + + fmpz_clear(a); + } + + /* Check correctness */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, x, y; + slong k; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(x); + fmpz_init(y); + + while (fmpz_cmp_ui(a, 1) < 0) + fmpz_randtest(a, state, 200); + while (fmpz_cmp_ui(b, 2) < 0) + fmpz_randtest(b, state, 200); + + k = fmpz_clog(a, b); /* p^{k-1} < a <= p^k*/ + + if (k > 0) + fmpz_pow_ui(x, b, k - 1); + else + fmpz_zero(x); + fmpz_pow_ui(y, b, k); + + result = (fmpz_cmp(x, a) < 0 && fmpz_cmp(a, y) <= 0); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpz_print(a), flint_printf("\n"); + flint_printf("b = "), fmpz_print(b), flint_printf("\n"); + flint_printf("x = "), fmpz_print(x), flint_printf("\n"); + flint_printf("y = "), fmpz_print(y), flint_printf("\n"); + flint_printf("k = %wd\n", k); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(x); + fmpz_clear(y); + } + + /* Check correctness: exact powers */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + slong k, l; + + fmpz_init(a); + fmpz_init(b); + + while (fmpz_cmp_ui(b, 2) < 0) + fmpz_randtest(b, state, 200); + l = n_randint(state, 20); + fmpz_pow_ui(a, b, l); + + k = fmpz_clog(a, b); + + result = (k == l); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpz_print(a), flint_printf("\n"); + flint_printf("b = "), fmpz_print(b), flint_printf("\n"); + flint_printf("k = %wd\n", k); + flint_printf("l = %wd\n", l); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/fmpz/test/t-clog_ui.c b/external/flint-2.4.3/fmpz/test/t-clog_ui.c new file mode 100644 index 0000000..ff28e8e --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-clog_ui.c @@ -0,0 +1,122 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("clog_ui...."); + fflush(stdout); + + + + /* Check correctness */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, x, y; + slong k; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(x); + fmpz_init(y); + + while (fmpz_cmp_ui(a, 1) < 0) + fmpz_randtest(a, state, 200); + while (fmpz_cmp_ui(b, 2) < 0) + fmpz_set_ui(b, n_randtest(state)); + + k = fmpz_clog_ui(a, fmpz_get_ui(b)); + + if (k > 0) + fmpz_pow_ui(x, b, k - 1); + else + fmpz_zero(x); + fmpz_pow_ui(y, b, k); + + result = (fmpz_cmp(x, a) < 0 && fmpz_cmp(a, y) <= 0); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpz_print(a), flint_printf("\n"); + flint_printf("b = "), fmpz_print(b), flint_printf("\n"); + flint_printf("x = "), fmpz_print(x), flint_printf("\n"); + flint_printf("y = "), fmpz_print(y), flint_printf("\n"); + flint_printf("k = %wd\n", k); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(x); + fmpz_clear(y); + } + + /* Check correctness: exact powers */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + slong k, l; + + fmpz_init(a); + fmpz_init(b); + + while (fmpz_cmp_ui(b, 2) < 0) + fmpz_set_ui(b, n_randtest(state)); + l = n_randint(state, 20); + fmpz_pow_ui(a, b, l); + + k = fmpz_clog_ui(a, fmpz_get_ui(b)); + + result = (k == l); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpz_print(a), flint_printf("\n"); + flint_printf("b = "), fmpz_print(b), flint_printf("\n"); + flint_printf("k = %wd\n", k); + flint_printf("l = %wd\n", l); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/fmpz/test/t-cmp.c b/external/flint-2.4.3/fmpz/test/t-cmp.c new file mode 100644 index 0000000..56d9d0d --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-cmp.c @@ -0,0 +1,109 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("cmp...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + + fmpz_init(a); + fmpz_init(b); + + fmpz_randtest(a, state, 200); + + fmpz_set(b, a); + result = (fmpz_cmp(a, b)); + + if (result != 0) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpz_print(a), flint_printf("\n"); + flint_printf("b = "), fmpz_print(b), flint_printf("\n"); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + } + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t c, d; + int r1, r2; + + fmpz_init(a); + fmpz_init(b); + + mpz_init(c); + mpz_init(d); + + fmpz_randtest(a, state, 200); + fmpz_randtest(b, state, 200); + + fmpz_get_mpz(c, a); + fmpz_get_mpz(d, b); + + r1 = fmpz_cmp(a, b); + r2 = mpz_cmp(c, d); + result = ((r1 == 0 && r2 == 0) || (r1 > 0 && r2 > 0) + || (r1 < 0 && r2 < 0)); + + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("c = %Zd, d = %Zd\n", c, d); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + + mpz_clear(c); + mpz_clear(d); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-cmp_si.c b/external/flint-2.4.3/fmpz/test/t-cmp_si.c new file mode 100644 index 0000000..4ce6bec --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-cmp_si.c @@ -0,0 +1,83 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "long_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("cmp_si...."); + fflush(stdout); + + + + /* Compare with fmpz_cmp */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + slong n; + int lhs, rhs; + + fmpz_init(a); + fmpz_init(b); + + fmpz_randtest(a, state, 200); + + n = z_randtest(state); + fmpz_set_si(b, n); + + lhs = fmpz_cmp(a, b); + rhs = fmpz_cmp_si(a, n); + + result = (lhs < 0) ? (rhs < 0) : ((lhs > 0) ? (rhs > 0) : (rhs == 0)); + if (result == 0) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpz_print(a), flint_printf("\n"); + flint_printf("b = "), fmpz_print(b), flint_printf("\n"); + flint_printf("n = %wd\n", n); + flint_printf("cmp(a, b) = %d\n", fmpz_cmp(a, b)); + flint_printf("cmp_si(a, n) = %d\n", fmpz_cmp_si(a, n)); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fmpz/test/t-cmp_ui.c b/external/flint-2.4.3/fmpz/test/t-cmp_ui.c new file mode 100644 index 0000000..549c9a7 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-cmp_ui.c @@ -0,0 +1,82 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("cmp_ui...."); + fflush(stdout); + + + + /* Compare with fmpz_cmp */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + ulong n; + int lhs, rhs; + + fmpz_init(a); + fmpz_init(b); + + fmpz_randtest(a, state, 200); + + n = n_randtest(state); + fmpz_set_ui(b, n); + + lhs = fmpz_cmp(a, b); + rhs = fmpz_cmp_ui(a, n); + + result = (lhs < 0) ? (rhs < 0) : ((lhs > 0) ? (rhs > 0) : (rhs == 0)); + if (result == 0) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpz_print(a), flint_printf("\n"); + flint_printf("b = "), fmpz_print(b), flint_printf("\n"); + flint_printf("n = %wu\n", n); + flint_printf("cmp(a, b) = %d\n", fmpz_cmp(a, b)); + flint_printf("cmp_ui(a, n) = %d\n", fmpz_cmp_ui(a, n)); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fmpz/test/t-cmpabs.c b/external/flint-2.4.3/fmpz/test/t-cmpabs.c new file mode 100644 index 0000000..d21fcdc --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-cmpabs.c @@ -0,0 +1,109 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("cmpabs...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + + fmpz_init(a); + fmpz_init(b); + + fmpz_randtest(a, state, 200); + + fmpz_set(b, a); + result = (fmpz_cmpabs(a, b)); + + if (result != 0) + { + flint_printf("FAIL\n"); + flint_printf("a = "), fmpz_print(a), flint_printf("\n"); + flint_printf("b = "), fmpz_print(b), flint_printf("\n"); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + } + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t c, d; + int r1, r2; + + fmpz_init(a); + fmpz_init(b); + + mpz_init(c); + mpz_init(d); + + fmpz_randtest(a, state, 200); + fmpz_randtest(b, state, 200); + + fmpz_get_mpz(c, a); + fmpz_get_mpz(d, b); + + r1 = fmpz_cmpabs(a, b); + r2 = mpz_cmpabs(c, d); + result = ((r1 == 0 && r2 == 0) || (r1 > 0 && r2 > 0) + || (r1 < 0 && r2 < 0)); + + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("c = %Zd, d = %Zd\n", c, d); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + + mpz_clear(c); + mpz_clear(d); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-comb_init_clear.c b/external/flint-2.4.3/fmpz/test/t-comb_init_clear.c new file mode 100644 index 0000000..251eee7 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-comb_init_clear.c @@ -0,0 +1,71 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + + +int main() +{ + slong i, j; + mp_limb_t n; + slong num_primes; + mp_limb_t * primes; + mp_limb_t p; + fmpz_comb_t comb; + FLINT_TEST_INIT(state); + + + flint_printf("comb_init/clear...."); + fflush(stdout); + + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + n = n_randint(state, 10); + num_primes = (WORD(1) << n); + primes = (mp_limb_t *) flint_malloc(num_primes * sizeof(mp_limb_t)); + p = n_nextprime((UWORD(1) << (FLINT_BITS-1)) - WORD(10000000), 0); + + for (j = 0; j < num_primes; j++) + { + primes[j] = p; + p = n_nextprime(p, 0); + } + + fmpz_comb_init(comb, primes, num_primes); + fmpz_comb_clear(comb); + flint_free(primes); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-combit.c b/external/flint-2.4.3/fmpz/test/t-combit.c new file mode 100644 index 0000000..21761ff --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-combit.c @@ -0,0 +1,83 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("combit...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + ulong j; + fmpz_t a; + mpz_t b, c; + + fmpz_init(a); + mpz_init(b); + mpz_init(c); + + fmpz_randtest(a, state, 2 * FLINT_BITS); + fmpz_get_mpz(b, a); + j = n_randint(state, 3 * FLINT_BITS); + + fmpz_combit(a, j); + mpz_combit(b, j); + fmpz_get_mpz(c, a); + + result = (mpz_cmp(b, c) == 0); + + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpz_print(a), flint_printf("\n"); + gmp_printf("b = %Zd\n", b); + flint_printf("j = %wd\n", j); + abort(); + } + + fmpz_clear(a); + mpz_clear(c); + mpz_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-complement.c b/external/flint-2.4.3/fmpz/test/t-complement.c new file mode 100644 index 0000000..8cde730 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-complement.c @@ -0,0 +1,117 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("complement...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t c, d; + + fmpz_init(a); + fmpz_init(b); + + mpz_init(c); + mpz_init(d); + + fmpz_randtest(a, state, 200); + + fmpz_get_mpz(c, a); + + fmpz_complement(b, a); + mpz_com(c, c); + + fmpz_get_mpz(d, b); + + result = (mpz_cmp(c, d) == 0); + if (!result) + { + flint_printf("FAIL (no alias):\n"); + gmp_printf("c = %Zd, d = %Zd\n", c, d); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + + mpz_clear(c); + mpz_clear(d); + } + + /* Check aliasing */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a; + mpz_t c, d; + + fmpz_init(a); + + mpz_init(c); + mpz_init(d); + + fmpz_randtest(a, state, 200); + + fmpz_get_mpz(c, a); + + fmpz_complement(a, a); + mpz_com(c, c); + + fmpz_get_mpz(d, a); + + result = (mpz_cmp(c, d) == 0); + if (!result) + { + flint_printf("FAIL (aliased):\n"); + gmp_printf("c = %Zd, d = %Zd\n", c, d); + abort(); + } + + fmpz_clear(a); + + mpz_clear(c); + mpz_clear(d); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-crt_ui.c b/external/flint-2.4.3/fmpz/test/t-crt_ui.c new file mode 100644 index 0000000..d19e5af --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-crt_ui.c @@ -0,0 +1,117 @@ +/*============================================================================ + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +===============================================================================*/ +/**************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +*****************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "ulong_extras.h" + + +int main() +{ + slong i, j; + int sign; + + fmpz_t input; + fmpz_t result; + fmpz_t r1; + fmpz_t m1; + fmpz_t mprod; + ulong r2, m2; + + FLINT_TEST_INIT(state); + + flint_printf("CRT_ui...."); + fflush(stdout); + + fmpz_init(input); + fmpz_init(result); + fmpz_init(r1); + fmpz_init(m1); + fmpz_init(mprod); + + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + slong nprimes; + + m2 = n_randtest_prime(state, 0); + nprimes = 1 + n_randint(state, 4); + + fmpz_set_ui(m1, UWORD(1)); + for (j = 0; j < nprimes; ) + { + ulong t = n_randtest_prime(state, 0); + if (t != m2) + { + fmpz_mul_ui(m1, m1, t); + j++; + } + } + + fmpz_mul_ui(mprod, m1, m2); + + sign = n_randint(state, 2); + + if (sign) + fmpz_randtest_mod_signed(input, state, mprod); + else + fmpz_randtest_mod(input, state, mprod); + + fmpz_mod(r1, input, m1); + r2 = fmpz_fdiv_ui(input, m2); + + fmpz_CRT_ui(result, r1, m1, r2, m2, sign); + + if (!fmpz_equal(result, input)) + { + flint_printf("FAIL:\n"); + flint_printf("m1: "); fmpz_print(m1); flint_printf("\n"); + flint_printf("m2: %wu\n", m2); + flint_printf("m1*m2: "); fmpz_print(mprod); flint_printf("\n"); + flint_printf("input: "); fmpz_print(input); flint_printf("\n"); + flint_printf("r1: "); fmpz_print(r1); flint_printf("\n"); + flint_printf("r2: %wu\n", r2); + flint_printf("result: "); fmpz_print(result); flint_printf("\n"); + flint_printf("%wd Equalness: %d\n", i, fmpz_equal(result, input)); + flint_printf("\n"); + abort(); + } + } + + fmpz_clear(input); + fmpz_clear(result); + fmpz_clear(r1); + fmpz_clear(m1); + fmpz_clear(mprod); + + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-divexact.c b/external/flint-2.4.3/fmpz/test/t-divexact.c new file mode 100644 index 0000000..afb7a48 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-divexact.c @@ -0,0 +1,220 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("divexact...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c; + mpz_t d, e, f, g; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + fmpz_randtest_not_zero(b, state, 200); + fmpz_mul(c, a, b); + + fmpz_get_mpz(d, b); + fmpz_get_mpz(e, c); + + fmpz_divexact(a, c, b); + mpz_divexact(f, e, d); + + fmpz_get_mpz(g, a); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + /* Check aliasing of a and b */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, c; + mpz_t d, f, g; + + fmpz_init(a); + fmpz_init(c); + + mpz_init(d); + mpz_init(f); + mpz_init(g); + + fmpz_randtest_not_zero(a, state, 200); + + fmpz_get_mpz(d, a); + + fmpz_divexact(c, a, a); + mpz_divexact(f, d, d); + + fmpz_get_mpz(g, c); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, f = %Zd, g = %Zd\n", d, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(c); + + mpz_clear(d); + mpz_clear(f); + mpz_clear(g); + } + + /* Test aliasing of a and c */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c; + mpz_t d, e, f, g; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + fmpz_randtest_not_zero(b, state, 200); + fmpz_mul(c, a, b); + + fmpz_get_mpz(d, c); + fmpz_get_mpz(e, b); + + fmpz_divexact(c, c, b); + mpz_divexact(f, d, e); + + fmpz_get_mpz(g, c); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + /* Test aliasing of b and c */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c; + mpz_t d, e, f, g; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + fmpz_randtest_not_zero(b, state, 200); + fmpz_mul(c, a, b); + + fmpz_get_mpz(d, c); + fmpz_get_mpz(e, b); + + fmpz_divexact(b, c, b); + mpz_divexact(f, d, e); + + fmpz_get_mpz(g, b); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-divexact2_uiui.c b/external/flint-2.4.3/fmpz/test/t-divexact2_uiui.c new file mode 100644 index 0000000..322f562 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-divexact2_uiui.c @@ -0,0 +1,138 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("divexact2_uiui...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, c; + mpz_t e, f, g; + ulong n, m; + + fmpz_init(a); + fmpz_init(c); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + n = n_randtest_not_zero(state); + m = n_randtest_not_zero(state); + + fmpz_mul_ui(c, a, n); + fmpz_mul_ui(c, c, m); + + fmpz_get_mpz(e, c); + + fmpz_divexact2_uiui(a, c, n, m); + + flint_mpz_divexact_ui(f, e, n); + flint_mpz_divexact_ui(f, f, m); + + fmpz_get_mpz(g, a); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("n = %wu, m = %wu, e = %Zd, f = %Zd, g = %Zd\n", + n, m, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(c); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + /* Test aliasing of a and c */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, c; + mpz_t d, f, g; + ulong n, m; + + fmpz_init(a); + fmpz_init(c); + mpz_init(d); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + n = n_randtest_not_zero(state); + m = n_randtest_not_zero(state); + fmpz_mul_ui(c, a, n); + fmpz_mul_ui(c, c, m); + + fmpz_get_mpz(d, c); + + fmpz_divexact2_uiui(c, c, n, m); + + flint_mpz_divexact_ui(f, d, n); + flint_mpz_divexact_ui(f, f, m); + + fmpz_get_mpz(g, c); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, n = %wu, m = %wu, f = %Zd, g = %Zd\n", + d, n, m, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(c); + mpz_clear(d); + mpz_clear(f); + mpz_clear(g); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-divexact_si.c b/external/flint-2.4.3/fmpz/test/t-divexact_si.c new file mode 100644 index 0000000..910ee52 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-divexact_si.c @@ -0,0 +1,131 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("divexact_si...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, c; + mpz_t e, f, g; + slong n; + + fmpz_init(a); + fmpz_init(c); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + n = z_randtest_not_zero(state); + fmpz_mul_si(c, a, n); + + fmpz_get_mpz(e, c); + + fmpz_divexact_si(a, c, n); + flint_mpz_divexact_ui(f, e, FLINT_ABS(n)); + if (n < 0) + mpz_neg(f, f); + + fmpz_get_mpz(g, a); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("n = %wd, e = %Zd, f = %Zd, g = %Zd\n", n, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(c); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + /* Test aliasing of a and c */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, c; + mpz_t d, f, g; + slong n; + + fmpz_init(a); + fmpz_init(c); + mpz_init(d); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + n = z_randtest_not_zero(state); + fmpz_mul_si(c, a, n); + + fmpz_get_mpz(d, c); + + fmpz_divexact_si(c, c, n); + flint_mpz_divexact_ui(f, d, FLINT_ABS(n)); + if (n < 0) + mpz_neg(f, f); + + fmpz_get_mpz(g, c); + + result = (mpz_cmp(f, g) == 0); + + if (!result) + { + flint_printf("FAIL;\n"); + gmp_printf("d = %Zd, n = %wd, f = %Zd, g = %Zd\n", d, n, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(c); + mpz_clear(d); + mpz_clear(f); + mpz_clear(g); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-divexact_ui.c b/external/flint-2.4.3/fmpz/test/t-divexact_ui.c new file mode 100644 index 0000000..e21f70c --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-divexact_ui.c @@ -0,0 +1,126 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("divexact_ui...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, c; + mpz_t e, f, g; + ulong n; + + fmpz_init(a); + fmpz_init(c); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + n = n_randtest_not_zero(state); + fmpz_mul_ui(c, a, n); + + fmpz_get_mpz(e, c); + + fmpz_divexact_ui(a, c, n); + flint_mpz_divexact_ui(f, e, n); + + fmpz_get_mpz(g, a); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL1\n"); + gmp_printf("n = %wu, e = %Zd, f = %Zd, g = %Zd\n", n, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(c); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + /* Test aliasing of a and c */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, c; + mpz_t d, f, g; + ulong n; + + fmpz_init(a); + fmpz_init(c); + mpz_init(d); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + n = n_randtest_not_zero(state); + fmpz_mul_ui(c, a, n); + + fmpz_get_mpz(d, c); + + fmpz_divexact_ui(c, c, n); + flint_mpz_divexact_ui(f, d, n); + + fmpz_get_mpz(g, c); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, n = %wu, f = %Zd, g = %Zd\n", d, n, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(c); + mpz_clear(d); + mpz_clear(f); + mpz_clear(g); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-divisible.c b/external/flint-2.4.3/fmpz/test/t-divisible.c new file mode 100644 index 0000000..62cc0dc --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-divisible.c @@ -0,0 +1,146 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("divisible...."); + fflush(stdout); + + + + /* Compare with MPIR: random */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t c, d; + int e, f; + + fmpz_init(a); + fmpz_init(b); + mpz_init(c); + mpz_init(d); + + fmpz_randtest_unsigned(a, state, 200); + fmpz_add_ui(a, a, 1); + fmpz_randtest(b, state, 200); + + fmpz_get_mpz(c, a); + fmpz_get_mpz(d, b); + + e = fmpz_divisible(b, a); + f = mpz_divisible_p(d, c); + + result = (e == f); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("c = %Zd, d = %Zd\n", c, d); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + mpz_clear(c); + mpz_clear(d); + } + + /* Compare with MPIR: b a multiple of a */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t c, d; + int e, f; + + fmpz_init(a); + fmpz_init(b); + mpz_init(c); + mpz_init(d); + + fmpz_randtest_unsigned(a, state, 200); + fmpz_add_ui(a, a, 1); + fmpz_randtest(b, state, 200); + fmpz_mul(b, a, b); + + fmpz_get_mpz(c, a); + fmpz_get_mpz(d, b); + + e = fmpz_divisible(b, a); + f = mpz_divisible_p(d, c); + + result = (e == f && e == 1); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("c = %Zd, d = %Zd\n", c, d); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + mpz_clear(c); + mpz_clear(d); + } + + /* Check aliasing */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_t a; + int b; + + fmpz_init(a); + + fmpz_randtest_unsigned(a, state, 200); + fmpz_add_ui(a, a, 1); + + b = fmpz_divisible(a, a); + + result = (b == 1); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpz_print(a); + abort(); + } + + fmpz_clear(a); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/fmpz/test/t-divisible_si.c b/external/flint-2.4.3/fmpz/test/t-divisible_si.c new file mode 100644 index 0000000..646aff2 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-divisible_si.c @@ -0,0 +1,120 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "long_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("divisible_si...."); + fflush(stdout); + + + + /* Compare with MPIR: random */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + slong a; + fmpz_t b; + mpz_t d; + int e, f; + + fmpz_init(b); + mpz_init(d); + + a = z_randtest(state); + if (a == WORD_MIN) + a = 1; + a = FLINT_ABS(a) + 1; + fmpz_randtest(b, state, 200); + + fmpz_get_mpz(d, b); + + e = fmpz_divisible_si(b, a); + f = flint_mpz_divisible_ui_p(d, a); + + result = (e == f); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = %wd, b = ", a), fmpz_print(b), flint_printf("\n"); + abort(); + } + + fmpz_clear(b); + mpz_clear(d); + } + + /* Compare with MPIR: b a multiple of a */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + slong a; + fmpz_t b; + mpz_t d; + int e, f; + + fmpz_init(b); + mpz_init(d); + + a = z_randtest(state); + if (a == WORD_MIN) + a = 1; + a = FLINT_ABS(a) + 1; + fmpz_randtest(b, state, 200); + fmpz_mul_ui(b, b, a); + + fmpz_get_mpz(d, b); + + e = fmpz_divisible_si(b, a); + f = flint_mpz_divisible_ui_p(d, a); + + result = (e == f && e == 1); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = %wd, b = ", a), fmpz_print(b), flint_printf("\n"); + abort(); + } + + fmpz_clear(b); + mpz_clear(d); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/fmpz/test/t-dlog.c b/external/flint-2.4.3/fmpz/test/t-dlog.c new file mode 100644 index 0000000..186607e --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-dlog.c @@ -0,0 +1,89 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("dlog...."); + fflush(stdout); + + + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_t x; + mpz_t z; + mpfr_t r; + double y, w; + + fmpz_init(x); + mpz_init(z); + mpfr_init2(r, 53); + + fmpz_randtest_not_zero(x, state, 10000); + fmpz_abs(x, x); + + y = fmpz_dlog(x); + + fmpz_get_mpz(z, x); + mpfr_set_z(r, z, MPFR_RNDN); + + mpfr_log(r, r, MPFR_RNDN); + w = mpfr_get_d(r, MPFR_RNDN); + + result = (FLINT_ABS(y - w) <= w * 1e-13); + + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("x = "), fmpz_print(x), flint_printf("\n"); + flint_printf("y = %.20g\n", y); + flint_printf("w = %.20g\n", w); + abort(); + } + + fmpz_clear(x); + mpz_clear(z); + mpfr_clear(r); + } + + mpfr_free_cache(); + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/fmpz/test/t-equal.c b/external/flint-2.4.3/fmpz/test/t-equal.c new file mode 100644 index 0000000..540f964 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-equal.c @@ -0,0 +1,103 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("equal...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + + fmpz_init(a); + fmpz_init(b); + + fmpz_randtest(a, state, 200); + fmpz_set(b, a); + + result = (fmpz_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpz_print(a), flint_printf("\n"); + flint_printf("b = "), fmpz_print(b), flint_printf("\n"); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + } + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t c, d; + + fmpz_init(a); + fmpz_init(b); + + mpz_init(c); + mpz_init(d); + + fmpz_randtest(a, state, 200); + fmpz_randtest(b, state, 200); + + fmpz_get_mpz(c, a); + fmpz_get_mpz(d, b); + + result = (fmpz_equal(a, b) == (mpz_cmp(c, d) == 0)); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("c = %Zd, d = %Zd\n", c, d); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + + mpz_clear(c); + mpz_clear(d); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-equal_si.c b/external/flint-2.4.3/fmpz/test/t-equal_si.c new file mode 100644 index 0000000..faa513f --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-equal_si.c @@ -0,0 +1,116 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "long_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("equal_si...."); + fflush(stdout); + + + + /* Compare with fmpz_equal, random values */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + slong n; + int lhs, rhs; + + fmpz_init(a); + fmpz_init(b); + + fmpz_randtest(a, state, 200); + + n = z_randtest(state); + fmpz_set_si(b, n); + + lhs = fmpz_equal(a, b); + rhs = fmpz_equal_si(a, n); + + result = (lhs == rhs); + if (result == 0) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpz_print(a), flint_printf("\n"); + flint_printf("b = "), fmpz_print(b), flint_printf("\n"); + flint_printf("n = %wd\n", n); + flint_printf("equal(a, b) = %d\n", fmpz_equal(a, b)); + flint_printf("equal_si(a, n) = %d\n", fmpz_equal_si(a, n)); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + } + + /* Compare with fmpz_equal, equal values */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + slong n; + int lhs, rhs; + + fmpz_init(a); + fmpz_init(b); + + n = z_randtest(state); + fmpz_set_si(a, n); + fmpz_set_si(b, n); + + lhs = fmpz_equal(a, b); + rhs = fmpz_equal_si(a, n); + + result = (lhs == rhs) && (lhs == 1); + if (result == 0) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpz_print(a), flint_printf("\n"); + flint_printf("b = "), fmpz_print(b), flint_printf("\n"); + flint_printf("n = %wd\n", n); + flint_printf("equal(a, b) = %d\n", fmpz_equal(a, b)); + flint_printf("equal_si(a, n) = %d\n", fmpz_equal_si(a, n)); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fmpz/test/t-equal_ui.c b/external/flint-2.4.3/fmpz/test/t-equal_ui.c new file mode 100644 index 0000000..4371dad --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-equal_ui.c @@ -0,0 +1,115 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("equal_ui...."); + fflush(stdout); + + + + /* Compare with fmpz_equal, random values */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + ulong n; + int lhs, rhs; + + fmpz_init(a); + fmpz_init(b); + + fmpz_randtest(a, state, 200); + + n = n_randtest(state); + fmpz_set_ui(b, n); + + lhs = fmpz_equal(a, b); + rhs = fmpz_equal_ui(a, n); + + result = (lhs == rhs); + if (result == 0) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpz_print(a), flint_printf("\n"); + flint_printf("b = "), fmpz_print(b), flint_printf("\n"); + flint_printf("n = %wu\n", n); + flint_printf("equal(a, b) = %d\n", fmpz_equal(a, b)); + flint_printf("equal_ui(a, n) = %d\n", fmpz_equal_ui(a, n)); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + } + + /* Compare with fmpz_equal, equal values */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + ulong n; + int lhs, rhs; + + fmpz_init(a); + fmpz_init(b); + + n = n_randtest(state); + fmpz_set_ui(a, n); + fmpz_set_ui(b, n); + + lhs = fmpz_equal(a, b); + rhs = fmpz_equal_ui(a, n); + + result = (lhs == rhs) && (lhs == 1); + if (result == 0) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpz_print(a), flint_printf("\n"); + flint_printf("b = "), fmpz_print(b), flint_printf("\n"); + flint_printf("n = %wu\n", n); + flint_printf("equal(a, b) = %d\n", fmpz_equal(a, b)); + flint_printf("equal_ui(a, n) = %d\n", fmpz_equal_ui(a, n)); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fmpz/test/t-fac_ui.c b/external/flint-2.4.3/fmpz/test/t-fac_ui.c new file mode 100644 index 0000000..b7cf77d --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-fac_ui.c @@ -0,0 +1,76 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + slong i, n; + fmpz_t x; + fmpz_t y; + + FLINT_TEST_INIT(state); + + flint_printf("fac_ui...."); + fflush(stdout); + + fmpz_init(x); + fmpz_init(y); + + /* Twice to check demotion */ + for (n = 0; n < 2; n++) + { + fmpz_set_ui(y, UWORD(1)); + + for (i = 0; i < 100; i++) + { + fmpz_fac_ui(x, i); + fmpz_mul_ui(y, y, FLINT_MAX(1, i)); + if (!fmpz_equal(x, y)) + { + flint_printf("FAIL: %wd\n", i); + fmpz_print(x); + flint_printf("\n"); + fmpz_print(y); + flint_printf("\n"); + abort(); + } + } + } + + fmpz_clear(x); + fmpz_clear(y); + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-fdiv_q.c b/external/flint-2.4.3/fmpz/test/t-fdiv_q.c new file mode 100644 index 0000000..c9bc33a --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-fdiv_q.c @@ -0,0 +1,213 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("fdiv_q...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c; + mpz_t d, e, f, g; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + fmpz_randtest_not_zero(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_fdiv_q(c, a, b); + mpz_fdiv_q(f, d, e); + + fmpz_get_mpz(g, c); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + /* Check aliasing of a and b */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, c; + mpz_t d, f, g; + + fmpz_init(a); + fmpz_init(c); + + mpz_init(d); + mpz_init(f); + mpz_init(g); + + fmpz_randtest_not_zero(a, state, 200); + + fmpz_get_mpz(d, a); + + fmpz_fdiv_q(c, a, a); + mpz_fdiv_q(f, d, d); + + fmpz_get_mpz(g, c); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, f = %Zd, g = %Zd\n", d, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(c); + + mpz_clear(d); + mpz_clear(f); + mpz_clear(g); + } + + /* Test aliasing of a and c */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t d, e, f, g; + + fmpz_init(a); + fmpz_init(b); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + fmpz_randtest_not_zero(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_fdiv_q(a, a, b); + mpz_fdiv_q(f, d, e); + + fmpz_get_mpz(g, a); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + /* Test aliasing of b and c */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t d, e, f, g; + + fmpz_init(a); + fmpz_init(b); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + fmpz_randtest_not_zero(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_fdiv_q(b, a, b); + mpz_fdiv_q(f, d, e); + + fmpz_get_mpz(g, b); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-fdiv_q_2exp.c b/external/flint-2.4.3/fmpz/test/t-fdiv_q_2exp.c new file mode 100644 index 0000000..864dc80 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-fdiv_q_2exp.c @@ -0,0 +1,125 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("fdiv_q_2exp...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t d, e, f; + ulong x; + + fmpz_init(a); + fmpz_init(b); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + + fmpz_randtest(a, state, 200); + + fmpz_get_mpz(d, a); + x = n_randint(state, 200); + + fmpz_fdiv_q_2exp(b, a, x); + mpz_fdiv_q_2exp(e, d, x); + + fmpz_get_mpz(f, b); + + result = (mpz_cmp(e, f) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, exp = %wu\n", d, e, f, x); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + } + + /* Check aliasing of a and b */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a; + mpz_t d, e, f; + ulong x; + + fmpz_init(a); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + + fmpz_randtest(a, state, 200); + + fmpz_get_mpz(d, a); + x = n_randint(state, 200); + + fmpz_fdiv_q_2exp(a, a, x); + mpz_fdiv_q_2exp(e, d, x); + + fmpz_get_mpz(f, a); + + result = (mpz_cmp(e, f) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, exp = %wu\n", d, e, f, x); + abort(); + } + + fmpz_clear(a); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-fdiv_q_si.c b/external/flint-2.4.3/fmpz/test/t-fdiv_q_si.c new file mode 100644 index 0000000..99ed719 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-fdiv_q_si.c @@ -0,0 +1,131 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("fdiv_q_si...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + slong b; + fmpz_t a, c; + mpz_t d, e, f, g; + + fmpz_init(a); + fmpz_init(c); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + b = z_randtest_not_zero(state); + + fmpz_get_mpz(d, a); + flint_mpz_set_si(e, b); + + fmpz_fdiv_q_si(c, a, b); + mpz_fdiv_q(f, d, e); + + fmpz_get_mpz(g, c); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL (1):\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(c); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + /* Test aliasing of a and c */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + slong b; + fmpz_t a; + mpz_t d, e, f, g; + + fmpz_init(a); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + b = z_randtest_not_zero(state); + + fmpz_get_mpz(d, a); + flint_mpz_set_si(e, b); + + fmpz_fdiv_q_si(a, a, b); + mpz_fdiv_q(f, d, e); + + fmpz_get_mpz(g, a); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL (2):\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-fdiv_q_ui.c b/external/flint-2.4.3/fmpz/test/t-fdiv_q_ui.c new file mode 100644 index 0000000..af840e1 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-fdiv_q_ui.c @@ -0,0 +1,131 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("fdiv_q_ui...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + ulong b; + fmpz_t a, c; + mpz_t d, e, f, g; + + fmpz_init(a); + fmpz_init(c); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + b = n_randtest_not_zero(state); + + fmpz_get_mpz(d, a); + flint_mpz_set_ui(e, b); + + fmpz_fdiv_q_ui(c, a, b); + mpz_fdiv_q(f, d, e); + + fmpz_get_mpz(g, c); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL (1):\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(c); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + /* Test aliasing of a and c */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + ulong b; + fmpz_t a; + mpz_t d, e, f, g; + + fmpz_init(a); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + b = n_randtest_not_zero(state); + + fmpz_get_mpz(d, a); + flint_mpz_set_ui(e, b); + + fmpz_fdiv_q_ui(a, a, b); + mpz_fdiv_q(f, d, e); + + fmpz_get_mpz(g, a); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL (2):\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-fdiv_qr.c b/external/flint-2.4.3/fmpz/test/t-fdiv_qr.c new file mode 100644 index 0000000..dc8276f --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-fdiv_qr.c @@ -0,0 +1,317 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("fdiv_qr...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c, r; + mpz_t d, e, f, g, h, s; + slong j; + + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + fmpz_init(r); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + mpz_init(h); + mpz_init(s); + + fmpz_randbits(a, state, 1000); + do { + fmpz_randbits(b, state, 500); + } while(fmpz_is_zero(b)); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + for (j = 1; j < 100; j++) + fmpz_fdiv_qr(c, r, a, b); + mpz_fdiv_qr(f, s, d, e); + + fmpz_get_mpz(g, c); + fmpz_get_mpz(h, r); + + result = (mpz_cmp(f, g) == 0 && mpz_cmp(h, s) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf + ("d = %Zd, e = %Zd, f = %Zd, g = %Zd, h = %Zd, s = %Zd\n", d, + e, f, g, h, s); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + fmpz_clear(r); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + mpz_clear(h); + mpz_clear(s); + } + + /* Check aliasing of c and a */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c, r; + mpz_t d, e, f, g, h, s; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + fmpz_init(r); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + mpz_init(h); + mpz_init(s); + + fmpz_randtest(a, state, 200); + fmpz_randtest_not_zero(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_fdiv_qr(a, r, a, b); + mpz_fdiv_qr(f, s, d, e); + + fmpz_get_mpz(g, a); + fmpz_get_mpz(h, r); + + result = (mpz_cmp(f, g) == 0 && mpz_cmp(h, s) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf + ("d = %Zd, e = %Zd, f = %Zd, g = %Zd, h = %Zd, s = %Zd\n", d, + e, f, g, h, s); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + fmpz_clear(r); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + mpz_clear(h); + mpz_clear(s); + } + + /* Check aliasing of c and b */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c, r; + mpz_t d, e, f, g, h, s; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + fmpz_init(r); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + mpz_init(h); + mpz_init(s); + + fmpz_randtest(a, state, 200); + fmpz_randtest_not_zero(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_fdiv_qr(b, r, a, b); + mpz_fdiv_qr(f, s, d, e); + + fmpz_get_mpz(g, b); + fmpz_get_mpz(h, r); + + result = (mpz_cmp(f, g) == 0 && mpz_cmp(h, s) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf + ("d = %Zd, e = %Zd, f = %Zd, g = %Zd, h = %Zd, s = %Zd\n", d, + e, f, g, h, s); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + fmpz_clear(r); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + mpz_clear(h); + mpz_clear(s); + } + + /* Check aliasing of r and a */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c, r; + mpz_t d, e, f, g, h, s; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + fmpz_init(r); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + mpz_init(h); + mpz_init(s); + + fmpz_randtest(a, state, 200); + fmpz_randtest_not_zero(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_fdiv_qr(c, a, a, b); + mpz_fdiv_qr(f, s, d, e); + + fmpz_get_mpz(g, c); + fmpz_get_mpz(h, a); + + result = (mpz_cmp(f, g) == 0 && mpz_cmp(h, s) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf + ("d = %Zd, e = %Zd, f = %Zd, g = %Zd, h = %Zd, s = %Zd\n", d, + e, f, g, h, s); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + fmpz_clear(r); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + mpz_clear(h); + mpz_clear(s); + } + + /* Check aliasing of r and b */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c, r; + mpz_t d, e, f, g, h, s; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + fmpz_init(r); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + mpz_init(h); + mpz_init(s); + + fmpz_randtest(a, state, 200); + fmpz_randtest_not_zero(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_fdiv_qr(c, b, a, b); + mpz_fdiv_qr(f, s, d, e); + + fmpz_get_mpz(g, c); + fmpz_get_mpz(h, b); + + result = (mpz_cmp(f, g) == 0 && mpz_cmp(h, s) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf + ("d = %Zd, e = %Zd, f = %Zd, g = %Zd, h = %Zd, s = %Zd\n", d, + e, f, g, h, s); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + fmpz_clear(r); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + mpz_clear(h); + mpz_clear(s); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-fdiv_qr_preinvn.c b/external/flint-2.4.3/fmpz/test/t-fdiv_qr_preinvn.c new file mode 100644 index 0000000..f5e912a --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-fdiv_qr_preinvn.c @@ -0,0 +1,327 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("fdiv_qr_preinvn...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c, r; + mpz_t d, e, f, g, h, s; + fmpz_preinvn_t inv; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + fmpz_init(r); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + mpz_init(h); + mpz_init(s); + + fmpz_randtest(a, state, 400); + fmpz_randtest_not_zero(b, state, 400); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_preinvn_init(inv, b); + fmpz_fdiv_qr_preinvn(c, r, a, b, inv); + mpz_fdiv_qr(f, s, d, e); + + fmpz_get_mpz(g, c); + fmpz_get_mpz(h, r); + + result = (mpz_cmp(f, g) == 0 && mpz_cmp(h, s) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf + ("d = %Zd, e = %Zd, f = %Zd, g = %Zd, h = %Zd, s = %Zd\n", d, + e, f, g, h, s); + abort(); + } + + fmpz_preinvn_clear(inv); + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + fmpz_clear(r); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + mpz_clear(h); + mpz_clear(s); + } + + /* Check aliasing of c and a */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c, r; + mpz_t d, e, f, g, h, s; + fmpz_preinvn_t inv; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + fmpz_init(r); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + mpz_init(h); + mpz_init(s); + + fmpz_randtest(a, state, 200); + fmpz_randtest_not_zero(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_preinvn_init(inv, b); + fmpz_fdiv_qr_preinvn(a, r, a, b, inv); + mpz_fdiv_qr(f, s, d, e); + + fmpz_get_mpz(g, a); + fmpz_get_mpz(h, r); + + result = (mpz_cmp(f, g) == 0 && mpz_cmp(h, s) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf + ("d = %Zd, e = %Zd, f = %Zd, g = %Zd, h = %Zd, s = %Zd\n", d, + e, f, g, h, s); + abort(); + } + + fmpz_preinvn_clear(inv); + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + fmpz_clear(r); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + mpz_clear(h); + mpz_clear(s); + } + + /* Check aliasing of c and b */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c, r; + mpz_t d, e, f, g, h, s; + fmpz_preinvn_t inv; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + fmpz_init(r); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + mpz_init(h); + mpz_init(s); + + fmpz_randtest(a, state, 200); + fmpz_randtest_not_zero(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_preinvn_init(inv, b); + fmpz_fdiv_qr_preinvn(b, r, a, b, inv); + mpz_fdiv_qr(f, s, d, e); + + fmpz_get_mpz(g, b); + fmpz_get_mpz(h, r); + + result = (mpz_cmp(f, g) == 0 && mpz_cmp(h, s) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf + ("d = %Zd, e = %Zd, f = %Zd, g = %Zd, h = %Zd, s = %Zd\n", d, + e, f, g, h, s); + abort(); + } + + fmpz_preinvn_clear(inv); + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + fmpz_clear(r); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + mpz_clear(h); + mpz_clear(s); + } + + /* Check aliasing of r and a */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c, r; + mpz_t d, e, f, g, h, s; + fmpz_preinvn_t inv; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + fmpz_init(r); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + mpz_init(h); + mpz_init(s); + + fmpz_randtest(a, state, 200); + fmpz_randtest_not_zero(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_preinvn_init(inv, b); + fmpz_fdiv_qr_preinvn(c, a, a, b, inv); + mpz_fdiv_qr(f, s, d, e); + + fmpz_get_mpz(g, c); + fmpz_get_mpz(h, a); + + result = (mpz_cmp(f, g) == 0 && mpz_cmp(h, s) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf + ("d = %Zd, e = %Zd, f = %Zd, g = %Zd, h = %Zd, s = %Zd\n", d, + e, f, g, h, s); + abort(); + } + + fmpz_preinvn_clear(inv); + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + fmpz_clear(r); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + mpz_clear(h); + mpz_clear(s); + } + + /* Check aliasing of r and b */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c, r; + mpz_t d, e, f, g, h, s; + fmpz_preinvn_t inv; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + fmpz_init(r); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + mpz_init(h); + mpz_init(s); + + fmpz_randtest(a, state, 200); + fmpz_randtest_not_zero(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_preinvn_init(inv, b); + fmpz_fdiv_qr_preinvn(c, b, a, b, inv); + mpz_fdiv_qr(f, s, d, e); + + fmpz_get_mpz(g, c); + fmpz_get_mpz(h, b); + + result = (mpz_cmp(f, g) == 0 && mpz_cmp(h, s) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf + ("d = %Zd, e = %Zd, f = %Zd, g = %Zd, h = %Zd, s = %Zd\n", d, + e, f, g, h, s); + abort(); + } + + fmpz_preinvn_clear(inv); + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + fmpz_clear(r); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + mpz_clear(h); + mpz_clear(s); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-fdiv_r.c b/external/flint-2.4.3/fmpz/test/t-fdiv_r.c new file mode 100644 index 0000000..2de739a --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-fdiv_r.c @@ -0,0 +1,213 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("fdiv_r...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c; + mpz_t d, e, f, g; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + fmpz_randtest_not_zero(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_fdiv_r(c, a, b); + mpz_fdiv_r(f, d, e); + + fmpz_get_mpz(g, c); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + /* Check aliasing of a and b */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, c; + mpz_t d, f, g; + + fmpz_init(a); + fmpz_init(c); + + mpz_init(d); + mpz_init(f); + mpz_init(g); + + fmpz_randtest_not_zero(a, state, 200); + + fmpz_get_mpz(d, a); + + fmpz_fdiv_r(c, a, a); + mpz_fdiv_r(f, d, d); + + fmpz_get_mpz(g, c); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, f = %Zd, g = %Zd\n", d, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(c); + + mpz_clear(d); + mpz_clear(f); + mpz_clear(g); + } + + /* Test aliasing of a and c */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t d, e, f, g; + + fmpz_init(a); + fmpz_init(b); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + fmpz_randtest_not_zero(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_fdiv_r(a, a, b); + mpz_fdiv_r(f, d, e); + + fmpz_get_mpz(g, a); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + /* Test aliasing of b and c */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t d, e, f, g; + + fmpz_init(a); + fmpz_init(b); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + fmpz_randtest_not_zero(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_fdiv_r(b, a, b); + mpz_fdiv_r(f, d, e); + + fmpz_get_mpz(g, b); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-fdiv_r_2exp.c b/external/flint-2.4.3/fmpz/test/t-fdiv_r_2exp.c new file mode 100644 index 0000000..aba0149 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-fdiv_r_2exp.c @@ -0,0 +1,127 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("fdiv_r_2exp...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t d, e, f; + ulong x; + + fmpz_init(a); + fmpz_init(b); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + + fmpz_randtest(a, state, 200); + + fmpz_get_mpz(d, a); + x = n_randint(state, 200); + + fmpz_fdiv_r_2exp(b, a, x); + mpz_fdiv_r_2exp(e, d, x); + + fmpz_get_mpz(f, b); + + result = (mpz_cmp(e, f) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, exp = %wu\n", d, e, f, x); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + } + + /* Check aliasing of a and b */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a; + mpz_t d, e, f; + ulong x; + + fmpz_init(a); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + + fmpz_randtest(a, state, 200); + + fmpz_get_mpz(d, a); + x = n_randint(state, 200); + + fmpz_fdiv_r_2exp(a, a, x); + mpz_fdiv_r_2exp(e, d, x); + + fmpz_get_mpz(f, a); + + result = (mpz_cmp(e, f) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, exp = %wu\n", d, e, f, x); + abort(); + } + + fmpz_clear(a); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/fmpz/test/t-fdiv_ui.c b/external/flint-2.4.3/fmpz/test/t-fdiv_ui.c new file mode 100644 index 0000000..920dab5 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-fdiv_ui.c @@ -0,0 +1,78 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("fdiv_ui...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a; + mpz_t b; + ulong x, r1, r2; + + fmpz_init(a); + mpz_init(b); + + fmpz_randtest(a, state, 200); + + fmpz_get_mpz(b, a); + x = n_randtest_not_zero(state); + + r1 = fmpz_fdiv_ui(a, x); + r2 = flint_mpz_fdiv_ui(b, x); + + result = (r1 == r2); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf + ("b = %Zd, x = %wu, r1 = %wu, r2 = %wu\n", b, x, r1, r2); + abort(); + } + + fmpz_clear(a); + mpz_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-fib_ui.c b/external/flint-2.4.3/fmpz/test/t-fib_ui.c new file mode 100644 index 0000000..97053d2 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-fib_ui.c @@ -0,0 +1,82 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + slong i, n; + fmpz_t x, y, z, w; + + FLINT_TEST_INIT(state); + + flint_printf("fib_ui...."); + fflush(stdout); + + fmpz_init(x); + fmpz_init(y); + fmpz_init(z); + fmpz_init(w); + + /* Twice to check demotion */ + for (n = 0; n < 2; n++) + { + for (i = 0; i < 200; i++) + { + fmpz_fib_ui(x, i); + fmpz_fib_ui(y, i+1); + fmpz_fib_ui(z, i+2); + fmpz_add(w, x, y); + + if (!fmpz_equal(w, z)) + { + flint_printf("FAIL: %wd\n", i); + fmpz_print(x); + flint_printf("\n"); + fmpz_print(y); + flint_printf("\n"); + fmpz_print(z); + flint_printf("\n"); + abort(); + } + } + } + + fmpz_clear(x); + fmpz_clear(y); + fmpz_clear(z); + fmpz_clear(w); + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-fits_si.c b/external/flint-2.4.3/fmpz/test/t-fits_si.c new file mode 100644 index 0000000..ae872a9 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-fits_si.c @@ -0,0 +1,101 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +static void check(fmpz_t x, int expected) +{ + if (fmpz_fits_si(x) != expected) + { + flint_printf("FAIL:\n\n"); + flint_printf("x = "), fmpz_print(x), flint_printf("\n"); + flint_printf("fmpz_fits_si(x) = %d\n", fmpz_fits_si(x)); + flint_printf("WORD_MIN = %wd\n", WORD_MIN); + abort(); + } +} + +int +main(void) +{ + slong i; + fmpz_t x; + + FLINT_TEST_INIT(state); + + flint_printf("fits_si...."); + fflush(stdout); + + fmpz_init(x); + + fmpz_set_si(x, COEFF_MIN); + check(x, 1); + + fmpz_set_si(x, COEFF_MAX); + check(x, 1); + + fmpz_set_si(x, WORD_MAX); + check(x, 1); + + fmpz_set_si(x, WORD_MIN); + check(x, 1); + + fmpz_set_ui(x, UWORD_MAX); + check(x, 0); + + fmpz_set_ui(x, UWORD_MAX); + fmpz_neg(x, x); + check(x, 0); + + fmpz_set_si(x, WORD_MAX); + fmpz_add_ui(x, x, 1); + check(x, 0); + + fmpz_set_si(x, WORD_MIN); + fmpz_sub_ui(x, x, 1); + check(x, 0); + + for (i = 0; i < 1000; i++) + { + fmpz_set_ui(x, 1); + fmpz_mul_2exp(x, x, i); + check(x, i < FLINT_BITS - 1); + fmpz_neg(x, x); + check(x, i < FLINT_BITS); /* WORD_MIN fits */ + } + + fmpz_clear(x); + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fmpz/test/t-flog.c b/external/flint-2.4.3/fmpz/test/t-flog.c new file mode 100644 index 0000000..cf530d6 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-flog.c @@ -0,0 +1,144 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("flog...."); + fflush(stdout); + + + + /* Check aliasing */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a; + slong l; + + fmpz_init(a); + + while (fmpz_cmp_ui(a, 2) < 0) + fmpz_randtest(a, state, 200); + + l = fmpz_flog(a, a); + + result = (l == 1); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpz_print(a), flint_printf("\n"); + flint_printf("l = %wd\n", l); + abort(); + } + + fmpz_clear(a); + } + + /* Check correctness */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, x, y; + slong k; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(x); + fmpz_init(y); + + while (fmpz_cmp_ui(a, 1) < 0) + fmpz_randtest(a, state, 200); + while (fmpz_cmp_ui(b, 2) < 0) + fmpz_randtest(b, state, 200); + + k = fmpz_flog(a, b); + + fmpz_pow_ui(x, b, k); + fmpz_pow_ui(y, b, k + 1); + + result = (fmpz_cmp(x, a) <= 0 && fmpz_cmp(a, y) < 0); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpz_print(a), flint_printf("\n"); + flint_printf("b = "), fmpz_print(b), flint_printf("\n"); + flint_printf("x = "), fmpz_print(x), flint_printf("\n"); + flint_printf("y = "), fmpz_print(y), flint_printf("\n"); + flint_printf("k = %wd\n", k); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(x); + fmpz_clear(y); + } + + /* Check correctness: exact powers */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + slong k, l; + + fmpz_init(a); + fmpz_init(b); + + while (fmpz_cmp_ui(b, 2) < 0) + fmpz_randtest(b, state, 200); + l = n_randint(state, 20); + fmpz_pow_ui(a, b, l); + + k = fmpz_flog(a, b); + + result = (k == l); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpz_print(a), flint_printf("\n"); + flint_printf("b = "), fmpz_print(b), flint_printf("\n"); + flint_printf("k = %wd\n", k); + flint_printf("l = %wd\n", l); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/fmpz/test/t-flog_ui.c b/external/flint-2.4.3/fmpz/test/t-flog_ui.c new file mode 100644 index 0000000..4ecb4c2 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-flog_ui.c @@ -0,0 +1,119 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("flog_ui...."); + fflush(stdout); + + + + /* Check correctness */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, x, y; + slong k; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(x); + fmpz_init(y); + + while (fmpz_cmp_ui(a, 1) < 0) + fmpz_randtest(a, state, 200); + while (fmpz_cmp_ui(b, 2) < 0) + fmpz_set_ui(b, n_randtest(state)); + + k = fmpz_flog_ui(a, fmpz_get_ui(b)); + + fmpz_pow_ui(x, b, k); + fmpz_pow_ui(y, b, k + 1); + + result = (fmpz_cmp(x, a) <= 0 && fmpz_cmp(a, y) < 0); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpz_print(a), flint_printf("\n"); + flint_printf("b = "), fmpz_print(b), flint_printf("\n"); + flint_printf("x = "), fmpz_print(x), flint_printf("\n"); + flint_printf("y = "), fmpz_print(y), flint_printf("\n"); + flint_printf("k = %wd\n", k); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(x); + fmpz_clear(y); + } + + /* Check correctness: exact powers */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + slong k, l; + + fmpz_init(a); + fmpz_init(b); + + while (fmpz_cmp_ui(b, 2) < 0) + fmpz_set_ui(b, n_randtest(state)); + l = n_randint(state, 20); + fmpz_pow_ui(a, b, l); + + k = fmpz_flog_ui(a, fmpz_get_ui(b)); + + result = (k == l); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpz_print(a), flint_printf("\n"); + flint_printf("b = "), fmpz_print(b), flint_printf("\n"); + flint_printf("k = %wd\n", k); + flint_printf("l = %wd\n", l); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/fmpz/test/t-fmpz.c b/external/flint-2.4.3/fmpz/test/t-fmpz.c new file mode 100644 index 0000000..9d29127 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-fmpz.c @@ -0,0 +1,70 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("fmpz...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + + *a = WORD(0); + + fmpz_randtest(a, state, FLINT_BITS - 2); + + *b = *a; + + _fmpz_promote_val(a); + _fmpz_demote_val(a); + + result = (*b == *a); + + if (!result) + { + flint_printf("FAIL\n"); + abort(); + } + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-fmpz_cleanup.c b/external/flint-2.4.3/fmpz/test/t-fmpz_cleanup.c new file mode 100644 index 0000000..42044d6 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-fmpz_cleanup.c @@ -0,0 +1,79 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 "fmpz.h" +#include "fmpz_vec.h" +#include "flint.h" +#include "ulong_extras.h" + +int +main(void) +{ + slong iter; + FLINT_TEST_INIT(state); + + flint_printf("fmpz_cleanup...."); + fflush(stdout); + + + + for (iter = 0; iter < 300 * flint_test_multiplier(); iter++) + { + slong i, n; + fmpz *A, *B; + + n = n_randint(state, 100); + A = _fmpz_vec_init(n); + B = _fmpz_vec_init(n); + + for (i = 0; i < n; i++) + { + fmpz_randtest(A + i, state, 1 + n_randint(state, 1000)); + fmpz_randtest(B + i, state, 1 + n_randint(state, 1000)); + } + + for (i = 0; i < n; i++) + { + fmpz_addmul(A + n_randint(state, n), + A + n_randint(state, n), B + n_randint(state, n)); + fmpz_addmul(B + n_randint(state, n), + A + n_randint(state, n), B + n_randint(state, n)); + + if (n_randint(state, 10) == 0) + { + + } + } + + _fmpz_vec_clear(A, n); + _fmpz_vec_clear(B, n); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} + diff --git a/external/flint-2.4.3/fmpz/test/t-gcd.c b/external/flint-2.4.3/fmpz/test/t-gcd.c new file mode 100644 index 0000000..e25e696 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-gcd.c @@ -0,0 +1,226 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("gcd...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c; + mpz_t d, e, f, g; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + fmpz_randtest(b, state, 200); + fmpz_randtest(c, state, 200); + fmpz_mul(a, a, c); + fmpz_mul(b, b, c); + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_gcd(c, a, b); + mpz_gcd(f, d, e); + + fmpz_get_mpz(g, c); + + result = (mpz_cmp(f, g) == 0); + + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + /* Check aliasing of a and b */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, c; + mpz_t d, f, g; + + fmpz_init(a); + fmpz_init(c); + + mpz_init(d); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + + fmpz_get_mpz(d, a); + + fmpz_gcd(c, a, a); + mpz_gcd(f, d, d); + + fmpz_get_mpz(g, c); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, f = %Zd, g = %Zd\n", d, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(c); + + mpz_clear(d); + mpz_clear(f); + mpz_clear(g); + } + + /* Test aliasing of a and c */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c; + mpz_t d, e, f, g; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + fmpz_randtest(b, state, 200); + fmpz_randtest(c, state, 200); + fmpz_mul(a, a, c); + fmpz_mul(b, b, c); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_gcd(a, a, b); + mpz_gcd(f, d, e); + + fmpz_get_mpz(g, a); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + /* Test aliasing of b and c */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c; + mpz_t d, e, f, g; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + fmpz_randtest(b, state, 200); + fmpz_randtest(c, state, 200); + fmpz_mul(a, a, c); + fmpz_mul(b, b, c); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_gcd(b, a, b); + mpz_gcd(f, d, e); + + fmpz_get_mpz(g, b); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-gcdinv.c b/external/flint-2.4.3/fmpz/test/t-gcdinv.c new file mode 100644 index 0000000..ed9f30d --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-gcdinv.c @@ -0,0 +1,218 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("gcdinv...."); + fflush(stdout); + + + + /* Test aliasing of d and f, a and g */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_t d, a, f, g, F, G; + + fmpz_init(d); + fmpz_init(a); + fmpz_init(f); + fmpz_init(g); + fmpz_init(F); + fmpz_init(G); + + fmpz_randtest_unsigned(G, state, 200); + fmpz_add_ui(G, G, 1); + fmpz_randm(F, state, G); + fmpz_set(f, F); + fmpz_set(g, G); + + fmpz_gcdinv(d, a, f, g); + fmpz_gcdinv(f, g, f, g); + + result = (fmpz_equal(d, f) && (fmpz_equal(a, g) || fmpz_is_zero(F))); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("d = "), fmpz_print(d), flint_printf("\n"); + flint_printf("a = "), fmpz_print(a), flint_printf("\n"); + flint_printf("f = "), fmpz_print(f), flint_printf("\n"); + flint_printf("g = "), fmpz_print(g), flint_printf("\n"); + flint_printf("F = "), fmpz_print(F), flint_printf("\n"); + flint_printf("G = "), fmpz_print(G), flint_printf("\n"); + abort(); + } + + fmpz_clear(d); + fmpz_clear(a); + fmpz_clear(f); + fmpz_clear(g); + fmpz_clear(F); + fmpz_clear(G); + } + + /* Test aliasing of a and f, d and g */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_t d, a, f, g, F, G; + + fmpz_init(d); + fmpz_init(a); + fmpz_init(f); + fmpz_init(g); + fmpz_init(F); + fmpz_init(G); + + fmpz_randtest_unsigned(G, state, 200); + fmpz_add_ui(G, G, 1); + fmpz_randm(F, state, G); + fmpz_set(f, F); + fmpz_set(g, G); + + fmpz_gcdinv(d, a, f, g); + fmpz_gcdinv(g, f, f, g); + + result = (fmpz_equal(d, g) && (fmpz_equal(a, f) || fmpz_is_zero(F))); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("d = "), fmpz_print(d), flint_printf("\n"); + flint_printf("a = "), fmpz_print(a), flint_printf("\n"); + flint_printf("f = "), fmpz_print(f), flint_printf("\n"); + flint_printf("g = "), fmpz_print(g), flint_printf("\n"); + flint_printf("F = "), fmpz_print(F), flint_printf("\n"); + flint_printf("G = "), fmpz_print(G), flint_printf("\n"); + abort(); + } + + fmpz_clear(d); + fmpz_clear(a); + fmpz_clear(f); + fmpz_clear(g); + fmpz_clear(F); + fmpz_clear(G); + } + + /* Test a f == d mod g (generically d == 1) */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_t d, a, f, g, t; + + fmpz_init(d); + fmpz_init(a); + fmpz_init(f); + fmpz_init(g); + fmpz_init(t); + + fmpz_randtest_unsigned(g, state, 200); + fmpz_add_ui(g, g, 1); + fmpz_randm(f, state, g); + + fmpz_gcdinv(d, a, f, g); + + fmpz_mul(t, a, f); + fmpz_mod(t, t, g); + + result = (fmpz_equal(t, d) || fmpz_is_zero(f)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("d = "), fmpz_print(d), flint_printf("\n"); + flint_printf("a = "), fmpz_print(a), flint_printf("\n"); + flint_printf("f = "), fmpz_print(f), flint_printf("\n"); + flint_printf("g = "), fmpz_print(g), flint_printf("\n"); + flint_printf("t = "), fmpz_print(t), flint_printf("\n"); + abort(); + } + + fmpz_clear(d); + fmpz_clear(a); + fmpz_clear(f); + fmpz_clear(g); + fmpz_clear(t); + } + + /* Test a f == d mod g (specifically d > 1) */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_t d, a, f, g, t, x; + + fmpz_init(d); + fmpz_init(a); + fmpz_init(f); + fmpz_init(g); + fmpz_init(t); + fmpz_init(x); + + fmpz_randtest_unsigned(g, state, 200); + fmpz_add_ui(g, g, 1); + fmpz_randm(f, state, g); + fmpz_randtest_unsigned(x, state, 100); + fmpz_add_ui(x, x, 1); + fmpz_mul(f, f, x); + fmpz_mul(g, g, x); + + fmpz_gcdinv(d, a, f, g); + + fmpz_mul(t, a, f); + fmpz_mod(t, t, g); + + result = (fmpz_equal(t, d) || fmpz_is_zero(f)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("d = "), fmpz_print(d), flint_printf("\n"); + flint_printf("a = "), fmpz_print(a), flint_printf("\n"); + flint_printf("f = "), fmpz_print(f), flint_printf("\n"); + flint_printf("g = "), fmpz_print(g), flint_printf("\n"); + flint_printf("t = "), fmpz_print(t), flint_printf("\n"); + flint_printf("x = "), fmpz_print(x), flint_printf("\n"); + abort(); + } + + fmpz_clear(d); + fmpz_clear(a); + fmpz_clear(f); + fmpz_clear(g); + fmpz_clear(t); + fmpz_clear(x); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} + diff --git a/external/flint-2.4.3/fmpz/test/t-get_d.c b/external/flint-2.4.3/fmpz/test/t-get_d.c new file mode 100644 index 0000000..74ab6f0 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-get_d.c @@ -0,0 +1,97 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("get_d...."); + fflush(stdout); + + + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_t x, y; + mpz_t z; + double a, b; + + fmpz_init(x); + fmpz_init(y); + mpz_init(z); + + fmpz_randtest(x, state, 200); + fmpz_get_mpz(z, x); + + a = fmpz_get_d(x); + b = mpz_get_d(z); + + result = (a == b); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("x = "), fmpz_print(x), flint_printf("\n"); + flint_printf("a = %f\n", a); + flint_printf("b = %f\n", b); + abort(); + } + + a = a * (n_randtest(state) / (double) n_randtest_not_zero(state)); + + fmpz_set_d(x, a); + mpz_set_d(z, a); + + fmpz_set_mpz(y, z); + result = fmpz_equal(x, y); + + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("x = "), fmpz_print(x), flint_printf("\n"); + flint_printf("y = "), fmpz_print(y), flint_printf("\n"); + flint_printf("a = %f\n", a); + abort(); + } + + fmpz_clear(x); + fmpz_clear(y); + mpz_clear(z); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-get_d_2exp.c b/external/flint-2.4.3/fmpz/test/t-get_d_2exp.c new file mode 100644 index 0000000..67c6f8f --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-get_d_2exp.c @@ -0,0 +1,74 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2009 Andy Novocin + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + + double output; + slong exp; + + FLINT_TEST_INIT(state); + + flint_printf("get_d_2exp...."); + fflush(stdout); + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_t a; + fmpz_init(a); + + fmpz_randtest(a, state, 200); + + output = fmpz_get_d_2exp(&exp, a); + + result = (fmpz_bits(a) == exp); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpz_print(a), flint_printf("\n"); + flint_printf("output = %f\n", output); + flint_printf("exp = %wd, bits = %wu\n", exp, fmpz_bits(a)); + abort(); + } + + fmpz_clear(a); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-get_mpz.c b/external/flint-2.4.3/fmpz/test/t-get_mpz.c new file mode 100644 index 0000000..318f15f --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-get_mpz.c @@ -0,0 +1,84 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + + FLINT_TEST_INIT(state); + + + flint_printf("get/set_mpz...."); + fflush(stdout); + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a; + mpz_t b, c; + mp_bitcnt_t bits; + + mpz_init(b); + mpz_init(c); + + bits = n_randint(state, 200) + 1; + + _flint_rand_init_gmp(state); + mpz_rrandomb(b, state->gmp_state, bits); + + if (n_randint(state, 2)) + mpz_neg(b, b); + + fmpz_init(a); + + fmpz_set_mpz(a, b); + fmpz_get_mpz(c, a); + + result = (mpz_cmp(b, c) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("b = %Zd, c = %Zd\n", b, c); + abort(); + } + + fmpz_clear(a); + + mpz_clear(b); + mpz_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-get_si.c b/external/flint-2.4.3/fmpz/test/t-get_si.c new file mode 100644 index 0000000..b20053e --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-get_si.c @@ -0,0 +1,107 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "long_extras.h" + +int +main(void) +{ + fmpz_t x; + + int i, result; + FLINT_TEST_INIT(state); + + + + flint_printf("get/set_si...."); + fflush(stdout); + + fmpz_init(x); + + fmpz_set_si(x, COEFF_MIN); + if (COEFF_IS_MPZ(*x) || fmpz_get_si(x) != COEFF_MIN) + { + flint_printf("FAIL: COEFF_MIN"); + abort(); + } + + fmpz_set_si(x, COEFF_MAX); + if (COEFF_IS_MPZ(*x) || fmpz_get_si(x) != COEFF_MAX) + { + flint_printf("FAIL: COEFF_MIN"); + abort(); + } + + fmpz_set_si(x, WORD_MIN); + if (!COEFF_IS_MPZ(*x) || fmpz_get_si(x) != WORD_MIN) + { + flint_printf("FAIL: WORD_MIN"); + abort(); + } + + fmpz_set_si(x, WORD_MIN); + if (!COEFF_IS_MPZ(*x) || fmpz_get_si(x) != WORD_MIN) + { + flint_printf("FAIL: WORD_MAX"); + abort(); + } + + fmpz_clear(x); + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a; + slong b, c; + + b = z_randtest(state); + + fmpz_init(a); + + fmpz_set_si(a, b); + c = fmpz_get_si(a); + + result = (b == c); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("b = %wd, c = %wd\n", b, c); + abort(); + } + + fmpz_clear(a); + } + + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-get_str.c b/external/flint-2.4.3/fmpz/test/t-get_str.c new file mode 100644 index 0000000..d769491 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-get_str.c @@ -0,0 +1,90 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("get_str...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a; + mpz_t b; + int base, j; + char *str1, *str2; + + fmpz_init(a); + mpz_init(b); + fmpz_randtest(a, state, 200); + base = (int) (n_randint(state, 61) + 2); + + fmpz_get_mpz(b, a); + + str1 = fmpz_get_str(NULL, base, a); + str2 = mpz_get_str(NULL, base, b); + result = strlen(str1) == strlen(str2); + if (result) + { + for (j = 0; result && j < strlen(str1); j++) + if (str1[j] != str2[j]) + result = 0; + } + + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("b = %Zd\n", b); + flint_printf("base = %d\n", base); + flint_printf("str1 = %s\n, str2 = %s\n", str1, str2); + abort(); + } + + flint_free(str1); + flint_free(str2); + + fmpz_clear(a); + mpz_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-get_ui.c b/external/flint-2.4.3/fmpz/test/t-get_ui.c new file mode 100644 index 0000000..42eaf62 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-get_ui.c @@ -0,0 +1,71 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("get/set_ui...."); + fflush(stdout); + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a; + ulong b, c; + + b = n_randtest(state); + + fmpz_init(a); + + fmpz_set_ui(a, b); + c = fmpz_get_ui(a); + + result = (b == c); + + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("b = %wd, c = %wd\n", b, c); + abort(); + } + + fmpz_clear(a); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-init2.c b/external/flint-2.4.3/fmpz/test/t-init2.c new file mode 100644 index 0000000..0c251dd --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-init2.c @@ -0,0 +1,69 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + flint_printf("init/init2/clear...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a; + + fmpz_init2(a, n_randint(state, 100)); + fmpz_clear(a); + } + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a; + + fmpz_init(a); + fmpz_randtest(a, state, FLINT_BITS - 2); + + _fmpz_promote_val(a); + _fmpz_demote_val(a); + + fmpz_clear(a); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-init_set.c b/external/flint-2.4.3/fmpz/test/t-init_set.c new file mode 100644 index 0000000..0dd005c --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-init_set.c @@ -0,0 +1,92 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("init_set...."); + fflush(stdout); + + + + /* Small integers */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + + fmpz_init(a); + fmpz_randtest(a, state, FLINT_BITS - 2); + fmpz_init_set(b, a); + + result = fmpz_equal(a, b); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), fmpz_print(a), flint_printf("\n"); + flint_printf("b = "), fmpz_print(b), flint_printf("\n"); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + } + + /* Large integers */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + + fmpz_init(a); + fmpz_randtest(a, state, 2 * FLINT_BITS); + fmpz_init_set(b, a); + + result = fmpz_equal(a, b); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), fmpz_print(a), flint_printf("\n"); + flint_printf("b = "), fmpz_print(b), flint_printf("\n"); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-init_set_readonly.c b/external/flint-2.4.3/fmpz/test/t-init_set_readonly.c new file mode 100644 index 0000000..c3b6c87 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-init_set_readonly.c @@ -0,0 +1,122 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "long_extras.h" +#include "fmpz.h" + +int main(void) +{ + int i; + FLINT_TEST_INIT(state); + + flint_printf("init_set_readonly...."); + fflush(stdout); + + + + /* Create some small fmpz integers, clear the mpz_t */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t f; + mpz_t z; + + *f = z_randint(state, COEFF_MAX + 1); + + mpz_init(z); + fmpz_get_mpz(z, f); + + { + fmpz_t g; + + fmpz_init_set_readonly(g, z); + fmpz_clear_readonly(g); + } + + mpz_clear(z); + } + + /* Create some small fmpz integers, do *not* clear the mpz_t */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t f; + mpz_t z; + + *f = z_randint(state, COEFF_MAX + 1); + + mpz_init(z); + fmpz_get_mpz(z, f); + + { + fmpz_t g; + + fmpz_init_set_readonly(g, z); + } + + mpz_clear(z); + } + + /* Create some more fmpz integers */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t f; + mpz_t z; + + fmpz_init(f); + fmpz_randtest(f, state, 2 * FLINT_BITS); + mpz_init(z); + fmpz_get_mpz(z, f); + + { + fmpz_t g, h; + + fmpz_init_set_readonly(g, z); + fmpz_init(h); + fmpz_set_mpz(h, z); + + if (!fmpz_equal(g, h)) + { + flint_printf("FAIL:\n\n"); + flint_printf("g = "), fmpz_print(g), flint_printf("\n"); + flint_printf("h = "), fmpz_print(h), flint_printf("\n"); + gmp_printf("z = %Zd\n", z); + } + + fmpz_clear_readonly(g); + fmpz_clear(h); + } + + fmpz_clear(f); + mpz_clear(z); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-init_set_ui.c b/external/flint-2.4.3/fmpz/test/t-init_set_ui.c new file mode 100644 index 0000000..7ea2e4a --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-init_set_ui.c @@ -0,0 +1,71 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("init_set_ui...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + ulong x = n_randtest(state); + + fmpz_init(a); + fmpz_set_ui(a, x); + fmpz_init_set_ui(b, x); + + result = fmpz_equal(a, b); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), fmpz_print(a), flint_printf("\n"); + flint_printf("b = "), fmpz_print(b), flint_printf("\n"); + flint_printf("x = %wu\n", x); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-invmod.c b/external/flint-2.4.3/fmpz/test/t-invmod.c new file mode 100644 index 0000000..aea236e --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-invmod.c @@ -0,0 +1,220 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("invmod...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c; + mpz_t d, e, f, g; + int r1, r2; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + fmpz_randtest_not_zero(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + r1 = fmpz_invmod(c, a, b); + r2 = mpz_invert(f, d, e); + + fmpz_get_mpz(g, c); + + result = (r1 != 0 && r2 != 0 && (mpz_cmp(f, g) == 0)) || (r1 == 0 && r2 == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf + ("d = %Zd, e = %Zd, f = %Zd, g = %Zd, r1 = %d, r2 = %d\n", d, + e, f, g, r1, r2); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + /* Check aliasing of a and b */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, c; + mpz_t d, f, g; + int r1, r2; + + fmpz_init(a); + fmpz_init(c); + + mpz_init(d); + mpz_init(f); + mpz_init(g); + + fmpz_randtest_not_zero(a, state, 200); + + fmpz_get_mpz(d, a); + + r1 = fmpz_invmod(c, a, a); + r2 = mpz_invert(f, d, d); + + fmpz_get_mpz(g, c); + + result = (r1 != 0 && r2 != 0 && (mpz_cmp(f, g) == 0)) || (r1 == 0 && r2 == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, f = %Zd, g = %Zd, r1 = %d, r2 = %d\n", d, f, + g, r1, r2); + abort(); + } + + fmpz_clear(a); + fmpz_clear(c); + + mpz_clear(d); + mpz_clear(f); + mpz_clear(g); + } + + /* Test aliasing of a and c */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t d, e, f, g; + int r1, r2; + + fmpz_init(a); + fmpz_init(b); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + fmpz_randtest_not_zero(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + r1 = fmpz_invmod(a, a, b); + r2 = mpz_invert(f, d, e); + + fmpz_get_mpz(g, a); + + result = (r1 != 0 && r2 != 0 && (mpz_cmp(f, g) == 0)) || (r1 == 0 && r2 == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + /* Test aliasing of b and c */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t d, e, f, g; + int r1, r2; + + fmpz_init(a); + fmpz_init(b); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + fmpz_randtest_not_zero(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + r1 = fmpz_invmod(b, a, b); + r2 = mpz_invert(f, d, e); + + fmpz_get_mpz(g, b); + + result = (r1 != 0 && r2 != 0 && (mpz_cmp(f, g) == 0)) || (r1 == 0 && r2 == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-is_even.c b/external/flint-2.4.3/fmpz/test/t-is_even.c new file mode 100644 index 0000000..500601e --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-is_even.c @@ -0,0 +1,96 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("is_even/odd...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t f; + mpz_t g; + + fmpz_init(f); + mpz_init(g); + + fmpz_randtest(f, state, 100); + fmpz_get_mpz(g, f); + + result = (fmpz_is_even(f) == mpz_even_p(g)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("f = "), fmpz_print(f), flint_printf("\n"); + gmp_printf("g = %Zd\n", g); + abort(); + } + + fmpz_clear(f); + mpz_clear(g); + } + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t f; + mpz_t g; + + fmpz_init(f); + mpz_init(g); + + fmpz_randtest(f, state, 100); + fmpz_get_mpz(g, f); + + result = (fmpz_is_odd(f) == mpz_odd_p(g)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("f = "), fmpz_print(f), flint_printf("\n"); + gmp_printf("g = %Zd\n", g); + abort(); + } + + fmpz_clear(f); + mpz_clear(g); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-is_prime_pseudosquare.c b/external/flint-2.4.3/fmpz/test/t-is_prime_pseudosquare.c new file mode 100644 index 0000000..c6a65a4 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-is_prime_pseudosquare.c @@ -0,0 +1,72 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("is_prime_pseudosquare...."); + fflush(stdout); + + + + for (i = 0; i < 100000 * flint_test_multiplier(); i++) + { + fmpz_t p; + int r1, r2; + + fmpz_init(p); + + fmpz_randtest_unsigned(p, state, n_randint(state, 94) + 1); + + r1 = fmpz_is_probabprime(p); + r2 = fmpz_is_prime_pseudosquare(p); + + result = (r1 == r2); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_print(p); + flint_printf("r1 = %d, r2 = %d\n", r1, r2); + abort(); + } + + fmpz_clear(p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-is_square.c b/external/flint-2.4.3/fmpz/test/t-is_square.c new file mode 100644 index 0000000..4cda6c2 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-is_square.c @@ -0,0 +1,80 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("is_square...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a; + mpz_t b; + int r1, r2; + + fmpz_init(a); + + mpz_init(b); + + fmpz_randtest(a, state, 200); + if (n_randint(state, 2) == 0) + fmpz_mul(a, a, a); + + fmpz_get_mpz(b, a); + + r1 = fmpz_is_square(a); + r2 = mpz_perfect_square_p(b); + result = (r1 == r2); + + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("b = %Zd\n", b); + abort(); + } + + fmpz_clear(a); + + mpz_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-jacobi.c b/external/flint-2.4.3/fmpz/test/t-jacobi.c new file mode 100644 index 0000000..5af2586 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-jacobi.c @@ -0,0 +1,93 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("jacobi...."); + fflush(stdout); + + + _flint_rand_init_gmp(state); + + for (i = 0; i < 3000 * flint_test_multiplier(); i++) + { + fmpz_t a, p; + mpz_t b, q; + int r1, r2; + + fmpz_init(a); + fmpz_init(p); + + mpz_init(b); + mpz_init(q); + + mpz_rrandomb(q, state->gmp_state, n_randint(state, 200) + 1); +#ifdef mpz_next_likely_prime + mpz_next_likely_prime(q, q, state->gmp_state); +#else + mpz_nextprime(q, q); +#endif + fmpz_set_mpz(p, q); + + mpz_rrandomb(b, state->gmp_state, n_randint(state, 200) + 1); + mpz_mod(b, b, q); + if (n_randint(state, 2)) + mpz_neg(b, b); + fmpz_set_mpz(a, b); + + r1 = fmpz_jacobi(a, p); + r2 = mpz_jacobi(b, q); + result = (r1 == r2); + + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("b = %Zd, q = %Zd\n", b, q); + abort(); + } + + fmpz_clear(a); + fmpz_clear(p); + + mpz_clear(b); + mpz_clear(q); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-lcm.c b/external/flint-2.4.3/fmpz/test/t-lcm.c new file mode 100644 index 0000000..9480a63 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-lcm.c @@ -0,0 +1,227 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("lcm...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c; + mpz_t d, e, f, g; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + fmpz_randtest(b, state, 200); + fmpz_randtest(c, state, 200); + fmpz_mul(a, a, c); + fmpz_mul(b, b, c); + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_lcm(c, a, b); + mpz_lcm(f, d, e); + + fmpz_get_mpz(g, c); + + result = (mpz_cmp(f, g) == 0); + + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + /* Check aliasing of a and b */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, c; + mpz_t d, f, g; + + fmpz_init(a); + fmpz_init(c); + + mpz_init(d); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + + fmpz_get_mpz(d, a); + + fmpz_lcm(c, a, a); + mpz_lcm(f, d, d); + + fmpz_get_mpz(g, c); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, f = %Zd, g = %Zd\n", d, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(c); + + mpz_clear(d); + mpz_clear(f); + mpz_clear(g); + } + + /* Test aliasing of a and c */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c; + mpz_t d, e, f, g; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + fmpz_randtest(b, state, 200); + fmpz_randtest(c, state, 200); + fmpz_mul(a, a, c); + fmpz_mul(b, b, c); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_lcm(a, a, b); + mpz_lcm(f, d, e); + + fmpz_get_mpz(g, a); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + /* Test aliasing of b and c */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c; + mpz_t d, e, f, g; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + fmpz_randtest(b, state, 200); + fmpz_randtest(c, state, 200); + fmpz_mul(a, a, c); + fmpz_mul(b, b, c); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_lcm(b, a, b); + mpz_lcm(f, d, e); + + fmpz_get_mpz(g, b); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-mod.c b/external/flint-2.4.3/fmpz/test/t-mod.c new file mode 100644 index 0000000..1cf5a21 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-mod.c @@ -0,0 +1,214 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("mod...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c; + mpz_t d, e, f, g; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + fmpz_randtest_not_zero(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_mod(c, a, b); + mpz_mod(f, d, e); + + fmpz_get_mpz(g, c); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + /* Check aliasing of a and b */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, c; + mpz_t d, f, g; + + fmpz_init(a); + fmpz_init(c); + + mpz_init(d); + mpz_init(f); + mpz_init(g); + + fmpz_randtest_not_zero(a, state, 200); + + fmpz_get_mpz(d, a); + + fmpz_mod(c, a, a); + mpz_mod(f, d, d); + + fmpz_get_mpz(g, c); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, f = %Zd, g = %Zd\n", d, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(c); + + mpz_clear(d); + mpz_clear(f); + mpz_clear(g); + } + + /* Test aliasing of a and c */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t d, e, f, g; + + fmpz_init(a); + fmpz_init(b); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + fmpz_randtest_not_zero(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_mod(a, a, b); + mpz_mod(f, d, e); + + fmpz_get_mpz(g, a); + + result = (mpz_cmp(f, g) == 0); + + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + /* Test aliasing of b and c */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t d, e, f, g; + + fmpz_init(a); + fmpz_init(b); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + fmpz_randtest_not_zero(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_mod(b, a, b); + mpz_mod(f, d, e); + + fmpz_get_mpz(g, b); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-mod_ui.c b/external/flint-2.4.3/fmpz/test/t-mod_ui.c new file mode 100644 index 0000000..70eb08c --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-mod_ui.c @@ -0,0 +1,129 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("mod_ui...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t d, e, f; + ulong x, r1, r2; + + fmpz_init(a); + fmpz_init(b); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + + fmpz_randtest(a, state, 200); + + fmpz_get_mpz(d, a); + x = n_randtest_not_zero(state); + + r1 = fmpz_mod_ui(b, a, x); + r2 = flint_mpz_fdiv_r_ui(e, d, x); + + fmpz_get_mpz(f, b); + + result = ((mpz_cmp(e, f) == 0) && (r1 == r2)); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf + ("d = %Zd, e = %Zd, f = %Zd, x = %wu, r1 = %wu, r2 = %wu\n", d, + e, f, x, r1, r2); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + } + + /* Check aliasing of a and b */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a; + mpz_t d, e, f; + ulong x, r1, r2; + + fmpz_init(a); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + + fmpz_randtest(a, state, 200); + + fmpz_get_mpz(d, a); + x = n_randtest_not_zero(state); + + r1 = fmpz_mod_ui(a, a, x); + r2 = flint_mpz_fdiv_r_ui(e, d, x); + + fmpz_get_mpz(f, a); + + result = ((mpz_cmp(e, f) == 0) && (r1 == r2)); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf + ("d = %Zd, e = %Zd, f = %Zd, x = %wu, r1 = %wu, r2 = %wu\n", d, + e, f, x, r1, r2); + abort(); + } + + fmpz_clear(a); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-mpz_init_set_readonly.c b/external/flint-2.4.3/fmpz/test/t-mpz_init_set_readonly.c new file mode 100644 index 0000000..e84ddb9 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-mpz_init_set_readonly.c @@ -0,0 +1,102 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "long_extras.h" +#include "fmpz.h" + +int main(void) +{ + int i; + FLINT_TEST_INIT(state); + + flint_printf("mpz_init_set_readonly...."); + fflush(stdout); + + + + /* Create some small fmpz integers, clear the mpz_t */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t f; + mpz_t z; + + *f = z_randint(state, COEFF_MAX + 1); + + flint_mpz_init_set_readonly(z, f); + flint_mpz_clear_readonly(z); + } + + /* Create some large fmpz integers, do not clear the mpz_t */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t f; + mpz_t z; + + fmpz_init(f); + fmpz_randtest(f, state, 2 * FLINT_BITS); + + if (COEFF_IS_MPZ(*f)) + { + flint_mpz_init_set_readonly(z, f); + } + + fmpz_clear(f); + } + + /* Create some more fmpz integers */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t f, g; + mpz_t z; + + fmpz_init(f); + fmpz_init(g); + fmpz_randtest(f, state, 2 * FLINT_BITS); + + flint_mpz_init_set_readonly(z, f); + fmpz_set_mpz(g, z); + + if (!fmpz_equal(f, g)) + { + flint_printf("FAIL:\n\n"); + flint_printf("f = "), fmpz_print(f), flint_printf("\n"); + flint_printf("g = "), fmpz_print(g), flint_printf("\n"); + gmp_printf("z = %Zd\n", z); + } + + fmpz_clear(f); + fmpz_clear(g); + flint_mpz_clear_readonly(z); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-mul.c b/external/flint-2.4.3/fmpz/test/t-mul.c new file mode 100644 index 0000000..101f073 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-mul.c @@ -0,0 +1,213 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("mul...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c; + mpz_t d, e, f, g; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + fmpz_randtest(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_mul(c, a, b); + mpz_mul(f, d, e); + + fmpz_get_mpz(g, c); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + /* Check aliasing of a and b */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, c; + mpz_t d, f, g; + + fmpz_init(a); + fmpz_init(c); + + mpz_init(d); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + + fmpz_get_mpz(d, a); + + fmpz_mul(c, a, a); + mpz_mul(f, d, d); + + fmpz_get_mpz(g, c); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, f = %Zd, g = %Zd\n", d, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(c); + + mpz_clear(d); + mpz_clear(f); + mpz_clear(g); + } + + /* Test aliasing of a and c */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t d, e, f, g; + + fmpz_init(a); + fmpz_init(b); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + fmpz_randtest(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_mul(a, a, b); + mpz_mul(f, d, e); + + fmpz_get_mpz(g, a); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + /* Test aliasing of b and c */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t d, e, f, g; + + fmpz_init(a); + fmpz_init(b); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + fmpz_randtest(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_mul(b, a, b); + mpz_mul(f, d, e); + + fmpz_get_mpz(g, b); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-mul2_uiui.c b/external/flint-2.4.3/fmpz/test/t-mul2_uiui.c new file mode 100644 index 0000000..fe06d10 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-mul2_uiui.c @@ -0,0 +1,132 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("mul2_uiui...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t d, e, f; + ulong x, y; + + fmpz_init(a); + fmpz_init(b); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + + fmpz_randtest(a, state, 200); + + fmpz_get_mpz(d, a); + x = n_randtest(state); + y = n_randtest(state); + + fmpz_mul2_uiui(b, a, x, y); + flint_mpz_mul_ui(e, d, x); + flint_mpz_mul_ui(e, e, y); + + fmpz_get_mpz(f, b); + + result = (mpz_cmp(e, f) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, x = %wu, y = %wu\n", + d, e, f, x, y); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + } + + /* Check aliasing of a and b */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a; + mpz_t d, e, f; + ulong x, y; + + fmpz_init(a); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + + fmpz_randtest(a, state, 200); + + fmpz_get_mpz(d, a); + x = n_randtest(state); + y = n_randtest(state); + + fmpz_mul2_uiui(a, a, x, y); + flint_mpz_mul_ui(e, d, x); + flint_mpz_mul_ui(e, e, y); + + fmpz_get_mpz(f, a); + + result = (mpz_cmp(e, f) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, x = %wu, y = %wu\n", + d, e, f, x, y); + abort(); + } + + fmpz_clear(a); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-mul_2exp.c b/external/flint-2.4.3/fmpz/test/t-mul_2exp.c new file mode 100644 index 0000000..ce41e0e --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-mul_2exp.c @@ -0,0 +1,126 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("mul_2exp...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t d, e, f; + ulong x; + + fmpz_init(a); + fmpz_init(b); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + + fmpz_randtest(a, state, 200); + + fmpz_get_mpz(d, a); + x = n_randint(state, 200); + + fmpz_mul_2exp(b, a, x); + mpz_mul_2exp(e, d, x); + + fmpz_get_mpz(f, b); + + result = (mpz_cmp(e, f) == 0); + + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, exp = %wu\n", d, e, f, x); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + } + + /* Check aliasing of a and b */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a; + mpz_t d, e, f; + ulong x; + + fmpz_init(a); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + + fmpz_randtest(a, state, 200); + + fmpz_get_mpz(d, a); + x = n_randint(state, 200); + + fmpz_mul_2exp(a, a, x); + mpz_mul_2exp(e, d, x); + + fmpz_get_mpz(f, a); + + result = (mpz_cmp(e, f) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, exp = %wu\n", d, e, f, x); + abort(); + } + + fmpz_clear(a); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-mul_si.c b/external/flint-2.4.3/fmpz/test/t-mul_si.c new file mode 100644 index 0000000..e619c98 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-mul_si.c @@ -0,0 +1,125 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("mul_si...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t d, e, f; + slong x; + + fmpz_init(a); + fmpz_init(b); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + + fmpz_randtest(a, state, 200); + + fmpz_get_mpz(d, a); + x = z_randtest(state); + + fmpz_mul_si(b, a, x); + flint_mpz_mul_si(e, d, x); + + fmpz_get_mpz(f, b); + + result = (mpz_cmp(e, f) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, x = %wd\n", d, e, f, x); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + } + + /* Check aliasing of a and b */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a; + mpz_t d, e, f; + slong x; + + fmpz_init(a); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + + fmpz_randtest(a, state, 200); + + fmpz_get_mpz(d, a); + x = z_randtest(state); + + fmpz_mul_si(a, a, x); + flint_mpz_mul_si(e, d, x); + + fmpz_get_mpz(f, a); + + result = (mpz_cmp(e, f) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, x = %wd\n", d, e, f, x); + abort(); + } + + fmpz_clear(a); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-mul_si_tdiv_q_2exp.c b/external/flint-2.4.3/fmpz/test/t-mul_si_tdiv_q_2exp.c new file mode 100644 index 0000000..fbef118 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-mul_si_tdiv_q_2exp.c @@ -0,0 +1,134 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2012 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("mul_si_tdiv_q_2exp...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t d, e, f; + slong x; + ulong exp; + + fmpz_init(a); + fmpz_init(b); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + + fmpz_randtest(a, state, 200); + + fmpz_get_mpz(d, a); + x = z_randtest(state); + exp = n_randint(state, 200); + + fmpz_mul_si_tdiv_q_2exp(b, a, x, exp); + flint_mpz_mul_si(e, d, x); + mpz_tdiv_q_2exp(e, e, exp); + + fmpz_get_mpz(f, b); + + result = (mpz_cmp(e, f) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, x = %wd, exp = %wu\n", + d, e, f, x, exp); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + } + + /* Check aliasing of a and b */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a; + mpz_t d, e, f; + slong x; + ulong exp; + + fmpz_init(a); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + + fmpz_randtest(a, state, 200); + + fmpz_get_mpz(d, a); + x = z_randtest(state); + exp = n_randint(state, 200); + + fmpz_mul_si_tdiv_q_2exp(a, a, x, exp); + flint_mpz_mul_si(e, d, x); + mpz_tdiv_q_2exp(e, e, exp); + + fmpz_get_mpz(f, a); + + result = (mpz_cmp(e, f) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, x = %wd, exp = %wu\n", + d, e, f, x, exp); + abort(); + } + + fmpz_clear(a); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-mul_tdiv_q_2exp.c b/external/flint-2.4.3/fmpz/test/t-mul_tdiv_q_2exp.c new file mode 100644 index 0000000..d35ae15 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-mul_tdiv_q_2exp.c @@ -0,0 +1,226 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2012 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("mul_tdiv_q_2exp...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c; + mpz_t d, e, f, g; + ulong exp; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + fmpz_randtest(b, state, 200); + exp = n_randint(state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_mul_tdiv_q_2exp(c, a, b, exp); + mpz_mul(f, d, e); + mpz_tdiv_q_2exp(f, f, exp); + + fmpz_get_mpz(g, c); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd, exp = %wu\n", + d, e, f, g, exp); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + /* Check aliasing of a and b */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, c; + mpz_t d, f, g; + ulong exp; + + fmpz_init(a); + fmpz_init(c); + + mpz_init(d); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + exp = n_randint(state, 200); + fmpz_get_mpz(d, a); + + fmpz_mul_tdiv_q_2exp(c, a, a, exp); + mpz_mul(f, d, d); + mpz_tdiv_q_2exp(f, f, exp); + + fmpz_get_mpz(g, c); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, f = %Zd, g = %Zd, exp = %wu\n", d, f, g, exp); + abort(); + } + + fmpz_clear(a); + fmpz_clear(c); + + mpz_clear(d); + mpz_clear(f); + mpz_clear(g); + } + + /* Test aliasing of a and c */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t d, e, f, g; + ulong exp; + + fmpz_init(a); + fmpz_init(b); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + fmpz_randtest(b, state, 200); + exp = n_randint(state, 200); + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_mul_tdiv_q_2exp(a, a, b, exp); + mpz_mul(f, d, e); + mpz_tdiv_q_2exp(f, f, exp); + + fmpz_get_mpz(g, a); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd, exp = %wu\n", + d, e, f, g, exp); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + /* Test aliasing of b and c */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t d, e, f, g; + ulong exp; + + fmpz_init(a); + fmpz_init(b); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + fmpz_randtest(b, state, 200); + exp = n_randint(state, 200); + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_mul_tdiv_q_2exp(b, a, b, exp); + mpz_mul(f, d, e); + mpz_tdiv_q_2exp(f, f, exp); + + fmpz_get_mpz(g, b); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd, exp = %wu\n", + d, e, f, g, exp); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-mul_ui.c b/external/flint-2.4.3/fmpz/test/t-mul_ui.c new file mode 100644 index 0000000..301dee0 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-mul_ui.c @@ -0,0 +1,125 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("mul_ui...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t d, e, f; + ulong x; + + fmpz_init(a); + fmpz_init(b); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + + fmpz_randtest(a, state, 200); + + fmpz_get_mpz(d, a); + x = n_randtest(state); + + fmpz_mul_ui(b, a, x); + flint_mpz_mul_ui(e, d, x); + + fmpz_get_mpz(f, b); + + result = (mpz_cmp(e, f) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, x = %wu\n", d, e, f, x); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + } + + /* Check aliasing of a and b */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a; + mpz_t d, e, f; + ulong x; + + fmpz_init(a); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + + fmpz_randtest(a, state, 200); + + fmpz_get_mpz(d, a); + x = n_randtest(state); + + fmpz_mul_ui(a, a, x); + flint_mpz_mul_ui(e, d, x); + + fmpz_get_mpz(f, a); + + result = (mpz_cmp(e, f) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, x = %wu\n", d, e, f, x); + abort(); + } + + fmpz_clear(a); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-multi_CRT_ui.c b/external/flint-2.4.3/fmpz/test/t-multi_CRT_ui.c new file mode 100644 index 0000000..db76dde --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-multi_CRT_ui.c @@ -0,0 +1,134 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + + +int main() +{ + int result = 1; + fmpz_t input, temp; + mpz_t num1; + mp_limb_t * output, * output2; + slong i, j, k; + mp_limb_t * primes; + mp_limb_t prime; + slong num_primes; + slong bits; + double primes_per_limb; + + fmpz_comb_t comb; + fmpz_comb_temp_t comb_temp; + + FLINT_TEST_INIT(state); + + flint_printf("multi_CRT_ui...."); + fflush(stdout); + + + mpz_init(num1); + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + bits = n_randint(state, 300)+1; + + if (FLINT_BITS == 32) + primes_per_limb = 1.0325; + else if (FLINT_BITS == 64) + primes_per_limb = 1.016; + + num_primes = ((bits + 1)*primes_per_limb)/FLINT_BITS + 1; + + primes = (mp_limb_t *) flint_malloc(num_primes * sizeof(mp_limb_t)); + prime = n_nextprime((UWORD(1) << (FLINT_BITS-1)) - WORD(10000000), 0); + + for (j = 0; j < num_primes; j++) + { + primes[j] = prime; + prime = n_nextprime(prime, 0); + } + + fmpz_init(input); + + fmpz_randtest(input, state, bits); + fmpz_get_mpz(num1, input); + + output = (mp_limb_t *) flint_malloc(num_primes * sizeof(mp_limb_t)); + output2 = (mp_limb_t *) flint_malloc(num_primes * sizeof(mp_limb_t)); + + fmpz_comb_init(comb, primes, num_primes); + fmpz_comb_temp_init(comb_temp, comb); + + fmpz_multi_mod_ui(output, input, comb, comb_temp); + + fmpz_init(temp); + + fmpz_multi_CRT_ui(temp, output, comb, comb_temp, 1); + result &= fmpz_equal(temp, input); + + fmpz_comb_temp_clear(comb_temp); + + if (!result) + { + flint_printf("FAIL: bits = %wd, num_primes = %wd\n", bits, num_primes); + fmpz_print(temp); flint_printf("\n"); + fmpz_print(input); flint_printf("\n"); + abort(); + } + + for (k = 0; k < num_primes; k++) + { + output2[k] = fmpz_mod_ui(temp, input, primes[k]); + result &= (output[k] == output2[k]); + + if (!result) + { + flint_printf("FAIL: bits = %wd, num_primes = %wd\n", bits, num_primes); + flint_printf("FAIL: k = %wd, output[k] = %wd, output2[k] = %wd\n", k, output[k], output2[k]); + abort(); + } + } + + fmpz_comb_clear(comb); + fmpz_clear(temp); + fmpz_clear(input); + flint_free(output); + flint_free(output2); + flint_free(primes); + } + + + mpz_clear(num1); + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} + diff --git a/external/flint-2.4.3/fmpz/test/t-multi_CRT_ui_unsigned.c b/external/flint-2.4.3/fmpz/test/t-multi_CRT_ui_unsigned.c new file mode 100644 index 0000000..4075383 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-multi_CRT_ui_unsigned.c @@ -0,0 +1,132 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + + +int main() +{ + int result; + fmpz_t input, temp; + mpz_t num1; + mp_limb_t * output, * output2; + double primes_per_limb; + slong i, j, k; + slong bits; + + slong num_primes; + mp_limb_t * primes; + mp_limb_t prime; + + fmpz_comb_t comb; + fmpz_comb_temp_t comb_temp; + + FLINT_TEST_INIT(state); + + flint_printf("multi_CRT_ui_unsigned...."); + fflush(stdout); + + mpz_init(num1); + + + result = 1; + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + bits = n_randint(state, 300)+1; + + if (FLINT_BITS == 32) + primes_per_limb = 1.0325; + else if (FLINT_BITS == 64) + primes_per_limb = 1.016; + + num_primes = (bits*primes_per_limb)/FLINT_BITS + 1; + + primes = (mp_limb_t *) flint_malloc(num_primes * sizeof(mp_limb_t)); + prime = n_nextprime((UWORD(1) << (FLINT_BITS-1)) - WORD(10000000), 0); + + for (j = 0; j < num_primes; j++) + { + primes[j] = prime; + prime = n_nextprime(prime, 0); + } + + fmpz_init(input); + + fmpz_randtest(input, state, bits); + fmpz_abs(input, input); + fmpz_get_mpz(num1, input); + + output = (mp_limb_t *) flint_malloc(num_primes * sizeof(mp_limb_t)); + output2 = (mp_limb_t *) flint_malloc(num_primes * sizeof(mp_limb_t)); + + fmpz_comb_init(comb, primes, num_primes); + fmpz_comb_temp_init(comb_temp, comb); + + fmpz_multi_mod_ui(output, input, comb, comb_temp); + + fmpz_init(temp); + + fmpz_multi_CRT_ui(temp, output, comb, comb_temp, 0); + result &= fmpz_equal(temp, input); + + fmpz_comb_temp_clear(comb_temp); + + for (k = 0; k < num_primes; k++) + { + output2[k] = fmpz_mod_ui(temp, input, primes[k]); + result &= (output[k] == output2[k]); + } + + if (!result) + { + flint_printf("FAIL: bits = %wd, num_primes = %wd\n", bits, num_primes); + fmpz_print(temp); flint_printf("\n"); + fmpz_print(input); flint_printf("\n"); + abort(); + } + + fmpz_clear(temp); + + fmpz_comb_clear(comb); + fmpz_clear(input); + + flint_free(output); + flint_free(output2); + flint_free(primes); + } + + + mpz_clear(num1); + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-neg.c b/external/flint-2.4.3/fmpz/test/t-neg.c new file mode 100644 index 0000000..79d3b9b --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-neg.c @@ -0,0 +1,117 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("neg...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t c, d; + + fmpz_init(a); + fmpz_init(b); + + mpz_init(c); + mpz_init(d); + + fmpz_randtest(a, state, 200); + + fmpz_get_mpz(c, a); + + fmpz_neg(b, a); + mpz_neg(c, c); + + fmpz_get_mpz(d, b); + + result = (mpz_cmp(c, d) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("c = %Zd, d = %Zd\n", c, d); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + + mpz_clear(c); + mpz_clear(d); + } + + /* Check aliasing */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a; + mpz_t c, d; + + fmpz_init(a); + + mpz_init(c); + mpz_init(d); + + fmpz_randtest(a, state, 200); + + fmpz_get_mpz(c, a); + + fmpz_neg(a, a); + mpz_neg(c, c); + + fmpz_get_mpz(d, a); + + result = (mpz_cmp(c, d) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("c = %Zd, d = %Zd\n", c, d); + abort(); + } + + fmpz_clear(a); + + mpz_clear(c); + mpz_clear(d); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-neg_ui.c b/external/flint-2.4.3/fmpz/test/t-neg_ui.c new file mode 100644 index 0000000..1b4ab6c --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-neg_ui.c @@ -0,0 +1,77 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + + FLINT_TEST_INIT(state); + + + flint_printf("neg_ui...."); + fflush(stdout); + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + ulong c; + + c = n_randtest(state); + + fmpz_init(a); + fmpz_init(b); + + fmpz_set_ui(a, c); + fmpz_neg(a, a); + + fmpz_neg_ui(b, c); + + result = fmpz_equal(a, b); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("c = %wu\n", c); + flint_printf("a = "); fmpz_print(a); flint_printf("\n"); + flint_printf("b = "); fmpz_print(b); flint_printf("\n"); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-neg_uiui.c b/external/flint-2.4.3/fmpz/test/t-neg_uiui.c new file mode 100644 index 0000000..9a9812b --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-neg_uiui.c @@ -0,0 +1,81 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + + FLINT_TEST_INIT(state); + + + flint_printf("neg_uiui...."); + fflush(stdout); + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + ulong hi, lo; + + hi = n_randtest(state); + lo = n_randtest(state); + + fmpz_init(a); + fmpz_init(b); + + fmpz_set_ui(a, hi); + fmpz_mul_2exp(a, a, FLINT_BITS); + fmpz_add_ui(a, a, lo); + fmpz_neg(a, a); + + fmpz_neg_uiui(b, hi, lo); + + result = fmpz_equal(a, b); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("hi = %wu\n", hi); + flint_printf("lo = %wu\n", lo); + flint_printf("a = "); fmpz_print(a); flint_printf("\n"); + flint_printf("b = "); fmpz_print(b); flint_printf("\n"); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-or.c b/external/flint-2.4.3/fmpz/test/t-or.c new file mode 100644 index 0000000..854e6c9 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-or.c @@ -0,0 +1,217 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("or...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c; + mpz_t d, e, f, g; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + fmpz_randtest(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_or(c, a, b); + mpz_ior(f, d, e); + + fmpz_get_mpz(g, c); + + result = (mpz_cmp(f, g) == 0); + + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + /* Check aliasing of a and b */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, c; + mpz_t d, f, g; + + fmpz_init(a); + fmpz_init(c); + + mpz_init(d); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + + fmpz_get_mpz(d, a); + + fmpz_or(c, a, a); + mpz_ior(f, d, d); + + fmpz_get_mpz(g, c); + + result = (mpz_cmp(f, g) == 0); + + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, f = %Zd, g = %Zd\n", d, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(c); + + mpz_clear(d); + mpz_clear(f); + mpz_clear(g); + } + + /* Test aliasing of a and c */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t d, e, f, g; + + fmpz_init(a); + fmpz_init(b); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + fmpz_randtest(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_or(a, a, b); + mpz_ior(f, d, e); + + fmpz_get_mpz(g, a); + + result = (mpz_cmp(f, g) == 0); + + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + /* Test aliasing of b and c */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t d, e, f, g; + + fmpz_init(a); + fmpz_init(b); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + fmpz_randtest(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_or(b, a, b); + mpz_ior(f, d, e); + + fmpz_get_mpz(g, b); + + result = (mpz_cmp(f, g) == 0); + + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-out_inp_raw.c b/external/flint-2.4.3/fmpz/test/t-out_inp_raw.c new file mode 100644 index 0000000..29c215f --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-out_inp_raw.c @@ -0,0 +1,179 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 Qingwen GUAN + +******************************************************************************/ + +#undef ulong +#define ulong ulongxx /* interferes with standard libraries */ +#include +#include +#include +#include + +#undef ulong +#include +#define ulong mp_limb_t + +#include "flint.h" +#include "fmpz.h" + +#if !defined (__WIN32) || defined(__CYGWIN__) + +/* + The function fdopen is declared in stdio.h. It is POSIX.1 compliant, + but not ANSI compliant. The following line enables compilation with + the "-ansi" flag. + */ +extern FILE * fdopen(int fildes, const char *mode); + +int main(void) +{ + int i, j, n = 10000, result; + + FILE *in, *out; + int fd[2]; + pid_t childpid; + + FLINT_TEST_INIT(state); + + printf("out_raw/inp_raw...."); + fflush(stdout); + + /* Randomise n integers, write to and read from a pipe */ + { + fmpz *a; + + a = flint_calloc(n, sizeof(fmpz)); + for (i = 0; i < n; i++) + fmpz_randtest(a + i, state, 200); + + if (pipe(fd)) + { + printf("FAIL:\n"); + printf("Failed to set-up the pipe.\n"); + abort(); + } + + if((childpid = fork()) == -1) + { + printf("FAIL:\n"); + printf("Failed to fork the process.\n"); + abort(); + } + + if(childpid == 0) /* Child process */ + { + size_t r; + + close(fd[0]); + out = fdopen(fd[1], "w"); + if (out == NULL) + { + printf("FAIL:\n"); + printf("Could not open output file at the pipe.\n"); + abort(); + } + + for (j = 0; j < n; j++) + { + r = fmpz_out_raw(out, a + j); + + if (r <= 0) + { + printf("FAIL:\n"); + printf("Write error.\n"); + abort(); + } + } + + fclose(out); + exit(0); + } + else /* Parent process */ + { + size_t r; + fmpz_t t; + + close(fd[1]); + in = fdopen(fd[0], "r"); + if (in == NULL) + { + printf("FAIL:\n"); + printf("Could not open input file at the pipe.\n"); + abort(); + } + + fmpz_init(t); + + i = 0; + while ( (r = fmpz_inp_raw(t, in)) != 0 ) + { + result = fmpz_equal(t, a + i); + if (!result) + { + printf("FAIL:\n"); + printf("a[i] = "), fmpz_print(a + i), printf("\n"); + printf("t = "), fmpz_print(t), printf("\n"); + abort(); + } + + ++i; + } + + fmpz_clear(t); + fclose(in); + } + + if (i != n) + { + printf("FAIL:\n"); + printf("Only %d out of %d objects were processed.\n", i, n); + abort(); + } + + for (i = 0; i < n; i++) + fmpz_clear(a + i); + flint_free(a); + } + + /* Write bad data to a pipe and read it */ + /* Not necessary */ + + FLINT_TEST_CLEANUP(state); + + printf("PASS\n"); + return EXIT_SUCCESS; +} + +#else + +int main(void) +{ + printf("out_raw/ inp_raw...."); + fflush(stdout); + printf("SKIPPED\n"); + return EXIT_SUCCESS; +} + +#endif diff --git a/external/flint-2.4.3/fmpz/test/t-popcnt.c b/external/flint-2.4.3/fmpz/test/t-popcnt.c new file mode 100644 index 0000000..b863161 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-popcnt.c @@ -0,0 +1,79 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + mp_bitcnt_t r1, r2; + FLINT_TEST_INIT(state); + + flint_printf("popcnt...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a; + mpz_t b; + + fmpz_init(a); + mpz_init(b); + + fmpz_randtest(a, state, 2 * FLINT_BITS); + fmpz_get_mpz(b, a); + + r1 = fmpz_popcnt(a); + r2 = mpz_popcount(b); + + result = r1 == r2; + + if (!result && fmpz_cmp_si(a,0) >= 0) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpz_print(a), flint_printf("\n"); + gmp_printf("b = %Zd\n", b); + flint_printf("r1 = %wu r2 = %wu\n", r1, r2); + abort(); + } + + fmpz_clear(a); + mpz_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-pow_ui.c b/external/flint-2.4.3/fmpz/test/t-pow_ui.c new file mode 100644 index 0000000..bde8361 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-pow_ui.c @@ -0,0 +1,125 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("pow_ui...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t d, e, f; + ulong x; + + fmpz_init(a); + fmpz_init(b); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + + fmpz_randtest(a, state, 200); + + fmpz_get_mpz(d, a); + x = n_randint(state, 20); + + fmpz_pow_ui(b, a, x); + flint_mpz_pow_ui(e, d, x); + + fmpz_get_mpz(f, b); + + result = (mpz_cmp(e, f) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, x = %wu\n", d, e, f, x); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + } + + /* Check aliasing of a and b */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a; + mpz_t d, e, f; + ulong x; + + fmpz_init(a); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + + fmpz_randtest(a, state, 200); + + fmpz_get_mpz(d, a); + x = n_randint(state, 20); + + fmpz_pow_ui(a, a, x); + flint_mpz_pow_ui(e, d, x); + + fmpz_get_mpz(f, a); + + result = (mpz_cmp(e, f) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, x = %wu\n", d, e, f, x); + abort(); + } + + fmpz_clear(a); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-powm.c b/external/flint-2.4.3/fmpz/test/t-powm.c new file mode 100644 index 0000000..4279eb7 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-powm.c @@ -0,0 +1,207 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("powm...."); + fflush(stdout); + + + + /* Compare with MPIR */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c; + mpz_t d, e, f, m; + fmpz_t x; + mpz_t y; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + fmpz_init(x); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(m); + mpz_init(y); + + fmpz_randtest(a, state, 200); + fmpz_randtest_not_zero(c, state, 200); + fmpz_abs(c, c); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(m, c); + fmpz_randtest_unsigned(x, state, 20); + fmpz_get_mpz(y, x); + + fmpz_powm(b, a, x, c); + mpz_powm(e, d, y, m); + + fmpz_get_mpz(f, b); + + result = (mpz_cmp(e, f) == 0); + if (!result) + { + flint_printf("FAIL (cmp f with MPIR e := d^y mod m):\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, y = %Zd, m = %Zd\n", d, e, f, y, m); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + fmpz_clear(x); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(m); + mpz_clear(y); + } + + /* Check aliasing of a and b */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c; + fmpz_t n; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + fmpz_init(n); + + fmpz_randtest(b, state, 200); + fmpz_randtest_not_zero(c, state, 200); + fmpz_abs(c, c); + fmpz_randtest_unsigned(n, state, 20); + + fmpz_powm(a, b, n, c); + fmpz_powm(b, b, n, c); + + result = (fmpz_equal(a, b)); + if (!result) + { + flint_printf("FAIL (alias a and b):\n"); + flint_printf("a = "), fmpz_print(a), flint_printf("\n"); + flint_printf("b = "), fmpz_print(b), flint_printf("\n"); + flint_printf("c = "), fmpz_print(c), flint_printf("\n"); + flint_printf("n = "), fmpz_print(n), flint_printf("\n"); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + fmpz_clear(n); + } + + /* Check aliasing of a and c */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c; + fmpz_t n; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + fmpz_init(n); + + fmpz_randtest(b, state, 200); + fmpz_randtest_not_zero(c, state, 200); + fmpz_abs(c, c); + fmpz_randtest_unsigned(n, state, 20); + + fmpz_powm(a, b, n, c); + fmpz_powm(c, b, n, c); + + result = (fmpz_equal(a, c)); + if (!result) + { + flint_printf("FAIL (alias a and c):\n"); + flint_printf("a = "), fmpz_print(a), flint_printf("\n"); + flint_printf("b = "), fmpz_print(b), flint_printf("\n"); + flint_printf("c = "), fmpz_print(c), flint_printf("\n"); + flint_printf("n = "), fmpz_print(n), flint_printf("\n"); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + fmpz_clear(n); + } + + /* Check aliasing of a and {b, c} */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, c; + fmpz_t n; + + fmpz_init(a); + fmpz_init(c); + fmpz_init(n); + + fmpz_randtest_not_zero(c, state, 200); + fmpz_abs(c, c); + fmpz_randtest_unsigned(n, state, 20); + + fmpz_powm(a, c, n, c); + fmpz_powm(c, c, n, c); + + result = (fmpz_equal(a, c)); + if (!result) + { + flint_printf("FAIL (alias a and b,c):\n"); + flint_printf("a = "), fmpz_print(a), flint_printf("\n"); + flint_printf("c = "), fmpz_print(c), flint_printf("\n"); + flint_printf("n = "), fmpz_print(n), flint_printf("\n"); + abort(); + } + + fmpz_clear(a); + fmpz_clear(c); + fmpz_clear(n); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} + diff --git a/external/flint-2.4.3/fmpz/test/t-powm_ui.c b/external/flint-2.4.3/fmpz/test/t-powm_ui.c new file mode 100644 index 0000000..9570ea3 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-powm_ui.c @@ -0,0 +1,194 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("powm_ui...."); + fflush(stdout); + + + + /* Compare with MPIR */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c; + mpz_t d, e, f, m; + ulong x; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(m); + + fmpz_randtest(a, state, 200); + fmpz_randtest_not_zero(c, state, 200); + fmpz_abs(c, c); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(m, c); + x = n_randtest(state); + + fmpz_powm_ui(b, a, x, c); + flint_mpz_powm_ui(e, d, x, m); + + fmpz_get_mpz(f, b); + + result = (mpz_cmp(e, f) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, x = %wu, m = %Zd\n", d, e, f, x, m); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(m); + } + + /* Check aliasing of a and b */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c; + ulong n; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + + fmpz_randtest(b, state, 200); + fmpz_randtest_not_zero(c, state, 200); + fmpz_abs(c, c); + n = n_randtest(state); + + fmpz_powm_ui(a, b, n, c); + fmpz_powm_ui(b, b, n, c); + + result = (fmpz_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpz_print(a), flint_printf("\n"); + flint_printf("b = "), fmpz_print(b), flint_printf("\n"); + flint_printf("c = "), fmpz_print(c), flint_printf("\n"); + flint_printf("n = %wu\n", n); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + } + + /* Check aliasing of a and c */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c; + ulong n; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + + fmpz_randtest(b, state, 200); + fmpz_randtest_not_zero(c, state, 200); + fmpz_abs(c, c); + n = n_randtest(state); + + fmpz_powm_ui(a, b, n, c); + fmpz_powm_ui(c, b, n, c); + + result = (fmpz_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpz_print(a), flint_printf("\n"); + flint_printf("b = "), fmpz_print(b), flint_printf("\n"); + flint_printf("c = "), fmpz_print(c), flint_printf("\n"); + flint_printf("n = %wu\n", n); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + } + + /* Check aliasing of a and {b, c} */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, c; + ulong n; + + fmpz_init(a); + fmpz_init(c); + + fmpz_randtest_not_zero(c, state, 200); + fmpz_abs(c, c); + n = n_randtest(state); + + fmpz_powm_ui(a, c, n, c); + fmpz_powm_ui(c, c, n, c); + + result = (fmpz_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpz_print(a), flint_printf("\n"); + flint_printf("c = "), fmpz_print(c), flint_printf("\n"); + flint_printf("n = %wu\n", n); + abort(); + } + + fmpz_clear(a); + fmpz_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-print_read.c b/external/flint-2.4.3/fmpz/test/t-print_read.c new file mode 100644 index 0000000..8190be2 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-print_read.c @@ -0,0 +1,265 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + + +#include +#include +#include +#include +#include + +#include "flint.h" +#include "fmpz.h" + +#if !defined (__WIN32) || defined(__CYGWIN__) + +/* + The function fdopen is declared in stdio.h. It is POSIX.1 compliant, + but not ANSI compliant. The following line enables compilation with + the "-ansi" flag. + */ +extern FILE * fdopen(int fildes, const char *mode); + +int main(void) +{ + int i, j, n = 10000, result; + + FILE *in, *out; + int fd[2]; + pid_t childpid; + + FLINT_TEST_INIT(state); + + flint_printf("print/ read...."); + fflush(stdout); + + /* Randomise n integers, write to and read from a pipe */ + { + fmpz *a; + + a = flint_calloc(n, sizeof(fmpz)); + for (i = 0; i < n; i++) + fmpz_randtest(a + i, state, 200); + + if (pipe(fd)) + { + flint_printf("FAIL:\n"); + flint_printf("Failed to set-up the pipe.\n"); + abort(); + } + + if((childpid = fork()) == -1) + { + flint_printf("FAIL:\n"); + flint_printf("Failed to fork the process.\n"); + abort(); + } + + if(childpid == 0) /* Child process */ + { + int r; + + close(fd[0]); + out = fdopen(fd[1], "w"); + if (out == NULL) + { + flint_printf("FAIL:\n"); + flint_printf("Could not open output file at the pipe.\n"); + abort(); + } + + for (j = 0; j < n; j++) + { + r = fmpz_fprint(out, a + j); + if ((j < n - 1) && (r > 0)) + r = flint_fprintf(out, "\n"); + + if (r <= 0) + { + flint_printf("FAIL:\n"); + flint_printf("Write error.\n"); + abort(); + } + } + + fclose(out); + exit(0); + } + else /* Parent process */ + { + int r; + fmpz_t t; + + close(fd[1]); + in = fdopen(fd[0], "r"); + if (in == NULL) + { + flint_printf("FAIL:\n"); + flint_printf("Could not open input file at the pipe.\n"); + abort(); + } + + fmpz_init(t); + + i = 0; + while (!feof(in)) + { + r = fmpz_fread(in, t); + if (r <= 0) + { + flint_printf("FAIL:\n"); + flint_printf("Read error.\n"); + abort(); + } + + result = fmpz_equal(t, a + i); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a[i] = "), fmpz_print(a + i), flint_printf("\n"); + flint_printf("t = "), fmpz_print(t), flint_printf("\n"); + abort(); + } + + ++i; + } + + fmpz_clear(t); + fclose(in); + } + + if (i != n) + { + flint_printf("FAIL:\n"); + flint_printf("Only %d out of %d objects were processed.\n", i, n); + abort(); + } + + for (i = 0; i < n; i++) + fmpz_clear(a + i); + flint_free(a); + } + + /* Write bad data to a pipe and read it */ + { + char str[5] = {'b', 'l', 'a', 'h', '\0'}; + + if (pipe(fd)) + { + flint_printf("FAIL:\n"); + flint_printf("Failed to set-up the pipe.\n"); + abort(); + } + + if((childpid = fork()) == -1) + { + flint_printf("FAIL:\n"); + flint_printf("Failed to fork the process.\n"); + abort(); + } + + if(childpid == 0) /* Child process */ + { + int r; + + close(fd[0]); + out = fdopen(fd[1], "w"); + if (out == NULL) + { + flint_printf("FAIL:\n"); + flint_printf("Could not open output file at the pipe.\n"); + abort(); + } + + r = flint_fprintf(out, "blah"); + if (r <= 0) + { + flint_printf("FAIL:\n"); + flint_printf("Write error.\n"); + abort(); + } + + fclose(out); + exit(0); + } + else /* Parent process */ + { + int r; + fmpz_t t; + + close(fd[1]); + in = fdopen(fd[0], "r"); + if (in == NULL) + { + flint_printf("FAIL:\n"); + flint_printf("Could not open input file at the pipe.\n"); + abort(); + } + + fmpz_init(t); + + i = 0; + while (!feof(in)) + { + r = fmpz_fread(in, t); + if (r > 0) + { + flint_printf("FAIL:\n"); + flint_printf("r = %d\n", r); + abort(); + } + ++i; + } + + fmpz_clear(t); + fclose(in); + } + + /* For {'b','l','a','h','\0'} we expect 5 reads */ + if (i != 5) + { + flint_printf("FAIL:\n"); + flint_printf("Carried out %d reads, but \"%s\" has only 4 characters.\n", i, str); + abort(); + } + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + +#else + +int main(void) +{ + flint_printf("print/ read...."); + fflush(stdout); + flint_printf("SKIPPED\n"); + return EXIT_SUCCESS; +} + +#endif diff --git a/external/flint-2.4.3/fmpz/test/t-remove.c b/external/flint-2.4.3/fmpz/test/t-remove.c new file mode 100644 index 0000000..c59eb92 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-remove.c @@ -0,0 +1,254 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("remove...."); + fflush(stdout); + + + + /* Compare with MPIR, random input */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c; + mpz_t d, e, f, g; + slong x, y; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest_not_zero(a, state, 200); + do { + fmpz_randtest_not_zero(b, state, 200); + fmpz_abs(b, b); + } while (fmpz_is_one(b)); + + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + x = fmpz_remove(c, a, b); + y = mpz_remove(f, d, e); + + fmpz_get_mpz(g, c); + + result = ((x == y) && (mpz_cmp(f, g) == 0)); + + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + /* Compare with MPIR, random input but ensure that factors exist */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c, pow; + mpz_t d, e, f, g; + slong x, y; + ulong n; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + fmpz_init(pow); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest_not_zero(a, state, 200); + do { + fmpz_randtest_not_zero(b, state, 200); + fmpz_abs(b, b); + } while (fmpz_is_one(b)); + + n = n_randint(state, 10); + fmpz_pow_ui(pow, b, n); + fmpz_mul(a, a, pow); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + x = fmpz_remove(c, a, b); + y = mpz_remove(f, d, e); + + fmpz_get_mpz(g, c); + + result = ((x == y) && (x >= n) && (mpz_cmp(f, g) == 0)); + + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + fmpz_clear(pow); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + /* Check aliasing of a and b */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_t a, c; + slong x; + + fmpz_init(a); + fmpz_init(c); + + do { + fmpz_randtest_not_zero(a, state, 200); + fmpz_abs(a, a); + } while (fmpz_is_one(a)); + + x = fmpz_remove(c, a, a); + + result = ((x == 1) && (fmpz_cmp_ui(c, 1) == 0)); + + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_print(a), flint_printf("\n"); + fmpz_print(c), flint_printf("\n"); + abort(); + } + + fmpz_clear(a); + fmpz_clear(c); + } + + /* Check aliasing of a and c */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c; + slong x, y; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + + fmpz_randtest_not_zero(a, state, 200); + do { + fmpz_randtest_not_zero(b, state, 200); + fmpz_abs(b, b); + } while (fmpz_is_one(b)); + + x = fmpz_remove(c, a, b); + y = fmpz_remove(a, a, b); + + result = ((x == y) && fmpz_equal(a, c)); + + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_print(a), flint_printf("\n"); + fmpz_print(b), flint_printf("\n"); + fmpz_print(c), flint_printf("\n"); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + } + + /* Check aliasing of b and c */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c; + slong x, y; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + + fmpz_randtest_not_zero(a, state, 200); + do { + fmpz_randtest_not_zero(b, state, 200); + fmpz_abs(b, b); + } while (fmpz_is_one(b)); + + x = fmpz_remove(c, a, b); + y = fmpz_remove(b, a, b); + + result = ((x == y) && fmpz_equal(b, c)); + + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_print(a), flint_printf("\n"); + fmpz_print(b), flint_printf("\n"); + fmpz_print(c), flint_printf("\n"); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-rfac_ui.c b/external/flint-2.4.3/fmpz/test/t-rfac_ui.c new file mode 100644 index 0000000..1632ee5 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-rfac_ui.c @@ -0,0 +1,123 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("rfac_ui... "); + fflush(stdout); + + + + /* Check aliasing */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_t x, r; + ulong a; + + fmpz_init(x); + fmpz_init(r); + + fmpz_randtest(x, state, 1 + n_randint(state, 200)); + a = n_randint(state, 100); + + fmpz_rfac_ui(r, x, a); + fmpz_rfac_ui(x, x, a); + + result = fmpz_equal(r, x); + + if (!result) + { + flint_printf("FAIL (aliasing)\n\n"); + flint_printf("x: "); fmpz_print(x); flint_printf("\n\n"); + flint_printf("a = %wu\n\n", a); + flint_printf("r: "); fmpz_print(r); flint_printf("\n\n"); + abort(); + } + + fmpz_clear(x); + fmpz_clear(r); + } + + /* Check rf(x,a) * rf(x+a,b) = rf(x,a+b) */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_t x, xa, r1, r2, r1r2, r3; + ulong a, b; + + fmpz_init(x); + fmpz_init(xa); + fmpz_init(r1); + fmpz_init(r2); + fmpz_init(r1r2); + fmpz_init(r3); + + fmpz_randtest(x, state, 1 + n_randint(state, 200)); + a = n_randint(state, 100); + b = n_randint(state, 100); + fmpz_add_ui(xa, x, a); + + fmpz_rfac_ui(r1, x, a); + fmpz_rfac_ui(r2, xa, b); + fmpz_rfac_ui(r3, x, a+b); + + fmpz_mul(r1r2, r1, r2); + + result = fmpz_equal(r1r2, r3); + + if (!result) + { + flint_printf("FAIL\n\n"); + flint_printf("x: "); fmpz_print(x); flint_printf("\n\n"); + flint_printf("a = %wu, b = %wu\n\n", a, b); + flint_printf("rf(x,a): "); fmpz_print(r1); flint_printf("\n\n"); + flint_printf("rf(x+a,b): "); fmpz_print(r2); flint_printf("\n\n"); + flint_printf("rf(x,a+b): "); fmpz_print(r3); flint_printf("\n\n"); + abort(); + } + + fmpz_clear(x); + fmpz_clear(xa); + fmpz_clear(r1); + fmpz_clear(r2); + fmpz_clear(r1r2); + fmpz_clear(r3); + } + + + flint_printf("PASS\n"); + FLINT_TEST_CLEANUP(state); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fmpz/test/t-rfac_uiui.c b/external/flint-2.4.3/fmpz/test/t-rfac_uiui.c new file mode 100644 index 0000000..3f8434b --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-rfac_uiui.c @@ -0,0 +1,94 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("rfac_uiui... "); + fflush(stdout); + + + + /* Check rf(x,a) * rf(x+a,b) = rf(x,a+b) */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_t xa, r1, r2, r1r2, r3; + mp_limb_t x; + ulong a, b; + + fmpz_init(xa); + fmpz_init(r1); + fmpz_init(r2); + fmpz_init(r1r2); + fmpz_init(r3); + + x = n_randlimb(state); + a = n_randint(state, 100); + b = n_randint(state, 100); + + fmpz_set_ui(xa, x); + fmpz_add_ui(xa, xa, a); + + fmpz_rfac_uiui(r1, x, a); + fmpz_rfac_ui(r2, xa, b); + fmpz_rfac_uiui(r3, x, a+b); + + fmpz_mul(r1r2, r1, r2); + + result = fmpz_equal(r1r2, r3); + + if (!result) + { + flint_printf("FAIL\n\n"); + flint_printf("x: %wu", x); flint_printf("\n\n"); + flint_printf("a = %wu, b = %wu\n\n", a, b); + flint_printf("rf(x,a): "); fmpz_print(r1); flint_printf("\n\n"); + flint_printf("rf(x+a,b): "); fmpz_print(r2); flint_printf("\n\n"); + flint_printf("rf(x,a+b): "); fmpz_print(r3); flint_printf("\n\n"); + abort(); + } + + fmpz_clear(xa); + fmpz_clear(r1); + fmpz_clear(r2); + fmpz_clear(r1r2); + fmpz_clear(r3); + } + + + flint_printf("PASS\n"); + FLINT_TEST_CLEANUP(state); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fmpz/test/t-root.c b/external/flint-2.4.3/fmpz/test/t-root.c new file mode 100644 index 0000000..527bf91 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-root.c @@ -0,0 +1,130 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009, 2011 William Hart + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("root...."); + fflush(stdout); + + + + /* Comparison with mpz routines */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t f, g; + mpz_t mf, mf2, mg; + slong n; + + fmpz_init(f); + fmpz_init(g); + + mpz_init(mf); + mpz_init(mf2); + mpz_init(mg); + + n = n_randint(state, 20) + 1; + + fmpz_randtest(g, state, 200); + if ((n & 1) == 0) + fmpz_abs(g, g); + fmpz_get_mpz(mg, g); + + fmpz_root(f, g, n); + mpz_root(mf, mg, n); + + fmpz_get_mpz(mf2, f); + + result = (mpz_cmp(mf2, mf) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("mf = %Zd, mf2 = %Zd, mg = %Zd, root = %wd\n", mf, mf2, mg, n); + abort(); + } + + fmpz_clear(f); + fmpz_clear(g); + + mpz_clear(mf); + mpz_clear(mf2); + mpz_clear(mg); + } + + /* Check aliasing of f and g */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t f; + mpz_t mf, mf2; + slong n; + + fmpz_init(f); + + mpz_init(mf); + mpz_init(mf2); + + n = n_randint(state, 20) + 1; + + fmpz_randtest(f, state, 200); + if ((n & 1) == 0) + fmpz_abs(f, f); + fmpz_get_mpz(mf, f); + + fmpz_root(f, f, n); + mpz_root(mf, mf, n); + + fmpz_get_mpz(mf2, f); + + result = (mpz_cmp(mf, mf2) == 0); + + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("mf = %Zd, mf2 = %Zd, root = %wd\n", mf, mf2, n); + abort(); + } + + fmpz_clear(f); + + mpz_clear(mf); + mpz_clear(mf2); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-set.c b/external/flint-2.4.3/fmpz/test/t-set.c new file mode 100644 index 0000000..03a1663 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-set.c @@ -0,0 +1,87 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + + FLINT_TEST_INIT(state); + + + flint_printf("set...."); + fflush(stdout); + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t c, d; + mp_bitcnt_t bits; + + mpz_init(c); + mpz_init(d); + + bits = n_randint(state, 200) + 1; + + _flint_rand_init_gmp(state); + mpz_rrandomb(c, state->gmp_state, bits); + + if (n_randint(state, 2)) + mpz_neg(c, c); + + fmpz_init(a); + fmpz_init(b); + + fmpz_set_mpz(a, c); + fmpz_set(b, a); + fmpz_get_mpz(d, b); + + result = (mpz_cmp(c, d) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("c = %Zd, d = %Zd\n", c, d); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + + mpz_clear(c); + mpz_clear(d); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-set_ui_smod.c b/external/flint-2.4.3/fmpz/test/t-set_ui_smod.c new file mode 100644 index 0000000..5620731 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-set_ui_smod.c @@ -0,0 +1,81 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + flint_printf("set_ui_smod...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, mz; + mp_limb_t m, r; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(mz); + + do { m = n_randtest(state); } while (m < 2); + + fmpz_set_ui(mz, m); + fmpz_randtest_mod_signed(a, state, mz); + + r = fmpz_fdiv_ui(a, m); + + fmpz_set_ui_smod(b, r, m); + + if (!fmpz_equal(a, b)) + { + flint_printf("FAIL:\n"); + flint_printf("a: "); fmpz_print(a); flint_printf("\n"); + flint_printf("m: %wu\n", m); + flint_printf("r: %wu\n", m); + flint_printf("b: "); fmpz_print(b); flint_printf("\n"); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(mz); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-set_uiui.c b/external/flint-2.4.3/fmpz/test/t-set_uiui.c new file mode 100644 index 0000000..0850f50 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-set_uiui.c @@ -0,0 +1,80 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + + FLINT_TEST_INIT(state); + + + flint_printf("set_uiui...."); + fflush(stdout); + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + ulong hi, lo; + + hi = n_randtest(state); + lo = n_randtest(state); + + fmpz_init(a); + fmpz_init(b); + + fmpz_set_ui(a, hi); + fmpz_mul_2exp(a, a, FLINT_BITS); + fmpz_add_ui(a, a, lo); + + fmpz_set_uiui(b, hi, lo); + + result = fmpz_equal(a, b); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("hi = %wu\n", hi); + flint_printf("lo = %wu\n", lo); + flint_printf("a = "); fmpz_print(a); flint_printf("\n"); + flint_printf("b = "); fmpz_print(b); flint_printf("\n"); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-setbit.c b/external/flint-2.4.3/fmpz/test/t-setbit.c new file mode 100644 index 0000000..34c1212 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-setbit.c @@ -0,0 +1,88 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("setbit...."); + fflush(stdout); + + + + for (i = 0; i < 100000 * flint_test_multiplier(); i++) + { + ulong j; + fmpz_t a, b, c; + mpz_t z; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + mpz_init(z); + + fmpz_randtest(a, state, 2 * FLINT_BITS); + fmpz_set(b, a); + fmpz_get_mpz(z, b); + j = n_randint(state, 3 * FLINT_BITS); + + fmpz_setbit(b, j); + mpz_setbit(z, j); + fmpz_set_mpz(c, z); + + result = (fmpz_equal(b, c)); + + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpz_print(a), flint_printf("\n"); + flint_printf("b = "), fmpz_print(b), flint_printf("\n"); + flint_printf("c = "), fmpz_print(c), flint_printf("\n"); + gmp_printf("z = %Zd\n", z); + flint_printf("j = %wd\n", j); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + mpz_clear(z); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-sgn.c b/external/flint-2.4.3/fmpz/test/t-sgn.c new file mode 100644 index 0000000..10c9ef6 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-sgn.c @@ -0,0 +1,78 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("sgn...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a; + mpz_t b; + mp_size_t r1, r2; + + fmpz_init(a); + + mpz_init(b); + + fmpz_randtest(a, state, 200); + + fmpz_get_mpz(b, a); + + r1 = fmpz_sgn(a); + r2 = mpz_sgn(b); + result = (r1 == r2); + + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("b = %Zd\n", b); + abort(); + } + + fmpz_clear(a); + + mpz_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-size.c b/external/flint-2.4.3/fmpz/test/t-size.c new file mode 100644 index 0000000..8554838 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-size.c @@ -0,0 +1,78 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("size...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a; + mpz_t b; + mp_size_t r1, r2; + + fmpz_init(a); + + mpz_init(b); + + fmpz_randtest(a, state, 200); + + fmpz_get_mpz(b, a); + + r1 = fmpz_size(a); + r2 = mpz_size(b); + result = (r1 == r2); + + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("b = %Zd\n", b); + abort(); + } + + fmpz_clear(a); + + mpz_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-sizeinbase.c b/external/flint-2.4.3/fmpz/test/t-sizeinbase.c new file mode 100644 index 0000000..0cb1ce2 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-sizeinbase.c @@ -0,0 +1,81 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("sizeinbase...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a; + mpz_t b; + int base; + size_t r1, r2; + + fmpz_init(a); + mpz_init(b); + fmpz_randtest(a, state, 200); + base = (int) (n_randint(state, 61) + 2); + + fmpz_get_mpz(b, a); + + r1 = fmpz_sizeinbase(a, base); + r2 = mpz_sizeinbase(b, base); + result = (r1 == r2 || r1 + 1 == r2); + + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("b = %Zd\n", b); + flint_printf("base = %d\n", base); + flint_printf("r1 = %wu\n, r2 = %wu\n", (ulong) r1, (ulong) r2); + abort(); + } + + fmpz_clear(a); + mpz_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-sqrt.c b/external/flint-2.4.3/fmpz/test/t-sqrt.c new file mode 100644 index 0000000..3f95ca4 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-sqrt.c @@ -0,0 +1,122 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("sqrt...."); + fflush(stdout); + + + + /* Comparison with mpz routines */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t f, g; + mpz_t mf, mf2, mg; + + fmpz_init(f); + fmpz_init(g); + + mpz_init(mf); + mpz_init(mf2); + mpz_init(mg); + + fmpz_randtest(g, state, 200); + fmpz_abs(g, g); + fmpz_get_mpz(mg, g); + + fmpz_sqrt(f, g); + mpz_sqrt(mf, mg); + + fmpz_get_mpz(mf2, f); + + result = (mpz_cmp(mf2, mf) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("mf = %Zd, mf2 = %Zd, mg = %Zd\n", mf, mf2, mg); + abort(); + } + + fmpz_clear(f); + fmpz_clear(g); + + mpz_clear(mf); + mpz_clear(mf2); + mpz_clear(mg); + } + + /* Check aliasing of f and g */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t f; + mpz_t mf, mf2; + + fmpz_init(f); + + mpz_init(mf); + mpz_init(mf2); + + fmpz_randtest(f, state, 200); + fmpz_abs(f, f); + fmpz_get_mpz(mf, f); + + fmpz_sqrt(f, f); + mpz_sqrt(mf, mf); + + fmpz_get_mpz(mf2, f); + + result = (mpz_cmp(mf, mf2) == 0); + + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("mf = %Zd, mf2 = %Zd\n", mf, mf2); + abort(); + } + + fmpz_clear(f); + + mpz_clear(mf); + mpz_clear(mf2); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-sqrtmod.c b/external/flint-2.4.3/fmpz/test/t-sqrtmod.c new file mode 100644 index 0000000..9675801 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-sqrtmod.c @@ -0,0 +1,141 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("sqrtmod...."); + fflush(stdout); + + + + for (i = 0; i < 100 * flint_test_multiplier(); i++) /* Test random integers */ + { + int ans; + fmpz_t a, b, c, p; + mp_limb_t prime; + + prime = n_randint(state, UWORD(1) << (FLINT_BITS - 1)); + prime = n_nextprime(prime, 1); + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + fmpz_init(p); + + fmpz_set_ui(p, prime); + fmpz_randm(a, state, p); + + ans = fmpz_sqrtmod(b, a, p); + + fmpz_mul(c, b, b); + fmpz_mod(c, c, p); + + result = (ans == 0 || fmpz_equal(a, c)); + if (!result) + { + flint_printf("FAIL (random):\n"); + flint_printf("p = "), fmpz_print(p), flint_printf("\n"); + flint_printf("a = "), fmpz_print(a), flint_printf("\n"); + flint_printf("b = "), fmpz_print(b), flint_printf("\n"); + flint_printf("c = "), fmpz_print(c), flint_printf("\n"); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + fmpz_clear(p); + } + + for (i = 0; i < 100 * flint_test_multiplier(); i++) /* Test random squares */ + { + int ans; + fmpz_t a, b, c, d, p; + mp_limb_t prime; + + prime = n_randint(state, UWORD(1) << (FLINT_BITS - 1)); + prime = n_nextprime(prime, 1); + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + fmpz_init(d); + fmpz_init(p); + + fmpz_set_ui(p, prime); + do + fmpz_randm(b, state, p); + while (fmpz_is_zero(b)); + + fmpz_mul(a, b, b); + fmpz_mod(a, a, p); + + /* check a special case */ + if (i == 0) + { + fmpz_set_str(p, "15951355998396157", 10); + fmpz_set_str(a, "7009303413761286", 10); + } + + ans = fmpz_sqrtmod(c, a, p); + + fmpz_mul(d, c, c); + fmpz_mod(d, d, p); + + result = (ans && fmpz_equal(a, d)); + if (!result) + { + flint_printf("FAIL (squares):\n"); + flint_printf("p = "), fmpz_print(p), flint_printf("\n"); + flint_printf("a (= b^2) = "), fmpz_print(a), flint_printf("\n"); + flint_printf("b = "), fmpz_print(b), flint_printf("\n"); + flint_printf("c (= sqrt(a) = "), fmpz_print(c), flint_printf("\n"); + flint_printf("d (= c^2) = "), fmpz_print(d), flint_printf("\n"); + flint_printf("ans = %d\n", ans); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + fmpz_clear(d); + fmpz_clear(p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-sqrtrem.c b/external/flint-2.4.3/fmpz/test/t-sqrtrem.c new file mode 100644 index 0000000..9daacaf --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-sqrtrem.c @@ -0,0 +1,168 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("sqrtrem...."); + fflush(stdout); + + + + /* Comparison with mpz routines */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t f, r, g; + mpz_t mf, mf2, mr, mg; + + fmpz_init(f); + fmpz_init(r); + fmpz_init(g); + + mpz_init(mf); + mpz_init(mf2); + mpz_init(mr); + mpz_init(mg); + + fmpz_randtest(g, state, 200); + fmpz_abs(g, g); + fmpz_get_mpz(mg, g); + + fmpz_sqrtrem(f, r, g); + mpz_sqrtrem(mf, mr, mg); + + fmpz_get_mpz(mf2, f); + + result = (mpz_cmp(mf2, mf) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("mf = %Zd, mf2 = %Zd, mr = %Zd, mg = %Zd\n", mf, mf2, + mr, mg); + abort(); + } + + fmpz_clear(f); + fmpz_clear(r); + fmpz_clear(g); + + mpz_clear(mf); + mpz_clear(mf2); + mpz_clear(mr); + mpz_clear(mg); + } + + /* Check aliasing of r and g */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, f; + mpz_t ma, mf, mf2; + + fmpz_init(a); + fmpz_init(f); + + mpz_init(ma); + mpz_init(mf); + mpz_init(mf2); + + fmpz_randtest(a, state, 200); + fmpz_abs(a, a); + fmpz_get_mpz(ma, a); + + fmpz_sqrtrem(f, a, a); + mpz_sqrtrem(mf, ma, ma); + + fmpz_get_mpz(mf2, f); + + result = (mpz_cmp(mf, mf2) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("ma = %Zd, mf = %Zd, mf2 = %Zd\n", ma, mf, mf2); + abort(); + } + + fmpz_clear(a); + fmpz_clear(f); + + mpz_clear(ma); + mpz_clear(mf); + mpz_clear(mf2); + } + + /* Check aliasing of f and g */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t r, f; + mpz_t mr, mf, mf2; + + fmpz_init(r); + fmpz_init(f); + + mpz_init(mr); + mpz_init(mf); + mpz_init(mf2); + + fmpz_randtest(f, state, 200); + fmpz_abs(f, f); + fmpz_get_mpz(mf, f); + + fmpz_sqrtrem(f, r, f); + mpz_sqrtrem(mf, mr, mf); + + fmpz_get_mpz(mf2, f); + + result = (mpz_cmp(mf, mf2) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("mr = %Zd, mf = %Zd, mf2 = %Zd\n", mr, mf, mf2); + abort(); + } + + fmpz_clear(r); + fmpz_clear(f); + + mpz_clear(mr); + mpz_clear(mf); + mpz_clear(mf2); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-sub.c b/external/flint-2.4.3/fmpz/test/t-sub.c new file mode 100644 index 0000000..717837f --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-sub.c @@ -0,0 +1,213 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("sub...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c; + mpz_t d, e, f, g; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + fmpz_randtest(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_sub(c, a, b); + mpz_sub(f, d, e); + + fmpz_get_mpz(g, c); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + /* Check aliasing of a and b */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, c; + mpz_t d, f, g; + + fmpz_init(a); + fmpz_init(c); + + mpz_init(d); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + + fmpz_get_mpz(d, a); + + fmpz_sub(c, a, a); + mpz_sub(f, d, d); + + fmpz_get_mpz(g, c); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, f = %Zd, g = %Zd\n", d, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(c); + + mpz_clear(d); + mpz_clear(f); + mpz_clear(g); + } + + /* Test aliasing of a and c */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t d, e, f, g; + + fmpz_init(a); + fmpz_init(b); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + fmpz_randtest(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_sub(a, a, b); + mpz_sub(f, d, e); + + fmpz_get_mpz(g, a); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + /* Test aliasing of b and c */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t d, e, f, g; + + fmpz_init(a); + fmpz_init(b); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + fmpz_randtest(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_sub(b, a, b); + mpz_sub(f, d, e); + + fmpz_get_mpz(g, b); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-sub_ui.c b/external/flint-2.4.3/fmpz/test/t-sub_ui.c new file mode 100644 index 0000000..d5f2d16 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-sub_ui.c @@ -0,0 +1,125 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("sub_ui...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t d, e, f; + ulong x; + + fmpz_init(a); + fmpz_init(b); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + + fmpz_randtest(a, state, 200); + + fmpz_get_mpz(d, a); + x = n_randtest(state); + + fmpz_sub_ui(b, a, x); + flint_mpz_sub_ui(e, d, x); + + fmpz_get_mpz(f, b); + + result = (mpz_cmp(e, f) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, x = %wu\n", d, e, f, x); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + } + + /* Check aliasing of a and b */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a; + mpz_t d, e, f; + ulong x; + + fmpz_init(a); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + + fmpz_randtest(a, state, 200); + + fmpz_get_mpz(d, a); + x = n_randtest(state); + + fmpz_sub_ui(a, a, x); + flint_mpz_sub_ui(e, d, x); + + fmpz_get_mpz(f, a); + + result = (mpz_cmp(e, f) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, x = %wu\n", d, e, f, x); + abort(); + } + + fmpz_clear(a); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-submul.c b/external/flint-2.4.3/fmpz/test/t-submul.c new file mode 100644 index 0000000..c438021 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-submul.c @@ -0,0 +1,214 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("submul...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c; + mpz_t d, e, f, g; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + fmpz_randtest(b, state, 200); + fmpz_randtest(c, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + fmpz_get_mpz(f, c); + + fmpz_submul(c, a, b); + mpz_submul(f, d, e); + + fmpz_get_mpz(g, c); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + /* Check aliasing of a and b */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, c; + mpz_t d, f, g; + + fmpz_init(a); + fmpz_init(c); + + mpz_init(d); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + fmpz_randtest(c, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(f, c); + + fmpz_submul(c, a, a); + mpz_submul(f, d, d); + + fmpz_get_mpz(g, c); + + result = (mpz_cmp(f, g) == 0); + + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, f = %Zd, g = %Zd\n", d, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(c); + + mpz_clear(d); + mpz_clear(f); + mpz_clear(g); + } + + /* Test aliasing of a and c */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t d, e, f; + + fmpz_init(a); + fmpz_init(b); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + + fmpz_randtest(a, state, 200); + fmpz_randtest(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_submul(a, a, b); + mpz_submul(d, d, e); + + fmpz_get_mpz(f, a); + + result = (mpz_cmp(d, f) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd\n", d, e, f); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + } + + /* Test aliasing of b and c */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t d, e, f; + + fmpz_init(a); + fmpz_init(b); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + + fmpz_randtest(a, state, 200); + fmpz_randtest(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_submul(b, a, b); + mpz_submul(e, d, e); + + fmpz_get_mpz(f, b); + + result = (mpz_cmp(f, e) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd\n", d, e, f); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-submul_ui.c b/external/flint-2.4.3/fmpz/test/t-submul_ui.c new file mode 100644 index 0000000..f205397 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-submul_ui.c @@ -0,0 +1,125 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("submul_ui...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t d, e, f; + ulong x; + + fmpz_init(a); + fmpz_init(b); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + + fmpz_randtest(a, state, 200); + fmpz_randtest(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + x = n_randtest(state); + + fmpz_submul_ui(b, a, x); + flint_mpz_submul_ui(e, d, x); + + fmpz_get_mpz(f, b); + + result = (mpz_cmp(e, f) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, x = %wu\n", d, e, f, x); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + } + + /* Check aliasing of a and b */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a; + mpz_t d, e; + ulong x; + + fmpz_init(a); + + mpz_init(d); + mpz_init(e); + + fmpz_randtest(a, state, 200); + + fmpz_get_mpz(d, a); + x = n_randtest(state); + + fmpz_submul_ui(a, a, x); + flint_mpz_submul_ui(d, d, x); + + fmpz_get_mpz(e, a); + + result = (mpz_cmp(d, e) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, x = %wu\n", d, e, x); + abort(); + } + + fmpz_clear(a); + + mpz_clear(d); + mpz_clear(e); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-swap.c b/external/flint-2.4.3/fmpz/test/t-swap.c new file mode 100644 index 0000000..6f24e85 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-swap.c @@ -0,0 +1,83 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("swap...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t c, d; + + fmpz_init(a); + fmpz_init(b); + + mpz_init(c); + mpz_init(d); + + fmpz_randtest(a, state, 200); + fmpz_randtest(b, state, 200); + + fmpz_get_mpz(c, a); + + fmpz_swap(a, b); + + fmpz_get_mpz(d, b); + + result = (mpz_cmp(c, d) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("c = %Zd, d = %Zd\n", c, d); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + + mpz_clear(c); + mpz_clear(d); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-tdiv_q.c b/external/flint-2.4.3/fmpz/test/t-tdiv_q.c new file mode 100644 index 0000000..594cdf4 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-tdiv_q.c @@ -0,0 +1,214 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("tdiv_q...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c; + mpz_t d, e, f, g; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + fmpz_randtest_not_zero(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_tdiv_q(c, a, b); + mpz_tdiv_q(f, d, e); + + fmpz_get_mpz(g, c); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + /* Check aliasing of a and b */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, c; + mpz_t d, f, g; + + fmpz_init(a); + fmpz_init(c); + + mpz_init(d); + mpz_init(f); + mpz_init(g); + + fmpz_randtest_not_zero(a, state, 200); + + fmpz_get_mpz(d, a); + + fmpz_tdiv_q(c, a, a); + mpz_tdiv_q(f, d, d); + + fmpz_get_mpz(g, c); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, f = %Zd, g = %Zd\n", d, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(c); + + mpz_clear(d); + mpz_clear(f); + mpz_clear(g); + } + + /* Test aliasing of a and c */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t d, e, f, g; + + fmpz_init(a); + fmpz_init(b); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + fmpz_randtest_not_zero(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_tdiv_q(a, a, b); + mpz_tdiv_q(f, d, e); + + fmpz_get_mpz(g, a); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + /* Test aliasing of b and c */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t d, e, f, g; + + fmpz_init(a); + fmpz_init(b); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + fmpz_randtest_not_zero(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_tdiv_q(b, a, b); + mpz_tdiv_q(f, d, e); + + fmpz_get_mpz(g, b); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-tdiv_q_2exp.c b/external/flint-2.4.3/fmpz/test/t-tdiv_q_2exp.c new file mode 100644 index 0000000..49a32ec --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-tdiv_q_2exp.c @@ -0,0 +1,125 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("tdiv_q_2exp...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t d, e, f; + ulong x; + + fmpz_init(a); + fmpz_init(b); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + + fmpz_randtest(a, state, 200); + + fmpz_get_mpz(d, a); + x = n_randint(state, 200); + + fmpz_tdiv_q_2exp(b, a, x); + mpz_tdiv_q_2exp(e, d, x); + + fmpz_get_mpz(f, b); + + result = (mpz_cmp(e, f) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, exp = %wu\n", d, e, f, x); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + } + + /* Check aliasing of a and b */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a; + mpz_t d, e, f; + ulong x; + + fmpz_init(a); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + + fmpz_randtest(a, state, 200); + + fmpz_get_mpz(d, a); + x = n_randint(state, 200); + + fmpz_tdiv_q_2exp(a, a, x); + mpz_tdiv_q_2exp(e, d, x); + + fmpz_get_mpz(f, a); + + result = (mpz_cmp(e, f) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, exp = %wu\n", d, e, f, x); + abort(); + } + + fmpz_clear(a); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-tdiv_q_si.c b/external/flint-2.4.3/fmpz/test/t-tdiv_q_si.c new file mode 100644 index 0000000..f1a43b5 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-tdiv_q_si.c @@ -0,0 +1,131 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("tdiv_q_si...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + slong b; + fmpz_t a, c; + mpz_t d, e, f, g; + + fmpz_init(a); + fmpz_init(c); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + b = z_randtest_not_zero(state); + + fmpz_get_mpz(d, a); + flint_mpz_set_si(e, b); + + fmpz_tdiv_q_si(c, a, b); + mpz_tdiv_q(f, d, e); + + fmpz_get_mpz(g, c); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL (1):\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(c); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + /* Test aliasing of a and c */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + slong b; + fmpz_t a; + mpz_t d, e, f, g; + + fmpz_init(a); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + b = z_randtest_not_zero(state); + + fmpz_get_mpz(d, a); + flint_mpz_set_si(e, b); + + fmpz_tdiv_q_si(a, a, b); + mpz_tdiv_q(f, d, e); + + fmpz_get_mpz(g, a); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL (2):\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-tdiv_q_ui.c b/external/flint-2.4.3/fmpz/test/t-tdiv_q_ui.c new file mode 100644 index 0000000..b6ecb8f --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-tdiv_q_ui.c @@ -0,0 +1,131 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("tdiv_q_ui...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + ulong b; + fmpz_t a, c; + mpz_t d, e, f, g; + + fmpz_init(a); + fmpz_init(c); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + b = n_randtest_not_zero(state); + + fmpz_get_mpz(d, a); + flint_mpz_set_ui(e, b); + + fmpz_tdiv_q_ui(c, a, b); + mpz_tdiv_q(f, d, e); + + fmpz_get_mpz(g, c); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL (1):\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(c); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + /* Test aliasing of a and c */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + ulong b; + fmpz_t a; + mpz_t d, e, f, g; + + fmpz_init(a); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + b = n_randtest_not_zero(state); + + fmpz_get_mpz(d, a); + flint_mpz_set_ui(e, b); + + fmpz_tdiv_q_ui(a, a, b); + mpz_tdiv_q(f, d, e); + + fmpz_get_mpz(g, a); + + result = (mpz_cmp(f, g) == 0); + if (!result) + { + flint_printf("FAIL (2):\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-tdiv_qr.c b/external/flint-2.4.3/fmpz/test/t-tdiv_qr.c new file mode 100644 index 0000000..4b9a446 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-tdiv_qr.c @@ -0,0 +1,312 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("tdiv_qr...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c, r; + mpz_t d, e, f, g, h, s; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + fmpz_init(r); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + mpz_init(h); + mpz_init(s); + + fmpz_randtest(a, state, 200); + fmpz_randtest_not_zero(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_tdiv_qr(c, r, a, b); + mpz_tdiv_qr(f, s, d, e); + + fmpz_get_mpz(g, c); + fmpz_get_mpz(h, r); + + result = (mpz_cmp(f, g) == 0 && mpz_cmp(h, s) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf + ("d = %Zd, e = %Zd, f = %Zd, g = %Zd, h = %Zd, s = %Zd\n", d, + e, f, g, h, s); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + fmpz_clear(r); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + mpz_clear(h); + mpz_clear(s); + } + + /* Check aliasing of c and a */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c, r; + mpz_t d, e, f, g, h, s; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + fmpz_init(r); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + mpz_init(h); + mpz_init(s); + + fmpz_randtest(a, state, 200); + fmpz_randtest_not_zero(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_tdiv_qr(a, r, a, b); + mpz_tdiv_qr(f, s, d, e); + + fmpz_get_mpz(g, a); + fmpz_get_mpz(h, r); + + result = (mpz_cmp(f, g) == 0 && mpz_cmp(h, s) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf + ("d = %Zd, e = %Zd, f = %Zd, g = %Zd, h = %Zd, s = %Zd\n", d, + e, f, g, h, s); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + fmpz_clear(r); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + mpz_clear(h); + mpz_clear(s); + } + + /* Check aliasing of c and b */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c, r; + mpz_t d, e, f, g, h, s; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + fmpz_init(r); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + mpz_init(h); + mpz_init(s); + + fmpz_randtest(a, state, 200); + fmpz_randtest_not_zero(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_tdiv_qr(b, r, a, b); + mpz_tdiv_qr(f, s, d, e); + + fmpz_get_mpz(g, b); + fmpz_get_mpz(h, r); + + result = (mpz_cmp(f, g) == 0 && mpz_cmp(h, s) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf + ("d = %Zd, e = %Zd, f = %Zd, g = %Zd, h = %Zd, s = %Zd\n", d, + e, f, g, h, s); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + fmpz_clear(r); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + mpz_clear(h); + mpz_clear(s); + } + + /* Check aliasing of r and a */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c, r; + mpz_t d, e, f, g, h, s; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + fmpz_init(r); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + mpz_init(h); + mpz_init(s); + + fmpz_randtest(a, state, 200); + fmpz_randtest_not_zero(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_tdiv_qr(c, a, a, b); + mpz_tdiv_qr(f, s, d, e); + + fmpz_get_mpz(g, c); + fmpz_get_mpz(h, a); + + result = (mpz_cmp(f, g) == 0 && mpz_cmp(h, s) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf + ("d = %Zd, e = %Zd, f = %Zd, g = %Zd, h = %Zd, s = %Zd\n", d, + e, f, g, h, s); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + fmpz_clear(r); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + mpz_clear(h); + mpz_clear(s); + } + + /* Check aliasing of r and b */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c, r; + mpz_t d, e, f, g, h, s; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + fmpz_init(r); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + mpz_init(h); + mpz_init(s); + + fmpz_randtest(a, state, 200); + fmpz_randtest_not_zero(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_tdiv_qr(c, b, a, b); + mpz_tdiv_qr(f, s, d, e); + + fmpz_get_mpz(g, c); + fmpz_get_mpz(h, b); + + result = (mpz_cmp(f, g) == 0 && mpz_cmp(h, s) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf + ("d = %Zd, e = %Zd, f = %Zd, g = %Zd, h = %Zd, s = %Zd\n", d, + e, f, g, h, s); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + fmpz_clear(r); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + mpz_clear(h); + mpz_clear(s); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-tdiv_ui.c b/external/flint-2.4.3/fmpz/test/t-tdiv_ui.c new file mode 100644 index 0000000..874cf56 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-tdiv_ui.c @@ -0,0 +1,78 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("tdiv_ui...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a; + mpz_t b; + ulong x, r1, r2; + + fmpz_init(a); + mpz_init(b); + + fmpz_randtest(a, state, 200); + + fmpz_get_mpz(b, a); + x = n_randtest_not_zero(state); + + r1 = fmpz_tdiv_ui(a, x); + r2 = flint_mpz_tdiv_ui(b, x); + + result = (r1 == r2); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf + ("b = %Zd, x = %wu, r1 = %wu, r2 = %wu\n", b, x, r1, r2); + abort(); + } + + fmpz_clear(a); + mpz_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-tstbit.c b/external/flint-2.4.3/fmpz/test/t-tstbit.c new file mode 100644 index 0000000..4f28c2a --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-tstbit.c @@ -0,0 +1,79 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("tstbit...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + int k, l; + ulong j; + fmpz_t a; + mpz_t b; + + fmpz_init(a); + mpz_init(b); + + fmpz_randtest(a, state, 2 * FLINT_BITS); + fmpz_get_mpz(b, a); + j = n_randint(state, 3 * FLINT_BITS); + + k = fmpz_tstbit(a, j); + l = mpz_tstbit(b, j); + + result = (k == l); + + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("b = %Zd, j = %wu k = %d, l = %d\n", b, j, k, l); + abort(); + } + + fmpz_clear(a); + mpz_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-val2.c b/external/flint-2.4.3/fmpz/test/t-val2.c new file mode 100644 index 0000000..3ce0a52 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-val2.c @@ -0,0 +1,85 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("val2...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t x; + slong v1, v2; + + fmpz_init(x); + + /* Test special case */ + if (n_randint(state, 1000) == 0) + { + fmpz_zero(x); + v1 = 0; + } + else + { + do { + fmpz_randtest(x, state, 1000); + } while (fmpz_is_even(x)); + + v1 = n_randint(state, 1000); + fmpz_mul_2exp(x, x, v1); + } + + v2 = fmpz_val2(x); + + result = ((v1 == v2) == 1); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("v1 = %wd v2 = %wd\n", v1, v2); + abort(); + } + + fmpz_clear(x); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/test/t-xgcd.c b/external/flint-2.4.3/fmpz/test/t-xgcd.c new file mode 100644 index 0000000..93d3877 --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-xgcd.c @@ -0,0 +1,305 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("xgcd...."); + fflush(stdout); + + + + /* Test aliasing of d and f, a and g */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_t d, a, b, c, f, g, F, G; + + fmpz_init(d); + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + fmpz_init(f); + fmpz_init(g); + fmpz_init(F); + fmpz_init(G); + + fmpz_randtest_unsigned(G, state, 200); + fmpz_add_ui(G, G, 1); + fmpz_randm(F, state, G); + if (n_randint(state, 2)) fmpz_neg(G, G); + if (n_randint(state, 2)) fmpz_neg(F, F); + fmpz_set(f, F); + fmpz_set(g, G); + + fmpz_xgcd(d, a, b, f, g); + fmpz_xgcd(f, g, c, f, g); + + result = (fmpz_equal(d, f) + && fmpz_equal(b, c) + && fmpz_equal(a, g)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("d = "), fmpz_print(d), flint_printf("\n"); + flint_printf("a = "), fmpz_print(a), flint_printf("\n"); + flint_printf("b = "), fmpz_print(b), flint_printf("\n"); + flint_printf("c = "), fmpz_print(c), flint_printf("\n"); + flint_printf("f = "), fmpz_print(f), flint_printf("\n"); + flint_printf("g = "), fmpz_print(g), flint_printf("\n"); + flint_printf("F = "), fmpz_print(F), flint_printf("\n"); + flint_printf("G = "), fmpz_print(G), flint_printf("\n"); + abort(); + } + + fmpz_clear(d); + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + fmpz_clear(f); + fmpz_clear(g); + fmpz_clear(F); + fmpz_clear(G); + } + + /* Test aliasing of a and f, d and g */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_t d, a, b, c, f, g, F, G; + + fmpz_init(d); + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + fmpz_init(f); + fmpz_init(g); + fmpz_init(F); + fmpz_init(G); + + fmpz_randtest_unsigned(G, state, 200); + fmpz_add_ui(G, G, 1); + fmpz_randm(F, state, G); + if (n_randint(state, 2)) fmpz_neg(G, G); + if (n_randint(state, 2)) fmpz_neg(F, F); + fmpz_set(f, F); + fmpz_set(g, G); + + fmpz_xgcd(d, a, b, f, g); + fmpz_xgcd(g, f, c, f, g); + + result = (fmpz_equal(d, g) + && fmpz_equal(b, c) + && fmpz_equal(a, f)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("d = "), fmpz_print(d), flint_printf("\n"); + flint_printf("a = "), fmpz_print(a), flint_printf("\n"); + flint_printf("b = "), fmpz_print(b), flint_printf("\n"); + flint_printf("c = "), fmpz_print(c), flint_printf("\n"); + flint_printf("f = "), fmpz_print(f), flint_printf("\n"); + flint_printf("g = "), fmpz_print(g), flint_printf("\n"); + flint_printf("F = "), fmpz_print(F), flint_printf("\n"); + flint_printf("G = "), fmpz_print(G), flint_printf("\n"); + abort(); + } + + fmpz_clear(d); + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + fmpz_clear(f); + fmpz_clear(g); + fmpz_clear(F); + fmpz_clear(G); + } + + /* Test aliasing of d and f, b and g */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_t d, a, b, c, f, g, F, G; + + fmpz_init(d); + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + fmpz_init(f); + fmpz_init(g); + fmpz_init(F); + fmpz_init(G); + + fmpz_randtest_unsigned(G, state, 200); + fmpz_add_ui(G, G, 1); + fmpz_randm(F, state, G); + if (n_randint(state, 2)) fmpz_neg(G, G); + if (n_randint(state, 2)) fmpz_neg(F, F); + fmpz_set(f, F); + fmpz_set(g, G); + + fmpz_xgcd(d, a, b, f, g); + fmpz_xgcd(f, c, g, f, g); + + result = (fmpz_equal(d, f) + && fmpz_equal(a, c) + && fmpz_equal(b, g)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("d = "), fmpz_print(d), flint_printf("\n"); + flint_printf("a = "), fmpz_print(a), flint_printf("\n"); + flint_printf("b = "), fmpz_print(b), flint_printf("\n"); + flint_printf("c = "), fmpz_print(c), flint_printf("\n"); + flint_printf("f = "), fmpz_print(f), flint_printf("\n"); + flint_printf("g = "), fmpz_print(g), flint_printf("\n"); + flint_printf("F = "), fmpz_print(F), flint_printf("\n"); + flint_printf("G = "), fmpz_print(G), flint_printf("\n"); + abort(); + } + + fmpz_clear(d); + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + fmpz_clear(f); + fmpz_clear(g); + fmpz_clear(F); + fmpz_clear(G); + } + + /* Test aliasing of b and f, d and g */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_t d, a, b, c, f, g, F, G; + + fmpz_init(d); + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + fmpz_init(f); + fmpz_init(g); + fmpz_init(F); + fmpz_init(G); + + fmpz_randtest_unsigned(G, state, 200); + fmpz_add_ui(G, G, 1); + fmpz_randm(F, state, G); + if (n_randint(state, 2)) fmpz_neg(G, G); + if (n_randint(state, 2)) fmpz_neg(F, F); + fmpz_set(f, F); + fmpz_set(g, G); + + fmpz_xgcd(d, a, b, f, g); + fmpz_xgcd(g, c, f, f, g); + + result = (fmpz_equal(d, g) + && fmpz_equal(a, c) + && fmpz_equal(b, f)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("d = "), fmpz_print(d), flint_printf("\n"); + flint_printf("a = "), fmpz_print(a), flint_printf("\n"); + flint_printf("b = "), fmpz_print(b), flint_printf("\n"); + flint_printf("c = "), fmpz_print(c), flint_printf("\n"); + flint_printf("f = "), fmpz_print(f), flint_printf("\n"); + flint_printf("g = "), fmpz_print(g), flint_printf("\n"); + flint_printf("F = "), fmpz_print(F), flint_printf("\n"); + flint_printf("G = "), fmpz_print(G), flint_printf("\n"); + abort(); + } + + fmpz_clear(d); + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + fmpz_clear(f); + fmpz_clear(g); + fmpz_clear(F); + fmpz_clear(G); + } + + /* Test a f + b g == d */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_t d, a, b, f, g, t1, t2; + + fmpz_init(d); + fmpz_init(a); + fmpz_init(b); + fmpz_init(f); + fmpz_init(g); + fmpz_init(t1); + fmpz_init(t2); + + fmpz_randtest_unsigned(g, state, 200); + fmpz_add_ui(g, g, 1); + fmpz_randm(f, state, g); + if (n_randint(state, 2)) fmpz_neg(g, g); + if (n_randint(state, 2)) fmpz_neg(f, f); + + fmpz_xgcd(d, a, b, f, g); + + fmpz_mul(t1, a, f); + fmpz_mul(t2, b, g); + fmpz_add(t1, t1, t2); + + result = fmpz_equal(t1, d); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("d = "), fmpz_print(d), flint_printf("\n"); + flint_printf("a = "), fmpz_print(a), flint_printf("\n"); + flint_printf("b = "), fmpz_print(b), flint_printf("\n"); + flint_printf("f = "), fmpz_print(f), flint_printf("\n"); + flint_printf("g = "), fmpz_print(g), flint_printf("\n"); + flint_printf("t1 = "), fmpz_print(t1), flint_printf("\n"); + flint_printf("t2 = "), fmpz_print(t2), flint_printf("\n"); + abort(); + } + + fmpz_clear(d); + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(f); + fmpz_clear(g); + fmpz_clear(t1); + fmpz_clear(t2); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} + diff --git a/external/flint-2.4.3/fmpz/test/t-xgcd_partial.c b/external/flint-2.4.3/fmpz/test/t-xgcd_partial.c new file mode 100644 index 0000000..43637ce --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-xgcd_partial.c @@ -0,0 +1,99 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("xgcd_partial...."); + fflush(stdout); + + + + /* Test co2*r1 - co1*r2 = r2_orig */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_t co1, co2, f, g, t1, t2, L; + + fmpz_init(co1); + fmpz_init(co2); + fmpz_init(f); + fmpz_init(g); + fmpz_init(L); + fmpz_init(t1); + fmpz_init(t2); + + fmpz_randtest_unsigned(g, state, 200); + fmpz_add_ui(g, g, 1); + fmpz_randm(f, state, g); + fmpz_randtest_unsigned(L, state, 200); + + fmpz_set(t2, g); + fmpz_abs(t2, t2); + + fmpz_xgcd_partial(co2, co1, g, f, L); + + fmpz_mul(t1, co2, f); + fmpz_submul(t1, co1, g); + fmpz_abs(t1, t1); + + result = fmpz_equal(t1, t2); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("co1 = "), fmpz_print(co1), flint_printf("\n"); + flint_printf("co2 = "), fmpz_print(co2), flint_printf("\n"); + flint_printf("f = "), fmpz_print(f), flint_printf("\n"); + flint_printf("g = "), fmpz_print(g), flint_printf("\n"); + flint_printf("L = "), fmpz_print(L), flint_printf("\n"); + flint_printf("t1 = "), fmpz_print(t1), flint_printf("\n"); + flint_printf("t2 = "), fmpz_print(t2), flint_printf("\n"); + abort(); + } + + fmpz_clear(co1); + fmpz_clear(co2); + fmpz_clear(f); + fmpz_clear(g); + fmpz_clear(L); + fmpz_clear(t1); + fmpz_clear(t2); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} + diff --git a/external/flint-2.4.3/fmpz/test/t-xor.c b/external/flint-2.4.3/fmpz/test/t-xor.c new file mode 100644 index 0000000..4c0cc1f --- /dev/null +++ b/external/flint-2.4.3/fmpz/test/t-xor.c @@ -0,0 +1,217 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("xor...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c; + mpz_t d, e, f, g; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + fmpz_randtest(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_xor(c, a, b); + mpz_xor(f, d, e); + + fmpz_get_mpz(g, c); + + result = (mpz_cmp(f, g) == 0); + + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + /* Check aliasing of a and b */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, c; + mpz_t d, f, g; + + fmpz_init(a); + fmpz_init(c); + + mpz_init(d); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + + fmpz_get_mpz(d, a); + + fmpz_xor(c, a, a); + mpz_xor(f, d, d); + + fmpz_get_mpz(g, c); + + result = (mpz_cmp(f, g) == 0); + + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, f = %Zd, g = %Zd\n", d, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(c); + + mpz_clear(d); + mpz_clear(f); + mpz_clear(g); + } + + /* Test aliasing of a and c */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t d, e, f, g; + + fmpz_init(a); + fmpz_init(b); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + fmpz_randtest(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_xor(a, a, b); + mpz_xor(f, d, e); + + fmpz_get_mpz(g, a); + + result = (mpz_cmp(f, g) == 0); + + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + /* Test aliasing of b and c */ + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpz_t d, e, f, g; + + fmpz_init(a); + fmpz_init(b); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(g); + + fmpz_randtest(a, state, 200); + fmpz_randtest(b, state, 200); + + fmpz_get_mpz(d, a); + fmpz_get_mpz(e, b); + + fmpz_xor(b, a, b); + mpz_xor(f, d, e); + + fmpz_get_mpz(g, b); + + result = (mpz_cmp(f, g) == 0); + + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(g); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz/tstbit.c b/external/flint-2.4.3/fmpz/tstbit.c new file mode 100644 index 0000000..b9c4cd0 --- /dev/null +++ b/external/flint-2.4.3/fmpz/tstbit.c @@ -0,0 +1,46 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz.h" + +int fmpz_tstbit(const fmpz_t f, ulong i) +{ + if (!COEFF_IS_MPZ(*f)) + { + if (i < FLINT_BITS) + { + return ((WORD(1) << i) & *f) != 0; + } + else /* i >= FLINT_BITS */ + { + return *f < 0; + } + } + else + { + return mpz_tstbit(COEFF_TO_PTR(*f), i); + } +} + diff --git a/external/flint-2.4.3/fmpz/val2.c b/external/flint-2.4.3/fmpz/val2.c new file mode 100644 index 0000000..91c84cb --- /dev/null +++ b/external/flint-2.4.3/fmpz/val2.c @@ -0,0 +1,60 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +mp_bitcnt_t fmpz_val2(const fmpz_t x) +{ + fmpz c = *x; + mp_bitcnt_t t; + + if (!COEFF_IS_MPZ(c)) + { + if (c == 0) + t = 0; + else + count_trailing_zeros(t, FLINT_ABS(c)); + } + else + { + mp_limb_t *d = (COEFF_TO_PTR(c))->_mp_d; + mp_bitcnt_t u; + + t = 0; + while (*d == 0) + { + d++; + t += FLINT_BITS; + } + + count_trailing_zeros(u, *d); + t += u; + } + + return t; +} diff --git a/external/flint-2.4.3/fmpz/xgcd.c b/external/flint-2.4.3/fmpz/xgcd.c new file mode 100644 index 0000000..c1df3c3 --- /dev/null +++ b/external/flint-2.4.3/fmpz/xgcd.c @@ -0,0 +1,91 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +void fmpz_xgcd(fmpz_t d, fmpz_t a, fmpz_t b, const fmpz_t f, const fmpz_t g) +{ + fmpz_t t1, t2; + fmpz * f1, * g1; + + if (fmpz_is_zero(f)) + { + fmpz_set(d, g); + fmpz_set_ui(a, 0); + fmpz_set_ui(b, 1); + } else if (fmpz_cmp(f, g) == 0) + { + fmpz_set(d, f); + fmpz_set_ui(a, 1); + fmpz_set_si(b, 0); + } else + { + int sign1 = fmpz_sgn(f); + int sign2 = fmpz_sgn(g); + + fmpz_init(t1); + fmpz_init(t2); + + /* support aliasing */ + if (d == f || a == f || sign1 < 0) + { + f1 = t1; + if (sign1 < 0) fmpz_neg(f1, f); + else fmpz_set(f1, f); + } else + f1 = (fmpz *) f; + + if (d == g || a == g || sign2 < 0) + { + g1 = t2; + if (sign2 < 0) fmpz_neg(g1, g); + else fmpz_set(g1, g); + } else + g1 = (fmpz *) g; + + if (fmpz_cmp(f1, g1) < 0) + { + fmpz_gcdinv(d, a, f1, g1); + fmpz_mul(t1, a, f1); + fmpz_sub(t1, d, t1); + fmpz_divexact(b, t1, g1); + } else /* g < f */ + { + fmpz_gcdinv(d, b, g1, f1); + fmpz_mul(t2, b, g1); + fmpz_sub(t2, d, t2); + fmpz_divexact(a, t2, f1); + } + + if (sign1 < 0) fmpz_neg(a, a); + if (sign2 < 0) fmpz_neg(b, b); + + fmpz_clear(t1); + fmpz_clear(t2); + } +} diff --git a/external/flint-2.4.3/fmpz/xgcd_partial.c b/external/flint-2.4.3/fmpz/xgcd_partial.c new file mode 100644 index 0000000..931aa3b --- /dev/null +++ b/external/flint-2.4.3/fmpz/xgcd_partial.c @@ -0,0 +1,126 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +void fmpz_xgcd_partial(fmpz_t co2, fmpz_t co1, + fmpz_t r2, fmpz_t r1, const fmpz_t L) +{ + fmpz_t q, r; + slong aa2, aa1, bb2, bb1, rr1, rr2, qq, bb, t1, t2, t3, i; + slong bits, bits1, bits2; + + fmpz_init(q); fmpz_init(r); + + fmpz_zero(co2); + fmpz_set_si(co1, -1); + + while (!fmpz_is_zero(r1) && fmpz_cmp(r1, L) > 0) + { + bits2 = fmpz_bits(r2); + bits1 = fmpz_bits(r1); + bits = FLINT_MAX(bits2, bits1) - FLINT_BITS + 1; + if (bits < 0) bits = 0; + + fmpz_tdiv_q_2exp(r, r2, bits); + rr2 = fmpz_get_ui(r); + fmpz_tdiv_q_2exp(r, r1, bits); + rr1 = fmpz_get_ui(r); + fmpz_tdiv_q_2exp(r, L, bits); + bb = fmpz_get_ui(r); + + aa2 = 0; aa1 = 1; + bb2 = 1; bb1 = 0; + + for (i = 0; rr1 != 0 && rr1 > bb; i++) + { + qq = rr2 / rr1; + + t1 = rr2 - qq*rr1; + t2 = aa2 - qq*aa1; + t3 = bb2 - qq*bb1; + + if (i & 1) + { + if (t1 < -t3 || rr1 - t1 < t2 - aa1) break; + } else + { + if (t1 < -t2 || rr1 - t1 < t3 - bb1) break; + } + + rr2 = rr1; rr1 = t1; + aa2 = aa1; aa1 = t2; + bb2 = bb1; bb1 = t3; + } + + if (i == 0) + { + fmpz_fdiv_qr(q, r2, r2, r1); + fmpz_swap(r2, r1); + + fmpz_submul(co2, co1, q); + fmpz_swap(co2, co1); + } else + { + fmpz_mul_si(r, r2, bb2); + if (aa2 >= 0) + fmpz_addmul_ui(r, r1, aa2); + else + fmpz_submul_ui(r, r1, -aa2); + fmpz_mul_si(r1, r1, aa1); + if (bb1 >= 0) + fmpz_addmul_ui(r1, r2, bb1); + else + fmpz_submul_ui(r1, r2, -bb1); + fmpz_set(r2, r); + + fmpz_mul_si(r, co2, bb2); + if (aa2 >= 0) + fmpz_addmul_ui(r, co1, aa2); + else + fmpz_submul_ui(r, co1, -aa2); + fmpz_mul_si(co1, co1, aa1); + if (bb1 >= 0) + fmpz_addmul_ui(co1, co2, bb1); + else + fmpz_submul_ui(co1, co2, -bb1); + fmpz_set(co2, r); + + if (fmpz_sgn(r1) < 0) { fmpz_neg(co1, co1); fmpz_neg(r1, r1); } + if (fmpz_sgn(r2) < 0) { fmpz_neg(co2, co2); fmpz_neg(r2, r2); } + } + } + + if (fmpz_sgn(r2) < 0) + { + fmpz_neg(co2, co2); fmpz_neg(co1, co1); + fmpz_neg(r2, r2); + } + + fmpz_clear(q); fmpz_clear(r); +} diff --git a/external/flint-2.4.3/fmpz/xor.c b/external/flint-2.4.3/fmpz/xor.c new file mode 100644 index 0000000..61b54d4 --- /dev/null +++ b/external/flint-2.4.3/fmpz/xor.c @@ -0,0 +1,70 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Thomas M. DuBuisson + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" + +void fmpz_xor(fmpz_t f, const fmpz_t g, const fmpz_t h) +{ + fmpz c1,c2; + c1 = *g; + c2 = *h; + if(!COEFF_IS_MPZ(c1)) + { + if(!COEFF_IS_MPZ(c2)) /* both inputs are small */ + { + fmpz_set_si(f, c1 ^ c2); + } else /* g is small, h is large */ + { + mpz_t tmp; + __mpz_struct * mpz3 = _fmpz_promote(f); + flint_mpz_init_set_si(tmp, c1); + mpz_xor(mpz3, COEFF_TO_PTR(c2), tmp); + _fmpz_demote_val(f); + mpz_clear(tmp); + } + } else + { + if(!COEFF_IS_MPZ(c2)) /* g is large, h is small */ + { + mpz_t tmp; + __mpz_struct *mpz3 = _fmpz_promote(f); + flint_mpz_init_set_si(tmp, c2); + mpz_xor(mpz3, COEFF_TO_PTR(c1), tmp); + _fmpz_demote_val(f); + mpz_clear(tmp); + } else /* g and h are large */ + { + __mpz_struct * mpz3 = _fmpz_promote(f); + __mpz_struct * mpz1 = COEFF_TO_PTR(c1); + __mpz_struct * mpz2 = COEFF_TO_PTR(c2); + mpz_xor(mpz3, mpz1, mpz2); + _fmpz_demote_val(f); + } + } +} + diff --git a/external/flint-2.4.3/fmpz_factor.h b/external/flint-2.4.3/fmpz_factor.h new file mode 100644 index 0000000..53043c6 --- /dev/null +++ b/external/flint-2.4.3/fmpz_factor.h @@ -0,0 +1,88 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#ifndef FMPZ_FACTOR_H +#define FMPZ_FACTOR_H + +#include +#include "flint.h" + +#ifdef __cplusplus + extern "C" { +#endif + +typedef struct +{ + int sign; + fmpz * p; + ulong * exp; + slong alloc; + slong num; +} fmpz_factor_struct; + +typedef fmpz_factor_struct fmpz_factor_t[1]; + + +/* Utility functions *********************************************************/ + +void fmpz_factor_init(fmpz_factor_t factor); + +void fmpz_factor_clear(fmpz_factor_t factor); + +void fmpz_factor_print(const fmpz_factor_t factor); + +void _fmpz_factor_fit_length(fmpz_factor_t factor, slong len); + +void _fmpz_factor_append_ui(fmpz_factor_t factor, mp_limb_t p, ulong exp); + +void _fmpz_factor_set_length(fmpz_factor_t factor, slong newlen); + +/* Factoring *****************************************************************/ + +void _fmpz_factor_extend_factor_ui(fmpz_factor_t factor, mp_limb_t n); + +int fmpz_factor_trial_range(fmpz_factor_t factor, const fmpz_t n, + ulong start, ulong num_primes); + +void fmpz_factor(fmpz_factor_t factor, const fmpz_t n); + +void fmpz_factor_si(fmpz_factor_t factor, slong n); + +int fmpz_factor_pp1(fmpz_t factor, const fmpz_t n, + ulong B1, ulong B2_sqrt, ulong c); + +/* Expansion *****************************************************************/ + +void fmpz_factor_expand_iterative(fmpz_t n, const fmpz_factor_t factor); + +void fmpz_factor_expand_multiexp(fmpz_t n, const fmpz_factor_t factor); + +void fmpz_factor_expand(fmpz_t n, const fmpz_factor_t factor); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/flint-2.4.3/fmpz_factor/append_ui.c b/external/flint-2.4.3/fmpz_factor/append_ui.c new file mode 100644 index 0000000..d7567e3 --- /dev/null +++ b/external/flint-2.4.3/fmpz_factor/append_ui.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +void +_fmpz_factor_append_ui(fmpz_factor_t factor, mp_limb_t p, ulong exp) +{ + _fmpz_factor_fit_length(factor, factor->num + 1); + fmpz_set_ui(factor->p + factor->num, p); + factor->exp[factor->num] = exp; + factor->num++; +} diff --git a/external/flint-2.4.3/fmpz_factor/clear.c b/external/flint-2.4.3/fmpz_factor/clear.c new file mode 100644 index 0000000..c88d778 --- /dev/null +++ b/external/flint-2.4.3/fmpz_factor/clear.c @@ -0,0 +1,37 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +void +fmpz_factor_clear(fmpz_factor_t factor) +{ + _fmpz_vec_clear(factor->p, factor->alloc); + flint_free(factor->exp); +} diff --git a/external/flint-2.4.3/fmpz_factor/doc/fmpz_factor.txt b/external/flint-2.4.3/fmpz_factor/doc/fmpz_factor.txt new file mode 100644 index 0000000..6233996 --- /dev/null +++ b/external/flint-2.4.3/fmpz_factor/doc/fmpz_factor.txt @@ -0,0 +1,96 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +******************************************************************************* + + Factoring integers + + An integer may be represented in factored form using the + \code{fmpz_factor_t} data structure. This consists of two \code{fmpz} + vectors representing bases and exponents, respectively. Canonically, + the bases will be prime numbers sorted in ascending order and the + exponents will be positive. + + A separate \code{int} field holds the sign, which may be $-1$, $0$ or $1$. + +******************************************************************************* + +void fmpz_factor_init(fmpz_factor_t factor) + + Initialises an \code{fmpz_factor_t} structure. + +void fmpz_factor_clear(fmpz_factor_t factor) + + Clears an \code{fmpz_factor_t} structure. + +void fmpz_factor(fmpz_factor_t factor, const fmpz_t n) + + Factors $n$ into prime numbers. If $n$ is zero or negative, the + sign field of the \code{factor} object will be set accordingly. + + This currently only uses trial division, falling back to \code{n_factor()} + as soon as the number shrinks to a single limb. + +void fmpz_factor_si(fmpz_factor_t factor, slong n) + + Like \code{fmpz_factor}, but takes a machine integer $n$ as input. + +int fmpz_factor_trial_range(fmpz_factor_t factor, const fmpz_t n, + ulong start, ulong num_primes) + + Factors $n$ into prime factors using trial division. If $n$ is + zero or negative, the sign field of the \code{factor} object will be + set accordingly. + + The algorithm starts with the given start index in the \code{flint_primes} + table and uses at most \code{num_primes} primes from that point. + + The function returns 1 if $n$ is completely factored, otherwise it returns + $0$. + +void fmpz_factor_expand_iterative(fmpz_t n, const fmpz_factor_t factor) + + Evaluates an integer in factored form back to an \code{fmpz_t}. + + This currently exponentiates the bases separately and multiplies + them together one by one, although much more efficient algorithms + exist. + +int fmpz_factor_pp1(fmpz_t factor, const fmpz_t n, + ulong B1, ulong B2_sqrt, ulong c) + + Use Williams' $p + 1$ method to factor $n$, using a prime bound in + stage 1 of \code{B1} and a prime limit in stage 2 of at least the square + of \code{B2_sqrt}. If a factor is found, the function returns $1$ and + \code{factor} is set to the factor that is found. Otherwise, the function + returns $0$. + + The value $c$ should be a random value greater than $2$. Successive + calls to the function with different values of $c$ give additional + chances to factor $n$ with roughly exponentially decaying probability + of finding a factor which has been missed (if $p+1$ or $p-1$ is not + smooth for any prime factors $p$ of $n$ then the function will + not ever succeed). + diff --git a/external/flint-2.4.3/fmpz_factor/expand.c b/external/flint-2.4.3/fmpz_factor/expand.c new file mode 100644 index 0000000..8f84d4e --- /dev/null +++ b/external/flint-2.4.3/fmpz_factor/expand.c @@ -0,0 +1,34 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" + +void +fmpz_factor_expand(fmpz_t n, const fmpz_factor_t factor) +{ + fmpz_factor_expand_multiexp(n, factor); +} diff --git a/external/flint-2.4.3/fmpz_factor/expand_iterative.c b/external/flint-2.4.3/fmpz_factor/expand_iterative.c new file mode 100644 index 0000000..cd70995 --- /dev/null +++ b/external/flint-2.4.3/fmpz_factor/expand_iterative.c @@ -0,0 +1,45 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" + +void +fmpz_factor_expand_iterative(fmpz_t n, const fmpz_factor_t factor) +{ + slong i; + fmpz_t tmp; + + fmpz_set_si(n, factor->sign); + + fmpz_init(tmp); + for (i = 0; i < factor->num; i++) + { + fmpz_pow_ui(tmp, factor->p + i, factor->exp[i]); + fmpz_mul(n, n, tmp); + } + fmpz_clear(tmp); +} diff --git a/external/flint-2.4.3/fmpz_factor/expand_multiexp.c b/external/flint-2.4.3/fmpz_factor/expand_multiexp.c new file mode 100644 index 0000000..12881a8 --- /dev/null +++ b/external/flint-2.4.3/fmpz_factor/expand_multiexp.c @@ -0,0 +1,91 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Multi-exponentiation code based on Paul Zimmermann's implementation + of the double factorial + + Copyright (C) 2009, 2010 Paul Zimmermann + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +void +_fmpz_factor_eval_multiexp(fmpz_t res, const fmpz * p, const ulong * e, slong len) +{ + slong i, j; + ulong mask, emax; + fmpz * q; + fmpz_t tmp; + + if (len <= 1) + { + if (len < 1) + fmpz_one(res); + else + fmpz_pow_ui(res, p, e[0]); + return; + } + + q = flint_malloc(sizeof(fmpz) * len); + + emax = e[0]; + for (i = 1; i < len; i++) + emax = FLINT_MAX(emax, e[i]); + + for (mask = 1; emax >= (mask << 1); mask <<= 1); + + fmpz_init(tmp); + fmpz_one(res); + + while (mask) + { + for (i = 0, j = 0; i < len; i++) + if (e[i] & mask) + q[j++] = p[i]; + + _fmpz_vec_prod(tmp, q, j); + fmpz_mul(res, res, res); + fmpz_mul(res, res, tmp); + mask >>= 1; + } + + fmpz_clear(tmp); + flint_free(q); +} + +void +fmpz_factor_expand_multiexp(fmpz_t n, const fmpz_factor_t factor) +{ + if (factor->num != 0 && factor->p[0] == 2) + { + _fmpz_factor_eval_multiexp(n, factor->p + 1, factor->exp + 1, factor->num - 1); + fmpz_mul_2exp(n, n, factor->exp[0]); + } + else + _fmpz_factor_eval_multiexp(n, factor->p, factor->exp, factor->num); + + fmpz_mul_si(n, n, factor->sign); +} diff --git a/external/flint-2.4.3/fmpz_factor/extend_factor_ui.c b/external/flint-2.4.3/fmpz_factor/extend_factor_ui.c new file mode 100644 index 0000000..1fb4b5b --- /dev/null +++ b/external/flint-2.4.3/fmpz_factor/extend_factor_ui.c @@ -0,0 +1,59 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" + +void +_fmpz_factor_extend_factor_ui(fmpz_factor_t factor, mp_limb_t n) +{ + slong i, len; + n_factor_t nfac; + + if (n == 0) + { + _fmpz_factor_set_length(factor, 0); + factor->sign = 0; + return; + } + + n_factor_init(&nfac); + n_factor(&nfac, n, 0); + + len = factor->num; + + _fmpz_factor_fit_length(factor, len + nfac.num); + _fmpz_factor_set_length(factor, len + nfac.num); + + for (i = 0; i < nfac.num; i++) + { + fmpz_set_ui(factor->p + len + i, nfac.p[i]); + factor->exp[len + i] = nfac.exp[i]; + } +} diff --git a/external/flint-2.4.3/fmpz_factor/factor.c b/external/flint-2.4.3/fmpz_factor/factor.c new file mode 100644 index 0000000..7ba3fbf --- /dev/null +++ b/external/flint-2.4.3/fmpz_factor/factor.c @@ -0,0 +1,139 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "mpn_extras.h" +#include "ulong_extras.h" + +void +fmpz_factor(fmpz_factor_t factor, const fmpz_t n) +{ + ulong exp; + mp_limb_t p; + __mpz_struct * xsrc; + mp_ptr xd; + mp_size_t xsize; + slong found; + slong trial_start, trial_stop; + TMP_INIT; + + if (!COEFF_IS_MPZ(*n)) + { + fmpz_factor_si(factor, *n); + return; + } + + _fmpz_factor_set_length(factor, 0); + + /* Get sign and size */ + xsrc = COEFF_TO_PTR(*n); + if (xsrc->_mp_size < 0) + { + xsize = -(xsrc->_mp_size); + factor->sign = -1; + } + else + { + xsize = xsrc->_mp_size; + factor->sign = 1; + } + + /* Just a single limb */ + if (xsize == 1) + { + _fmpz_factor_extend_factor_ui(factor, xsrc->_mp_d[0]); + return; + } + + /* Create a temporary copy to be mutated */ + TMP_START; + xd = TMP_ALLOC(xsize * sizeof(mp_limb_t)); + flint_mpn_copyi(xd, xsrc->_mp_d, xsize); + + /* Factor out powers of two */ + xsize = flint_mpn_remove_2exp(xd, xsize, &exp); + if (exp != 0) + _fmpz_factor_append_ui(factor, UWORD(2), exp); + + trial_start = 1; + trial_stop = 1000; + + while (xsize > 1) + { + found = flint_mpn_factor_trial(xd, xsize, trial_start, trial_stop); + + if (found) + { + p = n_primes_arr_readonly(found+1)[found]; + exp = 1; + xsize = flint_mpn_divexact_1(xd, xsize, p); + + /* Check if p^2 divides n */ + if (flint_mpn_divisible_1_p(xd, xsize, p)) + { + /* TODO: when searching for squarefree numbers + (Moebius function, etc), we can abort here. */ + xsize = flint_mpn_divexact_1(xd, xsize, p); + exp = 2; + } + + /* If we're up to cubes, then maybe there are higher powers */ + if (exp == 2 && flint_mpn_divisible_1_p(xd, xsize, p)) + { + xsize = flint_mpn_divexact_1(xd, xsize, p); + xsize = flint_mpn_remove_power_ascending(xd, xsize, &p, 1, &exp); + exp += 3; + } + + _fmpz_factor_append_ui(factor, p, exp); + /* flint_printf("added %wu %wu\n", p, exp); */ + + /* Continue using only trial division whilst it is successful. + This allows quickly factoring huge highly composite numbers + such as factorials, which can arise in some applications. */ + trial_start = found + 1; + trial_stop = trial_start + 1000; + continue; + } + else + { + /* Insert primality test, perfect power test, other factoring + algorithms here... */ + trial_start = trial_stop; + trial_stop = trial_start + 1000; + } + } + + /* Any single-limb factor left? */ + if (xd[0] != 1) + _fmpz_factor_extend_factor_ui(factor, xd[0]); + + TMP_END; + return; +} + diff --git a/external/flint-2.4.3/fmpz_factor/factor_pp1.c b/external/flint-2.4.3/fmpz_factor/factor_pp1.c new file mode 100644 index 0000000..50998ce --- /dev/null +++ b/external/flint-2.4.3/fmpz_factor/factor_pp1.c @@ -0,0 +1,602 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 William Hart + +******************************************************************************/ + +#define ulong ulongxx /* interferes with system includes */ +#include +#undef ulong +#define ulong mp_limb_t +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_mod_poly.h" +#include "mpn_extras.h" +#include "ulong_extras.h" + +#define DEBUG 0 /* turn on some trace information */ + +#define pp1_mulmod(rxx, axx, bxx, nnn, nxx, ninv, norm) \ + flint_mpn_mulmod_preinvn(rxx, axx, bxx, nnn, nxx, ninv, norm) + +#ifdef FLINT64 +static +ulong pp1_primorial[15] = +{ + UWORD(2), UWORD(6), UWORD(30), UWORD(210), UWORD(2310), UWORD(30030), UWORD(510510), UWORD(9699690), + UWORD(223092870), UWORD(6469693230), UWORD(200560490130), UWORD(7420738134810), + UWORD(304250263527210), UWORD(13082761331670030), UWORD(614889782588491410) +}; +#define num_primorials 15 +#else +static +ulong pp1_primorial[9] = +{ + UWORD(2), UWORD(6), UWORD(30), UWORD(210), UWORD(2310), UWORD(30030), UWORD(510510), UWORD(9699690), + UWORD(223092870) +}; +#define num_primorials 9 +#endif + +void pp1_set(mp_ptr x1, mp_ptr y1, + mp_srcptr x2, mp_srcptr y2, mp_size_t nn) +{ + mpn_copyi(x1, x2, nn); + mpn_copyi(y1, y2, nn); +} + +void pp1_set_ui(mp_ptr x, mp_size_t nn, ulong norm, ulong c) +{ + mpn_zero(x, nn); + x[0] = (c << norm); + if (nn > 1 && norm) + x[1] = (c >> (FLINT_BITS - norm)); +} + +void pp1_print(mp_srcptr x, mp_srcptr y, mp_size_t nn, ulong norm) +{ + mp_ptr tx = flint_malloc(nn*sizeof(mp_limb_t)); + mp_ptr ty = flint_malloc(nn*sizeof(mp_limb_t)); + + if (norm) + { + mpn_rshift(tx, x, nn, norm); + mpn_rshift(ty, y, nn, norm); + } else + { + mpn_copyi(tx, x, nn); + mpn_copyi(ty, y, nn); + } + + flint_printf("["), gmp_printf("%Nd", tx, nn), flint_printf(", "), gmp_printf("%Nd", ty, nn), flint_printf("]"); + + flint_free(tx); + flint_free(ty); +} + +void pp1_2k(mp_ptr x, mp_ptr y, mp_size_t nn, mp_srcptr n, + mp_srcptr ninv, mp_srcptr x0, ulong norm) +{ + pp1_mulmod(y, y, x, nn, n, ninv, norm); + if (mpn_sub_n(y, y, x0, nn)) + mpn_add_n(y, y, n, nn); + + pp1_mulmod(x, x, x, nn, n, ninv, norm); + if (mpn_sub_1(x, x, nn, UWORD(2) << norm)) + mpn_add_n(x, x, n, nn); +} + +void pp1_2kp1(mp_ptr x, mp_ptr y, mp_size_t nn, mp_srcptr n, + mp_srcptr ninv, mp_srcptr x0, ulong norm) +{ + pp1_mulmod(x, x, y, nn, n, ninv, norm); + if (mpn_sub_n(x, x, x0, nn)) + mpn_add_n(x, x, n, nn); + + pp1_mulmod(y, y, y, nn, n, ninv, norm); + if (mpn_sub_1(y, y, nn, UWORD(2) << norm)) + mpn_add_n(y, y, n, nn); +} + +void pp1_pow_ui(mp_ptr x, mp_ptr y, mp_size_t nn, + ulong exp, mp_srcptr n, mp_srcptr ninv, ulong norm) +{ + mp_limb_t t[30]; + mp_ptr x0 = t; + ulong bit = ((UWORD(1) << FLINT_BIT_COUNT(exp)) >> 2); + + if (nn > 30) + x0 = flint_malloc(nn*sizeof(mp_limb_t)); + mpn_copyi(x0, x, nn); + + pp1_mulmod(y, x, x, nn, n, ninv, norm); + if (mpn_sub_1(y, y, nn, UWORD(2) << norm)) + mpn_add_n(y, y, n, nn); + + while (bit) + { + if (exp & bit) + pp1_2kp1(x, y, nn, n, ninv, x0, norm); + else + pp1_2k(x, y, nn, n, ninv, x0, norm); + + bit >>= 1; + } + + if (nn > 30) + flint_free(x0); +} + +mp_size_t pp1_factor(mp_ptr factor, mp_srcptr n, + mp_srcptr x, mp_size_t nn, ulong norm) +{ + mp_size_t ret = 0, xn = nn; + + mp_ptr n2 = flint_malloc(nn*sizeof(mp_limb_t)); + mp_ptr x2 = flint_malloc(nn*sizeof(mp_limb_t)); + + if (norm) + mpn_rshift(n2, n, nn, norm); + else + mpn_copyi(n2, n, nn); + + if (norm) + mpn_rshift(x2, x, nn, norm); + else + mpn_copyi(x2, x, nn); + + if (mpn_sub_1(x2, x2, nn, 2)) + mpn_add_n(x2, x2, n2, nn); + + MPN_NORM(x2, xn); + + if (xn == 0) + goto cleanup; + + ret = flint_mpn_gcd_full(factor, n2, nn, x2, xn); + +cleanup: + + flint_free(n2); + flint_free(x2); + + return ret; +} + +mp_size_t pp1_find_power(mp_ptr factor, mp_ptr x, mp_ptr y, mp_size_t nn, + ulong p, mp_srcptr n, mp_srcptr ninv, ulong norm) +{ + mp_size_t ret; + + do + { + pp1_pow_ui(x, y, nn, p, n, ninv, norm); + ret = pp1_factor(factor, n, x, nn, norm); + } while (ret == 1 && factor[0] == 1); + + return ret; +} + +int fmpz_factor_pp1(fmpz_t fac, const fmpz_t n_in, ulong B1, ulong B2sqrt, ulong c) +{ + slong i, j; + int ret = 0; + mp_size_t nn = fmpz_size(n_in), r; + mp_ptr x, y, oldx, oldy, n, ninv, factor, ptr_0, ptr_1, ptr_2, ptr_k; + ulong pr, oldpr, sqrt, bits0, norm; + n_primes_t iter; + + if (fmpz_is_even(n_in)) + { + fmpz_set_ui(fac, 2); + return 1; + } + +#if DEBUG + flint_printf("starting stage 1\n"); +#endif + + n_primes_init(iter); + + sqrt = n_sqrt(B1); + bits0 = FLINT_BIT_COUNT(B1); + + x = flint_malloc(nn*sizeof(mp_limb_t)); + y = flint_malloc(nn*sizeof(mp_limb_t)); + oldx = flint_malloc(nn*sizeof(mp_limb_t)); + oldy = flint_malloc(nn*sizeof(mp_limb_t)); + n = flint_malloc(nn*sizeof(mp_limb_t)); + ninv = flint_malloc(nn*sizeof(mp_limb_t)); + factor = flint_malloc(nn*sizeof(mp_limb_t)); + + if (nn == 1) + { + n[0] = fmpz_get_ui(n_in); + count_leading_zeros(norm, n[0]); + n[0] <<= norm; + } else + { + mp_ptr np = COEFF_TO_PTR(*n_in)->_mp_d; + count_leading_zeros(norm, np[nn - 1]); + if (norm) + mpn_lshift(n, np, nn, norm); + else + mpn_copyi(n, np, nn); + } + + flint_mpn_preinvn(ninv, n, nn); + + pp1_set_ui(x, nn, norm, c); + + /* mul by various prime powers */ + pr = 0; + oldpr = 0; + + for (i = 0; pr < B1; ) + { + j = i + 1024; + oldpr = pr; + pp1_set(oldx, oldy, x, y, nn); + for ( ; i < j; i++) + { + pr = n_primes_next(iter); + if (pr < sqrt) + { + ulong bits = FLINT_BIT_COUNT(pr); + ulong exp = bits0 / bits; + pp1_pow_ui(x, y, nn, n_pow(pr, exp), n, ninv, norm); + } else + pp1_pow_ui(x, y, nn, pr, n, ninv, norm); + } + + r = pp1_factor(factor, n, x, nn, norm); + if (r == 0) + break; + if (r != 1 || factor[0] != 1) + { + ret = 1; + goto cleanup; + } + } + + if (pr < B1) /* factor = 0 */ + { + n_primes_jump_after(iter, oldpr); + pp1_set(x, y, oldx, oldy, nn); + + do + { + pr = n_primes_next(iter); + pp1_set(oldx, oldy, x, y, nn); + if (pr < sqrt) + { + ulong bits = FLINT_BIT_COUNT(pr); + ulong exp = bits0 / bits; + pp1_pow_ui(x, y, nn, n_pow(pr, exp), n, ninv, norm); + } else + pp1_pow_ui(x, y, nn, pr, n, ninv, norm); + + r = pp1_factor(factor, n, x, nn, norm); + if (r == 0) + break; + if (r != 1 || factor[0] != 1) + { + ret = 1; + goto cleanup; + } + } while (1); + + /* factor is still 0 */ + ret = pp1_find_power(factor, oldx, oldy, nn, pr, n, ninv, norm); + } else /* stage 2 */ + { + double quot; + int num; + char * sieve = flint_malloc(32768); + slong * sieve_index = flint_malloc(32768*sizeof(slong)); + mp_ptr diff = flint_malloc(16384*nn*sizeof(mp_limb_t)); + ulong offset[15], num_roots; + slong k, index = 0, s; + fmpz * roots, * roots2, * evals; + fmpz_poly_struct ** tree, ** tree2; + +#if DEBUG + ulong primorial; + flint_printf("starting stage 2\n"); +#endif + + /* find primorial <= B2sqrt ... */ + for (num = 1; num < num_primorials; num++) + { + if (pp1_primorial[num] > B2sqrt) + break; + } + num--; + + /* ... but not too big */ + quot = (double) B2sqrt / (double) pp1_primorial[num]; + if (quot < 1.1 && num > 0) + num--; + +#if DEBUG + primorial = pp1_primorial[num]; + flint_printf("found primorial %wu\n", primorial); +#endif + + /* adjust B2sqrt to multiple of primorial */ + B2sqrt = (((B2sqrt - 1)/ pp1_primorial[num]) + 1) * pp1_primorial[num]; + +#if DEBUG + flint_printf("adjusted B2sqrt %wu\n", B2sqrt); +#endif + + /* compute num roots */ + num++; /* number of primes is 1 more than primorial index */ + pr = 2; + num_roots = B2sqrt; + for (i = 0; i < num; i++) + { + num_roots = (num_roots*(pr - 1))/pr; + pr = n_nextprime(pr, 0); + } + +#if DEBUG + flint_printf("computed num_roots %wu\n", num_roots); + flint_printf("B2 = %wu\n", num_roots * B2sqrt); +#endif + + /* construct roots */ + roots = _fmpz_vec_init(num_roots); + for (i = 0; i < num_roots; i++) + { + __mpz_struct * m = _fmpz_promote(roots + i); + mpz_realloc(m, nn); + } + + roots2 = _fmpz_vec_init(num_roots); + for (i = 0; i < num_roots; i++) + { + __mpz_struct * m = _fmpz_promote(roots2 + i); + mpz_realloc(m, nn); + } + + evals = _fmpz_vec_init(num_roots); + +#if DEBUG + flint_printf("constructed roots\n"); +#endif + + /* compute differences table v0, ... */ + mpn_zero(diff, nn); + diff[0] = (UWORD(2) << norm); + + /* ... v2, ... */ + pp1_mulmod(diff + nn, x, x, nn, n, ninv, norm); + if (mpn_sub_1(diff + nn, diff + nn, nn, UWORD(2) << norm)) + mpn_add_n(diff + nn, diff + nn, n, nn); + + /* ... the rest ... v_{k+2} = v_k v_2 - v_{k-2} */ + k = 2*nn; + for (i = 2; i < 16384; i++, k += nn) + { + pp1_mulmod(diff + k, diff + k - nn, diff + nn, nn, n, ninv, norm); + if (mpn_sub_n(diff + k, diff + k, diff + k - 2*nn, nn)) + mpn_add_n(diff + k, diff + k, n, nn); + } + +#if DEBUG + flint_printf("conputed differences table\n"); +#endif + + /* initial positions */ + pr = 2; + for (i = 0; i < num; i++) + { + offset[i] = pr/2; + pr = n_nextprime(pr, 0); + } + + s = 0; + while (2*s + 1 < B2sqrt) + { + /* sieve */ + memset(sieve, 1, 32768); + pr = 3; + for (i = 1; i < num; i++) + { + j = offset[i]; + while (j < 32768) + sieve[j] = 0, j += pr; + + /* store offset for start of next sieve run */ + offset[i] = j - 32768; + pr = n_nextprime(pr, 0); + } + + /* compute roots */ + for (i = 0; i < 32768 && 2*(s + i) + 1 < B2sqrt; i++) + { + if (sieve[i]) + { + ptr_2 = COEFF_TO_PTR(roots[index])->_mp_d; + k = (i + 1)/2; + for (j = i - 1; j >= k; j--) + { + if (sieve[j] && sieve[2*j - i]) + { + /* V_{n+k} = V_n V_k - V_{n-k} */ + ptr_0 = COEFF_TO_PTR(roots[sieve_index[2*j - i]])->_mp_d; + ptr_1 = COEFF_TO_PTR(roots[sieve_index[j]])->_mp_d; + ptr_k = diff + (i - j)*nn; + pp1_mulmod(ptr_2, ptr_1, ptr_k, nn, n, ninv, norm); + if (mpn_sub_n(ptr_2, ptr_2, ptr_0, nn)) + mpn_add_n(ptr_2, ptr_2, n, nn); + break; + } + } + + if (j < k) /* pair not found, compute using pow_ui */ + { + mpn_copyi(ptr_2, x, nn); + pp1_pow_ui(ptr_2, y, nn, 2*(s + i) + 1, n, ninv, norm); + } + + sieve_index[i] = index; + index++; + } + } + + s += 32768; + } + +#if DEBUG + flint_printf("roots computed %wd\n", index); +#endif + + /* v_1 */ + mpn_copyi(oldx, x, nn); + pp1_pow_ui(oldx, y, nn, B2sqrt, n, ninv, norm); + ptr_0 = COEFF_TO_PTR(roots2[0])->_mp_d; + mpn_copyi(ptr_0, oldx, nn); + + /* v_2 */ + ptr_1 = COEFF_TO_PTR(roots2[1])->_mp_d; + pp1_mulmod(ptr_1, ptr_0, ptr_0, nn, n, ninv, norm); + if (mpn_sub_1(ptr_1, ptr_1, nn, UWORD(2) << norm)) + mpn_add_n(ptr_1, ptr_1, n, nn); + + for (i = 2; i < num_roots; i++) + { + /* V_{k+n} = V_k V_n - V_{k-n} */ + ptr_2 = COEFF_TO_PTR(roots2[i])->_mp_d; + + pp1_mulmod(ptr_2, ptr_1, oldx, nn, n, ninv, norm); + if (mpn_sub_n(ptr_2, ptr_2, ptr_0, nn)) + mpn_add_n(ptr_2, ptr_2, n, nn); + + ptr_0 = ptr_1; + ptr_1 = ptr_2; + } + +#if DEBUG + flint_printf("roots2 computed %wu\n", num_roots); +#endif + + for (i = 0; i < num_roots; i++) + { + mp_size_t sn; + __mpz_struct * m1 = COEFF_TO_PTR(roots[i]); + __mpz_struct * m2 = COEFF_TO_PTR(roots2[i]); + + ptr_1 = m1->_mp_d; + ptr_2 = m2->_mp_d; + + mpn_rshift(ptr_1, ptr_1, nn, norm); + mpn_rshift(ptr_2, ptr_2, nn, norm); + + sn = nn; + MPN_NORM(ptr_1, sn); + m1->_mp_size = sn; + + sn = nn; + MPN_NORM(ptr_2, sn); + m2->_mp_size = sn; + + _fmpz_demote_val(roots + i); + _fmpz_demote_val(roots2 + i); + } + +#if DEBUG + flint_printf("normalised roots\n"); +#endif + + tree = _fmpz_mod_poly_tree_alloc(num_roots); + _fmpz_mod_poly_tree_build(tree, roots, num_roots, n_in); + + tree2 = _fmpz_mod_poly_tree_alloc(num_roots); + _fmpz_mod_poly_tree_build(tree2, roots2, num_roots, n_in); + + fmpz_poly_mul(tree2[FLINT_CLOG2(num_roots)], tree2[FLINT_CLOG2(num_roots)-1], tree2[FLINT_CLOG2(num_roots)-1]+1); + +#if DEBUG + flint_printf("built trees\n"); +#endif + + _fmpz_mod_poly_evaluate_fmpz_vec_fast_precomp(evals, tree2[FLINT_CLOG2(num_roots)]->coeffs, tree2[FLINT_CLOG2(num_roots)]->length, tree, num_roots, n_in); + _fmpz_mod_poly_tree_free(tree, num_roots); + _fmpz_mod_poly_tree_free(tree2, num_roots); + +#if DEBUG + flint_printf("evaluated at roots\n"); +#endif + + for (i = 0; i < num_roots; i++) + { + fmpz_gcd(fac, n_in, evals + i); + if (!fmpz_is_zero(fac) && !fmpz_is_one(fac)) + { + ret = 1; + break; + } + } + + _fmpz_vec_clear(evals, num_roots); + _fmpz_vec_clear(roots, num_roots); + _fmpz_vec_clear(roots2, num_roots); + flint_free(sieve); + flint_free(diff); + + + if (i < num_roots) + goto cleanup2; + } + +#if DEBUG + flint_printf("done stage2\n"); +#endif + +cleanup: + + if (ret) + { + __mpz_struct * fm = _fmpz_promote(fac); + mpz_realloc(fm, r); + mpn_copyi(fm->_mp_d, factor, r); + fm->_mp_size = r; + _fmpz_demote_val(fac); + } + +cleanup2: + + flint_free(x); + flint_free(y); + flint_free(oldx); + flint_free(oldy); + flint_free(n); + flint_free(ninv); + + n_primes_clear(iter); + + return ret; +} diff --git a/external/flint-2.4.3/fmpz_factor/factor_si.c b/external/flint-2.4.3/fmpz_factor/factor_si.c new file mode 100644 index 0000000..ee91b7c --- /dev/null +++ b/external/flint-2.4.3/fmpz_factor/factor_si.c @@ -0,0 +1,48 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +void +fmpz_factor_si(fmpz_factor_t factor, slong n) +{ + _fmpz_factor_set_length(factor, 0); + + if (n < 0) + { + _fmpz_factor_extend_factor_ui(factor, -n); + factor->sign = -1; + return; + } + else + { + factor->sign = 1; + _fmpz_factor_extend_factor_ui(factor, n); + } +} diff --git a/external/flint-2.4.3/fmpz_factor/factor_trial_range.c b/external/flint-2.4.3/fmpz_factor/factor_trial_range.c new file mode 100644 index 0000000..50eddf2 --- /dev/null +++ b/external/flint-2.4.3/fmpz_factor/factor_trial_range.c @@ -0,0 +1,133 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "mpn_extras.h" +#include "ulong_extras.h" + +int +fmpz_factor_trial_range(fmpz_factor_t factor, const fmpz_t n, ulong start, ulong num_primes) +{ + ulong exp; + mp_limb_t p; + mpz_t x; + mp_ptr xd; + mp_size_t xsize; + slong found; + slong trial_start, trial_stop; + int ret = 1; + + if (!COEFF_IS_MPZ(*n)) + { + fmpz_factor_si(factor, *n); + + return ret; + } + + _fmpz_factor_set_length(factor, 0); + + /* Make an mpz_t copy whose limbs will be mutated */ + mpz_init(x); + fmpz_get_mpz(x, n); + if (x->_mp_size < 0) + { + x->_mp_size = -(x->_mp_size); + factor->sign = -1; + } + else + { + factor->sign = 1; + } + + xd = x->_mp_d; + xsize = x->_mp_size; + + /* Factor out powers of two */ + if (start == 0) + { + xsize = flint_mpn_remove_2exp(xd, xsize, &exp); + if (exp != 0) + _fmpz_factor_append_ui(factor, UWORD(2), exp); + } + + trial_start = FLINT_MAX(1, start); + trial_stop = FLINT_MIN(start + 1000, start + num_primes); + + do + { + found = flint_mpn_factor_trial(xd, xsize, trial_start, trial_stop); + + if (found) + { + p = n_primes_arr_readonly(found+1)[found]; + exp = 1; + xsize = flint_mpn_divexact_1(xd, xsize, p); + + /* Check if p^2 divides n */ + if (flint_mpn_divisible_1_p(xd, xsize, p)) + { + /* TODO: when searching for squarefree numbers + (Moebius function, etc), we can abort here. */ + xsize = flint_mpn_divexact_1(xd, xsize, p); + exp = 2; + } + + /* If we're up to cubes, then maybe there are higher powers */ + if (exp == 2 && flint_mpn_divisible_1_p(xd, xsize, p)) + { + xsize = flint_mpn_divexact_1(xd, xsize, p); + xsize = flint_mpn_remove_power_ascending(xd, xsize, &p, 1, &exp); + exp += 3; + } + + _fmpz_factor_append_ui(factor, p, exp); + /* flint_printf("added %wu %wu\n", p, exp); */ + + /* Continue using only trial division whilst it is successful. + This allows quickly factoring huge highly composite numbers + such as factorials, which can arise in some applications. */ + trial_start = found + 1; + trial_stop = FLINT_MIN(trial_start + 1000, start + num_primes); + continue; + } + else + { + /* Insert primality test, perfect power test, other factoring + algorithms here... */ + trial_start = trial_stop; + trial_stop = FLINT_MIN(trial_start + 1000, start + num_primes); + } + } while ((xsize > 1 || xd[0] != 1) && trial_start != trial_stop); + + /* Any factor left? */ + if (xsize > 1 || xd[0] != 1) + ret = 0; + + mpz_clear(x); + return ret; +} diff --git a/external/flint-2.4.3/fmpz_factor/fit_length.c b/external/flint-2.4.3/fmpz_factor/fit_length.c new file mode 100644 index 0000000..3c39969 --- /dev/null +++ b/external/flint-2.4.3/fmpz_factor/fit_length.c @@ -0,0 +1,51 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +void +_fmpz_factor_fit_length(fmpz_factor_t factor, slong len) +{ + if (len > factor->alloc) + { + if (len < 2 * factor->alloc) + len = 2 * factor->alloc; + + factor->p = (fmpz *) flint_realloc(factor->p, len * sizeof(fmpz)); + factor->exp = flint_realloc(factor->exp, len * sizeof(slong)); + + if (len > factor->alloc) + { + flint_mpn_zero((mp_ptr)(factor->p + factor->alloc), len-factor->alloc); + flint_mpn_zero((mp_ptr)(factor->exp + factor->alloc), len-factor->alloc); + } + + factor->alloc = len; + } +} diff --git a/external/flint-2.4.3/fmpz_factor/init.c b/external/flint-2.4.3/fmpz_factor/init.c new file mode 100644 index 0000000..cbf764a --- /dev/null +++ b/external/flint-2.4.3/fmpz_factor/init.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +void +fmpz_factor_init(fmpz_factor_t factor) +{ + factor->sign = 0; + factor->p = NULL; + factor->exp = NULL; + factor->num = 0; + factor->alloc = 0; +} diff --git a/external/flint-2.4.3/fmpz_factor/print.c b/external/flint-2.4.3/fmpz_factor/print.c new file mode 100644 index 0000000..dcb8a4c --- /dev/null +++ b/external/flint-2.4.3/fmpz_factor/print.c @@ -0,0 +1,62 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +void +fmpz_factor_print(const fmpz_factor_t factor) +{ + slong i; + + if (factor->sign == 0) + { + flint_printf("0"); + return; + } + + if (factor->sign == -1) + { + if (factor->num) + flint_printf("-1 * "); + else + flint_printf("-1"); + } + + for (i = 0; i < factor->num; i++) + { + fmpz_print(factor->p + i); + + if (factor->exp[i] != UWORD(1)) + flint_printf("^%wu", factor->exp[i]); + + if (i != factor->num - 1) + flint_printf(" * "); + } +} diff --git a/external/flint-2.4.3/fmpz_factor/profile/p-factor_pp1.c b/external/flint-2.4.3/fmpz_factor/profile/p-factor_pp1.c new file mode 100644 index 0000000..280d4a4 --- /dev/null +++ b/external/flint-2.4.3/fmpz_factor/profile/p-factor_pp1.c @@ -0,0 +1,81 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright 2012 William Hart + +******************************************************************************/ + +#include +#include +#include "profiler.h" +#include "flint.h" +#include "fmpz.h" +#include "fmpz_factor.h" + +int main(void) +{ + fmpz_t n, p; + ulong c; + ulong B1; + + fmpz_init(n); + fmpz_init(p); + + FLINT_TEST_INIT(state); + + + while(1) + { + flint_printf("Enter number to be factored: "); fflush(stdout); + if (!fmpz_read(n)) + { + flint_printf("Read failed\n"); + abort(); + } + + flint_printf("Enter B1: "); fflush(stdout); + if (!flint_scanf("%wu", &B1)) + { + flint_printf("Read failed\n"); + abort(); + } + + do + { + c = n_randlimb(state); + } while (c <= UWORD(2)); + + if (fmpz_factor_pp1(p, n, B1, B1/100, c)) + { + flint_printf("Factor: "); + fmpz_print(p); + flint_printf("\n"); + } else + flint_printf("Factor not found!\n"); + } while(1); + + flint_randclear(state); + + fmpz_clear(n); + fmpz_clear(p); + + return 0; +} \ No newline at end of file diff --git a/external/flint-2.4.3/fmpz_factor/set_length.c b/external/flint-2.4.3/fmpz_factor/set_length.c new file mode 100644 index 0000000..a8a34bc --- /dev/null +++ b/external/flint-2.4.3/fmpz_factor/set_length.c @@ -0,0 +1,42 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +void +_fmpz_factor_set_length(fmpz_factor_t factor, slong newlen) +{ + if (factor->num > newlen) + { + slong i; + for (i = newlen; i < factor->num; i++) + _fmpz_demote(factor->p + i); + } + factor->num = newlen; +} diff --git a/external/flint-2.4.3/fmpz_factor/test/t-factor.c b/external/flint-2.4.3/fmpz_factor/test/t-factor.c new file mode 100644 index 0000000..88a00aa --- /dev/null +++ b/external/flint-2.4.3/fmpz_factor/test/t-factor.c @@ -0,0 +1,176 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "ulong_extras.h" + +void check(fmpz_t n) +{ + fmpz_factor_t factor; + fmpz_t m; + slong i; + + fmpz_factor_init(factor); + fmpz_init(m); + + fmpz_factor(factor, n); + fmpz_factor_expand(m, factor); + + if (!fmpz_equal(n, m)) + { + flint_printf("ERROR: factors do not unfactor to original number!\n"); + + flint_printf("input: "); + fmpz_print(n); + flint_printf("\n"); + + flint_printf("computed factors: "); + fmpz_factor_print(factor); + flint_printf("\n"); + + flint_printf("value: "); + fmpz_print(m); + flint_printf("\n"); + + abort(); + } + + for (i = 0; i < factor->num; i++) + { + if (!fmpz_is_probabprime(factor->p + i)) + { + flint_printf("ERROR: factor is not prime!\n"); + + flint_printf("input: "); + fmpz_print(n); + flint_printf("\n"); + + flint_printf("computed factors: "); + fmpz_factor_print(factor); + flint_printf("\n"); + + abort(); + } + } + + fmpz_clear(m); + fmpz_factor_clear(factor); +} + +int main(void) +{ + int i, j; + fmpz_t x; + mpz_t y; + FLINT_TEST_INIT(state); + + flint_printf("factor...."); + fflush(stdout); + + fmpz_init(x); + mpz_init(y); + + /* Some corner cases */ + fmpz_set_ui(x, UWORD_MAX); + check(x); + fmpz_set_si(x, WORD_MAX); + check(x); + fmpz_set_si(x, WORD_MIN); + check(x); + fmpz_set_si(x, COEFF_MAX); + check(x); + fmpz_set_si(x, COEFF_MIN); + check(x); + + /* Small integers */ + for (i = -10000; i < 10000; i++) + { + fmpz_set_si(x, i); + check(x); + } + + /* Powers */ + for (i = 1; i < 250; i++) + { + for (j = 0; j < 250; j++) + { + fmpz_set_ui(x, i); + fmpz_pow_ui(x, x, j); + check(x); + } + } + + /* Factorials */ + for (i = 0; i < 1000; i++) + { + flint_mpz_fac_ui(y, i); + fmpz_set_mpz(x, y); + check(x); + } + + /* Powers of factorials */ + for (i = 0; i < 100; i++) + { + for (j = 1; j < 5; j++) + { + flint_mpz_fac_ui(y, i); + fmpz_set_mpz(x, y); + fmpz_pow_ui(x, x, j); + check(x); + } + } + + /* Whole limbs */ + for (i = 0; i < 1000; i++) + { + fmpz_set_ui(x, n_randtest(state)); + if (n_randint(state, 2)) + fmpz_neg(x, x); + check(x); + } + + /* Large negative integers */ + fmpz_set_ui(x, 10); + fmpz_pow_ui(x, x, 100); + fmpz_neg(x, x); + check(x); + flint_mpz_fac_ui(y, 50); + mpz_neg(y, y); + fmpz_set_mpz(x, y); + check(x); + + fmpz_clear(x); + mpz_clear(y); + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_factor/test/t-factor_pp1.c b/external/flint-2.4.3/fmpz_factor/test/t-factor_pp1.c new file mode 100644 index 0000000..bc85e2e --- /dev/null +++ b/external/flint-2.4.3/fmpz_factor/test/t-factor_pp1.c @@ -0,0 +1,112 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 William Hart + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, j, result; + ulong count = UWORD(0); + gmp_randstate_t st; + FLINT_TEST_INIT(state); + gmp_randinit_default(st); + + + flint_printf("factor_pp1...."); + fflush(stdout); + + for (i = 0; i < 50 * flint_test_multiplier(); i++) /* Test random numbers */ + { + mp_bitcnt_t bits; + mpz_t m, n; + fmpz_t n1, n2, r; + + mpz_init(n); + mpz_init(m); + fmpz_init(n1); + fmpz_init(n2); + fmpz_init(r); + + do { + mpz_urandomb(n, st, n_randint(state, 128) + 2); + } while (flint_mpz_cmp_ui(n, 2) < 0); + do { + mpz_urandomb(m, st, n_randint(state, 50) + 2); + } while (!mpz_probab_prime_p(m, 20)); + mpz_mul(n, n, m); + + fmpz_set_mpz(n1, n); + bits = FLINT_MIN(fmpz_bits(n1), FLINT_BITS); + + for (j = 0; j < 20; j++) + { + fmpz_factor_pp1(n2, n1, 10000, 10000, n_randbits(state, bits - 2) + 3); + if (fmpz_cmp_ui(n2, 1) > 0) break; + } + + if (fmpz_cmp_ui(n2, 1) > 0) + { + count++; + fmpz_mod(r, n1, n2); + result = (fmpz_is_zero(r)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("n1 = "); + fmpz_print(n1); + flint_printf(", n2 = "); + fmpz_print(n2); + flint_printf("\n"); + fmpz_print(r); flint_printf("\n"); + abort(); + } + } + + fmpz_clear(n1); + fmpz_clear(n2); + fmpz_clear(r); + mpz_clear(m); + mpz_clear(n); + } + + if (count < 49 * flint_test_multiplier()) + { + flint_printf("FAIL:\n"); + flint_printf("Only %wu numbers factored\n", count); + abort(); + } + + + gmp_randclear(st); + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_factorxx.h b/external/flint-2.4.3/fmpz_factorxx.h new file mode 100644 index 0000000..206e32b --- /dev/null +++ b/external/flint-2.4.3/fmpz_factorxx.h @@ -0,0 +1,189 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#ifndef FMPZ_FACTORXX_H +#define FMPZ_FACTORXX_H + +#include "fmpz_factor.h" +#include "fmpz_vec.h" + +#include "flintxx/ltuple.h" + +// TODO codegen +// TODO factor_pp1 multiple return values + +namespace flint { +FLINT_DEFINE_THREEARY(factor_trial_range) +FLINT_DEFINE_UNOP(expand) +FLINT_DEFINE_UNOP(expand_iterative) +FLINT_DEFINE_UNOP(expand_multiexp) + +namespace detail { +template +class fmpz_factorxx_delayed +{ +private: + fmpz_factor_t inner; + + void copy_init(const fmpz_factorxx_delayed& o) + { + _fmpz_factor_fit_length(inner, o.inner->num); + _fmpz_factor_set_length(inner, o.inner->num); + inner->sign = o.inner->sign; + for(slong i = 0;i < o.inner->num;++i) + { + fmpz_set(inner->p + i, o.inner->p + i); + inner->exp[i] = o.inner->exp[i]; + } + } + +public: + fmpz_factorxx_delayed() {fmpz_factor_init(inner);} + ~fmpz_factorxx_delayed() {fmpz_factor_clear(inner);} + + fmpz_factorxx_delayed(const fmpz_factorxx_delayed& o) + { + fmpz_factor_init(inner); + copy_init(o); + } + + fmpz_factorxx_delayed& operator=(const fmpz_factorxx_delayed& o) + { + copy_init(o); + return *this; + } + + bool operator==(const fmpz_factorxx_delayed& o) + { + if(o.sign() != sign() || o.size() != size()) + return false; + for(ulong i = 0;i < size();++i) + if(p(i) != o.p(i) || exp(i) != o.exp(i)) + return false; + return true; + } + + ulong size() const {return inner->num;} + ulong exp(slong i) const {return inner->exp[i];} + ulong& exp(slong i) {return inner->exp[i];} + fmpzxx_srcref p(slong i) const {return fmpzxx_srcref::make(inner->p + i);} + fmpzxx_ref p(slong i) {return fmpzxx_ref::make(inner->p + i);} + int sign() const {return inner->sign;} + int& sign() {return inner->sign;} + + fmpz_factor_t& _data() {return inner;} + const fmpz_factor_t& _data() const {return inner;} + + void print() const {fmpz_factor_print(inner);} + + template + typename mp::enable_if >::type + set_factor(const Fmpz& f) + { + fmpz_factor(_data(), f.evaluate()._fmpz()); + } + + template + typename mp::enable_if >::type + set_factor(T t) + { + fmpz_factor_si(_data(), t); + } + + template + typename mp::enable_if, bool>::type + set_factor_trial_range(const Fmpz& f, ulong start, ulong nprimes) + { + return fmpz_factor_trial_range(_data(), f.evaluate()._fmpz(), + start, nprimes); + } + + template + typename mp::enable_if, bool>::type + set_factor_pp1(const Fmpz& f, ulong B1, ulong B2_sqrt, ulong c) + { + return fmpz_factor_pp1(_data(), f.evaluate()._fmpz(), + B1, B2_sqrt, c); + } + +#define FLINTXX_DEFINE_MEMBER_UNOP_EXTRA(funcname, Class, rtype) \ + FLINT_UNOP_BUILD_RETTYPE(funcname, rtype, Class) \ + funcname() const {return flint::funcname(*this);} + + FLINTXX_DEFINE_MEMBER_UNOP_EXTRA(expand, fmpz_factorxx_delayed, fmpzxx) + FLINTXX_DEFINE_MEMBER_UNOP_EXTRA(expand_iterative, fmpz_factorxx_delayed, fmpzxx) + FLINTXX_DEFINE_MEMBER_UNOP_EXTRA(expand_multiexp, fmpz_factorxx_delayed, fmpzxx) +}; +} // detail +typedef detail::fmpz_factorxx_delayed fmpz_factorxx; + +template +inline typename mp::enable_if, traits::fits_into_slong >, + fmpz_factorxx>::type factor(const Fmpz& f) +{ + fmpz_factorxx res; + res.set_factor(f); + return res; +} + +namespace rules { +namespace rdetail { +typedef make_ltuple::type>::type + fmpz_factor_rt; + +template struct signed_or_fmpz + : mp::or_, traits::fits_into_slong > { }; +} // rdetail +FLINT_DEFINE_THREEARY_EXPR_COND3(factor_trial_range_op, rdetail::fmpz_factor_rt, + rdetail::signed_or_fmpz, + traits::is_unsigned_integer, traits::is_unsigned_integer, + to.template get<0>() = to.template get<1>().set_factor_trial_range( + e1, e2, e3)) + +FLINT_DEFINE_UNARY_EXPR_(expand_op, fmpzxx, fmpz_factorxx, + fmpz_factor_expand(to._fmpz(), from._data())) +FLINT_DEFINE_UNARY_EXPR_(expand_iterative_op, fmpzxx, fmpz_factorxx, + fmpz_factor_expand_iterative(to._fmpz(), from._data())) +FLINT_DEFINE_UNARY_EXPR_(expand_multiexp_op, fmpzxx, fmpz_factorxx, + fmpz_factor_expand_multiexp(to._fmpz(), from._data())) +} // rules + +template +inline typename mp::enable_if, fmpz_factorxx>::type +factor_pp1(const Fmpz& f, ulong B1, ulong B2_sqrt, ulong c) +{ + fmpz_factorxx res; + res.set_factor_pp1(f, B1, B2_sqrt, c); + return res; +} + +inline void print(const fmpz_factorxx& f) +{ + f.print(); +} +} // flint + +#endif diff --git a/external/flint-2.4.3/fmpz_mat.h b/external/flint-2.4.3/fmpz_mat.h new file mode 100644 index 0000000..359e7e2 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat.h @@ -0,0 +1,316 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Fredrik Johansson + +******************************************************************************/ + +#ifndef FMPZ_MAT_H +#define FMPZ_MAT_H + +#undef ulong +#define ulong ulongxx /* interferes with system includes */ +#include +#undef ulong + +#include +#define ulong mp_limb_t +#include "flint.h" +#include "fmpz.h" +#include "nmod_mat.h" +#include "fmpz_poly.h" + +#ifdef __cplusplus + extern "C" { +#endif + +typedef struct +{ + fmpz * entries; + slong r; + slong c; + fmpz ** rows; +} fmpz_mat_struct; + +typedef fmpz_mat_struct fmpz_mat_t[1]; + +/* Memory management ********************************************************/ + +#define fmpz_mat_entry(mat,i,j) ((mat)->rows[i] + (j)) +#define fmpz_mat_nrows(mat) ((mat)->r) +#define fmpz_mat_ncols(mat) ((mat)->c) + +void fmpz_mat_init(fmpz_mat_t mat, slong rows, slong cols); +void fmpz_mat_init_set(fmpz_mat_t mat, const fmpz_mat_t src); +void fmpz_mat_swap(fmpz_mat_t mat1, fmpz_mat_t mat2); +void fmpz_mat_set(fmpz_mat_t mat1, const fmpz_mat_t mat2); +void fmpz_mat_clear(fmpz_mat_t mat); + +int fmpz_mat_equal(const fmpz_mat_t mat1, const fmpz_mat_t mat2); +int fmpz_mat_is_zero(const fmpz_mat_t mat); + +static __inline__ int +fmpz_mat_is_empty(const fmpz_mat_t mat) +{ + return (mat->r == 0) || (mat->c == 0); +} + +static __inline__ int +fmpz_mat_is_square(const fmpz_mat_t mat) +{ + return (mat->r == mat->c); +} + +void fmpz_mat_zero(fmpz_mat_t mat); +void fmpz_mat_one(fmpz_mat_t mat); + + +/* Input and output *********************************************************/ + +int fmpz_mat_fprint(FILE * file, const fmpz_mat_t mat); + +int fmpz_mat_fprint_pretty(FILE * file, const fmpz_mat_t mat); + +static __inline__ +int fmpz_mat_print(const fmpz_mat_t mat) +{ + return fmpz_mat_fprint(stdout, mat); +} + +static __inline__ +int fmpz_mat_print_pretty(const fmpz_mat_t mat) +{ + return fmpz_mat_fprint_pretty(stdout, mat); +} + +int fmpz_mat_fread(FILE* file, fmpz_mat_t mat); + +static __inline__ +int fmpz_mat_read(fmpz_mat_t mat) +{ + return fmpz_mat_fread(stdin, mat); +} + +/* Random matrix generation *************************************************/ + +void fmpz_mat_randbits(fmpz_mat_t mat, flint_rand_t state, mp_bitcnt_t bits); +void fmpz_mat_randtest(fmpz_mat_t mat, flint_rand_t state, mp_bitcnt_t bits); +void fmpz_mat_randtest_unsigned(fmpz_mat_t mat, flint_rand_t state, mp_bitcnt_t bits); +void fmpz_mat_randintrel(fmpz_mat_t mat, flint_rand_t state, mp_bitcnt_t bits); +void fmpz_mat_randsimdioph(fmpz_mat_t mat, flint_rand_t state, mp_bitcnt_t bits, mp_bitcnt_t bits2); +void fmpz_mat_randntrulike(fmpz_mat_t mat, flint_rand_t state, mp_bitcnt_t bits, ulong q); +void fmpz_mat_randntrulike2(fmpz_mat_t mat, flint_rand_t state, mp_bitcnt_t bits, ulong q); +void fmpz_mat_randajtai(fmpz_mat_t mat, flint_rand_t state, double alpha); +void fmpz_mat_randrank(fmpz_mat_t mat, flint_rand_t state, slong rank, mp_bitcnt_t bits); +void fmpz_mat_randdet(fmpz_mat_t mat, flint_rand_t state, const fmpz_t det); +void fmpz_mat_randops(fmpz_mat_t mat, flint_rand_t state, slong count); +int fmpz_mat_randpermdiag(fmpz_mat_t mat, flint_rand_t state, const fmpz * diag, slong n); + +/* Norms */ + +slong fmpz_mat_max_bits(const fmpz_mat_t mat); + +/* Transpose */ + +void fmpz_mat_transpose(fmpz_mat_t B, const fmpz_mat_t A); + +/* Addition and subtraction */ + +void fmpz_mat_add(fmpz_mat_t C, const fmpz_mat_t A, const fmpz_mat_t B); +void fmpz_mat_sub(fmpz_mat_t C, const fmpz_mat_t A, const fmpz_mat_t B); +void fmpz_mat_neg(fmpz_mat_t B, const fmpz_mat_t A); + +/* Scalar operations */ +void fmpz_mat_scalar_mul_fmpz(fmpz_mat_t B, const fmpz_mat_t A, const fmpz_t c); +void fmpz_mat_scalar_mul_si(fmpz_mat_t B, const fmpz_mat_t A, slong c); +void fmpz_mat_scalar_mul_ui(fmpz_mat_t B, const fmpz_mat_t A, ulong c); + +void fmpz_mat_scalar_addmul_fmpz(fmpz_mat_t B, const fmpz_mat_t A, const fmpz_t c); +void fmpz_mat_scalar_addmul_si(fmpz_mat_t B, const fmpz_mat_t A, slong c); +void fmpz_mat_scalar_addmul_ui(fmpz_mat_t B, const fmpz_mat_t A, ulong c); + +void fmpz_mat_scalar_submul_fmpz(fmpz_mat_t B, const fmpz_mat_t A, const fmpz_t c); +void fmpz_mat_scalar_submul_si(fmpz_mat_t B, const fmpz_mat_t A, slong c); +void fmpz_mat_scalar_submul_ui(fmpz_mat_t B, const fmpz_mat_t A, ulong c); + +void fmpz_mat_scalar_addmul_nmod_mat_fmpz(fmpz_mat_t B, const nmod_mat_t A, const fmpz_t c); +void fmpz_mat_scalar_addmul_nmod_mat_ui(fmpz_mat_t B, const nmod_mat_t A, ulong c); + +void fmpz_mat_scalar_divexact_fmpz(fmpz_mat_t B, const fmpz_mat_t A, const fmpz_t c); +void fmpz_mat_scalar_divexact_si(fmpz_mat_t B, const fmpz_mat_t A, slong c); +void fmpz_mat_scalar_divexact_ui(fmpz_mat_t B, const fmpz_mat_t A, ulong c); + +void fmpz_mat_scalar_mod_fmpz(fmpz_mat_t B, const fmpz_mat_t A, const fmpz_t m); + +/* Multiplication */ + +void fmpz_mat_mul(fmpz_mat_t C, const fmpz_mat_t A, const fmpz_mat_t B); + +void fmpz_mat_mul_classical(fmpz_mat_t C, const fmpz_mat_t A, + const fmpz_mat_t B); + +void fmpz_mat_mul_classical_inline(fmpz_mat_t C, const fmpz_mat_t A, + const fmpz_mat_t B); + +void _fmpz_mat_mul_multi_mod(fmpz_mat_t C, const fmpz_mat_t A, + const fmpz_mat_t B, mp_bitcnt_t bits); + +void fmpz_mat_mul_multi_mod(fmpz_mat_t C, const fmpz_mat_t A, + const fmpz_mat_t B); + +void fmpz_mat_sqr(fmpz_mat_t B, const fmpz_mat_t A); + +void fmpz_mat_pow(fmpz_mat_t B, const fmpz_mat_t A, ulong exp); + +/* Permutations */ + +static __inline__ void +fmpz_mat_swap_rows(fmpz_mat_t mat, slong * perm, slong r, slong s) +{ + if (r != s) + { + fmpz * u; + slong t; + + if (perm) + { + t = perm[s]; + perm[s] = perm[r]; + perm[r] = t; + } + + u = mat->rows[s]; + mat->rows[s] = mat->rows[r]; + mat->rows[r] = u; + } +} + +/* Gaussian elimination *****************************************************/ + +slong fmpz_mat_find_pivot_any(const fmpz_mat_t mat, + slong start_row, slong end_row, slong c); + +slong fmpz_mat_fflu(fmpz_mat_t B, fmpz_t den, slong * perm, + const fmpz_mat_t A, int rank_check); + +slong fmpz_mat_rref(fmpz_mat_t B, fmpz_t den, const fmpz_mat_t A); + +/* Modular gaussian elimination *********************************************/ + +slong +fmpz_mat_rref_mod(slong * perm, fmpz_mat_t A, const fmpz_t p); + +/* Trace ********************************************************************/ + +void fmpz_mat_trace(fmpz_t trace, const fmpz_mat_t mat); + +/* Determinant **************************************************************/ + +void fmpz_mat_det(fmpz_t det, const fmpz_mat_t A); + +void fmpz_mat_det_cofactor(fmpz_t det, const fmpz_mat_t A); +void _fmpz_mat_det_cofactor_2x2(fmpz_t det, fmpz ** const x); +void _fmpz_mat_det_cofactor_3x3(fmpz_t det, fmpz ** const x); +void _fmpz_mat_det_cofactor_4x4(fmpz_t det, fmpz ** const x); + +void fmpz_mat_det_bareiss(fmpz_t det, const fmpz_mat_t A); + +void fmpz_mat_det_modular(fmpz_t det, const fmpz_mat_t A, int proved); + +void fmpz_mat_det_modular_accelerated(fmpz_t det, + const fmpz_mat_t A, int proved); + +void fmpz_mat_det_modular_given_divisor(fmpz_t det, const fmpz_mat_t A, + const fmpz_t d, int proved); + +void fmpz_mat_det_bound(fmpz_t bound, const fmpz_mat_t A); +void fmpz_mat_det_divisor(fmpz_t d, const fmpz_mat_t A); + +/* Characteristic polynomial ************************************************/ + +void _fmpz_mat_charpoly(fmpz *cp, const fmpz_mat_t mat); +void fmpz_mat_charpoly(fmpz_poly_t cp, const fmpz_mat_t mat); + +/* Rank *********************************************************************/ + +slong fmpz_mat_rank(const fmpz_mat_t A); + +/* Nonsingular solving ******************************************************/ + +void fmpz_mat_solve_bound(fmpz_t N, fmpz_t D, + const fmpz_mat_t A, const fmpz_mat_t B); + +int fmpz_mat_solve(fmpz_mat_t X, fmpz_t den, + const fmpz_mat_t A, const fmpz_mat_t B); + +int fmpz_mat_solve_cramer(fmpz_mat_t X, fmpz_t den, + const fmpz_mat_t A, const fmpz_mat_t B); + +int fmpz_mat_solve_fflu(fmpz_mat_t X, fmpz_t den, + const fmpz_mat_t A, const fmpz_mat_t B); + +void fmpz_mat_solve_fflu_precomp(fmpz_mat_t X, const slong * perm, + const fmpz_mat_t FFLU, const fmpz_mat_t B); + +int fmpz_mat_solve_dixon(fmpz_mat_t X, fmpz_t mod, + const fmpz_mat_t A, const fmpz_mat_t B); + +/* Nullspace ****************************************************************/ + +slong fmpz_mat_nullspace(fmpz_mat_t res, const fmpz_mat_t mat); + +/* Inverse ******************************************************************/ + +int fmpz_mat_inv(fmpz_mat_t B, fmpz_t den, const fmpz_mat_t A); + +/* Modular reduction and reconstruction *************************************/ + +void fmpz_mat_set_nmod_mat(fmpz_mat_t A, const nmod_mat_t Amod); + +void fmpz_mat_set_nmod_mat_unsigned(fmpz_mat_t A, const nmod_mat_t Amod); + +void fmpz_mat_get_nmod_mat(nmod_mat_t Amod, const fmpz_mat_t A); + +void fmpz_mat_CRT_ui(fmpz_mat_t res, const fmpz_mat_t mat1, + const fmpz_t m1, const nmod_mat_t mat2, int sign); + +void +fmpz_mat_multi_mod_ui_precomp(nmod_mat_t * residues, slong nres, + const fmpz_mat_t mat, const fmpz_comb_t comb, fmpz_comb_temp_t temp); + +void +fmpz_mat_multi_mod_ui(nmod_mat_t * residues, slong nres, const fmpz_mat_t mat); + +void +fmpz_mat_multi_CRT_ui_precomp(fmpz_mat_t mat, + nmod_mat_t * const residues, slong nres, + const fmpz_comb_t comb, fmpz_comb_temp_t temp, int sign); + +void fmpz_mat_multi_CRT_ui(fmpz_mat_t mat, nmod_mat_t * const residues, + slong nres, int sign); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/external/flint-2.4.3/fmpz_mat/CRT_ui.c b/external/flint-2.4.3/fmpz_mat/CRT_ui.c new file mode 100644 index 0000000..76777a3 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/CRT_ui.c @@ -0,0 +1,59 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +void +fmpz_mat_CRT_ui(fmpz_mat_t res, const fmpz_mat_t mat1, + const fmpz_t m1, const nmod_mat_t mat2, int sign) +{ + slong i, j; + mp_limb_t c; + mp_limb_t m2 = mat2->mod.n; + mp_limb_t m2inv = mat2->mod.ninv; + fmpz_t m1m2; + + c = fmpz_fdiv_ui(m1, m2); + c = n_invmod(c, m2); + + if (c == 0) + { + flint_printf("Exception (fmpz_mat_CRT_ui). m1 not invertible modulo m2.\n"); + abort(); + } + + fmpz_init(m1m2); + fmpz_mul_ui(m1m2, m1, m2); + + for (i = 0; i < mat1->r; i++) + { + for (j = 0; j < mat1->c; j++) + _fmpz_CRT_ui_precomp(fmpz_mat_entry(res, i, j), + fmpz_mat_entry(mat1, i, j), m1, + nmod_mat_entry(mat2, i, j), m2, m2inv, m1m2, c, sign); + } + + fmpz_clear(m1m2); +} diff --git a/external/flint-2.4.3/fmpz_mat/add.c b/external/flint-2.4.3/fmpz_mat/add.c new file mode 100644 index 0000000..1890832 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/add.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +void +fmpz_mat_add(fmpz_mat_t res, const fmpz_mat_t mat1, const fmpz_mat_t mat2) +{ + slong i; + + if (res->c < 1) + return; + + for (i = 0; i < res->r; i++) + _fmpz_vec_add(res->rows[i], mat1->rows[i], mat2->rows[i], res->c); +} diff --git a/external/flint-2.4.3/fmpz_mat/charpoly.c b/external/flint-2.4.3/fmpz_mat/charpoly.c new file mode 100644 index 0000000..474efcf --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/charpoly.c @@ -0,0 +1,124 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_mat.h" + +/* + Assumes that \code{mat} is an $n \times n$ matrix and sets \code{(cp,n+1)} + to its characteristic polynomial. + + Employs a division-free algorithm using $O(n^4)$ ring operations. + */ + +void _fmpz_mat_charpoly(fmpz *cp, const fmpz_mat_t mat) +{ + const slong n = mat->r; + + if (n == 0) + { + fmpz_one(cp); + } + else if (n == 1) + { + fmpz_neg(cp + 0, fmpz_mat_entry(mat, 0, 0)); + fmpz_one(cp + 1); + } + else + { + slong i, j, k, t; + fmpz *a, *A, *s; + + a = _fmpz_vec_init(n * n); + A = a + (n - 1) * n; + + _fmpz_vec_zero(cp, n + 1); + fmpz_neg(cp + 0, fmpz_mat_entry(mat, 0, 0)); + + for (t = 1; t < n; t++) + { + for (i = 0; i <= t; i++) + { + fmpz_set(a + 0 * n + i, fmpz_mat_entry(mat, i, t)); + } + + fmpz_set(A + 0, fmpz_mat_entry(mat, t, t)); + + for (k = 1; k < t; k++) + { + for (i = 0; i <= t; i++) + { + s = a + k * n + i; + fmpz_zero(s); + for (j = 0; j <= t; j++) + { + fmpz_addmul(s, fmpz_mat_entry(mat, i, j), a + (k - 1) * n + j); + } + } + fmpz_set(A + k, a + k * n + t); + } + + fmpz_zero(A + t); + for (j = 0; j <= t; j++) + { + fmpz_addmul(A + t, fmpz_mat_entry(mat, t, j), a + (t - 1) * n + j); + } + + for (k = 0; k <= t; k++) + { + for (j = 0; j < k; j++) + { + fmpz_submul(cp + k, A + j, cp + (k - j - 1)); + } + fmpz_sub(cp + k, cp + k, A + k); + } + } + + /* Shift all coefficients up by one */ + for (i = n; i > 0; i--) + { + fmpz_swap(cp + i, cp + (i - 1)); + } + fmpz_one(cp + 0); + + _fmpz_poly_reverse(cp, cp, n + 1, n + 1); + + _fmpz_vec_clear(a, n * n); + } +} + +void fmpz_mat_charpoly(fmpz_poly_t cp, const fmpz_mat_t mat) +{ + if (mat->r != mat->c) + { + flint_printf("Exception (fmpz_mat_charpoly). Non-square matrix.\n"); + abort(); + } + + fmpz_poly_fit_length(cp, mat->r + 1); + _fmpz_poly_set_length(cp, mat->r + 1); + + _fmpz_mat_charpoly(cp->coeffs, mat); +} + diff --git a/external/flint-2.4.3/fmpz_mat/clear.c b/external/flint-2.4.3/fmpz_mat/clear.c new file mode 100644 index 0000000..19b4df9 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/clear.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include "fmpz_mat.h" + +void +fmpz_mat_clear(fmpz_mat_t mat) +{ + if (mat->entries) + { + slong i; + for (i = 0; i < mat->r * mat->c; i++) + fmpz_clear(mat->entries + i); /* Clear all coefficients */ + flint_free(mat->entries); /* Clean up array of entries */ + flint_free(mat->rows); /* Clean up row array */ + } +} diff --git a/external/flint-2.4.3/fmpz_mat/det.c b/external/flint-2.4.3/fmpz_mat/det.c new file mode 100644 index 0000000..8526b4c --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/det.c @@ -0,0 +1,54 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010,2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +void +fmpz_mat_det(fmpz_t det, const fmpz_mat_t A) +{ + slong dim = A->r; + + if (dim != A->c) + { + flint_printf("Exception (fmpz_mat_det). Non-square matrix.\n"); + abort(); + } + + if (dim < 5) + fmpz_mat_det_cofactor(det, A); + else if (dim < 25) + fmpz_mat_det_bareiss(det, A); + else if (dim < 60) + fmpz_mat_det_modular(det, A, 1); + else + { + slong bits = fmpz_mat_max_bits(A); + + if (dim < FLINT_ABS(bits)) + fmpz_mat_det_modular(det, A, 1); + else + fmpz_mat_det_modular_accelerated(det, A, 1); + } +} diff --git a/external/flint-2.4.3/fmpz_mat/det_bareiss.c b/external/flint-2.4.3/fmpz_mat/det_bareiss.c new file mode 100644 index 0000000..99c61b0 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/det_bareiss.c @@ -0,0 +1,57 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010,2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" +#include "perm.h" + +void +_fmpz_mat_det_bareiss(fmpz_t det, fmpz_mat_t tmp) +{ + slong *perm, n = fmpz_mat_nrows(tmp); + perm = _perm_init(n); + + fmpz_mat_fflu(tmp, det, perm, tmp, 1); + + if (_perm_parity(perm, n) == 1) + fmpz_neg(det, det); + + _perm_clear(perm); +} + +void +fmpz_mat_det_bareiss(fmpz_t det, const fmpz_mat_t A) +{ + fmpz_mat_t tmp; + + if (A->r < 1) + { + fmpz_one(det); + return; + } + + fmpz_mat_init_set(tmp, A); + _fmpz_mat_det_bareiss(det, tmp); + fmpz_mat_clear(tmp); +} diff --git a/external/flint-2.4.3/fmpz_mat/det_bound.c b/external/flint-2.4.3/fmpz_mat/det_bound.c new file mode 100644 index 0000000..e53a398 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/det_bound.c @@ -0,0 +1,57 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +void +fmpz_mat_det_bound(fmpz_t bound, const fmpz_mat_t A) +{ + fmpz_t p, s, t; + slong i, j; + + fmpz_init(p); + fmpz_init(s); + fmpz_init(t); + fmpz_one(p); + + for (i = 0; i < A->r; i++) + { + fmpz_zero(s); + + for (j = 0; j < A->c; j++) + fmpz_addmul(s, A->rows[i] + j, A->rows[i] + j); + + fmpz_sqrtrem(s, t, s); + if (!fmpz_is_zero(t)) + fmpz_add_ui(s, s, UWORD(1)); + + fmpz_mul(p, p, s); + } + + fmpz_set(bound, p); + fmpz_clear(p); + fmpz_clear(s); + fmpz_clear(t); +} diff --git a/external/flint-2.4.3/fmpz_mat/det_cofactor.c b/external/flint-2.4.3/fmpz_mat/det_cofactor.c new file mode 100644 index 0000000..03fe3de --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/det_cofactor.c @@ -0,0 +1,136 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010,2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +void +_fmpz_mat_det_cofactor_2x2(fmpz_t det, fmpz ** const x) +{ + fmpz_t t; + fmpz_init(t); + + fmpz_mul (t, &x[0][0], &x[1][1]); + fmpz_submul(t, &x[0][1], &x[1][0]); + + fmpz_set(det, t); + fmpz_clear(t); +} + +void +_fmpz_mat_det_cofactor_3x3(fmpz_t det, fmpz ** const x) +{ + fmpz_t a, t; + + fmpz_init(a); + fmpz_init(t); + + fmpz_mul (a, &x[1][0], &x[2][1]); + fmpz_submul(a, &x[1][1], &x[2][0]); + fmpz_mul (t, a, &x[0][2]); + + fmpz_mul (a, &x[1][2], &x[2][0]); + fmpz_submul(a, &x[1][0], &x[2][2]); + fmpz_addmul(t, a, &x[0][1]); + + fmpz_mul (a, &x[1][1], &x[2][2]); + fmpz_submul(a, &x[1][2], &x[2][1]); + fmpz_addmul(t, a, &x[0][0]); + + fmpz_set(det, t); + + fmpz_clear(a); + fmpz_clear(t); +} + +void +_fmpz_mat_det_cofactor_4x4(fmpz_t det, fmpz ** const x) +{ + fmpz_t a, b, t; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(t); + + fmpz_mul (a, &x[0][3], &x[1][2]); + fmpz_submul(a, &x[0][2], &x[1][3]); + fmpz_mul (b, &x[2][1], &x[3][0]); + fmpz_submul(b, &x[2][0], &x[3][1]); + fmpz_mul(t, a, b); + + fmpz_mul (a, &x[0][1], &x[1][3]); + fmpz_submul(a, &x[0][3], &x[1][1]); + fmpz_mul (b, &x[2][2], &x[3][0]); + fmpz_submul(b, &x[2][0], &x[3][2]); + fmpz_addmul(t, a, b); + + fmpz_mul (a, &x[0][2], &x[1][1]); + fmpz_submul(a, &x[0][1], &x[1][2]); + fmpz_mul (b, &x[2][3], &x[3][0]); + fmpz_submul(b, &x[2][0], &x[3][3]); + fmpz_addmul(t, a, b); + + fmpz_mul (a, &x[0][3], &x[1][0]); + fmpz_submul(a, &x[0][0], &x[1][3]); + fmpz_mul (b, &x[2][2], &x[3][1]); + fmpz_submul(b, &x[2][1], &x[3][2]); + fmpz_addmul(t, a, b); + + fmpz_mul (a, &x[0][0], &x[1][2]); + fmpz_submul(a, &x[0][2], &x[1][0]); + fmpz_mul (b, &x[2][3], &x[3][1]); + fmpz_submul(b, &x[2][1], &x[3][3]); + fmpz_addmul(t, a, b); + + fmpz_mul (a, &x[0][1], &x[1][0]); + fmpz_submul(a, &x[0][0], &x[1][1]); + fmpz_mul (b, &x[2][3], &x[3][2]); + fmpz_submul(b, &x[2][2], &x[3][3]); + fmpz_addmul(t, a, b); + + fmpz_set(det, t); + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(t); +} + + +void +fmpz_mat_det_cofactor(fmpz_t det, const fmpz_mat_t A) +{ + slong dim = A->r; + + switch (dim) + { + case 0: fmpz_one(det); break; + case 1: fmpz_set(det, A->rows[0]); break; + case 2: _fmpz_mat_det_cofactor_2x2(det, A->rows); break; + case 3: _fmpz_mat_det_cofactor_3x3(det, A->rows); break; + case 4: _fmpz_mat_det_cofactor_4x4(det, A->rows); break; + default: + flint_printf("Exception (fmpz_mat_det_cofactor). dim > 4 not implemented."); + abort(); + } +} diff --git a/external/flint-2.4.3/fmpz_mat/det_divisor.c b/external/flint-2.4.3/fmpz_mat/det_divisor.c new file mode 100644 index 0000000..0a71d74 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/det_divisor.c @@ -0,0 +1,82 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" +#include "fmpq.h" + +void +fmpz_mat_det_divisor(fmpz_t d, const fmpz_mat_t A) +{ + fmpz_mat_t X, B; + fmpz_t t, u, v, mod; + slong i, n; + int success; + + n = A->r; + + fmpz_mat_init(B, n, 1); + fmpz_mat_init(X, n, 1); + fmpz_init(t); + fmpz_init(u); + fmpz_init(v); + fmpz_init(mod); + + /* Create a "random" vector */ + for (i = 0; i < n; i++) + { + fmpz_set_si(fmpz_mat_entry(B, i, 0), 2*(i % 2) - 1); + } + + success = fmpz_mat_solve_dixon(X, mod, A, B); + + if (success) + { + fmpz_one(d); + for (i = 0; i < n; i++) + { + fmpz_mul(t, d, fmpz_mat_entry(X, i, 0)); + fmpz_fdiv_qr(u, t, t, mod); + if (!_fmpq_reconstruct_fmpz(u, v, t, mod)) + { + flint_printf("Exception (fmpz_mat_det_divisor): " + "Rational reconstruction failed.\n"); + abort(); + } + + fmpz_mul(d, v, d); + } + } + else + { + fmpz_zero(d); + } + + fmpz_mat_clear(B); + fmpz_mat_clear(X); + fmpz_clear(t); + fmpz_clear(u); + fmpz_clear(v); + fmpz_clear(mod); +} diff --git a/external/flint-2.4.3/fmpz_mat/det_modular.c b/external/flint-2.4.3/fmpz_mat/det_modular.c new file mode 100644 index 0000000..f5e4152 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/det_modular.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +void +fmpz_mat_det_modular(fmpz_t det, const fmpz_mat_t A, int proved) +{ + fmpz_t d; + fmpz_init(d); + fmpz_one(d); + fmpz_mat_det_modular_given_divisor(det, A, d, proved); + fmpz_clear(d); +} diff --git a/external/flint-2.4.3/fmpz_mat/det_modular_accelerated.c b/external/flint-2.4.3/fmpz_mat/det_modular_accelerated.c new file mode 100644 index 0000000..d9cc823 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/det_modular_accelerated.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +void +fmpz_mat_det_modular_accelerated(fmpz_t det, const fmpz_mat_t A, int proved) +{ + fmpz_t d; + fmpz_init(d); + fmpz_mat_det_divisor(d, A); + fmpz_mat_det_modular_given_divisor(det, A, d, proved); + fmpz_clear(d); +} diff --git a/external/flint-2.4.3/fmpz_mat/det_modular_given_divisor.c b/external/flint-2.4.3/fmpz_mat/det_modular_given_divisor.c new file mode 100644 index 0000000..8b6612e --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/det_modular_given_divisor.c @@ -0,0 +1,127 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +/* Enable to exercise corner cases */ +#define DEBUG_USE_SMALL_PRIMES 0 + + +static mp_limb_t +next_good_prime(const fmpz_t d, mp_limb_t p) +{ + mp_limb_t r = 0; + + while (r == 0) + { + p = n_nextprime(p, 0); + r = fmpz_fdiv_ui(d, p); + } + + return p; +} + + +void +fmpz_mat_det_modular_given_divisor(fmpz_t det, const fmpz_mat_t A, + const fmpz_t d, int proved) +{ + fmpz_t bound, prod, stable_prod, x, xnew; + mp_limb_t p, xmod; + nmod_mat_t Amod; + slong n = A->r; + + if (n == 0) + { + fmpz_one(det); + return; + } + + if (fmpz_is_zero(d)) + { + fmpz_zero(det); + return; + } + + fmpz_init(bound); + fmpz_init(prod); + fmpz_init(stable_prod); + fmpz_init(x); + fmpz_init(xnew); + + /* Bound x = det(A) / d */ + fmpz_mat_det_bound(bound, A); + fmpz_mul_ui(bound, bound, UWORD(2)); /* accomodate sign */ + fmpz_cdiv_q(bound, bound, d); + + nmod_mat_init(Amod, n, n, 2); + fmpz_zero(x); + fmpz_one(prod); + +#if DEBUG_USE_SMALL_PRIMES + p = UWORD(1); +#else + p = UWORD(1) << NMOD_MAT_OPTIMAL_MODULUS_BITS; +#endif + + /* Compute x = det(A) / d */ + while (fmpz_cmp(prod, bound) <= 0) + { + p = next_good_prime(d, p); + _nmod_mat_set_mod(Amod, p); + fmpz_mat_get_nmod_mat(Amod, A); + + /* Compute x = det(A) / d mod p */ + xmod = _nmod_mat_det(Amod); + xmod = n_mulmod2_preinv(xmod, + n_invmod(fmpz_fdiv_ui(d, p), p), Amod->mod.n, Amod->mod.ninv); + + fmpz_CRT_ui(xnew, x, prod, xmod, p, 1); + + if (fmpz_equal(xnew, x)) + { + fmpz_mul_ui(stable_prod, stable_prod, p); + if (!proved && fmpz_bits(stable_prod) > 100) + break; + } + else + { + fmpz_set_ui(stable_prod, p); + } + + fmpz_mul_ui(prod, prod, p); + fmpz_set(x, xnew); + } + + /* det(A) = x * d */ + fmpz_mul(det, x, d); + + nmod_mat_clear(Amod); + fmpz_clear(bound); + fmpz_clear(prod); + fmpz_clear(stable_prod); + fmpz_clear(x); + fmpz_clear(xnew); +} diff --git a/external/flint-2.4.3/fmpz_mat/doc/fmpz_mat.txt b/external/flint-2.4.3/fmpz_mat/doc/fmpz_mat.txt new file mode 100644 index 0000000..2b25dd4 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/doc/fmpz_mat.txt @@ -0,0 +1,860 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010-2011 Andy Novocin + Copyright (C) 2010-2011 Fredrik Johansson + +******************************************************************************/ + + +******************************************************************************* + + Memory management + +******************************************************************************* + +void fmpz_mat_init(fmpz_mat_t mat, slong rows, slong cols) + + Initialises a matrix with the given number of rows and columns for use. + +void fmpz_mat_clear(fmpz_mat_t mat) + + Clears the given matrix. + +******************************************************************************* + + Basic assignment and manipulation + +******************************************************************************* + +void fmpz_mat_set(fmpz_mat_t mat1, const fmpz_mat_t mat2) + + Sets \code{mat1} to a copy of \code{mat2}. The dimensions of + \code{mat1} and \code{mat2} must be the same. + +void fmpz_mat_init_set(fmpz_mat_t mat, const fmpz_mat_t src) + + Initialises the matrix \code{mat} to the same size as \code{src} and + sets it to a copy of \code{src}. + +void fmpz_mat_swap(fmpz_mat_t mat1, fmpz_mat_t mat2) + + Swaps two matrices. The dimensions of \code{mat1} and \code{mat2} + are allowed to be different. + +fmpz * fmpz_mat_entry(fmpz_mat_t mat, slong i, slong j) + + Returns a reference to the entry of \code{mat} at row $i$ and column $j$. + This reference can be passed as an input or output variable to any + function in the \code{fmpz} module for direct manipulation. + + Both $i$ and $j$ must not exceed the dimensions of the matrix. + + This function is implemented as a macro. + +void fmpz_mat_zero(fmpz_mat_t mat) + + Sets all entries of \code{mat} to 0. + +void fmpz_mat_one(fmpz_mat_t mat) + + Sets \code{mat} to the unit matrix, having ones on the main diagonal + and zeroes elsewhere. If \code{mat} is nonsquare, it is set to the + truncation of a unit matrix. + + +******************************************************************************* + + Random matrix generation + +******************************************************************************* + +void fmpz_mat_randbits(fmpz_mat_t mat, flint_rand_t state, mp_bitcnt_t bits) + + Sets the entries of \code{mat} to random signed integers whose absolute + values have the given number of binary bits. + +void fmpz_mat_randtest(fmpz_mat_t mat, flint_rand_t state, mp_bitcnt_t bits) + + Sets the entries of \code{mat} to random signed integers whose + absolute values have a random number of bits up to the given number + of bits inclusive. + +void fmpz_mat_randintrel(fmpz_mat_t mat, flint_rand_t state, mp_bitcnt_t bits) + + Sets \code{mat} to be a random \emph{integer relations} matrix, with + signed entries up to the given number of bits. + + The number of columns of \code{mat} must be equal to one more than + the number of rows. The format of the matrix is a set of random integers + in the left hand column and an identity matrix in the remaining square + submatrix. + +void fmpz_mat_randsimdioph(fmpz_mat_t mat, flint_rand_t state, + mp_bitcnt_t bits, mp_bitcnt_t bits2) + + Sets \code{mat} to a random \emph{simultaneous diophantine} matrix. + + The matrix must be square. The top left entry is set to \code{2^bits2}. + The remainder of that row is then set to signed random integers of the + given number of binary bits. The remainder of the first column is zero. + Running down the rest of the diagonal are the values \code{2^bits} with + all remaining entries zero. + +void fmpz_mat_randntrulike(fmpz_mat_t mat, flint_rand_t state, + mp_bitcnt_t bits, ulong q) + + Sets a square matrix \code{mat} of even dimension to a random + \emph{NTRU like} matrix. + + The matrix is broken into four square submatrices. The top left submatrix + is set to the identity. The bottom left submatrix is set to the zero + matrix. The bottom right submatrix is set to $q$ times the identity matrix. + Finally the top right submatrix has the following format. A random vector + $h$ of length $r/2$ is created, with random signed entries of the given + number of bits. Then entry $(i, j)$ of the submatrix is set to + $h[i + j \bmod{r/2}]$. + +void fmpz_mat_randntrulike2(fmpz_mat_t mat, flint_rand_t state, + mp_bitcnt_t bits, ulong q) + + Sets a square matrix \code{mat} of even dimension to a random + \emph{NTRU like} matrix. + + The matrix is broken into four square submatrices. The top left submatrix + is set to $q$ times the identity matrix. The top right submatrix is set to + the zero matrix. The bottom right submatrix is set to the identity matrix. + Finally the bottom left submatrix has the following format. A random vector + $h$ of length $r/2$ is created, with random signed entries of the given + number of bits. Then entry $(i, j)$ of the submatrix is set to + $h[i + j \bmod{r/2}]$. + +void fmpz_mat_randajtai(fmpz_mat_t mat, flint_rand_t state, double alpha) + + Sets a square matrix \code{mat} to a random \emph{ajtai} matrix. + The diagonal entries $(i, i)$ are set to a random entry in the range + $[1, 2^{b-1}]$ inclusive where $b = \floor{(2 r - i)^\alpha}$ for some + double parameter~$\alpha$. The entries below the diagonal in column~$i$ + are set to a random entry in the range $(-2^b + 1, 2^b - 1)$ whilst the + entries to the right of the diagonal in row~$i$ are set to zero. + +int fmpz_mat_randpermdiag(fmpz_mat_t mat, flint_rand_t state, + const fmpz * diag, slong n) + + Sets \code{mat} to a random permutation of the rows and columns of a + given diagonal matrix. The diagonal matrix is specified in the form of + an array of the $n$ initial entries on the main diagonal. + + The return value is $0$ or $1$ depending on whether the permutation is + even or odd. + +void fmpz_mat_randrank(fmpz_mat_t mat, flint_rand_t state, slong rank, + mp_bitcnt_t bits) + + Sets \code{mat} to a random sparse matrix with the given rank, + having exactly as many non-zero elements as the rank, with the + nonzero elements being random integers of the given bit size. + + The matrix can be transformed into a dense matrix with unchanged + rank by subsequently calling \code{fmpz_mat_randops()}. + +void fmpz_mat_randdet(fmpz_mat_t mat, flint_rand_t state, const fmpz_t det) + + Sets \code{mat} to a random sparse matrix with minimal number of + nonzero entries such that its determinant has the given value. + + Note that the matrix will be zero if \code{det} is zero. + In order to generate a non-zero singular matrix, the function + \code{fmpz_mat_randrank()} can be used. + + The matrix can be transformed into a dense matrix with unchanged + determinant by subsequently calling \code{fmpz_mat_randops()}. + +void fmpz_mat_randops(fmpz_mat_t mat, flint_rand_t state, slong count) + + Randomises \code{mat} by performing elementary row or column operations. + More precisely, at most \code{count} random additions or subtractions of + distinct rows and columns will be performed. This leaves the rank + (and for square matrices, the determinant) unchanged. + + +******************************************************************************* + + Input and output + +******************************************************************************* + +int fmpz_mat_fprint(FILE * file, const fmpz_mat_t mat) + + Prints the given matrix to the stream \code{file}. The format is + the number of rows, a space, the number of columns, two spaces, then + a space separated list of coefficients, one row after the other. + + In case of success, returns a positive value; otherwise, returns + a non-positive value. + +int fmpz_mat_fprint_pretty(FILE * file, const fmpz_mat_t mat) + + Prints the given matrix to the stream \code{file}. The format is an + opening square bracket then on each line a row of the matrix, followed + by a closing square bracket. Each row is written as an opening square + bracket followed by a space separated list of coefficients followed + by a closing square bracket. + + In case of success, returns a positive value; otherwise, returns + a non-positive value. + +int fmpz_mat_print(const fmpz_mat_t mat) + + Prints the given matrix to the stream \code{stdout}. For further + details, see \code{fmpz_mat_fprint()}. + +int fmpz_mat_print_pretty(const fmpz_mat_t mat) + + Prints the given matrix to \code{stdout}. For further details, + see \code{fmpz_mat_fprint_pretty()}. + +int fmpz_mat_fread(FILE* file, fmpz_mat_t mat) + + Reads a matrix from the stream \code{file}, storing the result + in \code{mat}. The expected format is the number of rows, a + space, the number of columns, two spaces, then a space separated + list of coefficients, one row after the other. + + In case of success, returns a positive number. In case of failure, + returns a non-positive value. + +int fmpz_mat_read(fmpz_mat_t mat) + + Reads a matrix from \code{stdin}, storing the result + in \code{mat}. + + In case of success, returns a positive number. In case of failure, + returns a non-positive value. + +******************************************************************************* + + Comparison + +******************************************************************************* + +int fmpz_mat_equal(const fmpz_mat_t mat1, const fmpz_mat_t mat2) + + Returns a non-zero value if \code{mat1} and \code{mat2} have + the same dimensions and entries, and zero otherwise. + +int fmpz_mat_is_zero(const fmpz_mat_t mat) + + Returns a non-zero value if all entries \code{mat} are zero, and + otherwise returns zero. + +int fmpz_mat_is_empty(const fmpz_mat_t mat) + + Returns a non-zero value if the number of rows or the number of + columns in \code{mat} is zero, and otherwise returns + zero. + +int fmpz_mat_is_square(const fmpz_mat_t mat) + + Returns a non-zero value if the number of rows is equal to the + number of columns in \code{mat}, and otherwise returns zero. + +******************************************************************************* + + Transpose + +******************************************************************************* + +void fmpz_mat_transpose(fmpz_mat_t B, const fmpz_mat_t A) + + Sets $B$ to $A^T$, the transpose of $A$. Dimensions must be compatible. + $A$ and $B$ are allowed to be the same object if $A$ is a square matrix. + + +******************************************************************************* + + Modular reduction and reconstruction + +******************************************************************************* + +void fmpz_mat_get_nmod_mat(nmod_mat_t Amod, const fmpz_mat_t A) + + Sets the entries of \code{Amod} to the entries of \code{A} reduced + by the modulus of \code{Amod}. + +void fmpz_mat_set_nmod_mat(fmpz_mat_t A, const nmod_mat_t Amod) + + Sets the entries of \code{Amod} to the residues in \code{Amod}, + normalised to the interval $-m/2 <= r < m/2$ where $m$ is the modulus. + +void fmpz_mat_set_nmod_mat_unsigned(fmpz_mat_t A, const nmod_mat_t Amod) + + Sets the entries of \code{Amod} to the residues in \code{Amod}, + normalised to the interval $0 <= r < m$ where $m$ is the modulus. + +void fmpz_mat_CRT_ui(fmpz_mat_t res, const fmpz_mat_t mat1, + const fmpz_t m1, const nmod_mat_t mat2, int sign) + + Given \code{mat1} with entries modulo \code{m} and \code{mat2} + with modulus $n$, sets \code{res} to the CRT reconstruction modulo $mn$ + with entries satisfying $-mn/2 <= c < mn/2$ (if sign = 1) + or $0 <= c < mn$ (if sign = 0). + +void fmpz_mat_multi_mod_ui_precomp(nmod_mat_t * residues, slong nres, + const fmpz_mat_t mat, fmpz_comb_t comb, fmpz_comb_temp_t temp) + + Sets each of the \code{nres} matrices in \code{residues} to \code{mat} + reduced modulo the modulus of the respective matrix, given + precomputed \code{comb} and \code{comb_temp} structures. + +void fmpz_mat_multi_mod_ui(nmod_mat_t * residues, slong nres, + const fmpz_mat_t mat) + + Sets each of the \code{nres} matrices in \code{residues} to \code{mat} + reduced modulo the modulus of the respective matrix. + + This function is provided for convenience purposes. + For reducing or reconstructing multiple integer matrices over the same + set of moduli, it is faster to use\\ \code{fmpz_mat_multi_mod_precomp}. + +void fmpz_mat_multi_CRT_ui_precomp(fmpz_mat_t mat, nmod_mat_t * const residues, + slong nres, fmpz_comb_t comb, fmpz_comb_temp_t temp, int sign) + + Reconstructs \code{mat} from its images modulo the \code{nres} matrices + in \code{residues}, given precomputed \code{comb} and \code{comb_temp} + structures. + +void fmpz_mat_multi_CRT_ui(fmpz_mat_t mat, nmod_mat_t * const residues, + slong nres, int sign) + + Reconstructs \code{mat} from its images modulo the \code{nres} matrices + in \code{residues}. + + This function is provided for convenience purposes. + For reducing or reconstructing multiple integer matrices over the same + set of moduli, it is faster to use\\ \code{fmpz_mat_multi_CRT_ui_precomp}. + +******************************************************************************* + + Addition and subtraction + +******************************************************************************* + +void fmpz_mat_add(fmpz_mat_t C, const fmpz_mat_t A, const fmpz_mat_t B) + + Sets \code{C} to the elementwise sum $A + B$. All inputs must + be of the same size. Aliasing is allowed. + +void fmpz_mat_sub(fmpz_mat_t C, const fmpz_mat_t A, const fmpz_mat_t B) + + Sets \code{C} to the elementwise difference $A - B$. All inputs must + be of the same size. Aliasing is allowed. + +void fmpz_mat_neg(fmpz_mat_t B, const fmpz_mat_t A) + + Sets \code{B} to the elementwise negation of \code{A}. Both inputs + must be of the same size. Aliasing is allowed. + +******************************************************************************* + + Matrix-scalar arithmetic + +******************************************************************************* + +void fmpz_mat_scalar_mul_si(fmpz_mat_t B, const fmpz_mat_t A, slong c) + +void fmpz_mat_scalar_mul_ui(fmpz_mat_t B, const fmpz_mat_t A, ulong c) + +void fmpz_mat_scalar_mul_fmpz(fmpz_mat_t B, const fmpz_mat_t A, const fmpz_t c) + + Set \code{A = B*c} where \code{B} is an \code{fmpz_mat_t} and \code{c} + is a scalar respectively of type \code{slong}, \code{ulong}, + or \code{fmpz_t}. The dimensions of \code{A} and \code{B} must + be compatible. + +void fmpz_mat_scalar_addmul_si(fmpz_mat_t B, const fmpz_mat_t A, slong c) + +void fmpz_mat_scalar_addmul_ui(fmpz_mat_t B, const fmpz_mat_t A, ulong c) + +void fmpz_mat_scalar_addmul_fmpz(fmpz_mat_t B, const fmpz_mat_t A, + const fmpz_t c) + + Set \code{A = A + B*c} where \code{B} is an \code{fmpz_mat_t} and \code{c} + is a scalar respectively of type \code{slong}, \code{ulong}, + or \code{fmpz_t}. The dimensions of \code{A} and \code{B} must + be compatible. + +void fmpz_mat_scalar_submul_si(fmpz_mat_t B, const fmpz_mat_t A, slong c) + +void fmpz_mat_scalar_submul_ui(fmpz_mat_t B, const fmpz_mat_t A, ulong c) + +void fmpz_mat_scalar_submul_fmpz(fmpz_mat_t B, const fmpz_mat_t A, + const fmpz_t c) + + Set \code{A = A - B*c} where \code{B} is an \code{fmpz_mat_t} and \code{c} + is a scalar respectively of type \code{slong}, \code{ulong}, + or \code{fmpz_t}. The dimensions of \code{A} and \code{B} must + be compatible. + +void fmpz_mat_scalar_addmul_nmod_mat_ui(fmpz_mat_t B, const nmod_mat_t A, + ulong c) +void fmpz_mat_scalar_addmul_nmod_mat_fmpz(fmpz_mat_t B, const nmod_mat_t A, + const fmpz_t c) + + Set \code{A = A + B*c} where \code{B} is an \code{nmod_mat_t} and \code{c} + is a scalar respectively of type \code{ulong} or \code{fmpz_t}. + The dimensions of \code{A} and \code{B} must be compatible. + +void fmpz_mat_scalar_divexact_si(fmpz_mat_t B, const fmpz_mat_t A, slong c) + +void fmpz_mat_scalar_divexact_ui(fmpz_mat_t B, const fmpz_mat_t A, ulong c) + +void fmpz_mat_scalar_divexact_fmpz(fmpz_mat_t B, const fmpz_mat_t A, + const fmpz_t c) + + Set \code{A = B / c}, where \code{B} is an \code{fmpz_mat_t} and \code{c} + is a scalar respectively of type \code{slong}, \code{ulong}, + or \code{fmpz_t}, which is assumed to divide all elements of + \code{B} exactly. + + +******************************************************************************* + + Matrix multiplication + +******************************************************************************* + +void fmpz_mat_mul(fmpz_mat_t C, const fmpz_mat_t A, const fmpz_mat_t B) + + Sets \code{C} to the matrix product $C = A B$. The matrices must have + compatible dimensions for matrix multiplication. Aliasing + is allowed. + + This function automatically switches between classical and + multimodular multiplication, based on a heuristic comparison of + the dimensions and entry sizes. + +void fmpz_mat_mul_classical(fmpz_mat_t C, + const fmpz_mat_t A, const fmpz_mat_t B) + + Sets \code{C} to the matrix product $C = A B$ computed using + classical matrix algorithm. + + The matrices must have compatible dimensions for matrix multiplication. + No aliasing is allowed. + +void _fmpz_mat_mul_multi_mod(fmpz_mat_t C, + const fmpz_mat_t A, const fmpz_mat_t B, mp_bitcnt_t bits) + +void fmpz_mat_mul_multi_mod(fmpz_mat_t C, + const fmpz_mat_t A, const fmpz_mat_t B) + + Sets \code{C} to the matrix product $C = AB$ computed using a multimodular + algorithm. $C$ is computed modulo several small prime numbers + and reconstructed using the Chinese Remainder Theorem. This generally + becomes more efficient than classical multiplication for large matrices. + + The \code{bits} parameter is a bound for the bit size of largest + element of $C$, or twice the absolute value of the largest element + if any elements of $C$ are negative. The function + \code{fmpz_mat_mul_multi_mod} calculates a rigorous bound automatically. + If the default bound is too pessimistic, \code{_fmpz_mat_mul_multi_mod} + can be used with a custom bound. + + The matrices must have compatible dimensions for matrix multiplication. + No aliasing is allowed. + +void fmpz_mat_sqr(fmpz_mat_t B, const fmpz_mat_t A) + + Sets \code{B} to the square of the matrix \code{A}, which must be + a square matrix. Aliasing is allowed. + +void fmpz_mat_pow(fmpz_mat_t B, const fmpz_mat_t A, ulong e) + + Sets \code{B} to the matrix \code{A} raised to the power \code{e}, + where \code{A} must be a square matrix. Aliasing is allowed. + + +******************************************************************************* + + Inverse + +******************************************************************************* + +int fmpz_mat_inv(fmpz_mat_t Ainv, fmpz_t den, const fmpz_mat_t A) + + Sets (\code{Ainv}, \code{den}) to the inverse matrix of \code{A}. + Returns 1 if \code{A} is nonsingular and 0 if \code{A} is singular. + Aliasing of \code{Ainv} and \code{A} is allowed. + + The denominator is not guaranteed to be minimal, but is guaranteed + to be a divisor of the determinant of \code{A}. + + This function uses a direct formula for matrices of size two or less, + and otherwise solves for the identity matrix using + fraction-free LU decomposition. + + +******************************************************************************* + + Trace + +******************************************************************************* + +void fmpz_mat_trace(fmpz_t trace, const fmpz_mat_t mat) + + Computes the trace of the matrix, i.e. the sum of the entries on + the main diagonal. The matrix is required to be square. + + +******************************************************************************* + + Determinant + +******************************************************************************* + +void fmpz_mat_det(fmpz_t det, const fmpz_mat_t A) + + Sets \code{det} to the determinant of the square matrix $A$. + The matrix of dimension $0 \times 0$ is defined to have determinant 1. + + This function automatically chooses between \code{fmpz_mat_det_cofactor},\\ + \code{fmpz_mat_det_bareiss}, \code{fmpz_mat_det_modular} and\\ + \code{fmpz_mat_det_modular_accelerated} + (with \code{proved} = 1), depending on the size of the matrix + and its entries. + +void fmpz_mat_det_cofactor(fmpz_t det, const fmpz_mat_t A) + + Sets \code{det} to the determinant of the square matrix $A$ + computed using direct cofactor expansion. This function only + supports matrices up to size $4 \times 4$. + +void fmpz_mat_det_bareiss(fmpz_t det, const fmpz_mat_t A) + + Sets \code{det} to the determinant of the square matrix $A$ + computed using the Bareiss algorithm. A copy of the input matrix is + row reduced using fraction-free Gaussian elimination, and the + determinant is read off from the last element on the main + diagonal. + +void fmpz_mat_det_modular(fmpz_t det, const fmpz_mat_t A, int proved) + + Sets \code{det} to the determinant of the square matrix $A$ + (if \code{proved} = 1), or a probabilistic value for the + determinant (\code{proved} = 0), computed using a multimodular + algorithm. + + The determinant is computed modulo several small primes and + reconstructed using the Chinese Remainder Theorem. + With \code{proved} = 1, sufficiently many primes are chosen + to satisfy the bound computed by \code{fmpz_mat_det_bound}. + With \code{proved} = 0, the determinant is considered determined + if it remains unchanged modulo several consecutive primes + (currently if their product exceeds $2^{100}$). + +void fmpz_mat_det_modular_accelerated(fmpz_t det, + const fmpz_mat_t A, int proved) + + Sets \code{det} to the determinant of the square matrix $A$ + (if \code{proved} = 1), or a probabilistic value for the + determinant (\code{proved} = 0), computed using a multimodular + algorithm. + + This function uses the same basic algorithm as \code{fmpz_mat_det_modular}, + but instead of computing $\det(A)$ directly, it generates a divisor $d$ + of $\det(A)$ and then computes $x = \det(A) / d$ modulo several + small primes not dividing $d$. This typically accelerates the + computation by requiring fewer primes for large matrices, since $d$ + with high probability will be nearly as large as the determinant. + This trick is described in \citep{AbbottBronsteinMulders1999}. + +void fmpz_mat_det_modular_given_divisor(fmpz_t det, const fmpz_mat_t A, + const fmpz_t d, int proved) + + Given a positive divisor $d$ of $\det(A)$, sets \code{det} to the + determinant of the square matrix $A$ (if \code{proved} = 1), or a + probabilistic value for the determinant (\code{proved} = 0), computed + using a multimodular algorithm. + +void fmpz_mat_det_bound(fmpz_t bound, const fmpz_mat_t A) + + Sets \code{bound} to a nonnegative integer $B$ such that + $|\det(A)| \le B$. Assumes $A$ to be a square matrix. + The bound is computed from the Hadamard inequality + $|\det(A)| \le \prod \|a_i\|_2$ where the product is taken + over the rows $a_i$ of $A$. + +void fmpz_mat_det_divisor(fmpz_t d, const fmpz_mat_t A) + + Sets $d$ to some positive divisor of the determinant of the given + square matrix $A$, if the determinant is nonzero. If $|\det(A)| = 0$, + $d$ will always be set to zero. + + A divisor is obtained by solving $Ax = b$ for an arbitrarily chosen + right-hand side $b$ using Dixon's algorithm and computing the least + common multiple of the denominators in $x$. This yields a divisor $d$ + such that $|\det(A)| / d$ is tiny with very high probability. + + +******************************************************************************* + + Charactersitic polynomial + +******************************************************************************* + +void _fmpz_mat_charpoly(fmpz * cp, const fmpz_mat_t mat) + + Sets \code{(cp, n+1)} to the characteristic polynomial of + an $n \times n$ square matrix. + +void fmpz_mat_charpoly(fmpz_poly_t cp, const fmpz_mat_t mat) + + Computes the characteristic polynomial of length $n + 1$ of + an $n \times n$ square matrix. + +******************************************************************************* + + Rank + +******************************************************************************* + +slong fmpz_mat_rank(const fmpz_mat_t A) + + Returns the rank, that is, the number of linearly independent columns + (equivalently, rows), of $A$. The rank is computed by row reducing + a copy of $A$. + + +******************************************************************************* + + Nonsingular solving + + The following functions allow solving matrix-matrix equations $AX = B$ + where the system matrix $A$ is square and has full rank. The solving + is implicitly done over the field of rational numbers: except + where otherwise noted, an integer matrix $\hat X$ and a separate + denominator $d$ (\code{den}) are computed such that $A(\hat X/d) = b$, + equivalently such that $A\hat X = bd$ holds over the integers. + + No guarantee is made that the numerators and denominator + are reduced to lowest terms, but the denominator is always guaranteed + to be a divisor of the determinant of $A$. If $A$ is singular, + \code{den} will be set to zero and the elements of the solution + vector or matrix will have undefined values. No aliasing is + allowed between arguments. + +******************************************************************************* + +int fmpz_mat_solve(fmpz_mat_t X, fmpz_t den, + const fmpz_mat_t A, const fmpz_mat_t B) + + Solves the equation $AX = B$ for nonsingular $A$. More precisely, computes + (\code{X}, \code{den}) such that $AX = B \times \operatorname{den}$. + Returns 1 if $A$ is nonsingular and 0 if $A$ is singular. + The computed denominator will not generally be minimal. + + This function uses Cramer's rule for small systems and + fraction-free LU decomposition followed by fraction-free forward + and back substitution for larger systems. + + Note that for very large systems, it is faster to compute a modular + solution using \code{fmpz_mat_solve_dixon}. + +int fmpz_mat_solve_fflu(fmpz_mat_t X, fmpz_t den, + const fmpz_mat_t A, const fmpz_mat_t B) + + Solves the equation $AX = B$ for nonsingular $A$. More precisely, computes + (\code{X}, \code{den}) such that $AX = B \times \operatorname{den}$. + Returns 1 if $A$ is nonsingular and 0 if $A$ is singular. + The computed denominator will not generally be minimal. + + Uses fraction-free LU decomposition followed by fraction-free + forward and back substitution. + +void fmpz_mat_solve_fflu_precomp(fmpz_mat_t X, + const slong * perm, + const fmpz_mat_t FFLU, const fmpz_mat_t B) + + Performs fraction-free forward and back substitution given a precomputed + fraction-free LU decomposition and corresponding permutation. + +int fmpz_mat_solve_cramer(fmpz_mat_t X, fmpz_t den, + const fmpz_mat_t A, const fmpz_mat_t B) + + Solves the equation $AX = B$ for nonsingular $A$. More precisely, computes + (\code{X}, \code{den}) such that $AX = B \times \operatorname{den}$. + Returns 1 if $A$ is nonsingular and 0 if $A$ is singular. + + Uses Cramer's rule. Only systems of size up to $3 \times 3$ are allowed. + +void fmpz_mat_solve_bound(fmpz_t N, fmpz_t D, const fmpz_mat_t A, + const fmpz_mat_t B) + + Assuming that $A$ is nonsingular, computes integers $N$ and $D$ + such that the reduced numerators and denominators $n/d$ in + $A^{-1} B$ satisfy the bounds $0 \le |n| \le N$ and $0 \le d \le D$. + +int fmpz_mat_solve_dixon(fmpz_mat_t X, fmpz_t M, const fmpz_mat_t A, + const fmpz_mat_t B) + + Solves $AX = B$ given a nonsingular square matrix $A$ and a matrix $B$ of + compatible dimensions, using a modular algorithm. In particular, + Dixon's p-adic lifting algorithm is used (currently a non-adaptive version). + This is generally the preferred method for large dimensions. + + More precisely, this function computes an integer $M$ and an integer + matrix $X$ such that $AX = B \bmod M$ and such that all the reduced + numerators and denominators of the elements $x = p/q$ in the full + solution satisfy $2|p|q < B$. As such, the explicit rational solution + matrix can be recovered uniquely by passing the output of this + function to \code{fmpq_mat_set_fmpz_mat_mod}. + + A nonzero value is returned if $A$ is nonsingular. If $A$ is singular, + zero is returned and the values of the output variables will be + undefined. + + Aliasing between input and output matrices is allowed. + +******************************************************************************* + + Row reduction + +******************************************************************************* + +slong fmpz_mat_find_pivot_any(const fmpz_mat_t mat, + slong start_row, slong end_row, slong c) + + Attempts to find a pivot entry for row reduction. + Returns a row index $r$ between \code{start_row} (inclusive) and + \code{stop_row} (exclusive) such that column $c$ in \code{mat} has + a nonzero entry on row $r$, or returns -1 if no such entry exists. + + This implementation simply chooses the first nonzero entry from + it encounters. This is likely to be a nearly optimal choice if all + entries in the matrix have roughly the same size, but can lead to + unnecessary coefficient growth if the entries vary in size. + +slong fmpz_mat_fflu(fmpz_mat_t B, fmpz_poly_t den, slong * perm, + const fmpz_mat_t A, int rank_check) + + Uses fraction-free Gaussian elimination to set (\code{B}, \code{den}) to a + fraction-free LU decomposition of \code{A} and returns the + rank of \code{A}. Aliasing of \code{A} and \code{B} is allowed. + + Pivot elements are chosen with \code{fmpz_mat_find_pivot_any}. + If \code{perm} is non-\code{NULL}, the permutation of + rows in the matrix will also be applied to \code{perm}. + + If \code{rank_check} is set, the function aborts and returns 0 if the + matrix is detected not to have full rank without completing the + elimination. + + The denominator \code{den} is set to $\pm \operatorname{det}(S)$ where + $S$ is an appropriate submatrix of $A$ ($S = A$ if $A$ is square) + and the sign is decided by the parity of the permutation. Note that the + determinant is not generally the minimal denominator. + + The fraction-free LU decomposition is defined in \citep{NakTurWil1997}. + +slong fmpz_mat_rref(fmpz_mat_t B, fmpz_t den, const fmpz_mat_t A) + + Sets (\code{B}, \code{den}) to the reduced row echelon form of \code{A} + and returns the rank of \code{A}. Aliasing of \code{A} and \code{B} + is allowed. + + The algorithm proceeds by first computing a row echelon form using + \code{fmpz_mat_fflu}. Letting the upper part of this matrix be + $(U | V) P$ where $U$ is full rank upper triangular and $P$ is a + permutation matrix, we obtain the rref by setting $V$ to $U^{-1} V$ + using back substitution. Scaling each completed row in the back + substitution to the denominator \code{den}, we avoid introducing + new fractions. This strategy is equivalent to the fraction-free + Gauss-Jordan elimination in \citep{NakTurWil1997}, but faster since + only the part $V$ corresponding to the null space has to be updated. + + The denominator \code{den} is set to $\pm \operatorname{det}(S)$ where + $S$ is an appropriate submatrix of $A$ ($S = A$ if $A$ is square). + Note that the determinant is not generally the minimal denominator. + + +******************************************************************************* + + Modular gaussian elimination + +******************************************************************************* + +slong fmpz_mat_rref_mod(slong * perm, fmpz_mat_t A, const fmpz_t p) + + Uses fraction-free Gauss-Jordan elimination to set \code{A} + to its reduced row echelon form and returns the rank of \code{A}. + All computations are done modulo p. + + Pivot elements are chosen with \code{fmpz_mat_find_pivot_any}. + If \code{perm} is non-\code{NULL}, the permutation of + rows in the matrix will also be applied to \code{perm}. + +******************************************************************************* + + Nullspace + +******************************************************************************* + +slong fmpz_mat_nullspace(fmpz_mat_t B, const fmpz_mat_t A) + + Computes a basis for the right rational nullspace of $A$ and returns + the dimension of the nullspace (or nullity). $B$ is set to a matrix with + linearly independent columns and maximal rank such that $AB = 0$ + (i.e. $Ab = 0$ for each column $b$ in $B$), and the rank of $B$ is + returned. + + In general, the entries in $B$ will not be minimal: in particular, + the pivot entries in $B$ will generally differ from unity. + $B$ must be allocated with sufficient space to represent the result + (at most $n \times n$ where $n$ is the number of column of $A$). + + +******************************************************************************* + + Echelon form + +******************************************************************************* + +slong fmpz_mat_rref_fraction_free(slong * perm, fmpz_mat_t B, fmpz_t den, + const fmpz_mat_t A) + + Computes an integer matrix \code{B} and an integer \code{den} such that + \code{B / den} is the unique row reduced echelon form (RREF) of \code{A} + and returns the rank, i.e. the number of nonzero rows in \code{B}. + + Aliasing of \code{B} and \code{A} is allowed, with an in-place + computation being more efficient. The size of \code{B} must be + the same as that of \code{A}. + + The permutation order will be written to \code{perm} unless this + argument is \code{NULL}. That is, row \code{i} of the output matrix will + correspond to row \code{perm[i]} of the input matrix. + + The denominator will always be a divisor of the determinant of (some + submatrix of) $A$, but is not guaranteed to be minimal or canonical in + any other sense. + diff --git a/external/flint-2.4.3/fmpz_mat/equal.c b/external/flint-2.4.3/fmpz_mat/equal.c new file mode 100644 index 0000000..897681d --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/equal.c @@ -0,0 +1,49 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +int fmpz_mat_equal(const fmpz_mat_t mat1, const fmpz_mat_t mat2) +{ + slong j; + + if (mat1->r != mat2->r || mat1->c != mat2->c) + { + return 0; + } + + if (mat1->r == 0 || mat1->c == 0) + return 1; + + for (j = 0; j < mat1->r; j++) + { + if (!_fmpz_vec_equal(mat1->rows[j], mat2->rows[j], mat1->c)) + { + return 0; + } + } + + return 1; +} diff --git a/external/flint-2.4.3/fmpz_mat/fflu.c b/external/flint-2.4.3/fmpz_mat/fflu.c new file mode 100644 index 0000000..ad2e9e2 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/fflu.c @@ -0,0 +1,92 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" +#include "perm.h" + +#define E(j,k) fmpz_mat_entry(B,j,k) + +slong +fmpz_mat_fflu(fmpz_mat_t B, fmpz_t den, slong * perm, + const fmpz_mat_t A, int rank_check) +{ + fmpz_t t; + slong m, n, j, k, rank, r, pivot_row, pivot_col; + + if (fmpz_mat_is_empty(A)) + { + fmpz_one(den); + return 0; + } + + fmpz_mat_set(B, A); + m = B->r; + n = B->c; + rank = pivot_row = pivot_col = 0; + + fmpz_init(t); + + while (pivot_row < m && pivot_col < n) + { + r = fmpz_mat_find_pivot_any(B, pivot_row, m, pivot_col); + + if (r == -1) + { + if (rank_check) + { + fmpz_zero(den); + rank = 0; + break; + } + pivot_col++; + continue; + } + else if (r != pivot_row) + fmpz_mat_swap_rows(B, perm, pivot_row, r); + + rank++; + + for (j = pivot_row + 1; j < m; j++) + { + for (k = pivot_col + 1; k < n; k++) + { + /* todo: use submul */ + fmpz_mul(E(j, k), E(j, k), E(pivot_row, pivot_col)); + fmpz_mul(t, E(j, pivot_col), E(pivot_row, k)); + fmpz_sub(E(j, k), E(j, k), t); + + if (pivot_row > 0) + fmpz_divexact(E(j, k), E(j, k), den); + } + } + + fmpz_set(den, E(pivot_row, pivot_col)); + pivot_row++; + pivot_col++; + } + + fmpz_clear(t); + return rank; +} diff --git a/external/flint-2.4.3/fmpz_mat/find_pivot_any.c b/external/flint-2.4.3/fmpz_mat/find_pivot_any.c new file mode 100644 index 0000000..194a9d1 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/find_pivot_any.c @@ -0,0 +1,41 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +slong +fmpz_mat_find_pivot_any(const fmpz_mat_t mat, + slong start_row, slong end_row, slong c) +{ + slong r; + + for (r = start_row; r < end_row; r++) + { + if (!fmpz_is_zero(fmpz_mat_entry(mat, r, c))) + return r; + } + + return -1; +} diff --git a/external/flint-2.4.3/fmpz_mat/fprint.c b/external/flint-2.4.3/fmpz_mat/fprint.c new file mode 100644 index 0000000..77f977e --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/fprint.c @@ -0,0 +1,111 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include "fmpz_mat.h" + +/* + The macros xxx_putc, xxx_flint_printf, and xxx_fmpz_print are provided + as wrappers to handle return values and error conditions. While + this is not exactly pretty, it improves the readability of the + functions fmpz_mat_fprint and fmpz_mat_fprint_pretty. Moreover, + if we later want to improve the handling of returns values, e.g. + to return the number of characters printed, this will be easier. + + The macros are undef'd at the end of the file. + */ + +#define xxx_putc(c) \ +do { \ + z = fputc((c), file); \ + if (z <= 0) \ + return z; \ +} while (0) + +#define xxx_flint_printf() \ +do { \ + z = flint_fprintf(file, "%li %li ", r, c); \ + if (z <= 0) \ + return z; \ +} while (0) + +#define xxx_fmpz_print(f) \ +do { \ + z = fmpz_fprint(file, (f)); \ + if (z <= 0) \ + return z; \ +} while(0) + +int fmpz_mat_fprint(FILE * file, const fmpz_mat_t mat) +{ + int z; + slong i, j; + slong r = mat->r; + slong c = mat->c; + + xxx_flint_printf(); + for (i = 0; (i < r); i++) + { + for (j = 0; j < c; j++) + { + xxx_fmpz_print(mat->rows[i] + j); + if (j != c - 1) + xxx_putc(' '); + } + if (i != r - 1) + xxx_putc(' '); + } + + return z; +} + +int fmpz_mat_fprint_pretty(FILE * file, const fmpz_mat_t mat) +{ + int z; + slong i, j; + slong r = mat->r; + slong c = mat->c; + + xxx_putc('['); + for (i = 0; i < r; i++) + { + xxx_putc('['); + for (j = 0; j < c; j++) + { + xxx_fmpz_print(mat->rows[i] + j); + if (j != c - 1) + xxx_putc(' '); + } + xxx_putc(']'); + xxx_putc('\n'); + } + xxx_putc(']'); + + return z; +} + +#undef xxx_putc +#undef xxx_flint_printf +#undef xxx_fmpz_print + diff --git a/external/flint-2.4.3/fmpz_mat/fread.c b/external/flint-2.4.3/fmpz_mat/fread.c new file mode 100644 index 0000000..2c4041d --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/fread.c @@ -0,0 +1,95 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Andy Novocin + +******************************************************************************/ + +#include "fmpz_mat.h" + +int +fmpz_mat_fread(FILE* file, fmpz_mat_t mat) +{ + slong r, c, i, j; + int byte_count; + mpz_t t; + + /* first number in file should be row dimension */ + mpz_init(t); + byte_count = mpz_inp_str(t, file, 10); + if (byte_count == 0) + { + mpz_clear(t); + return 0; + } + + if (!mpz_fits_slong_p(t)) + { + flint_printf("Exception (fmpz_mat_fread). " + "Number of rows does not fit into a slong.\n"); + abort(); + } + r = flint_mpz_get_si(t); + + /* second number in file should be column dimension */ + byte_count = mpz_inp_str(t, file, 10); + if (byte_count == 0) + { + mpz_clear(t); + return 0; + } + + if (!mpz_fits_slong_p(t)) + { + flint_printf("Exception (fmpz_mat_fread). " + "Number of columns does not fit into a slong.\n"); + abort(); + } + c = flint_mpz_get_si(t); + mpz_clear(t); + + /* if the input is 0 by 0 then set the dimensions to r and c */ + if (mat->r == 0 && mat->c == 0) + { + fmpz_mat_clear(mat); + fmpz_mat_init(mat,r,c); + } + else if (mat->r == 0 && mat->c == 0) + { + flint_printf("Exception (fmpz_mat_fread). \n" + "Dimensions are non-zero and do not match input dimensions.\n"); + abort(); + } + + for (i = 0; i < r; i++) + { + for (j = 0; j < c; j++) + { + if (!fmpz_fread(file, fmpz_mat_entry(mat, i, j))) + return 0; + } + } + + /* a return value of 0 means a problem with + the file stream a value of 1 means success*/ + return 1; +} + diff --git a/external/flint-2.4.3/fmpz_mat/get_nmod_mat.c b/external/flint-2.4.3/fmpz_mat/get_nmod_mat.c new file mode 100644 index 0000000..7a20c89 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/get_nmod_mat.c @@ -0,0 +1,37 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +void +fmpz_mat_get_nmod_mat(nmod_mat_t Amod, const fmpz_mat_t A) +{ + slong i, j; + mp_limb_t m = Amod->mod.n; + + for (i = 0; i < A->r; i++) + for (j = 0; j < A->c; j++) + Amod->rows[i][j] = fmpz_fdiv_ui(A->rows[i]+j, m); +} diff --git a/external/flint-2.4.3/fmpz_mat/init.c b/external/flint-2.4.3/fmpz_mat/init.c new file mode 100644 index 0000000..0222475 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/init.c @@ -0,0 +1,45 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include "fmpz_mat.h" + +void +fmpz_mat_init(fmpz_mat_t mat, slong rows, slong cols) +{ + if ((rows) && (cols)) /* Allocate space for r*c small entries */ + { + slong i; + mat->entries = (fmpz *) flint_calloc(rows * cols, sizeof(fmpz)); + mat->rows = (fmpz **) flint_malloc(rows * sizeof(fmpz *)); /* Initialise rows */ + + for (i = 0; i < rows; i++) + mat->rows[i] = mat->entries + i * cols; + } + else + mat->entries = NULL; + + mat->r = rows; + mat->c = cols; +} diff --git a/external/flint-2.4.3/fmpz_mat/init_set.c b/external/flint-2.4.3/fmpz_mat/init_set.c new file mode 100644 index 0000000..986d3c9 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/init_set.c @@ -0,0 +1,34 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +void +fmpz_mat_init_set(fmpz_mat_t mat, const fmpz_mat_t src) +{ + fmpz_mat_init(mat, src->r, src->c); + fmpz_mat_set(mat, src); +} diff --git a/external/flint-2.4.3/fmpz_mat/inv.c b/external/flint-2.4.3/fmpz_mat/inv.c new file mode 100644 index 0000000..bc38833 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/inv.c @@ -0,0 +1,79 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010-2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +void +_fmpz_mat_inv_2x2(fmpz ** b, fmpz_t den, fmpz ** const a) +{ + fmpz_t tmp; + + _fmpz_mat_det_cofactor_2x2(den, a); + + fmpz_neg(&b[0][1], &a[0][1]); + fmpz_neg(&b[1][0], &a[1][0]); + + fmpz_init(tmp); + fmpz_set(tmp, &a[0][0]); + fmpz_set(&b[0][0], &a[1][1]); + fmpz_set(&b[1][1], tmp); + fmpz_clear(tmp); +} + +int +fmpz_mat_inv(fmpz_mat_t B, fmpz_t den, const fmpz_mat_t A) +{ + slong dim = A->r; + + if (dim == 0) + { + fmpz_one(den); + return 1; + } + else if (dim == 1) + { + fmpz_set(den, A->entries); + fmpz_one(B->entries); + return !fmpz_is_zero(den); + } + else if (dim == 2) + { + _fmpz_mat_inv_2x2(B->rows, den, A->rows); + return !fmpz_is_zero(den); + } + else + { + fmpz_mat_t I; + slong i; + int success; + + fmpz_mat_init(I, dim, dim); + for (i = 0; i < dim; i++) + fmpz_one(fmpz_mat_entry(I, i, i)); + success = fmpz_mat_solve_fflu(B, den, A, I); + fmpz_mat_clear(I); + return success; + } +} diff --git a/external/flint-2.4.3/fmpz_mat/is_zero.c b/external/flint-2.4.3/fmpz_mat/is_zero.c new file mode 100644 index 0000000..b7e90be --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/is_zero.c @@ -0,0 +1,43 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +int +fmpz_mat_is_zero(const fmpz_mat_t mat) +{ + slong j; + + if (mat->r == 0 || mat->c == 0) + return 1; + + for (j = 0; j < mat->r; j++) + { + if (!_fmpz_vec_is_zero(mat->rows[j], mat->c)) + return 0; + } + + return 1; +} diff --git a/external/flint-2.4.3/fmpz_mat/max_bits.c b/external/flint-2.4.3/fmpz_mat/max_bits.c new file mode 100644 index 0000000..840d241 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/max_bits.c @@ -0,0 +1,52 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +slong +fmpz_mat_max_bits(const fmpz_mat_t mat) +{ + slong i; + slong bits, row_bits, sign; + + sign = 1; + bits = 0; + + if (mat->r == 0 || mat->c == 0) + return 0; + + for (i = 0; i < mat->r; i++) + { + row_bits = _fmpz_vec_max_bits(mat->rows[i], mat->c); + if (row_bits < 0) + { + row_bits = -row_bits; + sign = -1; + } + bits = FLINT_MAX(bits, row_bits); + } + + return bits * sign; +} diff --git a/external/flint-2.4.3/fmpz_mat/mul.c b/external/flint-2.4.3/fmpz_mat/mul.c new file mode 100644 index 0000000..2417047 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/mul.c @@ -0,0 +1,78 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010,2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +void +fmpz_mat_mul(fmpz_mat_t C, const fmpz_mat_t A, const fmpz_mat_t B) +{ + slong dim, m, n, k; + + m = A->r; + n = A->c; + k = B->c; + + if (C == A || C == B) + { + fmpz_mat_t t; + fmpz_mat_init(t, m, k); + fmpz_mat_mul(t, A, B); + fmpz_mat_swap(C, t); + fmpz_mat_clear(t); + return; + } + + dim = FLINT_MIN(FLINT_MIN(m, n), k); + + if (dim < 12) + { + /* The inline version only benefits from large n */ + if (n <= 2) + fmpz_mat_mul_classical(C, A, B); + else + fmpz_mat_mul_classical_inline(C, A, B); + } + else + { + slong ab, bb, bits; + + ab = fmpz_mat_max_bits(A); + bb = fmpz_mat_max_bits(B); + + ab = FLINT_ABS(ab); + bb = FLINT_ABS(bb); + + bits = ab + bb + FLINT_BIT_COUNT(n) + 1; + + if (5*(ab + bb) > dim * dim || (bits > FLINT_BITS - 3 && dim < 60)) + { + fmpz_mat_mul_classical_inline(C, A, B); + } + else + { + _fmpz_mat_mul_multi_mod(C, A, B, bits); + } + } +} diff --git a/external/flint-2.4.3/fmpz_mat/mul_classical.c b/external/flint-2.4.3/fmpz_mat/mul_classical.c new file mode 100644 index 0000000..bf8da6f --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/mul_classical.c @@ -0,0 +1,60 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010,2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +void +fmpz_mat_mul_classical(fmpz_mat_t C, const fmpz_mat_t A, const fmpz_mat_t B) +{ + slong ar, bc, br; + slong i, j, k; + + ar = A->r; + br = B->r; + bc = B->c; + + if (br == 0) + { + fmpz_mat_zero(C); + return; + } + + for (i = 0; i < ar; i++) + { + for (j = 0; j < bc; j++) + { + fmpz_mul(fmpz_mat_entry(C, i, j), + fmpz_mat_entry(A, i, 0), + fmpz_mat_entry(B, 0, j)); + + for (k = 1; k < br; k++) + { + fmpz_addmul(fmpz_mat_entry(C, i, j), + fmpz_mat_entry(A, i, k), + fmpz_mat_entry(B, k, j)); + } + } + } +} diff --git a/external/flint-2.4.3/fmpz_mat/mul_classical_inline.c b/external/flint-2.4.3/fmpz_mat/mul_classical_inline.c new file mode 100644 index 0000000..feee1df --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/mul_classical_inline.c @@ -0,0 +1,131 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" +#include "longlong.h" + +void +fmpz_mat_mul_classical_inline(fmpz_mat_t C, const fmpz_mat_t A, + const fmpz_mat_t B) +{ + slong ar, bc, br; + slong i, j, k; + + fmpz a, b; + mpz_t t; + + mp_limb_t au, bu; + mp_limb_t pos[3]; + mp_limb_t neg[3]; + + ar = A->r; + br = B->r; + bc = B->c; + + mpz_init(t); + + for (i = 0; i < ar; i++) + { + for (j = 0; j < bc; j++) + { + flint_mpz_set_ui(t, UWORD(0)); + + pos[2] = pos[1] = pos[0] = neg[2] = neg[1] = neg[0] = UWORD(0); + + for (k = 0; k < br; k++) + { + a = A->rows[i][k]; + b = B->rows[k][j]; + + if (a == 0 || b == 0) + continue; + + if (!COEFF_IS_MPZ(a)) /* a is small */ + { + if (!COEFF_IS_MPZ(b)) /* both are small */ + { + au = FLINT_ABS(a); + bu = FLINT_ABS(b); + + umul_ppmm(au, bu, au, bu); + + if ((a ^ b) >= WORD(0)) + add_sssaaaaaa(pos[2], pos[1], pos[0], + pos[2], pos[1], pos[0], 0, au, bu); + else + add_sssaaaaaa(neg[2], neg[1], neg[0], + neg[2], neg[1], neg[0], 0, au, bu); + } + else + { + if (a >= 0) + flint_mpz_addmul_ui(t, COEFF_TO_PTR(b), a); + else + flint_mpz_submul_ui(t, COEFF_TO_PTR(b), -a); + } + } + else if (!COEFF_IS_MPZ(b)) /* b is small */ + { + if (b >= 0) + flint_mpz_addmul_ui(t, COEFF_TO_PTR(a), b); + else + flint_mpz_submul_ui(t, COEFF_TO_PTR(a), -b); + } + else + { + mpz_addmul(t, COEFF_TO_PTR(a), COEFF_TO_PTR(b)); + } + } + + if (mpz_sgn(t) != 0 || pos[2] || neg[2] || pos[1] || neg[1]) + { + __mpz_struct r; + + r._mp_size = pos[2] ? 3 : (pos[1] ? 2 : pos[0] != 0); + r._mp_alloc = r._mp_size; + r._mp_d = pos; + + mpz_add(t, t, &r); + + r._mp_size = neg[2] ? 3 : (neg[1] ? 2 : neg[0] != 0); + r._mp_alloc = r._mp_size; + r._mp_d = neg; + + mpz_sub(t, t, &r); + + fmpz_set_mpz(fmpz_mat_entry(C, i, j), t); + } + else + { + if (neg[0] > pos[0]) + fmpz_neg_ui(fmpz_mat_entry(C, i, j), neg[0] - pos[0]); + else + fmpz_set_ui(fmpz_mat_entry(C, i, j), pos[0] - neg[0]); + } + } + } + + mpz_clear(t); +} diff --git a/external/flint-2.4.3/fmpz_mat/mul_multi_mod.c b/external/flint-2.4.3/fmpz_mat/mul_multi_mod.c new file mode 100644 index 0000000..8903687 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/mul_multi_mod.c @@ -0,0 +1,140 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +void +_fmpz_mat_mul_multi_mod(fmpz_mat_t C, const fmpz_mat_t A, const fmpz_mat_t B, + mp_bitcnt_t bits) +{ + slong i, j; + + fmpz_comb_t comb; + fmpz_comb_temp_t comb_temp; + + slong num_primes; + mp_bitcnt_t primes_bits; + mp_limb_t * primes; + mp_limb_t * residues; + + nmod_mat_t * mod_C; + nmod_mat_t * mod_A; + nmod_mat_t * mod_B; + + primes_bits = NMOD_MAT_OPTIMAL_MODULUS_BITS; + + if (bits < primes_bits) + { + primes_bits = bits; + num_primes = 1; + } + else + { + /* Round up in the division */ + num_primes = (bits + primes_bits - 1) / primes_bits; + } + + /* Initialize */ + primes = flint_malloc(sizeof(mp_limb_t) * num_primes); + primes[0] = n_nextprime(UWORD(1) << primes_bits, 0); + for (i = 1; i < num_primes; i++) + primes[i] = n_nextprime(primes[i-1], 0); + + residues = flint_malloc(sizeof(mp_limb_t) * num_primes); + + mod_A = flint_malloc(sizeof(nmod_mat_t) * num_primes); + mod_B = flint_malloc(sizeof(nmod_mat_t) * num_primes); + mod_C = flint_malloc(sizeof(nmod_mat_t) * num_primes); + for (i = 0; i < num_primes; i++) + { + nmod_mat_init(mod_A[i], A->r, A->c, primes[i]); + nmod_mat_init(mod_B[i], B->r, B->c, primes[i]); + nmod_mat_init(mod_C[i], C->r, C->c, primes[i]); + } + + fmpz_comb_init(comb, primes, num_primes); + fmpz_comb_temp_init(comb_temp, comb); + + /* Calculate residues of A */ + for (i = 0; i < A->r * A->c; i++) + { + fmpz_multi_mod_ui(residues, &A->entries[i], comb, comb_temp); + for (j = 0; j < num_primes; j++) + mod_A[j]->entries[i] = residues[j]; + } + + /* Calculate residues of B */ + for (i = 0; i < B->r * B->c; i++) + { + fmpz_multi_mod_ui(residues, &B->entries[i], comb, comb_temp); + for (j = 0; j < num_primes; j++) + mod_B[j]->entries[i] = residues[j]; + } + + /* Multiply */ + for (i = 0; i < num_primes; i++) + { + nmod_mat_mul(mod_C[i], mod_A[i], mod_B[i]); + } + + /* Chinese remaindering */ + for (i = 0; i < C->r * C->c; i++) + { + for (j = 0; j < num_primes; j++) + residues[j] = mod_C[j]->entries[i]; + fmpz_multi_CRT_ui(&C->entries[i], residues, comb, comb_temp, 1); + } + + /* Cleanup */ + for (i = 0; i < num_primes; i++) + { + nmod_mat_clear(mod_A[i]); + nmod_mat_clear(mod_B[i]); + nmod_mat_clear(mod_C[i]); + } + + flint_free(mod_A); + flint_free(mod_B); + flint_free(mod_C); + + fmpz_comb_temp_clear(comb_temp); + fmpz_comb_clear(comb); + + flint_free(residues); + flint_free(primes); +} + +void +fmpz_mat_mul_multi_mod(fmpz_mat_t C, const fmpz_mat_t A, const fmpz_mat_t B) +{ + slong A_bits; + slong B_bits; + + A_bits = fmpz_mat_max_bits(A); + B_bits = fmpz_mat_max_bits(B); + + _fmpz_mat_mul_multi_mod(C, A, B, FLINT_ABS(A_bits) + FLINT_ABS(B_bits) \ + + FLINT_BIT_COUNT(A->c) + 1); +} diff --git a/external/flint-2.4.3/fmpz_mat/multi_CRT_ui.c b/external/flint-2.4.3/fmpz_mat/multi_CRT_ui.c new file mode 100644 index 0000000..88a409d --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/multi_CRT_ui.c @@ -0,0 +1,72 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +void +fmpz_mat_multi_CRT_ui_precomp(fmpz_mat_t mat, + nmod_mat_t * const residues, slong nres, + const fmpz_comb_t comb, fmpz_comb_temp_t temp, int sign) +{ + slong i, j, k; + mp_ptr r; + + r = _nmod_vec_init(nres); + + for (i = 0; i < fmpz_mat_nrows(mat); i++) + { + for (j = 0; j < fmpz_mat_ncols(mat); j++) + { + for (k = 0; k < nres; k++) + r[k] = nmod_mat_entry(residues[k], i, j); + fmpz_multi_CRT_ui(fmpz_mat_entry(mat, i, j), r, comb, temp, sign); + } + } + + _nmod_vec_clear(r); +} + +void +fmpz_mat_multi_CRT_ui(fmpz_mat_t mat, nmod_mat_t * const residues, + slong nres, int sign) +{ + fmpz_comb_t comb; + fmpz_comb_temp_t temp; + mp_ptr primes; + slong i; + + primes = _nmod_vec_init(nres); + for (i = 0; i < nres; i++) + primes[i] = residues[i]->mod.n; + + fmpz_comb_init(comb, primes, nres); + fmpz_comb_temp_init(temp, comb); + + fmpz_mat_multi_CRT_ui_precomp(mat, residues, nres, comb, temp, sign); + + fmpz_comb_clear(comb); + fmpz_comb_temp_clear(temp); + _nmod_vec_clear(primes); +} diff --git a/external/flint-2.4.3/fmpz_mat/multi_mod_ui.c b/external/flint-2.4.3/fmpz_mat/multi_mod_ui.c new file mode 100644 index 0000000..823fb7e --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/multi_mod_ui.c @@ -0,0 +1,69 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +void +fmpz_mat_multi_mod_ui_precomp(nmod_mat_t * residues, slong nres, + const fmpz_mat_t mat, const fmpz_comb_t comb, fmpz_comb_temp_t temp) +{ + slong i, j, k; + mp_ptr r; + + r = _nmod_vec_init(nres); + + for (i = 0; i < fmpz_mat_nrows(mat); i++) + { + for (j = 0; j < fmpz_mat_ncols(mat); j++) + { + fmpz_multi_mod_ui(r, fmpz_mat_entry(mat, i, j), comb, temp); + for (k = 0; k < nres; k++) + nmod_mat_entry(residues[k], i, j) = r[k]; + } + } + + _nmod_vec_clear(r); +} + +void +fmpz_mat_multi_mod_ui(nmod_mat_t * residues, slong nres, const fmpz_mat_t mat) +{ + fmpz_comb_t comb; + fmpz_comb_temp_t temp; + mp_ptr primes; + slong i; + + primes = _nmod_vec_init(nres); + for (i = 0; i < nres; i++) + primes[i] = residues[i]->mod.n; + fmpz_comb_init(comb, primes, nres); + fmpz_comb_temp_init(temp, comb); + + fmpz_mat_multi_mod_ui_precomp(residues, nres, mat, comb, temp); + + fmpz_comb_clear(comb); + fmpz_comb_temp_clear(temp); + _nmod_vec_clear(primes); +} diff --git a/external/flint-2.4.3/fmpz_mat/neg.c b/external/flint-2.4.3/fmpz_mat/neg.c new file mode 100644 index 0000000..df5b500 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/neg.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +void +fmpz_mat_neg(fmpz_mat_t res, const fmpz_mat_t mat) +{ + slong i; + + if (res->c < 1) + return; + + for (i = 0; i < res->r; i++) + _fmpz_vec_neg(res->rows[i], mat->rows[i], res->c); +} diff --git a/external/flint-2.4.3/fmpz_mat/nullspace.c b/external/flint-2.4.3/fmpz_mat/nullspace.c new file mode 100644 index 0000000..6fb4aa0 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/nullspace.c @@ -0,0 +1,91 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +slong +fmpz_mat_nullspace(fmpz_mat_t res, const fmpz_mat_t mat) +{ + slong i, j, k, n, rank, nullity; + slong * pivots; + slong * nonpivots; + fmpz_mat_t tmp; + fmpz_t den; + + n = mat->c; + + fmpz_mat_init_set(tmp, mat); + fmpz_init(den); + + rank = fmpz_mat_rref(tmp, den, mat); + nullity = n - rank; + + fmpz_mat_zero(res); + if (rank == 0) + { + for (i = 0; i < nullity; i++) + fmpz_one(res->rows[i] + i); + } + else if (nullity) + { + pivots = flint_malloc(rank * sizeof(slong)); + nonpivots = flint_malloc(nullity * sizeof(slong)); + + for (i = j = k = 0; i < rank; i++) + { + while (fmpz_is_zero(tmp->rows[i] + j)) + { + nonpivots[k] = j; + k++; + j++; + } + pivots[i] = j; + j++; + } + while (k < nullity) + { + nonpivots[k] = j; + k++; + j++; + } + + fmpz_set(den, tmp->rows[0] + pivots[0]); + + for (i = 0; i < nullity; i++) + { + for (j = 0; j < rank; j++) + fmpz_set(res->rows[pivots[j]] + i, tmp->rows[j] + nonpivots[i]); + fmpz_neg(res->rows[nonpivots[i]] + i, den); + } + + flint_free(pivots); + flint_free(nonpivots); + } + + fmpz_clear(den); + fmpz_mat_clear(tmp); + + return nullity; +} diff --git a/external/flint-2.4.3/fmpz_mat/one.c b/external/flint-2.4.3/fmpz_mat/one.c new file mode 100644 index 0000000..aabc065 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/one.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +void +fmpz_mat_one(fmpz_mat_t mat) +{ + slong i, n; + + fmpz_mat_zero(mat); + n = FLINT_MIN(mat->r, mat->c); + + for (i = 0; i < n; i++) + fmpz_one(fmpz_mat_entry(mat, i, i)); +} diff --git a/external/flint-2.4.3/fmpz_mat/pow.c b/external/flint-2.4.3/fmpz_mat/pow.c new file mode 100644 index 0000000..250652c --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/pow.c @@ -0,0 +1,75 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 "fmpz_mat.h" + +void +fmpz_mat_pow(fmpz_mat_t B, const fmpz_mat_t A, ulong exp) +{ + slong d = fmpz_mat_nrows(A); + + if (exp <= 2 || d <= 1) + { + if (exp == 0 || d == 0) + { + fmpz_mat_one(B); + } + else if (d == 1) + { + fmpz_pow_ui(fmpz_mat_entry(B, 0, 0), + fmpz_mat_entry(A, 0, 0), exp); + } + else if (exp == 1) + { + fmpz_mat_set(B, A); + } + else if (exp == 2) + { + fmpz_mat_sqr(B, A); + } + } + else + { + fmpz_mat_t T, U; + slong i; + + fmpz_mat_init_set(T, A); + fmpz_mat_init(U, d, d); + + for (i = ((slong) FLINT_BIT_COUNT(exp)) - 2; i >= 0; i--) + { + fmpz_mat_sqr(U, T); + + if (exp & (WORD(1) << i)) + fmpz_mat_mul(T, U, A); + else + fmpz_mat_swap(T, U); + } + + fmpz_mat_swap(B, T); + fmpz_mat_clear(T); + fmpz_mat_clear(U); + } +} diff --git a/external/flint-2.4.3/fmpz_mat/profile/p-det.c b/external/flint-2.4.3/fmpz_mat/profile/p-det.c new file mode 100644 index 0000000..a3a7059 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/profile/p-det.c @@ -0,0 +1,116 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright 2009 William Hart + Copyright 2010,2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "profiler.h" +#include "flint.h" +#include "fmpz_mat.h" +#include "fmpz.h" +#include "ulong_extras.h" + +typedef struct +{ + ulong dim; + int algorithm; + slong bits; +} mat_mul_t; + + +void sample(void * arg, ulong count) +{ + mat_mul_t * params = (mat_mul_t *) arg; + ulong i, dim = params->dim; + slong bits = params->bits; + int algorithm = params->algorithm; + + flint_rand_t rnd; + fmpz_mat_t A; + fmpz_t d; + FLINT_TEST_INIT(state); + + + fmpz_mat_init(A, dim, dim); + fmpz_init(d); + + fmpz_mat_randtest(A, state, bits); + + prof_start(); + + if (algorithm == 0) + for (i = 0; i < count; i++) + fmpz_mat_det_bareiss(d, A); + else if (algorithm == 1) + for (i = 0; i < count; i++) + fmpz_mat_det_modular(d, A, 1); + else if (algorithm == 2) + for (i = 0; i < count; i++) + fmpz_mat_det_modular_accelerated(d, A, 1); + + prof_stop(); + + fmpz_mat_clear(A); + fmpz_clear(d); + + flint_randclear(state); +} + +int main(void) +{ + double min_default, min_classical, min_modular, min_modular_2, max; + mat_mul_t params; + slong dim, bits; + + params.bits = 200; + + for (bits = 2; bits <= 4096; bits *= 2) + { + params.bits = bits; + flint_printf("fmpz_mat_det (bits = %wd):\n", params.bits); + + for (dim = 2; dim <= 512; dim = (slong) ((double) dim * 1.1) + 1) + { + params.dim = dim; + + params.algorithm = 0; + prof_repeat(&min_classical, &max, sample, ¶ms); + + params.algorithm = 1; + prof_repeat(&min_modular, &max, sample, ¶ms); + + params.algorithm = 2; + prof_repeat(&min_modular_2, &max, sample, ¶ms); + + flint_printf("dim = %wd classical/modular/acc. %.2f %.2f %.2f (us)\n", + dim, min_classical, min_modular, min_modular_2); + + if (min_modular > 1.1*min_modular_2) + break; + } + } + + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mat/profile/p-mul.c b/external/flint-2.4.3/fmpz_mat/profile/p-mul.c new file mode 100644 index 0000000..338cf64 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/profile/p-mul.c @@ -0,0 +1,133 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright 2009 William Hart + Copyright 2010,2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "profiler.h" +#include "flint.h" +#include "fmpz_mat.h" +#include "fmpz.h" +#include "ulong_extras.h" + +typedef struct +{ + slong m; + slong n; + slong k; + int algorithm; + slong bits; +} mat_mul_t; + + +void sample(void * arg, ulong count) +{ + mat_mul_t * params = (mat_mul_t *) arg; + slong i, m = params->m, n = params->n, k = params->k; + slong bits = params->bits; + int algorithm = params->algorithm; + + flint_rand_t rnd; + fmpz_mat_t A, B, C; + FLINT_TEST_INIT(state); + + + fmpz_mat_init(A, m, n); + fmpz_mat_init(B, n, k); + fmpz_mat_init(C, m, k); + + fmpz_mat_randbits(A, state, bits); + fmpz_mat_randbits(B, state, bits); + + prof_start(); + + if (algorithm == 0) + for (i = 0; i < count; i++) + fmpz_mat_mul(C, A, B); + else if (algorithm == 1) + for (i = 0; i < count; i++) + fmpz_mat_mul_classical(C, A, B); + else if (algorithm == 2) + for (i = 0; i < count; i++) + fmpz_mat_mul_classical_inline(C, A, B); + else if (algorithm == 3) + for (i = 0; i < count; i++) + fmpz_mat_mul_multi_mod(C, A, B); + + prof_stop(); + + fmpz_mat_clear(A); + fmpz_mat_clear(B); + fmpz_mat_clear(C); + + flint_randclear(state); +} + +int main(void) +{ + double min_default, min_classical, min_inline, min_multi_mod, max; + mat_mul_t params; + slong bits, dim; + + for (bits = 1; bits <= 2000; bits = (slong) ((double) bits * 1.3) + 1) + { + params.bits = bits; + + flint_printf("fmpz_mat_mul (bits = %wd):\n", params.bits); + + for (dim = 1; dim <= 512; dim = (slong) ((double) dim * 1.3) + 1) + { + params.m = dim; + params.n = dim; + params.k = dim; + + params.algorithm = 0; + prof_repeat(&min_default, &max, sample, ¶ms); + + params.algorithm = 1; + prof_repeat(&min_classical, &max, sample, ¶ms); + + params.algorithm = 2; + prof_repeat(&min_inline, &max, sample, ¶ms); + + params.algorithm = 3; + prof_repeat(&min_multi_mod, &max, sample, ¶ms); + + flint_printf("dim = %wd default/classical/inline/multi_mod %.2f %.2f %.2f %.2f (us)\n", + dim, min_default, min_classical, min_inline, min_multi_mod); + + if (min_multi_mod < 0.6*min_default) + flint_printf("BAD!\n"); + + if (min_inline < 0.6*min_default) + flint_printf("BAD!\n"); + + if (min_multi_mod < 0.7*min_inline) + break; + } + } + + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mat/randajtai.c b/external/flint-2.4.3/fmpz_mat/randajtai.c new file mode 100644 index 0000000..899171c --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/randajtai.c @@ -0,0 +1,68 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2005-2009 Damien Stehle + Copyright (C) 2007 David Cade + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include "fmpz_mat.h" + +void +fmpz_mat_randajtai(fmpz_mat_t mat, flint_rand_t state, double alpha) +{ + const slong c = mat->c, r = mat->r, d = r; + + slong i, j; + fmpz_t tmp; + + if (c != r) + { + flint_printf("Exception (fmpz_mat_ajtai): Non-square matrix.\n"); + abort(); + } + + fmpz_init(tmp); + + for (i = 0; i < d; i++) + { + mp_bitcnt_t bits = (mp_bitcnt_t) pow((double) (2 * d - i), alpha); + + fmpz_one(tmp); + fmpz_mul_2exp(tmp, tmp, bits); + fmpz_sub_ui(tmp, tmp, 1); + fmpz_randm(mat->rows[i] + i, state, tmp); + fmpz_add_ui(mat->rows[i] + i, mat->rows[i] + i, 2); + fmpz_fdiv_q_2exp(mat->rows[i] + i, mat->rows[i] + i, 1); + + for (j = i + 1; j <= d; j++) + { + fmpz_randm(mat->rows[j] + i, state, tmp); + if (n_randint(state, 2)) + fmpz_neg(mat->rows[j] + i, mat->rows[j] + i); + fmpz_zero(mat->rows[i] + j); + } + } + + fmpz_clear(tmp); +} diff --git a/external/flint-2.4.3/fmpz_mat/randbits.c b/external/flint-2.4.3/fmpz_mat/randbits.c new file mode 100644 index 0000000..f39ef74 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/randbits.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include "fmpz_mat.h" + +void +fmpz_mat_randbits(fmpz_mat_t mat, flint_rand_t state, mp_bitcnt_t bits) +{ + slong r, c, i, j; + + r = mat->r; + c = mat->c; + + for (i = 0; i < r; i++) + for (j = 0; j < c; j++) + fmpz_randbits(mat->rows[i] + j, state, bits); +} diff --git a/external/flint-2.4.3/fmpz_mat/randdet.c b/external/flint-2.4.3/fmpz_mat/randdet.c new file mode 100644 index 0000000..cfbec35 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/randdet.c @@ -0,0 +1,101 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" +#include "fmpz.h" + +void +fmpz_mat_randdet(fmpz_mat_t mat, flint_rand_t state, const fmpz_t det) +{ + slong i, j, k, n; + int parity; + fmpz * diag; + fmpz_factor_t factor; + + n = mat->r; + if (n != mat->c) + { + flint_printf("Exception (fmpz_mat_randdet). Non-square matrix.\n"); + abort(); + } + + if (n < 1) + return; + + /* Start with the zero matrix */ + fmpz_mat_zero(mat); + + if (*det == WORD(0)) + return; + + fmpz_factor_init(factor); + fmpz_factor(factor, det); + + diag = _fmpz_vec_init(n); + for (i = 0; i < n; i++) + fmpz_one(&diag[i]); + + /* Form diagonal entries that multiply to the determinant */ + for (i = 0; i < factor->num; i++) + { + for (j = 0; j < factor->exp[i]; j++) + { + k = n_randint(state, n); + fmpz_mul(&diag[k], &diag[k], &factor->p[i]); + } + } + + /* Reverse signs an even number of times */ + for (i = 0; i < 2*n; i++) + { + k = n_randint(state, n); + fmpz_neg(&diag[k], &diag[k]); + } + + if (factor->sign == -1) + fmpz_neg(&diag[0], &diag[0]); + + parity = fmpz_mat_randpermdiag(mat, state, diag, n); + + /* Need another reversal if the permutation was odd */ + if (parity) + { + for (i = 0; i < mat->r; i++) + { + for (j = 0; j < mat->c; j++) + { + if (!fmpz_is_zero(mat->rows[i] + j)) + { + fmpz_neg(mat->rows[i] + j, mat->rows[i] + j); + goto end; + } + } + } + } + end: + + _fmpz_vec_clear(diag, n); + fmpz_factor_clear(factor); +} diff --git a/external/flint-2.4.3/fmpz_mat/randintrel.c b/external/flint-2.4.3/fmpz_mat/randintrel.c new file mode 100644 index 0000000..9ac9908 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/randintrel.c @@ -0,0 +1,52 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2005-2009 Damien Stehle + Copyright (C) 2007 David Cade + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include "fmpz_mat.h" + +void +fmpz_mat_randintrel(fmpz_mat_t mat, flint_rand_t state, mp_bitcnt_t bits) +{ + const slong c = mat->c, r = mat->r; + + slong i, j; + + if (c != r + 1) + { + flint_printf("Exception (fmpz_mat_randintrel). c != r + 1.\n"); + abort(); + } + + for (i = 0; i < r; i++) + { + fmpz_randbits(mat->rows[i], state, bits); + for (j = 1; j <= i; j++) + fmpz_zero(mat->rows[i] + j); + fmpz_one(mat->rows[i] + i + 1); + for (j = i + 2; j < c; j++) + fmpz_zero(mat->rows[i] + j); + } +} diff --git a/external/flint-2.4.3/fmpz_mat/randntrulike.c b/external/flint-2.4.3/fmpz_mat/randntrulike.c new file mode 100644 index 0000000..13b35ab --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/randntrulike.c @@ -0,0 +1,83 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2005-2009 Damien Stehle + Copyright (C) 2007 David Cade + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include "fmpz_mat.h" + +void +fmpz_mat_randntrulike(fmpz_mat_t mat, flint_rand_t state, mp_bitcnt_t bits, ulong q) +{ + const slong c = mat->c, r = mat->r, d = r / 2; + + slong i, j, k; + fmpz *h; + + if ((c != r) || (c != 2 * d)) + { + flint_printf("Exception (fmpz_mat_randntrulike). Ill-formed matrix.\n"); + abort(); + } + + h = _fmpz_vec_init(d); + + for (i = 0; i < d; i++) + fmpz_randbits(h + i, state, bits); + + for (i = 0; i < d; i++) + { + for (j = 0; j < i; j++) + fmpz_zero(mat->rows[i] + j); + fmpz_one(mat->rows[i] + i); + for (j = i + 1; j < d; j++) + fmpz_zero(mat->rows[i] + j); + } + + for (i = d; i < r; i++) + for (j = 0; j < d; j++) + fmpz_zero(mat->rows[i] + j); + + for (i = d; i < r; i++) + { + for (j = d; j < i; j++) + fmpz_zero(mat->rows[i] + j); + fmpz_set_ui(mat->rows[i] + i, q); + for (j = i + 1; j < c; j++) + fmpz_zero(mat->rows[i] + j); + } + + for (i = 0; i < d; i++) + { + for (j = d; j < c; j++) + { + k = j + i; + while (k >= d) + k -= d; + fmpz_set(mat->rows[i] + j, h + k); + } + } + + _fmpz_vec_clear(h, d); +} diff --git a/external/flint-2.4.3/fmpz_mat/randntrulike2.c b/external/flint-2.4.3/fmpz_mat/randntrulike2.c new file mode 100644 index 0000000..1738220 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/randntrulike2.c @@ -0,0 +1,83 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2005-2009 Damien Stehle + Copyright (C) 2007 David Cade + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include "fmpz_mat.h" + +void +fmpz_mat_randntrulike2(fmpz_mat_t mat, flint_rand_t state, mp_bitcnt_t bits, ulong q) +{ + const slong c = mat->c, r = mat->r, d = r / 2; + + slong i, j, k; + fmpz *h; + + if ((c != r) || (c != 2 * d)) + { + flint_printf("Exception (fmpz_mat_randntrulike2). Ill-formed matrix.\n"); + abort(); + } + + h = _fmpz_vec_init(d); + + for (i = 0; i < d; i++) + fmpz_randbits(h + i, state, bits); + + for (i = 0; i < d; i++) + { + for (j = 0; j < i; j++) + fmpz_zero(mat->rows[i] + j); + fmpz_set_ui(mat->rows[i] + i, q); + for (j = i + 1; j < d; j++) + fmpz_zero(mat->rows[i] + j); + } + + for (i = 0; i < d; i++) + for (j = d; j < c; j++) + fmpz_zero(mat->rows[i] + j); + + for (i = d; i < c; i++) + { + for (j = d; j < i; j++) + fmpz_zero(mat->rows[i] + j); + fmpz_one(mat->rows[i] + i); + for (j = i + 1; j < c; j++) + fmpz_zero(mat->rows[i] + j); + } + + for (i = d; i < r; i++) + { + for (j = 0; j < d; j++) + { + k = j + i; + while (k >= d) + k -= d; + fmpz_set(mat->rows[i] + j, h + k); + } + } + + _fmpz_vec_clear(h, d); +} diff --git a/external/flint-2.4.3/fmpz_mat/randops.c b/external/flint-2.4.3/fmpz_mat/randops.c new file mode 100644 index 0000000..6c6f64e --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/randops.c @@ -0,0 +1,67 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +void +fmpz_mat_randops(fmpz_mat_t mat, flint_rand_t state, slong count) +{ + slong c, i, j, k; + slong m = mat->r; + slong n = mat->c; + + if (mat->r == 0 || mat->c == 0) + return; + + for (c = 0; c < count; c++) + { + if (n_randint(state, 2)) + { + if ((i = n_randint(state, m)) == (j = n_randint(state, m))) + continue; + if (n_randint(state, 2)) + for (k = 0; k < n; k++) + fmpz_add(&mat->rows[j][k], &mat->rows[j][k], + &mat->rows[i][k]); + else + for (k = 0; k < n; k++) + fmpz_sub(&mat->rows[j][k], &mat->rows[j][k], + &mat->rows[i][k]); + } + else + { + if ((i = n_randint(state, n)) == (j = n_randint(state, n))) + continue; + if (n_randint(state, 2)) + for (k = 0; k < m; k++) + fmpz_add(&mat->rows[k][j], &mat->rows[k][j], + &mat->rows[k][i]); + else + for (k = 0; k < m; k++) + fmpz_sub(&mat->rows[k][j], &mat->rows[k][j], + &mat->rows[k][i]); + } + } +} diff --git a/external/flint-2.4.3/fmpz_mat/randpermdiag.c b/external/flint-2.4.3/fmpz_mat/randpermdiag.c new file mode 100644 index 0000000..eae63b5 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/randpermdiag.c @@ -0,0 +1,52 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010,2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" +#include "perm.h" + +int +fmpz_mat_randpermdiag(fmpz_mat_t mat, flint_rand_t state, + const fmpz * diag, slong n) +{ + int parity; + slong i; + slong * rows; + slong * cols; + + rows = _perm_init(mat->r); + cols = _perm_init(mat->c); + + parity = _perm_randtest(rows, mat->r, state); + parity ^= _perm_randtest(cols, mat->c, state); + + fmpz_mat_zero(mat); + for (i = 0; i < n; i++) + fmpz_set(fmpz_mat_entry(mat, rows[i], cols[i]), diag + i); + + _perm_clear(rows); + _perm_clear(cols); + + return parity; +} diff --git a/external/flint-2.4.3/fmpz_mat/randrank.c b/external/flint-2.4.3/fmpz_mat/randrank.c new file mode 100644 index 0000000..924b9b0 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/randrank.c @@ -0,0 +1,48 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +void +fmpz_mat_randrank(fmpz_mat_t mat, flint_rand_t state, slong rank, + mp_bitcnt_t bits) +{ + slong i; + fmpz * diag; + + if (rank < 0 || rank > mat->r || rank > mat->c) + { + flint_printf("Exception (fmpz_mat_randrank). Impossible rank.\n"); + abort(); + } + + diag = _fmpz_vec_init(rank); + for (i = 0; i < rank; i++) + fmpz_randtest_not_zero(&diag[i], state, bits); + + fmpz_mat_randpermdiag(mat, state, diag, rank); + + _fmpz_vec_clear(diag, rank); +} diff --git a/external/flint-2.4.3/fmpz_mat/randsimdioph.c b/external/flint-2.4.3/fmpz_mat/randsimdioph.c new file mode 100644 index 0000000..34e30c6 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/randsimdioph.c @@ -0,0 +1,56 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2005-2009 Damien Stehle + Copyright (C) 2007 David Cade + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include "fmpz_mat.h" + +void +fmpz_mat_randsimdioph(fmpz_mat_t mat, flint_rand_t state, mp_bitcnt_t bits, mp_bitcnt_t bits2) +{ + const slong c = mat->c, r = mat->r; + + slong i, j; + + if (c != r) + { + flint_printf("Exception (fmpz_mat_randsimdioph). Ill-formed matrix.\n"); + abort(); + } + + fmpz_one(mat->rows[0]); + fmpz_mul_2exp(mat->rows[0], mat->rows[0], bits2); + for (j = 1; j < c; j++) + fmpz_randbits(mat->rows[0] + j, state, bits); + for (i = 1; i < r; i++) + { + for (j = 0; j < i; j++) + fmpz_zero(mat->rows[i] + j); + fmpz_one(mat->rows[i] + i); + fmpz_mul_2exp(mat->rows[i] + i, mat->rows[i] + i, bits); + for (j = i + 1; j < c; j++) + fmpz_zero(mat->rows[i] + j); + } +} diff --git a/external/flint-2.4.3/fmpz_mat/randtest.c b/external/flint-2.4.3/fmpz_mat/randtest.c new file mode 100644 index 0000000..aec56cd --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/randtest.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include "fmpz_mat.h" + +void +fmpz_mat_randtest(fmpz_mat_t mat, flint_rand_t state, mp_bitcnt_t bits) +{ + slong r, c, i, j; + + r = mat->r; + c = mat->c; + + for (i = 0; i < r; i++) + for (j = 0; j < c; j++) + fmpz_randtest(mat->rows[i] + j, state, bits); +} diff --git a/external/flint-2.4.3/fmpz_mat/randtest_unsigned.c b/external/flint-2.4.3/fmpz_mat/randtest_unsigned.c new file mode 100644 index 0000000..e58126a --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/randtest_unsigned.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include "fmpz_mat.h" + +void +fmpz_mat_randtest_unsigned(fmpz_mat_t mat, flint_rand_t state, mp_bitcnt_t bits) +{ + slong r, c, i, j; + + r = mat->r; + c = mat->c; + + for (i = 0; i < r; i++) + for (j = 0; j < c; j++) + fmpz_randtest_unsigned(mat->rows[i] + j, state, bits); +} diff --git a/external/flint-2.4.3/fmpz_mat/rank.c b/external/flint-2.4.3/fmpz_mat/rank.c new file mode 100644 index 0000000..950bc27 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/rank.c @@ -0,0 +1,47 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +slong +fmpz_mat_rank(const fmpz_mat_t A) +{ + fmpz_mat_t tmp; + fmpz_t den; + slong rank; + + if (fmpz_mat_is_empty(A)) + return 0; + + fmpz_mat_init_set(tmp, A); + fmpz_init(den); + + rank = fmpz_mat_fflu(tmp, den, NULL, tmp, 0); + + fmpz_mat_clear(tmp); + fmpz_clear(den); + + return rank; +} diff --git a/external/flint-2.4.3/fmpz_mat/rref.c b/external/flint-2.4.3/fmpz_mat/rref.c new file mode 100644 index 0000000..f83ed5a --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/rref.c @@ -0,0 +1,105 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011-2012 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +slong +fmpz_mat_rref(fmpz_mat_t R, fmpz_t den, const fmpz_mat_t A) +{ + slong i, j, k, m, n, rank; + slong *pivots, *nonpivots; + + rank = fmpz_mat_fflu(R, den, NULL, A, 0); + m = fmpz_mat_nrows(R); + n = fmpz_mat_ncols(R); + + /* clear bottom */ + for (i = rank; i < m; i++) + for (j = 0; j < n; j++) + fmpz_zero(fmpz_mat_entry(R, i, j)); + + /* Convert row echelon form to reduced row echelon form */ + if (rank > 1) + { + fmpz_t tmp; + fmpz_init(tmp); + + pivots = flint_malloc(sizeof(slong) * n); + nonpivots = pivots + rank; + + for (i = j = k = 0; i < rank; i++) + { + while (fmpz_is_zero(fmpz_mat_entry(R, i, j))) + { + nonpivots[k] = j; + k++; + j++; + } + pivots[i] = j; + j++; + } + while (k < n - rank) + { + nonpivots[k] = j; + k++; + j++; + } + + for (k = 0; k < n - rank; k++) + { + for (i = rank - 2; i >= 0; i--) + { + fmpz_mul(tmp, den, fmpz_mat_entry(R, i, nonpivots[k])); + + for (j = i + 1; j < rank; j++) + { + fmpz_submul(tmp, fmpz_mat_entry(R, i, pivots[j]), + fmpz_mat_entry(R, j, nonpivots[k])); + } + + fmpz_divexact(fmpz_mat_entry(R, i, nonpivots[k]), + tmp, fmpz_mat_entry(R, i, pivots[i])); + } + } + + /* clear pivot columns */ + for (i = 0; i < rank; i++) + { + for (j = 0; j < rank; j++) + { + if (i == j) + fmpz_set(fmpz_mat_entry(R, j, pivots[i]), den); + else + fmpz_zero(fmpz_mat_entry(R, j, pivots[i])); + } + } + + flint_free(pivots); + fmpz_clear(tmp); + } + + return rank; +} + diff --git a/external/flint-2.4.3/fmpz_mat/rref_mod.c b/external/flint-2.4.3/fmpz_mat/rref_mod.c new file mode 100644 index 0000000..e9551fc --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/rref_mod.c @@ -0,0 +1,98 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + +******************************************************************************/ + +#include "fmpz_mat.h" + +#define E(j,k) fmpz_mat_entry(A,j,k) + +slong +fmpz_mat_rref_mod(slong * perm, fmpz_mat_t A, const fmpz_t p) +{ + fmpz_t t, inv; + slong m, n, j, k, rank, r, pivot_row, pivot_col; + + if (fmpz_mat_is_empty(A)) + { + return 0; + } + + m = A->r; + n = A->c; + rank = pivot_row = pivot_col = 0; + + fmpz_init(t); + fmpz_init(inv); + + while (pivot_row < m && pivot_col < n) + { + r = fmpz_mat_find_pivot_any(A, pivot_row, m, pivot_col); + + if (r == -1) + { + pivot_col++; + continue; + } + else if (r != pivot_row) + { + fmpz_mat_swap_rows(A, perm, pivot_row, r); + } + rank++; + + fmpz_invmod(inv, E(pivot_row, pivot_col), p); + + /* pivot row */ + for (k = pivot_col + 1; k < n; k++) + { + fmpz_mul(E(pivot_row, k), E(pivot_row, k), inv); + fmpz_mod(E(pivot_row, k), E(pivot_row, k), p); + } + fmpz_one(E(pivot_row, pivot_col)); + + /* other rows */ + for (j = 0; j < m; j++) + { + if (j == pivot_row) + continue; + + for (k = pivot_col + 1; k < n; k++) + { + fmpz_mul(t, E(j, pivot_col), E(pivot_row, k)); + fmpz_sub(E(j, k), E(j, k), t); + fmpz_mod(E(j, k), E(j, k), p); + } + + fmpz_zero(E(j, pivot_col)); + } + + pivot_row++; + pivot_col++; + } + + fmpz_clear(inv); + fmpz_clear(t); + + return rank; +} diff --git a/external/flint-2.4.3/fmpz_mat/scalar_addmul_fmpz.c b/external/flint-2.4.3/fmpz_mat/scalar_addmul_fmpz.c new file mode 100644 index 0000000..2a3aa70 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/scalar_addmul_fmpz.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +void +fmpz_mat_scalar_addmul_fmpz(fmpz_mat_t B, const fmpz_mat_t A, const fmpz_t c) +{ + slong i, j; + + for (i = 0; i < A->r; i++) + for (j = 0; j < A->c; j++) + fmpz_addmul(fmpz_mat_entry(B,i,j), fmpz_mat_entry(A,i,j), c); +} diff --git a/external/flint-2.4.3/fmpz_mat/scalar_addmul_nmod_mat_fmpz.c b/external/flint-2.4.3/fmpz_mat/scalar_addmul_nmod_mat_fmpz.c new file mode 100644 index 0000000..8da4d3a --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/scalar_addmul_nmod_mat_fmpz.c @@ -0,0 +1,37 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +void +fmpz_mat_scalar_addmul_nmod_mat_fmpz(fmpz_mat_t B, + const nmod_mat_t A, const fmpz_t c) +{ + slong i, j; + + for (i = 0; i < A->r; i++) + for (j = 0; j < A->c; j++) + fmpz_addmul_ui(fmpz_mat_entry(B,i,j), c, nmod_mat_entry(A,i,j)); +} diff --git a/external/flint-2.4.3/fmpz_mat/scalar_addmul_nmod_mat_ui.c b/external/flint-2.4.3/fmpz_mat/scalar_addmul_nmod_mat_ui.c new file mode 100644 index 0000000..cceafb0 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/scalar_addmul_nmod_mat_ui.c @@ -0,0 +1,37 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +void +fmpz_mat_scalar_addmul_nmod_mat_ui(fmpz_mat_t B, + const nmod_mat_t A, ulong c) +{ + fmpz_t t; + fmpz_init(t); + fmpz_set_ui(t, c); + fmpz_mat_scalar_addmul_nmod_mat_fmpz(B, A, t); + fmpz_clear(t); +} diff --git a/external/flint-2.4.3/fmpz_mat/scalar_addmul_si.c b/external/flint-2.4.3/fmpz_mat/scalar_addmul_si.c new file mode 100644 index 0000000..40b7d2c --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/scalar_addmul_si.c @@ -0,0 +1,35 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +void +fmpz_mat_scalar_addmul_si(fmpz_mat_t B, const fmpz_mat_t A, slong c) +{ + if (c > 0) + fmpz_mat_scalar_addmul_ui(B, A, c); + else + fmpz_mat_scalar_submul_ui(B, A, -c); +} diff --git a/external/flint-2.4.3/fmpz_mat/scalar_addmul_ui.c b/external/flint-2.4.3/fmpz_mat/scalar_addmul_ui.c new file mode 100644 index 0000000..beadf0e --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/scalar_addmul_ui.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +void +fmpz_mat_scalar_addmul_ui(fmpz_mat_t B, const fmpz_mat_t A, ulong c) +{ + slong i, j; + + for (i = 0; i < A->r; i++) + for (j = 0; j < A->c; j++) + fmpz_addmul_ui(fmpz_mat_entry(B,i,j), fmpz_mat_entry(A,i,j), c); +} diff --git a/external/flint-2.4.3/fmpz_mat/scalar_divexact_fmpz.c b/external/flint-2.4.3/fmpz_mat/scalar_divexact_fmpz.c new file mode 100644 index 0000000..d99d788 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/scalar_divexact_fmpz.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +void +fmpz_mat_scalar_divexact_fmpz(fmpz_mat_t B, const fmpz_mat_t A, const fmpz_t c) +{ + slong i, j; + + for (i = 0; i < A->r; i++) + for (j = 0; j < A->c; j++) + fmpz_divexact(fmpz_mat_entry(B,i,j), fmpz_mat_entry(A,i,j), c); +} diff --git a/external/flint-2.4.3/fmpz_mat/scalar_divexact_si.c b/external/flint-2.4.3/fmpz_mat/scalar_divexact_si.c new file mode 100644 index 0000000..104b25c --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/scalar_divexact_si.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +void +fmpz_mat_scalar_divexact_si(fmpz_mat_t B, const fmpz_mat_t A, slong c) +{ + slong i, j; + + for (i = 0; i < A->r; i++) + for (j = 0; j < A->c; j++) + fmpz_divexact_si(fmpz_mat_entry(B,i,j), fmpz_mat_entry(A,i,j), c); +} diff --git a/external/flint-2.4.3/fmpz_mat/scalar_divexact_ui.c b/external/flint-2.4.3/fmpz_mat/scalar_divexact_ui.c new file mode 100644 index 0000000..2d427f3 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/scalar_divexact_ui.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +void +fmpz_mat_scalar_divexact_ui(fmpz_mat_t B, const fmpz_mat_t A, ulong c) +{ + slong i, j; + + for (i = 0; i < A->r; i++) + for (j = 0; j < A->c; j++) + fmpz_divexact_ui(fmpz_mat_entry(B,i,j), fmpz_mat_entry(A,i,j), c); +} diff --git a/external/flint-2.4.3/fmpz_mat/scalar_mod_fmpz.c b/external/flint-2.4.3/fmpz_mat/scalar_mod_fmpz.c new file mode 100644 index 0000000..81bf65c --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/scalar_mod_fmpz.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +void +fmpz_mat_scalar_mod_fmpz(fmpz_mat_t B, const fmpz_mat_t A, const fmpz_t m) +{ + slong i, j; + fmpz_t t; + fmpz_init(t); + + for (i = 0; i < A->r; i++) + for (j = 0; j < A->c; j++) + fmpz_fdiv_qr(t, fmpz_mat_entry(B,i,j), fmpz_mat_entry(A,i,j), m); + + fmpz_clear(t); +} diff --git a/external/flint-2.4.3/fmpz_mat/scalar_mul_fmpz.c b/external/flint-2.4.3/fmpz_mat/scalar_mul_fmpz.c new file mode 100644 index 0000000..cad35e1 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/scalar_mul_fmpz.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +void +fmpz_mat_scalar_mul_fmpz(fmpz_mat_t B, const fmpz_mat_t A, const fmpz_t c) +{ + slong i, j; + + for (i = 0; i < A->r; i++) + for (j = 0; j < A->c; j++) + fmpz_mul(fmpz_mat_entry(B,i,j), fmpz_mat_entry(A,i,j), c); +} diff --git a/external/flint-2.4.3/fmpz_mat/scalar_mul_si.c b/external/flint-2.4.3/fmpz_mat/scalar_mul_si.c new file mode 100644 index 0000000..eee5948 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/scalar_mul_si.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +void +fmpz_mat_scalar_mul_si(fmpz_mat_t B, const fmpz_mat_t A, slong c) +{ + slong i, j; + + for (i = 0; i < A->r; i++) + for (j = 0; j < A->c; j++) + fmpz_mul_si(fmpz_mat_entry(B,i,j), fmpz_mat_entry(A,i,j), c); +} diff --git a/external/flint-2.4.3/fmpz_mat/scalar_mul_ui.c b/external/flint-2.4.3/fmpz_mat/scalar_mul_ui.c new file mode 100644 index 0000000..60be0f6 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/scalar_mul_ui.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +void +fmpz_mat_scalar_mul_ui(fmpz_mat_t B, const fmpz_mat_t A, ulong c) +{ + slong i, j; + + for (i = 0; i < A->r; i++) + for (j = 0; j < A->c; j++) + fmpz_mul_ui(fmpz_mat_entry(B,i,j), fmpz_mat_entry(A,i,j), c); +} diff --git a/external/flint-2.4.3/fmpz_mat/scalar_submul_fmpz.c b/external/flint-2.4.3/fmpz_mat/scalar_submul_fmpz.c new file mode 100644 index 0000000..2df7402 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/scalar_submul_fmpz.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +void +fmpz_mat_scalar_submul_fmpz(fmpz_mat_t B, const fmpz_mat_t A, const fmpz_t c) +{ + slong i, j; + + for (i = 0; i < A->r; i++) + for (j = 0; j < A->c; j++) + fmpz_submul(fmpz_mat_entry(B,i,j), fmpz_mat_entry(A,i,j), c); +} diff --git a/external/flint-2.4.3/fmpz_mat/scalar_submul_si.c b/external/flint-2.4.3/fmpz_mat/scalar_submul_si.c new file mode 100644 index 0000000..1822e67 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/scalar_submul_si.c @@ -0,0 +1,35 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +void +fmpz_mat_scalar_submul_si(fmpz_mat_t B, const fmpz_mat_t A, slong c) +{ + if (c > 0) + fmpz_mat_scalar_submul_ui(B, A, c); + else + fmpz_mat_scalar_addmul_ui(B, A, -c); +} diff --git a/external/flint-2.4.3/fmpz_mat/scalar_submul_ui.c b/external/flint-2.4.3/fmpz_mat/scalar_submul_ui.c new file mode 100644 index 0000000..19bce8f --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/scalar_submul_ui.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +void +fmpz_mat_scalar_submul_ui(fmpz_mat_t B, const fmpz_mat_t A, ulong c) +{ + slong i, j; + + for (i = 0; i < A->r; i++) + for (j = 0; j < A->c; j++) + fmpz_submul_ui(fmpz_mat_entry(B,i,j), fmpz_mat_entry(A,i,j), c); +} diff --git a/external/flint-2.4.3/fmpz_mat/set.c b/external/flint-2.4.3/fmpz_mat/set.c new file mode 100644 index 0000000..5d839bf --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/set.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +void +fmpz_mat_set(fmpz_mat_t mat1, const fmpz_mat_t mat2) +{ + if (mat1 != mat2) + { + slong i; + + if (mat2->r && mat2->c) + for (i = 0; i < mat2->r; i++) + _fmpz_vec_set(mat1->rows[i], mat2->rows[i], mat2->c); + } +} diff --git a/external/flint-2.4.3/fmpz_mat/set_nmod_mat.c b/external/flint-2.4.3/fmpz_mat/set_nmod_mat.c new file mode 100644 index 0000000..ad3c79d --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/set_nmod_mat.c @@ -0,0 +1,37 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +void +fmpz_mat_set_nmod_mat(fmpz_mat_t A, const nmod_mat_t Amod) +{ + slong i, j; + + for (i = 0; i < Amod->r; i++) + for (j = 0; j < Amod->c; j++) + fmpz_set_ui_smod(fmpz_mat_entry(A, i, j), + nmod_mat_entry(Amod, i, j), Amod->mod.n); +} diff --git a/external/flint-2.4.3/fmpz_mat/set_nmod_mat_unsigned.c b/external/flint-2.4.3/fmpz_mat/set_nmod_mat_unsigned.c new file mode 100644 index 0000000..5798f6c --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/set_nmod_mat_unsigned.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +void +fmpz_mat_set_nmod_mat_unsigned(fmpz_mat_t A, const nmod_mat_t Amod) +{ + slong i, j; + + for (i = 0; i < Amod->r; i++) + for (j = 0; j < Amod->c; j++) + fmpz_set_ui(fmpz_mat_entry(A, i, j), nmod_mat_entry(Amod, i, j)); +} diff --git a/external/flint-2.4.3/fmpz_mat/solve.c b/external/flint-2.4.3/fmpz_mat/solve.c new file mode 100644 index 0000000..2e6674b --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/solve.c @@ -0,0 +1,37 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" +#include "perm.h" + +int +fmpz_mat_solve(fmpz_mat_t X, fmpz_t den, + const fmpz_mat_t A, const fmpz_mat_t B) +{ + if (fmpz_mat_nrows(A) <= 3) + return fmpz_mat_solve_cramer(X, den, A, B); + else + return fmpz_mat_solve_fflu(X, den, A, B); +} diff --git a/external/flint-2.4.3/fmpz_mat/solve_bound.c b/external/flint-2.4.3/fmpz_mat/solve_bound.c new file mode 100644 index 0000000..4c6683e --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/solve_bound.c @@ -0,0 +1,63 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +void +fmpz_mat_solve_bound(fmpz_t N, fmpz_t D, + const fmpz_mat_t A, const fmpz_mat_t B) +{ + slong i, j, m, n; + fmpz_t t, u; + + m = B->r; + n = B->c; + + fmpz_mat_det_bound(D, A); + + fmpz_init(t); + fmpz_init(u); + + fmpz_zero(t); + + /* Largest column norm of B */ + for (j = 0; j < n; j++) + { + fmpz_zero(u); + for (i = 0; i < m; i++) + fmpz_addmul(u, fmpz_mat_entry(B, i, j), fmpz_mat_entry(B, i, j)); + if (fmpz_cmp(t, u) < 0) + fmpz_set(t, u); + } + + fmpz_sqrtrem(t, u, t); + if (!fmpz_is_zero(u)) + fmpz_add_ui(t, t, UWORD(1)); + + fmpz_mul(N, D, t); + + fmpz_clear(t); + fmpz_clear(u); +} diff --git a/external/flint-2.4.3/fmpz_mat/solve_cramer.c b/external/flint-2.4.3/fmpz_mat/solve_cramer.c new file mode 100644 index 0000000..34bbe65 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/solve_cramer.c @@ -0,0 +1,172 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +#define AA(i,j) fmpz_mat_entry(A, i, j) +#define BB(i,j) fmpz_mat_entry(B, i, j) +#define XX(i,j) fmpz_mat_entry(X, i, j) + +int +_fmpz_mat_solve_cramer_3x3(fmpz_mat_t X, fmpz_t den, + const fmpz_mat_t A, const fmpz_mat_t B) +{ + fmpz_t t15, t16, t17; + int success; + + fmpz_init(t15); + fmpz_init(t16); + fmpz_init(t17); + + fmpz_mul(t17, AA(1,0), AA(2,1)); + fmpz_submul(t17, AA(1,1), AA(2,0)); + + fmpz_mul(t16, AA(1,2), AA(2,0)); + fmpz_submul(t16, AA(1,0), AA(2,2)); + + fmpz_mul(t15, AA(1,1), AA(2,2)); + fmpz_submul(t15, AA(1,2), AA(2,1)); + + fmpz_mul (den, t15, AA(0,0)); + fmpz_addmul(den, t16, AA(0,1)); + fmpz_addmul(den, t17, AA(0,2)); + + success = !fmpz_is_zero(den); + + if (success) + { + fmpz_t t12, t13, t14, x0, x1, x2; + slong i, n = fmpz_mat_ncols(B); + + fmpz_init(t12); + fmpz_init(t13); + fmpz_init(t14); + fmpz_init(x0); + fmpz_init(x1); + fmpz_init(x2); + + for (i = 0; i < n; i++) + { + fmpz_mul(t14, AA(2,0), BB(1,i)); + fmpz_submul(t14, AA(1,0), BB(2,i)); + + fmpz_mul(t13, AA(2,1), BB(1,i)); + fmpz_submul(t13, AA(1,1), BB(2,i)); + + fmpz_mul(t12, AA(2,2), BB(1,i)); + fmpz_submul(t12, AA(1,2), BB(2,i)); + + fmpz_mul (x0, t15, BB(0,i)); + fmpz_addmul(x0, t13, AA(0,2)); + fmpz_submul(x0, t12, AA(0,1)); + + fmpz_mul (x1, t16, BB(0,i)); + fmpz_addmul(x1, t12, AA(0,0)); + fmpz_submul(x1, t14, AA(0,2)); + + fmpz_mul (x2, t17, BB(0,i)); + fmpz_addmul(x2, t14, AA(0,1)); + fmpz_submul(x2, t13, AA(0,0)); + + fmpz_swap(XX(0,i), x0); + fmpz_swap(XX(1,i), x1); + fmpz_swap(XX(2,i), x2); + } + + fmpz_clear(t12); + fmpz_clear(t13); + fmpz_clear(t14); + fmpz_clear(x0); + fmpz_clear(x1); + fmpz_clear(x2); + } + + fmpz_clear(t15); + fmpz_clear(t16); + fmpz_clear(t17); + + return success; +} + +int +fmpz_mat_solve_cramer(fmpz_mat_t X, fmpz_t den, + const fmpz_mat_t A, const fmpz_mat_t B) +{ + slong i, dim = fmpz_mat_nrows(A); + + if (dim == 0 || fmpz_mat_ncols(B) == 0) + { + fmpz_one(den); + return 1; + } + else if (dim == 1) + { + fmpz_set(den, fmpz_mat_entry(A, 0, 0)); + + if (fmpz_is_zero(den)) + return 0; + + if (!fmpz_mat_is_empty(B)) + _fmpz_vec_set(X->rows[0], B->rows[0], fmpz_mat_ncols(B)); + return 1; + } + else if (dim == 2) + { + fmpz_t t, u; + + _fmpz_mat_det_cofactor_2x2(den, A->rows); + + if (fmpz_is_zero(den)) + return 0; + + fmpz_init(t); + fmpz_init(u); + + for (i = 0; i < fmpz_mat_ncols(B); i++) + { + fmpz_mul (t, fmpz_mat_entry(A, 1, 1), fmpz_mat_entry(B, 0, i)); + fmpz_submul(t, fmpz_mat_entry(A, 0, 1), fmpz_mat_entry(B, 1, i)); + fmpz_mul (u, fmpz_mat_entry(A, 0, 0), fmpz_mat_entry(B, 1, i)); + fmpz_submul(u, fmpz_mat_entry(A, 1, 0), fmpz_mat_entry(B, 0, i)); + + fmpz_swap(fmpz_mat_entry(X, 0, i), t); + fmpz_swap(fmpz_mat_entry(X, 1, i), u); + } + + fmpz_clear(t); + fmpz_clear(u); + + return 1; + } + else if (dim == 3) + { + return _fmpz_mat_solve_cramer_3x3(X, den, A, B); + } + else + { + flint_printf("Exception (fmpz_mat_solve_cramer). dim > 3 not implemented."); + abort(); + } +} diff --git a/external/flint-2.4.3/fmpz_mat/solve_dixon.c b/external/flint-2.4.3/fmpz_mat/solve_dixon.c new file mode 100644 index 0000000..0f42a29 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/solve_dixon.c @@ -0,0 +1,251 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +static mp_limb_t +find_good_prime_and_invert(nmod_mat_t Ainv, + const fmpz_mat_t A, const fmpz_t det_bound) +{ + mp_limb_t p; + fmpz_t tested; + + p = UWORD(1) << NMOD_MAT_OPTIMAL_MODULUS_BITS; + fmpz_init(tested); + fmpz_one(tested); + + while (1) + { + p = n_nextprime(p, 0); + _nmod_mat_set_mod(Ainv, p); + fmpz_mat_get_nmod_mat(Ainv, A); + if (nmod_mat_inv(Ainv, Ainv)) + break; + fmpz_mul_ui(tested, tested, p); + if (fmpz_cmp(tested, det_bound) > 0) + { + p = 0; + break; + } + } + + fmpz_clear(tested); + return p; +} + +/* We need to perform several matrix-vector products Ay, and speed them + up by using modular multiplication (this is only faster if we + precompute the modular matrices). Note: we assume that all + primes are >= p. This allows reusing y_mod as the right-hand + side without reducing it. */ + +#define USE_SLOW_MULTIPLICATION 0 + +mp_limb_t * get_crt_primes(slong * num_primes, const fmpz_mat_t A, mp_limb_t p) +{ + fmpz_t bound, prod; + mp_limb_t * primes; + slong i, j; + + fmpz_init(bound); + fmpz_init(prod); + + for (i = 0; i < A->r; i++) + for (j = 0; j < A->c; j++) + if (fmpz_cmpabs(bound, fmpz_mat_entry(A, i, j)) < 0) + fmpz_abs(bound, fmpz_mat_entry(A, i, j)); + + fmpz_mul_ui(bound, bound, p - UWORD(1)); + fmpz_mul_ui(bound, bound, A->r); + fmpz_mul_ui(bound, bound, UWORD(2)); /* signs */ + + primes = flint_malloc(sizeof(mp_limb_t) * (fmpz_bits(bound) / + (FLINT_BIT_COUNT(p) - 1) + 2)); + primes[0] = p; + fmpz_set_ui(prod, p); + *num_primes = 1; + + while (fmpz_cmp(prod, bound) <= 0) + { + primes[*num_primes] = p = n_nextprime(p, 0); + *num_primes += 1; + fmpz_mul_ui(prod, prod, p); + } + + fmpz_clear(bound); + fmpz_clear(prod); + + return primes; +} + + +static void +_fmpz_mat_solve_dixon(fmpz_mat_t X, fmpz_t mod, + const fmpz_mat_t A, const fmpz_mat_t B, + const nmod_mat_t Ainv, mp_limb_t p, + const fmpz_t N, const fmpz_t D) +{ + fmpz_t bound, ppow; + fmpz_mat_t x, d, y, Ay; + fmpz_t prod; + mp_limb_t * crt_primes; + nmod_mat_t * A_mod; + nmod_mat_t Ay_mod, d_mod, y_mod; + slong i, n, cols, num_primes; + + n = A->r; + cols = B->c; + + fmpz_init(bound); + fmpz_init(ppow); + fmpz_init(prod); + + fmpz_mat_init(x, n, cols); + fmpz_mat_init(y, n, cols); + fmpz_mat_init(Ay, n, cols); + fmpz_mat_init_set(d, B); + + /* Compute bound for the needed modulus. TODO: if one of N and D + is much smaller than the other, we could use a tighter bound (i.e. 2ND). + This would require the ability to forward N and D to the + rational reconstruction routine. + */ + if (fmpz_cmpabs(N, D) < 0) + fmpz_mul(bound, D, D); + else + fmpz_mul(bound, N, N); + fmpz_mul_ui(bound, bound, UWORD(2)); /* signs */ + + crt_primes = get_crt_primes(&num_primes, A, p); + A_mod = flint_malloc(sizeof(nmod_mat_t) * num_primes); + for (i = 0; i < num_primes; i++) + { + nmod_mat_init(A_mod[i], n, n, crt_primes[i]); + fmpz_mat_get_nmod_mat(A_mod[i], A); + } + + nmod_mat_init(Ay_mod, n, cols, UWORD(1)); + nmod_mat_init(d_mod, n, cols, p); + nmod_mat_init(y_mod, n, cols, p); + + fmpz_one(ppow); + + while (fmpz_cmp(ppow, bound) <= 0) + { + /* y = A^(-1) * d (mod p) */ + fmpz_mat_get_nmod_mat(d_mod, d); + nmod_mat_mul(y_mod, Ainv, d_mod); + + /* x = x + y * p^i [= A^(-1) * b mod p^(i+1)] */ + fmpz_mat_scalar_addmul_nmod_mat_fmpz(x, y_mod, ppow); + + /* ppow = p^(i+1) */ + fmpz_mul_ui(ppow, ppow, p); + if (fmpz_cmp(ppow, bound) > 0) + break; + + /* d = (d - Ay) / p */ +#if USE_SLOW_MULTIPLICATION + fmpz_mat_set_nmod_mat_unsigned(y, y_mod); + fmpz_mat_mul(Ay, A, y); +#else + for (i = 0; i < num_primes; i++) + { + _nmod_mat_set_mod(y_mod, crt_primes[i]); + _nmod_mat_set_mod(Ay_mod, crt_primes[i]); + nmod_mat_mul(Ay_mod, A_mod[i], y_mod); + if (i == 0) + { + fmpz_mat_set_nmod_mat(Ay, Ay_mod); + fmpz_set_ui(prod, crt_primes[0]); + } + else + { + fmpz_mat_CRT_ui(Ay, Ay, prod, Ay_mod, 1); + fmpz_mul_ui(prod, prod, crt_primes[i]); + } + } +#endif + + _nmod_mat_set_mod(y_mod, p); + fmpz_mat_sub(d, d, Ay); + fmpz_mat_scalar_divexact_ui(d, d, p); + } + + fmpz_set(mod, ppow); + fmpz_mat_set(X, x); + + nmod_mat_clear(y_mod); + nmod_mat_clear(d_mod); + nmod_mat_clear(Ay_mod); + + for (i = 0; i < num_primes; i++) + nmod_mat_clear(A_mod[i]); + + flint_free(A_mod); + flint_free(crt_primes); + + fmpz_clear(bound); + fmpz_clear(ppow); + fmpz_clear(prod); + + fmpz_mat_clear(x); + fmpz_mat_clear(y); + fmpz_mat_clear(d); + fmpz_mat_clear(Ay); +} + +int +fmpz_mat_solve_dixon(fmpz_mat_t X, fmpz_t mod, + const fmpz_mat_t A, const fmpz_mat_t B) +{ + nmod_mat_t Ainv; + fmpz_t N, D; + mp_limb_t p; + + if (!fmpz_mat_is_square(A)) + { + flint_printf("Exception (fmpz_mat_solve_dixon). Non-square system matrix.\n"); + abort(); + } + + if (fmpz_mat_is_empty(A) || fmpz_mat_is_empty(B)) + return 1; + + fmpz_init(N); + fmpz_init(D); + fmpz_mat_solve_bound(N, D, A, B); + + nmod_mat_init(Ainv, A->r, A->r, 1); + p = find_good_prime_and_invert(Ainv, A, D); + if (p != 0) + _fmpz_mat_solve_dixon(X, mod, A, B, Ainv, p, N, D); + + nmod_mat_clear(Ainv); + fmpz_clear(N); + fmpz_clear(D); + + return p != 0; +} diff --git a/external/flint-2.4.3/fmpz_mat/solve_fflu.c b/external/flint-2.4.3/fmpz_mat/solve_fflu.c new file mode 100644 index 0000000..327c415 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/solve_fflu.c @@ -0,0 +1,56 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" +#include "perm.h" + +int +fmpz_mat_solve_fflu(fmpz_mat_t X, fmpz_t den, + const fmpz_mat_t A, const fmpz_mat_t B) +{ + fmpz_mat_t LU; + slong dim, *perm; + int result; + + if (fmpz_mat_is_empty(A) || fmpz_mat_is_empty(B)) + { + fmpz_one(den); + return 1; + } + + dim = fmpz_mat_nrows(A); + perm = _perm_init(dim); + fmpz_mat_init_set(LU, A); + result = (fmpz_mat_fflu(LU, den, perm, LU, 1) == dim); + + if (result) + fmpz_mat_solve_fflu_precomp(X, perm, LU, B); + else + fmpz_zero(den); + + _perm_clear(perm); + fmpz_mat_clear(LU); + return result; +} diff --git a/external/flint-2.4.3/fmpz_mat/solve_fflu_precomp.c b/external/flint-2.4.3/fmpz_mat/solve_fflu_precomp.c new file mode 100644 index 0000000..ab6d49e --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/solve_fflu_precomp.c @@ -0,0 +1,97 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +#define XX(ii,jj) fmpz_mat_entry(X,(ii),(jj)) +#define BB(ii,jj) fmpz_mat_entry(B,(ii),(jj)) +#define LU(ii,jj) fmpz_mat_entry(FFLU,(ii),(jj)) + +void +fmpz_mat_set_perm(fmpz_mat_t X, const slong * perm, const fmpz_mat_t B) +{ + if (X == B) + { + /* Not implemented */ + abort(); + } + else + { + slong i, j; + + if (perm == NULL) + abort(); + + for (i = 0; i < fmpz_mat_nrows(B); i++) + for (j = 0; j < fmpz_mat_ncols(B); j++) + fmpz_set(fmpz_mat_entry(X, i, j), + fmpz_mat_entry(B, perm[i], j)); + } +} + +void +fmpz_mat_solve_fflu_precomp(fmpz_mat_t X, + const slong * perm, + const fmpz_mat_t FFLU, const fmpz_mat_t B) +{ + fmpz_t T; + slong i, j, k, m, n; + + n = X->r; + m = X->c; + + fmpz_init(T); + fmpz_mat_set_perm(X, perm, B); + + for (k = 0; k < m; k++) + { + /* Fraction-free forward substitution */ + for (i = 0; i < n - 1; i++) + { + for (j = i + 1; j < n; j++) + { + fmpz_mul(XX(j, k), XX(j, k), LU(i, i)); + fmpz_mul(T, LU(j, i), XX(i, k)); + fmpz_sub(XX(j, k), XX(j, k), T); + if (i > 0) + fmpz_divexact(XX(j, k), XX(j, k), LU(i-1, i-1)); + } + } + + /* Fraction-free back substitution */ + for (i = n - 2; i >= 0; i--) + { + fmpz_mul(XX(i, k), XX(i, k), LU(n-1, n-1)); + for (j = i + 1; j < n; j++) + { + fmpz_mul(T, XX(j, k), LU(i, j)); + fmpz_sub(XX(i, k), XX(i, k), T); + } + fmpz_divexact(XX(i, k), XX(i, k), LU(i, i)); + } + } + + fmpz_clear(T); +} diff --git a/external/flint-2.4.3/fmpz_mat/sqr.c b/external/flint-2.4.3/fmpz_mat/sqr.c new file mode 100644 index 0000000..049db28 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/sqr.c @@ -0,0 +1,69 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 "fmpz_mat.h" + +#define E fmpz_mat_entry + +void +fmpz_mat_sqr(fmpz_mat_t B, const fmpz_mat_t A) +{ + slong n = A->r; + + if (n == 0) + { + return; + } + else if (n == 1) + { + fmpz_mul(E(B, 0, 0), E(A, 0, 0), E(A, 0, 0)); + } + else if (n == 2) + { + fmpz_t t, u; + + fmpz_init(t); + fmpz_init(u); + + fmpz_add(t, E(A, 0, 0), E(A, 1, 1)); + fmpz_mul(u, E(A, 0, 1), E(A, 1, 0)); + + fmpz_mul(E(B, 0, 0), E(A, 0, 0), E(A, 0, 0)); + fmpz_add(E(B, 0, 0), E(B, 0, 0), u); + + fmpz_mul(E(B, 1, 1), E(A, 1, 1), E(A, 1, 1)); + fmpz_add(E(B, 1, 1), E(B, 1, 1), u); + + fmpz_mul(E(B, 0, 1), E(A, 0, 1), t); + fmpz_mul(E(B, 1, 0), E(A, 1, 0), t); + + fmpz_clear(t); + fmpz_clear(u); + } + else + { + fmpz_mat_mul(B, A, A); + } +} diff --git a/external/flint-2.4.3/fmpz_mat/sub.c b/external/flint-2.4.3/fmpz_mat/sub.c new file mode 100644 index 0000000..27f04ad --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/sub.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +void +fmpz_mat_sub(fmpz_mat_t res, const fmpz_mat_t mat1, const fmpz_mat_t mat2) +{ + slong i; + + if (res->c < 1) + return; + + for (i = 0; i < res->r; i++) + _fmpz_vec_sub(res->rows[i], mat1->rows[i], mat2->rows[i], res->c); +} diff --git a/external/flint-2.4.3/fmpz_mat/swap.c b/external/flint-2.4.3/fmpz_mat/swap.c new file mode 100644 index 0000000..10c33cd --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/swap.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +void +fmpz_mat_swap(fmpz_mat_t mat1, fmpz_mat_t mat2) +{ + if (mat1 != mat2) + { + fmpz_mat_struct tmp; + + tmp = *mat1; + *mat1 = *mat2; + *mat2 = tmp; + } +} diff --git a/external/flint-2.4.3/fmpz_mat/test/t-CRT_ui.c b/external/flint-2.4.3/fmpz_mat/test/t-CRT_ui.c new file mode 100644 index 0000000..9070afe --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/test/t-CRT_ui.c @@ -0,0 +1,119 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 William Hart and David Harvey + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mat.h" +#include "nmod_mat.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + flint_printf("CRT_ui...."); + fflush(stdout); + + + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + slong bits, prime_bits, rows, cols, num_primes, j; + fmpz_t mod; + fmpz_mat_t A, B, C; + nmod_mat_t Amod; + mp_limb_t primes[1000]; + + bits = n_randint(state, 500) + 1; + rows = n_randint(state, 10); + cols = n_randint(state, 10); + prime_bits = 1 + n_randint(state, FLINT_BITS - 1); + + fmpz_mat_init(A, rows, cols); + fmpz_mat_init(B, rows, cols); + fmpz_mat_init(C, rows, cols); + + fmpz_mat_randtest(A, state, bits); + + fmpz_init(mod); + num_primes = 0; + primes[0] = n_nextprime(UWORD(1) << prime_bits, 0); + fmpz_set_ui(mod, primes[0]); + + /* + 1 for sign */ + while (fmpz_bits(mod) <= bits + 1) + { + primes[num_primes + 1] = n_nextprime(primes[num_primes], 0); + fmpz_mul_ui(mod, mod, primes[num_primes + 1]); + num_primes++; + } + + num_primes++; + + nmod_mat_init(Amod, rows, cols, primes[0]); + fmpz_mat_get_nmod_mat(Amod, A); + fmpz_mat_set_nmod_mat(B, Amod); + fmpz_set_ui(mod, primes[0]); + + for (j = 1; j < num_primes; j++) + { + nmod_mat_clear(Amod); + nmod_mat_init(Amod, rows, cols, primes[j]); + fmpz_mat_get_nmod_mat(Amod, A); + fmpz_mat_CRT_ui(B, B, mod, Amod, 1); + fmpz_mul_ui(mod, mod, primes[j]); + } + + if (!fmpz_mat_equal(B, A)) + { + flint_printf("FAIL!\n"); + flint_printf("primes: "); + for (j = 0; j < num_primes; j++) + flint_printf("%wu ", primes[j]); + flint_printf("\nA: \n"); + fmpz_mat_print_pretty(A); + flint_printf("\nB: \n"); + fmpz_mat_print_pretty(B); + flint_printf("\n"); + abort(); + } + + nmod_mat_clear(Amod); + fmpz_mat_clear(A); + fmpz_mat_clear(B); + fmpz_mat_clear(C); + fmpz_clear(mod); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mat/test/t-CRT_ui_unsigned.c b/external/flint-2.4.3/fmpz_mat/test/t-CRT_ui_unsigned.c new file mode 100644 index 0000000..fdf41da --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/test/t-CRT_ui_unsigned.c @@ -0,0 +1,118 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 William Hart and David Harvey + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mat.h" +#include "nmod_mat.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + flint_printf("CRT_ui_unsigned...."); + fflush(stdout); + + + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + slong bits, prime_bits, rows, cols, num_primes, j; + fmpz_t mod; + fmpz_mat_t A, B, C; + nmod_mat_t Amod; + mp_limb_t primes[1000]; + + bits = n_randint(state, 500) + 1; + rows = n_randint(state, 10); + cols = n_randint(state, 10); + prime_bits = 1 + n_randint(state, FLINT_BITS - 1); + + fmpz_mat_init(A, rows, cols); + fmpz_mat_init(B, rows, cols); + fmpz_mat_init(C, rows, cols); + + fmpz_mat_randtest_unsigned(A, state, bits); + + fmpz_init(mod); + num_primes = 0; + primes[0] = n_nextprime(UWORD(1) << prime_bits, 0); + fmpz_set_ui(mod, primes[0]); + + while (fmpz_bits(mod) <= bits) + { + primes[num_primes + 1] = n_nextprime(primes[num_primes], 0); + fmpz_mul_ui(mod, mod, primes[num_primes + 1]); + num_primes++; + } + + num_primes++; + + nmod_mat_init(Amod, rows, cols, primes[0]); + fmpz_mat_get_nmod_mat(Amod, A); + fmpz_mat_set_nmod_mat_unsigned(B, Amod); + fmpz_set_ui(mod, primes[0]); + + for (j = 1; j < num_primes; j++) + { + nmod_mat_clear(Amod); + nmod_mat_init(Amod, rows, cols, primes[j]); + fmpz_mat_get_nmod_mat(Amod, A); + fmpz_mat_CRT_ui(B, B, mod, Amod, 0); + fmpz_mul_ui(mod, mod, primes[j]); + } + + if (!fmpz_mat_equal(B, A)) + { + flint_printf("FAIL!\n"); + flint_printf("primes: "); + for (j = 0; j < num_primes; j++) + flint_printf("%wu ", primes[j]); + flint_printf("\nA: \n"); + fmpz_mat_print_pretty(A); + flint_printf("\nB: \n"); + fmpz_mat_print_pretty(B); + flint_printf("\n"); + abort(); + } + + nmod_mat_clear(Amod); + fmpz_mat_clear(A); + fmpz_mat_clear(B); + fmpz_mat_clear(C); + fmpz_clear(mod); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mat/test/t-add_sub.c b/external/flint-2.4.3/fmpz_mat/test/t-add_sub.c new file mode 100644 index 0000000..1ac7fc2 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/test/t-add_sub.c @@ -0,0 +1,81 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mat.h" +#include "ulong_extras.h" + +int +main(void) +{ + slong m, n, rep; + FLINT_TEST_INIT(state); + + flint_printf("add/sub/neg...."); + fflush(stdout); + + + + for (rep = 0; rep < 1000 * flint_test_multiplier(); rep++) + { + fmpz_mat_t A; + fmpz_mat_t B; + fmpz_mat_t C; + + m = n_randint(state, 20); + n = n_randint(state, 20); + + fmpz_mat_init(A, m, n); + fmpz_mat_init(B, m, n); + fmpz_mat_init(C, m, n); + + fmpz_mat_randtest(A, state, 100); + fmpz_mat_randtest(B, state, 100); + + fmpz_mat_neg(C, A); + fmpz_mat_add(A, A, B); + fmpz_mat_sub(A, A, B); + fmpz_mat_neg(A, A); + + if (!fmpz_mat_equal(A, C)) + { + flint_printf("FAIL: matrices not equal!\n"); + abort(); + } + + fmpz_mat_clear(A); + fmpz_mat_clear(B); + fmpz_mat_clear(C); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mat/test/t-charpoly.c b/external/flint-2.4.3/fmpz_mat/test/t-charpoly.c new file mode 100644 index 0000000..fd1d4ca --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/test/t-charpoly.c @@ -0,0 +1,92 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mat.h" +#include "ulong_extras.h" + +int +main(void) +{ + slong m, n, rep; + FLINT_TEST_INIT(state); + + flint_printf("charpoly...."); + fflush(stdout); + + + + for (rep = 0; rep < 1000 * flint_test_multiplier(); rep++) + { + fmpz_mat_t A, B, C, D; + fmpz_poly_t f, g; + + m = n_randint(state, 4); + n = m; + + fmpz_mat_init(A, m, n); + fmpz_mat_init(B, m, n); + fmpz_mat_init(C, m, m); + fmpz_mat_init(D, n, n); + fmpz_poly_init(f); + fmpz_poly_init(g); + + fmpz_mat_randtest(A, state, 10); + fmpz_mat_randtest(B, state, 10); + + fmpz_mat_mul(C, A, B); + fmpz_mat_mul(D, B, A); + + fmpz_mat_charpoly(f, C); + fmpz_mat_charpoly(g, D); + + if (!fmpz_poly_equal(f, g)) + { + flint_printf("FAIL: charpoly(AB) != charpoly(BA).\n"); + flint_printf("Matrix A:\n"), fmpz_mat_print(A), flint_printf("\n"); + flint_printf("Matrix B:\n"), fmpz_mat_print(B), flint_printf("\n"); + flint_printf("cp(AB) = "), fmpz_poly_print_pretty(f, "X"), flint_printf("\n"); + flint_printf("cp(BA) = "), fmpz_poly_print_pretty(g, "X"), flint_printf("\n"); + abort(); + } + + fmpz_mat_clear(A); + fmpz_mat_clear(B); + fmpz_mat_clear(C); + fmpz_mat_clear(D); + fmpz_poly_clear(f); + fmpz_poly_clear(g); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mat/test/t-det.c b/external/flint-2.4.3/fmpz_mat/test/t-det.c new file mode 100644 index 0000000..cd53fa8 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/test/t-det.c @@ -0,0 +1,110 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_mat.h" +#include "ulong_extras.h" + + +int +main(void) +{ + fmpz_mat_t A; + slong i, m; + + fmpz_t det, result; + + FLINT_TEST_INIT(state); + + flint_printf("det...."); + fflush(stdout); + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + m = n_randint(state, 10); + + fmpz_mat_init(A, m, m); + + fmpz_init(det); + fmpz_init(result); + + if (m) + fmpz_randtest(det, state, 30); + else + fmpz_set_ui(det, UWORD(1)); + + fmpz_mat_randdet(A, state, det); + fmpz_mat_randops(A, state, n_randint(state, 2*m*m + 1)); + + fmpz_mat_det(result, A); + + if (!fmpz_equal(det, result)) + { + flint_printf("FAIL:\n"); + flint_printf("wrong determinant!\n"); + fmpz_mat_print_pretty(A), flint_printf("\n"); + flint_printf("expected: "), fmpz_print(det), flint_printf("\n"); + flint_printf("ncomputed: "), fmpz_print(result), flint_printf("\n"); + abort(); + } + + fmpz_mat_clear(A); + fmpz_clear(det); + fmpz_clear(result); + } + + /* Generate nontrivial singular matrices */ + for (i = 0; i < 10000; i++) + { + m = 2 + n_randint(state, 10); + fmpz_mat_init(A, m, m); + fmpz_init(det); + + fmpz_mat_randrank(A, state, 1+n_randint(state, m - 1), 1+n_randint(state, 10)); + fmpz_mat_randops(A, state, n_randint(state, 2*m*m + 1)); + + fmpz_mat_det(det, A); + if (*det) + { + flint_printf("FAIL:\n"); + flint_printf("expected zero determinant!\n"); + fmpz_mat_print_pretty(A), flint_printf("\n"); + abort(); + } + + fmpz_mat_clear(A); + fmpz_clear(det); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mat/test/t-det_bound.c b/external/flint-2.4.3/fmpz_mat/test/t-det_bound.c new file mode 100644 index 0000000..c0e675b --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/test/t-det_bound.c @@ -0,0 +1,82 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_mat.h" +#include "ulong_extras.h" + + +int +main(void) +{ + fmpz_mat_t A; + slong i, m; + + fmpz_t det, bound; + + FLINT_TEST_INIT(state); + + flint_printf("det_bound...."); + fflush(stdout); + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + m = n_randint(state, 10); + + fmpz_mat_init(A, m, m); + + fmpz_init(det); + fmpz_init(bound); + + fmpz_mat_randtest(A, state, 1+n_randint(state,200)); + + fmpz_mat_det(det, A); + fmpz_mat_det_bound(bound, A); + + if (fmpz_cmp(det, bound) > 0) + { + flint_printf("FAIL:\n"); + flint_printf("bound too small!\n"); + fmpz_mat_print_pretty(A), flint_printf("\n"); + flint_printf("det: "), fmpz_print(det), flint_printf("\n"); + flint_printf("bound: "), fmpz_print(bound), flint_printf("\n"); + abort(); + } + + fmpz_clear(det); + fmpz_clear(bound); + fmpz_mat_clear(A); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mat/test/t-det_divisor.c b/external/flint-2.4.3/fmpz_mat/test/t-det_divisor.c new file mode 100644 index 0000000..86ded5b --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/test/t-det_divisor.c @@ -0,0 +1,106 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_mat.h" +#include "ulong_extras.h" + + +int +main(void) +{ + slong i; + int result; + + FLINT_TEST_INIT(state); + + flint_printf("det_divisor...."); + fflush(stdout); + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_mat_t A; + fmpz_t det, d, q, r; + slong m, bits; + + m = n_randint(state, 15); + bits = 1 + n_randint(state, 50); + + fmpz_init(det); + fmpz_init(d); + fmpz_init(q); + fmpz_init(r); + fmpz_mat_init(A, m, m); + + if (i % 3 == 0 && m > 1) + { + /* Generate a nontrivial singular matrix */ + fmpz_mat_randrank(A, state, 1 + n_randint(state, m - 1), bits); + fmpz_mat_randops(A, state, n_randint(state, 2*m*m + 1)); + } + else + { + fmpz_mat_randtest(A, state, bits); + } + + fmpz_mat_det_divisor(d, A); + fmpz_mat_det_bareiss(det, A); + + if (fmpz_is_zero(det) || fmpz_is_zero(d)) + { + result = fmpz_equal(det, d); + } + else + { + fmpz_fdiv_qr(q, r, det, d); + result = fmpz_is_zero(r) && (fmpz_sgn(d) > 0); + } + + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_mat_print_pretty(A), flint_printf("\n"); + flint_printf("det: "); fmpz_print(det); flint_printf("\n"); + flint_printf("d: "); fmpz_print(d); flint_printf("\n"); + abort(); + } + + fmpz_mat_clear(A); + fmpz_clear(det); + fmpz_clear(d); + fmpz_clear(q); + fmpz_clear(r); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mat/test/t-det_modular.c b/external/flint-2.4.3/fmpz_mat/test/t-det_modular.c new file mode 100644 index 0000000..69b12f9 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/test/t-det_modular.c @@ -0,0 +1,107 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_mat.h" +#include "ulong_extras.h" + + +int +main(void) +{ + fmpz_mat_t A; + slong i, m; + + fmpz_t det1, det2; + + FLINT_TEST_INIT(state); + + flint_printf("det_modular...."); + fflush(stdout); + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + int proved = n_randlimb(state) % 2; + m = n_randint(state, 10); + + fmpz_mat_init(A, m, m); + + fmpz_init(det1); + fmpz_init(det2); + + fmpz_mat_randtest(A, state, 1+n_randint(state,200)); + + fmpz_mat_det_bareiss(det1, A); + fmpz_mat_det_modular(det2, A, proved); + + if (!fmpz_equal(det1, det2)) + { + flint_printf("FAIL:\n"); + flint_printf("different determinants!\n"); + fmpz_mat_print_pretty(A), flint_printf("\n"); + flint_printf("det1: "), fmpz_print(det1), flint_printf("\n"); + flint_printf("det2: "), fmpz_print(det2), flint_printf("\n"); + abort(); + } + + fmpz_clear(det1); + fmpz_clear(det2); + fmpz_mat_clear(A); + } + + for (i = 0; i < 10000; i++) + { + int proved = n_randlimb(state) % 2; + m = 2 + n_randint(state, 10); + fmpz_mat_init(A, m, m); + fmpz_init(det2); + + fmpz_mat_randrank(A, state, 1+n_randint(state, m - 1), + 1+n_randint(state, 10)); + fmpz_mat_randops(A, state, n_randint(state, 2*m*m + 1)); + + fmpz_mat_det_modular(det2, A, proved); + if (!fmpz_is_zero(det2)) + { + flint_printf("FAIL:\n"); + flint_printf("expected zero determinant!\n"); + fmpz_mat_print_pretty(A), flint_printf("\n"); + abort(); + } + + fmpz_mat_clear(A); + fmpz_clear(det2); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mat/test/t-det_modular_accelerated.c b/external/flint-2.4.3/fmpz_mat/test/t-det_modular_accelerated.c new file mode 100644 index 0000000..197af9d --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/test/t-det_modular_accelerated.c @@ -0,0 +1,107 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_mat.h" +#include "ulong_extras.h" + + +int +main(void) +{ + fmpz_mat_t A; + slong i, m; + + fmpz_t det1, det2; + + FLINT_TEST_INIT(state); + + flint_printf("det_modular_accelerated...."); + fflush(stdout); + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + int proved = n_randlimb(state) % 2; + m = n_randint(state, 10); + + fmpz_mat_init(A, m, m); + + fmpz_init(det1); + fmpz_init(det2); + + fmpz_mat_randtest(A, state, 1+n_randint(state,200)); + + fmpz_mat_det_bareiss(det1, A); + fmpz_mat_det_modular_accelerated(det2, A, proved); + + if (!fmpz_equal(det1, det2)) + { + flint_printf("FAIL:\n"); + flint_printf("different determinants!\n"); + fmpz_mat_print_pretty(A), flint_printf("\n"); + flint_printf("det1: "), fmpz_print(det1), flint_printf("\n"); + flint_printf("det2: "), fmpz_print(det2), flint_printf("\n"); + abort(); + } + + fmpz_clear(det1); + fmpz_clear(det2); + fmpz_mat_clear(A); + } + + for (i = 0; i < 10000; i++) + { + int proved = n_randlimb(state) % 2; + m = 2 + n_randint(state, 10); + fmpz_mat_init(A, m, m); + fmpz_init(det2); + + fmpz_mat_randrank(A, state, 1+n_randint(state, m - 1), + 1+n_randint(state, 10)); + fmpz_mat_randops(A, state, n_randint(state, 2*m*m + 1)); + + fmpz_mat_det_modular_accelerated(det2, A, proved); + if (!fmpz_is_zero(det2)) + { + flint_printf("FAIL:\n"); + flint_printf("expected zero determinant!\n"); + fmpz_mat_print_pretty(A), flint_printf("\n"); + abort(); + } + + fmpz_mat_clear(A); + fmpz_clear(det2); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mat/test/t-entry.c b/external/flint-2.4.3/fmpz_mat/test/t-entry.c new file mode 100644 index 0000000..350df69 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/test/t-entry.c @@ -0,0 +1,82 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mat.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("entry...."); + fflush(stdout); + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_mat_t a; + slong j, k; + slong rows = n_randint(state, 10); + slong cols = n_randint(state, 10); + + fmpz_mat_init(a, rows, cols); + + for (j = 0; j < rows; j++) + { + for (k = 0; k < cols; k++) + { + fmpz_set_ui(fmpz_mat_entry(a,j,k), 3*j + 7*k); + } + } + + for (j = 0; j < rows; j++) + { + for (k = 0; k < cols; k++) + { + if (fmpz_get_ui(fmpz_mat_entry(a,j,k)) != 3*j + 7*k) + { + flint_printf("FAIL: get/set entry %wd,%wd\n", j, k); + abort(); + } + } + } + + fmpz_mat_clear(a); + } + + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mat/test/t-equal.c b/external/flint-2.4.3/fmpz_mat/test/t-equal.c new file mode 100644 index 0000000..8447296 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/test/t-equal.c @@ -0,0 +1,97 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mat.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + flint_printf("equal...."); + fflush(stdout); + + + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_mat_t A, B, C, D, E; + slong m, n, j; + + m = n_randint(state, 20); + n = n_randint(state, 20); + + fmpz_mat_init(A, m, n); + fmpz_mat_init(B, m, n); + fmpz_mat_init(C, m, n); + fmpz_mat_init(D, m+1, n); + fmpz_mat_init(E, m, n+1); + + if (fmpz_mat_equal(A, D) || fmpz_mat_equal(A, E)) + { + flint_printf("FAIL: different dimensions should not be equal\n"); + abort(); + } + + fmpz_mat_randtest(A, state, 1 + n_randint(state, 100)); + fmpz_mat_set(B, A); + + if (!fmpz_mat_equal(A, B)) + { + flint_printf("FAIL: copied matrices should be equal\n"); + abort(); + } + + if (m && n) + { + j = n_randint(state, m*n); + fmpz_add_ui(A->entries + j, A->entries + j, 1); + + if (fmpz_mat_equal(A, B)) + { + flint_printf("FAIL: modified matrices should not be equal\n"); + abort(); + } + } + + fmpz_mat_clear(A); + fmpz_mat_clear(B); + fmpz_mat_clear(C); + fmpz_mat_clear(D); + fmpz_mat_clear(E); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mat/test/t-get_nmod_mat.c b/external/flint-2.4.3/fmpz_mat/test/t-get_nmod_mat.c new file mode 100644 index 0000000..ec6a3f0 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/test/t-get_nmod_mat.c @@ -0,0 +1,87 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mat.h" +#include "nmod_mat.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("get/set_nmod_mat...."); + fflush(stdout); + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_mat_t A; + nmod_mat_t M, M2; + slong rows, cols; + mp_limb_t mod; + + rows = n_randint(state, 50); + cols = n_randint(state, 50); + + mod = n_randtest_prime(state, 0); + + nmod_mat_init(M, rows, cols, mod); + nmod_mat_init(M2, rows, cols, mod); + fmpz_mat_init(A, rows, cols); + + nmod_mat_randtest(M, state); + + if (i % 2 == 0) + fmpz_mat_set_nmod_mat(A, M); + else + fmpz_mat_set_nmod_mat_unsigned(A, M); + + fmpz_mat_scalar_mul_ui(A, A, UWORD(2)); + nmod_mat_add(M, M, M); + fmpz_mat_get_nmod_mat(M2, A); + + if (!nmod_mat_equal(M, M2)) + { + flint_printf("FAIL!\n"); + abort(); + } + + fmpz_mat_clear(A); + nmod_mat_clear(M); + nmod_mat_clear(M2); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mat/test/t-init_clear.c b/external/flint-2.4.3/fmpz_mat/test/t-init_clear.c new file mode 100644 index 0000000..76e32e9 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/test/t-init_clear.c @@ -0,0 +1,65 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mat.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("init/clear...."); + fflush(stdout); + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_mat_t a; + slong j, k; + slong rows = n_randint(state, 100); + slong cols = n_randint(state, 100); + + fmpz_mat_init(a, rows, cols); + + for (j = 0; j < rows; j++) + for (k = 0; k < cols; k++) + fmpz_zero(a->rows[j] + k); + + fmpz_mat_clear(a); + } + + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mat/test/t-inv.c b/external/flint-2.4.3/fmpz_mat/test/t-inv.c new file mode 100644 index 0000000..9a6de59 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/test/t-inv.c @@ -0,0 +1,148 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_mat.h" +#include "ulong_extras.h" + + +int +main(void) +{ + fmpz_mat_t A, B, C, I; + fmpz_t den; + slong i, j, m, r; + + FLINT_TEST_INIT(state); + + flint_printf("inv...."); + fflush(stdout); + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + m = n_randint(state, 10); + + fmpz_mat_init(A, m, m); + fmpz_mat_init(B, m, m); + fmpz_mat_init(C, m, m); + fmpz_mat_init(I, m, m); + fmpz_init(den); + + for (j = 0; j < m; j++) + fmpz_set_ui(&I->rows[j][j], UWORD(1)); + + /* Verify that A * A^-1 = I for random matrices */ + + fmpz_mat_randrank(A, state, m, 1+n_randint(state, 2)*n_randint(state, 100)); + /* Dense or sparse? */ + if (n_randint(state, 2)) + fmpz_mat_randops(A, state, 1+n_randint(state, 1 + m*m)); + + fmpz_mat_inv(B, den, A); + fmpz_mat_mul(C, A, B); + + _fmpz_vec_scalar_divexact_fmpz(C->entries, C->entries, m*m, den); + + if (!fmpz_mat_equal(C, I)) + { + flint_printf("FAIL:\n"); + flint_printf("A * A^-1 != I!\n"); + flint_printf("A:\n"), fmpz_mat_print_pretty(A), flint_printf("\n"); + flint_printf("A^-1:\n"), fmpz_mat_print_pretty(B), flint_printf("\n"); + flint_printf("den(A^-1) = "), fmpz_print(den), flint_printf("\n"); + flint_printf("A * A^-1:\n"), fmpz_mat_print_pretty(C), flint_printf("\n"); + abort(); + } + + /* Test aliasing */ + fmpz_mat_set(C, A); + fmpz_mat_inv(A, den, A); + fmpz_mat_mul(B, A, C); + _fmpz_vec_scalar_divexact_fmpz(B->entries, B->entries, m*m, den); + + if (!fmpz_mat_equal(B, I)) + { + flint_printf("FAIL:\n"); + flint_printf("aliasing failed!\n"); + fmpz_mat_print(C); flint_printf("\n"); + abort(); + } + + fmpz_mat_clear(A); + fmpz_mat_clear(B); + fmpz_mat_clear(C); + fmpz_mat_clear(I); + fmpz_clear(den); + } + + /* Test singular matrices */ + /* Test singular systems */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + m = 1 + n_randint(state, 10); + r = n_randint(state, m); + + fmpz_mat_init(A, m, m); + fmpz_mat_init(B, m, m); + fmpz_init(den); + + fmpz_mat_randrank(A, state, r, 1+n_randint(state, 2)*n_randint(state, 100)); + + /* Dense */ + if (n_randint(state, 2)) + fmpz_mat_randops(A, state, 1+n_randint(state, 1 + m*m)); + + fmpz_mat_inv(B, den, A); + if (!fmpz_is_zero(den)) + { + flint_printf("FAIL:\n"); + flint_printf("singular system gave nonzero denominator\n"); + abort(); + } + + /* Aliasing */ + fmpz_mat_inv(A, den, A); + if (!fmpz_is_zero(den)) + { + flint_printf("FAIL:\n"); + flint_printf("singular system gave nonzero denominator\n"); + abort(); + } + + fmpz_mat_clear(A); + fmpz_mat_clear(B); + fmpz_clear(den); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mat/test/t-is_empty.c b/external/flint-2.4.3/fmpz_mat/test/t-is_empty.c new file mode 100644 index 0000000..38a4921 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/test/t-is_empty.c @@ -0,0 +1,65 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mat.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("is_empty...."); + fflush(stdout); + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_mat_t A; + slong rows = n_randint(state, 10); + slong cols = n_randint(state, 10); + + fmpz_mat_init(A, rows, cols); + + if (fmpz_mat_is_empty(A) != (rows == 0 || cols == 0)) + { + flint_printf("FAIL!\n"); + abort(); + } + fmpz_mat_clear(A); + } + + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mat/test/t-is_square.c b/external/flint-2.4.3/fmpz_mat/test/t-is_square.c new file mode 100644 index 0000000..1efb7a9 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/test/t-is_square.c @@ -0,0 +1,65 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mat.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("is_square...."); + fflush(stdout); + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_mat_t A; + slong rows = n_randint(state, 10); + slong cols = n_randint(state, 10); + + fmpz_mat_init(A, rows, cols); + + if (fmpz_mat_is_square(A) != (rows == cols)) + { + flint_printf("FAIL!\n"); + abort(); + } + fmpz_mat_clear(A); + } + + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mat/test/t-is_zero.c b/external/flint-2.4.3/fmpz_mat/test/t-is_zero.c new file mode 100644 index 0000000..9734d79 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/test/t-is_zero.c @@ -0,0 +1,76 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mat.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("is_zero...."); + fflush(stdout); + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_mat_t A; + slong rows = n_randint(state, 10); + slong cols = n_randint(state, 10); + + fmpz_mat_init(A, rows, cols); + + if (!fmpz_mat_is_zero(A)) + { + flint_printf("FAIL!\n"); + abort(); + } + + if (rows && cols) + { + fmpz_mat_randrank(A, state, FLINT_MIN(rows, cols), 100); + if (fmpz_mat_is_zero(A)) + { + flint_printf("FAIL!\n"); + abort(); + } + } + + fmpz_mat_clear(A); + } + + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mat/test/t-max_bits.c b/external/flint-2.4.3/fmpz_mat/test/t-max_bits.c new file mode 100644 index 0000000..911781f --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/test/t-max_bits.c @@ -0,0 +1,72 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mat.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" + +int +main(void) +{ + slong m, n, rep, res1, res2; + FLINT_TEST_INIT(state); + + flint_printf("max_bits...."); + fflush(stdout); + + + + for (rep = 0; rep < 100 * flint_test_multiplier(); rep++) + { + fmpz_mat_t A; + + m = n_randint(state, 20); + n = n_randint(state, 20); + + fmpz_mat_init(A, m, n); + fmpz_mat_randtest(A, state, 1 + n_randint(state, 100)); + + res1 = fmpz_mat_max_bits(A); + res2 = _fmpz_vec_max_bits(A->entries, m*n); + + if (res1 != res2) + { + flint_printf("FAIL!\n"); + abort(); + } + + fmpz_mat_clear(A); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mat/test/t-mul.c b/external/flint-2.4.3/fmpz_mat/test/t-mul.c new file mode 100644 index 0000000..bfec7c6 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/test/t-mul.c @@ -0,0 +1,92 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_mat.h" +#include "ulong_extras.h" + +int main(void) +{ + fmpz_mat_t A, B, C, D; + slong i; + FLINT_TEST_INIT(state); + + flint_printf("mul...."); + fflush(stdout); + + + + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + slong m, n, k; + + m = n_randint(state, 50); + n = n_randint(state, 50); + k = n_randint(state, 50); + + fmpz_mat_init(A, m, n); + fmpz_mat_init(B, n, k); + fmpz_mat_init(C, m, k); + fmpz_mat_init(D, m, k); + + fmpz_mat_randtest(A, state, n_randint(state, 200) + 1); + fmpz_mat_randtest(B, state, n_randint(state, 200) + 1); + + /* Make sure noise in the output is ok */ + fmpz_mat_randtest(C, state, n_randint(state, 200) + 1); + + fmpz_mat_mul(C, A, B); + fmpz_mat_mul_classical_inline(D, A, B); + + if (!fmpz_mat_equal(C, D)) + { + flint_printf("FAIL: results not equal\n"); + abort(); + } + + fmpz_mat_mul(A, A, B); + + if (!fmpz_mat_equal(A, C)) + { + flint_printf("FAIL: aliasing failed\n"); + abort(); + } + + fmpz_mat_clear(A); + fmpz_mat_clear(B); + fmpz_mat_clear(C); + fmpz_mat_clear(D); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mat/test/t-mul_classical.c b/external/flint-2.4.3/fmpz_mat/test/t-mul_classical.c new file mode 100644 index 0000000..aa68a81 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/test/t-mul_classical.c @@ -0,0 +1,84 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_mat.h" +#include "ulong_extras.h" + +int main(void) +{ + fmpz_mat_t A, B, C, D; + slong i; + FLINT_TEST_INIT(state); + + flint_printf("mul_classical...."); + fflush(stdout); + + + + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + slong m, n, k; + + m = n_randint(state, 50); + n = n_randint(state, 50); + k = n_randint(state, 50); + + fmpz_mat_init(A, m, n); + fmpz_mat_init(B, n, k); + fmpz_mat_init(C, m, k); + fmpz_mat_init(D, m, k); + + fmpz_mat_randtest(A, state, n_randint(state, 200) + 1); + fmpz_mat_randtest(B, state, n_randint(state, 200) + 1); + + /* Make sure noise in the output is ok */ + fmpz_mat_randtest(C, state, n_randint(state, 200) + 1); + + fmpz_mat_mul_classical(C, A, B); + fmpz_mat_mul_classical_inline(D, A, B); + + if (!fmpz_mat_equal(C, D)) + { + flint_printf("FAIL: results not equal\n"); + abort(); + } + + fmpz_mat_clear(A); + fmpz_mat_clear(B); + fmpz_mat_clear(C); + fmpz_mat_clear(D); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mat/test/t-mul_multi_mod.c b/external/flint-2.4.3/fmpz_mat/test/t-mul_multi_mod.c new file mode 100644 index 0000000..325fc86 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/test/t-mul_multi_mod.c @@ -0,0 +1,84 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_mat.h" +#include "ulong_extras.h" + +int main(void) +{ + fmpz_mat_t A, B, C, D; + slong i; + FLINT_TEST_INIT(state); + + flint_printf("mul_multi_mod...."); + fflush(stdout); + + + + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + slong m, n, k; + + m = n_randint(state, 50); + n = n_randint(state, 50); + k = n_randint(state, 50); + + fmpz_mat_init(A, m, n); + fmpz_mat_init(B, n, k); + fmpz_mat_init(C, m, k); + fmpz_mat_init(D, m, k); + + fmpz_mat_randtest(A, state, n_randint(state, 200) + 1); + fmpz_mat_randtest(B, state, n_randint(state, 200) + 1); + + /* Make sure noise in the output is ok */ + fmpz_mat_randtest(C, state, n_randint(state, 200) + 1); + + fmpz_mat_mul_classical_inline(C, A, B); + fmpz_mat_mul_multi_mod(D, A, B); + + if (!fmpz_mat_equal(C, D)) + { + flint_printf("FAIL: results not equal\n"); + abort(); + } + + fmpz_mat_clear(A); + fmpz_mat_clear(B); + fmpz_mat_clear(C); + fmpz_mat_clear(D); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mat/test/t-multi_CRT_ui.c b/external/flint-2.4.3/fmpz_mat/test/t-multi_CRT_ui.c new file mode 100644 index 0000000..0edf3b9 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/test/t-multi_CRT_ui.c @@ -0,0 +1,112 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 William Hart and David Harvey + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mat.h" +#include "nmod_mat.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + flint_printf("multi_CRT_ui...."); + fflush(stdout); + + + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + slong bits, prime_bits, rows, cols, num_primes, j; + fmpz_t mod; + fmpz_mat_t A, B, C; + nmod_mat_t Amod[1000]; + mp_limb_t primes[1000]; + + bits = n_randint(state, 500) + 1; + rows = n_randint(state, 10); + cols = n_randint(state, 10); + prime_bits = 1 + n_randint(state, FLINT_BITS - 1); + + fmpz_mat_init(A, rows, cols); + fmpz_mat_init(B, rows, cols); + fmpz_mat_init(C, rows, cols); + + fmpz_mat_randtest(A, state, bits); + + fmpz_init(mod); + num_primes = 0; + primes[0] = n_nextprime(UWORD(1) << prime_bits, 0); + fmpz_set_ui(mod, primes[0]); + + /* + 1 for sign */ + while (fmpz_bits(mod) <= bits + 1) + { + primes[num_primes + 1] = n_nextprime(primes[num_primes], 0); + fmpz_mul_ui(mod, mod, primes[num_primes + 1]); + num_primes++; + } + + num_primes++; + + for (j = 0; j < num_primes; j++) + nmod_mat_init(Amod[j], rows, cols, primes[j]); + + fmpz_mat_multi_mod_ui(Amod, num_primes, A); + fmpz_mat_multi_CRT_ui(B, Amod, num_primes, 1); + + if (!fmpz_mat_equal(B, A)) + { + flint_printf("FAIL!\n"); + flint_printf("primes: "); + for (j = 0; j < num_primes; j++) + flint_printf("%wu ", primes[j]); + flint_printf("\nA: \n"); + fmpz_mat_print_pretty(A); + flint_printf("\nB: \n"); + fmpz_mat_print_pretty(B); + flint_printf("\n"); + abort(); + } + + for (j = 0; j < num_primes; j++) + nmod_mat_clear(Amod[j]); + fmpz_mat_clear(A); + fmpz_mat_clear(B); + fmpz_mat_clear(C); + fmpz_clear(mod); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mat/test/t-multi_CRT_ui_unsigned.c b/external/flint-2.4.3/fmpz_mat/test/t-multi_CRT_ui_unsigned.c new file mode 100644 index 0000000..b5eb45b --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/test/t-multi_CRT_ui_unsigned.c @@ -0,0 +1,111 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 William Hart and David Harvey + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mat.h" +#include "nmod_mat.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + flint_printf("multi_CRT_ui_unsigned...."); + fflush(stdout); + + + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + slong bits, prime_bits, rows, cols, num_primes, j; + fmpz_t mod; + fmpz_mat_t A, B, C; + nmod_mat_t Amod[1000]; + mp_limb_t primes[1000]; + + bits = n_randint(state, 500) + 1; + rows = n_randint(state, 10); + cols = n_randint(state, 10); + prime_bits = 1 + n_randint(state, FLINT_BITS - 1); + + fmpz_mat_init(A, rows, cols); + fmpz_mat_init(B, rows, cols); + fmpz_mat_init(C, rows, cols); + + fmpz_mat_randtest_unsigned(A, state, bits); + + fmpz_init(mod); + num_primes = 0; + primes[0] = n_nextprime(UWORD(1) << prime_bits, 0); + fmpz_set_ui(mod, primes[0]); + + while (fmpz_bits(mod) <= bits) + { + primes[num_primes + 1] = n_nextprime(primes[num_primes], 0); + fmpz_mul_ui(mod, mod, primes[num_primes + 1]); + num_primes++; + } + + num_primes++; + + for (j = 0; j < num_primes; j++) + nmod_mat_init(Amod[j], rows, cols, primes[j]); + + fmpz_mat_multi_mod_ui(Amod, num_primes, A); + fmpz_mat_multi_CRT_ui(B, Amod, num_primes, 0); + + if (!fmpz_mat_equal(B, A)) + { + flint_printf("FAIL!\n"); + flint_printf("primes: "); + for (j = 0; j < num_primes; j++) + flint_printf("%wu ", primes[j]); + flint_printf("\nA: \n"); + fmpz_mat_print_pretty(A); + flint_printf("\nB: \n"); + fmpz_mat_print_pretty(B); + flint_printf("\n"); + abort(); + } + + for (j = 0; j < num_primes; j++) + nmod_mat_clear(Amod[j]); + fmpz_mat_clear(A); + fmpz_mat_clear(B); + fmpz_mat_clear(C); + fmpz_clear(mod); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mat/test/t-nullspace.c b/external/flint-2.4.3/fmpz_mat/test/t-nullspace.c new file mode 100644 index 0000000..2321849 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/test/t-nullspace.c @@ -0,0 +1,108 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_mat.h" +#include "ulong_extras.h" + + +int +main(void) +{ + fmpz_mat_t A, B, ker; + slong i, m, n, b, d, r, nullity, nulrank; + + FLINT_TEST_INIT(state); + + flint_printf("nullspace...."); + fflush(stdout); + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + m = n_randint(state, 10); + n = n_randint(state, 10); + + for (r = 0; r <= FLINT_MIN(m,n); r++) + { + b = 1 + n_randint(state, 10) * n_randint(state, 10); + d = n_randint(state, 2*m*n + 1); + + fmpz_mat_init(A, m, n); + fmpz_mat_init(ker, n, n); + fmpz_mat_init(B, m, n); + + fmpz_mat_randrank(A, state, r, b); + /* Densify */ + if (n_randlimb(state) % 2) + fmpz_mat_randops(A, state, d); + + nullity = fmpz_mat_nullspace(ker, A); + nulrank = fmpz_mat_rank(ker); + + if (nullity != nulrank) + { + flint_printf("FAIL:\n"); + flint_printf("rank(ker) != nullity!\n"); + fmpz_mat_print_pretty(A); + flint_printf("\n"); + abort(); + } + + if (nullity + r != n) + { + flint_printf("FAIL:\n"); + flint_printf("nullity + rank != n\n"); + fmpz_mat_print_pretty(A); + flint_printf("\n"); + abort(); + } + + fmpz_mat_mul(B, A, ker); + + if (fmpz_mat_rank(B) != 0) + { + flint_printf("FAIL:\n"); + flint_printf("A * ker != 0\n"); + fmpz_mat_print_pretty(A); + flint_printf("\n"); + abort(); + } + + fmpz_mat_clear(A); + fmpz_mat_clear(ker); + fmpz_mat_clear(B); + } + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mat/test/t-one.c b/external/flint-2.4.3/fmpz_mat/test/t-one.c new file mode 100644 index 0000000..00a03fc --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/test/t-one.c @@ -0,0 +1,76 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mat.h" +#include "ulong_extras.h" + +int +main(void) +{ + slong m, n, i, j, rep; + FLINT_TEST_INIT(state); + + flint_printf("one...."); + fflush(stdout); + + + + for (rep = 0; rep < 100 * flint_test_multiplier(); rep++) + { + fmpz_mat_t A; + + m = n_randint(state, 20); + n = n_randint(state, 20); + + fmpz_mat_init(A, m, n); + + fmpz_mat_randtest(A, state, 100); + fmpz_mat_one(A); + + for (i = 0; i < m; i++) + { + for (j = 0; j < n; j++) + { + if (fmpz_cmp_ui(fmpz_mat_entry(A,i,j), i == j) != 0) + { + flint_printf("FAIL: nonzero entry\n"); + abort(); + } + } + } + + fmpz_mat_clear(A); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mat/test/t-pow.c b/external/flint-2.4.3/fmpz_mat/test/t-pow.c new file mode 100644 index 0000000..5561f8c --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/test/t-pow.c @@ -0,0 +1,93 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_mat.h" +#include "ulong_extras.h" + +int main(void) +{ + slong i; + FLINT_TEST_INIT(state); + + flint_printf("pow...."); + fflush(stdout); + + + + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_mat_t A, B, C; + slong i, n; + ulong e; + + n = n_randint(state, 10); + e = n_randint(state, 20); + + fmpz_mat_init(A, n, n); + fmpz_mat_init(B, n, n); + fmpz_mat_init(C, n, n); + + fmpz_mat_randtest(A, state, n_randint(state, 200) + 1); + fmpz_mat_randtest(B, state, n_randint(state, 200) + 1); + + /* Make sure noise in the output is ok */ + fmpz_mat_randtest(B, state, n_randint(state, 200) + 1); + + fmpz_mat_pow(B, A, e); + + fmpz_mat_one(C); + for (i = 0; i < e; i++) + fmpz_mat_mul(C, C, A); + + if (!fmpz_mat_equal(C, B)) + { + flint_printf("FAIL: results not equal\n"); + abort(); + } + + fmpz_mat_pow(A, A, e); + + if (!fmpz_mat_equal(A, B)) + { + flint_printf("FAIL: aliasing failed\n"); + abort(); + } + + fmpz_mat_clear(A); + fmpz_mat_clear(B); + fmpz_mat_clear(C); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mat/test/t-print_read.c b/external/flint-2.4.3/fmpz_mat/test/t-print_read.c new file mode 100644 index 0000000..fa9630f --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/test/t-print_read.c @@ -0,0 +1,269 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Andy Novocin + +******************************************************************************/ + + +#include +#include +#include +#include +#include + +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mat.h" + +#if !defined (__WIN32) || defined(__CYGWIN__) + +/* + The function fdopen is declared in stdio.h. It is POSIX.1 compliant, + but not ANSI compliant. The following line enables compilation with + the "-ansi" flag. + */ +extern FILE * fdopen(int fildes, const char *mode); + +int main(void) +{ + int i, j, m, n, k = 1000, result; + + FILE *in, *out; + int fd[2]; + pid_t childpid; + + FLINT_TEST_INIT(state); + + flint_printf("print/ read...."); + fflush(stdout); + + /* Randomise k mats, write to and read from a pipe */ + { + fmpz_mat_t *M; + + M = flint_malloc(k * sizeof(fmpz_mat_t)); + for (i = 0; i < k; i++) + { + m = n_randint(state, 10); + n = n_randint(state, 10); + fmpz_mat_init(M[i], m, n); + fmpz_mat_randtest(M[i], state, 100); + } + + if (pipe(fd)) + { + flint_printf("FAIL:\n"); + flint_printf("Failed to set-up the pipe.\n"); + abort(); + } + + if((childpid = fork()) == -1) + { + flint_printf("FAIL:\n"); + flint_printf("Failed to fork the process.\n"); + abort(); + } + + if(childpid == 0) /* Child process */ + { + int r; + + close(fd[0]); + out = fdopen(fd[1], "w"); + if (out == NULL) + { + flint_printf("FAIL:\n"); + flint_printf("Could not open output file at the pipe.\n"); + abort(); + } + + for (j = 0; j < k; j++) + { + r = fmpz_mat_fprint(out, M[j]); + if ((j < k - 1) && (r > 0)) + r = flint_fprintf(out, "\n"); + + if (r <= 0) + { + flint_printf("FAIL:\n"); + flint_printf("Write error.\n"); + abort(); + } + } + + fclose(out); + exit(0); + } + else /* Parent process */ + { + int r; + fmpz_mat_t t; + + close(fd[1]); + in = fdopen(fd[0], "r"); + if (in == NULL) + { + flint_printf("FAIL:\n"); + flint_printf("Could not open input file at the pipe.\n"); + abort(); + } + + for (i = 0; i < k && !feof(in); i++) + { + fmpz_mat_init(t, 0, 0); + + r = fmpz_mat_fread(in, t); + if (r <= 0) + { + flint_printf("FAIL:\n"); + flint_printf("Read error.\n"); + abort(); + } + + result = fmpz_mat_equal(t, M[i]); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("M[i] = "), fmpz_mat_print(M[i]), flint_printf("\n"); + flint_printf("t = "), fmpz_mat_print(t), flint_printf("\n"); + abort(); + } + + fmpz_mat_clear(t); + } + + fclose(in); + } + + if (i != k) + { + flint_printf("FAIL:\n"); + flint_printf("Only %d out of %d objects were processed.\n", i, n); + abort(); + } + + for (i = 0; i < k; i++) + fmpz_mat_clear(M[i]); + flint_free(M); + } + + /* Write bad data to a pipe and read it */ + { + char str[5] = {'b', 'l', 'a', 'h', '\0'}; + + if (pipe(fd)) + { + flint_printf("FAIL:\n"); + flint_printf("Failed to set-up the pipe.\n"); + abort(); + } + + if((childpid = fork()) == -1) + { + flint_printf("FAIL:\n"); + flint_printf("Failed to fork the process.\n"); + abort(); + } + + if(childpid == 0) /* Child process */ + { + int r; + + close(fd[0]); + out = fdopen(fd[1], "w"); + if (out == NULL) + { + flint_printf("FAIL:\n"); + flint_printf("Could not open output file at the pipe.\n"); + abort(); + } + + r = flint_fprintf(out, "blah"); + if (r <= 0) + { + flint_printf("FAIL:\n"); + flint_printf("Write error.\n"); + abort(); + } + + fclose(out); + exit(0); + } + else /* Parent process */ + { + int r; + fmpz_mat_t t; + + close(fd[1]); + in = fdopen(fd[0], "r"); + if (in == NULL) + { + flint_printf("FAIL:\n"); + flint_printf("Could not open input file at the pipe.\n"); + abort(); + } + + fmpz_mat_init(t,0,0); + + i = 0; + while (!feof(in)) + { + r = fmpz_mat_fread(in, t); + if (r > 0) + { + flint_printf("FAIL:\n"); + flint_printf("r = %d\n", r); + abort(); + } + ++i; + } + + fmpz_mat_clear(t); + fclose(in); + } + + /* For {'b','l','a','h','\0'} we expect 5 reads */ + if (i != 5) + { + flint_printf("FAIL:\n"); + flint_printf("Carried out %d reads, but \"%s\" has only 4 characters.\n", i, str); + abort(); + } + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + +#else + +int main(void) +{ + flint_printf("print/ read...."); + fflush(stdout); + flint_printf("SKIPPED\n"); + return EXIT_SUCCESS; +} + +#endif diff --git a/external/flint-2.4.3/fmpz_mat/test/t-rank.c b/external/flint-2.4.3/fmpz_mat/test/t-rank.c new file mode 100644 index 0000000..f99b5df --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/test/t-rank.c @@ -0,0 +1,96 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_mat.h" +#include "ulong_extras.h" + + +int +main(void) +{ + fmpz_mat_t A; + slong i, m, n, b, d, r; + + FLINT_TEST_INIT(state); + + flint_printf("rank...."); + fflush(stdout); + + /* Maximally sparse matrices of given rank */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + m = n_randint(state, 10); + n = n_randint(state, 10); + + for (r = 0; r <= FLINT_MIN(m,n); r++) + { + b = 1 + n_randint(state, 10) * n_randint(state, 10); + d = n_randint(state, 2*m*n + 1); + fmpz_mat_init(A, m, n); + fmpz_mat_randrank(A, state, r, b); + if (r != fmpz_mat_rank(A)) + { + flint_printf("FAIL:\n"); + flint_printf("wrong rank!\n"); + abort(); + } + fmpz_mat_clear(A); + } + } + + /* Dense */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + m = n_randint(state, 10); + n = n_randint(state, 10); + + for (r = 0; r <= FLINT_MIN(m,n); r++) + { + b = 1 + n_randint(state, 10) * n_randint(state, 10); + d = n_randint(state, 2*m*n + 1); + fmpz_mat_init(A, m, n); + fmpz_mat_randrank(A, state, r, b); + fmpz_mat_randops(A, state, d); + if (r != fmpz_mat_rank(A)) + { + flint_printf("FAIL:\n"); + flint_printf("wrong rank!\n"); + abort(); + } + fmpz_mat_clear(A); + } + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mat/test/t-rref.c b/external/flint-2.4.3/fmpz_mat/test/t-rref.c new file mode 100644 index 0000000..6bd3940 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/test/t-rref.c @@ -0,0 +1,192 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010-2012 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_mat.h" +#include "perm.h" +#include "ulong_extras.h" + +/* checks that the rref has the right form */ +int check_rref(const fmpz_mat_t A, const fmpz_t den, slong rank) +{ + slong i, j, k, prev_pivot; + + /* bottom should be zero */ + for (i = rank; i < A->r; i++) + for (j = 0; j < A->c; j++) + if (!fmpz_is_zero(fmpz_mat_entry(A, i, j))) + return 0; + + prev_pivot = -1; + + for (i = 0; i < rank; i++) + { + for (j = 0; j < A->c; j++) + { + if (!fmpz_is_zero(fmpz_mat_entry(A, i, j))) + { + /* pivot should have a higher column index than previous */ + if (j <= prev_pivot) + return 0; + + /* column should be 0 ... 0 1 0 ... 0 */ + for (k = 0; k < rank; k++) + { + if (i == k && !fmpz_equal(fmpz_mat_entry(A, k, j), den)) + return 0; + if (i != k && !fmpz_is_zero(fmpz_mat_entry(A, k, j))) + return 0; + } + + prev_pivot = j; + break; + } + } + } + + return 1; +} + +int +main(void) +{ + slong iter; + FLINT_TEST_INIT(state); + + flint_printf("rref...."); + fflush(stdout); + + + + for (iter = 0; iter < 10000 * flint_test_multiplier(); iter++) + { + fmpz_mat_t A, R, B, R2; + fmpz_t den, c, den2; + slong j, k, m, n, b, d, r, rank1, rank2; + slong *perm; + int equal; + + m = n_randint(state, 10); + n = n_randint(state, 10); + r = n_randint(state, FLINT_MIN(m, n) + 1); + + fmpz_mat_init(A, m, n); + fmpz_mat_init(R, m, n); + fmpz_mat_init(B, 2 * m, n); + fmpz_mat_init(R2, 2 * m, n); + + fmpz_init(c); + fmpz_init(den); + fmpz_init(den2); + + perm = _perm_init(2 * m); + + /* sparse */ + b = 1 + n_randint(state, 10) * n_randint(state, 10); + d = n_randint(state, 2*m*n + 1); + fmpz_mat_randrank(A, state, r, b); + + /* dense */ + if (n_randint(state, 2)) + fmpz_mat_randops(A, state, d); + + rank1 = fmpz_mat_rref(R, den, A); + + if (r != rank1) + { + flint_printf("FAIL:\n"); + flint_printf("wrong rank!\n"); + abort(); + } + + check_rref(R, den, rank1); + + /* Concatenate the original matrix with the rref, scramble the rows, + and check that the rref is the same */ + _perm_randtest(perm, 2 * m, state); + + for (j = 0; j < m; j++) + { + fmpz_randtest_not_zero(c, state, 5); + for (k = 0; k < n; k++) + fmpz_mul(fmpz_mat_entry(B, perm[j], k), fmpz_mat_entry(A, j, k), c); + } + + for (j = 0; j < m; j++) + { + fmpz_randtest_not_zero(c, state, 5); + for (k = 0; k < n; k++) + fmpz_mul(fmpz_mat_entry(B, perm[m + j], k), fmpz_mat_entry(R, j, k), c); + } + + rank2 = fmpz_mat_rref(R2, den2, B); + equal = (rank1 == rank2); + + if (equal) + { + fmpz_mat_scalar_mul_fmpz(R, R, den2); + fmpz_mat_scalar_mul_fmpz(R2, R2, den); + + for (j = 0; j < rank2; j++) + for (k = 0; k < n; k++) + equal = equal && + fmpz_equal(fmpz_mat_entry(R, j, k), fmpz_mat_entry(R2, j, k)); + for (j = rank2; j < 2 * rank2; j++) + for (k = 0; k < n; k++) + equal = equal && fmpz_is_zero(fmpz_mat_entry(R2, j, k)); + } + + if (!equal) + { + flint_printf("FAIL (rank1 = %wd, rank2 = %wd)!\n", rank1, rank2); + fmpz_mat_print_pretty(A); flint_printf("\n\n"); + fmpz_mat_print_pretty(R); flint_printf("\n\n"); + fmpz_mat_print_pretty(R2); flint_printf("\n\n"); + abort(); + } + + fmpz_clear(c); + fmpz_clear(den); + fmpz_clear(den2); + + _perm_clear(perm); + + fmpz_mat_clear(A); + fmpz_mat_clear(R); + fmpz_mat_clear(B); + fmpz_mat_clear(R2); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} + diff --git a/external/flint-2.4.3/fmpz_mat/test/t-rref_mod.c b/external/flint-2.4.3/fmpz_mat/test/t-rref_mod.c new file mode 100644 index 0000000..f66b0ed --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/test/t-rref_mod.c @@ -0,0 +1,172 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_mat.h" +#include "ulong_extras.h" + +static void +check_rref(fmpz_mat_t A) +{ + slong i, j, prev_pivot, prev_row_zero; + + prev_row_zero = 0; + prev_pivot = -1; + + for (i = 0; i < A->r; i++) + { + for (j = 0; j < A->c; j++) + { + /* Found nonzero entry */ + if (!fmpz_is_zero(A->rows[i] + j)) + { + if (prev_row_zero) + { + flint_printf("nonzero row after zero row\n"); + abort(); + } + + if (j <= prev_pivot) + { + flint_printf("pivot not strictly to the right of previous\n"); + abort(); + } + + prev_pivot = j; + break; + } + + prev_row_zero = (j + 1 == A->c); + } + } +} + + +int +main(void) +{ + fmpz_mat_t A; + fmpz_t p; + slong i, j, k, m, n, b, d, r, rank; + slong *perm; + + FLINT_TEST_INIT(state); + + flint_printf("rref_mod...."); + fflush(stdout); + + /* Maximally sparse matrices of given rank */ + for (i = 0; i < 10000; i++) + { + m = n_randint(state, 10); + n = n_randint(state, 10); + perm = flint_malloc(FLINT_MAX(1, m) * sizeof(slong)); + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + + for (r = 0; r <= FLINT_MIN(m, n); r++) + { + b = 1 + n_randint(state, 10) * n_randint(state, 10); + + fmpz_mat_init(A, m, n); + + fmpz_mat_randrank(A, state, r, b); + + for (j = 0; j < m; j++) + for (k = 0; k < n; k++) + fmpz_mod(fmpz_mat_entry(A, j, k), fmpz_mat_entry(A, j, k), + p); + + rank = fmpz_mat_rref_mod(perm, A, p); + + if (r < rank) + { + flint_printf("FAIL:\n"); + flint_printf("wrong rank!\n"); + abort(); + } + + check_rref(A); + + fmpz_mat_clear(A); + } + + fmpz_clear(p); + flint_free(perm); + } + + /* Dense */ + for (i = 0; i < 10000; i++) + { + m = n_randint(state, 10); + n = n_randint(state, 10); + perm = flint_malloc(FLINT_MAX(1, m) * sizeof(slong)); + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + + for (r = 0; r <= FLINT_MIN(m, n); r++) + { + b = 1 + n_randint(state, 10) * n_randint(state, 10); + d = n_randint(state, 2 * m * n + 1); + + fmpz_mat_init(A, m, n); + fmpz_mat_randrank(A, state, r, b); + + fmpz_mat_randops(A, state, d); + + for (j = 0; j < m; j++) + for (k = 0; k < n; k++) + fmpz_mod(fmpz_mat_entry(A, j, k), fmpz_mat_entry(A, j, k), + p); + + rank = fmpz_mat_rref_mod(perm, A, p); + + if (r < rank) + { + flint_printf("FAIL:\n"); + flint_printf("wrong rank!\n"); + abort(); + } + + check_rref(A); + + fmpz_mat_clear(A); + } + + fmpz_clear(p); + flint_free(perm); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mat/test/t-scalar_addmul_fmpz.c b/external/flint-2.4.3/fmpz_mat/test/t-scalar_addmul_fmpz.c new file mode 100644 index 0000000..edd585c --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/test/t-scalar_addmul_fmpz.c @@ -0,0 +1,85 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mat.h" +#include "nmod_mat.h" +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("scalar_add/submul_fmpz...."); + fflush(stdout); + + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_mat_t A, B, C; + slong rows, cols; + fmpz_t c; + + rows = n_randint(state, 10); + cols = n_randint(state, 10); + + fmpz_mat_init(A, rows, cols); + fmpz_mat_init(B, rows, cols); + fmpz_mat_init(C, rows, cols); + fmpz_init(c); + + fmpz_randtest(c, state, 100); + fmpz_mat_randtest(A, state, 100); + fmpz_mat_randtest(B, state, 100); + fmpz_mat_set(C, B); + + fmpz_mat_scalar_addmul_fmpz(B, A, c); + fmpz_mat_scalar_submul_fmpz(B, A, c); + + if (!fmpz_mat_equal(B, C)) + { + flint_printf("FAIL!\n"); + abort(); + } + + fmpz_mat_clear(A); + fmpz_mat_clear(B); + fmpz_mat_clear(C); + fmpz_clear(c); + } + + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mat/test/t-scalar_addmul_nmod_mat_fmpz.c b/external/flint-2.4.3/fmpz_mat/test/t-scalar_addmul_nmod_mat_fmpz.c new file mode 100644 index 0000000..66dd5ec --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/test/t-scalar_addmul_nmod_mat_fmpz.c @@ -0,0 +1,91 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mat.h" +#include "nmod_mat.h" +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("scalar_add/submul_nmod_mat_fmpz...."); + fflush(stdout); + + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_mat_t A, B, C; + nmod_mat_t M; + slong rows, cols; + fmpz_t c; + ulong mod; + + rows = n_randint(state, 10); + cols = n_randint(state, 10); + mod = n_randtest_prime(state, 0); + + fmpz_mat_init(A, rows, cols); + fmpz_mat_init(B, rows, cols); + fmpz_mat_init(C, rows, cols); + nmod_mat_init(M, rows, cols, mod); + fmpz_init(c); + + fmpz_randtest(c, state, 100); + nmod_mat_randtest(M, state); + fmpz_mat_set_nmod_mat_unsigned(A, M); + + fmpz_mat_randtest(B, state, 100); + fmpz_mat_set(C, B); + + fmpz_mat_scalar_addmul_nmod_mat_fmpz(B, M, c); + fmpz_mat_scalar_addmul_fmpz(C, A, c); + + if (!fmpz_mat_equal(B, C)) + { + flint_printf("FAIL!\n"); + abort(); + } + + fmpz_mat_clear(A); + fmpz_mat_clear(B); + fmpz_mat_clear(C); + nmod_mat_clear(M); + fmpz_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mat/test/t-scalar_addmul_nmod_mat_ui.c b/external/flint-2.4.3/fmpz_mat/test/t-scalar_addmul_nmod_mat_ui.c new file mode 100644 index 0000000..f126920 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/test/t-scalar_addmul_nmod_mat_ui.c @@ -0,0 +1,90 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mat.h" +#include "nmod_mat.h" +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("scalar_add/submul_nmod_mat_ui...."); + fflush(stdout); + + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_mat_t A, B, C; + nmod_mat_t M; + slong rows, cols; + ulong c; + ulong mod; + + rows = n_randint(state, 10); + cols = n_randint(state, 10); + mod = n_randtest_prime(state, 0); + + fmpz_mat_init(A, rows, cols); + fmpz_mat_init(B, rows, cols); + fmpz_mat_init(C, rows, cols); + nmod_mat_init(M, rows, cols, mod); + c = n_randtest(state); + + nmod_mat_randtest(M, state); + fmpz_mat_set_nmod_mat_unsigned(A, M); + + fmpz_mat_randtest(B, state, 100); + fmpz_mat_set(C, B); + + fmpz_mat_scalar_addmul_nmod_mat_ui(B, M, c); + fmpz_mat_scalar_addmul_ui(C, A, c); + + if (!fmpz_mat_equal(B, C)) + { + flint_printf("FAIL!\n"); + abort(); + } + + fmpz_mat_clear(A); + fmpz_mat_clear(B); + fmpz_mat_clear(C); + nmod_mat_clear(M); + } + + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mat/test/t-scalar_addmul_si.c b/external/flint-2.4.3/fmpz_mat/test/t-scalar_addmul_si.c new file mode 100644 index 0000000..031e7e2 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/test/t-scalar_addmul_si.c @@ -0,0 +1,84 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mat.h" +#include "nmod_mat.h" +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("scalar_add/submul_si...."); + fflush(stdout); + + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_mat_t A, B, C; + slong rows, cols; + slong c; + + rows = n_randint(state, 10); + cols = n_randint(state, 10); + + fmpz_mat_init(A, rows, cols); + fmpz_mat_init(B, rows, cols); + fmpz_mat_init(C, rows, cols); + + c = z_randtest(state); + + fmpz_mat_randtest(A, state, 100); + fmpz_mat_randtest(B, state, 100); + fmpz_mat_set(C, B); + + fmpz_mat_scalar_addmul_si(B, A, c); + fmpz_mat_scalar_submul_si(B, A, c); + + if (!fmpz_mat_equal(B, C)) + { + flint_printf("FAIL!\n"); + abort(); + } + + fmpz_mat_clear(A); + fmpz_mat_clear(B); + fmpz_mat_clear(C); + } + + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mat/test/t-scalar_addmul_ui.c b/external/flint-2.4.3/fmpz_mat/test/t-scalar_addmul_ui.c new file mode 100644 index 0000000..c4def1d --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/test/t-scalar_addmul_ui.c @@ -0,0 +1,84 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mat.h" +#include "nmod_mat.h" +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("scalar_add/submul_ui...."); + fflush(stdout); + + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_mat_t A, B, C; + slong rows, cols; + ulong c; + + rows = n_randint(state, 10); + cols = n_randint(state, 10); + + fmpz_mat_init(A, rows, cols); + fmpz_mat_init(B, rows, cols); + fmpz_mat_init(C, rows, cols); + + c = n_randtest(state); + + fmpz_mat_randtest(A, state, 100); + fmpz_mat_randtest(B, state, 100); + fmpz_mat_set(C, B); + + fmpz_mat_scalar_addmul_ui(B, A, c); + fmpz_mat_scalar_submul_ui(B, A, c); + + if (!fmpz_mat_equal(B, C)) + { + flint_printf("FAIL!\n"); + abort(); + } + + fmpz_mat_clear(A); + fmpz_mat_clear(B); + fmpz_mat_clear(C); + } + + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mat/test/t-scalar_mod_fmpz.c b/external/flint-2.4.3/fmpz_mat/test/t-scalar_mod_fmpz.c new file mode 100644 index 0000000..bd3981e --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/test/t-scalar_mod_fmpz.c @@ -0,0 +1,84 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mat.h" +#include "nmod_mat.h" +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("scalar_mod_fmpz...."); + fflush(stdout); + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_mat_t A, Amod; + fmpz_t mod; + + slong rows, cols; + + rows = n_randint(state, 20); + cols = n_randint(state, 20); + + fmpz_mat_init(A, rows, cols); + fmpz_mat_init(Amod, rows, cols); + fmpz_init(mod); + + fmpz_randtest_not_zero(mod, state, 100); + + fmpz_mat_randtest(A, state, 100); + fmpz_mat_randtest(Amod, state, 100); + + fmpz_mat_scalar_mod_fmpz(Amod, A, mod); + fmpz_mat_scalar_mod_fmpz(A, A, mod); + + if (!fmpz_mat_equal(A, Amod)) + { + flint_printf("FAIL: aliasing!\n"); + abort(); + } + + fmpz_mat_clear(A); + fmpz_mat_clear(Amod); + fmpz_clear(mod); + } + + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mat/test/t-scalar_mul_fmpz.c b/external/flint-2.4.3/fmpz_mat/test/t-scalar_mul_fmpz.c new file mode 100644 index 0000000..b7ed1a9 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/test/t-scalar_mul_fmpz.c @@ -0,0 +1,95 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mat.h" +#include "nmod_mat.h" +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("scalar_mul/divexact_fmpz...."); + fflush(stdout); + + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_mat_t C, B, A; + slong rows, cols; + fmpz_t c; + + rows = n_randint(state, 10); + cols = n_randint(state, 10); + + fmpz_mat_init(A, rows, cols); + fmpz_mat_init(B, rows, cols); + fmpz_mat_init(C, rows, cols); + fmpz_init(c); + + fmpz_randtest(c, state, 100); + fmpz_mat_randtest(A, state, 100); + + fmpz_mat_scalar_mul_fmpz(B, A, c); + + if (fmpz_is_zero(c)) + { + if (!fmpz_mat_is_zero(B)) + { + flint_printf("FAIL!\n"); + abort(); + } + } + else + { + fmpz_mat_scalar_divexact_fmpz(C, B, c); + + if (!fmpz_mat_equal(C, A)) + { + flint_printf("FAIL!\n"); + abort(); + } + } + + fmpz_mat_clear(A); + fmpz_mat_clear(B); + fmpz_mat_clear(C); + fmpz_clear(c); + } + + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mat/test/t-scalar_mul_si.c b/external/flint-2.4.3/fmpz_mat/test/t-scalar_mul_si.c new file mode 100644 index 0000000..12a6cc4 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/test/t-scalar_mul_si.c @@ -0,0 +1,93 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mat.h" +#include "nmod_mat.h" +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("scalar_mul/divexact_si...."); + fflush(stdout); + + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_mat_t C, B, A; + slong rows, cols; + slong c; + + rows = n_randint(state, 10); + cols = n_randint(state, 10); + + fmpz_mat_init(A, rows, cols); + fmpz_mat_init(B, rows, cols); + fmpz_mat_init(C, rows, cols); + + c = z_randtest(state); + fmpz_mat_randtest(A, state, 100); + + fmpz_mat_scalar_mul_si(B, A, c); + + if (c == 0) + { + if (!fmpz_mat_is_zero(B)) + { + flint_printf("FAIL!\n"); + abort(); + } + } + else + { + fmpz_mat_scalar_divexact_si(C, B, c); + + if (!fmpz_mat_equal(C, A)) + { + flint_printf("FAIL!\n"); + abort(); + } + } + + fmpz_mat_clear(A); + fmpz_mat_clear(B); + fmpz_mat_clear(C); + } + + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mat/test/t-scalar_mul_ui.c b/external/flint-2.4.3/fmpz_mat/test/t-scalar_mul_ui.c new file mode 100644 index 0000000..b5a30fb --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/test/t-scalar_mul_ui.c @@ -0,0 +1,92 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mat.h" +#include "nmod_mat.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("scalar_mul/divexact_ui...."); + fflush(stdout); + + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_mat_t C, B, A; + slong rows, cols; + ulong c; + + rows = n_randint(state, 10); + cols = n_randint(state, 10); + + fmpz_mat_init(A, rows, cols); + fmpz_mat_init(B, rows, cols); + fmpz_mat_init(C, rows, cols); + + c = n_randtest(state); + fmpz_mat_randtest(A, state, 100); + + fmpz_mat_scalar_mul_ui(B, A, c); + + if (c == 0) + { + if (!fmpz_mat_is_zero(B)) + { + flint_printf("FAIL!\n"); + abort(); + } + } + else + { + fmpz_mat_scalar_divexact_ui(C, B, c); + + if (!fmpz_mat_equal(C, A)) + { + flint_printf("FAIL!\n"); + abort(); + } + } + + fmpz_mat_clear(A); + fmpz_mat_clear(B); + fmpz_mat_clear(C); + } + + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mat/test/t-solve.c b/external/flint-2.4.3/fmpz_mat/test/t-solve.c new file mode 100644 index 0000000..8528a21 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/test/t-solve.c @@ -0,0 +1,131 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_mat.h" +#include "ulong_extras.h" + + +int +main(void) +{ + fmpz_mat_t A, X, B, AX; + fmpz_t den; + slong i, m, n, r; + int success; + + FLINT_TEST_INIT(state); + + flint_printf("solve...."); + fflush(stdout); + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + m = n_randint(state, 10); + n = n_randint(state, 10); + + fmpz_mat_init(A, m, m); + fmpz_mat_init(B, m, n); + fmpz_mat_init(X, m, n); + fmpz_mat_init(AX, m, n); + fmpz_init(den); + + fmpz_mat_randrank(A, state, m, 1+n_randint(state, 2)*n_randint(state, 100)); + fmpz_mat_randtest(B, state, 1+n_randint(state, 2)*n_randint(state, 100)); + + /* Dense */ + if (n_randint(state, 2)) + fmpz_mat_randops(A, state, 1+n_randint(state, 1 + m*m)); + + success = fmpz_mat_solve(X, den, A, B); + + fmpz_mat_mul(AX, A, X); + fmpz_mat_scalar_divexact_fmpz(AX, AX, den); + + if (!fmpz_mat_equal(AX, B) || !success) + { + flint_printf("FAIL:\n"); + flint_printf("AX != B!\n"); + flint_printf("A:\n"), fmpz_mat_print_pretty(A), flint_printf("\n"); + flint_printf("B:\n"), fmpz_mat_print_pretty(B), flint_printf("\n"); + flint_printf("X:\n"), fmpz_mat_print_pretty(X), flint_printf("\n"); + flint_printf("den(X) = "), fmpz_print(den), flint_printf("\n"); + flint_printf("AX:\n"), fmpz_mat_print_pretty(AX), flint_printf("\n"); + abort(); + } + + fmpz_mat_clear(A); + fmpz_mat_clear(B); + fmpz_mat_clear(X); + fmpz_mat_clear(AX); + fmpz_clear(den); + } + + /* Test singular systems */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + m = 1 + n_randint(state, 10); + n = 1 + n_randint(state, 10); + r = n_randint(state, m); + + fmpz_mat_init(A, m, m); + fmpz_mat_init(B, m, n); + fmpz_mat_init(X, m, n); + fmpz_mat_init(AX, m, n); + fmpz_init(den); + + fmpz_mat_randrank(A, state, r, 1+n_randint(state, 2)*n_randint(state, 100)); + fmpz_mat_randtest(B, state, 1+n_randint(state, 2)*n_randint(state, 100)); + + /* Dense */ + if (n_randint(state, 2)) + fmpz_mat_randops(A, state, 1+n_randint(state, 1 + m*m)); + + success = fmpz_mat_solve(X, den, A, B); + + if (!fmpz_is_zero(den) || success) + { + flint_printf("FAIL:\n"); + flint_printf("singular system gave nonzero determinant\n"); + abort(); + } + + fmpz_mat_clear(A); + fmpz_mat_clear(B); + fmpz_mat_clear(X); + fmpz_mat_clear(AX); + fmpz_clear(den); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mat/test/t-solve_bound.c b/external/flint-2.4.3/fmpz_mat/test/t-solve_bound.c new file mode 100644 index 0000000..9600ed0 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/test/t-solve_bound.c @@ -0,0 +1,123 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_mat.h" +#include "ulong_extras.h" + + +int +main(void) +{ + slong i; + + FLINT_TEST_INIT(state); + + flint_printf("solve_bound...."); + fflush(stdout); + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_mat_t A, B, X; + fmpz_t N, D, den; + slong m, n, b1, b2; + slong j, k; + + b1 = 1 + n_randint(state, 100); + b2 = 1 + n_randint(state, 100); + m = n_randint(state, 20); + n = n_randint(state, 20); + + fmpz_init(den); + fmpz_init(N); + fmpz_init(D); + fmpz_mat_init(A, m, m); + fmpz_mat_init(B, m, n); + fmpz_mat_init(X, m, n); + + fmpz_mat_randrank(A, state, m, b1); + fmpz_mat_randops(A, state, n_randint(state, m)*n_randint(state, m)); + fmpz_mat_randtest(B, state, b2); + + fmpz_mat_solve_bound(N, D, A, B); + fmpz_mat_solve(X, den, A, B); + + if (fmpz_cmpabs(D, den) < 0) + { + flint_printf("FAIL:\n"); + flint_printf("denominator bound:\n"); + fmpz_print(D); + flint_printf("\ndenominator:\n"); + fmpz_print(den); + flint_printf("\n"); + flint_printf("A:\n"); + fmpz_mat_print_pretty(A); + flint_printf("B:\n"); + fmpz_mat_print_pretty(B); + flint_printf("\n"); + abort(); + } + + for (j = 0; j < m; j++) + { + for (k = 0; k < n; k++) + { + if (fmpz_cmpabs(N, fmpz_mat_entry(X, j, k)) < 0) + { + flint_printf("FAIL:\n"); + flint_printf("numerator bound:\n"); + fmpz_print(N); + flint_printf("\nnumerator:\n"); + fmpz_print(fmpz_mat_entry(X, j, k)); + flint_printf("\n"); + flint_printf("A:\n"); + fmpz_mat_print_pretty(A); + flint_printf("B:\n"); + fmpz_mat_print_pretty(B); + flint_printf("\n"); + abort(); + } + } + } + + fmpz_mat_clear(A); + fmpz_mat_clear(B); + fmpz_mat_clear(X); + + fmpz_clear(den); + fmpz_clear(N); + fmpz_clear(D); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mat/test/t-solve_cramer.c b/external/flint-2.4.3/fmpz_mat/test/t-solve_cramer.c new file mode 100644 index 0000000..a87e7ea --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/test/t-solve_cramer.c @@ -0,0 +1,131 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_mat.h" +#include "ulong_extras.h" + + +int +main(void) +{ + fmpz_mat_t A, X, B, AX; + fmpz_t den; + slong i, m, n, r; + int success; + + FLINT_TEST_INIT(state); + + flint_printf("solve_cramer...."); + fflush(stdout); + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + m = n_randint(state, 4); + n = n_randint(state, 10); + + fmpz_mat_init(A, m, m); + fmpz_mat_init(B, m, n); + fmpz_mat_init(X, m, n); + fmpz_mat_init(AX, m, n); + fmpz_init(den); + + fmpz_mat_randrank(A, state, m, 1+n_randint(state, 2)*n_randint(state, 100)); + fmpz_mat_randtest(B, state, 1+n_randint(state, 2)*n_randint(state, 100)); + + /* Dense */ + if (n_randint(state, 2)) + fmpz_mat_randops(A, state, 1+n_randint(state, 1 + m*m)); + + success = fmpz_mat_solve_cramer(X, den, A, B); + + fmpz_mat_mul(AX, A, X); + fmpz_mat_scalar_divexact_fmpz(AX, AX, den); + + if (!fmpz_mat_equal(AX, B) || !success) + { + flint_printf("FAIL:\n"); + flint_printf("AX != B!\n"); + flint_printf("A:\n"), fmpz_mat_print_pretty(A), flint_printf("\n"); + flint_printf("B:\n"), fmpz_mat_print_pretty(B), flint_printf("\n"); + flint_printf("X:\n"), fmpz_mat_print_pretty(X), flint_printf("\n"); + flint_printf("den(X) = "), fmpz_print(den), flint_printf("\n"); + flint_printf("AX:\n"), fmpz_mat_print_pretty(AX), flint_printf("\n"); + abort(); + } + + fmpz_mat_clear(A); + fmpz_mat_clear(B); + fmpz_mat_clear(X); + fmpz_mat_clear(AX); + fmpz_clear(den); + } + + /* Test singular systems */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + m = 1 + n_randint(state, 3); + n = 1 + n_randint(state, 10); + r = n_randint(state, m); + + fmpz_mat_init(A, m, m); + fmpz_mat_init(B, m, n); + fmpz_mat_init(X, m, n); + fmpz_mat_init(AX, m, n); + fmpz_init(den); + + fmpz_mat_randrank(A, state, r, 1+n_randint(state, 2)*n_randint(state, 100)); + fmpz_mat_randtest(B, state, 1+n_randint(state, 2)*n_randint(state, 100)); + + /* Dense */ + if (n_randint(state, 2)) + fmpz_mat_randops(A, state, 1+n_randint(state, 1 + m*m)); + + success = fmpz_mat_solve_cramer(X, den, A, B); + + if (!fmpz_is_zero(den) || success) + { + flint_printf("FAIL:\n"); + flint_printf("singular system gave nonzero determinant\n"); + abort(); + } + + fmpz_mat_clear(A); + fmpz_mat_clear(B); + fmpz_mat_clear(X); + fmpz_mat_clear(AX); + fmpz_clear(den); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mat/test/t-solve_dixon.c b/external/flint-2.4.3/fmpz_mat/test/t-solve_dixon.c new file mode 100644 index 0000000..3915d5b --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/test/t-solve_dixon.c @@ -0,0 +1,134 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_mat.h" +#include "ulong_extras.h" + +int +main(void) +{ + fmpz_mat_t A, X, B, AX, AXm, Bm; + fmpz_t mod; + slong i, m, n, r; + int success; + + FLINT_TEST_INIT(state); + + flint_printf("solve_dixon...."); + fflush(stdout); + + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + m = n_randint(state, 20); + n = n_randint(state, 20); + + fmpz_mat_init(A, m, m); + fmpz_mat_init(B, m, n); + fmpz_mat_init(Bm, m, n); + fmpz_mat_init(X, m, n); + fmpz_mat_init(AX, m, n); + fmpz_mat_init(AXm, m, n); + fmpz_init(mod); + + fmpz_mat_randrank(A, state, m, 1+n_randint(state, 2)*n_randint(state, 100)); + fmpz_mat_randtest(B, state, 1+n_randint(state, 2)*n_randint(state, 100)); + + /* Dense */ + if (n_randint(state, 2)) + fmpz_mat_randops(A, state, 1+n_randint(state, 1 + m*m)); + + success = fmpz_mat_solve_dixon(X, mod, A, B); + + fmpz_mat_set(AXm, X); + + fmpz_mat_mul(AX, A, AXm); + + fmpz_mat_scalar_mod_fmpz(AXm, AX, mod); + fmpz_mat_scalar_mod_fmpz(Bm, B, mod); + + if (!fmpz_mat_equal(AXm, Bm) || !success) + { + flint_printf("FAIL:\n"); + flint_printf("AX != B!\n"); + flint_printf("A:\n"), fmpz_mat_print_pretty(A), flint_printf("\n"); + flint_printf("B:\n"), fmpz_mat_print_pretty(B), flint_printf("\n"); + flint_printf("X:\n"), fmpz_mat_print_pretty(X), flint_printf("\n"); + flint_printf("mod = "), fmpz_print(mod), flint_printf("\n"); + flint_printf("AX:\n"), fmpz_mat_print_pretty(AX), flint_printf("\n"); + abort(); + } + + fmpz_mat_clear(A); + fmpz_mat_clear(B); + fmpz_mat_clear(Bm); + fmpz_mat_clear(X); + fmpz_mat_clear(AX); + fmpz_mat_clear(AXm); + fmpz_clear(mod); + } + + /* Test singular systems */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + m = 1 + n_randint(state, 10); + n = 1 + n_randint(state, 10); + r = n_randint(state, m); + + fmpz_mat_init(A, m, m); + fmpz_mat_init(B, m, n); + fmpz_mat_init(X, m, n); + fmpz_init(mod); + + fmpz_mat_randrank(A, state, r, 1+n_randint(state, 2)*n_randint(state, 100)); + fmpz_mat_randtest(B, state, 1+n_randint(state, 2)*n_randint(state, 100)); + + /* Dense */ + if (n_randint(state, 2)) + fmpz_mat_randops(A, state, 1+n_randint(state, 1 + m*m)); + + if (fmpz_mat_solve_dixon(X, mod, A, B) != 0) + { + flint_printf("FAIL:\n"); + flint_printf("singular system, returned nonzero\n"); + abort(); + } + + fmpz_mat_clear(A); + fmpz_mat_clear(B); + fmpz_mat_clear(X); + fmpz_clear(mod); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mat/test/t-sqr.c b/external/flint-2.4.3/fmpz_mat/test/t-sqr.c new file mode 100644 index 0000000..3a3ba0e --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/test/t-sqr.c @@ -0,0 +1,88 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_mat.h" +#include "ulong_extras.h" + +int main(void) +{ + slong i; + FLINT_TEST_INIT(state); + + flint_printf("sqr...."); + fflush(stdout); + + + + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_mat_t A, B, C; + slong n; + + n = n_randint(state, 20); + + fmpz_mat_init(A, n, n); + fmpz_mat_init(B, n, n); + fmpz_mat_init(C, n, n); + + fmpz_mat_randtest(A, state, n_randint(state, 200) + 1); + fmpz_mat_randtest(B, state, n_randint(state, 200) + 1); + + /* Make sure noise in the output is ok */ + fmpz_mat_randtest(B, state, n_randint(state, 200) + 1); + + fmpz_mat_sqr(B, A); + fmpz_mat_mul_classical(C, A, A); + + if (!fmpz_mat_equal(C, B)) + { + flint_printf("FAIL: results not equal\n"); + abort(); + } + + fmpz_mat_sqr(A, A); + + if (!fmpz_mat_equal(A, B)) + { + flint_printf("FAIL: aliasing failed\n"); + abort(); + } + + fmpz_mat_clear(A); + fmpz_mat_clear(B); + fmpz_mat_clear(C); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mat/test/t-trace.c b/external/flint-2.4.3/fmpz_mat/test/t-trace.c new file mode 100644 index 0000000..52336a9 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/test/t-trace.c @@ -0,0 +1,97 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_mat.h" +#include "ulong_extras.h" + +int +main(void) +{ + slong i; + FLINT_TEST_INIT(state); + + flint_printf("trace...."); + fflush(stdout); + + + + /* Test trace(AB) = trace(BA) */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_mat_t A, B, AB, BA; + fmpz_t trab, trba; + slong m, n; + + m = n_randint(state, 10); + n = n_randint(state, 10); + + fmpz_mat_init(A, m, n); + fmpz_mat_init(B, n, m); + fmpz_mat_init(AB, m, m); + fmpz_mat_init(BA, n, n); + + fmpz_init(trab); + fmpz_init(trba); + + fmpz_mat_randtest(A, state, 1 + n_randint(state, 100)); + fmpz_mat_randtest(B, state, 1 + n_randint(state, 100)); + + fmpz_mat_mul(AB, A, B); + fmpz_mat_mul(BA, B, A); + + fmpz_mat_trace(trab, AB); + fmpz_mat_trace(trba, BA); + + if (!fmpz_equal(trab, trba)) + { + flint_printf("FAIL:\n"); + fmpz_mat_print_pretty(A), flint_printf("\n"); + fmpz_mat_print_pretty(B), flint_printf("\n"); + fmpz_mat_print_pretty(AB), flint_printf("\n"); + fmpz_mat_print_pretty(BA), flint_printf("\n"); + flint_printf("tr(AB): "), fmpz_print(trab), flint_printf("\n"); + flint_printf("tr(BA): "), fmpz_print(trba), flint_printf("\n"); + abort(); + } + + fmpz_mat_clear(A); + fmpz_mat_clear(B); + fmpz_mat_clear(AB); + fmpz_mat_clear(BA); + fmpz_clear(trab); + fmpz_clear(trba); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mat/test/t-transpose.c b/external/flint-2.4.3/fmpz_mat/test/t-transpose.c new file mode 100644 index 0000000..278395b --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/test/t-transpose.c @@ -0,0 +1,103 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mat.h" +#include "ulong_extras.h" + +int +main(void) +{ + slong m, n, rep; + FLINT_TEST_INIT(state); + + flint_printf("transpose...."); + fflush(stdout); + + + + /* Rectangular transpose */ + for (rep = 0; rep < 100 * flint_test_multiplier(); rep++) + { + fmpz_mat_t A, B, C; + + m = n_randint(state, 20); + n = n_randint(state, 20); + + fmpz_mat_init(A, m, n); + fmpz_mat_init(B, n, m); + fmpz_mat_init(C, m, n); + + fmpz_mat_randtest(A, state, 1+n_randint(state, 100)); + fmpz_mat_randtest(B, state, 1+n_randint(state, 100)); + + fmpz_mat_transpose(B, A); + fmpz_mat_transpose(C, B); + + if (!fmpz_mat_equal(C, A)) + { + flint_printf("FAIL: C != A\n"); + abort(); + } + + fmpz_mat_clear(A); + fmpz_mat_clear(B); + fmpz_mat_clear(C); + } + + /* Self-transpose */ + for (rep = 0; rep < 1000; rep++) + { + fmpz_mat_t A, B; + + m = n_randint(state, 20); + + fmpz_mat_init(A, m, m); + fmpz_mat_init(B, m, m); + + fmpz_mat_randtest(A, state, 1+n_randint(state, 100)); + fmpz_mat_set(B, A); + fmpz_mat_transpose(B, B); + fmpz_mat_transpose(B, B); + + if (!fmpz_mat_equal(B, A)) + { + flint_printf("FAIL: B != A\n"); + abort(); + } + + fmpz_mat_clear(A); + fmpz_mat_clear(B); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mat/test/t-zero.c b/external/flint-2.4.3/fmpz_mat/test/t-zero.c new file mode 100644 index 0000000..893ac8a --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/test/t-zero.c @@ -0,0 +1,76 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mat.h" +#include "ulong_extras.h" + +int +main(void) +{ + slong m, n, i, j, rep; + FLINT_TEST_INIT(state); + + flint_printf("zero...."); + fflush(stdout); + + + + for (rep = 0; rep < 100 * flint_test_multiplier(); rep++) + { + fmpz_mat_t A; + + m = n_randint(state, 20); + n = n_randint(state, 20); + + fmpz_mat_init(A, m, n); + + fmpz_mat_randtest(A, state, 100); + fmpz_mat_zero(A); + + for (i = 0; i < m; i++) + { + for (j = 0; j < n; j++) + { + if (!fmpz_is_zero(fmpz_mat_entry(A,i,j))) + { + flint_printf("FAIL: nonzero entry\n"); + abort(); + } + } + } + + fmpz_mat_clear(A); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mat/trace.c b/external/flint-2.4.3/fmpz_mat/trace.c new file mode 100644 index 0000000..ae341b9 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/trace.c @@ -0,0 +1,41 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +void +fmpz_mat_trace(fmpz_t trace, const fmpz_mat_t mat) +{ + slong i, n = fmpz_mat_nrows(mat); + + if (n == 0) + fmpz_zero(trace); + else + { + fmpz_set(trace, fmpz_mat_entry(mat, 0, 0)); + for (i = 1; i < n; i++) + fmpz_add(trace, trace, fmpz_mat_entry(mat, i, i)); + } +} diff --git a/external/flint-2.4.3/fmpz_mat/transpose.c b/external/flint-2.4.3/fmpz_mat/transpose.c new file mode 100644 index 0000000..5c4ab63 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/transpose.c @@ -0,0 +1,56 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +void +fmpz_mat_transpose(fmpz_mat_t B, const fmpz_mat_t A) +{ + fmpz tmp; + slong i, j; + + if (B->r != A->c || B->c != A->r) + { + flint_printf("Exception (fmpz_mat_transpose). Incompatible dimensions.\n"); + abort(); + } + + if (A == B) /* In-place, guaranteed to be square */ + { + for (i = 0; i < A->r - 1; i++) + for (j = i + 1; j < A->c; j++) + { + tmp = A->rows[i][j]; + A->rows[i][j] = A->rows[j][i]; + A->rows[j][i] = tmp; + } + } + else /* Not aliased; general case */ + { + for (i = 0; i < B->r; i++) + for (j = 0; j < B->c; j++) + fmpz_set(&B->rows[i][j], &A->rows[j][i]); + } +} diff --git a/external/flint-2.4.3/fmpz_mat/zero.c b/external/flint-2.4.3/fmpz_mat/zero.c new file mode 100644 index 0000000..8657f80 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mat/zero.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mat.h" + +void +fmpz_mat_zero(fmpz_mat_t mat) +{ + slong i; + + if (mat->c < 1) + return; + + for (i = 0; i < mat->r; i++) + _fmpz_vec_zero(mat->rows[i], mat->c); +} diff --git a/external/flint-2.4.3/fmpz_matxx.h b/external/flint-2.4.3/fmpz_matxx.h new file mode 100644 index 0000000..9cc8b24 --- /dev/null +++ b/external/flint-2.4.3/fmpz_matxx.h @@ -0,0 +1,534 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#ifndef FMPZ_MATXX_H +#define FMPZ_MATXX_H FMPZ_MATXX_H + +#include "fmpz_mat.h" +#include "fmpq_mat.h" // fmpq_mat_get_fmpz_mat_mod_fmpz + +#include "fmpzxx.h" +#include "fmpz_polyxx.h" +#include "permxx.h" + +#include "flintxx/ltuple.h" +#include "flintxx/matrix.h" +#include "flintxx/traits_fwd.h" + +// TODO input and output +// TODO addmul +// TODO nullspace member + +namespace flint { +FLINT_DEFINE_BINOP(det_modular) +FLINT_DEFINE_BINOP(det_modular_accelerated) +FLINT_DEFINE_BINOP(mul_multi_mod) +FLINT_DEFINE_BINOP(solve_dixon) +FLINT_DEFINE_BINOP(solve_cramer) +FLINT_DEFINE_BINOP(solve_bound) +FLINT_DEFINE_THREEARY(det_modular_given_divisor) +FLINT_DEFINE_UNOP(det_bareiss) +FLINT_DEFINE_UNOP(det_bound) +FLINT_DEFINE_UNOP(det_cofactor) +FLINT_DEFINE_UNOP(det_divisor) + +namespace detail { +template +struct fmpz_matxx_traits : matrices::generic_traits { }; +} // detail + +template +class fmpz_matxx_expression + : public expression, Operation, Data> +{ +public: + typedef expression, + Operation, Data> base_t; + typedef detail::fmpz_matxx_traits traits_t; + + FLINTXX_DEFINE_BASICS(fmpz_matxx_expression) + FLINTXX_DEFINE_CTORS(fmpz_matxx_expression) + FLINTXX_DEFINE_C_REF(fmpz_matxx_expression, fmpz_mat_struct, _mat) + + template + static evaluated_t create_temporary_rowscols( + const Expr&, slong rows, slong cols) + { + return evaluated_t(rows, cols); + } + FLINTXX_DEFINE_MATRIX_METHODS(traits_t) + + template + static fmpz_matxx_expression lift(const Nmod_mat& mat, + typename mp::enable_if >::type* = 0) + { + fmpz_matxx_expression res(mat.rows(), mat.cols()); + fmpz_mat_set_nmod_mat(res._mat(), mat.evaluate()._mat()); + return res; + } + template + static fmpz_matxx_expression lift_unsigned(const Nmod_mat& mat, + typename mp::enable_if >::type* = 0) + { + fmpz_matxx_expression res(mat.rows(), mat.cols()); + fmpz_mat_set_nmod_mat_unsigned(res._mat(), mat.evaluate()._mat()); + return res; + } + + template + static fmpz_matxx_expression reduce(const Fmpq_mat& mat, const Fmpz& mod, + typename mp::enable_if >::type* = 0, + typename mp::enable_if >::type* = 0) + { + fmpz_matxx_expression res(mat.rows(), mat.cols()); + fmpq_mat_get_fmpz_mat_mod_fmpz(res._mat(), mat.evaluate()._mat(), + mod.evaluate()._fmpz()); + return res; + } + + template + static fmpz_matxx_expression from_integral_fraction(const Fmpq_mat& mat, + typename mp::enable_if >::type* = 0) + { + fmpz_matxx_expression res(mat.rows(), mat.cols()); + res.set_integral_fraction(mat); + return res; + } + template + void set_integral_fraction(const Fmpq_mat& mat, + typename mp::enable_if >::type* = 0) + { + execution_check(fmpq_mat_get_fmpz_mat(_mat(), mat.evaluate()._mat()), + "set_integral_fraction", "fmpq_matxx"); + } + + static fmpz_matxx_expression randbits(slong rows, slong cols, + frandxx& state, mp_bitcnt_t bits) + { + fmpz_matxx_expression res(rows, cols); + res.set_randbits(state, bits); + return res; + } + static fmpz_matxx_expression randtest(slong rows, slong cols, + frandxx& state, mp_bitcnt_t bits) + { + fmpz_matxx_expression res(rows, cols); + res.set_randtest(state, bits); + return res; + } + static fmpz_matxx_expression randintrel(slong rows, slong cols, + frandxx& state, mp_bitcnt_t bits) + { + fmpz_matxx_expression res(rows, cols); + res.set_randintrel(state, bits); + return res; + } + static fmpz_matxx_expression randsimdioph(slong rows, slong cols, + frandxx& state, mp_bitcnt_t bits, mp_bitcnt_t bits2) + { + fmpz_matxx_expression res(rows, cols); + res.set_randsimdioph(state, bits, bits2); + return res; + } + static fmpz_matxx_expression randntrulike(slong rows, slong cols, + frandxx& state, mp_bitcnt_t bits, ulong q) + { + fmpz_matxx_expression res(rows, cols); + res.set_randntrulike(state, bits, q); + return res; + } + static fmpz_matxx_expression randntrulike2(slong rows, slong cols, + frandxx& state, mp_bitcnt_t bits, ulong q) + { + fmpz_matxx_expression res(rows, cols); + res.set_randntrulike2(state, bits, q); + return res; + } + static fmpz_matxx_expression randajtai(slong rows, slong cols, + frandxx& state, mp_bitcnt_t bits, double alpha) + { + fmpz_matxx_expression res(rows, cols); + res.set_randajtai(state, bits, alpha); + return res; + } + static fmpz_matxx_expression randrank(slong rows, slong cols, + frandxx& state, slong rank, mp_bitcnt_t bits) + { + fmpz_matxx_expression res(rows, cols); + res.set_randrank(state, rank, bits); + return res; + } + template + static typename mp::enable_if, + fmpz_matxx_expression>::type + randdet(slong rows, slong cols, frandxx& state, const Fmpz& d) + { + fmpz_matxx_expression res(rows, cols); + res.set_randdet(state, d); + return res; + } + + static fmpz_matxx_expression zero(slong rows, slong cols) + {return fmpz_matxx_expression(rows, cols);} + static fmpz_matxx_expression one(slong rows, slong cols) + { + fmpz_matxx_expression res(rows, cols); + res.set_one(); + return res; + } + + // these only make sense with targets + void set_randbits(frandxx& state, mp_bitcnt_t bits) + {fmpz_mat_randbits(_mat(), state._data(), bits);} + void set_randtest(frandxx& state, mp_bitcnt_t bits) + {fmpz_mat_randtest(_mat(), state._data(), bits);} + void set_randintrel(frandxx& state, mp_bitcnt_t bits) + {fmpz_mat_randintrel(_mat(), state._data(), bits);} + void set_randsimdioph(frandxx& state, mp_bitcnt_t bits, mp_bitcnt_t bits2) + {fmpz_mat_randsimdioph(_mat(), state._data(), bits, bits2);} + void set_randntrulike(frandxx& state, mp_bitcnt_t bits, ulong q) + {fmpz_mat_randntrulike(_mat(), state._data(), bits, q);} + void set_randntrulike2(frandxx& state, mp_bitcnt_t bits, ulong q) + {fmpz_mat_randntrulike2(_mat(), state._data(), bits, q);} + void set_randajtai(frandxx& state, mp_bitcnt_t bits, double alpha) + {fmpz_mat_randajtai(_mat(), state._data(), bits, alpha);} + void set_randrank(frandxx& state, slong rank, mp_bitcnt_t bits) + {fmpz_mat_randrank(_mat(), state._data(), rank, bits);} + + template + typename mp::enable_if >::type + set_randdet(frandxx& state, const Fmpz& d) + {fmpz_mat_randdet(_mat(), state._data(), d.evaluate()._fmpz());} + + template + int set_randpermdiag(frandxx& state, const Vec& v) + { + return fmpz_mat_randpermdiag(_mat(), state._data(), v._array(), v.size()); + } + + void apply_randops(frandxx& state, slong count) + {fmpz_mat_randops(_mat(), state._data(), count);} + + void set_zero() + {fmpz_mat_zero(_mat());} + void set_one() + {fmpz_mat_one(_mat());} + + template + slong set_rref_mod(const Fmpz& p, permxx* perm = 0, + typename mp::enable_if >::type* = 0) + { + return fmpz_mat_rref_mod(maybe_perm_data(perm), _mat(), p.evaluate()._fmpz()); + } + + // these cause evaluation + slong rank() const {return fmpz_mat_rank(this->evaluate()._mat());} + bool is_zero() const {return fmpz_mat_is_zero(this->evaluate()._mat());} + bool is_empty() const {return fmpz_mat_is_empty(this->evaluate()._mat());} + bool is_square() const {return fmpz_mat_is_square(this->evaluate()._mat());} + slong find_pivot_any(slong start, slong end, slong c) const + {return fmpz_mat_find_pivot_any(this->evaluate()._mat(), start, end, c);} + + // forwarded lazy ops + FLINTXX_DEFINE_MEMBER_BINOP(det_modular) + FLINTXX_DEFINE_MEMBER_BINOP(det_modular_accelerated) + FLINTXX_DEFINE_MEMBER_BINOP(divexact) + FLINTXX_DEFINE_MEMBER_BINOP(mul_classical) + FLINTXX_DEFINE_MEMBER_BINOP(mul_multi_mod) + FLINTXX_DEFINE_MEMBER_BINOP(pow) + + FLINTXX_DEFINE_MEMBER_BINOP(solve) + FLINTXX_DEFINE_MEMBER_BINOP(solve_bound) + FLINTXX_DEFINE_MEMBER_BINOP(solve_cramer) + FLINTXX_DEFINE_MEMBER_BINOP(solve_dixon) + FLINTXX_DEFINE_MEMBER_BINOP(solve_fflu) + + FLINTXX_DEFINE_MEMBER_3OP(det_modular_given_divisor) + + FLINTXX_DEFINE_MEMBER_UNOP(sqr) + FLINTXX_DEFINE_MEMBER_UNOP(transpose) + + FLINTXX_DEFINE_MEMBER_UNOP_RTYPE(fmpz_polyxx, charpoly) + FLINTXX_DEFINE_MEMBER_UNOP_RTYPE(fmpzxx, det) + FLINTXX_DEFINE_MEMBER_UNOP_RTYPE(fmpzxx, det_bareiss) + FLINTXX_DEFINE_MEMBER_UNOP_RTYPE(fmpzxx, det_bound) + FLINTXX_DEFINE_MEMBER_UNOP_RTYPE(fmpzxx, det_cofactor) + FLINTXX_DEFINE_MEMBER_UNOP_RTYPE(fmpzxx, det_divisor) + FLINTXX_DEFINE_MEMBER_UNOP_RTYPE(fmpzxx, trace) + //FLINTXX_DEFINE_MEMBER_UNOP_RTYPE(nullspace) // TODO + //FLINTXX_DEFINE_MEMBER_UNOP_RTYPE(???, inv) // TODO + //FLINTXX_DEFINE_MEMBER_UNOP_RTYPE(???, rref) // TODO + + FLINTXX_DEFINE_MEMBER_4OP(CRT) + + FLINTXX_DEFINE_MEMBER_FFLU +}; + +namespace detail { +struct fmpz_mat_data; +} // detail + +typedef fmpz_matxx_expression fmpz_matxx; +typedef fmpz_matxx_expression > fmpz_matxx_ref; +typedef fmpz_matxx_expression > fmpz_matxx_srcref; + +template<> +struct matrix_traits +{ + template static slong rows(const M& m) + { + return fmpz_mat_nrows(m._mat()); + } + template static slong cols(const M& m) + { + return fmpz_mat_ncols(m._mat()); + } + + template static fmpzxx_srcref at(const M& m, slong i, slong j) + { + return fmpzxx_srcref::make(fmpz_mat_entry(m._mat(), i, j)); + } + template static fmpzxx_ref at(M& m, slong i, slong j) + { + return fmpzxx_ref::make(fmpz_mat_entry(m._mat(), i, j)); + } +}; + +namespace detail { +template<> +struct fmpz_matxx_traits + : matrices::generic_traits_srcref { }; +template<> +struct fmpz_matxx_traits + : matrices::generic_traits_ref { }; +template<> struct fmpz_matxx_traits + : matrices::generic_traits_nonref { }; + +struct fmpz_mat_data +{ + typedef fmpz_mat_t& data_ref_t; + typedef const fmpz_mat_t& data_srcref_t; + + fmpz_mat_t inner; + + fmpz_mat_data(slong m, slong n) + { + fmpz_mat_init(inner, m, n); + } + + fmpz_mat_data(const fmpz_mat_data& o) + { + fmpz_mat_init_set(inner, o.inner); + } + + fmpz_mat_data(fmpz_matxx_srcref o) + { + fmpz_mat_init_set(inner, o._data().inner); + } + + ~fmpz_mat_data() {fmpz_mat_clear(inner);} +}; +} // detail + +#define FMPZ_MATXX_COND_S FLINTXX_COND_S(fmpz_matxx) +#define FMPZ_MATXX_COND_T FLINTXX_COND_T(fmpz_matxx) + +namespace traits { +template struct is_fmpz_matxx + : flint_classes::is_Base { }; +} // traits +namespace mp { +template +struct all_fmpz_matxx : mp::and_, all_fmpz_matxx > { }; +template +struct all_fmpz_matxx : traits::is_fmpz_matxx { }; + +template +struct enable_all_fmpz_matxx + : mp::enable_if, Out> { }; +} // mp + +namespace matrices { +template<> +struct outsize + : outsize { }; + +template<> struct outsize + : outsize { }; +template<> struct outsize + : outsize { }; +} // matrices + +// temporary instantiation stuff +FLINTXX_DEFINE_TEMPORARY_RULES(fmpz_matxx) + +namespace rules { +FLINT_DEFINE_DOIT_COND2(assignment, FMPZ_MATXX_COND_T, FMPZ_MATXX_COND_S, + fmpz_mat_set(to._mat(), from._mat())) + +FLINTXX_DEFINE_SWAP(fmpz_matxx, fmpz_mat_swap(e1._mat(), e2._mat())) + +FLINTXX_DEFINE_EQUALS(fmpz_matxx, fmpz_mat_equal(e1._mat(), e2._mat())) + +FLINT_DEFINE_PRINT_COND(FMPZ_MATXX_COND_S, fmpz_mat_fprint(to, from._mat())) +FLINT_DEFINE_READ_COND(FMPZ_MATXX_COND_T, fmpz_mat_fread(from, to._mat())) +FLINT_DEFINE_PRINT_PRETTY_COND(FMPZ_MATXX_COND_S, + fmpz_mat_fprint_pretty(to, from._mat())) + +FLINT_DEFINE_BINARY_EXPR_COND2(times, fmpz_matxx, + FMPZ_MATXX_COND_S, FMPZ_MATXX_COND_S, + fmpz_mat_mul(to._mat(), e1._mat(), e2._mat())) +FLINT_DEFINE_CBINARY_EXPR_COND2(times, fmpz_matxx, + FMPZ_MATXX_COND_S, FMPZXX_COND_S, + fmpz_mat_scalar_mul_fmpz(to._mat(), e1._mat(), e2._fmpz())) +FLINT_DEFINE_CBINARY_EXPR_COND2(times, fmpz_matxx, + FMPZ_MATXX_COND_S, traits::is_unsigned_integer, + fmpz_mat_scalar_mul_ui(to._mat(), e1._mat(), e2)) +FLINT_DEFINE_CBINARY_EXPR_COND2(times, fmpz_matxx, + FMPZ_MATXX_COND_S, traits::is_signed_integer, + fmpz_mat_scalar_mul_si(to._mat(), e1._mat(), e2)) + +FLINT_DEFINE_BINARY_EXPR_COND2(divexact_op, fmpz_matxx, + FMPZ_MATXX_COND_S, FMPZXX_COND_S, + fmpz_mat_scalar_divexact_fmpz(to._mat(), e1._mat(), e2._fmpz())) +FLINT_DEFINE_BINARY_EXPR_COND2(divexact_op, fmpz_matxx, + FMPZ_MATXX_COND_S, traits::is_unsigned_integer, + fmpz_mat_scalar_divexact_ui(to._mat(), e1._mat(), e2)) +FLINT_DEFINE_BINARY_EXPR_COND2(divexact_op, fmpz_matxx, + FMPZ_MATXX_COND_S, traits::is_signed_integer, + fmpz_mat_scalar_divexact_si(to._mat(), e1._mat(), e2)) + +FLINT_DEFINE_BINARY_EXPR_COND2(plus, fmpz_matxx, + FMPZ_MATXX_COND_S, FMPZ_MATXX_COND_S, + fmpz_mat_add(to._mat(), e1._mat(), e2._mat())) +FLINT_DEFINE_BINARY_EXPR_COND2(minus, fmpz_matxx, + FMPZ_MATXX_COND_S, FMPZ_MATXX_COND_S, + fmpz_mat_sub(to._mat(), e1._mat(), e2._mat())) + +FLINT_DEFINE_UNARY_EXPR_COND(negate, fmpz_matxx, FMPZ_MATXX_COND_S, + fmpz_mat_neg(to._mat(), from._mat())) + +FLINT_DEFINE_UNARY_EXPR_COND(transpose_op, fmpz_matxx, FMPZ_MATXX_COND_S, + fmpz_mat_transpose(to._mat(), from._mat())) +FLINT_DEFINE_UNARY_EXPR_COND(trace_op, fmpzxx, FMPZ_MATXX_COND_S, + fmpz_mat_trace(to._fmpz(), from._mat())) + +#define FMPZ_MATXX_DEFINE_DET(name) \ +FLINT_DEFINE_UNARY_EXPR_COND(name##_op, fmpzxx, FMPZ_MATXX_COND_S, \ + fmpz_mat_##name(to._fmpz(), from._mat())) +FMPZ_MATXX_DEFINE_DET(det) +FMPZ_MATXX_DEFINE_DET(det_cofactor) +FMPZ_MATXX_DEFINE_DET(det_bareiss) +FMPZ_MATXX_DEFINE_DET(det_divisor) +FMPZ_MATXX_DEFINE_DET(det_bound) + +FLINT_DEFINE_BINARY_EXPR_COND2(det_modular_op, fmpzxx, + FMPZ_MATXX_COND_S, tools::is_bool, + fmpz_mat_det_modular(to._fmpz(), e1._mat(), e2)) +FLINT_DEFINE_BINARY_EXPR_COND2(det_modular_accelerated_op, fmpzxx, + FMPZ_MATXX_COND_S, tools::is_bool, + fmpz_mat_det_modular_accelerated(to._fmpz(), e1._mat(), e2)) +FLINT_DEFINE_THREEARY_EXPR_COND3(det_modular_given_divisor_op, fmpzxx, + FMPZ_MATXX_COND_S, FMPZXX_COND_S, tools::is_bool, + fmpz_mat_det_modular_given_divisor(to._fmpz(), e1._mat(), e2._fmpz(), e3)) + +FLINT_DEFINE_THREEARY_EXPR_COND3(mat_at_op, fmpzxx, + FMPZ_MATXX_COND_S, traits::fits_into_slong, traits::fits_into_slong, + fmpz_set(to._fmpz(), fmpz_mat_entry(e1._mat(), e2, e3))) + +FLINT_DEFINE_BINARY_EXPR_COND2(mul_classical_op, fmpz_matxx, + FMPZ_MATXX_COND_S, FMPZ_MATXX_COND_S, + fmpz_mat_mul_classical(to._mat(), e1._mat(), e2._mat())) +FLINT_DEFINE_BINARY_EXPR_COND2(mul_multi_mod_op, fmpz_matxx, + FMPZ_MATXX_COND_S, FMPZ_MATXX_COND_S, + fmpz_mat_mul_multi_mod(to._mat(), e1._mat(), e2._mat())) + +FLINT_DEFINE_UNARY_EXPR_COND(sqr_op, fmpz_matxx, FMPZ_MATXX_COND_S, + fmpz_mat_sqr(to._mat(), from._mat())) +FLINT_DEFINE_BINARY_EXPR_COND2(pow_op, fmpz_matxx, + FMPZ_MATXX_COND_S, traits::is_unsigned_integer, + fmpz_mat_pow(to._mat(), e1._mat(), e2)) + +namespace rdetail { +typedef make_ltuple::type >::type + fmpz_mat_inv_rt; + +typedef make_ltuple::type >::type + fmpz_solve_bound_rt; + +typedef make_ltuple::type >::type + fmpz_mat_nullspace_rt; +} // rdetail + +FLINT_DEFINE_UNARY_EXPR_COND(inv_op, rdetail::fmpz_mat_inv_rt, + FMPZ_MATXX_COND_S, + to.template get<0>() = fmpz_mat_inv(to.template get<1>()._mat(), + to.template get<2>()._fmpz(), from._mat())) + +FLINT_DEFINE_UNARY_EXPR_COND(charpoly_op, fmpz_polyxx, FMPZ_MATXX_COND_S, + fmpz_mat_charpoly(to._poly(), from._mat())) + +#define FMPZ_MATXX_DEFINE_SOLVE(name) \ +FLINT_DEFINE_BINARY_EXPR_COND2(name##_op, rdetail::fmpz_mat_inv_rt, \ + FMPZ_MATXX_COND_S, FMPZ_MATXX_COND_S, \ + to.template get<0>() = fmpz_mat_##name(to.template get<1>()._mat(), \ + to.template get<2>()._fmpz(), e1._mat(), e2._mat())) +FMPZ_MATXX_DEFINE_SOLVE(solve) +FMPZ_MATXX_DEFINE_SOLVE(solve_dixon) +FMPZ_MATXX_DEFINE_SOLVE(solve_cramer) +FMPZ_MATXX_DEFINE_SOLVE(solve_fflu) + +FLINT_DEFINE_BINARY_EXPR_COND2(solve_bound_op, + rdetail::fmpz_solve_bound_rt, + FMPZ_MATXX_COND_S, FMPZ_MATXX_COND_S, + fmpz_mat_solve_bound(to.template get<0>()._fmpz(), + to.template get<1>()._fmpz(), e1._mat(), e2._mat())) + +FLINT_DEFINE_UNARY_EXPR_COND(nullspace_op, rdetail::fmpz_mat_nullspace_rt, + FMPZ_MATXX_COND_S, to.template get<0>() = fmpz_mat_nullspace( + to.template get<1>()._mat(), from._mat())) + +namespace rdetail { +typedef make_ltuple::type>::type + fmpz_matxx_fflu_rt; +} // rdetail + +FLINT_DEFINE_THREEARY_EXPR_COND3(fflu_op, rdetail::fmpz_matxx_fflu_rt, + FMPZ_MATXX_COND_S, traits::is_maybe_perm, tools::is_bool, + to.template get<0>() = fmpz_mat_fflu(to.template get<1>()._mat(), + to.template get<2>()._fmpz(), maybe_perm_data(e2), e1._mat(), e3)) + +FLINT_DEFINE_UNARY_EXPR_COND(rref_op, rdetail::fmpz_matxx_fflu_rt, + FMPZ_MATXX_COND_S, + to.template get<0>() = fmpz_mat_rref(to.template get<1>()._mat(), + to.template get<2>()._fmpz(), from._mat())) +} // rules +} // flint + +#include "nmod_matxx.h" // modular reconstruction code + +#endif diff --git a/external/flint-2.4.3/fmpz_mod_poly.h b/external/flint-2.4.3/fmpz_mod_poly.h new file mode 100644 index 0000000..1b62de8 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly.h @@ -0,0 +1,832 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#ifndef FMPZ_MOD_POLY_H +#define FMPZ_MOD_POLY_H + +#undef ulong +#define ulong ulongxx /* interferes with system includes */ +#include +#undef ulong +#include +#define ulong mp_limb_t + +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpz_mat.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/* Type definitions *********************************************************/ + +typedef struct +{ + fmpz * coeffs; + slong alloc; + slong length; + fmpz p; +} fmpz_mod_poly_struct; + +typedef fmpz_mod_poly_struct fmpz_mod_poly_t[1]; + +/* Initialisation and memory management *************************************/ + +void fmpz_mod_poly_init(fmpz_mod_poly_t poly, const fmpz_t p); + +void fmpz_mod_poly_init2(fmpz_mod_poly_t poly, const fmpz_t p, slong alloc); + +void fmpz_mod_poly_clear(fmpz_mod_poly_t poly); + +void fmpz_mod_poly_realloc(fmpz_mod_poly_t poly, slong alloc); + +void fmpz_mod_poly_fit_length(fmpz_mod_poly_t poly, slong len); + +/* Normalisation and truncation *********************************************/ + +void _fmpz_mod_poly_normalise(fmpz_mod_poly_t poly); + +static __inline__ +void _fmpz_mod_poly_set_length(fmpz_mod_poly_t poly, slong len) +{ + if (poly->length > len) + { + slong i; + + for (i = len; i < poly->length; i++) + _fmpz_demote(poly->coeffs + i); + } + poly->length = len; +} + +static __inline__ +void fmpz_mod_poly_truncate(fmpz_mod_poly_t poly, slong len) +{ + if (poly->length > len) + { + slong i; + + for (i = len; i < poly->length; i++) + _fmpz_demote(poly->coeffs + i); + poly->length = len; + _fmpz_mod_poly_normalise(poly); + } +} + +/* Randomisation ************************************************************/ + +void +fmpz_mod_poly_randtest(fmpz_mod_poly_t f, flint_rand_t state, slong len); + +void +fmpz_mod_poly_randtest_irreducible(fmpz_mod_poly_t f, + flint_rand_t state, slong len); + +void +fmpz_mod_poly_randtest_not_zero(fmpz_mod_poly_t f, + flint_rand_t state, slong len); + +void +fmpz_mod_poly_randtest_monic(fmpz_mod_poly_t f, flint_rand_t state, slong len); + +void +fmpz_mod_poly_randtest_monic_irreducible(fmpz_mod_poly_t f, + flint_rand_t state, slong len); + +void +fmpz_mod_poly_randtest_trinomial(fmpz_mod_poly_t f, flint_rand_t state, slong len); + +int +fmpz_mod_poly_randtest_trinomial_irreducible(fmpz_mod_poly_t f, + flint_rand_t state, slong len, + slong max_attempts); + +void +fmpz_mod_poly_randtest_pentomial(fmpz_mod_poly_t f, flint_rand_t state, slong len); + +int +fmpz_mod_poly_randtest_pentomial_irreducible(fmpz_mod_poly_t f, + flint_rand_t state, slong len, + slong max_attempts); + +void +fmpz_mod_poly_randtest_sparse_irreducible(fmpz_mod_poly_t poly, + flint_rand_t state, slong len); + +/* Attributes ***************************************************************/ + +#define fmpz_mod_poly_modulus(poly) (&((poly)->p)) + +static __inline__ +slong fmpz_mod_poly_degree(const fmpz_mod_poly_t poly) +{ + return poly->length - 1; +} + +static __inline__ +slong fmpz_mod_poly_length(const fmpz_mod_poly_t poly) +{ + return poly->length; +} + +static __inline__ +fmpz * fmpz_mod_poly_lead(const fmpz_mod_poly_t poly) +{ + if (poly->length) + return poly->coeffs + (poly->length - 1); + else + return NULL; +} + +/* Assignment and basic manipulation ****************************************/ + +void fmpz_mod_poly_set(fmpz_mod_poly_t poly1, const fmpz_mod_poly_t poly2); + +void fmpz_mod_poly_swap(fmpz_mod_poly_t poly1, fmpz_mod_poly_t poly2); + +void _fmpz_mod_poly_reverse(fmpz * res, const fmpz * poly, slong len, slong n); + +void fmpz_mod_poly_reverse(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly, slong n); + +static __inline__ +void fmpz_mod_poly_zero(fmpz_mod_poly_t poly) +{ + _fmpz_mod_poly_set_length(poly, 0); +} + +void fmpz_mod_poly_zero_coeffs(fmpz_mod_poly_t poly, slong i, slong j); + +/* Conversion ***************************************************************/ + +static __inline__ +void fmpz_mod_poly_set_ui(fmpz_mod_poly_t f, ulong x) +{ + if (x == 0) + { + fmpz_mod_poly_zero(f); + } + else + { + fmpz_mod_poly_fit_length(f, 1); + _fmpz_mod_poly_set_length(f, 1); + fmpz_set_ui(f->coeffs, x); + fmpz_mod(f->coeffs, f->coeffs, &(f->p)); + _fmpz_mod_poly_normalise(f); + } +} + +void fmpz_mod_poly_set_fmpz(fmpz_mod_poly_t poly, const fmpz_t c); + +void fmpz_mod_poly_set_fmpz_poly(fmpz_mod_poly_t f, const fmpz_poly_t g); + +void fmpz_mod_poly_get_fmpz_poly(fmpz_poly_t f, const fmpz_mod_poly_t g); + +/* Comparison ***************************************************************/ + +static __inline__ +int fmpz_mod_poly_equal(const fmpz_mod_poly_t poly1, + const fmpz_mod_poly_t poly2) +{ + return fmpz_poly_equal((fmpz_poly_struct *) poly1, + (fmpz_poly_struct *) poly2); +} + +static __inline__ +int fmpz_mod_poly_is_zero(const fmpz_mod_poly_t poly) +{ + return (poly->length == 0); +} + +/* Getting and setting coefficients *****************************************/ + +void fmpz_mod_poly_set_coeff_fmpz(fmpz_mod_poly_t poly, slong n, const fmpz_t x); + +void fmpz_mod_poly_set_coeff_ui(fmpz_mod_poly_t poly, slong n, ulong x); + +static __inline__ +void fmpz_mod_poly_get_coeff_fmpz(fmpz_t x, const fmpz_mod_poly_t poly, slong n) +{ + if (n < poly->length) + fmpz_set(x, poly->coeffs + n); + else + fmpz_zero(x); +} + +static __inline__ void fmpz_mod_poly_set_coeff_mpz(fmpz_mod_poly_t poly, slong n, + const mpz_t x) +{ + fmpz_t t; + fmpz_init_set_readonly(t, x); + fmpz_mod_poly_set_coeff_fmpz(poly, n, t); + fmpz_clear_readonly(t); +} + +static __inline__ void fmpz_mod_poly_get_coeff_mpz(mpz_t x, const fmpz_mod_poly_t poly, slong n) +{ + fmpz_t t; + fmpz_init(t); + fmpz_mod_poly_get_coeff_fmpz(t, poly, n); + fmpz_get_mpz(x, t); + fmpz_clear(t); +} + + +/* Shifting *****************************************************************/ + +void _fmpz_mod_poly_shift_left(fmpz * res, const fmpz * poly, slong len, slong n); + +void fmpz_mod_poly_shift_left(fmpz_mod_poly_t f, + const fmpz_mod_poly_t g, slong n); + +void _fmpz_mod_poly_shift_right(fmpz * res, const fmpz * poly, slong len, slong n); + +void fmpz_mod_poly_shift_right(fmpz_mod_poly_t f, + const fmpz_mod_poly_t g, slong n); + +/* Addition and subtraction *************************************************/ + +void _fmpz_mod_poly_add(fmpz *res, const fmpz *poly1, slong len1, + const fmpz *poly2, slong len2, const fmpz_t p); + +void fmpz_mod_poly_add(fmpz_mod_poly_t res, + const fmpz_mod_poly_t poly1, const fmpz_mod_poly_t poly2); + +void _fmpz_mod_poly_sub(fmpz *res, const fmpz *poly1, slong len1, + const fmpz *poly2, slong len2, const fmpz_t p); + +void fmpz_mod_poly_sub(fmpz_mod_poly_t res, + const fmpz_mod_poly_t poly1, const fmpz_mod_poly_t poly2); + +void _fmpz_mod_poly_neg(fmpz *res, const fmpz *poly, slong len, const fmpz_t p); + +void fmpz_mod_poly_neg(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly); + +/* Scalar multiplication ****************************************************/ + +void _fmpz_mod_poly_scalar_mul_fmpz(fmpz *res, const fmpz *poly, slong len, + const fmpz_t x, const fmpz_t p); + +void fmpz_mod_poly_scalar_mul_fmpz(fmpz_mod_poly_t res, + const fmpz_mod_poly_t poly, const fmpz_t x); + +/* Multiplication ***********************************************************/ + +void _fmpz_mod_poly_mul(fmpz *res, const fmpz *poly1, slong len1, + const fmpz *poly2, slong len2, const fmpz_t p); + +void fmpz_mod_poly_mul(fmpz_mod_poly_t res, + const fmpz_mod_poly_t poly1, const fmpz_mod_poly_t poly2); + +void _fmpz_mod_poly_mullow(fmpz *res, const fmpz *poly1, slong len1, + const fmpz *poly2, slong len2, + const fmpz_t p, slong n); + +void fmpz_mod_poly_mullow(fmpz_mod_poly_t res, + const fmpz_mod_poly_t poly1, const fmpz_mod_poly_t poly2, slong n); + +void _fmpz_mod_poly_sqr(fmpz *res, const fmpz *poly, slong len, const fmpz_t p); + +void fmpz_mod_poly_sqr(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly); + +void _fmpz_mod_poly_mulmod(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2, const fmpz * f, + slong lenf, const fmpz_t p); + +void fmpz_mod_poly_mulmod(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly1, + const fmpz_mod_poly_t poly2, const fmpz_mod_poly_t f); + +void _fmpz_mod_poly_mulmod_preinv(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2, const fmpz * f, slong lenf, + const fmpz* finv, slong lenfinv, const fmpz_t p); + +void +fmpz_mod_poly_mulmod_preinv(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly1, + const fmpz_mod_poly_t poly2, const fmpz_mod_poly_t f, + const fmpz_mod_poly_t finv); + +/* Powering *****************************************************************/ + +void _fmpz_mod_poly_pow(fmpz *rop, const fmpz *op, slong len, ulong e, + const fmpz_t p); + +void fmpz_mod_poly_pow(fmpz_mod_poly_t rop, const fmpz_mod_poly_t op, ulong e); + +void _fmpz_mod_poly_pow_trunc(fmpz * res, const fmpz * poly, + ulong e, slong trunc, const fmpz_t p); + +void fmpz_mod_poly_pow_trunc(fmpz_mod_poly_t res, + const fmpz_mod_poly_t poly, ulong e, slong trunc); + +void _fmpz_mod_poly_pow_trunc_binexp(fmpz * res, const fmpz * poly, + ulong e, slong trunc, const fmpz_t p); + +void fmpz_mod_poly_pow_trunc_binexp(fmpz_mod_poly_t res, + const fmpz_mod_poly_t poly, ulong e, slong trunc); + +void +_fmpz_mod_poly_powmod_ui_binexp(fmpz * res, const fmpz * poly, + ulong e, const fmpz * f, slong lenf, const fmpz_t p); + +void +fmpz_mod_poly_powmod_ui_binexp(fmpz_mod_poly_t res, + const fmpz_mod_poly_t poly, ulong e, + const fmpz_mod_poly_t f); + + +void +_fmpz_mod_poly_powmod_ui_binexp_preinv(fmpz * res, const fmpz * poly, + ulong e, const fmpz * f, slong lenf, + const fmpz * finv, slong lenfinv, const fmpz_t p); + +void +fmpz_mod_poly_powmod_ui_binexp_preinv(fmpz_mod_poly_t res, + const fmpz_mod_poly_t poly, ulong e, + const fmpz_mod_poly_t f, const fmpz_mod_poly_t finv); + +void +_fmpz_mod_poly_powmod_fmpz_binexp(fmpz * res, const fmpz * poly, + const fmpz_t e, const fmpz * f, + slong lenf, const fmpz_t p); + +void +fmpz_mod_poly_powmod_fmpz_binexp(fmpz_mod_poly_t res, + const fmpz_mod_poly_t poly, const fmpz_t e, + const fmpz_mod_poly_t f); + +void +_fmpz_mod_poly_powmod_fmpz_binexp_preinv(fmpz * res, const fmpz * poly, + const fmpz_t e, const fmpz * f, slong lenf, + const fmpz* finv, slong lenfinv, + const fmpz_t p); + +void +fmpz_mod_poly_powmod_fmpz_binexp_preinv(fmpz_mod_poly_t res, + const fmpz_mod_poly_t poly, const fmpz_t e, + const fmpz_mod_poly_t f, const fmpz_mod_poly_t finv); + +void +_fmpz_mod_poly_powmod_x_fmpz_preinv(fmpz * res, const fmpz_t e, const fmpz * f, + slong lenf, const fmpz* finv, slong lenfinv, + const fmpz_t p); + +void +fmpz_mod_poly_powmod_x_fmpz_preinv(fmpz_mod_poly_t res, const fmpz_t e, + const fmpz_mod_poly_t f, const fmpz_mod_poly_t finv); + +/* Division *****************************************************************/ + +void _fmpz_mod_poly_divrem_basecase(fmpz * Q, fmpz * R, + const fmpz * A, slong lenA, const fmpz * B, slong lenB, + const fmpz_t invB, const fmpz_t p); + +void fmpz_mod_poly_divrem_basecase(fmpz_mod_poly_t Q, fmpz_mod_poly_t R, + const fmpz_mod_poly_t A, const fmpz_mod_poly_t B); + +void _fmpz_mod_poly_div_basecase(fmpz * Q, fmpz * R, + const fmpz * A, slong lenA, const fmpz * B, slong lenB, + const fmpz_t invB, const fmpz_t p); + +void fmpz_mod_poly_div_basecase(fmpz_mod_poly_t Q, + const fmpz_mod_poly_t A, const fmpz_mod_poly_t B); + +void +_fmpz_mod_poly_div_newton_n_preinv (fmpz* Q, const fmpz* A, slong lenA, + const fmpz* B, slong lenB, const fmpz* Binv, + slong lenBinv, const fmpz_t mod); + +void +fmpz_mod_poly_div_newton_n_preinv(fmpz_mod_poly_t Q, const fmpz_mod_poly_t A, + const fmpz_mod_poly_t B, const fmpz_mod_poly_t Binv); + +void +_fmpz_mod_poly_divrem_newton_n_preinv (fmpz* Q, fmpz* R, const fmpz* A, + slong lenA, const fmpz* B, slong lenB, + const fmpz* Binv, slong lenBinv, const fmpz_t mod); + +void +fmpz_mod_poly_divrem_newton_n_preinv(fmpz_mod_poly_t Q, fmpz_mod_poly_t R, + const fmpz_mod_poly_t A, const fmpz_mod_poly_t B, + const fmpz_mod_poly_t Binv); + +ulong fmpz_mod_poly_remove(fmpz_mod_poly_t f, const fmpz_mod_poly_t p); + +void _fmpz_mod_poly_rem_basecase(fmpz * R, + const fmpz * A, slong lenA, const fmpz * B, slong lenB, + const fmpz_t invB, const fmpz_t p); + +void fmpz_mod_poly_rem_basecase(fmpz_mod_poly_t R, + const fmpz_mod_poly_t A, const fmpz_mod_poly_t B); + +void _fmpz_mod_poly_divrem_divconquer_recursive(fmpz * Q, fmpz * BQ, fmpz * W, + const fmpz * A, const fmpz * B, slong lenB, + const fmpz_t invB, const fmpz_t p); + +void _fmpz_mod_poly_divrem_divconquer(fmpz * Q, fmpz * R, + const fmpz * A, slong lenA, const fmpz * B, slong lenB, + const fmpz_t invB, const fmpz_t p); + +void fmpz_mod_poly_divrem_divconquer(fmpz_mod_poly_t Q, fmpz_mod_poly_t R, + const fmpz_mod_poly_t A, const fmpz_mod_poly_t B); + +static __inline__ +void _fmpz_mod_poly_divrem(fmpz *Q, fmpz *R, + const fmpz *A, slong lenA, const fmpz *B, slong lenB, + const fmpz_t invB, const fmpz_t p) +{ + _fmpz_mod_poly_divrem_divconquer(Q, R, A, lenA, B, lenB, invB, p); +} + +static __inline__ +void fmpz_mod_poly_divrem(fmpz_mod_poly_t Q, fmpz_mod_poly_t R, + const fmpz_mod_poly_t A, const fmpz_mod_poly_t B) +{ + fmpz_mod_poly_divrem_divconquer(Q, R, A, B); +} + +void _fmpz_mod_poly_divrem_f(fmpz_t f, fmpz *Q, fmpz *R, + const fmpz *A, slong lenA, + const fmpz *B, slong lenB, const fmpz_t p); + +void fmpz_mod_poly_divrem_f(fmpz_t f, fmpz_mod_poly_t Q, fmpz_mod_poly_t R, + const fmpz_mod_poly_t A, const fmpz_mod_poly_t B); + +static __inline__ +void _fmpz_mod_poly_rem(fmpz *R, + const fmpz *A, slong lenA, const fmpz *B, slong lenB, + const fmpz_t invB, const fmpz_t p) +{ + fmpz *Q = _fmpz_vec_init(lenA - lenB + 1); + fmpz *T = _fmpz_vec_init(lenA); + + if (lenA < lenB) + { + _fmpz_vec_set(R, A, lenA); + _fmpz_vec_zero(R + lenA, lenB - 1 - lenA); + } else + { + _fmpz_mod_poly_divrem_divconquer(Q, T, A, lenA, B, lenB, invB, p); + _fmpz_vec_set(R, T, lenB - 1); + } + + _fmpz_vec_clear(T, lenA); + _fmpz_vec_clear(Q, lenA - lenB + 1); +} + +static __inline__ +void fmpz_mod_poly_rem(fmpz_mod_poly_t R, + const fmpz_mod_poly_t A, const fmpz_mod_poly_t B) +{ + fmpz_mod_poly_t Q; + + fmpz_mod_poly_init(Q, &(A->p)); + fmpz_mod_poly_divrem(Q, R, A, B); + fmpz_mod_poly_clear(Q); +} + +void _fmpz_mod_poly_div_newton_n_preinv (fmpz *Q, const fmpz* A, slong lenA, + const fmpz* B, slong lenB, const fmpz* Binv, + slong lenBinv, const fmpz_t p); + +void fmpz_mod_poly_div_newton_n_preinv (fmpz_mod_poly_t Q, const fmpz_mod_poly_t A, + const fmpz_mod_poly_t B, const fmpz_mod_poly_t Binv); + + +void _fmpz_mod_poly_divrem_newton_n_preinv (fmpz* Q, fmpz* R, const fmpz* A, + slong lenA, const fmpz* B, slong lenB, + const fmpz* Binv, slong lenBinv, const fmpz_t p); + +void fmpz_mod_poly_divrem_newton_n_preinv(fmpz_mod_poly_t Q, fmpz_mod_poly_t R, + const fmpz_mod_poly_t A, const fmpz_mod_poly_t B, + const fmpz_mod_poly_t Binv); + +/* Power series inversion ***************************************************/ + +void +_fmpz_mod_poly_inv_series_newton(fmpz * Qinv, const fmpz * Q, slong n, + const fmpz_t cinv, const fmpz_t p); + +void fmpz_mod_poly_inv_series_newton(fmpz_mod_poly_t Qinv, + const fmpz_mod_poly_t Q, slong n); + +/* Greatest common divisor **************************************************/ + +void fmpz_mod_poly_make_monic(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly); + +slong _fmpz_mod_poly_gcd_euclidean(fmpz *G, const fmpz *A, slong lenA, + const fmpz *B, slong lenB, + const fmpz_t invB, const fmpz_t p); + +void fmpz_mod_poly_gcd_euclidean(fmpz_mod_poly_t G, + const fmpz_mod_poly_t A, + const fmpz_mod_poly_t B); + +static __inline__ +slong _fmpz_mod_poly_gcd(fmpz *G, const fmpz *A, slong lenA, + const fmpz *B, slong lenB, + const fmpz_t invB, const fmpz_t p) +{ + return _fmpz_mod_poly_gcd_euclidean(G, A, lenA, B, lenB, invB, p); +} + +static __inline__ +void fmpz_mod_poly_gcd(fmpz_mod_poly_t G, + const fmpz_mod_poly_t A, const fmpz_mod_poly_t B) +{ + fmpz_mod_poly_gcd_euclidean(G, A, B); +} + +slong _fmpz_mod_poly_gcd_euclidean_f(fmpz_t f, fmpz *G, + const fmpz *A, slong lenA, + const fmpz *B, slong lenB, const fmpz_t p); + +void fmpz_mod_poly_gcd_euclidean_f(fmpz_t f, fmpz_mod_poly_t G, + const fmpz_mod_poly_t A, + const fmpz_mod_poly_t B); + +static __inline__ +slong _fmpz_mod_poly_gcd_f(fmpz_t f, fmpz *G, + const fmpz *A, slong lenA, + const fmpz *B, slong lenB, const fmpz_t p) +{ + return _fmpz_mod_poly_gcd_euclidean_f(f, G, A, lenA, B, lenB, p); +} + +static __inline__ +void fmpz_mod_poly_gcd_f(fmpz_t f, fmpz_mod_poly_t G, + const fmpz_mod_poly_t A, const fmpz_mod_poly_t B) +{ + fmpz_mod_poly_gcd_euclidean_f(f, G, A, B); +} + +slong _fmpz_mod_poly_xgcd_euclidean(fmpz *G, fmpz *S, fmpz *T, + const fmpz *A, slong lenA, + const fmpz *B, slong lenB, + const fmpz_t invB, const fmpz_t p); + +void fmpz_mod_poly_xgcd_euclidean(fmpz_mod_poly_t G, + fmpz_mod_poly_t S, fmpz_mod_poly_t T, + const fmpz_mod_poly_t A, const fmpz_mod_poly_t B); + +static __inline__ slong +_fmpz_mod_poly_xgcd(fmpz *G, fmpz *S, fmpz *T, + const fmpz *A, slong lenA, const fmpz *B, slong lenB, + const fmpz_t invB, const fmpz_t p) +{ + return _fmpz_mod_poly_xgcd_euclidean(G, S, T, A, lenA, B, lenB, invB, p); +} + +static __inline__ void +fmpz_mod_poly_xgcd(fmpz_mod_poly_t G, fmpz_mod_poly_t S, fmpz_mod_poly_t T, + const fmpz_mod_poly_t A, const fmpz_mod_poly_t B) +{ + fmpz_mod_poly_xgcd_euclidean(G, S, T, A, B); +} + +slong _fmpz_mod_poly_gcdinv(fmpz *G, fmpz *S, + const fmpz *A, slong lenA, const fmpz *B, slong lenB, + const fmpz_t p); + +void fmpz_mod_poly_gcdinv(fmpz_mod_poly_t G, fmpz_mod_poly_t S, + const fmpz_mod_poly_t A, const fmpz_mod_poly_t B); + +int _fmpz_mod_poly_invmod(fmpz *A, + const fmpz *B, slong lenB, + const fmpz *P, slong lenP, const fmpz_t p); + +int fmpz_mod_poly_invmod(fmpz_mod_poly_t A, + const fmpz_mod_poly_t B, const fmpz_mod_poly_t P); + +/* Derivative **************************************************************/ + +void _fmpz_mod_poly_derivative(fmpz *res, const fmpz *poly, slong len, + const fmpz_t p); + +void fmpz_mod_poly_derivative(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly); + +/* Evaluation **************************************************************/ + +void _fmpz_mod_poly_evaluate_fmpz(fmpz_t res, const fmpz *poly, slong len, + const fmpz_t a, const fmpz_t p); + +void fmpz_mod_poly_evaluate_fmpz(fmpz_t res, + const fmpz_mod_poly_t poly, const fmpz_t a); + +fmpz_poly_struct ** _fmpz_mod_poly_tree_alloc(slong len); + +void _fmpz_mod_poly_tree_free(fmpz_poly_struct ** tree, slong len); + +void _fmpz_mod_poly_tree_build(fmpz_poly_struct ** tree, + const fmpz * roots, slong len, const fmpz_t mod); + +void _fmpz_mod_poly_evaluate_fmpz_vec_iter(fmpz * ys, const fmpz * coeffs, + slong len, const fmpz * xs, slong n, const fmpz_t mod); + +void fmpz_mod_poly_evaluate_fmpz_vec_iter(fmpz * ys, + const fmpz_mod_poly_t poly, const fmpz * xs, slong n); + +void _fmpz_mod_poly_evaluate_fmpz_vec_fast_precomp(fmpz * vs, + const fmpz * poly, slong plen, fmpz_poly_struct * const * tree, + slong len, const fmpz_t mod); + +void _fmpz_mod_poly_evaluate_fmpz_vec_fast(fmpz * ys, + const fmpz * poly, slong plen, const fmpz * xs, slong n, const fmpz_t mod); + +void fmpz_mod_poly_evaluate_fmpz_vec_fast(fmpz * ys, + const fmpz_mod_poly_t poly, const fmpz * xs, slong n); + +void _fmpz_mod_poly_evaluate_fmpz_vec(fmpz * ys, const fmpz * coeffs, + slong len, const fmpz * xs, slong n, const fmpz_t mod); + +void fmpz_mod_poly_evaluate_fmpz_vec(fmpz * ys, + const fmpz_mod_poly_t poly, const fmpz * xs, slong n); + + + +/* Composition *************************************************************/ + +void _fmpz_mod_poly_compose_horner(fmpz *res, const fmpz *poly1, slong len1, + const fmpz *poly2, slong len2, + const fmpz_t p); + +void fmpz_mod_poly_compose_horner(fmpz_mod_poly_t res, + const fmpz_mod_poly_t poly1, + const fmpz_mod_poly_t poly2); + +void _fmpz_mod_poly_compose_divconquer(fmpz *res, + const fmpz *poly1, slong len1, + const fmpz *poly2, slong len2, + const fmpz_t p); + +void fmpz_mod_poly_compose_divconquer(fmpz_mod_poly_t res, + const fmpz_mod_poly_t poly1, + const fmpz_mod_poly_t poly2); + +static __inline__ +void _fmpz_mod_poly_compose(fmpz *res, const fmpz *poly1, slong len1, + const fmpz *poly2, slong len2, + const fmpz_t p) +{ + _fmpz_mod_poly_compose_divconquer(res, poly1, len1, poly2, len2, p); +} + +static __inline__ +void fmpz_mod_poly_compose(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly1, + const fmpz_mod_poly_t poly2) +{ + fmpz_mod_poly_compose_divconquer(res, poly1, poly2); +} + +/* Modular composition ******************************************************/ + +void +_fmpz_mod_poly_compose_mod(fmpz * res, const fmpz * f, slong lenf, const fmpz * g, + const fmpz * h, slong lenh, const fmpz_t p); + +void +fmpz_mod_poly_compose_mod(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly1, + const fmpz_mod_poly_t poly2, const fmpz_mod_poly_t poly3); + +void +_fmpz_mod_poly_compose_mod_brent_kung(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, const fmpz * poly3, slong len3, const fmpz_t p); + +void +fmpz_mod_poly_compose_mod_brent_kung(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly1, + const fmpz_mod_poly_t poly2, const fmpz_mod_poly_t poly3); + +void +_fmpz_mod_poly_reduce_matrix_mod_poly (fmpz_mat_t A, const fmpz_mat_t B, + const fmpz_mod_poly_t f); + +void +_fmpz_mod_poly_precompute_matrix (fmpz_mat_t A, const fmpz * poly1, + const fmpz * poly2, slong len2, const fmpz * poly2inv, + slong len2inv, const fmpz_t p); + +void +fmpz_mod_poly_precompute_matrix(fmpz_mat_t A, const fmpz_mod_poly_t poly1, + const fmpz_mod_poly_t poly2, const fmpz_mod_poly_t poly2inv); + +void +_fmpz_mod_poly_compose_mod_brent_kung_precomp_preinv(fmpz * res, + const fmpz * poly1, slong len1, const fmpz_mat_t A, const fmpz * poly3, + slong len3, const fmpz * poly3inv, slong len3inv, const fmpz_t p); + +void +fmpz_mod_poly_compose_mod_brent_kung_precomp_preinv(fmpz_mod_poly_t res, + const fmpz_mod_poly_t poly1, const fmpz_mat_t A, + const fmpz_mod_poly_t poly3, const fmpz_mod_poly_t poly3inv); + +void +_fmpz_mod_poly_compose_mod_brent_kung_preinv(fmpz * res, const fmpz * poly1, + slong len1, const fmpz * poly2, const fmpz * poly3, slong len3, + const fmpz * poly3inv, slong len3inv, const fmpz_t p); + +void +fmpz_mod_poly_compose_mod_brent_kung_preinv(fmpz_mod_poly_t res, + const fmpz_mod_poly_t poly1, const fmpz_mod_poly_t poly2, + const fmpz_mod_poly_t poly3, const fmpz_mod_poly_t poly3inv); + +void +_fmpz_mod_poly_compose_mod_horner(fmpz * res, const fmpz * f, slong lenf, const fmpz * g, + const fmpz * h, slong lenh, const fmpz_t p); + +void +fmpz_mod_poly_compose_mod_horner(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly1, + const fmpz_mod_poly_t poly2, const fmpz_mod_poly_t poly3); + +/* Radix conversion *********************************************************/ + +typedef struct { + fmpz *V; + fmpz *W; + fmpz **Rpow; + fmpz **Rinv; + slong degR; + slong k; + fmpz invL; +} fmpz_mod_poly_radix_struct; + +typedef fmpz_mod_poly_radix_struct fmpz_mod_poly_radix_t[1]; + +void _fmpz_mod_poly_radix_init(fmpz **Rpow, fmpz **Rinv, + const fmpz *R, slong lenR, slong k, + const fmpz_t invL, const fmpz_t p); + +void fmpz_mod_poly_radix_init(fmpz_mod_poly_radix_t D, + const fmpz_mod_poly_t R, slong degF); + +void fmpz_mod_poly_radix_clear(fmpz_mod_poly_radix_t D); + +void _fmpz_mod_poly_radix(fmpz **B, const fmpz *F, fmpz **Rpow, fmpz **Rinv, + slong degR, slong k, slong i, fmpz *W, const fmpz_t p); + +void fmpz_mod_poly_radix(fmpz_mod_poly_struct **B, const fmpz_mod_poly_t F, + const fmpz_mod_poly_radix_t D); + +/* Input and output *********************************************************/ + +int _fmpz_mod_poly_fprint(FILE * file, const fmpz *poly, slong len, + const fmpz_t p); + +int fmpz_mod_poly_fprint(FILE * file, const fmpz_mod_poly_t poly); + +int fmpz_mod_poly_fread(FILE * file, fmpz_mod_poly_t poly); + +static __inline__ +int fmpz_mod_poly_fprint_pretty(FILE * file, + const fmpz_mod_poly_t poly, const char * x) +{ + return _fmpz_poly_fprint_pretty(file, poly->coeffs, poly->length, x); +} + +static __inline__ +int _fmpz_mod_poly_print(const fmpz *poly, slong len, const fmpz_t p) +{ + return _fmpz_mod_poly_fprint(stdout, poly, len, p); +} + +static __inline__ +int fmpz_mod_poly_print(const fmpz_mod_poly_t poly) +{ + return fmpz_mod_poly_fprint(stdout, poly); +} + +static __inline__ +int fmpz_mod_poly_print_pretty(const fmpz_mod_poly_t poly, const char * x) +{ + return fmpz_mod_poly_fprint_pretty(stdout, poly, x); +} + +#ifdef __cplusplus +} +#endif + +#include "fmpz_mod_poly_factor.h" + +#endif + diff --git a/external/flint-2.4.3/fmpz_mod_poly/add.c b/external/flint-2.4.3/fmpz_mod_poly/add.c new file mode 100644 index 0000000..75e4bf6 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/add.c @@ -0,0 +1,60 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2008, 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpz_mod_poly.h" + +void _fmpz_mod_poly_add(fmpz *res, const fmpz *poly1, slong len1, + const fmpz *poly2, slong len2, const fmpz_t p) +{ + slong i, len = FLINT_MAX(len1, len2); + + _fmpz_poly_add(res, poly1, len1, poly2, len2); + + for (i = 0; i < len; i++) + { + if (fmpz_cmpabs(res + i, p) >= 0) + fmpz_sub(res + i, res + i, p); + } +} + +void fmpz_mod_poly_add(fmpz_mod_poly_t res, + const fmpz_mod_poly_t poly1, const fmpz_mod_poly_t poly2) +{ + slong max = FLINT_MAX(poly1->length, poly2->length); + + fmpz_mod_poly_fit_length(res, max); + + _fmpz_mod_poly_add(res->coeffs, poly1->coeffs, poly1->length, + poly2->coeffs, poly2->length, &(res->p)); + + _fmpz_mod_poly_set_length(res, max); + _fmpz_mod_poly_normalise(res); +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/clear.c b/external/flint-2.4.3/fmpz_mod_poly/clear.c new file mode 100644 index 0000000..3eff0f8 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/clear.c @@ -0,0 +1,42 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" + +void fmpz_mod_poly_clear(fmpz_mod_poly_t poly) +{ + slong i; + + for (i = 0; i < poly->alloc; i++) /* Clean up any mpz_t's */ + _fmpz_demote(poly->coeffs + i); + if (poly->coeffs) + flint_free(poly->coeffs); /* clean up ordinary coeffs */ + fmpz_clear(&(poly->p)); +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/compose_divconquer.c b/external/flint-2.4.3/fmpz_mod_poly/compose_divconquer.c new file mode 100644 index 0000000..ac53e5a --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/compose_divconquer.c @@ -0,0 +1,160 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 copy1 of the GNU General Public License + along with FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz_mod_poly.h" + +/* + Let i be such that 2^{i} < len1 <= 2^{i+1}. + + Note that the jth step of the recursion requires temporary space + of size no more than (len2 - 1)(2^j - 1) + 1. Note the smallest + step j=0 doesn't require any temporary space and the largest step + has j = i, and hence the sum is + + sum_{j=1}^i [(len2 - 1) (2^j - 1) + 1] + + = (len2 - 1)(2^{i+1} - 2) - (len2 - 2) i + */ + +void _fmpz_mod_poly_compose_divconquer_recursive(fmpz *res, + const fmpz *poly1, slong len1, fmpz **pow2, slong len2, fmpz *v, + const fmpz_t p) +{ + if (len1 == 1) + { + fmpz_set(res, poly1); + } + else if (len1 == 2) + { + _fmpz_mod_poly_scalar_mul_fmpz(res, pow2[0], len2, poly1 + 1, p); + fmpz_add(res, res, poly1); + if (fmpz_cmpabs(res, p) >= 0) + fmpz_sub(res, res, p); + } + else + { + const slong i = FLINT_BIT_COUNT(len1 - 1) - 1; + fmpz *w = v + ((WORD(1) << i) - 1) * (len2 - 1) + 1; + + _fmpz_mod_poly_compose_divconquer_recursive(v, + poly1 + (WORD(1) << i), len1 - (WORD(1) << i), pow2, len2, w, p); + + _fmpz_mod_poly_mul(res, pow2[i], (len2 - 1) * (WORD(1) << i) + 1, + v, (len2 - 1) * (len1 - (WORD(1) << i) - 1) + 1, p); + + _fmpz_mod_poly_compose_divconquer_recursive(v, poly1, WORD(1) << i, + pow2, len2, w, p); + + _fmpz_mod_poly_add(res, res, (len2 - 1) * ((WORD(1) << i) - 1) + 1, + v, (len2 - 1) * ((WORD(1) << i) - 1) + 1, p); + } +} + +void _fmpz_mod_poly_compose_divconquer(fmpz *res, + const fmpz *poly1, slong len1, + const fmpz *poly2, slong len2, + const fmpz_t p) +{ + if (len1 == 1 || len2 == 0) + { + fmpz_set(res, poly1); + } + else + { + const slong k = FLINT_BIT_COUNT(len1 - 1); + const slong lenV = len2 * ((WORD(1) << k) - 1) + k; + const slong lenW = (len2 - 1) * ((WORD(1) << k) - 2) - (len2 - 2) * (k-1); + slong i; + fmpz *v, *w, **pow2; + + v = _fmpz_vec_init(lenV + lenW); + w = v + lenV; + pow2 = flint_malloc(k * sizeof(fmpz *)); + + for (i = 0; i < k; i++) + { + pow2[i] = v + (len2 * ((WORD(1) << i) - 1) + i); + } + + _fmpz_vec_set(pow2[0], poly2, len2); + for (i = 1; i < k; i++) + { + _fmpz_mod_poly_sqr(pow2[i], + pow2[i-1], (len2 - 1) * (WORD(1) << (i - 1)) + 1, p); + } + + _fmpz_mod_poly_compose_divconquer_recursive(res, poly1, len1, + pow2, len2, w, p); + + _fmpz_vec_clear(v, lenV + lenW); + flint_free(pow2); + } +} + +void fmpz_mod_poly_compose_divconquer(fmpz_mod_poly_t res, + const fmpz_mod_poly_t poly1, + const fmpz_mod_poly_t poly2) +{ + const slong len1 = poly1->length; + const slong len2 = poly2->length; + + if (len1 == 0) + { + fmpz_mod_poly_zero(res); + } + else if (len1 == 1 || len2 == 0) + { + fmpz_mod_poly_set_fmpz(res, poly1->coeffs); + } + else + { + const slong lenr = (len1 - 1) * (len2 - 1) + 1; + + if ((res != poly1) && (res != poly2)) + { + fmpz_mod_poly_fit_length(res, lenr); + _fmpz_mod_poly_compose_divconquer(res->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2, + &(res->p)); + } + else + { + fmpz *t = _fmpz_vec_init(lenr); + + _fmpz_mod_poly_compose_divconquer(t, poly1->coeffs, len1, + poly2->coeffs, len2, &(res->p)); + _fmpz_vec_clear(res->coeffs, res->alloc); + res->coeffs = t; + res->alloc = lenr; + res->length = lenr; + } + + _fmpz_mod_poly_set_length(res, lenr); + _fmpz_mod_poly_normalise(res); + } +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/compose_horner.c b/external/flint-2.4.3/fmpz_mod_poly/compose_horner.c new file mode 100644 index 0000000..513f7cc --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/compose_horner.c @@ -0,0 +1,108 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz_mod_poly.h" + +void _fmpz_mod_poly_compose_horner(fmpz *res, const fmpz *poly1, slong len1, + const fmpz *poly2, slong len2, + const fmpz_t p) +{ + if (len1 == 1 || len2 == 0) + { + fmpz_set(res, poly1); + } + else + { + const slong alloc = (len1 - 1) * (len2 - 1) + 1; + slong i = len1 - 1, lenr = len2; + fmpz * t = _fmpz_vec_init(alloc); + + /* + Perform the first two steps as one, + "res = a(m) * poly2 + a(m-1)". + */ + { + _fmpz_mod_poly_scalar_mul_fmpz(res, poly2, len2, poly1 + i, p); + i--; + fmpz_add(res, res, poly1 + i); + if (fmpz_cmpabs(res, p) >= 0) + fmpz_sub(res, res, p); + } + while (i > 0) + { + i--; + _fmpz_mod_poly_mul(t, res, lenr, poly2, len2, p); + lenr += len2 - 1; + _fmpz_mod_poly_add(res, t, lenr, poly1 + i, 1, p); + } + + _fmpz_vec_clear(t, alloc); + } +} + +void fmpz_mod_poly_compose_horner(fmpz_mod_poly_t res, + const fmpz_mod_poly_t poly1, + const fmpz_mod_poly_t poly2) +{ + const slong len1 = poly1->length; + const slong len2 = poly2->length; + + if (len1 == 0) + { + fmpz_mod_poly_zero(res); + } + else if (len1 == 1 || len2 == 0) + { + fmpz_mod_poly_set_fmpz(res, poly1->coeffs); + } + else + { + const slong lenr = (len1 - 1) * (len2 - 1) + 1; + + if ((res != poly1) && (res != poly2)) + { + fmpz_mod_poly_fit_length(res, lenr); + _fmpz_mod_poly_compose_horner(res->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2, + &(res->p)); + } + else + { + fmpz *t = _fmpz_vec_init(lenr); + + _fmpz_mod_poly_compose_horner(t, poly1->coeffs, len1, + poly2->coeffs, len2, &(res->p)); + _fmpz_vec_clear(res->coeffs, res->alloc); + res->coeffs = t; + res->alloc = lenr; + res->length = lenr; + } + + _fmpz_mod_poly_set_length(res, lenr); + _fmpz_mod_poly_normalise(res); + } +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/compose_mod.c b/external/flint-2.4.3/fmpz_mod_poly/compose_mod.c new file mode 100644 index 0000000..6c328a5 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/compose_mod.c @@ -0,0 +1,108 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz_vec.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +void +_fmpz_mod_poly_compose_mod(fmpz * res, const fmpz * f, slong lenf, const fmpz * g, + const fmpz * h, slong lenh, const fmpz_t p) +{ + if (lenh < 12 || lenf >= lenh) + _fmpz_mod_poly_compose_mod_horner(res, f, lenf, g, h, lenh, p); + else + _fmpz_mod_poly_compose_mod_brent_kung(res, f, lenf, g, h, lenh, p); +} + +void +fmpz_mod_poly_compose_mod(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly1, + const fmpz_mod_poly_t poly2, const fmpz_mod_poly_t poly3) +{ + fmpz_t inv3; + slong len1 = poly1->length; + slong len2 = poly2->length; + slong len3 = poly3->length; + slong len = len3 - 1; + slong vec_len = FLINT_MAX(len3 - 1, len2); + + fmpz * ptr2; + + if (len3 == 0) + { + flint_printf("Exception (fmpz_mod_poly_compose_mod)." + "Division by zero.\n"); + abort(); + } + + if (len1 == 0 || len3 == 1) + { + fmpz_mod_poly_zero(res); + return; + } + + if (len1 == 1) + { + fmpz_mod_poly_set(res, poly1); + return; + } + + if (res == poly3 || res == poly1) + { + fmpz_mod_poly_t tmp; + fmpz_mod_poly_init(tmp, &res->p); + fmpz_mod_poly_compose_mod(tmp, poly1, poly2, poly3); + fmpz_mod_poly_swap(tmp, res); + fmpz_mod_poly_clear(tmp); + return; + } + + ptr2 = _fmpz_vec_init(vec_len); + + if (len2 <= len) + { + _fmpz_vec_set(ptr2, poly2->coeffs, len2); + _fmpz_vec_zero(ptr2 + len2, len - len2); + } + else + { + fmpz_init(inv3); + fmpz_invmod(inv3, poly3->coeffs + len, &res->p); + _fmpz_mod_poly_rem(ptr2, poly2->coeffs, len2, + poly3->coeffs, len3, inv3, &res->p); + fmpz_clear(inv3); + } + + fmpz_mod_poly_fit_length(res, len); + _fmpz_mod_poly_compose_mod(res->coeffs, + poly1->coeffs, len1, ptr2, poly3->coeffs, len3, &res->p); + _fmpz_mod_poly_set_length(res, len); + _fmpz_mod_poly_normalise(res); + + _fmpz_vec_clear(ptr2, vec_len); +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/compose_mod_brent_kung.c b/external/flint-2.4.3/fmpz_mod_poly/compose_mod_brent_kung.c new file mode 100644 index 0000000..b40a701 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/compose_mod_brent_kung.c @@ -0,0 +1,181 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz_vec.h" +#include "fmpz_mod_poly.h" +#include "fmpz_mat.h" +#include "ulong_extras.h" + +void +_fmpz_mod_poly_compose_mod_brent_kung(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, const fmpz * poly3, slong len3, + const fmpz_t p) +{ + fmpz_mat_t A, B, C; + fmpz * t, * h, * tmp; + slong i, j, n, m; + + n = len3 - 1; + + if (len3 == 1) + return; + + if (len1 == 1) + { + fmpz_set(res, poly1); + return; + } + + if (len3 == 2) + { + _fmpz_mod_poly_evaluate_fmpz(res, poly1, len1, poly2, p); + return; + } + + m = n_sqrt(n) + 1; + + fmpz_mat_init(A, m, n); + fmpz_mat_init(B, m, m); + fmpz_mat_init(C, m, n); + + h = _fmpz_vec_init(2 * n - 1); + t = _fmpz_vec_init(2 * n - 1); + + /* Set rows of B to the segments of poly1 */ + for (i = 0; i < len1 / m; i++) + _fmpz_vec_set(B->rows[i], poly1 + i * m, m); + + _fmpz_vec_set(B->rows[i], poly1 + i * m, len1 % m); + + /* Set rows of A to powers of poly2 */ + fmpz_one(A->rows[0]); + _fmpz_vec_set(A->rows[1], poly2, n); + tmp = _fmpz_vec_init(2 * n - 1); + for (i = 2; i < m; i++) + { + _fmpz_mod_poly_mulmod(tmp, A->rows[i - 1], n, poly2, n, poly3, len3, p); + _fmpz_vec_set(A->rows[i], tmp, n); + } + _fmpz_vec_clear(tmp, 2 * n - 1); + + fmpz_mat_mul(C, B, A); + for (i = 0; i < m; i++) + for (j = 0; j < n; j++) + fmpz_mod(C->rows[i] + j, C->rows[i] + j, p); + + /* Evaluate block composition using the Horner scheme */ + _fmpz_vec_set(res, C->rows[m - 1], n); + _fmpz_mod_poly_mulmod(h, A->rows[m - 1], n, poly2, n, poly3, len3, p); + + for (i = m - 2; i >= 0; i--) + { + _fmpz_mod_poly_mulmod(t, res, n, h, n, poly3, len3, p); + _fmpz_mod_poly_add(res, t, n, C->rows[i], n, p); + } + + _fmpz_vec_clear(h, 2 * n - 1); + _fmpz_vec_clear(t, 2 * n - 1); + + fmpz_mat_clear(A); + fmpz_mat_clear(B); + fmpz_mat_clear(C); +} + +void +fmpz_mod_poly_compose_mod_brent_kung(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly1, + const fmpz_mod_poly_t poly2, const fmpz_mod_poly_t poly3) +{ + slong len1 = poly1->length; + slong len2 = poly2->length; + slong len3 = poly3->length; + slong len = len3 - 1; + slong vec_len = FLINT_MAX(len3 - 1, len2); + + fmpz * ptr2; + fmpz_t inv3; + + if (len3 == 0) + { + flint_printf("Exception (fmpz_mod_poly_compose_mod_brent_kung)." + "Division by zero in\n"); + abort(); + } + + if (len1 >= len3) + { + flint_printf("Exception (fmpz_mod_poly_compose_brent_kung). the degree of the" + " first polynomial must be smaller than that of the modulus\n"); + abort(); + } + + if (len1 == 0 || len3 == 1) + { + fmpz_mod_poly_zero(res); + return; + } + + if (len1 == 1) + { + fmpz_mod_poly_set(res, poly1); + return; + } + + if (res == poly3 || res == poly1) + { + fmpz_mod_poly_t tmp; + fmpz_mod_poly_init(tmp, &res->p); + fmpz_mod_poly_compose_mod_brent_kung(tmp, poly1, poly2, poly3); + fmpz_mod_poly_swap(tmp, res); + fmpz_mod_poly_clear(tmp); + return; + } + + ptr2 = _fmpz_vec_init(vec_len); + + if (len2 <= len) + { + _fmpz_vec_set(ptr2, poly2->coeffs, len2); + _fmpz_vec_zero(ptr2 + len2, vec_len - len2); + } + else + { + fmpz_init(inv3); + fmpz_invmod(inv3, poly3->coeffs + len, &res->p); + _fmpz_mod_poly_rem(ptr2, poly2->coeffs, len2, + poly3->coeffs, len3, inv3, &res->p); + fmpz_clear(inv3); + } + + fmpz_mod_poly_fit_length(res, len); + _fmpz_mod_poly_compose_mod_brent_kung(res->coeffs, + poly1->coeffs, len1, ptr2, poly3->coeffs, len3, &res->p); + _fmpz_mod_poly_set_length(res, len); + _fmpz_mod_poly_normalise(res); + + _fmpz_vec_clear(ptr2, vec_len); +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/compose_mod_brent_kung_precomp_preinv.c b/external/flint-2.4.3/fmpz_mod_poly/compose_mod_brent_kung_precomp_preinv.c new file mode 100644 index 0000000..25837ae --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/compose_mod_brent_kung_precomp_preinv.c @@ -0,0 +1,255 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Martin Lee + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz_vec.h" +#include "fmpz_mod_poly.h" +#include "fmpz_mat.h" +#include "ulong_extras.h" + +void +_fmpz_mod_poly_reduce_matrix_mod_poly (fmpz_mat_t A, const fmpz_mat_t B, + const fmpz_mod_poly_t f) +{ + fmpz * tmp1, *tmp2; + slong n = f->length - 1; + slong i, m = n_sqrt(n) + 1; + + fmpz_t invf; + fmpz_init(invf); + fmpz_invmod(invf, f->coeffs + n, &f->p); + + fmpz_mat_init(A, m, n); + + fmpz_one(A->rows[0]); + tmp1 = _fmpz_vec_init(2 * (B->c) - n); + tmp2 = tmp1 + (B->c - n); + for (i= 1; i < m; i++) + { + _fmpz_mod_poly_divrem(tmp1, tmp2, B->rows[i], B->c, f->coeffs, + f->length, invf, &f->p); + _fmpz_vec_set(A->rows[i], tmp2, n); + } + + _fmpz_vec_clear(tmp1, 2 * (B->c) - n); + fmpz_clear(invf); +} + +void +_fmpz_mod_poly_precompute_matrix (fmpz_mat_t A, const fmpz * poly1, + const fmpz * poly2, slong len2, const fmpz * poly2inv, + slong len2inv, const fmpz_t p) +{ + /* Set rows of A to powers of poly1 */ + slong i, n, m; + + n = len2 - 1; + + m = n_sqrt(n) + 1; + + fmpz_one(A->rows[0]); + _fmpz_vec_set(A->rows[1], poly1, n); + for (i = 2; i < m; i++) + _fmpz_mod_poly_mulmod_preinv(A->rows[i], A->rows[i - 1], n, poly1, n, + poly2, len2, poly2inv, len2inv, p); +} + +void +fmpz_mod_poly_precompute_matrix(fmpz_mat_t A, const fmpz_mod_poly_t poly1, + const fmpz_mod_poly_t poly2, const fmpz_mod_poly_t poly2inv) +{ + slong len1 = poly1->length; + slong len2 = poly2->length; + slong len = len2 - 1; + slong vec_len = FLINT_MAX(len2 - 1, len1); + slong m= n_sqrt(len) + 1; + + fmpz* ptr; + fmpz_t inv2; + + if (len2 == 0) + { + flint_printf("Exception (fmpz_mod_poly_precompute_matrix)." + "Division by zero.\n"); + abort(); + } + + if (A->r != m || A->c != len) + { + flint_printf("Exception (fmpz_mod_poly_precompute_matrix)." + " Wrong dimensions.\n"); + abort(); + } + + if (len2 == 1) + { + fmpz_mat_zero(A); + return; + } + + ptr = _fmpz_vec_init(vec_len); + + if (len1 <= len) + { + _fmpz_vec_set(ptr, poly1->coeffs, len1); + _fmpz_vec_zero(ptr + len1, vec_len - len1); + } + else + { + fmpz_init(inv2); + fmpz_invmod(inv2, poly2->coeffs + len, &poly1->p); + _fmpz_mod_poly_rem(ptr, poly1->coeffs, len1, + poly2->coeffs, len2, inv2, &poly1->p); + fmpz_clear(inv2); + } + + _fmpz_mod_poly_precompute_matrix (A, ptr, poly2->coeffs, len2, + poly2inv->coeffs, poly2inv->length, &poly1->p); + + _fmpz_vec_clear(ptr, vec_len); +} + +void +_fmpz_mod_poly_compose_mod_brent_kung_precomp_preinv(fmpz * res, + const fmpz * poly1, slong len1, const fmpz_mat_t A, const fmpz * poly3, + slong len3, const fmpz * poly3inv, slong len3inv, const fmpz_t p) +{ + fmpz_mat_t B, C; + fmpz * t, * h; + slong i, j, n, m; + + n = len3 - 1; + + if (len3 == 1) + return; + + if (len1 == 1) + { + fmpz_set(res, poly1); + return; + } + + if (len3 == 2) + { + _fmpz_mod_poly_evaluate_fmpz(res, poly1, len1, A->rows[1], p); + return; + } + + m = n_sqrt(n) + 1; + + fmpz_mat_init(B, m, m); + fmpz_mat_init(C, m, n); + + h = _fmpz_vec_init(n); + t = _fmpz_vec_init(n); + + /* Set rows of B to the segments of poly1 */ + for (i = 0; i < len1 / m; i++) + _fmpz_vec_set(B->rows[i], poly1 + i * m, m); + + _fmpz_vec_set(B->rows[i], poly1 + i * m, len1 % m); + + fmpz_mat_mul(C, B, A); + for (i = 0; i < m; i++) + for (j = 0; j < n; j++) + fmpz_mod(C->rows[i] + j, C->rows[i] + j, p); + + /* Evaluate block composition using the Horner scheme */ + _fmpz_vec_set(res, C->rows[m - 1], n); + _fmpz_mod_poly_mulmod_preinv(h, A->rows[m - 1], n, A->rows[1], n, poly3, + len3, poly3inv, len3inv, p); + + for (i = m - 2; i >= 0; i--) + { + _fmpz_mod_poly_mulmod_preinv(t, res, n, h, n, poly3, len3, + poly3inv, len3inv, p); + _fmpz_mod_poly_add(res, t, n, C->rows[i], n, p); + } + + _fmpz_vec_clear(h, n); + _fmpz_vec_clear(t, n); + + fmpz_mat_clear(B); + fmpz_mat_clear(C); +} + +void +fmpz_mod_poly_compose_mod_brent_kung_precomp_preinv(fmpz_mod_poly_t res, + const fmpz_mod_poly_t poly1, const fmpz_mat_t A, + const fmpz_mod_poly_t poly3, const fmpz_mod_poly_t poly3inv) +{ + slong len1 = poly1->length; + slong len3 = poly3->length; + slong len = len3 - 1; + + if (len3 == 0) + { + flint_printf("Exception (fmpz_mod_poly_compose_mod_brent_kung_precomp_preinv)." + "Division by zero\n"); + abort(); + } + + if (len1 >= len3) + { + flint_printf("Exception (fmpz_mod_poly_compose_mod_brent_kung_precomp_preinv)." + "The degree of the first polynomial must be smaller than that of the " + " modulus\n"); + abort(); + } + + if (len1 == 0 || len3 == 1) + { + fmpz_mod_poly_zero(res); + return; + } + + if (len1 == 1) + { + fmpz_mod_poly_set(res, poly1); + return; + } + + if (res == poly3 || res == poly1 || res == poly3inv) + { + fmpz_mod_poly_t tmp; + fmpz_mod_poly_init(tmp, &res->p); + fmpz_mod_poly_compose_mod_brent_kung_precomp_preinv(tmp, poly1, A, + poly3, poly3inv); + fmpz_mod_poly_swap(tmp, res); + fmpz_mod_poly_clear(tmp); + return; + } + + fmpz_mod_poly_fit_length(res, len); + _fmpz_mod_poly_compose_mod_brent_kung_precomp_preinv(res->coeffs, + poly1->coeffs, len1, A, poly3->coeffs, len3, + poly3inv->coeffs, poly3inv->length, &res->p); + _fmpz_mod_poly_set_length(res, len); + _fmpz_mod_poly_normalise(res); + +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/compose_mod_brent_kung_preinv.c b/external/flint-2.4.3/fmpz_mod_poly/compose_mod_brent_kung_preinv.c new file mode 100644 index 0000000..54cf39a --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/compose_mod_brent_kung_preinv.c @@ -0,0 +1,183 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Martin Lee + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz_vec.h" +#include "fmpz_mod_poly.h" +#include "fmpz_mat.h" +#include "ulong_extras.h" + +void +_fmpz_mod_poly_compose_mod_brent_kung_preinv(fmpz * res, const fmpz * poly1, + slong len1, const fmpz * poly2, const fmpz * poly3, slong len3, + const fmpz * poly3inv, slong len3inv, const fmpz_t p) +{ + fmpz_mat_t A, B, C; + fmpz * t, * h; + slong i, j, n, m; + + n = len3 - 1; + + if (len3 == 1) + return; + + if (len1 == 1) + { + fmpz_set(res, poly1); + return; + } + + if (len3 == 2) + { + _fmpz_mod_poly_evaluate_fmpz(res, poly1, len1, poly2, p); + return; + } + + m = n_sqrt(n) + 1; + + fmpz_mat_init(A, m, n); + fmpz_mat_init(B, m, m); + fmpz_mat_init(C, m, n); + + h = _fmpz_vec_init(2 * n - 1); + t = _fmpz_vec_init(2 * n - 1); + + /* Set rows of B to the segments of poly1 */ + for (i = 0; i < len1 / m; i++) + _fmpz_vec_set(B->rows[i], poly1 + i * m, m); + + _fmpz_vec_set(B->rows[i], poly1 + i * m, len1 % m); + + /* Set rows of A to powers of poly2 */ + fmpz_one(A->rows[0]); + _fmpz_vec_set(A->rows[1], poly2, n); + for (i = 2; i < m; i++) + _fmpz_mod_poly_mulmod_preinv (A->rows[i], A->rows[i - 1], n, poly2, n, + poly3, len3, poly3inv, len3inv, p); + + fmpz_mat_mul(C, B, A); + for (i = 0; i < m; i++) + for (j = 0; j < n; j++) + fmpz_mod(C->rows[i] + j, C->rows[i] + j, p); + + /* Evaluate block composition using the Horner scheme */ + _fmpz_vec_set(res, C->rows[m - 1], n); + _fmpz_mod_poly_mulmod_preinv(h, A->rows[m - 1], n, poly2, n, poly3, len3, + poly3inv, len3inv, p); + + for (i = m - 2; i >= 0; i--) + { + _fmpz_mod_poly_mulmod_preinv(t, res, n, h, n, poly3, len3, + poly3inv, len3inv, p); + _fmpz_mod_poly_add(res, t, n, C->rows[i], n, p); + } + + _fmpz_vec_clear(h, 2 * n - 1); + _fmpz_vec_clear(t, 2 * n - 1); + + fmpz_mat_clear(A); + fmpz_mat_clear(B); + fmpz_mat_clear(C); +} + +void +fmpz_mod_poly_compose_mod_brent_kung_preinv(fmpz_mod_poly_t res, + const fmpz_mod_poly_t poly1, const fmpz_mod_poly_t poly2, + const fmpz_mod_poly_t poly3, const fmpz_mod_poly_t poly3inv) +{ + slong len1 = poly1->length; + slong len2 = poly2->length; + slong len3 = poly3->length; + slong len = len3 - 1; + + fmpz * ptr2; + fmpz_t inv3; + + if (len3 == 0) + { + flint_printf("Exception (fmpz_mod_poly_compose_mod_brent_kung preinv)." + "Division by zero\n"); + abort(); + } + + if (len1 >= len3) + { + flint_printf("Exception (fmpz_mod_poly_compose_mod_brent_kung_preinv)." + "The degree of the first polynomial must be smaller than that of the " + " modulus\n"); + abort(); + } + + if (len1 == 0 || len3 == 1) + { + fmpz_mod_poly_zero(res); + return; + } + + if (len1 == 1) + { + fmpz_mod_poly_set(res, poly1); + return; + } + + if (res == poly3 || res == poly1 || res == poly3inv) + { + fmpz_mod_poly_t tmp; + fmpz_mod_poly_init(tmp, &res->p); + fmpz_mod_poly_compose_mod_brent_kung_preinv(tmp, poly1, poly2, + poly3, poly3inv); + fmpz_mod_poly_swap(tmp, res); + fmpz_mod_poly_clear(tmp); + return; + } + + ptr2 = _fmpz_vec_init(len); + + if (len2 <= len) + { + _fmpz_vec_set(ptr2, poly2->coeffs, len2); + _fmpz_vec_zero(ptr2 + len2, len - len2); + } + else + { + fmpz_init(inv3); + fmpz_invmod(inv3, poly3->coeffs + len, &res->p); + _fmpz_mod_poly_rem(ptr2, poly2->coeffs, len2, + poly3->coeffs, len3, inv3, &res->p); + fmpz_clear(inv3); + } + + fmpz_mod_poly_fit_length(res, len); + _fmpz_mod_poly_compose_mod_brent_kung_preinv(res->coeffs, + poly1->coeffs, len1, ptr2, poly3->coeffs, len3, + poly3inv->coeffs, poly3inv->length, &res->p); + _fmpz_mod_poly_set_length(res, len); + _fmpz_mod_poly_normalise(res); + + _fmpz_vec_clear(ptr2, len); +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/compose_mod_horner.c b/external/flint-2.4.3/fmpz_mod_poly/compose_mod_horner.c new file mode 100644 index 0000000..1af883f --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/compose_mod_horner.c @@ -0,0 +1,141 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz_vec.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +void +_fmpz_mod_poly_compose_mod_horner(fmpz * res, const fmpz * f, slong lenf, const fmpz * g, + const fmpz * h, slong lenh, const fmpz_t p) +{ + slong i, len; + fmpz * t; + + if (lenh == 1) + return; + + if (lenf == 1) + { + fmpz_set(res, f); + return; + } + + if (lenh == 2) + { + _fmpz_mod_poly_evaluate_fmpz(res, f, lenf, g, p); + return; + } + + len = lenh - 1; + i = lenf - 1; + t = _fmpz_vec_init(2 * lenh - 3); + + _fmpz_mod_poly_scalar_mul_fmpz(res, g, len, f + i, p); + i--; + if (i >= 0) + { + fmpz_add(res, res, f + i); + fmpz_mod(res, res, p); + } + + while (i > 0) + { + i--; + _fmpz_mod_poly_mulmod(t, res, len, g, len, h, lenh, p); + _fmpz_mod_poly_add(res, t, len, f + i, 1, p); + } + + _fmpz_vec_clear(t, 2 * lenh - 3); +} + +void +fmpz_mod_poly_compose_mod_horner(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly1, + const fmpz_mod_poly_t poly2, const fmpz_mod_poly_t poly3) +{ + fmpz_t inv3; + slong len1 = poly1->length; + slong len2 = poly2->length; + slong len3 = poly3->length; + slong len = len3 - 1; + slong vec_len = FLINT_MAX(len3 - 1, len2); + + fmpz * ptr2; + + if (len3 == 0) + { + flint_printf("Exception (fmpz_mod_poly_compose_mod_horner). Division by zero \n"); + abort(); + } + + if (len1 == 0 || len3 == 1) + { + fmpz_mod_poly_zero(res); + return; + } + + if (len1 == 1) + { + fmpz_mod_poly_set(res, poly1); + return; + } + + if (res == poly3 || res == poly1) + { + fmpz_mod_poly_t tmp; + fmpz_mod_poly_init(tmp, &res->p); + fmpz_mod_poly_compose_mod_horner(tmp, poly1, poly2, poly3); + fmpz_mod_poly_swap(tmp, res); + fmpz_mod_poly_clear(tmp); + return; + } + + ptr2 = _fmpz_vec_init(vec_len); + + if (len2 <= len3 - 1) + { + _fmpz_vec_set(ptr2, poly2->coeffs, len2); + _fmpz_vec_zero(ptr2 + len2, vec_len - len2); + } + else + { + fmpz_init(inv3); + fmpz_invmod(inv3, poly3->coeffs + len, &res->p); + _fmpz_mod_poly_rem(ptr2, poly2->coeffs, len2, + poly3->coeffs, len3, inv3, &res->p); + fmpz_clear(inv3); + } + + fmpz_mod_poly_fit_length(res, len); + _fmpz_mod_poly_compose_mod_horner(res->coeffs, + poly1->coeffs, len1, ptr2, poly3->coeffs, len3, &res->p); + _fmpz_mod_poly_set_length(res, len); + _fmpz_mod_poly_normalise(res); + + _fmpz_vec_clear(ptr2, vec_len); +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/derivative.c b/external/flint-2.4.3/fmpz_mod_poly/derivative.c new file mode 100644 index 0000000..706fc72 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/derivative.c @@ -0,0 +1,70 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpz_mod_poly.h" + +void _fmpz_mod_poly_derivative(fmpz *res, const fmpz *poly, slong len, + const fmpz_t p) +{ + slong j, k = 1; + + for (j = 1; j < len; j++) + { + if (k == 0) + fmpz_zero(res + (j - 1)); + else if (k == 1) + fmpz_set(res + (j - 1), poly + j); + else + { + fmpz_mul_ui(res + (j - 1), poly + j, k); + fmpz_mod(res + (j - 1), res + (j - 1), p); + } + + if (fmpz_equal_ui(p, ++k)) + k = 0; + } +} + +void fmpz_mod_poly_derivative(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly) +{ + const slong len = poly->length; + + if (len < 2) + { + fmpz_mod_poly_zero(res); + } + else + { + fmpz_mod_poly_fit_length(res, len - 1); + _fmpz_mod_poly_derivative(res->coeffs, poly->coeffs, len, &(res->p)); + _fmpz_mod_poly_set_length(res, len - 1); + _fmpz_mod_poly_normalise(res); + } +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/div_basecase.c b/external/flint-2.4.3/fmpz_mod_poly/div_basecase.c new file mode 100644 index 0000000..6c7ce1e --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/div_basecase.c @@ -0,0 +1,114 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2010 Sebastian Pancratz + Copyright (C) 2008, 2009 William Hart + +******************************************************************************/ + +#include +#include "fmpz_vec.h" +#include "fmpz_mod_poly.h" + +void _fmpz_mod_poly_div_basecase(fmpz *Q, fmpz *R, + const fmpz *A, slong lenA, const fmpz *B, slong lenB, + const fmpz_t invB, const fmpz_t p) +{ + const slong alloc = (R == NULL) ? lenA : 0; + slong lenR = lenB - 1, iQ; + + if (alloc) + R = _fmpz_vec_init(alloc); + if (R != A) + _fmpz_vec_set(R + lenR, A + lenR, lenA - lenR); + + for (iQ = lenA - lenB; iQ >= 0; iQ--) + { + if (fmpz_is_zero(R + lenA - 1)) + { + fmpz_zero(Q + iQ); + } + else + { + fmpz_mul(Q + iQ, R + lenA - 1, invB); + fmpz_mod(Q + iQ, Q + iQ, p); + + _fmpz_vec_scalar_submul_fmpz(R + lenA - lenR - 1, B, lenR, Q + iQ); + _fmpz_vec_scalar_mod_fmpz(R + lenA - lenR - 1, R + lenA - lenR - 1, lenR, p); + } + + if (lenR - 1 >= iQ) + { + B++; + lenR--; + } + + lenA--; + } + + if (alloc) + _fmpz_vec_clear(R, alloc); +} + +void fmpz_mod_poly_div_basecase(fmpz_mod_poly_t Q, + const fmpz_mod_poly_t A, const fmpz_mod_poly_t B) +{ + const slong lenA = A->length, lenB = B->length, lenQ = lenA - lenB + 1; + fmpz *q; + fmpz_t invB; + + if (lenA < lenB) + { + fmpz_mod_poly_zero(Q); + return; + } + + fmpz_init(invB); + fmpz_invmod(invB, B->coeffs + (lenB - 1), &(B->p)); + + if (Q == A || Q == B) + { + q = _fmpz_vec_init(lenQ); + } + else + { + fmpz_mod_poly_fit_length(Q, lenQ); + q = Q->coeffs; + } + + _fmpz_mod_poly_div_basecase(q, NULL, A->coeffs, lenA, + B->coeffs, lenB, invB, &(B->p)); + + if (Q == A || Q == B) + { + _fmpz_vec_clear(Q->coeffs, Q->alloc); + Q->coeffs = q; + Q->alloc = lenQ; + Q->length = lenQ; + } + else + { + _fmpz_mod_poly_set_length(Q, lenQ); + } + + fmpz_clear(invB); +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/div_newton_n_preinv.c b/external/flint-2.4.3/fmpz_mod_poly/div_newton_n_preinv.c new file mode 100644 index 0000000..7bb33af --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/div_newton_n_preinv.c @@ -0,0 +1,111 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2010 Sebastian Pancratz + Copyright (C) 2008, 2009 William Hart + Copyright (C) 2013 Martin Lee + +******************************************************************************/ + +#undef ulong +#define ulong ulongxx/* interferes with system includes */ + +#include + +#undef ulong + +#include + +#define ulong mp_limb_t + +#include "fmpz_vec.h" +#include "fmpz_mod_poly.h" + +void _fmpz_mod_poly_div_newton_n_preinv (fmpz* Q, const fmpz* A, slong lenA, + const fmpz* B, slong lenB, const fmpz* Binv, + slong lenBinv, const fmpz_t mod) +{ + const slong lenQ = lenA - lenB + 1; + fmpz * Arev; + + Arev = _fmpz_vec_init(lenQ); + + _fmpz_poly_reverse(Arev, A + (lenA - lenQ), lenQ, lenQ); + + _fmpz_mod_poly_mullow(Q, Arev, lenQ, Binv, FLINT_MIN(lenQ, lenBinv), mod, + lenQ); + + _fmpz_poly_reverse(Q, Q, lenQ, lenQ); + + _fmpz_vec_clear(Arev, lenQ); +} + + +void fmpz_mod_poly_div_newton_n_preinv(fmpz_mod_poly_t Q, + const fmpz_mod_poly_t A, const fmpz_mod_poly_t B, + const fmpz_mod_poly_t Binv) +{ + const slong lenA = A->length, lenB = B->length, lenQ = lenA - lenB + 1, + lenBinv = Binv->length; + fmpz *q; + + if (lenB == 0) + { + flint_printf("Exception (fmpz_mod_poly_div_newton_n_preinv). Division by zero.\n"); + abort(); + } + + if (lenA < lenB) + { + fmpz_mod_poly_zero(Q); + return; + } + + if (lenA > 2 * lenB - 2) + { + flint_printf ("Exception (fmpz_mod_poly_div_newton_n_preinv).\n"); + } + + if (Q == A || Q == B || Q == Binv) + { + q = _fmpz_vec_init(lenQ); + } + else + { + fmpz_mod_poly_fit_length(Q, lenQ); + q = Q->coeffs; + } + + _fmpz_mod_poly_div_newton_n_preinv (q, A->coeffs, lenA, B->coeffs, lenB, + Binv->coeffs, lenBinv, &(B->p)); + + if (Q == A || Q == B || Q == Binv) + { + _fmpz_vec_clear(Q->coeffs, Q->alloc); + Q->coeffs = q; + Q->alloc = lenQ; + Q->length = lenQ; + } + else + { + _fmpz_mod_poly_set_length(Q, lenQ); + } +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/divrem_basecase.c b/external/flint-2.4.3/fmpz_mod_poly/divrem_basecase.c new file mode 100644 index 0000000..a6a8e92 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/divrem_basecase.c @@ -0,0 +1,121 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2010 Sebastian Pancratz + Copyright (C) 2008, 2009 William Hart + +******************************************************************************/ + +#include +#include "fmpz_vec.h" +#include "fmpz_mod_poly.h" + +void _fmpz_mod_poly_divrem_basecase(fmpz *Q, fmpz *R, + const fmpz *A, slong lenA, const fmpz *B, slong lenB, + const fmpz_t invB, const fmpz_t p) +{ + slong iQ, iR; + + if (R != A) + _fmpz_vec_set(R, A, lenA); + + for (iQ = lenA - lenB, iR = lenA - 1; iQ >= 0; iQ--, iR--) + { + if (fmpz_is_zero(R + iR)) + fmpz_zero(Q + iQ); + else + { + fmpz_mul(Q + iQ, R + iR, invB); + fmpz_mod(Q + iQ, Q + iQ, p); + + _fmpz_vec_scalar_submul_fmpz(R + iQ, B, lenB, Q + iQ); + _fmpz_vec_scalar_mod_fmpz(R + iQ, R + iQ, lenB, p); + } + } +} + +void fmpz_mod_poly_divrem_basecase(fmpz_mod_poly_t Q, fmpz_mod_poly_t R, + const fmpz_mod_poly_t A, const fmpz_mod_poly_t B) +{ + const slong lenA = A->length, lenB = B->length, lenQ = lenA - lenB + 1; + fmpz *q, *r; + fmpz_t invB; + + if (lenA < lenB) + { + fmpz_mod_poly_set(R, A); + fmpz_mod_poly_zero(Q); + return; + } + + fmpz_init(invB); + fmpz_invmod(invB, B->coeffs + (lenB - 1), &(B->p)); + + if (Q == A || Q == B) + { + q = _fmpz_vec_init(lenQ); + } + else + { + fmpz_mod_poly_fit_length(Q, lenQ); + q = Q->coeffs; + } + if (R == B) + { + r = _fmpz_vec_init(lenA); + } + else + { + fmpz_mod_poly_fit_length(R, lenA); + r = R->coeffs; + } + + _fmpz_mod_poly_divrem_basecase(q, r, A->coeffs, lenA, + B->coeffs, lenB, invB, &(B->p)); + + if (Q == A || Q == B) + { + _fmpz_vec_clear(Q->coeffs, Q->alloc); + Q->coeffs = q; + Q->alloc = lenQ; + Q->length = lenQ; + } + else + { + _fmpz_mod_poly_set_length(Q, lenQ); + } + if (R == B) + { + _fmpz_vec_clear(R->coeffs, R->alloc); + R->coeffs = r; + R->alloc = lenB - 1; + R->length = lenB - 1; + } + else + { + _fmpz_mod_poly_set_length(R, lenB - 1); + } + + _fmpz_mod_poly_normalise(R); + + fmpz_clear(invB); +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/divrem_divconquer.c b/external/flint-2.4.3/fmpz_mod_poly/divrem_divconquer.c new file mode 100644 index 0000000..17e8cbc --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/divrem_divconquer.c @@ -0,0 +1,196 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_mod_poly.h" + +static void +__fmpz_mod_poly_divrem_divconquer(fmpz * Q, fmpz * R, + const fmpz * A, slong lenA, const fmpz * B, slong lenB, + const fmpz_t invB, const fmpz_t p) +{ + if (lenA < 2 * lenB - 1) + { + /* + Convert unbalanced division into a 2 n1 - 1 by n1 division + */ + + const slong n1 = lenA - lenB + 1; + const slong n2 = lenB - n1; + + const fmpz * p1 = A + n2; + const fmpz * d1 = B + n2; + const fmpz * d2 = B; + + fmpz * W = _fmpz_vec_init((2 * n1 - 1) + lenB - 1); + + fmpz * d1q1 = R + n2; + fmpz * d2q1 = W + (2 * n1 - 1); + + _fmpz_mod_poly_divrem_divconquer_recursive(Q, d1q1, W, p1, d1, n1, + invB, p); + + /* + Compute d2q1 = Q d2, of length lenB - 1 + */ + + if (n1 >= n2) + _fmpz_mod_poly_mul(d2q1, Q, n1, d2, n2, p); + else + _fmpz_mod_poly_mul(d2q1, d2, n2, Q, n1, p); + + /* + Compute BQ = d1q1 * x^n1 + d2q1, of length lenB - 1; + then compute R = A - BQ + */ + + _fmpz_vec_swap(R, d2q1, n2); + _fmpz_mod_poly_add(R + n2, R + n2, n1 - 1, d2q1 + n2, n1 - 1, p); + _fmpz_mod_poly_sub(R, A, lenA, R, lenA, p); + + _fmpz_vec_clear(W, (2 * n1 - 1) + lenB - 1); + } + else /* lenA = 2 * lenB - 1 */ + { + fmpz * W = _fmpz_vec_init(lenA); + + _fmpz_mod_poly_divrem_divconquer_recursive(Q, R, W, + A, B, lenB, invB, p); + + _fmpz_mod_poly_sub(R, A, lenB - 1, R, lenB - 1, p); + + _fmpz_vec_clear(W, lenA); + } +} + +void _fmpz_mod_poly_divrem_divconquer(fmpz *Q, fmpz *R, + const fmpz *A, slong lenA, const fmpz *B, slong lenB, + const fmpz_t invB, const fmpz_t p) +{ + if (lenA <= 2 * lenB - 1) + { + __fmpz_mod_poly_divrem_divconquer(Q, R, A, lenA, B, lenB, invB, p); + } + else /* lenA > 2 * lenB - 1 */ + { + slong shift, n = 2 * lenB - 1; + fmpz *QB, *W; + + _fmpz_vec_set(R, A, lenA); + W = _fmpz_vec_init(2 * n); + QB = W + n; + + while (lenA >= n) + { + shift = lenA - n; + _fmpz_mod_poly_divrem_divconquer_recursive(Q + shift, QB, + W, R + shift, B, lenB, invB, p); + _fmpz_mod_poly_sub(R + shift, R + shift, n, QB, n, p); + lenA -= lenB; + } + + if (lenA >= lenB) + { + __fmpz_mod_poly_divrem_divconquer(Q, W, R, lenA, B, lenB, invB, p); + _fmpz_vec_swap(W, R, lenA); + } + + _fmpz_vec_clear(W, 2 * n); + } +} + +void +fmpz_mod_poly_divrem_divconquer(fmpz_mod_poly_t Q, fmpz_mod_poly_t R, + const fmpz_mod_poly_t A, const fmpz_mod_poly_t B) +{ + const slong lenA = A->length; + const slong lenB = B->length; + const slong lenQ = lenA - lenB + 1; + + fmpz *q, *r; + fmpz_t invB; + + if (lenA < lenB) + { + fmpz_mod_poly_set(R, A); + fmpz_mod_poly_zero(Q); + return; + } + + fmpz_init(invB); + fmpz_invmod(invB, fmpz_mod_poly_lead(B), &(B->p)); + + if (Q == A || Q == B) + { + q = _fmpz_vec_init(lenQ); + } + else + { + fmpz_mod_poly_fit_length(Q, lenQ); + q = Q->coeffs; + } + + if (R == A || R == B) + { + r = _fmpz_vec_init(lenA); + } + else + { + fmpz_mod_poly_fit_length(R, lenA); + r = R->coeffs; + } + + _fmpz_mod_poly_divrem_divconquer(q, r, A->coeffs, lenA, + B->coeffs, lenB, invB, &(B->p)); + + if (Q == A || Q == B) + { + _fmpz_vec_clear(Q->coeffs, Q->alloc); + Q->coeffs = q; + Q->alloc = lenQ; + Q->length = lenQ; + } + else + { + _fmpz_mod_poly_set_length(Q, lenQ); + } + + if (R == A || R == B) + { + _fmpz_vec_clear(R->coeffs, R->alloc); + R->coeffs = r; + R->alloc = lenA; + R->length = lenA; + } + _fmpz_mod_poly_set_length(R, lenB - 1); + _fmpz_mod_poly_normalise(R); + + fmpz_clear(invB); +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/divrem_divconquer_recursive.c b/external/flint-2.4.3/fmpz_mod_poly/divrem_divconquer_recursive.c new file mode 100644 index 0000000..9475a37 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/divrem_divconquer_recursive.c @@ -0,0 +1,140 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_mod_poly.h" + +#define FMPZ_MOD_POLY_DIVREM_DIVCONQUER_CUTOFF 16 + +void +_fmpz_mod_poly_divrem_divconquer_recursive(fmpz * Q, fmpz * BQ, fmpz * W, + const fmpz * A, const fmpz * B, slong lenB, + const fmpz_t invB, const fmpz_t p) +{ + if (lenB <= FMPZ_MOD_POLY_DIVREM_DIVCONQUER_CUTOFF) + { + _fmpz_vec_zero(BQ, lenB - 1); + _fmpz_vec_set(BQ + (lenB - 1), A + (lenB - 1), lenB); + + _fmpz_mod_poly_divrem_basecase(Q, BQ, BQ, 2 * lenB - 1, B, lenB, invB, p); + + _fmpz_mod_poly_neg(BQ, BQ, lenB - 1, p); + _fmpz_vec_set(BQ + (lenB - 1), A + (lenB - 1), lenB); + } + else + { + const slong n2 = lenB / 2; + const slong n1 = lenB - n2; + + fmpz * W1 = W; + fmpz * W2 = W + lenB; + + const fmpz * p1 = A + 2 * n2; + const fmpz * p2; + const fmpz * d1 = B + n2; + const fmpz * d2 = B; + const fmpz * d3 = B + n1; + const fmpz * d4 = B; + + fmpz * q1 = Q + n2; + fmpz * q2 = Q; + fmpz * dq1 = BQ + n2; + fmpz * d1q1 = BQ + 2 * n2; + + fmpz *d2q1, *d3q2, *d4q2, *t; + + /* + Set q1 to p1 div d1, a 2 n1 - 1 by n1 division so q1 ends up + being of length n1; d1q1 = d1 q1 is of length 2 n1 - 1 + */ + + _fmpz_mod_poly_divrem_divconquer_recursive(q1, d1q1, W1, + p1, d1, n1, invB, p); + + /* + Compute d2q1 = d2 q1, of length lenB - 1 + */ + + d2q1 = W1; + _fmpz_mod_poly_mul(d2q1, q1, n1, d2, n2, p); + + /* + Compute dq1 = d1 q1 x^n2 + d2 q1, of length 2 n1 + n2 - 1 + */ + + _fmpz_vec_swap(dq1, d2q1, n2); + _fmpz_mod_poly_add(dq1 + n2, dq1 + n2, n1 - 1, d2q1 + n2, n1 - 1, p); + + /* + Compute t = A/x^n2 - dq1, which has length 2 n1 + n2 - 1, but we + are not interested in the top n1 coeffs as they will be zero, so + this has effective length n1 + n2 - 1 + + For the following division, we want to set {p2, 2 n2 - 1} to the + top 2 n2 - 1 coeffs of this + + Since the bottom n2 - 1 coeffs of p2 are irrelevant for the + division, we in fact set {t, n2} to the relevant coeffs + */ + + t = BQ; + _fmpz_mod_poly_sub(t, A + n2 + (n1 - 1), n2, dq1 + (n1 - 1), n2, p); + p2 = t - (n2 - 1); + + /* + Compute q2 = t div d3, a 2 n2 - 1 by n2 division, so q2 will have + length n2; let d3q2 = d3 q2, of length 2 n2 - 1 + */ + + d3q2 = W1; + _fmpz_mod_poly_divrem_divconquer_recursive(q2, d3q2, W2, + p2, d3, n2, invB, p); + + /* + Compute d4q2 = d4 q2, of length n1 + n2 - 1 = lenB - 1 + */ + + d4q2 = W2; + _fmpz_mod_poly_mul(d4q2, d4, n1, q2, n2, p); + + /* + Compute dq2 = d3q2 x^n1 + d4q2, of length n1 + 2 n2 - 1 + */ + + _fmpz_vec_swap(BQ, d4q2, n2); + _fmpz_mod_poly_add(BQ + n2, BQ + n2, n1 - 1, d4q2 + n2, n1 - 1, p); + _fmpz_mod_poly_add(BQ + n1, BQ + n1, 2 * n2 - 1, d3q2, 2 * n2 - 1, p); + + /* + Note Q = q1 x^n2 + q2, and BQ = dq1 x^n2 + dq2 + */ + } +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/divrem_f.c b/external/flint-2.4.3/fmpz_mod_poly/divrem_f.c new file mode 100644 index 0000000..33dd6d5 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/divrem_f.c @@ -0,0 +1,120 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "fmpz_vec.h" +#include "fmpz_mod_poly.h" + +void _fmpz_mod_poly_divrem_f(fmpz_t f, fmpz *Q, fmpz *R, + const fmpz *A, slong lenA, + const fmpz *B, slong lenB, const fmpz_t p) +{ + fmpz_t invB; + + fmpz_init(invB); + fmpz_gcdinv(f, invB, B + lenB - 1, p); + + if (fmpz_is_one(f)) + { + _fmpz_mod_poly_divrem(Q, R, A, lenA, B, lenB, invB, p); + } + + fmpz_clear(invB); +} + +void fmpz_mod_poly_divrem_f(fmpz_t f, fmpz_mod_poly_t Q, fmpz_mod_poly_t R, + const fmpz_mod_poly_t A, const fmpz_mod_poly_t B) +{ + const slong lenA = A->length; + const slong lenB = B->length; + const slong lenQ = lenA - lenB + 1; + + fmpz *q, *r; + fmpz_t invB; + + fmpz_init(invB); + fmpz_gcdinv(f, invB, fmpz_poly_lead(B), &(B->p)); + + if (!fmpz_is_one(f)) + { + fmpz_clear(invB); + return; + } + + if (lenA < lenB) + { + fmpz_mod_poly_set(R, A); + fmpz_mod_poly_zero(Q); + fmpz_clear(invB); + return; + } + + if (Q == A || Q == B) + { + q = _fmpz_vec_init(lenQ); + } + else + { + fmpz_mod_poly_fit_length(Q, lenQ); + q = Q->coeffs; + } + + if (R == A || R == B) + { + r = _fmpz_vec_init(lenA); + } + else + { + fmpz_mod_poly_fit_length(R, lenA); + r = R->coeffs; + } + + _fmpz_mod_poly_divrem_divconquer(q, r, A->coeffs, lenA, + B->coeffs, lenB, invB, &(B->p)); + + if (Q == A || Q == B) + { + _fmpz_vec_clear(Q->coeffs, Q->alloc); + Q->coeffs = q; + Q->alloc = lenQ; + Q->length = lenQ; + } + else + { + _fmpz_mod_poly_set_length(Q, lenQ); + } + + if (R == A || R == B) + { + _fmpz_vec_clear(R->coeffs, R->alloc); + R->coeffs = r; + R->alloc = lenA; + R->length = lenA; + } + _fmpz_mod_poly_set_length(R, lenB - 1); + _fmpz_mod_poly_normalise(R); + + fmpz_clear(invB); +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/divrem_newton_n_preinv.c b/external/flint-2.4.3/fmpz_mod_poly/divrem_newton_n_preinv.c new file mode 100644 index 0000000..fc32093 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/divrem_newton_n_preinv.c @@ -0,0 +1,134 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Martin Lee + +******************************************************************************/ + +#undef ulong +#define ulong ulongxx/* interferes with system includes */ + +#include + +#undef ulong + +#include + +#define ulong mp_limb_t + +#include "fmpz_vec.h" +#include "fmpz_mod_poly.h" + +void _fmpz_mod_poly_divrem_newton_n_preinv (fmpz* Q, fmpz* R, const fmpz* A, + slong lenA, const fmpz* B, slong lenB, + const fmpz* Binv, slong lenBinv, const fmpz_t mod) +{ + const slong lenQ = lenA - lenB + 1; + + _fmpz_mod_poly_div_newton_n_preinv(Q, A, lenA, B, lenB, Binv, lenBinv, mod); + + if (lenB > 1) + { + if (lenQ >= lenB - 1) + _fmpz_mod_poly_mullow(R, Q, lenQ, B, lenB - 1, mod, lenB - 1); + else + _fmpz_mod_poly_mullow(R, B, lenB - 1, Q, lenQ, mod, lenB - 1); + + _fmpz_vec_sub(R, A, R, lenB - 1); + _fmpz_vec_scalar_mod_fmpz(R, R, lenB - 1, mod); + } +} + +void fmpz_mod_poly_divrem_newton_n_preinv(fmpz_mod_poly_t Q, fmpz_mod_poly_t R, + const fmpz_mod_poly_t A, const fmpz_mod_poly_t B, + const fmpz_mod_poly_t Binv) +{ + const slong lenA = A->length, lenB = B->length, lenBinv= Binv->length, + lenQ = lenA - lenB + 1; + fmpz* q, * r; + + if (lenB == 0) + { + flint_printf("Exception (fmpz_mod_poly_divrem_newton_n_preinv)." + " Division by zero.\n"); + abort(); + } + + if (lenA < lenB) + { + fmpz_mod_poly_set(R, A); + fmpz_mod_poly_zero(Q); + return; + } + + if (lenA > 2 * lenB - 2) + { + flint_printf ("Exception (fmpz_mod_poly_divrem_newton_n_preinv).\n"); + } + + if (Q == A || Q == B || Q == Binv) + { + q = _fmpz_vec_init(lenQ); + } + else + { + fmpz_mod_poly_fit_length(Q, lenQ); + q = Q->coeffs; + } + if (R == A || R == B || R == Binv) + { + r = _fmpz_vec_init(lenB - 1); + } + else + { + fmpz_mod_poly_fit_length(R, lenB - 1); + r = R->coeffs; + } + + _fmpz_mod_poly_divrem_newton_n_preinv (q, r, A->coeffs, lenA, + B->coeffs, lenB, Binv->coeffs, + lenBinv, &(B->p)); + + if (Q == A || Q == B || Q == Binv) + { + _fmpz_vec_clear(Q->coeffs, Q->alloc); + Q->coeffs = q; + Q->alloc = lenQ; + Q->length = lenQ; + } + else + { + _fmpz_mod_poly_set_length(Q, lenQ); + } + if (R == A || R == B || R == Binv) + { + _fmpz_vec_clear(R->coeffs, R->alloc); + R->coeffs = r; + R->alloc = lenB - 1; + R->length = lenB - 1; + } + else + { + _fmpz_mod_poly_set_length(R, lenB - 1); + } + + _fmpz_mod_poly_normalise(R); +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/doc/fmpz_mod_poly.txt b/external/flint-2.4.3/fmpz_mod_poly/doc/fmpz_mod_poly.txt new file mode 100644 index 0000000..c0642f2 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/doc/fmpz_mod_poly.txt @@ -0,0 +1,1612 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009, 2008 William Hart + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +******************************************************************************* + + Memory management + +******************************************************************************* + +void fmpz_mod_poly_init(fmpz_mod_poly_t poly, const fmpz_t p) + + Initialises \code{poly} for use over $\mathbf{Z} / p \mathbf{Z}$, + setting its length to zero. + + A corresponding call to \code{fmpz_mod_poly_clear()} must be made after + finishing with the \code{fmpz_mod_poly_t} to free the memory used by + the polynomial. The user is also responsible to clearing the + integer~$p$. + +void fmpz_mod_poly_init2(fmpz_mod_poly_t poly, const fmpz_t p, slong alloc) + + Initialises \code{poly} with space for at least \code{alloc} coefficients + and sets the length to zero. The allocated coefficients are all set to + zero. + +void fmpz_mod_poly_clear(fmpz_mod_poly_t poly) + + Clears the given polynomial, releasing any memory used. It must + be reinitialised in order to be used again. + +void fmpz_mod_poly_realloc(fmpz_mod_poly_t poly, slong alloc) + + Reallocates the given polynomial to have space for \code{alloc} + coefficients. If \code{alloc} is zero the polynomial is cleared + and then reinitialised. If the current length is greater than + \code{alloc} the polynomial is first truncated to length \code{alloc}. + +void fmpz_mod_poly_fit_length(fmpz_mod_poly_t poly, slong len) + + If \code{len} is greater than the number of coefficients currently + allocated, then the polynomial is reallocated to have space for at + least \code{len} coefficients. No data is lost when calling this + function. + + The function efficiently deals with the case where it is called + many times in small increments by at least doubling the number of + allocated coefficients when length is larger than the number of + coefficients currently allocated. + +void _fmpz_mod_poly_normalise(fmpz_mod_poly_t poly) + + Sets the length of \code{poly} so that the top coefficient is non-zero. + If all coefficients are zero, the length is set to zero. This function + is mainly used internally, as all functions guarantee normalisation. + +void _fmpz_mod_poly_set_length(fmpz_mod_poly_t poly, slong len) + + Demotes the coefficients of \code{poly} beyond \code{len} and sets + the length of \code{poly} to \code{len}. + +void fmpz_mod_poly_truncate(fmpz_mod_poly_t poly, slong len) + + If the current length of \code{poly} is greater than \code{len}, it + is truncated to have the given length. Discarded coefficients are + not necessarily set to zero. + +******************************************************************************* + + Randomisation + +******************************************************************************* + +void fmpz_mod_poly_randtest(fmpz_mod_poly_t f, flint_rand_t state, slong len) + + Sets the polynomial~$f$ to a random polynomial of length up~\code{len}. + +void fmpz_mod_poly_randtest_irreducible(fmpz_mod_poly_t f, + flint_rand_t state, slong len) + + Sets the polynomial~$f$ to a random irreducible polynomial of length + up~\code{len}, assuming \code{len} is positive. + +void fmpz_mod_poly_randtest_not_zero(fmpz_mod_poly_t f, + flint_rand_t state, slong len) + + Sets the polynomial~$f$ to a random polynomial of length up~\code{len}, + assuming \code{len} is positive. + +void fmpz_mod_poly_randtest_monic(fmpz_mod_poly_t poly, flint_rand_t state, + slong len) + + Generates a random monic polynomial with length \code{len}. + +void +fmpz_mod_poly_randtest_monic_irreducible(fmpz_mod_poly_t poly, + flint_rand_t state, slong len) + + Generates a random monic irreducible polynomial with length \code{len}. + + +void +fmpz_mod_poly_randtest_trinomial(fmpz_mod_poly_t poly, flint_rand_t state, + slong len) + + Generates a random monic trinomial of length \code{len}. + +int +fmpz_mod_poly_randtest_trinomial_irreducible(fmpz_mod_poly_t poly, + flint_rand_t state, + slong len, slong max_attempts) + + Attempts to set \code{poly} to a monic irreducible trinomial of + length \code{len}. It will generate up to \code{max_attempts} + trinomials in attempt to find an irreducible one. If + \code{max_attempts} is \code{0}, then it will keep generating + trinomials until an irreducible one is found. Returns $1$ if one + is found and $0$ otherwise. + +void +fmpz_mod_poly_randtest_pentomial(fmpz_mod_poly_t poly, flint_rand_t state, + slong len) + + Generates a random monic pentomial of length \code{len}. + +int +fmpz_mod_poly_randtest_pentomial_irreducible(fmpz_mod_poly_t poly, + flint_rand_t state, + slong len, slong max_attempts) + + Attempts to set \code{poly} to a monic irreducible pentomial of + length \code{len}. It will generate up to \code{max_attempts} + pentomials in attempt to find an irreducible one. If + \code{max_attempts} is \code{0}, then it will keep generating + pentomials until an irreducible one is found. Returns $1$ if one + is found and $0$ otherwise. + +void +fmpz_mod_poly_randtest_sparse_irreducible(fmpz_mod_poly_t poly, + flint_rand_t state, slong len) + + Attempts to set \code{poly} to a sparse, monic irreducible polynomial + with length \code{len}. It attempts to find an irreducible + trinomial. If that does not succeed, it attempts to find a + irreducible pentomial. If that fails, then \code{poly} is just + set to a random monic irreducible polynomial. + + +******************************************************************************* + + Attributes + +******************************************************************************* + +fmpz * fmpz_mod_poly_modulus(const fmpz_mod_poly_t poly) + + Returns the modulus of this polynomial. This function is + implemented as a macro. + +slong fmpz_mod_poly_degree(const fmpz_mod_poly_t poly) + + Returns the degree of the polynomial. The degree of the zero + polynomial is defined to be $-1$. + +slong fmpz_mod_poly_length(const fmpz_mod_poly_t poly) + + Returns the length of the polynomial, which is one more than + its degree. + +fmpz * fmpz_mod_poly_lead(const fmpz_mod_poly_t poly) + + Returns a pointer to the first leading coefficient of \code{poly} + if this is non-zero, otherwise returns \code{NULL}. + +******************************************************************************* + + Assignment and basic manipulation + +******************************************************************************* + +void fmpz_mod_poly_set(fmpz_mod_poly_t poly1, const fmpz_mod_poly_t poly2) + + Sets the polynomial \code{poly1} to the value of \code{poly2}. + +void fmpz_mod_poly_swap(fmpz_mod_poly_t poly1, fmpz_mod_poly_t poly2) + + Swaps the two polynomials. This is done efficiently by swapping + pointers rather than individual coefficients. + +void fmpz_mod_poly_zero(fmpz_mod_poly_t poly) + + Sets \code{poly} to the zero polynomial. + +void fmpz_mod_poly_zero_coeffs(fmpz_mod_poly_t poly, slong i, slong j) + + Sets the coefficients of $X^k$ for $k \in [i, j)$ in the polynomial + to zero. + +void fmpz_mod_poly_reverse(fmpz_mod_poly_t res, + const fmpz_mod_poly_t poly, slong n) + + This function considers the polynomial \code{poly} to be of length $n$, + notionally truncating and zero padding if required, and reverses + the result. Since the function normalises its result \code{res} may be + of length less than $n$. + +******************************************************************************* + + Conversion + +******************************************************************************* + +void fmpz_mod_poly_set_ui(fmpz_mod_poly_t f, ulong c) + + Sets the polynomial $f$ to the constant $c$ reduced modulo $p$. + +void fmpz_mod_poly_set_fmpz(fmpz_mod_poly_t f, const fmpz_t c) + + Sets the polynomial $f$ to the constant $c$ reduced modulo $p$. + +void fmpz_mod_poly_set_fmpz_poly(fmpz_mod_poly_t f, const fmpz_poly_t g) + + Sets $f$ to $g$ reduced modulo $p$, where $p$ is the modulus that + is part of the data structure of $f$. + +void fmpz_mod_poly_get_fmpz_poly(fmpz_poly_t f, const fmpz_mod_poly_t g) + + Sets $f$ to $g$. This is done simply by lifting the coefficients + of $g$ taking representatives $[0, p) \subset \mathbf{Z}$. + +******************************************************************************* + + Comparison + +******************************************************************************* + +int fmpz_mod_poly_equal(const fmpz_mod_poly_t poly1, + const fmpz_mod_poly_t poly2) + + Returns non-zero if the two polynomials are equal. + +int fmpz_mod_poly_is_zero(const fmpz_mod_poly_t poly) + + Returns non-zero if the polynomial is zero. + +******************************************************************************* + + Getting and setting coefficients + +******************************************************************************* + +void +fmpz_mod_poly_set_coeff_fmpz(fmpz_mod_poly_t poly, slong n, const fmpz_t x) + + Sets the coefficient of $X^n$ in the polynomial to $x$, + assuming $n \geq 0$. + +void fmpz_mod_poly_set_coeff_ui(fmpz_mod_poly_t poly, slong n, ulong x) + + Sets the coefficient of $X^n$ in the polynomial to $x$, + assuming $n \geq 0$. + +void +fmpz_mod_poly_get_coeff_fmpz(fmpz_t x, const fmpz_mod_poly_t poly, slong n) + + Sets $x$ to the coefficient of $X^n$ in the polynomial, + assumng $n \geq 0$. + +void +fmpz_mod_poly_set_coeff_mpz(fmpz_mod_poly_t poly, slong n, const mpz_t x) + + Sets the coefficient of $X^n$ in the polynomial to $x$, + assuming $n \geq 0$. + +void +fmpz_mod_poly_get_coeff_mpz(mpz_t x, const fmpz_mod_poly_t poly, slong n) + + Sets $x$ to the coefficient of $X^n$ in the polynomial, + assumng $n \geq 0$. + +******************************************************************************* + + Shifting + +******************************************************************************* + +void _fmpz_mod_poly_shift_left(fmpz * res, + const fmpz * poly, slong len, slong n) + + Sets \code{(res, len + n)} to \code{(poly, len)} shifted left by + $n$ coefficients. + + Inserts zero coefficients at the lower end. Assumes that \code{len} + and $n$ are positive, and that \code{res} fits \code{len + n} elements. + Supports aliasing between \code{res} and \code{poly}. + +void fmpz_mod_poly_shift_left(fmpz_mod_poly_t f, + const fmpz_mod_poly_t g, slong n) + + Sets \code{res} to \code{poly} shifted left by $n$ coeffs. Zero + coefficients are inserted. + +void _fmpz_mod_poly_shift_right(fmpz * res, + const fmpz * poly, slong len, slong n) + + Sets \code{(res, len - n)} to \code{(poly, len)} shifted right by + $n$ coefficients. + + Assumes that \code{len} and $n$ are positive, that \code{len > n}, + and that \code{res} fits \code{len - n} elements. Supports aliasing + between \code{res} and \code{poly}, although in this case the top + coefficients of \code{poly} are not set to zero. + +void fmpz_mod_poly_shift_right(fmpz_mod_poly_t f, + const fmpz_mod_poly_t g, slong n) + + Sets \code{res} to \code{poly} shifted right by $n$ coefficients. If $n$ + is equal to or greater than the current length of \code{poly}, \code{res} + is set to the zero polynomial. + +******************************************************************************* + + Addition and subtraction + +******************************************************************************* + +void _fmpz_mod_poly_add(fmpz *res, const fmpz *poly1, slong len1, + const fmpz *poly2, slong len2, + const fmpz_t p) + + Sets \code{res} to the sum of \code{(poly1, len1)} and + \code{(poly2, len2)}. It is assumed that \code{res} has + sufficient space for the longer of the two polynomials. + +void fmpz_mod_poly_add(fmpz_mod_poly_t res, + const fmpz_mod_poly_t poly1, + const fmpz_mod_poly_t poly2) + + Sets \code{res} to the sum of \code{poly1} and \code{poly2}. + +void _fmpz_mod_poly_sub(fmpz *res, const fmpz *poly1, slong len1, + const fmpz *poly2, slong len2, + const fmpz_t p) + + Sets \code{res} to \code{(poly1, len1)} minus \code{(poly2, len2)}. It + is assumed that \code{res} has sufficient space for the longer of the + two polynomials. + +void fmpz_mod_poly_sub(fmpz_mod_poly_t res, + const fmpz_mod_poly_t poly1, + const fmpz_mod_poly_t poly2) + + Sets \code{res} to \code{poly1} minus \code{poly2}. + +void _fmpz_mod_poly_neg(fmpz *res, const fmpz *poly, slong len, const fmpz_t p) + + Sets \code{(res, len)} to the negative of \code{(poly, len)} + modulo $p$. + +void fmpz_mod_poly_neg(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly) + + Sets \code{res} to the negative of \code{poly} modulo $p$. + +******************************************************************************* + + Scalar multiplication + +******************************************************************************* + +void _fmpz_mod_poly_scalar_mul_fmpz(fmpz *res, const fmpz *poly, slong len, + const fmpz_t x, const fmpz_t p) + + Sets \code{(res, len}) to \code{(poly, len)} multiplied by $x$, + reduced modulo $p$. + +void fmpz_mod_poly_scalar_mul_fmpz(fmpz_mod_poly_t res, + const fmpz_mod_poly_t poly, const fmpz_t x) + + Sets \code{res} to \code{poly} multiplied by $x$. + +******************************************************************************* + + Multiplication + +******************************************************************************* + +void _fmpz_mod_poly_mul(fmpz *res, const fmpz *poly1, slong len1, + const fmpz *poly2, slong len2, + const fmpz_t p) + + Sets \code{(res, len1 + len2 - 1)} to the product of \code{(poly1, len1)} + and \code{(poly2, len2)}. Assumes \code{len1 >= len2 > 0}. Allows + zero-padding of the two input polynomials. + +void fmpz_mod_poly_mul(fmpz_mod_poly_t res, + const fmpz_mod_poly_t poly1, + const fmpz_mod_poly_t poly2) + + Sets \code{res} to the product of \code{poly1} and \code{poly2}. + +void _fmpz_mod_poly_mullow(fmpz *res, const fmpz *poly1, slong len1, + const fmpz *poly2, slong len2, + const fmpz_t p, slong n) + + Sets \code{(res, n)} to the lowest $n$ coefficients of the product of + \code{(poly1, len1)} and \code{(poly2, len2)}. + + Assumes \code{len1 >= len2 > 0} and \code{0 < n <= len1 + len2 - 1}. + Allows for zero-padding in the inputs. Does not support aliasing between + the inputs and the output. + +void fmpz_mod_poly_mullow(fmpz_mod_poly_t res, + const fmpz_mod_poly_t poly1, const fmpz_mod_poly_t poly2, slong n) + + Sets \code{res} to the lowest $n$ coefficients of the product of + \code{poly1} and \code{poly2}. + +void _fmpz_mod_poly_sqr(fmpz *res, const fmpz *poly, slong len, const fmpz_t p) + + Sets \code{res} to the square of \code{poly}. + +void fmpz_mod_poly_sqr(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly) + + Computes \code{res} as the square of \code{poly}. + +void _fmpz_mod_poly_mulmod(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2, const fmpz * f, + slong lenf, const fmpz_t p) + + Sets \code{res, len1 + len2 - 1} to the remainder of the product of + \code{poly1} and \code{poly2} upon polynomial division by \code{f}. + + It is required that \code{len1 + len2 - lenf > 0}, which is equivalent + to requiring that the result will actually be reduced. Otherwise, simply + use \code{_fmpz_mod_poly_mul} instead. + + Aliasing of \code{f} and \code{res} is not permitted. + +void fmpz_mod_poly_mulmod(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly1, + const fmpz_mod_poly_t poly2, const fmpz_mod_poly_t f) + + Sets \code{res} to the remainder of the product of \code{poly1} and + \code{poly2} upon polynomial division by \code{f}. + +void _fmpz_mod_poly_mulmod_preinv(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2, const fmpz * f, slong lenf, + const fmpz* finv, slong lenfinv, const fmpz_t p) + + Sets \code{res, len1 + len2 - 1} to the remainder of the product of + \code{poly1} and \code{poly2} upon polynomial division by \code{f}. + + It is required that \code{finv} is the inverse of the reverse of \code{f} + mod \code{x^lenf}. It is required that \code{len1 + len2 - lenf > 0}, + which is equivalent to requiring that the result will actually be reduced. + It is required that \code{len1 < lenf} and \code{len2 < lenf}. + Otherwise, simply use \code{_fmpz_mod_poly_mul} instead. + + Aliasing of \code{f} or \code{finv} and \code{res} is not permitted. + +void fmpz_mod_poly_mulmod_preinv(fmpz_mod_poly_t res, + const fmpz_mod_poly_t poly1, const fmpz_mod_poly_t poly2, + const fmpz_mod_poly_t f, const fmpz_mod_poly_t finv) + + Sets \code{res} to the remainder of the product of \code{poly1} and + \code{poly2} upon polynomial division by \code{f}. \code{finv} is the + inverse of the reverse of \code{f}. It is required that \code{poly1} and + \code{poly2} are reduced modulo \code{f}. + +******************************************************************************* + + Powering + +******************************************************************************* + +void _fmpz_mod_poly_pow(fmpz *rop, const fmpz *op, slong len, ulong e, + const fmpz_t p) + + Sets \code{res = poly^e}, assuming that $e > 1$ and \code{elen > 0}, + and that \code{res} has space for \code{e*(len - 1) + 1} coefficients. + Does not support aliasing. + +void fmpz_mod_poly_pow(fmpz_mod_poly_t rop, const fmpz_mod_poly_t op, ulong e) + + Computes \code{res = poly^e}. If $e$ is zero, returns one, + so that in particular \code{0^0 = 1}. + +void _fmpz_mod_poly_pow_trunc(fmpz * res, const fmpz * poly, + ulong e, slong trunc, const fmpz_t p) + + Sets \code{res} to the low \code{trunc} coefficients of \code{poly} + (assumed to be zero padded if necessary to length \code{trunc}) to + the power \code{e}. This is equivalent to doing a powering followed + by a truncation. We require that \code{res} has enough space for + \code{trunc} coefficients, that \code{trunc > 0} and that + \code{e > 1}. Aliasing is not permitted. + +void fmpz_mod_poly_pow_trunc(fmpz_mod_poly_t res, + const fmpz_mod_poly_t poly, ulong e, slong trunc) + + Sets \code{res} to the low \code{trunc} coefficients of \code{poly} + to the power \code{e}. This is equivalent to doing a powering + followed by a truncation. + +void _fmpz_mod_poly_pow_trunc_binexp(fmpz * res, const fmpz * poly, + ulong e, slong trunc, const fmpz_t p) + + Sets \code{res} to the low \code{trunc} coefficients of \code{poly} + (assumed to be zero padded if necessary to length \code{trunc}) to + the power \code{e}. This is equivalent to doing a powering followed + by a truncation. We require that \code{res} has enough space for + \code{trunc} coefficients, that \code{trunc > 0} and that + \code{e > 1}. Aliasing is not permitted. Uses the binary + exponentiation method. + +void fmpz_mod_poly_pow_trunc_binexp(fmpz_mod_poly_t res, + const fmpz_mod_poly_t poly, ulong e, slong trunc) + + Sets \code{res} to the low \code{trunc} coefficients of \code{poly} + to the power \code{e}. This is equivalent to doing a powering + followed by a truncation. Uses the binary exponentiation method. + +void _fmpz_mod_poly_powmod_ui_binexp(fmpz * res, const fmpz * poly, + ulong e, const fmpz * f, + slong lenf, const fmpz_t p) + + Sets \code{res} to \code{poly} raised to the power \code{e} + modulo \code{f}, using binary exponentiation. We require \code{e > 0}. + + We require \code{lenf > 1}. It is assumed that \code{poly} is already + reduced modulo \code{f} and zero-padded as necessary to have length + exactly \code{lenf - 1}. The output \code{res} must have room for + \code{lenf - 1} coefficients. + +void fmpz_mod_poly_powmod_ui_binexp(fmpz_mod_poly_t res, + const fmpz_mod_poly_t poly, ulong e, + const fmpz_mod_poly_t f) + + Sets \code{res} to \code{poly} raised to the power \code{e} + modulo \code{f}, using binary exponentiation. We require \code{e >= 0}. + +void +_fmpz_mod_poly_powmod_ui_binexp_preinv(fmpz * res, const fmpz * poly, + ulong e, const fmpz * f, slong lenf, + const fmpz * finv, slong lenfinv, const fmpz_t p) + + Sets \code{res} to \code{poly} raised to the power \code{e} + modulo \code{f}, using binary exponentiation. We require \code{e > 0}. + We require \code{finv} to be the inverse of the reverse of \code{f}. + + We require \code{lenf > 1}. It is assumed that \code{poly} is already + reduced modulo \code{f} and zero-padded as necessary to have length + exactly \code{lenf - 1}. The output \code{res} must have room for + \code{lenf - 1} coefficients. + +void +fmpz_mod_poly_powmod_ui_binexp_preinv(fmpz_mod_poly_t res, + const fmpz_mod_poly_t poly, ulong e, + const fmpz_mod_poly_t f, const fmpz_mod_poly_t finv) + + Sets \code{res} to \code{poly} raised to the power \code{e} + modulo \code{f}, using binary exponentiation. We require \code{e >= 0}. + We require \code{finv} to be the inverse of the reverse of \code{f}. + +void _fmpz_mod_poly_powmod_fmpz_binexp(fmpz * res, const fmpz * poly, + const fmpz_t e, const fmpz * f, + slong lenf, const fmpz_t p) + + Sets \code{res} to \code{poly} raised to the power \code{e} + modulo \code{f}, using binary exponentiation. We require \code{e > 0}. + + We require \code{lenf > 1}. It is assumed that \code{poly} is already + reduced modulo \code{f} and zero-padded as necessary to have length + exactly \code{lenf - 1}. The output \code{res} must have room for + \code{lenf - 1} coefficients. + +void fmpz_mod_poly_powmod_fmpz_binexp(fmpz_mod_poly_t res, + const fmpz_mod_poly_t poly, const fmpz_t e, + const fmpz_mod_poly_t f) + + Sets \code{res} to \code{poly} raised to the power \code{e} + modulo \code{f}, using binary exponentiation. We require \code{e >= 0}. + +void _fmpz_mod_poly_powmod_fmpz_binexp_preinv(fmpz * res, const fmpz * poly, + const fmpz_t e, const fmpz * f, slong lenf, + const fmpz* finv, slong lenfinv, + const fmpz_t p) + + Sets \code{res} to \code{poly} raised to the power \code{e} + modulo \code{f}, using binary exponentiation. We require \code{e > 0}. + We require \code{finv} to be the inverse of the reverse of \code{f}. + + We require \code{lenf > 1}. It is assumed that \code{poly} is already + reduced modulo \code{f} and zero-padded as necessary to have length + exactly \code{lenf - 1}. The output \code{res} must have room for + \code{lenf - 1} coefficients. + +void fmpz_mod_poly_powmod_fmpz_binexp_preinv(fmpz_mod_poly_t res, + const fmpz_mod_poly_t poly, const fmpz_t e, + const fmpz_mod_poly_t f, const fmpz_mod_poly_t finv) + + Sets \code{res} to \code{poly} raised to the power \code{e} + modulo \code{f}, using binary exponentiation. We require \code{e >= 0}. + We require \code{finv} to be the inverse of the reverse of \code{f}. + +void +_fmpz_mod_poly_powmod_x_fmpz_preinv(fmpz * res, const fmpz_t e, const fmpz * f, + slong lenf, const fmpz* finv, slong lenfinv, + const fmpz_t p) + + Sets \code{res} to \code{x} raised to the power \code{e} modulo \code{f}, + using sliding window exponentiation. We require \code{e > 0}. + We require \code{finv} to be the inverse of the reverse of \code{f}. + + We require \code{lenf > 2}. The output \code{res} must have room for + \code{lenf - 1} coefficients. + +void +fmpz_mod_poly_powmod_x_fmpz_preinv(fmpz_mod_poly_t res, const fmpz_t e, + const fmpz_mod_poly_t f, const fmpz_mod_poly_t finv) + + Sets \code{res} to \code{x} raised to the power \code{e} + modulo \code{f}, using sliding window exponentiation. We require + \code{e >= 0}. We require \code{finv} to be the inverse of the reverse of + \code{f}. + +******************************************************************************* + + Division + +******************************************************************************* + +void _fmpz_mod_poly_divrem_basecase(fmpz * Q, fmpz * R, + const fmpz * A, slong lenA, const fmpz * B, slong lenB, + const fmpz_t invB, const fmpz_t p) + + Computes \code{(Q, lenA - lenB + 1)}, \code{(R, lenA)} such that + $A = B Q + R$ with $0 \leq \len(R) < \len(B)$. + + Assumes that the leading coefficient of $B$ is invertible + modulo $p$, and that \code{invB} is the inverse. + + Assumes that $\len(A), \len(B) > 0$. Allows zero-padding in + \code{(A, lenA)}. $R$ and $A$ may be aliased, but apart from this no + aliasing of input and output operands is allowed. + +void fmpz_mod_poly_divrem_basecase(fmpz_mod_poly_t Q, fmpz_mod_poly_t R, + const fmpz_mod_poly_t A, const fmpz_mod_poly_t B) + + Computes $Q$, $R$ such that $A = B Q + R$ with + $0 \leq \len(R) < \len(B)$. + + Assumes that the leading coefficient of $B$ is invertible + modulo $p$. + +void _fmpz_mod_poly_divrem_newton_n_preinv (fmpz* Q, fmpz* R, const fmpz* A, + slong lenA, const fmpz* B, slong lenB, + const fmpz* Binv, slong lenBinv, const fmpz_t mod) + + Computes $Q$ and $R$ such that $A = BQ + R$ with $\len(R)$ less than + \code{lenB}, where $A$ is of length \code{lenA} and $B$ is of length + \code{lenB}. We require that $Q$ have space for \code{lenA - lenB + 1} + coefficients. Furthermore, we assume that $Binv$ is the inverse of the + reverse of $B$ mod $x^{\len(B)}$. The algorithm used is to call + \code{div_newton_n_preinv()} and then multiply out and compute + the remainder. + +void fmpz_mod_poly_divrem_newton_n_preinv(fmpz_mod_poly_t Q, fmpz_mod_poly_t R, + const fmpz_mod_poly_t A, const fmpz_mod_poly_t B, + const fmpz_mod_poly_t Binv) + + Computes $Q$ and $R$ such that $A = BQ + R$ with $\len(R) < \len(B)$. + We assume $Binv$ is the inverse of the reverse of $B$ mod $x^{\len(B)}$. + + It is required that the length of $A$ is less than or equal to + 2*the length of $B$ - 2. + + The algorithm used is to call \code{div_newton_n()} and then multiply out + and compute the remainder. + +void _fmpz_mod_poly_div_basecase(fmpz * Q, fmpz * R, + const fmpz * A, slong lenA, const fmpz * B, slong lenB, + const fmpz_t invB, const fmpz_t p) + + Notationally, computes $Q$, $R$ such that $A = B Q + R$ with + $0 \leq \len(R) < \len(B)$ but only sets \code{(Q, lenA - lenB + 1)}. + + Requires temporary space \code{(R, lenA)}. Allows aliasing + only between $A$ and $R$. Allows zero-padding in $A$ but + not in $B$. Assumes that the leading coefficient of $B$ + is a unit modulo $p$. + +void fmpz_mod_poly_div_basecase(fmpz_mod_poly_t Q, + const fmpz_mod_poly_t A, const fmpz_mod_poly_t B) + + Notationally, computes $Q$, $R$ such that $A = B Q + R$ with + $0 \leq \len(R) < \len(B)$ assuming that the leading term + of $B$ is a unit. + +void _fmpz_mod_poly_div_newton_n_preinv (fmpz* Q, const fmpz* A, slong lenA, + const fmpz* B, slong lenB, const fmpz* Binv, + slong lenBinv, const fmpz_t mod) + + Notionally computes polynomials $Q$ and $R$ such that $A = BQ + R$ with + $\len(R)$ less than \code{lenB}, where \code{A} is of length \code{lenA} + and \code{B} is of length \code{lenB}, but return only $Q$. + + We require that $Q$ have space for \code{lenA - lenB + 1} coefficients + and assume that the leading coefficient of $B$ is a unit. Furthermore, we + assume that $Binv$ is the inverse of the reverse of $B$ mod $x^{\len(B)}$. + + The algorithm used is to reverse the polynomials and divide the + resulting power series, then reverse the result. + +void fmpz_mod_poly_div_newton_n_preinv(fmpz_mod_poly_t Q, + const fmpz_mod_poly_t A, const fmpz_mod_poly_t B, + const fmpz_mod_poly_t Binv) + + Notionally computes $Q$ and $R$ such that $A = BQ + R$ with + $\len(R) < \len(B)$, but returns only $Q$. + + We assume that the leading coefficient of $B$ is a unit and that $Binv$ is + the inverse of the reverse of $B$ mod $x^{\len(B)}$. + + It is required that the length of $A$ is less than or equal to + 2*the length of $B$ - 2. + + The algorithm used is to reverse the polynomials and divide the + resulting power series, then reverse the result. + +ulong fmpz_mod_poly_remove(fmpz_mod_poly_t f, const fmpz_mod_poly_t g) + + Removes the highest possible power of \code{g} from \code{f} and + returns the exponent. + +void _fmpz_mod_poly_rem_basecase(fmpz * R, + const fmpz * A, slong lenA, const fmpz * B, slong lenB, + const fmpz_t invB, const fmpz_t p) + + Notationally, computes $Q$, $R$ such that $A = B Q + R$ with + $0 \leq \len(R) < \len(B)$ but only sets \code{(R, lenA)}. + + Allows aliasing only between $A$ and $R$. Allows zero-padding + in $A$ but not in $B$. Assumes that the leading coefficient + of $B$ is a unit modulo $p$. + +void fmpz_mod_poly_rem_basecase(fmpz_mod_poly_t R, + const fmpz_mod_poly_t A, const fmpz_mod_poly_t B) + + Notationally, computes $Q$, $R$ such that $A = B Q + R$ with + $0 \leq \len(R) < \len(B)$ assuming that the leading term + of $B$ is a unit. + +void _fmpz_mod_poly_divrem_divconquer_recursive(fmpz * Q, fmpz * BQ, fmpz * W, + const fmpz * A, const fmpz * B, slong lenB, + const fmpz_t invB, const fmpz_t p) + + Computes \code{(Q, lenB)}, \code{(BQ, 2 lenB - 1)} such that + $BQ = B \times Q$ and $A = B Q + R$ where $0 \leq \len(R) < \len(B)$. + + Assumes that the leading coefficient of $B$ is invertible + modulo $p$, and that \code{invB} is the inverse. + + Assumes $\len(B) > 0$. Allows zero-padding in \code{(A, lenA)}. Requires + a temporary array \code{(W, 2 lenB - 1)}. No aliasing of input and output + operands is allowed. + + This function does not read the bottom $\len(B) - 1$ coefficients from + $A$, which means that they might not even need to exist in allocated + memory. + +void _fmpz_mod_poly_divrem_divconquer(fmpz * Q, fmpz * R, + const fmpz * A, slong lenA, const fmpz * B, slong lenB, + const fmpz_t invB, const fmpz_t p) + + Computes \code{(Q, lenA - lenB + 1)}, \code{(R, lenA)} such that + $A = B Q + R$ and $0 \leq \len(R) < \len(B)$. + + Assumes that the leading coefficient of $B$ is invertible + modulo $p$, and that \code{invB} is the inverse. + + Assumes $\len(A) \geq \len(B) > 0$. Allows zero-padding in + \code{(A, lenA)}. No aliasing of input and output operands is + allowed. + +void fmpz_mod_poly_divrem_divconquer(fmpz_mod_poly_t Q, fmpz_mod_poly_t R, + const fmpz_mod_poly_t A, const fmpz_mod_poly_t B) + + Computes $Q$, $R$ such that $A = B Q + R$ and $0 \leq \len(R) < \len(B)$. + + Assumes that $B$ is non-zero and that the leading coefficient + of $B$ is invertible modulo $p$. + +void _fmpz_mod_poly_divrem(fmpz * Q, fmpz * R, const fmpz * A, slong lenA, + const fmpz * B, slong lenB, const fmpz_t invB, const fmpz_t p) + + Computes \code{(Q, lenA - lenB + 1)}, \code{(R, lenA)} such that + $A = B Q + R$ and $0 \leq \len(R) < \len(B)$. + + Assumes that $B$ is non-zero, that the leading coefficient + of $B$ is invertible modulo $p$ and that \code{invB} is + the inverse. + + Assumes $\len(A) \geq \len(B) > 0$. Allows zero-padding in + \code{(A, lenA)}. No aliasing of input and output operands is + allowed. + +void fmpz_mod_poly_divrem(fmpz_mod_poly_t Q, fmpz_mod_poly_t R, + const fmpz_mod_poly_t A, const fmpz_mod_poly_t B) + + Computes $Q$, $R$ such that $A = B Q + R$ and + $0 \leq \len(R) < \len(B)$. + + Assumes that $B$ is non-zero and that the leading coefficient + of $B$ is invertible modulo $p$. + +void fmpz_mod_poly_divrem_f(fmpz_t f, fmpz_mod_poly_t Q, fmpz_mod_poly_t R, + const fmpz_mod_poly_t A, const fmpz_mod_poly_t B) + + Either finds a non-trivial factor~$f$ of the modulus~$p$, or computes + $Q$, $R$ such that $A = B Q + R$ and $0 \leq \len(R) < \len(B)$. + + If the leading coefficient of $B$ is invertible in $\mathbf{Z}/(p)$, + the division with remainder operation is carried out, $Q$ and $R$ are + computed correctly, and $f$ is set to $1$. Otherwise, $f$ is set to + a non-trivial factor of $p$ and $Q$ and $R$ are not touched. + + Assumes that $B$ is non-zero. + +void _fmpz_mod_poly_rem(fmpz *R, + const fmpz *A, slong lenA, const fmpz *B, slong lenB, + const fmpz_t invB, const fmpz_t p) + + Notationally, computes \code{(Q, lenA - lenB + 1)}, \code{(R, lenA)} + such that $A = B Q + R$ and $0 \leq \len(R) < \len(B)$, returning + only the remainder part. + + Assumes that $B$ is non-zero, that the leading coefficient + of $B$ is invertible modulo $p$ and that \code{invB} is + the inverse. + + Assumes $\len(A) \geq \len(B) > 0$. Allows zero-padding in + \code{(A, lenA)}. No aliasing of input and output operands is + allowed. + +void fmpz_mod_poly_rem(fmpz_mod_poly_t R, + const fmpz_mod_poly_t A, const fmpz_mod_poly_t B) + + Notationally, computes $Q$, $R$ such that $A = B Q + R$ + and $0 \leq \len(R) < \len(B)$, returning only the remainder + part. + + Assumes that $B$ is non-zero and that the leading coefficient + of $B$ is invertible modulo $p$. + +******************************************************************************* + + Power series inversion + +******************************************************************************* + +void _fmpz_mod_poly_inv_series_newton(fmpz * Qinv, const fmpz * Q, slong n, + const fmpz_t cinv, const fmpz_t p) + + Sets \code{(Qinv, n)} to the inverse of \code{(Q, n)} modulo $x^n$, + where $n \geq 1$, assuming that the bottom coefficient of $Q$ is + invertible modulo $p$ and that its inverse is \code{cinv}. + +void fmpz_mod_poly_inv_series_newton(fmpz_mod_poly_t Qinv, + const fmpz_mod_poly_t Q, slong n) + + Sets \code{Qinv} to the inverse of \code{Q} modulo $x^n$, + where $n \geq 1$, assuming that the bottom coefficient of + $Q$ is a unit. + +******************************************************************************* + + Greatest common divisor + +******************************************************************************* + +void fmpz_mod_poly_make_monic(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly) + + If \code{poly} is non-zero, sets \code{res} to \code{poly} divided + by its leading coefficient. This assumes that the leading coefficient + of \code{poly} is invertible modulo $p$. + + Otherwise, if \code{poly} is zero, sets \code{res} to zero. + +slong _fmpz_mod_poly_gcd_euclidean(fmpz *G, const fmpz *A, slong lenA, + const fmpz *B, slong lenB, + const fmpz_t invB, const fmpz_t p) + + Sets $G$ to the greatest common divisor of $(A, \len(A))$ + and $(B, \len(B))$ and returns its length. + + Assumes that $\len(A) \geq \len(B) > 0$ and that the vector $G$ has + space for sufficiently many coefficients. + + Assumes that \code{invB} is the inverse of the leading coefficients + of $B$ modulo the prime number $p$. + +void fmpz_mod_poly_gcd_euclidean(fmpz_mod_poly_t G, + const fmpz_mod_poly_t A, + const fmpz_mod_poly_t B) + + Sets $G$ to the greatest common divisor of $A$ and $B$. + + The algorithm used to compute $G$ is the classical Euclidean + algorithm. + + In general, the greatest common divisor is defined in the polynomial + ring $(\mathbf{Z}/(p \mathbf{Z}))[X]$ if and only if $p$ is a prime + number. Thus, this function assumes that $p$ is prime. + +slong _fmpz_mod_poly_gcd(fmpz *G, const fmpz *A, slong lenA, + const fmpz *B, slong lenB, + const fmpz_t invB, const fmpz_t p) + + Sets $G$ to the greatest common divisor of $(A, \len(A))$ + and $(B, \len(B))$ and returns its length. + + Assumes that $\len(A) \geq \len(B) > 0$ and that the vector $G$ has + space for sufficiently many coefficients. + + Assumes that \code{invB} is the inverse of the leading coefficients + of $B$ modulo the prime number $p$. + +void fmpz_mod_poly_gcd(fmpz_mod_poly_t G, + const fmpz_mod_poly_t A, const fmpz_mod_poly_t B) + + Sets $G$ to the greatest common divisor of $A$ and $B$. + + In general, the greatest common divisor is defined in the polynomial + ring $(\mathbf{Z}/(p \mathbf{Z}))[X]$ if and only if $p$ is a prime + number. Thus, this function assumes that $p$ is prime. + +slong _fmpz_mod_poly_gcd_euclidean_f(fmpz_t f, fmpz *G, + const fmpz *A, slong lenA, const fmpz *B, slong lenB, const fmpz_t p) + + Either sets $f = 1$ and $G$ to the greatest common divisor + of $(A, \len(A))$ and $(B, \len(B))$ and returns its length, + or sets $f \in (1,p)$ to a non-trivial factor of $p$ and + leaves the contents of the vector $(G, lenB)$ undefined. + + Assumes that $\len(A) \geq \len(B) > 0$ and that the vector $G$ has + space for sufficiently many coefficients. + + Does not support aliasing of any of the input arguments + with any of the output argument. + +void fmpz_mod_poly_gcd_euclidean_f(fmpz_t f, fmpz_mod_poly_t G, + const fmpz_mod_poly_t A, const fmpz_mod_poly_t B) + + Either sets $f = 1$ and $G$ to the greatest common divisor + of $A$ and $B$, or $ \in (1,p)$ to a non-trivial factor of $p$. + + In general, the greatest common divisor is defined in the polynomial + ring $(\mathbf{Z}/(p \mathbf{Z}))[X]$ if and only if $p$ is a prime + number. + +slong _fmpz_mod_poly_gcd_f(fmpz_t f, fmpz *G, const fmpz *A, slong lenA, + const fmpz *B, slong lenB, const fmpz_t p) + + Either sets $f = 1$ and $G$ to the greatest common divisor + of $(A, \len(A))$ and $(B, \len(B))$ and returns its length, + or sets $f \in (1,p)$ to a non-trivial factor of $p$ and + leaves the contents of the vector $(G, lenB)$ undefined. + + Assumes that $\len(A) \geq \len(B) > 0$ and that the vector $G$ has + space for sufficiently many coefficients. + + Does not support aliasing of any of the input arguments + with any of the output argument. + +void fmpz_mod_poly_gcd_f(fmpz_t f, fmpz_mod_poly_t G, + const fmpz_mod_poly_t A, const fmpz_mod_poly_t B) + + Either sets $f = 1$ and $G$ to the greatest common divisor + of $A$ and $B$, or $ \in (1,p)$ to a non-trivial factor of $p$. + + In general, the greatest common divisor is defined in the polynomial + ring $(\mathbf{Z}/(p \mathbf{Z}))[X]$ if and only if $p$ is a prime + number. + +slong _fmpz_mod_poly_xgcd_euclidean(fmpz *G, fmpz *S, fmpz *T, + const fmpz *A, slong lenA, + const fmpz *B, slong lenB, + const fmpz_t invB, const fmpz_t p) + + Computes the GCD of $A$ and $B$ together with cofactors $S$ and $T$ + such that $S A + T B = G$. Returns the length of $G$. + + Assumes that $\len(A) \geq \len(B) \geq 1$ and + $(\len(A),\len(B)) \neq (1,1)$. + + No attempt is made to make the GCD monic. + + Requires that $G$ have space for $\len(B)$ coefficients. Writes + $\len(B)-1$ and $\len(A)-1$ coefficients to $S$ and $T$, respectively. + Note that, in fact, $\len(S) \leq \max(\len(B) - \len(G), 1)$ and + $\len(T) \leq \max(\len(A) - \len(G), 1)$. + + No aliasing of input and output operands is permitted. + +void fmpz_mod_poly_xgcd_euclidean(fmpz_mod_poly_t G, + fmpz_mod_poly_t S, fmpz_mod_poly_t T, + const fmpz_mod_poly_t A, const fmpz_mod_poly_t B) + + Computes the GCD of $A$ and $B$. The GCD of zero polynomials is + defined to be zero, whereas the GCD of the zero polynomial and some other + polynomial $P$ is defined to be $P$. Except in the case where + the GCD is zero, the GCD $G$ is made monic. + + Polynomials \code{S} and \code{T} are computed such that + \code{S*A + T*B = G}. The length of \code{S} will be at most + \code{lenB} and the length of \code{T} will be at most \code{lenA}. + +slong _fmpz_mod_poly_xgcd(fmpz *G, fmpz *S, fmpz *T, + const fmpz *A, slong lenA, + const fmpz *B, slong lenB, + const fmpz_t invB, const fmpz_t p) + + Computes the GCD of $A$ and $B$ together with cofactors $S$ and $T$ + such that $S A + T B = G$. Returns the length of $G$. + + Assumes that $\len(A) \geq \len(B) \geq 1$ and + $(\len(A),\len(B)) \neq (1,1)$. + + No attempt is made to make the GCD monic. + + Requires that $G$ have space for $\len(B)$ coefficients. Writes + $\len(B)-1$ and $\len(A)-1$ coefficients to $S$ and $T$, respectively. + Note that, in fact, $\len(S) \leq \max(\len(B) - \len(G), 1)$ and + $\len(T) \leq \max(\len(A) - \len(G), 1)$. + + No aliasing of input and output operands is permitted. + +void fmpz_mod_poly_xgcd(fmpz_mod_poly_t G, + fmpz_mod_poly_t S, fmpz_mod_poly_t T, + const fmpz_mod_poly_t A, const fmpz_mod_poly_t B) + + Computes the GCD of $A$ and $B$. The GCD of zero polynomials is + defined to be zero, whereas the GCD of the zero polynomial and some other + polynomial $P$ is defined to be $P$. Except in the case where + the GCD is zero, the GCD $G$ is made monic. + + Polynomials \code{S} and \code{T} are computed such that + \code{S*A + T*B = G}. The length of \code{S} will be at most + \code{lenB} and the length of \code{T} will be at most \code{lenA}. + +slong _fmpz_mod_poly_gcdinv(fmpz *G, fmpz *S, + const fmpz *A, slong lenA, const fmpz *B, slong lenB, + const fmpz_t p) + + Computes \code{(G, lenA)}, \code{(S, lenB-1)} such that + $G \cong S A \pmod{B}$, returning the actual length of $G$. + + Assumes that $0 < \len(A) < \len(B)$. + +void fmpz_mod_poly_gcdinv(fmpz_mod_poly_t G, fmpz_mod_poly_t S, + const fmpz_mod_poly_t A, const fmpz_mod_poly_t B) + + Computes polynomials $G$ and $S$, both reduced modulo~$B$, + such that $G \cong S A \pmod{B}$, where $B$ is assumed to + have $\len(B) \geq 2$. + + In the case that $A = 0 \pmod{B}$, returns $G = S = 0$. + +int _fmpz_mod_poly_invmod(fmpz *A, + const fmpz *B, slong lenB, + const fmpz *P, slong lenP, const fmpz_t p) + + Attempts to set \code{(A, lenP-1)} to the inverse of \code{(B, lenB)} + modulo the polynomial \code{(P, lenP)}. Returns $1$ if \code{(B, lenB)} + is invertible and $0$ otherwise. + + Assumes that $0 < \len(B) < \len(P)$, and hence also $\len(P) \geq 2$, + but supports zero-padding in \code{(B, lenB)}. + + Does not support aliasing. + + Assumes that $p$ is a prime number. + +int fmpz_mod_poly_invmod(fmpz_mod_poly_t A, + const fmpz_mod_poly_t B, const fmpz_mod_poly_t P) + + Attempts to set $A$ to the inverse of $B$ modulo $P$ in the polynomial + ring $(\mathbf{Z}/p\mathbf{Z})[X]$, where we assume that $p$ is a prime + number. + + If $\deg(P) < 2$, raises an exception. + + If the greatest common divisor of $B$ and $P$ is~$1$, returns~$1$ and + sets $A$ to the inverse of $B$. Otherwise, returns~$0$ and the value + of $A$ on exit is undefined. + +******************************************************************************* + + Derivative + +******************************************************************************* + +void _fmpz_mod_poly_derivative(fmpz *res, const fmpz *poly, slong len, + const fmpz_t p) + + Sets \code{(res, len - 1)} to the derivative of \code{(poly, len)}. + Also handles the cases where \code{len} is $0$ or $1$ correctly. + Supports aliasing of \code{res} and \code{poly}. + +void fmpz_mod_poly_derivative(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly) + + Sets \code{res} to the derivative of \code{poly}. + +******************************************************************************* + + Evaluation + +******************************************************************************* + +void _fmpz_mod_poly_evaluate_fmpz(fmpz_t res, const fmpz *poly, slong len, + const fmpz_t a, const fmpz_t p) + + Evaluates the polynomial \code{(poly, len)} at the integer $a$ and sets + \code{res} to the result. Aliasing between \code{res} and $a$ or any + of the coefficients of \code{poly} is not supported. + +void fmpz_mod_poly_evaluate_fmpz(fmpz_t res, + const fmpz_mod_poly_t poly, const fmpz_t a) + + Evaluates the polynomial \code{poly} at the integer $a$ and sets + \code{res} to the result. + + As expected, aliasing between \code{res} and $a$ is supported. However, + \code{res} may not be aliased with a coefficient of \code{poly}. + +******************************************************************************* + + Multipoint evaluation + +******************************************************************************* + +void _fmpz_mod_poly_evaluate_fmpz_vec_iter(fmpz * ys, const fmpz * coeffs, + slong len, const fmpz * xs, slong n, const fmpz_t mod) + + Evaluates (\code{coeffs}, \code{len}) at the \code{n} values + given in the vector \code{xs}, writing the output values + to \code{ys}. The values in \code{xs} should be reduced + modulo the modulus. + + Uses Horner's method iteratively. + +void fmpz_mod_poly_evaluate_fmpz_vec_iter(fmpz * ys, + const fmpz_mod_poly_t poly, const fmpz * xs, slong n) + + Evaluates \code{poly} at the \code{n} values given in the vector + \code{xs}, writing the output values to \code{ys}. The values in + \code{xs} should be reduced modulo the modulus. + + Uses Horner's method iteratively. + +void _fmpz_mod_poly_evaluate_fmpz_vec_fast_precomp(fmpz * vs, + const fmpz * poly, slong plen, fmpz_poly_struct * const * tree, + slong len, const fmpz_t mod) + Evaluates (\code{poly}, \code{plen}) at the \code{len} values given + by the precomputed subproduct tree \code{tree}. + +void _fmpz_mod_poly_evaluate_fmpz_vec_fast(fmpz * ys, + const fmpz * poly, slong plen, const fmpz * xs, slong n, const fmpz_t mod) + + Evaluates (\code{coeffs}, \code{len}) at the \code{n} values + given in the vector \code{xs}, writing the output values + to \code{ys}. The values in \code{xs} should be reduced + modulo the modulus. + + Uses fast multipoint evaluation, building a temporary subproduct tree. + +void fmpz_mod_poly_evaluate_fmpz_vec_fast(fmpz * ys, + const fmpz_mod_poly_t poly, const fmpz * xs, slong n) + + Evaluates \code{poly} at the \code{n} values given in the vector + \code{xs}, writing the output values to \code{ys}. The values in + \code{xs} should be reduced modulo the modulus. + + Uses fast multipoint evaluation, building a temporary subproduct tree. + +void _fmpz_mod_poly_evaluate_fmpz_vec(fmpz * ys, const fmpz * coeffs, + slong len, const fmpz * xs, slong n, const fmpz_t mod) + + Evaluates (\code{coeffs}, \code{len}) at the \code{n} values + given in the vector \code{xs}, writing the output values + to \code{ys}. The values in \code{xs} should be reduced + modulo the modulus. + +void fmpz_mod_poly_evaluate_fmpz_vec(fmpz * ys, + const fmpz_mod_poly_t poly, const fmpz * xs, slong n) + + Evaluates \code{poly} at the \code{n} values given in the vector + \code{xs}, writing the output values to \code{ys}. The values in + \code{xs} should be reduced modulo the modulus. + +******************************************************************************* + + Composition + +******************************************************************************* + +void _fmpz_mod_poly_compose_horner(fmpz *res, const fmpz *poly1, slong len1, + const fmpz *poly2, slong len2, + const fmpz_t p) + + Sets \code{res} to the composition of \code{(poly1, len1)} and + \code{(poly2, len2)} using Horner's algorithm. + + Assumes that \code{res} has space for \code{(len1-1)*(len2-1) + 1} + coefficients, although in $\mathbf{Z}_p[X]$ this might not actually + be the length of the resulting polynomial when $p$ is not a prime. + + Assumes that \code{poly1} and \code{poly2} are non-zero polynomials. + Does not support aliasing between any of the inputs and the output. + +void fmpz_mod_poly_compose_horner(fmpz_mod_poly_t res, + const fmpz_mod_poly_t poly1, + const fmpz_mod_poly_t poly2) + + Sets \code{res} to the composition of \code{poly1} and \code{poly2} + using Horner's algorithm. + + To be precise about the order of composition, denoting \code{res}, + \code{poly1}, and \code{poly2} by $f$, $g$, and $h$, respectively, + sets $f(t) = g(h(t))$. + +void _fmpz_mod_poly_compose_divconquer(fmpz *res, + const fmpz *poly1, slong len1, const fmpz *poly2, slong len2, const fmpz_t p) + + Sets \code{res} to the composition of \code{(poly1, len1)} and + \code{(poly2, len2)} using a divide and conquer algorithm which + takes out factors of \code{poly2} raised to $2^i$ where possible. + + Assumes that \code{res} has space for \code{(len1-1)*(len2-1) + 1} + coefficients, although in $\mathbf{Z}_p[X]$ this might not actually + be the length of the resulting polynomial when $p$ is not a prime. + + Assumes that \code{poly1} and \code{poly2} are non-zero polynomials. + Does not support aliasing between any of the inputs and the output. + +void fmpz_mod_poly_compose_divconquer(fmpz_mod_poly_t res, + const fmpz_mod_poly_t poly1, + const fmpz_mod_poly_t poly2) + + Sets \code{res} to the composition of \code{poly1} and \code{poly2} + using a divide and conquer algorithm which takes out factors of + \code{poly2} raised to $2^i$ where possible. + + To be precise about the order of composition, denoting \code{res}, + \code{poly1}, and \code{poly2} by $f$, $g$, and $h$, respectively, + sets $f(t) = g(h(t))$. + +void _fmpz_mod_poly_compose(fmpz *res, const fmpz *poly1, slong len1, + const fmpz *poly2, slong len2, + const fmpz_t p) + + Sets \code{res} to the composition of \code{(poly1, len1)} and + \code{(poly2, len2)}. + + Assumes that \code{res} has space for \code{(len1-1)*(len2-1) + 1} + coefficients, although in $\mathbf{Z}_p[X]$ this might not actually + be the length of the resulting polynomial when $p$ is not a prime. + + Assumes that \code{poly1} and \code{poly2} are non-zero polynomials. + Does not support aliasing between any of the inputs and the output. + +void fmpz_mod_poly_compose(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly1, + const fmpz_mod_poly_t poly2) + + Sets \code{res} to the composition of \code{poly1} and \code{poly2}. + + To be precise about the order of composition, denoting \code{res}, + \code{poly1}, and \code{poly2} by $f$, $g$, and $h$, respectively, + sets $f(t) = g(h(t))$. + +******************************************************************************* + + Modular composition + +******************************************************************************* + +void _fmpz_mod_poly_compose_mod(fmpz * res, + const fmpz * f, slong lenf, const fmpz * g, + const fmpz * h, slong lenh, const fmpz_t p) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require that + $h$ is nonzero and that the length of $g$ is one less than the + length of $h$ (possibly with zero padding). The output is not allowed + to be aliased with any of the inputs. + +void +fmpz_mod_poly_compose_mod(fmpz_mod_poly_t res, const fmpz_mod_poly_t f, + const fmpz_mod_poly_t g, const fmpz_mod_poly_t h) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require that + $h$ is nonzero. + +void _fmpz_mod_poly_compose_mod_horner(fmpz * res, + const fmpz * f, slong lenf, const fmpz * g, + const fmpz * h, slong lenh, const fmpz_t p) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require that + $h$ is nonzero and that the length of $g$ is one less than the + length of $h$ (possibly with zero padding). The output is not allowed + to be aliased with any of the inputs. + + The algorithm used is Horner's rule. + +void +fmpz_mod_poly_compose_mod_horner(fmpz_mod_poly_t res, const fmpz_mod_poly_t f, + const fmpz_mod_poly_t g, const fmpz_mod_poly_t h) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require that + $h$ is nonzero. The algorithm used is Horner's rule. + +void +_fmpz_mod_poly_compose_mod_brent_kung(fmpz * res, const fmpz * f, slong len1, + const fmpz * g, const fmpz * h, slong len3, const fmpz_t p) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require that + $h$ is nonzero and that the length of $g$ is one less than the + length of $h$ (possibly with zero padding). We also require that + the length of $f$ is less than the length of $h$. The output is not + allowed to be aliased with any of the inputs. + + The algorithm used is the Brent-Kung matrix algorithm. + +void fmpz_mod_poly_compose_mod_brent_kung( + fmpz_mod_poly_t res, const fmpz_mod_poly_t f, + const fmpz_mod_poly_t g, const fmpz_mod_poly_t h) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require that + $h$ is nonzero and that $f$ has smaller degree than $h$. + The algorithm used is the Brent-Kung matrix algorithm. + +void +_fmpz_mod_poly_reduce_matrix_mod_poly (fmpz_mat_t A, const fmpz_mat_t B, + const fmpz_mod_poly_t f) + + Sets the ith row of \code{A} to the reduction of the ith row of $B$ modulo + $f$ for $i=1,\ldots,\sqrt{\deg(f)}$. We require $B$ to be at least + a $\sqrt{\deg(f)}\times \deg(f)$ matrix and $f$ to be nonzero. + +void +_fmpz_mod_poly_precompute_matrix (fmpz_mat_t A, const fmpz * f, + const fmpz * g, slong leng, const fmpz * ginv, + slong lenginv, const fmpz_t p) + + Sets the ith row of \code{A} to $f^i$ modulo $g$ for + $i=1,\ldots,\sqrt{\deg(g)}$. We require $A$ to be + a $\sqrt{\deg(g)}\times \deg(g)$ matrix. We require + \code{ginv} to be the inverse of the reverse of \code{g} and $g$ to be + nonzero. + +void +fmpz_mod_poly_precompute_matrix(fmpz_mat_t A, const fmpz_mod_poly_t f, + const fmpz_mod_poly_t g, const fmpz_mod_poly_t ginv) + + Sets the ith row of \code{A} to $f^i$ modulo $g$ for + $i=1,\ldots,\sqrt{\deg(g)}$. We require $A$ to be + a $\sqrt{\deg(g)}\times \deg(g)$ matrix. We require + \code{ginv} to be the inverse of the reverse of \code{g}. + +void +_fmpz_mod_poly_compose_mod_brent_kung_precomp_preinv(fmpz * res, + const fmpz * f, slong lenf, const fmpz_mat_t A, const fmpz * h, + slong lenh, const fmpz * hinv, slong lenhinv, const fmpz_t p) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require that + $h$ is nonzero. We require that the ith row of $A$ contains $g^i$ for + $i=1,\ldots,\sqrt{\deg(h)}$, i.e. $A$ is a + $\sqrt{\deg(h)}\times \deg(h)$ matrix. We also require that + the length of $f$ is less than the length of $h$. Furthermore, we require + \code{hinv} to be the inverse of the reverse of \code{h}. + The output is not allowed to be aliased with any of the inputs. + + The algorithm used is the Brent-Kung matrix algorithm. + +void +fmpz_mod_poly_compose_mod_brent_kung_precomp_preinv(fmpz_mod_poly_t res, + const fmpz_mod_poly_t f, const fmpz_mat_t A, + const fmpz_mod_poly_t h, const fmpz_mod_poly_t hinv) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require that the + ith row of $A$ contains $g^i$ for $i=1,\ldots,\sqrt{\deg(h)}$, i.e. $A$ is + a $\sqrt{\deg(h)}\times \deg(h)$ matrix. We require that $h$ is nonzero and + that $f$ has smaller degree than $h$. Furthermore, we require \code{hinv} + to be the inverse of the reverse of \code{h}. This version of Brent-Kung + modular composition is particularly useful if one has to perform several + modular composition of the form $f(g)$ modulo $h$ for fixed $g$ and $h$. + +void +_fmpz_mod_poly_compose_mod_brent_kung_preinv(fmpz * res, const fmpz * f, + slong lenf, const fmpz * g, const fmpz * h, slong lenh, + const fmpz * hinv, slong lenhinv, const fmpz_t p) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require that + $h$ is nonzero and that the length of $g$ is one less than the + length of $h$ (possibly with zero padding). We also require that + the length of $f$ is less than the length of $h$. Furthermore, we require + \code{hinv} to be the inverse of the reverse of \code{h}. + The output is not allowed to be aliased with any of the inputs. + + The algorithm used is the Brent-Kung matrix algorithm. + +void +fmpz_mod_poly_compose_mod_brent_kung_preinv(fmpz_mod_poly_t res, + const fmpz_mod_poly_t f, const fmpz_mod_poly_t g, + const fmpz_mod_poly_t h, const fmpz_mod_poly_t hinv) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require that + $h$ is nonzero and that $f$ has smaller degree than $h$. Furthermore, + we require \code{hinv} to be the inverse of the reverse of \code{h}. + The algorithm used is the Brent-Kung matrix algorithm. + +******************************************************************************* + + Subproduct trees + +******************************************************************************* + +fmpz_poly_struct ** _fmpz_mod_poly_tree_alloc(slong len) + + Allocates space for a subproduct tree of the given length, having + linear factors at the lowest level. + +void _fmpz_mod_poly_tree_free(fmpz_poly_struct ** tree, slong len) + + Free the allocated space for the subproduct. + +void _fmpz_mod_poly_tree_build(fmpz_poly_struct ** tree, + const fmpz * roots, slong len, const fmpz_t mod) + + Builds a subproduct tree in the preallocated space from + the \code{len} monic linear factors $(x-r_i)$ where $r_i$ are given by + \code{roots}. The top level product is not computed. + +******************************************************************************* + + Radix conversion + + The following functions provide the functionality to solve the + radix conversion problems for polynomials, which is to express + a polynomial $f(X)$ with respect to a given radix $r(X)$ as + \begin{equation*} + f(X) = \sum_{i = 0}^{N} b_i(X) r(X)^i + \end{equation*} + where $N = \floor{\deg(f) / \deg(r)}$. + + The algorithm implemented here is a recursive one, which performs + Euclidean divisions by powers of $r$ of the form $r^{2^i}$, and it + has time complexity $\Theta(\deg(f) \log \deg(f))$. + + It facilitates the repeated use of precomputed data, namely the + powers of $r$ and their power series inverses. This data is stored + in objects of type \code{fmpz_mod_poly_radix_t} and it is computed + using the function \code{fmpz_mod_poly_radix_init()}, which only + depends on~$r$ and an upper bound on the degree of~$f$. + +******************************************************************************* + +void _fmpz_mod_poly_radix_init(fmpz **Rpow, fmpz **Rinv, + const fmpz *R, slong lenR, slong k, + const fmpz_t invL, const fmpz_t p) + + Computes powers of $R$ of the form $R^{2^i}$ and their Newton inverses + modulo $x^{2^{i} \deg(R)}$ for $i = 0, \dotsc, k-1$. + + Assumes that the vectors \code{Rpow[i]} and \code{Rinv[i]} have space + for $2^i \deg(R) + 1$ and $2^i \deg(R)$ coefficients, respectively. + + Assumes that the polynomial $R$ is non-constant, i.e.\ $\deg(R) \geq 1$. + + Assumes that the leading coefficient of $R$ is a unit and that the + argument \code{invL} is the inverse of the coefficient modulo~$p$. + + The argument~$p$ is the modulus, which in $p$-adic applications is + typically a prime power, although this is not necessary. Here, we + only assume that $p \geq 2$. + + Note that this precomputed data can be used for any $F$ such that + $\len(F) \leq 2^k \deg(R)$. + +void fmpz_mod_poly_radix_init(fmpz_mod_poly_radix_t D, + const fmpz_mod_poly_t R, slong degF) + + Carries out the precomputation necessary to perform radix conversion + to radix~$R$ for polynomials~$F$ of degree at most \code{degF}. + + Assumes that $R$ is non-constant, i.e.\ $\deg(R) \geq 1$, + and that the leading coefficient is a unit. + +void _fmpz_mod_poly_radix(fmpz **B, const fmpz *F, fmpz **Rpow, fmpz **Rinv, + slong degR, slong k, slong i, fmpz *W, const fmpz_t p) + + This is the main recursive function used by the + function \code{fmpz_mod_poly_radix()}. + + Assumes that, for all $i = 0, \dotsc, N$, the vector + \code{B[i]} has space for $\deg(R)$ coefficients. + + The variable $k$ denotes the factors of $r$ that have + previously been counted for the polynomial $F$, which + is assumed to have length $2^{i+1} \deg(R)$, possibly + including zero-padding. + + Assumes that $W$ is a vector providing temporary space + of length $\len(F) = 2^{i+1} \deg(R)$. + + The entire computation takes place over $\mathbf{Z} / p \mathbf{Z}$, + where $p \geq 2$ is a natural number. + + Thus, the top level call will have $F$ as in the original + problem, and $k = 0$. + +void fmpz_mod_poly_radix(fmpz_mod_poly_struct **B, const fmpz_mod_poly_t F, + const fmpz_mod_poly_radix_t D) + + Given a polynomial $F$ and the precomputed data $D$ for the radix $R$, + computes polynomials $B_0, \dotsc, B_N$ of degree less than $\deg(R)$ + such that + \begin{equation*} + F = B_0 + B_1 R + \dotsb + B_N R^N, + \end{equation*} + where necessarily $N = \floor{\deg(F) / \deg(R)}$. + + Assumes that $R$ is non-constant, i.e.\ $\deg(R) \geq 1$, + and that the leading coefficient is a unit. + +******************************************************************************* + + Input and output + + The printing options supported by this module are very similar to + what can be found in the two related modules \code{fmpz_poly} and + \code{nmod_poly}. + + Consider, for example, the polynomial $f(x) = 5x^3 + 2x + 1$ in + $(\mathbf{Z}/6\mathbf{Z})[x]$. Its simple string representation + is \code{"4 6 1 2 0 5"}, where the first two numbers denote the + length of the polynomial and the modulus. The pretty string + representation is \code{"5*x^3+2*x+1"}. + +******************************************************************************* + +int _fmpz_mod_poly_fprint(FILE * file, const fmpz *poly, slong len, + const fmpz_t p) + + Prints the polynomial \code{(poly, len)} to the stream \code{file}. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + +int fmpz_mod_poly_fprint(FILE * file, const fmpz_mod_poly_t poly) + + Prints the polynomial to the stream \code{file}. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + +int fmpz_mod_poly_fprint_pretty(FILE * file, + const fmpz_mod_poly_t poly, const char * x) + + Prints the pretty representation of \code{(poly, len)} to the stream + \code{file}, using the string \code{x} to represent the indeterminate. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + +int fmpz_mod_poly_print(const fmpz_mod_poly_t poly) + + Prints the polynomial to \code{stdout}. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + +int fmpz_mod_poly_print_pretty(const fmpz_mod_poly_t poly, const char * x) + + Prints the pretty representation of \code{poly} to \code{stdout}, + using the string \code{x} to represent the indeterminate. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. diff --git a/external/flint-2.4.3/fmpz_mod_poly/evaluate_fmpz.c b/external/flint-2.4.3/fmpz_mod_poly/evaluate_fmpz.c new file mode 100644 index 0000000..7337716 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/evaluate_fmpz.c @@ -0,0 +1,80 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz_mod_poly.h" + +void _fmpz_mod_poly_evaluate_fmpz(fmpz_t res, const fmpz *poly, slong len, + const fmpz_t a, const fmpz_t p) +{ + if (len == 0) + { + fmpz_zero(res); + } + else if (len == 1 || fmpz_is_zero(a)) + { + fmpz_set(res, poly); + } + else + { + slong i = len - 1; + fmpz_t t; + + fmpz_init(t); + fmpz_set(res, poly + i); + for (i = len - 2; i >= 0; i--) + { + fmpz_mul(t, res, a); + fmpz_mod(t, t, p); + fmpz_add(res, poly + i, t); + } + fmpz_clear(t); + + if (fmpz_cmpabs(res, p) >= 0) + fmpz_sub(res, res, p); + } +} + +void fmpz_mod_poly_evaluate_fmpz(fmpz_t res, + const fmpz_mod_poly_t poly, const fmpz_t a) +{ + if (res == a) + { + fmpz_t t; + + fmpz_init(t); + _fmpz_mod_poly_evaluate_fmpz(t, poly->coeffs, poly->length, + a, &(poly->p)); + fmpz_swap(res, t); + fmpz_clear(t); + } + else + { + _fmpz_mod_poly_evaluate_fmpz(res, poly->coeffs, poly->length, + a, &(poly->p)); + } +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/evaluate_fmpz_vec.c b/external/flint-2.4.3/fmpz_mod_poly/evaluate_fmpz_vec.c new file mode 100644 index 0000000..eb32fca --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/evaluate_fmpz_vec.c @@ -0,0 +1,50 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpz_mod_poly.h" + +void +_fmpz_mod_poly_evaluate_fmpz_vec(fmpz * ys, const fmpz * coeffs, + slong len, const fmpz * xs, slong n, const fmpz_t mod) +{ + if (len < 32) + _fmpz_mod_poly_evaluate_fmpz_vec_iter(ys, coeffs, len, xs, n, mod); + else + _fmpz_mod_poly_evaluate_fmpz_vec_fast(ys, coeffs, len, xs, n, mod); +} + +void +fmpz_mod_poly_evaluate_fmpz_vec(fmpz * ys, + const fmpz_mod_poly_t poly, const fmpz * xs, slong n) +{ + _fmpz_mod_poly_evaluate_fmpz_vec(ys, poly->coeffs, + poly->length, xs, n, &(poly->p)); +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/evaluate_fmpz_vec_fast.c b/external/flint-2.4.3/fmpz_mod_poly/evaluate_fmpz_vec_fast.c new file mode 100644 index 0000000..122977e --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/evaluate_fmpz_vec_fast.c @@ -0,0 +1,151 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Fredrik Johansson + Copyright (C) 2012 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_mod_poly.h" + +void +_fmpz_mod_poly_evaluate_fmpz_vec_fast_precomp(fmpz * vs, const fmpz * poly, + slong plen, fmpz_poly_struct * const * tree, slong len, const fmpz_t mod) +{ + slong height, i, j, pow, left; + slong tree_height; + fmpz_t temp, inv; + fmpz * t, * u, * pb, * pc, * swap; + fmpz_poly_struct * pa; + + fmpz_init(temp); + fmpz_init(inv); + + /* avoid worrying about some degenerate cases */ + if (len < 2 || plen < 2) + { + if (len == 1) + { + fmpz_negmod(temp, tree[0]->coeffs, mod); + _fmpz_mod_poly_evaluate_fmpz(vs, poly, plen, temp, mod); + } else if (len != 0 && plen == 0) + _fmpz_vec_zero(vs, len); + else if (len != 0 && plen == 1) + for (i = 0; i < len; i++) + fmpz_set(vs + i, poly); + + fmpz_clear(temp); + return; + } + + t = _fmpz_vec_init(2*len); + u = _fmpz_vec_init(2*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 = WORD(1) << height; + + for (i = j = 0; i < len; i += pow, j++) + { + pa = tree[height] + j; + fmpz_invmod(inv, pa->coeffs + pa->length - 1, mod); + _fmpz_mod_poly_rem(t + i, poly, plen, pa->coeffs, pa->length, inv, mod); + } + + for (i = height - 1; i >= 0; i--) + { + pow = WORD(1) << i; + left = len; + pa = tree[i]; + pb = t; + pc = u; + + left = len; + while (left >= 2 * pow) + { + fmpz_invmod(inv, pa->coeffs + pa->length - 1, mod); + _fmpz_mod_poly_rem(pc, pb, 2 * pow, pa->coeffs, pa->length, inv, mod); + + pa++; + fmpz_invmod(inv, pa->coeffs + pa->length - 1, mod); + _fmpz_mod_poly_rem(pc + pow, pb, 2 * pow, pa->coeffs, pa->length, inv, mod); + + pa++; + pb += 2 * pow; + pc += 2 * pow; + left -= 2 * pow; + } + + if (left > pow) + { + fmpz_invmod(inv, pa->coeffs + pa->length - 1, mod); + _fmpz_mod_poly_rem(pc, pb, left, pa->coeffs, pa->length, inv, mod); + + pa ++; + fmpz_invmod(inv, pa->coeffs + pa->length - 1, mod); + _fmpz_mod_poly_rem(pc + pow, pb, left, pa->coeffs, pa->length, inv, mod); + } + else if (left > 0) + _fmpz_vec_set(pc, pb, left); + + swap = t; + t = u; + u = swap; + } + + fmpz_clear(temp); + fmpz_clear(inv); + + _fmpz_vec_set(vs, t, len); + + _fmpz_vec_clear(t, 2*len); + _fmpz_vec_clear(u, 2*len); +} + +void _fmpz_mod_poly_evaluate_fmpz_vec_fast(fmpz * ys, const fmpz * poly, slong plen, + const fmpz * xs, slong n, const fmpz_t mod) +{ + fmpz_poly_struct ** tree; + + tree = _fmpz_mod_poly_tree_alloc(n); + _fmpz_mod_poly_tree_build(tree, xs, n, mod); + _fmpz_mod_poly_evaluate_fmpz_vec_fast_precomp(ys, poly, plen, tree, n, mod); + _fmpz_mod_poly_tree_free(tree, n); +} + +void +fmpz_mod_poly_evaluate_fmpz_vec_fast(fmpz * ys, + const fmpz_mod_poly_t poly, const fmpz * xs, slong n) +{ + _fmpz_mod_poly_evaluate_fmpz_vec_fast(ys, poly->coeffs, + poly->length, xs, n, &(poly->p)); +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/evaluate_fmpz_vec_iter.c b/external/flint-2.4.3/fmpz_mod_poly/evaluate_fmpz_vec_iter.c new file mode 100644 index 0000000..5d2dafc --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/evaluate_fmpz_vec_iter.c @@ -0,0 +1,49 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpz_mod_poly.h" + +void +_fmpz_mod_poly_evaluate_fmpz_vec_iter(fmpz * ys, const fmpz * coeffs, slong len, + const fmpz * xs, slong n, const fmpz_t mod) +{ + slong i; + for (i = 0; i < n; i++) + _fmpz_mod_poly_evaluate_fmpz(ys + i, coeffs, len, xs + i, mod); +} + +void +fmpz_mod_poly_evaluate_fmpz_vec_iter(fmpz * ys, + const fmpz_mod_poly_t poly, const fmpz * xs, slong n) +{ + _fmpz_mod_poly_evaluate_fmpz_vec_iter(ys, poly->coeffs, + poly->length, xs, n, &(poly->p)); +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/fit_length.c b/external/flint-2.4.3/fmpz_mod_poly/fit_length.c new file mode 100644 index 0000000..a747a44 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/fit_length.c @@ -0,0 +1,42 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2008, 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" + +void fmpz_mod_poly_fit_length(fmpz_mod_poly_t poly, slong len) +{ + if (len > poly->alloc) + { + /* At least double number of allocated coeffs */ + if (len < 2 * poly->alloc) + len = 2 * poly->alloc; + fmpz_mod_poly_realloc(poly, len); + } +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/fprint.c b/external/flint-2.4.3/fmpz_mod_poly/fprint.c new file mode 100644 index 0000000..53f9d58 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/fprint.c @@ -0,0 +1,70 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include + +#include "fmpz.h" +#include "fmpz_mod_poly.h" + +int _fmpz_mod_poly_fprint(FILE * file, const fmpz *poly, slong len, + const fmpz_t p) +{ + int r; + slong i; + + r = flint_fprintf(file, "%wd ", len); + if (r <= 0) + return r; + + r = fmpz_fprint(file, p); + if (r <= 0) + return r; + + if (len == 0) + return r; + + r = flint_fprintf(file, " "); + if (r <= 0) + return r; + + for (i = 0; (r > 0) && (i < len); i++) + { + r = flint_fprintf(file, " "); + if (r <= 0) + return r; + r = fmpz_fprint(file, poly + i); + if (r <= 0) + return r; + } + + return r; +} + +int fmpz_mod_poly_fprint(FILE * file, const fmpz_mod_poly_t poly) +{ + return _fmpz_mod_poly_fprint(file, poly->coeffs, poly->length, &(poly->p)); +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/fread.c b/external/flint-2.4.3/fmpz_mod_poly/fread.c new file mode 100644 index 0000000..e0afbf1 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/fread.c @@ -0,0 +1,69 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007, David Howden. + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz_mod_poly.h" +#include "fmpz.h" + +int fmpz_mod_poly_fread(FILE * f, fmpz_mod_poly_t poly) +{ + slong i, length; + fmpz_t coeff; + ulong res; + + fmpz_init(coeff); + if (flint_fscanf(f, "%wd", &length) != 1) { + fmpz_clear(coeff); + return 0; + } + + fmpz_fread(f,coeff); + fmpz_mod_poly_clear(poly); + fmpz_mod_poly_init(poly, coeff); + fmpz_mod_poly_fit_length(poly, length); + poly->length = length; + + for (i = 0; i < length; i++) + { + res = fmpz_fread(f, coeff); + fmpz_mod_poly_set_coeff_fmpz(poly,i,coeff); + + if (!res) + { + poly->length = i; + fmpz_clear(coeff); + return 0; + } + } + + fmpz_clear(coeff); + _fmpz_mod_poly_normalise(poly); + + return 1; +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/gcd_euclidean.c b/external/flint-2.4.3/fmpz_mod_poly/gcd_euclidean.c new file mode 100644 index 0000000..f1a7fb5 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/gcd_euclidean.c @@ -0,0 +1,151 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "fmpz_vec.h" +#include "fmpz_mod_poly.h" + +slong _fmpz_mod_poly_gcd_euclidean(fmpz *G, const fmpz *A, slong lenA, + const fmpz *B, slong lenB, + const fmpz_t invB, const fmpz_t p) +{ + if (lenB == 1) + { + fmpz_one(G); + return 1; + } + else /* lenA >= lenB > 1 */ + { + const slong lenW = FLINT_MAX(lenA - lenB + 1, lenB) + lenA + 2 * lenB; + fmpz_t invR3; + fmpz *Q, *R1, *R2, *R3, *T, *W; + slong lenR2, lenR3; + + W = _fmpz_vec_init(lenW); + Q = W; + R1 = W + FLINT_MAX(lenA - lenB + 1, lenB); + R2 = R1 + lenA; + R3 = R2 + lenB; + + _fmpz_mod_poly_divrem(Q, R1, A, lenA, B, lenB, invB, p); + + lenR3 = lenB - 1; + FMPZ_VEC_NORM(R1, lenR3); + + if (lenR3 == 0) + { + _fmpz_vec_set(G, B, lenB); + _fmpz_vec_clear(W, lenW); + return lenB; + } + + fmpz_init(invR3); + + T = R3; + R3 = R1; + R1 = T; + _fmpz_vec_set(R2, B, lenB); + lenR2 = lenB; + + do + { + fmpz_invmod(invR3, R3 + (lenR3 - 1), p); + + _fmpz_mod_poly_divrem(Q, R1, R2, lenR2, R3, lenR3, invR3, p); + lenR2 = lenR3--; + FMPZ_VEC_NORM(R1, lenR3); + T = R2; R2 = R3; R3 = R1; R1 = T; + } + while (lenR3 > 0); + + _fmpz_vec_set(G, R2, lenR2); + + _fmpz_vec_clear(W, lenW); + fmpz_clear(invR3); + + return lenR2; + } +} + +void fmpz_mod_poly_gcd_euclidean(fmpz_mod_poly_t G, + const fmpz_mod_poly_t A, + const fmpz_mod_poly_t B) +{ + if (A->length < B->length) + { + fmpz_mod_poly_gcd_euclidean(G, B, A); + } + else /* lenA >= lenB >= 0 */ + { + const slong lenA = A->length, lenB = B->length; + slong lenG; + fmpz *g; + + if (lenA == 0) /* lenA = lenB = 0 */ + { + fmpz_mod_poly_zero(G); + } + else if (lenB == 0) /* lenA > lenB = 0 */ + { + fmpz_mod_poly_make_monic(G, A); + } + else /* lenA >= lenB >= 1 */ + { + fmpz_t invB; + + if (G == A || G == B) + { + g = _fmpz_vec_init(FLINT_MIN(lenA, lenB)); + } + else + { + fmpz_mod_poly_fit_length(G, FLINT_MIN(lenA, lenB)); + g = G->coeffs; + } + + fmpz_init(invB); + fmpz_invmod(invB, fmpz_mod_poly_lead(B), &(B->p)); + lenG = _fmpz_mod_poly_gcd_euclidean(g, A->coeffs, lenA, + B->coeffs, lenB, invB, &(B->p)); + fmpz_clear(invB); + + if (G == A || G == B) + { + _fmpz_vec_clear(G->coeffs, G->alloc); + G->coeffs = g; + G->alloc = FLINT_MIN(lenA, lenB); + G->length = FLINT_MIN(lenA, lenB); + } + _fmpz_mod_poly_set_length(G, lenG); + + if (lenG == 1) + fmpz_one(G->coeffs); + else + fmpz_mod_poly_make_monic(G, G); + } + } +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/gcd_euclidean_f.c b/external/flint-2.4.3/fmpz_mod_poly/gcd_euclidean_f.c new file mode 100644 index 0000000..ab199f5 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/gcd_euclidean_f.c @@ -0,0 +1,176 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "fmpz_vec.h" +#include "fmpz_mod_poly.h" + +slong _fmpz_mod_poly_gcd_euclidean_f(fmpz_t f, fmpz *G, + const fmpz *A, slong lenA, + const fmpz *B, slong lenB, const fmpz_t p) +{ + slong lenG = 0; + + if (lenB == 1) + { + fmpz_t invB; + fmpz_init(invB); + fmpz_gcdinv(f, invB, B, p); + if (fmpz_is_one(f)) + { + fmpz_one(G); + lenG = 1; + } + fmpz_clear(invB); + } + else /* lenA >= lenB > 1 */ + { + const slong lenW = FLINT_MAX(lenA - lenB + 1, lenB) + lenA + 2 * lenB; + fmpz *Q, *R1, *R2, *R3, *T, *W; + slong lenR2, lenR3; + + W = _fmpz_vec_init(lenW); + Q = W; + R1 = W + FLINT_MAX(lenA - lenB + 1, lenB); + R2 = R1 + lenA; + R3 = R2 + lenB; + + _fmpz_mod_poly_divrem_f(f, Q, R1, A, lenA, B, lenB, p); + if (!fmpz_is_one(f)) + goto exit; + + lenR3 = lenB - 1; + FMPZ_VEC_NORM(R1, lenR3); + + if (lenR3 == 0) + { + _fmpz_vec_set(G, B, lenB); + lenG = lenB; + } + else + { + T = R3; + R3 = R1; + R1 = T; + _fmpz_vec_set(R2, B, lenB); + lenR2 = lenB; + + do + { + _fmpz_mod_poly_divrem_f(f, Q, R1, R2, lenR2, R3, lenR3, p); + if (!fmpz_is_one(f)) + goto exit; + + lenR2 = lenR3--; + FMPZ_VEC_NORM(R1, lenR3); + T = R2; R2 = R3; R3 = R1; R1 = T; + } + while (lenR3 > 0); + + _fmpz_vec_set(G, R2, lenR2); + lenG = lenR2; + } + + exit: + _fmpz_vec_clear(W, lenW); + } + return lenG; +} + +void fmpz_mod_poly_gcd_euclidean_f(fmpz_t f, fmpz_mod_poly_t G, + const fmpz_mod_poly_t A, + const fmpz_mod_poly_t B) +{ + if (A->length < B->length) + { + fmpz_mod_poly_gcd_euclidean_f(f, G, B, A); + } + else /* lenA >= lenB >= 0 */ + { + const slong lenA = A->length, lenB = B->length; + slong lenG; + fmpz *g; + + if (lenA == 0) /* lenA = lenB = 0 */ + { + fmpz_mod_poly_zero(G); + fmpz_one(f); + } + else if (lenB == 0) /* lenA > lenB = 0 */ + { + fmpz_t invA; + fmpz_init(invA); + fmpz_gcdinv(f, invA, A->coeffs + lenA - 1, &B->p); + if (fmpz_is_one(f)) + fmpz_mod_poly_scalar_mul_fmpz(G, A, invA); + else + fmpz_mod_poly_zero(G); + fmpz_clear(invA); + } + else /* lenA >= lenB >= 1 */ + { + if (G == A || G == B) + { + g = _fmpz_vec_init(FLINT_MIN(lenA, lenB)); + } + else + { + fmpz_mod_poly_fit_length(G, FLINT_MIN(lenA, lenB)); + g = G->coeffs; + } + + lenG = _fmpz_mod_poly_gcd_euclidean_f(f, g, A->coeffs, lenA, + B->coeffs, lenB, &(B->p)); + + if (fmpz_is_one(f)) + { + if (G == A || G == B) + { + _fmpz_vec_clear(G->coeffs, G->alloc); + G->coeffs = g; + G->alloc = FLINT_MIN(lenA, lenB); + G->length = FLINT_MIN(lenA, lenB); + } + _fmpz_mod_poly_set_length(G, lenG); + if (lenG == 1) + fmpz_one(G->coeffs); + else + fmpz_mod_poly_make_monic(G, G); + } + else /* Factor found, ensure G is normalised */ + { + if (G == A || G == B) + _fmpz_vec_clear(g, FLINT_MIN(lenA, lenB)); + else + { + _fmpz_vec_zero(G->coeffs, FLINT_MIN(lenA, lenB)); + _fmpz_mod_poly_set_length(G, 0); + } + } + } + } +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/gcdinv.c b/external/flint-2.4.3/fmpz_mod_poly/gcdinv.c new file mode 100644 index 0000000..dda3df7 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/gcdinv.c @@ -0,0 +1,133 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "fmpz_vec.h" +#include "fmpz_mod_poly.h" + +slong _fmpz_mod_poly_gcdinv(fmpz *G, fmpz *S, + const fmpz *A, slong lenA, const fmpz *B, slong lenB, + const fmpz_t p) +{ + fmpz *T; + fmpz_t inv; + slong ans; + + T = _fmpz_vec_init(lenA - 1); + fmpz_init(inv); + fmpz_invmod(inv, A + (lenA - 1), p); + + ans = _fmpz_mod_poly_xgcd(G, T, S, B, lenB, A, lenA, inv, p); + + fmpz_clear(inv); + _fmpz_vec_clear(T, lenA - 1); + + return ans; +} + +void fmpz_mod_poly_gcdinv(fmpz_mod_poly_t G, fmpz_mod_poly_t S, + const fmpz_mod_poly_t A, const fmpz_mod_poly_t B) +{ + const slong lenA = A->length, lenB = B->length; + + if (lenB < 2) + { + flint_printf("Exception (fmpz_mod_poly_gcdinv). lenB < 2.\n"); + abort(); + } + if (lenA >= lenB) + { + fmpz_mod_poly_t T; + + fmpz_mod_poly_init(T, &A->p); + fmpz_mod_poly_rem(T, A, B); + fmpz_mod_poly_gcdinv(G, S, T, B); + fmpz_mod_poly_clear(T); + return; + } + + if (lenA == 0) + { + fmpz_mod_poly_zero(G); + fmpz_mod_poly_zero(S); + } + else + { + fmpz *g, *s; + slong lenG; + + if (G == A || G == B) + { + g = _fmpz_vec_init(lenA); + } + else + { + fmpz_mod_poly_fit_length(G, lenA); + g = G->coeffs; + } + if (S == A || S == B) + { + s = _fmpz_vec_init(lenB - 1); + } + else + { + fmpz_mod_poly_fit_length(S, lenB - 1); + s = S->coeffs; + } + + lenG = _fmpz_mod_poly_gcdinv(g, s, + A->coeffs, lenA, B->coeffs, lenB, &A->p); + + if (G == A || G == B) + { + _fmpz_vec_clear(G->coeffs, G->alloc); + G->coeffs = g; + G->alloc = lenA; + } + if (S == A || S == B) + { + _fmpz_vec_clear(S->coeffs, S->alloc); + S->coeffs = s; + S->alloc = lenB - 1; + } + + _fmpz_mod_poly_set_length(G, lenG); + _fmpz_mod_poly_set_length(S, lenB - lenG); + _fmpz_mod_poly_normalise(S); + + if (!fmpz_is_one(fmpz_mod_poly_lead(G))) + { + fmpz_t inv; + + fmpz_init(inv); + fmpz_invmod(inv, fmpz_mod_poly_lead(G), &A->p); + fmpz_mod_poly_scalar_mul_fmpz(G, G, inv); + fmpz_mod_poly_scalar_mul_fmpz(S, S, inv); + fmpz_clear(inv); + } + } +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/get_fmpz_poly.c b/external/flint-2.4.3/fmpz_mod_poly/get_fmpz_poly.c new file mode 100644 index 0000000..5949e83 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/get_fmpz_poly.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" + +void fmpz_mod_poly_get_fmpz_poly(fmpz_poly_t f, const fmpz_mod_poly_t g) +{ + fmpz_poly_fit_length(f, g->length); + _fmpz_poly_set_length(f, g->length); + + _fmpz_vec_set(f->coeffs, g->coeffs, g->length); +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/init.c b/external/flint-2.4.3/fmpz_mod_poly/init.c new file mode 100644 index 0000000..af032be --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/init.c @@ -0,0 +1,53 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" + +void fmpz_mod_poly_init(fmpz_mod_poly_t poly, const fmpz_t p) +{ + poly->coeffs = NULL; + poly->alloc = 0; + poly->length = 0; + fmpz_init(&(poly->p)); + fmpz_set(&(poly->p), p); +} + +void fmpz_mod_poly_init2(fmpz_mod_poly_t poly, const fmpz_t p, slong alloc) +{ + if (alloc) /* allocate space for alloc small coeffs */ + poly->coeffs = (fmpz *) flint_calloc(alloc, sizeof(fmpz)); + else + poly->coeffs = NULL; + + poly->alloc = alloc; + poly->length = 0; + fmpz_init(&(poly->p)); + fmpz_set(&(poly->p), p); +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/inv_series_newton.c b/external/flint-2.4.3/fmpz_mod_poly/inv_series_newton.c new file mode 100644 index 0000000..dd62aff --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/inv_series_newton.c @@ -0,0 +1,134 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" +#include "fmpz_mod_poly.h" + +#define FMPZ_MOD_POLY_INV_NEWTON_CUTOFF 64 + +void +_fmpz_mod_poly_inv_series_newton(fmpz * Qinv, const fmpz * Q, slong n, + const fmpz_t cinv, const fmpz_t p) +{ + if (n == 1) /* {Q,1} * cinv == 1 mod (x) */ + { + fmpz_set(Qinv, cinv); + } + else + { + const slong alloc = FLINT_MAX(n, 3 * FMPZ_MOD_POLY_INV_NEWTON_CUTOFF); + slong *a, i, m; + fmpz *W; + + W = _fmpz_vec_init(alloc); + + for (i = 1; (WORD(1) << i) < n; i++) ; + + a = (slong *) flint_malloc(i * sizeof(slong)); + a[i = 0] = n; + while (n >= FMPZ_MOD_POLY_INV_NEWTON_CUTOFF) + a[++i] = (n = (n + 1) / 2); + + /* Base case */ + { + fmpz *Qrev = W + 2 * FMPZ_MOD_POLY_INV_NEWTON_CUTOFF; + + _fmpz_poly_reverse(Qrev, Q, n, n); + _fmpz_vec_zero(W, 2*n - 2); + fmpz_one(W + (2*n - 2)); + _fmpz_mod_poly_div_basecase(Qinv, W, W, 2*n - 1, Qrev, n, cinv, p); + _fmpz_poly_reverse(Qinv, Qinv, n, n); + } + + for (i--; i >= 0; i--) + { + m = n; + n = a[i]; + + _fmpz_mod_poly_mullow(W, Q, n, Qinv, m, p, n); + _fmpz_mod_poly_mullow(Qinv + m, Qinv, m, W + m, n - m, p, n - m); + _fmpz_mod_poly_neg(Qinv + m, Qinv + m, n - m, p); + } + + _fmpz_vec_clear(W, alloc); + flint_free(a); + } +} + +void fmpz_mod_poly_inv_series_newton(fmpz_mod_poly_t Qinv, + const fmpz_mod_poly_t Q, slong n) +{ + const fmpz *p = &(Q->p); + fmpz_t cinv; + fmpz *Qcopy; + int Qalloc; + + if (Q->length >= n) + { + Qcopy = Q->coeffs; + Qalloc = 0; + } + else + { + slong i; + Qcopy = (fmpz *) flint_malloc(n * sizeof(fmpz)); + for (i = 0; i < Q->length; i++) + Qcopy[i] = Q->coeffs[i]; + flint_mpn_zero((mp_ptr) Qcopy + i, n - i); + Qalloc = 1; + } + + fmpz_init(cinv); + fmpz_invmod(cinv, Q->coeffs, p); + + if (Qinv != Q) + { + fmpz_mod_poly_fit_length(Qinv, n); + _fmpz_mod_poly_inv_series_newton(Qinv->coeffs, Qcopy, n, cinv, p); + } + else + { + fmpz *t = _fmpz_vec_init(n); + + _fmpz_mod_poly_inv_series_newton(t, Qcopy, n, cinv, p); + + _fmpz_vec_clear(Qinv->coeffs, Qinv->alloc); + Qinv->coeffs = t; + Qinv->alloc = n; + Qinv->length = n; + } + _fmpz_mod_poly_set_length(Qinv, n); + _fmpz_mod_poly_normalise(Qinv); + + if (Qalloc) + flint_free(Qcopy); + fmpz_clear(cinv); +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/invmod.c b/external/flint-2.4.3/fmpz_mod_poly/invmod.c new file mode 100644 index 0000000..25089c2 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/invmod.c @@ -0,0 +1,108 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "fmpz_mod_poly.h" + +int _fmpz_mod_poly_invmod(fmpz *A, + const fmpz *B, slong lenB, + const fmpz *P, slong lenP, const fmpz_t p) +{ + fmpz *G; + slong lenG; + + FMPZ_VEC_NORM(B, lenB); + + G = _fmpz_vec_init(lenB); + + lenG = _fmpz_mod_poly_gcdinv(G, A, B, lenB, P, lenP, p); + + if (lenG == 1 && !fmpz_is_one(G + 0)) + { + fmpz_t invG; + + fmpz_init(invG); + fmpz_invmod(invG, G + 0, p); + _fmpz_mod_poly_scalar_mul_fmpz(A, A, lenP - 1, invG, p); + fmpz_clear(invG); + } + + _fmpz_vec_clear(G, lenB); + + return (lenG == 1); +} + +int fmpz_mod_poly_invmod(fmpz_mod_poly_t A, + const fmpz_mod_poly_t B, const fmpz_mod_poly_t P) +{ + const slong lenB = B->length, lenP = P->length; + fmpz *t; + int ans; + + if (lenP < 2) + { + flint_printf("Exception (fmpz_mod_poly_invmod). lenP < 2.\n"); + abort(); + } + if (lenB == 0) + { + fmpz_mod_poly_zero(A); + return 0; + } + if (lenB >= lenP) + { + fmpz_mod_poly_t T; + + fmpz_mod_poly_init(T, &B->p); + fmpz_mod_poly_rem(T, B, P); + ans = fmpz_mod_poly_invmod(A, T, P); + fmpz_mod_poly_clear(T); + return ans; + } + + if (A != B && A != P) + { + fmpz_mod_poly_fit_length(A, lenP - 1); + t = A->coeffs; + } + else + { + t = _fmpz_vec_init(lenP); + } + + ans = _fmpz_mod_poly_invmod(t, B->coeffs, lenB, P->coeffs, lenP, &B->p); + + if (A == B || A == P) + { + _fmpz_vec_clear(A->coeffs, A->alloc); + A->coeffs = t; + A->alloc = lenP - 1; + } + _fmpz_mod_poly_set_length(A, lenP - 1); + _fmpz_mod_poly_normalise(A); + return ans; +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/make_monic.c b/external/flint-2.4.3/fmpz_mod_poly/make_monic.c new file mode 100644 index 0000000..5e5e5be --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/make_monic.c @@ -0,0 +1,52 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" + +void fmpz_mod_poly_make_monic(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly) +{ + const slong len = poly->length; + fmpz_t inv; + + if (len == 0) + { + fmpz_mod_poly_zero(res); + return; + } + + fmpz_init(inv); + fmpz_invmod(inv, fmpz_mod_poly_lead(poly), &(poly->p)); + + fmpz_mod_poly_fit_length(res, len); + _fmpz_mod_poly_set_length(res, len); + + _fmpz_mod_poly_scalar_mul_fmpz(res->coeffs, + poly->coeffs, len, inv, &(poly->p)); + + fmpz_clear(inv); +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/mul.c b/external/flint-2.4.3/fmpz_mod_poly/mul.c new file mode 100644 index 0000000..065611d --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/mul.c @@ -0,0 +1,84 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpz_mod_poly.h" + +void _fmpz_mod_poly_mul(fmpz *res, const fmpz *poly1, slong len1, + const fmpz *poly2, slong len2, const fmpz_t p) +{ + _fmpz_poly_mul(res, poly1, len1, poly2, len2); + _fmpz_vec_scalar_mod_fmpz(res, res, len1 + len2 - 1, p); +} + +void fmpz_mod_poly_mul(fmpz_mod_poly_t res, + const fmpz_mod_poly_t poly1, const fmpz_mod_poly_t poly2) +{ + const slong len1 = poly1->length; + const slong len2 = poly2->length; + const slong lenr = len1 + len2 - 1; + + if ((len1 == 0) || (len2 == 0)) + { + fmpz_mod_poly_zero(res); + return; + } + + if ((res == poly1) || (res == poly2)) + { + fmpz *t = _fmpz_vec_init(lenr); + + if (len1 >= len2) + _fmpz_mod_poly_mul(t, poly1->coeffs, len1, + poly2->coeffs, len2, &(res->p)); + else + _fmpz_mod_poly_mul(t, poly2->coeffs, len2, + poly1->coeffs, len1, &(res->p)); + + _fmpz_vec_clear(res->coeffs, res->alloc); + res->alloc = lenr; + res->length = lenr; + res->coeffs = t; + } + else + { + fmpz_mod_poly_fit_length(res, lenr); + + if (len1 >= len2) + _fmpz_mod_poly_mul(res->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2, &(res->p)); + else + _fmpz_mod_poly_mul(res->coeffs, poly2->coeffs, len2, + poly1->coeffs, len1, &(res->p)); + + _fmpz_mod_poly_set_length(res, lenr); + } + _fmpz_mod_poly_normalise(res); +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/mullow.c b/external/flint-2.4.3/fmpz_mod_poly/mullow.c new file mode 100644 index 0000000..b8051bc --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/mullow.c @@ -0,0 +1,87 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpz_mod_poly.h" + +void _fmpz_mod_poly_mullow(fmpz *res, const fmpz *poly1, slong len1, + const fmpz *poly2, slong len2, + const fmpz_t p, slong n) +{ + _fmpz_poly_mullow(res, poly1, len1, poly2, len2, n); + _fmpz_vec_scalar_mod_fmpz(res, res, n, p); +} + +void fmpz_mod_poly_mullow(fmpz_mod_poly_t res, + const fmpz_mod_poly_t poly1, const fmpz_mod_poly_t poly2, slong n) +{ + const slong len1 = poly1->length; + const slong len2 = poly2->length; + + if ((len1 == 0) || (len2 == 0) || (n == 0)) + { + fmpz_mod_poly_zero(res); + return; + } + + n = FLINT_MIN(n, len1 + len2 - 1); + + if ((res == poly1) || (res == poly2)) + { + fmpz *t = _fmpz_vec_init(n); + + if (len1 >= len2) + _fmpz_mod_poly_mullow(t, poly1->coeffs, len1, + poly2->coeffs, len2, &(res->p), n); + else + _fmpz_mod_poly_mullow(t, poly2->coeffs, len2, + poly1->coeffs, len1, &(res->p), n); + + _fmpz_vec_clear(res->coeffs, res->alloc); + res->coeffs = t; + res->alloc = n; + res->length = n; + _fmpz_mod_poly_normalise(res); + } + else + { + fmpz_mod_poly_fit_length(res, n); + + if (len1 >= len2) + _fmpz_mod_poly_mullow(res->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2, &(res->p), n); + else + _fmpz_mod_poly_mullow(res->coeffs, poly2->coeffs, len2, + poly1->coeffs, len1, &(res->p), n); + + _fmpz_mod_poly_set_length(res, n); + _fmpz_mod_poly_normalise(res); + } +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/mulmod.c b/external/flint-2.4.3/fmpz_mod_poly/mulmod.c new file mode 100644 index 0000000..0be5916 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/mulmod.c @@ -0,0 +1,110 @@ + +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz_vec.h" +#include "fmpz_mod_poly.h" + +void _fmpz_mod_poly_mulmod(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2, const fmpz * f, + slong lenf, const fmpz_t p) +{ + fmpz * T, * Q; + fmpz_t invf; + slong lenT, lenQ; + + lenT = len1 + len2 - 1; + lenQ = lenT - lenf + 1; + + T = _fmpz_vec_init(lenT + lenQ); + Q = T + lenT; + + if (len1 >= len2) + _fmpz_mod_poly_mul(T, poly1, len1, poly2, len2, p); + else + _fmpz_mod_poly_mul(T, poly2, len2, poly1, len1, p); + + fmpz_init(invf); + fmpz_invmod(invf, f + lenf - 1, p); + + _fmpz_mod_poly_divrem(Q, res, T, lenT, f, lenf, invf, p); + + _fmpz_vec_clear(T, lenT + lenQ); + fmpz_clear(invf); +} + +void +fmpz_mod_poly_mulmod(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly1, + const fmpz_mod_poly_t poly2, const fmpz_mod_poly_t f) +{ + slong len1, len2, lenf; + fmpz * fcoeffs; + + lenf = f->length; + len1 = poly1->length; + len2 = poly2->length; + + if (lenf == 0) + { + flint_printf("Exception (fmpz_mod_poly_mulmod). Divide by zero\n"); + abort(); + } + + if (lenf == 1 || len1 == 0 || len2 == 0) + { + fmpz_mod_poly_zero(res); + return; + } + + if (len1 + len2 - lenf > 0) + { + if (f == res) + { + fcoeffs = _fmpz_vec_init(lenf); + _fmpz_vec_set(fcoeffs, f->coeffs, lenf); + } + else + fcoeffs = f->coeffs; + + fmpz_mod_poly_fit_length(res, len1 + len2 - 1); + _fmpz_mod_poly_mulmod(res->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2, + fcoeffs, lenf, + &res->p); + if (f == res) + _fmpz_vec_clear(fcoeffs, lenf); + + _fmpz_mod_poly_set_length(res, lenf - 1); + _fmpz_mod_poly_normalise(res); + } + else + { + fmpz_mod_poly_mul(res, poly1, poly2); + } +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/mulmod_preinv.c b/external/flint-2.4.3/fmpz_mod_poly/mulmod_preinv.c new file mode 100644 index 0000000..bdaf090 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/mulmod_preinv.c @@ -0,0 +1,121 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Martin Lee + +******************************************************************************/ + +#undef ulong +#define ulong ulongxx/* interferes with system includes */ + +#include + +#undef ulong + +#include + +#define ulong mp_limb_t + +#include "flint.h" +#include "fmpz_vec.h" +#include "fmpz_mod_poly.h" + +void _fmpz_mod_poly_mulmod_preinv(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2, const fmpz * f, slong lenf, + const fmpz* finv, slong lenfinv, const fmpz_t p) +{ + fmpz * T, * Q; + slong lenT, lenQ; + + lenT = len1 + len2 - 1; + lenQ = lenT - lenf + 1; + + T = _fmpz_vec_init(lenT + lenQ); + Q = T + lenT; + + if (len1 >= len2) + _fmpz_mod_poly_mul(T, poly1, len1, poly2, len2, p); + else + _fmpz_mod_poly_mul(T, poly2, len2, poly1, len1, p); + + _fmpz_mod_poly_divrem_newton_n_preinv(Q, res, T, lenT, f, lenf, + finv, lenfinv, p); + + _fmpz_vec_clear(T, lenT + lenQ); +} + +void +fmpz_mod_poly_mulmod_preinv(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly1, + const fmpz_mod_poly_t poly2, const fmpz_mod_poly_t f, + const fmpz_mod_poly_t finv) +{ + slong len1, len2, lenf; + fmpz * fcoeffs; + + lenf = f->length; + len1 = poly1->length; + len2 = poly2->length; + + if (lenf == 0) + { + flint_printf("Exception (fmpz_mod_poly_mulmod_preinv). Divide by zero\n"); + abort(); + } + + if (lenf <= len1 || lenf <= len2) + { + flint_printf("Exception (fmpz_mod_poly_mulmod_preinv). Input larger than modulus.\n"); + abort(); + } + + if (lenf == 1 || len1 == 0 || len2 == 0) + { + fmpz_mod_poly_zero(res); + return; + } + + if (len1 + len2 - lenf > 0) + { + if (f == res) + { + fcoeffs = _fmpz_vec_init(lenf); + _fmpz_vec_set(fcoeffs, f->coeffs, lenf); + } + else + fcoeffs = f->coeffs; + + fmpz_mod_poly_fit_length(res, len1 + len2 - 1); + _fmpz_mod_poly_mulmod_preinv(res->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2, fcoeffs, lenf, + finv->coeffs, finv->length, &res->p); + if (f == res) + _fmpz_vec_clear(fcoeffs, lenf); + + _fmpz_mod_poly_set_length(res, lenf - 1); + _fmpz_mod_poly_normalise(res); + } + else + { + fmpz_mod_poly_mul(res, poly1, poly2); + } +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/neg.c b/external/flint-2.4.3/fmpz_mod_poly/neg.c new file mode 100644 index 0000000..e3b6058 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/neg.c @@ -0,0 +1,54 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpz_mod_poly.h" + +void _fmpz_mod_poly_neg(fmpz *res, const fmpz *poly, slong len, const fmpz_t p) +{ + slong i; + + for (i = 0; i < len; i++) + { + if (poly[i]) + fmpz_sub(res + i, p, poly + i); + else + fmpz_zero(res + i); + } +} + +void fmpz_mod_poly_neg(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly) +{ + const slong len = poly->length; + + fmpz_mod_poly_fit_length(res, len); + _fmpz_mod_poly_set_length(res, len); + + _fmpz_mod_poly_neg(res->coeffs, poly->coeffs, poly->length, &(poly->p)); +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/normalise.c b/external/flint-2.4.3/fmpz_mod_poly/normalise.c new file mode 100644 index 0000000..89dfcbd --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/normalise.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2008, 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" + +void _fmpz_mod_poly_normalise(fmpz_mod_poly_t poly) +{ + slong i; + + for (i = poly->length - 1; (i >= 0) && !poly->coeffs[i]; i--) ; + poly->length = i + 1; +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/pow.c b/external/flint-2.4.3/fmpz_mod_poly/pow.c new file mode 100644 index 0000000..f03c7b3 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/pow.c @@ -0,0 +1,162 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" +#include "fmpz_mod_poly.h" + +void _fmpz_mod_poly_pow(fmpz *res, const fmpz *poly, slong len, ulong e, + const fmpz_t p) +{ + ulong bit = ~((~UWORD(0)) >> 1); + slong rlen; + slong alloc = (slong) e * (len - 1) + 1; + fmpz *v = _fmpz_vec_init(alloc); + fmpz *R, *S, *T; + + /* + Set bits to the bitmask with a 1 one place lower than the msb of e + */ + + while ((bit & e) == UWORD(0)) + bit >>= 1; + + bit >>= 1; + + /* + Trial run without any polynomial arithmetic to determine the parity + of the number of swaps; then set R and S accordingly + */ + + { + unsigned int swaps = 0U; + ulong bit2 = bit; + if ((bit2 & e)) + swaps = ~swaps; + while (bit2 >>= 1) + if ((bit2 & e) == UWORD(0)) + swaps = ~swaps; + + if (swaps == 0U) + { + R = res; + S = v; + } + else + { + R = v; + S = res; + } + } + + /* + We unroll the first step of the loop, referring to {poly, len} + */ + + _fmpz_mod_poly_sqr(R, poly, len, p); + rlen = 2 * len - 1; + if ((bit & e)) + { + _fmpz_mod_poly_mul(S, R, rlen, poly, len, p); + rlen += len - 1; + T = R; + R = S; + S = T; + } + + while ((bit >>= 1)) + { + if ((bit & e)) + { + _fmpz_mod_poly_sqr(S, R, rlen, p); + rlen += rlen - 1; + _fmpz_mod_poly_mul(R, S, rlen, poly, len, p); + rlen += len - 1; + } + else + { + _fmpz_mod_poly_sqr(S, R, rlen, p); + rlen += rlen - 1; + T = R; + R = S; + S = T; + } + } + + _fmpz_vec_clear(v, alloc); +} + +void fmpz_mod_poly_pow(fmpz_mod_poly_t rop, const fmpz_mod_poly_t op, ulong e) +{ + const slong len = op->length; + slong rlen; + + if ((len < 2) || (e < UWORD(3))) + { + if (e == UWORD(0)) + fmpz_mod_poly_set_ui(rop, 1); + else if (len == 0) + fmpz_mod_poly_zero(rop); + else if (len == 1) + { + fmpz_mod_poly_fit_length(rop, 1); + fmpz_powm_ui(rop->coeffs, op->coeffs, e, &(rop->p)); + _fmpz_mod_poly_set_length(rop, 1); + _fmpz_mod_poly_normalise(rop); + } + else if (e == UWORD(1)) + fmpz_mod_poly_set(rop, op); + else /* e == UWORD(2) */ + fmpz_mod_poly_sqr(rop, op); + return; + } + + rlen = (slong) e * (len - 1) + 1; + + if (rop != op) + { + fmpz_mod_poly_fit_length(rop, rlen); + _fmpz_mod_poly_pow(rop->coeffs, op->coeffs, len, e, &(rop->p)); + _fmpz_mod_poly_set_length(rop, rlen); + } + else + { + fmpz *t = _fmpz_vec_init(rlen); + + _fmpz_mod_poly_pow(t, op->coeffs, len, e, &(rop->p)); + + _fmpz_vec_clear(rop->coeffs, rop->alloc); + rop->coeffs = t; + rop->alloc = rlen; + rop->length = rlen; + } + + _fmpz_mod_poly_normalise(rop); +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/pow_trunc.c b/external/flint-2.4.3/fmpz_mod_poly/pow_trunc.c new file mode 100644 index 0000000..158a022 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/pow_trunc.c @@ -0,0 +1,105 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 William Hart + Copyright (C) 2012 Lina Kulakova + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz_vec.h" +#include "fmpz_mod_poly.h" + +void +_fmpz_mod_poly_pow_trunc(fmpz * res, const fmpz * poly, + ulong e, slong trunc, const fmpz_t p) +{ + _fmpz_mod_poly_pow_trunc_binexp(res, poly, e, trunc, p); +} + +void +fmpz_mod_poly_pow_trunc(fmpz_mod_poly_t res, + const fmpz_mod_poly_t poly, ulong e, slong trunc) +{ + const slong len = poly->length; + fmpz * q; + int qcopy = 0; + + if (len < 2 || e < UWORD(3) || trunc == 0) + { + if (len == 0 || trunc == 0) + fmpz_mod_poly_zero(res); + else if (len == 1) + { + fmpz_mod_poly_fit_length(res, 1); + fmpz_powm_ui(res->coeffs, poly->coeffs, e, &res->p); + _fmpz_mod_poly_set_length(res, 1); + _fmpz_mod_poly_normalise(res); + } + else if (e == UWORD(0)) + { + fmpz_mod_poly_set_coeff_ui(res, 0, UWORD(1)); + _fmpz_mod_poly_set_length(res, 1); + _fmpz_mod_poly_normalise(res); + } + else if (e == UWORD(1)) + { + fmpz_mod_poly_set(res, poly); + fmpz_mod_poly_truncate(res, trunc); + } + else /* e == UWORD(2) */ + fmpz_mod_poly_mullow(res, poly, poly, trunc); + + return; + } + + if (poly->length < trunc) + { + q = _fmpz_vec_init(trunc); + _fmpz_vec_set(q, poly->coeffs, poly->length); + _fmpz_vec_zero(q + poly->length, trunc - poly->length); + qcopy = 1; + } else + q = poly->coeffs; + + if (res != poly || qcopy) + { + fmpz_mod_poly_fit_length(res, trunc); + _fmpz_mod_poly_pow_trunc(res->coeffs, q, e, trunc, &poly->p); + } + else + { + fmpz_mod_poly_t t; + fmpz_mod_poly_init2(t, &poly->p, trunc); + _fmpz_mod_poly_pow_trunc(t->coeffs, q, e, trunc, &poly->p); + fmpz_mod_poly_swap(res, t); + fmpz_mod_poly_clear(t); + } + + if (qcopy) + _fmpz_vec_clear(q, trunc); + + _fmpz_mod_poly_set_length(res, trunc); + _fmpz_mod_poly_normalise(res); +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/pow_trunc_binexp.c b/external/flint-2.4.3/fmpz_mod_poly/pow_trunc_binexp.c new file mode 100644 index 0000000..c8052ac --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/pow_trunc_binexp.c @@ -0,0 +1,174 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 William Hart + Copyright (C) 2012 Lina Kulakova + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz_vec.h" +#include "fmpz_mod_poly.h" + +void +_fmpz_mod_poly_pow_trunc_binexp(fmpz * res, const fmpz * poly, + ulong e, slong trunc, const fmpz_t p) +{ + ulong bit = ~((~UWORD(0)) >> 1); + fmpz * v = _fmpz_vec_init(trunc); + fmpz * R, * S, * T; + + /* + Set bits to the bitmask with a 1 one place lower than the msb of e + */ + + while ((bit & e) == UWORD(0)) + bit >>= 1; + + bit >>= 1; + + /* + Trial run without any polynomial arithmetic to determine the parity + of the number of swaps; then set R and S accordingly + */ + + { + unsigned int swaps = 0U; + ulong bit2 = bit; + if ((bit2 & e)) + swaps = ~swaps; + while (bit2 >>= 1) + if ((bit2 & e) == UWORD(0)) + swaps = ~swaps; + + if (swaps == 0U) + { + R = res; + S = v; + } + else + { + R = v; + S = res; + } + } + + /* + We unroll the first step of the loop, referring to {poly, len} + */ + + _fmpz_mod_poly_mullow(R, poly, trunc, poly, trunc, p, trunc); + if ((bit & e)) + { + _fmpz_mod_poly_mullow(S, R, trunc, poly, trunc, p, trunc); + T = R; + R = S; + S = T; + } + + while ((bit >>= 1)) + { + if ((bit & e)) + { + _fmpz_mod_poly_mullow(S, R, trunc, R, trunc, p, trunc); + _fmpz_mod_poly_mullow(R, S, trunc, poly, trunc, p, trunc); + } + else + { + _fmpz_mod_poly_mullow(S, R, trunc, R, trunc, p, trunc); + T = R; + R = S; + S = T; + } + } + + _fmpz_vec_clear(v, trunc); +} + +void +fmpz_mod_poly_pow_trunc_binexp(fmpz_mod_poly_t res, + const fmpz_mod_poly_t poly, ulong e, slong trunc) +{ + const slong len = poly->length; + fmpz * q; + int qcopy = 0; + + if (len < 2 || e < UWORD(3) || trunc == 0) + { + if (len == 0 || trunc == 0) + fmpz_mod_poly_zero(res); + else if (len == 1) + { + fmpz_mod_poly_fit_length(res, 1); + fmpz_powm_ui(res->coeffs, poly->coeffs, e, &res->p); + _fmpz_mod_poly_set_length(res, 1); + _fmpz_mod_poly_normalise(res); + } + else if (e == UWORD(0)) + { + fmpz_mod_poly_set_coeff_ui(res, 0, UWORD(1)); + _fmpz_mod_poly_set_length(res, 1); + _fmpz_mod_poly_normalise(res); + } + else if (e == UWORD(1)) + { + fmpz_mod_poly_set(res, poly); + fmpz_mod_poly_truncate(res, trunc); + } + else /* e == UWORD(2) */ + fmpz_mod_poly_mullow(res, poly, poly, trunc); + + return; + } + + if (poly->length < trunc) + { + q = _fmpz_vec_init(trunc); + _fmpz_vec_set(q, poly->coeffs, poly->length); + _fmpz_vec_zero(q + poly->length, trunc - poly->length); + qcopy = 1; + } else + q = poly->coeffs; + + if (res != poly || qcopy) + { + fmpz_mod_poly_fit_length(res, trunc); + _fmpz_mod_poly_pow_trunc_binexp(res->coeffs, q, e, trunc, &poly->p); + } + else + { + fmpz_mod_poly_t t; + fmpz_mod_poly_init2(t, &poly->p, trunc); + _fmpz_mod_poly_pow_trunc_binexp(t->coeffs, q, e, trunc, &poly->p); + fmpz_mod_poly_swap(res, t); + fmpz_mod_poly_clear(t); + } + + if (qcopy) + _fmpz_vec_clear(q, trunc); + + _fmpz_mod_poly_set_length(res, trunc); + _fmpz_mod_poly_normalise(res); +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/powmod_fmpz_binexp.c b/external/flint-2.4.3/fmpz_mod_poly/powmod_fmpz_binexp.c new file mode 100644 index 0000000..21b669d --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/powmod_fmpz_binexp.c @@ -0,0 +1,172 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 William Hart + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz_vec.h" +#include "fmpz_mod_poly.h" + +void +_fmpz_mod_poly_powmod_fmpz_binexp(fmpz * res, const fmpz * poly, + const fmpz_t e, const fmpz * f, + slong lenf, const fmpz_t p) +{ + fmpz * T, * Q; + fmpz_t invf; + slong lenT, lenQ; + slong i; + + if (lenf == 2) + { + fmpz_powm(res, poly, e, p); + return; + } + + lenT = 2 * lenf - 3; + lenQ = lenT - lenf + 1; + + T = _fmpz_vec_init(lenT + lenQ); + Q = T + lenT; + + fmpz_init(invf); + fmpz_invmod(invf, f + lenf - 1, p); + + _fmpz_vec_set(res, poly, lenf - 1); + + for (i = fmpz_sizeinbase(e, 2) - 2; i >= 0; i--) + { + _fmpz_mod_poly_sqr(T, res, lenf - 1, p); + _fmpz_mod_poly_divrem(Q, res, T, 2 * lenf - 3, f, lenf, invf, p); + + if (fmpz_tstbit(e, i)) + { + _fmpz_mod_poly_mul(T, res, lenf - 1, poly, lenf - 1, p); + _fmpz_mod_poly_divrem(Q, res, T, 2 * lenf - 3, f, lenf, invf, p); + } + } + + fmpz_clear(invf); + _fmpz_vec_clear(T, lenT + lenQ); +} + + +void +fmpz_mod_poly_powmod_fmpz_binexp(fmpz_mod_poly_t res, + const fmpz_mod_poly_t poly, const fmpz_t e, + const fmpz_mod_poly_t f) +{ + fmpz * q; + slong len = poly->length; + slong lenf = f->length; + slong trunc = lenf - 1; + int qcopy = 0; + + if (lenf == 0) + { + flint_printf("Exception (fmpz_mod_poly_powmod_fmpz_binexp). Divide by zero\n"); + abort(); + } + + if (fmpz_sgn(e) < 0) + { + flint_printf("Exception (fmpz_mod_poly_powmod_fmpz_binexp). negative exp not implemented\n"); + abort(); + } + + if (len >= lenf) + { + fmpz_mod_poly_t t, r; + fmpz_mod_poly_init(t, &res->p); + fmpz_mod_poly_init(r, &res->p); + fmpz_mod_poly_divrem(t, r, poly, f); + fmpz_mod_poly_powmod_fmpz_binexp(res, r, e, f); + fmpz_mod_poly_clear(t); + fmpz_mod_poly_clear(r); + return; + } + + if (fmpz_abs_fits_ui(e)) + { + ulong exp = fmpz_get_ui(e); + + if (exp <= 2) + { + if (exp == UWORD(0)) + { + fmpz_mod_poly_fit_length(res, 1); + fmpz_one(res->coeffs); + _fmpz_mod_poly_set_length(res, 1); + } + else if (exp == UWORD(1)) + { + fmpz_mod_poly_set(res, poly); + } + else + fmpz_mod_poly_mulmod(res, poly, poly, f); + return; + } + } + + if (lenf == 1 || len == 0) + { + fmpz_mod_poly_zero(res); + return; + } + + if (poly->length < trunc) + { + q = _fmpz_vec_init(trunc); + _fmpz_vec_set(q, poly->coeffs, len); + _fmpz_vec_zero(q + len, trunc - len); + qcopy = 1; + } else + q = poly->coeffs; + + if ((res == poly && !qcopy) || (res == f)) + { + fmpz_mod_poly_t t; + fmpz_mod_poly_init2(t, &poly->p, 2 * lenf - 3); + _fmpz_mod_poly_powmod_fmpz_binexp(t->coeffs, + q, e, f->coeffs, lenf, &poly->p); + fmpz_mod_poly_swap(res, t); + fmpz_mod_poly_clear(t); + } + else + { + fmpz_mod_poly_fit_length(res, 2 * lenf - 3); + _fmpz_mod_poly_powmod_fmpz_binexp(res->coeffs, + q, e, f->coeffs, lenf, &poly->p); + } + + if (qcopy) + _fmpz_vec_clear(q, trunc); + + _fmpz_mod_poly_set_length(res, trunc); + _fmpz_mod_poly_normalise(res); +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/powmod_fmpz_binexp_preinv.c b/external/flint-2.4.3/fmpz_mod_poly/powmod_fmpz_binexp_preinv.c new file mode 100644 index 0000000..557c4ee --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/powmod_fmpz_binexp_preinv.c @@ -0,0 +1,182 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 William Hart + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Martin Lee + +******************************************************************************/ + +#undef ulong +#define ulong ulongxx/* interferes with system includes */ + +#include + +#undef ulong + +#include + +#define ulong mp_limb_t + +#include "flint.h" +#include "fmpz_vec.h" +#include "fmpz_mod_poly.h" + +void +_fmpz_mod_poly_powmod_fmpz_binexp_preinv(fmpz * res, const fmpz * poly, + const fmpz_t e, const fmpz * f, + slong lenf, const fmpz* finv, slong lenfinv, + const fmpz_t p) +{ + fmpz * T, * Q; + slong lenT, lenQ; + slong i; + + if (lenf == 2) + { + fmpz_powm(res, poly, e, p); + return; + } + + lenT = 2 * lenf - 3; + lenQ = lenT - lenf + 1; + + T = _fmpz_vec_init(lenT + lenQ); + Q = T + lenT; + + _fmpz_vec_set(res, poly, lenf - 1); + + for (i = fmpz_sizeinbase(e, 2) - 2; i >= 0; i--) + { + _fmpz_mod_poly_sqr(T, res, lenf - 1, p); + _fmpz_mod_poly_divrem_newton_n_preinv(Q, res, T, 2 * lenf - 3, f, lenf, + finv, lenfinv, p); + + if (fmpz_tstbit(e, i)) + { + _fmpz_mod_poly_mul(T, res, lenf - 1, poly, lenf - 1, p); + _fmpz_mod_poly_divrem_newton_n_preinv(Q, res, T, 2 * lenf - 3, f, + lenf, finv, lenfinv, p); + } + } + + _fmpz_vec_clear(T, lenT + lenQ); +} + + +void +fmpz_mod_poly_powmod_fmpz_binexp_preinv(fmpz_mod_poly_t res, + const fmpz_mod_poly_t poly, const fmpz_t e, + const fmpz_mod_poly_t f, const fmpz_mod_poly_t finv) +{ + fmpz * q; + slong len = poly->length; + slong lenf = f->length; + slong trunc = lenf - 1; + int qcopy = 0; + + if (lenf == 0) + { + flint_printf("Exception (fmpz_mod_poly_powmod_fmpz_binexp_preinv)." + "Divide by zero.\n"); + abort(); + } + + if (fmpz_sgn(e) < 0) + { + flint_printf("Exception (fmpz_mod_poly_powmod_fmpz_binexp_preinv)." + "Negative exp not implemented\n"); + abort(); + } + + if (len >= lenf) + { + fmpz_mod_poly_t t, r; + fmpz_mod_poly_init(t, &res->p); + fmpz_mod_poly_init(r, &res->p); + fmpz_mod_poly_divrem(t, r, poly, f); + fmpz_mod_poly_powmod_fmpz_binexp_preinv(res, r, e, f, finv); + fmpz_mod_poly_clear(t); + fmpz_mod_poly_clear(r); + return; + } + + if (fmpz_abs_fits_ui(e)) + { + ulong exp = fmpz_get_ui(e); + + if (exp <= 2) + { + if (exp == UWORD (0)) + { + fmpz_mod_poly_fit_length(res, 1); + fmpz_one(res->coeffs); + _fmpz_mod_poly_set_length(res, 1); + } + else if (exp == UWORD (1)) + { + fmpz_mod_poly_set(res, poly); + } + else + fmpz_mod_poly_mulmod_preinv(res, poly, poly, f, finv); + return; + } + } + + if (lenf == 1 || len == 0) + { + fmpz_mod_poly_zero(res); + return; + } + + if (poly->length < trunc) + { + q = _fmpz_vec_init(trunc); + _fmpz_vec_set(q, poly->coeffs, len); + _fmpz_vec_zero(q + len, trunc - len); + qcopy = 1; + } else + q = poly->coeffs; + + if ((res == poly && !qcopy) || (res == f) || (res == finv)) + { + fmpz_mod_poly_t t; + fmpz_mod_poly_init2(t, &poly->p, 2 * lenf - 3); + _fmpz_mod_poly_powmod_fmpz_binexp_preinv(t->coeffs, + q, e, f->coeffs, lenf, finv->coeffs, finv->length, &poly->p); + fmpz_mod_poly_swap(res, t); + fmpz_mod_poly_clear(t); + } + else + { + fmpz_mod_poly_fit_length(res, 2 * lenf - 3); + _fmpz_mod_poly_powmod_fmpz_binexp_preinv(res->coeffs, + q, e, f->coeffs, lenf, finv->coeffs, finv->length, &poly->p); + } + + if (qcopy) + _fmpz_vec_clear(q, trunc); + + _fmpz_mod_poly_set_length(res, trunc); + _fmpz_mod_poly_normalise(res); +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/powmod_ui_binexp.c b/external/flint-2.4.3/fmpz_mod_poly/powmod_ui_binexp.c new file mode 100644 index 0000000..bd4becb --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/powmod_ui_binexp.c @@ -0,0 +1,161 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 William Hart + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz_vec.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +void +_fmpz_mod_poly_powmod_ui_binexp(fmpz * res, const fmpz * poly, + ulong e, const fmpz * f, slong lenf, const fmpz_t p) +{ + fmpz * T, * Q; + fmpz_t invf; + slong lenT, lenQ; + int i; + + if (lenf == 2) + { + fmpz_powm_ui(res, poly, e, p); + return; + } + + lenT = 2 * lenf - 3; + lenQ = FLINT_MAX(lenT - lenf + 1, 1); + + T = _fmpz_vec_init(lenT + lenQ); + Q = T + lenT; + + fmpz_init(invf); + fmpz_invmod(invf, f + lenf - 1, p); + + _fmpz_vec_set(res, poly, lenf - 1); + + for (i = ((int) FLINT_BIT_COUNT(e) - 2); i >= 0; i--) + { + _fmpz_mod_poly_sqr(T, res, lenf - 1, p); + _fmpz_mod_poly_divrem(Q, res, T, 2 * lenf - 3, f, lenf, invf, p); + + if (e & (UWORD(1) << i)) + { + _fmpz_mod_poly_mul(T, res, lenf - 1, poly, lenf - 1, p); + _fmpz_mod_poly_divrem(Q, res, T, 2 * lenf - 3, f, lenf, invf, p); + } + } + + fmpz_clear(invf); + _fmpz_vec_clear(T, lenT + lenQ); +} + + +void +fmpz_mod_poly_powmod_ui_binexp(fmpz_mod_poly_t res, + const fmpz_mod_poly_t poly, ulong e, + const fmpz_mod_poly_t f) +{ + fmpz * q; + slong len = poly->length; + slong lenf = f->length; + slong trunc = lenf - 1; + int qcopy = 0; + + if (lenf == 0) + { + flint_printf("Exception (fmpz_mod_poly_powmod). Divide by zero\n"); + abort(); + } + + if (len >= lenf) + { + fmpz_mod_poly_t t, r; + fmpz_mod_poly_init(t, &res->p); + fmpz_mod_poly_init(r, &res->p); + fmpz_mod_poly_divrem(t, r, poly, f); + fmpz_mod_poly_powmod_ui_binexp(res, r, e, f); + fmpz_mod_poly_clear(t); + fmpz_mod_poly_clear(r); + return; + } + + if (e <= 2) + { + if (e == UWORD(0)) + { + fmpz_mod_poly_fit_length(res, 1); + fmpz_one(res->coeffs); + _fmpz_mod_poly_set_length(res, 1); + } + else if (e == UWORD(1)) + { + fmpz_mod_poly_set(res, poly); + } + else + fmpz_mod_poly_mulmod(res, poly, poly, f); + return; + } + + if (lenf == 1 || len == 0) + { + fmpz_mod_poly_zero(res); + return; + } + + if (len < trunc) + { + q = _fmpz_vec_init(trunc); + _fmpz_vec_set(q, poly->coeffs, len); + _fmpz_vec_zero(q + len, trunc - len); + qcopy = 1; + } else + q = poly->coeffs; + + if ((res == poly && !qcopy) || (res == f)) + { + fmpz_mod_poly_t t; + fmpz_mod_poly_init2(t, &poly->p, 2 * lenf - 3); + _fmpz_mod_poly_powmod_ui_binexp(t->coeffs, + q, e, f->coeffs, lenf, &poly->p); + fmpz_mod_poly_swap(res, t); + fmpz_mod_poly_clear(t); + } + else + { + fmpz_mod_poly_fit_length(res, 2 * lenf - 3); + _fmpz_mod_poly_powmod_ui_binexp(res->coeffs, + q, e, f->coeffs, lenf, &poly->p); + } + + if (qcopy) + _fmpz_vec_clear(q, trunc); + + _fmpz_mod_poly_set_length(res, trunc); + _fmpz_mod_poly_normalise(res); +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/powmod_ui_binexp_preinv.c b/external/flint-2.4.3/fmpz_mod_poly/powmod_ui_binexp_preinv.c new file mode 100644 index 0000000..a2810d8 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/powmod_ui_binexp_preinv.c @@ -0,0 +1,170 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 William Hart + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Martin Lee + +******************************************************************************/ + +#undef ulong +#define ulong ulongxx/* interferes with system includes */ + +#include + +#undef ulong + +#include + +#define ulong mp_limb_t + +#include "flint.h" +#include "fmpz_vec.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +void +_fmpz_mod_poly_powmod_ui_binexp_preinv(fmpz * res, const fmpz * poly, + ulong e, const fmpz * f, slong lenf, + const fmpz * finv, slong lenfinv, const fmpz_t p) +{ + fmpz * T, * Q; + slong lenT, lenQ; + int i; + + if (lenf == 2) + { + fmpz_powm_ui(res, poly, e, p); + return; + } + + lenT = 2 * lenf - 3; + lenQ = FLINT_MAX(lenT - lenf + 1, 1); + + T = _fmpz_vec_init(lenT + lenQ); + Q = T + lenT; + + _fmpz_vec_set(res, poly, lenf - 1); + + for (i = ((int) FLINT_BIT_COUNT(e) - 2); i >= 0; i--) + { + _fmpz_mod_poly_sqr(T, res, lenf - 1, p); + _fmpz_mod_poly_divrem_newton_n_preinv(Q, res, T, 2 * lenf - 3, f, lenf, + finv, lenfinv, p); + + if (e & (UWORD (1) << i)) + { + _fmpz_mod_poly_mul(T, res, lenf - 1, poly, lenf - 1, p); + _fmpz_mod_poly_divrem_newton_n_preinv(Q, res, T, 2 * lenf - 3, f, + lenf, finv, lenfinv, p); + } + } + + _fmpz_vec_clear(T, lenT + lenQ); +} + + +void +fmpz_mod_poly_powmod_ui_binexp_preinv(fmpz_mod_poly_t res, + const fmpz_mod_poly_t poly, ulong e, + const fmpz_mod_poly_t f, const fmpz_mod_poly_t finv) +{ + fmpz * q; + slong len = poly->length; + slong lenf = f->length; + slong trunc = lenf - 1; + int qcopy = 0; + + if (lenf == 0) + { + flint_printf("Exception (fmpz_mod_poly_powmod_ui_binexp_preinv)." + "Divide by zero\n"); + abort(); + } + + if (len >= lenf) + { + fmpz_mod_poly_t t, r; + fmpz_mod_poly_init(t, &res->p); + fmpz_mod_poly_init(r, &res->p); + fmpz_mod_poly_divrem(t, r, poly, f); + fmpz_mod_poly_powmod_ui_binexp_preinv(res, r, e, f, finv); + fmpz_mod_poly_clear(t); + fmpz_mod_poly_clear(r); + return; + } + + if (e <= 2) + { + if (e == UWORD (0)) + { + fmpz_mod_poly_fit_length(res, 1); + fmpz_one(res->coeffs); + _fmpz_mod_poly_set_length(res, 1); + } + else if (e == UWORD (1)) + { + fmpz_mod_poly_set(res, poly); + } + else + fmpz_mod_poly_mulmod_preinv(res, poly, poly, f, finv); + return; + } + + if (lenf == 1 || len == 0) + { + fmpz_mod_poly_zero(res); + return; + } + + if (len < trunc) + { + q = _fmpz_vec_init(trunc); + _fmpz_vec_set(q, poly->coeffs, len); + _fmpz_vec_zero(q + len, trunc - len); + qcopy = 1; + } else + q = poly->coeffs; + + if ((res == poly && !qcopy) || (res == f) || (res == finv)) + { + fmpz_mod_poly_t t; + fmpz_mod_poly_init2(t, &poly->p, 2 * lenf - 3); + _fmpz_mod_poly_powmod_ui_binexp_preinv(t->coeffs, + q, e, f->coeffs, lenf, finv->coeffs, finv->length, &poly->p); + fmpz_mod_poly_swap(res, t); + fmpz_mod_poly_clear(t); + } + else + { + fmpz_mod_poly_fit_length(res, 2 * lenf - 3); + _fmpz_mod_poly_powmod_ui_binexp_preinv(res->coeffs, + q, e, f->coeffs, lenf, finv->coeffs, finv->length, &poly->p); + } + + if (qcopy) + _fmpz_vec_clear(q, trunc); + + _fmpz_mod_poly_set_length(res, trunc); + _fmpz_mod_poly_normalise(res); +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/powmod_x_fmpz_preinv.c b/external/flint-2.4.3/fmpz_mod_poly/powmod_x_fmpz_preinv.c new file mode 100644 index 0000000..7128bfb --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/powmod_x_fmpz_preinv.c @@ -0,0 +1,208 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 William Hart + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Martin Lee + +******************************************************************************/ + +#undef ulong +#define ulong ulongxx/* interferes with system includes */ + +#include + +#undef ulong + +#include + +#define ulong mp_limb_t + +#include "flint.h" +#include "fmpz_vec.h" +#include "fmpz_mod_poly.h" +#include "long_extras.h" + +void +_fmpz_mod_poly_powmod_x_fmpz_preinv(fmpz * res, const fmpz_t e, const fmpz * f, + slong lenf, const fmpz* finv, slong lenfinv, + const fmpz_t p) +{ + fmpz * T, * Q; + slong lenT, lenQ; + slong i, window, l, c; + + lenT = 2 * lenf - 3; + lenQ = lenT - lenf + 1; + + T = _fmpz_vec_init(lenT + lenQ); + Q = T + lenT; + + fmpz_one (res); + l = z_sizeinbase (lenf - 1, 2) - 2; + window = WORD(0); + window = (WORD(1) << l); + c = l; + i = fmpz_sizeinbase(e, 2) - 2; + if (i <= l) + { + window = WORD(0); + window = (WORD(1) << i); + c = i; + l = i; + } + + if (c == 0) + { + _fmpz_mod_poly_shift_left(T, res, lenf - 1, window); + _fmpz_mod_poly_divrem_newton_n_preinv(Q, res, T, lenf - 1 + window, f, + lenf, finv, lenfinv, p); + c = l + 1; + window = WORD(0); + } + + for (; i >= 0; i--) + { + _fmpz_mod_poly_sqr(T, res, lenf - 1, p); + _fmpz_mod_poly_divrem_newton_n_preinv(Q, res, T, 2 * lenf - 3, f, lenf, + finv, lenfinv, p); + + c--; + if (fmpz_tstbit(e, i)) + { + if (window == WORD(0) && i <= l - 1) + c = i; + if ( c >= 0) + window = window | (WORD(1) << c); + } + else if (window == WORD(0)) + c = l + 1; + if (c == 0) + { + _fmpz_mod_poly_shift_left(T, res, lenf - 1, window); + + _fmpz_mod_poly_divrem_newton_n_preinv(Q, res, T, lenf - 1 + window, + f, lenf, finv, lenfinv, p); + c = l + 1; + window = WORD(0); + } + } + + _fmpz_vec_clear(T, lenT + lenQ); +} + + +void +fmpz_mod_poly_powmod_x_fmpz_preinv(fmpz_mod_poly_t res, const fmpz_t e, + const fmpz_mod_poly_t f, const fmpz_mod_poly_t finv) +{ + slong lenf = f->length; + slong trunc = lenf - 1; + fmpz_mod_poly_t tmp; + + if (lenf == 0) + { + flint_printf("Exception (fmpz_mod_poly_powmod_x_fmpz_preinv)." + "Divide by zero\n"); + abort(); + } + + if (fmpz_sgn(e) < 0) + { + flint_printf("Exception (fmpz_mod_poly_powmod_x_fmpz_preinv)." + "Negative exp not implemented\n"); + abort(); + } + + if (lenf == 1) + { + fmpz_mod_poly_zero(res); + return; + } + + if (lenf == 2) + { + fmpz_mod_poly_t r, poly; + fmpz_mod_poly_init(tmp, &res->p); + fmpz_mod_poly_init(r, &res->p); + fmpz_mod_poly_init2(poly, &res->p, 2); + fmpz_mod_poly_set_coeff_ui (poly, 1, 1); + fmpz_mod_poly_divrem(tmp, r, poly, f); + fmpz_mod_poly_powmod_fmpz_binexp_preinv(res, r, e, f, finv); + fmpz_mod_poly_clear(tmp); + fmpz_mod_poly_clear(r); + fmpz_mod_poly_clear(poly); + return; + } + + if (fmpz_abs_fits_ui(e)) + { + ulong exp = fmpz_get_ui(e); + + if (exp <= 2) + { + if (exp == UWORD(0)) + { + fmpz_mod_poly_fit_length(res, 1); + fmpz_one(res->coeffs); + _fmpz_mod_poly_set_length(res, 1); + } + else if (exp == UWORD(1)) + { + fmpz_mod_poly_t r; + fmpz_mod_poly_init2(r, &f->p, 2); + fmpz_mod_poly_set_coeff_ui(r, 1, 1); + fmpz_mod_poly_init(tmp, &f->p); + fmpz_mod_poly_divrem(tmp, res, r, f); + fmpz_mod_poly_clear(tmp); + fmpz_mod_poly_clear(r); + } + else + { + fmpz_mod_poly_init2(tmp, &f->p, 3); + fmpz_mod_poly_set_coeff_ui(tmp, 1, 1); + fmpz_mod_poly_mulmod(res, tmp, tmp, f); + fmpz_mod_poly_clear(tmp); + } + return; + } + } + + if ((res == f) || (res == finv)) + { + fmpz_mod_poly_init2(tmp, &f->p, trunc); + _fmpz_mod_poly_powmod_x_fmpz_preinv(tmp->coeffs, e, f->coeffs, lenf, + finv->coeffs, finv->length, &f->p); + fmpz_mod_poly_swap(res, tmp); + fmpz_mod_poly_clear(tmp); + } + else + { + fmpz_mod_poly_fit_length(res, trunc); + _fmpz_mod_poly_powmod_x_fmpz_preinv(res->coeffs, e, f->coeffs, lenf, + finv->coeffs, finv->length, &f->p); + } + + _fmpz_mod_poly_set_length(res, trunc); + _fmpz_mod_poly_normalise(res); +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/profile/p-invert.c b/external/flint-2.4.3/fmpz_mod_poly/profile/p-invert.c new file mode 100644 index 0000000..d2e1284 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/profile/p-invert.c @@ -0,0 +1,93 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 William Hart + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" +#include "profiler.h" + +int +main(void) +{ + slong len, iter; + fmpz_mod_poly_t f, g, q, r; + fmpz_t N, c, one; + timeit_t t; + char N_str[201] = "29799904256775982671863388319999573561548825027149399972531599612392671227006866151136667908641695103422986028076864929902803267437351318167549013218980573566942647077444419419003164546362008247462049"; + + FLINT_TEST_INIT(state); + + + len = 36865; + + fmpz_init(N); + fmpz_init(c); + fmpz_init(one); + + fmpz_set_str(N, N_str, 10); + fmpz_set_ui(one, 1); + + fmpz_mod_poly_init2(f, N, len); + fmpz_mod_poly_init2(g, N, 2*len - 1); + fmpz_mod_poly_init2(q, N, len); + fmpz_mod_poly_init2(r, N, len - 1); + + /* + Construct random polynomial f + */ + + fmpz_mod_poly_randtest(f, state, len); + + fmpz_mod_poly_set_coeff_fmpz(g, 2*len - 2, one); + + /* + Time inversion + */ + + timeit_start(t); + + for (iter = 0; iter < 10; iter++) + fmpz_mod_poly_inv_series_newton(q, f, len); + + timeit_stop(t); + + flint_printf("len = %wd, time = %wdms\n", len, ((slong) t->cpu)/10); + + fmpz_mod_poly_clear(f); + fmpz_mod_poly_clear(g); + fmpz_mod_poly_clear(q); + fmpz_mod_poly_clear(r); + + fmpz_clear(N); + fmpz_clear(c); + fmpz_clear(one); + + flint_randclear(state); +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/profile/p-mul.c b/external/flint-2.4.3/fmpz_mod_poly/profile/p-mul.c new file mode 100644 index 0000000..f27e802 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/profile/p-mul.c @@ -0,0 +1,85 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 William Hart + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" +#include "profiler.h" + +int +main(void) +{ + slong len, iter; + fmpz_mod_poly_t f, g, r; + fmpz_t N; + timeit_t t; + char N_str[201] = "29799904256775982671863388319999573561548825027149399972531599612392671227006866151136667908641695103422986028076864929902803267437351318167549013218980573566942647077444419419003164546362008247462049"; + + FLINT_TEST_INIT(state); + + + len = 36865; + + fmpz_init(N); + + fmpz_set_str(N, N_str, 10); + + fmpz_mod_poly_init2(f, N, len); + fmpz_mod_poly_init2(g, N, len); + fmpz_mod_poly_init2(r, N, 2*len - 1); + + /* + Construct random polynomials f, g + */ + + fmpz_mod_poly_randtest(f, state, len); + fmpz_mod_poly_randtest(g, state, len); + + /* + Time multiplication + */ + + timeit_start(t); + + for (iter = 0; iter < 10; iter++) + fmpz_mod_poly_mul(r, f, g); + + timeit_stop(t); + + flint_printf("len = %wd, time = %wdms\n", len, ((slong) t->cpu)/10); + + fmpz_mod_poly_clear(f); + fmpz_mod_poly_clear(g); + fmpz_mod_poly_clear(r); + + fmpz_clear(N); + + flint_randclear(state); +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/profile/p-tree.c b/external/flint-2.4.3/fmpz_mod_poly/profile/p-tree.c new file mode 100644 index 0000000..07cc68a --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/profile/p-tree.c @@ -0,0 +1,86 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 William Hart + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" +#include "profiler.h" + +int +main(void) +{ + slong len, iter, i; + fmpz_mod_poly_t f; + fmpz * roots; + fmpz_poly_struct ** tree; + fmpz_t N; + timeit_t t; + char N_str[201] = "29799904256775982671863388319999573561548825027149399972531599612392671227006866151136667908641695103422986028076864929902803267437351318167549013218980573566942647077444419419003164546362008247462049"; + + FLINT_TEST_INIT(state); + + + len = 36865; + + fmpz_init(N); + fmpz_set_str(N, N_str, 10); + + roots = _fmpz_vec_init(len); + + for (i = 0; i < len; i++) + fmpz_randm(roots + i, state, N); + + fmpz_mod_poly_init(f, N); + + /* + Time tree + */ + + timeit_start(t); + + for (iter = 0; iter < 10; iter++) + { + tree = _fmpz_mod_poly_tree_alloc(len); + _fmpz_mod_poly_tree_build(tree, roots, len, N); + _fmpz_mod_poly_tree_free(tree, len); + } + + timeit_stop(t); + + flint_printf("len = %wd, time = %wdms\n", len, ((slong) t->cpu)/10); + + fmpz_mod_poly_clear(f); + + _fmpz_vec_clear(roots, len); + + fmpz_clear(N); + + flint_randclear(state); +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/radix.c b/external/flint-2.4.3/fmpz_mod_poly/radix.c new file mode 100644 index 0000000..1ff1bc3 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/radix.c @@ -0,0 +1,235 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpz_mod_poly.h" + +void _fmpz_mod_poly_radix_init(fmpz **Rpow, fmpz **Rinv, + const fmpz *R, slong lenR, slong k, + const fmpz_t invL, const fmpz_t p) +{ + const slong degR = lenR - 1; + slong i; + fmpz_t invLP; + fmpz *W; + + fmpz_init_set(invLP, invL); + W = flint_malloc((WORD(1) << (k - 1)) * degR * sizeof(fmpz)); + + _fmpz_vec_set(Rpow[0], R, lenR); + for (i = 1; i < k; i++) + { + _fmpz_mod_poly_sqr(Rpow[i], Rpow[i - 1], degR * (WORD(1) << (i - 1)) + 1, p); + } + + for (i = 0; i < k; i++) + { + const slong lenQ = (WORD(1) << i) * degR; + slong j; + + /* W := rev{Rpow[i], lenQ} */ + for (j = 0; j < lenQ; j++) + { + W[j] = Rpow[i][lenQ - j]; + } + + _fmpz_mod_poly_inv_series_newton(Rinv[i], W, lenQ, invLP, p); + + /* invLP := inv{lead{R^{2^i}}} */ + if (i != k - 1) + { + fmpz_mul(invLP, invLP, invLP); + fmpz_mod(invLP, invLP, p); + } + } + + fmpz_clear(invLP); + flint_free(W); +} + +void fmpz_mod_poly_radix_init(fmpz_mod_poly_radix_t D, + const fmpz_mod_poly_t R, slong degF) +{ + const slong degR = R->length - 1; + + if (degF < degR) + { + D->k = 0; + D->degR = degR; + } + else + { + const slong N = degF / degR; + const slong k = FLINT_BIT_COUNT(N); /* k := ceil{log{N+1}} */ + const slong lenV = degR * ((WORD(1) << k) - 1) + k; + const slong lenW = degR * ((WORD(1) << k) - 1); + + slong i; + + D->V = _fmpz_vec_init(lenV + lenW); + D->W = D->V + lenV; + + D->Rpow = flint_malloc(k * sizeof(fmpz *)); + D->Rinv = flint_malloc(k * sizeof(fmpz *)); + + for (i = 0; i < k; i++) + { + D->Rpow[i] = D->V + (degR * ((WORD(1) << i) - 1) + i); + D->Rinv[i] = D->W + (degR * ((WORD(1) << i) - 1)); + } + + fmpz_init(&(D->invL)); + fmpz_invmod(&(D->invL), R->coeffs + degR, &(R->p)); + + _fmpz_mod_poly_radix_init(D->Rpow, D->Rinv, R->coeffs, degR + 1, + k, &(D->invL), &(R->p)); + + D->k = k; + D->degR = degR; + } +} + +void fmpz_mod_poly_radix_clear(fmpz_mod_poly_radix_t D) +{ + if (D->k) + { + const slong degR = D->degR; + const slong k = D->k; + const slong lenV = degR * ((WORD(1) << k) - 1) + k; + const slong lenW = degR * ((WORD(1) << k) - 1); + + _fmpz_vec_clear(D->V, lenV + lenW); + flint_free(D->Rpow); + flint_free(D->Rinv); + fmpz_clear(&(D->invL)); + } +} + +void _fmpz_mod_poly_radix(fmpz **B, const fmpz *F, fmpz **Rpow, fmpz **Rinv, + slong degR, slong k, slong i, fmpz *W, const fmpz_t p) +{ + if (i == -1) + { + _fmpz_vec_set(B[k], F, degR); + } + else + { + const slong lenQ = (WORD(1) << i) * degR; + + fmpz *Frev = W; + fmpz *Q = W + lenQ; + fmpz *S = W; + + _fmpz_poly_reverse(Frev, F + lenQ, lenQ, lenQ); + _fmpz_mod_poly_mullow(Q, Frev, lenQ, Rinv[i], lenQ, p, lenQ); + _fmpz_poly_reverse(Q, Q, lenQ, lenQ); + + _fmpz_mod_poly_radix(B, Q, Rpow, Rinv, degR, k + (WORD(1) << i), i-1, W, p); + + _fmpz_mod_poly_mullow(S, Rpow[i], lenQ, Q, lenQ, p, lenQ); + _fmpz_mod_poly_sub(S, F, lenQ, S, lenQ, p); + + _fmpz_mod_poly_radix(B, S, Rpow, Rinv, degR, k, i-1, W + lenQ, p); + } +} + +void fmpz_mod_poly_radix(fmpz_mod_poly_struct **B, + const fmpz_mod_poly_t F, + const fmpz_mod_poly_radix_t D) +{ + const slong lenF = F->length; + const slong degF = F->length - 1; + const slong degR = D->degR; + const slong N = degF / degR; + + if (N == 0) + { + fmpz_mod_poly_set(B[0], F); + } + else + { + const slong k = FLINT_BIT_COUNT(N); /* k := ceil{log{N+1}} */ + const slong lenG = (WORD(1) << k) * degR; /* Padded size */ + const slong t = (lenG - 1) / degR - N; /* Extra {degR}-blocks */ + + fmpz *G; /* Padded copy of F */ + fmpz *T; /* Additional B[i] */ + fmpz **C; /* Enlarged version of B */ + fmpz *W; /* Temporary space */ + + slong i; + + if (lenF < lenG) + { + G = flint_malloc(lenG * sizeof(fmpz)); + for (i = 0; i < lenF; i++) + G[i] = F->coeffs[i]; + flint_mpn_zero((mp_ptr) G + lenF, lenG - lenF); + + T = t ? _fmpz_vec_init(t * degR) : NULL; + } + else /* lenF == lenG */ + { + G = F->coeffs; + T = NULL; + } + + C = flint_malloc((N + 1 + t) * sizeof(fmpz *)); + for (i = 0; i <= N; i++) + { + fmpz_mod_poly_fit_length(B[i], degR); + C[i] = B[i]->coeffs; + } + for (i = 0; i < t; i++) + { + C[N + 1 + i] = T + i * degR; + } + + W = _fmpz_vec_init(lenG); + + _fmpz_mod_poly_radix(C, G, D->Rpow, D->Rinv, degR, 0, k-1, W, &(F->p)); + + _fmpz_vec_clear(W, lenG); + + for (i = 0; i <= N; i++) + { + _fmpz_mod_poly_set_length(B[i], degR); + _fmpz_mod_poly_normalise(B[i]); + } + flint_free(C); + if (lenF < lenG) + { + flint_free(G); + } + if (t) + { + _fmpz_vec_clear(T, t * degR); + } + } +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/randtest.c b/external/flint-2.4.3/fmpz_mod_poly/randtest.c new file mode 100644 index 0000000..922e7a5 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/randtest.c @@ -0,0 +1,198 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2009 William Hart + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" + +void +fmpz_mod_poly_randtest(fmpz_mod_poly_t f, flint_rand_t state, slong len) +{ + slong i; + + fmpz_mod_poly_fit_length(f, len); + + for (i = 0; i < len; i++) + fmpz_randm(f->coeffs + i, state, &(f->p)); + + _fmpz_mod_poly_set_length(f, len); + _fmpz_mod_poly_normalise(f); +} + +void +fmpz_mod_poly_randtest_monic(fmpz_mod_poly_t f, flint_rand_t state, slong len) +{ + slong i; + + fmpz_mod_poly_fit_length(f, len); + + for (i = 0; i < len - 1; i++) + fmpz_randm(f->coeffs + i, state, &(f->p)); + + fmpz_one(f->coeffs + len - 1); + + _fmpz_mod_poly_set_length(f, len); +} + +void +fmpz_mod_poly_randtest_irreducible(fmpz_mod_poly_t f, + flint_rand_t state, slong len) +{ + if (len == 0) + { + flint_printf("Exception (fmpz_mod_poly_randtest_irreducible). len == 0.\n"); + abort(); + } + + fmpz_mod_poly_randtest(f, state, len); + while (fmpz_mod_poly_is_zero(f) || !fmpz_mod_poly_is_irreducible(f)) + fmpz_mod_poly_randtest(f, state, len); +} + +void +fmpz_mod_poly_randtest_monic_irreducible(fmpz_mod_poly_t f, + flint_rand_t state, slong len) +{ + if (len == 0) + { + flint_printf("Exception (fmpz_mod_poly_randtest_monic_irreducible). len == 0.\n"); + abort(); + } + + fmpz_mod_poly_randtest_monic(f, state, len); + while (fmpz_mod_poly_is_zero(f) || !fmpz_mod_poly_is_irreducible(f)) + fmpz_mod_poly_randtest_monic(f, state, len); +} + +void +fmpz_mod_poly_randtest_not_zero(fmpz_mod_poly_t f, + flint_rand_t state, slong len) +{ + if (len == 0) + { + flint_printf("Exception (fmpz_mod_poly_randtest_not_zero). len == 0.\n"); + abort(); + } + + fmpz_mod_poly_randtest(f, state, len); + while (fmpz_mod_poly_is_zero(f)) + fmpz_mod_poly_randtest(f, state, len); +} + +void +fmpz_mod_poly_randtest_trinomial(fmpz_mod_poly_t poly, flint_rand_t state, slong len) +{ + ulong k; + fmpz_mod_poly_fit_length(poly, len); + _fmpz_vec_zero(poly->coeffs, len); + fmpz_randm(poly->coeffs, state, &(poly->p)); + k = (n_randtest(state) % (len - 2)) + 1; + fmpz_randm(poly->coeffs + k, state, &(poly->p)); + fmpz_one(poly->coeffs + len - 1); + _fmpz_mod_poly_set_length(poly, len); +} + +void +fmpz_mod_poly_randtest_pentomial(fmpz_mod_poly_t poly, flint_rand_t state, slong len) +{ + fmpz_mod_poly_fit_length(poly, len); + _fmpz_vec_zero(poly->coeffs, len); + fmpz_randm(poly->coeffs, state, &(poly->p)); + fmpz_randm(poly->coeffs + 1, state, &(poly->p)); + fmpz_randm(poly->coeffs + 2, state, &(poly->p)); + fmpz_randm(poly->coeffs + 3, state, &(poly->p)); + fmpz_one(poly->coeffs + len - 1); + _fmpz_mod_poly_set_length(poly, len); +} + +int +fmpz_mod_poly_randtest_trinomial_irreducible(fmpz_mod_poly_t poly, flint_rand_t state, + slong len, slong max_attempts) +{ + slong i = 0; + + while (max_attempts == 0 || i < max_attempts) + { + fmpz_mod_poly_randtest_trinomial(poly, state, len); + if (!fmpz_mod_poly_is_zero(poly) && fmpz_mod_poly_is_irreducible(poly)) + { + return 1; + } + i++; + + } + return 0; +} + +int +fmpz_mod_poly_randtest_pentomial_irreducible(fmpz_mod_poly_t poly, flint_rand_t state, + slong len, slong max_attempts) +{ + slong i = 0; + + while (max_attempts == 0 || i < max_attempts) + { + fmpz_mod_poly_randtest_pentomial(poly, state, len); + if (!fmpz_mod_poly_is_zero(poly) && fmpz_mod_poly_is_irreducible(poly)) + { + return 1; + } + i++; + + } + return 0; +} + +void +fmpz_mod_poly_randtest_sparse_irreducible(fmpz_mod_poly_t poly, flint_rand_t state, slong len) +{ + if (len < 3) + { + fmpz_mod_poly_randtest_monic_irreducible(poly, state, len); + return; + } + + /* Try trinomials */ + if (fmpz_mod_poly_randtest_trinomial_irreducible(poly, state, len, 2*len)) + return; + + if (len < 5) + { + fmpz_mod_poly_randtest_monic_irreducible(poly, state, len); + return; + } + + /* Try pentomials */ + if (fmpz_mod_poly_randtest_pentomial_irreducible(poly, state, len, 2*len)) + return; + + /* Give up */ + fmpz_mod_poly_randtest_monic_irreducible(poly, state, len); +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/realloc.c b/external/flint-2.4.3/fmpz_mod_poly/realloc.c new file mode 100644 index 0000000..3765775 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/realloc.c @@ -0,0 +1,57 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_mod_poly.h" + +void fmpz_mod_poly_realloc(fmpz_mod_poly_t poly, slong alloc) +{ + if (alloc == 0) /* Clear up, reinitialise */ + { + if (poly->coeffs) + _fmpz_vec_clear(poly->coeffs, poly->alloc); + + poly->coeffs = NULL; + poly->length = 0; + poly->alloc = 0; + + return; + } + + if (poly->alloc) /* Realloc */ + { + fmpz_mod_poly_truncate(poly, alloc); + + poly->coeffs = (fmpz *) flint_realloc(poly->coeffs, alloc * sizeof(fmpz)); + if (alloc > poly->alloc) + flint_mpn_zero((mp_ptr) (poly->coeffs + poly->alloc), + alloc - poly->alloc); + } + else /* Nothing allocated already so do it now */ + { + poly->coeffs = (fmpz *) flint_calloc(alloc, sizeof(fmpz)); + } + + poly->alloc = alloc; +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/rem_basecase.c b/external/flint-2.4.3/fmpz_mod_poly/rem_basecase.c new file mode 100644 index 0000000..b92de48 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/rem_basecase.c @@ -0,0 +1,98 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2010 Sebastian Pancratz + Copyright (C) 2008, 2009 William Hart + +******************************************************************************/ + +#include +#include "fmpz_vec.h" +#include "fmpz_mod_poly.h" + +void _fmpz_mod_poly_rem_basecase(fmpz *R, + const fmpz *A, slong lenA, const fmpz *B, slong lenB, + const fmpz_t invB, const fmpz_t p) +{ + fmpz_t q; + slong iR; + + fmpz_init(q); + + if (R != A) + _fmpz_vec_set(R, A, lenA); + + for (iR = lenA - 1; iR >= lenB - 1; iR--) + { + if (!fmpz_is_zero(R + iR)) + { + fmpz_mul(q, R + iR, invB); + fmpz_mod(q, q, p); + + _fmpz_vec_scalar_submul_fmpz(R + (iR - lenB + 1), B, lenB, q); + _fmpz_vec_scalar_mod_fmpz(R + (iR - lenB + 1), R + (iR - lenB + 1), lenB, p); + } + } + fmpz_clear(q); +} + +void fmpz_mod_poly_rem_basecase(fmpz_mod_poly_t R, + const fmpz_mod_poly_t A, const fmpz_mod_poly_t B) +{ + const slong lenA = A->length, lenB = B->length; + fmpz *r; + fmpz_t invB; + + if (lenA < lenB) + { + fmpz_mod_poly_set(R, A); + return; + } + + fmpz_init(invB); + fmpz_invmod(invB, B->coeffs + (lenB - 1), &(B->p)); + + if (R == B) + { + r = _fmpz_vec_init(lenA); + } + else + { + fmpz_mod_poly_fit_length(R, lenA); + r = R->coeffs; + } + + _fmpz_mod_poly_rem_basecase(r, A->coeffs, lenA, + B->coeffs, lenB, invB, &(B->p)); + + if (R == B) + { + _fmpz_vec_clear(R->coeffs, R->alloc); + R->coeffs = r; + R->alloc = lenA; + R->length = lenA; + } + _fmpz_mod_poly_set_length(R, lenB - 1); + _fmpz_mod_poly_normalise(R); + + fmpz_clear(invB); +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/remove.c b/external/flint-2.4.3/fmpz_mod_poly/remove.c new file mode 100644 index 0000000..b197780 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/remove.c @@ -0,0 +1,55 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "fmpz_mod_poly.h" + +ulong fmpz_mod_poly_remove(fmpz_mod_poly_t f, const fmpz_mod_poly_t g) +{ + fmpz_mod_poly_t q, r; + ulong i = 0; + + fmpz_mod_poly_init(q, &g->p); + fmpz_mod_poly_init(r, &g->p); + + while (1) + { + if (f->length < g->length) + break; + fmpz_mod_poly_divrem(q, r, f, g); + if (r->length == 0) + fmpz_mod_poly_swap(q, f); + else + break; + i++; + } + + fmpz_mod_poly_clear(q); + fmpz_mod_poly_clear(r); + + return i; +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/reverse.c b/external/flint-2.4.3/fmpz_mod_poly/reverse.c new file mode 100644 index 0000000..fa6bc7d --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/reverse.c @@ -0,0 +1,76 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" + +void +_fmpz_mod_poly_reverse(fmpz * res, const fmpz * poly, slong len, slong n) +{ + if (res == poly) + { + slong i; + + for (i = 0; i < n / 2; i++) + { + fmpz t = res[i]; + res[i] = res[n - 1 - i]; + res[n - 1 - i] = t; + } + + for (i = 0; i < n - len; i++) + fmpz_zero(res + i); + } + else + { + slong i; + + for (i = 0; i < n - len; i++) + fmpz_zero(res + i); + + for (i = 0; i < len; i++) + fmpz_set(res + (n - len) + i, poly + (len - 1) - i); + } +} + +void +fmpz_mod_poly_reverse(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly, slong n) +{ + slong len = FLINT_MIN(n, poly->length); + if (len == 0) + { + fmpz_mod_poly_zero(res); + return; + } + + fmpz_mod_poly_fit_length(res, n); + + _fmpz_mod_poly_reverse(res->coeffs, poly->coeffs, len, n); + + _fmpz_mod_poly_set_length(res, n); + _fmpz_mod_poly_normalise(res); +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/scalar_mul_fmpz.c b/external/flint-2.4.3/fmpz_mod_poly/scalar_mul_fmpz.c new file mode 100644 index 0000000..946dc4a --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/scalar_mul_fmpz.c @@ -0,0 +1,49 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpz_mod_poly.h" + +void _fmpz_mod_poly_scalar_mul_fmpz(fmpz *res, const fmpz *poly, slong len, + const fmpz_t x, const fmpz_t p) +{ + _fmpz_vec_scalar_mul_fmpz(res, poly, len, x); + _fmpz_vec_scalar_mod_fmpz(res, res, len, p); +} + +void fmpz_mod_poly_scalar_mul_fmpz(fmpz_mod_poly_t res, + const fmpz_mod_poly_t poly, const fmpz_t x) +{ + fmpz_mod_poly_fit_length(res, poly->length); + _fmpz_mod_poly_scalar_mul_fmpz(res->coeffs, + poly->coeffs, poly->length, x, &(poly->p)); + + _fmpz_mod_poly_set_length(res, poly->length); + _fmpz_mod_poly_normalise(res); +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/set.c b/external/flint-2.4.3/fmpz_mod_poly/set.c new file mode 100644 index 0000000..924087f --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/set.c @@ -0,0 +1,45 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2008, 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" + +void fmpz_mod_poly_set(fmpz_mod_poly_t poly1, const fmpz_mod_poly_t poly2) +{ + if (poly1 != poly2) /* Aliasing is trivial */ + { + slong i, len = poly2->length; + + fmpz_mod_poly_fit_length(poly1, len); + + for (i = 0; i < len; i++) + fmpz_set(poly1->coeffs + i, poly2->coeffs + i); + + _fmpz_mod_poly_set_length(poly1, len); + } +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/set_coeff_fmpz.c b/external/flint-2.4.3/fmpz_mod_poly/set_coeff_fmpz.c new file mode 100644 index 0000000..bd76501 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/set_coeff_fmpz.c @@ -0,0 +1,47 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2008, 2009 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" + +void +fmpz_mod_poly_set_coeff_fmpz(fmpz_mod_poly_t poly, slong n, const fmpz_t x) +{ + fmpz_mod_poly_fit_length(poly, n + 1); + + if (n + 1 > poly->length) + { + flint_mpn_zero((mp_ptr) (poly->coeffs + poly->length), n - poly->length); + poly->length = n + 1; + } + + fmpz_mod(poly->coeffs + n, x, &(poly->p)); + _fmpz_mod_poly_normalise(poly); +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/set_coeff_ui.c b/external/flint-2.4.3/fmpz_mod_poly/set_coeff_ui.c new file mode 100644 index 0000000..a3426e3 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/set_coeff_ui.c @@ -0,0 +1,47 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2008, 2009 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" + +void fmpz_mod_poly_set_coeff_ui(fmpz_mod_poly_t poly, slong n, ulong x) +{ + fmpz_mod_poly_fit_length(poly, n + 1); + + if (n + 1 > poly->length) + { + flint_mpn_zero((mp_ptr) (poly->coeffs + poly->length), n - poly->length); + poly->length = n + 1; + } + + fmpz_set_ui(poly->coeffs + n, x); + fmpz_mod(poly->coeffs + n, poly->coeffs + n, &(poly->p)); + _fmpz_mod_poly_normalise(poly); +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/set_fmpz.c b/external/flint-2.4.3/fmpz_mod_poly/set_fmpz.c new file mode 100644 index 0000000..c80a087 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/set_fmpz.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" + +void fmpz_mod_poly_set_fmpz(fmpz_mod_poly_t poly, const fmpz_t c) +{ + fmpz_mod_poly_fit_length(poly, 1); + fmpz_mod(poly->coeffs, c, &(poly->p)); + _fmpz_mod_poly_set_length(poly, 1); + _fmpz_mod_poly_normalise(poly); +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/set_fmpz_poly.c b/external/flint-2.4.3/fmpz_mod_poly/set_fmpz_poly.c new file mode 100644 index 0000000..5766ba5 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/set_fmpz_poly.c @@ -0,0 +1,45 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" + +void fmpz_mod_poly_set_fmpz_poly(fmpz_mod_poly_t f, const fmpz_poly_t g) +{ + slong i; + + fmpz_mod_poly_fit_length(f, g->length); + _fmpz_mod_poly_set_length(f, g->length); + + for (i = 0; i < g->length; i++) + { + fmpz_mod(f->coeffs + i, g->coeffs + i, &(f->p)); + } + + _fmpz_mod_poly_normalise(f); +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/shift_left.c b/external/flint-2.4.3/fmpz_mod_poly/shift_left.c new file mode 100644 index 0000000..9a58341 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/shift_left.c @@ -0,0 +1,72 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2010 Sebastian Pancratz + Copyright (C) 2009, 2008 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" + +void +_fmpz_mod_poly_shift_left(fmpz * res, const fmpz * poly, slong len, slong n) +{ + slong i; + + /* Copy in reverse to avoid writing over unshifted coefficients */ + if (res != poly) + { + for (i = len; i--; ) + fmpz_set(res + n + i, poly + i); + } + else + { + for (i = len; i--; ) + fmpz_swap(res + n + i, res + i); + } + + for (i = 0; i < n; i++) + fmpz_zero(res + i); +} + +void +fmpz_mod_poly_shift_left(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly, slong n) +{ + if (n == 0) + { + fmpz_mod_poly_set(res, poly); + return; + } + + if (poly->length == 0) + { + fmpz_mod_poly_zero(res); + return; + } + + fmpz_mod_poly_fit_length(res, poly->length + n); + _fmpz_mod_poly_shift_left(res->coeffs, poly->coeffs, poly->length, n); + _fmpz_mod_poly_set_length(res, poly->length + n); +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/shift_right.c b/external/flint-2.4.3/fmpz_mod_poly/shift_right.c new file mode 100644 index 0000000..9f4c16e --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/shift_right.c @@ -0,0 +1,69 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2010 Sebastian Pancratz + Copyright (C) 2009, 2008 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" + +void +_fmpz_mod_poly_shift_right(fmpz * res, const fmpz * poly, slong len, slong n) +{ + slong i; + + /* Copy in forward order to avoid writing over unshifted coefficients */ + if (res != poly) + { + for (i = 0; i < len - n; i++) + fmpz_set(res + i, poly + n + i); + } + else + { + for (i = 0; i < len - n; i++) + fmpz_swap(res + i, res + n + i); + } + +} + +void +fmpz_mod_poly_shift_right(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly, slong n) +{ + if (n == 0) + { + fmpz_mod_poly_set(res, poly); + return; + } + + if (poly->length <= n) + { + fmpz_mod_poly_zero(res); + return; + } + + fmpz_mod_poly_fit_length(res, poly->length - n); + _fmpz_mod_poly_shift_right(res->coeffs, poly->coeffs, poly->length, n); + _fmpz_mod_poly_set_length(res, poly->length - n); +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/sqr.c b/external/flint-2.4.3/fmpz_mod_poly/sqr.c new file mode 100644 index 0000000..e574f57 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/sqr.c @@ -0,0 +1,71 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpz_mod_poly.h" + +void _fmpz_mod_poly_sqr(fmpz *res, const fmpz *poly, slong len, const fmpz_t p) +{ + _fmpz_poly_sqr(res, poly, len); + _fmpz_vec_scalar_mod_fmpz(res, res, 2 * len - 1, p); +} + +void fmpz_mod_poly_sqr(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly) +{ + const slong len = poly->length; + + if (len == 0) + { + fmpz_mod_poly_zero(res); + return; + } + + if (res == poly) + { + fmpz *t = flint_calloc(2 * len - 1, sizeof(fmpz)); + + _fmpz_mod_poly_sqr(t, poly->coeffs, len, &(res->p)); + + _fmpz_vec_clear(res->coeffs, res->alloc); + res->alloc = 2 * len - 1; + res->length = 2 * len - 1; + res->coeffs = t; + _fmpz_mod_poly_normalise(res); + } + else + { + fmpz_mod_poly_fit_length(res, 2 * len - 1); + + _fmpz_mod_poly_sqr(res->coeffs, poly->coeffs, len, &(res->p)); + + _fmpz_mod_poly_set_length(res, 2 * len - 1); + _fmpz_mod_poly_normalise(res); + } +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/sub.c b/external/flint-2.4.3/fmpz_mod_poly/sub.c new file mode 100644 index 0000000..bc9b5a5 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/sub.c @@ -0,0 +1,60 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2008, 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpz_mod_poly.h" + +void _fmpz_mod_poly_sub(fmpz *res, const fmpz *poly1, slong len1, + const fmpz *poly2, slong len2, const fmpz_t p) +{ + slong i, len = FLINT_MAX(len1, len2); + + _fmpz_poly_sub(res, poly1, len1, poly2, len2); + + for (i = 0; i < len; i++) + { + if (fmpz_sgn(res + i) < 0) + fmpz_add(res + i, res + i, p); + } +} + +void fmpz_mod_poly_sub(fmpz_mod_poly_t res, + const fmpz_mod_poly_t poly1, const fmpz_mod_poly_t poly2) +{ + slong max = FLINT_MAX(poly1->length, poly2->length); + + fmpz_mod_poly_fit_length(res, max); + + _fmpz_mod_poly_sub(res->coeffs, poly1->coeffs, poly1->length, + poly2->coeffs, poly2->length, &(res->p)); + + _fmpz_mod_poly_set_length(res, max); + _fmpz_mod_poly_normalise(res); +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/swap.c b/external/flint-2.4.3/fmpz_mod_poly/swap.c new file mode 100644 index 0000000..216d7a9 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/swap.c @@ -0,0 +1,52 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2008, 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" + +void fmpz_mod_poly_swap(fmpz_mod_poly_t poly1, fmpz_mod_poly_t poly2) +{ + if (poly1 != poly2) + { + slong t; + fmpz *c; + + t = poly1->length; + poly1->length = poly2->length; + poly2->length = t; + + t = poly1->alloc; + poly1->alloc = poly2->alloc; + poly2->alloc = t; + + c = poly1->coeffs; + poly1->coeffs = poly2->coeffs; + poly2->coeffs = c; + } +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/test/t-add.c b/external/flint-2.4.3/fmpz_mod_poly/test/t-add.c new file mode 100644 index 0000000..414322c --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/test/t-add.c @@ -0,0 +1,121 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2010 Sebastian Pancratz + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("add...."); + fflush(stdout); + + + + /* Check aliasing of a and c */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, c; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + fmpz_mod_poly_randtest(b, state, n_randint(state, 100)); + + fmpz_mod_poly_add(c, a, b); + fmpz_mod_poly_add(a, a, b); + + result = (fmpz_mod_poly_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_mod_poly_print(a), flint_printf("\n\n"); + fmpz_mod_poly_print(b), flint_printf("\n\n"); + fmpz_mod_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(c); + fmpz_clear(p); + } + + /* Check aliasing of b and c */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, c; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + fmpz_mod_poly_randtest(b, state, n_randint(state, 100)); + + fmpz_mod_poly_add(c, a, b); + fmpz_mod_poly_add(b, a, b); + + result = (fmpz_mod_poly_equal(b, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_mod_poly_print(a), flint_printf("\n\n"); + fmpz_mod_poly_print(b), flint_printf("\n\n"); + fmpz_mod_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(c); + fmpz_clear(p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/test/t-compose_divconquer.c b/external/flint-2.4.3/fmpz_mod_poly/test/t-compose_divconquer.c new file mode 100644 index 0000000..a6fa83e --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/test/t-compose_divconquer.c @@ -0,0 +1,170 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2010 Sebastian Pancratz + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("compose_divconquer...."); + fflush(stdout); + + + + /* Check aliasing of a and c */ + for (i = 0; i < 100; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, c; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + fmpz_mod_poly_randtest(a, state, n_randint(state, 80)); + fmpz_mod_poly_randtest(b, state, n_randint(state, 30)); + + fmpz_mod_poly_compose_divconquer(c, a, b); + fmpz_mod_poly_compose_divconquer(a, a, b); + + result = (fmpz_mod_poly_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_mod_poly_print(a), flint_printf("\n\n"); + fmpz_mod_poly_print(b), flint_printf("\n\n"); + fmpz_mod_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(c); + fmpz_clear(p); + } + + /* Check aliasing of b and c */ + for (i = 0; i < 100; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, c; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + fmpz_mod_poly_randtest(a, state, n_randint(state, 80)); + fmpz_mod_poly_randtest(b, state, n_randint(state, 30)); + + fmpz_mod_poly_compose_divconquer(c, a, b); + fmpz_mod_poly_compose_divconquer(b, a, b); + + result = (fmpz_mod_poly_equal(b, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_mod_poly_print(a), flint_printf("\n\n"); + fmpz_mod_poly_print(b), flint_printf("\n\n"); + fmpz_mod_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(c); + fmpz_clear(p); + } + + /* Compare with composition over Z[X] */ + for (i = 0; i < 100; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, c, d; + fmpz_poly_t A, B, C; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + fmpz_mod_poly_init(d, p); + fmpz_mod_poly_randtest(a, state, n_randint(state, 80)); + fmpz_mod_poly_randtest(b, state, n_randint(state, 30)); + + fmpz_poly_init(A); + fmpz_poly_init(B); + fmpz_poly_init(C); + fmpz_mod_poly_get_fmpz_poly(A, a); + fmpz_mod_poly_get_fmpz_poly(B, b); + + fmpz_mod_poly_compose_divconquer(c, a, b); + fmpz_poly_compose(C, A, B); + fmpz_mod_poly_set_fmpz_poly(d, C); + + result = (fmpz_mod_poly_equal(c, d)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_mod_poly_print(a), flint_printf("\n\n"); + fmpz_mod_poly_print(b), flint_printf("\n\n"); + fmpz_mod_poly_print(c), flint_printf("\n\n"); + fmpz_mod_poly_print(d), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(c); + fmpz_mod_poly_clear(d); + fmpz_poly_clear(A); + fmpz_poly_clear(B); + fmpz_poly_clear(C); + fmpz_clear(p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/test/t-compose_horner.c b/external/flint-2.4.3/fmpz_mod_poly/test/t-compose_horner.c new file mode 100644 index 0000000..54ed5b9 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/test/t-compose_horner.c @@ -0,0 +1,170 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2010 Sebastian Pancratz + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("compose_horner...."); + fflush(stdout); + + + + /* Check aliasing of a and c */ + for (i = 0; i < 100; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, c; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + fmpz_mod_poly_randtest(a, state, n_randint(state, 80)); + fmpz_mod_poly_randtest(b, state, n_randint(state, 30)); + + fmpz_mod_poly_compose_horner(c, a, b); + fmpz_mod_poly_compose_horner(a, a, b); + + result = (fmpz_mod_poly_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_mod_poly_print(a), flint_printf("\n\n"); + fmpz_mod_poly_print(b), flint_printf("\n\n"); + fmpz_mod_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(c); + fmpz_clear(p); + } + + /* Check aliasing of b and c */ + for (i = 0; i < 100; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, c; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + fmpz_mod_poly_randtest(a, state, n_randint(state, 80)); + fmpz_mod_poly_randtest(b, state, n_randint(state, 30)); + + fmpz_mod_poly_compose_horner(c, a, b); + fmpz_mod_poly_compose_horner(b, a, b); + + result = (fmpz_mod_poly_equal(b, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_mod_poly_print(a), flint_printf("\n\n"); + fmpz_mod_poly_print(b), flint_printf("\n\n"); + fmpz_mod_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(c); + fmpz_clear(p); + } + + /* Compare with composition over Z[X] */ + for (i = 0; i < 100; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, c, d; + fmpz_poly_t A, B, C; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + fmpz_mod_poly_init(d, p); + fmpz_mod_poly_randtest(a, state, n_randint(state, 80)); + fmpz_mod_poly_randtest(b, state, n_randint(state, 30)); + + fmpz_poly_init(A); + fmpz_poly_init(B); + fmpz_poly_init(C); + fmpz_mod_poly_get_fmpz_poly(A, a); + fmpz_mod_poly_get_fmpz_poly(B, b); + + fmpz_mod_poly_compose_horner(c, a, b); + fmpz_poly_compose(C, A, B); + fmpz_mod_poly_set_fmpz_poly(d, C); + + result = (fmpz_mod_poly_equal(c, d)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_mod_poly_print(a), flint_printf("\n\n"); + fmpz_mod_poly_print(b), flint_printf("\n\n"); + fmpz_mod_poly_print(c), flint_printf("\n\n"); + fmpz_mod_poly_print(d), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(c); + fmpz_mod_poly_clear(d); + fmpz_poly_clear(A); + fmpz_poly_clear(B); + fmpz_poly_clear(C); + fmpz_clear(p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/test/t-compose_mod.c b/external/flint-2.4.3/fmpz_mod_poly/test/t-compose_mod.c new file mode 100644 index 0000000..593b174 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/test/t-compose_mod.c @@ -0,0 +1,202 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + flint_printf("compose_mod...."); + fflush(stdout); + + for (i = 0; i < 1000; i++) + { + fmpz_mod_poly_t a, b, c, d, e; + fmpz_t p; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + fmpz_mod_poly_init(d, p); + fmpz_mod_poly_init(e, p); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 20) + 1); + fmpz_mod_poly_randtest(b, state, n_randint(state, 20) + 1); + fmpz_mod_poly_randtest_not_zero(c, state, n_randint(state, 20) + 1); + + fmpz_mod_poly_compose_mod(d, a, b, c); + fmpz_mod_poly_compose(e, a, b); + fmpz_mod_poly_rem(e, e, c); + + if (!fmpz_mod_poly_equal(d, e)) + { + flint_printf("FAIL (composition):\n"); + flint_printf("a:\n"); fmpz_mod_poly_print(a); flint_printf("\n"); + flint_printf("b:\n"); fmpz_mod_poly_print(b); flint_printf("\n"); + flint_printf("c:\n"); fmpz_mod_poly_print(c); flint_printf("\n"); + flint_printf("d:\n"); fmpz_mod_poly_print(d); flint_printf("\n"); + flint_printf("e:\n"); fmpz_mod_poly_print(e); flint_printf("\n"); + abort(); + } + + fmpz_clear(p); + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(c); + fmpz_mod_poly_clear(d); + fmpz_mod_poly_clear(e); + } + + /* Test aliasing of res and a */ + for (i = 0; i < 1000; i++) + { + fmpz_mod_poly_t a, b, c, d; + fmpz_t p; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + fmpz_mod_poly_init(d, p); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 20) + 1); + fmpz_mod_poly_randtest(b, state, n_randint(state, 20) + 1); + fmpz_mod_poly_randtest_not_zero(c, state, n_randint(state, 20) + 1); + + fmpz_mod_poly_compose_mod(d, a, b, c); + fmpz_mod_poly_compose_mod(a, a, b, c); + + if (!fmpz_mod_poly_equal(d, a)) + { + flint_printf("FAIL (aliasing a):\n"); + flint_printf("a:\n"); fmpz_mod_poly_print(a); flint_printf("\n"); + flint_printf("b:\n"); fmpz_mod_poly_print(b); flint_printf("\n"); + flint_printf("c:\n"); fmpz_mod_poly_print(c); flint_printf("\n"); + flint_printf("d:\n"); fmpz_mod_poly_print(d); flint_printf("\n"); + abort(); + } + + fmpz_clear(p); + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(c); + fmpz_mod_poly_clear(d); + } + + /* Test aliasing of res and b */ + for (i = 0; i < 1000; i++) + { + fmpz_mod_poly_t a, b, c, d; + fmpz_t p; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + fmpz_mod_poly_init(d, p); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 20) + 1); + fmpz_mod_poly_randtest(b, state, n_randint(state, 20) + 1); + fmpz_mod_poly_randtest_not_zero(c, state, n_randint(state, 20) + 1); + + fmpz_mod_poly_compose_mod(d, a, b, c); + fmpz_mod_poly_compose_mod(b, a, b, c); + + if (!fmpz_mod_poly_equal(d, b)) + { + flint_printf("FAIL (aliasing b)\n"); + flint_printf("a:\n"); fmpz_mod_poly_print(a); flint_printf("\n"); + flint_printf("b:\n"); fmpz_mod_poly_print(b); flint_printf("\n"); + flint_printf("c:\n"); fmpz_mod_poly_print(c); flint_printf("\n"); + flint_printf("d:\n"); fmpz_mod_poly_print(d); flint_printf("\n"); + abort(); + } + + fmpz_clear(p); + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(c); + fmpz_mod_poly_clear(d); + } + + /* Test aliasing of res and c */ + for (i = 0; i < 1000; i++) + { + fmpz_mod_poly_t a, b, c, d; + fmpz_t p; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + fmpz_mod_poly_init(d, p); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 20) + 1); + fmpz_mod_poly_randtest(b, state, n_randint(state, 20) + 1); + fmpz_mod_poly_randtest_not_zero(c, state, n_randint(state, 20) + 1); + + fmpz_mod_poly_compose_mod(d, a, b, c); + fmpz_mod_poly_compose_mod(c, a, b, c); + + if (!fmpz_mod_poly_equal(d, c)) + { + flint_printf("FAIL (aliasing c)\n"); + flint_printf("a:\n"); fmpz_mod_poly_print(a); flint_printf("\n"); + flint_printf("b:\n"); fmpz_mod_poly_print(b); flint_printf("\n"); + flint_printf("c:\n"); fmpz_mod_poly_print(c); flint_printf("\n"); + flint_printf("d:\n"); fmpz_mod_poly_print(d); flint_printf("\n"); + abort(); + } + + fmpz_clear(p); + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(c); + fmpz_mod_poly_clear(d); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/test/t-compose_mod_brent_kung.c b/external/flint-2.4.3/fmpz_mod_poly/test/t-compose_mod_brent_kung.c new file mode 100644 index 0000000..244c7d3 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/test/t-compose_mod_brent_kung.c @@ -0,0 +1,206 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + flint_printf("compose_mod_brent_kung...."); + fflush(stdout); + + for (i = 0; i < 2000; i++) + { + fmpz_mod_poly_t a, b, c, d, e; + fmpz_t p; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + fmpz_mod_poly_init(d, p); + fmpz_mod_poly_init(e, p); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 20) + 1); + fmpz_mod_poly_randtest(b, state, n_randint(state, 20) + 1); + fmpz_mod_poly_randtest_not_zero(c, state, n_randint(state, 20) + 1); + + fmpz_mod_poly_rem(a, a, c); + fmpz_mod_poly_compose_mod_brent_kung(d, a, b, c); + fmpz_mod_poly_compose(e, a, b); + fmpz_mod_poly_rem(e, e, c); + + if (!fmpz_mod_poly_equal(d, e)) + { + flint_printf("FAIL (composition):\n"); + flint_printf("a:\n"); fmpz_mod_poly_print(a); flint_printf("\n"); + flint_printf("b:\n"); fmpz_mod_poly_print(b); flint_printf("\n"); + flint_printf("c:\n"); fmpz_mod_poly_print(c); flint_printf("\n"); + flint_printf("d:\n"); fmpz_mod_poly_print(d); flint_printf("\n"); + flint_printf("e:\n"); fmpz_mod_poly_print(e); flint_printf("\n"); + abort(); + } + + fmpz_clear(p); + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(c); + fmpz_mod_poly_clear(d); + fmpz_mod_poly_clear(e); + } + + /* Test aliasing of res and a */ + for (i = 0; i < 1000; i++) + { + fmpz_mod_poly_t a, b, c, d; + fmpz_t p; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + fmpz_mod_poly_init(d, p); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 20) + 1); + fmpz_mod_poly_randtest(b, state, n_randint(state, 20) + 1); + fmpz_mod_poly_randtest_not_zero(c, state, n_randint(state, 20) + 1); + + fmpz_mod_poly_rem(a, a, c); + fmpz_mod_poly_compose_mod_brent_kung(d, a, b, c); + fmpz_mod_poly_compose_mod_brent_kung(a, a, b, c); + + if (!fmpz_mod_poly_equal(d, a)) + { + flint_printf("FAIL (aliasing a):\n"); + flint_printf("a:\n"); fmpz_mod_poly_print(a); flint_printf("\n"); + flint_printf("b:\n"); fmpz_mod_poly_print(b); flint_printf("\n"); + flint_printf("c:\n"); fmpz_mod_poly_print(c); flint_printf("\n"); + flint_printf("d:\n"); fmpz_mod_poly_print(d); flint_printf("\n"); + abort(); + } + + fmpz_clear(p); + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(c); + fmpz_mod_poly_clear(d); + } + + /* Test aliasing of res and b */ + for (i = 0; i < 1000; i++) + { + fmpz_mod_poly_t a, b, c, d; + fmpz_t p; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + fmpz_mod_poly_init(d, p); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 20) + 1); + fmpz_mod_poly_randtest(b, state, n_randint(state, 20) + 1); + fmpz_mod_poly_randtest_not_zero(c, state, n_randint(state, 20) + 1); + + fmpz_mod_poly_rem(a, a, c); + fmpz_mod_poly_compose_mod_brent_kung(d, a, b, c); + fmpz_mod_poly_compose_mod_brent_kung(b, a, b, c); + + if (!fmpz_mod_poly_equal(d, b)) + { + flint_printf("FAIL (aliasing b)\n"); + flint_printf("a:\n"); fmpz_mod_poly_print(a); flint_printf("\n"); + flint_printf("b:\n"); fmpz_mod_poly_print(b); flint_printf("\n"); + flint_printf("c:\n"); fmpz_mod_poly_print(c); flint_printf("\n"); + flint_printf("d:\n"); fmpz_mod_poly_print(d); flint_printf("\n"); + abort(); + } + + fmpz_clear(p); + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(c); + fmpz_mod_poly_clear(d); + } + + /* Test aliasing of res and c */ + for (i = 0; i < 1000; i++) + { + fmpz_mod_poly_t a, b, c, d; + fmpz_t p; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + fmpz_mod_poly_init(d, p); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 20) + 1); + fmpz_mod_poly_randtest(b, state, n_randint(state, 20) + 1); + fmpz_mod_poly_randtest_not_zero(c, state, n_randint(state, 20) + 1); + + fmpz_mod_poly_rem(a, a, c); + fmpz_mod_poly_compose_mod_brent_kung(d, a, b, c); + fmpz_mod_poly_compose_mod_brent_kung(c, a, b, c); + + if (!fmpz_mod_poly_equal(d, c)) + { + flint_printf("FAIL (aliasing c)\n"); + flint_printf("a:\n"); fmpz_mod_poly_print(a); flint_printf("\n"); + flint_printf("b:\n"); fmpz_mod_poly_print(b); flint_printf("\n"); + flint_printf("c:\n"); fmpz_mod_poly_print(c); flint_printf("\n"); + flint_printf("d:\n"); fmpz_mod_poly_print(d); flint_printf("\n"); + abort(); + } + + fmpz_clear(p); + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(c); + fmpz_mod_poly_clear(d); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/test/t-compose_mod_brent_kung_precomp_preinv.c b/external/flint-2.4.3/fmpz_mod_poly/test/t-compose_mod_brent_kung_precomp_preinv.c new file mode 100644 index 0000000..aed8b45 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/test/t-compose_mod_brent_kung_precomp_preinv.c @@ -0,0 +1,253 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Martin Lee + +******************************************************************************/ + +#undef ulong +#define ulong ulongxx/* interferes with system includes */ + +#include +#include + +#undef ulong + +#include + +#define ulong mp_limb_t + +#include "flint.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + flint_printf("compose_mod_brent_kung_precomp_preinv...."); + fflush(stdout); + + /* no aliasing */ + for (i = 0; i < 2000; i++) + { + fmpz_mod_poly_t a, b, c, cinv, d, e; + fmpz_t p; + fmpz_mat_t B; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + fmpz_mod_poly_init(cinv, p); + fmpz_mod_poly_init(d, p); + fmpz_mod_poly_init(e, p); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 20) + 1); + fmpz_mod_poly_randtest(b, state, n_randint(state, 20) + 1); + fmpz_mod_poly_randtest_not_zero(c, state, n_randint(state, 20) + 1); + + fmpz_mod_poly_reverse (cinv, c, c->length); + fmpz_mod_poly_inv_series_newton (cinv, cinv, c->length); + fmpz_mat_init (B, n_sqrt (c->length-1)+1, c->length-1); + fmpz_mod_poly_precompute_matrix (B, b, c, cinv); + + fmpz_mod_poly_rem(a, a, c); + fmpz_mod_poly_compose_mod_brent_kung_precomp_preinv(d, a, B, c, cinv); + fmpz_mod_poly_compose(e, a, b); + fmpz_mod_poly_rem(e, e, c); + + if (!fmpz_mod_poly_equal(d, e)) + { + flint_printf("FAIL (composition):\n"); + flint_printf("a:\n"); fmpz_mod_poly_print(a); flint_printf("\n"); + flint_printf("b:\n"); fmpz_mod_poly_print(b); flint_printf("\n"); + flint_printf("c:\n"); fmpz_mod_poly_print(c); flint_printf("\n"); + flint_printf("d:\n"); fmpz_mod_poly_print(d); flint_printf("\n"); + flint_printf("e:\n"); fmpz_mod_poly_print(e); flint_printf("\n"); + abort(); + } + + fmpz_clear(p); + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mat_clear (B); + fmpz_mod_poly_clear(c); + fmpz_mod_poly_clear(cinv); + fmpz_mod_poly_clear(d); + fmpz_mod_poly_clear(e); + } + + /* Test aliasing of res and a */ + for (i = 0; i < 1000; i++) + { + fmpz_mod_poly_t a, b, c, cinv, d; + fmpz_t p; + fmpz_mat_t B; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + fmpz_mod_poly_init(cinv, p); + fmpz_mod_poly_init(d, p); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 20) + 1); + fmpz_mod_poly_randtest(b, state, n_randint(state, 20) + 1); + fmpz_mod_poly_randtest_not_zero(c, state, n_randint(state, 20) + 1); + + fmpz_mod_poly_reverse (cinv, c, c->length); + fmpz_mod_poly_inv_series_newton (cinv, cinv, c->length); + fmpz_mat_init (B, n_sqrt (c->length-1)+1, c->length-1); + fmpz_mod_poly_precompute_matrix (B, b, c, cinv); + + fmpz_mod_poly_rem(a, a, c); + fmpz_mod_poly_compose_mod_brent_kung_precomp_preinv(d, a, B, c, cinv); + fmpz_mod_poly_compose_mod_brent_kung_precomp_preinv(a, a, B, c, cinv); + + if (!fmpz_mod_poly_equal(d, a)) + { + flint_printf("FAIL (aliasing a):\n"); + flint_printf("a:\n"); fmpz_mod_poly_print(a); flint_printf("\n"); + flint_printf("b:\n"); fmpz_mod_poly_print(b); flint_printf("\n"); + flint_printf("c:\n"); fmpz_mod_poly_print(c); flint_printf("\n"); + flint_printf("d:\n"); fmpz_mod_poly_print(d); flint_printf("\n"); + abort(); + } + + fmpz_clear(p); + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mat_clear (B); + fmpz_mod_poly_clear(c); + fmpz_mod_poly_clear(cinv); + fmpz_mod_poly_clear(d); + } + + /* Test aliasing of res and c */ + for (i = 0; i < 1000; i++) + { + fmpz_mod_poly_t a, b, c, cinv, d; + fmpz_t p; + fmpz_mat_t B; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + fmpz_mod_poly_init(cinv, p); + fmpz_mod_poly_init(d, p); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 20) + 1); + fmpz_mod_poly_randtest(b, state, n_randint(state, 20) + 1); + fmpz_mod_poly_randtest_not_zero(c, state, n_randint(state, 20) + 1); + + fmpz_mod_poly_reverse (cinv, c, c->length); + fmpz_mod_poly_inv_series_newton (cinv, cinv, c->length); + fmpz_mat_init (B, n_sqrt (c->length-1)+1, c->length-1); + fmpz_mod_poly_precompute_matrix (B, b, c, cinv); + + fmpz_mod_poly_rem(a, a, c); + fmpz_mod_poly_compose_mod_brent_kung_precomp_preinv(d, a, B, c, cinv); + fmpz_mod_poly_compose_mod_brent_kung_precomp_preinv(c, a, B, c, cinv); + + if (!fmpz_mod_poly_equal(d, c)) + { + flint_printf("FAIL (aliasing c)\n"); + flint_printf("a:\n"); fmpz_mod_poly_print(a); flint_printf("\n"); + flint_printf("b:\n"); fmpz_mod_poly_print(b); flint_printf("\n"); + flint_printf("c:\n"); fmpz_mod_poly_print(c); flint_printf("\n"); + flint_printf("d:\n"); fmpz_mod_poly_print(d); flint_printf("\n"); + abort(); + } + + fmpz_clear(p); + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mat_clear (B); + fmpz_mod_poly_clear(c); + fmpz_mod_poly_clear(cinv); + fmpz_mod_poly_clear(d); + } + + /* Test aliasing of res and cinv */ + for (i = 0; i < 1000; i++) + { + fmpz_mod_poly_t a, b, c, cinv, d; + fmpz_t p; + fmpz_mat_t B; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + fmpz_mod_poly_init(cinv, p); + fmpz_mod_poly_init(d, p); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 20) + 1); + fmpz_mod_poly_randtest(b, state, n_randint(state, 20) + 1); + fmpz_mod_poly_randtest_not_zero(c, state, n_randint(state, 20) + 1); + + fmpz_mod_poly_reverse (cinv, c, c->length); + fmpz_mod_poly_inv_series_newton (cinv, cinv, c->length); + fmpz_mat_init (B, n_sqrt (c->length-1)+1, c->length-1); + fmpz_mod_poly_precompute_matrix (B, b, c, cinv); + + fmpz_mod_poly_rem(a, a, c); + fmpz_mod_poly_compose_mod_brent_kung_precomp_preinv(d, a, B, c, cinv); + fmpz_mod_poly_compose_mod_brent_kung_precomp_preinv(cinv, a, B, c, cinv); + + if (!fmpz_mod_poly_equal(d, cinv)) + { + flint_printf("FAIL (aliasing c)\n"); + flint_printf("a:\n"); fmpz_mod_poly_print(a); flint_printf("\n"); + flint_printf("b:\n"); fmpz_mod_poly_print(b); flint_printf("\n"); + flint_printf("c:\n"); fmpz_mod_poly_print(c); flint_printf("\n"); + flint_printf("d:\n"); fmpz_mod_poly_print(d); flint_printf("\n"); + abort(); + } + + fmpz_clear(p); + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mat_clear (B); + fmpz_mod_poly_clear(c); + fmpz_mod_poly_clear(cinv); + fmpz_mod_poly_clear(d); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/test/t-compose_mod_brent_kung_preinv.c b/external/flint-2.4.3/fmpz_mod_poly/test/t-compose_mod_brent_kung_preinv.c new file mode 100644 index 0000000..7e1b8b4 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/test/t-compose_mod_brent_kung_preinv.c @@ -0,0 +1,281 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Martin Lee + +******************************************************************************/ + +#undef ulong +#define ulong ulongxx/* interferes with system includes */ + +#include +#include + +#undef ulong + +#include + +#define ulong mp_limb_t + +#include "flint.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + flint_printf("compose_mod_brent_kung_preinv...."); + fflush(stdout); + + /* no aliasing */ + for (i = 0; i < 2000; i++) + { + fmpz_mod_poly_t a, b, c, cinv, d, e; + fmpz_t p; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + fmpz_mod_poly_init(cinv, p); + fmpz_mod_poly_init(d, p); + fmpz_mod_poly_init(e, p); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 20) + 1); + fmpz_mod_poly_randtest(b, state, n_randint(state, 20) + 1); + fmpz_mod_poly_randtest_not_zero(c, state, n_randint(state, 20) + 1); + + fmpz_mod_poly_reverse (cinv, c, c->length); + fmpz_mod_poly_inv_series_newton (cinv, cinv, c->length); + + fmpz_mod_poly_rem(a, a, c); + fmpz_mod_poly_compose_mod_brent_kung_preinv(d, a, b, c, cinv); + fmpz_mod_poly_compose(e, a, b); + fmpz_mod_poly_rem(e, e, c); + + if (!fmpz_mod_poly_equal(d, e)) + { + flint_printf("FAIL (composition):\n"); + flint_printf("a:\n"); fmpz_mod_poly_print(a); flint_printf("\n"); + flint_printf("b:\n"); fmpz_mod_poly_print(b); flint_printf("\n"); + flint_printf("c:\n"); fmpz_mod_poly_print(c); flint_printf("\n"); + flint_printf("d:\n"); fmpz_mod_poly_print(d); flint_printf("\n"); + flint_printf("e:\n"); fmpz_mod_poly_print(e); flint_printf("\n"); + abort(); + } + + fmpz_clear(p); + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(c); + fmpz_mod_poly_clear(cinv); + fmpz_mod_poly_clear(d); + fmpz_mod_poly_clear(e); + } + + /* Test aliasing of res and a */ + for (i = 0; i < 1000; i++) + { + fmpz_mod_poly_t a, b, c, cinv, d; + fmpz_t p; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + fmpz_mod_poly_init(cinv, p); + fmpz_mod_poly_init(d, p); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 20) + 1); + fmpz_mod_poly_randtest(b, state, n_randint(state, 20) + 1); + fmpz_mod_poly_randtest_not_zero(c, state, n_randint(state, 20) + 1); + + fmpz_mod_poly_reverse (cinv, c, c->length); + fmpz_mod_poly_inv_series_newton (cinv, cinv, c->length); + + fmpz_mod_poly_rem(a, a, c); + fmpz_mod_poly_compose_mod_brent_kung_preinv(d, a, b, c, cinv); + fmpz_mod_poly_compose_mod_brent_kung_preinv(a, a, b, c, cinv); + + if (!fmpz_mod_poly_equal(d, a)) + { + flint_printf("FAIL (aliasing a):\n"); + flint_printf("a:\n"); fmpz_mod_poly_print(a); flint_printf("\n"); + flint_printf("b:\n"); fmpz_mod_poly_print(b); flint_printf("\n"); + flint_printf("c:\n"); fmpz_mod_poly_print(c); flint_printf("\n"); + flint_printf("d:\n"); fmpz_mod_poly_print(d); flint_printf("\n"); + abort(); + } + + fmpz_clear(p); + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(c); + fmpz_mod_poly_clear(cinv); + fmpz_mod_poly_clear(d); + } + + /* Test aliasing of res and b */ + for (i = 0; i < 1000; i++) + { + fmpz_mod_poly_t a, b, c, cinv, d; + fmpz_t p; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + fmpz_mod_poly_init(cinv, p); + fmpz_mod_poly_init(d, p); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 20) + 1); + fmpz_mod_poly_randtest(b, state, n_randint(state, 20) + 1); + fmpz_mod_poly_randtest_not_zero(c, state, n_randint(state, 20) + 1); + + fmpz_mod_poly_reverse (cinv, c, c->length); + fmpz_mod_poly_inv_series_newton (cinv, cinv, c->length); + + fmpz_mod_poly_rem(a, a, c); + fmpz_mod_poly_compose_mod_brent_kung_preinv(d, a, b, c, cinv); + fmpz_mod_poly_compose_mod_brent_kung_preinv(b, a, b, c, cinv); + + if (!fmpz_mod_poly_equal(d, b)) + { + flint_printf("FAIL (aliasing b)\n"); + flint_printf("a:\n"); fmpz_mod_poly_print(a); flint_printf("\n"); + flint_printf("b:\n"); fmpz_mod_poly_print(b); flint_printf("\n"); + flint_printf("c:\n"); fmpz_mod_poly_print(c); flint_printf("\n"); + flint_printf("d:\n"); fmpz_mod_poly_print(d); flint_printf("\n"); + abort(); + } + + fmpz_clear(p); + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(c); + fmpz_mod_poly_clear(cinv); + fmpz_mod_poly_clear(d); + } + + /* Test aliasing of res and c */ + for (i = 0; i < 1000; i++) + { + fmpz_mod_poly_t a, b, c, cinv, d; + fmpz_t p; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + fmpz_mod_poly_init(cinv, p); + fmpz_mod_poly_init(d, p); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 20) + 1); + fmpz_mod_poly_randtest(b, state, n_randint(state, 20) + 1); + fmpz_mod_poly_randtest_not_zero(c, state, n_randint(state, 20) + 1); + + fmpz_mod_poly_reverse (cinv, c, c->length); + fmpz_mod_poly_inv_series_newton (cinv, cinv, c->length); + + fmpz_mod_poly_rem(a, a, c); + fmpz_mod_poly_compose_mod_brent_kung_preinv(d, a, b, c, cinv); + fmpz_mod_poly_compose_mod_brent_kung_preinv(c, a, b, c, cinv); + + if (!fmpz_mod_poly_equal(d, c)) + { + flint_printf("FAIL (aliasing c)\n"); + flint_printf("a:\n"); fmpz_mod_poly_print(a); flint_printf("\n"); + flint_printf("b:\n"); fmpz_mod_poly_print(b); flint_printf("\n"); + flint_printf("c:\n"); fmpz_mod_poly_print(c); flint_printf("\n"); + flint_printf("d:\n"); fmpz_mod_poly_print(d); flint_printf("\n"); + abort(); + } + + fmpz_clear(p); + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(c); + fmpz_mod_poly_clear(cinv); + fmpz_mod_poly_clear(d); + } + + /* Test aliasing of res and cinv */ + for (i = 0; i < 1000; i++) + { + fmpz_mod_poly_t a, b, c, cinv, d; + fmpz_t p; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + fmpz_mod_poly_init(cinv, p); + fmpz_mod_poly_init(d, p); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 20) + 1); + fmpz_mod_poly_randtest(b, state, n_randint(state, 20) + 1); + fmpz_mod_poly_randtest_not_zero(c, state, n_randint(state, 20) + 1); + + fmpz_mod_poly_reverse (cinv, c, c->length); + fmpz_mod_poly_inv_series_newton (cinv, cinv, c->length); + + fmpz_mod_poly_rem(a, a, c); + fmpz_mod_poly_compose_mod_brent_kung_preinv(d, a, b, c, cinv); + fmpz_mod_poly_compose_mod_brent_kung_preinv(cinv, a, b, c, cinv); + + if (!fmpz_mod_poly_equal(d, cinv)) + { + flint_printf("FAIL (aliasing c)\n"); + flint_printf("a:\n"); fmpz_mod_poly_print(a); flint_printf("\n"); + flint_printf("b:\n"); fmpz_mod_poly_print(b); flint_printf("\n"); + flint_printf("c:\n"); fmpz_mod_poly_print(c); flint_printf("\n"); + flint_printf("d:\n"); fmpz_mod_poly_print(d); flint_printf("\n"); + abort(); + } + + fmpz_clear(p); + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(c); + fmpz_mod_poly_clear(cinv); + fmpz_mod_poly_clear(d); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/test/t-compose_mod_horner.c b/external/flint-2.4.3/fmpz_mod_poly/test/t-compose_mod_horner.c new file mode 100644 index 0000000..4a5ced6 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/test/t-compose_mod_horner.c @@ -0,0 +1,202 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + flint_printf("compose_mod_horner...."); + fflush(stdout); + + for (i = 0; i < 1000; i++) + { + fmpz_mod_poly_t a, b, c, d, e; + fmpz_t p; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + fmpz_mod_poly_init(d, p); + fmpz_mod_poly_init(e, p); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 20) + 1); + fmpz_mod_poly_randtest(b, state, n_randint(state, 20) + 1); + fmpz_mod_poly_randtest_not_zero(c, state, n_randint(state, 20) + 1); + + fmpz_mod_poly_compose_mod_horner(d, a, b, c); + fmpz_mod_poly_compose(e, a, b); + fmpz_mod_poly_rem(e, e, c); + + if (!fmpz_mod_poly_equal(d, e)) + { + flint_printf("FAIL (composition):\n"); + flint_printf("a:\n"); fmpz_mod_poly_print(a); flint_printf("\n"); + flint_printf("b:\n"); fmpz_mod_poly_print(b); flint_printf("\n"); + flint_printf("c:\n"); fmpz_mod_poly_print(c); flint_printf("\n"); + flint_printf("d:\n"); fmpz_mod_poly_print(d); flint_printf("\n"); + flint_printf("e:\n"); fmpz_mod_poly_print(e); flint_printf("\n"); + abort(); + } + + fmpz_clear(p); + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(c); + fmpz_mod_poly_clear(d); + fmpz_mod_poly_clear(e); + } + + /* Test aliasing of res and a */ + for (i = 0; i < 1000; i++) + { + fmpz_mod_poly_t a, b, c, d; + fmpz_t p; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + fmpz_mod_poly_init(d, p); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 20) + 1); + fmpz_mod_poly_randtest(b, state, n_randint(state, 20) + 1); + fmpz_mod_poly_randtest_not_zero(c, state, n_randint(state, 20) + 1); + + fmpz_mod_poly_compose_mod_horner(d, a, b, c); + fmpz_mod_poly_compose_mod_horner(a, a, b, c); + + if (!fmpz_mod_poly_equal(d, a)) + { + flint_printf("FAIL (aliasing a):\n"); + flint_printf("a:\n"); fmpz_mod_poly_print(a); flint_printf("\n"); + flint_printf("b:\n"); fmpz_mod_poly_print(b); flint_printf("\n"); + flint_printf("c:\n"); fmpz_mod_poly_print(c); flint_printf("\n"); + flint_printf("d:\n"); fmpz_mod_poly_print(d); flint_printf("\n"); + abort(); + } + + fmpz_clear(p); + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(c); + fmpz_mod_poly_clear(d); + } + + /* Test aliasing of res and b */ + for (i = 0; i < 1000; i++) + { + fmpz_mod_poly_t a, b, c, d; + fmpz_t p; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + fmpz_mod_poly_init(d, p); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 20) + 1); + fmpz_mod_poly_randtest(b, state, n_randint(state, 20) + 1); + fmpz_mod_poly_randtest_not_zero(c, state, n_randint(state, 20) + 1); + + fmpz_mod_poly_compose_mod_horner(d, a, b, c); + fmpz_mod_poly_compose_mod_horner(b, a, b, c); + + if (!fmpz_mod_poly_equal(d, b)) + { + flint_printf("FAIL (aliasing b)\n"); + flint_printf("a:\n"); fmpz_mod_poly_print(a); flint_printf("\n"); + flint_printf("b:\n"); fmpz_mod_poly_print(b); flint_printf("\n"); + flint_printf("c:\n"); fmpz_mod_poly_print(c); flint_printf("\n"); + flint_printf("d:\n"); fmpz_mod_poly_print(d); flint_printf("\n"); + abort(); + } + + fmpz_clear(p); + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(c); + fmpz_mod_poly_clear(d); + } + + /* Test aliasing of res and c */ + for (i = 0; i < 1000; i++) + { + fmpz_mod_poly_t a, b, c, d; + fmpz_t p; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + fmpz_mod_poly_init(d, p); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 20) + 1); + fmpz_mod_poly_randtest(b, state, n_randint(state, 20) + 1); + fmpz_mod_poly_randtest_not_zero(c, state, n_randint(state, 20) + 1); + + fmpz_mod_poly_compose_mod_horner(d, a, b, c); + fmpz_mod_poly_compose_mod_horner(c, a, b, c); + + if (!fmpz_mod_poly_equal(d, c)) + { + flint_printf("FAIL (aliasing c)\n"); + flint_printf("a:\n"); fmpz_mod_poly_print(a); flint_printf("\n"); + flint_printf("b:\n"); fmpz_mod_poly_print(b); flint_printf("\n"); + flint_printf("c:\n"); fmpz_mod_poly_print(c); flint_printf("\n"); + flint_printf("d:\n"); fmpz_mod_poly_print(d); flint_printf("\n"); + abort(); + } + + fmpz_clear(p); + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(c); + fmpz_mod_poly_clear(d); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/test/t-derivative.c b/external/flint-2.4.3/fmpz_mod_poly/test/t-derivative.c new file mode 100644 index 0000000..7b89a0e --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/test/t-derivative.c @@ -0,0 +1,163 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2010 Sebastian Pancratz + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("derivative...."); + fflush(stdout); + + + + /* Check aliasing */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, c; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + fmpz_mod_poly_set(b, a); + + fmpz_mod_poly_derivative(c, b); + fmpz_mod_poly_derivative(b, b); + + result = (fmpz_mod_poly_equal(b, c)); + if (!result) + { + flint_printf("FAIL (alias):\n"); + fmpz_mod_poly_print(a), flint_printf("\n\n"); + fmpz_mod_poly_print(b), flint_printf("\n\n"); + fmpz_mod_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(c); + fmpz_clear(p); + } + + /* Check constants have derivative zero */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_randtest(a, state, n_randint(state, 2)); + + fmpz_mod_poly_derivative(b, a); + + result = (b->length == 0); + if (!result) + { + flint_printf("FAIL (da == 0):\n"); + fmpz_mod_poly_print(a), flint_printf("\n\n"); + fmpz_mod_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_clear(p); + } + + /* Check (f g)' = f' g + f g' */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, c, d, lhs, rhs; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + fmpz_mod_poly_init(d, p); + fmpz_mod_poly_init(lhs, p); + fmpz_mod_poly_init(rhs, p); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + fmpz_mod_poly_randtest(b, state, n_randint(state, 100)); + + fmpz_mod_poly_mul(lhs, a, b); + fmpz_mod_poly_derivative(lhs, lhs); + fmpz_mod_poly_derivative(c, a); + fmpz_mod_poly_derivative(d, b); + fmpz_mod_poly_mul(c, c, b); + fmpz_mod_poly_mul(d, a, d); + fmpz_mod_poly_add(rhs, c, d); + + result = fmpz_mod_poly_equal(lhs, rhs); + if (!result) + { + flint_printf("FAIL (Leibniz):\n"); + flint_printf("a = "), fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_mod_poly_print(b), flint_printf("\n\n"); + flint_printf("(ab)' = "), fmpz_mod_poly_print(lhs), flint_printf("\n\n"); + flint_printf("a'b + ab' = "), fmpz_mod_poly_print(rhs), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(c); + fmpz_mod_poly_clear(d); + fmpz_mod_poly_clear(lhs); + fmpz_mod_poly_clear(rhs); + fmpz_clear(p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/test/t-div_basecase.c b/external/flint-2.4.3/fmpz_mod_poly/test/t-div_basecase.c new file mode 100644 index 0000000..50aaaad --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/test/t-div_basecase.c @@ -0,0 +1,206 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("div_basecase...."); + fflush(stdout); + + + + /* Compare to divrem_basecase */ + for (i = 0; i < 5000; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, q, q2, r2; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(q, p); + fmpz_mod_poly_init(q2, p); + fmpz_mod_poly_init(r2, p); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + fmpz_mod_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1); + + { + fmpz_t d; + fmpz *leadB = fmpz_mod_poly_lead(b); + + fmpz_init(d); + fmpz_gcd(d, p, leadB); + while (!fmpz_is_one(d)) + { + fmpz_divexact(leadB, leadB, d); + fmpz_gcd(d, p, leadB); + } + fmpz_clear(d); + } + + fmpz_mod_poly_div_basecase(q, a, b); + fmpz_mod_poly_divrem_basecase(q2, r2, a, b); + + result = (fmpz_mod_poly_equal(q, q2)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("p = "), fmpz_print(p), flint_printf("\n\n"); + flint_printf("a = "), fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_mod_poly_print(b), flint_printf("\n\n"); + flint_printf("q = "), fmpz_mod_poly_print(q), flint_printf("\n\n"); + flint_printf("q2 = "), fmpz_mod_poly_print(q2), flint_printf("\n\n"); + flint_printf("r2 = "), fmpz_mod_poly_print(r2), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(q); + fmpz_mod_poly_clear(q2); + fmpz_mod_poly_clear(r2); + fmpz_clear(p); + } + + /* Alias a and q */ + for (i = 0; i < 500; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, q; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(q, p); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + fmpz_mod_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1); + + { + fmpz_t d; + fmpz *leadB = fmpz_mod_poly_lead(b); + + fmpz_init(d); + fmpz_gcd(d, p, leadB); + while (!fmpz_is_one(d)) + { + fmpz_divexact(leadB, leadB, d); + fmpz_gcd(d, p, leadB); + } + fmpz_clear(d); + } + + fmpz_mod_poly_div_basecase(q, a, b); + fmpz_mod_poly_div_basecase(a, a, b); + + result = (fmpz_mod_poly_equal(q, a)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("p = "), fmpz_print(p), flint_printf("\n\n"); + flint_printf("a = "), fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_mod_poly_print(b), flint_printf("\n\n"); + flint_printf("q = "), fmpz_mod_poly_print(q), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(q); + fmpz_clear(p); + } + + /* Alias b and q */ + for (i = 0; i < 500; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, q; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(q, p); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + fmpz_mod_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1); + + { + fmpz_t d; + fmpz *leadB = fmpz_mod_poly_lead(b); + + fmpz_init(d); + fmpz_gcd(d, p, leadB); + while (!fmpz_is_one(d)) + { + fmpz_divexact(leadB, leadB, d); + fmpz_gcd(d, p, leadB); + } + fmpz_clear(d); + } + + fmpz_mod_poly_div_basecase(q, a, b); + fmpz_mod_poly_div_basecase(b, a, b); + + result = (fmpz_mod_poly_equal(q, b)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("p = "), fmpz_print(p), flint_printf("\n\n"); + flint_printf("a = "), fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_mod_poly_print(b), flint_printf("\n\n"); + flint_printf("q = "), fmpz_mod_poly_print(q), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(q); + fmpz_clear(p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/test/t-div_newton_n_preinv.c b/external/flint-2.4.3/fmpz_mod_poly/test/t-div_newton_n_preinv.c new file mode 100644 index 0000000..ac4ef68 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/test/t-div_newton_n_preinv.c @@ -0,0 +1,297 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2009 William Hart + Copyright (C) 2013 Martin Lee + +******************************************************************************/ + +#undef ulong +#define ulong ulongxx/* interferes with system includes */ + +#include +#include + +#undef ulong + +#include + +#define ulong mp_limb_t + +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("div_newton_n_preinv...."); + fflush(stdout); + + + + /* Compare to div_basecase */ + for (i = 0; i < 5000; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, q, q2, binv; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(binv, p); + fmpz_mod_poly_init(q, p); + fmpz_mod_poly_init(q2, p); + do + fmpz_mod_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1); + while (b->length <= 2); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + if (a->length > 2*(b->length)-3) + fmpz_mod_poly_truncate (a, 2*(b->length)-3); + + { + fmpz_t d; + fmpz *leadB = fmpz_mod_poly_lead(b); + + fmpz_init(d); + fmpz_gcd(d, p, leadB); + while (!fmpz_is_one(d)) + { + fmpz_divexact(leadB, leadB, d); + fmpz_gcd(d, p, leadB); + } + fmpz_clear(d); + } + + fmpz_mod_poly_reverse (binv, b, b->length); + fmpz_mod_poly_inv_series_newton (binv, binv, b->length); + fmpz_mod_poly_div_basecase(q, a, b); + fmpz_mod_poly_div_newton_n_preinv(q2, a, b, binv); + + result = (fmpz_mod_poly_equal(q, q2)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("p = "), fmpz_print(p), flint_printf("\n\n"); + flint_printf("a = "), fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_mod_poly_print(b), flint_printf("\n\n"); + flint_printf("q = "), fmpz_mod_poly_print(q), flint_printf("\n\n"); + flint_printf("q2 = "), fmpz_mod_poly_print(q2), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(binv); + fmpz_mod_poly_clear(q); + fmpz_mod_poly_clear(q2); + fmpz_clear(p); + } + + /* Alias a and q */ + for (i = 0; i < 500; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, q, binv; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(binv, p); + fmpz_mod_poly_init(q, p); + do + fmpz_mod_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1); + while (b->length <= 2); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + if (a->length > 2*(b->length)-3) + fmpz_mod_poly_truncate (a, 2*(b->length)-3); + + { + fmpz_t d; + fmpz *leadB = fmpz_mod_poly_lead(b); + + fmpz_init(d); + fmpz_gcd(d, p, leadB); + while (!fmpz_is_one(d)) + { + fmpz_divexact(leadB, leadB, d); + fmpz_gcd(d, p, leadB); + } + fmpz_clear(d); + } + + fmpz_mod_poly_reverse (binv, b, b->length); + fmpz_mod_poly_inv_series_newton (binv, binv, b->length); + fmpz_mod_poly_div_newton_n_preinv(q, a, b, binv); + fmpz_mod_poly_div_newton_n_preinv(a, a, b, binv); + + result = (fmpz_mod_poly_equal(q, a)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("p = "), fmpz_print(p), flint_printf("\n\n"); + flint_printf("a = "), fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_mod_poly_print(b), flint_printf("\n\n"); + flint_printf("q = "), fmpz_mod_poly_print(q), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(binv); + fmpz_mod_poly_clear(q); + fmpz_clear(p); + } + + /* Alias b and q */ + for (i = 0; i < 500; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, q, binv; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(binv, p); + fmpz_mod_poly_init(q, p); + do + fmpz_mod_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1); + while (b->length <= 2); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + if (a->length > 2*(b->length)-3) + fmpz_mod_poly_truncate (a, 2*(b->length)-3); + + { + fmpz_t d; + fmpz *leadB = fmpz_mod_poly_lead(b); + + fmpz_init(d); + fmpz_gcd(d, p, leadB); + while (!fmpz_is_one(d)) + { + fmpz_divexact(leadB, leadB, d); + fmpz_gcd(d, p, leadB); + } + fmpz_clear(d); + } + + fmpz_mod_poly_reverse (binv, b, b->length); + fmpz_mod_poly_inv_series_newton (binv, binv, b->length); + fmpz_mod_poly_div_newton_n_preinv(q, a, b, binv); + fmpz_mod_poly_div_newton_n_preinv(b, a, b, binv); + + result = (fmpz_mod_poly_equal(q, b)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("p = "), fmpz_print(p), flint_printf("\n\n"); + flint_printf("a = "), fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_mod_poly_print(b), flint_printf("\n\n"); + flint_printf("q = "), fmpz_mod_poly_print(q), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(binv); + fmpz_mod_poly_clear(q); + fmpz_clear(p); + } + + + /* Alias binv and q */ + for (i = 0; i < 500; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, q, binv; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(binv, p); + fmpz_mod_poly_init(q, p); + do + fmpz_mod_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1); + while (b->length <= 2); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + if (a->length > 2*(b->length)-3) + fmpz_mod_poly_truncate (a, 2*(b->length)-3); + + { + fmpz_t d; + fmpz *leadB = fmpz_mod_poly_lead(b); + + fmpz_init(d); + fmpz_gcd(d, p, leadB); + while (!fmpz_is_one(d)) + { + fmpz_divexact(leadB, leadB, d); + fmpz_gcd(d, p, leadB); + } + fmpz_clear(d); + } + + fmpz_mod_poly_reverse (binv, b, b->length); + fmpz_mod_poly_inv_series_newton (binv, binv, b->length); + fmpz_mod_poly_div_newton_n_preinv(q, a, b, binv); + fmpz_mod_poly_div_newton_n_preinv(binv, a, b, binv); + + result = (fmpz_mod_poly_equal(q, binv)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("p = "), fmpz_print(p), flint_printf("\n\n"); + flint_printf("a = "), fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_mod_poly_print(b), flint_printf("\n\n"); + flint_printf("binv = "), fmpz_mod_poly_print(binv), flint_printf("\n\n"); + flint_printf("q = "), fmpz_mod_poly_print(q), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(binv); + fmpz_mod_poly_clear(q); + fmpz_clear(p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/test/t-divrem_basecase.c b/external/flint-2.4.3/fmpz_mod_poly/test/t-divrem_basecase.c new file mode 100644 index 0000000..91e7ba0 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/test/t-divrem_basecase.c @@ -0,0 +1,213 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("divrem_basecase...."); + fflush(stdout); + + + + /* Check q*b + r = a, no aliasing */ + for (i = 0; i < 5000; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, q, r, t; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(q, p); + fmpz_mod_poly_init(r, p); + fmpz_mod_poly_init(t, p); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + fmpz_mod_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1); + + { + fmpz_t d; + fmpz *leadB = fmpz_mod_poly_lead(b); + + fmpz_init(d); + fmpz_gcd(d, p, leadB); + while (!fmpz_is_one(d)) + { + fmpz_divexact(leadB, leadB, d); + fmpz_gcd(d, p, leadB); + } + fmpz_clear(d); + } + + fmpz_mod_poly_divrem_basecase(q, r, a, b); + fmpz_mod_poly_mul(t, q, b); + fmpz_mod_poly_add(t, t, r); + + result = (fmpz_mod_poly_equal(a, t)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("p = "), fmpz_print(p), flint_printf("\n\n"); + flint_printf("a = "), fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_mod_poly_print(b), flint_printf("\n\n"); + flint_printf("q = "), fmpz_mod_poly_print(q), flint_printf("\n\n"); + flint_printf("r = "), fmpz_mod_poly_print(r), flint_printf("\n\n"); + flint_printf("t = "), fmpz_mod_poly_print(t), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(q); + fmpz_mod_poly_clear(r); + fmpz_mod_poly_clear(t); + fmpz_clear(p); + } + + /* Alias a and q, b and r */ + for (i = 0; i < 500; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, q, r; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(q, p); + fmpz_mod_poly_init(r, p); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + fmpz_mod_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1); + + { + fmpz_t d; + fmpz *leadB = fmpz_mod_poly_lead(b); + + fmpz_init(d); + fmpz_gcd(d, p, leadB); + while (!fmpz_is_one(d)) + { + fmpz_divexact(leadB, leadB, d); + fmpz_gcd(d, p, leadB); + } + fmpz_clear(d); + } + + fmpz_mod_poly_divrem_basecase(q, r, a, b); + fmpz_mod_poly_divrem_basecase(a, b, a, b); + + result = (fmpz_mod_poly_equal(q, a) && fmpz_mod_poly_equal(r, b)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("p = "), fmpz_print(p), flint_printf("\n\n"); + flint_printf("a = "), fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_mod_poly_print(b), flint_printf("\n\n"); + flint_printf("q = "), fmpz_mod_poly_print(q), flint_printf("\n\n"); + flint_printf("r = "), fmpz_mod_poly_print(r), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(q); + fmpz_mod_poly_clear(r); + fmpz_clear(p); + } + + /* Alias b and q, a and r */ + for (i = 0; i < 500; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, q, r; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(q, p); + fmpz_mod_poly_init(r, p); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + fmpz_mod_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1); + + { + fmpz_t d; + fmpz *leadB = fmpz_mod_poly_lead(b); + + fmpz_init(d); + fmpz_gcd(d, p, leadB); + while (!fmpz_is_one(d)) + { + fmpz_divexact(leadB, leadB, d); + fmpz_gcd(d, p, leadB); + } + fmpz_clear(d); + } + + fmpz_mod_poly_divrem_basecase(q, r, a, b); + fmpz_mod_poly_divrem_basecase(b, a, a, b); + + result = (fmpz_mod_poly_equal(q, b) && fmpz_mod_poly_equal(r, a)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("p = "), fmpz_print(p), flint_printf("\n\n"); + flint_printf("a = "), fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_mod_poly_print(b), flint_printf("\n\n"); + flint_printf("q = "), fmpz_mod_poly_print(q), flint_printf("\n\n"); + flint_printf("r = "), fmpz_mod_poly_print(r), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(q); + fmpz_mod_poly_clear(r); + fmpz_clear(p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/test/t-divrem_divconquer.c b/external/flint-2.4.3/fmpz_mod_poly/test/t-divrem_divconquer.c new file mode 100644 index 0000000..f2c2e83 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/test/t-divrem_divconquer.c @@ -0,0 +1,213 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("divrem_divconquer...."); + fflush(stdout); + + + + /* Check q*b + r = a, no aliasing */ + for (i = 0; i < 5000; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, q, r, t; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(q, p); + fmpz_mod_poly_init(r, p); + fmpz_mod_poly_init(t, p); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + fmpz_mod_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1); + + { + fmpz_t d; + fmpz *leadB = fmpz_mod_poly_lead(b); + + fmpz_init(d); + fmpz_gcd(d, p, leadB); + while (!fmpz_is_one(d)) + { + fmpz_divexact(leadB, leadB, d); + fmpz_gcd(d, p, leadB); + } + fmpz_clear(d); + } + + fmpz_mod_poly_divrem_divconquer(q, r, a, b); + fmpz_mod_poly_mul(t, q, b); + fmpz_mod_poly_add(t, t, r); + + result = (fmpz_mod_poly_equal(a, t)); + if (!result) + { + flint_printf("FAIL #1:\n"); + flint_printf("p = "), fmpz_print(p), flint_printf("\n\n"); + flint_printf("a = "), fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_mod_poly_print(b), flint_printf("\n\n"); + flint_printf("q = "), fmpz_mod_poly_print(q), flint_printf("\n\n"); + flint_printf("r = "), fmpz_mod_poly_print(r), flint_printf("\n\n"); + flint_printf("t = "), fmpz_mod_poly_print(t), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(q); + fmpz_mod_poly_clear(r); + fmpz_mod_poly_clear(t); + fmpz_clear(p); + } + + /* Alias a and q, b and r */ + for (i = 0; i < 500; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, q, r; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(q, p); + fmpz_mod_poly_init(r, p); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + fmpz_mod_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1); + + { + fmpz_t d; + fmpz *leadB = fmpz_mod_poly_lead(b); + + fmpz_init(d); + fmpz_gcd(d, p, leadB); + while (!fmpz_is_one(d)) + { + fmpz_divexact(leadB, leadB, d); + fmpz_gcd(d, p, leadB); + } + fmpz_clear(d); + } + + fmpz_mod_poly_divrem_divconquer(q, r, a, b); + fmpz_mod_poly_divrem_divconquer(a, b, a, b); + + result = (fmpz_mod_poly_equal(q, a) && fmpz_mod_poly_equal(r, b)); + if (!result) + { + flint_printf("FAIL #2:\n"); + flint_printf("p = "), fmpz_print(p), flint_printf("\n\n"); + flint_printf("a = "), fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_mod_poly_print(b), flint_printf("\n\n"); + flint_printf("q = "), fmpz_mod_poly_print(q), flint_printf("\n\n"); + flint_printf("r = "), fmpz_mod_poly_print(r), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(q); + fmpz_mod_poly_clear(r); + fmpz_clear(p); + } + + /* Alias b and q, a and r */ + for (i = 0; i < 500; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, q, r; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(q, p); + fmpz_mod_poly_init(r, p); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + fmpz_mod_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1); + + { + fmpz_t d; + fmpz *leadB = fmpz_mod_poly_lead(b); + + fmpz_init(d); + fmpz_gcd(d, p, leadB); + while (!fmpz_is_one(d)) + { + fmpz_divexact(leadB, leadB, d); + fmpz_gcd(d, p, leadB); + } + fmpz_clear(d); + } + + fmpz_mod_poly_divrem_divconquer(q, r, a, b); + fmpz_mod_poly_divrem_divconquer(b, a, a, b); + + result = (fmpz_mod_poly_equal(q, b) && fmpz_mod_poly_equal(r, a)); + if (!result) + { + flint_printf("FAIL #3:\n"); + flint_printf("p = "), fmpz_print(p), flint_printf("\n\n"); + flint_printf("a = "), fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_mod_poly_print(b), flint_printf("\n\n"); + flint_printf("q = "), fmpz_mod_poly_print(q), flint_printf("\n\n"); + flint_printf("r = "), fmpz_mod_poly_print(r), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(q); + fmpz_mod_poly_clear(r); + fmpz_clear(p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/test/t-divrem_f.c b/external/flint-2.4.3/fmpz_mod_poly/test/t-divrem_f.c new file mode 100644 index 0000000..0cf5f86 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/test/t-divrem_f.c @@ -0,0 +1,176 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("divrem_f...."); + fflush(stdout); + + + + /* Check q*b + r = a when gcd(lead(B),p) = 1, no aliasing */ + for (i = 0; i < 5000; i++) + { + fmpz_t f, p; + fmpz_mod_poly_t a, b, q, r, t; + + fmpz_init(f); + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(q, p); + fmpz_mod_poly_init(r, p); + fmpz_mod_poly_init(t, p); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + fmpz_mod_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1); + + { + fmpz_t d; + fmpz *leadB = fmpz_mod_poly_lead(b); + + fmpz_init(d); + fmpz_gcd(d, p, leadB); + while (!fmpz_is_one(d)) + { + fmpz_divexact(leadB, leadB, d); + fmpz_gcd(d, p, leadB); + } + fmpz_clear(d); + } + + fmpz_mod_poly_divrem_f(f, q, r, a, b); + fmpz_mod_poly_mul(t, q, b); + fmpz_mod_poly_add(t, t, r); + + result = (fmpz_is_one(f) && fmpz_mod_poly_equal(a, t)); + if (!result) + { + flint_printf("FAIL (divrem):\n"); + flint_printf("p = "), fmpz_print(p), flint_printf("\n\n"); + flint_printf("f = "), fmpz_print(f), flint_printf("\n\n"); + flint_printf("a = "), fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_mod_poly_print(b), flint_printf("\n\n"); + flint_printf("q = "), fmpz_mod_poly_print(q), flint_printf("\n\n"); + flint_printf("r = "), fmpz_mod_poly_print(r), flint_printf("\n\n"); + flint_printf("t = "), fmpz_mod_poly_print(t), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(q); + fmpz_mod_poly_clear(r); + fmpz_mod_poly_clear(t); + fmpz_clear(f); + fmpz_clear(p); + } + + /* Check f | p when gcd(lead(B),p) > 1 */ + for (i = 0; i < 5000; i++) + { + fmpz_t f, p, q1, q2; + fmpz_mod_poly_t a, b, q, r, t; + + fmpz_init(f); + fmpz_init(p); + fmpz_init(q1); + fmpz_init(q2); + fmpz_randtest_unsigned(q1, state, 2 * FLINT_BITS); + fmpz_randtest_unsigned(q2, state, 2 * FLINT_BITS); + fmpz_add_ui(q1, q1, 2); + fmpz_add_ui(q2, q2, 2); + fmpz_mul(p, q1, q2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(q, p); + fmpz_mod_poly_init(r, p); + fmpz_mod_poly_init(t, p); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + fmpz_mod_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1); + + { + fmpz_t d; + fmpz *leadB = fmpz_mod_poly_lead(b); + + fmpz_init(d); + fmpz_gcd(d, p, leadB); + if (fmpz_is_one(d)) + fmpz_set(leadB, q1); + fmpz_clear(d); + } + + fmpz_mod_poly_divrem_f(f, q, r, a, b); + fmpz_mod_poly_mul(t, q, b); + fmpz_mod_poly_add(t, t, r); + + result = (fmpz_cmp_ui(f, 1) > 0 && fmpz_cmp(f, p) < 0 && fmpz_divisible(p, f)); + if (!result) + { + flint_printf("FAIL (factor):\n"); + flint_printf("p = "), fmpz_print(p), flint_printf("\n\n"); + flint_printf("f = "), fmpz_print(f), flint_printf("\n\n"); + flint_printf("q1 = "), fmpz_print(q1), flint_printf("\n\n"); + flint_printf("q2 = "), fmpz_print(q2), flint_printf("\n\n"); + flint_printf("a = "), fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_mod_poly_print(b), flint_printf("\n\n"); + flint_printf("q = "), fmpz_mod_poly_print(q), flint_printf("\n\n"); + flint_printf("r = "), fmpz_mod_poly_print(r), flint_printf("\n\n"); + flint_printf("t = "), fmpz_mod_poly_print(t), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(q); + fmpz_mod_poly_clear(r); + fmpz_mod_poly_clear(t); + fmpz_clear(f); + fmpz_clear(p); + fmpz_clear(q1); + fmpz_clear(q2); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/test/t-divrem_newton_n_preinv.c b/external/flint-2.4.3/fmpz_mod_poly/test/t-divrem_newton_n_preinv.c new file mode 100644 index 0000000..bd3b9f0 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/test/t-divrem_newton_n_preinv.c @@ -0,0 +1,521 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2009 William Hart + Copyright (C) 2013 Martin Lee + +******************************************************************************/ + +#undef ulong +#define ulong ulongxx/* interferes with system includes */ + +#include +#include + +#undef ulong + +#include + +#define ulong mp_limb_t + +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("divrem_newton_n_preinv...."); + fflush(stdout); + + + + /* Check q*b + r = a, no aliasing */ + for (i = 0; i < 5000; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, binv, q, r, t, q2, r2; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(binv, p); + fmpz_mod_poly_init(q, p); + fmpz_mod_poly_init(q2, p); + fmpz_mod_poly_init(r, p); + fmpz_mod_poly_init(r2, p); + fmpz_mod_poly_init(t, p); + do + fmpz_mod_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1); + while (b->length <= 2); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + if (a->length > 2*(b->length)-3) + fmpz_mod_poly_truncate (a, 2*(b->length)-3); + + { + fmpz_t d; + fmpz *leadB = fmpz_mod_poly_lead(b); + + fmpz_init(d); + fmpz_gcd(d, p, leadB); + while (!fmpz_is_one(d)) + { + fmpz_divexact(leadB, leadB, d); + fmpz_gcd(d, p, leadB); + } + fmpz_clear(d); + } + + fmpz_mod_poly_reverse (binv, b, b->length); + fmpz_mod_poly_inv_series_newton (binv, binv, b->length); + + fmpz_mod_poly_divrem_newton_n_preinv (q, r, a, b, binv); + fmpz_mod_poly_mul(t, q, b); + fmpz_mod_poly_add(t, t, r); + + result = (fmpz_mod_poly_equal(a, t)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("p = "), fmpz_print(p), flint_printf("\n\n"); + flint_printf("a = "), fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_mod_poly_print(b), flint_printf("\n\n"); + flint_printf("q = "), fmpz_mod_poly_print(q), flint_printf("\n\n"); + flint_printf("r = "), fmpz_mod_poly_print(r), flint_printf("\n\n"); + flint_printf("t = "), fmpz_mod_poly_print(t), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_divrem_basecase(q2, r2, a, b); + result = (fmpz_mod_poly_equal(q2, q)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("p = "), fmpz_print(p), flint_printf("\n\n"); + flint_printf("a = "), fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_mod_poly_print(b), flint_printf("\n\n"); + flint_printf("q = "), fmpz_mod_poly_print(q), flint_printf("\n\n"); + flint_printf("q2 = "), fmpz_mod_poly_print(q2), flint_printf("\n\n"); + flint_printf("r = "), fmpz_mod_poly_print(r), flint_printf("\n\n"); + flint_printf("t = "), fmpz_mod_poly_print(t), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(binv); + fmpz_mod_poly_clear(q); + fmpz_mod_poly_clear(q2); + fmpz_mod_poly_clear(r); + fmpz_mod_poly_clear(r2); + fmpz_mod_poly_clear(t); + fmpz_clear(p); + } + + /* Alias a and q, b and r */ + for (i = 0; i < 500; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, binv, q, r; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(binv, p); + fmpz_mod_poly_init(q, p); + fmpz_mod_poly_init(r, p); + do + fmpz_mod_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1); + while (b->length <= 2); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + if (a->length > 2*(b->length)-3) + fmpz_mod_poly_truncate (a, 2*(b->length)-3); + + { + fmpz_t d; + fmpz *leadB = fmpz_mod_poly_lead(b); + + fmpz_init(d); + fmpz_gcd(d, p, leadB); + while (!fmpz_is_one(d)) + { + fmpz_divexact(leadB, leadB, d); + fmpz_gcd(d, p, leadB); + } + fmpz_clear(d); + } + + fmpz_mod_poly_reverse (binv, b, b->length); + fmpz_mod_poly_inv_series_newton (binv, binv, b->length); + + fmpz_mod_poly_divrem_newton_n_preinv(q, r, a, b, binv); + fmpz_mod_poly_divrem_newton_n_preinv(a, b, a, b, binv); + + result = (fmpz_mod_poly_equal(q, a) && fmpz_mod_poly_equal(r, b)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("p = "), fmpz_print(p), flint_printf("\n\n"); + flint_printf("a = "), fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_mod_poly_print(b), flint_printf("\n\n"); + flint_printf("q = "), fmpz_mod_poly_print(q), flint_printf("\n\n"); + flint_printf("r = "), fmpz_mod_poly_print(r), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(binv); + fmpz_mod_poly_clear(q); + fmpz_mod_poly_clear(r); + fmpz_clear(p); + } + + /* Alias b and q, a and r */ + for (i = 0; i < 500; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, binv, q, r; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(binv, p); + fmpz_mod_poly_init(q, p); + fmpz_mod_poly_init(r, p); + do + fmpz_mod_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1); + while (b->length <= 2); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + if (a->length > 2*(b->length)-3) + fmpz_mod_poly_truncate (a, 2*(b->length)-3); + + { + fmpz_t d; + fmpz *leadB = fmpz_mod_poly_lead(b); + + fmpz_init(d); + fmpz_gcd(d, p, leadB); + while (!fmpz_is_one(d)) + { + fmpz_divexact(leadB, leadB, d); + fmpz_gcd(d, p, leadB); + } + fmpz_clear(d); + } + + fmpz_mod_poly_reverse (binv, b, b->length); + fmpz_mod_poly_inv_series_newton (binv, binv, b->length); + + fmpz_mod_poly_divrem_newton_n_preinv(q, r, a, b, binv); + fmpz_mod_poly_divrem_newton_n_preinv(b, a, a, b, binv); + + result = (fmpz_mod_poly_equal(q, b) && fmpz_mod_poly_equal(r, a)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("p = "), fmpz_print(p), flint_printf("\n\n"); + flint_printf("a = "), fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_mod_poly_print(b), flint_printf("\n\n"); + flint_printf("q = "), fmpz_mod_poly_print(q), flint_printf("\n\n"); + flint_printf("r = "), fmpz_mod_poly_print(r), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(binv); + fmpz_mod_poly_clear(q); + fmpz_mod_poly_clear(r); + fmpz_clear(p); + } + + /* Alias binv and q, a and r*/ + for (i = 0; i < 500; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, binv, q, r; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(binv, p); + fmpz_mod_poly_init(q, p); + fmpz_mod_poly_init(r, p); + do + fmpz_mod_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1); + while (b->length <= 2); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + if (a->length > 2*(b->length)-3) + fmpz_mod_poly_truncate (a, 2*(b->length)-3); + + { + fmpz_t d; + fmpz *leadB = fmpz_mod_poly_lead(b); + + fmpz_init(d); + fmpz_gcd(d, p, leadB); + while (!fmpz_is_one(d)) + { + fmpz_divexact(leadB, leadB, d); + fmpz_gcd(d, p, leadB); + } + fmpz_clear(d); + } + + fmpz_mod_poly_reverse (binv, b, b->length); + fmpz_mod_poly_inv_series_newton (binv, binv, b->length); + + fmpz_mod_poly_divrem_newton_n_preinv(q, r, a, b, binv); + fmpz_mod_poly_divrem_newton_n_preinv(binv, a, a, b, binv); + + result = (fmpz_mod_poly_equal(q, binv) && fmpz_mod_poly_equal(r, a)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("p = "), fmpz_print(p), flint_printf("\n\n"); + flint_printf("a = "), fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_mod_poly_print(b), flint_printf("\n\n"); + flint_printf("binv = "), fmpz_mod_poly_print(binv), flint_printf("\n\n"); + flint_printf("q = "), fmpz_mod_poly_print(q), flint_printf("\n\n"); + flint_printf("r = "), fmpz_mod_poly_print(r), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(binv); + fmpz_mod_poly_clear(q); + fmpz_mod_poly_clear(r); + fmpz_clear(p); + } + + /* Alias binv and q, b and r*/ + for (i = 0; i < 500; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, binv, q, r; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(binv, p); + fmpz_mod_poly_init(q, p); + fmpz_mod_poly_init(r, p); + do + fmpz_mod_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1); + while (b->length <= 2); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + if (a->length > 2*(b->length)-3) + fmpz_mod_poly_truncate (a, 2*(b->length)-3); + + { + fmpz_t d; + fmpz *leadB = fmpz_mod_poly_lead(b); + + fmpz_init(d); + fmpz_gcd(d, p, leadB); + while (!fmpz_is_one(d)) + { + fmpz_divexact(leadB, leadB, d); + fmpz_gcd(d, p, leadB); + } + fmpz_clear(d); + } + + fmpz_mod_poly_reverse (binv, b, b->length); + fmpz_mod_poly_inv_series_newton (binv, binv, b->length); + + fmpz_mod_poly_divrem_newton_n_preinv(q, r, a, b, binv); + fmpz_mod_poly_divrem_newton_n_preinv(binv, b, a, b, binv); + + result = (fmpz_mod_poly_equal(q, binv) && fmpz_mod_poly_equal(r, b)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("p = "), fmpz_print(p), flint_printf("\n\n"); + flint_printf("a = "), fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_mod_poly_print(b), flint_printf("\n\n"); + flint_printf("binv = "), fmpz_mod_poly_print(binv), flint_printf("\n\n"); + flint_printf("q = "), fmpz_mod_poly_print(q), flint_printf("\n\n"); + flint_printf("r = "), fmpz_mod_poly_print(r), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(binv); + fmpz_mod_poly_clear(q); + fmpz_mod_poly_clear(r); + fmpz_clear(p); + } + + /* Alias a and q, binv and r*/ + for (i = 0; i < 500; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, binv, q, r; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(binv, p); + fmpz_mod_poly_init(q, p); + fmpz_mod_poly_init(r, p); + do + fmpz_mod_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1); + while (b->length <= 2); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + if (a->length > 2*(b->length)-3) + fmpz_mod_poly_truncate (a, 2*(b->length)-3); + + { + fmpz_t d; + fmpz *leadB = fmpz_mod_poly_lead(b); + + fmpz_init(d); + fmpz_gcd(d, p, leadB); + while (!fmpz_is_one(d)) + { + fmpz_divexact(leadB, leadB, d); + fmpz_gcd(d, p, leadB); + } + fmpz_clear(d); + } + + fmpz_mod_poly_reverse (binv, b, b->length); + fmpz_mod_poly_inv_series_newton (binv, binv, b->length); + + fmpz_mod_poly_divrem_newton_n_preinv(q, r, a, b, binv); + fmpz_mod_poly_divrem_newton_n_preinv(a, binv, a, b, binv); + + result = (fmpz_mod_poly_equal(q, a) && fmpz_mod_poly_equal(r, binv)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("p = "), fmpz_print(p), flint_printf("\n\n"); + flint_printf("a = "), fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_mod_poly_print(b), flint_printf("\n\n"); + flint_printf("binv = "), fmpz_mod_poly_print(binv), flint_printf("\n\n"); + flint_printf("q = "), fmpz_mod_poly_print(q), flint_printf("\n\n"); + flint_printf("r = "), fmpz_mod_poly_print(r), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(binv); + fmpz_mod_poly_clear(q); + fmpz_mod_poly_clear(r); + fmpz_clear(p); + } + + /* Alias b and q, binv and r*/ + for (i = 0; i < 500; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, binv, q, r; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(binv, p); + fmpz_mod_poly_init(q, p); + fmpz_mod_poly_init(r, p); + do + fmpz_mod_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1); + while (b->length <= 2); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + if (a->length > 2*(b->length)-3) + fmpz_mod_poly_truncate (a, 2*(b->length)-3); + + { + fmpz_t d; + fmpz *leadB = fmpz_mod_poly_lead(b); + + fmpz_init(d); + fmpz_gcd(d, p, leadB); + while (!fmpz_is_one(d)) + { + fmpz_divexact(leadB, leadB, d); + fmpz_gcd(d, p, leadB); + } + fmpz_clear(d); + } + + fmpz_mod_poly_reverse (binv, b, b->length); + fmpz_mod_poly_inv_series_newton (binv, binv, b->length); + + fmpz_mod_poly_divrem_newton_n_preinv(q, r, a, b, binv); + fmpz_mod_poly_divrem_newton_n_preinv(b, binv, a, b, binv); + + result = (fmpz_mod_poly_equal(q, b) && fmpz_mod_poly_equal(r, binv)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("p = "), fmpz_print(p), flint_printf("\n\n"); + flint_printf("a = "), fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_mod_poly_print(b), flint_printf("\n\n"); + flint_printf("binv = "), fmpz_mod_poly_print(binv), flint_printf("\n\n"); + flint_printf("q = "), fmpz_mod_poly_print(q), flint_printf("\n\n"); + flint_printf("r = "), fmpz_mod_poly_print(r), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(binv); + fmpz_mod_poly_clear(q); + fmpz_mod_poly_clear(r); + fmpz_clear(p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/test/t-evaluate_fmpz.c b/external/flint-2.4.3/fmpz_mod_poly/test/t-evaluate_fmpz.c new file mode 100644 index 0000000..a4f4cfc --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/test/t-evaluate_fmpz.c @@ -0,0 +1,130 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2010 Sebastian Pancratz + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("evaluate_fmpz...."); + fflush(stdout); + + + + /* Check aliasing */ + for (i = 0; i < 10000; i++) + { + fmpz_t a, b, p; + fmpz_mod_poly_t f; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_init(a); + fmpz_init(b); + fmpz_randm(a, state, p); + fmpz_mod_poly_init(f, p); + fmpz_mod_poly_randtest(f, state, n_randint(state, 100)); + + fmpz_mod_poly_evaluate_fmpz(b, f, a); + fmpz_mod_poly_evaluate_fmpz(a, f, a); + + result = (fmpz_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_mod_poly_print(f), flint_printf("\n\n"); + fmpz_print(a), flint_printf("\n\n"); + fmpz_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(f); + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(p); + } + + /* Check that the result agrees with Z[X] */ + for (i = 0; i < 10000; i++) + { + fmpz_t a, b, c, p; + fmpz_mod_poly_t f; + fmpz_poly_t g; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + fmpz_mod_poly_init(f, p); + fmpz_poly_init(g); + fmpz_randm(a, state, p); + fmpz_mod_poly_randtest(f, state, n_randint(state, 100)); + fmpz_mod_poly_get_fmpz_poly(g, f); + + fmpz_mod_poly_evaluate_fmpz(b, f, a); + fmpz_poly_evaluate_fmpz(c, g, a); + fmpz_mod(c, c, p); + + result = (fmpz_equal(b, c)); + if (!result) + { + flint_printf("FAIL (cmp with fmpz_poly):\n"); + fmpz_mod_poly_print(f), flint_printf("\n\n"); + fmpz_poly_print(g), flint_printf("\n\n"); + fmpz_print(a), flint_printf("\n\n"); + fmpz_print(b), flint_printf("\n\n"); + fmpz_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + fmpz_clear(p); + fmpz_mod_poly_clear(f); + fmpz_poly_clear(g); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/test/t-evaluate_fmpz_vec_fast.c b/external/flint-2.4.3/fmpz_mod_poly/test/t-evaluate_fmpz_vec_fast.c new file mode 100644 index 0000000..151cd8e --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/test/t-evaluate_fmpz_vec_fast.c @@ -0,0 +1,106 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2012 William Hart + Copyright (C) 2011, 2012 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result = 1; + FLINT_TEST_INIT(state); + + + flint_printf("evaluate_fmpz_vec_fast...."); + fflush(stdout); + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_mod_poly_t P; + fmpz * x, * y, * z; + fmpz_t mod; + slong j, n, npoints; + + fmpz_init(mod); + + do + { + fmpz_randtest_unsigned(mod, state, 5); + fmpz_add_ui(mod, mod, 2); + } while (!fmpz_is_probabprime(mod)); + + npoints = n_randint(state, 10); + n = n_randint(state, 10); + + fmpz_mod_poly_init(P, mod); + x = _fmpz_vec_init(npoints); + y = _fmpz_vec_init(npoints); + z = _fmpz_vec_init(npoints); + + fmpz_mod_poly_randtest(P, state, n); + + for (j = 0; j < npoints; j++) + fmpz_randtest_mod(x + j, state, mod); + + fmpz_mod_poly_evaluate_fmpz_vec_iter(y, P, x, npoints); + fmpz_mod_poly_evaluate_fmpz_vec_fast(z, P, x, npoints); + + result = _fmpz_vec_equal(y, z, npoints); + + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("mod="); + fmpz_print(mod); + flint_printf(", n=%wd, npoints=%wd\n\n", n, npoints); + flint_printf("P: "); fmpz_mod_poly_print(P); flint_printf("\n\n"); + for (j = 0; j < npoints; j++) + fmpz_print(y + j), flint_printf(" "); + flint_printf("\n"); + for (j = 0; j < npoints; j++) + fmpz_print(z + j), flint_printf(" "); + flint_printf("\n"); + abort(); + } + + fmpz_clear(mod); + fmpz_mod_poly_clear(P); + _fmpz_vec_clear(x, npoints); + _fmpz_vec_clear(y, npoints); + _fmpz_vec_clear(z, npoints); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/test/t-gcd_euclidean.c b/external/flint-2.4.3/fmpz_mod_poly/test/t-gcd_euclidean.c new file mode 100644 index 0000000..769ab6f --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/test/t-gcd_euclidean.c @@ -0,0 +1,335 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("gcd_euclidean...."); + fflush(stdout); + + + + /* Generic case, most likely co-prime arguments ******************************/ + + /* Check aliasing of a and c */ + for (i = 0; i < 1000; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, c; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + fmpz_mod_poly_randtest(b, state, n_randint(state, 100)); + + fmpz_mod_poly_gcd_euclidean(c, a, b); + fmpz_mod_poly_gcd_euclidean(a, a, b); + + result = (fmpz_mod_poly_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_mod_poly_print(a), flint_printf("\n\n"); + fmpz_mod_poly_print(b), flint_printf("\n\n"); + fmpz_mod_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(c); + fmpz_clear(p); + } + + /* Check aliasing of b and c */ + for (i = 0; i < 1000; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, c; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + fmpz_mod_poly_randtest(b, state, n_randint(state, 100)); + + fmpz_mod_poly_gcd_euclidean(c, a, b); + fmpz_mod_poly_gcd_euclidean(b, a, b); + + result = (fmpz_mod_poly_equal(b, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_mod_poly_print(a), flint_printf("\n\n"); + fmpz_mod_poly_print(b), flint_printf("\n\n"); + fmpz_mod_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(c); + fmpz_clear(p); + } + + /* + Check that g = GCD(a,b) divides a and b, + and that 1 == GCD(a/g, b/g) + */ + for (i = 0; i < 500; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, c, d, g, h, s, t; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + fmpz_mod_poly_init(d, p); + fmpz_mod_poly_init(g, p); + fmpz_mod_poly_init(h, p); + fmpz_mod_poly_init(s, p); + fmpz_mod_poly_init(t, p); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + fmpz_mod_poly_randtest(b, state, n_randint(state, 100)); + + fmpz_mod_poly_gcd_euclidean(g, a, b); + + if (fmpz_mod_poly_is_zero(g)) + { + result = 1; + } + else + { + fmpz_mod_poly_divrem_basecase(c, s, a, g); + fmpz_mod_poly_divrem_basecase(d, t, b, g); + fmpz_mod_poly_gcd_euclidean(h, c, d); + + result = (fmpz_mod_poly_is_zero(s) && fmpz_mod_poly_is_zero(t) + && (h->length == 1) && (fmpz_is_one(h->coeffs))); + } + + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("p = "), fmpz_print(p), flint_printf("\n\n"); + flint_printf("a = "), fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_mod_poly_print(b), flint_printf("\n\n"); + flint_printf("c = "), fmpz_mod_poly_print(c), flint_printf("\n\n"); + flint_printf("d = "), fmpz_mod_poly_print(d), flint_printf("\n\n"); + flint_printf("g = "), fmpz_mod_poly_print(g), flint_printf("\n\n"); + flint_printf("h = "), fmpz_mod_poly_print(h), flint_printf("\n\n"); + flint_printf("s = "), fmpz_mod_poly_print(s), flint_printf("\n\n"); + flint_printf("t = "), fmpz_mod_poly_print(t), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(c); + fmpz_mod_poly_clear(d); + fmpz_mod_poly_clear(g); + fmpz_mod_poly_clear(h); + fmpz_mod_poly_clear(s); + fmpz_mod_poly_clear(t); + fmpz_clear(p); + } + + /* Special case, arguments share a factor ********************************/ + + /* Check aliasing of a and c */ + for (i = 0; i < 1000; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, c, f; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + fmpz_mod_poly_init(f, p); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + fmpz_mod_poly_randtest(b, state, n_randint(state, 100)); + fmpz_mod_poly_randtest(f, state, n_randint(state, 20)); + fmpz_mod_poly_mul(a, a, f); + fmpz_mod_poly_mul(b, b, f); + + fmpz_mod_poly_gcd_euclidean(c, a, b); + fmpz_mod_poly_gcd_euclidean(a, a, b); + + result = (fmpz_mod_poly_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_mod_poly_print(a), flint_printf("\n\n"); + fmpz_mod_poly_print(b), flint_printf("\n\n"); + fmpz_mod_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(c); + fmpz_mod_poly_clear(f); + fmpz_clear(p); + } + + /* Check aliasing of b and c */ + for (i = 0; i < 1000; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, c, f; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + fmpz_mod_poly_init(f, p); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + fmpz_mod_poly_randtest(b, state, n_randint(state, 100)); + fmpz_mod_poly_randtest(f, state, n_randint(state, 20)); + fmpz_mod_poly_mul(a, a, f); + fmpz_mod_poly_mul(b, b, f); + + fmpz_mod_poly_gcd_euclidean(c, a, b); + fmpz_mod_poly_gcd_euclidean(b, a, b); + + result = (fmpz_mod_poly_equal(b, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_mod_poly_print(a), flint_printf("\n\n"); + fmpz_mod_poly_print(b), flint_printf("\n\n"); + fmpz_mod_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(c); + fmpz_mod_poly_clear(f); + fmpz_clear(p); + } + + /* + Check that g = GCD(a,b) divides a and b, + and that 1 == GCD(a/g, b/g) + */ + for (i = 0; i < 500; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, c, d, f, g, h, s, t; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + fmpz_mod_poly_init(d, p); + fmpz_mod_poly_init(f, p); + fmpz_mod_poly_init(g, p); + fmpz_mod_poly_init(h, p); + fmpz_mod_poly_init(s, p); + fmpz_mod_poly_init(t, p); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + fmpz_mod_poly_randtest(b, state, n_randint(state, 100)); + fmpz_mod_poly_randtest(f, state, n_randint(state, 20)); + fmpz_mod_poly_mul(a, a, f); + fmpz_mod_poly_mul(b, b, f); + + fmpz_mod_poly_gcd_euclidean(g, a, b); + + if (fmpz_mod_poly_is_zero(g)) + { + result = 1; + } + else + { + fmpz_mod_poly_divrem_basecase(c, s, a, g); + fmpz_mod_poly_divrem_basecase(d, t, b, g); + fmpz_mod_poly_gcd_euclidean(h, c, d); + + result = (fmpz_mod_poly_is_zero(s) && fmpz_mod_poly_is_zero(t) + && (h->length == 1) && (fmpz_is_one(h->coeffs))); + } + + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("p = "), fmpz_print(p), flint_printf("\n\n"); + flint_printf("a = "), fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_mod_poly_print(b), flint_printf("\n\n"); + flint_printf("c = "), fmpz_mod_poly_print(c), flint_printf("\n\n"); + flint_printf("d = "), fmpz_mod_poly_print(d), flint_printf("\n\n"); + flint_printf("g = "), fmpz_mod_poly_print(g), flint_printf("\n\n"); + flint_printf("h = "), fmpz_mod_poly_print(h), flint_printf("\n\n"); + flint_printf("s = "), fmpz_mod_poly_print(s), flint_printf("\n\n"); + flint_printf("t = "), fmpz_mod_poly_print(t), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(c); + fmpz_mod_poly_clear(d); + fmpz_mod_poly_clear(f); + fmpz_mod_poly_clear(g); + fmpz_mod_poly_clear(h); + fmpz_mod_poly_clear(s); + fmpz_mod_poly_clear(t); + fmpz_clear(p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/test/t-gcd_euclidean_f.c b/external/flint-2.4.3/fmpz_mod_poly/test/t-gcd_euclidean_f.c new file mode 100644 index 0000000..3d63efa --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/test/t-gcd_euclidean_f.c @@ -0,0 +1,100 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("gcd_euclidean_f...."); + fflush(stdout); + + + + /* + Compare with the usual GCD function. + + N.B. I checked by hand that this test shows both outcomes, + i.e. trivial and non-trivial factors, sufficiently frequently. + */ + for (i = 0; i < 1000; i++) + { + fmpz_t p, f; + fmpz_mod_poly_t a, b, c, d; + + fmpz_init(f); + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 100); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + fmpz_mod_poly_init(d, p); + fmpz_mod_poly_randtest(a, state, n_randint(state, 60)); + fmpz_mod_poly_randtest(b, state, n_randint(state, 60)); + + fmpz_mod_poly_gcd_euclidean_f(f, c, a, b); + if (!fmpz_is_one(f)) + { + result = 1; + } + else + { + fmpz_mod_poly_gcd(d, a, b); + result = fmpz_mod_poly_equal(c, d); + } + + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("p = "), fmpz_print(p), flint_printf("\n\n"); + flint_printf("a = "), fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_mod_poly_print(b), flint_printf("\n\n"); + flint_printf("c = "), fmpz_mod_poly_print(c), flint_printf("\n\n"); + flint_printf("d = "), fmpz_mod_poly_print(d), flint_printf("\n\n"); + flint_printf("f = "), fmpz_print(f), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(c); + fmpz_mod_poly_clear(d); + fmpz_clear(f); + fmpz_clear(p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/test/t-gcdinv.c b/external/flint-2.4.3/fmpz_mod_poly/test/t-gcdinv.c new file mode 100644 index 0000000..90df18c --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/test/t-gcdinv.c @@ -0,0 +1,160 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("gcdinv...."); + fflush(stdout); + + + + /* Generic case, most likely co-prime arguments ******************************/ + + /* Compare with result from XGCD */ + for (i = 0; i < 1000; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, d, g, s, t, u; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(d, p); + fmpz_mod_poly_init(g, p); + fmpz_mod_poly_init(s, p); + fmpz_mod_poly_init(t, p); + fmpz_mod_poly_init(u, p); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + do + fmpz_mod_poly_randtest(b, state, n_randint(state, 100)); + while (b->length < 2); + + fmpz_mod_poly_gcdinv(d, u, a, b); + fmpz_mod_poly_xgcd(g, s, t, a, b); + + result = ((fmpz_mod_poly_equal(d, g) && fmpz_mod_poly_equal(u, s)) + || (fmpz_mod_poly_is_zero(d))); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_mod_poly_print(b), flint_printf("\n\n"); + flint_printf("d = "), fmpz_mod_poly_print(d), flint_printf("\n\n"); + flint_printf("g = "), fmpz_mod_poly_print(g), flint_printf("\n\n"); + flint_printf("s = "), fmpz_mod_poly_print(s), flint_printf("\n\n"); + flint_printf("t = "), fmpz_mod_poly_print(t), flint_printf("\n\n"); + flint_printf("u = "), fmpz_mod_poly_print(u), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(d); + fmpz_mod_poly_clear(g); + fmpz_mod_poly_clear(s); + fmpz_mod_poly_clear(t); + fmpz_mod_poly_clear(u); + fmpz_clear(p); + } + + /* Special case, arguments share a factor ********************************/ + + /* Compare with result from XGCD */ + for (i = 0; i < 1000; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, d, f, g, s, t, u; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(d, p); + fmpz_mod_poly_init(f, p); + fmpz_mod_poly_init(g, p); + fmpz_mod_poly_init(s, p); + fmpz_mod_poly_init(t, p); + fmpz_mod_poly_init(u, p); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + do + fmpz_mod_poly_randtest(b, state, n_randint(state, 100)); + while (b->length < 2); + fmpz_mod_poly_randtest_not_zero(f, state, n_randint(state, 20) + 1); + fmpz_mod_poly_mul(a, f, a); + fmpz_mod_poly_mul(b, f, b); + + fmpz_mod_poly_gcdinv(d, u, a, b); + fmpz_mod_poly_xgcd(g, s, t, a, b); + + result = ((fmpz_mod_poly_equal(d, g) && fmpz_mod_poly_equal(u, s)) + || (fmpz_mod_poly_is_zero(d))); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_mod_poly_print(b), flint_printf("\n\n"); + flint_printf("d = "), fmpz_mod_poly_print(d), flint_printf("\n\n"); + flint_printf("f = "), fmpz_mod_poly_print(f), flint_printf("\n\n"); + flint_printf("g = "), fmpz_mod_poly_print(g), flint_printf("\n\n"); + flint_printf("s = "), fmpz_mod_poly_print(s), flint_printf("\n\n"); + flint_printf("t = "), fmpz_mod_poly_print(t), flint_printf("\n\n"); + flint_printf("u = "), fmpz_mod_poly_print(u), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(d); + fmpz_mod_poly_clear(f); + fmpz_mod_poly_clear(g); + fmpz_mod_poly_clear(s); + fmpz_mod_poly_clear(t); + fmpz_mod_poly_clear(u); + fmpz_clear(p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/test/t-get_set_fmpz_poly.c b/external/flint-2.4.3/fmpz_mod_poly/test/t-get_set_fmpz_poly.c new file mode 100644 index 0000000..d3d101f --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/test/t-get_set_fmpz_poly.c @@ -0,0 +1,84 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("get/set_fmpz_poly...."); + fflush(stdout); + + + + for (i = 0; i < 10000; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b; + fmpz_poly_t c; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_poly_init(c); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + + fmpz_mod_poly_get_fmpz_poly(c, a); + fmpz_mod_poly_set_fmpz_poly(b, c); + + result = fmpz_mod_poly_equal(a, b); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), fmpz_mod_poly_print(a), flint_printf("\n"); + flint_printf("b = "), fmpz_mod_poly_print(b), flint_printf("\n"); + flint_printf("c = "), fmpz_poly_print(c), flint_printf("\n"); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_poly_clear(c); + + fmpz_clear(p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/test/t-init_realloc_clear.c b/external/flint-2.4.3/fmpz_mod_poly/test/t-init_realloc_clear.c new file mode 100644 index 0000000..6c60767 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/test/t-init_realloc_clear.c @@ -0,0 +1,95 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + flint_printf("init/init2/realloc/clear...."); + fflush(stdout); + + + + for (i = 0; i < 10000; i++) + { + fmpz_t p; + fmpz_mod_poly_t a; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init2(a, p, n_randint(state, 100)); + fmpz_mod_poly_clear(a); + + fmpz_clear(p); + } + + for (i = 0; i < 10000; i++) + { + fmpz_t p; + fmpz_mod_poly_t a; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init2(a, p, n_randint(state, 100)); + fmpz_mod_poly_realloc(a, n_randint(state, 100)); + fmpz_mod_poly_clear(a); + + fmpz_clear(p); + } + + for (i = 0; i < 10000; i++) + { + fmpz_t p; + fmpz_mod_poly_t a; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + fmpz_mod_poly_clear(a); + + fmpz_clear(p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/test/t-inv_series_newton.c b/external/flint-2.4.3/fmpz_mod_poly/test/t-inv_series_newton.c new file mode 100644 index 0000000..a0a10af --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/test/t-inv_series_newton.c @@ -0,0 +1,104 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("inv_series_newton...."); + fflush(stdout); + + + + /* Check Q^{-1} * Q is congruent 1 mod t^n */ + for (i = 0; i < 1000; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, c, one; + slong n = n_randint(state, 80) + 1; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + fmpz_mod_poly_init(one, p); + + fmpz_mod_poly_randtest_not_zero(a, state, n_randint(state, 80) + 1); + { + fmpz_t d; + + fmpz_init(d); + fmpz_gcd(d, a->coeffs, p); + while (!fmpz_is_one(d)) + { + fmpz_randm(a->coeffs, state, p); + fmpz_gcd(d, a->coeffs, p); + } + fmpz_clear(d); + } + + fmpz_mod_poly_set_ui(one, 1); + + fmpz_mod_poly_inv_series_newton(b, a, n); + fmpz_mod_poly_mullow(c, a, b, n); + + result = (fmpz_mod_poly_equal(c, one)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_mod_poly_print(b), flint_printf("\n\n"); + flint_printf("c = "), fmpz_mod_poly_print(c), flint_printf("\n\n"); + flint_printf("p = "), fmpz_print(p), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(c); + fmpz_mod_poly_clear(one); + fmpz_clear(p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/test/t-invmod.c b/external/flint-2.4.3/fmpz_mod_poly/test/t-invmod.c new file mode 100644 index 0000000..ab156a4 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/test/t-invmod.c @@ -0,0 +1,231 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("invmod...."); + fflush(stdout); + + + + /* Test aliasing *************************************************************/ + + /* Aliasing c and a */ + for (i = 0; i < 500; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, c; + int ans1, ans2; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + + do + fmpz_mod_poly_randtest(b, state, n_randint(state, 100)); + while (b->length < 3); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + + ans1 = fmpz_mod_poly_invmod(c, a, b); + ans2 = fmpz_mod_poly_invmod(a, a, b); + + result = (ans1 == ans2 && fmpz_mod_poly_equal(a, c)); + if (!result) + { + flint_printf("FAIL (alias a and c):\n"); + fmpz_mod_poly_print(a), flint_printf("\n\n"); + fmpz_mod_poly_print(b), flint_printf("\n\n"); + fmpz_mod_poly_print(c), flint_printf("\n\n"); + flint_printf("ans1 = %d\n\n", ans1); + flint_printf("ans2 = %d\n\n", ans2); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(c); + fmpz_clear(p); + } + + /* Aliasing c and b */ + for (i = 0; i < 500; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, c; + int ans1, ans2; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + + do + fmpz_mod_poly_randtest(b, state, n_randint(state, 100)); + while (b->length < 3); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + + ans1 = fmpz_mod_poly_invmod(c, a, b); + ans2 = fmpz_mod_poly_invmod(b, a, b); + + result = ((ans1 == ans2) && fmpz_mod_poly_equal(b, c)); + if (!result) + { + flint_printf("FAIL (alias b and c):\n"); + fmpz_mod_poly_print(a), flint_printf("\n\n"); + fmpz_mod_poly_print(b), flint_printf("\n\n"); + fmpz_mod_poly_print(c), flint_printf("\n\n"); + flint_printf("ans1 = %d\n\n", ans1); + flint_printf("ans2 = %d\n\n", ans2); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(c); + fmpz_clear(p); + } + + /* Compare with result from XGCD */ + for (i = 0; i < 1000; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, g, s, t, u; + int ans; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(g, p); + fmpz_mod_poly_init(s, p); + fmpz_mod_poly_init(t, p); + fmpz_mod_poly_init(u, p); + + do + fmpz_mod_poly_randtest(b, state, n_randint(state, 100)); + while (b->length < 3); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + + ans = fmpz_mod_poly_invmod(u, a, b); + fmpz_mod_poly_xgcd(g, s, t, a, b); + + result = (((ans) && g->length == 1 + && fmpz_is_one(g->coeffs) && fmpz_mod_poly_equal(s, u)) + || (!(ans) && g->length > 1)); + + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_mod_poly_print(a), flint_printf("\n\n"); + fmpz_mod_poly_print(b), flint_printf("\n\n"); + fmpz_mod_poly_print(g), flint_printf("\n\n"); + fmpz_mod_poly_print(s), flint_printf("\n\n"); + fmpz_mod_poly_print(t), flint_printf("\n\n"); + fmpz_mod_poly_print(u), flint_printf("\n\n"); + flint_printf("ans = %d\n\n", ans); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(g); + fmpz_mod_poly_clear(s); + fmpz_mod_poly_clear(t); + fmpz_mod_poly_clear(u); + fmpz_clear(p); + } + + /* Special case, arguments share a factor ********************************/ + + /* Check correctness */ + for (i = 0; i < 1000; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, f, u; + int ans; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(f, p); + fmpz_mod_poly_init(u, p); + + do + fmpz_mod_poly_randtest(b, state, n_randint(state, 100)); + while (b->length < 2); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + do + fmpz_mod_poly_randtest_not_zero(f, state, n_randint(state, 20) + 1); + while (f->length < 2); + fmpz_mod_poly_mul(a, f, a); + fmpz_mod_poly_mul(b, f, b); + + ans = fmpz_mod_poly_invmod(u, a, b); + + result = (!ans); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_mod_poly_print(a), flint_printf("\n\n"); + fmpz_mod_poly_print(b), flint_printf("\n\n"); + fmpz_mod_poly_print(f), flint_printf("\n\n"); + fmpz_mod_poly_print(u), flint_printf("\n\n"); + flint_printf("ans = %d\n\n", ans); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(f); + fmpz_mod_poly_clear(u); + fmpz_clear(p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/test/t-mul.c b/external/flint-2.4.3/fmpz_mod_poly/test/t-mul.c new file mode 100644 index 0000000..9a0bd40 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/test/t-mul.c @@ -0,0 +1,161 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2010 Sebastian Pancratz + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("mul...."); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 2000; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, c; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + fmpz_mod_poly_randtest(b, state, n_randint(state, 50)); + fmpz_mod_poly_randtest(c, state, n_randint(state, 50)); + + fmpz_mod_poly_mul(a, b, c); + fmpz_mod_poly_mul(b, b, c); + + result = (fmpz_mod_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_mod_poly_print(a), flint_printf("\n\n"); + fmpz_mod_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(c); + fmpz_clear(p); + } + + /* Check aliasing of a and c */ + for (i = 0; i < 2000; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, c; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + fmpz_mod_poly_randtest(b, state, n_randint(state, 50)); + fmpz_mod_poly_randtest(c, state, n_randint(state, 50)); + + fmpz_mod_poly_mul(a, b, c); + fmpz_mod_poly_mul(c, b, c); + + result = (fmpz_mod_poly_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_mod_poly_print(a), flint_printf("\n\n"); + fmpz_mod_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(c); + fmpz_clear(p); + } + + /* Check (b*c)+(b*d) = b*(c+d) */ + for (i = 0; i < 2000; i++) + { + fmpz_mod_poly_t a1, a2, b, c, d; + fmpz_t p; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a1, p); + fmpz_mod_poly_init(a2, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + fmpz_mod_poly_init(d, p); + fmpz_mod_poly_randtest(b, state, n_randint(state, 100)); + fmpz_mod_poly_randtest(c, state, n_randint(state, 100)); + fmpz_mod_poly_randtest(d, state, n_randint(state, 100)); + + fmpz_mod_poly_mul(a1, b, c); + fmpz_mod_poly_mul(a2, b, d); + fmpz_mod_poly_add(a1, a1, a2); + + fmpz_mod_poly_add(c, c, d); + fmpz_mod_poly_mul(a2, b, c); + + result = (fmpz_mod_poly_equal(a1, a2)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_mod_poly_print(a1), flint_printf("\n\n"); + fmpz_mod_poly_print(a2), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a1); + fmpz_mod_poly_clear(a2); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(c); + fmpz_mod_poly_clear(d); + fmpz_clear(p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/test/t-mullow.c b/external/flint-2.4.3/fmpz_mod_poly/test/t-mullow.c new file mode 100644 index 0000000..a9c8ca9 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/test/t-mullow.c @@ -0,0 +1,88 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("mullow...."); + fflush(stdout); + + + + /* Compare with truncated product of a and b */ + for (i = 0; i < 2000; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, c; + slong trunc; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + trunc = n_randint(state, 50); + fmpz_mod_poly_randtest(b, state, trunc); + fmpz_mod_poly_randtest(c, state, trunc); + + fmpz_mod_poly_mullow(a, b, c, trunc); + fmpz_mod_poly_mul(b, b, c); + fmpz_mod_poly_truncate(b, trunc); + + result = (fmpz_mod_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_mod_poly_print(a), flint_printf("\n\n"); + fmpz_mod_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(c); + fmpz_clear(p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/test/t-mulmod.c b/external/flint-2.4.3/fmpz_mod_poly/test/t-mulmod.c new file mode 100644 index 0000000..d92893a --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/test/t-mulmod.c @@ -0,0 +1,213 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2011, 2010 Sebastian Pancratz + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("mulmod...."); + fflush(stdout); + + + + /* Check aliasing of res and a */ + for (i = 0; i < 2000; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, res, f; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(f, p); + fmpz_mod_poly_init(res, p); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 50)); + fmpz_mod_poly_randtest(b, state, n_randint(state, 50)); + fmpz_mod_poly_randtest_not_zero(f, state, n_randint(state, 50) + 1); + + fmpz_mod_poly_mulmod(res, a, b, f); + fmpz_mod_poly_mulmod(a, a, b, f); + + result = (fmpz_mod_poly_equal(res, a)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("b:\n"); fmpz_mod_poly_print(b), flint_printf("\n\n"); + flint_printf("f:\n"); fmpz_mod_poly_print(f), flint_printf("\n\n"); + flint_printf("res:\n"); fmpz_mod_poly_print(res), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(f); + fmpz_mod_poly_clear(res); + fmpz_clear(p); + } + + /* Check aliasing of res and b */ + for (i = 0; i < 2000; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, f, res; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(f, p); + fmpz_mod_poly_init(res, p); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 50)); + fmpz_mod_poly_randtest(b, state, n_randint(state, 50)); + fmpz_mod_poly_randtest_not_zero(f, state, n_randint(state, 50) + 1); + + fmpz_mod_poly_mulmod(res, a, b, f); + fmpz_mod_poly_mulmod(b, a, b, f); + + result = (fmpz_mod_poly_equal(res, b)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("b:\n"); fmpz_mod_poly_print(b), flint_printf("\n\n"); + flint_printf("f:\n"); fmpz_mod_poly_print(f), flint_printf("\n\n"); + flint_printf("res:\n"); fmpz_mod_poly_print(res), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(f); + fmpz_mod_poly_clear(res); + fmpz_clear(p); + } + + /* Check aliasing of res and f */ + for (i = 0; i < 2000; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, f, res; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(f, p); + fmpz_mod_poly_init(res, p); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 50)); + fmpz_mod_poly_randtest(b, state, n_randint(state, 50)); + fmpz_mod_poly_randtest_not_zero(f, state, n_randint(state, 50) + 1); + + fmpz_mod_poly_mulmod(res, a, b, f); + fmpz_mod_poly_mulmod(f, a, b, f); + + result = (fmpz_mod_poly_equal(res, f)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("b:\n"); fmpz_mod_poly_print(b), flint_printf("\n\n"); + flint_printf("f:\n"); fmpz_mod_poly_print(f), flint_printf("\n\n"); + flint_printf("res:\n"); fmpz_mod_poly_print(res), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(f); + fmpz_mod_poly_clear(res); + fmpz_clear(p); + } + + /* No aliasing */ + for (i = 0; i < 1000; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, res1, res2, t, f; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(f, p); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 50)); + fmpz_mod_poly_randtest(b, state, n_randint(state, 50)); + fmpz_mod_poly_randtest_not_zero(f, state, n_randint(state, 50) + 1); + + fmpz_mod_poly_init(res1, p); + fmpz_mod_poly_init(res2, p); + fmpz_mod_poly_init(t, p); + fmpz_mod_poly_mulmod(res1, a, b, f); + fmpz_mod_poly_mul(res2, a, b); + fmpz_mod_poly_divrem(t, res2, res2, f); + + result = (fmpz_mod_poly_equal(res1, res2)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("b:\n"); fmpz_mod_poly_print(b), flint_printf("\n\n"); + flint_printf("f:\n"); fmpz_mod_poly_print(f), flint_printf("\n\n"); + flint_printf("res1:\n"); fmpz_mod_poly_print(res1), flint_printf("\n\n"); + flint_printf("res2:\n"); fmpz_mod_poly_print(res2), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(f); + fmpz_mod_poly_clear(res1); + fmpz_mod_poly_clear(res2); + fmpz_mod_poly_clear(t); + fmpz_clear(p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/test/t-mulmod_preinv.c b/external/flint-2.4.3/fmpz_mod_poly/test/t-mulmod_preinv.c new file mode 100644 index 0000000..93f6ea2 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/test/t-mulmod_preinv.c @@ -0,0 +1,305 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2011, 2010 Sebastian Pancratz + Copyright (C) 2009 William Hart + Copyright (C) 2013 Martin Lee + +******************************************************************************/ + +#undef ulong +#define ulong ulongxx/* interferes with system includes */ + +#include +#include + +#undef ulong + +#include + +#define ulong mp_limb_t + +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("mulmod_preinv...."); + fflush(stdout); + + + + /* Check aliasing of res and a */ + for (i = 0; i < 2000; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, res, f, finv; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(f, p); + fmpz_mod_poly_init(finv, p); + fmpz_mod_poly_init(res, p); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 50)); + fmpz_mod_poly_randtest(b, state, n_randint(state, 50)); + fmpz_mod_poly_randtest_not_zero(f, state, n_randint(state, 50) + 1); + if (a->length >= f->length) + fmpz_mod_poly_rem (a, a, f); + if (b->length >= f->length) + fmpz_mod_poly_rem (b, b, f); + + fmpz_mod_poly_reverse (finv, f, f->length); + fmpz_mod_poly_inv_series_newton (finv, finv, f->length); + + fmpz_mod_poly_mulmod_preinv(res, a, b, f, finv); + fmpz_mod_poly_mulmod_preinv(a, a, b, f, finv); + + result = (fmpz_mod_poly_equal(res, a)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("b:\n"); fmpz_mod_poly_print(b), flint_printf("\n\n"); + flint_printf("f:\n"); fmpz_mod_poly_print(f), flint_printf("\n\n"); + flint_printf("res:\n"); fmpz_mod_poly_print(res), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(f); + fmpz_mod_poly_clear(finv); + fmpz_mod_poly_clear(res); + fmpz_clear(p); + } + + /* Check aliasing of res and b */ + for (i = 0; i < 2000; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, f, finv, res; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(f, p); + fmpz_mod_poly_init(finv, p); + fmpz_mod_poly_init(res, p); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 50)); + fmpz_mod_poly_randtest(b, state, n_randint(state, 50)); + fmpz_mod_poly_randtest_not_zero(f, state, n_randint(state, 50) + 1); + if (a->length >= f->length) + fmpz_mod_poly_rem (a, a, f); + if (b->length >= f->length) + fmpz_mod_poly_rem (b, b, f); + + fmpz_mod_poly_reverse (finv, f, f->length); + fmpz_mod_poly_inv_series_newton (finv, finv, f->length); + + fmpz_mod_poly_mulmod_preinv(res, a, b, f, finv); + fmpz_mod_poly_mulmod_preinv(b, a, b, f, finv); + + result = (fmpz_mod_poly_equal(res, b)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("b:\n"); fmpz_mod_poly_print(b), flint_printf("\n\n"); + flint_printf("f:\n"); fmpz_mod_poly_print(f), flint_printf("\n\n"); + flint_printf("res:\n"); fmpz_mod_poly_print(res), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(f); + fmpz_mod_poly_clear(finv); + fmpz_mod_poly_clear(res); + fmpz_clear(p); + } + + /* Check aliasing of res and f */ + for (i = 0; i < 2000; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, f, finv, res; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(f, p); + fmpz_mod_poly_init(finv, p); + fmpz_mod_poly_init(res, p); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 50)); + fmpz_mod_poly_randtest(b, state, n_randint(state, 50)); + fmpz_mod_poly_randtest_not_zero(f, state, n_randint(state, 50) + 1); + if (a->length >= f->length) + fmpz_mod_poly_rem (a, a, f); + if (b->length >= f->length) + fmpz_mod_poly_rem (b, b, f); + + fmpz_mod_poly_reverse (finv, f, f->length); + fmpz_mod_poly_inv_series_newton (finv, finv, f->length); + + fmpz_mod_poly_mulmod_preinv(res, a, b, f, finv); + fmpz_mod_poly_mulmod_preinv(f, a, b, f, finv); + + result = (fmpz_mod_poly_equal(res, f)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("b:\n"); fmpz_mod_poly_print(b), flint_printf("\n\n"); + flint_printf("f:\n"); fmpz_mod_poly_print(f), flint_printf("\n\n"); + flint_printf("res:\n"); fmpz_mod_poly_print(res), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(f); + fmpz_mod_poly_clear(finv); + fmpz_mod_poly_clear(res); + fmpz_clear(p); + } + + /* Check aliasing of res and finv */ + for (i = 0; i < 2000; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, f, finv, res; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(f, p); + fmpz_mod_poly_init(finv, p); + fmpz_mod_poly_init(res, p); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 50)); + fmpz_mod_poly_randtest(b, state, n_randint(state, 50)); + fmpz_mod_poly_randtest_not_zero(f, state, n_randint(state, 50) + 1); + if (a->length >= f->length) + fmpz_mod_poly_rem (a, a, f); + if (b->length >= f->length) + fmpz_mod_poly_rem (b, b, f); + + fmpz_mod_poly_reverse (finv, f, f->length); + fmpz_mod_poly_inv_series_newton (finv, finv, f->length); + + fmpz_mod_poly_mulmod_preinv(res, a, b, f, finv); + fmpz_mod_poly_mulmod_preinv(finv, a, b, f, finv); + + result = (fmpz_mod_poly_equal(res, finv)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("b:\n"); fmpz_mod_poly_print(b), flint_printf("\n\n"); + flint_printf("f:\n"); fmpz_mod_poly_print(f), flint_printf("\n\n"); + flint_printf("finv:\n"); fmpz_mod_poly_print(finv), flint_printf("\n\n"); + flint_printf("res:\n"); fmpz_mod_poly_print(res), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(f); + fmpz_mod_poly_clear(finv); + fmpz_mod_poly_clear(res); + fmpz_clear(p); + } + + /* No aliasing */ + for (i = 0; i < 1000; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, res1, res2, f, finv; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(f, p); + fmpz_mod_poly_init(finv, p); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 50)); + fmpz_mod_poly_randtest(b, state, n_randint(state, 50)); + fmpz_mod_poly_randtest_not_zero(f, state, n_randint(state, 50) + 1); + if (a->length >= f->length) + fmpz_mod_poly_rem (a, a, f); + if (b->length >= f->length) + fmpz_mod_poly_rem (b, b, f); + + fmpz_mod_poly_reverse (finv, f, f->length); + fmpz_mod_poly_inv_series_newton (finv, finv, f->length); + + fmpz_mod_poly_init(res1, p); + fmpz_mod_poly_init(res2, p); + fmpz_mod_poly_mulmod(res1, a, b, f); + fmpz_mod_poly_mulmod_preinv(res2, a, b, f, finv); + + result = (fmpz_mod_poly_equal(res1, res2)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("b:\n"); fmpz_mod_poly_print(b), flint_printf("\n\n"); + flint_printf("f:\n"); fmpz_mod_poly_print(f), flint_printf("\n\n"); + flint_printf("res1:\n"); fmpz_mod_poly_print(res1), flint_printf("\n\n"); + flint_printf("res2:\n"); fmpz_mod_poly_print(res2), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(f); + fmpz_mod_poly_clear(finv); + fmpz_mod_poly_clear(res1); + fmpz_mod_poly_clear(res2); + fmpz_clear(p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/test/t-neg.c b/external/flint-2.4.3/fmpz_mod_poly/test/t-neg.c new file mode 100644 index 0000000..addbc70 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/test/t-neg.c @@ -0,0 +1,83 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("neg...."); + fflush(stdout); + + + + for (i = 0; i < 10000; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, c; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + + fmpz_mod_poly_neg(b, a); + fmpz_mod_poly_neg(c, b); + + result = (fmpz_mod_poly_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_mod_poly_print(a), flint_printf("\n\n"); + fmpz_mod_poly_print(b), flint_printf("\n\n"); + fmpz_mod_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(c); + fmpz_clear(p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/test/t-pow_trunc.c b/external/flint-2.4.3/fmpz_mod_poly/test/t-pow_trunc.c new file mode 100644 index 0000000..f768db4 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/test/t-pow_trunc.c @@ -0,0 +1,131 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 Lina Kulakova + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("pow_trunc...."); + fflush(stdout); + + /* Check aliasing */ + for (i = 0; i < 10000; i++) + { + fmpz_mod_poly_t a, b, c; + fmpz_t p; + slong e, trunc; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 30)); + e = n_randint(state, 20); + trunc = n_randint(state, 30); + + fmpz_mod_poly_set(c, a); + + fmpz_mod_poly_pow_trunc(b, a, e, trunc); + fmpz_mod_poly_pow_trunc(c, c, e, trunc); + + result = (fmpz_mod_poly_equal(b, c)); + if (!result) + { + flint_printf("FAIL aliasing:\n"); + flint_printf("a->length = %wd, p = %wu, exp = %wd, trunc = %wd\n", + a->length, a->p, e, trunc); + flint_printf("a:\n"); fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("b:\n"); fmpz_mod_poly_print(b), flint_printf("\n\n"); + flint_printf("c:\n"); fmpz_mod_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(p); + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(c); + } + + /* Check powering against naive method */ + for (i = 0; i < 10000; i++) + { + fmpz_mod_poly_t a, b, c; + fmpz_t p; + slong e, trunc; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + fmpz_mod_poly_randtest(a, state, n_randint(state, 30)); + e = n_randint(state, 20); + trunc = n_randint(state, 30); + + fmpz_mod_poly_pow_trunc(b, a, e, trunc); + fmpz_mod_poly_pow(c, a, e); + fmpz_mod_poly_truncate(c, trunc); + + result = (fmpz_mod_poly_equal(b, c) + || (a->length == 0 && e == 0 && c->length == 1 && c->coeffs[0] == 1)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a->length = %wd, p = %wu, exp = %wd, trunc = %wd\n", + a->length, a->p, e, trunc); + flint_printf("a:\n"); fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("b:\n"); fmpz_mod_poly_print(b), flint_printf("\n\n"); + flint_printf("c:\n"); fmpz_mod_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(p); + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/test/t-pow_trunc_binexp.c b/external/flint-2.4.3/fmpz_mod_poly/test/t-pow_trunc_binexp.c new file mode 100644 index 0000000..12b8e75 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/test/t-pow_trunc_binexp.c @@ -0,0 +1,131 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 Lina Kulakova + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("pow_trunc_binexp...."); + fflush(stdout); + + /* Check aliasing */ + for (i = 0; i < 10000; i++) + { + fmpz_mod_poly_t a, b, c; + fmpz_t p; + slong e, trunc; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 30)); + e = n_randint(state, 20); + trunc = n_randint(state, 30); + + fmpz_mod_poly_set(c, a); + + fmpz_mod_poly_pow_trunc_binexp(b, a, e, trunc); + fmpz_mod_poly_pow_trunc_binexp(c, c, e, trunc); + + result = (fmpz_mod_poly_equal(b, c)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a->length = %wd, p = %wu, exp = %wd, trunc = %wd\n", + a->length, a->p, e, trunc); + flint_printf("a:\n"); fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("b:\n"); fmpz_mod_poly_print(b), flint_printf("\n\n"); + flint_printf("c:\n"); fmpz_mod_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(p); + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(c); + } + + /* Check powering against naive method */ + for (i = 0; i < 10000; i++) + { + fmpz_mod_poly_t a, b, c; + fmpz_t p; + slong e, trunc; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + fmpz_mod_poly_randtest(a, state, n_randint(state, 30)); + e = n_randint(state, 20); + trunc = n_randint(state, 30); + + fmpz_mod_poly_pow_trunc_binexp(b, a, e, trunc); + fmpz_mod_poly_pow(c, a, e); + fmpz_mod_poly_truncate(c, trunc); + + result = (fmpz_mod_poly_equal(b, c) + || (a->length == 0 && e == 0 && c->length == 1 && c->coeffs[0] == 1)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a->length = %wd, p = %wu, exp = %wd, trunc = %wd\n", + a->length, a->p, e, trunc); + flint_printf("a:\n"); fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("b:\n"); fmpz_mod_poly_print(b), flint_printf("\n\n"); + flint_printf("c:\n"); fmpz_mod_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(p); + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/test/t-powmod_fmpz_binexp.c b/external/flint-2.4.3/fmpz_mod_poly/test/t-powmod_fmpz_binexp.c new file mode 100644 index 0000000..1f19edf --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/test/t-powmod_fmpz_binexp.c @@ -0,0 +1,238 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz_vec.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("powmod_fmpz_binexp...."); + fflush(stdout); + + /* Aliasing of res and a */ + for (i = 0; i < 250; i++) + { + fmpz_mod_poly_t a, res, t, f; + fmpz_t p; + ulong exp; + fmpz_t expz; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + exp = n_randint(state, 50); + fmpz_init_set_ui(expz, exp); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(f, p); + fmpz_mod_poly_init(res, p); + fmpz_mod_poly_init(t, p); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 50)); + fmpz_mod_poly_randtest_not_zero(f, state, n_randint(state, 50) + 1); + + fmpz_mod_poly_powmod_fmpz_binexp(res, a, expz, f); + fmpz_mod_poly_powmod_fmpz_binexp(a, a, expz, f); + + result = (fmpz_mod_poly_equal(res, a)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("f:\n"); fmpz_mod_poly_print(f), flint_printf("\n\n"); + flint_printf("res:\n"); fmpz_mod_poly_print(res), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(p); + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(f); + fmpz_mod_poly_clear(res); + fmpz_mod_poly_clear(t); + fmpz_clear(expz); + } + + /* Aliasing of res and f */ + for (i = 0; i < 250; i++) + { + fmpz_mod_poly_t a, res, t, f; + fmpz_t p; + ulong exp; + fmpz_t expz; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + exp = n_randint(state, 50); + fmpz_init_set_ui(expz, exp); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(f, p); + fmpz_mod_poly_init(res, p); + fmpz_mod_poly_init(t, p); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 50)); + fmpz_mod_poly_randtest_not_zero(f, state, n_randint(state, 50) + 1); + + fmpz_mod_poly_powmod_fmpz_binexp(res, a, expz, f); + fmpz_mod_poly_powmod_fmpz_binexp(f, a, expz, f); + + result = (fmpz_mod_poly_equal(res, f)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("f:\n"); fmpz_mod_poly_print(f), flint_printf("\n\n"); + flint_printf("res:\n"); fmpz_mod_poly_print(res), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(p); + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(f); + fmpz_mod_poly_clear(res); + fmpz_mod_poly_clear(t); + fmpz_clear(expz); + } + + /* No aliasing */ + for (i = 0; i < 500; i++) + { + fmpz_mod_poly_t a, res1, res2, t, f; + fmpz_t p; + ulong exp; + fmpz_t expz; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + exp = n_randint(state, 50); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(f, p); + fmpz_mod_poly_init(res1, p); + fmpz_mod_poly_init(res2, p); + fmpz_mod_poly_init(t, p); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 50)); + fmpz_mod_poly_randtest_not_zero(f, state, n_randint(state, 50) + 1); + fmpz_init_set_ui(expz, exp); + + fmpz_mod_poly_powmod_fmpz_binexp(res1, a, expz, f); + fmpz_mod_poly_powmod_ui_binexp(res2, a, exp, f); + + result = (fmpz_mod_poly_equal(res1, res2)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("f:\n"); fmpz_mod_poly_print(f), flint_printf("\n\n"); + flint_printf("res1:\n"); fmpz_mod_poly_print(res1), flint_printf("\n\n"); + flint_printf("res2:\n"); fmpz_mod_poly_print(res2), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(p); + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(f); + fmpz_mod_poly_clear(res1); + fmpz_mod_poly_clear(res2); + fmpz_mod_poly_clear(t); + fmpz_clear(expz); + } + + /* Check that a^(b+c) = a^b * a^c */ + for (i = 0; i < 500; i++) + { + fmpz_mod_poly_t a, res1, res2, res3, res4, t, f; + fmpz_t p; + fmpz_t exp1, exp2, exp3; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + fmpz_init(exp1); + fmpz_init(exp2); + fmpz_randtest(exp1, state, 200); + if (fmpz_sgn(exp1) == -1) fmpz_neg(exp1, exp1); + fmpz_randtest(exp2, state, 200); + if (fmpz_sgn(exp2) == -1) fmpz_neg(exp2, exp2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(f, p); + fmpz_mod_poly_init(res1, p); + fmpz_mod_poly_init(res2, p); + fmpz_mod_poly_init(res3, p); + fmpz_mod_poly_init(res4, p); + fmpz_mod_poly_init(t, p); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 50)); + fmpz_mod_poly_randtest_not_zero(f, state, n_randint(state, 50) + 1); + + fmpz_mod_poly_powmod_fmpz_binexp(res1, a, exp1, f); + fmpz_mod_poly_powmod_fmpz_binexp(res2, a, exp2, f); + fmpz_mod_poly_mulmod(res4, res1, res2, f); + fmpz_init(exp3); + fmpz_add(exp3, exp1, exp2); + fmpz_mod_poly_powmod_fmpz_binexp(res3, a, exp3, f); + + result = (fmpz_mod_poly_equal(res4, res3)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("f:\n"); fmpz_mod_poly_print(f), flint_printf("\n\n"); + flint_printf("res3:\n"); fmpz_mod_poly_print(res3), flint_printf("\n\n"); + flint_printf("res4:\n"); fmpz_mod_poly_print(res4), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(p); + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(f); + fmpz_mod_poly_clear(res1); + fmpz_mod_poly_clear(res2); + fmpz_mod_poly_clear(res3); + fmpz_mod_poly_clear(res4); + fmpz_mod_poly_clear(t); + fmpz_clear(exp1); + fmpz_clear(exp2); + fmpz_clear(exp3); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/test/t-powmod_fmpz_binexp_preinv.c b/external/flint-2.4.3/fmpz_mod_poly/test/t-powmod_fmpz_binexp_preinv.c new file mode 100644 index 0000000..a3c6078 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/test/t-powmod_fmpz_binexp_preinv.c @@ -0,0 +1,308 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Martin Lee + +******************************************************************************/ + +#undef ulong +#define ulong ulongxx/* interferes with system includes */ + +#include +#include + +#undef ulong + +#include + +#define ulong mp_limb_t + +#include "flint.h" +#include "fmpz_vec.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("powmod_fmpz_binexp_preinv...."); + fflush(stdout); + + /* Aliasing of res and a */ + for (i = 0; i < 250; i++) + { + fmpz_mod_poly_t a, res, f, finv; + fmpz_t p; + ulong exp; + fmpz_t expz; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + exp = n_randint(state, 50); + fmpz_init_set_ui(expz, exp); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(f, p); + fmpz_mod_poly_init(finv, p); + fmpz_mod_poly_init(res, p); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 50)); + fmpz_mod_poly_randtest_not_zero(f, state, n_randint(state, 50) + 1); + + fmpz_mod_poly_reverse (finv, f, f->length); + fmpz_mod_poly_inv_series_newton (finv, finv, f->length); + + fmpz_mod_poly_powmod_fmpz_binexp_preinv(res, a, expz, f, finv); + fmpz_mod_poly_powmod_fmpz_binexp_preinv(a, a, expz, f, finv); + + result = (fmpz_mod_poly_equal(res, a)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("f:\n"); fmpz_mod_poly_print(f), flint_printf("\n\n"); + flint_printf("res:\n"); fmpz_mod_poly_print(res), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(p); + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(f); + fmpz_mod_poly_clear(finv); + fmpz_mod_poly_clear(res); + fmpz_clear(expz); + } + + /* Aliasing of res and f */ + for (i = 0; i < 250; i++) + { + fmpz_mod_poly_t a, res, f, finv; + fmpz_t p; + ulong exp; + fmpz_t expz; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + exp = n_randint(state, 50); + fmpz_init_set_ui(expz, exp); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(f, p); + fmpz_mod_poly_init(finv, p); + fmpz_mod_poly_init(res, p); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 50)); + fmpz_mod_poly_randtest_not_zero(f, state, n_randint(state, 50) + 1); + + fmpz_mod_poly_reverse (finv, f, f->length); + fmpz_mod_poly_inv_series_newton (finv, finv, f->length); + + fmpz_mod_poly_powmod_fmpz_binexp_preinv(res, a, expz, f, finv); + fmpz_mod_poly_powmod_fmpz_binexp_preinv(f, a, expz, f, finv); + + result = (fmpz_mod_poly_equal(res, f)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("f:\n"); fmpz_mod_poly_print(f), flint_printf("\n\n"); + flint_printf("res:\n"); fmpz_mod_poly_print(res), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(p); + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(f); + fmpz_mod_poly_clear(finv); + fmpz_mod_poly_clear(res); + fmpz_clear(expz); + } + + /* Aliasing of res and finv */ + for (i = 0; i < 250; i++) + { + fmpz_mod_poly_t a, res, f, finv; + fmpz_t p; + ulong exp; + fmpz_t expz; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + exp = n_randint(state, 50); + fmpz_init_set_ui(expz, exp); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(f, p); + fmpz_mod_poly_init(finv, p); + fmpz_mod_poly_init(res, p); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 50)); + fmpz_mod_poly_randtest_not_zero(f, state, n_randint(state, 50) + 1); + + + fmpz_mod_poly_reverse (finv, f, f->length); + fmpz_mod_poly_inv_series_newton (finv, finv, f->length); + + fmpz_mod_poly_powmod_fmpz_binexp_preinv(res, a, expz, f, finv); + fmpz_mod_poly_powmod_fmpz_binexp_preinv(finv, a, expz, f, finv); + + result = (fmpz_mod_poly_equal(res, finv)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("f:\n"); fmpz_mod_poly_print(f), flint_printf("\n\n"); + flint_printf("finv:\n"); fmpz_mod_poly_print(finv), flint_printf("\n\n"); + flint_printf("res:\n"); fmpz_mod_poly_print(res), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(p); + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(f); + fmpz_mod_poly_clear(finv); + fmpz_mod_poly_clear(res); + fmpz_clear(expz); + } + + /* No aliasing */ + for (i = 0; i < 500; i++) + { + fmpz_mod_poly_t a, res1, res2, f, finv; + fmpz_t p; + ulong exp; + fmpz_t expz; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + exp = n_randint(state, 50); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(f, p); + fmpz_mod_poly_init(finv, p); + fmpz_mod_poly_init(res1, p); + fmpz_mod_poly_init(res2, p); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 50)); + fmpz_mod_poly_randtest_not_zero(f, state, n_randint(state, 50) + 1); + fmpz_init_set_ui(expz, exp); + + fmpz_mod_poly_reverse (finv, f, f->length); + fmpz_mod_poly_inv_series_newton (finv, finv, f->length); + + fmpz_mod_poly_powmod_fmpz_binexp(res1, a, expz, f); + fmpz_mod_poly_powmod_fmpz_binexp_preinv(res2, a, expz, f, finv); + + result = (fmpz_mod_poly_equal(res1, res2)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("f:\n"); fmpz_mod_poly_print(f), flint_printf("\n\n"); + flint_printf("finv:\n"); fmpz_mod_poly_print(finv), flint_printf("\n\n"); + flint_printf("res1:\n"); fmpz_mod_poly_print(res1), flint_printf("\n\n"); + flint_printf("res2:\n"); fmpz_mod_poly_print(res2), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(p); + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(f); + fmpz_mod_poly_clear(res1); + fmpz_mod_poly_clear(res2); + fmpz_mod_poly_clear(finv); + fmpz_clear(expz); + } + + /* Check that a^(b+c) = a^b * a^c */ + for (i = 0; i < 500; i++) + { + fmpz_mod_poly_t a, res1, res2, res3, res4, f, finv; + fmpz_t p; + fmpz_t exp1, exp2, exp3; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + fmpz_init(exp1); + fmpz_init(exp2); + fmpz_randtest(exp1, state, 200); + if (fmpz_sgn(exp1) == -1) fmpz_neg(exp1, exp1); + fmpz_randtest(exp2, state, 200); + if (fmpz_sgn(exp2) == -1) fmpz_neg(exp2, exp2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(f, p); + fmpz_mod_poly_init(finv, p); + fmpz_mod_poly_init(res1, p); + fmpz_mod_poly_init(res2, p); + fmpz_mod_poly_init(res3, p); + fmpz_mod_poly_init(res4, p); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 50)); + fmpz_mod_poly_randtest_not_zero(f, state, n_randint(state, 50) + 1); + + fmpz_mod_poly_reverse (finv, f, f->length); + fmpz_mod_poly_inv_series_newton (finv, finv, f->length); + + fmpz_mod_poly_powmod_fmpz_binexp_preinv(res1, a, exp1, f, finv); + fmpz_mod_poly_powmod_fmpz_binexp_preinv(res2, a, exp2, f, finv); + fmpz_mod_poly_mulmod(res4, res1, res2, f); + fmpz_init(exp3); + fmpz_add(exp3, exp1, exp2); + fmpz_mod_poly_powmod_fmpz_binexp_preinv(res3, a, exp3, f, finv); + + result = (fmpz_mod_poly_equal(res4, res3)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("f:\n"); fmpz_mod_poly_print(f), flint_printf("\n\n"); + flint_printf("res3:\n"); fmpz_mod_poly_print(res3), flint_printf("\n\n"); + flint_printf("res4:\n"); fmpz_mod_poly_print(res4), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(p); + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(f); + fmpz_mod_poly_clear(finv); + fmpz_mod_poly_clear(res1); + fmpz_mod_poly_clear(res2); + fmpz_mod_poly_clear(res3); + fmpz_mod_poly_clear(res4); + fmpz_clear(exp1); + fmpz_clear(exp2); + fmpz_clear(exp3); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/test/t-powmod_ui_binexp.c b/external/flint-2.4.3/fmpz_mod_poly/test/t-powmod_ui_binexp.c new file mode 100644 index 0000000..ebd534e --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/test/t-powmod_ui_binexp.c @@ -0,0 +1,232 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz_vec.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("powmod_ui_binexp...."); + fflush(stdout); + + /* Aliasing of res and a */ + for (i = 0; i < 500; i++) + { + fmpz_mod_poly_t a, res1, t, f; + fmpz_t p; + ulong exp; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + exp = n_randint(state, 50); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(f, p); + fmpz_mod_poly_init(res1, p); + fmpz_mod_poly_init(t, p); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 50)); + fmpz_mod_poly_randtest_not_zero(f, state, n_randint(state, 50) + 1); + + fmpz_mod_poly_powmod_ui_binexp(res1, a, exp, f); + fmpz_mod_poly_powmod_ui_binexp(a, a, exp, f); + + result = (fmpz_mod_poly_equal(res1, a)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("exp: %wu\n\n", exp); + flint_printf("a:\n"); fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("f:\n"); fmpz_mod_poly_print(f), flint_printf("\n\n"); + flint_printf("res:\n"); fmpz_mod_poly_print(res1), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(p); + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(f); + fmpz_mod_poly_clear(res1); + fmpz_mod_poly_clear(t); + } + + /* Aliasing of res and f */ + for (i = 0; i < 500; i++) + { + fmpz_mod_poly_t a, res1, t, f; + fmpz_t p; + ulong exp; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + exp = n_randint(state, 50); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(f, p); + fmpz_mod_poly_init(res1, p); + fmpz_mod_poly_init(t, p); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 50)); + fmpz_mod_poly_randtest_not_zero(f, state, n_randint(state, 50) + 1); + + fmpz_mod_poly_powmod_ui_binexp(res1, a, exp, f); + fmpz_mod_poly_powmod_ui_binexp(f, a, exp, f); + + result = (fmpz_mod_poly_equal(res1, f)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("exp: %wu\n\n", exp); + flint_printf("a:\n"); fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("f:\n"); fmpz_mod_poly_print(f), flint_printf("\n\n"); + flint_printf("res1:\n"); fmpz_mod_poly_print(res1), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(p); + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(f); + fmpz_mod_poly_clear(res1); + fmpz_mod_poly_clear(t); + } + + /* No aliasing */ + for (i = 0; i < 1000; i++) + { + fmpz_mod_poly_t a, res1, res2, t, f; + fmpz_t p; + ulong exp; + int j; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + exp = n_randint(state, 50); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(f, p); + fmpz_mod_poly_init(res1, p); + fmpz_mod_poly_init(res2, p); + fmpz_mod_poly_init(t, p); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 50)); + fmpz_mod_poly_randtest_not_zero(f, state, n_randint(state, 50) + 1); + + fmpz_mod_poly_powmod_ui_binexp(res1, a, exp, f); + + fmpz_mod_poly_zero(res2); + fmpz_mod_poly_set_coeff_ui(res2, 0, 1); + for (j = 1; j <= exp; j++) + fmpz_mod_poly_mulmod(res2, res2, a, f); + + result = (fmpz_mod_poly_equal(res1, res2)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("exp: %wu\n\n", exp); + flint_printf("a:\n"); fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("f:\n"); fmpz_mod_poly_print(f), flint_printf("\n\n"); + flint_printf("res1:\n"); fmpz_mod_poly_print(res1), flint_printf("\n\n"); + flint_printf("res2:\n"); fmpz_mod_poly_print(res2), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(p); + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(f); + fmpz_mod_poly_clear(res1); + fmpz_mod_poly_clear(res2); + fmpz_mod_poly_clear(t); + } + + /* Check that a^(b+c) = a^b * a^c */ + for (i = 0; i < 500; i++) + { + fmpz_mod_poly_t a, res1, res2, res3, res4, t, f; + fmpz_t p; + ulong exp1, exp2, exp3; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + exp1 = n_randint(state, 50); + exp2 = n_randint(state, 50); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(f, p); + fmpz_mod_poly_init(res1, p); + fmpz_mod_poly_init(res2, p); + fmpz_mod_poly_init(res3, p); + fmpz_mod_poly_init(res4, p); + fmpz_mod_poly_init(t, p); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 50)); + fmpz_mod_poly_randtest_not_zero(f, state, n_randint(state, 50) + 1); + + fmpz_mod_poly_powmod_ui_binexp(res1, a, exp1, f); + fmpz_mod_poly_powmod_ui_binexp(res2, a, exp2, f); + fmpz_mod_poly_mulmod(res4, res1, res2, f); + exp3 = exp1 + exp2; + fmpz_mod_poly_powmod_ui_binexp(res3, a, exp3, f); + + result = (fmpz_mod_poly_equal(res4, res3)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("f:\n"); fmpz_mod_poly_print(f), flint_printf("\n\n"); + flint_printf("res3:\n"); fmpz_mod_poly_print(res3), flint_printf("\n\n"); + flint_printf("res4:\n"); fmpz_mod_poly_print(res4), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(p); + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(f); + fmpz_mod_poly_clear(res1); + fmpz_mod_poly_clear(res2); + fmpz_mod_poly_clear(res3); + fmpz_mod_poly_clear(res4); + fmpz_mod_poly_clear(t); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/test/t-powmod_ui_binexp_preinv.c b/external/flint-2.4.3/fmpz_mod_poly/test/t-powmod_ui_binexp_preinv.c new file mode 100644 index 0000000..cf02fce --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/test/t-powmod_ui_binexp_preinv.c @@ -0,0 +1,294 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Martin Lee + +******************************************************************************/ + +#undef ulong +#define ulong ulongxx/* interferes with system includes */ + +#include +#include + +#undef ulong + +#include + +#define ulong mp_limb_t + +#include "flint.h" +#include "fmpz_vec.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("powmod_ui_binexp_preinv...."); + fflush(stdout); + + /* Aliasing of res and a */ + for (i = 0; i < 500; i++) + { + fmpz_mod_poly_t a, res, f, finv; + fmpz_t p; + ulong exp; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + exp = n_randint(state, 50); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(f, p); + fmpz_mod_poly_init(finv, p); + fmpz_mod_poly_init(res, p); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 50)); + fmpz_mod_poly_randtest_not_zero(f, state, n_randint(state, 50) + 1); + + fmpz_mod_poly_reverse (finv, f, f->length); + fmpz_mod_poly_inv_series_newton (finv, finv, f->length); + + fmpz_mod_poly_powmod_ui_binexp_preinv(res, a, exp, f, finv); + fmpz_mod_poly_powmod_ui_binexp_preinv(a, a, exp, f, finv); + + result = (fmpz_mod_poly_equal(res, a)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("f:\n"); fmpz_mod_poly_print(f), flint_printf("\n\n"); + flint_printf("res:\n"); fmpz_mod_poly_print(res), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(p); + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(f); + fmpz_mod_poly_clear(finv); + fmpz_mod_poly_clear(res); + } + + /* Aliasing of res and f */ + for (i = 0; i < 500; i++) + { + fmpz_mod_poly_t a, res, f, finv; + fmpz_t p; + ulong exp; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + exp = n_randint(state, 50); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(f, p); + fmpz_mod_poly_init(finv, p); + fmpz_mod_poly_init(res, p); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 50)); + fmpz_mod_poly_randtest_not_zero(f, state, n_randint(state, 50) + 1); + + fmpz_mod_poly_reverse (finv, f, f->length); + fmpz_mod_poly_inv_series_newton (finv, finv, f->length); + + fmpz_mod_poly_powmod_ui_binexp_preinv(res, a, exp, f, finv); + fmpz_mod_poly_powmod_ui_binexp_preinv(f, a, exp, f, finv); + + result = (fmpz_mod_poly_equal(res, f)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("f:\n"); fmpz_mod_poly_print(f), flint_printf("\n\n"); + flint_printf("res:\n"); fmpz_mod_poly_print(res), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(p); + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(f); + fmpz_mod_poly_clear(finv); + fmpz_mod_poly_clear(res); + } + + /* Aliasing of res and finv */ + for (i = 0; i < 500; i++) + { + fmpz_mod_poly_t a, res, f, finv; + fmpz_t p; + ulong exp; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + exp = n_randint(state, 50); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(f, p); + fmpz_mod_poly_init(finv, p); + fmpz_mod_poly_init(res, p); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 50)); + fmpz_mod_poly_randtest_not_zero(f, state, n_randint(state, 50) + 1); + + + fmpz_mod_poly_reverse (finv, f, f->length); + fmpz_mod_poly_inv_series_newton (finv, finv, f->length); + + fmpz_mod_poly_powmod_ui_binexp_preinv(res, a, exp, f, finv); + fmpz_mod_poly_powmod_ui_binexp_preinv(finv, a, exp, f, finv); + + result = (fmpz_mod_poly_equal(res, finv)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("f:\n"); fmpz_mod_poly_print(f), flint_printf("\n\n"); + flint_printf("finv:\n"); fmpz_mod_poly_print(finv), flint_printf("\n\n"); + flint_printf("res:\n"); fmpz_mod_poly_print(res), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(p); + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(f); + fmpz_mod_poly_clear(finv); + fmpz_mod_poly_clear(res); + } + + /* No aliasing */ + for (i = 0; i < 1000; i++) + { + fmpz_mod_poly_t a, res1, res2, f, finv; + fmpz_t p; + ulong exp; + int j; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + exp = n_randint(state, 50); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(f, p); + fmpz_mod_poly_init(finv, p); + fmpz_mod_poly_init(res1, p); + fmpz_mod_poly_init(res2, p); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 50)); + fmpz_mod_poly_randtest_not_zero(f, state, n_randint(state, 50) + 1); + + fmpz_mod_poly_reverse (finv, f, f->length); + fmpz_mod_poly_inv_series_newton (finv, finv, f->length); + + fmpz_mod_poly_powmod_ui_binexp_preinv(res1, a, exp, f, finv); + + fmpz_mod_poly_zero(res2); + fmpz_mod_poly_set_coeff_ui(res2, 0, 1); + for (j = 1; j <= exp; j++) + fmpz_mod_poly_mulmod(res2, res2, a, f); + + result = (fmpz_mod_poly_equal(res1, res2)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("f:\n"); fmpz_mod_poly_print(f), flint_printf("\n\n"); + flint_printf("finv:\n"); fmpz_mod_poly_print(finv), flint_printf("\n\n"); + flint_printf("res1:\n"); fmpz_mod_poly_print(res1), flint_printf("\n\n"); + flint_printf("res2:\n"); fmpz_mod_poly_print(res2), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(p); + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(f); + fmpz_mod_poly_clear(res1); + fmpz_mod_poly_clear(res2); + fmpz_mod_poly_clear(finv); + } + + /* Check that a^(b+c) = a^b * a^c */ + for (i = 0; i < 500; i++) + { + fmpz_mod_poly_t a, res1, res2, res3, res4, f, finv; + fmpz_t p; + ulong exp1, exp2, exp3; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + exp1 = n_randint(state, 50); + exp2 = n_randint(state, 50); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(f, p); + fmpz_mod_poly_init(finv, p); + fmpz_mod_poly_init(res1, p); + fmpz_mod_poly_init(res2, p); + fmpz_mod_poly_init(res3, p); + fmpz_mod_poly_init(res4, p); + + fmpz_mod_poly_randtest(a, state, n_randint(state, 50)); + fmpz_mod_poly_randtest_not_zero(f, state, n_randint(state, 50) + 1); + + fmpz_mod_poly_reverse (finv, f, f->length); + fmpz_mod_poly_inv_series_newton (finv, finv, f->length); + + fmpz_mod_poly_powmod_ui_binexp_preinv(res1, a, exp1, f, finv); + fmpz_mod_poly_powmod_ui_binexp_preinv(res2, a, exp2, f, finv); + fmpz_mod_poly_mulmod(res4, res1, res2, f); + + exp3= exp1+exp2; + fmpz_mod_poly_powmod_ui_binexp_preinv(res3, a, exp3, f, finv); + + result = (fmpz_mod_poly_equal(res4, res3)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("f:\n"); fmpz_mod_poly_print(f), flint_printf("\n\n"); + flint_printf("res3:\n"); fmpz_mod_poly_print(res3), flint_printf("\n\n"); + flint_printf("res4:\n"); fmpz_mod_poly_print(res4), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(p); + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(f); + fmpz_mod_poly_clear(finv); + fmpz_mod_poly_clear(res1); + fmpz_mod_poly_clear(res2); + fmpz_mod_poly_clear(res3); + fmpz_mod_poly_clear(res4); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/test/t-powmod_x_fmpz_preinv.c b/external/flint-2.4.3/fmpz_mod_poly/test/t-powmod_x_fmpz_preinv.c new file mode 100644 index 0000000..cd834c4 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/test/t-powmod_x_fmpz_preinv.c @@ -0,0 +1,256 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Martin Lee + +******************************************************************************/ + +#undef ulong +#define ulong ulongxx/* interferes with system includes */ + +#include +#include + +#undef ulong + +#include + +#define ulong mp_limb_t + +#include "flint.h" +#include "fmpz_vec.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("powmod_x_fmpz_preinv...."); + fflush(stdout); + + /* No aliasing */ + for (i = 0; i < 500; i++) + { + fmpz_mod_poly_t a, res1, res2, f, finv; + fmpz_t p; + ulong exp; + fmpz_t expz; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + exp = n_randint(state, 50); + + + fmpz_mod_poly_init(f, p); + fmpz_mod_poly_init(finv, p); + fmpz_mod_poly_init(res1, p); + fmpz_mod_poly_init(res2, p); + + fmpz_mod_poly_randtest_not_zero(f, state, n_randint(state, 50) + 1); + fmpz_init_set_ui(expz, exp); + + fmpz_mod_poly_reverse (finv, f, f->length); + fmpz_mod_poly_inv_series_newton (finv, finv, f->length); + + fmpz_mod_poly_init2(a, p, f->length-1); + fmpz_mod_poly_set_coeff_ui (a, 1, 1); + fmpz_mod_poly_powmod_x_fmpz_preinv(res1, expz, f, finv); + fmpz_mod_poly_powmod_fmpz_binexp_preinv(res2, a, expz, f, finv); + + result = (fmpz_mod_poly_equal(res1, res2)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("expz:\n"); fmpz_print(expz), flint_printf("\n\n"); + flint_printf("a:\n"); fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("f:\n"); fmpz_mod_poly_print(f), flint_printf("\n\n"); + flint_printf("finv:\n"); fmpz_mod_poly_print(finv), flint_printf("\n\n"); + flint_printf("res1:\n"); fmpz_mod_poly_print(res1), flint_printf("\n\n"); + flint_printf("res2:\n"); fmpz_mod_poly_print(res2), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(p); + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(f); + fmpz_mod_poly_clear(res1); + fmpz_mod_poly_clear(res2); + fmpz_mod_poly_clear(finv); + fmpz_clear(expz); + } + + /* Aliasing of res and f */ + for (i = 0; i < 250; i++) + { + fmpz_mod_poly_t res, f, finv; + fmpz_t p; + ulong exp; + fmpz_t expz; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + exp = n_randint(state, 50); + fmpz_init_set_ui(expz, exp); + + fmpz_mod_poly_init(f, p); + fmpz_mod_poly_init(finv, p); + fmpz_mod_poly_init(res, p); + + fmpz_mod_poly_randtest_not_zero(f, state, n_randint(state, 50) + 1); + + fmpz_mod_poly_reverse (finv, f, f->length); + fmpz_mod_poly_inv_series_newton (finv, finv, f->length); + + fmpz_mod_poly_powmod_x_fmpz_preinv(res, expz, f, finv); + fmpz_mod_poly_powmod_x_fmpz_preinv(f, expz, f, finv); + + result = (fmpz_mod_poly_equal(res, f)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("f:\n"); fmpz_mod_poly_print(f), flint_printf("\n\n"); + flint_printf("finv:\n"); fmpz_mod_poly_print(finv), flint_printf("\n\n"); + flint_printf("expz:\n"); fmpz_print(expz), flint_printf("\n\n"); + flint_printf("res:\n"); fmpz_mod_poly_print(res), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(p); + fmpz_mod_poly_clear(f); + fmpz_mod_poly_clear(finv); + fmpz_mod_poly_clear(res); + fmpz_clear(expz); + } + + /* Aliasing of res and finv */ + for (i = 0; i < 250; i++) + { + fmpz_mod_poly_t res, f, finv; + fmpz_t p; + ulong exp; + fmpz_t expz; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + exp = n_randint(state, 50); + fmpz_init_set_ui(expz, exp); + + fmpz_mod_poly_init(f, p); + fmpz_mod_poly_init(finv, p); + fmpz_mod_poly_init(res, p); + + fmpz_mod_poly_randtest_not_zero(f, state, n_randint(state, 50) + 1); + + + fmpz_mod_poly_reverse (finv, f, f->length); + fmpz_mod_poly_inv_series_newton (finv, finv, f->length); + + fmpz_mod_poly_powmod_x_fmpz_preinv(res, expz, f, finv); + fmpz_mod_poly_powmod_x_fmpz_preinv(finv, expz, f, finv); + + result = (fmpz_mod_poly_equal(res, finv)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("f:\n"); fmpz_mod_poly_print(f), flint_printf("\n\n"); + flint_printf("expz:\n"); fmpz_print(expz), flint_printf("\n\n"); + flint_printf("finv:\n"); fmpz_mod_poly_print(finv), flint_printf("\n\n"); + flint_printf("res:\n"); fmpz_mod_poly_print(res), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(p); + fmpz_mod_poly_clear(f); + fmpz_mod_poly_clear(finv); + fmpz_mod_poly_clear(res); + fmpz_clear(expz); + } + + /* Check that x^(b+c) = x^b * x^c */ + for (i = 0; i < 500; i++) + { + fmpz_mod_poly_t res1, res2, res3, res4, f, finv; + fmpz_t p; + fmpz_t exp1, exp2, exp3; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + fmpz_init(exp1); + fmpz_init(exp2); + fmpz_randtest(exp1, state, 200); + if (fmpz_sgn(exp1) == -1) fmpz_neg(exp1, exp1); + fmpz_randtest(exp2, state, 200); + if (fmpz_sgn(exp2) == -1) fmpz_neg(exp2, exp2); + + fmpz_mod_poly_init(f, p); + fmpz_mod_poly_init(finv, p); + fmpz_mod_poly_init(res1, p); + fmpz_mod_poly_init(res2, p); + fmpz_mod_poly_init(res3, p); + fmpz_mod_poly_init(res4, p); + + fmpz_mod_poly_randtest_not_zero(f, state, n_randint(state, 50) + 1); + + fmpz_mod_poly_reverse (finv, f, f->length); + fmpz_mod_poly_inv_series_newton (finv, finv, f->length); + + fmpz_mod_poly_powmod_x_fmpz_preinv(res1, exp1, f, finv); + fmpz_mod_poly_powmod_x_fmpz_preinv(res2, exp2, f, finv); + fmpz_mod_poly_mulmod(res4, res1, res2, f); + fmpz_init(exp3); + fmpz_add(exp3, exp1, exp2); + fmpz_mod_poly_powmod_x_fmpz_preinv(res3, exp3, f, finv); + + result = (fmpz_mod_poly_equal(res4, res3)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("f:\n"); fmpz_mod_poly_print(f), flint_printf("\n\n"); + flint_printf("res3:\n"); fmpz_mod_poly_print(res3), flint_printf("\n\n"); + flint_printf("res4:\n"); fmpz_mod_poly_print(res4), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(p); + fmpz_mod_poly_clear(f); + fmpz_mod_poly_clear(finv); + fmpz_mod_poly_clear(res1); + fmpz_mod_poly_clear(res2); + fmpz_mod_poly_clear(res3); + fmpz_mod_poly_clear(res4); + fmpz_clear(exp1); + fmpz_clear(exp2); + fmpz_clear(exp3); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/test/t-print_read.c b/external/flint-2.4.3/fmpz_mod_poly/test/t-print_read.c new file mode 100644 index 0000000..82e2eb3 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/test/t-print_read.c @@ -0,0 +1,265 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + + +#include +#include +#include +#include +#include + +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" + +#if !defined (__WIN32) || defined(__CYGWIN__) + +/* + The function fdopen is declared in stdio.h. It is POSIX.1 compliant, + but not ANSI compliant. The following line enables compilation with + the "-ansi" flag. + */ +extern FILE * fdopen(int fildes, const char *mode); + +int main(void) +{ + int i, j, n = 1000, result; + + FILE *in, *out; + int fd[2]; + pid_t childpid; + fmpz_t two; + + FLINT_TEST_INIT(state); + + fmpz_init(two); + fmpz_set_ui(two,2); + + flint_printf("print/ read...."); + fflush(stdout); + + /* Randomise n polynomials, write to and read from a pipe */ + { + fmpz_mod_poly_t *a; + + a = flint_malloc(n * sizeof(fmpz_mod_poly_t)); + for (i = 0; i < n; i++) + { + fmpz_mod_poly_init(a[i],two); + fmpz_mod_poly_randtest(a[i], state, n_randint(state, 100)); + } + + if (pipe(fd)) + { + flint_printf("FAIL:\n"); + flint_printf("Failed to set-up the pipe.\n"); + abort(); + } + + if((childpid = fork()) == -1) + { + flint_printf("FAIL:\n"); + flint_printf("Failed to fork the process.\n"); + abort(); + } + + if(childpid == 0) /* Child process */ + { + int r; + + close(fd[0]); + out = fdopen(fd[1], "w"); + if (out == NULL) + { + flint_printf("FAIL:\n"); + flint_printf("Could not open output file at the pipe.\n"); + abort(); + } + + for (j = 0; j < n; j++) + { + r = fmpz_mod_poly_fprint(out, a[j]); + if ((j < n - 1) && (r > 0)) + r = flint_fprintf(out, "\n"); + + if (r <= 0) + { + flint_printf("FAIL:\n"); + flint_printf("Write error.\n"); + abort(); + } + } + + fclose(out); + exit(0); + } + else /* Parent process */ + { + int r; + fmpz_mod_poly_t t; + + close(fd[1]); + in = fdopen(fd[0], "r"); + if (in == NULL) + { + flint_printf("FAIL:\n"); + flint_printf("Could not open input file at the pipe.\n"); + abort(); + } + + fmpz_mod_poly_init(t,two); + + i = 0; + while (!feof(in)) + { + r = fmpz_mod_poly_fread(in, t); + if (r <= 0) + { + flint_printf("FAIL:\n"); + flint_printf("Read error.\n"); + abort(); + } + + result = fmpz_mod_poly_equal(t, a[i]); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a[i] = "), fmpz_mod_poly_print(a[i]), flint_printf("\n"); + flint_printf("t = "), fmpz_mod_poly_print(t), flint_printf("\n"); + abort(); + } + + ++i; + } + + fmpz_mod_poly_clear(t); + fclose(in); + } + + if (i != n) + { + flint_printf("FAIL:\n"); + flint_printf("Only %d out of %d objects were processed.\n", i, n); + abort(); + } + + for (i = 0; i < n; i++) + fmpz_mod_poly_clear(a[i]); + flint_free(a); + } + + /* Write bad data to a pipe and read it */ + { + if (pipe(fd)) + { + flint_printf("FAIL:\n"); + flint_printf("Failed to set-up the pipe.\n"); + abort(); + } + + if((childpid = fork()) == -1) + { + flint_printf("FAIL:\n"); + flint_printf("Failed to fork the process.\n"); + abort(); + } + + if(childpid == 0) /* Child process */ + { + int r; + + close(fd[0]); + out = fdopen(fd[1], "w"); + if (out == NULL) + { + flint_printf("FAIL:\n"); + flint_printf("Could not open output file at the pipe.\n"); + abort(); + } + + r = flint_fprintf(out, "blah"); + if (r <= 0) + { + flint_printf("FAIL:\n"); + flint_printf("Write error.\n"); + abort(); + } + + fclose(out); + exit(0); + } + else /* Parent process */ + { + int r; + fmpz_mod_poly_t t; + + close(fd[1]); + in = fdopen(fd[0], "r"); + if (in == NULL) + { + flint_printf("FAIL:\n"); + flint_printf("Could not open input file at the pipe.\n"); + abort(); + } + + fmpz_mod_poly_init(t,two); + + i = 0; + /* Only four junk bytes are sent and our read + doesn't consume invalid bytes, so eof is never reached */ + for(i=0; i<500; i++) + { + r = fmpz_mod_poly_fread(in, t); + if (r > 0) + { + flint_printf("FAIL:\n"); + flint_printf("r = %d\n", r); + abort(); + } + } + + fmpz_mod_poly_clear(t); + fclose(in); + } + } + + fmpz_clear(two); + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + +#else + +int main(void) +{ + flint_printf("print/ read...."); + fflush(stdout); + flint_printf("SKIPPED\n"); + return EXIT_SUCCESS; +} + +#endif diff --git a/external/flint-2.4.3/fmpz_mod_poly/test/t-radix.c b/external/flint-2.4.3/fmpz_mod_poly/test/t-radix.c new file mode 100644 index 0000000..be80fed --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/test/t-radix.c @@ -0,0 +1,148 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2010 Sebastian Pancratz + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +static int _check(fmpz_mod_poly_struct **B, + const fmpz_mod_poly_t F, const fmpz_mod_poly_t R) +{ + const slong lenF = F->length; + const slong lenR = R->length; + const slong N = (lenF - 1) / (lenR - 1); + + slong i; + int result; + + fmpz_mod_poly_t S; + + fmpz_mod_poly_init(S, &(R->p)); + fmpz_mod_poly_set(S, B[N]); + for (i = N; i > 0; i--) + { + fmpz_mod_poly_mul(S, S, R); + fmpz_mod_poly_add(S, S, B[i - 1]); + } + result = fmpz_mod_poly_equal(F, S); + fmpz_mod_poly_clear(S); + return result; +} + +int main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("radix...."); + fflush(stdout); + + + + for (i = 0; i < 500; i++) + { + fmpz_t p; + fmpz_mod_poly_t f, r; + fmpz_mod_poly_struct **b; + fmpz_mod_poly_radix_t D; + slong j, N; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(f, p); + fmpz_mod_poly_init(r, p); + fmpz_mod_poly_randtest(f, state, n_randint(state, 500)); + do + fmpz_mod_poly_randtest_not_zero(r, state, n_randint(state, 20) + 2); + while (r->length < 2); + + N = FLINT_MAX(0, fmpz_mod_poly_degree(f) / fmpz_mod_poly_degree(r)); + b = flint_malloc((N + 1) * sizeof(fmpz_mod_poly_struct *)); + for (j = 0; j <= N; j++) + { + b[j] = flint_malloc(sizeof(fmpz_mod_poly_struct)); + fmpz_mod_poly_init(b[j], p); + } + + /* Ensure that lead(r) is a unit mod p */ + { + fmpz_t d; + fmpz *leadR = fmpz_mod_poly_lead(r); + + fmpz_init(d); + fmpz_gcd(d, p, leadR); + while (!fmpz_is_one(d)) + { + fmpz_divexact(leadR, leadR, d); + fmpz_gcd(d, p, leadR); + } + fmpz_clear(d); + } + + fmpz_mod_poly_radix_init(D, r, f->length - 1 + n_randint(state, 50)); + + fmpz_mod_poly_radix(b, f, D); + + result = _check(b, f, r); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("result = %d\n", result); + flint_printf("p = "), fmpz_print(p), flint_printf("\n\n"); + flint_printf("f = "), fmpz_mod_poly_print(f), flint_printf("\n\n"); + flint_printf("r = "), fmpz_mod_poly_print(r), flint_printf("\n\n"); + flint_printf("N = %wd\n\n", N); + for (j = 0; j <= N; j++) + { + flint_printf("b[%wd] = ", j), fmpz_mod_poly_print(b[j]), flint_printf("\n\n"); + } + abort(); + } + + fmpz_mod_poly_clear(f); + fmpz_mod_poly_clear(r); + fmpz_mod_poly_radix_clear(D); + for (j = 0; j <= N; j++) + { + fmpz_mod_poly_clear(b[j]); + flint_free(b[j]); + } + flint_free(b); + fmpz_clear(p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/test/t-rem_basecase.c b/external/flint-2.4.3/fmpz_mod_poly/test/t-rem_basecase.c new file mode 100644 index 0000000..84d936d --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/test/t-rem_basecase.c @@ -0,0 +1,206 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("rem_basecase...."); + fflush(stdout); + + + + /* Check q*b + r = a, no aliasing */ + for (i = 0; i < 5000; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, q, r, t; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(q, p); + fmpz_mod_poly_init(r, p); + fmpz_mod_poly_init(t, p); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + fmpz_mod_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1); + + { + fmpz_t d; + fmpz *leadB = fmpz_mod_poly_lead(b); + + fmpz_init(d); + fmpz_gcd(d, p, leadB); + while (!fmpz_is_one(d)) + { + fmpz_divexact(leadB, leadB, d); + fmpz_gcd(d, p, leadB); + } + fmpz_clear(d); + } + + fmpz_mod_poly_divrem_basecase(q, r, a, b); + fmpz_mod_poly_rem_basecase(t, a, b); + + result = (fmpz_mod_poly_equal(r, t)); + if (!result) + { + flint_printf("FAIL (cmp with divrem):\n"); + flint_printf("p = "), fmpz_print(p), flint_printf("\n\n"); + flint_printf("a = "), fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_mod_poly_print(b), flint_printf("\n\n"); + flint_printf("q = "), fmpz_mod_poly_print(q), flint_printf("\n\n"); + flint_printf("r = "), fmpz_mod_poly_print(r), flint_printf("\n\n"); + flint_printf("t = "), fmpz_mod_poly_print(t), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(q); + fmpz_mod_poly_clear(r); + fmpz_mod_poly_clear(t); + fmpz_clear(p); + } + + /* Alias b and r */ + for (i = 0; i < 500; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, r; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(r, p); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + fmpz_mod_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1); + + { + fmpz_t d; + fmpz *leadB = fmpz_mod_poly_lead(b); + + fmpz_init(d); + fmpz_gcd(d, p, leadB); + while (!fmpz_is_one(d)) + { + fmpz_divexact(leadB, leadB, d); + fmpz_gcd(d, p, leadB); + } + fmpz_clear(d); + } + + fmpz_mod_poly_rem_basecase(r, a, b); + fmpz_mod_poly_rem_basecase(b, a, b); + + result = (fmpz_mod_poly_equal(r, b)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("p = "), fmpz_print(p), flint_printf("\n\n"); + flint_printf("a = "), fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_mod_poly_print(b), flint_printf("\n\n"); + flint_printf("r = "), fmpz_mod_poly_print(r), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(r); + fmpz_clear(p); + } + + /* a and r */ + for (i = 0; i < 500; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, r; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(r, p); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + fmpz_mod_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1); + + { + fmpz_t d; + fmpz *leadB = fmpz_mod_poly_lead(b); + + fmpz_init(d); + fmpz_gcd(d, p, leadB); + while (!fmpz_is_one(d)) + { + fmpz_divexact(leadB, leadB, d); + fmpz_gcd(d, p, leadB); + } + fmpz_clear(d); + } + + fmpz_mod_poly_rem_basecase(r, a, b); + fmpz_mod_poly_rem_basecase(a, a, b); + + result = (fmpz_mod_poly_equal(r, a)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("p = "), fmpz_print(p), flint_printf("\n\n"); + flint_printf("a = "), fmpz_mod_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_mod_poly_print(b), flint_printf("\n\n"); + flint_printf("r = "), fmpz_mod_poly_print(r), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(r); + fmpz_clear(p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/test/t-scalar_mul_fmpz.c b/external/flint-2.4.3/fmpz_mod_poly/test/t-scalar_mul_fmpz.c new file mode 100644 index 0000000..7eec6e4 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/test/t-scalar_mul_fmpz.c @@ -0,0 +1,86 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("scalar_mul_fmpz...."); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 10000; i++) + { + fmpz_t n, p; + fmpz_mod_poly_t a, b; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_init(n); + fmpz_randtest(n, state, 200); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + + fmpz_mod_poly_scalar_mul_fmpz(b, a, n); + fmpz_mod_poly_scalar_mul_fmpz(a, a, n); + + result = (fmpz_mod_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_mod_poly_print(a), flint_printf("\n\n"); + fmpz_mod_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(n); + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_clear(p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/test/t-set_equal.c b/external/flint-2.4.3/fmpz_mod_poly/test/t-set_equal.c new file mode 100644 index 0000000..e86be40 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/test/t-set_equal.c @@ -0,0 +1,120 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("set/equal...."); + fflush(stdout); + + + + /* Equal polynomials */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + + fmpz_mod_poly_set(b, a); + + result = (fmpz_mod_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_mod_poly_print(a), flint_printf("\n\n"); + fmpz_mod_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + + fmpz_clear(p); + } + + for (i = 0; i < 10000; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b; + slong coeff = n_randint(state, 100); + fmpz_t x; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_init(x); + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + + fmpz_mod_poly_set(b, a); + + fmpz_mod_poly_get_coeff_fmpz(x, b, coeff); + fmpz_sub_ui(x, x, 1); + fmpz_mod_poly_set_coeff_fmpz(b, coeff, x); + + result = (!fmpz_mod_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("p = "), fmpz_print(p), flint_printf("\n\n"); + fmpz_mod_poly_print(a), flint_printf("\n\n"); + fmpz_mod_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(x); + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + + fmpz_clear(p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/test/t-shift_left_right.c b/external/flint-2.4.3/fmpz_mod_poly/test/t-shift_left_right.c new file mode 100644 index 0000000..5613172 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/test/t-shift_left_right.c @@ -0,0 +1,151 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("shift_left/right...."); + fflush(stdout); + + + + /* Check aliasing of a and b for left shift */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b; + slong shift = n_randint(state, 100); + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_randtest(a, state, 200); + + fmpz_mod_poly_shift_left(b, a, shift); + fmpz_mod_poly_shift_left(a, a, shift); + + result = (fmpz_mod_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_mod_poly_print(a), flint_printf("\n\n"); + fmpz_mod_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_clear(p); + } + + /* Check aliasing of a and b for right shift */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b; + slong shift; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_randtest_not_zero(a, state, 200); + + shift = n_randint(state, a->length); + + fmpz_mod_poly_shift_right(b, a, shift); + fmpz_mod_poly_shift_right(a, a, shift); + + result = (fmpz_mod_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_mod_poly_print(a), flint_printf("\n\n"); + fmpz_mod_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_clear(p); + } + + /* Check shift left then right does nothing */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, c; + slong shift = n_randint(state, 100); + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + fmpz_mod_poly_randtest(a, state, 200); + + fmpz_mod_poly_shift_left(b, a, shift); + fmpz_mod_poly_shift_right(c, b, shift); + + result = (fmpz_mod_poly_equal(c, a)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_mod_poly_print(a), flint_printf("\n\n"); + fmpz_mod_poly_print(b), flint_printf("\n\n"); + fmpz_mod_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(c); + fmpz_clear(p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/test/t-sub.c b/external/flint-2.4.3/fmpz_mod_poly/test/t-sub.c new file mode 100644 index 0000000..c927587 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/test/t-sub.c @@ -0,0 +1,160 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("sub...."); + fflush(stdout); + + + + /* Check a - b = a + neg(b) */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, c, d; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + fmpz_mod_poly_init(d, p); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + fmpz_mod_poly_randtest(b, state, n_randint(state, 100)); + + fmpz_mod_poly_sub(c, a, b); + fmpz_mod_poly_neg(b, b); + fmpz_mod_poly_add(d, a, b); + + result = (fmpz_mod_poly_equal(d, d)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_mod_poly_print(a), flint_printf("\n\n"); + fmpz_mod_poly_print(b), flint_printf("\n\n"); + fmpz_mod_poly_print(c), flint_printf("\n\n"); + fmpz_mod_poly_print(d), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(c); + fmpz_mod_poly_clear(d); + fmpz_clear(p); + } + + /* Check aliasing of a and c */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, c; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + fmpz_mod_poly_randtest(b, state, n_randint(state, 100)); + + fmpz_mod_poly_sub(c, a, b); + fmpz_mod_poly_sub(a, a, b); + + result = (fmpz_mod_poly_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_mod_poly_print(a), flint_printf("\n\n"); + fmpz_mod_poly_print(b), flint_printf("\n\n"); + fmpz_mod_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(c); + fmpz_clear(p); + } + + /* Check aliasing of b and c */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, c; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + fmpz_mod_poly_randtest(b, state, n_randint(state, 100)); + + fmpz_mod_poly_sub(c, a, b); + fmpz_mod_poly_sub(b, a, b); + + result = (fmpz_mod_poly_equal(b, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_mod_poly_print(a), flint_printf("\n\n"); + fmpz_mod_poly_print(b), flint_printf("\n\n"); + fmpz_mod_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(c); + fmpz_clear(p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/test/t-swap.c b/external/flint-2.4.3/fmpz_mod_poly/test/t-swap.c new file mode 100644 index 0000000..1aa0451 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/test/t-swap.c @@ -0,0 +1,84 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("swap...."); + fflush(stdout); + + + + for (i = 0; i < 10000; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, c; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(c, p); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + fmpz_mod_poly_randtest(b, state, n_randint(state, 100)); + + fmpz_mod_poly_set(c, b); + fmpz_mod_poly_swap(a, b); + + result = (fmpz_mod_poly_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_mod_poly_print(a), flint_printf("\n\n"); + fmpz_mod_poly_print(b), flint_printf("\n\n"); + fmpz_mod_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(c); + fmpz_clear(p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/test/t-xgcd.c b/external/flint-2.4.3/fmpz_mod_poly/test/t-xgcd.c new file mode 100644 index 0000000..df9704d --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/test/t-xgcd.c @@ -0,0 +1,166 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("xgcd...."); + fflush(stdout); + + + + /* Generic case, most likely co-prime arguments ******************************/ + + /* Compare with result from GCD and check correctness */ + for (i = 0; i < 1000; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, d, g, s, t, v, w; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(d, p); + fmpz_mod_poly_init(g, p); + fmpz_mod_poly_init(s, p); + fmpz_mod_poly_init(t, p); + fmpz_mod_poly_init(v, p); + fmpz_mod_poly_init(w, p); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + fmpz_mod_poly_randtest(b, state, n_randint(state, 100)); + + fmpz_mod_poly_gcd(d, a, b); + fmpz_mod_poly_xgcd(g, s, t, a, b); + + fmpz_mod_poly_mul(v, s, a); + fmpz_mod_poly_mul(w, t, b); + fmpz_mod_poly_add(w, v, w); + + result = (fmpz_mod_poly_equal(d, g) && fmpz_mod_poly_equal(g, w)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_mod_poly_print(a), flint_printf("\n\n"); + fmpz_mod_poly_print(b), flint_printf("\n\n"); + fmpz_mod_poly_print(d), flint_printf("\n\n"); + fmpz_mod_poly_print(g), flint_printf("\n\n"); + fmpz_mod_poly_print(s), flint_printf("\n\n"); + fmpz_mod_poly_print(t), flint_printf("\n\n"); + fmpz_mod_poly_print(v), flint_printf("\n\n"); + fmpz_mod_poly_print(w), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(d); + fmpz_mod_poly_clear(g); + fmpz_mod_poly_clear(s); + fmpz_mod_poly_clear(t); + fmpz_mod_poly_clear(v); + fmpz_mod_poly_clear(w); + fmpz_clear(p); + } + + /* Special case, arguments share a factor ********************************/ + + /* Compare with result from GCD and check correctness */ + for (i = 0; i < 1000; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, d, f, g, s, t, v, w; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(d, p); + fmpz_mod_poly_init(f, p); + fmpz_mod_poly_init(g, p); + fmpz_mod_poly_init(s, p); + fmpz_mod_poly_init(t, p); + fmpz_mod_poly_init(v, p); + fmpz_mod_poly_init(w, p); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + fmpz_mod_poly_randtest(b, state, n_randint(state, 100)); + fmpz_mod_poly_randtest(f, state, n_randint(state, 20)); + fmpz_mod_poly_mul(a, a, f); + fmpz_mod_poly_mul(b, b, f); + + fmpz_mod_poly_gcd(d, a, b); + fmpz_mod_poly_xgcd(g, s, t, a, b); + + fmpz_mod_poly_mul(v, s, a); + fmpz_mod_poly_mul(w, t, b); + fmpz_mod_poly_add(w, v, w); + + result = (fmpz_mod_poly_equal(d, g) && fmpz_mod_poly_equal(g, w)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_mod_poly_print(a), flint_printf("\n\n"); + fmpz_mod_poly_print(b), flint_printf("\n\n"); + fmpz_mod_poly_print(d), flint_printf("\n\n"); + fmpz_mod_poly_print(f), flint_printf("\n\n"); + fmpz_mod_poly_print(g), flint_printf("\n\n"); + fmpz_mod_poly_print(s), flint_printf("\n\n"); + fmpz_mod_poly_print(t), flint_printf("\n\n"); + fmpz_mod_poly_print(v), flint_printf("\n\n"); + fmpz_mod_poly_print(w), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(d); + fmpz_mod_poly_clear(f); + fmpz_mod_poly_clear(g); + fmpz_mod_poly_clear(s); + fmpz_mod_poly_clear(t); + fmpz_mod_poly_clear(v); + fmpz_mod_poly_clear(w); + fmpz_clear(p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/test/t-xgcd_euclidean.c b/external/flint-2.4.3/fmpz_mod_poly/test/t-xgcd_euclidean.c new file mode 100644 index 0000000..1de400a --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/test/t-xgcd_euclidean.c @@ -0,0 +1,166 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("xgcd_euclidean...."); + fflush(stdout); + + + + /* Generic case, most likely co-prime arguments ******************************/ + + /* Compare with result from GCD and check correctness */ + for (i = 0; i < 1000; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, d, g, s, t, v, w; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(d, p); + fmpz_mod_poly_init(g, p); + fmpz_mod_poly_init(s, p); + fmpz_mod_poly_init(t, p); + fmpz_mod_poly_init(v, p); + fmpz_mod_poly_init(w, p); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + fmpz_mod_poly_randtest(b, state, n_randint(state, 100)); + + fmpz_mod_poly_gcd_euclidean(d, a, b); + fmpz_mod_poly_xgcd_euclidean(g, s, t, a, b); + + fmpz_mod_poly_mul(v, s, a); + fmpz_mod_poly_mul(w, t, b); + fmpz_mod_poly_add(w, v, w); + + result = (fmpz_mod_poly_equal(d, g) && fmpz_mod_poly_equal(g, w)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_mod_poly_print(a), flint_printf("\n\n"); + fmpz_mod_poly_print(b), flint_printf("\n\n"); + fmpz_mod_poly_print(d), flint_printf("\n\n"); + fmpz_mod_poly_print(g), flint_printf("\n\n"); + fmpz_mod_poly_print(s), flint_printf("\n\n"); + fmpz_mod_poly_print(t), flint_printf("\n\n"); + fmpz_mod_poly_print(v), flint_printf("\n\n"); + fmpz_mod_poly_print(w), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(d); + fmpz_mod_poly_clear(g); + fmpz_mod_poly_clear(s); + fmpz_mod_poly_clear(t); + fmpz_mod_poly_clear(v); + fmpz_mod_poly_clear(w); + fmpz_clear(p); + } + + /* Special case, arguments share a factor ********************************/ + + /* Compare with result from GCD and check correctness */ + for (i = 0; i < 1000; i++) + { + fmpz_t p; + fmpz_mod_poly_t a, b, d, f, g, s, t, v, w; + + fmpz_init(p); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(d, p); + fmpz_mod_poly_init(f, p); + fmpz_mod_poly_init(g, p); + fmpz_mod_poly_init(s, p); + fmpz_mod_poly_init(t, p); + fmpz_mod_poly_init(v, p); + fmpz_mod_poly_init(w, p); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + fmpz_mod_poly_randtest(b, state, n_randint(state, 100)); + fmpz_mod_poly_randtest(f, state, n_randint(state, 20)); + fmpz_mod_poly_mul(a, a, f); + fmpz_mod_poly_mul(b, b, f); + + fmpz_mod_poly_gcd_euclidean(d, a, b); + fmpz_mod_poly_xgcd_euclidean(g, s, t, a, b); + + fmpz_mod_poly_mul(v, s, a); + fmpz_mod_poly_mul(w, t, b); + fmpz_mod_poly_add(w, v, w); + + result = (fmpz_mod_poly_equal(d, g) && fmpz_mod_poly_equal(g, w)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_mod_poly_print(a), flint_printf("\n\n"); + fmpz_mod_poly_print(b), flint_printf("\n\n"); + fmpz_mod_poly_print(d), flint_printf("\n\n"); + fmpz_mod_poly_print(f), flint_printf("\n\n"); + fmpz_mod_poly_print(g), flint_printf("\n\n"); + fmpz_mod_poly_print(s), flint_printf("\n\n"); + fmpz_mod_poly_print(t), flint_printf("\n\n"); + fmpz_mod_poly_print(v), flint_printf("\n\n"); + fmpz_mod_poly_print(w), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(d); + fmpz_mod_poly_clear(f); + fmpz_mod_poly_clear(g); + fmpz_mod_poly_clear(s); + fmpz_mod_poly_clear(t); + fmpz_mod_poly_clear(v); + fmpz_mod_poly_clear(w); + fmpz_clear(p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/test/t-zero.c b/external/flint-2.4.3/fmpz_mod_poly/test/t-zero.c new file mode 100644 index 0000000..4eda965 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/test/t-zero.c @@ -0,0 +1,75 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("zero...."); + fflush(stdout); + + + + for (i = 0; i < 10000; i++) + { + fmpz_t p; + fmpz_mod_poly_t a; + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_mod_poly_init(a, p); + fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); + fmpz_mod_poly_zero(a); + + result = (fmpz_mod_poly_is_zero(a)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpz_mod_poly_print(a), flint_printf("\n\n"); + abort(); + } + + fmpz_mod_poly_clear(a); + fmpz_clear(p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/tree.c b/external/flint-2.4.3/fmpz_mod_poly/tree.c new file mode 100644 index 0000000..540e59a --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/tree.c @@ -0,0 +1,115 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" +#include "fmpz_mod_poly.h" + +fmpz_poly_struct ** _fmpz_mod_poly_tree_alloc(slong len) +{ + fmpz_poly_struct ** tree = NULL; + + if (len) + { + slong i, j, height = FLINT_CLOG2(len); + + tree = flint_malloc(sizeof(fmpz_poly_struct *) * (height + 1)); + for (i = 0; i <= height; i++, len = (len + 1)/2) + { + tree[i] = flint_malloc(sizeof(fmpz_poly_struct) * len); + for (j = 0; j < len; j++) + fmpz_poly_init(tree[i] + j); + } + + } + + return tree; +} + +void _fmpz_mod_poly_tree_free(fmpz_poly_struct ** tree, slong len) +{ + if (len) + { + slong i, j, height = FLINT_CLOG2(len); + + for (i = 0; i <= height; i++, len = (len + 1)/2) + { + for (j = 0; j < len; j++) + fmpz_poly_clear(tree[i] + j); + flint_free(tree[i]); + } + + flint_free(tree); + } +} + +void +_fmpz_mod_poly_tree_build(fmpz_poly_struct ** tree, const fmpz * roots, slong len, const fmpz_t mod) +{ + slong height, pow, left, i; + fmpz_poly_struct * pa, * pb; + + if (len == 0) + return; + + height = FLINT_CLOG2(len); + + /* zeroth level, (x-a) */ + for (i = 0; i < len; i++) + { + fmpz_poly_set_coeff_ui(tree[0] + i, 1, 1); + fmpz_negmod((tree[0] + i)->coeffs, roots + i, mod); + } + + for (i = 0; i < height - 1; i++) + { + left = len; + pow = WORD(1) << i; + pa = tree[i]; + pb = tree[i + 1]; + + while (left >= 2 * pow) + { + fmpz_poly_fit_length(pb, pa->length + (pa + 1)->length - 1); + _fmpz_mod_poly_mul(pb->coeffs, pa->coeffs, pa->length, (pa + 1)->coeffs, (pa + 1)->length, mod); + _fmpz_poly_set_length(pb, pa->length + (pa + 1)->length - 1); + left -= 2 * pow; + pa += 2; + pb += 1; + } + + if (left > pow) + { + fmpz_poly_fit_length(pb, pa->length + (pa + 1)->length - 1); + _fmpz_mod_poly_mul(pb->coeffs, pa->coeffs, pa->length, (pa + 1)->coeffs, (pa + 1)->length, mod); + _fmpz_poly_set_length(pb, pa->length + (pa + 1)->length - 1); + } else if (left > 0) + fmpz_poly_set(pb, pa); + } +} diff --git a/external/flint-2.4.3/fmpz_mod_poly/xgcd_euclidean.c b/external/flint-2.4.3/fmpz_mod_poly/xgcd_euclidean.c new file mode 100644 index 0000000..c4bb01a --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/xgcd_euclidean.c @@ -0,0 +1,243 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "fmpz_vec.h" +#include "fmpz_mod_poly.h" + +slong _fmpz_mod_poly_xgcd_euclidean(fmpz *G, fmpz *S, fmpz *T, + const fmpz *A, slong lenA, + const fmpz *B, slong lenB, + const fmpz_t invB, const fmpz_t p) +{ + _fmpz_vec_zero(G, lenB); + _fmpz_vec_zero(S, lenB - 1); + _fmpz_vec_zero(T, lenA - 1); + + if (lenB == 1) + { + fmpz_set(G + 0, B + 0); + fmpz_one(T + 0); + return 1; + } + else + { + fmpz *Q, *R; + slong lenQ, lenR; + + Q = _fmpz_vec_init(2 * lenA); + R = Q + lenA; + + _fmpz_mod_poly_divrem(Q, R, A, lenA, B, lenB, invB, p); + lenR = lenB - 1; + FMPZ_VEC_NORM(R, lenR); + + if (lenR == 0) + { + _fmpz_vec_set(G, B, lenB); + fmpz_one(T + 0); + + _fmpz_vec_clear(Q, 2 * lenA); + return lenB; + } + else + { + fmpz_t inv; + fmpz *D, *U, *V1, *V3, *W; + slong lenD, lenU, lenV1, lenV3, lenW; + + fmpz_init(inv); + W = _fmpz_vec_init(FLINT_MAX(5 * lenB, lenA + lenB)); + D = W + lenB; + U = D + lenB; + V1 = U + lenB; + V3 = V1 + lenB; + + lenU = 0; + _fmpz_vec_set(D, B, lenB); + lenD = lenB; + fmpz_one(V1 + 0); + lenV1 = 1; + lenV3 = 0; + FMPZ_VEC_SWAP(V3, lenV3, R, lenR); + + do { + fmpz_invmod(inv, V3 + (lenV3 - 1), p); + _fmpz_mod_poly_divrem(Q, R, D, lenD, V3, lenV3, inv, p); + lenQ = lenD - lenV3 + 1; + lenR = lenV3 - 1; + FMPZ_VEC_NORM(R, lenR); + + if (lenV1 >= lenQ) + _fmpz_mod_poly_mul(W, V1, lenV1, Q, lenQ, p); + else + _fmpz_mod_poly_mul(W, Q, lenQ, V1, lenV1, p); + lenW = lenQ + lenV1 - 1; + + _fmpz_mod_poly_sub(U, U, lenU, W, lenW, p); + lenU = FLINT_MAX(lenU, lenW); + FMPZ_VEC_NORM(U, lenU); + + FMPZ_VEC_SWAP(U, lenU, V1, lenV1); + { + fmpz *__t; + slong __tn; + + __t = D; + D = V3; + V3 = R; + R = __t; + __tn = lenD; + lenD = lenV3; + lenV3 = lenR; + lenR = __tn; + } + + } while (lenV3 != 0); + + _fmpz_vec_set(G, D, lenD); + _fmpz_vec_set(S, U, lenU); + { + lenQ = lenA + lenU - 1; + + _fmpz_mod_poly_mul(Q, A, lenA, S, lenU, p); + _fmpz_mod_poly_neg(Q, Q, lenQ, p); + _fmpz_mod_poly_add(Q, G, lenD, Q, lenQ, p); + + _fmpz_mod_poly_divrem(T, W, Q, lenQ, B, lenB, invB, p); + } + + _fmpz_vec_clear(W, FLINT_MAX(5 * lenB, lenA + lenB)); + _fmpz_vec_clear(Q, 2 * lenA); + fmpz_clear(inv); + + return lenD; + } + } +} + +void +fmpz_mod_poly_xgcd_euclidean(fmpz_mod_poly_t G, + fmpz_mod_poly_t S, fmpz_mod_poly_t T, + const fmpz_mod_poly_t A, const fmpz_mod_poly_t B) +{ + if (A->length < B->length) + { + fmpz_mod_poly_xgcd_euclidean(G, T, S, B, A); + } + else /* lenA >= lenB >= 0 */ + { + const slong lenA = A->length, lenB = B->length; + fmpz_t inv; + + fmpz_init(inv); + if (lenA == 0) /* lenA = lenB = 0 */ + { + fmpz_mod_poly_zero(G); + fmpz_mod_poly_zero(S); + fmpz_mod_poly_zero(T); + } + else if (lenB == 0) /* lenA > lenB = 0 */ + { + fmpz_invmod(inv, fmpz_mod_poly_lead(A), &A->p); + fmpz_mod_poly_scalar_mul_fmpz(G, A, inv); + fmpz_mod_poly_zero(T); + fmpz_mod_poly_set_fmpz(S, inv); + } + else /* lenA >= lenB >= 2 */ + { + fmpz *g, *s, *t; + slong lenG; + + if (G == A || G == B) + { + g = _fmpz_vec_init(FLINT_MIN(lenA, lenB)); + } + else + { + fmpz_mod_poly_fit_length(G, FLINT_MIN(lenA, lenB)); + g = G->coeffs; + } + if (S == A || S == B) + { + s = _fmpz_vec_init(lenB); + } + else + { + fmpz_mod_poly_fit_length(S, lenB); + s = S->coeffs; + } + if (T == A || T == B) + { + t = _fmpz_vec_init(lenA); + } + else + { + fmpz_mod_poly_fit_length(T, lenA); + t = T->coeffs; + } + + fmpz_invmod(inv, fmpz_mod_poly_lead(B), &B->p); + lenG = _fmpz_mod_poly_xgcd_euclidean(g, s, t, + A->coeffs, lenA, B->coeffs, lenB, inv, &B->p); + + if (G == A || G == B) + { + _fmpz_vec_clear(G->coeffs, G->alloc); + G->coeffs = g; + G->alloc = FLINT_MIN(lenA, lenB); + } + if (S == A || S == B) + { + _fmpz_vec_clear(S->coeffs, S->alloc); + S->coeffs = s; + S->alloc = lenB; + } + if (T == A || T == B) + { + _fmpz_vec_clear(T->coeffs, T->alloc); + T->coeffs = t; + T->alloc = lenA; + } + + _fmpz_mod_poly_set_length(G, lenG); + _fmpz_mod_poly_set_length(S, FLINT_MAX(lenB - lenG, 1)); + _fmpz_mod_poly_set_length(T, FLINT_MAX(lenA - lenG, 1)); + _fmpz_mod_poly_normalise(S); + _fmpz_mod_poly_normalise(T); + + if (!fmpz_is_one(fmpz_mod_poly_lead(G))) + { + fmpz_invmod(inv, fmpz_mod_poly_lead(G), &A->p); + fmpz_mod_poly_scalar_mul_fmpz(G, G, inv); + fmpz_mod_poly_scalar_mul_fmpz(S, S, inv); + fmpz_mod_poly_scalar_mul_fmpz(T, T, inv); + } + } + fmpz_clear(inv); + } +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly/zero_coeffs.c b/external/flint-2.4.3/fmpz_mod_poly/zero_coeffs.c new file mode 100644 index 0000000..f6b5455 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly/zero_coeffs.c @@ -0,0 +1,46 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mod_poly.h" + +void fmpz_mod_poly_zero_coeffs(fmpz_mod_poly_t poly, slong i, slong j) +{ + if (i < 0) + i = 0; + if (j > poly->length) + j = poly->length; + + _fmpz_vec_zero(poly->coeffs + i, j - i); + + if (j == poly->length) + { + _fmpz_mod_poly_set_length(poly, i); + _fmpz_mod_poly_normalise(poly); + } +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly_factor.h b/external/flint-2.4.3/fmpz_mod_poly_factor.h new file mode 100644 index 0000000..a1f674c --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly_factor.h @@ -0,0 +1,117 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2012 Lina Kulakova + +******************************************************************************/ + +#ifndef FMPZ_MOD_POLY_FACTOR_H +#define FMPZ_MOD_POLY_FACTOR_H + +#undef ulong +#define ulong ulongxx /* interferes with system includes */ +#include +#undef ulong +#include +#define ulong mp_limb_t + +#include "flint.h" +#include "fmpz.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/* Factoring ****************************************************************/ + +typedef struct +{ + fmpz_mod_poly_struct *poly; + slong *exp; + slong num; + slong alloc; +} fmpz_mod_poly_factor_struct; + +typedef fmpz_mod_poly_factor_struct fmpz_mod_poly_factor_t[1]; + +void fmpz_mod_poly_factor_init(fmpz_mod_poly_factor_t fac); + +void fmpz_mod_poly_factor_clear(fmpz_mod_poly_factor_t fac); + +void fmpz_mod_poly_factor_realloc(fmpz_mod_poly_factor_t fac, slong alloc); + +void fmpz_mod_poly_factor_fit_length(fmpz_mod_poly_factor_t fac, slong len); + +void fmpz_mod_poly_factor_set(fmpz_mod_poly_factor_t res, const fmpz_mod_poly_factor_t fac); + +void fmpz_mod_poly_factor_insert(fmpz_mod_poly_factor_t fac, + const fmpz_mod_poly_t poly, slong exp); + +void fmpz_mod_poly_factor_print(const fmpz_mod_poly_factor_t fac); + +void fmpz_mod_poly_factor_concat(fmpz_mod_poly_factor_t res, + const fmpz_mod_poly_factor_t fac); + +void fmpz_mod_poly_factor_pow(fmpz_mod_poly_factor_t fac, slong exp); + +int fmpz_mod_poly_is_irreducible(const fmpz_mod_poly_t f); + +int fmpz_mod_poly_is_irreducible_ddf(const fmpz_mod_poly_t f); + +int fmpz_mod_poly_is_irreducible_rabin(const fmpz_mod_poly_t f); + +int +_fmpz_mod_poly_is_squarefree(const fmpz * f, slong len, const fmpz_t p); + +int fmpz_mod_poly_is_squarefree(const fmpz_mod_poly_t f); + +int +fmpz_mod_poly_factor_equal_deg_prob(fmpz_mod_poly_t factor, + flint_rand_t state, const fmpz_mod_poly_t pol, slong d); + +void +fmpz_mod_poly_factor_equal_deg(fmpz_mod_poly_factor_t factors, + const fmpz_mod_poly_t pol, slong d); + +void fmpz_mod_poly_factor_distinct_deg(fmpz_mod_poly_factor_t res, + const fmpz_mod_poly_t poly, slong * const *degs); + +void fmpz_mod_poly_factor_squarefree(fmpz_mod_poly_factor_t res, + const fmpz_mod_poly_t f); + +void fmpz_mod_poly_factor(fmpz_mod_poly_factor_t res, + const fmpz_mod_poly_t f); + +void fmpz_mod_poly_factor_cantor_zassenhaus(fmpz_mod_poly_factor_t res, + const fmpz_mod_poly_t f); + +void fmpz_mod_poly_factor_kaltofen_shoup(fmpz_mod_poly_factor_t res, + const fmpz_mod_poly_t poly); + +void fmpz_mod_poly_factor_berlekamp(fmpz_mod_poly_factor_t factors, + const fmpz_mod_poly_t f); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/flint-2.4.3/fmpz_mod_poly_factor/clear.c b/external/flint-2.4.3/fmpz_mod_poly_factor/clear.c new file mode 100644 index 0000000..0bd8d97 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly_factor/clear.c @@ -0,0 +1,44 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz_mod_poly.h" + +void +fmpz_mod_poly_factor_clear(fmpz_mod_poly_factor_t fac) +{ + slong i; + + for (i = 0; i < fac->alloc; i++) + fmpz_mod_poly_clear(fac->poly + i); + + flint_free(fac->poly); + flint_free(fac->exp); +} diff --git a/external/flint-2.4.3/fmpz_mod_poly_factor/concat.c b/external/flint-2.4.3/fmpz_mod_poly_factor/concat.c new file mode 100644 index 0000000..0dc3780 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly_factor/concat.c @@ -0,0 +1,42 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz_mod_poly.h" + +void +fmpz_mod_poly_factor_concat(fmpz_mod_poly_factor_t res, + const fmpz_mod_poly_factor_t fac) +{ + slong i; + + for (i = 0; i < fac->num; i++) + fmpz_mod_poly_factor_insert(res, fac->poly + i, fac->exp[i]); +} diff --git a/external/flint-2.4.3/fmpz_mod_poly_factor/doc/fmpz_mod_poly_factor.txt b/external/flint-2.4.3/fmpz_mod_poly_factor/doc/fmpz_mod_poly_factor.txt new file mode 100644 index 0000000..ddae2f0 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly_factor/doc/fmpz_mod_poly_factor.txt @@ -0,0 +1,174 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009, 2008 William Hart + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + +******************************************************************************/ + +******************************************************************************* + + Factorisation + +******************************************************************************* + +void fmpz_mod_poly_factor_init(fmpz_mod_poly_factor_t fac) + + Initialises \code{fac} for use. An \code{fmpz_mod_poly_factor_t} + represents a polynomial in factorised form as a product of + polynomials with associated exponents. + +void fmpz_mod_poly_factor_clear(fmpz_mod_poly_factor_t fac) + + Frees all memory associated with \code{fac}. + +void fmpz_mod_poly_factor_realloc(fmpz_mod_poly_factor_t fac, slong alloc) + + Reallocates the factor structure to provide space for + precisely \code{alloc} factors. + +void fmpz_mod_poly_factor_fit_length(fmpz_mod_poly_factor_t fac, slong len) + + Ensures that the factor structure has space for at + least \code{len} factors. This function takes care + of the case of repeated calls by always, at least + doubling the number of factors the structure can hold. + +void fmpz_mod_poly_factor_set(fmpz_mod_poly_factor_t res, + const fmpz_mod_poly_factor_t fac) + + Sets \code{res} to the same factorisation as \code{fac}. + +void fmpz_mod_poly_factor_print(const fmpz_mod_poly_factor_t fac) + + Prints the entries of \code{fac} to standard output. + +void fmpz_mod_poly_factor_insert(fmpz_mod_poly_factor_t fac, + const fmpz_mod_poly_t poly, slong exp) + + Inserts the factor \code{poly} with multiplicity \code{exp} into + the factorisation \code{fac}. + + If \code{fac} already contains \code{poly}, then \code{exp} simply + gets added to the exponent of the existing entry. + +void fmpz_mod_poly_factor_concat(fmpz_mod_poly_factor_t res, + const fmpz_mod_poly_factor_t fac) + + Concatenates two factorisations. + + This is equivalent to calling \code{fmpz_mod_poly_factor_insert()} + repeatedly with the individual factors of \code{fac}. + + Does not support aliasing between \code{res} and \code{fac}. + +void fmpz_mod_poly_factor_pow(fmpz_mod_poly_factor_t fac, slong exp) + + Raises \code{fac} to the power \code{exp}. + +int fmpz_mod_poly_is_irreducible(const fmpz_mod_poly_t f) + + Returns 1 if the polynomial \code{f} is irreducible, otherwise returns 0. + +int fmpz_mod_poly_is_irreducible_ddf(const fmpz_mod_poly_t f) + + Returns 1 if the polynomial \code{f} is irreducible, otherwise returns 0. + Uses fast distinct-degree factorisation. + +int fmpz_mod_poly_is_irreducible_rabin(const fmpz_mod_poly_t f) + + Returns 1 if the polynomial \code{f} is irreducible, otherwise returns 0. + Uses Rabin irreducibility test. + +int _fmpz_mod_poly_is_squarefree(const fmpz * f, slong len, const fmpz_t p) + + Returns 1 if \code{(f, len)} is squarefree, and 0 otherwise. As a + special case, the zero polynomial is not considered squarefree. + There are no restrictions on the length. + +int fmpz_mod_poly_is_squarefree(const fmpz_mod_poly_t f) + + Returns 1 if \code{f} is squarefree, and 0 otherwise. As a special + case, the zero polynomial is not considered squarefree. + +int fmpz_mod_poly_factor_equal_deg_prob(fmpz_mod_poly_t factor, + flint_rand_t state, const fmpz_mod_poly_t pol, slong d) + + Probabilistic equal degree factorisation of \code{pol} into + irreducible factors of degree \code{d}. If it passes, a factor is + placed in \code{factor} and 1 is returned, otherwise 0 is returned and + the value of factor is undetermined. + + Requires that \code{pol} be monic, non-constant and squarefree. + +void fmpz_mod_poly_factor_equal_deg(fmpz_mod_poly_factor_t factors, + const fmpz_mod_poly_t pol, slong d) + + Assuming \code{pol} is a product of irreducible factors all of + degree \code{d}, finds all those factors and places them in factors. + Requires that \code{pol} be monic, non-constant and squarefree. + +void fmpz_mod_poly_factor_distinct_deg(fmpz_mod_poly_factor_t res, + const fmpz_mod_poly_t poly, slong * const *degs) + + Factorises a monic non-constant squarefree polynomial \code{poly} + of degree n into factors $f[d]$ such that for $1 \leq d \leq n$ + $f[d]$ is the product of the monic irreducible factors of \code{poly} + of degree $d$. Factors $f[d]$ are stored in \code{res}, and the degree $d$ + of the irreducible factors is stored in \code{degs} in the same order + as the factors. + + Requires that \code{degs} has enough space for $(n/2)+1 * sizeof(slong)$. + +void fmpz_mod_poly_factor_squarefree(fmpz_mod_poly_factor_t res, + const fmpz_mod_poly_t f) + + Sets \code{res} to a squarefree factorization of \code{f}. + +void fmpz_mod_poly_factor(fmpz_mod_poly_factor_t res, + const fmpz_mod_poly_t f) + + Factorises a non-constant polynomial \code{f} into monic irreducible + factors choosing the best algorithm for given modulo and degree. + Choise is based on heuristic measurments. + +void fmpz_mod_poly_factor_cantor_zassenhaus(fmpz_mod_poly_factor_t res, + const fmpz_mod_poly_t f) + + Factorises a non-constant polynomial \code{f} into monic irreducible + factors using the Cantor-Zassenhaus algorithm. + +void fmpz_mod_poly_factor_kaltofen_shoup(fmpz_mod_poly_factor_t res, + const fmpz_mod_poly_t poly) + + Factorises a non-constant polynomial \code{poly} into monic irreducible + factors using the fast version of Cantor-Zassenhaus algorithm proposed by + Kaltofen and Shoup (1998). More precisely this algorithm uses a + ``baby step/giant step'' strategy for the distinct-degree factorization + step. + +void fmpz_mod_poly_factor_berlekamp(fmpz_mod_poly_factor_t factors, + const fmpz_mod_poly_t f) + + Factorises a non-constant polynomial \code{f} into monic irreducible + factors using the Berlekamp algorithm. diff --git a/external/flint-2.4.3/fmpz_mod_poly_factor/factor.c b/external/flint-2.4.3/fmpz_mod_poly_factor/factor.c new file mode 100644 index 0000000..298f76f --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly_factor/factor.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Lina Kulakova + +******************************************************************************/ + +#include +#include "fmpz_mod_poly.h" + +void +fmpz_mod_poly_factor(fmpz_mod_poly_factor_t res, + const fmpz_mod_poly_t f) +{ + slong n = fmpz_mod_poly_degree(f); + mp_bitcnt_t bits = fmpz_bits(&f->p); + + if (5 * bits + n > 75) + fmpz_mod_poly_factor_kaltofen_shoup(res, f); + else + fmpz_mod_poly_factor_cantor_zassenhaus(res, f); +} diff --git a/external/flint-2.4.3/fmpz_mod_poly_factor/factor_berlekamp.c b/external/flint-2.4.3/fmpz_mod_poly_factor/factor_berlekamp.c new file mode 100644 index 0000000..20e0b6e --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly_factor/factor_berlekamp.c @@ -0,0 +1,303 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + +******************************************************************************/ + +#include +#include "fmpz_mod_poly.h" +#include "fmpz_mat.h" +#include "ulong_extras.h" +#include "profiler.h" +#include "perm.h" + +static void +fmpz_mod_poly_to_fmpz_mat_col(fmpz_mat_t mat, slong col, fmpz_mod_poly_t poly) +{ + slong i; + + for (i = 0; i < poly->length; i++) + fmpz_set(fmpz_mat_entry(mat, i, col), poly->coeffs + i); + + for (; i < mat->r; i++) + fmpz_zero(fmpz_mat_entry(mat, i, col)); + +} + +static void +fmpz_mat_col_to_fmpz_mod_poly_shifted(fmpz_mod_poly_t poly, fmpz_mat_t mat, + slong col, slong *shift) +{ + slong i, j, rows = mat->r; + + fmpz_mod_poly_fit_length(poly, rows); + + for (i = 0, j = 0; j < rows; j++) + { + if (shift[j]) + fmpz_zero(poly->coeffs + j); + else + { + fmpz_set(poly->coeffs + j, fmpz_mat_entry(mat, i, col)); + i++; + } + } + + _fmpz_mod_poly_set_length(poly, rows); + _fmpz_mod_poly_normalise(poly); +} + +static void +__fmpz_mod_poly_factor_berlekamp(fmpz_mod_poly_factor_t factors, + flint_rand_t state, const fmpz_mod_poly_t f) +{ + const slong n = fmpz_mod_poly_degree(f); + + fmpz_mod_poly_factor_t fac1, fac2; + fmpz_mod_poly_t x, x_p; + fmpz_mod_poly_t x_pi, x_pi2; + fmpz_mod_poly_t Q, r; + fmpz_mat_t matrix; + fmpz_t coeff, p, q, mul, pow; + slong i, nullity, col, row; + slong *shift, *perm; + fmpz_mod_poly_t *basis; + + if (f->length <= 2) + { + fmpz_mod_poly_factor_insert(factors, f, 1); + return; + } + + fmpz_init(coeff); + fmpz_init(mul); + + fmpz_init_set(p, &f->p); + + /* q = p - 1 */ + fmpz_init_set(q, p); + fmpz_sub_ui(q, q, 1); + fmpz_mod(q, q, p); + + /* pow = (p-1)/2 */ + fmpz_init(pow); + if (fmpz_cmp_ui(p, 3) > 0) + { + fmpz_set(pow, q); + fmpz_divexact_ui(pow, pow, 2); + } + + /* Step 1, compute x^p mod f in F_p[X]/ */ + fmpz_mod_poly_init(x, p); + fmpz_mod_poly_init(x_p, p); + + fmpz_mod_poly_set_coeff_ui(x, 1, 1); + fmpz_mod_poly_powmod_fmpz_binexp(x_p, x, p, f); + fmpz_mod_poly_clear(x); + + /* Step 2, compute the matrix for the Berlekamp Map */ + fmpz_mat_init(matrix, n, n); + fmpz_mod_poly_init(x_pi, p); + fmpz_mod_poly_init(x_pi2, p); + fmpz_mod_poly_set_coeff_ui(x_pi, 0, 1); + + for (i = 0; i < n; i++) + { + /* Q - I */ + fmpz_mod_poly_set(x_pi2, x_pi); + fmpz_mod_poly_get_coeff_fmpz(coeff, x_pi2, i); + if (!fmpz_is_zero(coeff)) + { + fmpz_sub_ui(coeff, coeff, 1); + fmpz_mod(coeff, coeff, p); + fmpz_mod_poly_set_coeff_fmpz(x_pi2, i, coeff); + } + else + { + fmpz_mod_poly_set_coeff_fmpz(x_pi2, i, q); + } + fmpz_mod_poly_to_fmpz_mat_col(matrix, i, x_pi2); + fmpz_mod_poly_mulmod(x_pi, x_pi, x_p, f); + } + + fmpz_mod_poly_clear(x_p); + fmpz_mod_poly_clear(x_pi); + fmpz_mod_poly_clear(x_pi2); + + /* Row reduce Q - I */ + perm = _perm_init(n); + nullity = n - fmpz_mat_rref_mod(perm, matrix, p); + _perm_clear(perm); + + /* Find a basis for the nullspace */ + basis = + (fmpz_mod_poly_t *) flint_malloc(nullity * sizeof(fmpz_mod_poly_t)); + shift = (slong *) flint_calloc(n, sizeof(slong)); + + col = 1; /* first column is always zero */ + row = 0; + shift[0] = 1; + + for (i = 1; i < nullity; i++) + { + fmpz_mod_poly_init(basis[i], p); + while (!fmpz_is_zero(fmpz_mat_entry(matrix, row, col))) + { + row++; + col++; + } + fmpz_mat_col_to_fmpz_mod_poly_shifted(basis[i], matrix, col, shift); + fmpz_mod_poly_set_coeff_fmpz(basis[i], col, q); + shift[col] = 1; + col++; + } + + flint_free(shift); + fmpz_mat_clear(matrix); + + /* we are done */ + if (nullity == 1) + { + fmpz_mod_poly_factor_insert(factors, f, 1); + } + else + { + /* Generate random linear combinations */ + fmpz_mod_poly_t factor, b, power, g; + fmpz_mod_poly_init(factor, p); + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(power, p); + fmpz_mod_poly_init(g, p); + + while (1) + { + do + { + fmpz_mod_poly_zero(factor); + for (i = 1; i < nullity; i++) + { + fmpz_randm(mul, state, p); + fmpz_mod_poly_scalar_mul_fmpz(b, basis[i], mul); + fmpz_mod_poly_add(factor, factor, b); + } + + fmpz_randm(coeff, state, p); + fmpz_mod_poly_set_coeff_fmpz(factor, 0, coeff); + if (!fmpz_mod_poly_is_zero(factor)) + fmpz_mod_poly_make_monic(factor, factor); + } + while (fmpz_mod_poly_is_zero(factor) || + (factor->length < 2 && fmpz_is_one(factor->coeffs))); + + fmpz_mod_poly_gcd(g, f, factor); + + if (fmpz_mod_poly_length(g) != 1) + break; + + if (fmpz_cmp_ui(p, 3) > 0) + fmpz_mod_poly_powmod_fmpz_binexp(power, factor, pow, f); + else + fmpz_mod_poly_set(power, factor); + + fmpz_add(power->coeffs, power->coeffs, q); + fmpz_mod(power->coeffs, power->coeffs, p); + _fmpz_mod_poly_normalise(power); + fmpz_mod_poly_gcd(g, power, f); + + if (fmpz_mod_poly_length(g) != 1) + break; + } + + fmpz_mod_poly_clear(power); + fmpz_mod_poly_clear(factor); + fmpz_mod_poly_clear(b); + + if (!fmpz_mod_poly_is_zero(g)) + fmpz_mod_poly_make_monic(g, g); + + fmpz_mod_poly_factor_init(fac1); + fmpz_mod_poly_factor_init(fac2); + __fmpz_mod_poly_factor_berlekamp(fac1, state, g); + fmpz_mod_poly_init(Q, p); + fmpz_mod_poly_init(r, p); + fmpz_mod_poly_divrem(Q, r, f, g); + fmpz_mod_poly_clear(r); + + if (!fmpz_mod_poly_is_zero(Q)) + fmpz_mod_poly_make_monic(Q, Q); + + __fmpz_mod_poly_factor_berlekamp(fac2, state, Q); + fmpz_mod_poly_factor_concat(factors, fac1); + fmpz_mod_poly_factor_concat(factors, fac2); + fmpz_mod_poly_factor_clear(fac1); + fmpz_mod_poly_factor_clear(fac2); + fmpz_mod_poly_clear(Q); + fmpz_mod_poly_clear(g); + } + + for (i = 1; i < nullity; i++) + fmpz_mod_poly_clear(basis[i]); + flint_free(basis); + + fmpz_clear(coeff); + fmpz_clear(p); + fmpz_clear(q); + fmpz_clear(mul); + fmpz_clear(pow); +} + +void +fmpz_mod_poly_factor_berlekamp(fmpz_mod_poly_factor_t factors, + const fmpz_mod_poly_t f) +{ + slong i; + flint_rand_t r; + fmpz_mod_poly_t v; + fmpz_mod_poly_factor_t sq_free; + + fmpz_mod_poly_init(v, &f->p); + + fmpz_mod_poly_make_monic(v, f); + + /* compute squarefree factorisation */ + fmpz_mod_poly_factor_init(sq_free); + fmpz_mod_poly_factor_squarefree(sq_free, v); + + /* run Berlekamp algorithm for all squarefree factors */ + flint_randinit(r); + for (i = 0; i < sq_free->num; i++) + { + __fmpz_mod_poly_factor_berlekamp(factors, r, sq_free->poly + i); + } + flint_randclear(r); + + /* compute multiplicities of factors in f */ + for (i = 0; i < factors->num; i++) + factors->exp[i] = fmpz_mod_poly_remove(v, factors->poly + i); + + fmpz_mod_poly_clear(v); + fmpz_mod_poly_factor_clear(sq_free); +} diff --git a/external/flint-2.4.3/fmpz_mod_poly_factor/factor_cantor_zassenhaus.c b/external/flint-2.4.3/fmpz_mod_poly_factor/factor_cantor_zassenhaus.c new file mode 100644 index 0000000..f621137 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly_factor/factor_cantor_zassenhaus.c @@ -0,0 +1,78 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + +******************************************************************************/ + +#include "fmpz_mod_poly.h" + +void +fmpz_mod_poly_factor_cantor_zassenhaus(fmpz_mod_poly_factor_t res, + const fmpz_mod_poly_t f) +{ + fmpz_mod_poly_t h, v, g, x; + slong i, j, num; + + fmpz_mod_poly_init(h, &f->p); + fmpz_mod_poly_init(g, &f->p); + fmpz_mod_poly_init(v, &f->p); + fmpz_mod_poly_init(x, &f->p); + + fmpz_mod_poly_set_coeff_ui(h, 1, 1); + fmpz_mod_poly_set_coeff_ui(x, 1, 1); + + fmpz_mod_poly_make_monic(v, f); + + i = 0; + do + { + i++; + fmpz_mod_poly_powmod_fmpz_binexp(h, h, &f->p, v); + + fmpz_mod_poly_sub(h, h, x); + fmpz_mod_poly_gcd(g, h, v); + fmpz_mod_poly_add(h, h, x); + + if (g->length != 1) + { + fmpz_mod_poly_make_monic(g, g); + num = res->num; + + fmpz_mod_poly_factor_equal_deg(res, g, i); + for (j = num; j < res->num; j++) + res->exp[j] = fmpz_mod_poly_remove(v, res->poly + j); + } + } + while (v->length >= 2 * i + 3); + + if (v->length > 1) + fmpz_mod_poly_factor_insert(res, v, 1); + + fmpz_mod_poly_clear(g); + fmpz_mod_poly_clear(h); + fmpz_mod_poly_clear(v); + fmpz_mod_poly_clear(x); +} diff --git a/external/flint-2.4.3/fmpz_mod_poly_factor/factor_distinct_deg.c b/external/flint-2.4.3/fmpz_mod_poly_factor/factor_distinct_deg.c new file mode 100644 index 0000000..8a98f45 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly_factor/factor_distinct_deg.c @@ -0,0 +1,219 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Martin Lee + +******************************************************************************/ + +#undef ulong +#define ulong ulongxx/* interferes with system includes */ + +#include + +#undef ulong + +#include + +#define ulong mp_limb_t + +#include "fmpz_mod_poly.h" + +void +fmpz_mod_poly_factor_distinct_deg(fmpz_mod_poly_factor_t res, + const fmpz_mod_poly_t poly, slong * const *degs) +{ + fmpz_mod_poly_t f, g, v, vinv, reducedH0, tmp; + fmpz_mod_poly_t *h, *H, *I; + slong i, j, l, m, n, index, d; + fmpz_t p; + fmpz_mat_t HH, HHH; + double beta; + + fmpz_init(p); + fmpz_set(p, &poly->p); + fmpz_mod_poly_init(v, p); + + fmpz_mod_poly_make_monic(v, poly); + + n = fmpz_mod_poly_degree(poly); + if (n == 1) + { + fmpz_mod_poly_factor_insert(res, v, 1); + (*degs)[0]= 1; + fmpz_mod_poly_clear(v); + return; + } + beta = 0.5 * (1. - (log(2) / log(n))); + l = ceil(pow(n, beta)); + m = ceil(0.5 * n / l); + + /* initialization */ + fmpz_mod_poly_init(f, p); + fmpz_mod_poly_init(g, p); + fmpz_mod_poly_init(vinv, p); + fmpz_mod_poly_init(reducedH0, p); + fmpz_mod_poly_init(tmp, p); + + if (!(h = flint_malloc((2 * m + l + 1) * sizeof(fmpz_mod_poly_struct)))) + { + flint_printf("Exception (fmpz_mod_poly_factor_distinct_deg):\n"); + flint_printf("Not enough memory.\n"); + abort(); + } + H = h + (l + 1); + I = H + m; + for (i = 0; i < l + 1; i++) + fmpz_mod_poly_init(h[i], p); + for (i = 0; i < m; i++) + { + fmpz_mod_poly_init(H[i], p); + fmpz_mod_poly_init(I[i], p); + } + + fmpz_mod_poly_reverse(vinv, v, v->length); + fmpz_mod_poly_inv_series_newton(vinv, vinv, v->length); + + /* compute baby steps: h[i]=x^{p^i}mod v */ + fmpz_mod_poly_set_coeff_ui(h[0], 1, 1); + fmpz_mod_poly_powmod_x_fmpz_preinv(h[1], p, v, vinv); + if (fmpz_sizeinbase(p, 2) > ((n_sqrt (v->length - 1) + 1) * 3) / 4) + { + fmpz_mat_init(HH, n_sqrt (v->length - 1) + 1, v->length - 1); + fmpz_mod_poly_precompute_matrix(HH, h[1], v, vinv); + for (i = 2; i < l + 1; i++) + fmpz_mod_poly_compose_mod_brent_kung_precomp_preinv(h[i], h[i - 1], + HH, v, vinv); + fmpz_mat_clear(HH); + } + else + { + for (i = 2; i < l + 1; i++) + fmpz_mod_poly_powmod_fmpz_binexp_preinv(h[i], h[i - 1], p, + v, vinv); + } + + /* compute coarse distinct-degree factorisation */ + index= 0; + fmpz_mod_poly_set(H[0], h[l]); + fmpz_mod_poly_set(reducedH0, H[0]); + fmpz_mat_init(HH, n_sqrt (v->length - 1) + 1, v->length - 1); + fmpz_mod_poly_precompute_matrix(HH, reducedH0, v, vinv); + d = 1; + for (j = 0; j < m; j++) + { + /* compute giant steps: H[i]=x^{p^(li)}mod v */ + if (j > 0) + { + if (I[j - 1]->length > 1) + { + _fmpz_mod_poly_reduce_matrix_mod_poly(HHH, HH, v); + fmpz_mat_clear(HH); + fmpz_mat_init_set(HH, HHH); + fmpz_mat_clear(HHH); + fmpz_mod_poly_rem(reducedH0, reducedH0, v); + fmpz_mod_poly_rem(tmp, H[j - 1], v); + fmpz_mod_poly_compose_mod_brent_kung_precomp_preinv(H[j], tmp, + HH, v, vinv); + } + else + fmpz_mod_poly_compose_mod_brent_kung_precomp_preinv(H[j], + H[j - 1], HH, v, vinv); + } + /* compute interval polynomials */ + fmpz_mod_poly_set_coeff_ui(I[j], 0, 1); + for (i = l - 1; (i >= 0) && (2 * d <= v->length - 1); i--, d++) + { + fmpz_mod_poly_rem(tmp, h[i], v); + fmpz_mod_poly_sub(tmp, H[j], tmp); + fmpz_mod_poly_mulmod_preinv(I[j], tmp, I[j], v, vinv); + } + + /* compute F_j=f^{[j*l+1]} * ... * f^{[j*l+l]} */ + /* F_j is stored on the place of I_j */ + fmpz_mod_poly_gcd(I[j], v, I[j]); + if (I[j]->length > 1) + { + fmpz_mod_poly_remove(v, I[j]); + fmpz_mod_poly_reverse(vinv, v, v->length); + fmpz_mod_poly_inv_series_newton(vinv, vinv, v->length); + } + if (v->length-1 < 2 * d) + { + break; + } + } + if (v->length > 1) + { + fmpz_mod_poly_factor_insert(res, v, 1); + (*degs)[index++] = v->length - 1; + } + + /* compute fine distinct-degree factorisation */ + for (j = 0; j < m; j++) + { + if (I[j]->length - 1 > (j + 1)*l || j == 0) + { + fmpz_mod_poly_set(g, I[j]); + for (i = l - 1; i >= 0 && (g->length > 1); i--) + { + /* compute f^{[l*(j+1)-i]} */ + fmpz_mod_poly_sub(tmp, H[j], h[i]); + fmpz_mod_poly_gcd(f, g, tmp); + if (f->length > 1) + { + /* insert f^{[l*(j+1)-i]} into res */ + fmpz_mod_poly_make_monic(f, f); + fmpz_mod_poly_factor_insert(res, f, 1); + (*degs)[index++] = l * (j + 1) - i; + + fmpz_mod_poly_remove(g, f); + } + } + } + else if (I[j]->length > 1) + { + fmpz_mod_poly_make_monic(I[j], I[j]); + fmpz_mod_poly_factor_insert(res, I[j], 1); + (*degs)[index++] = I[j]->length - 1; + } + } + + /* cleanup */ + fmpz_clear(p); + fmpz_mod_poly_clear(f); + fmpz_mod_poly_clear(g); + fmpz_mod_poly_clear(reducedH0); + fmpz_mod_poly_clear(v); + fmpz_mod_poly_clear(vinv); + fmpz_mod_poly_clear(tmp); + + fmpz_mat_clear(HH); + + for (i = 0; i < l + 1; i++) + fmpz_mod_poly_clear(h[i]); + for (i = 0; i < m; i++) + { + fmpz_mod_poly_clear(H[i]); + fmpz_mod_poly_clear(I[i]); + } + flint_free(h); +} diff --git a/external/flint-2.4.3/fmpz_mod_poly_factor/factor_equal_deg.c b/external/flint-2.4.3/fmpz_mod_poly_factor/factor_equal_deg.c new file mode 100644 index 0000000..bcfa7ad --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly_factor/factor_equal_deg.c @@ -0,0 +1,66 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + +******************************************************************************/ + +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +void +fmpz_mod_poly_factor_equal_deg(fmpz_mod_poly_factor_t factors, + const fmpz_mod_poly_t pol, slong d) +{ + if (pol->length == d + 1) + { + fmpz_mod_poly_factor_insert(factors, pol, 1); + } + else + { + fmpz_mod_poly_t f, g, r; + flint_rand_t state; + + fmpz_mod_poly_init(f, &pol->p); + + flint_randinit(state); + + while (!fmpz_mod_poly_factor_equal_deg_prob(f, state, pol, d)) + { + }; + + flint_randclear(state); + + fmpz_mod_poly_init(g, &pol->p); + fmpz_mod_poly_init(r, &pol->p); + fmpz_mod_poly_divrem(g, r, pol, f); + fmpz_mod_poly_clear(r); + + fmpz_mod_poly_factor_equal_deg(factors, f, d); + fmpz_mod_poly_clear(f); + fmpz_mod_poly_factor_equal_deg(factors, g, d); + fmpz_mod_poly_clear(g); + } +} diff --git a/external/flint-2.4.3/fmpz_mod_poly_factor/factor_equal_deg_prob.c b/external/flint-2.4.3/fmpz_mod_poly_factor/factor_equal_deg_prob.c new file mode 100644 index 0000000..d3696d4 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly_factor/factor_equal_deg_prob.c @@ -0,0 +1,117 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + +******************************************************************************/ + +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +fmpz_mod_poly_factor_equal_deg_prob(fmpz_mod_poly_t factor, + flint_rand_t state, + const fmpz_mod_poly_t pol, slong d) +{ + fmpz_mod_poly_t a, b, c, polinv; + fmpz_t exp, t, p; + int res = 1; + slong i; + + if (pol->length <= 1) + { + flint_printf("Exception (fmpz_mod_poly_factor_equal_deg_prob): \n"); + flint_printf("Input polynomial is linear.\n"); + abort(); + } + + fmpz_init_set(p, &pol->p); + + fmpz_mod_poly_init(a, p); + + do + { + fmpz_mod_poly_randtest(a, state, pol->length - 1); + } while (a->length <= 1); + + fmpz_mod_poly_gcd(factor, a, pol); + + if (factor->length != 1) + { + fmpz_mod_poly_clear(a); + return 1; + } + + fmpz_mod_poly_init(b, p); + fmpz_mod_poly_init(polinv, p); + + fmpz_mod_poly_reverse(polinv, pol, pol->length); + fmpz_mod_poly_inv_series_newton(polinv, polinv, polinv->length); + + fmpz_init(exp); + if (fmpz_cmp_ui(p, 2) > 0) + { + /* compute a^{(p^d-1)/2} rem pol */ + fmpz_pow_ui(exp, p, d); + fmpz_sub_ui(exp, exp, 1); + fmpz_fdiv_q_2exp(exp, exp, 1); + + fmpz_mod_poly_powmod_fmpz_binexp_preinv(b, a, exp, pol, polinv); + } + else + { + /* compute b = (a^{2^{d-1}}+a^{2^{d-2}}+...+a^4+a^2+a) rem pol */ + fmpz_mod_poly_rem(b, a, pol); + fmpz_mod_poly_init(c, p); + fmpz_mod_poly_set(c, b); + for (i = 1; i < d; i++) + { + /* c = a^{2^i} = (a^{2^{i-1}})^2 */ + fmpz_mod_poly_powmod_ui_binexp_preinv(c, c, 2, pol, polinv); + fmpz_mod_poly_add(b, b, c); + } + fmpz_mod_poly_rem(b, b, pol); + fmpz_mod_poly_clear(c); + } + fmpz_clear(exp); + + fmpz_init(t); + fmpz_sub_ui(t, &(b->coeffs[0]), 1); + fmpz_mod(t, t, p); + fmpz_mod_poly_set_coeff_fmpz(b, 0, t); + fmpz_clear(t); + + fmpz_mod_poly_gcd(factor, b, pol); + + if ((factor->length <= 1) || (factor->length == pol->length)) + res = 0; + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(b); + fmpz_mod_poly_clear(polinv); + fmpz_clear(p); + + return res; +} diff --git a/external/flint-2.4.3/fmpz_mod_poly_factor/factor_kaltofen_shoup.c b/external/flint-2.4.3/fmpz_mod_poly_factor/factor_kaltofen_shoup.c new file mode 100644 index 0000000..f9d2454 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly_factor/factor_kaltofen_shoup.c @@ -0,0 +1,83 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Lina Kulakova + +******************************************************************************/ + +#include +#include "fmpz_mod_poly.h" + +void +fmpz_mod_poly_factor_kaltofen_shoup(fmpz_mod_poly_factor_t res, + const fmpz_mod_poly_t poly) +{ + fmpz_mod_poly_t v; + fmpz_mod_poly_factor_t sq_free, dist_deg; + slong i, j, k, l, res_num, dist_deg_num; + slong *degs; + + fmpz_mod_poly_init(v, &poly->p); + + fmpz_mod_poly_make_monic(v, poly); + + if (poly->length <= 2) + { + fmpz_mod_poly_factor_insert (res, v, 1); + fmpz_mod_poly_clear (v); + return; + } + + if (!(degs = flint_malloc(fmpz_mod_poly_degree(poly) * sizeof(slong)))) + { + flint_printf("Exception (fmpz_mod_poly_factor_kaltofen_shoup): \n"); + flint_printf("Not enough memory.\n"); + abort(); + } + + /* compute squarefree factorisation */ + fmpz_mod_poly_factor_init(sq_free); + fmpz_mod_poly_factor_squarefree(sq_free, v); + + /* compute distinct-degree factorisation */ + fmpz_mod_poly_factor_init(dist_deg); + for (i = 0; i < sq_free->num; i++) + { + dist_deg_num = dist_deg->num; + + fmpz_mod_poly_factor_distinct_deg(dist_deg, sq_free->poly + i, °s); + + /* compute equal-degree factorisation */ + for (j = dist_deg_num, l = 0; j < dist_deg->num; j++, l++) + { + res_num = res->num; + + fmpz_mod_poly_factor_equal_deg(res, dist_deg->poly + j, degs[l]); + for (k = res_num; k < res->num; k++) + res->exp[k] = fmpz_mod_poly_remove(v, res->poly + k); + } + } + + flint_free(degs); + fmpz_mod_poly_clear(v); + fmpz_mod_poly_factor_clear(dist_deg); + fmpz_mod_poly_factor_clear(sq_free); +} diff --git a/external/flint-2.4.3/fmpz_mod_poly_factor/factor_squarefree.c b/external/flint-2.4.3/fmpz_mod_poly_factor/factor_squarefree.c new file mode 100644 index 0000000..afea10c --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly_factor/factor_squarefree.c @@ -0,0 +1,163 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + +******************************************************************************/ + +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +void +fmpz_mod_poly_factor_squarefree(fmpz_mod_poly_factor_t res, + const fmpz_mod_poly_t f) +{ + fmpz_mod_poly_t f_d, g, g_1, r; + fmpz_t p, x; + slong deg, i, p_ui; + + if (f->length <= 1) + { + res->num = 0; + return; + } + + if (f->length == 2) + { + fmpz_mod_poly_factor_insert(res, f, 1); + return; + } + + fmpz_init(p); + fmpz_set(p, &f->p); + p_ui = fmpz_get_ui(p); + deg = fmpz_mod_poly_degree(f); + + /* Step 1, look at f', if it is zero then we are done since f = h(x)^p + for some particular h(x), clearly f(x) = sum a_k x^kp, k <= deg(f) */ + + fmpz_init(x); + fmpz_mod_poly_init(g_1, p); + fmpz_mod_poly_init(f_d, p); + fmpz_mod_poly_init(g, p); + fmpz_mod_poly_derivative(f_d, f); + + /* Case 1 */ + if (fmpz_mod_poly_is_zero(f_d)) + { + fmpz_mod_poly_factor_t new_res; + fmpz_mod_poly_t h; + + fmpz_mod_poly_init(h, p); + + for (i = 0; i <= deg / p_ui; i++) /* this will be an integer since f'=0 */ + { + fmpz_mod_poly_get_coeff_fmpz(x, f, i * p_ui); + fmpz_mod_poly_set_coeff_fmpz(h, i, x); + } + + /* Now run squarefree on h, and return it to the pth power */ + fmpz_mod_poly_factor_init(new_res); + + fmpz_mod_poly_factor_squarefree(new_res, h); + fmpz_mod_poly_factor_pow(new_res, p_ui); + + fmpz_mod_poly_factor_concat(res, new_res); + fmpz_mod_poly_clear(h); + fmpz_mod_poly_factor_clear(new_res); + } + else + { + fmpz_mod_poly_t h, z; + + fmpz_mod_poly_init(r, p); + + fmpz_mod_poly_gcd(g, f, f_d); + fmpz_mod_poly_divrem(g_1, r, f, g); + + i = 1; + + fmpz_mod_poly_init(h, p); + fmpz_mod_poly_init(z, p); + + /* Case 2 */ + while (g_1->length > 1) + { + fmpz_mod_poly_gcd(h, g_1, g); + fmpz_mod_poly_divrem(z, r, g_1, h); + + /* out <- out.z */ + if (z->length > 1) + { + fmpz_mod_poly_factor_insert(res, z, 1); + fmpz_mod_poly_make_monic(res->poly + (res->num - 1), + res->poly + (res->num - 1)); + if (res->num) + res->exp[res->num - 1] *= i; + } + + i++; + fmpz_mod_poly_set(g_1, h); + fmpz_mod_poly_divrem(g, r, g, h); + } + + fmpz_mod_poly_clear(h); + fmpz_mod_poly_clear(z); + fmpz_mod_poly_clear(r); + + fmpz_mod_poly_make_monic(g, g); + + if (g->length > 1) + { + /* so now we multiply res with squarefree(g^1/p) ^ p */ + fmpz_mod_poly_t g_p; /* g^(1/p) */ + fmpz_mod_poly_factor_t new_res_2; + + fmpz_mod_poly_init(g_p, p); + + for (i = 0; i <= fmpz_mod_poly_degree(g) / p_ui; i++) + { + fmpz_mod_poly_get_coeff_fmpz(x, g, i * p_ui); + fmpz_mod_poly_set_coeff_fmpz(g_p, i, x); + } + + fmpz_mod_poly_factor_init(new_res_2); + + /* squarefree(g^(1/p)) */ + fmpz_mod_poly_factor_squarefree(new_res_2, g_p); + fmpz_mod_poly_factor_pow(new_res_2, p_ui); + + fmpz_mod_poly_factor_concat(res, new_res_2); + fmpz_mod_poly_clear(g_p); + fmpz_mod_poly_factor_clear(new_res_2); + } + } + + fmpz_clear(p); + fmpz_clear(x); + fmpz_mod_poly_clear(g_1); + fmpz_mod_poly_clear(f_d); + fmpz_mod_poly_clear(g); +} diff --git a/external/flint-2.4.3/fmpz_mod_poly_factor/fit_length.c b/external/flint-2.4.3/fmpz_mod_poly_factor/fit_length.c new file mode 100644 index 0000000..399dd34 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly_factor/fit_length.c @@ -0,0 +1,41 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2008, 2009 William Hart + +******************************************************************************/ + +#include +#include "fmpz_mod_poly.h" + +void +fmpz_mod_poly_factor_fit_length(fmpz_mod_poly_factor_t fac, slong len) +{ + if (len > fac->alloc) + { + /* At least double number of allocated coeffs */ + if (len < 2 * fac->alloc) + len = 2 * fac->alloc; + fmpz_mod_poly_factor_realloc(fac, len); + } +} diff --git a/external/flint-2.4.3/fmpz_mod_poly_factor/init.c b/external/flint-2.4.3/fmpz_mod_poly_factor/init.c new file mode 100644 index 0000000..6610328 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly_factor/init.c @@ -0,0 +1,50 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz_mod_poly.h" + +void +fmpz_mod_poly_factor_init(fmpz_mod_poly_factor_t fac) +{ + slong i; + fmpz_t p; + + fac->alloc = 5; + fac->num = 0; + fac->poly = flint_malloc(sizeof(fmpz_mod_poly_struct) * 5); + fac->exp = flint_malloc(sizeof(slong) * 5); + + fmpz_init_set_ui(p, 5); + for (i = 0; i < 5; i++) + fmpz_mod_poly_init(fac->poly + i, p); + fmpz_clear(p); +} diff --git a/external/flint-2.4.3/fmpz_mod_poly_factor/insert.c b/external/flint-2.4.3/fmpz_mod_poly_factor/insert.c new file mode 100644 index 0000000..23b8b0c --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly_factor/insert.c @@ -0,0 +1,72 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + +******************************************************************************/ + +#include +#include "fmpz_mod_poly.h" + +void +fmpz_mod_poly_factor_insert(fmpz_mod_poly_factor_t fac, + const fmpz_mod_poly_t poly, slong exp) +{ + slong i; + fmpz_t p; + + if (poly->length <= 1) + return; + + for (i = 0; i < fac->num; i++) + { + if (fmpz_mod_poly_equal(poly, fac->poly + i)) + { + fac->exp[i] += exp; + return; + } + } + + if (fac->alloc == fac->num) + { + slong new_size = 2 * fac->alloc; + + fac->poly = + flint_realloc(fac->poly, sizeof(fmpz_mod_poly_struct) * new_size); + fac->exp = flint_realloc(fac->exp, sizeof(slong) * new_size); + + fmpz_init_set_ui(p, 5); + for (i = fac->alloc; i < new_size; i++) + fmpz_mod_poly_init(fac->poly + i, p); + fmpz_clear(p); + + fac->alloc = new_size; + } + + fmpz_mod_poly_set(fac->poly + fac->num, poly); + fmpz_set(&(fac->poly + fac->num)->p, &poly->p); + fac->exp[fac->num] = exp; + fac->num++; +} diff --git a/external/flint-2.4.3/fmpz_mod_poly_factor/is_irreducible.c b/external/flint-2.4.3/fmpz_mod_poly_factor/is_irreducible.c new file mode 100644 index 0000000..de20b14 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly_factor/is_irreducible.c @@ -0,0 +1,43 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + +******************************************************************************/ + +#include "fmpz.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +fmpz_mod_poly_is_irreducible(const fmpz_mod_poly_t f) +{ + if (fmpz_mod_poly_length(f) > 2) + { + return fmpz_mod_poly_is_irreducible_ddf(f); + } + + return 1; +} diff --git a/external/flint-2.4.3/fmpz_mod_poly_factor/is_irreducible_ddf.c b/external/flint-2.4.3/fmpz_mod_poly_factor/is_irreducible_ddf.c new file mode 100644 index 0000000..bf3f7c6 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly_factor/is_irreducible_ddf.c @@ -0,0 +1,146 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Martin Lee + +******************************************************************************/ + +#undef ulong +#define ulong ulongxx/* interferes with system includes */ + +#include + +#undef ulong + +#include + +#define ulong mp_limb_t + +#include "fmpz_mod_poly.h" + +int fmpz_mod_poly_is_irreducible_ddf(const fmpz_mod_poly_t poly) +{ + fmpz_mod_poly_t f, v, vinv, reducedH0, tmp; + fmpz_mod_poly_t *h, *H, *I; + slong i, j, l, m, n, d; + fmpz_t p; + double beta; + int result = 1; + + n = fmpz_mod_poly_degree(poly); + + if (n < 2) + return 1; + + if (!fmpz_mod_poly_is_squarefree(poly)) + return 0; + + beta = 0.5 * (1. - (log(2) / log(n))); + l = ceil(pow(n, beta)); + m = ceil(0.5 * n / l); + + /* initialization */ + fmpz_init(p); + fmpz_set(p, &poly->p); + + fmpz_mod_poly_init(f, p); + fmpz_mod_poly_init(v, p); + fmpz_mod_poly_init(vinv, p); + fmpz_mod_poly_init(reducedH0, p); + fmpz_mod_poly_init(tmp, p); + + if (!(h = flint_malloc((2 * m + l + 1) * sizeof(fmpz_mod_poly_struct)))) + { + flint_printf("Exception (fmpz_mod_poly_is_irreducible_ddf): \n"); + flint_printf("Not enough memory.\n"); + abort(); + } + H = h + (l + 1); + I = H + m; + for (i = 0; i < l + 1; i++) + fmpz_mod_poly_init(h[i], p); + for (i = 0; i < m; i++) + { + fmpz_mod_poly_init(H[i], p); + fmpz_mod_poly_init(I[i], p); + } + + fmpz_mod_poly_make_monic(v, poly); + + fmpz_mod_poly_reverse (vinv, v, v->length); + fmpz_mod_poly_inv_series_newton (vinv, vinv, v->length); + /* compute baby steps: h[i]=x^{p^i}mod v */ + fmpz_mod_poly_set_coeff_ui(h[0], 1, 1); + for (i = 1; i < l + 1; i++) + fmpz_mod_poly_powmod_fmpz_binexp_preinv(h[i], h[i - 1], p, v, vinv); + + /* compute coarse distinct-degree factorisation */ + fmpz_mod_poly_set(H[0], h[l]); + fmpz_mod_poly_set(reducedH0, H[0]); + d = 1; + for (j = 0; j < m; j++) + { + /* compute giant steps: H[i]=x^{p^(li)}mod v */ + if (j > 0) + { + fmpz_mod_poly_rem (reducedH0, reducedH0, v); + fmpz_mod_poly_rem (tmp, H[j-1], v); + fmpz_mod_poly_compose_mod_brent_kung_preinv(H[j], tmp, reducedH0, + v, vinv); + } + /* compute interval polynomials */ + fmpz_mod_poly_set_coeff_ui(I[j], 0, 1); + for (i = l - 1; (i >= 0) && (2*d <= v->length - 1); i--, d++) + { + fmpz_mod_poly_rem(tmp, h[i], v); + fmpz_mod_poly_sub(tmp, H[j], tmp); + fmpz_mod_poly_mulmod_preinv (I[j], tmp, I[j], v, vinv); + } + + /* compute F_j=f^{[j*l+1]} * ... * f^{[j*l+l]} */ + /* F_j is stored on the place of I_j */ + fmpz_mod_poly_gcd(I[j], v, I[j]); + if (I[j]->length > 1) + { + result = 0; + break; + } + } + + fmpz_clear(p); + fmpz_mod_poly_clear(f); + fmpz_mod_poly_clear(reducedH0); + fmpz_mod_poly_clear(v); + fmpz_mod_poly_clear(vinv); + fmpz_mod_poly_clear(tmp); + + for (i = 0; i < l + 1; i++) + fmpz_mod_poly_clear(h[i]); + for (i = 0; i < m; i++) + { + fmpz_mod_poly_clear(H[i]); + fmpz_mod_poly_clear(I[i]); + } + flint_free(h); + + return result; +} diff --git a/external/flint-2.4.3/fmpz_mod_poly_factor/is_irreducible_rabin.c b/external/flint-2.4.3/fmpz_mod_poly_factor/is_irreducible_rabin.c new file mode 100644 index 0000000..8c9ba48 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly_factor/is_irreducible_rabin.c @@ -0,0 +1,112 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + +******************************************************************************/ + +#include "fmpz.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +void +fmpz_mod_poly_powpowmod(fmpz_mod_poly_t res, const fmpz_mod_poly_t pol, + const fmpz_t exp, ulong exp2, const fmpz_mod_poly_t f) +{ + fmpz_mod_poly_t pow; + ulong i; + + fmpz_mod_poly_init(pow, &f->p); + fmpz_mod_poly_powmod_fmpz_binexp(pow, pol, exp, f); + fmpz_mod_poly_set(res, pow); + + if (!fmpz_mod_poly_equal(pow, pol)) + for (i = 1; i < exp2; i++) + fmpz_mod_poly_powmod_fmpz_binexp(res, res, exp, f); + + fmpz_mod_poly_clear(pow); +} + +int +fmpz_mod_poly_is_irreducible_rabin(const fmpz_mod_poly_t f) +{ + if (fmpz_mod_poly_length(f) > 2) + { + const slong n = fmpz_mod_poly_degree(f); + fmpz_mod_poly_t a, x, x_p; + + fmpz_mod_poly_init(a, &f->p); + fmpz_mod_poly_init(x, &f->p); + fmpz_mod_poly_init(x_p, &f->p); + fmpz_mod_poly_set_coeff_ui(x, 1, 1); + + /* Compute x^q mod f */ + fmpz_mod_poly_powpowmod(x_p, x, &f->p, n, f); + if (!fmpz_mod_poly_is_zero(x_p)) + fmpz_mod_poly_make_monic(x_p, x_p); + + /* Now do the irreducibility test */ + if (!fmpz_mod_poly_equal(x_p, x)) + { + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(x); + fmpz_mod_poly_clear(x_p); + return 0; + } + else + { + n_factor_t factors; + slong i; + + n_factor_init(&factors); + n_factor(&factors, n, 1); + + for (i = 0; i < factors.num; i++) + { + fmpz_mod_poly_powpowmod(a, x, &f->p, n / factors.p[i], f); + fmpz_mod_poly_sub(a, a, x); + + if (!fmpz_mod_poly_is_zero(a)) + fmpz_mod_poly_make_monic(a, a); + + fmpz_mod_poly_gcd(a, a, f); + + if (a->length != 1) + { + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(x); + fmpz_mod_poly_clear(x_p); + return 0; + } + } + } + + fmpz_mod_poly_clear(a); + fmpz_mod_poly_clear(x); + fmpz_mod_poly_clear(x_p); + } + + return 1; +} diff --git a/external/flint-2.4.3/fmpz_mod_poly_factor/is_squarefree.c b/external/flint-2.4.3/fmpz_mod_poly_factor/is_squarefree.c new file mode 100644 index 0000000..ccb5d14 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly_factor/is_squarefree.c @@ -0,0 +1,68 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + +******************************************************************************/ + +#include "fmpz_mod_poly.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" + +#include + +int +_fmpz_mod_poly_is_squarefree(const fmpz * f, slong len, const fmpz_t p) +{ + fmpz * fd, * g; + fmpz_t invd; + slong dlen; + int res; + + if (len <= 2) + return len != 0; + + fd = _fmpz_vec_init(2 * (len - 1)); + g = fd + len - 1; + + _fmpz_mod_poly_derivative(fd, f, len, p); + dlen = len - 1; + FMPZ_VEC_NORM(fd, dlen); + + if (dlen) + { + fmpz_init(invd); + fmpz_invmod(invd, fd + dlen - 1, p); + res = (_fmpz_mod_poly_gcd(g, f, len, fd, dlen, invd, p) == 1); + fmpz_clear(invd); + } + else + res = 0; /* gcd(f, 0) = f, and len(f) > 2 */ + + _fmpz_vec_clear(fd, 2 * (len - 1)); + return res; +} + +int fmpz_mod_poly_is_squarefree(const fmpz_mod_poly_t f) +{ + return _fmpz_mod_poly_is_squarefree(f->coeffs, f->length, &f->p); +} diff --git a/external/flint-2.4.3/fmpz_mod_poly_factor/pow.c b/external/flint-2.4.3/fmpz_mod_poly_factor/pow.c new file mode 100644 index 0000000..eb40f70 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly_factor/pow.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + +******************************************************************************/ + +#include +#include "fmpz_mod_poly.h" + +void +fmpz_mod_poly_factor_pow(fmpz_mod_poly_factor_t fac, slong exp) +{ + slong i; + + for (i = 0; i < fac->num; i++) + fac->exp[i] *= exp; +} diff --git a/external/flint-2.4.3/fmpz_mod_poly_factor/print.c b/external/flint-2.4.3/fmpz_mod_poly_factor/print.c new file mode 100644 index 0000000..3b1f8d8 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly_factor/print.c @@ -0,0 +1,45 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz_mod_poly.h" + +void +fmpz_mod_poly_factor_print(const fmpz_mod_poly_factor_t fac) +{ + slong i; + + for (i = 0; i < fac->num; i++) + { + fmpz_mod_poly_print(fac->poly + i); + flint_printf(" ^ %wd\n", fac->exp[i]); + } +} diff --git a/external/flint-2.4.3/fmpz_mod_poly_factor/profile/p-factor.c b/external/flint-2.4.3/fmpz_mod_poly_factor/profile/p-factor.c new file mode 100644 index 0000000..abe4c3b --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly_factor/profile/p-factor.c @@ -0,0 +1,377 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Lina Kulakova + +******************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include "flint.h" +#include "fmpz_mod_poly.h" + +#define NP 20 /* number of moduli */ +#define ND 8 /* number of degrees */ + +/* + Benchmarking code for factorisation in fmpz_mod_poly. + + Test how the relation between n (degree of polynomial) and p + affects working time for Cantor-Zassenhaus, Berlekamp and + Kaltofen-Shoup algorithms. p and n are chosen independently. +*/ + +int main(void) +{ + FLINT_TEST_INIT(state); + fmpz_mod_poly_t f, g; + fmpz_mod_poly_factor_t res; + fmpz_t p; + mpz_t pz, curr; + int i, j, k, n, num; + double t, T1, T2, T3; + + const slong degs[] = {8, 16, 32, 64, 128, 256, 512, 1024}; + const int iter_count[] = {10000, 5000, 1000, 500, 300, 100, 50, 20}; + + + + mpz_init(pz); + mpz_init(curr); + fmpz_init(p); + + flint_printf("Random polynomials\n"); + flint_mpz_set_ui(pz, 2); + flint_mpz_set_ui(curr, 10); + for (i = 0; i < NP; i++) + { + fmpz_set_mpz(p, pz); + flint_printf("========== p: "); fmpz_print(p); flint_printf(" ==========\n"); + fflush(stdout); + + for (j = 0; j < ND; j++) + { + n = degs[j]; + flint_printf(">>>>>n: %d\n", n); + fflush(stdout); + + T1 = 0; + T2 = 0; + T3 = 0; + for (k = 0; k < iter_count[j]; k++) + { + fmpz_mod_poly_init(f, p); + fmpz_mod_poly_randtest_not_zero(f, state, n); + + t = clock(); + fmpz_mod_poly_factor_init(res); + fmpz_mod_poly_factor_cantor_zassenhaus(res, f); + fmpz_mod_poly_factor_clear(res); + t = (clock() - t) / CLOCKS_PER_SEC; + T1 += t; + + t = clock(); + fmpz_mod_poly_factor_init(res); + fmpz_mod_poly_factor_berlekamp(res, f); + fmpz_mod_poly_factor_clear(res); + t = (clock() - t) / CLOCKS_PER_SEC; + T2 += t; + + t = clock(); + fmpz_mod_poly_factor_init(res); + fmpz_mod_poly_factor_kaltofen_shoup(res, f); + fmpz_mod_poly_factor_clear(res); + t = (clock() - t) / CLOCKS_PER_SEC; + T3 += t; + + fmpz_mod_poly_clear(f); + } + + flint_printf("CZ: %.2lf B: %.2lf KS: %.2lf\n", T1, T2, T3); + fflush(stdout); + + if (T1 > T3 + 1) + break; + } + + mpz_nextprime(pz, curr); + flint_mpz_mul_ui(curr, curr, 10); + } + + /* This code checks whether fmpz_mod_poly_factor + made a correct choice between CZ and KS */ + + flint_printf("Check choice correctness\n"); + flint_mpz_set_ui(pz, 2); + flint_mpz_set_ui(curr, 10); + for (i = 0; i < NP; i++) + { + fmpz_set_mpz(p, pz); + flint_printf("========== p: "); fmpz_print(p); flint_printf(" ==========\n"); + fflush(stdout); + + for (j = 0; j < ND; j++) + { + n = degs[j]; + flint_printf(">>>>>n: %d\n", n); + fflush(stdout); + + T1 = 0; + T2 = 0; + T3 = 0; + for (k = 0; k < iter_count[j]; k++) + { + fmpz_mod_poly_init(f, p); + fmpz_mod_poly_randtest_not_zero(f, state, n); + + t = clock(); + fmpz_mod_poly_factor_init(res); + fmpz_mod_poly_factor_cantor_zassenhaus(res, f); + fmpz_mod_poly_factor_clear(res); + t = (clock() - t) / CLOCKS_PER_SEC; + T1 += t; + + t = clock(); + fmpz_mod_poly_factor_init(res); + fmpz_mod_poly_factor(res, f); + fmpz_mod_poly_factor_clear(res); + t = (clock() - t) / CLOCKS_PER_SEC; + T2 += t; + + t = clock(); + fmpz_mod_poly_factor_init(res); + fmpz_mod_poly_factor_kaltofen_shoup(res, f); + fmpz_mod_poly_factor_clear(res); + t = (clock() - t) / CLOCKS_PER_SEC; + T3 += t; + + fmpz_mod_poly_clear(f); + } + + flint_printf("CZ: %.2lf F: %.2lf KS: %.2lf\n", T1, T2, T3); + fflush(stdout); + + if (T1 > T3 + 1) + break; + } + + mpz_nextprime(pz, curr); + flint_mpz_mul_ui(curr, curr, 10); + } + + flint_printf("Irreducible polynomials\n"); + flint_mpz_set_ui(pz, 2); + flint_mpz_set_ui(curr, 10); + for (i = 0; i < NP; i++) + { + fmpz_set_mpz(p, pz); + flint_printf("========== p: "); fmpz_print(p); flint_printf(" ==========\n"); + fflush(stdout); + + for (j = 0; j < ND; j++) + { + n = degs[j]; + flint_printf(">>>>>n: %d\n", n); + fflush(stdout); + + T1 = 0; + T2 = 0; + T3 = 0; + for (k = 0; k < iter_count[j]; k++) + { + fmpz_mod_poly_init(f, p); + fmpz_mod_poly_randtest_irreducible(f, state, n); + + t = clock(); + fmpz_mod_poly_factor_init(res); + fmpz_mod_poly_factor_cantor_zassenhaus(res, f); + fmpz_mod_poly_factor_clear(res); + t = (clock() - t) / CLOCKS_PER_SEC; + T1 += t; + + t = clock(); + fmpz_mod_poly_factor_init(res); + fmpz_mod_poly_factor_berlekamp(res, f); + fmpz_mod_poly_factor_clear(res); + t = (clock() - t) / CLOCKS_PER_SEC; + T2 += t; + + t = clock(); + fmpz_mod_poly_factor_init(res); + fmpz_mod_poly_factor_kaltofen_shoup(res, f); + fmpz_mod_poly_factor_clear(res); + t = (clock() - t) / CLOCKS_PER_SEC; + T3 += t; + + fmpz_mod_poly_clear(f); + } + + flint_printf("CZ: %.2lf B: %.2lf KS: %.2lf\n", T1, T2, T3); + fflush(stdout); + + if (T1 > T3 + 1) + break; + } + + mpz_nextprime(pz, curr); + flint_mpz_mul_ui(curr, curr, 10); + } + + flint_printf("Product of two irreducible polynomials\n"); + flint_mpz_set_ui(pz, 2); + flint_mpz_set_ui(curr, 10); + for (i = 0; i < NP; i++) + { + fmpz_set_mpz(p, pz); + flint_printf("========== p: "); fmpz_print(p); flint_printf(" ==========\n"); + fflush(stdout); + + for (j = 0; j < ND; j++) + { + n = (degs[j] >> 1); + flint_printf(">>>>>n: %d\n", n); + fflush(stdout); + + T1 = 0; + T2 = 0; + T3 = 0; + for (k = 0; k < iter_count[j]; k++) + { + fmpz_mod_poly_init(f, p); + fmpz_mod_poly_init(g, p); + fmpz_mod_poly_randtest_irreducible(f, state, n); + fmpz_mod_poly_randtest_irreducible(g, state, n); + fmpz_mod_poly_mul(f, f, g); + + t = clock(); + fmpz_mod_poly_factor_init(res); + fmpz_mod_poly_factor_cantor_zassenhaus(res, f); + fmpz_mod_poly_factor_clear(res); + t = (clock() - t) / CLOCKS_PER_SEC; + T1 += t; + + t = clock(); + fmpz_mod_poly_factor_init(res); + fmpz_mod_poly_factor_berlekamp(res, f); + fmpz_mod_poly_factor_clear(res); + t = (clock() - t) / CLOCKS_PER_SEC; + T2 += t; + + t = clock(); + fmpz_mod_poly_factor_init(res); + fmpz_mod_poly_factor_kaltofen_shoup(res, f); + fmpz_mod_poly_factor_clear(res); + t = (clock() - t) / CLOCKS_PER_SEC; + T3 += t; + + fmpz_mod_poly_clear(f); + fmpz_mod_poly_clear(g); + } + + flint_printf("CZ: %.2lf B: %.2lf KS: %.2lf\n", T1, T2, T3); + fflush(stdout); + + if (T1 > T3 + 1) + break; + } + + mpz_nextprime(pz, curr); + flint_mpz_mul_ui(curr, curr, 10); + } + + flint_printf("Product of 8 small irreducible polynomials\n"); + flint_mpz_set_ui(pz, 2); + flint_mpz_set_ui(curr, 10); + for (i = 0; i < NP; i++) + { + fmpz_set_mpz(p, pz); + flint_printf("========== p: "); fmpz_print(p); flint_printf(" ==========\n"); + fflush(stdout); + + for (j = 1; j < ND; j++) + { + n = (degs[j] >> 3); + flint_printf(">>>>>n: %d\n", n); + fflush(stdout); + + T1 = 0; + T2 = 0; + T3 = 0; + for (k = 0; k < iter_count[j]; k++) + { + fmpz_mod_poly_init(f, p); + fmpz_mod_poly_init(g, p); + fmpz_mod_poly_randtest_irreducible(f, state, n); + for (num = 1; num < 8; num++) + { + fmpz_mod_poly_randtest_irreducible(g, state, n); + fmpz_mod_poly_mul(f, f, g); + } + + t = clock(); + fmpz_mod_poly_factor_init(res); + fmpz_mod_poly_factor_cantor_zassenhaus(res, f); + fmpz_mod_poly_factor_clear(res); + t = (clock() - t) / CLOCKS_PER_SEC; + T1 += t; + + t = clock(); + fmpz_mod_poly_factor_init(res); + fmpz_mod_poly_factor_berlekamp(res, f); + fmpz_mod_poly_factor_clear(res); + t = (clock() - t) / CLOCKS_PER_SEC; + T2 += t; + + t = clock(); + fmpz_mod_poly_factor_init(res); + fmpz_mod_poly_factor_kaltofen_shoup(res, f); + fmpz_mod_poly_factor_clear(res); + t = (clock() - t) / CLOCKS_PER_SEC; + T3 += t; + + fmpz_mod_poly_clear(f); + fmpz_mod_poly_clear(g); + } + + flint_printf("CZ: %.2lf B: %.2lf KS: %.2lf\n", T1, T2, T3); + fflush(stdout); + + if (T1 > T3 + 1) + break; + } + + mpz_nextprime(pz, curr); + flint_mpz_mul_ui(curr, curr, 10); + } + + mpz_clear(pz); + mpz_clear(curr); + fmpz_clear(p); + FLINT_TEST_CLEANUP(state); + + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/fmpz_mod_poly_factor/realloc.c b/external/flint-2.4.3/fmpz_mod_poly_factor/realloc.c new file mode 100644 index 0000000..b0bbd58 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly_factor/realloc.c @@ -0,0 +1,84 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2012 Lina Kulakova + +******************************************************************************/ + +#include +#include "fmpz_mod_poly.h" + +void +fmpz_mod_poly_factor_realloc(fmpz_mod_poly_factor_t fac, slong alloc) +{ + fmpz_t p; + fmpz_init_set_ui(p, 5); + + if (alloc == 0) /* Clear up, reinitialise */ + { + fmpz_mod_poly_factor_clear(fac); + fmpz_mod_poly_factor_init(fac); + } + else if (fac->alloc) /* Realloc */ + { + if (fac->alloc > alloc) + { + slong i; + + for (i = alloc; i < fac->num; i++) + fmpz_mod_poly_clear(fac->poly + i); + + fac->poly = + flint_realloc(fac->poly, alloc * sizeof(fmpz_mod_poly_struct)); + fac->exp = flint_realloc(fac->exp, alloc * sizeof(slong)); + fac->alloc = alloc; + } + else if (fac->alloc < alloc) + { + slong i; + + fac->poly = + flint_realloc(fac->poly, alloc * sizeof(fmpz_mod_poly_struct)); + fac->exp = flint_realloc(fac->exp, alloc * sizeof(slong)); + + for (i = fac->alloc; i < alloc; i++) + { + fmpz_mod_poly_init(fac->poly + i, p); + fac->exp[i] = WORD(0); + } + fac->alloc = alloc; + } + } + else /* Nothing allocated already so do it now */ + { + slong i; + + fac->poly = flint_malloc(alloc * sizeof(fmpz_mod_poly_struct)); + fac->exp = flint_calloc(alloc, sizeof(slong)); + + for (i = 0; i < alloc; i++) + fmpz_mod_poly_init(fac->poly + i, p); + fac->num = 0; + fac->alloc = alloc; + } + fmpz_clear(p); +} diff --git a/external/flint-2.4.3/fmpz_mod_poly_factor/set.c b/external/flint-2.4.3/fmpz_mod_poly_factor/set.c new file mode 100644 index 0000000..060a4e6 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly_factor/set.c @@ -0,0 +1,59 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2012 Lina Kulakova + +******************************************************************************/ + +#include "flint.h" +#include "fmpz_mod_poly.h" + +void +fmpz_mod_poly_factor_set(fmpz_mod_poly_factor_t res, + const fmpz_mod_poly_factor_t fac) +{ + if (res != fac) + { + if (fac->num == 0) + { + fmpz_mod_poly_factor_clear(res); + fmpz_mod_poly_factor_init(res); + } + else + { + slong i; + + fmpz_mod_poly_factor_fit_length(res, fac->num); + for (i = 0; i < fac->num; i++) + { + fmpz_mod_poly_set(res->poly + i, fac->poly + i); + res->exp[i] = fac->exp[i]; + } + for (; i < res->num; i++) + { + fmpz_mod_poly_zero(res->poly + i); + res->exp[i] = 0; + } + res->num = fac->num; + } + } +} diff --git a/external/flint-2.4.3/fmpz_mod_poly_factor/test/t-factor.c b/external/flint-2.4.3/fmpz_mod_poly_factor/test/t-factor.c new file mode 100644 index 0000000..c142f88 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly_factor/test/t-factor.c @@ -0,0 +1,142 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + +******************************************************************************/ + +#include +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int iter; + FLINT_TEST_INIT(state); + + + flint_printf("factor...."); + fflush(stdout); + + for (iter = 0; iter < 200; iter++) + { + fmpz_mod_poly_t poly1, poly, q, r, product; + fmpz_mod_poly_factor_t res; + fmpz_t modulus; + slong i, j, length, num; + slong exp[5]; + + fmpz_init_set_ui(modulus, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(poly1, modulus); + fmpz_mod_poly_init(poly, modulus); + fmpz_mod_poly_init(q, modulus); + fmpz_mod_poly_init(r, modulus); + + fmpz_mod_poly_zero(poly1); + fmpz_mod_poly_set_coeff_ui(poly1, 0, 1); + + length = n_randint(state, 7) + 2; + do + { + fmpz_mod_poly_randtest(poly, state, length); + if (poly->length) + fmpz_mod_poly_make_monic(poly, poly); + } + while ((poly->length < 2) || (!fmpz_mod_poly_is_irreducible(poly))); + + exp[0] = n_randint(state, 30) + 1; + for (i = 0; i < exp[0]; i++) + fmpz_mod_poly_mul(poly1, poly1, poly); + + num = n_randint(state, 5) + 1; + + for (i = 1; i < num; i++) + { + do + { + length = n_randint(state, 7) + 2; + fmpz_mod_poly_randtest(poly, state, length); + if (poly->length) + { + fmpz_mod_poly_make_monic(poly, poly); + fmpz_mod_poly_divrem(q, r, poly1, poly); + } + } + while ((poly->length < 2) || (!fmpz_mod_poly_is_irreducible(poly)) + || (r->length == 0)); + + exp[i] = n_randint(state, 30) + 1; + for (j = 0; j < exp[i]; j++) + fmpz_mod_poly_mul(poly1, poly1, poly); + } + + fmpz_mod_poly_factor_init(res); + fmpz_mod_poly_factor(res, poly1); + + if (res->num != num) + { + flint_printf("Error: number of factors incorrect: %wd != %wd\n", + res->num, num); + abort(); + } + + fmpz_mod_poly_init(product, &poly1->p); + fmpz_mod_poly_set_coeff_ui(product, 0, 1); + for (i = 0; i < res->num; i++) + for (j = 0; j < res->exp[i]; j++) + fmpz_mod_poly_mul(product, product, res->poly + i); + + fmpz_mod_poly_scalar_mul_fmpz(product, product, + &(poly1->coeffs[poly1->length - 1])); + + if (!fmpz_mod_poly_equal(poly1, product)) + { + flint_printf + ("Error: product of factors does not equal to the original polynomial\n"); + flint_printf("poly:\n"); + fmpz_mod_poly_print(poly1); + flint_printf("\n"); + flint_printf("product:\n"); + fmpz_mod_poly_print(product); + flint_printf("\n"); + abort(); + } + + fmpz_clear(modulus); + fmpz_mod_poly_clear(product); + fmpz_mod_poly_clear(q); + fmpz_mod_poly_clear(r); + fmpz_mod_poly_clear(poly1); + fmpz_mod_poly_clear(poly); + fmpz_mod_poly_factor_clear(res); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mod_poly_factor/test/t-factor_berlekamp.c b/external/flint-2.4.3/fmpz_mod_poly_factor/test/t-factor_berlekamp.c new file mode 100644 index 0000000..641413b --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly_factor/test/t-factor_berlekamp.c @@ -0,0 +1,142 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + +******************************************************************************/ + +#include +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int iter; + FLINT_TEST_INIT(state); + + + flint_printf("factor_berlekamp...."); + fflush(stdout); + + for (iter = 0; iter < 200; iter++) + { + fmpz_mod_poly_t poly1, poly, q, r, product; + fmpz_mod_poly_factor_t res; + fmpz_t modulus; + slong i, j, length, num; + slong exp[5]; + + fmpz_init_set_ui(modulus, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(poly1, modulus); + fmpz_mod_poly_init(poly, modulus); + fmpz_mod_poly_init(q, modulus); + fmpz_mod_poly_init(r, modulus); + + fmpz_mod_poly_zero(poly1); + fmpz_mod_poly_set_coeff_ui(poly1, 0, 1); + + length = n_randint(state, 7) + 2; + do + { + fmpz_mod_poly_randtest(poly, state, length); + if (poly->length) + fmpz_mod_poly_make_monic(poly, poly); + } + while ((poly->length < 2) || (!fmpz_mod_poly_is_irreducible(poly))); + + exp[0] = n_randint(state, 30) + 1; + for (i = 0; i < exp[0]; i++) + fmpz_mod_poly_mul(poly1, poly1, poly); + + num = n_randint(state, 5) + 1; + + for (i = 1; i < num; i++) + { + do + { + length = n_randint(state, 7) + 2; + fmpz_mod_poly_randtest(poly, state, length); + if (poly->length) + { + fmpz_mod_poly_make_monic(poly, poly); + fmpz_mod_poly_divrem(q, r, poly1, poly); + } + } + while ((poly->length < 2) || (!fmpz_mod_poly_is_irreducible(poly)) + || (r->length == 0)); + + exp[i] = n_randint(state, 30) + 1; + for (j = 0; j < exp[i]; j++) + fmpz_mod_poly_mul(poly1, poly1, poly); + } + + fmpz_mod_poly_factor_init(res); + fmpz_mod_poly_factor_berlekamp(res, poly1); + + if (res->num != num) + { + flint_printf("Error: number of factors incorrect: %wd != %wd\n", + res->num, num); + abort(); + } + + fmpz_mod_poly_init(product, &poly1->p); + fmpz_mod_poly_set_coeff_ui(product, 0, 1); + for (i = 0; i < res->num; i++) + for (j = 0; j < res->exp[i]; j++) + fmpz_mod_poly_mul(product, product, res->poly + i); + + fmpz_mod_poly_scalar_mul_fmpz(product, product, + &(poly1->coeffs[poly1->length - 1])); + + if (!fmpz_mod_poly_equal(poly1, product)) + { + flint_printf + ("Error: product of factors does not equal to the original polynomial\n"); + flint_printf("poly:\n"); + fmpz_mod_poly_print(poly1); + flint_printf("\n"); + flint_printf("product:\n"); + fmpz_mod_poly_print(product); + flint_printf("\n"); + abort(); + } + + fmpz_clear(modulus); + fmpz_mod_poly_clear(product); + fmpz_mod_poly_clear(q); + fmpz_mod_poly_clear(r); + fmpz_mod_poly_clear(poly1); + fmpz_mod_poly_clear(poly); + fmpz_mod_poly_factor_clear(res); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mod_poly_factor/test/t-factor_cantor_zassenhaus.c b/external/flint-2.4.3/fmpz_mod_poly_factor/test/t-factor_cantor_zassenhaus.c new file mode 100644 index 0000000..a9a33d4 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly_factor/test/t-factor_cantor_zassenhaus.c @@ -0,0 +1,142 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + +******************************************************************************/ + +#include +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int iter; + FLINT_TEST_INIT(state); + + + flint_printf("factor_cantor_zassenhaus...."); + fflush(stdout); + + for (iter = 0; iter < 200; iter++) + { + fmpz_mod_poly_t poly1, poly, q, r, product; + fmpz_mod_poly_factor_t res; + fmpz_t modulus; + slong i, j, length, num; + slong exp[5]; + + fmpz_init_set_ui(modulus, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(poly1, modulus); + fmpz_mod_poly_init(poly, modulus); + fmpz_mod_poly_init(q, modulus); + fmpz_mod_poly_init(r, modulus); + + fmpz_mod_poly_zero(poly1); + fmpz_mod_poly_set_coeff_ui(poly1, 0, 1); + + length = n_randint(state, 7) + 2; + do + { + fmpz_mod_poly_randtest(poly, state, length); + if (poly->length) + fmpz_mod_poly_make_monic(poly, poly); + } + while ((poly->length < 2) || (!fmpz_mod_poly_is_irreducible(poly))); + + exp[0] = n_randint(state, 30) + 1; + for (i = 0; i < exp[0]; i++) + fmpz_mod_poly_mul(poly1, poly1, poly); + + num = n_randint(state, 5) + 1; + + for (i = 1; i < num; i++) + { + do + { + length = n_randint(state, 7) + 2; + fmpz_mod_poly_randtest(poly, state, length); + if (poly->length) + { + fmpz_mod_poly_make_monic(poly, poly); + fmpz_mod_poly_divrem(q, r, poly1, poly); + } + } + while ((poly->length < 2) || (!fmpz_mod_poly_is_irreducible(poly)) + || (r->length == 0)); + + exp[i] = n_randint(state, 30) + 1; + for (j = 0; j < exp[i]; j++) + fmpz_mod_poly_mul(poly1, poly1, poly); + } + + fmpz_mod_poly_factor_init(res); + fmpz_mod_poly_factor_cantor_zassenhaus(res, poly1); + + if (res->num != num) + { + flint_printf("Error: number of factors incorrect: %wd != %wd\n", + res->num, num); + abort(); + } + + fmpz_mod_poly_init(product, &poly1->p); + fmpz_mod_poly_set_coeff_ui(product, 0, 1); + for (i = 0; i < res->num; i++) + for (j = 0; j < res->exp[i]; j++) + fmpz_mod_poly_mul(product, product, res->poly + i); + + fmpz_mod_poly_scalar_mul_fmpz(product, product, + &(poly1->coeffs[poly1->length - 1])); + + if (!fmpz_mod_poly_equal(poly1, product)) + { + flint_printf + ("Error: product of factors does not equal to the original polynomial\n"); + flint_printf("poly:\n"); + fmpz_mod_poly_print(poly1); + flint_printf("\n"); + flint_printf("product:\n"); + fmpz_mod_poly_print(product); + flint_printf("\n"); + abort(); + } + + fmpz_clear(modulus); + fmpz_mod_poly_clear(product); + fmpz_mod_poly_clear(q); + fmpz_mod_poly_clear(r); + fmpz_mod_poly_clear(poly1); + fmpz_mod_poly_clear(poly); + fmpz_mod_poly_factor_clear(res); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mod_poly_factor/test/t-factor_distinct_deg.c b/external/flint-2.4.3/fmpz_mod_poly_factor/test/t-factor_distinct_deg.c new file mode 100644 index 0000000..e245a81 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly_factor/test/t-factor_distinct_deg.c @@ -0,0 +1,137 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + +******************************************************************************/ + +#include +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int iter; + FLINT_TEST_INIT(state); + + + flint_printf("factor_distinct_deg...."); + fflush(stdout); + + for (iter = 0; iter < 200; iter++) + { + fmpz_mod_poly_t poly1, poly, q, r, product; + fmpz_mod_poly_factor_t res; + fmpz_t modulus; + slong i, length, num; + slong *degs; + + fmpz_init(modulus); + fmpz_set_ui(modulus, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(poly1, modulus); + fmpz_mod_poly_init(poly, modulus); + fmpz_mod_poly_init(q, modulus); + fmpz_mod_poly_init(r, modulus); + + fmpz_mod_poly_zero(poly1); + fmpz_mod_poly_set_coeff_ui(poly1, 0, 1); + + length = n_randint(state, 7) + 2; + do + { + fmpz_mod_poly_randtest(poly, state, length); + if (poly->length) + fmpz_mod_poly_make_monic(poly, poly); + } + while ((poly->length < 2) || (!fmpz_mod_poly_is_irreducible(poly))); + + fmpz_mod_poly_mul(poly1, poly1, poly); + + num = n_randint(state, 5) + 1; + + for (i = 1; i < num; i++) + { + do + { + length = n_randint(state, 7) + 2; + fmpz_mod_poly_randtest(poly, state, length); + if (poly->length) + { + fmpz_mod_poly_make_monic(poly, poly); + fmpz_mod_poly_divrem(q, r, poly1, poly); + } + } + while ((poly->length < 2) || (!fmpz_mod_poly_is_irreducible(poly)) + || (r->length == 0)); + + fmpz_mod_poly_mul(poly1, poly1, poly); + } + + if (!(degs = flint_malloc((poly1->length - 1) * sizeof(slong)))) + { + flint_printf("Fatal error: not enough memory."); + abort(); + } + fmpz_mod_poly_factor_init(res); + fmpz_mod_poly_factor_distinct_deg(res, poly1, °s); + + fmpz_mod_poly_init(product, &poly1->p); + fmpz_mod_poly_set_coeff_ui(product, 0, 1); + for (i = 0; i < res->num; i++) + fmpz_mod_poly_mul(product, product, res->poly + i); + + fmpz_mod_poly_scalar_mul_fmpz(product, product, + &(poly1->coeffs[poly1->length - 1])); + + if (!fmpz_mod_poly_equal(poly1, product)) + { + flint_printf + ("Error: product of factors does not equal to the original polynomial\n"); + flint_printf("poly:\n"); + fmpz_mod_poly_print(poly1); + flint_printf("\n"); + flint_printf("product:\n"); + fmpz_mod_poly_print(product); + flint_printf("\n"); + abort(); + } + + flint_free(degs); + fmpz_clear(modulus); + fmpz_mod_poly_clear(product); + fmpz_mod_poly_clear(q); + fmpz_mod_poly_clear(r); + fmpz_mod_poly_clear(poly1); + fmpz_mod_poly_clear(poly); + fmpz_mod_poly_factor_clear(res); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mod_poly_factor/test/t-factor_equal_deg_prob.c b/external/flint-2.4.3/fmpz_mod_poly_factor/test/t-factor_equal_deg_prob.c new file mode 100644 index 0000000..fbfa400 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly_factor/test/t-factor_equal_deg_prob.c @@ -0,0 +1,108 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Lina Kulakova + +******************************************************************************/ + +#include +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int iter; + FLINT_TEST_INIT(state); + + + flint_printf("factor_equal_deg_prob...."); + fflush(stdout); + + for (iter = 0; iter < 200; iter++) + { + fmpz_mod_poly_t poly1, poly2, q, r; + fmpz_t modulus; + slong length; + int i, num; + + fmpz_init_set_ui(modulus, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(q, modulus); + fmpz_mod_poly_init(r, modulus); + fmpz_mod_poly_init(poly1, modulus); + fmpz_mod_poly_init(poly2, modulus); + + length = n_randint(state, 10) + 2; + do + { + fmpz_mod_poly_randtest(poly1, state, length); + if (poly1->length) + fmpz_mod_poly_make_monic(poly1, poly1); + } + while ((poly1->length < 2) || (!fmpz_mod_poly_is_irreducible(poly1))); + + num = n_randint(state, 5) + 1; + + for (i = 0; i < num; i++) + { + do + { + fmpz_mod_poly_randtest(poly2, state, length); + if (poly2->length) + fmpz_mod_poly_make_monic(poly2, poly2); + } + while ((poly2->length < 2) + || (!fmpz_mod_poly_is_irreducible(poly2))); + + fmpz_mod_poly_mul(poly1, poly1, poly2); + } + + while (!fmpz_mod_poly_factor_equal_deg_prob + (poly2, state, poly1, length - 1)) + { + }; + fmpz_mod_poly_divrem(q, r, poly1, poly2); + if (!fmpz_mod_poly_is_zero(r)) + { + flint_printf("FAIL:\n"); + flint_printf("Error: factor does not divide original polynomial\n"); + flint_printf("factor:\n"); + fmpz_mod_poly_print(poly2); + flint_printf("\n\n"); + flint_printf("polynomial:\n"); + fmpz_mod_poly_print(poly1); + flint_printf("\n\n"); + abort(); + } + + fmpz_clear(modulus); + fmpz_mod_poly_clear(q); + fmpz_mod_poly_clear(r); + fmpz_mod_poly_clear(poly1); + fmpz_mod_poly_clear(poly2); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mod_poly_factor/test/t-factor_kaltofen_shoup.c b/external/flint-2.4.3/fmpz_mod_poly_factor/test/t-factor_kaltofen_shoup.c new file mode 100644 index 0000000..597e3bc --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly_factor/test/t-factor_kaltofen_shoup.c @@ -0,0 +1,142 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + +******************************************************************************/ + +#include +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int iter; + FLINT_TEST_INIT(state); + + + flint_printf("factor_kaltofen_shoup...."); + fflush(stdout); + + for (iter = 0; iter < 200; iter++) + { + fmpz_mod_poly_t poly1, poly, q, r, product; + fmpz_mod_poly_factor_t res; + fmpz_t modulus; + slong i, j, length, num; + slong exp[5]; + + fmpz_init_set_ui(modulus, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(poly1, modulus); + fmpz_mod_poly_init(poly, modulus); + fmpz_mod_poly_init(q, modulus); + fmpz_mod_poly_init(r, modulus); + + fmpz_mod_poly_zero(poly1); + fmpz_mod_poly_set_coeff_ui(poly1, 0, 1); + + length = n_randint(state, 7) + 2; + do + { + fmpz_mod_poly_randtest(poly, state, length); + if (poly->length) + fmpz_mod_poly_make_monic(poly, poly); + } + while ((poly->length < 2) || (!fmpz_mod_poly_is_irreducible(poly))); + + exp[0] = n_randint(state, 30) + 1; + for (i = 0; i < exp[0]; i++) + fmpz_mod_poly_mul(poly1, poly1, poly); + + num = n_randint(state, 5) + 1; + + for (i = 1; i < num; i++) + { + do + { + length = n_randint(state, 7) + 2; + fmpz_mod_poly_randtest(poly, state, length); + if (poly->length) + { + fmpz_mod_poly_make_monic(poly, poly); + fmpz_mod_poly_divrem(q, r, poly1, poly); + } + } + while ((poly->length < 2) || (!fmpz_mod_poly_is_irreducible(poly)) + || (r->length == 0)); + + exp[i] = n_randint(state, 30) + 1; + for (j = 0; j < exp[i]; j++) + fmpz_mod_poly_mul(poly1, poly1, poly); + } + + fmpz_mod_poly_factor_init(res); + fmpz_mod_poly_factor_kaltofen_shoup(res, poly1); + + if (res->num != num) + { + flint_printf("Error: number of factors incorrect: %wd != %wd\n", + res->num, num); + abort(); + } + + fmpz_mod_poly_init(product, &poly1->p); + fmpz_mod_poly_set_coeff_ui(product, 0, 1); + for (i = 0; i < res->num; i++) + for (j = 0; j < res->exp[i]; j++) + fmpz_mod_poly_mul(product, product, res->poly + i); + + fmpz_mod_poly_scalar_mul_fmpz(product, product, + &(poly1->coeffs[poly1->length - 1])); + + if (!fmpz_mod_poly_equal(poly1, product)) + { + flint_printf + ("Error: product of factors does not equal to the original polynomial\n"); + flint_printf("poly:\n"); + fmpz_mod_poly_print(poly1); + flint_printf("\n"); + flint_printf("product:\n"); + fmpz_mod_poly_print(product); + flint_printf("\n"); + abort(); + } + + fmpz_clear(modulus); + fmpz_mod_poly_clear(product); + fmpz_mod_poly_clear(q); + fmpz_mod_poly_clear(r); + fmpz_mod_poly_clear(poly1); + fmpz_mod_poly_clear(poly); + fmpz_mod_poly_factor_clear(res); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mod_poly_factor/test/t-factor_squarefree.c b/external/flint-2.4.3/fmpz_mod_poly_factor/test/t-factor_squarefree.c new file mode 100644 index 0000000..d60e779 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly_factor/test/t-factor_squarefree.c @@ -0,0 +1,144 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz_vec.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int iter; + FLINT_TEST_INIT(state); + + + flint_printf("factor_squarefree...."); + fflush(stdout); + + for (iter = 0; iter < 300; iter++) + { + int result = 1; + fmpz_mod_poly_t pol1, poly, quot, rem; + fmpz_mod_poly_factor_t res; + fmpz_t modulus; + slong exp[5], prod1; + slong length, i, j, num; + + fmpz_init_set_ui(modulus, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(pol1, modulus); + fmpz_mod_poly_init(poly, modulus); + fmpz_mod_poly_init(quot, modulus); + fmpz_mod_poly_init(rem, modulus); + + fmpz_mod_poly_zero(pol1); + fmpz_mod_poly_set_coeff_ui(pol1, 0, 1); + + length = n_randint(state, 7) + 2; + + do + { + fmpz_mod_poly_randtest(poly, state, length); + fmpz_mod_poly_make_monic(poly, poly); + } + while ((!fmpz_mod_poly_is_irreducible(poly)) || (poly->length < 2)); + exp[0] = n_randprime(state, 5, 0); + + prod1 = exp[0]; + for (i = 0; i < exp[0]; i++) + fmpz_mod_poly_mul(pol1, pol1, poly); + + num = n_randint(state, 5) + 1; + for (i = 1; i < num; i++) + { + do + { + length = n_randint(state, 7) + 2; + fmpz_mod_poly_randtest(poly, state, length); + if (poly->length) + { + fmpz_mod_poly_make_monic(poly, poly); + fmpz_mod_poly_divrem(quot, rem, pol1, poly); + } + } + while ((!fmpz_mod_poly_is_irreducible(poly)) || + (poly->length < 2) || (rem->length == 0)); + + do + exp[i] = n_randprime(state, 5, 0); + while (prod1 % exp[i] == 0); + + prod1 *= exp[i]; + for (j = 0; j < exp[i]; j++) + fmpz_mod_poly_mul(pol1, pol1, poly); + } + + fmpz_mod_poly_factor_init(res); + fmpz_mod_poly_factor_squarefree(res, pol1); + + result &= (res->num == num); + if (result) + { + ulong prod2 = 1; + for (i = 0; i < num; i++) + prod2 *= res->exp[i]; + result &= (prod1 == prod2); + } + + if (!result) + { + flint_printf("Error: exp don't match. Modulus = "); + fmpz_print(modulus); + flint_printf("\n"); + for (i = 0; i < res->num; i++) + flint_printf("%wd ", res->exp[i]); + flint_printf("\n"); + for (i = 0; i < num; i++) + flint_printf("%wd ", exp[i]); + flint_printf("\n"); + abort(); + } + + fmpz_clear(modulus); + fmpz_mod_poly_clear(quot); + fmpz_mod_poly_clear(rem); + fmpz_mod_poly_clear(pol1); + fmpz_mod_poly_clear(poly); + fmpz_mod_poly_factor_clear(res); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mod_poly_factor/test/t-is_irreducible.c b/external/flint-2.4.3/fmpz_mod_poly_factor/test/t-is_irreducible.c new file mode 100644 index 0000000..7deae2b --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly_factor/test/t-is_irreducible.c @@ -0,0 +1,99 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz_vec.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int iter; + FLINT_TEST_INIT(state); + + + flint_printf("is_irreducible...."); + fflush(stdout); + + for (iter = 0; iter < 100; iter++) + { + fmpz_mod_poly_t poly1, poly2; + fmpz_t modulus; + slong length; + int i, num; + + fmpz_init_set_ui(modulus, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(poly1, modulus); + fmpz_mod_poly_init(poly2, modulus); + + length = n_randint(state, 10) + 2; + do + { + fmpz_mod_poly_randtest(poly1, state, length); + if (!fmpz_mod_poly_is_zero(poly1)) + fmpz_mod_poly_make_monic(poly1, poly1); + } + while ((!fmpz_mod_poly_is_irreducible(poly1)) || (poly1->length < 2)); + + num = n_randint(state, 5) + 1; + + for (i = 0; i < num; i++) + { + do + { + fmpz_mod_poly_randtest(poly2, state, length); + if (!fmpz_mod_poly_is_zero(poly1)) + fmpz_mod_poly_make_monic(poly2, poly2); + } + while ((!fmpz_mod_poly_is_irreducible(poly2)) || (poly2->length < 2)); + + fmpz_mod_poly_mul(poly1, poly1, poly2); + } + + if (fmpz_mod_poly_is_irreducible(poly1)) + { + flint_printf("Error: reducible polynomial declared irreducible!\n"); + flint_printf("poly:\n"); + fmpz_mod_poly_print(poly1); + flint_printf("\n"); + abort(); + } + + fmpz_clear(modulus); + fmpz_mod_poly_clear(poly1); + fmpz_mod_poly_clear(poly2); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mod_poly_factor/test/t-is_irreducible_ddf.c b/external/flint-2.4.3/fmpz_mod_poly_factor/test/t-is_irreducible_ddf.c new file mode 100644 index 0000000..5ded040 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly_factor/test/t-is_irreducible_ddf.c @@ -0,0 +1,99 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz_vec.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int iter; + FLINT_TEST_INIT(state); + + + flint_printf("is_irreducible_ddf...."); + fflush(stdout); + + for (iter = 0; iter < 100; iter++) + { + fmpz_mod_poly_t poly1, poly2; + fmpz_t modulus; + slong length; + int i, num; + + fmpz_init_set_ui(modulus, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(poly1, modulus); + fmpz_mod_poly_init(poly2, modulus); + + length = n_randint(state, 10) + 2; + do + { + fmpz_mod_poly_randtest(poly1, state, length); + if (!fmpz_mod_poly_is_zero(poly1)) + fmpz_mod_poly_make_monic(poly1, poly1); + } + while ((!fmpz_mod_poly_is_irreducible_ddf(poly1)) || (poly1->length < 2)); + + num = n_randint(state, 5) + 1; + + for (i = 0; i < num; i++) + { + do + { + fmpz_mod_poly_randtest(poly2, state, length); + if (!fmpz_mod_poly_is_zero(poly1)) + fmpz_mod_poly_make_monic(poly2, poly2); + } + while ((!fmpz_mod_poly_is_irreducible_ddf(poly2)) || (poly2->length < 2)); + + fmpz_mod_poly_mul(poly1, poly1, poly2); + } + + if (fmpz_mod_poly_is_irreducible_ddf(poly1)) + { + flint_printf("Error: reducible polynomial declared irreducible!\n"); + flint_printf("poly:\n"); + fmpz_mod_poly_print(poly1); + flint_printf("\n"); + abort(); + } + + fmpz_clear(modulus); + fmpz_mod_poly_clear(poly1); + fmpz_mod_poly_clear(poly2); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mod_poly_factor/test/t-is_irreducible_rabin.c b/external/flint-2.4.3/fmpz_mod_poly_factor/test/t-is_irreducible_rabin.c new file mode 100644 index 0000000..963242a --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly_factor/test/t-is_irreducible_rabin.c @@ -0,0 +1,99 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz_vec.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int iter; + FLINT_TEST_INIT(state); + + + flint_printf("is_irreducible_rabin...."); + fflush(stdout); + + for (iter = 0; iter < 100; iter++) + { + fmpz_mod_poly_t poly1, poly2; + fmpz_t modulus; + slong length; + int i, num; + + fmpz_init_set_ui(modulus, n_randtest_prime(state, 0)); + + fmpz_mod_poly_init(poly1, modulus); + fmpz_mod_poly_init(poly2, modulus); + + length = n_randint(state, 10) + 2; + do + { + fmpz_mod_poly_randtest(poly1, state, length); + if (!fmpz_mod_poly_is_zero(poly1)) + fmpz_mod_poly_make_monic(poly1, poly1); + } + while ((!fmpz_mod_poly_is_irreducible_rabin(poly1)) || (poly1->length < 2)); + + num = n_randint(state, 5) + 1; + + for (i = 0; i < num; i++) + { + do + { + fmpz_mod_poly_randtest(poly2, state, length); + if (!fmpz_mod_poly_is_zero(poly1)) + fmpz_mod_poly_make_monic(poly2, poly2); + } + while ((!fmpz_mod_poly_is_irreducible_rabin(poly2)) || (poly2->length < 2)); + + fmpz_mod_poly_mul(poly1, poly1, poly2); + } + + if (fmpz_mod_poly_is_irreducible_rabin(poly1)) + { + flint_printf("Error: reducible polynomial declared irreducible!\n"); + flint_printf("poly:\n"); + fmpz_mod_poly_print(poly1); + flint_printf("\n"); + abort(); + } + + fmpz_clear(modulus); + fmpz_mod_poly_clear(poly1); + fmpz_mod_poly_clear(poly2); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mod_poly_factor/test/t-is_squarefree.c b/external/flint-2.4.3/fmpz_mod_poly_factor/test/t-is_squarefree.c new file mode 100644 index 0000000..a278373 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly_factor/test/t-is_squarefree.c @@ -0,0 +1,112 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz_vec.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int iter; + FLINT_TEST_INIT(state); + + + flint_printf("is_squarefree...."); + fflush(stdout); + + for (iter = 0; iter < 200 * flint_test_multiplier(); iter++) + { + fmpz_mod_poly_t poly, Q, R, t; + fmpz_t modulus; + mp_limb_t mod; + slong i, num_factors, exp, max_exp; + int v, result; + + mod = n_randtest_prime(state, 0); + fmpz_init_set_ui(modulus, mod); + + fmpz_mod_poly_init(poly, modulus); + fmpz_mod_poly_init(t, modulus); + fmpz_mod_poly_init(Q, modulus); + fmpz_mod_poly_init(R, modulus); + + fmpz_mod_poly_set_coeff_ui(poly, 0, n_randint(state, mod)); + num_factors = n_randint(state, 5); + + max_exp = 0; + for (i = 0; i < num_factors; i++) + { + do { + fmpz_mod_poly_randtest(t, state, n_randint(state, 10)); + } while (!fmpz_mod_poly_is_irreducible(t) || + (fmpz_mod_poly_length(t) < 2)); + + exp = n_randint(state, 4) + 1; + if (n_randint(state, 2) == 0) + exp = 1; + + fmpz_mod_poly_divrem(Q, R, poly, t); + if (!fmpz_mod_poly_is_zero(R)) + { + fmpz_mod_poly_pow(t, t, exp); + fmpz_mod_poly_mul(poly, poly, t); + max_exp = FLINT_MAX(exp, max_exp); + } + } + + v = fmpz_mod_poly_is_squarefree(poly); + + if (v == 1) + result = (max_exp <= 1 && !fmpz_mod_poly_is_zero(poly)); + else + result = (max_exp > 1 || fmpz_mod_poly_is_zero(poly)); + + if (!result) + { + flint_printf("FAIL: "); + fmpz_print(modulus); + flint_printf(" %wd, %d\n", max_exp, v); + fmpz_mod_poly_print(poly); flint_printf("\n"); + abort(); + } + + fmpz_clear(modulus); + fmpz_mod_poly_clear(poly); + fmpz_mod_poly_clear(t); + fmpz_mod_poly_clear(Q); + fmpz_mod_poly_clear(R); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_mod_poly_factorxx.h b/external/flint-2.4.3/fmpz_mod_poly_factorxx.h new file mode 100644 index 0000000..edd9343 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_poly_factorxx.h @@ -0,0 +1,147 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#ifndef FMPZ_MOD_POLY_FACTORXX_H +#define FMPZ_MOD_POLY_FACTORXX_H + + +#include "fmpz_mod_poly.h" + +namespace flint { +class fmpz_mod_poly_factorxx +{ +private: + fmpz_mod_poly_factor_t inner; + +public: + fmpz_mod_poly_factorxx() {fmpz_mod_poly_factor_init(inner);} + ~fmpz_mod_poly_factorxx() {fmpz_mod_poly_factor_clear(inner);} + + fmpz_mod_poly_factorxx(const fmpz_mod_poly_factorxx& o) + { + fmpz_mod_poly_factor_init(inner); + fmpz_mod_poly_factor_set(inner, o.inner); + } + + bool operator==(const fmpz_mod_poly_factorxx& o) + { + if(o.size() != size()) + return false; + for(slong i = 0;i < size();++i) + if(p(i) != o.p(i) || exp(i) != o.exp(i)) + return false; + return true; + } + + fmpz_mod_poly_factorxx& operator=(const fmpz_mod_poly_factorxx& o) + { + fmpz_mod_poly_factor_set(inner, o.inner); + return *this; + } + + slong size() const {return inner->num;} + slong exp(slong i) const {return inner->exp[i];} + slong& exp(slong i) {return inner->exp[i];} + fmpz_mod_polyxx_srcref p(slong i) const + {return fmpz_mod_polyxx_srcref::make(inner->poly + i);} + fmpz_mod_polyxx_ref p(slong i) {return fmpz_mod_polyxx_ref::make(inner->poly + i);} + + fmpz_mod_poly_factor_t& _data() {return inner;} + const fmpz_mod_poly_factor_t& _data() const {return inner;} + + void realloc(slong a) {fmpz_mod_poly_factor_realloc(inner, a);} + void fit_length(slong a) {fmpz_mod_poly_factor_fit_length(inner, a);} + + void print() const {fmpz_mod_poly_factor_print(inner);} + + template + void insert(const Fmpz_mod_poly& p, slong e, + typename mp::enable_if >::type* = 0) + {fmpz_mod_poly_factor_insert(_data(), p.evaluate()._poly(), e);} + + void concat(const fmpz_mod_poly_factorxx& o) + {fmpz_mod_poly_factor_concat(_data(), o._data());} + + void pow(slong exp) {fmpz_mod_poly_factor_pow(_data(), exp);} + +#define FMPZ_MOD_POLY_FACTORXX_DEFINE_SET_FACTOR(name) \ + template \ + void set_##name(const Fmpz_mod_poly& p, \ + typename mp::enable_if >::type* = 0) \ + {fmpz_mod_poly_##name(_data(), p.evaluate()._poly());} + + FMPZ_MOD_POLY_FACTORXX_DEFINE_SET_FACTOR(factor) + FMPZ_MOD_POLY_FACTORXX_DEFINE_SET_FACTOR(factor_squarefree) + FMPZ_MOD_POLY_FACTORXX_DEFINE_SET_FACTOR(factor_cantor_zassenhaus) + FMPZ_MOD_POLY_FACTORXX_DEFINE_SET_FACTOR(factor_berlekamp) + FMPZ_MOD_POLY_FACTORXX_DEFINE_SET_FACTOR(factor_kaltofen_shoup) + + template + bool set_factor_equal_deg_probab(frandxx& state, const Fmpz_mod_poly& p, slong d, + typename mp::enable_if >::type* = 0) + { + return fmpz_mod_poly_factor_equal_deg_prob(_data(), state._data(), + p.evaluate()._poly(), d); + } + template + void set_factor_equal_deg(const Fmpz_mod_poly& p, slong d, + typename mp::enable_if >::type* = 0) + { + fmpz_mod_poly_factor_equal_deg(_data(), p.evaluate()._poly(), d); + } + + template + void set_factor_distinct_deg(const Fmpz_mod_poly& p, std::vector& degs, + typename mp::enable_if >::type* = 0) + { + slong* dgs = °s.front(); + fmpz_mod_poly_factor_distinct_deg(_data(), p.evaluate()._poly(), &dgs); + } +}; + +#define FMPZ_MOD_POLY_FACTORXX_DEFINE_FACTOR(name) \ +template \ +fmpz_mod_poly_factorxx name(const Fmpz_mod_poly& p, \ + typename mp::enable_if >::type* = 0) \ +{ \ + fmpz_mod_poly_factorxx res; \ + res.set_##name(p); \ + return res; \ +} +FMPZ_MOD_POLY_FACTORXX_DEFINE_FACTOR(factor) +FMPZ_MOD_POLY_FACTORXX_DEFINE_FACTOR(factor_squarefree) +FMPZ_MOD_POLY_FACTORXX_DEFINE_FACTOR(factor_cantor_zassenhaus) +FMPZ_MOD_POLY_FACTORXX_DEFINE_FACTOR(factor_berlekamp) +FMPZ_MOD_POLY_FACTORXX_DEFINE_FACTOR(factor_kaltofen_shoup) + +// TODO do we want global versions of factor_distinct_deg etc? + +inline void print(const fmpz_mod_poly_factorxx& f) +{ + f.print(); +} +} // flint + +#endif diff --git a/external/flint-2.4.3/fmpz_mod_polyxx.h b/external/flint-2.4.3/fmpz_mod_polyxx.h new file mode 100644 index 0000000..cf46534 --- /dev/null +++ b/external/flint-2.4.3/fmpz_mod_polyxx.h @@ -0,0 +1,688 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#ifndef FMPZ_MOD_POLYXX_H +#define FMPZ_MOD_POLYXX_H + +#include "fmpz_mod_poly.h" + +#include "fmpzxx.h" +#include "fmpz_polyxx.h" +#include "nmod_polyxx.h" + +#include "flintxx/expression.h" +#include "flintxx/flint_classes.h" +#include "flintxx/flint_exception.h" +#include "flintxx/frandxx.h" +#include "flintxx/ltuple.h" +#include "flintxx/stdmath.h" +#include "flintxx/vector.h" + +// TODO create/use fmpz_modxx class? + +namespace flint { +FLINT_DEFINE_BINOP(divrem_f) +FLINT_DEFINE_BINOP(gcd_euclidean_f) +FLINT_DEFINE_BINOP(gcd_f) +FLINT_DEFINE_BINOP(radix) + +FLINT_DEFINE_UNOP(fmpz_mod_polyxx_lead) // TODO standardise? +FLINT_DEFINE_BINOP(fmpz_mod_polyxx_get_coeff) // TODO standardise? + +namespace detail { +template +struct fmpz_mod_poly_traits +{ + typedef FLINT_UNOP_BUILD_RETTYPE( + fmpz_mod_polyxx_lead, fmpzxx, Poly) lead_ref_t; + typedef lead_ref_t lead_srcref_t; + static lead_ref_t lead(const Poly& p) {return fmpz_mod_polyxx_lead(p);} +}; +} + +template +class fmpz_mod_polyxx_expression + : public expression, + Operation, Data> +{ + typedef expression, + Operation, Data> base_t; + typedef detail::fmpz_mod_poly_traits + poly_traits_t; + + FLINTXX_DEFINE_BASICS(fmpz_mod_polyxx_expression) + FLINTXX_DEFINE_CTORS(fmpz_mod_polyxx_expression) + FLINTXX_DEFINE_C_REF(fmpz_mod_polyxx_expression, fmpz_mod_poly_struct, _poly) + + template + static fmpz_mod_polyxx_expression randtest(const Fmpz& m, + frandxx& state, slong len) + { + fmpz_mod_polyxx_expression res(m); + res.set_randtest(state, len); + return res; + } + template + static fmpz_mod_polyxx_expression randtest_irreducible(const Fmpz& m, + frandxx& state, slong len) + { + fmpz_mod_polyxx_expression res(m); + res.set_randtest_irreducible(state, len); + return res; + } + template + static fmpz_mod_polyxx_expression randtest_not_zero(const Fmpz& m, + frandxx& state, slong len) + { + fmpz_mod_polyxx_expression res(m); + res.set_randtest_not_zero(state, len); + return res; + } + + template + static fmpz_mod_polyxx_expression zero(const Fmpz& m) + {return fmpz_mod_polyxx_expression(m);} + + // these only make sense with immediates + fmpzxx_srcref _mod() const + {return fmpzxx_srcref::make(fmpz_mod_poly_modulus(_poly()));} + + // These only make sense with target immediates + void realloc(slong alloc) {fmpz_mod_poly_realloc(_poly(), alloc);} + void fit_length(slong len) {fmpz_mod_poly_fit_length(_poly(), len);} + void _normalise() {_fmpz_mod_poly_normalise(_poly());} + void set_coeff(slong n, ulong c) {fmpz_mod_poly_set_coeff_ui(_poly(), n, c);} + template + typename mp::enable_if >::type + set_coeff(slong j, const Fmpz& c) + { + fmpz_mod_poly_set_coeff_fmpz(_poly(), j, c.evaluate()._fmpz()); + } + void truncate(slong n) {fmpz_mod_poly_truncate(_poly(), n);} + void zero_coeffs(slong i, slong j) {fmpz_mod_poly_zero_coeffs(_poly(), i, j);} + + void set_randtest(frandxx& state, slong len) + {fmpz_mod_poly_randtest(_poly(), state._data(), len);} + void set_randtest_irreducible(frandxx& state, slong len) + {fmpz_mod_poly_randtest_irreducible(_poly(), state._data(), len);} + void set_randtest_not_zero(frandxx& state, slong len) + {fmpz_mod_poly_randtest_not_zero(_poly(), state._data(), len);} + + template + slong remove(const Poly& p) + { + return fmpz_mod_poly_remove(_poly(), p.evaluate()._poly()); + } + + void set_zero() {fmpz_mod_poly_zero(_poly());} + + // unified coefficient access + typename poly_traits_t::lead_ref_t lead() + { + return poly_traits_t::lead(*this); + } + typename poly_traits_t::lead_srcref_t lead() const + { + return poly_traits_t::lead(*this); + } + + // this works without evaluation + fmpzxx_srcref modulus() const; + + evaluated_t create_temporary() const + { + return evaluated_t(modulus()); + } + + // These cause evaluation + slong length() const {return fmpz_mod_poly_length(this->evaluate()._poly());} + slong degree() const {return fmpz_mod_poly_degree(this->evaluate()._poly());} + bool is_zero() const {return fmpz_mod_poly_is_zero(this->evaluate()._poly());} + bool is_squarefree() const + {return fmpz_mod_poly_is_squarefree(this->evaluate()._poly());} + bool is_irreducible() const + {return fmpz_mod_poly_is_irreducible(this->evaluate()._poly());} + bool is_irreducible_ddf() const + {return fmpz_mod_poly_is_irreducible_ddf(this->evaluate()._poly());} + bool is_irreducible_rabin() const + {return fmpz_mod_poly_is_irreducible_rabin(this->evaluate()._poly());} + + // Lazy members + FLINTXX_DEFINE_MEMBER_BINOP_(get_coeff, fmpz_mod_polyxx_get_coeff) + FLINTXX_DEFINE_MEMBER_BINOP_(operator(), compeval) + + FLINTXX_DEFINE_MEMBER_UNOP(derivative) + FLINTXX_DEFINE_MEMBER_UNOP(invmod) + FLINTXX_DEFINE_MEMBER_UNOP(make_monic) + FLINTXX_DEFINE_MEMBER_UNOP(sqr) + + FLINTXX_DEFINE_MEMBER_BINOP(compose_divconquer) + FLINTXX_DEFINE_MEMBER_BINOP(compose_horner) + FLINTXX_DEFINE_MEMBER_BINOP(div_basecase) + FLINTXX_DEFINE_MEMBER_BINOP(divrem) + FLINTXX_DEFINE_MEMBER_BINOP(divrem_basecase) + FLINTXX_DEFINE_MEMBER_BINOP(divrem_divconquer) + FLINTXX_DEFINE_MEMBER_BINOP(divrem_f) + FLINTXX_DEFINE_MEMBER_BINOP(gcd) + FLINTXX_DEFINE_MEMBER_BINOP(gcd_euclidean) + FLINTXX_DEFINE_MEMBER_BINOP(gcd_euclidean_f) + FLINTXX_DEFINE_MEMBER_BINOP(gcd_f) + FLINTXX_DEFINE_MEMBER_BINOP(gcdinv) + FLINTXX_DEFINE_MEMBER_BINOP(invmod) + FLINTXX_DEFINE_MEMBER_BINOP(inv_series_newton) + FLINTXX_DEFINE_MEMBER_BINOP(shift_left) + FLINTXX_DEFINE_MEMBER_BINOP(shift_right) + FLINTXX_DEFINE_MEMBER_BINOP(pow) + FLINTXX_DEFINE_MEMBER_BINOP(radix) + FLINTXX_DEFINE_MEMBER_BINOP(rem_basecase) + FLINTXX_DEFINE_MEMBER_BINOP(xgcd) + FLINTXX_DEFINE_MEMBER_BINOP(xgcd_euclidean) + + FLINTXX_DEFINE_MEMBER_3OP(compose_mod) + FLINTXX_DEFINE_MEMBER_3OP(compose_mod_brent_kung) + FLINTXX_DEFINE_MEMBER_3OP(compose_mod_horner) + FLINTXX_DEFINE_MEMBER_3OP(mullow) + FLINTXX_DEFINE_MEMBER_3OP(mulmod) + FLINTXX_DEFINE_MEMBER_3OP(powmod_binexp) + FLINTXX_DEFINE_MEMBER_3OP(pow_trunc) + FLINTXX_DEFINE_MEMBER_3OP(pow_trunc_binexp) +}; + +namespace detail { +struct fmpz_mod_poly_data; +} + +typedef fmpz_mod_polyxx_expression + fmpz_mod_polyxx; +typedef fmpz_mod_polyxx_expression > + fmpz_mod_polyxx_ref; +typedef fmpz_mod_polyxx_expression > + fmpz_mod_polyxx_srcref; + +#define FMPZ_MOD_POLYXX_COND_S FLINTXX_COND_S(fmpz_mod_polyxx) +#define FMPZ_MOD_POLYXX_COND_T FLINTXX_COND_T(fmpz_mod_polyxx) + +namespace detail { +template<> +struct fmpz_mod_poly_traits +{ + typedef fmpzxx_srcref lead_srcref_t; + typedef fmpzxx_srcref lead_ref_t; + + template + static lead_srcref_t lead(P p) + {return lead_srcref_t::make(fmpz_mod_poly_lead(p._poly()));} +}; +template<> +struct fmpz_mod_poly_traits +{ + typedef fmpzxx_ref lead_ref_t; + typedef fmpzxx_ref lead_srcref_t; + + template + static lead_ref_t lead(P p) + {return lead_ref_t::make(fmpz_mod_poly_lead(p._poly()));} +}; +template<> +struct fmpz_mod_poly_traits +{ + typedef fmpzxx_ref lead_ref_t; + typedef fmpzxx_srcref lead_srcref_t; + + template + static lead_ref_t lead(P& p) + {return lead_ref_t::make(fmpz_mod_poly_lead(p._poly()));} + template + static lead_srcref_t lead(const P& p) + {return lead_srcref_t::make(fmpz_mod_poly_lead(p._poly()));} +}; + +struct fmpz_mod_poly_data +{ + fmpz_mod_poly_t inner; + typedef fmpz_mod_poly_t& data_ref_t; + typedef const fmpz_mod_poly_t& data_srcref_t; + + template + fmpz_mod_poly_data(const Fmpz& n, + typename mp::enable_if >::type* = 0) + { + fmpz_mod_poly_init(inner, n.evaluate()._fmpz()); + } + template + fmpz_mod_poly_data(const Fmpz& n, slong alloc, + typename mp::enable_if >::type* = 0) + { + fmpz_mod_poly_init2(inner, n.evaluate()._fmpz(), alloc); + } + ~fmpz_mod_poly_data() {fmpz_mod_poly_clear(inner);} + + fmpz_mod_poly_data(const fmpz_mod_poly_data& o) + { + fmpz_mod_poly_init(inner, fmpz_mod_poly_modulus(o.inner)); + fmpz_mod_poly_set(inner, o.inner); + } + + fmpz_mod_poly_data(fmpz_mod_polyxx_srcref r) + { + fmpz_mod_poly_init(inner, r.modulus()._fmpz()); + fmpz_mod_poly_set(inner, r._poly()); + } +}; + +struct is_fmpz_mod_polyxx_predicate +{ + template struct type : FMPZ_MOD_POLYXX_COND_S { }; +}; +} +template +inline fmpzxx_srcref +fmpz_mod_polyxx_expression::modulus() const +{ + return tools::find_subexpr( + *this)._mod(); +} + +namespace traits { +template struct is_fmpz_mod_polyxx : mp::or_< + traits::is_T_expr, + flint_classes::is_source > { }; +} + +namespace rules { +FLINT_DEFINE_DOIT_COND2(assignment, FMPZ_MOD_POLYXX_COND_T, + FMPZ_MOD_POLYXX_COND_S, fmpz_mod_poly_set(to._poly(), from._poly())) +FLINT_DEFINE_DOIT_COND2(assignment, FMPZ_MOD_POLYXX_COND_T, + traits::is_unsigned_integer, fmpz_mod_poly_set_ui(to._poly(), from)) +FLINT_DEFINE_DOIT_COND2(assignment, FMPZ_MOD_POLYXX_COND_T, + FMPZXX_COND_S, fmpz_mod_poly_set_fmpz(to._poly(), from._fmpz())) +FLINT_DEFINE_DOIT_COND2(assignment, FMPZ_MOD_POLYXX_COND_T, FMPZ_POLYXX_COND_S, + fmpz_mod_poly_set_fmpz_poly(to._poly(), from._poly())) +FLINTXX_DEFINE_CONVERSION_TMP(fmpz_polyxx, fmpz_mod_polyxx, + fmpz_mod_poly_get_fmpz_poly(to._poly(), from._poly())) + +FLINTXX_DEFINE_SWAP(fmpz_mod_polyxx, fmpz_mod_poly_swap(e1._poly(), e2._poly())) + +FLINTXX_DEFINE_EQUALS(fmpz_mod_polyxx, fmpz_mod_poly_equal(e1._poly(), e2._poly())) + +FLINT_DEFINE_BINARY_EXPR_COND2(fmpz_mod_polyxx_get_coeff_op, fmpzxx, + FMPZ_MOD_POLYXX_COND_S, traits::fits_into_slong, + fmpz_mod_poly_get_coeff_fmpz(to._fmpz(), e1._poly(), e2)) + +FLINT_DEFINE_PRINT_COND(FMPZ_MOD_POLYXX_COND_S, fmpz_mod_poly_fprint(to, from._poly())) +FLINT_DEFINE_PRINT_PRETTY_COND_2(FMPZ_MOD_POLYXX_COND_S, const char*, + fmpz_mod_poly_fprint_pretty(to, from._poly(), extra)) +FLINT_DEFINE_READ_COND(FMPZ_MOD_POLYXX_COND_T, fmpz_mod_poly_fread(from, to._poly())) + +FLINT_DEFINE_BINARY_EXPR_COND2(plus, fmpz_mod_polyxx, + FMPZ_MOD_POLYXX_COND_S, FMPZ_MOD_POLYXX_COND_S, + fmpz_mod_poly_add(to._poly(), e1._poly(), e2._poly())) +FLINT_DEFINE_BINARY_EXPR_COND2(minus, fmpz_mod_polyxx, + FMPZ_MOD_POLYXX_COND_S, FMPZ_MOD_POLYXX_COND_S, + fmpz_mod_poly_sub(to._poly(), e1._poly(), e2._poly())) + +FLINT_DEFINE_CBINARY_EXPR_COND2(times, fmpz_mod_polyxx, + FMPZ_MOD_POLYXX_COND_S, FMPZXX_COND_S, + fmpz_mod_poly_scalar_mul_fmpz(to._poly(), e1._poly(), e2._fmpz())) +FLINT_DEFINE_BINARY_EXPR_COND2(times, fmpz_mod_polyxx, + FMPZ_MOD_POLYXX_COND_S, FMPZ_MOD_POLYXX_COND_S, + fmpz_mod_poly_mul(to._poly(), e1._poly(), e2._poly())) + +// TODO expose the temporary +FLINT_DEFINE_BINARY_EXPR_COND2(divided_by, fmpz_mod_polyxx, + FMPZ_MOD_POLYXX_COND_S, FMPZ_MOD_POLYXX_COND_S, + fmpz_mod_polyxx tmp(to.modulus()); + fmpz_mod_poly_divrem(to._poly(), tmp._poly(), e1._poly(), e2._poly())) + +FLINT_DEFINE_UNARY_EXPR_COND(negate, fmpz_mod_polyxx, FMPZ_MOD_POLYXX_COND_S, + fmpz_mod_poly_neg(to._poly(), from._poly())) + +FLINT_DEFINE_UNARY_EXPR_COND(fmpz_mod_polyxx_lead_op, fmpzxx, + FMPZ_MOD_POLYXX_COND_S, + fmpz_set(to._fmpz(), fmpz_mod_poly_lead(from._poly()))) + +FLINT_DEFINE_BINARY_EXPR_COND2(shift_left_op, fmpz_mod_polyxx, + FMPZ_MOD_POLYXX_COND_S, traits::fits_into_slong, + fmpz_mod_poly_shift_left(to._poly(), e1._poly(), e2)) +FLINT_DEFINE_BINARY_EXPR_COND2(shift_right_op, fmpz_mod_polyxx, + FMPZ_MOD_POLYXX_COND_S, traits::fits_into_slong, + fmpz_mod_poly_shift_right(to._poly(), e1._poly(), e2)) + +FLINT_DEFINE_UNARY_EXPR_COND(make_monic_op, fmpz_mod_polyxx, FMPZ_MOD_POLYXX_COND_S, + fmpz_mod_poly_make_monic(to._poly(), from._poly())) + +FLINT_DEFINE_THREEARY_EXPR_COND3(mullow_op, fmpz_mod_polyxx, + FMPZ_MOD_POLYXX_COND_S, FMPZ_MOD_POLYXX_COND_S, traits::fits_into_slong, + fmpz_mod_poly_mullow(to._poly(), e1._poly(), e2._poly(), e3)) +FLINT_DEFINE_THREEARY_EXPR_COND3(mulmod_op, fmpz_mod_polyxx, + FMPZ_MOD_POLYXX_COND_S, FMPZ_MOD_POLYXX_COND_S, FMPZ_MOD_POLYXX_COND_S, + fmpz_mod_poly_mulmod(to._poly(), e1._poly(), e2._poly(), e3._poly())) +FLINT_DEFINE_UNARY_EXPR_COND(sqr_op, fmpz_mod_polyxx, FMPZ_MOD_POLYXX_COND_S, + fmpz_mod_poly_sqr(to._poly(), from._poly())) + +FLINT_DEFINE_BINARY_EXPR_COND2(modulo, fmpz_mod_polyxx, + FMPZ_MOD_POLYXX_COND_S, FMPZ_MOD_POLYXX_COND_S, + fmpz_mod_poly_rem(to._poly(), e1._poly(), e2._poly())) + +FLINT_DEFINE_THREEARY_EXPR_COND3(powmod_binexp_op, fmpz_mod_polyxx, + FMPZ_MOD_POLYXX_COND_S, traits::is_unsigned_integer, FMPZ_MOD_POLYXX_COND_S, + fmpz_mod_poly_powmod_ui_binexp(to._poly(), e1._poly(), e2, e3._poly())) +FLINT_DEFINE_THREEARY_EXPR_COND3(powmod_binexp_op, fmpz_mod_polyxx, + FMPZ_MOD_POLYXX_COND_S, FMPZXX_COND_S, FMPZ_MOD_POLYXX_COND_S, + fmpz_mod_poly_powmod_fmpz_binexp( + to._poly(), e1._poly(), e2._fmpz(), e3._poly())) + +FLINT_DEFINE_THREEARY_EXPR_COND3(pow_trunc_op, fmpz_mod_polyxx, + FMPZ_MOD_POLYXX_COND_S, traits::is_unsigned_integer, traits::fits_into_slong, + fmpz_mod_poly_pow_trunc(to._poly(), e1._poly(), e2, e3)) +FLINT_DEFINE_THREEARY_EXPR_COND3(pow_trunc_binexp_op, fmpz_mod_polyxx, + FMPZ_MOD_POLYXX_COND_S, traits::is_unsigned_integer, traits::fits_into_slong, + fmpz_mod_poly_pow_trunc_binexp(to._poly(), e1._poly(), e2, e3)) + +FLINT_DEFINE_BINARY_EXPR_COND2(pow_op, fmpz_mod_polyxx, + FMPZ_MOD_POLYXX_COND_S, traits::is_unsigned_integer, + fmpz_mod_poly_pow(to._poly(), e1._poly(), e2)) + +namespace rdetail { +typedef make_ltuple::type>::type + fmpz_mod_polyxx_pair; +typedef make_ltuple::type>::type + fmpz_mod_poly_divrem_f_rt; +} // rdetail +FLINT_DEFINE_BINARY_EXPR_COND2(divrem_basecase_op, rdetail::fmpz_mod_polyxx_pair, + FMPZ_MOD_POLYXX_COND_S, FMPZ_MOD_POLYXX_COND_S, + fmpz_mod_poly_divrem_basecase( + to.template get<0>()._poly(), to.template get<1>()._poly(), + e1._poly(), e2._poly())) +FLINT_DEFINE_BINARY_EXPR_COND2(divrem_divconquer_op, rdetail::fmpz_mod_polyxx_pair, + FMPZ_MOD_POLYXX_COND_S, FMPZ_MOD_POLYXX_COND_S, + fmpz_mod_poly_divrem_divconquer( + to.template get<0>()._poly(), to.template get<1>()._poly(), + e1._poly(), e2._poly())) +FLINT_DEFINE_BINARY_EXPR_COND2(divrem_op, rdetail::fmpz_mod_polyxx_pair, + FMPZ_MOD_POLYXX_COND_S, FMPZ_MOD_POLYXX_COND_S, + fmpz_mod_poly_divrem_divconquer( + to.template get<0>()._poly(), to.template get<1>()._poly(), + e1._poly(), e2._poly())) +FLINT_DEFINE_BINARY_EXPR_COND2(divrem_f_op, rdetail::fmpz_mod_poly_divrem_f_rt, + FMPZ_MOD_POLYXX_COND_S, FMPZ_MOD_POLYXX_COND_S, + fmpz_mod_poly_divrem_f( + to.template get<0>()._fmpz(), to.template get<1>()._poly(), + to.template get<2>()._poly(), e1._poly(), e2._poly())) + +FLINT_DEFINE_BINARY_EXPR_COND2(div_basecase_op, fmpz_mod_polyxx, + FMPZ_MOD_POLYXX_COND_S, FMPZ_MOD_POLYXX_COND_S, + fmpz_mod_poly_div_basecase(to._poly(), e1._poly(), e2._poly())) +FLINT_DEFINE_BINARY_EXPR_COND2(rem_basecase_op, fmpz_mod_polyxx, + FMPZ_MOD_POLYXX_COND_S, FMPZ_MOD_POLYXX_COND_S, + fmpz_mod_poly_rem_basecase(to._poly(), e1._poly(), e2._poly())) + +FLINT_DEFINE_BINARY_EXPR_COND2(inv_series_newton_op, fmpz_mod_polyxx, + FMPZ_MOD_POLYXX_COND_S, traits::fits_into_slong, + fmpz_mod_poly_inv_series_newton(to._poly(), e1._poly(), e2)) + +FLINT_DEFINE_BINARY_EXPR_COND2(gcd_op, fmpz_mod_polyxx, + FMPZ_MOD_POLYXX_COND_S, FMPZ_MOD_POLYXX_COND_S, + fmpz_mod_poly_gcd(to._poly(), e1._poly(), e2._poly())) +FLINT_DEFINE_BINARY_EXPR_COND2(gcd_euclidean_op, fmpz_mod_polyxx, + FMPZ_MOD_POLYXX_COND_S, FMPZ_MOD_POLYXX_COND_S, + fmpz_mod_poly_gcd_euclidean(to._poly(), e1._poly(), e2._poly())) + +namespace rdetail { +typedef make_ltuple::type>::type + fmpz_mod_polyxx_triple; +} // rdetail +FLINT_DEFINE_BINARY_EXPR_COND2(xgcd_op, rdetail::fmpz_mod_polyxx_triple, + FMPZ_MOD_POLYXX_COND_S, FMPZ_MOD_POLYXX_COND_S, + fmpz_mod_poly_xgcd(to.template get<0>()._poly(), to.template get<1>()._poly(), + to.template get<2>()._poly(), e1._poly(), e2._poly())) +FLINT_DEFINE_BINARY_EXPR_COND2(xgcd_euclidean_op, rdetail::fmpz_mod_polyxx_triple, + FMPZ_MOD_POLYXX_COND_S, FMPZ_MOD_POLYXX_COND_S, + fmpz_mod_poly_xgcd_euclidean(to.template get<0>()._poly(), + to.template get<1>()._poly(), + to.template get<2>()._poly(), e1._poly(), e2._poly())) + +namespace rdetail { +typedef make_ltuple::type>::type + fmpz_mod_gcd_f_rt; +} // rdetail +FLINT_DEFINE_BINARY_EXPR_COND2(gcd_f_op, rdetail::fmpz_mod_gcd_f_rt, + FMPZ_MOD_POLYXX_COND_S, FMPZ_MOD_POLYXX_COND_S, + fmpz_mod_poly_gcd_f(to.template get<0>()._fmpz(), + to.template get<1>()._poly(), e1._poly(), e2._poly())) +FLINT_DEFINE_BINARY_EXPR_COND2(gcd_euclidean_f_op, rdetail::fmpz_mod_gcd_f_rt, + FMPZ_MOD_POLYXX_COND_S, FMPZ_MOD_POLYXX_COND_S, + fmpz_mod_poly_gcd_euclidean_f(to.template get<0>()._fmpz(), + to.template get<1>()._poly(), e1._poly(), e2._poly())) + +FLINT_DEFINE_BINARY_EXPR_COND2(gcdinv_op, rdetail::fmpz_mod_polyxx_pair, + FMPZ_MOD_POLYXX_COND_S, FMPZ_MOD_POLYXX_COND_S, + fmpz_mod_poly_gcdinv( + to.template get<0>()._poly(), to.template get<1>()._poly(), + e1._poly(), e2._poly())) + +FLINT_DEFINE_BINARY_EXPR_COND2(invmod_op, fmpz_mod_polyxx, + FMPZ_MOD_POLYXX_COND_S, FMPZ_MOD_POLYXX_COND_S, + execution_check(fmpz_mod_poly_invmod(to._poly(), e1._poly(), e2._poly()), + "invmod", "fmpz_mod_polyxx")) + +FLINT_DEFINE_UNARY_EXPR_COND(derivative_op, fmpz_mod_polyxx, FMPZ_MOD_POLYXX_COND_S, + fmpz_mod_poly_derivative(to._poly(), from._poly())) + +FLINT_DEFINE_BINARY_EXPR_COND2(evaluate_op, fmpzxx, + FMPZ_MOD_POLYXX_COND_S, FMPZXX_COND_S, + fmpz_mod_poly_evaluate_fmpz(to._fmpz(), e1._poly(), e2._fmpz())) + +FLINT_DEFINE_BINARY_EXPR_COND2(compose_op, fmpz_mod_polyxx, + FMPZ_MOD_POLYXX_COND_S, FMPZ_MOD_POLYXX_COND_S, + fmpz_mod_poly_compose(to._poly(), e1._poly(), e2._poly())) +FLINT_DEFINE_BINARY_EXPR_COND2(compose_divconquer_op, fmpz_mod_polyxx, + FMPZ_MOD_POLYXX_COND_S, FMPZ_MOD_POLYXX_COND_S, + fmpz_mod_poly_compose_divconquer(to._poly(), e1._poly(), e2._poly())) +FLINT_DEFINE_BINARY_EXPR_COND2(compose_horner_op, fmpz_mod_polyxx, + FMPZ_MOD_POLYXX_COND_S, FMPZ_MOD_POLYXX_COND_S, + fmpz_mod_poly_compose_horner(to._poly(), e1._poly(), e2._poly())) + +FLINT_DEFINE_THREEARY_EXPR_COND3(compose_mod_op, fmpz_mod_polyxx, + FMPZ_MOD_POLYXX_COND_S, FMPZ_MOD_POLYXX_COND_S, FMPZ_MOD_POLYXX_COND_S, + fmpz_mod_poly_compose_mod(to._poly(), e1._poly(), e2._poly(), e3._poly())) +FLINT_DEFINE_THREEARY_EXPR_COND3(compose_mod_horner_op, fmpz_mod_polyxx, + FMPZ_MOD_POLYXX_COND_S, FMPZ_MOD_POLYXX_COND_S, FMPZ_MOD_POLYXX_COND_S, + fmpz_mod_poly_compose_mod_horner( + to._poly(), e1._poly(), e2._poly(), e3._poly())) +FLINT_DEFINE_THREEARY_EXPR_COND3(compose_mod_brent_kung_op, fmpz_mod_polyxx, + FMPZ_MOD_POLYXX_COND_S, FMPZ_MOD_POLYXX_COND_S, FMPZ_MOD_POLYXX_COND_S, + fmpz_mod_poly_compose_mod_brent_kung( + to._poly(), e1._poly(), e2._poly(), e3._poly())) +} // rules + + +/////////////////////////////////////////////////////////////////////////////// +// fmpz_mod_poly_vecxx (for radix conversion) +/////////////////////////////////////////////////////////////////////////////// +namespace detail { +struct fmpz_mod_poly_vector_data +{ + slong size; + fmpz_mod_poly_struct** array; + + template + void init(slong n, const Fmpz& f) + { + size = n; + array = new fmpz_mod_poly_struct*[n]; + for(slong i = 0;i < n;++i) + { + array[i] = new fmpz_mod_poly_struct(); + fmpz_mod_poly_init(array[i], f._fmpz()); + } + } + + template + fmpz_mod_poly_vector_data(slong n, const Fmpz& f, + typename mp::enable_if >::type* = 0) + { + init(n, f.evaluate()); + } + + ~fmpz_mod_poly_vector_data() + { + for(slong i = 0;i < size;++i) + { + fmpz_mod_poly_clear(array[i]); + delete array[i]; + } + delete[] array; + } + + fmpz_mod_poly_vector_data(const fmpz_mod_poly_vector_data& o) + : size(o.size) + { + array = new fmpz_mod_poly_struct*[size]; + for(slong i = 0;i < size;++i) + { + array[i] = new fmpz_mod_poly_struct(); + fmpz_mod_poly_init(array[i], &o.array[0]->p); + fmpz_mod_poly_set(array[i], o.array[i]); + } + } + + fmpz_mod_polyxx_ref at(slong i) + {return fmpz_mod_polyxx_ref::make(array[i]);} + fmpz_mod_polyxx_srcref at(slong i) const + {return fmpz_mod_polyxx_srcref::make(array[i]);} + + bool equals(const fmpz_mod_poly_vector_data& o) const + { + if(size != o.size) + return false; + for(slong i = 0;i < size;++i) + if(!fmpz_mod_poly_equal(array[i], o.array[i])) + return false; + return true; + } +}; + +// TODO extend this somewhat similarly to the nmod* setup +template +fmpzxx_srcref find_fmpz_mod_polyxx_mod(const T& t) +{ + // this works because there are not actually any functions operating on + // fmpz_mod_poly_vecxx + return tools::find_subexpr( + t)._mod(); +} + +struct fmpz_mod_poly_vector_traits + : wrapped_vector_traits +{ + template + static typename Expr::evaluated_t create_temporary(const Expr& e) + { + return typename Expr::evaluated_t( + e.size(), find_fmpz_mod_polyxx_mod(e)); + } +}; +} // detail + +// TODO would it make more sense to have this have its own class? +typedef vector_expression< + detail::fmpz_mod_poly_vector_traits, operations::immediate, + detail::fmpz_mod_poly_vector_data> fmpz_mod_poly_vecxx; +// TODO references + +template<> +struct enable_vector_rules : mp::false_ { }; + +namespace rules { +// TODO hack to make code look like references are implemented +template struct FMPZ_MOD_POLY_VECXX_COND_S + : mp::equal_types { }; +#define FMPZ_MOD_POLY_VECXX_COND_T FMPZ_MOD_POLY_VECXX_COND_S + +// TODO references +FLINT_DEFINE_GET(equals, bool, fmpz_mod_poly_vecxx, e1._data().equals(e2._data())) +} // rules + + +/////////////////////////////////////////////////////////////////////////////// +// radix conversion +/////////////////////////////////////////////////////////////////////////////// + +class fmpz_mod_poly_radixxx +{ +private: + fmpz_mod_poly_radix_t inner; + + // not copyable + fmpz_mod_poly_radixxx(const fmpz_mod_poly_radixxx&); + +public: + template + fmpz_mod_poly_radixxx(const Fmpz_mod_poly& r, slong deg, + typename mp::enable_if< + traits::is_fmpz_mod_polyxx >::type* = 0) + {fmpz_mod_poly_radix_init(inner, r.evaluate()._poly(), deg);} + ~fmpz_mod_poly_radixxx() {fmpz_mod_poly_radix_clear(inner);} + + fmpz_mod_poly_radix_t& _data() {return inner;} + const fmpz_mod_poly_radix_t& _data() const {return inner;} + + slong degR() const {return inner->degR;} +}; + +namespace traits { +template struct is_fmpz_mod_poly_radixxx + : mp::equal_types { }; +} // traits + +namespace vectors { +template<> +struct outsize +{ + template + static unsigned get(const Expr& e) + { + return e._data().first().degree() / e._data().second().degR() + 1; + } +}; +} + +namespace rules { +FLINT_DEFINE_BINARY_EXPR_COND2(radix_op, fmpz_mod_poly_vecxx, + FMPZ_MOD_POLYXX_COND_S, traits::is_fmpz_mod_poly_radixxx, + fmpz_mod_poly_radix(to._array(), e1._poly(), e2._data())) +} +} // flint + +#include "fmpz_mod_poly_factorxx.h" + +#endif diff --git a/external/flint-2.4.3/fmpz_poly.h b/external/flint-2.4.3/fmpz_poly.h new file mode 100644 index 0000000..462c657 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly.h @@ -0,0 +1,1175 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2006, 2007, 2008, 2009, 2010, 2013 William Hart + Copyright (C) 2009, 2011 Andy Novocin + Copyright (C) 2010 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#ifndef FMPZ_POLY_H +#define FMPZ_POLY_H + +#undef ulong +#define ulong ulongxx /* interferes with system includes */ +#include +#undef ulong + +#include +#define ulong mp_limb_t + +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "nmod_poly.h" + + +#ifdef __cplusplus + extern "C" { +#endif + +#define FMPZ_POLY_INV_NEWTON_CUTOFF 32 + +/* Type definitions *********************************************************/ + +typedef struct +{ + fmpz * coeffs; + slong alloc; + slong length; +} fmpz_poly_struct; + +typedef fmpz_poly_struct fmpz_poly_t[1]; + +typedef struct +{ + fmpz ** powers; + slong len; +} fmpz_poly_powers_precomp_struct; + +typedef fmpz_poly_powers_precomp_struct fmpz_poly_powers_precomp_t[1]; + +typedef struct { + fmpz c; + fmpz_poly_struct *p; + slong *exp; + slong num; + slong alloc; +} fmpz_poly_factor_struct; + +typedef fmpz_poly_factor_struct fmpz_poly_factor_t[1]; + +/* Memory management ********************************************************/ + +void fmpz_poly_init(fmpz_poly_t poly); + +void fmpz_poly_init2(fmpz_poly_t poly, slong alloc); + +void fmpz_poly_realloc(fmpz_poly_t poly, slong alloc); + +void fmpz_poly_fit_length(fmpz_poly_t poly, slong len); + +void fmpz_poly_clear(fmpz_poly_t poly); + +void _fmpz_poly_normalise(fmpz_poly_t poly); + +static __inline__ +void _fmpz_poly_set_length(fmpz_poly_t poly, slong newlen) +{ + if (poly->length > newlen) + { + slong i; + for (i = newlen; i < poly->length; i++) + _fmpz_demote(poly->coeffs + i); + } + poly->length = newlen; +} + +/* Polynomial parameters ***************************************************/ + +static __inline__ +slong fmpz_poly_length(const fmpz_poly_t poly) +{ + return poly->length; +} + +static __inline__ +slong fmpz_poly_degree(const fmpz_poly_t poly) +{ + return poly->length - 1; +} + +/* Assignment and basic manipulation ***************************************/ + +void fmpz_poly_set(fmpz_poly_t poly1, const fmpz_poly_t poly2); + +void fmpz_poly_set_ui(fmpz_poly_t poly, ulong c); + +void fmpz_poly_set_si(fmpz_poly_t poly, slong c); + +void fmpz_poly_set_fmpz(fmpz_poly_t poly, const fmpz_t c); + +void fmpz_poly_set_mpz(fmpz_poly_t poly, const mpz_t c); + +int _fmpz_poly_set_str(fmpz * poly, const char * str); + +int fmpz_poly_set_str(fmpz_poly_t poly, const char * str); + +char * _fmpz_poly_get_str(const fmpz * poly, slong len); + +char * fmpz_poly_get_str(const fmpz_poly_t poly); + +char * _fmpz_poly_get_str_pretty(const fmpz * poly, slong len, const char * x); + +char * fmpz_poly_get_str_pretty(const fmpz_poly_t poly, const char * x); + +static __inline__ +void fmpz_poly_zero(fmpz_poly_t poly) +{ + _fmpz_poly_set_length(poly, 0); +} + +static __inline__ +void fmpz_poly_one(fmpz_poly_t poly) +{ + fmpz_poly_set_ui(poly, UWORD(1)); +} + +void fmpz_poly_zero_coeffs(fmpz_poly_t poly, slong i, slong j); + +void fmpz_poly_swap(fmpz_poly_t poly1, fmpz_poly_t poly2); + +void _fmpz_poly_reverse(fmpz * res, const fmpz * poly, slong len, slong n); + +void fmpz_poly_reverse(fmpz_poly_t res, const fmpz_poly_t poly, slong n); + +static __inline__ +void fmpz_poly_truncate(fmpz_poly_t poly, slong newlen) +{ + if (poly->length > newlen) + { + slong i; + for (i = newlen; i < poly->length; i++) + _fmpz_demote(poly->coeffs + i); + poly->length = newlen; + _fmpz_poly_normalise(poly); + } +} + +/* Randomisation ***********************************************************/ + +void fmpz_poly_randtest(fmpz_poly_t f, flint_rand_t state, + slong len, mp_bitcnt_t bits); + +void fmpz_poly_randtest_unsigned(fmpz_poly_t f, flint_rand_t state, + slong len, mp_bitcnt_t bits); + +void fmpz_poly_randtest_not_zero(fmpz_poly_t f, flint_rand_t state, + slong len, mp_bitcnt_t bits); + +/* Getting and setting coefficients ****************************************/ + +slong fmpz_poly_get_coeff_si(const fmpz_poly_t poly, slong n); + +void fmpz_poly_set_coeff_si(fmpz_poly_t poly, slong n, slong x); + +ulong fmpz_poly_get_coeff_ui(const fmpz_poly_t poly, slong n); + +void fmpz_poly_set_coeff_ui(fmpz_poly_t poly, slong n, ulong x); + +void fmpz_poly_set_coeff_fmpz(fmpz_poly_t poly, slong n, const fmpz_t x); + +void fmpz_poly_get_coeff_fmpz(fmpz_t x, const fmpz_poly_t poly, slong n); + +#define fmpz_poly_get_coeff_ptr(poly, n) \ + ((n) < (poly)->length ? (poly)->coeffs + (n) : NULL) + +#define fmpz_poly_lead(poly) \ + ((poly)->length ? (poly)->coeffs + (poly)->length - 1 : NULL) + +/* Comparison **************************************************************/ + +int fmpz_poly_equal(const fmpz_poly_t poly1, const fmpz_poly_t poly2); + +#define fmpz_poly_is_zero(poly) \ + ((poly)->length == 0) + +static __inline__ +int _fmpz_poly_is_one(const fmpz *poly, slong len) +{ + return (len > 0 && fmpz_is_one(poly) + && _fmpz_vec_is_zero(poly + 1, len - 1)); +} + +static __inline__ +int fmpz_poly_is_one(const fmpz_poly_t op) +{ + return (op->length) == 1 && (*(op->coeffs) == WORD(1)); +} + +static __inline__ +int fmpz_poly_is_unit(const fmpz_poly_t op) +{ + return (op->length == 1) && (*(op->coeffs) == WORD(1) || *(op->coeffs) == WORD(-1)); +} + +static __inline__ +int fmpz_poly_equal_fmpz(const fmpz_poly_t poly, const fmpz_t c) +{ + return ((poly->length == 0) && fmpz_is_zero(c)) || + ((poly->length == 1) && fmpz_equal(poly->coeffs, c)); +} + +/* Addition and subtraction ************************************************/ + +void _fmpz_poly_add(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2); + +void fmpz_poly_add(fmpz_poly_t res, const fmpz_poly_t poly1, + const fmpz_poly_t poly2); + +void _fmpz_poly_sub(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2); + +void fmpz_poly_sub(fmpz_poly_t res, const fmpz_poly_t poly1, + const fmpz_poly_t poly2); + +void fmpz_poly_neg(fmpz_poly_t res, const fmpz_poly_t poly); + +/* Scalar multiplication and division **************************************/ + +void fmpz_poly_scalar_mul_ui(fmpz_poly_t poly1, + const fmpz_poly_t poly2, ulong x); + +void fmpz_poly_scalar_mul_si(fmpz_poly_t poly1, + const fmpz_poly_t poly2, slong x); + +void fmpz_poly_scalar_mul_fmpz(fmpz_poly_t poly1, + const fmpz_poly_t poly2, const fmpz_t x); + +void fmpz_poly_scalar_addmul_fmpz(fmpz_poly_t poly1, + const fmpz_poly_t poly2, const fmpz_t x); + +void fmpz_poly_scalar_submul_fmpz(fmpz_poly_t poly1, + const fmpz_poly_t poly2, const fmpz_t x); + +void fmpz_poly_scalar_fdiv_ui(fmpz_poly_t poly1, + const fmpz_poly_t poly2, ulong x); + +void fmpz_poly_scalar_fdiv_si(fmpz_poly_t poly1, + const fmpz_poly_t poly2, slong x); + +void fmpz_poly_scalar_fdiv_fmpz(fmpz_poly_t poly1, + const fmpz_poly_t poly2, const fmpz_t x); + +void fmpz_poly_scalar_tdiv_ui(fmpz_poly_t poly1, + const fmpz_poly_t poly2, ulong x); + +void fmpz_poly_scalar_tdiv_si(fmpz_poly_t poly1, + const fmpz_poly_t poly2, slong x); + +void fmpz_poly_scalar_tdiv_fmpz(fmpz_poly_t poly1, + const fmpz_poly_t poly2, const fmpz_t x); + +void fmpz_poly_scalar_divexact_ui(fmpz_poly_t poly1, + const fmpz_poly_t poly2, ulong x); + +void fmpz_poly_scalar_divexact_si(fmpz_poly_t poly1, + const fmpz_poly_t poly2, slong x); + +void fmpz_poly_scalar_divexact_fmpz(fmpz_poly_t poly1, + const fmpz_poly_t poly2, const fmpz_t x); + +void fmpz_poly_scalar_fdiv_2exp(fmpz_poly_t poly1, const fmpz_poly_t poly2, + ulong exp); + +void fmpz_poly_scalar_tdiv_2exp(fmpz_poly_t poly1, const fmpz_poly_t poly2, + ulong exp); + +void fmpz_poly_scalar_mul_2exp(fmpz_poly_t poly1, const fmpz_poly_t poly2, + ulong exp); + +static __inline__ +void fmpz_poly_scalar_mod_fmpz(fmpz_poly_t poly1, + const fmpz_poly_t poly2, const fmpz_t x) +{ + if (poly2->length == 0) + { + fmpz_poly_zero(poly1); + } + else + { + fmpz_poly_fit_length(poly1, poly2->length); + _fmpz_vec_scalar_mod_fmpz(poly1->coeffs, poly2->coeffs, poly2->length, x); + _fmpz_poly_set_length(poly1, poly2->length); + _fmpz_poly_normalise(poly1); + } +} + +static __inline__ +void fmpz_poly_scalar_smod_fmpz(fmpz_poly_t poly1, + const fmpz_poly_t poly2, const fmpz_t x) +{ + if (poly2->length == 0) + { + fmpz_poly_zero(poly1); + } + else + { + fmpz_poly_fit_length(poly1, poly2->length); + _fmpz_vec_scalar_smod_fmpz(poly1->coeffs, poly2->coeffs, poly2->length, x); + _fmpz_poly_set_length(poly1, poly2->length); + _fmpz_poly_normalise(poly1); + + } +} + +/* Bit packing *************************************************************/ + +void _fmpz_poly_bit_pack(mp_ptr arr, const fmpz * poly, + slong len, mp_bitcnt_t bit_size, int negate); + +int _fmpz_poly_bit_unpack(fmpz * poly, slong len, + mp_srcptr arr, mp_bitcnt_t bit_size, int negate); + +void _fmpz_poly_bit_unpack_unsigned(fmpz * poly, slong len, + mp_srcptr arr, mp_bitcnt_t bit_size); + +void fmpz_poly_bit_pack(fmpz_t f, const fmpz_poly_t poly, + mp_bitcnt_t bit_size); + +void fmpz_poly_bit_unpack(fmpz_poly_t poly, const fmpz_t f, + mp_bitcnt_t bit_size); + +void fmpz_poly_bit_unpack_unsigned(fmpz_poly_t poly, const fmpz_t f, + mp_bitcnt_t bit_size); + + +/* Multiplication **********************************************************/ + +void _fmpz_poly_mul_classical(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2); + +void fmpz_poly_mul_classical(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2); + +void _fmpz_poly_mullow_classical(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2, slong n); + +void fmpz_poly_mullow_classical(fmpz_poly_t res, const fmpz_poly_t poly1, + const fmpz_poly_t poly2, slong n); + +void _fmpz_poly_mulhigh_classical(fmpz * res, const fmpz * poly1, + slong len1, const fmpz * poly2, slong len2, slong start); + +void fmpz_poly_mulhigh_classical(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2, slong start); + +void _fmpz_poly_mulmid_classical(fmpz * res, const fmpz * poly1, + slong len1, const fmpz * poly2, slong len2); + +void fmpz_poly_mulmid_classical(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2); + +void fmpz_poly_mul_karatsuba(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2); + +void _fmpz_poly_mul_karatsuba(fmpz * res, const fmpz * poly1, + slong len1, const fmpz * poly2, slong len2); + +void _fmpz_poly_mullow_karatsuba_n(fmpz * res, const fmpz * poly1, + const fmpz * poly2, slong n); + +void fmpz_poly_mullow_karatsuba_n(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2, slong n); + +void _fmpz_poly_mulhigh_karatsuba_n(fmpz * res, const fmpz * poly1, + const fmpz * poly2, slong len); + +void fmpz_poly_mulhigh_karatsuba_n(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2, slong length); + +void _fmpz_poly_mul_KS(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2); + +void fmpz_poly_mul_KS(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2); + +void _fmpz_poly_mullow_KS(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2, slong n); + +void fmpz_poly_mullow_KS(fmpz_poly_t res, const fmpz_poly_t poly1, + const fmpz_poly_t poly2, slong n); + +void _fmpz_poly_mul_SS(fmpz * output, const fmpz * input1, slong length1, + const fmpz * input2, slong length2); + +void fmpz_poly_mul_SS(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2); + +void _fmpz_poly_mullow_SS(fmpz * output, const fmpz * input1, slong length1, + const fmpz * input2, slong length2, slong n); + +void fmpz_poly_mullow_SS(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2, slong n); + +void _fmpz_poly_mul(fmpz * res, const fmpz * poly1, + slong len1, const fmpz * poly2, slong len2); + +void fmpz_poly_mul(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2); + +void _fmpz_poly_mullow(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2, slong n); + +void fmpz_poly_mullow(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2, slong n); + +void fmpz_poly_mulhigh_n(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2, slong n); + +/* Squaring ******************************************************************/ + +void _fmpz_poly_sqr_KS(fmpz * rop, const fmpz * op, slong len); + +void fmpz_poly_sqr_KS(fmpz_poly_t rop, const fmpz_poly_t op); + +void fmpz_poly_sqr_karatsuba(fmpz_poly_t rop, const fmpz_poly_t op); + +void _fmpz_poly_sqr_karatsuba(fmpz * rop, const fmpz * op, slong len); + +void _fmpz_poly_sqr_classical(fmpz * rop, const fmpz * op, slong len); + +void fmpz_poly_sqr_classical(fmpz_poly_t rop, const fmpz_poly_t op); + +void _fmpz_poly_sqr(fmpz * rop, const fmpz * op, slong len); + +void fmpz_poly_sqr(fmpz_poly_t rop, const fmpz_poly_t op); + +void _fmpz_poly_sqrlow_KS(fmpz * res, const fmpz * poly, slong len, slong n); + +void fmpz_poly_sqrlow_KS(fmpz_poly_t res, const fmpz_poly_t poly, slong n); + +void _fmpz_poly_sqrlow_karatsuba_n(fmpz * res, const fmpz * poly, slong n); + +void fmpz_poly_sqrlow_karatsuba_n(fmpz_poly_t res, const fmpz_poly_t poly, slong n); + +void _fmpz_poly_sqrlow_classical(fmpz * res, const fmpz * poly, slong len, slong n); + +void fmpz_poly_sqrlow_classical(fmpz_poly_t res, const fmpz_poly_t poly, slong n); + +void _fmpz_poly_sqrlow(fmpz * res, const fmpz * poly, slong len, slong n); + +void fmpz_poly_sqrlow(fmpz_poly_t res, const fmpz_poly_t poly, slong n); + +/* Powering ****************************************************************/ + +void _fmpz_poly_pow_multinomial(fmpz * res, const fmpz * poly, slong len, ulong e); + +void fmpz_poly_pow_multinomial(fmpz_poly_t res, const fmpz_poly_t poly, ulong e); + +void _fmpz_poly_pow_binomial(fmpz * res, const fmpz * poly, ulong e); + +void fmpz_poly_pow_binomial(fmpz_poly_t res, const fmpz_poly_t poly, ulong e); + +void _fmpz_poly_pow_binexp(fmpz * res, const fmpz * poly, slong len, ulong e); + +void fmpz_poly_pow_binexp(fmpz_poly_t res, const fmpz_poly_t poly, ulong e); + +void _fmpz_poly_pow_addchains(fmpz * res, const fmpz * poly, slong len, const int * a, int n); + +void fmpz_poly_pow_addchains(fmpz_poly_t res, const fmpz_poly_t poly, ulong e); + +void _fmpz_poly_pow_small(fmpz * res, const fmpz * poly, slong len, ulong e); + +void _fmpz_poly_pow(fmpz * res, const fmpz * poly, slong len, ulong e); + +void fmpz_poly_pow(fmpz_poly_t res, const fmpz_poly_t poly, ulong e); + +void _fmpz_poly_pow_trunc(fmpz * res, const fmpz * poly, ulong e, slong n); + +void +fmpz_poly_pow_trunc(fmpz_poly_t res, const fmpz_poly_t poly, ulong e, slong n); + +/* Shifting ****************************************************************/ + +void _fmpz_poly_shift_left(fmpz * res, const fmpz * poly, slong len, slong n); + +void _fmpz_poly_shift_right(fmpz * res, const fmpz * poly, slong len, slong n); + +void fmpz_poly_shift_left(fmpz_poly_t res, const fmpz_poly_t poly, slong n); + +void fmpz_poly_shift_right(fmpz_poly_t res, const fmpz_poly_t poly, slong n); + +/* Norms *******************************************************************/ + +void _fmpz_poly_2norm(fmpz_t res, const fmpz * poly, slong len); + +void fmpz_poly_2norm(fmpz_t res, const fmpz_poly_t poly); + +mp_bitcnt_t _fmpz_poly_2norm_normalised_bits(const fmpz * poly, slong len); + +static __inline__ +ulong fmpz_poly_max_limbs(const fmpz_poly_t poly) +{ + return _fmpz_vec_max_limbs(poly->coeffs, poly->length); +} + +static __inline__ +slong fmpz_poly_max_bits(const fmpz_poly_t poly) +{ + return _fmpz_vec_max_bits(poly->coeffs, poly->length); +} + +static __inline__ void +fmpz_poly_height(fmpz_t res, const fmpz_poly_t poly) +{ + _fmpz_vec_height(res, poly->coeffs, poly->length); +} + +/* Greatest common divisor *************************************************/ + +void _fmpz_poly_gcd_subresultant(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2); + +void fmpz_poly_gcd_subresultant(fmpz_poly_t res, const fmpz_poly_t poly1, + const fmpz_poly_t poly2); + +int _fmpz_poly_gcd_heuristic(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2); + +int fmpz_poly_gcd_heuristic(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2); + +void _fmpz_poly_gcd_modular(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2); + +void fmpz_poly_gcd_modular(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2); + +void _fmpz_poly_gcd(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2); + +void fmpz_poly_gcd(fmpz_poly_t res, const fmpz_poly_t poly1, + const fmpz_poly_t poly2); + +void _fmpz_poly_lcm(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2); + +void fmpz_poly_lcm(fmpz_poly_t res, const fmpz_poly_t poly1, + const fmpz_poly_t poly2); + +void _fmpz_poly_resultant(fmpz_t res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2); + +void fmpz_poly_resultant(fmpz_t res, const fmpz_poly_t poly1, + const fmpz_poly_t poly2); + +void _fmpz_poly_xgcd_modular(fmpz_t r, fmpz * s, fmpz * t, + const fmpz * poly1, slong len1, const fmpz * poly2, slong len2); + +void fmpz_poly_xgcd_modular(fmpz_t r, fmpz_poly_t s, fmpz_poly_t t, + const fmpz_poly_t poly1, const fmpz_poly_t poly2); + +static __inline__ +void _fmpz_poly_xgcd(fmpz_t r, fmpz * s, fmpz * t, + const fmpz * poly1, slong len1, const fmpz * poly2, slong len2) +{ + _fmpz_poly_xgcd_modular(r, s, t, poly1, len1, poly2, len2); +} + +static __inline__ +void fmpz_poly_xgcd(fmpz_t r, fmpz_poly_t s, fmpz_poly_t t, + const fmpz_poly_t poly1, const fmpz_poly_t poly2) +{ + fmpz_poly_xgcd_modular(r, s, t, poly1, poly2); +} + +/* Gaussian content ********************************************************/ + +void _fmpz_poly_content(fmpz_t res, const fmpz * poly, slong len); + +void fmpz_poly_content(fmpz_t res, const fmpz_poly_t poly); + +void _fmpz_poly_primitive_part(fmpz * res, const fmpz * poly, slong len); + +void fmpz_poly_primitive_part(fmpz_poly_t res, const fmpz_poly_t poly); + +/* Square-free *************************************************************/ + +int _fmpz_poly_is_squarefree(const fmpz * poly, slong len); + +int fmpz_poly_is_squarefree(const fmpz_poly_t poly); + +/* Euclidean division ******************************************************/ + +void _fmpz_poly_divrem_basecase(fmpz * Q, fmpz * R, const fmpz * A, + slong lenA, const fmpz * B, slong lenB); + +void fmpz_poly_divrem_basecase(fmpz_poly_t Q, fmpz_poly_t R, + const fmpz_poly_t A, const fmpz_poly_t B); + +void _fmpz_poly_divrem_divconquer_recursive(fmpz * Q, fmpz * BQ, fmpz * W, + const fmpz * A, const fmpz * B, slong lenB); + +void _fmpz_poly_divrem_divconquer(fmpz * Q, fmpz * R, + const fmpz * A, slong lenA, const fmpz * B, slong lenB); + +void fmpz_poly_divrem_divconquer(fmpz_poly_t Q, fmpz_poly_t R, + const fmpz_poly_t A, const fmpz_poly_t B); + +void _fmpz_poly_divrem(fmpz * Q, fmpz * R, const fmpz * A, slong lenA, + const fmpz * B, slong lenB); + +void fmpz_poly_divrem(fmpz_poly_t Q, fmpz_poly_t R, const fmpz_poly_t A, + const fmpz_poly_t B); + +void _fmpz_poly_div_basecase(fmpz * Q, fmpz * R, const fmpz * A, slong lenA, + const fmpz * B, slong lenB); + +void fmpz_poly_div_basecase(fmpz_poly_t Q, + const fmpz_poly_t A, const fmpz_poly_t B); + +void _fmpz_poly_divremlow_divconquer_recursive(fmpz * Q, fmpz * QB, + const fmpz * A, const fmpz * B, slong lenB); + +void _fmpz_poly_div_divconquer_recursive(fmpz * Q, fmpz * temp, + const fmpz * A, const fmpz * B, slong lenB); + +void _fmpz_poly_div_divconquer(fmpz * Q, const fmpz * A, slong lenA, + const fmpz * B, slong lenB); + +void fmpz_poly_div_divconquer(fmpz_poly_t Q, + const fmpz_poly_t A, const fmpz_poly_t B); + +void _fmpz_poly_div(fmpz * Q, const fmpz * A, slong lenA, + const fmpz * B, slong lenB); + +void fmpz_poly_div(fmpz_poly_t Q, const fmpz_poly_t A, const fmpz_poly_t B); + +void _fmpz_poly_preinvert(fmpz * B_inv, const fmpz * B, slong n); + +void fmpz_poly_preinvert(fmpz_poly_t B_inv, const fmpz_poly_t B); + +void _fmpz_poly_div_preinv(fmpz * Q, const fmpz * A, slong len1, + const fmpz * B, const fmpz * B_inv, slong len2); + +void fmpz_poly_div_preinv(fmpz_poly_t Q, const fmpz_poly_t A, + const fmpz_poly_t B, const fmpz_poly_t B_inv); + +void _fmpz_poly_divrem_preinv(fmpz * Q, fmpz * A, slong len1, + const fmpz * B, const fmpz * B_inv, slong len2); + +void fmpz_poly_divrem_preinv(fmpz_poly_t Q, fmpz_poly_t R, + const fmpz_poly_t A, const fmpz_poly_t B, const fmpz_poly_t B_inv); + +fmpz ** _fmpz_poly_powers_precompute(const fmpz * B, slong len); + +void fmpz_poly_powers_precompute(fmpz_poly_powers_precomp_t pinv, + fmpz_poly_t poly); + +void _fmpz_poly_powers_clear(fmpz ** powers, slong len); + +void fmpz_poly_powers_clear(fmpz_poly_powers_precomp_t pinv); + +void _fmpz_poly_rem_powers_precomp(fmpz * A, slong m, + const fmpz * B, slong n, fmpz ** const powers); + +void fmpz_poly_rem_powers_precomp(fmpz_poly_t R, + const fmpz_poly_t A, const fmpz_poly_t B, + const fmpz_poly_powers_precomp_t B_inv); + +void _fmpz_poly_rem_basecase(fmpz * Q, const fmpz * A, slong lenA, + const fmpz * B, slong lenB); + +void fmpz_poly_rem_basecase(fmpz_poly_t R, + const fmpz_poly_t A, const fmpz_poly_t B); + +void _fmpz_poly_rem(fmpz * R, const fmpz * A, slong lenA, + const fmpz * B, slong lenB); + +void fmpz_poly_rem(fmpz_poly_t R, const fmpz_poly_t A, const fmpz_poly_t B); + +void +fmpz_poly_div_root(fmpz_poly_t Q, const fmpz_poly_t A, const fmpz_t c); + +void +_fmpz_poly_div_root(fmpz * Q, const fmpz * A, slong len, const fmpz_t c); + +/* Power series division ***************************************************/ + +void _fmpz_poly_inv_series_newton(fmpz * Qinv, const fmpz * Q, slong n); + +void fmpz_poly_inv_series_newton(fmpz_poly_t Qinv, const fmpz_poly_t Q, slong n); + +static __inline__ void +_fmpz_poly_inv_series(fmpz * Qinv, const fmpz * Q, slong n) +{ + _fmpz_poly_inv_series_newton(Qinv, Q, n); +} + +static __inline__ void +fmpz_poly_inv_series(fmpz_poly_t Qinv, const fmpz_poly_t Q, slong n) +{ + fmpz_poly_inv_series_newton(Qinv, Q, n); +} + +void _fmpz_poly_div_series(fmpz * Q, const fmpz * A, const fmpz * B, slong n); + +void fmpz_poly_div_series(fmpz_poly_t Q, const fmpz_poly_t A, + const fmpz_poly_t B, slong n); + +/* Divisibility testing ***************************************************/ + +int _fmpz_poly_divides(fmpz * q, const fmpz * a, + slong len1, const fmpz * b, slong len2); + +int fmpz_poly_divides(fmpz_poly_t q, const fmpz_poly_t a, const fmpz_poly_t b); + + +/* Pseudo division *********************************************************/ + +void _fmpz_poly_pseudo_divrem_basecase(fmpz * Q, fmpz * R, + ulong * d, const fmpz * A, slong A_len, + const fmpz * B, slong B_len, const fmpz_preinvn_t inv); + +void fmpz_poly_pseudo_divrem_basecase(fmpz_poly_t Q, fmpz_poly_t R, + ulong * d, const fmpz_poly_t A, const fmpz_poly_t B); + +void _fmpz_poly_pseudo_divrem_divconquer(fmpz * Q, fmpz * R, + ulong * d, const fmpz * A, slong lenA, + const fmpz * B, slong lenB, const fmpz_preinvn_t inv); + +void fmpz_poly_pseudo_divrem_divconquer(fmpz_poly_t Q, fmpz_poly_t R, + ulong * d, const fmpz_poly_t A, const fmpz_poly_t B); + +void _fmpz_poly_pseudo_divrem_cohen(fmpz * Q, fmpz * R, const fmpz * A, + slong lenA, const fmpz * B, slong lenB); + +void fmpz_poly_pseudo_divrem_cohen(fmpz_poly_t Q, fmpz_poly_t R, + const fmpz_poly_t A, const fmpz_poly_t B); + +void _fmpz_poly_pseudo_rem_cohen(fmpz * R, const fmpz * A, slong lenA, + const fmpz * B, slong lenB); + +void fmpz_poly_pseudo_rem_cohen(fmpz_poly_t R, const fmpz_poly_t A, + const fmpz_poly_t B); + +static __inline__ +void _fmpz_poly_pseudo_divrem(fmpz * Q, fmpz * R, + ulong * d, const fmpz * A, slong A_len, + const fmpz * B, slong B_len, const fmpz_preinvn_t inv) +{ + _fmpz_poly_pseudo_divrem_divconquer(Q, R, d, A, A_len, B, B_len, inv); +} + +static __inline__ +void fmpz_poly_pseudo_divrem(fmpz_poly_t Q, fmpz_poly_t R, + ulong * d, const fmpz_poly_t A, const fmpz_poly_t B) +{ + fmpz_poly_pseudo_divrem_divconquer(Q, R, d, A, B); +} + +void _fmpz_poly_pseudo_div(fmpz * Q, ulong * d, const fmpz * A, slong lenA, + const fmpz * B, slong lenB, const fmpz_preinvn_t inv); + +void fmpz_poly_pseudo_div(fmpz_poly_t Q, ulong * d, const fmpz_poly_t A, + const fmpz_poly_t B); + +void _fmpz_poly_pseudo_rem(fmpz * R, ulong * d, const fmpz * A, slong lenA, + const fmpz * B, slong lenB, const fmpz_preinvn_t inv); + +void fmpz_poly_pseudo_rem(fmpz_poly_t R, ulong * d, const fmpz_poly_t A, + const fmpz_poly_t B); + +/* Derivative **************************************************************/ + +void _fmpz_poly_derivative(fmpz * rpoly, const fmpz * poly, slong len); + +void fmpz_poly_derivative(fmpz_poly_t res, const fmpz_poly_t poly); + +/* Evaluation **************************************************************/ + +void +_fmpz_poly_evaluate_divconquer_fmpz(fmpz_t res, const fmpz * poly, slong len, + const fmpz_t a); + +void fmpz_poly_evaluate_divconquer_fmpz(fmpz_t res, const fmpz_poly_t poly, + const fmpz_t a); + +void _fmpz_poly_evaluate_horner_fmpz(fmpz_t res, const fmpz * f, slong len, + const fmpz_t a); + +void fmpz_poly_evaluate_horner_fmpz(fmpz_t res, const fmpz_poly_t f, + const fmpz_t a); + +void _fmpz_poly_evaluate_fmpz(fmpz_t res, const fmpz * f, slong len, const fmpz_t a); + +void fmpz_poly_evaluate_fmpz(fmpz_t res, const fmpz_poly_t f, const fmpz_t a); + +void _fmpz_poly_evaluate_horner_mpq(fmpz_t rnum, fmpz_t rden, + const fmpz * f, slong len, + const fmpz_t anum, const fmpz_t aden); + +void fmpz_poly_evaluate_horner_mpq(mpq_t res, const fmpz_poly_t f, + const mpq_t a); + +void _fmpz_poly_evaluate_mpq(fmpz_t rnum, fmpz_t rden, + const fmpz * f, slong len, + const fmpz_t anum, const fmpz_t aden); + +void fmpz_poly_evaluate_mpq(mpq_t res, const fmpz_poly_t f, const mpq_t a); + +mp_limb_t _fmpz_poly_evaluate_mod(const fmpz * poly, slong len, mp_limb_t a, + mp_limb_t n, mp_limb_t ninv); + +mp_limb_t fmpz_poly_evaluate_mod(const fmpz_poly_t poly, mp_limb_t a, + mp_limb_t n); + +void +_fmpz_poly_evaluate_divconquer(fmpz * res, const fmpz * poly, slong len, + const fmpz_t x); + +void +fmpz_poly_evaluate_divconquer(fmpz_t res, + const fmpz_poly_t poly, const fmpz_t x); + +/* Composition *************************************************************/ + +void _fmpz_poly_compose_horner(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2); + +void fmpz_poly_compose_horner(fmpz_poly_t res, const fmpz_poly_t poly1, + const fmpz_poly_t poly2); + +void _fmpz_poly_compose_divconquer(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2); + +void fmpz_poly_compose_divconquer(fmpz_poly_t res, const fmpz_poly_t poly1, + const fmpz_poly_t poly2); + +void _fmpz_poly_compose(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2); + +void fmpz_poly_compose(fmpz_poly_t res, const fmpz_poly_t poly1, + const fmpz_poly_t poly2); + +/* Taylor shift ************************************************************/ + +void _fmpz_poly_taylor_shift_horner(fmpz * poly, const fmpz_t c, slong n); + +void fmpz_poly_taylor_shift_horner(fmpz_poly_t g, const fmpz_poly_t f, + const fmpz_t c); + +void _fmpz_poly_taylor_shift_divconquer(fmpz * poly, const fmpz_t c, slong n); + +void fmpz_poly_taylor_shift_divconquer(fmpz_poly_t g, const fmpz_poly_t f, + const fmpz_t c); + +void _fmpz_poly_taylor_shift(fmpz * poly, const fmpz_t c, slong n); + +void fmpz_poly_taylor_shift(fmpz_poly_t g, const fmpz_poly_t f, const fmpz_t c); + +/* Power series composition and compositional inverse **********************/ + +void +_fmpz_poly_compose_series_brent_kung(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2, slong n); + +void +fmpz_poly_compose_series_brent_kung(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2, slong n); + +void +_fmpz_poly_compose_series_horner(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2, slong n); + +void +fmpz_poly_compose_series_horner(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2, slong n); + +void +_fmpz_poly_compose_series(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2, slong n); + +void +fmpz_poly_compose_series(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2, slong n); + +void +_fmpz_poly_revert_series_lagrange(fmpz * Qinv, const fmpz * Q, slong n); + +void +fmpz_poly_revert_series_lagrange(fmpz_poly_t Qinv, const fmpz_poly_t Q, slong n); + +void +_fmpz_poly_revert_series_lagrange_fast(fmpz * Qinv, const fmpz * Q, slong n); + +void +fmpz_poly_revert_series_lagrange_fast(fmpz_poly_t Qinv, + const fmpz_poly_t Q, slong n); + +void +_fmpz_poly_revert_series_newton(fmpz * Qinv, const fmpz * Q, slong n); + +void +fmpz_poly_revert_series_newton(fmpz_poly_t Qinv, const fmpz_poly_t Q, slong n); + +void +_fmpz_poly_revert_series(fmpz * Qinv, const fmpz * Q, slong n); + +void +fmpz_poly_revert_series(fmpz_poly_t Qinv, const fmpz_poly_t Q, slong n); + +/* Square root *************************************************************/ + +int _fmpz_poly_sqrt_classical(fmpz * res, const fmpz * poly, slong len); + +int fmpz_poly_sqrt_classical(fmpz_poly_t b, const fmpz_poly_t a); + +int _fmpz_poly_sqrt(fmpz * res, const fmpz * poly, slong len); + +int fmpz_poly_sqrt(fmpz_poly_t b, const fmpz_poly_t a); + + +/* Signature ***************************************************************/ + +void _fmpz_poly_signature(slong * r1, slong * r2, const fmpz * poly, slong len); + +void fmpz_poly_signature(slong * r1, slong * r2, const fmpz_poly_t poly); + +/* Input and output ********************************************************/ + +int fmpz_poly_fprint(FILE * file, const fmpz_poly_t poly); + +int _fmpz_poly_fprint_pretty(FILE * file, + const fmpz * poly, slong len, const char * x); + +int fmpz_poly_fprint_pretty(FILE * file, + const fmpz_poly_t poly, const char * x); + +static __inline__ +int fmpz_poly_print(const fmpz_poly_t poly) +{ + return fmpz_poly_fprint(stdout, poly); +} + +static __inline__ +int fmpz_poly_print_pretty(const fmpz_poly_t poly, const char * x) +{ + return fmpz_poly_fprint_pretty(stdout, poly, x); +} + +int fmpz_poly_fread(FILE * file, fmpz_poly_t poly); + +int fmpz_poly_fread_pretty(FILE *file, fmpz_poly_t poly, char **x); + +static __inline__ +int fmpz_poly_read(fmpz_poly_t poly) +{ + return fmpz_poly_fread(stdin, poly); +} + +static __inline__ +int fmpz_poly_read_pretty(fmpz_poly_t poly, char **x) +{ + return fmpz_poly_fread_pretty(stdin, poly, x); +} + +static __inline__ +void fmpz_poly_debug(const fmpz_poly_t poly) +{ + flint_printf("(alloc = %wd, length = %wd, vec = ", poly->alloc, poly->length); + if (poly->coeffs) + { + flint_printf("{"); + _fmpz_vec_print(poly->coeffs, poly->alloc); + flint_printf("}"); + } + else + { + flint_printf("NULL"); + } + flint_printf(")"); + fflush(stdout); +} + +/* CRT ********************************************************************/ + +void fmpz_poly_get_nmod_poly(nmod_poly_t res, const fmpz_poly_t poly); + +void fmpz_poly_set_nmod_poly(fmpz_poly_t res, const nmod_poly_t poly); + +void fmpz_poly_set_nmod_poly_unsigned(fmpz_poly_t res, const nmod_poly_t poly); + +void +_fmpz_poly_CRT_ui_precomp(fmpz * res, const fmpz * poly1, slong len1, + const fmpz_t m1, mp_srcptr poly2, slong len2, mp_limb_t m2, + mp_limb_t m2inv, fmpz_t m1m2, mp_limb_t c, int sign); + +void _fmpz_poly_CRT_ui(fmpz * res, const fmpz * poly1, slong len1, + const fmpz_t m1, mp_srcptr poly2, slong len2, mp_limb_t m2, + mp_limb_t m2inv, int sign); + +void fmpz_poly_CRT_ui(fmpz_poly_t res, const fmpz_poly_t poly1, + const fmpz_t m1, const nmod_poly_t poly2, + int sign); + + +/* Products *****************************************************************/ + +void _fmpz_poly_product_roots_fmpz_vec(fmpz * poly, + const fmpz * xs, slong n); + +void fmpz_poly_product_roots_fmpz_vec(fmpz_poly_t poly, + const fmpz * xs, slong n); + +/* Newton basis *************************************************************/ + +void _fmpz_poly_monomial_to_newton(fmpz * poly, const fmpz * roots, slong n); + +void _fmpz_poly_newton_to_monomial(fmpz * poly, const fmpz * roots, slong n); + + +/* Multipoint evaluation and interpolation *********************************/ + +void +fmpz_poly_evaluate_fmpz_vec(fmpz * res, const fmpz_poly_t f, + const fmpz * a, slong n); + +void +fmpz_poly_interpolate_fmpz_vec(fmpz_poly_t poly, + const fmpz * xs, const fmpz * ys, slong n); + +/* Hensel lifting ************************************************************/ + +void fmpz_poly_hensel_build_tree(slong * link, fmpz_poly_t *v, fmpz_poly_t *w, + const nmod_poly_factor_t fac); + +void fmpz_poly_hensel_lift(fmpz_poly_t Gout, fmpz_poly_t Hout, + fmpz_poly_t Aout, fmpz_poly_t Bout, + const fmpz_poly_t f, + const fmpz_poly_t g, const fmpz_poly_t h, + const fmpz_poly_t a, const fmpz_poly_t b, + const fmpz_t p, const fmpz_t p1); + +void _fmpz_poly_hensel_lift_without_inverse(fmpz *G, fmpz *H, + const fmpz *f, slong lenF, + const fmpz *g, slong lenG, const fmpz *h, slong lenH, + const fmpz *a, slong lenA, const fmpz *b, slong lenB, + const fmpz_t p, const fmpz_t p1); + +void fmpz_poly_hensel_lift_without_inverse(fmpz_poly_t Gout, fmpz_poly_t Hout, + const fmpz_poly_t f, const fmpz_poly_t g, const fmpz_poly_t h, + const fmpz_poly_t a, const fmpz_poly_t b, + const fmpz_t p, const fmpz_t p1); + +void _fmpz_poly_hensel_lift_only_inverse(fmpz *A, fmpz *B, + const fmpz *G, slong lenG, const fmpz *H, slong lenH, + const fmpz *a, slong lenA, const fmpz *b, slong lenB, + const fmpz_t p, const fmpz_t p1); + +void fmpz_poly_hensel_lift_only_inverse(fmpz_poly_t Aout, fmpz_poly_t Bout, + const fmpz_poly_t G, const fmpz_poly_t H, + const fmpz_poly_t a, const fmpz_poly_t b, + const fmpz_t p, const fmpz_t p1); + +void fmpz_poly_hensel_lift_tree_recursive(slong *link, + fmpz_poly_t *v, fmpz_poly_t *w, fmpz_poly_t f, slong j, slong inv, + const fmpz_t p0, const fmpz_t p1); + +void fmpz_poly_hensel_lift_tree(slong *link, fmpz_poly_t *v, fmpz_poly_t *w, + fmpz_poly_t f, slong r, const fmpz_t p, slong e0, slong e1, slong inv); + +slong _fmpz_poly_hensel_start_lift(fmpz_poly_factor_t lifted_fac, slong *link, + fmpz_poly_t *v, fmpz_poly_t *w, const fmpz_poly_t f, + const nmod_poly_factor_t local_fac, slong target_exp); + +slong _fmpz_poly_hensel_continue_lift(fmpz_poly_factor_t lifted_fac, + slong *link, fmpz_poly_t *v, fmpz_poly_t *w, const fmpz_poly_t f, + slong prev, slong curr, slong N, const fmpz_t p); + +void fmpz_poly_hensel_lift_once(fmpz_poly_factor_t lifted_fac, + const fmpz_poly_t f, + const nmod_poly_factor_t local_fac, slong N); + +/* Some functions for backwards compatibility */ + +static __inline__ void fmpz_poly_scalar_mul_mpz(fmpz_poly_t poly1, + const fmpz_poly_t poly2, const mpz_t x) +{ + fmpz_t t; + fmpz_init_set_readonly(t, x); + fmpz_poly_scalar_mul_fmpz(poly1, poly2, t); + fmpz_clear_readonly(t); +} + +static __inline__ void fmpz_poly_scalar_divexact_mpz(fmpz_poly_t poly1, + const fmpz_poly_t poly2, const mpz_t x) +{ + fmpz_t t; + fmpz_init_set_readonly(t, x); + fmpz_poly_scalar_divexact_fmpz(poly1, poly2, t); + fmpz_clear_readonly(t); +} + +static __inline__ void fmpz_poly_scalar_fdiv_mpz(fmpz_poly_t poly1, + const fmpz_poly_t poly2, const mpz_t x) +{ + fmpz_t t; + fmpz_init_set_readonly(t, x); + fmpz_poly_scalar_fdiv_fmpz(poly1, poly2, t); + fmpz_clear_readonly(t); +} + +static __inline__ void fmpz_poly_set_coeff_mpz(fmpz_poly_t poly, slong n, + const mpz_t x) +{ + fmpz_t t; + fmpz_init_set_readonly(t, x); + fmpz_poly_set_coeff_fmpz(poly, n, t); + fmpz_clear_readonly(t); +} + +static __inline__ void fmpz_poly_get_coeff_mpz(mpz_t x, const fmpz_poly_t poly, slong n) +{ + fmpz_t t; + fmpz_init(t); + fmpz_poly_get_coeff_fmpz(t, poly, n); + fmpz_get_mpz(x, t); + fmpz_clear(t); +} + +/* Roots */ + +void _fmpz_poly_bound_roots(fmpz_t bound, const fmpz * poly, slong len); + +void fmpz_poly_bound_roots(fmpz_t bound, const fmpz_poly_t poly); + +#ifdef __cplusplus +} +#endif + +#include "fmpz_poly_factor.h" + +#endif + diff --git a/external/flint-2.4.3/fmpz_poly/2norm.c b/external/flint-2.4.3/fmpz_poly/2norm.c new file mode 100644 index 0000000..d17fcbd --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/2norm.c @@ -0,0 +1,45 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +void +_fmpz_poly_2norm(fmpz_t res, const fmpz * poly, slong len) +{ + slong i; + fmpz_zero(res); + for (i = 0; i < len; i++) + fmpz_addmul(res, poly + i, poly + i); + fmpz_sqrt(res, res); +} + +void +fmpz_poly_2norm(fmpz_t res, const fmpz_poly_t poly) +{ + _fmpz_poly_2norm(res, poly->coeffs, poly->length); +} diff --git a/external/flint-2.4.3/fmpz_poly/2norm_normalised_bits.c b/external/flint-2.4.3/fmpz_poly/2norm_normalised_bits.c new file mode 100644 index 0000000..ca664f3 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/2norm_normalised_bits.c @@ -0,0 +1,44 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +mp_bitcnt_t _fmpz_poly_2norm_normalised_bits(const fmpz * poly, slong len) +{ + fmpz_t norm; + mp_bitcnt_t bits; + fmpz_init(norm); + + _fmpz_poly_2norm(norm, poly, len); + + bits = fmpz_bits(norm); + fmpz_clear(norm); + + return bits - fmpz_bits(poly + len - 1) + 1; +} diff --git a/external/flint-2.4.3/fmpz_poly/CRT_ui.c b/external/flint-2.4.3/fmpz_poly/CRT_ui.c new file mode 100644 index 0000000..2dc9fb1 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/CRT_ui.c @@ -0,0 +1,113 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" +#include "nmod_poly.h" + + +void +_fmpz_poly_CRT_ui_precomp(fmpz * res, const fmpz * poly1, slong len1, + const fmpz_t m1, mp_srcptr poly2, slong len2, mp_limb_t m2, + mp_limb_t m2inv, fmpz_t m1m2, mp_limb_t c, int sign) +{ + slong i; + + for (i = 0; i < FLINT_MIN(len1, len2); i++) + { + _fmpz_CRT_ui_precomp(res + i, poly1 + i, m1, + poly2[i], m2, m2inv, m1m2, c, sign); + } + + if (len2 > len1) + { + fmpz_t zero; + fmpz_init(zero); + for (i = len1; i < len2; i++) + { + _fmpz_CRT_ui_precomp(res + i, zero, m1, + poly2[i], m2, m2inv, m1m2, c, sign); + } + fmpz_clear(zero); + } + + for (i = len2; i < len1; i++) + { + _fmpz_CRT_ui_precomp(res + i, res + i, m1, + 0, m2, m2inv, m1m2, c, sign); + } +} + +void +_fmpz_poly_CRT_ui(fmpz * res, const fmpz * poly1, slong len1, + const fmpz_t m1, mp_srcptr poly2, slong len2, mp_limb_t m2, + mp_limb_t m2inv, int sign) +{ + mp_limb_t c; + fmpz_t m1m2; + + c = fmpz_fdiv_ui(m1, m2); + c = n_invmod(c, m2); + + if (c == 0) + { + flint_printf("Exception (_fmpz_poly_CRT_ui): m1 not invertible modulo m2.\n"); + abort(); + } + + fmpz_init(m1m2); + fmpz_mul_ui(m1m2, m1, m2); + + _fmpz_poly_CRT_ui_precomp(res, poly1, len1, m1, + poly2, len2, m2, m2inv, m1m2, c, sign); + + fmpz_clear(m1m2); +} + +void +fmpz_poly_CRT_ui(fmpz_poly_t res, const fmpz_poly_t poly1, + const fmpz_t m1, const nmod_poly_t poly2, int sign) +{ + slong len1 = poly1->length; + slong len2 = poly2->length; + slong len = FLINT_MAX(len1, len2); + + if (len == 0) + { + fmpz_poly_zero(res); + return; + } + + fmpz_poly_fit_length(res, len); + + _fmpz_poly_CRT_ui(res->coeffs, poly1->coeffs, poly1->length, m1, + poly2->coeffs, poly2->length, poly2->mod.n, poly2->mod.ninv, sign); + + _fmpz_poly_set_length(res, len); + _fmpz_poly_normalise(res); +} diff --git a/external/flint-2.4.3/fmpz_poly/add.c b/external/flint-2.4.3/fmpz_poly/add.c new file mode 100644 index 0000000..20aeec6 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/add.c @@ -0,0 +1,62 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +void +_fmpz_poly_add(fmpz * res, const fmpz * poly1, slong len1, const fmpz * poly2, + slong len2) +{ + slong i, min = FLINT_MIN(len1, len2); + + for (i = 0; i < min; i++) /* add up to the length of the shorter poly */ + fmpz_add(res + i, poly1 + i, poly2 + i); + + if (poly1 != res) /* copy any remaining coefficients from poly1 */ + for (i = min; i < len1; i++) + fmpz_set(res + i, poly1 + i); + + if (poly2 != res) /* copy any remaining coefficients from poly2 */ + for (i = min; i < len2; i++) + fmpz_set(res + i, poly2 + i); +} + +void +fmpz_poly_add(fmpz_poly_t res, const fmpz_poly_t poly1, + const fmpz_poly_t poly2) +{ + slong max = FLINT_MAX(poly1->length, poly2->length); + + fmpz_poly_fit_length(res, max); + + _fmpz_poly_add(res->coeffs, poly1->coeffs, poly1->length, poly2->coeffs, + poly2->length); + + _fmpz_poly_set_length(res, max); + _fmpz_poly_normalise(res); /* there may have been cancellation */ +} diff --git a/external/flint-2.4.3/fmpz_poly/bit_pack.c b/external/flint-2.4.3/fmpz_poly/bit_pack.c new file mode 100644 index 0000000..c10a133 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/bit_pack.c @@ -0,0 +1,99 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +void +_fmpz_poly_bit_pack(mp_ptr arr, const fmpz * poly, slong len, + mp_bitcnt_t bit_size, int negate) +{ + mp_bitcnt_t bits = 0; + mp_size_t limbs = 0; + mp_bitcnt_t b = bit_size % FLINT_BITS; + mp_size_t l = bit_size / FLINT_BITS; + int borrow = 0; + slong i; + + for (i = 0; i < len; i++) + { + borrow = + fmpz_bit_pack(arr + limbs, bits, bit_size, poly + i, negate, + borrow); + limbs += l; + bits += b; + if (bits >= FLINT_BITS) + { + bits -= FLINT_BITS; + limbs++; + } + } +} + +void +fmpz_poly_bit_pack(fmpz_t f, const fmpz_poly_t poly, + mp_bitcnt_t bit_size) +{ + slong len; + __mpz_struct * mpz; + slong i, d; + int negate; + + len = fmpz_poly_length(poly); + + if (len == 0 || bit_size == 0) + { + fmpz_zero(f); + return; + } + + mpz = _fmpz_promote(f); + mpz_realloc2(mpz, len * bit_size); + d = mpz->_mp_alloc; + + flint_mpn_zero(mpz->_mp_d, d); + + if (fmpz_sgn(fmpz_poly_lead(poly)) < 0) + negate = -1; + else + negate = 0; + + _fmpz_poly_bit_pack(mpz->_mp_d, poly->coeffs, len, bit_size, negate); + + for (i = d - 1; i >= 0; i--) + { + if (mpz->_mp_d[i] != 0) + break; + } + d = i + 1; + + mpz->_mp_size = d; + _fmpz_demote_val(f); + + if (negate) + fmpz_neg(f, f); +} diff --git a/external/flint-2.4.3/fmpz_poly/bit_unpack.c b/external/flint-2.4.3/fmpz_poly/bit_unpack.c new file mode 100644 index 0000000..ae4b85b --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/bit_unpack.c @@ -0,0 +1,157 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +int +_fmpz_poly_bit_unpack(fmpz * poly, slong len, + mp_srcptr arr, mp_bitcnt_t bit_size, int negate) +{ + mp_bitcnt_t bits = 0; + mp_size_t limbs = 0; + mp_bitcnt_t b = bit_size % FLINT_BITS; + mp_size_t l = bit_size / FLINT_BITS; + int borrow = 0; + slong i; + + for (i = 0; i < len; i++) + { + borrow = + fmpz_bit_unpack(poly + i, arr + limbs, bits, bit_size, negate, + borrow); + limbs += l; + bits += b; + if (bits >= FLINT_BITS) + { + bits -= FLINT_BITS; + limbs++; + } + } + + return borrow; +} + +void +_fmpz_poly_bit_unpack_unsigned(fmpz * poly, slong len, + mp_srcptr arr, mp_bitcnt_t bit_size) +{ + mp_bitcnt_t bits = 0; + mp_size_t limbs = 0; + mp_bitcnt_t b = bit_size % FLINT_BITS; + mp_size_t l = bit_size / FLINT_BITS; + slong i; + + for (i = 0; i < len; i++) + { + fmpz_bit_unpack_unsigned(poly + i, arr + limbs, bits, bit_size); + limbs += l; + bits += b; + if (bits >= FLINT_BITS) + { + bits -= FLINT_BITS; + limbs++; + } + } +} + +void +fmpz_poly_bit_unpack_unsigned(fmpz_poly_t poly, const fmpz_t f, + mp_bitcnt_t bit_size) +{ + slong len; + mpz_t tmp; + + if (fmpz_sgn(f) < 0) + { + flint_printf("Exception (fmpz_poly_bit_unpack_unsigned). Expected an unsigned value.\n"); + abort(); + } + + if (bit_size == 0 || fmpz_is_zero(f)) + { + fmpz_poly_zero(poly); + return; + } + + len = (fmpz_bits(f) + bit_size - 1) / bit_size; + + mpz_init2(tmp, bit_size*len); + flint_mpn_zero(tmp->_mp_d, tmp->_mp_alloc); + fmpz_get_mpz(tmp, f); + + fmpz_poly_fit_length(poly, len); + + _fmpz_poly_bit_unpack_unsigned(poly->coeffs, len, tmp->_mp_d, bit_size); + _fmpz_poly_set_length(poly, len); + _fmpz_poly_normalise(poly); + + mpz_clear(tmp); +} + + +void +fmpz_poly_bit_unpack(fmpz_poly_t poly, const fmpz_t f, mp_bitcnt_t bit_size) +{ + slong len; + mpz_t tmp; + int negate, borrow; + + if (bit_size == 0 || fmpz_is_zero(f)) + { + fmpz_poly_zero(poly); + return; + } + + /* Round up */ + len = (fmpz_bits(f) + bit_size - 1) / bit_size; + negate = (fmpz_sgn(f) < 0) ? -1 : 0; + + mpz_init2(tmp, bit_size*len); + + /* TODO: avoid all this wastefulness */ + flint_mpn_zero(tmp->_mp_d, tmp->_mp_alloc); + fmpz_get_mpz(tmp, f); + + fmpz_poly_fit_length(poly, len + 1); + + borrow = _fmpz_poly_bit_unpack(poly->coeffs, len, + tmp->_mp_d, bit_size, negate); + + if (borrow) + { + fmpz_set_si(poly->coeffs + len, negate ? WORD(-1) : WORD(1)); + _fmpz_poly_set_length(poly, len + 1); + } + else + { + _fmpz_poly_set_length(poly, len); + _fmpz_poly_normalise(poly); + } + + mpz_clear(tmp); +} diff --git a/external/flint-2.4.3/fmpz_poly/bound_roots.c b/external/flint-2.4.3/fmpz_poly/bound_roots.c new file mode 100644 index 0000000..d6bbe73 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/bound_roots.c @@ -0,0 +1,87 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 "fmpz_poly.h" + +/* quotient of absolute value, rounded up */ +static __inline__ void +fmpz_cdiv_abs_q(fmpz_t q, const fmpz_t x, const fmpz_t y) +{ + if (fmpz_sgn(x) == fmpz_sgn(y)) + { + fmpz_cdiv_q(q, x, y); + } + else + { + fmpz_fdiv_q(q, x, y); + fmpz_neg(q, q); + } +} + +void +_fmpz_poly_bound_roots(fmpz_t bound, const fmpz * poly, slong len) +{ + + if (len <= 1) + { + fmpz_zero(bound); + } + else if (len == 2) + { + fmpz_cdiv_abs_q(bound, poly + 0, poly + 1); + } + else + { + slong i; + fmpz_t t; + + fmpz_init(t); + + fmpz_mul_2exp(t, poly + len - 1, 1); + fmpz_cdiv_abs_q(bound, poly + 0, t); + fmpz_root(bound, bound, len - 1); + + for (i = 1; i < len - 1; i++) + { + fmpz_cdiv_abs_q(t, poly + len - i - 1, poly + len - 1); + fmpz_root(t, t, i); + fmpz_add_ui(t, t, 1); + + if (fmpz_cmp(t, bound) > 0) + fmpz_swap(t, bound); + } + + fmpz_mul_2exp(bound, bound, 1); + + fmpz_clear(t); + } +} + +void +fmpz_poly_bound_roots(fmpz_t bound, const fmpz_poly_t poly) +{ + _fmpz_poly_bound_roots(bound, poly->coeffs, poly->length); +} + diff --git a/external/flint-2.4.3/fmpz_poly/clear.c b/external/flint-2.4.3/fmpz_poly/clear.c new file mode 100644 index 0000000..46fe6b8 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/clear.c @@ -0,0 +1,43 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +void +fmpz_poly_clear(fmpz_poly_t poly) +{ + if (poly->coeffs) + { + slong i; + for (i = 0; i < poly->alloc; i++) + _fmpz_demote(poly->coeffs + i); + flint_free(poly->coeffs); + } +} diff --git a/external/flint-2.4.3/fmpz_poly/compose.c b/external/flint-2.4.3/fmpz_poly/compose.c new file mode 100644 index 0000000..67847f9 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/compose.c @@ -0,0 +1,86 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void +_fmpz_poly_compose(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2) +{ + if (len1 == 1) + fmpz_set(res, poly1); + else if (len2 == 1) + _fmpz_poly_evaluate_fmpz(res, poly1, len1, poly2); + else if (len1 <= 4) + _fmpz_poly_compose_horner(res, poly1, len1, poly2, len2); + else + _fmpz_poly_compose_divconquer(res, poly1, len1, poly2, len2); +} + +void +fmpz_poly_compose(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2) +{ + const slong len1 = poly1->length; + const slong len2 = poly2->length; + slong lenr; + + if (len1 == 0) + { + fmpz_poly_zero(res); + return; + } + if (len1 == 1 || len2 == 0) + { + fmpz_poly_set_fmpz(res, poly1->coeffs); + return; + } + + lenr = (len1 - 1) * (len2 - 1) + 1; + + if (res != poly1 && res != poly2) + { + fmpz_poly_fit_length(res, lenr); + _fmpz_poly_compose(res->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2); + _fmpz_poly_set_length(res, lenr); + _fmpz_poly_normalise(res); + } + else + { + fmpz_poly_t t; + fmpz_poly_init2(t, lenr); + _fmpz_poly_compose(t->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2); + _fmpz_poly_set_length(t, lenr); + _fmpz_poly_normalise(t); + fmpz_poly_swap(res, t); + fmpz_poly_clear(t); + } +} diff --git a/external/flint-2.4.3/fmpz_poly/compose_divconquer.c b/external/flint-2.4.3/fmpz_poly/compose_divconquer.c new file mode 100644 index 0000000..337a863 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/compose_divconquer.c @@ -0,0 +1,253 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +/* + Assumptions. + + Suppose that $len1 \geq 3$ and $len2 \geq 2$. + + + Definitions. + + Define a sequence $(n_i)$ by $n_1 = \ceil{len1 / 2}$, + $n_2 = \ceil{n_1 / 2}$, etc. all the way to + $n_K = \ceil{n_{K-1} / 2} = 2$. Thus, $K = \ceil{\log_2 len1} - 1$. + Note that we can write $n_i = \ceil{len1 / 2^i}$. + + + Rough description (of the allocation process, or the algorithm). + + Step 1. + For $0 \leq i < n_1$, set h[i] to something of length at most len2. + Set pow to $poly2^2$. + + Step n. + For $0 \leq i < n_n$, set h[i] to something of length at most the length + of $poly2^{2^n - 1}$. + Set pow to $poly^{2^n}$. + + Step K. + For $0 \leq i < n_K$, set h[i] to something of length at most the length + of $poly2^{2^K - 1}$. + Set pow to $poly^{2^K}$. + + + Analysis of the space requirements. + + Let $S$ be the over all space we need, measured in number of coefficients. + Then + \begin{align*} + S & = 2 \times \bigl[ (2^K - 1) (len2 - 1) + 1 \bigr] + + \sum_{i=1}^{K-1} (n_i - n_{i+1}) \bigl[(2^i - 1) (len2 - 1) + 1\bigr] \\ + & = 2 \times \bigl[ (2^K - 1) (len2 - 1) + 1 \bigr] + + (len2 - 1) \sum_{i=1}^{K-1} (n_i - n_{i+1}) (2^i - 1) + n_1 - n_K. + \end{align*} + + If $K = 1$, or equivalently $len1$ is 3 or 4, then $S = 2 \times len2$. + Otherwise, we can bound $n_i - n_{i+1}$ from above as follows. For any + non-negative integer $x$, + \begin{equation*} + \ceil{x / 2^i} - \ceil{x / 2^{i+1}} \leq x/2^i - x/2^{i+1} = x / 2^{i+1}. + \end{equation*} + + Thus, + \begin{align*} + S & \leq 2 \times \bigl[ (2^K - 1) (len2 - 1) + 1 \bigr] + + (len2 - 1) \times len1 \times \sum_{i=1}^{K-1} (1/2 - 1/2^{i+1}) \\ + & \leq 2 \times \bigl[ (2^K - 1) (len2 - 1) + 1 \bigr] + + (len2 - 1) \times len1 \times (K/2 + 1). + \end{align*} + */ + +void +_fmpz_poly_compose_divconquer(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2) +{ + slong i, j, k, n; + slong *hlen, alloc, powlen; + fmpz *v, **h, *pow, *temp; + + if (len1 <= 2 || len2 <= 1) + { + if (len1 == 1) + fmpz_set(res, poly1); + else if (len2 == 1) + _fmpz_poly_evaluate_fmpz(res, poly1, len1, poly2); + else /* len1 == 2 */ + _fmpz_poly_compose_horner(res, poly1, len1, poly2, len2); + return; + } + + /* Initialisation */ + + hlen = (slong *) flint_malloc(((len1 + 1) / 2) * sizeof(slong)); + + k = FLINT_CLOG2(len1) - 1; + + hlen[0] = hlen[1] = ((1 << k) - 1) * (len2 - 1) + 1; + for (i = k - 1; i > 0; i--) + { + slong 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 = _fmpz_vec_init(alloc + 2 * powlen); + h = (fmpz **) flint_malloc(((len1 + 1) / 2) * sizeof(fmpz *)); + 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 (poly1[j + 1] != WORD(0)) + { + _fmpz_vec_scalar_mul_fmpz(h[i], poly2, len2, poly1 + j + 1); + fmpz_add(h[i], h[i], poly1 + j); + hlen[i] = len2; + } + else if (poly1[j] != WORD(0)) + { + fmpz_set(h[i], poly1 + j); + hlen[i] = 1; + } + } + if ((len1 & WORD(1))) + { + if (poly1[j] != WORD(0)) + { + fmpz_set(h[i], poly1 + j); + hlen[i] = 1; + } + } + + _fmpz_poly_sqr(pow, poly2, len2); + powlen = 2 * len2 - 1; + + for (n = (len1 + 1) / 2; n > 2; n = (n + 1) / 2) + { + if (hlen[1] > 0) + { + slong templen = powlen + hlen[1] - 1; + _fmpz_poly_mul(temp, pow, powlen, h[1], hlen[1]); + _fmpz_poly_add(h[0], temp, templen, h[0], hlen[0]); + hlen[0] = FLINT_MAX(hlen[0], templen); + } + + for (i = 1; i < n / 2; i++) + { + if (hlen[2*i + 1] > 0) + { + _fmpz_poly_mul(h[i], pow, powlen, h[2*i + 1], hlen[2*i + 1]); + hlen[i] = hlen[2*i + 1] + powlen - 1; + } else + hlen[i] = 0; + _fmpz_poly_add(h[i], h[i], hlen[i], h[2*i], hlen[2*i]); + hlen[i] = FLINT_MAX(hlen[i], hlen[2*i]); + } + if ((n & WORD(1))) + { + _fmpz_vec_set(h[i], h[2*i], hlen[2*i]); + hlen[i] = hlen[2*i]; + } + + _fmpz_poly_sqr(temp, pow, powlen); + powlen += powlen - 1; + { + fmpz * t = pow; + pow = temp; + temp = t; + } + } + + _fmpz_poly_mul(res, pow, powlen, h[1], hlen[1]); + _fmpz_vec_add(res, res, h[0], hlen[0]); + + _fmpz_vec_clear(v, alloc + 2 * powlen); + flint_free(h); + flint_free(hlen); +} + +void +fmpz_poly_compose_divconquer(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2) +{ + const slong len1 = poly1->length; + const slong len2 = poly2->length; + slong lenr; + + if (len1 == 0) + { + fmpz_poly_zero(res); + return; + } + if (len1 == 1 || len2 == 0) + { + fmpz_poly_set_fmpz(res, poly1->coeffs); + return; + } + + lenr = (len1 - 1) * (len2 - 1) + 1; + + if (res != poly1 && res != poly2) + { + fmpz_poly_fit_length(res, lenr); + _fmpz_poly_compose_divconquer(res->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2); + _fmpz_poly_set_length(res, lenr); + _fmpz_poly_normalise(res); + } + else + { + fmpz_poly_t t; + fmpz_poly_init2(t, lenr); + _fmpz_poly_compose_divconquer(t->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2); + _fmpz_poly_set_length(t, lenr); + _fmpz_poly_normalise(t); + fmpz_poly_swap(res, t); + fmpz_poly_clear(t); + } +} diff --git a/external/flint-2.4.3/fmpz_poly/compose_horner.c b/external/flint-2.4.3/fmpz_poly/compose_horner.c new file mode 100644 index 0000000..60a0648 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/compose_horner.c @@ -0,0 +1,105 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void +_fmpz_poly_compose_horner(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2) +{ + if (len1 == 1) + { + fmpz_set(res, poly1); + } + else + { + const slong alloc = (len1 - 1) * (len2 - 1) + 1; + + slong i = len1 - 1, lenr; + fmpz * t = _fmpz_vec_init(alloc); + + /* + Perform the first two steps as one, + "res = a(m) * poly2 + a(m-1)". + */ + { + lenr = len2; + _fmpz_vec_scalar_mul_fmpz(res, poly2, len2, poly1 + i); + i--; + fmpz_add(res, res, poly1 + i); + } + while (i--) + { + _fmpz_poly_mul(t, res, lenr, poly2, len2); + lenr += len2 - 1; + _fmpz_poly_add(res, t, lenr, poly1 + i, 1); + } + _fmpz_vec_clear(t, alloc); + } +} + +void +fmpz_poly_compose_horner(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2) +{ + const slong len1 = poly1->length; + const slong len2 = poly2->length; + + if (len1 == 0) + { + fmpz_poly_zero(res); + } + else if (len1 == 1 || len2 == 0) + { + fmpz_poly_set_fmpz(res, poly1->coeffs); + } + else + { + const slong lenr = (len1 - 1) * (len2 - 1) + 1; + + if ((res != poly1) && (res != poly2)) + { + fmpz_poly_fit_length(res, lenr); + _fmpz_poly_compose_horner(res->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2); + _fmpz_poly_set_length(res, lenr); + } + else + { + fmpz_poly_t t; + fmpz_poly_init2(t, lenr); + _fmpz_poly_compose_horner(t->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2); + _fmpz_poly_set_length(t, lenr); + fmpz_poly_swap(res, t); + fmpz_poly_clear(t); + } + _fmpz_poly_normalise(res); + } +} diff --git a/external/flint-2.4.3/fmpz_poly/compose_series.c b/external/flint-2.4.3/fmpz_poly/compose_series.c new file mode 100644 index 0000000..cb15a61 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/compose_series.c @@ -0,0 +1,93 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + + +void +_fmpz_poly_compose_series(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2, slong n) +{ + if (len1 <= 10) + _fmpz_poly_compose_series_horner(res, poly1, len1, poly2, len2, n); + else + _fmpz_poly_compose_series_brent_kung(res, poly1, len1, poly2, len2, n); +} + +void +fmpz_poly_compose_series(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2, slong n) +{ + slong len1 = poly1->length; + slong len2 = poly2->length; + slong lenr; + + if (len2 != 0 && !fmpz_is_zero(poly2->coeffs)) + { + flint_printf("Exception (fmpz_poly_compose_series). Inner polynomial \n" + "must have zero constant term.\n"); + abort(); + } + + if (len1 == 0 || n == 0) + { + fmpz_poly_zero(res); + return; + } + + if (len2 == 0 || len1 == 1) + { + fmpz_poly_set_fmpz(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)) + { + fmpz_poly_fit_length(res, lenr); + _fmpz_poly_compose_series(res->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2, lenr); + _fmpz_poly_set_length(res, lenr); + _fmpz_poly_normalise(res); + } + else + { + fmpz_poly_t t; + fmpz_poly_init2(t, lenr); + _fmpz_poly_compose_series(t->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2, lenr); + _fmpz_poly_set_length(t, lenr); + _fmpz_poly_normalise(t); + fmpz_poly_swap(res, t); + fmpz_poly_clear(t); + } +} diff --git a/external/flint-2.4.3/fmpz_poly/compose_series_brent_kung.c b/external/flint-2.4.3/fmpz_poly/compose_series_brent_kung.c new file mode 100644 index 0000000..8ada77a --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/compose_series_brent_kung.c @@ -0,0 +1,137 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpz_mat.h" +#include "ulong_extras.h" + +void +_fmpz_poly_compose_series_brent_kung(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2, slong n) +{ + fmpz_mat_t A, B, C; + fmpz *t, *h; + slong i, m; + + if (n == 1) + { + fmpz_set(res, poly1); + return; + } + + m = n_sqrt(n) + 1; + + fmpz_mat_init(A, m, n); + fmpz_mat_init(B, m, m); + fmpz_mat_init(C, m, n); + + h = _fmpz_vec_init(n); + t = _fmpz_vec_init(n); + + /* Set rows of B to the segments of poly1 */ + for (i = 0; i < len1 / m; i++) + _fmpz_vec_set(B->rows[i], poly1 + i*m, m); + _fmpz_vec_set(B->rows[i], poly1 + i*m, len1 % m); + + /* Set rows of A to powers of poly2 */ + fmpz_one(A->rows[0]); + _fmpz_vec_set(A->rows[1], poly2, len2); + for (i = 2; i < m; i++) + _fmpz_poly_mullow(A->rows[i], A->rows[i-1], n, poly2, len2, n); + + fmpz_mat_mul(C, B, A); + + /* Evaluate block composition using the Horner scheme */ + _fmpz_vec_set(res, C->rows[m - 1], n); + _fmpz_poly_mullow(h, A->rows[m - 1], n, poly2, len2, n); + + for (i = m - 2; i >= 0; i--) + { + _fmpz_poly_mullow(t, res, n, h, n, n); + _fmpz_poly_add(res, t, n, C->rows[i], n); + } + + _fmpz_vec_clear(h, n); + _fmpz_vec_clear(t, n); + + fmpz_mat_clear(A); + fmpz_mat_clear(B); + fmpz_mat_clear(C); +} + +void +fmpz_poly_compose_series_brent_kung(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2, slong n) +{ + slong len1 = poly1->length; + slong len2 = poly2->length; + slong lenr; + + if (len2 != 0 && !fmpz_is_zero(poly2->coeffs)) + { + flint_printf("Exception (fmpz_poly_compose_series_brent_kung). Inner \n" + "polynomial must have zero constant term.\n"); + abort(); + } + + if (len1 == 0 || n == 0) + { + fmpz_poly_zero(res); + return; + } + + if (len2 == 0 || len1 == 1) + { + fmpz_poly_set_fmpz(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)) + { + fmpz_poly_fit_length(res, lenr); + _fmpz_poly_compose_series_brent_kung(res->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2, lenr); + _fmpz_poly_set_length(res, lenr); + _fmpz_poly_normalise(res); + } + else + { + fmpz_poly_t t; + fmpz_poly_init2(t, lenr); + _fmpz_poly_compose_series_brent_kung(t->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2, lenr); + _fmpz_poly_set_length(t, lenr); + _fmpz_poly_normalise(t); + fmpz_poly_swap(res, t); + fmpz_poly_clear(t); + } +} diff --git a/external/flint-2.4.3/fmpz_poly/compose_series_horner.c b/external/flint-2.4.3/fmpz_poly/compose_series_horner.c new file mode 100644 index 0000000..581f906 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/compose_series_horner.c @@ -0,0 +1,124 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + + +void +_fmpz_poly_compose_series_horner(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2, slong n) +{ + if (n == 1) + { + fmpz_set(res, poly1); + } + else + { + slong i = len1 - 1; + slong lenr; + + fmpz * t = _fmpz_vec_init(n); + + lenr = len2; + _fmpz_vec_scalar_mul_fmpz(res, poly2, len2, poly1 + i); + i--; + fmpz_add(res, res, poly1 + i); + + while (i > 0) + { + i--; + if (lenr + len2 - 1 < n) + { + _fmpz_poly_mul(t, res, lenr, poly2, len2); + lenr = lenr + len2 - 1; + } + else + { + _fmpz_poly_mullow(t, res, lenr, poly2, len2, n); + lenr = n; + } + _fmpz_poly_add(res, t, lenr, poly1 + i, 1); + } + + _fmpz_vec_zero(res + lenr, n - lenr); + _fmpz_vec_clear(t, n); + } +} + +void +fmpz_poly_compose_series_horner(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2, slong n) +{ + slong len1 = poly1->length; + slong len2 = poly2->length; + slong lenr; + + if (len2 != 0 && !fmpz_is_zero(poly2->coeffs)) + { + flint_printf("Exception (fmpz_poly_compose_series_horner). Inner polynomial \n" + "must have zero constant term.\n"); + abort(); + } + + if (len1 == 0 || n == 0) + { + fmpz_poly_zero(res); + return; + } + + if (len2 == 0 || len1 == 1) + { + fmpz_poly_set_fmpz(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)) + { + fmpz_poly_fit_length(res, lenr); + _fmpz_poly_compose_series_horner(res->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2, lenr); + _fmpz_poly_set_length(res, lenr); + _fmpz_poly_normalise(res); + } + else + { + fmpz_poly_t t; + fmpz_poly_init2(t, lenr); + _fmpz_poly_compose_series_horner(t->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2, lenr); + _fmpz_poly_set_length(t, lenr); + _fmpz_poly_normalise(t); + fmpz_poly_swap(res, t); + fmpz_poly_clear(t); + } +} diff --git a/external/flint-2.4.3/fmpz_poly/content.c b/external/flint-2.4.3/fmpz_poly/content.c new file mode 100644 index 0000000..d80e318 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/content.c @@ -0,0 +1,47 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +void +_fmpz_poly_content(fmpz_t res, const fmpz * poly, slong len) +{ + fmpz_zero(res); + while (len--) + fmpz_gcd(res, res, poly + len); +} + +void +fmpz_poly_content(fmpz_t res, const fmpz_poly_t poly) +{ + fmpz_t t; + fmpz_init(t); + _fmpz_poly_content(t, poly->coeffs, poly->length); + fmpz_swap(res, t); + fmpz_clear(t); +} diff --git a/external/flint-2.4.3/fmpz_poly/derivative.c b/external/flint-2.4.3/fmpz_poly/derivative.c new file mode 100644 index 0000000..1dbda30 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/derivative.c @@ -0,0 +1,53 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +void _fmpz_poly_derivative(fmpz * rpoly, const fmpz * poly, slong len) +{ + slong i; + + for (i = 1; i < len; i++) + fmpz_mul_ui(rpoly + (i - 1), poly + i, i); +} + +void fmpz_poly_derivative(fmpz_poly_t res, const fmpz_poly_t poly) +{ + const slong len = poly->length; + + if (len < 2) + { + fmpz_poly_zero(res); + } + else + { + fmpz_poly_fit_length(res, len - 1); + _fmpz_poly_derivative(res->coeffs, poly->coeffs, len); + _fmpz_poly_set_length(res, len - 1); + } +} diff --git a/external/flint-2.4.3/fmpz_poly/div.c b/external/flint-2.4.3/fmpz_poly/div.c new file mode 100644 index 0000000..1d01d0e --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/div.c @@ -0,0 +1,80 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void +_fmpz_poly_div(fmpz * Q, const fmpz * A, slong lenA, const fmpz * B, slong lenB) +{ + _fmpz_poly_div_divconquer(Q, A, lenA, B, lenB); +} + +void +fmpz_poly_div(fmpz_poly_t Q, const fmpz_poly_t A, const fmpz_poly_t B) +{ + fmpz_poly_t tQ; + fmpz *q; + + if (B->length == 0) + { + flint_printf("Exception (fmpz_poly_div). Division by zero.\n"); + abort(); + } + + if (A->length < B->length) + { + fmpz_poly_zero(Q); + return; + } + + if (Q == A || Q == B) + { + fmpz_poly_init2(tQ, A->length - B->length + 1); + q = tQ->coeffs; + } + else + { + fmpz_poly_fit_length(Q, A->length - B->length + 1); + q = Q->coeffs; + } + + _fmpz_poly_div(q, A->coeffs, A->length, B->coeffs, B->length); + + if (Q == A || Q == B) + { + _fmpz_poly_set_length(tQ, A->length - B->length + 1); + fmpz_poly_swap(tQ, Q); + fmpz_poly_clear(tQ); + } + else + _fmpz_poly_set_length(Q, A->length - B->length + 1); + + _fmpz_poly_normalise(Q); +} diff --git a/external/flint-2.4.3/fmpz_poly/div_basecase.c b/external/flint-2.4.3/fmpz_poly/div_basecase.c new file mode 100644 index 0000000..229b3d1 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/div_basecase.c @@ -0,0 +1,125 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void +_fmpz_poly_div_basecase(fmpz * Q, fmpz * R, const fmpz * A, slong lenA, + const fmpz * B, slong lenB) +{ + const fmpz * leadB = B + lenB - 1; + slong B1, iQ = lenA - lenB; + slong alloc; + + while (lenA >= lenB && fmpz_cmpabs(A + lenA - 1, leadB) < 0) + { + fmpz_zero(Q + iQ); + iQ--; + lenA--; + } + + if (lenA < lenB) + return; + + alloc = (R == NULL) ? lenA : 0; + if (alloc) + R = _fmpz_vec_init(alloc); + if (R != A) + _fmpz_vec_set(R + lenB - 1, A + lenB - 1, lenA - lenB + 1); + + B1 = lenB - 1; + + while (lenA >= lenB) + { + if (fmpz_cmpabs(R + lenA - 1, leadB) < 0) + fmpz_zero(Q + iQ); + else + { + fmpz_fdiv_q(Q + iQ, R + lenA - 1, leadB); + _fmpz_vec_scalar_submul_fmpz(R + lenA - B1 - 1, B, B1, Q + iQ); + } + + if (B1 >= lenA - lenB + 1) + { + B++; + B1--; + } + + lenA--; + iQ--; + } + + if (alloc) + _fmpz_vec_clear(R, alloc); +} + +void +fmpz_poly_div_basecase(fmpz_poly_t Q, + const fmpz_poly_t A, const fmpz_poly_t B) +{ + slong lenq; + fmpz *q; + + if (B->length == 0) + { + flint_printf("Exception (fmpz_poly_div_basecase). Division by zero.\n"); + abort(); + } + if (A->length < B->length) + { + fmpz_poly_zero(Q); + return; + } + + lenq = A->length - B->length + 1; + if ((Q == A) || (Q == B)) + q = _fmpz_vec_init(lenq); + else + { + fmpz_poly_fit_length(Q, lenq); + q = Q->coeffs; + } + + _fmpz_poly_div_basecase(q, NULL, A->coeffs, A->length, + B->coeffs, B->length); + + if ((Q == A) || (Q == B)) + { + _fmpz_vec_clear(Q->coeffs, Q->alloc); + Q->coeffs = q; + Q->alloc = lenq; + Q->length = lenq; + } + else + _fmpz_poly_set_length(Q, lenq); + + _fmpz_poly_normalise(Q); +} diff --git a/external/flint-2.4.3/fmpz_poly/div_divconquer.c b/external/flint-2.4.3/fmpz_poly/div_divconquer.c new file mode 100644 index 0000000..7c3f6ff --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/div_divconquer.c @@ -0,0 +1,156 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2012 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +static void +__fmpz_poly_div_divconquer(fmpz * Q, const fmpz * A, slong lenA, + const fmpz * B, slong lenB) +{ + if (lenA < 2 * lenB - 1) + { + /* + Convert unbalanced division into a 2 q1 - 1 by q1 division + */ + + const slong q1 = lenA - lenB + 1; + const slong q2 = lenB - q1; + + fmpz * temp = _fmpz_vec_init(2 * q1 - 1); + + _fmpz_poly_div_divconquer_recursive(Q, temp, A + q2, B + q2, q1); + + _fmpz_vec_clear(temp, 2 * q1 - 1); + } + else /* lenA = 2 lenB - 1 */ + { + fmpz * temp = _fmpz_vec_init(lenA); + + _fmpz_poly_div_divconquer_recursive(Q, temp, A, B, lenB); + + _fmpz_vec_clear(temp, lenA); + } +} + +/* needed due to partial overlap */ +static void +_fmpz_vec_sub_dec(fmpz * a, const fmpz * b, const fmpz * c, slong n) +{ + slong i; + + for (i = n - 1; i >= 0; i--) + fmpz_sub(a + i, b + i, c + i); +} + +void _fmpz_poly_div_divconquer(fmpz *Q, + const fmpz *A, slong lenA, + const fmpz *B, slong lenB) +{ + if (lenA <= 2 * lenB - 1) + { + __fmpz_poly_div_divconquer(Q, A, lenA, B, lenB); + } + else /* lenA > 2 * lenB - 1 */ + { + fmpz *S, *T; + slong shift, next, n = 2 * lenB - 1; + + S = _fmpz_vec_init(2 * n); + T = S + n; + + /* To avoid copying all of A, we let S be a window of the + remainder, taking up to n coefficients at a time */ + shift = lenA - n; + _fmpz_vec_set(S, A + shift, n); + + while (lenA >= n) + { + shift = lenA - n; + _fmpz_poly_divremlow_divconquer_recursive(Q + shift, T, S, B, lenB); + next = FLINT_MIN(lenB, shift); + _fmpz_vec_sub_dec(S + next, S, T, lenB - 1); + _fmpz_vec_set(S, A + shift - next, next); + lenA -= lenB; + } + + if (lenA >= lenB) + __fmpz_poly_div_divconquer(Q, S, lenA, B, lenB); + + _fmpz_vec_clear(S, 2 * n); + } +} + +void +fmpz_poly_div_divconquer(fmpz_poly_t Q, + const fmpz_poly_t A, const fmpz_poly_t B) +{ + const slong lenA = A->length; + const slong lenB = B->length; + fmpz_poly_t t; + fmpz *q; + + if (lenB == 0) + { + flint_printf("Exception (fmpz_poly_div_divconquer). Division by zero.\n"); + abort(); + } + + if (lenA < lenB) + { + fmpz_poly_zero(Q); + return; + } + + if (Q == A || Q == B) + { + fmpz_poly_init2(t, lenA - lenB + 1); + q = t->coeffs; + } + else + { + fmpz_poly_fit_length(Q, lenA - lenB + 1); + q = Q->coeffs; + } + + _fmpz_poly_div_divconquer(q, A->coeffs, lenA, B->coeffs, lenB); + + if (Q == A || Q == B) + { + _fmpz_poly_set_length(t, lenA - lenB + 1); + fmpz_poly_swap(t, Q); + fmpz_poly_clear(t); + } + else + _fmpz_poly_set_length(Q, lenA - lenB + 1); + + _fmpz_poly_normalise(Q); +} diff --git a/external/flint-2.4.3/fmpz_poly/div_divconquer_recursive.c b/external/flint-2.4.3/fmpz_poly/div_divconquer_recursive.c new file mode 100644 index 0000000..9e0afe9 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/div_divconquer_recursive.c @@ -0,0 +1,108 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +#define FLINT_DIV_DIVCONQUER_CUTOFF 16 + +void +_fmpz_poly_div_divconquer_recursive(fmpz * Q, fmpz * temp, + const fmpz * A, const fmpz * B, slong lenB) +{ + if (lenB <= FLINT_DIV_DIVCONQUER_CUTOFF) + { + _fmpz_poly_div_basecase(Q, temp, A, 2 * lenB - 1, B, lenB); + } + else + { + const slong n2 = lenB / 2; + const slong n1 = lenB - n2; + + fmpz * q0 = Q; + fmpz * q1 = Q + n2; + + /* + t is a vector of length lenB - 1, h points to the top n2 coeffs + of t; r1 is vector of length lenB >= 2 n1 - 1 + */ + + fmpz * t = temp; + fmpz * h = temp + (n1 - 1); + fmpz * r1 = temp + (lenB - 1); + + /* + Set {q1, n1}, {r1, 2 n1 - 1} to the quotient and remainder of + {A + 2 n2, 2 n1 - 1} divided by {B + n2, n1} + */ + + _fmpz_poly_divremlow_divconquer_recursive(q1, r1, A + 2 * n2, B + n2, n1); + _fmpz_vec_sub(r1, A + 2 * n2, r1, n1 - 1); + + /* + Set the top n2 coeffs of t to the top n2 coeffs of the product of + {q1, n1} and {B, n2}; the bottom n1 - 1 coeffs may be arbitrary + + For sufficiently large polynomials, computing the full product + using Kronecker segmentation is faster than computing the opposite + short product via Karatsuba + */ + + _fmpz_poly_mul_KS(t, q1, n1, B, n2); + + /* + If lenB is odd, set {h, n2} to {r1, n2} - {h, n2}, otherwise, to + + {A + lenB - 1, 1} + {x * r1, n2} - {h, n2} + */ + + if (lenB & WORD(1)) + { + _fmpz_vec_sub(h, r1, h, n2); + } + else + { + _fmpz_vec_sub(h + 1, r1, h + 1, n2 - 1); + fmpz_neg(h, h); + fmpz_add(h, h, A + lenB - 1); + } + + /* + Set t to h shifted to the right by n2 - 1, and set q0 to the + quotient of {t, 2 n2 - 1} and {B + n1, n2} + + Note the bottom n2 - 1 coefficients of t are irrelevant + */ + + t += (lenB & WORD(1)); + + _fmpz_poly_div_divconquer_recursive(q0, temp + lenB, t, B + n1, n2); + } +} + diff --git a/external/flint-2.4.3/fmpz_poly/div_preinv.c b/external/flint-2.4.3/fmpz_poly/div_preinv.c new file mode 100644 index 0000000..4fda8d1 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/div_preinv.c @@ -0,0 +1,104 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +void +_fmpz_poly_div_preinv(fmpz * Q, const fmpz * A, slong len1_in, + const fmpz * B, const fmpz * B_inv, slong len2) +{ + slong len1 = len1_in; + slong n = len1 - len2 + 1; + fmpz * A_rev; + fmpz * a; + + if (n > len2) + { + a = _fmpz_vec_init(len1_in); + _fmpz_vec_set(a, A, len1_in); + + do { + slong start = n - len2; + _fmpz_poly_divrem_preinv(Q + start, a + start, len1 - start, + B, B_inv, len2); + n -= len2; + len1 -= len2; + } while (n > len2); + } else + a = (fmpz *) A; + + A_rev = _fmpz_vec_init(len1); + + _fmpz_poly_reverse(A_rev, a, len1, len1); + _fmpz_poly_mullow(Q, A_rev, len1, B_inv, len2, n); + _fmpz_poly_reverse(Q, Q, n, n); + + if (a != A) + _fmpz_vec_clear(a, len1_in); + _fmpz_vec_clear(A_rev, len1); +} + +void +fmpz_poly_div_preinv(fmpz_poly_t Q, const fmpz_poly_t A, + const fmpz_poly_t B, const fmpz_poly_t B_inv) +{ + fmpz_poly_t tQ; + fmpz *q; + slong len1 = A->length, len2 = B_inv->length; + slong qlen = len1 - len2 + 1; + + if (len1 < len2) + { + fmpz_poly_zero(Q); + return; + } + + if (Q == A || Q == B || Q == B_inv) + { + fmpz_poly_init2(tQ, qlen); + q = tQ->coeffs; + } + else + { + fmpz_poly_fit_length(Q, qlen); + q = Q->coeffs; + } + + _fmpz_poly_div_preinv(q, A->coeffs, len1, B->coeffs, B_inv->coeffs, len2); + + if (Q == A || Q == B || Q == B_inv) + { + _fmpz_poly_set_length(tQ, qlen); + fmpz_poly_swap(tQ, Q); + fmpz_poly_clear(tQ); + } + else + _fmpz_poly_set_length(Q, qlen); + + /* no need to normalise */ +} diff --git a/external/flint-2.4.3/fmpz_poly/div_root.c b/external/flint-2.4.3/fmpz_poly/div_root.c new file mode 100644 index 0000000..ed4275f --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/div_root.c @@ -0,0 +1,78 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + + +void +_fmpz_poly_div_root(fmpz * Q, const fmpz * A, slong len, const fmpz_t c) +{ + fmpz_t r, t; + slong i; + + if (len < 2) + return; + + fmpz_init(r); + fmpz_init(t); + fmpz_set(r, A + len - 1); + + for (i = len - 2; i > 0; i--) + { + fmpz_mul(t, r, c); + fmpz_add(t, t, A + i); + fmpz_swap(Q + i, r); + fmpz_swap(r, t); + } + + fmpz_swap(Q, r); + fmpz_clear(r); + fmpz_clear(t); +} + +void +fmpz_poly_div_root(fmpz_poly_t Q, const fmpz_poly_t A, const fmpz_t c) +{ + slong len = A->length; + + if (len <= 1) + { + fmpz_poly_zero(Q); + return; + } + + if (fmpz_is_zero(c)) + { + fmpz_poly_shift_right(Q, A, 1); + return; + } + + fmpz_poly_fit_length(Q, len - 1); + _fmpz_poly_div_root(Q->coeffs, A->coeffs, len, c); + _fmpz_poly_set_length(Q, len - 1); +} diff --git a/external/flint-2.4.3/fmpz_poly/div_series.c b/external/flint-2.4.3/fmpz_poly/div_series.c new file mode 100644 index 0000000..a84c8b1 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/div_series.c @@ -0,0 +1,107 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void +_fmpz_poly_div_series(fmpz * Q, const fmpz * A, const fmpz * B, slong n) +{ + if (n == 1) + { + _fmpz_vec_set(Q, A, n); + } + else + { + fmpz * Binv = _fmpz_vec_init(n); + + _fmpz_poly_inv_series(Binv, B, n); + _fmpz_poly_mullow(Q, A, n, Binv, n, n); + + _fmpz_vec_clear(Binv, n); + } +} + +void fmpz_poly_div_series(fmpz_poly_t Q, const fmpz_poly_t A, + const fmpz_poly_t B, slong n) +{ + fmpz *a, *b; + ulong flags = UWORD(0); /* 2^0 for a, 2^1 for b */ + + if (Q == A) + { + fmpz_poly_t t; + fmpz_poly_init2(t, n); + fmpz_poly_div_series(t, A, B, n); + fmpz_poly_swap(Q, t); + fmpz_poly_clear(t); + return; + } + + fmpz_poly_fit_length(Q, n); + + if (A->length >= n) + { + a = A->coeffs; + } + else + { + slong i; + a = (fmpz *) flint_malloc(n * sizeof(fmpz)); + for (i = 0; i < A->length; i++) + a[i] = A->coeffs[i]; + flint_mpn_zero((mp_ptr) a + A->length, n - A->length); + flags |= UWORD(1); + } + + if (B->length >= n) + { + b = B->coeffs; + } + else + { + slong i; + b = (fmpz *) flint_malloc(n * sizeof(fmpz)); + for (i = 0; i < B->length; i++) + b[i] = B->coeffs[i]; + flint_mpn_zero((mp_ptr) b + B->length, n - B->length); + flags |= UWORD(2); + } + + _fmpz_poly_div_series(Q->coeffs, a, b, n); + + _fmpz_poly_set_length(Q, n); + _fmpz_poly_normalise(Q); + + if ((flags & UWORD(1))) + flint_free(a); + if ((flags & UWORD(2))) + flint_free(b); +} + diff --git a/external/flint-2.4.3/fmpz_poly/divides.c b/external/flint-2.4.3/fmpz_poly/divides.c new file mode 100644 index 0000000..59e682e --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/divides.c @@ -0,0 +1,87 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +int _fmpz_poly_divides(fmpz * q, const fmpz * a, + slong len1, const fmpz * b, slong len2) +{ + fmpz * r = _fmpz_vec_init(len1); + + _fmpz_poly_divrem(q, r, a, len1, b, len2); + + FMPZ_VEC_NORM(r, len1); + + _fmpz_vec_clear(r, len1); + + return (len1 == 0); +} + +int fmpz_poly_divides(fmpz_poly_t q, const fmpz_poly_t a, const fmpz_poly_t b) +{ + if (fmpz_poly_is_zero(b)) + { + flint_printf("Exception (fmpz_poly_divides). Division by zero.\n"); + abort(); + } + if (fmpz_poly_is_zero(a)) + { + fmpz_poly_zero(q); + return 1; + } + if (a->length < b->length) + { + return 0; + } + + { + const slong lenQ = a->length - b->length + 1; + int res; + + if (q == a || q == b) + { + fmpz_poly_t t; + + fmpz_poly_init2(t, lenQ); + res = _fmpz_poly_divides(t->coeffs, a->coeffs, a->length, b->coeffs, b->length); + _fmpz_poly_set_length(t, lenQ); + _fmpz_poly_normalise(t); + fmpz_poly_swap(q, t); + fmpz_poly_clear(t); + } + else + { + fmpz_poly_fit_length(q, lenQ); + res = _fmpz_poly_divides(q->coeffs, a->coeffs, a->length, b->coeffs, b->length); + _fmpz_poly_set_length(q, lenQ); + _fmpz_poly_normalise(q); + } + return res; + } +} diff --git a/external/flint-2.4.3/fmpz_poly/divrem.c b/external/flint-2.4.3/fmpz_poly/divrem.c new file mode 100644 index 0000000..00f65c3 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/divrem.c @@ -0,0 +1,99 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void _fmpz_poly_divrem(fmpz * Q, fmpz * R, + const fmpz * A, slong lenA, const fmpz * B, slong lenB) +{ + if (lenB < 6) + _fmpz_poly_divrem_basecase(Q, R, A, lenA, B, lenB); + else + _fmpz_poly_divrem_divconquer(Q, R, A, lenA, B, lenB); +} + +void fmpz_poly_divrem(fmpz_poly_t Q, fmpz_poly_t R, + const fmpz_poly_t A, const fmpz_poly_t B) +{ + const slong lenA = A->length, lenB = B->length; + fmpz *q, *r; + + if (lenB == 0) + { + flint_printf("Exception (fmpz_poly_divrem). Division by zero.\n"); + abort(); + } + + if (lenA < lenB) + { + fmpz_poly_set(R, A); + fmpz_poly_zero(Q); + return; + } + + if (Q == A || Q == B) + { + q = _fmpz_vec_init(lenA - lenB + 1); + } + else + { + fmpz_poly_fit_length(Q, lenA - lenB + 1); + q = Q->coeffs; + } + + if (R == A || R == B) + { + r = _fmpz_vec_init(lenA); + } + else + { + fmpz_poly_fit_length(R, lenA); + r = R->coeffs; + } + + _fmpz_poly_divrem(q, r, A->coeffs, lenA, B->coeffs, lenB); + + if (Q == A || Q == B) + { + _fmpz_vec_clear(Q->coeffs, Q->alloc); + Q->coeffs = q; + Q->alloc = lenA - lenB + 1; + } + if (R == A || R == B) + { + _fmpz_vec_clear(R->coeffs, R->alloc); + R->coeffs = r; + R->alloc = lenB - 1; + } + _fmpz_poly_set_length(Q, lenA - lenB + 1); + _fmpz_poly_set_length(R, lenA); + _fmpz_poly_normalise(Q); + _fmpz_poly_normalise(R); +} diff --git a/external/flint-2.4.3/fmpz_poly/divrem_basecase.c b/external/flint-2.4.3/fmpz_poly/divrem_basecase.c new file mode 100644 index 0000000..03648bc --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/divrem_basecase.c @@ -0,0 +1,122 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void +_fmpz_poly_divrem_basecase(fmpz * Q, fmpz * R, const fmpz * A, slong lenA, + const fmpz * B, slong lenB) +{ + const fmpz * leadB = B + (lenB - 1); + slong iQ, iR; + + if (R != A) + _fmpz_vec_set(R, A, lenA); + + for (iQ = lenA - lenB, iR = lenA - 1; iQ >= 0; iQ--, iR--) + { + if (fmpz_cmpabs(R + iR, leadB) < 0) + fmpz_zero(Q + iQ); + else + { + fmpz_fdiv_q(Q + iQ, R + iR, leadB); + _fmpz_vec_scalar_submul_fmpz(R + iQ, B, lenB, Q + iQ); + } + } +} + +void +fmpz_poly_divrem_basecase(fmpz_poly_t Q, fmpz_poly_t R, + const fmpz_poly_t A, const fmpz_poly_t B) +{ + slong lenq, lenr; + fmpz *q, *r; + + if (B->length == 0) + { + flint_printf("Exception (fmpz_poly_divrem_basecase). Division by zero.\n"); + abort(); + } + if (Q == R) + { + flint_printf("Exception (fmpz_poly_divrem_basecase). \n" + "Output arguments Q and R may not be aliased.\n"); + abort(); + } + if (A->length < B->length) + { + fmpz_poly_set(R, A); + fmpz_poly_zero(Q); + return; + } + + lenq = A->length - B->length + 1; + lenr = A->length; + if (Q == A || Q == B) + q = _fmpz_vec_init(lenq); + else + { + fmpz_poly_fit_length(Q, lenq); + q = Q->coeffs; + } + if (R == B) + r = _fmpz_vec_init(lenr); + else + { + fmpz_poly_fit_length(R, lenr); + r = R->coeffs; + } + + _fmpz_poly_divrem_basecase(q, r, A->coeffs, A->length, + B->coeffs, B->length); + + if (Q == A || Q == B) + { + _fmpz_vec_clear(Q->coeffs, Q->alloc); + Q->coeffs = q; + Q->alloc = lenq; + Q->length = lenq; + } + else + _fmpz_poly_set_length(Q, lenq); + if (R == B) + { + _fmpz_vec_clear(R->coeffs, R->alloc); + R->coeffs = r; + R->alloc = lenr; + R->length = lenr; + } + else + _fmpz_poly_set_length(R, lenr); + + _fmpz_poly_normalise(Q); + _fmpz_poly_normalise(R); +} diff --git a/external/flint-2.4.3/fmpz_poly/divrem_divconquer.c b/external/flint-2.4.3/fmpz_poly/divrem_divconquer.c new file mode 100644 index 0000000..be2bee4 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/divrem_divconquer.c @@ -0,0 +1,194 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2012 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + + +static void +__fmpz_poly_divrem_divconquer(fmpz * Q, fmpz * R, + const fmpz * A, slong lenA, + const fmpz * B, slong lenB) +{ + if (lenA < 2 * lenB - 1) + { + /* + Convert unbalanced division into a 2 n1 - 1 by n1 division + */ + + const slong n1 = lenA - lenB + 1; + const slong n2 = lenB - n1; + + const fmpz * p1 = A + n2; + const fmpz * d1 = B + n2; + const fmpz * d2 = B; + + fmpz * W = _fmpz_vec_init((2 * n1 - 1) + lenB - 1); + + fmpz * d1q1 = R + n2; + fmpz * d2q1 = W + (2 * n1 - 1); + + _fmpz_poly_divrem_divconquer_recursive(Q, d1q1, W, p1, d1, n1); + + /* + Compute d2q1 = Q d2, of length lenB - 1 + */ + + if (n1 >= n2) + _fmpz_poly_mul(d2q1, Q, n1, d2, n2); + else + _fmpz_poly_mul(d2q1, d2, n2, Q, n1); + + /* + Compute BQ = d1q1 * x^n1 + d2q1, of length lenB - 1; + then compute R = A - BQ + */ + + _fmpz_vec_swap(R, d2q1, n2); + _fmpz_vec_add(R + n2, R + n2, d2q1 + n2, n1 - 1); + _fmpz_vec_sub(R, A, R, lenA); + + _fmpz_vec_clear(W, (2 * n1 - 1) + lenB - 1); + } + else /* lenA = 2 * lenB - 1 */ + { + fmpz * W = _fmpz_vec_init(lenA); + + _fmpz_poly_divrem_divconquer_recursive(Q, R, W, A, B, lenB); + _fmpz_vec_sub(R, A, R, lenA); + + _fmpz_vec_clear(W, lenA); + } +} + +void _fmpz_poly_divrem_divconquer(fmpz *Q, fmpz *R, + const fmpz *A, slong lenA, + const fmpz *B, slong lenB) +{ + if (lenA <= 2 * lenB - 1) + { + __fmpz_poly_divrem_divconquer(Q, R, A, lenA, B, lenB); + } + else /* lenA > 2 * lenB - 1 */ + { + slong shift, n = 2 * lenB - 1; + fmpz *QB, *W; + + _fmpz_vec_set(R, A, lenA); + W = _fmpz_vec_init(2 * n); + QB = W + n; + + while (lenA >= n) + { + shift = lenA - n; + _fmpz_poly_divrem_divconquer_recursive(Q + shift, QB, + W, R + shift, B, lenB); + _fmpz_vec_sub(R + shift, R + shift, QB, n); + lenA -= lenB; + } + + if (lenA >= lenB) + { + __fmpz_poly_divrem_divconquer(Q, W, R, lenA, B, lenB); + _fmpz_vec_swap(W, R, lenA); + } + + _fmpz_vec_clear(W, 2 * n); + } +} + +void +fmpz_poly_divrem_divconquer(fmpz_poly_t Q, fmpz_poly_t R, + const fmpz_poly_t A, const fmpz_poly_t B) +{ + const slong lenA = A->length; + const slong lenB = B->length; + fmpz_poly_t tQ, tR; + fmpz *q, *r; + + if (lenB == 0) + { + flint_printf("Exception (fmpz_poly_divrem_divconquer). Division by zero.\n"); + abort(); + } + + if (lenA < lenB) + { + fmpz_poly_set(R, A); + fmpz_poly_zero(Q); + return; + } + + if (Q == A || Q == B) + { + fmpz_poly_init2(tQ, lenA - lenB + 1); + q = tQ->coeffs; + } + else + { + fmpz_poly_fit_length(Q, lenA - lenB + 1); + q = Q->coeffs; + } + + if (R == A || R == B) + { + fmpz_poly_init2(tR, lenA); + r = tR->coeffs; + } + else + { + fmpz_poly_fit_length(R, lenA); + r = R->coeffs; + } + + _fmpz_poly_divrem_divconquer(q, r, A->coeffs, lenA, B->coeffs, lenB); + + if (Q == A || Q == B) + { + _fmpz_poly_set_length(tQ, lenA - lenB + 1); + fmpz_poly_swap(tQ, Q); + fmpz_poly_clear(tQ); + } + else + _fmpz_poly_set_length(Q, lenA - lenB + 1); + + if (R == A || R == B) + { + _fmpz_poly_set_length(tR, lenA); + fmpz_poly_swap(tR, R); + fmpz_poly_clear(tR); + } + else + _fmpz_poly_set_length(R, lenA); + + _fmpz_poly_normalise(Q); + _fmpz_poly_normalise(R); +} diff --git a/external/flint-2.4.3/fmpz_poly/divrem_divconquer_recursive.c b/external/flint-2.4.3/fmpz_poly/divrem_divconquer_recursive.c new file mode 100644 index 0000000..2f61a3e --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/divrem_divconquer_recursive.c @@ -0,0 +1,137 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +#define FLINT_DIVREM_DIVCONQUER_CUTOFF 16 + +void +_fmpz_poly_divrem_divconquer_recursive(fmpz * Q, fmpz * BQ, fmpz * W, + const fmpz * A, const fmpz * B, + slong lenB) +{ + if (lenB <= FLINT_DIVREM_DIVCONQUER_CUTOFF) + { + _fmpz_vec_zero(BQ, lenB - 1); + _fmpz_vec_set(BQ + (lenB - 1), A + (lenB - 1), lenB); + + _fmpz_poly_divrem_basecase(Q, BQ, BQ, 2 * lenB - 1, B, lenB); + + _fmpz_vec_neg(BQ, BQ, lenB - 1); + _fmpz_vec_sub(BQ + (lenB - 1), A + (lenB - 1), BQ + (lenB - 1), lenB); + } + else + { + const slong n2 = lenB / 2; + const slong n1 = lenB - n2; + + fmpz * W1 = W; + fmpz * W2 = W + lenB; + + const fmpz * p1 = A + 2 * n2; + const fmpz * p2; + const fmpz * d1 = B + n2; + const fmpz * d2 = B; + const fmpz * d3 = B + n1; + const fmpz * d4 = B; + + fmpz * q1 = Q + n2; + fmpz * q2 = Q; + fmpz * dq1 = BQ + n2; + fmpz * d1q1 = BQ + 2 * n2; + + fmpz *d2q1, *d3q2, *d4q2, *t; + + /* + Set q1 to p1 div d1, a 2 n1 - 1 by n1 division so q1 ends up + being of length n1; d1q1 = d1 q1 is of length 2 n1 - 1 + */ + + _fmpz_poly_divrem_divconquer_recursive(q1, d1q1, W1, p1, d1, n1); + + /* + Compute d2q1 = d2 q1, of length lenB - 1 + */ + + d2q1 = W1; + _fmpz_poly_mul(d2q1, q1, n1, d2, n2); + + /* + Compute dq1 = d1 q1 x^n2 + d2 q1, of length 2 n1 + n2 - 1 + */ + + _fmpz_vec_swap(dq1, d2q1, n2); + _fmpz_vec_add(dq1 + n2, dq1 + n2, d2q1 + n2, n1 - 1); + + /* + Compute t = A/x^n2 - dq1, which has length 2 n1 + n2 - 1, but we + are not interested in the top n1 coeffs as they will be zero, so + this has effective length n1 + n2 - 1 + + For the following division, we want to set {p2, 2 n2 - 1} to the + top 2 n2 - 1 coeffs of this + + Since the bottom n2 - 1 coeffs of p2 are irrelevant for the + division, we in fact set {t, n2} to the relevant coeffs + */ + + t = BQ; + _fmpz_vec_sub(t, A + n2 + (n1 - 1), dq1 + (n1 - 1), n2); + p2 = t - (n2 - 1); + + /* + Compute q2 = t div d3, a 2 n2 - 1 by n2 division, so q2 will have + length n2; let d3q2 = d3 q2, of length 2 n2 - 1 + */ + + d3q2 = W1; + _fmpz_poly_divrem_divconquer_recursive(q2, d3q2, W2, p2, d3, n2); + + /* + Compute d4q2 = d4 q2, of length n1 + n2 - 1 = lenB - 1 + */ + + d4q2 = W2; + _fmpz_poly_mul(d4q2, d4, n1, q2, n2); + + /* + Compute dq2 = d3q2 x^n1 + d4q2, of length n1 + 2 n2 - 1 + */ + + _fmpz_vec_swap(BQ, d4q2, n2); + _fmpz_vec_add(BQ + n2, BQ + n2, d4q2 + n2, n1 - 1); + _fmpz_vec_add(BQ + n1, BQ + n1, d3q2, 2 * n2 - 1); + + /* + Note Q = q1 x^n2 + q2, and BQ = dq1 x^n2 + dq2 + */ + } +} diff --git a/external/flint-2.4.3/fmpz_poly/divrem_preinv.c b/external/flint-2.4.3/fmpz_poly/divrem_preinv.c new file mode 100644 index 0000000..c2a4585 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/divrem_preinv.c @@ -0,0 +1,113 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +void +_fmpz_poly_divrem_preinv(fmpz * Q, fmpz * A, slong len1, + const fmpz * B, const fmpz * B_inv, slong len2) +{ + slong n = len1 - len2 + 1; + fmpz * P = _fmpz_vec_init(len2 - 1); + + _fmpz_poly_div_preinv(Q, A, len1, B, B_inv, len2); + + if (len2 - 1 > n) + _fmpz_poly_mullow(P, B, len2 - 1, Q, n, len2 - 1); + else + _fmpz_poly_mullow(P, Q, n, B, len2 - 1, len2 - 1); + + _fmpz_poly_sub(A, A, len2 - 1, P, len2 - 1); + + _fmpz_vec_clear(P, len2 - 1); +} + +void +fmpz_poly_divrem_preinv(fmpz_poly_t Q, fmpz_poly_t R, const fmpz_poly_t A, + const fmpz_poly_t B, const fmpz_poly_t B_inv) +{ + fmpz_poly_t tQ, tR; + fmpz *q, *r; + slong len1 = A->length, len2 = B->length; + slong qlen = len1 - len2 + 1; + + if (len1 < len2) + { + fmpz_poly_zero(Q); + fmpz_poly_set(R, A); + return; + } + + if (Q == A || Q == B || Q == B_inv) + { + fmpz_poly_init2(tQ, qlen); + q = tQ->coeffs; + } + else + { + fmpz_poly_fit_length(Q, qlen); + q = Q->coeffs; + } + + if (R == B || R == B_inv) + { + fmpz_poly_init2(tR, len1); + r = tR->coeffs; + } + else + { + fmpz_poly_fit_length(R, len1); + r = R->coeffs; + } + + if (R == B || R == B_inv || R != A) + _fmpz_vec_set(r, A->coeffs, A->length); + + _fmpz_poly_divrem_preinv(q, r, len1, B->coeffs, B_inv->coeffs, len2); + + if (Q == A || Q == B || Q == B_inv) + { + _fmpz_poly_set_length(tQ, qlen); + fmpz_poly_swap(tQ, Q); + fmpz_poly_clear(tQ); + } + else + _fmpz_poly_set_length(Q, qlen); + + if (R == B || R == B_inv) + { + _fmpz_poly_set_length(tR, len2 - 1); + fmpz_poly_swap(tR, R); + fmpz_poly_clear(tR); + } + else + _fmpz_poly_set_length(R, len2 - 1); + + /* no need to normalise Q */ + _fmpz_poly_normalise(R); +} diff --git a/external/flint-2.4.3/fmpz_poly/divremlow_divconquer_recursive.c b/external/flint-2.4.3/fmpz_poly/divremlow_divconquer_recursive.c new file mode 100644 index 0000000..a1482e1 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/divremlow_divconquer_recursive.c @@ -0,0 +1,151 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +#define FLINT_DIVREMLOW_DIVCONQUER_CUTOFF 16 + +void +_fmpz_poly_divremlow_divconquer_recursive(fmpz * Q, fmpz * QB, + const fmpz * A, const fmpz * B, slong lenB) +{ + if (lenB <= FLINT_DIVREMLOW_DIVCONQUER_CUTOFF) + { + _fmpz_poly_divrem_basecase(Q, QB, A, 2 * lenB - 1, B, lenB); + _fmpz_vec_sub(QB, A, QB, lenB - 1); + } + else + { + const slong n2 = lenB / 2; + const slong n1 = lenB - n2; + + const fmpz * p1 = A + 2 * n2; + const fmpz * p2; + const fmpz * d1 = B + n2; + const fmpz * d2 = B; + + fmpz * q1 = Q + n2; + fmpz * q2 = Q; + + /* + Think of the top lenB coefficients of QB as temporary space; this + code will not depend on {QB, lenB - 1} and W being adjacent + */ + + fmpz * W = QB + (lenB - 1); + + fmpz *d1q1, *d2q1, *t, *d3q2, *d4q2; + + /* + Set q1 to p1 div d1, a 2 n1 - 1 by n1 division, so q1 has length + at most n1; {W, n1 - 1} is d1 * q1 is truncated to length n1 - 1 + */ + + _fmpz_poly_divremlow_divconquer_recursive(q1, W, p1, d1, n1); + + /* + W is of length lenB, but we only care about the bottom n1 - 1 + coeffs, which we push up by n2 + 1, to the very top; we do this + manually here instead of via _fmpz_vec_swap() because the source + and destination arrays overlap + */ + + d1q1 = W + (n2 + 1); + + { + slong i; + for (i = 0; i < n1 - 1; i++) + fmpz_swap(d1q1 + i, W + i); + } + + /* + Compute d2q1 = d2 * q1, of length at most lenB - 1; we'll need the + top n2 coeffs for t and the bottom n1 - 1 coeffs for QB + */ + + d2q1 = QB; + + _fmpz_poly_mul(d2q1, q1, n1, d2, n2); + + /* + Compute {t - (n2 - 1), 2 n2 - 1} to be the top 2 n2 - 1 coeffs of + + A / x^n2 - (d1q1 x^n2 + d2q1). + + Note that actually the bottom n2 - 1 coeffs may be arbitrary + */ + + t = W + n1; + + if (n1 == n2) + fmpz_zero(t); + _fmpz_vec_add(t, t, d2q1 + (n1 - 1), n2); + _fmpz_vec_neg(t, t, n2); + _fmpz_vec_add(t, t, A + (n1 + n2 - 1), n2); + + p2 = t - (n2 - 1); + + /* + Move {QB, n1 - 1} into the bottom coefficients of W, so that + we can use {QB, 2 n2 - 1} as space in the next division + */ + + _fmpz_vec_swap(QB, W, n1 - 1); + + /* + Compute q2 = t div {B + n1}, a 2 n2 - 1 by n2 division + */ + + d3q2 = QB; + + _fmpz_poly_divremlow_divconquer_recursive(q2, d3q2, p2, B + n1, n2); + + _fmpz_vec_swap(QB + n1, d3q2, n2 - 1); + + if (lenB & WORD(1)) + fmpz_zero(QB + n2); + _fmpz_vec_add(QB + n2, QB + n2, W, n1 - 1); + + /* + Compute {d4q2, lenB - 1} as {B, n1} * {q2, n2}; then move the + bottom n2 coeffs of this into {QB, n2}, and add the top n1 - 1 + coeffs to {QB + n2, n1 - 1} + */ + + d4q2 = W; + + _fmpz_poly_mul(d4q2, B, n1, q2, n2); + + _fmpz_vec_swap(QB, d4q2, n2); + _fmpz_vec_add(QB + n2, QB + n2, d4q2 + n2, n1 - 1); + } +} + diff --git a/external/flint-2.4.3/fmpz_poly/doc/fmpz_poly.txt b/external/flint-2.4.3/fmpz_poly/doc/fmpz_poly.txt new file mode 100644 index 0000000..e618ac0 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/doc/fmpz_poly.txt @@ -0,0 +1,2848 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +******************************************************************************* + + Memory management + +******************************************************************************* + +void fmpz_poly_init(fmpz_poly_t poly) + + Initialises \code{poly} for use, setting its length to zero. + A corresponding call to\\ \code{fmpz_poly_clear()} must be made after + finishing with the \code{fmpz_poly_t} to free the memory used by + the polynomial. + +void fmpz_poly_init2(fmpz_poly_t poly, slong alloc) + + Initialises \code{poly} with space for at least \code{alloc} coefficients + and sets the length to zero. The allocated coefficients are all set to + zero. + +void fmpz_poly_realloc(fmpz_poly_t poly, slong alloc) + + Reallocates the given polynomial to have space for \code{alloc} + coefficients. If \code{alloc} is zero the polynomial is cleared + and then reinitialised. If the current length is greater than + \code{alloc} the polynomial is first truncated to length \code{alloc}. + +void fmpz_poly_fit_length(fmpz_poly_t poly, slong len) + + If \code{len} is greater than the number of coefficients currently + allocated, then the polynomial is reallocated to have space for at + least \code{len} coefficients. No data is lost when calling this + function. + + The function efficiently deals with the case where \code{fit_length} is + called many times in small increments by at least doubling the number + of allocated coefficients when length is larger than the number of + coefficients currently allocated. + +void fmpz_poly_clear(fmpz_poly_t poly) + + Clears the given polynomial, releasing any memory used. It must + be reinitialised in order to be used again. + +void _fmpz_poly_normalise(fmpz_poly_t poly) + + Sets the length of \code{poly} so that the top coefficient is non-zero. + If all coefficients are zero, the length is set to zero. This function + is mainly used internally, as all functions guarantee normalisation. + +void _fmpz_poly_set_length(fmpz_poly_t poly, slong newlen) + + Demotes the coefficients of \code{poly} beyond \code{newlen} and sets + the length of \code{poly} to \code{newlen}. + +******************************************************************************* + + Polynomial parameters + +******************************************************************************* + +slong fmpz_poly_length(const fmpz_poly_t poly) + + Returns the length of \code{poly}. The zero polynomial has length zero. + +slong fmpz_poly_degree(const fmpz_poly_t poly) + + Returns the degree of \code{poly}, which is one less than its length. + +******************************************************************************* + + Assignment and basic manipulation + +******************************************************************************* + +void fmpz_poly_set(fmpz_poly_t poly1, const fmpz_poly_t poly2) + + Sets \code{poly1} to equal \code{poly2}. + +void fmpz_poly_set_si(fmpz_poly_t poly, slong c) + + Sets \code{poly} to the signed integer \code{c}. + +void fmpz_poly_set_ui(fmpz_poly_t poly, ulong c) + + Sets \code{poly} to the unsigned integer \code{c}. + +void fmpz_poly_set_fmpz(fmpz_poly_t poly, const fmpz_t c) + + Sets \code{poly} to the integer \code{c}. + +void fmpz_poly_set_mpz(fmpz_poly_t poly, const mpz_t c) + + Sets \code{poly} to the integer \code{c}. + +int _fmpz_poly_set_str(fmpz * poly, const char * str) + + Sets \code{poly} to the polynomial encoded in the null-terminated + string \code{str}. Assumes that \code{poly} is allocated as a + sufficiently large array suitable for the number of coefficients + present in \code{str}. + + Returns $0$ if no error occurred. Otherwise, returns a non-zero + value, in which case the resulting value of \code{poly} is undefined. + If \code{str} is not null-terminated, calling this method might result + in a segmentation fault. + +int fmpz_poly_set_str(fmpz_poly_t poly, const char * str) + + Imports a polynomial from a null-terminated string. If the string + \code{str} represents a valid polynomial returns $1$, otherwise + returns $0$. + + Returns $0$ if no error occurred. Otherwise, returns a non-zero value, + in which case the resulting value of \code{poly} is undefined. If + \code{str} is not null-terminated, calling this method might result in + a segmentation fault. + +char * _fmpz_poly_get_str(const fmpz * poly, slong len) + + Returns the plain FLINT string representation of the polynomial + \code{(poly, len)}. + +char * fmpz_poly_get_str(const fmpz_poly_t poly) + + Returns the plain FLINT string representation of the polynomial + \code{poly}. + +char * _fmpz_poly_get_str_pretty(const fmpz * poly, slong len, const char * x) + + Returns a pretty representation of the polynomial + \code{(poly, len)} using the null-terminated string~\code{x} as the + variable name. + +char * fmpz_poly_get_str_pretty(const fmpz_poly_t poly, const char * x) + + Returns a pretty representation of the polynomial~\code{poly} using the + null-terminated string \code{x} as the variable name. + +void fmpz_poly_zero(fmpz_poly_t poly) + + Sets \code{poly} to the zero polynomial. + +void fmpz_poly_one(fmpz_poly_t poly) + + Sets \code{poly} to the constant polynomial one. + +void fmpz_poly_zero_coeffs(fmpz_poly_t poly, slong i, slong j) + + Sets the coefficients of $x^i, \dotsc, x^{j-1}$ to zero. + +void fmpz_poly_swap(fmpz_poly_t poly1, fmpz_poly_t poly2) + + Swaps \code{poly1} and \code{poly2}. This is done efficiently without + copying data by swapping pointers, etc. + +void _fmpz_poly_reverse(fmpz * res, const fmpz * poly, slong len, slong n) + + Sets \code{(res, n)} to the reverse of \code{(poly, n)}, where + \code{poly} is in fact an array of length \code{len}. Assumes that + \code{0 < len <= n}. Supports aliasing of \code{res} and \code{poly}, + but the behaviour is undefined in case of partial overlap. + +void fmpz_poly_reverse(fmpz_poly_t res, const fmpz_poly_t poly, slong n) + + This function considers the polynomial \code{poly} to be of length $n$, + notionally truncating and zero padding if required, and reverses + the result. Since the function normalises its result \code{res} may be + of length less than $n$. + +void fmpz_poly_truncate(fmpz_poly_t poly, slong newlen) + + If the current length of \code{poly} is greater than \code{newlen}, it + is truncated to have the given length. Discarded coefficients are not + necessarily set to zero. + +******************************************************************************* + + Randomisation + +******************************************************************************* + +void fmpz_poly_randtest(fmpz_poly_t f, flint_rand_t state, + slong len, mp_bitcnt_t bits) + + Sets $f$ to a random polynomial with up to the given length and where + each coefficient has up to the given number of bits. The coefficients + are signed randomly. One must call \code{flint_randinit()} before + calling this function. + +void fmpz_poly_randtest_unsigned(fmpz_poly_t f, flint_rand_t state, + slong len, mp_bitcnt_t bits) + + Sets $f$ to a random polynomial with up to the given length and where + each coefficient has up to the given number of bits. One must call + \code{flint_randinit()} before calling this function. + +void fmpz_poly_randtest_not_zero(fmpz_poly_t f, flint_rand_t state, + slong len, mp_bitcnt_t bits) + + As for \code{fmpz_poly_randtest()} except that \code{len} and bits may + not be zero and the polynomial generated is guaranteed not to be the + zero polynomial. One must call \code{flint_randinit()} before + calling this function. + +******************************************************************************* + + Getting and setting coefficients + +******************************************************************************* + +void fmpz_poly_get_coeff_fmpz(fmpz_t x, const fmpz_poly_t poly, slong n) + + Sets $x$ to the $n$th coefficient of \code{poly}. Coefficient + numbering is from zero and if $n$ is set to a value beyond the end of + the polynomial, zero is returned. + +slong fmpz_poly_get_coeff_si(const fmpz_poly_t poly, slong n) + + Returns coefficient $n$ of \code{poly} as a \code{slong}. The result is + undefined if the value does not fit into a \code{slong}. Coefficient + numbering is from zero and if $n$ is set to a value beyond the end of + the polynomial, zero is returned. + +ulong fmpz_poly_get_coeff_ui(const fmpz_poly_t poly, slong n) + + Returns coefficient $n$ of \code{poly} as a \code{ulong}. The result is + undefined if the value does not fit into a \code{ulong}. Coefficient + numbering is from zero and if $n$ is set to a value beyond the end of the + polynomial, zero is returned. + +fmpz * fmpz_poly_get_coeff_ptr(const fmpz_poly_t poly, slong n) + + Returns a reference to the coefficient of $x^n$ in the polynomial, + as an \code{fmpz *}. This function is provided so that individual + coefficients can be accessed and operated on by functions in the + \code{fmpz} module. This function does not make a copy of the + data, but returns a reference to the actual coefficient. + + Returns \code{NULL} when $n$ exceeds the degree of the polynomial. + + This function is implemented as a macro. + +fmpz * fmpz_poly_lead(const fmpz_poly_t poly) + + Returns a reference to the leading coefficient of the polynomial, + as an \code{fmpz *}. This function is provided so that the leading + coefficient can be easily accessed and operated on by functions in + the \code{fmpz} module. This function does not make a copy of the + data, but returns a reference to the actual coefficient. + + Returns \code{NULL} when the polynomial is zero. + + This function is implemented as a macro. + +void fmpz_poly_set_coeff_fmpz(fmpz_poly_t poly, slong n, const fmpz_t x) + + Sets coefficient $n$ of \code{poly} to the \code{fmpz} value \code{x}. + Coefficient numbering starts from zero and if $n$ is beyond the current + length of \code{poly} then the polynomial is extended and zero + coefficients inserted if necessary. + +void fmpz_poly_set_coeff_si(fmpz_poly_t poly, slong n, slong x) + + Sets coefficient $n$ of \code{poly} to the \code{slong} value \code{x}. + Coefficient numbering starts from zero and if $n$ is beyond the current + length of \code{poly} then the polynomial is extended and zero + coefficients inserted if necessary. + +void fmpz_poly_set_coeff_ui(fmpz_poly_t poly, slong n, ulong x) + + Sets coefficient $n$ of \code{poly} to the \code{ulong} value + \code{x}. Coefficient numbering starts from zero and if $n$ is beyond + the current length of \code{poly} then the polynomial is extended and + zero coefficients inserted if necessary. + +******************************************************************************* + + Comparison + +******************************************************************************* + +int fmpz_poly_equal(const fmpz_poly_t poly1, const fmpz_poly_t poly2) + + Returns $1$ if \code{poly1} is equal to \code{poly2}, otherwise + returns $0$. The polynomials are assumed to be normalised. + +int fmpz_poly_is_zero(const fmpz_poly_t poly) + + Returns $1$ if the polynomial is zero and $0$ otherwise. + + This function is implemented as a macro. + +int fmpz_poly_is_one(const fmpz_poly_t poly) + + Returns $1$ if the polynomial is one and $0$ otherwise. + +int fmpz_poly_is_unit(const fmpz_poly_t poly) + + Returns $1$ is the polynomial is the constant polynomial $\pm 1$, + and $0$ otherwise. + +******************************************************************************* + + Addition and subtraction + +******************************************************************************* + +void _fmpz_poly_add(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2) + + Sets \code{res} to the sum of \code{(poly1, len1)} and + \code{(poly2, len2)}. It is assumed that \code{res} has + sufficient space for the longer of the two polynomials. + +void fmpz_poly_add(fmpz_poly_t res, const fmpz_poly_t poly1, + const fmpz_poly_t poly2) + + Sets \code{res} to the sum of \code{poly1} and \code{poly2}. + +void _fmpz_poly_sub(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2) + + Sets \code{res} to \code{(poly1, len1)} minus \code{(poly2, len2)}. It + is assumed that \code{res} has sufficient space for the longer of the + two polynomials. + +void fmpz_poly_sub(fmpz_poly_t res, const fmpz_poly_t poly1, + const fmpz_poly_t poly2) + + Sets \code{res} to \code{poly1} minus \code{poly2}. + +void fmpz_poly_neg(fmpz_poly_t res, const fmpz_poly_t poly) + + Sets \code{res} to \code{-poly}. + +******************************************************************************* + + Scalar multiplication and division + +******************************************************************************* + +void fmpz_poly_scalar_mul_fmpz(fmpz_poly_t poly1, + const fmpz_poly_t poly2, const fmpz_t x) + + Sets \code{poly1} to \code{poly2} times $x$. + +void fmpz_poly_scalar_mul_mpz(fmpz_poly_t poly1, + const fmpz_poly_t poly2, const mpz_t x) + + Sets \code{poly1} to \code{poly2} times the \code{mpz_t} $x$. + +void fmpz_poly_scalar_mul_si(fmpz_poly_t poly1, fmpz_poly_t poly2, slong x) + + Sets \code{poly1} to \code{poly2} times the signed \code{slong x}. + +void fmpz_poly_scalar_mul_ui(fmpz_poly_t poly1, fmpz_poly_t poly2, ulong x) + + Sets \code{poly1} to \code{poly2} times the \code{ulong x}. + +void fmpz_poly_scalar_mul_2exp(fmpz_poly_t poly1, fmpz_poly_t poly2, ulong exp) + + Sets \code{poly1} to \code{poly2} times \code{2^exp}. + +void fmpz_poly_scalar_addmul_fmpz(fmpz_poly_t poly1, const fmpz_poly_t poly2, + const fmpz_t x) + + Sets \code{poly} to \code{poly1 + x * poly2}. + +void fmpz_poly_scalar_submul_fmpz(fmpz_poly_t poly1, const fmpz_poly_t poly2, + const fmpz_t x) + + Sets \code{poly} to \code{poly1 - x * poly2}. + +void fmpz_poly_scalar_fdiv_fmpz(fmpz_poly_t poly1, + const fmpz_poly_t poly2, const fmpz_t x) + + Sets \code{poly1} to \code{poly2} divided by the \code{fmpz_t x}, + rounding coefficients down toward~$- \infty$. + +void fmpz_poly_scalar_fdiv_mpz(fmpz_poly_t poly1, + const fmpz_poly_t poly2, const mpz_t x) + + Sets \code{poly1} to \code{poly2} divided by the \code{mpz_t x}, + rounding coefficients down toward~$- \infty$. + +void fmpz_poly_scalar_fdiv_si(fmpz_poly_t poly1, fmpz_poly_t poly2, slong x) + + Sets \code{poly1} to \code{poly2} divided by the \code{slong x}, + rounding coefficients down toward~$- \infty$. + +void fmpz_poly_scalar_fdiv_ui(fmpz_poly_t poly1, fmpz_poly_t poly2, ulong x) + + Sets \code{poly1} to \code{poly2} divided by the \code{ulong x}, + rounding coefficients down toward~$- \infty$. + +void fmpz_poly_scalar_fdiv_2exp(fmpz_poly_t poly1, fmpz_poly_t poly2, ulong x) + + Sets \code{poly1} to \code{poly2} divided by \code{2^x}, + rounding coefficients down toward~$- \infty$. + +void fmpz_poly_scalar_tdiv_fmpz(fmpz_poly_t poly1, + const fmpz_poly_t poly2, const fmpz_t x) + + Sets \code{poly1} to \code{poly2} divided by the \code{fmpz_t x}, + rounding coefficients toward~$0$. + +void fmpz_poly_scalar_tdiv_si(fmpz_poly_t poly1, fmpz_poly_t poly2, slong x) + + Sets \code{poly1} to \code{poly2} divided by the \code{slong x}, + rounding coefficients toward~$0$. + +void fmpz_poly_scalar_tdiv_ui(fmpz_poly_t poly1, fmpz_poly_t poly2, ulong x) + + Sets \code{poly1} to \code{poly2} divided by the \code{ulong x}, + rounding coefficients toward~$0$. + +void fmpz_poly_scalar_tdiv_2exp(fmpz_poly_t poly1, fmpz_poly_t poly2, ulong x) + + Sets \code{poly1} to \code{poly2} divided by \code{2^x}, + rounding coefficients toward~$0$. + +void fmpz_poly_scalar_divexact_fmpz(fmpz_poly_t poly1, + const fmpz_poly_t poly2, const fmpz_t x) + + Sets \code{poly1} to \code{poly2} divided by the \code{fmpz_t x}, + assuming the division is exact for every coefficient. + +void fmpz_poly_scalar_divexact_mpz(fmpz_poly_t poly1, + const fmpz_poly_t poly2, const mpz_t x) + + Sets \code{poly1} to \code{poly2} divided by the \code{mpz_t x}, + assuming the coefficient is exact for every coefficient. + +id fmpz_poly_scalar_divexact_si(fmpz_poly_t poly1, fmpz_poly_t poly2, slong x) + + Sets \code{poly1} to \code{poly2} divided by the \code{slong x}, + assuming the coefficient is exact for every coefficient. + +void fmpz_poly_scalar_divexact_ui(fmpz_poly_t poly1, + fmpz_poly_t poly2, ulong x) + + Sets \code{poly1} to \code{poly2} divided by the \code{ulong x}, + assuming the coefficient is exact for every coefficient. + +void fmpz_poly_scalar_mod_fmpz(fmpz_poly_t poly1, + const fmpz_poly_t poly2, const fmpz_t p) + + Sets \code{poly1} to \code{poly2}, reducing each coefficient + modulo $p > 0$. + +void fmpz_poly_scalar_smod_fmpz(fmpz_poly_t poly1, + const fmpz_poly_t poly2, const fmpz_t p) + + Sets \code{poly1} to \code{poly2}, symmetrically reducing + each coefficient modulo $p > 0$, that is, choosing the unique + representative in the interval $(-p/2, p/2]$. + +******************************************************************************* + + Bit packing + +******************************************************************************* + +void _fmpz_poly_bit_pack(mp_ptr arr, const fmpz * poly, + slong len, mp_bitcnt_t bit_size, int negate) + + Packs the coefficients of \code{poly} into bitfields of the given + \code{bit_size}, negating the coefficients before packing + if \code{negate} is set to $-1$. + +int _fmpz_poly_bit_unpack(fmpz * poly, slong len, + mp_srcptr arr, mp_bitcnt_t bit_size, int negate) + + Unpacks the polynomial of given length from the array as packed into + fields of the given \code{bit_size}, finally negating the coefficients + if \code{negate} is set to $-1$. Returns borrow, which is nonzero if a + leading term with coefficient $\pm1$ should be added at + position \code{len} of \code{poly}. + +void _fmpz_poly_bit_unpack_unsigned(fmpz * poly, slong len, + mp_srcptr_t arr, mp_bitcnt_t bit_size) + + Unpacks the polynomial of given length from the array as packed into + fields of the given \code{bit_size}. The coefficients are assumed to + be unsigned. + +void fmpz_poly_bit_pack(fmpz_t f, const fmpz_poly_t poly, mp_bitcnt_t bit_size) + + Packs \code{poly} into bitfields of size \code{bit_size}, writing the + result to \code{f}. The sign of \code{f} will be the same as that of + the leading coefficient of \code{poly}. + +void fmpz_poly_bit_unpack(fmpz_poly_t poly, const fmpz_t f, + mp_bitcnt_t bit_size) + + Unpacks the polynomial with signed coefficients packed into + fields of size \code{bit_size} as represented by the integer \code{f}. + +void fmpz_poly_bit_unpack_unsigned(fmpz_poly_t poly, const fmpz_t f, + mp_bitcnt_t bit_size) + + Unpacks the polynomial with unsigned coefficients packed into + fields of size \code{bit_size} as represented by the integer \code{f}. + It is required that \code{f} is nonnegative. + +******************************************************************************* + + Multiplication + +******************************************************************************* + +void _fmpz_poly_mul_classical(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2) + + Sets \code{(res, len1 + len2 - 1)} to the product of \code{(poly1, len1)} + and \code{(poly2, len2)}. + + Assumes \code{len1} and \code{len2} are positive. Allows zero-padding + of the two input polynomials. No aliasing of inputs with outputs is + allowed. + +void fmpz_poly_mul_classical(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2) + + Sets \code{res} to the product of \code{poly1} and \code{poly2}, computed + using the classical or schoolbook method. + +void _fmpz_poly_mullow_classical(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2, slong n) + + Sets \code{(res, n)} to the first $n$ coefficients of \code{(poly1, len1)} + multiplied by \code{(poly2, len2)}. + + Assumes \code{0 < n <= len1 + len2 - 1}. Assumes neither \code{len1} nor + \code{len2} is zero. + +void fmpz_poly_mullow_classical(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2, slong n) + + Sets \code{res} to the first $n$ coefficients of \code{poly1 * poly2}. + +void _fmpz_poly_mulhigh_classical(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2, slong start) + + Sets the first \code{start} coefficients of \code{res} to zero and the + remainder to the corresponding coefficients of + \code{(poly1, len1) * (poly2, len2)}. + + Assumes \code{start <= len1 + len2 - 1}. Assumes neither \code{len1} nor + \code{len2} is zero. + +void fmpz_poly_mulhigh_classical(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2, slong start) + + Sets the first \code{start} coefficients of \code{res} to zero and the + remainder to the corresponding coefficients of the product of \code{poly1} + and \code{poly2}. + +void _fmpz_poly_mulmid_classical(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2) + + Sets \code{res} to the middle \code{len1 - len2 + 1} coefficients of + the product of \code{(poly1, len1)} and \code{(poly2, len2)}, i.e.\ the + coefficients from degree \code{len2 - 1} to \code{len1 - 1} inclusive. + Assumes that \code{len1 >= len2 > 0}. + +void fmpz_poly_mulmid_classical(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2) + + Sets \code{res} to the middle \code{len(poly1) - len(poly2) + 1} + coefficients of \code{poly1 * poly2}, i.e.\ the coefficient from degree + \code{len2 - 1} to \code{len1 - 1} inclusive. Assumes that + \code{len1 >= len2}. + +void _fmpz_poly_mul_karatsuba(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2) + + Sets \code{(res, len1 + len2 - 1)} to the product of \code{(poly1, len1)} + and \code{(poly2, len2)}. Assumes \code{len1 >= len2 > 0}. Allows + zero-padding of the two input polynomials. No aliasing of inputs with + outputs is allowed. + +void fmpz_poly_mul_karatsuba(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2) + + Sets \code{res} to the product of \code{poly1} and \code{poly2}. + +void _fmpz_poly_mullow_karatsuba_n(fmpz * res, const fmpz * poly1, + const fmpz * poly2, slong n) + + Sets \code{res} to the product of \code{poly1} and \code{poly2} and + truncates to the given length. It is assumed that \code{poly1} and + \code{poly2} are precisely the given length, possibly zero padded. + Assumes $n$ is not zero. + +void fmpz_poly_mullow_karatsuba_n(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2, slong n) + + Sets \code{res} to the product of \code{poly1} and \code{poly2} and + truncates to the given length. + +void _fmpz_poly_mulhigh_karatsuba_n(fmpz * res, const fmpz * poly1, + const fmpz * poly2, slong len) + + Sets \code{res} to the product of \code{poly1} and \code{poly2} and + truncates at the top to the given length. The first \code{len - 1} + coefficients are set to zero. It is assumed that \code{poly1} and + \code{poly2} are precisely the given length, possibly zero padded. + Assumes \code{len} is not zero. + +void fmpz_poly_mulhigh_karatsuba_n(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2, slong len) + + Sets the first \code{len - 1} coefficients of the result to zero and the + remaining coefficients to the corresponding coefficients of the product of + \code{poly1} and \code{poly2}. Assumes \code{poly1} and \code{poly2} are + at most of the given length. + +void _fmpz_poly_mul_KS(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2) + + Sets \code{(res, len1 + len2 - 1)} to the product of \code{(poly1, len1)} + and \code{(poly2, len2)}. + + Places no assumptions on \code{len1} and \code{len2}. Allows zero-padding + of the two input polynomials. Supports aliasing of inputs and outputs. + +void fmpz_poly_mul_KS(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2) + + Sets \code{res} to the product of \code{poly1} and \code{poly2}. + +void _fmpz_poly_mullow_KS(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2, slong n) + + Sets \code{(res, n)} to the lowest $n$ coefficients of the product of + \code{(poly1, len1)} and \code{(poly2, len2)}. + + Assumes that \code{len1} and \code{len2} are positive, but does allow + for the polynomials to be zero-padded. The polynomials may be zero, + too. Assumes $n$ is positive. Supports aliasing between \code{res}, + \code{poly1} and \code{poly2}. + +void fmpz_poly_mullow_KS(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2, slong n) + + Sets \code{res} to the lowest $n$ coefficients of the product of + \code{poly1} and \code{poly2}. + +void _fmpz_poly_mul_SS(fmpz * output, const fmpz * input1, slong length1, + const fmpz * input2, slong length2) + + Sets \code{(output, length1 + length2 - 1)} to the product of + \code{(input1, length1)} and \code{(input2, length2)}. + + We must have \code{len1 > 1} and \code{len2 > 1}. Allows zero-padding + of the two input polynomials. Supports aliasing of inputs and outputs. + +void fmpz_poly_mul_SS(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2) + + Sets \code{res} to the product of \code{poly1} and \code{poly2}. Uses the + Sch\"{o}nhage-Strassen algorithm. + +void _fmpz_poly_mullow_SS(fmpz * output, const fmpz * input1, slong length1, + const fmpz * input2, slong length2, slong n) + + Sets \code{(res, n)} to the lowest $n$ coefficients of the product of + \code{(poly1, len1)} and \code{(poly2, len2)}. + + Assumes that \code{len1} and \code{len2} are positive, but does allow + for the polynomials to be zero-padded. We must have \code{len1 > 1} + and \code{len2 > 1}. Assumes $n$ is positive. Supports aliasing between + \code{res}, \code{poly1} and \code{poly2}. + +void fmpz_poly_mullow_SS(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2, slong n) + + Sets \code{res} to the lowest $n$ coefficients of the product of + \code{poly1} and \code{poly2}. + +void _fmpz_poly_mul(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2) + + Sets \code{(res, len1 + len2 - 1)} to the product of \code{(poly1, len1)} + and \code{(poly2, len2)}. Assumes \code{len1 >= len2 > 0}. Allows + zero-padding of the two input polynomials. Does not support aliasing + between the inputs and the output. + + +void fmpz_poly_mul(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2) + + Sets \code{res} to the product of \code{poly1} and \code{poly2}. Chooses + an optimal algorithm from the choices above. + +void _fmpz_poly_mullow(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2, slong n) + + Sets \code{(res, n)} to the lowest $n$ coefficients of the product of + \code{(poly1, len1)} and \code{(poly2, len2)}. + + Assumes \code{len1 >= len2 > 0} and \code{0 < n <= len1 + len2 - 1}. + Allows for zero-padding in the inputs. Does not support aliasing between + the inputs and the output. + +void fmpz_poly_mullow(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2, slong n) + + Sets \code{res} to the lowest $n$ coefficients of the product of + \code{poly1} and \code{poly2}. + +void fmpz_poly_mulhigh_n(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2, slong n) + + Sets the high $n$ coefficients of \code{res} to the high $n$ coefficients + of the product of \code{poly1} and \code{poly2}, assuming the latter are + precisely $n$ coefficients in length, zero padded if necessary. The + remaining $n - 1$ coefficients may be arbitrary. + +******************************************************************************* + + Squaring + +******************************************************************************* + +void _fmpz_poly_sqr_KS(fmpz * rop, const fmpz * op, slong len) + + Sets \code{(rop, 2*len - 1)} to the square of \code{(op, len)}, + assuming that \code{len > 0}. + + Supports zero-padding in \code{(op, len)}. Does not support aliasing. + +void fmpz_poly_sqr_KS(fmpz_poly_t rop, const fmpz_poly_t op) + + Sets \code{rop} to the square of the polynomial \code{op} using + Kronecker segmentation. + +void _fmpz_poly_sqr_karatsuba(fmpz * rop, const fmpz * op, slong len) + + Sets \code{(rop, 2*len - 1)} to the square of \code{(op, len)}, + assuming that \code{len > 0}. + + Supports zero-padding in \code{(op, len)}. Does not support aliasing. + +void fmpz_poly_sqr_karatsuba(fmpz_poly_t rop, const fmpz_poly_t op) + + Sets \code{rop} to the square of the polynomial \code{op} using + the Karatsuba multiplication algorithm. + +void _fmpz_poly_sqr_classical(fmpz * rop, const fmpz * op, slong len) + + Sets \code{(rop, 2*len - 1)} to the square of \code{(op, len)}, + assuming that \code{len > 0}. + + Supports zero-padding in \code{(op, len)}. Does not support aliasing. + +void fmpz_poly_sqr_classical(fmpz_poly_t rop, const fmpz_poly_t op) + + Sets \code{rop} to the square of the polynomial \code{op} using + the classical or schoolbook method. + +void _fmpz_poly_sqr(fmpz * rop, const fmpz * op, slong len) + + Sets \code{(rop, 2*len - 1)} to the square of \code{(op, len)}, + assuming that \code{len > 0}. + + Supports zero-padding in \code{(op, len)}. Does not support aliasing. + +void fmpz_poly_sqr(fmpz_poly_t rop, const fmpz_poly_t op) + + Sets \code{rop} to the square of the polynomial \code{op}. + +void _fmpz_poly_sqrlow_KS(fmpz * res, const fmpz * poly, slong len, slong n) + + Sets \code{(res, n)} to the lowest $n$ coefficients + of the square of \code{(poly, len)}. + + Assumes that \code{len} is positive, but does allow for the polynomial + to be zero-padded. The polynomial may be zero, too. Assumes $n$ is + positive. Supports aliasing between \code{res} and \code{poly}. + +void fmpz_poly_sqrlow_KS(fmpz_poly_t res, const fmpz_poly_t poly, slong n) + + Sets \code{res} to the lowest $n$ coefficients + of the square of \code{poly}. + +void _fmpz_poly_sqrlow_karatsuba_n(fmpz * res, const fmpz * poly, slong n) + + Sets \code{(res, n)} to the square of \code{(poly, n)} truncated + to length $n$, which is assumed to be positive. Allows for \code{poly} + to be zero-oadded. + +void fmpz_poly_sqrlow_karatsuba_n(fmpz_poly_t res, + const fmpz_poly_t poly, slong n) + + Sets \code{res} to the square of \code{poly} and + truncates to the given length. + +void _fmpz_poly_sqrlow_classical(fmpz * res, + const fmpz * poly, slong len, slong n) + + Sets \code{(res, n)} to the first $n$ coefficients of the square + of \code{(poly, len)}. + + Assumes that \code{0 < n <= 2 * len - 1}. + +void fmpz_poly_sqrlow_classical(fmpz_poly_t res, + const fmpz_poly_t poly, slong n) + + Sets \code{res} to the first $n$ coefficients of + the square of \code{poly}. + +void _fmpz_poly_sqrlow(fmpz * res, const fmpz * poly, slong len, slong n) + + Sets \code{(res, n)} to the lowest $n$ coefficients + of the square of \code{(poly, len)}. + + Assumes \code{len1 >= len2 > 0} and \code{0 < n <= 2 * len - 1}. + Allows for zero-padding in the input. Does not support aliasing + between the input and the output. + +void fmpz_poly_sqrlow(fmpz_poly_t res, const fmpz_poly_t poly, slong n) + + Sets \code{res} to the lowest $n$ coefficients + of the square of \code{poly}. + +******************************************************************************* + + Powering + +******************************************************************************* + +void _fmpz_poly_pow_multinomial(fmpz * res, + const fmpz * poly, slong len, ulong e) + + Computes \code{res = poly^e}. This uses the J.C.P.~Miller pure + recurrence as follows: + + If $\ell$ is the index of the lowest non-zero coefficient in \code{poly}, + as a first step this method zeros out the lowest $e \ell$ coefficients of + \code{res}. The recurrence above is then used to compute the remaining + coefficients. + + Assumes \code{len > 0}, \code{e > 0}. Does not support aliasing. + +void fmpz_poly_pow_multinomial(fmpz_poly_t res, + const fmpz_poly_t poly, ulong e) + + Computes \code{res = poly^e} using a generalisation of binomial expansion + called the J.C.P.~Miller pure recurrence~\citep{Knu1997, Zei1995}. + If $e$ is zero, returns one, so that in particular \code{0^0 = 1}. + + The formal statement of the recurrence is as follows. Write the input + polynomial as $P(x) = p_0 + p_1 x + \dotsb + p_m x^m$ with $p_0 \neq 0$ + and let + \begin{equation*} + P(x)^n = a(n, 0) + a(n, 1) x + \dotsb + a(n, mn) x^{mn}. + \end{equation*} + Then $a(n, 0) = p_0^n$ and, for all $1 \leq k \leq mn$, + \begin{equation*} + a(n, k) = + (k p_0)^{-1} \sum_{i = 1}^m p_i \bigl( (n + 1) i - k \bigr) a(n, k-i). + \end{equation*} + + % [1] D. Knuth, The Art of Computer Programming Vol. 2, Seminumerical + % Algorithms, Third Edition (Reading, Massachusetts: Addison-Wesley, 1997) + % + % [2] D. Zeilberger, The J.C.P. Miller Recurrence for Exponentiating a + % Polynomial, and its q-Analog, Journal of Difference Equations and + % Applications, 1995, Vol. 1, pp. 57--60 + +void _fmpz_poly_pow_binomial(fmpz * res, const fmpz * poly, ulong e) + + Computes \code{res = poly^e} when poly is of length~$2$, using binomial + expansion. + + Assumes $e > 0$. Does not support aliasing. + +void fmpz_poly_pow_binomial(fmpz_poly_t res, const fmpz_poly_t poly, ulong e) + + Computes \code{res = poly^e} when \code{poly} is of length~$2$, using + binomial expansion. + + If the length of \code{poly} is not~$2$, raises an exception and aborts. + +void _fmpz_poly_pow_addchains(fmpz * res, const fmpz * poly, slong len, + const int * a, int n) + + Given a star chain $1 = a_0 < a_1 < \dotsb < a_n = e$ computes + \code{res = poly^e}. + + A star chain is an addition chain $1 = a_0 < a_1 < \dotsb < a_n$ such + that, for all $i > 0$, $a_i = a_{i-1} + a_j$ for some $j < i$. + + Assumes that $e > 2$, or equivalently $n > 1$, and \code{len > 0}. Does + not support aliasing. + +void fmpz_poly_pow_addchains(fmpz_poly_t res, const fmpz_poly_t poly, ulong e) + + Computes \code{res = poly^e} using addition chains whenever + $0 \leq e \leq 148$. + + If $e > 148$, raises an exception and aborts. + +void _fmpz_poly_pow_binexp(fmpz * res, const fmpz * poly, slong len, ulong e) + + Sets \code{res = poly^e} using left-to-right binary exponentiation as + described in~\citep[p.~461]{Knu1997}. + + Assumes that \code{len > 0}, \code{e > 1}. Assumes that \code{res} is + an array of length at least \code{e*(len - 1) + 1}. Does not support + aliasing. + +void fmpz_poly_pow_binexp(fmpz_poly_t res, const fmpz_poly_t poly, ulong e) + + Computes \code{res = poly^e} using the binary exponentiation algorithm. + If $e$ is zero, returns one, so that in particular \code{0^0 = 1}. + +void _fmpz_poly_pow_small(fmpz * res, const fmpz * poly, slong len, ulong e) + + Sets \code{res = poly^e} whenever $0 \leq e \leq 4$. + + Assumes that \code{len > 0} and that \code{res} is an array of length + at least \code{e*(len - 1) + 1}. Does not support aliasing. + +void _fmpz_poly_pow(fmpz * res, const fmpz * poly, slong len, ulong e) + + Sets \code{res = poly^e}, assuming that \code{e, len > 0} and that + \code{res} has space for \code{e*(len - 1) + 1} coefficients. Does + not support aliasing. + +void fmpz_poly_pow(fmpz_poly_t res, const fmpz_poly_t poly, ulong e) + + Computes \code{res = poly^e}. If $e$ is zero, returns one, + so that in particular \code{0^0 = 1}. + +void _fmpz_poly_pow_trunc(fmpz * res, const fmpz * poly, ulong e, slong n) + + Sets \code{(res, n)} to \code{(poly, n)} raised to the power $e$ and + truncated to length $n$. + + Assumes that $e, n > 0$. Allows zero-padding of \code{(poly, n)}. + Does not support aliasing of any inputs and outputs. + +void fmpz_poly_pow_trunc(fmpz_poly_t res, + const fmpz_poly_t poly, ulong e, slong n) + + Notationally raises \code{poly} to the power $e$, truncates the result + to length $n$ and writes the result in \code{res}. This is computed + much more efficiently than simply powering the polynomial and truncating. + + Thus, if $n = 0$ the result is zero. Otherwise, whenever $e = 0$ the + result will be the constant polynomial equal to $1$. + + This function can be used to raise power series to a power in an + efficient way. + +******************************************************************************* + + Shifting + +******************************************************************************* + +void _fmpz_poly_shift_left(fmpz * res, const fmpz * poly, slong len, slong n) + + Sets \code{(res, len + n)} to \code{(poly, len)} shifted left by + $n$ coefficients. + + Inserts zero coefficients at the lower end. Assumes that \code{len} + and $n$ are positive, and that \code{res} fits \code{len + n} elements. + Supports aliasing between \code{res} and \code{poly}. + +void fmpz_poly_shift_left(fmpz_poly_t res, const fmpz_poly_t poly, slong n) + + Sets \code{res} to \code{poly} shifted left by $n$ coeffs. Zero + coefficients are inserted. + +void _fmpz_poly_shift_right(fmpz * res, const fmpz * poly, slong len, slong n) + + Sets \code{(res, len - n)} to \code{(poly, len)} shifted right by + $n$ coefficients. + + Assumes that \code{len} and $n$ are positive, that \code{len > n}, + and that \code{res} fits \code{len - n} elements. Supports aliasing + between \code{res} and \code{poly}, although in this case the top + coefficients of \code{poly} are not set to zero. + +void fmpz_poly_shift_right(fmpz_poly_t res, const fmpz_poly_t poly, slong n) + + Sets \code{res} to \code{poly} shifted right by $n$ coefficients. If $n$ + is equal to or greater than the current length of \code{poly}, \code{res} + is set to the zero polynomial. + +******************************************************************************* + + Bit sizes and norms + +******************************************************************************* + +ulong fmpz_poly_max_limbs(const fmpz_poly_t poly) + + Returns the maximum number of limbs required to store the absolute value + of coefficients of \code{poly}. If \code{poly} is zero, returns $0$. + +slong fmpz_poly_max_bits(const fmpz_poly_t poly) + + Computes the maximum number of bits $b$ required to store the absolute + value of coefficients of \code{poly}. If all the coefficients of + \code{poly} are non-negative, $b$ is returned, otherwise $-b$ is returned. + +void fmpz_poly_height(fmpz_t height, const fmpz_poly_t poly) + + Computes the height of \code{poly}, defined as the largest of the + absolute values the coefficients of \code{poly}. Equivalently, this + gives the infinity norm of the coefficients. If \code{poly} is zero, + the height is $0$. + +void _fmpz_poly_2norm(fmpz_t res, const fmpz * poly, slong len) + + Sets \code{res} to the Euclidean norm of \code{(poly, len)}, that is, + the integer square root of the sum of the squares of the coefficients + of \code{poly}. + +void fmpz_poly_2norm(fmpz_t res, const fmpz_poly_t poly) + + Sets \code{res} to the Euclidean norm of \code{poly}, that is, the + integer square root of the sum of the squares of the coefficients of + \code{poly}. + +mp_limb_t _fmpz_poly_2norm_normalised_bits(const fmpz * poly, slong len) + + Returns an upper bound on the number of bits of the normalised + Euclidean norm of \code{(poly, len)}, i.e. the number of bits of + the Euclidean norm divided by the absolute value of the leading + coefficient. The returned value will be no more than 1 bit too + large. + + This is used in the computation of the Landau-Mignotte bound. + + It is assumed that \code{len > 0}. The result only makes sense + if the leading coefficient is nonzero. + +******************************************************************************* + + Greatest common divisor + +******************************************************************************* + +void _fmpz_poly_gcd_subresultant(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2) + + Computes the greatest common divisor \code{(res, len2)} of + \code{(poly1, len1)} and \code{(poly2, len2)}, assuming + \code{len1 >= len2 > 0}. The result is normalised to have + positive leading coefficient. Aliasing between \code{res}, + \code{poly1} and \code{poly2} is supported. + +void fmpz_poly_gcd_subresultant(fmpz_poly_t res, const fmpz_poly_t poly1, + const fmpz_poly_t poly2) + + Computes the greatest common divisor \code{res} of \code{poly1} and + \code{poly2}, normalised to have non-negative leading coefficient. + + This function uses the subresultant algorithm as described + in~\citep[Algorithm~3.3.1]{Coh1996}. + +int _fmpz_poly_gcd_heuristic(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2) + + Computes the greatest common divisor \code{(res, len2)} of + \code{(poly1, len1)} and \code{(poly2, len2)}, assuming + \code{len1 >= len2 > 0}. The result is normalised to have + positive leading coefficient. Aliasing between \code{res}, + \code{poly1} and \code{poly2} is not supported. The function + may not always succeed in finding the GCD. If it fails, the + function returns 0, otherwise it returns 1. + +int fmpz_poly_gcd_heuristic(fmpz_poly_t res, const fmpz_poly_t poly1, + const fmpz_poly_t poly2) + + Computes the greatest common divisor \code{res} of \code{poly1} and + \code{poly2}, normalised to have non-negative leading coefficient. + + The function may not always succeed in finding the GCD. If it fails, + the function returns 0, otherwise it returns 1. + + This function uses the heuristic GCD algorithm (GCDHEU). The basic + strategy is to remove the content of the polynomials, pack them + using Kronecker segmentation (given a bound on the size of the + coefficients of the GCD) and take the integer GCD. Unpack the + result and test divisibility. + +void _fmpz_poly_gcd_modular(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2) + + Computes the greatest common divisor \code{(res, len2)} of + \code{(poly1, len1)} and \code{(poly2, len2)}, assuming + \code{len1 >= len2 > 0}. The result is normalised to have + positive leading coefficient. Aliasing between \code{res}, + \code{poly1} and \code{poly2} is not supported. + +void fmpz_poly_gcd_modular(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2) + + Computes the greatest common divisor \code{res} of \code{poly1} and + \code{poly2}, normalised to have non-negative leading coefficient. + + This function uses the modular GCD algorithm. The basic + strategy is to remove the content of the polynomials, reduce them + modulo sufficiently many primes and do CRT reconstruction until + some bound is reached (or we can prove with trial division that + we have the GCD). + +void _fmpz_poly_gcd(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2) + + Computes the greatest common divisor \code{res} of \code{(poly1, len1)} + and \code{(poly2, len2)}, assuming \code{len1 >= len2 > 0}. The result + is normalised to have positive leading coefficient. + + Assumes that \code{res} has space for \code{len2} coefficients. + Aliasing between \code{res}, \code{poly1} and \code{poly2} is not + supported. + +void fmpz_poly_gcd(fmpz_poly_t res, const fmpz_poly_t poly1, + const fmpz_poly_t poly2) + + Computes the greatest common divisor \code{res} of \code{poly1} and + \code{poly2}, normalised to have non-negative leading coefficient. + +void _fmpz_poly_xgcd_modular(fmpz_t r, fmpz * s, fmpz * t, + const fmpz * f, slong len1, const fmpz * g, slong len2) + + Set $r$ to the resultant of \code{(f, len1)} and \code{(g, len2)}. + If the resultant is zero, the function returns immediately. Otherwise it + finds polynomials $s$ and $t$ such that \code{s*f + t*g = r}. The length + of $s$ will be no greater than \code{len2} and the length of $t$ will be + no greater than \code{len1} (both are zero padded if necessary). + + It is assumed that \code{len1 >= len2 > 0}. No aliasing of inputs and + outputs is permitted. + + The function assumes that $f$ and $g$ are primitive (have Gaussian content + equal to 1). The result is undefined otherwise. + + Uses a multimodular algorithm. The resultant is first computed and + extended GCD's modulo various primes $p$ are computed and combined using + CRT. When the CRT stabilises the resulting polynomials are simply reduced + modulo further primes until a proven bound is reached. + +void fmpz_poly_xgcd_modular(fmpz_t r, fmpz_poly_t s, fmpz_poly_t t, + const fmpz_poly_t f, const fmpz_poly_t g) + + Set $r$ to the resultant of $f$ and $g$. If the resultant is zero, the + function then returns immediately, otherwise $s$ and $t$ are found such + that \code{s*f + t*g = r}. + + The function assumes that $f$ and $g$ are primitive (have Gaussian content + equal to 1). The result is undefined otherwise. + + Uses the multimodular algorithm. + +void _fmpz_poly_xgcd(fmpz_t r, fmpz * s, fmpz * t, + const fmpz * f, slong len1, const fmpz * g, slong len2) + + Set $r$ to the resultant of \code{(f, len1)} and \code{(g, len2)}. + If the resultant is zero, the function returns immediately. Otherwise it + finds polynomials $s$ and $t$ such that \code{s*f + t*g = r}. The length + of $s$ will be no greater than \code{len2} and the length of $t$ will be + no greater than \code{len1} (both are zero padded if necessary). + + The function assumes that $f$ and $g$ are primitive (have Gaussian content + equal to 1). The result is undefined otherwise. + + It is assumed that \code{len1 >= len2 > 0}. No aliasing of inputs and + outputs is permitted. + +void fmpz_poly_xgcd(fmpz_t r, fmpz_poly_t s, fmpz_poly_t t, + const fmpz_poly_t f, const fmpz_poly_t g) + + Set $r$ to the resultant of $f$ and $g$. If the resultant is zero, the + function then returns immediately, otherwise $s$ and $t$ are found such + that \code{s*f + t*g = r}. + + The function assumes that $f$ and $g$ are primitive (have Gaussian content + equal to 1). The result is undefined otherwise. + +void _fmpz_poly_lcm(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2) + + Sets \code{(res, len1 + len2 - 1)} to the least common multiple + of the two polynomials \code{(poly1, len1)} and \code{(poly2, len2)}, + normalised to have non-negative leading coefficient. + + Assumes that \code{len1 >= len2 > 0}. + + Does not support aliasing. + +void fmpz_poly_lcm(fmpz_poly_t res, const fmpz_poly_t poly1, + const fmpz_poly_t poly2) + + Sets \code{res} to the least common multiple of the two + polynomials \code{poly1} and \code{poly2}, normalised to + have non-negative leading coefficient. + + If either of the two polynomials is zero, sets \code{res} + to zero. + + This ensures that the equality + \begin{equation*} + f g = \gcd(f, g) \operatorname{lcm}(f, g) + \end{equation*} + holds up to sign. + +void _fmpz_poly_resultant(fmpz_t res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2) + + Sets \code{res} to the resultant of \code{(poly1, len1)} and + \code{(poly2, len2)}, assuming that \code{len1 >= len2 > 0}. + +void fmpz_poly_resultant(fmpz_t res, const fmpz_poly_t poly1, + const fmpz_poly_t poly2) + + Computes the resultant of \code{poly1} and \code{poly2}. + + For two non-zero polynomials $f(x) = a_m x^m + \dotsb + a_0$ and + $g(x) = b_n x^n + \dotsb + b_0$ of degrees $m$ and $n$, the resultant + is defined to be + \begin{equation*} + a_m^n b_n^m \prod_{(x, y) : f(x) = g(y) = 0} (x - y). + \end{equation*} + For convenience, we define the resultant to be equal to zero if either + of the two polynomials is zero. + + This function uses the algorithm described + in~\citep[Algorithm~3.3.7]{Coh1996}. + +******************************************************************************* + + Gaussian content + +******************************************************************************* + +void _fmpz_poly_content(fmpz_t res, const fmpz * poly, slong len) + + Sets \code{res} to the non-negative content of \code{(poly, len)}. + Aliasing between \code{res} and the coefficients of \code{poly} is + not supported. + +void fmpz_poly_content(fmpz_t res, const fmpz_poly_t poly) + + Sets \code{res} to the non-negative content of \code{poly}. The content + of the zero polynomial is defined to be zero. Supports aliasing, that is, + \code{res} is allowed to be one of the coefficients of \code{poly}. + +void _fmpz_poly_primitive_part(fmpz * res, const fmpz * poly, slong len) + + Sets \code{(res, len)} to \code{(poly, len)} divided by the content + of \code{(poly, len)}, and normalises the result to have non-negative + leading coefficient. + + Assumes that \code{(poly, len)} is non-zero. Supports aliasing of + \code{res} and \code{poly}. + +void fmpz_poly_primitive_part(fmpz_poly_t res, const fmpz_poly_t poly) + + Sets \code{res} to \code{poly} divided by the content of \code{poly}, + and normalises the result to have non-negative leading coefficient. + If \code{poly} is zero, sets \code{res} to zero. + +******************************************************************************* + + Square-free + +******************************************************************************* + +int _fmpz_poly_is_squarefree(const fmpz * poly, slong len) + + Returns whether the polynomial \code{(poly, len)} is square-free. + +int fmpz_poly_is_squarefree(const fmpz_poly_t poly) + + Returns whether the polynomial \code{poly} is square-free. A non-zero + polynomial is defined to be square-free if it has no non-unit square + factors. We also define the zero polynomial to be square-free. + + Returns~$1$ if the length of \code{poly} is at most~$2$. Returns whether + the discriminant is zero for quadratic polynomials. Otherwise, returns + whether the greatest common divisor of \code{poly} and its derivative has + length~$1$. + +******************************************************************************* + + Euclidean division + +******************************************************************************* + +void _fmpz_poly_divrem_basecase(fmpz * Q, fmpz * R, const fmpz * A, + slong lenA, const fmpz * B, slong lenB) + + Computes \code{(Q, lenA - lenB + 1)}, \code{(R, lenA)} such that + $A = B Q + R$ and each coefficient of $R$ beyond \code{lenB} is reduced + modulo the leading coefficient of $B$. + If the leading coefficient of $B$ is $\pm 1$ or the division is exact, + this is the same thing as division over~$\Q$. + + Assumes that $\len(A), \len(B) > 0$. Allows zero-padding in + \code{(A, lenA)}. $R$ and $A$ may be aliased, but apart from this no + aliasing of input and output operands is allowed. + +void fmpz_poly_divrem_basecase(fmpz_poly_t Q, fmpz_poly_t R, + const fmpz_poly_t A, const fmpz_poly_t B) + + Computes $Q$, $R$ such that $A = B Q + R$ and each coefficient of $R$ + beyond $\len(B) - 1$ is reduced modulo the leading coefficient of $B$. + If the leading coefficient of $B$ is $\pm 1$ or the division is exact, + this is the same thing as division over~$\Q$. An exception is raised + if $B$ is zero. + +void _fmpz_poly_divrem_divconquer_recursive(fmpz * Q, fmpz * BQ, fmpz * W, + const fmpz * A, const fmpz * B, slong lenB) + + Computes \code{(Q, lenB)}, \code{(BQ, 2 lenB - 1)} such that + $BQ = B \times Q$ and $A = B Q + R$ where each coefficient of $R$ beyond + $\len(B) - 1$ is reduced modulo the leading coefficient of $B$. We + assume that $\len(A) = 2 \len(B) - 1$. If the leading coefficient + of $B$ is $\pm 1$ or the division is exact, this is the same as division + over~$\Q$. + + Assumes $\len(B) > 0$. Allows zero-padding in \code{(A, lenA)}. Requires + a temporary array \code{(W, 2 lenB - 1)}. No aliasing of input and output + operands is allowed. + + This function does not read the bottom $\len(B) - 1$ coefficients from + $A$, which means that they might not even need to exist in allocated + memory. + +void _fmpz_poly_divrem_divconquer(fmpz * Q, fmpz * R, + const fmpz * A, slong lenA, const fmpz * B, slong lenB) + + Computes \code{(Q, lenA - lenB + 1)}, \code{(R, lenA)} such that + $A = B Q + R$ and each coefficient of $R$ beyond $\len(B) - 1$ is + reduced modulo the leading coefficient of $B$. If the leading + coefficient of $B$ is $\pm 1$ or the division is exact, this is + the same as division over~$\Q$. + + Assumes $\len(A) \geq \len(B) > 0$. Allows zero-padding in + \code{(A, lenA)}. No aliasing of input and output operands is + allowed. + +void fmpz_poly_divrem_divconquer(fmpz_poly_t Q, fmpz_poly_t R, + const fmpz_poly_t A, const fmpz_poly_t B) + + Computes $Q$, $R$ such that $A = B Q + R$ and each coefficient of $R$ + beyond $\len(B) - 1$ is reduced modulo the leading coefficient of $B$. + If the leading coefficient of $B$ is $\pm 1$ or the division is exact, + this is the same as division over~$\Q$. An exception is raised if $B$ + is zero. + +void _fmpz_poly_divrem(fmpz * Q, fmpz * R, const fmpz * A, slong lenA, + const fmpz * B, slong lenB) + + Computes \code{(Q, lenA - lenB + 1)}, \code{(R, lenA)} such that + $A = B Q + R$ and each coefficient of $R$ beyond $\len(B) - 1$ is + reduced modulo the leading coefficient of $B$. If the leading + coefficient of $B$ is $\pm 1$ or the division is exact, this is + the same thing as division over~$\Q$. + + Assumes $\len(A) \geq \len(B) > 0$. Allows zero-padding in + \code{(A, lenA)}. No aliasing of input and output operands is + allowed. + +void fmpz_poly_divrem(fmpz_poly_t Q, fmpz_poly_t R, const fmpz_poly_t A, + const fmpz_poly_t B) + + Computes $Q$, $R$ such that $A = B Q + R$ and each coefficient of $R$ + beyond $\len(B) - 1$ is reduced modulo the leading coefficient of $B$. + If the leading coefficient of $B$ is $\pm 1$ or the division is exact, + this is the same as division over~$\Q$. An exception is raised if $B$ + is zero. + +void _fmpz_poly_div_basecase(fmpz * Q, fmpz * R, const fmpz * A, slong lenA, + const fmpz * B, slong lenB) + + Computes the quotient \code{(Q, lenA - lenB + 1)} of \code{(A, lenA)} + divided by \code{(B, lenB)}. + + Notationally, computes $Q$, $R$ such that $A = B Q + R$ and each + coefficient of $R$ beyond $\len(B) - 1$ is reduced modulo the leading + coefficient of $B$. + + If the leading coefficient of $B$ is $\pm 1$ or the division is exact, + this is the same as division over~$\Q$. + + Assumes $\len(A), \len(B) > 0$. Allows zero-padding in \code{(A, lenA)}. + Requires a temporary array $R$ of size at least the (actual) length + of $A$. For convenience, $R$ may be \code{NULL}. $R$ and $A$ may be + aliased, but apart from this no aliasing of input and output operands + is allowed. + +void fmpz_poly_div_basecase(fmpz_poly_t Q, + const fmpz_poly_t A, const fmpz_poly_t B) + + Computes the quotient $Q$ of $A$ divided by $Q$. + + Notationally, computes $Q$, $R$ such that $A = B Q + R$ and each + coefficient of $R$ beyond $\len(B) - 1$ is reduced modulo the leading + coefficient of $B$. + + If the leading coefficient of $B$ is $\pm 1$ or the division is exact, + this is the same as division over~$\Q$. An exception is raised if $B$ + is zero. + +void _fmpz_poly_divremlow_divconquer_recursive(fmpz * Q, fmpz * BQ, + const fmpz * A, const fmpz * B, slong lenB) + + Divide and conquer division of \code{(A, 2 lenB - 1)} by \code{(B, lenB)}, + computing only the bottom $\len(B) - 1$ coefficients of $B Q$. + + Assumes $\len(B) > 0$. Requires $B Q$ to have length at least + $2 \len(B) - 1$, although only the bottom $\len(B) - 1$ coefficients will + carry meaningful output. Does not support any aliasing. Allows + zero-padding in $A$, but not in $B$. + +void _fmpz_poly_div_divconquer_recursive(fmpz * Q, fmpz * temp, + const fmpz * A, const fmpz * B, slong lenB) + + Recursive short division in the balanced case. + + Computes the quotient \code{(Q, lenB)} of \code{(A, 2 lenB - 1)} upon + division by \code{(B, lenB)}. Requires $\len(B) > 0$. Needs a + temporary array \code{temp} of length $2 \len(B) - 1$. Does not support + any aliasing. + + For further details, see~\citep{Mul2000}. + +void _fmpz_poly_div_divconquer(fmpz * Q, const fmpz * A, slong lenA, + const fmpz * B, slong lenB) + + Computes the quotient \code{(Q, lenA - lenB + 1)} of \code{(A, lenA)} + upon division by \code{(B, lenB)}. Assumes that + $\len(A) \geq \len(B) > 0$. Does not support aliasing. + +fmpz_poly_div_divconquer(fmpz_poly_t Q, + const fmpz_poly_t A, const fmpz_poly_t B) + + Computes the quotient $Q$ of $A$ divided by $B$. + + Notationally, computes $Q$, $R$ such that $A = B Q + R$ and each + coefficient of $R$ beyond $\len(B) - 1$ is reduced modulo the leading + coefficient of $B$. + + If the leading coefficient of $B$ is $\pm 1$ or the division is exact, + this is the same as division over~$\Q$. An exception is raised if $B$ + is zero. + +void _fmpz_poly_div(fmpz * Q, const fmpz * A, slong lenA, + const fmpz * B, slong lenB) + + Computes the quotient \code{(Q, lenA - lenB + 1)} of \code{(A, lenA)} + divided by \code{(B, lenB)}. + + Notationally, computes $Q$, $R$ such that $A = B Q + R$ and each + coefficient of $R$ beyond $\len(B) - 1$ is reduced modulo the leading + coefficient of $B$. If the leading coefficient of $B$ is $\pm 1$ or + the division is exact, this is the same as division over~$\Q$. + + Assumes $\len(A) \geq \len(B) > 0$. Allows zero-padding in + \code{(A, lenA)}. Aliasing of input and output operands is not + allowed. + +void fmpz_poly_div(fmpz_poly_t Q, const fmpz_poly_t A, const fmpz_poly_t B) + + Computes the quotient $Q$ of $A$ divided by $B$. + + Notationally, computes $Q$, $R$ such that $A = B Q + R$ and each + coefficient of $R$ beyond $\len(B) - 1$ is reduced modulo the leading + coefficient of $B$. If the leading coefficient of $B$ is $\pm 1$ or + the division is exact, this is the same as division over $Q$. An + exception is raised if $B$ is zero. + +void _fmpz_poly_rem_basecase(fmpz * R, const fmpz * A, slong lenA, + const fmpz * B, slong lenB) + + Computes the remainder \code{(R, lenA)} of \code{(A, lenA)} upon + division by \code{(B, lenB)}. + + Notationally, computes $Q$, $R$ such that $A = B Q + R$ and each + coefficient of $R$ beyond $\len(B) - 1$ is reduced modulo the leading + coefficient of $B$. If the leading coefficient of $B$ is $\pm 1$ or + the division is exact, this is the same thing as division over~$\Q$. + + Assumes that $\len(A), \len(B) > 0$. Allows zero-padding in + \code{(A, lenA)}. $R$ and $A$ may be aliased, but apart from this no + aliasing of input and output operands is allowed. + +void fmpz_poly_rem_basecase(fmpz_poly_t R, + const fmpz_poly_t A, const fmpz_poly_t B) + + Computes the remainder $R$ of $A$ upon division by $B$. + + Notationally, computes $Q$, $R$ such that $A = B Q + R$ and each + coefficient of $R$ beyond $\len(B) - 1$ is reduced modulo the leading + coefficient of $B$. If the leading coefficient of $B$ is $\pm 1$ or + the division is exact, this is the same as division over~$\Q$. An + exception is raised if $B$ is zero. + +void _fmpz_poly_rem(fmpz * R, const fmpz * A, slong lenA, + const fmpz * B, slong lenB) + + Computes the remainder \code{(R, lenA)} of \code{(A, lenA)} upon division + by \code{(B, lenB)}. + + Notationally, computes $Q$, $R$ such that $A = B Q + R$ and each + coefficient of $R$ beyond $\len(B) - 1$ is reduced modulo the leading + coefficient of $B$. If the leading coefficient of $B$ is $\pm 1$ or + the division is exact, this is the same thing as division over~$\Q$. + + Assumes that $\len(A) \geq \len(B) > 0$. Allows zero-padding in + \code{(A, lenA)}. Aliasing of input and output operands is not allowed. + +void fmpz_poly_rem(fmpz_poly_t R, const fmpz_poly_t A, const fmpz_poly_t B) + + Computes the remainder $R$ of $A$ upon division by $B$. + + Notationally, computes $Q$, $R$ such that $A = B Q + R$ and each + coefficient of $R$ beyond $\len(B) - 1$ is reduced modulo the leading + coefficient of $B$. If the leading coefficient of $B$ is $\pm 1$ or + the division is exact, this is the same as division over~$\Q$. An + exception is raised if $B$ is zero. + +void _fmpz_poly_div_root(fmpz * Q, const fmpz * A, slong len, const fmpz_t c) + + Computes the quotient \code{(Q, len-1)} of \code{(A, len)} upon + division by $x - c$. + + Supports aliasing of \code{Q} and \code{A}, but the result is + undefined in case of partial overlap. + +void fmpz_poly_div_root(fmpz_poly_t Q, const fmpz_poly_t A, const fmpz_t c) + + Computes the quotient \code{(Q, len-1)} of \code{(A, len)} upon + division by $x - c$. + +******************************************************************************* + + Division with precomputed inverse + +******************************************************************************* + +void _fmpz_poly_preinvert(fmpz * B_inv, const fmpz * B, slong n) + + Given a monic polynomial \code{B} of length \code{n}, compute a precomputed + inverse \code{B_inv} of length \code{n} for use in the functions below. No + aliasing of B and $B_inv$ is permitted. We assume \code{n} is not zero. + +void fmpz_poly_preinvert(fmpz_poly_t B_inv, const fmpz_poly_t B) + + Given a monic polynomial \code{B}, compute a precomputed inverse + \code{B_inv} for use in the functions below. An exception is raised if + \code{B} is zero. + +void _fmpz_poly_div_preinv(fmpz * Q, const fmpz * A, slong len1, + const fmpz * B, const fmpz * B_inv, slong len2) + + Given a precomputed inverse \code{B_inv} of the polynomial \code{B} of + length \code{len2}, compute the quotient \code{Q} of \code{A} by \code{B}. + We assume the length \code{len1} of \code{A} is at least \code{len2}. The + polynomial \code{Q} must have space for \code{len1 - len2 + 1} + coefficients. No aliasing of operands is permitted. + +void fmpz_poly_div_preinv(fmpz_poly_t Q, const fmpz_poly_t A, + const fmpz_poly_t B, const fmpz_poly_t B_inv) + + Given a precomputed inverse \code{B_inv} of the polynomial \code{B}, + compute the quotient \code{Q} of \code{A} by \code{B}. Aliasing of \code{B} + and \code{B_inv} is not permitted. + +void _fmpz_poly_divrem_preinv(fmpz * Q, fmpz * A, slong len1, + const fmpz * B, const fmpz * B_inv, slong len2) + + Given a precomputed inverse \code{B_inv} of the polynomial \code{B} of + length \code{len2}, compute the quotient \code{Q} of \code{A} by \code{B}. + The remainder is then placed in \code{A}. We assume the length \code{len1} + of \code{A} is at least \code{len2}. The polynomial \code{Q} must have + space for \code{len1 - len2 + 1} coefficients. No aliasing of operands is + permitted. + +void fmpz_poly_divrem_preinv(fmpz_poly_t Q, fmpz_poly_t R, + const fmpz_poly_t A, const fmpz_poly_t B, const fmpz_poly_t B_inv) + + Given a precomputed inverse \code{B_inv} of the polynomial \code{B}, + compute the quotient \code{Q} of \code{A} by \code{B} and the remainder + \code{R}. Aliasing of \code{B} and \code{B_inv} is not permitted. + +fmpz ** _fmpz_poly_powers_precompute(const fmpz * B, slong len) + + Computes \code{2*len - 1} powers of $x$ modulo the polynomial $B$ of + the given length. This is used as a kind of precomputed inverse in + the remainder routine below. + +void fmpz_poly_powers_precompute(fmpz_poly_powers_precomp_t pinv, + fmpz_poly_t poly) + + Computes \code{2*len - 1} powers of $x$ modulo the polynomial $B$ of + the given length. This is used as a kind of precomputed inverse in + the remainder routine below. + +void _fmpz_poly_powers_clear(fmpz ** powers, slong len) + + Clean up resources used by precomputed powers which have been computed + by\\ + \code{_fmpz_poly_powers_precompute}. + +void fmpz_poly_powers_clear(fmpz_poly_powers_precomp_t pinv) + + Clean up resources used by precomputed powers which have been computed + by\\ + \code{fmpz_poly_powers_precompute}. + +void _fmpz_poly_rem_powers_precomp(fmpz * A, slong m, + const fmpz * B, slong n, fmpz ** const powers) + + Set $A$ to the remainder of $A$ divide $B$ given precomputed powers mod $B$ + provided by \code{_fmpz_poly_powers_precompute}. No aliasing is allowed. + +void fmpz_poly_rem_powers_precomp(fmpz_poly_t R, + const fmpz_poly_t A, const fmpz_poly_t B, + const fmpz_poly_powers_precomp_t B_inv) + + Set $R$ to the remainder of $A$ divide $B$ given precomputed powers mod $B$ + provided by \code{fmpz_poly_powers_precompute}. + +******************************************************************************* + + Divisibility testing + +******************************************************************************* + +int _fmpz_poly_divides(fmpz * Q, const fmpz * A, + slong lenA, const fmpz * B, slong lenB) + + Returns 1 if \code{(B, lenB)} divides \code{(A, lenA)} exactly and + sets $Q$ to the quotient, otherwise returns 0. + + It is assumed that $\len(A) \geq \len(B) > 0$ and that $Q$ has space + for $\len(A) - \len(B) + 1$ coefficients. + + Aliasing of $Q$ with either of the inputs is not permitted. + + This function is currently unoptimised and provided for convenience + only. + +int fmpz_poly_divides(fmpz_poly_t Q, + const fmpz_poly_t A, const fmpz_poly_t B) + + Returns 1 if $B$ divides $A$ exactly and sets $Q$ to the quotient, + otherwise returns 0. + + This function is currently unoptimised and provided for convenience + only. + +******************************************************************************* + + Power series division + +******************************************************************************* + +void _fmpz_poly_inv_series_newton(fmpz * Qinv, const fmpz * Q, slong n) + + Computes the first $n$ terms of the inverse power series of $Q$ using + Newton iteration. + + Assumes that $n \geq 1$, that $Q$ has length at least $n$ and constant + term~$\pm 1$. Does not support aliasing. + +id fmpz_poly_inv_series_newton(fmpz_poly_t Qinv, const fmpz_poly_t Q, slong n) + + Computes the first $n$ terms of the inverse power series of $Q$ + using Newton iteration, assuming that $Q$ has constant term~$\pm 1$ + and $n \geq 1$. + +void _fmpz_poly_inv_series(fmpz * Qinv, const fmpz * Q, slong n) + + Computes the first $n$ terms of the inverse power series of $Q$. + + Assumes that $n \geq 1$, that $Q$ has length at least $n$ and constant + term~$1$. Does not support aliasing. + +void fmpz_poly_inv_series(fmpz_poly_t Qinv, const fmpz_poly_t Q, slong n) + + Computes the first $n$ terms of the inverse power series of $Q$, + assuming $Q$ has constant term~$1$ and $n \geq 1$. + +void _fmpz_poly_div_series(fmpz * Q, const fmpz * A, const fmpz * B) + + Divides \code{(A, n)} by \code{(B, n)} as power series over $\Z$, + assuming $B$ has constant term~$1$ and $n \geq 1$. + + Only supports aliasing of \code{(Q, n)} and \code{(B, n)}. + +void fmpz_poly_div_series(fmpz_poly_t Q, const fmpz_poly_t A, + const fmpz_poly_t B, slong n) + + Performs power series division in $\Z[[x]] / (x^n)$. The function + considers the polynomials $A$ and $B$ as power series of length $n$ + starting with the constant terms. The function assumes that $B$ has + constant term~$1$ and $n \geq 1$. + +******************************************************************************* + + Pseudo division + +******************************************************************************* + +void _fmpz_poly_pseudo_divrem_basecase(fmpz * Q, fmpz * R, + ulong * d, const fmpz * A, slong lenA, + const fmpz * B, slong lenB, const fmpz_preinvn_t inv) + + If $\ell$ is the leading coefficient of $B$, then computes $Q$, $R$ such + that $\ell^d A = Q B + R$. This function is used for simulating division + over~$\Q$. + + Assumes that $\len(A) \geq \len(B) > 0$. Assumes that $Q$ can fit + $\len(A) - \len(B) + 1$ coefficients, and that $R$ can fit $\len(A)$ + coefficients. Supports aliasing of \code{(R, lenA)} and \code{(A, lenA)}. + But other than this, no aliasing of the inputs and outputs is suppported. + + An optional precomputed inverse of the leading coefficient of $B$ from + \code{fmpz_preinvn_init} can be supplied. Otherwise \code{inv} should be + \code{NULL}. + +void fmpz_poly_pseudo_divrem_basecase(fmpz_poly_t Q, fmpz_poly_t R, + ulong * d, const fmpz_poly_t A, const fmpz_poly_t B) + + If $\ell$ is the leading coefficient of $B$, then computes $Q$, $R$ such + that $\ell^d A = Q B + R$. This function is used for simulating division + over~$\Q$. + +void _fmpz_poly_pseudo_divrem_divconquer(fmpz * Q, fmpz * R, + ulong * d, const fmpz * A, slong lenB, + const fmpz * B, slong lenB, const fmpz_preinvn_t inv) + + Computes \code{(Q, lenA - lenB + 1)}, \code{(R, lenA)} such that + $\ell^d A = B Q + R$, only setting the bottom $\len(B) - 1$ coefficients + of $R$ to their correct values. The remaining top coefficients of + \code{(R, lenA)} may be arbitrary. + + Assumes $\len(A) \geq \len(B) > 0$. Allows zero-padding in + \code{(A, lenA)}. No aliasing of input and output operands is allowed. + + An optional precomputed inverse of the leading coefficient of $B$ from + \code{fmpz_preinvn_init} can be supplied. Otherwise \code{inv} should be + \code{NULL}. + +void fmpz_poly_pseudo_divrem_divconquer(fmpz_poly_t Q, fmpz_poly_t R, + ulong * d, const fmpz_poly_t A, const fmpz_poly_t B) + + Computes $Q$, $R$, and $d$ such that $\ell^d A = B Q + R$, where $R$ has + length less than the length of $B$ and $\ell$ is the leading coefficient + of $B$. An exception is raised if $B$ is zero. + +void _fmpz_poly_pseudo_divrem_cohen(fmpz * Q, fmpz * R, const fmpz * A, + slong lenA, const fmpz * B, slong lenB) + + Assumes that $\len(A) \geq \len(B) > 0$. Assumes that $Q$ can fit + $\len(A) - \len(B) + 1$ coefficients, and that $R$ can fit $\len(A)$ + coefficients. Supports aliasing of \code{(R, lenA)} and \code{(A, lenA)}. + But other than this, no aliasing of the inputs and outputs is supported. + +void fmpz_poly_pseudo_divrem_cohen(fmpz_poly_t Q, fmpz_poly_t R, + const fmpz_poly_t A, const fmpz_poly_t B) + + This is a variant of \code{fmpz_poly_pseudo_divrem} which computes + polynomials $Q$ and $R$ such that $\ell^d A = B Q + R$. However, the + value of $d$ is fixed at $\max{\{0, \len(A) - \len(B) + 1\}}$. + + This function is faster when the remainder is not well behaved, i.e.\ + where it is not expected to be close to zero. Note that this function + is not asymptotically fast. It is efficient only for short polynomials, + e.g.\ when $\len(B) < 32$. + +void _fmpz_poly_pseudo_rem_cohen(fmpz * R, const fmpz * A, slong lenA, + const fmpz * B, slong lenB) + + Assumes that $\len(A) \geq \len(B) > 0$. Assumes that $R$ can fit + $\len(A)$ coefficients. Supports aliasing of \code{(R, lenA)} and + \code{(A, lenA)}. But other than this, no aliasing of the inputs and + outputs is supported. + +void fmpz_poly_pseudo_rem_cohen(fmpz_poly_t R, const fmpz_poly_t A, + const fmpz_poly_t B) + + This is a variant of \code{fmpz_poly_pseudo_rem()} which computes + polynomials $Q$ and $R$ such that $\ell^d A = B Q + R$, but only + returns $R$. However, the value of $d$ is fixed at + $\max{\{0, \len(A) - \len(B) + 1\}}$. + + This function is faster when the remainder is not well behaved, i.e.\ + where it is not expected to be close to zero. Note that this function + is not asymptotically fast. It is efficient only for short polynomials, + e.g.\ when $\len(B) < 32$. + + This function uses the algorithm described + in~\citep[Algorithm~3.1.2]{Coh1996}. + +void _fmpz_poly_pseudo_divrem(fmpz * Q, fmpz * R, ulong * d, const fmpz * A, + slong lenA, const fmpz * B, slong lenB, const fmpz_preinvn_t inv) + + If $\ell$ is the leading coefficient of $B$, then computes + \code{(Q, lenA - lenB + 1)}, \code{(R, lenB - 1)} and $d$ such that + $\ell^d A = B Q + R$. This function is used for simulating division + over~$\Q$. + + Assumes that $\len(A) \geq \len(B) > 0$. Assumes that $Q$ can fit + $\len(A) - \len(B) + 1$ coefficients, and that $R$ can fit $\len(A)$ + coefficients, although on exit only the bottom $\len(B)$ coefficients + will carry meaningful data. + + Supports aliasing of \code{(R, lenA)} and \code{(A, lenA)}. But other + than this, no aliasing of the inputs and outputs is suppported. + + An optional precomputed inverse of the leading coefficient of $B$ from + \code{fmpz_preinvn_init} can be supplied. Otherwise \code{inv} should be + \code{NULL}. + +void fmpz_poly_pseudo_divrem(fmpz_poly_t Q, fmpz_poly_t R, ulong * d, + const fmpz_poly_t A, const fmpz_poly_t B) + + Computes $Q$, $R$, and $d$ such that $\ell^d A = B Q + R$. + +void _fmpz_poly_pseudo_div(fmpz * Q, ulong * d, const fmpz * A, slong lenA, + const fmpz * B, slong lenB, const fmpz_preinvn_t inv) + + Pseudo-division, only returning the quotient. + +void fmpz_poly_pseudo_div(fmpz_poly_t Q, ulong * d, const fmpz_poly_t A, + const fmpz_poly_t B) + + Pseudo-division, only returning the quotient. + +void _fmpz_poly_pseudo_rem(fmpz * R, ulong * d, const fmpz * A, slong lenA, + const fmpz * B, slong lenB, const fmpz_preinvn_t inv) + + Pseudo-division, only returning the remainder. + +void fmpz_poly_pseudo_rem(fmpz_poly_t R, ulong * d, const fmpz_poly_t A, + const fmpz_poly_t B) + + Pseudo-division, only returning the remainder. + +******************************************************************************* + + Derivative + +******************************************************************************* + +void _fmpz_poly_derivative(fmpz * rpoly, const fmpz * poly, slong len) + + Sets \code{(rpoly, len - 1)} to the derivative of \code{(poly, len)}. + Also handles the cases where \code{len} is $0$ or $1$ correctly. + Supports aliasing of \code{rpoly} and \code{poly}. + +void fmpz_poly_derivative(fmpz_poly_t res, const fmpz_poly_t poly) + + Sets \code{res} to the derivative of \code{poly}. + +******************************************************************************* + + Evaluation + +******************************************************************************* + +void _fmpz_poly_evaluate_divconquer_fmpz(fmpz_t res, + const fmpz * poly, slong len, const fmpz_t a) + + Evaluates the polynomial \code{(poly, len)} at the integer~$a$ using + a divide and conquer approach. Assumes that the length of the polynomial + is at least one. Allows zero padding. Does not allow aliasing between + \code{res} and \code{x}. + +void fmpz_poly_evaluate_divconquer_fmpz(fmpz_t res, const fmpz_poly_t poly, + const fmpz_t a) + + Evaluates the polynomial \code{poly} at the integer $a$ using a divide + and conquer approach. + + Aliasing between \code{res} and \code{a} is supported, however, + \code{res} may not be part of \code{poly}. + +void _fmpz_poly_evaluate_horner_fmpz(fmpz_t res, const fmpz * f, slong len, + const fmpz_t a) + + Evaluates the polynomial \code{(f, len)} at the integer $a$ using + Horner's rule, and sets \code{res} to the result. Aliasing between + \code{res} and $a$ or any of the coefficients of $f$ is not supported. + +void fmpz_poly_evaluate_horner_fmpz(fmpz_t res, const fmpz_poly_t f, + const fmpz_t a) + + Evaluates the polynomial $f$ at the integer $a$ using Horner's rule, and + sets \code{res} to the result. + + As expected, aliasing between \code{res} and \code{a} is supported. + However, \code{res} may not be aliased with a coefficient of $f$. + +void _fmpz_poly_evaluate_fmpz(fmpz_t res, const fmpz * f, slong len, + const fmpz_t a) + + Evaluates the polynomial \code{(f, len)} at the integer $a$ and sets + \code{res} to the result. Aliasing between \code{res} and $a$ or any + of the coefficients of $f$ is not supported. + +void fmpz_poly_evaluate_fmpz(fmpz_t res, const fmpz_poly_t f, const fmpz_t a) + + Evaluates the polynomial $f$ at the integer $a$ and sets \code{res} + to the result. + + As expected, aliasing between \code{res} and $a$ is supported. However, + \code{res} may not be aliased with a coefficient of $f$. + +void _fmpz_poly_evaluate_horner_mpq(fmpz_t rnum, fmpz_t rden, + const fmpz * f, slong len, + const fmpz_t anum, const fmpz_t aden) + + Evaluates the polynomial \code{(f, len)} at the rational + \code{(anum, aden)} using Horner's rule, and sets \code{(rnum, rden)} to + the result in lowest terms. + + Aliasing between \code{(rnum, rden)} and \code{(anum, aden)} or any of + the coefficients of $f$ is not supported. + +void fmpz_poly_evaluate_horner_mpq(mpq_t res, const fmpz_poly_t f, + const mpq_t a) + + Evaluates the polynomial $f$ at the rational $a$ using Horner's rule, and + sets \code{res} to the result. + +void _fmpz_poly_evaluate_mpq(fmpz_t rnum, fmpz_t rden, + const fmpz * f, slong len, + const fmpz_t anum, const fmpz_t aden) + + Evaluates the polynomial \code{(f, len)} at the rational + \code{(anum, aden)} and sets \code{(rnum, rden)} to the result in lowest + terms. + + Aliasing between \code{(rnum, rden)} and \code{(anum, aden)} or any of + the coefficients of $f$ is not supported. + +void fmpz_poly_evaluate_mpq(mpq_t res, const fmpz_poly_t f, const mpq_t a) + + Evaluates the polynomial $f$ at the rational $a$ and sets \code{res} to + the result. + +mp_limb_t _fmpz_poly_evaluate_mod(const fmpz * poly, slong len, mp_limb_t a, + mp_limb_t n, mp_limb_t ninv) + + Evaluates \code{(poly, len)} at the value $a$ modulo $n$ and + returns the result. The last argument \code{ninv} must be set + to the precomputed inverse of $n$, which can be obtained using + the function \code{n_preinvert_limb()}. + +mp_limb_t fmpz_poly_evaluate_mod(const fmpz_poly_t poly, mp_limb_t a, + mp_limb_t n) + + Evaluates \code{poly} at the value $a$ modulo $n$ and returns the result. + +void fmpz_poly_evaluate_fmpz_vec(fmpz * res, const fmpz_poly_t f, + const fmpz * a, slong n) + + Evaluates \code{f} at the $n$ values given in the vector \code{f}, + writing the results to \code{res}. + +******************************************************************************* + + Newton basis + +******************************************************************************* + +void _fmpz_poly_monomial_to_newton(fmpz * poly, const fmpz * roots, slong n) + + Converts \code{(poly, n)} in-place from its coefficients given + in the standard monomial basis to the Newton basis + for the roots $r_0, r_1, \ldots, r_{n-2}$. + In other words, this determines output coefficients $c_i$ such that + $$c_0 + c_1(x-r_0) + c_2(x-r_0)(x-r_1) + \ldots + + c_{n-1}(x-r_0)(x-r_1)\cdots(x-r_{n-2})$$ + is equal to the input polynomial. + Uses repeated polynomial division. + +void _fmpz_poly_newton_to_monomial(fmpz * poly, const fmpz * roots, slong n) + + Converts \code{(poly, n)} in-place from its coefficients given + in the Newton basis for the roots $r_0, r_1, \ldots, r_{n-2}$ + to the standard monomial basis. In other words, this evaluates + $$c_0 + c_1(x-r_0) + c_2(x-r_0)(x-r_1) + \ldots + + c_{n-1}(x-r_0)(x-r_1)\cdots(x-r_{n-2})$$ + where $c_i$ are the input coefficients for \code{poly}. + Uses Horner's rule. + +******************************************************************************* + + Interpolation + +******************************************************************************* + +void +fmpz_poly_interpolate_fmpz_vec(fmpz_poly_t poly, + const fmpz * xs, const fmpz * ys, slong n) + + Sets \code{poly} to the unique interpolating polynomial of degree at + most $n - 1$ satisfying $f(x_i) = y_i$ for every pair $x_i, y_u$ in + \code{xs} and \code{ys}, assuming that this polynomial has integer + coefficients. + + If an interpolating polynomial with integer coefficients does not + exist, the result is undefined. + + It is assumed that the $x$ values are distinct. + +******************************************************************************* + + Composition + +******************************************************************************* + +void _fmpz_poly_compose_horner(fmpz * res, + const fmpz * poly1, slong len1, const fmpz * poly2, slong len2) + + Sets \code{res} to the composition of \code{(poly1, len1)} and + \code{(poly2, len2)}. + + Assumes that \code{res} has space for \code{(len1-1)*(len2-1) + 1} + coefficients. Assumes that \code{poly1} and \code{poly2} are non-zero + polynomials. Does not support aliasing between any of the inputs and + the output. + +void fmpz_poly_compose_horner(fmpz_poly_t res, const fmpz_poly_t poly1, + const fmpz_poly_t poly2) + + Sets \code{res} to the composition of \code{poly1} and \code{poly2}. + To be more precise, denoting \code{res}, \code{poly1}, and \code{poly2} + by $f$, $g$, and $h$, sets $f(t) = g(h(t))$. + + This implementation uses Horner's method. + +void _fmpz_poly_compose_divconquer(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2) + + Computes the composition of \code{(poly1, len1)} and \code{(poly2, len2)} + using a divide and conquer approach and places the result into \code{res}, + assuming \code{res} can hold the output of length + \code{(len1 - 1) * (len2 - 1) + 1}. + + Assumes \code{len1, len2 > 0}. Does not support aliasing between + \code{res} and any of \code{(poly1, len1)} and \code{(poly2, len2)}. + +void fmpz_poly_compose_divconquer(fmpz_poly_t res, const fmpz_poly_t poly1, + const fmpz_poly_t poly2) + + Sets \code{res} to the composition of \code{poly1} and \code{poly2}. + To be precise about the order of composition, denoting \code{res}, + \code{poly1}, and \code{poly2} by $f$, $g$, and $h$, respectively, + sets $f(t) = g(h(t))$. + +void _fmpz_poly_compose(fmpz * res, + const fmpz * poly1, slong len1, const fmpz * poly2, slong len2) + + Sets \code{res} to the composition of \code{(poly1, len1)} and + \code{(poly2, len2)}. + + Assumes that \code{res} has space for \code{(len1-1)*(len2-1) + 1} + coefficients. Assumes that \code{poly1} and \code{poly2} are non-zero + polynomials. Does not support aliasing between any of the inputs and + the output. + +void fmpz_poly_compose(fmpz_poly_t res, const fmpz_poly_t poly1, + const fmpz_poly_t poly2) + + Sets \code{res} to the composition of \code{poly1} and \code{poly2}. + To be precise about the order of composition, denoting \code{res}, + \code{poly1}, and \code{poly2} by $f$, $g$, and $h$, respectively, + sets $f(t) = g(h(t))$. + +******************************************************************************* + + Taylor shift + +******************************************************************************* + +void _fmpz_poly_taylor_shift_horner(fmpz * poly, const fmpz_t c, slong n) + + Performs the Taylor shift composing \code{poly} by $x+c$ in-place. + Uses an efficient version Horner's rule. + +void fmpz_poly_taylor_shift_horner(fmpz_poly_t g, const fmpz_poly_t f, + const fmpz_t c) + + Performs the Taylor shift composing \code{f} by $x+c$. + +void _fmpz_poly_taylor_shift_divconquer(fmpz * poly, const fmpz_t c, slong n) + + Performs the Taylor shift composing \code{poly} by $x+c$ in-place. + Uses the divide-and-conquer polynomial composition algorithm. + +void fmpz_poly_taylor_shift_divconquer(fmpz_poly_t g, const fmpz_poly_t f, + const fmpz_t c) + + Performs the Taylor shift composing \code{f} by $x+c$. + Uses the divide-and-conquer polynomial composition algorithm. + +void _fmpz_poly_taylor_shift(fmpz * poly, const fmpz_t c, slong n) + + Performs the Taylor shift composing \code{poly} by $x+c$ in-place. + +void fmpz_poly_taylor_shift(fmpz_poly_t g, const fmpz_poly_t f, const fmpz_t c) + + Performs the Taylor shift composing \code{f} by $x+c$. + +******************************************************************************* + + Power series composition + +******************************************************************************* + +void _fmpz_poly_compose_series_horner(fmpz * res, + const fmpz * poly1, slong len1, const fmpz * poly2, slong len2, slong n) + + Sets \code{res} to the composition of \code{poly1} and \code{poly2} + modulo $x^n$, where the constant term of \code{poly2} is required + to be zero. + + Assumes that \code{len1, len2, n > 0}, that \code{len1, len2 <= n}, + and that\\ \code{(len1-1) * (len2-1) + 1 <= n}, and that \code{res} has + space for \code{n} coefficients. Does not support aliasing between any + of the inputs and the output. + + This implementation uses the Horner scheme. + +void fmpz_poly_compose_series_horner(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2, slong n) + + Sets \code{res} to the composition of \code{poly1} and \code{poly2} + modulo $x^n$, where the constant term of \code{poly2} is required + to be zero. + + This implementation uses the Horner scheme. + +void _fmpz_poly_compose_series_brent_kung(fmpz * res, const fmpz * poly1, + slong len1, const fmpz * poly2, slong len2, slong n) + + Sets \code{res} to the composition of \code{poly1} and \code{poly2} + modulo $x^n$, where the constant term of \code{poly2} is required + to be zero. + + Assumes that \code{len1, len2, n > 0}, that \code{len1, len2 <= n}, + and that\\ \code{(len1-1) * (len2-1) + 1 <= n}, and that \code{res} has + space for \code{n} coefficients. Does not support aliasing between any + of the inputs and the output. + + This implementation uses Brent-Kung algorithm 2.1 \cite{BrentKung1978}. + +void fmpz_poly_compose_series_brent_kung(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2, slong n) + + Sets \code{res} to the composition of \code{poly1} and \code{poly2} + modulo $x^n$, where the constant term of \code{poly2} is required + to be zero. + + This implementation uses Brent-Kung algorithm 2.1 \cite{BrentKung1978}. + +void _fmpz_poly_compose_series(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2, slong n) + + Sets \code{res} to the composition of \code{poly1} and \code{poly2} + modulo $x^n$, where the constant term of \code{poly2} is required + to be zero. + + Assumes that \code{len1, len2, n > 0}, that \code{len1, len2 <= n}, + and that\\ \code{(len1-1) * (len2-1) + 1 <= n}, and that \code{res} has + space for \code{n} coefficients. Does not support aliasing between any + of the inputs and the output. + + This implementation automatically switches between the Horner scheme + and Brent-Kung algorithm 2.1 depending on the size of the inputs. + +void fmpz_poly_compose_series(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2, slong n) + + Sets \code{res} to the composition of \code{poly1} and \code{poly2} + modulo $x^n$, where the constant term of \code{poly2} is required + to be zero. + + This implementation automatically switches between the Horner scheme + and Brent-Kung algorithm 2.1 depending on the size of the inputs. + +******************************************************************************* + + Power series reversion + +******************************************************************************* + +void _fmpz_poly_revert_series_lagrange(fmpz * Qinv, const fmpz * Q, slong n) + + Sets \code{Qinv} to the compositional inverse or reversion of \code{Q} + as a power series, i.e. computes $Q^{-1}$ such that + $Q(Q^{-1}(x)) = Q^{-1}(Q(x)) = x \bmod x^n$. The arguments must + both have length \code{n} and may not be aliased. + It is required that $Q_0 = 0$ and $Q_1 = \pm 1$. + + This implementation uses the Lagrange inversion formula. + +void fmpz_poly_revert_series_lagrange(fmpz_poly_t Qinv, + const fmpz_poly_t Q, slong n) + + Sets \code{Qinv} to the compositional inverse or reversion of \code{Q} + as a power series, i.e. computes $Q^{-1}$ such that + $Q(Q^{-1}(x)) = Q^{-1}(Q(x)) = x \bmod x^n$. + It is required that $Q_0 = 0$ and $Q_1 = \pm 1$. + + This implementation uses the Lagrange inversion formula. + +void _fmpz_poly_revert_series_lagrange_fast(fmpz * Qinv, + const fmpz * Q, slong n) + + Sets \code{Qinv} to the compositional inverse or reversion of \code{Q} + as a power series, i.e. computes $Q^{-1}$ such that + $Q(Q^{-1}(x)) = Q^{-1}(Q(x)) = x \bmod x^n$. The arguments must + both have length \code{n} and may not be aliased. + It is required that $Q_0 = 0$ and $Q_1 = \pm 1$. + + This implementation uses a reduced-complexity implementation + of the Lagrange inversion formula. + +void fmpz_poly_revert_series_lagrange_fast(fmpz_poly_t Qinv, + const fmpz_poly_t Q, slong n) + + Sets \code{Qinv} to the compositional inverse or reversion of \code{Q} + as a power series, i.e. computes $Q^{-1}$ such that + $Q(Q^{-1}(x)) = Q^{-1}(Q(x)) = x \bmod x^n$. + It is required that $Q_0 = 0$ and $Q_1 = \pm 1$. + + This implementation uses a reduced-complexity implementation + of the Lagrange inversion formula. + +void _fmpz_poly_revert_series_newton(fmpz * Qinv, const fmpz * Q, slong n) + + Sets \code{Qinv} to the compositional inverse or reversion of \code{Q} + as a power series, i.e. computes $Q^{-1}$ such that + $Q(Q^{-1}(x)) = Q^{-1}(Q(x)) = x \bmod x^n$. The arguments must + both have length \code{n} and may not be aliased. + It is required that $Q_0 = 0$ and $Q_1 = \pm 1$. + + This implementation uses Newton iteration \cite{BrentKung1978}. + +void fmpz_poly_revert_series_newton(fmpz_poly_t Qinv, + const fmpz_poly_t Q, slong n) + + Sets \code{Qinv} to the compositional inverse or reversion of \code{Q} + as a power series, i.e. computes $Q^{-1}$ such that + $Q(Q^{-1}(x)) = Q^{-1}(Q(x)) = x \bmod x^n$. + It is required that $Q_0 = 0$ and $Q_1 = \pm 1$. + + This implementation uses Newton iteration \cite{BrentKung1978}. + +void _fmpz_poly_revert_series(fmpz * Qinv, const fmpz * Q, slong n) + + Sets \code{Qinv} to the compositional inverse or reversion of \code{Q} + as a power series, i.e. computes $Q^{-1}$ such that + $Q(Q^{-1}(x)) = Q^{-1}(Q(x)) = x \bmod x^n$. The arguments must + both have length \code{n} and may not be aliased. + It is required that $Q_0 = 0$ and $Q_1 = \pm 1$. + + This implementation defaults to the fast version of + Lagrange interpolation. + +void fmpz_poly_revert_series(fmpz_poly_t Qinv, const fmpz_poly_t Q, slong n) + + Sets \code{Qinv} to the compositional inverse or reversion of \code{Q} + as a power series, i.e. computes $Q^{-1}$ such that + $Q(Q^{-1}(x)) = Q^{-1}(Q(x)) = x \bmod x^n$. + It is required that $Q_0 = 0$ and $Q_1 = \pm 1$. + + This implementation defaults to the fast version of + Lagrange interpolation. + +******************************************************************************* + + Square root + +******************************************************************************* + +int _fmpz_poly_sqrt_classical(fmpz * res, const fmpz * poly, slong len) + + If \code{(poly, len)} is a perfect square, sets \code{(res, len / 2 + 1)} + to the square root of \code{poly} with positive leading coefficient + and returns 1. Otherwise returns 0. + + This function first uses various tests to detect nonsquares quickly. + Then, it computes the square root iteratively from top to bottom, + requiring $O(n^2)$ coefficient operations. + +int fmpz_poly_sqrt_classical(fmpz_poly_t b, const fmpz_poly_t a) + + If \code{a} is a perfect square, sets \code{b} to the square root of + \code{a} with positive leading coefficient and returns 1. + Otherwise returns 0. + +int _fmpz_poly_sqrt(fmpz * res, const fmpz * poly, slong len) + + If \code{(poly, len)} is a perfect square, sets \code{(res, len / 2 + 1)} + to the square root of \code{poly} with positive leading coefficient + and returns 1. Otherwise returns 0. + +int fmpz_poly_sqrt(fmpz_poly_t b, const fmpz_poly_t a) + + If \code{a} is a perfect square, sets \code{b} to the square root of + \code{a} with positive leading coefficient and returns 1. + Otherwise returns 0. + +******************************************************************************* + + Signature + +******************************************************************************* + +void _fmpz_poly_signature(slong * r1, slong * r2, const fmpz * poly, slong len) + + Computes the signature $(r_1, r_2)$ of the polynomial + \code{(poly, len)}. Assumes that the polynomial is squarefree over~$\Q$. + +void fmpz_poly_signature(slong * r1, slong * r2, const fmpz_poly_t poly) + + Computes the signature $(r_1, r_2)$ of the polynomial \code{poly}, + which is assumed to be square-free over~$\Q$. The values of $r_1$ and + $2 r_2$ are the number of real and complex roots of the polynomial, + respectively. For convenience, the zero polynomial is allowed, in which + case the output is $(0, 0)$. + + If the polynomial is not square-free, the behaviour is undefined and an + exception may be raised. + + This function uses the algorithm described + in~\citep[Algorithm~4.1.11]{Coh1996}. + +******************************************************************************* + + Hensel lifting + +******************************************************************************* + +void fmpz_poly_hensel_build_tree(slong * link, fmpz_poly_t *v, fmpz_poly_t *w, + const nmod_poly_factor_t fac) + + Initialises and builds a Hensel tree consisting of two arrays $v$, $w$ + of polynomials an array of links, called \code{link}. + + The caller supplies a set of $r$ local factors (in the factor structure + \code{fac}) of some polynomial $F$ over $\mathbf{Z}$. They also supply + two arrays of initialised polynomials $v$ and $w$, each of length + $2r - 2$ and an array \code{link}, also of length $2r - 2$. + + We will have five arrays: a $v$ of \code{fmpz_poly_t}'s and a $V$ of + \code{nmod_poly_t}'s and also a $w$ and a $W$ and \code{link}. Here's + the idea: we sort each leaf and node of a factor tree by degree, in + fact choosing to multiply the two smallest factors, then the next two + smallest (factors or products) etc.\ until a tree is made. The tree + will be stored in the $v$'s. The first two elements of $v$ will be the + smallest modular factors, the last two elements of $v$ will multiply to + form $F$ itself. Since $v$ will be rearranging the original factors we + will need to be able to recover the original order. For this we use the + array \code{link} which has nonnegative even numbers and negative numbers. + It is an array of \code{slong}'s which aligns with $V$ and $v$ if + \code{link} has a negative number in spot $j$ that means $V_j$ is an + original modular factor which has been lifted, if \code{link[j]} is a + nonnegative even number then $V_j$ stores a product of the two entries + at \code{V[link[j]]} and \code{V[link[j]+1]}. + $W$ and $w$ play the role of the extended GCD, at $V_0$, $V_2$, $V_4$, + etc.\ we have a new product, $W_0$, $W_2$, $W_4$, etc.\ are the XGCD + cofactors of the $V$'s. For example, + $V_0 W_0 + V_1 W_1 \equiv 1 \pmod{p^{\ell}}$ for some $\ell$. These + will be lifted along with the entries in $V$. It is not enough to just + lift each factor, we have to lift the entire tree and the tree of + XGCD cofactors. + +void fmpz_poly_hensel_lift(fmpz_poly_t G, fmpz_poly_t H, + fmpz_poly_t A, fmpz_poly_t B, + const fmpz_poly_t f, + const fmpz_poly_t g, const fmpz_poly_t h, + const fmpz_poly_t a, const fmpz_poly_t b, + const fmpz_t p, const fmpz_t p1) + + This is the main Hensel lifting routine, which performs a Hensel step + from polynomials mod $p$ to polynomials mod $P = p p_1$. One starts with + polynomials $f$, $g$, $h$ such that $f = gh \pmod p$. The polynomials + $a$, $b$ satisfy $ag + bh = 1 \pmod p$. + + The lifting formulae are + \begin{align*} + G & = \biggl( \bigl( \frac{f-gh}{p} \bigr) b \bmod g \biggr) p + g \\ + H & = \biggl( \bigl( \frac{f-gh}{p} \bigr) a \bmod h \biggr) p + h \\ + B & = \biggl( \bigl( \frac{1-aG-bH}{p} \bigr) b \bmod g \biggr) p + b \\ + A & = \biggl( \bigl( \frac{1-aG-bH}{p} \bigr) a \bmod h \biggr) p + a. + \end{align*} + + Upon return we have $A G + B H = 1 \pmod P$ and $f = G H \pmod P$, + where $G = g \pmod p$ etc. + + We require that $1 < p_1 \leq p$ and that the input polynomials $f, g, h$ + have degree at least~$1$ and that the input polynomials $a$ and $b$ are + non-zero. + + The output arguments $G, H, A, B$ may only be aliased with + the input arguments $g, h, a, b$, respectively. + +void fmpz_poly_hensel_lift_without_inverse(fmpz_poly_t Gout, fmpz_poly_t Hout, + const fmpz_poly_t f, const fmpz_poly_t g, const fmpz_poly_t h, + const fmpz_poly_t a, const fmpz_poly_t b, + const fmpz_t p, const fmpz_t p1) + + Given polynomials such that $f = gh \pmod p$ and $ag + bh = 1 \pmod p$, + lifts only the factors $g$ and $h$ modulo $P = p p_1$. + + See \code{fmpz_poly_hensel_lift()}. + +void fmpz_poly_hensel_lift_only_inverse(fmpz_poly_t Aout, fmpz_poly_t Bout, + const fmpz_poly_t G, const fmpz_poly_t H, + const fmpz_poly_t a, const fmpz_poly_t b, + const fmpz_t p, const fmpz_t p1) + + Given polynomials such that $f = gh \pmod p$ and $ag + bh = 1 \pmod p$, + lifts only the cofactors $a$ and $b$ modulo $P = p p_1$. + + See \code{fmpz_poly_hensel_lift()}. + +void fmpz_poly_hensel_lift_tree_recursive(slong *link, + fmpz_poly_t *v, fmpz_poly_t *w, fmpz_poly_t f, slong j, slong inv, + const fmpz_t p0, const fmpz_t p1) + + Takes a current Hensel tree \code{(link, v, w)} and a pair $(j,j+1)$ + of entries in the tree and lifts the tree from mod $p_0$ to + mod $P = p_0 p_1$, where $1 < p_1 \leq p_0$. + + Set \code{inv} to $-1$ if restarting Hensel lifting, $0$ if stopping + and $1$ otherwise. + + Here $f = g h$ is the polynomial whose factors we are trying to lift. + We will have that \code{v[j]} is the product of \code{v[link[j]]} and + \code{v[link[j] + 1]} as described above. + + Does support aliasing of $f$ with one of the polynomials in + the lists $v$ and $w$. But the polynomials in these two lists + are not allowed to be aliases of each other. + +void fmpz_poly_hensel_lift_tree(slong *link, fmpz_poly_t *v, fmpz_poly_t *w, + fmpz_poly_t f, slong r, const fmpz_t p, slong e0, slong e1, slong inv) + + Computes $p_0 = p^{e_0}$ and $p_1 = p^{e_1 - e_0}$ for a small prime $p$ + and $P = p^{e_1}$. + + If we aim to lift to $p^b$ then $f$ is the polynomial whose factors we + wish to lift, made monic mod $p^b$. As usual, \code{(link, v, w)} is an + initialised tree. + + This starts the recursion on lifting the \emph{product tree} for lifting + from $p^{e_0}$ to $p^{e_1}$. The value of \code{inv} corresponds to that + given for the function \code{fmpz_poly_hensel_lift_tree_recursive()}. We + set $r$ to the number of local factors of $f$. + + In terms of the notation, above $P = p^{e_1}$, $p_0 = p^{e_0}$ and + $p_1 = p^{e_1-e_0}$. + + Assumes that $f$ is monic. + + Assumes that $1 < p_1 \leq p_0$, that is, $0 < e_1 \leq e_0$. + +slong _fmpz_poly_hensel_start_lift(fmpz_poly_factor_t lifted_fac, slong *link, + fmpz_poly_t *v, fmpz_poly_t *w, const fmpz_poly_t f, + const nmod_poly_factor_t local_fac, slong N) + + This function takes the local factors in \code{local_fac} + and Hensel lifts them until they are known mod $p^N$, where + $N \geq 1$. + + These lifted factors will be stored (in the same ordering) in + \code{lifted_fac}. It is assumed that \code{link}, \code{v}, and + \code{w} are initialized arrays \code{fmpz_poly_t}'s with at least + $2*r - 2$ entries and that $r \geq 2$. This is done outside of + this function so that you can keep them for restarting Hensel lifting + later. The product of local factors must be squarefree. + + The return value is an exponent which must be passed to the function\\ + \code{_fmpz_poly_hensel_continue_lift()} as \code{prev_exp} if the + Hensel lifting is to be resumed. + + Currently, supports the case when $N = 1$ for convenience, + although it is preferable in this case to simple iterate + over the local factors and convert them to polynomials over + $\mathbf{Z}$. + +slong _fmpz_poly_hensel_continue_lift(fmpz_poly_factor_t lifted_fac, + slong *link, fmpz_poly_t *v, fmpz_poly_t *w, const fmpz_poly_t f, + slong prev, slong curr, slong N, const fmpz_t p) + + This function restarts a stopped Hensel lift. + + It lifts from \code{curr} to $N$. It also requires \code{prev} + (to lift the cofactors) given as the return value of the function + \code{_fmpz_poly_hensel_start_lift()} or the function\\ + \code{_fmpz_poly_hensel_continue_lift()}. The current lifted factors + are supplied in \code{lifted_fac} and upon return are updated + there. As usual \code{link}, \code{v}, and \code{w} describe the + current Hensel tree, $r$ is the number of local factors and $p$ is + the small prime modulo whose power we are lifting to. It is required + that \code{curr} be at least $1$ and that \code{N > curr}. + + Currently, supports the case when \code{prev} and \code{curr} + are equal. + +void fmpz_poly_hensel_lift_once(fmpz_poly_factor_t lifted_fac, + const fmpz_poly_t f, + const nmod_poly_factor_t local_fac, slong N) + + This function does a Hensel lift. + + It lifts local factors stored in \code{local_fac} of $f$ to $p^N$, + where $N \geq 2$. The lifted factors will be stored in \code{lifted_fac}. + This lift cannot be restarted. This function is a convenience function + intended for end users. The product of local factors must be squarefree. + +******************************************************************************* + + Input and output + + The functions in this section are not intended to be particularly fast. + They are intended mainly as a debugging aid. + + For the string output functions there are two variants. The first uses a + simple string representation of polynomials which prints only the length + of the polynomial and the integer coefficients, whilst the latter variant, + appended with \code{_pretty}, uses a more traditional string + representation of polynomials which prints a variable name as part of the + representation. + + The first string representation is given by a sequence of integers, in + decimal notation, separated by white space. The first integer gives the + length of the polynomial; the remaining integers are the coefficients. + For example $5x^3 - x + 1$ is represented by the string + \code{"4 1 -1 0 5"}, and the zero polynomial is represented by \code{"0"}. + The coefficients may be signed and arbitrary precision. + + The string representation of the functions appended by \code{_pretty} + includes only the non-zero terms of the polynomial, starting with the + one of highest degree. Each term starts with a coefficient, prepended + with a sign, followed by the character \code{*}, followed by a variable + name, which must be passed as a string parameter to the function, + followed by a carot \code{^} followed by a non-negative exponent. + + If the sign of the leading coefficient is positive, it is omitted. Also + the exponents of the degree $1$ and $0$ terms are omitted, as is the + variable and the \code{*} character in the case of the degree $0$ + coefficient. If the coefficient is plus or minus one, the coefficient + is omitted, except for the sign. + + Some examples of the \code{_pretty} representation are: + + \begin{lstlisting} + 5*x^3+7*x-4 + x^2+3 + -x^4+2*x-1 + x+1 + 5 + \end{lstlisting} + +******************************************************************************* + +int _fmpz_poly_print(const fmpz * poly, slong len) + + Prints the polynomial \code{(poly, len)} to \code{stdout}. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + +int fmpz_poly_print(const fmpz_poly_t poly) + + Prints the polynomial to \code{stdout}. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + +int _fmpz_poly_print_pretty(const fmpz * poly, slong len, const char * x) + + Prints the pretty representation of \code{(poly, len)} to \code{stdout}, + using the string \code{x} to represent the indeterminate. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + +int fmpz_poly_print_pretty(const fmpz_poly_t poly, const char * x) + + Prints the pretty representation of \code{poly} to \code{stdout}, + using the string \code{x} to represent the indeterminate. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + +int _fmpz_poly_fprint(FILE * file, const fmpz * poly, slong len) + + Prints the polynomial \code{(poly, len)} to the stream \code{file}. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + +int fmpz_poly_fprint(FILE * file, const fmpz_poly_t poly) + + Prints the polynomial to the stream \code{file}. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + +int _fmpz_poly_fprint_pretty(FILE * file, + const fmpz * poly, slong len, char * x) + + Prints the pretty representation of \code{(poly, len)} to the stream + \code{file}, using the string \code{x} to represent the indeterminate. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + +int fmpz_poly_fprint_pretty(FILE * file, const fmpz_poly_t poly, char * x) + + Prints the pretty representation of \code{poly} to the stream \code{file}, + using the string \code{x} to represent the indeterminate. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + +int fmpz_poly_read(fmpz_poly_t poly) + + Reads a polynomial from \code{stdin}, storing the result in \code{poly}. + + In case of success, returns a positive number. In case of failure, + returns a non-positive value. + +int fmpz_poly_read_pretty(fmpz_poly_t poly, char **x) + + Reads a polynomial in pretty format from \code{stdin}. + + For further details, see the documentation for the function + \code{fmpz_poly_fread_pretty()}. + +int fmpz_poly_fread(FILE * file, fmpz_poly_t poly) + + Reads a polynomial from the stream \code{file}, storing the result + in \code{poly}. + + In case of success, returns a positive number. In case of failure, + returns a non-positive value. + +int fmpz_poly_fread_pretty(FILE *file, fmpz_poly_t poly, char **x) + + Reads a polynomial from the file \code{file} and sets \code{poly} + to this polynomial. The string \code{*x} is set to the variable + name that is used in the input. + + The parser is implemented via a finite state machine as follows: + \begin{verbatim} + state event next state + ---------------------------- + 0 '-' 1 + D 2 + V0 3 + 1 D 2 + V0 3 + 2 D 2 + '*' 4 + '+', '-' 1 + 3 V 3 + '^' 5 + '+', '-' 1 + 4 V0 3 + 5 D 6 + 6 D 6 + '+', '-' 1 + \end{verbatim} + Here, {\tt D} refers to any digit, {\tt V0} to any character which + is allowed as the first character in the variable name (an alphetic + character), and {\tt V} to any character which is allowed in the + remaining part of the variable name (an alphanumeric character or + underscore). + + Once we encounter a character which does not fit into the above + pattern, we stop. + + Returns a positive value, equal to the number of characters read from + the file, in case of success. Returns a non-positive value in case of + failure, which could either be a read error or the indicator of a + malformed input. + +******************************************************************************* + + Modular reduction and reconstruction + +******************************************************************************* + +void fmpz_poly_get_nmod_poly(nmod_poly_t Amod, fmpz_poly_t A) + + Sets the coefficients of \code{Amod} to the coefficients in \code{A}, + reduced by the modulus of \code{Amod}. + +void fmpz_poly_set_nmod_poly(fmpz_poly_t A, const nmod_poly_t Amod) + + Sets the coefficients of \code{A} to the residues in \code{Amod}, + normalised to the interval $-m/2 \le r < m/2$ where $m$ is the modulus. + +void fmpz_poly_set_nmod_poly_unsigned(fmpz_poly_t A, const nmod_poly_t Amod) + + Sets the coefficients of \code{A} to the residues in \code{Amod}, + normalised to the interval $0 \le r < m$ where $m$ is the modulus. + +void +_fmpz_poly_CRT_ui_precomp(fmpz * res, const fmpz * poly1, slong len1, + const fmpz_t m1, mp_srcptr poly2, slong len2, mp_limb_t m2, + mp_limb_t m2inv, fmpz_t m1m2, mp_limb_t c, int sign) + + Sets the coefficients in \code{res} to the CRT reconstruction modulo + $m_1m_2$ of the residues \code{(poly1, len1)} and \code{(poly2, len2)} + which are images modulo $m_1$ and $m_2$ respectively. + The caller must supply the precomputed product of the input moduli as + $m_1m_2$, the inverse of $m_1$ modulo $m_2$ as $c$, and + the precomputed inverse of $m_2$ (in the form computed by + \code{n_preinvert_limb}) as \code{m2inv}. + + If \code{sign} = 0, residues $0 <= r < m_1 m_2$ are computed, while + if \code{sign} = 1, residues $-m_1 m_2/2 <= r < m_1 m_2/2$ are computed. + + Coefficients of \code{res} are written up to the maximum of + \code{len1} and \code{len2}. + +void +_fmpz_poly_CRT_ui(fmpz * res, const fmpz * poly1, slong len1, + const fmpz_t m1, mp_srcptr poly2, slong len2, mp_limb_t m2, + mp_limb_t m2inv, int sign) + + This function is identical to \code{_fmpz_poly_CRT_ui_precomp}, + apart from automatically computing $m_1m_2$ and $c$. It also + aborts if $c$ cannot be computed. + +void fmpz_poly_CRT_ui(fmpz_poly_t res, const fmpz_poly_t poly1, + const fmpz_t m, const nmod_poly_t poly2, int sign) + + Given \code{poly1} with coefficients modulo \code{m} and \code{poly2} + with modulus $n$, sets \code{res} to the CRT reconstruction modulo $mn$ + with coefficients satisfying $-mn/2 \le c < mn/2$ (if sign = 1) + or $0 \le c < mn$ (if sign = 0). + +******************************************************************************* + + Products + +******************************************************************************* + +void _fmpz_poly_product_roots_fmpz_vec(fmpz * poly, const fmpz * xs, slong n) + + Sets \code{(poly, n + 1)} to the monic polynomial which is the product + of $(x - x_0)(x - x_1) \cdots (x - x_{n-1})$, the roots $x_i$ being + given by \code{xs}. + + Aliasing of the input and output is not allowed. + + +void fmpz_poly_product_roots_fmpz_vec(fmpz_poly_t poly, + const fmpz * xs, slong n) + + Sets \code{poly} to the monic polynomial which is the product + of $(x - x_0)(x - x_1) \cdots (x - x_{n-1})$, the roots $x_i$ being + given by \code{xs}. + +******************************************************************************* + + Newton basis conversion + +******************************************************************************* + +void _fmpz_poly_monomial_to_newton(fmpz * poly, const fmpz * roots, slong n) + + Converts the polynomial in-place from its coefficients in the + monomial basis to the Newton basis $1, (x-r_0), (x-r_0)(x-r_1), \ldots$. + Uses Horner's rule, requiring $O(n^2)$ operations. + +void _fmpz_poly_newton_to_monomial(fmpz * poly, const fmpz * roots, slong n) + + Converts the polynomial in-place from its coefficients in the + Newton basis $1, (x-r_0), (x-r_0)(x-r_1), \ldots$ to the monomial + basis. Uses repeated polynomial division, requiring $O(n^2)$ operations. + +******************************************************************************* + + Roots + +******************************************************************************* + +void _fmpz_poly_bound_roots(fmpz_t bound, const fmpz * poly, slong len) + +void fmpz_poly_bound_roots(fmpz_t bound, const fmpz_poly_t poly) + + Computes a nonnegative integer \code{bound} that bounds the absolute + value of all complex roots of \code{poly}. Uses Fujiwara's bound + + $$ + 2 \max \left( + \left|\frac{a_{n-1}}{a_n}\right|, + \left|\frac{a_{n-2}}{a_n}\right|^{\frac{1}{2}}, \dots + \left|\frac{a_1}{a_n}\right|^{\frac{1}{n-1}}, + \left|\frac{a_0}{2a_n}\right|^{\frac{1}{n}} + \right) + $$ + + where the coefficients of the polynomial are $a_0, \ldots, a_n$. + diff --git a/external/flint-2.4.3/fmpz_poly/equal.c b/external/flint-2.4.3/fmpz_poly/equal.c new file mode 100644 index 0000000..b65a4e6 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/equal.c @@ -0,0 +1,47 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +int +fmpz_poly_equal(const fmpz_poly_t poly1, const fmpz_poly_t poly2) +{ + slong i; + + if (poly1 == poly2) + return 1; /* same polynomial */ + + if (poly1->length != poly2->length) + return 0; /* check if lengths the same */ + + for (i = 0; i < poly1->length; i++) /* check if coefficients the same */ + if (!fmpz_equal(poly1->coeffs + i, poly2->coeffs + i)) + return 0; + + return 1; +} diff --git a/external/flint-2.4.3/fmpz_poly/evaluate_divconquer_fmpz.c b/external/flint-2.4.3/fmpz_poly/evaluate_divconquer_fmpz.c new file mode 100644 index 0000000..82308b7 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/evaluate_divconquer_fmpz.c @@ -0,0 +1,108 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void +_fmpz_poly_evaluate_divconquer_fmpz(fmpz_t res, const fmpz * poly, slong len, + const fmpz_t x) +{ + slong c, h, i, k = 1; + fmpz *y, *T, *t = res, *u; + + h = FLINT_BIT_COUNT(len - 1); /* 2^{h-1} < len <= 2^h */ + y = _fmpz_vec_init(2 * h + 2); /* x^{2^0}, x^{2^1}, ..., x^{2^{h-1}} */ + T = y + h; + u = y + 2 * h + 1; + + *y = *x; + for (i = 1; i < h; i++) + fmpz_mul(y + i, y + (i - 1), y + (i - 1)); + + for (i = 0; i < len - 1; ) + { + fmpz_mul(u, y + 0, poly + i + 1); + fmpz_add(t, poly + i, u); + i += 2; + count_trailing_zeros(c, i); + for (k = 1; k < c; k++) + { + fmpz_mul(u, y + k, t); + fmpz_add(t, T + k, u); + } + fmpz_swap(T + k, t); + } + if (len & WORD(1)) + { + fmpz_set(t, poly + (len - 1)); + count_trailing_zeros(c, len + 1); + for (k = 1; k < c; k++) + { + fmpz_mul(u, y + k, t); + fmpz_add(t, T + k, u); + } + fmpz_swap(T + k, t); + } + fmpz_swap(t, T + k); + + for ( ; k < h; k++) + { + if ((len - 1) & (WORD(1) << k)) + { + fmpz_mul(u, y + k, t); + fmpz_add(t, T + k, u); + } + } + + *y = WORD(0); + _fmpz_vec_clear(y, 2 * h + 2); +} + +void +fmpz_poly_evaluate_divconquer_fmpz(fmpz_t res, const fmpz_poly_t poly, + const fmpz_t a) +{ + if (fmpz_poly_is_zero(poly)) + { + fmpz_zero(res); + return; + } + + if (res == a) + { + fmpz_t t; + + fmpz_init(t); + _fmpz_poly_evaluate_divconquer_fmpz(t, poly->coeffs, poly->length, a); + fmpz_swap(res, t); + fmpz_clear(t); + } + else + _fmpz_poly_evaluate_divconquer_fmpz(res, poly->coeffs, poly->length, a); +} + diff --git a/external/flint-2.4.3/fmpz_poly/evaluate_fmpz.c b/external/flint-2.4.3/fmpz_poly/evaluate_fmpz.c new file mode 100644 index 0000000..9fb869d --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/evaluate_fmpz.c @@ -0,0 +1,54 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +void +_fmpz_poly_evaluate_fmpz(fmpz_t res, const fmpz * f, slong len, const fmpz_t a) +{ + if (len <= 50) + _fmpz_poly_evaluate_horner_fmpz(res, f, len, a); + else + _fmpz_poly_evaluate_divconquer_fmpz(res, f, len, a); +} + +void +fmpz_poly_evaluate_fmpz(fmpz_t res, const fmpz_poly_t f, const fmpz_t a) +{ + if (res == a) + { + fmpz_t t; + + fmpz_init(t); + _fmpz_poly_evaluate_fmpz(t, f->coeffs, f->length, a); + fmpz_swap(res, t); + fmpz_clear(t); + } + else + _fmpz_poly_evaluate_fmpz(res, f->coeffs, f->length, a); +} diff --git a/external/flint-2.4.3/fmpz_poly/evaluate_fmpz_vec.c b/external/flint-2.4.3/fmpz_poly/evaluate_fmpz_vec.c new file mode 100644 index 0000000..bd1c445 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/evaluate_fmpz_vec.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +void +fmpz_poly_evaluate_fmpz_vec(fmpz * res, const fmpz_poly_t f, + const fmpz * a, slong n) +{ + slong i; + + for (i = 0; i < n; i++) + fmpz_poly_evaluate_fmpz(res + i, f, a + i); +} diff --git a/external/flint-2.4.3/fmpz_poly/evaluate_horner_fmpz.c b/external/flint-2.4.3/fmpz_poly/evaluate_horner_fmpz.c new file mode 100644 index 0000000..7602064 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/evaluate_horner_fmpz.c @@ -0,0 +1,72 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +void +_fmpz_poly_evaluate_horner_fmpz(fmpz_t res, const fmpz * f, slong len, + const fmpz_t a) +{ + if (len == 0) + { + fmpz_zero(res); + } + else if (len == 1 || fmpz_is_zero(a)) + { + fmpz_set(res, f); + } + else + { + slong i = len - 1; + fmpz_t t; + + fmpz_init(t); + fmpz_set(res, f + i); + for (i = len - 2; i >= 0; i--) + { + fmpz_mul(t, res, a); + fmpz_add(res, f + i, t); + } + fmpz_clear(t); + } +} + +void +fmpz_poly_evaluate_horner_fmpz(fmpz_t res, const fmpz_poly_t f, const fmpz_t a) +{ + if (res == a) + { + fmpz_t t; + fmpz_init(t); + _fmpz_poly_evaluate_horner_fmpz(t, f->coeffs, f->length, a); + fmpz_swap(res, t); + fmpz_clear(t); + } + else + _fmpz_poly_evaluate_horner_fmpz(res, f->coeffs, f->length, a); +} diff --git a/external/flint-2.4.3/fmpz_poly/evaluate_horner_mpq.c b/external/flint-2.4.3/fmpz_poly/evaluate_horner_mpq.c new file mode 100644 index 0000000..573cde8 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/evaluate_horner_mpq.c @@ -0,0 +1,94 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +void +_fmpz_poly_evaluate_horner_mpq(fmpz_t rnum, fmpz_t rden, + const fmpz * f, slong len, + const fmpz_t anum, const fmpz_t aden) +{ + if (len == 0) + { + fmpz_zero(rnum); + fmpz_one(rden); + } + else if (len == 1) + { + fmpz_set(rnum, f); + fmpz_one(rden); + } + else + { + slong i = len - 1; + fmpz_t d; + fmpz_init(d); + + fmpz_set(rnum, f + i); + fmpz_one(rden); + do + { + --i; + fmpz_mul(rnum, rnum, anum); + fmpz_mul(rden, rden, aden); + { + fmpz_gcd(d, rnum, rden); + fmpz_divexact(rnum, rnum, d); + fmpz_divexact(rden, rden, d); + } + + fmpz_addmul(rnum, rden, f + i); + if (*rnum == WORD(0)) + fmpz_one(rden); + } while (i); + + fmpz_clear(d); + } +} + +void +fmpz_poly_evaluate_horner_mpq(mpq_t res, const fmpz_poly_t f, const mpq_t a) +{ + fmpz_t rnum, rden, anum, aden; + fmpz_init(rnum); + fmpz_init(rden); + fmpz_init(anum); + fmpz_init(aden); + fmpz_set_mpz(anum, mpq_numref(a)); + fmpz_set_mpz(aden, mpq_denref(a)); + + _fmpz_poly_evaluate_horner_mpq(rnum, rden, f->coeffs, f->length, anum, aden); + + fmpz_get_mpz(mpq_numref(res), rnum); + fmpz_get_mpz(mpq_denref(res), rden); + fmpz_clear(rnum); + fmpz_clear(rden); + fmpz_clear(anum); + fmpz_clear(aden); + +} diff --git a/external/flint-2.4.3/fmpz_poly/evaluate_mod.c b/external/flint-2.4.3/fmpz_poly/evaluate_mod.c new file mode 100644 index 0000000..307cfc3 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/evaluate_mod.c @@ -0,0 +1,67 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +mp_limb_t _fmpz_poly_evaluate_mod(const fmpz * poly, slong len, mp_limb_t a, + mp_limb_t n, mp_limb_t ninv) +{ + mp_limb_t c, res = 0; + + while (len--) + { + c = fmpz_fdiv_ui(poly + len, n); + res = n_addmod(n_mulmod2_preinv(res, a, n, ninv), c, n); + } + + return res; +} + +mp_limb_t fmpz_poly_evaluate_mod(const fmpz_poly_t poly, mp_limb_t a, + mp_limb_t n) +{ + if (poly->length == 0) + return 0; + + if (a == 0) + { + mp_limb_t res; + res = fmpz_fdiv_ui(poly->coeffs, n); + return res; + } + else + { + mp_limb_t ninv; + + ninv = n_preinvert_limb(n); + return _fmpz_poly_evaluate_mod(poly->coeffs, poly->length, a, n, ninv); + } +} + diff --git a/external/flint-2.4.3/fmpz_poly/evaluate_mpq.c b/external/flint-2.4.3/fmpz_poly/evaluate_mpq.c new file mode 100644 index 0000000..e5c46fe --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/evaluate_mpq.c @@ -0,0 +1,57 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +void +_fmpz_poly_evaluate_mpq(fmpz_t rnum, fmpz_t rden, const fmpz * f, slong len, + const fmpz_t anum, const fmpz_t aden) +{ + _fmpz_poly_evaluate_horner_mpq(rnum, rden, f, len, anum, aden); +} + +void +fmpz_poly_evaluate_mpq(mpq_t res, const fmpz_poly_t f, const mpq_t a) +{ + fmpz_t rnum, rden, anum, aden; + fmpz_init(rnum); + fmpz_init(rden); + fmpz_init(anum); + fmpz_init(aden); + fmpz_set_mpz(anum, mpq_numref(a)); + fmpz_set_mpz(aden, mpq_denref(a)); + + _fmpz_poly_evaluate_mpq(rnum, rden, f->coeffs, f->length, anum, aden); + + fmpz_get_mpz(mpq_numref(res), rnum); + fmpz_get_mpz(mpq_denref(res), rden); + fmpz_clear(rnum); + fmpz_clear(rden); + fmpz_clear(anum); + fmpz_clear(aden); +} diff --git a/external/flint-2.4.3/fmpz_poly/fit_length.c b/external/flint-2.4.3/fmpz_poly/fit_length.c new file mode 100644 index 0000000..afd908a --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/fit_length.c @@ -0,0 +1,41 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +void +fmpz_poly_fit_length(fmpz_poly_t poly, slong len) +{ + if (len > poly->alloc) + { + /* At least double number of allocated coeffs */ + if (len < 2 * poly->alloc) + len = 2 * poly->alloc; + fmpz_poly_realloc(poly, len); + } +} diff --git a/external/flint-2.4.3/fmpz_poly/fprint.c b/external/flint-2.4.3/fmpz_poly/fprint.c new file mode 100644 index 0000000..94e88f8 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/fprint.c @@ -0,0 +1,45 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 + +******************************************************************************/ + +#include +#include +#include + +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +int _fmpz_poly_fprint(FILE * file, const fmpz * poly, slong len) +{ + return _fmpz_vec_fprint(file, poly, len); +} + +int fmpz_poly_fprint(FILE * file, const fmpz_poly_t poly) +{ + return _fmpz_vec_fprint(file, poly->coeffs, poly->length); +} + diff --git a/external/flint-2.4.3/fmpz_poly/fprint_pretty.c b/external/flint-2.4.3/fmpz_poly/fprint_pretty.c new file mode 100644 index 0000000..7600fdb --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/fprint_pretty.c @@ -0,0 +1,184 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include + +#include "fmpz_poly.h" + +int _fmpz_poly_fprint_pretty(FILE * file, + const fmpz * poly, slong len, const char * x) +{ + int r; + slong i; + + FMPZ_VEC_NORM(poly, len); + + if (len == 0) + { + r = fputc('0', file); + r = (r != EOF) ? 1 : EOF; + return r; + } + else if (len == 1) + { + r = fmpz_fprint(file, poly + 0); + return r; + } + else if (len == 2) + { + if (*(poly + 1) == WORD(1)) + { + r = flint_fprintf(file, "%s", x); + } + else if (*(poly + 1) == WORD(-1)) + { + r = flint_fprintf(file, "-%s", x); + } + else + { + r = fmpz_fprint(file, poly + 1); + if (r > 0) + r = flint_fprintf(file, "*%s", x); + } + + if (r > 0) + { + if (fmpz_sgn(poly + 0) > 0) + { + r = flint_fprintf(file, "+"); + if (r > 0) + r = fmpz_fprint(file, poly + 0); + } + else if (fmpz_sgn(poly + 0) < 0) + { + r = fmpz_fprint(file, poly + 0); + } + } + return r; + } + + i = len - 1; /* i >= 2 */ + r = 1; + { + if (*(poly + i) == 1) + r = flint_fprintf(file, "%s^%wd", x, i); + else if (*(poly + i) == -1) + r = flint_fprintf(file, "-%s^%wd", x, i); + else + { + r = fmpz_fprint(file, poly + i); + if (r > 0) + r = flint_fprintf(file, "*%s^%wd", x, i); + } + --i; + } + + for (; (r > 0) && (i > 1); --i) + { + if (*(poly + i) == 0) + continue; + + if (*(poly + i) == 1) + r = flint_fprintf(file, "+%s^%wd", x, i); + else if (*(poly + i) == -1) + r = flint_fprintf(file, "-%s^%wd", x, i); + else + { + if (fmpz_sgn(poly + i) > 0) + { + r = fputc('+', file); + r = (r != EOF) ? 1 : EOF; + } + if (r > 0) + r = fmpz_fprint(file, poly + i); + if (r > 0) + r = flint_fprintf(file, "*%s^%wd", x, i); + } + } + + if ((r > 0) && *(poly + 1)) + { + if (*(poly + 1) == 1) + { + r = fputc('+', file); + r = (r != EOF) ? 1 : EOF; + if (r > 0) + { + r = fputs(x, file); + r = (r >= 0) ? 1 : -1; + } + } + else if (*(poly + 1) == -1) + { + r = fputc('-', file); + r = (r != EOF) ? 1 : EOF; + if (r > 0) + { + r = fputs(x, file); + r = (r >= 0) ? 1 : -1; + } + } + else + { + if (fmpz_sgn(poly + 1) > 0) + { + r = fputc('+', file); + r = (r != EOF) ? 1 : EOF; + } + if (r > 0) + r = fmpz_fprint(file, poly + 1); + if (r > 0) + { + r = fputc('*', file); + r = (r != EOF) ? 1 : EOF; + } + if (r > 0) + { + r = fputs(x, file); + r = (r >= 0) ? 1 : -1; + } + } + } + if ((r > 0) && *(poly)) + { + if (fmpz_sgn(poly) > 0) + { + r = fputc('+', file); + r = (r != EOF) ? 1 : EOF; + } + if (r > 0) + r = fmpz_fprint(file, poly); + } + + return r; +} + +int fmpz_poly_fprint_pretty(FILE * file, + const fmpz_poly_t poly, const char * x) +{ + return _fmpz_poly_fprint_pretty(file, poly->coeffs, poly->length, x); +} + diff --git a/external/flint-2.4.3/fmpz_poly/fread.c b/external/flint-2.4.3/fmpz_poly/fread.c new file mode 100644 index 0000000..b56c6da --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/fread.c @@ -0,0 +1,67 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +int fmpz_poly_fread(FILE * file, fmpz_poly_t poly) +{ + int r; + slong i, len; + mpz_t t; + + mpz_init(t); + r = mpz_inp_str(t, file, 10); + if (r == 0) + { + mpz_clear(t); + return 0; + } + if (!mpz_fits_slong_p(t)) + { + flint_printf("Exception (fmpz_poly_fread). Length does not fit into a slong.\n"); + abort(); + } + len = flint_mpz_get_si(t); + mpz_clear(t); + + fmpz_poly_fit_length(poly, len); + + for (i = 0; i < len; i++) + { + r = fmpz_fread(file, poly->coeffs + i); + if (r <= 0) + return r; + } + + _fmpz_poly_set_length(poly, len); + _fmpz_poly_normalise(poly); + + return 1; +} + diff --git a/external/flint-2.4.3/fmpz_poly/fread_pretty.c b/external/flint-2.4.3/fmpz_poly/fread_pretty.c new file mode 100644 index 0000000..e6ed478 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/fread_pretty.c @@ -0,0 +1,290 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include +#include + +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +static __inline__ +int is_varsymbol0(char c) +{ + return isalpha((unsigned char) c); +} + +static __inline__ +int is_varsymbol1(char c) +{ + return isalnum((unsigned char) c) || (c == '_'); +} + +#define next_event() \ +do { \ + c = fgetc(file); \ + if (c == EOF && !feof(file)) \ + goto s_ioe; \ + ++r; \ + if (i == N) \ + { \ + buf = flint_realloc(buf, N = 2*N); \ + } \ + buf[i++] = c; \ +} while (0) + +#define add_coeff() \ +do { \ + fmpz_set_mpz(f_coeff, z_coeff); \ + fmpz_poly_fit_length(poly, exp + 1); \ + fmpz_add(poly->coeffs + exp, poly->coeffs + exp, f_coeff); \ + if (poly->length < exp + 1) \ + poly->length = exp + 1; \ +} while (0) + +int fmpz_poly_fread_pretty(FILE *file, fmpz_poly_t poly, char **x) +{ + /* + var - variable name + buf - buffer of size N, at write position i, with c == buf[i-1] + z_coeff - mpz_t for the coefficient, f_coeff is the fmpz_t version + z_exp - mpz_t for the exponent, exp is the slong version + r - return value + */ + + char *var = NULL; + + char c, *buf; + int i, N; + + fmpz_t f_coeff; + mpz_t z_coeff, z_exp; + slong exp; + + int r = 0; + + fmpz_poly_zero(poly); + if (poly->alloc) + flint_mpn_zero((mp_ptr) poly->coeffs, poly->alloc); + + i = 0; + N = 80; + buf = flint_malloc(N); + + fmpz_init(f_coeff); + mpz_init(z_coeff); + mpz_init(z_exp); + + /* s_0 : */ + + next_event(); + + if (c == '-') + goto s_1; + if (isdigit((unsigned char) c)) + goto s_2; + if (is_varsymbol0(c)) + { + flint_mpz_set_si(z_coeff, 1); + goto s_3; + } + + goto s_parse_error; + + s_1 : + + next_event(); + + if (isdigit((unsigned char) c)) + goto s_2; + if (is_varsymbol0(c)) + { + if (i == 1) + flint_mpz_set_si(z_coeff, 1); + else /* i == 2 */ + { + flint_mpz_set_si(z_coeff, -1); + buf[0] = c; + i = 1; + } + goto s_3; + } + + goto s_parse_error; + + s_2 : + + next_event(); + + if (isdigit((unsigned char) c)) + goto s_2; + if (c == '*') + { + buf[i-1] = '\0'; + mpz_set_str(z_coeff, buf, 10); + i = 0; + goto s_4; + } + { + buf[i-1] = '\0'; + mpz_set_str(z_coeff, buf, 10); + exp = 0; + add_coeff(); + if (c == '+' || c == '-') + { + i = 0; + if (c == '-') + buf[i++] = '-'; + goto s_1; + } + else + goto s_end; + } + + s_3 : + + next_event(); + + if (is_varsymbol1(c)) + goto s_3; + + { + buf[i-1] = '\0'; + if (var) + { + if (strcmp(buf, var)) /* Parse error */ + goto s_parse_error; + } + else + { + var = flint_malloc(i); + strcpy(var, buf); + } + + if (c == '^') + { + i = 0; + goto s_5; + } + else if (c == '+' || c == '-') + { + exp = 1; + add_coeff(); + + i = 0; + if (c == '-') + buf[i++] = '-'; + goto s_1; + } + else + { + exp = 1; + add_coeff(); + goto s_end; + } + } + + s_4 : + + next_event(); + + if (is_varsymbol0(c)) + goto s_3; + + goto s_parse_error; + + s_5 : + + next_event(); + + if (isdigit((unsigned char) c)) + goto s_6; + + goto s_parse_error; + + s_6 : + + next_event(); + + if (isdigit((unsigned char) c)) + goto s_6; + + { + buf[i-1] = '\0'; + mpz_set_str(z_exp, buf, 10); + if (!mpz_fits_slong_p(z_exp)) + { + goto s_parse_error; + } + exp = flint_mpz_get_si(z_exp); + add_coeff(); + + if (c == '+' || c == '-') + { + i = 0; + if (c == '-') + buf[i++] = '-'; + goto s_1; + } + else + goto s_end; + } + + s_parse_error : + + r = -2; + goto s_end; + + s_ioe : + + r = -1; + goto s_end; + + s_end : + + _fmpz_poly_normalise(poly); + + if (var) + *x = var; + else + { + *x = flint_malloc(1); + **x = '\0'; + } + + fmpz_clear(f_coeff); + mpz_clear(z_coeff); + mpz_clear(z_exp); + flint_free(buf); + + return r; +} + +#undef next_event +#undef add_coeff + diff --git a/external/flint-2.4.3/fmpz_poly/gcd.c b/external/flint-2.4.3/fmpz_poly/gcd.c new file mode 100644 index 0000000..20994e4 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/gcd.c @@ -0,0 +1,98 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void +_fmpz_poly_gcd(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2) +{ + + if (len1 < 6) + { + _fmpz_poly_gcd_subresultant(res, poly1, len1, poly2, len2); + } + else + { + slong b1, b2; + + b1 = _fmpz_vec_max_bits(poly1, len1); + b2 = _fmpz_vec_max_bits(poly2, len2); + b1 = FLINT_ABS(b1); + b2 = FLINT_ABS(b2); + + if (b1 + b2 < 2 * FLINT_BITS) + { + if (_fmpz_poly_gcd_heuristic(res, poly1, len1, poly2, len2)) + return; + } + + _fmpz_poly_gcd_modular(res, poly1, len1, poly2, len2); + } +} + +void +fmpz_poly_gcd(fmpz_poly_t res, const fmpz_poly_t poly1, + const fmpz_poly_t poly2) +{ + if (poly1->length < poly2->length) + { + fmpz_poly_gcd(res, poly2, poly1); + } + else /* len1 >= len2 >= 0 */ + { + const slong len1 = poly1->length; + const slong len2 = poly2->length; + + if (len1 == 0) /* len1 = len2 = 0 */ + { + fmpz_poly_zero(res); + } + else if (len2 == 0) /* len1 > len2 = 0 */ + { + if (fmpz_sgn(poly1->coeffs + (len1 - 1)) > 0) + fmpz_poly_set(res, poly1); + else + fmpz_poly_neg(res, poly1); + } + else /* len1 >= len2 >= 1 */ + { + /* all current gcd functions automatically handle aliasing */ + + fmpz_poly_fit_length(res, len2); + + _fmpz_poly_gcd(res->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2); + + _fmpz_poly_set_length(res, len2); + _fmpz_poly_normalise(res); + } + } +} + diff --git a/external/flint-2.4.3/fmpz_poly/gcd_heuristic.c b/external/flint-2.4.3/fmpz_poly/gcd_heuristic.c new file mode 100644 index 0000000..4a07dfb --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/gcd_heuristic.c @@ -0,0 +1,335 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" +#include "mpn_extras.h" + +/* + Divide (arrayg, limbsg) by the positive value gc inplace and + return the number of limbs written +*/ +mp_size_t flint_mpn_tdiv_q_fmpz_inplace(mp_ptr arrayg, mp_size_t limbsg, fmpz_t gc) +{ + if (fmpz_size(gc) == 1) + { + mpn_divmod_1(arrayg, arrayg, limbsg, fmpz_get_ui(gc)); + return limbsg - (arrayg[limbsg - 1] == 0); + } + else + { + mp_size_t tlimbs; + __mpz_struct * mpz_ptr = COEFF_TO_PTR(*gc); + + mp_ptr temp = flint_malloc(limbsg*sizeof(mp_limb_t)); + flint_mpn_copyi(temp, arrayg, limbsg); + + mpn_tdiv_q(arrayg, temp, limbsg, mpz_ptr->_mp_d, mpz_ptr->_mp_size); + tlimbs = limbsg - mpz_ptr->_mp_size + 1; + tlimbs -= (arrayg[tlimbs - 1] == 0); + + flint_free(temp); + return tlimbs; + } +} + +/* + Returns 1 if sign * (G, glen) * (Q, qlen) = (P, len), else returns 0. + Temp requires space for glen + qlen - 1 coefficients +*/ +int multiplies_out(fmpz * P, slong len, const fmpz * Q, slong qlen, + const fmpz * G, slong glen, slong sign, fmpz * temp) +{ + int divides = 0; + + /* multiply out */ + if (qlen >= glen) + _fmpz_poly_mul(temp, Q, qlen, G, glen); + else + _fmpz_poly_mul(temp, G, glen, Q, qlen); + if (sign < WORD(0)) _fmpz_vec_neg(temp, temp, glen + qlen - 1); + + /* check if quotient really was exact */ + divides = (glen + qlen - 1 == len && _fmpz_vec_equal(temp, P, len)); + + return divides; +} + +/* Assumes len1 != 0 != len2 */ +int +_fmpz_poly_gcd_heuristic(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2) +{ + ulong bits1, bits2, max_bits, pack_bits, bound_bits, bits_G, bits_Q; + ulong limbs1, limbs2, limbsg, pack_limbs, qlimbs; + ulong log_glen, log_length; + slong sign1, sign2, glen, qlen; + fmpz_t ac, bc, d, gc; + fmpz * A, * B, * G, * Q, * t; + mp_ptr array1, array2, arrayg, q, temp; + int divides; + + fmpz_init(ac); + fmpz_init(bc); + fmpz_init(d); + + /* compute gcd of content of poly1 and poly2 */ + _fmpz_poly_content(ac, poly1, len1); + _fmpz_poly_content(bc, poly2, len2); + fmpz_gcd(d, ac, bc); + + /* special case, one of the polys is a constant */ + if (len2 == 1) /* if len1 == 1 then so does len2 */ + { + fmpz_set(res, d); + + fmpz_clear(ac); + fmpz_clear(bc); + fmpz_clear(d); + + return 1; + } + + /* divide poly1 and poly2 by their content */ + A = _fmpz_vec_init(len1); + B = _fmpz_vec_init(len2); + _fmpz_vec_scalar_divexact_fmpz(A, poly1, len1, ac); + _fmpz_vec_scalar_divexact_fmpz(B, poly2, len2, bc); + fmpz_clear(ac); + fmpz_clear(bc); + + /* special case, one of the polys is length 2 */ + if (len2 == 2) /* if len1 == 2 then so does len2 */ + { + Q = _fmpz_vec_init(len1 - len2 + 1); + if (_fmpz_poly_divides(Q, A, len1, B, 2)) + { + _fmpz_vec_scalar_mul_fmpz(res, B, 2, d); + if (fmpz_sgn(res + 1) < 0) + _fmpz_vec_neg(res, res, 2); + } + else + { + fmpz_set(res, d); + fmpz_zero(res + 1); + } + + fmpz_clear(d); + _fmpz_vec_clear(A, len1); + _fmpz_vec_clear(B, len2); + _fmpz_vec_clear(Q, len1 - len2 + 1); + + return 1; + } + + /* + Determine how many bits (pack_bits) to pack into. The bound + bound_bits ensures that if G | A and G | B with G primitive + then G is the gcd of A and B. The bound is taken from + http://arxiv.org/abs/cs/0206032v1 + */ + bits1 = FLINT_ABS(_fmpz_vec_max_bits(A, len1)); + bits2 = FLINT_ABS(_fmpz_vec_max_bits(B, len2)); + max_bits = FLINT_MAX(bits1, bits2); + + bound_bits = FLINT_MIN(bits1, bits2) + 6; + pack_bits = FLINT_MAX(bound_bits, max_bits); /* need to pack original polys */ + pack_limbs = (pack_bits - 1)/FLINT_BITS + 1; + + if (pack_bits >= 32) /* pack into multiples of limbs if >= 32 bits */ + pack_bits = FLINT_BITS*pack_limbs; + + /* allocate space to pack into */ + limbs1 = (pack_bits*len1 - 1)/FLINT_BITS + 1; + limbs2 = (pack_bits*len2 - 1)/FLINT_BITS + 1; + array1 = flint_calloc(limbs1, sizeof(mp_limb_t)); + array2 = flint_calloc(limbs2, sizeof(mp_limb_t)); + arrayg = flint_calloc(limbs2, sizeof(mp_limb_t)); + + /* pack first poly and normalise */ + sign1 = (slong) fmpz_sgn(A + len1 - 1); + _fmpz_poly_bit_pack(array1, A, len1, pack_bits, sign1); + while (array1[limbs1 - 1] == 0) limbs1--; + + /* pack second poly and normalise */ + sign2 = (slong) fmpz_sgn(B + len2 - 1); + _fmpz_poly_bit_pack(array2, B, len2, pack_bits, sign2); + while (array2[limbs2 - 1] == 0) limbs2--; + + /* compute integer GCD */ + limbsg = flint_mpn_gcd_full(arrayg, array1, limbs1, array2, limbs2); + + /* + Make space for unpacked gcd. May have one extra coeff due to + 1 0 -x being packed as 0 -1 -x. + */ + glen = FLINT_MIN((limbsg*FLINT_BITS)/pack_bits + 1, len2); + G = _fmpz_vec_init(glen); + + /* + clear bits after g in arrayg so they are not inadvertently + pulled into G after bit unpacking + */ + flint_mpn_zero(arrayg + limbsg, limbs2-limbsg); + + /* unpack gcd */ + _fmpz_poly_bit_unpack(G, glen, arrayg, pack_bits, 0); + while (G[glen - 1] == 0) glen--; + + /* divide by any content */ + fmpz_init(gc); + _fmpz_poly_content(gc, G, glen); + + if (!fmpz_is_one(gc)) + limbsg = flint_mpn_tdiv_q_fmpz_inplace(arrayg, limbsg, gc); + + /* make space for quotient and remainder of first poly by gcd */ + qlimbs = limbs1 - limbsg + 1; + qlen = FLINT_MIN(len1, (qlimbs*FLINT_BITS)/pack_bits + 1); + qlimbs = (qlen*pack_bits - 1)/FLINT_BITS + 1; + q = flint_calloc(qlimbs, sizeof(mp_limb_t)); + temp = flint_malloc(limbsg*sizeof(mp_limb_t)); + + divides = 0; + + if (flint_mpn_divides(q, array1, limbs1, arrayg, limbsg, temp)) + { + /* unpack quotient of first poly by gcd */ + Q = _fmpz_vec_init(len1); + t = _fmpz_vec_init(len1 + glen); + _fmpz_poly_bit_unpack(Q, qlen, q, pack_bits, 0); + while (Q[qlen - 1] == 0) qlen--; + + /* divide by content */ + _fmpz_vec_scalar_divexact_fmpz(G, G, glen, gc); + + /* check if we really need to multiply out to check for exact quotient */ + bits_G = FLINT_ABS(_fmpz_vec_max_bits(G, glen)); + bits_Q = FLINT_ABS(_fmpz_vec_max_bits(Q, qlen)); + log_glen = FLINT_BIT_COUNT(glen); + log_length = FLINT_MIN(log_glen, FLINT_BIT_COUNT(qlen)); + + divides = (bits_G + bits_Q + log_length < pack_bits); + + if (!divides) /* need to multiply out to check exact quotient */ + divides = multiplies_out(A, len1, Q, qlen, G, glen, sign1, t); + + if (divides) /* quotient really was exact */ + { + flint_mpn_zero(q, qlimbs); + + if (flint_mpn_divides(q, array2, limbs2, arrayg, limbsg, temp)) + { + /* unpack quotient of second poly by gcd */ + qlimbs = limbs2 - limbsg + 1; + qlen = FLINT_MIN(len2, (qlimbs*FLINT_BITS - 1)/pack_bits + 1); + _fmpz_poly_bit_unpack(Q, qlen, q, pack_bits, 0); + while (Q[qlen - 1] == 0) qlen--; + + /* check if we really need to multiply out to check for exact quotient */ + bits_Q = FLINT_ABS(_fmpz_vec_max_bits(Q, qlen)); + log_length = FLINT_MIN(log_glen, FLINT_BIT_COUNT(qlen)); + + divides = (bits_G + bits_Q + log_length < pack_bits); + + if (!divides) /* we need to multiply out */ + divides = multiplies_out(B, len2, Q, qlen, G, glen, sign1, t); + } + } + + _fmpz_vec_clear(t, len1 + glen); + _fmpz_vec_clear(Q, len1); + } + + flint_free(q); + flint_free(temp); + flint_free(arrayg); + flint_free(array1); + flint_free(array2); + fmpz_clear(gc); + + _fmpz_vec_clear(A, len1); + _fmpz_vec_clear(B, len2); + + /* we found the gcd, so multiply by content */ + if (divides) + { + _fmpz_vec_zero(res + glen, len2 - glen); + _fmpz_vec_scalar_mul_fmpz(res, G, glen, d); + } + + fmpz_clear(d); + _fmpz_vec_clear(G, glen); + + return divides; +} + +int +fmpz_poly_gcd_heuristic(fmpz_poly_t res, const fmpz_poly_t poly1, + const fmpz_poly_t poly2) +{ + if (poly1->length < poly2->length) + { + return fmpz_poly_gcd_heuristic(res, poly2, poly1); + } + else /* len1 >= len2 >= 0 */ + { + const slong len1 = poly1->length; + const slong len2 = poly2->length; + int done = 1; /* len1 = 0 or len2 = 0 need done = 1 */ + + if (len1 == 0) /* len1 = len2 = 0 */ + { + fmpz_poly_zero(res); + } + else if (len2 == 0) /* len1 > len2 = 0 */ + { + if (fmpz_sgn(poly1->coeffs + (len1 - 1)) > 0) + fmpz_poly_set(res, poly1); + else + fmpz_poly_neg(res, poly1); + } + else /* len1 >= len2 >= 1 */ + { + /* underscore function automatically takes care of aliasing */ + + fmpz_poly_fit_length(res, len2); + + done = _fmpz_poly_gcd_heuristic(res->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2); + + if (done) + { + _fmpz_poly_set_length(res, len2); + _fmpz_poly_normalise(res); + } + } + + return done; + } +} diff --git a/external/flint-2.4.3/fmpz_poly/gcd_modular.c b/external/flint-2.4.3/fmpz_poly/gcd_modular.c new file mode 100644 index 0000000..a5470c2 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/gcd_modular.c @@ -0,0 +1,346 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" +#include "mpn_extras.h" + + +void _fmpz_poly_gcd_modular(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2) +{ + mp_bitcnt_t bits1, bits2, nb1, nb2, bits_small, pbits, curr_bits = 0, new_bits; + fmpz_t ac, bc, hc, d, g, l, eval_A, eval_B, eval_GCD, modulus; + fmpz * A, * B, * Q, * lead_A, * lead_B; + mp_ptr a, b, h; + mp_limb_t p, h_inv, g_mod; + nmod_t mod; + slong i, n, n0, unlucky, hlen, bound; + int g_pm1; + + fmpz_init(ac); + fmpz_init(bc); + fmpz_init(d); + + /* compute gcd of content of poly1 and poly2 */ + _fmpz_vec_content(ac, poly1, len1); + _fmpz_vec_content(bc, poly2, len2); + fmpz_gcd(d, ac, bc); + + /* special case, one of the polys is a constant */ + if (len2 == 1) /* if len1 == 1 then so does len2 */ + { + fmpz_set(res, d); + + fmpz_clear(ac); + fmpz_clear(bc); + fmpz_clear(d); + return; + } + + /* divide poly1 and poly2 by their content */ + A = _fmpz_vec_init(len1); + B = _fmpz_vec_init(len2); + _fmpz_vec_scalar_divexact_fmpz(A, poly1, len1, ac); + _fmpz_vec_scalar_divexact_fmpz(B, poly2, len2, bc); + fmpz_clear(ac); + fmpz_clear(bc); + + /* get bound on size of gcd coefficients */ + lead_A = A + len1 - 1; + lead_B = B + len2 - 1; + + bits1 = _fmpz_vec_max_bits(A, len1); bits1 = FLINT_ABS(bits1); + bits2 = _fmpz_vec_max_bits(B, len2); bits2 = FLINT_ABS(bits2); + + fmpz_init(l); + + if (len1 < 64 && len2 < 64) /* compute the squares of the 2-norms */ + { + fmpz_set_ui(l, 0); + for (i = 0; i < len1; i++) + fmpz_addmul(l, A + i, A + i); + nb1 = fmpz_bits(l); + fmpz_set_ui(l, 0); + for (i = 0; i < len2; i++) + fmpz_addmul(l, B + i, B + i); + nb2 = fmpz_bits(l); + } else /* approximate to save time */ + { + nb1 = 2*bits1 + FLINT_BIT_COUNT(len1); + nb2 = 2*bits2 + FLINT_BIT_COUNT(len2); + } + + /* get gcd of leading coefficients */ + fmpz_init(g); + fmpz_gcd(g, lead_A, lead_B); + fmpz_mul(l, lead_A, lead_B); + + g_pm1 = fmpz_is_pm1(g); + + /* evaluate -A at -1 */ + fmpz_init(eval_A); + for (i = 0; i < len1; i++) + { + if (i & 1) fmpz_add(eval_A, eval_A, A + i); + else fmpz_sub(eval_A, eval_A, A + i); + } + + /* evaluate -B at -1 */ + fmpz_init(eval_B); + for (i = 0; i < len2; i++) + { + if (i & 1) fmpz_add(eval_B, eval_B, B + i); + else fmpz_sub(eval_B, eval_B, B + i); + } + + /* compute the gcd of eval(-A, -1) and eval(-B, -1) */ + fmpz_init(eval_GCD); + fmpz_gcd(eval_GCD, eval_A, eval_B); + + /* compute a heuristic bound after which we should begin checking if we're done */ + bits_small = FLINT_MAX(fmpz_bits(eval_GCD), fmpz_bits(g)); + if (bits_small < WORD(2)) bits_small = 2; + + fmpz_clear(eval_GCD); + fmpz_clear(eval_A); + fmpz_clear(eval_B); + + /* set size of first prime */ + pbits = FLINT_BITS - 1; + p = (UWORD(1)< n + 1) /* discard this prime */ + { + unlucky += pbits; + continue; + } + + /* scale new polynomial mod p appropriately */ + if (g_pm1) _nmod_poly_make_monic(h, h, hlen, mod); + else + { + h_inv = n_invmod(h[hlen - 1], mod.n); + g_mod = fmpz_fdiv_ui(g, mod.n); + h_inv = n_mulmod2_preinv(h_inv, g_mod, mod.n, mod.ninv); + _nmod_vec_scalar_mul_nmod(h, h, hlen, h_inv, mod); + } + + if (hlen <= n) /* we have a new bound on size of result */ + { + unlucky += fmpz_bits(modulus); + _fmpz_vec_set_nmod_vec(res, h, hlen, mod); + _fmpz_vec_zero(res + hlen, len2 - hlen); + + if (g_pm1) + { + /* are we done? */ + if (_fmpz_poly_divides(Q, B, len2, res, hlen) && + _fmpz_poly_divides(Q, A, len1, res, hlen)) + break; + } + else + { + if (pbits + unlucky >= bound) /* if we reach the bound with one prime */ + { + _fmpz_vec_content(hc, res, hlen); + + /* divide by content */ + _fmpz_vec_scalar_divexact_fmpz(res, res, hlen, hc); + break; + } + + if (pbits >= bits_small) /* if one prime is already big enough to check */ + { + /* divide by content */ + _fmpz_vec_content(hc, res, hlen); + + /* correct sign of leading term */ + if (fmpz_sgn(res + hlen - 1) < 0) + fmpz_neg(hc, hc); + + _fmpz_vec_scalar_divexact_fmpz(res, res, hlen, hc); + + /* are we done? */ + if (_fmpz_poly_divides(Q, B, len2, res, hlen) && + _fmpz_poly_divides(Q, A, len1, res, hlen)) + break; + + /* no, so multiply by content again */ + _fmpz_vec_scalar_mul_fmpz(res, res, hlen, hc); + } + } + + curr_bits = FLINT_ABS(_fmpz_vec_max_bits(res, hlen)); + fmpz_set_ui(modulus, p); + n = hlen - 1; /* if we reach this we have a new bound on length of result */ + continue; + } + + _fmpz_poly_CRT_ui(res, res, hlen, modulus, h, hlen, mod.n, mod.ninv, 1); + fmpz_mul_ui(modulus, modulus, mod.n); + + new_bits = _fmpz_vec_max_bits(res, hlen); + new_bits = FLINT_ABS(new_bits); + + if (new_bits == curr_bits || fmpz_bits(modulus) >= bits_small) + { + if (!g_pm1) + { + _fmpz_vec_content(hc, res, hlen); + + /* correct sign of leading term */ + if (fmpz_sgn(res + hlen - 1) < 0) + fmpz_neg(hc, hc); + + /* divide by content */ + _fmpz_vec_scalar_divexact_fmpz(res, res, hlen, hc); + } + + if (fmpz_bits(modulus) + unlucky >= bound) + break; + + /* are we done? */ + if (_fmpz_poly_divides(Q, B, len2, res, hlen) && + _fmpz_poly_divides(Q, A, len1, res, hlen)) + break; + + if (!g_pm1) + { + /* no, so multiply by content again */ + _fmpz_vec_scalar_mul_fmpz(res, res, hlen, hc); + } + } + + curr_bits = new_bits; + } + + fmpz_clear(modulus); + fmpz_clear(g); + fmpz_clear(l); + fmpz_clear(hc); + + _nmod_vec_clear(a); + _nmod_vec_clear(b); + _nmod_vec_clear(h); + + /* finally multiply by content */ + _fmpz_vec_scalar_mul_fmpz(res, res, hlen, d); + + fmpz_clear(d); + _fmpz_vec_clear(A, len1); + _fmpz_vec_clear(B, len2); + _fmpz_vec_clear(Q, len1); +} + +void +fmpz_poly_gcd_modular(fmpz_poly_t res, const fmpz_poly_t poly1, + const fmpz_poly_t poly2) +{ + if (poly1->length < poly2->length) + { + fmpz_poly_gcd_modular(res, poly2, poly1); + } + else /* len1 >= len2 >= 0 */ + { + const slong len1 = poly1->length; + const slong len2 = poly2->length; + + if (len1 == 0) /* len1 = len2 = 0 */ + { + fmpz_poly_zero(res); + } + else if (len2 == 0) /* len1 > len2 = 0 */ + { + if (fmpz_sgn(poly1->coeffs + (len1 - 1)) > 0) + fmpz_poly_set(res, poly1); + else + fmpz_poly_neg(res, poly1); + } + else /* len1 >= len2 >= 1 */ + { + /* underscore function automatically aliases */ + fmpz_poly_fit_length(res, len2); + + _fmpz_poly_gcd_modular(res->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2); + + + _fmpz_poly_set_length(res, len2); + _fmpz_poly_normalise(res); + } + } +} + diff --git a/external/flint-2.4.3/fmpz_poly/gcd_subresultant.c b/external/flint-2.4.3/fmpz_poly/gcd_subresultant.c new file mode 100644 index 0000000..273488a --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/gcd_subresultant.c @@ -0,0 +1,170 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void +_fmpz_poly_gcd_subresultant(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2) +{ + if (len2 == 1) + { + fmpz_t c; + fmpz_init(c); + _fmpz_poly_content(c, poly1, len1); + fmpz_gcd(res, c, poly2); + fmpz_clear(c); + } + else + { + fmpz_t a, b, d, g, h; + fmpz *A, *B, *W; + slong lenA, lenB; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(d); + fmpz_init(g); + fmpz_init(h); + + A = W = _fmpz_vec_init(len1 + len2); + B = W + len1; + + lenA = len1; + lenB = len2; + _fmpz_poly_content(a, poly1, lenA); + _fmpz_poly_content(b, poly2, lenB); + _fmpz_vec_scalar_divexact_fmpz(A, poly1, lenA, a); + _fmpz_vec_scalar_divexact_fmpz(B, poly2, lenB, b); + + fmpz_gcd(d, a, b); + fmpz_one(g); + fmpz_one(h); + + while (1) + { + const slong delta = lenA - lenB; + + _fmpz_poly_pseudo_rem_cohen(A, A, lenA, B, lenB); + + FMPZ_VEC_NORM(A, lenA); + + if (lenA <= 1) + break; + + { /* Swap A and B */ + fmpz *T; + slong len; + T = A, A = B, B = T, len = lenA, lenA = lenB, lenB = len; + } + + if (delta == 1) + { + fmpz_mul(b, g, h); + _fmpz_vec_scalar_divexact_fmpz(B, B, lenB, b); + fmpz_set(g, A + (lenA - 1)); + fmpz_set(h, g); + } + else + { + fmpz_pow_ui(a, h, delta); + fmpz_mul(b, g, a); + _fmpz_vec_scalar_divexact_fmpz(B, B, lenB, b); + fmpz_pow_ui(b, A + (lenA - 1), delta); + fmpz_mul(g, h, b); + fmpz_divexact(h, g, a); + fmpz_set(g, A + (lenA - 1)); + } + } + + if (lenA == 1) + { + fmpz_set(res, d); + _fmpz_vec_zero(res + 1, len2 - 1); + } + else + { + _fmpz_poly_content(b, B, lenB); + _fmpz_vec_scalar_divexact_fmpz(B, B, lenB, b); + if (fmpz_sgn(B + (lenB - 1)) < 0) + fmpz_neg(d, d); + _fmpz_vec_scalar_mul_fmpz(res, B, lenB, d); + if (len2 >= lenB) + _fmpz_vec_zero(res + lenB, len2 - lenB); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(d); + fmpz_clear(g); + fmpz_clear(h); + + _fmpz_vec_clear(W, len1 + len2); + } +} + +void +fmpz_poly_gcd_subresultant(fmpz_poly_t res, const fmpz_poly_t poly1, + const fmpz_poly_t poly2) +{ + if (poly1->length < poly2->length) + { + fmpz_poly_gcd_subresultant(res, poly2, poly1); + } + else /* len1 >= len2 >= 0 */ + { + const slong len1 = poly1->length; + const slong len2 = poly2->length; + + if (len1 == 0) /* len1 = len2 = 0 */ + { + fmpz_poly_zero(res); + } + else if (len2 == 0) /* len1 > len2 = 0 */ + { + if (fmpz_sgn(poly1->coeffs + (len1 - 1)) > 0) + fmpz_poly_set(res, poly1); + else + fmpz_poly_neg(res, poly1); + } + else /* len1 >= len2 >= 1 */ + { + /* underscore code automatically handles aliasing */ + + fmpz_poly_fit_length(res, len2); + + _fmpz_poly_gcd_subresultant(res->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2); + + _fmpz_poly_set_length(res, len2); + _fmpz_poly_normalise(res); + } + } +} diff --git a/external/flint-2.4.3/fmpz_poly/get_coeff_fmpz.c b/external/flint-2.4.3/fmpz_poly/get_coeff_fmpz.c new file mode 100644 index 0000000..279bb19 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/get_coeff_fmpz.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +void +fmpz_poly_get_coeff_fmpz(fmpz_t x, const fmpz_poly_t poly, slong n) +{ + if (n < poly->length) + fmpz_set(x, poly->coeffs + n); + else + fmpz_zero(x); +} diff --git a/external/flint-2.4.3/fmpz_poly/get_coeff_si.c b/external/flint-2.4.3/fmpz_poly/get_coeff_si.c new file mode 100644 index 0000000..e150a48 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/get_coeff_si.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +slong +fmpz_poly_get_coeff_si(const fmpz_poly_t poly, slong n) +{ + return (n < poly->length) ? fmpz_get_si(poly->coeffs + n) : WORD(0); +} diff --git a/external/flint-2.4.3/fmpz_poly/get_coeff_ui.c b/external/flint-2.4.3/fmpz_poly/get_coeff_ui.c new file mode 100644 index 0000000..458c7b1 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/get_coeff_ui.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +ulong +fmpz_poly_get_coeff_ui(const fmpz_poly_t poly, slong n) +{ + return (n < poly->length) ? fmpz_get_ui(poly->coeffs + n) : UWORD(0); +} diff --git a/external/flint-2.4.3/fmpz_poly/get_nmod_poly.c b/external/flint-2.4.3/fmpz_poly/get_nmod_poly.c new file mode 100644 index 0000000..e47f745 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/get_nmod_poly.c @@ -0,0 +1,51 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" +#include "nmod_poly.h" + +void +fmpz_poly_get_nmod_poly(nmod_poly_t res, const fmpz_poly_t poly) +{ + slong len = poly->length; + + if (len == 0) + { + nmod_poly_zero(res); + } + else + { + slong i; + nmod_poly_fit_length(res, len); + for (i = 0; i < len; i++) + res->coeffs[i] = fmpz_fdiv_ui(poly->coeffs + i, res->mod.n); + res->length = len; + _nmod_poly_normalise(res); + } +} diff --git a/external/flint-2.4.3/fmpz_poly/get_str.c b/external/flint-2.4.3/fmpz_poly/get_str.c new file mode 100644 index 0000000..d601110 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/get_str.c @@ -0,0 +1,72 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +char * +_fmpz_poly_get_str(const fmpz * poly, slong len) +{ + slong i, bound; + char *str, *strbase; + + if (len == 0) + { + str = (char *) flint_malloc(2 * sizeof(char)); + str[0] = '0'; + str[1] = '\0'; + return str; + } + + bound = (slong) (ceil(log10((double) (len + 1)))); + for (i = 0; i < len; i++) + bound += fmpz_sizeinbase(poly + i, 10) + 1; + bound += len + 2; + + strbase = (char *) flint_malloc(bound * sizeof(char)); + str = strbase; + + str += flint_sprintf(str, "%wd ", len); + do + { + if (!COEFF_IS_MPZ(*poly)) + str += flint_sprintf(str, " %wd", *poly); + else + str += gmp_sprintf(str, " %Zd", COEFF_TO_PTR(*poly)); + } while (poly++, --len); + + return strbase; +} + +char * +fmpz_poly_get_str(const fmpz_poly_t poly) +{ + return _fmpz_poly_get_str(poly->coeffs, poly->length); +} diff --git a/external/flint-2.4.3/fmpz_poly/get_str_pretty.c b/external/flint-2.4.3/fmpz_poly/get_str_pretty.c new file mode 100644 index 0000000..7e483e6 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/get_str_pretty.c @@ -0,0 +1,121 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +char * +_fmpz_poly_get_str_pretty(const fmpz * poly, slong len, const char *x) +{ + char *str; + size_t off; + slong i, bound, nz; + + if (len == 0) + { + str = flint_malloc(2); + str[0] = '0'; + str[1] = '\0'; + return str; + } + + if (len == 1) + { + str = fmpz_get_str(NULL, 10, poly); + return str; + } + + nz = 0; + bound = 1; + for (i = 0; i < len; i++) + if (!fmpz_is_zero(poly + i)) + { + bound += fmpz_sizeinbase(poly + i, 10) + 1; + nz++; + } + bound += nz * (3 + strlen(x) + (slong) (ceil(log10(len)))); + + str = flint_malloc(bound); + off = 0; + i = len - 1; + + if (poly[i] == WORD(1)) + { + } + else if (poly[i] == WORD(-1)) + str[off++] = '-'; + else if (!COEFF_IS_MPZ(poly[i])) + off += flint_sprintf(str + off, "%wd*", poly[i]); + else + off += gmp_sprintf(str + off, "%Zd*", COEFF_TO_PTR(poly[i])); + if (i > 1) + off += flint_sprintf(str + off, "%s^%wd", x, i); + else + off += flint_sprintf(str + off, "%s", x); + + for (--i; i > 0; --i) + { + if (poly[i] == WORD(0)) + continue; + if (fmpz_sgn(poly + i) > 0) + str[off++] = '+'; + if (poly[i] == WORD(-1)) + str[off++] = '-'; + if (poly[i] != WORD(1) && poly[i] != WORD(-1)) + { + if (!COEFF_IS_MPZ(poly[i])) + off += flint_sprintf(str + off, "%wd*", poly[i]); + else + off += gmp_sprintf(str + off, "%Zd*", COEFF_TO_PTR(poly[i])); + } + if (i > 1) + off += flint_sprintf(str + off, "%s^%wd", x, i); + else + off += flint_sprintf(str + off, "%s", x); + } + + if (poly[i] != WORD(0)) + { + if (fmpz_sgn(poly + i) > 0) + str[off++] = '+'; + if (!COEFF_IS_MPZ(poly[i])) + off += flint_sprintf(str + off, "%wd", poly[i]); + else + off += gmp_sprintf(str + off, "%Zd", COEFF_TO_PTR(poly[i])); + } + + return str; +} + +char * +fmpz_poly_get_str_pretty(const fmpz_poly_t poly, const char *x) +{ + return _fmpz_poly_get_str_pretty(poly->coeffs, poly->length, x); +} diff --git a/external/flint-2.4.3/fmpz_poly/hensel_build_tree.c b/external/flint-2.4.3/fmpz_poly/hensel_build_tree.c new file mode 100644 index 0000000..b4d7275 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/hensel_build_tree.c @@ -0,0 +1,128 @@ +/*============================================================================= + + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Andy Novocin + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +void fmpz_poly_hensel_build_tree(slong *link, fmpz_poly_t *v, fmpz_poly_t *w, + const nmod_poly_factor_t fac) +{ + const slong r = fac->num; + const nmod_t mod = (fac->p + 0)->mod; + + slong i, j; + + nmod_poly_t d; + nmod_poly_t *V = flint_malloc((2*r - 2)*sizeof(nmod_poly_t)); + nmod_poly_t *W = flint_malloc((2*r - 2)*sizeof(nmod_poly_t)); + + nmod_poly_init_preinv(d, mod.n, mod.ninv); + + for (i = 0; i < 2*r - 2; i++) + { + nmod_poly_init_preinv(V[i], mod.n, mod.ninv); + nmod_poly_init_preinv(W[i], mod.n, mod.ninv); + } + + for (i = 0; i < r; i++) + { + nmod_poly_set(V[i], fac->p + i); + link[i] = - i - 1; + } + + for (i = r, j = 0; j < 2*r - 4; i++, j += 2) + { + slong s; + slong minp, mind; + slong tmp; + + minp = j; + mind = nmod_poly_degree(V[j]); + for (s = j+1; s < i; s++) + { + if (nmod_poly_degree(V[s]) < mind) + { + minp = s; + mind = nmod_poly_degree(V[s]); + } + } + + nmod_poly_swap(V[j], V[minp]); + + /* Swap link[j] and V[minp] */ + tmp = link[j]; + link[j] = link[minp]; + link[minp] = tmp; + + minp = j+1; + mind = nmod_poly_degree(V[j+1]); + + for (s = j + 2; s < i; s++) + { + if (nmod_poly_degree(V[s]) < mind) + { + minp = s; + mind = nmod_poly_degree(V[s]); + } + } + + nmod_poly_swap(V[j + 1], V[minp]); + + /* Swap link[j+1] and V[minp] */ + tmp = link[j + 1]; + link[j+1] = link[minp]; + link[minp] = tmp; + + nmod_poly_mul(V[i], V[j], V[j+1]); + link[i] = j; + } + + for (j = 0; j < 2*r - 2; j += 2) + { + /* N.B. d == 1 */ + nmod_poly_xgcd(d, W[j], W[j+1], V[j], V[j+1]); + } + + for (j = 0; j < 2*r - 2; j++) + { + fmpz_poly_set_nmod_poly(v[j], V[j]); + fmpz_poly_set_nmod_poly(w[j], W[j]); + } + + for (i = 0; i < 2*r - 2; i++) + { + nmod_poly_clear(V[i]); + nmod_poly_clear(W[i]); + } + + nmod_poly_clear(d); + flint_free(V); + flint_free(W); +} + diff --git a/external/flint-2.4.3/fmpz_poly/hensel_continue_lift.c b/external/flint-2.4.3/fmpz_poly/hensel_continue_lift.c new file mode 100644 index 0000000..1f24fcf --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/hensel_continue_lift.c @@ -0,0 +1,114 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Andy Novocin + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_poly.h" + +slong _fmpz_poly_hensel_continue_lift(fmpz_poly_factor_t lifted_fac, + slong *link, fmpz_poly_t *v, fmpz_poly_t *w, const fmpz_poly_t f, + slong prev, slong curr, slong N, const fmpz_t p) +{ + const slong r = lifted_fac->num; + + slong i, new_prev; + + fmpz_t P; + fmpz_poly_t monic_f; + + fmpz_init(P); + fmpz_pow_ui(P, p, N); + fmpz_poly_init(monic_f); + + if (fmpz_is_one(fmpz_poly_lead(f))) + { + fmpz_poly_set(monic_f, f); + } + else if (fmpz_cmp_si(fmpz_poly_lead(f), -1) == 0) + { + fmpz_poly_neg(monic_f, f); + } + else + { + fmpz_t t; + + fmpz_init(t); + fmpz_mod(t, fmpz_poly_lead(f), P); + + if (fmpz_invmod(t, t, P) == 0) + { + flint_printf("Exception (fmpz_poly_continue_hensel_lift).\n"); + abort(); + } + + fmpz_poly_scalar_mul_fmpz(monic_f, f, t); + fmpz_poly_scalar_mod_fmpz(monic_f, monic_f, P); + fmpz_clear(t); + } + + { + slong *e, n = 3 + FLINT_FLOG2(N - prev); + + e = flint_malloc(n * sizeof(slong)); + + for (e[i = 0] = N; e[i] > curr; i++) + e[i + 1] = (e[i] + 1) / 2; + e[i] = curr; + e[i+1] = prev; + + if (prev < curr) + fmpz_poly_hensel_lift_tree(link, v, w, monic_f, r, p, e[i+1], e[i], -1); + + for (i--; i > 0; i--) + fmpz_poly_hensel_lift_tree(link, v, w, monic_f, r, p, e[i+1], e[i], 1); + + fmpz_poly_hensel_lift_tree(link, v, w, monic_f, r, p, e[i+1], e[i], 0); + + new_prev = e[i+1]; + + flint_free(e); + } + + /* + Now everything is lifted to p^N, we just need to + insert the factors into their correct places in lifted_fac. + */ + fmpz_poly_factor_fit_length(lifted_fac, r); + + for(i = 0; i < 2*r - 2; i++) + { + if (link[i] < 0) + { + fmpz_poly_scalar_smod_fmpz(lifted_fac->p + (- link[i] - 1), v[i], P); + lifted_fac->exp[- link[i] - 1] = WORD(1); + } + } + lifted_fac->num = r; + + fmpz_clear(P); + fmpz_poly_clear(monic_f); + + return new_prev; +} + diff --git a/external/flint-2.4.3/fmpz_poly/hensel_lift.c b/external/flint-2.4.3/fmpz_poly/hensel_lift.c new file mode 100644 index 0000000..0b77328 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/hensel_lift.c @@ -0,0 +1,72 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Andy Novocin + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpz_mod_poly.h" + +void _fmpz_poly_hensel_lift(fmpz *G, fmpz *H, fmpz *A, fmpz *B, + const fmpz *f, slong lenF, + const fmpz *g, slong lenG, const fmpz *h, slong lenH, + const fmpz *a, slong lenA, const fmpz *b, slong lenB, + const fmpz_t p, const fmpz_t p1) +{ + _fmpz_poly_hensel_lift_without_inverse(G, H, f, lenF, g, lenG, h, lenH, + a, lenA, b, lenB, p, p1); + + _fmpz_poly_hensel_lift_only_inverse(A, B, G, lenG, H, lenH, + a, lenA, b, lenB, p, p1); +} + +void fmpz_poly_hensel_lift(fmpz_poly_t G, fmpz_poly_t H, + fmpz_poly_t A, fmpz_poly_t B, + const fmpz_poly_t f, + const fmpz_poly_t g, const fmpz_poly_t h, + const fmpz_poly_t a, const fmpz_poly_t b, + const fmpz_t p, const fmpz_t p1) +{ + const slong lenG = g->length; + const slong lenH = h->length; + + fmpz_poly_fit_length(G, lenG); + fmpz_poly_fit_length(H, lenH); + fmpz_poly_fit_length(A, lenH - 1); + fmpz_poly_fit_length(B, lenG - 1); + + _fmpz_poly_hensel_lift(G->coeffs, H->coeffs, A->coeffs, B->coeffs, + f->coeffs, f->length, g->coeffs, g->length, h->coeffs, h->length, + a->coeffs, a->length, b->coeffs, b->length, p, p1); + + _fmpz_poly_set_length(G, lenG); + _fmpz_poly_set_length(H, lenH); + _fmpz_poly_set_length(A, lenH - 1); + _fmpz_poly_set_length(B, lenG - 1); + _fmpz_poly_normalise(A); + _fmpz_poly_normalise(B); +} + diff --git a/external/flint-2.4.3/fmpz_poly/hensel_lift_once.c b/external/flint-2.4.3/fmpz_poly/hensel_lift_once.c new file mode 100644 index 0000000..382e924 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/hensel_lift_once.c @@ -0,0 +1,63 @@ +/*============================================================================= + + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Andy Novocin + Copyright (C) 2011 William Hart + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "flint.h" +#include "fmpz_poly.h" +#include "nmod_poly.h" + +void fmpz_poly_hensel_lift_once(fmpz_poly_factor_t lifted_fac, + const fmpz_poly_t f, + const nmod_poly_factor_t local_fac, slong N) +{ + const slong r = local_fac->num; + + slong i; + slong *link; + fmpz_poly_t *v, *w; + + link = flint_malloc((2*r - 2) * sizeof(slong)); + v = flint_malloc(2*(2*r - 2) * sizeof(fmpz_poly_t)); + w = v + (2*r - 2); + + for(i = 0; i < 2*r - 2; i++) + { + fmpz_poly_init(v[i]); + fmpz_poly_init(w[i]); + } + + _fmpz_poly_hensel_start_lift(lifted_fac, link, v, w, f, local_fac, N); + + for (i = 0; i < 2*r - 2; i++) + { + fmpz_poly_clear(v[i]); + fmpz_poly_clear(w[i]); + } + flint_free(link); + flint_free(v); +} + diff --git a/external/flint-2.4.3/fmpz_poly/hensel_lift_only_inverse.c b/external/flint-2.4.3/fmpz_poly/hensel_lift_only_inverse.c new file mode 100644 index 0000000..96a4a16 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/hensel_lift_only_inverse.c @@ -0,0 +1,120 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Andy Novocin + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpz_mod_poly.h" + +/* + Macro for the lift B := [{(1 - aG - bH)/p} * b mod g] p + b, + of length at most lenG - 1. + + Assumes that {C, lenC} contains the inner part {(1 - aG - bH)/p} mod p1, + where lenC = max(lenA + lenG - 1, lenB + lenH - 1). Requires temporary + space M, D, E. We really only need + lenM = max(lenG, lenH) + lenE = max(lenG + lenB - 2, lenH + lenA - 2) + lenD = max(lenC, lenE) + + Writes {B, lenG - 1}. The cofactor that is lifted is the + polynomial {b, lenB}, which may be aliased with B. Although + it suffices to have g modulo p, there is no harm in supplying + {g, lenG} only reduced modulo p p1. + */ +#define liftinv(B, b, lenB, g, lenG) \ +do { \ + _fmpz_vec_scalar_mod_fmpz(M, g, lenG, p1); \ + _fmpz_mod_poly_rem(D, C, lenC, M, lenG, one, p1); \ + _fmpz_mod_poly_mul(E, D, lenG - 1, b, lenB, p1); \ + if (lenB > 1) \ + { \ + _fmpz_mod_poly_rem(D, E, lenG + lenB - 2, M, lenG, one, p1); \ + _fmpz_vec_scalar_mul_fmpz(M, D, lenG - 1, p); \ + } \ + else \ + { \ + _fmpz_vec_scalar_mul_fmpz(M, E, lenG - 1, p); \ + } \ + _fmpz_poly_add(B, M, lenG - 1, b, lenB); \ +} while (0) + +void _fmpz_poly_hensel_lift_only_inverse(fmpz *A, fmpz *B, + const fmpz *G, slong lenG, const fmpz *H, slong lenH, + const fmpz *a, slong lenA, const fmpz *b, slong lenB, + const fmpz_t p, const fmpz_t p1) +{ + const fmpz one[1] = {WORD(1)}; + const slong lenC = FLINT_MAX(lenA + lenG - 1, lenB + lenH - 1); + const slong lenM = FLINT_MAX(lenG, lenH); + const slong lenE = FLINT_MAX(lenG + lenB - 2, lenH + lenA - 2); + const slong lenD = FLINT_MAX(lenC, lenE); + fmpz *C, *D, *E, *M; + + C = _fmpz_vec_init(lenC + lenD + lenD + lenM); + D = C + lenC; + E = D + lenD; + M = E + lenE; + + if (lenG >= lenA) + _fmpz_poly_mul(C, G, lenG, a, lenA); + else + _fmpz_poly_mul(C, a, lenA, G, lenG); + if (lenH >= lenB) + _fmpz_poly_mul(D, H, lenH, b, lenB); + else + _fmpz_poly_mul(D, b, lenB, H, lenH); + _fmpz_vec_add(C, C, D, lenC); + fmpz_sub_ui(C, C, 1); + _fmpz_vec_neg(C, C, lenC); + _fmpz_vec_scalar_divexact_fmpz(D, C, lenC, p); + _fmpz_vec_scalar_mod_fmpz(C, D, lenC, p1); + + liftinv(B, b, lenB, G, lenG); + liftinv(A, a, lenA, H, lenH); + + _fmpz_vec_clear(C, lenC + lenD + lenD + lenM); +} + +void fmpz_poly_hensel_lift_only_inverse(fmpz_poly_t Aout, fmpz_poly_t Bout, + const fmpz_poly_t G, const fmpz_poly_t H, + const fmpz_poly_t a, const fmpz_poly_t b, + const fmpz_t p, const fmpz_t p1) +{ + fmpz_poly_fit_length(Aout, H->length - 1); + fmpz_poly_fit_length(Bout, G->length - 1); + + _fmpz_poly_hensel_lift_only_inverse(Aout->coeffs, Bout->coeffs, + G->coeffs, G->length, H->coeffs, H->length, + a->coeffs, a->length, b->coeffs, b->length, p, p1); + + _fmpz_poly_set_length(Aout, H->length - 1); + _fmpz_poly_set_length(Bout, G->length - 1); + _fmpz_poly_normalise(Aout); + _fmpz_poly_normalise(Bout); +} + diff --git a/external/flint-2.4.3/fmpz_poly/hensel_lift_tree.c b/external/flint-2.4.3/fmpz_poly/hensel_lift_tree.c new file mode 100644 index 0000000..b58e92f --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/hensel_lift_tree.c @@ -0,0 +1,48 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Andy Novocin + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +void fmpz_poly_hensel_lift_tree(slong *link, fmpz_poly_t *v, fmpz_poly_t *w, + fmpz_poly_t f, slong r, const fmpz_t p, slong e0, slong e1, slong inv) +{ + fmpz_t p0, p1; + + fmpz_init(p0); + fmpz_init(p1); + + fmpz_pow_ui(p0, p, e0); + fmpz_pow_ui(p1, p, e1 - e0); + + fmpz_poly_hensel_lift_tree_recursive(link, v, w, f, 2*r - 4, inv, p0, p1); + + fmpz_clear(p0); + fmpz_clear(p1); +} + diff --git a/external/flint-2.4.3/fmpz_poly/hensel_lift_tree_recursive.c b/external/flint-2.4.3/fmpz_poly/hensel_lift_tree_recursive.c new file mode 100644 index 0000000..cb2ffb0 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/hensel_lift_tree_recursive.c @@ -0,0 +1,56 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Andy Novocin + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +void fmpz_poly_hensel_lift_tree_recursive(slong *link, + fmpz_poly_t *v, fmpz_poly_t *w, fmpz_poly_t f, slong j, slong inv, + const fmpz_t p0, const fmpz_t p1) +{ + if (j >= 0) + { + if (inv == 1) + fmpz_poly_hensel_lift(v[j], v[j + 1], w[j], w[j + 1], f, + v[j], v[j + 1], w[j], w[j + 1], + p0, p1); + else if (inv == -1) + fmpz_poly_hensel_lift_only_inverse(w[j], w[j+1], + v[j], v[j+1], w[j], w[j+1], p0, p1); + else + fmpz_poly_hensel_lift_without_inverse(v[j], v[j+1], f, + v[j], v[j+1], w[j], w[j+1], + p0, p1); + + fmpz_poly_hensel_lift_tree_recursive(link, v, w, v[j], link[j], + inv, p0, p1); + fmpz_poly_hensel_lift_tree_recursive(link, v, w, v[j+1], link[j+1], + inv, p0, p1); + } +} + diff --git a/external/flint-2.4.3/fmpz_poly/hensel_lift_without_inverse.c b/external/flint-2.4.3/fmpz_poly/hensel_lift_without_inverse.c new file mode 100644 index 0000000..7e27b61 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/hensel_lift_without_inverse.c @@ -0,0 +1,108 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Andy Novocin + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpz_mod_poly.h" + +/* + Macro for the lift G := [{(f - gh)/p} * b mod g] p + g. + + Assumes that {C, lenF} contains the inner part {f - gh}/p mod p1. + Requires temporary space M, D, E. We really only need + lenM = max(lenG, lenH) + lenE = max(lenG + lenB - 2, lenH + lenA - 2) + lenD = max(lenE, lenF) + + Only supports aliasing between G and g. + */ +#define lift(G, g, lenG, b, lenB) \ +do { \ + _fmpz_vec_scalar_mod_fmpz(M, g, lenG, p1); \ + _fmpz_mod_poly_rem(D, C, lenF, M, lenG, one, p1); \ + _fmpz_mod_poly_mul(E, D, lenG - 1, b, lenB, p1); \ + if (lenB > 1) \ + { \ + _fmpz_mod_poly_rem(D, E, lenG + lenB - 2, M, lenG, one, p1); \ + _fmpz_vec_scalar_mul_fmpz(M, D, lenG - 1, p); \ + } \ + else \ + { \ + _fmpz_vec_scalar_mul_fmpz(M, E, lenG - 1, p); \ + } \ + _fmpz_vec_add(G, g, M, lenG - 1); \ + fmpz_one(G + lenG - 1); \ +} while (0) + +void _fmpz_poly_hensel_lift_without_inverse(fmpz *G, fmpz *H, + const fmpz *f, slong lenF, + const fmpz *g, slong lenG, const fmpz *h, slong lenH, + const fmpz *a, slong lenA, const fmpz *b, slong lenB, + const fmpz_t p, const fmpz_t p1) +{ + const fmpz one[1] = {1l}; + const slong lenM = FLINT_MAX(lenG, lenH); + const slong lenE = FLINT_MAX(lenG + lenB - 2, lenH + lenA - 2); + const slong lenD = FLINT_MAX(lenE, lenF); + fmpz *C, *D, *E, *M; + + C = _fmpz_vec_init(lenF + lenD + lenE + lenM); + D = C + lenF; + E = D + lenD; + M = E + lenE; + + if (lenG >= lenH) + _fmpz_poly_mul(C, g,lenG, h, lenH); + else + _fmpz_poly_mul(C, h, lenH, g, lenG); + _fmpz_vec_sub(C, f, C, lenF); + _fmpz_vec_scalar_divexact_fmpz(D, C, lenF, p); + _fmpz_vec_scalar_mod_fmpz(C, D, lenF, p1); + + lift(G, g, lenG, b, lenB); + + lift(H, h, lenH, a, lenA); + + _fmpz_vec_clear(C, lenF + lenD + lenE + lenM); +} + +void fmpz_poly_hensel_lift_without_inverse(fmpz_poly_t Gout, fmpz_poly_t Hout, + const fmpz_poly_t f, const fmpz_poly_t g, const fmpz_poly_t h, + const fmpz_poly_t a, const fmpz_poly_t b, + const fmpz_t p, const fmpz_t p1) +{ + fmpz_poly_fit_length(Gout, g->length); + fmpz_poly_fit_length(Hout, h->length); + _fmpz_poly_set_length(Gout, g->length); + _fmpz_poly_set_length(Hout, h->length); + + _fmpz_poly_hensel_lift_without_inverse(Gout->coeffs, Hout->coeffs, + f->coeffs, f->length, g->coeffs, g->length, h->coeffs, h->length, + a->coeffs, a->length, b->coeffs, b->length, p, p1); +} + diff --git a/external/flint-2.4.3/fmpz_poly/hensel_start_lift.c b/external/flint-2.4.3/fmpz_poly/hensel_start_lift.c new file mode 100644 index 0000000..f452643 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/hensel_start_lift.c @@ -0,0 +1,119 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Andy Novocin + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_poly.h" + +slong _fmpz_poly_hensel_start_lift(fmpz_poly_factor_t lifted_fac, slong *link, + fmpz_poly_t *v, fmpz_poly_t *w, const fmpz_poly_t f, + const nmod_poly_factor_t local_fac, slong N) +{ + const slong r = local_fac->num; + + slong i, preve; + fmpz_t p, P; + fmpz_poly_t monic_f; + + fmpz_init(p); + fmpz_init(P); + fmpz_poly_init(monic_f); + + fmpz_set_ui(p, (local_fac->p + 0)->mod.n); + fmpz_pow_ui(P, p, N); + + if (fmpz_is_one(fmpz_poly_lead(f))) + { + fmpz_poly_set(monic_f, f); + } + else if (fmpz_cmp_si(fmpz_poly_lead(f), -1) == 0) + { + fmpz_poly_neg(monic_f, f); + } + else + { + fmpz_t t; + + fmpz_init(t); + fmpz_mod(t, fmpz_poly_lead(f), P); + + if (fmpz_invmod(t, t, P) == 0) + { + flint_printf("Exception (fmpz_poly_start_hensel_lift).\n"); + abort(); + } + + fmpz_poly_scalar_mul_fmpz(monic_f, f, t); + fmpz_poly_scalar_mod_fmpz(monic_f, monic_f, P); + fmpz_clear(t); + } + + fmpz_poly_hensel_build_tree(link, v, w, local_fac); + + { + slong *e, n = FLINT_CLOG2(N) + 1; + + e = flint_malloc(n * sizeof(slong)); + for (e[i = 0] = N; e[i] > 1; i++) + e[i + 1] = (e[i] + 1) / 2; + + for (i--; i > 0; i--) + { + fmpz_poly_hensel_lift_tree(link, v, w, monic_f, r, + p, e[i+1], e[i], 1); + } + if (N > 1) + { + fmpz_poly_hensel_lift_tree(link, v, w, monic_f, r, + p, e[i+1], e[i], 0); + } + + preve = e[i+1]; + + flint_free(e); + } + + /* + Now everything is lifted to p^N, we just need to + insert the factors into their correct places in lifted_fac. + */ + fmpz_poly_factor_fit_length(lifted_fac, r); + + for (i = 0; i < 2*r - 2; i++) + { + if (link[i] < 0) + { + fmpz_poly_scalar_smod_fmpz(lifted_fac->p + (- link[i] - 1), v[i], P); + lifted_fac->exp[- link[i] - 1] = WORD(1); + } + } + lifted_fac->num = r; + + fmpz_clear(p); + fmpz_clear(P); + fmpz_poly_clear(monic_f); + + return preve; +} + diff --git a/external/flint-2.4.3/fmpz_poly/init.c b/external/flint-2.4.3/fmpz_poly/init.c new file mode 100644 index 0000000..4ef3b02 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/init.c @@ -0,0 +1,51 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +void +fmpz_poly_init(fmpz_poly_t poly) +{ + poly->coeffs = NULL; + + poly->alloc = 0; + poly->length = 0; +} + +void +fmpz_poly_init2(fmpz_poly_t poly, slong alloc) +{ + if (alloc) /* allocate space for alloc small coeffs */ + poly->coeffs = (fmpz *) flint_calloc(alloc, sizeof(fmpz)); + else + poly->coeffs = NULL; + + poly->alloc = alloc; + poly->length = 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/interpolate_fmpz_vec.c b/external/flint-2.4.3/fmpz_poly/interpolate_fmpz_vec.c new file mode 100644 index 0000000..17516fd --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/interpolate_fmpz_vec.c @@ -0,0 +1,83 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + + +static void +_fmpz_poly_interpolate_newton(fmpz * ys, const fmpz * xs, slong n) +{ + fmpz_t p, q, t; + slong i, j; + + fmpz_init(p); + fmpz_init(q); + fmpz_init(t); + + for (i = 1; i < n; i++) + { + fmpz_set(t, ys + i - 1); + + for (j = i; j < n; j++) + { + fmpz_sub(p, ys + j, t); + fmpz_sub(q, xs + j, xs + j - i); + fmpz_set(t, ys + j); + fmpz_divexact(ys + j, p, q); + } + } + + fmpz_clear(p); + fmpz_clear(q); + fmpz_clear(t); +} + +void +fmpz_poly_interpolate_fmpz_vec(fmpz_poly_t poly, + const fmpz * xs, const fmpz * ys, slong n) +{ + if (n == 0) + { + fmpz_poly_zero(poly); + return; + } + else if (n == 1) + { + fmpz_poly_set_fmpz(poly, ys); + return; + } + else + { + fmpz_poly_fit_length(poly, n); + _fmpz_vec_set(poly->coeffs, ys, n); + _fmpz_poly_interpolate_newton(poly->coeffs, xs, n); + _fmpz_poly_set_length(poly, n); + _fmpz_poly_normalise(poly); + _fmpz_poly_newton_to_monomial(poly->coeffs, xs, poly->length); + } +} diff --git a/external/flint-2.4.3/fmpz_poly/inv_series_newton.c b/external/flint-2.4.3/fmpz_poly/inv_series_newton.c new file mode 100644 index 0000000..2002062 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/inv_series_newton.c @@ -0,0 +1,121 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void +_fmpz_poly_inv_series_newton(fmpz * Qinv, const fmpz * Q, slong n) +{ + if (n == 1) /* Q is +-1 */ + { + fmpz_set(Qinv, Q); + } + else + { + const slong alloc = FLINT_MAX(n, 3 * FMPZ_POLY_INV_NEWTON_CUTOFF); + slong *a, i, m; + fmpz *W; + + W = _fmpz_vec_init(alloc); + + for (i = 1; (WORD(1) << i) < n; i++) ; + + a = (slong *) flint_malloc(i * sizeof(slong)); + a[i = 0] = n; + while (n >= FMPZ_POLY_INV_NEWTON_CUTOFF) + a[++i] = (n = (n + 1) / 2); + + /* Base case */ + { + fmpz *Qrev = W + 2 * FMPZ_POLY_INV_NEWTON_CUTOFF; + + _fmpz_poly_reverse(Qrev, Q, n, n); + _fmpz_vec_zero(W, 2*n - 2); + fmpz_one(W + (2*n - 2)); + _fmpz_poly_div_basecase(Qinv, W, W, 2*n - 1, Qrev, n); + _fmpz_poly_reverse(Qinv, Qinv, n, n); + } + + for (i--; i >= 0; i--) + { + m = n; + n = a[i]; + + _fmpz_poly_mullow(W, Q, n, Qinv, m, n); + _fmpz_poly_mullow(Qinv + m, Qinv, m, W + m, n - m, n - m); + _fmpz_vec_neg(Qinv + m, Qinv + m, n - m); + } + + _fmpz_vec_clear(W, alloc); + flint_free(a); + } +} + +void fmpz_poly_inv_series_newton(fmpz_poly_t Qinv, const fmpz_poly_t Q, slong n) +{ + fmpz *Qcopy; + int Qalloc; + + if (Q->length >= n) + { + Qcopy = Q->coeffs; + Qalloc = 0; + } + else + { + slong i; + Qcopy = (fmpz *) flint_malloc(n * sizeof(fmpz)); + for (i = 0; i < Q->length; i++) + Qcopy[i] = Q->coeffs[i]; + flint_mpn_zero((mp_ptr) Qcopy + i, n - i); + Qalloc = 1; + } + + if (Qinv != Q) + { + fmpz_poly_fit_length(Qinv, n); + _fmpz_poly_inv_series_newton(Qinv->coeffs, Qcopy, n); + } + else + { + fmpz_poly_t t; + fmpz_poly_init2(t, n); + _fmpz_poly_inv_series_newton(t->coeffs, Qcopy, n); + fmpz_poly_swap(Qinv, t); + fmpz_poly_clear(t); + } + + _fmpz_poly_set_length(Qinv, n); + _fmpz_poly_normalise(Qinv); + + if (Qalloc) + flint_free(Qcopy); +} + diff --git a/external/flint-2.4.3/fmpz_poly/is_squarefree.c b/external/flint-2.4.3/fmpz_poly/is_squarefree.c new file mode 100644 index 0000000..01ba36c --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/is_squarefree.c @@ -0,0 +1,73 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" +#include "fmpq_poly.h" + +int _fmpz_poly_is_squarefree(const fmpz * poly, slong len) +{ + if (len < 3) + { + return 1; + } + else if (len == 3) + { + int ans; + fmpz_t lhs, rhs; + fmpz_init(lhs); + fmpz_init(rhs); + + fmpz_mul(lhs, poly + 1, poly + 1); + fmpz_mul(rhs, poly, poly + 2); + fmpz_mul_ui(rhs, rhs, 4); + + ans = !fmpz_equal(lhs, rhs); + fmpz_clear(lhs); + fmpz_clear(rhs); + return ans; + } + else + { + int ans; + fmpz * w = _fmpz_vec_init(2 * len); + + _fmpz_poly_derivative(w, poly, len); + _fmpz_poly_gcd(w + len, poly, len, w, len - WORD(1)); + ans = _fmpz_vec_is_zero(w + len + 1, len - 2); + + _fmpz_vec_clear(w, 2 * len); + return ans; + } +} + +int fmpz_poly_is_squarefree(const fmpz_poly_t poly) +{ + return _fmpz_poly_is_squarefree(poly->coeffs, poly->length); +} + diff --git a/external/flint-2.4.3/fmpz_poly/lcm.c b/external/flint-2.4.3/fmpz_poly/lcm.c new file mode 100644 index 0000000..1ee3164 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/lcm.c @@ -0,0 +1,105 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +void _fmpz_poly_lcm(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2) +{ + fmpz *W; + slong lenW = len2; + + W = _fmpz_vec_init(len2); + + _fmpz_poly_mul(res, poly1, len1, poly2, len2); + + _fmpz_poly_gcd(W, poly1, len1, poly2, len2); + + FMPZ_VEC_NORM(W, lenW); + + if (lenW == 1) + { + if (fmpz_sgn(res + (len1 + len2 - 1 - 1)) < 0) + fmpz_neg(W + 0, W + 0); + _fmpz_vec_scalar_divexact_fmpz(res, res, len1 + len2 - 1, W + 0); + } + else + { + fmpz *V; + slong lenV = len1 + len2 - lenW; + + V = _fmpz_vec_init(lenV); + _fmpz_poly_div(V, res, len1 + len2 - 1, W, lenW); + if (fmpz_sgn(V + (lenV - 1)) > 0) + _fmpz_vec_set(res, V, lenV); + else + _fmpz_vec_neg(res, V, lenV); + _fmpz_vec_zero(res + lenV, len1 + len2 - 1 - lenV); + _fmpz_vec_clear(V, lenV); + } + + _fmpz_vec_clear(W, len2); +} + +void fmpz_poly_lcm(fmpz_poly_t res, const fmpz_poly_t poly1, + const fmpz_poly_t poly2) +{ + slong len1 = poly1->length; + slong len2 = poly2->length; + + if (len1 == 0 || len2 == 0) + { + fmpz_poly_zero(res); + return; + } + + if (res == poly1 || res == poly2) + { + fmpz_poly_t t; + + fmpz_poly_init(t); + fmpz_poly_lcm(t, poly1, poly2); + fmpz_poly_swap(res, t); + fmpz_poly_clear(t); + return; + } + + fmpz_poly_fit_length(res, len1 + len2 - 1); + _fmpz_poly_set_length(res, len1 + len2 - 1); + if (len1 >= len2) + { + _fmpz_poly_lcm(res->coeffs, poly1->coeffs, len1, poly2->coeffs, len2); + } + else + { + _fmpz_poly_lcm(res->coeffs, poly2->coeffs, len2, poly1->coeffs, len1); + } + _fmpz_poly_normalise(res); + +} + diff --git a/external/flint-2.4.3/fmpz_poly/monomial_to_newton.c b/external/flint-2.4.3/fmpz_poly/monomial_to_newton.c new file mode 100644 index 0000000..0a27d2d --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/monomial_to_newton.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +void +_fmpz_poly_monomial_to_newton(fmpz * poly, const fmpz * roots, slong n) +{ + slong i, j; + + for (i = 0; i < n - 1; i++) + for (j = n - 2; j >= i; j--) + fmpz_addmul(poly + j, poly + j + 1, roots + i); +} diff --git a/external/flint-2.4.3/fmpz_poly/mul.c b/external/flint-2.4.3/fmpz_poly/mul.c new file mode 100644 index 0000000..3c5907e --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/mul.c @@ -0,0 +1,100 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void +_fmpz_poly_mul(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2) +{ + mp_size_t limbs1, limbs2; + + if (len2 < 7) + { + _fmpz_poly_mul_classical(res, poly1, len1, poly2, len2); + return; + } + + limbs1 = _fmpz_vec_max_limbs(poly1, len1); + limbs2 = _fmpz_vec_max_limbs(poly2, len2); + + if (len1 < 16 && (limbs1 > 12 || limbs2 > 12)) + _fmpz_poly_mul_karatsuba(res, poly1, len1, poly2, len2); + else if (limbs1 + limbs2 <= 8) + _fmpz_poly_mul_KS(res, poly1, len1, poly2, len2); + else if ((limbs1+limbs2)/2048 > len1 + len2) + _fmpz_poly_mul_KS(res, poly1, len1, poly2, len2); + else if ((limbs1 + limbs2)*FLINT_BITS*4 < len1 + len2) + _fmpz_poly_mul_KS(res, poly1, len1, poly2, len2); + else + _fmpz_poly_mul_SS(res, poly1, len1, poly2, len2); +} + +void +fmpz_poly_mul(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2) +{ + slong len1 = poly1->length; + slong len2 = poly2->length; + slong rlen; + + if (len1 == 0 || len2 == 0) + { + fmpz_poly_zero(res); + return; + } + + rlen = len1 + len2 - 1; + + if (res == poly1 || res == poly2) + { + fmpz_poly_t t; + fmpz_poly_init2(t, rlen); + if (len1 >= len2) + _fmpz_poly_mul(t->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2); + else + _fmpz_poly_mul(t->coeffs, poly2->coeffs, len2, + poly1->coeffs, len1); + fmpz_poly_swap(res, t); + fmpz_poly_clear(t); + } + else + { + fmpz_poly_fit_length(res, rlen); + if (len1 >= len2) + _fmpz_poly_mul(res->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2); + else + _fmpz_poly_mul(res->coeffs, poly2->coeffs, len2, + poly1->coeffs, len1); + } + + _fmpz_poly_set_length(res, rlen); +} diff --git a/external/flint-2.4.3/fmpz_poly/mul_KS.c b/external/flint-2.4.3/fmpz_poly/mul_KS.c new file mode 100644 index 0000000..444188a --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/mul_KS.c @@ -0,0 +1,141 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void +_fmpz_poly_mul_KS(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2) +{ + const slong in1_len = len1, in2_len = len2; + int neg1, neg2; + slong limbs1, limbs2, loglen; + slong bits1, bits2, bits; + mp_limb_t *arr1, *arr2, *arr3; + slong sign = 0; + + FMPZ_VEC_NORM(poly1, len1); + FMPZ_VEC_NORM(poly2, len2); + + if (!len1 | !len2) + { + if (in1_len + in2_len - 1 > 0) + _fmpz_vec_zero(res, in1_len + in2_len - 1); + return; + } + + neg1 = (fmpz_sgn(poly1 + len1 - 1) > 0) ? 0 : -1; + neg2 = (fmpz_sgn(poly2 + len2 - 1) > 0) ? 0 : -1; + + bits1 = _fmpz_vec_max_bits(poly1, len1); + if (bits1 < 0) + { + sign = 1; + bits1 = -bits1; + } + + if (poly1 != poly2) + { + bits2 = _fmpz_vec_max_bits(poly2, len2); + if (bits2 < 0) + { + sign = 1; + bits2 = -bits2; + } + } + else + bits2 = bits1; + + loglen = FLINT_BIT_COUNT(FLINT_MIN(len1, len2)); + bits = bits1 + bits2 + loglen + sign; + + limbs1 = (bits * len1 - 1) / FLINT_BITS + 1; + limbs2 = (bits * len2 - 1) / FLINT_BITS + 1; + + if (poly1 == poly2) + { + arr1 = (mp_limb_t *) flint_calloc(limbs1, sizeof(mp_limb_t)); + arr2 = arr1; + _fmpz_poly_bit_pack(arr1, poly1, len1, bits, neg1); + } + else + { + arr1 = (mp_limb_t *) flint_calloc(limbs1 + limbs2, sizeof(mp_limb_t)); + arr2 = arr1 + limbs1; + _fmpz_poly_bit_pack(arr1, poly1, len1, bits, neg1); + _fmpz_poly_bit_pack(arr2, poly2, len2, bits, neg2); + } + + arr3 = (mp_limb_t *) flint_malloc((limbs1 + limbs2) * sizeof(mp_limb_t)); + + if (limbs1 == limbs2) + mpn_mul_n(arr3, arr1, arr2, limbs1); + else if (limbs1 > limbs2) + mpn_mul(arr3, arr1, limbs1, arr2, limbs2); + else + mpn_mul(arr3, arr2, limbs2, arr1, limbs1); + + if (sign) + _fmpz_poly_bit_unpack(res, len1 + len2 - 1, arr3, bits, neg1 ^ neg2); + else + _fmpz_poly_bit_unpack_unsigned(res, len1 + len2 - 1, arr3, bits); + + if ((len1 < in1_len) | (len2 < in2_len)) + _fmpz_vec_zero(res + (len1 + len2 - 1), (in1_len - len1) + (in2_len - len2)); + + flint_free(arr1); + flint_free(arr3); +} + +void +fmpz_poly_mul_KS(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2) +{ + const slong len1 = poly1->length; + const slong len2 = poly2->length; + const slong rlen = len1 + len2 - 1; + + if (len1 == 0 || len2 == 0) + { + fmpz_poly_zero(res); + } + else + { + fmpz_poly_fit_length(res, rlen); + if (len1 >= len2) + _fmpz_poly_mul_KS(res->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2); + else + _fmpz_poly_mul_KS(res->coeffs, poly2->coeffs, len2, + poly1->coeffs, len1); + _fmpz_poly_set_length(res, rlen); + } +} diff --git a/external/flint-2.4.3/fmpz_poly/mul_SS.c b/external/flint-2.4.3/fmpz_poly/mul_SS.c new file mode 100644 index 0000000..35ff208 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/mul_SS.c @@ -0,0 +1,66 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2008-2011 William Hart + +******************************************************************************/ + +#include "fmpz_poly.h" +#include "fft.h" +#include "fft_tuning.h" + +void _fmpz_poly_mul_SS(fmpz *output, const fmpz *input1, slong len1, + const fmpz *input2, slong len2) +{ + const slong rlen = len1 + len2 - 1; + + _fmpz_poly_mullow_SS(output, input1, len1, input2, len2, rlen); +} + +void +fmpz_poly_mul_SS(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2) +{ + const slong len1 = poly1->length, len2 = poly2->length; + slong rlen; + + if (len1 == 0 || len2 == 0) + { + fmpz_poly_zero(res); + return; + } + if (len1 == 1 || len2 == 1) + { + fmpz_poly_mul_classical(res, poly1, poly2); + return; + } + + rlen = len1 + len2 - 1; + + fmpz_poly_fit_length(res, rlen); + if (len1 >= len2) + _fmpz_poly_mullow_SS(res->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2, rlen); + else + _fmpz_poly_mullow_SS(res->coeffs, poly2->coeffs, len2, + poly1->coeffs, len1, rlen); + _fmpz_poly_set_length(res, rlen); +} diff --git a/external/flint-2.4.3/fmpz_poly/mul_classical.c b/external/flint-2.4.3/fmpz_poly/mul_classical.c new file mode 100644 index 0000000..5323060 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/mul_classical.c @@ -0,0 +1,90 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +/* Assumes poly1 and poly2 are not length 0. */ +void +_fmpz_poly_mul_classical(fmpz * res, const fmpz * poly1, + slong len1, const fmpz * poly2, slong len2) +{ + if (len1 == 1 && len2 == 1) /* Special case if the length of both inputs is 1 */ + { + fmpz_mul(res, poly1, poly2); + } + else /* Ordinary case */ + { + slong i; + + /* Set res[i] = poly1[i]*poly2[0] */ + _fmpz_vec_scalar_mul_fmpz(res, poly1, len1, poly2); + + /* Set res[i+len1-1] = in1[len1-1]*in2[i] */ + _fmpz_vec_scalar_mul_fmpz(res + len1, poly2 + 1, len2 - 1, + poly1 + len1 - 1); + + /* out[i+j] += in1[i]*in2[j] */ + for (i = 0; i < len1 - 1; i++) + _fmpz_vec_scalar_addmul_fmpz(res + i + 1, poly2 + 1, len2 - 1, + poly1 + i); + } +} + +void +fmpz_poly_mul_classical(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2) +{ + slong len_out; + + if ((poly1->length == 0) || (poly2->length == 0)) + { + fmpz_poly_zero(res); + return; + } + + len_out = poly1->length + poly2->length - 1; + + if (res == poly1 || res == poly2) + { + fmpz_poly_t temp; + fmpz_poly_init2(temp, len_out); + _fmpz_poly_mul_classical(temp->coeffs, poly1->coeffs, poly1->length, + poly2->coeffs, poly2->length); + fmpz_poly_swap(res, temp); + fmpz_poly_clear(temp); + } + else + { + fmpz_poly_fit_length(res, len_out); + _fmpz_poly_mul_classical(res->coeffs, poly1->coeffs, poly1->length, + poly2->coeffs, poly2->length); + } + + _fmpz_poly_set_length(res, len_out); +} diff --git a/external/flint-2.4.3/fmpz_poly/mul_karatsuba.c b/external/flint-2.4.3/fmpz_poly/mul_karatsuba.c new file mode 100644 index 0000000..22a04a6 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/mul_karatsuba.c @@ -0,0 +1,195 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +/* + Implements karatsuba multiplication. There is no basecase crossover, so + this is only efficient when the coefficients are large (the main usage + case). + + The algorithm is the "odd/even" Karatsuba algorithm. Let + f(x) = f1(x^2) + x*f2(x^2), g(x) = g1(x^2) + x*g2(x^2), then + + f(x)*g(x) = f1(x^2)*g1(x^2) + x^2*f2(x^2)*g2(x^2) + + x*((f1(x^2) + f2(x^2))*(g1(x^2) + g2(x^2)) + - f1(x^2)*g1(x^2) - f2(x^2)*g2(x^2)). + + Thus only three multiplications are performed (and numerous additions + and subtractions). + + Instead of working with polynomials with the usual ordering, reverse + binary ordering is used, i.e. for length 2^3 (zero padded) terms of + degree 110 and 011 in binary are swapped, etc. + + The advantage of working in this format is that the first half of the + coefficients of f will be the coefficients of f1, and the second half, + those of f2, etc. This applies right down the recursion. The only tricky + bit is when multiplying by x. One must undo the revbin to shift by one + term to the left. +*/ + +void _fmpz_poly_mul_kara_recursive(fmpz * out, fmpz * rev1, fmpz * rev2, + fmpz * temp, slong bits); + +/* + Switches the coefficients of poly in of length len into a + poly out of length 2^bits. + */ +void +revbin1(fmpz * out, const fmpz * in, slong len, slong bits) +{ + slong i; + for (i = 0; i < len; i++) + out[n_revbin(i, bits)] = in[i]; +} + +/* + Switches the coefficients of poly in of length 2^bits into a + poly out of length len. + */ +void +revbin2(fmpz * out, const fmpz * in, slong len, slong bits) +{ + slong i; + for (i = 0; i < len; i++) + out[i] = in[n_revbin(i, bits)]; +} + +/* in1 += x*in2 assuming both in1 and in2 are revbin'd. */ +void +_fmpz_vec_add_rev(fmpz * in1, fmpz * in2, slong bits) +{ + slong i; + for (i = 0; i < (WORD(1) << bits) - 1; i++) + { + slong j = n_revbin(n_revbin(i, bits) + 1, bits); + fmpz_add(in1 + j, in1 + j, in2 + i); + } +} + +/* + Recursive Karatsuba assuming polynomials are in revbin format. + + Assumes rev1 and rev2 are both of length 2^bits and that temp has + space for 2^bits coefficients. + */ +void +_fmpz_poly_mul_kara_recursive(fmpz * out, fmpz * rev1, fmpz * rev2, + fmpz * temp, slong bits) +{ + slong length = (WORD(1) << bits); + slong m = length / 2; + + if (length == 1) + { + fmpz_mul(out, rev1, rev2); + fmpz_zero(out + 1); + return; + } + + _fmpz_vec_add(temp, rev1, rev1 + m, m); + _fmpz_vec_add(temp + m, rev2, rev2 + m, m); + + _fmpz_poly_mul_kara_recursive(out, rev1, rev2, temp + 2 * m, bits - 1); + + _fmpz_poly_mul_kara_recursive(out + length, temp, temp + m, temp + 2 * m, + bits - 1); + + _fmpz_poly_mul_kara_recursive(temp, rev1 + m, rev2 + m, temp + 2 * m, + bits - 1); + + _fmpz_vec_sub(out + length, out + length, out, length); + _fmpz_vec_sub(out + length, out + length, temp, length); + + _fmpz_vec_add_rev(out, temp, bits); +} + +/* Assumes poly1 and poly2 are not length 0 and len1 >= len2. */ +void +_fmpz_poly_mul_karatsuba(fmpz * res, const fmpz * poly1, + slong len1, const fmpz * poly2, slong len2) +{ + fmpz *rev1, *rev2, *out, *temp; + slong length, loglen = 0; + + if (len1 == 1) + { + fmpz_mul(res, poly1, poly2); + return; + } + + while ((WORD(1) << loglen) < len1) + loglen++; + length = (WORD(1) << loglen); + + rev1 = (fmpz *) flint_calloc(4 * length, sizeof(fmpz *)); + rev2 = rev1 + length; + out = rev1 + 2 * length; + temp = _fmpz_vec_init(2 * length); + + revbin1(rev1, poly1, len1, loglen); + revbin1(rev2, poly2, len2, loglen); + + _fmpz_poly_mul_kara_recursive(out, rev1, rev2, temp, loglen); + + _fmpz_vec_zero(res, len1 + len2 - 1); + revbin2(res, out, len1 + len2 - 1, loglen + 1); + + _fmpz_vec_clear(temp, 2 * length); + flint_free(rev1); +} + +void +fmpz_poly_mul_karatsuba(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2) +{ + slong len_out; + + if ((poly1->length == 0) || (poly2->length == 0)) + { + fmpz_poly_zero(res); + return; + } + + len_out = poly1->length + poly2->length - 1; + + fmpz_poly_fit_length(res, len_out); + + if (poly1->length >= poly2->length) + _fmpz_poly_mul_karatsuba(res->coeffs, poly1->coeffs, poly1->length, + poly2->coeffs, poly2->length); + else + _fmpz_poly_mul_karatsuba(res->coeffs, poly2->coeffs, poly2->length, + poly1->coeffs, poly1->length); + + _fmpz_poly_set_length(res, len_out); +} diff --git a/external/flint-2.4.3/fmpz_poly/mulhigh_classical.c b/external/flint-2.4.3/fmpz_poly/mulhigh_classical.c new file mode 100644 index 0000000..1e62fad --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/mulhigh_classical.c @@ -0,0 +1,101 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +/* Assumes poly1 and poly2 are not length 0. */ +void +_fmpz_poly_mulhigh_classical(fmpz * res, const fmpz * poly1, + slong len1, const fmpz * poly2, slong len2, + slong start) +{ + _fmpz_vec_zero(res, start); + + if (len1 == 1 && len2 == 1) /* Special case if the length of both inputs is 1 */ + { + if (start == 0) + fmpz_mul(res, poly1, poly2); + } + else /* Ordinary case */ + { + slong i, m, n; + + /* Set res[i] = poly1[i]*poly2[0] */ + if (start < len1) + _fmpz_vec_scalar_mul_fmpz(res + start, poly1 + start, len1 - start, + poly2); + + /* Set res[i+len1-1] = in1[len1-1]*in2[i] */ + m = FLINT_MAX(len1 - 1, start); + _fmpz_vec_scalar_mul_fmpz(res + m, poly2 + m - len1 + 1, + len2 - 1 + len1 - m, poly1 + len1 - 1); + + /* out[i+j] += in1[i]*in2[j] */ + m = FLINT_MAX(start, len2 - 1); + for (i = m - len2 + 1; i < len1 - 1; i++) + { + n = FLINT_MAX(i + 1, start); + _fmpz_vec_scalar_addmul_fmpz(res + n, poly2 + n - i, len2 + i - n, + poly1 + i); + } + } +} + +void +fmpz_poly_mulhigh_classical(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2, + slong start) +{ + slong len_out = poly1->length + poly2->length - 1; + + if (poly1->length == 0 || poly2->length == 0 || start >= len_out) + { + fmpz_poly_zero(res); + return; + } + + if (res == poly1 || res == poly2) + { + fmpz_poly_t temp; + fmpz_poly_init2(temp, len_out); + _fmpz_poly_mulhigh_classical(temp->coeffs, poly1->coeffs, + poly1->length, poly2->coeffs, + poly2->length, start); + fmpz_poly_swap(res, temp); + fmpz_poly_clear(temp); + } + else + { + fmpz_poly_fit_length(res, len_out); + _fmpz_poly_mulhigh_classical(res->coeffs, poly1->coeffs, poly1->length, + poly2->coeffs, poly2->length, start); + } + + _fmpz_poly_set_length(res, len_out); +} diff --git a/external/flint-2.4.3/fmpz_poly/mulhigh_karatsuba_n.c b/external/flint-2.4.3/fmpz_poly/mulhigh_karatsuba_n.c new file mode 100644 index 0000000..ba4f771 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/mulhigh_karatsuba_n.c @@ -0,0 +1,165 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void _fmpz_poly_mulhigh_kara_recursive(fmpz * out, const fmpz * pol1, + const fmpz * pol2, fmpz * temp, + slong length); + +/* + Multiplication using truncated karatsuba. Below length 7, classical + truncated multiplication is always theoretically faster, so we switch + to that as the basecase. + + Above that we use the ordinary (left/right) karatsuba identity and + recursively do one full karatsuba multiplication and two truncated + karatsuba multiplications. +*/ + +void +_fmpz_poly_mulhigh_kara_recursive(fmpz * out, const fmpz * pol1, + const fmpz * pol2, fmpz * temp, slong length) +{ + slong m1 = length / 2; + slong m2 = length - m1; + int odd = (length & 1); + + if (length <= 6) + { + _fmpz_poly_mulhigh_classical(out, pol1, length, pol2, length, + length - 1); + return; + } + + _fmpz_vec_add(out, pol1, pol1 + m1, m1); + if (odd) + fmpz_set(out + m1, pol1 + 2 * m1); + + _fmpz_vec_add(out + m2, pol2, pol2 + m1, m1); + if (odd) + fmpz_set(out + m2 + m1, pol2 + 2 * m1); + + _fmpz_poly_mulhigh_kara_recursive(temp, out, out + m2, temp + 2 * m2, m2); + + _fmpz_poly_mul_karatsuba(out + 2 * m1, pol1 + m1, m2, pol2 + m1, m2); + fmpz_zero(out + 2 * m1 - 1); + + _fmpz_poly_mulhigh_kara_recursive(out, pol1, pol2, temp + 2 * m2, m1); + + _fmpz_vec_sub(temp + m2 - 1, temp + m2 - 1, out + m2 - 1, 2 * m1 - m2); + _fmpz_vec_sub(temp + m2 - 1, temp + m2 - 1, out + 2 * m1 + m2 - 1, m2); + + _fmpz_vec_add(out + length - 1, out + length - 1, temp + m2 - 1, m2); + _fmpz_vec_zero(out, length - 1); +} + +/* Assumes poly1 and poly2 are not length 0. */ +void +_fmpz_poly_mulhigh_karatsuba_n(fmpz * res, const fmpz * poly1, + const fmpz * poly2, slong len) +{ + fmpz *temp; + slong length, loglen = 0; + + if (len == 1) + { + fmpz_mul(res, poly1, poly2); + return; + } + + while ((WORD(1) << loglen) < len) + loglen++; + length = (WORD(1) << loglen); + + temp = _fmpz_vec_init(2 * length); + + _fmpz_poly_mulhigh_kara_recursive(res, poly1, poly2, temp, len); + + _fmpz_vec_clear(temp, 2 * length); +} + +void +fmpz_poly_mulhigh_karatsuba_n(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2, + slong len) +{ + slong lenr = poly1->length + poly2->length - 1; + int clear1 = 0, clear2 = 0; + fmpz *pol1, *pol2; + + if (poly1->length == 0 || poly2->length == 0 || len - 1 >= lenr) + { + fmpz_poly_zero(res); + return; + } + + if (poly1->length != len) + { + pol1 = (fmpz *) flint_calloc(len, sizeof(fmpz)); + memcpy(pol1, poly1->coeffs, poly1->length * sizeof(fmpz)); + clear1 = 1; + } + else + pol1 = poly1->coeffs; + + if (poly2->length != len) + { + pol2 = (fmpz *) flint_calloc(len, sizeof(fmpz)); + memcpy(pol2, poly2->coeffs, poly2->length * sizeof(fmpz)); + clear2 = 1; + } + else + pol2 = poly2->coeffs; + + if (res != poly1 && res != poly2) + { + fmpz_poly_fit_length(res, 2 * len - 1); + _fmpz_poly_mulhigh_karatsuba_n(res->coeffs, pol1, pol2, len); + _fmpz_poly_set_length(res, lenr); + } + else + { + fmpz_poly_t temp; + fmpz_poly_init2(temp, 2 * len - 1); + + _fmpz_poly_mulhigh_karatsuba_n(temp->coeffs, pol1, pol2, len); + _fmpz_poly_set_length(temp, lenr); + + fmpz_poly_swap(temp, res); + fmpz_poly_clear(temp); + } + + if (clear1) + flint_free(pol1); + if (clear2) + flint_free(pol2); +} diff --git a/external/flint-2.4.3/fmpz_poly/mulhigh_n.c b/external/flint-2.4.3/fmpz_poly/mulhigh_n.c new file mode 100644 index 0000000..30bf715 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/mulhigh_n.c @@ -0,0 +1,64 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void +fmpz_poly_mulhigh_n(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2, slong n) +{ + mp_size_t limbs1 = _fmpz_vec_max_limbs(poly1->coeffs, poly1->length); + mp_size_t limbs2 = _fmpz_vec_max_limbs(poly2->coeffs, poly2->length); + mp_size_t len1 = poly1->length; + mp_size_t len2 = poly2->length; + mp_size_t limbsx = FLINT_MAX(limbs1, limbs2); + + if (n == 0) + { + fmpz_poly_zero(res); + return; + } + + if (n < 4) + { + fmpz_poly_mulhigh_classical(res, poly1, poly2, n - 1); + return; + } + + if ((limbsx > 4) && (n < 16)) + fmpz_poly_mulhigh_karatsuba_n(res, poly1, poly2, n); + else if (limbs1 + limbs2 <= 8) + fmpz_poly_mul_KS(res, poly1, poly2); + else if ((limbs1+limbs2)/2048 > len1 + len2) + fmpz_poly_mul_KS(res, poly1, poly2); + else if ((limbs1 + limbs2)*FLINT_BITS*4 < len1 + len2) + fmpz_poly_mul_KS(res, poly1, poly2); + else + fmpz_poly_mul_SS(res, poly1, poly2); +} diff --git a/external/flint-2.4.3/fmpz_poly/mullow.c b/external/flint-2.4.3/fmpz_poly/mullow.c new file mode 100644 index 0000000..e7bbd96 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/mullow.c @@ -0,0 +1,126 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void +_fmpz_poly_mullow(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2, slong n) +{ + mp_size_t limbs1, limbs2; + + if (len2 < 7 || n < 7) + { + _fmpz_poly_mullow_classical(res, poly1, len1, poly2, len2, n); + return; + } + + limbs1 = _fmpz_vec_max_limbs(poly1, len1); + limbs2 = _fmpz_vec_max_limbs(poly2, len2); + + if (n < 16 && (limbs1 > 12 || limbs2 > 12)) + { + int clear = 0, i; + fmpz *copy1, *copy2; + + if (len1 >= n) + copy1 = (fmpz *) poly1; + else + { + copy1 = (fmpz *) flint_malloc(n * sizeof(fmpz)); + for (i = 0; i < len1; i++) + copy1[i] = poly1[i]; + flint_mpn_zero((mp_ptr) copy1 + len1, n - len1); + clear |= 1; + } + + if (len2 >= n) + copy2 = (fmpz *) poly2; + else + { + copy2 = (fmpz *) flint_malloc(n * sizeof(fmpz)); + for (i = 0; i < len2; i++) + copy2[i] = poly2[i]; + flint_mpn_zero((mp_ptr) copy2 + len2, n - len2); + clear |= 2; + } + + _fmpz_poly_mullow_karatsuba_n(res, copy1, copy2, n); + + if (clear & 1) + flint_free(copy1); + if (clear & 2) + flint_free(copy2); + } + else if (limbs1 + limbs2 <= 8) + _fmpz_poly_mullow_KS(res, poly1, len1, poly2, len2, n); + else if ((limbs1+limbs2)/2048 > len1 + len2) + _fmpz_poly_mullow_KS(res, poly1, len1, poly2, len2, n); + else if ((limbs1 + limbs2)*FLINT_BITS*4 < len1 + len2) + _fmpz_poly_mullow_KS(res, poly1, len1, poly2, len2, n); + else + _fmpz_poly_mullow_SS(res, poly1, len1, poly2, len2, n); +} + +void +fmpz_poly_mullow(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2, + slong n) +{ + const slong len1 = poly1->length; + const slong len2 = poly2->length; + + if (len1 == 0 || len2 == 0 || n == 0) + { + fmpz_poly_zero(res); + return; + } + + if (res == poly1 || res == poly2) + { + fmpz_poly_t t; + fmpz_poly_init2(t, n); + fmpz_poly_mullow(t, poly1, poly2, n); + fmpz_poly_swap(res, t); + fmpz_poly_clear(t); + return; + } + + n = FLINT_MIN(n, len1 + len2 - 1); + + fmpz_poly_fit_length(res, n); + if (len1 >= len2) + _fmpz_poly_mullow(res->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, n); + else + _fmpz_poly_mullow(res->coeffs, poly2->coeffs, len2, poly1->coeffs, len1, n); + _fmpz_poly_set_length(res, n); + _fmpz_poly_normalise(res); +} diff --git a/external/flint-2.4.3/fmpz_poly/mullow_KS.c b/external/flint-2.4.3/fmpz_poly/mullow_KS.c new file mode 100644 index 0000000..627ad15 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/mullow_KS.c @@ -0,0 +1,144 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void +_fmpz_poly_mullow_KS(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2, slong n) +{ + int neg1, neg2; + slong limbs1, limbs2, loglen; + slong bits1, bits2, bits; + mp_limb_t *arr1, *arr2, *arr3; + slong sign = 0; + + FMPZ_VEC_NORM(poly1, len1); + FMPZ_VEC_NORM(poly2, len2); + + if (!len1 | !len2) + { + _fmpz_vec_zero(res, n); + return; + } + + neg1 = (fmpz_sgn(poly1 + len1 - 1) > 0) ? 0 : -1; + neg2 = (fmpz_sgn(poly2 + len2 - 1) > 0) ? 0 : -1; + + if (n > len1 + len2 - 1) + { + _fmpz_vec_zero(res + len1 + len2 - 1, n - (len1 + len2 - 1)); + n = len1 + len2 - 1; + } + + bits1 = _fmpz_vec_max_bits(poly1, len1); + if (bits1 < 0) + { + sign = 1; + bits1 = -bits1; + } + + if (poly1 != poly2) + { + bits2 = _fmpz_vec_max_bits(poly2, len2); + if (bits2 < 0) + { + sign = 1; + bits2 = -bits2; + } + } + else + bits2 = bits1; + + loglen = FLINT_BIT_COUNT(FLINT_MIN(len1, len2)); + bits = bits1 + bits2 + loglen + sign; + + limbs1 = (bits * len1 - 1) / FLINT_BITS + 1; + limbs2 = (bits * len2 - 1) / FLINT_BITS + 1; + + if (poly1 == poly2) + { + arr1 = (mp_ptr) flint_calloc(limbs1, sizeof(mp_limb_t)); + arr2 = arr1; + _fmpz_poly_bit_pack(arr1, poly1, len1, bits, neg1); + } + else + { + arr1 = (mp_ptr) flint_calloc(limbs1 + limbs2, sizeof(mp_limb_t)); + arr2 = arr1 + limbs1; + _fmpz_poly_bit_pack(arr1, poly1, len1, bits, neg1); + _fmpz_poly_bit_pack(arr2, poly2, len2, bits, neg2); + } + + arr3 = (mp_ptr) flint_malloc((limbs1 + limbs2) * sizeof(mp_limb_t)); + + if (limbs1 == limbs2) + mpn_mul_n(arr3, arr1, arr2, limbs1); + else if (limbs1 > limbs2) + mpn_mul(arr3, arr1, limbs1, arr2, limbs2); + else + mpn_mul(arr3, arr2, limbs2, arr1, limbs1); + + if (sign) + _fmpz_poly_bit_unpack(res, n, arr3, bits, neg1 ^ neg2); + else + _fmpz_poly_bit_unpack_unsigned(res, n, arr3, bits); + + flint_free(arr1); + flint_free(arr3); +} + +void +fmpz_poly_mullow_KS(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2, slong n) +{ + const slong len1 = poly1->length; + const slong len2 = poly2->length; + + if (len1 == 0 || len2 == 0 || n == 0) + { + fmpz_poly_zero(res); + } + else + { + fmpz_poly_fit_length(res, n); + + if (len1 >= len2) + _fmpz_poly_mullow_KS(res->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2, n); + else + _fmpz_poly_mullow_KS(res->coeffs, poly2->coeffs, len2, + poly1->coeffs, len1, n); + + _fmpz_poly_set_length(res, n); + _fmpz_poly_normalise(res); + } +} diff --git a/external/flint-2.4.3/fmpz_poly/mullow_SS.c b/external/flint-2.4.3/fmpz_poly/mullow_SS.c new file mode 100644 index 0000000..a5d5ed7 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/mullow_SS.c @@ -0,0 +1,142 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2008-2011 William Hart + +******************************************************************************/ + +#include +#include "fmpz_poly.h" +#include "fft.h" +#include "fft_tuning.h" + +void _fmpz_poly_mullow_SS(fmpz * output, const fmpz * input1, slong len1, + const fmpz * input2, slong len2, slong trunc) +{ + slong len_out = len1 + len2 - 1; + slong loglen = FLINT_CLOG2(len_out); + slong loglen2 = FLINT_CLOG2(len2); + slong n = (WORD(1) << (loglen - 2)); + + slong output_bits, limbs, size, i; + mp_limb_t * ptr, * t1, * t2, * tt, * s1, ** ii, ** jj; + slong bits1, bits2; + int sign = 0; + + ulong size1 = _fmpz_vec_max_limbs(input1, len1); + ulong size2 = _fmpz_vec_max_limbs(input2, len2); + + /* Start with an upper bound on the number of bits needed */ + output_bits = FLINT_BITS * (size1 + size2) + loglen2 + 1; + + /* round up for sqrt2 trick */ + output_bits = (((output_bits - 1) >> (loglen - 2)) + 1) << (loglen - 2); + + limbs = (output_bits - 1) / FLINT_BITS + 1; /* initial size of FFT coeffs */ + if (limbs > FFT_MULMOD_2EXPP1_CUTOFF) /* can't be worse than next power of 2 limbs */ + limbs = (WORD(1) << FLINT_CLOG2(limbs)); + size = limbs + 1; + + /* allocate space for ffts */ + ii = flint_malloc((4*(n + n*size) + 5*size)*sizeof(mp_limb_t)); + for (i = 0, ptr = (mp_limb_t *) ii + 4*n; i < 4*n; i++, ptr += size) + ii[i] = ptr; + t1 = ptr; + t2 = t1 + size; + s1 = t2 + size; + tt = s1 + size; + + if (input1 != input2) + { + jj = flint_malloc(4*(n + n*size)*sizeof(mp_limb_t)); + for (i = 0, ptr = (mp_limb_t *) jj + 4*n; i < 4*n; i++, ptr += size) + jj[i] = ptr; + } else jj = ii; + + /* put coefficients into FFT vecs */ + bits1 = _fmpz_vec_get_fft(ii, input1, limbs, len1); + for (i = len1; i < 4*n; i++) + flint_mpn_zero(ii[i], limbs + 1); + + if (input1 != input2) + { + bits2 = _fmpz_vec_get_fft(jj, input2, limbs, len2); + for (i = len2; i < 4*n; i++) + flint_mpn_zero(jj[i], limbs + 1); + } + else bits2 = bits1; + + if (bits1 < WORD(0) || bits2 < WORD(0)) + { + sign = 1; + bits1 = FLINT_ABS(bits1); + bits2 = FLINT_ABS(bits2); + } + + /* Recompute the number of bits/limbs now that we know how large everything is */ + output_bits = bits1 + bits2 + loglen2 + sign; + + /* round up output bits for sqrt2 */ + output_bits = (((output_bits - 1) >> (loglen - 2)) + 1) << (loglen - 2); + + limbs = (output_bits - 1) / FLINT_BITS + 1; + limbs = fft_adjust_limbs(limbs); /* round up limbs for Nussbaumer */ + + fft_convolution(ii, jj, loglen - 2, limbs, len_out, &t1, &t2, &s1, tt); + + _fmpz_vec_set_fft(output, trunc, ii, limbs, sign); /* write output */ + + flint_free(ii); + if (input1 != input2) + flint_free(jj); +} + +void +fmpz_poly_mullow_SS(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2, slong n) +{ + const slong len1 = poly1->length; + const slong len2 = poly2->length; + + if (len1 == 0 || len2 == 0 || n == 0) + { + fmpz_poly_zero(res); + return; + } + + if (len1 == 1 || len2 == 1) + { + fmpz_poly_mullow_classical(res, poly1, poly2, n); + return; + } + + fmpz_poly_fit_length(res, n); + + if (len1 >= len2) + _fmpz_poly_mullow_SS(res->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2, n); + else + _fmpz_poly_mullow_SS(res->coeffs, poly2->coeffs, len2, + poly1->coeffs, len1, n); + + _fmpz_poly_set_length(res, n); + _fmpz_poly_normalise(res); +} diff --git a/external/flint-2.4.3/fmpz_poly/mullow_classical.c b/external/flint-2.4.3/fmpz_poly/mullow_classical.c new file mode 100644 index 0000000..3377397 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/mullow_classical.c @@ -0,0 +1,97 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +/* + Assumes poly1 and poly2 are not length 0 and 0 < n <= len1 + len2 - 1. + */ +void +_fmpz_poly_mullow_classical(fmpz * res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2, slong n) +{ + if ((len1 == 1 && len2 == 1) || n == 1) /* Special case if the length of output is 1 */ + { + fmpz_mul(res, poly1, poly2); + } + else /* Ordinary case */ + { + slong i; + + /* Set res[i] = poly1[i]*poly2[0] */ + _fmpz_vec_scalar_mul_fmpz(res, poly1, FLINT_MIN(len1, n), poly2); + + /* Set res[i+len1-1] = in1[len1-1]*in2[i] */ + if (n > len1) + _fmpz_vec_scalar_mul_fmpz(res + len1, poly2 + 1, n - len1, + poly1 + len1 - 1); + + /* out[i+j] += in1[i]*in2[j] */ + for (i = 0; i < FLINT_MIN(len1, n) - 1; i++) + _fmpz_vec_scalar_addmul_fmpz(res + i + 1, poly2 + 1, + FLINT_MIN(len2, n - i) - 1, + poly1 + i); + } +} + +void +fmpz_poly_mullow_classical(fmpz_poly_t res, const fmpz_poly_t poly1, + const fmpz_poly_t poly2, slong n) +{ + slong len_out; + + if (poly1->length == 0 || poly2->length == 0 || n == 0) + { + fmpz_poly_zero(res); + return; + } + + len_out = poly1->length + poly2->length - 1; + if (n > len_out) + n = len_out; + + if (res == poly1 || res == poly2) + { + fmpz_poly_t t; + fmpz_poly_init2(t, n); + _fmpz_poly_mullow_classical(t->coeffs, poly1->coeffs, poly1->length, + poly2->coeffs, poly2->length, n); + fmpz_poly_swap(res, t); + fmpz_poly_clear(t); + } + else + { + fmpz_poly_fit_length(res, n); + _fmpz_poly_mullow_classical(res->coeffs, poly1->coeffs, poly1->length, + poly2->coeffs, poly2->length, n); + } + + _fmpz_poly_set_length(res, n); + _fmpz_poly_normalise(res); +} diff --git a/external/flint-2.4.3/fmpz_poly/mullow_karatsuba_n.c b/external/flint-2.4.3/fmpz_poly/mullow_karatsuba_n.c new file mode 100644 index 0000000..e9aa3de --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/mullow_karatsuba_n.c @@ -0,0 +1,173 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void +_fmpz_poly_mullow_kara_recursive(fmpz * out, const fmpz * pol1, + const fmpz * pol2, fmpz * temp, slong len); + +/* + Multiplication using truncated karatsuba. + + Below length 7, classical truncated multiplication is always theoretically + faster, so we switch to that as the basecase. Above that we use the + ordinary (left/right) karatsuba identity and recursively do one full + karatsuba multiplication and two truncated karatsuba multiplications. + */ + +void +_fmpz_poly_mullow_kara_recursive(fmpz * out, const fmpz * pol1, + const fmpz * pol2, fmpz * temp, slong len) +{ + slong m1 = len / 2; + slong m2 = len - m1; + int odd = (len & 1); + + if (len <= 6) + { + _fmpz_poly_mullow_classical(out, pol1, len, pol2, len, len); + return; + } + + _fmpz_vec_add(temp + m2, pol1, pol1 + m1, m1); + if (odd) + fmpz_set(temp + m2 + m1, pol1 + 2 * m1); + + _fmpz_vec_add(temp + 2 * m2, pol2, pol2 + m1, m1); + if (odd) + fmpz_set(temp + 2 * m2 + m1, pol2 + 2 * m1); + + _fmpz_poly_mul_karatsuba(out, pol1, m1, pol2, m1); + fmpz_zero(out + 2 * m1 - 1); + + _fmpz_poly_mullow_kara_recursive(temp, temp + m2, temp + 2 * m2, + temp + 3 * m2, m2); + + _fmpz_poly_mullow_kara_recursive(temp + m2, pol1 + m1, pol2 + m1, + temp + 2 * m2, m2); + + _fmpz_vec_sub(temp, temp, out, m2); + _fmpz_vec_sub(temp, temp, temp + m2, m2); + + if (odd) + fmpz_set(out + 2 * m1, temp + m2); + _fmpz_vec_add(out + m1, out + m1, temp, m2); +} + +/* Assumes poly1 and poly2 are not length 0. */ +void +_fmpz_poly_mullow_karatsuba_n(fmpz * res, const fmpz * poly1, + const fmpz * poly2, slong n) +{ + fmpz *temp; + slong len, loglen = 0; + + if (n == 1) + { + fmpz_mul(res, poly1, poly2); + return; + } + + while ((WORD(1) << loglen) < n) + loglen++; + len = (WORD(1) << loglen); + + temp = _fmpz_vec_init(3 * len); + + _fmpz_poly_mullow_kara_recursive(res, poly1, poly2, temp, n); + + _fmpz_vec_clear(temp, 3 * len); +} + +void +fmpz_poly_mullow_karatsuba_n(fmpz_poly_t res, const fmpz_poly_t poly1, + const fmpz_poly_t poly2, slong n) +{ + const slong len1 = FLINT_MIN(poly1->length, n); + const slong len2 = FLINT_MIN(poly2->length, n); + slong i, lenr; + + int clear = 0; + fmpz *copy1, *copy2; + + if (len1 == 0 || len2 == 0) + { + fmpz_poly_zero(res); + return; + } + + lenr = len1 + len2 - 1; + if (n > lenr) + n = lenr; + + if (len1 >= n) + copy1 = poly1->coeffs; + else + { + copy1 = (fmpz *) flint_malloc(n * sizeof(fmpz)); + for (i = 0; i < len1; i++) + copy1[i] = poly1->coeffs[i]; + flint_mpn_zero((mp_ptr) copy1 + len1, n - len1); + clear |= 1; + } + + if (len2 >= n) + copy2 = poly2->coeffs; + else + { + copy2 = (fmpz *) flint_malloc(n * sizeof(fmpz)); + for (i = 0; i < len2; i++) + copy2[i] = poly2->coeffs[i]; + flint_mpn_zero((mp_ptr) copy2 + len2, n - len2); + clear |= 2; + } + + if (res != poly1 && res != poly2) + { + fmpz_poly_fit_length(res, n); + _fmpz_poly_mullow_karatsuba_n(res->coeffs, copy1, copy2, n); + } + else + { + fmpz_poly_t t; + fmpz_poly_init2(t, n); + _fmpz_poly_mullow_karatsuba_n(t->coeffs, copy1, copy2, n); + fmpz_poly_swap(res, t); + fmpz_poly_clear(t); + } + _fmpz_poly_set_length(res, n); + _fmpz_poly_normalise(res); + + if (clear & 1) + flint_free(copy1); + if (clear & 2) + flint_free(copy2); +} diff --git a/external/flint-2.4.3/fmpz_poly/mulmid_classical.c b/external/flint-2.4.3/fmpz_poly/mulmid_classical.c new file mode 100644 index 0000000..d4630df --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/mulmid_classical.c @@ -0,0 +1,94 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +/* Assumes poly1 and poly2 are not length 0 and len1 >= len2. */ +void +_fmpz_poly_mulmid_classical(fmpz * res, const fmpz * poly1, + slong len1, const fmpz * poly2, slong len2) +{ + if ((len1 == 1) && (len2 == 1)) /* Special case if the length of both inputs is 1 */ + { + fmpz_mul(res, poly1, poly2); + } + else /* Ordinary case */ + { + slong i; + + /* Set res[i] = poly1[i]*poly2[0] */ + _fmpz_vec_scalar_mul_fmpz(res, poly1 + len2 - 1, len1 - len2 + 1, + poly2); + + /* out[i+j] += in1[i]*in2[j] */ + for (i = 0; i < len2 - 1; i++) + _fmpz_vec_scalar_addmul_fmpz(res, poly2 + len2 - i - 1, + FLINT_MIN(i + 1, len1 - len2 + 1), + poly1 + i); + for (; i < len1 - 1; i++) + _fmpz_vec_scalar_addmul_fmpz(res + i - len2 + 2, poly2 + 1, + FLINT_MIN(len2 - 1, len1 - i - 1), + poly1 + i); + } +} + + +void +fmpz_poly_mulmid_classical(fmpz_poly_t res, + const fmpz_poly_t poly1, const fmpz_poly_t poly2) +{ + slong len_out; + + if (poly1->length == 0 || poly2->length == 0) + { + fmpz_poly_zero(res); + return; + } + + len_out = poly1->length - poly2->length + 1; + + if (res == poly1 || res == poly2) + { + fmpz_poly_t temp; + fmpz_poly_init2(temp, len_out); + _fmpz_poly_mulmid_classical(temp->coeffs, poly1->coeffs, poly1->length, + poly2->coeffs, poly2->length); + fmpz_poly_swap(res, temp); + fmpz_poly_clear(temp); + } + else + { + fmpz_poly_fit_length(res, len_out); + _fmpz_poly_mulmid_classical(res->coeffs, poly1->coeffs, poly1->length, + poly2->coeffs, poly2->length); + } + + _fmpz_poly_set_length(res, len_out); + _fmpz_poly_normalise(res); +} diff --git a/external/flint-2.4.3/fmpz_poly/neg.c b/external/flint-2.4.3/fmpz_poly/neg.c new file mode 100644 index 0000000..ad77daa --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/neg.c @@ -0,0 +1,41 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +void +fmpz_poly_neg(fmpz_poly_t res, const fmpz_poly_t poly) +{ + slong i; + fmpz_poly_fit_length(res, poly->length); + + for (i = 0; i < poly->length; i++) + fmpz_neg(res->coeffs + i, poly->coeffs + i); + + _fmpz_poly_set_length(res, poly->length); +} diff --git a/external/flint-2.4.3/fmpz_poly/newton_to_monomial.c b/external/flint-2.4.3/fmpz_poly/newton_to_monomial.c new file mode 100644 index 0000000..fd841a8 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/newton_to_monomial.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +void +_fmpz_poly_newton_to_monomial(fmpz * poly, const fmpz * roots, slong n) +{ + slong i, j; + + for (i = n - 2; i >= 0; i--) + for (j = i; j < n - 1; j++) + fmpz_submul(poly + j, poly + j + 1, roots + i); +} diff --git a/external/flint-2.4.3/fmpz_poly/normalise.c b/external/flint-2.4.3/fmpz_poly/normalise.c new file mode 100644 index 0000000..995397e --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/normalise.c @@ -0,0 +1,37 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +void +_fmpz_poly_normalise(fmpz_poly_t poly) +{ + slong i; + for (i = poly->length - 1; (i >= 0) && !poly->coeffs[i]; i--) ; + poly->length = i + 1; +} diff --git a/external/flint-2.4.3/fmpz_poly/pow.c b/external/flint-2.4.3/fmpz_poly/pow.c new file mode 100644 index 0000000..92ff19e --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/pow.c @@ -0,0 +1,92 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void +_fmpz_poly_pow(fmpz * res, const fmpz * poly, slong len, ulong e) +{ + if (e < UWORD(5)) + _fmpz_poly_pow_small(res, poly, len, e); + else if (len == 2) + _fmpz_poly_pow_binomial(res, poly, e); + else + { + ulong limbs = (ulong) _fmpz_vec_max_limbs(poly, len); + + if (limbs < ((UWORD(3) * e) / UWORD(2) + UWORD(150)) / (ulong) len) + _fmpz_poly_pow_multinomial(res, poly, len, e); + else + _fmpz_poly_pow_binexp(res, poly, len, e); + } +} + +void +fmpz_poly_pow(fmpz_poly_t res, const fmpz_poly_t poly, ulong e) +{ + const slong len = poly->length; + slong rlen; + + if ((len < 2) | (e < UWORD(3))) + { + if (e == UWORD(0)) + fmpz_poly_set_ui(res, 1); + else if (len == 0) + fmpz_poly_zero(res); + else if (len == 1) + { + fmpz_poly_fit_length(res, 1); + fmpz_pow_ui(res->coeffs, poly->coeffs, e); + _fmpz_poly_set_length(res, 1); + } + else if (e == UWORD(1)) + fmpz_poly_set(res, poly); + else /* e == UWORD(2) */ + fmpz_poly_sqr(res, poly); + return; + } + + rlen = (slong) e * (len - 1) + 1; + + if (res != poly) + { + fmpz_poly_fit_length(res, rlen); + _fmpz_poly_set_length(res, rlen); + _fmpz_poly_pow(res->coeffs, poly->coeffs, len, e); + } + else + { + fmpz_poly_t t; + fmpz_poly_init2(t, rlen); + _fmpz_poly_set_length(t, rlen); + _fmpz_poly_pow(t->coeffs, poly->coeffs, len, e); + fmpz_poly_swap(res, t); + fmpz_poly_clear(t); + } +} diff --git a/external/flint-2.4.3/fmpz_poly/pow_addchains.c b/external/flint-2.4.3/fmpz_poly/pow_addchains.c new file mode 100644 index 0000000..a0bda8e --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/pow_addchains.c @@ -0,0 +1,202 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void _fmpz_poly_pow_addchains(fmpz * res, const fmpz * poly, slong len, + const int * a, int n) +{ + int *b; + slong lenm1 = len - 1, lenv; + fmpz *v; + + /* + Compute partial sums + */ + { + int i; + b = (int *) flint_malloc(n * sizeof(int)); + b[0] = 0; + for (i = 1; i < n; i++) + b[i] = b[i-1] + a[i]; + } + + /* + Allocate memory for the polynomials f^{a[1]}, ..., f^{a[n-1]} + */ + lenv = lenm1 * b[n-1] + n - 1; + v = _fmpz_vec_init(lenv); + + /* + Compute f^{a[1]}, ..., f^{a[n-1]} + */ + { + int d, i, j; + + _fmpz_poly_sqr(v, poly, len); + + for (i = 1; i < n-1; i++) + { + d = a[i+1] - a[i]; + if (d == 1) + { + _fmpz_poly_mul(v + lenm1 * b[i] + (i), + v + lenm1 * b[i-1], lenm1 * a[i] + 1, + poly, len); + } + else + { + for (j = i; a[j] != d; j--) ; + _fmpz_poly_mul(v + lenm1 * b[i] + (i), + v + lenm1 * b[i-1], lenm1 * a[i] + 1, + v + lenm1 * b[j-1] + (j-1), lenm1 * a[j] + 1); + } + } + + /* + Deal with the final product stored in res, i == n-1 + */ + { + d = a[i+1] - a[i]; + if (d == 1) + { + _fmpz_poly_mul(res, + v + lenm1 * b[i-1], lenm1 * a[i] + 1, + poly, len); + } + else + { + for (j = i; a[j] != d; j--) ; + _fmpz_poly_mul(res, + v + lenm1 * b[i-1], lenm1 * a[i] + 1, + v + lenm1 * b[j-1] + (j-1), lenm1 * a[j] + 1); + } + } + + } + + flint_free(b); + _fmpz_vec_clear(v, lenv); +} + +void fmpz_poly_pow_addchains(fmpz_poly_t res, const fmpz_poly_t poly, ulong e) +{ + const slong len = poly->length; + + if ((len < 2) | (e < UWORD(3))) + { + if (e == UWORD(0)) + fmpz_poly_set_ui(res, 1); + else if (len == 0) + fmpz_poly_zero(res); + else if (len == 1) + { + fmpz_poly_fit_length(res, 1); + fmpz_pow_ui(res->coeffs, poly->coeffs, e); + _fmpz_poly_set_length(res, 1); + } + else if (e == UWORD(1)) + fmpz_poly_set(res, poly); + else /* e == UWORD(2) */ + fmpz_poly_sqr(res, poly); + return; + } + + if (e <= UWORD(148)) + { + /* + An array storing a tree with shortest addition chains (star chains, + in fact) for all integers up to and including 148. + + Let A denote the array. The entry A[0] is present to provide + 1-based indexing. The integer 1 is the root of the tree and the + entry A[1] is irrelevant. For integers i >= 2, A[i] is the parent + of i. + + We can iterate through an addition chain for n, where 0 < n < 148, + in the array shortest_addchains_148 as follows: + + Visit n + while ((n = shortest_addchains_148[n])) + { + Visit n + } + */ + static const int shortest_addchains_148[149] = { + 0, 0, 1, 2, 2, 3, 3, 5, 4, 8, + 5, 10, 6, 9, 7, 12, 8, 9, 16, 18, + 10, 15, 11, 20, 12, 17, 13, 24, 14, 25, + 15, 28, 16, 32, 17, 26, 18, 36, 19, 27, + 20, 40, 21, 34, 22, 30, 23, 46, 24, 33, + 25, 48, 26, 37, 27, 54, 28, 49, 29, 56, + 30, 52, 31, 51, 32, 64, 33, 66, 34, 68, + 35, 70, 36, 72, 66, 60, 38, 43, 39, 78, + 40, 65, 41, 80, 42, 80, 43, 86, 44, 88, + 45, 90, 46, 92, 47, 92, 48, 96, 49, 96, + 50,100, 51,102, 52,102, 53, 74, 54,108, + 55,108, 56,104, 57,112, 58,104, 59,112, + 60,120, 61,120, 62,100, 63,126, 64,128, + 65,130,128,132, 67, 90, 68,136, 69,138, + 70,140, 71,117, 72,144, 73, 99, 74 + }; + + int a[11], i = 11, n = (int) e; + slong rlen = (slong) e * (len - 1) + 1; + + /* + Copy the addition chain into 1 = a[0] < a[1] < ... < a[n] + */ + a[--i] = n; + while ((n = shortest_addchains_148[n])) + a[--i] = n; + n = 10 - i; + + if (res != poly) + { + fmpz_poly_fit_length(res, rlen); + _fmpz_poly_pow_addchains(res->coeffs, poly->coeffs, len, a + i, n); + _fmpz_poly_set_length(res, rlen); + } + else + { + fmpz_poly_t t; + fmpz_poly_init2(t, rlen); + _fmpz_poly_pow_addchains(t->coeffs, poly->coeffs, len, a + i, n); + _fmpz_poly_set_length(t, rlen); + fmpz_poly_swap(res, t); + fmpz_poly_clear(t); + } + } + else + { + flint_printf("Exception (fmpz_poly_addchains). Powering via chains not implemented for e > 148.\n"); + abort(); + } +} diff --git a/external/flint-2.4.3/fmpz_poly/pow_binexp.c b/external/flint-2.4.3/fmpz_poly/pow_binexp.c new file mode 100644 index 0000000..b21a938 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/pow_binexp.c @@ -0,0 +1,156 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void +_fmpz_poly_pow_binexp(fmpz * res, const fmpz * poly, slong len, ulong e) +{ + ulong bit = ~((~UWORD(0)) >> 1); + slong rlen; + slong alloc = (slong) e * (len - 1) + 1; + fmpz *v = _fmpz_vec_init(alloc); + fmpz *R, *S, *T; + + /* + Set bits to the bitmask with a 1 one place lower than the msb of e + */ + + while ((bit & e) == UWORD(0)) + bit >>= 1; + + bit >>= 1; + + /* + Trial run without any polynomial arithmetic to determine the parity + of the number of swaps; then set R and S accordingly + */ + + { + unsigned int swaps = 0U; + ulong bit2 = bit; + if ((bit2 & e)) + swaps = ~swaps; + while (bit2 >>= 1) + if ((bit2 & e) == UWORD(0)) + swaps = ~swaps; + + if (swaps == 0U) + { + R = res; + S = v; + } + else + { + R = v; + S = res; + } + } + + /* + We unroll the first step of the loop, referring to {poly, len} + */ + + _fmpz_poly_sqr(R, poly, len); + rlen = 2 * len - 1; + if ((bit & e)) + { + _fmpz_poly_mul(S, R, rlen, poly, len); + rlen += len - 1; + T = R; + R = S; + S = T; + } + + while ((bit >>= 1)) + { + if ((bit & e)) + { + _fmpz_poly_sqr(S, R, rlen); + rlen += rlen - 1; + _fmpz_poly_mul(R, S, rlen, poly, len); + rlen += len - 1; + } + else + { + _fmpz_poly_sqr(S, R, rlen); + rlen += rlen - 1; + T = R; + R = S; + S = T; + } + } + + _fmpz_vec_clear(v, alloc); +} + +void +fmpz_poly_pow_binexp(fmpz_poly_t res, const fmpz_poly_t poly, ulong e) +{ + const slong len = poly->length; + slong rlen; + + if ((len < 2) | (e < UWORD(3))) + { + if (e == UWORD(0)) + fmpz_poly_set_ui(res, 1); + else if (len == 0) + fmpz_poly_zero(res); + else if (len == 1) + { + fmpz_poly_fit_length(res, 1); + fmpz_pow_ui(res->coeffs, poly->coeffs, e); + _fmpz_poly_set_length(res, 1); + } + else if (e == UWORD(1)) + fmpz_poly_set(res, poly); + else /* e == UWORD(2) */ + fmpz_poly_sqr(res, poly); + return; + } + + rlen = (slong) e * (len - 1) + 1; + + if (res != poly) + { + fmpz_poly_fit_length(res, rlen); + _fmpz_poly_pow_binexp(res->coeffs, poly->coeffs, len, e); + _fmpz_poly_set_length(res, rlen); + } + else + { + fmpz_poly_t t; + fmpz_poly_init2(t, rlen); + _fmpz_poly_pow_binexp(t->coeffs, poly->coeffs, len, e); + _fmpz_poly_set_length(t, rlen); + fmpz_poly_swap(res, t); + fmpz_poly_clear(t); + } +} diff --git a/external/flint-2.4.3/fmpz_poly/pow_binomial.c b/external/flint-2.4.3/fmpz_poly/pow_binomial.c new file mode 100644 index 0000000..471ea7b --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/pow_binomial.c @@ -0,0 +1,123 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void +_fmpz_poly_pow_binomial(fmpz * res, const fmpz * poly, ulong e) +{ + ulong i, f; + fmpz_t a, b, c; + + *a = WORD(1); + *b = WORD(1); + *c = WORD(1); + + fmpz_one(res); + fmpz_one(res + e); + + for (i = UWORD(1), f = e - UWORD(1); i <= (e - UWORD(1)) >> 1; i++, f--) + { + fmpz_mul(a, a, poly); + fmpz_mul(b, b, poly + 1); + fmpz_mul_ui(c, c, f + UWORD(1)); + fmpz_divexact_ui(c, c, i); + + fmpz_mul(res + i, b, c); + fmpz_mul(res + f, a, c); + } + + if ((e & UWORD(1)) == UWORD(0)) + { + fmpz_mul(a, a, poly); + fmpz_mul(b, b, poly + 1); + fmpz_mul_ui(c, c, f + UWORD(1)); + fmpz_divexact_ui(c, c, i); + + fmpz_mul(res + i, b, c); + fmpz_mul(res + i, res + i, a); + i++, f--; + } + + for ( ; i <= e; i++, f--) + { + fmpz_mul(a, a, poly); + fmpz_mul(b, b, poly + 1); + + fmpz_mul(res + i, res + i, b); + fmpz_mul(res + f, res + f, a); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); +} + +void +fmpz_poly_pow_binomial(fmpz_poly_t res, const fmpz_poly_t poly, ulong e) +{ + const slong len = poly->length; + slong rlen; + + if (len != 2) + { + flint_printf("Exception (fmpz_poly_pow_binomial). poly->length not equal to 2.\n"); + abort(); + } + + if (e < UWORD(3)) + { + if (e == UWORD(0)) + fmpz_poly_set_ui(res, UWORD(1)); + else if (e == UWORD(1)) + fmpz_poly_set(res, poly); + else /* e == UWORD(2) */ + fmpz_poly_sqr(res, poly); + return; + } + + rlen = (slong) e + 1; + + if (res != poly) + { + fmpz_poly_fit_length(res, rlen); + _fmpz_poly_set_length(res, rlen); + _fmpz_poly_pow_binomial(res->coeffs, poly->coeffs, e); + } + else + { + fmpz_poly_t t; + fmpz_poly_init2(t, rlen); + _fmpz_poly_set_length(t, rlen); + _fmpz_poly_pow_binomial(t->coeffs, poly->coeffs, e); + fmpz_poly_swap(res, t); + fmpz_poly_clear(t); + } +} diff --git a/external/flint-2.4.3/fmpz_poly/pow_multinomial.c b/external/flint-2.4.3/fmpz_poly/pow_multinomial.c new file mode 100644 index 0000000..e02a762 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/pow_multinomial.c @@ -0,0 +1,123 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void +_fmpz_poly_pow_multinomial(fmpz * res, const fmpz * poly, slong len, ulong e) +{ + slong k, low, rlen; + fmpz_t d, t; + fmpz * P; + + rlen = (slong) e * (len - WORD(1)) + WORD(1); + _fmpz_vec_zero(res, rlen); + + for (low = WORD(0); poly[low] == WORD(0); low++) ; + if (low == WORD(0)) + { + P = (fmpz *) poly; + } + else + { + P = (fmpz *) poly + low; + len -= low; + res += (slong) e * low; + rlen -= (slong) e * low; + } + + fmpz_init(d); + fmpz_init(t); + + fmpz_pow_ui(res, P, e); + + for (k = 1; k < rlen; k++) + { + slong i, u = -k; + for (i = 1; i <= FLINT_MIN(k, len - 1); i++) + { + fmpz_mul(t, P + i, res + (k - i)); + u += (slong) e + 1; + if (u >= 0) + fmpz_addmul_ui(res + k, t, (ulong) u); + else + fmpz_submul_ui(res + k, t, - ((ulong) u)); + } + fmpz_add(d, d, P); + fmpz_divexact(res + k, res + k, d); + } + + fmpz_clear(d); + fmpz_clear(t); +} + +void +fmpz_poly_pow_multinomial(fmpz_poly_t res, const fmpz_poly_t poly, ulong e) +{ + const slong len = poly->length; + slong rlen; + + if ((len < 2) | (e < UWORD(3))) + { + if (e == UWORD(0)) + fmpz_poly_set_ui(res, 1); + else if (len == 0) + fmpz_poly_zero(res); + else if (len == 1) + { + fmpz_poly_fit_length(res, 1); + fmpz_pow_ui(res->coeffs, poly->coeffs, e); + _fmpz_poly_set_length(res, 1); + } + else if (e == UWORD(1)) + fmpz_poly_set(res, poly); + else /* e == UWORD(2) */ + fmpz_poly_sqr(res, poly); + return; + } + + rlen = (slong) e * (len - 1) + 1; + + if (res != poly) + { + fmpz_poly_fit_length(res, rlen); + _fmpz_poly_pow_multinomial(res->coeffs, poly->coeffs, len, e); + _fmpz_poly_set_length(res, rlen); + } + else + { + fmpz_poly_t t; + fmpz_poly_init2(t, rlen); + _fmpz_poly_pow_multinomial(t->coeffs, poly->coeffs, len, e); + _fmpz_poly_set_length(t, rlen); + fmpz_poly_swap(res, t); + fmpz_poly_clear(t); + } +} diff --git a/external/flint-2.4.3/fmpz_poly/pow_small.c b/external/flint-2.4.3/fmpz_poly/pow_small.c new file mode 100644 index 0000000..0a00365 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/pow_small.c @@ -0,0 +1,66 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void +_fmpz_poly_pow_small(fmpz * res, const fmpz * poly, slong len, ulong e) +{ + switch (e) + { + case 0: + fmpz_one(res); + break; + case 1: + _fmpz_vec_set(res, poly, len); + break; + case 2: + _fmpz_poly_sqr(res, poly, len); + break; + case 3: + { + slong alloc = 2 * len - 1; + fmpz *t = _fmpz_vec_init(alloc); + _fmpz_poly_sqr(t, poly, len); + _fmpz_poly_mul(res, t, alloc, poly, len); + _fmpz_vec_clear(t, alloc); + break; + } + case 4: + { + slong alloc = 2 * len - 1; + fmpz *t = _fmpz_vec_init(alloc); + _fmpz_poly_sqr(t, poly, len); + _fmpz_poly_sqr(res, t, alloc); + _fmpz_vec_clear(t, alloc); + break; + } + } +} + diff --git a/external/flint-2.4.3/fmpz_poly/pow_trunc.c b/external/flint-2.4.3/fmpz_poly/pow_trunc.c new file mode 100644 index 0000000..fcb8d9e --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/pow_trunc.c @@ -0,0 +1,188 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void +_fmpz_poly_pow_trunc(fmpz * res, const fmpz * poly, ulong e, slong n) +{ + ulong bit = ~((~UWORD(0)) >> 1); + fmpz *v = _fmpz_vec_init(n); + fmpz *R, *S, *T; + + /* + Set bits to the bitmask with a 1 one place lower than the msb of e + */ + + while ((bit & e) == UWORD(0)) + bit >>= 1; + + bit >>= 1; + + /* + Trial run without any polynomial arithmetic to determine the parity + of the number of swaps; then set R and S accordingly + */ + + { + unsigned int swaps = 0U; + ulong bit2 = bit; + if ((bit2 & e)) + swaps = ~swaps; + while (bit2 >>= 1) + if ((bit2 & e) == UWORD(0)) + swaps = ~swaps; + + if (swaps == 0U) + { + R = res; + S = v; + } + else + { + R = v; + S = res; + } + } + + /* + We unroll the first step of the loop, referring to {poly, n} + */ + + _fmpz_poly_sqrlow(R, poly, n, n); + if ((bit & e)) + { + _fmpz_poly_mullow(S, R, n, poly, n, n); + T = R; + R = S; + S = T; + } + + while ((bit >>= 1)) + { + if ((bit & e)) + { + _fmpz_poly_sqrlow(S, R, n, n); + _fmpz_poly_mullow(R, S, n, poly, n, n); + } + else + { + _fmpz_poly_sqrlow(S, R, n, n); + T = R; + R = S; + S = T; + } + } + + _fmpz_vec_clear(v, n); +} + +void +fmpz_poly_pow_trunc(fmpz_poly_t res, const fmpz_poly_t poly, ulong e, slong n) +{ + fmpz * copy; + int clear; + slong i, len; + + if (n == 0) + { + fmpz_poly_zero(res); + return; + } + if (e == 0) + { + fmpz_poly_set_ui(res, 1); + return; + } + + /* Set len to the length of poly mod x^n */ + len = FLINT_MIN(n, poly->length); + for (--len; (len >= 0) && !poly->coeffs[len]; --len) ; + ++len; + + if ((len < 2) | (e < 3)) + { + if (len == 0) + fmpz_poly_zero(res); + else if (len == 1) + { + fmpz_poly_fit_length(res, 1); + fmpz_pow_ui(res->coeffs, poly->coeffs, e); + _fmpz_poly_set_length(res, 1); + } + else if (e == 1) + { + if (res != poly) + { + fmpz_poly_fit_length(res, len); + _fmpz_vec_set(res->coeffs, poly->coeffs, len); + _fmpz_poly_set_length(res, len); + } + else + fmpz_poly_truncate(res, len); + } + else /* e == 2 */ + fmpz_poly_sqrlow(res, poly, n); + return; + } + + if (poly->length >= n) + { + copy = poly->coeffs; + clear = 0; + } + else + { + copy = (fmpz *) flint_malloc(n * sizeof(fmpz)); + for (i = 0; i < poly->length; i++) + copy[i] = poly->coeffs[i]; + flint_mpn_zero((mp_ptr) copy + poly->length, n - poly->length); + clear = 1; + } + + if (res != poly) + { + fmpz_poly_fit_length(res, n); + _fmpz_poly_pow_trunc(res->coeffs, copy, e, n); + } + else + { + fmpz_poly_t t; + fmpz_poly_init2(t, n); + _fmpz_poly_pow_trunc(t->coeffs, copy, e, n); + fmpz_poly_swap(res, t); + fmpz_poly_clear(t); + } + _fmpz_poly_set_length(res, n); + _fmpz_poly_normalise(res); + + if (clear) + flint_free(copy); +} + diff --git a/external/flint-2.4.3/fmpz_poly/powers_clear.c b/external/flint-2.4.3/fmpz_poly/powers_clear.c new file mode 100644 index 0000000..177ec44 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/powers_clear.c @@ -0,0 +1,45 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +void +_fmpz_poly_powers_clear(fmpz ** powers, slong len) +{ + slong i; + for (i = 0; i < 2*len - 1; i++) + _fmpz_vec_clear(powers[i], len - 1); + + flint_free(powers); +} + +void +fmpz_poly_powers_clear(fmpz_poly_powers_precomp_t pinv) +{ + _fmpz_poly_powers_clear(pinv->powers, pinv->len); +} diff --git a/external/flint-2.4.3/fmpz_poly/powers_precompute.c b/external/flint-2.4.3/fmpz_poly/powers_precompute.c new file mode 100644 index 0000000..7691a04 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/powers_precompute.c @@ -0,0 +1,77 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +fmpz ** +_fmpz_poly_powers_precompute(const fmpz * B, slong len) +{ + slong i; + fmpz ** powers = flint_malloc(sizeof(fmpz *)*(2*len - 1)); + fmpz_poly_t pow, p; + + fmpz_poly_init2(pow, len); + fmpz_poly_one(pow); + fmpz_poly_init2(p, len - 1); + + for (i = 0; i < 2*len - 1; i++) + { + powers[i] = _fmpz_vec_init(len - 1); + + if (pow->length == len) /* reduce pow mod B */ + { + _fmpz_vec_scalar_mul_fmpz(p->coeffs, B, len - 1, pow->coeffs + pow->length - 1); + _fmpz_poly_set_length(p, len - 1); + _fmpz_poly_normalise(p); + fmpz_poly_sub(pow, pow, p); + _fmpz_poly_set_length(pow, len - 1); + _fmpz_poly_normalise(pow); + } + + _fmpz_vec_set(powers[i], pow->coeffs, len - 1); + fmpz_poly_shift_left(pow, pow, 1); + } + + fmpz_poly_clear(pow); + fmpz_poly_clear(p); + + return powers; +} + +void fmpz_poly_powers_precompute(fmpz_poly_powers_precomp_t pinv, + fmpz_poly_t poly) +{ + if (poly->length == 0) + { + flint_printf("Exception (fmpz_poly_powers_precompute). Division by zero.\n"); + abort(); + } + + pinv->powers = _fmpz_poly_powers_precompute(poly->coeffs, poly->length); + pinv->len = poly->length; +} diff --git a/external/flint-2.4.3/fmpz_poly/preinvert.c b/external/flint-2.4.3/fmpz_poly/preinvert.c new file mode 100644 index 0000000..2a46d98 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/preinvert.c @@ -0,0 +1,121 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + Copyright (C) 2013 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +void +_fmpz_poly_preinvert(fmpz * Binv, const fmpz * B, slong len) +{ + if (len == 1) /* B is +-1 */ + { + fmpz_set(Binv, B); + } + else + { + const slong alloc = len + FLINT_MAX(len, 3 * FMPZ_POLY_INV_NEWTON_CUTOFF); + slong *a, i, m, n = len; + fmpz *T, *W; + + T = _fmpz_vec_init(alloc); + W = T + len; + + for (i = 1; (WORD(1) << i) < n; i++) ; + + a = (slong *) flint_malloc(i * sizeof(slong)); + a[i = 0] = n; + while (n >= FMPZ_POLY_INV_NEWTON_CUTOFF) + a[++i] = (n = (n + 1) / 2); + + if (len != n) + _fmpz_poly_reverse(T, B, len, len); /* only reverse if it ... */ + + /* Base case */ + { + fmpz *Brev = W + 2 * FMPZ_POLY_INV_NEWTON_CUTOFF; + if (len != n) + _fmpz_poly_reverse(Brev, T, n, n); /* ... won't be undone */ + else Brev = (fmpz *) B; + + _fmpz_vec_zero(W, 2*n - 2); + fmpz_one(W + (2*n - 2)); + _fmpz_poly_div_basecase(Binv, W, W, 2*n - 1, Brev, n); + _fmpz_poly_reverse(Binv, Binv, n, n); + } + + for (i--; i >= 0; i--) + { + m = n; + n = a[i]; + + _fmpz_poly_mullow(W, T, n, Binv, m, n); + _fmpz_poly_mullow(Binv + m, Binv, m, W + m, n - m, n - m); + _fmpz_vec_neg(Binv + m, Binv + m, n - m); + } + + _fmpz_vec_clear(T, alloc); + flint_free(a); + } +} + +void +fmpz_poly_preinvert(fmpz_poly_t B_inv, const fmpz_poly_t B) +{ + slong n = B->length; + fmpz_poly_t temp; + fmpz * Binv_coeffs; + + if (n == 0) + { + flint_printf("Exception (fmpz_poly_preinvert). Division by zero.\n"); + abort(); + } + + if (B == B_inv) + { + fmpz_poly_init2(temp, n); + Binv_coeffs = temp->coeffs; + } else + { + fmpz_poly_fit_length(B_inv, n); + Binv_coeffs = B_inv->coeffs; + } + + _fmpz_poly_preinvert(Binv_coeffs, B->coeffs, n); + + + if (B == B_inv) + { + _fmpz_poly_set_length(temp, n); + fmpz_poly_swap(B_inv, temp); + fmpz_poly_clear(temp); + } else + _fmpz_poly_set_length(B_inv, n); + + /* no need to normalise */ +} diff --git a/external/flint-2.4.3/fmpz_poly/primitive_part.c b/external/flint-2.4.3/fmpz_poly/primitive_part.c new file mode 100644 index 0000000..fd87ec0 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/primitive_part.c @@ -0,0 +1,57 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void +_fmpz_poly_primitive_part(fmpz * res, const fmpz * poly, slong len) +{ + fmpz_t x; + fmpz_init(x); + _fmpz_poly_content(x, poly, len); + if (fmpz_sgn(poly + (len - 1)) < 0) + fmpz_neg(x, x); + _fmpz_vec_scalar_divexact_fmpz(res, poly, len, x); + fmpz_clear(x); +} + +void +fmpz_poly_primitive_part(fmpz_poly_t res, const fmpz_poly_t poly) +{ + slong len = poly->length; + if (len == 0) + { + fmpz_poly_zero(res); + return; + } + + fmpz_poly_fit_length(res, len); + _fmpz_poly_set_length(res, len); + _fmpz_poly_primitive_part(res->coeffs, poly->coeffs, len); +} diff --git a/external/flint-2.4.3/fmpz_poly/product_roots_fmpz_vec.c b/external/flint-2.4.3/fmpz_poly/product_roots_fmpz_vec.c new file mode 100644 index 0000000..ca17a95 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/product_roots_fmpz_vec.c @@ -0,0 +1,77 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +void +_fmpz_poly_product_roots_fmpz_vec(fmpz * poly, const fmpz * xs, slong n) +{ + if (n == 0) + { + fmpz_one(poly); + } + else if (n < 20) + { + slong i, j; + + fmpz_one(poly + n); + fmpz_neg(poly + n - 1, xs); + + for (i = 1; i < n; i++) + { + fmpz_mul(poly + n - i - 1, poly + n - i, xs + i); + fmpz_neg(poly + n - i - 1, poly + n - i - 1); + for (j = 0; j < i - 1; j++) + fmpz_submul(poly + n - i + j, poly + n - i + j + 1, xs + i); + fmpz_sub(poly + n - 1, poly + n - 1, xs + i); + } + } + else + { + slong m; + fmpz * tmp; + + m = (n + 1) / 2; + + tmp = _fmpz_vec_init(n + 2); + + _fmpz_poly_product_roots_fmpz_vec(tmp, xs, m); + _fmpz_poly_product_roots_fmpz_vec(tmp + m + 1, xs + m, n - m); + _fmpz_poly_mul(poly, tmp, m + 1, tmp + m + 1, n - m + 1); + + _fmpz_vec_clear(tmp, n + 2); + } +} + +void +fmpz_poly_product_roots_fmpz_vec(fmpz_poly_t poly, const fmpz * xs, slong n) +{ + fmpz_poly_fit_length(poly, n + 1); + _fmpz_poly_product_roots_fmpz_vec(poly->coeffs, xs, n); + _fmpz_poly_set_length(poly, n + 1); +} diff --git a/external/flint-2.4.3/fmpz_poly/profile/bm-div_divconquer.c b/external/flint-2.4.3/fmpz_poly/profile/bm-div_divconquer.c new file mode 100644 index 0000000..eeff599 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/profile/bm-div_divconquer.c @@ -0,0 +1,148 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +void fmpz_poly_gmprand(fmpz_poly_t rop, gmp_randstate_t state, slong len, slong bits) +{ + slong i; + mpz_t c; + fmpz_t d; + mpz_init(c); + fmpz_init(d); + fmpz_poly_zero(rop); + fmpz_poly_fit_length(rop, len); + for (i = 0; i < len; i++) + { + mpz_urandomb(c, state, bits); + if (rand() & WORD(1)) + mpz_neg(c, c); + fmpz_set_mpz(d, c); + fmpz_poly_set_coeff_fmpz(rop, i, d); + } + mpz_clear(c); + fmpz_clear(d); +} + +#define lenlo 1 +#define lenhi 100 +#define lenh 5 +#define bitslo 16 +#define bitshi 80 +#define bitsh 32 +#define cols ((lenhi + 1 - lenlo + (lenh - 1)) / lenh) +#define rows ((bitshi + 1 - bitslo + (bitsh - 1)) / bitsh) +#define cpumin 10 +#define ncases 100 + +int +main(void) +{ + int i, j, len, bits; + double X[rows][cols]; + fmpz_poly_t f, g, q, r; + gmp_randstate_t state; + + gmp_randinit_default(state); + gmp_randseed_ui(state, UWORD(362436069)); + srand(UWORD(521288629)); + + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_poly_init(q); + fmpz_poly_init(r); + + fmpz_poly_fit_length(f, 2 * lenhi - 1); + fmpz_poly_fit_length(g, lenhi); + fmpz_poly_fit_length(q, lenhi); + fmpz_poly_fit_length(r, 2 * lenhi - 1); + + flint_printf("3 2 1"); + for (len = lenlo, j = 0; len <= lenhi; len += lenh, j++) + { + for (bits = bitslo, i = 0; bits <= bitshi; bits += bitsh, i++) + { + int c, n, reps = 0; + slong s = WORD(0); + + for (n = 0; n < ncases; n++) + { + clock_t c0, c1; + int l, loops = 1; + + /* + Construct random polynomials f and g + */ + { + fmpz_poly_gmprand(f, state, 2*len - 1, bits); + fmpz_poly_gmprand(g, state, len, bits); + } + + loop: + + c0 = clock(); + for (l = 0; l < loops; l++) + { + fmpz_poly_div_divconquer(q, f, g); + } + c1 = clock(); + + if (c1 - c0 <= cpumin) + { + loops *= 10; + goto loop; + } + + s += c1 - c0; + reps += loops; + } + + X[i][j] = (double) s / (double) reps; + flint_printf(" ."); + fflush(stdout); + } + } + flint_printf("\n"); + + fmpz_poly_clear(f); + fmpz_poly_clear(g); + fmpz_poly_clear(q); + fmpz_poly_clear(r); + + for (i = 0; i < rows; i++) + { + for (j = 0; j < cols; j++) + flint_printf("%8.3f", X[i][j]); + flint_printf("\n"); + } + + gmp_randclear(state); +} diff --git a/external/flint-2.4.3/fmpz_poly/profile/p-compose.c b/external/flint-2.4.3/fmpz_poly/profile/p-compose.c new file mode 100644 index 0000000..68674ac --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/profile/p-compose.c @@ -0,0 +1,167 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" +#include "profiler.h" + +/* + Definitions for the parameters of the timing process. + + len1lo Minimum length + len1hi Maximum length + len1h Step size for the length + len2lo Minimum length + len2hi Maximum length + len2h Step size for the length + bits Bit size of the coefficients + cols Number of different lengths + rows Number of different bit sizes + cpumin Minimum number of ms spent on each test case + ncases Number of test cases per point (length, bit size) + nalgs Number of algorithms + img Whether an RGB coloured image should be produced + imgname File name for image + */ + +#define len1lo 1 +#define len1hi 30 +#define len1h 1 +#define len2lo 1 +#define len2hi 30 +#define len2h 1 +#define bits 112 +#define cols ((len1hi + 1 - len1lo + (len1h - 1)) / len1h) +#define rows ((len2hi + 1 - len2lo + (len2h - 1)) / len2h) +#define cpumin 10 +#define ncases 1 +#define nalgs 2 + +int +main(void) +{ + int i, j, len1, len2; + int X[rows][cols]; + double T[rows][cols][nalgs]; + fmpz_poly_t f, g, h; + FLINT_TEST_INIT(state); + + + fmpz_poly_init2(f, len1hi); + fmpz_poly_init2(g, len2hi); + fmpz_poly_init2(h, (len1hi-1) * (len2hi-1) + 1); + + for (len1 = len1lo, j = 0; len1 <= len1hi; len1 += len1h, j++) + { + slong s[nalgs]; + + for (len2 = len2lo, i = 0; len2 <= len2hi; len2 += len2h, i++) + { + int c, n, reps = 0; + + for (c = 0; c < nalgs; c++) + s[c] = WORD(0); + + for (n = 0; n < ncases; n++) + { + timeit_t t[nalgs]; + int l, loops = 1; + + /* + Construct random polynomials f and g + */ + { + slong k; + for (k = 0; k < len1; k++) + fmpz_randbits(f->coeffs + k, state, bits); + if ((f->coeffs)[len1-1] == WORD(0)) + fmpz_randtest_not_zero(f->coeffs + (len1 - 1), state, bits); + f->length = len1; + } + { + slong k; + for (k = 0; k < len2; k++) + fmpz_randbits(g->coeffs + k, state, bits); + if ((g->coeffs)[len2-1] == WORD(0)) + fmpz_randtest_not_zero(g->coeffs + (len2 - 1), state, bits); + g->length = len2; + } + + loop: + + timeit_start(t[0]); + for (l = 0; l < loops; l++) + fmpz_poly_compose_horner(h, f, g); + timeit_stop(t[0]); + + timeit_start(t[1]); + for (l = 0; l < loops; l++) + fmpz_poly_compose_divconquer(h, f, g); + timeit_stop(t[1]); + + for (c = 0; c < nalgs; c++) + if (t[c]->cpu <= cpumin) + { + loops *= 10; + goto loop; + } + + for (c = 0; c < nalgs; c++) + s[c] += t[c]->cpu; + reps += loops; + } + + for (c = 0; c < nalgs; c++) + T[i][j][c] = s[c] / (double) reps; + + if (s[0] <= s[1]) + X[i][j] = 0; + else + X[i][j] = 1; + } + flint_printf("len1 = %d, time = %wdms\n", len1, s[0] + s[1]), fflush(stdout); + } + fmpz_poly_clear(f); + fmpz_poly_clear(g); + fmpz_poly_clear(h); + + /* + Print 2-D ASCII image of the winning algorithms + */ + for (i = 0; i < rows; i++) + { + for (j = 0; j < cols; j++) + flint_printf("%d", X[i][j]); + flint_printf("\n"); + } + + flint_randclear(state); +} diff --git a/external/flint-2.4.3/fmpz_poly/profile/p-mul.c b/external/flint-2.4.3/fmpz_poly/profile/p-mul.c new file mode 100644 index 0000000..41c4283 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/profile/p-mul.c @@ -0,0 +1,235 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" +#include "profiler.h" + +/* + Definitions for the parameters of the timing process. + + lenlo Minimum length + lenhi Maximum length + lenh Step size for the length + bitslo Minimum bit size + bitshi Maximum bit size + bitsh Step size for the bit size + cols Number of different lengths + rows Number of different bit sizes + cpumin Minimum number of ms spent on each test case + ncases Number of test cases per point (length, bit size) + nalgs Number of algorithms + img Whether an RGB coloured image should be produced + imgname File name for image + */ + +#define lenlo 1 +#define lenhi 60 +#define lenh 1 +#define bitslo 16 +#define bitshi 2048 +#define bitsh 32 +#define cols ((lenhi + 1 - lenlo + (lenh - 1)) / lenh) +#define rows ((bitshi + 1 - bitslo + (bitsh - 1)) / bitsh) +#define cpumin 10 +#define ncases 1 +#define nalgs 3 +#define img 1 +#define imgname "out.ppm" + +/* + Write a binary 24-bit ppm image. + */ +int write_rgb_ppm(const char* file_name, unsigned char* pixels, + unsigned int width, unsigned int height) +{ + FILE* file = fopen(file_name, "wb"); + if (file == NULL) + return -1; + flint_fprintf(file, "P6\n%d %d\n255\n", width, height); + fwrite(pixels, sizeof(unsigned char), width * height * 3, file); + fclose(file); + return 0; +} + +int +main(void) +{ + int i, j, len, bits; + int X[rows][cols]; + double T[rows][cols][nalgs]; + fmpz_poly_t f, g, h; + + FLINT_TEST_INIT(state); + + + fmpz_poly_init2(f, lenhi); + fmpz_poly_init2(g, lenhi); + fmpz_poly_init2(h, 2*lenhi - 1); + + for (len = lenlo, j = 0; len <= lenhi; len += lenh, j++) + { + slong s[nalgs]; + + for (bits = bitslo, i = 0; bits <= bitshi; bits += bitsh, i++) + { + int c, n, reps = 0; + + for (c = 0; c < nalgs; c++) + s[c] = WORD(0); + + for (n = 0; n < ncases; n++) + { + timeit_t t[nalgs]; + int l, loops = 1; + + /* + Construct random polynomials f and g + */ + { + slong k; + for (k = 0; k < len; k++) + { + fmpz_randbits(f->coeffs + k, state, bits); + fmpz_randbits(g->coeffs + k, state, bits); + } + if ((f->coeffs)[len-1] == WORD(0)) + fmpz_randtest_not_zero(f->coeffs + (len - 1), state, bits); + if ((g->coeffs)[len-1] == WORD(0)) + fmpz_randtest_not_zero(g->coeffs + (len - 1), state, bits); + f->length = len; + g->length = len; + } + + loop: + + timeit_start(t[0]); + for (l = 0; l < loops; l++) + fmpz_poly_mul_classical(h, f, g); + timeit_stop(t[0]); + + timeit_start(t[1]); + for (l = 0; l < loops; l++) + fmpz_poly_mul_karatsuba(h, f, g); + timeit_stop(t[1]); + + timeit_start(t[2]); + for (l = 0; l < loops; l++) + fmpz_poly_mul_KS(h, f, g); + timeit_stop(t[2]); + + for (c = 0; c < nalgs; c++) + if (t[c]->cpu <= cpumin) + { + loops *= 10; + goto loop; + } + + for (c = 0; c < nalgs; c++) + s[c] += t[c]->cpu; + reps += loops; + } + + for (c = 0; c < nalgs; c++) + T[i][j][c] = s[c] / (double) reps; + + if (s[0] <= s[1] && s[0] <= s[2]) + X[i][j] = 0; + else if (s[1] <= s[2]) + X[i][j] = 1; + else + X[i][j] = 2; + } + { + slong sum = 0, c; + for (c = 0; c < nalgs; c++) + sum += s[c]; + flint_printf("len = %d, time = %wdms\n", len, sum), fflush(stdout); + } + } + fmpz_poly_clear(f); + fmpz_poly_clear(g); + fmpz_poly_clear(h); + + /* + Print 2-D ASCII image of the winning algorithms + */ + for (i = 0; i < rows; i++) + { + for (j = 0; j < cols; j++) + flint_printf("%d", X[i][j]); + flint_printf("\n"); + } + + /* + Print 2-D coloured image to file + */ + if (img) + { + unsigned char * PIXELS; + int k; + + PIXELS = (unsigned char *) flint_malloc(3 * rows * cols * sizeof(unsigned char)); + k = 0; + for (i = 0; i < rows; i++) + { + for (j = 0; j < cols; j++) + { + double max = DBL_MIN, v[nalgs]; + int m; + + for (m = 0; m < nalgs; m++) + { + v[m] = T[i][j][m] - T[i][j][X[i][j]]; + if (v[m] > max) + max = v[m]; + } + for (m = 0; m < nalgs; m++) + { + v[m] = (max - v[m]) / max; + PIXELS[k++] = (unsigned char) (v[m] * 255); + } + for (; m < 3; m++) + PIXELS[k++] = (unsigned char) 0; + } + } + + k = write_rgb_ppm(imgname, PIXELS, cols, rows); + flint_free(PIXELS); + + if (k) + { + flint_printf("Exception: writing ppm image failed\n"); + } + } + + flint_randclear(state); +} diff --git a/external/flint-2.4.3/fmpz_poly/profile/p-mul_triangle.c b/external/flint-2.4.3/fmpz_poly/profile/p-mul_triangle.c new file mode 100644 index 0000000..9ca4ac1 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/profile/p-mul_triangle.c @@ -0,0 +1,261 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 William Hart + +******************************************************************************/ + +#include +#include +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" +#include "profiler.h" + +/* + Definitions for the parameters of the timing process. + + lenlo Minimum length + lenhi Maximum length + lenh Factor by which length increases at each step + bitslo Minimum bit size + bitshi Maximum bit size + bitsh Factor by which bitsize increases at each step + cutoff Maximum product of length*bits + cols Number of different lengths + rows Number of different bit sizes + cpumin Minimum number of ms spent on each test case + ncases Number of test cases per point (length, bit size) + nalgs Number of algorithms + img Whether an RGB coloured image should be produced + imgname File name for image + */ + +#define lenlo 16 +#define lenhi 131072 +#define lenh 2 +#define bitslo 256 +#define bitshi 67108864 +#define bitsh 2 +#define cutoff WORD(22000000000) +#define cols ((slong)(log((double)lenhi/(double)lenlo)/log(lenh) + 1.5)) +#define rows ((slong)(log((double)bitshi/(double)bitslo)/log(bitsh) + 1.5)) +#define cpumin 100 +#define ncases 1 +#define nalgs 2 +#define img 1 +#define imgname "out.ppm" + +/* + Write a binary 24-bit ppm image. + */ +int write_rgb_ppm(const char* file_name, unsigned char* pixels, + unsigned int width, unsigned int height) +{ + FILE* file = fopen(file_name, "wb"); + if (file == NULL) + return -1; + flint_fprintf(file, "P6\n%d %d\n255\n", width, height); + fwrite(pixels, sizeof(unsigned char), width * height * 3, file); + fclose(file); + return 0; +} + +int +main(void) +{ + slong i, j, k, len, bits; + int X[rows][cols]; + double T[rows][cols][nalgs]; + fmpz_poly_t f, g, h; + + FLINT_TEST_INIT(state); + + + fmpz_poly_init2(f, lenhi); + fmpz_poly_init2(g, lenhi); + fmpz_poly_init2(h, 2*lenhi - 1); + + for (len = lenlo, j = 0; len <= lenhi; len *= lenh, j++) + { + slong s[nalgs], sum; + + for (bits = bitslo, i = 0; bits <= bitshi; bits *= bitsh, i++) + { + int c, n, reps = 0, none = 0; + + for (c = 0; c < nalgs; c++) + s[c] = WORD(0); + + for (n = 0; n < ncases; n++) + { + timeit_t t[nalgs]; + int l, loops = 1; + + if (bits*len <= cutoff) + { /* + Construct random polynomials f and g + */ + { + slong k; + for (k = 0; k < len; k++) + { + fmpz_randbits(f->coeffs + k, state, bits); + fmpz_randbits(g->coeffs + k, state, bits); + } + if ((f->coeffs)[len-1] == WORD(0)) + fmpz_randtest_not_zero(f->coeffs + (len - 1), state, bits); + if ((g->coeffs)[len-1] == WORD(0)) + fmpz_randtest_not_zero(g->coeffs + (len - 1), state, bits); + f->length = len; + g->length = len; + } + + loop: + + timeit_start(t[0]); + for (l = 0; l < loops; l++) + fmpz_poly_mul_KS(h, f, g); + timeit_stop(t[0]); + + timeit_start(t[1]); + for (l = 0; l < loops; l++) + fmpz_poly_mul_SS(h, f, g); + timeit_stop(t[1]); + + for (c = 0; c < nalgs; c++) + if (t[c]->cpu <= cpumin) + { + loops *= 2; + goto loop; + } + + for (c = 0; c < nalgs; c++) + s[c] += t[c]->cpu; + reps += loops; + } else + none = 1; + } + + for (c = 0; c < nalgs; c++) + T[i][j][c] = s[c] / (double) reps; + + if (none) + X[i][j] = -1; + else if (s[0] <= s[1] && s[0] <= s[2]) + X[i][j] = 0; + else if (s[1] <= s[2]) + X[i][j] = 1; + else + X[i][j] = 2; + + if (s[0] != 0) + { + sum = 0; + for (c = 0; c < nalgs; c++) + sum += s[c]; + } + } + flint_printf("len = %wd, time = %wdms\n", len, sum), fflush(stdout); + for (k = 0; k < rows; k++) + { + if (X[k][j] == -1) + flint_printf(" "); + else + flint_printf("%d", X[k][j]); + } + flint_printf("\n"); + } + fmpz_poly_clear(f); + fmpz_poly_clear(g); + fmpz_poly_clear(h); + + /* + Print 2-D ASCII image of the winning algorithms + */ + for (i = 0; i < rows; i++) + { + for (j = 0; j < cols; j++) + { + if (X[i][j] == -1) + flint_printf(" "); + else + flint_printf("%d", X[i][j]); + } + flint_printf("\n"); + } + + /* + Print 2-D coloured image to file + */ + if (img) + { + unsigned char * PIXELS; + int k; + + PIXELS = (unsigned char *) flint_malloc(3 * rows * cols * sizeof(unsigned char)); + k = 0; + for (i = 0; i < rows; i++) + { + for (j = 0; j < cols; j++) + { + double max = DBL_MIN, v[nalgs]; + int m; + + if (X[i][j] == -1) + { + for (m = 0; m < 3; m++) + PIXELS[k++] = (unsigned char) 0; + } else + { + for (m = 0; m < nalgs; m++) + { + v[m] = T[i][j][m] - T[i][j][X[i][j]]; + if (v[m] > max) + max = v[m]; + } + for (m = 0; m < nalgs; m++) + { + v[m] = (max - v[m]) / max; + PIXELS[k++] = (unsigned char) (v[m] * 255); + } + for (; m < 3; m++) + PIXELS[k++] = (unsigned char) 0; + } + } + } + + k = write_rgb_ppm(imgname, PIXELS, cols, rows); + flint_free(PIXELS); + + if (k) + { + flint_printf("Exception: writing ppm image failed\n"); + } + } + + flint_randclear(state); +} diff --git a/external/flint-2.4.3/fmpz_poly/profile/p-pow.c b/external/flint-2.4.3/fmpz_poly/profile/p-pow.c new file mode 100644 index 0000000..cf77816 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/profile/p-pow.c @@ -0,0 +1,138 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" +#include "profiler.h" + +#define lenlo 1 +#define lenhi 100 +#define lenh 5 +#define bitslo 16 +#define bitshi 512 +#define bitsh 32 +#define explo 2 +#define exphi 140 +#define exph 5 +#define cols ((lenhi + 1 - lenlo + (lenh - 1)) / lenh) +#define rows ((bitshi + 1 - bitslo + (bitsh - 1)) / bitsh) +#define height ((exphi + 1 - explo + (exph - 1)) / exph) +#define cpumin 10 +#define img 1 + +int +main(void) +{ + int k, exp; + fmpz_poly_t f, g; + + FLINT_TEST_INIT(state); + + + fmpz_poly_init2(f, lenhi); + fmpz_poly_init2(g, exphi * (lenhi - 1) + 1); + + flint_printf("Comparative timing for fmpz_poly_pow\n"); + flint_printf("\n"); + flint_printf("Length: [%d..%d] with step size %d\n", lenlo, lenhi, lenh); + flint_printf("Bit size: [%d..%d] with step size %d\n", bitslo, bitshi, bitsh); + flint_printf("Exponents: [%d..%d] with step size %d\n", explo, exphi, exph); + flint_printf("\n"); + flint_printf("exp len bits (Binary exponentiation) Multinomials\n"); + flint_printf("\n"); + + for (exp = explo, k = 0; exp <= exphi; exp += exph, k++) + { + int i, j, len, bits; + + for (len = lenlo, j = 0; len <= lenhi; len += lenh, j++) + { + for (bits = bitslo, i = 0; bits <= bitshi; bits += bitsh, i++) + { + + timeit_t t[2]; + int l, loops = 1, r = 0; + slong s[2] = {WORD(0), WORD(0)}; + double T[2]; + + /* + Construct random polynomial f of length len + */ + { + slong ell; + for (ell = 0; ell < len; ell++) + fmpz_randbits(f->coeffs + ell, state, bits); + if ((f->coeffs)[len - 1] == WORD(0)) + fmpz_randtest_not_zero(f->coeffs + (len - 1), state, bits); + f->length = len; + } + + /* + Run tests + */ + + loop: + + timeit_start(t[0]); + for (l = 0; l < loops; l++) + fmpz_poly_pow_binexp(g, f, exp); + timeit_stop(t[0]); + + timeit_start(t[1]); + for (l = 0; l < loops; l++) + fmpz_poly_pow_multinomial(g, f, exp); + timeit_stop(t[1]); + + if (t[0]->cpu <= cpumin || t[1]->cpu <= cpumin) + { + loops *= 10; + goto loop; + } + + s[0] += t[0]->cpu; + s[1] += t[1]->cpu; + r += loops; + + T[0] = s[0] / (double) r; + T[1] = s[1] / (double) r; + + flint_printf("%d %d %d %f %f\n", exp, len, bits, T[0], T[1]); + fflush(stdout); + } + } + } + + fmpz_poly_clear(f); + fmpz_poly_clear(g); + + flint_randclear(state); +} diff --git a/external/flint-2.4.3/fmpz_poly/profile/p-pow_binomial.c b/external/flint-2.4.3/fmpz_poly/profile/p-pow_binomial.c new file mode 100644 index 0000000..1440726 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/profile/p-pow_binomial.c @@ -0,0 +1,103 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" +#include "profiler.h" + +#define lenlo 2 +#define lenhi 2 +#define lenh 1 +#define bits 16 +#define elo 26 +#define ehi 50 +#define eh 1 +#define cpumin 100 + +int +main(void) +{ + int len, e; + fmpz_poly_t f, g[1]; + + FLINT_TEST_INIT(state); + + + fmpz_poly_init2(f, lenhi); + fmpz_poly_init2(g[0], ehi * (lenhi - 1) + 1); + fmpz_poly_init2(g[1], ehi * (lenhi - 1) + 1); + + flint_printf("| len | exp | binomial |\n"); + + for (len = lenlo; len <= lenhi; len += lenh) + { + /* + Construct random polynomial f of length len + */ + { + slong k; + for (k = 0; k < len; k++) + fmpz_randbits(f->coeffs + k, state, bits); + if ((f->coeffs)[len-1] == WORD(0)) + fmpz_randtest_not_zero(f->coeffs + (len-1), state, bits); + f->length = len; + } + + for (e = elo; e <= ehi; e += eh) + { + timeit_t t[1]; + int l, loops = 1, r = 0; + slong s[1] = {0}; + + loop: + + timeit_start(t[0]); + for (l = 0; l < loops; l++) + fmpz_poly_pow_binomial(g[0], f, e); + timeit_stop(t[0]); + + if (t[0]->cpu <= cpumin) + { + loops *= 10; + goto loop; + } + + s[0] += t[0]->cpu; + r += loops; + + flint_printf("%d %d %lf\n", len, e, s[0] / (double) r); + } + } + + fmpz_poly_clear(f); + fmpz_poly_clear(g[0]); + + flint_randclear(state); +} diff --git a/external/flint-2.4.3/fmpz_poly/profile/p-rem_powers_precomp.c b/external/flint-2.4.3/fmpz_poly/profile/p-rem_powers_precomp.c new file mode 100644 index 0000000..a1ceb8d --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/profile/p-rem_powers_precomp.c @@ -0,0 +1,158 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "profiler.h" +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +#define BITS 100 + +typedef struct +{ + int algo; + slong length; +} info_t; + +void random_fmpz_poly(fmpz_poly_t pol, flint_rand_t state, slong length) +{ + fmpz * arr; + slong i; + + fmpz_poly_fit_length(pol, length); + + arr = pol->coeffs; + + for (i = 0; i < length; i++) + fmpz_randbits(arr + i, state, BITS); + + _fmpz_poly_set_length(pol, length); + _fmpz_poly_normalise(pol); +} + +void sample(void * arg, ulong count) +{ + info_t * info = (info_t *) arg; + slong length = info->length, i, j; + int algo = info->algo; + int scale; + + scale = 100; + if (length >= 50) scale = 10; + if (length >= 500) scale = 4; + + FLINT_TEST_INIT(state); + + + fmpz_poly_t p1, p2, b, q, r; + fmpz_poly_powers_precomp_t pinv; + + fmpz_poly_init(p1); + fmpz_poly_init(p2); + fmpz_poly_init(b); + fmpz_poly_init(q); + fmpz_poly_init(r); + + for (i = 0; i < count; i++) + { + random_fmpz_poly(p1, state, 2*length - 1); + random_fmpz_poly(p2, state, length); + fmpz_set_ui(p2->coeffs + p2->length - 1, 1); /* p2 must be monic */ + + fmpz_poly_powers_precompute(pinv, p2); + + if (algo) + { + prof_start(); + for (j = 0; j < scale; j++) + { + fmpz_poly_rem_powers_precomp(r, p1, p2, pinv); + } + prof_stop(); + } else + { + prof_start(); + for (j = 0; j < scale; j++) + { + fmpz_poly_rem(r, p1, p2); + } + prof_stop(); + } + + fmpz_poly_powers_clear(pinv); + } + + fmpz_poly_clear(p1); + fmpz_poly_clear(p2); + fmpz_poly_clear(b); + fmpz_poly_clear(q); + fmpz_poly_clear(r); + + flint_randclear(state); +} + +int main(void) +{ + double min, max; + info_t info; + slong k, scale; + + printf("fmpz_poly_rem with precomputed powers\n"); + flint_printf("bits = %wd\n", BITS); + + for (k = 1; k <= 1000; k = (slong) ceil(1.1*k)) + { + info.length = k; + info.algo = 0; + + scale = 100; + if (k >= 50) scale = 10; + if (k >= 500) scale = 4; + + prof_repeat(&min, &max, sample, (void *) &info); + + flint_printf("Standard: length %wd, min %.3g ms, max %.3g ms\n", + info.length, + ((min/(double)FLINT_CLOCK_SCALE_FACTOR)/scale)/2400000.0, + ((max/(double)FLINT_CLOCK_SCALE_FACTOR)/scale)/2400000.0 + ); + + info.algo = 1; + + prof_repeat(&min, &max, sample, (void *) &info); + + flint_printf("With powers: length %wd, min %.3g ms, max %.3g ms\n\n", + info.length, + ((min/(double)FLINT_CLOCK_SCALE_FACTOR)/scale)/2400000.0, + ((max/(double)FLINT_CLOCK_SCALE_FACTOR)/scale)/2400000.0 + ); + } + + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/pseudo_div.c b/external/flint-2.4.3/fmpz_poly/pseudo_div.c new file mode 100644 index 0000000..c7930dd --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/pseudo_div.c @@ -0,0 +1,80 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void _fmpz_poly_pseudo_div(fmpz * Q, ulong * d, const fmpz * A, slong lenA, + const fmpz * B, slong lenB, const fmpz_preinvn_t inv) +{ + fmpz * R = _fmpz_vec_init(lenA); + _fmpz_poly_pseudo_divrem(Q, R, d, A, lenA, B, lenB, inv); + _fmpz_vec_clear(R, lenA); +} + +void fmpz_poly_pseudo_div(fmpz_poly_t Q, ulong * d, const fmpz_poly_t A, + const fmpz_poly_t B) +{ + slong lenq; + fmpz * q; + + if (B->length == 0) + { + flint_printf("Exception (fmpz_poly_pseudo_div). Division by zero.\n"); + abort(); + } + if (A->length < B->length) + { + fmpz_poly_zero(Q); + *d = 0; + return; + } + + lenq = A->length - B->length + 1; + if (Q == A || Q == B) + q = _fmpz_vec_init(lenq); + else + { + fmpz_poly_fit_length(Q, lenq); + q = Q->coeffs; + } + + _fmpz_poly_pseudo_div(q, d, A->coeffs, A->length, + B->coeffs, B->length, NULL); + + if (Q == A || Q == B) + { + _fmpz_vec_clear(Q->coeffs, Q->alloc); + Q->coeffs = q; + Q->alloc = lenq; + Q->length = lenq; + } + else + _fmpz_poly_set_length(Q, lenq); +} diff --git a/external/flint-2.4.3/fmpz_poly/pseudo_divrem_basecase.c b/external/flint-2.4.3/fmpz_poly/pseudo_divrem_basecase.c new file mode 100644 index 0000000..7a91810 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/pseudo_divrem_basecase.c @@ -0,0 +1,145 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void +_fmpz_poly_pseudo_divrem_basecase(fmpz * Q, fmpz * R, ulong * d, + const fmpz * A, slong lenA, const fmpz * B, + slong lenB, const fmpz_preinvn_t inv) +{ + const fmpz * leadB = B + (lenB - 1); + slong iQ = lenA - lenB, iR = lenA - 1; + fmpz_t rem; + + fmpz_init(rem); + + *d = 0; + _fmpz_vec_zero(Q, lenA - lenB + 1); + if (R != A) + _fmpz_vec_set(R, A, lenA); + + while (iR >= lenB - 1) + { + if (inv) + fmpz_fdiv_qr_preinvn(Q + iQ, rem, R + iR, leadB, inv); + else + fmpz_fdiv_qr(Q + iQ, rem, R + iR, leadB); + + if (!fmpz_is_zero(rem)) + { + _fmpz_vec_scalar_mul_fmpz(Q, Q, lenA - lenB + 1, leadB); + fmpz_set(Q + iQ, R + iR); + _fmpz_vec_scalar_mul_fmpz(R, R, lenA, leadB); + (*d)++; + } + + if (lenB > 1) + _fmpz_vec_scalar_submul_fmpz(R + (iR - lenB + 1), B, lenB - 1, Q + iQ); + + fmpz_zero(R + iR); + + iR--; + iQ--; + } + + fmpz_clear(rem); +} + +void +fmpz_poly_pseudo_divrem_basecase(fmpz_poly_t Q, fmpz_poly_t R, + ulong * d, const fmpz_poly_t A, + const fmpz_poly_t B) +{ + slong lenq, lenr; + fmpz *q, *r; + + if (B->length == 0) + { + flint_printf("Exception (fmpz_poly_pseudo_divrem_basecase). Division by zero.\n"); + abort(); + } + if (Q == R) + { + flint_printf("Exception (fmpz_poly_pseudo_divrem_basecase). \n" + "Output arguments Q and R may not be aliased.\n"); + abort(); + } + if (A->length < B->length) + { + fmpz_poly_zero(Q); + fmpz_poly_set(R, A); + *d = 0; + return; + } + + lenq = A->length - B->length + 1; + lenr = A->length; + if (Q == A || Q == B) + q = _fmpz_vec_init(lenq); + else + { + fmpz_poly_fit_length(Q, lenq); + q = Q->coeffs; + } + if (R == B) + r = _fmpz_vec_init(lenr); + else + { + fmpz_poly_fit_length(R, lenr); + r = R->coeffs; + } + + _fmpz_poly_pseudo_divrem_basecase(q, r, d, A->coeffs, A->length, + B->coeffs, B->length, NULL); + + for (lenr = B->length - 2; (lenr >= 0) && !r[lenr]; lenr--) ; + lenr++; + + if (Q == A || Q == B) + { + _fmpz_vec_clear(Q->coeffs, Q->alloc); + Q->coeffs = q; + Q->alloc = lenq; + Q->length = lenq; + } + else + _fmpz_poly_set_length(Q, lenq); + if (R == B) + { + _fmpz_vec_clear(R->coeffs, R->alloc); + R->coeffs = r; + R->alloc = A->length; + R->length = lenr; + } + else + _fmpz_poly_set_length(R, lenr); +} diff --git a/external/flint-2.4.3/fmpz_poly/pseudo_divrem_cohen.c b/external/flint-2.4.3/fmpz_poly/pseudo_divrem_cohen.c new file mode 100644 index 0000000..9a263f6 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/pseudo_divrem_cohen.c @@ -0,0 +1,156 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void +_fmpz_poly_pseudo_divrem_cohen(fmpz * Q, fmpz * R, const fmpz * A, + slong lenA, const fmpz * B, slong lenB) +{ + const fmpz * leadB = B + (lenB - 1); + slong e, lenQ; + fmpz_t pow; + + if (lenB == 1) + { + fmpz_init(pow); + fmpz_pow_ui(pow, leadB, lenA - 1); + _fmpz_vec_scalar_mul_fmpz(Q, A, lenA, pow); + _fmpz_vec_zero(R, lenA); + fmpz_clear(pow); + return; + } + + lenQ = lenA - lenB + 1; + _fmpz_vec_zero(Q, lenQ); + if (R != A) + _fmpz_vec_set(R, A, lenA); + e = lenA - lenB; + + /* Unroll the first run of the while loop */ + { + fmpz_set(Q + (lenQ - 1), R + (lenA - 1)); + + _fmpz_vec_scalar_mul_fmpz(R, R, lenA - 1, leadB); + _fmpz_vec_scalar_submul_fmpz(R + (lenA - lenB), B, lenB - 1, R + (lenA - 1)); + fmpz_zero(R + (lenA - 1)); + + lenA--; + FMPZ_VEC_NORM(R, lenA); + } + while (lenA >= lenB) + { + _fmpz_vec_scalar_mul_fmpz(Q, Q, lenQ, leadB); + fmpz_add(Q + (lenA - lenB), Q + (lenA - lenB), R + (lenA - 1)); + + _fmpz_vec_scalar_mul_fmpz(R, R, lenA - 1, leadB); + _fmpz_vec_scalar_submul_fmpz(R + lenA - lenB, B, lenB - 1, R + (lenA - 1)); + fmpz_zero(R + (lenA - 1)); + + lenA--; + FMPZ_VEC_NORM(R, lenA); + + e--; + } + + fmpz_init(pow); + fmpz_pow_ui(pow, leadB, e); + _fmpz_vec_scalar_mul_fmpz(Q, Q, lenQ, pow); + _fmpz_vec_scalar_mul_fmpz(R, R, lenA, pow); + fmpz_clear(pow); +} + +void +fmpz_poly_pseudo_divrem_cohen(fmpz_poly_t Q, fmpz_poly_t R, + const fmpz_poly_t A, const fmpz_poly_t B) +{ + slong lenq, lenr; + fmpz *q, *r; + + if (B->length == 0) + { + flint_printf("Exception (fmpz_poly_pseudo_divrem_cohen). Division by zero.\n"); + abort(); + } + if (Q == R) + { + flint_printf("Exception (fmpz_poly_pseudo_divrem_cohen). \n" + "Output arguments Q and R may not be aliased.\n"); + abort(); + } + if (A->length < B->length) + { + fmpz_poly_zero(Q); + fmpz_poly_set(R, A); + return; + } + + lenq = A->length - B->length + 1; + lenr = A->length; + if ((Q == A) || (Q == B)) + q = _fmpz_vec_init(lenq); + else + { + fmpz_poly_fit_length(Q, lenq); + q = Q->coeffs; + } + if (R == B) + r = _fmpz_vec_init(lenr); + else + { + fmpz_poly_fit_length(R, lenr); + r = R->coeffs; + } + + _fmpz_poly_pseudo_divrem_cohen(q, r, A->coeffs, A->length, B->coeffs, B->length); + + for (lenr = B->length - 1; (lenr >= 0) && r[lenr] == WORD(0); lenr--) ; + lenr++; + + if ((Q == A) || (Q == B)) + { + _fmpz_vec_clear(Q->coeffs, Q->alloc); + Q->coeffs = q; + Q->alloc = lenq; + Q->length = lenq; + } + else + _fmpz_poly_set_length(Q, lenq); + if (R == B) + { + _fmpz_vec_clear(R->coeffs, R->alloc); + R->coeffs = r; + R->alloc = A->length; + R->length = lenr; + } + else + _fmpz_poly_set_length(R, lenr); +} + diff --git a/external/flint-2.4.3/fmpz_poly/pseudo_divrem_divconquer.c b/external/flint-2.4.3/fmpz_poly/pseudo_divrem_divconquer.c new file mode 100644 index 0000000..8b4b6e9 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/pseudo_divrem_divconquer.c @@ -0,0 +1,363 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 + +******************************************************************************/ + +#include +#include "fmpz_poly.h" + +static void +__fmpz_poly_pseudo_divrem_divconquer(fmpz * Q, fmpz * R, + ulong * d, const fmpz * A, slong lenA, + const fmpz * B, slong lenB, const fmpz_preinvn_t inv) +{ + if (lenB <= 16 || (lenA > 2 * lenB - 1 && lenA < 128)) + { + _fmpz_poly_pseudo_divrem_basecase(Q, R, d, A, lenA, B, lenB, inv); + } + else + { + const slong n2 = lenB / 2; + const slong n1 = lenB - n2; + + const fmpz * d1 = B + n2; + const fmpz * d2 = B; + const fmpz * d3 = B + n1; + const fmpz * d4 = B; + + if (lenA <= lenB + n2 - 1) + { + fmpz *p1, *r1, *d2q1; + fmpz *f; + + /* + Shift A right by n1, zero the bottom n2 - 1 coeffs; call this p1 + */ + + p1 = (fmpz *) flint_malloc((lenA - n1) * sizeof(fmpz)); + { + slong i; + flint_mpn_zero((mp_ptr) p1, n2 - 1); + for (i = n2 - 1; i < lenA - n1; i++) + p1[i] = (A + n1)[i]; + } + + /* + Compute p1 div d3, at most a 2 n2 - 1 by n2 division, leaving + lenA - lenB + 1 <= n2 terms in the quotient + */ + + r1 = R + n1; + _fmpz_poly_pseudo_divrem_divconquer(Q, r1, d, p1, lenA - n1, d3, n2, inv); + + flint_free(p1); + + /* + Push the relevant {n2 - 1} terms of the remainder to the + top of {R, lenA} + */ + + { + slong i; + for (i = n2 - 2; i >= 0; i--) + fmpz_swap(R + lenA - (n2 - 1) + i, r1 + i); + r1 = R + lenA - (n2 - 1); + } + + /* + Compute d2q1 = Q d4 of length lenA - n2, which is + at most n1 + n2 - 1 terms + */ + + d2q1 = R; + _fmpz_poly_mul(d2q1, d4, n1, Q, lenA - lenB + 1); + + /* + Compute R = L^d R', where R' is the terms of A we have not dealt, + of which there are at most n1 + n2 - 1; that is, + + Set R to {A, n1 + n2 - 1} * f + r1 x^n1 - d2q1 + */ + + _fmpz_vec_neg(R, R, lenA - n2); + _fmpz_vec_add(R + n1, R + n1, R + lenA - n2 + 1, lenA - lenB); + _fmpz_vec_swap(R + lenA - n2, R + 2 * lenA - lenB + 1 - n2, n2 - (lenA - lenB + 1)); + + f = R + lenB - 1; + fmpz_pow_ui(f, B + (lenB - 1), *d); + _fmpz_vec_scalar_addmul_fmpz(R, A, n1 + n2 - 1, f); + } + else if (lenA > 2 * lenB - 1) + { + /* + XXX: In this case, we expect A to be modifiable + */ + + ulong s1, s2; + const slong shift = lenA - 2 * lenB + 1; + + fmpz * q1 = Q + shift; + fmpz * q2 = Q; + fmpz * r1 = R; + + fmpz *p1, *t; + fmpz_t f; + + fmpz_init(f); + + /* + Shift A right until it is of length 2 lenB - 1, call this p1; + zero the bottom lenB - 1 coeffs + */ + + p1 = (fmpz *) flint_malloc((2 * lenB - 1) * sizeof(fmpz)); + { + slong i; + flint_mpn_zero((mp_ptr) p1, lenB - 1); + for (i = lenB - 1; i < 2*lenB - 1; i++) + p1[i] = (A + shift)[i]; + } + + /* + Set q1 to p1 div B, a 2 lenB - 1 by lenB division, so q1 ends up + being at most length lenB; r1 is of length at most lenB - 1 + */ + + _fmpz_poly_pseudo_divrem_divconquer(q1, r1, &s1, p1, 2 * lenB - 1, B, lenB, inv); + + flint_free(p1); + + /* + Compute t = L^s1 a2 + r1 x^shift, of length at most lenA - lenB + since r1 is of length at most lenB - 1. Here a2 is what remains + of A after the first lenR coefficients are removed + */ + + t = (fmpz *) A; + + fmpz_pow_ui(f, B + (lenB - 1), s1); + + _fmpz_vec_scalar_mul_fmpz(t, A, lenA - lenB, f); + _fmpz_vec_add(t + shift, t + shift, r1, lenB - 1); + + /* + Compute q2 = t div B; it is a smaller division than the original + since len(t) <= lenA - lenB, and r2 has length at most lenB - 1 + */ + + _fmpz_poly_pseudo_divrem_divconquer(q2, R, &s2, t, lenA - lenB, B, lenB, inv); + + /* + Write out Q = L^s2 q1 x^shift + q2, of length at most + lenB + shift. Note q2 has length at most shift since it is at + most an lenA - lenB by lenB division; q1 cannot have length zero + since we are doing pseudo division + */ + + fmpz_pow_ui(f, B + (lenB - 1), s2); + + _fmpz_vec_scalar_mul_fmpz(q1, q1, lenB, f); + + *d = s1 + s2; + + fmpz_clear(f); + } + else /* n1 + 2 n2 - 1 < lenA <= 2 lenB - 1 */ + { + fmpz * q1 = Q + n2; + fmpz * q2 = Q; + fmpz * r1 = R; + fmpz * d2q1 = R + (n1 - 1); + fmpz *p1, *t; + fmpz_t f; + ulong s1, s2; + + fmpz_init(f); + + /* + Set p1 to the top lenA - 2 n2 coeffs of A, clearing the bottom + n1 - 1 coeffs + */ + + p1 = (fmpz *) flint_malloc((lenA - 2 * n2) * sizeof(fmpz)); + { + slong i; + flint_mpn_zero((mp_ptr) p1, n1 - 1); + for (i = n1 - 1; i < lenA - 2 * n2; i++) + p1[i] = (A + 2 * n2)[i]; + } + + /* + Set q1 to p1 div d1, at most a 2 n1 - 1 by n1 division, so q1 ends + up being of length at most n1; r1 is of length n1 - 1 + */ + + _fmpz_poly_pseudo_divrem_divconquer(q1, r1, &s1, p1, lenA - 2 * n2, d1, n1, inv); + + flint_free(p1); + + /* + Compute d2q1 = d2q1, of length lenA - lenB + + Note lenA - lenB <= lenB - 1 <= 2 n2 and lenA - (n1 - 1) > 2 n2, + so we can store d2q1 in the top 2 n2 coeffs of R + */ + + if (n2 >= lenA - n1 - 2 * n2 + 1) + _fmpz_poly_mul(d2q1, d2, n2, q1, lenA - (n1 + 2 * n2 - 1)); + else + _fmpz_poly_mul(d2q1, q1, lenA - (n1 + 2 * n2 - 1), d2, n2); + + /* + Compute + t = L^s1 * (a2 x^{n1 + n2 - 1} + a3) + + r1 x^{2 n2} - d2q1 x^n2 + of length at most lenB + n2 - 1, since r1 is of length at most + n1 - 1 and d2q1 is of length at most n1 + n2 - 1 + */ + + t = _fmpz_vec_init(n1 + 2 * n2 - 1); + + fmpz_pow_ui(f, B + (lenB - 1), s1); + + _fmpz_vec_scalar_mul_fmpz(t, A, n1 + 2 * n2 - 1, f); + _fmpz_vec_add(t + 2 * n2, t + 2 * n2, r1, n1 - 1); + _fmpz_vec_sub(t + n2, t + n2, d2q1, lenA - lenB); + + /* + Compute q2 = t div B and set R to the remainder, at most a + lenB + n2 - 1 by lenB division, so q2 is of length at most n2 + */ + + _fmpz_poly_pseudo_divrem_divconquer(q2, R, &s2, t, lenB + n2 - 1, B, lenB, inv); + + _fmpz_vec_clear(t, n1 + 2 * n2 - 1); + + /* + Write Q = L^s2 q1 x^n2 + q2; note len(q1) is non-zero since + we are performing pseudo division + */ + + fmpz_pow_ui(f, B + (lenB - 1), s2); + + _fmpz_vec_scalar_mul_fmpz(q1, q1, lenA - lenB + 1 - n2, f); + + *d = s1 + s2; + + fmpz_clear(f); + } + } +} + +void +_fmpz_poly_pseudo_divrem_divconquer(fmpz * Q, fmpz * R, + ulong * d, const fmpz * A, slong lenA, + const fmpz * B, slong lenB, const fmpz_preinvn_t inv) +{ + if (lenA <= 2 * lenB - 1) + { + __fmpz_poly_pseudo_divrem_divconquer(Q, R, d, A, lenA, B, lenB, inv); + } + else /* lenA > 2 * lenB - 1 */ + { + fmpz *S = _fmpz_vec_init(lenA); + + _fmpz_vec_set(S, A, lenA); + + __fmpz_poly_pseudo_divrem_divconquer(Q, R, d, S, lenA, B, lenB, inv); + + _fmpz_vec_clear(S, lenA); + } +} + +void +fmpz_poly_pseudo_divrem_divconquer(fmpz_poly_t Q, fmpz_poly_t R, + ulong * d, const fmpz_poly_t A, + const fmpz_poly_t B) +{ + slong lenq, lenr; + fmpz *q, *r; + + if (B->length == 0) + { + flint_printf("Exception (fmpz_poly_pseudo_divrem_divconquer). Division by zero.\n"); + abort(); + } + if (Q == R) + { + flint_printf("Exception (fmpz_poly_pseudo_divrem_divconquer). \n" + "Output arguments Q and R may not be aliased.\n"); + abort(); + } + if (A->length < B->length) + { + fmpz_poly_zero(Q); + fmpz_poly_set(R, A); + *d = 0; + return; + } + + lenq = A->length - B->length + 1; + lenr = A->length; + if (Q == A || Q == B) + q = _fmpz_vec_init(lenq); + else + { + fmpz_poly_fit_length(Q, lenq); + q = Q->coeffs; + } + if (R == A || R == B) + r = _fmpz_vec_init(lenr); + else + { + fmpz_poly_fit_length(R, lenr); + r = R->coeffs; + } + + _fmpz_poly_pseudo_divrem_divconquer(q, r, d, A->coeffs, A->length, + B->coeffs, B->length, NULL); + + lenr = B->length - 1; + FMPZ_VEC_NORM(r, lenr); + + if (Q == A || Q == B) + { + _fmpz_vec_clear(Q->coeffs, Q->alloc); + Q->coeffs = q; + Q->alloc = lenq; + Q->length = lenq; + } + else + _fmpz_poly_set_length(Q, lenq); + if (R == A || R == B) + { + _fmpz_vec_clear(R->coeffs, R->alloc); + R->coeffs = r; + R->alloc = A->length; + R->length = lenr; + } + else + _fmpz_poly_set_length(R, lenr); +} + diff --git a/external/flint-2.4.3/fmpz_poly/pseudo_rem.c b/external/flint-2.4.3/fmpz_poly/pseudo_rem.c new file mode 100644 index 0000000..f7c223b --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/pseudo_rem.c @@ -0,0 +1,83 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void _fmpz_poly_pseudo_rem(fmpz * R, ulong * d, const fmpz * A, slong lenA, + const fmpz * B, slong lenB, const fmpz_preinvn_t inv) +{ + fmpz * Q = _fmpz_vec_init(lenA + lenB - 1); + _fmpz_poly_pseudo_divrem(Q, R, d, A, lenA, B, lenB, inv); + _fmpz_vec_clear(Q, lenA + lenB - 1); +} + +void fmpz_poly_pseudo_rem(fmpz_poly_t R, ulong * d, const fmpz_poly_t A, + const fmpz_poly_t B) +{ + slong lenr; + fmpz * r; + + if (B->length == 0) + { + flint_printf("Exception (fmpz_poly_pseudo_rem). Division by zero.\n"); + abort(); + } + if (A->length < B->length) + { + fmpz_poly_set(R, A); + *d = 0; + return; + } + + lenr = A->length; + if (R == B || R == A) + r = _fmpz_vec_init(lenr); + else + { + fmpz_poly_fit_length(R, lenr); + r = R->coeffs; + } + + _fmpz_poly_pseudo_rem(r, d, A->coeffs, A->length, + B->coeffs, B->length, NULL); + + for (lenr = B->length - 2; (lenr >= 0) && !r[lenr]; lenr--) ; + lenr++; + + if (R == B || R == A) + { + _fmpz_vec_clear(R->coeffs, R->alloc); + R->coeffs = r; + R->alloc = A->length; + R->length = lenr; + } + else + _fmpz_poly_set_length(R, lenr); +} diff --git a/external/flint-2.4.3/fmpz_poly/pseudo_rem_cohen.c b/external/flint-2.4.3/fmpz_poly/pseudo_rem_cohen.c new file mode 100644 index 0000000..94ae174 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/pseudo_rem_cohen.c @@ -0,0 +1,110 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void +_fmpz_poly_pseudo_rem_cohen(fmpz * R, const fmpz * A, slong lenA, + const fmpz * B, slong lenB) +{ + const fmpz * leadB = B + (lenB - 1); + slong e; + fmpz_t pow; + + if (lenB == 1) + { + _fmpz_vec_zero(R, lenA); + return; + } + + if (R != A) + _fmpz_vec_set(R, A, lenA); + e = lenA - lenB + 1; + + while (lenA >= lenB) + { + _fmpz_vec_scalar_mul_fmpz(R, R, lenA - 1, leadB); + _fmpz_vec_scalar_submul_fmpz(R + (lenA - lenB), B, lenB - 1, R + (lenA - 1)); + fmpz_zero(R + (lenA - 1)); + + lenA--; + FMPZ_VEC_NORM(R, lenA); + + e--; + } + + fmpz_init(pow); + fmpz_pow_ui(pow, leadB, e); + _fmpz_vec_scalar_mul_fmpz(R, R, lenA, pow); + fmpz_clear(pow); +} + +void +fmpz_poly_pseudo_rem_cohen(fmpz_poly_t R, const fmpz_poly_t A, const fmpz_poly_t B) +{ + slong lenr; + fmpz *r; + + if (B->length == 0) + { + flint_printf("Exception (fmpz_poly_pseudo_rem_cohen). Division by zero.\n"); + abort(); + } + if (A->length < B->length) + { + fmpz_poly_set(R, A); + return; + } + + lenr = A->length; + if (R == B) + r = _fmpz_vec_init(lenr); + else + { + fmpz_poly_fit_length(R, lenr); + r = R->coeffs; + } + + _fmpz_poly_pseudo_rem_cohen(r, A->coeffs, A->length, B->coeffs, B->length); + + for (lenr = B->length - 1; (lenr >= 0) && (r[lenr] == WORD(0)); lenr--) ; + lenr++; + + if (R == B) + { + _fmpz_vec_clear(R->coeffs, R->alloc); + R->coeffs = r; + R->alloc = A->length; + R->length = lenr; + } + else + _fmpz_poly_set_length(R, lenr); +} + diff --git a/external/flint-2.4.3/fmpz_poly/randtest.c b/external/flint-2.4.3/fmpz_poly/randtest.c new file mode 100644 index 0000000..f963632 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/randtest.c @@ -0,0 +1,67 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +void +fmpz_poly_randtest(fmpz_poly_t f, flint_rand_t state, + slong len, mp_bitcnt_t bits) +{ + fmpz_poly_fit_length(f, len); + _fmpz_vec_randtest(f->coeffs, state, len, bits); + _fmpz_poly_set_length(f, len); + _fmpz_poly_normalise(f); +} + +void +fmpz_poly_randtest_unsigned(fmpz_poly_t f, flint_rand_t state, + slong len, mp_bitcnt_t bits) +{ + fmpz_poly_fit_length(f, len); + _fmpz_vec_randtest_unsigned(f->coeffs, state, len, bits); + _fmpz_poly_set_length(f, len); + _fmpz_poly_normalise(f); +} + +void +fmpz_poly_randtest_not_zero(fmpz_poly_t f, flint_rand_t state, + slong len, mp_bitcnt_t bits) +{ + if ((bits == 0) || (len == 0)) + { + flint_printf("Exception (fmpz_poly_randtest_not_zero). bits or len is zero.\n"); + abort(); + } + + fmpz_poly_randtest(f, state, len, bits); + if (fmpz_poly_is_zero(f)) + fmpz_poly_set_ui(f, 1); +} diff --git a/external/flint-2.4.3/fmpz_poly/realloc.c b/external/flint-2.4.3/fmpz_poly/realloc.c new file mode 100644 index 0000000..ff74caf --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/realloc.c @@ -0,0 +1,57 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +void +fmpz_poly_realloc(fmpz_poly_t poly, slong alloc) +{ + if (alloc == 0) /* Clear up, reinitialise */ + { + fmpz_poly_clear(poly); + fmpz_poly_init(poly); + return; + } + + if (poly->alloc) /* Realloc */ + { + fmpz_poly_truncate(poly, alloc); + + poly->coeffs = (fmpz *) flint_realloc(poly->coeffs, alloc * sizeof(fmpz)); + if (alloc > poly->alloc) + flint_mpn_zero((mp_ptr) (poly->coeffs + poly->alloc), + alloc - poly->alloc); + } + else /* Nothing allocated already so do it now */ + { + poly->coeffs = (fmpz *) flint_calloc(alloc, sizeof(fmpz)); + } + + poly->alloc = alloc; +} diff --git a/external/flint-2.4.3/fmpz_poly/rem.c b/external/flint-2.4.3/fmpz_poly/rem.c new file mode 100644 index 0000000..4d98588 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/rem.c @@ -0,0 +1,87 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void +_fmpz_poly_rem(fmpz * R, const fmpz * A, slong lenA, const fmpz * B, slong lenB) +{ + if (lenA < 15) + { + _fmpz_poly_rem_basecase(R, A, lenA, B, lenB); + } + else + { + fmpz *Q = _fmpz_vec_init(lenA - lenB + 1); + + _fmpz_poly_divrem(Q, R, A, lenA, B, lenB); + + _fmpz_vec_clear(Q, lenA - lenB + 1); + } +} + +void fmpz_poly_rem(fmpz_poly_t R, const fmpz_poly_t A, const fmpz_poly_t B) +{ + const slong lenA = A->length, lenB = B->length; + fmpz *r; + + if (lenB == 0) + { + flint_printf("Exception (fmpz_poly_rem). Division by zero.\n"); + abort(); + } + + if (lenA < lenB) + { + fmpz_poly_set(R, A); + return; + } + + if (R == A || R == B) + { + r = _fmpz_vec_init(lenA); + } + else + { + fmpz_poly_fit_length(R, lenA); + r = R->coeffs; + } + + _fmpz_poly_rem(r, A->coeffs, lenA, B->coeffs, lenB); + + if (R == A || R == B) + { + _fmpz_vec_clear(R->coeffs, R->alloc); + R->coeffs = r; + R->alloc = lenB - 1; + } + _fmpz_poly_set_length(R, lenA); + _fmpz_poly_normalise(R); +} diff --git a/external/flint-2.4.3/fmpz_poly/rem_basecase.c b/external/flint-2.4.3/fmpz_poly/rem_basecase.c new file mode 100644 index 0000000..eeda2a7 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/rem_basecase.c @@ -0,0 +1,99 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void +_fmpz_poly_rem_basecase(fmpz * R, const fmpz * A, slong lenA, + const fmpz * B, slong lenB) +{ + const fmpz * leadB = B + (lenB - 1); + fmpz_t q; + + fmpz_init(q); + + if (R != A) + _fmpz_vec_set(R, A, lenA); + + for ( ; lenA >= lenB; lenA--) + { + if (fmpz_cmpabs(R + lenA - 1, leadB) >= 0) + { + fmpz_fdiv_q(q, R + lenA - 1, leadB); + _fmpz_vec_scalar_submul_fmpz(R + lenA - lenB, B, lenB, q); + } + } + + fmpz_clear(q); +} + +void +fmpz_poly_rem_basecase(fmpz_poly_t R, + const fmpz_poly_t A, const fmpz_poly_t B) +{ + slong lenr; + fmpz *r; + + if (B->length == 0) + { + flint_printf("Exception (fmpz_poly_rem_basecase). Division by zero.\n"); + abort(); + } + if (A->length < B->length) + { + fmpz_poly_set(R, A); + return; + } + + lenr = A->length; + if (R == B) + r = _fmpz_vec_init(lenr); + else + { + fmpz_poly_fit_length(R, lenr); + r = R->coeffs; + } + + _fmpz_poly_rem_basecase(r, A->coeffs, A->length, + B->coeffs, B->length); + + if (R == B) + { + _fmpz_vec_clear(R->coeffs, R->alloc); + R->coeffs = r; + R->alloc = lenr; + R->length = lenr; + } + else + _fmpz_poly_set_length(R, lenr); + + _fmpz_poly_normalise(R); +} diff --git a/external/flint-2.4.3/fmpz_poly/rem_powers_precomp.c b/external/flint-2.4.3/fmpz_poly/rem_powers_precomp.c new file mode 100644 index 0000000..819ae63 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/rem_powers_precomp.c @@ -0,0 +1,98 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +void _fmpz_poly_rem_powers_precomp(fmpz * A, slong m, + const fmpz * B, slong n, fmpz ** const powers) +{ + slong i; + fmpz * prod; + + if (m >= 2*n) + { + _fmpz_poly_rem_powers_precomp(A + n, m - n, B, n, powers); + m = 2*n - 1; + while (m && fmpz_is_zero(A + m - 1)) m--; + } + + if (m < n) + return; + + prod = _fmpz_vec_init(n - 1); + + for (i = n - 1; i < m; i++) + { + _fmpz_vec_scalar_mul_fmpz(prod, powers[i], n - 1, A + i); + _fmpz_poly_add(A, A, n - 1, prod, n - 1); + } + + _fmpz_vec_clear(prod, n - 1); +} + +void +fmpz_poly_rem_powers_precomp(fmpz_poly_t R, const fmpz_poly_t A, + const fmpz_poly_t B, const fmpz_poly_powers_precomp_t B_inv) +{ + fmpz_poly_t tR; + fmpz *r; + slong len1 = A->length, len2 = B->length; + + if (len1 < len2) + { + fmpz_poly_set(R, A); + return; + } + + if (R == B) + { + fmpz_poly_init2(tR, len1); + r = tR->coeffs; + } + else + { + fmpz_poly_fit_length(R, len1); + r = R->coeffs; + } + + if (R == B || R != A) + _fmpz_vec_set(r, A->coeffs, len1); + + _fmpz_poly_rem_powers_precomp(r, len1, B->coeffs, len2, B_inv->powers); + + if (R == B) + { + _fmpz_poly_set_length(tR, len2 - 1); + fmpz_poly_swap(tR, R); + fmpz_poly_clear(tR); + } + else + _fmpz_poly_set_length(R, len2 - 1); + + _fmpz_poly_normalise(R); +} diff --git a/external/flint-2.4.3/fmpz_poly/resultant.c b/external/flint-2.4.3/fmpz_poly/resultant.c new file mode 100644 index 0000000..ac95050 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/resultant.c @@ -0,0 +1,144 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void +_fmpz_poly_resultant(fmpz_t res, const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2) +{ + if (len2 == 1) + { + fmpz_pow_ui(res, poly2, len1 - 1); + } + else + { + fmpz_t a, b, g, h, t; + fmpz *A, *B, *W; + const slong alloc = len1 + len2; + slong sgn = 1; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(g); + fmpz_init(h); + fmpz_init(t); + + A = W = _fmpz_vec_init(alloc); + B = W + len1; + + _fmpz_poly_content(a, poly1, len1); + _fmpz_poly_content(b, poly2, len2); + _fmpz_vec_scalar_divexact_fmpz(A, poly1, len1, a); + _fmpz_vec_scalar_divexact_fmpz(B, poly2, len2, b); + + fmpz_one(g); + fmpz_one(h); + + fmpz_pow_ui(a, a, len2 - 1); + fmpz_pow_ui(b, b, len1 - 1); + fmpz_mul(t, a, b); + + do + { + const slong d = len1 - len2; + + if (!(len1 & WORD(1)) & !(len2 & WORD(1))) + sgn = -sgn; + + _fmpz_poly_pseudo_rem_cohen(A, A, len1, B, len2); + + FMPZ_VEC_NORM(A, len1); + + if (len1 == 0) + { + fmpz_zero(res); + goto cleanup; + } + + { + fmpz * T; + slong len; + T = A, A = B, B = T; + len = len1, len1 = len2, len2 = len; + } + + fmpz_pow_ui(a, h, d); + fmpz_mul(b, g, a); + _fmpz_vec_scalar_divexact_fmpz(B, B, len2, b); + + fmpz_pow_ui(g, A + (len1 - 1), d); + fmpz_mul(b, h, g); + fmpz_divexact(h, b, a); + fmpz_set(g, A + (len1 - 1)); + + } while (len2 > 1); + + fmpz_pow_ui(g, h, len1 - 1); + fmpz_pow_ui(b, B + (len2 - 1), len1 - 1); + fmpz_mul(a, h, b); + fmpz_divexact(h, a, g); + + fmpz_mul(res, t, h); + if (sgn < 0) + fmpz_neg(res, res); + + cleanup: + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(g); + fmpz_clear(h); + fmpz_clear(t); + + _fmpz_vec_clear(W, alloc); + } +} + +void +fmpz_poly_resultant(fmpz_t res, const fmpz_poly_t poly1, + const fmpz_poly_t poly2) +{ + const slong len1 = poly1->length, len2 = poly2->length; + + if (len1 == 0 || len2 == 0) + { + fmpz_zero(res); + return; + } + + if (len1 >= len2) + _fmpz_poly_resultant(res, poly1->coeffs, len1, poly2->coeffs, len2); + else + { + _fmpz_poly_resultant(res, poly2->coeffs, len2, poly1->coeffs, len1); + if ((len1 > 1) && (!(len1 & WORD(1)) & !(len2 & WORD(1)))) + fmpz_neg(res, res); + } +} diff --git a/external/flint-2.4.3/fmpz_poly/reverse.c b/external/flint-2.4.3/fmpz_poly/reverse.c new file mode 100644 index 0000000..a332fbd --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/reverse.c @@ -0,0 +1,76 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +void +_fmpz_poly_reverse(fmpz * res, const fmpz * poly, slong len, slong n) +{ + if (res == poly) + { + slong i; + + for (i = 0; i < n / 2; i++) + { + fmpz t = res[i]; + res[i] = res[n - 1 - i]; + res[n - 1 - i] = t; + } + + for (i = 0; i < n - len; i++) + fmpz_zero(res + i); + } + else + { + slong i; + + for (i = 0; i < n - len; i++) + fmpz_zero(res + i); + + for (i = 0; i < len; i++) + fmpz_set(res + (n - len) + i, poly + (len - 1) - i); + } +} + +void +fmpz_poly_reverse(fmpz_poly_t res, const fmpz_poly_t poly, slong n) +{ + slong len = FLINT_MIN(n, poly->length); + if (len == 0) + { + fmpz_poly_zero(res); + return; + } + + fmpz_poly_fit_length(res, n); + + _fmpz_poly_reverse(res->coeffs, poly->coeffs, len, n); + + _fmpz_poly_set_length(res, n); + _fmpz_poly_normalise(res); +} diff --git a/external/flint-2.4.3/fmpz_poly/revert_series.c b/external/flint-2.4.3/fmpz_poly/revert_series.c new file mode 100644 index 0000000..3de1d37 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/revert_series.c @@ -0,0 +1,88 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + + +void +_fmpz_poly_revert_series(fmpz * Qinv, const fmpz * Q, slong n) +{ + _fmpz_poly_revert_series_lagrange_fast(Qinv, Q, n); +} + +void +fmpz_poly_revert_series(fmpz_poly_t Qinv, const fmpz_poly_t Q, slong n) +{ + fmpz *Qcopy; + int Qalloc; + slong Qlen = Q->length; + + if (Qlen < 2 || !fmpz_is_zero(Q->coeffs) || !fmpz_is_pm1(Q->coeffs + 1)) + { + flint_printf("Exception (fmpz_poly_revert_series). Input must have \n" + "zero constant term and +1 or -1 as coefficient of x^1\n."); + abort(); + } + + if (Qlen >= n) + { + Qcopy = Q->coeffs; + Qalloc = 0; + } + else + { + slong i; + Qcopy = (fmpz *) flint_malloc(n * sizeof(fmpz)); + for (i = 0; i < Qlen; i++) + Qcopy[i] = Q->coeffs[i]; + for ( ; i < n; i++) + Qcopy[i] = 0; + Qalloc = 1; + } + + if (Qinv != Q) + { + fmpz_poly_fit_length(Qinv, n); + _fmpz_poly_revert_series(Qinv->coeffs, Qcopy, n); + } + else + { + fmpz_poly_t t; + fmpz_poly_init2(t, n); + _fmpz_poly_revert_series(t->coeffs, Qcopy, n); + fmpz_poly_swap(Qinv, t); + fmpz_poly_clear(t); + } + + _fmpz_poly_set_length(Qinv, n); + _fmpz_poly_normalise(Qinv); + + if (Qalloc) + flint_free(Qcopy); +} diff --git a/external/flint-2.4.3/fmpz_poly/revert_series_lagrange.c b/external/flint-2.4.3/fmpz_poly/revert_series_lagrange.c new file mode 100644 index 0000000..886f55a --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/revert_series_lagrange.c @@ -0,0 +1,117 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + + +void +_fmpz_poly_revert_series_lagrange(fmpz * Qinv, const fmpz * Q, slong n) +{ + slong i; + fmpz *R, *S, *T, *tmp; + + if (n <= 2) + { + _fmpz_vec_set(Qinv, Q, n); + return; + } + + R = _fmpz_vec_init(n - 1); + S = _fmpz_vec_init(n - 1); + T = _fmpz_vec_init(n - 1); + + fmpz_zero(Qinv); + fmpz_set(Qinv + 1, Q + 1); + + _fmpz_poly_inv_series(R, Q + 1, n - 1); + _fmpz_vec_set(S, R, n - 1); + + for (i = 2; i < n; i++) + { + _fmpz_poly_mullow(T, S, n - 1, R, n - 1, n - 1); + fmpz_divexact_ui(Qinv + i, T + i - 1, i); + tmp = S; S = T; T = tmp; + } + + _fmpz_vec_clear(R, n - 1); + _fmpz_vec_clear(S, n - 1); + _fmpz_vec_clear(T, n - 1); +} + +void +fmpz_poly_revert_series_lagrange(fmpz_poly_t Qinv, + const fmpz_poly_t Q, slong n) +{ + fmpz *Qcopy; + int Qalloc; + slong Qlen = Q->length; + + if (Qlen < 2 || !fmpz_is_zero(Q->coeffs) || !fmpz_is_pm1(Q->coeffs + 1)) + { + flint_printf("Exception (fmpz_poly_revert_series_lagrange). Input must have \n" + "zero constant term and +1 or -1 as coefficient of x^1.\n"); + abort(); + } + + if (Qlen >= n) + { + Qcopy = Q->coeffs; + Qalloc = 0; + } + else + { + slong i; + Qcopy = (fmpz *) flint_malloc(n * sizeof(fmpz)); + for (i = 0; i < Qlen; i++) + Qcopy[i] = Q->coeffs[i]; + for ( ; i < n; i++) + Qcopy[i] = 0; + Qalloc = 1; + } + + if (Qinv != Q) + { + fmpz_poly_fit_length(Qinv, n); + _fmpz_poly_revert_series_lagrange(Qinv->coeffs, Qcopy, n); + } + else + { + fmpz_poly_t t; + fmpz_poly_init2(t, n); + _fmpz_poly_revert_series_lagrange(t->coeffs, Qcopy, n); + fmpz_poly_swap(Qinv, t); + fmpz_poly_clear(t); + } + + _fmpz_poly_set_length(Qinv, n); + _fmpz_poly_normalise(Qinv); + + if (Qalloc) + flint_free(Qcopy); +} diff --git a/external/flint-2.4.3/fmpz_poly/revert_series_lagrange_fast.c b/external/flint-2.4.3/fmpz_poly/revert_series_lagrange_fast.c new file mode 100644 index 0000000..95c165c --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/revert_series_lagrange_fast.c @@ -0,0 +1,143 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + + +/* pointer to (x/Q)^i */ +#define Ri(ii) (R + (n-1)*((ii)-1)) + +void +_fmpz_poly_revert_series_lagrange_fast(fmpz * Qinv, const fmpz * Q, slong n) +{ + slong i, j, k, m; + fmpz *R, *S, *T, *tmp; + fmpz_t t; + + if (n <= 2) + { + _fmpz_vec_set(Qinv, Q, n); + return; + } + + m = n_sqrt(n); + + fmpz_init(t); + R = _fmpz_vec_init((n - 1) * m); + S = _fmpz_vec_init(n - 1); + T = _fmpz_vec_init(n - 1); + + fmpz_zero(Qinv); + fmpz_set(Qinv + 1, Q + 1); + + _fmpz_poly_inv_series(Ri(1), Q + 1, n - 1); + for (i = 2; i <= m; i++) + _fmpz_poly_mullow(Ri(i), Ri(i-1), n - 1, Ri(1), n - 1, n - 1); + for (i = 2; i < m; i++) + fmpz_divexact_ui(Qinv + i, Ri(i) + i - 1, i); + + _fmpz_vec_set(S, Ri(m), n - 1); + + for (i = m; i < n; i += m) + { + fmpz_divexact_ui(Qinv + i, S + i - 1, i); + + for (j = 1; j < m && i + j < n; j++) + { + fmpz_mul(t, S + 0, Ri(j) + i + j - 1); + for (k = 1; k <= i + j - 1; k++) + fmpz_addmul(t, S + k, Ri(j) + i + j - 1 - k); + fmpz_divexact_ui(Qinv + i + j, t, i + j); + } + + if (i + 1 < n) + { + _fmpz_poly_mullow(T, S, n - 1, Ri(m), n - 1, n - 1); + tmp = S; S = T; T = tmp; + } + } + + fmpz_clear(t); + _fmpz_vec_clear(R, (n - 1) * m); + _fmpz_vec_clear(S, n - 1); + _fmpz_vec_clear(T, n - 1); +} + +void +fmpz_poly_revert_series_lagrange_fast(fmpz_poly_t Qinv, + const fmpz_poly_t Q, slong n) +{ + fmpz *Qcopy; + int Qalloc; + slong Qlen = Q->length; + + if (Qlen < 2 || !fmpz_is_zero(Q->coeffs) || !fmpz_is_pm1(Q->coeffs + 1)) + { + flint_printf("Exception (fmpz_poly_revert_series_lagrange_fast). Input must \n" + "have zero constant term and +1 or -1 as coefficient of x^1.\n"); + abort(); + } + + if (Qlen >= n) + { + Qcopy = Q->coeffs; + Qalloc = 0; + } + else + { + slong i; + Qcopy = (fmpz *) flint_malloc(n * sizeof(fmpz)); + for (i = 0; i < Qlen; i++) + Qcopy[i] = Q->coeffs[i]; + for ( ; i < n; i++) + Qcopy[i] = 0; + Qalloc = 1; + } + + if (Qinv != Q) + { + fmpz_poly_fit_length(Qinv, n); + _fmpz_poly_revert_series_lagrange_fast(Qinv->coeffs, Qcopy, n); + } + else + { + fmpz_poly_t t; + fmpz_poly_init2(t, n); + _fmpz_poly_revert_series_lagrange_fast(t->coeffs, Qcopy, n); + fmpz_poly_swap(Qinv, t); + fmpz_poly_clear(t); + } + + _fmpz_poly_set_length(Qinv, n); + _fmpz_poly_normalise(Qinv); + + if (Qalloc) + flint_free(Qcopy); +} diff --git a/external/flint-2.4.3/fmpz_poly/revert_series_newton.c b/external/flint-2.4.3/fmpz_poly/revert_series_newton.c new file mode 100644 index 0000000..a5e1d1d --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/revert_series_newton.c @@ -0,0 +1,131 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + + +#define FLINT_REVERSE_NEWTON_CUTOFF 10 + +void +_fmpz_poly_revert_series_newton(fmpz * Qinv, const fmpz * Q, slong n) +{ + if (n <= 2) + { + _fmpz_vec_set(Qinv, Q, n); + return; + } + else + { + slong *a, i, k; + fmpz *T, *U, *V; + + T = _fmpz_vec_init(n); + U = _fmpz_vec_init(n); + V = _fmpz_vec_init(n); + + k = n; + for (i = 1; (WORD(1) << i) < k; i++); + a = (slong *) flint_malloc(i * sizeof(slong)); + a[i = 0] = k; + while (k >= FLINT_REVERSE_NEWTON_CUTOFF) + a[++i] = (k = (k + 1) / 2); + + _fmpz_poly_revert_series_lagrange(Qinv, Q, k); + _fmpz_vec_zero(Qinv + k, n - k); + + for (i--; i >= 0; i--) + { + k = a[i]; + _fmpz_poly_compose_series(T, Q, k, Qinv, k, k); + _fmpz_poly_derivative(U, T, k); fmpz_zero(U + k - 1); + fmpz_zero(T + 1); + _fmpz_poly_div_series(V, T, U, k); + _fmpz_poly_derivative(T, Qinv, k); + _fmpz_poly_mullow(U, V, k, T, k, k); + _fmpz_vec_sub(Qinv, Qinv, U, k); + } + + flint_free(a); + _fmpz_vec_clear(T, n); + _fmpz_vec_clear(U, n); + _fmpz_vec_clear(V, n); + } +} + +void +fmpz_poly_revert_series_newton(fmpz_poly_t Qinv, const fmpz_poly_t Q, slong n) +{ + fmpz *Qcopy; + int Qalloc; + slong Qlen = Q->length; + + if (Qlen < 2 || !fmpz_is_zero(Q->coeffs) || !fmpz_is_pm1(Q->coeffs + 1)) + { + flint_printf("Exception (fmpz_poly_revert_series_newton). Input must have \n" + "zero constant term and +1 or -1 as coefficient of x^1.\n"); + abort(); + } + + if (Qlen >= n) + { + Qcopy = Q->coeffs; + Qalloc = 0; + } + else + { + slong i; + Qcopy = (fmpz *) flint_malloc(n * sizeof(fmpz)); + for (i = 0; i < Qlen; i++) + Qcopy[i] = Q->coeffs[i]; + for ( ; i < n; i++) + Qcopy[i] = 0; + Qalloc = 1; + } + + if (Qinv != Q) + { + fmpz_poly_fit_length(Qinv, n); + _fmpz_poly_revert_series_newton(Qinv->coeffs, Qcopy, n); + } + else + { + fmpz_poly_t t; + fmpz_poly_init2(t, n); + _fmpz_poly_revert_series_newton(t->coeffs, Qcopy, n); + fmpz_poly_swap(Qinv, t); + fmpz_poly_clear(t); + } + + _fmpz_poly_set_length(Qinv, n); + _fmpz_poly_normalise(Qinv); + + if (Qalloc) + flint_free(Qcopy); +} + diff --git a/external/flint-2.4.3/fmpz_poly/scalar_addmul_fmpz.c b/external/flint-2.4.3/fmpz_poly/scalar_addmul_fmpz.c new file mode 100644 index 0000000..ece7eec --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/scalar_addmul_fmpz.c @@ -0,0 +1,45 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void +fmpz_poly_scalar_addmul_fmpz(fmpz_poly_t poly1, const fmpz_poly_t poly2, + const fmpz_t x) +{ + if (!fmpz_is_zero(x) && !fmpz_poly_is_zero(poly2)) + { + fmpz_poly_fit_length(poly1, poly2->length); + _fmpz_vec_scalar_addmul_fmpz(poly1->coeffs, + poly2->coeffs, poly2->length, x); + _fmpz_poly_set_length(poly1, FLINT_MAX(poly1->length, poly2->length)); + _fmpz_poly_normalise(poly1); + } +} diff --git a/external/flint-2.4.3/fmpz_poly/scalar_divexact_fmpz.c b/external/flint-2.4.3/fmpz_poly/scalar_divexact_fmpz.c new file mode 100644 index 0000000..4be12a5 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/scalar_divexact_fmpz.c @@ -0,0 +1,51 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void +fmpz_poly_scalar_divexact_fmpz(fmpz_poly_t poly1, const fmpz_poly_t poly2, + const fmpz_t x) +{ + if (fmpz_is_zero(x)) + { + flint_printf("Exception (fmpz_poly_scalar_divexact_fmpz). Division by zero.\n"); + abort(); + } + + if (poly2->length == 0) + { + fmpz_poly_zero(poly1); + return; + } + + fmpz_poly_fit_length(poly1, poly2->length); + _fmpz_vec_scalar_divexact_fmpz(poly1->coeffs, poly2->coeffs, poly2->length, x); + _fmpz_poly_set_length(poly1, poly2->length); +} diff --git a/external/flint-2.4.3/fmpz_poly/scalar_divexact_si.c b/external/flint-2.4.3/fmpz_poly/scalar_divexact_si.c new file mode 100644 index 0000000..2670dbb --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/scalar_divexact_si.c @@ -0,0 +1,51 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void +fmpz_poly_scalar_divexact_si(fmpz_poly_t poly1, const fmpz_poly_t poly2, + slong x) +{ + if (x == 0) + { + flint_printf("Exception (fmpz_poly_scalar_divexact_si). Division by zero.\n"); + abort(); + } + + if (poly2->length == 0) + { + fmpz_poly_zero(poly1); + return; + } + + fmpz_poly_fit_length(poly1, poly2->length); + _fmpz_vec_scalar_divexact_si(poly1->coeffs, poly2->coeffs, poly2->length, x); + _fmpz_poly_set_length(poly1, poly2->length); +} diff --git a/external/flint-2.4.3/fmpz_poly/scalar_divexact_ui.c b/external/flint-2.4.3/fmpz_poly/scalar_divexact_ui.c new file mode 100644 index 0000000..293ff4f --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/scalar_divexact_ui.c @@ -0,0 +1,51 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void +fmpz_poly_scalar_divexact_ui(fmpz_poly_t poly1, const fmpz_poly_t poly2, + ulong x) +{ + if (x == 0) + { + flint_printf("Exception (fmpz_poly_scalar_divexact_ui). Division by zero.\n"); + abort(); + } + + if (poly2->length == 0) + { + fmpz_poly_zero(poly1); + return; + } + + fmpz_poly_fit_length(poly1, poly2->length); + _fmpz_vec_scalar_divexact_ui(poly1->coeffs, poly2->coeffs, poly2->length, x); + _fmpz_poly_set_length(poly1, poly2->length); +} diff --git a/external/flint-2.4.3/fmpz_poly/scalar_fdiv_2exp.c b/external/flint-2.4.3/fmpz_poly/scalar_fdiv_2exp.c new file mode 100644 index 0000000..9f9347d --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/scalar_fdiv_2exp.c @@ -0,0 +1,46 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void +fmpz_poly_scalar_fdiv_2exp(fmpz_poly_t poly1, const fmpz_poly_t poly2, + ulong exp) +{ + if (poly2->length == 0) + { + fmpz_poly_zero(poly1); + return; + } + + fmpz_poly_fit_length(poly1, poly2->length); + _fmpz_vec_scalar_fdiv_q_2exp(poly1->coeffs, poly2->coeffs, + poly2->length, exp); + _fmpz_poly_set_length(poly1, poly2->length); +} diff --git a/external/flint-2.4.3/fmpz_poly/scalar_fdiv_fmpz.c b/external/flint-2.4.3/fmpz_poly/scalar_fdiv_fmpz.c new file mode 100644 index 0000000..e4eddb3 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/scalar_fdiv_fmpz.c @@ -0,0 +1,51 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void +fmpz_poly_scalar_fdiv_fmpz(fmpz_poly_t poly1, const fmpz_poly_t poly2, + const fmpz_t x) +{ + if (fmpz_is_zero(x)) + { + flint_printf("Exception (fmpz_poly_scalar_fdiv_fmpz). Division by zero.\n"); + abort(); + } + + if (poly2->length == 0) + { + fmpz_poly_zero(poly1); + return; + } + + fmpz_poly_fit_length(poly1, poly2->length); + _fmpz_vec_scalar_fdiv_q_fmpz(poly1->coeffs, poly2->coeffs, poly2->length, x); + _fmpz_poly_set_length(poly1, poly2->length); +} diff --git a/external/flint-2.4.3/fmpz_poly/scalar_fdiv_si.c b/external/flint-2.4.3/fmpz_poly/scalar_fdiv_si.c new file mode 100644 index 0000000..ce23698 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/scalar_fdiv_si.c @@ -0,0 +1,51 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void +fmpz_poly_scalar_fdiv_si(fmpz_poly_t poly1, const fmpz_poly_t poly2, + slong x) +{ + if (x == 0) + { + flint_printf("Exception (fmpz_poly_scalar_fdiv_si). Division by zero.\n"); + abort(); + } + + if (poly2->length == 0) + { + fmpz_poly_zero(poly1); + return; + } + + fmpz_poly_fit_length(poly1, poly2->length); + _fmpz_vec_scalar_fdiv_q_si(poly1->coeffs, poly2->coeffs, poly2->length, x); + _fmpz_poly_set_length(poly1, poly2->length); +} diff --git a/external/flint-2.4.3/fmpz_poly/scalar_fdiv_ui.c b/external/flint-2.4.3/fmpz_poly/scalar_fdiv_ui.c new file mode 100644 index 0000000..a18d2a3 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/scalar_fdiv_ui.c @@ -0,0 +1,51 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void +fmpz_poly_scalar_fdiv_ui(fmpz_poly_t poly1, const fmpz_poly_t poly2, + ulong x) +{ + if (x == 0) + { + flint_printf("Exception (fmpz_poly_scalar_fdiv_ui). Division by zero.\n"); + abort(); + } + + if (poly2->length == 0) + { + fmpz_poly_zero(poly1); + return; + } + + fmpz_poly_fit_length(poly1, poly2->length); + _fmpz_vec_scalar_fdiv_q_ui(poly1->coeffs, poly2->coeffs, poly2->length, x); + _fmpz_poly_set_length(poly1, poly2->length); +} diff --git a/external/flint-2.4.3/fmpz_poly/scalar_mul_2exp.c b/external/flint-2.4.3/fmpz_poly/scalar_mul_2exp.c new file mode 100644 index 0000000..02b17f2 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/scalar_mul_2exp.c @@ -0,0 +1,45 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void +fmpz_poly_scalar_mul_2exp(fmpz_poly_t poly1, const fmpz_poly_t poly2, + ulong exp) +{ + if (poly2->length == 0) + { + fmpz_poly_zero(poly1); + return; + } + + fmpz_poly_fit_length(poly1, poly2->length); + _fmpz_vec_scalar_mul_2exp(poly1->coeffs, poly2->coeffs, poly2->length, exp); + _fmpz_poly_set_length(poly1, poly2->length); +} diff --git a/external/flint-2.4.3/fmpz_poly/scalar_mul_fmpz.c b/external/flint-2.4.3/fmpz_poly/scalar_mul_fmpz.c new file mode 100644 index 0000000..9513ea9 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/scalar_mul_fmpz.c @@ -0,0 +1,46 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void +fmpz_poly_scalar_mul_fmpz(fmpz_poly_t poly1, const fmpz_poly_t poly2, + const fmpz_t x) +{ + /* Either scalar or input poly is zero */ + if ((*x == 0) || (poly2->length == 0)) + { + fmpz_poly_zero(poly1); + return; + } + + fmpz_poly_fit_length(poly1, poly2->length); + _fmpz_vec_scalar_mul_fmpz(poly1->coeffs, poly2->coeffs, poly2->length, x); + _fmpz_poly_set_length(poly1, poly2->length); +} diff --git a/external/flint-2.4.3/fmpz_poly/scalar_mul_si.c b/external/flint-2.4.3/fmpz_poly/scalar_mul_si.c new file mode 100644 index 0000000..b47cddd --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/scalar_mul_si.c @@ -0,0 +1,63 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +void +fmpz_poly_scalar_mul_si(fmpz_poly_t poly1, const fmpz_poly_t poly2, slong x) +{ + slong i; + + /* Either scalar or input poly is zero */ + if ((x == WORD(0)) || (poly2->length == 0)) + { + fmpz_poly_zero(poly1); + return; + } + + /* Special case, multiply by 1 */ + if (x == WORD(1)) + { + fmpz_poly_set(poly1, poly2); + return; + } + + /* Special case, multiply by -1 */ + if (x == WORD(-1)) + { + fmpz_poly_neg(poly1, poly2); + return; + } + + fmpz_poly_fit_length(poly1, poly2->length); + + for (i = 0; i < poly2->length; i++) + fmpz_mul_si(poly1->coeffs + i, poly2->coeffs + i, x); + + _fmpz_poly_set_length(poly1, poly2->length); +} diff --git a/external/flint-2.4.3/fmpz_poly/scalar_mul_ui.c b/external/flint-2.4.3/fmpz_poly/scalar_mul_ui.c new file mode 100644 index 0000000..37b21db --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/scalar_mul_ui.c @@ -0,0 +1,56 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +void +fmpz_poly_scalar_mul_ui(fmpz_poly_t poly1, const fmpz_poly_t poly2, ulong x) +{ + slong i; + + /* Either scalar or input poly is zero */ + if ((x == 0) || (poly2->length == 0)) + { + fmpz_poly_zero(poly1); + return; + } + + /* Special case, multiply by 1 */ + if (x == 1) + { + fmpz_poly_set(poly1, poly2); + return; + } + + fmpz_poly_fit_length(poly1, poly2->length); + + for (i = 0; i < poly2->length; i++) + fmpz_mul_ui(poly1->coeffs + i, poly2->coeffs + i, x); + + _fmpz_poly_set_length(poly1, poly2->length); +} diff --git a/external/flint-2.4.3/fmpz_poly/scalar_submul_fmpz.c b/external/flint-2.4.3/fmpz_poly/scalar_submul_fmpz.c new file mode 100644 index 0000000..14c85a3 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/scalar_submul_fmpz.c @@ -0,0 +1,45 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void +fmpz_poly_scalar_submul_fmpz(fmpz_poly_t poly1, const fmpz_poly_t poly2, + const fmpz_t x) +{ + if (!fmpz_is_zero(x) && !fmpz_poly_is_zero(poly2)) + { + fmpz_poly_fit_length(poly1, poly2->length); + _fmpz_vec_scalar_submul_fmpz(poly1->coeffs, + poly2->coeffs, poly2->length, x); + _fmpz_poly_set_length(poly1, FLINT_MAX(poly1->length, poly2->length)); + _fmpz_poly_normalise(poly1); + } +} diff --git a/external/flint-2.4.3/fmpz_poly/scalar_tdiv_2exp.c b/external/flint-2.4.3/fmpz_poly/scalar_tdiv_2exp.c new file mode 100644 index 0000000..17fd224 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/scalar_tdiv_2exp.c @@ -0,0 +1,46 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void +fmpz_poly_scalar_tdiv_2exp(fmpz_poly_t poly1, const fmpz_poly_t poly2, + ulong exp) +{ + if (poly2->length == 0) + { + fmpz_poly_zero(poly1); + return; + } + + fmpz_poly_fit_length(poly1, poly2->length); + _fmpz_vec_scalar_tdiv_q_2exp(poly1->coeffs, poly2->coeffs, + poly2->length, exp); + _fmpz_poly_set_length(poly1, poly2->length); +} diff --git a/external/flint-2.4.3/fmpz_poly/scalar_tdiv_fmpz.c b/external/flint-2.4.3/fmpz_poly/scalar_tdiv_fmpz.c new file mode 100644 index 0000000..b8fbc1e --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/scalar_tdiv_fmpz.c @@ -0,0 +1,51 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void +fmpz_poly_scalar_tdiv_fmpz(fmpz_poly_t poly1, const fmpz_poly_t poly2, + const fmpz_t x) +{ + if (fmpz_is_zero(x)) + { + flint_printf("Exception (fmpz_poly_scalar_tdiv_fmpz). Division by zero.\n"); + abort(); + } + + if (poly2->length == 0) + { + fmpz_poly_zero(poly1); + return; + } + + fmpz_poly_fit_length(poly1, poly2->length); + _fmpz_vec_scalar_tdiv_q_fmpz(poly1->coeffs, poly2->coeffs, poly2->length, x); + _fmpz_poly_set_length(poly1, poly2->length); +} diff --git a/external/flint-2.4.3/fmpz_poly/scalar_tdiv_si.c b/external/flint-2.4.3/fmpz_poly/scalar_tdiv_si.c new file mode 100644 index 0000000..eb27b08 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/scalar_tdiv_si.c @@ -0,0 +1,51 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void +fmpz_poly_scalar_tdiv_si(fmpz_poly_t poly1, const fmpz_poly_t poly2, + slong x) +{ + if (x == 0) + { + flint_printf("Exception (fmpz_poly_scalar_tdiv_si). Division by zero.\n"); + abort(); + } + + if (poly2->length == 0) + { + fmpz_poly_zero(poly1); + return; + } + + fmpz_poly_fit_length(poly1, poly2->length); + _fmpz_vec_scalar_tdiv_q_si(poly1->coeffs, poly2->coeffs, poly2->length, x); + _fmpz_poly_set_length(poly1, poly2->length); +} diff --git a/external/flint-2.4.3/fmpz_poly/scalar_tdiv_ui.c b/external/flint-2.4.3/fmpz_poly/scalar_tdiv_ui.c new file mode 100644 index 0000000..2f7ab72 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/scalar_tdiv_ui.c @@ -0,0 +1,51 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void +fmpz_poly_scalar_tdiv_ui(fmpz_poly_t poly1, const fmpz_poly_t poly2, + ulong x) +{ + if (x == 0) + { + flint_printf("Exception (fmpz_poly_scalar_tdiv_ui). Division by zero.\n"); + abort(); + } + + if (poly2->length == 0) + { + fmpz_poly_zero(poly1); + return; + } + + fmpz_poly_fit_length(poly1, poly2->length); + _fmpz_vec_scalar_tdiv_q_ui(poly1->coeffs, poly2->coeffs, poly2->length, x); + _fmpz_poly_set_length(poly1, poly2->length); +} diff --git a/external/flint-2.4.3/fmpz_poly/set.c b/external/flint-2.4.3/fmpz_poly/set.c new file mode 100644 index 0000000..bd6b855 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/set.c @@ -0,0 +1,45 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +void +fmpz_poly_set(fmpz_poly_t poly1, const fmpz_poly_t poly2) +{ + if (poly1 != poly2) /* Aliasing is trivial */ + { + slong i, len = poly2->length; + + fmpz_poly_fit_length(poly1, len); + + for (i = 0; i < len; i++) + fmpz_set(poly1->coeffs + i, poly2->coeffs + i); + + _fmpz_poly_set_length(poly1, len); + } +} diff --git a/external/flint-2.4.3/fmpz_poly/set_coeff_fmpz.c b/external/flint-2.4.3/fmpz_poly/set_coeff_fmpz.c new file mode 100644 index 0000000..e864052 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/set_coeff_fmpz.c @@ -0,0 +1,45 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +void +fmpz_poly_set_coeff_fmpz(fmpz_poly_t poly, slong n, const fmpz_t x) +{ + fmpz_poly_fit_length(poly, n + 1); + + if (n + 1 > poly->length) /* insert zeroes between end of poly and new coeff if needed */ + { + flint_mpn_zero((mp_ptr) (poly->coeffs + poly->length), n - poly->length); + poly->length = n + 1; + } + + fmpz_set(poly->coeffs + n, x); + _fmpz_poly_normalise(poly); /* we may have set leading coefficient to zero */ +} diff --git a/external/flint-2.4.3/fmpz_poly/set_coeff_si.c b/external/flint-2.4.3/fmpz_poly/set_coeff_si.c new file mode 100644 index 0000000..9ffdffe --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/set_coeff_si.c @@ -0,0 +1,45 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +void +fmpz_poly_set_coeff_si(fmpz_poly_t poly, slong n, slong x) +{ + fmpz_poly_fit_length(poly, n + 1); + + if (n + 1 > poly->length) /* insert zeroes between end of poly and new coeff if needed */ + { + flint_mpn_zero((mp_ptr) (poly->coeffs + poly->length), n - poly->length); + poly->length = n + 1; + } + + fmpz_set_si(poly->coeffs + n, x); + _fmpz_poly_normalise(poly); /* we may have set leading coefficient to zero */ +} diff --git a/external/flint-2.4.3/fmpz_poly/set_coeff_ui.c b/external/flint-2.4.3/fmpz_poly/set_coeff_ui.c new file mode 100644 index 0000000..0ee1a89 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/set_coeff_ui.c @@ -0,0 +1,45 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +void +fmpz_poly_set_coeff_ui(fmpz_poly_t poly, slong n, ulong x) +{ + fmpz_poly_fit_length(poly, n + 1); + + if (n + 1 > poly->length) /* insert zeroes between end of poly and new coeff if needed */ + { + flint_mpn_zero((mp_ptr) (poly->coeffs + poly->length), n - poly->length); + poly->length = n + 1; + } + + fmpz_set_ui(poly->coeffs + n, x); + _fmpz_poly_normalise(poly); /* we may have set leading coefficient to zero */ +} diff --git a/external/flint-2.4.3/fmpz_poly/set_fmpz.c b/external/flint-2.4.3/fmpz_poly/set_fmpz.c new file mode 100644 index 0000000..9a44477 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/set_fmpz.c @@ -0,0 +1,42 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +void +fmpz_poly_set_fmpz(fmpz_poly_t poly, const fmpz_t c) +{ + if (fmpz_is_zero(c)) + fmpz_poly_zero(poly); + else + { + fmpz_poly_fit_length(poly, 1); + fmpz_set(poly->coeffs, c); + _fmpz_poly_set_length(poly, 1); + } +} diff --git a/external/flint-2.4.3/fmpz_poly/set_mpz.c b/external/flint-2.4.3/fmpz_poly/set_mpz.c new file mode 100644 index 0000000..484a7d0 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/set_mpz.c @@ -0,0 +1,42 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +void +fmpz_poly_set_mpz(fmpz_poly_t poly, const mpz_t c) +{ + if (mpz_sgn(c) == 0) + fmpz_poly_zero(poly); + else + { + fmpz_poly_fit_length(poly, 1); + fmpz_set_mpz(poly->coeffs, c); + _fmpz_poly_set_length(poly, 1); + } +} diff --git a/external/flint-2.4.3/fmpz_poly/set_nmod_poly.c b/external/flint-2.4.3/fmpz_poly/set_nmod_poly.c new file mode 100644 index 0000000..67c0c72 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/set_nmod_poly.c @@ -0,0 +1,50 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" +#include "nmod_poly.h" + +void +fmpz_poly_set_nmod_poly(fmpz_poly_t res, const nmod_poly_t poly) +{ + slong len = poly->length; + + if (len == 0) + { + fmpz_poly_zero(res); + } + else + { + slong i; + fmpz_poly_fit_length(res, len); + for (i = 0; i < len; i++) + fmpz_set_ui_smod(res->coeffs + i, poly->coeffs[i], poly->mod.n); + _fmpz_poly_set_length(res, len); + } +} diff --git a/external/flint-2.4.3/fmpz_poly/set_nmod_poly_unsigned.c b/external/flint-2.4.3/fmpz_poly/set_nmod_poly_unsigned.c new file mode 100644 index 0000000..37664dc --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/set_nmod_poly_unsigned.c @@ -0,0 +1,50 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" +#include "nmod_poly.h" + +void +fmpz_poly_set_nmod_poly_unsigned(fmpz_poly_t res, const nmod_poly_t poly) +{ + slong len = poly->length; + + if (len == 0) + { + fmpz_poly_zero(res); + } + else + { + slong i; + fmpz_poly_fit_length(res, len); + for (i = 0; i < len; i++) + fmpz_set_ui(res->coeffs + i, poly->coeffs[i]); + _fmpz_poly_set_length(res, len); + } +} diff --git a/external/flint-2.4.3/fmpz_poly/set_si.c b/external/flint-2.4.3/fmpz_poly/set_si.c new file mode 100644 index 0000000..3c2f17d --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/set_si.c @@ -0,0 +1,42 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +void +fmpz_poly_set_si(fmpz_poly_t poly, slong c) +{ + if (c == 0) + fmpz_poly_zero(poly); + else + { + fmpz_poly_fit_length(poly, 1); + fmpz_set_si(poly->coeffs, c); + _fmpz_poly_set_length(poly, 1); + } +} diff --git a/external/flint-2.4.3/fmpz_poly/set_str.c b/external/flint-2.4.3/fmpz_poly/set_str.c new file mode 100644 index 0000000..732171d --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/set_str.c @@ -0,0 +1,122 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +int +_fmpz_poly_set_str(fmpz * poly, const char *str) +{ + char * w; + slong i, len; + + if (!isdigit((unsigned char) str[0])) + return -1; + len = atol(str); + if (len < 0) + return -1; + if (len == 0) + return 0; + + while (*str++ != ' ') + ; + + /* Find maximal gap between spaces and allocate w */ + { + const char * s = str; + slong max; + for (max = 0; *s != '\0';) + { + slong cur; + for (s++, cur = 1; *s != ' ' && *s != '\0'; s++, cur++) ; + if (max < cur) + max = cur; + } + + w = flint_malloc(max + 1); + } + + for (i = 0; i < len; i++) + { + char * v; + int ans; + + for (str++, v = w; *str != ' ' && *str != '\0';) + *v++ = *str++; + *v = '\0'; + ans = fmpz_set_str(poly++, w, 10); + + if (ans) + { + flint_free(w); + return -1; + } + } + + flint_free(w); + return 0; +} + +int +fmpz_poly_set_str(fmpz_poly_t poly, const char * str) +{ + int ans; + slong len; + + if (!isdigit((unsigned char) str[0])) + return -1; + len = atol(str); + if (len < 0) + return -1; + if (len == 0) + { + fmpz_poly_zero(poly); + return 0; + } + + fmpz_poly_fit_length(poly, len); + + ans = _fmpz_poly_set_str(poly->coeffs, str); + + if (ans == 0) + { + _fmpz_poly_set_length(poly, len); + _fmpz_poly_normalise(poly); + } + else + { + _fmpz_vec_zero(poly->coeffs, len); + _fmpz_poly_set_length(poly, 0); + } + + return ans; +} diff --git a/external/flint-2.4.3/fmpz_poly/set_ui.c b/external/flint-2.4.3/fmpz_poly/set_ui.c new file mode 100644 index 0000000..acc1d60 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/set_ui.c @@ -0,0 +1,42 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +void +fmpz_poly_set_ui(fmpz_poly_t poly, ulong c) +{ + if (c == UWORD(0)) + fmpz_poly_zero(poly); + else + { + fmpz_poly_fit_length(poly, 1); + fmpz_set_ui(poly->coeffs, c); + _fmpz_poly_set_length(poly, 1); + } +} diff --git a/external/flint-2.4.3/fmpz_poly/shift_left.c b/external/flint-2.4.3/fmpz_poly/shift_left.c new file mode 100644 index 0000000..f4b03be --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/shift_left.c @@ -0,0 +1,71 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +void +_fmpz_poly_shift_left(fmpz * res, const fmpz * poly, slong len, slong n) +{ + slong i; + + /* Copy in reverse to avoid writing over unshifted coefficients */ + if (res != poly) + { + for (i = len; i--; ) + fmpz_set(res + n + i, poly + i); + } + else + { + for (i = len; i--; ) + fmpz_swap(res + n + i, res + i); + } + + for (i = 0; i < n; i++) + fmpz_zero(res + i); +} + +void +fmpz_poly_shift_left(fmpz_poly_t res, const fmpz_poly_t poly, slong n) +{ + if (n == 0) + { + fmpz_poly_set(res, poly); + return; + } + + if (poly->length == 0) + { + fmpz_poly_zero(res); + return; + } + + fmpz_poly_fit_length(res, poly->length + n); + _fmpz_poly_shift_left(res->coeffs, poly->coeffs, poly->length, n); + _fmpz_poly_set_length(res, poly->length + n); +} diff --git a/external/flint-2.4.3/fmpz_poly/shift_right.c b/external/flint-2.4.3/fmpz_poly/shift_right.c new file mode 100644 index 0000000..33d2d85 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/shift_right.c @@ -0,0 +1,69 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +void +_fmpz_poly_shift_right(fmpz * res, const fmpz * poly, slong len, slong n) +{ + slong i; + + /* Copy in forward order to avoid writing over unshifted coefficients */ + if (res != poly) + { + for (i = 0; i < len - n; i++) + fmpz_set(res + i, poly + n + i); + } + else + { + for (i = 0; i < len - n; i++) + fmpz_swap(res + i, res + n + i); + } + +} + +void +fmpz_poly_shift_right(fmpz_poly_t res, const fmpz_poly_t poly, slong n) +{ + if (n == 0) + { + fmpz_poly_set(res, poly); + return; + } + + if (poly->length <= n) + { + fmpz_poly_zero(res); + return; + } + + fmpz_poly_fit_length(res, poly->length - n); + _fmpz_poly_shift_right(res->coeffs, poly->coeffs, poly->length, n); + _fmpz_poly_set_length(res, poly->length - n); +} diff --git a/external/flint-2.4.3/fmpz_poly/signature.c b/external/flint-2.4.3/fmpz_poly/signature.c new file mode 100644 index 0000000..d9305a5 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/signature.c @@ -0,0 +1,143 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void _fmpz_poly_signature(slong * r1, slong * r2, const fmpz * poly, slong len) +{ + fmpz *A, *B, *f, *g, *h, *w; + slong lenA, lenB; + int s, t; + + if (len <= 2) + { + *r1 = (len == 2); + *r2 = 0; + return; + } + + w = _fmpz_vec_init(2 * len + 2); + A = w; + B = w + len; + lenA = len; + lenB = lenA - 1; + f = w + 2 * len - 1; + g = w + 2 * len; + h = w + 2 * len + 1; + + _fmpz_poly_primitive_part(A, poly, lenA); + _fmpz_poly_derivative(B, A, lenA); + _fmpz_poly_primitive_part(B, B, lenB); + + fmpz_one(g); + fmpz_one(h); + + s = 1; + t = (lenA & WORD(1)) ? -s : s; + *r1 = 1; + + while (1) + { + slong delta = lenA - lenB; + int sgnA; + + _fmpz_poly_pseudo_rem_cohen(A, A, lenA, B, lenB); + + lenA = lenB; + FMPZ_VEC_NORM(A, lenA); + + if (lenA == 0) + { + flint_printf("Exception (fmpz_poly_signature). Non-squarefree polynomial detected.\n"); + _fmpz_vec_clear(w, 2 * len + 2); + abort(); + } + + if ((fmpz_sgn(B + (lenB - 1)) > 0) || (delta & WORD(1))) + _fmpz_vec_neg(A, A, lenA); + + sgnA = fmpz_sgn(A + (lenA - 1)); + if (sgnA != s) + { + s = -s; + (*r1)--; + } + if (sgnA != ((lenA & WORD(1)) ? t : -t)) + { + t = -t; + (*r1)++; + } + + if (lenA == 1) + { + *r2 = ((len - 1) - *r1) / 2; + + _fmpz_vec_clear(w, 2 * len + 2); + return; + } + else + { + { + fmpz * temp = A; + A = B; + B = temp; + } + { + slong temp = lenA; + lenA = lenB; + lenB = temp; + } + + if (delta == 1) + { + fmpz_mul(f, g, h); + _fmpz_vec_scalar_divexact_fmpz(B, B, lenB, f); + fmpz_set(g, A + (lenA - 1)); + fmpz_set(h, g); + } + else + { + fmpz_pow_ui(f, h, delta); + fmpz_mul(f, f, g); + _fmpz_vec_scalar_divexact_fmpz(B, B, lenB, f); + fmpz_pow_ui(f, h, delta - 1); + fmpz_pow_ui(g, A + (lenA - 1), delta); + fmpz_divexact(h, g, f); + fmpz_set(g, A + (lenA - 1)); + } + } + } +} + +void fmpz_poly_signature(slong * r1, slong * r2, const fmpz_poly_t poly) +{ + _fmpz_poly_signature(r1, r2, poly->coeffs, poly->length); +} + diff --git a/external/flint-2.4.3/fmpz_poly/sqr.c b/external/flint-2.4.3/fmpz_poly/sqr.c new file mode 100644 index 0000000..ac66f9c --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/sqr.c @@ -0,0 +1,85 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void _fmpz_poly_sqr(fmpz * res, const fmpz * poly, slong len) +{ + mp_size_t limbs; + + if (len < 7) + { + _fmpz_poly_sqr_classical(res, poly, len); + return; + } + + limbs = _fmpz_vec_max_limbs(poly, len); + + if (len < 16 && limbs > 12) + _fmpz_poly_sqr_karatsuba(res, poly, len); + else if (limbs <= 4) + _fmpz_poly_sqr_KS(res, poly, len); + else if (limbs/2048 > len) + _fmpz_poly_sqr_KS(res, poly, len); + else if (limbs*FLINT_BITS*4 < len) + _fmpz_poly_sqr_KS(res, poly, len); + else + _fmpz_poly_mul_SS(res, poly, len, poly, len); +} + +void fmpz_poly_sqr(fmpz_poly_t res, const fmpz_poly_t poly) +{ + slong len = poly->length; + slong rlen; + + if (len == 0) + { + fmpz_poly_zero(res); + return; + } + + rlen = 2 * len - 1; + + if (res == poly) + { + fmpz_poly_t t; + fmpz_poly_init2(t, rlen); + _fmpz_poly_sqr(t->coeffs, poly->coeffs, len); + fmpz_poly_swap(res, t); + fmpz_poly_clear(t); + } + else + { + fmpz_poly_fit_length(res, rlen); + _fmpz_poly_sqr(res->coeffs, poly->coeffs, len); + } + + _fmpz_poly_set_length(res, rlen); +} + diff --git a/external/flint-2.4.3/fmpz_poly/sqr_KS.c b/external/flint-2.4.3/fmpz_poly/sqr_KS.c new file mode 100644 index 0000000..2725e38 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/sqr_KS.c @@ -0,0 +1,111 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void +_fmpz_poly_sqr_KS(fmpz *rop, const fmpz *op, slong len) +{ + const slong in_len = len; + int neg; + slong bits, limbs, loglen; + mp_limb_t *arr, *arr3; + slong sign = 0; + + FMPZ_VEC_NORM(op, len); + + if (!len) + { + if (2 * in_len - 1 > 0) + _fmpz_vec_zero(rop, 2 * in_len - 1); + return; + } + + neg = (fmpz_sgn(op + len - 1) > 0) ? 0 : -1; + + bits = _fmpz_vec_max_bits(op, len); + if (bits < 0) + { + sign = 1; + bits = - bits; + } + + loglen = FLINT_BIT_COUNT(len); + bits = 2 * bits + loglen + sign; + limbs = (bits * len - 1) / FLINT_BITS + 1; + + arr = (mp_limb_t *) flint_calloc(limbs, sizeof(mp_limb_t)); + + _fmpz_poly_bit_pack(arr, op, len, bits, neg); + + arr3 = (mp_limb_t *) flint_malloc((2 * limbs) * sizeof(mp_limb_t)); + + mpn_sqr(arr3, arr, limbs); + + if (sign) + _fmpz_poly_bit_unpack(rop, 2 * len - 1, arr3, bits, 0); + else + _fmpz_poly_bit_unpack_unsigned(rop, 2 * len - 1, arr3, bits); + + if (len < in_len) + _fmpz_vec_zero(rop + (2 * len - 1), 2 * (in_len - len)); + + flint_free(arr); + flint_free(arr3); +} + +void fmpz_poly_sqr_KS(fmpz_poly_t rop, const fmpz_poly_t op) +{ + slong len; + + if (op->length == 0) + { + fmpz_poly_zero(rop); + return; + } + + len = 2 * op->length - 1; + + if (rop == op) + { + fmpz_poly_t t; + fmpz_poly_init2(t, len); + fmpz_poly_sqr_KS(t, op); + fmpz_poly_swap(rop, t); + fmpz_poly_clear(t); + return; + } + + fmpz_poly_fit_length(rop, len); + _fmpz_poly_sqr_KS(rop->coeffs, op->coeffs, op->length); + _fmpz_poly_set_length(rop, len); +} + diff --git a/external/flint-2.4.3/fmpz_poly/sqr_classical.c b/external/flint-2.4.3/fmpz_poly/sqr_classical.c new file mode 100644 index 0000000..7e4b075 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/sqr_classical.c @@ -0,0 +1,87 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +/* Assumes len > 0. */ +void _fmpz_poly_sqr_classical(fmpz *rop, const fmpz *op, slong len) +{ + if (len == 1) /* Special case */ + { + fmpz_mul(rop, op, op); + } + else /* Ordinary case */ + { + slong i; + + _fmpz_vec_scalar_mul_fmpz(rop, op, len, op); + + _fmpz_vec_scalar_mul_fmpz(rop + len, op + 1, len - 1, op + len - 1); + + for (i = 1; i < len - 1; i++) + _fmpz_vec_scalar_addmul_fmpz(rop + i + 1, op + 1, i - 1, op + i); + + for (i = 1; i < 2 * len - 2; i++) + fmpz_mul_ui(rop + i, rop + i, 2); + + for (i = 1; i < len - 1; i++) + fmpz_addmul(rop + 2 * i, op + i, op + i); + } +} + +void fmpz_poly_sqr_classical(fmpz_poly_t rop, const fmpz_poly_t op) +{ + slong len; + + if (op->length == 0) + { + fmpz_poly_zero(rop); + return; + } + + len = 2 * op->length - 1; + + if (rop == op) + { + fmpz_poly_t t; + fmpz_poly_init2(t, len); + _fmpz_poly_sqr_classical(t->coeffs, op->coeffs, op->length); + fmpz_poly_swap(rop, t); + fmpz_poly_clear(t); + } + else + { + fmpz_poly_fit_length(rop, len); + _fmpz_poly_sqr_classical(rop->coeffs, op->coeffs, op->length); + } + + _fmpz_poly_set_length(rop, len); +} + diff --git a/external/flint-2.4.3/fmpz_poly/sqr_karatsuba.c b/external/flint-2.4.3/fmpz_poly/sqr_karatsuba.c new file mode 100644 index 0000000..84cfe85 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/sqr_karatsuba.c @@ -0,0 +1,120 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +/* + For documentation, see fmpz_poly/mul_karatsuba.c + */ + +extern void revbin1(fmpz * out, const fmpz * in, slong len, slong bits); + +extern void revbin2(fmpz * out, const fmpz * in, slong len, slong bits); + +extern void _fmpz_vec_add_rev(fmpz * in1, fmpz * in2, slong bits); + +void _fmpz_poly_sqr_kara_recursive(fmpz * out, fmpz * rev, + fmpz * temp, slong bits) +{ + slong len = (WORD(1) << bits); + slong m = len / 2; + + if (len == 1) + { + fmpz_mul(out, rev, rev); + fmpz_zero(out + 1); + return; + } + + _fmpz_vec_add(temp, rev, rev + m, m); + + _fmpz_poly_sqr_kara_recursive(out, rev, temp + 2 * m, bits - 1); + + _fmpz_poly_sqr_kara_recursive(out + len, temp, temp + 2 * m, bits - 1); + + _fmpz_poly_sqr_kara_recursive(temp, rev + m, temp + 2 * m, bits - 1); + + _fmpz_vec_sub(out + len, out + len, out, len); + _fmpz_vec_sub(out + len, out + len, temp, len); + + _fmpz_vec_add_rev(out, temp, bits); +} + +void _fmpz_poly_sqr_karatsuba(fmpz * res, const fmpz * poly, slong len) +{ + fmpz *rev, *out, *temp; + slong length, loglen = 0; + + if (len == 1) + { + fmpz_mul(res, poly, poly); + return; + } + + while ((WORD(1) << loglen) < len) + loglen++; + length = (WORD(1) << loglen); + + rev = flint_calloc(3 * length, sizeof(fmpz *)); + out = rev + length; + temp = _fmpz_vec_init(2 * length); + + revbin1(rev, poly, len, loglen); + + _fmpz_poly_sqr_kara_recursive(out, rev, temp, loglen); + + _fmpz_vec_zero(res, 2 * len - 1); + revbin2(res, out, 2 * len - 1, loglen + 1); + + _fmpz_vec_clear(temp, 2 * length); + flint_free(rev); +} + +void fmpz_poly_sqr_karatsuba(fmpz_poly_t res, const fmpz_poly_t poly) +{ + slong len; + + if (poly->length == 0) + { + fmpz_poly_zero(res); + return; + } + + len = 2 * poly->length - 1; + + fmpz_poly_fit_length(res, len); + + _fmpz_poly_sqr_karatsuba(res->coeffs, poly->coeffs, poly->length); + + _fmpz_poly_set_length(res, len); +} + diff --git a/external/flint-2.4.3/fmpz_poly/sqrlow.c b/external/flint-2.4.3/fmpz_poly/sqrlow.c new file mode 100644 index 0000000..2cb6648 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/sqrlow.c @@ -0,0 +1,96 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void _fmpz_poly_sqrlow(fmpz * res, const fmpz * poly, slong len, slong n) +{ + mp_size_t limbs; + + if (n < 7) + { + _fmpz_poly_sqrlow_classical(res, poly, len, n); + return; + } + + limbs = _fmpz_vec_max_limbs(poly, len); + + if (n < 16 && limbs > 12) + { + int i; + fmpz *copy; + + copy = flint_malloc(n * sizeof(fmpz)); + for (i = 0; i < len; i++) + copy[i] = poly[i]; + flint_mpn_zero((mp_ptr) copy + len, n - len); + + _fmpz_poly_sqrlow_karatsuba_n(res, copy, n); + + flint_free(copy); + } + else if (limbs <= 4) + _fmpz_poly_sqrlow_KS(res, poly, len, n); + else if (limbs/2048 > len) + _fmpz_poly_sqrlow_KS(res, poly, len, n); + else if (limbs*FLINT_BITS*4 < len) + _fmpz_poly_sqrlow_KS(res, poly, len, n); + else + _fmpz_poly_mullow_SS(res, poly, len, poly, len, n); +} + +void fmpz_poly_sqrlow(fmpz_poly_t res, const fmpz_poly_t poly, slong n) +{ + const slong len = poly->length; + + if (len == 0 || n == 0) + { + fmpz_poly_zero(res); + return; + } + + if (res == poly) + { + fmpz_poly_t t; + fmpz_poly_init2(t, n); + fmpz_poly_sqrlow(t, poly, n); + fmpz_poly_swap(res, t); + fmpz_poly_clear(t); + return; + } + + n = FLINT_MIN(2 * len - 1, n); + + fmpz_poly_fit_length(res, n); + _fmpz_poly_sqrlow(res->coeffs, poly->coeffs, len, n); + _fmpz_poly_set_length(res, n); + _fmpz_poly_normalise(res); +} diff --git a/external/flint-2.4.3/fmpz_poly/sqrlow_KS.c b/external/flint-2.4.3/fmpz_poly/sqrlow_KS.c new file mode 100644 index 0000000..fcad8bf --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/sqrlow_KS.c @@ -0,0 +1,108 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +void _fmpz_poly_sqrlow_KS(fmpz * res, const fmpz * poly, slong len, slong n) +{ + int neg; + slong bits, limbs, loglen, sign = 0; + mp_limb_t *arr_in, *arr_out; + + FMPZ_VEC_NORM(poly, len); + + if (len == 0) + { + _fmpz_vec_zero(res, n); + return; + } + + neg = (fmpz_sgn(poly + len - 1) > 0) ? 0 : -1; + + if (n > 2 * len - 1) + { + _fmpz_vec_zero(res + 2 * len - 1, n - (2 * len - 1)); + n = 2 * len - 1; + } + + bits = _fmpz_vec_max_bits(poly, len); + if (bits < 0) + { + sign = 1; + bits = - bits; + } + + loglen = FLINT_BIT_COUNT(len); + bits = 2 * bits + loglen + sign; + limbs = (bits * len - 1) / FLINT_BITS + 1; + + arr_in = flint_calloc(limbs, sizeof(mp_limb_t)); + arr_out = flint_malloc((2 * limbs) * sizeof(mp_limb_t)); + + _fmpz_poly_bit_pack(arr_in, poly, len, bits, neg); + + mpn_sqr(arr_out, arr_in, limbs); + + if (sign) + _fmpz_poly_bit_unpack(res, n, arr_out, bits, 0); + else + _fmpz_poly_bit_unpack_unsigned(res, n, arr_out, bits); + + flint_free(arr_in); + flint_free(arr_out); +} + +void fmpz_poly_sqrlow_KS(fmpz_poly_t res, const fmpz_poly_t poly, slong n) +{ + const slong len = poly->length; + + if (len == 0 || n == 0) + { + fmpz_poly_zero(res); + return; + } + + if (res == poly) + { + fmpz_poly_t t; + fmpz_poly_init2(t, n); + fmpz_poly_sqrlow_KS(t, poly, n); + fmpz_poly_swap(res, t); + fmpz_poly_clear(t); + return; + } + + fmpz_poly_fit_length(res, n); + _fmpz_poly_sqrlow_KS(res->coeffs, poly->coeffs, len, n); + _fmpz_poly_set_length(res, n); + _fmpz_poly_normalise(res); +} + diff --git a/external/flint-2.4.3/fmpz_poly/sqrlow_classical.c b/external/flint-2.4.3/fmpz_poly/sqrlow_classical.c new file mode 100644 index 0000000..05e7087 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/sqrlow_classical.c @@ -0,0 +1,91 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +/* + Assumes len > 0 and 0 < n <= 2 * len - 1. + */ +void _fmpz_poly_sqrlow_classical(fmpz *rop, const fmpz *op, slong len, slong n) +{ + if (len == 1 || n == 1) /* Special case */ + { + fmpz_mul(rop, op, op); + } + else /* Ordinary case */ + { + slong i; + + _fmpz_vec_scalar_mul_fmpz(rop, op, FLINT_MIN(len, n), op); + + _fmpz_vec_scalar_mul_fmpz(rop + len, op + 1, n - len, op + len - 1); + + for (i = 1; i < len - 1; i++) + _fmpz_vec_scalar_addmul_fmpz(rop + i + 1, + op + 1, FLINT_MIN(i - 1, n - (i + 1)), op + i); + + for (i = 1; i < FLINT_MIN(2 * len - 2, n); i++) + fmpz_mul_ui(rop + i, rop + i, 2); + + for (i = 1; i < FLINT_MIN(len - 1, (n + 1) / 2); i++) + fmpz_addmul(rop + 2 * i, op + i, op + i); + } +} + +void +fmpz_poly_sqrlow_classical(fmpz_poly_t res, const fmpz_poly_t poly, slong n) +{ + slong len = poly->length; + + if (len == 0 || n == 0) + { + fmpz_poly_zero(res); + return; + } + + n = FLINT_MIN(2 * len - 1, n); + + if (res == poly) + { + fmpz_poly_t t; + fmpz_poly_init2(t, n); + _fmpz_poly_sqrlow_classical(t->coeffs, poly->coeffs, len, n); + fmpz_poly_swap(res, t); + fmpz_poly_clear(t); + } + else + { + fmpz_poly_fit_length(res, n); + _fmpz_poly_sqrlow_classical(res->coeffs, poly->coeffs, len, n); + } + + _fmpz_poly_set_length(res, n); + _fmpz_poly_normalise(res); +} + diff --git a/external/flint-2.4.3/fmpz_poly/sqrlow_karatsuba_n.c b/external/flint-2.4.3/fmpz_poly/sqrlow_karatsuba_n.c new file mode 100644 index 0000000..0115ee4 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/sqrlow_karatsuba_n.c @@ -0,0 +1,147 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" + +/* + For documentation, see fmpz_poly/mullow_karatsuba_n.c + */ + +void _fmpz_poly_sqrlow_kara_recursive(fmpz * out, + const fmpz * pol, fmpz * temp, slong len) +{ + slong m1 = len / 2; + slong m2 = len - m1; + int odd = (len & 1); + + if (len <= 6) + { + _fmpz_poly_sqrlow_classical(out, pol, len, len); + return; + } + + _fmpz_vec_add(temp + m2, pol, pol + m1, m1); + if (odd) + fmpz_set(temp + m2 + m1, pol + 2 * m1); + + _fmpz_poly_sqrlow_kara_recursive(temp, temp + m2, temp + 2 * m2, m2); + _fmpz_poly_sqrlow_kara_recursive(temp + m2, pol + m1, temp + 2 * m2, m2); + + _fmpz_poly_sqr_karatsuba(out, pol, m1); + fmpz_zero(out + 2 * m1 - 1); + + _fmpz_vec_sub(temp, temp, out, m2); + _fmpz_vec_sub(temp, temp, temp + m2, m2); + + if (odd) + fmpz_set(out + 2 * m1, temp + m2); + _fmpz_vec_add(out + m1, out + m1, temp, m2); +} + +/* + Assumes poly1 and poly2 are not length 0. + + We almost get away with temporary space of length 2 * len, + but in the recursion we might need 4 * \ceil{len/2}, which + exceeds 2 * len by at most 2. +*/ +void _fmpz_poly_sqrlow_karatsuba_n(fmpz * res, const fmpz * poly, slong n) +{ + fmpz *temp; + slong len, loglen = 0; + + if (n == 1) + { + fmpz_mul(res, poly, poly); + return; + } + + while ((WORD(1) << loglen) < n) + loglen++; + len = (WORD(1) << loglen); + + temp = _fmpz_vec_init(2 * len + 2); + + _fmpz_poly_sqrlow_kara_recursive(res, poly, temp, n); + + _fmpz_vec_clear(temp, 2 * len + 2); +} + +void +fmpz_poly_sqrlow_karatsuba_n(fmpz_poly_t res, const fmpz_poly_t poly, slong n) +{ + const slong len = FLINT_MIN(poly->length, n); + slong i, lenr; + + int clear = 0; + fmpz *copy; + + if (len == 0) + { + fmpz_poly_zero(res); + return; + } + + lenr = 2 * len - 1; + if (n > lenr) + n = lenr; + + if (len >= n) + copy = poly->coeffs; + else + { + copy = flint_malloc(n * sizeof(fmpz)); + for (i = 0; i < len; i++) + copy[i] = poly->coeffs[i]; + flint_mpn_zero((mp_ptr) copy + len, n - len); + clear = 1; + } + + if (res != poly) + { + fmpz_poly_fit_length(res, n); + _fmpz_poly_sqrlow_karatsuba_n(res->coeffs, copy, n); + } + else + { + fmpz_poly_t t; + fmpz_poly_init2(t, n); + _fmpz_poly_sqrlow_karatsuba_n(t->coeffs, copy, n); + fmpz_poly_swap(res, t); + fmpz_poly_clear(t); + } + _fmpz_poly_set_length(res, n); + _fmpz_poly_normalise(res); + + if (clear) + flint_free(copy); +} + diff --git a/external/flint-2.4.3/fmpz_poly/sqrt.c b/external/flint-2.4.3/fmpz_poly/sqrt.c new file mode 100644 index 0000000..4438998 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/sqrt.c @@ -0,0 +1,66 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +int +_fmpz_poly_sqrt(fmpz * res, const fmpz * poly, slong len) +{ + return _fmpz_poly_sqrt_classical(res, poly, len); +} + +int +fmpz_poly_sqrt(fmpz_poly_t b, const fmpz_poly_t a) +{ + slong blen, len = a->length; + int result; + + if (len % 2 == 0) + { + fmpz_poly_zero(b); + return len == 0; + } + + if (b == a) + { + fmpz_poly_t tmp; + fmpz_poly_init(tmp); + result = fmpz_poly_sqrt(tmp, a); + fmpz_poly_swap(b, tmp); + fmpz_poly_clear(tmp); + return result; + } + + blen = len / 2 + 1; + fmpz_poly_fit_length(b, blen); + _fmpz_poly_set_length(b, blen); + result = _fmpz_poly_sqrt(b->coeffs, a->coeffs, len); + if (!result) + _fmpz_poly_set_length(b, 0); + return result; +} diff --git a/external/flint-2.4.3/fmpz_poly/sqrt_classical.c b/external/flint-2.4.3/fmpz_poly/sqrt_classical.c new file mode 100644 index 0000000..8e287a8 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/sqrt_classical.c @@ -0,0 +1,134 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +int +_fmpz_poly_sqrt_classical(fmpz * res, const fmpz * poly, slong len) +{ + slong i, m; + int result; + + /* the degree must be even */ + if (len % 2 == 0) + return 0; + + /* valuation must be even, and then can be reduced to 0 */ + while (fmpz_is_zero(poly)) + { + if (!fmpz_is_zero(poly + 1)) + return 0; + + fmpz_zero(res); + poly += 2; + len -= 2; + res++; + } + + /* check whether a square root exists modulo 2 */ + for (i = 1; i < len; i += 2) + if (!fmpz_is_even(poly + i)) + return 0; + + /* check endpoints */ + if (!fmpz_is_square(poly) || (len > 1 && !fmpz_is_square(poly + len - 1))) + return 0; + + /* square root of leading coefficient */ + m = (len + 1) / 2; + fmpz_sqrt(res + m - 1, poly + len - 1); + result = 1; + + /* do slong divison style 'square root with remainder' from top to bottom */ + if (len > 1) + { + fmpz_t t, u; + fmpz * r; + + fmpz_init(t); + fmpz_init(u); + r = _fmpz_vec_init(len); + _fmpz_vec_set(r, poly, len); + fmpz_mul_ui(u, res + m - 1, 2); + + for (i = 1; i < m; i++) + { + fmpz_fdiv_qr(res + m - i - 1, t, r + len - i - 1, u); + if (!fmpz_is_zero(t)) + { + result = 0; + break; + } + + fmpz_mul_si(t, res + m - i - 1, -2); + _fmpz_vec_scalar_addmul_fmpz(r + len - 2*i, res + m - i, i - 1, t); + fmpz_submul(r + len - 2*i - 1, res + m - i - 1, res + m - i - 1); + } + + for (i = m; i < len && result; i++) + if (!fmpz_is_zero(r + len - 1 - i)) + result = 0; + + _fmpz_vec_clear(r, len); + fmpz_clear(t); + fmpz_clear(u); + } + + return result; +} + +int +fmpz_poly_sqrt_classical(fmpz_poly_t b, const fmpz_poly_t a) +{ + slong blen, len = a->length; + int result; + + if (len % 2 == 0) + { + fmpz_poly_zero(b); + return len == 0; + } + + if (b == a) + { + fmpz_poly_t tmp; + fmpz_poly_init(tmp); + result = fmpz_poly_sqrt_classical(tmp, a); + fmpz_poly_swap(b, tmp); + fmpz_poly_clear(tmp); + return result; + } + + blen = len / 2 + 1; + fmpz_poly_fit_length(b, blen); + _fmpz_poly_set_length(b, blen); + result = _fmpz_poly_sqrt_classical(b->coeffs, a->coeffs, len); + if (!result) + _fmpz_poly_set_length(b, 0); + return result; +} diff --git a/external/flint-2.4.3/fmpz_poly/sub.c b/external/flint-2.4.3/fmpz_poly/sub.c new file mode 100644 index 0000000..37f5c60 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/sub.c @@ -0,0 +1,62 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +void +_fmpz_poly_sub(fmpz * res, const fmpz * poly1, slong len1, const fmpz * poly2, + slong len2) +{ + slong i, min = FLINT_MIN(len1, len2); + + for (i = 0; i < min; i++) /* subtract up to the length of the shorter poly */ + fmpz_sub(res + i, poly1 + i, poly2 + i); + + if (poly1 != res) /* copy any remaining coefficients from poly1 */ + for (i = min; i < len1; i++) + fmpz_set(res + i, poly1 + i); + + /* careful, it is *always* necessary to negate coeffs from poly2, even if this is already res */ + for (i = min; i < len2; i++) + fmpz_neg(res + i, poly2 + i); +} + +void +fmpz_poly_sub(fmpz_poly_t res, const fmpz_poly_t poly1, + const fmpz_poly_t poly2) +{ + slong max = FLINT_MAX(poly1->length, poly2->length); + + fmpz_poly_fit_length(res, max); + + _fmpz_poly_sub(res->coeffs, poly1->coeffs, poly1->length, poly2->coeffs, + poly2->length); + + _fmpz_poly_set_length(res, max); + _fmpz_poly_normalise(res); /* there may have been cancellation */ +} diff --git a/external/flint-2.4.3/fmpz_poly/swap.c b/external/flint-2.4.3/fmpz_poly/swap.c new file mode 100644 index 0000000..b7bfa28 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/swap.c @@ -0,0 +1,51 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +void +fmpz_poly_swap(fmpz_poly_t poly1, fmpz_poly_t poly2) +{ + if (poly1 != poly2) + { + slong temp; + fmpz *temp_c; + + temp = poly1->length; + poly1->length = poly2->length; + poly2->length = temp; + + temp = poly1->alloc; + poly1->alloc = poly2->alloc; + poly2->alloc = temp; + + temp_c = poly1->coeffs; + poly1->coeffs = poly2->coeffs; + poly2->coeffs = temp_c; + } +} diff --git a/external/flint-2.4.3/fmpz_poly/taylor_shift.c b/external/flint-2.4.3/fmpz_poly/taylor_shift.c new file mode 100644 index 0000000..fe3a5bb --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/taylor_shift.c @@ -0,0 +1,47 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +void +_fmpz_poly_taylor_shift(fmpz * poly, const fmpz_t c, slong n) +{ + if (n <= 256) + _fmpz_poly_taylor_shift_horner(poly, c, n); + else + _fmpz_poly_taylor_shift_divconquer(poly, c, n); +} + +void +fmpz_poly_taylor_shift(fmpz_poly_t g, const fmpz_poly_t f, const fmpz_t c) +{ + if (f != g) + fmpz_poly_set(g, f); + + _fmpz_poly_taylor_shift(g->coeffs, c, g->length); +} diff --git a/external/flint-2.4.3/fmpz_poly/taylor_shift_divconquer.c b/external/flint-2.4.3/fmpz_poly/taylor_shift_divconquer.c new file mode 100644 index 0000000..379e033 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/taylor_shift_divconquer.c @@ -0,0 +1,60 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "nmod_poly.h" + +void +_fmpz_poly_taylor_shift_divconquer(fmpz * poly, const fmpz_t c, slong len) +{ + fmpz d[2]; + + if (len <= 1 || fmpz_is_zero(c)) + return; + + if (len == 2) + { + fmpz_addmul(poly, poly + 1, c); + return; + } + + d[0] = *c; + d[1] = 1; + + _fmpz_poly_compose_divconquer(poly, poly, len, d, 2); +} + +void +fmpz_poly_taylor_shift_divconquer(fmpz_poly_t g, const fmpz_poly_t f, + const fmpz_t c) +{ + if (f != g) + fmpz_poly_set(g, f); + + _fmpz_poly_taylor_shift_divconquer(g->coeffs, c, g->length); +} diff --git a/external/flint-2.4.3/fmpz_poly/taylor_shift_horner.c b/external/flint-2.4.3/fmpz_poly/taylor_shift_horner.c new file mode 100644 index 0000000..55e5f14 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/taylor_shift_horner.c @@ -0,0 +1,64 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +void +_fmpz_poly_taylor_shift_horner(fmpz * poly, const fmpz_t c, slong n) +{ + slong i, j; + + if (*c == WORD(1)) + { + for (i = n - 2; i >= 0; i--) + for (j = i; j < n - 1; j++) + fmpz_add(poly + j, poly + j, poly + j + 1); + } + else if (*c == WORD(-1)) + { + for (i = n - 2; i >= 0; i--) + for (j = i; j < n - 1; j++) + fmpz_sub(poly + j, poly + j, poly + j + 1); + } + else if (*c != WORD(0)) + { + for (i = n - 2; i >= 0; i--) + for (j = i; j < n - 1; j++) + fmpz_addmul(poly + j, poly + j + 1, c); + } +} + +void +fmpz_poly_taylor_shift_horner(fmpz_poly_t g, const fmpz_poly_t f, + const fmpz_t c) +{ + if (f != g) + fmpz_poly_set(g, f); + + _fmpz_poly_taylor_shift_horner(g->coeffs, c, g->length); +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-2norm_normalised_bits.c b/external/flint-2.4.3/fmpz_poly/test/t-2norm_normalised_bits.c new file mode 100644 index 0000000..990a663 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-2norm_normalised_bits.c @@ -0,0 +1,89 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("2norm_normalised_bits...."); + fflush(stdout); + + + + /* Check aliasing */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c; + fmpz_poly_t f; + mp_bitcnt_t b1, b2; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + fmpz_poly_init(f); + do { + fmpz_poly_randtest(f, state, n_randint(state, 100) + 1, 200); + } while (f->length == 0); + + fmpz_poly_2norm(a, f); + fmpz_abs(b, fmpz_poly_lead(f)); + fmpz_fdiv_q(c, a, b); + b1 = fmpz_bits(c); + + b2 = _fmpz_poly_2norm_normalised_bits(f->coeffs, f->length); + + result = (b1 == b2 || b1 + 1 == b2); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_print(a), flint_printf("\n\n"); + fmpz_print(b), flint_printf("\n\n"); + fmpz_print(c), flint_printf("\n\n"); + flint_printf("b1 = %wd, b2 = %wd\n", b1, b2); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + fmpz_poly_clear(f); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-CRT_ui.c b/external/flint-2.4.3/fmpz_poly/test/t-CRT_ui.c new file mode 100644 index 0000000..ddfd237 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-CRT_ui.c @@ -0,0 +1,118 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 William Hart and David Harvey + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "nmod_poly.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + flint_printf("CRT_ui...."); + fflush(stdout); + + + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + slong bits, prime_bits, length, num_primes, j; + fmpz_t mod; + fmpz_poly_t A, B, C; + nmod_poly_t Amod; + mp_limb_t primes[1000]; + + bits = n_randint(state, 500) + 1; + length = n_randint(state, 30) + 1; + prime_bits = 1 + n_randint(state, FLINT_BITS - 1); + + fmpz_poly_init(A); + fmpz_poly_init(B); + fmpz_poly_init(C); + + fmpz_poly_randtest(A, state, length, bits); + + fmpz_init(mod); + num_primes = 0; + primes[0] = n_nextprime(UWORD(1) << prime_bits, 0); + fmpz_set_ui(mod, primes[0]); + + /* + 1 for sign */ + while (fmpz_bits(mod) <= bits + 1) + { + primes[num_primes + 1] = n_nextprime(primes[num_primes], 0); + fmpz_mul_ui(mod, mod, primes[num_primes + 1]); + num_primes++; + } + + num_primes++; + + nmod_poly_init(Amod, primes[0]); + fmpz_poly_get_nmod_poly(Amod, A); + fmpz_poly_set_nmod_poly(B, Amod); + fmpz_set_ui(mod, primes[0]); + + for (j = 1; j < num_primes; j++) + { + nmod_poly_clear(Amod); + nmod_poly_init(Amod, primes[j]); + fmpz_poly_get_nmod_poly(Amod, A); + fmpz_poly_CRT_ui(B, B, mod, Amod, 1); + fmpz_mul_ui(mod, mod, primes[j]); + } + + if (!fmpz_poly_equal(B, A)) + { + flint_printf("FAIL!\n"); + flint_printf("primes: "); + for (j = 0; j < num_primes; j++) + flint_printf("%wu ", primes[j]); + flint_printf("\nA: \n"); + fmpz_poly_print(A); + flint_printf("\nB: \n"); + fmpz_poly_print(B); + flint_printf("\n"); + abort(); + } + + nmod_poly_clear(Amod); + fmpz_poly_clear(A); + fmpz_poly_clear(B); + fmpz_poly_clear(C); + fmpz_clear(mod); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-CRT_ui_unsigned.c b/external/flint-2.4.3/fmpz_poly/test/t-CRT_ui_unsigned.c new file mode 100644 index 0000000..9336ab7 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-CRT_ui_unsigned.c @@ -0,0 +1,117 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 William Hart and David Harvey + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "nmod_poly.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + flint_printf("CRT_ui_unsigned...."); + fflush(stdout); + + + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + slong bits, prime_bits, length, num_primes, j; + fmpz_t mod; + fmpz_poly_t A, B, C; + nmod_poly_t Amod; + mp_limb_t primes[1000]; + + bits = n_randint(state, 500) + 1; + length = n_randint(state, 30) + 1; + prime_bits = 1 + n_randint(state, FLINT_BITS - 1); + + fmpz_poly_init(A); + fmpz_poly_init(B); + fmpz_poly_init(C); + + fmpz_poly_randtest_unsigned(A, state, length, bits); + + fmpz_init(mod); + num_primes = 0; + primes[0] = n_nextprime(UWORD(1) << prime_bits, 0); + fmpz_set_ui(mod, primes[0]); + + while (fmpz_bits(mod) <= bits) + { + primes[num_primes + 1] = n_nextprime(primes[num_primes], 0); + fmpz_mul_ui(mod, mod, primes[num_primes + 1]); + num_primes++; + } + + num_primes++; + + nmod_poly_init(Amod, primes[0]); + fmpz_poly_get_nmod_poly(Amod, A); + fmpz_poly_set_nmod_poly_unsigned(B, Amod); + fmpz_set_ui(mod, primes[0]); + + for (j = 1; j < num_primes; j++) + { + nmod_poly_clear(Amod); + nmod_poly_init(Amod, primes[j]); + fmpz_poly_get_nmod_poly(Amod, A); + fmpz_poly_CRT_ui(B, B, mod, Amod, 0); + fmpz_mul_ui(mod, mod, primes[j]); + } + + if (!fmpz_poly_equal(B, A)) + { + flint_printf("FAIL!\n"); + flint_printf("primes: "); + for (j = 0; j < num_primes; j++) + flint_printf("%wu ", primes[j]); + flint_printf("\nA: \n"); + fmpz_poly_print(A); + flint_printf("\nB: \n"); + fmpz_poly_print(B); + flint_printf("\n"); + abort(); + } + + nmod_poly_clear(Amod); + fmpz_poly_clear(A); + fmpz_poly_clear(B); + fmpz_poly_clear(C); + fmpz_clear(mod); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-add.c b/external/flint-2.4.3/fmpz_poly/test/t-add.c new file mode 100644 index 0000000..61ca151 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-add.c @@ -0,0 +1,108 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("add...."); + fflush(stdout); + + + + /* Check aliasing of a and c */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(a, state, n_randint(state, 100), 200); + fmpz_poly_randtest(b, state, n_randint(state, 100), 200); + + fmpz_poly_add(c, a, b); + fmpz_poly_add(a, a, b); + + result = (fmpz_poly_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + fmpz_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + /* Check aliasing of b and c */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(a, state, n_randint(state, 100), 200); + fmpz_poly_randtest(b, state, n_randint(state, 100), 200); + + fmpz_poly_add(c, a, b); + fmpz_poly_add(b, a, b); + + result = (fmpz_poly_equal(b, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + fmpz_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-bit_pack.c b/external/flint-2.4.3/fmpz_poly/test/t-bit_pack.c new file mode 100644 index 0000000..fca4abf --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-bit_pack.c @@ -0,0 +1,206 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("bit_pack/bit_unpack...."); + fflush(stdout); + + + + for (i = 0; i < 2000 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b; + + slong length = n_randint(state, 100) + 1; + mp_bitcnt_t bits = n_randint(state, 300) + 2; + mp_ptr arr = (mp_ptr) flint_calloc((length * bits - 1) / FLINT_BITS + 1, + sizeof(mp_limb_t)); + int negate; + + fmpz_poly_init(a); + fmpz_poly_init(b); + + /* -1 bit to handle signs */ + fmpz_poly_randtest_not_zero(a, state, length, bits - 1); + + negate = fmpz_sgn(a->coeffs + a->length - 1); + if (negate > 0) + negate = 0; + + _fmpz_poly_bit_pack(arr, a->coeffs, a->length, bits, negate); + fmpz_poly_fit_length(b, a->length); + _fmpz_poly_bit_unpack(b->coeffs, a->length, arr, bits, negate); + _fmpz_poly_set_length(b, a->length); + + result = (fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + flint_free(arr); + fmpz_poly_clear(a); + fmpz_poly_clear(b); + } + + for (i = 0; i < 2000 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b; + + slong length = n_randint(state, 100) + 1; + mp_bitcnt_t bits = n_randint(state, 300) + 1; + mp_ptr arr = (mp_ptr) flint_calloc((length * bits - 1) / FLINT_BITS + 1, + sizeof(mp_limb_t)); + + fmpz_poly_init(a); + fmpz_poly_init(b); + + do + fmpz_poly_randtest_unsigned(a, state, length, bits); + while (a->length == 0); + + _fmpz_poly_bit_pack(arr, a->coeffs, a->length, bits, 0); + fmpz_poly_fit_length(b, a->length); + _fmpz_poly_bit_unpack_unsigned(b->coeffs, a->length, arr, bits); + _fmpz_poly_set_length(b, a->length); + + result = (fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + flint_free(arr); + fmpz_poly_clear(a); + fmpz_poly_clear(b); + } + + /* Test fmpz functions */ + for (i = 0; i < 2000 * flint_test_multiplier(); i++) + { + fmpz_t f; + fmpz_poly_t A, B; + slong b; + + fmpz_init(f); + fmpz_poly_init(A); + fmpz_poly_init(B); + + fmpz_poly_randtest(A, state, 1+n_randint(state,100), + 1+n_randint(state,300)); + + b = FLINT_ABS(fmpz_poly_max_bits(A)) + 1; + + fmpz_poly_bit_pack(f, A, b); + fmpz_poly_bit_unpack(B, f, b); + + if (!fmpz_poly_equal(A, B)) + { + mpz_t zz; + flint_printf("FAIL:\n"); + flint_printf("BITS: %wd (signed)\n", b); + flint_printf("INPUT: "); + fmpz_poly_print_pretty(A, "x"); + flint_printf("\n"); + mpz_init(zz); fmpz_get_mpz(zz, f); + flint_printf("PACKED: "); + mpz_out_str(stdout, 2, zz); + flint_printf("\n"); + flint_printf("OUTPUT: "); + fmpz_poly_print_pretty(B, "x"); + flint_printf("\n\n"); + abort(); + } + + fmpz_clear(f); + fmpz_poly_clear(A); + fmpz_poly_clear(B); + } + + for (i = 0; i < 2000 * flint_test_multiplier(); i++) + { + fmpz_t f; + fmpz_poly_t A, B; + slong b; + + fmpz_init(f); + fmpz_poly_init(A); + fmpz_poly_init(B); + + fmpz_poly_randtest_unsigned(A, state, 1+n_randint(state,100), + 1+n_randint(state,300)); + + b = FLINT_ABS(fmpz_poly_max_bits(A)); + + fmpz_poly_bit_pack(f, A, b); + fmpz_poly_bit_unpack_unsigned(B, f, b); + + if (!fmpz_poly_equal(A, B)) + { + mpz_t zz; + flint_printf("FAIL:\n"); + flint_printf("BITS: %wd (unsigned)\n", b); + flint_printf("INPUT: "); + fmpz_poly_print_pretty(A, "x"); + flint_printf("\n"); + mpz_init(zz); fmpz_get_mpz(zz, f); + flint_printf("PACKED: "); + mpz_out_str(stdout, 2, zz); + flint_printf("\n"); + flint_printf("OUTPUT: "); + fmpz_poly_print_pretty(B, "x"); + flint_printf("\n\n"); + abort(); + } + + fmpz_clear(f); + fmpz_poly_clear(A); + fmpz_poly_clear(B); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-bound_roots.c b/external/flint-2.4.3/fmpz_poly/test/t-bound_roots.c new file mode 100644 index 0000000..20c8e11 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-bound_roots.c @@ -0,0 +1,112 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + slong iter; + FLINT_TEST_INIT(state); + + flint_printf("bound_roots...."); + fflush(stdout); + + + + for (iter = 0; iter < 10000 * flint_test_multiplier(); iter++) + { + fmpz_poly_t f, g; + fmpz_t t, p, q, bound, nbound; + slong i, num_roots; + + fmpz_init(t); + fmpz_init(p); + fmpz_init(q); + fmpz_init(bound); + fmpz_init(nbound); + fmpz_poly_init(f); + fmpz_poly_init(g); + + /* start with a constant */ + fmpz_poly_randtest(f, state, 1, 1 + n_randint(state, 200)); + fmpz_zero(bound); + + num_roots = n_randint(state, 10); + if (fmpz_poly_is_zero(f)) + num_roots = 0; + + for (i = 0; i < num_roots; i++) + { + fmpz_randtest(p, state, 1 + n_randint(state, 200)); + fmpz_randtest_not_zero(q, state, 1 + n_randint(state, 200)); + + fmpz_abs(p, p); + fmpz_abs(q, q); + + fmpz_cdiv_q(t, p, q); + if (fmpz_cmp(t, bound) > 0) + fmpz_set(bound, t); + + if (n_randint(state, 2)) + fmpz_neg(p, p); + + fmpz_poly_set_coeff_fmpz(g, 0, p); + fmpz_poly_set_coeff_fmpz(g, 1, q); + + fmpz_poly_mul(f, f, g); + } + + fmpz_poly_bound_roots(nbound, f); + + if (fmpz_cmp(nbound, bound) < 0) + { + flint_printf("FAIL\n"); + flint_printf("f = "); fmpz_poly_print(f); flint_printf("\n\n"); + flint_printf("bound = "); fmpz_print(bound); flint_printf("\n\n"); + flint_printf("computed bound = "); fmpz_print(nbound); flint_printf("\n\n"); + abort(); + } + + fmpz_clear(t); + fmpz_clear(p); + fmpz_clear(q); + fmpz_clear(bound); + fmpz_clear(nbound); + fmpz_poly_clear(f); + fmpz_poly_clear(g); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-compose.c b/external/flint-2.4.3/fmpz_poly/test/t-compose.c new file mode 100644 index 0000000..23314c7 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-compose.c @@ -0,0 +1,188 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("compose...."); + fflush(stdout); + + + + /* Bill's bug */ + { + fmpz_poly_t f, g, h, s, t; + slong k; + + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_poly_init(h); + fmpz_poly_init(s); + fmpz_poly_init(t); + + fmpz_poly_set_str(g, "21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6"); + fmpz_poly_set_str(h, "8 -2411740686 -274861162464 -4294966273 -35167058005888 4261511676 -1 8589869056 -70334401183747"); + + fmpz_poly_set_ui(t, 1); + for (k = 0; k < g->length; k++) + { + fmpz_poly_scalar_addmul_fmpz(s, t, g->coeffs + k); + fmpz_poly_mul(t, t, h); + } + + fmpz_poly_compose(f, g, h); + + result = (fmpz_poly_equal(f, s)); + if (!result) + { + flint_printf("FAIL (Bill's bug):\n"); + flint_printf("g = "), fmpz_poly_print(g), flint_printf("\n\n"); + flint_printf("h = "), fmpz_poly_print(h), flint_printf("\n\n"); + flint_printf("f = "), fmpz_poly_print(f), flint_printf("\n\n"); + flint_printf("s = "), fmpz_poly_print(s), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(f); + fmpz_poly_clear(g); + fmpz_poly_clear(h); + fmpz_poly_clear(s); + fmpz_poly_clear(t); + } + + /* Check aliasing of the first argument */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + fmpz_poly_t f, g, h; + + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_poly_init(h); + fmpz_poly_randtest(g, state, n_randint(state, 40), 80); + fmpz_poly_randtest(h, state, n_randint(state, 20), 50); + + fmpz_poly_compose(f, g, h); + fmpz_poly_compose(g, g, h); + + result = (fmpz_poly_equal(f, g)); + if (!result) + { + flint_printf("FAIL (aliasing 1):\n"); + fmpz_poly_print(f), flint_printf("\n\n"); + fmpz_poly_print(g), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(f); + fmpz_poly_clear(g); + fmpz_poly_clear(h); + } + + /* Check aliasing of the second argument */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + fmpz_poly_t f, g, h; + + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_poly_init(h); + fmpz_poly_randtest(g, state, n_randint(state, 40), 80); + fmpz_poly_randtest(h, state, n_randint(state, 20), 50); + + fmpz_poly_compose(f, g, h); + fmpz_poly_compose(h, g, h); + + result = (fmpz_poly_equal(f, h)); + if (!result) + { + flint_printf("FAIL (aliasing 2):\n"); + fmpz_poly_print(f), flint_printf("\n\n"); + fmpz_poly_print(h), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(f); + fmpz_poly_clear(g); + fmpz_poly_clear(h); + } + + /* Compare with the naive method for g(h(t)) */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + fmpz_poly_t f, g, h, s, t; + slong k; + + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_poly_init(h); + fmpz_poly_init(s); + fmpz_poly_init(t); + fmpz_poly_randtest(g, state, n_randint(state, 40), 80); + fmpz_poly_randtest(h, state, n_randint(state, 20), 50); + + fmpz_poly_set_ui(t, 1); + for (k = 0; k < g->length; k++) + { + fmpz_poly_scalar_addmul_fmpz(s, t, g->coeffs + k); + fmpz_poly_mul(t, t, h); + } + + fmpz_poly_compose(f, g, h); + + result = (fmpz_poly_equal(f, s)); + if (!result) + { + flint_printf("FAIL (comparison):\n"); + flint_printf("g = "), fmpz_poly_print(g), flint_printf("\n\n"); + flint_printf("h = "), fmpz_poly_print(h), flint_printf("\n\n"); + flint_printf("f = "), fmpz_poly_print(f), flint_printf("\n\n"); + flint_printf("s = "), fmpz_poly_print(s), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(f); + fmpz_poly_clear(g); + fmpz_poly_clear(h); + fmpz_poly_clear(s); + fmpz_poly_clear(t); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-compose_divconquer.c b/external/flint-2.4.3/fmpz_poly/test/t-compose_divconquer.c new file mode 100644 index 0000000..cf4e3dc --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-compose_divconquer.c @@ -0,0 +1,136 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("compose_divconquer...."); + fflush(stdout); + + + + /* Check aliasing of the first argument */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + fmpz_poly_t f, g, h; + + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_poly_init(h); + fmpz_poly_randtest(g, state, n_randint(state, 50), 100); + fmpz_poly_randtest(h, state, n_randint(state, 20), 50); + + fmpz_poly_compose_divconquer(f, g, h); + fmpz_poly_compose_divconquer(g, g, h); + + result = (fmpz_poly_equal(f, g)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(f), flint_printf("\n\n"); + fmpz_poly_print(g), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(f); + fmpz_poly_clear(g); + fmpz_poly_clear(h); + } + + /* Check aliasing of the second argument */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + fmpz_poly_t f, g, h; + + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_poly_init(h); + fmpz_poly_randtest(g, state, n_randint(state, 50), 100); + fmpz_poly_randtest(h, state, n_randint(state, 20), 50); + + fmpz_poly_compose_divconquer(f, g, h); + fmpz_poly_compose_divconquer(h, g, h); + + result = (fmpz_poly_equal(f, h)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(f), flint_printf("\n\n"); + fmpz_poly_print(h), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(f); + fmpz_poly_clear(g); + fmpz_poly_clear(h); + } + + /* Compare with the default method */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + fmpz_poly_t f1, f2, g, h; + + fmpz_poly_init(f1); + fmpz_poly_init(f2); + fmpz_poly_init(g); + fmpz_poly_init(h); + fmpz_poly_randtest(g, state, n_randint(state, 50), 100); + fmpz_poly_randtest(h, state, n_randint(state, 20), 50); + + fmpz_poly_compose_divconquer(f1, g, h); + fmpz_poly_compose(f2, g, h); + + result = (fmpz_poly_equal(f1, f2)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(f1), flint_printf("\n\n"); + fmpz_poly_print(f2), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(f1); + fmpz_poly_clear(f2); + fmpz_poly_clear(g); + fmpz_poly_clear(h); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-compose_horner.c b/external/flint-2.4.3/fmpz_poly/test/t-compose_horner.c new file mode 100644 index 0000000..9c02ce4 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-compose_horner.c @@ -0,0 +1,136 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("compose_horner...."); + fflush(stdout); + + + + /* Check aliasing of the first argument */ + for (i = 0; i < 8 * flint_test_multiplier(); i++) + { + fmpz_poly_t f, g, h; + + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_poly_init(h); + fmpz_poly_randtest(g, state, n_randint(state, 40), 80); + fmpz_poly_randtest(h, state, n_randint(state, 20), 50); + + fmpz_poly_compose_horner(f, g, h); + fmpz_poly_compose_horner(g, g, h); + + result = (fmpz_poly_equal(f, g)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(f), flint_printf("\n\n"); + fmpz_poly_print(g), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(f); + fmpz_poly_clear(g); + fmpz_poly_clear(h); + } + + /* Check aliasing of the second argument */ + for (i = 0; i < 8 * flint_test_multiplier(); i++) + { + fmpz_poly_t f, g, h; + + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_poly_init(h); + fmpz_poly_randtest(g, state, n_randint(state, 40), 80); + fmpz_poly_randtest(h, state, n_randint(state, 20), 50); + + fmpz_poly_compose_horner(f, g, h); + fmpz_poly_compose_horner(h, g, h); + + result = (fmpz_poly_equal(f, h)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(f), flint_printf("\n\n"); + fmpz_poly_print(h), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(f); + fmpz_poly_clear(g); + fmpz_poly_clear(h); + } + + /* Compare with the default method */ + for (i = 0; i < 8 * flint_test_multiplier(); i++) + { + fmpz_poly_t f1, f2, g, h; + + fmpz_poly_init(f1); + fmpz_poly_init(f2); + fmpz_poly_init(g); + fmpz_poly_init(h); + fmpz_poly_randtest(g, state, n_randint(state, 40), 80); + fmpz_poly_randtest(h, state, n_randint(state, 20), 50); + + fmpz_poly_compose_horner(f1, g, h); + fmpz_poly_compose(f2, g, h); + + result = (fmpz_poly_equal(f1, f2)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(f1), flint_printf("\n\n"); + fmpz_poly_print(f2), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(f1); + fmpz_poly_clear(f2); + fmpz_poly_clear(g); + fmpz_poly_clear(h); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-compose_series.c b/external/flint-2.4.3/fmpz_poly/test/t-compose_series.c new file mode 100644 index 0000000..fdb6691 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-compose_series.c @@ -0,0 +1,152 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("compose_series...."); + fflush(stdout); + + + + /* Check aliasing of the first argument */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + fmpz_poly_t f, g, h; + slong n; + + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_poly_init(h); + fmpz_poly_randtest(g, state, n_randint(state, 40), 80); + fmpz_poly_randtest(h, state, n_randint(state, 20), 50); + fmpz_poly_set_coeff_ui(h, 0, 0); + n = n_randint(state, 20); + + fmpz_poly_compose_series(f, g, h, n); + fmpz_poly_compose_series(g, g, h, n); + + result = (fmpz_poly_equal(f, g)); + if (!result) + { + flint_printf("FAIL (aliasing 1):\n"); + fmpz_poly_print(f), flint_printf("\n\n"); + fmpz_poly_print(g), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(f); + fmpz_poly_clear(g); + fmpz_poly_clear(h); + } + + /* Check aliasing of the second argument */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + fmpz_poly_t f, g, h; + slong n; + + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_poly_init(h); + fmpz_poly_randtest(g, state, n_randint(state, 40), 80); + fmpz_poly_randtest(h, state, n_randint(state, 20), 50); + fmpz_poly_set_coeff_ui(h, 0, 0); + n = n_randint(state, 20); + + fmpz_poly_compose_series(f, g, h, n); + fmpz_poly_compose_series(h, g, h, n); + + result = (fmpz_poly_equal(f, h)); + if (!result) + { + flint_printf("FAIL (aliasing 2):\n"); + fmpz_poly_print(f), flint_printf("\n\n"); + fmpz_poly_print(h), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(f); + fmpz_poly_clear(g); + fmpz_poly_clear(h); + } + + /* Compare with compose */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + fmpz_poly_t f, g, h, s, t; + slong n; + + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_poly_init(h); + fmpz_poly_init(s); + fmpz_poly_init(t); + fmpz_poly_randtest(g, state, n_randint(state, 40), 80); + fmpz_poly_randtest(h, state, n_randint(state, 20), 50); + fmpz_poly_set_coeff_ui(h, 0, 0); + n = n_randint(state, 10); + + fmpz_poly_compose(s, g, h); + fmpz_poly_truncate(s, n); + fmpz_poly_compose_series(f, g, h, n); + + result = (fmpz_poly_equal(f, s)); + if (!result) + { + flint_printf("FAIL (comparison):\n"); + flint_printf("n = %wd\n", n); + flint_printf("g = "), fmpz_poly_print(g), flint_printf("\n\n"); + flint_printf("h = "), fmpz_poly_print(h), flint_printf("\n\n"); + flint_printf("f = "), fmpz_poly_print(f), flint_printf("\n\n"); + flint_printf("s = "), fmpz_poly_print(s), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(f); + fmpz_poly_clear(g); + fmpz_poly_clear(h); + fmpz_poly_clear(s); + fmpz_poly_clear(t); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-compose_series_brent_kung.c b/external/flint-2.4.3/fmpz_poly/test/t-compose_series_brent_kung.c new file mode 100644 index 0000000..903df30 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-compose_series_brent_kung.c @@ -0,0 +1,151 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("compose_series_brent_kung...."); + fflush(stdout); + + + + /* Check aliasing of the first argument */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + fmpz_poly_t f, g, h; + slong n; + + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_poly_init(h); + fmpz_poly_randtest(g, state, n_randint(state, 40), 80); + fmpz_poly_randtest(h, state, n_randint(state, 20), 50); + fmpz_poly_set_coeff_ui(h, 0, 0); + n = n_randint(state, 20); + + fmpz_poly_compose_series_brent_kung(f, g, h, n); + fmpz_poly_compose_series_brent_kung(g, g, h, n); + + result = (fmpz_poly_equal(f, g)); + if (!result) + { + flint_printf("FAIL (aliasing 1):\n"); + fmpz_poly_print(f), flint_printf("\n\n"); + fmpz_poly_print(g), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(f); + fmpz_poly_clear(g); + fmpz_poly_clear(h); + } + + /* Check aliasing of the second argument */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + fmpz_poly_t f, g, h; + slong n; + + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_poly_init(h); + fmpz_poly_randtest(g, state, n_randint(state, 40), 80); + fmpz_poly_randtest(h, state, n_randint(state, 20), 50); + fmpz_poly_set_coeff_ui(h, 0, 0); + n = n_randint(state, 20); + + fmpz_poly_compose_series_brent_kung(f, g, h, n); + fmpz_poly_compose_series_brent_kung(h, g, h, n); + + result = (fmpz_poly_equal(f, h)); + if (!result) + { + flint_printf("FAIL (aliasing 2):\n"); + fmpz_poly_print(f), flint_printf("\n\n"); + fmpz_poly_print(h), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(f); + fmpz_poly_clear(g); + fmpz_poly_clear(h); + } + + /* Compare with Horner */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t f, g, h, s, t; + slong n; + + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_poly_init(h); + fmpz_poly_init(s); + fmpz_poly_init(t); + fmpz_poly_randtest(g, state, n_randint(state, 50), n_randint(state, 100)); + fmpz_poly_randtest(h, state, n_randint(state, 50), n_randint(state, 100)); + fmpz_poly_set_coeff_ui(h, 0, 0); + n = n_randint(state, 50); + + fmpz_poly_compose_series_brent_kung(s, g, h, n); + fmpz_poly_compose_series_horner(f, g, h, n); + + result = (fmpz_poly_equal(f, s)); + if (!result) + { + flint_printf("FAIL (comparison):\n"); + flint_printf("n = %wd\n", n); + flint_printf("g = "), fmpz_poly_print(g), flint_printf("\n\n"); + flint_printf("h = "), fmpz_poly_print(h), flint_printf("\n\n"); + flint_printf("f = "), fmpz_poly_print(f), flint_printf("\n\n"); + flint_printf("s = "), fmpz_poly_print(s), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(f); + fmpz_poly_clear(g); + fmpz_poly_clear(h); + fmpz_poly_clear(s); + fmpz_poly_clear(t); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-compose_series_horner.c b/external/flint-2.4.3/fmpz_poly/test/t-compose_series_horner.c new file mode 100644 index 0000000..ddc332b --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-compose_series_horner.c @@ -0,0 +1,152 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("compose_series_horner...."); + fflush(stdout); + + + + /* Check aliasing of the first argument */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + fmpz_poly_t f, g, h; + slong n; + + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_poly_init(h); + fmpz_poly_randtest(g, state, n_randint(state, 40), 80); + fmpz_poly_randtest(h, state, n_randint(state, 20), 50); + fmpz_poly_set_coeff_ui(h, 0, 0); + n = n_randint(state, 20); + + fmpz_poly_compose_series_horner(f, g, h, n); + fmpz_poly_compose_series_horner(g, g, h, n); + + result = (fmpz_poly_equal(f, g)); + if (!result) + { + flint_printf("FAIL (aliasing 1):\n"); + fmpz_poly_print(f), flint_printf("\n\n"); + fmpz_poly_print(g), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(f); + fmpz_poly_clear(g); + fmpz_poly_clear(h); + } + + /* Check aliasing of the second argument */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + fmpz_poly_t f, g, h; + slong n; + + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_poly_init(h); + fmpz_poly_randtest(g, state, n_randint(state, 40), 80); + fmpz_poly_randtest(h, state, n_randint(state, 20), 50); + fmpz_poly_set_coeff_ui(h, 0, 0); + n = n_randint(state, 20); + + fmpz_poly_compose_series_horner(f, g, h, n); + fmpz_poly_compose_series_horner(h, g, h, n); + + result = (fmpz_poly_equal(f, h)); + if (!result) + { + flint_printf("FAIL (aliasing 2):\n"); + fmpz_poly_print(f), flint_printf("\n\n"); + fmpz_poly_print(h), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(f); + fmpz_poly_clear(g); + fmpz_poly_clear(h); + } + + /* Compare with compose */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + fmpz_poly_t f, g, h, s, t; + slong n; + + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_poly_init(h); + fmpz_poly_init(s); + fmpz_poly_init(t); + fmpz_poly_randtest(g, state, n_randint(state, 40), 80); + fmpz_poly_randtest(h, state, n_randint(state, 20), 50); + fmpz_poly_set_coeff_ui(h, 0, 0); + n = n_randint(state, 20); + + fmpz_poly_compose(s, g, h); + fmpz_poly_truncate(s, n); + fmpz_poly_compose_series_horner(f, g, h, n); + + result = (fmpz_poly_equal(f, s)); + if (!result) + { + flint_printf("FAIL (comparison):\n"); + flint_printf("n = %wd\n", n); + flint_printf("g = "), fmpz_poly_print(g), flint_printf("\n\n"); + flint_printf("h = "), fmpz_poly_print(h), flint_printf("\n\n"); + flint_printf("f = "), fmpz_poly_print(f), flint_printf("\n\n"); + flint_printf("s = "), fmpz_poly_print(s), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(f); + fmpz_poly_clear(g); + fmpz_poly_clear(h); + fmpz_poly_clear(s); + fmpz_poly_clear(t); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-content.c b/external/flint-2.4.3/fmpz_poly/test/t-content.c new file mode 100644 index 0000000..ed93750 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-content.c @@ -0,0 +1,84 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("content...."); + fflush(stdout); + + + + /* Check that content(a f) = abs(a) content(f) */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_t a, c, d; + fmpz_poly_t f; + + fmpz_init(a); + fmpz_init(c); + fmpz_init(d); + fmpz_poly_init(f); + fmpz_poly_randtest(f, state, n_randint(state, 100), 200); + fmpz_randtest(a, state, 100); + + fmpz_poly_content(c, f); + fmpz_poly_scalar_mul_fmpz(f, f, a); + fmpz_abs(a, a); + fmpz_mul(c, a, c); + fmpz_poly_content(d, f); + + result = (fmpz_equal(c, d)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_print(c), flint_printf("\n\n"); + fmpz_print(d), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(a); + fmpz_clear(c); + fmpz_clear(d); + fmpz_poly_clear(f); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-derivative.c b/external/flint-2.4.3/fmpz_poly/test/t-derivative.c new file mode 100644 index 0000000..fd5a0dd --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-derivative.c @@ -0,0 +1,138 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("derivative...."); + fflush(stdout); + + + + /* Check aliasing */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_randtest(a, state, n_randint(state, 100), 200); + + fmpz_poly_derivative(b, a); + fmpz_poly_derivative(a, a); + + result = (fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + } + + /* Check constants have derivative zero */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_randtest(a, state, n_randint(state, 2), 200); + + fmpz_poly_derivative(b, a); + + result = (b->length == UWORD(0)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + } + + /* Check (f g)' = f' g + f g' */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c, d, lhs, rhs; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_init(d); + fmpz_poly_init(lhs); + fmpz_poly_init(rhs); + fmpz_poly_randtest(a, state, n_randint(state, 100), 200); + fmpz_poly_randtest(b, state, n_randint(state, 100), 200); + + fmpz_poly_mul(lhs, a, b); + fmpz_poly_derivative(lhs, lhs); + fmpz_poly_derivative(c, a); + fmpz_poly_derivative(d, b); + fmpz_poly_mul(c, c, b); + fmpz_poly_mul(d, a, d); + fmpz_poly_add(rhs, c, d); + + result = fmpz_poly_equal(lhs, rhs); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + fmpz_poly_clear(d); + fmpz_poly_clear(lhs); + fmpz_poly_clear(rhs); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-div_basecase.c b/external/flint-2.4.3/fmpz_poly/test/t-div_basecase.c new file mode 100644 index 0000000..8b8abe2 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-div_basecase.c @@ -0,0 +1,143 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("div_basecase...."); + fflush(stdout); + + + + /* Compare with full division, no aliasing */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, q, r, q2; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(q); + fmpz_poly_init(r); + fmpz_poly_init(q2); + + fmpz_poly_randtest(a, state, n_randint(state, 50), 100); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, a->length + 1) + 1, 100); + + fmpz_poly_divrem_basecase(q, r, a, b); + fmpz_poly_div_basecase(q2, a, b); + + result = (fmpz_poly_equal(q, q2)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + fmpz_poly_print(q), flint_printf("\n\n"); + fmpz_poly_print(r), flint_printf("\n\n"); + fmpz_poly_print(q2), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(q); + fmpz_poly_clear(r); + fmpz_poly_clear(q2); + } + + /* Check q and a alias */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, q; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(q); + fmpz_poly_randtest(a, state, n_randint(state, 50), 100); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 50) + 1, 100); + + fmpz_poly_div_basecase(q, a, b); + fmpz_poly_div_basecase(a, a, b); + + result = (fmpz_poly_equal(a, q)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(q), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(q); + } + + /* Check q and b alias */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, q; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(q); + fmpz_poly_randtest(a, state, n_randint(state, 50), 100); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 50) + 1, 100); + + fmpz_poly_div_basecase(q, a, b); + fmpz_poly_div_basecase(b, a, b); + + result = (fmpz_poly_equal(b, q)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(q), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(q); + } + + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-div_divconquer.c b/external/flint-2.4.3/fmpz_poly/test/t-div_divconquer.c new file mode 100644 index 0000000..d3db097 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-div_divconquer.c @@ -0,0 +1,143 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("div_divconquer...."); + fflush(stdout); + + + + /* Compare with full division, no aliasing */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, q, r, q2; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(q); + fmpz_poly_init(r); + fmpz_poly_init(q2); + + fmpz_poly_randtest(a, state, n_randint(state, 200), 100); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, a->length + 1) + 1, 100); + + fmpz_poly_divrem_divconquer(q, r, a, b); + fmpz_poly_div_divconquer(q2, a, b); + + result = (fmpz_poly_equal(q, q2)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + fmpz_poly_print(q), flint_printf("\n\n"); + fmpz_poly_print(r), flint_printf("\n\n"); + fmpz_poly_print(q2), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(q); + fmpz_poly_clear(r); + fmpz_poly_clear(q2); + } + + /* Check q and a alias */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, q; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(q); + fmpz_poly_randtest(a, state, n_randint(state, 100), 200); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1, 200); + + fmpz_poly_div_divconquer(q, a, b); + fmpz_poly_div_divconquer(a, a, b); + + result = (fmpz_poly_equal(a, q)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(q), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(q); + } + + /* Check q and b alias */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, q; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(q); + fmpz_poly_randtest(a, state, n_randint(state, 100), 200); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1, 200); + + fmpz_poly_div_divconquer(q, a, b); + fmpz_poly_div_divconquer(b, a, b); + + result = (fmpz_poly_equal(b, q)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(q), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(q); + } + + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-div_preinv.c b/external/flint-2.4.3/fmpz_poly/test/t-div_preinv.c new file mode 100644 index 0000000..666fbc3 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-div_preinv.c @@ -0,0 +1,155 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009, 2013 William Hart + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("div_preinv...."); + fflush(stdout); + + + + /* Compare with full division, no aliasing */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, b_inv, q, r, q2; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(b_inv); + fmpz_poly_init(q); + fmpz_poly_init(r); + fmpz_poly_init(q2); + + fmpz_poly_randtest(a, state, n_randint(state, 50), 100); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, a->length + 1) + 1, 100); + fmpz_set_ui(b->coeffs + b->length - 1, 1); /* b must be monic */ + + fmpz_poly_divrem_basecase(q, r, a, b); + fmpz_poly_preinvert(b_inv, b); + fmpz_poly_div_preinv(q2, a, b, b_inv); + + result = (fmpz_poly_equal(q, q2)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + fmpz_poly_print(q), flint_printf("\n\n"); + fmpz_poly_print(r), flint_printf("\n\n"); + fmpz_poly_print(q2), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(b_inv); + fmpz_poly_clear(q); + fmpz_poly_clear(r); + fmpz_poly_clear(q2); + } + + /* Check q and a alias */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, b_inv, q; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(b_inv); + fmpz_poly_init(q); + fmpz_poly_randtest(a, state, n_randint(state, 50), 100); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 50) + 1, 100); + fmpz_set_ui(b->coeffs + b->length - 1, 1); /* b must be monic */ + + fmpz_poly_div_basecase(q, a, b); + fmpz_poly_preinvert(b_inv, b); + fmpz_poly_div_preinv(a, a, b, b_inv); + + result = (fmpz_poly_equal(a, q)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(q), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(b_inv); + fmpz_poly_clear(q); + } + + /* Check q and b alias */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, b_inv, q; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(b_inv); + fmpz_poly_init(q); + fmpz_poly_randtest(a, state, n_randint(state, 50), 100); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 50) + 1, 100); + fmpz_set_ui(b->coeffs + b->length - 1, 1); /* b must be monic */ + + fmpz_poly_div_basecase(q, a, b); + fmpz_poly_preinvert(b_inv, b); + fmpz_poly_div_preinv(b, a, b, b_inv); + + result = (fmpz_poly_equal(b, q)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(q), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(b_inv); + fmpz_poly_clear(q); + } + + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-div_root.c b/external/flint-2.4.3/fmpz_poly/test/t-div_root.c new file mode 100644 index 0000000..7ca627a --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-div_root.c @@ -0,0 +1,133 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("div_root...."); + fflush(stdout); + + + + /* Compare with standard divrem */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t P, Q, D, DQ; + fmpz_t c; + slong n, b; + + n = n_randint(state, 100); + b = n_randint(state, 200); + + fmpz_init(c); + fmpz_poly_init(P); + fmpz_poly_init(Q); + fmpz_poly_init(D); + fmpz_poly_init(DQ); + + fmpz_poly_randtest(P, state, n, b); + fmpz_randtest(c, state, b); + + fmpz_poly_div_root(Q, P, c); + + fmpz_poly_set_coeff_fmpz(D, 0, c); + fmpz_poly_neg(D, D); + fmpz_poly_set_coeff_ui(D, 1, UWORD(1)); + + fmpz_poly_div_basecase(DQ, P, D); + + result = fmpz_poly_equal(Q, DQ); + + if (!result) + { + flint_printf("FAIL!\n"); + flint_printf("P:\n"); fmpz_poly_print(P); flint_printf("\n\n"); + flint_printf("Q:\n"); fmpz_poly_print(Q); flint_printf("\n\n"); + flint_printf("D:\n"); fmpz_poly_print(D); flint_printf("\n\n"); + flint_printf("DQ:\n"); fmpz_poly_print(DQ); flint_printf("\n\n"); + abort(); + } + + fmpz_clear(c); + fmpz_poly_clear(P); + fmpz_poly_clear(Q); + fmpz_poly_clear(D); + fmpz_poly_clear(DQ); + } + + /* Check aliasing */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t P, Q1, Q2; + fmpz_t c; + slong n, b; + + n = n_randint(state, 100); + b = n_randint(state, 200); + + fmpz_init(c); + fmpz_poly_init(P); + fmpz_poly_init(Q1); + fmpz_poly_init(Q2); + + fmpz_randtest(c, state, b); + fmpz_poly_randtest(P, state, n, b); + fmpz_poly_set(Q2, P); + + fmpz_poly_div_root(Q1, P, c); + fmpz_poly_div_root(Q2, Q2, c); + + result = fmpz_poly_equal(Q1, Q2); + + if (!result) + { + flint_printf("FAIL (aliasing)!\n"); + flint_printf("P:\n"); fmpz_poly_print(P); flint_printf("\n\n"); + flint_printf("Q1:\n"); fmpz_poly_print(Q1); flint_printf("\n\n"); + flint_printf("Q2:\n"); fmpz_poly_print(Q2); flint_printf("\n\n"); + abort(); + } + + fmpz_clear(c); + fmpz_poly_clear(P); + fmpz_poly_clear(Q1); + fmpz_poly_clear(Q2); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-div_series.c b/external/flint-2.4.3/fmpz_poly/test/t-div_series.c new file mode 100644 index 0000000..fc6e361 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-div_series.c @@ -0,0 +1,150 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("div_series...."); + fflush(stdout); + + + + /* Check aliasing q and a */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, q; + slong n = n_randint(state, 50) + 1; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(q); + + fmpz_poly_randtest(a, state, n_randint(state, 50) + 1, 100); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 50) + 1, 100); + fmpz_poly_set_coeff_ui(b, 0, 1); + + fmpz_poly_div_series(q, a, b, n); + fmpz_poly_div_series(a, a, b, n); + + result = (fmpz_poly_equal(q, a)); + if (!result) + { + flint_printf("FAIL (alias q and a):\n"); + flint_printf("a = "), fmpz_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_poly_print(b), flint_printf("\n\n"); + flint_printf("q = "), fmpz_poly_print(q), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(q); + } + + /* Check aliasing q and b */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, q; + slong n = n_randint(state, 50) + 1; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(q); + + fmpz_poly_randtest(a, state, n_randint(state, 50) + 1, 100); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 50) + 1, 100); + fmpz_poly_set_coeff_ui(b, 0, 1); + + fmpz_poly_div_series(q, a, b, n); + fmpz_poly_div_series(b, a, b, n); + + result = (fmpz_poly_equal(q, b)); + if (!result) + { + flint_printf("FAIL (alias q and b):\n"); + flint_printf("a = "), fmpz_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_poly_print(b), flint_printf("\n\n"); + flint_printf("q = "), fmpz_poly_print(q), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(q); + } + + /* Check that Q * B == A */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, p, q; + slong n = n_randint(state, 50) + 1; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(p); + fmpz_poly_init(q); + + fmpz_poly_randtest(a, state, n_randint(state, 50) + 1, 100); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 50) + 1, 100); + fmpz_poly_set_coeff_ui(b, 0, 1); + + fmpz_poly_div_series(q, a, b, n); + fmpz_poly_mullow(p, q, b, n); + + fmpz_poly_truncate(a, n); + + result = (fmpz_poly_equal(p, a)); + if (!result) + { + flint_printf("FAIL (check Q * B = A):\n"); + flint_printf("a = "), fmpz_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_poly_print(b), flint_printf("\n\n"); + flint_printf("p = "), fmpz_poly_print(p), flint_printf("\n\n"); + flint_printf("q = "), fmpz_poly_print(q), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(p); + fmpz_poly_clear(q); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-divides.c b/external/flint-2.4.3/fmpz_poly/test/t-divides.c new file mode 100644 index 0000000..c77b8e4 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-divides.c @@ -0,0 +1,173 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("divides...."); + fflush(stdout); + + + + /* Check that b divides a*b and that the quotient is a */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, p, q; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(p); + fmpz_poly_init(q); + fmpz_poly_randtest(a, state, n_randint(state, 100), 200); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1, 200); + fmpz_poly_mul(p, a, b); + + result = (fmpz_poly_divides(q, p, b) && fmpz_poly_equal(q, a)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + fmpz_poly_print(p), flint_printf("\n\n"); + fmpz_poly_print(q), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(p); + fmpz_poly_clear(q); + } + + /* Check aliasing of q with a */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, p; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(p); + fmpz_poly_randtest(a, state, n_randint(state, 100), 200); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1, 200); + fmpz_poly_mul(p, a, b); + + result = (fmpz_poly_divides(p, p, b) && fmpz_poly_equal(p, a)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + fmpz_poly_print(p), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(p); + } + + /* Check aliasing of q with b */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, p; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(p); + fmpz_poly_randtest(a, state, n_randint(state, 100), 200); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1, 200); + fmpz_poly_mul(p, a, b); + + result = (fmpz_poly_divides(b, p, b) && fmpz_poly_equal(b, a)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + fmpz_poly_print(p), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(p); + } + + /* Check when not divisible */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, p, q, g, s; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(p); + fmpz_poly_init(q); + fmpz_poly_init(s); + fmpz_poly_init(g); + fmpz_poly_randtest(a, state, n_randint(state, 100), 200); + do { + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1, 200); + } while (b->length < 2); + fmpz_poly_mul(p, a, b); + do { + fmpz_poly_randtest_not_zero(s, state, b->length, 200); + fmpz_poly_gcd(g, s, b); + } while (g->length == b->length); + fmpz_poly_add(p, p, s); + + result = (!fmpz_poly_divides(q, p, b)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + fmpz_poly_print(p), flint_printf("\n\n"); + fmpz_poly_print(q), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(p); + fmpz_poly_clear(q); + fmpz_poly_clear(s); + fmpz_poly_clear(g); + } + + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-divrem_basecase.c b/external/flint-2.4.3/fmpz_poly/test/t-divrem_basecase.c new file mode 100644 index 0000000..ca2c927 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-divrem_basecase.c @@ -0,0 +1,208 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("divrem_basecase...."); + fflush(stdout); + + + + /* Check q*b + r = a, no aliasing */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, q, r, prod; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(q); + fmpz_poly_init(r); + fmpz_poly_init(prod); + fmpz_poly_randtest(a, state, n_randint(state, 100), 100); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1, 100); + + fmpz_poly_divrem_basecase(q, r, a, b); + fmpz_poly_mul(prod, q, b); + fmpz_poly_add(prod, prod, r); + + result = (fmpz_poly_equal(a, prod)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(prod), flint_printf("\n\n"); + fmpz_poly_print(q), flint_printf("\n\n"); + fmpz_poly_print(r), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(q); + fmpz_poly_clear(r); + fmpz_poly_clear(prod); + } + + /* Check r and a alias */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, q, r; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(q); + fmpz_poly_init(r); + fmpz_poly_randtest(a, state, n_randint(state, 100), 100); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1, 100); + + fmpz_poly_divrem_basecase(q, r, a, b); + fmpz_poly_divrem_basecase(q, a, a, b); + + result = (fmpz_poly_equal(a, r)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(q), flint_printf("\n\n"); + fmpz_poly_print(r), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(q); + fmpz_poly_clear(r); + } + + /* Check r and b alias */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, q, r; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(q); + fmpz_poly_init(r); + fmpz_poly_randtest(a, state, n_randint(state, 100), 100); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1, 100); + + fmpz_poly_divrem_basecase(q, r, a, b); + fmpz_poly_divrem_basecase(q, b, a, b); + + result = (fmpz_poly_equal(b, r)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(q), flint_printf("\n\n"); + fmpz_poly_print(r), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(q); + fmpz_poly_clear(r); + } + + /* Check q and a alias */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, q, r; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(q); + fmpz_poly_init(r); + fmpz_poly_randtest(a, state, n_randint(state, 100), 100); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1, 100); + + fmpz_poly_divrem_basecase(q, r, a, b); + fmpz_poly_divrem_basecase(a, r, a, b); + + result = (fmpz_poly_equal(a, q)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(q), flint_printf("\n\n"); + fmpz_poly_print(r), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(q); + fmpz_poly_clear(r); + } + + /* Check q and b alias */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, q, r; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(q); + fmpz_poly_init(r); + fmpz_poly_randtest(a, state, n_randint(state, 100), 100); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1, 100); + + fmpz_poly_divrem_basecase(q, r, a, b); + fmpz_poly_divrem_basecase(b, r, a, b); + + result = (fmpz_poly_equal(b, q)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(q), flint_printf("\n\n"); + fmpz_poly_print(r), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(q); + fmpz_poly_clear(r); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-divrem_divconquer.c b/external/flint-2.4.3/fmpz_poly/test/t-divrem_divconquer.c new file mode 100644 index 0000000..7d690f3 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-divrem_divconquer.c @@ -0,0 +1,208 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("divrem_divconquer...."); + fflush(stdout); + + + + /* Check q*b + r = a, no aliasing */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, q, r, prod; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(q); + fmpz_poly_init(r); + fmpz_poly_init(prod); + fmpz_poly_randtest(a, state, n_randint(state, 100), 100); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1, 100); + + fmpz_poly_divrem_divconquer(q, r, a, b); + fmpz_poly_mul(prod, q, b); + fmpz_poly_add(prod, prod, r); + + result = (fmpz_poly_equal(a, prod)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(prod), flint_printf("\n\n"); + fmpz_poly_print(q), flint_printf("\n\n"); + fmpz_poly_print(r), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(q); + fmpz_poly_clear(r); + fmpz_poly_clear(prod); + } + + /* Check r and a alias */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, q, r; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(q); + fmpz_poly_init(r); + fmpz_poly_randtest(a, state, n_randint(state, 100), 100); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1, 100); + + fmpz_poly_divrem_divconquer(q, r, a, b); + fmpz_poly_divrem_divconquer(q, a, a, b); + + result = (fmpz_poly_equal(a, r)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(q), flint_printf("\n\n"); + fmpz_poly_print(r), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(q); + fmpz_poly_clear(r); + } + + /* Check r and b alias */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, q, r; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(q); + fmpz_poly_init(r); + fmpz_poly_randtest(a, state, n_randint(state, 100), 100); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1, 100); + + fmpz_poly_divrem_divconquer(q, r, a, b); + fmpz_poly_divrem_divconquer(q, b, a, b); + + result = (fmpz_poly_equal(b, r)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(q), flint_printf("\n\n"); + fmpz_poly_print(r), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(q); + fmpz_poly_clear(r); + } + + /* Check q and a alias */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, q, r; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(q); + fmpz_poly_init(r); + fmpz_poly_randtest(a, state, n_randint(state, 100), 100); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1, 100); + + fmpz_poly_divrem_divconquer(q, r, a, b); + fmpz_poly_divrem_divconquer(a, r, a, b); + + result = (fmpz_poly_equal(a, q)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(q), flint_printf("\n\n"); + fmpz_poly_print(r), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(q); + fmpz_poly_clear(r); + } + + /* Check q and b alias */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, q, r; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(q); + fmpz_poly_init(r); + fmpz_poly_randtest(a, state, n_randint(state, 100), 100); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1, 100); + + fmpz_poly_divrem_divconquer(q, r, a, b); + fmpz_poly_divrem_divconquer(b, r, a, b); + + result = (fmpz_poly_equal(b, q)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(q), flint_printf("\n\n"); + fmpz_poly_print(r), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(q); + fmpz_poly_clear(r); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-divrem_preinv.c b/external/flint-2.4.3/fmpz_poly/test/t-divrem_preinv.c new file mode 100644 index 0000000..e951f21 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-divrem_preinv.c @@ -0,0 +1,228 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009, 2013 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("divrem_preinv...."); + fflush(stdout); + + + + /* Check q*b + r = a, no aliasing */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, b_inv, q, r, prod; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(b_inv); + fmpz_poly_init(q); + fmpz_poly_init(r); + fmpz_poly_init(prod); + fmpz_poly_randtest(a, state, n_randint(state, 100), 100); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1, 100); + fmpz_set_ui(b->coeffs + b->length - 1, 1); /* b must be monic */ + + fmpz_poly_preinvert(b_inv, b); + fmpz_poly_divrem_preinv(q, r, a, b, b_inv); + fmpz_poly_mul(prod, q, b); + fmpz_poly_add(prod, prod, r); + + result = (fmpz_poly_equal(a, prod)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(prod), flint_printf("\n\n"); + fmpz_poly_print(q), flint_printf("\n\n"); + fmpz_poly_print(r), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(b_inv); + fmpz_poly_clear(q); + fmpz_poly_clear(r); + fmpz_poly_clear(prod); + } + + /* Check r and a alias */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, b_inv, q, r; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(b_inv); + fmpz_poly_init(q); + fmpz_poly_init(r); + fmpz_poly_randtest(a, state, n_randint(state, 100), 100); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1, 100); + fmpz_set_ui(b->coeffs + b->length - 1, 1); /* b must be monic */ + + fmpz_poly_divrem_basecase(q, r, a, b); + fmpz_poly_preinvert(b_inv, b); + fmpz_poly_divrem_preinv(q, a, a, b, b_inv); + + result = (fmpz_poly_equal(a, r)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(q), flint_printf("\n\n"); + fmpz_poly_print(r), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(b_inv); + fmpz_poly_clear(q); + fmpz_poly_clear(r); + } + + /* Check r and b alias */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, b_inv, q, r; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(b_inv); + fmpz_poly_init(q); + fmpz_poly_init(r); + fmpz_poly_randtest(a, state, n_randint(state, 100), 100); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1, 100); + fmpz_set_ui(b->coeffs + b->length - 1, 1); /* b must be monic */ + + fmpz_poly_divrem_basecase(q, r, a, b); + fmpz_poly_preinvert(b_inv, b); + fmpz_poly_divrem_preinv(q, b, a, b, b_inv); + + result = (fmpz_poly_equal(b, r)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(q), flint_printf("\n\n"); + fmpz_poly_print(r), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(b_inv); + fmpz_poly_clear(q); + fmpz_poly_clear(r); + } + + /* Check q and a alias */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, b_inv, q, r; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(b_inv); + fmpz_poly_init(q); + fmpz_poly_init(r); + fmpz_poly_randtest(a, state, n_randint(state, 100), 100); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1, 100); + fmpz_set_ui(b->coeffs + b->length - 1, 1); /* b must be monic */ + + fmpz_poly_divrem_basecase(q, r, a, b); + fmpz_poly_preinvert(b_inv, b); + fmpz_poly_divrem_preinv(a, r, a, b, b_inv); + + result = (fmpz_poly_equal(a, q)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(q), flint_printf("\n\n"); + fmpz_poly_print(r), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(b_inv); + fmpz_poly_clear(q); + fmpz_poly_clear(r); + } + + /* Check q and b alias */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, b_inv, q, r; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(b_inv); + fmpz_poly_init(q); + fmpz_poly_init(r); + fmpz_poly_randtest(a, state, n_randint(state, 100), 100); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1, 100); + fmpz_set_ui(b->coeffs + b->length - 1, 1); /* b must be monic */ + + fmpz_poly_divrem_basecase(q, r, a, b); + fmpz_poly_preinvert(b_inv, b); + fmpz_poly_divrem_preinv(b, r, a, b, b_inv); + + result = (fmpz_poly_equal(b, q)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(q), flint_printf("\n\n"); + fmpz_poly_print(r), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(b_inv); + fmpz_poly_clear(q); + fmpz_poly_clear(r); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-equal_fmpz.c b/external/flint-2.4.3/fmpz_poly/test/t-equal_fmpz.c new file mode 100644 index 0000000..ab0ccfd --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-equal_fmpz.c @@ -0,0 +1,82 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("equal_fmpz...."); + fflush(stdout); + + + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b; + fmpz_t c; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_init(c); + + fmpz_randtest(c, state, 1 + n_randint(state, 200)); + fmpz_poly_set_fmpz(b, c); + + fmpz_poly_randtest(a, state, n_randint(state, 6), + 1 + n_randint(state, 200)); + if (n_randint(state, 2)) + fmpz_poly_set_coeff_fmpz(a, 0, c); + + result = fmpz_poly_equal(a, b) == fmpz_poly_equal_fmpz(a, c); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + fmpz_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-evaluate_divconquer_fmpz.c b/external/flint-2.4.3/fmpz_poly/test/t-evaluate_divconquer_fmpz.c new file mode 100644 index 0000000..00dca2a --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-evaluate_divconquer_fmpz.c @@ -0,0 +1,110 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("evaluate_divconquer_fmpz...."); + fflush(stdout); + + + + /* Check aliasing */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + fmpz_poly_t f; + + fmpz_init(a); + fmpz_init(b); + fmpz_poly_init(f); + fmpz_poly_randtest(f, state, n_randint(state, 100), 200); + fmpz_randtest(a, state, 100); + + fmpz_poly_evaluate_divconquer_fmpz(b, f, a); + fmpz_poly_evaluate_divconquer_fmpz(a, f, a); + + result = (fmpz_equal(a, b)); + if (!result) + { + flint_printf("FAIL (alias):\n"); + fmpz_print(a), flint_printf("\n\n"); + fmpz_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_poly_clear(f); + } + + /* Check that the result agrees with Horner's method */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c; + fmpz_poly_t f; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + fmpz_poly_init(f); + fmpz_poly_randtest(f, state, n_randint(state, 100), 200); + fmpz_randtest(a, state, 100); + + fmpz_poly_evaluate_divconquer_fmpz(b, f, a); + fmpz_poly_evaluate_horner_fmpz(c, f, a); + + result = (fmpz_equal(b, c)); + if (!result) + { + flint_printf("FAIL (cmp with Horner):\n"); + fmpz_print(a), flint_printf("\n\n"); + fmpz_print(b), flint_printf("\n\n"); + fmpz_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + fmpz_poly_clear(f); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-evaluate_fmpz.c b/external/flint-2.4.3/fmpz_poly/test/t-evaluate_fmpz.c new file mode 100644 index 0000000..aece02e --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-evaluate_fmpz.c @@ -0,0 +1,79 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("evaluate_fmpz...."); + fflush(stdout); + + + + /* Check aliasing */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + fmpz_poly_t f; + + fmpz_init(a); + fmpz_init(b); + fmpz_poly_init(f); + fmpz_poly_randtest(f, state, n_randint(state, 100), 200); + fmpz_randtest(a, state, 100); + + fmpz_poly_evaluate_fmpz(b, f, a); + fmpz_poly_evaluate_fmpz(a, f, a); + + result = (fmpz_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_print(a), flint_printf("\n\n"); + fmpz_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_poly_clear(f); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-evaluate_horner_fmpz.c b/external/flint-2.4.3/fmpz_poly/test/t-evaluate_horner_fmpz.c new file mode 100644 index 0000000..b01bd52 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-evaluate_horner_fmpz.c @@ -0,0 +1,116 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("evaluate_horner...."); + fflush(stdout); + + + + /* Check aliasing */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + fmpz_poly_t f; + + fmpz_init(a); + fmpz_init(b); + fmpz_poly_init(f); + fmpz_poly_randtest(f, state, n_randint(state, 100), 200); + fmpz_randtest(a, state, 100); + + fmpz_poly_evaluate_horner_fmpz(b, f, a); + fmpz_poly_evaluate_horner_fmpz(a, f, a); + + result = (fmpz_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_print(a), flint_printf("\n\n"); + fmpz_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_poly_clear(f); + } + + /* Check that (f+g)(a) = f(a) + g(a) */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c; + fmpz_poly_t f, g; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_poly_randtest(f, state, n_randint(state, 100), 200); + fmpz_poly_randtest(g, state, n_randint(state, 100), 200); + fmpz_randtest(a, state, 100); + + fmpz_poly_evaluate_horner_fmpz(b, f, a); + fmpz_poly_evaluate_horner_fmpz(c, g, a); + fmpz_add(b, b, c); + fmpz_poly_add(f, f, g); + fmpz_poly_evaluate_horner_fmpz(c, f, a); + + result = (fmpz_equal(b, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_print(b), flint_printf("\n\n"); + fmpz_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + fmpz_poly_clear(f); + fmpz_poly_clear(g); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-evaluate_horner_mpq.c b/external/flint-2.4.3/fmpz_poly/test/t-evaluate_horner_mpq.c new file mode 100644 index 0000000..927960d --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-evaluate_horner_mpq.c @@ -0,0 +1,181 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 1509 William Hart + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("evaluate_horner_mpq...."); + fflush(stdout); + + + + /* Check aliasing */ + for (i = 0; i < 75 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpq_t x, y; + fmpz_poly_t f; + + fmpz_init(a); + fmpz_init(b); + mpq_init(x); + mpq_init(y); + fmpz_poly_init(f); + fmpz_poly_randtest(f, state, n_randint(state, 100), 150); + fmpz_randtest(a, state, 100); + fmpz_randtest_not_zero(b, state, 100); + fmpz_get_mpz(mpq_numref(x), a); + fmpz_get_mpz(mpq_denref(x), b); + mpq_canonicalize(x); + + fmpz_poly_evaluate_horner_mpq(y, f, x); + fmpz_poly_evaluate_horner_mpq(x, f, x); + + result = (mpq_equal(x, y)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_print(a), flint_printf("\n\n"); + fmpz_print(b), flint_printf("\n\n"); + fmpz_poly_print(f), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + mpq_clear(x); + mpq_clear(y); + fmpz_poly_clear(f); + } + + /* Check that (f+g)(a) = f(a) + g(a) */ + for (i = 0; i < 75 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpq_t x, y, z; + fmpz_poly_t f, g; + + fmpz_init(a); + fmpz_init(b); + mpq_init(x); + mpq_init(y); + mpq_init(z); + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_poly_randtest(f, state, n_randint(state, 100), 150); + fmpz_poly_randtest(g, state, n_randint(state, 100), 150); + fmpz_randtest(a, state, 100); + fmpz_randtest_not_zero(b, state, 100); + fmpz_get_mpz(mpq_numref(x), a); + fmpz_get_mpz(mpq_denref(x), b); + mpq_canonicalize(x); + + fmpz_poly_evaluate_horner_mpq(y, f, x); + fmpz_poly_evaluate_horner_mpq(z, g, x); + mpq_add(y, y, z); + fmpz_poly_add(f, f, g); + fmpz_poly_evaluate_horner_mpq(z, f, x); + + result = (mpq_equal(y, z)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_print(a), flint_printf("\n\n"); + fmpz_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + mpq_clear(x); + mpq_clear(y); + mpq_clear(z); + fmpz_poly_clear(f); + fmpz_poly_clear(g); + } + + /* Check that (f*g)(a) = f(a) * g(a) */ + for (i = 0; i < 75 * flint_test_multiplier(); i++) + { + fmpz_t a, b; + mpq_t x, y, z; + fmpz_poly_t f, g; + + fmpz_init(a); + fmpz_init(b); + mpq_init(x); + mpq_init(y); + mpq_init(z); + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_poly_randtest(f, state, n_randint(state, 50), 100); + fmpz_poly_randtest(g, state, n_randint(state, 50), 100); + fmpz_randtest(a, state, 100); + fmpz_randtest_not_zero(b, state, 100); + fmpz_get_mpz(mpq_numref(x), a); + fmpz_get_mpz(mpq_denref(x), b); + mpq_canonicalize(x); + + fmpz_poly_evaluate_horner_mpq(y, f, x); + fmpz_poly_evaluate_horner_mpq(z, g, x); + mpq_mul(y, y, z); + fmpz_poly_mul(f, f, g); + fmpz_poly_evaluate_horner_mpq(z, f, x); + + result = (mpq_equal(y, z)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_print(a), flint_printf("\n\n"); + fmpz_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + mpq_clear(x); + mpq_clear(y); + mpq_clear(z); + fmpz_poly_clear(f); + fmpz_poly_clear(g); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-evaluate_mod.c b/external/flint-2.4.3/fmpz_poly/test/t-evaluate_mod.c new file mode 100644 index 0000000..b906bf5 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-evaluate_mod.c @@ -0,0 +1,87 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("evaluate_mod...."); + fflush(stdout); + + + + /* Compare with evaluation over the integers */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_t b, s; + fmpz_poly_t f; + mp_limb_t a, n, r; + + fmpz_poly_init(f); + fmpz_poly_randtest(f, state, n_randint(state, 10), 20); + + n = n_randtest_not_zero(state); + a = n_randint(state, n); + + fmpz_init(b); + fmpz_init(s); + fmpz_set_ui(b, a); + + r = fmpz_poly_evaluate_mod(f, a, n); + fmpz_poly_evaluate_fmpz(s, f, b); + + result = (r == fmpz_mod_ui(s, s, n)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(f), flint_printf("\n\n"); + gmp_printf("a = %Mu\n\n", a); + gmp_printf("n = %Mu\n\n", n); + gmp_printf("r = %Mu\n\n", r); + flint_printf("s = "), fmpz_print(s), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(f); + fmpz_clear(b); + fmpz_clear(s); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-gcd.c b/external/flint-2.4.3/fmpz_poly/test/t-gcd.c new file mode 100644 index 0000000..8127d9d --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-gcd.c @@ -0,0 +1,146 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("gcd...."); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(b, state, n_randint(state, 40), 80); + fmpz_poly_randtest(c, state, n_randint(state, 40), 80); + + fmpz_poly_gcd(a, b, c); + fmpz_poly_gcd(b, b, c); + + result = (fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL (aliasing a and b):\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + /* Check aliasing of a and c */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(b, state, n_randint(state, 40), 80); + fmpz_poly_randtest(c, state, n_randint(state, 40), 80); + + fmpz_poly_gcd(a, b, c); + fmpz_poly_gcd(c, b, c); + + result = (fmpz_poly_equal(a, c)); + if (!result) + { + flint_printf("FAIL (aliasing a and c):\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + /* Check that a divides GCD(af, ag) */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, d, f, g, q, r; + + fmpz_poly_init(a); + fmpz_poly_init(d); + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_poly_init(q); + fmpz_poly_init(r); + fmpz_poly_randtest_not_zero(a, state, n_randint(state, 24) + 1, 24); + fmpz_poly_randtest(f, state, n_randint(state, 40), 80); + fmpz_poly_randtest(g, state, n_randint(state, 40), 80); + + fmpz_poly_mul(f, a, f); + fmpz_poly_mul(g, a, g); + fmpz_poly_gcd(d, f, g); + + fmpz_poly_divrem_divconquer(q, r, d, a); + + result = (r->length == WORD(0)); + if (!result) + { + flint_printf("FAIL (check a | gcd(af, ag)):\n"); + fmpz_poly_print(f), flint_printf("\n"); + fmpz_poly_print(g), flint_printf("\n"); + fmpz_poly_print(a), flint_printf("\n"); + fmpz_poly_print(d), flint_printf("\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(d); + fmpz_poly_clear(f); + fmpz_poly_clear(g); + fmpz_poly_clear(q); + fmpz_poly_clear(r); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-gcd_heuristic.c b/external/flint-2.4.3/fmpz_poly/test/t-gcd_heuristic.c new file mode 100644 index 0000000..d0d167c --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-gcd_heuristic.c @@ -0,0 +1,235 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +/* + Tests whether the polynomial is suitably normalised for the + result of a GCD operation, that is, whether it's leading + coefficient is non-negative. + */ +static +int _t_gcd_is_canonical(const fmpz_poly_t poly) +{ + return fmpz_poly_is_zero(poly) || (fmpz_sgn(fmpz_poly_lead(poly)) > 0); +} + +int +main(void) +{ + int i, result, d1, d2; + FLINT_TEST_INIT(state); + + flint_printf("gcd_heuristic...."); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(b, state, n_randint(state, 40), 80); + fmpz_poly_randtest(c, state, n_randint(state, 40), 80); + + d1 = fmpz_poly_gcd_heuristic(a, b, c); + d2 = fmpz_poly_gcd_heuristic(b, b, c); + + result = ((d1 == 0 && d2 == 0) || (fmpz_poly_equal(a, b) + && _t_gcd_is_canonical(a))); + if (!result) + { + flint_printf("FAIL (aliasing a and b):\n"); + flint_printf("a = "), fmpz_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + /* Check aliasing of a and c */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(b, state, n_randint(state, 40), 80); + fmpz_poly_randtest(c, state, n_randint(state, 40), 80); + + d1 = fmpz_poly_gcd_heuristic(a, b, c); + d2 = fmpz_poly_gcd_heuristic(c, b, c); + + result = ((d1 == 0 && d2 == 0) || (fmpz_poly_equal(a, c) + && _t_gcd_is_canonical(a))); + if (!result) + { + flint_printf("FAIL (aliasing a and c):\n"); + flint_printf("a = "), fmpz_poly_print(a), flint_printf("\n\n"); + flint_printf("c = "), fmpz_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + /* Check that a divides GCD(af, ag) */ + for (i = 0; i < 300 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, d, f, g, q, r; + + fmpz_poly_init(a); + fmpz_poly_init(d); + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_poly_init(q); + fmpz_poly_init(r); + fmpz_poly_randtest_not_zero(a, state, n_randint(state, 100) + 1, 40); + fmpz_poly_randtest(f, state, n_randint(state, 100), 40); + fmpz_poly_randtest(g, state, n_randint(state, 100), 40); + + fmpz_poly_mul(f, a, f); + fmpz_poly_mul(g, a, g); + d1 = fmpz_poly_gcd_heuristic(d, f, g); + + if (d1) + { + fmpz_poly_divrem_divconquer(q, r, d, a); + + result = fmpz_poly_is_zero(r) && _t_gcd_is_canonical(d); + if (!result) + { + flint_printf("FAIL (check a | gcd(af, ag)):\n"); + flint_printf("f = "), fmpz_poly_print(f), flint_printf("\n"); + flint_printf("g = "), fmpz_poly_print(g), flint_printf("\n"); + flint_printf("a = "), fmpz_poly_print(a), flint_printf("\n"); + flint_printf("d = "), fmpz_poly_print(d), flint_printf("\n"); + abort(); + } + } + + fmpz_poly_clear(a); + fmpz_poly_clear(d); + fmpz_poly_clear(f); + fmpz_poly_clear(g); + fmpz_poly_clear(q); + fmpz_poly_clear(r); + } + + /* Check that a == GCD(af, ag) when GCD(f, g) = 1 */ + for (i = 0; i < 300 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, d, f, g, q, r; + + fmpz_poly_init(a); + fmpz_poly_init(d); + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_poly_init(q); + fmpz_poly_init(r); + fmpz_poly_randtest_not_zero(a, state, n_randint(state, 100) + 1, 200); + do { + fmpz_poly_randtest(f, state, n_randint(state, 100), 200); + fmpz_poly_randtest(g, state, n_randint(state, 100), 200); + fmpz_poly_gcd_heuristic(d, f, g); + } while (!(d->length == 1 && fmpz_is_one(d->coeffs))); + + fmpz_poly_mul(f, a, f); + fmpz_poly_mul(g, a, g); + d1 = fmpz_poly_gcd_heuristic(d, f, g); + + if (d1) + { + if (!_t_gcd_is_canonical(a)) fmpz_poly_neg(a, a); + + result = fmpz_poly_equal(d, a) && _t_gcd_is_canonical(d); + if (!result) + { + flint_printf("FAIL (check a == gcd(af, ag) when gcd(f, g) = 1):\n"); + flint_printf("f = "), fmpz_poly_print(f), flint_printf("\n"); + flint_printf("g = "), fmpz_poly_print(g), flint_printf("\n"); + flint_printf("a = "), fmpz_poly_print(a), flint_printf("\n"); + flint_printf("d = "), fmpz_poly_print(d), flint_printf("\n"); + abort(); + } + } + + fmpz_poly_clear(a); + fmpz_poly_clear(d); + fmpz_poly_clear(f); + fmpz_poly_clear(g); + fmpz_poly_clear(q); + fmpz_poly_clear(r); + } + + /* Sebastian's test case */ + { + fmpz_poly_t a, b, d; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(d); + + fmpz_poly_set_coeff_ui(b, 2, 1); + fmpz_poly_set_coeff_si(a, 0, -32); + fmpz_poly_set_coeff_si(a, 1, 24); + + fmpz_poly_gcd_heuristic(d, a, b); + + result = (d->length == 1 && fmpz_is_one(d->coeffs)); + if (!result) + { + flint_printf("FAIL (check 1 == gcd(x^2, 24*x - 32):\n"); + fmpz_poly_print(d); flint_printf("\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(d); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-gcd_modular.c b/external/flint-2.4.3/fmpz_poly/test/t-gcd_modular.c new file mode 100644 index 0000000..2479460 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-gcd_modular.c @@ -0,0 +1,256 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +/* + Tests whether the polynomial is suitably normalised for the + result of a GCD operation, that is, whether it's leading + coefficient is non-negative. + */ +static +int _t_gcd_is_canonical(const fmpz_poly_t poly) +{ + return fmpz_poly_is_zero(poly) || (fmpz_sgn(fmpz_poly_lead(poly)) > 0); +} + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("gcd_modular...."); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(b, state, n_randint(state, 40), 80); + fmpz_poly_randtest(c, state, n_randint(state, 40), 80); + + fmpz_poly_gcd_modular(a, b, c); + fmpz_poly_gcd_modular(b, b, c); + + result = (fmpz_poly_equal(a, b) && _t_gcd_is_canonical(a)); + if (!result) + { + flint_printf("FAIL (aliasing a and b):\n"); + flint_printf("a = "), fmpz_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + /* Check aliasing of a and c */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(b, state, n_randint(state, 40), 80); + fmpz_poly_randtest(c, state, n_randint(state, 40), 80); + + fmpz_poly_gcd_modular(a, b, c); + fmpz_poly_gcd_modular(c, b, c); + + result = (fmpz_poly_equal(a, c) && _t_gcd_is_canonical(a)); + if (!result) + { + flint_printf("FAIL (aliasing a and c):\n"); + flint_printf("a = "), fmpz_poly_print(a), flint_printf("\n\n"); + flint_printf("c = "), fmpz_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + /* Check that a divides GCD(af, ag) */ + for (i = 0; i < 300 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, d, f, g, q, r; + + fmpz_poly_init(a); + fmpz_poly_init(d); + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_poly_init(q); + fmpz_poly_init(r); + fmpz_poly_randtest_not_zero(a, state, n_randint(state, 100) + 1, 40); + fmpz_poly_randtest(f, state, n_randint(state, 100), 40); + fmpz_poly_randtest(g, state, n_randint(state, 100), 40); + + fmpz_poly_mul(f, a, f); + fmpz_poly_mul(g, a, g); + fmpz_poly_gcd_modular(d, f, g); + + fmpz_poly_divrem_divconquer(q, r, d, a); + + result = fmpz_poly_is_zero(r) && _t_gcd_is_canonical(d); + if (!result) + { + flint_printf("FAIL (check a | gcd(af, ag)):\n"); + flint_printf("f = "), fmpz_poly_print(f), flint_printf("\n"); + flint_printf("g = "), fmpz_poly_print(g), flint_printf("\n"); + flint_printf("a = "), fmpz_poly_print(a), flint_printf("\n"); + flint_printf("d = "), fmpz_poly_print(d), flint_printf("\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(d); + fmpz_poly_clear(f); + fmpz_poly_clear(g); + fmpz_poly_clear(q); + fmpz_poly_clear(r); + } + + /* Check that a == GCD(af, ag) when GCD(f, g) = 1 */ + for (i = 0; i < 300 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, d, f, g, q, r; + + fmpz_poly_init(a); + fmpz_poly_init(d); + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_poly_init(q); + fmpz_poly_init(r); + fmpz_poly_randtest_not_zero(a, state, n_randint(state, 100) + 1, 200); + do { + fmpz_poly_randtest(f, state, n_randint(state, 100), 200); + fmpz_poly_randtest(g, state, n_randint(state, 100), 200); + fmpz_poly_gcd_heuristic(d, f, g); + } while (!(d->length == 1 && fmpz_is_one(d->coeffs))); + + fmpz_poly_mul(f, a, f); + fmpz_poly_mul(g, a, g); + fmpz_poly_gcd_modular(d, f, g); + + if (!_t_gcd_is_canonical(a)) fmpz_poly_neg(a, a); + + result = fmpz_poly_equal(d, a) && _t_gcd_is_canonical(d); + if (!result) + { + flint_printf("FAIL (check a == gcd(af, ag) when gcd(f, g) = 1):\n"); + flint_printf("f = "), fmpz_poly_print(f), flint_printf("\n"); + flint_printf("g = "), fmpz_poly_print(g), flint_printf("\n"); + flint_printf("a = "), fmpz_poly_print(a), flint_printf("\n"); + flint_printf("d = "), fmpz_poly_print(d), flint_printf("\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(d); + fmpz_poly_clear(f); + fmpz_poly_clear(g); + fmpz_poly_clear(q); + fmpz_poly_clear(r); + } + + /* Sebastian's test case */ + { + fmpz_poly_t a, b, d; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(d); + + fmpz_poly_set_coeff_ui(b, 2, 1); + fmpz_poly_set_coeff_si(a, 0, -32); + fmpz_poly_set_coeff_si(a, 1, 24); + + fmpz_poly_gcd_modular(d, a, b); + + result = (d->length == 1 && fmpz_is_one(d->coeffs)); + if (!result) + { + flint_printf("FAIL (check 1 == gcd(x^2, 24*x - 32):\n"); + fmpz_poly_print(d); flint_printf("\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(d); + } + + /* another test case */ + { + fmpz_poly_t a, b, d, e; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(d); + fmpz_poly_init(e); + + fmpz_poly_set_str(a, "12 0 0 0 0 0 0 0 0 0 8582594367 -9297159048333985579007 33822867456"); + fmpz_poly_set_str(b, "8 0 0 -258272396248218664896 0 -2762 -549690802047 -3771028 8796059467776"); + fmpz_poly_set_str(e, "3 0 0 1"); + + fmpz_poly_gcd_modular(d, a, b); + + result = fmpz_poly_equal(d, e); + if (!result) + { + flint_printf("FAIL (check special #2):\n"); + fmpz_poly_print(d); flint_printf("\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(d); + fmpz_poly_clear(e); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-gcd_subresultant.c b/external/flint-2.4.3/fmpz_poly/test/t-gcd_subresultant.c new file mode 100644 index 0000000..0efdcd4 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-gcd_subresultant.c @@ -0,0 +1,145 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("gcd_subresultant...."); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(b, state, n_randint(state, 40), 80); + fmpz_poly_randtest(c, state, n_randint(state, 40), 80); + + fmpz_poly_gcd_subresultant(a, b, c); + fmpz_poly_gcd_subresultant(b, b, c); + + result = (fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL (aliasing a and b):\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + /* Check aliasing of a and c */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(b, state, n_randint(state, 40), 80); + fmpz_poly_randtest(c, state, n_randint(state, 40), 80); + + fmpz_poly_gcd_subresultant(a, b, c); + fmpz_poly_gcd_subresultant(c, b, c); + + result = (fmpz_poly_equal(a, c)); + if (!result) + { + flint_printf("FAIL (aliasing a and c):\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + /* Check that a divides GCD(af, ag) */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, d, f, g, q, r; + + fmpz_poly_init(a); + fmpz_poly_init(d); + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_poly_init(q); + fmpz_poly_init(r); + fmpz_poly_randtest_not_zero(a, state, n_randint(state, 24) + 1, 24); + fmpz_poly_randtest(f, state, n_randint(state, 40), 80); + fmpz_poly_randtest(g, state, n_randint(state, 40), 80); + + fmpz_poly_mul(f, a, f); + fmpz_poly_mul(g, a, g); + fmpz_poly_gcd_subresultant(d, f, g); + + fmpz_poly_divrem_divconquer(q, r, d, a); + + result = (r->length == WORD(0)); + if (!result) + { + flint_printf("FAIL (check a | gcd(af, ag)):\n"); + fmpz_poly_print(f), flint_printf("\n"); + fmpz_poly_print(g), flint_printf("\n"); + fmpz_poly_print(d), flint_printf("\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(d); + fmpz_poly_clear(f); + fmpz_poly_clear(g); + fmpz_poly_clear(q); + fmpz_poly_clear(r); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-get_coeff_ptr.c b/external/flint-2.4.3/fmpz_poly/test/t-get_coeff_ptr.c new file mode 100644 index 0000000..bee4756 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-get_coeff_ptr.c @@ -0,0 +1,76 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("get_coeff_ptr...."); + fflush(stdout); + + + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t A; + fmpz_t a; + slong n = n_randint(state, 100); + + fmpz_poly_init(A); + fmpz_poly_randtest(A, state, n_randint(state, 100), 100); + fmpz_init(a); + + fmpz_poly_get_coeff_fmpz(a, A, n); + + result = n < fmpz_poly_length(A) ? + fmpz_equal(a, fmpz_poly_get_coeff_ptr(A, n)) : + fmpz_poly_get_coeff_ptr(A, n) == NULL; + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("A = "), fmpz_poly_print(A), flint_printf("\n\n"); + flint_printf("a = "), fmpz_print(a), flint_printf("\n\n"); + flint_printf("n = %wd\n\n", n); + abort(); + } + + fmpz_poly_clear(A); + fmpz_clear(a); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-get_nmod_poly.c b/external/flint-2.4.3/fmpz_poly/test/t-get_nmod_poly.c new file mode 100644 index 0000000..70ec22a --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-get_nmod_poly.c @@ -0,0 +1,87 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("get/set_nmod_poly...."); + fflush(stdout); + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t A; + nmod_poly_t M, M2; + slong length; + mp_limb_t mod; + + length = n_randint(state, 50); + + mod = n_randtest_prime(state, 0); + + nmod_poly_init(M, mod); + nmod_poly_init(M2, mod); + fmpz_poly_init(A); + + nmod_poly_randtest(M, state, length); + + if (i % 2 == 0) + fmpz_poly_set_nmod_poly(A, M); + else + fmpz_poly_set_nmod_poly_unsigned(A, M); + + fmpz_poly_scalar_mul_ui(A, A, UWORD(2)); + nmod_poly_add(M, M, M); + fmpz_poly_get_nmod_poly(M2, A); + + if (!nmod_poly_equal(M, M2)) + { + flint_printf("FAIL!\n"); + abort(); + } + + fmpz_poly_clear(A); + nmod_poly_clear(M); + nmod_poly_clear(M2); + } + + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-get_set_coeff_fmpz.c b/external/flint-2.4.3/fmpz_poly/test/t-get_set_coeff_fmpz.c new file mode 100644 index 0000000..cb9c8fe --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-get_set_coeff_fmpz.c @@ -0,0 +1,83 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, j, result; + FLINT_TEST_INIT(state); + + flint_printf("get/set_coeff_fmpz...."); + fflush(stdout); + + + + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t a; + fmpz_t x1, x2; + slong coeff, len; + + fmpz_poly_init(a); + fmpz_init(x1); + fmpz_init(x2); + len = n_randint(state, 100) + 1; + + for (j = 0; j < 1000; j++) + { + fmpz_randtest(x1, state, 200); + coeff = n_randint(state, len); + fmpz_poly_set_coeff_fmpz(a, coeff, x1); + fmpz_poly_get_coeff_fmpz(x2, a, coeff); + + result = (fmpz_equal(x1, x2)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("x1 = "), fmpz_print(x1), flint_printf("\n"); + flint_printf("x2 = "), fmpz_print(x2), flint_printf("\n"); + flint_printf("coeff = %wd, length = %wd\n", coeff, len); + abort(); + } + } + + fmpz_clear(x1); + fmpz_clear(x2); + fmpz_poly_clear(a); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-get_set_coeff_mpz.c b/external/flint-2.4.3/fmpz_poly/test/t-get_set_coeff_mpz.c new file mode 100644 index 0000000..f1211f6 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-get_set_coeff_mpz.c @@ -0,0 +1,90 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, j, result; + FLINT_TEST_INIT(state); + + flint_printf("get/set_coeff_mpz...."); + fflush(stdout); + + + + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t a; + fmpz_t x1, x2; + mpz_t y1, y2; + slong coeff, len; + + fmpz_poly_init(a); + fmpz_init(x1); + fmpz_init(x2); + mpz_init(y1); + mpz_init(y2); + len = n_randint(state, 100) + 1; + + for (j = 0; j < 1000; j++) + { + fmpz_randtest(x1, state, 200); + fmpz_get_mpz(y1, x1); + coeff = n_randint(state, len); + fmpz_poly_set_coeff_mpz(a, coeff, y1); + fmpz_poly_get_coeff_mpz(y2, a, coeff); + fmpz_set_mpz(x2, y2); + + result = (fmpz_equal(x1, x2)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("x1 = "), fmpz_print(x1), flint_printf("\n"); + flint_printf("x2 = "), fmpz_print(x2), flint_printf("\n"); + flint_printf("coeff = %wd, length = %wd\n", coeff, len); + abort(); + } + } + + fmpz_clear(x1); + fmpz_clear(x2); + mpz_clear(y1); + mpz_clear(y2); + fmpz_poly_clear(a); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-get_set_coeff_si.c b/external/flint-2.4.3/fmpz_poly/test/t-get_set_coeff_si.c new file mode 100644 index 0000000..1cc3f12 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-get_set_coeff_si.c @@ -0,0 +1,77 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz_poly.h" +#include "long_extras.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, j, result; + FLINT_TEST_INIT(state); + + flint_printf("get/set_coeff_si...."); + fflush(stdout); + + + + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t a; + slong coeff, len; + slong n1, n2; + + fmpz_poly_init(a); + len = n_randint(state, 100) + 1; + + for (j = 0; j < 1000; j++) + { + n1 = z_randtest(state); + coeff = n_randint(state, len); + fmpz_poly_set_coeff_si(a, coeff, n1); + n2 = fmpz_poly_get_coeff_si(a, coeff); + + result = (n1 == n2); + if (!result) + { + flint_printf("FAIL: n1 = %wd, n2 = %wd, coeff = %wd, length = %wd\n", + n1, n2, coeff, len); + abort(); + } + } + + fmpz_poly_clear(a); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-get_set_coeff_ui.c b/external/flint-2.4.3/fmpz_poly/test/t-get_set_coeff_ui.c new file mode 100644 index 0000000..5b7ce79 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-get_set_coeff_ui.c @@ -0,0 +1,76 @@ +/*============================================================================ + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +===============================================================================*/ +/**************************************************************************** + +Copyright (C) 2009 William Hart + +*****************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, j, result; + FLINT_TEST_INIT(state); + + flint_printf("get/set_coeff_ui...."); + fflush(stdout); + + + + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t a; + ulong n1, n2; + slong coeff, len; + + fmpz_poly_init(a); + len = n_randint(state, 100) + 1; + + for (j = 0; j < 1000; j++) + { + n1 = n_randtest(state); + coeff = n_randint(state, len); + fmpz_poly_set_coeff_ui(a, coeff, n1); + n2 = fmpz_poly_get_coeff_ui(a, coeff); + + result = (n1 == n2); + if (!result) + { + flint_printf("FAIL: n1 = %wu, n2 = %wu, coeff = %wd, length = %wd\n", + n1, n2, coeff, len); + abort(); + } + } + + fmpz_poly_clear(a); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-get_set_str.c b/external/flint-2.4.3/fmpz_poly/test/t-get_set_str.c new file mode 100644 index 0000000..3ca3166 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-get_set_str.c @@ -0,0 +1,77 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("get_set_str...."); + fflush(stdout); + + + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b; + char * str; + int ans; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_randtest(a, state, n_randint(state, 100), n_randint(state, 200)); + + str = fmpz_poly_get_str(a); + ans = fmpz_poly_set_str(b, str); + + result = (ans == 0 && fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpz_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + flint_free(str); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-get_str.c b/external/flint-2.4.3/fmpz_poly/test/t-get_str.c new file mode 100644 index 0000000..cc0db84 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-get_str.c @@ -0,0 +1,88 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int result; + char *str; + fmpz_poly_t a; + + FLINT_TEST_INIT(state); + + flint_printf("get_str...."); + fflush(stdout); + + fmpz_poly_init(a); + + str = fmpz_poly_get_str(a); + result = strcmp(str, "0") == 0; + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpz_poly_print(a), flint_printf("\n"); + flint_printf("str(a) = {%s}\n", str); + abort(); + } + flint_free(str); + + fmpz_poly_set_si(a, -2); + str = fmpz_poly_get_str(a); + result = strcmp(str, "1 -2") == 0; + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpz_poly_print(a), flint_printf("\n"); + flint_printf("str(a) = {%s}\n", str); + abort(); + } + flint_free(str); + + fmpz_poly_set_coeff_si(a, 3, 1); + str = fmpz_poly_get_str(a); + result = strcmp(str, "4 -2 0 0 1") == 0; + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpz_poly_print(a), flint_printf("\n"); + flint_printf("str(a) = {%s}\n", str); + abort(); + } + flint_free(str); + fmpz_poly_clear(a); + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-get_str_pretty.c b/external/flint-2.4.3/fmpz_poly/test/t-get_str_pretty.c new file mode 100644 index 0000000..540d6a0 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-get_str_pretty.c @@ -0,0 +1,88 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int result; + char *str; + fmpz_poly_t a; + + FLINT_TEST_INIT(state); + + flint_printf("get_str_pretty...."); + fflush(stdout); + + fmpz_poly_init(a); + + str = fmpz_poly_get_str_pretty(a, "t"); + result = strcmp(str, "0") == 0; + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpz_poly_print(a), flint_printf("\n"); + flint_printf("str(a) = {%s}\n", str); + abort(); + } + flint_free(str); + + fmpz_poly_set_si(a, -2); + str = fmpz_poly_get_str_pretty(a, "t"); + result = strcmp(str, "-2") == 0; + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpz_poly_print(a), flint_printf("\n"); + flint_printf("str(a) = {%s}\n", str); + abort(); + } + flint_free(str); + + fmpz_poly_set_coeff_si(a, 3, 1); + str = fmpz_poly_get_str_pretty(a, "t"); + result = strcmp(str, "t^3-2") == 0; + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpz_poly_print(a), flint_printf("\n"); + flint_printf("str(a) = {%s}\n", str); + abort(); + } + flint_free(str); + fmpz_poly_clear(a); + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-hensel_lift.c b/external/flint-2.4.3/fmpz_poly/test/t-hensel_lift.c new file mode 100644 index 0000000..c82cb3e --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-hensel_lift.c @@ -0,0 +1,213 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("hensel_lift...."); + fflush(stdout); + + + + /* We check that lifting local factors of F_poly yields factors */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t F_poly, F_poly2, F_poly3, A, B, G, H, + A_out, B_out, G_out, H_out, Prod_1, Prod_2; + nmod_poly_t a, b, d, g, h, prod; + fmpz_t p, p1, big_P, p1_2, big_P_2; + slong bits, length, nbits, n, exp, part_exp; + + bits = n_randint(state, 200) + 1; + nbits = n_randint(state, FLINT_BITS - 6) + 6; + + fmpz_init(p); + fmpz_init(p1); + fmpz_init(big_P); + fmpz_init(p1_2); + fmpz_init(big_P_2); + + fmpz_poly_init(F_poly); + fmpz_poly_init(F_poly2); + fmpz_poly_init(F_poly3); + + fmpz_poly_init(Prod_1); + fmpz_poly_init(Prod_2); + + fmpz_poly_init(A); + fmpz_poly_init(B); + fmpz_poly_init(G); + fmpz_poly_init(H); + fmpz_poly_init(A_out); + fmpz_poly_init(B_out); + fmpz_poly_init(G_out); + fmpz_poly_init(H_out); + + n = n_randprime(state, nbits, 0); + exp = bits/(FLINT_BIT_COUNT(n) - 1) + 1; + part_exp = n_randint(state, exp); + + nmod_poly_init(g, n); + nmod_poly_init(h, n); + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(d, n); + nmod_poly_init(prod, n); + + do { + length = n_randint(state, 200) + 2; + + do { fmpz_poly_randtest(F_poly2, state, length, bits); } + while (F_poly2->length < 2); + + fmpz_set_ui(F_poly2->coeffs, n_randbits(state, FLINT_MIN(bits, FLINT_BITS - 2))); + fmpz_set_ui(F_poly2->coeffs + F_poly2->length - 1, 1); + + length = n_randint(state, 200) + 2; + + do { fmpz_poly_randtest(F_poly3, state, length, bits); } + while (F_poly3->length < 2); + + fmpz_set_ui(F_poly3->coeffs, n_randbits(state, FLINT_MIN(bits, FLINT_BITS - 2))); + fmpz_set_ui(F_poly3->coeffs + F_poly3->length - 1, 1); + + fmpz_poly_mul(F_poly, F_poly2, F_poly3); + + fmpz_poly_get_nmod_poly(prod, F_poly); + } while (!nmod_poly_is_squarefree(prod)); + + fmpz_poly_get_nmod_poly(g, F_poly2); + fmpz_poly_get_nmod_poly(h, F_poly3); + + nmod_poly_xgcd(d, a, b, g, h); + nmod_poly_clear(prod); + nmod_poly_clear(d); + + fmpz_poly_set_nmod_poly(A, a); + fmpz_poly_set_nmod_poly(B, b); + fmpz_poly_set_nmod_poly(G, g); + fmpz_poly_set_nmod_poly(H, h); + + fmpz_set_ui(p, n); + fmpz_set_ui(p1, n); + fmpz_set_ui(big_P, n); + fmpz_set_ui(p1_2, n); + fmpz_set_ui(big_P_2, n); + + part_exp = 1; + + while (part_exp < exp) + { + fmpz_set(p, big_P); + fmpz_set_ui(p1, n); + fmpz_set_ui(big_P, n); + + if (exp - part_exp <= part_exp) + { + fmpz_pow_ui(p1, p1, exp - part_exp); + fmpz_pow_ui(big_P, big_P, exp); + part_exp = exp; + } + else + { + fmpz_set(p1, p); + fmpz_pow_ui(big_P, big_P, 2*part_exp); + part_exp = 2*part_exp; + } + + fmpz_poly_hensel_lift(G_out, H_out, A_out, B_out, F_poly, + G, H, A, B, p, p1); + + fmpz_poly_set(G, G_out); + fmpz_poly_set(H, H_out); + fmpz_poly_set(A, A_out); + fmpz_poly_set(B, B_out); + } + + fmpz_poly_mul(Prod_1, A, G); + fmpz_poly_mul(Prod_2, B, H); + fmpz_poly_add(Prod_1, Prod_1, Prod_2); + + fmpz_poly_scalar_smod_fmpz(Prod_1, Prod_1, big_P); + + result = (Prod_1->length == 1 && fmpz_is_one(Prod_1->coeffs)); + + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("length = %wd, bits = %wd, n = %wd, exp = %wd\n", length, bits, n, exp); + fmpz_poly_print(F_poly); flint_printf("\n\n"); + fmpz_poly_print(F_poly2); flint_printf("\n\n"); + fmpz_poly_print(F_poly3); flint_printf("\n\n"); + fmpz_poly_print(Prod_1); flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(g); + nmod_poly_clear(h); + nmod_poly_clear(a); + nmod_poly_clear(b); + + fmpz_poly_clear(Prod_1); + fmpz_poly_clear(Prod_2); + + fmpz_poly_clear(A); + fmpz_poly_clear(B); + fmpz_poly_clear(G); + fmpz_poly_clear(H); + fmpz_poly_clear(A_out); + fmpz_poly_clear(B_out); + fmpz_poly_clear(G_out); + fmpz_poly_clear(H_out); + + fmpz_clear(p); + fmpz_clear(p1); + fmpz_clear(big_P); + fmpz_clear(p1_2); + fmpz_clear(big_P_2); + + fmpz_poly_clear(F_poly3); + fmpz_poly_clear(F_poly2); + fmpz_poly_clear(F_poly); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-hensel_lift_once.c b/external/flint-2.4.3/fmpz_poly/test/t-hensel_lift_once.c new file mode 100644 index 0000000..e025a7a --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-hensel_lift_once.c @@ -0,0 +1,132 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("hensel_lift_once...."); + fflush(stdout); + + /* We check that lifting local factors of F yields factors */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t F, G, H, R; + fmpz_poly_factor_t F_fac; + nmod_poly_factor_t f_fac; + slong bits, nbits, n, exp, j; + + bits = n_randint(state, 200) + 1; + nbits = n_randint(state, FLINT_BITS - 6) + 6; + + fmpz_poly_init(F); + fmpz_poly_init(G); + fmpz_poly_init(H); + fmpz_poly_init(R); + nmod_poly_factor_init(f_fac); + fmpz_poly_factor_init(F_fac); + + n = n_randprime(state, nbits, 0); + exp = bits / (FLINT_BIT_COUNT(n) - 1) + 1; + + /* Produce F as the product of random G and H */ + { + nmod_poly_t f; + + nmod_poly_init(f, n); + + do { + do { + fmpz_poly_randtest(G, state, n_randint(state, 200) + 2, bits); + } while (G->length < 2); + + fmpz_randtest_not_zero(G->coeffs, state, bits); + fmpz_one(fmpz_poly_lead(G)); + + do { + fmpz_poly_randtest(H, state, n_randint(state, 200) + 2, bits); + } while (H->length < 2); + + fmpz_randtest_not_zero(H->coeffs, state, bits); + fmpz_one(fmpz_poly_lead(H)); + + fmpz_poly_mul(F, G, H); + + fmpz_poly_get_nmod_poly(f, F); + } while (!nmod_poly_is_squarefree(f)); + + fmpz_poly_get_nmod_poly(f, G); + nmod_poly_factor_insert(f_fac, f, 1); + fmpz_poly_get_nmod_poly(f, H); + nmod_poly_factor_insert(f_fac, f, 1); + nmod_poly_clear(f); + } + + fmpz_poly_hensel_lift_once(F_fac, F, f_fac, exp); + + result = 1; + for (j = 0; j < F_fac->num; j++) + { + fmpz_poly_rem(R, F, F_fac->p + j); + result &= (R->length == 0); + } + + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("bits = %wd, n = %wd, exp = %wd\n", bits, n, exp); + fmpz_poly_print(F); flint_printf("\n\n"); + fmpz_poly_print(G); flint_printf("\n\n"); + fmpz_poly_print(H); flint_printf("\n\n"); + fmpz_poly_factor_print(F_fac); flint_printf("\n\n"); + abort(); + } + + nmod_poly_factor_clear(f_fac); + fmpz_poly_factor_clear(F_fac); + fmpz_poly_clear(F); + fmpz_poly_clear(G); + fmpz_poly_clear(H); + fmpz_poly_clear(R); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} + diff --git a/external/flint-2.4.3/fmpz_poly/test/t-hensel_lift_without_only_inverse.c b/external/flint-2.4.3/fmpz_poly/test/t-hensel_lift_without_only_inverse.c new file mode 100644 index 0000000..d85c342 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-hensel_lift_without_only_inverse.c @@ -0,0 +1,212 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("hensel_lift_without_only_inverse...."); + fflush(stdout); + + + + /* We check that lifting local factors of F_poly yields factors */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t F_poly, F_poly2, F_poly3, A, B, G, H, + A_out, B_out, G_out, H_out, Prod_1, Prod_2; + nmod_poly_t a, b, d, g, h, prod; + fmpz_t p, p1, big_P, p1_2, big_P_2; + slong bits, length, nbits, n, exp, part_exp; + + bits = n_randint(state, 200) + 1; + nbits = n_randint(state, FLINT_BITS - 6) + 6; + + fmpz_init(p); + fmpz_init(p1); + fmpz_init(big_P); + fmpz_init(p1_2); + fmpz_init(big_P_2); + + fmpz_poly_init(F_poly); + fmpz_poly_init(F_poly2); + fmpz_poly_init(F_poly3); + + fmpz_poly_init(Prod_1); + fmpz_poly_init(Prod_2); + + fmpz_poly_init(A); + fmpz_poly_init(B); + fmpz_poly_init(G); + fmpz_poly_init(H); + fmpz_poly_init(A_out); + fmpz_poly_init(B_out); + fmpz_poly_init(G_out); + fmpz_poly_init(H_out); + + n = n_randprime(state, nbits, 0); + exp = bits/(FLINT_BIT_COUNT(n) - 1) + 1; + part_exp = n_randint(state, exp); + + nmod_poly_init(g, n); + nmod_poly_init(h, n); + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(d, n); + nmod_poly_init(prod, n); + + do + { + length = n_randint(state, 200) + 2; + do { fmpz_poly_randtest(F_poly2, state, length, bits); } + while (F_poly2->length < 2); + fmpz_set_ui(F_poly2->coeffs, n_randbits(state, FLINT_MIN(bits, FLINT_BITS - 2))); + fmpz_set_ui(F_poly2->coeffs + F_poly2->length - 1, 1); + + length = n_randint(state, 200) + 2; + do { fmpz_poly_randtest(F_poly3, state, length, bits); } + while (F_poly3->length < 2); + fmpz_set_ui(F_poly3->coeffs, n_randbits(state, FLINT_MIN(bits, FLINT_BITS - 2))); + fmpz_set_ui(F_poly3->coeffs + F_poly3->length - 1, 1); + + fmpz_poly_mul(F_poly, F_poly2, F_poly3); + + fmpz_poly_get_nmod_poly(prod, F_poly); + } while (!nmod_poly_is_squarefree(prod)); + + fmpz_poly_get_nmod_poly(g, F_poly2); + fmpz_poly_get_nmod_poly(h, F_poly3); + + nmod_poly_xgcd(d, a, b, g, h); + nmod_poly_clear(prod); + nmod_poly_clear(d); + + fmpz_poly_set_nmod_poly(A, a); + fmpz_poly_set_nmod_poly(B, b); + fmpz_poly_set_nmod_poly(G, g); + fmpz_poly_set_nmod_poly(H, h); + + fmpz_set_ui(p, n); + fmpz_set_ui(p1, n); + fmpz_set_ui(big_P, n); + fmpz_set_ui(p1_2, n); + fmpz_set_ui(big_P_2, n); + + part_exp = 1; + + while (part_exp < exp) + { + fmpz_set(p, big_P); + fmpz_set_ui(p1, n); + fmpz_set_ui(big_P, n); + + if (exp - part_exp <= part_exp) + { + fmpz_pow_ui(p1, p1, exp - part_exp); + fmpz_pow_ui(big_P, big_P, exp); + part_exp = exp; + } + else + { + fmpz_set(p1, p); + fmpz_pow_ui(big_P, big_P, 2*part_exp); + part_exp = 2*part_exp; + } + + fmpz_poly_hensel_lift_without_inverse(G_out, H_out, F_poly, + G, H, A, B, p, p1); + fmpz_poly_hensel_lift_only_inverse(A_out, B_out, + G_out, H_out, A, B, p, p1); + + fmpz_poly_set(G, G_out); + fmpz_poly_set(H, H_out); + fmpz_poly_set(A, A_out); + fmpz_poly_set(B, B_out); + } + + fmpz_poly_mul(Prod_1, A, G); + fmpz_poly_mul(Prod_2, B, H); + fmpz_poly_add(Prod_1, Prod_1, Prod_2); + + fmpz_poly_scalar_smod_fmpz(Prod_1, Prod_1, big_P); + + result = (Prod_1->length == 1 && fmpz_is_one(Prod_1->coeffs)); + + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("length = %wd, bits = %wd, n = %wd, exp = %wd\n", length, bits, n, exp); + fmpz_poly_print(F_poly); flint_printf("\n\n"); + fmpz_poly_print(F_poly2); flint_printf("\n\n"); + fmpz_poly_print(F_poly3); flint_printf("\n\n"); + fmpz_poly_print(Prod_1); flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(g); + nmod_poly_clear(h); + nmod_poly_clear(a); + nmod_poly_clear(b); + + fmpz_poly_clear(Prod_1); + fmpz_poly_clear(Prod_2); + + fmpz_poly_clear(A); + fmpz_poly_clear(B); + fmpz_poly_clear(G); + fmpz_poly_clear(H); + fmpz_poly_clear(A_out); + fmpz_poly_clear(B_out); + fmpz_poly_clear(G_out); + fmpz_poly_clear(H_out); + + fmpz_clear(p); + fmpz_clear(p1); + fmpz_clear(big_P); + fmpz_clear(p1_2); + fmpz_clear(big_P_2); + + fmpz_poly_clear(F_poly3); + fmpz_poly_clear(F_poly2); + fmpz_poly_clear(F_poly); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-hensel_start_continue_lift.c b/external/flint-2.4.3/fmpz_poly/test/t-hensel_start_continue_lift.c new file mode 100644 index 0000000..00dd651 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-hensel_start_continue_lift.c @@ -0,0 +1,177 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "nmod_poly.h" +#include "ulong_extras.h" +#include "mpn_extras.h" +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("hensel_start_continue_lift...."); + fflush(stdout); + + + + /* We check that lifting local factors of F yields factors */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t F, G, H, R; + nmod_poly_factor_t f_fac; + fmpz_poly_factor_t F_fac; + slong bits, nbits, n, exp, j, part_exp; + + slong r; + fmpz_poly_t *v, *w; + slong *link; + slong prev_exp; + + bits = n_randint(state, 200) + 1; + nbits = n_randint(state, FLINT_BITS - 6) + 6; + + fmpz_poly_init(F); + fmpz_poly_init(G); + fmpz_poly_init(H); + fmpz_poly_init(R); + nmod_poly_factor_init(f_fac); + fmpz_poly_factor_init(F_fac); + + n = n_randprime(state, nbits, 0); + exp = bits / (FLINT_BIT_COUNT(n) - 1) + 1; + part_exp = n_randint(state, exp); + + /* Produce F as the product of random G and H */ + { + nmod_poly_t f; + + nmod_poly_init(f, n); + + do { + do { + fmpz_poly_randtest(G, state, n_randint(state, 200) + 2, bits); + } while (G->length < 2); + + fmpz_randtest_not_zero(G->coeffs, state, bits); + fmpz_one(fmpz_poly_lead(G)); + + do { + fmpz_poly_randtest(H, state, n_randint(state, 200) + 2, bits); + } while (H->length < 2); + + fmpz_randtest_not_zero(H->coeffs, state, bits); + fmpz_one(fmpz_poly_lead(H)); + + fmpz_poly_mul(F, G, H); + + fmpz_poly_get_nmod_poly(f, F); + } while (!nmod_poly_is_squarefree(f)); + + fmpz_poly_get_nmod_poly(f, G); + nmod_poly_factor_insert(f_fac, f, 1); + fmpz_poly_get_nmod_poly(f, H); + nmod_poly_factor_insert(f_fac, f, 1); + nmod_poly_clear(f); + } + + r = f_fac->num; + v = flint_malloc((2*r - 2)*sizeof(fmpz_poly_t)); + w = flint_malloc((2*r - 2)*sizeof(fmpz_poly_t)); + link = flint_malloc((2*r - 2)*sizeof(slong)); + + for (j = 0; j < 2*r - 2; j++) + { + fmpz_poly_init(v[j]); + fmpz_poly_init(w[j]); + } + + if (part_exp < 1) + { + _fmpz_poly_hensel_start_lift(F_fac, link, v, w, F, f_fac, exp); + } + else + { + fmpz_t nn; + + fmpz_init_set_ui(nn, n); + + prev_exp = _fmpz_poly_hensel_start_lift(F_fac, link, v, w, + F, f_fac, part_exp); + _fmpz_poly_hensel_continue_lift(F_fac, link, v, w, + F, prev_exp, part_exp, exp, nn); + + fmpz_clear(nn); + } + + result = 1; + for (j = 0; j < F_fac->num; j++) + { + fmpz_poly_rem(R, F, F_fac->p + j); + result &= (R->length == 0); + } + + for (j = 0; j < 2*r - 2; j++) + { + fmpz_poly_clear(v[j]); + fmpz_poly_clear(w[j]); + } + + flint_free(link); + flint_free(v); + flint_free(w); + + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("bits = %wd, n = %wd, exp = %wd\n", bits, n, exp); + fmpz_poly_print(F); flint_printf("\n\n"); + fmpz_poly_print(G); flint_printf("\n\n"); + fmpz_poly_print(H); flint_printf("\n\n"); + fmpz_poly_factor_print(F_fac); flint_printf("\n\n"); + abort(); + } + + nmod_poly_factor_clear(f_fac); + fmpz_poly_factor_clear(F_fac); + + fmpz_poly_clear(F); + fmpz_poly_clear(H); + fmpz_poly_clear(G); + fmpz_poly_clear(R); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-init_realloc_clear.c b/external/flint-2.4.3/fmpz_poly/test/t-init_realloc_clear.c new file mode 100644 index 0000000..f962377 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-init_realloc_clear.c @@ -0,0 +1,74 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + flint_printf("init/init2/realloc/clear...."); + fflush(stdout); + + + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t a; + + fmpz_poly_init2(a, n_randint(state, 100)); + fmpz_poly_clear(a); + } + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t a; + + fmpz_poly_init2(a, n_randint(state, 100)); + fmpz_poly_realloc(a, n_randint(state, 100)); + fmpz_poly_clear(a); + } + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t a; + + fmpz_poly_init(a); + fmpz_poly_randtest(a, state, n_randint(state, 100), 200); + fmpz_poly_clear(a); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-interpolate_fmpz_vec.c b/external/flint-2.4.3/fmpz_poly/test/t-interpolate_fmpz_vec.c new file mode 100644 index 0000000..1d3d43d --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-interpolate_fmpz_vec.c @@ -0,0 +1,88 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("interpolate_fmpz_vec...."); + fflush(stdout); + + + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t P, Q; + fmpz *x, *y; + slong j, n, npoints, bits; + + npoints = n_randint(state, 50); + n = n_randint(state, npoints + 1); + bits = n_randint(state, 100); + + x = _fmpz_vec_init(npoints); + y = _fmpz_vec_init(npoints); + + fmpz_poly_init(P); + fmpz_poly_init(Q); + + fmpz_poly_randtest(P, state, n, bits); + + for (j = 0; j < npoints; j++) + fmpz_set_si(x + j, -npoints/2 + j); + + fmpz_poly_evaluate_fmpz_vec(y, P, x, npoints); + fmpz_poly_interpolate_fmpz_vec(Q, x, y, npoints); + + result = (fmpz_poly_equal(P, Q)); + if (!result) + { + flint_printf("FAIL (P != Q):\n"); + fmpz_poly_print(P), flint_printf("\n\n"); + fmpz_poly_print(Q), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(P); + fmpz_poly_clear(Q); + _fmpz_vec_clear(x, npoints); + _fmpz_vec_clear(y, npoints); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-inv_series_newton.c b/external/flint-2.4.3/fmpz_poly/test/t-inv_series_newton.c new file mode 100644 index 0000000..c21a7b9 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-inv_series_newton.c @@ -0,0 +1,116 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("inv_series_newton...."); + fflush(stdout); + + + + /* Check Q^{-1} * Q is congruent 1 mod t^n */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c, one; + slong n = n_randint(state, 80) + 1; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_init(one); + + fmpz_poly_randtest_not_zero(a, state, n_randint(state, 80) + 1, 100); + fmpz_poly_set_coeff_si(a, 0, n_randint(state, 2) ? 1 : -1); + + fmpz_poly_set_ui(one, 1); + + fmpz_poly_inv_series_newton(b, a, n); + fmpz_poly_mullow(c, a, b, n); + + result = (fmpz_poly_equal(c, one)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpz_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_poly_print(b), flint_printf("\n\n"); + flint_printf("c = "), fmpz_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + fmpz_poly_clear(one); + } + + /* Verify bug fix for the case Q = -1 mod (x) */ + { + fmpz_poly_t a, b, c, one; + slong n = 1; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_init(one); + + fmpz_poly_set_si(a, -1); + fmpz_poly_set_ui(one, 1); + + fmpz_poly_inv_series_newton(b, a, n); + fmpz_poly_mullow(c, a, b, n); + + result = (fmpz_poly_equal(c, one)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpz_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_poly_print(b), flint_printf("\n\n"); + flint_printf("c = "), fmpz_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + fmpz_poly_clear(one); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-is_squarefree.c b/external/flint-2.4.3/fmpz_poly/test/t-is_squarefree.c new file mode 100644 index 0000000..f54d55a --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-is_squarefree.c @@ -0,0 +1,135 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("is_squarefree...."); + fflush(stdout); + + + + /* Check that polynomials of degree <= 1 are square-free */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpz_poly_t f; + + fmpz_poly_init(f); + fmpz_poly_randtest(f, state, n_randint(state, 2), 100); + + result = (fmpz_poly_is_squarefree(f)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_debug(f), flint_printf("\n"); + abort(); + } + + fmpz_poly_clear(f); + } + + /* Check that a^2 f is not square-free */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, f; + + fmpz_poly_init(a); + fmpz_poly_randtest_not_zero(a, state, n_randint(state, 20) + 1, 40); + if (a->length < 2) + { + fmpz_poly_clear(a); + continue; + } + fmpz_poly_init(f); + fmpz_poly_randtest_not_zero(f, state, n_randint(state, 20) + 1, 40); + + fmpz_poly_mul(a, a, a); + fmpz_poly_mul(f, a, f); + + result = (!fmpz_poly_is_squarefree(f)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_debug(f), flint_printf("\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(f); + } + + /* Check that f + N*(x^M + 1) is square-free, for N >> f, M > deg(f) */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, f; + fmpz_t N; + + fmpz_poly_init(a); + fmpz_poly_set_coeff_si(a, 0, WORD(1)); + fmpz_poly_set_coeff_si(a, n_randint(state, 20), WORD(1)); + if (a->length < 2) + { + fmpz_poly_clear(a); + continue; + } + fmpz_poly_init(f); + fmpz_poly_randtest(f, state, a->length - 2, 40); + + fmpz_init_set_ui(N, UWORD(1)); + fmpz_mul_2exp(N, N, 45 + a->length); + + fmpz_poly_scalar_mul_fmpz(a, a, N); + fmpz_poly_add(f, a, f); + + result = fmpz_poly_is_squarefree(f); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_debug(f), flint_printf("\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(f); + fmpz_clear(N); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-lcm.c b/external/flint-2.4.3/fmpz_poly/test/t-lcm.c new file mode 100644 index 0000000..e7e4b66 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-lcm.c @@ -0,0 +1,152 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("lcm...."); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + + fmpz_poly_randtest(b, state, n_randint(state, 40), 80); + fmpz_poly_randtest(c, state, n_randint(state, 40), 80); + + fmpz_poly_lcm(a, b, c); + fmpz_poly_lcm(b, b, c); + + result = (fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL (aliasing a and b):\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + /* Check aliasing of a and c */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + + fmpz_poly_randtest(b, state, n_randint(state, 40), 80); + fmpz_poly_randtest(c, state, n_randint(state, 40), 80); + + fmpz_poly_lcm(a, b, c); + fmpz_poly_lcm(c, b, c); + + result = (fmpz_poly_equal(a, c)); + if (!result) + { + flint_printf("FAIL (aliasing a and c):\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + /* Check that GCD(f, g) LCM(f, g) == f g */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpz_poly_t f, g, gcd, lcm, lhs, rhs; + + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_poly_init(gcd); + fmpz_poly_init(lcm); + fmpz_poly_init(lhs); + fmpz_poly_init(rhs); + + fmpz_poly_randtest(f, state, n_randint(state, 40), 80); + fmpz_poly_randtest(g, state, n_randint(state, 40), 80); + + fmpz_poly_gcd(gcd, f, g); + fmpz_poly_lcm(lcm, f, g); + fmpz_poly_mul(lhs, gcd, lcm); + fmpz_poly_mul(rhs, f, g); + if (!fmpz_poly_is_zero(rhs) && fmpz_sgn(fmpz_poly_lead(rhs)) < 0) + fmpz_poly_neg(rhs, rhs); + + result = (fmpz_poly_equal(lhs, rhs)); + if (!result) + { + flint_printf("FAIL (GCD(f, g) * LCM(f, g) == f * g):\n"); + fmpz_poly_print(f), flint_printf("\n"); + fmpz_poly_print(g), flint_printf("\n"); + fmpz_poly_print(gcd), flint_printf("\n"); + fmpz_poly_print(lcm), flint_printf("\n"); + fmpz_poly_print(lhs), flint_printf("\n"); + fmpz_poly_print(rhs), flint_printf("\n"); + abort(); + } + + fmpz_poly_clear(f); + fmpz_poly_clear(g); + fmpz_poly_clear(gcd); + fmpz_poly_clear(lcm); + fmpz_poly_clear(lhs); + fmpz_poly_clear(rhs); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/fmpz_poly/test/t-mul.c b/external/flint-2.4.3/fmpz_poly/test/t-mul.c new file mode 100644 index 0000000..4dd1000 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-mul.c @@ -0,0 +1,188 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("mul...."); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(b, state, n_randint(state, 50), 500); + fmpz_poly_randtest(c, state, n_randint(state, 50), 500); + + fmpz_poly_mul(a, b, c); + fmpz_poly_mul(b, b, c); + + result = (fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + /* Check aliasing of a and c */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(b, state, n_randint(state, 50), 500); + fmpz_poly_randtest(c, state, n_randint(state, 50), 500); + + fmpz_poly_mul(a, b, c); + fmpz_poly_mul(c, b, c); + + result = (fmpz_poly_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + /* Check (b*c)+(b*d) = b*(c+d) */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a1, a2, b, c, d; + + fmpz_poly_init(a1); + fmpz_poly_init(a2); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_init(d); + fmpz_poly_randtest(b, state, n_randint(state, 100), 500); + fmpz_poly_randtest(c, state, n_randint(state, 100), 500); + fmpz_poly_randtest(d, state, n_randint(state, 100), 500); + + fmpz_poly_mul(a1, b, c); + fmpz_poly_mul(a2, b, d); + fmpz_poly_add(a1, a1, a2); + + fmpz_poly_add(c, c, d); + fmpz_poly_mul(a2, b, c); + + result = (fmpz_poly_equal(a1, a2)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a1), flint_printf("\n\n"); + fmpz_poly_print(a2), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a1); + fmpz_poly_clear(a2); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + fmpz_poly_clear(d); + } + + /* Check _fmpz_poly_mul directly */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + slong len1, len2; + fmpz_poly_t a, b, out1, out2; + + len1 = n_randint(state, 100) + 1; + len2 = n_randint(state, 100) + 1; + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(out1); + fmpz_poly_init(out2); + fmpz_poly_randtest(a, state, len1, 200); + fmpz_poly_randtest(b, state, len2, 200); + + fmpz_poly_mul(out1, a, b); + fmpz_poly_fit_length(a, a->alloc + n_randint(state, 10)); + fmpz_poly_fit_length(b, b->alloc + n_randint(state, 10)); + a->length = a->alloc; + b->length = b->alloc; + fmpz_poly_fit_length(out2, a->length + b->length - 1); + if (a->length >= b->length) + _fmpz_poly_mul(out2->coeffs, a->coeffs, a->length, + b->coeffs, b->length); + else + _fmpz_poly_mul(out2->coeffs, b->coeffs, b->length, + a->coeffs, a->length); + _fmpz_poly_set_length(out2, a->length + b->length - 1); + _fmpz_poly_normalise(out2); + + result = (fmpz_poly_equal(out1, out2)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(out1), flint_printf("\n\n"); + fmpz_poly_print(out2), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(out1); + fmpz_poly_clear(out2); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-mul_KS.c b/external/flint-2.4.3/fmpz_poly/test/t-mul_KS.c new file mode 100644 index 0000000..737426a --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-mul_KS.c @@ -0,0 +1,234 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("mul_KS...."); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(b, state, n_randint(state, 50), 200); + fmpz_poly_randtest(c, state, n_randint(state, 50), 200); + fmpz_poly_mul_KS(a, b, c); + fmpz_poly_mul_KS(b, b, c); + + result = (fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + /* Check aliasing of a and c */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(b, state, n_randint(state, 50), 200); + fmpz_poly_randtest(c, state, n_randint(state, 50), 200); + + fmpz_poly_mul_KS(a, b, c); + fmpz_poly_mul_KS(c, b, c); + + result = (fmpz_poly_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + /* Check aliasing of b and c */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(b, state, n_randint(state, 50), 200); + fmpz_poly_set(c, b); + + fmpz_poly_mul_KS(a, b, b); + fmpz_poly_mul_KS(c, b, c); + + result = (fmpz_poly_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + /* Compare with mul_classical */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c, d; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_init(d); + fmpz_poly_randtest(b, state, n_randint(state, 50), 200); + fmpz_poly_randtest(c, state, n_randint(state, 50), 200); + + fmpz_poly_mul_KS(a, b, c); + fmpz_poly_mul_classical(d, b, c); + + result = (fmpz_poly_equal(a, d)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(d), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + fmpz_poly_clear(d); + } + + /* Compare with mul_classical unsigned */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c, d; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_init(d); + fmpz_poly_randtest_unsigned(b, state, n_randint(state, 50), 200); + fmpz_poly_randtest_unsigned(c, state, n_randint(state, 50), 200); + + fmpz_poly_mul_KS(a, b, c); + fmpz_poly_mul_classical(d, b, c); + + result = (fmpz_poly_equal(a, d)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(d), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + fmpz_poly_clear(d); + } + + /* Check _fmpz_poly_mul_KS directly */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + slong len1, len2; + fmpz_poly_t a, b, out1, out2; + + len1 = n_randint(state, 100) + 1; + len2 = n_randint(state, 100) + 1; + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(out1); + fmpz_poly_init(out2); + fmpz_poly_randtest(a, state, len1, 200); + fmpz_poly_randtest(b, state, len2, 200); + + fmpz_poly_mul_KS(out1, a, b); + fmpz_poly_fit_length(a, a->alloc + n_randint(state, 10)); + fmpz_poly_fit_length(b, b->alloc + n_randint(state, 10)); + a->length = a->alloc; + b->length = b->alloc; + fmpz_poly_fit_length(out2, a->length + b->length - 1); + _fmpz_poly_mul_KS(out2->coeffs, a->coeffs, a->length, + b->coeffs, b->length); + _fmpz_poly_set_length(out2, a->length + b->length - 1); + _fmpz_poly_normalise(out2); + + result = (fmpz_poly_equal(out1, out2)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(out1), flint_printf("\n\n"); + fmpz_poly_print(out2), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(out1); + fmpz_poly_clear(out2); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-mul_SS.c b/external/flint-2.4.3/fmpz_poly/test/t-mul_SS.c new file mode 100644 index 0000000..96b14b8 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-mul_SS.c @@ -0,0 +1,223 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009, 2011 William Hart + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("mul_SS...."); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(b, state, n_randint(state, 50), 200); + fmpz_poly_randtest(c, state, n_randint(state, 50), 200); + fmpz_poly_mul_SS(a, b, c); + fmpz_poly_mul_SS(b, b, c); + + result = (fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + /* Check aliasing of a and c */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(b, state, n_randint(state, 50), 200); + fmpz_poly_randtest(c, state, n_randint(state, 50), 200); + + fmpz_poly_mul_SS(a, b, c); + fmpz_poly_mul_SS(c, b, c); + + result = (fmpz_poly_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + /* Check aliasing of b and c */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(b, state, n_randint(state, 50), 200); + fmpz_poly_set(c, b); + + fmpz_poly_mul_SS(a, b, b); + fmpz_poly_mul_SS(c, b, c); + + result = (fmpz_poly_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + /* Compare with mul_KS */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c, d; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_init(d); + fmpz_poly_randtest(b, state, n_randint(state, 300), n_randint(state, 500) + 1); + fmpz_poly_randtest(c, state, n_randint(state, 300), n_randint(state, 500) + 1); + + fmpz_poly_mul_SS(a, b, c); + fmpz_poly_mul_KS(d, b, c); + + result = fmpz_poly_equal(a, d); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(d), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + fmpz_poly_clear(d); + } + + /* Compare with mul_KS large */ + for (i = 0; i < 40 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c, d; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_init(d); + fmpz_poly_randtest(b, state, n_randint(state, 300), n_randint(state, 20000) + 1); + fmpz_poly_randtest(c, state, n_randint(state, 300), n_randint(state, 20000) + 1); + + fmpz_poly_mul_SS(a, b, c); + fmpz_poly_mul_KS(d, b, c); + + result = (fmpz_poly_equal(a, d)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(d), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + fmpz_poly_clear(d); + } + + /* Compare with mul_KS unsigned */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c, d; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_init(d); + fmpz_poly_randtest_unsigned(b, state, n_randint(state, 300), n_randint(state, 500) + 1); + fmpz_poly_randtest_unsigned(c, state, n_randint(state, 300), n_randint(state, 500) + 1); + + fmpz_poly_mul_SS(a, b, c); + fmpz_poly_mul_KS(d, b, c); + + result = (fmpz_poly_equal(a, d)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(d), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + fmpz_poly_clear(d); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-mul_classical.c b/external/flint-2.4.3/fmpz_poly/test/t-mul_classical.c new file mode 100644 index 0000000..605cc45 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-mul_classical.c @@ -0,0 +1,184 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("mul_classical...."); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(b, state, n_randint(state, 50), 200); + fmpz_poly_randtest(c, state, n_randint(state, 50), 200); + + fmpz_poly_mul_classical(a, b, c); + fmpz_poly_mul_classical(b, b, c); + + result = (fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + /* Check aliasing of a and c */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(b, state, n_randint(state, 50), 200); + fmpz_poly_randtest(c, state, n_randint(state, 50), 200); + + fmpz_poly_mul_classical(a, b, c); + fmpz_poly_mul_classical(c, b, c); + + result = (fmpz_poly_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + /* Check (b*c)+(b*d) = b*(c+d) */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a1, a2, b, c, d; + + fmpz_poly_init(a1); + fmpz_poly_init(a2); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_init(d); + fmpz_poly_randtest(b, state, n_randint(state, 100), 200); + fmpz_poly_randtest(c, state, n_randint(state, 100), 200); + fmpz_poly_randtest(d, state, n_randint(state, 100), 200); + + fmpz_poly_mul_classical(a1, b, c); + fmpz_poly_mul_classical(a2, b, d); + fmpz_poly_add(a1, a1, a2); + + fmpz_poly_add(c, c, d); + fmpz_poly_mul_classical(a2, b, c); + + result = (fmpz_poly_equal(a1, a2)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a1), flint_printf("\n\n"); + fmpz_poly_print(a2), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a1); + fmpz_poly_clear(a2); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + fmpz_poly_clear(d); + } + + /* Check _fmpz_poly_mul_classical directly */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + slong len1, len2; + fmpz_poly_t a, b, out1, out2; + + len1 = n_randint(state, 100) + 1; + len2 = n_randint(state, 100) + 1; + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(out1); + fmpz_poly_init(out2); + fmpz_poly_randtest(a, state, len1, 200); + fmpz_poly_randtest(b, state, len2, 200); + + fmpz_poly_mul_classical(out1, a, b); + fmpz_poly_fit_length(a, a->alloc + n_randint(state, 10)); + fmpz_poly_fit_length(b, b->alloc + n_randint(state, 10)); + a->length = a->alloc; + b->length = b->alloc; + fmpz_poly_fit_length(out2, a->length + b->length - 1); + _fmpz_poly_mul_classical(out2->coeffs, a->coeffs, a->length, + b->coeffs, b->length); + _fmpz_poly_set_length(out2, a->length + b->length - 1); + _fmpz_poly_normalise(out2); + + result = (fmpz_poly_equal(out1, out2)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(out1), flint_printf("\n\n"); + fmpz_poly_print(out2), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(out1); + fmpz_poly_clear(out2); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-mul_karatsuba.c b/external/flint-2.4.3/fmpz_poly/test/t-mul_karatsuba.c new file mode 100644 index 0000000..18f15cc --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-mul_karatsuba.c @@ -0,0 +1,181 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("mul_karatsuba...."); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(b, state, n_randint(state, 50), 200); + fmpz_poly_randtest(c, state, n_randint(state, 50), 200); + + fmpz_poly_mul_karatsuba(a, b, c); + fmpz_poly_mul_karatsuba(b, b, c); + + result = (fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + /* Check aliasing of a and c */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(b, state, n_randint(state, 50), 200); + fmpz_poly_randtest(c, state, n_randint(state, 50), 200); + + fmpz_poly_mul_karatsuba(a, b, c); + fmpz_poly_mul_karatsuba(c, b, c); + + result = (fmpz_poly_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + /* Compare with mul_classical */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c, d; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_init(d); + fmpz_poly_randtest(b, state, n_randint(state, 50), 200); + fmpz_poly_randtest(c, state, n_randint(state, 50), 200); + + fmpz_poly_mul_karatsuba(a, b, c); + fmpz_poly_mul_classical(d, b, c); + + result = (fmpz_poly_equal(a, d)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(d), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + fmpz_poly_clear(d); + } + + /* Check _fmpz_poly_mul_karatsuba directly */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + slong len1, len2; + fmpz_poly_t a, b, out1, out2; + + len1 = n_randint(state, 100) + 1; + len2 = n_randint(state, 100) + 1; + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(out1); + fmpz_poly_init(out2); + fmpz_poly_randtest(a, state, len1, 200); + fmpz_poly_randtest(b, state, len2, 200); + + fmpz_poly_mul_karatsuba(out1, a, b); + fmpz_poly_fit_length(a, a->alloc + n_randint(state, 10)); + fmpz_poly_fit_length(b, b->alloc + n_randint(state, 10)); + a->length = a->alloc; + b->length = b->alloc; + fmpz_poly_fit_length(out2, a->length + b->length - 1); + if (a->length >= b->length) + _fmpz_poly_mul_karatsuba(out2->coeffs, a->coeffs, a->length, + b->coeffs, b->length); + else + _fmpz_poly_mul_karatsuba(out2->coeffs, b->coeffs, b->length, + a->coeffs, a->length); + _fmpz_poly_set_length(out2, a->length + b->length - 1); + _fmpz_poly_normalise(out2); + + result = (fmpz_poly_equal(out1, out2)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(out1), flint_printf("\n\n"); + fmpz_poly_print(out2), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(out1); + fmpz_poly_clear(out2); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-mulhigh_classical.c b/external/flint-2.4.3/fmpz_poly/test/t-mulhigh_classical.c new file mode 100644 index 0000000..17b01be --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-mulhigh_classical.c @@ -0,0 +1,150 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("mulhigh_classical...."); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + slong len, start; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(b, state, n_randint(state, 50), 200); + fmpz_poly_randtest(c, state, n_randint(state, 50), 200); + + len = b->length + c->length - 1; + start = (len <= 0) ? 0 : n_randint(state, b->length + c->length); + + fmpz_poly_mulhigh_classical(a, b, c, start); + fmpz_poly_mulhigh_classical(b, b, c, start); + + result = (fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + /* Check aliasing of a and c */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + slong len, start; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(b, state, n_randint(state, 50), 200); + fmpz_poly_randtest(c, state, n_randint(state, 50), 200); + + len = b->length + c->length - 1; + start = (len <= 0) ? 0 : n_randint(state, b->length + c->length - 1); + + fmpz_poly_mulhigh_classical(a, b, c, start); + fmpz_poly_mulhigh_classical(c, b, c, start); + + result = (fmpz_poly_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + /* Compare with mul_basecase */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c, d; + slong len, start; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_init(d); + fmpz_poly_randtest(b, state, n_randint(state, 50), 200); + fmpz_poly_randtest(c, state, n_randint(state, 50), 200); + + len = b->length + c->length - 1; + start = (len <= 0) ? 0 : n_randint(state, b->length + c->length - 1); + + fmpz_poly_mul_classical(a, b, c); + if (a->length >= start) + _fmpz_vec_zero(a->coeffs, start); + fmpz_poly_mulhigh_classical(d, b, c, start); + + result = (fmpz_poly_equal(a, d)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(d), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + fmpz_poly_clear(d); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-mulhigh_karatsuba_n.c b/external/flint-2.4.3/fmpz_poly/test/t-mulhigh_karatsuba_n.c new file mode 100644 index 0000000..0c0709f --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-mulhigh_karatsuba_n.c @@ -0,0 +1,145 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("mulhigh_karatsuba_n...."); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + slong len; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + len = n_randint(state, 50); + fmpz_poly_randtest(b, state, len, 200); + fmpz_poly_randtest(c, state, len, 200); + + fmpz_poly_mulhigh_karatsuba_n(a, b, c, len); + fmpz_poly_mulhigh_karatsuba_n(b, b, c, len); + + result = (fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + /* Check aliasing of a and c */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + slong len; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + len = n_randint(state, 50); + fmpz_poly_randtest(b, state, len, 200); + fmpz_poly_randtest(c, state, len, 200); + + fmpz_poly_mulhigh_karatsuba_n(a, b, c, len); + fmpz_poly_mulhigh_karatsuba_n(c, b, c, len); + + result = (fmpz_poly_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + /* Compare with mul_basecase */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c, d; + slong len; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_init(d); + len = n_randint(state, 50); + fmpz_poly_randtest(b, state, len, 200); + fmpz_poly_randtest(c, state, len, 200); + + fmpz_poly_mul_classical(a, b, c); + if (len) + _fmpz_vec_zero(a->coeffs, FLINT_MIN(len - 1, a->length)); + _fmpz_poly_normalise(a); + fmpz_poly_mulhigh_karatsuba_n(d, b, c, len); + + result = (fmpz_poly_equal(a, d)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(d), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + fmpz_poly_clear(d); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-mulhigh_n.c b/external/flint-2.4.3/fmpz_poly/test/t-mulhigh_n.c new file mode 100644 index 0000000..f8c9551 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-mulhigh_n.c @@ -0,0 +1,88 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("mulhigh_n...."); + fflush(stdout); + + + + /* Compare with left truncated product of a and b */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + slong j, n; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + n = n_randint(state, 50); + fmpz_poly_randtest(b, state, n, 200); + fmpz_poly_randtest(c, state, n, 200); + + fmpz_poly_mulhigh_n(a, b, c, n); + fmpz_poly_mul(b, b, c); + for (j = 0; j + 1 < n; j++) + { + if (j < a->length) + fmpz_zero(a->coeffs + j); + if (j < b->length) + fmpz_zero(b->coeffs + j); + } + _fmpz_poly_normalise(a); + _fmpz_poly_normalise(b); + + result = (fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-mullow.c b/external/flint-2.4.3/fmpz_poly/test/t-mullow.c new file mode 100644 index 0000000..158521a --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-mullow.c @@ -0,0 +1,80 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("mullow...."); + fflush(stdout); + + + + /* Compare with truncated product of a and b */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + slong trunc; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + trunc = n_randint(state, 50); + fmpz_poly_randtest(b, state, trunc, 200); + fmpz_poly_randtest(c, state, trunc, 200); + + fmpz_poly_mullow(a, b, c, trunc); + fmpz_poly_mul(b, b, c); + fmpz_poly_truncate(b, trunc); + + result = (fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-mullow_KS.c b/external/flint-2.4.3/fmpz_poly/test/t-mullow_KS.c new file mode 100644 index 0000000..b5ce507 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-mullow_KS.c @@ -0,0 +1,149 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("mullow_KS...."); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + slong len, trunc; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(b, state, n_randint(state, 50), 200); + fmpz_poly_randtest(c, state, n_randint(state, 50), 200); + + len = b->length + c->length - 1; + trunc = (len <= 0) ? 0 : n_randint(state, b->length + c->length); + + fmpz_poly_mullow_KS(a, b, c, trunc); + fmpz_poly_mullow_KS(b, b, c, trunc); + + result = (fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + /* Check aliasing of a and c */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + slong len; + ulong trunc; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(b, state, n_randint(state, 50), 200); + fmpz_poly_randtest(c, state, n_randint(state, 50), 200); + + len = b->length + c->length - 1; + trunc = (len <= 0) ? 0 : n_randint(state, b->length + c->length - 1); + + fmpz_poly_mullow_KS(a, b, c, trunc); + fmpz_poly_mullow_KS(c, b, c, trunc); + + result = (fmpz_poly_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + /* Compare with mul_basecase */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c, d; + slong len, trunc; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_init(d); + fmpz_poly_randtest(b, state, n_randint(state, 50), 200); + fmpz_poly_randtest(c, state, n_randint(state, 50), 200); + + len = b->length + c->length - 1; + trunc = (len <= 0) ? 0 : n_randint(state, b->length + c->length - 1); + + fmpz_poly_mul_KS(a, b, c); + fmpz_poly_truncate(a, trunc); + fmpz_poly_mullow_KS(d, b, c, trunc); + + result = (fmpz_poly_equal(a, d)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(d), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + fmpz_poly_clear(d); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-mullow_SS.c b/external/flint-2.4.3/fmpz_poly/test/t-mullow_SS.c new file mode 100644 index 0000000..e1563c9 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-mullow_SS.c @@ -0,0 +1,149 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("mullow_SS...."); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + slong len, trunc; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(b, state, n_randint(state, 50), 200); + fmpz_poly_randtest(c, state, n_randint(state, 50), 200); + + len = b->length + c->length - 1; + trunc = (len <= 0) ? 0 : n_randint(state, b->length + c->length); + + fmpz_poly_mullow_SS(a, b, c, trunc); + fmpz_poly_mullow_SS(b, b, c, trunc); + + result = (fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + /* Check aliasing of a and c */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + slong len; + ulong trunc; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(b, state, n_randint(state, 50), 200); + fmpz_poly_randtest(c, state, n_randint(state, 50), 200); + + len = b->length + c->length - 1; + trunc = (len <= 0) ? 0 : n_randint(state, b->length + c->length - 1); + + fmpz_poly_mullow_SS(a, b, c, trunc); + fmpz_poly_mullow_SS(c, b, c, trunc); + + result = (fmpz_poly_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + /* Compare with mul_KS */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c, d; + slong len, trunc; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_init(d); + fmpz_poly_randtest(b, state, n_randint(state, 50), 200); + fmpz_poly_randtest(c, state, n_randint(state, 50), 200); + + len = b->length + c->length - 1; + trunc = (len <= 0) ? 0 : n_randint(state, b->length + c->length - 1); + + fmpz_poly_mul_KS(a, b, c); + fmpz_poly_truncate(a, trunc); + fmpz_poly_mullow_SS(d, b, c, trunc); + + result = (fmpz_poly_equal(a, d)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(d), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + fmpz_poly_clear(d); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-mullow_classical.c b/external/flint-2.4.3/fmpz_poly/test/t-mullow_classical.c new file mode 100644 index 0000000..7664223 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-mullow_classical.c @@ -0,0 +1,149 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("mullow_classical...."); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + slong len, trunc; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(b, state, n_randint(state, 50), 200); + fmpz_poly_randtest(c, state, n_randint(state, 50), 200); + + len = b->length + c->length - 1; + trunc = (len <= 0) ? 0 : n_randint(state, b->length + c->length); + + fmpz_poly_mullow_classical(a, b, c, trunc); + fmpz_poly_mullow_classical(b, b, c, trunc); + + result = (fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + /* Check aliasing of a and c */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + slong len; + ulong trunc; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(b, state, n_randint(state, 50), 200); + fmpz_poly_randtest(c, state, n_randint(state, 50), 200); + + len = b->length + c->length - 1; + trunc = (len <= 0) ? 0 : n_randint(state, b->length + c->length - 1); + + fmpz_poly_mullow_classical(a, b, c, trunc); + fmpz_poly_mullow_classical(c, b, c, trunc); + + result = (fmpz_poly_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + /* Compare with mul_basecase */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c, d; + slong len, trunc; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_init(d); + fmpz_poly_randtest(b, state, n_randint(state, 50), 200); + fmpz_poly_randtest(c, state, n_randint(state, 50), 200); + + len = b->length + c->length - 1; + trunc = (len <= 0) ? 0 : n_randint(state, b->length + c->length - 1); + + fmpz_poly_mul_classical(a, b, c); + fmpz_poly_truncate(a, trunc); + fmpz_poly_mullow_classical(d, b, c, trunc); + + result = (fmpz_poly_equal(a, d)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(d), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + fmpz_poly_clear(d); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-mullow_karatsuba_n.c b/external/flint-2.4.3/fmpz_poly/test/t-mullow_karatsuba_n.c new file mode 100644 index 0000000..7a34ffd --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-mullow_karatsuba_n.c @@ -0,0 +1,143 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("mullow_karatsuba_n...."); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + slong len; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + len = n_randint(state, 50); + fmpz_poly_randtest(b, state, len, 200); + fmpz_poly_randtest(c, state, len, 200); + + fmpz_poly_mullow_karatsuba_n(a, b, c, len); + fmpz_poly_mullow_karatsuba_n(b, b, c, len); + + result = (fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + /* Check aliasing of a and c */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + slong len; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + len = n_randint(state, 50); + fmpz_poly_randtest(b, state, len, 200); + fmpz_poly_randtest(c, state, len, 200); + + fmpz_poly_mullow_karatsuba_n(a, b, c, len); + fmpz_poly_mullow_karatsuba_n(c, b, c, len); + + result = (fmpz_poly_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + /* Compare with mul_karatsuba */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c, d; + slong len; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_init(d); + len = n_randint(state, 50); + fmpz_poly_randtest(b, state, len, 200); + fmpz_poly_randtest(c, state, len, 200); + + fmpz_poly_mullow_karatsuba_n(a, b, c, len); + fmpz_poly_mul_karatsuba(d, b, c); + fmpz_poly_truncate(d, len); + + result = (fmpz_poly_equal(a, d)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(d), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + fmpz_poly_clear(d); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-mulmid_classical.c b/external/flint-2.4.3/fmpz_poly/test/t-mulmid_classical.c new file mode 100644 index 0000000..422134d --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-mulmid_classical.c @@ -0,0 +1,152 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("mulmid_classical...."); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(b, state, n_randint(state, 50), 200); + if (b->length == 0) + fmpz_poly_zero(c); + else + fmpz_poly_randtest(c, state, n_randint(state, b->length), 200); + + fmpz_poly_mulmid_classical(a, b, c); + fmpz_poly_mulmid_classical(b, b, c); + + result = (fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + /* Check aliasing of a and c */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(b, state, n_randint(state, 50), 200); + if (b->length == 0) + fmpz_poly_zero(c); + else + fmpz_poly_randtest(c, state, n_randint(state, b->length), 200); + + fmpz_poly_mulmid_classical(a, b, c); + fmpz_poly_mulmid_classical(c, b, c); + + result = (fmpz_poly_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + /* Compare with mul_basecase */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c, d; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_init(d); + fmpz_poly_randtest(b, state, n_randint(state, 50), 200); + fmpz_poly_randtest(c, state, n_randint(state, b->length + 1), 200); + + fmpz_poly_mulmid_classical(d, b, c); + if (b->length == 0 || c->length == 0) + { + result = (d->length == 0); + } + else + { + fmpz_poly_mul_classical(a, b, c); + fmpz_poly_truncate(a, b->length); + fmpz_poly_shift_right(a, a, c->length - 1); + result = (fmpz_poly_equal(a, d)); + } + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("b = "), fmpz_poly_print(b), flint_printf("\n\n"); + flint_printf("c = "), fmpz_poly_print(c), flint_printf("\n\n"); + flint_printf("a = "), fmpz_poly_print(a), flint_printf("\n\n"); + flint_printf("d = "), fmpz_poly_print(d), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + fmpz_poly_clear(d); + } + + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-neg.c b/external/flint-2.4.3/fmpz_poly/test/t-neg.c new file mode 100644 index 0000000..ce633f8 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-neg.c @@ -0,0 +1,76 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("neg...."); + fflush(stdout); + + + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(a, state, n_randint(state, 100), 200); + + fmpz_poly_neg(b, a); + fmpz_poly_neg(c, b); + + result = (fmpz_poly_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + fmpz_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-newton_to_monomial.c b/external/flint-2.4.3/fmpz_poly/test/t-newton_to_monomial.c new file mode 100644 index 0000000..70fe687 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-newton_to_monomial.c @@ -0,0 +1,85 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + flint_printf("newton_to_monomial...."); + fflush(stdout); + + + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t f, g; + fmpz * r; + slong k, n; + + fmpz_poly_init(f); + fmpz_poly_init(g); + + fmpz_poly_randtest(f, state, 1 + n_randint(state, 20), + 1 + n_randint(state, 200)); + + n = fmpz_poly_length(f); + r = _fmpz_vec_init(n); + + for (k = 0; k < n; k++) + fmpz_randtest(r + k, state, n_randint(state, 200)); + + fmpz_poly_set(g, f); + + _fmpz_poly_newton_to_monomial(g->coeffs, r, n); + _fmpz_poly_monomial_to_newton(g->coeffs, r, n); + + if (!fmpz_poly_equal(f, g)) + { + flint_printf("FAIL: roundtrip\n"); + fmpz_poly_print(f); flint_printf("\n"); + fmpz_poly_print(g); flint_printf("\n"); + abort(); + } + + fmpz_poly_clear(f); + fmpz_poly_clear(g); + _fmpz_vec_clear(r, n); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-pow.c b/external/flint-2.4.3/fmpz_poly/test/t-pow.c new file mode 100644 index 0000000..a5ed8b1 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-pow.c @@ -0,0 +1,122 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("pow...."); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b; + ulong exp; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_randtest(b, state, n_randint(state, 10), 100); + + exp = n_randtest(state) % UWORD(20); + + fmpz_poly_pow(a, b, exp); + fmpz_poly_pow(b, b, exp); + + result = (fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("exp = %wu\n", exp); + flint_printf("a = "), fmpz_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + } + + /* Compare with repeated multiplications by the case */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + ulong exp; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(b, state, n_randint(state, 10), 100); + + exp = n_randtest(state) % UWORD(20); + + fmpz_poly_pow(a, b, exp); + + if (exp == UWORD(0)) + { + fmpz_poly_set_ui(c, 1); + } + else + { + ulong j; + fmpz_poly_set(c, b); + + for (j = 1; j < exp; j++) + fmpz_poly_mul(c, c, b); + } + + result = (fmpz_poly_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("exp = %wu\n", exp); + flint_printf("a = "), fmpz_poly_print(a), flint_printf("\n\n"); + flint_printf("c = "), fmpz_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-pow_addchains.c b/external/flint-2.4.3/fmpz_poly/test/t-pow_addchains.c new file mode 100644 index 0000000..dbc5bff --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-pow_addchains.c @@ -0,0 +1,110 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("pow_addchains...."); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b; + ulong exp; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_randtest(b, state, n_randint(state, 10), 100); + + exp = n_randtest(state) % UWORD(20); + + fmpz_poly_pow_addchains(a, b, exp); + fmpz_poly_pow_addchains(b, b, exp); + + result = (fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("exp = %wu\n", exp); + flint_printf("a = "), fmpz_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + } + + /* Compare with fmpz_poly_pow */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b; + ulong exp; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_randtest(b, state, n_randint(state, 10), 100); + + for (exp = UWORD(0); exp < UWORD(149); exp++) + { + fmpz_poly_pow_addchains(a, b, exp); + fmpz_poly_pow(b, b, exp); + + result = (fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("exp = %wu\n", exp); + flint_printf("a = "), fmpz_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-pow_binexp.c b/external/flint-2.4.3/fmpz_poly/test/t-pow_binexp.c new file mode 100644 index 0000000..bce4efd --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-pow_binexp.c @@ -0,0 +1,108 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("pow_binexp...."); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b; + ulong exp; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_randtest(b, state, n_randint(state, 10), 100); + + exp = n_randtest(state) % UWORD(20); + + fmpz_poly_pow_binexp(a, b, exp); + fmpz_poly_pow_binexp(b, b, exp); + + result = (fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL(1):\n"); + flint_printf("exp = %wu\n", exp); + flint_printf("a = "), fmpz_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + } + + /* Compare with fmpz_poly_pow */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b; + ulong exp; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_randtest(b, state, n_randint(state, 10), 100); + + exp = n_randtest(state) % UWORD(20); + + fmpz_poly_pow_binexp(a, b, exp); + fmpz_poly_pow(b, b, exp); + + result = (fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL(2):\n"); + flint_printf("exp = %wu\n", exp); + flint_printf("a = "), fmpz_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-pow_binomial.c b/external/flint-2.4.3/fmpz_poly/test/t-pow_binomial.c new file mode 100644 index 0000000..903c64f --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-pow_binomial.c @@ -0,0 +1,114 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("pow_binomial...."); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b; + ulong exp; + + fmpz_poly_init(a); + fmpz_poly_init2(b, 2); + + fmpz_randtest(b->coeffs, state, 100); + fmpz_randtest_not_zero(b->coeffs + 1, state, 100); + _fmpz_poly_set_length(b, 2); + + exp = n_randtest(state) % UWORD(100); + + fmpz_poly_pow_binomial(a, b, exp); + fmpz_poly_pow_binomial(b, b, exp); + + result = (fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL(1):\n"); + flint_printf("exp = %wu\n", exp); + flint_printf("a = "), fmpz_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + } + + /* Compare with fmpz_poly_pow */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b; + ulong exp; + + fmpz_poly_init(a); + fmpz_poly_init2(b, 2); + + fmpz_randtest(b->coeffs, state, 100); + fmpz_randtest_not_zero(b->coeffs + 1, state, 100); + _fmpz_poly_set_length(b, 2); + + exp = n_randtest(state) % UWORD(100); + + fmpz_poly_pow_binomial(a, b, exp); + fmpz_poly_pow(b, b, exp); + + result = (fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL(2):\n"); + flint_printf("exp = %wu\n", exp); + flint_printf("a = "), fmpz_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-pow_multinomial.c b/external/flint-2.4.3/fmpz_poly/test/t-pow_multinomial.c new file mode 100644 index 0000000..3f1a66a --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-pow_multinomial.c @@ -0,0 +1,109 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("pow_multinomial...."); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b; + ulong exp; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_randtest(b, state, n_randint(state, 10), 100); + + exp = n_randtest(state) % UWORD(20); + + fmpz_poly_pow_multinomial(a, b, exp); + fmpz_poly_pow_multinomial(b, b, exp); + + result = (fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL(1):\n"); + flint_printf("exp = %wu\n", exp); + flint_printf("a = "), fmpz_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + } + + /* Compare with fmpz_poly_pow */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b; + ulong exp; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_randtest(b, state, n_randint(state, 10), 100); + + exp = n_randtest(state) % UWORD(20); + + fmpz_poly_pow_multinomial(a, b, exp); + fmpz_poly_pow(b, b, exp); + + result = (fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL(2):\n"); + flint_printf("exp = %wu\n", exp); + flint_printf("a = "), fmpz_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-pow_trunc.c b/external/flint-2.4.3/fmpz_poly/test/t-pow_trunc.c new file mode 100644 index 0000000..19732fd --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-pow_trunc.c @@ -0,0 +1,118 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("pow_trunc...."); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b; + slong n; + ulong exp; + + n = n_randtest(state) % 10; + exp = n_randtest(state) % 100; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_randtest(b, state, n_randint(state, 100), n); + + fmpz_poly_pow_trunc(a, b, exp, n); + fmpz_poly_pow_trunc(b, b, exp, n); + + result = (fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("n = %wd\n", n); + flint_printf("exp = %wu\n", exp); + flint_printf("a = "), fmpz_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + } + + /* Compare with powering followed truncating */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + slong n; + ulong exp; + + n = n_randtest(state) % 10; + exp = n_randtest(state) % 50; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(b, state, n_randint(state, 50), n); + + fmpz_poly_pow(a, b, exp); + fmpz_poly_truncate(a, n); + fmpz_poly_pow_trunc(c, b, exp, n); + + result = (fmpz_poly_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("n = %wd\n", n); + flint_printf("exp = %wu\n", exp); + flint_printf("b = "), fmpz_poly_print(b), flint_printf("\n\n"); + flint_printf("a = "), fmpz_poly_print(a), flint_printf("\n\n"); + flint_printf("c = "), fmpz_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-primitive_part.c b/external/flint-2.4.3/fmpz_poly/test/t-primitive_part.c new file mode 100644 index 0000000..3019c87 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-primitive_part.c @@ -0,0 +1,106 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("primitive_part...."); + fflush(stdout); + + + + /* Check aliasing */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t f, g; + + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_poly_randtest(g, state, n_randint(state, 100), 200); + + fmpz_poly_primitive_part(f, g); + fmpz_poly_primitive_part(g, g); + + result = (fmpz_poly_equal(f, g)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(f), flint_printf("\n\n"); + fmpz_poly_print(g), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(f); + fmpz_poly_clear(g); + } + + /* Check that content(f) primitive_part(f) = sgn(lead(f)) f */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t f, g; + fmpz_t c; + + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_init(c); + fmpz_poly_randtest_not_zero(f, state, n_randint(state, 100) + 1, 200); + + fmpz_poly_content(c, f); + if (fmpz_sgn(f->coeffs + f->length - 1) < 0) + fmpz_neg(c, c); + fmpz_poly_primitive_part(g, f); + fmpz_poly_scalar_mul_fmpz(g, g, c); + + result = (fmpz_poly_equal(f, g)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(f), flint_printf("\n\n"); + fmpz_poly_print(g), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(c); + fmpz_poly_clear(f); + fmpz_poly_clear(g); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-print_read.c b/external/flint-2.4.3/fmpz_poly/test/t-print_read.c new file mode 100644 index 0000000..47f1b7e --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-print_read.c @@ -0,0 +1,269 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + + +#include +#include +#include +#include +#include + +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +#if !defined (__WIN32) || defined(__CYGWIN__) + +/* + The function fdopen is declared in stdio.h. It is POSIX.1 compliant, + but not ANSI compliant. The following line enables compilation with + the "-ansi" flag. + */ +extern FILE * fdopen(int fildes, const char *mode); + +int main(void) +{ + int i, j, n = 1000, result; + + FILE *in, *out; + int fd[2]; + pid_t childpid; + + FLINT_TEST_INIT(state); + + flint_printf("print/ read...."); + fflush(stdout); + + /* Randomise n polynomials, write to and read from a pipe */ + { + fmpz_poly_t *a; + + a = flint_malloc(n * sizeof(fmpz_poly_t)); + for (i = 0; i < n; i++) + { + fmpz_poly_init(a[i]); + fmpz_poly_randtest(a[i], state, 100, 100); + } + + if (pipe(fd)) + { + flint_printf("FAIL:\n"); + flint_printf("Failed to set-up the pipe.\n"); + abort(); + } + + if((childpid = fork()) == -1) + { + flint_printf("FAIL:\n"); + flint_printf("Failed to fork the process.\n"); + abort(); + } + + if(childpid == 0) /* Child process */ + { + int r; + + close(fd[0]); + out = fdopen(fd[1], "w"); + if (out == NULL) + { + flint_printf("FAIL:\n"); + flint_printf("Could not open output file at the pipe.\n"); + abort(); + } + + for (j = 0; j < n; j++) + { + r = fmpz_poly_fprint(out, a[j]); + if ((j < n - 1) && (r > 0)) + r = flint_fprintf(out, "\n"); + + if (r <= 0) + { + flint_printf("FAIL:\n"); + flint_printf("Write error.\n"); + abort(); + } + } + + fclose(out); + exit(0); + } + else /* Parent process */ + { + int r; + fmpz_poly_t t; + + close(fd[1]); + in = fdopen(fd[0], "r"); + if (in == NULL) + { + flint_printf("FAIL:\n"); + flint_printf("Could not open input file at the pipe.\n"); + abort(); + } + + fmpz_poly_init(t); + + i = 0; + while (!feof(in)) + { + r = fmpz_poly_fread(in, t); + if (r <= 0) + { + flint_printf("FAIL:\n"); + flint_printf("Read error.\n"); + abort(); + } + + result = fmpz_poly_equal(t, a[i]); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a[i] = "), fmpz_poly_print(a[i]), flint_printf("\n"); + flint_printf("t = "), fmpz_poly_print(t), flint_printf("\n"); + abort(); + } + + ++i; + } + + fmpz_poly_clear(t); + fclose(in); + } + + if (i != n) + { + flint_printf("FAIL:\n"); + flint_printf("Only %d out of %d objects were processed.\n", i, n); + abort(); + } + + for (i = 0; i < n; i++) + fmpz_poly_clear(a[i]); + flint_free(a); + } + + /* Write bad data to a pipe and read it */ + { + char str[5] = {'b', 'l', 'a', 'h', '\0'}; + + if (pipe(fd)) + { + flint_printf("FAIL:\n"); + flint_printf("Failed to set-up the pipe.\n"); + abort(); + } + + if((childpid = fork()) == -1) + { + flint_printf("FAIL:\n"); + flint_printf("Failed to fork the process.\n"); + abort(); + } + + if(childpid == 0) /* Child process */ + { + int r; + + close(fd[0]); + out = fdopen(fd[1], "w"); + if (out == NULL) + { + flint_printf("FAIL:\n"); + flint_printf("Could not open output file at the pipe.\n"); + abort(); + } + + r = flint_fprintf(out, "blah"); + if (r <= 0) + { + flint_printf("FAIL:\n"); + flint_printf("Write error.\n"); + abort(); + } + + fclose(out); + exit(0); + } + else /* Parent process */ + { + int r; + fmpz_poly_t t; + + close(fd[1]); + in = fdopen(fd[0], "r"); + if (in == NULL) + { + flint_printf("FAIL:\n"); + flint_printf("Could not open input file at the pipe.\n"); + abort(); + } + + fmpz_poly_init(t); + + i = 0; + while (!feof(in)) + { + r = fmpz_poly_fread(in, t); + if (r > 0) + { + flint_printf("FAIL:\n"); + flint_printf("r = %d\n", r); + abort(); + } + ++i; + } + + fmpz_poly_clear(t); + fclose(in); + } + + /* For {'b','l','a','h','\0'} we expect 5 reads */ + if (i != 5) + { + flint_printf("FAIL:\n"); + flint_printf("Carried out %d reads, but \"%s\" has only 4 characters.\n", i, str); + abort(); + } + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + +#else + +int main(void) +{ + flint_printf("print/ read...."); + fflush(stdout); + flint_printf("SKIPPED\n"); + return EXIT_SUCCESS; +} + +#endif diff --git a/external/flint-2.4.3/fmpz_poly/test/t-print_read_pretty.c b/external/flint-2.4.3/fmpz_poly/test/t-print_read_pretty.c new file mode 100644 index 0000000..b63213b --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-print_read_pretty.c @@ -0,0 +1,273 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +#if !defined (__WIN32) || defined(__CYGWIN__) + +/* + The function fdopen is declared in stdio.h. It is POSIX.1 compliant, + but not ANSI compliant. The following line enables compilation with + the "-ansi" flag. + */ +extern FILE * fdopen(int fildes, const char *mode); + +int main(void) +{ + int i, j, n = 1000, result; + + FILE *in, *out; + int fd[2]; + pid_t childpid; + + FLINT_TEST_INIT(state); + + flint_printf("print/ read_pretty...."); + fflush(stdout); + + /* Randomise n polynomials, write to and read from a pipe */ + { + fmpz_poly_t *a; + char *var = "x"; + + a = flint_malloc(n * sizeof(fmpz_poly_t)); + for (i = 0; i < n; i++) + { + fmpz_poly_init(a[i]); + fmpz_poly_randtest(a[i], state, 100, 100); + } + + if (pipe(fd)) + { + flint_printf("FAIL:\n"); + flint_printf("Failed to set-up the pipe.\n"); + abort(); + } + + if((childpid = fork()) == -1) + { + flint_printf("FAIL:\n"); + flint_printf("Failed to fork the process.\n"); + abort(); + } + + if(childpid == 0) /* Child process */ + { + int r; + + close(fd[0]); + out = fdopen(fd[1], "w"); + if (out == NULL) + { + flint_printf("FAIL:\n"); + flint_printf("Could not open output file at the pipe.\n"); + abort(); + } + + for (j = 0; j < n; j++) + { + r = fmpz_poly_fprint_pretty(out, a[j], var); + if ((j < n - 1) && (r > 0)) + r = flint_fprintf(out, "\n"); + + if (r <= 0) + { + flint_printf("FAIL:\n"); + flint_printf("Write error.\n"); + abort(); + } + } + + fclose(out); + exit(0); + } + else /* Parent process */ + { + int r; + fmpz_poly_t t; + char *rvar; + + close(fd[1]); + in = fdopen(fd[0], "r"); + if (in == NULL) + { + flint_printf("FAIL:\n"); + flint_printf("Could not open input file at the pipe.\n"); + abort(); + } + + fmpz_poly_init(t); + + i = 0; + while (!feof(in)) + { + r = fmpz_poly_fread_pretty(in, t, &rvar); + if (r <= 0) + { + flint_printf("FAIL:\n"); + flint_printf("Read error.\n"); + abort(); + } + + result = fmpz_poly_equal(t, a[i]) && + (t->length <= 1 || (strcmp(var, rvar) == 0)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a[i] = "), fmpz_poly_print_pretty(a[i], var), flint_printf("\n"); + flint_printf("t = "), fmpz_poly_print_pretty(t, rvar), flint_printf("\n"); + flint_printf("rvar = %s\n", rvar); + abort(); + } + flint_free(rvar); + + ++i; + } + + fmpz_poly_clear(t); + fclose(in); + } + + if (i != n) + { + flint_printf("FAIL:\n"); + flint_printf("Only %d out of %d objects were processed.\n", i, n); + abort(); + } + + for (i = 0; i < n; i++) + fmpz_poly_clear(a[i]); + flint_free(a); + } + + /* Write "blah" to the pipe and see it read as a variable */ + { + char str[5] = {'b', 'l', 'a', 'h', '\0'}; + + if (pipe(fd)) + { + flint_printf("FAIL:\n"); + flint_printf("Failed to set-up the pipe.\n"); + abort(); + } + + if((childpid = fork()) == -1) + { + flint_printf("FAIL:\n"); + flint_printf("Failed to fork the process.\n"); + abort(); + } + + if(childpid == 0) /* Child process */ + { + int r; + + close(fd[0]); + out = fdopen(fd[1], "w"); + if (out == NULL) + { + flint_printf("FAIL:\n"); + flint_printf("Could not open output file at the pipe.\n"); + abort(); + } + + r = fputs(str, out); + if (r == EOF) + { + flint_printf("FAIL:\n"); + flint_printf("Write error.\n"); + abort(); + } + + fclose(out); + exit(0); + } + else /* Parent process */ + { + char *rvar = NULL; + int r; + fmpz_poly_t t; + + close(fd[1]); + in = fdopen(fd[0], "r"); + if (in == NULL) + { + flint_printf("FAIL:\n"); + flint_printf("Could not open input file at the pipe.\n"); + abort(); + } + + fmpz_poly_init(t); + + while (!feof(in)) + { + r = fmpz_poly_fread_pretty(in, t, &rvar); + result = (r > 0) && rvar && (strcmp(str, rvar) == 0) && + (t->length == 2) && (t->coeffs[0] == WORD(0)) && + (t->coeffs[1] == WORD(1)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("r = %d\n", r); + flint_printf("str = {%s}\n", str); + flint_printf("rvar = {%s}\n", rvar); + flint_printf("t = "), fmpz_poly_print(t), flint_printf("\n"); + abort(); + } + if (rvar) + flint_free(rvar); + } + + fmpz_poly_clear(t); + fclose(in); + } + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + +#else + +int main(void) +{ + flint_printf("print/ read...."); + fflush(stdout); + flint_printf("SKIPPED\n"); + return EXIT_SUCCESS; +} + +#endif diff --git a/external/flint-2.4.3/fmpz_poly/test/t-product_roots_fmpz_vec.c b/external/flint-2.4.3/fmpz_poly/test/t-product_roots_fmpz_vec.c new file mode 100644 index 0000000..6db2bd5 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-product_roots_fmpz_vec.c @@ -0,0 +1,92 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("product_roots_fmpz_vec...."); + fflush(stdout); + + + + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t P, Q, tmp; + fmpz * x; + slong j, n, bits; + + n = n_randint(state, 100); + bits = n_randint(state, 10); + + x = _fmpz_vec_init(n); + _fmpz_vec_randtest(x, state, n, bits); + + fmpz_poly_init(P); + fmpz_poly_init(Q); + fmpz_poly_init(tmp); + + fmpz_poly_product_roots_fmpz_vec(P, x, n); + + fmpz_poly_set_ui(Q, UWORD(1)); + for (j = 0; j < n; j++) + { + fmpz_poly_zero(tmp); + fmpz_poly_set_coeff_si(tmp, 1, WORD(-1)); + fmpz_poly_set_coeff_fmpz(tmp, 0, x + j); + fmpz_poly_neg(tmp, tmp); + fmpz_poly_mul(Q, Q, tmp); + } + + result = (fmpz_poly_equal(P, Q)); + if (!result) + { + flint_printf("FAIL (P != Q):\n"); + fmpz_poly_print(P), flint_printf("\n\n"); + fmpz_poly_print(Q), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(P); + fmpz_poly_clear(Q); + fmpz_poly_clear(tmp); + _fmpz_vec_clear(x, n); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-pseudo_div.c b/external/flint-2.4.3/fmpz_poly/test/t-pseudo_div.c new file mode 100644 index 0000000..3b5f76c --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-pseudo_div.c @@ -0,0 +1,147 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("pseudo_div...."); + fflush(stdout); + + + + /* Check r = a - q * b has small degree, no aliasing */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, q, r, prod; + fmpz_t p; + ulong d; + + fmpz_init(p); + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(q); + fmpz_poly_init(r); + fmpz_poly_init(prod); + fmpz_poly_randtest(a, state, n_randint(state, 100), 50); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1, 50); + + fmpz_poly_pseudo_div(q, &d, a, b); + fmpz_poly_mul(prod, q, b); + fmpz_pow_ui(p, b->coeffs + b->length - 1, d); + fmpz_poly_scalar_mul_fmpz(a, a, p); + fmpz_poly_sub(r, a, prod); + + result = (fmpz_poly_length(r) < fmpz_poly_length(b)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(prod), flint_printf("\n\n"); + fmpz_poly_print(q), flint_printf("\n\n"); + fmpz_poly_print(r), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(p); + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(q); + fmpz_poly_clear(r); + fmpz_poly_clear(prod); + } + + /* Check q and a alias */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, q; + ulong d; + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(q); + fmpz_poly_randtest(a, state, n_randint(state, 100), 50); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1, 50); + + fmpz_poly_pseudo_div(q, &d, a, b); + fmpz_poly_pseudo_div(a, &d, a, b); + + result = (fmpz_poly_equal(a, q)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(q), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(q); + } + + /* Check q and b alias */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, q; + ulong d; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(q); + fmpz_poly_randtest(a, state, n_randint(state, 100), 50); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1, 50); + + fmpz_poly_pseudo_div(q, &d, a, b); + fmpz_poly_pseudo_div(b, &d, a, b); + + result = (fmpz_poly_equal(b, q)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(q), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(q); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-pseudo_divrem_basecase.c b/external/flint-2.4.3/fmpz_poly/test/t-pseudo_divrem_basecase.c new file mode 100644 index 0000000..d2cf069 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-pseudo_divrem_basecase.c @@ -0,0 +1,217 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("pseudo_divrem_basecase...."); + fflush(stdout); + + + + /* Check q*b + r = a, no aliasing */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, q, r, prod; + fmpz_t p; + ulong d; + + fmpz_init(p); + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(q); + fmpz_poly_init(r); + fmpz_poly_init(prod); + fmpz_poly_randtest(a, state, n_randint(state, 100), 50); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1, 50); + + fmpz_poly_pseudo_divrem_basecase(q, r, &d, a, b); + fmpz_poly_mul(prod, q, b); + fmpz_poly_add(prod, prod, r); + fmpz_pow_ui(p, b->coeffs + b->length - 1, d); + fmpz_poly_scalar_mul_fmpz(a, a, p); + + result = (fmpz_poly_equal(a, prod)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(prod), flint_printf("\n\n"); + fmpz_poly_print(q), flint_printf("\n\n"); + fmpz_poly_print(r), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(p); + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(q); + fmpz_poly_clear(r); + fmpz_poly_clear(prod); + } + + /* Check r and a alias */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, q, r; + ulong d; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(q); + fmpz_poly_init(r); + fmpz_poly_randtest(a, state, n_randint(state, 100), 50); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1, 50); + + fmpz_poly_pseudo_divrem_basecase(q, r, &d, a, b); + fmpz_poly_pseudo_divrem_basecase(q, a, &d, a, b); + + result = (fmpz_poly_equal(a, r)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(q), flint_printf("\n\n"); + fmpz_poly_print(r), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(q); + fmpz_poly_clear(r); + } + + /* Check r and b alias */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, q, r; + ulong d; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(q); + fmpz_poly_init(r); + fmpz_poly_randtest(a, state, n_randint(state, 100), 50); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1, 50); + + fmpz_poly_pseudo_divrem_basecase(q, r, &d, a, b); + fmpz_poly_pseudo_divrem_basecase(q, b, &d, a, b); + + result = (fmpz_poly_equal(b, r)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(q), flint_printf("\n\n"); + fmpz_poly_print(r), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(q); + fmpz_poly_clear(r); + } + + /* Check q and a alias */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, q, r; + ulong d; + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(q); + fmpz_poly_init(r); + fmpz_poly_randtest(a, state, n_randint(state, 100), 50); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1, 50); + + fmpz_poly_pseudo_divrem_basecase(q, r, &d, a, b); + fmpz_poly_pseudo_divrem_basecase(a, r, &d, a, b); + + result = (fmpz_poly_equal(a, q)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(q), flint_printf("\n\n"); + fmpz_poly_print(r), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(q); + fmpz_poly_clear(r); + } + + /* Check q and b alias */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, q, r; + ulong d; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(q); + fmpz_poly_init(r); + fmpz_poly_randtest(a, state, n_randint(state, 100), 50); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1, 50); + + fmpz_poly_pseudo_divrem_basecase(q, r, &d, a, b); + fmpz_poly_pseudo_divrem_basecase(b, r, &d, a, b); + + result = (fmpz_poly_equal(b, q)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(q), flint_printf("\n\n"); + fmpz_poly_print(r), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(q); + fmpz_poly_clear(r); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-pseudo_divrem_cohen.c b/external/flint-2.4.3/fmpz_poly/test/t-pseudo_divrem_cohen.c new file mode 100644 index 0000000..147631d --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-pseudo_divrem_cohen.c @@ -0,0 +1,217 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("pseudo_divrem_cohen...."); + fflush(stdout); + + + + /* Check q*b + r = a, no aliasing */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, q, r, prod; + slong d; + fmpz_t p; + + fmpz_init(p); + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(q); + fmpz_poly_init(r); + fmpz_poly_init(prod); + fmpz_poly_randtest(a, state, n_randint(state, 80), 100); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 80) + 1, 100); + + fmpz_poly_pseudo_divrem_cohen(q, r, a, b); + fmpz_poly_mul(prod, q, b); + fmpz_poly_add(prod, prod, r); + d = a->length - b->length + 1; + d = FLINT_MAX(d, 0); + fmpz_pow_ui(p, b->coeffs + b->length - 1, d); + fmpz_poly_scalar_mul_fmpz(a, a, p); + + result = (fmpz_poly_equal(a, prod)); + if (!result) + { + flint_printf("FAIL (correctness):\n"); + flint_printf("a = "), fmpz_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_poly_print(b), flint_printf("\n\n"); + flint_printf("prod = "), fmpz_poly_print(prod), flint_printf("\n\n"); + flint_printf("q = "), fmpz_poly_print(q), flint_printf("\n\n"); + flint_printf("r = "), fmpz_poly_print(r), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(p); + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(q); + fmpz_poly_clear(r); + fmpz_poly_clear(prod); + } + + /* Check r and a alias */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, q, r; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(q); + fmpz_poly_init(r); + fmpz_poly_randtest(a, state, n_randint(state, 80), 100); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 80) + 1, 100); + + fmpz_poly_pseudo_divrem_cohen(q, r, a, b); + fmpz_poly_pseudo_divrem_cohen(q, a, a, b); + + result = (fmpz_poly_equal(a, r)); + if (!result) + { + flint_printf("FAIL (aliasing r, a):\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(q), flint_printf("\n\n"); + fmpz_poly_print(r), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(q); + fmpz_poly_clear(r); + } + + /* Check r and b alias */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, q, r; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(q); + fmpz_poly_init(r); + fmpz_poly_randtest(a, state, n_randint(state, 80), 100); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 80) + 1, 100); + + fmpz_poly_pseudo_divrem_cohen(q, r, a, b); + fmpz_poly_pseudo_divrem_cohen(q, b, a, b); + + result = (fmpz_poly_equal(b, r)); + if (!result) + { + flint_printf("FAIL (aliasing r, b):\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(q), flint_printf("\n\n"); + fmpz_poly_print(r), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(q); + fmpz_poly_clear(r); + } + + /* Check q and a alias */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, q, r; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(q); + fmpz_poly_init(r); + fmpz_poly_randtest(a, state, n_randint(state, 80), 100); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 80) + 1, 100); + + fmpz_poly_pseudo_divrem_cohen(q, r, a, b); + fmpz_poly_pseudo_divrem_cohen(a, r, a, b); + + result = (fmpz_poly_equal(a, q)); + if (!result) + { + flint_printf("FAIL (aliasing q, a):\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(q), flint_printf("\n\n"); + fmpz_poly_print(r), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(q); + fmpz_poly_clear(r); + } + + /* Check q and b alias */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, q, r; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(q); + fmpz_poly_init(r); + fmpz_poly_randtest(a, state, n_randint(state, 80), 100); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 80) + 1, 100); + + fmpz_poly_pseudo_divrem_cohen(q, r, a, b); + fmpz_poly_pseudo_divrem_cohen(b, r, a, b); + + result = (fmpz_poly_equal(b, q)); + if (!result) + { + flint_printf("FAIL (aliasing q, b):\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(q), flint_printf("\n\n"); + fmpz_poly_print(r), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(q); + fmpz_poly_clear(r); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-pseudo_divrem_divconquer.c b/external/flint-2.4.3/fmpz_poly/test/t-pseudo_divrem_divconquer.c new file mode 100644 index 0000000..a7ae7a1 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-pseudo_divrem_divconquer.c @@ -0,0 +1,217 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("pseudo_divrem_divconquer...."); + fflush(stdout); + + + + /* Check q*b + r = l(b)^d a, no aliasing */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, q, r, prod; + fmpz_t p; + ulong d; + + fmpz_init(p); + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(q); + fmpz_poly_init(r); + fmpz_poly_init(prod); + fmpz_poly_randtest(a, state, n_randint(state, 200), 50); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1, 50); + + fmpz_poly_pseudo_divrem_divconquer(q, r, &d, a, b); + fmpz_poly_mul(prod, q, b); + fmpz_poly_add(prod, prod, r); + fmpz_pow_ui(p, b->coeffs + b->length - 1, d); + fmpz_poly_scalar_mul_fmpz(a, a, p); + + result = (fmpz_poly_equal(a, prod)); + if (!result) + { + flint_printf("FAIL (check qb + r = l(b)^d a):\n"); + flint_printf("l^d a = "), fmpz_poly_print(a), flint_printf("\n\n"); + flint_printf("qb + r = "), fmpz_poly_print(prod), flint_printf("\n\n"); + flint_printf("q = "), fmpz_poly_print(q), flint_printf("\n\n"); + flint_printf("r = "), fmpz_poly_print(r), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(p); + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(q); + fmpz_poly_clear(r); + fmpz_poly_clear(prod); + } + + /* Check r and a alias */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, q, r; + ulong d; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(q); + fmpz_poly_init(r); + fmpz_poly_randtest(a, state, n_randint(state, 100), 50); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1, 50); + + fmpz_poly_pseudo_divrem_divconquer(q, r, &d, a, b); + fmpz_poly_pseudo_divrem_divconquer(q, a, &d, a, b); + + result = (fmpz_poly_equal(a, r)); + if (!result) + { + flint_printf("FAIL (alias r and a):\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(q), flint_printf("\n\n"); + fmpz_poly_print(r), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(q); + fmpz_poly_clear(r); + } + + /* Check r and b alias */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, q, r; + ulong d; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(q); + fmpz_poly_init(r); + fmpz_poly_randtest(a, state, n_randint(state, 100), 50); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1, 50); + + fmpz_poly_pseudo_divrem_divconquer(q, r, &d, a, b); + fmpz_poly_pseudo_divrem_divconquer(q, b, &d, a, b); + + result = (fmpz_poly_equal(b, r)); + if (!result) + { + flint_printf("FAIL (alias r and b):\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(q), flint_printf("\n\n"); + fmpz_poly_print(r), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(q); + fmpz_poly_clear(r); + } + + /* Check q and a alias */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, q, r; + ulong d; + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(q); + fmpz_poly_init(r); + fmpz_poly_randtest(a, state, n_randint(state, 100), 50); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1, 50); + + fmpz_poly_pseudo_divrem_divconquer(q, r, &d, a, b); + fmpz_poly_pseudo_divrem_divconquer(a, r, &d, a, b); + + result = (fmpz_poly_equal(a, q)); + if (!result) + { + flint_printf("FAIL (alias q and a):\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(q), flint_printf("\n\n"); + fmpz_poly_print(r), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(q); + fmpz_poly_clear(r); + } + + /* Check q and b alias */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, q, r; + ulong d; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(q); + fmpz_poly_init(r); + fmpz_poly_randtest(a, state, n_randint(state, 100), 50); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1, 50); + + fmpz_poly_pseudo_divrem_divconquer(q, r, &d, a, b); + fmpz_poly_pseudo_divrem_divconquer(b, r, &d, a, b); + + result = (fmpz_poly_equal(b, q)); + if (!result) + { + flint_printf("FAIL (alias q and b):\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(q), flint_printf("\n\n"); + fmpz_poly_print(r), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(q); + fmpz_poly_clear(r); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-pseudo_rem.c b/external/flint-2.4.3/fmpz_poly/test/t-pseudo_rem.c new file mode 100644 index 0000000..e5e816e --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-pseudo_rem.c @@ -0,0 +1,144 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("pseudo_rem...."); + fflush(stdout); + + + + /* Compare with divrem */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, q, r, r2; + ulong d, d2; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(q); + fmpz_poly_init(r); + fmpz_poly_init(r2); + fmpz_poly_randtest(a, state, n_randint(state, 100), 50); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1, 50); + + fmpz_poly_pseudo_divrem(q, r, &d, a, b); + fmpz_poly_pseudo_rem(r2, &d2, a, b); + + result = (fmpz_poly_equal(r, r2) && d == d2); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + fmpz_poly_print(r), flint_printf("\n\n"); + fmpz_poly_print(r2), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(q); + fmpz_poly_clear(r); + fmpz_poly_clear(r2); + } + + /* Check r and a alias */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, r; + ulong d; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(r); + fmpz_poly_randtest(a, state, n_randint(state, 100), 50); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1, 50); + + fmpz_poly_pseudo_rem(r, &d, a, b); + fmpz_poly_pseudo_rem(a, &d, a, b); + + result = (fmpz_poly_equal(a, r)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + fmpz_poly_print(r), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(r); + } + + /* Check r and b alias */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, r; + ulong d; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(r); + fmpz_poly_randtest(a, state, n_randint(state, 100), 50); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1, 50); + + fmpz_poly_pseudo_rem(r, &d, a, b); + fmpz_poly_pseudo_rem(b, &d, a, b); + + result = (fmpz_poly_equal(b, r)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + fmpz_poly_print(r), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(r); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-pseudo_rem_cohen.c b/external/flint-2.4.3/fmpz_poly/test/t-pseudo_rem_cohen.c new file mode 100644 index 0000000..45cdda1 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-pseudo_rem_cohen.c @@ -0,0 +1,139 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("pseudo_rem_cohen...."); + fflush(stdout); + + + + /* Compare with q*b + r = a, no aliasing */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, q, r1, r2; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(q); + fmpz_poly_init(r1); + fmpz_poly_init(r2); + fmpz_poly_randtest(a, state, n_randint(state, 100), 200); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1, 200); + + fmpz_poly_pseudo_divrem_cohen(q, r1, a, b); + fmpz_poly_pseudo_rem_cohen(r2, a, b); + + result = (fmpz_poly_equal(r1, r2)); + if (!result) + { + flint_printf("FAIL (correctness):\n"); + flint_printf("a = "), fmpz_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_poly_print(b), flint_printf("\n\n"); + flint_printf("r1 = "), fmpz_poly_print(r1), flint_printf("\n\n"); + flint_printf("r2 = "), fmpz_poly_print(r2), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(q); + fmpz_poly_clear(r1); + fmpz_poly_clear(r2); + } + + /* Check r and a alias */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, r; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(r); + fmpz_poly_randtest(a, state, n_randint(state, 100), 200); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1, 200); + + fmpz_poly_pseudo_rem_cohen(r, a, b); + fmpz_poly_pseudo_rem_cohen(a, a, b); + + result = (fmpz_poly_equal(a, r)); + if (!result) + { + flint_printf("FAIL (aliasing r, a):\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(r), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(r); + } + + /* Check r and b alias */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, r; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(r); + fmpz_poly_randtest(a, state, n_randint(state, 100), 200); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 100) + 1, 200); + + fmpz_poly_pseudo_rem_cohen(r, a, b); + fmpz_poly_pseudo_rem_cohen(b, a, b); + + result = (fmpz_poly_equal(b, r)); + if (!result) + { + flint_printf("FAIL (aliasing r, b):\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + fmpz_poly_print(r), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(r); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-rem_basecase.c b/external/flint-2.4.3/fmpz_poly/test/t-rem_basecase.c new file mode 100644 index 0000000..f9af84b --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-rem_basecase.c @@ -0,0 +1,143 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("rem_basecase...."); + fflush(stdout); + + + + /* Compare with full division, no aliasing */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, q, r, r2; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(q); + fmpz_poly_init(r); + fmpz_poly_init(r2); + + fmpz_poly_randtest(a, state, n_randint(state, 50), 100); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, a->length + 1) + 1, 100); + + fmpz_poly_divrem_basecase(q, r, a, b); + fmpz_poly_rem_basecase(r2, a, b); + + result = (fmpz_poly_equal(r, r2)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + fmpz_poly_print(q), flint_printf("\n\n"); + fmpz_poly_print(r), flint_printf("\n\n"); + fmpz_poly_print(r2), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(q); + fmpz_poly_clear(r); + fmpz_poly_clear(r2); + } + + /* Check r and a alias */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, r; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(r); + fmpz_poly_randtest(a, state, n_randint(state, 50), 100); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 50) + 1, 100); + + fmpz_poly_rem_basecase(r, a, b); + fmpz_poly_rem_basecase(a, a, b); + + result = (fmpz_poly_equal(a, r)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(r), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(r); + } + + /* Check r and b alias */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, r; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(r); + fmpz_poly_randtest(a, state, n_randint(state, 50), 100); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 50) + 1, 100); + + fmpz_poly_rem_basecase(r, a, b); + fmpz_poly_rem_basecase(b, a, b); + + result = (fmpz_poly_equal(b, r)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(r), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(r); + } + + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-rem_powers_precomp.c b/external/flint-2.4.3/fmpz_poly/test/t-rem_powers_precomp.c new file mode 100644 index 0000000..dc12d06 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-rem_powers_precomp.c @@ -0,0 +1,155 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009, 2013 William Hart + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("rem_powers_precomp...."); + fflush(stdout); + + + + /* Compare with full division, no aliasing */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, q, r, r2; + fmpz_poly_powers_precomp_t b_inv; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(q); + fmpz_poly_init(r); + fmpz_poly_init(r2); + + fmpz_poly_randtest(a, state, n_randint(state, 50), 100); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, a->length + 1) + 1, 100); + fmpz_set_ui(b->coeffs + b->length - 1, 1); /* b must be monic */ + + fmpz_poly_divrem_basecase(q, r, a, b); + fmpz_poly_powers_precompute(b_inv, b); + fmpz_poly_rem_powers_precomp(r2, a, b, b_inv); + + result = (fmpz_poly_equal(r, r2)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + fmpz_poly_print(q), flint_printf("\n\n"); + fmpz_poly_print(r), flint_printf("\n\n"); + fmpz_poly_print(r2), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_powers_clear(b_inv); + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(q); + fmpz_poly_clear(r); + fmpz_poly_clear(r2); + } + + /* Check q and a alias */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, b_inv, q; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(b_inv); + fmpz_poly_init(q); + fmpz_poly_randtest(a, state, n_randint(state, 50), 100); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 50) + 1, 100); + fmpz_set_ui(b->coeffs + b->length - 1, 1); /* b must be monic */ + + fmpz_poly_div_basecase(q, a, b); + fmpz_poly_preinvert(b_inv, b); + fmpz_poly_div_preinv(a, a, b, b_inv); + + result = (fmpz_poly_equal(a, q)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(q), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(b_inv); + fmpz_poly_clear(q); + } + + /* Check q and b alias */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, b_inv, q; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(b_inv); + fmpz_poly_init(q); + fmpz_poly_randtest(a, state, n_randint(state, 50), 100); + fmpz_poly_randtest_not_zero(b, state, n_randint(state, 50) + 1, 100); + fmpz_set_ui(b->coeffs + b->length - 1, 1); /* b must be monic */ + + fmpz_poly_div_basecase(q, a, b); + fmpz_poly_preinvert(b_inv, b); + fmpz_poly_div_preinv(b, a, b, b_inv); + + result = (fmpz_poly_equal(b, q)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(q), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(b_inv); + fmpz_poly_clear(q); + } + + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-resultant.c b/external/flint-2.4.3/fmpz_poly/test/t-resultant.c new file mode 100644 index 0000000..fa2fbb1 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-resultant.c @@ -0,0 +1,126 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("resultant...."); + fflush(stdout); + + + + /* Just one specific test */ + { + fmpz_poly_t f, g; + fmpz_t a, b; + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_init(a); + fmpz_init(b); + fmpz_poly_set_str(f, "11 -15 -2 -2 17 0 0 6 0 -5 1 -1"); + fmpz_poly_set_str(g, "9 2 1 1 1 1 1 0 -1 -2"); + fmpz_poly_resultant(a, f, g); + fmpz_set_str(b, "-44081924855067", 10); + + result = (fmpz_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("f = "), fmpz_poly_print(f), flint_printf("\n\n"); + flint_printf("g = "), fmpz_poly_print(g), flint_printf("\n\n"); + flint_printf("res(f, h) = "), fmpz_print(a), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(f); + fmpz_poly_clear(g); + fmpz_clear(a); + fmpz_clear(b); + } + + /* Check that R(fg, h) = R(f, h) R(g, h) */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_t a, b, c, d; + fmpz_poly_t f, g, h, p; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + fmpz_init(d); + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_poly_init(h); + fmpz_poly_init(p); + fmpz_poly_randtest(f, state, n_randint(state, 50), 100); + fmpz_poly_randtest(g, state, n_randint(state, 50), 100); + fmpz_poly_randtest(h, state, n_randint(state, 10), 100); + + fmpz_poly_resultant(a, f, h); + fmpz_poly_resultant(b, g, h); + fmpz_mul(c, a, b); + fmpz_poly_mul(p, f, g); + fmpz_poly_resultant(d, p, h); + + result = (fmpz_equal(c, d)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("f = "), fmpz_poly_print(f), flint_printf("\n\n"); + flint_printf("g = "), fmpz_poly_print(g), flint_printf("\n\n"); + flint_printf("h = "), fmpz_poly_print(h), flint_printf("\n\n"); + flint_printf("res(f, h) = "), fmpz_print(a), flint_printf("\n\n"); + flint_printf("res(g, h) = "), fmpz_print(b), flint_printf("\n\n"); + flint_printf("res(fg, h) = "), fmpz_print(d), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + fmpz_clear(d); + fmpz_poly_clear(f); + fmpz_poly_clear(g); + fmpz_poly_clear(h); + fmpz_poly_clear(p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-reverse.c b/external/flint-2.4.3/fmpz_poly/test/t-reverse.c new file mode 100644 index 0000000..c85ad18 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-reverse.c @@ -0,0 +1,115 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("reverse...."); + fflush(stdout); + + + + /* Aliasing */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b; + slong n; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_randtest(b, state, n_randint(state, 100), 200); + n = n_randint(state, 150); + + fmpz_poly_reverse(a, b, n); + fmpz_poly_reverse(b, b, n); + + result = (fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("n = %wd\n", n); + flint_printf("a = "), fmpz_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + } + + /* Correctness (?) */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b; + slong j, len, n; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_randtest(b, state, n_randint(state, 100), 200); + n = n_randint(state, 150); + + len = FLINT_MIN(n, b->length); + if (len) + { + fmpz_poly_fit_length(a, n); + for (j = 0; j < len; j++) + fmpz_set(a->coeffs + (n - len) + j, b->coeffs + (len - 1 - j)); + _fmpz_poly_set_length(a, n); + _fmpz_poly_normalise(a); + } + + fmpz_poly_reverse(b, b, n); + + result = (fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("n = %wd\n", n); + flint_printf("a = "), fmpz_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-revert_series.c b/external/flint-2.4.3/fmpz_poly/test/t-revert_series.c new file mode 100644 index 0000000..9cbd2f9 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-revert_series.c @@ -0,0 +1,119 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("revert_series...."); + fflush(stdout); + + + + /* Check aliasing */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpz_poly_t f, g; + slong n; + + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_poly_randtest(g, state, n_randint(state, 50), + 1+n_randint(state,100)); + fmpz_poly_set_coeff_ui(g, 0, 0); + fmpz_poly_set_coeff_ui(g, 1, 1); + if (n_randlimb(state) % 2) + fmpz_poly_neg(g, g); /* get -x term */ + n = n_randint(state, 50); + + fmpz_poly_revert_series(f, g, n); + fmpz_poly_revert_series(g, g, n); + + result = (fmpz_poly_equal(f, g)); + if (!result) + { + flint_printf("FAIL (aliasing):\n"); + fmpz_poly_print(f), flint_printf("\n\n"); + fmpz_poly_print(g), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(f); + fmpz_poly_clear(g); + } + + /* Check f(f^(-1)) = id */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpz_poly_t f, g, h; + slong n; + + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_poly_init(h); + fmpz_poly_randtest(g, state, n_randint(state, 50), 10); + fmpz_poly_set_coeff_ui(g, 0, 0); + fmpz_poly_set_coeff_ui(g, 1, 1); + if (n_randlimb(state) % 2) + fmpz_poly_neg(g, g); /* get -x term */ + n = n_randint(state, 50); + + fmpz_poly_revert_series(f, g, n); + fmpz_poly_compose_series(h, g, f, n); + + result = ((n <= 1 && fmpz_poly_is_zero(h)) || + (h->length == 2 && fmpz_is_zero(h->coeffs + 0) && + fmpz_is_one(h->coeffs + 1))); + if (!result) + { + flint_printf("FAIL (comparison):\n"); + fmpz_poly_print(f), flint_printf("\n\n"); + fmpz_poly_print(g), flint_printf("\n\n"); + fmpz_poly_print(h), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(f); + fmpz_poly_clear(g); + fmpz_poly_clear(h); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-revert_series_lagrange.c b/external/flint-2.4.3/fmpz_poly/test/t-revert_series_lagrange.c new file mode 100644 index 0000000..cc404a3 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-revert_series_lagrange.c @@ -0,0 +1,119 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("revert_series_lagrange...."); + fflush(stdout); + + + + /* Check aliasing */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + fmpz_poly_t f, g; + slong n; + + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_poly_randtest(g, state, n_randint(state, 50), + 1+n_randint(state,100)); + fmpz_poly_set_coeff_ui(g, 0, 0); + fmpz_poly_set_coeff_ui(g, 1, 1); + if (n_randlimb(state) % 2) + fmpz_poly_neg(g, g); /* get -x term */ + n = n_randint(state, 50); + + fmpz_poly_revert_series_lagrange(f, g, n); + fmpz_poly_revert_series_lagrange(g, g, n); + + result = (fmpz_poly_equal(f, g)); + if (!result) + { + flint_printf("FAIL (aliasing):\n"); + fmpz_poly_print(f), flint_printf("\n\n"); + fmpz_poly_print(g), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(f); + fmpz_poly_clear(g); + } + + /* Check f(f^(-1)) = id */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + fmpz_poly_t f, g, h; + slong n; + + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_poly_init(h); + fmpz_poly_randtest(g, state, n_randint(state, 50), 1+n_randint(state,100)); + fmpz_poly_set_coeff_ui(g, 0, 0); + fmpz_poly_set_coeff_ui(g, 1, 1); + if (n_randlimb(state) % 2) + fmpz_poly_neg(g, g); /* get -x term */ + n = n_randint(state, 50); + + fmpz_poly_revert_series_lagrange(f, g, n); + fmpz_poly_compose_series(h, g, f, n); + + result = ((n <= 1 && fmpz_poly_is_zero(h)) || + (h->length == 2 && fmpz_is_zero(h->coeffs + 0) && + fmpz_is_one(h->coeffs + 1))); + if (!result) + { + flint_printf("FAIL (comparison):\n"); + fmpz_poly_print(f), flint_printf("\n\n"); + fmpz_poly_print(g), flint_printf("\n\n"); + fmpz_poly_print(h), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(f); + fmpz_poly_clear(g); + fmpz_poly_clear(h); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-revert_series_lagrange_fast.c b/external/flint-2.4.3/fmpz_poly/test/t-revert_series_lagrange_fast.c new file mode 100644 index 0000000..0ab18d2 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-revert_series_lagrange_fast.c @@ -0,0 +1,119 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("revert_series_lagrange_fast...."); + fflush(stdout); + + + + /* Check aliasing */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + fmpz_poly_t f, g; + slong n; + + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_poly_randtest(g, state, n_randint(state, 50), + 1+n_randint(state,100)); + fmpz_poly_set_coeff_ui(g, 0, 0); + fmpz_poly_set_coeff_ui(g, 1, 1); + if (n_randlimb(state) % 2) + fmpz_poly_neg(g, g); /* get -x term */ + n = n_randint(state, 50); + + fmpz_poly_revert_series_lagrange_fast(f, g, n); + fmpz_poly_revert_series_lagrange_fast(g, g, n); + + result = (fmpz_poly_equal(f, g)); + if (!result) + { + flint_printf("FAIL (aliasing):\n"); + fmpz_poly_print(f), flint_printf("\n\n"); + fmpz_poly_print(g), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(f); + fmpz_poly_clear(g); + } + + /* Check f(f^(-1)) = id */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + fmpz_poly_t f, g, h; + slong n; + + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_poly_init(h); + fmpz_poly_randtest(g, state, n_randint(state, 50), 1+n_randint(state,100)); + fmpz_poly_set_coeff_ui(g, 0, 0); + fmpz_poly_set_coeff_ui(g, 1, 1); + if (n_randlimb(state) % 2) + fmpz_poly_neg(g, g); /* get -x term */ + n = n_randint(state, 50); + + fmpz_poly_revert_series_lagrange_fast(f, g, n); + fmpz_poly_compose_series(h, g, f, n); + + result = ((n <= 1 && fmpz_poly_is_zero(h)) || + (h->length == 2 && fmpz_is_zero(h->coeffs + 0) && + fmpz_is_one(h->coeffs + 1))); + if (!result) + { + flint_printf("FAIL (comparison):\n"); + fmpz_poly_print(f), flint_printf("\n\n"); + fmpz_poly_print(g), flint_printf("\n\n"); + fmpz_poly_print(h), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(f); + fmpz_poly_clear(g); + fmpz_poly_clear(h); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-revert_series_newton.c b/external/flint-2.4.3/fmpz_poly/test/t-revert_series_newton.c new file mode 100644 index 0000000..4055603 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-revert_series_newton.c @@ -0,0 +1,119 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("revert_series_newton...."); + fflush(stdout); + + + + /* Check aliasing */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + fmpz_poly_t f, g; + slong n; + + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_poly_randtest(g, state, n_randint(state, 50), + 1+n_randint(state,100)); + fmpz_poly_set_coeff_ui(g, 0, 0); + fmpz_poly_set_coeff_ui(g, 1, 1); + if (n_randlimb(state) % 2) + fmpz_poly_neg(g, g); /* get -x term */ + n = n_randint(state, 50); + + fmpz_poly_revert_series_newton(f, g, n); + fmpz_poly_revert_series_newton(g, g, n); + + result = (fmpz_poly_equal(f, g)); + if (!result) + { + flint_printf("FAIL (aliasing):\n"); + fmpz_poly_print(f), flint_printf("\n\n"); + fmpz_poly_print(g), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(f); + fmpz_poly_clear(g); + } + + /* Check f(f^(-1)) = id */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + fmpz_poly_t f, g, h; + slong n; + + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_poly_init(h); + fmpz_poly_randtest(g, state, n_randint(state, 50), 1+n_randint(state,100)); + fmpz_poly_set_coeff_ui(g, 0, 0); + fmpz_poly_set_coeff_ui(g, 1, 1); + if (n_randlimb(state) % 2) + fmpz_poly_neg(g, g); /* get -x term */ + n = n_randint(state, 50); + + fmpz_poly_revert_series_newton(f, g, n); + fmpz_poly_compose_series(h, g, f, n); + + result = ((n <= 1 && fmpz_poly_is_zero(h)) || + (h->length == 2 && fmpz_is_zero(h->coeffs + 0) && + fmpz_is_one(h->coeffs + 1))); + if (!result) + { + flint_printf("FAIL (comparison):\n"); + fmpz_poly_print(f), flint_printf("\n\n"); + fmpz_poly_print(g), flint_printf("\n\n"); + fmpz_poly_print(h), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(f); + fmpz_poly_clear(g); + fmpz_poly_clear(h); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-scalar_addmul_fmpz.c b/external/flint-2.4.3/fmpz_poly/test/t-scalar_addmul_fmpz.c new file mode 100644 index 0000000..3dd4560 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-scalar_addmul_fmpz.c @@ -0,0 +1,121 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("scalar_addmul_fmpz...."); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + fmpz_t x; + + fmpz_init(x); + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_randtest(x, state, n_randint(state, 100)); + fmpz_poly_randtest(a, state, n_randint(state, 100), 200); + fmpz_poly_set(b, a); + fmpz_poly_set(c, a); + + fmpz_poly_scalar_addmul_fmpz(b, a, x); + fmpz_poly_scalar_addmul_fmpz(a, a, x); + + result = (fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL (1):\n"); + flint_printf("a = "), fmpz_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_poly_print(b), flint_printf("\n\n"); + flint_printf("c = "), fmpz_poly_print(c), flint_printf("\n\n"); + flint_printf("x = "), fmpz_print(x), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(x); + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + /* Check that b += x*a is the same as c = b + x*a */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + fmpz_t x; + + fmpz_init(x); + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_randtest(x, state, n_randint(state, 100)); + fmpz_poly_randtest(a, state, n_randint(state, 100), 200); + fmpz_poly_randtest(b, state, n_randint(state, 100), 200); + + fmpz_poly_scalar_mul_fmpz(c, a, x); + fmpz_poly_add(c, b, c); + + fmpz_poly_scalar_addmul_fmpz(b, a, x); + + result = (fmpz_poly_equal(b, c)); + if (!result) + { + flint_printf("FAIL (2):\n"); + flint_printf("a = "), fmpz_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_poly_print(b), flint_printf("\n\n"); + flint_printf("c = "), fmpz_poly_print(c), flint_printf("\n\n"); + flint_printf("x = "), fmpz_print(x), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(x); + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-scalar_divexact_mpz.c b/external/flint-2.4.3/fmpz_poly/test/t-scalar_divexact_mpz.c new file mode 100644 index 0000000..2eecda0 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-scalar_divexact_mpz.c @@ -0,0 +1,100 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("scalar_divexact_mpz...."); + fflush(stdout); + + + + /* Compare with fmpz_poly_scalar_divexact_fmpz */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + fmpz_t n; + mpz_t n1; + + fmpz_init(n); + mpz_init(n1); + do { + fmpz_randtest(n, state, 200); + } while (fmpz_is_zero(n)); + fmpz_get_mpz(n1, n); + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(a, state, n_randint(state, 100), 200); + fmpz_poly_scalar_mul_fmpz(a, a, n); + + fmpz_poly_scalar_divexact_fmpz(b, a, n); + fmpz_poly_scalar_divexact_mpz(c, a, n1); + + result = (fmpz_poly_equal(b, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + fmpz_poly_print(c), flint_printf("\n\n"); + abort(); + } + + /* aliasing */ + fmpz_poly_scalar_divexact_mpz(a, a, n1); + result = (fmpz_poly_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(c), flint_printf("\n\n"); + abort(); + } + + mpz_clear(n1); + fmpz_clear(n); + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-scalar_fdiv_mpz.c b/external/flint-2.4.3/fmpz_poly/test/t-scalar_fdiv_mpz.c new file mode 100644 index 0000000..4adb23d --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-scalar_fdiv_mpz.c @@ -0,0 +1,100 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("scalar_fdiv_mpz...."); + fflush(stdout); + + + + /* Compare with fmpz_poly_scalar_fdiv_fmpz */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + fmpz_t n; + mpz_t n1; + + fmpz_init(n); + mpz_init(n1); + do { + fmpz_randtest(n, state, 200); + } while (fmpz_is_zero(n)); + fmpz_get_mpz(n1, n); + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(a, state, n_randint(state, 100), 200); + fmpz_poly_scalar_mul_fmpz(a, a, n); + + fmpz_poly_scalar_fdiv_fmpz(b, a, n); + fmpz_poly_scalar_fdiv_mpz(c, a, n1); + + result = (fmpz_poly_equal(b, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + fmpz_poly_print(c), flint_printf("\n\n"); + abort(); + } + + /* aliasing */ + fmpz_poly_scalar_fdiv_mpz(a, a, n1); + result = (fmpz_poly_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(c), flint_printf("\n\n"); + abort(); + } + + mpz_clear(n1); + fmpz_clear(n); + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-scalar_mul_fmpz.c b/external/flint-2.4.3/fmpz_poly/test/t-scalar_mul_fmpz.c new file mode 100644 index 0000000..2c2d42b --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-scalar_mul_fmpz.c @@ -0,0 +1,111 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("scalar_mul_fmpz...."); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b; + fmpz_t n; + fmpz_init(n); + fmpz_randtest(n, state, 200); + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_randtest(a, state, n_randint(state, 100), 200); + + fmpz_poly_scalar_mul_fmpz(b, a, n); + fmpz_poly_scalar_mul_fmpz(a, a, n); + + result = (fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(n); + fmpz_poly_clear(a); + fmpz_poly_clear(b); + } + + /* Compare with fmpz_poly_scalar_mul_si */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b; + fmpz_t n1; + slong n; + fmpz_init(n1); + n = (slong) n_randbits(state, FLINT_BITS - 1); + if (n_randint(state, 2)) + n = -n; + fmpz_set_si(n1, n); + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_randtest(a, state, n_randint(state, 100), 200); + + fmpz_poly_scalar_mul_fmpz(b, a, n1); + fmpz_poly_scalar_mul_si(a, a, n); + + result = (fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(n1); + fmpz_poly_clear(a); + fmpz_poly_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-scalar_mul_mpz.c b/external/flint-2.4.3/fmpz_poly/test/t-scalar_mul_mpz.c new file mode 100644 index 0000000..1041682 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-scalar_mul_mpz.c @@ -0,0 +1,97 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("scalar_mul_mpz...."); + fflush(stdout); + + + + /* Compare with fmpz_poly_scalar_mul_fmpz */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + fmpz_t n; + mpz_t n1; + + fmpz_init(n); + mpz_init(n1); + fmpz_randtest(n, state, 200); + fmpz_get_mpz(n1, n); + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(a, state, n_randint(state, 100), 200); + + fmpz_poly_scalar_mul_fmpz(b, a, n); + fmpz_poly_scalar_mul_mpz(c, a, n1); + + result = (fmpz_poly_equal(b, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + fmpz_poly_print(c), flint_printf("\n\n"); + abort(); + } + + /* aliasing */ + fmpz_poly_scalar_mul_mpz(a, a, n1); + result = (fmpz_poly_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(c), flint_printf("\n\n"); + abort(); + } + + mpz_clear(n1); + fmpz_clear(n); + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-scalar_mul_si.c b/external/flint-2.4.3/fmpz_poly/test/t-scalar_mul_si.c new file mode 100644 index 0000000..407617a --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-scalar_mul_si.c @@ -0,0 +1,137 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "long_extras.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("scalar_mul_si...."); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b; + slong n = z_randtest(state); + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_randtest(a, state, n_randint(state, 100), 200); + + fmpz_poly_scalar_mul_si(b, a, n); + fmpz_poly_scalar_mul_si(a, a, n); + + result = (fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + } + + /* Compare with fmpz_poly_scalar_mul_ui */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b; + ulong n = n_randbits(state, FLINT_BITS - 1); + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_randtest(a, state, n_randint(state, 100), 200); + + fmpz_poly_scalar_mul_ui(b, a, n); + fmpz_poly_scalar_mul_si(a, a, n); + + result = (fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + } + + /* Check (a*n1)*n2 = a*(n1*n2) */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + slong n1 = (slong) n_randbits(state, (FLINT_BITS - 2) / 2); + slong n2 = (slong) n_randbits(state, (FLINT_BITS - 2) / 2); + if (n_randint(state, 2)) + n1 = -n1; + if (n_randint(state, 2)) + n2 = -n2; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(a, state, n_randint(state, 100), 200); + + fmpz_poly_scalar_mul_si(b, a, n1); + fmpz_poly_scalar_mul_si(c, b, n2); + fmpz_poly_scalar_mul_si(b, a, n1 * n2); + + result = (fmpz_poly_equal(b, c)); + if (!result) + { + flint_printf("FAIL n1 = %wd, n2 = %wd:\n", n1, n2); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + fmpz_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-scalar_mul_ui.c b/external/flint-2.4.3/fmpz_poly/test/t-scalar_mul_ui.c new file mode 100644 index 0000000..3794ddc --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-scalar_mul_ui.c @@ -0,0 +1,106 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("scalar_mul_ui...."); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b; + ulong n = n_randtest(state); + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_randtest(a, state, n_randint(state, 100), 200); + + fmpz_poly_scalar_mul_ui(b, a, n); + fmpz_poly_scalar_mul_ui(a, a, n); + + result = (fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + } + + /* Check (a*n1)*n2 = a*(n1*n2) */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + ulong n1 = n_randbits(state, FLINT_BITS / 2); + ulong n2 = n_randbits(state, FLINT_BITS / 2); + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(a, state, n_randint(state, 100), 200); + + fmpz_poly_scalar_mul_ui(b, a, n1); + fmpz_poly_scalar_mul_ui(c, b, n2); + fmpz_poly_scalar_mul_ui(b, a, n1 * n2); + + result = (fmpz_poly_equal(b, c)); + if (!result) + { + flint_printf("FAIL n1 = %wu, n2 = %wu:\n", n1, n2); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + fmpz_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-scalar_submul_fmpz.c b/external/flint-2.4.3/fmpz_poly/test/t-scalar_submul_fmpz.c new file mode 100644 index 0000000..5a7f808 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-scalar_submul_fmpz.c @@ -0,0 +1,121 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("scalar_submul_fmpz...."); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + fmpz_t x; + + fmpz_init(x); + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_randtest(x, state, n_randint(state, 100)); + fmpz_poly_randtest(a, state, n_randint(state, 100), 200); + fmpz_poly_set(b, a); + fmpz_poly_set(c, a); + + fmpz_poly_scalar_submul_fmpz(b, a, x); + fmpz_poly_scalar_submul_fmpz(a, a, x); + + result = (fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL (1):\n"); + flint_printf("a = "), fmpz_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_poly_print(b), flint_printf("\n\n"); + flint_printf("c = "), fmpz_poly_print(c), flint_printf("\n\n"); + flint_printf("x = "), fmpz_print(x), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(x); + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + /* Check that b += x*a is the same as c = b + x*a */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + fmpz_t x; + + fmpz_init(x); + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_randtest(x, state, n_randint(state, 100)); + fmpz_poly_randtest(a, state, n_randint(state, 100), 200); + fmpz_poly_randtest(b, state, n_randint(state, 100), 200); + + fmpz_poly_scalar_mul_fmpz(c, a, x); + fmpz_poly_sub(c, b, c); + + fmpz_poly_scalar_submul_fmpz(b, a, x); + + result = (fmpz_poly_equal(b, c)); + if (!result) + { + flint_printf("FAIL (2):\n"); + flint_printf("a = "), fmpz_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_poly_print(b), flint_printf("\n\n"); + flint_printf("c = "), fmpz_poly_print(c), flint_printf("\n\n"); + flint_printf("x = "), fmpz_print(x), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(x); + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-set_equal.c b/external/flint-2.4.3/fmpz_poly/test/t-set_equal.c new file mode 100644 index 0000000..90124bc --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-set_equal.c @@ -0,0 +1,108 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("set/equal...."); + fflush(stdout); + + + + /* equal polynomials */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_randtest(a, state, n_randint(state, 100), 200); + + fmpz_poly_set(b, a); + + result = (fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + } + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b; + slong coeff = n_randint(state, 100); + fmpz_t x1, x2; + + fmpz_init(x1); + fmpz_init(x2); + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_randtest(a, state, n_randint(state, 100), 200); + + fmpz_poly_set(b, a); + + fmpz_poly_get_coeff_fmpz(x2, b, coeff); + do + fmpz_randtest(x1, state, 200); + while (fmpz_equal(x1, x2)); + fmpz_poly_set_coeff_fmpz(b, coeff, x1); + + result = (!fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(x1); + fmpz_clear(x2); + fmpz_poly_clear(a); + fmpz_poly_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-set_fmpz_equal.c b/external/flint-2.4.3/fmpz_poly/test/t-set_fmpz_equal.c new file mode 100644 index 0000000..d967fe6 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-set_fmpz_equal.c @@ -0,0 +1,112 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("set_fmpz_equal...."); + fflush(stdout); + + + + /* equal polynomials */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b; + fmpz_t n; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_init(n); + + fmpz_randtest(n, state, 200); + fmpz_poly_set_fmpz(a, n); + fmpz_poly_set(b, a); + + result = (fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("n = "), fmpz_print(n), flint_printf("\n\n"); + flint_printf("a = "), fmpz_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_clear(n); + } + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b; + fmpz_t m, n; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_init(m); + fmpz_init(n); + + fmpz_randtest(m, state, 200); + fmpz_randtest(n, state, 200); + while (fmpz_equal(m, n)) + fmpz_randtest(n, state, 200); + fmpz_poly_set_fmpz(a, m); + fmpz_poly_set_fmpz(b, n); + + result = (!fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("m = "), fmpz_print(m), flint_printf("\n\n"); + flint_printf("n = "), fmpz_print(n), flint_printf("\n\n"); + flint_printf("a = "), fmpz_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_clear(m); + fmpz_clear(n); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-set_mpz_equal.c b/external/flint-2.4.3/fmpz_poly/test/t-set_mpz_equal.c new file mode 100644 index 0000000..1a66767 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-set_mpz_equal.c @@ -0,0 +1,116 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + gmp_randstate_t state; + + FLINT_TEST_INIT(dummy); + + flint_printf("set_mpz_equal...."); + fflush(stdout); + + gmp_randinit_default(state); + gmp_randseed_ui(state, 23); + + /* equal polynomials */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b; + mpz_t n; + + fmpz_poly_init(a); + fmpz_poly_init(b); + mpz_init(n); + + mpz_rrandomb(n, state, 200); + fmpz_poly_set_mpz(a, n); + fmpz_poly_set(b, a); + + result = (fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("n = %Zd\n\n", n); + flint_printf("a = "), fmpz_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + mpz_clear(n); + } + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b; + mpz_t m, n; + + fmpz_poly_init(a); + fmpz_poly_init(b); + mpz_init(m); + mpz_init(n); + + mpz_rrandomb(m, state, 200); + mpz_rrandomb(n, state, 200); + while (mpz_cmp(m, n) == 0) + mpz_rrandomb(n, state, 200); + fmpz_poly_set_mpz(a, m); + fmpz_poly_set_mpz(b, n); + + result = (!fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("m = %Zd\n\n", m); + gmp_printf("n = %Zd\n\n", n); + flint_printf("a = "), fmpz_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + mpz_clear(m); + mpz_clear(n); + } + + gmp_randclear(state); + + FLINT_TEST_CLEANUP(dummy); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-set_si_equal.c b/external/flint-2.4.3/fmpz_poly/test/t-set_si_equal.c new file mode 100644 index 0000000..892bcfe --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-set_si_equal.c @@ -0,0 +1,107 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "long_extras.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("set_si_equal...."); + fflush(stdout); + + + + /* equal polynomials */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b; + slong n; + + fmpz_poly_init(a); + fmpz_poly_init(b); + n = z_randtest(state); + + fmpz_poly_set_si(a, n); + fmpz_poly_set(b, a); + + result = (fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("n = %wd\n\n", n); + flint_printf("a = "), fmpz_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + } + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b; + slong m, n; + + fmpz_poly_init(a); + fmpz_poly_init(b); + + m = z_randtest(state); + n = z_randtest(state); + while (m == n) + n = z_randtest(state); + fmpz_poly_set_si(a, m); + fmpz_poly_set_si(b, n); + + result = (!fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("m = %wd\n\n", m); + flint_printf("n = %wd\n\n", n); + flint_printf("a = "), fmpz_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-set_ui_equal.c b/external/flint-2.4.3/fmpz_poly/test/t-set_ui_equal.c new file mode 100644 index 0000000..99e7df3 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-set_ui_equal.c @@ -0,0 +1,106 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("set_ui_equal...."); + fflush(stdout); + + + + /* equal polynomials */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b; + ulong n; + + fmpz_poly_init(a); + fmpz_poly_init(b); + n = n_randtest(state); + + fmpz_poly_set_ui(a, n); + fmpz_poly_set(b, a); + + result = (fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("n = %wu\n\n", n); + flint_printf("a = "), fmpz_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + } + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b; + ulong m, n; + + fmpz_poly_init(a); + fmpz_poly_init(b); + + m = n_randtest(state); + n = n_randtest(state); + while (m == n) + n = n_randtest(state); + fmpz_poly_set_ui(a, m); + fmpz_poly_set_ui(b, n); + + result = (!fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("m = %wu\n\n", m); + flint_printf("n = %wu\n\n", n); + flint_printf("a = "), fmpz_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-shift_left_right.c b/external/flint-2.4.3/fmpz_poly/test/t-shift_left_right.c new file mode 100644 index 0000000..9117326 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-shift_left_right.c @@ -0,0 +1,132 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("shift_left/right...."); + fflush(stdout); + + + + /* Check aliasing of a and b for left shift */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b; + slong shift = n_randint(state, 100); + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_randtest(a, state, n_randint(state, 100), 200); + + fmpz_poly_shift_left(b, a, shift); + fmpz_poly_shift_left(a, a, shift); + + result = (fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + } + + /* Check aliasing of a and b for right shift */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b; + slong shift; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_randtest_not_zero(a, state, n_randint(state, 100) + 1, 200); + + shift = n_randint(state, a->length); + + fmpz_poly_shift_right(b, a, shift); + fmpz_poly_shift_right(a, a, shift); + + result = (fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + } + + /* Check shift left then right does nothing */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + slong shift = n_randint(state, 100); + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(a, state, n_randint(state, 100), 200); + + fmpz_poly_shift_left(b, a, shift); + fmpz_poly_shift_right(c, b, shift); + + result = (fmpz_poly_equal(c, a)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + fmpz_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-signature.c b/external/flint-2.4.3/fmpz_poly/test/t-signature.c new file mode 100644 index 0000000..e01f97d --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-signature.c @@ -0,0 +1,157 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, j, result; + FLINT_TEST_INIT(state); + + flint_printf("signature...."); + fflush(stdout); + + + + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpz_poly_t poly, linear, quadratic, rem; + fmpz_t lhs, rhs; + slong nreal, ncomplex, nreal_max, ncomplex_max, r1, r2; + slong len = n_randint(state, 20) + 1; + mp_bitcnt_t bits = n_randint(state, 50) + 1; + + fmpz_poly_init2(poly, len); + fmpz_poly_init2(linear, 2); + fmpz_poly_init2(quadratic, 3); + fmpz_poly_init2(rem, len); + linear->length = 2; + quadratic->length = 3; + fmpz_init(lhs); + fmpz_init(rhs); + + ncomplex_max = n_randint(state, len) / 2; + nreal_max = len - 2 * ncomplex_max; + ncomplex = 0; + nreal = 0; + + fmpz_poly_set_coeff_si(poly, 0, 1); + + for (j = 0; j < ncomplex_max; j++) + { + fmpz * a = quadratic->coeffs + 2; + fmpz * b = quadratic->coeffs + 1; + fmpz * c = quadratic->coeffs; + + /* Form a quadratic polynomial with complex roots: b^2 < 4ac */ + fmpz_randtest_not_zero(c, state, bits); + fmpz_randtest(b, state, bits); + fmpz_randtest_unsigned(a, state, bits); + + if (fmpz_sgn(c) < 0) + { + fmpz_neg(c, c); + fmpz_neg(b, b); + } + + fmpz_mul_ui(rhs, c, 4); + fmpz_mul(lhs, b, b); + fmpz_add(lhs, lhs, rhs); + fmpz_fdiv_q(lhs, lhs, rhs); + fmpz_add(a, a, lhs); + + /* If quadratic does not divide poly over Q, set poly *= complex */ + fmpz_poly_pseudo_rem_cohen(rem, poly, quadratic); + if (rem->length > 0) + { + fmpz_poly_mul(poly, poly, quadratic); + ncomplex++; + } + } + + for (j = 0; j < nreal_max; j++) + { + /* Form a linear polynomial */ + fmpz_randtest(linear->coeffs, state, bits); + fmpz_randtest_not_zero(linear->coeffs + 1, state, bits); + + /* If linear does not divide poly over Q, set poly *= linear */ + fmpz_poly_pseudo_rem_cohen(rem, poly, linear); + if (rem->length > 0) + { + fmpz_poly_mul(poly, poly, linear); + nreal++; + } + } + + fmpz_poly_signature(&r1, &r2, poly); + + result = ((r1 == nreal) && (r2 == ncomplex)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("poly = "), fmpz_poly_print(poly), flint_printf("\n\n"); + flint_printf("r1 r2 = %wd %wd\n\n", r1, r2); + abort(); + } + + fmpz_poly_clear(poly); + fmpz_poly_clear(linear); + fmpz_poly_clear(quadratic); + fmpz_poly_clear(rem); + fmpz_clear(lhs); + fmpz_clear(rhs); + } + + { + fmpz_poly_t poly; + slong r1, r2; + fmpz_poly_init(poly); + fmpz_poly_set_str(poly, "6 1 1 1 10 5 1"); + fmpz_poly_signature(&r1, &r2, poly); + result = ((r1 == 1) && (r2 == 2)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("poly = "), fmpz_poly_print(poly), flint_printf("\n\n"); + flint_printf("r1 r2 = %wd %wd\n\n", r1, r2); + abort(); + } + fmpz_poly_clear(poly); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-sqr.c b/external/flint-2.4.3/fmpz_poly/test/t-sqr.c new file mode 100644 index 0000000..a0afb8b --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-sqr.c @@ -0,0 +1,141 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("sqr...."); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(a, state, n_randint(state, 50), 500); + + fmpz_poly_set(b, a); + fmpz_poly_sqr(c, b); + fmpz_poly_sqr(b, b); + + result = (fmpz_poly_equal(b, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + fmpz_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + /* Compare with mul */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(a, state, n_randint(state, 100), 500); + + fmpz_poly_sqr(b, a); + fmpz_poly_mul(c, a, a); + + result = (fmpz_poly_equal(b, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + fmpz_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + /* Check _fmpz_poly_sqr directly */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + slong len; + fmpz_poly_t a, out1, out2; + + len = n_randint(state, 100) + 1; + fmpz_poly_init(a); + fmpz_poly_init(out1); + fmpz_poly_init(out2); + fmpz_poly_randtest(a, state, len, 200); + + fmpz_poly_sqr(out1, a); + fmpz_poly_fit_length(a, a->alloc + n_randint(state, 10)); + a->length = a->alloc; + fmpz_poly_fit_length(out2, 2 * a->length - 1); + _fmpz_poly_sqr(out2->coeffs, a->coeffs, a->length); + _fmpz_poly_set_length(out2, 2 * a->length - 1); + _fmpz_poly_normalise(out2); + + result = (fmpz_poly_equal(out1, out2)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(out1), flint_printf("\n\n"); + fmpz_poly_print(out2), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(out1); + fmpz_poly_clear(out2); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-sqr_KS.c b/external/flint-2.4.3/fmpz_poly/test/t-sqr_KS.c new file mode 100644 index 0000000..e7b542e --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-sqr_KS.c @@ -0,0 +1,168 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("sqr_KS...."); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(a, state, n_randint(state, 50), 200); + fmpz_poly_set(b, a); + fmpz_poly_sqr_KS(c, b); + fmpz_poly_sqr_KS(b, b); + + result = (fmpz_poly_equal(b, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + fmpz_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + /* Compare with mul_classical */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(a, state, n_randint(state, 50), 200); + + fmpz_poly_sqr_KS(b, a); + fmpz_poly_sqr_classical(c, a); + + result = (fmpz_poly_equal(b, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + fmpz_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + /* Compare with mul_classical unsigned */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest_unsigned(a, state, n_randint(state, 50), 200); + + fmpz_poly_sqr_KS(b, a); + fmpz_poly_sqr_classical(c, a); + + result = (fmpz_poly_equal(b, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + fmpz_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + /* Check _fmpz_poly_sqr_KS directly */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + slong len; + fmpz_poly_t a, out1, out2; + + len = n_randint(state, 100) + 1; + fmpz_poly_init(a); + fmpz_poly_init(out1); + fmpz_poly_init(out2); + fmpz_poly_randtest(a, state, len, 200); + + fmpz_poly_sqr_KS(out1, a); + fmpz_poly_fit_length(a, a->alloc + n_randint(state, 10)); + a->length = a->alloc; + fmpz_poly_fit_length(out2, 2 * a->length - 1); + _fmpz_poly_sqr_KS(out2->coeffs, a->coeffs, a->length); + _fmpz_poly_set_length(out2, 2 * a->length - 1); + _fmpz_poly_normalise(out2); + + result = (fmpz_poly_equal(out1, out2)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(out1), flint_printf("\n\n"); + fmpz_poly_print(out2), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(out1); + fmpz_poly_clear(out2); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-sqr_classical.c b/external/flint-2.4.3/fmpz_poly/test/t-sqr_classical.c new file mode 100644 index 0000000..aa5a9cb --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-sqr_classical.c @@ -0,0 +1,105 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("sqr_classical...."); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_randtest(b, state, n_randint(state, 50), 200); + + fmpz_poly_sqr_classical(a, b); + fmpz_poly_sqr_classical(b, b); + + result = (fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + } + + /* Compare with mul_classical */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(a, state, n_randint(state, 50), 200); + fmpz_poly_set(b, a); + + fmpz_poly_sqr_classical(c, b); + fmpz_poly_mul_classical(b, b, b); + + result = (fmpz_poly_equal(b, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + fmpz_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} + diff --git a/external/flint-2.4.3/fmpz_poly/test/t-sqr_karatsuba.c b/external/flint-2.4.3/fmpz_poly/test/t-sqr_karatsuba.c new file mode 100644 index 0000000..f0d06f9 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-sqr_karatsuba.c @@ -0,0 +1,141 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("sqr_karatsuba...."); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(a, state, n_randint(state, 50), 200); + fmpz_poly_set(b, a); + + fmpz_poly_sqr_karatsuba(c, b); + fmpz_poly_sqr_karatsuba(b, b); + + result = (fmpz_poly_equal(b, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + fmpz_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + /* Compare with mul_karatsuba */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(a, state, n_randint(state, 50), 200); + + fmpz_poly_sqr_karatsuba(b, a); + fmpz_poly_mul_karatsuba(c, a, a); + + result = (fmpz_poly_equal(b, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + fmpz_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + /* Check _fmpz_poly_sqr_karatsuba directly */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + slong len; + fmpz_poly_t a, out1, out2; + + len = n_randint(state, 100) + 1; + fmpz_poly_init(a); + fmpz_poly_init(out1); + fmpz_poly_init(out2); + fmpz_poly_randtest(a, state, len, 200); + + fmpz_poly_sqr_karatsuba(out1, a); + fmpz_poly_fit_length(a, a->alloc + n_randint(state, 10)); + a->length = a->alloc; + fmpz_poly_fit_length(out2, 2 * a->length - 1); + _fmpz_poly_sqr_karatsuba(out2->coeffs, a->coeffs, a->length); + _fmpz_poly_set_length(out2, 2 * a->length - 1); + _fmpz_poly_normalise(out2); + + result = (fmpz_poly_equal(out1, out2)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(out1), flint_printf("\n\n"); + fmpz_poly_print(out2), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(out1); + fmpz_poly_clear(out2); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-sqrlow.c b/external/flint-2.4.3/fmpz_poly/test/t-sqrlow.c new file mode 100644 index 0000000..dfba39f --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-sqrlow.c @@ -0,0 +1,112 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("sqrlow...."); + fflush(stdout); + + + + /* Check aliasing */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b; + slong len, trunc; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_randtest(b, state, n_randint(state, 50), 200); + + len = 2 * b->length - 1; + trunc = (len <= 0) ? 0 : n_randint(state, 2 * b->length); + + fmpz_poly_sqrlow(a, b, trunc); + fmpz_poly_sqrlow(b, b, trunc); + + result = (fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + } + + /* Compare with sqr */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + slong len, trunc; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(b, state, n_randint(state, 50), 200); + + len = 2 * b->length - 1; + trunc = (len <= 0) ? 0 : n_randint(state, 2 * b->length - 1); + + fmpz_poly_sqr(a, b); + fmpz_poly_truncate(a, trunc); + fmpz_poly_sqrlow(c, b, trunc); + + result = (fmpz_poly_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + fmpz_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-sqrlow_KS.c b/external/flint-2.4.3/fmpz_poly/test/t-sqrlow_KS.c new file mode 100644 index 0000000..89c7503 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-sqrlow_KS.c @@ -0,0 +1,112 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("sqrlow_KS...."); + fflush(stdout); + + + + /* Check aliasing */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b; + slong len, trunc; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_randtest(b, state, n_randint(state, 50), 200); + + len = 2 * b->length - 1; + trunc = (len <= 0) ? 0 : n_randint(state, 2 * b->length); + + fmpz_poly_sqrlow_KS(a, b, trunc); + fmpz_poly_sqrlow_KS(b, b, trunc); + + result = (fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + } + + /* Compare with sqr_KS */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + slong len, trunc; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(b, state, n_randint(state, 50), 200); + + len = 2 * b->length - 1; + trunc = (len <= 0) ? 0 : n_randint(state, 2 * b->length - 1); + + fmpz_poly_sqr_KS(a, b); + fmpz_poly_truncate(a, trunc); + fmpz_poly_sqrlow_KS(c, b, trunc); + + result = (fmpz_poly_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + fmpz_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-sqrlow_classical.c b/external/flint-2.4.3/fmpz_poly/test/t-sqrlow_classical.c new file mode 100644 index 0000000..5153a1a --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-sqrlow_classical.c @@ -0,0 +1,112 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("sqrlow_classical...."); + fflush(stdout); + + + + /* Check aliasing */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b; + slong len, trunc; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_randtest(b, state, n_randint(state, 50), 200); + + len = 2 * b->length - 1; + trunc = (len <= 0) ? 0 : n_randint(state, 2 * b->length); + + fmpz_poly_sqrlow_classical(a, b, trunc); + fmpz_poly_sqrlow_classical(b, b, trunc); + + result = (fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + } + + /* Compare with sqr_classical */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + slong len, trunc; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(b, state, n_randint(state, 50), 200); + + len = 2 * b->length - 1; + trunc = (len <= 0) ? 0 : n_randint(state, 2 * b->length - 1); + + fmpz_poly_mul_classical(a, b, b); + fmpz_poly_truncate(a, trunc); + fmpz_poly_sqrlow_classical(c, b, trunc); + + result = (fmpz_poly_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + fmpz_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-sqrlow_karatsuba_n.c b/external/flint-2.4.3/fmpz_poly/test/t-sqrlow_karatsuba_n.c new file mode 100644 index 0000000..5430a83 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-sqrlow_karatsuba_n.c @@ -0,0 +1,112 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("sqrlow_karatsuba_n...."); + fflush(stdout); + + + + /* Check aliasing */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b; + slong len, trunc; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_randtest(b, state, n_randint(state, 50), 200); + + len = 2 * b->length - 1; + trunc = (len <= 0) ? 0 : n_randint(state, 2 * b->length); + + fmpz_poly_sqrlow_karatsuba_n(a, b, trunc); + fmpz_poly_sqrlow_karatsuba_n(b, b, trunc); + + result = (fmpz_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + } + + /* Compare with sqr_karatsuba */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + slong len, trunc; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(b, state, n_randint(state, 50), 200); + + len = 2 * b->length - 1; + trunc = (len <= 0) ? 0 : n_randint(state, 2 * b->length - 1); + + fmpz_poly_sqr_karatsuba(a, b); + fmpz_poly_truncate(a, trunc); + fmpz_poly_sqrlow_karatsuba_n(c, b, trunc); + + result = (fmpz_poly_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + fmpz_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-sqrt.c b/external/flint-2.4.3/fmpz_poly/test/t-sqrt.c new file mode 100644 index 0000000..1d993e7 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-sqrt.c @@ -0,0 +1,172 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + flint_printf("sqrt... "); + fflush(stdout); + + + + /* Test aliasing */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b; + int square1, square2; + + fmpz_poly_init(a); + fmpz_poly_init(b); + + fmpz_poly_randtest(a, state, 1 + n_randint(state, 20), + 1 + n_randint(state, 200)); + + if (n_randint(state, 2)) + fmpz_poly_sqr(a, a); + + square1 = fmpz_poly_sqrt(b, a); + square2 = fmpz_poly_sqrt(a, a); + + if ((square1 != square2) || (square1 && !fmpz_poly_equal(a, b))) + { + flint_printf("FAIL: aliasing:\n"); + flint_printf("square1 = %d, square2 = %d\n\n", square1, square2); + flint_printf("a: "); fmpz_poly_print(a); flint_printf("\n\n"); + flint_printf("b: "); fmpz_poly_print(b); flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + } + + /* Test random squares */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + int square; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + + fmpz_poly_randtest(a, state, 1 + n_randint(state, 20), + 1 + n_randint(state, 200)); + fmpz_poly_sqr(b, a); + square = fmpz_poly_sqrt(c, b); + + if (!square) + { + flint_printf("FAIL: square reported nonsquare:\n"); + flint_printf("a: "); fmpz_poly_print(a); flint_printf("\n\n"); + flint_printf("b: "); fmpz_poly_print(b); flint_printf("\n\n"); + flint_printf("c: "); fmpz_poly_print(c); flint_printf("\n\n"); + abort(); + } + + if (!fmpz_poly_is_zero(c) && + fmpz_sgn(fmpz_poly_get_coeff_ptr(c, fmpz_poly_degree(c))) < 0) + { + flint_printf("FAIL: leading coefficient not positive:\n"); + flint_printf("a: "); fmpz_poly_print(a); flint_printf("\n\n"); + flint_printf("b: "); fmpz_poly_print(b); flint_printf("\n\n"); + flint_printf("c: "); fmpz_poly_print(c); flint_printf("\n\n"); + abort(); + } + + fmpz_poly_sqr(c, c); + if (!fmpz_poly_equal(c, b)) + { + flint_printf("FAIL: sqrt(b)^2 != b:\n"); + flint_printf("a: "); fmpz_poly_print(a); flint_printf("\n\n"); + flint_printf("b: "); fmpz_poly_print(b); flint_printf("\n\n"); + flint_printf("c: "); fmpz_poly_print(c); flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + /* Test "almost" squares */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + fmpz_t t; + slong j; + int square; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_init(t); + + fmpz_poly_randtest_not_zero(a, state, 1 + n_randint(state, 20), + 1 + n_randint(state, 200)); + fmpz_poly_sqr(b, a); + + j = n_randint(state, fmpz_poly_length(b)); + fmpz_randtest_not_zero(t, state, 1 + n_randint(state, 100)); + fmpz_add(b->coeffs + j, b->coeffs + j, t); + _fmpz_poly_normalise(b); + + square = fmpz_poly_sqrt(c, b); + + if (square) + { + fmpz_poly_sqr(c, c); + if (!fmpz_poly_equal(c, b)) + { + flint_printf("FAIL: sqrt(b)^2 != b:\n"); + flint_printf("a: "); fmpz_poly_print(a); flint_printf("\n\n"); + flint_printf("b: "); fmpz_poly_print(b); flint_printf("\n\n"); + flint_printf("c: "); fmpz_poly_print(c); flint_printf("\n\n"); + abort(); + } + } + + fmpz_clear(t); + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + + flint_printf("PASS\n"); + FLINT_TEST_CLEANUP(state); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-sub.c b/external/flint-2.4.3/fmpz_poly/test/t-sub.c new file mode 100644 index 0000000..f5bf641 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-sub.c @@ -0,0 +1,140 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("sub...."); + fflush(stdout); + + + + /* Check a - b = a + neg(b) */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c, d; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_init(d); + fmpz_poly_randtest(a, state, n_randint(state, 100), 200); + fmpz_poly_randtest(b, state, n_randint(state, 100), 200); + + fmpz_poly_sub(c, a, b); + fmpz_poly_neg(b, b); + fmpz_poly_add(d, a, b); + + result = (fmpz_poly_equal(d, d)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + fmpz_poly_print(c), flint_printf("\n\n"); + fmpz_poly_print(d), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + fmpz_poly_clear(d); + } + + /* Check aliasing of a and c */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(a, state, n_randint(state, 100), 200); + fmpz_poly_randtest(b, state, n_randint(state, 100), 200); + + fmpz_poly_sub(c, a, b); + fmpz_poly_sub(a, a, b); + + result = (fmpz_poly_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + fmpz_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + /* Check aliasing of b and c */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(a, state, n_randint(state, 100), 200); + fmpz_poly_randtest(b, state, n_randint(state, 100), 200); + + fmpz_poly_sub(c, a, b); + fmpz_poly_sub(b, a, b); + + result = (fmpz_poly_equal(b, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + fmpz_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-swap.c b/external/flint-2.4.3/fmpz_poly/test/t-swap.c new file mode 100644 index 0000000..800954d --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-swap.c @@ -0,0 +1,77 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("swap...."); + fflush(stdout); + + + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t a, b, c; + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(c); + fmpz_poly_randtest(a, state, n_randint(state, 100), 200); + fmpz_poly_randtest(b, state, n_randint(state, 100), 200); + + fmpz_poly_set(c, b); + fmpz_poly_swap(a, b); + + result = (fmpz_poly_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + fmpz_poly_print(b), flint_printf("\n\n"); + fmpz_poly_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-taylor_shift.c b/external/flint-2.4.3/fmpz_poly/test/t-taylor_shift.c new file mode 100644 index 0000000..658feb0 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-taylor_shift.c @@ -0,0 +1,121 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + flint_printf("taylor_shift...."); + fflush(stdout); + + + + /* Check aliasing */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t f, g; + fmpz_t c; + + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_init(c); + + fmpz_poly_randtest(f, state, 1 + n_randint(state, 20), + 1 + n_randint(state, 200)); + + fmpz_randtest(c, state, n_randint(state, 200)); + + fmpz_poly_taylor_shift(g, f, c); + fmpz_poly_taylor_shift(f, f, c); + + if (!fmpz_poly_equal(g, f)) + { + flint_printf("FAIL\n"); + fmpz_poly_print(f); flint_printf("\n"); + fmpz_poly_print(g); flint_printf("\n"); + abort(); + } + + fmpz_poly_clear(f); + fmpz_poly_clear(g); + fmpz_clear(c); + } + + /* Compare with composition */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t f, g, h1, h2; + fmpz_t c; + + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_poly_init(h1); + fmpz_poly_init(h2); + + fmpz_init(c); + + fmpz_poly_randtest(f, state, 1 + n_randint(state, 20), + 1 + n_randint(state, 200)); + + fmpz_randtest(c, state, n_randint(state, 200)); + + fmpz_poly_set_coeff_ui(g, 1, 1); + fmpz_poly_set_coeff_fmpz(g, 0, c); + + fmpz_poly_taylor_shift(h1, f, c); + fmpz_poly_compose(h2, f, g); + + if (!fmpz_poly_equal(h1, h2)) + { + flint_printf("FAIL\n"); + fmpz_poly_print(f); flint_printf("\n"); + fmpz_poly_print(g); flint_printf("\n"); + fmpz_poly_print(h1); flint_printf("\n"); + fmpz_poly_print(h2); flint_printf("\n"); + abort(); + } + + fmpz_poly_clear(f); + fmpz_poly_clear(g); + fmpz_poly_clear(h1); + fmpz_poly_clear(h2); + fmpz_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-taylor_shift_divconquer.c b/external/flint-2.4.3/fmpz_poly/test/t-taylor_shift_divconquer.c new file mode 100644 index 0000000..d272e65 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-taylor_shift_divconquer.c @@ -0,0 +1,121 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + flint_printf("taylor_shift_divconquer...."); + fflush(stdout); + + + + /* Check aliasing */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t f, g; + fmpz_t c; + + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_init(c); + + fmpz_poly_randtest(f, state, 1 + n_randint(state, 20), + 1 + n_randint(state, 200)); + + fmpz_randtest(c, state, n_randint(state, 200)); + + fmpz_poly_taylor_shift_divconquer(g, f, c); + fmpz_poly_taylor_shift_divconquer(f, f, c); + + if (!fmpz_poly_equal(g, f)) + { + flint_printf("FAIL\n"); + fmpz_poly_print(f); flint_printf("\n"); + fmpz_poly_print(g); flint_printf("\n"); + abort(); + } + + fmpz_poly_clear(f); + fmpz_poly_clear(g); + fmpz_clear(c); + } + + /* Compare with composition */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t f, g, h1, h2; + fmpz_t c; + + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_poly_init(h1); + fmpz_poly_init(h2); + + fmpz_init(c); + + fmpz_poly_randtest(f, state, 1 + n_randint(state, 20), + 1 + n_randint(state, 200)); + + fmpz_randtest(c, state, n_randint(state, 200)); + + fmpz_poly_set_coeff_ui(g, 1, 1); + fmpz_poly_set_coeff_fmpz(g, 0, c); + + fmpz_poly_taylor_shift_divconquer(h1, f, c); + fmpz_poly_compose(h2, f, g); + + if (!fmpz_poly_equal(h1, h2)) + { + flint_printf("FAIL\n"); + fmpz_poly_print(f); flint_printf("\n"); + fmpz_poly_print(g); flint_printf("\n"); + fmpz_poly_print(h1); flint_printf("\n"); + fmpz_poly_print(h2); flint_printf("\n"); + abort(); + } + + fmpz_poly_clear(f); + fmpz_poly_clear(g); + fmpz_poly_clear(h1); + fmpz_poly_clear(h2); + fmpz_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-taylor_shift_horner.c b/external/flint-2.4.3/fmpz_poly/test/t-taylor_shift_horner.c new file mode 100644 index 0000000..8bb8f36 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-taylor_shift_horner.c @@ -0,0 +1,121 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + flint_printf("taylor_shift_horner...."); + fflush(stdout); + + + + /* Check aliasing */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t f, g; + fmpz_t c; + + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_init(c); + + fmpz_poly_randtest(f, state, 1 + n_randint(state, 20), + 1 + n_randint(state, 200)); + + fmpz_randtest(c, state, n_randint(state, 200)); + + fmpz_poly_taylor_shift_horner(g, f, c); + fmpz_poly_taylor_shift_horner(f, f, c); + + if (!fmpz_poly_equal(g, f)) + { + flint_printf("FAIL\n"); + fmpz_poly_print(f); flint_printf("\n"); + fmpz_poly_print(g); flint_printf("\n"); + abort(); + } + + fmpz_poly_clear(f); + fmpz_poly_clear(g); + fmpz_clear(c); + } + + /* Compare with composition */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_t f, g, h1, h2; + fmpz_t c; + + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_poly_init(h1); + fmpz_poly_init(h2); + + fmpz_init(c); + + fmpz_poly_randtest(f, state, 1 + n_randint(state, 20), + 1 + n_randint(state, 200)); + + fmpz_randtest(c, state, n_randint(state, 200)); + + fmpz_poly_set_coeff_ui(g, 1, 1); + fmpz_poly_set_coeff_fmpz(g, 0, c); + + fmpz_poly_taylor_shift_horner(h1, f, c); + fmpz_poly_compose(h2, f, g); + + if (!fmpz_poly_equal(h1, h2)) + { + flint_printf("FAIL\n"); + fmpz_poly_print(f); flint_printf("\n"); + fmpz_poly_print(g); flint_printf("\n"); + fmpz_poly_print(h1); flint_printf("\n"); + fmpz_poly_print(h2); flint_printf("\n"); + abort(); + } + + fmpz_poly_clear(f); + fmpz_poly_clear(g); + fmpz_poly_clear(h1); + fmpz_poly_clear(h2); + fmpz_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-xgcd_modular.c b/external/flint-2.4.3/fmpz_poly/test/t-xgcd_modular.c new file mode 100644 index 0000000..dcc6dfc --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-xgcd_modular.c @@ -0,0 +1,308 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("xgcd_modular...."); + fflush(stdout); + + + + /* Check s*f + t*g == r */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpz_poly_t d, f, g, s, t; + fmpz_t r; + + fmpz_poly_init(d); + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_poly_init(s); + fmpz_poly_init(t); + fmpz_init(r); + + do { + fmpz_poly_randtest(f, state, n_randint(state, 50), 150); + fmpz_poly_randtest(g, state, n_randint(state, 50), 150); + fmpz_poly_primitive_part(f, f); + fmpz_poly_primitive_part(g, g); + fmpz_poly_gcd_modular(d, f, g); + } while (d->length != 1); + + fmpz_poly_xgcd_modular(r, s, t, f, g); + fmpz_poly_mul(s, s, f); + fmpz_poly_mul(t, t, g); + fmpz_poly_add(s, s, t); + + result = fmpz_poly_equal_fmpz(s, r); + if (!result) + { + flint_printf("FAIL (check s*f + t*g == r):\n"); + flint_printf("f = "), fmpz_poly_print(f), flint_printf("\n"); + flint_printf("g = "), fmpz_poly_print(g), flint_printf("\n"); + flint_printf("s = "), fmpz_poly_print(s); flint_printf("\n"); + flint_printf("t = "), fmpz_poly_print(t); flint_printf("\n"); + flint_printf("d = "), fmpz_poly_print(d); flint_printf("\n"); + flint_printf("r = "), fmpz_print(r); flint_printf("\n"); + abort(); + } + + fmpz_clear(r); + fmpz_poly_clear(d); + fmpz_poly_clear(f); + fmpz_poly_clear(g); + fmpz_poly_clear(s); + fmpz_poly_clear(t); + } + + /* Check s*f + t*g == r with smaller polynomials */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpz_poly_t d, f, g, s, t; + fmpz_t r; + + fmpz_poly_init(d); + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_poly_init(s); + fmpz_poly_init(t); + fmpz_init(r); + + do { + fmpz_poly_randtest(f, state, n_randint(state, 30), 50); + fmpz_poly_randtest(g, state, n_randint(state, 30), 50); + fmpz_poly_primitive_part(f, f); + fmpz_poly_primitive_part(g, g); + fmpz_poly_gcd_modular(d, f, g); + } while (d->length != 1); + + fmpz_poly_xgcd_modular(r, s, t, f, g); + fmpz_poly_mul(s, s, f); + fmpz_poly_mul(t, t, g); + fmpz_poly_add(s, s, t); + + result = fmpz_poly_equal_fmpz(s, r); + if (!result) + { + flint_printf("FAIL (check small s*f + t*g == r):\n"); + flint_printf("f = "), fmpz_poly_print(f), flint_printf("\n"); + flint_printf("g = "), fmpz_poly_print(g), flint_printf("\n"); + flint_printf("s = "), fmpz_poly_print(s); flint_printf("\n"); + flint_printf("t = "), fmpz_poly_print(t); flint_printf("\n"); + flint_printf("d = "), fmpz_poly_print(d); flint_printf("\n"); + flint_printf("r = "), fmpz_print(r); flint_printf("\n"); + abort(); + } + + fmpz_clear(r); + fmpz_poly_clear(d); + fmpz_poly_clear(f); + fmpz_poly_clear(g); + fmpz_poly_clear(s); + fmpz_poly_clear(t); + } + + /* Check aliasing of s and f */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + fmpz_poly_t d, f, g, s, t; + fmpz_t r; + + fmpz_poly_init(d); + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_poly_init(s); + fmpz_poly_init(t); + fmpz_init(r); + + do { + fmpz_poly_randtest(f, state, n_randint(state, 50), 100); + fmpz_poly_randtest(g, state, n_randint(state, 50), 100); + fmpz_poly_primitive_part(f, f); + fmpz_poly_primitive_part(g, g); + fmpz_poly_gcd_modular(d, f, g); + } while (d->length != 1); + + fmpz_poly_xgcd_modular(r, s, t, f, g); + fmpz_poly_xgcd_modular(r, f, t, f, g); + + result = (fmpz_poly_equal(s, f) || fmpz_is_zero(r)); + if (!result) + { + flint_printf("FAIL (alias s and f):\n"); + flint_printf("f = "), fmpz_poly_print(f), flint_printf("\n"); + flint_printf("s = "), fmpz_poly_print(s); flint_printf("\n"); + abort(); + } + + fmpz_clear(r); + fmpz_poly_clear(d); + fmpz_poly_clear(f); + fmpz_poly_clear(g); + fmpz_poly_clear(s); + fmpz_poly_clear(t); + } + + /* Check aliasing of s and g */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + fmpz_poly_t d, f, g, s, t; + fmpz_t r; + + fmpz_poly_init(d); + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_poly_init(s); + fmpz_poly_init(t); + fmpz_init(r); + + do { + fmpz_poly_randtest(f, state, n_randint(state, 50), 100); + fmpz_poly_randtest(g, state, n_randint(state, 50), 100); + fmpz_poly_primitive_part(f, f); + fmpz_poly_primitive_part(g, g); + fmpz_poly_gcd_modular(d, f, g); + } while (d->length != 1); + + fmpz_poly_xgcd_modular(r, s, t, f, g); + fmpz_poly_xgcd_modular(r, g, t, f, g); + + result = (fmpz_poly_equal(s, g) || fmpz_is_zero(r)); + if (!result) + { + flint_printf("FAIL (alias s and g):\n"); + flint_printf("g = "), fmpz_poly_print(g), flint_printf("\n"); + flint_printf("s = "), fmpz_poly_print(s); flint_printf("\n"); + abort(); + } + + fmpz_clear(r); + fmpz_poly_clear(d); + fmpz_poly_clear(f); + fmpz_poly_clear(g); + fmpz_poly_clear(s); + fmpz_poly_clear(t); + } + + /* Check aliasing of t and f */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + fmpz_poly_t d, f, g, s, t; + fmpz_t r; + + fmpz_poly_init(d); + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_poly_init(s); + fmpz_poly_init(t); + fmpz_init(r); + + do { + fmpz_poly_randtest(f, state, n_randint(state, 50), 100); + fmpz_poly_randtest(g, state, n_randint(state, 50), 100); + fmpz_poly_primitive_part(f, f); + fmpz_poly_primitive_part(g, g); + fmpz_poly_gcd_modular(d, f, g); + } while (d->length != 1); + + fmpz_poly_xgcd_modular(r, s, t, f, g); + fmpz_poly_xgcd_modular(r, s, f, f, g); + + result = (fmpz_poly_equal(t, f) || fmpz_is_zero(r)); + if (!result) + { + flint_printf("FAIL (alias t and f):\n"); + flint_printf("f = "), fmpz_poly_print(f), flint_printf("\n"); + flint_printf("t = "), fmpz_poly_print(t); flint_printf("\n"); + abort(); + } + + fmpz_clear(r); + fmpz_poly_clear(d); + fmpz_poly_clear(f); + fmpz_poly_clear(g); + fmpz_poly_clear(s); + fmpz_poly_clear(t); + } + + /* Check aliasing of t and g */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + fmpz_poly_t d, f, g, s, t; + fmpz_t r; + + fmpz_poly_init(d); + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_poly_init(s); + fmpz_poly_init(t); + fmpz_init(r); + + do { + fmpz_poly_randtest(f, state, n_randint(state, 50), 100); + fmpz_poly_randtest(g, state, n_randint(state, 50), 100); + fmpz_poly_primitive_part(f, f); + fmpz_poly_primitive_part(g, g); + fmpz_poly_gcd_modular(d, f, g); + } while (d->length != 1); + + fmpz_poly_xgcd_modular(r, s, t, f, g); + fmpz_poly_xgcd_modular(r, s, g, f, g); + + result = (fmpz_poly_equal(t, g) || fmpz_is_zero(r)); + if (!result) + { + flint_printf("FAIL (alias t and g):\n"); + flint_printf("f = "), fmpz_poly_print(g), flint_printf("\n"); + flint_printf("t = "), fmpz_poly_print(t); flint_printf("\n"); + abort(); + } + + fmpz_clear(r); + fmpz_poly_clear(d); + fmpz_poly_clear(f); + fmpz_poly_clear(g); + fmpz_poly_clear(s); + fmpz_poly_clear(t); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-zero.c b/external/flint-2.4.3/fmpz_poly/test/t-zero.c new file mode 100644 index 0000000..9524cfd --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-zero.c @@ -0,0 +1,69 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("zero...."); + fflush(stdout); + + + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t a; + + fmpz_poly_init(a); + fmpz_poly_randtest(a, state, n_randint(state, 100), 100); + fmpz_poly_zero(a); + + result = (fmpz_poly_is_zero(a)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpz_poly_print(a), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/test/t-zero_coeffs.c b/external/flint-2.4.3/fmpz_poly/test/t-zero_coeffs.c new file mode 100644 index 0000000..056f209 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/test/t-zero_coeffs.c @@ -0,0 +1,74 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("zero_coeffs...."); + fflush(stdout); + + + + /* Check that zeroing [0,len/2) and [len/2,len) sets a to zero */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_t a; + slong len; + + fmpz_poly_init(a); + fmpz_poly_randtest(a, state, n_randint(state, 100), 200); + len = a->length; + + fmpz_poly_zero_coeffs(a, -23, len/2); + fmpz_poly_zero_coeffs(a, len/2, len + 42); + + result = (fmpz_poly_length(a) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_print(a), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(a); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly/xgcd_modular.c b/external/flint-2.4.3/fmpz_poly/xgcd_modular.c new file mode 100644 index 0000000..5e6ce0a --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/xgcd_modular.c @@ -0,0 +1,240 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" +#include "mpn_extras.h" + +void _fmpz_poly_xgcd_modular(fmpz_t r, fmpz * s, fmpz * t, + const fmpz * poly1, slong len1, + const fmpz * poly2, slong len2) +{ + mp_ptr G, S, T, A, B, T1, T2; + fmpz_t prod; + int stabilised = 0, first; + mp_limb_t p; + mp_bitcnt_t s_bits = 0, t_bits = 0; + + /* Compute resultant of input polys */ + _fmpz_poly_resultant(r, poly1, len1, poly2, len2); + + if (fmpz_is_zero(r)) + return; + + fmpz_init(prod); + fmpz_one(prod); + + _fmpz_vec_zero(s, len2); + _fmpz_vec_zero(t, len1); + + p = (UWORD(1) << (FLINT_BITS - 1)); + + G = _nmod_vec_init(4 * len1 + 5 * len2 - 2); + S = G + len2; + T = S + len2; + A = T + len1; + B = A + len1; + T1 = B + len2; + T2 = T1 + (len1 + len2 - 1); + + _nmod_vec_zero(S, len2 + len1); /* S = T = 0 */ + + first = 1; + + for (;;) + { + mp_limb_t R; + nmod_t mod; + + /* Get next prime */ + p = n_nextprime(p, 0); + + /* Resultant mod p */ + R = fmpz_fdiv_ui(r, p); + + /* If p divides resultant or either leading coeff, discard p */ + if ((fmpz_fdiv_ui(poly1 + len1 - 1, p) == WORD(0)) || + (fmpz_fdiv_ui(poly2 + len2 - 1, p) == WORD(0)) || (R == 0)) + continue; + + nmod_init(&mod, p); + + /* Reduce polynomials modulo p */ + _fmpz_vec_get_nmod_vec(A, poly1, len1, mod); + _fmpz_vec_get_nmod_vec(B, poly2, len2, mod); + + if (stabilised) /* CRT has stabilised, probably don't need more xgcds */ + { + slong tlen; + + /* Multiply out A*S + B*T to see if it is R mod p */ + _fmpz_vec_get_nmod_vec(S, s, len2, mod); + _fmpz_vec_get_nmod_vec(T, t, len1, mod); + + _nmod_poly_mul(T1, A, len1, S, len2, mod); + _nmod_poly_mul(T2, T, len1, B, len2, mod); + _nmod_vec_add(T1, T1, T2, len1 + len2 - 1, mod); + tlen = len1 + len2 - 1; + FMPZ_VEC_NORM(T1, tlen); + + if (tlen == 1 && T1[0] == R) /* It is, so this prime is good */ + fmpz_mul_ui(prod, prod, p); + else + stabilised = 0; /* It's not, keep going with xgcds */ + } + + if (!stabilised) /* Need to keep computing xgcds mod p */ + { + mp_limb_t RGinv; + + /* Compute xgcd mod p */ + _nmod_poly_xgcd(G, S, T, A, len1, B, len2, mod); + RGinv = n_invmod(G[0], mod.n); + RGinv = n_mulmod2_preinv(RGinv, R, mod.n, mod.ninv); + + /* Scale appropriately */ + _nmod_vec_scalar_mul_nmod(S, S, len2, RGinv, mod); + _nmod_vec_scalar_mul_nmod(T, T, len1, RGinv, mod); + + if (first) /* First time around set s and t to S and T */ + { + _fmpz_vec_set_nmod_vec(s, S, len2, mod); + _fmpz_vec_set_nmod_vec(t, T, len1, mod); + fmpz_set_ui(prod, p); + + stabilised = 1; /* Optimise the case where one prime is enough */ + first = 0; + } + else /* Otherwise do CRT */ + { + mp_bitcnt_t new_s_bits, new_t_bits; + + _fmpz_poly_CRT_ui(s, s, len2, prod, S, len2, mod.n, mod.ninv, 1); + _fmpz_poly_CRT_ui(t, t, len1, prod, T, len1, mod.n, mod.ninv, 1); + fmpz_mul_ui(prod, prod, p); + + /* Check to see if CRT has stabilised */ + new_s_bits = FLINT_ABS(_fmpz_vec_max_bits(s, len2)); + new_t_bits = FLINT_ABS(_fmpz_vec_max_bits(t, len1)); + + stabilised = (s_bits == new_s_bits && t_bits == new_t_bits); + + s_bits = new_s_bits; + t_bits = new_t_bits; + } + } + + if (stabilised) + { + slong bound1, bound2, bound; + + bound1 = FLINT_BIT_COUNT(len2) + + FLINT_ABS(_fmpz_vec_max_bits(poly1, len1)) + + FLINT_ABS(_fmpz_vec_max_bits(s, len2)); + bound2 = FLINT_BIT_COUNT(len2) + + FLINT_ABS(_fmpz_vec_max_bits(poly2, len2)) + + FLINT_ABS(_fmpz_vec_max_bits(t, len1)); + + bound = 4 + FLINT_MAX(fmpz_bits(r), FLINT_MAX(bound1, bound2)); + + if (fmpz_bits(prod) > bound) + break; + } + } + + _nmod_vec_clear(G); + fmpz_clear(prod); +} + +void +fmpz_poly_xgcd_modular(fmpz_t r, fmpz_poly_t s, fmpz_poly_t t, + const fmpz_poly_t poly1, const fmpz_poly_t poly2) +{ + if (poly1->length < poly2->length) + { + fmpz_poly_xgcd_modular(r, t, s, poly2, poly1); + } else /* len1 >= len2 >= 0 */ + { + const slong len1 = poly1->length; + const slong len2 = poly2->length; + fmpz *S, *T; + fmpz_poly_t temp1, temp2; + + if (len1 == 0 || len2 == 0) + { + fmpz_zero(r); + } + else /* len1 >= len2 >= 1 */ + { + if (s == poly1 || s == poly2) + { + fmpz_poly_init2(temp1, len2); + S = temp1->coeffs; + } + else + { + fmpz_poly_fit_length(s, len2); + S = s->coeffs; + } + + if (t == poly1 || t == poly2) + { + fmpz_poly_init2(temp2, len1); + T = temp2->coeffs; + } + else + { + fmpz_poly_fit_length(t, len1); + T = t->coeffs; + } + + _fmpz_poly_xgcd_modular(r, S, T, poly1->coeffs, len1, + poly2->coeffs, len2); + + if (s == poly1 || s == poly2) + { + fmpz_poly_swap(s, temp1); + fmpz_poly_clear(temp1); + } + + if (t == poly1 || t == poly2) + { + fmpz_poly_swap(t, temp2); + fmpz_poly_clear(temp2); + } + + _fmpz_poly_set_length(s, len2); + _fmpz_poly_normalise(s); + + _fmpz_poly_set_length(t, len1); + _fmpz_poly_normalise(t); + } + } +} + diff --git a/external/flint-2.4.3/fmpz_poly/zero_coeffs.c b/external/flint-2.4.3/fmpz_poly/zero_coeffs.c new file mode 100644 index 0000000..5ef8a0a --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly/zero_coeffs.c @@ -0,0 +1,46 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +void +fmpz_poly_zero_coeffs(fmpz_poly_t poly, slong i, slong j) +{ + if (i < 0) + i = 0; + if (j > poly->length) + j = poly->length; + + _fmpz_vec_zero(poly->coeffs + i, j - i); + + if (j == poly->length) + { + _fmpz_poly_set_length(poly, i); + _fmpz_poly_normalise(poly); + } +} diff --git a/external/flint-2.4.3/fmpz_poly_factor.h b/external/flint-2.4.3/fmpz_poly_factor.h new file mode 100644 index 0000000..024aaf8 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_factor.h @@ -0,0 +1,83 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2006, 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2009, 2011 Andy Novocin + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#ifndef FMPZ_POLY_FACTOR_H +#define FMPZ_POLY_FACTOR_H + +#undef ulong +#define ulong ulongxx /* interferes with system includes */ +#include +#undef ulong +#include +#define ulong mp_limb_t + +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "nmod_poly.h" + +#ifdef __cplusplus + extern "C" { +#endif + +void fmpz_poly_factor_init(fmpz_poly_factor_t fac); + +void fmpz_poly_factor_init2(fmpz_poly_factor_t fac, slong alloc); + +void fmpz_poly_factor_realloc(fmpz_poly_factor_t fac, slong alloc); + +void fmpz_poly_factor_fit_length(fmpz_poly_factor_t fac, slong len); + +void fmpz_poly_factor_clear(fmpz_poly_factor_t fac); + +void fmpz_poly_factor_set(fmpz_poly_factor_t res, const fmpz_poly_factor_t fac); + +void fmpz_poly_factor_insert(fmpz_poly_factor_t fac, + const fmpz_poly_t p, slong exp); + +void fmpz_poly_factor_concat(fmpz_poly_factor_t res, + const fmpz_poly_factor_t fac); + +void fmpz_poly_factor_print(const fmpz_poly_factor_t fac); + +void fmpz_poly_factor_zassenhaus_recombination(fmpz_poly_factor_t final_fac, + const fmpz_poly_factor_t lifted_fac, + const fmpz_poly_t F, const fmpz_t P, slong exp); + +void fmpz_poly_factor_squarefree(fmpz_poly_factor_t fac, const fmpz_poly_t F); + +void _fmpz_poly_factor_zassenhaus(fmpz_poly_factor_t final_fac, + slong exp, const fmpz_poly_t f, slong cutoff); + +void fmpz_poly_factor_zassenhaus(fmpz_poly_factor_t fac, const fmpz_poly_t G); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/external/flint-2.4.3/fmpz_poly_factor/clear.c b/external/flint-2.4.3/fmpz_poly_factor/clear.c new file mode 100644 index 0000000..5121a6e --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_factor/clear.c @@ -0,0 +1,50 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +void fmpz_poly_factor_clear(fmpz_poly_factor_t fac) +{ + if (fac->alloc) + { + slong i; + + for (i = 0; i < fac->alloc; i++) + { + fmpz_poly_clear(fac->p + i); + } + + fmpz_clear(&(fac->c)); + flint_free(fac->p); + flint_free(fac->exp); + fac->p = NULL; + fac->exp = NULL; + } +} + diff --git a/external/flint-2.4.3/fmpz_poly_factor/concat.c b/external/flint-2.4.3/fmpz_poly_factor/concat.c new file mode 100644 index 0000000..d6f375e --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_factor/concat.c @@ -0,0 +1,43 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz_poly.h" + +void +fmpz_poly_factor_concat(fmpz_poly_factor_t res, const fmpz_poly_factor_t fac) +{ + slong i; + + fmpz_mul(&(res->c), &(res->c), &(fac->c)); + + for (i = 0; i < fac->num; i++) + fmpz_poly_factor_insert(res, fac->p + i, fac->exp[i]); +} diff --git a/external/flint-2.4.3/fmpz_poly_factor/doc/fmpz_poly_factor.txt b/external/flint-2.4.3/fmpz_poly_factor/doc/fmpz_poly_factor.txt new file mode 100644 index 0000000..42e1c64 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_factor/doc/fmpz_poly_factor.txt @@ -0,0 +1,151 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Andy Novocin + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +******************************************************************************* + + Memory management + +******************************************************************************* + +void fmpz_poly_factor_init(fmpz_poly_factor_t fac) + + Initialises a new factor structure. + +void fmpz_poly_factor_init2(fmpz_poly_factor_t fac, slong alloc) + + Initialises a new factor structure, providing space for + at least \code{alloc} factors. + +void fmpz_poly_factor_realloc(fmpz_poly_factor_t fac, slong alloc) + + Reallocates the factor structure to provide space for + precisely \code{alloc} factors. + +void fmpz_poly_factor_fit_length(fmpz_poly_factor_t fac, slong len) + + Ensures that the factor structure has space for at + least \code{len} factors. This functions takes care + of the case of repeated calls by always at least + doubling the number of factors the structure can hold. + +void fmpz_poly_factor_clear(fmpz_poly_factor_t fac) + + Releases all memory occupied by the factor structure. + +******************************************************************************* + + Manipulating factors + +******************************************************************************* + +void fmpz_poly_factor_set(fmpz_poly_factor_t res, const fmpz_poly_factor_t fac) + + Sets \code{res} to the same factorisation as \code{fac}. + +void fmpz_poly_factor_insert(fmpz_poly_factor_t fac, + const fmpz_poly_t p, slong e) + + Adds the primitive polynomial $p^e$ to the factorisation \code{fac}. + + Assumes that $\deg(p) \geq 2$ and $e \neq 0$. + +void fmpz_poly_factor_concat(fmpz_poly_factor_t res, + const fmpz_poly_factor_t fac) + + Concatenates two factorisations. + + This is equivalent to calling \code{fmpz_poly_factor_insert()} + repeatedly with the individual factors of \code{fac}. + + Does not support aliasing between \code{res} and \code{fac}. + +******************************************************************************* + + Input and output + +******************************************************************************* + +void fmpz_poly_factor_print(const fmpz_poly_factor_t fac) + + Prints the entries of \code{fac} to standard output. + +******************************************************************************* + + Factoring algorithms + +******************************************************************************* + +void fmpz_poly_factor_squarefree(fmpz_poly_factor_t fac, fmpz_poly_t F) + + Takes as input a polynomial $F$ and a freshly initialized factor + structure \code{fac}. Updates \code{fac} to contain a factorization + of $F$ into (not necessarily irreducible) factors that themselves + have no repeated factors. None of the returned factors will have + the same exponent. That is we return $g_i$ and unique $e_i$ such that + \begin{equation*} + F = c \prod_{i} g_i^{e_i} + \end{equation*} + where $c$ is the signed content of $F$ and $\gcd(g_i, g_i') = 1$. + +void fmpz_poly_factor_zassenhaus_recombination(fmpz_poly_factor_t + final_fac, const fmpz_poly_factor_t lifted_fac, + const fmpz_poly_t F, const fmpz_t P, slong exp) + + Takes as input a factor structure \code{lifted_fac} containing a + squarefree factorization of the polynomial $F \bmod p$. The algorithm + does a brute force search for irreducible factors of $F$ over the + integers, and each factor is raised to the power \code{exp}. + + The impact of the algorithm is to augment a factorization of + \code{F^exp} to the factor structure \code{final_fac}. + +void _fmpz_poly_factor_zassenhaus(fmpz_poly_factor_t final_fac, + slong exp, fmpz_poly_t f, slong cutoff) + + This is the internal wrapper of Zassenhaus. + + It will attempt to find a small prime such that $f$ modulo $p$ has + a minimal number of factors. If it cannot find a prime giving less + than \code{cutoff} factors it aborts. Then it decides a $p$-adic + precision to lift the factors to, hensel lifts, and finally calls + Zassenhaus recombination. + + Assumes that $\len(f) \geq 2$. + + Assumes that $f$ is primitive. + + Assumes that the constant coefficient of $f$ is non-zero. Note that + this can be easily achieved by taking out factors of the form $x^k$ + before calling this routine. + +void fmpz_poly_factor_zassenhaus(fmpz_poly_factor_t final_fac, fmpz_poly_t F) + + A wrapper of the Zassenhaus factoring algorithm, which takes as input + any polynomial $F$, and stores a factorization in \code{final_fac}. + + The complexity will be exponential in the number of local factors + we find for the components of a squarefree factorization of $F$. + diff --git a/external/flint-2.4.3/fmpz_poly_factor/factor_squarefree.c b/external/flint-2.4.3/fmpz_poly_factor/factor_squarefree.c new file mode 100644 index 0000000..8defe14 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_factor/factor_squarefree.c @@ -0,0 +1,96 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Andy Novocin + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +void fmpz_poly_factor_squarefree(fmpz_poly_factor_t fac, const fmpz_poly_t F) +{ + fmpz_poly_content(&(fac->c), F); + if (fmpz_sgn(fmpz_poly_lead(F)) < 0) + fmpz_neg(&(fac->c), &(fac->c)); + + if (F->length > 1) + { + fmpz_poly_t f, d, t1; + + fmpz_poly_init(f); + fmpz_poly_init(d); + fmpz_poly_init(t1); + + fmpz_poly_scalar_divexact_fmpz(f, F, &(fac->c)); + + fmpz_poly_derivative(t1, f); + fmpz_poly_gcd(d, f, t1); + + if (d->length == 1) + { + fmpz_poly_factor_insert(fac, f, 1); + } + else + { + fmpz_poly_t v, w, s; + slong i; + + fmpz_poly_init(v); + fmpz_poly_init(w); + fmpz_poly_init(s); + + fmpz_poly_div(v, f, d); + fmpz_poly_div(w, t1, d); + + for (i = 1; ; i++) + { + fmpz_poly_derivative(t1, v); + fmpz_poly_sub(s, w, t1); + + if (s->length == 0) + { + if (v->length > 1) + fmpz_poly_factor_insert(fac, v, i); + break; + } + + fmpz_poly_gcd(d, v, s); + fmpz_poly_div(v, v, d); + fmpz_poly_div(w, s, d); + + if (d->length > 1) + fmpz_poly_factor_insert(fac, d, i); + } + + fmpz_poly_clear(v); + fmpz_poly_clear(w); + fmpz_poly_clear(s); + } + fmpz_poly_clear(f); + fmpz_poly_clear(d); + fmpz_poly_clear(t1); + } +} diff --git a/external/flint-2.4.3/fmpz_poly_factor/factor_zassenhaus.c b/external/flint-2.4.3/fmpz_poly_factor/factor_zassenhaus.c new file mode 100644 index 0000000..cd0367a --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_factor/factor_zassenhaus.c @@ -0,0 +1,290 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Andy Novocin + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "fmpz_poly.h" + +#define TRACE_ZASSENHAUS 0 + +/* + Let $f$ be a polynomial of degree $m = \deg(f) \geq 2$. + If another polynomial $g$ divides $f$ then, for all + $0 \leq j \leq \deg(g)$, + \begin{equation*} + \abs{b_j} \leq \binom{n-1}{j} \abs{f} + \binom{n-1}{j-1} \abs{a_m} + \end{equation*} + where $\abs{f}$ denotes the $2$-norm of $f$. This bound + is due to Mignotte, see e.g., Cohen p.\ 134. + + This function sets $B$ such that, for all $0 \leq j \leq \deg(g)$, + $\abs{b_j} \leq B$. + + Consequently, when proceeding with Hensel lifting, we + proceed to choose an $a$ such that $p^a \geq 2 B + 1$, + e.g., $a = \ceil{\log_p(2B + 1)}$. + + Note that the formula degenerates for $j = 0$ and $j = n$ + and so in this case we use that the leading (resp.\ constant) + term of $g$ divides the leading (resp.\ constant) term of $f$. + */ +static void _fmpz_poly_factor_mignotte(fmpz_t B, const fmpz *f, slong m) +{ + slong j; + fmpz_t b, f2, lc, s, t; + + fmpz_init(b); + fmpz_init(f2); + fmpz_init(lc); + fmpz_init(s); + fmpz_init(t); + + for (j = 0; j <= m; j++) + fmpz_addmul(f2, f + j, f + j); + fmpz_sqrt(f2, f2); + fmpz_add_ui(f2, f2, 1); + + fmpz_abs(lc, f + m); + + fmpz_abs(B, f + 0); + + /* We have $b = \binom{m-1}{j-1}$ on loop entry and + $b = \binom{m-1}{j}$ on exit. */ + fmpz_set_ui(b, m-1); + for (j = 1; j < m; j++) + { + fmpz_mul(t, b, lc); + + fmpz_mul_ui(b, b, m - j); + fmpz_divexact_ui(b, b, j); + + fmpz_mul(s, b, f2); + fmpz_add(s, s, t); + if (fmpz_cmp(B, s) < 0) + fmpz_set(B, s); + } + + if (fmpz_cmp(B, lc) < 0) + fmpz_set(B, lc); + + fmpz_clear(b); + fmpz_clear(f2); + fmpz_clear(lc); + fmpz_clear(s); + fmpz_clear(t); +} + +static void fmpz_poly_factor_mignotte(fmpz_t B, const fmpz_poly_t f) +{ + _fmpz_poly_factor_mignotte(B, f->coeffs, f->length - 1); +} + +void _fmpz_poly_factor_zassenhaus(fmpz_poly_factor_t final_fac, + slong exp, const fmpz_poly_t f, slong cutoff) +{ + const slong lenF = f->length; + + #if TRACE_ZASSENHAUS == 1 + flint_printf("\n[Zassenhaus]\n"); + flint_printf("|f = "), fmpz_poly_print(f), flint_printf("\n"); + #endif + + if (lenF == 2) + { + fmpz_poly_factor_insert(final_fac, f, exp); + } + else + { + slong i; + slong r = lenF; + mp_limb_t p = 2; + nmod_poly_t d, g, t; + nmod_poly_factor_t fac; + + nmod_poly_factor_init(fac); + nmod_poly_init_preinv(t, 1, 0); + nmod_poly_init_preinv(d, 1, 0); + nmod_poly_init_preinv(g, 1, 0); + + for (i = 0; i < 3; i++) + { + for ( ; ; p = n_nextprime(p, 0)) + { + nmod_t mod; + + nmod_init(&mod, p); + d->mod = mod; + g->mod = mod; + t->mod = mod; + + fmpz_poly_get_nmod_poly(t, f); + if (t->length == lenF) + { + nmod_poly_derivative(d, t); + nmod_poly_gcd(g, t, d); + + if (nmod_poly_is_one(g)) + { + nmod_poly_factor_t temp_fac; + + nmod_poly_factor_init(temp_fac); + nmod_poly_factor(temp_fac, t); + + if (temp_fac->num <= r) + { + r = temp_fac->num; + nmod_poly_factor_set(fac, temp_fac); + } + nmod_poly_factor_clear(temp_fac); + break; + } + } + } + p = n_nextprime(p, 0); + } + nmod_poly_clear(d); + nmod_poly_clear(g); + nmod_poly_clear(t); + + if (r > cutoff) + { + flint_printf("Exception (fmpz_poly_factor_zassenhaus). r > cutoff.\n"); + nmod_poly_factor_clear(fac); + abort(); + } + else if (r == 1) + { + fmpz_poly_factor_insert(final_fac, f, exp); + } + else + { + slong a; + fmpz_poly_factor_t lifted_fac; + fmpz_poly_factor_init(lifted_fac); + + p = (fac->p + 0)->mod.n; + { + fmpz_t B; + fmpz_init(B); + fmpz_poly_factor_mignotte(B, f); + fmpz_mul_ui(B, B, 2); + fmpz_add_ui(B, B, 1); + a = fmpz_clog_ui(B, p); + fmpz_clear(B); + } + + /* TODO: Check if use_Hoeij_Novocin and try smaller a. */ + fmpz_poly_hensel_lift_once(lifted_fac, f, fac, a); + + #if TRACE_ZASSENHAUS == 1 + flint_printf("|p = %wd, a = %wd\n", p, a); + flint_printf("|Pre hensel lift factorisation (nmod_poly):\n"); + nmod_poly_factor_print(fac); + flint_printf("|Post hensel lift factorisation (fmpz_poly):\n"); + fmpz_poly_factor_print(lifted_fac); + #endif + + /* Recombination */ + { + fmpz_t P; + fmpz_init(P); + fmpz_set_ui(P, p); + fmpz_pow_ui(P, P, a); + + fmpz_poly_factor_zassenhaus_recombination(final_fac, lifted_fac, f, P, exp); + + fmpz_clear(P); + } + + fmpz_poly_factor_clear(lifted_fac); + } + nmod_poly_factor_clear(fac); + } +} + +void fmpz_poly_factor_zassenhaus(fmpz_poly_factor_t fac, const fmpz_poly_t G) +{ + const slong lenG = G->length; + fmpz_poly_t g; + + if (lenG == 0) + { + fmpz_set_ui(&fac->c, 0); + return; + } + if (lenG == 1) + { + fmpz_set(&fac->c, G->coeffs); + return; + } + + fmpz_poly_init(g); + + if (lenG == 2) + { + fmpz_poly_content(&fac->c, G); + if (fmpz_sgn(fmpz_poly_lead(G)) < 0) + fmpz_neg(&fac->c, &fac->c); + fmpz_poly_scalar_divexact_fmpz(g, G, &fac->c); + fmpz_poly_factor_insert(fac, g, 1); + } + else + { + slong j, k; + fmpz_poly_factor_t sq_fr_fac; + + /* Does a presearch for a factor of form x^k */ + for (k = 0; fmpz_is_zero(G->coeffs + k); k++) ; + + if (k != 0) + { + fmpz_poly_t t; + + fmpz_poly_init(t); + fmpz_poly_set_coeff_ui(t, 1, 1); + fmpz_poly_factor_insert(fac, t, k); + fmpz_poly_clear(t); + } + + fmpz_poly_shift_right(g, G, k); + + /* Could make other tests for x-1 or simple things + maybe take advantage of the composition algorithm */ + fmpz_poly_factor_init(sq_fr_fac); + fmpz_poly_factor_squarefree(sq_fr_fac, g); + + fmpz_set(&fac->c, &sq_fr_fac->c); + + /* Factor each square-free part */ + for (j = 0; j < sq_fr_fac->num; j++) + _fmpz_poly_factor_zassenhaus(fac, sq_fr_fac->exp[j], sq_fr_fac->p + j, 10); + + fmpz_poly_factor_clear(sq_fr_fac); + } + fmpz_poly_clear(g); +} + +#undef TRACE_ZASSENHAUS + diff --git a/external/flint-2.4.3/fmpz_poly_factor/factor_zassenhaus_recombination.c b/external/flint-2.4.3/fmpz_poly_factor/factor_zassenhaus_recombination.c new file mode 100644 index 0000000..07b9e67 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_factor/factor_zassenhaus_recombination.c @@ -0,0 +1,146 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Andy Novocin + Copyright (C) 2011 William Hart + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "fmpz_poly.h" + +#define TRACE 0 + +void fmpz_poly_factor_zassenhaus_recombination(fmpz_poly_factor_t final_fac, + const fmpz_poly_factor_t lifted_fac, + const fmpz_poly_t F, const fmpz_t P, slong exp) +{ + const slong r = lifted_fac->num; + + slong k, *used_arr, *sub_arr; + fmpz_poly_t f, Q, R, tryme; + fmpz *leadF; + + used_arr = flint_calloc(2 * r, sizeof(slong)); + sub_arr = used_arr + r; + + fmpz_poly_init(f); + fmpz_poly_init(Q); + fmpz_poly_init(R); + fmpz_poly_init(tryme); + fmpz_poly_set(f, F); + +#if TRACE == 1 + fmpz_poly_factor_print(lifted_fac); flint_printf(" lifted_fac\n"); +#endif + + leadF = fmpz_poly_lead(F); + + for (k = 1; k < r; k++) + { + slong count = 0, indx = k - 1, l; + + for(l = 0; l < k; l++) + sub_arr[l] = l; + + sub_arr[indx]--; + while ((indx >= 0)) + { + sub_arr[indx] = sub_arr[indx] + 1; + + for (l = indx + 1; l < k; l++) + sub_arr[l] = sub_arr[l - 1] + 1; + + if (sub_arr[k - 1] > r - 1) + indx--; + else + { + for(l = 0; l < k; l++) + { + if (used_arr[sub_arr[l]] == 1) + break; + } + + /* Need to involve leadF, perhaps set coeff 0 to leadF and do + leadF * rest and check if under M_bits... here I'm using a + trial division... */ + fmpz_poly_set_fmpz(tryme, leadF); + + for(l = 0; l < k; l++) + fmpz_poly_mul(tryme, tryme, lifted_fac->p + (sub_arr[l])); + + fmpz_poly_scalar_smod_fmpz(tryme, tryme, P); + fmpz_poly_primitive_part(tryme, tryme); + fmpz_poly_divrem(Q, R, f, tryme); + +#if TRACE == 1 + fmpz_poly_print(tryme); flint_printf(" is tryme\n"); + fmpz_poly_print(R); flint_printf(" is R\n"); +#endif + + if (fmpz_poly_is_zero(R)) + { + fmpz_poly_factor_insert(final_fac, tryme, exp); + + for(l = 0; l < k; l++) + { + used_arr[sub_arr[l]] = 1; + count++; + } + + fmpz_poly_set(f, Q); + leadF = fmpz_poly_lead(f); + /* If r - count = k then the rest are irreducible. + TODO: Add a test for that case */ + } + + indx = k - 1; + } + } + + /* This is where we switch to the next loop for k. So we will have + found all factors using <= k local factors. We should/could update + f to be the rest divided away (or multiply the remaining), could + also adjust r. It is the number of remaining factors so if you + update then test if r = k or k+1 in which case the remaining f is + irreducible. */ + } + + { + slong test = 0; + + for (k = 0; k < r; k++) + test = test + used_arr[k]; + + if (test == 0) + fmpz_poly_factor_insert(final_fac, f, exp); + } + + fmpz_poly_clear(f); + fmpz_poly_clear(tryme); + fmpz_poly_clear(Q); + fmpz_poly_clear(R); + flint_free(used_arr); +} + +#undef TRACE + diff --git a/external/flint-2.4.3/fmpz_poly_factor/fit_length.c b/external/flint-2.4.3/fmpz_poly_factor/fit_length.c new file mode 100644 index 0000000..48e2664 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_factor/fit_length.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2008, 2009 William Hart + +******************************************************************************/ + +#include "fmpz_poly.h" + +void fmpz_poly_factor_fit_length(fmpz_poly_factor_t fac, slong len) +{ + if (len > fac->alloc) + { + /* At least double number of allocated coeffs */ + if (len < 2 * fac->alloc) + len = 2 * fac->alloc; + fmpz_poly_factor_realloc(fac, len); + } +} + diff --git a/external/flint-2.4.3/fmpz_poly_factor/init.c b/external/flint-2.4.3/fmpz_poly_factor/init.c new file mode 100644 index 0000000..3ce6f2e --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_factor/init.c @@ -0,0 +1,67 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +void fmpz_poly_factor_init(fmpz_poly_factor_t fac) +{ + fmpz_init_set_ui(&(fac->c), 1); + fac->p = NULL; + fac->exp = NULL; + fac->num = 0; + fac->alloc = 0; +} + +void fmpz_poly_factor_init2(fmpz_poly_factor_t fac, slong alloc) +{ + fmpz_init_set_ui(&(fac->c), 1); + + if (alloc) + { + slong i; + + fac->p = flint_malloc(alloc * sizeof(fmpz_poly_struct)); + fac->exp = flint_malloc(alloc * sizeof(slong)); + + for (i = 0; i < alloc; i++) + { + fmpz_poly_init(fac->p + i); + fac->exp[i] = WORD(0); + } + } + else + { + fac->p = NULL; + fac->exp = NULL; + } + + fac->num = 0; + fac->alloc = alloc; +} + diff --git a/external/flint-2.4.3/fmpz_poly_factor/insert.c b/external/flint-2.4.3/fmpz_poly_factor/insert.c new file mode 100644 index 0000000..28d9a95 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_factor/insert.c @@ -0,0 +1,54 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz_poly.h" + +void +fmpz_poly_factor_insert(fmpz_poly_factor_t fac, const fmpz_poly_t p, slong exp) +{ + slong i; + + for (i = 0; i < fac->num; i++) + { + if (fmpz_poly_equal(p, fac->p + i)) + { + fac->exp[i] += exp; + return; + } + } + + fmpz_poly_factor_fit_length(fac, i + 1); + + fmpz_poly_set(fac->p + i, p); + fac->exp[i] = exp; + fac->num = i + 1; +} diff --git a/external/flint-2.4.3/fmpz_poly_factor/print.c b/external/flint-2.4.3/fmpz_poly_factor/print.c new file mode 100644 index 0000000..89746ce --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_factor/print.c @@ -0,0 +1,45 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz_poly.h" + +void fmpz_poly_factor_print(const fmpz_poly_factor_t fac) +{ + slong i; + + fmpz_print(&(fac->c)); + flint_printf("\n"); + for (i = 0; i < fac->num; i++) + { + fmpz_poly_print(fac->p + i); + flint_printf(" ^ %wd\n", fac->exp[i]); + } +} diff --git a/external/flint-2.4.3/fmpz_poly_factor/realloc.c b/external/flint-2.4.3/fmpz_poly_factor/realloc.c new file mode 100644 index 0000000..16babcc --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_factor/realloc.c @@ -0,0 +1,80 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +void fmpz_poly_factor_realloc(fmpz_poly_factor_t fac, slong alloc) +{ + if (alloc == 0) /* Clear up, reinitialise */ + { + fmpz_poly_factor_clear(fac); + fmpz_poly_factor_init(fac); + } + else if (fac->alloc) /* Realloc */ + { + if (fac->alloc > alloc) + { + slong i; + + for (i = alloc; i < fac->num; i++) + fmpz_poly_clear(fac->p + i); + + fac->p = flint_realloc(fac->p, alloc * sizeof(fmpz_poly_struct)); + fac->exp = flint_realloc(fac->exp, alloc * sizeof(slong)); + fac->alloc = alloc; + } + else if (fac->alloc < alloc) + { + slong i; + + fac->p = flint_realloc(fac->p, alloc * sizeof(fmpz_poly_struct)); + fac->exp = flint_realloc(fac->exp, alloc * sizeof(slong)); + + for (i = fac->alloc; i < alloc; i++) + { + fmpz_poly_init(fac->p + i); + fac->exp[i] = WORD(0); + } + fac->alloc = alloc; + } + } + else /* Nothing allocated already so do it now */ + { + slong i; + + fac->p = flint_malloc(alloc * sizeof(fmpz_poly_struct)); + fac->exp = flint_calloc(alloc, sizeof(slong)); + + for (i = 0; i < alloc; i++) + fmpz_poly_init(fac->p + i); + fac->num = 0; + fac->alloc = alloc; + } +} + diff --git a/external/flint-2.4.3/fmpz_poly_factor/set.c b/external/flint-2.4.3/fmpz_poly_factor/set.c new file mode 100644 index 0000000..c887baa --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_factor/set.c @@ -0,0 +1,58 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "flint.h" +#include "fmpz_poly.h" + +void fmpz_poly_factor_set(fmpz_poly_factor_t res, const fmpz_poly_factor_t fac) +{ + if (res != fac) + { + if (fac->num == 0) + { + fmpz_poly_factor_clear(res); + fmpz_poly_factor_init(res); + } + else + { + slong i; + + fmpz_poly_factor_fit_length(res, fac->num); + fmpz_set(&(res->c), &(fac->c)); + for (i = 0; i < fac->num; i++) + { + fmpz_poly_set(res->p + i, fac->p + i); + res->exp[i] = fac->exp[i]; + } + for ( ; i < res->num; i++) + { + fmpz_poly_zero(res->p + i); + res->exp[i] = 0; + } + res->num = fac->num; + } + } +} + diff --git a/external/flint-2.4.3/fmpz_poly_factor/test/t-factor_squarefree.c b/external/flint-2.4.3/fmpz_poly_factor/test/t-factor_squarefree.c new file mode 100644 index 0000000..5887f3d --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_factor/test/t-factor_squarefree.c @@ -0,0 +1,114 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +int main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("squarefree...."); + fflush(stdout); + + + + for (i = 0; i < 1000; i++) + { + fmpz_poly_t f, g[10], h, t; + fmpz_poly_factor_t fac; + slong k, l, n = n_randint(state, 10) + 1; + + fmpz_poly_init(f); + fmpz_poly_init(h); + fmpz_poly_init(t); + fmpz_poly_factor_init(fac); + + fmpz_poly_one(f); + for (k = 0; k < n; k++) + { + fmpz_poly_init(g[k]); + fmpz_poly_randtest_not_zero(g[k], state, n_randint(state, 40)+1, 20); + l = n_randint(state, 2) + 1; + while (l--) + fmpz_poly_mul(f, f, g[k]); + } + fmpz_poly_factor_squarefree(fac, f); + + /* Squarefree? */ + result = 1; + for (k = 0; k < fac->num && result; k++) + { + fmpz_poly_derivative(h, fac->p + k); + fmpz_poly_gcd(t, h, fac->p + k); + result &= fmpz_poly_is_one(t); + } + + /* Product? */ + fmpz_poly_set_fmpz(h, &(fac->c)); + for (k = 0; k < fac->num; k++) + { + if (fac->exp[k] == 1) + fmpz_poly_mul(h, h, fac->p + k); + else + { + fmpz_poly_pow(t, fac->p + k, fac->exp[k]); + fmpz_poly_mul(h, h, t); + } + } + + result &= fmpz_poly_equal(f, h); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("f = "), fmpz_poly_print_pretty(f, "x"), flint_printf("\n\n"); + for (k = 0; k < n; k++) + { + flint_printf("g[%wd] = ", k), fmpz_poly_print_pretty(g[k], "x"), flint_printf("\n\n"); + } + flint_printf("h = "), fmpz_poly_print_pretty(h, "x"), flint_printf("\n\n"); + fmpz_poly_factor_print(fac); + abort(); + } + + fmpz_poly_clear(f); + for (k = 0; k < n; k++) + fmpz_poly_clear(g[k]); + fmpz_poly_clear(h); + fmpz_poly_clear(t); + fmpz_poly_factor_clear(fac); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} + diff --git a/external/flint-2.4.3/fmpz_poly_factor/test/t-factor_zassenhaus.c b/external/flint-2.4.3/fmpz_poly_factor/test/t-factor_zassenhaus.c new file mode 100644 index 0000000..deae8fc --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_factor/test/t-factor_zassenhaus.c @@ -0,0 +1,102 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Andy Novocin + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz_poly.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("zassenhaus...."); + fflush(stdout); + + + + for (i = 0; i < 10000; i++) + { + fmpz_t c; + fmpz_poly_t f, g, h, t; + fmpz_poly_factor_t fac; + slong j, n = n_randint(state, 5); + + fmpz_init(c); + fmpz_poly_init(f); + fmpz_poly_init(g); + fmpz_poly_init(h); + fmpz_poly_init(t); + fmpz_poly_factor_init(fac); + + fmpz_randtest_not_zero(c, state, n_randint(state, 10) + 1); + fmpz_poly_set_fmpz(f, c); + + for (j = 0; j < n; j++) + { + fmpz_poly_randtest(g, state, n_randint(state, 5) + 2, n_randint(state, 40)); + fmpz_poly_mul(f, f, g); + } +/* fmpz_poly_set_str(f, "6 0 -1 0 0 0 1");*/ + + fmpz_poly_factor_zassenhaus(fac, f); + + fmpz_poly_set_fmpz(h, &fac->c); + for (j = 0; j < fac->num; j++) + { + if (fac->exp[j] == 1) + fmpz_poly_mul(h, h, fac->p + j); + else + { + fmpz_poly_pow(t, fac->p + j, fac->exp[j]); + fmpz_poly_mul(h, h, t); + } + } + + result = fmpz_poly_equal(f, h); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("f = "), fmpz_poly_print(f), flint_printf("\n\n"); + flint_printf("h = "), fmpz_poly_print(h), flint_printf("\n\n"); + flint_printf("fac = "), fmpz_poly_factor_print(fac), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(c); + fmpz_poly_clear(f); + fmpz_poly_clear(g); + fmpz_poly_clear(h); + fmpz_poly_clear(t); + fmpz_poly_factor_clear(fac); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly_factorxx.h b/external/flint-2.4.3/fmpz_poly_factorxx.h new file mode 100644 index 0000000..061b11d --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_factorxx.h @@ -0,0 +1,157 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#ifndef FMPZ_POLY_FACTORXX_H +#define FMPZ_POLY_FACTORXX_H + + +#include "fmpz_poly.h" +#include "nmod_polyxx.h" + +namespace flint { +class fmpz_poly_factorxx +{ +private: + fmpz_poly_factor_t inner; + +public: + fmpz_poly_factorxx() {fmpz_poly_factor_init(inner);} + explicit fmpz_poly_factorxx(slong alloc) + {fmpz_poly_factor_init2(inner, alloc);} + ~fmpz_poly_factorxx() {fmpz_poly_factor_clear(inner);} + + fmpz_poly_factorxx(const fmpz_poly_factorxx& o) + { + fmpz_poly_factor_init2(inner, o.size()); + fmpz_poly_factor_set(inner, o.inner); + } + + bool operator==(const fmpz_poly_factorxx& o) + { + if(o.content() != content() || o.size() != size()) + return false; + for(ulong i = 0;i < size();++i) + if(p(i) != o.p(i) || exp(i) != o.exp(i)) + return false; + return true; + } + + fmpz_poly_factorxx& operator=(const fmpz_poly_factorxx& o) + { + fmpz_poly_factor_set(inner, o.inner); + return *this; + } + + ulong size() const {return inner->num;} + slong exp(slong i) const {return inner->exp[i];} + slong& exp(slong i) {return inner->exp[i];} + fmpz_polyxx_srcref p(slong i) const + {return fmpz_polyxx_srcref::make(inner->p + i);} + fmpz_polyxx_ref p(slong i) {return fmpz_polyxx_ref::make(inner->p + i);} + fmpzxx_srcref content() const + {return fmpzxx_srcref::make(& inner->c);} + fmpzxx_ref content() {return fmpzxx_ref::make(& inner->c);} + + fmpz_poly_factor_t& _data() {return inner;} + const fmpz_poly_factor_t& _data() const {return inner;} + + void realloc(slong a) {fmpz_poly_factor_realloc(inner, a);} + void fit_length(slong a) {fmpz_poly_factor_fit_length(inner, a);} + + void print() const {fmpz_poly_factor_print(inner);} + + template + void insert(const Fmpz_poly& p, slong e, + typename mp::enable_if >::type* = 0) + {fmpz_poly_factor_insert(_data(), p.evaluate()._poly(), e);} + + void concat(const fmpz_poly_factorxx& o) + {fmpz_poly_factor_concat(_data(), o._data());} + + template + void set_factor_squarefree(const Fmpz_poly& p, + typename mp::enable_if >::type* = 0) + {fmpz_poly_factor_squarefree(_data(), p.evaluate()._poly());} + + template + void set_factor_zassenhaus_recombination( + const fmpz_poly_factorxx& lifted_fac, const Fmpz_poly& F, + const Fmpz& P, slong exp, + typename mp::enable_if >::type* = 0, + typename mp::enable_if >::type* = 0) + { + fmpz_poly_factor_zassenhaus_recombination(_data(), lifted_fac._data(), + F.evaluate()._poly(), P.evaluate()._fmpz(), exp); + } + + template + void set_factor_zassenhaus(const Fmpz_poly& p, + typename mp::enable_if >::type* = 0) + {fmpz_poly_factor_zassenhaus(_data(), p.evaluate()._poly());} + + template + void set_hensel_lift_once(const Fmpz_poly& f, + const nmod_poly_factorxx& local_fac, slong N, + typename mp::enable_if >::type* = 0) + { + fmpz_poly_hensel_lift_once(_data(), f.evaluate()._poly(), + local_fac._data(), N); + } +}; + +template +inline fmpz_poly_factorxx factor_squarefree(const Fmpz_poly& p, + typename mp::enable_if >* = 0) +{ + fmpz_poly_factorxx res; + res.set_factor_squarefree(p); + return res; +} +template +inline fmpz_poly_factorxx factor_zassenhaus(const Fmpz_poly& p, + typename mp::enable_if >* = 0) +{ + fmpz_poly_factorxx res; + res.set_factor_zassenhaus(p); + return res; +} + +template +inline fmpz_poly_factorxx hensel_lift_once(const Fmpz_poly& f, + const nmod_poly_factorxx& local_fac, slong N, + typename mp::enable_if >* = 0) +{ + fmpz_poly_factorxx res; + res.set_hensel_lift_once(f, local_fac, N); + return res; +} + +inline void print(const fmpz_poly_factorxx& f) +{ + f.print(); +} +} // flint + +#endif diff --git a/external/flint-2.4.3/fmpz_poly_mat.h b/external/flint-2.4.3/fmpz_poly_mat.h new file mode 100644 index 0000000..ae51cdf --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat.h @@ -0,0 +1,240 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#ifndef POLY_MAT_H +#define POLY_MAT_H + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mat.h" +#include "fmpz_poly.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/* Types *********************************************************************/ + +typedef struct +{ + fmpz_poly_struct * entries; + slong r; + slong c; + fmpz_poly_struct ** rows; +} fmpz_poly_mat_struct; + +typedef fmpz_poly_mat_struct fmpz_poly_mat_t[1]; + +#define fmpz_poly_mat_entry(mat,i,j) ((mat)->rows[(i)] + (j)) + +/* Memory management *********************************************************/ + +void fmpz_poly_mat_init(fmpz_poly_mat_t mat, slong rows, slong cols); + +void fmpz_poly_mat_init_set(fmpz_poly_mat_t mat, const fmpz_poly_mat_t src); + +void fmpz_poly_mat_swap(fmpz_poly_mat_t mat1, fmpz_poly_mat_t mat2); + +void fmpz_poly_mat_set(fmpz_poly_mat_t mat1, const fmpz_poly_mat_t mat2); + +void fmpz_poly_mat_clear(fmpz_poly_mat_t mat); + +/* Basic properties **********************************************************/ + +static __inline__ slong +fmpz_poly_mat_nrows(const fmpz_poly_mat_t mat) +{ + return mat->r; +} + +static __inline__ slong +fmpz_poly_mat_ncols(const fmpz_poly_mat_t mat) +{ + return mat->c; +} + +/* Comparison ****************************************************************/ + +int fmpz_poly_mat_equal(const fmpz_poly_mat_t mat1, + const fmpz_poly_mat_t mat2); + +int fmpz_poly_mat_is_zero(const fmpz_poly_mat_t mat); + +int fmpz_poly_mat_is_one(const fmpz_poly_mat_t mat); + +static __inline__ int +fmpz_poly_mat_is_empty(const fmpz_poly_mat_t mat) +{ + return (mat->r == 0) || (mat->c == 0); +} + +static __inline__ int +fmpz_poly_mat_is_square(const fmpz_poly_mat_t mat) +{ + return (mat->r == mat->c); +} + +/* Standard matrices *********************************************************/ + +void fmpz_poly_mat_zero(fmpz_poly_mat_t mat); + +void fmpz_poly_mat_one(fmpz_poly_mat_t mat); + +/* Random matrices ***********************************************************/ + +void fmpz_poly_mat_randtest(fmpz_poly_mat_t mat, flint_rand_t state, + slong len, mp_bitcnt_t bits); + +void fmpz_poly_mat_randtest_unsigned(fmpz_poly_mat_t mat, flint_rand_t state, + slong len, mp_bitcnt_t bits); + +void fmpz_poly_mat_randtest_sparse(fmpz_poly_mat_t A, flint_rand_t state, + slong len, mp_bitcnt_t bits, float density); + +/* Input and output **********************************************************/ + +void fmpz_poly_mat_print(const fmpz_poly_mat_t mat, const char * x); + +/* Norms *********************************************************************/ + +slong fmpz_poly_mat_max_bits(const fmpz_poly_mat_t A); + +slong fmpz_poly_mat_max_length(const fmpz_poly_mat_t A); + +/* Transpose *****************************************************************/ + +void fmpz_poly_mat_transpose(fmpz_poly_mat_t B, const fmpz_poly_mat_t A); + +/* Truncation ****************************************************************/ + +void fmpz_poly_mat_truncate(fmpz_poly_mat_t A, slong len); + +/* Scalar arithmetic *********************************************************/ + +void fmpz_poly_mat_scalar_mul_fmpz_poly(fmpz_poly_mat_t B, + const fmpz_poly_mat_t A, const fmpz_poly_t c); + +void fmpz_poly_mat_scalar_mul_fmpz(fmpz_poly_mat_t B, + const fmpz_poly_mat_t A, const fmpz_t c); + +/* Matrix arithmetic *********************************************************/ + +void fmpz_poly_mat_add(fmpz_poly_mat_t C, const fmpz_poly_mat_t A, + const fmpz_poly_mat_t B); + +void fmpz_poly_mat_sub(fmpz_poly_mat_t C, const fmpz_poly_mat_t A, + const fmpz_poly_mat_t B); + +void fmpz_poly_mat_neg(fmpz_poly_mat_t B, const fmpz_poly_mat_t A); + +void fmpz_poly_mat_mul(fmpz_poly_mat_t C, const fmpz_poly_mat_t A, + const fmpz_poly_mat_t B); + +void fmpz_poly_mat_mul_classical(fmpz_poly_mat_t C, const fmpz_poly_mat_t A, + const fmpz_poly_mat_t B); + +void fmpz_poly_mat_mul_KS(fmpz_poly_mat_t C, const fmpz_poly_mat_t A, + const fmpz_poly_mat_t B); + +void fmpz_poly_mat_mullow(fmpz_poly_mat_t C, const fmpz_poly_mat_t A, + const fmpz_poly_mat_t B, slong len); + +void fmpz_poly_mat_sqr(fmpz_poly_mat_t B, const fmpz_poly_mat_t A); + +void fmpz_poly_mat_sqr_classical(fmpz_poly_mat_t B, const fmpz_poly_mat_t A); + +void fmpz_poly_mat_sqr_KS(fmpz_poly_mat_t B, const fmpz_poly_mat_t A); + +void fmpz_poly_mat_sqrlow(fmpz_poly_mat_t B, const fmpz_poly_mat_t A, slong len); + +void fmpz_poly_mat_pow(fmpz_poly_mat_t B, const fmpz_poly_mat_t A, ulong exp); + +void +fmpz_poly_mat_pow_trunc(fmpz_poly_mat_t B, const fmpz_poly_mat_t A, ulong exp, + slong len); + +void fmpz_poly_mat_prod(fmpz_poly_mat_t res, + fmpz_poly_mat_t * const factors, slong n); + +/* Evaluation ****************************************************************/ + +void fmpz_poly_mat_evaluate_fmpz(fmpz_mat_t B, + const fmpz_poly_mat_t A, const fmpz_t x); + +/* Row reduction *************************************************************/ + +slong fmpz_poly_mat_find_pivot_any(const fmpz_poly_mat_t mat, + slong start_row, slong end_row, slong c); + +slong fmpz_poly_mat_find_pivot_partial(const fmpz_poly_mat_t mat, + slong start_row, slong end_row, slong c); + +slong fmpz_poly_mat_fflu(fmpz_poly_mat_t B, fmpz_poly_t den, slong * perm, + const fmpz_poly_mat_t A, int rank_check); + +slong fmpz_poly_mat_rref(fmpz_poly_mat_t B, fmpz_poly_t den, + const fmpz_poly_mat_t A); + +/* Trace *********************************************************************/ + +void fmpz_poly_mat_trace(fmpz_poly_t trace, const fmpz_poly_mat_t mat); + +/* Determinant and rank ******************************************************/ + +void fmpz_poly_mat_det(fmpz_poly_t det, const fmpz_poly_mat_t A); + +void fmpz_poly_mat_det_fflu(fmpz_poly_t det, const fmpz_poly_mat_t A); + +void fmpz_poly_mat_det_interpolate(fmpz_poly_t det, const fmpz_poly_mat_t A); + +slong fmpz_poly_mat_rank(const fmpz_poly_mat_t A); + +/* Inverse *******************************************************************/ + +int fmpz_poly_mat_inv(fmpz_poly_mat_t Ainv, fmpz_poly_t den, + const fmpz_poly_mat_t A); + +/* Nullspace *****************************************************************/ + +slong fmpz_poly_mat_nullspace(fmpz_poly_mat_t res, const fmpz_poly_mat_t mat); + +/* Solving *******************************************************************/ + +int fmpz_poly_mat_solve(fmpz_poly_mat_t X, fmpz_poly_t den, + const fmpz_poly_mat_t A, const fmpz_poly_mat_t B); + +int fmpz_poly_mat_solve_fflu(fmpz_poly_mat_t X, fmpz_poly_t den, + const fmpz_poly_mat_t A, const fmpz_poly_mat_t B); + +void fmpz_poly_mat_solve_fflu_precomp(fmpz_poly_mat_t X, + const slong * perm, + const fmpz_poly_mat_t FFLU, const fmpz_poly_mat_t B); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/flint-2.4.3/fmpz_poly_mat/add.c b/external/flint-2.4.3/fmpz_poly_mat/add.c new file mode 100644 index 0000000..334b62b --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/add.c @@ -0,0 +1,42 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + +void +fmpz_poly_mat_add(fmpz_poly_mat_t C, + const fmpz_poly_mat_t A, const fmpz_poly_mat_t B) +{ + slong i, j; + + for (i = 0; i < A->r; i++) + for (j = 0; j < A->c; j++) + fmpz_poly_add(fmpz_poly_mat_entry(C, i, j), + fmpz_poly_mat_entry(A, i, j), + fmpz_poly_mat_entry(B, i, j)); +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/clear.c b/external/flint-2.4.3/fmpz_poly_mat/clear.c new file mode 100644 index 0000000..312a17a --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/clear.c @@ -0,0 +1,44 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + +void +fmpz_poly_mat_clear(fmpz_poly_mat_t A) +{ + if (A->entries) + { + slong i; + + for (i = 0; i < A->r * A->c; i++) + fmpz_poly_clear(A->entries + i); + + flint_free(A->entries); + flint_free(A->rows); + } +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/det.c b/external/flint-2.4.3/fmpz_poly_mat/det.c new file mode 100644 index 0000000..24a80df --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/det.c @@ -0,0 +1,63 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + +void +fmpz_poly_mat_det(fmpz_poly_t det, const fmpz_poly_mat_t A) +{ + slong n = A->r; + + if (n == 0) + { + fmpz_poly_set_ui(det, UWORD(1)); + } + else if (n == 1) + { + fmpz_poly_set(det, fmpz_poly_mat_entry(A, 0, 0)); + } + else if (n == 2) + { + fmpz_poly_t tmp; + fmpz_poly_init(tmp); + fmpz_poly_mul(det, fmpz_poly_mat_entry(A, 0, 0), + fmpz_poly_mat_entry(A, 1, 1)); + fmpz_poly_mul(tmp, fmpz_poly_mat_entry(A, 0, 1), + fmpz_poly_mat_entry(A, 1, 0)); + fmpz_poly_sub(det, det, tmp); + fmpz_poly_clear(tmp); + } + else if (n < 15) /* should be entry sensitive too */ + { + fmpz_poly_mat_det_fflu(det, A); + } + else + { + fmpz_poly_mat_det_interpolate(det, A); + } +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/det_fflu.c b/external/flint-2.4.3/fmpz_poly_mat/det_fflu.c new file mode 100644 index 0000000..ec76c71 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/det_fflu.c @@ -0,0 +1,53 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" +#include "perm.h" + +void +fmpz_poly_mat_det_fflu(fmpz_poly_t det, const fmpz_poly_mat_t A) +{ + slong n = fmpz_poly_mat_nrows(A); + + if (n == 0) + fmpz_poly_one(det); + else + { + fmpz_poly_mat_t tmp; + slong * perm; + fmpz_poly_mat_init_set(tmp, A); + perm = _perm_init(n); + + fmpz_poly_mat_fflu(tmp, det, perm, tmp, 1); + if (_perm_parity(perm, n)) + fmpz_poly_neg(det, det); + + _perm_clear(perm); + fmpz_poly_mat_clear(tmp); + } +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/det_interpolate.c b/external/flint-2.4.3/fmpz_poly_mat/det_interpolate.c new file mode 100644 index 0000000..6f9208d --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/det_interpolate.c @@ -0,0 +1,75 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + +void +fmpz_poly_mat_det_interpolate(fmpz_poly_t det, const fmpz_poly_mat_t A) +{ + slong i, l, n, len; + + fmpz_mat_t X; + fmpz * x; + fmpz * d; + + n = A->r; + + if (n == 0) + { + fmpz_poly_one(det); + return; + } + + l = fmpz_poly_mat_max_length(A); + + if (l == 0) + { + fmpz_poly_zero(det); + return; + } + + /* Bound degree based on Laplace expansion */ + len = n*(l - 1) + 1; + + x = _fmpz_vec_init(len); + d = _fmpz_vec_init(len); + fmpz_mat_init(X, n, n); + + for (i = 0; i < len; i++) + { + fmpz_set_si(x + i, -len/2 + i); + fmpz_poly_mat_evaluate_fmpz(X, A, x + i); + fmpz_mat_det(d + i, X); + } + + fmpz_poly_interpolate_fmpz_vec(det, x, d, len); + + _fmpz_vec_clear(x, len); + _fmpz_vec_clear(d, len); + fmpz_mat_clear(X); +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/doc/fmpz_poly_mat.txt b/external/flint-2.4.3/fmpz_poly_mat/doc/fmpz_poly_mat.txt new file mode 100644 index 0000000..113fb2c --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/doc/fmpz_poly_mat.txt @@ -0,0 +1,500 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + + +******************************************************************************* + + Memory management + +******************************************************************************* + +void fmpz_poly_mat_init(fmpz_poly_mat_t mat, slong rows, slong cols) + + Initialises a matrix with the given number of rows and columns for use. + +void fmpz_poly_mat_init_set(fmpz_poly_mat_t mat, const fmpz_poly_mat_t src) + + Initialises a matrix \code{mat} of the same dimensions as \code{src}, + and sets it to a copy of \code{src}. + +void fmpz_poly_mat_clear(fmpz_poly_mat_t mat) + + Frees all memory associated with the matrix. The matrix must be + reinitialised if it is to be used again. + +******************************************************************************* + + Basic properties + +******************************************************************************* + +slong fmpz_poly_mat_nrows(const fmpz_poly_mat_t mat) + + Returns the number of rows in \code{mat}. + +slong fmpz_poly_mat_ncols(const fmpz_poly_mat_t mat) + + Returns the number of columns in \code{mat}. + + +******************************************************************************* + + Basic assignment and manipulation + +******************************************************************************* + +MACRO fmpz_poly_mat_entry(mat,i,j) + + Gives a reference to the entry at row \code{i} and column \code{j}. + The reference can be passed as an input or output variable to any + \code{fmpz_poly} function for direct manipulation of the matrix element. + No bounds checking is performed. + +void fmpz_poly_mat_set(fmpz_poly_mat_t mat1, const fmpz_poly_mat_t mat2) + + Sets \code{mat1} to a copy of \code{mat2}. + +void fmpz_poly_mat_swap(fmpz_poly_mat_t mat1, fmpz_poly_mat_t mat2) + + Swaps \code{mat1} and \code{mat2} efficiently. + + +******************************************************************************* + + Input and output + +******************************************************************************* + +void fmpz_poly_mat_print(const fmpz_poly_mat_t mat, const char * x) + + Prints the matrix \code{mat} to standard output, using the + variable \code{x}. + +******************************************************************************* + + Random matrix generation + +******************************************************************************* + +void fmpz_poly_mat_randtest(fmpz_poly_mat_t mat, flint_rand_t state, + slong len, mp_bitcnt_t bits) + + This is equivalent to applying \code{fmpz_poly_randtest} to all entries + in the matrix. + +void fmpz_poly_mat_randtest_unsigned(fmpz_poly_mat_t mat, flint_rand_t state, + slong len, mp_bitcnt_t bits) + + This is equivalent to applying \code{fmpz_poly_randtest_unsigned} to + all entries in the matrix. + +void fmpz_poly_mat_randtest_sparse(fmpz_poly_mat_t A, flint_rand_t state, + slong len, mp_bitcnt_t bits, float density) + + Creates a random matrix with the amount of nonzero entries given + approximately by the \code{density} variable, which should be a fraction + between 0 (most sparse) and 1 (most dense). + + The nonzero entries will have random lengths between 1 and \code{len}. + +******************************************************************************* + + Special matrices + +******************************************************************************* + +void fmpz_poly_mat_zero(fmpz_poly_mat_t mat) + + Sets \code{mat} to the zero matrix. + +void fmpz_poly_mat_one(fmpz_poly_mat_t mat) + + Sets \code{mat} to the unit or identity matrix of given shape, + having the element 1 on the main diagonal and zeros elsewhere. + If \code{mat} is nonsquare, it is set to the truncation of a unit matrix. + +******************************************************************************* + + Basic comparison and properties + +******************************************************************************* + +int fmpz_poly_mat_equal(const fmpz_poly_mat_t mat1, const fmpz_poly_mat_t mat2) + + Returns nonzero if \code{mat1} and \code{mat2} have the same shape and + all their entries agree, and returns zero otherwise. + +int fmpz_poly_mat_is_zero(const fmpz_poly_mat_t mat) + + Returns nonzero if all entries in \code{mat} are zero, and returns + zero otherwise. + +int fmpz_poly_mat_is_one(const fmpz_poly_mat_t mat) + + Returns nonzero if all entry of \code{mat} on the main diagonal + are the constant polynomial 1 and all remaining entries are zero, + and returns zero otherwise. The matrix need not be square. + +int fmpz_poly_mat_is_empty(const fmpz_poly_mat_t mat) + + Returns a non-zero value if the number of rows or the number of + columns in \code{mat} is zero, and otherwise returns + zero. + +int fmpz_poly_mat_is_square(const fmpz_poly_mat_t mat) + + Returns a non-zero value if the number of rows is equal to the + number of columns in \code{mat}, and otherwise returns zero. + + +******************************************************************************* + + Norms + +******************************************************************************* + +slong fmpz_poly_mat_max_bits(const fmpz_poly_mat_t A) + + Returns the maximum number of bits among the coefficients of the + entries in \code{A}, or the negative of that value if any + coefficient is negative. + +slong fmpz_poly_mat_max_length(const fmpz_poly_mat_t A) + + Returns the maximum polynomial length among all the entries in \code{A}. + + +******************************************************************************* + + Transpose + +******************************************************************************* + +void fmpz_poly_mat_transpose(fmpz_poly_mat_t B, const fmpz_poly_mat_t A) + + Sets $B$ to $A^t$. + + +******************************************************************************* + + Evaluation + +******************************************************************************* + +void fmpz_poly_mat_evaluate_fmpz(fmpz_mat_t B, const fmpz_poly_mat_t A, + const fmpz_t x) + + Sets the \code{fmpz_mat_t} \code{B} to \code{A} evaluated entrywise + at the point \code{x}. + + +******************************************************************************* + + Arithmetic + +******************************************************************************* + +void fmpz_poly_mat_scalar_mul_fmpz_poly(fmpz_poly_mat_t B, + const fmpz_poly_mat_t A, const fmpz_poly_t c) + + Sets \code{B} to \code{A} multiplied entrywise by the polynomial \code{c}. + +void fmpz_poly_mat_scalar_mul_fmpz(fmpz_poly_mat_t B, + const fmpz_poly_mat_t A, const fmpz_t c) + + Sets \code{B} to \code{A} multiplied entrywise by the integer \code{c}. + +void fmpz_poly_mat_add(fmpz_poly_mat_t C, const fmpz_poly_mat_t A, + const fmpz_poly_mat_t B) + + Sets \code{C} to the sum of \code{A} and \code{B}. + All matrices must have the same shape. Aliasing is allowed. + +void fmpz_poly_mat_sub(fmpz_poly_mat_t C, const fmpz_poly_mat_t A, + const fmpz_poly_mat_t B) + + Sets \code{C} to the sum of \code{A} and \code{B}. + All matrices must have the same shape. Aliasing is allowed. + +void fmpz_poly_mat_neg(fmpz_poly_mat_t B, const fmpz_poly_mat_t A) + + Sets \code{B} to the negation of \code{A}. + The matrices must have the same shape. Aliasing is allowed. + +void fmpz_poly_mat_mul(fmpz_poly_mat_t C, const fmpz_poly_mat_t A, + const fmpz_poly_mat_t B) + + Sets \code{C} to the matrix product of \code{A} and \code{B}. + The matrices must have compatible dimensions for matrix multiplication. + Aliasing is allowed. This function automatically chooses between + classical and KS multiplication. + +void fmpz_poly_mat_mul_classical(fmpz_poly_mat_t C, const fmpz_poly_mat_t A, + const fmpz_poly_mat_t B) + + Sets \code{C} to the matrix product of \code{A} and \code{B}, + computed using the classical algorithm. The matrices must have + compatible dimensions for matrix multiplication. Aliasing is allowed. + +void fmpz_poly_mat_mul_KS(fmpz_poly_mat_t C, const fmpz_poly_mat_t A, + const fmpz_poly_mat_t B) + + Sets \code{C} to the matrix product of \code{A} and \code{B}, + computed using Kronecker segmentation. The matrices must have + compatible dimensions for matrix multiplication. Aliasing is allowed. + +void fmpz_poly_mat_mullow(fmpz_poly_mat_t C, const fmpz_poly_mat_t A, + const fmpz_poly_mat_t B, slong len) + + Sets \code{C} to the matrix product of \code{A} and \code{B}, + truncating each entry in the result to length \code{len}. + Uses classical matrix multiplication. The matrices must have + compatible dimensions for matrix multiplication. Aliasing is allowed. + +void fmpz_poly_mat_sqr(fmpz_poly_mat_t B, const fmpz_poly_mat_t A) + + Sets \code{B} to the square of \code{A}, which must be a square matrix. + Aliasing is allowed. This function automatically chooses between + classical and KS squaring. + +void fmpz_poly_mat_sqr_classical(fmpz_poly_mat_t B, const fmpz_poly_mat_t A) + + Sets \code{B} to the square of \code{A}, which must be a square matrix. + Aliasing is allowed. This function uses direct formulas for very small + matrices, and otherwise classical matrix multiplication. + +void fmpz_poly_mat_sqr_KS(fmpz_poly_mat_t B, const fmpz_poly_mat_t A) + + Sets \code{B} to the square of \code{A}, which must be a square matrix. + Aliasing is allowed. This function uses Kronecker segmentation. + +void fmpz_poly_mat_sqrlow(fmpz_poly_mat_t B, const fmpz_poly_mat_t A, + slong len) + + Sets \code{B} to the square of \code{A}, which must be a square matrix, + truncating all entries to length \code{len}. + Aliasing is allowed. This function uses direct formulas for very small + matrices, and otherwise classical matrix multiplication. + +void fmpz_poly_mat_pow(fmpz_poly_mat_t B, const fmpz_poly_mat_t A, ulong exp) + + Sets \code{B} to \code{A} raised to the power \code{exp}, where \code{A} + is a square matrix. Uses exponentiation by squaring. Aliasing is allowed. + +void +fmpz_poly_mat_pow_trunc(fmpz_poly_mat_t B, const fmpz_poly_mat_t A, ulong exp, + slong len) + + Sets \code{B} to \code{A} raised to the power \code{exp}, truncating + all entries to length \code{len}, where \code{A} is a square matrix. + Uses exponentiation by squaring. Aliasing is allowed. + +void fmpz_poly_mat_prod(fmpz_poly_mat_t res, + fmpz_poly_mat_t * const factors, slong n) + + Sets \code{res} to the product of the \code{n} matrices given in + the vector \code{factors}, all of which must be square and of the + same size. Uses binary splitting. + +******************************************************************************* + + Row reduction + +******************************************************************************* + +slong fmpz_poly_mat_find_pivot_any(const fmpz_poly_mat_t mat, + slong start_row, slong end_row, slong c) + + Attempts to find a pivot entry for row reduction. + Returns a row index $r$ between \code{start_row} (inclusive) and + \code{stop_row} (exclusive) such that column $c$ in \code{mat} has + a nonzero entry on row $r$, or returns -1 if no such entry exists. + + This implementation simply chooses the first nonzero entry from + it encounters. This is likely to be a nearly optimal choice if all + entries in the matrix have roughly the same size, but can lead to + unnecessary coefficient growth if the entries vary in size. + +slong fmpz_poly_mat_find_pivot_partial(const fmpz_poly_mat_t mat, + slong start_row, slong end_row, slong c) + + Attempts to find a pivot entry for row reduction. + Returns a row index $r$ between \code{start_row} (inclusive) and + \code{stop_row} (exclusive) such that column $c$ in \code{mat} has + a nonzero entry on row $r$, or returns -1 if no such entry exists. + + This implementation searches all the rows in the column and + chooses the nonzero entry of smallest degree. If there are several + entries with the same minimal degree, it chooses the entry with + the smallest coefficient bit bound. This heuristic typically reduces + coefficient growth when the matrix entries vary in size. + +slong fmpz_poly_mat_fflu(fmpz_poly_mat_t B, fmpz_poly_t den, slong * perm, + const fmpz_poly_mat_t A, int rank_check) + + Uses fraction-free Gaussian elimination to set (\code{B}, \code{den}) to a + fraction-free LU decomposition of \code{A} and returns the + rank of \code{A}. Aliasing of \code{A} and \code{B} is allowed. + + Pivot elements are chosen with \code{fmpz_poly_mat_find_pivot_partial}. + If \code{perm} is non-\code{NULL}, the permutation of + rows in the matrix will also be applied to \code{perm}. + + If \code{rank_check} is set, the function aborts and returns 0 if the + matrix is detected not to have full rank without completing the + elimination. + + The denominator \code{den} is set to $\pm \operatorname{det}(A)$, where + the sign is decided by the parity of the permutation. Note that the + determinant is not generally the minimal denominator. + +slong fmpz_poly_mat_rref(fmpz_poly_mat_t B, fmpz_poly_t den, + const fmpz_poly_mat_t A) + + Sets (\code{B}, \code{den}) to the reduced row echelon form of + \code{A} and returns the rank of \code{A}. Aliasing of \code{A} and + \code{B} is allowed. + + The denominator \code{den} is set to $\pm \operatorname{det}(A)$. + Note that the determinant is not generally the minimal denominator. + +******************************************************************************* + + Trace + +******************************************************************************* + +void fmpz_poly_mat_trace(fmpz_poly_t trace, const fmpz_poly_mat_t mat) + + Computes the trace of the matrix, i.e. the sum of the entries on + the main diagonal. The matrix is required to be square. + +******************************************************************************* + + Determinant and rank + +******************************************************************************* + +void fmpz_poly_mat_det(fmpz_poly_t det, const fmpz_poly_mat_t A) + + Sets \code{det} to the determinant of the square matrix \code{A}. Uses + a direct formula, fraction-free LU decomposition, or interpolation, + depending on the size of the matrix. + +void fmpz_poly_mat_det_fflu(fmpz_poly_t det, const fmpz_poly_mat_t A) + + Sets \code{det} to the determinant of the square matrix \code{A}. + The determinant is computed by performing a fraction-free LU + decomposition on a copy of \code{A}. + +void fmpz_poly_mat_det_interpolate(fmpz_poly_t det, const fmpz_poly_mat_t A) + + Sets \code{det} to the determinant of the square matrix \code{A}. + The determinant is computed by determing a bound $n$ for its length, + evaluating the matrix at $n$ distinct points, computing the determinant + of each integer matrix, and forming the interpolating polynomial. + +slong fmpz_poly_mat_rank(const fmpz_poly_mat_t A) + + Returns the rank of \code{A}. Performs fraction-free LU decomposition + on a copy of \code{A}. + + +******************************************************************************* + + Inverse + +******************************************************************************* + +int fmpz_poly_mat_inv(fmpz_poly_mat_t Ainv, fmpz_poly_t den, + const fmpz_poly_mat_t A) + + Sets (\code{Ainv}, \code{den}) to the inverse matrix of \code{A}. + Returns 1 if \code{A} is nonsingular and 0 if \code{A} is singular. + Aliasing of \code{Ainv} and \code{A} is allowed. + + More precisely, \code{det} will be set to the determinant of \code{A} + and \code{Ainv} will be set to the adjugate matrix of \code{A}. + Note that the determinant is not necessarily the minimal denominator. + + Uses fraction-free LU decomposition, followed by solving for + the identity matrix. + + +******************************************************************************* + + Nullspace + +******************************************************************************* + +slong fmpz_poly_mat_nullspace(fmpz_poly_mat_t res, const fmpz_poly_mat_t mat) + + Computes the right rational nullspace of the matrix \code{mat} and + returns the nullity. + + More precisely, assume that \code{mat} has rank $r$ and nullity $n$. + Then this function sets the first $n$ columns of \code{res} + to linearly independent vectors spanning the nullspace of \code{mat}. + As a result, we always have rank(\code{res}) $= n$, and + \code{mat} $\times$ \code{res} is the zero matrix. + + The computed basis vectors will not generally be in a reduced form. + In general, the polynomials in each column vector in the result + will have a nontrivial common GCD. + +******************************************************************************* + + Solving + +******************************************************************************* + +int fmpz_poly_mat_solve(fmpz_poly_mat_t X, fmpz_poly_t den, + const fmpz_poly_mat_t A, const fmpz_poly_mat_t B) + + Solves the equation $AX = B$ for nonsingular $A$. More precisely, computes + (\code{X}, \code{den}) such that $AX = B \times \operatorname{den}$. + Returns 1 if $A$ is nonsingular and 0 if $A$ is singular. + The computed denominator will not generally be minimal. + + Uses fraction-free LU decomposition followed by fraction-free + forward and back substitution. + +int fmpz_poly_mat_solve_fflu(fmpz_poly_mat_t X, fmpz_poly_t den, + const fmpz_poly_mat_t A, const fmpz_poly_mat_t B); + + Solves the equation $AX = B$ for nonsingular $A$. More precisely, computes + (\code{X}, \code{den}) such that $AX = B \times \operatorname{den}$. + Returns 1 if $A$ is nonsingular and 0 if $A$ is singular. + The computed denominator will not generally be minimal. + + Uses fraction-free LU decomposition followed by fraction-free + forward and back substitution. + +void fmpz_poly_mat_solve_fflu_precomp(fmpz_poly_mat_t X, + const slong * perm, + const fmpz_poly_mat_t FFLU, const fmpz_poly_mat_t B); + + Performs fraction-free forward and back substitution given a precomputed + fraction-free LU decomposition and corresponding permutation. diff --git a/external/flint-2.4.3/fmpz_poly_mat/equal.c b/external/flint-2.4.3/fmpz_poly_mat/equal.c new file mode 100644 index 0000000..78e1845 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/equal.c @@ -0,0 +1,45 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + +int +fmpz_poly_mat_equal(const fmpz_poly_mat_t A, const fmpz_poly_mat_t B) +{ + slong i, j; + + if (A->r != B->r || A->c != B->c) + return 0; + + for (i = 0; i < A->r; i++) + for (j = 0; j < A->c; j++) + if (!fmpz_poly_equal(fmpz_poly_mat_entry(A, i, j), + fmpz_poly_mat_entry(B, i, j))) + return 0; + return 1; +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/evaluate_fmpz.c b/external/flint-2.4.3/fmpz_poly_mat/evaluate_fmpz.c new file mode 100644 index 0000000..5823fc2 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/evaluate_fmpz.c @@ -0,0 +1,41 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz_mat.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + +void +fmpz_poly_mat_evaluate_fmpz(fmpz_mat_t B, const fmpz_poly_mat_t A, const fmpz_t x) +{ + slong i, j; + + for (i = 0; i < A->r; i++) + for (j = 0; j < A->c; j++) + fmpz_poly_evaluate_fmpz(fmpz_mat_entry(B, i, j), + fmpz_poly_mat_entry(A, i, j), x); +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/fflu.c b/external/flint-2.4.3/fmpz_poly_mat/fflu.c new file mode 100644 index 0000000..66d38c2 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/fflu.c @@ -0,0 +1,112 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "flint.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + +#define E(j,k) fmpz_poly_mat_entry(B,j,k) + +static __inline__ void +fmpz_poly_mat_swap_rows(fmpz_poly_mat_t mat, slong * perm, slong r, slong s) +{ + if (r != s) + { + fmpz_poly_struct * u; + slong t; + + if (perm) + { + t = perm[s]; + perm[s] = perm[r]; + perm[r] = t; + } + + u = mat->rows[s]; + mat->rows[s] = mat->rows[r]; + mat->rows[r] = u; + } +} + +slong +fmpz_poly_mat_fflu(fmpz_poly_mat_t B, fmpz_poly_t den, slong * perm, + const fmpz_poly_mat_t A, int rank_check) +{ + fmpz_poly_t t; + slong m, n, j, k, rank, r, pivot_row, pivot_col; + + if (fmpz_poly_mat_is_empty(A)) + { + fmpz_poly_one(den); + return 0; + } + + fmpz_poly_mat_set(B, A); + m = B->r; + n = B->c; + rank = pivot_row = pivot_col = 0; + + fmpz_poly_init(t); + + while (pivot_row < m && pivot_col < n) + { + r = fmpz_poly_mat_find_pivot_partial(B, pivot_row, m, pivot_col); + + if (r == -1) + { + if (rank_check) + { + fmpz_poly_zero(den); + rank = 0; + break; + } + pivot_col++; + continue; + } + else if (r != pivot_row) + fmpz_poly_mat_swap_rows(B, perm, pivot_row, r); + + rank++; + + for (j = pivot_row + 1; j < m; j++) + { + for (k = pivot_col + 1; k < n; k++) + { + fmpz_poly_mul(E(j, k), E(j, k), E(pivot_row, pivot_col)); + fmpz_poly_mul(t, E(j, pivot_col), E(pivot_row, k)); + fmpz_poly_sub(E(j, k), E(j, k), t); + if (pivot_row > 0) + fmpz_poly_div(E(j, k), E(j, k), den); + } + } + + fmpz_poly_set(den, E(pivot_row, pivot_col)); + pivot_row++; + pivot_col++; + } + + fmpz_poly_clear(t); + return rank; +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/find_pivot_any.c b/external/flint-2.4.3/fmpz_poly_mat/find_pivot_any.c new file mode 100644 index 0000000..37efb0a --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/find_pivot_any.c @@ -0,0 +1,44 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + +slong +fmpz_poly_mat_find_pivot_any(const fmpz_poly_mat_t mat, + slong start_row, slong end_row, slong c) +{ + slong r; + + for (r = start_row; r < end_row; r++) + { + if (!fmpz_poly_is_zero(fmpz_poly_mat_entry(mat, r, c))) + return r; + } + + return -1; +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/find_pivot_partial.c b/external/flint-2.4.3/fmpz_poly_mat/find_pivot_partial.c new file mode 100644 index 0000000..0718fd0 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/find_pivot_partial.c @@ -0,0 +1,67 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + +slong +fmpz_poly_mat_find_pivot_partial(const fmpz_poly_mat_t mat, + slong start_row, slong end_row, slong c) +{ + slong best_row, best_length, best_bits, i; + + best_row = start_row; + best_length = fmpz_poly_length(fmpz_poly_mat_entry(mat, start_row, c)); + + best_bits = fmpz_poly_max_bits(fmpz_poly_mat_entry(mat, start_row, c)); + best_bits = FLINT_ABS(best_bits); + + for (i = start_row + 1; i < end_row; i++) + { + slong b, l; + + l = fmpz_poly_length(fmpz_poly_mat_entry(mat, i, c)); + + if (l != 0 && (best_length == 0 || l <= best_length)) + { + b = fmpz_poly_max_bits(fmpz_poly_mat_entry(mat, i, c)); + b = FLINT_ABS(b); + + if (best_length == 0 || l < best_length || b < best_bits) + { + best_row = i; + best_length = l; + best_bits = b; + } + } + } + + if (best_length == 0) + return -1; + + return best_row; +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/init.c b/external/flint-2.4.3/fmpz_poly_mat/init.c new file mode 100644 index 0000000..58fa75e --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/init.c @@ -0,0 +1,52 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + +void +fmpz_poly_mat_init(fmpz_poly_mat_t A, slong rows, slong cols) +{ + if (rows && cols) + { + slong i; + + A->entries = (fmpz_poly_struct *) flint_malloc(rows * cols * sizeof(fmpz_poly_struct)); + A->rows = (fmpz_poly_struct **) flint_malloc(rows * sizeof(fmpz_poly_struct *)); + + for (i = 0; i < rows * cols; i++) + fmpz_poly_init(A->entries + i); + + for (i = 0; i < rows; i++) + A->rows[i] = A->entries + i * cols; + } + else + A->entries = NULL; + + A->r = rows; + A->c = cols; +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/init_set.c b/external/flint-2.4.3/fmpz_poly_mat/init_set.c new file mode 100644 index 0000000..22c0c77 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/init_set.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + +void +fmpz_poly_mat_init_set(fmpz_poly_mat_t A, const fmpz_poly_mat_t B) +{ + fmpz_poly_mat_init(A, B->r, B->c); + fmpz_poly_mat_set(A, B); +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/inv.c b/external/flint-2.4.3/fmpz_poly_mat/inv.c new file mode 100644 index 0000000..d09a9cc --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/inv.c @@ -0,0 +1,105 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" +#include "perm.h" + +#define E fmpz_poly_mat_entry + +int +fmpz_poly_mat_inv(fmpz_poly_mat_t Ainv, fmpz_poly_t den, + const fmpz_poly_mat_t A) +{ + slong n = fmpz_poly_mat_nrows(A); + + if (n == 0) + { + fmpz_poly_one(den); + return 1; + } + else if (n == 1) + { + fmpz_poly_set(den, E(A, 0, 0)); + fmpz_poly_one(E(Ainv, 0, 0)); + return !fmpz_poly_is_zero(den); + } + else if (n == 2) + { + fmpz_poly_mat_det(den, A); + if (fmpz_poly_is_zero(den)) + { + return 0; + } + else if (Ainv == A) + { + fmpz_poly_swap(E(A, 0, 0), E(A, 1, 1)); + fmpz_poly_neg(E(A, 0, 1), E(A, 0, 1)); + fmpz_poly_neg(E(A, 1, 0), E(A, 1, 0)); + return 1; + } + else + { + fmpz_poly_set(E(Ainv, 0, 0), E(A, 1, 1)); + fmpz_poly_set(E(Ainv, 1, 1), E(A, 0, 0)); + fmpz_poly_neg(E(Ainv, 0, 1), E(A, 0, 1)); + fmpz_poly_neg(E(Ainv, 1, 0), E(A, 1, 0)); + return 1; + } + } + else + { + fmpz_poly_mat_t LU, I; + slong * perm; + int result; + + perm = _perm_init(n); + fmpz_poly_mat_init_set(LU, A); + result = (fmpz_poly_mat_fflu(LU, den, perm, LU, 1) == n); + + if (result) + { + fmpz_poly_mat_init(I, n, n); + fmpz_poly_mat_one(I); + fmpz_poly_mat_solve_fflu_precomp(Ainv, perm, LU, I); + fmpz_poly_mat_clear(I); + } + else + fmpz_poly_zero(den); + + if (_perm_parity(perm, n)) + { + fmpz_poly_mat_neg(Ainv, Ainv); + fmpz_poly_neg(den, den); + } + + _perm_clear(perm); + fmpz_poly_mat_clear(LU); + return result; + } +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/is_one.c b/external/flint-2.4.3/fmpz_poly_mat/is_one.c new file mode 100644 index 0000000..47999aa --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/is_one.c @@ -0,0 +1,57 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + +int +fmpz_poly_mat_is_one(const fmpz_poly_mat_t A) +{ + slong i, j; + + if (A->r == 0 || A->c == 0) + return 1; + + for (i = 0; i < A->r; i++) + { + for (j = 0; j < A->c; j++) + { + if (i == j) + { + if (!fmpz_poly_is_one(fmpz_poly_mat_entry(A, i, j))) + return 0; + } + else + { + if (!fmpz_poly_is_zero(fmpz_poly_mat_entry(A, i, j))) + return 0; + } + } + } + + return 1; +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/is_zero.c b/external/flint-2.4.3/fmpz_poly_mat/is_zero.c new file mode 100644 index 0000000..96f3295 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/is_zero.c @@ -0,0 +1,45 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + +int +fmpz_poly_mat_is_zero(const fmpz_poly_mat_t A) +{ + slong i, j; + + if (A->r == 0 || A->c == 0) + return 1; + + for (i = 0; i < A->r; i++) + for (j = 0; j < A->c; j++) + if (!fmpz_poly_is_zero(fmpz_poly_mat_entry(A, i, j))) + return 0; + + return 1; +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/max_bits.c b/external/flint-2.4.3/fmpz_poly_mat/max_bits.c new file mode 100644 index 0000000..3e2c3ac --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/max_bits.c @@ -0,0 +1,57 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + +slong +fmpz_poly_mat_max_bits(const fmpz_poly_mat_t A) +{ + slong i, j, bits, max; + int sign; + + max = 0; + sign = 0; + + for (i = 0; i < A->r; i++) + { + for (j = 0; j < A->c; j++) + { + bits = fmpz_poly_max_bits(fmpz_poly_mat_entry(A, i, j)); + + if (bits < 0) + { + sign = 1; + max = FLINT_MAX(max, -bits); + } + else + max = FLINT_MAX(max, bits); + } + } + + return sign ? -max : max; +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/max_length.c b/external/flint-2.4.3/fmpz_poly_mat/max_length.c new file mode 100644 index 0000000..d42b687 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/max_length.c @@ -0,0 +1,48 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + +slong +fmpz_poly_mat_max_length(const fmpz_poly_mat_t A) +{ + slong i, j, len, max; + + max = 0; + + for (i = 0; i < A->r; i++) + { + for (j = 0; j < A->c; j++) + { + len = fmpz_poly_length(fmpz_poly_mat_entry(A, i, j)); + max = FLINT_MAX(len, max); + } + } + + return max; +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/mul.c b/external/flint-2.4.3/fmpz_poly_mat/mul.c new file mode 100644 index 0000000..f0c527d --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/mul.c @@ -0,0 +1,43 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + +void +fmpz_poly_mat_mul(fmpz_poly_mat_t C, const fmpz_poly_mat_t A, + const fmpz_poly_mat_t B) +{ + if (A->r < 8 || B->r < 8 || B->c < 8) + { + fmpz_poly_mat_mul_classical(C, A, B); + } + else + { + fmpz_poly_mat_mul_KS(C, A, B); + } +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/mul_KS.c b/external/flint-2.4.3/fmpz_poly_mat/mul_KS.c new file mode 100644 index 0000000..b7aa307 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/mul_KS.c @@ -0,0 +1,95 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" +#include "fmpz_mat.h" + +void +fmpz_poly_mat_mul_KS(fmpz_poly_mat_t C, const fmpz_poly_mat_t A, + const fmpz_poly_mat_t B) +{ + slong i, j; + slong A_len, B_len; + int signs; + slong A_bits, B_bits, bit_size; + + fmpz_mat_t AA, BB, CC; + + if (B->r == 0) + { + fmpz_poly_mat_zero(C); + return; + } + + A_len = fmpz_poly_mat_max_length(A); + B_len = fmpz_poly_mat_max_length(B); + + A_bits = fmpz_poly_mat_max_bits(A); + B_bits = fmpz_poly_mat_max_bits(B); + + signs = (A_bits < 0 || B_bits < 0); + + bit_size = FLINT_ABS(A_bits) + FLINT_ABS(B_bits) + signs; + bit_size += FLINT_BIT_COUNT(FLINT_MIN(A_len, B_len)); + bit_size += FLINT_BIT_COUNT(B->r); + +/* + flint_printf("A: BITS %wd LEN %wd\n", A_bits, A_len); + flint_printf("B: BITS %wd LEN %wd\n", B_bits, B_len); + flint_printf("bit_size: %wd\n", bit_size); +*/ + + fmpz_mat_init(AA, A->r, A->c); + fmpz_mat_init(BB, B->r, B->c); + fmpz_mat_init(CC, C->r, C->c); + + for (i = 0; i < A->r; i++) + for (j = 0; j < A->c; j++) + fmpz_poly_bit_pack(fmpz_mat_entry(AA, i, j), + fmpz_poly_mat_entry(A, i, j), bit_size); + + for (i = 0; i < B->r; i++) + for (j = 0; j < B->c; j++) + fmpz_poly_bit_pack(fmpz_mat_entry(BB, i, j), + fmpz_poly_mat_entry(B, i, j), bit_size); + + fmpz_mat_mul(CC, AA, BB); + + for (i = 0; i < C->r; i++) + for (j = 0; j < C->c; j++) + if (signs) + fmpz_poly_bit_unpack(fmpz_poly_mat_entry(C, i, j), + fmpz_mat_entry(CC, i, j), bit_size); + else + fmpz_poly_bit_unpack_unsigned(fmpz_poly_mat_entry(C, i, j), + fmpz_mat_entry(CC, i, j), bit_size); + + fmpz_mat_clear(AA); + fmpz_mat_clear(BB); + fmpz_mat_clear(CC); +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/mul_classical.c b/external/flint-2.4.3/fmpz_poly_mat/mul_classical.c new file mode 100644 index 0000000..d9598a3 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/mul_classical.c @@ -0,0 +1,81 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + +void +fmpz_poly_mat_mul_classical(fmpz_poly_mat_t C, const fmpz_poly_mat_t A, + const fmpz_poly_mat_t B) +{ + slong ar, bc, br; + slong i, j, k; + fmpz_poly_t t; + + ar = A->r; + br = B->r; + bc = B->c; + + if (br == 0) + { + fmpz_poly_mat_zero(C); + return; + } + + if (C == A || C == B) + { + fmpz_poly_mat_t T; + fmpz_poly_mat_init(T, ar, bc); + fmpz_poly_mat_mul_classical(T, A, B); + fmpz_poly_mat_swap(C, T); + fmpz_poly_mat_clear(T); + return; + } + + fmpz_poly_init(t); + + for (i = 0; i < ar; i++) + { + for (j = 0; j < bc; j++) + { + fmpz_poly_mul(fmpz_poly_mat_entry(C, i, j), + fmpz_poly_mat_entry(A, i, 0), + fmpz_poly_mat_entry(B, 0, j)); + + for (k = 1; k < br; k++) + { + fmpz_poly_mul(t, fmpz_poly_mat_entry(A, i, k), + fmpz_poly_mat_entry(B, k, j)); + + fmpz_poly_add(fmpz_poly_mat_entry(C, i, j), + fmpz_poly_mat_entry(C, i, j), t); + } + } + } + + fmpz_poly_clear(t); +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/mullow.c b/external/flint-2.4.3/fmpz_poly_mat/mullow.c new file mode 100644 index 0000000..91e3561 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/mullow.c @@ -0,0 +1,81 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + +void +fmpz_poly_mat_mullow(fmpz_poly_mat_t C, const fmpz_poly_mat_t A, + const fmpz_poly_mat_t B, slong len) +{ + slong ar, bc, br; + slong i, j, k; + fmpz_poly_t t; + + ar = A->r; + br = B->r; + bc = B->c; + + if (br == 0 || len < 1) + { + fmpz_poly_mat_zero(C); + return; + } + + if (C == A || C == B) + { + fmpz_poly_mat_t T; + fmpz_poly_mat_init(T, ar, bc); + fmpz_poly_mat_mullow(T, A, B, len); + fmpz_poly_mat_swap(C, T); + fmpz_poly_mat_clear(T); + return; + } + + fmpz_poly_init(t); + + for (i = 0; i < ar; i++) + { + for (j = 0; j < bc; j++) + { + fmpz_poly_mullow(fmpz_poly_mat_entry(C, i, j), + fmpz_poly_mat_entry(A, i, 0), + fmpz_poly_mat_entry(B, 0, j), len); + + for (k = 1; k < br; k++) + { + fmpz_poly_mullow(t, fmpz_poly_mat_entry(A, i, k), + fmpz_poly_mat_entry(B, k, j), len); + + fmpz_poly_add(fmpz_poly_mat_entry(C, i, j), + fmpz_poly_mat_entry(C, i, j), t); + } + } + } + + fmpz_poly_clear(t); +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/neg.c b/external/flint-2.4.3/fmpz_poly_mat/neg.c new file mode 100644 index 0000000..362b614 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/neg.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + +void +fmpz_poly_mat_neg(fmpz_poly_mat_t B, const fmpz_poly_mat_t A) +{ + slong i, j; + + for (i = 0; i < A->r; i++) + for (j = 0; j < A->c; j++) + fmpz_poly_neg(fmpz_poly_mat_entry(B, i, j), + fmpz_poly_mat_entry(A, i, j)); +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/nullspace.c b/external/flint-2.4.3/fmpz_poly_mat/nullspace.c new file mode 100644 index 0000000..62a565e --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/nullspace.c @@ -0,0 +1,95 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + +slong +fmpz_poly_mat_nullspace(fmpz_poly_mat_t res, const fmpz_poly_mat_t mat) +{ + slong i, j, k, n, rank, nullity; + slong * pivots; + slong * nonpivots; + fmpz_poly_mat_t tmp; + fmpz_poly_t den; + + n = mat->c; + + fmpz_poly_init(den); + fmpz_poly_mat_init_set(tmp, mat); + rank = fmpz_poly_mat_rref(tmp, den, tmp); + nullity = n - rank; + + fmpz_poly_mat_zero(res); + + if (rank == 0) + { + for (i = 0; i < nullity; i++) + fmpz_poly_set_ui(res->rows[i] + i, UWORD(1)); + } + else if (nullity) + { + pivots = flint_malloc(rank * sizeof(slong)); + nonpivots = flint_malloc(nullity * sizeof(slong)); + + for (i = j = k = 0; i < rank; i++) + { + while (fmpz_poly_is_zero(tmp->rows[i] + j)) + { + nonpivots[k] = j; + k++; + j++; + } + pivots[i] = j; + j++; + } + while (k < nullity) + { + nonpivots[k] = j; + k++; + j++; + } + + fmpz_poly_set(den, tmp->rows[0] + pivots[0]); + + for (i = 0; i < nullity; i++) + { + for (j = 0; j < rank; j++) + fmpz_poly_set(res->rows[pivots[j]] + i, + tmp->rows[j] + nonpivots[i]); + fmpz_poly_neg(res->rows[nonpivots[i]] + i, den); + } + + flint_free(pivots); + flint_free(nonpivots); + } + + fmpz_poly_clear(den); + fmpz_poly_mat_clear(tmp); + return nullity; +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/one.c b/external/flint-2.4.3/fmpz_poly_mat/one.c new file mode 100644 index 0000000..8b8663b --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/one.c @@ -0,0 +1,41 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + +void +fmpz_poly_mat_one(fmpz_poly_mat_t A) +{ + slong i, n; + + fmpz_poly_mat_zero(A); + n = FLINT_MIN(A->r, A->c); + + for (i = 0; i < n; i++) + fmpz_poly_one(fmpz_poly_mat_entry(A, i, i)); +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/pow.c b/external/flint-2.4.3/fmpz_poly_mat/pow.c new file mode 100644 index 0000000..aa6b8aa --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/pow.c @@ -0,0 +1,75 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + +void +fmpz_poly_mat_pow(fmpz_poly_mat_t B, const fmpz_poly_mat_t A, ulong exp) +{ + slong d = fmpz_poly_mat_nrows(A); + + if (exp == 0 || d == 0) + { + fmpz_poly_mat_one(B); + } + else if (exp == 1) + { + fmpz_poly_mat_set(B, A); + } + else if (exp == 2) + { + fmpz_poly_mat_sqr(B, A); + } + else if (d == 1) + { + fmpz_poly_pow(fmpz_poly_mat_entry(B, 0, 0), + fmpz_poly_mat_entry(A, 0, 0), exp); + } + else + { + fmpz_poly_mat_t T, U; + slong i; + + fmpz_poly_mat_init_set(T, A); + fmpz_poly_mat_init(U, d, d); + + for (i = ((slong) FLINT_BIT_COUNT(exp)) - 2; i >= 0; i--) + { + fmpz_poly_mat_sqr(U, T); + + if (exp & (WORD(1) << i)) + fmpz_poly_mat_mul(T, U, A); + else + fmpz_poly_mat_swap(T, U); + } + + fmpz_poly_mat_swap(B, T); + fmpz_poly_mat_clear(T); + fmpz_poly_mat_clear(U); + } +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/pow_trunc.c b/external/flint-2.4.3/fmpz_poly_mat/pow_trunc.c new file mode 100644 index 0000000..945b04d --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/pow_trunc.c @@ -0,0 +1,82 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + +void +fmpz_poly_mat_pow_trunc(fmpz_poly_mat_t B, const fmpz_poly_mat_t A, ulong exp, + slong len) +{ + slong d = fmpz_poly_mat_nrows(A); + + if (len < 1) + { + fmpz_poly_mat_zero(B); + } + else if (exp == 0 || d == 0) + { + fmpz_poly_mat_one(B); + } + else if (exp == 1) + { + fmpz_poly_mat_set(B, A); + fmpz_poly_mat_truncate(B, len); + } + else if (exp == 2) + { + fmpz_poly_mat_sqrlow(B, A, len); + } + else if (d == 1) + { + fmpz_poly_pow_trunc(fmpz_poly_mat_entry(B, 0, 0), + fmpz_poly_mat_entry(A, 0, 0), exp, len); + } + else + { + fmpz_poly_mat_t T, U; + slong i; + + fmpz_poly_mat_init_set(T, A); + fmpz_poly_mat_truncate(T, len); + fmpz_poly_mat_init(U, d, d); + + for (i = ((slong) FLINT_BIT_COUNT(exp)) - 2; i >= 0; i--) + { + fmpz_poly_mat_sqrlow(U, T, len); + + if (exp & (WORD(1) << i)) + fmpz_poly_mat_mullow(T, U, A, len); + else + fmpz_poly_mat_swap(T, U); + } + + fmpz_poly_mat_swap(B, T); + fmpz_poly_mat_clear(T); + fmpz_poly_mat_clear(U); + } +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/print.c b/external/flint-2.4.3/fmpz_poly_mat/print.c new file mode 100644 index 0000000..af063a2 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/print.c @@ -0,0 +1,50 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + +void +fmpz_poly_mat_print(const fmpz_poly_mat_t A, const char * x) +{ + slong i, j; + + flint_printf("<%wd x %wd matrix over Z[%s]>\n", A->r, A->c, x); + + for (i = 0; i < A->r; i++) + { + flint_printf("["); + for (j = 0; j < A->c; j++) + { + fmpz_poly_print_pretty(fmpz_poly_mat_entry(A, i, j), x); + if (j + 1 < A->c) + flint_printf(", "); + } + flint_printf("]\n"); + } + flint_printf("\n"); +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/prod.c b/external/flint-2.4.3/fmpz_poly_mat/prod.c new file mode 100644 index 0000000..4b86f7f --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/prod.c @@ -0,0 +1,70 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + +static void +binary_splitting(fmpz_poly_mat_t P, fmpz_poly_mat_t * const factors, + slong n1, slong n2) +{ + if (n2 - n1 <= 0) + { + fmpz_poly_mat_one(P); + } + else if (n2 - n1 == 1) + { + fmpz_poly_mat_set(P, factors[n1]); + } + else if (n2 - n1 == 2) + { + fmpz_poly_mat_mul(P, factors[n1], factors[n1 + 1]); + } + else + { + fmpz_poly_mat_t P1, P2; + slong m = (n1 + n2) / 2; + + fmpz_poly_mat_init(P1, P->r, P->c); + fmpz_poly_mat_init(P2, P->r, P->c); + + binary_splitting(P1, factors, n1, m); + binary_splitting(P2, factors, m, n2); + + fmpz_poly_mat_mul(P, P1, P2); + + fmpz_poly_mat_clear(P1); + fmpz_poly_mat_clear(P2); + } +} + +void +fmpz_poly_mat_prod(fmpz_poly_mat_t res, + fmpz_poly_mat_t * const factors, slong n) +{ + binary_splitting(res, factors, 0, n); +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/randtest.c b/external/flint-2.4.3/fmpz_poly_mat/randtest.c new file mode 100644 index 0000000..fe9c986 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/randtest.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + +void +fmpz_poly_mat_randtest(fmpz_poly_mat_t A, flint_rand_t state, slong len, mp_bitcnt_t bits) +{ + slong i, j; + + for (i = 0; i < A->r; i++) + for (j = 0; j < A->c; j++) + fmpz_poly_randtest(fmpz_poly_mat_entry(A, i, j), state, len, bits); +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/randtest_sparse.c b/external/flint-2.4.3/fmpz_poly_mat/randtest_sparse.c new file mode 100644 index 0000000..a3ed5e1 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/randtest_sparse.c @@ -0,0 +1,55 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" +#include "ulong_extras.h" + +void +fmpz_poly_mat_randtest_sparse(fmpz_poly_mat_t A, flint_rand_t state, slong len, + mp_bitcnt_t bits, float density) +{ + slong i, j; + + for (i = 0; i < A->r; i++) + { + for (j = 0; j < A->c; j++) + { + if (n_randint(state, 1000) < density * 1000) + { + slong l = n_randint(state, len + 1); + l = FLINT_MAX(l, 1); + fmpz_poly_randtest_not_zero(fmpz_poly_mat_entry(A, i, j), + state, l, bits); + } + else + { + fmpz_poly_zero(fmpz_poly_mat_entry(A, i, j)); + } + } + } +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/randtest_unsigned.c b/external/flint-2.4.3/fmpz_poly_mat/randtest_unsigned.c new file mode 100644 index 0000000..fe73284 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/randtest_unsigned.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + +void +fmpz_poly_mat_randtest_unsigned(fmpz_poly_mat_t A, flint_rand_t state, slong len, mp_bitcnt_t bits) +{ + slong i, j; + + for (i = 0; i < A->r; i++) + for (j = 0; j < A->c; j++) + fmpz_poly_randtest_unsigned(fmpz_poly_mat_entry(A, i, j), state, len, bits); +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/rank.c b/external/flint-2.4.3/fmpz_poly_mat/rank.c new file mode 100644 index 0000000..98d58ed --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/rank.c @@ -0,0 +1,49 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + + +slong +fmpz_poly_mat_rank(const fmpz_poly_mat_t A) +{ + fmpz_poly_mat_t tmp; + fmpz_poly_t den; + slong rank; + + if (fmpz_poly_mat_is_empty(A)) + return 0; + + fmpz_poly_mat_init_set(tmp, A); + fmpz_poly_init(den); + rank = fmpz_poly_mat_fflu(tmp, den, NULL, tmp, 0); + fmpz_poly_mat_clear(tmp); + fmpz_poly_clear(den); + return rank; +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/rref.c b/external/flint-2.4.3/fmpz_poly_mat/rref.c new file mode 100644 index 0000000..6818e96 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/rref.c @@ -0,0 +1,111 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011-2012 Fredrik Johansson + +******************************************************************************/ + +#include "flint.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + +slong +fmpz_poly_mat_rref(fmpz_poly_mat_t R, fmpz_poly_t den, const fmpz_poly_mat_t A) +{ + slong i, j, k, m, n, rank; + slong *pivots, *nonpivots; + + rank = fmpz_poly_mat_fflu(R, den, NULL, A, 0); + m = fmpz_poly_mat_nrows(R); + n = fmpz_poly_mat_ncols(R); + + /* clear bottom */ + for (i = rank; i < m; i++) + for (j = 0; j < n; j++) + fmpz_poly_zero(fmpz_poly_mat_entry(R, i, j)); + + /* Convert row echelon form to reduced row echelon form */ + if (rank > 1) + { + fmpz_poly_t tmp, tmp2; + fmpz_poly_init(tmp); + fmpz_poly_init(tmp2); + + pivots = flint_malloc(sizeof(slong) * n); + nonpivots = pivots + rank; + + /* find pivot positions */ + for (i = j = k = 0; i < rank; i++) + { + while (fmpz_poly_is_zero(fmpz_poly_mat_entry(R, i, j))) + { + nonpivots[k] = j; + k++; + j++; + } + pivots[i] = j; + j++; + } + while (k < n - rank) + { + nonpivots[k] = j; + k++; + j++; + } + + for (k = 0; k < n - rank; k++) + { + for (i = rank - 2; i >= 0; i--) + { + fmpz_poly_mul(tmp, den, fmpz_poly_mat_entry(R, i, nonpivots[k])); + + for (j = i + 1; j < rank; j++) + { + fmpz_poly_mul(tmp2, fmpz_poly_mat_entry(R, i, pivots[j]), + fmpz_poly_mat_entry(R, j, nonpivots[k])); + fmpz_poly_sub(tmp, tmp, tmp2); + } + + fmpz_poly_div(fmpz_poly_mat_entry(R, i, nonpivots[k]), + tmp, fmpz_poly_mat_entry(R, i, pivots[i])); + } + } + + /* clear pivot columns */ + for (i = 0; i < rank; i++) + { + for (j = 0; j < rank; j++) + { + if (i == j) + fmpz_poly_set(fmpz_poly_mat_entry(R, j, pivots[i]), den); + else + fmpz_poly_zero(fmpz_poly_mat_entry(R, j, pivots[i])); + } + } + + flint_free(pivots); + fmpz_poly_clear(tmp); + fmpz_poly_clear(tmp2); + } + + return rank; +} + diff --git a/external/flint-2.4.3/fmpz_poly_mat/scalar_mul_fmpz.c b/external/flint-2.4.3/fmpz_poly_mat/scalar_mul_fmpz.c new file mode 100644 index 0000000..1ba7731 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/scalar_mul_fmpz.c @@ -0,0 +1,42 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + +void +fmpz_poly_mat_scalar_mul_fmpz(fmpz_poly_mat_t B, const fmpz_poly_mat_t A, + const fmpz_t c) +{ + slong i, j; + + for (i = 0; i < fmpz_poly_mat_nrows(B); i++) + for (j = 0; j < fmpz_poly_mat_ncols(B); j++) + fmpz_poly_scalar_mul_fmpz(fmpz_poly_mat_entry(B, i, j), + fmpz_poly_mat_entry(A, i, j), c); +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/scalar_mul_fmpz_poly.c b/external/flint-2.4.3/fmpz_poly_mat/scalar_mul_fmpz_poly.c new file mode 100644 index 0000000..070f4cc --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/scalar_mul_fmpz_poly.c @@ -0,0 +1,42 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + +void +fmpz_poly_mat_scalar_mul_fmpz_poly(fmpz_poly_mat_t B, const fmpz_poly_mat_t A, + const fmpz_poly_t c) +{ + slong i, j; + + for (i = 0; i < fmpz_poly_mat_nrows(B); i++) + for (j = 0; j < fmpz_poly_mat_ncols(B); j++) + fmpz_poly_mul(fmpz_poly_mat_entry(B, i, j), + fmpz_poly_mat_entry(A, i, j), c); +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/set.c b/external/flint-2.4.3/fmpz_poly_mat/set.c new file mode 100644 index 0000000..304d420 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/set.c @@ -0,0 +1,43 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + +void +fmpz_poly_mat_set(fmpz_poly_mat_t B, const fmpz_poly_mat_t A) +{ + if (A != B) + { + slong i, j; + + for (i = 0; i < A->r; i++) + for (j = 0; j < A->c; j++) + fmpz_poly_set(fmpz_poly_mat_entry(B, i, j), + fmpz_poly_mat_entry(A, i, j)); + } +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/solve.c b/external/flint-2.4.3/fmpz_poly_mat/solve.c new file mode 100644 index 0000000..c9b205a --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/solve.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" +#include "perm.h" + +int +fmpz_poly_mat_solve(fmpz_poly_mat_t X, fmpz_poly_t den, + const fmpz_poly_mat_t A, const fmpz_poly_mat_t B) +{ + return fmpz_poly_mat_solve_fflu(X, den, A, B); +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/solve_fflu.c b/external/flint-2.4.3/fmpz_poly_mat/solve_fflu.c new file mode 100644 index 0000000..2f6cbf6 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/solve_fflu.c @@ -0,0 +1,60 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" +#include "perm.h" + +int +fmpz_poly_mat_solve_fflu(fmpz_poly_mat_t X, fmpz_poly_t den, + const fmpz_poly_mat_t A, const fmpz_poly_mat_t B) +{ + fmpz_poly_mat_t LU; + slong dim, *perm; + int result; + + if (fmpz_poly_mat_is_empty(B)) + { + fmpz_poly_one(den); + return 1; + } + + dim = fmpz_poly_mat_nrows(A); + perm = _perm_init(dim); + fmpz_poly_mat_init_set(LU, A); + result = (fmpz_poly_mat_fflu(LU, den, perm, LU, 1) == dim); + + if (result) + fmpz_poly_mat_solve_fflu_precomp(X, perm, LU, B); + else + fmpz_poly_zero(den); + + _perm_clear(perm); + fmpz_poly_mat_clear(LU); + return result; +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/solve_fflu_precomp.c b/external/flint-2.4.3/fmpz_poly_mat/solve_fflu_precomp.c new file mode 100644 index 0000000..ac1702c --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/solve_fflu_precomp.c @@ -0,0 +1,103 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" +#include "perm.h" + +#define XX(ii,jj) fmpz_poly_mat_entry(X,(ii),(jj)) +#define BB(ii,jj) fmpz_poly_mat_entry(B,(ii),(jj)) +#define LU(ii,jj) fmpz_poly_mat_entry(FFLU,(ii),(jj)) + +void +fmpz_poly_mat_set_perm(fmpz_poly_mat_t X, const slong * perm, + const fmpz_poly_mat_t B) +{ + if (X == B) + { + /* Not implemented */ + abort(); + } + else + { + slong i, j; + + if (perm == NULL) + abort(); + + for (i = 0; i < fmpz_poly_mat_nrows(B); i++) + for (j = 0; j < fmpz_poly_mat_ncols(B); j++) + fmpz_poly_set(fmpz_poly_mat_entry(X, i, j), + fmpz_poly_mat_entry(B, perm[i], j)); + } +} + +void +fmpz_poly_mat_solve_fflu_precomp(fmpz_poly_mat_t X, + const slong * perm, + const fmpz_poly_mat_t FFLU, const fmpz_poly_mat_t B) +{ + fmpz_poly_t T; + slong i, j, k, m, n; + + n = X->r; + m = X->c; + + fmpz_poly_init(T); + fmpz_poly_mat_set_perm(X, perm, B); + + for (k = 0; k < m; k++) + { + /* Fraction-free forward substitution */ + for (i = 0; i < n - 1; i++) + { + for (j = i + 1; j < n; j++) + { + fmpz_poly_mul(XX(j, k), XX(j, k), LU(i, i)); + fmpz_poly_mul(T, LU(j, i), XX(i, k)); + fmpz_poly_sub(XX(j, k), XX(j, k), T); + if (i > 0) + fmpz_poly_div(XX(j, k), XX(j, k), LU(i-1, i-1)); + } + } + + /* Fraction-free back substitution */ + for (i = n - 2; i >= 0; i--) + { + fmpz_poly_mul(XX(i, k), XX(i, k), LU(n-1, n-1)); + for (j = i + 1; j < n; j++) + { + fmpz_poly_mul(T, XX(j, k), LU(i, j)); + fmpz_poly_sub(XX(i, k), XX(i, k), T); + } + fmpz_poly_div(XX(i, k), XX(i, k), LU(i, i)); + } + } + + fmpz_poly_clear(T); +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/sqr.c b/external/flint-2.4.3/fmpz_poly_mat/sqr.c new file mode 100644 index 0000000..e066053 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/sqr.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + +void +fmpz_poly_mat_sqr(fmpz_poly_mat_t B, const fmpz_poly_mat_t A) +{ + if (A->r < 8) + fmpz_poly_mat_sqr_classical(B, A); + else + fmpz_poly_mat_sqr_KS(B, A); +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/sqr_KS.c b/external/flint-2.4.3/fmpz_poly_mat/sqr_KS.c new file mode 100644 index 0000000..70241f9 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/sqr_KS.c @@ -0,0 +1,80 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" +#include "fmpz_mat.h" + +void +fmpz_poly_mat_sqr_KS(fmpz_poly_mat_t B, const fmpz_poly_mat_t A) +{ + fmpz_mat_t AA, BB; + slong i, j, n; + slong A_len; + int signs; + slong A_bits, bit_size; + + n = A->r; + + if (n == 0) + { + fmpz_poly_mat_zero(B); + return; + } + + A_len = fmpz_poly_mat_max_length(A); + A_bits = fmpz_poly_mat_max_bits(A); + + signs = A_bits < 0; + + bit_size = 2 * FLINT_ABS(A_bits) + signs; + bit_size += FLINT_BIT_COUNT(A_len); + bit_size += FLINT_BIT_COUNT(n); + + fmpz_mat_init(AA, n, n); + fmpz_mat_init(BB, n, n); + + for (i = 0; i < n; i++) + for (j = 0; j < n; j++) + fmpz_poly_bit_pack(fmpz_mat_entry(AA, i, j), + fmpz_poly_mat_entry(A, i, j), bit_size); + + /* Should use fmpz_mat_sqr */ + fmpz_mat_mul(BB, AA, AA); + + for (i = 0; i < n; i++) + for (j = 0; j < n; j++) + if (signs) + fmpz_poly_bit_unpack(fmpz_poly_mat_entry(B, i, j), + fmpz_mat_entry(BB, i, j), bit_size); + else + fmpz_poly_bit_unpack_unsigned(fmpz_poly_mat_entry(B, i, j), + fmpz_mat_entry(BB, i, j), bit_size); + + fmpz_mat_clear(AA); + fmpz_mat_clear(BB); +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/sqr_classical.c b/external/flint-2.4.3/fmpz_poly_mat/sqr_classical.c new file mode 100644 index 0000000..8ff70ad --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/sqr_classical.c @@ -0,0 +1,72 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + +#define E fmpz_poly_mat_entry + +void +fmpz_poly_mat_sqr_classical(fmpz_poly_mat_t B, const fmpz_poly_mat_t A) +{ + slong n = A->r; + + if (n == 0) + return; + + if (n == 1) + { + fmpz_poly_sqr(E(B, 0, 0), E(A, 0, 0)); + return; + } + + if (n == 2) + { + fmpz_poly_t t, u; + + fmpz_poly_init(t); + fmpz_poly_init(u); + + fmpz_poly_add(t, E(A, 0, 0), E(A, 1, 1)); + fmpz_poly_mul(u, E(A, 0, 1), E(A, 1, 0)); + + fmpz_poly_sqr(E(B, 0, 0), E(A, 0, 0)); + fmpz_poly_add(E(B, 0, 0), E(B, 0, 0), u); + + fmpz_poly_sqr(E(B, 1, 1), E(A, 1, 1)); + fmpz_poly_add(E(B, 1, 1), E(B, 1, 1), u); + + fmpz_poly_mul(E(B, 0, 1), E(A, 0, 1), t); + fmpz_poly_mul(E(B, 1, 0), E(A, 1, 0), t); + + fmpz_poly_clear(t); + fmpz_poly_clear(u); + return; + } + + fmpz_poly_mat_mul_classical(B, A, A); +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/sqrlow.c b/external/flint-2.4.3/fmpz_poly_mat/sqrlow.c new file mode 100644 index 0000000..e98fb32 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/sqrlow.c @@ -0,0 +1,86 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + +#define E fmpz_poly_mat_entry + +static __inline__ void +fmpz_poly_addlow(fmpz_poly_t c, const fmpz_poly_t a, + const fmpz_poly_t b, slong len) +{ + fmpz_poly_add(c, a, b); + fmpz_poly_truncate(c, len); +} + +void +fmpz_poly_mat_sqrlow(fmpz_poly_mat_t B, const fmpz_poly_mat_t A, slong len) +{ + slong n = A->r; + + if (n == 0) + return; + + if (len < 1) + { + fmpz_poly_mat_zero(B); + return; + } + + if (n == 1) + { + fmpz_poly_sqrlow(E(B, 0, 0), E(A, 0, 0), len); + return; + } + + if (n == 2) + { + fmpz_poly_t t, u; + + fmpz_poly_init(t); + fmpz_poly_init(u); + + fmpz_poly_addlow(t, E(A, 0, 0), E(A, 1, 1), len); + fmpz_poly_mullow(u, E(A, 0, 1), E(A, 1, 0), len); + + fmpz_poly_sqrlow(E(B, 0, 0), E(A, 0, 0), len); + fmpz_poly_addlow(E(B, 0, 0), E(B, 0, 0), u, len); + + fmpz_poly_sqrlow(E(B, 1, 1), E(A, 1, 1), len); + fmpz_poly_addlow(E(B, 1, 1), E(B, 1, 1), u, len); + + fmpz_poly_mullow(E(B, 0, 1), E(A, 0, 1), t, len); + fmpz_poly_mullow(E(B, 1, 0), E(A, 1, 0), t, len); + + fmpz_poly_clear(t); + fmpz_poly_clear(u); + return; + } + + fmpz_poly_mat_mullow(B, A, A, len); +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/sub.c b/external/flint-2.4.3/fmpz_poly_mat/sub.c new file mode 100644 index 0000000..0775dd4 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/sub.c @@ -0,0 +1,42 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + +void +fmpz_poly_mat_sub(fmpz_poly_mat_t C, + const fmpz_poly_mat_t A, const fmpz_poly_mat_t B) +{ + slong i, j; + + for (i = 0; i < A->r; i++) + for (j = 0; j < A->c; j++) + fmpz_poly_sub(fmpz_poly_mat_entry(C, i, j), + fmpz_poly_mat_entry(A, i, j), + fmpz_poly_mat_entry(B, i, j)); +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/swap.c b/external/flint-2.4.3/fmpz_poly_mat/swap.c new file mode 100644 index 0000000..fc975e6 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/swap.c @@ -0,0 +1,42 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + +void +fmpz_poly_mat_swap(fmpz_poly_mat_t A, fmpz_poly_mat_t B) +{ + if (A != B) + { + fmpz_poly_mat_struct tmp; + + tmp = *A; + *A = *B; + *B = tmp; + } +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/test/t-add.c b/external/flint-2.4.3/fmpz_poly_mat/test/t-add.c new file mode 100644 index 0000000..57f4b2f --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/test/t-add.c @@ -0,0 +1,186 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mat.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + +int +main(void) +{ + slong i; + + FLINT_TEST_INIT(state); + + flint_printf("add...."); + fflush(stdout); + + /* Check evaluation homomorphism */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_mat_t A, B, C; + fmpz_mat_t a, b, c, d; + fmpz_t x; + slong m, n, bits, deg; + + m = n_randint(state, 20); + n = n_randint(state, 20); + deg = 1 + n_randint(state, 10); + bits = 1 + n_randint(state, 100); + + fmpz_poly_mat_init(A, m, n); + fmpz_poly_mat_init(B, m, n); + fmpz_poly_mat_init(C, m, n); + + fmpz_mat_init(a, m, n); + fmpz_mat_init(b, m, n); + fmpz_mat_init(c, m, n); + fmpz_mat_init(d, m, n); + + fmpz_init(x); + + fmpz_poly_mat_randtest(A, state, deg, bits); + fmpz_poly_mat_randtest(B, state, deg, bits); + fmpz_poly_mat_add(C, A, B); + + fmpz_randtest(x, state, 1 + n_randint(state, 100)); + + fmpz_poly_mat_evaluate_fmpz(a, A, x); + fmpz_poly_mat_evaluate_fmpz(b, B, x); + fmpz_poly_mat_evaluate_fmpz(d, C, x); + fmpz_mat_add(c, a, b); + + if (!fmpz_mat_equal(c, d)) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"); + fmpz_poly_mat_print(A, "x"); + flint_printf("B:\n"); + fmpz_poly_mat_print(B, "x"); + flint_printf("C:\n"); + fmpz_poly_mat_print(C, "x"); + flint_printf("\n"); + abort(); + } + + fmpz_poly_mat_clear(A); + fmpz_poly_mat_clear(B); + fmpz_poly_mat_clear(C); + + fmpz_mat_clear(a); + fmpz_mat_clear(b); + fmpz_mat_clear(c); + fmpz_mat_clear(d); + + fmpz_clear(x); + } + + /* Check aliasing C and A */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_mat_t A, B, C; + slong m, n, bits, deg; + + m = n_randint(state, 20); + n = n_randint(state, 20); + deg = 1 + n_randint(state, 10); + bits = 1 + n_randint(state, 100); + + fmpz_poly_mat_init(A, m, n); + fmpz_poly_mat_init(B, m, n); + fmpz_poly_mat_init(C, m, n); + + fmpz_poly_mat_randtest(A, state, deg, bits); + fmpz_poly_mat_randtest(B, state, deg, bits); + + fmpz_poly_mat_add(C, A, B); + fmpz_poly_mat_add(A, A, B); + + if (!fmpz_poly_mat_equal(C, A)) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"); + fmpz_poly_mat_print(A, "x"); + flint_printf("B:\n"); + fmpz_poly_mat_print(B, "x"); + flint_printf("C:\n"); + fmpz_poly_mat_print(C, "x"); + flint_printf("\n"); + abort(); + } + + fmpz_poly_mat_clear(A); + fmpz_poly_mat_clear(B); + fmpz_poly_mat_clear(C); + } + + /* Check aliasing C and B */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_mat_t A, B, C; + slong m, n, bits, deg; + + m = n_randint(state, 20); + n = n_randint(state, 20); + deg = 1 + n_randint(state, 10); + bits = 1 + n_randint(state, 100); + + fmpz_poly_mat_init(A, m, n); + fmpz_poly_mat_init(B, m, n); + fmpz_poly_mat_init(C, m, n); + + fmpz_poly_mat_randtest(A, state, deg, bits); + fmpz_poly_mat_randtest(B, state, deg, bits); + + fmpz_poly_mat_add(C, A, B); + fmpz_poly_mat_add(B, A, B); + + if (!fmpz_poly_mat_equal(C, B)) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"); + fmpz_poly_mat_print(A, "x"); + flint_printf("B:\n"); + fmpz_poly_mat_print(B, "x"); + flint_printf("C:\n"); + fmpz_poly_mat_print(C, "x"); + flint_printf("\n"); + abort(); + } + + fmpz_poly_mat_clear(A); + fmpz_poly_mat_clear(B); + fmpz_poly_mat_clear(C); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/test/t-det.c b/external/flint-2.4.3/fmpz_poly_mat/test/t-det.c new file mode 100644 index 0000000..629b248 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/test/t-det.c @@ -0,0 +1,109 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + + +int +main(void) +{ + slong i; + + FLINT_TEST_INIT(state); + + flint_printf("det...."); + fflush(stdout); + + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_mat_t A, B, C; + fmpz_poly_t a, b, ab, c; + slong n, bits, deg; + float density; + + n = n_randint(state, 10); + deg = 1 + n_randint(state, 5); + bits = 1 + n_randint(state, 100); + density = n_randint(state, 100) * 0.01; + + fmpz_poly_mat_init(A, n, n); + fmpz_poly_mat_init(B, n, n); + fmpz_poly_mat_init(C, n, n); + + fmpz_poly_init(a); + fmpz_poly_init(b); + fmpz_poly_init(ab); + fmpz_poly_init(c); + + fmpz_poly_mat_randtest_sparse(A, state, deg, bits, density); + fmpz_poly_mat_randtest_sparse(B, state, deg, bits, density); + fmpz_poly_mat_mul(C, A, B); + + fmpz_poly_mat_det(a, A); + fmpz_poly_mat_det(b, B); + fmpz_poly_mat_det(c, C); + fmpz_poly_mul(ab, a, b); + + if (!fmpz_poly_equal(c, ab)) + { + flint_printf("FAIL:\n"); + flint_printf("determinants don't agree!\n"); + flint_printf("A:\n"); + fmpz_poly_mat_print(A, "x"); + flint_printf("B:\n"); + fmpz_poly_mat_print(B, "x"); + flint_printf("C:\n"); + fmpz_poly_mat_print(C, "x"); + flint_printf("det(A):\n"); + fmpz_poly_print_pretty(a, "x"); + flint_printf("\ndet(B):\n"); + fmpz_poly_print_pretty(b, "x"); + flint_printf("\ndet(C):\n"); + fmpz_poly_print_pretty(c, "x"); + flint_printf("\ndet(A)*det(B):\n"); + fmpz_poly_print_pretty(ab, "x"); + flint_printf("\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + fmpz_poly_clear(ab); + fmpz_poly_clear(c); + + fmpz_poly_mat_clear(A); + fmpz_poly_mat_clear(B); + fmpz_poly_mat_clear(C); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/test/t-det_interpolate.c b/external/flint-2.4.3/fmpz_poly_mat/test/t-det_interpolate.c new file mode 100644 index 0000000..83196d0 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/test/t-det_interpolate.c @@ -0,0 +1,87 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + + +int +main(void) +{ + slong i; + + FLINT_TEST_INIT(state); + + flint_printf("det_interpolate...."); + fflush(stdout); + + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_mat_t A; + fmpz_poly_t a, b; + slong n, bits, deg; + + n = n_randint(state, 10); + deg = 1 + n_randint(state, 5); + bits = 1 + n_randint(state, 100); + + fmpz_poly_mat_init(A, n, n); + + fmpz_poly_init(a); + fmpz_poly_init(b); + + fmpz_poly_mat_randtest(A, state, deg, bits); + + fmpz_poly_mat_det(a, A); + fmpz_poly_mat_det_interpolate(b, A); + + if (!fmpz_poly_equal(a, b)) + { + flint_printf("FAIL:\n"); + flint_printf("determinants don't agree!\n"); + flint_printf("A:\n"); + fmpz_poly_mat_print(A, "x"); + flint_printf("det(A):\n"); + fmpz_poly_print_pretty(a, "x"); + flint_printf("\ndet_interpolate(A):\n"); + fmpz_poly_print_pretty(b, "x"); + flint_printf("\n"); + abort(); + } + + fmpz_poly_clear(a); + fmpz_poly_clear(b); + + fmpz_poly_mat_clear(A); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/test/t-init_clear.c b/external/flint-2.4.3/fmpz_poly_mat/test/t-init_clear.c new file mode 100644 index 0000000..605b184 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/test/t-init_clear.c @@ -0,0 +1,67 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("init/clear...."); + fflush(stdout); + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_poly_mat_t a; + slong j, k; + slong rows = n_randint(state, 100); + slong cols = n_randint(state, 100); + + fmpz_poly_mat_init(a, rows, cols); + + for (j = 0; j < rows; j++) + for (k = 0; k < cols; k++) + fmpz_poly_zero(fmpz_poly_mat_entry(a, j, k)); + + fmpz_poly_mat_clear(a); + } + + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/test/t-inv.c b/external/flint-2.4.3/fmpz_poly_mat/test/t-inv.c new file mode 100644 index 0000000..7f5e527 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/test/t-inv.c @@ -0,0 +1,163 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + + +int +main(void) +{ + slong i; + + FLINT_TEST_INIT(state); + + flint_printf("inv...."); + fflush(stdout); + + /* Test aliasing */ + for (i = 0; i < 40 * flint_test_multiplier(); i++) + { + fmpz_poly_mat_t A, Ainv; + fmpz_poly_t den1, den2; + slong n, bits, deg; + float density; + int ns1, ns2; + int result; + + n = n_randint(state, 8); + deg = 1 + n_randint(state, 5); + bits = 1 + n_randint(state, 100); + density = n_randint(state, 100) * 0.01; + + fmpz_poly_mat_init(A, n, n); + fmpz_poly_mat_init(Ainv, n, n); + fmpz_poly_init(den1); + fmpz_poly_init(den2); + + fmpz_poly_mat_randtest_sparse(A, state, deg, bits, density); + + ns1 = fmpz_poly_mat_inv(Ainv, den1, A); + ns2 = fmpz_poly_mat_inv(A, den2, A); + + result = ns1 == ns2; + + if (result && ns1 != 0) + { + result = fmpz_poly_equal(den1, den2) && + fmpz_poly_mat_equal(A, Ainv); + } + + if (!result) + { + flint_printf("FAIL (aliasing)!\n"); + fmpz_poly_mat_print(A, "x"); flint_printf("\n"); + fmpz_poly_mat_print(Ainv, "x"); flint_printf("\n"); + abort(); + } + + fmpz_poly_mat_clear(A); + fmpz_poly_mat_clear(Ainv); + fmpz_poly_clear(den1); + fmpz_poly_clear(den2); + } + + /* Check A^(-1) = A = 1 */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_mat_t A, Ainv, B, Iden; + fmpz_poly_t den, det; + slong n, bits, deg; + float density; + int nonsingular; + + n = n_randint(state, 10); + deg = 1 + n_randint(state, 5); + bits = 1 + n_randint(state, 100); + density = n_randint(state, 100) * 0.01; + + fmpz_poly_mat_init(A, n, n); + fmpz_poly_mat_init(Ainv, n, n); + fmpz_poly_mat_init(B, n, n); + fmpz_poly_mat_init(Iden, n, n); + fmpz_poly_init(den); + fmpz_poly_init(det); + + fmpz_poly_mat_randtest_sparse(A, state, deg, bits, density); + nonsingular = fmpz_poly_mat_inv(Ainv, den, A); + fmpz_poly_mat_det_interpolate(det, A); + + if (n == 0) + { + if (nonsingular == 0 || !fmpz_poly_is_one(den)) + { + flint_printf("FAIL: expected empty matrix to pass\n"); + abort(); + } + } + else + { + if (!fmpz_poly_equal(den, det)) + { + fmpz_poly_neg(det, det); + flint_printf("FAIL: den != det(A)\n"); + abort(); + } + + fmpz_poly_mat_mul(B, Ainv, A); + fmpz_poly_mat_one(Iden); + fmpz_poly_mat_scalar_mul_fmpz_poly(Iden, Iden, den); + + if (!fmpz_poly_mat_equal(B, Iden)) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"); + fmpz_poly_mat_print(A, "x"); + flint_printf("Ainv:\n"); + fmpz_poly_mat_print(Ainv, "x"); + flint_printf("B:\n"); + fmpz_poly_mat_print(B, "x"); + flint_printf("den:\n"); + fmpz_poly_print_pretty(den, "x"); + abort(); + } + } + + fmpz_poly_clear(den); + fmpz_poly_clear(det); + fmpz_poly_mat_clear(A); + fmpz_poly_mat_clear(Ainv); + fmpz_poly_mat_clear(B); + fmpz_poly_mat_clear(Iden); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/test/t-mul.c b/external/flint-2.4.3/fmpz_poly_mat/test/t-mul.c new file mode 100644 index 0000000..e67c3bb --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/test/t-mul.c @@ -0,0 +1,191 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mat.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + +int +main(void) +{ + slong i; + + FLINT_TEST_INIT(state); + + flint_printf("mul...."); + fflush(stdout); + + /* Check evaluation homomorphism */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_mat_t A, B, C; + fmpz_mat_t a, b, c, d; + fmpz_t x; + slong m, n, k, bits, deg; + + m = n_randint(state, 20); + n = n_randint(state, 20); + k = n_randint(state, 20); + deg = 1 + n_randint(state, 10); + bits = 1 + n_randint(state, 100); + + fmpz_poly_mat_init(A, m, n); + fmpz_poly_mat_init(B, n, k); + fmpz_poly_mat_init(C, m, k); + + fmpz_mat_init(a, m, n); + fmpz_mat_init(b, n, k); + fmpz_mat_init(c, m, k); + fmpz_mat_init(d, m, k); + + fmpz_init(x); + + fmpz_poly_mat_randtest(A, state, deg, bits); + fmpz_poly_mat_randtest(B, state, deg, bits); + fmpz_poly_mat_randtest(C, state, deg, bits); /* noise in output */ + + fmpz_poly_mat_mul(C, A, B); + + fmpz_randtest(x, state, 1 + n_randint(state, 100)); + + fmpz_poly_mat_evaluate_fmpz(a, A, x); + fmpz_poly_mat_evaluate_fmpz(b, B, x); + fmpz_poly_mat_evaluate_fmpz(d, C, x); + fmpz_mat_mul(c, a, b); + + if (!fmpz_mat_equal(c, d)) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"); + fmpz_poly_mat_print(A, "x"); + flint_printf("B:\n"); + fmpz_poly_mat_print(B, "x"); + flint_printf("C:\n"); + fmpz_poly_mat_print(C, "x"); + flint_printf("\n"); + abort(); + } + + fmpz_poly_mat_clear(A); + fmpz_poly_mat_clear(B); + fmpz_poly_mat_clear(C); + + fmpz_mat_clear(a); + fmpz_mat_clear(b); + fmpz_mat_clear(c); + fmpz_mat_clear(d); + + fmpz_clear(x); + } + + /* Check aliasing C and A */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_mat_t A, B, C; + slong m, n, bits, deg; + + m = n_randint(state, 20); + n = n_randint(state, 20); + deg = 1 + n_randint(state, 10); + bits = 1 + n_randint(state, 100); + + fmpz_poly_mat_init(A, m, n); + fmpz_poly_mat_init(B, n, n); + fmpz_poly_mat_init(C, m, n); + + fmpz_poly_mat_randtest(A, state, deg, bits); + fmpz_poly_mat_randtest(B, state, deg, bits); + fmpz_poly_mat_randtest(C, state, deg, bits); /* noise in output */ + + fmpz_poly_mat_mul(C, A, B); + fmpz_poly_mat_mul(A, A, B); + + if (!fmpz_poly_mat_equal(C, A)) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"); + fmpz_poly_mat_print(A, "x"); + flint_printf("B:\n"); + fmpz_poly_mat_print(B, "x"); + flint_printf("C:\n"); + fmpz_poly_mat_print(C, "x"); + flint_printf("\n"); + abort(); + } + + fmpz_poly_mat_clear(A); + fmpz_poly_mat_clear(B); + fmpz_poly_mat_clear(C); + } + + /* Check aliasing C and B */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_mat_t A, B, C; + slong m, n, bits, deg; + + m = n_randint(state, 20); + n = n_randint(state, 20); + deg = 1 + n_randint(state, 10); + bits = 1 + n_randint(state, 100); + + fmpz_poly_mat_init(A, m, m); + fmpz_poly_mat_init(B, m, n); + fmpz_poly_mat_init(C, m, n); + + fmpz_poly_mat_randtest(A, state, deg, bits); + fmpz_poly_mat_randtest(B, state, deg, bits); + fmpz_poly_mat_randtest(C, state, deg, bits); /* noise in output */ + + fmpz_poly_mat_mul(C, A, B); + fmpz_poly_mat_mul(B, A, B); + + if (!fmpz_poly_mat_equal(C, B)) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"); + fmpz_poly_mat_print(A, "x"); + flint_printf("B:\n"); + fmpz_poly_mat_print(B, "x"); + flint_printf("C:\n"); + fmpz_poly_mat_print(C, "x"); + flint_printf("\n"); + abort(); + } + + fmpz_poly_mat_clear(A); + fmpz_poly_mat_clear(B); + fmpz_poly_mat_clear(C); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/test/t-mul_KS.c b/external/flint-2.4.3/fmpz_poly_mat/test/t-mul_KS.c new file mode 100644 index 0000000..865e0f7 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/test/t-mul_KS.c @@ -0,0 +1,182 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + + +int +main(void) +{ + slong i; + + FLINT_TEST_INIT(state); + + flint_printf("mul_KS...."); + fflush(stdout); + + + + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_mat_t A, B, C, D; + slong m, n, k, bits, deg; + + m = n_randint(state, 15); + n = n_randint(state, 15); + k = n_randint(state, 15); + deg = 1 + n_randint(state, 15); + bits = 1 + n_randint(state, 150); + + fmpz_poly_mat_init(A, m, n); + fmpz_poly_mat_init(B, n, k); + fmpz_poly_mat_init(C, m, k); + fmpz_poly_mat_init(D, m, k); + + if (n_randint(state, 2)) + fmpz_poly_mat_randtest(A, state, deg, bits); + else + fmpz_poly_mat_randtest_unsigned(A, state, deg, bits); + + if (n_randint(state, 2)) + fmpz_poly_mat_randtest(B, state, deg, bits); + else + fmpz_poly_mat_randtest_unsigned(B, state, deg, bits); + + fmpz_poly_mat_randtest(C, state, deg, bits); /* noise in output */ + + fmpz_poly_mat_mul_classical(C, A, B); + fmpz_poly_mat_mul_KS(D, A, B); + + if (!fmpz_poly_mat_equal(C, D)) + { + flint_printf("FAIL:\n"); + flint_printf("products don't agree!\n"); + flint_printf("A:\n"); + fmpz_poly_mat_print(A, "x"); + flint_printf("B:\n"); + fmpz_poly_mat_print(B, "x"); + flint_printf("C:\n"); + fmpz_poly_mat_print(C, "x"); + flint_printf("D:\n"); + fmpz_poly_mat_print(D, "x"); + flint_printf("\n"); + abort(); + } + + fmpz_poly_mat_clear(A); + fmpz_poly_mat_clear(B); + fmpz_poly_mat_clear(C); + fmpz_poly_mat_clear(D); + } + + /* Check aliasing C and A */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + fmpz_poly_mat_t A, B, C; + slong m, n, bits, deg; + + m = n_randint(state, 20); + n = n_randint(state, 20); + deg = 1 + n_randint(state, 10); + bits = 1 + n_randint(state, 100); + + fmpz_poly_mat_init(A, m, n); + fmpz_poly_mat_init(B, n, n); + fmpz_poly_mat_init(C, m, n); + + fmpz_poly_mat_randtest(A, state, deg, bits); + fmpz_poly_mat_randtest(B, state, deg, bits); + fmpz_poly_mat_randtest(C, state, deg, bits); /* noise in output */ + + fmpz_poly_mat_mul_KS(C, A, B); + fmpz_poly_mat_mul_KS(A, A, B); + + if (!fmpz_poly_mat_equal(C, A)) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"); + fmpz_poly_mat_print(A, "x"); + flint_printf("B:\n"); + fmpz_poly_mat_print(B, "x"); + flint_printf("C:\n"); + fmpz_poly_mat_print(C, "x"); + flint_printf("\n"); + abort(); + } + + fmpz_poly_mat_clear(A); + fmpz_poly_mat_clear(B); + fmpz_poly_mat_clear(C); + } + + /* Check aliasing C and B */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + fmpz_poly_mat_t A, B, C; + slong m, n, bits, deg; + + m = n_randint(state, 20); + n = n_randint(state, 20); + deg = 1 + n_randint(state, 10); + bits = 1 + n_randint(state, 100); + + fmpz_poly_mat_init(A, m, m); + fmpz_poly_mat_init(B, m, n); + fmpz_poly_mat_init(C, m, n); + + fmpz_poly_mat_randtest(A, state, deg, bits); + fmpz_poly_mat_randtest(B, state, deg, bits); + fmpz_poly_mat_randtest(C, state, deg, bits); /* noise in output */ + + fmpz_poly_mat_mul_KS(C, A, B); + fmpz_poly_mat_mul_KS(B, A, B); + + if (!fmpz_poly_mat_equal(C, B)) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"); + fmpz_poly_mat_print(A, "x"); + flint_printf("B:\n"); + fmpz_poly_mat_print(B, "x"); + flint_printf("C:\n"); + fmpz_poly_mat_print(C, "x"); + flint_printf("\n"); + abort(); + } + + fmpz_poly_mat_clear(A); + fmpz_poly_mat_clear(B); + fmpz_poly_mat_clear(C); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/test/t-mullow.c b/external/flint-2.4.3/fmpz_poly_mat/test/t-mullow.c new file mode 100644 index 0000000..25fdb6b --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/test/t-mullow.c @@ -0,0 +1,178 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mat.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + +int +main(void) +{ + slong i; + + FLINT_TEST_INIT(state); + + flint_printf("mullow...."); + fflush(stdout); + + /* Compare with mul */ + for (i = 0; i < 30 * flint_test_multiplier(); i++) + { + fmpz_poly_mat_t A, B, C, D; + slong m, n, k, bits, deg, len; + + m = n_randint(state, 20); + n = n_randint(state, 20); + k = n_randint(state, 20); + deg = 1 + n_randint(state, 10); + bits = 1 + n_randint(state, 100); + len = n_randint(state, 10); + + fmpz_poly_mat_init(A, m, n); + fmpz_poly_mat_init(B, n, k); + fmpz_poly_mat_init(C, m, k); + fmpz_poly_mat_init(D, m, k); + + fmpz_poly_mat_randtest(A, state, deg, bits); + fmpz_poly_mat_randtest(B, state, deg, bits); + fmpz_poly_mat_randtest(C, state, deg, bits); /* noise in output */ + fmpz_poly_mat_randtest(D, state, deg, bits); /* noise in output */ + + fmpz_poly_mat_mullow(C, A, B, len); + fmpz_poly_mat_mul(D, A, B); + fmpz_poly_mat_truncate(D, len); + + if (!fmpz_poly_mat_equal(C, D)) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"); + fmpz_poly_mat_print(A, "x"); + flint_printf("B:\n"); + fmpz_poly_mat_print(B, "x"); + flint_printf("C:\n"); + fmpz_poly_mat_print(C, "x"); + flint_printf("D:\n"); + fmpz_poly_mat_print(D, "x"); + flint_printf("\n"); + abort(); + } + + fmpz_poly_mat_clear(A); + fmpz_poly_mat_clear(B); + fmpz_poly_mat_clear(C); + fmpz_poly_mat_clear(D); + } + + /* Check aliasing C and A */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + fmpz_poly_mat_t A, B, C; + slong m, n, bits, deg, len; + + m = n_randint(state, 20); + n = n_randint(state, 20); + deg = 1 + n_randint(state, 10); + bits = 1 + n_randint(state, 100); + len = n_randint(state, 10); + + fmpz_poly_mat_init(A, m, n); + fmpz_poly_mat_init(B, n, n); + fmpz_poly_mat_init(C, m, n); + + fmpz_poly_mat_randtest(A, state, deg, bits); + fmpz_poly_mat_randtest(B, state, deg, bits); + fmpz_poly_mat_randtest(C, state, deg, bits); /* noise in output */ + + fmpz_poly_mat_mullow(C, A, B, len); + fmpz_poly_mat_mullow(A, A, B, len); + + if (!fmpz_poly_mat_equal(C, A)) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"); + fmpz_poly_mat_print(A, "x"); + flint_printf("B:\n"); + fmpz_poly_mat_print(B, "x"); + flint_printf("C:\n"); + fmpz_poly_mat_print(C, "x"); + flint_printf("\n"); + abort(); + } + + fmpz_poly_mat_clear(A); + fmpz_poly_mat_clear(B); + fmpz_poly_mat_clear(C); + } + + /* Check aliasing C and B */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + fmpz_poly_mat_t A, B, C; + slong m, n, bits, deg, len; + + m = n_randint(state, 20); + n = n_randint(state, 20); + deg = 1 + n_randint(state, 10); + bits = 1 + n_randint(state, 100); + len = n_randint(state, 10); + + fmpz_poly_mat_init(A, m, m); + fmpz_poly_mat_init(B, m, n); + fmpz_poly_mat_init(C, m, n); + + fmpz_poly_mat_randtest(A, state, deg, bits); + fmpz_poly_mat_randtest(B, state, deg, bits); + fmpz_poly_mat_randtest(C, state, deg, bits); /* noise in output */ + + fmpz_poly_mat_mullow(C, A, B, len); + fmpz_poly_mat_mullow(B, A, B, len); + + if (!fmpz_poly_mat_equal(C, B)) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"); + fmpz_poly_mat_print(A, "x"); + flint_printf("B:\n"); + fmpz_poly_mat_print(B, "x"); + flint_printf("C:\n"); + fmpz_poly_mat_print(C, "x"); + flint_printf("\n"); + abort(); + } + + fmpz_poly_mat_clear(A); + fmpz_poly_mat_clear(B); + fmpz_poly_mat_clear(C); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/test/t-neg.c b/external/flint-2.4.3/fmpz_poly_mat/test/t-neg.c new file mode 100644 index 0000000..ce8de1c --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/test/t-neg.c @@ -0,0 +1,134 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mat.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + +int +main(void) +{ + slong i; + + FLINT_TEST_INIT(state); + + flint_printf("neg...."); + fflush(stdout); + + /* Check evaluation homomorphism */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_mat_t A, B; + fmpz_mat_t a, b, c; + fmpz_t x; + slong m, n, bits, deg; + + m = n_randint(state, 20); + n = n_randint(state, 20); + deg = 1 + n_randint(state, 10); + bits = 1 + n_randint(state, 100); + + fmpz_poly_mat_init(A, m, n); + fmpz_poly_mat_init(B, m, n); + + fmpz_mat_init(a, m, n); + fmpz_mat_init(b, m, n); + fmpz_mat_init(c, m, n); + + fmpz_init(x); + + fmpz_poly_mat_randtest(A, state, deg, bits); + fmpz_poly_mat_neg(B, A); + + fmpz_randtest(x, state, 1 + n_randint(state, 100)); + + fmpz_poly_mat_evaluate_fmpz(a, A, x); + fmpz_poly_mat_evaluate_fmpz(b, B, x); + fmpz_mat_neg(c, a); + + if (!fmpz_mat_equal(b, c)) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"); + fmpz_poly_mat_print(A, "x"); + flint_printf("B:\n"); + fmpz_poly_mat_print(B, "x"); + flint_printf("\n"); + abort(); + } + + fmpz_poly_mat_clear(A); + fmpz_poly_mat_clear(B); + + fmpz_mat_clear(a); + fmpz_mat_clear(b); + fmpz_mat_clear(c); + + fmpz_clear(x); + } + + /* Check aliasing B and A */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_mat_t A, B; + slong m, n, bits, deg; + + m = n_randint(state, 20); + n = n_randint(state, 20); + deg = 1 + n_randint(state, 10); + bits = 1 + n_randint(state, 100); + + fmpz_poly_mat_init(A, m, n); + fmpz_poly_mat_init(B, m, n); + + fmpz_poly_mat_randtest(A, state, deg, bits); + + fmpz_poly_mat_neg(B, A); + fmpz_poly_mat_neg(A, A); + + if (!fmpz_poly_mat_equal(B, A)) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"); + fmpz_poly_mat_print(A, "x"); + flint_printf("B:\n"); + fmpz_poly_mat_print(B, "x"); + flint_printf("\n"); + abort(); + } + + fmpz_poly_mat_clear(A); + fmpz_poly_mat_clear(B); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/test/t-nullspace.c b/external/flint-2.4.3/fmpz_poly_mat/test/t-nullspace.c new file mode 100644 index 0000000..038a127 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/test/t-nullspace.c @@ -0,0 +1,101 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + + +int +main(void) +{ + slong i; + + FLINT_TEST_INIT(state); + + flint_printf("nullspace...."); + fflush(stdout); + + + + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_mat_t A, N, AN; + slong n, m, bits, deg, rank, nullity; + float density; + + m = n_randint(state, 13); + n = n_randint(state, 13); + deg = 1 + n_randint(state, 5); + bits = 1 + n_randint(state, 100); + density = n_randint(state, 100) * 0.01; + + fmpz_poly_mat_init(A, m, n); + fmpz_poly_mat_init(N, n, n); + fmpz_poly_mat_init(AN, m, n); + + fmpz_poly_mat_randtest_sparse(A, state, deg, bits, density); + + rank = fmpz_poly_mat_rank(A); + nullity = fmpz_poly_mat_nullspace(N, A); + + if (nullity + rank != n) + { + flint_printf("FAIL: wrong nullity!\n"); + flint_printf("rank = %wd\n", rank); + flint_printf("nullity = %wd\n", nullity); + fmpz_poly_mat_print(A, "x"); + flint_printf("\n"); + fmpz_poly_mat_print(N, "x"); + flint_printf("\n"); + abort(); + } + + if (fmpz_poly_mat_rank(N) != nullity) + { + flint_printf("FAIL: wrong rank(N) != nullity!\n"); + abort(); + } + + fmpz_poly_mat_mul(AN, A, N); + + if (!fmpz_poly_mat_is_zero(AN)) + { + flint_printf("FAIL: A * N != 0\n"); + abort(); + } + + fmpz_poly_mat_clear(A); + fmpz_poly_mat_clear(N); + fmpz_poly_mat_clear(AN); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/test/t-one.c b/external/flint-2.4.3/fmpz_poly_mat/test/t-one.c new file mode 100644 index 0000000..05dd531 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/test/t-one.c @@ -0,0 +1,90 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mat.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + +int +main(void) +{ + int iter; + + FLINT_TEST_INIT(state); + + flint_printf("one/is_one...."); + fflush(stdout); + + for (iter = 0; iter < 100 * flint_test_multiplier(); iter++) + { + fmpz_poly_mat_t A; + slong m, n; + + m = n_randint(state, 10); + n = n_randint(state, 10); + + fmpz_poly_mat_init(A, m, n); + fmpz_poly_mat_randtest(A, state, n_randint(state, 5), + n_randint(state, 100)); + fmpz_poly_mat_one(A); + + if (!fmpz_poly_mat_is_one(A)) + { + flint_printf("FAIL: expected matrix to be one\n"); + abort(); + } + + if (m > 0 && n > 0) + { + m = n_randint(state, m); + n = n_randint(state, n); + + if (m != n) + fmpz_poly_randtest_not_zero(fmpz_poly_mat_entry(A, m, n), + state, 5, 5); + else + do { fmpz_poly_randtest_not_zero(fmpz_poly_mat_entry(A, m, n), + state, 5, 5); } + while (fmpz_poly_is_one(fmpz_poly_mat_entry(A, m, n))); + + if (fmpz_poly_mat_is_one(A)) + { + flint_printf("FAIL: expected matrix not to be one\n"); + abort(); + } + } + + fmpz_poly_mat_clear(A); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/test/t-pow.c b/external/flint-2.4.3/fmpz_poly_mat/test/t-pow.c new file mode 100644 index 0000000..75eda0a --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/test/t-pow.c @@ -0,0 +1,124 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mat.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + +int +main(void) +{ + slong i; + + FLINT_TEST_INIT(state); + + flint_printf("pow...."); + fflush(stdout); + + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_mat_t A, B, C; + slong m, j, exp, bits, deg; + + m = n_randint(state, 6); + deg = 1 + n_randint(state, 6); + bits = 1 + n_randint(state, 100); + exp = n_randint(state, 20); + + fmpz_poly_mat_init(A, m, m); + fmpz_poly_mat_init(B, m, m); + fmpz_poly_mat_init(C, m, m); + + fmpz_poly_mat_randtest(A, state, deg, bits); + + fmpz_poly_mat_pow(B, A, exp); + + fmpz_poly_mat_one(C); + for (j = 0; j < exp; j++) + fmpz_poly_mat_mul(C, C, A); + + if (!fmpz_poly_mat_equal(C, B)) + { + flint_printf("FAIL:\n"); + flint_printf("exp = %wd\n", exp); + flint_printf("A:\n"); + fmpz_poly_mat_print(A, "x"); + flint_printf("B:\n"); + fmpz_poly_mat_print(B, "x"); + flint_printf("C:\n"); + fmpz_poly_mat_print(C, "x"); + flint_printf("\n"); + abort(); + } + + fmpz_poly_mat_clear(A); + fmpz_poly_mat_clear(B); + fmpz_poly_mat_clear(C); + } + + /* Check aliasing B and A */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_mat_t A, B; + slong m, exp, bits, deg; + + m = n_randint(state, 6); + deg = 1 + n_randint(state, 6); + bits = 1 + n_randint(state, 100); + exp = n_randint(state, 20); + + fmpz_poly_mat_init(A, m, m); + fmpz_poly_mat_init(B, m, m); + + fmpz_poly_mat_randtest(A, state, deg, bits); + + fmpz_poly_mat_pow(B, A, exp); + fmpz_poly_mat_pow(A, A, exp); + + if (!fmpz_poly_mat_equal(A, B)) + { + flint_printf("FAIL (aliasing)\n"); + flint_printf("exp = %wd\n", exp); + flint_printf("A:\n"); + fmpz_poly_mat_print(A, "x"); + flint_printf("B:\n"); + fmpz_poly_mat_print(B, "x"); + flint_printf("\n"); + abort(); + } + + fmpz_poly_mat_clear(A); + fmpz_poly_mat_clear(B); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/test/t-pow_trunc.c b/external/flint-2.4.3/fmpz_poly_mat/test/t-pow_trunc.c new file mode 100644 index 0000000..bc707fe --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/test/t-pow_trunc.c @@ -0,0 +1,126 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mat.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + +int +main(void) +{ + slong i; + + FLINT_TEST_INIT(state); + + flint_printf("pow_trunc...."); + fflush(stdout); + + /* Compare with pow */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_mat_t A, B, C; + slong n, exp, bits, deg, len; + + n = n_randint(state, 10); + exp = n_randint(state, 15); + deg = 1 + n_randint(state, 10); + bits = 1 + n_randint(state, 100); + len = n_randint(state, 10); + + fmpz_poly_mat_init(A, n, n); + fmpz_poly_mat_init(B, n, n); + fmpz_poly_mat_init(C, n, n); + + fmpz_poly_mat_randtest(A, state, deg, bits); + fmpz_poly_mat_randtest(B, state, deg, bits); /* noise in output */ + fmpz_poly_mat_randtest(C, state, deg, bits); /* noise in output */ + + fmpz_poly_mat_pow_trunc(B, A, exp, len); + fmpz_poly_mat_pow(C, A, exp); + fmpz_poly_mat_truncate(C, len); + + if (!fmpz_poly_mat_equal(B, C)) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"); + fmpz_poly_mat_print(A, "x"); + flint_printf("B:\n"); + fmpz_poly_mat_print(B, "x"); + flint_printf("C:\n"); + fmpz_poly_mat_print(C, "x"); + flint_printf("\n"); + abort(); + } + + fmpz_poly_mat_clear(A); + fmpz_poly_mat_clear(B); + fmpz_poly_mat_clear(C); + } + + /* Check aliasing */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + fmpz_poly_mat_t A, B; + slong n, exp, bits, deg, len; + + n = n_randint(state, 10); + exp = n_randint(state, 15); + deg = 1 + n_randint(state, 10); + bits = 1 + n_randint(state, 100); + len = n_randint(state, 10); + + fmpz_poly_mat_init(A, n, n); + fmpz_poly_mat_init(B, n, n); + + fmpz_poly_mat_randtest(A, state, deg, bits); + fmpz_poly_mat_randtest(B, state, deg, bits); + + fmpz_poly_mat_pow_trunc(B, A, exp, len); + fmpz_poly_mat_pow_trunc(A, A, exp, len); + + if (!fmpz_poly_mat_equal(B, A)) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"); + fmpz_poly_mat_print(A, "x"); + flint_printf("B:\n"); + fmpz_poly_mat_print(B, "x"); + flint_printf("\n"); + abort(); + } + + fmpz_poly_mat_clear(A); + fmpz_poly_mat_clear(B); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/test/t-prod.c b/external/flint-2.4.3/fmpz_poly_mat/test/t-prod.c new file mode 100644 index 0000000..13a1c1b --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/test/t-prod.c @@ -0,0 +1,94 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mat.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + +int +main(void) +{ + slong i; + + FLINT_TEST_INIT(state); + + flint_printf("prod...."); + fflush(stdout); + + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + fmpz_poly_mat_t A, B, *V; + slong m, j, count, bits, deg; + float density; + + m = n_randint(state, 6); + deg = 1 + n_randint(state, 6); + bits = 1 + n_randint(state, 100); + count = n_randint(state, 20); + density = n_randint(state, 100) * 0.01; + + fmpz_poly_mat_init(A, m, m); + fmpz_poly_mat_init(B, m, m); + + V = flint_malloc(sizeof(fmpz_poly_mat_t) * count); + for (j = 0; j < count; j++) + { + fmpz_poly_mat_init(V[j], m, m); + fmpz_poly_mat_randtest_sparse(V[j], state, deg, bits, density); + } + + fmpz_poly_mat_prod(A, V, count); + + fmpz_poly_mat_one(B); + for (j = 0; j < count; j++) + fmpz_poly_mat_mul(B, B, V[j]); + + if (!fmpz_poly_mat_equal(A, B)) + { + flint_printf("FAIL:\n"); + flint_printf("count = %wd\n", count); + flint_printf("A:\n"); + fmpz_poly_mat_print(A, "x"); + flint_printf("B:\n"); + fmpz_poly_mat_print(B, "x"); + abort(); + } + + fmpz_poly_mat_clear(A); + fmpz_poly_mat_clear(B); + for (j = 0; j < count; j++) + fmpz_poly_mat_clear(V[j]); + flint_free(V); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/test/t-rank.c b/external/flint-2.4.3/fmpz_poly_mat/test/t-rank.c new file mode 100644 index 0000000..6323b16 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/test/t-rank.c @@ -0,0 +1,95 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz_mat.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + + +int +main(void) +{ + slong i; + + FLINT_TEST_INIT(state); + + flint_printf("rank...."); + fflush(stdout); + + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_mat_t A; + fmpz_mat_t Ax; + fmpz_t x; + slong j, m, n, bits, deg, rank, zrank; + float density; + + m = n_randint(state, 15); + n = n_randint(state, 15); + deg = 1 + n_randint(state, 5); + bits = 1 + n_randint(state, 100); + density = n_randint(state, 100) * 0.01; + + fmpz_poly_mat_init(A, m, n); + fmpz_mat_init(Ax, m, n); + fmpz_init(x); + + fmpz_poly_mat_randtest_sparse(A, state, deg, bits, density); + + /* Probabilistic rank computation */ + zrank = 0; + for (j = 0; j < 5; j++) + { + slong r; + fmpz_randbits(x, state, 15); + fmpz_poly_mat_evaluate_fmpz(Ax, A, x); + r = fmpz_mat_rank(Ax); + zrank = FLINT_MAX(zrank, r); + } + + rank = fmpz_poly_mat_rank(A); + + if (rank != zrank) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"); + fmpz_poly_mat_print(A, "x"); + flint_printf("Computed rank: %wd (zrank = %wd)\n", rank, zrank); + abort(); + } + + fmpz_clear(x); + fmpz_mat_clear(Ax); + fmpz_poly_mat_clear(A); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/test/t-rref.c b/external/flint-2.4.3/fmpz_poly_mat/test/t-rref.c new file mode 100644 index 0000000..ff73e1b --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/test/t-rref.c @@ -0,0 +1,179 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010-2012 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz_poly_mat.h" +#include "perm.h" +#include "ulong_extras.h" + +/* checks that the rref has the right form */ +int check_rref(const fmpz_poly_mat_t A, const fmpz_poly_t den, slong rank) +{ + slong i, j, k, prev_pivot; + + /* bottom should be zero */ + for (i = rank; i < A->r; i++) + for (j = 0; j < A->c; j++) + if (!fmpz_poly_is_zero(fmpz_poly_mat_entry(A, i, j))) + return 0; + + prev_pivot = -1; + + for (i = 0; i < rank; i++) + { + for (j = 0; j < A->c; j++) + { + if (!fmpz_poly_is_zero(fmpz_poly_mat_entry(A, i, j))) + { + /* pivot should have a higher column index than previous */ + if (j <= prev_pivot) + return 0; + + /* column should be 0 ... 0 1 0 ... 0 */ + for (k = 0; k < rank; k++) + { + if (i == k && !fmpz_poly_equal(fmpz_poly_mat_entry(A, k, j), den)) + return 0; + if (i != k && !fmpz_poly_is_zero(fmpz_poly_mat_entry(A, k, j))) + return 0; + } + + prev_pivot = j; + break; + } + } + } + + return 1; +} + +int +main(void) +{ + slong iter; + FLINT_TEST_INIT(state); + + flint_printf("rref...."); + fflush(stdout); + + + + for (iter = 0; iter < 200 * flint_test_multiplier(); iter++) + { + fmpz_poly_mat_t A, R, B, R2; + fmpz_poly_t den, c, den2; + slong j, k, m, n, deg, bits, rank1, rank2; + slong *perm; + float density; + int equal; + + m = n_randint(state, 10); + n = n_randint(state, 10); + deg = 1 + n_randint(state, 5); + bits = 1 + n_randint(state, 100); + density = n_randint(state, 100) * 0.01; + + fmpz_poly_mat_init(A, m, n); + fmpz_poly_mat_init(R, m, n); + fmpz_poly_mat_init(B, 2 * m, n); + fmpz_poly_mat_init(R2, 2 * m, n); + + fmpz_poly_init(c); + fmpz_poly_init(den); + fmpz_poly_init(den2); + + perm = _perm_init(2 * m); + + fmpz_poly_mat_randtest_sparse(A, state, deg, bits, density); + + rank1 = fmpz_poly_mat_rref(R, den, A); + + check_rref(R, den, rank1); + + /* Concatenate the original matrix with the rref, scramble the rows, + and check that the rref is the same */ + _perm_randtest(perm, 2 * m, state); + + for (j = 0; j < m; j++) + { + fmpz_poly_randtest_not_zero(c, state, deg, bits); + for (k = 0; k < n; k++) + fmpz_poly_mul(fmpz_poly_mat_entry(B, perm[j], k), fmpz_poly_mat_entry(A, j, k), c); + } + + for (j = 0; j < m; j++) + { + fmpz_poly_randtest_not_zero(c, state, deg, bits); + for (k = 0; k < n; k++) + fmpz_poly_mul(fmpz_poly_mat_entry(B, perm[m + j], k), fmpz_poly_mat_entry(R, j, k), c); + } + + rank2 = fmpz_poly_mat_rref(R2, den2, B); + equal = (rank1 == rank2); + + if (equal) + { + fmpz_poly_mat_scalar_mul_fmpz_poly(R, R, den2); + fmpz_poly_mat_scalar_mul_fmpz_poly(R2, R2, den); + + for (j = 0; j < rank2; j++) + for (k = 0; k < n; k++) + equal = equal && + fmpz_poly_equal(fmpz_poly_mat_entry(R, j, k), fmpz_poly_mat_entry(R2, j, k)); + for (j = rank2; j < 2 * rank2; j++) + for (k = 0; k < n; k++) + equal = equal && fmpz_poly_is_zero(fmpz_poly_mat_entry(R2, j, k)); + } + + if (!equal) + { + flint_printf("FAIL (rank1 = %wd, rank2 = %wd)!\n", rank1, rank2); + fmpz_poly_mat_print(A, "x"); flint_printf("\n\n"); + fmpz_poly_mat_print(R, "x"); flint_printf("\n\n"); + fmpz_poly_mat_print(R2, "x"); flint_printf("\n\n"); + abort(); + } + + fmpz_poly_clear(c); + fmpz_poly_clear(den); + fmpz_poly_clear(den2); + + _perm_clear(perm); + + fmpz_poly_mat_clear(A); + fmpz_poly_mat_clear(R); + fmpz_poly_mat_clear(B); + fmpz_poly_mat_clear(R2); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} + diff --git a/external/flint-2.4.3/fmpz_poly_mat/test/t-solve_fflu.c b/external/flint-2.4.3/fmpz_poly_mat/test/t-solve_fflu.c new file mode 100644 index 0000000..baf07bd --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/test/t-solve_fflu.c @@ -0,0 +1,141 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + + +int +main(void) +{ + slong i; + + FLINT_TEST_INIT(state); + + flint_printf("solve_fflu...."); + fflush(stdout); + + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_mat_t A, X, B, AX, Bden; + fmpz_poly_t den, det; + slong n, m, bits, deg; + float density; + int solved; + + n = n_randint(state, 15); + m = n_randint(state, 5); + deg = 1 + n_randint(state, 5); + bits = 1 + n_randint(state, 100); + density = n_randint(state, 100) * 0.01; + + fmpz_poly_mat_init(A, n, n); + fmpz_poly_mat_init(B, n, m); + fmpz_poly_mat_init(X, n, m); + fmpz_poly_mat_init(AX, n, m); + fmpz_poly_mat_init(Bden, n, m); + fmpz_poly_init(den); + fmpz_poly_init(det); + + fmpz_poly_mat_randtest_sparse(A, state, deg, bits, density); + fmpz_poly_mat_randtest_sparse(B, state, deg, bits, density); + + solved = fmpz_poly_mat_solve_fflu(X, den, A, B); + fmpz_poly_mat_det_interpolate(det, A); + + if (m == 0 || n == 0) + { + if (solved == 0) + { + flint_printf("FAIL: expected empty system to pass\n"); + abort(); + } + } + else + { + if (!fmpz_poly_equal(den, det)) + { + fmpz_poly_neg(det, det); + if (!fmpz_poly_equal(den, det)) + { + fmpz_poly_neg(det, det); + flint_printf("FAIL: den != +/- det(A)\n"); + flint_printf("den:\n"); fmpz_poly_print_pretty(den, "x"); + flint_printf("\n\n"); + flint_printf("det:\n"); fmpz_poly_print_pretty(det, "x"); + flint_printf("\n\n"); + flint_printf("A:\n"); + fmpz_poly_mat_print(A, "x"); + flint_printf("B:\n"); + fmpz_poly_mat_print(B, "x"); + flint_printf("X:\n"); + fmpz_poly_mat_print(X, "x"); + abort(); + } + } + } + + if (solved != !fmpz_poly_is_zero(den)) + { + flint_printf("FAIL: return value does not match denominator\n"); + abort(); + } + + fmpz_poly_mat_mul(AX, A, X); + fmpz_poly_mat_scalar_mul_fmpz_poly(Bden, B, den); + + if (!fmpz_poly_mat_equal(AX, Bden)) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"); + fmpz_poly_mat_print(A, "x"); + flint_printf("B:\n"); + fmpz_poly_mat_print(B, "x"); + flint_printf("X:\n"); + fmpz_poly_mat_print(X, "x"); + flint_printf("AX:\n"); + fmpz_poly_mat_print(AX, "x"); + flint_printf("Bden:\n"); + fmpz_poly_mat_print(Bden, "x"); + abort(); + } + + fmpz_poly_clear(den); + fmpz_poly_clear(det); + fmpz_poly_mat_clear(A); + fmpz_poly_mat_clear(B); + fmpz_poly_mat_clear(X); + fmpz_poly_mat_clear(AX); + fmpz_poly_mat_clear(Bden); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/test/t-sqr.c b/external/flint-2.4.3/fmpz_poly_mat/test/t-sqr.c new file mode 100644 index 0000000..1907d7d --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/test/t-sqr.c @@ -0,0 +1,135 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mat.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + +int +main(void) +{ + slong i; + + FLINT_TEST_INIT(state); + + flint_printf("sqr...."); + fflush(stdout); + + /* Check evaluation homomorphism */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_mat_t A, C; + fmpz_mat_t a, c, d; + fmpz_t x; + slong m, bits, deg; + + m = n_randint(state, 20); + deg = 1 + n_randint(state, 10); + bits = 1 + n_randint(state, 100); + + fmpz_poly_mat_init(A, m, m); + fmpz_poly_mat_init(C, m, m); + + fmpz_mat_init(a, m, m); + fmpz_mat_init(c, m, m); + fmpz_mat_init(d, m, m); + + fmpz_init(x); + + fmpz_poly_mat_randtest(A, state, deg, bits); + fmpz_poly_mat_randtest(C, state, deg, bits); + + fmpz_poly_mat_sqr(C, A); + + fmpz_randtest(x, state, 1 + n_randint(state, 100)); + + fmpz_poly_mat_evaluate_fmpz(a, A, x); + fmpz_poly_mat_evaluate_fmpz(d, C, x); + fmpz_mat_mul(c, a, a); + + if (!fmpz_mat_equal(c, d)) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"); + fmpz_poly_mat_print(A, "x"); + flint_printf("C:\n"); + fmpz_poly_mat_print(C, "x"); + flint_printf("\n"); + abort(); + } + + fmpz_poly_mat_clear(A); + fmpz_poly_mat_clear(C); + + fmpz_mat_clear(a); + fmpz_mat_clear(c); + fmpz_mat_clear(d); + + fmpz_clear(x); + } + + /* Check aliasing B and A */ + for (i = 0; i < 1000; i++) + { + fmpz_poly_mat_t A, B; + slong m, bits, deg; + + m = n_randint(state, 20); + deg = 1 + n_randint(state, 10); + bits = 1 + n_randint(state, 100); + + fmpz_poly_mat_init(A, m, m); + fmpz_poly_mat_init(B, m, m); + + fmpz_poly_mat_randtest(A, state, deg, bits); + fmpz_poly_mat_randtest(B, state, deg, bits); + + fmpz_poly_mat_sqr(B, A); + fmpz_poly_mat_sqr(A, A); + + if (!fmpz_poly_mat_equal(B, A)) + { + flint_printf("FAIL (aliasing):\n"); + flint_printf("A:\n"); + fmpz_poly_mat_print(A, "x"); + flint_printf("B:\n"); + fmpz_poly_mat_print(B, "x"); + flint_printf("\n"); + abort(); + } + + fmpz_poly_mat_clear(A); + fmpz_poly_mat_clear(B); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/test/t-sqr_KS.c b/external/flint-2.4.3/fmpz_poly_mat/test/t-sqr_KS.c new file mode 100644 index 0000000..f33f441 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/test/t-sqr_KS.c @@ -0,0 +1,123 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + + +int +main(void) +{ + slong i; + + FLINT_TEST_INIT(state); + + flint_printf("sqr_KS...."); + fflush(stdout); + + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + fmpz_poly_mat_t A, C, D; + slong m, bits, deg; + + /* TODO: add separate unsigned tests */ + m = n_randint(state, 15); + deg = 1 + n_randint(state, 15); + bits = 1 + n_randint(state, 150); + + fmpz_poly_mat_init(A, m, m); + fmpz_poly_mat_init(C, m, m); + fmpz_poly_mat_init(D, m, m); + + if (n_randint(state, 2)) + fmpz_poly_mat_randtest(A, state, deg, bits); + else + fmpz_poly_mat_randtest(A, state, deg, bits); + fmpz_poly_mat_randtest(C, state, deg, bits); /* noise in output */ + + fmpz_poly_mat_sqr_classical(C, A); + fmpz_poly_mat_sqr_KS(D, A); + + if (!fmpz_poly_mat_equal(C, D)) + { + flint_printf("FAIL:\n"); + flint_printf("products don't agree!\n"); + flint_printf("A:\n"); + fmpz_poly_mat_print(A, "x"); + flint_printf("B:\n"); + fmpz_poly_mat_print(C, "x"); + flint_printf("D:\n"); + fmpz_poly_mat_print(D, "x"); + flint_printf("\n"); + abort(); + } + + fmpz_poly_mat_clear(A); + fmpz_poly_mat_clear(C); + fmpz_poly_mat_clear(D); + } + + /* Check aliasing B and A */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + fmpz_poly_mat_t A, B; + slong m, bits, deg; + + m = n_randint(state, 20); + deg = 1 + n_randint(state, 10); + bits = 1 + n_randint(state, 100); + + fmpz_poly_mat_init(A, m, m); + fmpz_poly_mat_init(B, m, m); + + fmpz_poly_mat_randtest(A, state, deg, bits); + fmpz_poly_mat_randtest(B, state, deg, bits); + + fmpz_poly_mat_sqr_KS(B, A); + fmpz_poly_mat_sqr_KS(A, A); + + if (!fmpz_poly_mat_equal(B, A)) + { + flint_printf("FAIL (aliasing):\n"); + flint_printf("A:\n"); + fmpz_poly_mat_print(A, "x"); + flint_printf("B:\n"); + fmpz_poly_mat_print(B, "x"); + flint_printf("\n"); + abort(); + } + + fmpz_poly_mat_clear(A); + fmpz_poly_mat_clear(B); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/test/t-sqrlow.c b/external/flint-2.4.3/fmpz_poly_mat/test/t-sqrlow.c new file mode 100644 index 0000000..b6a7323 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/test/t-sqrlow.c @@ -0,0 +1,124 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mat.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + +int +main(void) +{ + slong i; + + FLINT_TEST_INIT(state); + + flint_printf("sqrlow...."); + fflush(stdout); + + /* Compare with sqr */ + for (i = 0; i < 30 * flint_test_multiplier(); i++) + { + fmpz_poly_mat_t A, B, C; + slong n, bits, deg, len; + + n = n_randint(state, 20); + deg = 1 + n_randint(state, 10); + bits = 1 + n_randint(state, 100); + len = n_randint(state, 10); + + fmpz_poly_mat_init(A, n, n); + fmpz_poly_mat_init(B, n, n); + fmpz_poly_mat_init(C, n, n); + + fmpz_poly_mat_randtest(A, state, deg, bits); + fmpz_poly_mat_randtest(B, state, deg, bits); /* noise in output */ + fmpz_poly_mat_randtest(C, state, deg, bits); /* noise in output */ + + fmpz_poly_mat_sqrlow(B, A, len); + fmpz_poly_mat_sqr(C, A); + fmpz_poly_mat_truncate(C, len); + + if (!fmpz_poly_mat_equal(B, C)) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"); + fmpz_poly_mat_print(A, "x"); + flint_printf("B:\n"); + fmpz_poly_mat_print(B, "x"); + flint_printf("C:\n"); + fmpz_poly_mat_print(C, "x"); + flint_printf("\n"); + abort(); + } + + fmpz_poly_mat_clear(A); + fmpz_poly_mat_clear(B); + fmpz_poly_mat_clear(C); + } + + /* Check aliasing */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + fmpz_poly_mat_t A, B; + slong n, bits, deg, len; + + n = n_randint(state, 20); + deg = 1 + n_randint(state, 10); + bits = 1 + n_randint(state, 100); + len = n_randint(state, 10); + + fmpz_poly_mat_init(A, n, n); + fmpz_poly_mat_init(B, n, n); + + fmpz_poly_mat_randtest(A, state, deg, bits); + fmpz_poly_mat_randtest(B, state, deg, bits); + + fmpz_poly_mat_sqrlow(B, A, len); + fmpz_poly_mat_sqrlow(A, A, len); + + if (!fmpz_poly_mat_equal(B, A)) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"); + fmpz_poly_mat_print(A, "x"); + flint_printf("B:\n"); + fmpz_poly_mat_print(B, "x"); + flint_printf("\n"); + abort(); + } + + fmpz_poly_mat_clear(A); + fmpz_poly_mat_clear(B); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/test/t-sub.c b/external/flint-2.4.3/fmpz_poly_mat/test/t-sub.c new file mode 100644 index 0000000..ddb7380 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/test/t-sub.c @@ -0,0 +1,186 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mat.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + +int +main(void) +{ + slong i; + + FLINT_TEST_INIT(state); + + flint_printf("sub...."); + fflush(stdout); + + /* Check evaluation homomorphism */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_mat_t A, B, C; + fmpz_mat_t a, b, c, d; + fmpz_t x; + slong m, n, bits, deg; + + m = n_randint(state, 20); + n = n_randint(state, 20); + deg = 1 + n_randint(state, 10); + bits = 1 + n_randint(state, 100); + + fmpz_poly_mat_init(A, m, n); + fmpz_poly_mat_init(B, m, n); + fmpz_poly_mat_init(C, m, n); + + fmpz_mat_init(a, m, n); + fmpz_mat_init(b, m, n); + fmpz_mat_init(c, m, n); + fmpz_mat_init(d, m, n); + + fmpz_init(x); + + fmpz_poly_mat_randtest(A, state, deg, bits); + fmpz_poly_mat_randtest(B, state, deg, bits); + fmpz_poly_mat_sub(C, A, B); + + fmpz_randtest(x, state, 1 + n_randint(state, 100)); + + fmpz_poly_mat_evaluate_fmpz(a, A, x); + fmpz_poly_mat_evaluate_fmpz(b, B, x); + fmpz_poly_mat_evaluate_fmpz(d, C, x); + fmpz_mat_sub(c, a, b); + + if (!fmpz_mat_equal(c, d)) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"); + fmpz_poly_mat_print(A, "x"); + flint_printf("B:\n"); + fmpz_poly_mat_print(B, "x"); + flint_printf("C:\n"); + fmpz_poly_mat_print(C, "x"); + flint_printf("\n"); + abort(); + } + + fmpz_poly_mat_clear(A); + fmpz_poly_mat_clear(B); + fmpz_poly_mat_clear(C); + + fmpz_mat_clear(a); + fmpz_mat_clear(b); + fmpz_mat_clear(c); + fmpz_mat_clear(d); + + fmpz_clear(x); + } + + /* Check aliasing C and A */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_mat_t A, B, C; + slong m, n, bits, deg; + + m = n_randint(state, 20); + n = n_randint(state, 20); + deg = 1 + n_randint(state, 10); + bits = 1 + n_randint(state, 100); + + fmpz_poly_mat_init(A, m, n); + fmpz_poly_mat_init(B, m, n); + fmpz_poly_mat_init(C, m, n); + + fmpz_poly_mat_randtest(A, state, deg, bits); + fmpz_poly_mat_randtest(B, state, deg, bits); + + fmpz_poly_mat_sub(C, A, B); + fmpz_poly_mat_sub(A, A, B); + + if (!fmpz_poly_mat_equal(C, A)) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"); + fmpz_poly_mat_print(A, "x"); + flint_printf("B:\n"); + fmpz_poly_mat_print(B, "x"); + flint_printf("C:\n"); + fmpz_poly_mat_print(C, "x"); + flint_printf("\n"); + abort(); + } + + fmpz_poly_mat_clear(A); + fmpz_poly_mat_clear(B); + fmpz_poly_mat_clear(C); + } + + /* Check aliasing C and B */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_mat_t A, B, C; + slong m, n, bits, deg; + + m = n_randint(state, 20); + n = n_randint(state, 20); + deg = 1 + n_randint(state, 10); + bits = 1 + n_randint(state, 100); + + fmpz_poly_mat_init(A, m, n); + fmpz_poly_mat_init(B, m, n); + fmpz_poly_mat_init(C, m, n); + + fmpz_poly_mat_randtest(A, state, deg, bits); + fmpz_poly_mat_randtest(B, state, deg, bits); + + fmpz_poly_mat_sub(C, A, B); + fmpz_poly_mat_sub(B, A, B); + + if (!fmpz_poly_mat_equal(C, B)) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"); + fmpz_poly_mat_print(A, "x"); + flint_printf("B:\n"); + fmpz_poly_mat_print(B, "x"); + flint_printf("C:\n"); + fmpz_poly_mat_print(C, "x"); + flint_printf("\n"); + abort(); + } + + fmpz_poly_mat_clear(A); + fmpz_poly_mat_clear(B); + fmpz_poly_mat_clear(C); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/test/t-trace.c b/external/flint-2.4.3/fmpz_poly_mat/test/t-trace.c new file mode 100644 index 0000000..ce43ab1 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/test/t-trace.c @@ -0,0 +1,99 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" +#include "ulong_extras.h" + +int +main(void) +{ + slong i; + FLINT_TEST_INIT(state); + + flint_printf("trace...."); + fflush(stdout); + + + + /* Test trace(AB) = trace(BA) */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + fmpz_poly_mat_t A, B, AB, BA; + fmpz_poly_t trab, trba; + slong m, n; + + m = n_randint(state, 10); + n = n_randint(state, 10); + + fmpz_poly_mat_init(A, m, n); + fmpz_poly_mat_init(B, n, m); + fmpz_poly_mat_init(AB, m, m); + fmpz_poly_mat_init(BA, n, n); + + fmpz_poly_init(trab); + fmpz_poly_init(trba); + + fmpz_poly_mat_randtest(A, state, 1 + n_randint(state, 10), + 1 + n_randint(state, 100)); + fmpz_poly_mat_randtest(B, state, 1 + n_randint(state, 10), + 1 + n_randint(state, 100)); + + fmpz_poly_mat_mul(AB, A, B); + fmpz_poly_mat_mul(BA, B, A); + + fmpz_poly_mat_trace(trab, AB); + fmpz_poly_mat_trace(trba, BA); + + if (!fmpz_poly_equal(trab, trba)) + { + flint_printf("FAIL:\n"); + fmpz_poly_mat_print(A, "x"), flint_printf("\n"); + fmpz_poly_mat_print(B, "x"), flint_printf("\n"); + fmpz_poly_mat_print(AB, "x"), flint_printf("\n"); + fmpz_poly_mat_print(BA, "x"), flint_printf("\n"); + flint_printf("tr(AB): "), fmpz_poly_print(trab), flint_printf("\n"); + flint_printf("tr(BA): "), fmpz_poly_print(trba), flint_printf("\n"); + abort(); + } + + fmpz_poly_mat_clear(A); + fmpz_poly_mat_clear(B); + fmpz_poly_mat_clear(AB); + fmpz_poly_mat_clear(BA); + fmpz_poly_clear(trab); + fmpz_poly_clear(trba); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/test/t-zero.c b/external/flint-2.4.3/fmpz_poly_mat/test/t-zero.c new file mode 100644 index 0000000..01a42e7 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/test/t-zero.c @@ -0,0 +1,84 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mat.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + +int +main(void) +{ + int iter; + + FLINT_TEST_INIT(state); + + flint_printf("zero/is_zero...."); + fflush(stdout); + + for (iter = 0; iter < 100 * flint_test_multiplier(); iter++) + { + fmpz_poly_mat_t A; + slong m, n; + + m = n_randint(state, 10); + n = n_randint(state, 10); + + fmpz_poly_mat_init(A, m, n); + fmpz_poly_mat_randtest(A, state, n_randint(state, 5), + n_randint(state, 100)); + fmpz_poly_mat_zero(A); + + if (!fmpz_poly_mat_is_zero(A)) + { + flint_printf("FAIL: expected matrix to be zero\n"); + abort(); + } + + if (m > 0 && n > 0) + { + m = n_randint(state, m); + n = n_randint(state, n); + fmpz_poly_randtest_not_zero(fmpz_poly_mat_entry(A, m, n), + state, 5, 5); + + if (fmpz_poly_mat_is_zero(A)) + { + flint_printf("FAIL: expected matrix not to be zero\n"); + abort(); + } + } + + fmpz_poly_mat_clear(A); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/trace.c b/external/flint-2.4.3/fmpz_poly_mat/trace.c new file mode 100644 index 0000000..40d1961 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/trace.c @@ -0,0 +1,43 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "flint.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + +void +fmpz_poly_mat_trace(fmpz_poly_t trace, const fmpz_poly_mat_t mat) +{ + slong i, n = fmpz_poly_mat_nrows(mat); + + if (n == 0) + fmpz_poly_zero(trace); + else + { + fmpz_poly_set(trace, fmpz_poly_mat_entry(mat, 0, 0)); + for (i = 1; i < n; i++) + fmpz_poly_add(trace, trace, fmpz_poly_mat_entry(mat, i, i)); + } +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/transpose.c b/external/flint-2.4.3/fmpz_poly_mat/transpose.c new file mode 100644 index 0000000..2c048d6 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/transpose.c @@ -0,0 +1,55 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "fmpz_poly_mat.h" + +void +fmpz_poly_mat_transpose(fmpz_poly_mat_t B, const fmpz_poly_mat_t A) +{ + slong i, j; + + if (B->r != A->c || B->c != A->r) + { + flint_printf("Exception (fmpz_poly_mat_transpose). Incompatible dimensions.\n"); + abort(); + } + + if (A == B) /* In-place, guaranteed to be square */ + { + for (i = 0; i < A->r - 1; i++) + for (j = i + 1; j < A->c; j++) + fmpz_poly_swap(fmpz_poly_mat_entry(B, i, j), + fmpz_poly_mat_entry(B, j, i)); + } + else /* Not aliased; general case */ + { + for (i = 0; i < B->r; i++) + for (j = 0; j < B->c; j++) + fmpz_poly_set(fmpz_poly_mat_entry(B, i, j), + fmpz_poly_mat_entry(A, j, i)); + } +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/truncate.c b/external/flint-2.4.3/fmpz_poly_mat/truncate.c new file mode 100644 index 0000000..8248eaa --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/truncate.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + +void +fmpz_poly_mat_truncate(fmpz_poly_mat_t A, slong len) +{ + slong i, j; + + for (i = 0; i < fmpz_poly_mat_nrows(A); i++) + for (j = 0; j < fmpz_poly_mat_ncols(A); j++) + fmpz_poly_truncate(fmpz_poly_mat_entry(A, i, j), len); +} diff --git a/external/flint-2.4.3/fmpz_poly_mat/zero.c b/external/flint-2.4.3/fmpz_poly_mat/zero.c new file mode 100644 index 0000000..682900c --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_mat/zero.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz_poly.h" +#include "fmpz_poly_mat.h" + +void +fmpz_poly_mat_zero(fmpz_poly_mat_t A) +{ + slong i, j; + + for (i = 0; i < A->r; i++) + for (j = 0; j < A->c; j++) + fmpz_poly_zero(fmpz_poly_mat_entry(A, i, j)); +} diff --git a/external/flint-2.4.3/fmpz_poly_matxx.h b/external/flint-2.4.3/fmpz_poly_matxx.h new file mode 100644 index 0000000..7936d56 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_matxx.h @@ -0,0 +1,490 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#ifndef FMPZ_POLY_MATXX_H +#define FMPZ_POLY_MATXX_H FMPZ_POLY_MATXX_H + +#include "fmpz_poly_mat.h" + +#include "fmpz_matxx.h" +#include "fmpz_polyxx.h" +#include "permxx.h" + +#include "flintxx/matrix.h" + +namespace flint { +FLINT_DEFINE_UNOP(prod) + +namespace detail { +template +struct fmpz_poly_matxx_traits : matrices::generic_traits { }; +} // detail + +template +class fmpz_poly_matxx_expression + : public expression, Operation, Data> +{ +public: + typedef expression, + Operation, Data> base_t; + typedef detail::fmpz_poly_matxx_traits traits_t; + + FLINTXX_DEFINE_BASICS(fmpz_poly_matxx_expression) + FLINTXX_DEFINE_CTORS(fmpz_poly_matxx_expression) + FLINTXX_DEFINE_C_REF(fmpz_poly_matxx_expression, fmpz_poly_mat_struct, _mat) + + template + static evaluated_t create_temporary_rowscols( + const Expr&, slong rows, slong cols) + { + return evaluated_t(rows, cols); + } + FLINTXX_DEFINE_MATRIX_METHODS(traits_t) + + // static functions for fmpz_poly_matxx + template + static fmpz_poly_matxx_expression from_ground(const Fmpz_matxx& f) + { + return _from_ground(f.evaluate()); + } + template + static fmpz_poly_matxx_expression _from_ground(const Fmpz_matxx& f) + { + fmpz_poly_matxx_expression res(f.rows(), f.cols()); + for(slong i = 0;i < f.rows();++i) + for(slong j = 0;j < f.rows();++j) + res.at(i, j).set_coeff(0, f.at(i, j)); + return res; + } + + static fmpz_poly_matxx_expression randtest(slong rows, slong cols, + frandxx& state, slong len, mp_bitcnt_t bits) + { + fmpz_poly_matxx_expression res(rows, cols); + res.set_randtest(state, len, bits); + return res; + } + static fmpz_poly_matxx_expression randtest_unsigned(slong rows, slong cols, + frandxx& state, slong len, mp_bitcnt_t bits) + { + fmpz_poly_matxx_expression res(rows, cols); + res.set_randtest_unsigned(state, len, bits); + return res; + } + static fmpz_poly_matxx_expression randtest_sparse(slong rows, slong cols, + frandxx& state, slong len, mp_bitcnt_t bits, float density) + { + fmpz_poly_matxx_expression res(rows, cols); + res.set_randtest_sparse(state, len, bits, density); + return res; + } + + static fmpz_poly_matxx_expression zero(slong rows, slong cols) + {return fmpz_poly_matxx_expression(rows, cols);} + static fmpz_poly_matxx_expression one(slong rows, slong cols) + { + fmpz_poly_matxx_expression res(rows, cols); + res.set_one(); + return res; + } + + // these only make sense with targets + void set_randtest(frandxx& state, slong len, mp_bitcnt_t bits) + {fmpz_poly_mat_randtest(_mat(), state._data(), len, bits);} + void set_randtest_unsigned(frandxx& state, slong len, mp_bitcnt_t bits) + {fmpz_poly_mat_randtest_unsigned(_mat(), state._data(), len, bits);} + void set_randtest_sparse(frandxx& state, slong len, mp_bitcnt_t bits, + float density) + {fmpz_poly_mat_randtest_sparse(_mat(), state._data(), len, bits, density);} + void truncate(slong len) {fmpz_poly_mat_truncate(_mat(), len);} + void set_zero() + {fmpz_poly_mat_zero(_mat());} + void set_one() + {fmpz_poly_mat_one(_mat());} + + // these cause evaluation + slong rank() const {return fmpz_poly_mat_rank(this->evaluate()._mat());} + bool is_zero() const + {return fmpz_poly_mat_is_zero(this->evaluate()._mat());} + bool is_one() const + {return fmpz_poly_mat_is_one(this->evaluate()._mat());} + bool is_empty() const + {return fmpz_poly_mat_is_empty(this->evaluate()._mat());} + bool is_square() const + {return fmpz_poly_mat_is_square(this->evaluate()._mat());} + slong max_length() const + {return fmpz_poly_mat_max_length(this->evaluate()._mat());} + slong max_bits() const + {return fmpz_poly_mat_max_bits(this->evaluate()._mat());} + slong find_pivot_any(slong start, slong end, slong c) const + { + return fmpz_poly_mat_find_pivot_any( + this->evaluate()._mat(), start, end, c); + } + slong find_pivot_partial(slong start, slong end, slong c) const + { + return fmpz_poly_mat_find_pivot_partial( + this->evaluate()._mat(), start, end, c); + } + + // forwarded lazy ops + FLINTXX_DEFINE_MEMBER_BINOP_(operator(), compeval) + + FLINTXX_DEFINE_MEMBER_3OP(mullow) + FLINTXX_DEFINE_MEMBER_3OP(pow_trunc) + + FLINTXX_DEFINE_MEMBER_BINOP(solve) + FLINTXX_DEFINE_MEMBER_BINOP(solve_fflu) + FLINTXX_DEFINE_MEMBER_BINOP(mul_KS) + FLINTXX_DEFINE_MEMBER_BINOP(mul_classical) + FLINTXX_DEFINE_MEMBER_BINOP(pow) + FLINTXX_DEFINE_MEMBER_BINOP(sqrlow) + + FLINTXX_DEFINE_MEMBER_UNOP_RTYPE(fmpz_polyxx, det) + FLINTXX_DEFINE_MEMBER_UNOP_RTYPE(fmpz_polyxx, det_fflu) + FLINTXX_DEFINE_MEMBER_UNOP_RTYPE(fmpz_polyxx, det_interpolate) + FLINTXX_DEFINE_MEMBER_UNOP_RTYPE(fmpz_polyxx, trace) + FLINTXX_DEFINE_MEMBER_UNOP(sqr) + FLINTXX_DEFINE_MEMBER_UNOP(sqr_classical) + FLINTXX_DEFINE_MEMBER_UNOP(sqr_KS) + FLINTXX_DEFINE_MEMBER_UNOP(transpose) + + //FLINTXX_DEFINE_MEMBER_UNOP_RTYPE(nullspace) // TODO + //FLINTXX_DEFINE_MEMBER_UNOP_RTYPE(???, inv) // TODO + //FLINTXX_DEFINE_MEMBER_UNOP_RTYPE(???, rref) // TODO + + FLINTXX_DEFINE_MEMBER_FFLU +}; + +namespace detail { +struct fmpz_poly_mat_data; +} // detail + +typedef fmpz_poly_matxx_expression fmpz_poly_matxx; +typedef fmpz_poly_matxx_expression > fmpz_poly_matxx_ref; +typedef fmpz_poly_matxx_expression > fmpz_poly_matxx_srcref; + +template<> +struct matrix_traits +{ + template static slong rows(const M& m) + { + return fmpz_poly_mat_nrows(m._mat()); + } + template static slong cols(const M& m) + { + return fmpz_poly_mat_ncols(m._mat()); + } + + template static fmpz_polyxx_srcref at(const M& m, slong i, slong j) + { + return fmpz_polyxx_srcref::make(fmpz_poly_mat_entry(m._mat(), i, j)); + } + template static fmpz_polyxx_ref at(M& m, slong i, slong j) + { + return fmpz_polyxx_ref::make(fmpz_poly_mat_entry(m._mat(), i, j)); + } +}; + +namespace detail { +template<> +struct fmpz_poly_matxx_traits + : matrices::generic_traits_srcref { }; +template<> +struct fmpz_poly_matxx_traits + : matrices::generic_traits_ref { }; +template<> struct fmpz_poly_matxx_traits + : matrices::generic_traits_nonref { }; + +struct fmpz_poly_mat_data +{ + typedef fmpz_poly_mat_t& data_ref_t; + typedef const fmpz_poly_mat_t& data_srcref_t; + + fmpz_poly_mat_t inner; + + fmpz_poly_mat_data(slong m, slong n) + { + fmpz_poly_mat_init(inner, m, n); + } + + fmpz_poly_mat_data(const fmpz_poly_mat_data& o) + { + fmpz_poly_mat_init_set(inner, o.inner); + } + + fmpz_poly_mat_data(fmpz_poly_matxx_srcref o) + { + fmpz_poly_mat_init_set(inner, o._data().inner); + } + + ~fmpz_poly_mat_data() {fmpz_poly_mat_clear(inner);} +}; +} // detail + +#define FMPZ_POLY_MATXX_COND_S FLINTXX_COND_S(fmpz_poly_matxx) +#define FMPZ_POLY_MATXX_COND_T FLINTXX_COND_T(fmpz_poly_matxx) + +namespace matrices { +template<> +struct outsize + : outsize { }; +template<> +struct outsize + : outsize { }; +} // matrices + +FLINTXX_DEFINE_TEMPORARY_RULES(fmpz_poly_matxx) + +namespace rules { +FLINT_DEFINE_DOIT_COND2(assignment, FMPZ_POLY_MATXX_COND_T, FMPZ_POLY_MATXX_COND_S, + fmpz_poly_mat_set(to._mat(), from._mat())) + +FLINTXX_DEFINE_SWAP(fmpz_poly_matxx, fmpz_poly_mat_swap(e1._mat(), e2._mat())) + +FLINTXX_DEFINE_EQUALS(fmpz_poly_matxx, fmpz_poly_mat_equal(e1._mat(), e2._mat())) + +FLINT_DEFINE_PRINT_PRETTY_COND_2(FMPZ_POLY_MATXX_COND_S, const char*, + (fmpz_poly_mat_print(from._mat(), extra), 1)) + +FLINT_DEFINE_BINARY_EXPR_COND2(times, fmpz_poly_matxx, + FMPZ_POLY_MATXX_COND_S, FMPZ_POLY_MATXX_COND_S, + fmpz_poly_mat_mul(to._mat(), e1._mat(), e2._mat())) +FLINT_DEFINE_CBINARY_EXPR_COND2(times, fmpz_poly_matxx, + FMPZ_POLY_MATXX_COND_S, FMPZXX_COND_S, + fmpz_poly_mat_scalar_mul_fmpz(to._mat(), e1._mat(), e2._fmpz())) +FLINT_DEFINE_CBINARY_EXPR_COND2(times, fmpz_poly_matxx, + FMPZ_POLY_MATXX_COND_S, FMPZ_POLYXX_COND_S, + fmpz_poly_mat_scalar_mul_fmpz_poly(to._mat(), e1._mat(), e2._poly())) + +FLINT_DEFINE_BINARY_EXPR_COND2(plus, fmpz_poly_matxx, + FMPZ_POLY_MATXX_COND_S, FMPZ_POLY_MATXX_COND_S, + fmpz_poly_mat_add(to._mat(), e1._mat(), e2._mat())) +FLINT_DEFINE_BINARY_EXPR_COND2(minus, fmpz_poly_matxx, + FMPZ_POLY_MATXX_COND_S, FMPZ_POLY_MATXX_COND_S, + fmpz_poly_mat_sub(to._mat(), e1._mat(), e2._mat())) + +FLINT_DEFINE_UNARY_EXPR_COND(negate, fmpz_poly_matxx, FMPZ_POLY_MATXX_COND_S, + fmpz_poly_mat_neg(to._mat(), from._mat())) + +FLINT_DEFINE_UNARY_EXPR_COND(transpose_op, fmpz_poly_matxx, FMPZ_POLY_MATXX_COND_S, + fmpz_poly_mat_transpose(to._mat(), from._mat())) +FLINT_DEFINE_UNARY_EXPR_COND(trace_op, fmpz_polyxx, FMPZ_POLY_MATXX_COND_S, + fmpz_poly_mat_trace(to._poly(), from._mat())) + +FLINT_DEFINE_THREEARY_EXPR_COND3(mat_at_op, fmpz_polyxx, + FMPZ_POLY_MATXX_COND_S, traits::fits_into_slong, traits::fits_into_slong, + fmpz_poly_set(to._poly(), fmpz_poly_mat_entry(e1._mat(), e2, e3))) + +FLINT_DEFINE_BINARY_EXPR_COND2(evaluate_op, fmpz_matxx, + FMPZ_POLY_MATXX_COND_S, FMPZXX_COND_S, + fmpz_poly_mat_evaluate_fmpz(to._mat(), e1._mat(), e2._fmpz())) + +FLINT_DEFINE_BINARY_EXPR_COND2(mul_classical_op, fmpz_poly_matxx, + FMPZ_POLY_MATXX_COND_S, FMPZ_POLY_MATXX_COND_S, + fmpz_poly_mat_mul_classical(to._mat(), e1._mat(), e2._mat())) +FLINT_DEFINE_BINARY_EXPR_COND2(mul_KS_op, fmpz_poly_matxx, + FMPZ_POLY_MATXX_COND_S, FMPZ_POLY_MATXX_COND_S, + fmpz_poly_mat_mul_KS(to._mat(), e1._mat(), e2._mat())) + +FLINT_DEFINE_THREEARY_EXPR_COND3(mullow_op, fmpz_poly_matxx, + FMPZ_POLY_MATXX_COND_S, FMPZ_POLY_MATXX_COND_S, traits::fits_into_slong, + fmpz_poly_mat_mullow(to._mat(), e1._mat(), e2._mat(), e3)) + +FLINT_DEFINE_UNARY_EXPR_COND(sqr_op, fmpz_poly_matxx, FMPZ_POLY_MATXX_COND_S, + fmpz_poly_mat_sqr(to._mat(), from._mat())) +FLINT_DEFINE_UNARY_EXPR_COND(sqr_classical_op, fmpz_poly_matxx, + FMPZ_POLY_MATXX_COND_S, + fmpz_poly_mat_sqr_classical(to._mat(), from._mat())) +FLINT_DEFINE_UNARY_EXPR_COND(sqr_KS_op, fmpz_poly_matxx, + FMPZ_POLY_MATXX_COND_S, + fmpz_poly_mat_sqr_KS(to._mat(), from._mat())) +FLINT_DEFINE_BINARY_EXPR_COND2(sqrlow_op, fmpz_poly_matxx, + FMPZ_POLY_MATXX_COND_S, traits::fits_into_slong, + fmpz_poly_mat_sqrlow(to._mat(), e1._mat(), e2)) + +FLINT_DEFINE_BINARY_EXPR_COND2(pow_op, fmpz_poly_matxx, + FMPZ_POLY_MATXX_COND_S, traits::is_unsigned_integer, + fmpz_poly_mat_pow(to._mat(), e1._mat(), e2)) + +FLINT_DEFINE_THREEARY_EXPR_COND3(pow_trunc_op, fmpz_poly_matxx, + FMPZ_POLY_MATXX_COND_S, traits::is_unsigned_integer, traits::fits_into_slong, + fmpz_poly_mat_pow_trunc(to._mat(), e1._mat(), e2, e3)) + +FLINT_DEFINE_UNARY_EXPR_COND(det_op, fmpz_polyxx, FMPZ_POLY_MATXX_COND_S, + fmpz_poly_mat_det(to._poly(), from._mat())) +FLINT_DEFINE_UNARY_EXPR_COND(det_fflu_op, fmpz_polyxx, FMPZ_POLY_MATXX_COND_S, + fmpz_poly_mat_det_fflu(to._poly(), from._mat())) +FLINT_DEFINE_UNARY_EXPR_COND(det_interpolate_op, fmpz_polyxx, + FMPZ_POLY_MATXX_COND_S, + fmpz_poly_mat_det_interpolate(to._poly(), from._mat())) + +namespace rdetail { +typedef make_ltuple::type >::type + fmpz_poly_mat_inv_rt; + +typedef make_ltuple::type >::type + fmpz_poly_mat_nullspace_rt; +} +FLINT_DEFINE_UNARY_EXPR_COND(inv_op, rdetail::fmpz_poly_mat_inv_rt, + FMPZ_POLY_MATXX_COND_S, + to.template get<0>() = fmpz_poly_mat_inv(to.template get<1>()._mat(), + to.template get<2>()._poly(), from._mat())) +FLINT_DEFINE_UNARY_EXPR_COND(nullspace_op, rdetail::fmpz_poly_mat_nullspace_rt, + FMPZ_POLY_MATXX_COND_S, to.template get<0>() = fmpz_poly_mat_nullspace( + to.template get<1>()._mat(), from._mat())) + +FLINT_DEFINE_BINARY_EXPR_COND2(solve_op, rdetail::fmpz_poly_mat_inv_rt, + FMPZ_POLY_MATXX_COND_S, FMPZ_POLY_MATXX_COND_S, + to.template get<0>() = fmpz_poly_mat_solve(to.template get<1>()._mat(), + to.template get<2>()._poly(), e1._mat(), e2._mat())) +FLINT_DEFINE_BINARY_EXPR_COND2(solve_fflu_op, rdetail::fmpz_poly_mat_inv_rt, + FMPZ_POLY_MATXX_COND_S, FMPZ_POLY_MATXX_COND_S, + to.template get<0>() = fmpz_poly_mat_solve_fflu( + to.template get<1>()._mat(), + to.template get<2>()._poly(), e1._mat(), e2._mat())) + +namespace rdetail { +typedef make_ltuple::type>::type + fmpz_poly_matxx_fflu_rt; +} // rdetail + +FLINT_DEFINE_THREEARY_EXPR_COND3(fflu_op, rdetail::fmpz_poly_matxx_fflu_rt, + FMPZ_POLY_MATXX_COND_S, traits::is_maybe_perm, tools::is_bool, + to.template get<0>() = fmpz_poly_mat_fflu(to.template get<1>()._mat(), + to.template get<2>()._poly(), maybe_perm_data(e2), e1._mat(), e3)) + +FLINT_DEFINE_UNARY_EXPR_COND(rref_op, rdetail::fmpz_poly_matxx_fflu_rt, + FMPZ_POLY_MATXX_COND_S, + to.template get<0>() = fmpz_poly_mat_rref(to.template get<1>()._mat(), + to.template get<2>()._poly(), from._mat())) + +FLINT_DEFINE_THREEARY_EXPR_COND3(solve_fflu_precomp_op, fmpz_poly_matxx, + traits::is_permxx, FMPZ_POLY_MATXX_COND_S, FMPZ_POLY_MATXX_COND_S, + fmpz_poly_mat_solve_fflu_precomp(to._mat(), e1._data(), + e2._mat(), e3._mat())) +} // rules + + +//////////////////////////////////////////////////////////////////////////// +// fmpz_poly_mat_vecxx and prod +//////////////////////////////////////////////////////////////////////////// +namespace detail { +struct fmpz_poly_mat_vector_data +{ + slong size; + fmpz_poly_mat_t* array; + + fmpz_poly_mat_vector_data(slong n, slong rows, slong cols) + : size(n) + { + array = new fmpz_poly_mat_t[n]; + for(slong i = 0; i < n; ++i) + fmpz_poly_mat_init(array[i], rows, cols); + } + + ~fmpz_poly_mat_vector_data() + { + for(slong i = 0; i < size; ++i) + fmpz_poly_mat_clear(array[i]); + delete[] array; + } + + fmpz_poly_mat_vector_data(const fmpz_poly_mat_vector_data& o) + : size(o.size) + { + array = new fmpz_poly_mat_t[size]; + for(slong i = 0; i < size; ++i) + fmpz_poly_mat_init_set(array[i], o.array[i]); + } + + fmpz_poly_matxx_ref at(slong i) + {return fmpz_poly_matxx_ref::make(array[i]);} + fmpz_poly_matxx_srcref at(slong i) const + {return fmpz_poly_matxx_srcref::make(array[i]);} + + bool equals(const fmpz_poly_mat_vector_data& o) const + { + if(size != o.size) + return false; + for(slong i = 0; i < size; ++i) + if(!fmpz_poly_mat_equal(array[i], o.array[i])) + return false; + return true; + } +}; +} // detail +// TODO temporary allocation + +typedef vector_expression< + detail::wrapped_vector_traits, + operations::immediate, + detail::fmpz_poly_mat_vector_data> fmpz_poly_mat_vecxx; +// TODO references + +template<> +struct enable_vector_rules : mp::false_ { }; + +namespace matrices { +template<> +struct outsize +{ + template + static slong rows(const Mat& m) + { + return m._data().head[0].rows(); + } + template + static slong cols(const Mat& m) + { + return m._data().head[0].cols(); + } +}; +} + +namespace rules { +// TODO hack to make code look like references are implemented +template struct FMPZ_POLY_MAT_VECXX_COND_S + : mp::equal_types { }; +#define FMPZ_POLY_MAT_VECXX_COND_T FMPZ_POLY_MAT_VECXX_COND_S + +// TODO references +FLINT_DEFINE_GET(equals, bool, fmpz_poly_mat_vecxx, e1._data().equals(e2._data())) + +FLINT_DEFINE_UNARY_EXPR_COND(prod_op, fmpz_poly_matxx, + FMPZ_POLY_MAT_VECXX_COND_S, + fmpz_poly_mat_prod(to._mat(), (fmpz_poly_mat_t * const) from._array(), from.size())) +} // rules + +} // flint + +#endif diff --git a/external/flint-2.4.3/fmpz_poly_q.h b/external/flint-2.4.3/fmpz_poly_q.h new file mode 100644 index 0000000..8fdb0d6 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q.h @@ -0,0 +1,185 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009, 2010, 2011 Sebastian Pancratz + +******************************************************************************/ + +#ifndef FMPZ_POLY_Q_H +#define FMPZ_POLY_Q_H + +#undef ulong +#define ulong ulongxx /* interferes with system includes */ +#include +#undef ulong +#include +#define ulong mp_limb_t + +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +#ifdef __cplusplus + extern "C" { +#endif + +typedef struct +{ + fmpz_poly_struct *num; + fmpz_poly_struct *den; +} fmpz_poly_q_struct; + +typedef fmpz_poly_q_struct fmpz_poly_q_t[1]; + +/* Accessing numerator and denominator ***************************************/ + +#define fmpz_poly_q_numref(op) ((op)->num) + +#define fmpz_poly_q_denref(op) ((op)->den) + +void fmpz_poly_q_canonicalise(fmpz_poly_q_t rop); + +int fmpz_poly_q_is_canonical(const fmpz_poly_q_t op); + +/* Memory management *********************************************************/ + +void fmpz_poly_q_init(fmpz_poly_q_t rop); + +void fmpz_poly_q_clear(fmpz_poly_q_t rop); + +/* Randomisation *************************************************************/ + +void fmpz_poly_q_randtest(fmpz_poly_q_t poly, flint_rand_t state, + slong len1, mp_bitcnt_t bits1, + slong len2, mp_bitcnt_t bits2); + +void fmpz_poly_q_randtest_not_zero(fmpz_poly_q_t poly, flint_rand_t state, + slong len1, mp_bitcnt_t bits1, + slong len2, mp_bitcnt_t bits2); + +/* Assignment ****************************************************************/ + +void fmpz_poly_q_set(fmpz_poly_q_t rop, const fmpz_poly_q_t op); + +void fmpz_poly_q_set_si(fmpz_poly_q_t rop, slong op); + +void fmpz_poly_q_swap(fmpz_poly_q_t op1, fmpz_poly_q_t op2); + +static __inline__ +void fmpz_poly_q_zero(fmpz_poly_q_t rop) +{ + fmpz_poly_zero(rop->num); + fmpz_poly_set_si(rop->den, 1); +} + +static __inline__ +void fmpz_poly_q_one(fmpz_poly_q_t rop) +{ + fmpz_poly_set_si(rop->num, 1); + fmpz_poly_set_si(rop->den, 1); +} + +static __inline__ +void fmpz_poly_q_neg(fmpz_poly_q_t rop, const fmpz_poly_q_t op) +{ + fmpz_poly_neg(rop->num, op->num); + fmpz_poly_set(rop->den, op->den); +} + +void fmpz_poly_q_inv(fmpz_poly_q_t rop, const fmpz_poly_q_t op); + +/* Comparison ****************************************************************/ + +static __inline__ +int fmpz_poly_q_is_zero(const fmpz_poly_q_t op) +{ + return fmpz_poly_is_zero(op->num); +} + +static __inline__ +int fmpz_poly_q_is_one(const fmpz_poly_q_t op) +{ + return fmpz_poly_is_one(op->num) && fmpz_poly_is_one(op->den); +} + +static __inline__ +int fmpz_poly_q_equal(const fmpz_poly_q_t op1, const fmpz_poly_q_t op2) +{ + return fmpz_poly_equal(op1->num, op2->num) && fmpz_poly_equal(op1->den, op2->den); +} + +/* Addition and subtraction **************************************************/ + +void fmpz_poly_q_add_in_place(fmpz_poly_q_t rop, const fmpz_poly_q_t op); +void fmpz_poly_q_sub_in_place(fmpz_poly_q_t rop, const fmpz_poly_q_t op); + +void fmpz_poly_q_add(fmpz_poly_q_t rop, const fmpz_poly_q_t op1, const fmpz_poly_q_t op2); +void fmpz_poly_q_sub(fmpz_poly_q_t rop, const fmpz_poly_q_t op1, const fmpz_poly_q_t op2); + +void fmpz_poly_q_addmul(fmpz_poly_q_t rop, const fmpz_poly_q_t op1, const fmpz_poly_q_t op2); +void fmpz_poly_q_submul(fmpz_poly_q_t rop, const fmpz_poly_q_t op1, const fmpz_poly_q_t op2); + +/* Scalar multiplication and division ****************************************/ + +void fmpz_poly_q_scalar_mul_si(fmpz_poly_q_t rop, const fmpz_poly_q_t op, slong x); +void fmpz_poly_q_scalar_mul_mpz(fmpz_poly_q_t rop, const fmpz_poly_q_t op, const mpz_t x); +void fmpz_poly_q_scalar_mul_mpq(fmpz_poly_q_t rop, const fmpz_poly_q_t op, const mpq_t x); + +void fmpz_poly_q_scalar_div_si(fmpz_poly_q_t rop, const fmpz_poly_q_t op, slong x); +void fmpz_poly_q_scalar_div_mpz(fmpz_poly_q_t rop, const fmpz_poly_q_t op, const mpz_t x); +void fmpz_poly_q_scalar_div_mpq(fmpz_poly_q_t rop, const fmpz_poly_q_t op, const mpq_t x); + +/* Multiplication and division ***********************************************/ + +void fmpz_poly_q_mul(fmpz_poly_q_t rop, + const fmpz_poly_q_t op1, const fmpz_poly_q_t op2); + +void fmpz_poly_q_div(fmpz_poly_q_t rop, + const fmpz_poly_q_t op1, const fmpz_poly_q_t op2); + +/* Powering ******************************************************************/ + +void fmpz_poly_q_pow(fmpz_poly_q_t rop, const fmpz_poly_q_t op, ulong exp); + +/* Derivative ****************************************************************/ + +void fmpz_poly_q_derivative(fmpz_poly_q_t rop, const fmpz_poly_q_t op); + +/* Evaluation ****************************************************************/ + +int fmpz_poly_q_evaluate(mpq_t rop, const fmpz_poly_q_t f, const mpq_t a); + +/* Input and output **********************************************************/ + +int fmpz_poly_q_set_str(fmpz_poly_q_t rop, const char *s); + +char * fmpz_poly_q_get_str(const fmpz_poly_q_t op); +char * fmpz_poly_q_get_str_pretty(const fmpz_poly_q_t op, const char *x); + +int fmpz_poly_q_print(const fmpz_poly_q_t op); +int fmpz_poly_q_print_pretty(const fmpz_poly_q_t op, const char *x); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/external/flint-2.4.3/fmpz_poly_q/add.c b/external/flint-2.4.3/fmpz_poly_q/add.c new file mode 100644 index 0000000..e68a4ca --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/add.c @@ -0,0 +1,255 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpq_poly.h" + +#include "fmpz_poly_q.h" + +void fmpz_poly_q_add_in_place(fmpz_poly_q_t rop, const fmpz_poly_q_t op) +{ + fmpz_poly_t d, poly, r2, s2; + + if (rop == op) + { + fmpz_poly_q_scalar_mul_si(rop, rop, 2); + return; + } + + if (fmpz_poly_q_is_zero(rop)) + { + fmpz_poly_q_set(rop, op); + return; + } + if (fmpz_poly_q_is_zero(op)) + { + return; + } + + /* Polynomials? */ + if (fmpz_poly_length(rop->den) == 1 && fmpz_poly_length(op->den) == 1) + { + const slong len1 = fmpz_poly_length(rop->num); + const slong len2 = fmpz_poly_length(op->num); + + fmpz_poly_fit_length(rop->num, FLINT_MAX(len1, len2)); + _fmpq_poly_add(rop->num->coeffs, rop->den->coeffs, + rop->num->coeffs, rop->den->coeffs, len1, + op->num->coeffs, op->den->coeffs, len2); + _fmpz_poly_set_length(rop->num, FLINT_MAX(len1, len2)); + _fmpz_poly_set_length(rop->den, 1); + _fmpz_poly_normalise(rop->num); + return; + } + + /* Denominators equal to one? */ + if (fmpz_poly_is_one(rop->den)) + { + fmpz_poly_mul(rop->num, rop->num, op->den); + fmpz_poly_add(rop->num, rop->num, op->num); + fmpz_poly_set(rop->den, op->den); + return; + } + if (fmpz_poly_is_one(op->den)) + { + fmpz_poly_init(poly); + fmpz_poly_mul(poly, rop->den, op->num); + fmpz_poly_add(rop->num, rop->num, poly); + fmpz_poly_clear(poly); + return; + } + + /* Henrici's algorithm for summation in quotient fields */ + fmpz_poly_init(d); + fmpz_poly_gcd(d, rop->den, op->den); + + if (fmpz_poly_is_one(d)) + { + fmpz_poly_mul(rop->num, rop->num, op->den); + fmpz_poly_mul(d, rop->den, op->num); /* Using d as temp */ + fmpz_poly_add(rop->num, rop->num, d); + fmpz_poly_mul(rop->den, rop->den, op->den); + } + else + { + fmpz_poly_init(r2); + fmpz_poly_init(s2); + + fmpz_poly_div(r2, rop->den, d); + fmpz_poly_div(s2, op->den, d); + + fmpz_poly_mul(rop->num, rop->num, s2); + fmpz_poly_mul(s2, op->num, r2); /* Using s2 as temp */ + fmpz_poly_add(rop->num, rop->num, s2); + + if (fmpz_poly_is_zero(rop->num)) + { + fmpz_poly_zero(rop->den); + fmpz_poly_set_coeff_si(rop->den, 0, 1); + } + else + { + fmpz_poly_mul(rop->den, r2, op->den); + + fmpz_poly_gcd(r2, rop->num, d); /* Using r2 as temp */ + + if (!fmpz_poly_is_one(r2)) + { + fmpz_poly_div(rop->num, rop->num, r2); + fmpz_poly_div(rop->den, rop->den, r2); + } + } + fmpz_poly_clear(r2); + fmpz_poly_clear(s2); + } + fmpz_poly_clear(d); +} + +void +fmpz_poly_q_add(fmpz_poly_q_t rop, + const fmpz_poly_q_t op1, const fmpz_poly_q_t op2) +{ + fmpz_poly_t d, r2, s2; + + if (fmpz_poly_q_is_zero(op1)) + { + fmpz_poly_q_set(rop, op2); + return; + } + if (fmpz_poly_q_is_zero(op2)) + { + fmpz_poly_q_set(rop, op1); + return; + } + + if (op1 == op2) + { + fmpz_poly_q_scalar_mul_si(rop, op1, 2); + return; + } + if (rop == op1) + { + fmpz_poly_q_add_in_place(rop, op2); + return; + } + if (rop == op2) + { + fmpz_poly_q_add_in_place(rop, op1); + return; + } + + /* + From here on, we may assume that rop, op1 and op2 all refer to + distinct objects in memory, although they may still be equal + */ + + /* Polynomials? */ + if (fmpz_poly_length(op1->den) == 1 && fmpz_poly_length(op2->den) == 1) + { + const slong len1 = fmpz_poly_length(op1->num); + const slong len2 = fmpz_poly_length(op2->num); + + fmpz_poly_fit_length(rop->num, FLINT_MAX(len1, len2)); + _fmpq_poly_add(rop->num->coeffs, rop->den->coeffs, + op1->num->coeffs, op1->den->coeffs, len1, + op2->num->coeffs, op2->den->coeffs, len2); + _fmpz_poly_set_length(rop->num, FLINT_MAX(len1, len2)); + _fmpz_poly_set_length(rop->den, 1); + _fmpz_poly_normalise(rop->num); + return; + } + + /* Denominators equal to one? */ + if (fmpz_poly_is_one(op1->den)) + { + fmpz_poly_mul(rop->num, op1->num, op2->den); + fmpz_poly_add(rop->num, rop->num, op2->num); + fmpz_poly_set(rop->den, op2->den); + return; + } + if (fmpz_poly_is_one(op2->den)) + { + fmpz_poly_mul(rop->num, op2->num, op1->den); + fmpz_poly_add(rop->num, op1->num, rop->num); + fmpz_poly_set(rop->den, op1->den); + return; + } + + /* Henrici's algorithm for summation in quotient fields */ + + /* + We begin by using rop->num as a temporary variable for + the gcd of the two denominators' greatest common divisor + */ + fmpz_poly_gcd(rop->num, op1->den, op2->den); + + if (fmpz_poly_is_one(rop->num)) + { + fmpz_poly_mul(rop->num, op1->num, op2->den); + fmpz_poly_mul(rop->den, op1->den, op2->num); /* Using rop->den as temp */ + fmpz_poly_add(rop->num, rop->num, rop->den); + fmpz_poly_mul(rop->den, op1->den, op2->den); + } + else + { + /* + We now copy rop->num into a new variable d, so we + no longer need rop->num as a temporary variable + */ + fmpz_poly_init(d); + fmpz_poly_swap(d, rop->num); + + fmpz_poly_init(r2); + fmpz_poly_init(s2); + + fmpz_poly_div(r2, op1->den, d); /* +ve leading coeff */ + fmpz_poly_div(s2, op2->den, d); /* +ve leading coeff */ + + fmpz_poly_mul(rop->num, op1->num, s2); + fmpz_poly_mul(rop->den, op2->num, r2); /* Using rop->den as temp */ + fmpz_poly_add(rop->num, rop->num, rop->den); + + if (fmpz_poly_is_zero(rop->num)) + { + fmpz_poly_zero(rop->den); + fmpz_poly_set_coeff_si(rop->den, 0, 1); + } + else + { + fmpz_poly_mul(rop->den, op1->den, s2); + + fmpz_poly_gcd(r2, rop->num, d); + + if (!fmpz_poly_is_one(r2)) + { + fmpz_poly_div(rop->num, rop->num, r2); + fmpz_poly_div(rop->den, rop->den, r2); + } + } + + fmpz_poly_clear(d); + fmpz_poly_clear(r2); + fmpz_poly_clear(s2); + } +} diff --git a/external/flint-2.4.3/fmpz_poly_q/addmul.c b/external/flint-2.4.3/fmpz_poly_q/addmul.c new file mode 100644 index 0000000..5bf70bf --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/addmul.c @@ -0,0 +1,37 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_poly_q.h" + +void fmpz_poly_q_addmul(fmpz_poly_q_t rop, + const fmpz_poly_q_t op1, const fmpz_poly_q_t op2) +{ + fmpz_poly_q_t temp; + + fmpz_poly_q_init(temp); + fmpz_poly_q_mul(temp, op1, op2); + fmpz_poly_q_add(rop, rop, temp); + fmpz_poly_q_clear(temp); +} diff --git a/external/flint-2.4.3/fmpz_poly_q/canonicalise.c b/external/flint-2.4.3/fmpz_poly_q/canonicalise.c new file mode 100644 index 0000000..9cafe4e --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/canonicalise.c @@ -0,0 +1,56 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_poly_q.h" + +void fmpz_poly_q_canonicalise(fmpz_poly_q_t rop) +{ + fmpz_poly_t gcd; + + if (fmpz_poly_is_zero(rop->den)) + { + flint_printf("Exception (fmpz_poly_q_canonicalise). Denominator is zero.\n"); + abort(); + } + + if (fmpz_poly_is_one(rop->den)) + return; + + fmpz_poly_init(gcd); + fmpz_poly_gcd(gcd, rop->num, rop->den); + if (!fmpz_poly_is_unit(gcd)) + { + fmpz_poly_div(rop->num, rop->num, gcd); + fmpz_poly_div(rop->den, rop->den, gcd); + } + fmpz_poly_clear(gcd); + + if (fmpz_sgn(fmpz_poly_lead(rop->den)) < 0) + { + fmpz_poly_neg(rop->num, rop->num); + fmpz_poly_neg(rop->den, rop->den); + } +} + diff --git a/external/flint-2.4.3/fmpz_poly_q/clear.c b/external/flint-2.4.3/fmpz_poly_q/clear.c new file mode 100644 index 0000000..bd82831 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/clear.c @@ -0,0 +1,43 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_poly_q.h" + +void fmpz_poly_q_clear(fmpz_poly_q_t rop) +{ + if (rop->num != NULL) + { + fmpz_poly_clear(rop->num); + flint_free(rop->num); + rop->num = NULL; + } + if (rop->den != NULL); + { + fmpz_poly_clear(rop->den); + flint_free(rop->den); + rop->den = NULL; + } +} + diff --git a/external/flint-2.4.3/fmpz_poly_q/derivative.c b/external/flint-2.4.3/fmpz_poly_q/derivative.c new file mode 100644 index 0000000..f98ed8b --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/derivative.c @@ -0,0 +1,96 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_poly_q.h" + +void fmpz_poly_q_derivative(fmpz_poly_q_t rop, const fmpz_poly_q_t op) +{ + fmpz_poly_t d, lhs, rhs; + + if (fmpz_poly_q_is_zero(op)) + { + fmpz_poly_q_zero(rop); + return; + } + + if (fmpz_poly_length(op->den) == 1) + { + fmpz_poly_derivative(rop->num, op->num); + fmpz_poly_set(rop->den, op->den); + fmpz_poly_q_canonicalise(rop); + return; + } + + fmpz_poly_init(d); + fmpz_poly_init(rhs); + + fmpz_poly_derivative(rhs, op->den); + fmpz_poly_gcd(d, rhs, op->den); + if (!fmpz_poly_is_one(d)) + fmpz_poly_div(rhs, rhs, d); + fmpz_poly_mul(rhs, op->num, rhs); + + fmpz_poly_derivative(rop->num, op->num); + if (fmpz_poly_is_one(d)) + { + fmpz_poly_mul(rop->num, rop->num, op->den); + fmpz_poly_pow(rop->den, op->den, 2); + } + else + { + fmpz_poly_init(lhs); + fmpz_poly_div(lhs, op->den, d); + fmpz_poly_mul(rop->num, rop->num, lhs); + fmpz_poly_mul(rop->den, op->den, lhs); + fmpz_poly_clear(lhs); + } + fmpz_poly_sub(rop->num, rop->num, rhs); + + /* Canonicalise: there can be at most a constant factor */ + { + fmpz_t a, b, c; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + + fmpz_poly_content(a, rop->num); + fmpz_poly_content(b, rop->den); + fmpz_gcd(c, a, b); + + if (!fmpz_is_one(c)) + { + fmpz_poly_scalar_divexact_fmpz(rop->num, rop->num, c); + fmpz_poly_scalar_divexact_fmpz(rop->den, rop->den, c); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + } + + fmpz_poly_clear(d); + fmpz_poly_clear(rhs); +} diff --git a/external/flint-2.4.3/fmpz_poly_q/div.c b/external/flint-2.4.3/fmpz_poly_q/div.c new file mode 100644 index 0000000..a7192d3 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/div.c @@ -0,0 +1,137 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpq_poly.h" + +#include "fmpz_poly_q.h" + +void fmpz_poly_q_div(fmpz_poly_q_t rop, + const fmpz_poly_q_t op1, const fmpz_poly_q_t op2) +{ + if (fmpz_poly_q_is_zero(op2)) + { + flint_printf("Exception (fmpz_poly_q_div). Division by zero.\n"); + abort(); + } + if (fmpz_poly_q_is_zero(op1)) + { + fmpz_poly_q_zero(rop); + return; + } + + if (op1 == op2) + { + fmpz_poly_q_one(rop); + return; + } + if (rop == op1 || rop == op2) + { + fmpz_poly_q_t t; + + fmpz_poly_q_init(t); + fmpz_poly_q_div(t, op1, op2); + fmpz_poly_q_swap(rop, t); + fmpz_poly_q_clear(t); + return; + } + + /* + From here on, we know that rop, op1 and op2 refer to distinct objects + in memory, and that op1 and op2 are non-zero rational functions + */ + + /* + XXX: Do not maintain the remaining part of the function separately!!! + Instead, note that this is the same as the corresponding part of + the multiplication code, with op2->num and op2->den swapped. + + The only caveat to this is that we cannot assume the leading + coefficient of op2->num to be positive, and thus check for this + in the very end. + */ + + /* Denominator/ numerator equal to one? */ + if (fmpz_poly_is_one(op1->den) && fmpz_poly_is_one(op2->num)) + { + fmpz_poly_mul(rop->num, op1->num, op2->den); + fmpz_poly_set_si(rop->den, 1); + return; + } + + fmpz_poly_gcd(rop->num, op1->num, op2->num); + + if (fmpz_poly_is_one(rop->num)) + { + fmpz_poly_gcd(rop->den, op2->den, op1->den); + + if (fmpz_poly_is_one(rop->den)) + { + fmpz_poly_mul(rop->num, op1->num, op2->den); + fmpz_poly_mul(rop->den, op1->den, op2->num); + } + else + { + fmpz_poly_div(rop->num, op2->den, rop->den); + fmpz_poly_mul(rop->num, op1->num, rop->num); + fmpz_poly_div(rop->den, op1->den, rop->den); + fmpz_poly_mul(rop->den, rop->den, op2->num); + } + } + else + { + fmpz_poly_gcd(rop->den, op2->den, op1->den); + + if (fmpz_poly_is_one(rop->den)) + { + fmpz_poly_div(rop->den, op2->num, rop->num); + fmpz_poly_mul(rop->den, op1->den, rop->den); + fmpz_poly_div(rop->num, op1->num, rop->num); + fmpz_poly_mul(rop->num, rop->num, op2->den); + } + else + { + fmpz_poly_t t, u; + + fmpz_poly_init(t); + fmpz_poly_init(u); + fmpz_poly_div(t, op1->num, rop->num); + fmpz_poly_div(u, op2->num, rop->num); + fmpz_poly_div(rop->num, op2->den, rop->den); + fmpz_poly_mul(rop->num, t, rop->num); + fmpz_poly_div(rop->den, op1->den, rop->den); + fmpz_poly_mul(rop->den, rop->den, u); + fmpz_poly_clear(t); + fmpz_poly_clear(u); + } + } + + /* XXX: Check that the numerator has the appropriate sign. */ + if (fmpz_sgn(fmpz_poly_lead(rop->den)) < 0) + { + fmpz_poly_neg(rop->num, rop->num); + fmpz_poly_neg(rop->den, rop->den); + } +} + diff --git a/external/flint-2.4.3/fmpz_poly_q/doc/fmpz_poly_q.txt b/external/flint-2.4.3/fmpz_poly_q/doc/fmpz_poly_q.txt new file mode 100644 index 0000000..3ccae24 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/doc/fmpz_poly_q.txt @@ -0,0 +1,320 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009, 2010, 2011 Sebastian Pancratz + +******************************************************************************/ + +******************************************************************************* + + Memory management + + We represent a rational function over $\mathbf{Q}$ as the quotient + of two coprime integer polynomials of type \code{fmpz_poly_t}, + enforcing that the leading coefficient of the denominator is + positive. The zero function is represented as $0/1$. + +******************************************************************************* + +void fmpz_poly_q_init(fmpz_poly_q_t rop) + + Initialises \code{rop}. + +void fmpz_poly_q_clear(fmpz_poly_q_t rop) + + Clears the object \code{rop}. + +fmpz_poly_struct * fmpz_poly_q_numref(const fmpz_poly_q_t op) + + Returns a reference to the numerator of \code{op}. + +fmpz_poly_struct * fmpz_poly_q_denref(const fmpz_poly_q_t op) + + Returns a reference to the denominator of \code{op}. + +void fmpz_poly_q_canonicalise(fmpz_poly_q_t rop) + + Brings \code{rop} into canonical form, only assuming that + the denominator is non-zero. + +int fmpz_poly_q_is_canonical(const fmpz_poly_q_t op) + + Checks whether the rational function \code{op} is in + canonical form. + +******************************************************************************* + + Randomisation + +******************************************************************************* + +void fmpz_poly_q_randtest(fmpz_poly_q_t poly, flint_rand_t state, + slong len1, mp_bitcnt_t bits1, + slong len2, mp_bitcnt_t bits2) + + Sets \code{poly} to a random rational function. + +void fmpz_poly_q_randtest_not_zero(fmpz_poly_q_t poly, flint_rand_t state, + slong len1, mp_bitcnt_t bits1, + slong len2, mp_bitcnt_t bits2) + + Sets \code{poly} to a random non-zero rational function. + +******************************************************************************* + + Assignment + +******************************************************************************* + +void fmpz_poly_q_set(fmpz_poly_q_t rop, const fmpz_poly_q_t op) + + Sets the element \code{rop} to the same value as the element \code{op}. + +void fmpz_poly_q_set_si(fmpz_poly_q_t rop, slong op) + + Sets the element \code{rop} to the value given by the \code{slong} + \code{op}. + +void fmpz_poly_q_swap(fmpz_poly_q_t op1, fmpz_poly_q_t op2) + + Swaps the elements \code{op1} and \code{op2}. + + This is done efficiently by swapping pointers. + +void fmpz_poly_q_zero(fmpz_poly_q_t rop) + + Sets \code{rop} to zero. + +void fmpz_poly_q_one(fmpz_poly_q_t rop) + + Sets \code{rop} to one. + +void fmpz_poly_q_neg(fmpz_poly_q_t rop, const fmpz_poly_q_t op) + + Sets the element \code{rop} to the additive inverse of \code{op}. + +void fmpz_poly_q_inv(fmpz_poly_q_t rop, const fmpz_poly_q_t op) + + Sets the element \code{rop} to the multiplicative inverse of \code{op}. + + Assumes that the element \code{op} is non-zero. + +******************************************************************************* + + Comparison + +******************************************************************************* + +int fmpz_poly_q_is_zero(const fmpz_poly_q_t op) + + Returns whether the element \code{op} is zero. + +int fmpz_poly_q_is_one(const fmpz_poly_q_t op) + + Returns whether the element \code{rop} is equal to the constant + polynomial $1$. + +int fmpz_poly_q_equal(const fmpz_poly_q_t op1, const fmpz_poly_q_t op2) + + Returns whether the two elements \code{op1} and \code{op2} are equal. + +******************************************************************************* + + Addition and subtraction + +******************************************************************************* + +void fmpz_poly_q_add(fmpz_poly_q_t rop, + const fmpz_poly_q_t op1, const fmpz_poly_q_t op2) + + Sets \code{rop} to the sum of \code{op1} and \code{op2}. + +void fmpz_poly_q_sub(fmpz_poly_q_t rop, + const fmpz_poly_q_t op1, const fmpz_poly_q_t op2) + + Sets \code{rop} to the difference of \code{op1} and \code{op2}. + +void fmpz_poly_q_addmul(fmpz_poly_q_t rop, + const fmpz_poly_q_t op1, const fmpz_poly_q_t op2) + + Adds the product of \code{op1} and \code{op2} to \code{rop}. + +void fmpz_poly_q_submul(fmpz_poly_q_t rop, + const fmpz_poly_q_t op1, const fmpz_poly_q_t op2) + + Subtracts the product of \code{op1} and \code{op2} from \code{rop}. + +******************************************************************************* + + Scalar multiplication and division + +******************************************************************************* + +void fmpz_poly_q_scalar_mul_si(fmpz_poly_q_t rop, + const fmpz_poly_q_t op, slong x) + + Sets \code{rop} to the product of the rational function \code{op} + and the \code{slong} integer $x$. + +void fmpz_poly_q_scalar_mul_mpz(fmpz_poly_q_t rop, + const fmpz_poly_q_t op, const mpz_t x) + + Sets \code{rop} to the product of the rational function \code{op} + and the \code{mpz_t} integer $x$. + +void fmpz_poly_q_scalar_mul_mpq(fmpz_poly_q_t rop, + const fmpz_poly_q_t op, const mpq_t x) + + Sets \code{rop} to the product of the rational function \code{op} + and the \code{mpq_t} rational $x$. + +void fmpz_poly_q_scalar_div_si(fmpz_poly_q_t rop, + const fmpz_poly_q_t op, slong x) + + Sets \code{rop} to the quotient of the rational function \code{op} + and the \code{slong} integer $x$. + +void fmpz_poly_q_scalar_div_mpz(fmpz_poly_q_t rop, + const fmpz_poly_q_t op, const mpz_t x) + + Sets \code{rop} to the quotient of the rational function \code{op} + and the \code{mpz_t} integer $x$. + +void fmpz_poly_q_scalar_div_mpq(fmpz_poly_q_t rop, + const fmpz_poly_q_t op, const mpq_t x) + + Sets \code{rop} to the quotient of the rational function \code{op} + and the \code{mpq_t} rational $x$. + +******************************************************************************* + + Multiplication and division + +******************************************************************************* + +void fmpz_poly_q_mul(fmpz_poly_q_t rop, + const fmpz_poly_q_t op1, const fmpz_poly_q_t op2) + + Sets \code{rop} to the product of \code{op1} and \code{op2}. + +void fmpz_poly_q_div(fmpz_poly_q_t rop, + const fmpz_poly_q_t op1, const fmpz_poly_q_t op2) + + Sets \code{rop} to the quotient of \code{op1} and \code{op2}. + +******************************************************************************* + + Powering + +******************************************************************************* + +void fmpz_poly_q_pow(fmpz_poly_q_t rop, const fmpz_poly_q_t op, ulong exp) + + Sets \code{rop} to the \code{exp}-th power of \code{op}. + + The corner case of \code{exp == 0} is handled by setting \code{rop} to + the constant function $1$. Note that this includes the case $0^0 = 1$. + +******************************************************************************* + + Derivative + +******************************************************************************* + +void fmpz_poly_q_derivative(fmpz_poly_q_t rop, const fmpz_poly_q_t op) + + Sets \code{rop} to the derivative of \code{op}. + +******************************************************************************* + + Evaluation + +******************************************************************************* + +int fmpz_poly_q_evaluate(mpq_t rop, const fmpz_poly_q_t f, const mpq_t a) + + Sets \code{rop} to $f$ evaluated at the rational $a$. + + If the denominator evaluates to zero at $a$, returns non-zero and + does not modify any of the variables. Otherwise, returns $0$ and + sets \code{rop} to the rational $f(a)$. + +******************************************************************************* + + Input and output + + The following three methods enable users to construct elements of type\\ + \code{fmpz_poly_q_t} from strings or to obtain string representations of + such elements. + + The format used is based on the FLINT format for integer polynomials of + type \code{fmpz_poly_t}, which we recall first: + + A non-zero polynomial $a_0 + a_1 X + \dotsb + a_n X^n$ of length + $n + 1$ is represented by the string \code{"n+1 a_0 a_1 ... a_n"}, + where there are two space characters following the length and single + space characters separating the individual coefficients. There is no + leading or trailing white-space. The zero polynomial is simply + represented by \code{"0"}. + + We adapt this notation for rational functions as follows. We denote the + zero function by \code{"0"}. Given a non-zero function with numerator + and denominator string representations \code{num} and \code{den}, + respectively, we use the string \code{num/den} to represent the rational + function, unless the denominator is equal to one, in which case we simply + use \code{num}. + + There is also a \code{_pretty} variant available, which bases the string + parts for the numerator and denominator on the output of the function + \code{fmpz_poly_get_str_pretty} and introduces parentheses where + necessary. + + Note that currently these functions are not optimised for performance and + are intended to be used only for debugging purposes or one-off input and + output, rather than as a low-level parser. + +******************************************************************************* + +int fmpz_poly_q_set_str(fmpz_poly_q_t rop, const char *s) + + Sets \code{rop} to the rational function given + by the string \code{s}. + +char * fmpz_poly_q_get_str(const fmpz_poly_q_t op) + + Returns the string representation of + the rational function \code{op}. + +char * fmpz_poly_q_get_str_pretty(const fmpz_poly_q_t op, const char *x) + + Returns the pretty string representation of + the rational function \code{op}. + +int fmpz_poly_q_print(const fmpz_poly_q_t op) + + Prints the representation of the rational + function \code{op} to \code{stdout}. + +int fmpz_poly_q_print_pretty(const fmpz_poly_q_t op, const char *x) + + Prints the pretty representation of the rational + function \code{op} to \code{stdout}. + diff --git a/external/flint-2.4.3/fmpz_poly_q/evaluate.c b/external/flint-2.4.3/fmpz_poly_q/evaluate.c new file mode 100644 index 0000000..69c8d24 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/evaluate.c @@ -0,0 +1,81 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_poly_q.h" + +int fmpz_poly_q_evaluate(mpq_t rop, const fmpz_poly_q_t f, const mpq_t a) +{ + if (flint_mpz_cmp_si(mpq_denref(a), 1)) /* a is not an integer */ + { + mpq_t mpqnum, mpqden; + + mpq_init(mpqden); + fmpz_poly_evaluate_mpq(mpqden, f->den, a); + if (mpq_sgn(mpqden) == 0) + { + mpq_clear(mpqden); + return 1; + } + + mpq_init(mpqnum); + + fmpz_poly_evaluate_mpq(mpqnum, f->num, a); + mpq_div(rop, mpqnum, mpqden); + + mpq_clear(mpqnum); + mpq_clear(mpqden); + return 0; + } + else /* a is an integer */ + { + fmpz_t num, den, a2; + + fmpz_init(num); + fmpz_init(den); + fmpz_init(a2); + + fmpz_set_mpz(a2, mpq_numref(a)); + + fmpz_poly_evaluate_fmpz(den, f->den, a2); + if (fmpz_is_zero(den)) + { + fmpz_clear(a2); + fmpz_clear(num); + fmpz_clear(den); + return 1; + } + + fmpz_poly_evaluate_fmpz(num, f->num, a2); + + fmpz_get_mpz(mpq_numref(rop), num); + fmpz_get_mpz(mpq_denref(rop), den); + mpq_canonicalize(rop); + + fmpz_clear(a2); + fmpz_clear(num); + fmpz_clear(den); + return 0; + } +} diff --git a/external/flint-2.4.3/fmpz_poly_q/get_str.c b/external/flint-2.4.3/fmpz_poly_q/get_str.c new file mode 100644 index 0000000..de8a406 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/get_str.c @@ -0,0 +1,83 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include + +#include "fmpz_poly_q.h" + +/** + * \ingroup StringConversions + * + * Returns the string representation of the rational function \c op. + */ +char * fmpz_poly_q_get_str(const fmpz_poly_q_t op) +{ + int i, j; + char * str; + char * numstr; + char * denstr; + + if (fmpz_poly_is_one(op->den)) + { + numstr = fmpz_poly_get_str(op->num); + i = strlen(numstr) - 1; + if (numstr[i] == ' ') + { + numstr[i] = '\0'; + } + return numstr; + } + + numstr = fmpz_poly_get_str(op->num); + denstr = fmpz_poly_get_str(op->den); + + i = strlen(numstr) - 1; + if (numstr[i] == ' ') + numstr[i] = '\0'; + i = strlen(denstr) - 1; + if (denstr[i] == ' ') + denstr[i] = '\0'; + + str = flint_malloc(strlen(numstr) + strlen(denstr) + 2); + if (str == NULL) + { + flint_printf("Exception (fmpz_poly_q_get_str). Memory allocation failed.\n"); + abort(); + } + + for (i = 0; i < strlen(numstr); i++) + str[i] = numstr[i]; + str[i++] = '/'; + for (j = 0; j < strlen(denstr); j++) + str[i++] = denstr[j]; + str[i] = '\0'; + + flint_free(numstr); + flint_free(denstr); + + return str; +} diff --git a/external/flint-2.4.3/fmpz_poly_q/get_str_pretty.c b/external/flint-2.4.3/fmpz_poly_q/get_str_pretty.c new file mode 100644 index 0000000..8ed6cb8 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/get_str_pretty.c @@ -0,0 +1,94 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include + +#include "fmpz_poly_q.h" + +/** + * \ingroup StringConversions + * + * Returns the pretty string representation of \c op. + * + * Returns the pretty string representation of the rational function \c op, + * using the string \c x as the variable name. + */ +char * fmpz_poly_q_get_str_pretty(const fmpz_poly_q_t op, const char *x) +{ + int i, j; + char * str; + char * numstr; + char * denstr; + + if (fmpz_poly_is_one(op->den)) + { + return fmpz_poly_get_str_pretty(op->num, x); + } + + numstr = fmpz_poly_get_str_pretty(op->num, x); + denstr = fmpz_poly_get_str_pretty(op->den, x); + + str = flint_malloc(strlen(numstr) + strlen(denstr) + 6); + if (!str) + { + flint_printf("Exception (fmpz_poly_q_get_str_pretty). Memory allocation failed.\n"); + abort(); + } + + i = 0; + if (fmpz_poly_degree(op->num) > 0) + { + str[i++] = '('; + for (j = 0; j < strlen(numstr); j++) + str[i++] = numstr[j]; + str[i++] = ')'; + } + else + { + for (j = 0; j < strlen(numstr); j++) + str[i++] = numstr[j]; + } + str[i++] = '/'; + if (fmpz_poly_degree(op->den) > 0) + { + str[i++] = '('; + for (j = 0; j < strlen(denstr); j++) + str[i++] = denstr[j]; + str[i++] = ')'; + } + else + { + for (j = 0; j < strlen(denstr); j++) + str[i++] = denstr[j]; + } + str[i] = '\0'; + + flint_free(numstr); + flint_free(denstr); + + return str; +} diff --git a/external/flint-2.4.3/fmpz_poly_q/init.c b/external/flint-2.4.3/fmpz_poly_q/init.c new file mode 100644 index 0000000..dc4bb62 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/init.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_poly_q.h" + +void fmpz_poly_q_init(fmpz_poly_q_t rop) +{ + rop->num = flint_malloc(sizeof(fmpz_poly_struct)); + rop->den = flint_malloc(sizeof(fmpz_poly_struct)); + fmpz_poly_init(rop->num); + fmpz_poly_init(rop->den); + fmpz_poly_set_si(rop->den, 1); +} + diff --git a/external/flint-2.4.3/fmpz_poly_q/inv.c b/external/flint-2.4.3/fmpz_poly_q/inv.c new file mode 100644 index 0000000..dafdeb7 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/inv.c @@ -0,0 +1,59 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_poly_q.h" + +void fmpz_poly_q_inv(fmpz_poly_q_t rop, const fmpz_poly_q_t op) +{ + if (fmpz_poly_is_zero(op->num)) + { + flint_printf("Exception (fmpz_poly_q_inv). Zero is not invertible.\n"); + abort(); + } + + if (rop == op) + { + fmpz_poly_swap(rop->num, rop->den); + if (fmpz_sgn(fmpz_poly_lead(rop->den)) < 0) + { + fmpz_poly_neg(rop->num, rop->num); + fmpz_poly_neg(rop->den, rop->den); + } + } + else + { + if (fmpz_sgn(fmpz_poly_lead(op->num)) > 0) + { + fmpz_poly_set(rop->num, op->den); + fmpz_poly_set(rop->den, op->num); + } + else + { + fmpz_poly_neg(rop->num, op->den); + fmpz_poly_neg(rop->den, op->num); + } + } +} + diff --git a/external/flint-2.4.3/fmpz_poly_q/is_canonical.c b/external/flint-2.4.3/fmpz_poly_q/is_canonical.c new file mode 100644 index 0000000..e4c5535 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/is_canonical.c @@ -0,0 +1,45 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_poly_q.h" + +int fmpz_poly_q_is_canonical(const fmpz_poly_q_t op) +{ + int ans; + fmpz_poly_t t; + + if (fmpz_poly_is_zero(op->den)) + return 0; + + if (fmpz_sgn(fmpz_poly_lead(op->den)) < 0) + return 0; + + fmpz_poly_init(t); + fmpz_poly_gcd(t, op->num, op->den); + ans = fmpz_poly_is_one(t); + fmpz_poly_clear(t); + return ans; +} + diff --git a/external/flint-2.4.3/fmpz_poly_q/mul.c b/external/flint-2.4.3/fmpz_poly_q/mul.c new file mode 100644 index 0000000..74bc9ac --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/mul.c @@ -0,0 +1,132 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpq_poly.h" + +#include "fmpz_poly_q.h" + +void fmpz_poly_q_mul(fmpz_poly_q_t rop, + const fmpz_poly_q_t op1, const fmpz_poly_q_t op2) +{ + if (fmpz_poly_q_is_zero(op1) || fmpz_poly_q_is_zero(op2)) + { + fmpz_poly_q_zero(rop); + return; + } + + if (op1 == op2) + { + fmpz_poly_pow(rop->num, op1->num, 2); + fmpz_poly_pow(rop->den, op1->den, 2); + return; + } + if (rop == op1 || rop == op2) + { + fmpz_poly_q_t t; + + fmpz_poly_q_init(t); + fmpz_poly_q_mul(t, op1, op2); + fmpz_poly_q_swap(rop, t); + fmpz_poly_q_clear(t); + return; + } + + /* + From here on, we may assume that rop, op1 and op2 refer to distinct + objects in memory, and that op1 and op2 are non-zero + */ + + /* Polynomials? */ + if (fmpz_poly_length(op1->den) == 1 && fmpz_poly_length(op2->den) == 1) + { + const slong len1 = fmpz_poly_length(op1->num); + const slong len2 = fmpz_poly_length(op2->num); + + fmpz_poly_fit_length(rop->num, len1 + len2 - 1); + if (len1 >= len2) + { + _fmpq_poly_mul(rop->num->coeffs, rop->den->coeffs, + op1->num->coeffs, op1->den->coeffs, len1, + op2->num->coeffs, op2->den->coeffs, len2); + } + else + { + _fmpq_poly_mul(rop->num->coeffs, rop->den->coeffs, + op2->num->coeffs, op2->den->coeffs, len2, + op1->num->coeffs, op1->den->coeffs, len1); + } + _fmpz_poly_set_length(rop->num, len1 + len2 - 1); + _fmpz_poly_set_length(rop->den, 1); + + return; + } + + fmpz_poly_gcd(rop->num, op1->num, op2->den); + + if (fmpz_poly_is_one(rop->num)) + { + fmpz_poly_gcd(rop->den, op2->num, op1->den); + + if (fmpz_poly_is_one(rop->den)) + { + fmpz_poly_mul(rop->num, op1->num, op2->num); + fmpz_poly_mul(rop->den, op1->den, op2->den); + } + else + { + fmpz_poly_div(rop->num, op2->num, rop->den); + fmpz_poly_mul(rop->num, op1->num, rop->num); + fmpz_poly_div(rop->den, op1->den, rop->den); + fmpz_poly_mul(rop->den, rop->den, op2->den); + } + } + else + { + fmpz_poly_gcd(rop->den, op2->num, op1->den); + + if (fmpz_poly_is_one(rop->den)) + { + fmpz_poly_div(rop->den, op2->den, rop->num); + fmpz_poly_mul(rop->den, op1->den, rop->den); + fmpz_poly_div(rop->num, op1->num, rop->num); + fmpz_poly_mul(rop->num, rop->num, op2->num); + } + else + { + fmpz_poly_t t, u; + + fmpz_poly_init(t); + fmpz_poly_init(u); + fmpz_poly_div(t, op1->num, rop->num); + fmpz_poly_div(u, op2->den, rop->num); + fmpz_poly_div(rop->num, op2->num, rop->den); + fmpz_poly_mul(rop->num, t, rop->num); + fmpz_poly_div(rop->den, op1->den, rop->den); + fmpz_poly_mul(rop->den, rop->den, u); + fmpz_poly_clear(t); + fmpz_poly_clear(u); + } + } +} diff --git a/external/flint-2.4.3/fmpz_poly_q/pow.c b/external/flint-2.4.3/fmpz_poly_q/pow.c new file mode 100644 index 0000000..6f81150 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/pow.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_poly_q.h" + +void fmpz_poly_q_pow(fmpz_poly_q_t rop, + const fmpz_poly_q_t op, ulong exp) +{ + if (exp == 0) + { + fmpz_poly_q_one(rop); + } + else + { + fmpz_poly_pow(rop->num, op->num, exp); + fmpz_poly_pow(rop->den, op->den, exp); + } +} diff --git a/external/flint-2.4.3/fmpz_poly_q/print.c b/external/flint-2.4.3/fmpz_poly_q/print.c new file mode 100644 index 0000000..dc6b90f --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/print.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include + +#include "fmpz_poly_q.h" + +int fmpz_poly_q_print(const fmpz_poly_q_t op) +{ + char *str; + + str = fmpz_poly_q_get_str(op); + flint_printf("%s", str); + flint_free(str); + + return 1; +} diff --git a/external/flint-2.4.3/fmpz_poly_q/print_pretty.c b/external/flint-2.4.3/fmpz_poly_q/print_pretty.c new file mode 100644 index 0000000..7ada4b0 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/print_pretty.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include + +#include "fmpz_poly_q.h" + +int fmpz_poly_q_print_pretty(const fmpz_poly_q_t op, const char *x) +{ + char *str; + + str = fmpz_poly_q_get_str_pretty(op, x); + flint_printf("%s", str); + flint_free(str); + + return 1; +} diff --git a/external/flint-2.4.3/fmpz_poly_q/randtest.c b/external/flint-2.4.3/fmpz_poly_q/randtest.c new file mode 100644 index 0000000..55d5aa8 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/randtest.c @@ -0,0 +1,52 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_poly_q.h" + +void fmpz_poly_q_randtest(fmpz_poly_q_t poly, flint_rand_t state, + slong len1, mp_bitcnt_t bits1, + slong len2, mp_bitcnt_t bits2) +{ + len2 = FLINT_MAX(len2, 1); + bits2 = FLINT_MAX(bits2, 1); + + fmpz_poly_randtest(poly->num, state, len1, bits1); + fmpz_poly_randtest_not_zero(poly->den, state, len2, bits2); + fmpz_poly_q_canonicalise(poly); +} + +void fmpz_poly_q_randtest_not_zero(fmpz_poly_q_t poly, flint_rand_t state, + slong len1, mp_bitcnt_t bits1, + slong len2, mp_bitcnt_t bits2) +{ + len1 = FLINT_MAX(len1, 1); + len2 = FLINT_MAX(len2, 1); + bits1 = FLINT_MAX(bits1, 1); + bits2 = FLINT_MAX(bits2, 1); + + fmpz_poly_randtest_not_zero(poly->num, state, len1, bits1); + fmpz_poly_randtest_not_zero(poly->den, state, len2, bits2); + fmpz_poly_q_canonicalise(poly); +} diff --git a/external/flint-2.4.3/fmpz_poly_q/scalar_div_mpq.c b/external/flint-2.4.3/fmpz_poly_q/scalar_div_mpq.c new file mode 100644 index 0000000..a7933e3 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/scalar_div_mpq.c @@ -0,0 +1,50 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_poly_q.h" + +void fmpz_poly_q_scalar_div_mpq(fmpz_poly_q_t rop, + const fmpz_poly_q_t op, const mpq_t x) +{ + fmpz_t num, den; + + if (mpz_sgn(mpq_numref(x)) == 0) + { + flint_printf("Exception (fmpz_poly_q_scalar_div_mpq). Division by zero.\n"); + abort(); + } + + fmpz_init(num); + fmpz_init(den); + fmpz_set_mpz(num, mpq_numref(x)); + fmpz_set_mpz(den, mpq_denref(x)); + + fmpz_poly_scalar_mul_fmpz(rop->num, op->num, den); + fmpz_poly_scalar_mul_fmpz(rop->den, op->den, num); + fmpz_poly_q_canonicalise(rop); + + fmpz_clear(num); + fmpz_clear(den); +} diff --git a/external/flint-2.4.3/fmpz_poly_q/scalar_div_mpz.c b/external/flint-2.4.3/fmpz_poly_q/scalar_div_mpz.c new file mode 100644 index 0000000..6a999d9 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/scalar_div_mpz.c @@ -0,0 +1,47 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_poly_q.h" + +void fmpz_poly_q_scalar_div_mpz(fmpz_poly_q_t rop, + const fmpz_poly_q_t op, const mpz_t x) +{ + fmpz_t y; + + if (mpz_sgn(x) == 0) + { + flint_printf("Exception (fmpz_poly_q_scalar_div_mpz). Division by zero.\n"); + abort(); + } + + fmpz_init(y); + fmpz_set_mpz(y, x); + + fmpz_poly_set(rop->num, op->num); + fmpz_poly_scalar_mul_fmpz(rop->den, op->den, y); + fmpz_poly_q_canonicalise(rop); + + fmpz_clear(y); +} diff --git a/external/flint-2.4.3/fmpz_poly_q/scalar_div_si.c b/external/flint-2.4.3/fmpz_poly_q/scalar_div_si.c new file mode 100644 index 0000000..7dfaaae --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/scalar_div_si.c @@ -0,0 +1,104 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_poly_q.h" + +void fmpz_poly_q_scalar_div_si(fmpz_poly_q_t rop, const fmpz_poly_q_t op, slong x) +{ + fmpz_t cont, fx, gcd; + + if (FLINT_ABS(x) <= 1) + { + if (x == 0) + { + flint_printf("Exception (fmpz_poly_q_scalar_div_si). Division by zero.\n"); + abort(); + } + if (x == 1) + fmpz_poly_q_set(rop, op); + else + fmpz_poly_q_neg(rop, op); + return; + } + if (fmpz_poly_q_is_zero(op)) + { + fmpz_poly_q_zero(rop); + return; + } + + fmpz_init(cont); + fmpz_poly_content(cont, op->num); + + if (fmpz_is_one(cont)) + { + if (x > 0) + { + fmpz_poly_set(rop->num, op->num); + fmpz_poly_scalar_mul_si(rop->den, op->den, x); + } + else + { + fmpz_poly_neg(rop->num, op->num); + fmpz_poly_scalar_mul_ui(rop->den, op->den, - ((ulong) x)); + } + fmpz_clear(cont); + return; + } + + fmpz_init(fx); + fmpz_init(gcd); + + fmpz_set_si(fx, x); + fmpz_gcd(gcd, cont, fx); + + if (fmpz_is_one(gcd)) + { + if (x > 0) + { + fmpz_poly_set(rop->num, op->num); + fmpz_poly_scalar_mul_si(rop->den, op->den, x); + } + else + { + fmpz_poly_neg(rop->num, op->num); + fmpz_poly_scalar_mul_ui(rop->den, op->den, - ((ulong) x)); + } + } + else + { + fmpz_poly_scalar_divexact_fmpz(rop->num, op->num, gcd); + fmpz_divexact(fx, fx, gcd); + fmpz_poly_scalar_mul_fmpz(rop->den, op->den, fx); + if (x < 0) + { + fmpz_poly_neg(rop->num, rop->num); + fmpz_poly_neg(rop->den, rop->den); + } + } + + fmpz_clear(cont); + fmpz_clear(fx); + fmpz_clear(gcd); +} diff --git a/external/flint-2.4.3/fmpz_poly_q/scalar_mul_mpq.c b/external/flint-2.4.3/fmpz_poly_q/scalar_mul_mpq.c new file mode 100644 index 0000000..8043285 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/scalar_mul_mpq.c @@ -0,0 +1,44 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_poly_q.h" + +void fmpz_poly_q_scalar_mul_mpq(fmpz_poly_q_t rop, + const fmpz_poly_q_t op, const mpq_t x) +{ + fmpz_t num, den; + + fmpz_init(num); + fmpz_init(den); + fmpz_set_mpz(num, mpq_numref(x)); + fmpz_set_mpz(den, mpq_denref(x)); + + fmpz_poly_scalar_mul_fmpz(rop->num, op->num, num); + fmpz_poly_scalar_mul_fmpz(rop->den, op->den, den); + fmpz_poly_q_canonicalise(rop); + + fmpz_clear(num); + fmpz_clear(den); +} diff --git a/external/flint-2.4.3/fmpz_poly_q/scalar_mul_mpz.c b/external/flint-2.4.3/fmpz_poly_q/scalar_mul_mpz.c new file mode 100644 index 0000000..18c1dcd --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/scalar_mul_mpz.c @@ -0,0 +1,41 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_poly_q.h" + +void fmpz_poly_q_scalar_mul_mpz(fmpz_poly_q_t rop, + const fmpz_poly_q_t op, const mpz_t x) +{ + fmpz_t y; + + fmpz_init(y); + fmpz_set_mpz(y, x); + + fmpz_poly_scalar_mul_fmpz(rop->num, op->num, y); + fmpz_poly_set(rop->den, op->den); + fmpz_poly_q_canonicalise(rop); + + fmpz_clear(y); +} diff --git a/external/flint-2.4.3/fmpz_poly_q/scalar_mul_si.c b/external/flint-2.4.3/fmpz_poly_q/scalar_mul_si.c new file mode 100644 index 0000000..bb62141 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/scalar_mul_si.c @@ -0,0 +1,76 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_poly_q.h" + +void fmpz_poly_q_scalar_mul_si(fmpz_poly_q_t rop, const fmpz_poly_q_t op, slong x) +{ + fmpz_t cont, fx, gcd; + + if (fmpz_poly_q_is_zero(op) || (x == 0)) + { + fmpz_poly_q_zero(rop); + return; + } + + if (x == 1) + { + fmpz_poly_q_set(rop, op); + return; + } + + fmpz_init(cont); + fmpz_poly_content(cont, op->den); + + if (fmpz_is_one(cont)) + { + fmpz_poly_scalar_mul_si(rop->num, op->num, x); + fmpz_poly_set(rop->den, op->den); + fmpz_clear(cont); + return; + } + + fmpz_init(fx); + fmpz_init(gcd); + + fmpz_set_si(fx, x); + fmpz_gcd(gcd, cont, fx); + + if (fmpz_is_one(gcd)) + { + fmpz_poly_scalar_mul_si(rop->num, op->num, x); + fmpz_poly_set(rop->den, op->den); + } + else + { + fmpz_divexact(fx, fx, gcd); + fmpz_poly_scalar_mul_fmpz(rop->num, op->num, fx); + fmpz_poly_scalar_divexact_fmpz(rop->den, op->den, gcd); + } + + fmpz_clear(cont); + fmpz_clear(fx); + fmpz_clear(gcd); +} diff --git a/external/flint-2.4.3/fmpz_poly_q/set.c b/external/flint-2.4.3/fmpz_poly_q/set.c new file mode 100644 index 0000000..17fb78a --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/set.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_poly_q.h" + +void fmpz_poly_q_set(fmpz_poly_q_t rop, const fmpz_poly_q_t op) +{ + if (rop != op) + { + fmpz_poly_set(rop->num, op->num); + fmpz_poly_set(rop->den, op->den); + } +} + diff --git a/external/flint-2.4.3/fmpz_poly_q/set_si.c b/external/flint-2.4.3/fmpz_poly_q/set_si.c new file mode 100644 index 0000000..a708524 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/set_si.c @@ -0,0 +1,33 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_poly_q.h" + +void fmpz_poly_q_set_si(fmpz_poly_q_t rop, slong op) +{ + fmpz_poly_set_si(rop->num, op); + fmpz_poly_set_si(rop->den, 1); +} + diff --git a/external/flint-2.4.3/fmpz_poly_q/set_str.c b/external/flint-2.4.3/fmpz_poly_q/set_str.c new file mode 100644 index 0000000..794459e --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/set_str.c @@ -0,0 +1,92 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include + +#include "fmpz_poly_q.h" + +/** + * \ingroup StringConversions + * + * Sets the rational function \c rop to the value specified by the + * null-terminated string \c s. + * + * This method has now already been somewhat improved and is not very tolerant + * in the handling of malformed input. It expects either legitimate input for + * an \c fmpz_poly_t element, or two such inputs separated by a / + * only, in which case it is also assumed that the second polynomial is + * non-zero. + * + * The rational function is brought into canonical form by calling + * #fmpz_poly_q_canonicalize() in this function. + * + * Returns \c 0 if the string represents a valid rational function and + * \c non-zero otherwise. + */ +int fmpz_poly_q_set_str(fmpz_poly_q_t rop, const char *s) +{ + int ans, i, m; + size_t len; + char * numstr; + + len = strlen(s); + + for (m = 0; m < len; m++) + { + if (s[m] == '/') + break; + } + + if (m == len) + { + ans = fmpz_poly_set_str(rop->num, s); + fmpz_poly_set_si(rop->den, 1); + return ans; + } + else + { + numstr = flint_malloc(m + 1); + if (!numstr) + { + flint_printf("Exception (fmpz_poly_q_set_str). Memory allocation failed.\n"); + abort(); + } + + for (i = 0; i < m; i++) + numstr[i] = s[i]; + numstr[i] = '\0'; + + ans = fmpz_poly_set_str(rop->num, numstr); + ans |= fmpz_poly_set_str(rop->den, s + (m + 1)); + if (ans == 0) + fmpz_poly_q_canonicalise(rop); + else + fmpz_poly_q_zero(rop); + flint_free(numstr); + return ans; + } +} diff --git a/external/flint-2.4.3/fmpz_poly_q/sub.c b/external/flint-2.4.3/fmpz_poly_q/sub.c new file mode 100644 index 0000000..bace074 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/sub.c @@ -0,0 +1,174 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpq_poly.h" + +#include "fmpz_poly_q.h" + +void fmpz_poly_q_sub_in_place(fmpz_poly_q_t rop, const fmpz_poly_q_t op) +{ + if (rop == op) + { + fmpz_poly_q_zero(rop); + return; + } + + fmpz_poly_q_neg(rop, rop); + fmpz_poly_q_add_in_place(rop, op); + fmpz_poly_q_neg(rop, rop); +} + +void +fmpz_poly_q_sub(fmpz_poly_q_t rop, + const fmpz_poly_q_t op1, const fmpz_poly_q_t op2) +{ + fmpz_poly_t d, r2, s2; + + if (fmpz_poly_is_zero(op1->num)) + { + fmpz_poly_q_neg(rop, op2); + return; + } + if (fmpz_poly_is_zero(op2->num)) + { + fmpz_poly_q_set(rop, op1); + return; + } + + if (op1 == op2) + { + fmpz_poly_q_zero(rop); + return; + } + if (rop == op1) + { + fmpz_poly_q_sub_in_place(rop, op2); + return; + } + if (rop == op2) + { + fmpz_poly_q_sub_in_place(rop, op1); + fmpz_poly_q_neg(rop, rop); + return; + } + + /* + From here on, we know that rop, op1 and op2 refer to distinct objects + in memory, although as rational functions they may still be equal + + XXX: Do not maintain the remaining part of the function separately!!! + Instead, note that this is very similar to the corresponding part + of the summation code. + */ + + /* Polynomials? */ + if (fmpz_poly_length(op1->den) == 1 && fmpz_poly_length(op2->den) == 1) + { + const slong len1 = fmpz_poly_length(op1->num); + const slong len2 = fmpz_poly_length(op2->num); + + fmpz_poly_fit_length(rop->num, FLINT_MAX(len1, len2)); + _fmpq_poly_sub(rop->num->coeffs, rop->den->coeffs, + op1->num->coeffs, op1->den->coeffs, len1, + op2->num->coeffs, op2->den->coeffs, len2); + _fmpz_poly_set_length(rop->num, FLINT_MAX(len1, len2)); + _fmpz_poly_set_length(rop->den, 1); + _fmpz_poly_normalise(rop->num); + return; + } + + /* Denominators equal to one? */ + if (fmpz_poly_is_one(op1->den)) + { + fmpz_poly_mul(rop->num, op1->num, op2->den); + fmpz_poly_sub(rop->num, rop->num, op2->num); + fmpz_poly_set(rop->den, op2->den); + return; + } + if (fmpz_poly_is_one(op2->den)) + { + fmpz_poly_mul(rop->num, op2->num, op1->den); + fmpz_poly_sub(rop->num, op1->num, rop->num); + fmpz_poly_set(rop->den, op1->den); + return; + } + + /* Henrici's algorithm for summation in quotient fields */ + + /* + We begin by using rop->num as a temporary variable for the gcd of the + two denominators' greatest common divisor + */ + fmpz_poly_gcd(rop->num, op1->den, op2->den); + + if (fmpz_poly_is_one(rop->num)) + { + fmpz_poly_mul(rop->num, op1->num, op2->den); + fmpz_poly_mul(rop->den, op1->den, op2->num); /* Using rop->den as temp */ + fmpz_poly_sub(rop->num, rop->num, rop->den); + fmpz_poly_mul(rop->den, op1->den, op2->den); + } + else + { + /* + We now copy rop->num into a new variable d, so we no longer need + rop->num as a temporary variable + */ + fmpz_poly_init(d); + fmpz_poly_swap(d, rop->num); + + fmpz_poly_init(r2); + fmpz_poly_init(s2); + + fmpz_poly_div(r2, op1->den, d); /* +ve leading coeff */ + fmpz_poly_div(s2, op2->den, d); /* +ve leading coeff */ + + fmpz_poly_mul(rop->num, op1->num, s2); + fmpz_poly_mul(rop->den, op2->num, r2); /* Using rop->den as temp */ + fmpz_poly_sub(rop->num, rop->num, rop->den); + + if (fmpz_poly_degree(rop->num) < 0) + { + fmpz_poly_zero(rop->den); + fmpz_poly_set_coeff_si(rop->den, 0, 1); + } + else + { + fmpz_poly_mul(rop->den, op1->den, s2); + + fmpz_poly_gcd(r2, rop->num, d); + + if (!fmpz_poly_is_one(r2)) + { + fmpz_poly_div(rop->num, rop->num, r2); + fmpz_poly_div(rop->den, rop->den, r2); + } + } + + fmpz_poly_clear(d); + fmpz_poly_clear(r2); + fmpz_poly_clear(s2); + } +} diff --git a/external/flint-2.4.3/fmpz_poly_q/submul.c b/external/flint-2.4.3/fmpz_poly_q/submul.c new file mode 100644 index 0000000..11bcc33 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/submul.c @@ -0,0 +1,37 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_poly_q.h" + +void fmpz_poly_q_submul(fmpz_poly_q_t rop, + const fmpz_poly_q_t op1, const fmpz_poly_q_t op2) +{ + fmpz_poly_q_t temp; + + fmpz_poly_q_init(temp); + fmpz_poly_q_mul(temp, op1, op2); + fmpz_poly_q_sub(rop, rop, temp); + fmpz_poly_q_clear(temp); +} diff --git a/external/flint-2.4.3/fmpz_poly_q/swap.c b/external/flint-2.4.3/fmpz_poly_q/swap.c new file mode 100644 index 0000000..75d278f --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/swap.c @@ -0,0 +1,42 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_poly_q.h" + +void fmpz_poly_q_swap(fmpz_poly_q_t op1, fmpz_poly_q_t op2) +{ + if (op1 != op2) + { + fmpz_poly_struct *t; + + t = op1->num; + op1->num = op2->num; + op2->num = t; + + t = op1->den; + op1->den = op2->den; + op2->den = t; + } +} diff --git a/external/flint-2.4.3/fmpz_poly_q/test/t-add.c b/external/flint-2.4.3/fmpz_poly_q/test/t-add.c new file mode 100644 index 0000000..934f6b0 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/test/t-add.c @@ -0,0 +1,114 @@ +#include +#include +#include + +#include "fmpz_poly_q.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("add... "); + fflush(stdout); + + + + /* Check aliasing of a and c */ + for (i = 0; i < 100; i++) + { + fmpz_poly_q_t a, b, c; + + fmpz_poly_q_init(a); + fmpz_poly_q_init(b); + fmpz_poly_q_init(c); + fmpz_poly_q_randtest(a, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + fmpz_poly_q_randtest(b, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + + fmpz_poly_q_add(c, a, b); + fmpz_poly_q_add(a, a, b); + + result = (fmpz_poly_q_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_q_print(a), flint_printf("\n\n"); + fmpz_poly_q_print(b), flint_printf("\n\n"); + fmpz_poly_q_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_q_clear(a); + fmpz_poly_q_clear(b); + fmpz_poly_q_clear(c); + } + + /* Check aliasing of b and c */ + for (i = 0; i < 100; i++) + { + fmpz_poly_q_t a, b, c; + + fmpz_poly_q_init(a); + fmpz_poly_q_init(b); + fmpz_poly_q_init(c); + fmpz_poly_q_randtest(a, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + fmpz_poly_q_randtest(b, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + + fmpz_poly_q_add(c, a, b); + fmpz_poly_q_add(b, a, b); + + result = fmpz_poly_q_equal(b, c); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_q_print(a), flint_printf("\n\n"); + fmpz_poly_q_print(b), flint_printf("\n\n"); + fmpz_poly_q_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_q_clear(a); + fmpz_poly_q_clear(b); + fmpz_poly_q_clear(c); + } + + /* Check commutativity */ + for (i = 0; i < 100; i++) + { + fmpz_poly_q_t a, b, c, d; + + fmpz_poly_q_init(a); + fmpz_poly_q_init(b); + fmpz_poly_q_init(c); + fmpz_poly_q_init(d); + fmpz_poly_q_randtest(a, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + fmpz_poly_q_randtest(b, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + + fmpz_poly_q_add(c, a, b); + fmpz_poly_q_add(d, b, a); + + result = fmpz_poly_q_equal(c, d) && fmpz_poly_q_is_canonical(c) + && fmpz_poly_q_is_canonical(d); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_q_print(a), flint_printf("\n\n"); + fmpz_poly_q_print(b), flint_printf("\n\n"); + fmpz_poly_q_print(c), flint_printf("\n\n"); + fmpz_poly_q_print(d), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_q_clear(a); + fmpz_poly_q_clear(b); + fmpz_poly_q_clear(c); + fmpz_poly_q_clear(d); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fmpz_poly_q/test/t-addmul.c b/external/flint-2.4.3/fmpz_poly_q/test/t-addmul.c new file mode 100644 index 0000000..c9c5e28 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/test/t-addmul.c @@ -0,0 +1,83 @@ +#include +#include +#include + +#include "fmpz_poly_q.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("addmul... "); + fflush(stdout); + + + + /* Check aliasing of a and c */ + for (i = 0; i < 100; i++) + { + fmpz_poly_q_t a, b, c; + + fmpz_poly_q_init(a); + fmpz_poly_q_init(b); + fmpz_poly_q_init(c); + fmpz_poly_q_randtest(a, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + fmpz_poly_q_randtest(b, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + fmpz_poly_q_set(c, a); + + fmpz_poly_q_addmul(c, a, b); + fmpz_poly_q_addmul(a, a, b); + + result = fmpz_poly_q_equal(a, c) && fmpz_poly_q_is_canonical(a); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_q_print(a), flint_printf("\n\n"); + fmpz_poly_q_print(b), flint_printf("\n\n"); + fmpz_poly_q_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_q_clear(a); + fmpz_poly_q_clear(b); + fmpz_poly_q_clear(c); + } + + /* Check aliasing of b and c */ + for (i = 0; i < 100; i++) + { + fmpz_poly_q_t a, b, c; + + fmpz_poly_q_init(a); + fmpz_poly_q_init(b); + fmpz_poly_q_init(c); + fmpz_poly_q_randtest(a, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + fmpz_poly_q_randtest(b, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + fmpz_poly_q_set(c, b); + + fmpz_poly_q_addmul(c, a, b); + fmpz_poly_q_addmul(b, a, b); + + result = fmpz_poly_q_equal(b, c); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_q_print(a), flint_printf("\n\n"); + fmpz_poly_q_print(b), flint_printf("\n\n"); + fmpz_poly_q_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_q_clear(a); + fmpz_poly_q_clear(b); + fmpz_poly_q_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fmpz_poly_q/test/t-all.c b/external/flint-2.4.3/fmpz_poly_q/test/t-all.c new file mode 100644 index 0000000..cb3a8da --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/test/t-all.c @@ -0,0 +1,1546 @@ +/****************************************************************************** + + Copyright (C) 2009, 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include + +#include "fmpz_poly_q.h" + +void test_set(char * in, char * out) +{ + int ans; + fmpz_poly_q_t rop, op; + char * res; + + fmpz_poly_q_init(op); + fmpz_poly_q_set_str(op, in); + + fmpz_poly_q_init(rop); + fmpz_poly_q_set(rop, op); + + res = fmpz_poly_q_get_str(rop); + ans = !strcmp(out, res); + + if (!ans) + { + flint_printf("test_set: failed\n"); + flint_printf(" Expected \"%s\", got \"%s\"\n", out, res); + abort(); + } + + fmpz_poly_q_clear(op); + fmpz_poly_q_clear(rop); + flint_free(res); +} + +void test_set_si(slong x, char * out) +{ + int ans; + fmpz_poly_q_t rop; + char * res; + + fmpz_poly_q_init(rop); + fmpz_poly_q_set_si(rop, x); + + res = fmpz_poly_q_get_str(rop); + ans = !strcmp(out, res); + + if (!ans) + { + flint_printf("test_set_si: failed\n"); + flint_printf(" Expected \"%s\", got \"%s\"\n", out, res); + abort(); + } + + fmpz_poly_q_clear(rop); + flint_free(res); +} + +void test_swap(char * in1, char * in2, char * out1, char * out2) +{ + int ans; + fmpz_poly_q_t op1, op2; + char * res1; + char * res2; + + fmpz_poly_q_init(op1); + fmpz_poly_q_set_str(op1, in1); + fmpz_poly_q_init(op2); + fmpz_poly_q_set_str(op2, in2); + + fmpz_poly_q_swap(op1, op2); + + res1 = fmpz_poly_q_get_str(op1); + res2 = fmpz_poly_q_get_str(op2); + + ans = !strcmp(out1, res1) && !strcmp(out2, res2); + + if (!ans) + { + flint_printf("test_swap: failed\n"); + flint_printf(" Expected \"%s\" \"%s\", got \"%s\" \"%s\"\n", out1, out2, res1, res2); + abort(); + } + + fmpz_poly_q_clear(op1); + fmpz_poly_q_clear(op2); + flint_free(res1); + flint_free(res2); +} + +void test_zero(char * in, char * out) +{ + int ans; + fmpz_poly_q_t op; + char * res; + + fmpz_poly_q_init(op); + fmpz_poly_q_set_str(op, in); + + fmpz_poly_q_zero(op); + + res = fmpz_poly_q_get_str(op); + ans = !strcmp(res, out); + + if (!ans) + { + flint_printf("test_zero: failed\n"); + flint_printf(" Expected \"%s\", got \"%s\"\n", out, res); + abort(); + } + + fmpz_poly_q_clear(op); + flint_free(res); +} + +void test_neg(char * in, char * out) +{ + int ans; + fmpz_poly_q_t rop, op; + char * res; + + fmpz_poly_q_init(op); + fmpz_poly_q_set_str(op, in); + + fmpz_poly_q_init(rop); + fmpz_poly_q_neg(rop, op); + + res = fmpz_poly_q_get_str(rop); + ans = !strcmp(res, out); + + if (!ans) + { + flint_printf("test_neg: failed\n"); + flint_printf(" Expected \"%s\", got \"%s\"\n", out, res); + abort(); + } + + fmpz_poly_q_clear(op); + fmpz_poly_q_clear(rop); + flint_free(res); +} + +void test_inv(char * in, char * out) +{ + int ans; + fmpz_poly_q_t rop, op; + char * res; + + fmpz_poly_q_init(op); + fmpz_poly_q_set_str(op, in); + fmpz_poly_q_init(rop); + fmpz_poly_q_inv(rop, op); + + res = fmpz_poly_q_get_str(rop); + ans = !strcmp(res, out); + + if (!ans) + { + flint_printf("test_inv: failed\n"); + flint_printf(" Expected \"%s\", got \"%s\"\n", out, res); + abort(); + } + + fmpz_poly_q_clear(op); + fmpz_poly_q_clear(rop); + flint_free(res); +} + +void test_inv_inplace(char * in, char * out) +{ + int ans; + fmpz_poly_q_t rop; + char * res; + + fmpz_poly_q_init(rop); + fmpz_poly_q_set_str(rop, in); + fmpz_poly_q_inv(rop, rop); + + res = fmpz_poly_q_get_str(rop); + ans = !strcmp(res, out); + + if (!ans) + { + flint_printf("test_inv_inplace: failed\n"); + flint_printf(" Expected \"%s\", got \"%s\"\n", out, res); + abort(); + } + + fmpz_poly_q_clear(rop); + flint_free(res); +} + +void test_is_zero(char * in, int out) +{ + int ans; + fmpz_poly_q_t op; + int res; + + fmpz_poly_q_init(op); + fmpz_poly_q_set_str(op, in); + + res = fmpz_poly_q_is_zero(op); + ans = (res == out); + + if (!ans) + { + flint_printf("test_equal: failed\n"); + flint_printf(" Expected \"%d\", got \"%d\"\n", out, res); + abort(); + } + + fmpz_poly_q_clear(op); +} + +void test_is_one(char * in, int out) +{ + int ans; + fmpz_poly_q_t op; + int res; + + fmpz_poly_q_init(op); + fmpz_poly_q_set_str(op, in); + + res = fmpz_poly_q_is_one(op); + ans = (res == out); + + if (!ans) + { + flint_printf("test_equal: failed\n"); + flint_printf(" Expected \"%d\", got \"%d\"\n", out, res); + abort(); + } + + fmpz_poly_q_clear(op); +} + +void test_equal(char * in1, char * in2, int out) +{ + int ans; + fmpz_poly_q_t op1, op2; + int res; + + fmpz_poly_q_init(op1); + fmpz_poly_q_set_str(op1, in1); + + fmpz_poly_q_init(op2); + fmpz_poly_q_set_str(op2, in2); + + res = fmpz_poly_q_equal(op1, op2); + ans = (res == out); + + if (!ans) + { + flint_printf("test_equal: failed\n"); + flint_printf(" Expected \"%d\", got \"%d\"\n", out, res); + abort(); + } + + fmpz_poly_q_clear(op1); + fmpz_poly_q_clear(op2); +} + +void test_add(char * in1, char * in2, char * out) +{ + int ans; + fmpz_poly_q_t rop, op1, op2; + char * res; + + fmpz_poly_q_init(op1); + fmpz_poly_q_set_str(op1, in1); + + fmpz_poly_q_init(op2); + fmpz_poly_q_set_str(op2, in2); + + fmpz_poly_q_init(rop); + fmpz_poly_q_add(rop, op1, op2); + + res = fmpz_poly_q_get_str(rop); + ans = !strcmp(out, res); + + if (!ans) + { + flint_printf("test_add: failed\n"); + flint_printf(" Expected \"%s\", got \"%s\"\n", out, res); + abort(); + } + + fmpz_poly_q_clear(op1); + fmpz_poly_q_clear(op2); + fmpz_poly_q_clear(rop); + flint_free(res); +} + +/* Runs in1 = in1 + in2 */ +void test_add_in_place1(char * in1, char * in2, char * out) +{ + int ans; + fmpz_poly_q_t op1, op2; + char * res; + + fmpz_poly_q_init(op1); + fmpz_poly_q_set_str(op1, in1); + + fmpz_poly_q_init(op2); + fmpz_poly_q_set_str(op2, in2); + + fmpz_poly_q_add(op1, op1, op2); + + res = fmpz_poly_q_get_str(op1); + ans = !strcmp(out, res); + + if (!ans) + { + flint_printf("test_add_in_place1: failed\n"); + flint_printf(" Expected \"%s\", got \"%s\"\n", out, res); + abort(); + } + + fmpz_poly_q_clear(op1); + fmpz_poly_q_clear(op2); + flint_free(res); +} + +/* Runs in2 = in1 + in2 */ +void test_add_in_place2(char * in1, char * in2, char * out) +{ + int ans; + fmpz_poly_q_t op1, op2; + char * res; + + fmpz_poly_q_init(op1); + fmpz_poly_q_set_str(op1, in1); + + fmpz_poly_q_init(op2); + fmpz_poly_q_set_str(op2, in2); + + fmpz_poly_q_add(op2, op1, op2); + + res = fmpz_poly_q_get_str(op2); + ans = !strcmp(out, res); + + if (!ans) + { + flint_printf("test_add_in_place2: failed\n"); + flint_printf(" Expected \"%s\", got \"%s\"\n", out, res); + abort(); + } + + fmpz_poly_q_clear(op1); + fmpz_poly_q_clear(op2); + flint_free(res); +} + +/* Runs out = in + in */ +void test_add_in_place3(char * in, char * out) +{ + int ans; + fmpz_poly_q_t rop, op; + char * res; + + fmpz_poly_q_init(op); + fmpz_poly_q_set_str(op, in); + + fmpz_poly_q_init(rop); + fmpz_poly_q_add(rop, op, op); + + res = fmpz_poly_q_get_str(rop); + ans = !strcmp(out, res); + + if (!ans) + { + flint_printf("test_add_in_place3: failed\n"); + flint_printf(" Expected \"%s\", got \"%s\"\n", out, res); + abort(); + } + + fmpz_poly_q_clear(rop); + fmpz_poly_q_clear(op); + flint_free(res); +} + +void test_sub(char * in1, char * in2, char * out) +{ + int ans; + fmpz_poly_q_t rop, op1, op2; + char * res; + + fmpz_poly_q_init(op1); + fmpz_poly_q_set_str(op1, in1); + + fmpz_poly_q_init(op2); + fmpz_poly_q_set_str(op2, in2); + + fmpz_poly_q_init(rop); + fmpz_poly_q_sub(rop, op1, op2); + + res = fmpz_poly_q_get_str(rop); + ans = !strcmp(out, res); + + if (!ans) + { + flint_printf("test_sub: failed\n"); + flint_printf(" Expected \"%s\", got \"%s\"\n", out, res); + abort(); + } + + fmpz_poly_q_clear(op1); + fmpz_poly_q_clear(op2); + fmpz_poly_q_clear(rop); + flint_free(res); +} + +/* in1 = in1 + in2 */ +void test_sub_in_place1(char * in1, char * in2, char * out) +{ + int ans; + fmpz_poly_q_t op1, op2; + char * res; + + fmpz_poly_q_init(op1); + fmpz_poly_q_set_str(op1, in1); + + fmpz_poly_q_init(op2); + fmpz_poly_q_set_str(op2, in2); + + fmpz_poly_q_sub(op1, op1, op2); + + res = fmpz_poly_q_get_str(op1); + ans = !strcmp(out, res); + + if (!ans) + { + flint_printf("test_sub_in_place1: failed\n"); + flint_printf(" Expected \"%s\", got \"%s\"\n", out, res); + abort(); + } + + fmpz_poly_q_clear(op1); + fmpz_poly_q_clear(op2); + flint_free(res); +} + +/* in2 = in1 + in2 */ +void test_sub_in_place2(char * in1, char * in2, char * out) +{ + int ans; + fmpz_poly_q_t op1, op2; + char * res; + + fmpz_poly_q_init(op1); + fmpz_poly_q_set_str(op1, in1); + + fmpz_poly_q_init(op2); + fmpz_poly_q_set_str(op2, in2); + + fmpz_poly_q_sub(op2, op1, op2); + + res = fmpz_poly_q_get_str(op2); + ans = !strcmp(out, res); + + if (!ans) + { + flint_printf("test_sub_in_place2: failed\n"); + flint_printf(" Expected \"%s\", got \"%s\"\n", out, res); + abort(); + } + + fmpz_poly_q_clear(op1); + fmpz_poly_q_clear(op2); + flint_free(res); +} + +/* Runs out = in - in */ +void test_sub_in_place3(char * in, char * out) +{ + int ans; + fmpz_poly_q_t rop, op; + char * res; + + fmpz_poly_q_init(op); + fmpz_poly_q_set_str(op, in); + + fmpz_poly_q_init(rop); + fmpz_poly_q_sub(rop, op, op); + + res = fmpz_poly_q_get_str(rop); + ans = !strcmp(out, res); + + if (!ans) + { + flint_printf("test_sub_in_place3: failed\n"); + flint_printf(" Expected \"%s\", got \"%s\"\n", out, res); + abort(); + } + + fmpz_poly_q_clear(rop); + fmpz_poly_q_clear(op); + flint_free(res); +} + +void test_scalar_mul_si(char * in, slong x, char * out) +{ + int ans; + fmpz_poly_q_t rop, op; + char * res; + + fmpz_poly_q_init(op); + fmpz_poly_q_set_str(op, in); + + fmpz_poly_q_init(rop); + fmpz_poly_q_scalar_mul_si(rop, op, x); + + res = fmpz_poly_q_get_str(rop); + ans = !strcmp(out, res); + + if (!ans) + { + flint_printf("test_scalar_mul_si: failed\n"); + flint_printf(" Expected \"%s\", got \"%s\"\n", out, res); + abort(); + } + + fmpz_poly_q_clear(op); + fmpz_poly_q_clear(rop); + flint_free(res); +} + +void test_scalar_mul_mpz(char * in, mpz_t x, char * out) +{ + int ans; + fmpz_poly_q_t rop, op; + char * res; + + fmpz_poly_q_init(op); + fmpz_poly_q_set_str(op, in); + + fmpz_poly_q_init(rop); + fmpz_poly_q_scalar_mul_mpz(rop, op, x); + + res = fmpz_poly_q_get_str(rop); + ans = !strcmp(out, res); + + if (!ans) + { + flint_printf("test_scalar_mul_mpz: failed\n"); + flint_printf(" Expected \"%s\", got \"%s\"\n", out, res); + abort(); + } + + fmpz_poly_q_clear(op); + fmpz_poly_q_clear(rop); + flint_free(res); +} + +void test_scalar_mul_mpq(char * in, mpq_t x, char * out) +{ + int ans; + fmpz_poly_q_t rop, op; + char * res; + + fmpz_poly_q_init(op); + fmpz_poly_q_set_str(op, in); + + fmpz_poly_q_init(rop); + fmpz_poly_q_scalar_mul_mpq(rop, op, x); + + res = fmpz_poly_q_get_str(rop); + ans = !strcmp(out, res); + + if (!ans) + { + flint_printf("test_scalar_mul_mpq: failed\n"); + flint_printf(" Expected \"%s\", got \"%s\"\n", out, res); + abort(); + } + + fmpz_poly_q_clear(op); + fmpz_poly_q_clear(rop); + flint_free(res); +} + +void test_scalar_div_si(char * in, slong x, char * out) +{ + int ans; + fmpz_poly_q_t rop, op; + char * res; + + fmpz_poly_q_init(op); + fmpz_poly_q_set_str(op, in); + + fmpz_poly_q_init(rop); + fmpz_poly_q_scalar_div_si(rop, op, x); + + res = fmpz_poly_q_get_str(rop); + ans = !strcmp(out, res); + + if (!ans) + { + flint_printf("test_scalar_div_si: failed\n"); + flint_printf(" Expected \"%s\", got \"%s\"\n", out, res); + abort(); + } + + fmpz_poly_q_clear(op); + fmpz_poly_q_clear(rop); + flint_free(res); +} + +void test_scalar_div_mpz(char * in, mpz_t x, char * out) +{ + int ans; + fmpz_poly_q_t rop, op; + char * res; + + fmpz_poly_q_init(op); + fmpz_poly_q_set_str(op, in); + + fmpz_poly_q_init(rop); + fmpz_poly_q_scalar_div_mpz(rop, op, x); + + res = fmpz_poly_q_get_str(rop); + ans = !strcmp(out, res); + + if (!ans) + { + flint_printf("test_scalar_div_mpz: failed\n"); + flint_printf(" Expected \"%s\", got \"%s\"\n", out, res); + abort(); + } + + fmpz_poly_q_clear(op); + fmpz_poly_q_clear(rop); + flint_free(res); +} + +void test_scalar_div_mpq(char * in, mpq_t x, char * out) +{ + int ans; + fmpz_poly_q_t rop, op; + char * res; + + fmpz_poly_q_init(op); + fmpz_poly_q_set_str(op, in); + + fmpz_poly_q_init(rop); + fmpz_poly_q_scalar_div_mpq(rop, op, x); + + res = fmpz_poly_q_get_str(rop); + ans = !strcmp(out, res); + + if (!ans) + { + flint_printf("test_scalar_div_mpq: failed\n"); + flint_printf(" Expected \"%s\", got \"%s\"\n", out, res); + abort(); + } + + fmpz_poly_q_clear(op); + fmpz_poly_q_clear(rop); + flint_free(res); +} + +void test_mul(char * in1, char * in2, char * out) +{ + int ans; + fmpz_poly_q_t rop, op1, op2; + char * res; + + fmpz_poly_q_init(op1); + fmpz_poly_q_set_str(op1, in1); + + fmpz_poly_q_init(op2); + fmpz_poly_q_set_str(op2, in2); + + fmpz_poly_q_init(rop); + fmpz_poly_q_mul(rop, op1, op2); + + res = fmpz_poly_q_get_str(rop); + ans = !strcmp(out, res); + + if (!ans) + { + flint_printf("test_mul: failed\n"); + flint_printf(" Expected \"%s\", got \"%s\"\n", out, res); + abort(); + } + + fmpz_poly_q_clear(op1); + fmpz_poly_q_clear(op2); + fmpz_poly_q_clear(rop); + flint_free(res); +} + +/* in1 = in1 * in2 */ +void test_mul_in_place1(char * in1, char * in2, char * out) +{ + int ans; + fmpz_poly_q_t op1, op2; + char * res; + + fmpz_poly_q_init(op1); + fmpz_poly_q_set_str(op1, in1); + + fmpz_poly_q_init(op2); + fmpz_poly_q_set_str(op2, in2); + + fmpz_poly_q_mul(op1, op1, op2); + + res = fmpz_poly_q_get_str(op1); + ans = !strcmp(out, res); + + if (!ans) + { + flint_printf("test_mul_in_place1: failed\n"); + flint_printf(" Expected \"%s\", got \"%s\"\n", out, res); + abort(); + } + + fmpz_poly_q_clear(op1); + fmpz_poly_q_clear(op2); + flint_free(res); +} + +/* in2 = in1 * in2 */ +void test_mul_in_place2(char * in1, char * in2, char * out) +{ + int ans; + fmpz_poly_q_t op1, op2; + char * res; + + fmpz_poly_q_init(op1); + fmpz_poly_q_set_str(op1, in1); + + fmpz_poly_q_init(op2); + fmpz_poly_q_set_str(op2, in2); + + fmpz_poly_q_mul(op2, op1, op2); + + res = fmpz_poly_q_get_str(op2); + ans = !strcmp(out, res); + + if (!ans) + { + flint_printf("test_mul_in_place2: failed\n"); + flint_printf(" Expected \"%s\", got \"%s\"\n", out, res); + abort(); + } + + fmpz_poly_q_clear(op1); + fmpz_poly_q_clear(op2); + flint_free(res); +} + +/* Runs out = in * in */ +void test_mul_in_place3(char * in, char * out) +{ + int ans; + fmpz_poly_q_t rop, op; + char * res; + + fmpz_poly_q_init(op); + fmpz_poly_q_set_str(op, in); + + fmpz_poly_q_init(rop); + fmpz_poly_q_mul(rop, op, op); + + res = fmpz_poly_q_get_str(rop); + ans = !strcmp(out, res); + + if (!ans) + { + flint_printf("test_mul_in_place3: failed\n"); + flint_printf(" Expected \"%s\", got \"%s\"\n", out, res); + abort(); + } + + fmpz_poly_q_clear(rop); + fmpz_poly_q_clear(op); + flint_free(res); +} + +void test_div(char * in1, char * in2, char * out) +{ + int ans; + fmpz_poly_q_t rop, op1, op2; + char * res; + + fmpz_poly_q_init(op1); + fmpz_poly_q_set_str(op1, in1); + + fmpz_poly_q_init(op2); + fmpz_poly_q_set_str(op2, in2); + + fmpz_poly_q_init(rop); + fmpz_poly_q_div(rop, op1, op2); + + res = fmpz_poly_q_get_str(rop); + ans = !strcmp(out, res); + + if (!ans) + { + flint_printf("test_div: failed\n"); + flint_printf(" Expected \"%s\", got \"%s\"\n", out, res); + abort(); + } + + fmpz_poly_q_clear(op1); + fmpz_poly_q_clear(op2); + fmpz_poly_q_clear(rop); + flint_free(res); +} + +/* in1 = in1 / in2 */ +void test_div_in_place1(char * in1, char * in2, char * out) +{ + int ans; + fmpz_poly_q_t op1, op2; + char * res; + + fmpz_poly_q_init(op1); + fmpz_poly_q_set_str(op1, in1); + + fmpz_poly_q_init(op2); + fmpz_poly_q_set_str(op2, in2); + + fmpz_poly_q_div(op1, op1, op2); + + res = fmpz_poly_q_get_str(op1); + ans = !strcmp(out, res); + + if (!ans) + { + flint_printf("test_div_in_place1: failed\n"); + flint_printf(" Expected \"%s\", got \"%s\"\n", out, res); + abort(); + } + + fmpz_poly_q_clear(op1); + fmpz_poly_q_clear(op2); + flint_free(res); +} + +/* in2 = in1 / in2 */ +void test_div_in_place2(char * in1, char * in2, char * out) +{ + int ans; + fmpz_poly_q_t op1, op2; + char * res; + + fmpz_poly_q_init(op1); + fmpz_poly_q_set_str(op1, in1); + + fmpz_poly_q_init(op2); + fmpz_poly_q_set_str(op2, in2); + + fmpz_poly_q_div(op2, op1, op2); + + res = fmpz_poly_q_get_str(op2); + ans = !strcmp(out, res); + + if (!ans) + { + flint_printf("test_div_in_place2: failed\n"); + flint_printf(" Expected \"%s\", got \"%s\"\n", out, res); + abort(); + } + + fmpz_poly_q_clear(op1); + fmpz_poly_q_clear(op2); + flint_free(res); +} + +/* Runs out = in / in */ +void test_div_in_place3(char * in, char * out) +{ + int ans; + fmpz_poly_q_t rop, op; + char * res; + + fmpz_poly_q_init(op); + fmpz_poly_q_set_str(op, in); + + fmpz_poly_q_init(rop); + fmpz_poly_q_div(rop, op, op); + + res = fmpz_poly_q_get_str(rop); + ans = !strcmp(out, res); + + if (!ans) + { + flint_printf("test_div_in_place3: failed\n"); + flint_printf(" Expected \"%s\", got \"%s\"\n", out, res); + abort(); + } + + fmpz_poly_q_clear(rop); + fmpz_poly_q_clear(op); + flint_free(res); +} + +void test_pow(char * in, ulong x, char * out) +{ + int ans; + fmpz_poly_q_t rop, op; + char * res; + + fmpz_poly_q_init(op); + fmpz_poly_q_set_str(op, in); + + fmpz_poly_q_init(rop); + fmpz_poly_q_pow(rop, op, x); + + res = fmpz_poly_q_get_str(rop); + ans = !strcmp(out, res); + + if (!ans) + { + flint_printf("test_pow: failed\n"); + flint_printf(" Expected \"%s\", got \"%s\"\n", out, res); + abort(); + } + + fmpz_poly_q_clear(op); + fmpz_poly_q_clear(rop); + flint_free(res); +} + +void test_derivative(char * in, char * out) +{ + int ans; + fmpz_poly_q_t rop, op; + char * res; + + fmpz_poly_q_init(op); + fmpz_poly_q_set_str(op, in); + + fmpz_poly_q_init(rop); + fmpz_poly_q_derivative(rop, op); + + res = fmpz_poly_q_get_str(rop); + ans = !strcmp(out, res); + + if (!ans) + { + flint_printf("test_derivative: failed\n"); + flint_printf(" Expected \"%s\", got \"%s\"\n", out, res); + abort(); + } + + fmpz_poly_q_clear(op); + fmpz_poly_q_clear(rop); + flint_free(res); +} + +void test_evaluate(char * in, int numa, int numb, char * out) +{ + int ans, pole; + fmpz_poly_q_t op; + mpq_t rop, a; + char *res = NULL; + + fmpz_poly_q_init(op); + fmpz_poly_q_set_str(op, in); + + mpq_init(a); + flint_mpq_set_si(a, numa, numb); + mpq_init(rop); + pole = fmpz_poly_q_evaluate(rop, op, a); + + if (pole && strcmp(out, "P")) + { + flint_printf("test_evaluate: failed\n"); + flint_printf(" Expected \"%s\", got a pole\n", out); + abort(); + } + if (!pole && !strcmp(out, "P")) + { + res = mpq_get_str(NULL, 10, rop); + flint_printf("test_evaluate: failed\n"); + flint_printf(" Expected a pole, got \"%s\"\n", res); + abort(); + } + if (!pole) + { + res = mpq_get_str(NULL, 10, rop); + ans = (strcmp(out, res) == 0); + + if (!ans) + { + flint_printf("test_evaluate: failed\n"); + flint_printf(" Expected \"%s\", got \"%s\"\n", out, res); + abort(); + } + } + + fmpz_poly_q_clear(op); + mpq_clear(rop); + mpq_clear(a); + flint_free(res); +} + +void test_get_str_pretty(char * in, char * out) +{ + int ans; + fmpz_poly_q_t rop; + char * res; + + fmpz_poly_q_init(rop); + fmpz_poly_q_set_str(rop, in); + res = fmpz_poly_q_get_str_pretty(rop, "t"); + ans = !strcmp(out, res); + + if (!ans) + { + flint_printf("test_get_str_pretty: failed\n"); + flint_printf(" Expected \"%s\", got \"%s\"\n", out, res); + abort(); + } + + fmpz_poly_q_clear(rop); + flint_free(res); +} + +void test_addmul(char * in1, char * in2, char * in3, char * out) +{ + int ans; + fmpz_poly_q_t rop, op1, op2; + char * res; + + fmpz_poly_q_init(rop); + fmpz_poly_q_set_str(rop, in1); + fmpz_poly_q_init(op1); + fmpz_poly_q_set_str(op1, in2); + fmpz_poly_q_init(op2); + fmpz_poly_q_set_str(op2, in3); + + fmpz_poly_q_addmul(rop, op1, op2); + + res = fmpz_poly_q_get_str(rop); + ans = !strcmp(out, res); + + if (!ans) + { + flint_printf("test_addmul: failed\n"); + flint_printf(" Expected \"%s\", got \"%s\"\n", out, res); + abort(); + } + + fmpz_poly_q_clear(rop); + fmpz_poly_q_clear(op1); + fmpz_poly_q_clear(op2); + flint_free(res); +} + +void test_submul(char * in1, char * in2, char * in3, char * out) +{ + int ans; + fmpz_poly_q_t rop, op1, op2; + char * res; + + fmpz_poly_q_init(rop); + fmpz_poly_q_set_str(rop, in1); + fmpz_poly_q_init(op1); + fmpz_poly_q_set_str(op1, in2); + fmpz_poly_q_init(op2); + fmpz_poly_q_set_str(op2, in3); + + fmpz_poly_q_submul(rop, op1, op2); + + res = fmpz_poly_q_get_str(rop); + ans = !strcmp(out, res); + + if (!ans) + { + flint_printf("test_submul: failed\n"); + flint_printf(" Expected \"%s\", got \"%s\"\n", out, res); + abort(); + } + + fmpz_poly_q_clear(rop); + fmpz_poly_q_clear(op1); + fmpz_poly_q_clear(op2); + flint_free(res); +} + +int main(int argc, char *argv[]) +{ + int ans; + char *str, *strout; + + fmpz_poly_t zpoly; + fmpz_poly_q_t qpoly1; + + mpz_t mpzzero, mpzone, mpztwo; + mpq_t mpqzero, mpqone, mpqtwo, mpqtwoinv; + + FLINT_TEST_INIT(state); + + flint_printf("all... "); + fflush(stdout); + + /* Accessing numerator and denominator ***********************************/ + + fmpz_poly_q_init(qpoly1); + fmpz_poly_q_set_str(qpoly1, "2 -1 1/2 0 1"); + str = "2 -1 1"; + strout = fmpz_poly_get_str(fmpz_poly_q_numref(qpoly1)); + ans = !strcmp(str, strout); + if (!ans) + { + flint_printf("test_numref: failed\n"); + flint_printf(" Expected \"%s\", got \"%s\"\n", str, strout); + flint_printf(" qpoly1 = \""), fmpz_poly_q_print(qpoly1), flint_printf("\"\n"); + abort(); + } + fmpz_poly_q_clear(qpoly1); + flint_free(strout); + + fmpz_poly_q_init(qpoly1); + fmpz_poly_q_set_str(qpoly1, "2 -1 1/2 0 1"); + str = "2 0 1"; + strout = fmpz_poly_get_str(fmpz_poly_q_denref(qpoly1)); + ans = !strcmp(str, strout); + if (!ans) + { + flint_printf("test_denref: failed\n"); + flint_printf(" Expected \"%s\", got \"%s\"\n", str, strout); + abort(); + } + fmpz_poly_q_clear(qpoly1); + flint_free(strout); + + fmpz_poly_q_init(qpoly1); + fmpz_poly_init(zpoly); + fmpz_poly_q_set_str(qpoly1, "2 -1 1/2 0 1"); + fmpz_poly_set(zpoly, fmpz_poly_q_numref(qpoly1)); + str = "2 -1 1"; + strout = fmpz_poly_get_str(zpoly); + ans = !strcmp(str, strout); + if (!ans) + { + flint_printf("test_get_num: failed\n"); + flint_printf(" Expected \"%s\", got \"%s\"\n", str, strout); + abort(); + } + fmpz_poly_q_clear(qpoly1); + fmpz_poly_clear(zpoly); + flint_free(strout); + + fmpz_poly_q_init(qpoly1); + fmpz_poly_init(zpoly); + fmpz_poly_q_set_str(qpoly1, "2 -1 1/2 0 1"); + fmpz_poly_set(zpoly, fmpz_poly_q_denref(qpoly1)); + + str = "2 0 1"; + strout = fmpz_poly_get_str(zpoly); + ans = !strcmp(str, strout); + if (!ans) + { + flint_printf("test_get_den: failed\n"); + flint_printf(" Expected \"%s\", got \"%s\"\n", str, strout); + abort(); + } + fmpz_poly_q_clear(qpoly1); + fmpz_poly_clear(zpoly); + flint_free(strout); + + fmpz_poly_q_init(qpoly1); + fmpz_poly_init(zpoly); + fmpz_poly_q_set_str(qpoly1, "1 1/1 1"); + fmpz_poly_set_str(zpoly, "2 0 1"); + fmpz_poly_set(fmpz_poly_q_numref(qpoly1), zpoly); + str = "2 0 1"; + strout = fmpz_poly_get_str(fmpz_poly_q_numref(qpoly1)); + ans = !strcmp(str, strout); + if (!ans) + { + flint_printf("test_set_num: failed\n"); + flint_printf(" Expected \"%s\", got \"%s\"\n", str, strout); + abort(); + } + fmpz_poly_q_clear(qpoly1); + fmpz_poly_clear(zpoly); + flint_free(strout); + + fmpz_poly_q_init(qpoly1); + fmpz_poly_init(zpoly); + fmpz_poly_q_set_str(qpoly1, "1 1/1 1"); + fmpz_poly_set_str(zpoly, "2 0 1"); + fmpz_poly_set(fmpz_poly_q_denref(qpoly1), zpoly); + str = "2 0 1"; + strout = fmpz_poly_get_str(fmpz_poly_q_denref(qpoly1)); + ans = !strcmp(str, strout); + if (!ans) + { + flint_printf("test_set_den: failed\n"); + flint_printf(" Expected \"%s\", got \"%s\"\n", str, strout); + abort(); + } + fmpz_poly_q_clear(qpoly1); + fmpz_poly_clear(zpoly); + flint_free(strout); + + /* Canonicalise **********************************************************/ + + fmpz_poly_q_init(qpoly1); + str = "2 -1 1/2 0 1"; + fmpz_poly_q_set_str(qpoly1, str); + strout = fmpz_poly_q_get_str(qpoly1); + ans = !strcmp(str, strout); + if (!ans) + { + flint_printf("test_canonicalize: failed\n"); + flint_printf(" Expected \"%s\", got \"%s\"\n", str, strout); + abort(); + } + fmpz_poly_q_clear(qpoly1); + flint_free(strout); + + fmpz_poly_q_init(qpoly1); + str = "2 -1 -1/2 0 1"; + fmpz_poly_q_set_str(qpoly1, "2 1 1/2 0 -1"); + strout = fmpz_poly_q_get_str(qpoly1); + ans = !strcmp("2 -1 -1/2 0 1", strout); + if (!ans) + { + flint_printf("test_canonicalize: failed\n"); + flint_printf(" Expected \"%s\", got \"%s\"\n", str, strout); + abort(); + } + flint_free(strout); + fmpz_poly_q_clear(qpoly1); + + /* Initialization, memory management and basic operations ****************/ + + test_set("0", "0"); + test_set("0/1 1", "0"); + test_set("3 -1 0 1/2 0 1", "3 -1 0 1/2 0 1"); + test_set("3 -1 0 1/2 1 1", "2 -1 1"); + + test_set_si(-1, "1 -1"); + test_set_si(13, "1 13"); + test_set_si(0, "0"); + + test_swap("3 -1 0 1/2 0 1", "1 2/1 3", "1 2/1 3", "3 -1 0 1/2 0 1"); + + test_zero("0", "0"); + test_zero("0/1 1", "0"); + test_zero("3 -1 0 1/2 0 1", "0"); + + test_neg("0", "0"); + test_neg("1 1/1 2", "1 -1/1 2"); + test_neg("3 -1 0 1/2 0 1", "3 1 0 -1/2 0 1"); + + test_inv("1 1/1 2", "1 2"); + test_inv("3 -1 0 1/2 0 1", "2 0 1/3 -1 0 1"); + test_inv("3 -1 0 -1/2 0 1", "2 0 -1/3 1 0 1"); + + test_inv_inplace("1 1/1 2", "1 2"); + test_inv_inplace("3 -1 0 1/2 0 1", "2 0 1/3 -1 0 1"); + test_inv_inplace("3 -1 0 -1/2 0 1", "2 0 -1/3 1 0 1"); + + test_is_zero("0", 1); + test_is_zero("0/1 1", 1); + test_is_zero("3 -1 0 1/2 0 1", 0); + test_is_zero("3 -1 0 1/2 1 1", 0); + + test_is_one("0", 0); + test_is_one("0/1 1", 0); + test_is_one("1 1/1 1", 1); + test_is_one("2 1 1/2 1 1", 1); + test_is_one("3 -1 0 1/2 0 1", 0); + + test_equal("1 1/1 2", "1 1/1 2", 1); + test_equal("1 1/1 2", "1 1/1 2", 1); + test_equal("3 -1 0 1/2 1 1", "2 -1 1", 1); + test_equal("3 -1 0 1/2 -1 1", "2 -1 1", 0); + + /* Addition and subtraction **********************************************/ + + test_add("3 1 0 1/2 0 1", "2 0 -1/3 1 0 1", "5 1 0 1 0 1/4 0 1 0 1"); + test_add("3 -1 0 1/2 1 1", "1 2/2 -1 1", "3 3 -2 1/2 -1 1"); + test_add("0/2 1 1", "1 2/1 1", "1 2"); + test_add("1 -3/1 4", "0/3 1 0 1", "1 -3/1 4"); + test_add("2 1 1/1 1", "2 -1 1/1 1", "2 0 2"); + test_add("2 1 1/2 0 1", "2 2 1/2 -1 1", "3 -1 2 2/3 0 -1 1"); + test_add("2 -1 1/2 2 1", "3 4 4 1/2 1 1", "4 7 12 7 1/3 2 3 1"); + test_add("2 1 1/2 -1 1", "2 1 1", "3 0 1 1/2 -1 1"); + test_add("1 1/2 1 1", "2 0 1/2 1 1", "1 1"); + test_add("2 1 1/3 4 -4 1", "1 1/2 -2 1", "2 -1 2/3 4 -4 1"); + test_add("3 0 1 1/3 1 2 1", "2 0 -1/2 1 1", "0"); + test_add("2 1 1/2 0 1", "2 -1 1/2 0 1", "1 2"); + test_add("1 1/3 3 5 2", "1 1/3 6 7 2", "1 1/3 2 3 1"); + + test_add_in_place1("3 1 0 1/2 0 1", "2 0 -1/3 1 0 1", "5 1 0 1 0 1/4 0 1 0 1"); + test_add_in_place1("3 -1 0 1/2 1 1", "1 2/2 -1 1", "3 3 -2 1/2 -1 1"); + test_add_in_place1("0/2 1 1", "1 2/1 1", "1 2"); + test_add_in_place1("1 -3/1 4", "0/3 1 0 1", "1 -3/1 4"); + test_add_in_place1("2 1 1/1 1", "2 -1 1/1 1", "2 0 2"); + test_add_in_place1("2 1 1/2 0 1", "2 2 1/2 -1 1", "3 -1 2 2/3 0 -1 1"); + test_add_in_place1("2 -1 1/2 2 1", "3 4 4 1/2 1 1", "4 7 12 7 1/3 2 3 1"); + test_add_in_place1("2 1 1/2 -1 1", "2 1 1", "3 0 1 1/2 -1 1"); + test_add_in_place1("1 1/2 1 1", "2 0 1/2 1 1", "1 1"); + test_add_in_place1("2 1 1/3 4 -4 1", "1 1/2 -2 1", "2 -1 2/3 4 -4 1"); + test_add_in_place1("3 0 1 1/3 1 2 1", "2 0 -1/2 1 1", "0"); + test_add_in_place1("2 1 1/2 0 1", "2 -1 1/2 0 1", "1 2"); + + test_add_in_place2("3 1 0 1/2 0 1", "2 0 -1/3 1 0 1", "5 1 0 1 0 1/4 0 1 0 1"); + test_add_in_place2("3 -1 0 1/2 1 1", "1 2/2 -1 1", "3 3 -2 1/2 -1 1"); + test_add_in_place2("0/2 1 1", "1 2/1 1", "1 2"); + test_add_in_place2("1 -3/1 4", "0/3 1 0 1", "1 -3/1 4"); + test_add_in_place2("2 1 1/1 1", "2 -1 1/1 1", "2 0 2"); + test_add_in_place2("2 1 1/2 0 1", "2 2 1/2 -1 1", "3 -1 2 2/3 0 -1 1"); + test_add_in_place2("2 -1 1/2 2 1", "3 4 4 1/2 1 1", "4 7 12 7 1/3 2 3 1"); + test_add_in_place2("2 1 1/2 -1 1", "2 1 1", "3 0 1 1/2 -1 1"); + test_add_in_place2("1 1/2 1 1", "2 0 1/2 1 1", "1 1"); + test_add_in_place2("2 1 1/3 4 -4 1", "1 1/2 -2 1", "2 -1 2/3 4 -4 1"); + test_add_in_place2("3 0 1 1/3 1 2 1", "2 0 -1/2 1 1", "0"); + test_add_in_place2("2 1 1/2 0 1", "2 -1 1/2 0 1", "1 2"); + + test_add_in_place3("2 1 1", "2 2 2"); + test_add_in_place3("2 1 1/1 2", "2 1 1"); + + test_sub("3 1 0 1/2 0 1", "2 0 -1/3 1 0 1", "5 1 0 3 0 1/4 0 1 0 1"); + test_sub("3 -1 0 1/2 1 1", "1 2/2 -1 1", "3 -1 -2 1/2 -1 1"); + test_sub("0/2 1 1", "1 2/1 1", "1 -2"); + test_sub("1 -3/1 4", "0/3 1 0 1", "1 -3/1 4"); + test_sub("2 1 1/1 1", "2 -1 1/1 1", "1 2"); + test_sub("2 1 1/2 0 1", "2 2 1/2 -1 1", "2 -1 -2/3 0 -1 1"); + test_sub("2 -1 1/2 2 1", "3 4 4 1/2 1 1", "4 -9 -12 -5 -1/3 2 3 1"); + test_sub("2 -1 1/2 0 1", "1 1", "1 -1/2 0 1"); + test_sub("3 1 0 1/2 0 1", "2 0 -1/3 1 0 1", "5 1 0 3 0 1/4 0 1 0 1"); + test_sub("3 -1 0 1/2 1 1", "1 2/2 -1 1", "3 -1 -2 1/2 -1 1"); + test_sub("0/2 1 1", "1 2/1 1", "1 -2"); + test_sub("1 -3/1 4", "0/3 1 0 1", "1 -3/1 4"); + test_sub("2 1 1/1 1", "2 -1 1/1 1", "1 2"); + test_sub("2 1 1/2 0 1", "2 2 1/2 -1 1", "2 -1 -2/3 0 -1 1"); + test_sub("2 -1 1/2 2 1", "3 4 4 1/2 1 1", "4 -9 -12 -5 -1/3 2 3 1"); + test_sub("2 1 1/2 -1 1", "2 1 1", "3 2 1 -1/2 -1 1"); + test_sub("1 1/2 1 1", "2 0 1/2 1 1", "2 1 -1/2 1 1"); + test_sub("2 1 1/3 4 -4 1", "1 1/2 -2 1", "1 3/3 4 -4 1"); + test_sub("3 0 1 1/3 1 2 1", "2 0 -1/2 1 1", "2 0 2/2 1 1"); + test_sub("2 1 1/2 0 1", "2 -1 1/2 0 1", "1 2/2 0 1"); + test_sub("1 1/3 3 5 2", "1 1/3 6 7 2", "1 1/4 6 13 9 2"); + test_sub("2 1 1/2 0 2", "2 1 1/2 0 2", "0"); + test_sub("2 -1 2/2 0 1", "2 -1 1/2 0 1", "1 1"); + + test_sub_in_place1("3 1 0 1/2 0 1", "2 0 -1/3 1 0 1", "5 1 0 3 0 1/4 0 1 0 1"); + test_sub_in_place1("3 -1 0 1/2 1 1", "1 2/2 -1 1", "3 -1 -2 1/2 -1 1"); + test_sub_in_place1("0/2 1 1", "1 2/1 1", "1 -2"); + test_sub_in_place1("1 -3/1 4", "0/3 1 0 1", "1 -3/1 4"); + test_sub_in_place1("2 1 1/1 1", "2 -1 1/1 1", "1 2"); + test_sub_in_place1("2 1 1/2 0 1", "2 2 1/2 -1 1", "2 -1 -2/3 0 -1 1"); + test_sub_in_place1("2 -1 1/2 2 1", "3 4 4 1/2 1 1", "4 -9 -12 -5 -1/3 2 3 1"); + + test_sub_in_place2("3 1 0 1/2 0 1", "2 0 -1/3 1 0 1", "5 1 0 3 0 1/4 0 1 0 1"); + test_sub_in_place2("3 -1 0 1/2 1 1", "1 2/2 -1 1", "3 -1 -2 1/2 -1 1"); + test_sub_in_place2("0/2 1 1", "1 2/1 1", "1 -2"); + test_sub_in_place2("1 -3/1 4", "0/3 1 0 1", "1 -3/1 4"); + test_sub_in_place2("2 1 1/1 1", "2 -1 1/1 1", "1 2"); + test_sub_in_place2("2 1 1/2 0 1", "2 2 1/2 -1 1", "2 -1 -2/3 0 -1 1"); + test_sub_in_place2("2 -1 1/2 2 1", "3 4 4 1/2 1 1", "4 -9 -12 -5 -1/3 2 3 1"); + + test_sub_in_place3("2 -1 1/2 2 1", "0"); + + test_addmul("1 1/2 0 2", "2 3 1/1 4", "3 1 0 1/4 -2 0 0 1", "5 -4 3 1 5 1/5 0 -8 0 0 4"); + + test_submul("1 1/2 0 2", "2 3 1/1 4", "3 1 0 1/4 -2 0 0 1", "5 -4 -3 -1 -1 -1/5 0 -8 0 0 4"); + + /* Scalar multiplication and devision ************************************/ + + flint_mpz_init_set_si(mpzzero, 0); + flint_mpz_init_set_si(mpzone, 1); + flint_mpz_init_set_si(mpztwo, 2); + + mpq_init(mpqzero); flint_mpq_set_si(mpqzero, 0, 1); + mpq_init(mpqone); flint_mpq_set_si(mpqone, 1, 1); + mpq_init(mpqtwo); flint_mpq_set_si(mpqtwo, 2, 1); + mpq_init(mpqtwoinv); flint_mpq_set_si(mpqtwoinv, 1, 2); + + test_scalar_mul_si("0", 1, "0"); + test_scalar_mul_si("0", 0, "0"); + test_scalar_mul_si("1 2", 0, "0"); + test_scalar_mul_si("1 1/1 2", -2, "1 -1"); + test_scalar_mul_si("2 1 1/2 -2 3", 5, "2 5 5/2 -2 3"); + test_scalar_mul_si("2 1 1/2 -2 2", 3, "2 3 3/2 -2 2"); + + test_scalar_mul_mpz("0", mpzone, "0"); + test_scalar_mul_mpz("0", mpzzero, "0"); + test_scalar_mul_mpz("1 2", mpzzero, "0"); + test_scalar_mul_mpz("1 1/1 2", mpztwo, "1 1"); + + test_scalar_mul_mpq("0", mpqone, "0"); + test_scalar_mul_mpq("0", mpqzero, "0"); + test_scalar_mul_mpq("1 2", mpqzero, "0"); + test_scalar_mul_mpq("1 1/1 2", mpqtwo, "1 1"); + test_scalar_mul_mpq("1 -2/1 1", mpqtwoinv, "1 -1"); + + test_scalar_div_si("0", 1, "0"); + test_scalar_div_si("1 2", 2, "1 1"); + test_scalar_div_si("1 1/1 2", -2, "1 -1/1 4"); + test_scalar_div_si("3 -5 0 3/2 1 1", 2, "3 -5 0 3/2 2 2"); + test_scalar_div_si("3 2 8 4/2 0 1", 3, "3 2 8 4/2 0 3"); + test_scalar_div_si("3 2 8 4/2 0 1", -3, "3 -2 -8 -4/2 0 3"); + test_scalar_div_si("3 -27 0 9/2 0 1", -3, "3 9 0 -3/2 0 1"); + + test_scalar_div_mpz("0", mpzone, "0"); + test_scalar_div_mpz("1 2", mpztwo, "1 1"); + test_scalar_div_mpz("1 1/1 2", mpztwo, "1 1/1 4"); + + test_scalar_div_mpq("0", mpqone, "0"); + test_scalar_div_mpq("1 2", mpqone, "1 2"); + test_scalar_div_mpq("1 1/1 2", mpqtwo, "1 1/1 4"); + test_scalar_div_mpq("1 -2/1 1", mpqtwoinv, "1 -4"); + + mpz_clear(mpzzero); + mpz_clear(mpzone); + mpz_clear(mpztwo); + mpq_clear(mpqzero); + mpq_clear(mpqone); + mpq_clear(mpqtwo); + mpq_clear(mpqtwoinv); + + /* Multiplication, division and powing *********************************/ + + test_mul("3 1 0 1/2 0 1", "2 0 -1/3 1 0 1", "1 -1"); + test_mul("3 -1 0 1/2 1 1", "1 2/2 -1 1", "1 2"); + test_mul("0/2 1 1", "1 2/1 1", "0"); + test_mul("1 -3/1 4", "0/3 1 0 1", "0"); + test_mul("2 1 1/1 1", "2 -1 1/1 1", "3 -1 0 1"); + test_mul("2 1 1/2 0 1", "2 2 1/2 -1 1", "3 2 3 1/3 0 -1 1"); + test_mul("2 -1 1/2 2 1", "3 4 4 1/2 1 1", "3 -2 1 1/2 1 1"); + + test_mul_in_place1("3 1 0 1/2 0 1", "2 0 -1/3 1 0 1", "1 -1"); + test_mul_in_place1("3 -1 0 1/2 1 1", "1 2/2 -1 1", "1 2"); + test_mul_in_place1("0/2 1 1", "1 2/1 1", "0"); + test_mul_in_place1("1 -3/1 4", "0/3 1 0 1", "0"); + test_mul_in_place1("2 1 1/1 1", "2 -1 1/1 1", "3 -1 0 1"); + test_mul_in_place1("2 1 1/2 0 1", "2 2 1/2 -1 1", "3 2 3 1/3 0 -1 1"); + test_mul_in_place1("2 -1 1/2 2 1", "3 4 4 1/2 1 1", "3 -2 1 1/2 1 1"); + + test_mul_in_place2("3 1 0 1/2 0 1", "2 0 -1/3 1 0 1", "1 -1"); + test_mul_in_place2("3 -1 0 1/2 1 1", "1 2/2 -1 1", "1 2"); + test_mul_in_place2("0/2 1 1", "1 2/1 1", "0"); + test_mul_in_place2("1 -3/1 4", "0/3 1 0 1", "0"); + test_mul_in_place2("2 1 1/1 1", "2 -1 1/1 1", "3 -1 0 1"); + test_mul_in_place2("2 1 1/2 0 1", "2 2 1/2 -1 1", "3 2 3 1/3 0 -1 1"); + test_mul_in_place2("2 -1 1/2 2 1", "3 4 4 1/2 1 1", "3 -2 1 1/2 1 1"); + + test_mul_in_place3("2 0 1/2 1 1", "3 0 0 1/3 1 2 1"); + + test_div("3 -1 0 1/1 2", "2 1 1/1 1", "2 -1 1/1 2"); + test_div("0/2 1 1", "2 1 1/1 1", "0"); + test_div("3 -1 0 1/1 4", "2 -1 -1/1 2", "2 1 -1/1 2"); + test_div("2 1 1", "2 1 -1/2 1 -1", "2 1 1"); + test_div("2 1 1/3 4 4 1", "2 -1 1/3 6 5 1", "3 3 4 1/3 -2 1 1"); + + test_div_in_place1("3 -1 0 1/1 2", "2 1 1/1 1", "2 -1 1/1 2"); + test_div_in_place1("0/2 1 1", "2 1 1/1 1", "0"); + test_div_in_place1("3 -1 0 1/1 4", "2 -1 -1/1 2", "2 1 -1/1 2"); + test_div_in_place1("2 1 1", "2 1 -1/2 1 -1", "2 1 1"); + test_div_in_place1("2 1 1/3 4 4 1", "2 -1 1/3 6 5 1", "3 3 4 1/3 -2 1 1"); + test_div_in_place1("0", "1 2/2 3 5", "0"); + + test_div_in_place2("3 -1 0 1/1 2", "2 1 1/1 1", "2 -1 1/1 2"); + test_div_in_place2("0/2 1 1", "2 1 1/1 1", "0"); + test_div_in_place2("3 -1 0 1/1 4", "2 -1 -1/1 2", "2 1 -1/1 2"); + test_div_in_place2("2 1 1", "2 1 -1/2 1 -1", "2 1 1"); + test_div_in_place2("2 1 1/3 4 4 1", "2 -1 1/3 6 5 1", "3 3 4 1/3 -2 1 1"); + + test_div_in_place3("3 -1 0 1/1 2", "1 1"); + + test_pow("2 0 -1/1 2", 3, "4 0 0 0 -1/1 8"); + test_pow("0", 0, "1 1"); + test_pow("2 1 -1", 0, "1 1"); + test_pow("2 1 1/2 0 1", 0, "1 1"); + + /* Derivative ************************************************************/ + + test_derivative("0", "0"); + test_derivative("1 2", "0"); + test_derivative("1 -1/1 2", "0"); + test_derivative("2 0 1", "1 1"); + test_derivative("3 1 0 1", "2 0 2"); + test_derivative("1 1/2 0 1", "1 -1/3 0 0 1"); + test_derivative("2 2 1/2 -1 1", "1 -3/3 1 -2 1"); + + test_derivative("2 0 1/3 1 2 1", "2 1 -1/4 1 3 3 1"); + + /* Bug which allowed constant factors */ + test_derivative("3 5 1 -2/2 10 2", "3 0 -10 -1/3 25 10 1"); + + /* Evaluation ************************************************************/ + + test_evaluate("1 1/1 2", -2, 3, "1/2"); + test_evaluate("3 1 0 1/2 0 1", -1, 2, "-5/2"); + test_evaluate("2 3 1/2 -1 1", 1, 1, "P"); + test_evaluate("2 3 1/2 -1 1", 2, 3, "-11"); + test_evaluate("2 3 1/2 -1 2", 1, 2, "P"); + test_evaluate("2 1 1/2 -1 1", 2, 1, "3"); + + /* String methods ********************************************************/ + + fmpz_poly_q_init(qpoly1); + ans = fmpz_poly_q_set_str(qpoly1, "1 3/xyz"); + if ((ans == 0) || !fmpz_poly_q_is_zero(qpoly1)) + { + flint_printf("test_set_str: failed\n"); + abort(); + } + fmpz_poly_q_clear(qpoly1); + + fmpz_poly_q_init(qpoly1); + ans = fmpz_poly_q_set_str(qpoly1, "abc/1 3"); + if ((ans == 0) || !fmpz_poly_q_is_zero(qpoly1)) + { + flint_printf("test_set_str: failed\n"); + abort(); + } + fmpz_poly_q_clear(qpoly1); + + fmpz_poly_q_init(qpoly1); + ans = fmpz_poly_q_set_str(qpoly1, "abc/xyz"); + if ((ans == 0) || !fmpz_poly_q_is_zero(qpoly1)) + { + flint_printf("test_set_str: failed\n"); + abort(); + } + fmpz_poly_q_clear(qpoly1); + + test_get_str_pretty("1 -3", "-3"); + test_get_str_pretty("3 1 2 1", "t^2+2*t+1"); + test_get_str_pretty("1 -2/2 1 1", "-2/(t+1)"); + test_get_str_pretty("2 1 1/2 -1 1", "(t+1)/(t-1)"); + test_get_str_pretty("2 1 1/1 2", "(t+1)/2"); + test_get_str_pretty("1 1/1 2", "1/2"); + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/fmpz_poly_q/test/t-derivative.c b/external/flint-2.4.3/fmpz_poly_q/test/t-derivative.c new file mode 100644 index 0000000..22e1536 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/test/t-derivative.c @@ -0,0 +1,116 @@ +#include +#include +#include + +#include "fmpz_poly_q.h" +#include "long_extras.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("derivative... "); + fflush(stdout); + + + + /* Check aliasing */ + for (i = 0; i < 100; i++) + { + fmpz_poly_q_t a, b; + + fmpz_poly_q_init(a); + fmpz_poly_q_init(b); + fmpz_poly_q_randtest(a, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + + fmpz_poly_q_derivative(b, a); + fmpz_poly_q_derivative(a, a); + + result = fmpz_poly_q_equal(a, b); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_q_print(a), flint_printf("\n\n"); + fmpz_poly_q_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_q_clear(a); + fmpz_poly_q_clear(b); + } + + /* Check constants have derivative zero */ + for (i = 0; i < 100; i++) + { + fmpz_poly_q_t a, b; + + fmpz_poly_q_init(a); + fmpz_poly_q_init(b); + + fmpz_poly_q_set_si(a, z_randtest(state)); + + fmpz_poly_q_derivative(b, a); + + result = fmpz_poly_q_is_zero(b); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_q_print(a), flint_printf("\n\n"); + fmpz_poly_q_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_q_clear(a); + fmpz_poly_q_clear(b); + } + + /* Check (f g)' = f' g + f g' */ + for (i = 0; i < 100; i++) + { + fmpz_poly_q_t a, b, c, d, lhs, rhs; + + fmpz_poly_q_init(a); + fmpz_poly_q_init(b); + fmpz_poly_q_init(c); + fmpz_poly_q_init(d); + fmpz_poly_q_init(lhs); + fmpz_poly_q_init(rhs); + fmpz_poly_q_randtest(a, state, n_randint(state, 20), 20, n_randint(state, 20), 20); + fmpz_poly_q_randtest(b, state, n_randint(state, 20), 20, n_randint(state, 20), 20); + + fmpz_poly_q_mul(lhs, a, b); + fmpz_poly_q_derivative(lhs, lhs); + fmpz_poly_q_derivative(c, a); + fmpz_poly_q_derivative(d, b); + fmpz_poly_q_mul(c, c, b); + fmpz_poly_q_mul(d, a, d); + fmpz_poly_q_add(rhs, c, d); + + result = fmpz_poly_q_equal(lhs, rhs) && fmpz_poly_q_is_canonical(lhs) + && fmpz_poly_q_is_canonical(rhs); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_q_print(a), flint_printf("\n\n"); + fmpz_poly_q_print(b), flint_printf("\n\n"); + fmpz_poly_q_print(lhs), flint_printf("\n\n"); + fmpz_poly_q_print(rhs), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_q_clear(a); + fmpz_poly_q_clear(b); + fmpz_poly_q_clear(c); + fmpz_poly_q_clear(d); + fmpz_poly_q_clear(lhs); + fmpz_poly_q_clear(rhs); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fmpz_poly_q/test/t-div.c b/external/flint-2.4.3/fmpz_poly_q/test/t-div.c new file mode 100644 index 0000000..129667c --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/test/t-div.c @@ -0,0 +1,116 @@ +#include +#include +#include + +#include "fmpz_poly_q.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("div... "); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 100; i++) + { + fmpz_poly_q_t a, b, c; + + fmpz_poly_q_init(a); + fmpz_poly_q_init(b); + fmpz_poly_q_init(c); + fmpz_poly_q_randtest(b, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + fmpz_poly_q_randtest_not_zero(c, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + + fmpz_poly_q_div(a, b, c); + fmpz_poly_q_div(b, b, c); + + result = fmpz_poly_q_equal(a, b); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_q_print(a), flint_printf("\n\n"); + fmpz_poly_q_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_q_clear(a); + fmpz_poly_q_clear(b); + fmpz_poly_q_clear(c); + } + + /* Check aliasing of a and c */ + for (i = 0; i < 100; i++) + { + fmpz_poly_q_t a, b, c; + + fmpz_poly_q_init(a); + fmpz_poly_q_init(b); + fmpz_poly_q_init(c); + fmpz_poly_q_randtest(b, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + fmpz_poly_q_randtest_not_zero(c, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + + fmpz_poly_q_div(a, b, c); + fmpz_poly_q_div(c, b, c); + + result = (fmpz_poly_q_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_q_print(a), flint_printf("\n\n"); + fmpz_poly_q_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_q_clear(a); + fmpz_poly_q_clear(b); + fmpz_poly_q_clear(c); + } + + /* Check (c/b)+(d/b) = (c+d)/b */ + for (i = 0; i < 100; i++) + { + fmpz_poly_q_t a1, a2, b, c, d; + + fmpz_poly_q_init(a1); + fmpz_poly_q_init(a2); + fmpz_poly_q_init(b); + fmpz_poly_q_init(c); + fmpz_poly_q_init(d); + fmpz_poly_q_randtest_not_zero(b, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + fmpz_poly_q_randtest(c, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + fmpz_poly_q_randtest(d, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + + fmpz_poly_q_div(a1, c, b); + fmpz_poly_q_div(a2, d, b); + fmpz_poly_q_add(a1, a1, a2); + + fmpz_poly_q_add(c, c, d); + fmpz_poly_q_div(a2, c, b); + + result = fmpz_poly_q_equal(a1, a2) && fmpz_poly_q_is_canonical(a1); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_q_print(a1), flint_printf("\n\n"); + fmpz_poly_q_print(a2), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_q_clear(a1); + fmpz_poly_q_clear(a2); + fmpz_poly_q_clear(b); + fmpz_poly_q_clear(c); + fmpz_poly_q_clear(d); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fmpz_poly_q/test/t-evaluate.c b/external/flint-2.4.3/fmpz_poly_q/test/t-evaluate.c new file mode 100644 index 0000000..6073704 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/test/t-evaluate.c @@ -0,0 +1,68 @@ +#include +#include +#include + +#include "fmpz_poly_q.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("evaluate..."); + fflush(stdout); + + + + /* Check aliasing */ + for (i = 0; i < 100; i++) + { + int ans1, ans2; + mpq_t a, b; + fmpz_t num, den; + fmpz_poly_q_t f; + + mpq_init(a); + mpq_init(b); + fmpz_init(num); + fmpz_init(den); + fmpz_poly_q_init(f); + fmpz_poly_q_randtest(f, state, n_randint(state, 10), 10, n_randint(state, 10), 10); + + fmpz_randtest(num, state, 50); + fmpz_randtest_not_zero(den, state, 50); + fmpz_get_mpz(mpq_numref(a), num); + fmpz_get_mpz(mpq_denref(a), den); + mpq_canonicalize(a); + + ans1 = fmpz_poly_q_evaluate(b, f, a); + ans2 = fmpz_poly_q_evaluate(a, f, a); + + result = (ans1 == ans2) && mpq_equal(a, b); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("f = "), fmpz_poly_q_print(f), flint_printf("\n"); + flint_printf("num = "), fmpz_print(num), flint_printf("\n"); + flint_printf("den = "), fmpz_print(den), flint_printf("\n"); + gmp_printf("a = %Qd\n", a); + gmp_printf("b = %Qd\n", b); + flint_printf("ans1 = %d\n", ans1); + flint_printf("ans2 = %d\n", ans2); + abort(); + } + + mpq_clear(a); + mpq_clear(b); + fmpz_clear(num); + fmpz_clear(den); + fmpz_poly_q_clear(f); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fmpz_poly_q/test/t-init_clear.c b/external/flint-2.4.3/fmpz_poly_q/test/t-init_clear.c new file mode 100644 index 0000000..1a227d5 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/test/t-init_clear.c @@ -0,0 +1,41 @@ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include + +#include "fmpz_poly_q.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + flint_printf("init/clear... "); + fflush(stdout); + + + + for (i = 0; i < 100; i++) + { + fmpz_poly_q_t a; + slong len1 = n_randint(state, 50); + slong len2 = n_randint(state, 50); + mp_bitcnt_t bits1 = n_randint(state, 50); + mp_bitcnt_t bits2 = n_randint(state, 50); + + fmpz_poly_q_init(a); + fmpz_poly_q_randtest(a, state, len1, bits1, len2, bits2); + fmpz_poly_q_clear(a); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fmpz_poly_q/test/t-inv.c b/external/flint-2.4.3/fmpz_poly_q/test/t-inv.c new file mode 100644 index 0000000..732ac5c --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/test/t-inv.c @@ -0,0 +1,73 @@ +#include +#include +#include + +#include "fmpz_poly_q.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("inv... "); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 100; i++) + { + fmpz_poly_q_t a, b; + + fmpz_poly_q_init(a); + fmpz_poly_q_init(b); + fmpz_poly_q_randtest_not_zero(a, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + + fmpz_poly_q_inv(b, a); + fmpz_poly_q_inv(a, a); + + result = fmpz_poly_q_equal(a, b); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_q_print(a), flint_printf("\n\n"); + fmpz_poly_q_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_q_clear(a); + fmpz_poly_q_clear(b); + } + + /* Check a * (1/a) == 1 */ + for (i = 0; i < 100; i++) + { + fmpz_poly_q_t a, b; + + fmpz_poly_q_init(a); + fmpz_poly_q_init(b); + fmpz_poly_q_randtest_not_zero(a, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + + fmpz_poly_q_inv(b, a); + fmpz_poly_q_mul(b, a, b); + + result = fmpz_poly_q_is_one(b) && fmpz_poly_q_is_canonical(b); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_q_print(a), flint_printf("\n\n"); + fmpz_poly_q_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_q_clear(a); + fmpz_poly_q_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fmpz_poly_q/test/t-mul.c b/external/flint-2.4.3/fmpz_poly_q/test/t-mul.c new file mode 100644 index 0000000..031da8f --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/test/t-mul.c @@ -0,0 +1,116 @@ +#include +#include +#include + +#include "fmpz_poly_q.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("mul... "); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 100; i++) + { + fmpz_poly_q_t a, b, c; + + fmpz_poly_q_init(a); + fmpz_poly_q_init(b); + fmpz_poly_q_init(c); + fmpz_poly_q_randtest(b, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + fmpz_poly_q_randtest(c, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + + fmpz_poly_q_mul(a, b, c); + fmpz_poly_q_mul(b, b, c); + + result = fmpz_poly_q_equal(a, b); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_q_print(a), flint_printf("\n\n"); + fmpz_poly_q_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_q_clear(a); + fmpz_poly_q_clear(b); + fmpz_poly_q_clear(c); + } + + /* Check aliasing of a and c */ + for (i = 0; i < 100; i++) + { + fmpz_poly_q_t a, b, c; + + fmpz_poly_q_init(a); + fmpz_poly_q_init(b); + fmpz_poly_q_init(c); + fmpz_poly_q_randtest(b, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + fmpz_poly_q_randtest(c, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + + fmpz_poly_q_mul(a, b, c); + fmpz_poly_q_mul(c, b, c); + + result = (fmpz_poly_q_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_q_print(a), flint_printf("\n\n"); + fmpz_poly_q_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_q_clear(a); + fmpz_poly_q_clear(b); + fmpz_poly_q_clear(c); + } + + /* Check (b*c)+(b*d) = b*(c+d) */ + for (i = 0; i < 100; i++) + { + fmpz_poly_q_t a1, a2, b, c, d; + + fmpz_poly_q_init(a1); + fmpz_poly_q_init(a2); + fmpz_poly_q_init(b); + fmpz_poly_q_init(c); + fmpz_poly_q_init(d); + fmpz_poly_q_randtest(b, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + fmpz_poly_q_randtest(c, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + fmpz_poly_q_randtest(d, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + + fmpz_poly_q_mul(a1, b, c); + fmpz_poly_q_mul(a2, b, d); + fmpz_poly_q_add(a1, a1, a2); + + fmpz_poly_q_add(c, c, d); + fmpz_poly_q_mul(a2, b, c); + + result = fmpz_poly_q_equal(a1, a2) && fmpz_poly_q_is_canonical(a1); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_q_print(a1), flint_printf("\n\n"); + fmpz_poly_q_print(a2), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_q_clear(a1); + fmpz_poly_q_clear(a2); + fmpz_poly_q_clear(b); + fmpz_poly_q_clear(c); + fmpz_poly_q_clear(d); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fmpz_poly_q/test/t-neg.c b/external/flint-2.4.3/fmpz_poly_q/test/t-neg.c new file mode 100644 index 0000000..716e04e --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/test/t-neg.c @@ -0,0 +1,73 @@ +#include +#include +#include + +#include "fmpz_poly_q.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("neg... "); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 100; i++) + { + fmpz_poly_q_t a, b; + + fmpz_poly_q_init(a); + fmpz_poly_q_init(b); + fmpz_poly_q_randtest(a, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + + fmpz_poly_q_neg(b, a); + fmpz_poly_q_neg(a, a); + + result = fmpz_poly_q_equal(a, b); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_q_print(a), flint_printf("\n\n"); + fmpz_poly_q_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_q_clear(a); + fmpz_poly_q_clear(b); + } + + /* Check a + (-a) == 0 */ + for (i = 0; i < 100; i++) + { + fmpz_poly_q_t a, b; + + fmpz_poly_q_init(a); + fmpz_poly_q_init(b); + fmpz_poly_q_randtest(a, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + + fmpz_poly_q_neg(b, a); + fmpz_poly_q_add(b, a, b); + + result = fmpz_poly_q_is_zero(b) && fmpz_poly_q_is_canonical(b); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_q_print(a), flint_printf("\n\n"); + fmpz_poly_q_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_q_clear(a); + fmpz_poly_q_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fmpz_poly_q/test/t-pow.c b/external/flint-2.4.3/fmpz_poly_q/test/t-pow.c new file mode 100644 index 0000000..9bfdf48 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/test/t-pow.c @@ -0,0 +1,50 @@ +#include +#include +#include + +#include "fmpz_poly_q.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("pow... "); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 100; i++) + { + fmpz_poly_q_t a, b; + ulong e; + + fmpz_poly_q_init(a); + fmpz_poly_q_init(b); + fmpz_poly_q_randtest(b, state, n_randint(state, 10), 10, n_randint(state, 10), 10); + e = n_randint(state, 10); + + fmpz_poly_q_pow(a, b, e); + fmpz_poly_q_pow(b, b, e); + + result = fmpz_poly_q_equal(a, b) && fmpz_poly_q_is_canonical(a); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_q_print(a), flint_printf("\n\n"); + fmpz_poly_q_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_q_clear(a); + fmpz_poly_q_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fmpz_poly_q/test/t-scalar_div_mpq.c b/external/flint-2.4.3/fmpz_poly_q/test/t-scalar_div_mpq.c new file mode 100644 index 0000000..8a72eb6 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/test/t-scalar_div_mpq.c @@ -0,0 +1,114 @@ +#include +#include +#include + +#include "fmpz_poly_q.h" +#include "long_extras.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("scalar_div_mpq... "); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 100; i++) + { + fmpz_poly_q_t a, b; + fmpz_t x1, x2; + mpq_t y; + + fmpz_poly_q_init(a); + fmpz_poly_q_init(b); + fmpz_init(x1); + fmpz_init(x2); + mpq_init(y); + + fmpz_poly_q_randtest(b, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + fmpz_randtest_not_zero(x1, state, 50); + fmpz_randtest_not_zero(x2, state, 50); + fmpz_get_mpz(mpq_numref(y), x1); + fmpz_get_mpz(mpq_denref(y), x2); + mpq_canonicalize(y); + + fmpz_poly_q_scalar_div_mpq(a, b, y); + fmpz_poly_q_scalar_div_mpq(b, b, y); + + result = fmpz_poly_q_equal(a, b); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_q_print(a), flint_printf("\n\n"); + fmpz_poly_q_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_q_clear(a); + fmpz_poly_q_clear(b); + fmpz_clear(x1); + fmpz_clear(x2); + mpq_clear(y); + } + + /* Check that x (a + b) == x * a + x * b */ + for (i = 0; i < 100; i++) + { + fmpz_poly_q_t a, b, c, d; + fmpz_t x1, x2; + mpq_t y; + + fmpz_poly_q_init(a); + fmpz_poly_q_init(b); + fmpz_poly_q_init(c); + fmpz_poly_q_init(d); + fmpz_init(x1); + fmpz_init(x2); + mpq_init(y); + + fmpz_poly_q_randtest(a, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + fmpz_poly_q_randtest(b, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + fmpz_randtest_not_zero(x1, state, 50); + fmpz_randtest_not_zero(x2, state, 50); + fmpz_get_mpz(mpq_numref(y), x1); + fmpz_get_mpz(mpq_denref(y), x2); + mpq_canonicalize(y); + + fmpz_poly_q_scalar_div_mpq(c, a, y); + fmpz_poly_q_scalar_div_mpq(d, b, y); + fmpz_poly_q_add(d, c, d); + + fmpz_poly_q_add(c, a, b); + fmpz_poly_q_scalar_div_mpq(c, c, y); + + result = fmpz_poly_q_equal(c, d) && fmpz_poly_q_is_canonical(c); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpz_poly_q_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_poly_q_print(b), flint_printf("\n\n"); + flint_printf("c = "), fmpz_poly_q_print(c), flint_printf("\n\n"); + flint_printf("d = "), fmpz_poly_q_print(d), flint_printf("\n\n"); + gmp_printf("y = %Qd\n\n", y); + abort(); + } + + fmpz_poly_q_clear(a); + fmpz_poly_q_clear(b); + fmpz_poly_q_clear(c); + fmpz_poly_q_clear(d); + fmpz_clear(x1); + fmpz_clear(x2); + mpq_clear(y); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fmpz_poly_q/test/t-scalar_div_mpz.c b/external/flint-2.4.3/fmpz_poly_q/test/t-scalar_div_mpz.c new file mode 100644 index 0000000..3fb42d7 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/test/t-scalar_div_mpz.c @@ -0,0 +1,104 @@ +#include +#include +#include + +#include "fmpz_poly_q.h" +#include "long_extras.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("scalar_div_mpz... "); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 100; i++) + { + fmpz_poly_q_t a, b; + fmpz_t x; + mpz_t y; + + fmpz_poly_q_init(a); + fmpz_poly_q_init(b); + fmpz_init(x); + mpz_init(y); + + fmpz_poly_q_randtest(b, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + fmpz_randtest_not_zero(x, state, 50); + fmpz_get_mpz(y, x); + + fmpz_poly_q_scalar_div_mpz(a, b, y); + fmpz_poly_q_scalar_div_mpz(b, b, y); + + result = fmpz_poly_q_equal(a, b); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_q_print(a), flint_printf("\n\n"); + fmpz_poly_q_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_q_clear(a); + fmpz_poly_q_clear(b); + fmpz_clear(x); + mpz_clear(y); + } + + /* Check that (a + b) / x == a / x + b / x */ + for (i = 0; i < 100; i++) + { + fmpz_poly_q_t a, b, c, d; + fmpz_t x; + mpz_t y; + + fmpz_poly_q_init(a); + fmpz_poly_q_init(b); + fmpz_poly_q_init(c); + fmpz_poly_q_init(d); + fmpz_init(x); + mpz_init(y); + + fmpz_poly_q_randtest(a, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + fmpz_poly_q_randtest(b, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + fmpz_randtest_not_zero(x, state, 50); + fmpz_get_mpz(y, x); + + fmpz_poly_q_scalar_div_mpz(c, a, y); + fmpz_poly_q_scalar_div_mpz(d, b, y); + fmpz_poly_q_add(d, c, d); + + fmpz_poly_q_add(c, a, b); + fmpz_poly_q_scalar_div_mpz(c, c, y); + + result = fmpz_poly_q_equal(c, d) && fmpz_poly_q_is_canonical(c); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpz_poly_q_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_poly_q_print(b), flint_printf("\n\n"); + flint_printf("c = "), fmpz_poly_q_print(c), flint_printf("\n\n"); + flint_printf("d = "), fmpz_poly_q_print(d), flint_printf("\n\n"); + gmp_printf("y = %Zd\n\n", y); + abort(); + } + + fmpz_poly_q_clear(a); + fmpz_poly_q_clear(b); + fmpz_poly_q_clear(c); + fmpz_poly_q_clear(d); + fmpz_clear(x); + mpz_clear(y); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fmpz_poly_q/test/t-scalar_div_si.c b/external/flint-2.4.3/fmpz_poly_q/test/t-scalar_div_si.c new file mode 100644 index 0000000..7522b3d --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/test/t-scalar_div_si.c @@ -0,0 +1,94 @@ +#include +#include +#include + +#include "fmpz_poly_q.h" +#include "long_extras.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("scalar_div_si... "); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 100; i++) + { + fmpz_poly_q_t a, b; + slong x; + + fmpz_poly_q_init(a); + fmpz_poly_q_init(b); + fmpz_poly_q_randtest(b, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + x = z_randtest_not_zero(state); + + fmpz_poly_q_scalar_div_si(a, b, x); + fmpz_poly_q_scalar_div_si(b, b, x); + + result = fmpz_poly_q_equal(a, b); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_q_print(a), flint_printf("\n\n"); + fmpz_poly_q_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_q_clear(a); + fmpz_poly_q_clear(b); + } + + /* Check that (a + b) / x == a / x + b / x */ + for (i = 0; i < 100; i++) + { + fmpz_poly_q_t a, b, c, d; + slong x; + + fmpz_poly_q_init(a); + fmpz_poly_q_init(b); + fmpz_poly_q_init(c); + fmpz_poly_q_init(d); + + fmpz_poly_q_randtest(a, state, n_randint(state, 50), 50, + n_randint(state, 50), 50); + fmpz_poly_q_randtest(b, state, n_randint(state, 50), 50, + n_randint(state, 50), 50); + + x = z_randtest_not_zero(state); + + fmpz_poly_q_scalar_div_si(c, a, x); + fmpz_poly_q_scalar_div_si(d, b, x); + fmpz_poly_q_add(d, c, d); + + fmpz_poly_q_add(c, a, b); + fmpz_poly_q_scalar_div_si(c, c, x); + + result = fmpz_poly_q_equal(c, d) && fmpz_poly_q_is_canonical(c); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpz_poly_q_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_poly_q_print(b), flint_printf("\n\n"); + flint_printf("c = "), fmpz_poly_q_print(c), flint_printf("\n\n"); + flint_printf("d = "), fmpz_poly_q_print(d), flint_printf("\n\n"); + flint_printf("x = %wd\n\n", x); + abort(); + } + + fmpz_poly_q_clear(a); + fmpz_poly_q_clear(b); + fmpz_poly_q_clear(c); + fmpz_poly_q_clear(d); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fmpz_poly_q/test/t-scalar_mul_mpq.c b/external/flint-2.4.3/fmpz_poly_q/test/t-scalar_mul_mpq.c new file mode 100644 index 0000000..9902359 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/test/t-scalar_mul_mpq.c @@ -0,0 +1,114 @@ +#include +#include +#include + +#include "fmpz_poly_q.h" +#include "long_extras.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("scalar_mul_mpq... "); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 100; i++) + { + fmpz_poly_q_t a, b; + fmpz_t x1, x2; + mpq_t y; + + fmpz_poly_q_init(a); + fmpz_poly_q_init(b); + fmpz_init(x1); + fmpz_init(x2); + mpq_init(y); + + fmpz_poly_q_randtest(b, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + fmpz_randtest(x1, state, 50); + fmpz_randtest_not_zero(x2, state, 50); + fmpz_get_mpz(mpq_numref(y), x1); + fmpz_get_mpz(mpq_denref(y), x2); + mpq_canonicalize(y); + + fmpz_poly_q_scalar_mul_mpq(a, b, y); + fmpz_poly_q_scalar_mul_mpq(b, b, y); + + result = fmpz_poly_q_equal(a, b); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_q_print(a), flint_printf("\n\n"); + fmpz_poly_q_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_q_clear(a); + fmpz_poly_q_clear(b); + fmpz_clear(x1); + fmpz_clear(x2); + mpq_clear(y); + } + + /* Check that x (a + b) == x * a + x * b */ + for (i = 0; i < 100; i++) + { + fmpz_poly_q_t a, b, c, d; + fmpz_t x1, x2; + mpq_t y; + + fmpz_poly_q_init(a); + fmpz_poly_q_init(b); + fmpz_poly_q_init(c); + fmpz_poly_q_init(d); + fmpz_init(x1); + fmpz_init(x2); + mpq_init(y); + + fmpz_poly_q_randtest(a, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + fmpz_poly_q_randtest(b, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + fmpz_randtest(x1, state, 50); + fmpz_randtest_not_zero(x2, state, 50); + fmpz_get_mpz(mpq_numref(y), x1); + fmpz_get_mpz(mpq_denref(y), x2); + mpq_canonicalize(y); + + fmpz_poly_q_scalar_mul_mpq(c, a, y); + fmpz_poly_q_scalar_mul_mpq(d, b, y); + fmpz_poly_q_add(d, c, d); + + fmpz_poly_q_add(c, a, b); + fmpz_poly_q_scalar_mul_mpq(c, c, y); + + result = fmpz_poly_q_equal(c, d) && fmpz_poly_q_is_canonical(c); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpz_poly_q_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_poly_q_print(b), flint_printf("\n\n"); + flint_printf("c = "), fmpz_poly_q_print(c), flint_printf("\n\n"); + flint_printf("d = "), fmpz_poly_q_print(d), flint_printf("\n\n"); + gmp_printf("y = %Qd\n\n", y); + abort(); + } + + fmpz_poly_q_clear(a); + fmpz_poly_q_clear(b); + fmpz_poly_q_clear(c); + fmpz_poly_q_clear(d); + fmpz_clear(x1); + fmpz_clear(x2); + mpq_clear(y); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fmpz_poly_q/test/t-scalar_mul_mpz.c b/external/flint-2.4.3/fmpz_poly_q/test/t-scalar_mul_mpz.c new file mode 100644 index 0000000..1a09728 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/test/t-scalar_mul_mpz.c @@ -0,0 +1,104 @@ +#include +#include +#include + +#include "fmpz_poly_q.h" +#include "long_extras.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("scalar_mul_mpz... "); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 100; i++) + { + fmpz_poly_q_t a, b; + fmpz_t x; + mpz_t y; + + fmpz_poly_q_init(a); + fmpz_poly_q_init(b); + fmpz_init(x); + mpz_init(y); + + fmpz_poly_q_randtest(b, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + fmpz_randtest(x, state, 50); + fmpz_get_mpz(y, x); + + fmpz_poly_q_scalar_mul_mpz(a, b, y); + fmpz_poly_q_scalar_mul_mpz(b, b, y); + + result = fmpz_poly_q_equal(a, b); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_q_print(a), flint_printf("\n\n"); + fmpz_poly_q_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_q_clear(a); + fmpz_poly_q_clear(b); + fmpz_clear(x); + mpz_clear(y); + } + + /* Check that x (a + b) == x * a + x * b */ + for (i = 0; i < 100; i++) + { + fmpz_poly_q_t a, b, c, d; + fmpz_t x; + mpz_t y; + + fmpz_poly_q_init(a); + fmpz_poly_q_init(b); + fmpz_poly_q_init(c); + fmpz_poly_q_init(d); + fmpz_init(x); + mpz_init(y); + + fmpz_poly_q_randtest(a, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + fmpz_poly_q_randtest(b, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + fmpz_randtest(x, state, 50); + fmpz_get_mpz(y, x); + + fmpz_poly_q_scalar_mul_mpz(c, a, y); + fmpz_poly_q_scalar_mul_mpz(d, b, y); + fmpz_poly_q_add(d, c, d); + + fmpz_poly_q_add(c, a, b); + fmpz_poly_q_scalar_mul_mpz(c, c, y); + + result = fmpz_poly_q_equal(c, d) && fmpz_poly_q_is_canonical(c); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpz_poly_q_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_poly_q_print(b), flint_printf("\n\n"); + flint_printf("c = "), fmpz_poly_q_print(c), flint_printf("\n\n"); + flint_printf("d = "), fmpz_poly_q_print(d), flint_printf("\n\n"); + gmp_printf("y = %Zd\n\n", y); + abort(); + } + + fmpz_poly_q_clear(a); + fmpz_poly_q_clear(b); + fmpz_poly_q_clear(c); + fmpz_poly_q_clear(d); + fmpz_clear(x); + mpz_clear(y); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fmpz_poly_q/test/t-scalar_mul_si.c b/external/flint-2.4.3/fmpz_poly_q/test/t-scalar_mul_si.c new file mode 100644 index 0000000..10776d2 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/test/t-scalar_mul_si.c @@ -0,0 +1,90 @@ +#include +#include +#include + +#include "fmpz_poly_q.h" +#include "long_extras.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("scalar_mul_si... "); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 100; i++) + { + fmpz_poly_q_t a, b; + slong x; + + fmpz_poly_q_init(a); + fmpz_poly_q_init(b); + fmpz_poly_q_randtest(b, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + x = z_randtest(state); + + fmpz_poly_q_scalar_mul_si(a, b, x); + fmpz_poly_q_scalar_mul_si(b, b, x); + + result = fmpz_poly_q_equal(a, b); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_q_print(a), flint_printf("\n\n"); + fmpz_poly_q_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_q_clear(a); + fmpz_poly_q_clear(b); + } + + /* Check that x (a + b) == x * a + x * b */ + for (i = 0; i < 100; i++) + { + fmpz_poly_q_t a, b, c, d; + slong x; + + fmpz_poly_q_init(a); + fmpz_poly_q_init(b); + fmpz_poly_q_init(c); + fmpz_poly_q_init(d); + fmpz_poly_q_randtest(a, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + fmpz_poly_q_randtest(b, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + x = z_randtest(state); + + fmpz_poly_q_scalar_mul_si(c, a, x); + fmpz_poly_q_scalar_mul_si(d, b, x); + fmpz_poly_q_add(d, c, d); + + fmpz_poly_q_add(c, a, b); + fmpz_poly_q_scalar_mul_si(c, c, x); + + result = fmpz_poly_q_equal(c, d) && fmpz_poly_q_is_canonical(c); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpz_poly_q_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_poly_q_print(b), flint_printf("\n\n"); + flint_printf("c = "), fmpz_poly_q_print(c), flint_printf("\n\n"); + flint_printf("d = "), fmpz_poly_q_print(d), flint_printf("\n\n"); + flint_printf("x = %wd\n\n", x); + abort(); + } + + fmpz_poly_q_clear(a); + fmpz_poly_q_clear(b); + fmpz_poly_q_clear(c); + fmpz_poly_q_clear(d); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fmpz_poly_q/test/t-set_equal.c b/external/flint-2.4.3/fmpz_poly_q/test/t-set_equal.c new file mode 100644 index 0000000..07b6ab5 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/test/t-set_equal.c @@ -0,0 +1,83 @@ +#include +#include +#include + +#include "fmpz_poly_q.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("set/equal... "); + fflush(stdout); + + + + /* Equal polynomials */ + for (i = 0; i < 100; i++) + { + fmpz_poly_q_t a, b; + + fmpz_poly_q_init(a); + fmpz_poly_q_init(b); + fmpz_poly_q_randtest(a, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + + fmpz_poly_q_set(b, a); + + result = fmpz_poly_q_equal(a, b); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_q_print(a), flint_printf("\n\n"); + fmpz_poly_q_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_q_clear(a); + fmpz_poly_q_clear(b); + } + + for (i = 0; i < 100; i++) + { + fmpz_poly_q_t a, b; + slong coeff = n_randint(state, 50); + fmpz_t x1, x2; + + fmpz_init(x1); + fmpz_init(x2); + fmpz_poly_q_init(a); + fmpz_poly_q_init(b); + fmpz_poly_q_randtest(a, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + + fmpz_poly_q_set(b, a); + + fmpz_poly_get_coeff_fmpz(x2, fmpz_poly_q_numref(b), coeff); + do + fmpz_randtest(x1, state, 50); + while (fmpz_equal(x1, x2)); + fmpz_poly_set_coeff_fmpz(fmpz_poly_q_numref(b), coeff, x1); + fmpz_poly_q_canonicalise(b); + + result = !fmpz_poly_q_equal(a, b); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_q_print(a), flint_printf("\n\n"); + fmpz_poly_q_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(x1); + fmpz_clear(x2); + fmpz_poly_q_clear(a); + fmpz_poly_q_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fmpz_poly_q/test/t-set_si_equal.c b/external/flint-2.4.3/fmpz_poly_q/test/t-set_si_equal.c new file mode 100644 index 0000000..840cf08 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/test/t-set_si_equal.c @@ -0,0 +1,81 @@ +#include +#include +#include + +#include "fmpz_poly_q.h" +#include "long_extras.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("set_si_equal... "); + fflush(stdout); + + + + /* Equal polynomials */ + for (i = 0; i < 100; i++) + { + fmpz_poly_q_t a, b; + slong n; + + fmpz_poly_q_init(a); + fmpz_poly_q_init(b); + n = z_randtest(state); + + fmpz_poly_q_set_si(a, n); + fmpz_poly_q_set(b, a); + + result = fmpz_poly_q_equal(a, b); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("n = %wd\n\n", n); + flint_printf("a = "), fmpz_poly_q_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_poly_q_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_q_clear(a); + fmpz_poly_q_clear(b); + } + + for (i = 0; i < 100; i++) + { + fmpz_poly_q_t a, b; + slong m, n; + + fmpz_poly_q_init(a); + fmpz_poly_q_init(b); + + m = z_randtest(state); + n = z_randtest(state); + while (m == n) + n = z_randtest(state); + fmpz_poly_q_set_si(a, m); + fmpz_poly_q_set_si(b, n); + + result = !fmpz_poly_q_equal(a, b); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("m = %wd\n\n", m); + flint_printf("n = %wd\n\n", n); + flint_printf("a = "), fmpz_poly_q_print(a), flint_printf("\n\n"); + flint_printf("b = "), fmpz_poly_q_print(b), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_q_clear(a); + fmpz_poly_q_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fmpz_poly_q/test/t-sub.c b/external/flint-2.4.3/fmpz_poly_q/test/t-sub.c new file mode 100644 index 0000000..28e2f5f --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/test/t-sub.c @@ -0,0 +1,81 @@ +#include +#include +#include + +#include "fmpz_poly_q.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("add... "); + fflush(stdout); + + + + /* Check aliasing of a and c */ + for (i = 0; i < 100; i++) + { + fmpz_poly_q_t a, b, c; + + fmpz_poly_q_init(a); + fmpz_poly_q_init(b); + fmpz_poly_q_init(c); + fmpz_poly_q_randtest(a, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + fmpz_poly_q_randtest(b, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + + fmpz_poly_q_sub(c, a, b); + fmpz_poly_q_sub(a, a, b); + + result = (fmpz_poly_q_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_q_print(a), flint_printf("\n\n"); + fmpz_poly_q_print(b), flint_printf("\n\n"); + fmpz_poly_q_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_q_clear(a); + fmpz_poly_q_clear(b); + fmpz_poly_q_clear(c); + } + + /* Check aliasing of b and c */ + for (i = 0; i < 100; i++) + { + fmpz_poly_q_t a, b, c; + + fmpz_poly_q_init(a); + fmpz_poly_q_init(b); + fmpz_poly_q_init(c); + fmpz_poly_q_randtest(a, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + fmpz_poly_q_randtest(b, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + + fmpz_poly_q_sub(c, a, b); + fmpz_poly_q_sub(b, a, b); + + result = fmpz_poly_q_equal(b, c); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_q_print(a), flint_printf("\n\n"); + fmpz_poly_q_print(b), flint_printf("\n\n"); + fmpz_poly_q_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_q_clear(a); + fmpz_poly_q_clear(b); + fmpz_poly_q_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fmpz_poly_q/test/t-submul.c b/external/flint-2.4.3/fmpz_poly_q/test/t-submul.c new file mode 100644 index 0000000..bb3db57 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/test/t-submul.c @@ -0,0 +1,83 @@ +#include +#include +#include + +#include "fmpz_poly_q.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("submul... "); + fflush(stdout); + + + + /* Check aliasing of a and c */ + for (i = 0; i < 100; i++) + { + fmpz_poly_q_t a, b, c; + + fmpz_poly_q_init(a); + fmpz_poly_q_init(b); + fmpz_poly_q_init(c); + fmpz_poly_q_randtest(a, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + fmpz_poly_q_randtest(b, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + fmpz_poly_q_set(c, a); + + fmpz_poly_q_submul(c, a, b); + fmpz_poly_q_submul(a, a, b); + + result = fmpz_poly_q_equal(a, c) && fmpz_poly_q_is_canonical(a); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_q_print(a), flint_printf("\n\n"); + fmpz_poly_q_print(b), flint_printf("\n\n"); + fmpz_poly_q_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_q_clear(a); + fmpz_poly_q_clear(b); + fmpz_poly_q_clear(c); + } + + /* Check aliasing of b and c */ + for (i = 0; i < 100; i++) + { + fmpz_poly_q_t a, b, c; + + fmpz_poly_q_init(a); + fmpz_poly_q_init(b); + fmpz_poly_q_init(c); + fmpz_poly_q_randtest(a, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + fmpz_poly_q_randtest(b, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + fmpz_poly_q_set(c, b); + + fmpz_poly_q_submul(c, a, b); + fmpz_poly_q_submul(b, a, b); + + result = fmpz_poly_q_equal(b, c); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_q_print(a), flint_printf("\n\n"); + fmpz_poly_q_print(b), flint_printf("\n\n"); + fmpz_poly_q_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_q_clear(a); + fmpz_poly_q_clear(b); + fmpz_poly_q_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fmpz_poly_q/test/t-swap.c b/external/flint-2.4.3/fmpz_poly_q/test/t-swap.c new file mode 100644 index 0000000..b96745a --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/test/t-swap.c @@ -0,0 +1,51 @@ +#include +#include +#include + +#include "fmpz_poly_q.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("swap... "); + fflush(stdout); + + + + for (i = 0; i < 100; i++) + { + fmpz_poly_q_t a, b, c; + + fmpz_poly_q_init(a); + fmpz_poly_q_init(b); + fmpz_poly_q_init(c); + fmpz_poly_q_randtest(a, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + fmpz_poly_q_randtest(b, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + + fmpz_poly_q_set(c, b); + fmpz_poly_q_swap(a, b); + + result = fmpz_poly_q_equal(a, c); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_poly_q_print(a), flint_printf("\n\n"); + fmpz_poly_q_print(b), flint_printf("\n\n"); + fmpz_poly_q_print(c), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_q_clear(a); + fmpz_poly_q_clear(b); + fmpz_poly_q_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fmpz_poly_q/test/t-zero.c b/external/flint-2.4.3/fmpz_poly_q/test/t-zero.c new file mode 100644 index 0000000..827b5c8 --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_q/test/t-zero.c @@ -0,0 +1,42 @@ +#include +#include +#include + +#include "fmpz_poly_q.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("zero... "); + fflush(stdout); + + + + for (i = 0; i < 100; i++) + { + fmpz_poly_q_t a; + + fmpz_poly_q_init(a); + fmpz_poly_q_randtest(a, state, n_randint(state, 50), 50, n_randint(state, 50), 50); + fmpz_poly_q_zero(a); + + result = fmpz_poly_q_is_zero(a) && fmpz_poly_q_is_canonical(a); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), fmpz_poly_q_print(a), flint_printf("\n\n"); + abort(); + } + + fmpz_poly_q_clear(a); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fmpz_poly_qxx.h b/external/flint-2.4.3/fmpz_poly_qxx.h new file mode 100644 index 0000000..7ae681d --- /dev/null +++ b/external/flint-2.4.3/fmpz_poly_qxx.h @@ -0,0 +1,302 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#ifndef FMPZ_POLY_QXX_H +#define FMPZ_POLY_QXX_H FMPZ_POLY_QXX_H + +#include +#include + +#include "flint.h" +#include "fmpz_poly_q.h" + +#include "fmpz_polyxx.h" +#include "fmpqxx.h" + +#include "flintxx/expression.h" +#include "flintxx/flint_classes.h" + +namespace flint { +FLINT_DEFINE_UNOP(fmpz_poly_qxx_num) +FLINT_DEFINE_UNOP(fmpz_poly_qxx_den) + +namespace detail { +template +struct fmpz_poly_q_traits +{ + typedef FLINT_UNOP_BUILD_RETTYPE( + fmpz_poly_qxx_num, fmpz_polyxx, Polyq) num_ref_t; + typedef FLINT_UNOP_BUILD_RETTYPE( + fmpz_poly_qxx_den, fmpz_polyxx, Polyq) den_ref_t; + typedef num_ref_t num_srcref_t; + typedef den_ref_t den_srcref_t; + static num_ref_t num(const Polyq& p) {return fmpz_poly_qxx_num(p);} + static den_ref_t den(const Polyq& p) {return fmpz_poly_qxx_den(p);} +}; +} // detail + +template +class fmpz_poly_qxx_expression + : public expression, + Operation, Data> +{ +public: + typedef expression, + Operation, Data> base_t; + typedef detail::fmpz_poly_q_traits poly_traits_t; + typedef typename poly_traits_t::num_ref_t num_ref_t; + typedef typename poly_traits_t::num_srcref_t num_srcref_t; + typedef typename poly_traits_t::den_ref_t den_ref_t; + typedef typename poly_traits_t::den_srcref_t den_srcref_t; + + FLINTXX_DEFINE_BASICS(fmpz_poly_qxx_expression) + FLINTXX_DEFINE_CTORS(fmpz_poly_qxx_expression) + FLINTXX_DEFINE_C_REF(fmpz_poly_qxx_expression, fmpz_poly_q_struct, _polyq) + + // static methods which only make sense with fmpq_polyxx + static fmpz_poly_qxx_expression randtest(frandxx& state, + slong len1, mp_bitcnt_t bits1, slong len2, mp_bitcnt_t bits2) + { + fmpz_poly_qxx_expression res; + fmpz_poly_q_randtest(res._polyq(), state._data(), + len1, bits1, len2, bits2); + return res; + } + static fmpz_poly_qxx_expression randtest_not_zero(frandxx& state, + slong len1, mp_bitcnt_t bits1, slong len2, mp_bitcnt_t bits2) + { + fmpz_poly_qxx_expression res; + fmpz_poly_q_randtest_not_zero(res._polyq(), state._data(), + len1, bits1, len2, bits2); + return res; + } + + static fmpz_poly_qxx_expression zero(){return fmpz_poly_qxx_expression();} + static fmpz_poly_qxx_expression one() + { + fmpz_poly_qxx_expression res; + res.set_one(); + return res; + } + + // Numerator and denominator access + num_ref_t num() {return poly_traits_t::num(*this);} + num_srcref_t num() const {return poly_traits_t::num(*this);} + den_ref_t den() {return poly_traits_t::den(*this);} + den_srcref_t den() const {return poly_traits_t::den(*this);} + bool is_canonical() const {return fmpz_poly_q_is_canonical(_polyq());} + + // these only make sense with target immediates + void canonicalise() {fmpz_poly_q_canonicalise(_polyq());} + void set_zero() {fmpz_poly_q_zero(_polyq());} + void set_one() {fmpz_poly_q_one(_polyq());} + + // These cause evaluation + std::string pretty(const char* x) const + { + char* str = fmpz_poly_q_get_str_pretty(this->evaluate()._polyq(), x); + std::string res(str); + flint_free(str); + return res; + } + bool is_one() const {return fmpz_poly_q_is_one(this->evaluate()._polyq());} + bool is_zero() const {return fmpz_poly_q_is_zero(this->evaluate()._polyq());} + + // forwarded lazy member functions + FLINTXX_DEFINE_MEMBER_UNOP(inv) + FLINTXX_DEFINE_MEMBER_BINOP(pow) + FLINTXX_DEFINE_MEMBER_UNOP(derivative) +}; + +namespace detail { +struct fmpz_poly_q_data; +} + +typedef fmpz_poly_qxx_expression + fmpz_poly_qxx; +typedef fmpz_poly_qxx_expression > + fmpz_poly_qxx_ref; +typedef fmpz_poly_qxx_expression > + fmpz_poly_qxx_srcref; + +namespace detail { +template<> +struct fmpz_poly_q_traits +{ + typedef fmpz_polyxx_srcref num_ref_t; + typedef fmpz_polyxx_srcref num_srcref_t; + typedef fmpz_polyxx_srcref den_ref_t; + typedef fmpz_polyxx_srcref den_srcref_t; + template static num_srcref_t num(const P& p) + {return num_srcref_t::make(fmpz_poly_q_numref(p._polyq()));} + template static den_srcref_t den(const P& p) + {return num_srcref_t::make(fmpz_poly_q_denref(p._polyq()));} +}; +template<> +struct fmpz_poly_q_traits +{ + typedef fmpz_polyxx_ref num_ref_t; + typedef fmpz_polyxx_ref den_ref_t; + typedef fmpz_polyxx_ref num_srcref_t; + typedef fmpz_polyxx_ref den_srcref_t; + template static num_ref_t num(P p) + {return num_ref_t::make(fmpz_poly_q_numref(p._polyq()));} + template static den_ref_t den(P p) + {return num_ref_t::make(fmpz_poly_q_denref(p._polyq()));} +}; +template<> +struct fmpz_poly_q_traits +{ + typedef fmpz_polyxx_ref num_ref_t; + typedef fmpz_polyxx_ref den_ref_t; + typedef fmpz_polyxx_srcref num_srcref_t; + typedef fmpz_polyxx_srcref den_srcref_t; + template static num_ref_t num(P& p) + {return num_ref_t::make(fmpz_poly_q_numref(p._polyq()));} + template static den_ref_t den(P& p) + {return num_ref_t::make(fmpz_poly_q_denref(p._polyq()));} + template static num_srcref_t num(const P& p) + {return num_srcref_t::make(fmpz_poly_q_numref(p._polyq()));} + template static den_srcref_t den(const P& p) + {return num_srcref_t::make(fmpz_poly_q_denref(p._polyq()));} +}; + +struct fmpz_poly_q_data +{ + fmpz_poly_q_t inner; + typedef fmpz_poly_q_t& data_ref_t; + typedef const fmpz_poly_q_t& data_srcref_t; + + fmpz_poly_q_data() {fmpz_poly_q_init(inner);} + ~fmpz_poly_q_data() {fmpz_poly_q_clear(inner);} + + fmpz_poly_q_data(const fmpz_poly_q_data& o) + { + fmpz_poly_q_init(inner); + fmpz_poly_q_set(inner, o.inner); + } + + fmpz_poly_q_data(fmpz_poly_qxx_srcref r) + { + fmpz_poly_q_init(inner); + fmpz_poly_q_set(inner, r._polyq()); + } + + fmpz_poly_q_data(const char* str) + { + fmpz_poly_q_init(inner); + execution_check(!fmpz_poly_q_set_str(inner, str), + "construct from string", "fmpz_poly_qxx"); + } +}; +} // detail + +namespace rules { +#define FMPZ_POLY_QXX_COND_S FLINTXX_COND_S(fmpz_poly_qxx) +#define FMPZ_POLY_QXX_COND_T FLINTXX_COND_T(fmpz_poly_qxx) + +FLINTXX_DEFINE_TO_STR(fmpz_poly_qxx, fmpz_poly_q_get_str(from._polyq())) +FLINTXX_DEFINE_SWAP(fmpz_poly_qxx, fmpz_poly_q_swap(e1._polyq(), e2._polyq())) + +FLINT_DEFINE_DOIT_COND2(assignment, FMPZ_POLY_QXX_COND_T, FMPZ_POLY_QXX_COND_S, + fmpz_poly_q_set(to._polyq(), from._polyq())) +FLINT_DEFINE_DOIT_COND2(assignment, FMPZ_POLY_QXX_COND_T, + traits::fits_into_slong, fmpz_poly_q_set_si(to._polyq(), from)) + +FLINTXX_DEFINE_ASSIGN_STR(fmpz_poly_qxx, execution_check( + !fmpz_poly_q_set_str(to._polyq(), from), + "assign string", "fmpz_poly_qxx")) + +FLINT_DEFINE_PRINT_COND(FMPZ_POLY_QXX_COND_S, fmpz_poly_q_print(from._polyq())) +FLINT_DEFINE_PRINT_PRETTY_COND_2(FMPZ_POLY_QXX_COND_S, const char*, + fmpz_poly_q_print_pretty(from._polyq(), extra)) + +FLINTXX_DEFINE_EQUALS(fmpz_poly_qxx, fmpz_poly_q_equal(e1._polyq(), e2._polyq())) + +FLINT_DEFINE_UNARY_EXPR_COND(negate, fmpz_poly_qxx, FMPZ_POLY_QXX_COND_S, + fmpz_poly_q_neg(to._polyq(), from._polyq())) +FLINT_DEFINE_UNARY_EXPR_COND(inv_op, fmpz_poly_qxx, FMPZ_POLY_QXX_COND_S, + fmpz_poly_q_inv(to._polyq(), from._polyq())) + +FLINT_DEFINE_BINARY_EXPR_COND2(plus, fmpz_poly_qxx, + FMPZ_POLY_QXX_COND_S, FMPZ_POLY_QXX_COND_S, + fmpz_poly_q_add(to._polyq(), e1._polyq(), e2._polyq())) +FLINT_DEFINE_BINARY_EXPR_COND2(minus, fmpz_poly_qxx, + FMPZ_POLY_QXX_COND_S, FMPZ_POLY_QXX_COND_S, + fmpz_poly_q_sub(to._polyq(), e1._polyq(), e2._polyq())) + +FLINT_DEFINE_CBINARY_EXPR_COND2(times, fmpz_poly_qxx, + FMPZ_POLY_QXX_COND_S, traits::fits_into_slong, + fmpz_poly_q_scalar_mul_si(to._polyq(), e1._polyq(), e2)) +FLINT_DEFINE_BINARY_EXPR_COND2(divided_by, fmpz_poly_qxx, + FMPZ_POLY_QXX_COND_S, traits::fits_into_slong, + fmpz_poly_q_scalar_div_si(to._polyq(), e1._polyq(), e2)) + +FLINT_DEFINE_BINARY_EXPR_COND2(times, fmpz_poly_qxx, + FMPZ_POLY_QXX_COND_S, FMPZ_POLY_QXX_COND_S, + fmpz_poly_q_mul(to._polyq(), e1._polyq(), e2._polyq())) +FLINT_DEFINE_BINARY_EXPR_COND2(divided_by, fmpz_poly_qxx, + FMPZ_POLY_QXX_COND_S, FMPZ_POLY_QXX_COND_S, + fmpz_poly_q_div(to._polyq(), e1._polyq(), e2._polyq())) + +FLINT_DEFINE_BINARY_EXPR_COND2(pow_op, fmpz_poly_qxx, + FMPZ_POLY_QXX_COND_S, traits::is_unsigned_integer, + fmpz_poly_q_pow(to._polyq(), e1._polyq(), e2)) + +FLINT_DEFINE_UNARY_EXPR_COND(derivative_op, fmpz_poly_qxx, FMPZ_POLY_QXX_COND_S, + fmpz_poly_q_derivative(to._polyq(), from._polyq())) + +FLINT_DEFINE_UNARY_EXPR_COND(fmpz_poly_qxx_num_op, fmpz_polyxx, + FMPZ_POLY_QXX_COND_S, + fmpz_poly_set(to._poly(), fmpz_poly_q_numref(from._polyq()))) +FLINT_DEFINE_UNARY_EXPR_COND(fmpz_poly_qxx_den_op, fmpz_polyxx, + FMPZ_POLY_QXX_COND_S, + fmpz_poly_set(to._poly(), fmpz_poly_q_denref(from._polyq()))) + +// XXX these should really be in fmpz_poly_q.h ... +#if 0 +FLINT_DEFINE_CBINARY_EXPR_COND2(times, fmpz_poly_qxx, + FMPZ_POLY_QXX_COND_S, FMPZXX_COND_S, + to.numref() = e1.numref()*e2;to.denref() = e1.denref();to.canonicalise()) +FLINT_DEFINE_CBINARY_EXPR_COND2(divided_by, fmpz_poly_qxx, + FMPZ_POLY_QXX_COND_S, FMPZXX_COND_S, + to.denref() = e1.denref()*e2;to.numref() = e1.numref();to.canonicalise()) +FLINT_DEFINE_CBINARY_EXPR_COND2(times, fmpz_poly_qxx, + FMPZ_POLY_QXX_COND_S, FMPQXX_COND_S, + to.numref() = e1.numref()*e2.num();to.denref() = e1.denref()*e2.den(); + to.canonicalise()) +FLINT_DEFINE_CBINARY_EXPR_COND2(divided_by, fmpz_poly_qxx, + FMPZ_POLY_QXX_COND_S, FMPQXX_COND_S, + to.numref() = e1.numref()*e2.den();to.denref() = e1.denref()*e2.num(); + to.canonicalise()) +#endif +} // rules +// NB: addmul is not actually optimised currently +} // flint + +#endif diff --git a/external/flint-2.4.3/fmpz_polyxx.h b/external/flint-2.4.3/fmpz_polyxx.h new file mode 100644 index 0000000..fe49dd4 --- /dev/null +++ b/external/flint-2.4.3/fmpz_polyxx.h @@ -0,0 +1,962 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#ifndef FMPZ_POLYXX_H +#define FMPZ_POLYXX_H + +#include +#include + +#include "flint.h" +#include "fmpz_poly.h" + +#include "fmpzxx.h" +#include "fmpz_vecxx.h" + +#include "flintxx/expression.h" +#include "flintxx/flint_classes.h" +#include "flintxx/flint_exception.h" +#include "flintxx/frandxx.h" +#include "flintxx/ltuple.h" +#include "flintxx/traits.h" +#include "flintxx/traits_fwd.h" + +// TODO exhibit this as a specialisation of a generic poly +// TODO newton basis? +// TODO power series class? +// TODO input +// TODO addmul +// TODO more hensel lifting? + +namespace flint { +// function "declarations" +FLINT_DEFINE_UNOP(sqr_karatsuba) +FLINT_DEFINE_UNOP(sqrt_classical) + +FLINT_DEFINE_BINOP(evaluate_divconquer) +FLINT_DEFINE_BINOP(evaluate_horner) +FLINT_DEFINE_BINOP(gcd_heuristic) +FLINT_DEFINE_BINOP(gcd_modular) +FLINT_DEFINE_BINOP(gcd_subresultant) +FLINT_DEFINE_BINOP(mul_karatsuba) +FLINT_DEFINE_BINOP(mulmid_classical) +FLINT_DEFINE_BINOP(mul_SS) +FLINT_DEFINE_BINOP(divides) +FLINT_DEFINE_BINOP(pow_addchains) +FLINT_DEFINE_BINOP(pow_binomial) +FLINT_DEFINE_BINOP(pow_multinomial) +FLINT_DEFINE_BINOP(pseudo_div) +FLINT_DEFINE_BINOP(pseudo_divrem) +FLINT_DEFINE_BINOP(pseudo_divrem_basecase) +FLINT_DEFINE_BINOP(pseudo_divrem_cohen) +FLINT_DEFINE_BINOP(pseudo_divrem_divconquer) +FLINT_DEFINE_BINOP(pseudo_rem) +FLINT_DEFINE_BINOP(pseudo_rem_cohen) +FLINT_DEFINE_BINOP(sqrlow) +FLINT_DEFINE_BINOP(sqrlow_classical) +FLINT_DEFINE_BINOP(sqrlow_karatsuba_n) +FLINT_DEFINE_BINOP(sqrlow_KS) +FLINT_DEFINE_BINOP(taylor_shift_divconquer) +FLINT_DEFINE_BINOP(xgcd_modular) + +FLINT_DEFINE_THREEARY(mulhigh_karatsuba_n) +FLINT_DEFINE_THREEARY(mulhigh_n) +FLINT_DEFINE_THREEARY(mullow_karatsuba_n) +FLINT_DEFINE_THREEARY(mullow_SS) + + +FLINT_DEFINE_BINOP(fmpz_polyxx_interpolate) +FLINT_DEFINE_UNOP(fmpz_polyxx_product_roots) +FLINT_DEFINE_UNOP(fmpz_polyxx_lead) +FLINT_DEFINE_BINOP(fmpz_polyxx_get_coeff) +FLINT_DEFINE_BINOP(fmpz_polyxx_bit_unpack) +FLINT_DEFINE_BINOP(fmpz_polyxx_bit_unpack_unsigned) + +FLINT_DEFINE_SEVENARY(hensel_lift) +FLINT_DEFINE_SEVENARY(hensel_lift_without_inverse) +FLINT_DEFINE_SIXARY(hensel_lift_only_inverse) + + +namespace detail { +template +struct fmpz_poly_traits +{ + typedef FLINT_UNOP_BUILD_RETTYPE( + fmpz_polyxx_lead, fmpzxx, Poly) lead_ref_t; + typedef lead_ref_t lead_srcref_t; + static lead_ref_t lead(const Poly& p) {return fmpz_polyxx_lead(p);} + + template + struct coeff + { + typedef FLINT_BINOP_ENABLE_RETTYPE(fmpz_polyxx_get_coeff, Poly, T) ref_t; + typedef ref_t srcref_t; + static ref_t get(const Poly& p, const T& t) + {return fmpz_polyxx_get_coeff(p, t);} + }; +}; +} + +template +class fmpz_polyxx_expression + : public expression, + Operation, Data> +{ +public: + typedef expression, + Operation, Data> base_t; + typedef detail::fmpz_poly_traits poly_traits_t; + + FLINTXX_DEFINE_BASICS(fmpz_polyxx_expression) + FLINTXX_DEFINE_CTORS(fmpz_polyxx_expression) + FLINTXX_DEFINE_C_REF(fmpz_polyxx_expression, fmpz_poly_struct, _poly) + + // static methods which only make sense with fmpz_polyxx + static fmpz_polyxx_expression randtest(frandxx& state, slong len, + mp_bitcnt_t bits) + { + fmpz_polyxx_expression res; + fmpz_poly_randtest(res._poly(), state._data(), len, bits); + return res; + } + static fmpz_polyxx_expression randtest_unsigned(frandxx& state, slong len, + mp_bitcnt_t bits) + { + fmpz_polyxx_expression res; + fmpz_poly_randtest_unsigned(res._poly(), state._data(), len, bits); + return res; + } + static fmpz_polyxx_expression randtest_not_zero(frandxx& state, slong len, + mp_bitcnt_t bits) + { + fmpz_polyxx_expression res; + fmpz_poly_randtest_not_zero(res._poly(), state._data(), len, bits); + return res; + } + + template + static FLINT_BINOP_ENABLE_RETTYPE(fmpz_polyxx_interpolate, + Fmpz_vec1, Fmpz_vec2) + interpolate(const Fmpz_vec1& xs, const Fmpz_vec2& ys) + { + return fmpz_polyxx_interpolate(xs, ys); + } + + template + static FLINT_UNOP_ENABLE_RETTYPE(fmpz_polyxx_product_roots, Fmpz_vec) + product_roots(const Fmpz_vec& xs) + { + return fmpz_polyxx_product_roots(xs); + } + + template + static FLINT_BINOP_ENABLE_RETTYPE(fmpz_polyxx_bit_unpack, + Arg1, Arg2) + bit_unpack(const Arg1& a1, const Arg2& a2) + { + return fmpz_polyxx_bit_unpack(a1, a2); + } + template + static FLINT_BINOP_ENABLE_RETTYPE(fmpz_polyxx_bit_unpack_unsigned, + Arg1, Arg2) + bit_unpack_unsigned(const Arg1& a1, const Arg2& a2) + { + return fmpz_polyxx_bit_unpack_unsigned(a1, a2); + } + + template + static fmpz_polyxx_expression from_ground(const T& t) + { + fmpz_polyxx_expression res; + fmpzxx u; u = t; + res.set_coeff(0, u); + return res; + } + + template + static fmpz_polyxx_expression _lift(const Nmod_poly& poly) + { + fmpz_polyxx_expression res(poly.length()); + fmpz_poly_set_nmod_poly(res._poly(), poly._poly()); + return res; + } + template + static fmpz_polyxx_expression lift(const Nmod_poly& poly, + typename mp::enable_if >::type* = 0) + { + return _lift(poly.evaluate()); + } + template + static fmpz_polyxx_expression _lift_unsigned(const Nmod_poly& poly) + { + fmpz_polyxx_expression res(poly.length()); + fmpz_poly_set_nmod_poly_unsigned(res._poly(), poly.evaluate()._poly()); + return res; + } + template + static fmpz_polyxx_expression lift_unsigned(const Nmod_poly& poly, + typename mp::enable_if >::type* = 0) + { + return _lift_unsigned(poly.evaluate()); + } + + static fmpz_polyxx_expression zero() {return fmpz_polyxx_expression();} + static fmpz_polyxx_expression one() + { + fmpz_polyxx_expression res; + res.set_one(); + return res; + } + + // These only make sense with immediates + void realloc(slong alloc) {fmpz_poly_realloc(_poly(), alloc);} + void fit_length(slong len) {fmpz_poly_fit_length(_poly(), len);} + void _normalise() {_fmpz_poly_normalise(_poly());} + void _set_length(slong len) {_fmpz_poly_set_length(_poly(), len);} + void zero_coeffs(slong i, slong j) {fmpz_poly_zero_coeffs(_poly(), i, j);} + void set_zero() {fmpz_poly_zero(_poly());} + void set_one() {fmpz_poly_one(_poly());} + + // The result of these are undefined if n is >= length + // You also may have to call _normalise(). + template + typename poly_traits_t::template coeff::ref_t coeff(const T& n) + { + return poly_traits_t::template coeff::get(*this, n); + } + template + typename poly_traits_t::template coeff::srcref_t + coeff(const T& n) const + { + return poly_traits_t::template coeff::get(*this, n); + } + typename poly_traits_t::lead_ref_t lead() + { + return poly_traits_t::lead(*this); + } + typename poly_traits_t::lead_srcref_t lead() const + { + return poly_traits_t::lead(*this); + } + + // These only make sense with target immediates + template + typename mp::enable_if >::type + set_coeff(slong n, const Fmpz& x) + { + fmpz_poly_set_coeff_fmpz(_poly(), n, x.evaluate()._fmpz()); + } + template + typename mp::enable_if >::type + set_coeff(slong n, T x) + { + fmpz_poly_set_coeff_si(_poly(), n, x); + } + template + typename mp::enable_if >::type + set_coeff(slong n, T x) + { + fmpz_poly_set_coeff_ui(_poly(), n, x); + } + + void truncate(slong n) {fmpz_poly_truncate(_poly(), n);} + + // These cause evaluation + slong length() const {return fmpz_poly_length(this->evaluate()._poly());} + slong degree() const {return fmpz_poly_degree(this->evaluate()._poly());} + bool is_one() const {return fmpz_poly_is_one(this->evaluate()._poly());} + bool is_zero() const {return fmpz_poly_is_zero(this->evaluate()._poly());} + bool is_unit() const {return fmpz_poly_is_unit(this->evaluate()._poly());} + ulong max_limbs() const {return fmpz_poly_max_limbs(this->evaluate()._poly());} + slong max_bits() const {return fmpz_poly_max_bits(this->evaluate()._poly());} + + std::string pretty(const char* x) const + { + char* str = fmpz_poly_get_str_pretty(this->evaluate()._poly(), x); + std::string res(str); + flint_free(str); + return res; + } + + void signature(slong& r1, slong& r2) const + { + fmpz_poly_signature(&r1, &r2, this->evaluate()._poly()); + } + + int read_pretty(char** x, FILE* f = stdin) + { + return fmpz_poly_fread_pretty(f, _poly(), x); + } + + // lazy member forwarding + FLINTXX_DEFINE_MEMBER_BINOP_(operator(), compeval) + FLINTXX_DEFINE_MEMBER_BINOP_(get_coeff, fmpz_polyxx_get_coeff) + + FLINTXX_DEFINE_MEMBER_BINOP(bit_pack) + FLINTXX_DEFINE_MEMBER_BINOP(compose_divconquer) + FLINTXX_DEFINE_MEMBER_BINOP(compose_horner) + FLINTXX_DEFINE_MEMBER_BINOP(div_basecase) + FLINTXX_DEFINE_MEMBER_BINOP(div_divconquer) + FLINTXX_DEFINE_MEMBER_BINOP(divexact) + FLINTXX_DEFINE_MEMBER_BINOP(divides) + FLINTXX_DEFINE_MEMBER_BINOP(divrem) + FLINTXX_DEFINE_MEMBER_BINOP(divrem_basecase) + FLINTXX_DEFINE_MEMBER_BINOP(divrem_divconquer) + FLINTXX_DEFINE_MEMBER_BINOP(div_root) + FLINTXX_DEFINE_MEMBER_BINOP(evaluate_divconquer) + FLINTXX_DEFINE_MEMBER_BINOP(evaluate_horner) + FLINTXX_DEFINE_MEMBER_BINOP(fdiv_2exp) + FLINTXX_DEFINE_MEMBER_BINOP(gcd) + FLINTXX_DEFINE_MEMBER_BINOP(gcd_heuristic) + FLINTXX_DEFINE_MEMBER_BINOP(gcd_modular) + FLINTXX_DEFINE_MEMBER_BINOP(gcd_subresultant) + FLINTXX_DEFINE_MEMBER_BINOP(inv_series) + FLINTXX_DEFINE_MEMBER_BINOP(inv_series_newton) + FLINTXX_DEFINE_MEMBER_BINOP(lcm) + FLINTXX_DEFINE_MEMBER_BINOP(mul_2exp) + FLINTXX_DEFINE_MEMBER_BINOP(mul_classical) + FLINTXX_DEFINE_MEMBER_BINOP(mul_karatsuba) + FLINTXX_DEFINE_MEMBER_BINOP(mul_KS) + FLINTXX_DEFINE_MEMBER_BINOP(mulmid_classical) + FLINTXX_DEFINE_MEMBER_BINOP(mul_SS) + FLINTXX_DEFINE_MEMBER_BINOP(shift_left) + FLINTXX_DEFINE_MEMBER_BINOP(shift_right) + FLINTXX_DEFINE_MEMBER_BINOP(pow) + FLINTXX_DEFINE_MEMBER_BINOP(pow_addchains) + FLINTXX_DEFINE_MEMBER_BINOP(pow_binexp) + FLINTXX_DEFINE_MEMBER_BINOP(pow_binomial) + FLINTXX_DEFINE_MEMBER_BINOP(pow_multinomial) + FLINTXX_DEFINE_MEMBER_BINOP(pseudo_div) + FLINTXX_DEFINE_MEMBER_BINOP(pseudo_divrem) + FLINTXX_DEFINE_MEMBER_BINOP(pseudo_divrem_basecase) + FLINTXX_DEFINE_MEMBER_BINOP(pseudo_divrem_cohen) + FLINTXX_DEFINE_MEMBER_BINOP(pseudo_divrem_divconquer) + FLINTXX_DEFINE_MEMBER_BINOP(pseudo_rem) + FLINTXX_DEFINE_MEMBER_BINOP(pseudo_rem_cohen) + FLINTXX_DEFINE_MEMBER_BINOP(resultant) + FLINTXX_DEFINE_MEMBER_BINOP(reverse) + FLINTXX_DEFINE_MEMBER_BINOP(revert_series) + FLINTXX_DEFINE_MEMBER_BINOP(revert_series_lagrange) + FLINTXX_DEFINE_MEMBER_BINOP(revert_series_lagrange_fast) + FLINTXX_DEFINE_MEMBER_BINOP(revert_series_newton) + FLINTXX_DEFINE_MEMBER_BINOP(smod) + FLINTXX_DEFINE_MEMBER_BINOP(sqrlow) + FLINTXX_DEFINE_MEMBER_BINOP(sqrlow_classical) + FLINTXX_DEFINE_MEMBER_BINOP(sqrlow_karatsuba_n) + FLINTXX_DEFINE_MEMBER_BINOP(sqrlow_KS) + FLINTXX_DEFINE_MEMBER_BINOP(taylor_shift) + FLINTXX_DEFINE_MEMBER_BINOP(taylor_shift_divconquer) + FLINTXX_DEFINE_MEMBER_BINOP(taylor_shift_horner) + FLINTXX_DEFINE_MEMBER_BINOP(tdiv) + FLINTXX_DEFINE_MEMBER_BINOP(tdiv_2exp) + FLINTXX_DEFINE_MEMBER_BINOP(xgcd) + FLINTXX_DEFINE_MEMBER_BINOP(xgcd_modular) + + FLINTXX_DEFINE_MEMBER_UNOP(derivative) + FLINTXX_DEFINE_MEMBER_UNOP(primitive_part) + FLINTXX_DEFINE_MEMBER_UNOP(sqr) + FLINTXX_DEFINE_MEMBER_UNOP(sqr_classical) + FLINTXX_DEFINE_MEMBER_UNOP(sqr_karatsuba) + FLINTXX_DEFINE_MEMBER_UNOP(sqr_KS) + FLINTXX_DEFINE_MEMBER_UNOP(sqrt) + FLINTXX_DEFINE_MEMBER_UNOP(sqrt_classical) + + FLINTXX_DEFINE_MEMBER_UNOP_RTYPE(fmpzxx, bound_roots) + FLINTXX_DEFINE_MEMBER_UNOP_RTYPE(fmpzxx, twonorm) + + FLINTXX_DEFINE_MEMBER_UNOP_RTYPE(fmpzxx, content) + FLINTXX_DEFINE_MEMBER_UNOP_RTYPE(fmpzxx, height) + + FLINTXX_DEFINE_MEMBER_3OP(compose_series) + FLINTXX_DEFINE_MEMBER_3OP(compose_series_brent_kung) + FLINTXX_DEFINE_MEMBER_3OP(compose_series_horner) + FLINTXX_DEFINE_MEMBER_3OP(div_series) + FLINTXX_DEFINE_MEMBER_3OP(mulhigh_classical) + FLINTXX_DEFINE_MEMBER_3OP(mulhigh_karatsuba_n) + FLINTXX_DEFINE_MEMBER_3OP(mulhigh_n) + FLINTXX_DEFINE_MEMBER_3OP(mullow) + FLINTXX_DEFINE_MEMBER_3OP(mullow_classical) + FLINTXX_DEFINE_MEMBER_3OP(mullow_karatsuba_n) + FLINTXX_DEFINE_MEMBER_3OP(mullow_KS) + FLINTXX_DEFINE_MEMBER_3OP(mullow_SS) + FLINTXX_DEFINE_MEMBER_3OP(pow_trunc) + + FLINTXX_DEFINE_MEMBER_4OP(CRT) +}; + +namespace detail { +struct fmpz_poly_data; +} + +typedef fmpz_polyxx_expression + fmpz_polyxx; +typedef fmpz_polyxx_expression > + fmpz_polyxx_ref; +typedef fmpz_polyxx_expression > + fmpz_polyxx_srcref; + +namespace detail { +template<> +struct fmpz_poly_traits +{ + typedef fmpzxx_srcref lead_srcref_t; + typedef fmpzxx_srcref lead_ref_t; + + template + static lead_srcref_t lead(const P& p) + {return lead_srcref_t::make(fmpz_poly_lead(p._poly()));} + + template + struct coeff + { + typedef typename mp::enable_if< + traits::is_integer, fmpzxx_srcref>::type ref_t; + typedef ref_t srcref_t; + + template + static srcref_t get(const P& p, const T& n) + {return srcref_t::make(fmpz_poly_coeff_ptr(p._poly(), n));} + }; +}; +template<> +struct fmpz_poly_traits +{ + typedef fmpzxx_ref lead_ref_t; + typedef fmpzxx_ref lead_srcref_t; + + template + static lead_ref_t lead(P p) + {return lead_ref_t::make(fmpz_poly_lead(p._poly()));} + + template + struct coeff + { + typedef fmpzxx_ref ref_t; + typedef fmpzxx_ref srcref_t; + + template + static ref_t get(P p, const T& n) + {return ref_t::make(fmpz_poly_get_coeff_ptr(p._poly(), n));} + }; +}; +template<> +struct fmpz_poly_traits +{ + typedef fmpzxx_ref lead_ref_t; + typedef fmpzxx_srcref lead_srcref_t; + + template + static lead_ref_t lead(P& p) + {return lead_ref_t::make(fmpz_poly_lead(p._poly()));} + template + static lead_srcref_t lead(const P& p) + {return lead_srcref_t::make(fmpz_poly_lead(p._poly()));} + + template + struct coeff + { + typedef fmpzxx_ref ref_t; + typedef fmpzxx_srcref srcref_t; + + template + static ref_t get(P& p, const T& n) + {return ref_t::make(fmpz_poly_get_coeff_ptr(p._poly(), n));} + template + static srcref_t get(const P& p, const T& n) + {return srcref_t::make(fmpz_poly_get_coeff_ptr(p._poly(), n));} + }; +}; + +struct fmpz_poly_data +{ + fmpz_poly_t inner; + typedef fmpz_poly_t& data_ref_t; + typedef const fmpz_poly_t& data_srcref_t; + + fmpz_poly_data() {fmpz_poly_init(inner);} + ~fmpz_poly_data() {fmpz_poly_clear(inner);} + + fmpz_poly_data(const fmpz_poly_data& o) + { + fmpz_poly_init(inner); + fmpz_poly_set(inner, o.inner); + } + + fmpz_poly_data(fmpz_polyxx_srcref r) + { + fmpz_poly_init(inner); + fmpz_poly_set(inner, r._poly()); + } + + fmpz_poly_data(slong alloc) + { + fmpz_poly_init2(inner, alloc); + } + + fmpz_poly_data(const char* str) + { + fmpz_poly_init(inner); + execution_check(!fmpz_poly_set_str(inner, str), + "construct from string", "fmpz_polyxx"); + } +}; +} // detail + +namespace traits { +template struct is_fmpz_polyxx : mp::or_< + traits::is_T_expr, + flint_classes::is_source > { }; +} // traits +namespace mp { +template +struct all_fmpz_polyxx : mp::and_, all_fmpz_polyxx > { }; +template +struct all_fmpz_polyxx : traits::is_fmpz_polyxx { }; + +template +struct enable_all_fmpz_polyxx + : mp::enable_if, Out> { }; +} // mp + +namespace rules { +#define FMPZ_POLYXX_COND_S FLINTXX_COND_S(fmpz_polyxx) +#define FMPZ_POLYXX_COND_T FLINTXX_COND_T(fmpz_polyxx) + +FLINTXX_DEFINE_EQUALS(fmpz_polyxx, fmpz_poly_equal(e1._poly(), e2._poly())) + +FLINT_DEFINE_DOIT_COND2(assignment, FMPZ_POLYXX_COND_T, FMPZ_POLYXX_COND_S, + fmpz_poly_set(to._poly(), from._poly())) +FLINT_DEFINE_DOIT_COND2(assignment, FMPZ_POLYXX_COND_T, + traits::is_signed_integer, + fmpz_poly_set_si(to._poly(), from)) +FLINT_DEFINE_DOIT_COND2(assignment, FMPZ_POLYXX_COND_T, + traits::is_unsigned_integer, + fmpz_poly_set_ui(to._poly(), from)) +FLINT_DEFINE_DOIT_COND2(assignment, FMPZ_POLYXX_COND_T, FMPZXX_COND_S, + fmpz_poly_set_fmpz(to._poly(), from._fmpz())) +FLINTXX_DEFINE_ASSIGN_STR(fmpz_polyxx, execution_check( + !fmpz_poly_set_str(to._poly(), from), "assign string", "fmpz_polyxx")) + +FLINT_DEFINE_PRINT_COND(FMPZ_POLYXX_COND_S, fmpz_poly_fprint(to, from._poly())) +FLINT_DEFINE_PRINT_PRETTY_COND_2(FMPZ_POLYXX_COND_S, const char*, + fmpz_poly_fprint_pretty(to, from._poly(), extra)) +FLINT_DEFINE_READ_COND(FMPZ_POLYXX_COND_T, fmpz_poly_fread(from, to._poly())) + +FLINTXX_DEFINE_TO_STR(fmpz_polyxx, fmpz_poly_get_str(from._poly())) +FLINTXX_DEFINE_SWAP(fmpz_polyxx, fmpz_poly_swap(e1._poly(), e2._poly())) + +FLINT_DEFINE_BINARY_EXPR_COND2(reverse_op, fmpz_polyxx, + FMPZ_POLYXX_COND_S, traits::fits_into_slong, + fmpz_poly_reverse(to._poly(), e1._poly(), e2)) + +FLINT_DEFINE_BINARY_EXPR_COND2(plus, fmpz_polyxx, + FMPZ_POLYXX_COND_S, FMPZ_POLYXX_COND_S, + fmpz_poly_add(to._poly(), e1._poly(), e2._poly())) +FLINT_DEFINE_BINARY_EXPR_COND2(minus, fmpz_polyxx, + FMPZ_POLYXX_COND_S, FMPZ_POLYXX_COND_S, + fmpz_poly_sub(to._poly(), e1._poly(), e2._poly())) + +FLINT_DEFINE_UNARY_EXPR_COND(negate, fmpz_polyxx, FMPZ_POLYXX_COND_S, + fmpz_poly_neg(to._poly(), from._poly())) + +FLINT_DEFINE_CBINARY_EXPR_COND2(times, fmpz_polyxx, + FMPZ_POLYXX_COND_S, FMPZXX_COND_S, + fmpz_poly_scalar_mul_fmpz(to._poly(), e1._poly(), e2._fmpz())) +FLINT_DEFINE_CBINARY_EXPR_COND2(times, fmpz_polyxx, + FMPZ_POLYXX_COND_S, traits::is_signed_integer, + fmpz_poly_scalar_mul_si(to._poly(), e1._poly(), e2)) +FLINT_DEFINE_CBINARY_EXPR_COND2(times, fmpz_polyxx, + FMPZ_POLYXX_COND_S, traits::is_unsigned_integer, + fmpz_poly_scalar_mul_ui(to._poly(), e1._poly(), e2)) + +FLINT_DEFINE_CBINARY_EXPR_COND2(mul_2exp_op, fmpz_polyxx, + FMPZ_POLYXX_COND_S, traits::is_unsigned_integer, + fmpz_poly_scalar_mul_2exp(to._poly(), e1._poly(), e2)) + +FLINT_DEFINE_CBINARY_EXPR_COND2(divided_by, fmpz_polyxx, + FMPZ_POLYXX_COND_S, FMPZXX_COND_S, + fmpz_poly_scalar_fdiv_fmpz(to._poly(), e1._poly(), e2._fmpz())) +FLINT_DEFINE_BINARY_EXPR_COND2(divided_by, fmpz_polyxx, + FMPZ_POLYXX_COND_S, traits::is_unsigned_integer, + fmpz_poly_scalar_fdiv_ui(to._poly(), e1._poly(), e2)) +FLINT_DEFINE_BINARY_EXPR_COND2(divided_by, fmpz_polyxx, + FMPZ_POLYXX_COND_S, traits::is_signed_integer, + fmpz_poly_scalar_fdiv_si(to._poly(), e1._poly(), e2)) + +FLINT_DEFINE_CBINARY_EXPR_COND2(fdiv_2exp_op, fmpz_polyxx, + FMPZ_POLYXX_COND_S, traits::is_unsigned_integer, + fmpz_poly_scalar_fdiv_2exp(to._poly(), e1._poly(), e2)) + +#define FMPZ_POLYXX_DEFINE_SCALAR_DIVFUNCS(name) \ +FLINT_DEFINE_CBINARY_EXPR_COND2(name##_op, fmpz_polyxx, \ + FMPZ_POLYXX_COND_S, FMPZXX_COND_S, \ + fmpz_poly_scalar_##name##_fmpz(to._poly(), e1._poly(), e2._fmpz())) \ +FLINT_DEFINE_BINARY_EXPR_COND2(name##_op, fmpz_polyxx, \ + FMPZ_POLYXX_COND_S, traits::is_unsigned_integer, \ + fmpz_poly_scalar_##name##_ui(to._poly(), e1._poly(), e2)) \ +FLINT_DEFINE_BINARY_EXPR_COND2(name##_op, fmpz_polyxx, \ + FMPZ_POLYXX_COND_S, traits::is_signed_integer, \ + fmpz_poly_scalar_##name##_si(to._poly(), e1._poly(), e2)) +FMPZ_POLYXX_DEFINE_SCALAR_DIVFUNCS(tdiv) +FMPZ_POLYXX_DEFINE_SCALAR_DIVFUNCS(divexact) + +FLINT_DEFINE_CBINARY_EXPR_COND2(tdiv_2exp_op, fmpz_polyxx, + FMPZ_POLYXX_COND_S, traits::is_unsigned_integer, + fmpz_poly_scalar_tdiv_2exp(to._poly(), e1._poly(), e2)) + +FLINT_DEFINE_BINARY_EXPR_COND2(modulo, fmpz_polyxx, + FMPZ_POLYXX_COND_S, FMPZXX_COND_S, + fmpz_poly_scalar_mod_fmpz(to._poly(), e1._poly(), e2._fmpz())) + +FLINT_DEFINE_BINARY_EXPR_COND2(smod_op, fmpz_polyxx, + FMPZ_POLYXX_COND_S, FMPZXX_COND_S, + fmpz_poly_scalar_smod_fmpz(to._poly(), e1._poly(), e2._fmpz())) + +FLINT_DEFINE_BINARY_EXPR_COND2(bit_pack_op, fmpzxx, + FMPZ_POLYXX_COND_S, traits::fits_into_mp_bitcnt_t, + fmpz_poly_bit_pack(to._fmpz(), e1._poly(), e2)) + +FLINT_DEFINE_BINARY_EXPR_COND2(fmpz_polyxx_bit_unpack_op, fmpz_polyxx, + FMPZXX_COND_S, traits::fits_into_mp_bitcnt_t, + fmpz_poly_bit_unpack(to._poly(), e1._fmpz(), e2)) + +FLINT_DEFINE_BINARY_EXPR_COND2(fmpz_polyxx_bit_unpack_unsigned_op, fmpz_polyxx, + FMPZXX_COND_S, traits::fits_into_mp_bitcnt_t, + fmpz_poly_bit_unpack_unsigned(to._poly(), e1._fmpz(), e2)) + +FLINT_DEFINE_BINARY_EXPR_COND2(times, fmpz_polyxx, + FMPZ_POLYXX_COND_S, FMPZ_POLYXX_COND_S, + fmpz_poly_mul(to._poly(), e1._poly(), e2._poly())) + +#define FMPZ_POLYXX_DEFINE_MUL(name) \ +FLINT_DEFINE_BINARY_EXPR_COND2(name##_op, fmpz_polyxx, \ + FMPZ_POLYXX_COND_S, FMPZ_POLYXX_COND_S, \ + fmpz_poly_##name(to._poly(), e1._poly(), e2._poly())) +FMPZ_POLYXX_DEFINE_MUL(mul_classical) +FMPZ_POLYXX_DEFINE_MUL(mulmid_classical) +FMPZ_POLYXX_DEFINE_MUL(mul_karatsuba) +FMPZ_POLYXX_DEFINE_MUL(mul_SS) +FMPZ_POLYXX_DEFINE_MUL(mul_KS) + +FLINT_DEFINE_UNARY_EXPR_COND(sqr_KS_op, fmpz_polyxx, FMPZ_POLYXX_COND_S, + fmpz_poly_sqr_KS(to._poly(), from._poly())) +FLINT_DEFINE_UNARY_EXPR_COND(sqr_karatsuba_op, fmpz_polyxx, FMPZ_POLYXX_COND_S, + fmpz_poly_sqr_karatsuba(to._poly(), from._poly())) +FLINT_DEFINE_UNARY_EXPR_COND(sqr_classical_op, fmpz_polyxx, FMPZ_POLYXX_COND_S, + fmpz_poly_sqr_classical(to._poly(), from._poly())) +FLINT_DEFINE_UNARY_EXPR_COND(sqr_op, fmpz_polyxx, FMPZ_POLYXX_COND_S, + fmpz_poly_sqr(to._poly(), from._poly())) + +#define FMPZ_POLYXX_DEFINE_SQRLOW(name) \ +FLINT_DEFINE_BINARY_EXPR_COND2(name##_op, fmpz_polyxx, \ + FMPZ_POLYXX_COND_S, traits::fits_into_slong, \ + fmpz_poly_##name(to._poly(), e1._poly(), e2)) +FMPZ_POLYXX_DEFINE_SQRLOW(sqrlow_KS) +FMPZ_POLYXX_DEFINE_SQRLOW(sqrlow_karatsuba_n) +FMPZ_POLYXX_DEFINE_SQRLOW(sqrlow_classical) +FMPZ_POLYXX_DEFINE_SQRLOW(sqrlow) + +#define FMPZ_POLYXX_DEFINE_POW(name) \ +FLINT_DEFINE_BINARY_EXPR_COND2(name##_op, fmpz_polyxx, \ + FMPZ_POLYXX_COND_S, traits::is_unsigned_integer, \ + fmpz_poly_##name(to._poly(), e1._poly(), e2)) +FMPZ_POLYXX_DEFINE_POW(pow_multinomial) +FMPZ_POLYXX_DEFINE_POW(pow_binomial) +FMPZ_POLYXX_DEFINE_POW(pow_addchains) +FMPZ_POLYXX_DEFINE_POW(pow_binexp) +FMPZ_POLYXX_DEFINE_POW(pow) + +FLINT_DEFINE_BINARY_EXPR_COND2(shift_left_op, fmpz_polyxx, + FMPZ_POLYXX_COND_S, traits::fits_into_slong, + fmpz_poly_shift_left(to._poly(), e1._poly(), e2)) +FLINT_DEFINE_BINARY_EXPR_COND2(shift_right_op, fmpz_polyxx, + FMPZ_POLYXX_COND_S, traits::fits_into_slong, + fmpz_poly_shift_right(to._poly(), e1._poly(), e2)) + +FLINT_DEFINE_UNARY_EXPR_COND(height_op, fmpzxx, FMPZ_POLYXX_COND_S, + fmpz_poly_height(to._fmpz(), from._poly())) +FLINT_DEFINE_UNARY_EXPR_COND(twonorm_op, fmpzxx, FMPZ_POLYXX_COND_S, + fmpz_poly_2norm(to._fmpz(), from._poly())) + +FMPZ_POLYXX_DEFINE_MUL(gcd) +FMPZ_POLYXX_DEFINE_MUL(gcd_subresultant) +FMPZ_POLYXX_DEFINE_MUL(gcd_heuristic) +FMPZ_POLYXX_DEFINE_MUL(gcd_modular) +FMPZ_POLYXX_DEFINE_MUL(lcm) + +FLINT_DEFINE_BINARY_EXPR_COND2(resultant_op, fmpzxx, + FMPZ_POLYXX_COND_S, FMPZ_POLYXX_COND_S, + fmpz_poly_resultant(to._fmpz(), e1._poly(), e2._poly())) + +FLINT_DEFINE_UNARY_EXPR_COND(content_op, fmpzxx, FMPZ_POLYXX_COND_S, + fmpz_poly_content(to._fmpz(), from._poly())) +FLINT_DEFINE_UNARY_EXPR_COND(primitive_part_op, fmpz_polyxx, FMPZ_POLYXX_COND_S, + fmpz_poly_primitive_part(to._poly(), from._poly())) + +FLINT_DEFINE_BINARY_EXPR_COND2(div_basecase_op, fmpz_polyxx, + FMPZ_POLYXX_COND_S, FMPZ_POLYXX_COND_S, + fmpz_poly_div_basecase(to._poly(), e1._poly(), e2._poly())) +FLINT_DEFINE_BINARY_EXPR_COND2(div_divconquer_op, fmpz_polyxx, + FMPZ_POLYXX_COND_S, FMPZ_POLYXX_COND_S, + fmpz_poly_div_divconquer(to._poly(), e1._poly(), e2._poly())) + +FLINT_DEFINE_BINARY_EXPR_COND2(divided_by, fmpz_polyxx, + FMPZ_POLYXX_COND_S, FMPZ_POLYXX_COND_S, + fmpz_poly_div(to._poly(), e1._poly(), e2._poly())) + +FLINT_DEFINE_BINARY_EXPR_COND2(rem_basecase_op, fmpz_polyxx, + FMPZ_POLYXX_COND_S, FMPZ_POLYXX_COND_S, + fmpz_poly_rem_basecase(to._poly(), e1._poly(), e2._poly())) +FLINT_DEFINE_BINARY_EXPR_COND2(modulo, fmpz_polyxx, + FMPZ_POLYXX_COND_S, FMPZ_POLYXX_COND_S, + fmpz_poly_rem(to._poly(), e1._poly(), e2._poly())) + +FLINT_DEFINE_BINARY_EXPR_COND2(div_root_op, fmpz_polyxx, + FMPZ_POLYXX_COND_S, FMPZXX_COND_S, + fmpz_poly_div_root(to._poly(), e1._poly(), e2._fmpz())) + +FLINT_DEFINE_BINARY_EXPR_COND2(inv_series_newton_op, fmpz_polyxx, + FMPZ_POLYXX_COND_S, traits::fits_into_slong, + fmpz_poly_inv_series_newton(to._poly(), e1._poly(), e2)) +FLINT_DEFINE_BINARY_EXPR_COND2(inv_series_op, fmpz_polyxx, + FMPZ_POLYXX_COND_S, traits::fits_into_slong, + fmpz_poly_inv_series(to._poly(), e1._poly(), e2)) + +FLINT_DEFINE_BINARY_EXPR_COND2(pseudo_rem_cohen_op, fmpz_polyxx, + FMPZ_POLYXX_COND_S, FMPZ_POLYXX_COND_S, + fmpz_poly_pseudo_rem_cohen(to._poly(), e1._poly(), e2._poly())) + +FLINT_DEFINE_UNARY_EXPR_COND(derivative_op, fmpz_polyxx, FMPZ_POLYXX_COND_S, + fmpz_poly_derivative(to._poly(), from._poly())) + +FMPZ_POLYXX_DEFINE_MUL(compose) +FMPZ_POLYXX_DEFINE_MUL(compose_horner) +FMPZ_POLYXX_DEFINE_MUL(compose_divconquer) + +FLINT_DEFINE_BINARY_EXPR_COND2(evaluate_op, fmpzxx, + FMPZ_POLYXX_COND_S, FMPZXX_COND_S, + fmpz_poly_evaluate_fmpz(to._fmpz(), e1._poly(), e2._fmpz())) +FLINT_DEFINE_BINARY_EXPR_COND2(evaluate_divconquer_op, fmpzxx, + FMPZ_POLYXX_COND_S, FMPZXX_COND_S, + fmpz_poly_evaluate_divconquer_fmpz(to._fmpz(), e1._poly(), e2._fmpz())) +FLINT_DEFINE_BINARY_EXPR_COND2(evaluate_horner_op, fmpzxx, + FMPZ_POLYXX_COND_S, FMPZXX_COND_S, + fmpz_poly_evaluate_horner_fmpz(to._fmpz(), e1._poly(), e2._fmpz())) +FLINT_DEFINE_BINARY_EXPR_COND2(evaluate_op, fmpz_vecxx, + FMPZ_POLYXX_COND_S, FMPZ_VECXX_COND_S, + fmpz_poly_evaluate_fmpz_vec(to._data().array, e1._poly(), + e2._data().array, e2.size())) + +FLINT_DEFINE_BINARY_EXPR_COND2(fmpz_polyxx_interpolate_op, fmpz_polyxx, + FMPZ_VECXX_COND_S, FMPZ_VECXX_COND_S, + fmpz_poly_interpolate_fmpz_vec(to._poly(), e1._data().array, + e2._data().array, e2.size())) + +FLINT_DEFINE_BINARY_EXPR_COND2(taylor_shift_horner_op, fmpz_polyxx, + FMPZ_POLYXX_COND_S, FMPZXX_COND_S, + fmpz_poly_taylor_shift_horner(to._poly(), e1._poly(), e2._fmpz())) +FLINT_DEFINE_BINARY_EXPR_COND2(taylor_shift_divconquer_op, fmpz_polyxx, + FMPZ_POLYXX_COND_S, FMPZXX_COND_S, + fmpz_poly_taylor_shift_divconquer(to._poly(), e1._poly(), e2._fmpz())) +FLINT_DEFINE_BINARY_EXPR_COND2(taylor_shift_op, fmpz_polyxx, + FMPZ_POLYXX_COND_S, FMPZXX_COND_S, + fmpz_poly_taylor_shift(to._poly(), e1._poly(), e2._fmpz())) + +FMPZ_POLYXX_DEFINE_SQRLOW(revert_series) +FMPZ_POLYXX_DEFINE_SQRLOW(revert_series_newton) +FMPZ_POLYXX_DEFINE_SQRLOW(revert_series_lagrange_fast) +FMPZ_POLYXX_DEFINE_SQRLOW(revert_series_lagrange) + +FLINT_DEFINE_UNARY_EXPR_COND(sqrt_op, fmpz_polyxx, FMPZ_POLYXX_COND_S, + execution_check(fmpz_poly_sqrt(to._poly(), from._poly()), + "sqrt", "fmpz_polyxx")) +FLINT_DEFINE_UNARY_EXPR_COND(sqrt_classical_op, fmpz_polyxx, FMPZ_POLYXX_COND_S, + execution_check(fmpz_poly_sqrt_classical(to._poly(), from._poly()), + "sqrt_classical", "fmpz_polyxx")) + +FLINT_DEFINE_UNARY_EXPR_COND(fmpz_polyxx_product_roots_op, fmpz_polyxx, + FMPZ_VECXX_COND_S, + fmpz_poly_product_roots_fmpz_vec(to._poly(), + from._data().array, from.size())) + +FLINT_DEFINE_BINARY_EXPR_COND2(fmpz_polyxx_get_coeff_op, fmpzxx, + FMPZ_POLYXX_COND_S, traits::is_integer, + fmpz_poly_get_coeff_fmpz(to._fmpz(), e1._poly(), e2)) +FLINT_DEFINE_UNARY_EXPR_COND(fmpz_polyxx_lead_op, fmpzxx, + FMPZ_POLYXX_COND_S, + fmpz_set(to._fmpz(), fmpz_poly_lead(from._poly()))) + +FLINT_DEFINE_UNARY_EXPR_COND(bound_roots_op, fmpzxx, FMPZ_POLYXX_COND_S, + fmpz_poly_bound_roots(to._fmpz(), from._poly())) + +namespace rdetail { +typedef make_ltuple::type>::type + fmpz_polyxx_pair; +typedef make_ltuple::type>::type + fmpzxx_fmpz_polyxx_pair; +} // rdetail +#define FMPZ_POLYXX_DEFINE_DIVREM(name) \ +FLINT_DEFINE_BINARY_EXPR_COND2(name##_op, rdetail::fmpz_polyxx_pair, \ + FMPZ_POLYXX_COND_S, FMPZ_POLYXX_COND_S, \ + fmpz_poly_##name(to.template get<0>()._poly(), to.template get<1>()._poly(), \ + e1._poly(), e2._poly())) +FMPZ_POLYXX_DEFINE_DIVREM(divrem_basecase) +FMPZ_POLYXX_DEFINE_DIVREM(divrem_divconquer) +FMPZ_POLYXX_DEFINE_DIVREM(divrem) +FMPZ_POLYXX_DEFINE_DIVREM(pseudo_divrem_cohen) + +#define FMPZ_POLYXX_DEFINE_MULFUNC(name) \ +FLINT_DEFINE_THREEARY_EXPR_COND3(name##_op, fmpz_polyxx, \ + FMPZ_POLYXX_COND_S, FMPZ_POLYXX_COND_S, traits::fits_into_slong, \ + fmpz_poly_##name(to._poly(), e1._poly(), e2._poly(), e3)) + +FMPZ_POLYXX_DEFINE_MULFUNC(mullow_classical) +FMPZ_POLYXX_DEFINE_MULFUNC(mulhigh_classical) +FMPZ_POLYXX_DEFINE_MULFUNC(mullow_karatsuba_n) +FMPZ_POLYXX_DEFINE_MULFUNC(mulhigh_karatsuba_n) +FMPZ_POLYXX_DEFINE_MULFUNC(mullow_KS) +FMPZ_POLYXX_DEFINE_MULFUNC(mullow_SS) +FMPZ_POLYXX_DEFINE_MULFUNC(mullow) +FMPZ_POLYXX_DEFINE_MULFUNC(mulhigh_n) + +FLINT_DEFINE_BINARY_EXPR_COND2(xgcd_op, rdetail::fmpzxx_fmpz_polyxx_pair, + FMPZ_POLYXX_COND_S, FMPZ_POLYXX_COND_S, + fmpz_poly_xgcd(to.template get<0>()._fmpz(), to.template get<1>()._poly(), + to.template get<2>()._poly(), e1._poly(), e2._poly())) +FLINT_DEFINE_BINARY_EXPR_COND2(xgcd_modular_op, rdetail::fmpzxx_fmpz_polyxx_pair, + FMPZ_POLYXX_COND_S, FMPZ_POLYXX_COND_S, + fmpz_poly_xgcd_modular(to.template get<0>()._fmpz(), + to.template get<1>()._poly(), + to.template get<2>()._poly(), e1._poly(), e2._poly())) + +FLINT_DEFINE_THREEARY_EXPR_COND3(pow_trunc_op, fmpz_polyxx, + FMPZ_POLYXX_COND_S, traits::is_unsigned_integer, traits::fits_into_slong, + fmpz_poly_pow_trunc(to._poly(), e1._poly(), e2, e3)) + +#define FMPZ_POLYXX_DEFINE_SERIES(name) \ +FLINT_DEFINE_THREEARY_EXPR_COND3(name##_op, fmpz_polyxx, \ + FMPZ_POLYXX_COND_S, FMPZ_POLYXX_COND_S, traits::fits_into_slong, \ + fmpz_poly_##name(to._poly(), e1._poly(), e2._poly(), e3)) +FMPZ_POLYXX_DEFINE_SERIES(div_series) +FMPZ_POLYXX_DEFINE_SERIES(compose_series_brent_kung) +FMPZ_POLYXX_DEFINE_SERIES(compose_series_horner) +FMPZ_POLYXX_DEFINE_SERIES(compose_series) + +namespace rdetail { +typedef make_ltuple::type>::type + fmpz_polyxx_pair_ulong; +typedef make_ltuple::type>::type + fmpz_polyxx_ulong; +typedef make_ltuple::type>::type + bool_fmpz_polyxx; +} +#define FMPZ_POLYXX_DEFINE_PSEUDO_DIVREM(name) \ +FLINT_DEFINE_BINARY_EXPR_COND2(name##_op, rdetail::fmpz_polyxx_pair_ulong, \ + FMPZ_POLYXX_COND_S, FMPZ_POLYXX_COND_S, \ + fmpz_poly_##name(to.template get<0>()._poly(), to.template get<1>()._poly(), \ + &to.template get<2>(), e1._poly(), e2._poly())) +FMPZ_POLYXX_DEFINE_PSEUDO_DIVREM(pseudo_divrem_basecase) +FMPZ_POLYXX_DEFINE_PSEUDO_DIVREM(pseudo_divrem_divconquer) +FMPZ_POLYXX_DEFINE_PSEUDO_DIVREM(pseudo_divrem) + +FLINT_DEFINE_BINARY_EXPR_COND2(pseudo_div_op, rdetail::fmpz_polyxx_ulong, + FMPZ_POLYXX_COND_S, FMPZ_POLYXX_COND_S, + fmpz_poly_pseudo_div(to.template get<0>()._poly(), &to.template get<1>(), + e1._poly(), e2._poly())) +FLINT_DEFINE_BINARY_EXPR_COND2(pseudo_rem_op, rdetail::fmpz_polyxx_ulong, + FMPZ_POLYXX_COND_S, FMPZ_POLYXX_COND_S, + fmpz_poly_pseudo_rem(to.template get<0>()._poly(), &to.template get<1>(), + e1._poly(), e2._poly())) + +FLINT_DEFINE_BINARY_EXPR_COND2(divides_op, rdetail::bool_fmpz_polyxx, + FMPZ_POLYXX_COND_S, FMPZ_POLYXX_COND_S, + to.template get<0> () = + fmpz_poly_divides(to.template get<1>()._poly(), e1._poly(), e2._poly())) + +namespace rdetail { +typedef make_ltuple::type>::type + fmpz_polyxx_quadruple; +} +FLINT_DEFINE_SEVENARY_EXPR_COND7(hensel_lift_op, rdetail::fmpz_polyxx_quadruple, + FMPZ_POLYXX_COND_S, FMPZ_POLYXX_COND_S, FMPZ_POLYXX_COND_S, + FMPZ_POLYXX_COND_S, FMPZ_POLYXX_COND_S, + FMPZXX_COND_S, FMPZXX_COND_S, + fmpz_poly_hensel_lift(to.template get<0>()._poly(), + to.template get<1>()._poly(), to.template get<2>()._poly(), + to.template get<3>()._poly(), + e1._poly(), e2._poly(), e3._poly(), e4._poly(), e5._poly(), + e6._fmpz(), e7._fmpz())) +FLINT_DEFINE_SEVENARY_EXPR_COND7(hensel_lift_without_inverse_op, + rdetail::fmpz_polyxx_pair, + FMPZ_POLYXX_COND_S, FMPZ_POLYXX_COND_S, FMPZ_POLYXX_COND_S, + FMPZ_POLYXX_COND_S, FMPZ_POLYXX_COND_S, + FMPZXX_COND_S, FMPZXX_COND_S, + fmpz_poly_hensel_lift_without_inverse(to.template get<0>()._poly(), + to.template get<1>()._poly(), + e1._poly(), e2._poly(), e3._poly(), e4._poly(), e5._poly(), + e6._fmpz(), e7._fmpz())) +FLINT_DEFINE_SIXARY_EXPR_COND6(hensel_lift_only_inverse_op, + rdetail::fmpz_polyxx_pair, + FMPZ_POLYXX_COND_S, FMPZ_POLYXX_COND_S, FMPZ_POLYXX_COND_S, + FMPZ_POLYXX_COND_S, + FMPZXX_COND_S, FMPZXX_COND_S, + fmpz_poly_hensel_lift_only_inverse(to.template get<0>()._poly(), + to.template get<1>()._poly(), + e1._poly(), e2._poly(), e3._poly(), e4._poly(), + e5._fmpz(), e6._fmpz())) +} // rules + +// immediate functions +// TODO make lazy when we have nmod class +template +inline typename mp::enable_all_fmpz_polyxx::type +evaluate_mod(const Poly& p, mp_limb_t x, mp_limb_t n) +{ + return fmpz_poly_evaluate_mod(p.evaluate()._poly(), x, n); +} + +template +int read_pretty(Fmpz_poly& f, char** x, + typename mp::enable_if >::type* = 0) +{ + return f.read_pretty(x); +} +template +int read_pretty(FILE* fi, Fmpz_poly& f, char** x, + typename mp::enable_if >::type* = 0) +{ + return f.read_pretty(x, fi); +} +} // flint + +#include "nmod_polyxx.h" // modular reconstruction code + +#include "fmpz_poly_factorxx.h" + +#endif diff --git a/external/flint-2.4.3/fmpz_vec.h b/external/flint-2.4.3/fmpz_vec.h new file mode 100644 index 0000000..841eb4b --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec.h @@ -0,0 +1,233 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#ifndef FMPZ_VEC_H +#define FMPZ_VEC_H + +#include +#include "fmpz.h" +#include "flint.h" + +#ifdef __cplusplus + extern "C" { +#endif + +#define FMPZ_VEC_NORM(vec, i) \ +do { \ + while ((i) && vec[(i) - 1] == WORD(0)) \ + (i)--; \ +} while (0) + +#define FMPZ_VEC_SWAP(vec1, len1, vec2, len2) \ +do { \ + fmpz *__t; \ + slong __tn; \ + __t = (vec1); \ + (vec1) = (vec2); \ + (vec2) = __t; \ + __tn = (len1); \ + (len1) = (len2); \ + (len2) = __tn; \ +} while (0); + +/* Memory management *******************************************************/ + +fmpz * _fmpz_vec_init(slong len); + +void _fmpz_vec_clear(fmpz * vec, slong len); + +/* Randomisation ***********************************************************/ + +void _fmpz_vec_randtest(fmpz * f, flint_rand_t state, + slong len, mp_bitcnt_t bits); + +void _fmpz_vec_randtest_unsigned(fmpz * f, flint_rand_t state, + slong len, mp_bitcnt_t bits); + +/* Norms *******************************************************************/ + +slong _fmpz_vec_max_bits(const fmpz * vec, slong len); + +slong _fmpz_vec_max_bits_ref(const fmpz * vec, slong len); + +mp_size_t _fmpz_vec_max_limbs(const fmpz * vec, slong len); + +void _fmpz_vec_height(fmpz_t height, const fmpz * vec, slong len); + +slong _fmpz_vec_height_index(const fmpz * vec, slong len); + +/* Input and output ********************************************************/ + +int _fmpz_vec_fprint(FILE * file, const fmpz * vec, slong len); + +static __inline__ +int _fmpz_vec_print(const fmpz * vec, slong len) +{ + return _fmpz_vec_fprint(stdout, vec, len); +} + +int _fmpz_vec_fread(FILE * file, fmpz ** vec, slong * len); + +static __inline__ +int _fmpz_vec_read(fmpz ** vec, slong * len) +{ + return _fmpz_vec_fread(stdin, vec, len); +} + +/* Conversions *************************************************************/ + +void _fmpz_vec_set_nmod_vec(fmpz * res, + mp_srcptr poly, slong len, nmod_t mod); + +void _fmpz_vec_get_nmod_vec(mp_ptr res, + const fmpz * poly, slong len, nmod_t mod); + +slong _fmpz_vec_get_fft(mp_limb_t ** coeffs_f, + const fmpz * coeffs_m, slong l, slong length); + +void _fmpz_vec_set_fft(fmpz * coeffs_m, slong length, + const mp_ptr * coeffs_f, slong limbs, slong sign); + +/* Assignment and basic manipulation ***************************************/ + +void _fmpz_vec_set(fmpz * vec1, const fmpz * vec2, slong len2); + +void _fmpz_vec_swap(fmpz * vec1, fmpz * vec2, slong len2); + +void _fmpz_vec_zero(fmpz * vec, slong len); + +void _fmpz_vec_neg(fmpz * vec1, const fmpz * vec2, slong len2); + +/* Comparison **************************************************************/ + +int _fmpz_vec_equal(const fmpz * vec1, const fmpz * vec2, slong len); + +int _fmpz_vec_is_zero(const fmpz * vec, slong len); + +/* Sorting ******************************************************************/ + +void _fmpz_vec_sort(fmpz * vec, slong len); + +/* Addition ****************************************************************/ + +void _fmpz_vec_add(fmpz * res, const fmpz * vec1, + const fmpz * vec2, slong len2); + +void _fmpz_vec_sub(fmpz * res, const fmpz * vec1, + const fmpz * vec2, slong len2); + +/* Scalar multiplication and division **************************************/ + +void _fmpz_vec_scalar_mul_si(fmpz * vec1, + const fmpz * vec2, slong len2, slong c); + +void _fmpz_vec_scalar_mul_ui(fmpz * vec1, + const fmpz * vec2, slong len2, ulong c); + +void _fmpz_vec_scalar_mul_fmpz(fmpz * vec1, + const fmpz * vec2, slong len2, const fmpz_t x); + +void _fmpz_vec_scalar_mul_2exp(fmpz * vec1, + const fmpz * vec2, slong len2, ulong exp); + +void _fmpz_vec_scalar_divexact_fmpz(fmpz * vec1, const fmpz * vec2, + slong len2, const fmpz_t x); + +void _fmpz_vec_scalar_divexact_si(fmpz * vec1, + const fmpz * vec2, slong len2, slong c); + +void _fmpz_vec_scalar_divexact_ui(fmpz * vec1, + const fmpz * vec2, slong len2, ulong c); + +void _fmpz_vec_scalar_fdiv_q_fmpz(fmpz * vec1, + const fmpz * vec2, slong len2, const fmpz_t c); + +void _fmpz_vec_scalar_fdiv_q_si(fmpz * vec1, + const fmpz * vec2, slong len2, slong c); + +void _fmpz_vec_scalar_fdiv_q_ui(fmpz * vec1, + const fmpz * vec2, slong len2, ulong c); + +void _fmpz_vec_scalar_fdiv_q_2exp(fmpz * vec1, const fmpz * vec2, + slong len2, ulong exp); + +void _fmpz_vec_scalar_fdiv_r_2exp(fmpz * vec1, const fmpz * vec2, + slong len2, ulong exp); + +void _fmpz_vec_scalar_tdiv_q_fmpz(fmpz * vec1, + const fmpz * vec2, slong len2, const fmpz_t c); + +void _fmpz_vec_scalar_tdiv_q_si(fmpz * vec1, + const fmpz * vec2, slong len2, slong c); + +void _fmpz_vec_scalar_tdiv_q_ui(fmpz * vec1, + const fmpz * vec2, slong len2, ulong c); + +void _fmpz_vec_scalar_tdiv_q_2exp(fmpz * vec1, const fmpz * vec2, + slong len2, ulong exp); + +void _fmpz_vec_scalar_addmul_si(fmpz * vec1, + const fmpz * vec2, slong len2, slong c); + +void _fmpz_vec_scalar_addmul_fmpz(fmpz * poly1, const fmpz * poly2, + slong len2, const fmpz_t x); + +void _fmpz_vec_scalar_addmul_si_2exp(fmpz * vec1, const fmpz * vec2, + slong len2, slong c, ulong exp); + +void _fmpz_vec_scalar_submul_si(fmpz * vec1, + const fmpz * vec2, slong len2, slong c); + +void _fmpz_vec_scalar_submul_fmpz(fmpz * vec1, const fmpz * vec2, + slong len2, const fmpz_t x); + +void _fmpz_vec_scalar_submul_si_2exp(fmpz * vec1, const fmpz * vec2, + slong len2, slong c, ulong exp); + +/* Vector sum and product **************************************************/ + +void _fmpz_vec_sum(fmpz_t res, const fmpz * vec, slong len); + +void _fmpz_vec_prod(fmpz_t res, const fmpz * vec, slong len); + +/* Reduction mod p **********************************************************/ + +void _fmpz_vec_scalar_mod_fmpz(fmpz *res, const fmpz *vec, slong len, const fmpz_t p); + +void _fmpz_vec_scalar_smod_fmpz(fmpz *res, const fmpz *vec, slong len, const fmpz_t p); + +/* Gaussian content ********************************************************/ + +void _fmpz_vec_content(fmpz_t res, const fmpz * vec, slong len); + +void _fmpz_vec_lcm(fmpz_t res, const fmpz * vec, slong len); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/external/flint-2.4.3/fmpz_vec/add.c b/external/flint-2.4.3/fmpz_vec/add.c new file mode 100644 index 0000000..bbf9eeb --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/add.c @@ -0,0 +1,37 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +void +_fmpz_vec_add(fmpz * res, const fmpz * vec1, const fmpz * vec2, slong len2) +{ + slong i; + for (i = 0; i < len2; i++) + fmpz_add(res + i, vec1 + i, vec2 + i); +} diff --git a/external/flint-2.4.3/fmpz_vec/clear.c b/external/flint-2.4.3/fmpz_vec/clear.c new file mode 100644 index 0000000..9a731de --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/clear.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +void +_fmpz_vec_clear(fmpz * vec, slong len) +{ + slong i; + for (i = 0; i < len; i++) + fmpz_clear(vec + i); + flint_free(vec); +} diff --git a/external/flint-2.4.3/fmpz_vec/content.c b/external/flint-2.4.3/fmpz_vec/content.c new file mode 100644 index 0000000..6b507be --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/content.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +void +_fmpz_vec_content(fmpz_t res, const fmpz * vec, slong len) +{ + fmpz_zero(res); + while (len--) + fmpz_gcd(res, res, vec + len); +} diff --git a/external/flint-2.4.3/fmpz_vec/doc/fmpz_vec.txt b/external/flint-2.4.3/fmpz_vec/doc/fmpz_vec.txt new file mode 100644 index 0000000..d3b8d81 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/doc/fmpz_vec.txt @@ -0,0 +1,438 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +******************************************************************************* + + Memory management + +******************************************************************************* + +fmpz * _fmpz_vec_init(slong len) + + Returns an initialised vector of \code{fmpz}'s of given length. + +void _fmpz_vec_clear(fmpz * vec, slong len) + + Clears the entries of \code{(vec, len)} and frees the space allocated + for \code{vec}. + +******************************************************************************* + + Randomisation + +******************************************************************************* + +void _fmpz_vec_randtest(fmpz * f, flint_rand_t state, + slong len, mp_bitcnt_t bits) + + Sets the entries of a vector of the given length to random integers with + up to the given number of bits per entry. + +void _fmpz_vec_randtest_unsigned(fmpz * f, flint_rand_t state, + slong len, mp_bitcnt_t bits) + + Sets the entries of a vector of the given length to random unsigned + integers with up to the given number of bits per entry. + +******************************************************************************* + + Bit sizes and norms + +******************************************************************************* + +slong _fmpz_vec_max_bits(const fmpz * vec, slong len) + + If $b$ is the maximum number of bits of the absolute value of any + coefficient of \code{vec}, then if any coefficient of \code{vec} is + negative, $-b$ is returned, else $b$ is returned. + +slong _fmpz_vec_max_bits_ref(const fmpz * vec, slong len) + + If $b$ is the maximum number of bits of the absolute value of any + coefficient of \code{vec}, then if any coefficient of \code{vec} is + negative, $-b$ is returned, else $b$ is returned. + This is a slower reference implementation of \code{_fmpz_vec_max_bits}. + +ulong _fmpz_vec_max_limbs(const fmpz * vec, slong len) + + Returns the maximum number of limbs needed to store the absolute value + of any entry in \code{(vec, len)}. If all entries are zero, returns + zero. + +void _fmpz_vec_height(fmpz_t height, const fmpz * vec, slong len) + + Computes the height of \code{(vec, len)}, defined as the largest of the + absolute values the coefficients. Equivalently, this gives the infinity + norm of the vector. If \code{len} is zero, the height is $0$. + +slong _fmpz_vec_height_index(const fmpz * vec, slong len) + + Returns the index of an entry of maximum absolute value in the vector. + The the length must be at least 1. + +******************************************************************************* + + Input and output + +******************************************************************************* + +int _fmpz_vec_fread(FILE * file, fmpz ** vec, slong * len) + + Reads a vector from the stream \code{file} and stores it at + \code{*vec}. The format is the same as the output format of + \code{_fmpz_vec_fprint()}, followed by either any character + or the end of the file. + + The interpretation of the various input arguments depends on whether + or not \code{*vec} is \code{NULL}: + + If \code{*vec == NULL}, the value of \code{*len} on input is ignored. + Once the length has been read from \code{file}, \code{*len} is set + to that value and a vector of this length is allocated at \code{*vec}. + Finally, \code{*len} coefficients are read from the input stream. In + case of a file or parsing error, clears the vector and sets \code{*vec} + and \code{*len} to \code{NULL} and \code{0}, respectively. + + Otherwise, if \code{*vec != NULL}, it is assumed that \code{(*vec, *len)} + is a properly initialised vector. If the length on the input stream + does not match \code{*len}, a parsing error is raised. Attempts to read + the right number of coefficients from the input stream. In case of a + file or parsing error, leaves the vector \code{(*vec, *len)} in its + current state. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + +int _fmpz_vec_read(fmpz ** vec, slong * len) + + Reads a vector from \code{stdin} and stores it at \code{*vec}. + + For further details, see \code{_fmpz_vec_fread()}. + +int _fmpz_vec_fprint(FILE * file, const fmpz * vec, slong len) + + Prints the vector of given length to the stream \code{file}. The + format is the length followed by two spaces, then a space separated + list of coefficients. If the length is zero, only $0$ is printed. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + +int _fmpz_vec_print(const fmpz * vec, slong len) + + Prints the vector of given length to \code{stdout}. + + For further details, see \code{_fmpz_vec_fprint()}. + +******************************************************************************* + + Conversions + +******************************************************************************* + +void _fmpz_vec_get_nmod_vec(mp_ptr res, + const fmpz * poly, slong len, nmod_t mod) + + Reduce the coefficients of \code{(poly, len)} modulo the given + modulus and set \code{(res, len)} to the result. + +void _fmpz_vec_set_nmod_vec(fmpz * res, + mp_srcptr poly, slong len, nmod_t mod) + + Set the coefficients of \code{(res, len)} to the symmetric modulus + of the coefficients of \code{(poly, len)}, i.e. convert the given + coefficients modulo the given modulus $n$ to their signed integer + representatives in the range $[-n/2, n/2)$. + +slong _fmpz_vec_get_fft(mp_limb_t ** coeffs_f, + const fmpz * coeffs_m, slong l, slong length) + + Convert the vector of coeffs \code{coeffs_m} to an fft vector + \code{coeffs_f} of the given \code{length} with \code{l} limbs per + coefficient with an additional limb for overflow. + +void _fmpz_vec_set_fft(fmpz * coeffs_m, slong length, + const mp_ptr * coeffs_f, slong limbs, slong sign) + + Convert an fft vector \code{coeffs_f} of the given \code{length} + to a vector of \code{fmpz}'s. Each is assumed to be the given + number of limbs in length with an additional limb for overflow. If the + output coefficients are to be signed then set \code{sign}, + otherwise clear it. + +******************************************************************************* + + Assignment and basic manipulation + +******************************************************************************* + +void _fmpz_vec_set(fmpz * vec1, const fmpz * vec2, slong len2) + + Makes a copy of \code{(vec2, len2)} into \code{vec1}. + +void _fmpz_vec_swap(fmpz * vec1, fmpz * vec2, slong len2) + + Swaps the integers in \code{(vec1, len2)} and \code{(vec2, len2)}. + +void _fmpz_vec_zero(fmpz * vec, slong len) + + Zeros the entries of \code{(vec, len)}. + +void _fmpz_vec_neg(fmpz * vec1, const fmpz * vec2, slong len2) + + Negates \code{(vec2, len2)} and places it into \code{vec1}. + +******************************************************************************* + + Comparison + +******************************************************************************* + +int _fmpz_vec_equal(const fmpz * vec1, const fmpz * vec2, slong len) + + Compares two vectors of the given length and returns $1$ if they are + equal, otherwise returns $0$. + +int _fmpz_vec_is_zero(const fmpz * vec, slong len) + + Returns $1$ if \code{(vec, len)} is zero, and $0$ otherwise. + +******************************************************************************* + + Sorting + +******************************************************************************* + +void _fmpz_vec_sort(fmpz * vec, slong len) + + Sorts the coefficients of \code{vec} in ascending order. + +******************************************************************************* + + Addition and subtraction + +******************************************************************************* + +void _fmpz_vec_add(fmpz * res, const fmpz * vec1, + const fmpz * vec2, slong len2) + + Sets \code{(res, len2)} to the sum of \code{(vec1, len2)} + and \code{(vec2, len2)}. + +void _fmpz_vec_sub(fmpz * res, const fmpz * vec1, + const fmpz * vec2, slong len2) + + Sets \code{(res, len2)} to \code{(vec1, len2)} minus \code{(vec2, len2)}. + +******************************************************************************* + + Scalar multiplication and division + +******************************************************************************* + +void _fmpz_vec_scalar_mul_fmpz(fmpz * vec1, + const fmpz * vec2, slong len2, const fmpz_t x) + + Sets \code{(vec1, len2)} to \code{(vec2, len2)} multiplied by $c$, + where $c$ is an \code{fmpz_t}. + +id _fmpz_vec_scalar_mul_si(fmpz * vec1, const fmpz * vec2, slong len2, slong c) + + Sets \code{(vec1, len2)} to \code{(vec2, len2)} multiplied by $c$, + where $c$ is a \code{slong}. + +void _fmpz_vec_scalar_mul_ui(fmpz * vec1, + const fmpz * vec2, slong len2, ulong c) + + Sets \code{(vec1, len2)} to \code{(vec2, len2)} multiplied by $c$, + where $c$ is an \code{ulong}. + +void _fmpz_vec_scalar_mul_2exp(fmpz * vec1, + const fmpz * vec2, slong len2, ulong exp) + + Sets \code{(vec1, len2)} to \code{(vec2, len2)} multiplied by \code{2^exp}. + +void _fmpz_vec_scalar_divexact_fmpz(fmpz * vec1, + const fmpz * vec2, slong len2, const fmpz_t x) + + Sets \code{(vec1, len2)} to \code{(vec2, len2)} divided by $x$, where the + division is assumed to be exact for every entry in \code{vec2}. + +void _fmpz_vec_scalar_divexact_si(fmpz * vec1, + const fmpz * vec2, slong len2, slong c) + + Sets \code{(vec1, len2)} to \code{(vec2, len2)} divided by $x$, where the + division is assumed to be exact for every entry in \code{vec2}. + +void _fmpz_vec_scalar_divexact_ui(fmpz * vec1, + const fmpz * vec2, ulong len2, ulong c) + + Sets \code{(vec1, len2)} to \code{(vec2, len2)} divided by $x$, where the + division is assumed to be exact for every entry in \code{vec2}. + +void _fmpz_vec_scalar_fdiv_q_fmpz(fmpz * vec1, + const fmpz * vec2, slong len2, const fmpz_t c) + + Sets \code{(vec1, len2)} to \code{(vec2, len2)} divided by $c$, rounding + down towards minus infinity whenever the division is not exact. + +void _fmpz_vec_scalar_fdiv_q_si(fmpz * vec1, + const fmpz * vec2, slong len2, slong c) + + Sets \code{(vec1, len2)} to \code{(vec2, len2)} divided by $c$, rounding + down towards minus infinity whenever the division is not exact. + +void _fmpz_vec_scalar_fdiv_q_ui(fmpz * vec1, + const fmpz * vec2, slong len2, ulong c) + + Sets \code{(vec1, len2)} to \code{(vec2, len2)} divided by $c$, rounding + down towards minus infinity whenever the division is not exact. + +void _fmpz_vec_scalar_fdiv_q_2exp(fmpz * vec1, + const fmpz * vec2, slong len2, ulong exp) + + Sets \code{(vec1, len2)} to \code{(vec2, len2)} divided by \code{2^exp}, + rounding down towards minus infinity whenever the division is not exact. + +void _fmpz_vec_scalar_fdiv_r_2exp(fmpz * vec1, + const fmpz * vec2, slong len2, ulong exp) + + Sets \code{(vec1, len2)} to the remainder of \code{(vec2, len2)} + divided by \code{2^exp}, rounding down the quotient towards minus + infinity whenever the division is not exact. + +void _fmpz_vec_scalar_tdiv_q_fmpz(fmpz * vec1, + const fmpz * vec2, slong len2, const fmpz_t c) + + Sets \code{(vec1, len2)} to \code{(vec2, len2)} divided by $c$, rounding + towards zero whenever the division is not exact. + +void _fmpz_vec_scalar_tdiv_q_si(fmpz * vec1, + const fmpz * vec2, slong len2, slong c) + + Sets \code{(vec1, len2)} to \code{(vec2, len2)} divided by $c$, rounding + towards zero whenever the division is not exact. + +void _fmpz_vec_scalar_tdiv_q_ui(fmpz * vec1, + const fmpz * vec2, slong len2, ulong c) + + Sets \code{(vec1, len2)} to \code{(vec2, len2)} divided by $c$, rounding + towards zero whenever the division is not exact. + +void _fmpz_vec_scalar_tdiv_q_2exp(fmpz * vec1, + const fmpz * vec2, slong len2, ulong exp) + + Sets \code{(vec1, len2)} to \code{(vec2, len2)} divided by \code{2^exp}, + rounding down towards zero whenever the division is not exact. + +void _fmpz_vec_scalar_addmul_fmpz(fmpz * vec1, + const fmpz * vec2, slong len2, const fmpz_t c) + + Adds \code{(vec2, len2)} times $c$ to \code{(vec1, len2)}, where $c$ is a + \code{fmpz_t}. + +void _fmpz_vec_scalar_addmul_si(fmpz * vec1, + const fmpz * vec2, slong len2, slong c) + + Adds \code{(vec2, len2)} times $c$ to \code{(vec1, len2)}, where $c$ is a + \code{slong}. + +void _fmpz_vec_scalar_addmul_si_2exp(fmpz * vec1, + const fmpz * vec2, slong len2, slong c, ulong exp) + + Adds \code{(vec2, len2)} times \code{c * 2^exp} to \code{(vec1, len2)}, + where $c$ is a \code{slong}. + +void _fmpz_vec_scalar_submul_fmpz(fmpz * vec1, + const fmpz * vec2, slong len2, const fmpz_t x) + + Subtracts \code{(vec2, len2)} times $c$ from \code{(vec1, len2)}, + where $c$ is a \code{fmpz_t}. + +void _fmpz_vec_scalar_submul_si(fmpz * vec1, + const fmpz * vec2, slong len2, slong c) + + Subtracts \code{(vec2, len2)} times $c$ from \code{(vec1, len2)}, + where $c$ is a \code{slong}. + +void _fmpz_vec_scalar_submul_si_2exp(fmpz * vec1, + const fmpz * vec2, slong len2, slong c, ulong e) + + Subtracts \code{(vec2, len2)} times $c \times 2^e$ + from \code{(vec1, len2)}, where $c$ is a \code{slong}. + +******************************************************************************* + + Sums and products + +******************************************************************************* + +void _fmpz_vec_sum(fmpz_t res, const fmpz * vec, slong len) + + Sets \code{res} to the sum of the entries in \code{(vec, len)}. + Aliasing of \code{res} with the entries in \code{vec} is not permitted. + +void _fmpz_vec_prod(fmpz_t res, const fmpz * vec, slong len) + + Sets \code{res} to the product of the entries in \code{(vec, len)}. + Aliasing of \code{res} with the entries in \code{vec} is not permitted. + Uses binary splitting. + +******************************************************************************* + + Reduction mod $p$ + +******************************************************************************* + +void _fmpz_vec_scalar_mod_fmpz(fmpz *res, + const fmpz *vec, slong len, const fmpz_t p) + + Reduces all entries in \code{(vec, len)} modulo $p > 0$. + +void _fmpz_vec_scalar_smod_fmpz(fmpz *res, + const fmpz *vec, slong len, const fmpz_t p) + + Reduces all entries in \code{(vec, len)} modulo $p > 0$, choosing + the unique representative in $(-p/2, p/2]$. + +******************************************************************************* + + Gaussian content + +******************************************************************************* + +void _fmpz_vec_content(fmpz_t res, const fmpz * vec, slong len) + + Sets \code{res} to the non-negative content of the entries in \code{vec}. + The content of a zero vector, including the case when the length is zero, + is defined to be zero. + +void _fmpz_vec_lcm(fmpz_t res, const fmpz * vec, slong len) + + Sets \code{res} to the nonnegative least common multiple of the entries + in \code{vec}. The least common multiple is zero if any entry in + the vector is zero. The least common multiple of a length zero vector is + defined to be one. + diff --git a/external/flint-2.4.3/fmpz_vec/equal.c b/external/flint-2.4.3/fmpz_vec/equal.c new file mode 100644 index 0000000..b78a8c5 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/equal.c @@ -0,0 +1,43 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2008, 2009, 2010 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +int +_fmpz_vec_equal(const fmpz * vec1, const fmpz * vec2, slong len) +{ + slong i; + if (vec1 == vec2) + return 1; + + for (i = 0; i < len; i++) + if (!fmpz_equal(vec1 + i, vec2 + i)) + return 0; + + return 1; +} diff --git a/external/flint-2.4.3/fmpz_vec/fprint.c b/external/flint-2.4.3/fmpz_vec/fprint.c new file mode 100644 index 0000000..5b929d2 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/fprint.c @@ -0,0 +1,65 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2008, 2009, 2010 William Hart + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +/* + Recall the return value conventions for fputc (of type int) + + ``If there are no errors, the same character that has been written is + returned. If an error occurs, EOF is returned and the error indicator + is set'' + + where the EOF macro expands to a negative int, and flint_fprintf (of type int) + + ``On success, the total number of characters written is returned. + On failure, a negative number is returned.'' + */ + +int _fmpz_vec_fprint(FILE * file, const fmpz * vec, slong len) +{ + int r; + slong i; + + r = flint_fprintf(file, "%li", len); + if ((len > 0) && (r > 0)) + { + r = fputc(' ', file); + for (i = 0; (i < len) && (r > 0); i++) + { + r = fputc(' ', file); + if (r > 0) + r = fmpz_fprint(file, vec + i); + } + } + + return r; +} diff --git a/external/flint-2.4.3/fmpz_vec/fread.c b/external/flint-2.4.3/fmpz_vec/fread.c new file mode 100644 index 0000000..c627649 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/fread.c @@ -0,0 +1,87 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +int _fmpz_vec_fread(FILE * file, fmpz ** vec, slong * len) +{ + int alloc, r; + slong i; + mpz_t t; + + alloc = (*vec == NULL); + + mpz_init(t); + r = mpz_inp_str(t, file, 10); + if (r == 0) + { + if (alloc) + *len = 0; + mpz_clear(t); + return 0; + } + if (!mpz_fits_slong_p(t)) + { + flint_printf("Exception (_fmpz_vec_fread). Length does not fit into a slong.\n"); + abort(); + } + if (alloc) + { + *len = flint_mpz_get_si(t); + *vec = _fmpz_vec_init(*len); + } + else + { + if (*len != flint_mpz_get_si(t)) + { + mpz_clear(t); + return 0; + } + } + mpz_clear(t); + + for (i = 0; i < *len; i++) + { + r = fmpz_fread(file, (*vec) + i); + if (r <= 0) + { + if (alloc) + { + _fmpz_vec_clear(*vec, *len); + *vec = NULL; + *len = 0; + } + return r; + } + } + + return 1; +} + diff --git a/external/flint-2.4.3/fmpz_vec/get_fft.c b/external/flint-2.4.3/fmpz_vec/get_fft.c new file mode 100644 index 0000000..790c3f6 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/get_fft.c @@ -0,0 +1,102 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2008-2011 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" +#include "fft.h" + +slong _fmpz_vec_get_fft(mp_limb_t ** coeffs_f, + const fmpz * coeffs_m, slong l, slong length) +{ + slong size_f = l + 1; + mp_limb_t * coeff; + + mp_limb_t mask = WORD(-1); + slong bits = 0, limbs = 0, size_j, i, c; + int sign = 1, signed_c; + + for (i = 0; i < length; i++, coeffs_m++) + { + c = *coeffs_m; + signed_c = 0; + + if (!COEFF_IS_MPZ(c)) /* coeff is small */ + { + size_j = 1; + + if (c < 0) + { + signed_c = 1; + c = -c; + coeff = (mp_limb_t *) &c; + } else + coeff = (mp_limb_t *) coeffs_m; + } else /* coeff is an mpz_t */ + { + __mpz_struct * mpz_ptr = COEFF_TO_PTR(c); + size_j = mpz_ptr->_mp_size; + if (size_j < 0) + { + signed_c = 1; + size_j = -size_j; + } + coeff = mpz_ptr->_mp_d; + } + + if (signed_c) sign = -1; + + if (size_j > limbs + 1) /* coeff is at least 1 limb bigger */ + { + limbs = size_j - 1; + bits = FLINT_BIT_COUNT(coeff[size_j - 1]); + if (bits == FLINT_BITS) mask = WORD(0); + else mask = WORD(-1) - ((WORD(1)< +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" +#include "nmod_poly.h" + +void +_fmpz_vec_get_nmod_vec(mp_ptr res, const fmpz * poly, slong len, nmod_t mod) +{ + slong i; + + for (i = 0; i < len; i++) + res[i] = fmpz_fdiv_ui(poly + i, mod.n); +} diff --git a/external/flint-2.4.3/fmpz_vec/height.c b/external/flint-2.4.3/fmpz_vec/height.c new file mode 100644 index 0000000..41f885c --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/height.c @@ -0,0 +1,42 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +void +_fmpz_vec_height(fmpz_t height, const fmpz * vec, slong len) +{ + if (len) + { + slong pos = _fmpz_vec_height_index(vec, len); + + fmpz_abs(height, vec + pos); + } + else + fmpz_zero(height); +} diff --git a/external/flint-2.4.3/fmpz_vec/height_index.c b/external/flint-2.4.3/fmpz_vec/height_index.c new file mode 100644 index 0000000..65a1e9e --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/height_index.c @@ -0,0 +1,95 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +slong +_fmpz_vec_height_index(const fmpz * vec, slong len) +{ + if (len == 1) + { + return 0; + } + else + { + fmpz c; + mp_srcptr max_d; + slong max_mpz_limbs, i, max_i, max_coeff, mpz_limbs; + + max_coeff = 0; + max_i = 0; + + for (i = 0; i < len; i++) + { + c = vec[i]; + + if (!COEFF_IS_MPZ(c)) + { + c = FLINT_ABS(c); + if (c > max_coeff) + { + max_coeff = c; + max_i = i; + } + } + else + { + __mpz_struct * mpz_ptr = COEFF_TO_PTR(c); + max_d = mpz_ptr->_mp_d; + max_mpz_limbs = mpz_ptr->_mp_size; + max_mpz_limbs = FLINT_ABS(max_mpz_limbs); + max_i = i; + i++; + break; + } + } + + for ( ; i < len; i++) + { + c = vec[i]; + + /* we have found at least one mpz, so only look for those */ + if (COEFF_IS_MPZ(c)) + { + __mpz_struct * mpz_ptr = COEFF_TO_PTR(c); + mpz_limbs = mpz_ptr->_mp_size; + mpz_limbs = FLINT_ABS(mpz_limbs); + if (mpz_limbs > max_mpz_limbs || + ((mpz_limbs == max_mpz_limbs) && + (mpn_cmp(mpz_ptr->_mp_d, max_d, max_mpz_limbs) > 0))) + { + max_d = mpz_ptr->_mp_d; + max_mpz_limbs = mpz_limbs; + max_i = i; + } + } + } + + return max_i; + } +} diff --git a/external/flint-2.4.3/fmpz_vec/init.c b/external/flint-2.4.3/fmpz_vec/init.c new file mode 100644 index 0000000..e65e386 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/init.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +fmpz * +_fmpz_vec_init(slong len) +{ + return (fmpz *) flint_calloc(len, sizeof(fmpz)); +} diff --git a/external/flint-2.4.3/fmpz_vec/is_zero.c b/external/flint-2.4.3/fmpz_vec/is_zero.c new file mode 100644 index 0000000..300c1cb --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/is_zero.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +int +_fmpz_vec_is_zero(const fmpz * vec, slong len) +{ + slong i; + for (i = 0; i < len; i++) + if (vec[i] != WORD(0)) + return 0; + return 1; +} diff --git a/external/flint-2.4.3/fmpz_vec/lcm.c b/external/flint-2.4.3/fmpz_vec/lcm.c new file mode 100644 index 0000000..325d775 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/lcm.c @@ -0,0 +1,41 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +void +_fmpz_vec_lcm(fmpz_t res, const fmpz * vec, slong len) +{ + slong i; + + fmpz_one(res); + for (i = 0; i < len && !fmpz_is_zero(res); i++) + fmpz_lcm(res, res, vec + i); + + fmpz_abs(res, res); +} diff --git a/external/flint-2.4.3/fmpz_vec/max_bits.c b/external/flint-2.4.3/fmpz_vec/max_bits.c new file mode 100644 index 0000000..18ca818 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/max_bits.c @@ -0,0 +1,91 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +slong +_fmpz_vec_max_bits(const fmpz * vec, slong len) +{ + slong i, sign, max_limbs; + mp_limb_t max_limb; + mp_size_t limbs; + + sign = 1; + max_limb = 0; + + for (i = 0; i < len; i++) + { + fmpz c = vec[i]; + + if (c >= 0) + { + if (c > COEFF_MAX) + goto bignum; + max_limb |= c; + } + else + { + if (c < COEFF_MIN) + goto bignum; + max_limb |= -c; + sign = -1; + } + } + return sign * FLINT_BIT_COUNT(max_limb); + +bignum: + max_limbs = 1; + + for ( ; i < len; i++) + { + fmpz c = vec[i]; + + if (COEFF_IS_MPZ(c)) + { + __mpz_struct * z = COEFF_TO_PTR(c); + limbs = z->_mp_size; + + if (limbs < 0) + { + sign = -1; + limbs = -limbs; + } + + if (limbs == max_limbs) + max_limb |= z->_mp_d[limbs - 1]; + else if (limbs > max_limbs) + { + max_limb = z->_mp_d[limbs - 1]; + max_limbs = limbs; + } + } + else if (c < 0) + sign = -1; + } + return sign * ((max_limbs - 1) * FLINT_BITS + FLINT_BIT_COUNT(max_limb)); +} diff --git a/external/flint-2.4.3/fmpz_vec/max_bits_ref.c b/external/flint-2.4.3/fmpz_vec/max_bits_ref.c new file mode 100644 index 0000000..d372380 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/max_bits_ref.c @@ -0,0 +1,46 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +slong +_fmpz_vec_max_bits_ref(const fmpz * vec, slong len) +{ + slong i, bits, max_bits = 0, sign = 1; + + for (i = 0; i < len; i++) + { + bits = fmpz_bits(vec + i); + if (bits > max_bits) + max_bits = bits; + if (fmpz_sgn(vec + i) < 0) + sign = WORD(-1); + } + + return max_bits * sign; +} diff --git a/external/flint-2.4.3/fmpz_vec/max_limbs.c b/external/flint-2.4.3/fmpz_vec/max_limbs.c new file mode 100644 index 0000000..0578916 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/max_limbs.c @@ -0,0 +1,45 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +mp_size_t +_fmpz_vec_max_limbs(const fmpz * vec, slong len) +{ + slong i; + mp_size_t limbs, max_limbs = 0; + + for (i = 0; i < len; i++) + { + limbs = fmpz_size(vec + i); + if (limbs > max_limbs) + max_limbs = limbs; + } + + return max_limbs; +} diff --git a/external/flint-2.4.3/fmpz_vec/neg.c b/external/flint-2.4.3/fmpz_vec/neg.c new file mode 100644 index 0000000..8e1a01e --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/neg.c @@ -0,0 +1,37 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +void +_fmpz_vec_neg(fmpz * vec1, const fmpz * vec2, slong len2) +{ + slong i; + for (i = 0; i < len2; i++) + fmpz_neg(vec1 + i, vec2 + i); +} diff --git a/external/flint-2.4.3/fmpz_vec/prod.c b/external/flint-2.4.3/fmpz_vec/prod.c new file mode 100644 index 0000000..70d0066 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/prod.c @@ -0,0 +1,59 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +void +_fmpz_vec_prod(fmpz_t res, const fmpz * vec, slong len) +{ + if (len <= 1) + { + if (len == 1) + fmpz_set(res, vec); + else + fmpz_one(res); + } + else if (len <= 3) + { + slong i; + + fmpz_mul(res, vec, vec + 1); + for (i = 2; i < len; i++) + fmpz_mul(res, res, vec + i); + } + else + { + slong m = len / 2; + fmpz_t tmp; + fmpz_init(tmp); + _fmpz_vec_prod(res, vec, m); + _fmpz_vec_prod(tmp, vec + m, len - m); + fmpz_mul(res, res, tmp); + fmpz_clear(tmp); + } +} diff --git a/external/flint-2.4.3/fmpz_vec/randtest.c b/external/flint-2.4.3/fmpz_vec/randtest.c new file mode 100644 index 0000000..946aa23 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/randtest.c @@ -0,0 +1,82 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009, 2010 William Hart + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +void +_fmpz_vec_randtest(fmpz * f, flint_rand_t state, + slong len, mp_bitcnt_t bits) +{ + slong i, sparseness; + + if (n_randint(state, 2)) + { + for (i = 0; i < len; i++) + fmpz_randtest(f + i, state, bits); + } + else + { + sparseness = 1 + n_randint(state, FLINT_MAX(2, len)); + + for (i = 0; i < len; i++) + { + if (n_randint(state, sparseness)) + fmpz_zero(f + i); + else + fmpz_randtest(f + i, state, bits); + } + } +} + +void +_fmpz_vec_randtest_unsigned(fmpz * f, flint_rand_t state, + slong len, mp_bitcnt_t bits) +{ + slong i, sparseness; + + if (n_randint(state, 2)) + { + for (i = 0; i < len; i++) + fmpz_randtest_unsigned(f + i, state, bits); + } + else + { + sparseness = 1 + n_randint(state, FLINT_MAX(2, len)); + + for (i = 0; i < len; i++) + { + if (n_randint(state, sparseness)) + fmpz_zero(f + i); + else + fmpz_randtest_unsigned(f + i, state, bits); + } + } +} diff --git a/external/flint-2.4.3/fmpz_vec/scalar_addmul_fmpz.c b/external/flint-2.4.3/fmpz_vec/scalar_addmul_fmpz.c new file mode 100644 index 0000000..8e5613c --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/scalar_addmul_fmpz.c @@ -0,0 +1,54 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +void +_fmpz_vec_scalar_addmul_fmpz(fmpz * poly1, const fmpz * poly2, slong len2, + const fmpz_t x) +{ + fmpz c = *x; + + if (!COEFF_IS_MPZ(c)) + { + if (c == 0) + return; + else if (c == 1) + _fmpz_vec_add(poly1, poly1, poly2, len2); + else if (c == -1) + _fmpz_vec_sub(poly1, poly1, poly2, len2); + else + _fmpz_vec_scalar_addmul_si(poly1, poly2, len2, c); + } + else + { + slong i; + for (i = 0; i < len2; i++) + fmpz_addmul(poly1 + i, poly2 + i, x); + } +} diff --git a/external/flint-2.4.3/fmpz_vec/scalar_addmul_si.c b/external/flint-2.4.3/fmpz_vec/scalar_addmul_si.c new file mode 100644 index 0000000..d69d8f0 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/scalar_addmul_si.c @@ -0,0 +1,42 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +void +_fmpz_vec_scalar_addmul_si(fmpz * vec1, const fmpz * vec2, slong len2, slong c) +{ + slong i; + + if (c >= 0) + for (i = 0; i < len2; i++) + fmpz_addmul_ui(vec1 + i, vec2 + i, c); + else + for (i = 0; i < len2; i++) + fmpz_submul_ui(vec1 + i, vec2 + i, -c); +} diff --git a/external/flint-2.4.3/fmpz_vec/scalar_addmul_si_2exp.c b/external/flint-2.4.3/fmpz_vec/scalar_addmul_si_2exp.c new file mode 100644 index 0000000..5a3ae3e --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/scalar_addmul_si_2exp.c @@ -0,0 +1,86 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +void +_fmpz_vec_scalar_addmul_si_2exp(fmpz * vec1, const fmpz * vec2, slong len2, + slong c, ulong exp) +{ + slong i; + fmpz_t temp; + + if (c == 0) + return; /* nothing to add */ + + if (exp == 0) /* just do addmul */ + { + _fmpz_vec_scalar_addmul_si(vec1, vec2, len2, c); + return; + } + + fmpz_init(temp); + + if (c == 1) /* scalar is 1, just add c * 2^exp times c */ + { + for (i = 0; i < len2; i++) + { + fmpz_mul_2exp(temp, vec2 + i, exp); + fmpz_add(vec1 + i, vec1 + i, temp); + } + } + else if (c == -1) /* scalar is -1, subtract c * 2^exp */ + { + for (i = 0; i < len2; i++) + { + fmpz_mul_2exp(temp, vec2 + i, exp); + fmpz_sub(vec1 + i, vec1 + i, temp); + } + } + else /* generic case */ + { + if (c > 0) + { + for (i = 0; i < len2; i++) + { + fmpz_mul_2exp(temp, vec2 + i, exp); + fmpz_addmul_ui(vec1 + i, temp, c); + } + } + else + { + for (i = 0; i < len2; i++) + { + fmpz_mul_2exp(temp, vec2 + i, exp); + fmpz_submul_ui(vec1 + i, temp, -c); + } + } + } + + fmpz_clear(temp); +} diff --git a/external/flint-2.4.3/fmpz_vec/scalar_divexact_fmpz.c b/external/flint-2.4.3/fmpz_vec/scalar_divexact_fmpz.c new file mode 100644 index 0000000..e3157ef --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/scalar_divexact_fmpz.c @@ -0,0 +1,53 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +void +_fmpz_vec_scalar_divexact_fmpz(fmpz * vec1, const fmpz * vec2, + slong len2, const fmpz_t x) +{ + fmpz c = *x; + + if (!COEFF_IS_MPZ(c)) + { + if (c == 1) + _fmpz_vec_set(vec1, vec2, len2); + else if (c == -1) + _fmpz_vec_neg(vec1, vec2, len2); + else + _fmpz_vec_scalar_divexact_si(vec1, vec2, len2, c); + } + else + { + slong i; + for (i = 0; i < len2; i++) + fmpz_divexact(vec1 + i, vec2 + i, x); + } +} diff --git a/external/flint-2.4.3/fmpz_vec/scalar_divexact_si.c b/external/flint-2.4.3/fmpz_vec/scalar_divexact_si.c new file mode 100644 index 0000000..e51ab2f --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/scalar_divexact_si.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +void +_fmpz_vec_scalar_divexact_si(fmpz * vec1, const fmpz * vec2, slong len2, slong c) +{ + slong i; + for (i = 0; i < len2; i++) + fmpz_divexact_si(vec1 + i, vec2 + i, c); +} diff --git a/external/flint-2.4.3/fmpz_vec/scalar_divexact_ui.c b/external/flint-2.4.3/fmpz_vec/scalar_divexact_ui.c new file mode 100644 index 0000000..8f6a5a3 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/scalar_divexact_ui.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +void +_fmpz_vec_scalar_divexact_ui(fmpz * vec1, const fmpz * vec2, + slong len2, ulong c) +{ + slong i; + for (i = 0; i < len2; i++) + fmpz_divexact_ui(vec1 + i, vec2 + i, c); +} diff --git a/external/flint-2.4.3/fmpz_vec/scalar_fdiv_q_2exp.c b/external/flint-2.4.3/fmpz_vec/scalar_fdiv_q_2exp.c new file mode 100644 index 0000000..daad6b5 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/scalar_fdiv_q_2exp.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +void +_fmpz_vec_scalar_fdiv_q_2exp(fmpz * vec1, const fmpz * vec2, slong len2, + ulong exp) +{ + slong i; + for (i = 0; i < len2; i++) + fmpz_fdiv_q_2exp(vec1 + i, vec2 + i, exp); +} diff --git a/external/flint-2.4.3/fmpz_vec/scalar_fdiv_q_fmpz.c b/external/flint-2.4.3/fmpz_vec/scalar_fdiv_q_fmpz.c new file mode 100644 index 0000000..8266a16 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/scalar_fdiv_q_fmpz.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +void +_fmpz_vec_scalar_fdiv_q_fmpz(fmpz * vec1, const fmpz * vec2, slong len2, + const fmpz_t c) +{ + slong i; + for (i = 0; i < len2; i++) + fmpz_fdiv_q(vec1 + i, vec2 + i, c); +} diff --git a/external/flint-2.4.3/fmpz_vec/scalar_fdiv_q_si.c b/external/flint-2.4.3/fmpz_vec/scalar_fdiv_q_si.c new file mode 100644 index 0000000..9f143d2 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/scalar_fdiv_q_si.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +void +_fmpz_vec_scalar_fdiv_q_si(fmpz * vec1, const fmpz * vec2, slong len2, slong c) +{ + slong i; + for (i = 0; i < len2; i++) + fmpz_fdiv_q_si(vec1 + i, vec2 + i, c); +} diff --git a/external/flint-2.4.3/fmpz_vec/scalar_fdiv_q_ui.c b/external/flint-2.4.3/fmpz_vec/scalar_fdiv_q_ui.c new file mode 100644 index 0000000..13530fb --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/scalar_fdiv_q_ui.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +void +_fmpz_vec_scalar_fdiv_q_ui(fmpz * vec1, const fmpz * vec2, slong len2, ulong c) +{ + slong i; + for (i = 0; i < len2; i++) + fmpz_fdiv_q_ui(vec1 + i, vec2 + i, c); +} diff --git a/external/flint-2.4.3/fmpz_vec/scalar_fdiv_r_2exp.c b/external/flint-2.4.3/fmpz_vec/scalar_fdiv_r_2exp.c new file mode 100644 index 0000000..53c67a8 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/scalar_fdiv_r_2exp.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +void +_fmpz_vec_scalar_fdiv_r_2exp(fmpz * vec1, const fmpz * vec2, slong len2, + ulong exp) +{ + slong i; + for (i = 0; i < len2; i++) + fmpz_fdiv_r_2exp(vec1 + i, vec2 + i, exp); +} + diff --git a/external/flint-2.4.3/fmpz_vec/scalar_mod_fmpz.c b/external/flint-2.4.3/fmpz_vec/scalar_mod_fmpz.c new file mode 100644 index 0000000..64600b2 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/scalar_mod_fmpz.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +void _fmpz_vec_scalar_mod_fmpz(fmpz *res, const fmpz *vec, slong len, const fmpz_t p) +{ + slong i; + + for (i = 0; i < len; i++) + fmpz_mod(res + i, vec + i, p); +} + diff --git a/external/flint-2.4.3/fmpz_vec/scalar_mul_2exp.c b/external/flint-2.4.3/fmpz_vec/scalar_mul_2exp.c new file mode 100644 index 0000000..ae8a5d4 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/scalar_mul_2exp.c @@ -0,0 +1,38 @@ +/*============================================================================ + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +===============================================================================*/ +/**************************************************************************** + + Copyright (C) 2010 William Hart + +*****************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +void +_fmpz_vec_scalar_mul_2exp(fmpz * vec1, const fmpz * vec2, slong len2, ulong exp) +{ + slong i; + + for (i = 0; i < len2; i++) + fmpz_mul_2exp(vec1 + i, vec2 + i, exp); +} diff --git a/external/flint-2.4.3/fmpz_vec/scalar_mul_fmpz.c b/external/flint-2.4.3/fmpz_vec/scalar_mul_fmpz.c new file mode 100644 index 0000000..de81a69 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/scalar_mul_fmpz.c @@ -0,0 +1,54 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +void +_fmpz_vec_scalar_mul_fmpz(fmpz * poly1, const fmpz * poly2, slong len2, + const fmpz_t x) +{ + fmpz c = *x; + + if (!COEFF_IS_MPZ(c)) + { + if (c == 0) + _fmpz_vec_zero(poly1, len2); + else if (c == 1) + _fmpz_vec_set(poly1, poly2, len2); + else if (c == -1) + _fmpz_vec_neg(poly1, poly2, len2); + else + _fmpz_vec_scalar_mul_si(poly1, poly2, len2, c); + } + else + { + slong i; + for (i = 0; i < len2; i++) + fmpz_mul(poly1 + i, poly2 + i, x); + } +} diff --git a/external/flint-2.4.3/fmpz_vec/scalar_mul_si.c b/external/flint-2.4.3/fmpz_vec/scalar_mul_si.c new file mode 100644 index 0000000..3d6ab52 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/scalar_mul_si.c @@ -0,0 +1,37 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +void +_fmpz_vec_scalar_mul_si(fmpz * vec1, const fmpz * vec2, slong len2, slong c) +{ + slong i; + for (i = 0; i < len2; i++) + fmpz_mul_si(vec1 + i, vec2 + i, c); +} diff --git a/external/flint-2.4.3/fmpz_vec/scalar_mul_ui.c b/external/flint-2.4.3/fmpz_vec/scalar_mul_ui.c new file mode 100644 index 0000000..d5fed38 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/scalar_mul_ui.c @@ -0,0 +1,37 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +void +_fmpz_vec_scalar_mul_ui(fmpz * vec1, const fmpz * vec2, slong len2, ulong c) +{ + slong i; + for (i = 0; i < len2; i++) + fmpz_mul_ui(vec1 + i, vec2 + i, c); +} diff --git a/external/flint-2.4.3/fmpz_vec/scalar_smod_fmpz.c b/external/flint-2.4.3/fmpz_vec/scalar_smod_fmpz.c new file mode 100644 index 0000000..e1b5c0f --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/scalar_smod_fmpz.c @@ -0,0 +1,51 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +void _fmpz_vec_scalar_smod_fmpz(fmpz *res, const fmpz *vec, slong len, const fmpz_t p) +{ + slong i; + fmpz_t pdiv2; + + fmpz_init(pdiv2); + fmpz_fdiv_q_2exp(pdiv2, p, 1); + + for (i = 0; i < len; i++) + { + fmpz_mod(res + i, vec + i, p); + + if (fmpz_cmp(res + i, pdiv2) > 0) + { + fmpz_sub(res + i, res + i, p); + } + } + + fmpz_clear(pdiv2); +} + diff --git a/external/flint-2.4.3/fmpz_vec/scalar_submul_fmpz.c b/external/flint-2.4.3/fmpz_vec/scalar_submul_fmpz.c new file mode 100644 index 0000000..7a22c3d --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/scalar_submul_fmpz.c @@ -0,0 +1,55 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +void +_fmpz_vec_scalar_submul_fmpz(fmpz * vec1, const fmpz * vec2, slong len2, + const fmpz_t x) +{ + fmpz c = *x; + + if (!COEFF_IS_MPZ(c)) + { + if (c == 0) + return; + else if (c == 1) + _fmpz_vec_sub(vec1, vec1, vec2, len2); + else if (c == -1) + _fmpz_vec_add(vec1, vec1, vec2, len2); + else + _fmpz_vec_scalar_submul_si(vec1, vec2, len2, c); + } + else + { + slong i; + for (i = 0; i < len2; i++) + fmpz_submul(vec1 + i, vec2 + i, x); + } +} diff --git a/external/flint-2.4.3/fmpz_vec/scalar_submul_si.c b/external/flint-2.4.3/fmpz_vec/scalar_submul_si.c new file mode 100644 index 0000000..cafbbe1 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/scalar_submul_si.c @@ -0,0 +1,43 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +void +_fmpz_vec_scalar_submul_si(fmpz * vec1, const fmpz * vec2, slong len2, slong c) +{ + slong i; + + if (c >= 0) + for (i = 0; i < len2; i++) + fmpz_submul_ui(vec1 + i, vec2 + i, c); + else + for (i = 0; i < len2; i++) + fmpz_addmul_ui(vec1 + i, vec2 + i, -c); +} diff --git a/external/flint-2.4.3/fmpz_vec/scalar_submul_si_2exp.c b/external/flint-2.4.3/fmpz_vec/scalar_submul_si_2exp.c new file mode 100644 index 0000000..33c4daf --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/scalar_submul_si_2exp.c @@ -0,0 +1,87 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +void +_fmpz_vec_scalar_submul_si_2exp(fmpz * vec1, const fmpz * vec2, slong len2, + slong c, ulong exp) +{ + slong i; + fmpz_t temp; + + if (c == 0) + return; /* nothing to add */ + + if (exp == 0) /* just do submul */ + { + _fmpz_vec_scalar_submul_si(vec1, vec2, len2, c); + return; + } + + fmpz_init(temp); + + if (c == 1) /* scalar is 1, just subtract c * 2^exp times c */ + { + for (i = 0; i < len2; i++) + { + fmpz_mul_2exp(temp, vec2 + i, exp); + fmpz_sub(vec1 + i, vec1 + i, temp); + } + } + else if (c == -1) /* scalar is -1, add c * 2^exp */ + { + for (i = 0; i < len2; i++) + { + fmpz_mul_2exp(temp, vec2 + i, exp); + fmpz_add(vec1 + i, vec1 + i, temp); + } + } + else /* generic case */ + { + if (c >= 0) + { + for (i = 0; i < len2; i++) + { + fmpz_mul_2exp(temp, vec2 + i, exp); + fmpz_submul_ui(vec1 + i, temp, c); + } + } + else + { + for (i = 0; i < len2; i++) + { + fmpz_mul_2exp(temp, vec2 + i, exp); + fmpz_addmul_ui(vec1 + i, temp, -c); + } + } + } + + fmpz_clear(temp); +} diff --git a/external/flint-2.4.3/fmpz_vec/scalar_tdiv_q_2exp.c b/external/flint-2.4.3/fmpz_vec/scalar_tdiv_q_2exp.c new file mode 100644 index 0000000..251ef49 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/scalar_tdiv_q_2exp.c @@ -0,0 +1,39 @@ +/*============================================================================ + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +===============================================================================*/ +/**************************************************************************** + + Copyright (C) 2010 William Hart + +*****************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +void +_fmpz_vec_scalar_tdiv_q_2exp(fmpz * vec1, const fmpz * vec2, slong len2, + ulong exp) +{ + slong i; + + for (i = 0; i < len2; i++) + fmpz_tdiv_q_2exp(vec1 + i, vec2 + i, exp); +} diff --git a/external/flint-2.4.3/fmpz_vec/scalar_tdiv_q_fmpz.c b/external/flint-2.4.3/fmpz_vec/scalar_tdiv_q_fmpz.c new file mode 100644 index 0000000..cb0d921 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/scalar_tdiv_q_fmpz.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +void +_fmpz_vec_scalar_tdiv_q_fmpz(fmpz * vec1, const fmpz * vec2, slong len2, + const fmpz_t c) +{ + slong i; + for (i = 0; i < len2; i++) + fmpz_tdiv_q(vec1 + i, vec2 + i, c); +} diff --git a/external/flint-2.4.3/fmpz_vec/scalar_tdiv_q_si.c b/external/flint-2.4.3/fmpz_vec/scalar_tdiv_q_si.c new file mode 100644 index 0000000..6f32040 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/scalar_tdiv_q_si.c @@ -0,0 +1,37 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +void +_fmpz_vec_scalar_tdiv_q_si(fmpz * vec1, const fmpz * vec2, slong len2, slong c) +{ + slong i; + for (i = 0; i < len2; i++) + fmpz_tdiv_q_si(vec1 + i, vec2 + i, c); +} diff --git a/external/flint-2.4.3/fmpz_vec/scalar_tdiv_q_ui.c b/external/flint-2.4.3/fmpz_vec/scalar_tdiv_q_ui.c new file mode 100644 index 0000000..4647280 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/scalar_tdiv_q_ui.c @@ -0,0 +1,37 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +void +_fmpz_vec_scalar_tdiv_q_ui(fmpz * vec1, const fmpz * vec2, slong len2, ulong c) +{ + slong i; + for (i = 0; i < len2; i++) + fmpz_tdiv_q_ui(vec1 + i, vec2 + i, c); +} diff --git a/external/flint-2.4.3/fmpz_vec/set.c b/external/flint-2.4.3/fmpz_vec/set.c new file mode 100644 index 0000000..3cbf24a --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/set.c @@ -0,0 +1,37 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +void +_fmpz_vec_set(fmpz * vec1, const fmpz * vec2, slong len2) +{ + slong i; + for (i = 0; i < len2; i++) + fmpz_set(vec1 + i, vec2 + i); +} diff --git a/external/flint-2.4.3/fmpz_vec/set_fft.c b/external/flint-2.4.3/fmpz_vec/set_fft.c new file mode 100644 index 0000000..adb5ca9 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/set_fft.c @@ -0,0 +1,84 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2008-2011 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" +#include "fft.h" + +void _fmpz_vec_set_fft(fmpz * coeffs_m, slong length, + const mp_ptr * coeffs_f, slong limbs, slong sign) +{ + slong i, size; + mp_limb_t * data; + __mpz_struct * mpz_ptr; + + if (sign) + { + for (i = 0; i < length; i++) + { + mpz_ptr = _fmpz_promote(coeffs_m); + if (mpz_ptr->_mp_alloc < limbs) _mpz_realloc(mpz_ptr, limbs); + data = mpz_ptr->_mp_d; + + if ((coeffs_f[i][limbs - 1] >> (FLINT_BITS - 1)) || coeffs_f[i][limbs]) + { + mpn_neg_n(data, coeffs_f[i], limbs); + mpn_add_1(data, data, limbs, WORD(1)); + size = limbs; + while ((size) && (data[size - 1] == 0)) size--; /* normalise */ + mpz_ptr->_mp_size = -size; + if (size >= WORD(-1)) _fmpz_demote_val(coeffs_m); /* coefficient may be small*/ + } else + { + flint_mpn_copyi(data, coeffs_f[i], limbs); + size = limbs; + while ((size) && (data[size - 1] == WORD(0))) size--; /* normalise */ + mpz_ptr->_mp_size = size; + if (size <= 1) _fmpz_demote_val(coeffs_m); /* coefficient may be small */ + } + + coeffs_m++; + } + } else + { + for (i = 0; i < length; i++) + { + mpz_ptr = _fmpz_promote(coeffs_m); + if (mpz_ptr->_mp_alloc < limbs) _mpz_realloc(mpz_ptr, limbs); + data = mpz_ptr->_mp_d; + flint_mpn_copyi(data, coeffs_f[i], limbs); + size = limbs; + while ((size) && (data[size - 1] == WORD(0))) size--; /* normalise */ + mpz_ptr->_mp_size = size; + if (size <= 1) _fmpz_demote_val(coeffs_m); /* coefficient may be small */ + + coeffs_m++; + } + } +} diff --git a/external/flint-2.4.3/fmpz_vec/set_nmod_vec.c b/external/flint-2.4.3/fmpz_vec/set_nmod_vec.c new file mode 100644 index 0000000..d6e30eb --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/set_nmod_vec.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" +#include "nmod_poly.h" + +void +_fmpz_vec_set_nmod_vec(fmpz * res, mp_srcptr poly, slong len, nmod_t mod) +{ + slong i; + + for (i = 0; i < len; i++) + fmpz_set_ui_smod(res + i, poly[i], mod.n); +} diff --git a/external/flint-2.4.3/fmpz_vec/sort.c b/external/flint-2.4.3/fmpz_vec/sort.c new file mode 100644 index 0000000..fc7e3fa --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/sort.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +#ifndef __compar_fn_t +typedef int (*__compar_fn_t) (__const void *, __const void *); +#endif + +void _fmpz_vec_sort(fmpz * vec, slong len) +{ + qsort(vec, len, sizeof(fmpz), (__compar_fn_t) fmpz_cmp); +} diff --git a/external/flint-2.4.3/fmpz_vec/sub.c b/external/flint-2.4.3/fmpz_vec/sub.c new file mode 100644 index 0000000..9d5fba6 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/sub.c @@ -0,0 +1,37 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +void +_fmpz_vec_sub(fmpz * res, const fmpz * vec1, const fmpz * vec2, slong len2) +{ + slong i; + for (i = 0; i < len2; i++) + fmpz_sub(res + i, vec1 + i, vec2 + i); +} diff --git a/external/flint-2.4.3/fmpz_vec/sum.c b/external/flint-2.4.3/fmpz_vec/sum.c new file mode 100644 index 0000000..4c68f98 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/sum.c @@ -0,0 +1,50 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +void +_fmpz_vec_sum(fmpz_t res, const fmpz * vec, slong len) +{ + if (len <= 1) + { + if (len == 1) + fmpz_set(res, vec); + else + fmpz_zero(res); + } + else + { + slong i; + + fmpz_add(res, vec, vec + 1); + + for (i = 2; i < len; i++) + fmpz_add(res, res, vec + i); + } +} diff --git a/external/flint-2.4.3/fmpz_vec/swap.c b/external/flint-2.4.3/fmpz_vec/swap.c new file mode 100644 index 0000000..d3fdadc --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/swap.c @@ -0,0 +1,37 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +void +_fmpz_vec_swap(fmpz * vec1, fmpz * vec2, slong len2) +{ + slong i; + for (i = 0; i < len2; i++) + fmpz_swap(vec1 + i, vec2 + i); +} diff --git a/external/flint-2.4.3/fmpz_vec/test/t-add.c b/external/flint-2.4.3/fmpz_vec/test/t-add.c new file mode 100644 index 0000000..5bd406d --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/test/t-add.c @@ -0,0 +1,107 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009, 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("add...."); + fflush(stdout); + + + + /* Check aliasing of a and c */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz *a, *b, *c; + slong len = n_randint(state, 100); + + a = _fmpz_vec_init(len); + b = _fmpz_vec_init(len); + c = _fmpz_vec_init(len); + _fmpz_vec_randtest(a, state, len, 200); + _fmpz_vec_randtest(b, state, len, 200); + + _fmpz_vec_add(c, a, b, len); + _fmpz_vec_add(a, a, b, len); + + result = (_fmpz_vec_equal(a, c, len)); + if (!result) + { + flint_printf("FAIL:\n"); + _fmpz_vec_print(a, len), flint_printf("\n\n"); + _fmpz_vec_print(c, len), flint_printf("\n\n"); + abort(); + } + + _fmpz_vec_clear(a, len); + _fmpz_vec_clear(b, len); + _fmpz_vec_clear(c, len); + } + + /* Check aliasing of b and c */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz *a, *b, *c; + slong len = n_randint(state, 100); + + a = _fmpz_vec_init(len); + b = _fmpz_vec_init(len); + c = _fmpz_vec_init(len); + _fmpz_vec_randtest(a, state, len, 200); + _fmpz_vec_randtest(b, state, len, 200); + + _fmpz_vec_add(c, a, b, len); + _fmpz_vec_add(b, a, b, len); + + result = (_fmpz_vec_equal(b, c, len)); + if (!result) + { + flint_printf("FAIL:\n"); + _fmpz_vec_print(b, len), flint_printf("\n\n"); + _fmpz_vec_print(c, len), flint_printf("\n\n"); + abort(); + } + + _fmpz_vec_clear(a, len); + _fmpz_vec_clear(b, len); + _fmpz_vec_clear(c, len); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_vec/test/t-content.c b/external/flint-2.4.3/fmpz_vec/test/t-content.c new file mode 100644 index 0000000..7d94d5f --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/test/t-content.c @@ -0,0 +1,85 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("content...."); + fflush(stdout); + + + + /* Check that content(a f) = abs(a) content(f) */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_t a, c, d; + fmpz *f; + slong len = n_randint(state, 100); + + fmpz_init(a); + fmpz_init(c); + fmpz_init(d); + f = _fmpz_vec_init(len); + _fmpz_vec_randtest(f, state, len, 200); + fmpz_randtest(a, state, 100); + + _fmpz_vec_content(c, f, len); + _fmpz_vec_scalar_mul_fmpz(f, f, len, a); + fmpz_abs(a, a); + fmpz_mul(c, a, c); + _fmpz_vec_content(d, f, len); + + result = (fmpz_equal(c, d)); + if (!result) + { + flint_printf("FAIL:\n"); + fmpz_print(c), flint_printf("\n\n"); + fmpz_print(d), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(a); + fmpz_clear(c); + fmpz_clear(d); + _fmpz_vec_clear(f, len); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_vec/test/t-get_set_fft.c b/external/flint-2.4.3/fmpz_vec/test/t-get_set_fft.c new file mode 100644 index 0000000..ee37e7a --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/test/t-get_set_fft.c @@ -0,0 +1,131 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009, 2011 William Hart + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fft.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("get/set_fft...."); + fflush(stdout); + + + + /* convert back and forth and compare */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz * a, * b; + mp_bitcnt_t bits; + slong len, limbs; + mp_limb_t ** ii, * ptr; + slong i, bt; + + bits = n_randint(state, 300) + 1; + len = n_randint(state, 300) + 1; + limbs = 2*((bits - 1)/FLINT_BITS + 1); + + ii = flint_malloc((len + len*(limbs + 1))*sizeof(mp_limb_t)); + ptr = (mp_limb_t *) ii + len; + for (i = 0; i < len; i++, ptr += (limbs + 1)) + ii[i] = ptr; + + a = _fmpz_vec_init(len); + b = _fmpz_vec_init(len); + _fmpz_vec_randtest(a, state, len, bits); + + bt = _fmpz_vec_get_fft(ii, a, limbs, len); + for (i = 0; i < len; i++) + mpn_normmod_2expp1(ii[i], limbs); + _fmpz_vec_set_fft(b, len, ii, limbs, bt < 0); + + result = (_fmpz_vec_equal(a, b, len)); + if (!result) + { + flint_printf("FAIL:\n"); + _fmpz_vec_print(a, len), flint_printf("\n\n"); + _fmpz_vec_print(b, len), flint_printf("\n\n"); + abort(); + } + + flint_free(ii); + _fmpz_vec_clear(a, len); + _fmpz_vec_clear(b, len); + } + + /* convert back and forth unsigned and compare */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz * a, * b; + mp_bitcnt_t bits; + slong len, limbs; + mp_limb_t ** ii, * ptr; + slong i, bt; + + bits = n_randint(state, 300) + 1; + len = n_randint(state, 300) + 1; + limbs = 2*((bits - 1)/FLINT_BITS + 1); + + ii = flint_malloc((len + len*(limbs + 1))*sizeof(mp_limb_t)); + ptr = (mp_limb_t *) ii + len; + for (i = 0; i < len; i++, ptr += (limbs + 1)) + ii[i] = ptr; + + a = _fmpz_vec_init(len); + b = _fmpz_vec_init(len); + _fmpz_vec_randtest_unsigned(a, state, len, bits); + + bt = _fmpz_vec_get_fft(ii, a, limbs, len); + _fmpz_vec_set_fft(b, len, ii, limbs, bt < 0); + + result = (_fmpz_vec_equal(a, b, len)); + if (!result) + { + flint_printf("FAIL:\n"); + _fmpz_vec_print(a, len), flint_printf("\n\n"); + _fmpz_vec_print(b, len), flint_printf("\n\n"); + abort(); + } + + flint_free(ii); + _fmpz_vec_clear(a, len); + _fmpz_vec_clear(b, len); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_vec/test/t-get_set_nmod_vec.c b/external/flint-2.4.3/fmpz_vec/test/t-get_set_nmod_vec.c new file mode 100644 index 0000000..5ae96a7 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/test/t-get_set_nmod_vec.c @@ -0,0 +1,96 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009, 2010 William Hart + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" +#include "nmod_vec.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("get/set_nmod_vec...."); + fflush(stdout); + + + + /* Check conversion to and from nmod_vec */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz *a, *b; + mp_ptr c; + nmod_t mod; + slong i; + mp_limb_t t; + + slong len = n_randint(state, 100); + mp_limb_t n = n_randtest_not_zero(state); + + a = _fmpz_vec_init(len); + b = _fmpz_vec_init(len); + c = _nmod_vec_init(len); + + nmod_init(&mod, n); + + _fmpz_vec_randtest(a, state, len, 200); + + _fmpz_vec_get_nmod_vec(c, a, len, mod); + _fmpz_vec_set_nmod_vec(b, c, len, mod); + + for (i = 0; i < len; i++) + { + fmpz_mod_ui(a + i, a + i, n); + t = fmpz_get_ui(a + i); + if (t > n / 2) + fmpz_sub_ui(a + i, a + i, n); + } + + result = (_fmpz_vec_equal(a, b, len)); + if (!result) + { + flint_printf("FAIL:\n"); + _fmpz_vec_print(a, len), flint_printf("\n\n"); + _fmpz_vec_print(b, len), flint_printf("\n\n"); + abort(); + } + + _fmpz_vec_clear(a, len); + _fmpz_vec_clear(b, len); + _nmod_vec_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_vec/test/t-height.c b/external/flint-2.4.3/fmpz_vec/test/t-height.c new file mode 100644 index 0000000..5caf3c4 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/test/t-height.c @@ -0,0 +1,83 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("height...."); + fflush(stdout); + + + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz *a; + fmpz_t h; + slong len, bits, bits2; + + fmpz_init(h); + + len = n_randint(state, 100); + + a = _fmpz_vec_init(len); + bits = n_randint(state, 200); + _fmpz_vec_randtest(a, state, len, bits); + + bits2 = _fmpz_vec_max_bits(a, len); + _fmpz_vec_height(h, a, len); + + result = (fmpz_bits(h) == FLINT_ABS(bits2)) && (fmpz_sgn(h) >= 0); + + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("bits = %wd, bits2 = %wd\n", bits, bits2); + flint_printf("Computed height:\n"); + fmpz_print(h); + flint_printf("\n"); + abort(); + } + + fmpz_clear(h); + _fmpz_vec_clear(a, len); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_vec/test/t-height_index.c b/external/flint-2.4.3/fmpz_vec/test/t-height_index.c new file mode 100644 index 0000000..89b2bce --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/test/t-height_index.c @@ -0,0 +1,87 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2012 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" + +static slong +refimpl(const fmpz * v, slong len) +{ + slong i, max = 0; + + for (i = 1; i < len; i++) + if (fmpz_cmpabs(v + i, v + max) > 0) + max = i; + + return max; +} + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("height_index...."); + fflush(stdout); + + + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz *a; + slong len, bits, p1, p2; + + len = 1 + n_randint(state, 100); + + a = _fmpz_vec_init(len); + bits = n_randint(state, 200); + _fmpz_vec_randtest(a, state, len, bits); + + p1 = _fmpz_vec_height_index(a, len); + p2 = refimpl(a, len); + + result = (p1 == p2); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("bits = %wd, p1 = %wd, p2 = %wd\n", bits, p1, p2); + abort(); + } + + _fmpz_vec_clear(a, len); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_vec/test/t-init_clear.c b/external/flint-2.4.3/fmpz_vec/test/t-init_clear.c new file mode 100644 index 0000000..b427be9 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/test/t-init_clear.c @@ -0,0 +1,61 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + flint_printf("init/clear...."); + fflush(stdout); + + + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz *a; + slong j, len = n_randint(state, 100) + 1; + + a = _fmpz_vec_init(len); + for (j = 0; j < len; j++) + fmpz_zero(a + j); + + _fmpz_vec_clear(a, len); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_vec/test/t-is_zero.c b/external/flint-2.4.3/fmpz_vec/test/t-is_zero.c new file mode 100644 index 0000000..02a4c9f --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/test/t-is_zero.c @@ -0,0 +1,92 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009, 2010 William Hart + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("is_zero...."); + fflush(stdout); + + + + /* Check zero vector */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz *a; + slong len = n_randint(state, 100); + + a = _fmpz_vec_init(len); + _fmpz_vec_randtest(a, state, len, 200); + _fmpz_vec_zero(a, len); + + result = (_fmpz_vec_is_zero(a, len)); + if (!result) + { + flint_printf("FAIL1:\n"); + _fmpz_vec_print(a, len), flint_printf("\n\n"); + abort(); + } + + _fmpz_vec_clear(a, len); + } + + /* Check non-zero vector */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz *a; + slong len = n_randint(state, 100) + 1; + + a = _fmpz_vec_init(len); + _fmpz_vec_randtest(a, state, len, 200); + fmpz_set_ui(a + (len - 1), UWORD(1)); + + result = (!_fmpz_vec_is_zero(a, len)); + if (!result) + { + flint_printf("FAIL2:\n"); + _fmpz_vec_print(a, len), flint_printf("\n\n"); + abort(); + } + + _fmpz_vec_clear(a, len); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_vec/test/t-lcm.c b/external/flint-2.4.3/fmpz_vec/test/t-lcm.c new file mode 100644 index 0000000..840e110 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/test/t-lcm.c @@ -0,0 +1,93 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("lcm...."); + fflush(stdout); + + + + /* Check that lcm(a f) = abs(a) lcm(f) */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_t a, c, d; + fmpz *f; + slong len = n_randint(state, 100); + + fmpz_init(a); + fmpz_init(c); + fmpz_init(d); + f = _fmpz_vec_init(len); + _fmpz_vec_randtest(f, state, len, 200); + fmpz_randtest(a, state, 100); + + _fmpz_vec_lcm(c, f, len); + + if (len == 0) + { + result = fmpz_is_one(c); + } + else + { + _fmpz_vec_scalar_mul_fmpz(f, f, len, a); + fmpz_abs(a, a); + fmpz_mul(c, a, c); + _fmpz_vec_lcm(d, f, len); + result = (fmpz_equal(c, d)); + } + + if (!result) + { + fmpz_print(c), flint_printf("\n\n"); + fmpz_print(d), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(a); + fmpz_clear(c); + fmpz_clear(d); + _fmpz_vec_clear(f, len); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_vec/test/t-max_bits.c b/external/flint-2.4.3/fmpz_vec/test/t-max_bits.c new file mode 100644 index 0000000..2ec24d9 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/test/t-max_bits.c @@ -0,0 +1,74 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("max_bits...."); + fflush(stdout); + + + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz *a; + slong len, bits, bits2, bits3; + + len = n_randint(state, 100); + + a = _fmpz_vec_init(len); + bits = n_randint(state, 200); + _fmpz_vec_randtest(a, state, len, bits); + + bits2 = _fmpz_vec_max_bits(a, len); + bits3 = _fmpz_vec_max_bits_ref(a, len); + + result = (bits >= FLINT_ABS(bits2) && bits2 == bits3); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("bits = %wd, bits2 = %wd bits3 = %wd\n", bits, bits2, bits3); + abort(); + } + + _fmpz_vec_clear(a, len); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_vec/test/t-max_limbs.c b/external/flint-2.4.3/fmpz_vec/test/t-max_limbs.c new file mode 100644 index 0000000..3e58cb6 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/test/t-max_limbs.c @@ -0,0 +1,79 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("max_limbs...."); + fflush(stdout); + + + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz *a; + slong len, bits; + mp_size_t limbs, limbs2; + + len = n_randint(state, 100); + + a = _fmpz_vec_init(len); + bits = n_randint(state, 200); + limbs = (bits + FLINT_BITS - 1) / FLINT_BITS; + _fmpz_vec_randtest(a, state, len, bits); + + limbs2 = _fmpz_vec_max_limbs(a, len); + + result = (limbs >= limbs2); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("bits = %wd\n", bits); + flint_printf("limbs = %wd\n", limbs); + flint_printf("a = {"), _fmpz_vec_print(a, len), flint_printf("}\n"); + flint_printf("limbs2 = %wd\n", limbs2); + abort(); + } + + _fmpz_vec_clear(a, len); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_vec/test/t-neg.c b/external/flint-2.4.3/fmpz_vec/test/t-neg.c new file mode 100644 index 0000000..52ee0c8 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/test/t-neg.c @@ -0,0 +1,101 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009, 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("neg...."); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz *a, *b; + slong len = n_randint(state, 100); + + a = _fmpz_vec_init(len); + b = _fmpz_vec_init(len); + _fmpz_vec_randtest(a, state, len, 200); + + _fmpz_vec_neg(b, a, len); + _fmpz_vec_neg(a, a, len); + + result = (_fmpz_vec_equal(a, b, len)); + if (!result) + { + flint_printf("FAIL:\n"); + _fmpz_vec_print(a, len), flint_printf("\n\n"); + _fmpz_vec_print(b, len), flint_printf("\n\n"); + abort(); + } + + _fmpz_vec_clear(a, len); + _fmpz_vec_clear(b, len); + } + + /* Check -(-a) == a */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz *a, *b; + slong len = n_randint(state, 100); + + a = _fmpz_vec_init(len); + b = _fmpz_vec_init(len); + _fmpz_vec_randtest(a, state, len, 200); + + _fmpz_vec_neg(b, a, len); + _fmpz_vec_neg(b, b, len); + + result = (_fmpz_vec_equal(a, b, len)); + if (!result) + { + flint_printf("FAIL:\n"); + _fmpz_vec_print(a, len), flint_printf("\n\n"); + _fmpz_vec_print(b, len), flint_printf("\n\n"); + abort(); + } + + _fmpz_vec_clear(a, len); + _fmpz_vec_clear(b, len); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_vec/test/t-prod.c b/external/flint-2.4.3/fmpz_vec/test/t-prod.c new file mode 100644 index 0000000..98b7293 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/test/t-prod.c @@ -0,0 +1,88 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009, 2010 William Hart + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("prod...."); + fflush(stdout); + + + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz *a, *b; + fmpz_t x, y, z; + + slong len1 = n_randint(state, 100); + slong len2 = n_randint(state, 100); + + a = _fmpz_vec_init(len1 + len2); + b = a + len1; + + _fmpz_vec_randtest(a, state, len1 + len2, 200); + + fmpz_init(x); + fmpz_init(y); + fmpz_init(z); + + _fmpz_vec_prod(x, a, len1); + _fmpz_vec_prod(y, b, len2); + fmpz_mul(x, x, y); + _fmpz_vec_prod(z, a, len1 + len2); + + result = (fmpz_equal(x, z)); + if (!result) + { + flint_printf("FAIL:\n"); + _fmpz_vec_print(a, len1), flint_printf("\n\n"); + _fmpz_vec_print(b, len2), flint_printf("\n\n"); + abort(); + } + + _fmpz_vec_clear(a, len1 + len2); + + fmpz_clear(x); + fmpz_clear(y); + fmpz_clear(z); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_vec/test/t-scalar_addmul_fmpz.c b/external/flint-2.4.3/fmpz_vec/test/t-scalar_addmul_fmpz.c new file mode 100644 index 0000000..d8f8b69 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/test/t-scalar_addmul_fmpz.c @@ -0,0 +1,124 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009, 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("scalar_addmul_fmpz...."); + fflush(stdout); + + + + /* Compare with fmpz_vec_scalar_addmul_si */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz *a, *b, *c; + fmpz_t n1; + slong len, n; + len = n_randint(state, 100); + n = (slong) n_randbits(state, FLINT_BITS - 1); + if (n_randint(state, 2)) + n = -n; + fmpz_init(n1); + fmpz_set_si(n1, n); + + a = _fmpz_vec_init(len); + b = _fmpz_vec_init(len); + c = _fmpz_vec_init(len); + _fmpz_vec_randtest(a, state, len, 200); + _fmpz_vec_randtest(b, state, len, 200); + _fmpz_vec_set(c, b, len); + + _fmpz_vec_scalar_addmul_fmpz(b, a, len, n1); + _fmpz_vec_scalar_addmul_si(c, a, len, n); + + result = (_fmpz_vec_equal(c, b, len)); + if (!result) + { + flint_printf("FAIL:\n"); + _fmpz_vec_print(c, len), flint_printf("\n\n"); + _fmpz_vec_print(b, len), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(n1); + _fmpz_vec_clear(a, len); + _fmpz_vec_clear(b, len); + _fmpz_vec_clear(c, len); + } + + /* Compute a different way */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz *a, *b, *c, *d; + slong len = n_randint(state, 100); + fmpz_t n1; + fmpz_init(n1); + fmpz_randtest(n1, state, 200); + + a = _fmpz_vec_init(len); + b = _fmpz_vec_init(len); + c = _fmpz_vec_init(len); + d = _fmpz_vec_init(len); + _fmpz_vec_randtest(a, state, len, 200); + _fmpz_vec_randtest(b, state, len, 200); + _fmpz_vec_set(c, b, len); + + _fmpz_vec_scalar_addmul_fmpz(b, a, len, n1); + _fmpz_vec_scalar_mul_fmpz(d, a, len, n1); + _fmpz_vec_add(c, c, d, len); + + result = (_fmpz_vec_equal(c, b, len)); + if (!result) + { + flint_printf("FAIL:\n"); + _fmpz_vec_print(c, len), flint_printf("\n\n"); + _fmpz_vec_print(b, len), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(n1); + _fmpz_vec_clear(a, len); + _fmpz_vec_clear(b, len); + _fmpz_vec_clear(c, len); + _fmpz_vec_clear(d, len); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_vec/test/t-scalar_addmul_si.c b/external/flint-2.4.3/fmpz_vec/test/t-scalar_addmul_si.c new file mode 100644 index 0000000..4d5a3ca --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/test/t-scalar_addmul_si.c @@ -0,0 +1,90 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("scalar_addmul_si...."); + fflush(stdout); + + + + /* Compare with alternative method of computation */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz *a, *b, *c, *d; + slong len, x; + + len = n_randint(state, 100); + + a = _fmpz_vec_init(len); + b = _fmpz_vec_init(len); + c = _fmpz_vec_init(len); + d = _fmpz_vec_init(len); + + _fmpz_vec_randtest(a, state, len, 200); + _fmpz_vec_randtest(b, state, len, 200); + _fmpz_vec_set(c, b, len); + + x = z_randtest(state); + + _fmpz_vec_scalar_addmul_si(b, a, len, x); + _fmpz_vec_scalar_mul_si(d, a, len, x); + _fmpz_vec_add(c, c, d, len); + + result = (_fmpz_vec_equal(b, c, len)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("x = %wd\n", x); + _fmpz_vec_print(b, len), flint_printf("\n\n"); + _fmpz_vec_print(c, len), flint_printf("\n\n"); + abort(); + } + + _fmpz_vec_clear(a, len); + _fmpz_vec_clear(b, len); + _fmpz_vec_clear(c, len); + _fmpz_vec_clear(d, len); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_vec/test/t-scalar_addmul_si_2exp.c b/external/flint-2.4.3/fmpz_vec/test/t-scalar_addmul_si_2exp.c new file mode 100644 index 0000000..cdc8504 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/test/t-scalar_addmul_si_2exp.c @@ -0,0 +1,91 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("scalar_addmul_si_2exp...."); + fflush(stdout); + + + + /* Compare with alternative method of computation */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz *a, *b, *c, *d; + slong len, x; + mp_bitcnt_t exp; + + len = n_randint(state, 100); + + a = _fmpz_vec_init(len); + b = _fmpz_vec_init(len); + c = _fmpz_vec_init(len); + d = _fmpz_vec_init(len); + + _fmpz_vec_randtest(a, state, len, 200); + _fmpz_vec_randtest(b, state, len, 200); + _fmpz_vec_set(c, b, len); + + x = z_randtest(state); + exp = n_randint(state, 200); + + _fmpz_vec_scalar_addmul_si_2exp(b, a, len, x, exp); + _fmpz_vec_scalar_mul_2exp(d, a, len, exp); + _fmpz_vec_scalar_addmul_si(c, d, len, x); + + result = (_fmpz_vec_equal(b, c, len)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("x = %wd, exp = %wu\n", x, exp); + _fmpz_vec_print(b, len), flint_printf("\n\n"); + _fmpz_vec_print(c, len), flint_printf("\n\n"); + abort(); + } + + _fmpz_vec_clear(a, len); + _fmpz_vec_clear(b, len); + _fmpz_vec_clear(c, len); + _fmpz_vec_clear(d, len); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_vec/test/t-scalar_divexact_fmpz.c b/external/flint-2.4.3/fmpz_vec/test/t-scalar_divexact_fmpz.c new file mode 100644 index 0000000..22dbca7 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/test/t-scalar_divexact_fmpz.c @@ -0,0 +1,116 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009, 2010 William Hart + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("scalar_divexact_fmpz...."); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz *a, *b; + fmpz_t n; + slong len = n_randint(state, 100); + fmpz_init(n); + fmpz_randtest_not_zero(n, state, 100); + if (n_randint(state, 2)) + fmpz_neg(n, n); + + a = _fmpz_vec_init(len); + b = _fmpz_vec_init(len); + _fmpz_vec_randtest(a, state, len, 200); + + _fmpz_vec_scalar_mul_fmpz(a, a, len, n); + _fmpz_vec_scalar_divexact_fmpz(b, a, len, n); + _fmpz_vec_scalar_divexact_fmpz(a, a, len, n); + + result = (_fmpz_vec_equal(a, b, len)); + if (!result) + { + flint_printf("FAIL:\n"); + _fmpz_vec_print(a, len), flint_printf("\n\n"); + _fmpz_vec_print(b, len), flint_printf("\n\n"); + abort(); + } + + _fmpz_vec_clear(a, len); + _fmpz_vec_clear(b, len); + fmpz_clear(n); + } + + /* Check that a * n / n == a */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz *a, *b; + fmpz_t n; + slong len = n_randint(state, 100); + fmpz_init(n); + fmpz_randtest_not_zero(n, state, 100); + if (n_randint(state, 2)) + fmpz_neg(n, n); + + a = _fmpz_vec_init(len); + b = _fmpz_vec_init(len); + _fmpz_vec_randtest(a, state, len, 200); + + _fmpz_vec_set(b, a, len); + _fmpz_vec_scalar_mul_fmpz(a, a, len, n); + _fmpz_vec_scalar_divexact_fmpz(a, a, len, n); + + result = (_fmpz_vec_equal(a, b, len)); + if (!result) + { + flint_printf("FAIL:\n"); + _fmpz_vec_print(a, len), flint_printf("\n\n"); + _fmpz_vec_print(b, len), flint_printf("\n\n"); + abort(); + } + + _fmpz_vec_clear(a, len); + _fmpz_vec_clear(b, len); + fmpz_clear(n); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_vec/test/t-scalar_divexact_si.c b/external/flint-2.4.3/fmpz_vec/test/t-scalar_divexact_si.c new file mode 100644 index 0000000..6b0b99e --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/test/t-scalar_divexact_si.c @@ -0,0 +1,110 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("scalar_divexact_si...."); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz *a, *b; + slong len = n_randint(state, 100); + slong n; + + n = z_randtest_not_zero(state); + + a = _fmpz_vec_init(len); + b = _fmpz_vec_init(len); + _fmpz_vec_randtest(a, state, len, 200); + + _fmpz_vec_scalar_mul_si(a, a, len, n); + _fmpz_vec_scalar_divexact_si(b, a, len, n); + _fmpz_vec_scalar_divexact_si(a, a, len, n); + + result = (_fmpz_vec_equal(a, b, len)); + if (!result) + { + flint_printf("FAIL:\n"); + _fmpz_vec_print(a, len), flint_printf("\n\n"); + _fmpz_vec_print(b, len), flint_printf("\n\n"); + abort(); + } + + _fmpz_vec_clear(a, len); + _fmpz_vec_clear(b, len); + } + + /* Check that a * n / n == a */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz *a, *b; + slong len = n_randint(state, 100); + slong n; + + n = z_randtest_not_zero(state); + + a = _fmpz_vec_init(len); + b = _fmpz_vec_init(len); + _fmpz_vec_randtest(a, state, len, 200); + + _fmpz_vec_set(b, a, len); + _fmpz_vec_scalar_mul_si(a, a, len, n); + _fmpz_vec_scalar_divexact_si(a, a, len, n); + + result = (_fmpz_vec_equal(a, b, len)); + if (!result) + { + flint_printf("FAIL:\n"); + _fmpz_vec_print(a, len), flint_printf("\n\n"); + _fmpz_vec_print(b, len), flint_printf("\n\n"); + abort(); + } + + _fmpz_vec_clear(a, len); + _fmpz_vec_clear(b, len); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_vec/test/t-scalar_divexact_ui.c b/external/flint-2.4.3/fmpz_vec/test/t-scalar_divexact_ui.c new file mode 100644 index 0000000..c09f107 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/test/t-scalar_divexact_ui.c @@ -0,0 +1,105 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("scalar_divexact_ui...."); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz *a, *b; + ulong n = n_randtest_not_zero(state); + slong len = n_randint(state, 100); + + a = _fmpz_vec_init(len); + b = _fmpz_vec_init(len); + _fmpz_vec_randtest(a, state, len, 200); + + _fmpz_vec_scalar_mul_ui(a, a, len, n); + _fmpz_vec_scalar_divexact_ui(b, a, len, n); + _fmpz_vec_scalar_divexact_ui(a, a, len, n); + + result = (_fmpz_vec_equal(a, b, len)); + if (!result) + { + flint_printf("FAIL:\n"); + _fmpz_vec_print(a, len), flint_printf("\n\n"); + _fmpz_vec_print(b, len), flint_printf("\n\n"); + abort(); + } + + _fmpz_vec_clear(a, len); + _fmpz_vec_clear(b, len); + } + + /* Check that a * n / n == a */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz *a, *b; + ulong n = n_randtest_not_zero(state); + slong len = n_randint(state, 100); + + a = _fmpz_vec_init(len); + b = _fmpz_vec_init(len); + _fmpz_vec_randtest(a, state, len, 200); + + _fmpz_vec_set(b, a, len); + _fmpz_vec_scalar_mul_ui(a, a, len, n); + _fmpz_vec_scalar_divexact_ui(a, a, len, n); + + result = (_fmpz_vec_equal(a, b, len)); + if (!result) + { + flint_printf("FAIL:\n"); + _fmpz_vec_print(a, len), flint_printf("\n\n"); + _fmpz_vec_print(b, len), flint_printf("\n\n"); + abort(); + } + + _fmpz_vec_clear(a, len); + _fmpz_vec_clear(b, len); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_vec/test/t-scalar_fdiv_q_fmpz.c b/external/flint-2.4.3/fmpz_vec/test/t-scalar_fdiv_q_fmpz.c new file mode 100644 index 0000000..32d09c9 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/test/t-scalar_fdiv_q_fmpz.c @@ -0,0 +1,163 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009, 2010 William Hart + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("scalar_fdiv_q_fmpz...."); + fflush(stdout); + + + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz *a, *b, *c; + fmpz_t n; + mpz_t d, e, f, m; + slong i; + slong len = n_randint(state, 100); + + fmpz_init(n); + fmpz_randtest_not_zero(n, state, 100); + if (n_randint(state, 2)) + fmpz_neg(n, n); + + a = _fmpz_vec_init(len); + b = _fmpz_vec_init(len); + c = _fmpz_vec_init(len); + + _fmpz_vec_randtest(a, state, len, 200); + + _fmpz_vec_set(b, a, len); + + _fmpz_vec_scalar_fdiv_q_fmpz(c, a, len, n); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(m); + + for (i = 0; i < len; i++) + { + fmpz_get_mpz(m, n); + fmpz_get_mpz(d, b + i); + + mpz_fdiv_q(e, d, m); + + fmpz_get_mpz(f, c + i); + + result = (mpz_cmp(f, e) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, m = %Zd, e = %Zd, f = %Zd\n", d, m, e, f); + abort(); + } + } + + _fmpz_vec_clear(a, len); + _fmpz_vec_clear(b, len); + _fmpz_vec_clear(c, len); + + fmpz_clear(n); + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(m); + } + + /* Test aliasing of a and c */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz *a, *b; + fmpz_t n; + mpz_t d, e, f, m; + slong i; + slong len = n_randint(state, 100); + + fmpz_init(n); + fmpz_randtest_not_zero(n, state, 100); + if (n_randint(state, 2)) + fmpz_neg(n, n); + + a = _fmpz_vec_init(len); + b = _fmpz_vec_init(len); + + _fmpz_vec_randtest(a, state, len, 200); + + _fmpz_vec_set(b, a, len); + + _fmpz_vec_scalar_fdiv_q_fmpz(a, a, len, n); + + mpz_init(d); + mpz_init(e); + mpz_init(f); + mpz_init(m); + + for (i = 0; i < len; i++) + { + fmpz_get_mpz(m, n); + fmpz_get_mpz(d, b + i); + + mpz_fdiv_q(e, d, m); + + fmpz_get_mpz(f, a + i); + + result = (mpz_cmp(f, e) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("d = %Zd, m = %Zd, e = %Zd, f = %Zd\n", d, m, e, f); + abort(); + } + } + + _fmpz_vec_clear(a, len); + _fmpz_vec_clear(b, len); + + fmpz_clear(n); + mpz_clear(d); + mpz_clear(e); + mpz_clear(f); + mpz_clear(m); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_vec/test/t-scalar_mod_fmpz.c b/external/flint-2.4.3/fmpz_vec/test/t-scalar_mod_fmpz.c new file mode 100644 index 0000000..25dcfea --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/test/t-scalar_mod_fmpz.c @@ -0,0 +1,116 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("scalar_mod_fmpz...."); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_t p; + fmpz *a, *b; + slong len = n_randint(state, 100); + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 100); + fmpz_add_ui(p, p, 1); + + a = _fmpz_vec_init(len); + b = _fmpz_vec_init(len); + _fmpz_vec_randtest(a, state, len, 200); + + _fmpz_vec_scalar_mod_fmpz(b, a, len, p); + _fmpz_vec_scalar_mod_fmpz(a, a, len, p); + + result = (_fmpz_vec_equal(a, a, len)); + if (!result) + { + flint_printf("FAIL:\n"); + _fmpz_vec_print(a, len), flint_printf("\n\n"); + _fmpz_vec_print(b, len), flint_printf("\n\n"); + abort(); + } + + _fmpz_vec_clear(a, len); + _fmpz_vec_clear(b, len); + fmpz_clear(p); + } + + /* Check the result is reduced */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_t p; + fmpz *a, *b; + slong j, len = n_randint(state, 100); + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 100); + fmpz_add_ui(p, p, 1); + + a = _fmpz_vec_init(len); + b = _fmpz_vec_init(len); + _fmpz_vec_randtest(a, state, len, 200); + + _fmpz_vec_scalar_mod_fmpz(b, a, len, p); + + result = 1; + for (j = 0; j < len; j++) + result &= (fmpz_sgn(b + j) >= 0 && fmpz_cmp(b + j, p) < 0); + + if (!result) + { + flint_printf("FAIL:\n"); + _fmpz_vec_print(a, len), flint_printf("\n\n"); + _fmpz_vec_print(b, len), flint_printf("\n\n"); + fmpz_print(p), flint_printf("\n\n"); + abort(); + } + + _fmpz_vec_clear(a, len); + _fmpz_vec_clear(b, len); + fmpz_clear(p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_vec/test/t-scalar_mul_2exp.c b/external/flint-2.4.3/fmpz_vec/test/t-scalar_mul_2exp.c new file mode 100644 index 0000000..a80c32d --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/test/t-scalar_mul_2exp.c @@ -0,0 +1,107 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009, 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("scalar_mul_2exp...."); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz *a, *b; + slong len = n_randint(state, 100); + ulong exp = n_randint(state, 200); + + a = _fmpz_vec_init(len); + b = _fmpz_vec_init(len); + _fmpz_vec_randtest(a, state, len, 200); + + _fmpz_vec_scalar_mul_2exp(b, a, len, exp); + _fmpz_vec_scalar_mul_2exp(a, a, len, exp); + + result = (_fmpz_vec_equal(a, b, len)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("exp = %wu\n", exp); + _fmpz_vec_print(a, len), flint_printf("\n\n"); + _fmpz_vec_print(b, len), flint_printf("\n\n"); + abort(); + } + + _fmpz_vec_clear(a, len); + _fmpz_vec_clear(b, len); + } + + /* Check aliasing of (a*2^e1)*2^e2 equals a*2^(e1+e2) */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz *a, *b; + slong len = n_randint(state, 100); + ulong e1 = n_randint(state, 200); + ulong e2 = n_randint(state, 200); + + a = _fmpz_vec_init(len); + b = _fmpz_vec_init(len); + _fmpz_vec_randtest(a, state, len, 200); + + _fmpz_vec_scalar_mul_2exp(b, a, len, e1); + _fmpz_vec_scalar_mul_2exp(b, b, len, e2); + _fmpz_vec_scalar_mul_2exp(a, a, len, e1 + e2); + + result = (_fmpz_vec_equal(a, b, len)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("e1 = %wu, e2 = %wu\n", e1, e2); + _fmpz_vec_print(a, len), flint_printf("\n\n"); + _fmpz_vec_print(b, len), flint_printf("\n\n"); + abort(); + } + + _fmpz_vec_clear(a, len); + _fmpz_vec_clear(b, len); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_vec/test/t-scalar_mul_fmpz.c b/external/flint-2.4.3/fmpz_vec/test/t-scalar_mul_fmpz.c new file mode 100644 index 0000000..6248590 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/test/t-scalar_mul_fmpz.c @@ -0,0 +1,165 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009, 2010 William Hart + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("scalar_mul_fmpz...."); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz *a, *b; + fmpz_t n; + slong len = n_randint(state, 100); + fmpz_init(n); + fmpz_randtest(n, state, 100); + if (n_randint(state, 2)) + fmpz_neg(n, n); + + a = _fmpz_vec_init(len); + b = _fmpz_vec_init(len); + _fmpz_vec_randtest(a, state, len, 200); + + _fmpz_vec_scalar_mul_fmpz(b, a, len, n); + _fmpz_vec_scalar_mul_fmpz(a, a, len, n); + + result = (_fmpz_vec_equal(a, b, len)); + if (!result) + { + flint_printf("FAIL:\n"); + _fmpz_vec_print(a, len), flint_printf("\n\n"); + _fmpz_vec_print(b, len), flint_printf("\n\n"); + abort(); + } + + _fmpz_vec_clear(a, len); + _fmpz_vec_clear(b, len); + fmpz_clear(n); + } + + /* Check that n (a + b) == na + nb */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz *a, *b, *lhs, *rhs; + fmpz_t n; + slong len = n_randint(state, 100); + fmpz_init(n); + fmpz_randtest(n, state, 100); + if (n_randint(state, 2)) + fmpz_neg(n, n); + + a = _fmpz_vec_init(len); + b = _fmpz_vec_init(len); + lhs = _fmpz_vec_init(len); + rhs = _fmpz_vec_init(len); + _fmpz_vec_randtest(a, state, len, 200); + _fmpz_vec_randtest(b, state, len, 200); + + _fmpz_vec_scalar_mul_fmpz(lhs, a, len, n); + _fmpz_vec_scalar_mul_fmpz(rhs, b, len, n); + _fmpz_vec_add(rhs, lhs, rhs, len); + _fmpz_vec_add(lhs, a, b, len); + _fmpz_vec_scalar_mul_fmpz(lhs, lhs, len, n); + + result = (_fmpz_vec_equal(lhs, rhs, len)); + if (!result) + { + flint_printf("FAIL:\n"); + _fmpz_vec_print(a, len), flint_printf("\n\n"); + _fmpz_vec_print(b, len), flint_printf("\n\n"); + _fmpz_vec_print(lhs, len), flint_printf("\n\n"); + _fmpz_vec_print(rhs, len), flint_printf("\n\n"); + abort(); + } + + _fmpz_vec_clear(a, len); + _fmpz_vec_clear(b, len); + _fmpz_vec_clear(lhs, len); + _fmpz_vec_clear(rhs, len); + fmpz_clear(n); + } + + /* Check that n2 * (n1 a) == (n1 * n2) a */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz *a, *b; + fmpz_t n1, n2, n; + slong len = n_randint(state, 100); + fmpz_init(n1); + fmpz_init(n2); + fmpz_init(n); + fmpz_randtest(n1, state, 100); + fmpz_randtest(n2, state, 100); + if (n_randint(state, 2)) + fmpz_neg(n1, n1); + if (n_randint(state, 2)) + fmpz_neg(n2, n2); + + a = _fmpz_vec_init(len); + b = _fmpz_vec_init(len); + _fmpz_vec_randtest(a, state, len, 200); + + _fmpz_vec_scalar_mul_fmpz(b, a, len, n1); + _fmpz_vec_scalar_mul_fmpz(b, b, len, n2); + fmpz_mul(n, n1, n2); + _fmpz_vec_scalar_mul_fmpz(a, a, len, n); + + result = (_fmpz_vec_equal(a, b, len)); + if (!result) + { + flint_printf("FAIL:\n"); + _fmpz_vec_print(a, len), flint_printf("\n\n"); + _fmpz_vec_print(b, len), flint_printf("\n\n"); + abort(); + } + + _fmpz_vec_clear(a, len); + _fmpz_vec_clear(b, len); + fmpz_clear(n1); + fmpz_clear(n2); + fmpz_clear(n); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_vec/test/t-scalar_mul_si.c b/external/flint-2.4.3/fmpz_vec/test/t-scalar_mul_si.c new file mode 100644 index 0000000..b344b04 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/test/t-scalar_mul_si.c @@ -0,0 +1,111 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009, 2010 William Hart + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("scalar_mul_si...."); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz *a, *b; + slong len = n_randint(state, 100); + slong n = z_randtest(state); + + a = _fmpz_vec_init(len); + b = _fmpz_vec_init(len); + _fmpz_vec_randtest(a, state, len, 200); + + _fmpz_vec_scalar_mul_si(b, a, len, n); + _fmpz_vec_scalar_mul_si(a, a, len, n); + + result = (_fmpz_vec_equal(a, b, len)); + if (!result) + { + flint_printf("FAIL:\n"); + _fmpz_vec_print(a, len), flint_printf("\n\n"); + _fmpz_vec_print(b, len), flint_printf("\n\n"); + abort(); + } + + _fmpz_vec_clear(a, len); + _fmpz_vec_clear(b, len); + } + + /* Check agreement with _fmpz */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz *a, *b; + slong len, n; + fmpz_t x; + + len = n_randint(state, 100); + a = _fmpz_vec_init(len); + b = _fmpz_vec_init(len); + _fmpz_vec_randtest(a, state, len, 200); + n = z_randtest(state); + fmpz_init(x); + fmpz_set_si(x, n); + + _fmpz_vec_scalar_mul_fmpz(b, a, len, x); + _fmpz_vec_scalar_mul_si(a, a, len, n); + + result = (_fmpz_vec_equal(a, b, len)); + if (!result) + { + flint_printf("FAIL:\n"); + _fmpz_vec_print(a, len), flint_printf("\n\n"); + _fmpz_vec_print(b, len), flint_printf("\n\n"); + flint_printf("%li\n\n", n); + abort(); + } + + _fmpz_vec_clear(a, len); + _fmpz_vec_clear(b, len); + fmpz_clear(x); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_vec/test/t-scalar_mul_ui.c b/external/flint-2.4.3/fmpz_vec/test/t-scalar_mul_ui.c new file mode 100644 index 0000000..2b66b4d --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/test/t-scalar_mul_ui.c @@ -0,0 +1,108 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009, 2010 William Hart + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("scalar_mul_ui...."); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz *a, *b; + slong len = n_randint(state, 100); + ulong n = n_randtest(state); + + a = _fmpz_vec_init(len); + b = _fmpz_vec_init(len); + _fmpz_vec_randtest(a, state, len, 200); + + _fmpz_vec_scalar_mul_ui(b, a, len, n); + _fmpz_vec_scalar_mul_ui(a, a, len, n); + + result = (_fmpz_vec_equal(a, b, len)); + if (!result) + { + flint_printf("FAIL:\n"); + _fmpz_vec_print(a, len), flint_printf("\n\n"); + _fmpz_vec_print(b, len), flint_printf("\n\n"); + abort(); + } + + _fmpz_vec_clear(a, len); + _fmpz_vec_clear(b, len); + } + + /* Check agreement with _fmpz */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz *a, *b; + slong len = n_randint(state, 100); + ulong n = n_randbits(state, FLINT_BITS); + fmpz_t x; + + a = _fmpz_vec_init(len); + b = _fmpz_vec_init(len); + fmpz_init(x); + _fmpz_vec_randtest(a, state, len, 200); + + fmpz_set_ui(x, n); + _fmpz_vec_scalar_mul_ui(b, a, len, n); + _fmpz_vec_scalar_mul_fmpz(a, a, len, x); + + result = (_fmpz_vec_equal(a, b, len)); + if (!result) + { + flint_printf("FAIL:\n"); + _fmpz_vec_print(a, len), flint_printf("\n\n"); + _fmpz_vec_print(b, len), flint_printf("\n\n"); + abort(); + } + + _fmpz_vec_clear(a, len); + _fmpz_vec_clear(b, len); + fmpz_clear(x); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_vec/test/t-scalar_smod_fmpz.c b/external/flint-2.4.3/fmpz_vec/test/t-scalar_smod_fmpz.c new file mode 100644 index 0000000..4d8d135 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/test/t-scalar_smod_fmpz.c @@ -0,0 +1,137 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("scalar_smod_fmpz...."); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_t p; + fmpz *a, *b; + slong len = n_randint(state, 100); + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 100); + fmpz_add_ui(p, p, 1); + + a = _fmpz_vec_init(len); + b = _fmpz_vec_init(len); + _fmpz_vec_randtest(a, state, len, 200); + + _fmpz_vec_scalar_smod_fmpz(b, a, len, p); + _fmpz_vec_scalar_smod_fmpz(a, a, len, p); + + result = (_fmpz_vec_equal(a, a, len)); + if (!result) + { + flint_printf("FAIL:\n"); + _fmpz_vec_print(a, len), flint_printf("\n\n"); + _fmpz_vec_print(b, len), flint_printf("\n\n"); + abort(); + } + + _fmpz_vec_clear(a, len); + _fmpz_vec_clear(b, len); + fmpz_clear(p); + } + + /* Check the result is reduced */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz_t p, lo, hi; + fmpz *a, *b; + slong j, len = n_randint(state, 100); + + fmpz_init(p); + fmpz_init(lo); + fmpz_init(hi); + fmpz_randtest_unsigned(p, state, 100); + fmpz_add_ui(p, p, 1); + if (fmpz_cmp_ui(p, 2) > 0) + { + fmpz_fdiv_q_2exp(hi, p, 1); + fmpz_neg(lo, hi); + } + else if (fmpz_cmp_ui(p, 2) == 0) + { + fmpz_zero(lo); + fmpz_one(hi); + } + else + { + fmpz_zero(lo); + fmpz_zero(hi); + } + + a = _fmpz_vec_init(len); + b = _fmpz_vec_init(len); + _fmpz_vec_randtest(a, state, len, 200); + + _fmpz_vec_scalar_smod_fmpz(b, a, len, p); + + result = 1; + for (j = 0; j < len; j++) + result &= (fmpz_cmp(lo, b + j) <= 0 && fmpz_cmp(b + j, hi) <= 0); + + if (!result) + { + flint_printf("FAIL:\n"); + _fmpz_vec_print(a, len), flint_printf("\n\n"); + _fmpz_vec_print(b, len), flint_printf("\n\n"); + fmpz_print(p), flint_printf("\n\n"); + fmpz_print(lo), flint_printf("\n\n"); + fmpz_print(hi), flint_printf("\n\n"); + abort(); + } + + _fmpz_vec_clear(a, len); + _fmpz_vec_clear(b, len); + fmpz_clear(p); + fmpz_clear(lo); + fmpz_clear(hi); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_vec/test/t-scalar_submul_fmpz.c b/external/flint-2.4.3/fmpz_vec/test/t-scalar_submul_fmpz.c new file mode 100644 index 0000000..f30c2d0 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/test/t-scalar_submul_fmpz.c @@ -0,0 +1,124 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009, 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("scalar_submul_fmpz...."); + fflush(stdout); + + + + /* Compare with fmpz_vec_scalar_submul_si */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz *a, *b, *c; + slong len, n; + fmpz_t n1; + len = n_randint(state, 100); + n = (slong) n_randbits(state, FLINT_BITS - 1); + if (n_randint(state, 2)) + n = -n; + fmpz_init(n1); + fmpz_set_si(n1, n); + + a = _fmpz_vec_init(len); + b = _fmpz_vec_init(len); + c = _fmpz_vec_init(len); + _fmpz_vec_randtest(a, state, len, 200); + _fmpz_vec_randtest(b, state, len, 200); + _fmpz_vec_set(c, b, len); + + _fmpz_vec_scalar_submul_fmpz(b, a, len, n1); + _fmpz_vec_scalar_submul_si(c, a, len, n); + + result = (_fmpz_vec_equal(c, b, len)); + if (!result) + { + flint_printf("FAIL:\n"); + _fmpz_vec_print(c, len), flint_printf("\n\n"); + _fmpz_vec_print(b, len), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(n1); + _fmpz_vec_clear(a, len); + _fmpz_vec_clear(b, len); + _fmpz_vec_clear(c, len); + } + + /* Compute a different way */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz *a, *b, *c, *d; + slong len = n_randint(state, 100); + fmpz_t n1; + fmpz_init(n1); + fmpz_randtest(n1, state, 200); + + a = _fmpz_vec_init(len); + b = _fmpz_vec_init(len); + c = _fmpz_vec_init(len); + d = _fmpz_vec_init(len); + _fmpz_vec_randtest(a, state, len, 200); + _fmpz_vec_randtest(b, state, len, 200); + _fmpz_vec_set(c, b, len); + + _fmpz_vec_scalar_submul_fmpz(b, a, len, n1); + _fmpz_vec_scalar_mul_fmpz(d, a, len, n1); + _fmpz_vec_sub(c, c, d, len); + + result = (_fmpz_vec_equal(c, b, len)); + if (!result) + { + flint_printf("FAIL:\n"); + _fmpz_vec_print(c, len), flint_printf("\n\n"); + _fmpz_vec_print(b, len), flint_printf("\n\n"); + abort(); + } + + fmpz_clear(n1); + _fmpz_vec_clear(a, len); + _fmpz_vec_clear(b, len); + _fmpz_vec_clear(c, len); + _fmpz_vec_clear(d, len); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_vec/test/t-scalar_submul_si.c b/external/flint-2.4.3/fmpz_vec/test/t-scalar_submul_si.c new file mode 100644 index 0000000..c04f0a2 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/test/t-scalar_submul_si.c @@ -0,0 +1,88 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("scalar_submul_si...."); + fflush(stdout); + + + + /* Compare with alternative method of computation */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz *a, *b, *c, *d; + slong len = n_randint(state, 100), x; + + a = _fmpz_vec_init(len); + b = _fmpz_vec_init(len); + c = _fmpz_vec_init(len); + d = _fmpz_vec_init(len); + + _fmpz_vec_randtest(a, state, len, 200); + _fmpz_vec_randtest(b, state, len, 200); + _fmpz_vec_set(c, b, len); + + x = z_randtest(state); + + _fmpz_vec_scalar_submul_si(b, a, len, x); + _fmpz_vec_scalar_mul_si(d, a, len, x); + _fmpz_vec_sub(c, c, d, len); + + result = (_fmpz_vec_equal(b, c, len)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("x = %wd\n", x); + _fmpz_vec_print(b, len), flint_printf("\n\n"); + _fmpz_vec_print(c, len), flint_printf("\n\n"); + abort(); + } + + _fmpz_vec_clear(a, len); + _fmpz_vec_clear(b, len); + _fmpz_vec_clear(c, len); + _fmpz_vec_clear(d, len); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_vec/test/t-scalar_submul_si_2exp.c b/external/flint-2.4.3/fmpz_vec/test/t-scalar_submul_si_2exp.c new file mode 100644 index 0000000..9b826ee --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/test/t-scalar_submul_si_2exp.c @@ -0,0 +1,89 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("scalar_submul_si_2exp...."); + fflush(stdout); + + + + /* Compare with alternative method of computation */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz *a, *b, *c, *d; + slong len = n_randint(state, 100), x; + mp_bitcnt_t exp; + + a = _fmpz_vec_init(len); + b = _fmpz_vec_init(len); + c = _fmpz_vec_init(len); + d = _fmpz_vec_init(len); + + _fmpz_vec_randtest(a, state, len, 200); + _fmpz_vec_randtest(b, state, len, 200); + _fmpz_vec_set(c, b, len); + + x = z_randtest(state); + exp = n_randint(state, 200); + + _fmpz_vec_scalar_submul_si_2exp(b, a, len, x, exp); + _fmpz_vec_scalar_mul_2exp(d, a, len, exp); + _fmpz_vec_scalar_submul_si(c, d, len, x); + + result = (_fmpz_vec_equal(b, c, len)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("x = %wd, exp = %wu\n", x, exp); + _fmpz_vec_print(b, len), flint_printf("\n\n"); + _fmpz_vec_print(c, len), flint_printf("\n\n"); + abort(); + } + + _fmpz_vec_clear(a, len); + _fmpz_vec_clear(b, len); + _fmpz_vec_clear(c, len); + _fmpz_vec_clear(d, len); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_vec/test/t-set_equal.c b/external/flint-2.4.3/fmpz_vec/test/t-set_equal.c new file mode 100644 index 0000000..61c3ecb --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/test/t-set_equal.c @@ -0,0 +1,124 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009, 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("set/equal...."); + fflush(stdout); + + + + /* Check aliasing of a and b */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz *a; + slong len = n_randint(state, 100); + + a = _fmpz_vec_init(len); + _fmpz_vec_randtest(a, state, len, 200); + + _fmpz_vec_set(a, a, len); + + result = (_fmpz_vec_equal(a, a, len)); + if (!result) + { + flint_printf("FAIL:\n"); + _fmpz_vec_print(a, len), flint_printf("\n\n"); + abort(); + } + + _fmpz_vec_clear(a, len); + } + + /* Compare copied vectors */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz *a, *b; + slong len = n_randint(state, 100); + + a = _fmpz_vec_init(len); + b = _fmpz_vec_init(len); + _fmpz_vec_randtest(a, state, len, 200); + + _fmpz_vec_set(b, a, len); + + result = (_fmpz_vec_equal(a, b, len)); + if (!result) + { + flint_printf("FAIL:\n"); + _fmpz_vec_print(a, len), flint_printf("\n\n"); + _fmpz_vec_print(b, len), flint_printf("\n\n"); + abort(); + } + + _fmpz_vec_clear(a, len); + _fmpz_vec_clear(b, len); + } + + /* Compare unequal vectors */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz *a, *b; + slong len = n_randint(state, 100) + 1; + slong coeff; + + a = _fmpz_vec_init(len); + b = _fmpz_vec_init(len); + _fmpz_vec_randtest(a, state, len, 200); + + _fmpz_vec_set(b, a, len); + coeff = n_randint(state, len); + fmpz_add_ui(b + coeff, b + coeff, 1); + + result = (!_fmpz_vec_equal(a, b, len)); + if (!result) + { + flint_printf("FAIL:\n"); + _fmpz_vec_print(a, len), flint_printf("\n\n"); + _fmpz_vec_print(b, len), flint_printf("\n\n"); + abort(); + } + + _fmpz_vec_clear(a, len); + _fmpz_vec_clear(b, len); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_vec/test/t-sub.c b/external/flint-2.4.3/fmpz_vec/test/t-sub.c new file mode 100644 index 0000000..edf19a9 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/test/t-sub.c @@ -0,0 +1,139 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009, 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("sub...."); + fflush(stdout); + + + + /* Check aliasing of a and c */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz *a, *b, *c; + slong len = n_randint(state, 100); + + a = _fmpz_vec_init(len); + b = _fmpz_vec_init(len); + c = _fmpz_vec_init(len); + _fmpz_vec_randtest(a, state, len, 200); + _fmpz_vec_randtest(b, state, len, 200); + + _fmpz_vec_sub(c, a, b, len); + _fmpz_vec_sub(a, a, b, len); + + result = (_fmpz_vec_equal(a, c, len)); + if (!result) + { + flint_printf("FAIL:\n"); + _fmpz_vec_print(a, len), flint_printf("\n\n"); + _fmpz_vec_print(c, len), flint_printf("\n\n"); + abort(); + } + + _fmpz_vec_clear(a, len); + _fmpz_vec_clear(b, len); + _fmpz_vec_clear(c, len); + } + + /* Check aliasing of b and c */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz *a, *b, *c; + slong len = n_randint(state, 100); + + a = _fmpz_vec_init(len); + b = _fmpz_vec_init(len); + c = _fmpz_vec_init(len); + _fmpz_vec_randtest(a, state, len, 200); + _fmpz_vec_randtest(b, state, len, 200); + + _fmpz_vec_sub(c, a, b, len); + _fmpz_vec_sub(b, a, b, len); + + result = (_fmpz_vec_equal(b, c, len)); + if (!result) + { + flint_printf("FAIL:\n"); + _fmpz_vec_print(b, len), flint_printf("\n\n"); + _fmpz_vec_print(c, len), flint_printf("\n\n"); + abort(); + } + + _fmpz_vec_clear(a, len); + _fmpz_vec_clear(b, len); + _fmpz_vec_clear(c, len); + } + + /* Check a + b - b = a */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz *a, *b, *c, *d; + slong len = n_randint(state, 100); + + a = _fmpz_vec_init(len); + b = _fmpz_vec_init(len); + c = _fmpz_vec_init(len); + d = _fmpz_vec_init(len); + _fmpz_vec_randtest(a, state, len, 200); + _fmpz_vec_randtest(b, state, len, 200); + + _fmpz_vec_add(c, a, b, len); + _fmpz_vec_sub(d, c, b, len); + + result = (_fmpz_vec_equal(d, a, len)); + if (!result) + { + flint_printf("FAIL:\n"); + _fmpz_vec_print(a, len), flint_printf("\n\n"); + _fmpz_vec_print(d, len), flint_printf("\n\n"); + abort(); + } + + _fmpz_vec_clear(a, len); + _fmpz_vec_clear(b, len); + _fmpz_vec_clear(c, len); + _fmpz_vec_clear(d, len); + } + + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_vec/test/t-sum.c b/external/flint-2.4.3/fmpz_vec/test/t-sum.c new file mode 100644 index 0000000..9e53953 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/test/t-sum.c @@ -0,0 +1,88 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009, 2010 William Hart + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("sum...."); + fflush(stdout); + + + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz *a, *b; + fmpz_t x, y, z; + + slong len1 = n_randint(state, 100); + slong len2 = n_randint(state, 100); + + a = _fmpz_vec_init(len1 + len2); + b = a + len1; + + _fmpz_vec_randtest(a, state, len1 + len2, 200); + + fmpz_init(x); + fmpz_init(y); + fmpz_init(z); + + _fmpz_vec_sum(x, a, len1); + _fmpz_vec_sum(y, b, len2); + fmpz_add(x, x, y); + _fmpz_vec_sum(z, a, len1 + len2); + + result = (fmpz_equal(x, z)); + if (!result) + { + flint_printf("FAIL:\n"); + _fmpz_vec_print(a, len1), flint_printf("\n\n"); + _fmpz_vec_print(b, len2), flint_printf("\n\n"); + abort(); + } + + _fmpz_vec_clear(a, len1 + len2); + + fmpz_clear(x); + fmpz_clear(y); + fmpz_clear(z); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_vec/test/t-swap.c b/external/flint-2.4.3/fmpz_vec/test/t-swap.c new file mode 100644 index 0000000..91691b5 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/test/t-swap.c @@ -0,0 +1,79 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("swap...."); + fflush(stdout); + + + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz *a, *b, *c; + slong len = n_randint(state, 100); + + a = _fmpz_vec_init(len); + b = _fmpz_vec_init(len); + c = _fmpz_vec_init(len); + _fmpz_vec_randtest(a, state, len, 200); + _fmpz_vec_randtest(b, state, len, 200); + + _fmpz_vec_set(c, b, len); + _fmpz_vec_swap(a, b, len); + + result = (_fmpz_vec_equal(a, c, len)); + if (!result) + { + flint_printf("FAIL:\n"); + _fmpz_vec_print(a, len), flint_printf("\n\n"); + _fmpz_vec_print(b, len), flint_printf("\n\n"); + _fmpz_vec_print(c, len), flint_printf("\n\n"); + abort(); + } + + _fmpz_vec_clear(a, len); + _fmpz_vec_clear(b, len); + _fmpz_vec_clear(c, len); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_vec/test/t-zero.c b/external/flint-2.4.3/fmpz_vec/test/t-zero.c new file mode 100644 index 0000000..822d314 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/test/t-zero.c @@ -0,0 +1,72 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009, 2010 William Hart + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("zero...."); + fflush(stdout); + + + + /* Check it's zero */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + fmpz *a; + slong len = n_randint(state, 100); + + a = _fmpz_vec_init(len); + _fmpz_vec_randtest(a, state, len, 200); + + _fmpz_vec_zero(a, len); + + result = (_fmpz_vec_is_zero(a, len)); + if (!result) + { + flint_printf("FAIL:\n"); + _fmpz_vec_print(a, len), flint_printf("\n\n"); + abort(); + } + + _fmpz_vec_clear(a, len); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fmpz_vec/zero.c b/external/flint-2.4.3/fmpz_vec/zero.c new file mode 100644 index 0000000..8d7a370 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vec/zero.c @@ -0,0 +1,37 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_vec.h" + +void +_fmpz_vec_zero(fmpz * vec, slong len) +{ + slong i; + for (i = 0; i < len; i++) + fmpz_zero(vec + i); +} diff --git a/external/flint-2.4.3/fmpz_vecxx.h b/external/flint-2.4.3/fmpz_vecxx.h new file mode 100644 index 0000000..4306683 --- /dev/null +++ b/external/flint-2.4.3/fmpz_vecxx.h @@ -0,0 +1,110 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#ifndef CXX_FMPZ_VECXX_H +#define CXX_FMPZ_VECXX_H + +#include "fmpzxx.h" +#include "fmpz_vec.h" +#include "flintxx/vector.h" + +namespace flint { +namespace detail { +struct fmpz_vector_data +{ + slong size; + fmpz* array; + + fmpz_vector_data(slong n) + : size(n), array(_fmpz_vec_init(n)) {} + + ~fmpz_vector_data() {_fmpz_vec_clear(array, size);} + + fmpz_vector_data(const fmpz_vector_data& o) + : size(o.size), array(_fmpz_vec_init(o.size)) + { + _fmpz_vec_set(array, o.array, size); + } + + fmpzxx_ref at(slong i) {return fmpzxx_ref::make(array + i);} + fmpzxx_srcref at(slong i) const {return fmpzxx_srcref::make(array + i);} +}; +} // detail + +typedef vector_expression< + detail::wrapped_vector_traits, + operations::immediate, + detail::fmpz_vector_data> fmpz_vecxx; +// TODO references + +template<> +struct enable_vector_rules : mp::false_ { }; + +namespace rules { +// TODO hack to make code look like references are implemented +template struct FMPZ_VECXX_COND_S : mp::equal_types { }; +#define FMPZ_VECXX_COND_T FMPZ_VECXX_COND_S + +template +struct to_string >::type> +{ + static std::string get(const fmpz_vecxx& e, int base) + { + // TODO use _fmpz_vec_print somehow? + std::ostringstream o; + o << e.size(); + if(e.size() == 0) + { + return o.str(); + } + o << " "; + for(slong i = 0;i < e.size();++i) + { + o << e[i].to_string(base); + if(i != e.size() - 1) + o << " "; + } + return o.str(); + } +}; + +// TODO references +FLINT_DEFINE_GET(equals, bool, fmpz_vecxx, + e1.size() == e2.size() + && _fmpz_vec_equal(e1._data().array, e2._data().array, e1.size())) + +FLINT_DEFINE_BINARY_EXPR_COND2(plus, fmpz_vecxx, + FMPZ_VECXX_COND_S, FMPZ_VECXX_COND_S, + _fmpz_vec_add(to._data().array, e1._data().array, e2._data().array, + e1.size())) + +FLINT_DEFINE_DOIT_COND2(assignment, FMPZ_VECXX_COND_T, FMPZ_VECXX_COND_S, + _fmpz_vec_set(to._array(), from._array(), to.size())) + +// TODO more +} // rules +} // flint + +#endif diff --git a/external/flint-2.4.3/fmpzxx.h b/external/flint-2.4.3/fmpzxx.h new file mode 100644 index 0000000..fd2676d --- /dev/null +++ b/external/flint-2.4.3/fmpzxx.h @@ -0,0 +1,799 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#ifndef CXX_FMPZXX_H +#define CXX_FMPZXX_H + +#include +#include + +#include "flintxx/evaluation_tools.h" +#include "flintxx/expression.h" +#include "flintxx/expression_traits.h" +#include "flintxx/flint_classes.h" +#include "flintxx/frandxx.h" +#include "flintxx/ltuple.h" +#include "flintxx/stdmath.h" + +#include "fmpz.h" + +#undef clrbit /* no idea where these are coming from */ +#undef setbit + +// TODO functions for addmul? inhomogeneous addmul? +// TODO use evaluate_n in immediate functions? +// TODO fmpz_abs_ubound_ui_2exp, lbound +// TODO cmpabs +// TODO xgcd_partial + +namespace flint { +FLINT_DEFINE_BINOP(cdiv_q) +FLINT_DEFINE_BINOP(fdiv_r) +FLINT_DEFINE_BINOP(tdiv_q) +FLINT_DEFINE_BINOP(fdiv_r_2exp) +FLINT_DEFINE_BINOP(tdiv_q_2exp) +FLINT_DEFINE_UNOP(fac) +FLINT_DEFINE_UNOP(fib) +FLINT_DEFINE_BINOP(rfac) +FLINT_DEFINE_BINOP(bin) +FLINT_DEFINE_BINOP(gcd) +FLINT_DEFINE_BINOP(lcm) +FLINT_DEFINE_BINOP(invmod) +FLINT_DEFINE_BINOP(negmod) +FLINT_DEFINE_THREEARY(mul2) +FLINT_DEFINE_THREEARY(divexact2) +FLINT_DEFINE_THREEARY(powm) +FLINT_DEFINE_THREEARY(mul_tdiv_q_2exp) +FLINT_DEFINE_BINOP(fdiv_qr) +FLINT_DEFINE_BINOP(tdiv_qr) +FLINT_DEFINE_BINOP(sqrtmod) +FLINT_DEFINE_UNOP(sqrtrem) +FLINT_DEFINE_BINOP(gcdinv) +FLINT_DEFINE_BINOP(xgcd) +FLINT_DEFINE_BINOP(remove) + +FLINT_DEFINE_FIVEARY(fmpzxx_bit_unpack) +FLINT_DEFINE_THREEARY(fmpzxx_bit_unpack_unsigned) + +namespace mp { +template +struct enable_all_fmpzxx; +} + +template +class fmpzxx_expression + : public expression, Operation, Data> +{ +public: + typedef expression, + Operation, Data> base_t; + + FLINTXX_DEFINE_BASICS(fmpzxx_expression) + FLINTXX_DEFINE_CTORS(fmpzxx_expression) + FLINTXX_DEFINE_C_REF(fmpzxx_expression, fmpz, _fmpz) + + // these only make sense with fmpzxx + FLINTXX_DEFINE_RANDFUNC(fmpz, randbits) + FLINTXX_DEFINE_RANDFUNC(fmpz, randtest) + FLINTXX_DEFINE_RANDFUNC(fmpz, randtest_unsigned) + FLINTXX_DEFINE_RANDFUNC(fmpz, randtest_not_zero) + + template + static fmpzxx_expression randm(frandxx& state, const Fmpz& m) + { + fmpzxx_expression res; + fmpz_randm(res._fmpz(), state._data(), m.evaluate()._fmpz()); + return res; + } + template + static fmpzxx_expression randtest_mod(frandxx& state, const Fmpz& m) + { + fmpzxx_expression res; + fmpz_randtest_mod(res._fmpz(), state._data(), m.evaluate()._fmpz()); + return res; + } + template + static fmpzxx_expression randtest_mod_signed(frandxx& state, const Fmpz& m) + { + fmpzxx_expression res; + fmpz_randtest_mod_signed(res._fmpz(), state._data(), m.evaluate()._fmpz()); + return res; + } + + // TODO would these make more sense static? + void set_ui_smod(mp_limb_t x, mp_limb_t m) + { + fmpz_set_ui_smod(this->_fmpz(), x, m); + } + void set_uiui(mp_limb_t hi, mp_limb_t lo) + { + fmpz_set_uiui(this->_fmpz(), hi, lo); + } + void neg_uiui(mp_limb_t hi, mp_limb_t lo) + { + fmpz_neg_uiui(this->_fmpz(), hi, lo); + } + // these only make sense with fmpzxx/fmpzxx_ref + void clrbit(ulong i) {fmpz_clrbit(_fmpz(), i);} + void combit(ulong i) {fmpz_combit(_fmpz(), i);} + void setbit(ulong i) {fmpz_setbit(_fmpz(), i);} + void set_zero() {fmpz_zero(_fmpz());} + void set_one() {fmpz_one(_fmpz());} + + // These make sense with all expressions, but cause evaluation + double get_d_2exp(slong& exp) const + { + return fmpz_get_d_2exp(&exp, this->evaluate()._fmpz()); + } + bool is_zero() const + { + return fmpz_is_zero(this->evaluate()._fmpz()); + } + bool is_one() const + { + return fmpz_is_one(this->evaluate()._fmpz()); + } + bool is_pm1() const + { + return fmpz_is_pm1(this->evaluate()._fmpz()); + } + bool is_even() const + { + return fmpz_is_even(this->evaluate()._fmpz()); + } + bool is_odd() const + { + return fmpz_is_odd(this->evaluate()._fmpz()); + } + bool is_square() const + { + return fmpz_is_square(this->evaluate()._fmpz()); + } + int popcnt() const + { + return fmpz_popcnt(this->evaluate()._fmpz()); + } + bool is_probabprime() const + { + return fmpz_is_probabprime(this->evaluate()._fmpz()); + } + bool is_prime_pseudosquare() const + { + return fmpz_is_prime_pseudosquare(this->evaluate()._fmpz()); + } + bool abs_fits_ui() const + { + return fmpz_abs_fits_ui(this->evaluate()._fmpz()); + } + bool fits_si() const + { + return fmpz_fits_si(this->evaluate()._fmpz()); + } + bool tstbit(ulong i) const + { + return fmpz_tstbit(this->evaluate()._fmpz(), i); + } + + template + typename mp::enable_all_fmpzxx::type + divisible(const T2& t2) const + { + return fmpz_divisible(this->evaluate()._fmpz(), t2.evaluate()._fmpz()); + } + template + typename mp::enable_if, bool>::type + divisible(const T2& t2) const + { + return fmpz_divisible_si(this->evaluate()._fmpz(), t2); + } + template + typename mp::enable_all_fmpzxx::type + clog(const Fmpz2& b) const + { + return fmpz_clog(this->evaluate()._fmpz(), b.evaluate()._fmpz()); + } + template + typename mp::enable_if, slong>::type + clog(Int b) const + { + return fmpz_clog_ui(this->evaluate()._fmpz(), b); + } + template + typename mp::enable_all_fmpzxx::type + flog(const Fmpz2& b) const + { + return fmpz_flog(this->evaluate()._fmpz(), b.evaluate()._fmpz()); + } + template + typename mp::enable_if, slong>::type + flog(Int b) const + { + return fmpz_flog_ui(this->evaluate()._fmpz(), b); + } + double dlog() const + { + return fmpz_dlog(this->evaluate()._fmpz()); + } + template + typename mp::enable_all_fmpzxx::type + jacobi(const Fmpz2& p) const + { + return fmpz_jacobi(this->evaluate()._fmpz(), p.evaluate()._fmpz()); + } + + size_t sizeinbase(int b) const + {return fmpz_sizeinbase(this->evaluate()._fmpz(), b);} + mp_bitcnt_t bits() const + {return fmpz_bits(this->evaluate()._fmpz());} + mp_bitcnt_t size() const + {return fmpz_size(this->evaluate()._fmpz());} + mp_bitcnt_t val2() const + {return fmpz_val2(this->evaluate()._fmpz());} + int sgn() const + {return fmpz_sgn(this->evaluate()._fmpz());} + + // lazy function forwarding + FLINTXX_DEFINE_MEMBER_3OP(divexact2) + FLINTXX_DEFINE_MEMBER_3OP(mul2) + FLINTXX_DEFINE_MEMBER_3OP(mul_tdiv_q_2exp) + FLINTXX_DEFINE_MEMBER_3OP(powm) + FLINTXX_DEFINE_MEMBER_BINOP(cdiv_q) + FLINTXX_DEFINE_MEMBER_BINOP(divexact) + FLINTXX_DEFINE_MEMBER_BINOP(fdiv_qr) + FLINTXX_DEFINE_MEMBER_BINOP(fdiv_r) + FLINTXX_DEFINE_MEMBER_BINOP(fdiv_r_2exp) + FLINTXX_DEFINE_MEMBER_BINOP(gcd) + FLINTXX_DEFINE_MEMBER_BINOP(gcdinv) + FLINTXX_DEFINE_MEMBER_BINOP(invmod) + FLINTXX_DEFINE_MEMBER_BINOP(lcm) + FLINTXX_DEFINE_MEMBER_BINOP(negmod) + FLINTXX_DEFINE_MEMBER_BINOP(pow) + FLINTXX_DEFINE_MEMBER_BINOP(remove) + FLINTXX_DEFINE_MEMBER_BINOP(rfac) + FLINTXX_DEFINE_MEMBER_BINOP(root) + FLINTXX_DEFINE_MEMBER_BINOP(sqrtmod) + FLINTXX_DEFINE_MEMBER_BINOP(tdiv_q) + FLINTXX_DEFINE_MEMBER_BINOP(tdiv_q_2exp) + FLINTXX_DEFINE_MEMBER_BINOP(tdiv_qr) + FLINTXX_DEFINE_MEMBER_BINOP(xgcd) + FLINTXX_DEFINE_MEMBER_UNOP(abs) + FLINTXX_DEFINE_MEMBER_UNOP(sqrt) + // FLINTXX_DEFINE_MEMBER_UNOP(sqrtrem) // TODO + + FLINTXX_DEFINE_MEMBER_5OP(CRT) + + template + static FLINT_FIVEARY_ENABLE_RETTYPE(fmpzxx_bit_unpack, + Arg1, Arg2, mp_bitcnt_t, int, bool) + bit_unpack(const Arg1& arr, const Arg2& bits, + mp_bitcnt_t shift = 0, int negate = 0, bool borrow = false) + { + return fmpzxx_bit_unpack(arr, bits, shift, negate, borrow); + } + template + static FLINT_THREEARY_ENABLE_RETTYPE(fmpzxx_bit_unpack_unsigned, + Arg1, Arg2, mp_bitcnt_t) + bit_unpack_unsigned(const Arg1& arr, const Arg2& bits, mp_bitcnt_t shift = 0) + { + return fmpzxx_bit_unpack_unsigned(arr, bits, shift); + } +}; + +namespace detail { +struct fmpz_data; +} + +typedef fmpzxx_expression fmpzxx; +typedef fmpzxx_expression > fmpzxx_ref; +typedef fmpzxx_expression > fmpzxx_srcref; + +namespace detail { +struct fmpz_data +{ + typedef fmpz_t& data_ref_t; + typedef const fmpz_t& data_srcref_t; + + fmpz_t inner; + + fmpz_data() {fmpz_init(inner);} + ~fmpz_data() {fmpz_clear(inner);} + fmpz_data(const fmpz_data& o) {fmpz_init_set(inner, o.inner);} + + template + fmpz_data(const T& t) + { + init(t); + } + + template + typename mp::enable_if >::type init(T t) + { + fmpz_init_set_ui(inner, t); + } + template + typename mp::enable_if >::type init(T t) + { + fmpz_init(inner); + fmpz_set_si(inner, t); + } + + void init(const char* str) + { + fmpz_init(inner); + fmpz_set_str(inner, str, 10); + } + + void init(const fmpzxx_srcref& r) + { + fmpz_init_set(inner, r._fmpz()); + } +}; + +} // detail + +/////////////////////////////////////////////////////////////////// +// HELPERS +/////////////////////////////////////////////////////////////////// +namespace traits { +template struct is_fmpzxx : mp::or_< + traits::is_T_expr, + flint_classes::is_source > { }; +} // traits +namespace mp { +template +struct all_fmpzxx : mp::and_, all_fmpzxx > { }; +template +struct all_fmpzxx : traits::is_fmpzxx { }; + +template +struct enable_all_fmpzxx + : mp::enable_if, Out> { }; +} // mp + +/////////////////////////////////////////////////////////////////// +// RULES +/////////////////////////////////////////////////////////////////// +namespace rules { + +#define FMPZXX_COND_S FLINTXX_COND_S(fmpzxx) +#define FMPZXX_COND_T FLINTXX_COND_T(fmpzxx) + +FLINT_DEFINE_DOIT_COND2(assignment, FMPZXX_COND_T, FMPZXX_COND_S, + fmpz_set(to._fmpz(), from._fmpz())) + +FLINT_DEFINE_DOIT_COND2(assignment, + FMPZXX_COND_T, traits::is_unsigned_integer, + fmpz_set_ui(to._fmpz(), from)) + +FLINT_DEFINE_DOIT_COND2(assignment, + FMPZXX_COND_T, traits::is_signed_integer, + fmpz_set_si(to._fmpz(), from)) + +FLINTXX_DEFINE_CMP(fmpzxx, fmpz_cmp(e1._fmpz(), e2._fmpz())) + +template +struct cmp, traits::is_signed_integer > >::type> +{ + static int get(const T& v, const U& t) + { + return fmpz_cmp_si(v._fmpz(), t); + } +}; + +template +struct cmp >::type> +{ + static int get(const fmpzxx& v, const T& t) + { + return fmpz_cmp_ui(v._fmpz(), t); + } +}; + +FLINTXX_DEFINE_ASSIGN_STR(fmpzxx, fmpz_set_str(to._fmpz(), from, 10)) +FLINTXX_DEFINE_TO_STR(fmpzxx, fmpz_get_str(0, base, from._fmpz())) + +FLINTXX_DEFINE_SWAP(fmpzxx, fmpz_swap(e1._fmpz(), e2._fmpz())) + +FLINT_DEFINE_PRINT_COND(FMPZXX_COND_S, fmpz_fprint(to, from._fmpz())) +FLINT_DEFINE_READ_COND(FMPZXX_COND_T, fmpz_fread(from, to._fmpz())) + +FLINT_DEFINE_GET_COND(conversion, slong, FMPZXX_COND_S, + fmpz_get_si(from._fmpz())) +FLINT_DEFINE_GET_COND(conversion, ulong, FMPZXX_COND_S, + fmpz_get_ui(from._fmpz())) +FLINT_DEFINE_GET_COND(conversion, double, FMPZXX_COND_S, + fmpz_get_d(from._fmpz())) + +FLINT_DEFINE_BINARY_EXPR_COND2(plus, fmpzxx, FMPZXX_COND_S, FMPZXX_COND_S, + fmpz_add(to._fmpz(), e1._fmpz(), e2._fmpz())) + +FLINT_DEFINE_CBINARY_EXPR_COND2(plus, fmpzxx, + FMPZXX_COND_S, traits::is_unsigned_integer, + fmpz_add_ui(to._fmpz(), e1._fmpz(), e2)) + +FLINT_DEFINE_BINARY_EXPR_COND2(times, fmpzxx, FMPZXX_COND_S, FMPZXX_COND_S, + fmpz_mul(to._fmpz(), e1._fmpz(), e2._fmpz())) + +FLINT_DEFINE_CBINARY_EXPR_COND2(times, fmpzxx, + FMPZXX_COND_S, traits::is_unsigned_integer, + fmpz_mul_ui(to._fmpz(), e1._fmpz(), e2)) + +FLINT_DEFINE_CBINARY_EXPR_COND2(times, fmpzxx, + FMPZXX_COND_S, traits::is_signed_integer, + fmpz_mul_si(to._fmpz(), e1._fmpz(), e2)) + +FLINT_DEFINE_BINARY_EXPR_COND2(minus, fmpzxx, FMPZXX_COND_S, FMPZXX_COND_S, + fmpz_sub(to._fmpz(), e1._fmpz(), e2._fmpz())) + +FLINT_DEFINE_BINARY_EXPR_COND2(minus, fmpzxx, + FMPZXX_COND_S, traits::is_unsigned_integer, + fmpz_sub_ui(to._fmpz(), e1._fmpz(), e2)) + +FLINT_DEFINE_BINARY_EXPR_COND2(divided_by, fmpzxx, FMPZXX_COND_S, FMPZXX_COND_S, + fmpz_fdiv_q(to._fmpz(), e1._fmpz(), e2._fmpz())) + +FLINT_DEFINE_BINARY_EXPR_COND2(divided_by, fmpzxx, + FMPZXX_COND_S, traits::is_unsigned_integer, + fmpz_fdiv_q_ui(to._fmpz(), e1._fmpz(), e2)) + +FLINT_DEFINE_BINARY_EXPR_COND2(divided_by, fmpzxx, + FMPZXX_COND_S, traits::is_signed_integer, + fmpz_fdiv_q_si(to._fmpz(), e1._fmpz(), e2)) + +// TODO this interpretation of mod is not the same as for builtin types! +FLINT_DEFINE_BINARY_EXPR_COND2(modulo, fmpzxx, FMPZXX_COND_S, FMPZXX_COND_S, + fmpz_mod(to._fmpz(), e1._fmpz(), e2._fmpz())) + +FLINT_DEFINE_BINARY_EXPR_COND2(modulo, fmpzxx, + FMPZXX_COND_S, traits::is_unsigned_integer, + fmpz_mod_ui(to._fmpz(), e1._fmpz(), e2)) + +FLINT_DEFINE_BINARY_EXPR_COND2(binary_and, fmpzxx, FMPZXX_COND_S, FMPZXX_COND_S, + fmpz_and(to._fmpz(), e1._fmpz(), e2._fmpz())) + +FLINT_DEFINE_BINARY_EXPR_COND2(binary_or, fmpzxx, FMPZXX_COND_S, FMPZXX_COND_S, + fmpz_or(to._fmpz(), e1._fmpz(), e2._fmpz())) + +FLINT_DEFINE_BINARY_EXPR_COND2(binary_xor, fmpzxx, FMPZXX_COND_S, FMPZXX_COND_S, + fmpz_xor(to._fmpz(), e1._fmpz(), e2._fmpz())) + +FLINT_DEFINE_UNARY_EXPR_COND(negate, fmpzxx, FMPZXX_COND_S, + fmpz_neg(to._fmpz(), from._fmpz())) + +FLINT_DEFINE_UNARY_EXPR_COND(complement, fmpzxx, FMPZXX_COND_S, + fmpz_complement(to._fmpz(), from._fmpz())) + +namespace rdetail { +template +void fmpzxx_shift(Fmpz1& to, const Fmpz2& from, T howmuch) +{ + if(howmuch < 0) + fmpz_fdiv_q_2exp(to._fmpz(), from._fmpz(), -howmuch); + else + fmpz_mul_2exp(to._fmpz(), from._fmpz(), howmuch); +} +} // rdetail +FLINT_DEFINE_BINARY_EXPR_COND2(shift, fmpzxx, + FMPZXX_COND_S, traits::is_integer, + rdetail::fmpzxx_shift(to, e1, e2)) +} // rules + +FLINTXX_DEFINE_TERNARY(fmpzxx, + fmpz_addmul(to._fmpz(), e1._fmpz(), e2._fmpz()), + fmpz_submul(to._fmpz(), e1._fmpz(), e2._fmpz()), + FLINTXX_UNADORNED_MAKETYPES) + +/////////////////////////////////////////////////////////////////////////// +// FUNCTIONS +/////////////////////////////////////////////////////////////////////////// + +// These functions evaluate immediately, and (often) do not yield fmpzxxs + +template +inline typename mp::enable_all_fmpzxx::type +divisible(const T1& t1, const T2& t2) +{ + return t1.divisible(t2); +} + +template +inline typename mp::enable_all_fmpzxx::type +clog(const Fmpz1& x, const Fmpz2& b) +{ + return x.clog(b); +} + +template +inline typename mp::enable_all_fmpzxx::type +flog(const Fmpz1& x, const Fmpz2& b) +{ + return x.flog(b); +} + +template +inline typename mp::enable_if, double>::type +dlog(const Fmpz& x) +{ + return x.dlog(); +} + +template +inline typename mp::enable_all_fmpzxx::type +jacobi(const Fmpz1& a, const Fmpz2& p) +{ + return a.jacobi(p); +} + +template +inline typename mp::enable_if, size_t>::type +sizeinbase(const Fmpz& a, int b) +{ + return a.sizeinbase(b); +} +template +inline typename mp::enable_if, mp_bitcnt_t>::type +bits(const Fmpz& a) +{ + return a.bits(); +} +template +inline typename mp::enable_if, mp_bitcnt_t>::type +val2(const Fmpz& a) +{ + return a.val2(); +} +template +inline typename mp::enable_if, mp_bitcnt_t>::type +size(const Fmpz& a) +{ + return a.size(); +} +template +inline typename mp::enable_if, int>::type +sgn(const Fmpz& a) +{ + return a.sgn(); +} + +template +inline bool bit_pack(std::vector& arr, mp_bitcnt_t bits, + const Fmpz& coeff, mp_bitcnt_t shift = 0, int negate = 0, + bool borrow = false, + typename mp::enable_if >::type* = 0) +{ + return fmpz_bit_pack(&arr.front(), shift, bits, + coeff.evaluate()._fmpz(), negate, borrow); +} + +// These functions are evaluated lazily +namespace rules { +FLINT_DEFINE_BINARY_EXPR_COND2(rfac_op, fmpzxx, + FMPZXX_COND_S, traits::is_unsigned_integer, + fmpz_rfac_ui(to._fmpz(), e1._fmpz(), e2)) +FLINT_DEFINE_UNARY_EXPR_COND(fac_op, fmpzxx, traits::is_unsigned_integer, + fmpz_fac_ui(to._fmpz(), from)) +FLINT_DEFINE_UNARY_EXPR_COND(fib_op, fmpzxx, traits::is_unsigned_integer, + fmpz_fib_ui(to._fmpz(), from)) +FLINT_DEFINE_BINARY_EXPR_COND2(gcd_op, fmpzxx, FMPZXX_COND_S, FMPZXX_COND_S, + fmpz_gcd(to._fmpz(), e1._fmpz(), e2._fmpz())) +FLINT_DEFINE_BINARY_EXPR_COND2(lcm_op, fmpzxx, FMPZXX_COND_S, FMPZXX_COND_S, + fmpz_lcm(to._fmpz(), e1._fmpz(), e2._fmpz())) + +template +struct binary_expression< + T1, + typename mp::enable_if< + mp::and_< + traits::is_unsigned_integer, + traits::is_unsigned_integer >, + operations::bin_op>::type, + T2> +{ + typedef fmpzxx return_t; + template + static void doit(V& to, const T1& t1, const T2& t2) + { + fmpz_bin_uiui(to._fmpz(), t1, t2); + } +}; + +#define FMPZXX_DEFINE_DIVFUNCS(name) \ +FLINT_DEFINE_BINARY_EXPR_COND2(name##_op, fmpzxx, FMPZXX_COND_S, FMPZXX_COND_S, \ + fmpz_##name(to._fmpz(), e1._fmpz(), e2._fmpz())) \ +FLINT_DEFINE_BINARY_EXPR_COND2(name##_op, fmpzxx, FMPZXX_COND_S, \ + traits::is_signed_integer, \ + fmpz_##name##_si(to._fmpz(), e1._fmpz(), e2)) \ +FLINT_DEFINE_BINARY_EXPR_COND2(name##_op, fmpzxx, FMPZXX_COND_S, \ + traits::is_unsigned_integer, \ + fmpz_##name##_ui(to._fmpz(), e1._fmpz(), e2)) + +FMPZXX_DEFINE_DIVFUNCS(cdiv_q) +FMPZXX_DEFINE_DIVFUNCS(tdiv_q) +FMPZXX_DEFINE_DIVFUNCS(divexact) +FLINT_DEFINE_BINARY_EXPR_COND2(fdiv_r_op, fmpzxx, FMPZXX_COND_S, FMPZXX_COND_S, + fmpz_fdiv_r(to._fmpz(), e1._fmpz(), e2._fmpz())) + +FLINT_DEFINE_BINARY_EXPR_COND2(tdiv_q_2exp_op, fmpzxx, + FMPZXX_COND_S, traits::is_unsigned_integer, + fmpz_tdiv_q_2exp(to._fmpz(), e1._fmpz(), e2)) +FLINT_DEFINE_BINARY_EXPR_COND2(fdiv_r_2exp_op, fmpzxx, + FMPZXX_COND_S, traits::is_unsigned_integer, + fmpz_fdiv_r_2exp(to._fmpz(), e1._fmpz(), e2)) + +FLINT_DEFINE_BINARY_EXPR_COND2(invmod_op, fmpzxx, + FMPZXX_COND_S, FMPZXX_COND_S, + fmpz_invmod(to._fmpz(), e1._fmpz(), e2._fmpz())) +FLINT_DEFINE_BINARY_EXPR_COND2(negmod_op, fmpzxx, + FMPZXX_COND_S, FMPZXX_COND_S, + fmpz_negmod(to._fmpz(), e1._fmpz(), e2._fmpz())) + +FLINT_DEFINE_THREEARY_EXPR_COND3(mul2_op, fmpzxx, + FMPZXX_COND_S, traits::is_unsigned_integer, traits::is_unsigned_integer, + fmpz_mul2_uiui(to._fmpz(), e1._fmpz(), e2, e3)) +FLINT_DEFINE_THREEARY_EXPR_COND3(divexact2_op, fmpzxx, + FMPZXX_COND_S, traits::is_unsigned_integer, traits::is_unsigned_integer, + fmpz_divexact2_uiui(to._fmpz(), e1._fmpz(), e2, e3)) + +FLINT_DEFINE_THREEARY_EXPR_COND3(powm_op, fmpzxx, + FMPZXX_COND_S, traits::is_unsigned_integer, FMPZXX_COND_S, + fmpz_powm_ui(to._fmpz(), e1._fmpz(), e2, e3._fmpz())) +FLINT_DEFINE_THREEARY_EXPR_COND3(powm_op, fmpzxx, + FMPZXX_COND_S, FMPZXX_COND_S, FMPZXX_COND_S, + fmpz_powm(to._fmpz(), e1._fmpz(), e2._fmpz(), e3._fmpz())) + +FLINT_DEFINE_THREEARY_EXPR_COND3(mul_tdiv_q_2exp_op, fmpzxx, + FMPZXX_COND_S, FMPZXX_COND_S, traits::is_unsigned_integer, + fmpz_mul_tdiv_q_2exp(to._fmpz(), e1._fmpz(), e2._fmpz(), e3)) +FLINT_DEFINE_THREEARY_EXPR_COND3(mul_tdiv_q_2exp_op, fmpzxx, + FMPZXX_COND_S, traits::fits_into_slong, traits::is_unsigned_integer, + fmpz_mul_si_tdiv_q_2exp(to._fmpz(), e1._fmpz(), e2, e3)) +// TODO addmul, submul? + +namespace rdetail { +typedef make_ltuple::type>::type fmpzxx_pair; +typedef make_ltuple::type>::type fmpzxx_triple; +typedef make_ltuple::type>::type + bool_fmpzxx_pair; +} // rdetail + +FLINT_DEFINE_BINARY_EXPR_COND2(fdiv_qr_op, rdetail::fmpzxx_pair, + FMPZXX_COND_S, FMPZXX_COND_S, + fmpz_fdiv_qr(to.template get<0>()._fmpz(), to.template get<1>()._fmpz(), + e1._fmpz(), e2._fmpz())) +FLINT_DEFINE_BINARY_EXPR_COND2(tdiv_qr_op, rdetail::fmpzxx_pair, + FMPZXX_COND_S, FMPZXX_COND_S, + fmpz_tdiv_qr(to.template get<0>()._fmpz(), to.template get<1>()._fmpz(), + e1._fmpz(), e2._fmpz())) + +FLINT_DEFINE_BINARY_EXPR_COND2(sqrtmod_op, rdetail::bool_fmpzxx_pair, + FMPZXX_COND_S, FMPZXX_COND_S, + to.template get<0>() = fmpz_sqrtmod( + to.template get<1>()._fmpz(), e1._fmpz(), e2._fmpz())) + +FLINT_DEFINE_UNARY_EXPR_COND(sqrtrem_op, rdetail::fmpzxx_pair, + FMPZXX_COND_S, + fmpz_sqrtrem(to.template get<0>()._fmpz(), to.template get<1>()._fmpz(), + from._fmpz())) + +FLINT_DEFINE_BINARY_EXPR_COND2(gcdinv_op, rdetail::fmpzxx_pair, + FMPZXX_COND_S, FMPZXX_COND_S, + fmpz_gcdinv(to.template get<0>()._fmpz(), to.template get<1>()._fmpz(), + e1._fmpz(), e2._fmpz())) +FLINT_DEFINE_BINARY_EXPR_COND2(xgcd_op, rdetail::fmpzxx_triple, + FMPZXX_COND_S, FMPZXX_COND_S, fmpz_xgcd( + to.template get<0>()._fmpz(), to.template get<1>()._fmpz(), + to.template get<2>()._fmpz(), e1._fmpz(), e2._fmpz())) + +namespace rdetail { +template struct is_mplimb_t_vec + : mp::equal_types > { }; +} +FLINT_DEFINE_FIVEARY_EXPR_COND5(fmpzxx_bit_unpack_op, rdetail::bool_fmpzxx_pair, + rdetail::is_mplimb_t_vec, traits::fits_into_mp_bitcnt_t, + traits::fits_into_mp_bitcnt_t, traits::is_integer, tools::is_bool, + to.template get<0>() = fmpz_bit_unpack(to.template get<1>()._fmpz(), + &e1.front(), e3, e2, e4, e5)) +FLINT_DEFINE_THREEARY_EXPR_COND3(fmpzxx_bit_unpack_unsigned_op, fmpzxx, + rdetail::is_mplimb_t_vec, traits::fits_into_mp_bitcnt_t, + traits::fits_into_mp_bitcnt_t, + fmpz_bit_unpack_unsigned(to._fmpz(), &e1.front(), e3, e2)) + +// standard math functions (c/f stdmath.h) +FLINT_DEFINE_BINARY_EXPR_COND2(pow_op, fmpzxx, + FMPZXX_COND_S, traits::is_unsigned_integer, + fmpz_pow_ui(to._fmpz(), e1._fmpz(), e2)) +FLINT_DEFINE_BINARY_EXPR_COND2(root_op, fmpzxx, + FMPZXX_COND_S, traits::fits_into_slong, + fmpz_root(to._fmpz(), e1._fmpz(), e2)) +FLINT_DEFINE_UNARY_EXPR_COND(sqrt_op, fmpzxx, FMPZXX_COND_S, + fmpz_sqrt(to._fmpz(), from._fmpz())) +FLINT_DEFINE_UNARY_EXPR_COND(abs_op, fmpzxx, FMPZXX_COND_S, + fmpz_abs(to._fmpz(), from._fmpz())) + +namespace rdetail { +typedef make_ltuple::type>::type slong_fmpzxx_pair; +} // rdetail +FLINT_DEFINE_BINARY_EXPR_COND2(remove_op, rdetail::slong_fmpzxx_pair, + FMPZXX_COND_S, FMPZXX_COND_S, + to.template get<0>() = fmpz_remove(to.template get<1>()._fmpz(), + e1._fmpz(), e2._fmpz())) +} // rules + +// chinese remaindering +// TODO should this use nmod? +class fmpz_combxx +{ +private: + fmpz_comb_t comb; + mutable fmpz_comb_temp_t tmp; + + // not copyable + fmpz_combxx(const fmpz_combxx&); + +public: + fmpz_combxx(const std::vector& v) + { + fmpz_comb_init(comb, &v.front(), v.size()); + fmpz_comb_temp_init(tmp, comb); + } + + ~fmpz_combxx() + { + fmpz_comb_temp_clear(tmp); + fmpz_comb_clear(comb); + } + + const fmpz_comb_t& _comb() const {return comb;} + fmpz_comb_temp_t& _temp() const {return tmp;} +}; + +// TODO make lazy somehow? +template +inline typename mp::enable_if >::type +multi_mod(std::vector& out, const Fmpz& in, const fmpz_combxx& comb) +{ + fmpz_multi_mod_ui(&out.front(), in.evaluate()._fmpz(), + comb._comb(), comb._temp()); +} + +namespace rules { +FLINT_DEFINE_FIVEARY_EXPR_COND5(CRT_op, fmpzxx, FMPZXX_COND_S, FMPZXX_COND_S, + traits::is_unsigned_integer, traits::is_unsigned_integer, tools::is_bool, + fmpz_CRT_ui(to._fmpz(), e1._fmpz(), e2._fmpz(), e3, e4, e5)) + +FLINT_DEFINE_THREEARY_EXPR(multi_CRT_op, fmpzxx, + std::vector, fmpz_combxx, bool, + fmpz_multi_CRT_ui(to._fmpz(), &e1.front(), e2._comb(), e2._temp(), e3)) +} // rules +} // flint + +#include "fmpz_factorxx.h" + +#endif diff --git a/external/flint-2.4.3/fprintf.c b/external/flint-2.4.3/fprintf.c new file mode 100644 index 0000000..73b8737 --- /dev/null +++ b/external/flint-2.4.3/fprintf.c @@ -0,0 +1,125 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 William Hart + +******************************************************************************/ + +#include +#include +#include +#include +#include +#include "flint.h" + +size_t flint_fprintf(FILE * f, const char * str, ...) +{ + va_list ap; + size_t len = strlen(str); + char * str2 = flint_malloc(len + 1); + int w1 = 0, w2 = 0; + void * w3; + double d; + ulong wu; + slong w; + int args, floating; + size_t ret; + + /* deal with first substring */ + size_t n = strcspn(str, "%"); + strncpy(str2, str, n); + str2[n] = '\0'; + ret = fprintf(f, "%s", str2); + len -= n; + str += n; + + va_start(ap, str); + + while (len) /* deal with fmt spec prefixed strings */ + { + n = strcspn(str + 2, "%") + 2; /* be sure to skip a %% */ + strncpy(str2, str, n); + str2[n] = '\0'; + + switch (str[1]) + { + case 'w': + if (str[2] == 'x') + { + wu = (ulong) va_arg(ap, ulong); + ret += fprintf(f, WORD_FMT "x", wu); + ret += fprintf(f, "%s", str2 + 3); + } else if (str[2] == 'u') + { + wu = (ulong) va_arg(ap, ulong); + ret += fprintf(f, WORD_FMT "u", wu); + ret += fprintf(f, "%s", str2 + 3); + } else if (str[2] == 'd') + { + w = (slong) va_arg(ap, slong); + ret += fprintf(f, WORD_FMT "d", w); + ret += fprintf(f, "%s", str2 + 3); + } else + { + w = (slong) va_arg(ap, slong); + ret += fprintf(f, WORD_FMT "d", w); + ret += fprintf(f, "%s", str2 + 2); + } + break; + default: /* pass to fprintf */ + args = parse_fmt(&floating, str2); + if (args) + { + if (args == 3) + w1 = va_arg(ap, int); + if (args >= 2) + w2 = va_arg(ap, int); + if (floating) + { + d = va_arg(ap, double); + if (args == 2) + ret += fprintf(f, str2, w2, d); + else if (args == 3) + ret += fprintf(f, str2, w1, w2, d); + else + ret += fprintf(f, str2, d); + } else + { + w3 = va_arg(ap, void *); + if (args == 2) + ret += fprintf(f, str2, w2, w3); + else if (args == 3) + ret += fprintf(f, str2, w1, w2, w3); + else + ret += fprintf(f, str2, w3); + } + } else ret += fprintf(f, "%s", str2); /* zero args */ + } + + len -= n; + str += n; + } + + va_end(ap); + flint_free(str2); + + return ret; +} diff --git a/external/flint-2.4.3/fq.h b/external/flint-2.4.3/fq.h new file mode 100644 index 0000000..88b3932 --- /dev/null +++ b/external/flint-2.4.3/fq.h @@ -0,0 +1,365 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#ifndef FQ_H +#define FQ_H + +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" + +/* Data types and context ****************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef fmpz_poly_t fq_t; +typedef fmpz_poly_struct fq_struct; + +typedef struct +{ + fmpz p; + + int sparse_modulus; + + fmpz *a; + slong *j; + slong len; + + fmpz_mod_poly_t modulus; + fmpz_mod_poly_t inv; + + char *var; +} +fq_ctx_struct; + +typedef fq_ctx_struct fq_ctx_t[1]; + +void fq_ctx_init(fq_ctx_t ctx, const fmpz_t p, slong d, const char *var); + +int _fq_ctx_init_conway(fq_ctx_t ctx, const fmpz_t p, slong d, const char *var); + +void fq_ctx_init_conway(fq_ctx_t ctx, const fmpz_t p, slong d, const char *var); + +void fq_ctx_init_modulus(fq_ctx_t ctx, + fmpz_mod_poly_t modulus, + const char *var); + +void fq_ctx_randtest(fq_ctx_t ctx, flint_rand_t state); + +void fq_ctx_clear(fq_ctx_t ctx); + +static __inline__ slong fq_ctx_degree(const fq_ctx_t ctx) +{ + return ctx->modulus->length - 1; +} + +#define fq_ctx_prime(ctx) (&((ctx)->p)) + +static __inline__ void fq_ctx_order(fmpz_t f, const fq_ctx_t ctx) +{ + fmpz_set(f, fq_ctx_prime(ctx)); + fmpz_pow_ui(f, f, fq_ctx_degree(ctx)); +} + +static __inline__ int fq_ctx_fprint(FILE * file, const fq_ctx_t ctx) +{ + int r; + + r = flint_fprintf(file, "p = "); + if (r <= 0) + return r; + + r = fmpz_fprint(file, fq_ctx_prime(ctx)); + if (r <= 0) + return r; + + r = flint_fprintf(file, "\nd = %wd\n", fq_ctx_degree(ctx)); + if (r <= 0) + return r; + + r = flint_fprintf(file, "f(X) = "); + if (r <= 0) + return r; + + r = fmpz_mod_poly_fprint_pretty(file, ctx->modulus, "X"); + if (r <= 0) + return r; + + r = flint_fprintf(file, "\n"); + + return r; +} + +static __inline__ void fq_ctx_print(const fq_ctx_t ctx) +{ + fq_ctx_fprint(stdout, ctx); +} + + +/* Memory managment *********************************************************/ + +static __inline__ void fq_init(fq_t rop, const fq_ctx_t ctx) +{ + fmpz_poly_init(rop); +} + +static __inline__ void fq_init2(fq_t rop, const fq_ctx_t ctx) +{ + fmpz_poly_init2(rop, fq_ctx_degree(ctx)); +} + +static __inline__ void fq_clear(fq_t rop, const fq_ctx_t ctx) +{ + fmpz_poly_clear(rop); +} + +static __inline__ +void _fq_sparse_reduce(fmpz *R, slong lenR, const fq_ctx_t ctx) +{ + const slong d = ctx->j[ctx->len - 1]; + + FMPZ_VEC_NORM(R, lenR); + + if (lenR > d) + { + slong i, k; + + for (i = lenR - 1; i >= d; i--) + { + for (k = ctx->len - 2; k >= 0; k--) + { + fmpz_submul(R + ctx->j[k] + i - d, R + i, ctx->a + k); + } + fmpz_zero(R + i); + } + } + + _fmpz_vec_scalar_mod_fmpz(R, R, FLINT_MIN(d, lenR), fq_ctx_prime(ctx)); +} + +static __inline__ void _fq_dense_reduce(fmpz* R, slong lenR, const fq_ctx_t ctx) +{ + fmpz *q, *r; + + if (lenR < ctx->modulus->length) + { + _fmpz_vec_scalar_mod_fmpz(R, R, lenR, fq_ctx_prime(ctx)); + return; + } + + q = _fmpz_vec_init(lenR - ctx->modulus->length + 1); + r = _fmpz_vec_init(ctx->modulus->length - 1); + + _fmpz_mod_poly_divrem_newton_n_preinv(q, r, R, lenR, + ctx->modulus->coeffs, ctx->modulus->length, + ctx->inv->coeffs, ctx->inv->length, + fq_ctx_prime(ctx)); + + _fmpz_vec_set(R, r, ctx->modulus->length - 1); + _fmpz_vec_clear(q, lenR - ctx->modulus->length + 1); + _fmpz_vec_clear(r, ctx->modulus->length - 1); + +} + + +static __inline__ void _fq_reduce(fmpz* R, slong lenR, const fq_ctx_t ctx) +{ + if (ctx->sparse_modulus) + _fq_sparse_reduce(R, lenR, ctx); + else + _fq_dense_reduce(R, lenR, ctx); +} + +static __inline__ void fq_reduce(fq_t rop, const fq_ctx_t ctx) +{ + _fq_reduce(rop->coeffs, rop->length, ctx); + rop->length = FLINT_MIN(rop->length, ctx->modulus->length - 1); + _fmpz_poly_normalise(rop); +} + +/* Basic arithmetic **********************************************************/ + +void fq_add(fq_t rop, const fq_t op1, const fq_t op2, const fq_ctx_t ctx); + +void fq_sub(fq_t rop, const fq_t op1, const fq_t op2, const fq_ctx_t ctx); + +void fq_sub_one(fq_t rop, const fq_t op1, const fq_ctx_t ctx); + +void fq_neg(fq_t rop, const fq_t op1, const fq_ctx_t ctx); + +void fq_mul(fq_t rop, const fq_t op1, const fq_t op2, const fq_ctx_t ctx); + +void fq_mul_fmpz(fq_t rop, const fq_t op, const fmpz_t x, const fq_ctx_t ctx); + +void fq_mul_si(fq_t rop, const fq_t op, slong x, const fq_ctx_t ctx); + +void fq_mul_ui(fq_t rop, const fq_t op, ulong x, const fq_ctx_t ctx); + +void fq_sqr(fq_t rop, const fq_t op, const fq_ctx_t ctx); + +void fq_inv(fq_t rop, const fq_t op1, const fq_ctx_t ctx); + +void _fq_pow(fmpz *rop, const fmpz *op, slong len, const fmpz_t e, + const fq_ctx_t ctx); + +void fq_pow(fq_t rop, const fq_t op1, const fmpz_t e, const fq_ctx_t ctx); + +void fq_pow_ui(fq_t rop, const fq_t op, const ulong e, const fq_ctx_t ctx); + +void fq_pth_root(fq_t rop, const fq_t op1, const fq_ctx_t ctx); + +/* Randomisation *************************************************************/ + +void fq_randtest(fq_t rop, flint_rand_t state, const fq_ctx_t ctx); + +void fq_randtest_dense(fq_t rop, flint_rand_t state, const fq_ctx_t ctx); + +void fq_randtest_not_zero(fq_t rop, flint_rand_t state, const fq_ctx_t ctx); + +/* Comparison ****************************************************************/ + +static __inline__ int fq_equal(const fq_t op1, const fq_t op2, const fq_ctx_t ctx) +{ + return fmpz_poly_equal(op1, op2); +} + +static __inline__ int fq_is_zero(const fq_t op, const fq_ctx_t ctx) +{ + return fmpz_poly_is_zero(op); +} + +static __inline__ int fq_is_one(const fq_t op, const fq_ctx_t ctx) +{ + return fmpz_poly_is_one(op); +} + +/* Assignments and conversions ***********************************************/ + +static __inline__ void fq_set(fq_t rop, const fq_t op, const fq_ctx_t ctx) +{ + fmpz_poly_set(rop, op); +} + +static __inline__ void fq_set_fmpz(fq_t rop, const fmpz_t x, const fq_ctx_t ctx) +{ + fmpz_poly_set_fmpz(rop, x); + fq_reduce(rop, ctx); +} + +static __inline__ void fq_set_ui(fq_t rop, const ulong x, const fq_ctx_t ctx) +{ + fmpz_poly_set_ui(rop, x); + fq_reduce(rop, ctx); +} + +static __inline__ void fq_swap(fq_t op1, fq_t op2, const fq_ctx_t ctx) +{ + fmpz_poly_swap(op1, op2); +} + +static __inline__ void fq_zero(fq_t rop, const fq_ctx_t ctx) +{ + fmpz_poly_zero(rop); +} + +static __inline__ void fq_one(fq_t rop, const fq_ctx_t ctx) +{ + fmpz_poly_one(rop); +} + +static __inline__ void fq_gen(fq_t rop, const fq_ctx_t ctx) +{ + fmpz_poly_zero(rop); + fmpz_poly_set_coeff_ui(rop, 0, 0); + fmpz_poly_set_coeff_ui(rop, 1, 1); +} + +/* Output ********************************************************************/ + +static __inline__ +int fq_fprint(FILE * file, const fq_t op, const fq_ctx_t ctx) +{ + return fmpz_poly_fprint(file, op); +} + +static __inline__ +void fq_print(const fq_t op, const fq_ctx_t ctx) +{ + fmpz_poly_print(op); +} + +static __inline__ +int fq_fprint_pretty(FILE * file, const fq_t op, const fq_ctx_t ctx) +{ + return fmpz_poly_fprint_pretty(file, op, ctx->var); +} + +static __inline__ +int fq_print_pretty(const fq_t op, const fq_ctx_t ctx) +{ + return fmpz_poly_print_pretty(op, ctx->var); +} + +char * +fq_get_str(const fq_t op, const fq_ctx_t ctx); + +char * +fq_get_str_pretty(const fq_t op, const fq_ctx_t ctx); + +/* Special functions *********************************************************/ + +void _fq_trace(fmpz_t rop, const fmpz *op, slong len, const fq_ctx_t ctx); + +void fq_trace(fmpz_t rop, const fq_t op, const fq_ctx_t ctx); + +void _fq_frobenius(fmpz *rop, const fmpz *op, slong len, slong e, + const fq_ctx_t ctx); + +void fq_frobenius(fq_t rop, const fq_t op, slong e, const fq_ctx_t ctx); + +void _fq_norm(fmpz_t rop, const fmpz *op, slong len, const fq_ctx_t ctx); + +void fq_norm(fmpz_t rop, const fq_t op, const fq_ctx_t ctx); + + +/* Bit packing ******************************************************/ + +void +fq_bit_pack(fmpz_t f, const fq_t op, mp_bitcnt_t bit_size, + const fq_ctx_t ctx); + +void +fq_bit_unpack(fq_t rop, const fmpz_t f, mp_bitcnt_t bit_size, + const fq_ctx_t ctx); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/external/flint-2.4.3/fq/Makefile b/external/flint-2.4.3/fq/Makefile new file mode 100644 index 0000000..6969798 --- /dev/null +++ b/external/flint-2.4.3/fq/Makefile @@ -0,0 +1,54 @@ +SOURCES = $(wildcard *.c) + +OBJS = $(patsubst %.c, $(BUILD_DIR)/$(MOD_DIR)_%.o, $(SOURCES)) + +LOBJS = $(patsubst %.c, $(BUILD_DIR)/%.lo, $(SOURCES)) +MOD_LOBJ = $(BUILD_DIR)/../$(MOD_DIR).lo + +TEST_SOURCES = $(wildcard test/*.c) + +PROF_SOURCES = $(wildcard profile/*.c) + +TUNE_SOURCES = $(wildcard tune/*.c) + +TESTS = $(patsubst %.c, $(BUILD_DIR)/%, $(TEST_SOURCES)) + +TESTS_RUN = $(patsubst %, %_RUN, $(TESTS)) + +PROFS = $(patsubst %.c, %, $(PROF_SOURCES)) + +TUNE = $(patsubst %.c, %, $(TUNE_SOURCES)) + +all: shared static + +shared: $(MOD_LOBJ) + +static: $(OBJS) + +profile: $(PROF_SOURCES) + $(foreach prog, $(PROFS), $(CC) $(ABI_FLAG) -O2 -std=c99 $(INCS) $(prog).c ../profiler.o -o $(BUILD_DIR)/$(prog) $(LIBS) || exit $$?;) + +tune: $(TUNE_SOURCES) + $(foreach prog, $(TUNE), $(CC) $(ABI_FLAG) -O2 -std=c99 $(INCS) $(prog).c -o $(BUILD_DIR)/$(prog) $(LIBS) || exit $$?;) + +$(BUILD_DIR)/$(MOD_DIR)_%.o: %.c + $(CC) $(CFLAGS) -c $(INCS) $< -o $@ + +$(MOD_LOBJ): $(LOBJS) + $(CC) $(ABI_FLAG) -Wl,-r $^ -o $@ -nostdlib + +$(BUILD_DIR)/%.lo: %.c + $(CC) $(PICFLAG) $(CFLAGS) $(INCS) -c $< -o $@ + +clean: + rm -rf $(BUILD_DIR) $(MOD_LOBJ) + +check: $(TESTS) $(TESTS_RUN) + +$(BUILD_DIR)/test/%: test/%.c + $(CC) $(CFLAGS) $(INCS) $< ../test_helpers.o -o $@ $(LIBS) + +%_RUN: % + @$< + +.PHONY: profile tune clean check all shared static %_RUN diff --git a/external/flint-2.4.3/fq/add.c b/external/flint-2.4.3/fq/add.c new file mode 100644 index 0000000..b649c94 --- /dev/null +++ b/external/flint-2.4.3/fq/add.c @@ -0,0 +1,43 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq.h" + +void +fq_add(fq_t rop, const fq_t op1, const fq_t op2, const fq_ctx_t ctx) +{ + slong max = FLINT_MAX(op1->length, op2->length); + + fmpz_poly_fit_length(rop, max); + + _fmpz_mod_poly_add(rop->coeffs, + op1->coeffs, op1->length, op2->coeffs, op2->length, + fq_ctx_prime(ctx)); + + _fmpz_poly_set_length(rop, max); + _fmpz_poly_normalise(rop); +} diff --git a/external/flint-2.4.3/fq/bit_pack.c b/external/flint-2.4.3/fq/bit_pack.c new file mode 100644 index 0000000..4a89955 --- /dev/null +++ b/external/flint-2.4.3/fq/bit_pack.c @@ -0,0 +1,34 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq.h" + +void +fq_bit_pack(fmpz_t f, const fq_t op, mp_bitcnt_t bit_size, + const fq_ctx_t ctx) +{ + fmpz_poly_bit_pack(f, op, bit_size); +} + diff --git a/external/flint-2.4.3/fq/bit_unpack.c b/external/flint-2.4.3/fq/bit_unpack.c new file mode 100644 index 0000000..3c33481 --- /dev/null +++ b/external/flint-2.4.3/fq/bit_unpack.c @@ -0,0 +1,34 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq.h" + +void +fq_bit_unpack(fq_t rop, const fmpz_t f, mp_bitcnt_t bit_size, + const fq_ctx_t ctx) +{ + fmpz_poly_bit_unpack_unsigned(rop, f, bit_size); + fq_reduce(rop, ctx); +} diff --git a/external/flint-2.4.3/fq/ctx_clear.c b/external/flint-2.4.3/fq/ctx_clear.c new file mode 100644 index 0000000..6c0af11 --- /dev/null +++ b/external/flint-2.4.3/fq/ctx_clear.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq.h" + +void +fq_ctx_clear(fq_ctx_t ctx) +{ + fmpz_mod_poly_clear(ctx->modulus); + fmpz_mod_poly_clear(ctx->inv); + fmpz_clear(fq_ctx_prime(ctx)); + flint_free(ctx->var); + _fmpz_vec_clear(ctx->a, ctx->len); + flint_free(ctx->j); +} diff --git a/external/flint-2.4.3/fq/ctx_init.c b/external/flint-2.4.3/fq/ctx_init.c new file mode 100644 index 0000000..0fce73b --- /dev/null +++ b/external/flint-2.4.3/fq/ctx_init.c @@ -0,0 +1,52 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include +#include + +#include "fq.h" +#include "fq_poly.h" + +void +fq_ctx_init(fq_ctx_t ctx, const fmpz_t p, slong d, const char *var) +{ + flint_rand_t state; + fmpz_mod_poly_t poly; + + if (_fq_ctx_init_conway(ctx, p, d, var)) + { + return; + } + + flint_randinit(state); + + fmpz_mod_poly_init2(poly, p, d + 1); + fmpz_mod_poly_randtest_sparse_irreducible(poly, state, d + 1); + + fq_ctx_init_modulus(ctx, poly, var); + + fmpz_mod_poly_clear(poly); + flint_randclear(state); +} diff --git a/external/flint-2.4.3/fq/ctx_init_conway.c b/external/flint-2.4.3/fq/ctx_init_conway.c new file mode 100644 index 0000000..d8d64ce --- /dev/null +++ b/external/flint-2.4.3/fq/ctx_init_conway.c @@ -0,0 +1,128 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Andres Goens + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include +#include + +#include "fq.h" + +#ifndef FLINT_CPIMPORT +#define FLINT_CPIMPORT "../qadic/CPimport.txt" +#endif + +int +_fq_ctx_init_conway(fq_ctx_t ctx, const fmpz_t p, slong d, const char *var) +{ + char *buf; + FILE *file; + + if (fmpz_cmp_ui(p, 109987) > 0) + { + return 0; + } + + buf = flint_malloc(832); + file = fopen(FLINT_CPIMPORT, "r"); + + if (!file) + { + file = fopen("../qadic/CPimport.txt", "r"); + + if (!file) + { + flint_printf("Exception (fq_ctx_init_conway). File loading.\n"); + abort(); + } + } + + while (fgets(buf, 832, file)) + { + char *tmp = buf; + + /* Different prime? */ + if (fmpz_cmp_ui(p, atoi(tmp))) + continue; + + while (*tmp++ != ' ') ; + + /* Same degree? */ + if (d == atoi(tmp)) + { + fmpz_mod_poly_t mod; + slong i; + char *ptr; + + fmpz_mod_poly_init(mod, p); + + /* Copy the polynomial */ + ptr = tmp; + + for (i = 0; i < d; i++) + { + int coeff; + + while (*ptr++ != ' ') ; + + coeff = atoi(ptr); + fmpz_mod_poly_set_coeff_ui(mod, i, coeff); + } + fmpz_mod_poly_set_coeff_ui(mod, d, 1); + + fq_ctx_init_modulus(ctx, mod, var); + + fmpz_mod_poly_clear(mod); + fclose(file); + flint_free(buf); + return 1; + } + } + fclose(file); + flint_free(buf); + return 0; +} + +void +fq_ctx_init_conway(fq_ctx_t ctx, const fmpz_t p, slong d, const char *var) +{ + int result; + if (fmpz_cmp_ui(p, 109987) > 0) + { + flint_printf("Exception (fq_ctx_init_conway). Conway polynomials \n"); + flint_printf("are only available for primes up to 109987.\n"); + abort(); + } + + result = _fq_ctx_init_conway(ctx, p, d, var); + if (!result) + { + flint_printf + ("Exception (fq_ctx_init_conway). The polynomial for \n(p,d) = ("); + fmpz_print(p); + flint_printf(",%wd) is not present in the database.\n", d); + abort(); + } +} diff --git a/external/flint-2.4.3/fq/ctx_init_modulus.c b/external/flint-2.4.3/fq/ctx_init_modulus.c new file mode 100644 index 0000000..596c374 --- /dev/null +++ b/external/flint-2.4.3/fq/ctx_init_modulus.c @@ -0,0 +1,92 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include +#include + +#include "fq.h" +#include "fq_poly.h" + +void +fq_ctx_init_modulus(fq_ctx_t ctx, fmpz_mod_poly_t modulus, const char *var) +{ + slong nz; + int i, j; + fmpz* p; + fmpz_t inv; + + p = &(modulus->p); + + /* Count number of nonzero coefficients */ + nz = 0; + for (i = 0; i < modulus->length; i++) + { + if (!fmpz_is_zero(modulus->coeffs + i)) + { + nz += 1; + } + } + + ctx->len = nz; + ctx->a = _fmpz_vec_init(ctx->len); + ctx->j = flint_malloc(ctx->len * sizeof(slong)); + + fmpz_init(inv); + fmpz_invmod(inv, modulus->coeffs + modulus->length - 1, p); + + /* Copy the polynomial */ + j = 0; + for (i = 0; i < modulus->length; i++) + { + if (!fmpz_is_zero(modulus->coeffs + i)) + { + fmpz_mul(ctx->a + j, inv, modulus->coeffs + i); + fmpz_mod(ctx->a + j, ctx->a + j, p); + ctx->j[j] = i; + j++; + } + } + + fmpz_clear(inv); + + if (ctx->len < 6) + ctx->sparse_modulus = 1; + else + ctx->sparse_modulus = 0; + + fmpz_init_set(fq_ctx_prime(ctx), p); + + ctx->var = flint_malloc(strlen(var) + 1); + strcpy(ctx->var, var); + + /* Set the modulus */ + fmpz_mod_poly_init(ctx->modulus, fq_ctx_prime(ctx)); + fmpz_mod_poly_set(ctx->modulus, modulus); + + /* Precompute the inverse of the modulus */ + fmpz_mod_poly_init(ctx->inv, fq_ctx_prime(ctx)); + fmpz_mod_poly_reverse(ctx->inv, ctx->modulus, ctx->modulus->length); + fmpz_mod_poly_inv_series_newton(ctx->inv, ctx->inv, ctx->modulus->length); +} diff --git a/external/flint-2.4.3/fq/ctx_randtest.c b/external/flint-2.4.3/fq/ctx_randtest.c new file mode 100644 index 0000000..3a2da7d --- /dev/null +++ b/external/flint-2.4.3/fq/ctx_randtest.c @@ -0,0 +1,59 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq.h" + +void +fq_ctx_randtest(fq_ctx_t ctx, flint_rand_t state) +{ + fmpz_mod_poly_t modulus; + fmpz_t p, x; + slong d; + + fmpz_init(p); + fmpz_set_ui(p, n_randprime(state, 2 + n_randint(state, 6), 1)); + d = n_randint(state, 10) + 1; + fq_ctx_init_conway(ctx, p, d, "a"); + fmpz_clear(p); + + /* Test non-monic modulus */ + if (n_randint(state, 2)) + { + fmpz_init_set(x, p); + fmpz_sub_ui(x, x, 1); + fmpz_mod_poly_init(modulus, p); + fmpz_mod_poly_set(modulus, ctx->modulus); + fmpz_randm(x, state, x); + fmpz_add_ui(x, x, 1); + fmpz_mod_poly_scalar_mul_fmpz(modulus, modulus, x); + fq_ctx_clear(ctx); + fq_ctx_init_modulus(ctx, modulus, "a"); + fmpz_mod_poly_clear(modulus); + fmpz_clear(x); + } + +} diff --git a/external/flint-2.4.3/fq/doc/fq.txt b/external/flint-2.4.3/fq/doc/fq.txt new file mode 100644 index 0000000..23bd276 --- /dev/null +++ b/external/flint-2.4.3/fq/doc/fq.txt @@ -0,0 +1,468 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + Copyright (C) 2012, 2013 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +******************************************************************************* + + Context Management + +******************************************************************************* + +void fq_ctx_init(fq_ctx_t ctx, const fmpz_t p, slong d, const char *var) + + Initialises the context for prime~$p$ and extension degree~$d$, + with name \code{var} for the generator. By default, it will try + use a Conway polynomial; if one is not available, a random + irreducible polynomial will be used. + + Assumes that $p$ is a prime. + + Assumes that the string \code{var} is a null-terminated string + of length at least one. + +int _fq_ctx_init_conway(fq_ctx_t ctx, const fmpz_t p, slong d, const char *var) + + Attempts to initialise the context for prime~$p$ and extension + degree~$d$, with name \code{var} for the generator using a Conway + polynomial for the modulus. + + Returns $1$ if the Conway polynomial is in the database for the + given size and the initialization is successful; otherwise, + returns $0$. + + Assumes that $p$ is a prime. + + Assumes that the string \code{var} is a null-terminated string + of length at least one. + + +void fq_ctx_init_conway(fq_ctx_t ctx, const fmpz_t p, slong d, const char *var) + + Initialises the context for prime~$p$ and extension degree~$d$, + with name \code{var} for the generator using a Conway polynomial + for the modulus. + + Assumes that $p$ is a prime. + + Assumes that the string \code{var} is a null-terminated string + of length at least one. + +void fq_ctx_init_modulus(fq_ctx_t ctx, + fmpz_mod_poly_t modulus, + const char *var) + + Initialises the context for given \code{modulus} with name + \code{var} for the generator. + + Assumes that \code{modulus} is and irreducible polynomial over + $\mathbf{F}_{p}$. + + Assumes that the string \code{var} is a null-terminated string + of length at least one. + +void fq_ctx_clear(fq_ctx_t ctx) + + Clears all memory that has been allocated as part of the context. + +long fq_ctx_degree(const fq_ctx_t ctx) + + Returns the degree of the field extension + $[\mathbf{F}_{q} : \mathbf{F}_{p}]$, which + is equal to $\log_{p} q$. + +fmpz * fq_ctx_prime(const fq_ctx_t ctx) + + Returns a pointer to the prime $p$ in the context. + +void fq_ctx_order(fmpz_t f, const fq_ctx_t ctx) + + Sets $f$ to be the size of the finite field. + +int fq_ctx_fprint(FILE * file, const fq_ctx_t ctx) + + Prints the context information to {\tt{file}}. Returns 1 for a + success and a negative number for an error. + +void fq_ctx_print(const fq_ctx_t ctx) + + Prints the context information to {\tt{stdout}}. + +void fq_ctx_randtest(fq_ctx_t ctx) + + Initializes \code{ctx} to a random finite field. Assumes that + \code{fq_ctx_init} as not been called on \code{ctx} already. + +void fq_ctx_randtest_reducible(fq_ctx_t ctx) + + Initializes \code{ctx} to a random extension of a prime field. + The modulus may or may not be irreducible. Assumes that + \code{fq_ctx_init} as not been called on \code{ctx} already. + +******************************************************************************* + + Memory management + +******************************************************************************* + +void fq_init(fq_t rop, const fq_ctx_t ctx) + + Initialises the element \code{rop}, setting its value to~$0$. + +void fq_init2(fq_t rop, const fq_ctx_t ctx) + + Initialises \code{poly} with at least enough space for it to be an element + of \code{ctx} and sets it to~$0$. + +void fq_clear(fq_t rop, const fq_ctx_t ctx) + + Clears the element \code{rop}. + +void _fq_sparse_reduce(fmpz *R, slong lenR, const fq_ctx_t ctx) + + Reduces \code{(R, lenR)} modulo the polynomial $f$ given by the + modulus of \code{ctx}. + +void _fq_dense_reduce(fmpz *R, slong lenR, const fq_ctx_t ctx) + + Reduces \code{(R, lenR)} modulo the polynomial $f$ given by the + modulus of \code{ctx} using Newton division. + +void _fq_reduce(fmpz *r, slong lenR, const fq_ctx_t ctx) + + Reduces \code{(R, lenR)} modulo the polynomial $f$ given by the + modulus of \code{ctx}. Does either sparse or dense reduction + based on \code{ctx->sparse_modulus}. + +void fq_reduce(fq_t rop, const fq_ctx_t ctx) + + Reduces the polynomial \code{rop} as an element of + $\mathbf{F}_p[X] / (f(X))$. + +******************************************************************************* + + Basic arithmetic + +******************************************************************************* + +void fq_add(fq_t rop, const fq_t op1, const fq_t op2, const fq_ctx_t ctx) + + Sets \code{rop} to the sum of \code{op1} and \code{op2}. + +void fq_sub(fq_t rop, const fq_t op1, const fq_t op2, const fq_ctx_t ctx) + + Sets \code{rop} to the difference of \code{op1} and \code{op2}. + +void fq_sub_one(fq_t rop, const fq_t op1, const fq_ctx_t ctx) + + Sets \code{rop} to the difference of \code{op1} and $1$. + +void fq_neg(fq_t rop, const fq_t op, const fq_ctx_t ctx) + + Sets \code{rop} to the negative of \code{op}. + +void fq_mul(fq_t rop, const fq_t op1, const fq_t op2, const fq_ctx_t ctx) + + Sets \code{rop} to the product of \code{op1} and \code{op2}, + reducing the output in the given context. + +void fq_mul_fmpz(fq_t rop, const fq_t op, const fmpz_t x, const fq_ctx_t ctx) + + Sets \code{rop} to the product of \code{op} and $x$, + reducing the output in the given context. + +void fq_mul_si(fq_t rop, const fq_t op, slong x, const fq_ctx_t ctx) + + Sets \code{rop} to the product of \code{op} and $x$, + reducing the output in the given context. + +void fq_mul_ui(fq_t rop, const fq_t op, ulong x, const fq_ctx_t ctx) + + Sets \code{rop} to the product of \code{op} and $x$, + reducing the output in the given context. + +void fq_sqr(fq_t rop, const fq_t op, const fq_ctx_t ctx) + + Sets \code{rop} to the square of \code{op}, + reducing the output in the given context. + +void _fq_inv(fmpz *rop, const fmpz *op, slong len, const fq_ctx_t ctx) + + Sets \code{(rop, d)} to the inverse of the non-zero element + \code{(op, len)}. + +void fq_inv(fq_t rop, const fq_t op, const fq_ctx_t ctx) + + Sets \code{rop} to the inverse of the non-zero element \code{op}. + +void _fq_pow(fmpz *rop, const fmpz *op, slong len, const fmpz_t e, + const fq_ctx_t ctx) + + Sets \code{(rop, 2*d-1)} to \code{(op,len)} raised to the power~$e$, + reduced modulo $f(X)$, the modulus of \code{ctx}. + + Assumes that $e \geq 0$ and that \code{len} is positive and at most~$d$. + + Although we require that \code{rop} provides space for + $2d - 1$ coefficients, the output will be reduced modulo + $f(X)$, which is a polynomial of degree~$d$. + + Does not support aliasing. + +void fq_pow(fq_t rop, const fq_t op, const fmpz_t e, const fq_ctx_t ctx) + + Sets \code{rop} the \code{op} raised to the power~$e$. + + Currently assumes that $e \geq 0$. + + Note that for any input \code{op}, \code{rop} is set to~$1$ + whenever $e = 0$. + +void fq_pow_ui(fq_t rop, const fq_t op, const ulong e, const fq_ctx_t ctx) + + Sets \code{rop} the \code{op} raised to the power~$e$. + + Currently assumes that $e \geq 0$. + + Note that for any input \code{op}, \code{rop} is set to~$1$ + whenever $e = 0$. + + +******************************************************************************* + + Roots + +******************************************************************************* + +void fq_pth_root(fq_t rop, const fq_t op1, const fq_ctx_t ctx) + + Sets \code{rop} to a $p^{th}$ root root of \code{op1}. Currently, + this computes the root by raising \code{op1} to $p^{d-1}$ where + $d$ is the degree of the extension. + +******************************************************************************* + + Output + +******************************************************************************* + +int fq_fprint_pretty(FILE *file, const fq_t op, const fq_ctx_t ctx) + + Prints a pretty representation of \code{op} to \code{file}. + + In the current implementation, always returns~$1$. The return code is + part of the function's signature to allow for a later implementation to + return the number of characters printed or a non-positive error code. + +int fq_print_pretty(const fq_t op, const fq_ctx_t ctx) + + Prints a pretty representation of \code{op} to \code{stdout}. + + In the current implementation, always returns~$1$. The return code is + part of the function's signature to allow for a later implementation to + return the number of characters printed or a non-positive error code. + +void fq_fprint(FILE * file, const fq_t op, const fq_ctx_t ctx) + + Prints a representation of \code{op} to \code{file}. + + For further details on the representation used, see + \code{fmpz_mod_poly_fprint()}. + +void fq_print(const fq_t op, const fq_ctx_t ctx) + + Prints a representation of \code{op} to \code{stdout}. + + For further details on the representation used, see + \code{fmpz_mod_poly_print()}. + +char * fq_get_str(const fq_t op, const fq_ctx_t ctx) + + Returns the plain FLINT string representation of the element + \code{op}. + +char * fq_get_str_pretty(const fq_t op, const fq_ctx_t ctx) + + Returns a pretty representation of the element~\code{op} using the + null-terminated string \code{x} as the variable name. + +******************************************************************************* + + Randomisation + +******************************************************************************* + +void fq_randtest(fq_t rop, flint_rand_t state, const fq_ctx_t ctx) + + Generates a random element of $\mathbb{F}_q$. + +void fq_randtest_not_zero(fq_t rop, flint_rand_t state, + const fq_ctx_t ctx) + + Generates a random non-zero element of $\mathbb{F}_q$. + +void fq_randtest_dense(fq_t rop, flint_rand_t state, const fq_ctx_t ctx) + + Generates a random element of $\mathbb{F}_q$ which has an + underlying polynomial with dense coefficients. + +******************************************************************************* + + Assignments and conversions + +******************************************************************************* + +void fq_set(fq_t rop, const fq_t op, const fq_ctx_t ctx) + + Sets \code{rop} to \code{op}. + +void fq_set_ui(fq_t rop, const ulong x, const fq_ctx_t ctx) + + Sets \code{rop} to \code{x}, considered as an element of + $\mathbb{F}_p$. + +void fq_set_fmpz(fq_t rop, const fmpz_t x, const fq_ctx_t ctx) + + Sets \code{rop} to \code{x}, considered as an element of + $\mathbb{F}_p$. + +void fq_swap(fq_t op1, fq_t op2, const fq_ctx_t ctx) + + Swaps the two elements \code{op1} and \code{op2}. + +void fq_zero(fq_t rop, const fq_ctx_t ctx) + + Sets \code{rop} to zero. + +void fq_one(fq_t rop, const fq_ctx_t ctx) + + Sets \code{rop} to one, reduced in the given context. + +void fq_gen(fq_t rop, const fq_ctx_t ctx) + + Sets \code{rop} to a multiplicative generator for the finite field. + +******************************************************************************* + + Comparison + +******************************************************************************* + +int fq_is_zero(const fq_t op, const fq_ctx_t ctx) + + Returns whether \code{op} is equal to zero. + +int fq_is_one(const fq_t op, const fq_ctx_t ctx) + + Returns whether \code{op} is equal to one. + +int fq_equal(const fq_t op1, const fq_t op2, const fq_ctx_t ctx) + + Returns whether \code{op1} and \code{op2} are equal. + +int fq_is_invertible(const fq_t op, const fq_ctx_t ctx) + + Returns whether \code{op} is an invertible element. + +int fq_is_invertible_f(fq_t f, const fq_t op, const fq_ctx_t ctx) + + Returns whether \code{op} is an invertible element. If it is not, + then \code{f} is set of a factor of the modulus. + +******************************************************************************* + + Special functions + +******************************************************************************* + +void _fq_trace(fmpz_t rop, const fmpz *op, slong len, const fq_ctx_t ctx) + + Sets \code{rop} to the trace of the non-zero element \code{(op, len)} + in $\mathbf{F}_{q}$. + +void fq_trace(fq_t rop, const fq_t op, const fq_ctx_t ctx) + + Sets \code{rop} to the trace of \code{op}. + + For an element $a \in \mathbb{F}_q$, multiplication by $a$ defines + a $\mathbb{F}_p$-linear map on $\mathbb{F}_q$. We define the + trace of $a$ as the trace of this map. Equivalently, if $\Sigma$ + generates $\Gal(\mathbb{F}_q / \mathbb{F}_p)$ then the trace of + $a$ is equal to $\sum_{i=0}^{d-1} \Sigma^i (a)$, where $d = + \log_{p} q$. + +void _fq_norm(fmpz_t rop, const fmpz *op, slong len, const fq_ctx_t ctx) + + Sets \code{rop} to the norm of the non-zero element \code{(op, len)} + in $\mathbf{F}_{q}$. + +void fq_norm(fq_t rop, const fq_t op, const fq_ctx_t ctx) + + Computes the norm of \code{op}. + + For an element $a \in \mathbb{F}_q$, multiplication by $a$ defines + a $\mathbb{F}_p$-linear map on $\mathbb{F}_q$. We define the norm + of $a$ as the determinant of this map. Equivalently, if $\Sigma$ generates + $\Gal(\mathbb{F}_q / \mathbb{F}_p)$ then the trace of $a$ is equal to + $\prod_{i=0}^{d-1} \Sigma^i (a)$, where + $d = \text{dim}_{\mathbb{F}_p}(\mathbb{F}_q)$. + + Algorithm selection is automatic depending on the input. + +void _fq_frobenius(fmpz *rop, const fmpz *op, slong len, slong e, + const fq_ctx_t ctx) + + Sets \code{(rop, 2d-1)} to the image of \code{(op, len)} under the + Frobenius operator raised to the e-th power, assuming that neither + \code{op} nor \code{e} are zero. + +void fq_frobenius(fq_t rop, const fq_t op, slong e, const fq_ctx_t ctx) + + Evaluates the homomorphism $\Sigma^e$ at \code{op}. + + Recall that $\mathbb{F}_q / \mathbb{F}_p$ is Galois with Galois group + $\langle \sigma \rangle$, which is also isomorphic to + $\mathbf{Z}/d\mathbf{Z}$, where + $\sigma \in \Gal(\mathbf{F}_q/\mathbf{F}_p)$ is the Frobenius element + $\sigma \colon x \mapsto x^p$. + +******************************************************************************* + + Bit packing + +******************************************************************************* + +void fq_bit_pack(fmpz_t f, const fq_t op, mp_bitcnt_t bit_size, + const fq_ctx_t ctx) + + Packs \code{op} into bitfields of size \code{bit_size}, writing the + result to \code{f}. + +void fq_bit_unpack(fq_t rop, const fmpz_t f, mp_bitcnt_t bit_size, + const fq_ctx_t ctx) + + Unpacks into \code{rop} the element with coefficients packed into + fields of size \code{bit_size} as represented by the integer + \code{f}. diff --git a/external/flint-2.4.3/fq/frobenius.c b/external/flint-2.4.3/fq/frobenius.c new file mode 100644 index 0000000..a4f7405 --- /dev/null +++ b/external/flint-2.4.3/fq/frobenius.c @@ -0,0 +1,102 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "ulong_extras.h" +#include "fq.h" + +/* + Sets (rop, 2d-1) to the image of (op, len) under the Frobenius operator + raised to the e-th power, assuming that neither op nor e are zero. + */ + +void +_fq_frobenius(fmpz * rop, const fmpz * op, slong len, slong e, const fq_ctx_t ctx) +{ + const slong d = fq_ctx_degree(ctx); + + if (len == 1) /* op is in Fp, not just Fq */ + { + _fmpz_vec_set(rop, op, len); + _fmpz_vec_zero(rop + len, (2 * d - 1) - len); + } + else + { + fmpz_t t; + + fmpz_init(t); + fmpz_pow_ui(t, fq_ctx_prime(ctx), e); + _fq_pow(rop, op, len, t, ctx); + fmpz_clear(t); + } +} + +void +fq_frobenius(fq_t rop, const fq_t op, slong e, const fq_ctx_t ctx) +{ + const slong d = fq_ctx_degree(ctx); + + e = e % d; + if (e < 0) + e += d; + + if (fq_is_zero(op, ctx)) + { + fq_zero(rop, ctx); + } + else if (e == 0) + { + fq_set(rop, op, ctx); + } + else + { + fmpz *t; + + if (rop == op) + { + t = _fmpz_vec_init(2 * d - 1); + } + else + { + fmpz_poly_fit_length(rop, 2 * d - 1); + t = rop->coeffs; + } + + _fq_frobenius(t, op->coeffs, op->length, e, ctx); + + if (rop == op) + { + _fmpz_vec_clear(rop->coeffs, rop->alloc); + rop->coeffs = t; + rop->alloc = 2 * d - 1; + rop->length = d; + } + else + { + _fmpz_poly_set_length(rop, d); + } + _fmpz_poly_normalise(rop); + } +} diff --git a/external/flint-2.4.3/fq/get_str.c b/external/flint-2.4.3/fq/get_str.c new file mode 100644 index 0000000..5650980 --- /dev/null +++ b/external/flint-2.4.3/fq/get_str.c @@ -0,0 +1,32 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq.h" + +char * +fq_get_str(const fq_t op, const fq_ctx_t ctx) +{ + return fmpz_poly_get_str(op); +} diff --git a/external/flint-2.4.3/fq/get_str_pretty.c b/external/flint-2.4.3/fq/get_str_pretty.c new file mode 100644 index 0000000..d28aa4c --- /dev/null +++ b/external/flint-2.4.3/fq/get_str_pretty.c @@ -0,0 +1,32 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq.h" + +char * +fq_get_str_pretty(const fq_t op, const fq_ctx_t ctx) +{ + return fmpz_poly_get_str_pretty(op, ctx->var); +} diff --git a/external/flint-2.4.3/fq/inv.c b/external/flint-2.4.3/fq/inv.c new file mode 100644 index 0000000..7a5a17e --- /dev/null +++ b/external/flint-2.4.3/fq/inv.c @@ -0,0 +1,85 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq.h" + +void +_fq_inv(fmpz * rop, const fmpz * op, slong len, const fq_ctx_t ctx) +{ + const slong d = fq_ctx_degree(ctx); + + if (len == 1) + { + fmpz_invmod(rop, op, fq_ctx_prime(ctx)); + _fmpz_vec_zero(rop + 1, d - 1); + } + else + { + _fmpz_mod_poly_invmod(rop, op, len, ctx->modulus->coeffs, d + 1, + fq_ctx_prime(ctx)); + } +} + +void +fq_inv(fq_t rop, const fq_t op, const fq_ctx_t ctx) +{ + if (fq_is_zero(op, ctx)) + { + flint_printf("Exception (fq_inv). Zero is not invertible.\n"); + abort(); + } + else + { + const slong d = fq_ctx_degree(ctx); + fmpz *t; + + if (rop == op) + { + t = _fmpz_vec_init(d); + } + else + { + fmpz_poly_fit_length(rop, d); + t = rop->coeffs; + } + + _fq_inv(t, op->coeffs, op->length, ctx); + + if (rop == op) + { + _fmpz_vec_clear(rop->coeffs, rop->alloc); + rop->coeffs = t; + rop->alloc = d; + rop->length = d; + } + else + { + _fmpz_poly_set_length(rop, d); + } + _fmpz_poly_normalise(rop); + } +} diff --git a/external/flint-2.4.3/fq/mul.c b/external/flint-2.4.3/fq/mul.c new file mode 100644 index 0000000..dda50f3 --- /dev/null +++ b/external/flint-2.4.3/fq/mul.c @@ -0,0 +1,35 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + +******************************************************************************/ + +#include "fq.h" + +void +fq_mul(fq_t rop, const fq_t op1, const fq_t op2, const fq_ctx_t ctx) +{ + fmpz_poly_mul(rop, op1, op2); + + fq_reduce(rop, ctx); +} diff --git a/external/flint-2.4.3/fq/mul_fmpz.c b/external/flint-2.4.3/fq/mul_fmpz.c new file mode 100644 index 0000000..9d892af --- /dev/null +++ b/external/flint-2.4.3/fq/mul_fmpz.c @@ -0,0 +1,35 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq.h" + +void +fq_mul_fmpz(fq_t rop, const fq_t op, const fmpz_t x, const fq_ctx_t ctx) +{ + fmpz_poly_scalar_mul_fmpz(rop, op, x); + + fq_reduce(rop, ctx); +} diff --git a/external/flint-2.4.3/fq/mul_si.c b/external/flint-2.4.3/fq/mul_si.c new file mode 100644 index 0000000..680aa09 --- /dev/null +++ b/external/flint-2.4.3/fq/mul_si.c @@ -0,0 +1,35 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq.h" + +void +fq_mul_si(fq_t rop, const fq_t op, slong x, const fq_ctx_t ctx) +{ + fmpz_poly_scalar_mul_si(rop, op, x); + + fq_reduce(rop, ctx); +} diff --git a/external/flint-2.4.3/fq/mul_ui.c b/external/flint-2.4.3/fq/mul_ui.c new file mode 100644 index 0000000..0e8b1f1 --- /dev/null +++ b/external/flint-2.4.3/fq/mul_ui.c @@ -0,0 +1,35 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq.h" + +void +fq_mul_ui(fq_t rop, const fq_t op, ulong x, const fq_ctx_t ctx) +{ + fmpz_poly_scalar_mul_ui(rop, op, x); + + fq_reduce(rop, ctx); +} diff --git a/external/flint-2.4.3/fq/neg.c b/external/flint-2.4.3/fq/neg.c new file mode 100644 index 0000000..29af832 --- /dev/null +++ b/external/flint-2.4.3/fq/neg.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq.h" + +void +fq_neg(fq_t rop, const fq_t op, const fq_ctx_t ctx) +{ + slong len = op->length; + + fmpz_poly_fit_length(rop, len); + _fmpz_poly_set_length(rop, len); + + _fmpz_mod_poly_neg(rop->coeffs, op->coeffs, op->length, fq_ctx_prime(ctx)); +} diff --git a/external/flint-2.4.3/fq/norm.c b/external/flint-2.4.3/fq/norm.c new file mode 100644 index 0000000..3187594 --- /dev/null +++ b/external/flint-2.4.3/fq/norm.c @@ -0,0 +1,212 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq.h" + +/* + Computes the characteristic polynomial of the $n \times n$ matrix $M$ + modulo \code{pN} using a division-free algorithm in $O(n^4)$ ring + operations. + + Only returns the determinant. + + Assumes that $n$ is at least $2$. + */ + +static void +_fmpz_mod_mat_det(fmpz_t rop, const fmpz * M, slong n, const fmpz_t pN) +{ + if (n == 1) + { + fmpz_set(rop, M); + } + else + { + fmpz *F; + fmpz *a; + fmpz *A; + fmpz_t s; + slong t, i, j, p, k; + + F = _fmpz_vec_init(n); + a = _fmpz_vec_init((n - 1) * n); + A = _fmpz_vec_init(n); + + fmpz_init(s); + + fmpz_neg(F + 0, M + 0 * n + 0); + + for (t = 1; t < n; t++) + { + for (i = 0; i <= t; i++) + fmpz_set(a + 0 * n + i, M + i * n + t); + + fmpz_set(A + 0, M + t * n + t); + + for (p = 1; p < t; p++) + { + for (i = 0; i <= t; i++) + { + fmpz_zero(s); + for (j = 0; j <= t; j++) + fmpz_addmul(s, M + i * n + j, a + (p - 1) * n + j); + fmpz_mod(a + p * n + i, s, pN); + } + + fmpz_set(A + p, a + p * n + t); + } + + fmpz_zero(s); + for (j = 0; j <= t; j++) + fmpz_addmul(s, M + t * n + j, a + (t - 1) * n + j); + fmpz_mod(A + t, s, pN); + + for (p = 0; p <= t; p++) + { + fmpz_sub(F + p, F + p, A + p); + for (k = 0; k < p; k++) + fmpz_submul(F + p, A + k, F + (p - k - 1)); + fmpz_mod(F + p, F + p, pN); + } + } + + /* + Now [F{n-1}, F{n-2}, ..., F{0}, 1] is the + characteristic polynomial of the matrix M. + */ + + if (n % WORD(2) == 0) + { + fmpz_set(rop, F + (n - 1)); + } + else + { + fmpz_neg(rop, F + (n - 1)); + fmpz_mod(rop, rop, pN); + } + + _fmpz_vec_clear(F, n); + _fmpz_vec_clear(a, (n - 1) * n); + _fmpz_vec_clear(A, n); + fmpz_clear(s); + } +} + +/* + Computes the norm on $\mathbf{Q}_q$ to precision $N \geq 1$. + When $N = 1$, this computes the norm on $\mathbf{F}_q$. + */ + +void +_fq_norm(fmpz_t rop, const fmpz * op, slong len, const fq_ctx_t ctx) +{ + const slong d = fq_ctx_degree(ctx); + const slong N = 1; + + fmpz *pN; + const fmpz *p = fq_ctx_prime(ctx); + + if (N == 1) + { + pN = (fmpz *) p; /* XXX: Read-only */ + } + else + { + pN = flint_malloc(sizeof(fmpz)); + fmpz_init(pN); + fmpz_pow_ui(pN, p, N); + } + + if (len == 1) + { + fmpz_powm_ui(rop, op + 0, d, pN); + } + else + { + /* Construct an ad hoc matrix M and set rop to det(M) */ + { + const slong n = d + len - 1; + slong i, k; + fmpz *M; + + M = flint_calloc(n * n, sizeof(fmpz)); + + for (k = 0; k < len - 1; k++) + { + for (i = 0; i < ctx->len; i++) + { + M[k * n + k + (d - ctx->j[i])] = ctx->a[i]; + } + } + for (k = 0; k < d; k++) + { + for (i = 0; i < len; i++) + { + M[(len - 1 + k) * n + k + (len - 1 - i)] = op[i]; + } + } + + _fmpz_mod_mat_det(rop, M, n, pN); + + flint_free(M); + } + + /* + XXX: This part of the code is currently untested as the Conway + polynomials used for the extension Fq/Fp are monic. + */ + if (!fmpz_is_one(ctx->a + (ctx->len - 1))) + { + fmpz_t f; + + fmpz_init(f); + fmpz_powm_ui(f, ctx->a + (ctx->len - 1), len - 1, pN); + fmpz_invmod(f, f, pN); + fmpz_mul(rop, f, rop); + fmpz_mod(rop, rop, pN); + fmpz_clear(f); + } + } + + if (N > 1) + { + fmpz_clear(pN); + flint_free(pN); + } +} + +void +fq_norm(fmpz_t rop, const fq_t op, const fq_ctx_t ctx) +{ + if (fq_is_zero(op, ctx)) + { + fmpz_zero(rop); + } + else + { + _fq_norm(rop, op->coeffs, op->length, ctx); + } +} diff --git a/external/flint-2.4.3/fq/pow.c b/external/flint-2.4.3/fq/pow.c new file mode 100644 index 0000000..09d610e --- /dev/null +++ b/external/flint-2.4.3/fq/pow.c @@ -0,0 +1,175 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq.h" + +void +_fq_pow(fmpz * rop, const fmpz * op, slong len, const fmpz_t e, + const fq_ctx_t ctx) +{ + const slong d = fq_ctx_degree(ctx); + + if (fmpz_is_zero(e)) + { + fmpz_one(rop); + _fmpz_vec_zero(rop + 1, 2 * d - 1 - 1); + } + else if (fmpz_is_one(e)) + { + _fmpz_vec_set(rop, op, len); + _fmpz_vec_zero(rop + len, 2 * d - 1 - len); + } + else + { + ulong bit; + fmpz *v = _fmpz_vec_init(2 * d - 1); + fmpz *R, *S, *T; + + _fmpz_vec_zero(rop, 2 * d - 1); + + /* + Set bits to the bitmask with a 1 one place lower than the msb of e + */ + + bit = fmpz_bits(e) - 2; + + /* + Trial run without any polynomial arithmetic to determine the parity + of the number of swaps; then set R and S accordingly + */ + + { + unsigned int swaps = 0U; + ulong bit2 = bit; + if (fmpz_tstbit(e, bit2)) + swaps = ~swaps; + while (bit2--) + if (!fmpz_tstbit(e, bit2)) + swaps = ~swaps; + + if (swaps == 0U) + { + R = rop; + S = v; + } + else + { + R = v; + S = rop; + } + } + + /* + We unroll the first step of the loop, referring to {op, len} + */ + + _fmpz_poly_sqr(R, op, len); + _fq_reduce(R, 2 * len - 1, ctx); + + if (fmpz_tstbit(e, bit)) + { + _fmpz_poly_mul(S, R, d, op, len); + _fq_reduce(S, d + len - 1, ctx); + T = R; + R = S; + S = T; + } + + while (bit--) + { + if (fmpz_tstbit(e, bit)) + { + _fmpz_poly_sqr(S, R, d); + _fq_reduce(S, 2 * d - 1, ctx); + _fmpz_poly_mul(R, S, d, op, len); + _fq_reduce(R, d + len - 1, ctx); + } + else + { + _fmpz_poly_sqr(S, R, d); + _fq_reduce(S, 2 * d - 1, ctx); + T = R; + R = S; + S = T; + } + } + + _fmpz_vec_clear(v, 2 * d - 1); + } +} + +void +fq_pow(fq_t rop, const fq_t op, const fmpz_t e, const fq_ctx_t ctx) +{ + if (fmpz_sgn(e) < 0) + { + flint_printf("Exception (fq_pow). e < 0.\n"); + abort(); + } + + if (fmpz_is_zero(e)) + { + fq_one(rop, ctx); + } + else if (fq_is_zero(op, ctx)) + { + fq_zero(rop, ctx); + } + else if (fmpz_is_one(e)) + { + fq_set(rop, op, ctx); + } + else + { + const slong d = fq_ctx_degree(ctx); + fmpz *t; + + if (rop == op) + { + t = _fmpz_vec_init(2 * d - 1); + } + else + { + fmpz_poly_fit_length(rop, 2 * d - 1); + t = rop->coeffs; + } + + _fq_pow(t, op->coeffs, op->length, e, ctx); + + if (rop == op) + { + _fmpz_vec_clear(rop->coeffs, rop->alloc); + rop->coeffs = t; + rop->alloc = 2 * d - 1; + rop->length = d; + } + else + { + _fmpz_poly_set_length(rop, d); + } + _fmpz_poly_normalise(rop); + } +} diff --git a/external/flint-2.4.3/fq/pow_ui.c b/external/flint-2.4.3/fq/pow_ui.c new file mode 100644 index 0000000..ead13ff --- /dev/null +++ b/external/flint-2.4.3/fq/pow_ui.c @@ -0,0 +1,37 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ + +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq.h" + +/* TODO: optimize */ +void +fq_pow_ui(fq_t rop, const fq_t op, const ulong e, const fq_ctx_t ctx) +{ + fmpz_t exp; + fmpz_init_set_ui(exp, e); + fq_pow(rop, op, exp, ctx); + fmpz_clear(exp); +} diff --git a/external/flint-2.4.3/fq/profile/p-inv.c b/external/flint-2.4.3/fq/profile/p-inv.c new file mode 100644 index 0000000..5398a62 --- /dev/null +++ b/external/flint-2.4.3/fq/profile/p-inv.c @@ -0,0 +1,83 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ +#include "flint.h" +#include "fq.h" +#include +#include "profiler.h" + +#ifndef REPS +#define REPS 1000000 +#endif + +int +main() +{ + timeit_t t0; + + slong i, d, cpu, wall; + fmpz_t p; + fq_ctx_t ctx; + fq_t a,b; + + FLINT_TEST_INIT(state); + + fmpz_init(p); + fmpz_set_ui(p, n_randprime(state, 2+ n_randint(state,3),1)); + d = n_randint(state,10)+1; + fq_ctx_init_conway(ctx,p,d,"a"); + + fq_init(a, ctx); + fq_init(b, ctx); + + fq_randtest_not_zero(a,state,ctx); + + flint_printf("INV benchmark:single repeated inversion: \n"); + timeit_start(t0); + for(i=0;icpu , t0->wall ); + + flint_printf("random inversions: \n"); + + wall = 0; + cpu = 0; + for(i=0;icpu; + wall = wall + t0->wall; + } + + flint_printf ( " cpu = %wd ms, wall = %wd ms \n " , cpu , wall ); + + FLINT_TEST_CLEANUP(state); + + return 0; + +} diff --git a/external/flint-2.4.3/fq/profile/p-mul.c b/external/flint-2.4.3/fq/profile/p-mul.c new file mode 100644 index 0000000..775c231 --- /dev/null +++ b/external/flint-2.4.3/fq/profile/p-mul.c @@ -0,0 +1,66 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ +#include "flint.h" +#include "fq.h" +#include +#include "profiler.h" + +#ifndef REPS +#define REPS 1000000 +#endif + +int +main() +{ + timeit_t t0; + + slong i; + fmpz_t p; + slong d,cpu,wall; + fq_ctx_t ctx; + fq_t a,b,c; + + FLINT_TEST_INIT(state); + + fmpz_init(p); + fmpz_set_ui(p, n_randprime(state, 2+ n_randint(state,3),1)); + d = n_randint(state,10)+1; + fq_ctx_init_conway(ctx,p,d,"a"); + + fq_init(a, ctx); + fq_init(b, ctx); + fq_init(c, ctx); + + fq_randtest_not_zero(a,state,ctx); + fq_randtest_not_zero(b,state,ctx); + + flint_printf ( " cpu = %wd ms, wall = %wd ms \n " , cpu , wall ); + + FLINT_TEST_CLEANUP(state); + + return 0; + +} diff --git a/external/flint-2.4.3/fq/profile/p-reduce.c b/external/flint-2.4.3/fq/profile/p-reduce.c new file mode 100644 index 0000000..a553c6f --- /dev/null +++ b/external/flint-2.4.3/fq/profile/p-reduce.c @@ -0,0 +1,100 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ +#include "flint.h" +#include "fq.h" +#include +#include "profiler.h" + +int +main(int argc, char** argv) +{ + slong i, result; + fmpz_t p; + slong d; + fq_ctx_t ctx; + fq_t a,b,c; + double dense; + + FLINT_TEST_INIT(state); + + fmpz_init(p); + fmpz_set_str(p, argv[1], 10); + + d = atoi(argv[2]); + + fq_ctx_init(ctx,p,d,"a"); + + fq_init(a, ctx); + fq_init(b, ctx); + fq_init(c, ctx); + + fq_randtest_not_zero(a,state,ctx); + fq_randtest_not_zero(b,state,ctx); + + fmpz_poly_mul(c, a, b); + + init_clock(0); + + prof_start(); + for (i=0; i < 1000; i++) + { + fmpz_poly_set(a, c); + _fq_dense_reduce(a->coeffs, a->length, ctx); + } + prof_stop(); + + dense = get_clock(0); + + init_clock(0); + prof_start(); + for (i = 0; i < 1000; i++) + { + fmpz_poly_set(b, c); + _fq_sparse_reduce(b->coeffs, b->length, ctx); + } + prof_stop(); + + if (get_clock(0) <= dense) + { + result = 1; + } + else + { + result = 0; + } + + + fmpz_print(p); + flint_printf(" %d %d %d\n", ctx->len, ctx->modulus->length, result); + + fq_clear(a, ctx); + fq_clear(b, ctx); + fq_clear(c, ctx); + fq_ctx_clear(ctx); + fmpz_clear(p); + FLINT_TEST_CLEANUP(state); + + return 0; +} diff --git a/external/flint-2.4.3/fq/pth_root.c b/external/flint-2.4.3/fq/pth_root.c new file mode 100644 index 0000000..134460c --- /dev/null +++ b/external/flint-2.4.3/fq/pth_root.c @@ -0,0 +1,44 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq.h" + +void +fq_pth_root(fq_t rop, const fq_t op1, const fq_ctx_t ctx) +{ + slong i, d; + if (fq_is_zero(op1, ctx) || fq_is_one(op1, ctx)) + { + fq_set(rop, op1, ctx); + return; + } + + d = fq_ctx_degree(ctx) - 1; + fq_set(rop, op1, ctx); + for (i = 0; i < d; i++) + { + fq_pow(rop, rop, fq_ctx_prime(ctx), ctx); + } +} diff --git a/external/flint-2.4.3/fq/randtest.c b/external/flint-2.4.3/fq/randtest.c new file mode 100644 index 0000000..9137d03 --- /dev/null +++ b/external/flint-2.4.3/fq/randtest.c @@ -0,0 +1,88 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq.h" + +void +fq_randtest(fq_t rop, flint_rand_t state, const fq_ctx_t ctx) +{ + const slong d = fq_ctx_degree(ctx); + slong i, sparse; + + fmpz_poly_fit_length(rop, d); + + if (n_randint(state, 2)) + { + for (i = 0; i < d; i++) + fmpz_randm(rop->coeffs + i, state, fq_ctx_prime(ctx)); + } + else + { + sparse = 1 + n_randint(state, FLINT_MAX(2, d)); + + for (i = 0; i < d; i++) + if (n_randint(state, sparse)) + fmpz_zero(rop->coeffs + i); + else + fmpz_randm(rop->coeffs + i, state, fq_ctx_prime(ctx)); + } + + _fmpz_poly_set_length(rop, d); + _fmpz_poly_normalise(rop); +} + +void +fq_randtest_dense(fq_t rop, flint_rand_t state, const fq_ctx_t ctx) +{ + const slong d = fq_ctx_degree(ctx); + slong i; + + fmpz_poly_fit_length(rop, d); + + for (i = 0; i < d - 1; i++) + { + fmpz_randm(rop->coeffs + i, state, fq_ctx_prime(ctx)); + } + + fmpz_one(rop->coeffs + d - 1); + + _fmpz_poly_set_length(rop, d); + _fmpz_poly_normalise(rop); +} + +void +fq_randtest_not_zero(fq_t rop, flint_rand_t state, const fq_ctx_t ctx) +{ + slong i; + + fq_randtest(rop, state, ctx); + for (i = 0; fq_is_zero(rop, ctx) && (i < 10); i++) + fq_randtest(rop, state, ctx); + + if (fq_is_zero(rop, ctx)) + fq_one(rop, ctx); +} diff --git a/external/flint-2.4.3/fq/sqr.c b/external/flint-2.4.3/fq/sqr.c new file mode 100644 index 0000000..1605a49 --- /dev/null +++ b/external/flint-2.4.3/fq/sqr.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq.h" + +void +fq_sqr(fq_t rop, const fq_t op, const fq_ctx_t ctx) +{ + fmpz_poly_sqr(rop, op); + + fq_reduce(rop, ctx); +} diff --git a/external/flint-2.4.3/fq/sub.c b/external/flint-2.4.3/fq/sub.c new file mode 100644 index 0000000..81e813d --- /dev/null +++ b/external/flint-2.4.3/fq/sub.c @@ -0,0 +1,43 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq.h" + +void +fq_sub(fq_t rop, const fq_t op1, const fq_t op2, const fq_ctx_t ctx) +{ + slong max = FLINT_MAX(op1->length, op2->length); + + fmpz_poly_fit_length(rop, max); + + _fmpz_mod_poly_sub(rop->coeffs, + op1->coeffs, op1->length, op2->coeffs, op2->length, + fq_ctx_prime(ctx)); + + _fmpz_poly_set_length(rop, max); + _fmpz_poly_normalise(rop); +} diff --git a/external/flint-2.4.3/fq/sub_one.c b/external/flint-2.4.3/fq/sub_one.c new file mode 100644 index 0000000..e8babae --- /dev/null +++ b/external/flint-2.4.3/fq/sub_one.c @@ -0,0 +1,37 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq.h" + +void +fq_sub_one(fq_t rop, const fq_t op1, const fq_ctx_t ctx) +{ + fq_t one; + + fq_init(one, ctx); + fq_one(one, ctx); + fq_sub(rop, op1, one, ctx); + fq_clear(one, ctx); +} diff --git a/external/flint-2.4.3/fq/test/t-add.c b/external/flint-2.4.3/fq/test/t-add.c new file mode 100644 index 0000000..a725894 --- /dev/null +++ b/external/flint-2.4.3/fq/test/t-add.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq.h" + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_templates/test/t-add.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq/test/t-ctx_init.c b/external/flint-2.4.3/fq/test/t-ctx_init.c new file mode 100644 index 0000000..2c8125e --- /dev/null +++ b/external/flint-2.4.3/fq/test/t-ctx_init.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq.h" + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_templates/test/t-ctx_init.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq/test/t-frobenius.c b/external/flint-2.4.3/fq/test/t-frobenius.c new file mode 100644 index 0000000..96d4b14 --- /dev/null +++ b/external/flint-2.4.3/fq/test/t-frobenius.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq.h" + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_templates/test/t-frobenius.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq/test/t-inv.c b/external/flint-2.4.3/fq/test/t-inv.c new file mode 100644 index 0000000..09c4595 --- /dev/null +++ b/external/flint-2.4.3/fq/test/t-inv.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq.h" + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_templates/test/t-inv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq/test/t-mul.c b/external/flint-2.4.3/fq/test/t-mul.c new file mode 100644 index 0000000..25e88bd --- /dev/null +++ b/external/flint-2.4.3/fq/test/t-mul.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq.h" + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_templates/test/t-mul.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq/test/t-mul_fmpz.c b/external/flint-2.4.3/fq/test/t-mul_fmpz.c new file mode 100644 index 0000000..77a99f8 --- /dev/null +++ b/external/flint-2.4.3/fq/test/t-mul_fmpz.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq.h" + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_templates/test/t-mul_fmpz.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq/test/t-mul_si.c b/external/flint-2.4.3/fq/test/t-mul_si.c new file mode 100644 index 0000000..bd2fbc3 --- /dev/null +++ b/external/flint-2.4.3/fq/test/t-mul_si.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq.h" + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_templates/test/t-mul_si.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq/test/t-mul_ui.c b/external/flint-2.4.3/fq/test/t-mul_ui.c new file mode 100644 index 0000000..35737d5 --- /dev/null +++ b/external/flint-2.4.3/fq/test/t-mul_ui.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq.h" + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_templates/test/t-mul_ui.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq/test/t-neg.c b/external/flint-2.4.3/fq/test/t-neg.c new file mode 100644 index 0000000..777ec69 --- /dev/null +++ b/external/flint-2.4.3/fq/test/t-neg.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq.h" + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_templates/test/t-neg.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq/test/t-norm.c b/external/flint-2.4.3/fq/test/t-norm.c new file mode 100644 index 0000000..5526950 --- /dev/null +++ b/external/flint-2.4.3/fq/test/t-norm.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq.h" + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_templates/test/t-norm.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq/test/t-pow.c b/external/flint-2.4.3/fq/test/t-pow.c new file mode 100644 index 0000000..4f38c3e --- /dev/null +++ b/external/flint-2.4.3/fq/test/t-pow.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq.h" + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_templates/test/t-pow.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq/test/t-pth_root.c b/external/flint-2.4.3/fq/test/t-pth_root.c new file mode 100644 index 0000000..d73e795 --- /dev/null +++ b/external/flint-2.4.3/fq/test/t-pth_root.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq.h" + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_templates/test/t-pth_root.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq/test/t-sqr.c b/external/flint-2.4.3/fq/test/t-sqr.c new file mode 100644 index 0000000..39151ed --- /dev/null +++ b/external/flint-2.4.3/fq/test/t-sqr.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq.h" + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_templates/test/t-sqr.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq/test/t-sub.c b/external/flint-2.4.3/fq/test/t-sub.c new file mode 100644 index 0000000..120f302 --- /dev/null +++ b/external/flint-2.4.3/fq/test/t-sub.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq.h" + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_templates/test/t-sub.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq/test/t-trace.c b/external/flint-2.4.3/fq/test/t-trace.c new file mode 100644 index 0000000..0aa9c19 --- /dev/null +++ b/external/flint-2.4.3/fq/test/t-trace.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq.h" + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_templates/test/t-trace.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq/trace.c b/external/flint-2.4.3/fq/trace.c new file mode 100644 index 0000000..a8d2136 --- /dev/null +++ b/external/flint-2.4.3/fq/trace.c @@ -0,0 +1,77 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq.h" + +void +_fq_trace(fmpz_t rop, const fmpz * op, slong len, const fq_ctx_t ctx) +{ + const slong d = fq_ctx_degree(ctx); + + slong i, l; + fmpz *t; + + t = _fmpz_vec_init(d); + + fmpz_set_ui(t + 0, d); + for (i = 1; i < d; i++) + { + for (l = ctx->len - 2; l >= 0 && ctx->j[l] >= d - (i - 1); l--) + { + fmpz_addmul(t + i, t + (ctx->j[l] + i - d), ctx->a + l); + } + + if (l >= 0 && ctx->j[l] == d - i) + { + fmpz_addmul_ui(t + i, ctx->a + l, i); + } + + fmpz_neg(t + i, t + i); + fmpz_mod(t + i, t + i, fq_ctx_prime(ctx)); + } + + fmpz_zero(rop); + for (i = 0; i < d; i++) + { + fmpz_addmul(rop, op + i, t + i); + } + fmpz_mod(rop, rop, fq_ctx_prime(ctx)); + + _fmpz_vec_clear(t, d); +} + +void +fq_trace(fmpz_t rop, const fq_t op, const fq_ctx_t ctx) +{ + if (fq_is_zero(op, ctx)) + { + fmpz_zero(rop); + } + else + { + _fq_trace(rop, op->coeffs, op->length, ctx); + } +} diff --git a/external/flint-2.4.3/fq_mat.h b/external/flint-2.4.3/fq_mat.h new file mode 100644 index 0000000..ef10300 --- /dev/null +++ b/external/flint-2.4.3/fq_mat.h @@ -0,0 +1,53 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#ifndef FQ_MAT_H +#define FQ_MAT_H + +#include "fq.h" +#include "fq_vec.h" + +/* Cutoff between classical and recursive triangular solving */ +#define FQ_MAT_SOLVE_TRI_ROWS_CUTOFF 64 +#define FQ_MAT_SOLVE_TRI_COLS_CUTOFF 64 + +/* Cutoff between classical and recursive LU decomposition */ +#define FQ_MAT_LU_RECURSIVE_CUTOFF 4 + +static __inline__ int FQ_MAT_MUL_KS_CUTOFF(slong r, slong c, const fq_ctx_t ctx) +{ + if (5 * FLINT_MIN(r, c) > 8 * fq_ctx_degree(ctx) + 29) + return 1; + else + return 0; +} + +#define T fq +#define CAP_T FQ +#include "fq_mat_templates.h" +#undef CAP_T +#undef T + +#endif diff --git a/external/flint-2.4.3/fq_mat/add.c b/external/flint-2.4.3/fq_mat/add.c new file mode 100644 index 0000000..0b102da --- /dev/null +++ b/external/flint-2.4.3/fq_mat/add.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_mat_templates/add.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_mat/clear.c b/external/flint-2.4.3/fq_mat/clear.c new file mode 100644 index 0000000..2b382cf --- /dev/null +++ b/external/flint-2.4.3/fq_mat/clear.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_mat_templates/clear.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_mat/doc/fq_mat.txt b/external/flint-2.4.3/fq_mat/doc/fq_mat.txt new file mode 100644 index 0000000..f9835c1 --- /dev/null +++ b/external/flint-2.4.3/fq_mat/doc/fq_mat.txt @@ -0,0 +1,428 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +******************************************************************************* + + Memory management + +******************************************************************************* + +void fq_mat_init(fq_mat_t mat, slong rows, slong cols, const fq_ctx_t ctx) + + Initialises \code{mat} to a \code{rows}-by-\code{cols} matrix with + coefficients in $\mathbb{F}_{q}$ given by \code{ctx}. All elements + are set to zero. + +void fq_mat_init_set(fq_mat_t mat, fq_mat_t src, const fq_ctx_t ctx) + + Initialises \code{mat} and sets its dimensions and elements to + those of \code{src}. + +void fq_mat_clear(fq_mat_t mat, const fq_ctx_t ctx) + + Clears the matrix and releases any memory it used. The matrix + cannot be used again until it is initialised. This function must be + called exactly once when finished using an \code{fq_mat_t} object. + +void fq_mat_set(fq_mat_t mat, fq_mat_t src, const fq_ctx_t ctx) + + Sets \code{mat} to a copy of \code{src}. It is assumed + that \code{mat} and \code{src} have identical dimensions. + +******************************************************************************* + + Basic properties and manipulation + +******************************************************************************* + +fq_struct * fq_mat_entry(fq_mat_t mat, slong i, slong j) + + Directly accesses the entry in \code{mat} in row $i$ and column $j$, + indexed from zero. No bounds checking is performed. + +fq_struct * fq_mat_entry_set(fq_mat_t mat, slong i, slong j, fq_t x, + const fq_ctx_t ctx) + + Sets the entry in \code{mat} in row $i$ and column $j$ to \code{x}. + +slong fq_mat_nrows(fq_mat_t mat, const fq_ctx_t ctx) + + Returns the number of rows in \code{mat}. + +slong fq_mat_ncols(fq_mat_t mat, const fq_ctx_t ctx) + + Returns the number of columns in \code{mat}. + +void fq_mat_swap(fq_mat_t mat1, fq_mat_t mat2, const fq_ctx_t ctx) + + Swaps two matrices. The dimensions of \code{mat1} and \code{mat2} + are allowed to be different. + +void fq_mat_zero(fq_mat_t mat, const fq_ctx_t ctx) + + Sets all entries of \code{mat} to 0. + + +******************************************************************************* + + Printing + +******************************************************************************* + +void fq_mat_print_pretty(const fq_mat_t mat, const fq_ctx_t ctx) + + Pretty-prints \code{mat} to \code{stdout}. A header is printed + followed by the rows enclosed in brackets. + +int fq_mat_fprint_pretty(FILE * file, const fq_mat_t mat, const fq_ctx_t ctx) + + Pretty-prints \code{mat} to \code{file}. A header is printed + followed by the rows enclosed in brackets. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + +void fq_mat_print(const fq_mat_t mat, const fq_ctx_t ctx) + + Prints \code{mat} to \code{stdout}. A header is printed followed + by the rows enclosed in brackets. + +int fq_mat_fprint(FILE * file, const fq_mat_t mat, const fq_ctx_t ctx) + + Prints \code{mat} to \code{file}. A header is printed followed by + the rows enclosed in brackets. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + +******************************************************************************* + + Window + +******************************************************************************* + +void fq_mat_window_init(fq_mat_t window, const fq_mat_t mat, slong r1, + slong c1, slong r2, slong c2, const fq_ctx_t ctx) + + Initializes the matrix \code{window} to be an \code{r2 - r1} by + \code{c2 - c1} submatrix of \code{mat} whose \code{(0,0)} entry + is the \code{(r1, c1)} entry of \code{mat}. The memory for the + elements of \code{window} is shared with \code{mat}. + + +void fq_mat_window_clear(fq_mat_t window, const fq_ctx_t ctx) + + Clears the matrix \code{window} and releases any memory that it + uses. Note that the memory to the underlying matrix that + \code{window} points to is not freed. + + +******************************************************************************* + + Random matrix generation + +******************************************************************************* + +void fq_mat_randtest(fq_mat_t mat, flint_rand_t state, const fq_ctx_t ctx) + + Sets the elements of \code{mat} to random elements of + $\mathbb{F}_{q}$, given by \code{ctx}. + +int fq_mat_randpermdiag(fq_mat_t mat, fq_struct * diag, slong n, + flint_rand_t state, const fq_ctx_t ctx) + + Sets \code{mat} to a random permutation of the diagonal matrix + with $n$ leading entries given by the vector \code{diag}. It is + assumed that the main diagonal of \code{mat} has room for at + least $n$ entries. + + Returns $0$ or $1$, depending on whether the permutation is even + or odd respectively. + +void fq_mat_randrank(fq_mat_t mat, slong rank, flint_rand_t state, + const fq_ctx_t ctx) + + Sets \code{mat} to a random sparse matrix with the given rank, + having exactly as many non-zero elements as the rank, with the + non-zero elements being uniformly random elements of + $\mathbb{F}_{q}$. + + The matrix can be transformed into a dense matrix with unchanged + rank by subsequently calling \code{fq_mat_randops()}. + +void fq_mat_randops(fq_mat_t mat, slong count, flint_rand_t state, + const fq_ctx_t ctx) + + Randomises \code{mat} by performing elementary row or column + operations. More precisely, at most \code{count} random additions + or subtractions of distinct rows and columns will be performed. + This leaves the rank (and for square matrices, determinant) + unchanged. + +void fq_mat_randtril(fq_mat_t mat, flint_rand_t state, int unit, + const fq_ctx_t ctx) + + Sets \code{mat} to a random lower triangular matrix. If + \code{unit} is 1, it will have ones on the main diagonal, + otherwise it will have random nonzero entries on the main + diagonal. + +void fq_mat_randtriu(fq_mat_t mat, flint_rand_t state, int unit, + const fq_ctx_t ctx) + + Sets \code{mat} to a random upper triangular matrix. If + \code{unit} is 1, it will have ones on the main diagonal, + otherwise it will have random nonzero entries on the main + diagonal. + +******************************************************************************* + + Comparison + +******************************************************************************* + +int fq_mat_equal(fq_mat_t mat1, fq_mat_t mat2, const fq_ctx_t ctx) + + Returns nonzero if mat1 and mat2 have the same dimensions and elements, + and zero otherwise. + +int fq_mat_is_zero(const fq_mat_t mat, const fq_ctx_t ctx) + + Returns a non-zero value if all entries \code{mat} are zero, and + otherwise returns zero. + +int fq_mat_is_empty(const fq_mat_t mat, const fq_ctx_t ctx) + + Returns a non-zero value if the number of rows or the number of + columns in \code{mat} is zero, and otherwise returns zero. + +int fq_mat_is_square(const fq_mat_t mat, const fq_ctx_t ctx) + + Returns a non-zero value if the number of rows is equal to the + number of columns in \code{mat}, and otherwise returns zero. + + + +******************************************************************************* + + Addition and subtraction + +******************************************************************************* + +void fq_mat_add(fq_mat_t C, const fq_mat_t A, const fq_mat_t B, + const fq_ctx_t ctx) + + Computes $C = A + B$. Dimensions must be identical. + +void fq_mat_sub(fq_mat_t C, const fq_mat_t A, const fq_mat_t B, + const fq_ctx_t ctx) + + Computes $C = A - B$. Dimensions must be identical. + +void fq_mat_neg(fq_mat_t A, const fq_mat_t B, const fq_ctx_t ctx) + + Sets $B = -A$. Dimensions must be identical. + +******************************************************************************* + + Matrix multiplication + +******************************************************************************* + +void fq_mat_mul(fq_mat_t C, const fq_mat_t A, const fq_mat_t B, + const fq_ctx_t ctx) + + Sets $C = AB$. Dimensions must be compatible for matrix + multiplication. $C$ is not allowed to be aliased with $A$ or + $B$. This function automatically chooses between classical and + KS multiplication. + +void fq_mat_mul_classical(fq_mat_t C, const fq_mat_t A, const fq_mat_t B, + const fq_ctx_t ctx) + + Sets $C = AB$. Dimensions must be compatible for matrix multiplication. + $C$ is not allowed to be aliased with $A$ or $B$. Uses classical + matrix multiplication. + +void fq_mat_mul_KS(fq_mat_t C, const fq_mat_t A, const fq_mat_t B, + const fq_ctx_t ctx) + + Sets $C = AB$. Dimensions must be compatible for matrix + multiplication. $C$ is not allowed to be aliased with $A$ or + $B$. Uses Kronecker substitution to perform the multiplication + over the integers. + +void fq_mat_submul(fq_mat_t D, const fq_mat_t C, const fq_mat_t A, + const fq_mat_t B, const fq_ctx_t ctx) + + Sets $D = C + AB$. $C$ and $D$ may be aliased with each other but + not with $A$ or $B$. + +******************************************************************************* + + LU decomposition + +******************************************************************************* + +slong fq_mat_lu(slong * P, fq_mat_t A, int rank_check, const fq_ctx_t ctx) + + Computes a generalised LU decomposition $LU = PA$ of a given + matrix $A$, returning the rank of $A$. + + If $A$ is a nonsingular square matrix, it will be overwritten with + a unit diagonal lower triangular matrix $L$ and an upper + triangular matrix $U$ (the diagonal of $L$ will not be stored + explicitly). + + If $A$ is an arbitrary matrix of rank $r$, $U$ will be in row + echelon form having $r$ nonzero rows, and $L$ will be lower + triangular but truncated to $r$ columns, having implicit ones on + the $r$ first entries of the main diagonal. All other entries will + be zero. + + If a nonzero value for \code{rank_check} is passed, the function + will abandon the output matrix in an undefined state and return 0 + if $A$ is detected to be rank-deficient. + + This function calls \code{fq_mat_lu_recursive}. + +slong fq_mat_lu_classical(slong * P, fq_mat_t A, int rank_check, + const fq_ctx_t ctx) + + Computes a generalised LU decomposition $LU = PA$ of a given + matrix $A$, returning the rank of $A$. The behavior of this + function is identical to that of \code{fq_mat_lu}. Uses Gaussian + elimination. + +slong fq_mat_lu_recursive(slong * P, fq_mat_t A, int rank_check, + const fq_ctx_t ctx) + + Computes a generalised LU decomposition $LU = PA$ of a given + matrix $A$, returning the rank of $A$. The behavior of this + function is identical to that of \code{fq_mat_lu}. Uses recursive + block decomposition, switching to classical Gaussian elimination + for sufficiently small blocks. + +******************************************************************************* + + Reduced row echelon form + +******************************************************************************* + +slong fq_mat_rref(fq_mat_t A, const fq_ctx_t ctx) + + Puts $A$ in reduced row echelon form and returns the rank of $A$. + + The rref is computed by first obtaining an unreduced row echelon + form via LU decomposition and then solving an additional + triangular system. + +******************************************************************************* + + Triangular solving + +******************************************************************************* + +void fq_mat_solve_tril(fq_mat_t X, const fq_mat_t L, const fq_mat_t B, + int unit, const fq_ctx_t ctx) + + Sets $X = L^{-1} B$ where $L$ is a full rank lower triangular + square matrix. If \code{unit} = 1, $L$ is assumed to have ones on + its main diagonal, and the main diagonal will not be read. $X$ + and $B$ are allowed to be the same matrix, but no other aliasing + is allowed. Automatically chooses between the classical and + recursive algorithms. + +void fq_mat_solve_tril_classical(fq_mat_t X, const fq_mat_t L, + const fq_mat_t B, int unit, + const fq_ctx_t ctx) + + Sets $X = L^{-1} B$ where $L$ is a full rank lower triangular + square matrix. If \code{unit} = 1, $L$ is assumed to have ones on + its main diagonal, and the main diagonal will not be read. $X$ + and $B$ are allowed to be the same matrix, but no other aliasing + is allowed. Uses forward substitution. + +void fq_mat_solve_tril_recursive(fq_mat_t X, const fq_mat_t L, + const fq_mat_t B, int unit, + const fq_ctx_t ctx) + + Sets $X = L^{-1} B$ where $L$ is a full rank lower triangular + square matrix. If \code{unit} = 1, $L$ is assumed to have ones on + its main diagonal, and the main diagonal will not be read. $X$ + and $B$ are allowed to be the same matrix, but no other aliasing + is allowed. + + Uses the block inversion formula + + $$ + \begin{pmatrix} A & 0 \\ C & D \end{pmatrix}^{-1} + \begin{pmatrix} X \\ Y \end{pmatrix} = + \begin{pmatrix} A^{-1} X \\ D^{-1} ( Y - C A^{-1} X ) \end{pmatrix} + $$ + + to reduce the problem to matrix multiplication and triangular + solving of smaller systems. + +void fq_mat_solve_triu(fq_mat_t X, const fq_mat_t U, const fq_mat_t B, + int unit, const fq_ctx_t ctx) + + Sets $X = U^{-1} B$ where $U$ is a full rank upper triangular + square matrix. If \code{unit} = 1, $U$ is assumed to have ones on + its main diagonal, and the main diagonal will not be read. $X$ + and $B$ are allowed to be the same matrix, but no other aliasing + is allowed. Automatically chooses between the classical and + recursive algorithms. + +void fq_mat_solve_triu_classical(fq_mat_t X, const fq_mat_t U, + const fq_mat_t B, int unit, + const fq_ctx_t ctx) + + Sets $X = U^{-1} B$ where $U$ is a full rank upper triangular + square matrix. If \code{unit} = 1, $U$ is assumed to have ones on + its main diagonal, and the main diagonal will not be read. $X$ + and $B$ are allowed to be the same matrix, but no other aliasing + is allowed. Uses forward substitution. + +void fq_mat_solve_triu_recursive(fq_mat_t X, const fq_mat_t U, + const fq_mat_t B, int unit, + const fq_ctx_t ctx) + + Sets $X = U^{-1} B$ where $U$ is a full rank upper triangular + square matrix. If \code{unit} = 1, $U$ is assumed to have ones on + its main diagonal, and the main diagonal will not be read. $X$ + and $B$ are allowed to be the same matrix, but no other aliasing + is allowed. + + Uses the block inversion formula + + $$ + \begin{pmatrix} A & B \\ 0 & D \end{pmatrix}^{-1} + \begin{pmatrix} X \\ Y \end{pmatrix} = + \begin{pmatrix} A^{-1} (X - B D^{-1} Y) \\ D^{-1} Y \end{pmatrix} + $$ + + to reduce the problem to matrix multiplication and triangular + solving of smaller systems. diff --git a/external/flint-2.4.3/fq_mat/equal.c b/external/flint-2.4.3/fq_mat/equal.c new file mode 100644 index 0000000..fa72b65 --- /dev/null +++ b/external/flint-2.4.3/fq_mat/equal.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_mat_templates/equal.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_mat/fprint.c b/external/flint-2.4.3/fq_mat/fprint.c new file mode 100644 index 0000000..08d8f15 --- /dev/null +++ b/external/flint-2.4.3/fq_mat/fprint.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_mat_templates/fprint.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_mat/init.c b/external/flint-2.4.3/fq_mat/init.c new file mode 100644 index 0000000..379fc65 --- /dev/null +++ b/external/flint-2.4.3/fq_mat/init.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_mat_templates/init.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_mat/init_set.c b/external/flint-2.4.3/fq_mat/init_set.c new file mode 100644 index 0000000..e0c74b1 --- /dev/null +++ b/external/flint-2.4.3/fq_mat/init_set.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_mat_templates/init_set.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_mat/is_zero.c b/external/flint-2.4.3/fq_mat/is_zero.c new file mode 100644 index 0000000..b90ae8c --- /dev/null +++ b/external/flint-2.4.3/fq_mat/is_zero.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_mat_templates/is_zero.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_mat/lu.c b/external/flint-2.4.3/fq_mat/lu.c new file mode 100644 index 0000000..c274f6a --- /dev/null +++ b/external/flint-2.4.3/fq_mat/lu.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_mat_templates/lu.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_mat/lu_classical.c b/external/flint-2.4.3/fq_mat/lu_classical.c new file mode 100644 index 0000000..6144fca --- /dev/null +++ b/external/flint-2.4.3/fq_mat/lu_classical.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_mat_templates/lu_classical.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_mat/lu_recursive.c b/external/flint-2.4.3/fq_mat/lu_recursive.c new file mode 100644 index 0000000..ed87a7a --- /dev/null +++ b/external/flint-2.4.3/fq_mat/lu_recursive.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_mat_templates/lu_recursive.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_mat/mul.c b/external/flint-2.4.3/fq_mat/mul.c new file mode 100644 index 0000000..ddf9642 --- /dev/null +++ b/external/flint-2.4.3/fq_mat/mul.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_mat_templates/mul.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_mat/mul_KS.c b/external/flint-2.4.3/fq_mat/mul_KS.c new file mode 100644 index 0000000..0520d08 --- /dev/null +++ b/external/flint-2.4.3/fq_mat/mul_KS.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_mat_templates/mul_KS.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_mat/mul_classical.c b/external/flint-2.4.3/fq_mat/mul_classical.c new file mode 100644 index 0000000..3112014 --- /dev/null +++ b/external/flint-2.4.3/fq_mat/mul_classical.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_mat_templates/mul_classical.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_mat/neg.c b/external/flint-2.4.3/fq_mat/neg.c new file mode 100644 index 0000000..c2ddf46 --- /dev/null +++ b/external/flint-2.4.3/fq_mat/neg.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_mat_templates/neg.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_mat/profile/p-mul.c b/external/flint-2.4.3/fq_mat/profile/p-mul.c new file mode 100644 index 0000000..ead995b --- /dev/null +++ b/external/flint-2.4.3/fq_mat/profile/p-mul.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_mat_templates/profile/p-mul.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_mat/randops.c b/external/flint-2.4.3/fq_mat/randops.c new file mode 100644 index 0000000..ac62a75 --- /dev/null +++ b/external/flint-2.4.3/fq_mat/randops.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_mat_templates/randops.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_mat/randpermdiag.c b/external/flint-2.4.3/fq_mat/randpermdiag.c new file mode 100644 index 0000000..9436535 --- /dev/null +++ b/external/flint-2.4.3/fq_mat/randpermdiag.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_mat_templates/randpermdiag.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_mat/randrank.c b/external/flint-2.4.3/fq_mat/randrank.c new file mode 100644 index 0000000..9e20151 --- /dev/null +++ b/external/flint-2.4.3/fq_mat/randrank.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_mat_templates/randrank.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_mat/randtest.c b/external/flint-2.4.3/fq_mat/randtest.c new file mode 100644 index 0000000..e7aec2a --- /dev/null +++ b/external/flint-2.4.3/fq_mat/randtest.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_mat_templates/randtest.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_mat/randtril.c b/external/flint-2.4.3/fq_mat/randtril.c new file mode 100644 index 0000000..c185454 --- /dev/null +++ b/external/flint-2.4.3/fq_mat/randtril.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_mat_templates/randtril.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_mat/randtriu.c b/external/flint-2.4.3/fq_mat/randtriu.c new file mode 100644 index 0000000..e10e2df --- /dev/null +++ b/external/flint-2.4.3/fq_mat/randtriu.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_mat_templates/randtriu.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_mat/rref.c b/external/flint-2.4.3/fq_mat/rref.c new file mode 100644 index 0000000..c9ca16e --- /dev/null +++ b/external/flint-2.4.3/fq_mat/rref.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_mat_templates/rref.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_mat/set.c b/external/flint-2.4.3/fq_mat/set.c new file mode 100644 index 0000000..df3b3d1 --- /dev/null +++ b/external/flint-2.4.3/fq_mat/set.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_mat_templates/set.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_mat/solve_tril.c b/external/flint-2.4.3/fq_mat/solve_tril.c new file mode 100644 index 0000000..cf201ba --- /dev/null +++ b/external/flint-2.4.3/fq_mat/solve_tril.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_mat_templates/solve_tril.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_mat/solve_tril_classical.c b/external/flint-2.4.3/fq_mat/solve_tril_classical.c new file mode 100644 index 0000000..b15c992 --- /dev/null +++ b/external/flint-2.4.3/fq_mat/solve_tril_classical.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_mat_templates/solve_tril_classical.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_mat/solve_tril_recursive.c b/external/flint-2.4.3/fq_mat/solve_tril_recursive.c new file mode 100644 index 0000000..aae625f --- /dev/null +++ b/external/flint-2.4.3/fq_mat/solve_tril_recursive.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_mat_templates/solve_tril_recursive.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_mat/solve_triu.c b/external/flint-2.4.3/fq_mat/solve_triu.c new file mode 100644 index 0000000..3a9af21 --- /dev/null +++ b/external/flint-2.4.3/fq_mat/solve_triu.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_mat_templates/solve_triu.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_mat/solve_triu_classical.c b/external/flint-2.4.3/fq_mat/solve_triu_classical.c new file mode 100644 index 0000000..e29fa5b --- /dev/null +++ b/external/flint-2.4.3/fq_mat/solve_triu_classical.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_mat_templates/solve_triu_classical.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_mat/solve_triu_recursive.c b/external/flint-2.4.3/fq_mat/solve_triu_recursive.c new file mode 100644 index 0000000..b5575a4 --- /dev/null +++ b/external/flint-2.4.3/fq_mat/solve_triu_recursive.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_mat_templates/solve_triu_recursive.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_mat/sub.c b/external/flint-2.4.3/fq_mat/sub.c new file mode 100644 index 0000000..d5ee336 --- /dev/null +++ b/external/flint-2.4.3/fq_mat/sub.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_mat_templates/sub.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_mat/submul.c b/external/flint-2.4.3/fq_mat/submul.c new file mode 100644 index 0000000..0230d1c --- /dev/null +++ b/external/flint-2.4.3/fq_mat/submul.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_mat_templates/submul.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_mat/swap.c b/external/flint-2.4.3/fq_mat/swap.c new file mode 100644 index 0000000..2b522cc --- /dev/null +++ b/external/flint-2.4.3/fq_mat/swap.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_mat_templates/swap.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_mat/test/t-add_sub.c b/external/flint-2.4.3/fq_mat/test/t-add_sub.c new file mode 100644 index 0000000..e58134b --- /dev/null +++ b/external/flint-2.4.3/fq_mat/test/t-add_sub.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_mat_templates/test/t-add_sub.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_mat/test/t-equal.c b/external/flint-2.4.3/fq_mat/test/t-equal.c new file mode 100644 index 0000000..c8d5ce2 --- /dev/null +++ b/external/flint-2.4.3/fq_mat/test/t-equal.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_mat_templates/test/t-equal.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_mat/test/t-is_zero.c b/external/flint-2.4.3/fq_mat/test/t-is_zero.c new file mode 100644 index 0000000..035fc01 --- /dev/null +++ b/external/flint-2.4.3/fq_mat/test/t-is_zero.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_mat_templates/test/t-is_zero.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_mat/test/t-lu_classical.c b/external/flint-2.4.3/fq_mat/test/t-lu_classical.c new file mode 100644 index 0000000..836f687 --- /dev/null +++ b/external/flint-2.4.3/fq_mat/test/t-lu_classical.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_mat_templates/test/t-lu_classical.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_mat/test/t-lu_recursive.c b/external/flint-2.4.3/fq_mat/test/t-lu_recursive.c new file mode 100644 index 0000000..258ebb2 --- /dev/null +++ b/external/flint-2.4.3/fq_mat/test/t-lu_recursive.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_mat_templates/test/t-lu_recursive.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_mat/test/t-mul.c b/external/flint-2.4.3/fq_mat/test/t-mul.c new file mode 100644 index 0000000..9c11084 --- /dev/null +++ b/external/flint-2.4.3/fq_mat/test/t-mul.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_mat_templates/test/t-mul.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_mat/test/t-mul_KS.c b/external/flint-2.4.3/fq_mat/test/t-mul_KS.c new file mode 100644 index 0000000..c8cfa85 --- /dev/null +++ b/external/flint-2.4.3/fq_mat/test/t-mul_KS.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_mat_templates/test/t-mul_KS.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_mat/test/t-rref.c b/external/flint-2.4.3/fq_mat/test/t-rref.c new file mode 100644 index 0000000..7aeb164 --- /dev/null +++ b/external/flint-2.4.3/fq_mat/test/t-rref.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_mat_templates/test/t-rref.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_mat/test/t-solve_tril.c b/external/flint-2.4.3/fq_mat/test/t-solve_tril.c new file mode 100644 index 0000000..b829148 --- /dev/null +++ b/external/flint-2.4.3/fq_mat/test/t-solve_tril.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_mat_templates/test/t-solve_tril.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_mat/test/t-solve_tril_classical.c b/external/flint-2.4.3/fq_mat/test/t-solve_tril_classical.c new file mode 100644 index 0000000..e17211f --- /dev/null +++ b/external/flint-2.4.3/fq_mat/test/t-solve_tril_classical.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_mat_templates/test/t-solve_tril_classical.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_mat/test/t-solve_tril_recursive.c b/external/flint-2.4.3/fq_mat/test/t-solve_tril_recursive.c new file mode 100644 index 0000000..1b9d05c --- /dev/null +++ b/external/flint-2.4.3/fq_mat/test/t-solve_tril_recursive.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_mat_templates/test/t-solve_tril_recursive.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_mat/test/t-solve_triu.c b/external/flint-2.4.3/fq_mat/test/t-solve_triu.c new file mode 100644 index 0000000..d748cdf --- /dev/null +++ b/external/flint-2.4.3/fq_mat/test/t-solve_triu.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_mat_templates/test/t-solve_triu.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_mat/test/t-solve_triu_classical.c b/external/flint-2.4.3/fq_mat/test/t-solve_triu_classical.c new file mode 100644 index 0000000..54efa1d --- /dev/null +++ b/external/flint-2.4.3/fq_mat/test/t-solve_triu_classical.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_mat_templates/test/t-solve_triu_classical.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_mat/test/t-solve_triu_recursive.c b/external/flint-2.4.3/fq_mat/test/t-solve_triu_recursive.c new file mode 100644 index 0000000..a335ede --- /dev/null +++ b/external/flint-2.4.3/fq_mat/test/t-solve_triu_recursive.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_mat_templates/test/t-solve_triu_recursive.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_mat/test/t-submul.c b/external/flint-2.4.3/fq_mat/test/t-submul.c new file mode 100644 index 0000000..ea72802 --- /dev/null +++ b/external/flint-2.4.3/fq_mat/test/t-submul.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_mat_templates/test/t-submul.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_mat/test/t-zero.c b/external/flint-2.4.3/fq_mat/test/t-zero.c new file mode 100644 index 0000000..7437f0b --- /dev/null +++ b/external/flint-2.4.3/fq_mat/test/t-zero.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_mat_templates/test/t-zero.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_mat/window_clear.c b/external/flint-2.4.3/fq_mat/window_clear.c new file mode 100644 index 0000000..bec5fc0 --- /dev/null +++ b/external/flint-2.4.3/fq_mat/window_clear.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_mat_templates/window_clear.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_mat/window_init.c b/external/flint-2.4.3/fq_mat/window_init.c new file mode 100644 index 0000000..70e5ee1 --- /dev/null +++ b/external/flint-2.4.3/fq_mat/window_init.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_mat_templates/window_init.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_mat/zero.c b/external/flint-2.4.3/fq_mat/zero.c new file mode 100644 index 0000000..2501144 --- /dev/null +++ b/external/flint-2.4.3/fq_mat/zero.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_mat_templates/zero.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_mat_templates.h b/external/flint-2.4.3/fq_mat_templates.h new file mode 100644 index 0000000..05ac763 --- /dev/null +++ b/external/flint-2.4.3/fq_mat_templates.h @@ -0,0 +1,296 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ +#ifdef T + +#include "flint.h" +#include "templates.h" +#include "ulong_extras.h" + +#ifdef __cplusplus + extern "C" { +#endif + +typedef struct +{ + TEMPLATE(T, struct) * entries; + slong r; + slong c; + TEMPLATE(T, struct) ** rows; +} TEMPLATE(T, mat_struct); + +typedef TEMPLATE(T, mat_struct) TEMPLATE(T, mat_t)[1]; + +/* Memory management ********************************************************/ + +void +TEMPLATE(T, mat_init)(TEMPLATE(T, mat_t) mat, slong rows, slong cols, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, mat_init_set)(TEMPLATE(T, mat_t) mat, const TEMPLATE(T, mat_t) src, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, mat_swap)(TEMPLATE(T, mat_t) mat1, TEMPLATE(T, mat_t) mat2, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, mat_set)(TEMPLATE(T, mat_t) mat1, const TEMPLATE(T, mat_t) mat2, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, mat_clear)(TEMPLATE(T, mat_t) mat, const TEMPLATE(T, ctx_t) ctx); + +int +TEMPLATE(T, mat_equal)(const TEMPLATE(T, mat_t) mat1, + const TEMPLATE(T, mat_t) mat2, + const TEMPLATE(T, ctx_t) ctx); + +int +TEMPLATE(T, mat_is_zero)(const TEMPLATE(T, mat_t) mat, + const TEMPLATE(T, ctx_t) ctx); + +static __inline__ int +TEMPLATE(T, mat_is_empty)(const TEMPLATE(T, mat_t) mat, + const TEMPLATE(T, ctx_t) ctx) +{ + return (mat->r == 0) || (mat->c == 0); +} + +static __inline__ int +TEMPLATE(T, mat_is_square)(const TEMPLATE(T, mat_t) mat, + const TEMPLATE(T, ctx_t) ctx) +{ + return (mat->r == mat->c); +} + +static __inline__ TEMPLATE(T, struct) * +TEMPLATE(T, mat_entry)(const TEMPLATE(T, mat_t) mat, slong i, slong j) +{ + return mat->rows[i] + j; +} + +static __inline__ void +TEMPLATE(T, mat_entry_set)(TEMPLATE(T, mat_t) mat, slong i, slong j, + const TEMPLATE(T, t) x, + const TEMPLATE(T, ctx_t) ctx) +{ + TEMPLATE(T, set)(TEMPLATE(T, mat_entry)(mat, i, j), x, ctx); +} + +static __inline__ slong +TEMPLATE(T, mat_nrows)(const TEMPLATE(T, mat_t) mat , + const TEMPLATE(T, ctx_t) ctx) +{ + return mat->r; +} + +static __inline__ slong +TEMPLATE(T, mat_ncols)(const TEMPLATE(T, mat_t) mat, + const TEMPLATE(T, ctx_t) ctx) +{ + return mat->c; +} + +/* Assignment ***************************************************************/ +void +TEMPLATE(T, mat_zero)(TEMPLATE(T, mat_t) A, const TEMPLATE(T, ctx_t) ctx); + +/* Windows */ +void +TEMPLATE(T, mat_window_init)(TEMPLATE(T, mat_t) window, + const TEMPLATE(T, mat_t) mat, + slong r1, slong c1, slong r2, slong c2, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, mat_window_clear)(TEMPLATE(T, mat_t) window, + const TEMPLATE(T, ctx_t) ctx); + +/* Input and output *********************************************************/ + +int TEMPLATE(T, mat_fprint)(FILE * file, const TEMPLATE(T, mat_t) mat, + const TEMPLATE(T, ctx_t) ctx); + +int TEMPLATE(T, mat_fprint_pretty)(FILE * file, const TEMPLATE(T, mat_t) mat, + const TEMPLATE(T, ctx_t) ctx); + +static __inline__ +int TEMPLATE(T, mat_print)(const TEMPLATE(T, mat_t) mat, + const TEMPLATE(T, ctx_t) ctx) +{ + return TEMPLATE(T, mat_fprint)(stdout, mat, ctx); +} + +static __inline__ +int TEMPLATE(T, mat_print_pretty)(const TEMPLATE(T, mat_t) mat, + const TEMPLATE(T, ctx_t) ctx) +{ + return TEMPLATE(T, mat_fprint_pretty)(stdout, mat, ctx); +} + +/* TODO: Read functions */ + +/* Random matrix generation *************************************************/ +void +TEMPLATE(T, mat_randtest)(TEMPLATE(T, mat_t) mat, flint_rand_t state, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, mat_randrank)(TEMPLATE(T, mat_t) mat, flint_rand_t state, + slong rank, const TEMPLATE(T, ctx_t) ctx); + +int +TEMPLATE(T, mat_randpermdiag)(TEMPLATE(T, mat_t) mat, flint_rand_t state, + TEMPLATE(T, struct) * diag, slong n, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, mat_randops)(TEMPLATE(T, mat_t) mat, slong count, + flint_rand_t state, const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, mat_randtril)(TEMPLATE(T, mat_t) mat, flint_rand_t state, + int unit, const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, mat_randtriu)(TEMPLATE(T, mat_t) mat, flint_rand_t state, + int unit, const TEMPLATE(T, ctx_t) ctx); + +/* Norms */ + +/* Transpose */ + +/* Addition and subtraction */ + +void TEMPLATE(T, mat_add)(TEMPLATE(T, mat_t) C, + const TEMPLATE(T, mat_t) A, + const TEMPLATE(T, mat_t) B, + const TEMPLATE(T, ctx_t) ctx); + +void TEMPLATE(T, mat_sub)(TEMPLATE(T, mat_t) C, + const TEMPLATE(T, mat_t) A, + const TEMPLATE(T, mat_t) B, + const TEMPLATE(T, ctx_t) ctx); + +void TEMPLATE(T, mat_neg)(TEMPLATE(T, mat_t) B, + const TEMPLATE(T, mat_t) A, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, mat_submul)(TEMPLATE(T, mat_t) D, + const TEMPLATE(T, mat_t) C, + const TEMPLATE(T, mat_t) A, + const TEMPLATE(T, mat_t) B, + const TEMPLATE(T, ctx_t) ctx); + +/* Scalar operations */ + +/* Multiplication */ +void +TEMPLATE(T, mat_mul)(TEMPLATE(T, mat_t) C, + const TEMPLATE(T, mat_t) A, + const TEMPLATE(T, mat_t) B, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, mat_mul_classical)(TEMPLATE(T, mat_t) C, + const TEMPLATE(T, mat_t) A, + const TEMPLATE(T, mat_t) B, + const TEMPLATE(T, ctx_t) ctx); + + +void +TEMPLATE(T, mat_mul_KS)(TEMPLATE(T, mat_t) C, + const TEMPLATE(T, mat_t) A, + const TEMPLATE(T, mat_t) B, + const TEMPLATE(T, ctx_t) ctx); + +slong +TEMPLATE(T, mat_lu)(slong * P, + TEMPLATE(T, mat_t) A, + int rank_check, + const TEMPLATE(T, ctx_t) ctx); + +slong +TEMPLATE(T, mat_lu_recursive)(slong * P, + TEMPLATE(T, mat_t) A, + int rank_check, + const TEMPLATE(T, ctx_t) ctx); + +slong +TEMPLATE(T, mat_lu_classical)(slong * P, TEMPLATE(T, mat_t) A, int rank_check, + const TEMPLATE(T, ctx_t) ctx); + + +/* Solving *******************************************************************/ + +slong +TEMPLATE(T, mat_rref)(TEMPLATE(T, mat_t) A, const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, mat_solve_tril)(TEMPLATE(T, mat_t) X, const TEMPLATE(T, mat_t) L, + const TEMPLATE(T, mat_t) B, int unit, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, mat_solve_tril_classical)(TEMPLATE(T, mat_t) X, + const TEMPLATE(T, mat_t) L, + const TEMPLATE(T, mat_t) B, + int unit, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, mat_solve_tril_recursive)(TEMPLATE(T, mat_t) X, + const TEMPLATE(T, mat_t) L, + const TEMPLATE(T, mat_t) B, + int unit, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, mat_solve_triu)(TEMPLATE(T, mat_t) X, const TEMPLATE(T, mat_t) U, + const TEMPLATE(T, mat_t) B, int unit, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, mat_solve_triu_classical)(TEMPLATE(T, mat_t) X, + const TEMPLATE(T, mat_t) U, + const TEMPLATE(T, mat_t) B, + int unit, + const TEMPLATE(T, ctx_t) ctx); +void +TEMPLATE(T, mat_solve_triu_recursive)(TEMPLATE(T, mat_t) X, + const TEMPLATE(T, mat_t) U, + const TEMPLATE(T, mat_t) B, + int unit, + const TEMPLATE(T, ctx_t) ctx); + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/flint-2.4.3/fq_mat_templates/add.c b/external/flint-2.4.3/fq_mat_templates/add.c new file mode 100644 index 0000000..dca0e79 --- /dev/null +++ b/external/flint-2.4.3/fq_mat_templates/add.c @@ -0,0 +1,49 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +TEMPLATE(T, mat_add) (TEMPLATE(T, mat_t) res, + const TEMPLATE(T, mat_t) mat1, + const TEMPLATE(T, mat_t) mat2, + const TEMPLATE(T, ctx_t) ctx) +{ + slong i; + + if (res->c < 1) + return; + + for (i = 0; i < res->r; i++) + _TEMPLATE(T, vec_add) (res->rows[i], mat1->rows[i], mat2->rows[i], + res->c, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_mat_templates/clear.c b/external/flint-2.4.3/fq_mat_templates/clear.c new file mode 100644 index 0000000..04c026e --- /dev/null +++ b/external/flint-2.4.3/fq_mat_templates/clear.c @@ -0,0 +1,47 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +TEMPLATE(T, mat_clear) (TEMPLATE(T, mat_t) mat, const TEMPLATE(T, ctx_t) ctx) +{ + if (mat->entries) + { + slong i; + for (i = 0; i < mat->r * mat->c; i++) + TEMPLATE(T, clear) (mat->entries + i, ctx); /* Clear all coefficients */ + flint_free(mat->entries); /* Clean up array of entries */ + flint_free(mat->rows); /* Clean up row array */ + } +} + + +#endif diff --git a/external/flint-2.4.3/fq_mat_templates/equal.c b/external/flint-2.4.3/fq_mat_templates/equal.c new file mode 100644 index 0000000..8b6625e --- /dev/null +++ b/external/flint-2.4.3/fq_mat_templates/equal.c @@ -0,0 +1,59 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +int TEMPLATE(T, mat_equal) (const TEMPLATE(T, mat_t) mat1, + const TEMPLATE(T, mat_t) mat2, + const TEMPLATE(T, ctx_t) ctx) +{ + slong j; + + if (mat1->r != mat2->r || mat1->c != mat2->c) + { + return 0; + } + + if (mat1->r == 0 || mat1->c == 0) + return 1; + + for (j = 0; j < mat1->r; j++) + { + if (!_TEMPLATE(T, vec_equal) + (mat1->rows[j], mat2->rows[j], mat1->c, ctx)) + { + return 0; + } + } + + return 1; +} + + +#endif diff --git a/external/flint-2.4.3/fq_mat_templates/fprint.c b/external/flint-2.4.3/fq_mat_templates/fprint.c new file mode 100644 index 0000000..641606c --- /dev/null +++ b/external/flint-2.4.3/fq_mat_templates/fprint.c @@ -0,0 +1,126 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +/* + The macros xxx_putc, xxx_printf, and xxx_T_print are provided as + wrappers to handle return values and error conditions. While this + is not exactly pretty, it improves the readability of the + functions TEMPLATE(T, mat_fprint) and TEMPLATE(T, + mat_fprint_pretty). Moreover, if we later want to improve the + handling of returns values, e.g. to return the number of + characters printed, this will be easier. + + The macros are undef'd at the end of the file. + */ + +#define xxx_putc(c) \ +do { \ + z = fputc((c), file); \ + if (z <= 0) \ + return z; \ +} while (0) + +#define xxx_printf() \ +do { \ + z = fprintf(file, "%li %li ", r, c); \ + if (z <= 0) \ + return z; \ +} while (0) + +#define xxx_T_print(f, ctx) \ +do { \ + z = TEMPLATE(T, fprint)(file, (f), (ctx)); \ + if (z <= 0) \ + return z; \ +} while(0) + +#define xxx_T_print_pretty(f, ctx) \ +do { \ + z = TEMPLATE(T, fprint_pretty)(file, (f), (ctx)); \ + if (z <= 0) \ + return z; \ +} while(0) + +int TEMPLATE(T, mat_fprint) (FILE * file, const TEMPLATE(T, mat_t) mat, + const TEMPLATE(T, ctx_t) ctx) +{ + int z; + slong i, j; + slong r = mat->r; + slong c = mat->c; + + xxx_printf(); + for (i = 0; (i < r); i++) + { + for (j = 0; j < c; j++) + { + xxx_T_print(mat->rows[i] + j, ctx); + if (j != c - 1) + xxx_putc(' '); + } + if (i != r - 1) + xxx_putc(' '); + } + + return z; +} + +int TEMPLATE(T, mat_fprint_pretty) (FILE * file, const TEMPLATE(T, mat_t) mat, + const TEMPLATE(T, ctx_t) ctx) +{ + int z; + slong i, j; + slong r = mat->r; + slong c = mat->c; + + xxx_putc('['); + for (i = 0; i < r; i++) + { + xxx_putc('['); + for (j = 0; j < c; j++) + { + xxx_T_print_pretty(mat->rows[i] + j, ctx); + if (j != c - 1) + xxx_putc(' '); + } + xxx_putc(']'); + xxx_putc('\n'); + } + xxx_putc(']'); + + return z; +} + +#undef xxx_putc +#undef xxx_printf +#undef xxx_T_print + +#endif diff --git a/external/flint-2.4.3/fq_mat_templates/init.c b/external/flint-2.4.3/fq_mat_templates/init.c new file mode 100644 index 0000000..c25611c --- /dev/null +++ b/external/flint-2.4.3/fq_mat_templates/init.c @@ -0,0 +1,59 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +TEMPLATE(T, mat_init) (TEMPLATE(T, mat_t) mat, slong rows, slong cols, + const TEMPLATE(T, ctx_t) ctx) +{ + if ((rows) && (cols)) /* Allocate space for r*c small entries */ + { + slong i, j; + mat->entries = flint_malloc(rows * cols * sizeof(TEMPLATE(T, struct))); + mat->rows = flint_malloc(rows * sizeof(TEMPLATE(T, struct) *)); /* Initialise rows */ + + for (i = 0; i < rows; i++) + { + mat->rows[i] = mat->entries + i * cols; + for (j = 0; j < cols; j++) + { + TEMPLATE(T, init) (mat->rows[i] + j, ctx); + } + } + } + else + mat->entries = NULL; + + mat->r = rows; + mat->c = cols; +} + + +#endif diff --git a/external/flint-2.4.3/fq_mat_templates/init_set.c b/external/flint-2.4.3/fq_mat_templates/init_set.c new file mode 100644 index 0000000..1a6f6bc --- /dev/null +++ b/external/flint-2.4.3/fq_mat_templates/init_set.c @@ -0,0 +1,43 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +TEMPLATE(T, mat_init_set) (TEMPLATE(T, mat_t) mat, + const TEMPLATE(T, mat_t) src, + const TEMPLATE(T, ctx_t) ctx) +{ + TEMPLATE(T, mat_init) (mat, src->r, src->c, ctx); + TEMPLATE(T, mat_set) (mat, src, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_mat_templates/is_zero.c b/external/flint-2.4.3/fq_mat_templates/is_zero.c new file mode 100644 index 0000000..2e5c9b6 --- /dev/null +++ b/external/flint-2.4.3/fq_mat_templates/is_zero.c @@ -0,0 +1,51 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +int +TEMPLATE(T, mat_is_zero) (const TEMPLATE(T, mat_t) mat, + const TEMPLATE(T, ctx_t) ctx) +{ + slong j; + + if (mat->r == 0 || mat->c == 0) + return 1; + + for (j = 0; j < mat->r; j++) + { + if (!_TEMPLATE(T, vec_is_zero) (mat->rows[j], mat->c, ctx)) + return 0; + } + + return 1; +} + + +#endif diff --git a/external/flint-2.4.3/fq_mat_templates/lu.c b/external/flint-2.4.3/fq_mat_templates/lu.c new file mode 100644 index 0000000..fb409d2 --- /dev/null +++ b/external/flint-2.4.3/fq_mat_templates/lu.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +slong +TEMPLATE(T, mat_lu) (slong * P, TEMPLATE(T, mat_t) A, int rank_check, + const TEMPLATE(T, ctx_t) ctx) +{ + return TEMPLATE(T, mat_lu_recursive) (P, A, rank_check, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_mat_templates/lu_classical.c b/external/flint-2.4.3/fq_mat_templates/lu_classical.c new file mode 100644 index 0000000..42de827 --- /dev/null +++ b/external/flint-2.4.3/fq_mat_templates/lu_classical.c @@ -0,0 +1,131 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +static __inline__ int +TEMPLATE(T, mat_pivot) (TEMPLATE(T, mat_t) A, slong * P, slong start_row, + slong col, const TEMPLATE(T, ctx_t) ctx) +{ + slong j, t; + TEMPLATE(T, struct) * u; + + if (!TEMPLATE(T, is_zero) + (TEMPLATE(T, mat_entry) (A, start_row, col), ctx)) + return 1; + + for (j = start_row + 1; j < A->r; j++) + { + if (!TEMPLATE(T, is_zero) (TEMPLATE(T, mat_entry) (A, j, col), ctx)) + { + u = A->rows[j]; + A->rows[j] = A->rows[start_row]; + A->rows[start_row] = u; + + t = P[j]; + P[j] = P[start_row]; + P[start_row] = t; + + return -1; + } + } + return 0; +} + + +slong +TEMPLATE(T, mat_lu_classical) (slong * P, + TEMPLATE(T, mat_t) A, + int rank_check, const TEMPLATE(T, ctx_t) ctx) +{ + TEMPLATE(T, t) d, e, neg_e; + TEMPLATE(T, struct) ** a; + slong i, m, n, rank, length, row, col; + + m = A->r; + n = A->c; + a = A->rows; + + rank = row = col = 0; + + for (i = 0; i < m; i++) + P[i] = i; + + TEMPLATE(T, init) (d, ctx); + TEMPLATE(T, init) (e, ctx); + TEMPLATE(T, init) (neg_e, ctx); + + while (row < m && col < n) + { + if (TEMPLATE(T, mat_pivot) (A, P, row, col, ctx) == 0) + { + if (rank_check) + return 0; + col++; + continue; + } + + rank++; + + TEMPLATE(T, inv) (d, a[row] + col, ctx); + + length = n - col - 1; + + for (i = row + 1; i < m; i++) + { + TEMPLATE(T, mul) (e, a[i] + col, d, ctx); + if (length != 0) + { + TEMPLATE(T, neg) (neg_e, e, ctx); + _TEMPLATE3(T, vec_scalar_addmul, T) (a[i] + col + 1, + a[row] + col + 1, + length, neg_e, ctx); + } + + TEMPLATE(T, zero) (a[i] + col, ctx); + TEMPLATE(T, set) (a[i] + rank - 1, e, ctx); + } + row++; + col++; + } + + TEMPLATE(T, clear) (d, ctx); + TEMPLATE(T, clear) (e, ctx); + TEMPLATE(T, clear) (neg_e, ctx); + + return rank; +} + + +#endif diff --git a/external/flint-2.4.3/fq_mat_templates/lu_recursive.c b/external/flint-2.4.3/fq_mat_templates/lu_recursive.c new file mode 100644 index 0000000..6fdec50 --- /dev/null +++ b/external/flint-2.4.3/fq_mat_templates/lu_recursive.c @@ -0,0 +1,158 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + + Loosely based on the recursive PLS implementation in M4RI, + Copyright (C) 2008 Clement Pernet. + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include + +static void +_apply_permutation(slong * AP, + TEMPLATE(T, mat_t) A, slong * P, slong n, slong offset) +{ + if (n != 0) + { + TEMPLATE(T, struct) ** Atmp; + slong *APtmp; + slong i; + + Atmp = flint_malloc(sizeof(TEMPLATE(T, struct) *) * n); + APtmp = flint_malloc(sizeof(slong) * n); + + for (i = 0; i < n; i++) + Atmp[i] = A->rows[P[i] + offset]; + for (i = 0; i < n; i++) + A->rows[i + offset] = Atmp[i]; + + for (i = 0; i < n; i++) + APtmp[i] = AP[P[i] + offset]; + for (i = 0; i < n; i++) + AP[i + offset] = APtmp[i]; + + flint_free(Atmp); + flint_free(APtmp); + } +} + + +slong +TEMPLATE(T, mat_lu_recursive) (slong * P, + TEMPLATE(T, mat_t) A, + int rank_check, const TEMPLATE(T, ctx_t) ctx) +{ + + slong i, j, m, n, r1, r2, n1; + TEMPLATE(T, mat_t) A0, A1, A00, A01, A10, A11; + slong *P1; + + m = A->r; + n = A->c; + + if (m < TEMPLATE(CAP_T, MAT_LU_RECURSIVE_CUTOFF) + || n < TEMPLATE(CAP_T, MAT_LU_RECURSIVE_CUTOFF)) + { + r1 = TEMPLATE(T, mat_lu_classical) (P, A, rank_check, ctx); + return r1; + } + + n1 = n / 2; + + for (i = 0; i < m; i++) + P[i] = i; + + P1 = flint_malloc(sizeof(slong) * m); + TEMPLATE(T, mat_window_init) (A0, A, 0, 0, m, n1, ctx); + TEMPLATE(T, mat_window_init) (A1, A, 0, n1, m, n, ctx); + + r1 = TEMPLATE(T, mat_lu) (P1, A0, rank_check, ctx); + + if (rank_check && (r1 != n1)) + { + flint_free(P1); + TEMPLATE(T, mat_window_clear) (A0, ctx); + TEMPLATE(T, mat_window_clear) (A1, ctx); + return 0; + } + + if (r1 != 0) + { + _apply_permutation(P, A, P1, m, 0); + } + + TEMPLATE(T, mat_window_init) (A00, A, 0, 0, r1, r1, ctx); + TEMPLATE(T, mat_window_init) (A10, A, r1, 0, m, r1, ctx); + TEMPLATE(T, mat_window_init) (A01, A, 0, n1, r1, n, ctx); + TEMPLATE(T, mat_window_init) (A11, A, r1, n1, m, n, ctx); + + if (r1 != 0) + { + TEMPLATE(T, mat_solve_tril) (A01, A00, A01, 1, ctx); + TEMPLATE(T, mat_submul) (A11, A11, A10, A01, ctx); + } + + r2 = TEMPLATE(T, mat_lu) (P1, A11, rank_check, ctx); + + if (rank_check && (r1 + r2 < FLINT_MIN(m, n))) + { + r1 = r2 = 0; + } + else + { + _apply_permutation(P, A, P1, m - r1, r1); + + /* Compress L */ + if (r1 != n1) + { + for (i = 0; i < m - r1; i++) + { + TEMPLATE(T, struct) * row = A->rows[r1 + i]; + for (j = 0; j < FLINT_MIN(i, r2); j++) + { + TEMPLATE(T, set) (row + r1 + j, row + n1 + j, ctx); + TEMPLATE(T, zero) (row + n1 + j, ctx); + } + } + } + } + + flint_free(P1); + TEMPLATE(T, mat_window_clear) (A00, ctx); + TEMPLATE(T, mat_window_clear) (A01, ctx); + TEMPLATE(T, mat_window_clear) (A10, ctx); + TEMPLATE(T, mat_window_clear) (A11, ctx); + TEMPLATE(T, mat_window_clear) (A0, ctx); + TEMPLATE(T, mat_window_clear) (A1, ctx); + + return r1 + r2; +} + + +#endif diff --git a/external/flint-2.4.3/fq_mat_templates/mul.c b/external/flint-2.4.3/fq_mat_templates/mul.c new file mode 100644 index 0000000..d676f20 --- /dev/null +++ b/external/flint-2.4.3/fq_mat_templates/mul.c @@ -0,0 +1,43 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +TEMPLATE(T, mat_mul) (TEMPLATE(T, mat_t) C, + const TEMPLATE(T, mat_t) A, + const TEMPLATE(T, mat_t) B, const TEMPLATE(T, ctx_t) ctx) +{ + if (TEMPLATE(CAP_T, MAT_MUL_KS_CUTOFF) (A->r, B->c, ctx)) + TEMPLATE(T, mat_mul_KS) (C, A, B, ctx); + else + TEMPLATE(T, mat_mul_classical) (C, A, B, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_mat_templates/mul_KS.c b/external/flint-2.4.3/fq_mat_templates/mul_KS.c new file mode 100644 index 0000000..0d0f645 --- /dev/null +++ b/external/flint-2.4.3/fq_mat_templates/mul_KS.c @@ -0,0 +1,100 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" +#include "fmpz_mat.h" + +void +TEMPLATE(T, mat_mul_KS) (TEMPLATE(T, mat_t) C, + const TEMPLATE(T, mat_t) A, + const TEMPLATE(T, mat_t) B, + const TEMPLATE(T, ctx_t) ctx) +{ + slong bits; + slong ar, bc, br; + slong i, j; + fmpz_mat_t fa, fb, fc; + fmpz_t beta; + + ar = A->r; + br = B->r; + bc = B->c; + + if (br == 0) + { + TEMPLATE(T, mat_zero) (C, ctx); + return; + } + + /* Compute the number of bits needed */ + + /* TODO: Make this generic based on say an TEMPLATE(T, + * bits_needed) and TEMPLATE(T, bit_pack) */ + fmpz_init(beta); + fmpz_set(beta, TEMPLATE(T, ctx_prime) (ctx)); + fmpz_sub_ui(beta, beta, 1); + fmpz_mul(beta, beta, beta); + fmpz_mul_si(beta, beta, A->r); + fmpz_mul_si(beta, beta, TEMPLATE(T, ctx_degree) (ctx)); + bits = fmpz_bits(beta) + 1; + + fmpz_mat_init(fa, A->r, A->c); + fmpz_mat_init(fb, B->r, B->c); + fmpz_mat_init(fc, A->r, B->c); + + for (i = 0; i < A->r; i++) + for (j = 0; j < A->c; j++) + TEMPLATE(T, bit_pack) (fmpz_mat_entry(fa, i, j), + TEMPLATE(T, mat_entry) (A, i, j), bits, + ctx); + + for (i = 0; i < B->r; i++) + for (j = 0; j < B->c; j++) + TEMPLATE(T, bit_pack) (fmpz_mat_entry(fb, i, j), + TEMPLATE(T, mat_entry) (B, i, j), bits, + ctx); + + fmpz_mat_mul(fc, fa, fb); + + for (i = 0; i < ar; i++) + { + for (j = 0; j < bc; j++) + { + TEMPLATE(T, bit_unpack) (TEMPLATE(T, mat_entry) (C, i, j), + fmpz_mat_entry(fc, i, j), bits, ctx); + } + } + + fmpz_mat_clear(fa); + fmpz_mat_clear(fb); + fmpz_mat_clear(fc); +} + + +#endif diff --git a/external/flint-2.4.3/fq_mat_templates/mul_classical.c b/external/flint-2.4.3/fq_mat_templates/mul_classical.c new file mode 100644 index 0000000..8998771 --- /dev/null +++ b/external/flint-2.4.3/fq_mat_templates/mul_classical.c @@ -0,0 +1,88 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +TEMPLATE(T, mat_mul_classical) (TEMPLATE(T, mat_t) C, + const TEMPLATE(T, mat_t) A, + const TEMPLATE(T, mat_t) B, + const TEMPLATE(T, ctx_t) ctx) +{ + slong ar, bc, br; + slong i, j, k; + TEMPLATE(T, t) t; + + ar = A->r; + br = B->r; + bc = B->c; + + if (br == 0) + { + TEMPLATE(T, mat_zero) (C, ctx); + return; + } + + if (C == A || C == B) + { + TEMPLATE(T, mat_t) T; + TEMPLATE(T, mat_init) (T, ar, bc, ctx); + TEMPLATE(T, mat_mul_classical) (T, A, B, ctx); + TEMPLATE(T, mat_swap) (C, T, ctx); + TEMPLATE(T, mat_clear) (T, ctx); + return; + } + + TEMPLATE(T, init) (t, ctx); + + for (i = 0; i < ar; i++) + { + for (j = 0; j < bc; j++) + { + TEMPLATE(T, mul) (TEMPLATE(T, mat_entry) (C, i, j), + TEMPLATE(T, mat_entry) (A, i, 0), + TEMPLATE(T, mat_entry) (B, 0, j), ctx); + + for (k = 1; k < br; k++) + { + TEMPLATE(T, mul) (t, + TEMPLATE(T, mat_entry) (A, i, k), + TEMPLATE(T, mat_entry) (B, k, j), ctx); + + TEMPLATE(T, add) (TEMPLATE(T, mat_entry) (C, i, j), + TEMPLATE(T, mat_entry) (C, i, j), t, ctx); + } + } + } + + TEMPLATE(T, clear) (t, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_mat_templates/neg.c b/external/flint-2.4.3/fq_mat_templates/neg.c new file mode 100644 index 0000000..08cbc24 --- /dev/null +++ b/external/flint-2.4.3/fq_mat_templates/neg.c @@ -0,0 +1,47 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +TEMPLATE(T, mat_neg) (TEMPLATE(T, mat_t) res, + const TEMPLATE(T, mat_t) mat, + const TEMPLATE(T, ctx_t) ctx) +{ + slong i; + + if (res->c < 1) + return; + + for (i = 0; i < res->r; i++) + _TEMPLATE(T, vec_neg) (res->rows[i], mat->rows[i], res->c, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_mat_templates/profile/p-mul.c b/external/flint-2.4.3/fq_mat_templates/profile/p-mul.c new file mode 100644 index 0000000..4bb2dc6 --- /dev/null +++ b/external/flint-2.4.3/fq_mat_templates/profile/p-mul.c @@ -0,0 +1,132 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#ifdef T + +#include "flint.h" +#include "templates.h" + +#include +#include +#include "profiler.h" + +#define nalgs 2 +#define cpumin 2 +#define ncases 1 + +int +main(int argc, char** argv) +{ + fmpz_t p; + int c, n, reps = 0; + slong d, mat_size; + fq_ctx_t ctx; + fq_mat_t f, g, h; + + double s[nalgs]; + + FLINT_TEST_INIT(state); + + fmpz_init(p); + fmpz_set_str(p, argv[1], 10); + + d = atol(argv[2]); + mat_size = atol(argv[3]); + + TEMPLATE(T, ctx_init)(ctx, p, d, "a"); + + TEMPLATE(T, mat_init)(f, mat_size, mat_size, ctx); + TEMPLATE(T, mat_init)(g, mat_size, mat_size, ctx); + TEMPLATE(T, mat_init)(h, mat_size, mat_size, ctx); + + for (c = 0; c < nalgs; c++) + s[c] = 0.0; + + for (n = 0; n < ncases; n++) + { + double t[nalgs]; + int lo, loops = 1; + + /* + Construct random elements of fq + */ + { + TEMPLATE(T, mat_randtest)(g, state, ctx); + TEMPLATE(T, mat_randtest)(h, state, ctx); + } + + loop: + + t[0] = 0.0; + init_clock(0); + prof_start(); + for (lo = 0; lo < loops; lo++) + { + TEMPLATE(T, mat_mul_classical)(h, f, g, ctx); + } + prof_stop(); + t[0] += get_clock(0); + + t[1] = 0.0; + init_clock(0); + prof_start(); + for (lo = 0; lo < loops; lo++) + { + TEMPLATE(T, mat_mul_KS)(h, f, g, ctx); + } + prof_stop(); + t[1] += get_clock(0); + + for (c = 0; c < nalgs; c++) + if (t[c] * FLINT_CLOCK_SCALE_FACTOR <= cpumin) + { + loops *= 10; + goto loop; + } + + for (c = 0; c < nalgs; c++) + s[c] += t[c]; + reps += loops; + } + + for (c = 0; c < nalgs; c++) + { + printf("%20f", s[c] / (double) reps); + fflush(stdout); + } + printf("\n"); + + TEMPLATE(T, mat_clear)(f, ctx); + TEMPLATE(T, mat_clear)(g, ctx); + TEMPLATE(T, mat_clear)(h, ctx); + TEMPLATE(T, ctx_clear)(ctx); + fmpz_clear(p); + + FLINT_TEST_CLEANUP(state); + + return 0; +} + +#endif diff --git a/external/flint-2.4.3/fq_mat_templates/randops.c b/external/flint-2.4.3/fq_mat_templates/randops.c new file mode 100644 index 0000000..dd813c7 --- /dev/null +++ b/external/flint-2.4.3/fq_mat_templates/randops.c @@ -0,0 +1,76 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +TEMPLATE(T, mat_randops) (TEMPLATE(T, mat_t) mat, slong count, + flint_rand_t state, const TEMPLATE(T, ctx_t) ctx) +{ + slong c, i, j, k; + slong m = mat->r; + slong n = mat->c; + + if (mat->r == 0 || mat->c == 0) + return; + + for (c = 0; c < count; c++) + { + if (n_randint(state, 2)) + { + if ((i = n_randint(state, m)) == (j = n_randint(state, m))) + continue; + + if (n_randint(state, 2)) + for (k = 0; k < n; k++) + TEMPLATE(T, add) (mat->rows[j] + k, + mat->rows[j] + k, mat->rows[i] + k, ctx); + else + for (k = 0; k < n; k++) + TEMPLATE(T, sub) (mat->rows[j] + k, + mat->rows[j] + k, mat->rows[i] + k, ctx); + } + else + { + if ((i = n_randint(state, n)) == (j = n_randint(state, n))) + continue; + if (n_randint(state, 2)) + for (k = 0; k < m; k++) + TEMPLATE(T, add) (mat->rows[k] + j, + mat->rows[k] + j, mat->rows[k] + i, ctx); + else + for (k = 0; k < m; k++) + TEMPLATE(T, sub) (mat->rows[k] + j, + mat->rows[k] + j, mat->rows[k] + i, ctx); + } + } +} + + +#endif diff --git a/external/flint-2.4.3/fq_mat_templates/randpermdiag.c b/external/flint-2.4.3/fq_mat_templates/randpermdiag.c new file mode 100644 index 0000000..a3d7e3d --- /dev/null +++ b/external/flint-2.4.3/fq_mat_templates/randpermdiag.c @@ -0,0 +1,63 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010,2011 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include "flint.h" +#include "ulong_extras.h" +#include "perm.h" + +int +TEMPLATE(T, mat_randpermdiag) (TEMPLATE(T, mat_t) mat, flint_rand_t state, + TEMPLATE(T, struct) * diag, slong n, + const TEMPLATE(T, ctx_t) ctx) +{ + int parity; + slong i; + slong *rows; + slong *cols; + + rows = _perm_init(mat->r); + cols = _perm_init(mat->c); + + parity = _perm_randtest(rows, mat->r, state); + parity ^= _perm_randtest(cols, mat->c, state); + + TEMPLATE(T, mat_zero) (mat, ctx); + for (i = 0; i < n; i++) + TEMPLATE(T, mat_entry_set) (mat, rows[i], cols[i], diag + i, ctx); + + _perm_clear(rows); + _perm_clear(cols); + + return parity; +} + + +#endif diff --git a/external/flint-2.4.3/fq_mat_templates/randrank.c b/external/flint-2.4.3/fq_mat_templates/randrank.c new file mode 100644 index 0000000..ec3a449 --- /dev/null +++ b/external/flint-2.4.3/fq_mat_templates/randrank.c @@ -0,0 +1,55 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +TEMPLATE(T, mat_randrank) (TEMPLATE(T, mat_t) mat, flint_rand_t state, + slong rank, const TEMPLATE(T, ctx_t) ctx) +{ + slong i; + TEMPLATE(T, struct) * diag; + + if (rank < 0 || rank > mat->r || rank > mat->c) + { + printf("Exception (nmod_mat_randrank). Impossible rank.\n"); + abort(); + } + + diag = _TEMPLATE(T, vec_init) (rank, ctx); + for (i = 0; i < rank; i++) + TEMPLATE(T, randtest_not_zero) (diag + i, state, ctx); + + TEMPLATE(T, mat_randpermdiag) (mat, state, diag, rank, ctx); + + _TEMPLATE(T, vec_clear) (diag, rank, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_mat_templates/randtest.c b/external/flint-2.4.3/fq_mat_templates/randtest.c new file mode 100644 index 0000000..36fdc02 --- /dev/null +++ b/external/flint-2.4.3/fq_mat_templates/randtest.c @@ -0,0 +1,47 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +TEMPLATE(T, mat_randtest) (TEMPLATE(T, mat_t) mat, flint_rand_t state, + const TEMPLATE(T, ctx_t) ctx) +{ + slong r, c, i, j; + + r = mat->r; + c = mat->c; + + for (i = 0; i < r; i++) + for (j = 0; j < c; j++) + TEMPLATE(T, randtest) (mat->rows[i] + j, state, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_mat_templates/randtril.c b/external/flint-2.4.3/fq_mat_templates/randtril.c new file mode 100644 index 0000000..4ec7418 --- /dev/null +++ b/external/flint-2.4.3/fq_mat_templates/randtril.c @@ -0,0 +1,63 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +TEMPLATE(T, mat_randtril) (TEMPLATE(T, mat_t) mat, flint_rand_t state, + int unit, const TEMPLATE(T, ctx_t) ctx) +{ + TEMPLATE(T, struct) * e; + slong i, j; + + for (i = 0; i < mat->r; i++) + { + for (j = 0; j < mat->c; j++) + { + e = TEMPLATE(T, mat_entry) (mat, i, j); + if (j < i) + { + TEMPLATE(T, randtest) (e, state, ctx); + } + else if (i == j) + { + TEMPLATE(T, randtest) (e, state, ctx); + if (unit || TEMPLATE(T, is_zero) (e, ctx)) + TEMPLATE(T, one) (e, ctx); + } + else + { + TEMPLATE(T, zero) (e, ctx); + } + } + } +} + + +#endif diff --git a/external/flint-2.4.3/fq_mat_templates/randtriu.c b/external/flint-2.4.3/fq_mat_templates/randtriu.c new file mode 100644 index 0000000..14ba075 --- /dev/null +++ b/external/flint-2.4.3/fq_mat_templates/randtriu.c @@ -0,0 +1,63 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +TEMPLATE(T, mat_randtriu) (TEMPLATE(T, mat_t) mat, flint_rand_t state, + int unit, const TEMPLATE(T, ctx_t) ctx) +{ + TEMPLATE(T, struct) * e; + slong i, j; + + for (i = 0; i < mat->r; i++) + { + for (j = 0; j < mat->c; j++) + { + e = TEMPLATE(T, mat_entry) (mat, i, j); + if (j > i) + { + TEMPLATE(T, randtest) (e, state, ctx); + } + else if (i == j) + { + TEMPLATE(T, randtest) (e, state, ctx); + if (unit || TEMPLATE(T, is_zero)(e, ctx)) + TEMPLATE(T, one) (e, ctx); + } + else + { + TEMPLATE(T, zero) (e, ctx); + } + } + } +} + + +#endif diff --git a/external/flint-2.4.3/fq_mat_templates/rref.c b/external/flint-2.4.3/fq_mat_templates/rref.c new file mode 100644 index 0000000..1417592 --- /dev/null +++ b/external/flint-2.4.3/fq_mat_templates/rref.c @@ -0,0 +1,148 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include +#include "flint.h" +#include "perm.h" + +slong +TEMPLATE(T, mat_rref) (TEMPLATE(T, mat_t) A, const TEMPLATE(T, ctx_t) ctx) +{ + slong i, j, k, n, rank; + slong *pivots; + slong *nonpivots; + slong *P; + TEMPLATE(T, struct) * e; + TEMPLATE(T, mat_t) U, V; + + n = A->c; + + P = _perm_init(TEMPLATE(T, mat_nrows) (A, ctx)); + rank = TEMPLATE(T, mat_lu) (P, A, 0, ctx); + _perm_clear(P); + + if (rank == 0) + return rank; + + /* Clear L */ + for (i = 0; i < A->r; i++) + for (j = 0; j < FLINT_MIN(i, rank); j++) + TEMPLATE(T, zero) (TEMPLATE(T, mat_entry) (A, i, j), ctx); + + /* We now reorder U to proper upper triangular form U | V + with U full-rank triangular, set V = U^(-1) V, and then + put the column back in the original order. + + An improvement for some matrices would be to compress V by + discarding columns containing nothing but zeros. */ + + TEMPLATE(T, mat_init) (U, rank, rank, ctx); + TEMPLATE(T, mat_init) (V, rank, n - rank, ctx); + + pivots = flint_malloc(sizeof(slong) * rank); + nonpivots = flint_malloc(sizeof(slong) * (n - rank)); + + for (i = j = k = 0; i < rank; i++) + { + while (TEMPLATE(T, is_zero) (TEMPLATE(T, mat_entry) (A, i, j), ctx)) + { + nonpivots[k] = j; + k++; + j++; + } + pivots[i] = j; + j++; + } + while (k < n - rank) + { + nonpivots[k] = j; + k++; + j++; + } + + for (i = 0; i < rank; i++) + { + for (j = 0; j <= i; j++) + { + e = TEMPLATE(T, mat_entry) (A, j, pivots[i]); + TEMPLATE(T, mat_entry_set) (U, j, i, e, ctx); + } + } + + for (i = 0; i < n - rank; i++) + { + for (j = 0; j < rank; j++) + { + e = TEMPLATE(T, mat_entry) (A, j, nonpivots[i]); + TEMPLATE(T, mat_entry_set) (V, j, i, e, ctx); + } + } + + TEMPLATE(T, mat_solve_triu) (V, U, V, 0, ctx); + + /* Clear pivot columns */ + for (i = 0; i < rank; i++) + { + for (j = 0; j <= i; j++) + { + if (i == j) + { + TEMPLATE(T, one) (TEMPLATE(T, mat_entry) (A, j, pivots[i]), + ctx); + } + else + { + TEMPLATE(T, zero) (TEMPLATE(T, mat_entry) (A, j, pivots[i]), + ctx); + } + } + } + + /* Write back the actual content */ + for (i = 0; i < n - rank; i++) + { + for (j = 0; j < rank; j++) + TEMPLATE(T, mat_entry_set) (A, j, nonpivots[i], + TEMPLATE(T, mat_entry) (V, j, i), ctx); + } + + TEMPLATE(T, mat_clear) (U, ctx); + TEMPLATE(T, mat_clear) (V, ctx); + + flint_free(pivots); + flint_free(nonpivots); + + return rank; +} + + +#endif diff --git a/external/flint-2.4.3/fq_mat_templates/set.c b/external/flint-2.4.3/fq_mat_templates/set.c new file mode 100644 index 0000000..ba5759c --- /dev/null +++ b/external/flint-2.4.3/fq_mat_templates/set.c @@ -0,0 +1,49 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +TEMPLATE(T, mat_set) (TEMPLATE(T, mat_t) mat1, const TEMPLATE(T, mat_t) mat2, + const TEMPLATE(T, ctx_t) ctx) +{ + if (mat1 != mat2) + { + slong i; + + if (mat2->r && mat2->c) + for (i = 0; i < mat2->r; i++) + _TEMPLATE(T, vec_set) (mat1->rows[i], mat2->rows[i], mat2->c, + ctx); + } +} + + +#endif diff --git a/external/flint-2.4.3/fq_mat_templates/solve_tril.c b/external/flint-2.4.3/fq_mat_templates/solve_tril.c new file mode 100644 index 0000000..5372714 --- /dev/null +++ b/external/flint-2.4.3/fq_mat_templates/solve_tril.c @@ -0,0 +1,49 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010,2011 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +TEMPLATE(T, mat_solve_tril) (TEMPLATE(T, mat_t) X, const TEMPLATE(T, mat_t) L, + const TEMPLATE(T, mat_t) B, int unit, + const TEMPLATE(T, ctx_t) ctx) +{ + if (B->r < TEMPLATE(CAP_T, MAT_SOLVE_TRI_ROWS_CUTOFF) || + B->c < TEMPLATE(CAP_T, MAT_SOLVE_TRI_COLS_CUTOFF)) + { + TEMPLATE(T, mat_solve_tril_classical) (X, L, B, unit, ctx); + } + else + { + TEMPLATE(T, mat_solve_tril_recursive) (X, L, B, unit, ctx); + } +} + + +#endif diff --git a/external/flint-2.4.3/fq_mat_templates/solve_tril_classical.c b/external/flint-2.4.3/fq_mat_templates/solve_tril_classical.c new file mode 100644 index 0000000..2c776cd --- /dev/null +++ b/external/flint-2.4.3/fq_mat_templates/solve_tril_classical.c @@ -0,0 +1,82 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010,2011 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +TEMPLATE(T, mat_solve_tril_classical) (TEMPLATE(T, mat_t) X, + const TEMPLATE(T, mat_t) L, + const TEMPLATE(T, mat_t) B, + int unit, const TEMPLATE(T, ctx_t) ctx) +{ + slong i, j, n, m; + TEMPLATE(T, struct) * inv, *tmp; + + n = L->r; + m = B->c; + + if (!unit) + { + inv = _TEMPLATE(T, vec_init) (n, ctx); + for (i = 0; i < n; i++) + TEMPLATE(T, inv) (inv + i, TEMPLATE(T, mat_entry) (L, i, i), ctx); + } + else + inv = NULL; + + tmp = _TEMPLATE(T, vec_init) (n, ctx); + + for (i = 0; i < m; i++) + { + for (j = 0; j < n; j++) + TEMPLATE(T, set) (tmp + j, TEMPLATE(T, mat_entry) (X, j, i), ctx); + + for (j = 0; j < n; j++) + { + TEMPLATE(T, t) s; + TEMPLATE(T, init) (s, ctx); + _TEMPLATE(T, vec_dot) (s, L->rows[j], tmp, j, ctx); + TEMPLATE(T, sub) (s, TEMPLATE(T, mat_entry) (B, j, i), s, ctx); + if (!unit) + TEMPLATE(T, mul) (s, s, inv + j, ctx); + TEMPLATE(T, set) (tmp + j, s, ctx); + TEMPLATE(T, clear) (s, ctx); + } + + for (j = 0; j < n; j++) + TEMPLATE(T, mat_entry_set) (X, j, i, tmp + j, ctx); + } + + _TEMPLATE(T, vec_clear) (tmp, n, ctx); + if (!unit) + _TEMPLATE(T, vec_clear) (inv, n, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_mat_templates/solve_tril_recursive.c b/external/flint-2.4.3/fq_mat_templates/solve_tril_recursive.c new file mode 100644 index 0000000..ab73a53 --- /dev/null +++ b/external/flint-2.4.3/fq_mat_templates/solve_tril_recursive.c @@ -0,0 +1,77 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010,2011 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +TEMPLATE(T, mat_solve_tril_recursive) (TEMPLATE(T, mat_t) X, + const TEMPLATE(T, mat_t) L, + const TEMPLATE(T, mat_t) B, + int unit, const TEMPLATE(T, ctx_t) ctx) +{ + TEMPLATE(T, mat_t) LA, LC, LD, XX, XY, BX, BY; + slong r, n, m; + + n = L->r; + m = B->c; + r = n / 2; + + if (n == 0 || m == 0) + return; + + /* + Denoting inv(M) by M^, we have: + + [A 0]^ [X] == [A^ 0 ] [X] == [A^ X] + [C D] [Y] == [-D^ C A^ D^] [Y] == [D^ (Y - C A^ X)] + */ + + TEMPLATE(T, mat_window_init) (LA, L, 0, 0, r, r, ctx); + TEMPLATE(T, mat_window_init) (LC, L, r, 0, n, r, ctx); + TEMPLATE(T, mat_window_init) (LD, L, r, r, n, n, ctx); + TEMPLATE(T, mat_window_init) (BX, B, 0, 0, r, m, ctx); + TEMPLATE(T, mat_window_init) (BY, B, r, 0, n, m, ctx); + TEMPLATE(T, mat_window_init) (XX, X, 0, 0, r, m, ctx); + TEMPLATE(T, mat_window_init) (XY, X, r, 0, n, m, ctx); + + TEMPLATE(T, mat_solve_tril) (XX, LA, BX, unit, ctx); + TEMPLATE(T, mat_submul) (XY, BY, LC, XX, ctx); + TEMPLATE(T, mat_solve_tril) (XY, LD, XY, unit, ctx); + + TEMPLATE(T, mat_window_clear) (LA, ctx); + TEMPLATE(T, mat_window_clear) (LC, ctx); + TEMPLATE(T, mat_window_clear) (LD, ctx); + TEMPLATE(T, mat_window_clear) (BX, ctx); + TEMPLATE(T, mat_window_clear) (BY, ctx); + TEMPLATE(T, mat_window_clear) (XX, ctx); + TEMPLATE(T, mat_window_clear) (XY, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_mat_templates/solve_triu.c b/external/flint-2.4.3/fq_mat_templates/solve_triu.c new file mode 100644 index 0000000..fd3f3ad --- /dev/null +++ b/external/flint-2.4.3/fq_mat_templates/solve_triu.c @@ -0,0 +1,49 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010,2011 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +TEMPLATE(T, mat_solve_triu) (TEMPLATE(T, mat_t) X, const TEMPLATE(T, mat_t) U, + const TEMPLATE(T, mat_t) B, int unit, + const TEMPLATE(T, ctx_t) ctx) +{ + if (B->r < TEMPLATE(CAP_T, MAT_SOLVE_TRI_ROWS_CUTOFF) || + B->c < TEMPLATE(CAP_T, MAT_SOLVE_TRI_COLS_CUTOFF)) + { + TEMPLATE(T, mat_solve_triu_classical) (X, U, B, unit, ctx); + } + else + { + TEMPLATE(T, mat_solve_triu_recursive) (X, U, B, unit, ctx); + } +} + + +#endif diff --git a/external/flint-2.4.3/fq_mat_templates/solve_triu_classical.c b/external/flint-2.4.3/fq_mat_templates/solve_triu_classical.c new file mode 100644 index 0000000..7e032db --- /dev/null +++ b/external/flint-2.4.3/fq_mat_templates/solve_triu_classical.c @@ -0,0 +1,83 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010,2011 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +TEMPLATE(T, mat_solve_triu_classical) (TEMPLATE(T, mat_t) X, + const TEMPLATE(T, mat_t) U, + const TEMPLATE(T, mat_t) B, + int unit, const TEMPLATE(T, ctx_t) ctx) +{ + slong i, j, n, m; + TEMPLATE(T, struct) * inv, *tmp; + + n = U->r; + m = B->c; + + if (!unit) + { + inv = _TEMPLATE(T, vec_init) (n, ctx); + for (i = 0; i < n; i++) + TEMPLATE(T, inv) (inv + i, TEMPLATE(T, mat_entry) (U, i, i), ctx); + } + else + inv = NULL; + + tmp = _TEMPLATE(T, vec_init) (n, ctx); + + for (i = 0; i < m; i++) + { + for (j = 0; j < n; j++) + TEMPLATE(T, set) (tmp + j, TEMPLATE(T, mat_entry) (X, j, i), ctx); + + for (j = n - 1; j >= 0; j--) + { + TEMPLATE(T, t) s; + TEMPLATE(T, init) (s, ctx); + _TEMPLATE(T, vec_dot) (s, U->rows[j] + j + 1, tmp + j + 1, + n - j - 1, ctx); + TEMPLATE(T, sub) (s, TEMPLATE(T, mat_entry) (B, j, i), s, ctx); + if (!unit) + TEMPLATE(T, mul) (s, s, inv + j, ctx); + TEMPLATE(T, set) (tmp + j, s, ctx); + TEMPLATE(T, clear) (s, ctx); + } + + for (j = 0; j < n; j++) + TEMPLATE(T, mat_entry_set) (X, j, i, tmp + j, ctx); + } + + _TEMPLATE(T, vec_clear) (tmp, n, ctx); + if (!unit) + _TEMPLATE(T, vec_clear) (inv, n, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_mat_templates/solve_triu_recursive.c b/external/flint-2.4.3/fq_mat_templates/solve_triu_recursive.c new file mode 100644 index 0000000..ab31ec9 --- /dev/null +++ b/external/flint-2.4.3/fq_mat_templates/solve_triu_recursive.c @@ -0,0 +1,77 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010,2011 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +TEMPLATE(T, mat_solve_triu_recursive) (TEMPLATE(T, mat_t) X, + const TEMPLATE(T, mat_t) U, + const TEMPLATE(T, mat_t) B, + int unit, const TEMPLATE(T, ctx_t) ctx) +{ + TEMPLATE(T, mat_t) UA, UB, UD, XX, XY, BX, BY; + slong r, n, m; + + n = U->r; + m = B->c; + r = n / 2; + + if (n == 0 || m == 0) + return; + + /* + Denoting inv(M) by M^, we have: + + [A B]^ [X] == [A^ (X - B D^ Y)] + [0 D] [Y] == [ D^ Y ] + */ + + TEMPLATE(T, mat_window_init) (UA, U, 0, 0, r, r, ctx); + TEMPLATE(T, mat_window_init) (UB, U, 0, r, r, n, ctx); + TEMPLATE(T, mat_window_init) (UD, U, r, r, n, n, ctx); + TEMPLATE(T, mat_window_init) (BX, B, 0, 0, r, m, ctx); + TEMPLATE(T, mat_window_init) (BY, B, r, 0, n, m, ctx); + TEMPLATE(T, mat_window_init) (XX, X, 0, 0, r, m, ctx); + TEMPLATE(T, mat_window_init) (XY, X, r, 0, n, m, ctx); + + TEMPLATE(T, mat_solve_triu) (XY, UD, BY, unit, ctx); + TEMPLATE(T, mat_submul) (XX, BX, UB, XY, ctx); + TEMPLATE(T, mat_solve_triu) (XX, UA, XX, unit, ctx); + + TEMPLATE(T, mat_window_clear) (UA, ctx); + TEMPLATE(T, mat_window_clear) (UB, ctx); + TEMPLATE(T, mat_window_clear) (UD, ctx); + TEMPLATE(T, mat_window_clear) (BX, ctx); + TEMPLATE(T, mat_window_clear) (BY, ctx); + TEMPLATE(T, mat_window_clear) (XX, ctx); + TEMPLATE(T, mat_window_clear) (XY, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_mat_templates/sub.c b/external/flint-2.4.3/fq_mat_templates/sub.c new file mode 100644 index 0000000..2f228c0 --- /dev/null +++ b/external/flint-2.4.3/fq_mat_templates/sub.c @@ -0,0 +1,49 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +TEMPLATE(T, mat_sub) (TEMPLATE(T, mat_t) res, + const TEMPLATE(T, mat_t) mat1, + const TEMPLATE(T, mat_t) mat2, + const TEMPLATE(T, ctx_t) ctx) +{ + slong i; + + if (res->c < 1) + return; + + for (i = 0; i < res->r; i++) + _TEMPLATE(T, vec_sub) (res->rows[i], mat1->rows[i], mat2->rows[i], + res->c, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_mat_templates/submul.c b/external/flint-2.4.3/fq_mat_templates/submul.c new file mode 100644 index 0000000..447aae2 --- /dev/null +++ b/external/flint-2.4.3/fq_mat_templates/submul.c @@ -0,0 +1,47 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +TEMPLATE(T, mat_submul) (TEMPLATE(T, mat_t) D, + const TEMPLATE(T, mat_t) C, + const TEMPLATE(T, mat_t) A, + const TEMPLATE(T, mat_t) B, + const TEMPLATE(T, ctx_t) ctx) +{ + TEMPLATE(T, mat_t) tmp; + TEMPLATE(T, mat_init) (tmp, A->r, B->c, ctx); + TEMPLATE(T, mat_mul) (tmp, A, B, ctx); + TEMPLATE(T, mat_sub) (D, C, tmp, ctx); + TEMPLATE(T, mat_clear) (tmp, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_mat_templates/swap.c b/external/flint-2.4.3/fq_mat_templates/swap.c new file mode 100644 index 0000000..52dacbf --- /dev/null +++ b/external/flint-2.4.3/fq_mat_templates/swap.c @@ -0,0 +1,47 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +TEMPLATE(T, mat_swap) (TEMPLATE(T, mat_t) mat1, TEMPLATE(T, mat_t) mat2, + const TEMPLATE(T, ctx_t) ctx) +{ + if (mat1 != mat2) + { + TEMPLATE(T, mat_struct) tmp; + + tmp = *mat1; + *mat1 = *mat2; + *mat2 = tmp; + } +} + + +#endif diff --git a/external/flint-2.4.3/fq_mat_templates/test/t-add_sub.c b/external/flint-2.4.3/fq_mat_templates/test/t-add_sub.c new file mode 100644 index 0000000..d0e3bba --- /dev/null +++ b/external/flint-2.4.3/fq_mat_templates/test/t-add_sub.c @@ -0,0 +1,88 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include "ulong_extras.h" + +int +main(void) +{ + slong m, n, rep; + FLINT_TEST_INIT(state); + + printf("add/sub/neg...."); + fflush(stdout); + + for (rep = 0; rep < 500; rep++) + { + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, mat_t) A; + TEMPLATE(T, mat_t) B; + TEMPLATE(T, mat_t) C; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + m = n_randint(state, 20); + n = n_randint(state, 20); + + TEMPLATE(T, mat_init) (A, m, n, ctx); + TEMPLATE(T, mat_init) (B, m, n, ctx); + TEMPLATE(T, mat_init) (C, m, n, ctx); + + TEMPLATE(T, mat_randtest) (A, state, ctx); + TEMPLATE(T, mat_randtest) (B, state, ctx); + + TEMPLATE(T, mat_neg) (C, A, ctx); + TEMPLATE(T, mat_add) (A, A, B, ctx); + TEMPLATE(T, mat_sub) (A, A, B, ctx); + TEMPLATE(T, mat_neg) (A, A, ctx); + + if (!TEMPLATE(T, mat_equal) (A, C, ctx)) + { + printf("FAIL: matrices not equal!\n"); + abort(); + } + + TEMPLATE(T, mat_clear) (A, ctx); + TEMPLATE(T, mat_clear) (B, ctx); + TEMPLATE(T, mat_clear) (C, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_mat_templates/test/t-equal.c b/external/flint-2.4.3/fq_mat_templates/test/t-equal.c new file mode 100644 index 0000000..6c574d7 --- /dev/null +++ b/external/flint-2.4.3/fq_mat_templates/test/t-equal.c @@ -0,0 +1,113 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + printf("equal...."); + fflush(stdout); + + for (i = 0; i < 100; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, mat_t) A, B, C, D, E; + TEMPLATE(T, t) x; + slong m, n, j; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, init) (x, ctx); + + m = n_randint(state, 20); + n = n_randint(state, 20); + + TEMPLATE(T, mat_init) (A, m, n, ctx); + TEMPLATE(T, mat_init) (B, m, n, ctx); + TEMPLATE(T, mat_init) (C, m, n, ctx); + TEMPLATE(T, mat_init) (D, m + 1, n, ctx); + TEMPLATE(T, mat_init) (E, m, n + 1, ctx); + + if (TEMPLATE(T, mat_equal) (A, D, ctx) + || TEMPLATE(T, mat_equal) (A, E, ctx)) + { + printf("FAIL: different dimensions should not be equal\n"); + abort(); + } + + TEMPLATE(T, mat_randtest) (A, state, ctx); + TEMPLATE(T, mat_set) (B, A, ctx); + + if (!TEMPLATE(T, mat_equal) (A, B, ctx)) + { + printf("FAIL: copied matrices should be equal\n"); + abort(); + } + + if (m && n) + { + j = n_randint(state, m * n); + TEMPLATE(T, one) (x, ctx); + TEMPLATE(T, add) (A->entries + j, A->entries + j, x, ctx); + + if (TEMPLATE(T, mat_equal) (A, B, ctx)) + { + printf("FAIL: modified matrices should not be equal\n"); + abort(); + } + } + + TEMPLATE(T, clear) (x, ctx); + TEMPLATE(T, mat_clear) (A, ctx); + TEMPLATE(T, mat_clear) (B, ctx); + TEMPLATE(T, mat_clear) (C, ctx); + TEMPLATE(T, mat_clear) (D, ctx); + TEMPLATE(T, mat_clear) (E, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_mat_templates/test/t-is_zero.c b/external/flint-2.4.3/fq_mat_templates/test/t-is_zero.c new file mode 100644 index 0000000..4434d2d --- /dev/null +++ b/external/flint-2.4.3/fq_mat_templates/test/t-is_zero.c @@ -0,0 +1,90 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include "ulong_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + printf("is_zero...."); + fflush(stdout); + + for (i = 0; i < 100; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, mat_t) A; + TEMPLATE(T, t) x; + slong j; + + slong rows = n_randint(state, 10); + slong cols = n_randint(state, 10); + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, mat_init) (A, rows, cols, ctx); + + if (!TEMPLATE(T, mat_is_zero) (A, ctx)) + { + printf("FAIL!\n"); + abort(); + } + + TEMPLATE(T, init) (x, ctx); + TEMPLATE(T, randtest_not_zero) (x, state, ctx); + + if (rows && cols) + { + j = n_randint(state, rows * cols); + TEMPLATE(T, add) (A->entries + j, A->entries + j, x, ctx); + + if (TEMPLATE(T, mat_is_zero) (A, ctx)) + { + printf("FAIL!\n"); + abort(); + } + } + + TEMPLATE(T, clear) (x, ctx); + TEMPLATE(T, mat_clear) (A, ctx); + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_mat_templates/test/t-lu_classical.c b/external/flint-2.4.3/fq_mat_templates/test/t-lu_classical.c new file mode 100644 index 0000000..749000d --- /dev/null +++ b/external/flint-2.4.3/fq_mat_templates/test/t-lu_classical.c @@ -0,0 +1,185 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include +#include "ulong_extras.h" + +void +perm(TEMPLATE(T, mat_t) A, slong * P) +{ + slong i; + TEMPLATE(T, struct) ** tmp; + + if (A->c == 0 || A->r == 0) + return; + + tmp = flint_malloc(sizeof(TEMPLATE(T, struct) *) * A->r); + + for (i = 0; i < A->r; i++) + tmp[P[i]] = A->rows[i]; + for (i = 0; i < A->r; i++) + A->rows[i] = tmp[i]; + + flint_free(tmp); +} + +void +check(slong * P, TEMPLATE(T, mat_t) LU, const TEMPLATE(T, mat_t) A, slong rank, + const TEMPLATE(T, ctx_t) ctx) +{ + TEMPLATE(T, mat_t) B, L, U; + slong m, n, i, j; + + m = A->r; + n = A->c; + + TEMPLATE(T, mat_init) (B, m, n, ctx); + TEMPLATE(T, mat_init) (L, m, m, ctx); + TEMPLATE(T, mat_init) (U, m, n, ctx); + + rank = FLINT_ABS(rank); + + for (i = rank; i < FLINT_MIN(m, n); i++) + { + for (j = i; j < n; j++) + { + if (!TEMPLATE(T, is_zero) (TEMPLATE(T, mat_entry) (LU, i, j), ctx)) + { + printf("FAIL: wrong shape!\n"); + abort(); + } + } + } + + for (i = 0; i < m; i++) + { + for (j = 0; j < FLINT_MIN(i, n); j++) + TEMPLATE(T, mat_entry_set) (L, i, j, + TEMPLATE(T, mat_entry) (LU, i, j), + ctx); + if (i < rank) + TEMPLATE(T, one) (TEMPLATE(T, mat_entry) (L, i, i), ctx); + for (j = i; j < n; j++) + TEMPLATE(T, mat_entry_set) (U, i, j, + TEMPLATE(T, mat_entry) (LU, i, j), + ctx); + } + + TEMPLATE(T, mat_mul) (B, L, U, ctx); + perm(B, P); + + if (!TEMPLATE(T, mat_equal) (A, B, ctx)) + { + printf("FAIL\n"); + printf("A:\n"); + TEMPLATE(T, mat_print_pretty) (A, ctx); + printf("LU:\n"); + TEMPLATE(T, mat_print_pretty) (LU, ctx); + printf("B:\n"); + TEMPLATE(T, mat_print_pretty) (B, ctx); + abort(); + } + + TEMPLATE(T, mat_clear) (B, ctx); + TEMPLATE(T, mat_clear) (L, ctx); + TEMPLATE(T, mat_clear) (U, ctx); +} + + + +int +main(void) +{ + slong i; + FLINT_TEST_INIT(state); + + printf("lu_classical...."); + fflush(stdout); + + for (i = 0; i < 100; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, mat_t) A, LU; + + slong m, n, r, d, rank; + slong *P; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + m = n_randint(state, 20); + n = n_randint(state, 20); + + for (r = 0; r <= FLINT_MIN(m, n); r++) + { + TEMPLATE(T, mat_init) (A, m, n, ctx); + TEMPLATE(T, mat_randrank) (A, state, r, ctx); + + if (n_randint(state, 2)) + { + d = n_randint(state, 2 * m * n + 1); + TEMPLATE(T, mat_randops) (A, d, state, ctx); + } + + TEMPLATE(T, mat_init_set) (LU, A, ctx); + P = flint_malloc(sizeof(slong) * m); + + rank = TEMPLATE(T, mat_lu_classical) (P, LU, 0, ctx); + + if (r != rank) + { + printf("FAIL:\n"); + printf("wrong rank!\n"); + printf("A:"); + TEMPLATE(T, mat_print_pretty) (A, ctx); + printf("LU:"); + TEMPLATE(T, mat_print_pretty) (LU, ctx); + abort(); + } + + check(P, LU, A, rank, ctx); + + TEMPLATE(T, mat_clear) (A, ctx); + TEMPLATE(T, mat_clear) (LU, ctx); + flint_free(P); + + } + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_mat_templates/test/t-lu_recursive.c b/external/flint-2.4.3/fq_mat_templates/test/t-lu_recursive.c new file mode 100644 index 0000000..e17ae27 --- /dev/null +++ b/external/flint-2.4.3/fq_mat_templates/test/t-lu_recursive.c @@ -0,0 +1,184 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include +#include "ulong_extras.h" + +void +perm(TEMPLATE(T, mat_t) A, slong * P) +{ + slong i; + TEMPLATE(T, struct) ** tmp; + + if (A->c == 0 || A->r == 0) + return; + + tmp = flint_malloc(sizeof(TEMPLATE(T, struct) *) * A->r); + + for (i = 0; i < A->r; i++) + tmp[P[i]] = A->rows[i]; + for (i = 0; i < A->r; i++) + A->rows[i] = tmp[i]; + + flint_free(tmp); +} + + +void +check(slong * P, TEMPLATE(T, mat_t) LU, const TEMPLATE(T, mat_t) A, slong rank, + const TEMPLATE(T, ctx_t) ctx) +{ + TEMPLATE(T, mat_t) B, L, U; + slong m, n, i, j; + + m = A->r; + n = A->c; + + TEMPLATE(T, mat_init) (B, m, n, ctx); + TEMPLATE(T, mat_init) (L, m, m, ctx); + TEMPLATE(T, mat_init) (U, m, n, ctx); + + rank = FLINT_ABS(rank); + + for (i = rank; i < FLINT_MIN(m, n); i++) + { + for (j = i; j < n; j++) + { + if (!TEMPLATE(T, is_zero) (TEMPLATE(T, mat_entry) (LU, i, j), ctx)) + { + printf("FAIL: wrong shape!\n"); + abort(); + } + } + } + + for (i = 0; i < m; i++) + { + for (j = 0; j < FLINT_MIN(i, n); j++) + TEMPLATE(T, mat_entry_set) (L, i, j, + TEMPLATE(T, mat_entry) (LU, i, j), + ctx); + if (i < rank) + TEMPLATE(T, one) (TEMPLATE(T, mat_entry) (L, i, i), ctx); + for (j = i; j < n; j++) + TEMPLATE(T, mat_entry_set) (U, i, j, + TEMPLATE(T, mat_entry) (LU, i, j), + ctx); + } + + TEMPLATE(T, mat_mul) (B, L, U, ctx); + perm(B, P); + + if (!TEMPLATE(T, mat_equal) (A, B, ctx)) + { + printf("FAIL\n"); + printf("A:\n"); + TEMPLATE(T, mat_print_pretty) (A, ctx); + printf("LU:\n"); + TEMPLATE(T, mat_print_pretty) (LU, ctx); + printf("B:\n"); + TEMPLATE(T, mat_print_pretty) (B, ctx); + abort(); + } + + TEMPLATE(T, mat_clear) (B, ctx); + TEMPLATE(T, mat_clear) (L, ctx); + TEMPLATE(T, mat_clear) (U, ctx); +} + + +int +main(void) +{ + slong i; + FLINT_TEST_INIT(state); + + printf("lu_recursive...."); + fflush(stdout); + + for (i = 0; i < 100; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, mat_t) A, LU; + + slong m, n, r, d, rank; + slong *P; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + m = n_randint(state, 20); + n = n_randint(state, 20); + + for (r = 0; r <= FLINT_MIN(m, n); r++) + { + TEMPLATE(T, mat_init) (A, m, n, ctx); + TEMPLATE(T, mat_randrank) (A, state, r, ctx); + + if (n_randint(state, 2)) + { + d = n_randint(state, 2 * m * n + 1); + TEMPLATE(T, mat_randops) (A, d, state, ctx); + } + + TEMPLATE(T, mat_init_set) (LU, A, ctx); + P = flint_malloc(sizeof(slong) * m); + + rank = TEMPLATE(T, mat_lu_recursive) (P, LU, 0, ctx); + + if (r != rank) + { + printf("FAIL:\n"); + printf("wrong rank!\n"); + printf("A:"); + TEMPLATE(T, mat_print_pretty) (A, ctx); + printf("LU:"); + TEMPLATE(T, mat_print_pretty) (LU, ctx); + abort(); + } + + check(P, LU, A, rank, ctx); + + TEMPLATE(T, mat_clear) (A, ctx); + TEMPLATE(T, mat_clear) (LU, ctx); + flint_free(P); + } + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_mat_templates/test/t-mul.c b/external/flint-2.4.3/fq_mat_templates/test/t-mul.c new file mode 100644 index 0000000..8d6cb1b --- /dev/null +++ b/external/flint-2.4.3/fq_mat_templates/test/t-mul.c @@ -0,0 +1,135 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include + +int +main(void) +{ + slong i; + FLINT_TEST_INIT(state); + + printf("mul...."); + fflush(stdout); + + /* Check aliasing C and A */ + for (i = 0; i < 100; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, mat_t) A, B, C; + slong m, n; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + m = n_randint(state, 20); + n = n_randint(state, 20); + + TEMPLATE(T, mat_init) (A, m, n, ctx); + TEMPLATE(T, mat_init) (B, n, n, ctx); + TEMPLATE(T, mat_init) (C, m, n, ctx); + + TEMPLATE(T, mat_randtest) (A, state, ctx); + TEMPLATE(T, mat_randtest) (B, state, ctx); + TEMPLATE(T, mat_randtest) (C, state, ctx); /* noise in output */ + + TEMPLATE(T, mat_mul) (C, A, B, ctx); + TEMPLATE(T, mat_mul) (A, A, B, ctx); + + if (!TEMPLATE(T, mat_equal) (C, A, ctx)) + { + printf("FAIL:\n"); + printf("A:\n"); + TEMPLATE(T, mat_print) (A, ctx); + printf("B:\n"); + TEMPLATE(T, mat_print) (B, ctx); + printf("C:\n"); + TEMPLATE(T, mat_print) (C, ctx); + printf("\n"); + abort(); + } + + TEMPLATE(T, mat_clear) (A, ctx); + TEMPLATE(T, mat_clear) (B, ctx); + TEMPLATE(T, mat_clear) (C, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check aliasing C and B */ + for (i = 0; i < 100; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, mat_t) A, B, C; + slong m, n; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + m = n_randint(state, 20); + n = n_randint(state, 20); + + TEMPLATE(T, mat_init) (A, m, m, ctx); + TEMPLATE(T, mat_init) (B, m, n, ctx); + TEMPLATE(T, mat_init) (C, m, n, ctx); + + TEMPLATE(T, mat_randtest) (A, state, ctx); + TEMPLATE(T, mat_randtest) (B, state, ctx); + TEMPLATE(T, mat_randtest) (C, state, ctx); /* noise in output */ + + TEMPLATE(T, mat_mul) (C, A, B, ctx); + TEMPLATE(T, mat_mul) (B, A, B, ctx); + + if (!TEMPLATE(T, mat_equal) (C, B, ctx)) + { + printf("FAIL:\n"); + printf("A:\n"); + TEMPLATE(T, mat_print) (A, ctx); + printf("B:\n"); + TEMPLATE(T, mat_print) (B, ctx); + printf("C:\n"); + TEMPLATE(T, mat_print) (C, ctx); + printf("\n"); + abort(); + } + + TEMPLATE(T, mat_clear) (A, ctx); + TEMPLATE(T, mat_clear) (B, ctx); + TEMPLATE(T, mat_clear) (C, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_mat_templates/test/t-mul_KS.c b/external/flint-2.4.3/fq_mat_templates/test/t-mul_KS.c new file mode 100644 index 0000000..ddb4907 --- /dev/null +++ b/external/flint-2.4.3/fq_mat_templates/test/t-mul_KS.c @@ -0,0 +1,135 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include + +int +main(void) +{ + slong i; + FLINT_TEST_INIT(state); + + printf("mul_KS...."); + fflush(stdout); + + /* Check aliasing C and A */ + for (i = 0; i < 100; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, mat_t) A, B, C; + slong m, n; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + m = n_randint(state, 50); + n = n_randint(state, 50); + + TEMPLATE(T, mat_init) (A, m, n, ctx); + TEMPLATE(T, mat_init) (B, n, n, ctx); + TEMPLATE(T, mat_init) (C, m, n, ctx); + + TEMPLATE(T, mat_randtest) (A, state, ctx); + TEMPLATE(T, mat_randtest) (B, state, ctx); + TEMPLATE(T, mat_randtest) (C, state, ctx); /* noise in output */ + + TEMPLATE(T, mat_mul_KS) (C, A, B, ctx); + TEMPLATE(T, mat_mul_KS) (A, A, B, ctx); + + if (!TEMPLATE(T, mat_equal) (C, A, ctx)) + { + printf("FAIL:\n"); + printf("A:\n"); + TEMPLATE(T, mat_print) (A, ctx); + printf("B:\n"); + TEMPLATE(T, mat_print) (B, ctx); + printf("C:\n"); + TEMPLATE(T, mat_print) (C, ctx); + printf("\n"); + abort(); + } + + TEMPLATE(T, mat_clear) (A, ctx); + TEMPLATE(T, mat_clear) (B, ctx); + TEMPLATE(T, mat_clear) (C, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check aliasing C and B */ + for (i = 0; i < 100; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, mat_t) A, B, C; + slong m, n; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + m = n_randint(state, 50); + n = n_randint(state, 50); + + TEMPLATE(T, mat_init) (A, m, m, ctx); + TEMPLATE(T, mat_init) (B, m, n, ctx); + TEMPLATE(T, mat_init) (C, m, n, ctx); + + TEMPLATE(T, mat_randtest) (A, state, ctx); + TEMPLATE(T, mat_randtest) (B, state, ctx); + TEMPLATE(T, mat_randtest) (C, state, ctx); /* noise in output */ + + TEMPLATE(T, mat_mul_KS) (C, A, B, ctx); + TEMPLATE(T, mat_mul_KS) (B, A, B, ctx); + + if (!TEMPLATE(T, mat_equal) (C, B, ctx)) + { + printf("FAIL:\n"); + printf("A:\n"); + TEMPLATE(T, mat_print) (A, ctx); + printf("B:\n"); + TEMPLATE(T, mat_print) (B, ctx); + printf("C:\n"); + TEMPLATE(T, mat_print) (C, ctx); + printf("\n"); + abort(); + } + + TEMPLATE(T, mat_clear) (A, ctx); + TEMPLATE(T, mat_clear) (B, ctx); + TEMPLATE(T, mat_clear) (C, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_mat_templates/test/t-rref.c b/external/flint-2.4.3/fq_mat_templates/test/t-rref.c new file mode 100644 index 0000000..c412f23 --- /dev/null +++ b/external/flint-2.4.3/fq_mat_templates/test/t-rref.c @@ -0,0 +1,210 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include +#include +#include "perm.h" +#include "flint.h" + +int +check_rref_form(slong * perm, TEMPLATE(T, mat_t) A, slong rank, + const TEMPLATE(T, ctx_t) ctx) +{ + slong i, j, k, prev_pivot; + + /* bottom should be zero */ + for (i = rank; i < A->r; i++) + for (j = 0; j < A->c; j++) + if (!TEMPLATE(T, is_zero) (TEMPLATE(T, mat_entry) (A, i, j), ctx)) + return 0; + + prev_pivot = -1; + + for (i = 0; i < rank; i++) + { + for (j = 0; j < A->c; j++) + { + if (!TEMPLATE(T, is_zero) (TEMPLATE(T, mat_entry) (A, i, j), ctx)) + { + /* pivot should have a higher column index than previous */ + if (j <= prev_pivot) + return 0; + + /* column should be 0 ... 0 1 0 ... 0 */ + for (k = 0; k < rank; k++) + { + if (i == k) + { + if (!TEMPLATE(T, is_one) + (TEMPLATE(T, mat_entry) (A, k, j), ctx)) + return 0; + } + else + { + if (!TEMPLATE(T, is_zero) + (TEMPLATE(T, mat_entry) (A, k, j), ctx)) + return 0; + } + } + + prev_pivot = j; + break; + } + } + } + + return 1; +} + +int +main(void) +{ + slong i; + FLINT_TEST_INIT(state); + + printf("rref...."); + fflush(stdout); + + for (i = 0; i < 100; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, mat_t) A, B, C, D; + TEMPLATE(T, t) c; + slong j, k, m, n, rank1, rank2; + slong *perm; + int equal; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, init) (c, ctx); + + m = n_randint(state, 20); + n = n_randint(state, 20); + perm = _perm_init(2 * m); + + TEMPLATE(T, mat_init) (A, m, n, ctx); + TEMPLATE(T, mat_init) (D, 2 * m, n, ctx); + + TEMPLATE(T, mat_randtest) (A, state, ctx); + TEMPLATE(T, mat_init_set) (B, A, ctx); + TEMPLATE(T, mat_init_set) (C, A, ctx); + + rank1 = TEMPLATE(T, mat_rref) (B, ctx); + + if (!check_rref_form(perm, B, rank1, ctx)) + { + printf("FAIL (malformed rref)\n"); + TEMPLATE(T, mat_print_pretty) (A, ctx); + printf("\n\n"); + TEMPLATE(T, mat_print_pretty) (B, ctx); + printf("\n\n"); + abort(); + } + + /* Concatenate the original matrix with the rref, scramble the rows, + and check that the rref is the same */ + _perm_randtest(perm, 2 * m, state); + + for (j = 0; j < m; j++) + { + TEMPLATE(T, randtest_not_zero) (c, state, ctx); + for (k = 0; k < n; k++) + { + TEMPLATE(T, mul) (TEMPLATE(T, mat_entry) (D, perm[j], k), + TEMPLATE(T, mat_entry) (A, j, k), c, ctx); + } + } + + for (j = 0; j < m; j++) + { + TEMPLATE(T, randtest_not_zero) (c, state, ctx); + for (k = 0; k < n; k++) + { + TEMPLATE(T, mul) (TEMPLATE(T, mat_entry) (D, perm[m + j], k), + TEMPLATE(T, mat_entry) (B, j, k), c, ctx); + + } + } + + rank2 = TEMPLATE(T, mat_rref) (D, ctx); + equal = (rank1 == rank2); + + if (equal) + { + for (j = 0; j < rank2; j++) + for (k = 0; k < n; k++) + { + equal = equal + && TEMPLATE(T, + equal) (TEMPLATE(T, mat_entry) (B, j, k), + TEMPLATE(T, mat_entry) (D, j, k), + ctx); + } + for (j = rank2; j < 2 * rank2; j++) + for (k = 0; k < n; k++) + { + equal = equal + && TEMPLATE(T, + is_zero) (TEMPLATE(T, mat_entry) (D, j, k), + ctx); + } + } + + if (!equal) + { + flint_printf("FAIL (rank1 = %wd, rank2 = %wd)!\n", rank1, rank2); + TEMPLATE(T, mat_print_pretty) (A, ctx); + printf("\n\n"); + TEMPLATE(T, mat_print_pretty) (B, ctx); + printf("\n\n"); + TEMPLATE(T, mat_print_pretty) (D, ctx); + printf("\n\n"); + abort(); + } + + _perm_clear(perm); + TEMPLATE(T, mat_clear) (A, ctx); + TEMPLATE(T, mat_clear) (B, ctx); + TEMPLATE(T, mat_clear) (C, ctx); + TEMPLATE(T, mat_clear) (D, ctx); + + TEMPLATE(T, clear) (c, ctx); + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_mat_templates/test/t-solve_tril.c b/external/flint-2.4.3/fq_mat_templates/test/t-solve_tril.c new file mode 100644 index 0000000..ce89c3d --- /dev/null +++ b/external/flint-2.4.3/fq_mat_templates/test/t-solve_tril.c @@ -0,0 +1,111 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010,2011 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include +#include + +int +main(void) +{ + slong i; + FLINT_TEST_INIT(state); + + printf("solve_tril...."); + fflush(stdout); + + for (i = 0; i < 5 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, mat_t) A, X, B, Y; + + slong rows, cols; + int unit; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + rows = n_randint(state, 50); + cols = n_randint(state, 50); + unit = n_randint(state, 2); + + TEMPLATE(T, mat_init) (A, rows, rows, ctx); + TEMPLATE(T, mat_init) (B, rows, cols, ctx); + TEMPLATE(T, mat_init) (X, rows, cols, ctx); + TEMPLATE(T, mat_init) (Y, rows, cols, ctx); + + TEMPLATE(T, mat_randtril) (A, state, unit, ctx); + TEMPLATE(T, mat_randtest) (X, state, ctx); + TEMPLATE(T, mat_mul) (B, A, X, ctx); + + /* Check Y = A^(-1) * (A * X) = X */ + TEMPLATE(T, mat_solve_tril) (Y, A, B, unit, ctx); + if (!TEMPLATE(T, mat_equal) (Y, X, ctx)) + { + printf("FAIL!\n"); + printf("A:\n"); + TEMPLATE(T, mat_print_pretty) (A, ctx); + printf("X:\n"); + TEMPLATE(T, mat_print_pretty) (X, ctx); + printf("B:\n"); + TEMPLATE(T, mat_print_pretty) (B, ctx); + printf("Y:\n"); + TEMPLATE(T, mat_print_pretty) (Y, ctx); + abort(); + } + + /* Check aliasing */ + TEMPLATE(T, mat_solve_tril) (B, A, B, unit, ctx); + if (!TEMPLATE(T, mat_equal) (B, X, ctx)) + { + printf("FAIL!\n"); + printf("aliasing test failed"); + printf("A:\n"); + TEMPLATE(T, mat_print_pretty) (A, ctx); + printf("B:\n"); + TEMPLATE(T, mat_print_pretty) (B, ctx); + abort(); + } + + TEMPLATE(T, mat_clear) (A, ctx); + TEMPLATE(T, mat_clear) (B, ctx); + TEMPLATE(T, mat_clear) (X, ctx); + TEMPLATE(T, mat_clear) (Y, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_mat_templates/test/t-solve_tril_classical.c b/external/flint-2.4.3/fq_mat_templates/test/t-solve_tril_classical.c new file mode 100644 index 0000000..b348665 --- /dev/null +++ b/external/flint-2.4.3/fq_mat_templates/test/t-solve_tril_classical.c @@ -0,0 +1,110 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010,2011 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include +#include + +int +main(void) +{ + slong i; + FLINT_TEST_INIT(state); + + printf("solve_tril_classical...."); + fflush(stdout); + + for (i = 0; i < 5 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, mat_t) A, X, B, Y; + + slong rows, cols; + int unit; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + rows = n_randint(state, 50); + cols = n_randint(state, 50); + unit = n_randint(state, 2); + + TEMPLATE(T, mat_init) (A, rows, rows, ctx); + TEMPLATE(T, mat_init) (B, rows, cols, ctx); + TEMPLATE(T, mat_init) (X, rows, cols, ctx); + TEMPLATE(T, mat_init) (Y, rows, cols, ctx); + + TEMPLATE(T, mat_randtril) (A, state, unit, ctx); + TEMPLATE(T, mat_randtest) (X, state, ctx); + TEMPLATE(T, mat_mul) (B, A, X, ctx); + + /* Check Y = A^(-1) * (A * X) = X */ + TEMPLATE(T, mat_solve_tril_classical) (Y, A, B, unit, ctx); + if (!TEMPLATE(T, mat_equal) (Y, X, ctx)) + { + printf("FAIL!\n"); + printf("A:\n"); + TEMPLATE(T, mat_print_pretty) (A, ctx); + printf("X:\n"); + TEMPLATE(T, mat_print_pretty) (X, ctx); + printf("B:\n"); + TEMPLATE(T, mat_print_pretty) (B, ctx); + printf("Y:\n"); + TEMPLATE(T, mat_print_pretty) (Y, ctx); + abort(); + } + + /* Check aliasing */ + TEMPLATE(T, mat_solve_tril_classical) (B, A, B, unit, ctx); + if (!TEMPLATE(T, mat_equal) (B, X, ctx)) + { + printf("FAIL!\n"); + printf("aliasing test failed"); + printf("A:\n"); + TEMPLATE(T, mat_print_pretty) (A, ctx); + printf("B:\n"); + TEMPLATE(T, mat_print_pretty) (B, ctx); + abort(); + } + + TEMPLATE(T, mat_clear) (A, ctx); + TEMPLATE(T, mat_clear) (B, ctx); + TEMPLATE(T, mat_clear) (X, ctx); + TEMPLATE(T, mat_clear) (Y, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + printf("PASS\n"); + return 0; +} + +#endif diff --git a/external/flint-2.4.3/fq_mat_templates/test/t-solve_tril_recursive.c b/external/flint-2.4.3/fq_mat_templates/test/t-solve_tril_recursive.c new file mode 100644 index 0000000..d5fe938 --- /dev/null +++ b/external/flint-2.4.3/fq_mat_templates/test/t-solve_tril_recursive.c @@ -0,0 +1,110 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010,2011 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include +#include + +int +main(void) +{ + slong i; + FLINT_TEST_INIT(state); + + printf("solve_tril_recursive...."); + fflush(stdout); + + for (i = 0; i < 5 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, mat_t) A, X, B, Y; + + slong rows, cols; + int unit; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + rows = n_randint(state, 50); + cols = n_randint(state, 50); + unit = n_randint(state, 2); + + TEMPLATE(T, mat_init) (A, rows, rows, ctx); + TEMPLATE(T, mat_init) (B, rows, cols, ctx); + TEMPLATE(T, mat_init) (X, rows, cols, ctx); + TEMPLATE(T, mat_init) (Y, rows, cols, ctx); + + TEMPLATE(T, mat_randtril) (A, state, unit, ctx); + TEMPLATE(T, mat_randtest) (X, state, ctx); + TEMPLATE(T, mat_mul) (B, A, X, ctx); + + /* Check Y = A^(-1) * (A * X) = X */ + TEMPLATE(T, mat_solve_tril_recursive) (Y, A, B, unit, ctx); + if (!TEMPLATE(T, mat_equal) (Y, X, ctx)) + { + printf("FAIL!\n"); + printf("A:\n"); + TEMPLATE(T, mat_print_pretty) (A, ctx); + printf("X:\n"); + TEMPLATE(T, mat_print_pretty) (X, ctx); + printf("B:\n"); + TEMPLATE(T, mat_print_pretty) (B, ctx); + printf("Y:\n"); + TEMPLATE(T, mat_print_pretty) (Y, ctx); + abort(); + } + + /* Check aliasing */ + TEMPLATE(T, mat_solve_tril_recursive) (B, A, B, unit, ctx); + if (!TEMPLATE(T, mat_equal) (B, X, ctx)) + { + printf("FAIL!\n"); + printf("aliasing test failed"); + printf("A:\n"); + TEMPLATE(T, mat_print_pretty) (A, ctx); + printf("B:\n"); + TEMPLATE(T, mat_print_pretty) (B, ctx); + abort(); + } + + TEMPLATE(T, mat_clear) (A, ctx); + TEMPLATE(T, mat_clear) (B, ctx); + TEMPLATE(T, mat_clear) (X, ctx); + TEMPLATE(T, mat_clear) (Y, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + printf("PASS\n"); + return 0; +} + +#endif diff --git a/external/flint-2.4.3/fq_mat_templates/test/t-solve_triu.c b/external/flint-2.4.3/fq_mat_templates/test/t-solve_triu.c new file mode 100644 index 0000000..ab7d30b --- /dev/null +++ b/external/flint-2.4.3/fq_mat_templates/test/t-solve_triu.c @@ -0,0 +1,110 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010,2011 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include +#include + +int +main(void) +{ + slong i; + FLINT_TEST_INIT(state); + + printf("solve_triu...."); + fflush(stdout); + + for (i = 0; i < 5 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, mat_t) A, X, B, Y; + slong rows, cols; + int unit; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + rows = n_randint(state, 50); + cols = n_randint(state, 50); + unit = n_randint(state, 2); + + TEMPLATE(T, mat_init) (A, rows, rows, ctx); + TEMPLATE(T, mat_init) (B, rows, cols, ctx); + TEMPLATE(T, mat_init) (X, rows, cols, ctx); + TEMPLATE(T, mat_init) (Y, rows, cols, ctx); + + TEMPLATE(T, mat_randtriu) (A, state, unit, ctx); + TEMPLATE(T, mat_randtest) (X, state, ctx); + TEMPLATE(T, mat_mul) (B, A, X, ctx); + + /* Check Y = A^(-1) * (A * X) = X */ + TEMPLATE(T, mat_solve_triu) (Y, A, B, unit, ctx); + if (!TEMPLATE(T, mat_equal) (Y, X, ctx)) + { + printf("FAIL!\n"); + printf("A:\n"); + TEMPLATE(T, mat_print_pretty) (A, ctx); + printf("X:\n"); + TEMPLATE(T, mat_print_pretty) (X, ctx); + printf("B:\n"); + TEMPLATE(T, mat_print_pretty) (B, ctx); + printf("Y:\n"); + TEMPLATE(T, mat_print_pretty) (Y, ctx); + abort(); + } + + /* Check aliasing */ + TEMPLATE(T, mat_solve_triu) (B, A, B, unit, ctx); + if (!TEMPLATE(T, mat_equal) (B, X, ctx)) + { + printf("FAIL!\n"); + printf("aliasing test failed"); + printf("A:\n"); + TEMPLATE(T, mat_print_pretty) (A, ctx); + printf("B:\n"); + TEMPLATE(T, mat_print_pretty) (B, ctx); + abort(); + } + + TEMPLATE(T, mat_clear) (A, ctx); + TEMPLATE(T, mat_clear) (B, ctx); + TEMPLATE(T, mat_clear) (X, ctx); + TEMPLATE(T, mat_clear) (Y, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_mat_templates/test/t-solve_triu_classical.c b/external/flint-2.4.3/fq_mat_templates/test/t-solve_triu_classical.c new file mode 100644 index 0000000..0d87f13 --- /dev/null +++ b/external/flint-2.4.3/fq_mat_templates/test/t-solve_triu_classical.c @@ -0,0 +1,110 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010,2011 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include +#include + +int +main(void) +{ + slong i; + FLINT_TEST_INIT(state); + + printf("solve_triu_classical...."); + fflush(stdout); + + for (i = 0; i < 5 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, mat_t) A, X, B, Y; + slong rows, cols; + int unit; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + rows = n_randint(state, 50); + cols = n_randint(state, 50); + unit = n_randint(state, 2); + + TEMPLATE(T, mat_init) (A, rows, rows, ctx); + TEMPLATE(T, mat_init) (B, rows, cols, ctx); + TEMPLATE(T, mat_init) (X, rows, cols, ctx); + TEMPLATE(T, mat_init) (Y, rows, cols, ctx); + + TEMPLATE(T, mat_randtriu) (A, state, unit, ctx); + TEMPLATE(T, mat_randtest) (X, state, ctx); + TEMPLATE(T, mat_mul) (B, A, X, ctx); + + /* Check Y = A^(-1) * (A * X) = X */ + TEMPLATE(T, mat_solve_triu_classical) (Y, A, B, unit, ctx); + if (!TEMPLATE(T, mat_equal) (Y, X, ctx)) + { + printf("FAIL!\n"); + printf("A:\n"); + TEMPLATE(T, mat_print_pretty) (A, ctx); + printf("X:\n"); + TEMPLATE(T, mat_print_pretty) (X, ctx); + printf("B:\n"); + TEMPLATE(T, mat_print_pretty) (B, ctx); + printf("Y:\n"); + TEMPLATE(T, mat_print_pretty) (Y, ctx); + abort(); + } + + /* Check aliasing */ + TEMPLATE(T, mat_solve_triu_classical) (B, A, B, unit, ctx); + if (!TEMPLATE(T, mat_equal) (B, X, ctx)) + { + printf("FAIL!\n"); + printf("aliasing test failed"); + printf("A:\n"); + TEMPLATE(T, mat_print_pretty) (A, ctx); + printf("B:\n"); + TEMPLATE(T, mat_print_pretty) (B, ctx); + abort(); + } + + TEMPLATE(T, mat_clear) (A, ctx); + TEMPLATE(T, mat_clear) (B, ctx); + TEMPLATE(T, mat_clear) (X, ctx); + TEMPLATE(T, mat_clear) (Y, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_mat_templates/test/t-solve_triu_recursive.c b/external/flint-2.4.3/fq_mat_templates/test/t-solve_triu_recursive.c new file mode 100644 index 0000000..7a71e0c --- /dev/null +++ b/external/flint-2.4.3/fq_mat_templates/test/t-solve_triu_recursive.c @@ -0,0 +1,110 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010,2011 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include +#include + +int +main(void) +{ + slong i; + FLINT_TEST_INIT(state); + + printf("solve_triu_recursive...."); + fflush(stdout); + + for (i = 0; i < 5 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, mat_t) A, X, B, Y; + slong rows, cols; + int unit; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + rows = n_randint(state, 50); + cols = n_randint(state, 50); + unit = n_randint(state, 2); + + TEMPLATE(T, mat_init) (A, rows, rows, ctx); + TEMPLATE(T, mat_init) (B, rows, cols, ctx); + TEMPLATE(T, mat_init) (X, rows, cols, ctx); + TEMPLATE(T, mat_init) (Y, rows, cols, ctx); + + TEMPLATE(T, mat_randtriu) (A, state, unit, ctx); + TEMPLATE(T, mat_randtest) (X, state, ctx); + TEMPLATE(T, mat_mul) (B, A, X, ctx); + + /* Check Y = A^(-1) * (A * X) = X */ + TEMPLATE(T, mat_solve_triu_recursive) (Y, A, B, unit, ctx); + if (!TEMPLATE(T, mat_equal) (Y, X, ctx)) + { + printf("FAIL!\n"); + printf("A:\n"); + TEMPLATE(T, mat_print_pretty) (A, ctx); + printf("X:\n"); + TEMPLATE(T, mat_print_pretty) (X, ctx); + printf("B:\n"); + TEMPLATE(T, mat_print_pretty) (B, ctx); + printf("Y:\n"); + TEMPLATE(T, mat_print_pretty) (Y, ctx); + abort(); + } + + /* Check aliasing */ + TEMPLATE(T, mat_solve_triu_recursive) (B, A, B, unit, ctx); + if (!TEMPLATE(T, mat_equal) (B, X, ctx)) + { + printf("FAIL!\n"); + printf("aliasing test failed"); + printf("A:\n"); + TEMPLATE(T, mat_print_pretty) (A, ctx); + printf("B:\n"); + TEMPLATE(T, mat_print_pretty) (B, ctx); + abort(); + } + + TEMPLATE(T, mat_clear) (A, ctx); + TEMPLATE(T, mat_clear) (B, ctx); + TEMPLATE(T, mat_clear) (X, ctx); + TEMPLATE(T, mat_clear) (Y, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_mat_templates/test/t-submul.c b/external/flint-2.4.3/fq_mat_templates/test/t-submul.c new file mode 100644 index 0000000..8b3c945 --- /dev/null +++ b/external/flint-2.4.3/fq_mat_templates/test/t-submul.c @@ -0,0 +1,115 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include +#include + +int +main(void) +{ + slong i; + FLINT_TEST_INIT(state); + + printf("submul...."); + fflush(stdout); + + for (i = 0; i < 2 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, mat_t) A, B, C, D, T, E; + + slong m, k, n; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + m = n_randint(state, 50); + k = n_randint(state, 50); + n = n_randint(state, 50); + + TEMPLATE(T, mat_init) (A, m, k, ctx); + TEMPLATE(T, mat_init) (B, k, n, ctx); + TEMPLATE(T, mat_init) (C, m, n, ctx); + TEMPLATE(T, mat_init) (D, m, n, ctx); + TEMPLATE(T, mat_init) (T, m, n, ctx); + TEMPLATE(T, mat_init) (E, m, n, ctx); + + TEMPLATE(T, mat_randtest) (A, state, ctx); + TEMPLATE(T, mat_randtest) (B, state, ctx); + TEMPLATE(T, mat_randtest) (C, state, ctx); + + TEMPLATE(T, mat_submul) (D, C, A, B, ctx); + + TEMPLATE(T, mat_mul) (T, A, B, ctx); + TEMPLATE(T, mat_sub) (E, C, T, ctx); + + if (!TEMPLATE(T, mat_equal) (D, E, ctx)) + { + printf("FAIL: results not equal\n"); + TEMPLATE(T, mat_print_pretty) (A, ctx); + TEMPLATE(T, mat_print_pretty) (B, ctx); + TEMPLATE(T, mat_print_pretty) (C, ctx); + TEMPLATE(T, mat_print_pretty) (D, ctx); + TEMPLATE(T, mat_print_pretty) (E, ctx); + abort(); + } + + /* Check aliasing */ + TEMPLATE(T, mat_submul) (C, C, A, B, ctx); + + if (!TEMPLATE(T, mat_equal) (C, E, ctx)) + { + printf("FAIL: results not equal (aliasing)\n"); + TEMPLATE(T, mat_print_pretty) (A, ctx); + TEMPLATE(T, mat_print_pretty) (B, ctx); + TEMPLATE(T, mat_print_pretty) (C, ctx); + TEMPLATE(T, mat_print_pretty) (D, ctx); + TEMPLATE(T, mat_print_pretty) (E, ctx); + abort(); + } + + TEMPLATE(T, mat_clear) (A, ctx); + TEMPLATE(T, mat_clear) (B, ctx); + TEMPLATE(T, mat_clear) (C, ctx); + TEMPLATE(T, mat_clear) (D, ctx); + TEMPLATE(T, mat_clear) (E, ctx); + TEMPLATE(T, mat_clear) (T, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_mat_templates/test/t-zero.c b/external/flint-2.4.3/fq_mat_templates/test/t-zero.c new file mode 100644 index 0000000..389b503 --- /dev/null +++ b/external/flint-2.4.3/fq_mat_templates/test/t-zero.c @@ -0,0 +1,88 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include + +int +main(void) +{ + int iter; + FLINT_TEST_INIT(state); + + printf("zero/is_zero...."); + fflush(stdout); + + for (iter = 0; iter < 100; iter++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, mat_t) A; + slong m, n; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + m = n_randint(state, 10); + n = n_randint(state, 10); + + TEMPLATE(T, mat_init) (A, m, n, ctx); + TEMPLATE(T, mat_randtest) (A, state, ctx); + TEMPLATE(T, mat_zero) (A, ctx); + + if (!TEMPLATE(T, mat_is_zero) (A, ctx)) + { + printf("FAIL: expected matrix to be zero\n"); + abort(); + } + + if (m > 0 && n > 0) + { + m = n_randint(state, m); + n = n_randint(state, n); + TEMPLATE(T, randtest_not_zero) (TEMPLATE(T, mat_entry) (A, m, n), + state, ctx); + + if (TEMPLATE(T, mat_is_zero) (A, ctx)) + { + printf("FAIL: expected matrix not to be zero\n"); + abort(); + } + } + + TEMPLATE(T, mat_clear) (A, ctx); + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_mat_templates/window_clear.c b/external/flint-2.4.3/fq_mat_templates/window_clear.c new file mode 100644 index 0000000..7c09524 --- /dev/null +++ b/external/flint-2.4.3/fq_mat_templates/window_clear.c @@ -0,0 +1,43 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2008, Richard Howell-Peak + Copyright (C) 2008, Martin Albrecht + Copyright (C) 2010, Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +TEMPLATE(T, mat_window_clear) (TEMPLATE(T, mat_t) window, + const TEMPLATE(T, ctx_t) ctx) +{ + flint_free(window->rows); +} + + +#endif diff --git a/external/flint-2.4.3/fq_mat_templates/window_init.c b/external/flint-2.4.3/fq_mat_templates/window_init.c new file mode 100644 index 0000000..6ab3406 --- /dev/null +++ b/external/flint-2.4.3/fq_mat_templates/window_init.c @@ -0,0 +1,54 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2008, Richard Howell-Peak + Copyright (C) 2008, Martin Albrecht + Copyright (C) 2010, Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +TEMPLATE(T, mat_window_init) (TEMPLATE(T, mat_t) window, + const TEMPLATE(T, mat_t) mat, + slong r1, slong c1, slong r2, slong c2, + const TEMPLATE(T, ctx_t) ctx) +{ + slong i; + window->entries = NULL; + + window->rows = flint_malloc((r2 - r1) * sizeof(TEMPLATE(T, struct) *)); + + for (i = 0; i < r2 - r1; i++) + window->rows[i] = mat->rows[r1 + i] + c1; + + window->r = r2 - r1; + window->c = c2 - c1; +} + + +#endif diff --git a/external/flint-2.4.3/fq_mat_templates/zero.c b/external/flint-2.4.3/fq_mat_templates/zero.c new file mode 100644 index 0000000..e8e4997 --- /dev/null +++ b/external/flint-2.4.3/fq_mat_templates/zero.c @@ -0,0 +1,42 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void TEMPLATE(T, mat_zero) (TEMPLATE(T, mat_t) A, const TEMPLATE(T, ctx_t) ctx) +{ + slong i, j; + + for (i = 0; i < A->r; i++) + for (j = 0; j < A->c; j++) + TEMPLATE(T, zero) (TEMPLATE(T, mat_entry) (A, i, j), ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_nmod.h b/external/flint-2.4.3/fq_nmod.h new file mode 100644 index 0000000..412251f --- /dev/null +++ b/external/flint-2.4.3/fq_nmod.h @@ -0,0 +1,404 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#ifndef FQ_NMOD_H +#define FQ_NMOD_H + +#include "nmod_poly.h" +#include "ulong_extras.h" + +/* Data types and context ****************************************************/ +#ifdef __cplusplus +extern "C" { +#endif + +typedef nmod_poly_t fq_nmod_t; +typedef nmod_poly_struct fq_nmod_struct; + +typedef struct +{ + fmpz p; + nmod_t mod; + + int sparse_modulus; + + mp_limb_t *a; + slong *j; + slong len; + + nmod_poly_t modulus; + nmod_poly_t inv; + + char *var; +} +fq_nmod_ctx_struct; + +typedef fq_nmod_ctx_struct fq_nmod_ctx_t[1]; + +void fq_nmod_ctx_init(fq_nmod_ctx_t ctx, + const fmpz_t p, slong d, const char *var); + +int _fq_nmod_ctx_init_conway(fq_nmod_ctx_t ctx, + const fmpz_t p, slong d, const char *var); + +void fq_nmod_ctx_init_conway(fq_nmod_ctx_t ctx, + const fmpz_t p, slong d, const char *var); + +void fq_nmod_ctx_init_modulus(fq_nmod_ctx_t ctx, + const nmod_poly_t modulus, + const char *var); + +void fq_nmod_ctx_randtest(fq_nmod_ctx_t ctx, flint_rand_t state); + +void fq_nmod_ctx_clear(fq_nmod_ctx_t ctx); + +static __inline__ slong fq_nmod_ctx_degree(const fq_nmod_ctx_t ctx) +{ + return ctx->modulus->length - 1; +} + +#define fq_nmod_ctx_prime(ctx) (&((ctx)->p)) + +static __inline__ void fq_nmod_ctx_order(fmpz_t f, const fq_nmod_ctx_t ctx) +{ + fmpz_set(f, fq_nmod_ctx_prime(ctx)); + fmpz_pow_ui(f, f, fq_nmod_ctx_degree(ctx)); +} + +/* TODO */ +static __inline__ int fq_nmod_ctx_fprint(FILE * file, const fq_nmod_ctx_t ctx) +{ + int r; + slong i, k; + + r = flint_fprintf(file, "p = "); + if (r <= 0) + return r; + + r = fmpz_fprint(file, fq_nmod_ctx_prime(ctx)); + if (r <= 0) + return r; + + r = flint_fprintf(file, "\nd = %wd\nf(X) = ", ctx->j[ctx->len - 1]); + if (r <= 0) + return r; + + r = flint_fprintf(file, "%wu", ctx->a[0]); + if (r <= 0) + return r; + + for (k = 1; k < ctx->len; k++) + { + i = ctx->j[k]; + r = flint_fprintf(file, " + "); + if (r <= 0) + return r; + + if (ctx->a[k] == UWORD(1)) + { + if (i == 1) + r = flint_fprintf(file, "X"); + else + r = flint_fprintf(file, "X^%wd", i); + if (r <= 0) + return r; + } + else + { + r = flint_fprintf(file, "%wu", ctx->a[k]); + if (r <= 0) + return r; + + if (i == 1) + r = flint_fprintf(file, "*X"); + else + r = flint_fprintf(file, "*X^%wd", i); + if (r <= 0) + return r; + } + } + r = flint_fprintf(file, "\n"); + return r; +} + +static __inline__ void fq_nmod_ctx_print(const fq_nmod_ctx_t ctx) +{ + fq_nmod_ctx_fprint(stdout, ctx); +} + +/* Memory managment *********************************************************/ + +static __inline__ void fq_nmod_init(fq_nmod_t rop, const fq_nmod_ctx_t ctx) +{ + nmod_poly_init2_preinv(rop, ctx->mod.n, ctx->mod.ninv, fq_nmod_ctx_degree(ctx)); +} + +static __inline__ void fq_nmod_init2(fq_nmod_t rop, const fq_nmod_ctx_t ctx) +{ + nmod_poly_init2_preinv(rop, ctx->mod.n, ctx->mod.ninv, fq_nmod_ctx_degree(ctx)); +} + +static __inline__ void fq_nmod_clear(fq_nmod_t rop, const fq_nmod_ctx_t ctx) +{ + nmod_poly_clear(rop); +} + +static __inline__ +void _fq_nmod_sparse_reduce(mp_limb_t *R, slong lenR, const fq_nmod_ctx_t ctx) +{ + const slong d = ctx->j[ctx->len - 1]; + + NMOD_VEC_NORM(R, lenR); + + if (lenR > d) + { + slong i, k; + + for (i = lenR - 1; i >= d; i--) + { + for (k = ctx->len - 2; k >= 0; k--) + { + + R[ctx->j[k] + i - d] = n_submod(R[ctx->j[k] + i - d], + n_mulmod2_preinv(R[i], ctx->a[k], ctx->mod.n, ctx->mod.ninv), + ctx->mod.n); + } + R[i] = UWORD(0); + } + } +} + +static __inline__ void _fq_nmod_dense_reduce(mp_limb_t* R, slong lenR, const fq_nmod_ctx_t ctx) +{ + mp_limb_t *q, *r; + + if (lenR < ctx->modulus->length) + { + _nmod_vec_reduce(R, R, lenR, ctx->mod); + return; + } + + q = _nmod_vec_init(lenR - ctx->modulus->length + 1); + r = _nmod_vec_init(ctx->modulus->length - 1); + + _nmod_poly_divrem_newton_n_preinv(q, r, R, lenR, + ctx->modulus->coeffs, ctx->modulus->length, + ctx->inv->coeffs, ctx->inv->length, + ctx->mod); + + _nmod_vec_set(R, r, ctx->modulus->length - 1); + _nmod_vec_clear(q); + _nmod_vec_clear(r); + +} + +static __inline__ void _fq_nmod_reduce(mp_limb_t* R, slong lenR, const fq_nmod_ctx_t ctx) +{ + if (ctx->sparse_modulus) + _fq_nmod_sparse_reduce(R, lenR, ctx); + else + _fq_nmod_dense_reduce(R, lenR, ctx); +} + +static __inline__ void fq_nmod_reduce(fq_nmod_t rop, const fq_nmod_ctx_t ctx) +{ + _fq_nmod_reduce(rop->coeffs, rop->length, ctx); + rop->length = FLINT_MIN(rop->length, ctx->modulus->length - 1); + _nmod_poly_normalise(rop); +} + +/* Basic arithmetic **********************************************************/ + +void fq_nmod_add(fq_nmod_t rop, const fq_nmod_t op1, const fq_nmod_t op2, const fq_nmod_ctx_t ctx); + +void fq_nmod_sub(fq_nmod_t rop, const fq_nmod_t op1, const fq_nmod_t op2, const fq_nmod_ctx_t ctx); + +void fq_nmod_sub_one(fq_nmod_t rop, const fq_nmod_t op1, const fq_nmod_ctx_t ctx); + +void fq_nmod_neg(fq_nmod_t rop, const fq_nmod_t op1, const fq_nmod_ctx_t ctx); + +void fq_nmod_mul(fq_nmod_t rop, const fq_nmod_t op1, const fq_nmod_t op2, const fq_nmod_ctx_t ctx); + +void fq_nmod_mul_fmpz(fq_nmod_t rop, const fq_nmod_t op, const fmpz_t x, const fq_nmod_ctx_t ctx); + +void fq_nmod_mul_si(fq_nmod_t rop, const fq_nmod_t op, slong x, const fq_nmod_ctx_t ctx); + +void fq_nmod_mul_ui(fq_nmod_t rop, const fq_nmod_t op, ulong x, const fq_nmod_ctx_t ctx); + +void fq_nmod_sqr(fq_nmod_t rop, const fq_nmod_t op, const fq_nmod_ctx_t ctx); + +void fq_nmod_inv(fq_nmod_t rop, const fq_nmod_t op1, const fq_nmod_ctx_t ctx); + +void _fq_nmod_pow(mp_limb_t *rop, const mp_limb_t *op, slong len, const fmpz_t e, const fq_nmod_ctx_t ctx); + +void fq_nmod_pow(fq_nmod_t rop, const fq_nmod_t op1, const fmpz_t e, const fq_nmod_ctx_t ctx); + +void fq_nmod_pow_ui(fq_nmod_t rop, const fq_nmod_t op1, const ulong e, const fq_nmod_ctx_t ctx); + +void +fq_nmod_pth_root(fq_nmod_t rop, const fq_nmod_t op1, const fq_nmod_ctx_t ctx); + +/* Randomisation *************************************************************/ + +void fq_nmod_randtest(fq_nmod_t rop, flint_rand_t state, const fq_nmod_ctx_t ctx); + +void fq_nmod_randtest_dense(fq_nmod_t rop, flint_rand_t state, const fq_nmod_ctx_t ctx); + +void fq_nmod_randtest_not_zero(fq_nmod_t rop, flint_rand_t state, const fq_nmod_ctx_t ctx); + +/* Comparison ****************************************************************/ + +static __inline__ int fq_nmod_equal(const fq_nmod_t op1, const fq_nmod_t op2, + const fq_nmod_ctx_t ctx) +{ + return nmod_poly_equal(op1, op2); +} + +static __inline__ int fq_nmod_is_zero(const fq_nmod_t op, const fq_nmod_ctx_t ctx) +{ + return nmod_poly_is_zero(op); +} + +static __inline__ int fq_nmod_is_one(const fq_nmod_t op, const fq_nmod_ctx_t ctx) +{ + return nmod_poly_is_one(op); +} + +/* Assignments and conversions ***********************************************/ + +static __inline__ void fq_nmod_set(fq_nmod_t rop, const fq_nmod_t op, + const fq_nmod_ctx_t ctx) +{ + nmod_poly_set(rop, op); +} + +static __inline__ void fq_nmod_set_fmpz(fq_nmod_t rop, const fmpz_t x, const fq_nmod_ctx_t ctx) +{ + fmpz_t rx; + fmpz_init(rx); + fmpz_mod(rx, x, fq_nmod_ctx_prime(ctx)); + nmod_poly_zero(rop); + nmod_poly_set_coeff_ui(rop, 0, fmpz_get_ui(rx)); + fmpz_clear(rx); +} + +static __inline__ void fq_nmod_set_ui(fq_nmod_t rop, const ulong x, const fq_nmod_ctx_t ctx) +{ + nmod_poly_zero(rop); + nmod_poly_set_coeff_ui(rop, 0, n_mod2_preinv(x, ctx->mod.n, ctx->mod.ninv)); +} + +static __inline__ void fq_nmod_swap(fq_nmod_t op1, fq_nmod_t op2, + const fq_nmod_ctx_t ctx) +{ + nmod_poly_swap(op1, op2); +} + +static __inline__ void fq_nmod_zero(fq_nmod_t rop, const fq_nmod_ctx_t ctx) +{ + nmod_poly_zero(rop); +} + +static __inline__ void fq_nmod_one(fq_nmod_t rop, const fq_nmod_ctx_t ctx) +{ + nmod_poly_one(rop); +} + +static __inline__ void fq_nmod_gen(fq_nmod_t rop, const fq_nmod_ctx_t ctx) +{ + nmod_poly_zero(rop); + nmod_poly_set_coeff_ui(rop, 0, 0); + nmod_poly_set_coeff_ui(rop, 1, 1); +} + +/* Output ********************************************************************/ + +static __inline__ +int fq_nmod_fprint(FILE * file, const fq_nmod_t op, const fq_nmod_ctx_t ctx) +{ + return nmod_poly_fprint(file, op); +} + +static __inline__ +void fq_nmod_print(const fq_nmod_t op, const fq_nmod_ctx_t ctx) +{ + nmod_poly_print(op); +} + +/* TODO: Make nmod_poly_fprint_pretty */ +static __inline__ +int fq_nmod_fprint_pretty(FILE * file, const fq_nmod_t op, const fq_nmod_ctx_t ctx) +{ + return nmod_poly_fprint(file, op); +} + +/* TODO: Make nmod_poly_print_pretty */ +static __inline__ +void fq_nmod_print_pretty(const fq_nmod_t op, const fq_nmod_ctx_t ctx) +{ + nmod_poly_print(op); +} + +char * +fq_nmod_get_str(const fq_nmod_t op, const fq_nmod_ctx_t ctx); + +char * +fq_nmod_get_str_pretty(const fq_nmod_t op, const fq_nmod_ctx_t ctx); + +/* Special functions *********************************************************/ + +void _fq_nmod_trace(fmpz_t rop, const mp_limb_t *op, slong len, + const fq_nmod_ctx_t ctx); + +void fq_nmod_trace(fmpz_t rop, const fq_nmod_t op, const fq_nmod_ctx_t ctx); + +void _fq_nmod_frobenius(mp_limb_t *rop, const mp_limb_t *op, slong len, slong e, + const fq_nmod_ctx_t ctx); + +void fq_nmod_frobenius(fq_nmod_t rop, const fq_nmod_t op, slong e, const fq_nmod_ctx_t ctx); + +void _fq_nmod_norm(fmpz_t rop, const mp_limb_t *op, slong len, + const fq_nmod_ctx_t ctx); + +void fq_nmod_norm(fmpz_t rop, const fq_nmod_t op, const fq_nmod_ctx_t ctx); + +/* Bit packing ******************************************************/ + +void +fq_nmod_bit_pack(fmpz_t f, const fq_nmod_t op, mp_bitcnt_t bit_size, + const fq_nmod_ctx_t ctx); + +void +fq_nmod_bit_unpack(fq_nmod_t rop, const fmpz_t f, mp_bitcnt_t bit_size, + const fq_nmod_ctx_t ctx); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/external/flint-2.4.3/fq_nmod/add.c b/external/flint-2.4.3/fq_nmod/add.c new file mode 100644 index 0000000..0fe94ec --- /dev/null +++ b/external/flint-2.4.3/fq_nmod/add.c @@ -0,0 +1,42 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod.h" + +void fq_nmod_add(fq_nmod_t rop, const fq_nmod_t op1, const fq_nmod_t op2, const fq_nmod_ctx_t ctx) +{ + slong max = FLINT_MAX(op1->length, op2->length); + + nmod_poly_fit_length(rop, max); + + _nmod_poly_add(rop->coeffs, + op1->coeffs, op1->length, op2->coeffs, op2->length, + rop->mod); + + _nmod_poly_set_length(rop, max); + _nmod_poly_normalise(rop); +} diff --git a/external/flint-2.4.3/fq_nmod/bit_pack.c b/external/flint-2.4.3/fq_nmod/bit_pack.c new file mode 100644 index 0000000..e029a0d --- /dev/null +++ b/external/flint-2.4.3/fq_nmod/bit_pack.c @@ -0,0 +1,34 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod.h" + +void +fq_nmod_bit_pack(fmpz_t f, const fq_nmod_t op, mp_bitcnt_t bit_size, + const fq_nmod_ctx_t ctx) +{ + nmod_poly_bit_pack(f, op, bit_size); +} + diff --git a/external/flint-2.4.3/fq_nmod/bit_unpack.c b/external/flint-2.4.3/fq_nmod/bit_unpack.c new file mode 100644 index 0000000..289caed --- /dev/null +++ b/external/flint-2.4.3/fq_nmod/bit_unpack.c @@ -0,0 +1,34 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod.h" + +void +fq_nmod_bit_unpack(fq_nmod_t rop, const fmpz_t f, mp_bitcnt_t bit_size, + const fq_nmod_ctx_t ctx) +{ + nmod_poly_bit_unpack(rop, f, bit_size); + fq_nmod_reduce(rop, ctx); +} diff --git a/external/flint-2.4.3/fq_nmod/ctx_clear.c b/external/flint-2.4.3/fq_nmod/ctx_clear.c new file mode 100644 index 0000000..85cdf3c --- /dev/null +++ b/external/flint-2.4.3/fq_nmod/ctx_clear.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod.h" + +void fq_nmod_ctx_clear(fq_nmod_ctx_t ctx) +{ + nmod_poly_clear(ctx->modulus); + nmod_poly_clear(ctx->inv); + fmpz_clear(fq_nmod_ctx_prime(ctx)); + _nmod_vec_clear(ctx->a); + flint_free(ctx->j); + flint_free(ctx->var); +} diff --git a/external/flint-2.4.3/fq_nmod/ctx_init.c b/external/flint-2.4.3/fq_nmod/ctx_init.c new file mode 100644 index 0000000..0dee2a7 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod/ctx_init.c @@ -0,0 +1,51 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include +#include + +#include "fq_nmod.h" +#include "nmod_poly.h" + +void fq_nmod_ctx_init(fq_nmod_ctx_t ctx, const fmpz_t p, slong d, const char *var) +{ + flint_rand_t state; + nmod_poly_t poly; + + if (_fq_nmod_ctx_init_conway(ctx, p, d, var)) + { + return; + } + + flint_randinit(state); + + nmod_poly_init2(poly, fmpz_get_ui(p), d + 1); + nmod_poly_randtest_sparse_irreducible(poly, state, d + 1); + + fq_nmod_ctx_init_modulus(ctx, poly, var); + + nmod_poly_clear(poly); + flint_randclear(state); +} diff --git a/external/flint-2.4.3/fq_nmod/ctx_init_conway.c b/external/flint-2.4.3/fq_nmod/ctx_init_conway.c new file mode 100644 index 0000000..f6ffcd6 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod/ctx_init_conway.c @@ -0,0 +1,124 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Andres Goens + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include +#include + +#include "fq_nmod.h" + +int _fq_nmod_ctx_init_conway(fq_nmod_ctx_t ctx, const fmpz_t p, slong d, const char *var) +{ + char *buf; + FILE *file; + + if (fmpz_cmp_ui(p, 109987) > 0) + { + return 0; + } + + buf = flint_malloc(832); + file = fopen(FLINT_CPIMPORT, "r"); + + if (!file) + { + file = fopen("../qadic/CPimport.txt", "r"); + + if (!file) + { + flint_printf("Exception (fq_nmod_ctx_init_conway). File loading.\n"); + abort(); + } + } + + while (fgets(buf, 832, file)) + { + char *tmp = buf; + + /* Different prime? */ + if (fmpz_cmp_ui(p, atoi(tmp))) + continue; + + while (*tmp++ != ' ') ; + + /* Same degree? */ + if (d == atoi(tmp)) + { + nmod_poly_t mod; + slong i; + char *ptr; + + nmod_poly_init(mod, fmpz_get_ui(p)); + + /* Copy the polynomial */ + ptr = tmp; + + for (i = 0; i < d; i++) + { + int coeff; + + while (*ptr++ != ' ') ; + + coeff = atoi(ptr); + + nmod_poly_set_coeff_ui(mod, i, coeff); + } + + nmod_poly_set_coeff_ui(mod, d, 1); + + fq_nmod_ctx_init_modulus(ctx, mod, var); + + nmod_poly_clear(mod); + fclose(file); + flint_free(buf); + return 1; + } + } + + fclose(file); + flint_free(buf); + + return 0; +} + + +void fq_nmod_ctx_init_conway(fq_nmod_ctx_t ctx, const fmpz_t p, slong d, const char *var) +{ + int result; + if (fmpz_cmp_ui(p, 109987) > 0) + { + flint_printf("Exception (fq_nmod_ctx_init_conway). Conway polynomials \n"); + flint_printf("are only available for primes up to 109987.\n"); + abort(); + } + + result = _fq_nmod_ctx_init_conway(ctx, p, d, var); + if (!result) { + flint_printf("Exception (fq_nmod_ctx_init_conway). The polynomial for \n(p,d) = ("); + fmpz_print(p), flint_printf(",%wd) is not present in the database.\n", d); + abort(); + } +} diff --git a/external/flint-2.4.3/fq_nmod/ctx_init_modulus.c b/external/flint-2.4.3/fq_nmod/ctx_init_modulus.c new file mode 100644 index 0000000..516a51b --- /dev/null +++ b/external/flint-2.4.3/fq_nmod/ctx_init_modulus.c @@ -0,0 +1,91 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include +#include + +#include "fq_nmod.h" + +void +fq_nmod_ctx_init_modulus(fq_nmod_ctx_t ctx, const nmod_poly_t modulus, + const char *var) +{ + slong nz; + int i, j; + mp_limb_t inv; + + fmpz_init(fq_nmod_ctx_prime(ctx)); + fmpz_set_ui(fq_nmod_ctx_prime(ctx), modulus->mod.n); + + ctx->mod.n = modulus->mod.n; + ctx->mod.ninv = modulus->mod.ninv; + ctx->mod.norm = modulus->mod.norm; + + /* Count number of nonzero coefficients */ + nz = 0; + for (i = 0; i < modulus->length; i++) + { + if (modulus->coeffs[i] != 0) + { + nz += 1; + } + } + + ctx->len = nz; + ctx->a = _nmod_vec_init(ctx->len); + ctx->j = flint_malloc(ctx->len * sizeof(mp_limb_t)); + + inv = n_invmod(modulus->coeffs[modulus->length - 1], ctx->mod.n); + + /* Copy the polynomial */ + j = 0; + for (i = 0; i < modulus->length; i++) + { + if (modulus->coeffs[i] != 0) + { + ctx->a[j] = n_mulmod2_preinv(inv, modulus->coeffs[i], + ctx->mod.n, ctx->mod.ninv); + ctx->j[j] = i; + j++; + } + } + + if (ctx->len < 6) + ctx->sparse_modulus = 1; + else + ctx->sparse_modulus = 0; + + ctx->var = flint_malloc(strlen(var) + 1); + strcpy(ctx->var, var); + + /* Set the modulus */ + nmod_poly_init(ctx->modulus, ctx->mod.n); + nmod_poly_set(ctx->modulus, modulus); + + /* Precompute the inverse of the modulus */ + nmod_poly_init(ctx->inv, ctx->mod.n); + nmod_poly_reverse(ctx->inv, ctx->modulus, ctx->modulus->length); + nmod_poly_inv_series_newton(ctx->inv, ctx->inv, ctx->modulus->length); +} diff --git a/external/flint-2.4.3/fq_nmod/ctx_randtest.c b/external/flint-2.4.3/fq_nmod/ctx_randtest.c new file mode 100644 index 0000000..01196df --- /dev/null +++ b/external/flint-2.4.3/fq_nmod/ctx_randtest.c @@ -0,0 +1,55 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod.h" + +void +fq_nmod_ctx_randtest(fq_nmod_ctx_t ctx, flint_rand_t state) +{ + nmod_poly_t modulus; + mp_limb_t x; + fmpz_t p; + slong d; + + fmpz_init(p); + fmpz_set_ui(p, n_randprime(state, 2 + n_randint(state, 6), 1)); + d = n_randint(state, 10) + 1; + fq_nmod_ctx_init_conway(ctx, p, d, "a"); + fmpz_clear(p); + + /* Test non-monic modulus */ + if (n_randint(state, 2)) + { + nmod_poly_init(modulus, ctx->mod.n); + nmod_poly_set(modulus, ctx->modulus); + x = n_randint(state, ctx->mod.n - 1) + 1; + nmod_poly_scalar_mul_nmod(modulus, modulus, x); + fq_nmod_ctx_clear(ctx); + fq_nmod_ctx_init_modulus(ctx, modulus, "a"); + nmod_poly_clear(modulus); + } +} diff --git a/external/flint-2.4.3/fq_nmod/doc/fq_nmod.txt b/external/flint-2.4.3/fq_nmod/doc/fq_nmod.txt new file mode 100644 index 0000000..ce3534c --- /dev/null +++ b/external/flint-2.4.3/fq_nmod/doc/fq_nmod.txt @@ -0,0 +1,486 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +******************************************************************************* + + Context Management + +******************************************************************************* + +void fq_nmod_ctx_init(fq_nmod_ctx_t ctx, const fmpz_t p, + slong d, const char *var) + + Initialises the context for prime~$p$ and extension degree~$d$, + with name \code{var} for the generator. By default, it will try + use a Conway polynomial; if one is not available, a random + irreducible polynomial will be used. + + Assumes that $p$ is a prime. + + Assumes that the string \code{var} is a null-terminated string + of length at least one. + +int _fq_nmod_ctx_init_conway(fq_nmod_ctx_t ctx, const fmpz_t p, + slong d, const char *var) + + Attempts to initialise the context for prime~$p$ and extension + degree~$d$, with name \code{var} for the generator using a Conway + polynomial for the modulus. + + Returns $1$ if the Conway polynomial is in the database for the + given size and the initialization is successful; otherwise, + returns $0$. + + Assumes that $p$ is a prime. + + Assumes that the string \code{var} is a null-terminated string + of length at least one. + + +void fq_nmod_ctx_init_conway(fq_nmod_ctx_t ctx, const fmpz_t p, + slong d, const char *var) + + Initialises the context for prime~$p$ and extension degree~$d$, + with name \code{var} for the generator using a Conway polynomial + for the modulus. + + Assumes that $p$ is a prime. + + Assumes that the string \code{var} is a null-terminated string + of length at least one. + +void fq_nmod_ctx_init_modulus(fq_nmod_ctx_t ctx, + nmod_poly_t modulus, + const char *var) + + Initialises the context for given \code{modulus} with name + \code{var} for the generator. + + Assumes that \code{modulus} is and irreducible polynomial over + $\mathbf{F}_{p}$. + + Assumes that the string \code{var} is a null-terminated string + of length at least one. + +void fq_nmod_ctx_clear(fq_nmod_ctx_t ctx) + + Clears all memory that has been allocated as part of the context. + +long fq_nmod_ctx_degree(const fq_nmod_ctx_t ctx) + + Returns the degree of the field extension + $[\mathbf{F}_{q} : \mathbf{F}_{p}]$, which + is equal to $\log_{p} q$. + +fmpz * fq_nmod_ctx_prime(const fq_nmod_ctx_t ctx) + + Returns a pointer to the prime $p$ in the context. + +void fq_nmod_ctx_order(fmpz_t f, const fq_nmod_ctx_t ctx) + + Sets $f$ to be the size of the finite field. + +int fq_nmod_ctx_fprint(FILE * file, const fq_nmod_ctx_t ctx) + + Prints the context information to {\tt{file}}. Returns 1 for a + success and a negative number for an error. + +void fq_nmod_ctx_print(const fq_nmod_ctx_t ctx) + + Prints the context information to {\tt{stdout}}. + +void fq_nmod_ctx_randtest(fq_nmod_ctx_t ctx) + + Initializes \code{ctx} to a random finite field. Assumes that + \code{fq_nmod_ctx_init} as not been called on \code{ctx} already. + + +void fq_nmod_ctx_randtest_reducible(fq_nmod_ctx_t ctx) + + Initializes \code{ctx} to a random extension of a word-sized prime + field. The modulus may or may not be irreducible. Assumes that + \code{fq_nmod_ctx_init} as not been called on \code{ctx} already. + +******************************************************************************* + + Memory management + +******************************************************************************* + +void fq_nmod_init(fq_nmod_t rop, const fq_nmod_ctx_t ctx) + + Initialises the element \code{rop}, setting its value to~$0$. + +void fq_nmod_init2(fq_nmod_t rop, const fq_nmod_ctx_t ctx) + + Initialises \code{poly} with at least enough space for it to be an element + of \code{ctx} and sets it to~$0$. + +void fq_nmod_clear(fq_nmod_t rop, const fq_nmod_ctx_t ctx) + + Clears the element \code{rop}. + +void _fq_nmod_sparse_reduce(mp_ptr R, slong lenR, const fq_nmod_ctx_t ctx) + + Reduces \code{(R, lenR)} modulo the polynomial $f$ given by the + modulus of \code{ctx}. + +void _fq_nmod_dense_reduce(mp_ptr R, slong lenR, const fq_nmod_ctx_t ctx) + + Reduces \code{(R, lenR)} modulo the polynomial $f$ given by the + modulus of \code{ctx} using Newton division. + +void _fq_nmod_reduce(mp_ptr r, slong lenR, const fq_nmod_ctx_t ctx) + + Reduces \code{(R, lenR)} modulo the polynomial $f$ given by the + modulus of \code{ctx}. Does either sparse or dense reduction + based on \code{ctx->sparse_modulus}. + +void fq_nmod_reduce(fq_nmod_t rop, const fq_nmod_ctx_t ctx) + + Reduces the polynomial \code{rop} as an element of + $\mathbf{F}_p[X] / (f(X))$. + +******************************************************************************* + + Basic arithmetic + +******************************************************************************* + +void fq_nmod_add(fq_nmod_t rop, const fq_nmod_t op1, const fq_nmod_t op2, + const fq_nmod_ctx_t ctx) + + Sets \code{rop} to the sum of \code{op1} and \code{op2}. + +void fq_nmod_sub(fq_nmod_t rop, const fq_nmod_t op1, const fq_nmod_t op2, + const fq_nmod_ctx_t ctx) + + Sets \code{rop} to the difference of \code{op1} and \code{op2}. + +void fq_nmod_sub_one(fq_nmod_t rop, const fq_nmod_t op1, const fq_nmod_ctx_t ctx) + + Sets \code{rop} to the difference of \code{op1} and $1$. + +void fq_nmod_neg(fq_nmod_t rop, const fq_nmod_t op, const fq_nmod_ctx_t ctx) + + Sets \code{rop} to the negative of \code{op}. + +void fq_nmod_mul(fq_nmod_t rop, const fq_nmod_t op1, const fq_nmod_t op2, + const fq_nmod_ctx_t ctx) + + Sets \code{rop} to the product of \code{op1} and \code{op2}, + reducing the output in the given context. + +void fq_nmod_mul_fmpz(fq_nmod_t rop, const fq_nmod_t op, const fmpz_t x, + const fq_nmod_ctx_t ctx) + + Sets \code{rop} to the product of \code{op} and $x$, + reducing the output in the given context. + +void fq_nmod_mul_si(fq_nmod_t rop, const fq_nmod_t op, slong x, + const fq_nmod_ctx_t ctx) + + Sets \code{rop} to the product of \code{op} and $x$, + reducing the output in the given context. + +void fq_nmod_mul_ui(fq_nmod_t rop, const fq_nmod_t op, ulong x, + const fq_nmod_ctx_t ctx) + + Sets \code{rop} to the product of \code{op} and $x$, + reducing the output in the given context. + + +void fq_nmod_sqr(fq_nmod_t rop, const fq_nmod_t op, const fq_nmod_ctx_t ctx) + + Sets \code{rop} to the square of \code{op}, + reducing the output in the given context. + +void _fq_nmod_inv(mp_ptr *rop, mp_srcptr *op, slong len, const fq_nmod_ctx_t ctx) + + Sets \code{(rop, d)} to the inverse of the non-zero element + \code{(op, len)}. + +void fq_nmod_inv(fq_nmod_t rop, const fq_nmod_t op, const fq_nmod_ctx_t ctx) + + Sets \code{rop} to the inverse of the non-zero element \code{op}. + +void _fq_nmod_pow(mp_ptr *rop, mp_srcptr *op, slong len, const fmpz_t e, + const fq_nmod_ctx_t ctx) + + Sets \code{(rop, 2*d-1)} to \code{(op,len)} raised to the power~$e$, + reduced modulo $f(X)$, the modulus of \code{ctx}. + + Assumes that $e \geq 0$ and that \code{len} is positive and at most~$d$. + + Although we require that \code{rop} provides space for + $2d - 1$ coefficients, the output will be reduced modulo + $f(X)$, which is a polynomial of degree~$d$. + + Does not support aliasing. + +void fq_nmod_pow(fq_nmod_t rop, const fq_nmod_t op, const fmpz_t e, + const fq_nmod_ctx_t ctx) + + Sets \code{rop} the \code{op} raised to the power~$e$. + + Currently assumes that $e \geq 0$. + + Note that for any input \code{op}, \code{rop} is set to~$1$ + whenever $e = 0$. + +void fq_nmod_pow_ui(fq_nmod_t rop, const fq_nmod_t op, const ulong e, + const fq_nmod_ctx_t ctx) + + Sets \code{rop} the \code{op} raised to the power~$e$. + + Currently assumes that $e \geq 0$. + + Note that for any input \code{op}, \code{rop} is set to~$1$ + whenever $e = 0$. + +******************************************************************************* + + Roots + +******************************************************************************* + +void fq_nmod_pth_root(fq_nmod_t rop, const fq_nmod_t op1, + const fq_nmod_ctx_t ctx) + + Sets \code{rop} to a $p^{th}$ root root of \code{op1}. Currently, + this computes the root by raising \code{op1} to $p^{d-1}$ where + $d$ is the degree of the extension. + +******************************************************************************* + + Output + +******************************************************************************* + +int fq_nmod_fprint_pretty(FILE *file, const fq_nmod_t op, + const fq_nmod_ctx_t ctx) + + Prints a pretty representation of \code{op} to \code{file}. + + In the current implementation, always returns~$1$. The return code is + part of the function's signature to allow for a later implementation to + return the number of characters printed or a non-positive error code. + +int fq_nmod_print_pretty(const fq_nmod_t op, const fq_nmod_ctx_t ctx) + + Prints a pretty representation of \code{op} to \code{stdout}. + + In the current implementation, always returns~$1$. The return code is + part of the function's signature to allow for a later implementation to + return the number of characters printed or a non-positive error code. + +void fq_nmod_fprint(FILE * file, const fq_nmod_t op, const fq_nmod_ctx_t ctx) + + Prints a representation of \code{op} to \code{file}. + + For further details on the representation used, see + \code{nmod_poly_fprint()}. + +void fq_nmod_print(const fq_nmod_t op, const fq_nmod_ctx_t ctx) + + Prints a representation of \code{op} to \code{stdout}. + + For further details on the representation used, see + \code{nmod_poly_print()}. + +char * fq_nmod_get_str(const fq_nmod_t op, const fq_nmod_ctx_t ctx) + + Returns the plain FLINT string representation of the element + \code{op}. + +char * fq_nmod_get_str_pretty(const fq_nmod_t op, const fq_nmod_ctx_t ctx) + + Returns a pretty representation of the element~\code{op} using the + null-terminated string \code{x} as the variable name. + +******************************************************************************* + + Randomisation + +******************************************************************************* + +void fq_nmod_randtest(fq_nmod_t rop, flint_rand_t state, + const fq_nmod_ctx_t ctx) + + Generates a random element of $\mathbb{F}_q$. + +void fq_nmod_randtest_not_zero(fq_nmod_t rop, flint_rand_t state, + const fq_nmod_ctx_t ctx) + + Generates a random non-zero element of $\mathbb{F}_q$. + +void fq_nmod_randtest_dense(fq_nmod_t rop, flint_rand_t state, + const fq_nmod_ctx_t ctx) + + Generates a random element of $\mathbb{F}_q$ which has an + underlying polynomial with dense coefficients. + +******************************************************************************* + + Assignments and conversions + +******************************************************************************* + +void fq_nmod_set(fq_nmod_t rop, const fq_nmod_t op, const fq_nmod_ctx_t ctx) + + Sets \code{rop} to \code{op}. + +void fq_nmod_set_ui(fq_nmod_t rop, const ulong x, const fq_nmod_ctx_t ctx) + + Sets \code{rop} to \code{x}, considered as an element of + $\mathbb{F}_p$. + +void fq_nmod_set_fmpz(fq_nmod_t rop, const fmpz_t x, const fq_nmod_ctx_t ctx) + + Sets \code{rop} to \code{x}, considered as an element of + $\mathbb{F}_p$. + +void fq_nmod_swap(fq_nmod_t op1, fq_nmod_t op2, const fq_nmod_ctx_t ctx) + + Swaps the two elements \code{op1} and \code{op2}. + +void fq_nmod_zero(fq_nmod_t rop, const fq_nmod_ctx_t ctx) + + Sets \code{rop} to zero. + +void fq_nmod_one(fq_nmod_t rop, const fq_nmod_ctx_t ctx) + + Sets \code{rop} to one, reduced in the given context. + +void fq_nmod_gen(fq_nmod_t rop, const fq_nmod_ctx_t ctx) + + Sets \code{rop} to a multiplicative generator for the finite field. + +******************************************************************************* + + Comparison + +******************************************************************************* + +int fq_nmod_is_zero(const fq_nmod_t op, const fq_nmod_ctx_t ctx) + + Returns whether \code{op} is equal to zero. + +int fq_nmod_is_one(const fq_nmod_t op, const fq_nmod_ctx_t ctx) + + Returns whether \code{op} is equal to one. + +int fq_nmod_equal(const fq_nmod_t op1, const fq_nmod_t op2, + const fq_nmod_ctx_t ctx) + + Returns whether \code{op1} and \code{op2} are equal. + +int fq_nmod_is_invertible(const fq_nmod_t op, const fq_nmod_ctx_t ctx) + + Returns whether \code{op} is an invertible element. + +int fq_nmod_is_invertible_f(fq_nmod_t f, const fq_nmod_t op, + const fq_nmod_ctx_t ctx) + + Returns whether \code{op} is an invertible element. If it is not, + then \code{f} is set of a factor of the modulus. + +******************************************************************************* + + Special functions + +******************************************************************************* + +void _fq_nmod_trace(fmpz_t rop, mp_srcptr *op, slong len, + const fq_nmod_ctx_t ctx) + + Sets \code{rop} to the trace of the non-zero element \code{(op, len)} + in $\mathbf{F}_{q}$. + +void fq_nmod_trace(fq_nmod_t rop, const fq_nmod_t op, const fq_nmod_ctx_t ctx) + + Sets \code{rop} to the trace of \code{op}. + + For an element $a \in \mathbb{F}_q$, multiplication by $a$ defines + a $\mathbb{F}_p$-linear map on $\mathbb{F}_q$. We define the + trace of $a$ as the trace of this map. Equivalently, if $\Sigma$ + generates $\Gal(\mathbb{F}_q / \mathbb{F}_p)$ then the trace of + $a$ is equal to $\sum_{i=0}^{d-1} \Sigma^i (a)$, where $d = + \log_{p} q$. + +void _fq_nmod_norm(fmpz_t rop, mp_srcptr *op, slong len, const fq_nmod_ctx_t ctx) + + Sets \code{rop} to the norm of the non-zero element \code{(op, len)} + in $\mathbf{F}_{q}$. + +void fq_nmod_norm(fq_nmod_t rop, const fq_nmod_t op, const fq_nmod_ctx_t ctx) + + Computes the norm of \code{op}. + + For an element $a \in \mathbb{F}_q$, multiplication by $a$ defines + a $\mathbb{F}_p$-linear map on $\mathbb{F}_q$. We define the norm + of $a$ as the determinant of this map. Equivalently, if $\Sigma$ generates + $\Gal(\mathbb{F}_q / \mathbb{F}_p)$ then the trace of $a$ is equal to + $\prod_{i=0}^{d-1} \Sigma^i (a)$, where + $d = \text{dim}_{\mathbb{F}_p}(\mathbb{F}_q)$. + + Algorithm selection is automatic depending on the input. + +void _fq_nmod_frobenius(mp_ptr *rop, mp_srcptr *op, slong len, slong e, + const fq_nmod_ctx_t ctx) + + Sets \code{(rop, 2d-1)} to the image of \code{(op, len)} under the + Frobenius operator raised to the e-th power, assuming that neither + \code{op} nor \code{e} are zero. + +void fq_nmod_frobenius(fq_nmod_t rop, const fq_nmod_t op, slong e, + const fq_nmod_ctx_t ctx) + + Evaluates the homomorphism $\Sigma^e$ at \code{op}. + + Recall that $\mathbb{F}_q / \mathbb{F}_p$ is Galois with Galois group + $\langle \sigma \rangle$, which is also isomorphic to + $\mathbf{Z}/d\mathbf{Z}$, where + $\sigma \in \Gal(\mathbf{F}_q/\mathbf{F}_p)$ is the Frobenius element + $\sigma \colon x \mapsto x^p$. + +******************************************************************************* + + Bit packing + +******************************************************************************* + +void fq_nmod_bit_pack(fmpz_t f, const fq_nmod_t op, mp_bitcnt_t bit_size, + const fq_nmod_ctx_t ctx) + + Packs \code{op} into bitfields of size \code{bit_size}, writing the + result to \code{f}. + +void fq_nmod_bit_unpack(fq_nmod_t rop, const fmpz_t f, mp_bitcnt_t bit_size, + const fq_nmod_ctx_t ctx) + + Unpacks into \code{rop} the element with coefficients packed into + fields of size \code{bit_size} as represented by the integer + \code{f}. diff --git a/external/flint-2.4.3/fq_nmod/frobenius.c b/external/flint-2.4.3/fq_nmod/frobenius.c new file mode 100644 index 0000000..3a296fa --- /dev/null +++ b/external/flint-2.4.3/fq_nmod/frobenius.c @@ -0,0 +1,102 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "ulong_extras.h" +#include "fq_nmod.h" + +/* + Sets (rop, 2d-1) to the image of (op, len) under the Frobenius operator + raised to the e-th power, assuming that neither op nor e are zero. + */ + +void _fq_nmod_frobenius(mp_limb_t *rop, const mp_limb_t *op, slong len, slong e, + const fq_nmod_ctx_t ctx) +{ + const slong d = ctx->j[ctx->len - 1]; + + if (len == 1) /* op is in Fp, not just Fq */ + { + _nmod_vec_set(rop, op, len); + _nmod_vec_zero(rop + len, (2*d - 1) - len); + } + else + { + fmpz_t t; + + fmpz_init(t); + fmpz_pow_ui(t, fq_nmod_ctx_prime(ctx), e); + _fq_nmod_pow(rop, op, len, t, ctx); + fmpz_clear(t); + } +} + +void fq_nmod_frobenius(fq_nmod_t rop, const fq_nmod_t op, slong e, const fq_nmod_ctx_t ctx) +{ + const slong d = fq_nmod_ctx_degree(ctx); + + e = e % d; + if (e < 0) + e += d; + + if (fq_nmod_is_zero(op, ctx)) + { + fq_nmod_zero(rop, ctx); + } + else if (e == 0) + { + fq_nmod_set(rop, op, ctx); + } + else + { + mp_limb_t *t; + + if (rop == op) + { + t = _nmod_vec_init(2 * d - 1); + } + else + { + nmod_poly_fit_length(rop, 2 * d - 1); + t = rop->coeffs; + } + + _fq_nmod_frobenius(t, op->coeffs, op->length, e, ctx); + + if (rop == op) + { + _nmod_vec_clear(rop->coeffs); + rop->coeffs = t; + rop->alloc = 2 * d - 1; + rop->length = d; + } + else + { + _nmod_poly_set_length(rop, d); + } + _nmod_poly_normalise(rop); + } +} + diff --git a/external/flint-2.4.3/fq_nmod/get_str.c b/external/flint-2.4.3/fq_nmod/get_str.c new file mode 100644 index 0000000..0735310 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod/get_str.c @@ -0,0 +1,32 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod.h" + +char * +fq_nmod_get_str(const fq_nmod_t op, const fq_nmod_ctx_t ctx) +{ + return nmod_poly_get_str(op); +} diff --git a/external/flint-2.4.3/fq_nmod/get_str_pretty.c b/external/flint-2.4.3/fq_nmod/get_str_pretty.c new file mode 100644 index 0000000..b13f927 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod/get_str_pretty.c @@ -0,0 +1,33 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod.h" + +char * +fq_nmod_get_str_pretty(const fq_nmod_t op, const fq_nmod_ctx_t ctx) +{ + /* TODO: Implement nmod_poly_get_str_pretty */ + return nmod_poly_get_str(op); +} diff --git a/external/flint-2.4.3/fq_nmod/inv.c b/external/flint-2.4.3/fq_nmod/inv.c new file mode 100644 index 0000000..790cc10 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod/inv.c @@ -0,0 +1,83 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod.h" + +void _fq_nmod_inv(mp_limb_t *rop, const mp_limb_t *op, slong len, + const fq_nmod_ctx_t ctx) +{ + const slong d = fq_nmod_ctx_degree(ctx); + + if (len == 1) + { + rop[0] = n_invmod(op[0], ctx->mod.n); + _nmod_vec_zero(rop + 1, d - 1); + } + else + { + _nmod_poly_invmod(rop, op, len, ctx->modulus->coeffs, d + 1, ctx->mod); + } +} + +void fq_nmod_inv(fq_nmod_t rop, const fq_nmod_t op, const fq_nmod_ctx_t ctx) +{ + if (fq_nmod_is_zero(op, ctx)) + { + flint_printf("Exception (fq_nmod_inv). Zero is not invertible.\n"); + abort(); + } + else + { + const slong d = fq_nmod_ctx_degree(ctx); + mp_limb_t *t; + + if (rop == op) + { + t = _nmod_vec_init(d); + } + else + { + nmod_poly_fit_length(rop, d); + t = rop->coeffs; + } + + _fq_nmod_inv(t, op->coeffs, op->length, ctx); + + if (rop == op) + { + _nmod_vec_clear(rop->coeffs); + rop->coeffs = t; + rop->alloc = d; + rop->length = d; + } + else + { + _nmod_poly_set_length(rop, d); + } + _nmod_poly_normalise(rop); + } +} diff --git a/external/flint-2.4.3/fq_nmod/mul.c b/external/flint-2.4.3/fq_nmod/mul.c new file mode 100644 index 0000000..bcffa1d --- /dev/null +++ b/external/flint-2.4.3/fq_nmod/mul.c @@ -0,0 +1,35 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod.h" + +void fq_nmod_mul(fq_nmod_t rop, const fq_nmod_t op1, const fq_nmod_t op2, const fq_nmod_ctx_t ctx) +{ + nmod_poly_mul(rop, op1, op2); + + fq_nmod_reduce(rop, ctx); +} diff --git a/external/flint-2.4.3/fq_nmod/mul_fmpz.c b/external/flint-2.4.3/fq_nmod/mul_fmpz.c new file mode 100644 index 0000000..8cf1a8e --- /dev/null +++ b/external/flint-2.4.3/fq_nmod/mul_fmpz.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod.h" + +void fq_nmod_mul_fmpz(fq_nmod_t rop, const fq_nmod_t op, const fmpz_t x, const fq_nmod_ctx_t ctx) +{ + fmpz_t rx; + fmpz_init(rx); + + fmpz_mod(rx, x, fq_nmod_ctx_prime(ctx)); + nmod_poly_scalar_mul_nmod(rop, op, fmpz_get_ui(rx)); + + fmpz_clear(rx); +} diff --git a/external/flint-2.4.3/fq_nmod/mul_si.c b/external/flint-2.4.3/fq_nmod/mul_si.c new file mode 100644 index 0000000..8853b1c --- /dev/null +++ b/external/flint-2.4.3/fq_nmod/mul_si.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod.h" + +void fq_nmod_mul_si(fq_nmod_t rop, const fq_nmod_t op, slong x, const fq_nmod_ctx_t ctx) +{ + mp_limb_t rx = x < 0 ? -x : x; + + nmod_poly_scalar_mul_nmod(rop, op, rx); + + if (x < 0) + nmod_poly_neg(rop, rop); +} diff --git a/external/flint-2.4.3/fq_nmod/mul_ui.c b/external/flint-2.4.3/fq_nmod/mul_ui.c new file mode 100644 index 0000000..0a5deda --- /dev/null +++ b/external/flint-2.4.3/fq_nmod/mul_ui.c @@ -0,0 +1,31 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod.h" + +void fq_nmod_mul_ui(fq_nmod_t rop, const fq_nmod_t op, ulong x, const fq_nmod_ctx_t ctx) +{ + nmod_poly_scalar_mul_nmod(rop, op, n_mod2_preinv(x, ctx->mod.n, ctx->mod.ninv)); +} diff --git a/external/flint-2.4.3/fq_nmod/neg.c b/external/flint-2.4.3/fq_nmod/neg.c new file mode 100644 index 0000000..2501594 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod/neg.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod.h" + +void fq_nmod_neg(fq_nmod_t rop, const fq_nmod_t op, const fq_nmod_ctx_t ctx) +{ + slong len = op->length; + + nmod_poly_fit_length(rop, len); + _nmod_poly_set_length(rop, len); + + nmod_poly_neg(rop, op); +} diff --git a/external/flint-2.4.3/fq_nmod/norm.c b/external/flint-2.4.3/fq_nmod/norm.c new file mode 100644 index 0000000..9c8e18c --- /dev/null +++ b/external/flint-2.4.3/fq_nmod/norm.c @@ -0,0 +1,105 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod.h" +#include "nmod_mat.h" + +/* + Computes the norm on $\mathbf{Q}_q$ to precision $N \geq 1$. + When $N = 1$, this computes the norm on $\mathbf{F}_q$. + */ + +void _fq_nmod_norm(fmpz_t rop2, const mp_limb_t *op, slong len, + const fq_nmod_ctx_t ctx) +{ + const slong d = fq_nmod_ctx_degree(ctx); + + mp_limb_t rop; + + if (len == 1) + { + rop = n_powmod2_ui_preinv(op[0], d, ctx->mod.n, ctx->mod.ninv); + } + else + { + /* Construct an ad hoc matrix M and set rop to det(M) */ + { + const slong n = d + len - 1; + slong i, k; + nmod_mat_t M; + + nmod_mat_init(M, n, n, ctx->mod.n); + + for (k = 0; k < len-1; k++) + { + for (i = 0; i < ctx->len; i++) + { + M->entries[k * n + k + (d - ctx->j[i])] = ctx->a[i]; + } + } + for (k = 0; k < d; k++) + { + for (i = 0; i < len; i++) + { + M->entries[(len-1 + k) * n + k + (len-1 - i)] = op[i]; + } + } + + rop = _nmod_mat_det(M); + + nmod_mat_clear(M); + } + + /* + XXX: This part of the code is currently untested as the Conway + polynomials used for the extension Fq/Fp are monic. + */ + if (ctx->a[ctx->len - 1] != WORD(1)) + { + mp_limb_t f; + f = n_powmod2_ui_preinv(ctx->a[ctx->len - 1], len - 1, ctx->mod.n, ctx->mod.ninv); + f = n_invmod(f, ctx->mod.n); + rop = n_mulmod2_preinv(f, rop, ctx->mod.n, ctx->mod.ninv); + } + } + + fmpz_set_ui(rop2, rop); + +} + +void fq_nmod_norm(fmpz_t rop, const fq_nmod_t op, const fq_nmod_ctx_t ctx) +{ + if (fq_nmod_is_zero(op, ctx)) + { + fmpz_zero(rop); + return; + } + else + { + _fq_nmod_norm(rop, op->coeffs, op->length, ctx); + } +} + diff --git a/external/flint-2.4.3/fq_nmod/pow.c b/external/flint-2.4.3/fq_nmod/pow.c new file mode 100644 index 0000000..040ff61 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod/pow.c @@ -0,0 +1,184 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod.h" + +void _fq_nmod_pow(mp_limb_t *rop, const mp_limb_t *op, slong len, const fmpz_t e, + const fq_nmod_ctx_t ctx) +{ + const slong d = fq_nmod_ctx_degree(ctx); + + if (fmpz_is_zero(e)) + { + rop[0] = WORD(1); + _nmod_vec_zero(rop + 1, 2 * d - 1 - 1); + } + else if (fmpz_is_one(e)) + { + _nmod_vec_set(rop, op, len); + _nmod_vec_zero(rop + len, 2 * d - 1 - len); + } + else + { + ulong bit; + mp_limb_t *v = _nmod_vec_init(2 * d - 1); + mp_limb_t *R, *S, *T; + + _nmod_vec_zero(v, 2 * d - 1); + _nmod_vec_zero(rop, 2 * d - 1); + + /* + Set bits to the bitmask with a 1 one place lower than the msb of e + */ + + bit = fmpz_bits(e) - 2; + + /* + Trial run without any polynomial arithmetic to determine the parity + of the number of swaps; then set R and S accordingly + */ + + { + unsigned int swaps = 0U; + ulong bit2 = bit; + if (fmpz_tstbit(e, bit2)) + swaps = ~swaps; + while (bit2--) + if (!fmpz_tstbit(e, bit2)) + swaps = ~swaps; + + if (swaps == 0U) + { + R = rop; + S = v; + } + else + { + R = v; + S = rop; + } + } + + /* + We unroll the first step of the loop, referring to {op, len} + */ + + _nmod_poly_mul(R, op, len, op, len, ctx->mod); + _fq_nmod_reduce(R, 2 * len - 1, ctx); + + if (fmpz_tstbit(e, bit)) + { + _nmod_poly_mul(S, R, d, op, len, ctx->mod); + _fq_nmod_reduce(S, d + len - 1, ctx); + T = R; + R = S; + S = T; + } + + while (bit--) + { + if (fmpz_tstbit(e, bit)) + { + _nmod_poly_mul(S, R, d, R, d, ctx->mod); + _fq_nmod_reduce(S, 2 * d - 1, ctx); + _nmod_poly_mul(R, S, d, op, len, ctx->mod); + _fq_nmod_reduce(R, d + len - 1, ctx); + } + else + { + _nmod_poly_mul(S, R, d, R, d, ctx->mod); + _fq_nmod_reduce(S, 2 * d - 1, ctx); + T = R; + R = S; + S = T; + } + } + + _nmod_vec_clear(v); + } +} + +void fq_nmod_pow(fq_nmod_t rop, const fq_nmod_t op, const fmpz_t e, const fq_nmod_ctx_t ctx) +{ + if (fmpz_sgn(e) < 0) + { + flint_printf("Exception (fq_nmod_pow). e < 0.\n"); + abort(); + } + + if (fmpz_is_zero(e)) + { + fq_nmod_one(rop, ctx); + } + else if (fq_nmod_is_zero(op, ctx)) + { + fq_nmod_zero(rop, ctx); + } + else if (fmpz_is_one(e)) + { + fq_nmod_set(rop, op, ctx); + } + else + { + const slong d = fq_nmod_ctx_degree(ctx); + mp_limb_t *t; + + if (rop == op) + { + t = _nmod_vec_init(2 * d - 1); + } + else + { + nmod_poly_fit_length(rop, 2 * d - 1); + t = rop->coeffs; + } + + _fq_nmod_pow(t, op->coeffs, op->length, e, ctx); + + if (rop == op) + { + _nmod_vec_clear(rop->coeffs); + rop->coeffs = t; + rop->alloc = 2 * d - 1; + rop->length = d; + } + else + { + _nmod_poly_set_length(rop, d); + } + _nmod_poly_normalise(rop); + } +} + + +/* TODO: Move into separate function / optimize */ +void fq_nmod_pow_ui(fq_nmod_t rop, const fq_nmod_t op, const ulong e, const fq_nmod_ctx_t ctx) +{ + fmpz_t exp; + fmpz_init_set_ui(exp, e); + fq_nmod_pow(rop, op, exp, ctx); + fmpz_clear(exp); +} diff --git a/external/flint-2.4.3/fq_nmod/pth_root.c b/external/flint-2.4.3/fq_nmod/pth_root.c new file mode 100644 index 0000000..438a72d --- /dev/null +++ b/external/flint-2.4.3/fq_nmod/pth_root.c @@ -0,0 +1,45 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod.h" + +void +fq_nmod_pth_root(fq_nmod_t rop, const fq_nmod_t op1, const fq_nmod_ctx_t ctx) +{ + slong i, d; + if (fq_nmod_is_zero(op1, ctx) || fq_nmod_is_one(op1, ctx)) + { + fq_nmod_set(rop, op1, ctx); + return; + } + + /* TODO: Use modular composition */ + d = fq_nmod_ctx_degree(ctx) - 1; + fq_nmod_set(rop, op1, ctx); + for (i = 0; i < d; i++) + { + fq_nmod_pow(rop, rop, fq_nmod_ctx_prime(ctx), ctx); + } +} diff --git a/external/flint-2.4.3/fq_nmod/randtest.c b/external/flint-2.4.3/fq_nmod/randtest.c new file mode 100644 index 0000000..eaa9b66 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod/randtest.c @@ -0,0 +1,68 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod.h" + +void fq_nmod_randtest(fq_nmod_t rop, flint_rand_t state, const fq_nmod_ctx_t ctx) +{ + const slong d = fq_nmod_ctx_degree(ctx); + slong i, sparse; + + nmod_poly_fit_length(rop, d); + + if (n_randint(state, 2)) + { + for (i = 0; i < d; i++) + rop->coeffs[i] = n_randint(state, ctx->mod.n); + } + else + { + sparse = 1 + n_randint(state, FLINT_MAX(2, d)); + + for (i = 0; i < d; i++) + if (n_randint(state, sparse)) + rop->coeffs[i] = WORD(0); + else + rop->coeffs[i] = n_randint(state, ctx->mod.n); + } + + _nmod_poly_set_length(rop, d); + _nmod_poly_normalise(rop); +} + +void fq_nmod_randtest_not_zero(fq_nmod_t rop, flint_rand_t state, const fq_nmod_ctx_t ctx) +{ + slong i; + + fq_nmod_randtest(rop, state, ctx); + for (i = 0; fq_nmod_is_zero(rop, ctx) && (i < 10); i++) + fq_nmod_randtest(rop, state, ctx); + + if (fq_nmod_is_zero(rop, ctx)) + fq_nmod_one(rop, ctx); +} + diff --git a/external/flint-2.4.3/fq_nmod/sqr.c b/external/flint-2.4.3/fq_nmod/sqr.c new file mode 100644 index 0000000..376ddee --- /dev/null +++ b/external/flint-2.4.3/fq_nmod/sqr.c @@ -0,0 +1,33 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod.h" + +void fq_nmod_sqr(fq_nmod_t rop, const fq_nmod_t op, const fq_nmod_ctx_t ctx) +{ + nmod_poly_mul(rop, op, op); + + fq_nmod_reduce(rop, ctx); +} diff --git a/external/flint-2.4.3/fq_nmod/sub.c b/external/flint-2.4.3/fq_nmod/sub.c new file mode 100644 index 0000000..a150c24 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod/sub.c @@ -0,0 +1,42 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod.h" + +void fq_nmod_sub(fq_nmod_t rop, const fq_nmod_t op1, const fq_nmod_t op2, const fq_nmod_ctx_t ctx) +{ + slong max = FLINT_MAX(op1->length, op2->length); + + nmod_poly_fit_length(rop, max); + + _nmod_poly_sub(rop->coeffs, + op1->coeffs, op1->length, op2->coeffs, op2->length, + ctx->mod); + + _nmod_poly_set_length(rop, max); + _nmod_poly_normalise(rop); +} diff --git a/external/flint-2.4.3/fq_nmod/sub_one.c b/external/flint-2.4.3/fq_nmod/sub_one.c new file mode 100644 index 0000000..943ed5d --- /dev/null +++ b/external/flint-2.4.3/fq_nmod/sub_one.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod.h" + +void fq_nmod_sub_one(fq_nmod_t rop, const fq_nmod_t op1, const fq_nmod_ctx_t ctx) +{ + fq_nmod_t one; + + fq_nmod_init(one, ctx); + fq_nmod_one(one, ctx); + fq_nmod_sub(rop, op1, one, ctx); + fq_nmod_clear(one, ctx); +} diff --git a/external/flint-2.4.3/fq_nmod/test/t-add.c b/external/flint-2.4.3/fq_nmod/test/t-add.c new file mode 100644 index 0000000..f7dcdab --- /dev/null +++ b/external/flint-2.4.3/fq_nmod/test/t-add.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_templates/test/t-add.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod/test/t-ctx_init.c b/external/flint-2.4.3/fq_nmod/test/t-ctx_init.c new file mode 100644 index 0000000..3b0a5f5 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod/test/t-ctx_init.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_templates/test/t-ctx_init.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod/test/t-frobenius.c b/external/flint-2.4.3/fq_nmod/test/t-frobenius.c new file mode 100644 index 0000000..c89f943 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod/test/t-frobenius.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_templates/test/t-frobenius.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod/test/t-inv.c b/external/flint-2.4.3/fq_nmod/test/t-inv.c new file mode 100644 index 0000000..512cb07 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod/test/t-inv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_templates/test/t-inv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod/test/t-mul.c b/external/flint-2.4.3/fq_nmod/test/t-mul.c new file mode 100644 index 0000000..d121563 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod/test/t-mul.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_templates/test/t-mul.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod/test/t-mul_fmpz.c b/external/flint-2.4.3/fq_nmod/test/t-mul_fmpz.c new file mode 100644 index 0000000..ab68181 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod/test/t-mul_fmpz.c @@ -0,0 +1,139 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fq_nmod.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("mul_fmpz...."); + fflush(stdout); + + /* Check aliasing of a, b */ + for (i = 0; i < 2000; i++) + { + fmpz_t p; + slong d; + fq_nmod_ctx_t ctx; + fmpz_t x; + fq_nmod_t a, b; + + fmpz_init(p); + fmpz_set_ui(p, n_randprime(state, 2 + n_randint(state, 3), 1)); + d = n_randint(state, 10) + 1; + fq_nmod_ctx_init_conway(ctx, p, d, "a"); + + fq_nmod_init(a, ctx); + fq_nmod_init(b, ctx); + fmpz_init(x); + + fq_nmod_randtest(a, state, ctx); + fmpz_randtest_mod_signed(x,state,fq_nmod_ctx_prime(ctx)); + fq_nmod_mul_fmpz(b, a, x, ctx); + fq_nmod_mul_fmpz(a, a, x, ctx); + + result = (fq_nmod_equal(a, b, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), fq_nmod_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), fq_nmod_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("x = "), fmpz_print(x), flint_printf("\n"); + abort(); + } + + fq_nmod_clear(a, ctx); + fq_nmod_clear(b, ctx); + fmpz_clear(x); + fmpz_clear(p); + fq_nmod_ctx_clear(ctx); + } + + /* compare with direct multiplication */ + for (i = 0; i < 2000; i++) + { + fmpz_t p; + slong d; + fq_nmod_ctx_t ctx; + fmpz_t x; + fq_nmod_t a, c; + nmod_poly_t b; + + fmpz_init(p); + fmpz_set_ui(p, n_randprime(state, 2 + n_randint(state, 3), 1)); + d = n_randint(state, 10) + 1; + fq_nmod_ctx_init_conway(ctx, p, d, "a"); + + fq_nmod_init(a, ctx); + fq_nmod_init(c, ctx); + fmpz_init(x); + nmod_poly_init(b, fmpz_get_ui(p)); + + fq_nmod_randtest(a, state, ctx); + fmpz_randtest_mod_signed(x, state, fq_nmod_ctx_prime(ctx)); + fq_nmod_mul_fmpz(c, a, x, ctx); + + if (fmpz_cmp_ui(x, 0) < 0) + { + nmod_poly_scalar_mul_nmod(b,a,-fmpz_get_si(x)); + nmod_poly_neg(b, b); + } + else + { + nmod_poly_scalar_mul_nmod(b,a,fmpz_get_ui(x)); + } + + result = (fq_nmod_equal(c, b, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), fq_nmod_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), fq_nmod_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), fq_nmod_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("x = "), fmpz_print(x), flint_printf("\n"); + abort(); + } + + fq_nmod_clear(a, ctx); + fq_nmod_clear(c, ctx); + nmod_poly_clear(b); + fmpz_clear(p); + fmpz_clear(x); + fq_nmod_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fq_nmod/test/t-mul_si.c b/external/flint-2.4.3/fq_nmod/test/t-mul_si.c new file mode 100644 index 0000000..b315822 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod/test/t-mul_si.c @@ -0,0 +1,122 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fq_nmod.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("mul_si...."); + fflush(stdout); + + /* Check aliasing of a, b */ + for (i = 0; i < 1000; i++) + { + fq_nmod_ctx_t ctx; + slong x; + fq_nmod_t a, b; + + fq_nmod_ctx_randtest(ctx, state); + + fq_nmod_init(a, ctx); + fq_nmod_init(b, ctx); + + fq_nmod_randtest(a, state, ctx); + x = z_randtest(state); + fq_nmod_mul_si(b, a, x, ctx); + fq_nmod_mul_si(a, a, x, ctx); + + result = (fq_nmod_equal(a, b, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), fq_nmod_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), fq_nmod_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("x = %wd\n",x); + abort(); + } + + fq_nmod_clear(a, ctx); + fq_nmod_clear(b, ctx); + + fq_nmod_ctx_clear(ctx); + } + + /* compare with direct multiplication */ + for (i = 0; i < 1000; i++) + { + fq_nmod_ctx_t ctx; + slong x; + fq_nmod_t a, c; + nmod_poly_t b; + + fq_nmod_ctx_randtest(ctx, state); + + fq_nmod_init(a, ctx); + fq_nmod_init(c, ctx); + nmod_poly_init(b, ctx->mod.n); + + fq_nmod_randtest(a, state, ctx); + x = z_randtest(state); + fq_nmod_mul_si(c, a, x, ctx); + if (x < 0) + { + nmod_poly_scalar_mul_nmod(b, a, -x); + nmod_poly_neg(b, b); + } + else + { + nmod_poly_scalar_mul_nmod(b, a, x); + } + + result = (fq_nmod_equal(c, b, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), fq_nmod_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), fq_nmod_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("x = %wd\n",x); + abort(); + } + + fq_nmod_clear(a, ctx); + fq_nmod_clear(c, ctx); + nmod_poly_clear(b); + fq_nmod_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fq_nmod/test/t-mul_ui.c b/external/flint-2.4.3/fq_nmod/test/t-mul_ui.c new file mode 100644 index 0000000..b3c513b --- /dev/null +++ b/external/flint-2.4.3/fq_nmod/test/t-mul_ui.c @@ -0,0 +1,115 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fq_nmod.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("mul_ui...."); + fflush(stdout); + + /* Check aliasing of a, b */ + for (i = 0; i < 2000; i++) + { + fq_nmod_ctx_t ctx; + ulong x; + fq_nmod_t a, b; + + fq_nmod_ctx_randtest(ctx, state); + + fq_nmod_init(a, ctx); + fq_nmod_init(b, ctx); + + fq_nmod_randtest(a, state, ctx); + x = z_randtest(state); + fq_nmod_mul_ui(b, a, x, ctx); + fq_nmod_mul_ui(a, a, x, ctx); + + result = (fq_nmod_equal(a, b, ctx)); + if (!result) + { + flint_printf("FAIL 1:\n\n"); + flint_printf("a = "), fq_nmod_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), fq_nmod_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("x = %wu\n",x); + abort(); + } + + fq_nmod_clear(a, ctx); + fq_nmod_clear(b, ctx); + + fq_nmod_ctx_clear(ctx); + } + + /* compare with direct multiplication */ + for (i = 0; i < 2000; i++) + { + fq_nmod_ctx_t ctx; + ulong x; + fq_nmod_t a, c; + nmod_poly_t b; + + fq_nmod_ctx_randtest(ctx, state); + + fq_nmod_init(a, ctx); + fq_nmod_init(c, ctx); + nmod_poly_init(b, ctx->mod.n); + + fq_nmod_randtest(a, state, ctx); + x = n_randint(state, ctx->mod.n); + fq_nmod_mul_ui(c, a, x, ctx); + nmod_poly_scalar_mul_nmod(b,a,x); + + result = (fq_nmod_equal(c, b, ctx)); + if (!result) + { + flint_printf("FAIL 2:\n\n"); + flint_printf("a = "), fq_nmod_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), fq_nmod_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), fq_nmod_print_pretty(c, ctx), flint_printf("\n"); + flint_printf("x = %wu\n",x); + abort(); + } + + fq_nmod_clear(a, ctx); + fq_nmod_clear(c, ctx); + nmod_poly_clear(b); + fq_nmod_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/fq_nmod/test/t-neg.c b/external/flint-2.4.3/fq_nmod/test/t-neg.c new file mode 100644 index 0000000..94196ab --- /dev/null +++ b/external/flint-2.4.3/fq_nmod/test/t-neg.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_templates/test/t-neg.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod/test/t-norm.c b/external/flint-2.4.3/fq_nmod/test/t-norm.c new file mode 100644 index 0000000..31897c6 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod/test/t-norm.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_templates/test/t-norm.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod/test/t-pow.c b/external/flint-2.4.3/fq_nmod/test/t-pow.c new file mode 100644 index 0000000..a9212a5 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod/test/t-pow.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_templates/test/t-pow.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod/test/t-pth_root.c b/external/flint-2.4.3/fq_nmod/test/t-pth_root.c new file mode 100644 index 0000000..051d39c --- /dev/null +++ b/external/flint-2.4.3/fq_nmod/test/t-pth_root.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_templates/test/t-pth_root.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod/test/t-sqr.c b/external/flint-2.4.3/fq_nmod/test/t-sqr.c new file mode 100644 index 0000000..185bffb --- /dev/null +++ b/external/flint-2.4.3/fq_nmod/test/t-sqr.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_templates/test/t-sqr.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod/test/t-sub.c b/external/flint-2.4.3/fq_nmod/test/t-sub.c new file mode 100644 index 0000000..9901dfc --- /dev/null +++ b/external/flint-2.4.3/fq_nmod/test/t-sub.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_templates/test/t-sub.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod/test/t-trace.c b/external/flint-2.4.3/fq_nmod/test/t-trace.c new file mode 100644 index 0000000..ff101e2 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod/test/t-trace.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_templates/test/t-trace.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod/trace.c b/external/flint-2.4.3/fq_nmod/trace.c new file mode 100644 index 0000000..175bbd5 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod/trace.c @@ -0,0 +1,85 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod.h" + +void _fq_nmod_trace(fmpz_t rop2, const mp_limb_t *op, slong len, + const fq_nmod_ctx_t ctx) +{ + const slong d = fq_nmod_ctx_degree(ctx); + + ulong i, l; + mp_limb_t *t, rop; + + t = _nmod_vec_init(d); + _nmod_vec_zero(t, d); + + t[0] = n_mod2_preinv(d, ctx->mod.n, ctx->mod.ninv); + + for (i = 1; i < d; i++) + { + for (l = ctx->len - 2; l >= 0 && ctx->j[l] >= d - (i - 1); l--) + { + t[i] = n_addmod(t[i], + n_mulmod2_preinv(t[ctx->j[l] + i - d], ctx->a[l], ctx->mod.n, ctx->mod.ninv), + ctx->mod.n); + } + + if (l >= 0 && ctx->j[l] == d - i) + { + t[i] = n_addmod(t[i], + n_mulmod2_preinv(ctx->a[l], i, ctx->mod.n, ctx->mod.ninv), + ctx->mod.n); + } + + t[i] = n_negmod(t[i], ctx->mod.n); + } + + + rop = WORD(0); + for (i = 0; i < d; i++) + { + rop = n_addmod(rop, + n_mulmod2_preinv(op[i], t[i], ctx->mod.n, ctx->mod.ninv), + ctx->mod.n); + } + + _nmod_vec_clear(t); + + fmpz_set_ui(rop2, rop); +} + +void fq_nmod_trace(fmpz_t rop, const fq_nmod_t op, const fq_nmod_ctx_t ctx) +{ + if (fq_nmod_is_zero(op, ctx)) + { + fmpz_zero(rop); + return; + } + + _fq_nmod_trace(rop, op->coeffs, op->length, ctx); +} + diff --git a/external/flint-2.4.3/fq_nmod_mat.h b/external/flint-2.4.3/fq_nmod_mat.h new file mode 100644 index 0000000..b860cdb --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_mat.h @@ -0,0 +1,53 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#ifndef FQ_NMOD_MAT_H +#define FQ_NMOD_MAT_H + +#include "fq_nmod.h" +#include "fq_nmod_vec.h" + +/* Cutoff between classical and recursive triangular solving */ +#define FQ_NMOD_MAT_SOLVE_TRI_ROWS_CUTOFF 64 +#define FQ_NMOD_MAT_SOLVE_TRI_COLS_CUTOFF 64 + +/* Cutoff between classical and recursive LU decomposition */ +#define FQ_NMOD_MAT_LU_RECURSIVE_CUTOFF 4 + +static __inline__ int FQ_NMOD_MAT_MUL_KS_CUTOFF(slong r, slong c, const fq_nmod_ctx_t ctx) +{ + if (FLINT_MIN(r, c) > fq_nmod_ctx_degree(ctx) / 20 + 6) + return 1; + else + return 0; +} + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_mat_templates.h" +#undef CAP_T +#undef T + +#endif diff --git a/external/flint-2.4.3/fq_nmod_mat/add.c b/external/flint-2.4.3/fq_nmod_mat/add.c new file mode 100644 index 0000000..2902c7f --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_mat/add.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_mat_templates/add.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_mat/clear.c b/external/flint-2.4.3/fq_nmod_mat/clear.c new file mode 100644 index 0000000..cad6e8e --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_mat/clear.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_mat_templates/clear.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_mat/doc/fq_nmod_mat.txt b/external/flint-2.4.3/fq_nmod_mat/doc/fq_nmod_mat.txt new file mode 100644 index 0000000..f3a7c1f --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_mat/doc/fq_nmod_mat.txt @@ -0,0 +1,442 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +******************************************************************************* + + Memory management + +******************************************************************************* + +void fq_nmod_mat_init(fq_nmod_mat_t mat, slong rows, slong cols, + const fq_nmod_ctx_t ctx) + + Initialises \code{mat} to a \code{rows}-by-\code{cols} matrix with + coefficients in $\mathbb{F}_{q}$ given by \code{ctx}. All elements + are set to zero. + +void fq_nmod_mat_init_set(fq_nmod_mat_t mat, fq_nmod_mat_t src, + const fq_nmod_ctx_t ctx) + + Initialises \code{mat} and sets its dimensions and elements to + those of \code{src}. + +void fq_nmod_mat_clear(fq_nmod_mat_t mat, const fq_nmod_ctx_t ctx) + + Clears the matrix and releases any memory it used. The matrix + cannot be used again until it is initialised. This function must be + called exactly once when finished using an \code{fq_nmod_mat_t} object. + +void fq_nmod_mat_set(fq_nmod_mat_t mat, fq_nmod_mat_t src, + const fq_nmod_ctx_t ctx) + + Sets \code{mat} to a copy of \code{src}. It is assumed + that \code{mat} and \code{src} have identical dimensions. + +******************************************************************************* + + Basic properties and manipulation + +******************************************************************************* + +fq_nmod_struct * fq_nmod_mat_entry(fq_nmod_mat_t mat, slong i, slong j) + + Directly accesses the entry in \code{mat} in row $i$ and column $j$, + indexed from zero. No bounds checking is performed. + +fq_nmod_struct * fq_nmod_mat_entry_set(fq_nmod_mat_t mat, slong i, slong j, + fq_nmod_t x, const fq_nmod_ctx_t ctx) + + Sets the entry in \code{mat} in row $i$ and column $j$ to \code{x}. + +slong fq_nmod_mat_nrows(fq_nmod_mat_t mat, const fq_nmod_ctx_t ctx) + + Returns the number of rows in \code{mat}. + +slong fq_nmod_mat_ncols(fq_nmod_mat_t mat, const fq_nmod_ctx_t ctx) + + Returns the number of columns in \code{mat}. + +void fq_nmod_mat_swap(fq_nmod_mat_t mat1, fq_nmod_mat_t mat2, + const fq_nmod_ctx_t ctx) + + Swaps two matrices. The dimensions of \code{mat1} and \code{mat2} + are allowed to be different. + +void fq_nmod_mat_zero(fq_nmod_mat_t mat, const fq_nmod_ctx_t ctx) + + Sets all entries of \code{mat} to 0. + + +******************************************************************************* + + Printing + +******************************************************************************* + +void fq_nmod_mat_print_pretty(const fq_nmod_mat_t mat, const fq_nmod_ctx_t ctx) + + Pretty-prints \code{mat} to \code{stdout}. A header is printed + followed by the rows enclosed in brackets. + +int fq_nmod_mat_fprint_pretty(FILE * file, const fq_nmod_mat_t mat, + const fq_nmod_ctx_t ctx) + + Pretty-prints \code{mat} to \code{file}. A header is printed + followed by the rows enclosed in brackets. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + +void fq_nmod_mat_print(const fq_nmod_mat_t mat, const fq_nmod_ctx_t ctx) + + Prints \code{mat} to \code{stdout}. A header is printed followed + by the rows enclosed in brackets. + +int fq_nmod_mat_fprint(FILE * file, const fq_nmod_mat_t mat, + const fq_nmod_ctx_t ctx) + + Prints \code{mat} to \code{file}. A header is printed followed by + the rows enclosed in brackets. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + +******************************************************************************* + + Window + +******************************************************************************* + +void fq_nmod_mat_window_init(fq_nmod_mat_t window, const fq_nmod_mat_t mat, + slong r1, slong c1, slong r2, slong c2, + const fq_nmod_ctx_t ctx) + + Initializes the matrix \code{window} to be an \code{r2 - r1} by + \code{c2 - c1} submatrix of \code{mat} whose \code{(0,0)} entry + is the \code{(r1, c1)} entry of \code{mat}. The memory for the + elements of \code{window} is shared with \code{mat}. + + +void fq_nmod_mat_window_clear(fq_nmod_mat_t window, const fq_nmod_ctx_t ctx) + + Clears the matrix \code{window} and releases any memory that it + uses. Note that the memory to the underlying matrix that + \code{window} points to is not freed. + + +******************************************************************************* + + Random matrix generation + +******************************************************************************* + +void fq_nmod_mat_randtest(fq_nmod_mat_t mat, flint_rand_t state, + const fq_nmod_ctx_t ctx) + + Sets the elements of \code{mat} to random elements of + $\mathbb{F}_{q}$, given by \code{ctx}. + +int fq_nmod_mat_randpermdiag(fq_nmod_mat_t mat, fq_nmod_struct * diag, slong n, + flint_rand_t state, const fq_nmod_ctx_t ctx) + + Sets \code{mat} to a random permutation of the diagonal matrix + with $n$ leading entries given by the vector \code{diag}. It is + assumed that the main diagonal of \code{mat} has room for at + least $n$ entries. + + Returns $0$ or $1$, depending on whether the permutation is even + or odd respectively. + +void fq_nmod_mat_randrank(fq_nmod_mat_t mat, slong rank, flint_rand_t state, + const fq_nmod_ctx_t ctx) + + Sets \code{mat} to a random sparse matrix with the given rank, + having exactly as many non-zero elements as the rank, with the + non-zero elements being uniformly random elements of + $\mathbb{F}_{q}$. + + The matrix can be transformed into a dense matrix with unchanged + rank by subsequently calling \code{fq_nmod_mat_randops()}. + +void fq_nmod_mat_randops(fq_nmod_mat_t mat, slong count, flint_rand_t state, + const fq_nmod_ctx_t ctx) + + Randomises \code{mat} by performing elementary row or column + operations. More precisely, at most \code{count} random additions + or subtractions of distinct rows and columns will be performed. + This leaves the rank (and for square matrices, determinant) + unchanged. + +void fq_nmod_mat_randtril(fq_nmod_mat_t mat, flint_rand_t state, int unit, + const fq_nmod_ctx_t ctx) + + Sets \code{mat} to a random lower triangular matrix. If + \code{unit} is 1, it will have ones on the main diagonal, + otherwise it will have random nonzero entries on the main + diagonal. + +void fq_nmod_mat_randtriu(fq_nmod_mat_t mat, flint_rand_t state, int unit, + x const fq_nmod_ctx_t ctx) + + Sets \code{mat} to a random upper triangular matrix. If + \code{unit} is 1, it will have ones on the main diagonal, + otherwise it will have random nonzero entries on the main + diagonal. + +******************************************************************************* + + Comparison + +******************************************************************************* + +int fq_nmod_mat_equal(fq_nmod_mat_t mat1, fq_nmod_mat_t mat2, + const fq_nmod_ctx_t ctx) + + Returns nonzero if mat1 and mat2 have the same dimensions and elements, + and zero otherwise. + +int fq_nmod_mat_is_zero(const fq_nmod_mat_t mat, const fq_nmod_ctx_t ctx) + + Returns a non-zero value if all entries \code{mat} are zero, and + otherwise returns zero. + +int fq_nmod_mat_is_empty(const fq_nmod_mat_t mat, const fq_nmod_ctx_t ctx) + + Returns a non-zero value if the number of rows or the number of + columns in \code{mat} is zero, and otherwise returns zero. + +int fq_nmod_mat_is_square(const fq_nmod_mat_t mat, const fq_nmod_ctx_t ctx) + + Returns a non-zero value if the number of rows is equal to the + number of columns in \code{mat}, and otherwise returns zero. + + + +******************************************************************************* + + Addition and subtraction + +******************************************************************************* + +void fq_nmod_mat_add(fq_nmod_mat_t C, const fq_nmod_mat_t A, + const fq_nmod_mat_t B, const fq_nmod_ctx_t ctx) + + Computes $C = A + B$. Dimensions must be identical. + +void fq_nmod_mat_sub(fq_nmod_mat_t C, const fq_nmod_mat_t A, + const fq_nmod_mat_t B, const fq_nmod_ctx_t ctx) + + Computes $C = A - B$. Dimensions must be identical. + +void fq_nmod_mat_neg(fq_nmod_mat_t A, const fq_nmod_mat_t B, + const fq_nmod_ctx_t ctx) + + Sets $B = -A$. Dimensions must be identical. + +******************************************************************************* + + Matrix multiplication + +******************************************************************************* + +void fq_nmod_mat_mul(fq_nmod_mat_t C, const fq_nmod_mat_t A, + const fq_nmod_mat_t B, const fq_nmod_ctx_t ctx) + + Sets $C = AB$. Dimensions must be compatible for matrix + multiplication. $C$ is not allowed to be aliased with $A$ or + $B$. This function automatically chooses between classical and + KS multiplication. + +void fq_nmod_mat_mul_classical(fq_nmod_mat_t C, const fq_nmod_mat_t A, + const fq_nmod_mat_t B, const fq_nmod_ctx_t ctx) + + Sets $C = AB$. Dimensions must be compatible for matrix multiplication. + $C$ is not allowed to be aliased with $A$ or $B$. Uses classical + matrix multiplication. + +void fq_nmod_mat_mul_KS(fq_nmod_mat_t C, const fq_nmod_mat_t A, + const fq_nmod_mat_t B, const fq_nmod_ctx_t ctx) + + Sets $C = AB$. Dimensions must be compatible for matrix + multiplication. $C$ is not allowed to be aliased with $A$ or + $B$. Uses Kronecker substitution to perform the multiplication + over the integers. + +void fq_nmod_mat_submul(fq_nmod_mat_t D, const fq_nmod_mat_t C, + const fq_nmod_mat_t A, const fq_nmod_mat_t B, + const fq_nmod_ctx_t ctx) + + Sets $D = C + AB$. $C$ and $D$ may be aliased with each other but + not with $A$ or $B$. + +******************************************************************************* + + LU decomposition + +******************************************************************************* + +slong fq_nmod_mat_lu(slong * P, fq_nmod_mat_t A, int rank_check, + const fq_nmod_ctx_t ctx) + + Computes a generalised LU decomposition $LU = PA$ of a given + matrix $A$, returning the rank of $A$. + + If $A$ is a nonsingular square matrix, it will be overwritten with + a unit diagonal lower triangular matrix $L$ and an upper + triangular matrix $U$ (the diagonal of $L$ will not be stored + explicitly). + + If $A$ is an arbitrary matrix of rank $r$, $U$ will be in row + echelon form having $r$ nonzero rows, and $L$ will be lower + triangular but truncated to $r$ columns, having implicit ones on + the $r$ first entries of the main diagonal. All other entries will + be zero. + + If a nonzero value for \code{rank_check} is passed, the function + will abandon the output matrix in an undefined state and return 0 + if $A$ is detected to be rank-deficient. + + This function calls \code{fq_nmod_mat_lu_recursive}. + +slong fq_nmod_mat_lu_classical(slong * P, fq_nmod_mat_t A, int rank_check, + const fq_nmod_ctx_t ctx) + + Computes a generalised LU decomposition $LU = PA$ of a given + matrix $A$, returning the rank of $A$. The behavior of this + function is identical to that of \code{fq_nmod_mat_lu}. Uses Gaussian + elimination. + +slong fq_nmod_mat_lu_recursive(slong * P, fq_nmod_mat_t A, int rank_check, + const fq_nmod_ctx_t ctx) + + Computes a generalised LU decomposition $LU = PA$ of a given + matrix $A$, returning the rank of $A$. The behavior of this + function is identical to that of \code{fq_nmod_mat_lu}. Uses recursive + block decomposition, switching to classical Gaussian elimination + for sufficiently small blocks. + +******************************************************************************* + + Reduced row echelon form + +******************************************************************************* + +slong fq_nmod_mat_rref(fq_nmod_mat_t A, const fq_nmod_ctx_t ctx) + + Puts $A$ in reduced row echelon form and returns the rank of $A$. + + The rref is computed by first obtaining an unreduced row echelon + form via LU decomposition and then solving an additional + triangular system. + +******************************************************************************* + + Triangular solving + +******************************************************************************* + +void fq_nmod_mat_solve_tril(fq_nmod_mat_t X, const fq_nmod_mat_t L, + const fq_nmod_mat_t B, int unit, + const fq_nmod_ctx_t ctx) + + Sets $X = L^{-1} B$ where $L$ is a full rank lower triangular + square matrix. If \code{unit} = 1, $L$ is assumed to have ones on + its main diagonal, and the main diagonal will not be read. $X$ + and $B$ are allowed to be the same matrix, but no other aliasing + is allowed. Automatically chooses between the classical and + recursive algorithms. + +void fq_nmod_mat_solve_tril_classical(fq_nmod_mat_t X, const fq_nmod_mat_t L, + const fq_nmod_mat_t B, int unit, + const fq_nmod_ctx_t ctx) + + Sets $X = L^{-1} B$ where $L$ is a full rank lower triangular + square matrix. If \code{unit} = 1, $L$ is assumed to have ones on + its main diagonal, and the main diagonal will not be read. $X$ + and $B$ are allowed to be the same matrix, but no other aliasing + is allowed. Uses forward substitution. + +void fq_nmod_mat_solve_tril_recursive(fq_nmod_mat_t X, const fq_nmod_mat_t L, + const fq_nmod_mat_t B, int unit, + const fq_nmod_ctx_t ctx) + + Sets $X = L^{-1} B$ where $L$ is a full rank lower triangular + square matrix. If \code{unit} = 1, $L$ is assumed to have ones on + its main diagonal, and the main diagonal will not be read. $X$ + and $B$ are allowed to be the same matrix, but no other aliasing + is allowed. + + Uses the block inversion formula + + $$ + \begin{pmatrix} A & 0 \\ C & D \end{pmatrix}^{-1} + \begin{pmatrix} X \\ Y \end{pmatrix} = + \begin{pmatrix} A^{-1} X \\ D^{-1} ( Y - C A^{-1} X ) \end{pmatrix} + $$ + + to reduce the problem to matrix multiplication and triangular + solving of smaller systems. + +void fq_nmod_mat_solve_triu(fq_nmod_mat_t X, const fq_nmod_mat_t U, + const fq_nmod_mat_t B, int unit, + const fq_nmod_ctx_t ctx) + + Sets $X = U^{-1} B$ where $U$ is a full rank upper triangular + square matrix. If \code{unit} = 1, $U$ is assumed to have ones on + its main diagonal, and the main diagonal will not be read. $X$ + and $B$ are allowed to be the same matrix, but no other aliasing + is allowed. Automatically chooses between the classical and + recursive algorithms. + +void fq_nmod_mat_solve_triu_classical(fq_nmod_mat_t X, const fq_nmod_mat_t U, + const fq_nmod_mat_t B, int unit, + const fq_nmod_ctx_t ctx) + + Sets $X = U^{-1} B$ where $U$ is a full rank upper triangular + square matrix. If \code{unit} = 1, $U$ is assumed to have ones on + its main diagonal, and the main diagonal will not be read. $X$ + and $B$ are allowed to be the same matrix, but no other aliasing + is allowed. Uses forward substitution. + +void fq_nmod_mat_solve_triu_recursive(fq_nmod_mat_t X, const fq_nmod_mat_t U, + const fq_nmod_mat_t B, int unit, + const fq_nmod_ctx_t ctx) + + Sets $X = U^{-1} B$ where $U$ is a full rank upper triangular + square matrix. If \code{unit} = 1, $U$ is assumed to have ones on + its main diagonal, and the main diagonal will not be read. $X$ + and $B$ are allowed to be the same matrix, but no other aliasing + is allowed. + + Uses the block inversion formula + + $$ + \begin{pmatrix} A & B \\ 0 & D \end{pmatrix}^{-1} + \begin{pmatrix} X \\ Y \end{pmatrix} = + \begin{pmatrix} A^{-1} (X - B D^{-1} Y) \\ D^{-1} Y \end{pmatrix} + $$ + + to reduce the problem to matrix multiplication and triangular + solving of smaller systems. diff --git a/external/flint-2.4.3/fq_nmod_mat/equal.c b/external/flint-2.4.3/fq_nmod_mat/equal.c new file mode 100644 index 0000000..36f12fb --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_mat/equal.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_mat_templates/equal.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_mat/fprint.c b/external/flint-2.4.3/fq_nmod_mat/fprint.c new file mode 100644 index 0000000..fdaa5e2 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_mat/fprint.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_mat_templates/fprint.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_mat/init.c b/external/flint-2.4.3/fq_nmod_mat/init.c new file mode 100644 index 0000000..836234c --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_mat/init.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_mat_templates/init.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_mat/init_set.c b/external/flint-2.4.3/fq_nmod_mat/init_set.c new file mode 100644 index 0000000..d6de1ac --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_mat/init_set.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_mat_templates/init_set.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_mat/is_zero.c b/external/flint-2.4.3/fq_nmod_mat/is_zero.c new file mode 100644 index 0000000..b567241 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_mat/is_zero.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_mat_templates/is_zero.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_mat/lu.c b/external/flint-2.4.3/fq_nmod_mat/lu.c new file mode 100644 index 0000000..1b6e94c --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_mat/lu.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_mat_templates/lu.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_mat/lu_classical.c b/external/flint-2.4.3/fq_nmod_mat/lu_classical.c new file mode 100644 index 0000000..7cdea7d --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_mat/lu_classical.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_mat_templates/lu_classical.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_mat/lu_recursive.c b/external/flint-2.4.3/fq_nmod_mat/lu_recursive.c new file mode 100644 index 0000000..7283118 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_mat/lu_recursive.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_mat_templates/lu_recursive.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_mat/mul.c b/external/flint-2.4.3/fq_nmod_mat/mul.c new file mode 100644 index 0000000..42382ac --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_mat/mul.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_mat_templates/mul.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_mat/mul_KS.c b/external/flint-2.4.3/fq_nmod_mat/mul_KS.c new file mode 100644 index 0000000..c61b077 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_mat/mul_KS.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_mat_templates/mul_KS.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_mat/mul_classical.c b/external/flint-2.4.3/fq_nmod_mat/mul_classical.c new file mode 100644 index 0000000..747e7a1 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_mat/mul_classical.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_mat_templates/mul_classical.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_mat/neg.c b/external/flint-2.4.3/fq_nmod_mat/neg.c new file mode 100644 index 0000000..cfb16e1 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_mat/neg.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_mat_templates/neg.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_mat/randops.c b/external/flint-2.4.3/fq_nmod_mat/randops.c new file mode 100644 index 0000000..58a8d31 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_mat/randops.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_mat_templates/randops.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_mat/randpermdiag.c b/external/flint-2.4.3/fq_nmod_mat/randpermdiag.c new file mode 100644 index 0000000..319c517 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_mat/randpermdiag.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_mat_templates/randpermdiag.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_mat/randrank.c b/external/flint-2.4.3/fq_nmod_mat/randrank.c new file mode 100644 index 0000000..d1a10a2 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_mat/randrank.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_mat_templates/randrank.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_mat/randtest.c b/external/flint-2.4.3/fq_nmod_mat/randtest.c new file mode 100644 index 0000000..fa365c4 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_mat/randtest.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_mat_templates/randtest.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_mat/randtril.c b/external/flint-2.4.3/fq_nmod_mat/randtril.c new file mode 100644 index 0000000..4d84ebb --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_mat/randtril.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_mat_templates/randtril.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_mat/randtriu.c b/external/flint-2.4.3/fq_nmod_mat/randtriu.c new file mode 100644 index 0000000..037ccae --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_mat/randtriu.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_mat_templates/randtriu.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_mat/rref.c b/external/flint-2.4.3/fq_nmod_mat/rref.c new file mode 100644 index 0000000..565518d --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_mat/rref.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_mat_templates/rref.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_mat/set.c b/external/flint-2.4.3/fq_nmod_mat/set.c new file mode 100644 index 0000000..86d5958 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_mat/set.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_mat_templates/set.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_mat/solve_tril.c b/external/flint-2.4.3/fq_nmod_mat/solve_tril.c new file mode 100644 index 0000000..2c2aec6 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_mat/solve_tril.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_mat_templates/solve_tril.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_mat/solve_tril_classical.c b/external/flint-2.4.3/fq_nmod_mat/solve_tril_classical.c new file mode 100644 index 0000000..a24de53 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_mat/solve_tril_classical.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_mat_templates/solve_tril_classical.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_mat/solve_tril_recursive.c b/external/flint-2.4.3/fq_nmod_mat/solve_tril_recursive.c new file mode 100644 index 0000000..4aa0971 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_mat/solve_tril_recursive.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_mat_templates/solve_tril_recursive.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_mat/solve_triu.c b/external/flint-2.4.3/fq_nmod_mat/solve_triu.c new file mode 100644 index 0000000..d489643 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_mat/solve_triu.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_mat_templates/solve_triu.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_mat/solve_triu_classical.c b/external/flint-2.4.3/fq_nmod_mat/solve_triu_classical.c new file mode 100644 index 0000000..322a96b --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_mat/solve_triu_classical.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_mat_templates/solve_triu_classical.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_mat/solve_triu_recursive.c b/external/flint-2.4.3/fq_nmod_mat/solve_triu_recursive.c new file mode 100644 index 0000000..c395000 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_mat/solve_triu_recursive.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_mat_templates/solve_triu_recursive.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_mat/sub.c b/external/flint-2.4.3/fq_nmod_mat/sub.c new file mode 100644 index 0000000..1aa8c45 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_mat/sub.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_mat_templates/sub.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_mat/submul.c b/external/flint-2.4.3/fq_nmod_mat/submul.c new file mode 100644 index 0000000..c1c2417 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_mat/submul.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_mat_templates/submul.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_mat/swap.c b/external/flint-2.4.3/fq_nmod_mat/swap.c new file mode 100644 index 0000000..84c7ad3 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_mat/swap.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_mat_templates/swap.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_mat/test/t-add_sub.c b/external/flint-2.4.3/fq_nmod_mat/test/t-add_sub.c new file mode 100644 index 0000000..10d1bb6 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_mat/test/t-add_sub.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_mat_templates/test/t-add_sub.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_mat/test/t-equal.c b/external/flint-2.4.3/fq_nmod_mat/test/t-equal.c new file mode 100644 index 0000000..bedce84 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_mat/test/t-equal.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_mat_templates/test/t-equal.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_mat/test/t-is_zero.c b/external/flint-2.4.3/fq_nmod_mat/test/t-is_zero.c new file mode 100644 index 0000000..2872143 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_mat/test/t-is_zero.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_mat_templates/test/t-is_zero.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_mat/test/t-lu_classical.c b/external/flint-2.4.3/fq_nmod_mat/test/t-lu_classical.c new file mode 100644 index 0000000..40b7f9c --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_mat/test/t-lu_classical.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_mat_templates/test/t-lu_classical.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_mat/test/t-lu_recursive.c b/external/flint-2.4.3/fq_nmod_mat/test/t-lu_recursive.c new file mode 100644 index 0000000..034b992 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_mat/test/t-lu_recursive.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_mat_templates/test/t-lu_recursive.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_mat/test/t-mul.c b/external/flint-2.4.3/fq_nmod_mat/test/t-mul.c new file mode 100644 index 0000000..43d3854 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_mat/test/t-mul.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_mat_templates/test/t-mul.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_mat/test/t-mul_KS.c b/external/flint-2.4.3/fq_nmod_mat/test/t-mul_KS.c new file mode 100644 index 0000000..44a061c --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_mat/test/t-mul_KS.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_mat_templates/test/t-mul_KS.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_mat/test/t-rref.c b/external/flint-2.4.3/fq_nmod_mat/test/t-rref.c new file mode 100644 index 0000000..2bce631 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_mat/test/t-rref.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_mat_templates/test/t-rref.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_mat/test/t-solve_tril.c b/external/flint-2.4.3/fq_nmod_mat/test/t-solve_tril.c new file mode 100644 index 0000000..27fcf38 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_mat/test/t-solve_tril.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_mat_templates/test/t-solve_tril.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_mat/test/t-solve_tril_classical.c b/external/flint-2.4.3/fq_nmod_mat/test/t-solve_tril_classical.c new file mode 100644 index 0000000..8460f64 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_mat/test/t-solve_tril_classical.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_mat_templates/test/t-solve_tril_classical.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_mat/test/t-solve_tril_recursive.c b/external/flint-2.4.3/fq_nmod_mat/test/t-solve_tril_recursive.c new file mode 100644 index 0000000..00e6ab5 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_mat/test/t-solve_tril_recursive.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_mat_templates/test/t-solve_tril_recursive.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_mat/test/t-solve_triu.c b/external/flint-2.4.3/fq_nmod_mat/test/t-solve_triu.c new file mode 100644 index 0000000..275ebdb --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_mat/test/t-solve_triu.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_mat_templates/test/t-solve_triu.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_mat/test/t-solve_triu_classical.c b/external/flint-2.4.3/fq_nmod_mat/test/t-solve_triu_classical.c new file mode 100644 index 0000000..11c69b4 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_mat/test/t-solve_triu_classical.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_mat_templates/test/t-solve_triu_classical.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_mat/test/t-solve_triu_recursive.c b/external/flint-2.4.3/fq_nmod_mat/test/t-solve_triu_recursive.c new file mode 100644 index 0000000..05f4fe6 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_mat/test/t-solve_triu_recursive.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_mat_templates/test/t-solve_triu_recursive.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_mat/test/t-submul.c b/external/flint-2.4.3/fq_nmod_mat/test/t-submul.c new file mode 100644 index 0000000..d0101ee --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_mat/test/t-submul.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_mat_templates/test/t-submul.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_mat/test/t-zero.c b/external/flint-2.4.3/fq_nmod_mat/test/t-zero.c new file mode 100644 index 0000000..f8141ce --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_mat/test/t-zero.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_mat_templates/test/t-zero.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_mat/window_clear.c b/external/flint-2.4.3/fq_nmod_mat/window_clear.c new file mode 100644 index 0000000..11e8fe5 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_mat/window_clear.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_mat_templates/window_clear.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_mat/window_init.c b/external/flint-2.4.3/fq_nmod_mat/window_init.c new file mode 100644 index 0000000..225bb4c --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_mat/window_init.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_mat_templates/window_init.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_mat/zero.c b/external/flint-2.4.3/fq_nmod_mat/zero.c new file mode 100644 index 0000000..c1a8043 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_mat/zero.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_mat_templates/zero.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly.h b/external/flint-2.4.3/fq_nmod_poly.h new file mode 100644 index 0000000..ccf19b5 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly.h @@ -0,0 +1,53 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Andres Goens + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#ifndef FQ_NMOD_POLY_H +#define FQ_NMOD_POLY_H + +#include "fq_nmod.h" +#include "fq_nmod_mat.h" + +#define FQ_NMOD_POLY_DIVREM_DIVCONQUER_CUTOFF 16 +#define FQ_NMOD_COMPOSE_MOD_LENH_CUTOFF 6 +#define FQ_NMOD_COMPOSE_MOD_PREINV_LENH_CUTOFF 6 +#define FQ_NMOD_MUL_CLASSICAL_CUTOFF 6 +#define FQ_NMOD_SQR_CLASSICAL_CUTOFF 6 +#define FQ_NMOD_MULLOW_CLASSICAL_CUTOFF 6 + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates.h" +#undef CAP_T +#undef T + +#include "fq_nmod_poly_factor.h" + +#endif diff --git a/external/flint-2.4.3/fq_nmod_poly/add.c b/external/flint-2.4.3/fq_nmod_poly/add.c new file mode 100644 index 0000000..196aeee --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/add.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/add.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/clear.c b/external/flint-2.4.3/fq_nmod_poly/clear.c new file mode 100644 index 0000000..1d7fb6e --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/clear.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/clear.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/compose.c b/external/flint-2.4.3/fq_nmod_poly/compose.c new file mode 100644 index 0000000..fb3f62d --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/compose.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/compose.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/compose_divconquer.c b/external/flint-2.4.3/fq_nmod_poly/compose_divconquer.c new file mode 100644 index 0000000..dc2f6c2 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/compose_divconquer.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/compose_divconquer.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/compose_horner.c b/external/flint-2.4.3/fq_nmod_poly/compose_horner.c new file mode 100644 index 0000000..c7557d9 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/compose_horner.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/compose_horner.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/compose_mod.c b/external/flint-2.4.3/fq_nmod_poly/compose_mod.c new file mode 100644 index 0000000..c62dee5 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/compose_mod.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/compose_mod.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/compose_mod_brent_kung.c b/external/flint-2.4.3/fq_nmod_poly/compose_mod_brent_kung.c new file mode 100644 index 0000000..1de3e7c --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/compose_mod_brent_kung.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/compose_mod_brent_kung.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/compose_mod_brent_kung_precomp_preinv.c b/external/flint-2.4.3/fq_nmod_poly/compose_mod_brent_kung_precomp_preinv.c new file mode 100644 index 0000000..dad4c46 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/compose_mod_brent_kung_precomp_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/compose_mod_brent_kung_precomp_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/compose_mod_brent_kung_preinv.c b/external/flint-2.4.3/fq_nmod_poly/compose_mod_brent_kung_preinv.c new file mode 100644 index 0000000..c7118c7 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/compose_mod_brent_kung_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/compose_mod_brent_kung_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/compose_mod_horner.c b/external/flint-2.4.3/fq_nmod_poly/compose_mod_horner.c new file mode 100644 index 0000000..f17f6d4 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/compose_mod_horner.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/compose_mod_horner.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/compose_mod_horner_preinv.c b/external/flint-2.4.3/fq_nmod_poly/compose_mod_horner_preinv.c new file mode 100644 index 0000000..b616535 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/compose_mod_horner_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/compose_mod_horner_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/compose_mod_preinv.c b/external/flint-2.4.3/fq_nmod_poly/compose_mod_preinv.c new file mode 100644 index 0000000..2b6d461 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/compose_mod_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/compose_mod_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/deflate.c b/external/flint-2.4.3/fq_nmod_poly/deflate.c new file mode 100644 index 0000000..6b48b28 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/deflate.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/deflate.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/deflation.c b/external/flint-2.4.3/fq_nmod_poly/deflation.c new file mode 100644 index 0000000..8b2b1ca --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/deflation.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/deflation.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/derivative.c b/external/flint-2.4.3/fq_nmod_poly/derivative.c new file mode 100644 index 0000000..08dbedf --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/derivative.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/derivative.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/div_basecase.c b/external/flint-2.4.3/fq_nmod_poly/div_basecase.c new file mode 100644 index 0000000..ad5f362 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/div_basecase.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/div_basecase.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/div_newton_n_preinv.c b/external/flint-2.4.3/fq_nmod_poly/div_newton_n_preinv.c new file mode 100644 index 0000000..31789ea --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/div_newton_n_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/div_newton_n_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/divides.c b/external/flint-2.4.3/fq_nmod_poly/divides.c new file mode 100644 index 0000000..212023d --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/divides.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/divides.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/divrem_basecase.c b/external/flint-2.4.3/fq_nmod_poly/divrem_basecase.c new file mode 100644 index 0000000..d22c732 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/divrem_basecase.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/divrem_basecase.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/divrem_divconquer.c b/external/flint-2.4.3/fq_nmod_poly/divrem_divconquer.c new file mode 100644 index 0000000..1559209 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/divrem_divconquer.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/divrem_divconquer.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/divrem_divconquer_recursive.c b/external/flint-2.4.3/fq_nmod_poly/divrem_divconquer_recursive.c new file mode 100644 index 0000000..59807ca --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/divrem_divconquer_recursive.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/divrem_divconquer_recursive.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/divrem_newton_n_preinv.c b/external/flint-2.4.3/fq_nmod_poly/divrem_newton_n_preinv.c new file mode 100644 index 0000000..83445d3 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/divrem_newton_n_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/divrem_newton_n_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/doc/fq_nmod_poly.txt b/external/flint-2.4.3/fq_nmod_poly/doc/fq_nmod_poly.txt new file mode 100644 index 0000000..8633945 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/doc/fq_nmod_poly.txt @@ -0,0 +1,1596 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009, 2008 William Hart + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012,2013 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +******************************************************************************* + + Memory management + +******************************************************************************* + +void fq_nmod_poly_init(fq_nmod_poly_t poly, const fq_nmod_ctx_t ctx) + + Initialises \code{poly} for use, with context ctx, and setting its + length to zero. A corresponding call to \code{fq_nmod_poly_clear()} + must be made after finishing with the \code{fq_nmod_poly_t} to free the + memory used by the polynomial. + +void fq_nmod_poly_init2(fq_nmod_poly_t poly, slong alloc, + const fq_nmod_ctx_t ctx) + + Initialises \code{poly} with space for at least \code{alloc} + coefficients and sets the length to zero. The allocated + coefficients are all set to zero. A corresponding call to + \code{fq_nmod_poly_clear()} must be made after finishing with the + \code{fq_nmod_poly_t} to free the memory used by the polynomial. + +void fq_nmod_poly_realloc(fq_nmod_poly_t poly, slong alloc, + const fq_nmod_ctx_t ctx) + + Reallocates the given polynomial to have space for \code{alloc} + coefficients. If \code{alloc} is zero the polynomial is cleared + and then reinitialised. If the current length is greater than + \code{alloc} the polynomial is first truncated to length + \code{alloc}. + +void fq_nmod_poly_fit_length(fq_nmod_poly_t poly, slong len, + const fq_nmod_ctx_t ctx) + + If \code{len} is greater than the number of coefficients currently + allocated, then the polynomial is reallocated to have space for at + least \code{len} coefficients. No data is lost when calling this + function. + + The function efficiently deals with the case where + \code{fit_length} is called many times in small increments by at + least doubling the number of allocated coefficients when length is + larger than the number of coefficients currently allocated. + +void _fq_nmod_poly_set_length(fq_nmod_poly_t poly, slong newlen, + const fq_nmod_ctx_t ctx) + + Sets the coefficients of \code{poly} beyond \code{len} to zero and + sets the length of \code{poly} to \code{len}. + +void fq_nmod_poly_clear(fq_nmod_poly_t poly, const fq_nmod_ctx_t ctx) + + Clears the given polynomial, releasing any memory used. It must + be reinitialised in order to be used again. + +void _fq_nmod_poly_normalise(fq_nmod_poly_t poly, const fq_nmod_ctx_t ctx) + + Sets the length of \code{poly} so that the top coefficient is + non-zero. If all coefficients are zero, the length is set to + zero. This function is mainly used internally, as all functions + guarantee normalisation. + +void _fq_nmod_poly_normalise2(fq_nmod_struct *poly, slong *length, + const fq_nmod_ctx_t ctx) + + Sets the length \code{length} of \code{(poly,length)} so that the + top coefficient is non-zero. If all coefficients are zero, the + length is set to zero. This function is mainly used internally, as + all functions guarantee normalisation. + +void fq_nmod_poly_truncate(fq_nmod_poly_t poly, slong newlen, + const fq_nmod_ctx_t ctx) + + Truncates the polynomial to length at most~$n$. + +void _fq_nmod_poly_reverse(fq_nmod_struct* output, const fq_nmod_struct* input, + slong len, slong m, const fq_nmod_ctx_t ctx) + + Sets \code{output} to the reverse of \code{input}, which is of + length \code{len}, but thinking of it as a polynomial of + length~\code{m}, notionally zero-padded if necessary. The + length~\code{m} must be non-negative, but there are no other + restrictions. The polynomial \code{output} must have space for + \code{m} coefficients. + +void fq_nmod_poly_reverse(fq_nmod_poly_t output, const fq_nmod_poly_t input, + slong m, const fq_nmod_ctx_t ctx) + + Sets \code{output} to the reverse of \code{input}, thinking of it + as a polynomial of length~\code{m}, notionally zero-padded if + necessary). The length~\code{m} must be non-negative, but there + are no other restrictions. The output polynomial will be set to + length~\code{m} and then normalised. + +******************************************************************************* + + Polynomial parameters + +******************************************************************************* + +long fq_nmod_poly_degree(fq_nmod_poly_t poly, const fq_nmod_ctx_t ctx) + + Returns the degree of the polynomial \code{poly}. + +long fq_nmod_poly_length(fq_nmod_poly_t poly, const fq_nmod_ctx_t ctx) + + Returns the length of the polynomial \code{poly}. + +fq_nmod_struct * fq_nmod_poly_lead(const fq_nmod_poly_t poly, + const fq_nmod_ctx_t ctx) + + Returns a pointer to the leading coefficient of \code{poly}, or + \code{NULL} if \code{poly} is the zero polynomial. + +******************************************************************************* + + Randomisation + +******************************************************************************* + +void fq_nmod_poly_randtest(fq_nmod_poly_t f, flint_rand_t state, + slong len, const fq_nmod_ctx_t ctx) + + Sets $f$ to a random polynomial of length at most \code{len} + with entries in the field described by \code{ctx}. + +void fq_nmod_poly_randtest_not_zero(fq_nmod_poly_t f, flint_rand_t state, + slong len, const fq_nmod_ctx_t ctx) + + Same as \code{fq_nmod_poly_randtest} but guarantees that the polynomial + is not zero. + +void fq_nmod_poly_randtest_monic(fq_nmod_poly_t f, flint_rand_t state, + slong len, const fq_nmod_ctx_t ctx) + + Sets $f$ to a random monic polynomial of length \code{len} with + entries in the field described by \code{ctx}. + +void fq_nmod_poly_randtest_irreducible(fq_nmod_poly_t f, flint_rand_t state, + slong len, const fq_nmod_ctx_t ctx) + + Sets $f$ to a random monic, irreducible polynomial of length + \code{len} with entries in the field described by \code{ctx}. + +******************************************************************************* + + Assignment and basic manipulation + +******************************************************************************* + +void _fq_nmod_poly_set(fq_nmod_struct *rop, const fq_nmod_struct *op, slong len, + const fq_nmod_ctx_t ctx) + + Sets \code{(rop, len}) to \code{(op, len)}. + +void fq_nmod_poly_set(fq_nmod_poly_t poly1, const fq_nmod_poly_t poly2, + const fq_nmod_ctx_t ctx) + + Sets the polynomial \code{poly1} to the polynomial \code{poly2}. + +void fq_nmod_poly_set_fq_nmod(fq_nmod_poly_t poly, const fq_nmod_t c, + const fq_nmod_ctx_t ctx) + + Sets the polynomial \code{poly} to \code{c}. + +void fq_nmod_poly_swap(fq_nmod_poly_t op1, fq_nmod_poly_t op2, + const fq_nmod_ctx_t ctx) + + Swaps the two polynomials \code{op1} and \code{op2}. + +void _fq_nmod_poly_zero(fq_nmod_struct *rop, slong len, const fq_nmod_ctx_t ctx) + + Sets \code{(rop, len)} to the zero polynomial. + +void fq_nmod_poly_zero(fq_nmod_poly_t poly, const fq_nmod_ctx_t ctx) + + Sets \code{poly} to the zero polynomial. + +void void fq_nmod_poly_one(fq_nmod_poly_t poly, const fq_nmod_ctx_t ctx) + + Sets \code{poly} to the constant polynomial~$1$. + +void void fq_nmod_poly_gen(fq_nmod_poly_t poly, const fq_nmod_ctx_t ctx) + + Sets \code{poly} to the polynomial~$x$. + +void fq_nmod_poly_make_monic(fq_nmod_poly_t rop, const fq_nmod_poly_t op, + const fq_nmod_ctx_t ctx) + + Sets \code{rop} to \code{op}, normed to have leading coefficient 1. + +void _fq_nmod_poly_make_monic(fq_nmod_struct *rop, const fq_nmod_struct *op, + slong length, const fq_nmod_ctx_t ctx) + + Sets \code{rop} to \code{(op,length)}, normed to have leading coefficient 1. + Assumes that \code{rop} has enough space for the polynomial, assumes that + \code{op} is not zero (and thus has an invertible leading coefficient). + +******************************************************************************* + + Getting and setting coefficients + +******************************************************************************* + +void fq_nmod_poly_get_coeff(fq_nmod_t x, const fq_nmod_poly_t poly, slong n, + const fq_nmod_ctx_t ctx) + + Sets $x$ to the coefficient of $X^n$ in \code{poly}. + +void fq_nmod_poly_set_coeff(fq_nmod_poly_t poly, slong n, const fq_nmod_t x, + const fq_nmod_ctx_t ctx) + + Sets the coefficient of $X^n$ in \code{poly} to $x$. + +void +fq_nmod_poly_set_coeff_fmpz(fq_nmod_poly_t poly, slong n, const fmpz_t x, + const fq_nmod_ctx_t ctx) + + Sets the coefficient of $X^n$ in the polynomial to $x$, + assuming $n \geq 0$. + +******************************************************************************* + + Comparison + +******************************************************************************* + +int fq_nmod_poly_equal(const fq_nmod_poly_t poly1, const fq_nmod_poly_t poly2, + const fq_nmod_ctx_t ctx) + + Returns whether the two polynomials \code{poly1} and \code{poly2} + are equal. + +int fq_nmod_poly_is_zero(const fq_nmod_poly_t poly, const fq_nmod_ctx_t ctx) + + Returns whether the polynomial \code{poly} is the zero polynomial. + +int fq_nmod_poly_is_one(const fq_nmod_poly_t op) + + Returns whether the polynomial \code{poly} is equal + to the constant polynomial~$1$. + +int fq_nmod_poly_is_gen(const fq_nmod_poly_t op, const fq_nmod_ctx_t ctx) + + Returns whether the polynomial \code{poly} is equal + to the polynomial~$x$. + +int fq_nmod_poly_is_unit(const fq_nmod_poly_t op, const fq_nmod_ctx_t ctx) + + Returns whether the polynomial \code{poly} is a unit in the polynomial + ring $\mathbf{F}_q[X]$, i.e. if it has degree $0$ and is non-zero. + +int fq_nmod_poly_equal_fq_nmod(const fq_nmod_poly_t poly, const fq_nmod_t c, + const fq_nmod_ctx_t ctx) + + Returns whether the polynomial \code{poly} is equal the (constant) + $\mathbf{F}_q$ element \code{c} + +******************************************************************************* + + Addition and subtraction + +******************************************************************************* + +void _fq_nmod_poly_add(fq_nmod_struct *res, + const fq_nmod_struct *poly1, slong len1, + const fq_nmod_struct *poly2, slong len2, + const fq_nmod_ctx_t ctx) + + Sets \code{res} to the sum of \code{(poly1,len1)} and \code{(poly2,len2)}. + +void fq_nmod_poly_add(fq_nmod_poly_t res, const fq_nmod_poly_t poly1, + const fq_nmod_poly_t poly2, const fq_nmod_ctx_t ctx) + + Sets \code{res} to the sum of \code{poly1} and \code{poly2}. + +void _fq_nmod_poly_sub(fq_nmod_struct *res, + const fq_nmod_struct *poly1, slong len1, + const fq_nmod_struct *poly2, slong len2, + const fq_nmod_ctx_t ctx) + + Sets \code{res} to the difference of \code{(poly1,len1)} and + \code{(poly2,len2)}. + +void fq_nmod_poly_sub(fq_nmod_poly_t res, const fq_nmod_poly_t poly1, + const fq_nmod_poly_t poly2, const fq_nmod_ctx_t ctx) + + Sets \code{res} to the difference of \code{poly1} and \code{poly2}. + +void _fq_nmod_poly_neg(fq_nmod_struct *rop, const fq_nmod_struct *op, slong len, + const fq_nmod_ctx_t ctx) + + Sets \code{res} to the additive inverse of \code{(poly,len)}. + +void fq_nmod_poly_neg(fq_nmod_poly_t res, const fq_nmod_poly_t poly, + const fq_nmod_ctx_t ctx) + + Sets \code{res} to the additive inverse of \code{poly}. + +******************************************************************************* + + Scalar multiplication and division + +******************************************************************************* + +void _fq_nmod_poly_scalar_mul_fq_nmod(fq_nmod_struct *rop, + const fq_nmod_struct *op, slong len, const fq_nmod_t x, + const fq_nmod_ctx_t ctx) + + Sets \code{(rop,len)} to the product of \code{(op,len)} by the + scalar \code{x}, in the context defined by \code{ctx}. + +void fq_nmod_poly_scalar_mul_fq_nmod(fq_nmod_poly_t rop, + const fq_nmod_poly_t op, const fq_nmod_t x, const fq_nmod_ctx_t ctx) + + Sets \code{(rop,len)} to the product of \code{(op,len)} by the + scalar \code{x}, in the context defined by \code{ctx}. + +void _fq_nmod_poly_scalar_addmul_fq_nmod(fq_nmod_struct *rop, + const fq_nmod_struct *op, slong len, const fq_nmod_t x, + const fq_nmod_ctx_t ctx) + + Adds to \code{(rop,len)} the product of \code{(op,len)} by the + scalar \code{x}, in the context defined by \code{ctx}. + In particular, assumes the same length for \code{op} and + \code{rop}. + +void fq_nmod_poly_scalar_addmul_fq_nmod(fq_nmod_poly_t rop, + const fq_nmod_poly_t op, const fq_nmod_t x, + const fq_nmod_ctx_t ctx) + + Adds to \code{rop} the product of \code{op} by the + scalar \code{x}, in the context defined by \code{ctx}. + +void _fq_nmod_poly_scalar_submul_fq_nmod(fq_nmod_struct *rop, + const fq_nmod_struct *op, slong len, const fq_nmod_t x, + const fq_nmod_ctx_t ctx) + + Substracts from \code{(rop,len)} the product of \code{(op,len)} by the + scalar \code{x}, in the context defined by \code{ctx}. + In particular, assumes the same length for \code{op} and + \code{rop}. + +void fq_nmod_poly_scalar_submul_fq_nmod(fq_nmod_poly_t rop, + const fq_nmod_poly_t op, const fq_nmod_t x, const fq_nmod_ctx_t ctx) + + Substracts from \code{rop} the product of \code{op} by the + scalar \code{x}, in the context defined by \code{ctx}. + +******************************************************************************* + + Multiplication + +******************************************************************************* + +void _fq_nmod_poly_mul_classical(fq_nmod_struct *rop, + const fq_nmod_struct *op1, slong len1, + const fq_nmod_struct *op2, slong len2, + const fq_nmod_ctx_t ctx) + + Sets \code{(rop, len1 + len2 - 1)} to the product of \code{(op1, len1)} + and \code{(op2, len2)}, assuming that \code{len1} is at least \code{len2} + and neither is zero. + + Permits zero padding. Does not support aliasing of \code{rop} + with either \code{op1} or \code{op2}. + +void fq_nmod_poly_mul_classical(fq_nmod_poly_t rop, + const fq_nmod_poly_t op1, + const fq_nmod_poly_t op2, + const fq_nmod_ctx_t ctx) + + Sets \code{rop} to the product of \code{op1} and \code{op2} + using classical polynomial multiplication. + +void _fq_nmod_poly_mul_reorder(fq_nmod_struct *rop, + const fq_nmod_struct *op1, slong len1, + const fq_nmod_struct *op2, slong len2, + const fq_nmod_ctx_t ctx) + + Sets \code{(rop, len1 + len2 - 1)} to the product of \code{(op1, len1)} + and \code{(op2, len2)}, assuming that \code{len1} and \code{len2} are + non-zero. + + Permits zero padding. Supports aliasing. + +void fq_nmod_poly_mul_reorder(fq_nmod_poly_t rop, + const fq_nmod_poly_t op1, const fq_nmod_poly_t op2, + const fq_nmod_ctx_t ctx) + + Sets \code{rop} to the product of \code{op1} and \code{op2}, + reordering the two indeterminates $X$ and $Y$ when viewing + the polynomials as elements of $\mathbf{F}_p[X,Y]$. + + Suppose $\mathbf{F}_q = \mathbf{F}_p[X]/ (f(X))$ and recall + that elements of $\mathbf{F}_q$ are internally represented + by elements of type \code{fmpz_poly}. For small degree extensions + but polynomials in $\mathbf{F}_q[Y]$ of large degree~$n$, we + change the representation to + + \begin{equation*} + \begin{split} + g(Y) & = \sum_{i=0}^{n} a_i(X) Y^i \\ + & = \sum_{j=0}^{d} \sum_{i=0}^{n} \text{Coeff}(a_i(X), j) Y^i. + \end{split} + \end{equation*} + + This allows us to use a poor algorithm (such as classical multiplication) + in the $X$-direction and leverage the existing fast integer + multiplication routines in the $Y$-direction where the polynomial + degree~$n$ is large. + +void _fq_nmod_poly_mul_KS(fq_nmod_struct *rop, const fq_nmod_struct *op1, + slong len1, const fq_nmod_struct *op2, slong len2, + const fq_nmod_ctx_t ctx) + + Sets \code{(rop, len1 + len2 - 1)} to the product of \code{(op1, len1)} + and \code{(op2, len2)}. + + Permits zero padding and places no assumptions on the + lengths \code{len1} and \code{len2}. Supports aliasing. + +void fq_nmod_poly_mul_KS(fq_nmod_poly_t rop, + const fq_nmod_poly_t op1, const fq_nmod_poly_t op2, + const fq_nmod_ctx_t ctx) + + Sets \code{rop} to the product of \code{op1} and \code{op2} + using Kronecker substitution, that is, by encoding each + coefficient in $\mathbf{F}_{q}$ as an integer and reducing + this problem to multiplying two polynomials over the integers. + +void _fq_nmod_poly_mul(fq_nmod_struct *rop, + const fq_nmod_struct *op1, slong len1, + const fq_nmod_struct *op2, slong len2, + const fq_nmod_ctx_t ctx) + + Sets \code{(rop, len1 + len2 - 1)} to the product of \code{(op1, len1)} + and \code{(op2, len2)}, choosing an appropriate algorithm. + + Permits zero padding. Does not support aliasing. + +void fq_nmod_poly_mul(fq_nmod_poly_t rop, + const fq_nmod_poly_t op1, const fq_nmod_poly_t op2, const fq_nmod_ctx_t ctx) + + Sets \code{rop} to the product of \code{op1} and \code{op2}, + choosing an appropriate algorithm. + +void _fq_nmod_poly_mullow_classical(fq_nmod_struct *rop, + const fq_nmod_struct *op1, slong len1, + const fq_nmod_struct *op2, slong len2, slong n, + const fq_nmod_ctx_t ctx) + + Sets \code{(res, n)} to the first $n$ coefficients of + \code{(poly1, len1)} multiplied by \code{(poly2, len2)}. + + Assumes \code{0 < n <= len1 + len2 - 1}. Assumes neither + \code{len1} nor \code{len2} is zero. + +void fq_nmod_poly_mullow_classical(fq_nmod_poly_t rop, + const fq_nmod_poly_t op1, const fq_nmod_poly_t op2, slong n, const fq_nmod_ctx_t ctx) + + Sets \code{res} to the product of \code{poly1} and \code{poly2}, + computed using the classical or schoolbook method. + +void _fq_nmod_poly_mullow_KS(fq_nmod_struct *rop, + const fq_nmod_struct *op1, slong len1, + const fq_nmod_struct *op2, slong len2, slong n, + const fq_nmod_ctx_t ctx) + + Sets \code{(res, n)} to the lowest $n$ coefficients of the product of + \code{(poly1, len1)} and \code{(poly2, len2)}. + + Assumes that \code{len1} and \code{len2} are positive, but does allow + for the polynomials to be zero-padded. The polynomials may be zero, + too. Assumes $n$ is positive. Supports aliasing between \code{res}, + \code{poly1} and \code{poly2}. + +void fq_nmod_poly_mullow_KS(fq_nmod_poly_t rop, + const fq_nmod_poly_t op1, const fq_nmod_poly_t op2, + slong n, const fq_nmod_ctx_t ctx) + + Sets \code{res} to the product of \code{poly1} and \code{poly2}. + +void _fq_nmod_poly_mullow(fq_nmod_struct *rop, + const fq_nmod_struct *op1, slong len1, + const fq_nmod_struct *op2, slong len2, slong n, + const fq_nmod_ctx_t ctx) + + Sets \code{(res, n)} to the lowest $n$ coefficients of the product of + \code{(poly1, len1)} and \code{(poly2, len2)}. + + Assumes \code{0 < n <= len1 + len2 - 1}. Allows for zero-padding in + the inputs. Does not support aliasing between the inputs and the output. + +void fq_nmod_poly_mullow(fq_nmod_poly_t rop, + const fq_nmod_poly_t op1, const fq_nmod_poly_t op2, slong n, + const fq_nmod_ctx_t ctx) + + Sets \code{res} to the lowest $n$ coefficients of the product of + \code{poly1} and \code{poly2}. + +void _fq_nmod_poly_mulmod(fq_nmod_struct* res, + const fq_nmod_struct* poly1, slong len1, + const fq_nmod_struct* poly2, slong len2, + const fq_nmod_struct* f, slong lenf, + const fq_nmod_ctx_t ctx) + + Sets \code{res} to the remainder of the product of \code{poly1} + and \code{poly2} upon polynomial division by \code{f}. + + It is required that \code{len1 + len2 - lenf > 0}, which is + equivalent to requiring that the result will actually be + reduced. Otherwise, simply use \code{_fq_nmod_poly_mul} instead. + + Aliasing of \code{f} and \code{res} is not permitted. + +void fq_nmod_poly_mulmod(fq_nmod_poly_t res,const fq_nmod_poly_t poly1, + const fq_nmod_poly_t poly2, const fq_nmod_poly_t f, + const fq_nmod_ctx_t ctx) + + Sets \code{res} to the remainder of the product of \code{poly1} + and \code{poly2} upon polynomial division by \code{f}. + +void _fq_nmod_poly_mulmod_preinv(fq_nmod_struct* res, + const fq_nmod_struct* poly1, slong len1, + const fq_nmod_struct* poly2, slong len2, + const fq_nmod_struct* f, slong lenf, + const fq_nmod_struct* finv, slong lenfinv, + const fq_nmod_ctx_t ctx) + + Sets \code{res} to the remainder of the product of \code{poly1} + and \code{poly2} upon polynomial division by \code{f}. + + It is required that \code{finv} is the inverse of the reverse of + \code{f} mod \code{x^lenf}. It is required that + \code{len1 + len2 - lenf > 0}, which is equivalent to requiring that + the result will actually be reduced. Otherwise, simply use + \code{_fq_nmod_poly_mul} instead. + + Aliasing of \code{f} or \code{finv} and \code{res} is not + permitted. + +void fq_nmod_poly_mulmod_preinv(fq_nmod_poly_t res, const fq_nmod_poly_t poly1, + const fq_nmod_poly_t poly2, + const fq_nmod_poly_t f, + const fq_nmod_poly_t finv, + const fq_nmod_ctx_t ctx) + + Sets \code{res} to the remainder of the product of \code{poly1} + and \code{poly2} upon polynomial division by \code{f}. \code{finv} + is the inverse of the reverse of \code{f}. + +******************************************************************************* + + Squaring + +******************************************************************************* + +void _fq_nmod_poly_sqr_classical(fq_nmod_struct *rop, + const fq_nmod_struct *op, slong len, + const fq_nmod_ctx_t ctx) + + Sets \code{(rop, 2*len - 1)} to the square of \code{(op, len)}, + assuming that \code{(op,len)} is not zero and using classical + polynomial multiplication. + + Permits zero padding. Does not support aliasing of \code{rop} + with either \code{op1} or \code{op2}. + +void fq_nmod_poly_sqr_classical(fq_nmod_poly_t rop, const fq_nmod_poly_t op, + const fq_nmod_ctx_t ctx) + + Sets \code{rop} to the square of \code{op} using classical + polynomial multiplication. + + +void _fq_nmod_poly_sqr_KS(fq_nmod_struct *rop, const fq_nmod_struct *op, + slong len, const fq_nmod_ctx_t ctx) + + Sets \code{(rop, 2*len - 1)} to the square of \code{(op, len)}. + + Permits zero padding and places no assumptions on the + lengths \code{len1} and \code{len2}. Supports aliasing. + +void fq_nmod_poly_sqr_KS(fq_nmod_poly_t rop, const fq_nmod_poly_t op, + const fq_nmod_ctx_t ctx) + + Sets \code{rop} to the square \code{op} using Kronecker substitution, + that is, by encoding each coefficient in $\mathbf{F}_{q}$ as an integer + and reducing this problem to multiplying two polynomials over the integers. + +void _fq_nmod_poly_sqr(fq_nmod_struct *rop, const fq_nmod_struct *op, slong len, + const fq_nmod_ctx_t ctx) + + Sets \code{(rop, 2* len - 1)} to the square of \code{(op, len)}, + choosing an appropriate algorithm. + + Permits zero padding. Does not support aliasing. + +void fq_nmod_poly_sqr(fq_nmod_poly_t rop, const fq_nmod_poly_t op, + const fq_nmod_ctx_t ctx) + + Sets \code{rop} to the square of \code{op}, + choosing an appropriate algorithm. + + +******************************************************************************* + + Powering + +******************************************************************************* + +void _fq_nmod_poly_pow(fq_nmod_struct *rop, const fq_nmod_struct *op, slong len, + ulong e, const fq_nmod_ctx_t ctx) + + Sets \code{res = poly^e}, assuming that \code{e, len > 0} and that + \code{res} has space for \code{e*(len - 1) + 1} coefficients. Does + not support aliasing. + +void fq_nmod_poly_pow(fq_nmod_poly_t rop, const fq_nmod_poly_t op, ulong e, + const fq_nmod_ctx_t ctx) + + Computes \code{res = poly^e}. If $e$ is zero, returns one, + so that in particular \code{0^0 = 1}. + +void _fq_nmod_poly_powmod_ui_binexp(fq_nmod_struct* res, + const fq_nmod_struct* poly, ulong e, + const fq_nmod_struct* f, slong lenf, + const fq_nmod_ctx_t ctx) + + Sets \code{res} to \code{poly} raised to the power \code{e} modulo + \code{f}, using binary exponentiation. We require \code{e > 0}. + + We require \code{lenf > 1}. It is assumed that \code{poly} is + already reduced modulo \code{f} and zero-padded as necessary to + have length exactly \code{lenf - 1}. The output \code{res} must + have room for \code{lenf - 1} coefficients. + +void fq_nmod_poly_powmod_ui_binexp(fq_nmod_poly_t res, + const fq_nmod_poly_t poly, ulong e, + const fq_nmod_poly_t f, + const fq_nmod_ctx_t ctx) + + Sets \code{res} to \code{poly} raised to the power \code{e} modulo + \code{f}, using binary exponentiation. We require \code{e >= 0}. + +void +_fq_nmod_poly_powmod_ui_binexp_preinv(fq_nmod_struct* res, + const fq_nmod_struct* poly, ulong e, + const fq_nmod_struct* f, slong lenf, + const fq_nmod_struct* finv, slong lenfinv, + const fq_nmod_ctx_t ctx) + + Sets \code{res} to \code{poly} raised to the power \code{e} modulo + \code{f}, using binary exponentiation. We require \code{e > 0}. + We require \code{finv} to be the inverse of the reverse of + \code{f}. + + We require \code{lenf > 1}. It is assumed that \code{poly} is + already reduced modulo \code{f} and zero-padded as necessary to + have length exactly \code{lenf - 1}. The output \code{res} must + have room for \code{lenf - 1} coefficients. + +void +fq_nmod_poly_powmod_ui_binexp_preinv(fq_nmod_poly_t res, + const fq_nmod_poly_t poly, ulong e, + const fq_nmod_poly_t f, const fq_nmod_poly_t finv, + const fq_nmod_ctx_t ctx) + + Sets \code{res} to \code{poly} raised to the power \code{e} modulo + \code{f}, using binary exponentiation. We require \code{e >= 0}. + We require \code{finv} to be the inverse of the reverse of + \code{f}. + +void _fq_nmod_poly_powmod_fmpz_binexp(fq_nmod_struct* res, + const fq_nmod_struct* poly, + fmpz_t e, const fq_nmod_struct* f, + slong lenf, const fq_nmod_ctx_t ctx) + + Sets \code{res} to \code{poly} raised to the power \code{e} modulo + \code{f}, using binary exponentiation. We require \code{e > 0}. + + We require \code{lenf > 1}. It is assumed that \code{poly} is + already reduced modulo \code{f} and zero-padded as necessary to + have length exactly \code{lenf - 1}. The output \code{res} must + have room for \code{lenf - 1} coefficients. + +void fq_nmod_poly_powmod_fmpz_binexp(fq_nmod_poly_t res, + const fq_nmod_poly_t poly, fmpz_t e, + const fq_nmod_poly_t f, + const fq_nmod_ctx_t ctx) + + Sets \code{res} to \code{poly} raised to the power \code{e} modulo + \code{f}, using binary exponentiation. We require \code{e >= 0}. + +void +_fq_nmod_poly_powmod_fmpz_binexp_preinv(fq_nmod_struct* res, const fq_nmod_struct* poly, + fmpz_t e, const fq_nmod_struct* f, slong lenf, + const fq_nmod_struct* finv, slong lenfinv, + const fq_nmod_ctx_t ctx) + + Sets \code{res} to \code{poly} raised to the power \code{e} modulo + \code{f}, using binary exponentiation. We require \code{e > 0}. + We require \code{finv} to be the inverse of the reverse of + \code{f}. + + We require \code{lenf > 1}. It is assumed that \code{poly} is + already reduced modulo \code{f} and zero-padded as necessary to + have length exactly \code{lenf - 1}. The output \code{res} must + have room for \code{lenf - 1} coefficients. + +void +fq_nmod_poly_powmod_fmpz_binexp_preinv(fq_nmod_poly_t res, + const fq_nmod_poly_t poly, fmpz_t e, + const fq_nmod_poly_t f, + const fq_nmod_poly_t finv, + const fq_nmod_ctx_t ctx) + + Sets \code{res} to \code{poly} raised to the power \code{e} modulo + \code{f}, using binary exponentiation. We require \code{e >= 0}. + We require \code{finv} to be the inverse of the reverse of + \code{f}. + +void +_fq_nmod_poly_powmod_fmpz_sliding_preinv(fq_nmod_struct* res, + const fq_nmod_struct* poly, + fmpz_t e, ulong k, + const fq_nmod_struct* f, slong lenf, + const fq_nmod_struct* finv, slong lenfinv, + const fq_nmod_ctx_t ctx) + + Sets \code{res} to \code{poly} raised to the power \code{e} modulo + \code{f}, using sliding-window exponentiation with window size + \code{k}. We require \code{e > 0}. We require \code{finv} to be + the inverse of the reverse of \code{f}. If \code{k} is set to + zero, then an "optimum" size will be selected automatically base + on \code{e}. + + We require \code{lenf > 1}. It is assumed that \code{poly} is + already reduced modulo \code{f} and zero-padded as necessary to + have length exactly \code{lenf - 1}. The output \code{res} must + have room for \code{lenf - 1} coefficients. + +void +fq_nmod_poly_powmod_fmpz_sliding_preinv(fq_nmod_poly_t res, + const fq_nmod_poly_t poly, fmpz_t e, + ulong k, const fq_nmod_poly_t f, + const fq_nmod_poly_t finv, + const fq_nmod_ctx_t ctx) + + Sets \code{res} to \code{poly} raised to the power \code{e} modulo + \code{f}, using sliding-window exponentiation with window size + \code{k}. We require \code{e >= 0}. We require \code{finv} to be + the inverse of the reverse of \code{f}. If \code{k} is set to + zero, then an "optimum" size will be selected automatically base + on \code{e}. + +void +_fq_nmod_poly_powmod_x_fmpz_preinv(fq_nmod_struct * res, const fmpz_t e, + const fq_nmod_struct * f, slong lenf, + const fq_nmod_struct * finv, slong lenfinv, + const fq_nmod_ctx_t ctx) + + Sets \code{res} to \code{x} raised to the power \code{e} modulo \code{f}, + using sliding window exponentiation. We require \code{e > 0}. + We require \code{finv} to be the inverse of the reverse of \code{f}. + + We require \code{lenf > 2}. The output \code{res} must have room for + \code{lenf - 1} coefficients. + +void +fq_nmod_poly_powmod_x_fmpz_preinv(fq_nmod_poly_t res, const fmpz_t e, + const fq_nmod_poly_t f, const fq_nmod_poly_t finv, + const fq_nmod_ctx_t ctx) + + Sets \code{res} to \code{x} raised to the power \code{e} + modulo \code{f}, using sliding window exponentiation. We require + \code{e >= 0}. We require \code{finv} to be the inverse of the reverse of + \code{f}. + +******************************************************************************* + + Shifting + +******************************************************************************* + +void _fq_nmod_poly_shift_left(fq_nmod_struct *rop, const fq_nmod_struct *op, + slong len, slong n, const fq_nmod_ctx_t ctx) + + Sets \code{(res, len + n)} to \code{(poly, len)} shifted left by + $n$ coefficients. + + Inserts zero coefficients at the lower end. Assumes that + \code{len} and $n$ are positive, and that \code{res} fits + \code{len + n} elements. Supports aliasing between \code{res} and + \code{poly}. + +void fq_nmod_poly_shift_left(fq_nmod_poly_t rop, const fq_nmod_poly_t op, slong n, + const fq_nmod_ctx_t ctx) + + Sets \code{res} to \code{poly} shifted left by $n$ coeffs. Zero + coefficients are inserted. + +void _fq_nmod_poly_shift_right(fq_nmod_struct *rop, const fq_nmod_struct *op, + slong len, slong n, const fq_nmod_ctx_t ctx) + + Sets \code{(res, len - n)} to \code{(poly, len)} shifted right by + $n$ coefficients. + + Assumes that \code{len} and $n$ are positive, that \code{len > n}, + and that \code{res} fits \code{len - n} elements. Supports + aliasing between \code{res} and \code{poly}, although in this case + the top coefficients of \code{poly} are not set to zero. + +void fq_nmod_poly_shift_right(fq_nmod_poly_t rop, const fq_nmod_poly_t op, + slong n, const fq_nmod_ctx_t ctx) + + Sets \code{res} to \code{poly} shifted right by $n$ coefficients. + If $n$ is equal to or greater than the current length of + \code{poly}, \code{res} is set to the zero polynomial. + +******************************************************************************* + + Norms + +******************************************************************************* + +long _fq_nmod_poly_hamming_weight(const fq_nmod_poly *op, slong len, + const fq_nmod_ctx_t ctx) + + Returns the number of non-zero entries in \code{(op, len)}. + +long fq_nmod_poly_hamming_weight(const fq_nmod_poly_t op, + const fq_nmod_ctx_t ctx) + + Returns the number of non-zero entries in the polynomial \code{op}. + +******************************************************************************* + + Euclidean division + +******************************************************************************* + +void _fq_nmod_poly_divrem_basecase(fq_nmod_struct *Q, fq_nmod_struct *R, + const fq_nmod_struct *A, slong lenA, const fq_nmod_struct *B, slong lenB, + const fq_nmod_t invB, const fq_nmod_ctx_t ctx) + + Computes \code{(Q, lenA - lenB + 1)}, \code{(R, lenA)} such that + $A = B Q + R$ with $0 \leq \len(R) < \len(B)$. + + Assumes that the leading coefficient of $B$ is invertible + and that \code{invB} is its inverse. + + Assumes that $\len(A), \len(B) > 0$. Allows zero-padding in + \code{(A, lenA)}. $R$ and $A$ may be aliased, but apart from + this no aliasing of input and output operands is allowed. + +void fq_nmod_poly_divrem_basecase(fq_nmod_poly_t Q, fq_nmod_poly_t R, + const fq_nmod_poly_t A, const fq_nmod_poly_t B, + const fq_nmod_ctx_t ctx) + + Computes $Q$, $R$ such that $A = B Q + R$ with + $0 \leq \len(R) < \len(B)$. + + Assumes that the leading coefficient of $B$ is invertible. This can + be taken for granted the context is for a finite field, that is, when + $p$ is prime and $f(X)$ is irreducible. + +void _fq_nmod_poly_divrem(fq_nmod_struct *Q, fq_nmod_struct *R, + const fq_nmod_struct *A, slong lenA, const fq_nmod_struct *B, slong lenB, + const fq_nmod_t invB, const fq_nmod_ctx_t ctx) + + Computes \code{(Q, lenA - lenB + 1)}, \code{(R, lenA)} such that + $A = B Q + R$ with $0 \leq \len(R) < \len(B)$. + + Assumes that the leading coefficient of $B$ is invertible + and that \code{invB} is its inverse. + + Assumes that $\len(A), \len(B) > 0$. Allows zero-padding in + \code{(A, lenA)}. $R$ and $A$ may be aliased, but apart from + this no aliasing of input and output operands is allowed. + +void fq_nmod_poly_divrem(fq_nmod_poly_t Q, fq_nmod_poly_t R, + const fq_nmod_poly_t A, const fq_nmod_poly_t B, + const fq_nmod_ctx_t ctx) + + Computes $Q$, $R$ such that $A = B Q + R$ with + $0 \leq \len(R) < \len(B)$. + + Assumes that the leading coefficient of $B$ is invertible. This can + be taken for granted the context is for a finite field, that is, when + $p$ is prime and $f(X)$ is irreducible. + +void _fq_nmod_poly_rem(fq_nmod_struct *R, const fq_nmod_struct *A, slong lenA, + const fq_nmod_struct *B, slong lenB, const fq_nmod_t invB, + const fq_nmod_ctx_t ctx) + + Sets \code{R} to the remainder of the division of \code{(A,lenA)} by + \code{(B,lenB)}. Assumes that the leading coefficient of \code{(B,lenB)} + is invertible and that \code{invB} is its inverse. + +void fq_nmod_poly_rem(fq_nmod_poly_t R, + const fq_nmod_poly_t A, const fq_nmod_poly_t B, + const fq_nmod_ctx_t ctx) + + Sets \code{R} to the remainder of the division of \code{A} by + \code{B} in the context described by \code{ctx}. + +void _fq_nmod_poly_div_basecase(fq_nmod_struct *Q, fq_nmod_struct *R, + const fq_nmod_struct *A, slong lenA, + const fq_nmod_struct *B, slong lenB, + const fq_nmod_t invB, const fq_nmod_ctx_t ctx) + + Notationally, computes $Q$, $R$ such that $A = B Q + R$ with $0 + \leq \len(R) < \len(B)$ but only sets \code{(Q, lenA - lenB + 1)}. + + Requires temporary space \code{(R, lenA)}. If \code{R} is + \code{NULL}, then the temporary space will be allocated. Allows + aliasing only between $A$ and $R$. Allows zero-padding in $A$ but + not in $B$. Assumes that the leading coefficient of $B$ is a + unit. + +void fq_nmod_poly_div_basecase(fq_nmod_poly_t Q, const fq_nmod_poly_t A, + const fq_nmod_poly_t B, const fq_nmod_ctx_t ctx) + + Notionally finds polynomials $Q$ and $R$ such that $A = B Q + R$ with + $\len(R) < \len(B)$, but returns only \code{Q}. If $\len(B) = 0$ an + exception is raised. + +void _fq_nmod_poly_divrem_divconquer_recursive(fq_nmod_struct * Q, fq_nmod_struct * BQ, + fq_nmod_struct * W, const fq_nmod_struct * A, + const fq_nmod_struct * B, slong lenB, + const fq_nmod_t invB, const fq_nmod_ctx_t ctx) + + Computes \code{(Q, lenB)}, \code{(BQ, 2 lenB - 1)} such that + $BQ = B \times Q$ and $A = B Q + R$ where $0 \leq \len(R) < \len(B)$. + + Assumes that the leading coefficient of $B$ is invertible and that + \code{invB} is the inverse. + + Assumes $\len(B) > 0$. Allows zero-padding in \code{(A, lenA)}. Requires + a temporary array \code{(W, 2 lenB - 1)}. No aliasing of input and output + operands is allowed. + + This function does not read the bottom $\len(B) - 1$ coefficients from + $A$, which means that they might not even need to exist in allocated + memory. + +void _fq_nmod_poly_divrem_divconquer(fq_nmod_struct * Q, fq_nmod_struct * R, + const fq_nmod_struct * A, slong lenA, + const fq_nmod_struct * B, slong lenB, + const fq_nmod_t invB, const fq_nmod_ctx_t ctx) + + Computes \code{(Q, lenA - lenB + 1)}, \code{(R, lenA)} such that + $A = B Q + R$ and $0 \leq \len(R) < \len(B)$. + + Assumes that the leading coefficient of $B$ is invertible and that + \code{invB} is the inverse. + + Assumes $\len(A) \geq \len(B) > 0$. Allows zero-padding in + \code{(A, lenA)}. No aliasing of input and output operands is + allowed. + +void fq_nmod_poly_divrem_divconquer(fq_nmod_poly_t Q, fq_nmod_poly_t R, + const fq_nmod_poly_t A, const fq_nmod_poly_t B, + const fq_nmod_ctx_t ctx) + + Computes $Q$, $R$ such that $A = B Q + R$ and $0 \leq \len(R) < \len(B)$. + + Assumes that $B$ is non-zero and that the leading coefficient of + $B$ is invertible. + +void _fq_nmod_poly_div_newton_n_preinv(fq_nmod_struct* Q, const fq_nmod_struct* A, slong lenA, + const fq_nmod_struct* B, slong lenB, + const fq_nmod_struct* Binv, slong lenBinv, + const fq_nmod_struct ctx_t) + + Notionally computes polynomials $Q$ and $R$ such that $A = BQ + R$ with + $\len(R)$ less than \code{lenB}, where \code{A} is of length \code{lenA} + and \code{B} is of length \code{lenB}, but return only $Q$. + + We require that $Q$ have space for \code{lenA - lenB + 1} coefficients + and assume that the leading coefficient of $B$ is a unit. Furthermore, we + assume that $Binv$ is the inverse of the reverse of $B$ mod $x^{\len(B)}$. + + The algorithm used is to reverse the polynomials and divide the + resulting power series, then reverse the result. + +void fq_nmod_poly_div_newton_n_preinv(fq_nmod_poly_t Q, const fq_nmod_poly_t A, + const fq_nmod_poly_t B, + const fq_nmod_poly_t Binv, + const fq_nmod_ctx_t ctx) + + Notionally computes $Q$ and $R$ such that $A = BQ + R$ with + $\len(R) < \len(B)$, but returns only $Q$. + + We assume that the leading coefficient of $B$ is a unit and that $Binv$ is + the inverse of the reverse of $B$ mod $x^{\len(B)}$. + + It is required that the length of $A$ is less than or equal to + 2*the length of $B$ - 2. + + The algorithm used is to reverse the polynomials and divide the + resulting power series, then reverse the result. + +void _fq_nmod_poly_divrem_newton_n_preinv(fq_nmod_struct* Q, fq_nmod_struct* R, + const fq_nmod_struct* A, slong lenA, + const fq_nmod_struct* B, slong lenB, + const fq_nmod_struct* Binv, slong lenBinv, + const fq_nmod_ctx_t ctx) + + Computes $Q$ and $R$ such that $A = BQ + R$ with $\len(R)$ less + than \code{lenB}, where $A$ is of length \code{lenA} and $B$ is of + length \code{lenB}. We require that $Q$ have space for + \code{lenA - lenB + 1} coefficients. Furthermore, we assume that $Binv$ is + the inverse of the reverse of $B$ mod $x^{\len(B)}$. The algorithm + used is to call \code{div_newton_preinv()} and then multiply out + and compute the remainder. + +void fq_nmod_poly_divrem_newton_n_preinv(fq_nmod_poly_t Q, fq_nmod_poly_t R, + const fq_nmod_poly_t A, const fq_nmod_poly_t B, + const fq_nmod_poly_t Binv, const fq_nmod_ctx_t ctx) + + Computes $Q$ and $R$ such that $A = BQ + R$ with $\len(R) < + \len(B)$. We assume $Binv$ is the inverse of the reverse of $B$ + mod $x^{\len(B)}$. + + It is required that the length of $A$ is less than or equal to + 2*the length of $B$ - 2. + + The algorithm used is to call \code{div_newton()} and then + multiply out and compute the remainder. + +void +_fq_nmod_poly_inv_series_newton(fq_nmod_struct* Qinv, const fq_nmod_struct* Q, slong n, + const fq_nmod_ctx_t ctx) + + Given \code{Q} of length \code{n} whose constant coefficient is + invertible modulo the given modulus, find a polynomial \code{Qinv} + of length \code{n} such that \code{Q * Qinv} is \code{1} modulo + $x^n$. Requires \code{n > 0}. This function can be viewed as + inverting a power series via Newton iteration. + +void +fq_nmod_poly_inv_series_newton(fq_nmod_poly_t Qinv, const fq_nmod_poly_t Q, slong n, + const fq_nmod_ctx_t ctx) + + Given \code{Q} find \code{Qinv} such that \code{Q * Qinv} is + \code{1} modulo $x^n$. The constant coefficient of \code{Q} must + be invertible modulo the modulus of \code{Q}. An exception is + raised if this is not the case or if \code{n = 0}. This function + can be viewed as inverting a power series via Newton iteration. + +******************************************************************************* + + Greatest common divisor + +******************************************************************************* + +void fq_nmod_poly_gcd(fq_nmod_poly_t rop, const fq_nmod_poly_t op1, + const fq_nmod_poly_t op2, const fq_nmod_ctx_t ctx) + + Sets \code{rop} to the greatest common divisor of \code{op1} and + \code{op2}, using the either the Euclidean or HGCD algorithm. The + GCD of zero polynomials is defined to be zero, whereas the GCD of + the zero polynomial and some other polynomial $P$ is defined to be + $P$. Except in the case where the GCD is zero, the GCD $G$ is made + monic. + +long _fq_nmod_poly_gcd(fq_nmod_struct* G,const fq_nmod_struct* A, slong lenA, + const fq_nmod_struct* B, slong lenB, + const fq_nmod_ctx_t ctx) + + Computes the GCD of $A$ of length \code{lenA} and $B$ of length + \code{lenB}, where \code{lenA >= lenB > 0} and sets $G$ to it. The + length of the GCD $G$ is returned by the function. No attempt is + made to make the GCD monic. It is required that $G$ have space for + \code{lenB} coefficients. + +void fq_nmod_poly_gcd_euclidean(fq_nmod_poly_t rop, const fq_nmod_poly_t op1, + const fq_nmod_poly_t op2, + const fq_nmod_ctx_t ctx) + + Sets \code{rop} to the greatest common divisor of \code{op1} and + \code{op2}, using the Euclidean algorithm. The GCD of zero + polynomials is defined to be zero, whereas the GCD of the zero + polynomial and some other polynomial $P$ is defined to be + $P$. Except in the case where the GCD is zero, the GCD $G$ is made + monic. + +long _fq_nmod_poly_gcd_euclidean(fq_nmod_struct* G, + const fq_nmod_struct* A, slong lenA, + const fq_nmod_struct* B, slong lenB, + const fq_nmod_ctx_t ctx) + + Computes the GCD of $A$ of length \code{lenA} and $B$ of length + \code{lenB}, where \code{lenA >= lenB > 0} and sets $G$ to it. The + length of the GCD $G$ is returned by the function. No attempt is + made to make the GCD monic. It is required that $G$ have space for + \code{lenB} coefficients. + +******************************************************************************* + + Divisibility testing + +******************************************************************************* + +int _fq_nmod_poly_divides(fq_nmod_struct *Q, + const fq_nmod_struct *A, slong lenA, + const fq_nmod_struct *B, slong lenB, const fq_nmod_t invB, + const fq_nmod_ctx_t ctx) + + Returns $1$ if \code{(B, lenB)} divides \code{(A, lenA)} exactly and + sets $Q$ to the quotient, otherwise returns $0$. + + It is assumed that $\len(A) \geq \len(B) > 0$ and that $Q$ has space + for $\len(A) - \len(B) + 1$ coefficients. + + Aliasing of $Q$ with either of the inputs is not permitted. + + This function is currently unoptimised and provided for convenience + only. + +int fq_nmod_poly_divides(fq_nmod_poly_t Q, const fq_nmod_poly_t A, const fq_nmod_poly_t B, + const fq_nmod_ctx_t ctx) + + + Returns $1$ if $B$ divides $A$ exactly and sets $Q$ to the quotient, + otherwise returns $0$. + + This function is currently unoptimised and provided for convenience + only. + +******************************************************************************* + + Derivative + +******************************************************************************* + +void _fq_nmod_poly_derivative(fq_nmod_struct *rop, const fq_nmod_struct *op, slong len, + const fq_nmod_ctx_t ctx) + + Sets \code{(rpoly, len - 1)} to the derivative of \code{(poly, len)}. + Also handles the cases where \code{len} is $0$ or $1$ correctly. + Supports aliasing of \code{rpoly} and \code{poly}. + +void fq_nmod_poly_derivative(fq_nmod_poly_t rop, const fq_nmod_poly_t op, const fq_nmod_ctx_t ctx) + + Sets \code{res} to the derivative of \code{poly}. + +******************************************************************************* + + Evaluation + +******************************************************************************* + +void _fq_nmod_poly_evaluate_fq_nmod(fq_nmod_t rop, const fq_nmod_struct *op, slong len, + const fq_nmod_t a, const fq_nmod_ctx_t ctx) + + Sets \code{rop} to \code{(op, len)} evaluated at $a$. + + Supports zero padding. There are no restrictions on \code{len}, that + is, \code{len} is allowed to be zero, too. + +void fq_nmod_poly_evaluate_fq_nmod(fq_nmod_t rop, const fq_nmod_poly_t f, const fq_nmod_t a, + const fq_nmod_ctx_t ctx) + + Sets \code{rop} to the value of $f(a)$. + + As the coefficient ring $\mathbf{F}_q$ is finite, Horner's method + is sufficient. + +******************************************************************************* + + Composition + +******************************************************************************* + +void _fq_nmod_poly_compose_divconquer(fq_nmod_struct *rop, + const fq_nmod_struct *op1, slong len1, + const fq_nmod_struct *op2, slong len2, + const fq_nmod_ctx_t ctx) + + Computes the composition of \code{(op1, len1)} and \code{(op2, len2)} + using a divide and conquer approach and places the result into \code{rop}, + assuming \code{rop} can hold the output of length + \code{(len1 - 1) * (len2 - 1) + 1}. + + Assumes \code{len1, len2 > 0}. Does not support aliasing between + \code{rop} and any of \code{(op1, len1)} and \code{(op2, len2)}. + +void fq_nmod_poly_compose_divconquer(fq_nmod_poly_t rop, + const fq_nmod_poly_t op1, const fq_nmod_poly_t op2, + const fq_nmod_ctx_t ctx) + + Sets \code{rop} to the composition of \code{op1} and \code{op2}. + To be precise about the order of composition, denoting \code{rop}, + \code{op1}, and \code{op2} by $f$, $g$, and $h$, respectively, + sets $f(t) = g(h(t))$. + +void _fq_nmod_poly_compose_horner(fq_nmod_struct *rop, const fq_nmod_struct *op1, slong len1, + const fq_nmod_struct *op2, slong len2, + const fq_nmod_ctx_t ctx) + + Sets \code{rop} to the composition of \code{(op1, len1)} and + \code{(op2, len2)}. + + Assumes that \code{rop} has space for \code{(len1-1)*(len2-1) + 1} + coefficients. Assumes that \code{op1} and \code{op2} are non-zero + polynomials. Does not support aliasing between any of the inputs and + the output. + +void fq_nmod_poly_compose_horner(fq_nmod_poly_t rop, + const fq_nmod_poly_t op1, const fq_nmod_poly_t op2, + const fq_nmod_ctx_t ctx) + + Sets \code{rop} to the composition of \code{op1} and \code{op2}. + To be more precise, denoting \code{rop}, \code{op1}, and \code{op2} + by $f$, $g$, and $h$, sets $f(t) = g(h(t))$. + + This implementation uses Horner's method. + +void _fq_nmod_poly_compose(fq_nmod_struct *rop, const fq_nmod_struct *op1, slong len1, + const fq_nmod_struct *op2, slong len2, + const fq_nmod_ctx_t ctx) + + Sets \code{rop} to the composition of \code{(op1, len1)} and + \code{(op2, len2)}. + + Assumes that \code{rop} has space for \code{(len1-1)*(len2-1) + 1} + coefficients. Assumes that \code{op1} and \code{op2} are non-zero + polynomials. Does not support aliasing between any of the inputs and + the output. + +void fq_nmod_poly_compose(fq_nmod_poly_t rop, const fq_nmod_poly_t op1, const fq_nmod_poly_t op2, + const fq_nmod_ctx_t ctx) + + Sets \code{rop} to the composition of \code{op1} and \code{op2}. + To be precise about the order of composition, denoting \code{rop}, + \code{op1}, and \code{op2} by $f$, $g$, and $h$, respectively, + sets $f(t) = g(h(t))$. + +void _fq_nmod_poly_compose_mod_horner(fq_nmod_struct * res, + const fq_nmod_struct * f, slong lenf, + const fq_nmod_struct * g, + const fq_nmod_struct * h, slong lenh, + const fq_nmod_ctx_t ctx) + + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require that + $h$ is nonzero and that the length of $g$ is one less than the + length of $h$ (possibly with zero padding). The output is not allowed + to be aliased with any of the inputs. + + The algorithm used is Horner's rule. + +void fq_nmod_poly_compose_mod_horner(fq_nmod_poly_t res, const fq_nmod_poly_t f, + const fq_nmod_poly_t g, const fq_nmod_poly_t h, + const fq_nmod_ctx_t ctx) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require that + $h$ is nonzero. The algorithm used is Horner's rule. + +void _fq_nmod_poly_compose_mod_horner_preinv(fq_nmod_struct * res, + const fq_nmod_struct * f, slong lenf, + const fq_nmod_struct * g, + const fq_nmod_struct * h, slong lenh, + const fq_nmod_struct * hinv, slong lenhiv, + const fq_nmod_ctx_t ctx) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require + that $h$ is nonzero and that the length of $g$ is one less than + the length of $h$ (possibly with zero padding). We also require + that the length of $f$ is less than the length of + $h$. Furthermore, we require \code{hinv} to be the inverse of the + reverse of \code{h}. The output is not allowed to be aliased with + any of the inputs. + + The algorithm used is Horner's rule. + +void fq_nmod_poly_compose_mod_horner_preinv(fq_nmod_poly_t res, const fq_nmod_poly_t f, + const fq_nmod_poly_t g, const fq_nmod_poly_t h, + const fq_nmod_poly_t hinv, + const fq_nmod_ctx_t ctx) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require + that $h$ is nonzero and that $f$ has smaller degree than + $h$. Furthermore, we require \code{hinv} to be the inverse of the + reverse of \code{h}. The algorithm used is Horner's rule. + + +void _fq_nmod_poly_compose_mod_brent_kung(fq_nmod_struct * res, + const fq_nmod_struct * f, slong lenf, + const fq_nmod_struct * g, + const fq_nmod_struct * h, slong lenh, + const fq_nmod_ctx_t ctx) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require + that $h$ is nonzero and that the length of $g$ is one less than + the length of $h$ (possibly with zero padding). We also require + that the length of $f$ is less than the length of $h$. The output + is not allowed to be aliased with any of the inputs. + + The algorithm used is the Brent-Kung matrix algorithm. + +void fq_nmod_poly_compose_mod_brent_kung(fq_nmod_poly_t res, const fq_nmod_poly_t f, + const fq_nmod_poly_t g, const fq_nmod_poly_t h, + const fq_nmod_ctx_t ctx) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require + that $h$ is nonzero and that $f$ has smaller degree than $h$. The + algorithm used is the Brent-Kung matrix algorithm. + +void _fq_nmod_poly_compose_mod_brent_kung_preinv(fq_nmod_struct * res, + const fq_nmod_struct * f, slong lenf, + const fq_nmod_struct * g, + const fq_nmod_struct * h, slong lenh, + const fq_nmod_struct * hinv, slong lenhiv, + const fq_nmod_ctx_t ctx) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require + that $h$ is nonzero and that the length of $g$ is one less than + the length of $h$ (possibly with zero padding). We also require + that the length of $f$ is less than the length of + $h$. Furthermore, we require \code{hinv} to be the inverse of the + reverse of \code{h}. The output is not allowed to be aliased with + any of the inputs. + + The algorithm used is the Brent-Kung matrix algorithm. + +void fq_nmod_poly_compose_mod_brent_kung_preinv(fq_nmod_poly_t res, const fq_nmod_poly_t f, + const fq_nmod_poly_t g, const fq_nmod_poly_t h, + const fq_nmod_poly_t hinv, + const fq_nmod_ctx_t ctx) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require + that $h$ is nonzero and that $f$ has smaller degree than + $h$. Furthermore, we require \code{hinv} to be the inverse of the + reverse of \code{h}. The algorithm used is the Brent-Kung matrix + algorithm. + +void _fq_nmod_poly_compose_mod(fq_nmod_struct * res, const fq_nmod_struct * f, slong lenf, + const fq_nmod_struct * g, const fq_nmod_struct * h, slong lenh, + const fq_nmod_ctx_t ctx) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require + that $h$ is nonzero and that the length of $g$ is one less than + the length of $h$ (possibly with zero padding). The output is not + allowed to be aliased with any of the inputs. + +void fq_nmod_poly_compose_mod(fq_nmod_poly_t res, const fq_nmod_poly_t f, const fq_nmod_poly_t g, + const fq_nmod_poly_t h, const fq_nmod_ctx_t ctx) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require + that $h$ is nonzero. + +void _fq_nmod_poly_compose_mod_preinv(fq_nmod_struct * res, + const fq_nmod_struct * f, slong lenf, + const fq_nmod_struct * g, + const fq_nmod_struct * h, slong lenh, + const fq_nmod_struct * hinv, slong lenhiv, + const fq_nmod_ctx_t ctx) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require + that $h$ is nonzero and that the length of $g$ is one less than + the length of $h$ (possibly with zero padding). We also require + that the length of $f$ is less than the length of + $h$. Furthermore, we require \code{hinv} to be the inverse of the + reverse of \code{h}. The output is not allowed to be aliased with + any of the inputs. + +void fq_nmod_poly_compose_mod_preinv(fq_nmod_poly_t res, const fq_nmod_poly_t f, + const fq_nmod_poly_t g, const fq_nmod_poly_t h, + const fq_nmod_poly_t hinv, + const fq_nmod_ctx_t ctx) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require + that $h$ is nonzero and that $f$ has smaller degree than + $h$. Furthermore, we require \code{hinv} to be the inverse of the + reverse of \code{h}. + +void +_fq_nmod_poly_reduce_matrix_mod_poly (fq_nmod_mat_t A, const fq_nmod_mat_t B, + const fq_nmod_poly_t f, const fq_nmod_ctx_t ctx) + + Sets the ith row of \code{A} to the reduction of the ith row of $B$ modulo + $f$ for $i=1,\ldots,\sqrt{\deg(f)}$. We require $B$ to be at least + a $\sqrt{\deg(f)}\times \deg(f)$ matrix and $f$ to be nonzero. + +void +_fq_nmod_poly_precompute_matrix (fq_nmod_mat_t A, const fq_nmod_struct* f, const fq_nmod_struct* g, + slong leng, const fq_nmod_struct* ginv, slong lenginv, + const fq_nmod_ctx_t ctx) + + Sets the ith row of \code{A} to $f^i$ modulo $g$ for + $i=1,\ldots,\sqrt{\deg(g)}$. We require $A$ to be a + $\sqrt{\deg(g)}\times \deg(g)$ matrix. We require \code{ginv} to + be the inverse of the reverse of \code{g} and $g$ to be nonzero. + +void +fq_nmod_poly_precompute_matrix (fq_nmod_mat_t A, const fq_nmod_poly_t f, + const fq_nmod_poly_t g, const fq_nmod_poly_t ginv, + const fq_nmod_ctx_t ctx) + + Sets the ith row of \code{A} to $f^i$ modulo $g$ for + $i=1,\ldots,\sqrt{\deg(g)}$. We require $A$ to be a + $\sqrt{\deg(g)}\times \deg(g)$ matrix. We require \code{ginv} to + be the inverse of the reverse of \code{g}. + + +void +_fq_nmod_poly_compose_mod_brent_kung_precomp_preinv(fq_nmod_struct* res, const fq_nmod_struct* f, + slong lenf, const fq_nmod_mat_t A, const fq_nmod_struct* h, + slong h, const fq_nmod_struct* hinv, slong lenhinv, + const fq_nmod_ctx_t ctx) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require + that $h$ is nonzero. We require that the ith row of $A$ contains + $g^i$ for $i=1,\ldots,\sqrt{\deg(h)}$, i.e. $A$ is a + $\sqrt{\deg(h)}\times \deg(h)$ matrix. We also require that the + length of $f$ is less than the length of $h$. Furthermore, we + require \code{hinv} to be the inverse of the reverse of \code{h}. + The output is not allowed to be aliased with any of the inputs. + + The algorithm used is the Brent-Kung matrix algorithm. + +void +fq_nmod_poly_compose_mod_brent_kung_precomp_preinv(fq_nmod_poly_t res, + const fq_nmod_poly_t f, const fq_nmod_mat_t A, + const fq_nmod_poly_t h, const fq_nmod_poly_t hinv, + const fq_nmod_ctx_t ctx) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require + that the ith row of $A$ contains $g^i$ for + $i=1,\ldots,\sqrt{\deg(h)}$, i.e. $A$ is a $\sqrt{\deg(h)}\times + \deg(h)$ matrix. We require that $h$ is nonzero and that $f$ has + smaller degree than $h$. Furthermore, we require \code{hinv} to be + the inverse of the reverse of \code{h}. This version of Brent-Kung + modular composition is particularly useful if one has to perform + several modular composition of the form $f(g)$ modulo $h$ for + fixed $g$ and $h$. + + +******************************************************************************* + + Output + +******************************************************************************* + +int _fq_nmod_poly_fprint_pretty(FILE *file, const fq_nmod_struct *poly, slong len, + const char *x, const fq_nmod_ctx_t ctx) + + Prints the pretty representation of \code{(poly, len)} to the stream + \code{file}, using the string \code{x} to represent the indeterminate. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + +int fq_nmod_poly_fprint_pretty(FILE * file, const fq_nmod_poly_t poly, const char *x, + const fq_nmod_ctx_t ctx) + + Prints the pretty representation of \code{poly} to the stream + \code{file}, using the string \code{x} to represent the indeterminate. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + + +int _fq_nmod_poly_print_pretty(const fq_nmod_struct *poly, slong len, + const char *x, const fq_nmod_ctx_t ctx) + + Prints the pretty representation of \code{(poly, len)} to \code{stdout}, + using the string \code{x} to represent the indeterminate. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + + +int fq_nmod_poly_print_pretty(const fq_nmod_poly_t poly, const char *x, + const fq_nmod_ctx_t ctx) + + Prints the pretty representation of \code{poly} to \code{stdout}, + using the string \code{x} to represent the indeterminate. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + +int _fq_nmod_poly_fprint(FILE *file, const fq_nmod_struct *poly, slong len, + const fq_nmod_ctx_t ctx) + + Prints the pretty representation of \code{(poly, len)} to the stream + \code{file}. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + +int fq_nmod_poly_fprint(FILE * file, const fq_nmod_poly_t poly, const fq_nmod_ctx_t ctx) + + Prints the pretty representation of \code{poly} to the stream + \code{file}. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + + +int _fq_nmod_poly_print(const fq_nmod_struct *poly, slong len, const fq_nmod_ctx_t ctx) + + Prints the pretty representation of \code{(poly, len)} to \code{stdout}. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + + +int fq_nmod_poly_print(const fq_nmod_poly_t poly, const fq_nmod_ctx_t ctx) + + Prints the representation of \code{poly} to \code{stdout}. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + +char * _fq_nmod_poly_get_str(const fq_nmod_struct * poly, slong len, const fq_nmod_ctx_t ctx) + + Returns the plain FLINT string representation of the polynomial + \code{(poly, len)}. + +char * fq_nmod_poly_get_str(const fq_nmod_poly_t poly, const fq_nmod_ctx_t ctx) + + Returns the plain FLINT string representation of the polynomial + \code{poly}. + +char * _fq_nmod_poly_get_str_pretty(const fq_nmod_struct * poly, slong len, + const char * x, const fq_nmod_ctx_t ctx) + + Returns a pretty representation of the polynomial + \code{(poly, len)} using the null-terminated string~\code{x} as the + variable name. + +char * fq_nmod_poly_get_str_pretty(const fq_nmod_poly_t poly, const char * x, + const fq_nmod_ctx_t ctx) + + Returns a pretty representation of the polynomial~\code{poly} using the + null-terminated string \code{x} as the variable name + +******************************************************************************* + + Inflation and deflation + +******************************************************************************* + +void fq_nmod_poly_inflate(fq_nmod_poly_t result, const fq_nmod_poly_t input, + ulong inflation, const fq_nmod_ctx_t ctx) + + Sets \code{result} to the inflated polynomial $p(x^n)$ where + $p$ is given by \code{input} and $n$ is given by \code{inflation}. + +void fq_nmod_poly_deflate(fq_nmod_poly_t result, const fq_nmod_poly_t input, + ulong deflation, const fq_nmod_ctx_t ctx) + + Sets \code{result} to the deflated polynomial $p(x^{1/n})$ where + $p$ is given by \code{input} and $n$ is given by \code{deflation}. + Requires $n > 0$. + +ulong fq_nmod_poly_deflation(const fq_nmod_poly_t input, const fq_nmod_ctx_t ctx) + + Returns the largest integer by which \code{input} can be deflated. + As special cases, returns 0 if \code{input} is the zero polynomial + and 1 of \code{input} is a constant polynomial. diff --git a/external/flint-2.4.3/fq_nmod_poly/equal.c b/external/flint-2.4.3/fq_nmod_poly/equal.c new file mode 100644 index 0000000..fe21fd3 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/equal.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/equal.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/evaluate_fq.c b/external/flint-2.4.3/fq_nmod_poly/evaluate_fq.c new file mode 100644 index 0000000..7aec1e3 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/evaluate_fq.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/evaluate_fq.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/fit_length.c b/external/flint-2.4.3/fq_nmod_poly/fit_length.c new file mode 100644 index 0000000..7d8864c --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/fit_length.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/fit_length.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/fprint.c b/external/flint-2.4.3/fq_nmod_poly/fprint.c new file mode 100644 index 0000000..42ad25d --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/fprint.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/fprint.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/fprint_pretty.c b/external/flint-2.4.3/fq_nmod_poly/fprint_pretty.c new file mode 100644 index 0000000..6482692 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/fprint_pretty.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/fprint_pretty.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/gcd_euclidean.c b/external/flint-2.4.3/fq_nmod_poly/gcd_euclidean.c new file mode 100644 index 0000000..54dbf4f --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/gcd_euclidean.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/gcd_euclidean.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/gen.c b/external/flint-2.4.3/fq_nmod_poly/gen.c new file mode 100644 index 0000000..eb70cc7 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/gen.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/gen.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/get_coeff.c b/external/flint-2.4.3/fq_nmod_poly/get_coeff.c new file mode 100644 index 0000000..b361f54 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/get_coeff.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/get_coeff.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/get_str.c b/external/flint-2.4.3/fq_nmod_poly/get_str.c new file mode 100644 index 0000000..09126c0 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/get_str.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/get_str.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/get_str_pretty.c b/external/flint-2.4.3/fq_nmod_poly/get_str_pretty.c new file mode 100644 index 0000000..4a51a22 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/get_str_pretty.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/get_str_pretty.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/hamming_weight.c b/external/flint-2.4.3/fq_nmod_poly/hamming_weight.c new file mode 100644 index 0000000..ad8f613 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/hamming_weight.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/hamming_weight.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/inflate.c b/external/flint-2.4.3/fq_nmod_poly/inflate.c new file mode 100644 index 0000000..8672506 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/inflate.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/inflate.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/init.c b/external/flint-2.4.3/fq_nmod_poly/init.c new file mode 100644 index 0000000..025da0f --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/init.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/init.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/inv_series_newton.c b/external/flint-2.4.3/fq_nmod_poly/inv_series_newton.c new file mode 100644 index 0000000..4ba3753 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/inv_series_newton.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/inv_series_newton.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/make_monic.c b/external/flint-2.4.3/fq_nmod_poly/make_monic.c new file mode 100644 index 0000000..cbf2cbc --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/make_monic.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/make_monic.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/mul.c b/external/flint-2.4.3/fq_nmod_poly/mul.c new file mode 100644 index 0000000..e297531 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/mul.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/mul.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/mul_KS.c b/external/flint-2.4.3/fq_nmod_poly/mul_KS.c new file mode 100644 index 0000000..707da7b --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/mul_KS.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/mul_KS.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/mul_classical.c b/external/flint-2.4.3/fq_nmod_poly/mul_classical.c new file mode 100644 index 0000000..a7ce181 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/mul_classical.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/mul_classical.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/mullow.c b/external/flint-2.4.3/fq_nmod_poly/mullow.c new file mode 100644 index 0000000..a0f9831 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/mullow.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/mullow.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/mullow_KS.c b/external/flint-2.4.3/fq_nmod_poly/mullow_KS.c new file mode 100644 index 0000000..d6c4410 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/mullow_KS.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/mullow_KS.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/mullow_classical.c b/external/flint-2.4.3/fq_nmod_poly/mullow_classical.c new file mode 100644 index 0000000..2413c58 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/mullow_classical.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/mullow_classical.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/mulmod.c b/external/flint-2.4.3/fq_nmod_poly/mulmod.c new file mode 100644 index 0000000..4390e63 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/mulmod.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/mulmod.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/mulmod_preinv.c b/external/flint-2.4.3/fq_nmod_poly/mulmod_preinv.c new file mode 100644 index 0000000..02c3e05 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/mulmod_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/mulmod_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/neg.c b/external/flint-2.4.3/fq_nmod_poly/neg.c new file mode 100644 index 0000000..d90b79e --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/neg.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/neg.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/normalise.c b/external/flint-2.4.3/fq_nmod_poly/normalise.c new file mode 100644 index 0000000..9bb76fb --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/normalise.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/normalise.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/one.c b/external/flint-2.4.3/fq_nmod_poly/one.c new file mode 100644 index 0000000..af7cce9 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/one.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/one.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/pow.c b/external/flint-2.4.3/fq_nmod_poly/pow.c new file mode 100644 index 0000000..e380c9d --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/pow.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/pow.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/powmod_fmpz_binexp.c b/external/flint-2.4.3/fq_nmod_poly/powmod_fmpz_binexp.c new file mode 100644 index 0000000..7769fbf --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/powmod_fmpz_binexp.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/powmod_fmpz_binexp.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/powmod_fmpz_binexp_preinv.c b/external/flint-2.4.3/fq_nmod_poly/powmod_fmpz_binexp_preinv.c new file mode 100644 index 0000000..ba1f2ba --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/powmod_fmpz_binexp_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/powmod_fmpz_binexp_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/powmod_fmpz_sliding_preinv.c b/external/flint-2.4.3/fq_nmod_poly/powmod_fmpz_sliding_preinv.c new file mode 100644 index 0000000..1b31ceb --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/powmod_fmpz_sliding_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/powmod_fmpz_sliding_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/powmod_ui_binexp.c b/external/flint-2.4.3/fq_nmod_poly/powmod_ui_binexp.c new file mode 100644 index 0000000..0fdfaa2 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/powmod_ui_binexp.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/powmod_ui_binexp.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/powmod_ui_binexp_preinv.c b/external/flint-2.4.3/fq_nmod_poly/powmod_ui_binexp_preinv.c new file mode 100644 index 0000000..a36f764 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/powmod_ui_binexp_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/powmod_ui_binexp_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/powmod_x_fmpz_preinv.c b/external/flint-2.4.3/fq_nmod_poly/powmod_x_fmpz_preinv.c new file mode 100644 index 0000000..b32d19f --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/powmod_x_fmpz_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/powmod_x_fmpz_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/profile/p-factor_kaltofen_shoup_vs_fq_poly.c b/external/flint-2.4.3/fq_nmod_poly/profile/p-factor_kaltofen_shoup_vs_fq_poly.c new file mode 100644 index 0000000..e254b82 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/profile/p-factor_kaltofen_shoup_vs_fq_poly.c @@ -0,0 +1,164 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ +#include +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "ulong_extras.h" +#include "profiler.h" + +#include "fq_poly.h" +#include "fq_nmod_poly.h" + +#define nalgs 2 +#define ncases 1 +#define cpumin 2 + +int +main(int argc, char** argv) +{ + slong s[nalgs]; + + int c, n, len, ext, reps = 0; + slong j; + fmpz_t p, temp; + fq_poly_t f, g; + fq_nmod_poly_t fn; + fq_ctx_t ctx; + fq_nmod_ctx_t ctxn; + fmpz_poly_t fpoly; + nmod_poly_t nmod; + + FLINT_TEST_INIT(state); + + fmpz_init(p); + fmpz_set_str(p, argv[1], 10); + + fmpz_init(temp); + + fmpz_set_str(temp, argv[2], 10); + ext = fmpz_get_si(temp); + + fmpz_set_str(temp, argv[3], 10); + len = fmpz_get_si(temp); + + fq_ctx_init(ctx, p, ext, "a"); + + fmpz_poly_init(fpoly); + nmod_poly_init(nmod, fmpz_get_ui(p)); + fmpz_mod_poly_get_fmpz_poly(fpoly, ctx->modulus); + fmpz_poly_get_nmod_poly(nmod, fpoly); + + fq_nmod_ctx_init_modulus(ctxn, p, ext, nmod, "a"); + + fq_poly_init(f, ctx); + fq_poly_init(g, ctx); + fq_nmod_poly_init(fn, ctxn); + + for (c = 0; c < nalgs; c++) + { + s[c] = WORD(0); + } + + for (n = 0; n < ncases; n++) + { + timeit_t t[nalgs]; + int l, loops = 1; + fq_poly_factor_t res; + fq_nmod_poly_factor_t resn; + + /* + Construct random elements of fq + */ + { + fq_poly_randtest_irreducible(f, state, len + 1, ctx); + fq_poly_randtest_irreducible(g, state, len + 2, ctx); + fq_poly_mul(f, f, g, ctx); + fq_poly_make_monic(f, f, ctx); + + fq_nmod_poly_fit_length(fn, f->length, ctxn); + for (j = 0; j < f->length; j++) + { + fmpz_poly_get_nmod_poly(fn->coeffs + j, f->coeffs + j); + + } + _fq_nmod_poly_set_length(fn, f->length, ctxn); + } + + loop: + fflush(stdout); + timeit_start(t[0]); + for (l = 0; l < loops; l++) + { + fq_poly_factor_init(res, ctx); + fq_poly_factor_kaltofen_shoup(res, f, ctx); + fq_poly_factor_clear(res, ctx); + } + timeit_stop(t[0]); + + timeit_start(t[1]); + for (l = 0; l < loops; l++) + { + fq_nmod_poly_factor_init(resn, ctxn); + fq_nmod_poly_factor_kaltofen_shoup(resn, fn, ctxn); + fq_nmod_poly_factor_clear(resn, ctxn); + + } + timeit_stop(t[1]); + + for (c = 0; c < nalgs; c++) + if (t[c]->cpu <= cpumin) + { + loops += 2; + goto loop; + } + + for (c = 0; c < nalgs; c++) + s[c] += t[c]->cpu; + reps += loops; + } + + for (c = 0; c < nalgs; c++) + { + flint_printf("%20f ", s[c] / (double) reps); + fflush(stdout); + } + printf("\n"); + + fq_poly_clear(f, ctx); + fq_poly_clear(g, ctx); + fq_nmod_poly_clear(fn, ctxn); + nmod_poly_clear(nmod); + fq_ctx_clear(ctx); + fq_nmod_ctx_clear(ctxn); + fmpz_clear(p); + fmpz_clear(temp); + + FLINT_TEST_CLEANUP(state); + + return 0; +} diff --git a/external/flint-2.4.3/fq_nmod_poly/profile/p-factor_xnpxp1.c b/external/flint-2.4.3/fq_nmod_poly/profile/p-factor_xnpxp1.c new file mode 100644 index 0000000..43ed3c2 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/profile/p-factor_xnpxp1.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/profile/p-factor_xnpxp1.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/profile/p-is_irreducible.c b/external/flint-2.4.3/fq_nmod_poly/profile/p-is_irreducible.c new file mode 100644 index 0000000..034c890 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/profile/p-is_irreducible.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/profile/p-is_irreducible.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/profile/p-iterated_frobenius.c b/external/flint-2.4.3/fq_nmod_poly/profile/p-iterated_frobenius.c new file mode 100644 index 0000000..b02a225 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/profile/p-iterated_frobenius.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/profile/p-iterated_frobenius.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/profile/p-iterated_frobenius_table.c b/external/flint-2.4.3/fq_nmod_poly/profile/p-iterated_frobenius_table.c new file mode 100644 index 0000000..14f0191 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/profile/p-iterated_frobenius_table.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/profile/p-iterated_frobenius_table.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/profile/p-mullow.c b/external/flint-2.4.3/fq_nmod_poly/profile/p-mullow.c new file mode 100644 index 0000000..fdf42f6 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/profile/p-mullow.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/profile/p-mullow.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/randtest.c b/external/flint-2.4.3/fq_nmod_poly/randtest.c new file mode 100644 index 0000000..4be4561 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/randtest.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/randtest.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/randtest_irreducible.c b/external/flint-2.4.3/fq_nmod_poly/randtest_irreducible.c new file mode 100644 index 0000000..df4bbea --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/randtest_irreducible.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/randtest_irreducible.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/randtest_monic.c b/external/flint-2.4.3/fq_nmod_poly/randtest_monic.c new file mode 100644 index 0000000..8534c78 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/randtest_monic.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/randtest_monic.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/realloc.c b/external/flint-2.4.3/fq_nmod_poly/realloc.c new file mode 100644 index 0000000..cdddbb5 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/realloc.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/realloc.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/remove.c b/external/flint-2.4.3/fq_nmod_poly/remove.c new file mode 100644 index 0000000..d8ab126 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/remove.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/remove.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/reverse.c b/external/flint-2.4.3/fq_nmod_poly/reverse.c new file mode 100644 index 0000000..86df265 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/reverse.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/reverse.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/scalar_addmul_fq.c b/external/flint-2.4.3/fq_nmod_poly/scalar_addmul_fq.c new file mode 100644 index 0000000..39de4bc --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/scalar_addmul_fq.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/scalar_addmul_fq.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/scalar_mul_fq.c b/external/flint-2.4.3/fq_nmod_poly/scalar_mul_fq.c new file mode 100644 index 0000000..fc116f1 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/scalar_mul_fq.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/scalar_mul_fq.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/scalar_submul_fq.c b/external/flint-2.4.3/fq_nmod_poly/scalar_submul_fq.c new file mode 100644 index 0000000..37f1731 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/scalar_submul_fq.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/scalar_submul_fq.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/set.c b/external/flint-2.4.3/fq_nmod_poly/set.c new file mode 100644 index 0000000..a15a927 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/set.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/set.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/set_coeff.c b/external/flint-2.4.3/fq_nmod_poly/set_coeff.c new file mode 100644 index 0000000..4adbaf1 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/set_coeff.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/set_coeff.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/set_fq.c b/external/flint-2.4.3/fq_nmod_poly/set_fq.c new file mode 100644 index 0000000..ef79070 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/set_fq.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/set_fq.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/shift_left.c b/external/flint-2.4.3/fq_nmod_poly/shift_left.c new file mode 100644 index 0000000..778bda5 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/shift_left.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/shift_left.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/shift_right.c b/external/flint-2.4.3/fq_nmod_poly/shift_right.c new file mode 100644 index 0000000..bcbb038 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/shift_right.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/shift_right.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/sqr.c b/external/flint-2.4.3/fq_nmod_poly/sqr.c new file mode 100644 index 0000000..851b537 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/sqr.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/sqr.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/sqr_KS.c b/external/flint-2.4.3/fq_nmod_poly/sqr_KS.c new file mode 100644 index 0000000..9b3e6e5 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/sqr_KS.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/sqr_KS.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/sqr_classical.c b/external/flint-2.4.3/fq_nmod_poly/sqr_classical.c new file mode 100644 index 0000000..49b02c2 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/sqr_classical.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/sqr_classical.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/sub.c b/external/flint-2.4.3/fq_nmod_poly/sub.c new file mode 100644 index 0000000..96660d8 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/sub.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/sub.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/swap.c b/external/flint-2.4.3/fq_nmod_poly/swap.c new file mode 100644 index 0000000..73b7f58 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/swap.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/swap.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/test/t-add.c b/external/flint-2.4.3/fq_nmod_poly/test/t-add.c new file mode 100644 index 0000000..afb3045 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/test/t-add.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/test/t-add.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/test/t-compose.c b/external/flint-2.4.3/fq_nmod_poly/test/t-compose.c new file mode 100644 index 0000000..9d20be9 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/test/t-compose.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/test/t-compose.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/test/t-compose_divconquer.c b/external/flint-2.4.3/fq_nmod_poly/test/t-compose_divconquer.c new file mode 100644 index 0000000..1b39877 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/test/t-compose_divconquer.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/test/t-compose_divconquer.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/test/t-compose_horner.c b/external/flint-2.4.3/fq_nmod_poly/test/t-compose_horner.c new file mode 100644 index 0000000..9e15f7d --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/test/t-compose_horner.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/test/t-compose_horner.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/test/t-compose_mod.c b/external/flint-2.4.3/fq_nmod_poly/test/t-compose_mod.c new file mode 100644 index 0000000..adcb481 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/test/t-compose_mod.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/test/t-compose_mod.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/test/t-compose_mod_brent_kung.c b/external/flint-2.4.3/fq_nmod_poly/test/t-compose_mod_brent_kung.c new file mode 100644 index 0000000..0edc424 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/test/t-compose_mod_brent_kung.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/test/t-compose_mod_brent_kung.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/test/t-compose_mod_brent_kung_preinv.c b/external/flint-2.4.3/fq_nmod_poly/test/t-compose_mod_brent_kung_preinv.c new file mode 100644 index 0000000..1829044 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/test/t-compose_mod_brent_kung_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/test/t-compose_mod_brent_kung_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/test/t-compose_mod_horner.c b/external/flint-2.4.3/fq_nmod_poly/test/t-compose_mod_horner.c new file mode 100644 index 0000000..2641a86 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/test/t-compose_mod_horner.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/test/t-compose_mod_horner.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/test/t-compose_mod_horner_preinv.c b/external/flint-2.4.3/fq_nmod_poly/test/t-compose_mod_horner_preinv.c new file mode 100644 index 0000000..eee393b --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/test/t-compose_mod_horner_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/test/t-compose_mod_horner_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/test/t-compose_mod_preinv.c b/external/flint-2.4.3/fq_nmod_poly/test/t-compose_mod_preinv.c new file mode 100644 index 0000000..bd44414 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/test/t-compose_mod_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/test/t-compose_mod_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/test/t-deflate.c b/external/flint-2.4.3/fq_nmod_poly/test/t-deflate.c new file mode 100644 index 0000000..ebd52a8 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/test/t-deflate.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/test/t-deflate.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/test/t-derivative.c b/external/flint-2.4.3/fq_nmod_poly/test/t-derivative.c new file mode 100644 index 0000000..65f42fd --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/test/t-derivative.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/test/t-derivative.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/test/t-div_basecase.c b/external/flint-2.4.3/fq_nmod_poly/test/t-div_basecase.c new file mode 100644 index 0000000..03310d5 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/test/t-div_basecase.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/test/t-div_basecase.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/test/t-div_newton_n_preinv.c b/external/flint-2.4.3/fq_nmod_poly/test/t-div_newton_n_preinv.c new file mode 100644 index 0000000..1630836 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/test/t-div_newton_n_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/test/t-div_newton_n_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/test/t-divides.c b/external/flint-2.4.3/fq_nmod_poly/test/t-divides.c new file mode 100644 index 0000000..4613ea6 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/test/t-divides.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/test/t-divides.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/test/t-divrem_basecase.c b/external/flint-2.4.3/fq_nmod_poly/test/t-divrem_basecase.c new file mode 100644 index 0000000..cd7092f --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/test/t-divrem_basecase.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/test/t-divrem_basecase.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/test/t-divrem_divconquer.c b/external/flint-2.4.3/fq_nmod_poly/test/t-divrem_divconquer.c new file mode 100644 index 0000000..12cf549 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/test/t-divrem_divconquer.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/test/t-divrem_divconquer.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/test/t-divrem_newton_n_preinv.c b/external/flint-2.4.3/fq_nmod_poly/test/t-divrem_newton_n_preinv.c new file mode 100644 index 0000000..6c9a7e2 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/test/t-divrem_newton_n_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/test/t-divrem_newton_n_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/test/t-evaluate_fq.c b/external/flint-2.4.3/fq_nmod_poly/test/t-evaluate_fq.c new file mode 100644 index 0000000..f547b1a --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/test/t-evaluate_fq.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/test/t-evaluate_fq.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/test/t-gcd_euclidean.c b/external/flint-2.4.3/fq_nmod_poly/test/t-gcd_euclidean.c new file mode 100644 index 0000000..8d281de --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/test/t-gcd_euclidean.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/test/t-gcd_euclidean.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/test/t-get_str.c b/external/flint-2.4.3/fq_nmod_poly/test/t-get_str.c new file mode 100644 index 0000000..2c9e3ef --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/test/t-get_str.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/test/t-get_str.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/test/t-get_str_pretty.c b/external/flint-2.4.3/fq_nmod_poly/test/t-get_str_pretty.c new file mode 100644 index 0000000..89ac029 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/test/t-get_str_pretty.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/test/t-get_str_pretty.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/test/t-hamming_weight.c b/external/flint-2.4.3/fq_nmod_poly/test/t-hamming_weight.c new file mode 100644 index 0000000..d1a00b8 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/test/t-hamming_weight.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/test/t-hamming_weight.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/test/t-inflate.c b/external/flint-2.4.3/fq_nmod_poly/test/t-inflate.c new file mode 100644 index 0000000..83bbdcc --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/test/t-inflate.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/test/t-inflate.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/test/t-inv_series_newton.c b/external/flint-2.4.3/fq_nmod_poly/test/t-inv_series_newton.c new file mode 100644 index 0000000..4f0eec2 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/test/t-inv_series_newton.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/test/t-inv_series_newton.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/test/t-make_monic.c b/external/flint-2.4.3/fq_nmod_poly/test/t-make_monic.c new file mode 100644 index 0000000..df0c501 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/test/t-make_monic.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/test/t-make_monic.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/test/t-mul.c b/external/flint-2.4.3/fq_nmod_poly/test/t-mul.c new file mode 100644 index 0000000..d473a61 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/test/t-mul.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/test/t-mul.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/test/t-mul_KS.c b/external/flint-2.4.3/fq_nmod_poly/test/t-mul_KS.c new file mode 100644 index 0000000..63c5bf2 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/test/t-mul_KS.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/test/t-mul_KS.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/test/t-mul_classical.c b/external/flint-2.4.3/fq_nmod_poly/test/t-mul_classical.c new file mode 100644 index 0000000..93624b7 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/test/t-mul_classical.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/test/t-mul_classical.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/test/t-mullow.c b/external/flint-2.4.3/fq_nmod_poly/test/t-mullow.c new file mode 100644 index 0000000..ccc4ec5 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/test/t-mullow.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/test/t-mullow.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/test/t-mullow_KS.c b/external/flint-2.4.3/fq_nmod_poly/test/t-mullow_KS.c new file mode 100644 index 0000000..1ebf4f1 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/test/t-mullow_KS.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/test/t-mullow_KS.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/test/t-mullow_classical.c b/external/flint-2.4.3/fq_nmod_poly/test/t-mullow_classical.c new file mode 100644 index 0000000..59a050b --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/test/t-mullow_classical.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/test/t-mullow_classical.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/test/t-mulmod.c b/external/flint-2.4.3/fq_nmod_poly/test/t-mulmod.c new file mode 100644 index 0000000..84e1a51 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/test/t-mulmod.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/test/t-mulmod.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/test/t-mulmod_preinv.c b/external/flint-2.4.3/fq_nmod_poly/test/t-mulmod_preinv.c new file mode 100644 index 0000000..0243f7d --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/test/t-mulmod_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/test/t-mulmod_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/test/t-neg.c b/external/flint-2.4.3/fq_nmod_poly/test/t-neg.c new file mode 100644 index 0000000..e266abe --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/test/t-neg.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/test/t-neg.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/test/t-pow.c b/external/flint-2.4.3/fq_nmod_poly/test/t-pow.c new file mode 100644 index 0000000..086c6cd --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/test/t-pow.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/test/t-pow.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/test/t-powmod_fmpz_binexp.c b/external/flint-2.4.3/fq_nmod_poly/test/t-powmod_fmpz_binexp.c new file mode 100644 index 0000000..5964be7 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/test/t-powmod_fmpz_binexp.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/test/t-powmod_fmpz_binexp.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/test/t-powmod_fmpz_binexp_preinv.c b/external/flint-2.4.3/fq_nmod_poly/test/t-powmod_fmpz_binexp_preinv.c new file mode 100644 index 0000000..e07b010 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/test/t-powmod_fmpz_binexp_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/test/t-powmod_fmpz_binexp_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/test/t-powmod_fmpz_sliding_preinv.c b/external/flint-2.4.3/fq_nmod_poly/test/t-powmod_fmpz_sliding_preinv.c new file mode 100644 index 0000000..a68e6a3 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/test/t-powmod_fmpz_sliding_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/test/t-powmod_fmpz_sliding_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/test/t-powmod_ui_binexp.c b/external/flint-2.4.3/fq_nmod_poly/test/t-powmod_ui_binexp.c new file mode 100644 index 0000000..66dfc62 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/test/t-powmod_ui_binexp.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/test/t-powmod_ui_binexp.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/test/t-powmod_ui_binexp_preinv.c b/external/flint-2.4.3/fq_nmod_poly/test/t-powmod_ui_binexp_preinv.c new file mode 100644 index 0000000..9d9c943 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/test/t-powmod_ui_binexp_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/test/t-powmod_ui_binexp_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/test/t-powmod_x_fmpz_preinv.c b/external/flint-2.4.3/fq_nmod_poly/test/t-powmod_x_fmpz_preinv.c new file mode 100644 index 0000000..0b746cc --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/test/t-powmod_x_fmpz_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/test/t-powmod_x_fmpz_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/test/t-randtest_irreducible.c b/external/flint-2.4.3/fq_nmod_poly/test/t-randtest_irreducible.c new file mode 100644 index 0000000..b5bf9c9 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/test/t-randtest_irreducible.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/test/t-randtest_irreducible.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/test/t-scalar_addmul_fq.c b/external/flint-2.4.3/fq_nmod_poly/test/t-scalar_addmul_fq.c new file mode 100644 index 0000000..5ce2888 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/test/t-scalar_addmul_fq.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/test/t-scalar_addmul_fq.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/test/t-scalar_mul_fq.c b/external/flint-2.4.3/fq_nmod_poly/test/t-scalar_mul_fq.c new file mode 100644 index 0000000..dc5dcc1 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/test/t-scalar_mul_fq.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/test/t-scalar_mul_fq.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/test/t-scalar_submul_fq.c b/external/flint-2.4.3/fq_nmod_poly/test/t-scalar_submul_fq.c new file mode 100644 index 0000000..4ae8e11 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/test/t-scalar_submul_fq.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/test/t-scalar_submul_fq.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/test/t-shift_left_right.c b/external/flint-2.4.3/fq_nmod_poly/test/t-shift_left_right.c new file mode 100644 index 0000000..cbcba3d --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/test/t-shift_left_right.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/test/t-shift_left_right.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/test/t-sqr.c b/external/flint-2.4.3/fq_nmod_poly/test/t-sqr.c new file mode 100644 index 0000000..f9df42a --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/test/t-sqr.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/test/t-sqr.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/test/t-sqr_KS.c b/external/flint-2.4.3/fq_nmod_poly/test/t-sqr_KS.c new file mode 100644 index 0000000..af923cc --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/test/t-sqr_KS.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/test/t-sqr_KS.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/test/t-sqr_classical.c b/external/flint-2.4.3/fq_nmod_poly/test/t-sqr_classical.c new file mode 100644 index 0000000..fb98ed3 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/test/t-sqr_classical.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/test/t-sqr_classical.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/test/t-sub.c b/external/flint-2.4.3/fq_nmod_poly/test/t-sub.c new file mode 100644 index 0000000..ff94b92 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/test/t-sub.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/test/t-sub.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly/truncate.c b/external/flint-2.4.3/fq_nmod_poly/truncate.c new file mode 100644 index 0000000..d905c13 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly/truncate.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_templates/truncate.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly_factor.h b/external/flint-2.4.3/fq_nmod_poly_factor.h new file mode 100644 index 0000000..85deb96 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly_factor.h @@ -0,0 +1,53 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#ifndef FQ_NMOD_POLY_FACTOR_H +#define FQ_NMOD_POLY_FACTOR_H + +static __inline__ int FQ_NMOD_POLY_ITERATED_FROBENIUS_CUTOFF(const fq_nmod_ctx_t ctx, slong length) +{ + int result; + fmpz_t q; + fmpz_init(q); + fq_nmod_ctx_order(q, ctx); + if ( 2 * fmpz_sizeinbase(q, 2) < 3 * (n_sqrt(length) + 1)) + result = 1; + else + result = 0; + fmpz_clear(q); + return result; +} + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_factor_templates.h" +#undef CAP_T +#undef T + +#endif diff --git a/external/flint-2.4.3/fq_nmod_poly_factor/clear.c b/external/flint-2.4.3/fq_nmod_poly_factor/clear.c new file mode 100644 index 0000000..e37b81b --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly_factor/clear.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_factor_templates/clear.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly_factor/concat.c b/external/flint-2.4.3/fq_nmod_poly_factor/concat.c new file mode 100644 index 0000000..7e99104 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly_factor/concat.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_factor_templates/concat.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly_factor/doc/fq_nmod_poly_factor.txt b/external/flint-2.4.3/fq_nmod_poly_factor/doc/fq_nmod_poly_factor.txt new file mode 100644 index 0000000..6a178de --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly_factor/doc/fq_nmod_poly_factor.txt @@ -0,0 +1,254 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012,2013 Andres Goens + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +******************************************************************************* + + Memory Management + +******************************************************************************* + +void fq_nmod_poly_factor_init(fq_nmod_poly_factor_t fac, const fq_nmod_ctx_t ctx) + + Initialises \code{fac} for use. An \code{fq_nmod_poly_factor_t} + represents a polynomial in factorised form as a product of + polynomials with associated exponents. + +void fq_nmod_poly_factor_clear(fq_nmod_poly_factor_t fac, const fq_nmod_ctx_t ctx) + + Frees all memory associated with \code{fac}. + +void fq_nmod_poly_factor_realloc(fq_nmod_poly_factor_t fac, slong alloc, + const fq_nmod_ctx_t ctx) + + Reallocates the factor structure to provide space for + precisely \code{alloc} factors. + +void fq_nmod_poly_factor_fit_length(fq_nmod_poly_factor_t fac, slong len, + const fq_nmod_ctx_t ctx) + + Ensures that the factor structure has space for at least + \code{len} factors. This functions takes care of the case of + repeated calls by always at least doubling the number of factors + the structure can hold. + +******************************************************************************* + + Basic Operations + +******************************************************************************* + +void fq_nmod_poly_factor_set(fq_nmod_poly_factor_t res, const fq_nmod_poly_factor_t fac, + const fq_nmod_ctx_t ctx) + + Sets \code{res} to the same factorisation as \code{fac}. + +void fq_nmod_poly_factor_print_pretty(const fq_nmod_poly_factor_t fac, const fq_nmod_ctx_t ctx) + + Pretty-prints the entries of \code{fac} to standard output. + +void fq_nmod_poly_factor_print(const fq_nmod_poly_factor_t fac, const fq_nmod_ctx_t ctx) + + Prints the entries of \code{fac} to standard output. + +void fq_nmod_poly_factor_insert(fq_nmod_poly_factor_t fac, const fq_nmod_poly_t poly, + slong exp, const fq_nmod_ctx_t ctx) + + Inserts the factor \code{poly} with multiplicity \code{exp} into + the factorisation \code{fac}. + + If \code{fac} already contains \code{poly}, then \code{exp} simply + gets added to the exponent of the existing entry. + +void fq_nmod_poly_factor_concat(fq_nmod_poly_factor_t res, const fq_nmod_poly_factor_t fac, + const fq_nmod_ctx_t ctx) + + Concatenates two factorisations. + + This is equivalent to calling \code{fq_nmod_poly_factor_insert()} + repeatedly with the individual factors of \code{fac}. + + Does not support aliasing between \code{res} and \code{fac}. + +void fq_nmod_poly_factor_pow(fq_nmod_poly_factor_t fac, slong exp, const fq_nmod_ctx_t ctx) + + Raises \code{fac} to the power \code{exp}. + +ulong fq_nmod_poly_remove(fq_nmod_poly_t f, const fq_nmod_poly_t p, const fq_nmod_ctx_t ctx) + + Removes the highest possible power of \code{p} from \code{f} and + returns the exponent. + +******************************************************************************* + + Irreducibility Testing + +******************************************************************************* + +int fq_nmod_poly_is_irreducible(const fq_nmod_poly_t f, const fq_nmod_ctx_t ctx) + + Returns 1 if the polynomial \code{f} is irreducible, otherwise returns 0. + +int fq_nmod_poly_is_irreducible_ddf(const fq_nmod_poly_t f, const fq_nmod_ctx_t ctx) + + Returns 1 if the polynomial \code{f} is irreducible, otherwise returns 0. + Uses fast distinct-degree factorisation. + +int fq_nmod_poly_is_irreducible_ben_or(const fq_nmod_poly_t f, const fq_nmod_ctx_t ctx) + + Returns 1 if the polynomial \code{f} is irreducible, otherwise returns 0. + Uses Ben-Or's irreducibility test. + +int _fq_nmod_poly_is_squarefree(const fq_nmod_struct * f, slong len, const fq_nmod_ctx_t ctx) + + Returns 1 if \code{(f, len)} is squarefree, and 0 otherwise. As a + special case, the zero polynomial is not considered squarefree. + There are no restrictions on the length. + +int fq_nmod_poly_is_squarefree(const fq_nmod_poly_t f, const fq_nmod_ctx_t ctx) + + Returns 1 if \code{f} is squarefree, and 0 otherwise. As a special + case, the zero polynomial is not considered squarefree. + +******************************************************************************* + + Factorisation + +******************************************************************************* + +int fq_nmod_poly_factor_equal_deg_prob(fq_nmod_poly_t factor, flint_rand_t state, + const fq_nmod_poly_t pol, slong d, + const fq_nmod_ctx_t ctx) + + Probabilistic equal degree factorisation of \code{pol} into + irreducible factors of degree \code{d}. If it passes, a factor is + placed in factor and 1 is returned, otherwise 0 is returned and + the value of factor is undetermined. + + Requires that \code{pol} be monic, non-constant and squarefree. + +void fq_nmod_poly_factor_equal_deg(fq_nmod_poly_factor_t factors, const fq_nmod_poly_t pol, + slong d, const fq_nmod_ctx_t ctx) + + Assuming \code{pol} is a product of irreducible factors all of + degree \code{d}, finds all those factors and places them in + factors. Requires that \code{pol} be monic, non-constant and + squarefree. + +void fq_nmod_poly_factor_distinct_deg(fq_nmod_poly_factor_t res, const fq_nmod_poly_t poly, + slong * const *degs, const fq_nmod_ctx_t ctx) + + Factorises a monic non-constant squarefree polymnomial \code{poly} + of degree n into factors $f[d]$ such that for $1 \leq d \leq n$ + $f[d]$ is the product of the monic irreducible factors of + \code{poly} of degree $d$. Factors are stored in \code{res}, + assotiated powers of irreducible polynomials are stored in + \code{degs} in the same order as factors. + + Requires that \code{degs} have enough space for irreducible polynomials' + powers (maximum space required is $n * sizeof(slong)$). + +void fq_nmod_poly_factor_squarefree(fq_nmod_poly_factor_t res, const fq_nmod_poly_t f, + const fq_nmod_ctx_t ctx) + + Sets \code{res} to a squarefree factorization of \code{f}. + +void fq_nmod_poly_factor(fq_nmod_poly_factor_t res, const fq_nmod_poly_t f, const fq_nmod_ctx_t ctx) + + Factorises a non-constant polynomial \code{f} into monic + irreducible factors choosing the best algorithm for given modulo + and degree. Choise is based on heuristic measurments. + +void fq_nmod_poly_factor_cantor_zassenhaus(fq_nmod_poly_factor_t res, const fq_nmod_poly_t f, + const fq_nmod_ctx_t ctx) + + Factorises a non-constant polynomial \code{f} into monic + irreducible factors using the Cantor-Zassenhaus algorithm. + +void fq_nmod_poly_factor_kaltofen_shoup(fq_nmod_poly_factor_t res, const fq_nmod_poly_t poly, + const fq_nmod_ctx_t ctx) + + Factorises a non-constant polynomial \code{f} into monic + irreducible factors using the fast version of Cantor-Zassenhaus + algorithm proposed by Kaltofen and Shoup (1998). More precisely + this algorithm uses a “baby step/giant step†strategy for the + distinct-degree factorization step. + +void fq_nmod_poly_factor_berlekamp(fq_nmod_poly_factor_t factors, const fq_nmod_poly_t f, + const fq_nmod_ctx_t ctx) + + Factorises a non-constant polynomial \code{f} into monic + irreducible factors using the Berlekamp algorithm. + +void fq_nmod_poly_factor_with_berlekamp(fq_nmod_poly_factor_t res, fq_nmod_t leading_coeff, + const fq_nmod_poly_t f, const fq_nmod_ctx_t) + + Factorises a general polynomial \code{f} into monic irreducible + factors and sets \code{leading_coeff} to the leading coefficient + of \code{f}, or 0 if \code{f} is the zero polynomial. + + This function first checks for small special cases, deflates + \code{f} if it is of the form $p(x^m)$ for some $m > 1$, then + performs a square-free factorisation, and finally runs Berlekamp + on all the individual square-free factors. + +void fq_nmod_poly_factor_with_cantor_zassenhaus(fq_nmod_poly_factor_t res, + fq_nmod_t leading_coeff + const fq_nmod_poly_t f, + const fq_nmod_ctx_t ctx) + + Factorises a general polynomial \code{f} into monic irreducible + factors and sets \code{leading_coeff} to the leading coefficient + of \code{f}, or 0 if \code{f} is the zero polynomial. + + This function first checks for small special cases, deflates + \code{f} if it is of the form $p(x^m)$ for some $m > 1$, then + performs a square-free factorisation, and finally runs + Cantor-Zassenhaus on all the individual square-free factors. + +void fq_nmod_poly_factor_with_kaltofen_shoup(fq_nmod_poly_factor_t res, + fq_nmod_t leading_coeff, + const fq_nmod_poly_t f, + const fq_nmod_ctx_t ctx) + + Factorises a general polynomial \code{f} into monic irreducible + factors and sets \code{leading_coeff} to the leading coefficient + of \code{f}, or 0 if \code{f} is the zero polynomial. + + This function first checks for small special cases, deflates + \code{f} if it is of the form $p(x^m)$ for some $m > 1$, then + performs a square-free factorisation, and finally runs + Kaltofen-Shoup on all the individual square-free factors. + +void fq_nmod_poly_iterated_frobenius_preinv(fq_nmod_poly_t *rop, slong n, + const fq_nmod_poly_t v, + const fq_nmod_poly_t vinv, + const fq_nmod_ctx_t ctx) + + Sets \code{rop[i]} to be $x^{q^i} mod v$ for $0 <= i < n$. + + It is required that \code{vinv} is the inverse of the reverse of + \code{v} mod \code{x^lenv}. diff --git a/external/flint-2.4.3/fq_nmod_poly_factor/factor.c b/external/flint-2.4.3/fq_nmod_poly_factor/factor.c new file mode 100644 index 0000000..cb34501 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly_factor/factor.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_factor_templates/factor.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly_factor/factor_berlekamp.c b/external/flint-2.4.3/fq_nmod_poly_factor/factor_berlekamp.c new file mode 100644 index 0000000..4e294ba --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly_factor/factor_berlekamp.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_factor_templates/factor_berlekamp.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly_factor/factor_cantor_zassenhaus.c b/external/flint-2.4.3/fq_nmod_poly_factor/factor_cantor_zassenhaus.c new file mode 100644 index 0000000..e43d2ad --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly_factor/factor_cantor_zassenhaus.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_factor_templates/factor_cantor_zassenhaus.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly_factor/factor_distinct_deg.c b/external/flint-2.4.3/fq_nmod_poly_factor/factor_distinct_deg.c new file mode 100644 index 0000000..54e7474 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly_factor/factor_distinct_deg.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_factor_templates/factor_distinct_deg.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly_factor/factor_equal_deg.c b/external/flint-2.4.3/fq_nmod_poly_factor/factor_equal_deg.c new file mode 100644 index 0000000..e5f84ba --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly_factor/factor_equal_deg.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_factor_templates/factor_equal_deg.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly_factor/factor_equal_deg_prob.c b/external/flint-2.4.3/fq_nmod_poly_factor/factor_equal_deg_prob.c new file mode 100644 index 0000000..7e78eec --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly_factor/factor_equal_deg_prob.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_factor_templates/factor_equal_deg_prob.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly_factor/factor_kaltofen_shoup.c b/external/flint-2.4.3/fq_nmod_poly_factor/factor_kaltofen_shoup.c new file mode 100644 index 0000000..1b10784 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly_factor/factor_kaltofen_shoup.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_factor_templates/factor_kaltofen_shoup.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly_factor/factor_squarefree.c b/external/flint-2.4.3/fq_nmod_poly_factor/factor_squarefree.c new file mode 100644 index 0000000..28d3686 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly_factor/factor_squarefree.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_factor_templates/factor_squarefree.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly_factor/fit_length.c b/external/flint-2.4.3/fq_nmod_poly_factor/fit_length.c new file mode 100644 index 0000000..c476421 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly_factor/fit_length.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_factor_templates/fit_length.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly_factor/init.c b/external/flint-2.4.3/fq_nmod_poly_factor/init.c new file mode 100644 index 0000000..1858a5d --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly_factor/init.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_factor_templates/init.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly_factor/insert.c b/external/flint-2.4.3/fq_nmod_poly_factor/insert.c new file mode 100644 index 0000000..f8fe6a2 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly_factor/insert.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_factor_templates/insert.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly_factor/is_irreducible.c b/external/flint-2.4.3/fq_nmod_poly_factor/is_irreducible.c new file mode 100644 index 0000000..26a4324 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly_factor/is_irreducible.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_factor_templates/is_irreducible.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly_factor/is_irreducible_ben_or.c b/external/flint-2.4.3/fq_nmod_poly_factor/is_irreducible_ben_or.c new file mode 100644 index 0000000..9ca16cc --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly_factor/is_irreducible_ben_or.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_factor_templates/is_irreducible_ben_or.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly_factor/is_irreducible_ddf.c b/external/flint-2.4.3/fq_nmod_poly_factor/is_irreducible_ddf.c new file mode 100644 index 0000000..a6db7a5 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly_factor/is_irreducible_ddf.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_factor_templates/is_irreducible_ddf.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly_factor/is_squarefree.c b/external/flint-2.4.3/fq_nmod_poly_factor/is_squarefree.c new file mode 100644 index 0000000..7dbcd52 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly_factor/is_squarefree.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_factor_templates/is_squarefree.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly_factor/iterated_frobenius_preinv.c b/external/flint-2.4.3/fq_nmod_poly_factor/iterated_frobenius_preinv.c new file mode 100644 index 0000000..f90b1a8 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly_factor/iterated_frobenius_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_factor_templates/iterated_frobenius_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly_factor/pow.c b/external/flint-2.4.3/fq_nmod_poly_factor/pow.c new file mode 100644 index 0000000..f4953db --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly_factor/pow.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_factor_templates/pow.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly_factor/print.c b/external/flint-2.4.3/fq_nmod_poly_factor/print.c new file mode 100644 index 0000000..489c9b9 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly_factor/print.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_factor_templates/print.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly_factor/print_pretty.c b/external/flint-2.4.3/fq_nmod_poly_factor/print_pretty.c new file mode 100644 index 0000000..d5d1838 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly_factor/print_pretty.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_factor_templates/print_pretty.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly_factor/realloc.c b/external/flint-2.4.3/fq_nmod_poly_factor/realloc.c new file mode 100644 index 0000000..97a4531 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly_factor/realloc.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_factor_templates/realloc.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly_factor/set.c b/external/flint-2.4.3/fq_nmod_poly_factor/set.c new file mode 100644 index 0000000..13dc6cd --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly_factor/set.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_factor_templates/set.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly_factor/test/t-factor.c b/external/flint-2.4.3/fq_nmod_poly_factor/test/t-factor.c new file mode 100644 index 0000000..c015b93 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly_factor/test/t-factor.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_factor_templates/test/t-factor.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly_factor/test/t-factor_berlekamp.c b/external/flint-2.4.3/fq_nmod_poly_factor/test/t-factor_berlekamp.c new file mode 100644 index 0000000..91d0af2 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly_factor/test/t-factor_berlekamp.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_factor_templates/test/t-factor_berlekamp.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly_factor/test/t-factor_cantor_zassenhaus.c b/external/flint-2.4.3/fq_nmod_poly_factor/test/t-factor_cantor_zassenhaus.c new file mode 100644 index 0000000..0ba6640 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly_factor/test/t-factor_cantor_zassenhaus.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_factor_templates/test/t-factor_cantor_zassenhaus.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly_factor/test/t-factor_distinct_deg.c b/external/flint-2.4.3/fq_nmod_poly_factor/test/t-factor_distinct_deg.c new file mode 100644 index 0000000..fac0023 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly_factor/test/t-factor_distinct_deg.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_factor_templates/test/t-factor_distinct_deg.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly_factor/test/t-factor_equal_deg_prob.c b/external/flint-2.4.3/fq_nmod_poly_factor/test/t-factor_equal_deg_prob.c new file mode 100644 index 0000000..dd68115 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly_factor/test/t-factor_equal_deg_prob.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_factor_templates/test/t-factor_equal_deg_prob.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly_factor/test/t-factor_kaltofen_shoup.c b/external/flint-2.4.3/fq_nmod_poly_factor/test/t-factor_kaltofen_shoup.c new file mode 100644 index 0000000..901cb98 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly_factor/test/t-factor_kaltofen_shoup.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_factor_templates/test/t-factor_kaltofen_shoup.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly_factor/test/t-factor_squarefree.c b/external/flint-2.4.3/fq_nmod_poly_factor/test/t-factor_squarefree.c new file mode 100644 index 0000000..496f501 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly_factor/test/t-factor_squarefree.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_factor_templates/test/t-factor_squarefree.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly_factor/test/t-is_irreducible.c b/external/flint-2.4.3/fq_nmod_poly_factor/test/t-is_irreducible.c new file mode 100644 index 0000000..7ea28c3 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly_factor/test/t-is_irreducible.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_factor_templates/test/t-is_irreducible.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly_factor/test/t-is_irreducible_ben_or.c b/external/flint-2.4.3/fq_nmod_poly_factor/test/t-is_irreducible_ben_or.c new file mode 100644 index 0000000..869ad43 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly_factor/test/t-is_irreducible_ben_or.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_factor_templates/test/t-is_irreducible_ben_or.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly_factor/test/t-is_irreducible_ddf.c b/external/flint-2.4.3/fq_nmod_poly_factor/test/t-is_irreducible_ddf.c new file mode 100644 index 0000000..0171b60 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly_factor/test/t-is_irreducible_ddf.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_factor_templates/test/t-is_irreducible_ddf.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly_factor/test/t-is_squarefree.c b/external/flint-2.4.3/fq_nmod_poly_factor/test/t-is_squarefree.c new file mode 100644 index 0000000..6192e73 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly_factor/test/t-is_squarefree.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_factor_templates/test/t-is_squarefree.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_poly_factor/test/t-iterated_frobenius_preinv.c b/external/flint-2.4.3/fq_nmod_poly_factor/test/t-iterated_frobenius_preinv.c new file mode 100644 index 0000000..95256a1 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_poly_factor/test/t-iterated_frobenius_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_poly_factor_templates/test/t-iterated_frobenius_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_vec.h b/external/flint-2.4.3/fq_nmod_vec.h new file mode 100644 index 0000000..57dcc6f --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_vec.h @@ -0,0 +1,57 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#ifndef FQ_NMOD_VEC_H +#define FQ_NMOD_VEC_H + +#include "fq_nmod.h" + +#define FQ_NMOD_VEC_NORM(vec, i, ctx) \ +do { \ + while ((i) && fq_nmod_is_zero((vec) + (i) - 1, ctx)) \ + (i)--; \ +} while (0) + + +#define FQ_NMOD_VEC_SWAP(vec1, len1, vec2, len2) \ +do { \ + fq_nmod_struct *__t; \ + slong __tn; \ + __t = (vec1); \ + (vec1) = (vec2); \ + (vec2) = __t; \ + __tn = (len1); \ + (len1) = (len2); \ + (len2) = __tn; \ +} while (0); + + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_vec_templates.h" +#undef CAP_T +#undef T + +#endif diff --git a/external/flint-2.4.3/fq_nmod_vec/add.c b/external/flint-2.4.3/fq_nmod_vec/add.c new file mode 100644 index 0000000..7d5fd84 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_vec/add.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_vec_templates/add.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_vec/clear.c b/external/flint-2.4.3/fq_nmod_vec/clear.c new file mode 100644 index 0000000..0870a41 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_vec/clear.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_vec_templates/clear.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_vec/doc/fq_nmod_vec.txt b/external/flint-2.4.3/fq_nmod_vec/doc/fq_nmod_vec.txt new file mode 100644 index 0000000..5b87406 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_vec/doc/fq_nmod_vec.txt @@ -0,0 +1,168 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +******************************************************************************* + + Memory management + +******************************************************************************* + +fq_nmod_struct * _fq_nmod_vec_init(slong len, const fq_nmod_ctx_t ctx) + + Returns an initialised vector of \code{fq_nmod}'s of given length. + +void _fq_nmod_vec_clear(fq_nmod * vec, slong len, const fq_nmod_ctx_t ctx) + + Clears the entries of \code{(vec, len)} and frees the space allocated + for \code{vec}. + +******************************************************************************* + + Randomisation + +******************************************************************************* + +void _fq_nmod_vec_randtest(fq_nmod_struct * f, flint_rand_t state, + slong len, const fq_nmod_ctx_t ctx) + + Sets the entries of a vector of the given length to elements of + the finite field. + +******************************************************************************* + + Input and output + +******************************************************************************* + +int _fq_nmod_vec_fprint(FILE * file, const fq_nmod_struct * vec, slong len, + const fq_nmod_ctx_t ctx) + + Prints the vector of given length to the stream \code{file}. The + format is the length followed by two spaces, then a space separated + list of coefficients. If the length is zero, only $0$ is printed. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + +int _fq_nmod_vec_print(const fq_nmod_struct * vec, slong len, + const fq_nmod_ctx_t ctx) + + Prints the vector of given length to \code{stdout}. + + For further details, see \code{_fq_nmod_vec_fprint()}. + +******************************************************************************* + + Assignment and basic manipulation + +******************************************************************************* + +void _fq_nmod_vec_set(fq_nmod_struct * vec1, const fq_nmod_struct * vec2, + slong len2, const fq_nmod_ctx_t ctx) + + Makes a copy of \code{(vec2, len2)} into \code{vec1}. + +void _fq_nmod_vec_swap(fq_nmod_struct * vec1, fq_nmod_struct * vec2, slong len2, + const fq_nmod_ctx_t ctx) + + Swaps the elements in \code{(vec1, len2)} and \code{(vec2, len2)}. + +void _fq_nmod_vec_zero(fq_nmod_struct * vec, slong len, const fq_nmod_ctx_t ctx) + + Zeros the entries of \code{(vec, len)}. + +void _fq_nmod_vec_neg(fq_nmod_struct * vec1, const fq_nmod_struct * vec2, + slong len2, const fq_nmod_ctx_t ctx) + + Negates \code{(vec2, len2)} and places it into \code{vec1}. + +******************************************************************************* + + Comparison + +******************************************************************************* + +int _fq_nmod_vec_equal(const fq_nmod_struct * vec1, const fq_nmod_struct * vec2, + slong len, const fq_nmod_ctx_t ctx) + + Compares two vectors of the given length and returns $1$ if they are + equal, otherwise returns $0$. + +int _fq_nmod_vec_is_zero(const fq_nmod_struct * vec, slong len, const ctx_ctx) + + Returns $1$ if \code{(vec, len)} is zero, and $0$ otherwise. + +******************************************************************************* + + Addition and subtraction + +******************************************************************************* + +void _fq_nmod_vec_add(fq_nmod_struct * res, const fq_nmod_struct * vec1, + const fq_nmod_struct * vec2, slong len2, + const fq_nmod_ctx_t ctx) + + Sets \code{(res, len2)} to the sum of \code{(vec1, len2)} + and \code{(vec2, len2)}. + +void _fq_nmod_vec_sub(fq_nmod_struct * res, const fq_nmod_struct * vec1, + const fq_nmod_struct * vec2, slong len2, + const fq_nmod_ctx_t ctx) + + Sets \code{(res, len2)} to \code{(vec1, len2)} minus \code{(vec2, len2)}. + +******************************************************************************* + + Scalar multiplication and division + +******************************************************************************* +void _fq_nmod_vec_scalar_addmul_fq_nmod(fq_nmod_struct * vec1, + const fq_nmod_struct * vec2, slong len2, + const fq_nmod_t c, + const fq_nmod_ctx_t ctx) + + Adds \code{(vec2, len2)} times $c$ to \code{(vec1, len2)}, where + $c$ is a \code{fq_nmod_t}. + +void _fq_nmod_vec_scalar_submul_fq_nmod(fq_nmod_struct * vec1, + const fq_nmod_struct * vec2, slong len2, + const fq_nmod_t c, + const fq_nmod_ctx_t ctx) + + Subtracts \code{(vec2, len2)} times $c$ from \code{(vec1, len2)}, + where $c$ is a \code{fq_nmod_t}. + +******************************************************************************* + + Dot products + +******************************************************************************* + +void _fq_nmod_vec_dot(fq_nmod_t res, const fq_nmod_struct * vec1, + const fq_nmod_struct * vec2, slong len2, + const fq_nmod_ctx_t ctx) + + Sets \code{res} to the dot product of (\code{vec1}, \code{len}) + and (\code{vec2}, \code{len}). diff --git a/external/flint-2.4.3/fq_nmod_vec/dot.c b/external/flint-2.4.3/fq_nmod_vec/dot.c new file mode 100644 index 0000000..4746436 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_vec/dot.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_vec_templates/dot.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_vec/equal.c b/external/flint-2.4.3/fq_nmod_vec/equal.c new file mode 100644 index 0000000..6cf82d4 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_vec/equal.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_vec_templates/equal.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_vec/fprint.c b/external/flint-2.4.3/fq_nmod_vec/fprint.c new file mode 100644 index 0000000..97bcb62 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_vec/fprint.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_vec_templates/fprint.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_vec/init.c b/external/flint-2.4.3/fq_nmod_vec/init.c new file mode 100644 index 0000000..80edeb8 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_vec/init.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_vec_templates/init.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_vec/is_zero.c b/external/flint-2.4.3/fq_nmod_vec/is_zero.c new file mode 100644 index 0000000..8d4b3f4 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_vec/is_zero.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_vec_templates/is_zero.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_vec/neg.c b/external/flint-2.4.3/fq_nmod_vec/neg.c new file mode 100644 index 0000000..8ae63c0 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_vec/neg.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_vec_templates/neg.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_vec/randtest.c b/external/flint-2.4.3/fq_nmod_vec/randtest.c new file mode 100644 index 0000000..05b4293 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_vec/randtest.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_vec_templates/randtest.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_vec/scalar_addmul_fq.c b/external/flint-2.4.3/fq_nmod_vec/scalar_addmul_fq.c new file mode 100644 index 0000000..0bc412a --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_vec/scalar_addmul_fq.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_vec_templates/scalar_addmul_fq.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_vec/scalar_submul_fq.c b/external/flint-2.4.3/fq_nmod_vec/scalar_submul_fq.c new file mode 100644 index 0000000..99bee3b --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_vec/scalar_submul_fq.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_vec_templates/scalar_submul_fq.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_vec/set.c b/external/flint-2.4.3/fq_nmod_vec/set.c new file mode 100644 index 0000000..a295d75 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_vec/set.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_vec_templates/set.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_vec/sub.c b/external/flint-2.4.3/fq_nmod_vec/sub.c new file mode 100644 index 0000000..3dae661 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_vec/sub.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_vec_templates/sub.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_vec/swap.c b/external/flint-2.4.3/fq_nmod_vec/swap.c new file mode 100644 index 0000000..1d43dc7 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_vec/swap.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_vec_templates/swap.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_vec/test/t-add.c b/external/flint-2.4.3/fq_nmod_vec/test/t-add.c new file mode 100644 index 0000000..a2f7149 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_vec/test/t-add.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_vec_templates/test/t-add.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_vec/test/t-is_zero.c b/external/flint-2.4.3/fq_nmod_vec/test/t-is_zero.c new file mode 100644 index 0000000..5e85266 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_vec/test/t-is_zero.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_vec_templates/test/t-is_zero.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_vec/test/t-neg.c b/external/flint-2.4.3/fq_nmod_vec/test/t-neg.c new file mode 100644 index 0000000..88c967e --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_vec/test/t-neg.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_vec_templates/test/t-neg.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_vec/test/t-sub.c b/external/flint-2.4.3/fq_nmod_vec/test/t-sub.c new file mode 100644 index 0000000..d29330e --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_vec/test/t-sub.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_vec_templates/test/t-sub.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_vec/test/t-swap.c b/external/flint-2.4.3/fq_nmod_vec/test/t-swap.c new file mode 100644 index 0000000..abeb236 --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_vec/test/t-swap.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_vec_templates/test/t-swap.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_vec/test/t-zero.c b/external/flint-2.4.3/fq_nmod_vec/test/t-zero.c new file mode 100644 index 0000000..0677e5b --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_vec/test/t-zero.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_vec_templates/test/t-zero.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_nmod_vec/zero.c b/external/flint-2.4.3/fq_nmod_vec/zero.c new file mode 100644 index 0000000..b32e9ab --- /dev/null +++ b/external/flint-2.4.3/fq_nmod_vec/zero.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_nmod_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq_nmod +#define CAP_T FQ_NMOD +#include "fq_vec_templates/zero.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly.h b/external/flint-2.4.3/fq_poly.h new file mode 100644 index 0000000..78af1e1 --- /dev/null +++ b/external/flint-2.4.3/fq_poly.h @@ -0,0 +1,53 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Andres Goens + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#ifndef FQ_POLY_H +#define FQ_POLY_H + +#include "fq.h" +#include "fq_mat.h" + +#define FQ_POLY_DIVREM_DIVCONQUER_CUTOFF 16 +#define FQ_COMPOSE_MOD_LENH_CUTOFF 6 +#define FQ_COMPOSE_MOD_PREINV_LENH_CUTOFF 6 +#define FQ_MUL_CLASSICAL_CUTOFF 6 +#define FQ_MULLOW_CLASSICAL_CUTOFF 6 +#define FQ_SQR_CLASSICAL_CUTOFF 6 + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates.h" +#undef CAP_T +#undef T + +#include "fq_poly_factor.h" + +#endif diff --git a/external/flint-2.4.3/fq_poly/Makefile b/external/flint-2.4.3/fq_poly/Makefile new file mode 100644 index 0000000..6969798 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/Makefile @@ -0,0 +1,54 @@ +SOURCES = $(wildcard *.c) + +OBJS = $(patsubst %.c, $(BUILD_DIR)/$(MOD_DIR)_%.o, $(SOURCES)) + +LOBJS = $(patsubst %.c, $(BUILD_DIR)/%.lo, $(SOURCES)) +MOD_LOBJ = $(BUILD_DIR)/../$(MOD_DIR).lo + +TEST_SOURCES = $(wildcard test/*.c) + +PROF_SOURCES = $(wildcard profile/*.c) + +TUNE_SOURCES = $(wildcard tune/*.c) + +TESTS = $(patsubst %.c, $(BUILD_DIR)/%, $(TEST_SOURCES)) + +TESTS_RUN = $(patsubst %, %_RUN, $(TESTS)) + +PROFS = $(patsubst %.c, %, $(PROF_SOURCES)) + +TUNE = $(patsubst %.c, %, $(TUNE_SOURCES)) + +all: shared static + +shared: $(MOD_LOBJ) + +static: $(OBJS) + +profile: $(PROF_SOURCES) + $(foreach prog, $(PROFS), $(CC) $(ABI_FLAG) -O2 -std=c99 $(INCS) $(prog).c ../profiler.o -o $(BUILD_DIR)/$(prog) $(LIBS) || exit $$?;) + +tune: $(TUNE_SOURCES) + $(foreach prog, $(TUNE), $(CC) $(ABI_FLAG) -O2 -std=c99 $(INCS) $(prog).c -o $(BUILD_DIR)/$(prog) $(LIBS) || exit $$?;) + +$(BUILD_DIR)/$(MOD_DIR)_%.o: %.c + $(CC) $(CFLAGS) -c $(INCS) $< -o $@ + +$(MOD_LOBJ): $(LOBJS) + $(CC) $(ABI_FLAG) -Wl,-r $^ -o $@ -nostdlib + +$(BUILD_DIR)/%.lo: %.c + $(CC) $(PICFLAG) $(CFLAGS) $(INCS) -c $< -o $@ + +clean: + rm -rf $(BUILD_DIR) $(MOD_LOBJ) + +check: $(TESTS) $(TESTS_RUN) + +$(BUILD_DIR)/test/%: test/%.c + $(CC) $(CFLAGS) $(INCS) $< ../test_helpers.o -o $@ $(LIBS) + +%_RUN: % + @$< + +.PHONY: profile tune clean check all shared static %_RUN diff --git a/external/flint-2.4.3/fq_poly/add.c b/external/flint-2.4.3/fq_poly/add.c new file mode 100644 index 0000000..2129ba9 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/add.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/add.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/clear.c b/external/flint-2.4.3/fq_poly/clear.c new file mode 100644 index 0000000..633a01c --- /dev/null +++ b/external/flint-2.4.3/fq_poly/clear.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Andres Goens + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/clear.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/compose.c b/external/flint-2.4.3/fq_poly/compose.c new file mode 100644 index 0000000..9a972a6 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/compose.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/compose.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/compose_divconquer.c b/external/flint-2.4.3/fq_poly/compose_divconquer.c new file mode 100644 index 0000000..bd800c7 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/compose_divconquer.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/compose_divconquer.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/compose_horner.c b/external/flint-2.4.3/fq_poly/compose_horner.c new file mode 100644 index 0000000..883ea8e --- /dev/null +++ b/external/flint-2.4.3/fq_poly/compose_horner.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/compose_horner.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/compose_mod.c b/external/flint-2.4.3/fq_poly/compose_mod.c new file mode 100644 index 0000000..0636eac --- /dev/null +++ b/external/flint-2.4.3/fq_poly/compose_mod.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/compose_mod.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/compose_mod_brent_kung.c b/external/flint-2.4.3/fq_poly/compose_mod_brent_kung.c new file mode 100644 index 0000000..f4a8edf --- /dev/null +++ b/external/flint-2.4.3/fq_poly/compose_mod_brent_kung.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" +#include "fq_mat.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/compose_mod_brent_kung.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/compose_mod_brent_kung_precomp_preinv.c b/external/flint-2.4.3/fq_poly/compose_mod_brent_kung_precomp_preinv.c new file mode 100644 index 0000000..564f596 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/compose_mod_brent_kung_precomp_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/compose_mod_brent_kung_precomp_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/compose_mod_brent_kung_preinv.c b/external/flint-2.4.3/fq_poly/compose_mod_brent_kung_preinv.c new file mode 100644 index 0000000..2dbb4af --- /dev/null +++ b/external/flint-2.4.3/fq_poly/compose_mod_brent_kung_preinv.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" +#include "fq_mat.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/compose_mod_brent_kung_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/compose_mod_horner.c b/external/flint-2.4.3/fq_poly/compose_mod_horner.c new file mode 100644 index 0000000..ce21582 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/compose_mod_horner.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/compose_mod_horner.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/compose_mod_horner_preinv.c b/external/flint-2.4.3/fq_poly/compose_mod_horner_preinv.c new file mode 100644 index 0000000..e1dcb9b --- /dev/null +++ b/external/flint-2.4.3/fq_poly/compose_mod_horner_preinv.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/compose_mod_horner_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/compose_mod_preinv.c b/external/flint-2.4.3/fq_poly/compose_mod_preinv.c new file mode 100644 index 0000000..f1c973d --- /dev/null +++ b/external/flint-2.4.3/fq_poly/compose_mod_preinv.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/compose_mod_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/deflate.c b/external/flint-2.4.3/fq_poly/deflate.c new file mode 100644 index 0000000..407c389 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/deflate.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + Copyright (C) 2013 Mike Hansen +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/deflate.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/deflation.c b/external/flint-2.4.3/fq_poly/deflation.c new file mode 100644 index 0000000..dfbb792 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/deflation.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/deflation.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/derivative.c b/external/flint-2.4.3/fq_poly/derivative.c new file mode 100644 index 0000000..e639c3c --- /dev/null +++ b/external/flint-2.4.3/fq_poly/derivative.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/derivative.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/div_basecase.c b/external/flint-2.4.3/fq_poly/div_basecase.c new file mode 100644 index 0000000..e445fa4 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/div_basecase.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2010 Sebastian Pancratz + Copyright (C) 2008, 2009 William Hart + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/div_basecase.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/div_newton_n_preinv.c b/external/flint-2.4.3/fq_poly/div_newton_n_preinv.c new file mode 100644 index 0000000..4b4c844 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/div_newton_n_preinv.c @@ -0,0 +1,41 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Sebastian Pancratz + Copyright (C) 2013 Martin Lee + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/div_newton_n_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/divides.c b/external/flint-2.4.3/fq_poly/divides.c new file mode 100644 index 0000000..61fbe90 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/divides.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/divides.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/divrem_basecase.c b/external/flint-2.4.3/fq_poly/divrem_basecase.c new file mode 100644 index 0000000..2c63570 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/divrem_basecase.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/divrem_basecase.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/divrem_divconquer.c b/external/flint-2.4.3/fq_poly/divrem_divconquer.c new file mode 100644 index 0000000..78bf12a --- /dev/null +++ b/external/flint-2.4.3/fq_poly/divrem_divconquer.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/divrem_divconquer.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/divrem_divconquer_recursive.c b/external/flint-2.4.3/fq_poly/divrem_divconquer_recursive.c new file mode 100644 index 0000000..8aa7c7a --- /dev/null +++ b/external/flint-2.4.3/fq_poly/divrem_divconquer_recursive.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/divrem_divconquer_recursive.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/divrem_newton_n_preinv.c b/external/flint-2.4.3/fq_poly/divrem_newton_n_preinv.c new file mode 100644 index 0000000..43d11d1 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/divrem_newton_n_preinv.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2013 Martin Lee + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/divrem_newton_n_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/doc/fq_poly.txt b/external/flint-2.4.3/fq_poly/doc/fq_poly.txt new file mode 100644 index 0000000..9454629 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/doc/fq_poly.txt @@ -0,0 +1,1560 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009, 2008 William Hart + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012,2013 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +******************************************************************************* + + Memory management + +******************************************************************************* + +void fq_poly_init(fq_poly_t poly, const fq_ctx_t ctx) + + Initialises \code{poly} for use, with context ctx, and setting its + length to zero. A corresponding call to \code{fq_poly_clear()} + must be made after finishing with the \code{fq_poly_t} to free the + memory used by the polynomial. + +void fq_poly_init2(fq_poly_t poly, slong alloc, const fq_ctx_t ctx) + + Initialises \code{poly} with space for at least \code{alloc} + coefficients and sets the length to zero. The allocated + coefficients are all set to zero. A corresponding call to + \code{fq_poly_clear()} must be made after finishing with the + \code{fq_poly_t} to free the memory used by the polynomial. + +void fq_poly_realloc(fq_poly_t poly, slong alloc, const fq_ctx_t ctx) + + Reallocates the given polynomial to have space for \code{alloc} + coefficients. If \code{alloc} is zero the polynomial is cleared + and then reinitialised. If the current length is greater than + \code{alloc} the polynomial is first truncated to length + \code{alloc}. + +void fq_poly_fit_length(fq_poly_t poly, slong len, const fq_ctx_t ctx) + + If \code{len} is greater than the number of coefficients currently + allocated, then the polynomial is reallocated to have space for at + least \code{len} coefficients. No data is lost when calling this + function. + + The function efficiently deals with the case where + \code{fit_length} is called many times in small increments by at + least doubling the number of allocated coefficients when length is + larger than the number of coefficients currently allocated. + +void _fq_poly_set_length(fq_poly_t poly, slong newlen, const fq_ctx_t ctx) + + Sets the coefficients of \code{poly} beyond \code{len} to zero and + sets the length of \code{poly} to \code{len}. + +void fq_poly_clear(fq_poly_t poly, const fq_ctx_t ctx) + + Clears the given polynomial, releasing any memory used. It must + be reinitialised in order to be used again. + +void _fq_poly_normalise(fq_poly_t poly, const fq_ctx_t ctx) + + Sets the length of \code{poly} so that the top coefficient is + non-zero. If all coefficients are zero, the length is set to + zero. This function is mainly used internally, as all functions + guarantee normalisation. + +void _fq_poly_normalise2(fq_struct *poly, slong *length, const fq_ctx_t ctx) + + Sets the length \code{length} of \code{(poly,length)} so that the + top coefficient is non-zero. If all coefficients are zero, the + length is set to zero. This function is mainly used internally, as + all functions guarantee normalisation. + +void fq_poly_truncate(fq_poly_t poly, slong newlen, const fq_ctx_t ctx) + + Truncates the polynomial to length at most~$n$. + +void _fq_poly_reverse(fq_struct* output, const fq_struct* input, slong len, + slong m, const fq_ctx_t ctx) + + Sets \code{output} to the reverse of \code{input}, which is of + length \code{len}, but thinking of it as a polynomial of + length~\code{m}, notionally zero-padded if necessary. The + length~\code{m} must be non-negative, but there are no other + restrictions. The polynomial \code{output} must have space for + \code{m} coefficients. + +void fq_poly_reverse(fq_poly_t output, const fq_poly_t input, slong m, + const fq_ctx_t ctx) + + Sets \code{output} to the reverse of \code{input}, thinking of it + as a polynomial of length~\code{m}, notionally zero-padded if + necessary). The length~\code{m} must be non-negative, but there + are no other restrictions. The output polynomial will be set to + length~\code{m} and then normalised. + +******************************************************************************* + + Polynomial parameters + +******************************************************************************* + +long fq_poly_degree(fq_poly_t poly, const fq_ctx_t ctx) + + Returns the degree of the polynomial \code{poly}. + +long fq_poly_length(fq_poly_t poly, const fq_ctx_t ctx) + + Returns the length of the polynomial \code{poly}. + +fq_struct * fq_poly_lead(const fq_poly_t poly, const fq_ctx_t ctx) + + Returns a pointer to the leading coefficient of \code{poly}, or + \code{NULL} if \code{poly} is the zero polynomial. + +******************************************************************************* + + Randomisation + +******************************************************************************* + +void fq_poly_randtest(fq_poly_t f, flint_rand_t state, + slong len, const fq_ctx_t ctx) + + Sets $f$ to a random polynomial of length at most \code{len} + with entries in the field described by \code{ctx}. + +void fq_poly_randtest_not_zero(fq_poly_t f, flint_rand_t state, + slong len, const fq_ctx_t ctx) + + Same as \code{fq_poly_randtest} but guarantees that the polynomial + is not zero. + +void fq_poly_randtest_monic(fq_poly_t f, flint_rand_t state, + slong len, const fq_ctx_t ctx) + + Sets $f$ to a random monic polynomial of length \code{len} with + entries in the field described by \code{ctx}. + +void fq_poly_randtest_irreducible(fq_poly_t f, flint_rand_t state, + slong len, const fq_ctx_t ctx) + + Sets $f$ to a random monic, irreducible polynomial of length + \code{len} with entries in the field described by \code{ctx}. + +******************************************************************************* + + Assignment and basic manipulation + +******************************************************************************* + +void _fq_poly_set(fq_struct *rop, const fq_struct *op, slong len, + const fq_ctx_t ctx) + + Sets \code{(rop, len}) to \code{(op, len)}. + +void fq_poly_set(fq_poly_t poly1, const fq_poly_t poly2, const fq_ctx_t ctx) + + Sets the polynomial \code{poly1} to the polynomial \code{poly2}. + +void fq_poly_set_fq(fq_poly_t poly, const fq_t c, const fq_ctx_t ctx) + + Sets the polynomial \code{poly} to \code{c}. + +void fq_poly_swap(fq_poly_t op1, fq_poly_t op2, const fq_ctx_t ctx) + + Swaps the two polynomials \code{op1} and \code{op2}. + +void _fq_poly_zero(fq_struct *rop, slong len, const fq_ctx_t ctx) + + Sets \code{(rop, len)} to the zero polynomial. + +void fq_poly_zero(fq_poly_t poly, const fq_ctx_t ctx) + + Sets \code{poly} to the zero polynomial. + +void void fq_poly_one(fq_poly_t poly, const fq_ctx_t ctx) + + Sets \code{poly} to the constant polynomial~$1$. + +void void fq_poly_gen(fq_poly_t poly, const fq_ctx_t ctx) + + Sets \code{poly} to the polynomial~$x$. + +void fq_poly_make_monic(fq_poly_t rop, const fq_poly_t op, const fq_ctx_t ctx) + + Sets \code{rop} to \code{op}, normed to have leading coefficient 1. + +void _fq_poly_make_monic(fq_struct *rop, const fq_struct *op, slong length, + const fq_ctx_t ctx) + + Sets \code{rop} to \code{(op,length)}, normed to have leading coefficient 1. + Assumes that \code{rop} has enough space for the polynomial, assumes that + \code{op} is not zero (and thus has an invertible leading coefficient). + +******************************************************************************* + + Getting and setting coefficients + +******************************************************************************* + +void fq_poly_get_coeff(fq_t x, const fq_poly_t poly, slong n, const fq_ctx_t ctx) + + Sets $x$ to the coefficient of $X^n$ in \code{poly}. + +void fq_poly_set_coeff(fq_poly_t poly, slong n, const fq_t x, const fq_ctx_t ctx) + + Sets the coefficient of $X^n$ in \code{poly} to $x$. + +void +fq_poly_set_coeff_fmpz(fq_poly_t poly, slong n, const fmpz_t x, + const fq_ctx_t ctx) + + Sets the coefficient of $X^n$ in the polynomial to $x$, + assuming $n \geq 0$. + +******************************************************************************* + + Comparison + +******************************************************************************* + +int fq_poly_equal(const fq_poly_t poly1, const fq_poly_t poly2, const fq_ctx_t ctx) + + Returns whether the two polynomials \code{poly1} and \code{poly2} + are equal. + +int fq_poly_is_zero(const fq_poly_t poly, const fq_ctx_t ctx) + + Returns whether the polynomial \code{poly} is the zero polynomial. + +int fq_poly_is_one(const fq_poly_t op) + + Returns whether the polynomial \code{poly} is equal + to the constant polynomial~$1$. + +int fq_poly_is_gen(const fq_poly_t op, const fq_ctx_t ctx) + + Returns whether the polynomial \code{poly} is equal + to the polynomial~$x$. + +int fq_poly_is_unit(const fq_poly_t op, const fq_ctx_t ctx) + + Returns whether the polynomial \code{poly} is a unit in the polynomial + ring $\mathbf{F}_q[X]$, i.e. if it has degree $0$ and is non-zero. + +int fq_poly_equal_fq(const fq_poly_t poly, const fq_t c, const fq_ctx_t ctx) + + Returns whether the polynomial \code{poly} is equal the (constant) + $\mathbf{F}_q$ element \code{c} + +******************************************************************************* + + Addition and subtraction + +******************************************************************************* + +void _fq_poly_add(fq_struct *res, + const fq_struct *poly1, slong len1, + const fq_struct *poly2, slong len2, + const fq_ctx_t ctx) + + Sets \code{res} to the sum of \code{(poly1,len1)} and \code{(poly2,len2)}. + +void fq_poly_add(fq_poly_t res, const fq_poly_t poly1, const fq_poly_t poly2, + const fq_ctx_t ctx) + + Sets \code{res} to the sum of \code{poly1} and \code{poly2}. + +void _fq_poly_sub(fq_struct *res, + const fq_struct *poly1, slong len1, + const fq_struct *poly2, slong len2, + const fq_ctx_t ctx) + + Sets \code{res} to the difference of \code{(poly1,len1)} and \code{(poly2,len2)}. + +void fq_poly_sub(fq_poly_t res, const fq_poly_t poly1, const fq_poly_t poly2, + const fq_ctx_t ctx) + + Sets \code{res} to the difference of \code{poly1} and \code{poly2}. + +void _fq_poly_neg(fq_struct *rop, const fq_struct *op, slong len, + const fq_ctx_t ctx) + + Sets \code{res} to the additive inverse of \code{(poly,len)}. + +void fq_poly_neg(fq_poly_t res, const fq_poly_t poly, const fq_ctx_t ctx) + + Sets \code{res} to the additive inverse of \code{poly}. + +******************************************************************************* + + Scalar multiplication and division + +******************************************************************************* + +void _fq_poly_scalar_mul_fq(fq_struct *rop, + const fq_struct *op, slong len, const fq_t x, const fq_ctx_t ctx) + + Sets \code{(rop,len)} to the product of \code{(op,len)} by the + scalar \code{x}, in the context defined by \code{ctx}. + +void fq_poly_scalar_mul_fq(fq_poly_t rop, + const fq_poly_t op, const fq_t x, const fq_ctx_t ctx) + + Sets \code{(rop,len)} to the product of \code{(op,len)} by the + scalar \code{x}, in the context defined by \code{ctx}. + +void _fq_poly_scalar_addmul_fq(fq_struct *rop, + const fq_struct *op, slong len, const fq_t x, const fq_ctx_t ctx) + + Adds to \code{(rop,len)} the product of \code{(op,len)} by the + scalar \code{x}, in the context defined by \code{ctx}. + In particular, assumes the same length for \code{op} and + \code{rop}. + +void fq_poly_scalar_addmul_fq(fq_poly_t rop, + const fq_poly_t op, const fq_t x, const fq_ctx_t ctx) + + Adds to \code{rop} the product of \code{op} by the + scalar \code{x}, in the context defined by \code{ctx}. + +void _fq_poly_scalar_submul_fq(fq_struct *rop, + const fq_struct *op, slong len, const fq_t x, const fq_ctx_t ctx) + + Substracts from \code{(rop,len)} the product of \code{(op,len)} by the + scalar \code{x}, in the context defined by \code{ctx}. + In particular, assumes the same length for \code{op} and + \code{rop}. + +void fq_poly_scalar_submul_fq(fq_poly_t rop, + const fq_poly_t op, const fq_t x, const fq_ctx_t ctx) + + Substracts from \code{rop} the product of \code{op} by the + scalar \code{x}, in the context defined by \code{ctx}. + +******************************************************************************* + + Multiplication + +******************************************************************************* + +void _fq_poly_mul_classical(fq_struct *rop, + const fq_struct *op1, slong len1, + const fq_struct *op2, slong len2, + const fq_ctx_t ctx) + + Sets \code{(rop, len1 + len2 - 1)} to the product of \code{(op1, len1)} + and \code{(op2, len2)}, assuming that \code{len1} is at least \code{len2} + and neither is zero. + + Permits zero padding. Does not support aliasing of \code{rop} + with either \code{op1} or \code{op2}. + +void fq_poly_mul_classical(fq_poly_t rop, + const fq_poly_t op1, const fq_poly_t op2, + const fq_ctx_t ctx) + + Sets \code{rop} to the product of \code{op1} and \code{op2} + using classical polynomial multiplication. + +void _fq_poly_mul_reorder(fq_struct *rop, + const fq_struct *op1, slong len1, + const fq_struct *op2, slong len2, + const fq_ctx_t ctx) + + Sets \code{(rop, len1 + len2 - 1)} to the product of \code{(op1, len1)} + and \code{(op2, len2)}, assuming that \code{len1} and \code{len2} are + non-zero. + + Permits zero padding. Supports aliasing. + +void fq_poly_mul_reorder(fq_poly_t rop, + const fq_poly_t op1, const fq_poly_t op2, const fq_ctx_t ctx) + + Sets \code{rop} to the product of \code{op1} and \code{op2}, + reordering the two indeterminates $X$ and $Y$ when viewing + the polynomials as elements of $\mathbf{F}_p[X,Y]$. + + Suppose $\mathbf{F}_q = \mathbf{F}_p[X]/ (f(X))$ and recall + that elements of $\mathbf{F}_q$ are internally represented + by elements of type \code{fmpz_poly}. For small degree extensions + but polynomials in $\mathbf{F}_q[Y]$ of large degree~$n$, we + change the representation to + \begin{equation*} + \begin{split} + g(Y) & = \sum_{i=0}^{n} a_i(X) Y^i \\ + & = \sum_{j=0}^{d} \sum_{i=0}^{n} \text{Coeff}(a_i(X), j) Y^i. + \end{split} + \end{equation*} + This allows us to use a poor algorithm (such as classical multiplication) + in the $X$-direction and leverage the existing fast integer + multiplication routines in the $Y$-direction where the polynomial + degree~$n$ is large. + +void _fq_poly_mul_KS(fq_struct *rop, const fq_struct *op1, slong len1, + const fq_struct *op2, slong len2, + const fq_ctx_t ctx) + + Sets \code{(rop, len1 + len2 - 1)} to the product of \code{(op1, len1)} + and \code{(op2, len2)}. + + Permits zero padding and places no assumptions on the + lengths \code{len1} and \code{len2}. Supports aliasing. + +void fq_poly_mul_KS(fq_poly_t rop, + const fq_poly_t op1, const fq_poly_t op2, + const fq_ctx_t ctx) + + Sets \code{rop} to the product of \code{op1} and \code{op2} + using Kronecker substitution, that is, by encoding each + coefficient in $\mathbf{F}_{q}$ as an integer and reducing + this problem to multiplying two polynomials over the integers. + +void _fq_poly_mul(fq_struct *rop, + const fq_struct *op1, slong len1, + const fq_struct *op2, slong len2, const fq_ctx_t ctx) + + Sets \code{(rop, len1 + len2 - 1)} to the product of \code{(op1, len1)} + and \code{(op2, len2)}, choosing an appropriate algorithm. + + Permits zero padding. Does not support aliasing. + +void fq_poly_mul(fq_poly_t rop, + const fq_poly_t op1, const fq_poly_t op2, const fq_ctx_t ctx) + + Sets \code{rop} to the product of \code{op1} and \code{op2}, + choosing an appropriate algorithm. + +void _fq_poly_mullow_classical(fq_struct *rop, + const fq_struct *op1, slong len1, + const fq_struct *op2, slong len2, slong n, + const fq_ctx_t ctx) + + Sets \code{(res, n)} to the first $n$ coefficients of \code{(poly1, len1)} + multiplied by \code{(poly2, len2)}. + + Assumes \code{0 < n <= len1 + len2 - 1}. Assumes neither \code{len1} nor + \code{len2} is zero. + +void fq_poly_mullow_classical(fq_poly_t rop, + const fq_poly_t op1, const fq_poly_t op2, slong n, const fq_ctx_t ctx) + + Sets \code{res} to the product of \code{poly1} and \code{poly2}, computed + using the classical or schoolbook method. + +void _fq_poly_mullow_KS(fq_struct *rop, + const fq_struct *op1, slong len1, + const fq_struct *op2, slong len2, slong n, + const fq_ctx_t ctx) + + Sets \code{(res, n)} to the lowest $n$ coefficients of the product of + \code{(poly1, len1)} and \code{(poly2, len2)}. + + Assumes that \code{len1} and \code{len2} are positive, but does allow + for the polynomials to be zero-padded. The polynomials may be zero, + too. Assumes $n$ is positive. Supports aliasing between \code{res}, + \code{poly1} and \code{poly2}. + +void fq_poly_mullow_KS(fq_poly_t rop, + const fq_poly_t op1, const fq_poly_t op2, slong n, + const fq_ctx_t ctx) + + Sets \code{res} to the product of \code{poly1} and \code{poly2}. + +void _fq_poly_mullow(fq_struct *rop, + const fq_struct *op1, slong len1, + const fq_struct *op2, slong len2, slong n, + const fq_ctx_t ctx) + + Sets \code{(res, n)} to the lowest $n$ coefficients of the product of + \code{(poly1, len1)} and \code{(poly2, len2)}. + + Assumes \code{0 < n <= len1 + len2 - 1}. Allows for zero-padding in + the inputs. Does not support aliasing between the inputs and the output. + +void fq_poly_mullow(fq_poly_t rop, + const fq_poly_t op1, const fq_poly_t op2, slong n, + const fq_ctx_t ctx) + + Sets \code{res} to the lowest $n$ coefficients of the product of + \code{poly1} and \code{poly2}. + +void _fq_poly_mulmod(fq_struct* res, const fq_struct* poly1, slong len1, + const fq_struct* poly2, slong len2, const fq_struct* f, + slong lenf, const fq_ctx_t ctx) + + Sets \code{res} to the remainder of the product of \code{poly1} + and \code{poly2} upon polynomial division by \code{f}. + + It is required that \code{len1 + len2 - lenf > 0}, which is + equivalent to requiring that the result will actually be + reduced. Otherwise, simply use \code{_fq_poly_mul} instead. + + Aliasing of \code{f} and \code{res} is not permitted. + +void fq_poly_mulmod(fq_poly_t res,const fq_poly_t poly1, const fq_poly_t poly2, + const fq_poly_t f, const fq_ctx_t ctx) + + Sets \code{res} to the remainder of the product of \code{poly1} + and \code{poly2} upon polynomial division by \code{f}. + +void _fq_poly_mulmod_preinv(fq_struct* res, const fq_struct* poly1, slong len1, + const fq_struct* poly2, slong len2, + const fq_struct* f, slong lenf, + const fq_struct* finv, slong lenfinv, + const fq_ctx_t ctx) + + Sets \code{res} to the remainder of the product of \code{poly1} + and \code{poly2} upon polynomial division by \code{f}. + + It is required that \code{finv} is the inverse of the reverse of + \code{f} mod \code{x^lenf}. It is required that + \code{len1 + len2 - lenf > 0}, which is equivalent to requiring that + the result will actually be reduced. Otherwise, simply use + \code{_fq_poly_mul} instead. + + Aliasing of \code{f} or \code{finv} and \code{res} is not + permitted. + +void fq_poly_mulmod_preinv(fq_poly_t res, const fq_poly_t poly1, + const fq_poly_t poly2, const fq_poly_t f, + const fq_poly_t finv, const fq_ctx_t ctx) + + Sets \code{res} to the remainder of the product of \code{poly1} + and \code{poly2} upon polynomial division by \code{f}. \code{finv} + is the inverse of the reverse of \code{f}. + +******************************************************************************* + + Squaring + +******************************************************************************* + +void _fq_poly_sqr_classical(fq_struct *rop, + const fq_struct *op, slong len, + const fq_ctx_t ctx) + + Sets \code{(rop, 2*len - 1)} to the square of \code{(op, len)}, + assuming that \code{(op,len)} is not zero and using classical + polynomial multiplication. + + Permits zero padding. Does not support aliasing of \code{rop} + with either \code{op1} or \code{op2}. + +void fq_poly_sqr_classical(fq_poly_t rop, + const fq_poly_t op, const fq_ctx_t ctx) + + Sets \code{rop} to the square of \code{op} using classical + polynomial multiplication. + + +void _fq_poly_sqr_reorder(fq_struct *rop, + const fq_struct *op, slong len, const fq_ctx_t ctx) + + Sets \code{(rop, 2*len- 1)} to the square of \code{(op, len)}, + assuming that \code{len} is not zero reordering the two indeterminates + $X$ and $Y$ when viewing the polynomials as elements of $\mathbb{F}_p[X,Y]$. + + Permits zero padding. Supports aliasing. + +void fq_poly_sqr_reorder(fq_poly_t rop, + const fq_poly_t op, const fq_ctx_t ctx) + + Sets \code{rop} to the square of \code{op}, + assuming that \code{len} is not zero reordering the two indeterminates + $X$ and $Y$ when viewing the polynomials as elements of $\mathbb{F}_p[X,Y]$. + See \code{fq_poly_mul_reorder}. + + +void _fq_poly_sqr_KS(fq_struct *rop, const fq_struct *op, slong len, + const fq_ctx_t ctx) + + Sets \code{(rop, 2*len - 1)} to the square of \code{(op, len)}. + + Permits zero padding and places no assumptions on the + lengths \code{len1} and \code{len2}. Supports aliasing. + +void fq_poly_sqr_KS(fq_poly_t rop, const fq_poly_t op, const fq_ctx_t ctx) + + Sets \code{rop} to the square \code{op} using Kronecker substitution, + that is, by encoding each coefficient in $\mathbf{F}_{q}$ as an integer + and reducing this problem to multiplying two polynomials over the integers. + +void _fq_poly_sqr(fq_struct *rop, const fq_struct *op, slong len, + const fq_ctx_t ctx) + + Sets \code{(rop, 2* len - 1)} to the square of \code{(op, len)}, + choosing an appropriate algorithm. + + Permits zero padding. Does not support aliasing. + +void fq_poly_sqr(fq_poly_t rop, const fq_poly_t op, const fq_ctx_t ctx) + + Sets \code{rop} to the square of \code{op}, + choosing an appropriate algorithm. + + +******************************************************************************* + + Powering + +******************************************************************************* + +void _fq_poly_pow(fq_struct *rop, const fq_struct *op, slong len, ulong e, + const fq_ctx_t ctx) + + Sets \code{res = poly^e}, assuming that \code{e, len > 0} and that + \code{res} has space for \code{e*(len - 1) + 1} coefficients. Does + not support aliasing. + +void fq_poly_pow(fq_poly_t rop, const fq_poly_t op, ulong e, + const fq_ctx_t ctx) + + Computes \code{res = poly^e}. If $e$ is zero, returns one, + so that in particular \code{0^0 = 1}. + +void _fq_poly_powmod_ui_binexp(fq_struct* res, const fq_struct* poly, + ulong e, const fq_struct* f, slong lenf, + const fq_ctx_t ctx) + + Sets \code{res} to \code{poly} raised to the power \code{e} modulo + \code{f}, using binary exponentiation. We require \code{e > 0}. + + We require \code{lenf > 1}. It is assumed that \code{poly} is + already reduced modulo \code{f} and zero-padded as necessary to + have length exactly \code{lenf - 1}. The output \code{res} must + have room for \code{lenf - 1} coefficients. + +void fq_poly_powmod_ui_binexp(fq_poly_t res, const fq_poly_t poly, ulong e, + const fq_poly_t f, const fq_ctx_t ctx) + + Sets \code{res} to \code{poly} raised to the power \code{e} modulo + \code{f}, using binary exponentiation. We require \code{e >= 0}. + +void +_fq_poly_powmod_ui_binexp_preinv(fq_struct* res, const fq_struct* poly, + ulong e, const fq_struct* f, slong lenf, + const fq_struct* finv, slong lenfinv, + const fq_ctx_t ctx) + + Sets \code{res} to \code{poly} raised to the power \code{e} modulo + \code{f}, using binary exponentiation. We require \code{e > 0}. + We require \code{finv} to be the inverse of the reverse of + \code{f}. + + We require \code{lenf > 1}. It is assumed that \code{poly} is + already reduced modulo \code{f} and zero-padded as necessary to + have length exactly \code{lenf - 1}. The output \code{res} must + have room for \code{lenf - 1} coefficients. + +void +fq_poly_powmod_ui_binexp_preinv(fq_poly_t res, const fq_poly_t poly, ulong e, + const fq_poly_t f, const fq_poly_t finv, + const fq_ctx_t ctx) + + Sets \code{res} to \code{poly} raised to the power \code{e} modulo + \code{f}, using binary exponentiation. We require \code{e >= 0}. + We require \code{finv} to be the inverse of the reverse of + \code{f}. + +void _fq_poly_powmod_fmpz_binexp(fq_struct* res, const fq_struct* poly, + fmpz_t e, const fq_struct* f, + slong lenf, const fq_ctx_t ctx) + + Sets \code{res} to \code{poly} raised to the power \code{e} modulo + \code{f}, using binary exponentiation. We require \code{e > 0}. + + We require \code{lenf > 1}. It is assumed that \code{poly} is + already reduced modulo \code{f} and zero-padded as necessary to + have length exactly \code{lenf - 1}. The output \code{res} must + have room for \code{lenf - 1} coefficients. + +void fq_poly_powmod_fmpz_binexp(fq_poly_t res, const fq_poly_t poly, fmpz_t e, + const fq_poly_t f, const fq_ctx_t ctx) + + Sets \code{res} to \code{poly} raised to the power \code{e} modulo + \code{f}, using binary exponentiation. We require \code{e >= 0}. + +void +_fq_poly_powmod_fmpz_binexp_preinv(fq_struct* res, const fq_struct* poly, + fmpz_t e, const fq_struct* f, slong lenf, + const fq_struct* finv, slong lenfinv, + const fq_ctx_t ctx) + + Sets \code{res} to \code{poly} raised to the power \code{e} modulo + \code{f}, using binary exponentiation. We require \code{e > 0}. + We require \code{finv} to be the inverse of the reverse of + \code{f}. + + We require \code{lenf > 1}. It is assumed that \code{poly} is + already reduced modulo \code{f} and zero-padded as necessary to + have length exactly \code{lenf - 1}. The output \code{res} must + have room for \code{lenf - 1} coefficients. + +void +fq_poly_powmod_fmpz_binexp_preinv(fq_poly_t res, const fq_poly_t poly, fmpz_t e, + const fq_poly_t f, const fq_poly_t finv, + const fq_ctx_t ctx) + + Sets \code{res} to \code{poly} raised to the power \code{e} modulo + \code{f}, using binary exponentiation. We require \code{e >= 0}. + We require \code{finv} to be the inverse of the reverse of + \code{f}. + +void +_fq_poly_powmod_fmpz_sliding_preinv(fq_struct* res, const fq_struct* poly, + fmpz_t e, ulong k, const fq_struct* f, slong lenf, + const fq_struct* finv, slong lenfinv, + const fq_ctx_t ctx) + + Sets \code{res} to \code{poly} raised to the power \code{e} modulo + \code{f}, using sliding-window exponentiation with window size + \code{k}. We require \code{e > 0}. We require \code{finv} to be + the inverse of the reverse of \code{f}. If \code{k} is set to + zero, then an "optimum" size will be selected automatically base + on \code{e}. + + We require \code{lenf > 1}. It is assumed that \code{poly} is + already reduced modulo \code{f} and zero-padded as necessary to + have length exactly \code{lenf - 1}. The output \code{res} must + have room for \code{lenf - 1} coefficients. + +void +fq_poly_powmod_fmpz_sliding_preinv(fq_poly_t res, const fq_poly_t poly, fmpz_t e, + ulong k, const fq_poly_t f, const fq_poly_t finv, + const fq_ctx_t ctx) + + Sets \code{res} to \code{poly} raised to the power \code{e} modulo + \code{f}, using sliding-window exponentiation with window size + \code{k}. We require \code{e >= 0}. We require \code{finv} to be + the inverse of the reverse of \code{f}. If \code{k} is set to + zero, then an "optimum" size will be selected automatically base + on \code{e}. + +void +_fq_poly_powmod_x_fmpz_preinv(fq_struct * res, const fmpz_t e, + const fq_struct * f, slong lenf, + const fq_struct * finv, slong lenfinv, + const fq_ctx_t ctx) + + Sets \code{res} to \code{x} raised to the power \code{e} modulo \code{f}, + using sliding window exponentiation. We require \code{e > 0}. + We require \code{finv} to be the inverse of the reverse of \code{f}. + + We require \code{lenf > 2}. The output \code{res} must have room for + \code{lenf - 1} coefficients. + +void +fq_poly_powmod_x_fmpz_preinv(fq_poly_t res, const fmpz_t e, + const fq_poly_t f, const fq_poly_t finv, + const fq_ctx_t ctx) + + Sets \code{res} to \code{x} raised to the power \code{e} + modulo \code{f}, using sliding window exponentiation. We require + \code{e >= 0}. We require \code{finv} to be the inverse of the reverse of + \code{f}. + +******************************************************************************* + + Shifting + +******************************************************************************* + +void _fq_poly_shift_left(fq_struct *rop, const fq_struct *op, slong len, slong n, + const fq_ctx_t ctx) + + Sets \code{(res, len + n)} to \code{(poly, len)} shifted left by + $n$ coefficients. + + Inserts zero coefficients at the lower end. Assumes that + \code{len} and $n$ are positive, and that \code{res} fits + \code{len + n} elements. Supports aliasing between \code{res} and + \code{poly}. + +void fq_poly_shift_left(fq_poly_t rop, const fq_poly_t op, slong n, + const fq_ctx_t ctx) + + Sets \code{res} to \code{poly} shifted left by $n$ coeffs. Zero + coefficients are inserted. + +void _fq_poly_shift_right(fq_struct *rop, const fq_struct *op, slong len, + slong n, const fq_ctx_t ctx) + + Sets \code{(res, len - n)} to \code{(poly, len)} shifted right by + $n$ coefficients. + + Assumes that \code{len} and $n$ are positive, that \code{len > n}, + and that \code{res} fits \code{len - n} elements. Supports + aliasing between \code{res} and \code{poly}, although in this case + the top coefficients of \code{poly} are not set to zero. + +void fq_poly_shift_right(fq_poly_t rop, const fq_poly_t op, slong n, + const fq_ctx_t ctx) + + Sets \code{res} to \code{poly} shifted right by $n$ coefficients. + If $n$ is equal to or greater than the current length of + \code{poly}, \code{res} is set to the zero polynomial. + +******************************************************************************* + + Norms + +******************************************************************************* + +long _fq_poly_hamming_weight(const fq_poly *op, slong len, const fq_ctx_t ctx) + + Returns the number of non-zero entries in \code{(op, len)}. + +long fq_poly_hamming_weight(const fq_poly_t op, const fq_ctx_t ctx) + + Returns the number of non-zero entries in the polynomial \code{op}. + +******************************************************************************* + + Euclidean division + +******************************************************************************* + +void _fq_poly_divrem_basecase(fq_struct *Q, fq_struct *R, + const fq_struct *A, slong lenA, const fq_struct *B, slong lenB, + const fq_t invB, const fq_ctx_t ctx) + + Computes \code{(Q, lenA - lenB + 1)}, \code{(R, lenA)} such that + $A = B Q + R$ with $0 \leq \len(R) < \len(B)$. + + Assumes that the leading coefficient of $B$ is invertible + and that \code{invB} is its inverse. + + Assumes that $\len(A), \len(B) > 0$. Allows zero-padding in + \code{(A, lenA)}. $R$ and $A$ may be aliased, but apart from + this no aliasing of input and output operands is allowed. + +void fq_poly_divrem_basecase(fq_poly_t Q, fq_poly_t R, + const fq_poly_t A, const fq_poly_t B, + const fq_ctx_t ctx) + + Computes $Q$, $R$ such that $A = B Q + R$ with + $0 \leq \len(R) < \len(B)$. + + Assumes that the leading coefficient of $B$ is invertible. This can + be taken for granted the context is for a finite field, that is, when + $p$ is prime and $f(X)$ is irreducible. + +void _fq_poly_divrem(fq_struct *Q, fq_struct *R, + const fq_struct *A, slong lenA, const fq_struct *B, slong lenB, + const fq_t invB, const fq_ctx_t ctx) + + Computes \code{(Q, lenA - lenB + 1)}, \code{(R, lenA)} such that + $A = B Q + R$ with $0 \leq \len(R) < \len(B)$. + + Assumes that the leading coefficient of $B$ is invertible + and that \code{invB} is its inverse. + + Assumes that $\len(A), \len(B) > 0$. Allows zero-padding in + \code{(A, lenA)}. $R$ and $A$ may be aliased, but apart from + this no aliasing of input and output operands is allowed. + +void fq_poly_divrem(fq_poly_t Q, fq_poly_t R, + const fq_poly_t A, const fq_poly_t B, + const fq_ctx_t ctx) + + Computes $Q$, $R$ such that $A = B Q + R$ with + $0 \leq \len(R) < \len(B)$. + + Assumes that the leading coefficient of $B$ is invertible. This can + be taken for granted the context is for a finite field, that is, when + $p$ is prime and $f(X)$ is irreducible. + +void _fq_poly_rem(fq_struct *R, const fq_struct *A, slong lenA, + const fq_struct *B, slong lenB, const fq_t invB, + const fq_ctx_t ctx) + + Sets \code{R} to the remainder of the division of \code{(A,lenA)} by + \code{(B,lenB)}. Assumes that the leading coefficient of \code{(B,lenB)} + is invertible and that \code{invB} is its inverse. + +void fq_poly_rem(fq_poly_t R, + const fq_poly_t A, const fq_poly_t B, + const fq_ctx_t ctx) + + Sets \code{R} to the remainder of the division of \code{A} by + \code{B} in the context described by \code{ctx}. + +void _fq_poly_div_basecase(fq_struct *Q, fq_struct *R, + const fq_struct *A, slong lenA, + const fq_struct *B, slong lenB, + const fq_t invB, const fq_ctx_t ctx) + + Notationally, computes $Q$, $R$ such that $A = B Q + R$ with $0 + \leq \len(R) < \len(B)$ but only sets \code{(Q, lenA - lenB + 1)}. + + Requires temporary space \code{(R, lenA)}. If \code{R} is + \code{NULL}, then the temporary space will be allocated. Allows + aliasing only between $A$ and $R$. Allows zero-padding in $A$ but + not in $B$. Assumes that the leading coefficient of $B$ is a + unit. + +void fq_poly_div_basecase(fq_poly_t Q, const fq_poly_t A, const fq_poly_t B, + const fq_ctx_t ctx) + + Notionally finds polynomials $Q$ and $R$ such that $A = B Q + R$ with + $\len(R) < \len(B)$, but returns only \code{Q}. If $\len(B) = 0$ an + exception is raised. + +void _fq_poly_divrem_divconquer_recursive(fq_struct * Q, fq_struct * BQ, + fq_struct * W, const fq_struct * A, + const fq_struct * B, slong lenB, + const fq_t invB, const fq_ctx_t ctx) + + Computes \code{(Q, lenB)}, \code{(BQ, 2 lenB - 1)} such that + $BQ = B \times Q$ and $A = B Q + R$ where $0 \leq \len(R) < \len(B)$. + + Assumes that the leading coefficient of $B$ is invertible and that + \code{invB} is the inverse. + + Assumes $\len(B) > 0$. Allows zero-padding in \code{(A, lenA)}. Requires + a temporary array \code{(W, 2 lenB - 1)}. No aliasing of input and output + operands is allowed. + + This function does not read the bottom $\len(B) - 1$ coefficients from + $A$, which means that they might not even need to exist in allocated + memory. + +void _fq_poly_divrem_divconquer(fq_struct * Q, fq_struct * R, + const fq_struct * A, slong lenA, + const fq_struct * B, slong lenB, + const fq_t invB, const fq_ctx_t ctx) + + Computes \code{(Q, lenA - lenB + 1)}, \code{(R, lenA)} such that + $A = B Q + R$ and $0 \leq \len(R) < \len(B)$. + + Assumes that the leading coefficient of $B$ is invertible and that + \code{invB} is the inverse. + + Assumes $\len(A) \geq \len(B) > 0$. Allows zero-padding in + \code{(A, lenA)}. No aliasing of input and output operands is + allowed. + +void fq_poly_divrem_divconquer(fq_poly_t Q, fq_poly_t R, + const fq_poly_t A, const fq_poly_t B, + const fq_ctx_t ctx) + + Computes $Q$, $R$ such that $A = B Q + R$ and $0 \leq \len(R) < \len(B)$. + + Assumes that $B$ is non-zero and that the leading coefficient of + $B$ is invertible. + +void _fq_poly_div_newton_n_preinv(fq_struct* Q, const fq_struct* A, slong lenA, + const fq_struct* B, slong lenB, + const fq_struct* Binv, slong lenBinv, + const fq_struct ctx_t) + + Notionally computes polynomials $Q$ and $R$ such that $A = BQ + R$ with + $\len(R)$ less than \code{lenB}, where \code{A} is of length \code{lenA} + and \code{B} is of length \code{lenB}, but return only $Q$. + + We require that $Q$ have space for \code{lenA - lenB + 1} coefficients + and assume that the leading coefficient of $B$ is a unit. Furthermore, we + assume that $Binv$ is the inverse of the reverse of $B$ mod $x^{\len(B)}$. + + The algorithm used is to reverse the polynomials and divide the + resulting power series, then reverse the result. + +void fq_poly_div_newton_n_preinv(fq_poly_t Q, const fq_poly_t A, + const fq_poly_t B, const fq_poly_t Binv, + const fq_ctx_t ctx) + + Notionally computes $Q$ and $R$ such that $A = BQ + R$ with + $\len(R) < \len(B)$, but returns only $Q$. + + We assume that the leading coefficient of $B$ is a unit and that $Binv$ is + the inverse of the reverse of $B$ mod $x^{\len(B)}$. + + It is required that the length of $A$ is less than or equal to + 2*the length of $B$ - 2. + + The algorithm used is to reverse the polynomials and divide the + resulting power series, then reverse the result. + +void _fq_poly_divrem_newton_n_preinv(fq_struct* Q, fq_struct* R, + const fq_struct* A, slong lenA, + const fq_struct* B, slong lenB, + const fq_struct* Binv, slong lenBinv, + const fq_ctx_t ctx) + + Computes $Q$ and $R$ such that $A = BQ + R$ with $\len(R)$ less + than \code{lenB}, where $A$ is of length \code{lenA} and $B$ is of + length \code{lenB}. We require that $Q$ have space for + \code{lenA - lenB + 1} coefficients. Furthermore, we assume that $Binv$ is + the inverse of the reverse of $B$ mod $x^{\len(B)}$. The algorithm + used is to call \code{div_newton_n_preinv()} and then multiply out + and compute the remainder. + +void fq_poly_divrem_newton_preinv(fq_poly_t Q, fq_poly_t R, + const fq_poly_t A, const fq_poly_t B, + const fq_poly_t Binv, const fq_ctx_t ctx) + + Computes $Q$ and $R$ such that $A = BQ + R$ with $\len(R) < + \len(B)$. We assume $Binv$ is the inverse of the reverse of $B$ + mod $x^{\len(B)}$. + + It is required that the length of $A$ is less than or equal to + 2*the length of $B$ - 2. + + The algorithm used is to call \code{div_newton_n()} and then + multiply out and compute the remainder. + +void +_fq_poly_inv_series_newton(fq_struct* Qinv, const fq_struct* Q, slong n, + const fq_ctx_t ctx) + + Given \code{Q} of length \code{n} whose constant coefficient is + invertible modulo the given modulus, find a polynomial \code{Qinv} + of length \code{n} such that \code{Q * Qinv} is \code{1} modulo + $x^n$. Requires \code{n > 0}. This function can be viewed as + inverting a power series via Newton iteration. + +void +fq_poly_inv_series_newton(fq_poly_t Qinv, const fq_poly_t Q, slong n, + const fq_ctx_t ctx) + + Given \code{Q} find \code{Qinv} such that \code{Q * Qinv} is + \code{1} modulo $x^n$. The constant coefficient of \code{Q} must + be invertible modulo the modulus of \code{Q}. An exception is + raised if this is not the case or if \code{n = 0}. This function + can be viewed as inverting a power series via Newton iteration. + +******************************************************************************* + + Greatest common divisor + +******************************************************************************* + +void fq_poly_gcd(fq_poly_t rop, const fq_poly_t op1, const fq_poly_t op2, + const fq_ctx_t ctx) + + Sets \code{rop} to the greatest common divisor of \code{op1} and + \code{op2}, using the either the Euclidean or HGCD algorithm. The + GCD of zero polynomials is defined to be zero, whereas the GCD of + the zero polynomial and some other polynomial $P$ is defined to be + $P$. Except in the case where the GCD is zero, the GCD $G$ is made + monic. + +long _fq_poly_gcd(fq_struct* G,const fq_struct* A, slong lenA, + const fq_struct* B, slong lenB, const fq_ctx_t ctx) + + Computes the GCD of $A$ of length \code{lenA} and $B$ of length + \code{lenB}, where \code{lenA >= lenB > 0} and sets $G$ to it. The + length of the GCD $G$ is returned by the function. No attempt is + made to make the GCD monic. It is required that $G$ have space for + \code{lenB} coefficients. + +void fq_poly_gcd_euclidean(fq_poly_t rop, const fq_poly_t op1, + const fq_poly_t op2, const fq_ctx_t ctx) + + Sets \code{rop} to the greatest common divisor of \code{op1} and + \code{op2}, using the Euclidean algorithm. The GCD of zero + polynomials is defined to be zero, whereas the GCD of the zero + polynomial and some other polynomial $P$ is defined to be + $P$. Except in the case where the GCD is zero, the GCD $G$ is made + monic. + +long _fq_poly_gcd_euclidean(fq_struct* G, const fq_struct* A, slong lenA, + const fq_struct* B, slong lenB, + const fq_ctx_t ctx) + + Computes the GCD of $A$ of length \code{lenA} and $B$ of length + \code{lenB}, where \code{lenA >= lenB > 0} and sets $G$ to it. The + length of the GCD $G$ is returned by the function. No attempt is + made to make the GCD monic. It is required that $G$ have space for + \code{lenB} coefficients. + +******************************************************************************* + + Divisibility testing + +******************************************************************************* + +int _fq_poly_divides(fq_struct *Q, + const fq_struct *A, slong lenA, + const fq_struct *B, slong lenB, const fq_t invB, + const fq_ctx_t ctx) + + Returns $1$ if \code{(B, lenB)} divides \code{(A, lenA)} exactly and + sets $Q$ to the quotient, otherwise returns $0$. + + It is assumed that $\len(A) \geq \len(B) > 0$ and that $Q$ has space + for $\len(A) - \len(B) + 1$ coefficients. + + Aliasing of $Q$ with either of the inputs is not permitted. + + This function is currently unoptimised and provided for convenience + only. + +int fq_poly_divides(fq_poly_t Q, const fq_poly_t A, const fq_poly_t B, + const fq_ctx_t ctx) + + + Returns $1$ if $B$ divides $A$ exactly and sets $Q$ to the quotient, + otherwise returns $0$. + + This function is currently unoptimised and provided for convenience + only. + +******************************************************************************* + + Derivative + +******************************************************************************* + +void _fq_poly_derivative(fq_struct *rop, const fq_struct *op, slong len, + const fq_ctx_t ctx) + + Sets \code{(rpoly, len - 1)} to the derivative of \code{(poly, len)}. + Also handles the cases where \code{len} is $0$ or $1$ correctly. + Supports aliasing of \code{rpoly} and \code{poly}. + +void fq_poly_derivative(fq_poly_t rop, const fq_poly_t op, const fq_ctx_t ctx) + + Sets \code{res} to the derivative of \code{poly}. + +******************************************************************************* + + Evaluation + +******************************************************************************* + +void _fq_poly_evaluate_fq(fq_t rop, const fq_struct *op, slong len, + const fq_t a, const fq_ctx_t ctx) + + Sets \code{rop} to \code{(op, len)} evaluated at $a$. + + Supports zero padding. There are no restrictions on \code{len}, that + is, \code{len} is allowed to be zero, too. + +void fq_poly_evaluate_fq(fq_t rop, const fq_poly_t f, const fq_t a, + const fq_ctx_t ctx) + + Sets \code{rop} to the value of $f(a)$. + + As the coefficient ring $\mathbf{F}_q$ is finite, Horner's method + is sufficient. + +******************************************************************************* + + Composition + +******************************************************************************* + +void _fq_poly_compose_divconquer(fq_struct *rop, + const fq_struct *op1, slong len1, + const fq_struct *op2, slong len2, + const fq_ctx_t ctx) + + Computes the composition of \code{(op1, len1)} and \code{(op2, len2)} + using a divide and conquer approach and places the result into \code{rop}, + assuming \code{rop} can hold the output of length + \code{(len1 - 1) * (len2 - 1) + 1}. + + Assumes \code{len1, len2 > 0}. Does not support aliasing between + \code{rop} and any of \code{(op1, len1)} and \code{(op2, len2)}. + +void fq_poly_compose_divconquer(fq_poly_t rop, + const fq_poly_t op1, const fq_poly_t op2, + const fq_ctx_t ctx) + + Sets \code{rop} to the composition of \code{op1} and \code{op2}. + To be precise about the order of composition, denoting \code{rop}, + \code{op1}, and \code{op2} by $f$, $g$, and $h$, respectively, + sets $f(t) = g(h(t))$. + +void _fq_poly_compose_horner(fq_struct *rop, const fq_struct *op1, slong len1, + const fq_struct *op2, slong len2, + const fq_ctx_t ctx) + + Sets \code{rop} to the composition of \code{(op1, len1)} and + \code{(op2, len2)}. + + Assumes that \code{rop} has space for \code{(len1-1)*(len2-1) + 1} + coefficients. Assumes that \code{op1} and \code{op2} are non-zero + polynomials. Does not support aliasing between any of the inputs and + the output. + +void fq_poly_compose_horner(fq_poly_t rop, + const fq_poly_t op1, const fq_poly_t op2, + const fq_ctx_t ctx) + + Sets \code{rop} to the composition of \code{op1} and \code{op2}. + To be more precise, denoting \code{rop}, \code{op1}, and \code{op2} + by $f$, $g$, and $h$, sets $f(t) = g(h(t))$. + + This implementation uses Horner's method. + +void _fq_poly_compose(fq_struct *rop, const fq_struct *op1, slong len1, + const fq_struct *op2, slong len2, + const fq_ctx_t ctx) + + Sets \code{rop} to the composition of \code{(op1, len1)} and + \code{(op2, len2)}. + + Assumes that \code{rop} has space for \code{(len1-1)*(len2-1) + 1} + coefficients. Assumes that \code{op1} and \code{op2} are non-zero + polynomials. Does not support aliasing between any of the inputs and + the output. + +void fq_poly_compose(fq_poly_t rop, const fq_poly_t op1, const fq_poly_t op2, + const fq_ctx_t ctx) + + Sets \code{rop} to the composition of \code{op1} and \code{op2}. + To be precise about the order of composition, denoting \code{rop}, + \code{op1}, and \code{op2} by $f$, $g$, and $h$, respectively, + sets $f(t) = g(h(t))$. + +void _fq_poly_compose_mod_horner(fq_struct * res, + const fq_struct * f, slong lenf, + const fq_struct * g, + const fq_struct * h, slong lenh, + const fq_ctx_t ctx) + + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require that + $h$ is nonzero and that the length of $g$ is one less than the + length of $h$ (possibly with zero padding). The output is not allowed + to be aliased with any of the inputs. + + The algorithm used is Horner's rule. + +void fq_poly_compose_mod_horner(fq_poly_t res, const fq_poly_t f, + const fq_poly_t g, const fq_poly_t h, + const fq_ctx_t ctx) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require that + $h$ is nonzero. The algorithm used is Horner's rule. + +void _fq_poly_compose_mod_horner_preinv(fq_struct * res, + const fq_struct * f, slong lenf, + const fq_struct * g, + const fq_struct * h, slong lenh, + const fq_struct * hinv, slong lenhiv, + const fq_ctx_t ctx) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require + that $h$ is nonzero and that the length of $g$ is one less than + the length of $h$ (possibly with zero padding). We also require + that the length of $f$ is less than the length of + $h$. Furthermore, we require \code{hinv} to be the inverse of the + reverse of \code{h}. The output is not allowed to be aliased with + any of the inputs. + + The algorithm used is Horner's rule. + +void fq_poly_compose_mod_horner_preinv(fq_poly_t res, const fq_poly_t f, + const fq_poly_t g, const fq_poly_t h, + const fq_poly_t hinv, + const fq_ctx_t ctx) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require + that $h$ is nonzero and that $f$ has smaller degree than + $h$. Furthermore, we require \code{hinv} to be the inverse of the + reverse of \code{h}. The algorithm used is Horner's rule. + + +void _fq_poly_compose_mod_brent_kung(fq_struct * res, + const fq_struct * f, slong lenf, + const fq_struct * g, + const fq_struct * h, slong lenh, + const fq_ctx_t ctx) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require + that $h$ is nonzero and that the length of $g$ is one less than + the length of $h$ (possibly with zero padding). We also require + that the length of $f$ is less than the length of $h$. The output + is not allowed to be aliased with any of the inputs. + + The algorithm used is the Brent-Kung matrix algorithm. + +void fq_poly_compose_mod_brent_kung(fq_poly_t res, const fq_poly_t f, + const fq_poly_t g, const fq_poly_t h, + const fq_ctx_t ctx) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require + that $h$ is nonzero and that $f$ has smaller degree than $h$. The + algorithm used is the Brent-Kung matrix algorithm. + +void _fq_poly_compose_mod_brent_kung_preinv(fq_struct * res, + const fq_struct * f, slong lenf, + const fq_struct * g, + const fq_struct * h, slong lenh, + const fq_struct * hinv, slong lenhiv, + const fq_ctx_t ctx) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require + that $h$ is nonzero and that the length of $g$ is one less than + the length of $h$ (possibly with zero padding). We also require + that the length of $f$ is less than the length of + $h$. Furthermore, we require \code{hinv} to be the inverse of the + reverse of \code{h}. The output is not allowed to be aliased with + any of the inputs. + + The algorithm used is the Brent-Kung matrix algorithm. + +void fq_poly_compose_mod_brent_kung_preinv(fq_poly_t res, const fq_poly_t f, + const fq_poly_t g, const fq_poly_t h, + const fq_poly_t hinv, + const fq_ctx_t ctx) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require + that $h$ is nonzero and that $f$ has smaller degree than + $h$. Furthermore, we require \code{hinv} to be the inverse of the + reverse of \code{h}. The algorithm used is the Brent-Kung matrix + algorithm. + +void _fq_poly_compose_mod(fq_struct * res, const fq_struct * f, slong lenf, + const fq_struct * g, const fq_struct * h, slong lenh, + const fq_ctx_t ctx) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require + that $h$ is nonzero and that the length of $g$ is one less than + the length of $h$ (possibly with zero padding). The output is not + allowed to be aliased with any of the inputs. + +void fq_poly_compose_mod(fq_poly_t res, const fq_poly_t f, const fq_poly_t g, + const fq_poly_t h, const fq_ctx_t ctx) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require + that $h$ is nonzero. + +void _fq_poly_compose_mod_preinv(fq_struct * res, + const fq_struct * f, slong lenf, + const fq_struct * g, + const fq_struct * h, slong lenh, + const fq_struct * hinv, slong lenhiv, + const fq_ctx_t ctx) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require + that $h$ is nonzero and that the length of $g$ is one less than + the length of $h$ (possibly with zero padding). We also require + that the length of $f$ is less than the length of + $h$. Furthermore, we require \code{hinv} to be the inverse of the + reverse of \code{h}. The output is not allowed to be aliased with + any of the inputs. + +void fq_poly_compose_mod_preinv(fq_poly_t res, const fq_poly_t f, + const fq_poly_t g, const fq_poly_t h, + const fq_poly_t hinv, + const fq_ctx_t ctx) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require + that $h$ is nonzero and that $f$ has smaller degree than + $h$. Furthermore, we require \code{hinv} to be the inverse of the + reverse of \code{h}. + +void +_fq_poly_reduce_matrix_mod_poly (fq_mat_t A, const fq_mat_t B, + const fq_poly_t f, const fq_ctx_t ctx) + + Sets the ith row of \code{A} to the reduction of the ith row of $B$ modulo + $f$ for $i=1,\ldots,\sqrt{\deg(f)}$. We require $B$ to be at least + a $\sqrt{\deg(f)}\times \deg(f)$ matrix and $f$ to be nonzero. + +void +_fq_poly_precompute_matrix (fq_mat_t A, const fq_struct* f, const fq_struct* g, + slong leng, const fq_struct* ginv, slong lenginv, + const fq_ctx_t ctx) + + Sets the ith row of \code{A} to $f^i$ modulo $g$ for + $i=1,\ldots,\sqrt{\deg(g)}$. We require $A$ to be a + $\sqrt{\deg(g)}\times \deg(g)$ matrix. We require \code{ginv} to + be the inverse of the reverse of \code{g} and $g$ to be nonzero. + +void +fq_poly_precompute_matrix (fq_mat_t A, const fq_poly_t f, + const fq_poly_t g, const fq_poly_t ginv, + const fq_ctx_t ctx) + + Sets the ith row of \code{A} to $f^i$ modulo $g$ for + $i=1,\ldots,\sqrt{\deg(g)}$. We require $A$ to be a + $\sqrt{\deg(g)}\times \deg(g)$ matrix. We require \code{ginv} to + be the inverse of the reverse of \code{g}. + + +void +_fq_poly_compose_mod_brent_kung_precomp_preinv(fq_struct* res, const fq_struct* f, + slong lenf, const fq_mat_t A, const fq_struct* h, + slong h, const fq_struct* hinv, slong lenhinv, + const fq_ctx_t ctx) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require + that $h$ is nonzero. We require that the ith row of $A$ contains + $g^i$ for $i=1,\ldots,\sqrt{\deg(h)}$, i.e. $A$ is a + $\sqrt{\deg(h)}\times \deg(h)$ matrix. We also require that the + length of $f$ is less than the length of $h$. Furthermore, we + require \code{hinv} to be the inverse of the reverse of \code{h}. + The output is not allowed to be aliased with any of the inputs. + + The algorithm used is the Brent-Kung matrix algorithm. + +void +fq_poly_compose_mod_brent_kung_precomp_preinv(fq_poly_t res, + const fq_poly_t f, const fq_mat_t A, + const fq_poly_t h, const fq_poly_t hinv, + const fq_ctx_t ctx) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require + that the ith row of $A$ contains $g^i$ for + $i=1,\ldots,\sqrt{\deg(h)}$, i.e. $A$ is a $\sqrt{\deg(h)}\times + \deg(h)$ matrix. We require that $h$ is nonzero and that $f$ has + smaller degree than $h$. Furthermore, we require \code{hinv} to be + the inverse of the reverse of \code{h}. This version of Brent-Kung + modular composition is particularly useful if one has to perform + several modular composition of the form $f(g)$ modulo $h$ for + fixed $g$ and $h$. + + +******************************************************************************* + + Output + +******************************************************************************* + +int _fq_poly_fprint_pretty(FILE *file, const fq_struct *poly, slong len, + const char *x, const fq_ctx_t ctx) + + Prints the pretty representation of \code{(poly, len)} to the stream + \code{file}, using the string \code{x} to represent the indeterminate. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + +int fq_poly_fprint_pretty(FILE * file, const fq_poly_t poly, const char *x, + const fq_ctx_t ctx) + + Prints the pretty representation of \code{poly} to the stream + \code{file}, using the string \code{x} to represent the indeterminate. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + + +int _fq_poly_print_pretty(const fq_struct *poly, slong len, + const char *x, const fq_ctx_t ctx) + + Prints the pretty representation of \code{(poly, len)} to \code{stdout}, + using the string \code{x} to represent the indeterminate. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + + +int fq_poly_print_pretty(const fq_poly_t poly, const char *x, + const fq_ctx_t ctx) + + Prints the pretty representation of \code{poly} to \code{stdout}, + using the string \code{x} to represent the indeterminate. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + +int _fq_poly_fprint(FILE *file, const fq_struct *poly, slong len, + const fq_ctx_t ctx) + + Prints the pretty representation of \code{(poly, len)} to the stream + \code{file}. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + +int fq_poly_fprint(FILE * file, const fq_poly_t poly, const fq_ctx_t ctx) + + Prints the pretty representation of \code{poly} to the stream + \code{file}. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + + +int _fq_poly_print(const fq_struct *poly, slong len, const fq_ctx_t ctx) + + Prints the pretty representation of \code{(poly, len)} to \code{stdout}. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + + +int fq_poly_print(const fq_poly_t poly, const fq_ctx_t ctx) + + Prints the representation of \code{poly} to \code{stdout}. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + +char * _fq_poly_get_str(const fq_struct * poly, slong len, const fq_ctx_t ctx) + + Returns the plain FLINT string representation of the polynomial + \code{(poly, len)}. + +char * fq_poly_get_str(const fq_poly_t poly, const fq_ctx_t ctx) + + Returns the plain FLINT string representation of the polynomial + \code{poly}. + +char * _fq_poly_get_str_pretty(const fq_struct * poly, slong len, + const char * x, const fq_ctx_t ctx) + + Returns a pretty representation of the polynomial + \code{(poly, len)} using the null-terminated string~\code{x} as the + variable name. + +char * fq_poly_get_str_pretty(const fq_poly_t poly, const char * x, + const fq_ctx_t ctx) + + Returns a pretty representation of the polynomial~\code{poly} using the + null-terminated string \code{x} as the variable name + +******************************************************************************* + + Inflation and deflation + +******************************************************************************* + +void fq_poly_inflate(fq_poly_t result, const fq_poly_t input, + ulong inflation, const fq_ctx_t ctx) + + Sets \code{result} to the inflated polynomial $p(x^n)$ where + $p$ is given by \code{input} and $n$ is given by \code{inflation}. + +void fq_poly_deflate(fq_poly_t result, const fq_poly_t input, + ulong deflation, const fq_ctx_t ctx) + + Sets \code{result} to the deflated polynomial $p(x^{1/n})$ where + $p$ is given by \code{input} and $n$ is given by \code{deflation}. + Requires $n > 0$. + +ulong fq_poly_deflation(const fq_poly_t input, const fq_ctx_t ctx) + + Returns the largest integer by which \code{input} can be deflated. + As special cases, returns 0 if \code{input} is the zero polynomial + and 1 of \code{input} is a constant polynomial. diff --git a/external/flint-2.4.3/fq_poly/equal.c b/external/flint-2.4.3/fq_poly/equal.c new file mode 100644 index 0000000..d90fd85 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/equal.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/equal.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/evaluate_fq.c b/external/flint-2.4.3/fq_poly/evaluate_fq.c new file mode 100644 index 0000000..f05f48e --- /dev/null +++ b/external/flint-2.4.3/fq_poly/evaluate_fq.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/evaluate_fq.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/fit_length.c b/external/flint-2.4.3/fq_poly/fit_length.c new file mode 100644 index 0000000..32a98e2 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/fit_length.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/fit_length.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/fprint.c b/external/flint-2.4.3/fq_poly/fprint.c new file mode 100644 index 0000000..cafeb42 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/fprint.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/fprint.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/fprint_pretty.c b/external/flint-2.4.3/fq_poly/fprint_pretty.c new file mode 100644 index 0000000..e99b36e --- /dev/null +++ b/external/flint-2.4.3/fq_poly/fprint_pretty.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/fprint_pretty.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/gcd_euclidean.c b/external/flint-2.4.3/fq_poly/gcd_euclidean.c new file mode 100644 index 0000000..91f727d --- /dev/null +++ b/external/flint-2.4.3/fq_poly/gcd_euclidean.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/gcd_euclidean.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/gen.c b/external/flint-2.4.3/fq_poly/gen.c new file mode 100644 index 0000000..35c20f6 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/gen.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/gen.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/get_coeff.c b/external/flint-2.4.3/fq_poly/get_coeff.c new file mode 100644 index 0000000..839852d --- /dev/null +++ b/external/flint-2.4.3/fq_poly/get_coeff.c @@ -0,0 +1,41 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/get_coeff.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/get_str.c b/external/flint-2.4.3/fq_poly/get_str.c new file mode 100644 index 0000000..cf70e5f --- /dev/null +++ b/external/flint-2.4.3/fq_poly/get_str.c @@ -0,0 +1,37 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/get_str.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/get_str_pretty.c b/external/flint-2.4.3/fq_poly/get_str_pretty.c new file mode 100644 index 0000000..1822943 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/get_str_pretty.c @@ -0,0 +1,37 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/get_str_pretty.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/hamming_weight.c b/external/flint-2.4.3/fq_poly/hamming_weight.c new file mode 100644 index 0000000..71b1108 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/hamming_weight.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/hamming_weight.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/inflate.c b/external/flint-2.4.3/fq_poly/inflate.c new file mode 100644 index 0000000..eed3d56 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/inflate.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/inflate.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/init.c b/external/flint-2.4.3/fq_poly/init.c new file mode 100644 index 0000000..23ac59a --- /dev/null +++ b/external/flint-2.4.3/fq_poly/init.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Andres Goens + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/init.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/inv_series_newton.c b/external/flint-2.4.3/fq_poly/inv_series_newton.c new file mode 100644 index 0000000..2220af1 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/inv_series_newton.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/inv_series_newton.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/make_monic.c b/external/flint-2.4.3/fq_poly/make_monic.c new file mode 100644 index 0000000..b9f7147 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/make_monic.c @@ -0,0 +1,41 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007, David Howden. + Copyright (C) 2010 William Hart + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/make_monic.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/mul.c b/external/flint-2.4.3/fq_poly/mul.c new file mode 100644 index 0000000..f80fd7e --- /dev/null +++ b/external/flint-2.4.3/fq_poly/mul.c @@ -0,0 +1,41 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define USE_MUL_REORDER 1 +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/mul.c" +#undef CAP_T +#undef T +#undef USE_MUL_REORDER diff --git a/external/flint-2.4.3/fq_poly/mul_KS.c b/external/flint-2.4.3/fq_poly/mul_KS.c new file mode 100644 index 0000000..bae2d77 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/mul_KS.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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, 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/mul_KS.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/mul_classical.c b/external/flint-2.4.3/fq_poly/mul_classical.c new file mode 100644 index 0000000..affa652 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/mul_classical.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/mul_classical.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/mul_reorder.c b/external/flint-2.4.3/fq_poly/mul_reorder.c new file mode 100644 index 0000000..900d916 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/mul_reorder.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/mul_reorder.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/mullow.c b/external/flint-2.4.3/fq_poly/mullow.c new file mode 100644 index 0000000..6bab96a --- /dev/null +++ b/external/flint-2.4.3/fq_poly/mullow.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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, 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/mullow.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/mullow_KS.c b/external/flint-2.4.3/fq_poly/mullow_KS.c new file mode 100644 index 0000000..7c3a023 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/mullow_KS.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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, 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/mullow_KS.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/mullow_classical.c b/external/flint-2.4.3/fq_poly/mullow_classical.c new file mode 100644 index 0000000..aa8ac5d --- /dev/null +++ b/external/flint-2.4.3/fq_poly/mullow_classical.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/mullow_classical.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/mulmod.c b/external/flint-2.4.3/fq_poly/mulmod.c new file mode 100644 index 0000000..a611a07 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/mulmod.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/mulmod.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/mulmod_preinv.c b/external/flint-2.4.3/fq_poly/mulmod_preinv.c new file mode 100644 index 0000000..5805487 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/mulmod_preinv.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2013 Martin Lee + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/mulmod_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/neg.c b/external/flint-2.4.3/fq_poly/neg.c new file mode 100644 index 0000000..118328c --- /dev/null +++ b/external/flint-2.4.3/fq_poly/neg.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/neg.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/normalise.c b/external/flint-2.4.3/fq_poly/normalise.c new file mode 100644 index 0000000..b1b0f16 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/normalise.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/normalise.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/one.c b/external/flint-2.4.3/fq_poly/one.c new file mode 100644 index 0000000..ac5522d --- /dev/null +++ b/external/flint-2.4.3/fq_poly/one.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/one.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/pow.c b/external/flint-2.4.3/fq_poly/pow.c new file mode 100644 index 0000000..45c05e8 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/pow.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/pow.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/powmod_fmpz_binexp.c b/external/flint-2.4.3/fq_poly/powmod_fmpz_binexp.c new file mode 100644 index 0000000..824e04b --- /dev/null +++ b/external/flint-2.4.3/fq_poly/powmod_fmpz_binexp.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/powmod_fmpz_binexp.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/powmod_fmpz_binexp_preinv.c b/external/flint-2.4.3/fq_poly/powmod_fmpz_binexp_preinv.c new file mode 100644 index 0000000..fc3d6bd --- /dev/null +++ b/external/flint-2.4.3/fq_poly/powmod_fmpz_binexp_preinv.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/powmod_fmpz_binexp_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/powmod_fmpz_sliding_preinv.c b/external/flint-2.4.3/fq_poly/powmod_fmpz_sliding_preinv.c new file mode 100644 index 0000000..ca44b66 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/powmod_fmpz_sliding_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/powmod_fmpz_sliding_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/powmod_ui_binexp.c b/external/flint-2.4.3/fq_poly/powmod_ui_binexp.c new file mode 100644 index 0000000..6428156 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/powmod_ui_binexp.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/powmod_ui_binexp.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/powmod_ui_binexp_preinv.c b/external/flint-2.4.3/fq_poly/powmod_ui_binexp_preinv.c new file mode 100644 index 0000000..3fa4334 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/powmod_ui_binexp_preinv.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/powmod_ui_binexp_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/powmod_x_fmpz_preinv.c b/external/flint-2.4.3/fq_poly/powmod_x_fmpz_preinv.c new file mode 100644 index 0000000..58ad1a9 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/powmod_x_fmpz_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/powmod_x_fmpz_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/profile/p-compose_mod.c b/external/flint-2.4.3/fq_poly/profile/p-compose_mod.c new file mode 100644 index 0000000..b0a416b --- /dev/null +++ b/external/flint-2.4.3/fq_poly/profile/p-compose_mod.c @@ -0,0 +1,129 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "flint.h" +#include "fq_poly.h" +#include "profiler.h" + +#define nalgs 2 +#define cpumin 2 +#define ncases 1 + +int +main(int argc, char** argv) +{ + fmpz_t p; + int c, n, reps = 0; + slong d, lenf, leng, lenh; + fq_ctx_t ctx; + fq_poly_t f, g, h, res; + + double s[nalgs]; + + FLINT_TEST_INIT(state); + + fmpz_init(p); + fmpz_set_str(p, argv[1], 10); + + d = atol(argv[2]); + lenf = atol(argv[3]); + leng = atol(argv[4]); + lenh = atol(argv[5]); + + fq_ctx_init(ctx, p, d, "a"); + + fq_poly_init(f, ctx); + fq_poly_init(g, ctx); + fq_poly_init(h, ctx); + + fq_poly_init(res, ctx); + + for (c = 0; c < nalgs; c++) + s[c] = 0.0; + + for (n = 0; n < ncases; n++) + { + double t[nalgs]; + int l, loops = 1; + + /* + Construct random elements of fq + */ + { + fq_poly_randtest_monic(f, state, lenf, ctx); + fq_poly_randtest_monic(g, state, leng, ctx); + fq_poly_randtest_monic(h, state, lenh, ctx); + } + + loop: + + t[0] = 0.0; + init_clock(0); + prof_start(); + for (l = 0; l < loops; l++) + fq_poly_compose_mod_horner(res, f, g, h, ctx); + prof_stop(); + t[0] += get_clock(0); + + t[1] = 0.0; + init_clock(0); + prof_start(); + for (l = 0; l < loops; l++) + fq_poly_compose_mod_brent_kung(res, f, g, h, ctx); + prof_stop(); + t[1] += get_clock(0); + + for (c = 0; c < nalgs; c++) + if (t[c] * FLINT_CLOCK_SCALE_FACTOR <= cpumin) + { + loops *= 10; + goto loop; + } + + for (c = 0; c < nalgs; c++) + s[c] += t[c]; + reps += loops; + } + + for (c = 0; c < nalgs; c++) + { + printf("%20f", s[c] / (double) reps); + fflush(stdout); + } + printf("\n"); + + + fq_poly_clear(f, ctx); + fq_poly_clear(g, ctx); + fq_poly_clear(h, ctx); + fq_poly_clear(res, ctx); + + fq_ctx_clear(ctx); + fmpz_clear(p); + + FLINT_TEST_CLEANUP(state); + + return 0; +} diff --git a/external/flint-2.4.3/fq_poly/profile/p-compose_mod_preinv.c b/external/flint-2.4.3/fq_poly/profile/p-compose_mod_preinv.c new file mode 100644 index 0000000..f96fefd --- /dev/null +++ b/external/flint-2.4.3/fq_poly/profile/p-compose_mod_preinv.c @@ -0,0 +1,132 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "flint.h" +#include "fq_poly.h" +#include "profiler.h" + +#define nalgs 2 +#define cpumin 2 +#define ncases 1 + +int +main(int argc, char** argv) +{ + fmpz_t p; + int c, n, reps = 0; + slong d, lenf, leng, lenh; + fq_ctx_t ctx; + fq_poly_t f, g, h, hinv, res; + + double s[nalgs]; + + FLINT_TEST_INIT(state); + + fmpz_init(p); + fmpz_set_str(p, argv[1], 10); + + d = atol(argv[2]); + lenf = atol(argv[3]); + leng = atol(argv[4]); + lenh = atol(argv[5]); + + fq_ctx_init(ctx, p, d, "a"); + + fq_poly_init(f, ctx); + fq_poly_init(g, ctx); + fq_poly_init(h, ctx); + fq_poly_init(hinv, ctx); + + fq_poly_init(res, ctx); + + for (c = 0; c < nalgs; c++) + s[c] = 0.0; + + for (n = 0; n < ncases; n++) + { + double t[nalgs]; + int l, loops = 1; + + /* + Construct random elements of fq + */ + { + fq_poly_randtest_monic(f, state, lenf, ctx); + fq_poly_randtest_monic(g, state, leng, ctx); + fq_poly_randtest_monic(h, state, lenh, ctx); + fq_poly_reverse(hinv, h, h->length, ctx); + fq_poly_inv_series_newton(hinv, hinv, h->length, ctx); + } + + loop: + + t[0] = 0.0; + init_clock(0); + prof_start(); + for (l = 0; l < loops; l++) + fq_poly_compose_mod_horner_preinv(res, f, g, h, hinv, ctx); + prof_stop(); + t[0] += get_clock(0); + + t[1] = 0.0; + init_clock(0); + prof_start(); + for (l = 0; l < loops; l++) + fq_poly_compose_mod_brent_kung_preinv(res, f, g, h, hinv, ctx); + prof_stop(); + t[1] += get_clock(0); + + for (c = 0; c < nalgs; c++) + if (t[c] * FLINT_CLOCK_SCALE_FACTOR <= cpumin) + { + loops *= 10; + goto loop; + } + + for (c = 0; c < nalgs; c++) + s[c] += t[c]; + reps += loops; + } + + for (c = 0; c < nalgs; c++) + { + printf("%20f", s[c] / (double) reps); + fflush(stdout); + } + printf("\n"); + + + fq_poly_clear(f, ctx); + fq_poly_clear(g, ctx); + fq_poly_clear(h, ctx); + fq_poly_clear(res, ctx); + + fq_ctx_clear(ctx); + fmpz_clear(p); + + FLINT_TEST_CLEANUP(state); + + return 0; +} diff --git a/external/flint-2.4.3/fq_poly/profile/p-factor_xnpxp1.c b/external/flint-2.4.3/fq_poly/profile/p-factor_xnpxp1.c new file mode 100644 index 0000000..5893097 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/profile/p-factor_xnpxp1.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/profile/p-factor_xnpxp1.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/profile/p-is_irreducible.c b/external/flint-2.4.3/fq_poly/profile/p-is_irreducible.c new file mode 100644 index 0000000..833971f --- /dev/null +++ b/external/flint-2.4.3/fq_poly/profile/p-is_irreducible.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/profile/p-is_irreducible.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/profile/p-iterated_frobenius.c b/external/flint-2.4.3/fq_poly/profile/p-iterated_frobenius.c new file mode 100644 index 0000000..a3a1b2b --- /dev/null +++ b/external/flint-2.4.3/fq_poly/profile/p-iterated_frobenius.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/profile/p-iterated_frobenius.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/profile/p-iterated_frobenius_table.c b/external/flint-2.4.3/fq_poly/profile/p-iterated_frobenius_table.c new file mode 100644 index 0000000..47775ed --- /dev/null +++ b/external/flint-2.4.3/fq_poly/profile/p-iterated_frobenius_table.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/profile/p-iterated_frobenius_table.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/profile/p-mulmod.c b/external/flint-2.4.3/fq_poly/profile/p-mulmod.c new file mode 100644 index 0000000..92d7f12 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/profile/p-mulmod.c @@ -0,0 +1,167 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright 2010 William Hart + Copyright 2013 Martin Lee + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include +#include +#include "profiler.h" +#include "flint.h" +#include "ulong_extras.h" +#include "fq_poly.h" + +typedef struct +{ + slong n; + slong s; + slong alg; +} info_t; + +void +sample(void *arg, ulong count) +{ + info_t *info = (info_t *) arg; + slong n = info->n, i, j, s = info->s, alg = info->alg; + slong scale; + + fq_poly_t a, b, c, d, dinv; + fq_ctx_t ctx; + + FLINT_TEST_INIT(state); + + fq_ctx_randtest(ctx, state); + + fq_poly_init2(a, n, ctx); + fq_poly_init2(b, n, ctx); + fq_poly_init2(c, 2 * n - 1, ctx); + fq_poly_init2(d, s, ctx); + fq_poly_init2(dinv, s, ctx); + + fq_poly_randtest_monic(a, state, n, ctx); + fq_poly_randtest_monic(b, state, n, ctx); + fq_poly_randtest_monic(d, state, s, ctx); + + fq_poly_reverse(dinv, d, s, ctx); + fq_poly_inv_series_newton(dinv, dinv, s, ctx); + + scale = 1; + if (n < 100000) + scale = 10; + if (n < 10000) + scale = 100; + if (n < 100) + scale = 1000; + + for (i = 0; i < count; i++) + { + if (alg == 1) + { + prof_start(); + for (j = 0; j < scale; j++) + { + fq_poly_mulmod_preinv(c, a, b, d, dinv, ctx); + } + prof_stop(); + } + else + { + prof_start(); + for (j = 0; j < scale; j++) + { + fq_poly_mulmod(c, a, b, d, ctx); + } + prof_stop(); + } + } + + fq_poly_clear(a, ctx); + fq_poly_clear(b, ctx); + fq_poly_clear(c, ctx); + fq_poly_clear(d, ctx); + fq_poly_clear(dinv, ctx); + fq_ctx_clear(ctx); + FLINT_TEST_CLEANUP(state); +} + +int +main(void) +{ + double min, max; + info_t info; + slong i, k, scale; + + + for (k = 2; k <= 6; k++) + { + info.n = 1 << k; + + for (i = 0; i < 3; i++) + { + if (i == 0) + info.s = info.n / 2; + else if (i == 1) + info.s = info.n + ((1 << (k + 1)) - (1 << k)) / 2 * i; + else if (i == 2) + info.s = info.n * 2 - 1; + scale = 1; + if (info.n < 100000) + scale = 10; + if (info.n < 10000) + scale = 10; + if (info.n < 100) + scale = 10; + + info.alg = 1; + prof_repeat(&min, &max, sample, (void *) &info); + + flint_printf + ("length %wd, modulus degree %wd, min %.3g ms, max %.3g ms, norm %.3g\n", + info.n, info.s, + ((min / (double) FLINT_CLOCK_SCALE_FACTOR) / scale) / + 2400000.0, + ((max / (double) FLINT_CLOCK_SCALE_FACTOR) / scale) / + 2400000.0, + (((min / (double) FLINT_CLOCK_SCALE_FACTOR) / scale) / + 2400000.0) * 500000.0 / info.n / FLINT_BIT_COUNT(info.n)); + fflush(stdout); + + info.alg = 2; + prof_repeat(&min, &max, sample, (void *) &info); + + flint_printf + ("length %wd, modulus degree %wd, min %.3g ms, max %.3g ms, norm %.3g\n", + info.n, info.s, + ((min / (double) FLINT_CLOCK_SCALE_FACTOR) / scale) / + 2400000.0, + ((max / (double) FLINT_CLOCK_SCALE_FACTOR) / scale) / + 2400000.0, + (((min / (double) FLINT_CLOCK_SCALE_FACTOR) / scale) / + 2400000.0) * 500000.0 / info.n / FLINT_BIT_COUNT(info.n)); + fflush(stdout); + } + } + + return 0; +} diff --git a/external/flint-2.4.3/fq_poly/randtest.c b/external/flint-2.4.3/fq_poly/randtest.c new file mode 100644 index 0000000..b41f059 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/randtest.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/randtest.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/randtest_irreducible.c b/external/flint-2.4.3/fq_poly/randtest_irreducible.c new file mode 100644 index 0000000..75639e1 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/randtest_irreducible.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/randtest_irreducible.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/randtest_monic.c b/external/flint-2.4.3/fq_poly/randtest_monic.c new file mode 100644 index 0000000..14d944c --- /dev/null +++ b/external/flint-2.4.3/fq_poly/randtest_monic.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/randtest_monic.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/realloc.c b/external/flint-2.4.3/fq_poly/realloc.c new file mode 100644 index 0000000..da58f9e --- /dev/null +++ b/external/flint-2.4.3/fq_poly/realloc.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/realloc.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/remove.c b/external/flint-2.4.3/fq_poly/remove.c new file mode 100644 index 0000000..7620cb5 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/remove.c @@ -0,0 +1,42 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/remove.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/reverse.c b/external/flint-2.4.3/fq_poly/reverse.c new file mode 100644 index 0000000..d935d2c --- /dev/null +++ b/external/flint-2.4.3/fq_poly/reverse.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/reverse.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/scalar_addmul_fq.c b/external/flint-2.4.3/fq_poly/scalar_addmul_fq.c new file mode 100644 index 0000000..48e0139 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/scalar_addmul_fq.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/scalar_addmul_fq.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/scalar_mul_fq.c b/external/flint-2.4.3/fq_poly/scalar_mul_fq.c new file mode 100644 index 0000000..940ed9e --- /dev/null +++ b/external/flint-2.4.3/fq_poly/scalar_mul_fq.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/scalar_mul_fq.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/scalar_submul_fq.c b/external/flint-2.4.3/fq_poly/scalar_submul_fq.c new file mode 100644 index 0000000..8df92e4 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/scalar_submul_fq.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/scalar_submul_fq.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/set.c b/external/flint-2.4.3/fq_poly/set.c new file mode 100644 index 0000000..885c8ab --- /dev/null +++ b/external/flint-2.4.3/fq_poly/set.c @@ -0,0 +1,41 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2012 Andres Goens + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/set.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/set_coeff.c b/external/flint-2.4.3/fq_poly/set_coeff.c new file mode 100644 index 0000000..0d68cc7 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/set_coeff.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/set_coeff.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/set_fq.c b/external/flint-2.4.3/fq_poly/set_fq.c new file mode 100644 index 0000000..98512eb --- /dev/null +++ b/external/flint-2.4.3/fq_poly/set_fq.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/set_fq.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/shift_left.c b/external/flint-2.4.3/fq_poly/shift_left.c new file mode 100644 index 0000000..2583c5c --- /dev/null +++ b/external/flint-2.4.3/fq_poly/shift_left.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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, 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/shift_left.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/shift_right.c b/external/flint-2.4.3/fq_poly/shift_right.c new file mode 100644 index 0000000..1af8c12 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/shift_right.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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, 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/shift_right.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/sqr.c b/external/flint-2.4.3/fq_poly/sqr.c new file mode 100644 index 0000000..18ffced --- /dev/null +++ b/external/flint-2.4.3/fq_poly/sqr.c @@ -0,0 +1,41 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define USE_SQR_REORDER 1 +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/sqr.c" +#undef CAP_T +#undef T +#undef USE_SQR_REORDER diff --git a/external/flint-2.4.3/fq_poly/sqr_KS.c b/external/flint-2.4.3/fq_poly/sqr_KS.c new file mode 100644 index 0000000..332ab89 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/sqr_KS.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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, 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/sqr_KS.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/sqr_classical.c b/external/flint-2.4.3/fq_poly/sqr_classical.c new file mode 100644 index 0000000..bace439 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/sqr_classical.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/sqr_classical.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/sqr_reorder.c b/external/flint-2.4.3/fq_poly/sqr_reorder.c new file mode 100644 index 0000000..08cc3a6 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/sqr_reorder.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/sqr_reorder.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/sub.c b/external/flint-2.4.3/fq_poly/sub.c new file mode 100644 index 0000000..410a1e3 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/sub.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/sub.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/swap.c b/external/flint-2.4.3/fq_poly/swap.c new file mode 100644 index 0000000..95d4125 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/swap.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/swap.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-add.c b/external/flint-2.4.3/fq_poly/test/t-add.c new file mode 100644 index 0000000..f6cee14 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-add.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-add.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-compose.c b/external/flint-2.4.3/fq_poly/test/t-compose.c new file mode 100644 index 0000000..3e9b316 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-compose.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-compose.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-compose_divconquer.c b/external/flint-2.4.3/fq_poly/test/t-compose_divconquer.c new file mode 100644 index 0000000..b8a4fa8 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-compose_divconquer.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-compose_divconquer.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-compose_horner.c b/external/flint-2.4.3/fq_poly/test/t-compose_horner.c new file mode 100644 index 0000000..1adae05 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-compose_horner.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-compose_horner.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-compose_mod.c b/external/flint-2.4.3/fq_poly/test/t-compose_mod.c new file mode 100644 index 0000000..71dd69b --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-compose_mod.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-compose_mod.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-compose_mod_brent_kung.c b/external/flint-2.4.3/fq_poly/test/t-compose_mod_brent_kung.c new file mode 100644 index 0000000..01a2c0d --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-compose_mod_brent_kung.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-compose_mod_brent_kung.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-compose_mod_brent_kung_preinv.c b/external/flint-2.4.3/fq_poly/test/t-compose_mod_brent_kung_preinv.c new file mode 100644 index 0000000..5721bef --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-compose_mod_brent_kung_preinv.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-compose_mod_brent_kung_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-compose_mod_horner.c b/external/flint-2.4.3/fq_poly/test/t-compose_mod_horner.c new file mode 100644 index 0000000..a1e9918 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-compose_mod_horner.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-compose_mod_horner.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-compose_mod_horner_preinv.c b/external/flint-2.4.3/fq_poly/test/t-compose_mod_horner_preinv.c new file mode 100644 index 0000000..556b211 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-compose_mod_horner_preinv.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-compose_mod_horner_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-compose_mod_preinv.c b/external/flint-2.4.3/fq_poly/test/t-compose_mod_preinv.c new file mode 100644 index 0000000..4a2e6c4 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-compose_mod_preinv.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-compose_mod_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-deflate.c b/external/flint-2.4.3/fq_poly/test/t-deflate.c new file mode 100644 index 0000000..3562bba --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-deflate.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-deflate.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-derivative.c b/external/flint-2.4.3/fq_poly/test/t-derivative.c new file mode 100644 index 0000000..8ae1d2d --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-derivative.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-derivative.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-div_basecase.c b/external/flint-2.4.3/fq_poly/test/t-div_basecase.c new file mode 100644 index 0000000..a23da4e --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-div_basecase.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2009 William Hart + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-div_basecase.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-div_newton_n_preinv.c b/external/flint-2.4.3/fq_poly/test/t-div_newton_n_preinv.c new file mode 100644 index 0000000..7687ed8 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-div_newton_n_preinv.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2013 Martin Lee + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-div_newton_n_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-divides.c b/external/flint-2.4.3/fq_poly/test/t-divides.c new file mode 100644 index 0000000..c0ed857 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-divides.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-divides.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-divrem_basecase.c b/external/flint-2.4.3/fq_poly/test/t-divrem_basecase.c new file mode 100644 index 0000000..0bb17f5 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-divrem_basecase.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-divrem_basecase.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-divrem_divconquer.c b/external/flint-2.4.3/fq_poly/test/t-divrem_divconquer.c new file mode 100644 index 0000000..25322d9 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-divrem_divconquer.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-divrem_divconquer.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-divrem_newton_n_preinv.c b/external/flint-2.4.3/fq_poly/test/t-divrem_newton_n_preinv.c new file mode 100644 index 0000000..7ceeb6a --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-divrem_newton_n_preinv.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2013 Martin Lee + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-divrem_newton_n_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-evaluate_fq.c b/external/flint-2.4.3/fq_poly/test/t-evaluate_fq.c new file mode 100644 index 0000000..051f474 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-evaluate_fq.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-evaluate_fq.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-gcd_euclidean.c b/external/flint-2.4.3/fq_poly/test/t-gcd_euclidean.c new file mode 100644 index 0000000..2ff78ab --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-gcd_euclidean.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-gcd_euclidean.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-get_str.c b/external/flint-2.4.3/fq_poly/test/t-get_str.c new file mode 100644 index 0000000..a967d4e --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-get_str.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-get_str.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-get_str_pretty.c b/external/flint-2.4.3/fq_poly/test/t-get_str_pretty.c new file mode 100644 index 0000000..86be92d --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-get_str_pretty.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-get_str_pretty.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-hamming_weight.c b/external/flint-2.4.3/fq_poly/test/t-hamming_weight.c new file mode 100644 index 0000000..7182428 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-hamming_weight.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-hamming_weight.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-inflate.c b/external/flint-2.4.3/fq_poly/test/t-inflate.c new file mode 100644 index 0000000..f7f0030 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-inflate.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-inflate.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-inv_series_newton.c b/external/flint-2.4.3/fq_poly/test/t-inv_series_newton.c new file mode 100644 index 0000000..9f6b670 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-inv_series_newton.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-inv_series_newton.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-make_monic.c b/external/flint-2.4.3/fq_poly/test/t-make_monic.c new file mode 100644 index 0000000..a596c95 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-make_monic.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-make_monic.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-mul.c b/external/flint-2.4.3/fq_poly/test/t-mul.c new file mode 100644 index 0000000..62361bd --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-mul.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-mul.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-mul_KS.c b/external/flint-2.4.3/fq_poly/test/t-mul_KS.c new file mode 100644 index 0000000..646999a --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-mul_KS.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-mul_KS.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-mul_classical.c b/external/flint-2.4.3/fq_poly/test/t-mul_classical.c new file mode 100644 index 0000000..f18f788 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-mul_classical.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-mul_classical.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-mul_reorder.c b/external/flint-2.4.3/fq_poly/test/t-mul_reorder.c new file mode 100644 index 0000000..1d9f5df --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-mul_reorder.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-mul_reorder.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-mullow.c b/external/flint-2.4.3/fq_poly/test/t-mullow.c new file mode 100644 index 0000000..54e152d --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-mullow.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-mullow.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-mullow_KS.c b/external/flint-2.4.3/fq_poly/test/t-mullow_KS.c new file mode 100644 index 0000000..2352e1b --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-mullow_KS.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-mullow_KS.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-mullow_classical.c b/external/flint-2.4.3/fq_poly/test/t-mullow_classical.c new file mode 100644 index 0000000..3ee2f8b --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-mullow_classical.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-mullow_classical.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-mulmod.c b/external/flint-2.4.3/fq_poly/test/t-mulmod.c new file mode 100644 index 0000000..4aca133 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-mulmod.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-mulmod.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-mulmod_preinv.c b/external/flint-2.4.3/fq_poly/test/t-mulmod_preinv.c new file mode 100644 index 0000000..aadf3b0 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-mulmod_preinv.c @@ -0,0 +1,41 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + Copyright (C) 2013 Martin Lee + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-mulmod_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-neg.c b/external/flint-2.4.3/fq_poly/test/t-neg.c new file mode 100644 index 0000000..c764169 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-neg.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-neg.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-pow.c b/external/flint-2.4.3/fq_poly/test/t-pow.c new file mode 100644 index 0000000..fe8ffad --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-pow.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-pow.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-powmod_fmpz_binexp.c b/external/flint-2.4.3/fq_poly/test/t-powmod_fmpz_binexp.c new file mode 100644 index 0000000..ceae7ac --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-powmod_fmpz_binexp.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-powmod_fmpz_binexp.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-powmod_fmpz_binexp_preinv.c b/external/flint-2.4.3/fq_poly/test/t-powmod_fmpz_binexp_preinv.c new file mode 100644 index 0000000..5f3487b --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-powmod_fmpz_binexp_preinv.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-powmod_fmpz_binexp_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-powmod_fmpz_sliding_preinv.c b/external/flint-2.4.3/fq_poly/test/t-powmod_fmpz_sliding_preinv.c new file mode 100644 index 0000000..333aa65 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-powmod_fmpz_sliding_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-powmod_fmpz_sliding_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-powmod_ui_binexp.c b/external/flint-2.4.3/fq_poly/test/t-powmod_ui_binexp.c new file mode 100644 index 0000000..b754d66 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-powmod_ui_binexp.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-powmod_ui_binexp.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-powmod_ui_binexp_preinv.c b/external/flint-2.4.3/fq_poly/test/t-powmod_ui_binexp_preinv.c new file mode 100644 index 0000000..1ffcb16 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-powmod_ui_binexp_preinv.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-powmod_ui_binexp_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-powmod_x_fmpz_preinv.c b/external/flint-2.4.3/fq_poly/test/t-powmod_x_fmpz_preinv.c new file mode 100644 index 0000000..653050d --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-powmod_x_fmpz_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-powmod_x_fmpz_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-randtest_irreducible.c b/external/flint-2.4.3/fq_poly/test/t-randtest_irreducible.c new file mode 100644 index 0000000..bfba4d8 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-randtest_irreducible.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-randtest_irreducible.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-scalar_addmul_fq.c b/external/flint-2.4.3/fq_poly/test/t-scalar_addmul_fq.c new file mode 100644 index 0000000..f953ee1 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-scalar_addmul_fq.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-scalar_addmul_fq.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-scalar_mul_fq.c b/external/flint-2.4.3/fq_poly/test/t-scalar_mul_fq.c new file mode 100644 index 0000000..d5ab003 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-scalar_mul_fq.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-scalar_mul_fq.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-scalar_submul_fq.c b/external/flint-2.4.3/fq_poly/test/t-scalar_submul_fq.c new file mode 100644 index 0000000..e50e4a3 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-scalar_submul_fq.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-scalar_submul_fq.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-shift_left_right.c b/external/flint-2.4.3/fq_poly/test/t-shift_left_right.c new file mode 100644 index 0000000..22106cc --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-shift_left_right.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-shift_left_right.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-sqr.c b/external/flint-2.4.3/fq_poly/test/t-sqr.c new file mode 100644 index 0000000..f681525 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-sqr.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-sqr.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-sqr_KS.c b/external/flint-2.4.3/fq_poly/test/t-sqr_KS.c new file mode 100644 index 0000000..c8a0d51 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-sqr_KS.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-sqr_KS.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-sqr_classical.c b/external/flint-2.4.3/fq_poly/test/t-sqr_classical.c new file mode 100644 index 0000000..6c24ebb --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-sqr_classical.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-sqr_classical.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-sqr_reorder.c b/external/flint-2.4.3/fq_poly/test/t-sqr_reorder.c new file mode 100644 index 0000000..29016ad --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-sqr_reorder.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-sqr_reorder.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/test/t-sub.c b/external/flint-2.4.3/fq_poly/test/t-sub.c new file mode 100644 index 0000000..24f2c81 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/test/t-sub.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/test/t-sub.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly/truncate.c b/external/flint-2.4.3/fq_poly/truncate.c new file mode 100644 index 0000000..16b0bf1 --- /dev/null +++ b/external/flint-2.4.3/fq_poly/truncate.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Andres Goens + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_templates/truncate.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly_factor.h b/external/flint-2.4.3/fq_poly_factor.h new file mode 100644 index 0000000..e6ad1bf --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor.h @@ -0,0 +1,53 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#ifndef FQ_POLY_FACTOR_H +#define FQ_POLY_FACTOR_H + +static __inline__ int FQ_POLY_ITERATED_FROBENIUS_CUTOFF(const fq_ctx_t ctx, slong length) +{ + int result; + fmpz_t q; + fmpz_init(q); + fq_ctx_order(q, ctx); + if ( fmpz_sizeinbase(q, 2) < 3 * (n_sqrt(length) + 1)) + result = 1; + else + result = 0; + fmpz_clear(q); + return result; +} + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_factor_templates.h" +#undef CAP_T +#undef T + +#endif diff --git a/external/flint-2.4.3/fq_poly_factor/clear.c b/external/flint-2.4.3/fq_poly_factor/clear.c new file mode 100644 index 0000000..4fc5a1e --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor/clear.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_factor_templates/clear.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly_factor/concat.c b/external/flint-2.4.3/fq_poly_factor/concat.c new file mode 100644 index 0000000..e98c61a --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor/concat.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_factor_templates/concat.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly_factor/doc/fq_poly_factor.txt b/external/flint-2.4.3/fq_poly_factor/doc/fq_poly_factor.txt new file mode 100644 index 0000000..4d7339f --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor/doc/fq_poly_factor.txt @@ -0,0 +1,254 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012,2013 Andres Goens + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +******************************************************************************* + + Memory Management + +******************************************************************************* + +void fq_poly_factor_init(fq_poly_factor_t fac, const fq_ctx_t ctx) + + Initialises \code{fac} for use. An \code{fq_poly_factor_t} + represents a polynomial in factorised form as a product of + polynomials with associated exponents. + +void fq_poly_factor_clear(fq_poly_factor_t fac, const fq_ctx_t ctx) + + Frees all memory associated with \code{fac}. + +void fq_poly_factor_realloc(fq_poly_factor_t fac, slong alloc, + const fq_ctx_t ctx) + + Reallocates the factor structure to provide space for + precisely \code{alloc} factors. + +void fq_poly_factor_fit_length(fq_poly_factor_t fac, slong len, + const fq_ctx_t ctx) + + Ensures that the factor structure has space for at least + \code{len} factors. This functions takes care of the case of + repeated calls by always at least doubling the number of factors + the structure can hold. + +******************************************************************************* + + Basic Operations + +******************************************************************************* + +void fq_poly_factor_set(fq_poly_factor_t res, const fq_poly_factor_t fac, + const fq_ctx_t ctx) + + Sets \code{res} to the same factorisation as \code{fac}. + +void fq_poly_factor_print_pretty(const fq_poly_factor_t fac, const fq_ctx_t ctx) + + Pretty-prints the entries of \code{fac} to standard output. + +void fq_poly_factor_print(const fq_poly_factor_t fac, const fq_ctx_t ctx) + + Prints the entries of \code{fac} to standard output. + +void fq_poly_factor_insert(fq_poly_factor_t fac, const fq_poly_t poly, + slong exp, const fq_ctx_t ctx) + + Inserts the factor \code{poly} with multiplicity \code{exp} into + the factorisation \code{fac}. + + If \code{fac} already contains \code{poly}, then \code{exp} simply + gets added to the exponent of the existing entry. + +void fq_poly_factor_concat(fq_poly_factor_t res, const fq_poly_factor_t fac, + const fq_ctx_t ctx) + + Concatenates two factorisations. + + This is equivalent to calling \code{fq_poly_factor_insert()} + repeatedly with the individual factors of \code{fac}. + + Does not support aliasing between \code{res} and \code{fac}. + +void fq_poly_factor_pow(fq_poly_factor_t fac, slong exp, const fq_ctx_t ctx) + + Raises \code{fac} to the power \code{exp}. + +ulong fq_poly_remove(fq_poly_t f, const fq_poly_t p, const fq_ctx_t ctx) + + Removes the highest possible power of \code{p} from \code{f} and + returns the exponent. + +******************************************************************************* + + Irreducibility Testing + +******************************************************************************* + +int fq_poly_is_irreducible(const fq_poly_t f, const fq_ctx_t ctx) + + Returns 1 if the polynomial \code{f} is irreducible, otherwise returns 0. + +int fq_poly_is_irreducible_ddf(const fq_poly_t f, const fq_ctx_t ctx) + + Returns 1 if the polynomial \code{f} is irreducible, otherwise returns 0. + Uses fast distinct-degree factorisation. + +int fq_poly_is_irreducible_ben_or(const fq_poly_t f, const fq_ctx_t ctx) + + Returns 1 if the polynomial \code{f} is irreducible, otherwise returns 0. + Uses Ben-Or's irreducibility test. + +int _fq_poly_is_squarefree(const fq_struct * f, slong len, const fq_ctx_t ctx) + + Returns 1 if \code{(f, len)} is squarefree, and 0 otherwise. As a + special case, the zero polynomial is not considered squarefree. + There are no restrictions on the length. + +int fq_poly_is_squarefree(const fq_poly_t f, const fq_ctx_t ctx) + + Returns 1 if \code{f} is squarefree, and 0 otherwise. As a special + case, the zero polynomial is not considered squarefree. + + +******************************************************************************* + + Factorisation + +******************************************************************************* + +int fq_poly_factor_equal_deg_prob(fq_poly_t factor, flint_rand_t state, + const fq_poly_t pol, slong d, + const fq_ctx_t ctx) + + Probabilistic equal degree factorisation of \code{pol} into + irreducible factors of degree \code{d}. If it passes, a factor is + placed in factor and 1 is returned, otherwise 0 is returned and + the value of factor is undetermined. + + Requires that \code{pol} be monic, non-constant and squarefree. + +void fq_poly_factor_equal_deg(fq_poly_factor_t factors, const fq_poly_t pol, + slong d, const fq_ctx_t ctx) + + Assuming \code{pol} is a product of irreducible factors all of + degree \code{d}, finds all those factors and places them in + factors. Requires that \code{pol} be monic, non-constant and + squarefree. + +void fq_poly_factor_distinct_deg(fq_poly_factor_t res, const fq_poly_t poly, + slong * const *degs, const fq_ctx_t ctx) + + Factorises a monic non-constant squarefree polymnomial \code{poly} + of degree n into factors $f[d]$ such that for $1 \leq d \leq n$ + $f[d]$ is the product of the monic irreducible factors of + \code{poly} of degree $d$. Factors are stored in \code{res}, + assotiated powers of irreducible polynomials are stored in + \code{degs} in the same order as factors. + + Requires that \code{degs} have enough space for irreducible polynomials' + powers (maximum space required is $n * sizeof(slong)$). + +void fq_poly_factor_squarefree(fq_poly_factor_t res, const fq_poly_t f, + const fq_ctx_t ctx) + + Sets \code{res} to a squarefree factorization of \code{f}. + +void fq_poly_factor(fq_poly_factor_t res, const fq_poly_t f, const fq_ctx_t ctx) + + Factorises a non-constant polynomial \code{f} into monic + irreducible factors choosing the best algorithm for given modulo + and degree. Choise is based on heuristic measurments. + +void fq_poly_factor_cantor_zassenhaus(fq_poly_factor_t res, const fq_poly_t f, + const fq_ctx_t ctx) + + Factorises a non-constant polynomial \code{f} into monic + irreducible factors using the Cantor-Zassenhaus algorithm. + +void fq_poly_factor_kaltofen_shoup(fq_poly_factor_t res, const fq_poly_t poly, + const fq_ctx_t ctx) + + Factorises a non-constant polynomial \code{f} into monic + irreducible factors using the fast version of Cantor-Zassenhaus + algorithm proposed by Kaltofen and Shoup (1998). More precisely + this algorithm uses a “baby step/giant step†strategy for the + distinct-degree factorization step. + +void fq_poly_factor_berlekamp(fq_poly_factor_t factors, const fq_poly_t f, + const fq_ctx_t ctx) + + Factorises a non-constant polynomial \code{f} into monic + irreducible factors using the Berlekamp algorithm. + +void fq_poly_factor_with_berlekamp(fq_poly_factor_t res, fq_t leading_coeff, + const fq_poly_t f, const fq_ctx_t) + + Factorises a general polynomial \code{f} into monic irreducible + factors and sets \code{leading_coeff} to the leading coefficient + of \code{f}, or 0 if \code{f} is the zero polynomial. + + This function first checks for small special cases, deflates + \code{f} if it is of the form $p(x^m)$ for some $m > 1$, then + performs a square-free factorisation, and finally runs Berlekamp + factorisation on all the individual square-free factors. + +void fq_poly_factor_with_cantor_zassenhaus(fq_poly_factor_t res, + fq_t leading_coeff + const fq_poly_t f, + const fq_ctx_t ctx) + + Factorises a general polynomial \code{f} into monic irreducible + factors and sets \code{leading_coeff} to the leading coefficient + of \code{f}, or 0 if \code{f} is the zero polynomial. + + This function first checks for small special cases, deflates + \code{f} if it is of the form $p(x^m)$ for some $m > 1$, then + performs a square-free factorisation, and finally runs + Cantor-Zassenhaus on all the individual square-free factors. + +void fq_poly_factor_with_kaltofen_shoup(fq_poly_factor_t res, + fq_t leading_coeff, + const fq_poly_t f, + const fq_ctx_t ctx) + + Factorises a general polynomial \code{f} into monic irreducible + factors and sets \code{leading_coeff} to the leading coefficient + of \code{f}, or 0 if \code{f} is the zero polynomial. + + This function first checks for small special cases, deflates + \code{f} if it is of the form $p(x^m)$ for some $m > 1$, then + performs a square-free factorisation, and finally runs + Kaltofen-Shoup on all the individual square-free factors. + +void fq_poly_iterated_frobenius_preinv(fq_poly_t *rop, slong n, + const fq_poly_t v, const fq_poly_t vinv, + const fq_ctx_t ctx) + + Sets \code{rop[i]} to be $x^{q^i} mod v$ for $0 <= i < n$. + + It is required that \code{vinv} is the inverse of the reverse of + \code{v} mod \code{x^lenv}. diff --git a/external/flint-2.4.3/fq_poly_factor/factor.c b/external/flint-2.4.3/fq_poly_factor/factor.c new file mode 100644 index 0000000..579f84d --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor/factor.c @@ -0,0 +1,42 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_factor_templates/factor.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly_factor/factor_berlekamp.c b/external/flint-2.4.3/fq_poly_factor/factor_berlekamp.c new file mode 100644 index 0000000..a8f0c8a --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor/factor_berlekamp.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" +#include "fq_mat.h" + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_factor_templates/factor_berlekamp.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly_factor/factor_cantor_zassenhaus.c b/external/flint-2.4.3/fq_poly_factor/factor_cantor_zassenhaus.c new file mode 100644 index 0000000..0d1d04e --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor/factor_cantor_zassenhaus.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ + +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_factor_templates/factor_cantor_zassenhaus.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly_factor/factor_distinct_deg.c b/external/flint-2.4.3/fq_poly_factor/factor_distinct_deg.c new file mode 100644 index 0000000..c6ec7b0 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor/factor_distinct_deg.c @@ -0,0 +1,37 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_factor_templates/factor_distinct_deg.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly_factor/factor_equal_deg.c b/external/flint-2.4.3/fq_poly_factor/factor_equal_deg.c new file mode 100644 index 0000000..d6e7a73 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor/factor_equal_deg.c @@ -0,0 +1,37 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_factor_templates/factor_equal_deg.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly_factor/factor_equal_deg_prob.c b/external/flint-2.4.3/fq_poly_factor/factor_equal_deg_prob.c new file mode 100644 index 0000000..c997052 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor/factor_equal_deg_prob.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_factor_templates/factor_equal_deg_prob.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly_factor/factor_kaltofen_shoup.c b/external/flint-2.4.3/fq_poly_factor/factor_kaltofen_shoup.c new file mode 100644 index 0000000..421555f --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor/factor_kaltofen_shoup.c @@ -0,0 +1,37 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_factor_templates/factor_kaltofen_shoup.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly_factor/factor_squarefree.c b/external/flint-2.4.3/fq_poly_factor/factor_squarefree.c new file mode 100644 index 0000000..3f7ceb1 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor/factor_squarefree.c @@ -0,0 +1,37 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_factor_templates/factor_squarefree.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly_factor/fit_length.c b/external/flint-2.4.3/fq_poly_factor/fit_length.c new file mode 100644 index 0000000..b63d38a --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor/fit_length.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_factor_templates/fit_length.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly_factor/init.c b/external/flint-2.4.3/fq_poly_factor/init.c new file mode 100644 index 0000000..29f798a --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor/init.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_factor_templates/init.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly_factor/insert.c b/external/flint-2.4.3/fq_poly_factor/insert.c new file mode 100644 index 0000000..471a29b --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor/insert.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_factor_templates/insert.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly_factor/is_irreducible.c b/external/flint-2.4.3/fq_poly_factor/is_irreducible.c new file mode 100644 index 0000000..b1c88ab --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor/is_irreducible.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_factor_templates/is_irreducible.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly_factor/is_irreducible_ben_or.c b/external/flint-2.4.3/fq_poly_factor/is_irreducible_ben_or.c new file mode 100644 index 0000000..634dc82 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor/is_irreducible_ben_or.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_factor_templates/is_irreducible_ben_or.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly_factor/is_irreducible_ddf.c b/external/flint-2.4.3/fq_poly_factor/is_irreducible_ddf.c new file mode 100644 index 0000000..01f1b50 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor/is_irreducible_ddf.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_factor_templates/is_irreducible_ddf.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly_factor/is_squarefree.c b/external/flint-2.4.3/fq_poly_factor/is_squarefree.c new file mode 100644 index 0000000..b4ee977 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor/is_squarefree.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_factor_templates/is_squarefree.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly_factor/iterated_frobenius_preinv.c b/external/flint-2.4.3/fq_poly_factor/iterated_frobenius_preinv.c new file mode 100644 index 0000000..60eb51f --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor/iterated_frobenius_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_factor_templates/iterated_frobenius_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly_factor/pow.c b/external/flint-2.4.3/fq_poly_factor/pow.c new file mode 100644 index 0000000..ecc46d8 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor/pow.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_factor_templates/pow.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly_factor/print.c b/external/flint-2.4.3/fq_poly_factor/print.c new file mode 100644 index 0000000..ab0055d --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor/print.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_factor_templates/print.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly_factor/print_pretty.c b/external/flint-2.4.3/fq_poly_factor/print_pretty.c new file mode 100644 index 0000000..1251be0 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor/print_pretty.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_factor_templates/print_pretty.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly_factor/realloc.c b/external/flint-2.4.3/fq_poly_factor/realloc.c new file mode 100644 index 0000000..e2d9193 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor/realloc.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_factor_templates/realloc.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly_factor/set.c b/external/flint-2.4.3/fq_poly_factor/set.c new file mode 100644 index 0000000..0d258f6 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor/set.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_factor_templates/set.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly_factor/test/t-factor.c b/external/flint-2.4.3/fq_poly_factor/test/t-factor.c new file mode 100644 index 0000000..e1316da --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor/test/t-factor.c @@ -0,0 +1,42 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_factor_templates/test/t-factor.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly_factor/test/t-factor_berlekamp.c b/external/flint-2.4.3/fq_poly_factor/test/t-factor_berlekamp.c new file mode 100644 index 0000000..176e34a --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor/test/t-factor_berlekamp.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_factor_templates/test/t-factor_berlekamp.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly_factor/test/t-factor_cantor_zassenhaus.c b/external/flint-2.4.3/fq_poly_factor/test/t-factor_cantor_zassenhaus.c new file mode 100644 index 0000000..2357c39 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor/test/t-factor_cantor_zassenhaus.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_factor_templates/test/t-factor_cantor_zassenhaus.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly_factor/test/t-factor_distinct_deg.c b/external/flint-2.4.3/fq_poly_factor/test/t-factor_distinct_deg.c new file mode 100644 index 0000000..6aa4ae5 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor/test/t-factor_distinct_deg.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_factor_templates/test/t-factor_distinct_deg.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly_factor/test/t-factor_equal_deg_prob.c b/external/flint-2.4.3/fq_poly_factor/test/t-factor_equal_deg_prob.c new file mode 100644 index 0000000..58e93db --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor/test/t-factor_equal_deg_prob.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_factor_templates/test/t-factor_equal_deg_prob.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly_factor/test/t-factor_kaltofen_shoup.c b/external/flint-2.4.3/fq_poly_factor/test/t-factor_kaltofen_shoup.c new file mode 100644 index 0000000..65c862a --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor/test/t-factor_kaltofen_shoup.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_factor_templates/test/t-factor_kaltofen_shoup.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly_factor/test/t-factor_squarefree.c b/external/flint-2.4.3/fq_poly_factor/test/t-factor_squarefree.c new file mode 100644 index 0000000..fbf5cd1 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor/test/t-factor_squarefree.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_factor_templates/test/t-factor_squarefree.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly_factor/test/t-is_irreducible.c b/external/flint-2.4.3/fq_poly_factor/test/t-is_irreducible.c new file mode 100644 index 0000000..1d8bd13 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor/test/t-is_irreducible.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_factor_templates/test/t-is_irreducible.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly_factor/test/t-is_irreducible_ben_or.c b/external/flint-2.4.3/fq_poly_factor/test/t-is_irreducible_ben_or.c new file mode 100644 index 0000000..8c31b81 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor/test/t-is_irreducible_ben_or.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_factor_templates/test/t-is_irreducible_ben_or.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly_factor/test/t-is_irreducible_ddf.c b/external/flint-2.4.3/fq_poly_factor/test/t-is_irreducible_ddf.c new file mode 100644 index 0000000..46c8776 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor/test/t-is_irreducible_ddf.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_factor_templates/test/t-is_irreducible_ddf.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly_factor/test/t-is_squarefree.c b/external/flint-2.4.3/fq_poly_factor/test/t-is_squarefree.c new file mode 100644 index 0000000..365ba23 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor/test/t-is_squarefree.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + + + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_factor_templates/test/t-is_squarefree.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly_factor/test/t-iterated_frobenius_preinv.c b/external/flint-2.4.3/fq_poly_factor/test/t-iterated_frobenius_preinv.c new file mode 100644 index 0000000..c299dc5 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor/test/t-iterated_frobenius_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_poly_factor_templates/test/t-iterated_frobenius_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_poly_factor_templates.h b/external/flint-2.4.3/fq_poly_factor_templates.h new file mode 100644 index 0000000..b72de6a --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor_templates.h @@ -0,0 +1,186 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Andres Goens + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#ifdef T + +#ifdef __cplusplus +extern "C" { +#endif + +/* Type definitions *********************************************************/ + +typedef struct +{ + TEMPLATE(T, poly_struct) *poly; + slong *exp; + slong num; + slong alloc; +} TEMPLATE(T, poly_factor_struct); + +typedef TEMPLATE(T, poly_factor_struct) TEMPLATE(T, poly_factor_t)[1]; + + +void +TEMPLATE(T, poly_factor_init)(TEMPLATE(T, poly_factor_t) fac, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_factor_clear)(TEMPLATE(T, poly_factor_t) fac, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_factor_realloc)(TEMPLATE(T, poly_factor_t) fac, + slong alloc, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_factor_fit_length)(TEMPLATE(T, poly_factor_t) fac, + slong len, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_factor_set)(TEMPLATE(T, poly_factor_t) res, + const TEMPLATE(T, poly_factor_t) fac, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_factor_insert)(TEMPLATE(T, poly_factor_t) fac, + const TEMPLATE(T, poly_t) poly, + slong exp, const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_factor_print)(const TEMPLATE(T, poly_factor_t) fac, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_factor_print_pretty)(const TEMPLATE(T, poly_factor_t) fac, + const char * var, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_factor_concat)(TEMPLATE(T, poly_factor_t) res, + const TEMPLATE(T, poly_factor_t) fac, + const TEMPLATE(T, ctx_t) ctx); + +void TEMPLATE(T, poly_factor_pow)(TEMPLATE(T, poly_factor_t) fac, slong exp, + const TEMPLATE(T, ctx_t) ctx); + +int +_TEMPLATE(T, poly_is_squarefree)(const TEMPLATE(T, struct) * f, slong len, + const TEMPLATE(T, ctx_t) ctx); + +int +TEMPLATE(T, poly_is_squarefree)(const TEMPLATE(T, poly_t) f, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_factor_squarefree)(TEMPLATE(T, poly_factor_t) res, + const TEMPLATE(T, poly_t) f, + const TEMPLATE(T, ctx_t) ctx); + +int +TEMPLATE(T, poly_is_irreducible)(const TEMPLATE(T, poly_t) f, + const TEMPLATE(T, ctx_t) ctx); + +int +TEMPLATE(T, poly_is_irreducible_ddf)(const TEMPLATE(T, poly_t) f, + const TEMPLATE(T, ctx_t) ctx); + +int +TEMPLATE(T, poly_is_irreducible_ben_or)(const TEMPLATE(T, poly_t) f, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_factor_distinct_deg)(TEMPLATE(T, poly_factor_t) res, + const TEMPLATE(T, poly_t) poly, + slong * const *degs, + const TEMPLATE(T, ctx_t) ctx); + +int +TEMPLATE(T, poly_factor_equal_deg_prob)(TEMPLATE(T, poly_t) factor, + flint_rand_t state, + const TEMPLATE(T, poly_t) pol, slong d, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_factor_equal_deg)(TEMPLATE(T, poly_factor_t) factors, + const TEMPLATE(T, poly_t) pol, + slong d, const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_factor_cantor_zassenhaus)(TEMPLATE(T, poly_factor_t) res, + const TEMPLATE(T, poly_t) f, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_factor_kaltofen_shoup)(TEMPLATE(T, poly_factor_t) res, + const TEMPLATE(T, poly_t) poly, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_factor_berlekamp)(TEMPLATE(T, poly_factor_t) factors, + const TEMPLATE(T, poly_t) f, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_factor_with_berlekamp)(TEMPLATE(T, poly_factor_t) result, + TEMPLATE(T, t) leading_coeff, + const TEMPLATE(T, poly_t) input, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_factor_with_cantor_zassenhaus)( + TEMPLATE(T, poly_factor_t) result, + TEMPLATE(T, t) leading_coeff, + const TEMPLATE(T, poly_t) input, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_factor_with_kaltofen_shoup)(TEMPLATE(T, poly_factor_t) result, + TEMPLATE(T, t) leading_coeff, + const TEMPLATE(T, poly_t) input, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_factor)(TEMPLATE(T, poly_factor_t) result, + TEMPLATE(T, t) leading_coeff, + const TEMPLATE(T, poly_t) input, + const TEMPLATE(T, ctx_t) ctx); + + +void +TEMPLATE(T, poly_iterated_frobenius_preinv)(TEMPLATE(T, poly_t)* rop, + slong n, + const TEMPLATE(T, poly_t) v, + const TEMPLATE(T, poly_t) vinv, + const TEMPLATE(T, ctx_t) ctx); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/flint-2.4.3/fq_poly_factor_templates/clear.c b/external/flint-2.4.3/fq_poly_factor_templates/clear.c new file mode 100644 index 0000000..8fe1688 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor_templates/clear.c @@ -0,0 +1,53 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include "flint.h" +void +TEMPLATE(T, poly_factor_clear) (TEMPLATE(T, poly_factor_t) fac, + const TEMPLATE(T, ctx_t) ctx) +{ + slong i; + + for (i = 0; i < fac->alloc; i++) + { + TEMPLATE(T, poly_clear) (fac->poly + i, ctx); + } + + flint_free(fac->poly); + flint_free(fac->exp); +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_factor_templates/concat.c b/external/flint-2.4.3/fq_poly_factor_templates/concat.c new file mode 100644 index 0000000..cae9cee --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor_templates/concat.c @@ -0,0 +1,48 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +TEMPLATE(T, poly_factor_concat) (TEMPLATE(T, poly_factor_t) res, + const TEMPLATE(T, poly_factor_t) fac, + const TEMPLATE(T, ctx_t) ctx) +{ + slong i; + + for (i = 0; i < fac->num; i++) + TEMPLATE(T, poly_factor_insert) (res, fac->poly + i, fac->exp[i], ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_factor_templates/factor.c b/external/flint-2.4.3/fq_poly_factor_templates/factor.c new file mode 100644 index 0000000..bd627ac --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor_templates/factor.c @@ -0,0 +1,232 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#define ZASSENHAUS 0 +#define BERLEKAMP 1 +#define KALTOFEN 2 + +static __inline__ void +__TEMPLATE(T, poly_factor1) (TEMPLATE(T, poly_factor_t) res, + const TEMPLATE(T, poly_t) f, int algorithm, + const TEMPLATE(T, ctx_t) ctx) +{ + if (algorithm == KALTOFEN) + TEMPLATE(T, poly_factor_kaltofen_shoup) (res, f, ctx); + else if (algorithm == ZASSENHAUS) + TEMPLATE(T, poly_factor_cantor_zassenhaus) (res, f, ctx); + else + TEMPLATE(T, poly_factor_berlekamp) (res, f, ctx); +} + +void +__TEMPLATE(T, poly_factor) (TEMPLATE(T, poly_factor_t) result, + TEMPLATE(T, t) leading_coeff, + const TEMPLATE(T, poly_t) input, + int algorithm, const TEMPLATE(T, ctx_t) ctx) +{ + TEMPLATE(T, poly_t) monic_input; + TEMPLATE(T, poly_factor_t) sqfree_factors, factors; + slong i, len; + + len = input->length; + + if (len <= 1) + { + if (len == 0) + { + TEMPLATE(T, zero) (leading_coeff, ctx); + return; + } + else + { + TEMPLATE(T, set) (leading_coeff, input->coeffs, ctx); + } + } + + TEMPLATE(T, poly_get_coeff) (leading_coeff, input, + TEMPLATE(T, poly_degree) (input, ctx), ctx); + + TEMPLATE(T, poly_init) (monic_input, ctx); + TEMPLATE(T, poly_make_monic) (monic_input, input, ctx); + + if (len == 2) + { + TEMPLATE(T, poly_factor_insert) (result, monic_input, 1, ctx); + TEMPLATE(T, poly_clear) (monic_input, ctx); + TEMPLATE(T, set) (leading_coeff, input->coeffs + 1, ctx); + return; + } + + TEMPLATE(T, poly_factor_init) (sqfree_factors, ctx); + TEMPLATE(T, poly_factor_squarefree) (sqfree_factors, monic_input, ctx); + TEMPLATE(T, poly_clear) (monic_input, ctx); + + /* Run CZ on each of the square-free factors */ + for (i = 0; i < sqfree_factors->num; i++) + { + TEMPLATE(T, poly_factor_init) (factors, ctx); + __TEMPLATE(T, poly_factor1) (factors, sqfree_factors->poly + i, + algorithm, ctx); + TEMPLATE(T, poly_factor_pow) (factors, sqfree_factors->exp[i], ctx); + TEMPLATE(T, poly_factor_concat) (result, factors, ctx); + TEMPLATE(T, poly_factor_clear) (factors, ctx); + } + + TEMPLATE(T, poly_factor_clear) (sqfree_factors, ctx); + + return; +} + +void +__TEMPLATE(T, poly_factor_deflation) (TEMPLATE(T, poly_factor_t) result, + TEMPLATE(T, t) leading_coeff, + const TEMPLATE(T, poly_t) input, + int algorithm, + const TEMPLATE(T, ctx_t) ctx) +{ + slong i; + ulong deflation; + + if (input->length <= 1) + { + if (input->length == 0) + { + TEMPLATE(T, zero) (leading_coeff, ctx); + return; + } + else + { + TEMPLATE(T, set) (leading_coeff, input->coeffs, ctx); + return; + } + } + + deflation = TEMPLATE(T, poly_deflation) (input, ctx); + if (deflation == 1) + { + __TEMPLATE(T, poly_factor) (result, leading_coeff, input, algorithm, + ctx); + return; + } + else + { + TEMPLATE(T, poly_factor_t) def_res; + TEMPLATE(T, poly_t) def; + + TEMPLATE(T, poly_init) (def, ctx); + TEMPLATE(T, poly_deflate) (def, input, deflation, ctx); + TEMPLATE(T, poly_factor_init) (def_res, ctx); + __TEMPLATE(T, poly_factor) (def_res, leading_coeff, def, algorithm, + ctx); + TEMPLATE(T, poly_clear) (def, ctx); + + for (i = 0; i < def_res->num; i++) + { + /* Inflate */ + TEMPLATE(T, poly_t) pol; + TEMPLATE(T, poly_init) (pol, ctx); + TEMPLATE(T, poly_inflate) (pol, def_res->poly + i, deflation, ctx); + + /* Factor inflation */ + if (def_res->exp[i] == 1) + __TEMPLATE(T, poly_factor) (result, leading_coeff, pol, + algorithm, ctx); + else + { + TEMPLATE(T, poly_factor_t) t; + TEMPLATE(T, poly_factor_init) (t, ctx); + __TEMPLATE(T, poly_factor) (t, leading_coeff, pol, algorithm, + ctx); + TEMPLATE(T, poly_factor_pow) (t, def_res->exp[i], ctx); + TEMPLATE(T, poly_factor_concat) (result, t, ctx); + TEMPLATE(T, poly_factor_clear) (t, ctx); + } + TEMPLATE(T, poly_clear) (pol, ctx); + } + + TEMPLATE(T, poly_factor_clear) (def_res, ctx); + } +} + +void +TEMPLATE(T, poly_factor_with_berlekamp) (TEMPLATE(T, poly_factor_t) result, + TEMPLATE(T, t) leading_coeff, + const TEMPLATE(T, poly_t) input, + const TEMPLATE(T, ctx_t) ctx) +{ + __TEMPLATE(T, poly_factor_deflation) (result, leading_coeff, input, + BERLEKAMP, ctx); +} + +void +TEMPLATE(T, poly_factor_with_cantor_zassenhaus) ( + TEMPLATE(T, poly_factor_t) result, + TEMPLATE(T, t) leading_coeff, + const TEMPLATE(T, poly_t) input, + const TEMPLATE(T, ctx_t) ctx) +{ + __TEMPLATE(T, poly_factor_deflation) (result, leading_coeff, input, + ZASSENHAUS, ctx); +} + +void +TEMPLATE(T, poly_factor_with_kaltofen_shoup) ( + TEMPLATE(T, poly_factor_t) result, + TEMPLATE(T, t) leading_coeff, + const TEMPLATE(T, poly_t) input, + const TEMPLATE(T, ctx_t) ctx) +{ + __TEMPLATE(T, poly_factor_deflation) (result, leading_coeff, input, + KALTOFEN, ctx); +} + +void +TEMPLATE(T, poly_factor) (TEMPLATE(T, poly_factor_t) result, + TEMPLATE(T, t) leading_coeff, + const TEMPLATE(T, poly_t) input, + const TEMPLATE(T, ctx_t) ctx) +{ + mp_bitcnt_t bits = fmpz_bits(TEMPLATE(T, ctx_prime) (ctx)); + slong n = TEMPLATE(T, poly_degree) (input, ctx); + + if (n < 10 + 50 / bits) + __TEMPLATE(T, poly_factor_deflation) (result, leading_coeff, input, + ZASSENHAUS, ctx); + else + __TEMPLATE(T, poly_factor_deflation) (result, leading_coeff, input, + KALTOFEN, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_factor_templates/factor_berlekamp.c b/external/flint-2.4.3/fq_poly_factor_templates/factor_berlekamp.c new file mode 100644 index 0000000..45ed981 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor_templates/factor_berlekamp.c @@ -0,0 +1,320 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include "perm.h" + +static void +TEMPLATE(T, to_mat_col) (TEMPLATE(T, mat_t) mat, slong col, + TEMPLATE(T, poly_t) poly, + const TEMPLATE(T, ctx_t) ctx) +{ + slong i; + + for (i = 0; i < poly->length; i++) + TEMPLATE(T, set) (TEMPLATE(T, mat_entry) (mat, i, col), + poly->coeffs + i, ctx); + + for (; i < mat->r; i++) + TEMPLATE(T, zero) (TEMPLATE(T, mat_entry) (mat, i, col), ctx); + +} + +static void +TEMPLATE(T, mat_col_to_shifted) (TEMPLATE(T, poly_t) poly, + TEMPLATE(T, mat_t) mat, + slong col, slong * shift, + const TEMPLATE(T, ctx_t) ctx) +{ + slong i, j, rows = mat->r; + + TEMPLATE(T, poly_fit_length) (poly, rows, ctx); + + for (i = 0, j = 0; j < rows; j++) + { + if (shift[j]) + TEMPLATE(T, zero) (poly->coeffs + j, ctx); + else + { + TEMPLATE(T, set) (poly->coeffs + j, + TEMPLATE(T, mat_entry) (mat, i, col), ctx); + i++; + } + } + + _TEMPLATE(T, poly_set_length) (poly, rows, ctx); + _TEMPLATE(T, poly_normalise) (poly, ctx); +} + +static void +__TEMPLATE(T, poly_factor_berlekamp) (TEMPLATE(T, poly_factor_t) factors, + flint_rand_t state, + const TEMPLATE(T, poly_t) f, + const TEMPLATE(T, ctx_t) ctx) +{ + const slong n = TEMPLATE(T, poly_degree) (f, ctx); + + TEMPLATE(T, poly_factor_t) fac1, fac2; + TEMPLATE(T, poly_t) x, x_q; + TEMPLATE(T, poly_t) x_qi, x_qi2; + TEMPLATE(T, poly_t) Q, r; + + TEMPLATE(T, mat_t) matrix; + TEMPLATE(T, t) mul, coeff, neg_one; + fmpz_t p, q, s, pow; + slong i, nullity, col, row; + slong *shift; + + TEMPLATE(T, poly_t) * basis; + + if (f->length <= 2) + { + TEMPLATE(T, poly_factor_insert) (factors, f, 1, ctx); + return; + } + + TEMPLATE(T, init) (coeff, ctx); + TEMPLATE(T, init) (neg_one, ctx); + TEMPLATE(T, init) (mul, ctx); + + fmpz_init_set(p, TEMPLATE(T, ctx_prime) (ctx)); + fmpz_init(q); + TEMPLATE(T, ctx_order) (q, ctx); + + TEMPLATE(T, one) (neg_one, ctx); + TEMPLATE(T, neg) (neg_one, neg_one, ctx); + + + /* s = q - 1 */ + fmpz_init_set(s, q); + fmpz_sub_ui(s, s, 1); + + /* pow = (q-1)/2 */ + fmpz_init(pow); + if (fmpz_cmp_ui(p, 3) > 0) + { + fmpz_set(pow, s); + fmpz_divexact_ui(pow, pow, 2); + } + + /* Step 1, compute x^q mod f in F_p[X]/ */ + TEMPLATE(T, poly_init) (x, ctx); + TEMPLATE(T, poly_init) (x_q, ctx); + + TEMPLATE(T, poly_gen) (x, ctx); + TEMPLATE(T, poly_powmod_fmpz_binexp) (x_q, x, q, f, ctx); + TEMPLATE(T, poly_clear) (x, ctx); + + /* Step 2, compute the matrix for the Berlekamp Map */ + TEMPLATE(T, mat_init) (matrix, n, n, ctx); + TEMPLATE(T, poly_init) (x_qi, ctx); + TEMPLATE(T, poly_init) (x_qi2, ctx); + TEMPLATE(T, poly_one) (x_qi, ctx); + + for (i = 0; i < n; i++) + { + /* Q - I */ + TEMPLATE(T, poly_set) (x_qi2, x_qi, ctx); + TEMPLATE(T, poly_get_coeff) (coeff, x_qi2, i, ctx); + TEMPLATE(T, sub_one) (coeff, coeff, ctx); + TEMPLATE(T, poly_set_coeff) (x_qi2, i, coeff, ctx); + TEMPLATE(T, to_mat_col) (matrix, i, x_qi2, ctx); + TEMPLATE(T, poly_mulmod) (x_qi, x_qi, x_q, f, ctx); + } + + TEMPLATE(T, poly_clear) (x_q, ctx); + TEMPLATE(T, poly_clear) (x_qi, ctx); + TEMPLATE(T, poly_clear) (x_qi2, ctx); + + /* Row reduce Q - I */ + nullity = n - TEMPLATE(T, mat_rref) (matrix, ctx); + + /* Find a basis for the nullspace */ + basis = flint_malloc(nullity * sizeof(TEMPLATE(T, poly_t))); + shift = (slong *) flint_calloc(n, sizeof(slong)); + + col = 1; /* first column is always zero */ + row = 0; + shift[0] = 1; + + for (i = 1; i < nullity; i++) + { + TEMPLATE(T, poly_init) (basis[i], ctx); + while (!TEMPLATE(T, is_zero) + (TEMPLATE(T, mat_entry) (matrix, row, col), ctx)) + { + row++; + col++; + } + TEMPLATE(T, mat_col_to_shifted) (basis[i], matrix, col, shift, ctx); + TEMPLATE(T, poly_set_coeff) (basis[i], col, neg_one, ctx); + shift[col] = 1; + col++; + } + + flint_free(shift); + TEMPLATE(T, mat_clear) (matrix, ctx); + + /* we are done */ + if (nullity == 1) + { + TEMPLATE(T, poly_factor_insert) (factors, f, 1, ctx); + } + else + { + /* Generate random linear combinations */ + TEMPLATE(T, poly_t) factor, b, power, g; + TEMPLATE(T, poly_init) (factor, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (power, ctx); + TEMPLATE(T, poly_init) (g, ctx); + + while (1) + { + do + { + TEMPLATE(T, poly_zero) (factor, ctx); + for (i = 1; i < nullity; i++) + { + TEMPLATE(T, randtest) (mul, state, ctx); + TEMPLATE(T, TEMPLATE(poly_scalar_mul, T)) (b, basis[i], + mul, ctx); + TEMPLATE(T, poly_add) (factor, factor, b, ctx); + } + + TEMPLATE(T, randtest) (coeff, state, ctx); + TEMPLATE(T, poly_set_coeff) (factor, 0, coeff, ctx); + if (!TEMPLATE(T, poly_is_zero) (factor, ctx)) + TEMPLATE(T, poly_make_monic) (factor, factor, ctx); + } + while (TEMPLATE(T, poly_is_zero) (factor, ctx) || + (factor->length < 2 + && TEMPLATE(T, is_one) (factor->coeffs, ctx))); + + TEMPLATE(T, poly_gcd) (g, f, factor, ctx); + + if (TEMPLATE(T, poly_length) (g, ctx) != 1) + break; + + if (fmpz_cmp_ui(p, 3) > 0) + TEMPLATE(T, poly_powmod_fmpz_binexp) (power, factor, pow, f, + ctx); + else + TEMPLATE(T, poly_set) (power, factor, ctx); + + TEMPLATE(T, sub_one) (power->coeffs, power->coeffs, ctx); + + _TEMPLATE(T, poly_normalise) (power, ctx); + TEMPLATE(T, poly_gcd) (g, power, f, ctx); + + if (TEMPLATE(T, poly_length) (g, ctx) != 1) + break; + } + + TEMPLATE(T, poly_clear) (power, ctx); + TEMPLATE(T, poly_clear) (factor, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + + if (!TEMPLATE(T, poly_is_zero) (g, ctx)) + TEMPLATE(T, poly_make_monic) (g, g, ctx); + + TEMPLATE(T, poly_factor_init) (fac1, ctx); + TEMPLATE(T, poly_factor_init) (fac2, ctx); + __TEMPLATE(T, poly_factor_berlekamp) (fac1, state, g, ctx); + TEMPLATE(T, poly_init) (Q, ctx); + TEMPLATE(T, poly_init) (r, ctx); + TEMPLATE(T, poly_divrem) (Q, r, f, g, ctx); + TEMPLATE(T, poly_clear) (r, ctx); + + if (!TEMPLATE(T, poly_is_zero) (Q, ctx)) + TEMPLATE(T, poly_make_monic) (Q, Q, ctx); + + __TEMPLATE(T, poly_factor_berlekamp) (fac2, state, Q, ctx); + TEMPLATE(T, poly_factor_concat) (factors, fac1, ctx); + TEMPLATE(T, poly_factor_concat) (factors, fac2, ctx); + TEMPLATE(T, poly_factor_clear) (fac1, ctx); + TEMPLATE(T, poly_factor_clear) (fac2, ctx); + TEMPLATE(T, poly_clear) (Q, ctx); + TEMPLATE(T, poly_clear) (g, ctx); + } + + for (i = 1; i < nullity; i++) + TEMPLATE(T, poly_clear) (basis[i], ctx); + flint_free(basis); + + TEMPLATE(T, clear) (coeff, ctx); + TEMPLATE(T, clear) (neg_one, ctx); + TEMPLATE(T, clear) (mul, ctx); + fmpz_clear(pow); + fmpz_clear(p); + fmpz_clear(s); +} + +void +TEMPLATE(T, poly_factor_berlekamp) (TEMPLATE(T, poly_factor_t) factors, + const TEMPLATE(T, poly_t) f, + const TEMPLATE(T, ctx_t) ctx) +{ + slong i; + flint_rand_t r; + TEMPLATE(T, poly_t) v; + TEMPLATE(T, poly_factor_t) sq_free; + + TEMPLATE(T, poly_init) (v, ctx); + + TEMPLATE(T, poly_make_monic) (v, f, ctx); + + /* compute squarefree factorisation */ + TEMPLATE(T, poly_factor_init) (sq_free, ctx); + TEMPLATE(T, poly_factor_squarefree) (sq_free, v, ctx); + + /* run Berlekamp algorithm for all squarefree factors */ + flint_randinit(r); + for (i = 0; i < sq_free->num; i++) + { + __TEMPLATE(T, poly_factor_berlekamp) (factors, r, sq_free->poly + i, + ctx); + } + flint_randclear(r); + + /* compute multiplicities of factors in f */ + for (i = 0; i < factors->num; i++) + factors->exp[i] = TEMPLATE(T, poly_remove) (v, factors->poly + i, ctx); + + TEMPLATE(T, poly_clear) (v, ctx); + TEMPLATE(T, poly_factor_clear) (sq_free, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_factor_templates/factor_cantor_zassenhaus.c b/external/flint-2.4.3/fq_poly_factor_templates/factor_cantor_zassenhaus.c new file mode 100644 index 0000000..a69a5b7 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor_templates/factor_cantor_zassenhaus.c @@ -0,0 +1,92 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ + +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +TEMPLATE(T, poly_factor_cantor_zassenhaus) (TEMPLATE(T, poly_factor_t) res, + const TEMPLATE(T, poly_t) f, + const TEMPLATE(T, ctx_t) ctx) +{ + TEMPLATE(T, poly_t) h, v, g, x; + fmpz_t q; + slong i, j, num; + + fmpz_init(q); + TEMPLATE(T, ctx_order) (q, ctx); + + TEMPLATE(T, poly_init) (h, ctx); + TEMPLATE(T, poly_init) (g, ctx); + TEMPLATE(T, poly_init) (v, ctx); + TEMPLATE(T, poly_init) (x, ctx); + + TEMPLATE(T, poly_gen) (h, ctx); + TEMPLATE(T, poly_gen) (x, ctx); + + TEMPLATE(T, poly_make_monic) (v, f, ctx); + + i = 0; + do + { + i++; + TEMPLATE(T, poly_powmod_fmpz_binexp) (h, h, q, v, ctx); + + TEMPLATE(T, poly_sub) (h, h, x, ctx); + TEMPLATE(T, poly_gcd) (g, h, v, ctx); + TEMPLATE(T, poly_add) (h, h, x, ctx); + + if (g->length != 1) + { + TEMPLATE(T, poly_make_monic) (g, g, ctx); + num = res->num; + + TEMPLATE(T, poly_factor_equal_deg) (res, g, i, ctx); + for (j = num; j < res->num; j++) + res->exp[j] = TEMPLATE(T, poly_remove) (v, res->poly + j, ctx); + } + } + while (v->length >= 2 * i + 3); + + if (v->length > 1) + TEMPLATE(T, poly_factor_insert) (res, v, 1, ctx); + + TEMPLATE(T, poly_clear) (g, ctx); + TEMPLATE(T, poly_clear) (h, ctx); + TEMPLATE(T, poly_clear) (v, ctx); + TEMPLATE(T, poly_clear) (x, ctx); + fmpz_clear(q); +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_factor_templates/factor_distinct_deg.c b/external/flint-2.4.3/fq_poly_factor_templates/factor_distinct_deg.c new file mode 100644 index 0000000..e0cdb14 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor_templates/factor_distinct_deg.c @@ -0,0 +1,216 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Martin Lee + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include + +void +TEMPLATE(T, poly_factor_distinct_deg) (TEMPLATE(T, poly_factor_t) res, + const TEMPLATE(T, poly_t) poly, + slong * const *degs, + const TEMPLATE(T, ctx_t) ctx) +{ + TEMPLATE(T, poly_t) f, g, s, reducedH0, v, vinv, tmp; + TEMPLATE(T, poly_t) * h, *H, *I; + fmpz_t q; + slong i, j, l, m, n, index, d; + double beta; + TEMPLATE(T, mat_t) HH, HHH; + + TEMPLATE(T, poly_init) (v, ctx); + TEMPLATE(T, poly_make_monic) (v, poly, ctx); + + n = TEMPLATE(T, poly_degree) (poly, ctx); + if (n == 1) + { + TEMPLATE(T, poly_factor_insert) (res, poly, 1, ctx); + (*degs)[0] = 1; + TEMPLATE(T, poly_clear) (v, ctx); + return; + } + + beta = 0.5 * (1. - (log(2) / log(n))); + l = ceil(pow(n, beta)); + m = ceil(0.5 * n / l); + + fmpz_init(q); + TEMPLATE(T, ctx_order) (q, ctx); + + TEMPLATE(T, poly_init) (f, ctx); + TEMPLATE(T, poly_init) (g, ctx); + TEMPLATE(T, poly_init) (s, ctx); + TEMPLATE(T, poly_init) (reducedH0, ctx); + TEMPLATE(T, poly_init) (vinv, ctx); + TEMPLATE(T, poly_init) (tmp, ctx); + + if (! + (h = flint_malloc((2 * m + l + 1) * sizeof(TEMPLATE(T, poly_struct))))) + { + TEMPLATE_PRINTF("Exception (%s_poly_factor_distinct_deg):\n", T); + flint_printf("Not enough memory.\n"); + abort(); + } + H = h + (l + 1); + I = H + m; + for (i = 0; i < l + 1; i++) + TEMPLATE(T, poly_init) (h[i], ctx); + for (i = 0; i < m; i++) + { + TEMPLATE(T, poly_init) (H[i], ctx); + TEMPLATE(T, poly_init) (I[i], ctx); + } + + TEMPLATE(T, poly_make_monic) (v, poly, ctx); + + TEMPLATE(T, poly_reverse) (vinv, v, v->length, ctx); + TEMPLATE(T, poly_inv_series_newton) (vinv, vinv, v->length, ctx); + + /* compute baby steps: h[i]=x^{q^i}mod v */ + /* h[0] = x */ + + TEMPLATE(T, poly_iterated_frobenius_preinv) (h, l + 1, v, vinv, ctx); + + /* compute coarse distinct-degree factorisation */ + index = 0; + TEMPLATE(T, poly_set) (s, v, ctx); + TEMPLATE(T, poly_set) (H[0], h[l], ctx); + TEMPLATE(T, poly_set) (reducedH0, H[0], ctx); + TEMPLATE(T, mat_init) (HH, n_sqrt(v->length - 1) + 1, v->length - 1, ctx); + TEMPLATE(T, poly_precompute_matrix) (HH, reducedH0, s, vinv, ctx); + + d = 1; + for (j = 0; j < m; j++) + { + /* compute giant steps: H[j]=x^{q^(lj)}mod s */ + if (j > 0) + { + if (I[j - 1]->length > 1) + { + _TEMPLATE(T, poly_reduce_matrix_mod_poly) (HHH, HH, s, ctx); + TEMPLATE(T, mat_clear) (HH, ctx); + TEMPLATE(T, mat_init_set) (HH, HHH, ctx); + TEMPLATE(T, mat_clear) (HHH, ctx); + TEMPLATE(T, poly_rem) (reducedH0, reducedH0, s, ctx); + TEMPLATE(T, poly_rem) (tmp, H[j - 1], s, ctx); + TEMPLATE(T, poly_compose_mod_brent_kung_precomp_preinv) + (H[j], tmp, HH, s, vinv, ctx); + } + else + { + TEMPLATE(T, poly_compose_mod_brent_kung_precomp_preinv) + (H[j], H[j - 1], HH, s, vinv, ctx); + + } + } + + /* compute interval polynomials */ + TEMPLATE(T, poly_one) (I[j], ctx); + for (i = l - 1; (i >= 0) && (2 * d <= s->length - 1); i--, d++) + { + TEMPLATE(T, poly_rem) (tmp, h[i], s, ctx); + TEMPLATE(T, poly_sub) (tmp, H[j], tmp, ctx); + TEMPLATE(T, poly_mulmod_preinv) (I[j], tmp, I[j], s, vinv, ctx); + } + + /* compute F_j=f^{[j*l+1]} * ... * f^{[j*l+l]} */ + /* F_j is stored on the place of I_j */ + TEMPLATE(T, poly_gcd) (I[j], s, I[j], ctx); + if (I[j]->length > 1) + { + TEMPLATE(T, poly_remove) (s, I[j], ctx); + TEMPLATE(T, poly_reverse) (vinv, s, s->length, ctx); + TEMPLATE(T, poly_inv_series_newton) (vinv, vinv, s->length, ctx); + } + if (s->length - 1 < 2 * d) + { + break; + } + } + if (s->length > 1) + { + TEMPLATE(T, poly_factor_insert) (res, s, 1, ctx); + (*degs)[index++] = s->length - 1; + } + + + /* compute fine distinct-degree factorisation */ + for (j = 0; j < m; j++) + { + if (I[j]->length - 1 > (j + 1) * l || j == 0) + { + TEMPLATE(T, poly_set) (g, I[j], ctx); + for (i = l - 1; i >= 0 && (g->length > 1); i--) + { + /* compute f^{[l*(j+1)-i]} */ + TEMPLATE(T, poly_sub) (tmp, H[j], h[i], ctx); + TEMPLATE(T, poly_gcd) (f, g, tmp, ctx); + if (f->length > 1) + { + /* insert f^{[l*(j+1)-i]} into res */ + TEMPLATE(T, poly_make_monic) (f, f, ctx); + TEMPLATE(T, poly_factor_insert) (res, f, 1, ctx); + (*degs)[index++] = l * (j + 1) - i; + + TEMPLATE(T, poly_remove) (g, f, ctx); + } + } + } + else if (I[j]->length > 1) + { + TEMPLATE(T, poly_make_monic) (I[j], I[j], ctx); + TEMPLATE(T, poly_factor_insert) (res, I[j], 1, ctx); + (*degs)[index++] = I[j]->length - 1; + } + } + + /* cleanup */ + fmpz_clear(q); + TEMPLATE(T, poly_clear) (f, ctx); + TEMPLATE(T, poly_clear) (g, ctx); + TEMPLATE(T, poly_clear) (s, ctx); + TEMPLATE(T, poly_clear) (reducedH0, ctx); + TEMPLATE(T, poly_clear) (v, ctx); + TEMPLATE(T, poly_clear) (vinv, ctx); + TEMPLATE(T, poly_clear) (tmp, ctx); + TEMPLATE(T, mat_clear) (HH, ctx); + + for (i = 0; i < l + 1; i++) + TEMPLATE(T, poly_clear) (h[i], ctx); + for (i = 0; i < m; i++) + { + TEMPLATE(T, poly_clear) (H[i], ctx); + TEMPLATE(T, poly_clear) (I[i], ctx); + } + flint_free(h); +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_factor_templates/factor_equal_deg.c b/external/flint-2.4.3/fq_poly_factor_templates/factor_equal_deg.c new file mode 100644 index 0000000..b149535 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor_templates/factor_equal_deg.c @@ -0,0 +1,76 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include "ulong_extras.h" + +void +TEMPLATE(T, poly_factor_equal_deg) (TEMPLATE(T, poly_factor_t) factors, + const TEMPLATE(T, poly_t) pol, slong d, + const TEMPLATE(T, ctx_t) ctx) +{ + if (pol->length == d + 1) + { + TEMPLATE(T, poly_factor_insert) (factors, pol, 1, ctx); + } + else + { + TEMPLATE(T, poly_t) f, g, r; + flint_rand_t state; + + TEMPLATE(T, poly_init) (f, ctx); + + flint_randinit(state); + + while (!TEMPLATE(T, poly_factor_equal_deg_prob) + (f, state, pol, d, ctx)) + { + }; + + flint_randclear(state); + + TEMPLATE(T, poly_init) (g, ctx); + TEMPLATE(T, poly_init) (r, ctx); + TEMPLATE(T, poly_divrem) (g, r, pol, f, ctx); + TEMPLATE(T, poly_clear) (r, ctx); + + TEMPLATE(T, poly_factor_equal_deg) (factors, f, d, ctx); + TEMPLATE(T, poly_clear) (f, ctx); + TEMPLATE(T, poly_factor_equal_deg) (factors, g, d, ctx); + TEMPLATE(T, poly_clear) (g, ctx); + } +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_factor_templates/factor_equal_deg_prob.c b/external/flint-2.4.3/fq_poly_factor_templates/factor_equal_deg_prob.c new file mode 100644 index 0000000..8f9ce5d --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor_templates/factor_equal_deg_prob.c @@ -0,0 +1,130 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include "ulong_extras.h" +int +TEMPLATE(T, poly_factor_equal_deg_prob) (TEMPLATE(T, poly_t) factor, + flint_rand_t state, + const TEMPLATE(T, poly_t) pol, + slong d, + const TEMPLATE(T, ctx_t) ctx) +{ + TEMPLATE(T, poly_t) a, b, c, polinv; + TEMPLATE(T, t) t; + fmpz_t exp, q; + int res = 1; + slong i, k; + + if (pol->length <= 1) + { + TEMPLATE_PRINTF("Exception (%s_poly_factor_equal_deg_prob): \n", T); + flint_printf("Input polynomial is linear.\n"); + abort(); + } + + fmpz_init(q); + TEMPLATE(T, ctx_order) (q, ctx); + + TEMPLATE(T, poly_init) (a, ctx); + + do + { + TEMPLATE(T, poly_randtest) (a, state, pol->length - 1, ctx); + } while (a->length <= 1); + + TEMPLATE(T, poly_gcd) (factor, a, pol, ctx); + + if (factor->length != 1) + { + TEMPLATE(T, poly_clear) (a, ctx); + return 1; + } + + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (polinv, ctx); + + TEMPLATE(T, poly_reverse) (polinv, pol, pol->length, ctx); + TEMPLATE(T, poly_inv_series_newton) (polinv, polinv, polinv->length, ctx); + + fmpz_init(exp); + if (fmpz_cmp_ui(TEMPLATE(T, ctx_prime) (ctx), 2) > 0) + { + /* compute a^{(q^d-1)/2} rem pol */ + fmpz_pow_ui(exp, q, d); + fmpz_sub_ui(exp, exp, 1); + fmpz_fdiv_q_2exp(exp, exp, 1); + + TEMPLATE(T, poly_powmod_fmpz_sliding_preinv) (b, a, exp, 0, pol, + polinv, ctx); + } + else + { + /* compute b = (a^{2^{k*d-1}}+a^{2^{k*d-2}}+...+a^4+a^2+a) rem pol */ + k = d * TEMPLATE(T, ctx_degree) (ctx); /* TODO: Handle overflow? */ + TEMPLATE(T, poly_rem) (b, a, pol, ctx); + TEMPLATE(T, poly_init) (c, ctx); + TEMPLATE(T, poly_set) (c, b, ctx); + for (i = 1; i < k; i++) + { + /* c = a^{2^i} = (a^{2^{i-1}})^2 */ + TEMPLATE(T, poly_powmod_ui_binexp_preinv) (c, c, 2, pol, polinv, + ctx); + TEMPLATE(T, poly_add) (b, b, c, ctx); + } + TEMPLATE(T, poly_rem) (b, b, pol, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + } + fmpz_clear(exp); + + TEMPLATE(T, init) (t, ctx); + TEMPLATE(T, sub_one) (t, b->coeffs + 0, ctx); + TEMPLATE(T, poly_set_coeff) (b, 0, t, ctx); + TEMPLATE(T, clear) (t, ctx); + + TEMPLATE(T, poly_gcd) (factor, b, pol, ctx); + + if ((factor->length <= 1) || (factor->length == pol->length)) + res = 0; + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (polinv, ctx); + fmpz_clear(q); + + return res; +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_factor_templates/factor_kaltofen_shoup.c b/external/flint-2.4.3/fq_poly_factor_templates/factor_kaltofen_shoup.c new file mode 100644 index 0000000..168cacb --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor_templates/factor_kaltofen_shoup.c @@ -0,0 +1,89 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include + +void +TEMPLATE(T, poly_factor_kaltofen_shoup) (TEMPLATE(T, poly_factor_t) res, + const TEMPLATE(T, poly_t) poly, + const TEMPLATE(T, ctx_t) ctx) +{ + TEMPLATE(T, poly_t) v; + TEMPLATE(T, poly_factor_t) sq_free, dist_deg; + slong i, j, k, l, res_num, dist_deg_num; + slong *degs; + + if (! + (degs = + flint_malloc(TEMPLATE(T, poly_degree) (poly, ctx) * sizeof(slong)))) + { + TEMPLATE_PRINTF("Exception (%s_poly_factor_kaltofen_shoup): \n", T); + flint_printf("Not enough memory.\n"); + abort(); + } + + TEMPLATE(T, poly_init) (v, ctx); + + TEMPLATE(T, poly_make_monic) (v, poly, ctx); + + /* compute squarefree factorisation */ + TEMPLATE(T, poly_factor_init) (sq_free, ctx); + TEMPLATE(T, poly_factor_squarefree) (sq_free, v, ctx); + + /* compute distinct-degree factorisation */ + TEMPLATE(T, poly_factor_init) (dist_deg, ctx); + for (i = 0; i < sq_free->num; i++) + { + dist_deg_num = dist_deg->num; + + TEMPLATE(T, poly_factor_distinct_deg) (dist_deg, sq_free->poly + i, + °s, ctx); + + /* compute equal-degree factorisation */ + for (j = dist_deg_num, l = 0; j < dist_deg->num; j++, l++) + { + res_num = res->num; + + TEMPLATE(T, poly_factor_equal_deg) (res, dist_deg->poly + j, + degs[l], ctx); + for (k = res_num; k < res->num; k++) + res->exp[k] = TEMPLATE(T, poly_remove) (v, res->poly + k, ctx); + } + } + + flint_free(degs); + TEMPLATE(T, poly_clear) (v, ctx); + TEMPLATE(T, poly_factor_clear) (dist_deg, ctx); + TEMPLATE(T, poly_factor_clear) (sq_free, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_factor_templates/factor_squarefree.c b/external/flint-2.4.3/fq_poly_factor_templates/factor_squarefree.c new file mode 100644 index 0000000..591b4c7 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor_templates/factor_squarefree.c @@ -0,0 +1,180 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include "ulong_extras.h" + +void +TEMPLATE(T, poly_factor_squarefree) (TEMPLATE(T, poly_factor_t) res, + const TEMPLATE(T, poly_t) f, + const TEMPLATE(T, ctx_t) ctx) +{ + TEMPLATE(T, poly_t) f_d, g, g_1, r; + TEMPLATE(T, t) x; + fmpz_t p; + slong deg, i, p_ui; + + if (f->length <= 1) + { + res->num = 0; + return; + } + + if (f->length == 2) + { + TEMPLATE(T, poly_factor_insert) (res, f, 1, ctx); + return; + } + + fmpz_init(p); + fmpz_set(p, TEMPLATE(T, ctx_prime) (ctx)); + + deg = TEMPLATE(T, poly_degree) (f, ctx); + + /* Step 1, look at f', if it is zero then we are done since f = h(x)^p + for some particular h(x), clearly f(x) = sum a_k x^kp, k <= deg(f) */ + + TEMPLATE(T, init) (x, ctx); + TEMPLATE(T, poly_init) (g_1, ctx); + TEMPLATE(T, poly_init) (f_d, ctx); + TEMPLATE(T, poly_init) (g, ctx); + TEMPLATE(T, poly_derivative) (f_d, f, ctx); + + /* Case 1 */ + if (TEMPLATE(T, poly_is_zero) (f_d, ctx)) + { + TEMPLATE(T, poly_factor_t) new_res; + TEMPLATE(T, poly_t) h; + + /* We can do this since deg is a multiple of p in this case */ + p_ui = fmpz_get_ui(p); + + TEMPLATE(T, poly_init) (h, ctx); + + for (i = 0; i <= deg / p_ui; i++) /* this will be an integer since f'=0 */ + { + TEMPLATE(T, poly_get_coeff) (x, f, i * p_ui, ctx); + TEMPLATE(T, pth_root) (x, x, ctx); + TEMPLATE(T, poly_set_coeff) (h, i, x, ctx); + } + + /* Now run squarefree on h, and return it to the pth power */ + TEMPLATE(T, poly_factor_init) (new_res, ctx); + + TEMPLATE(T, poly_factor_squarefree) (new_res, h, ctx); + TEMPLATE(T, poly_factor_pow) (new_res, p_ui, ctx); + + TEMPLATE(T, poly_factor_concat) (res, new_res, ctx); + TEMPLATE(T, poly_clear) (h, ctx); + TEMPLATE(T, poly_factor_clear) (new_res, ctx); + } + else + { + TEMPLATE(T, poly_t) h, z; + + TEMPLATE(T, poly_init) (r, ctx); + + TEMPLATE(T, poly_gcd) (g, f, f_d, ctx); + TEMPLATE(T, poly_divrem) (g_1, r, f, g, ctx); + + i = 1; + + TEMPLATE(T, poly_init) (h, ctx); + TEMPLATE(T, poly_init) (z, ctx); + + /* Case 2 */ + while (g_1->length > 1) + { + TEMPLATE(T, poly_gcd) (h, g_1, g, ctx); + TEMPLATE(T, poly_divrem) (z, r, g_1, h, ctx); + + /* out <- out.z */ + if (z->length > 1) + { + TEMPLATE(T, poly_factor_insert) (res, z, 1, ctx); + TEMPLATE(T, poly_make_monic) (res->poly + (res->num - 1), + res->poly + (res->num - 1), ctx); + if (res->num) + res->exp[res->num - 1] *= i; + } + + i++; + TEMPLATE(T, poly_set) (g_1, h, ctx); + TEMPLATE(T, poly_divrem) (g, r, g, h, ctx); + } + + TEMPLATE(T, poly_clear) (h, ctx); + TEMPLATE(T, poly_clear) (z, ctx); + TEMPLATE(T, poly_clear) (r, ctx); + + TEMPLATE(T, poly_make_monic) (g, g, ctx); + + if (g->length > 1) + { + /* so now we multiply res with squarefree(g^1/p) ^ p */ + TEMPLATE(T, poly_t) g_p; /* g^(1/p) */ + TEMPLATE(T, poly_factor_t) new_res_2; + + TEMPLATE(T, poly_init) (g_p, ctx); + + p_ui = fmpz_get_ui(p); + + for (i = 0; i <= TEMPLATE(T, poly_degree) (g, ctx) / p_ui; i++) + { + TEMPLATE(T, poly_get_coeff) (x, g, i * p_ui, ctx); + TEMPLATE(T, pth_root) (x, x, ctx); + TEMPLATE(T, poly_set_coeff) (g_p, i, x, ctx); + } + + TEMPLATE(T, poly_factor_init) (new_res_2, ctx); + + /* squarefree(g^(1/p)) */ + TEMPLATE(T, poly_factor_squarefree) (new_res_2, g_p, ctx); + TEMPLATE(T, poly_factor_pow) (new_res_2, p_ui, ctx); + + TEMPLATE(T, poly_factor_concat) (res, new_res_2, ctx); + TEMPLATE(T, poly_clear) (g_p, ctx); + TEMPLATE(T, poly_factor_clear) (new_res_2, ctx); + } + } + + fmpz_clear(p); + TEMPLATE(T, clear) (x, ctx); + TEMPLATE(T, poly_clear) (g_1, ctx); + TEMPLATE(T, poly_clear) (f_d, ctx); + TEMPLATE(T, poly_clear) (g, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_factor_templates/fit_length.c b/external/flint-2.4.3/fq_poly_factor_templates/fit_length.c new file mode 100644 index 0000000..3e305fd --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor_templates/fit_length.c @@ -0,0 +1,48 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 Lina Kulakova + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +TEMPLATE(T, poly_factor_fit_length) (TEMPLATE(T, poly_factor_t) fac, slong len, + const TEMPLATE(T, ctx_t) ctx) +{ + if (len > fac->alloc) + { + /* At least double number of allocated coeffs */ + if (len < 2 * fac->alloc) + len = 2 * fac->alloc; + TEMPLATE(T, poly_factor_realloc) (fac, len, ctx); + } +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_factor_templates/init.c b/external/flint-2.4.3/fq_poly_factor_templates/init.c new file mode 100644 index 0000000..d5e9d11 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor_templates/init.c @@ -0,0 +1,52 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +TEMPLATE(T, poly_factor_init) (TEMPLATE(T, poly_factor_t) fac, + const TEMPLATE(T, ctx_t) ctx) +{ + slong i; + + fac->alloc = 5; + fac->num = 0; + fac->poly = flint_malloc(sizeof(TEMPLATE(T, poly_struct)) * 5); + fac->exp = flint_malloc(sizeof(slong) * 5); + + for (i = 0; i < fac->alloc; i++) + TEMPLATE(T, poly_init) (fac->poly + i, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_factor_templates/insert.c b/external/flint-2.4.3/fq_poly_factor_templates/insert.c new file mode 100644 index 0000000..4582171 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor_templates/insert.c @@ -0,0 +1,76 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +TEMPLATE(T, poly_factor_insert) (TEMPLATE(T, poly_factor_t) fac, + const TEMPLATE(T, poly_t) poly, slong exp, + const TEMPLATE(T, ctx_t) ctx) +{ + slong i; + + if (poly->length <= 1) + return; + + for (i = 0; i < fac->num; i++) + { + if (TEMPLATE(T, poly_equal) (poly, fac->poly + i, ctx)) + { + fac->exp[i] += exp; + return; + } + } + + if (fac->alloc == fac->num) + { + slong new_size = 2 * fac->alloc; + + fac->poly = + flint_realloc(fac->poly, + sizeof(TEMPLATE(T, poly_struct)) * new_size); + fac->exp = flint_realloc(fac->exp, sizeof(slong) * new_size); + + for (i = fac->alloc; i < new_size; i++) + TEMPLATE(T, poly_init) (fac->poly + i, ctx); + + fac->alloc = new_size; + } + + TEMPLATE(T, poly_set) (fac->poly + fac->num, poly, ctx); + fac->exp[fac->num] = exp; + fac->num++; +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_factor_templates/is_irreducible.c b/external/flint-2.4.3/fq_poly_factor_templates/is_irreducible.c new file mode 100644 index 0000000..2e02c16 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor_templates/is_irreducible.c @@ -0,0 +1,49 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +int +TEMPLATE(T, poly_is_irreducible) (const TEMPLATE(T, poly_t) f, + const TEMPLATE(T, ctx_t) ctx) +{ + if (TEMPLATE(T, poly_length) (f, ctx) > 2) + { + return TEMPLATE(T, poly_is_irreducible_ddf) (f, ctx); + } + + return 1; +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_factor_templates/is_irreducible_ben_or.c b/external/flint-2.4.3/fq_poly_factor_templates/is_irreducible_ben_or.c new file mode 100644 index 0000000..9d7ee3a --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor_templates/is_irreducible_ben_or.c @@ -0,0 +1,110 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include "math.h" + +int +TEMPLATE(T, poly_is_irreducible_ben_or) (const TEMPLATE(T, poly_t) f, + const TEMPLATE(T, ctx_t) ctx) +{ + int result; + slong i, n; + fmpz_t q; + TEMPLATE(T, poly_t) g, x, xq, xqimx; + TEMPLATE(T, poly_t) v, vinv; + + n = TEMPLATE(T, poly_degree) (f, ctx); + + if (n < 2) + return 1; + + if (!TEMPLATE(T, poly_is_squarefree) (f, ctx)) + return 0; + + TEMPLATE(T, poly_init) (v, ctx); + TEMPLATE(T, poly_init) (vinv, ctx); + TEMPLATE(T, poly_make_monic) (v, f, ctx); + TEMPLATE(T, poly_reverse) (vinv, v, v->length, ctx); + TEMPLATE(T, poly_inv_series_newton) (vinv, vinv, v->length, ctx); + + TEMPLATE(T, poly_init) (x, ctx); + TEMPLATE(T, poly_init) (xq, ctx); + TEMPLATE(T, poly_init) (xqimx, ctx); + + /* Compute xq = x^q mod f */ + fmpz_init(q); + fmpz_pow_ui(q, TEMPLATE(T, ctx_prime) (ctx), + TEMPLATE(T, ctx_degree) (ctx)); + TEMPLATE(T, poly_gen) (x, ctx); + TEMPLATE(T, poly_powmod_fmpz_sliding_preinv) (xq, x, q, 0, v, vinv, ctx); + TEMPLATE(T, poly_set) (xqimx, xq, ctx); + + result = 1; + TEMPLATE(T, poly_init) (g, ctx); + for (i = 1; i <= n / 2; i++) + { + TEMPLATE(T, poly_sub) (xqimx, xqimx, x, ctx); + TEMPLATE(T, poly_gcd) (g, f, xqimx, ctx); + if (!TEMPLATE(T, poly_is_one) (g, ctx)) + { + result = 0; + break; + } + else if (i == n / 2) + { + /* We don't need to compute the last step */ + break; + } + + TEMPLATE(T, poly_add) (xqimx, xqimx, x, ctx); + + if (TEMPLATE(CAP_T, POLY_ITERATED_FROBENIUS_CUTOFF) (ctx, v->length)) + { + TEMPLATE(T, poly_powmod_fmpz_sliding_preinv) (xqimx, xqimx, q, 0, + v, vinv, ctx); + } + else + { + TEMPLATE(T, poly_compose_mod_preinv) (xqimx, xqimx, xq, v, vinv, + ctx); + } + } + + TEMPLATE(T, poly_clear) (xq, ctx); + TEMPLATE(T, poly_clear) (xqimx, ctx); + TEMPLATE(T, poly_clear) (v, ctx); + TEMPLATE(T, poly_clear) (vinv, ctx); + fmpz_clear(q); + + return result; +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_factor_templates/is_irreducible_ddf.c b/external/flint-2.4.3/fq_poly_factor_templates/is_irreducible_ddf.c new file mode 100644 index 0000000..8cdb7e6 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor_templates/is_irreducible_ddf.c @@ -0,0 +1,82 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Martin Lee + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include "math.h" +int +TEMPLATE(T, poly_is_irreducible_ddf) (const TEMPLATE(T, poly_t) f, + const TEMPLATE(T, ctx_t) ctx) +{ + slong i, n; + slong *degs; + TEMPLATE(T, poly_factor_t) dist_deg; + + n = TEMPLATE(T, poly_degree) (f, ctx); + + if (n < 2) + return 1; + + if (!TEMPLATE(T, poly_is_squarefree) (f, ctx)) + return 0; + + if (!(degs = (slong *) flint_malloc(n * sizeof(slong)))) + { + TEMPLATE_PRINTF("Exception (%s_poly_is_irreducible_ddf): \n", T); + flint_printf("Not enough memory.\n"); + abort(); + } + + TEMPLATE(T, poly_factor_init) (dist_deg, ctx); + TEMPLATE(T, poly_factor_distinct_deg) (dist_deg, f, °s, ctx); + for (i = 0; i < dist_deg->num; i++) + { + if (degs[i] == n) + { + flint_free(degs); + TEMPLATE(T, poly_factor_clear) (dist_deg, ctx); + return 1; + } + if (degs[i] > 0) + { + flint_free(degs); + TEMPLATE(T, poly_factor_clear) (dist_deg, ctx); + return 0; + } + } + + flint_free(degs); + TEMPLATE(T, poly_factor_clear) (dist_deg, ctx); + + return 1; +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_factor_templates/is_squarefree.c b/external/flint-2.4.3/fq_poly_factor_templates/is_squarefree.c new file mode 100644 index 0000000..e761fb0 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor_templates/is_squarefree.c @@ -0,0 +1,75 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include "ulong_extras.h" +int +_TEMPLATE(T, poly_is_squarefree) (const TEMPLATE(T, struct) * f, slong len, + const TEMPLATE(T, ctx_t) ctx) +{ + TEMPLATE(T, struct) * fd, *g; + TEMPLATE(T, t) invfd; + slong dlen; + int res; + + if (len <= 2) + return len != 0; + + fd = _TEMPLATE(T, vec_init) (2 * (len - 1), ctx); + g = fd + len - 1; + + _TEMPLATE(T, poly_derivative) (fd, f, len, ctx); + dlen = len - 1; + TEMPLATE(CAP_T, VEC_NORM) (fd, dlen, ctx); + + if (dlen) + { + TEMPLATE(T, init) (invfd, ctx); + TEMPLATE(T, inv) (invfd, fd + (dlen - 1), ctx); + res = (_TEMPLATE(T, poly_gcd) (g, f, len, fd, dlen, invfd, ctx) == 1); + TEMPLATE(T, clear) (invfd, ctx); + } + else + res = 0; /* gcd(f, 0) = f, and len(f) > 2 */ + + _TEMPLATE(T, vec_clear) (fd, 2 * (len - 1), ctx); + return res; +} + +int +TEMPLATE(T, poly_is_squarefree) (const TEMPLATE(T, poly_t) f, + const TEMPLATE(T, ctx_t) ctx) +{ + return _TEMPLATE(T, poly_is_squarefree) (f->coeffs, f->length, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_factor_templates/iterated_frobenius_preinv.c b/external/flint-2.4.3/fq_poly_factor_templates/iterated_frobenius_preinv.c new file mode 100644 index 0000000..1b3fb9b --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor_templates/iterated_frobenius_preinv.c @@ -0,0 +1,74 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +TEMPLATE(T, poly_iterated_frobenius_preinv) (TEMPLATE(T, poly_t) * rop, + slong n, + const TEMPLATE(T, poly_t) v, + const TEMPLATE(T, poly_t) vinv, + const TEMPLATE(T, ctx_t) ctx) +{ + slong i; + fmpz_t q; + TEMPLATE(T, mat_t) HH; + + fmpz_init(q); + + TEMPLATE(T, ctx_order) (q, ctx); + TEMPLATE(T, poly_gen) (rop[0], ctx); + + if (TEMPLATE(CAP_T, POLY_ITERATED_FROBENIUS_CUTOFF) (ctx, v->length)) + { + TEMPLATE(T, mat_init) (HH, n_sqrt(v->length - 1) + 1, v->length - 1, + ctx); + TEMPLATE(T, poly_powmod_fmpz_sliding_preinv) (rop[1], rop[0], q, 0, v, + vinv, ctx); + TEMPLATE(T, poly_precompute_matrix) (HH, rop[1], v, vinv, ctx); + for (i = 2; i < n; i++) + { + TEMPLATE(T, poly_compose_mod_brent_kung_precomp_preinv) + (rop[i], rop[i - 1], HH, v, vinv, ctx); + + } + TEMPLATE(T, mat_clear) (HH, ctx); + } + else + { + for (i = 1; i < n; i++) + TEMPLATE(T, poly_powmod_fmpz_sliding_preinv) (rop[i], rop[i - 1], + q, 0, v, vinv, ctx); + + } + + fmpz_clear(q); + +} + +#endif diff --git a/external/flint-2.4.3/fq_poly_factor_templates/pow.c b/external/flint-2.4.3/fq_poly_factor_templates/pow.c new file mode 100644 index 0000000..d56172c --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor_templates/pow.c @@ -0,0 +1,47 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +TEMPLATE(T, poly_factor_pow) (TEMPLATE(T, poly_factor_t) fac, slong exp, + const TEMPLATE(T, ctx_t) ctx) +{ + slong i; + + for (i = 0; i < fac->num; i++) + fac->exp[i] *= exp; +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_factor_templates/print.c b/external/flint-2.4.3/fq_poly_factor_templates/print.c new file mode 100644 index 0000000..92111ba --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor_templates/print.c @@ -0,0 +1,51 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +void +TEMPLATE(T, poly_factor_print) (const TEMPLATE(T, poly_factor_t) fac, + const TEMPLATE(T, ctx_t) ctx) +{ + slong i; + + for (i = 0; i < fac->num; i++) + { + TEMPLATE(T, poly_print) (fac->poly + i, ctx); + flint_printf(" ^ %wd\n", fac->exp[i]); + } +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_factor_templates/print_pretty.c b/external/flint-2.4.3/fq_poly_factor_templates/print_pretty.c new file mode 100644 index 0000000..9ff5fe7 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor_templates/print_pretty.c @@ -0,0 +1,47 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +void +TEMPLATE(T, poly_factor_print_pretty) (const TEMPLATE(T, poly_factor_t) fac, + const char *var, + const TEMPLATE(T, ctx_t) ctx) +{ + slong i; + + for (i = 0; i < fac->num; i++) + { + TEMPLATE(T, poly_print_pretty) (fac->poly + i, var, ctx); + flint_printf(" ^ %wd\n", fac->exp[i]); + } +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_factor_templates/realloc.c b/external/flint-2.4.3/fq_poly_factor_templates/realloc.c new file mode 100644 index 0000000..39608b2 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor_templates/realloc.c @@ -0,0 +1,91 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include "flint.h" +void +TEMPLATE(T, poly_factor_realloc) (TEMPLATE(T, poly_factor_t) fac, slong alloc, + const TEMPLATE(T, ctx_t) ctx) +{ + if (alloc == 0) /* Clear up, reinitialise */ + { + TEMPLATE(T, poly_factor_clear) (fac, ctx); + TEMPLATE(T, poly_factor_init) (fac, ctx); + } + else if (fac->alloc) /* Realloc */ + { + if (fac->alloc > alloc) + { + slong i; + + for (i = alloc; i < fac->num; i++) + TEMPLATE(T, poly_clear) (fac->poly + i, ctx); + + fac->poly = + flint_realloc(fac->poly, + alloc * sizeof(TEMPLATE(T, poly_struct))); + fac->exp = flint_realloc(fac->exp, alloc * sizeof(slong)); + fac->alloc = alloc; + } + else if (fac->alloc < alloc) + { + slong i; + + fac->poly = + flint_realloc(fac->poly, + alloc * sizeof(TEMPLATE(T, poly_struct))); + fac->exp = flint_realloc(fac->exp, alloc * sizeof(slong)); + + for (i = fac->alloc; i < alloc; i++) + { + TEMPLATE(T, poly_init) (fac->poly + i, ctx); + fac->exp[i] = WORD(0); + } + fac->alloc = alloc; + } + } + else /* Nothing allocated already so do it now */ + { + slong i; + + fac->poly = flint_malloc(alloc * sizeof(TEMPLATE(T, poly_struct))); + fac->exp = flint_calloc(alloc, sizeof(slong)); + + for (i = 0; i < alloc; i++) + TEMPLATE(T, poly_init) (fac->poly + i, ctx); + fac->num = 0; + fac->alloc = alloc; + } +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_factor_templates/set.c b/external/flint-2.4.3/fq_poly_factor_templates/set.c new file mode 100644 index 0000000..56482a7 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor_templates/set.c @@ -0,0 +1,66 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +TEMPLATE(T, poly_factor_set) (TEMPLATE(T, poly_factor_t) res, + const TEMPLATE(T, poly_factor_t) fac, + const TEMPLATE(T, ctx_t) ctx) +{ + if (res != fac) + { + if (fac->num == 0) + { + TEMPLATE(T, poly_factor_clear) (res, ctx); + TEMPLATE(T, poly_factor_init) (res, ctx); + } + else + { + slong i; + + TEMPLATE(T, poly_factor_fit_length) (res, fac->num, ctx); + for (i = 0; i < fac->num; i++) + { + TEMPLATE(T, poly_set) (res->poly + i, fac->poly + i, ctx); + res->exp[i] = fac->exp[i]; + } + for (; i < res->num; i++) + { + TEMPLATE(T, poly_zero) (res->poly + i, ctx); + res->exp[i] = 0; + } + res->num = fac->num; + } + } +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_factor_templates/test/t-factor.c b/external/flint-2.4.3/fq_poly_factor_templates/test/t-factor.c new file mode 100644 index 0000000..adc092f --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor_templates/test/t-factor.c @@ -0,0 +1,278 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +int +main(void) +{ + int iter; + FLINT_TEST_INIT(state); + + flint_printf("factor...."); + fflush(stdout); + + /* Default algorithm */ + for (iter = 0; iter < flint_test_multiplier(); iter++) + { + int result = 1; + TEMPLATE(T, poly_t) pol1, poly, quot, rem, product; + TEMPLATE(T, poly_factor_t) res; + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, t) lead; + slong length, num, i, j; + ulong exp[5], prod1; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (pol1, ctx); + TEMPLATE(T, poly_init) (poly, ctx); + TEMPLATE(T, poly_init) (quot, ctx); + TEMPLATE(T, poly_init) (rem, ctx); + + TEMPLATE(T, poly_zero) (pol1, ctx); + TEMPLATE(T, poly_one) (pol1, ctx); + + length = n_randint(state, 4) + 2; + TEMPLATE(T, poly_randtest_irreducible) (poly, state, length, ctx); + + exp[0] = n_randint(state, 3) + 1; + prod1 = exp[0]; + for (i = 0; i < exp[0]; i++) + TEMPLATE(T, poly_mul) (pol1, pol1, poly, ctx); + + num = n_randint(state, 3) + 1; + for (i = 1; i < num; i++) + { + do + { + length = n_randint(state, 3) + 2; + TEMPLATE(T, poly_randtest_irreducible) (poly, state, length, + ctx); + TEMPLATE(T, poly_divrem) (quot, rem, pol1, poly, ctx); + } + while ((poly->length < 2) || (rem->length == 0)); + + exp[i] = n_randint(state, 3) + 1; + prod1 *= exp[i]; + + for (j = 0; j < exp[i]; j++) + TEMPLATE(T, poly_mul) (pol1, pol1, poly, ctx); + } + + TEMPLATE(T, poly_factor_init) (res, ctx); + + TEMPLATE(T, init) (lead, ctx); + + switch (n_randint(state, 4)) + { + case 0: + TEMPLATE(T, poly_factor) (res, lead, pol1, ctx); + break; + case 1: + TEMPLATE(T, poly_factor_with_berlekamp) (res, lead, pol1, ctx); + break; + case 2: + if (fmpz_is_even(TEMPLATE(T, ctx_prime) (ctx))) + TEMPLATE(T, poly_factor) (res, lead, pol1, ctx); + else + TEMPLATE(T, poly_factor_with_cantor_zassenhaus) (res, lead, + pol1, + ctx); + break; + case 3: + TEMPLATE(T, poly_factor_with_kaltofen_shoup) (res, lead, pol1, + ctx); + break; + + } + fflush(stdout); + + result &= (res->num == num); + if (!result) + { + flint_printf("Error: number of factors incorrect, %wd, %wd\n", + res->num, num); + abort(); + } + + TEMPLATE(T, poly_init) (product, ctx); + TEMPLATE(T, poly_one) (product, ctx); + for (i = 0; i < res->num; i++) + for (j = 0; j < res->exp[i]; j++) + TEMPLATE(T, poly_mul) (product, product, res->poly + i, ctx); + TEMPLATE(T, TEMPLATE(poly_scalar_mul, T)) (product, product, lead, + ctx); + result &= TEMPLATE(T, poly_equal) (pol1, product, ctx); + if (!result) + { + flint_printf + ("Error: product of factors does not equal original polynomial\n"); + TEMPLATE(T, poly_print_pretty) (pol1, "x", ctx); + flint_printf("\n"); + TEMPLATE(T, poly_print_pretty) (product, "x", ctx); + flint_printf("\n"); + abort(); + } + TEMPLATE(T, poly_clear) (product, ctx); + + TEMPLATE(T, poly_clear) (quot, ctx); + TEMPLATE(T, poly_clear) (rem, ctx); + TEMPLATE(T, poly_clear) (pol1, ctx); + TEMPLATE(T, poly_clear) (poly, ctx); + TEMPLATE(T, poly_factor_clear) (res, ctx); + TEMPLATE(T, clear) (lead, ctx); + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Test deflation trick */ + for (iter = 0; iter < flint_test_multiplier(); iter++) + { + TEMPLATE(T, poly_t) pol1, poly, quot, rem; + TEMPLATE(T, poly_factor_t) res, res2; + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, t) lead; + slong length, num, i, j; + slong exp[5], prod1; + ulong inflation; + int found; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (pol1, ctx); + TEMPLATE(T, poly_init) (poly, ctx); + TEMPLATE(T, poly_init) (quot, ctx); + TEMPLATE(T, poly_init) (rem, ctx); + + TEMPLATE(T, poly_zero) (pol1, ctx); + TEMPLATE(T, poly_one) (pol1, ctx); + + inflation = n_randint(state, 7) + 1; + + length = n_randint(state, 4) + 2; + TEMPLATE(T, poly_randtest_irreducible) (poly, state, length, ctx); + TEMPLATE(T, poly_inflate) (poly, poly, inflation, ctx); + + exp[0] = n_randint(state, 6) + 1; + prod1 = exp[0]; + for (i = 0; i < exp[0]; i++) + TEMPLATE(T, poly_mul) (pol1, pol1, poly, ctx); + + num = n_randint(state, 5) + 1; + for (i = 1; i < num; i++) + { + do + { + length = n_randint(state, 6) + 2; + TEMPLATE(T, poly_randtest_irreducible) (poly, state, length, + ctx); + TEMPLATE(T, poly_divrem) (quot, rem, pol1, poly, ctx); + } + while ((poly->length < 2) || (rem->length == 0)); + exp[i] = n_randint(state, 6) + 1; + prod1 *= exp[i]; + TEMPLATE(T, poly_inflate) (poly, poly, inflation, ctx); + + for (j = 0; j < exp[i]; j++) + TEMPLATE(T, poly_mul) (pol1, pol1, poly, ctx); + } + + TEMPLATE(T, poly_factor_init) (res, ctx); + TEMPLATE(T, poly_factor_init) (res2, ctx); + + TEMPLATE(T, init) (lead, ctx); + + switch (n_randint(state, 4)) + { + case 0: + TEMPLATE(T, poly_factor) (res, lead, pol1, ctx); + break; + case 1: + TEMPLATE(T, poly_factor_with_berlekamp) (res, lead, pol1, ctx); + break; + case 2: + TEMPLATE(T, poly_factor_with_cantor_zassenhaus) (res, lead, + pol1, ctx); + break; + case 3: + TEMPLATE(T, poly_factor_with_kaltofen_shoup) (res, lead, pol1, + ctx); + break; + } + + TEMPLATE(T, poly_factor_cantor_zassenhaus) (res2, pol1, ctx); + + if (res->num != res2->num) + { + flint_printf("FAIL: different number of factors found\n"); + abort(); + } + + for (i = 0; i < res->num; i++) + { + found = 0; + for (j = 0; j < res2->num; j++) + { + if (TEMPLATE(T, poly_equal) + (res->poly + i, res2->poly + j, ctx) + && res->exp[i] == res2->exp[j]) + { + found = 1; + break; + } + } + + if (!found) + { + flint_printf("FAIL: factor not found\n"); + abort(); + } + } + + TEMPLATE(T, poly_clear) (quot, ctx); + TEMPLATE(T, poly_clear) (rem, ctx); + TEMPLATE(T, poly_clear) (pol1, ctx); + TEMPLATE(T, poly_clear) (poly, ctx); + TEMPLATE(T, poly_factor_clear) (res, ctx); + TEMPLATE(T, poly_factor_clear) (res2, ctx); + + TEMPLATE(T, clear) (lead, ctx); + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_factor_templates/test/t-factor_berlekamp.c b/external/flint-2.4.3/fq_poly_factor_templates/test/t-factor_berlekamp.c new file mode 100644 index 0000000..3369a66 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor_templates/test/t-factor_berlekamp.c @@ -0,0 +1,153 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +int +main(void) +{ + int iter; + FLINT_TEST_INIT(state); + + flint_printf("factor_berlekamp...."); + fflush(stdout); + + for (iter = 0; iter < 10 * flint_test_multiplier(); iter++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) poly1, poly, q, r, product; + TEMPLATE(T, poly_factor_t) res; + slong i, j, length, num; + slong exp[5]; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (poly1, ctx); + TEMPLATE(T, poly_init) (poly, ctx); + TEMPLATE(T, poly_init) (q, ctx); + TEMPLATE(T, poly_init) (r, ctx); + + TEMPLATE(T, poly_zero) (poly1, ctx); + TEMPLATE(T, poly_one) (poly1, ctx); + + length = n_randint(state, 4) + 2; + do + { + TEMPLATE(T, poly_randtest) (poly, state, length, ctx); + if (poly->length) + TEMPLATE(T, poly_make_monic) (poly, poly, ctx); + } + while ((poly->length < 2) + || (!TEMPLATE(T, poly_is_irreducible) (poly, ctx))); + + exp[0] = n_randint(state, 5) + 1; + for (i = 0; i < exp[0]; i++) + TEMPLATE(T, poly_mul) (poly1, poly1, poly, ctx); + + num = n_randint(state, 5) + 1; + + for (i = 1; i < num; i++) + { + do + { + length = n_randint(state, 5) + 2; + TEMPLATE(T, poly_randtest) (poly, state, length, ctx); + if (poly->length) + { + TEMPLATE(T, poly_make_monic) (poly, poly, ctx); + TEMPLATE(T, poly_divrem) (q, r, poly1, poly, ctx); + } + } + while ((poly->length < 2) + || (!TEMPLATE(T, poly_is_irreducible) (poly, ctx)) + || (r->length == 0)); + + exp[i] = n_randint(state, 5) + 1; + for (j = 0; j < exp[i]; j++) + TEMPLATE(T, poly_mul) (poly1, poly1, poly, ctx); + } + + TEMPLATE(T, poly_factor_init) (res, ctx); + TEMPLATE(T, poly_factor_berlekamp) (res, poly1, ctx); + + if (res->num != num) + { + flint_printf("Error: number of factors incorrect: %wd != %wd\n", + res->num, num); + TEMPLATE(T, ctx_print) (ctx); + flint_printf("\n"); + TEMPLATE(T, poly_print_pretty) (poly1, "x", ctx); + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_init) (product, ctx); + TEMPLATE(T, poly_one) (product, ctx); + for (i = 0; i < res->num; i++) + for (j = 0; j < res->exp[i]; j++) + TEMPLATE(T, poly_mul) (product, product, res->poly + i, ctx); + + TEMPLATE3(T, poly_scalar_mul, T) (product, product, + poly1->coeffs + poly1->length - 1, + ctx); + + if (!TEMPLATE(T, poly_equal) (poly1, product, ctx)) + { + flint_printf + ("Error: product of factors does not equal to the original polynomial\n"); + flint_printf("poly:\n"); + TEMPLATE(T, poly_print) (poly1, ctx); + flint_printf("\n"); + flint_printf("product:\n"); + TEMPLATE(T, poly_print) (product, ctx); + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (product, ctx); + TEMPLATE(T, poly_clear) (q, ctx); + TEMPLATE(T, poly_clear) (r, ctx); + TEMPLATE(T, poly_clear) (poly1, ctx); + TEMPLATE(T, poly_clear) (poly, ctx); + TEMPLATE(T, poly_factor_clear) (res, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_factor_templates/test/t-factor_cantor_zassenhaus.c b/external/flint-2.4.3/fq_poly_factor_templates/test/t-factor_cantor_zassenhaus.c new file mode 100644 index 0000000..42e4e77 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor_templates/test/t-factor_cantor_zassenhaus.c @@ -0,0 +1,152 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include "ulong_extras.h" +int +main(void) +{ + int iter; + FLINT_TEST_INIT(state); + + flint_printf("factor_cantor_zassenhaus...."); + fflush(stdout); + + for (iter = 0; iter < 2 * flint_test_multiplier(); iter++) + { + TEMPLATE(T, poly_t) poly1, poly, q, r, product; + TEMPLATE(T, poly_factor_t) res; + TEMPLATE(T, ctx_t) ctx; + + slong i, j, length, num; + slong exp[5]; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (poly1, ctx); + TEMPLATE(T, poly_init) (poly, ctx); + TEMPLATE(T, poly_init) (q, ctx); + TEMPLATE(T, poly_init) (r, ctx); + + TEMPLATE(T, poly_zero) (poly1, ctx); + TEMPLATE(T, poly_one) (poly1, ctx); + + length = n_randint(state, 4) + 2; + do + { + TEMPLATE(T, poly_randtest) (poly, state, length, ctx); + if (poly->length) + TEMPLATE(T, poly_make_monic) (poly, poly, ctx); + } + while ((poly->length != length) + || (!TEMPLATE(T, poly_is_irreducible) (poly, ctx))); + + exp[0] = n_randint(state, 5) + 1; + for (i = 0; i < exp[0]; i++) + TEMPLATE(T, poly_mul) (poly1, poly1, poly, ctx); + + num = n_randint(state, 5) + 1; + + for (i = 1; i < num; i++) + { + do + { + length = n_randint(state, 4) + 2; + TEMPLATE(T, poly_randtest) (poly, state, length, ctx); + if (poly->length) + { + TEMPLATE(T, poly_make_monic) (poly, poly, ctx); + TEMPLATE(T, poly_divrem) (q, r, poly1, poly, ctx); + } + } + while ((poly->length != length) + || (!TEMPLATE(T, poly_is_irreducible) (poly, ctx)) + || (r->length == 0)); + + exp[i] = n_randint(state, 5) + 1; + for (j = 0; j < exp[i]; j++) + TEMPLATE(T, poly_mul) (poly1, poly1, poly, ctx); + } + + TEMPLATE(T, poly_factor_init) (res, ctx); + TEMPLATE(T, poly_factor_cantor_zassenhaus) (res, poly1, ctx); + + if (res->num != num) + { + flint_printf("Error: number of factors incorrect: %wd != %wd\n", + res->num, num); + abort(); + } + + TEMPLATE(T, poly_init) (product, ctx); + TEMPLATE(T, poly_one) (product, ctx); + for (i = 0; i < res->num; i++) + for (j = 0; j < res->exp[i]; j++) + TEMPLATE(T, poly_mul) (product, product, res->poly + i, ctx); + + TEMPLATE(T, TEMPLATE(poly_scalar_mul, T)) (product, product, + poly1->coeffs + + (poly1->length - 1), ctx); + + if (!TEMPLATE(T, poly_equal) (poly1, product, ctx)) + { + flint_printf + ("Error: product of factors does not equal to the original polynomial\n"); + flint_printf("poly:\n"); + TEMPLATE(T, poly_print) (poly1, ctx); + flint_printf("\n"); + flint_printf("product:\n"); + TEMPLATE(T, poly_print) (product, ctx); + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (product, ctx); + TEMPLATE(T, poly_clear) (q, ctx); + TEMPLATE(T, poly_clear) (r, ctx); + TEMPLATE(T, poly_clear) (poly1, ctx); + TEMPLATE(T, poly_clear) (poly, ctx); + TEMPLATE(T, poly_factor_clear) (res, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_factor_templates/test/t-factor_distinct_deg.c b/external/flint-2.4.3/fq_poly_factor_templates/test/t-factor_distinct_deg.c new file mode 100644 index 0000000..18358f7 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor_templates/test/t-factor_distinct_deg.c @@ -0,0 +1,145 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include "ulong_extras.h" +int +main(void) +{ + int iter; + FLINT_TEST_INIT(state); + + flint_printf("factor_distinct_deg...."); + fflush(stdout); + + for (iter = 0; iter < 200; iter++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) poly1, poly, q, r, product; + TEMPLATE(T, poly_factor_t) res; + slong i, length, num; + slong *degs; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (poly1, ctx); + TEMPLATE(T, poly_init) (poly, ctx); + TEMPLATE(T, poly_init) (q, ctx); + TEMPLATE(T, poly_init) (r, ctx); + + TEMPLATE(T, poly_zero) (poly1, ctx); + TEMPLATE(T, poly_one) (poly1, ctx); + + length = n_randint(state, 7) + 2; + do + { + TEMPLATE(T, poly_randtest) (poly, state, length, ctx); + if (poly->length) + TEMPLATE(T, poly_make_monic) (poly, poly, ctx); + } + while ((poly->length < 2) + || (!TEMPLATE(T, poly_is_irreducible) (poly, ctx))); + + TEMPLATE(T, poly_mul) (poly1, poly1, poly, ctx); + + num = n_randint(state, 5) + 1; + + for (i = 1; i < num; i++) + { + do + { + length = n_randint(state, 7) + 2; + TEMPLATE(T, poly_randtest) (poly, state, length, ctx); + if (poly->length) + { + TEMPLATE(T, poly_make_monic) (poly, poly, ctx); + TEMPLATE(T, poly_divrem) (q, r, poly1, poly, ctx); + } + } + while ((poly->length < 2) + || (!TEMPLATE(T, poly_is_irreducible) (poly, ctx)) + || (r->length == 0)); + + TEMPLATE(T, poly_mul) (poly1, poly1, poly, ctx); + } + + if (!(degs = flint_malloc((poly1->length - 1) * sizeof(slong)))) + { + flint_printf("Fatal error: not enough memory."); + abort(); + } + TEMPLATE(T, poly_factor_init) (res, ctx); + TEMPLATE(T, poly_factor_distinct_deg) (res, poly1, °s, ctx); + + TEMPLATE(T, poly_init) (product, ctx); + TEMPLATE(T, poly_one) (product, ctx); + for (i = 0; i < res->num; i++) + TEMPLATE(T, poly_mul) (product, product, res->poly + i, ctx); + + TEMPLATE(T, TEMPLATE(poly_scalar_mul, T)) (product, product, + poly1->coeffs + + (poly1->length - 1), ctx); + + if (!TEMPLATE(T, poly_equal) (poly1, product, ctx)) + { + flint_printf + ("Error: product of factors does not equal to the original polynomial\n"); + flint_printf("poly:\n"); + TEMPLATE(T, poly_print) (poly1, ctx); + flint_printf("\n"); + flint_printf("product:\n"); + TEMPLATE(T, poly_print) (product, ctx); + flint_printf("\n"); + abort(); + } + + flint_free(degs); + TEMPLATE(T, poly_clear) (product, ctx); + TEMPLATE(T, poly_clear) (q, ctx); + TEMPLATE(T, poly_clear) (r, ctx); + TEMPLATE(T, poly_clear) (poly1, ctx); + TEMPLATE(T, poly_clear) (poly, ctx); + TEMPLATE(T, poly_factor_clear) (res, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_factor_templates/test/t-factor_equal_deg_prob.c b/external/flint-2.4.3/fq_poly_factor_templates/test/t-factor_equal_deg_prob.c new file mode 100644 index 0000000..c6de719 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor_templates/test/t-factor_equal_deg_prob.c @@ -0,0 +1,117 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include "ulong_extras.h" +int +main(void) +{ + int iter; + FLINT_TEST_INIT(state); + + flint_printf("factor_equal_deg_prob...."); + fflush(stdout); + + for (iter = 0; iter < 5 * flint_test_multiplier(); iter++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) poly1, poly2, q, r; + slong length; + int i, num; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (q, ctx); + TEMPLATE(T, poly_init) (r, ctx); + TEMPLATE(T, poly_init) (poly1, ctx); + TEMPLATE(T, poly_init) (poly2, ctx); + + length = n_randint(state, 10) + 2; + do + { + TEMPLATE(T, poly_randtest) (poly1, state, length, ctx); + if (poly1->length) + TEMPLATE(T, poly_make_monic) (poly1, poly1, ctx); + } + while ((poly1->length != length) + || (!TEMPLATE(T, poly_is_irreducible) (poly1, ctx))); + + num = n_randint(state, 5) + 1; + + for (i = 0; i < num; i++) + { + do + { + TEMPLATE(T, poly_randtest) (poly2, state, length, ctx); + if (poly2->length) + TEMPLATE(T, poly_make_monic) (poly2, poly2, ctx); + } + while ((poly2->length != length) + || (!TEMPLATE(T, poly_is_irreducible) (poly2, ctx))); + + TEMPLATE(T, poly_mul) (poly1, poly1, poly2, ctx); + } + + while (!TEMPLATE(T, poly_factor_equal_deg_prob) + (poly2, state, poly1, length - 1, ctx)) + { + }; + + TEMPLATE(T, poly_divrem) (q, r, poly1, poly2, ctx); + if (!TEMPLATE(T, poly_is_zero) (r, ctx)) + { + flint_printf("FAIL:\n"); + flint_printf + ("Error: factor does not divide original polynomial\n"); + flint_printf("factor:\n"); + TEMPLATE(T, poly_print) (poly2, ctx); + flint_printf("\n\n"); + flint_printf("polynomial:\n"); + TEMPLATE(T, poly_print) (poly1, ctx); + flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (q, ctx); + TEMPLATE(T, poly_clear) (r, ctx); + TEMPLATE(T, poly_clear) (poly1, ctx); + TEMPLATE(T, poly_clear) (poly2, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_factor_templates/test/t-factor_kaltofen_shoup.c b/external/flint-2.4.3/fq_poly_factor_templates/test/t-factor_kaltofen_shoup.c new file mode 100644 index 0000000..c027cca --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor_templates/test/t-factor_kaltofen_shoup.c @@ -0,0 +1,160 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include "ulong_extras.h" +int +main(void) +{ + int iter; + FLINT_TEST_INIT(state); + + flint_printf("factor_kaltofen_shoup...."); + fflush(stdout); + + for (iter = 0; iter < 10 * flint_test_multiplier(); iter++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) poly1, poly, q, r, product; + TEMPLATE(T, poly_factor_t) res; + + slong i, j, length, num; + slong exp[5]; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (poly1, ctx); + TEMPLATE(T, poly_init) (poly, ctx); + TEMPLATE(T, poly_init) (q, ctx); + TEMPLATE(T, poly_init) (r, ctx); + + TEMPLATE(T, poly_one) (poly1, ctx); + + length = n_randint(state, 7) + 2; + do + { + TEMPLATE(T, poly_randtest) (poly, state, length, ctx); + if (poly->length) + TEMPLATE(T, poly_make_monic) (poly, poly, ctx); + } + while ((poly->length != length) + || (!TEMPLATE(T, poly_is_irreducible) (poly, ctx))); + + exp[0] = n_randint(state, 5) + 1; + for (i = 0; i < exp[0]; i++) + { + TEMPLATE(T, poly_mul) (poly1, poly1, poly, ctx); + } + + num = n_randint(state, 5) + 1; + + for (i = 1; i < num; i++) + { + do + { + length = n_randint(state, 5) + 2; + TEMPLATE(T, poly_randtest) (poly, state, length, ctx); + if (poly->length) + { + TEMPLATE(T, poly_make_monic) (poly, poly, ctx); + TEMPLATE(T, poly_divrem) (q, r, poly1, poly, ctx); + } + } + while ((poly->length != length) + || (!TEMPLATE(T, poly_is_irreducible) (poly, ctx)) + || (r->length == 0)); + + exp[i] = n_randint(state, 5) + 1; + for (j = 0; j < exp[i]; j++) + { + TEMPLATE(T, poly_mul) (poly1, poly1, poly, ctx); + } + } + + TEMPLATE(T, poly_factor_init) (res, ctx); + TEMPLATE(T, poly_factor_kaltofen_shoup) (res, poly1, ctx); + + if (res->num != num) + { + flint_printf("Error: number of factors incorrect: %wd != %wd\n", + res->num, num); + abort(); + } + + TEMPLATE(T, poly_init) (product, ctx); + TEMPLATE(T, poly_one) (product, ctx); + for (i = 0; i < res->num; i++) + { + for (j = 0; j < res->exp[i]; j++) + { + TEMPLATE(T, poly_mul) (product, product, res->poly + i, ctx); + } + } + + TEMPLATE(T, TEMPLATE(poly_scalar_mul, T)) (product, product, + poly1->coeffs + + (poly1->length - 1), ctx); + + if (!TEMPLATE(T, poly_equal) (poly1, product, ctx)) + { + flint_printf + ("Error: product of factors does not equal to the original polynomial\n"); + TEMPLATE(T, ctx_print) (ctx); + flint_printf("\n"); + flint_printf("poly:\n"); + TEMPLATE(T, poly_print_pretty) (poly1, "x", ctx); + flint_printf("\n"); + flint_printf("product:\n"); + TEMPLATE(T, poly_print_pretty) (product, "x", ctx); + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, ctx_clear) (ctx); + TEMPLATE(T, poly_clear) (product, ctx); + TEMPLATE(T, poly_clear) (q, ctx); + TEMPLATE(T, poly_clear) (r, ctx); + TEMPLATE(T, poly_clear) (poly1, ctx); + TEMPLATE(T, poly_clear) (poly, ctx); + TEMPLATE(T, poly_factor_clear) (res, ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_factor_templates/test/t-factor_squarefree.c b/external/flint-2.4.3/fq_poly_factor_templates/test/t-factor_squarefree.c new file mode 100644 index 0000000..87d5bb3 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor_templates/test/t-factor_squarefree.c @@ -0,0 +1,150 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include +#include +#include "flint.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" +int +main(void) +{ + int iter; + FLINT_TEST_INIT(state); + + flint_printf("factor_squarefree...."); + fflush(stdout); + + for (iter = 0; iter < 5 * flint_test_multiplier(); iter++) + { + int result = 1; + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) pol1, poly, quot, rem; + TEMPLATE(T, poly_factor_t) res; + slong exp[5], prod1; + slong length, i, j, num; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (pol1, ctx); + TEMPLATE(T, poly_init) (poly, ctx); + TEMPLATE(T, poly_init) (quot, ctx); + TEMPLATE(T, poly_init) (rem, ctx); + + TEMPLATE(T, poly_one) (pol1, ctx); + + length = n_randint(state, 5) + 2; + + do + { + TEMPLATE(T, poly_randtest) (poly, state, length, ctx); + TEMPLATE(T, poly_make_monic) (poly, poly, ctx); + } + while ((poly->length != length) + || (!TEMPLATE(T, poly_is_irreducible) (poly, ctx))); + exp[0] = n_randprime(state, 5, 0); + + prod1 = exp[0]; + for (i = 0; i < exp[0]; i++) + TEMPLATE(T, poly_mul) (pol1, pol1, poly, ctx); + + num = n_randint(state, 5) + 1; + for (i = 1; i < num; i++) + { + do + { + length = n_randint(state, 7) + 2; + TEMPLATE(T, poly_randtest) (poly, state, length, ctx); + if (poly->length) + { + TEMPLATE(T, poly_make_monic) (poly, poly, ctx); + TEMPLATE(T, poly_divrem) (quot, rem, pol1, poly, ctx); + } + } + while ((!TEMPLATE(T, poly_is_irreducible) (poly, ctx)) || + (poly->length != length) || (rem->length == 0)); + + do + exp[i] = n_randprime(state, 5, 0); + while (prod1 % exp[i] == 0); + + prod1 *= exp[i]; + for (j = 0; j < exp[i]; j++) + TEMPLATE(T, poly_mul) (pol1, pol1, poly, ctx); + } + + TEMPLATE(T, poly_factor_init) (res, ctx); + TEMPLATE(T, poly_factor_squarefree) (res, pol1, ctx); + + result &= (res->num == num); + if (result) + { + ulong prod2 = 1; + for (i = 0; i < num; i++) + prod2 *= res->exp[i]; + result &= (prod1 == prod2); + } + + if (!result) + { + flint_printf("Error: exp don't match. Ctx = "); + TEMPLATE(T, ctx_print) (ctx); + flint_printf("\n"); + for (i = 0; i < res->num; i++) + flint_printf("%wd ", res->exp[i]); + flint_printf("\n"); + for (i = 0; i < num; i++) + flint_printf("%wd ", exp[i]); + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (quot, ctx); + TEMPLATE(T, poly_clear) (rem, ctx); + TEMPLATE(T, poly_clear) (pol1, ctx); + TEMPLATE(T, poly_clear) (poly, ctx); + TEMPLATE(T, poly_factor_clear) (res, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_factor_templates/test/t-is_irreducible.c b/external/flint-2.4.3/fq_poly_factor_templates/test/t-is_irreducible.c new file mode 100644 index 0000000..92d9060 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor_templates/test/t-is_irreducible.c @@ -0,0 +1,108 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include +#include +#include "flint.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" +int +main(void) +{ + int iter; + FLINT_TEST_INIT(state); + + flint_printf("is_irreducible...."); + fflush(stdout); + + for (iter = 0; iter < 5 * flint_test_multiplier(); iter++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) poly1, poly2; + slong length; + int i, num; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (poly1, ctx); + TEMPLATE(T, poly_init) (poly2, ctx); + + length = n_randint(state, 5) + 2; + do + { + TEMPLATE(T, poly_randtest) (poly1, state, length, ctx); + if (!TEMPLATE(T, poly_is_zero) (poly1, ctx)) + TEMPLATE(T, poly_make_monic) (poly1, poly1, ctx); + } + while ((!TEMPLATE(T, poly_is_irreducible) (poly1, ctx)) + || (poly1->length < 2)); + + num = n_randint(state, 5) + 1; + + for (i = 0; i < num; i++) + { + do + { + TEMPLATE(T, poly_randtest) (poly2, state, length, ctx); + if (!TEMPLATE(T, poly_is_zero) (poly2, ctx)) + TEMPLATE(T, poly_make_monic) (poly2, poly2, ctx); + } + while ((!TEMPLATE(T, poly_is_irreducible) (poly2, ctx)) + || (poly2->length < 2)); + + TEMPLATE(T, poly_mul) (poly1, poly1, poly2, ctx); + } + + if (TEMPLATE(T, poly_is_irreducible) (poly1, ctx)) + { + flint_printf + ("Error: reducible polynomial declared irreducible!\n"); + flint_printf("poly:\n"); + TEMPLATE(T, poly_print) (poly1, ctx); + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (poly1, ctx); + TEMPLATE(T, poly_clear) (poly2, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_factor_templates/test/t-is_irreducible_ben_or.c b/external/flint-2.4.3/fq_poly_factor_templates/test/t-is_irreducible_ben_or.c new file mode 100644 index 0000000..aad41a4 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor_templates/test/t-is_irreducible_ben_or.c @@ -0,0 +1,108 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include +#include +#include "flint.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" +int +main(void) +{ + int iter; + FLINT_TEST_INIT(state); + + flint_printf("is_irreducible_ben_or...."); + fflush(stdout); + + for (iter = 0; iter < 50; iter++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) poly1, poly2; + slong length; + int i, num; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (poly1, ctx); + TEMPLATE(T, poly_init) (poly2, ctx); + + length = n_randint(state, 7) + 2; + do + { + TEMPLATE(T, poly_randtest) (poly1, state, length, ctx); + if (!TEMPLATE(T, poly_is_zero) (poly1, ctx)) + TEMPLATE(T, poly_make_monic) (poly1, poly1, ctx); + } + while ((!TEMPLATE(T, poly_is_irreducible_ben_or) (poly1, ctx)) + || (poly1->length < 2)); + + num = n_randint(state, 5) + 1; + + for (i = 0; i < num; i++) + { + do + { + TEMPLATE(T, poly_randtest) (poly2, state, length, ctx); + if (!TEMPLATE(T, poly_is_zero) (poly2, ctx)) + TEMPLATE(T, poly_make_monic) (poly2, poly2, ctx); + } + while ((!TEMPLATE(T, poly_is_irreducible_ben_or) (poly2, ctx)) + || (poly2->length < 2)); + + TEMPLATE(T, poly_mul) (poly1, poly1, poly2, ctx); + } + + if (TEMPLATE(T, poly_is_irreducible_ben_or) (poly1, ctx)) + { + flint_printf + ("Error: reducible polynomial declared irreducible!\n"); + flint_printf("poly:\n"); + TEMPLATE(T, poly_print) (poly1, ctx); + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (poly1, ctx); + TEMPLATE(T, poly_clear) (poly2, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_factor_templates/test/t-is_irreducible_ddf.c b/external/flint-2.4.3/fq_poly_factor_templates/test/t-is_irreducible_ddf.c new file mode 100644 index 0000000..20f9b75 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor_templates/test/t-is_irreducible_ddf.c @@ -0,0 +1,108 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include +#include +#include "flint.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" +int +main(void) +{ + int iter; + FLINT_TEST_INIT(state); + + flint_printf("is_irreducible_ddf...."); + fflush(stdout); + + for (iter = 0; iter < 50; iter++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) poly1, poly2; + slong length; + int i, num; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (poly1, ctx); + TEMPLATE(T, poly_init) (poly2, ctx); + + length = n_randint(state, 7) + 2; + do + { + TEMPLATE(T, poly_randtest) (poly1, state, length, ctx); + if (!TEMPLATE(T, poly_is_zero) (poly1, ctx)) + TEMPLATE(T, poly_make_monic) (poly1, poly1, ctx); + } + while ((!TEMPLATE(T, poly_is_irreducible_ddf) (poly1, ctx)) + || (poly1->length < 2)); + + num = n_randint(state, 5) + 1; + + for (i = 0; i < num; i++) + { + do + { + TEMPLATE(T, poly_randtest) (poly2, state, length, ctx); + if (!TEMPLATE(T, poly_is_zero) (poly2, ctx)) + TEMPLATE(T, poly_make_monic) (poly2, poly2, ctx); + } + while ((!TEMPLATE(T, poly_is_irreducible_ddf) (poly2, ctx)) + || (poly2->length < 2)); + + TEMPLATE(T, poly_mul) (poly1, poly1, poly2, ctx); + } + + if (TEMPLATE(T, poly_is_irreducible_ddf) (poly1, ctx)) + { + flint_printf + ("Error: reducible polynomial declared irreducible!\n"); + flint_printf("poly:\n"); + TEMPLATE(T, poly_print) (poly1, ctx); + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (poly1, ctx); + TEMPLATE(T, poly_clear) (poly2, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_factor_templates/test/t-is_squarefree.c b/external/flint-2.4.3/fq_poly_factor_templates/test/t-is_squarefree.c new file mode 100644 index 0000000..e0c56fb --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor_templates/test/t-is_squarefree.c @@ -0,0 +1,123 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include +#include +#include "flint.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" +int +main(void) +{ + int iter; + FLINT_TEST_INIT(state); + + flint_printf("is_squarefree...."); + fflush(stdout); + + for (iter = 0; iter < 200 * flint_test_multiplier(); iter++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) poly, Q, R, t; + fmpz_t x; + slong i, num_factors, exp, max_exp; + int v, result; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (poly, ctx); + TEMPLATE(T, poly_init) (t, ctx); + TEMPLATE(T, poly_init) (Q, ctx); + TEMPLATE(T, poly_init) (R, ctx); + + fmpz_init(x); + fmpz_randtest_mod(x, state, TEMPLATE(T, ctx_prime) (ctx)); + + TEMPLATE(T, poly_set_coeff_fmpz) (poly, 0, x, ctx); + num_factors = n_randint(state, 5); + + max_exp = 0; + for (i = 0; i < num_factors; i++) + { + do + { + TEMPLATE(T, poly_randtest) (t, state, n_randint(state, 10), + ctx); + } while (!TEMPLATE(T, poly_is_irreducible) (t, ctx) + || (TEMPLATE(T, poly_length) (t, ctx) < 2)); + + exp = n_randint(state, 4) + 1; + if (n_randint(state, 2) == 0) + exp = 1; + + TEMPLATE(T, poly_divrem) (Q, R, poly, t, ctx); + if (!TEMPLATE(T, poly_is_zero) (R, ctx)) + { + TEMPLATE(T, poly_pow) (t, t, exp, ctx); + TEMPLATE(T, poly_mul) (poly, poly, t, ctx); + max_exp = FLINT_MAX(exp, max_exp); + } + } + + v = TEMPLATE(T, poly_is_squarefree) (poly, ctx); + + if (v == 1) + result = (max_exp <= 1 && !TEMPLATE(T, poly_is_zero) (poly, ctx)); + else + result = (max_exp > 1 || TEMPLATE(T, poly_is_zero) (poly, ctx)); + + if (!result) + { + flint_printf("FAIL: "); + TEMPLATE(T, ctx_print) (ctx); + flint_printf(" %wd, %d\n", max_exp, v); + TEMPLATE(T, poly_print) (poly, ctx); + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (poly, ctx); + TEMPLATE(T, poly_clear) (t, ctx); + TEMPLATE(T, poly_clear) (Q, ctx); + TEMPLATE(T, poly_clear) (R, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_factor_templates/test/t-iterated_frobenius_preinv.c b/external/flint-2.4.3/fq_poly_factor_templates/test/t-iterated_frobenius_preinv.c new file mode 100644 index 0000000..9c73821 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_factor_templates/test/t-iterated_frobenius_preinv.c @@ -0,0 +1,114 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +int +main(void) +{ + int i, j; + FLINT_TEST_INIT(state); + + flint_printf("iterated_frobenius_preinv...."); + fflush(stdout); + + for (j = 0; j < 20 * flint_test_multiplier(); j++) + { + int result; + fmpz_t q; + slong n; + + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) v, vinv, *h1, *h2; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + fmpz_init(q); + TEMPLATE(T, ctx_order) (q, ctx); + + TEMPLATE(T, poly_init) (v, ctx); + TEMPLATE(T, poly_init) (vinv, ctx); + + TEMPLATE(T, poly_randtest_monic) (v, state, n_randint(state, 20) + 1, + ctx); + + TEMPLATE(T, poly_reverse) (vinv, v, v->length, ctx); + TEMPLATE(T, poly_inv_series_newton) (vinv, vinv, v->length, ctx); + + n = n_randint(state, 5) + 2; + if (!(h1 = flint_malloc((2 * n) * sizeof(TEMPLATE(T, poly_struct))))) + { + flint_printf("Exception (t-fq_poly_iterated_frobenius_preinv):\n"); + flint_printf("Not enough memory.\n"); + abort(); + } + h2 = h1 + n; + + for (i = 0; i < 2 * n; i++) + TEMPLATE(T, poly_init) (h1[i], ctx); + + TEMPLATE(T, poly_iterated_frobenius_preinv) (h1, n, v, vinv, ctx); + + TEMPLATE(T, poly_gen) (h2[0], ctx); + for (i = 1; i < n; i++) + TEMPLATE(T, poly_powmod_fmpz_sliding_preinv) (h2[i], h2[i - 1], q, + 0, v, vinv, ctx); + + result = 1; + for (i = 0; i < n; i++) + result = result && TEMPLATE(T, poly_equal) (h1[i], h2[i], ctx); + + + if (!result) + { + flint_printf("FAIL (composition):\n"); + flint_printf("v:\n"); + TEMPLATE(T, poly_print) (v, ctx); + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (v, ctx); + TEMPLATE(T, poly_clear) (vinv, ctx); + + for (i = 0; i < 2 * n; i++) + TEMPLATE(T, poly_clear) (h1[i], ctx); + + flint_free(h1); + TEMPLATE(T, ctx_clear) (ctx); + fmpz_clear(q); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} + + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates.h b/external/flint-2.4.3/fq_poly_templates.h new file mode 100644 index 0000000..ef075ca --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates.h @@ -0,0 +1,1135 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Andres Goens + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#ifdef T + +#ifdef __cplusplus +extern "C" { +#endif + +/* Type definitions *********************************************************/ + +typedef struct +{ + TEMPLATE(T, struct) *coeffs; + slong alloc; + slong length; +} +TEMPLATE(T, poly_struct); + +typedef TEMPLATE(T, poly_struct) TEMPLATE(T, poly_t)[1]; + +/* Memory management ********************************************************/ + +void +TEMPLATE(T, poly_init)(TEMPLATE(T, poly_t) poly, const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_init2)(TEMPLATE(T, poly_t) poly, slong alloc, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_realloc)(TEMPLATE(T, poly_t) poly, slong alloc, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_truncate)(TEMPLATE(T, poly_t) poly, slong len, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_fit_length)(TEMPLATE(T, poly_t) poly, slong len, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_clear)(TEMPLATE(T, poly_t) poly, + const TEMPLATE(T, ctx_t) ctx); + +void +_TEMPLATE(T, poly_normalise)(TEMPLATE(T, poly_t) poly, + const TEMPLATE(T, ctx_t) ctx); + +void +_TEMPLATE(T, poly_normalise2)(TEMPLATE(T, struct) *poly, slong *length, + const TEMPLATE(T, ctx_t) ctx); + +static __inline__ void +_TEMPLATE(T, poly_set_length)(TEMPLATE(T, poly_t) poly, slong len, + const TEMPLATE(T, ctx_t) ctx) +{ + if (poly->length > len) + { + slong i; + + for (i = len; i < poly->length; i++) + TEMPLATE(T, zero)(poly->coeffs + i, ctx); + } + poly->length = len; +} + +/* Polynomial parameters ***************************************************/ + +static __inline__ slong +TEMPLATE(T, poly_length)(const TEMPLATE(T, poly_t) poly, + const TEMPLATE(T, ctx_t) ctx) +{ + return poly->length; +} + +static __inline__ slong +TEMPLATE(T, poly_degree)(const TEMPLATE(T, poly_t) poly, + const TEMPLATE(T, ctx_t) ctx) +{ + return poly->length - 1; +} + +static __inline__ TEMPLATE(T, struct) * +TEMPLATE(T, poly_lead)(const TEMPLATE(T, poly_t) poly, + const TEMPLATE(T, ctx_t) ctx) +{ + return poly->length > 0 ? poly->coeffs + (poly->length - 1) : NULL; +} + +/* Randomisation ***********************************************************/ + +void +TEMPLATE(T, poly_randtest)(TEMPLATE(T, poly_t) f, flint_rand_t state, + slong len, const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_randtest_not_zero)(TEMPLATE(T, poly_t) f, flint_rand_t state, + slong len, const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_randtest_monic) (TEMPLATE(T, poly_t) f, flint_rand_t state, + slong len, const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_randtest_irreducible) (TEMPLATE(T, poly_t) f, + flint_rand_t state, slong len, + const TEMPLATE(T, ctx_t) ctx); + + +/* Assignment and basic manipulation ***************************************/ + +void +_TEMPLATE(T, poly_set)(TEMPLATE(T, struct) *rop, const TEMPLATE(T, struct) *op, + slong len, const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_set)(TEMPLATE(T, poly_t) rop, const TEMPLATE(T, poly_t) op, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE3(T, poly_set, T)(TEMPLATE(T, poly_t) poly, const TEMPLATE(T, t) c, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_swap)(TEMPLATE(T, poly_t) op1, TEMPLATE(T, poly_t) op2, + const TEMPLATE(T, ctx_t) ctx); + +static __inline__ void +_TEMPLATE(T, poly_zero)(TEMPLATE(T, struct) *rop, slong len, + const TEMPLATE(T, ctx_t) ctx) +{ + slong i; + + for (i = 0; i < len; i++) + TEMPLATE(T, zero)(rop + i, ctx); +} + +static __inline__ void +TEMPLATE(T, poly_zero)(TEMPLATE(T, poly_t) poly, const TEMPLATE(T, ctx_t) ctx) +{ + _TEMPLATE(T, poly_set_length)(poly, 0, ctx); +} + +void +TEMPLATE(T, poly_one)(TEMPLATE(T, poly_t) poly, const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_gen)(TEMPLATE(T, poly_t) f, const TEMPLATE(T, ctx_t) ctx); + +void +_TEMPLATE(T, poly_make_monic)(TEMPLATE(T, struct) *rop, + const TEMPLATE(T, struct) *op, slong length, + const TEMPLATE(T, ctx_t) ctx); + +void TEMPLATE(T, poly_make_monic)(TEMPLATE(T, poly_t) rop, + const TEMPLATE(T, poly_t) op, + const TEMPLATE(T, ctx_t) ctx); + +void +_TEMPLATE(T, poly_reverse)(TEMPLATE(T, struct) * res, + const TEMPLATE(T, struct) * poly, slong len, slong n, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_reverse)(TEMPLATE(T, poly_t) res, + const TEMPLATE(T, poly_t) poly, slong n, + const TEMPLATE(T, ctx_t) ctx); + +ulong +TEMPLATE(T, poly_deflation)(const TEMPLATE(T, poly_t) input, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_deflate)(TEMPLATE(T, poly_t) result, + const TEMPLATE(T, poly_t) input, ulong deflation, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_inflate)(TEMPLATE(T, poly_t) result, + const TEMPLATE(T, poly_t) input, ulong inflation, + const TEMPLATE(T, ctx_t) ctx); + +/* Getting and setting coefficients ****************************************/ + +void +TEMPLATE(T, poly_get_coeff)(TEMPLATE(T, t) x, const TEMPLATE(T, poly_t) poly, + slong n, const TEMPLATE(T, ctx_t) ctx); + +void TEMPLATE(T, poly_set_coeff)(TEMPLATE(T, poly_t) poly, slong n, + const TEMPLATE(T, t) x, + const TEMPLATE(T, ctx_t) ctx); + +static __inline__ void +TEMPLATE(T, poly_set_coeff_fmpz)(TEMPLATE(T, poly_t) poly, slong n, + const fmpz_t x, const TEMPLATE(T, ctx_t) ctx) +{ + TEMPLATE(T, poly_fit_length)(poly, n + 1, ctx); + TEMPLATE(T, set_fmpz)(poly->coeffs + n, x, ctx); + if (n + 1 > poly->length) + { + _TEMPLATE(T, poly_set_length)(poly, n + 1, ctx); + } + _TEMPLATE(T, poly_normalise)(poly, ctx); +} + +static __inline__ int +TEMPLATE(T, poly_is_gen)(const TEMPLATE(T, poly_t) poly, + const TEMPLATE(T, ctx_t) ctx) +{ + return ((poly->length == 2) && + TEMPLATE(T, is_zero)(poly->coeffs, ctx) && + TEMPLATE(T, is_one)(poly->coeffs + 1, ctx)); +} + +/* Comparison **************************************************************/ + +int TEMPLATE(T, poly_equal)(const TEMPLATE(T, poly_t) poly1, + const TEMPLATE(T, poly_t) poly2, + const TEMPLATE(T, ctx_t) ctx); + +static __inline__ int +TEMPLATE(T, poly_is_zero)(const TEMPLATE(T, poly_t) poly, + const TEMPLATE(T, ctx_t) ctx) +{ + return (poly->length == 0); +} + +static __inline__ int +TEMPLATE(T, poly_is_one)(const TEMPLATE(T, poly_t) op, + const TEMPLATE(T, ctx_t) ctx) +{ + return (op->length == 1) && (TEMPLATE(T, is_one)(op->coeffs + 0, ctx)); +} + +static __inline__ int +TEMPLATE(T, poly_is_unit)(const TEMPLATE(T, poly_t) op, + const TEMPLATE(T, ctx_t) ctx) +{ + return (op->length == 1) && (!(TEMPLATE(T, is_zero)(op->coeffs + 0, ctx))); +} + +static __inline__ int +TEMPLATE3(T, poly_equal, T)(const TEMPLATE(T, poly_t) poly, + const TEMPLATE(T, t) c, + const TEMPLATE(T, ctx_t) ctx) +{ + return ((poly->length == 0) && TEMPLATE(T, is_zero)(c, ctx)) || + ((poly->length == 1) && TEMPLATE(T, equal)(poly->coeffs, c, ctx)); +} + +/* Addition and subtraction ************************************************/ + +void +_TEMPLATE(T, poly_add)(TEMPLATE(T, struct) *res, + const TEMPLATE(T, struct) *poly1, slong len1, + const TEMPLATE(T, struct) *poly2, slong len2, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_add)(TEMPLATE(T, poly_t) rop, const TEMPLATE(T, poly_t) op1, + const TEMPLATE(T, poly_t) op2, + const TEMPLATE(T, ctx_t) ctx); + +void +_TEMPLATE(T, poly_sub)(TEMPLATE(T, struct) *res, + const TEMPLATE(T, struct) *poly1, slong len1, + const TEMPLATE(T, struct) *poly2, slong len2, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_sub)(TEMPLATE(T, poly_t) rop, + const TEMPLATE(T, poly_t) op1, + const TEMPLATE(T, poly_t) op2, + const TEMPLATE(T, ctx_t) ctx); + +void +_TEMPLATE(T, poly_neg)(TEMPLATE(T, struct) *rop, + const TEMPLATE(T, struct) *op, slong len, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_neg)(TEMPLATE(T, poly_t) rop, const TEMPLATE(T, poly_t) op, + const TEMPLATE(T, ctx_t) ctx); + +/* Scalar multiplication and division **************************************/ + +void +_TEMPLATE3(T, poly_scalar_mul, T)(TEMPLATE(T, struct) *rop, + const TEMPLATE(T, struct) *op, slong len, + const TEMPLATE(T, t) x, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE3(T, poly_scalar_mul, T)(TEMPLATE(T, poly_t) rop, + const TEMPLATE(T, poly_t) op, + const TEMPLATE(T, t) x, + const TEMPLATE(T, ctx_t) ctx); + +void +_TEMPLATE3(T, poly_scalar_addmul, T)(TEMPLATE(T, struct) *rop, + const TEMPLATE(T, struct) *op, slong len, + const TEMPLATE(T, t) x, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE3(T, poly_scalar_addmul, T)(TEMPLATE(T, poly_t) rop, + const TEMPLATE(T, poly_t) op, + const TEMPLATE(T, t) x, + const TEMPLATE(T, ctx_t) ctx); + +void +_TEMPLATE3(T, poly_scalar_submul, T)(TEMPLATE(T, struct) *rop, + const TEMPLATE(T, struct) *op, slong len, + const TEMPLATE(T, t) x, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE3(T, poly_scalar_submul, T)(TEMPLATE(T, poly_t) rop, + const TEMPLATE(T, poly_t) op, + const TEMPLATE(T, t) x, + const TEMPLATE(T, ctx_t) ctx); + +/* Multiplication **********************************************************/ + +void +_TEMPLATE(T, poly_mul_classical)(TEMPLATE(T, struct) *rop, + const TEMPLATE(T, struct) *op1, slong len1, + const TEMPLATE(T, struct) *op2, slong len2, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_mul_classical)(TEMPLATE(T, poly_t) rop, + const TEMPLATE(T, poly_t) op1, + const TEMPLATE(T, poly_t) op2, + const TEMPLATE(T, ctx_t) ctx); + +void +_TEMPLATE(T, poly_mul_reorder)(TEMPLATE(T, struct) *rop, + const TEMPLATE(T, struct) *op1, slong len1, + const TEMPLATE(T, struct) *op2, slong len2, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_mul_reorder)(TEMPLATE(T, poly_t) rop, + const TEMPLATE(T, poly_t) op1, + const TEMPLATE(T, poly_t) op2, + const TEMPLATE(T, ctx_t) ctx); + +void +_TEMPLATE(T, poly_mul_KS)(TEMPLATE(T, struct) *rop, + const TEMPLATE(T, struct) *op1, slong len1, + const TEMPLATE(T, struct) *op2, slong len2, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_mul_KS)(TEMPLATE(T, poly_t) rop, + const TEMPLATE(T, poly_t) op1, + const TEMPLATE(T, poly_t) op2, + const TEMPLATE(T, ctx_t) ctx); + +void +_TEMPLATE(T, poly_mul)(TEMPLATE(T, struct) *rop, + const TEMPLATE(T, struct) *op1, slong len1, + const TEMPLATE(T, struct) *op2, slong len2, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_mul)(TEMPLATE(T, poly_t) rop, + const TEMPLATE(T, poly_t) op1, + const TEMPLATE(T, poly_t) op2, + const TEMPLATE(T, ctx_t) ctx); + +void +_TEMPLATE(T, poly_mullow_classical)(TEMPLATE(T, struct) *rop, + const TEMPLATE(T, struct) *op1, slong len1, + const TEMPLATE(T, struct) *op2, slong len2, + slong n, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_mullow_classical)(TEMPLATE(T, poly_t) rop, + const TEMPLATE(T, poly_t) op1, + const TEMPLATE(T, poly_t) op2, + slong n, const + TEMPLATE(T, ctx_t) ctx); + +void +_TEMPLATE(T, poly_mullow_KS)(TEMPLATE(T, struct) *rop, + const TEMPLATE(T, struct) *op1, slong len1, + const TEMPLATE(T, struct) *op2, slong len2, + slong n, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_mullow_KS)(TEMPLATE(T, poly_t) rop, + const TEMPLATE(T, poly_t) op1, + const TEMPLATE(T, poly_t) op2, + slong n, + const TEMPLATE(T, ctx_t) ctx); + +void +_TEMPLATE(T, poly_mullow)(TEMPLATE(T, struct) *rop, + const TEMPLATE(T, struct) *op1, slong len1, + const TEMPLATE(T, struct) *op2, slong len2, + slong n, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_mullow)(TEMPLATE(T, poly_t) rop, + const TEMPLATE(T, poly_t) op1, + const TEMPLATE(T, poly_t) op2, + slong n, + const TEMPLATE(T, ctx_t) ctx); + +void _TEMPLATE(T, poly_mulmod)(TEMPLATE(T, struct) * res, + const TEMPLATE(T, struct) * poly1, slong len1, + const TEMPLATE(T, struct) * poly2, slong len2, + const TEMPLATE(T, struct) * f, slong lenf, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_mulmod)(TEMPLATE(T, poly_t) res, + const TEMPLATE(T, poly_t) poly1, + const TEMPLATE(T, poly_t) poly2, + const TEMPLATE(T, poly_t) f, + const TEMPLATE(T, ctx_t) ctx); + +void +_TEMPLATE(T, poly_mulmod_preinv)(TEMPLATE(T, struct) *res, + const TEMPLATE(T, struct) *poly1, slong len1, + const TEMPLATE(T, struct) *poly2, slong len2, + const TEMPLATE(T, struct) *f, slong lenf, + const TEMPLATE(T, struct) *finv, slong lenfinv, + const TEMPLATE(T, ctx_t) ctx); +void +TEMPLATE(T, poly_mulmod_preinv)(TEMPLATE(T, poly_t) res, + const TEMPLATE(T, poly_t) poly1, + const TEMPLATE(T, poly_t) poly2, + const TEMPLATE(T, poly_t) f, + const TEMPLATE(T, poly_t) finv, + const TEMPLATE(T, ctx_t) ctx); + +/* Squaring ******************************************************************/ + +void +_TEMPLATE(T, poly_sqr_classical)(TEMPLATE(T, struct) *rop, + const TEMPLATE(T, struct) *op, slong len, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_sqr_classical)(TEMPLATE(T, poly_t) rop, + const TEMPLATE(T, poly_t) op, + const TEMPLATE(T, ctx_t) ctx); + +void +_TEMPLATE(T, poly_sqr_reorder)(TEMPLATE(T, struct) *rop, + const TEMPLATE(T, struct) *op, slong len, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_sqr_reorder)(TEMPLATE(T, poly_t) rop, + const TEMPLATE(T, poly_t) op, + const TEMPLATE(T, ctx_t) ctx); + +void +_TEMPLATE(T, poly_sqr_KS)(TEMPLATE(T, struct) *rop, + const TEMPLATE(T, struct) *op, slong len, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_sqr_KS)(TEMPLATE(T, poly_t) rop, + const TEMPLATE(T, poly_t) op, + const TEMPLATE(T, ctx_t) ctx); + +void +_TEMPLATE(T, poly_sqr)(TEMPLATE(T, struct) *rop, + const TEMPLATE(T, struct) *op, slong len, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_sqr)(TEMPLATE(T, poly_t) rop, const TEMPLATE(T, poly_t) op, + const TEMPLATE(T, ctx_t) ctx); + +/* Powering ****************************************************************/ + +void +_TEMPLATE(T, poly_pow)(TEMPLATE(T, struct) *rop, + const TEMPLATE(T, struct) *op, slong len, + ulong e, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_pow)(TEMPLATE(T, poly_t) rop, + const TEMPLATE(T, poly_t) op, + ulong e, + const TEMPLATE(T, ctx_t) ctx); + +void +_TEMPLATE(T, poly_powmod_fmpz_binexp)(TEMPLATE(T, struct) * res, + const TEMPLATE(T, struct) * poly, + const fmpz_t e, + const TEMPLATE(T, struct) * f, slong lenf, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_powmod_fmpz_binexp)(TEMPLATE(T, poly_t) res, + const TEMPLATE(T, poly_t) poly, + const fmpz_t e, + const TEMPLATE(T, poly_t) f, + const TEMPLATE(T, ctx_t) ctx); + +void +_TEMPLATE(T, poly_powmod_fmpz_binexp_preinv)( + TEMPLATE(T, struct) * res, + const TEMPLATE(T, struct) * poly, + const fmpz_t e, + const TEMPLATE(T, struct) * f, slong lenf, + const TEMPLATE(T, struct) *finv, slong lenfinv, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_powmod_fmpz_binexp_preinv)( + TEMPLATE(T, poly_t) res, + const TEMPLATE(T, poly_t) poly, const fmpz_t e, + const TEMPLATE(T, poly_t) f, const TEMPLATE(T, poly_t) finv, + const TEMPLATE(T, ctx_t) ctx); + +void +_TEMPLATE(T, poly_powmod_ui_binexp)( + TEMPLATE(T, struct) * res, + const TEMPLATE(T, struct) * poly, + ulong e, + const TEMPLATE(T, struct) * f, slong lenf, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_powmod_ui_binexp)( + TEMPLATE(T, poly_t) res, + const TEMPLATE(T, poly_t) poly, ulong e, + const TEMPLATE(T, poly_t) f, + const TEMPLATE(T, ctx_t) ctx); + +void +_TEMPLATE(T, poly_powmod_ui_binexp_preinv)( + TEMPLATE(T, struct) * res, + const TEMPLATE(T, struct) * poly, + ulong e, + const TEMPLATE(T, struct) * f, slong lenf, + const TEMPLATE(T, struct) * finv, slong lenfinv, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_powmod_ui_binexp_preinv)( + TEMPLATE(T, poly_t) res, + const TEMPLATE(T, poly_t) poly, + ulong e, + const TEMPLATE(T, poly_t) f, + const TEMPLATE(T, poly_t) finv, + const TEMPLATE(T, ctx_t) ctx); + +void +_TEMPLATE(T, poly_powmod_fmpz_sliding_preinv)( + TEMPLATE(T, struct) * res, + const TEMPLATE(T, struct) * poly, + const fmpz_t e, ulong k, + const TEMPLATE(T, struct) * f, slong lenf, + const TEMPLATE(T, struct) * finv, slong lenfinv, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_powmod_fmpz_sliding_preinv)( + TEMPLATE(T, poly_t) res, + const TEMPLATE(T, poly_t) poly, + const fmpz_t e, ulong k, + const TEMPLATE(T, poly_t) f, + const TEMPLATE(T, poly_t) finv, + const TEMPLATE(T, ctx_t) ctx); + + +void +_TEMPLATE(T, poly_powmod_x_fmpz_preinv)( + TEMPLATE(T, struct) * res, const fmpz_t e, + const TEMPLATE(T, struct) * f, slong lenf, + const TEMPLATE(T, struct)* finv, slong lenfinv, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_powmod_x_fmpz_preinv)( + TEMPLATE(T, poly_t) res, const fmpz_t e, + const TEMPLATE(T, poly_t) f, + const TEMPLATE(T, poly_t) finv, + const TEMPLATE(T, ctx_t) ctx); + +/* Shifting ****************************************************************/ + +void +_TEMPLATE(T, poly_shift_left)(TEMPLATE(T, struct) *rop, + const TEMPLATE(T, struct) *op, slong len, + slong n, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_shift_left)(TEMPLATE(T, poly_t) rop, + const TEMPLATE(T, poly_t) op, + slong n, + const TEMPLATE(T, ctx_t) ctx); + +void +_TEMPLATE(T, poly_shift_right)(TEMPLATE(T, struct) *rop, + const TEMPLATE(T, struct) *op, slong len, + slong n, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_shift_right)(TEMPLATE(T, poly_t) rop, + const TEMPLATE(T, poly_t) op, + slong n, + const TEMPLATE(T, ctx_t) ctx); + +/* Norms *******************************************************************/ + +slong +_TEMPLATE(T, poly_hamming_weight)(const TEMPLATE(T, struct) *op, slong len, + const TEMPLATE(T, ctx_t) ctx); + +slong +TEMPLATE(T, poly_hamming_weight)(const TEMPLATE(T, poly_t) op, + const TEMPLATE(T, ctx_t) ctx); + +/* Greatest common divisor *************************************************/ + +void +TEMPLATE(T, poly_gcd_euclidean)(TEMPLATE(T, poly_t) rop, + const TEMPLATE(T, poly_t) op1, + const TEMPLATE(T, poly_t) op2, + const TEMPLATE(T, ctx_t) ctx); + +slong +_TEMPLATE(T, poly_gcd_euclidean)(TEMPLATE(T, struct)* G, + const TEMPLATE(T, struct)* A, slong lenA, + const TEMPLATE(T, struct)* B, slong lenB, + const TEMPLATE(T, t) invB, + const TEMPLATE(T, ctx_t) ctx); + +static __inline__ slong +_TEMPLATE(T, poly_gcd)(TEMPLATE(T, struct)* G, + const TEMPLATE(T, struct)* A, slong lenA, + const TEMPLATE(T, struct)* B, slong lenB, + const TEMPLATE(T, t) invB, + const TEMPLATE(T, ctx_t) ctx) +{ + return _TEMPLATE(T, poly_gcd_euclidean)(G, A, lenA, B, lenB, invB, ctx); +} + +static __inline__ void +TEMPLATE(T, poly_gcd)(TEMPLATE(T, poly_t) rop, + const TEMPLATE(T, poly_t) op1, + const TEMPLATE(T, poly_t) op2, + const TEMPLATE(T, ctx_t) ctx) +{ + TEMPLATE(T, poly_gcd_euclidean)(rop, op1, op2, ctx); +} + + +/* Euclidean division ******************************************************/ + +ulong +TEMPLATE(T, poly_remove)(TEMPLATE(T, poly_t) f, + const TEMPLATE(T, poly_t) g, + const TEMPLATE(T, ctx_t) ctx); + +void +_TEMPLATE(T, poly_div_basecase)(TEMPLATE(T, struct) *Q, TEMPLATE(T, struct) *R, + const TEMPLATE(T, struct) *A, slong lenA, + const TEMPLATE(T, struct) *B, slong lenB, + const TEMPLATE(T, t) invB, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_div_basecase)(TEMPLATE(T, poly_t) Q, + const TEMPLATE(T, poly_t) A, + const TEMPLATE(T, poly_t) B, + const TEMPLATE(T, ctx_t) ctx); + +void +_TEMPLATE(T, poly_divrem_basecase)(TEMPLATE(T, struct) *Q, + TEMPLATE(T, struct) *R, + const TEMPLATE(T, struct) *A, slong lenA, + const TEMPLATE(T, struct) *B, slong lenB, + const TEMPLATE(T, t) invB, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_divrem_basecase)(TEMPLATE(T, poly_t) Q, TEMPLATE(T, poly_t) R, + const TEMPLATE(T, poly_t) A, + const TEMPLATE(T, poly_t) B, + const TEMPLATE(T, ctx_t) ctx); + +void +_TEMPLATE(T, poly_divrem_divconquer_recursive)( + TEMPLATE(T, struct) * Q, TEMPLATE(T, struct) * BQ, + TEMPLATE(T, struct) * W, + const TEMPLATE(T, struct) * A, + const TEMPLATE(T, struct) * B, slong lenB, + const TEMPLATE(T, t) invB, + const TEMPLATE(T, ctx_t) ctx); + + + +void _TEMPLATE(T, poly_divrem_divconquer)( + TEMPLATE(T, struct) *Q, TEMPLATE(T, struct) *R, + const TEMPLATE(T, struct) *A, slong lenA, + const TEMPLATE(T, struct) *B, slong lenB, + const TEMPLATE(T, t) invB, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_divrem_divconquer)(TEMPLATE(T, poly_t) Q, + TEMPLATE(T, poly_t) R, + const TEMPLATE(T, poly_t) A, + const TEMPLATE(T, poly_t) B, + const TEMPLATE(T, ctx_t) ctx); + +static __inline__ void +_TEMPLATE(T, poly_divrem)(TEMPLATE(T, struct) *Q, TEMPLATE(T, struct) *R, + const TEMPLATE(T, struct) *A, slong lenA, + const TEMPLATE(T, struct) *B, slong lenB, + const TEMPLATE(T, t) invB, + const TEMPLATE(T, ctx_t) ctx) +{ + _TEMPLATE(T, poly_divrem_divconquer)(Q, R, A, lenA, B, lenB, invB, ctx); +} + +static __inline__ void +TEMPLATE(T, poly_divrem)(TEMPLATE(T, poly_t) Q, TEMPLATE(T, poly_t) R, + const TEMPLATE(T, poly_t) A, + const TEMPLATE(T, poly_t) B, + const TEMPLATE(T, ctx_t) ctx) +{ + TEMPLATE(T, poly_divrem_divconquer)(Q, R, A, B, ctx); +} + +static __inline__ void +_TEMPLATE(T, poly_rem)(TEMPLATE(T, struct) *R, + const TEMPLATE(T, struct) *A, slong lenA, + const TEMPLATE(T, struct) *B, slong lenB, + const TEMPLATE(T, t) invB, + const TEMPLATE(T, ctx_t) ctx) +{ + TEMPLATE(T, struct) *Q = _TEMPLATE(T, vec_init)(lenA - lenB + 1, ctx); + + if (lenA < lenB) + { + _TEMPLATE(T, vec_set)(R, A, lenA, ctx); + _TEMPLATE(T, vec_zero)(R + lenA, lenB - 1 - lenA, ctx); + } + else + { + TEMPLATE(T, struct) *T = _TEMPLATE(T, vec_init)(lenA, ctx); + _TEMPLATE(T, poly_divrem_divconquer)(Q, T, A, lenA, B, lenB, invB, ctx); + _TEMPLATE(T, vec_set)(R, T, lenB - 1, ctx); + _TEMPLATE(T, vec_clear)(T, lenA, ctx); + } + + _TEMPLATE(T, vec_clear)(Q, lenA - lenB + 1, ctx); +} + + + +static __inline__ void +TEMPLATE(T, poly_rem)(TEMPLATE(T, poly_t) R, + const TEMPLATE(T, poly_t) A, const TEMPLATE(T, poly_t) B, + const TEMPLATE(T, ctx_t) ctx) +{ + TEMPLATE(T, poly_t) Q; + TEMPLATE(T, poly_init)(Q, ctx); + TEMPLATE(T, poly_divrem)(Q, R, A, B, ctx); + TEMPLATE(T, poly_clear)(Q, ctx); +} + +void +_TEMPLATE(T, poly_inv_series_newton)(TEMPLATE(T, struct) * Qinv, + const TEMPLATE(T, struct) * Q, slong n, + const TEMPLATE(T, t) cinv, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_inv_series_newton)(TEMPLATE(T, poly_t) Qinv, + const TEMPLATE(T, poly_t) Q, slong n, + const TEMPLATE(T, ctx_t) ctx); + +void +_TEMPLATE(T, poly_div_newton_n_preinv) ( + TEMPLATE(T, struct) *Q, + const TEMPLATE(T, struct) *A, slong lenA, + const TEMPLATE(T, struct)* B, slong lenB, + const TEMPLATE(T, struct)* Binv, slong lenBinv, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_div_newton_n_preinv) (TEMPLATE(T, poly_t) Q, + const TEMPLATE(T, poly_t) A, + const TEMPLATE(T, poly_t) B, + const TEMPLATE(T, poly_t) Binv, + const TEMPLATE(T, ctx_t) ctx); + +void +_TEMPLATE(T, poly_divrem_newton_n_preinv) ( + TEMPLATE(T, struct)* Q, TEMPLATE(T, struct)* R, + const TEMPLATE(T, struct)* A, slong lenA, + const TEMPLATE(T, struct)* B, slong lenB, + const TEMPLATE(T, struct)* Binv, slong lenBinv, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_divrem_newton_n_preinv)( + TEMPLATE(T, poly_t) Q, TEMPLATE(T, poly_t) R, + const TEMPLATE(T, poly_t) A, const TEMPLATE(T, poly_t) B, + const TEMPLATE(T, poly_t) Binv, const TEMPLATE(T, ctx_t) ctx); + +/* Divisibility testing ***************************************************/ + +int +_TEMPLATE(T, poly_divides)(TEMPLATE(T, struct) *Q, + const TEMPLATE(T, struct) *A, slong lenA, + const TEMPLATE(T, struct) *B, slong lenB, + const TEMPLATE(T, t) invB, + const TEMPLATE(T, ctx_t) ctx); + +int +TEMPLATE(T, poly_divides)(TEMPLATE(T, poly_t) Q, + const TEMPLATE(T, poly_t) A, const TEMPLATE(T, poly_t) B, + const TEMPLATE(T, ctx_t) ctx); + +/* Derivative **************************************************************/ + +void +_TEMPLATE(T, poly_derivative)(TEMPLATE(T, struct) *rop, + const TEMPLATE(T, struct) *op, slong len, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_derivative)(TEMPLATE(T, poly_t) rop, + const TEMPLATE(T, poly_t) op, + const TEMPLATE(T, ctx_t) ctx); + +/* Evaluation **************************************************************/ + +void _TEMPLATE3(T, poly_evaluate, T)(TEMPLATE(T, t) rop, + const TEMPLATE(T, struct) *op, slong len, + const TEMPLATE(T, t) a, + const TEMPLATE(T, ctx_t) ctx); + +void TEMPLATE3(T, poly_evaluate, T)(TEMPLATE(T, t) res, + const TEMPLATE(T, poly_t) f, + const TEMPLATE(T, t) a, + const TEMPLATE(T, ctx_t) ctx); + +/* Composition *************************************************************/ + +void +_TEMPLATE(T, poly_compose_divconquer)( + TEMPLATE(T, struct) *rop, + const TEMPLATE(T, struct) *op1, slong len1, + const TEMPLATE(T, struct) *op2, slong len2, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_compose_divconquer)(TEMPLATE(T, poly_t) rop, + const TEMPLATE(T, poly_t) op1, + const TEMPLATE(T, poly_t) op2, + const TEMPLATE(T, ctx_t) ctx); + +void +_TEMPLATE(T, poly_compose_horner)(TEMPLATE(T, struct) *rop, + const TEMPLATE(T, struct) *op1, slong len1, + const TEMPLATE(T, struct) *op2, slong len2, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_compose_horner)(TEMPLATE(T, poly_t) rop, + const TEMPLATE(T, poly_t) op1, + const TEMPLATE(T, poly_t) op2, + const TEMPLATE(T, ctx_t) ctx); + +void +_TEMPLATE(T, poly_compose)(TEMPLATE(T, struct) *rop, + const TEMPLATE(T, struct) *op1, slong len1, + const TEMPLATE(T, struct) *op2, slong len2, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_compose)(TEMPLATE(T, poly_t) rop, + const TEMPLATE(T, poly_t) op1, + const TEMPLATE(T, poly_t) op2, + const TEMPLATE(T, ctx_t) ctx); + +void +_TEMPLATE(T, poly_compose_mod)(TEMPLATE(T, struct) * res, + const TEMPLATE(T, struct) * f, slong lenf, + const TEMPLATE(T, struct) * g, + const TEMPLATE(T, struct) * h, slong lenh, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_compose_mod)(TEMPLATE(T, poly_t) res, + const TEMPLATE(T, poly_t) poly1, + const TEMPLATE(T, poly_t) poly2, + const TEMPLATE(T, poly_t) poly3, + const TEMPLATE(T, ctx_t) ctx); + +void +_TEMPLATE(T, poly_compose_mod_preinv)( + TEMPLATE(T, struct) * res, + const TEMPLATE(T, struct) * f, slong lenf, + const TEMPLATE(T, struct) * g, + const TEMPLATE(T, struct) * h, slong lenh, + const TEMPLATE(T, struct) * hinv, slong lenhinv, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_compose_mod_preinv)(TEMPLATE(T, poly_t) res, + const TEMPLATE(T, poly_t) poly1, + const TEMPLATE(T, poly_t) poly2, + const TEMPLATE(T, poly_t) poly3, + const TEMPLATE(T, poly_t) poly3inv, + const TEMPLATE(T, ctx_t) ctx); + + +void +_TEMPLATE(T, poly_compose_mod_horner)( + TEMPLATE(T, struct) * res, + const TEMPLATE(T, struct) * f, slong lenf, + const TEMPLATE(T, struct) * g, + const TEMPLATE(T, struct) * h, slong lenh, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_compose_mod_horner)(TEMPLATE(T, poly_t) res, + const TEMPLATE(T, poly_t) poly1, + const TEMPLATE(T, poly_t) poly2, + const TEMPLATE(T, poly_t) poly3, + const TEMPLATE(T, ctx_t) ctx); + +void +_TEMPLATE(T, poly_compose_mod_horner_preinv)( + TEMPLATE(T, struct) * res, + const TEMPLATE(T, struct) * f, slong lenf, + const TEMPLATE(T, struct) * g, + const TEMPLATE(T, struct) * h, slong lenh, + const TEMPLATE(T, struct) * hinv, slong lenhinv, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_compose_mod_horner_preinv)(TEMPLATE(T, poly_t) res, + const TEMPLATE(T, poly_t) poly1, + const TEMPLATE(T, poly_t) poly2, + const TEMPLATE(T, poly_t) poly3, + const TEMPLATE(T, poly_t) poly3inv, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_compose_mod_brent_kung)(TEMPLATE(T, poly_t) res, + const TEMPLATE(T, poly_t) poly1, + const TEMPLATE(T, poly_t) poly2, + const TEMPLATE(T, poly_t) poly3, + const TEMPLATE(T, ctx_t) ctx); + +void +_TEMPLATE(T, poly_compose_mod_brent_kung)( + TEMPLATE(T, struct) * res, + const TEMPLATE(T, struct) * poly1, slong len1, + const TEMPLATE(T, struct) * poly2, + const TEMPLATE(T, struct) * poly3, slong len3, + const TEMPLATE(T, ctx_t) ctx); + +void +_TEMPLATE(T, poly_compose_mod_brent_kung_preinv)( + TEMPLATE(T, struct) * res, + const TEMPLATE(T, struct) * poly1, slong len1, + const TEMPLATE(T, struct) * poly2, + const TEMPLATE(T, struct) * poly3, slong len3, + const TEMPLATE(T, struct) * poly3inv, slong len3inv, + const TEMPLATE(T, ctx_t) ctx); +void +TEMPLATE(T, poly_compose_mod_brent_kung_preinv)( + TEMPLATE(T, poly_t) res, + const TEMPLATE(T, poly_t) poly1, + const TEMPLATE(T, poly_t) poly2, + const TEMPLATE(T, poly_t) poly3, + const TEMPLATE(T, poly_t) poly3inv, + const TEMPLATE(T, ctx_t) ctx); + +void +_TEMPLATE(T, poly_reduce_matrix_mod_poly) (TEMPLATE(T, mat_t) A, + const TEMPLATE(T, mat_t) B, + const TEMPLATE(T, poly_t) f, + const TEMPLATE(T, ctx_t) ctx); + +void +_TEMPLATE(T, poly_precompute_matrix) ( + TEMPLATE(T, mat_t A), + const TEMPLATE(T, struct)* poly1, + const TEMPLATE(T, struct)* poly2, slong len2, + const TEMPLATE(T, struct)* poly2inv, slong len2inv, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_precompute_matrix) (TEMPLATE(T, mat_t A), + const TEMPLATE(T, poly_t) poly1, + const TEMPLATE(T, poly_t) poly2, + const TEMPLATE(T, poly_t) poly2inv, + const TEMPLATE(T, ctx_t) ctx); + +void +_TEMPLATE(T, poly_compose_mod_brent_kung_precomp_preinv)( + TEMPLATE(T, struct)* res, + const TEMPLATE(T, struct)* poly1, slong len1, + const TEMPLATE(T, mat_t) A, + const TEMPLATE(T, struct)* poly3, slong len3, + const TEMPLATE(T, struct)* poly3inv, slong len3inv, + const TEMPLATE(T, ctx_t) ctx); + +void +TEMPLATE(T, poly_compose_mod_brent_kung_precomp_preinv)( + TEMPLATE(T, poly_t) res, + const TEMPLATE(T, poly_t) poly1, + const TEMPLATE(T, mat_t) A, + const TEMPLATE(T, poly_t) poly3, + const TEMPLATE(T, poly_t) poly3inv, + const TEMPLATE(T, ctx_t) ctx); + +/* Input and output ********************************************************/ + +int +_TEMPLATE(T, poly_fprint_pretty)(FILE *file, + const TEMPLATE(T, struct) *poly, slong len, + const char *x, + const TEMPLATE(T, ctx_t) ctx); + +int +TEMPLATE(T, poly_fprint_pretty)(FILE * file, + const TEMPLATE(T, poly_t) poly, + const char *x, + const TEMPLATE(T, ctx_t) ctx); + +int +_TEMPLATE(T, poly_fprint)(FILE * file, + const TEMPLATE(T, struct) *poly, slong len, + const TEMPLATE(T, ctx_t) ctx); + +int +TEMPLATE(T, poly_fprint)(FILE * file, + const TEMPLATE(T, poly_t) poly, + const TEMPLATE(T, ctx_t) ctx); + +static __inline__ int +_TEMPLATE(T, poly_print)(const TEMPLATE(T, struct) *poly, slong len, + const TEMPLATE(T, ctx_t) ctx) +{ + return _TEMPLATE(T, poly_fprint)(stdout, poly, len, ctx); +} + +static __inline__ int +TEMPLATE(T, poly_print)(const TEMPLATE(T, poly_t) poly, + const TEMPLATE(T, ctx_t) ctx) +{ + return TEMPLATE(T, poly_fprint)(stdout, poly, ctx); +} + + +static __inline__ int +_TEMPLATE(T, poly_print_pretty)(const TEMPLATE(T, struct) *poly, slong len, + const char *x, const TEMPLATE(T, ctx_t) ctx) +{ + return _TEMPLATE(T, poly_fprint_pretty)(stdout, poly, len, x, ctx); +} + +static __inline__ int +TEMPLATE(T, poly_print_pretty)(const TEMPLATE(T, poly_t) poly, + const char *x, + const TEMPLATE(T, ctx_t) ctx) +{ + return TEMPLATE(T, poly_fprint_pretty)(stdout, poly, x, ctx); +} + +char * +_TEMPLATE(T, poly_get_str_pretty)(const TEMPLATE(T, struct) * poly, slong len, + const char *x, + const TEMPLATE(T, ctx_t) ctx); + +char * +TEMPLATE(T, poly_get_str_pretty)(const TEMPLATE(T, poly_t) poly, + const char *x, + const TEMPLATE(T, ctx_t) ctx); + +char * +_TEMPLATE(T, poly_get_str)(const TEMPLATE(T, struct) * poly, slong len, + const TEMPLATE(T, ctx_t) ctx); + +char * +TEMPLATE(T, poly_get_str)(const TEMPLATE(T, poly_t) poly, + const TEMPLATE(T, ctx_t) ctx); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/add.c b/external/flint-2.4.3/fq_poly_templates/add.c new file mode 100644 index 0000000..6521390 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/add.c @@ -0,0 +1,71 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +_TEMPLATE(T, poly_add) (TEMPLATE(T, struct) * res, + const TEMPLATE(T, struct) * poly1, slong len1, + const TEMPLATE(T, struct) * poly2, slong len2, + const TEMPLATE(T, ctx_t) ctx) +{ + const slong min = FLINT_MIN(len1, len2); + slong i; + + for (i = 0; i < min; i++) + TEMPLATE(T, add) (res + i, poly1 + i, poly2 + i, ctx); + + if (poly1 != res) + for (i = min; i < len1; i++) + TEMPLATE(T, set) (res + i, poly1 + i, ctx); + + if (poly2 != res) + for (i = min; i < len2; i++) + TEMPLATE(T, set) (res + i, poly2 + i, ctx); +} + +void +TEMPLATE(T, poly_add) (TEMPLATE(T, poly_t) res, + const TEMPLATE(T, poly_t) poly1, + const TEMPLATE(T, poly_t) poly2, + const TEMPLATE(T, ctx_t) ctx) +{ + const slong max = FLINT_MAX(poly1->length, poly2->length); + + TEMPLATE(T, poly_fit_length) (res, max, ctx); + + _TEMPLATE(T, poly_add) (res->coeffs, poly1->coeffs, poly1->length, + poly2->coeffs, poly2->length, ctx); + + _TEMPLATE(T, poly_set_length) (res, max, ctx); + _TEMPLATE(T, poly_normalise) (res, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/clear.c b/external/flint-2.4.3/fq_poly_templates/clear.c new file mode 100644 index 0000000..586e862 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/clear.c @@ -0,0 +1,44 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Andres Goens + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +TEMPLATE(T, poly_clear) (TEMPLATE(T, poly_t) poly, + const TEMPLATE(T, ctx_t) ctx) +{ + if (poly->coeffs) + { + _TEMPLATE(T, vec_clear) (poly->coeffs, poly->alloc, ctx); + } +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/compose.c b/external/flint-2.4.3/fq_poly_templates/compose.c new file mode 100644 index 0000000..430a2d6 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/compose.c @@ -0,0 +1,90 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +_TEMPLATE(T, poly_compose) (TEMPLATE(T, struct) * rop, + const TEMPLATE(T, struct) * op1, slong len1, + const TEMPLATE(T, struct) * op2, slong len2, + const TEMPLATE(T, ctx_t) ctx) +{ + if (len1 == 1) + TEMPLATE(T, set) (rop + 0, op1 + 0, ctx); + else if (len2 == 1) + _TEMPLATE(T, TEMPLATE(poly_evaluate, T)) (rop + 0, op1, len1, op2 + 0, + ctx); + else if (len1 <= 4) + _TEMPLATE(T, poly_compose_horner) (rop, op1, len1, op2, len2, ctx); + else + _TEMPLATE(T, poly_compose_divconquer) (rop, op1, len1, op2, len2, ctx); +} + +void +TEMPLATE(T, poly_compose) (TEMPLATE(T, poly_t) rop, + const TEMPLATE(T, poly_t) op1, + const TEMPLATE(T, poly_t) op2, + const TEMPLATE(T, ctx_t) ctx) +{ + const slong len1 = op1->length; + const slong len2 = op2->length; + const slong lenr = (len1 - 1) * (len2 - 1) + 1; + + if (len1 == 0) + { + TEMPLATE(T, poly_zero) (rop, ctx); + } + else if (len1 == 1 || len2 == 0) + { + TEMPLATE(T, TEMPLATE(poly_set, T)) (rop, op1->coeffs + 0, ctx); + } + else if (rop != op1 && rop != op2) + { + TEMPLATE(T, poly_fit_length) (rop, lenr, ctx); + _TEMPLATE(T, poly_compose) (rop->coeffs, op1->coeffs, len1, + op2->coeffs, len2, ctx); + _TEMPLATE(T, poly_set_length) (rop, lenr, ctx); + _TEMPLATE(T, poly_normalise) (rop, ctx); + } + else + { + TEMPLATE(T, poly_t) t; + + TEMPLATE(T, poly_init2) (t, lenr, ctx); + _TEMPLATE(T, poly_compose) (t->coeffs, op1->coeffs, len1, op2->coeffs, + len2, ctx); + _TEMPLATE(T, poly_set_length) (t, lenr, ctx); + _TEMPLATE(T, poly_normalise) (t, ctx); + TEMPLATE(T, poly_swap) (rop, t, ctx); + TEMPLATE(T, poly_clear) (t, ctx); + } +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/compose_divconquer.c b/external/flint-2.4.3/fq_poly_templates/compose_divconquer.c new file mode 100644 index 0000000..62daf82 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/compose_divconquer.c @@ -0,0 +1,204 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +_TEMPLATE(T, poly_compose_divconquer) ( + TEMPLATE(T, struct) * rop, + const TEMPLATE(T, struct) * op1, slong len1, + const TEMPLATE(T, struct) * op2, slong len2, + const TEMPLATE(T, ctx_t) ctx) +{ + slong i, j, k, n; + slong *hlen, alloc, powlen; + TEMPLATE(T, struct) * v, **h, *pow, *temp; + + if (len1 <= 2 || len2 <= 1) + { + if (len1 == 1) + TEMPLATE(T, set) (rop, op1, ctx); + else if (len2 == 1) + _TEMPLATE(T, TEMPLATE(poly_evaluate, T)) (rop, op1, len1, op2, + ctx); + else /* len1 == 2 */ + _TEMPLATE(T, poly_compose_horner) (rop, op1, len1, op2, len2, ctx); + return; + } + + /* Initialisation */ + + hlen = (slong *) flint_malloc(((len1 + 1) / 2) * sizeof(slong)); + + k = FLINT_CLOG2(len1) - 1; + + hlen[0] = hlen[1] = ((1 << k) - 1) * (len2 - 1) + 1; + for (i = k - 1; i > 0; i--) + { + slong 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 = _TEMPLATE(T, vec_init) (alloc + 2 * powlen, ctx); + h = (TEMPLATE(T, struct) **) flint_malloc(((len1 + 1) / 2) * + sizeof(TEMPLATE(T, struct) *)); + 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 (!TEMPLATE(T, is_zero) (op1 + (j + 1), ctx)) + { + _TEMPLATE(T, TEMPLATE(poly_scalar_mul, T)) (h[i], op2, len2, + op1 + j + 1, ctx); + TEMPLATE(T, add) (h[i], h[i], op1 + j, ctx); + hlen[i] = len2; + } + else if (!TEMPLATE(T, is_zero) (op1 + j, ctx)) + { + TEMPLATE(T, set) (h[i], op1 + j, ctx); + hlen[i] = 1; + } + } + if ((len1 & WORD(1))) + { + if (!TEMPLATE(T, is_zero) (op1 + j, ctx)) + { + TEMPLATE(T, set) (h[i], op1 + j, ctx); + hlen[i] = 1; + } + } + + _TEMPLATE(T, poly_sqr) (pow, op2, len2, ctx); + powlen = 2 * len2 - 1; + + for (n = (len1 + 1) / 2; n > 2; n = (n + 1) / 2) + { + if (hlen[1] > 0) + { + slong templen = powlen + hlen[1] - 1; + _TEMPLATE(T, poly_mul) (temp, pow, powlen, h[1], hlen[1], ctx); + _TEMPLATE(T, poly_add) (h[0], temp, templen, h[0], hlen[0], ctx); + hlen[0] = FLINT_MAX(hlen[0], templen); + } + + for (i = 1; i < n / 2; i++) + { + if (hlen[2 * i + 1] > 0) + { + _TEMPLATE(T, poly_mul) (h[i], pow, powlen, h[2 * i + 1], + hlen[2 * i + 1], ctx); + hlen[i] = hlen[2 * i + 1] + powlen - 1; + } + else + hlen[i] = 0; + _TEMPLATE(T, poly_add) (h[i], h[i], hlen[i], h[2 * i], hlen[2 * i], + ctx); + hlen[i] = FLINT_MAX(hlen[i], hlen[2 * i]); + } + if ((n & WORD(1))) + { + _TEMPLATE(T, poly_set) (h[i], h[2 * i], hlen[2 * i], ctx); + hlen[i] = hlen[2 * i]; + } + + _TEMPLATE(T, poly_sqr) (temp, pow, powlen, ctx); + powlen += powlen - 1; + { + TEMPLATE(T, struct) * t = pow; + pow = temp; + temp = t; + } + } + + _TEMPLATE(T, poly_mul) (rop, pow, powlen, h[1], hlen[1], ctx); + _TEMPLATE(T, poly_add) (rop, rop, hlen[0], h[0], hlen[0], ctx); + + _TEMPLATE(T, vec_clear) (v, alloc + 2 * powlen, ctx); + flint_free(h); + flint_free(hlen); +} + +void +TEMPLATE(T, poly_compose_divconquer) (TEMPLATE(T, poly_t) rop, + const TEMPLATE(T, poly_t) op1, + const TEMPLATE(T, poly_t) op2, + const TEMPLATE(T, ctx_t) ctx) +{ + const slong len1 = op1->length; + const slong len2 = op2->length; + const slong lenr = (len1 - 1) * (len2 - 1) + 1; + + if (len1 == 0) + { + TEMPLATE(T, poly_zero) (rop, ctx); + } + else if (len1 == 1 || len2 == 0) + { + TEMPLATE(T, TEMPLATE(poly_set, T)) (rop, op1->coeffs + 0, ctx); + } + else if (rop != op1 && rop != op2) + { + TEMPLATE(T, poly_fit_length) (rop, lenr, ctx); + _TEMPLATE(T, poly_compose_divconquer) (rop->coeffs, op1->coeffs, len1, + op2->coeffs, len2, ctx); + _TEMPLATE(T, poly_set_length) (rop, lenr, ctx); + _TEMPLATE(T, poly_normalise) (rop, ctx); + } + else + { + TEMPLATE(T, poly_t) t; + + TEMPLATE(T, poly_init2) (t, lenr, ctx); + _TEMPLATE(T, poly_compose_divconquer) (t->coeffs, op1->coeffs, len1, + op2->coeffs, len2, ctx); + _TEMPLATE(T, poly_set_length) (t, lenr, ctx); + _TEMPLATE(T, poly_normalise) (t, ctx); + TEMPLATE(T, poly_swap) (rop, t, ctx); + TEMPLATE(T, poly_clear) (t, ctx); + } +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/compose_horner.c b/external/flint-2.4.3/fq_poly_templates/compose_horner.c new file mode 100644 index 0000000..62d7777 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/compose_horner.c @@ -0,0 +1,112 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +_TEMPLATE(T, poly_compose_horner) (TEMPLATE(T, struct) * rop, + const TEMPLATE(T, struct) * op1, slong len1, + const TEMPLATE(T, struct) * op2, slong len2, + const TEMPLATE(T, ctx_t) ctx) +{ + if (len1 == 1) + { + TEMPLATE(T, set) (rop, op1 + 0, ctx); + } + else + { + const slong alloc = (len1 - 1) * (len2 - 1) + 1; + + slong i = len1 - 1, lenr; + TEMPLATE(T, struct) * t = _TEMPLATE(T, vec_init) (alloc, ctx); + + /* + Perform the first two steps as one, + "res = a(m) * poly2 + a(m-1)". + */ + { + lenr = len2; + _TEMPLATE(T, TEMPLATE(poly_scalar_mul, T)) (rop, op2, len2, + op1 + i, ctx); + i--; + TEMPLATE(T, add) (rop + 0, rop + 0, op1 + i, ctx); + } + while (i--) + { + _TEMPLATE(T, poly_mul) (t, rop, lenr, op2, len2, ctx); + lenr += len2 - 1; + _TEMPLATE(T, poly_add) (rop, t, lenr, op1 + i, 1, ctx); + } + + _TEMPLATE(T, vec_clear) (t, alloc, ctx); + } +} + +void +TEMPLATE(T, poly_compose_horner) (TEMPLATE(T, poly_t) rop, + const TEMPLATE(T, poly_t) op1, + const TEMPLATE(T, poly_t) op2, + const TEMPLATE(T, ctx_t) ctx) +{ + const slong len1 = op1->length; + const slong len2 = op2->length; + const slong lenr = (len1 - 1) * (len2 - 1) + 1; + + if (len1 == 0) + { + TEMPLATE(T, poly_zero) (rop, ctx); + } + else if (len1 == 1 || len2 == 0) + { + TEMPLATE(T, TEMPLATE(poly_set, T)) (rop, op1->coeffs + 0, ctx); + } + else if (rop != op1 && rop != op2) + { + TEMPLATE(T, poly_fit_length) (rop, lenr, ctx); + _TEMPLATE(T, poly_compose_horner) (rop->coeffs, op1->coeffs, len1, + op2->coeffs, len2, ctx); + _TEMPLATE(T, poly_set_length) (rop, lenr, ctx); + _TEMPLATE(T, poly_normalise) (rop, ctx); + } + else + { + TEMPLATE(T, poly_t) t; + + TEMPLATE(T, poly_init2) (t, lenr, ctx); + _TEMPLATE(T, poly_compose_horner) (t->coeffs, op1->coeffs, len1, + op2->coeffs, len2, ctx); + _TEMPLATE(T, poly_set_length) (t, lenr, ctx); + _TEMPLATE(T, poly_normalise) (t, ctx); + TEMPLATE(T, poly_swap) (rop, t, ctx); + TEMPLATE(T, poly_clear) (t, ctx); + } +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/compose_mod.c b/external/flint-2.4.3/fq_poly_templates/compose_mod.c new file mode 100644 index 0000000..c4a00f5 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/compose_mod.c @@ -0,0 +1,122 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include "flint.h" +#include "ulong_extras.h" +void +_TEMPLATE(T, poly_compose_mod) (TEMPLATE(T, struct) * res, + const TEMPLATE(T, struct) * f, slong lenf, + const TEMPLATE(T, struct) * g, + const TEMPLATE(T, struct) * h, slong lenh, + const TEMPLATE(T, ctx_t) ctx) +{ + if (lenh < TEMPLATE(CAP_T, COMPOSE_MOD_LENH_CUTOFF) || lenf >= lenh) + _TEMPLATE(T, poly_compose_mod_horner) (res, f, lenf, g, h, lenh, ctx); + else + _TEMPLATE(T, poly_compose_mod_brent_kung) (res, f, lenf, g, h, lenh, + ctx); +} + +void +TEMPLATE(T, poly_compose_mod) (TEMPLATE(T, poly_t) res, + const TEMPLATE(T, poly_t) poly1, + const TEMPLATE(T, poly_t) poly2, + const TEMPLATE(T, poly_t) poly3, + const TEMPLATE(T, ctx_t) ctx) +{ + TEMPLATE(T, t) inv3; + slong len1 = poly1->length; + slong len2 = poly2->length; + slong len3 = poly3->length; + slong len = len3 - 1; + slong vec_len = FLINT_MAX(len3 - 1, len2); + + TEMPLATE(T, struct) * ptr2; + + if (len3 == 0) + { + TEMPLATE_PRINTF("Exception: division by zero in %s_poly_compose_mod\n", + T); + abort(); + } + + if (len1 == 0 || len3 == 1) + { + TEMPLATE(T, poly_zero) (res, ctx); + return; + } + + if (len1 == 1) + { + TEMPLATE(T, poly_set) (res, poly1, ctx); + return; + } + + if (res == poly3 || res == poly1) + { + TEMPLATE(T, poly_t) tmp; + TEMPLATE(T, poly_init) (tmp, ctx); + TEMPLATE(T, poly_compose_mod) (tmp, poly1, poly2, poly3, ctx); + TEMPLATE(T, poly_swap) (tmp, res, ctx); + TEMPLATE(T, poly_clear) (tmp, ctx); + return; + } + + ptr2 = _TEMPLATE(T, vec_init) (vec_len, ctx); + + if (len2 <= len) + { + _TEMPLATE(T, vec_set) (ptr2, poly2->coeffs, len2, ctx); + _TEMPLATE(T, vec_zero) (ptr2 + len2, len - len2, ctx); + } + else + { + TEMPLATE(T, init) (inv3, ctx); + TEMPLATE(T, inv) (inv3, poly3->coeffs + len, ctx); + _TEMPLATE(T, poly_rem) (ptr2, poly2->coeffs, len2, + poly3->coeffs, len3, inv3, ctx); + TEMPLATE(T, clear) (inv3, ctx); + } + + TEMPLATE(T, poly_fit_length) (res, len, ctx); + _TEMPLATE(T, poly_compose_mod) (res->coeffs, + poly1->coeffs, len1, ptr2, poly3->coeffs, + len3, ctx); + _TEMPLATE(T, poly_set_length) (res, len, ctx); + _TEMPLATE(T, poly_normalise) (res, ctx); + + _TEMPLATE(T, vec_clear) (ptr2, vec_len, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/compose_mod_brent_kung.c b/external/flint-2.4.3/fq_poly_templates/compose_mod_brent_kung.c new file mode 100644 index 0000000..18c6c1f --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/compose_mod_brent_kung.c @@ -0,0 +1,193 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +_TEMPLATE(T, poly_compose_mod_brent_kung) ( + TEMPLATE(T, struct) * res, + const TEMPLATE(T, struct) * poly1, slong len1, + const TEMPLATE(T, struct) * poly2, + const TEMPLATE(T, struct) * poly3, slong len3, + const TEMPLATE(T, ctx_t) ctx) +{ + TEMPLATE(T, mat_t) A, B, C; + TEMPLATE(T, struct) * t, *h, *tmp; + slong i, n, m; + + n = len3 - 1; + + if (len3 == 1) + return; + + if (len1 == 1) + { + TEMPLATE(T, set) (res, poly1, ctx); + return; + } + + if (len3 == 2) + { + _TEMPLATE(T, TEMPLATE(poly_evaluate, T)) (res, poly1, len1, poly2, + ctx); + return; + } + + m = n_sqrt(n) + 1; + + TEMPLATE(T, mat_init) (A, m, n, ctx); + TEMPLATE(T, mat_init) (B, m, m, ctx); + TEMPLATE(T, mat_init) (C, m, n, ctx); + + h = _TEMPLATE(T, vec_init) (2 * n - 1, ctx); + t = _TEMPLATE(T, vec_init) (2 * n - 1, ctx); + + /* Set rows of B to the segments of poly1 */ + for (i = 0; i < len1 / m; i++) + _TEMPLATE(T, vec_set) (B->rows[i], poly1 + i * m, m, ctx); + + _TEMPLATE(T, vec_set) (B->rows[i], poly1 + i * m, len1 % m, ctx); + + /* Set rows of A to powers of poly2 */ + TEMPLATE(T, one) (A->rows[0], ctx); + _TEMPLATE(T, vec_set) (A->rows[1], poly2, n, ctx); + tmp = _TEMPLATE(T, vec_init) (2 * n - 1, ctx); + for (i = 2; i < m; i++) + { + _TEMPLATE(T, poly_mulmod) (tmp, A->rows[i - 1], n, poly2, n, poly3, + len3, ctx); + _TEMPLATE(T, vec_set) (A->rows[i], tmp, n, ctx); + } + _TEMPLATE(T, vec_clear) (tmp, 2 * n - 1, ctx); + + TEMPLATE(T, mat_mul) (C, B, A, ctx); + + /* Evaluate block composition using the Horner scheme */ + _TEMPLATE(T, vec_set) (res, C->rows[m - 1], n, ctx); + _TEMPLATE(T, poly_mulmod) (h, A->rows[m - 1], n, poly2, n, poly3, len3, + ctx); + + for (i = m - 2; i >= 0; i--) + { + _TEMPLATE(T, poly_mulmod) (t, res, n, h, n, poly3, len3, ctx); + _TEMPLATE(T, poly_add) (res, t, n, C->rows[i], n, ctx); + } + + _TEMPLATE(T, vec_clear) (h, 2 * n - 1, ctx); + _TEMPLATE(T, vec_clear) (t, 2 * n - 1, ctx); + + TEMPLATE(T, mat_clear) (A, ctx); + TEMPLATE(T, mat_clear) (B, ctx); + TEMPLATE(T, mat_clear) (C, ctx); +} + +void +TEMPLATE(T, poly_compose_mod_brent_kung) (TEMPLATE(T, poly_t) res, + const TEMPLATE(T, poly_t) poly1, + const TEMPLATE(T, poly_t) poly2, + const TEMPLATE(T, poly_t) poly3, + const TEMPLATE(T, ctx_t) ctx) +{ + slong len1 = poly1->length; + slong len2 = poly2->length; + slong len3 = poly3->length; + slong len = len3 - 1; + slong vec_len = FLINT_MAX(len3 - 1, len2); + + TEMPLATE(T, struct) * ptr2; + TEMPLATE(T, t) inv3; + + if (len3 == 0) + { + flint_printf("Exception: division by zero in"); + TEMPLATE_PRINTF("%s_poly_compose_mod_brent_kung\n", T); + abort(); + } + + if (len1 >= len3) + { + TEMPLATE_PRINTF + ("Exception: %s_poly_compose_brent_kung: the degree of the", T); + flint_printf + (" first polynomial must be smaller than that of the modulus\n"); + abort(); + } + + if (len1 == 0 || len3 == 1) + { + TEMPLATE(T, poly_zero) (res, ctx); + return; + } + + if (len1 == 1) + { + TEMPLATE(T, poly_set) (res, poly1, ctx); + return; + } + + if (res == poly3 || res == poly1) + { + TEMPLATE(T, poly_t) tmp; + TEMPLATE(T, poly_init) (tmp, ctx); + TEMPLATE(T, poly_compose_mod_brent_kung) (tmp, poly1, poly2, poly3, + ctx); + TEMPLATE(T, poly_swap) (tmp, res, ctx); + TEMPLATE(T, poly_clear) (tmp, ctx); + return; + } + + ptr2 = _TEMPLATE(T, vec_init) (vec_len, ctx); + + if (len2 <= len) + { + _TEMPLATE(T, vec_set) (ptr2, poly2->coeffs, len2, ctx); + _TEMPLATE(T, vec_zero) (ptr2 + len2, vec_len - len2, ctx); + } + else + { + TEMPLATE(T, init) (inv3, ctx); + TEMPLATE(T, inv) (inv3, poly3->coeffs + len, ctx); + _TEMPLATE(T, poly_rem) (ptr2, poly2->coeffs, len2, + poly3->coeffs, len3, inv3, ctx); + TEMPLATE(T, clear) (inv3, ctx); + } + + TEMPLATE(T, poly_fit_length) (res, len, ctx); + _TEMPLATE(T, poly_compose_mod_brent_kung) (res->coeffs, poly1->coeffs, + len1, ptr2, poly3->coeffs, len3, + ctx); + _TEMPLATE(T, poly_set_length) (res, len, ctx); + _TEMPLATE(T, poly_normalise) (res, ctx); + + _TEMPLATE(T, vec_clear) (ptr2, vec_len, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/compose_mod_brent_kung_precomp_preinv.c b/external/flint-2.4.3/fq_poly_templates/compose_mod_brent_kung_precomp_preinv.c new file mode 100644 index 0000000..9448e08 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/compose_mod_brent_kung_precomp_preinv.c @@ -0,0 +1,275 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2013 Martin Lee + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include "flint.h" +#include "ulong_extras.h" + +void +_TEMPLATE(T, poly_reduce_matrix_mod_poly) (TEMPLATE(T, mat_t) A, + const TEMPLATE(T, mat_t) B, + const TEMPLATE(T, poly_t) f, + const TEMPLATE(T, ctx_t) ctx) +{ + slong n = f->length - 1; + slong i, m = n_sqrt(n) + 1; + TEMPLATE(T, t) invf; + + TEMPLATE(T, mat_init) (A, m, n, ctx); + + TEMPLATE(T, one) (TEMPLATE(T, mat_entry) (A, 0, 0), ctx); + TEMPLATE(T, init) (invf, ctx); + TEMPLATE(T, inv) (invf, f->coeffs + (f->length - 1), ctx); + for (i = 1; i < m; i++) + _TEMPLATE(T, poly_rem) (A->rows[i], B->rows[i], B->c, f->coeffs, + f->length, invf, ctx); + TEMPLATE(T, clear) (invf, ctx); +} + +void +_TEMPLATE(T, poly_precompute_matrix) ( + TEMPLATE(T, mat_t) A, + const TEMPLATE(T, struct) * poly1, + const TEMPLATE(T, struct) * poly2, slong len2, + const TEMPLATE(T, struct) * poly2inv, slong len2inv, + const TEMPLATE(T, ctx_t) ctx) +{ + /* Set rows of A to powers of poly1 */ + slong i, n, m; + + n = len2 - 1; + + m = n_sqrt(n) + 1; + + TEMPLATE(T, one) (TEMPLATE(T, mat_entry) (A, 0, 0), ctx); + _TEMPLATE(T, vec_set) (A->rows[1], poly1, n, ctx); + for (i = 2; i < m; i++) + _TEMPLATE(T, poly_mulmod_preinv) (A->rows[i], A->rows[i - 1], + n, poly1, n, poly2, len2, + poly2inv, len2inv, ctx); +} + +void +TEMPLATE(T, poly_precompute_matrix) (TEMPLATE(T, mat_t) A, + const TEMPLATE(T, poly_t) poly1, + const TEMPLATE(T, poly_t) poly2, + const TEMPLATE(T, poly_t) poly2inv, + const TEMPLATE(T, ctx_t) ctx) +{ + slong len1 = poly1->length; + slong len2 = poly2->length; + slong len = len2 - 1; + slong m = n_sqrt(len) + 1; + + TEMPLATE(T, struct) * ptr1; + + if (len2 == 0) + { + flint_printf + ("Exception (nmod_poly_compose_mod_brent_kung). Division by zero.\n"); + abort(); + } + + if (A->r != m || A->c != len) + { + flint_printf + ("Exception (nmod_poly_compose_mod_brent_kung). Wrong dimensions.\n"); + abort(); + } + + if (len2 == 1) + { + TEMPLATE(T, mat_zero) (A, ctx); + return; + } + + ptr1 = _TEMPLATE(T, vec_init) (len, ctx); + + if (len1 <= len) + { + _TEMPLATE(T, vec_set) (ptr1, poly1->coeffs, len1, ctx); + _TEMPLATE(T, vec_zero) (ptr1 + len1, len - len1, ctx); + } + else + { + TEMPLATE(T, t) inv2; + TEMPLATE(T, init) (inv2, ctx); + TEMPLATE(T, inv) (inv2, poly2->coeffs + len2 - 1, ctx); + _TEMPLATE(T, poly_rem) (ptr1, poly1->coeffs, len1, + poly2->coeffs, len2, inv2, ctx); + TEMPLATE(T, clear) (inv2, ctx); + } + + _TEMPLATE(T, poly_precompute_matrix) (A, ptr1, poly2->coeffs, len2, + poly2inv->coeffs, poly2inv->length, + ctx); + + _TEMPLATE(T, vec_clear) (ptr1, len, ctx); +} + +void +_TEMPLATE(T, poly_compose_mod_brent_kung_precomp_preinv) ( + TEMPLATE(T, struct) * res, + const TEMPLATE(T, struct) * poly1, slong len1, + const TEMPLATE(T, mat_t) A, + const TEMPLATE(T, struct) * poly3, slong len3, + const TEMPLATE(T, struct) * poly3inv, slong len3inv, + const TEMPLATE(T, ctx_t) ctx) +{ + TEMPLATE(T, mat_t) B, C; + TEMPLATE(T, struct) * t, *h; + slong i, n, m; + + n = len3 - 1; + + if (len3 == 1) + return; + + if (len1 == 1) + { + TEMPLATE(T, set) (res, poly1, ctx); + return; + } + + if (len3 == 2) + { + _TEMPLATE3(T, poly_evaluate, T) (res, poly1, len1, + TEMPLATE(T, mat_entry) (A, 1, 0), + ctx); + return; + } + + m = n_sqrt(n) + 1; + + /* TODO check A */ + + TEMPLATE(T, mat_init) (B, m, m, ctx); + TEMPLATE(T, mat_init) (C, m, n, ctx); + + h = _TEMPLATE(T, vec_init) (n, ctx); + t = _TEMPLATE(T, vec_init) (n, ctx); + + /* Set rows of B to the segments of poly1 */ + for (i = 0; i < len1 / m; i++) + _TEMPLATE(T, vec_set) (B->rows[i], poly1 + i * m, m, ctx); + + _TEMPLATE(T, vec_set) (B->rows[i], poly1 + i * m, len1 % m, ctx); + + TEMPLATE(T, mat_mul) (C, B, A, ctx); + + /* Evaluate block composition using the Horner scheme */ + _TEMPLATE(T, vec_set) (res, C->rows[m - 1], n, ctx); + _TEMPLATE(T, poly_mulmod_preinv) (h, A->rows[m - 1], n, A->rows[1], n, + poly3, len3, poly3inv, len3inv, ctx); + + for (i = m - 2; i >= 0; i--) + { + _TEMPLATE(T, poly_mulmod_preinv) (t, res, n, h, n, poly3, len3, + poly3inv, len3inv, ctx); + _TEMPLATE(T, poly_add) (res, t, n, C->rows[i], n, ctx); + } + + _TEMPLATE(T, vec_clear) (h, n, ctx); + _TEMPLATE(T, vec_clear) (t, n, ctx); + + TEMPLATE(T, mat_clear) (B, ctx); + TEMPLATE(T, mat_clear) (C, ctx); +} + +void +TEMPLATE(T, poly_compose_mod_brent_kung_precomp_preinv) ( + TEMPLATE(T, poly_t) res, + const TEMPLATE(T, poly_t) poly1, const TEMPLATE(T, mat_t) A, + const TEMPLATE(T, poly_t) poly3, const TEMPLATE(T, poly_t) poly3inv, + const TEMPLATE(T, ctx_t) ctx) +{ + slong len1 = poly1->length; + slong len3 = poly3->length; + slong len = len3 - 1; + + if (len3 == 0) + { + TEMPLATE_PRINTF + ("Exception (%s_poly_compose_mod_brent_kung). Division by zero.\n", + T); + abort(); + } + + if (len1 >= len3) + { + TEMPLATE_PRINTF + ("Exception (%s_poly_compose_brent_kung). The degree of the \n", + T); + flint_printf + ("first polynomial must be smaller than that of the modulus.\n"); + abort(); + } + + if (len1 == 0 || len3 == 1) + { + TEMPLATE(T, poly_zero) (res, ctx); + return; + } + + if (len1 == 1) + { + TEMPLATE(T, poly_set) (res, poly1, ctx); + return; + } + + if (res == poly3 || res == poly1 || res == poly3inv) + { + TEMPLATE(T, poly_t) tmp; + TEMPLATE(T, poly_init) (tmp, ctx); + TEMPLATE(T, poly_compose_mod_brent_kung_precomp_preinv) (tmp, poly1, A, + poly3, + poly3inv, + ctx); + TEMPLATE(T, poly_swap) (tmp, res, ctx); + TEMPLATE(T, poly_clear) (tmp, ctx); + return; + } + + TEMPLATE(T, poly_fit_length) (res, len, ctx); + _TEMPLATE(T, poly_compose_mod_brent_kung_precomp_preinv) (res->coeffs, + poly1->coeffs, + len1, A, + poly3->coeffs, + len3, + poly3inv->coeffs, + poly3inv->length, + ctx); + res->length = len; + _TEMPLATE(T, poly_normalise) (res, ctx); + +} +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/compose_mod_brent_kung_preinv.c b/external/flint-2.4.3/fq_poly_templates/compose_mod_brent_kung_preinv.c new file mode 100644 index 0000000..9e9700d --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/compose_mod_brent_kung_preinv.c @@ -0,0 +1,201 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Martin Lee + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +_TEMPLATE(T, poly_compose_mod_brent_kung_preinv) ( + TEMPLATE(T, struct) * res, + const TEMPLATE(T, struct) * poly1, slong len1, + const TEMPLATE(T, struct) * poly2, + const TEMPLATE(T, struct) * poly3, slong len3, + const TEMPLATE(T, struct) * poly3inv, slong len3inv, + const TEMPLATE(T, ctx_t) ctx) +{ + TEMPLATE(T, mat_t) A, B, C; + TEMPLATE(T, struct) * t, *h, *tmp; + slong i, n, m; + + n = len3 - 1; + + if (len3 == 1) + return; + + if (len1 == 1) + { + TEMPLATE(T, set) (res, poly1, ctx); + return; + } + + if (len3 == 2) + { + _TEMPLATE(T, TEMPLATE(poly_evaluate, T)) (res, poly1, len1, poly2, + ctx); + return; + } + + m = n_sqrt(n) + 1; + + TEMPLATE(T, mat_init) (A, m, n, ctx); + TEMPLATE(T, mat_init) (B, m, m, ctx); + TEMPLATE(T, mat_init) (C, m, n, ctx); + + h = _TEMPLATE(T, vec_init) (2 * n - 1, ctx); + t = _TEMPLATE(T, vec_init) (2 * n - 1, ctx); + + /* Set rows of B to the segments of poly1 */ + for (i = 0; i < len1 / m; i++) + _TEMPLATE(T, vec_set) (B->rows[i], poly1 + i * m, m, ctx); + + _TEMPLATE(T, vec_set) (B->rows[i], poly1 + i * m, len1 % m, ctx); + + /* Set rows of A to powers of poly2 */ + TEMPLATE(T, one) (A->rows[0], ctx); + _TEMPLATE(T, vec_set) (A->rows[1], poly2, n, ctx); + tmp = _TEMPLATE(T, vec_init) (2 * n - 1, ctx); + for (i = 2; i < m; i++) + { + _TEMPLATE(T, poly_mulmod_preinv) (tmp, A->rows[i - 1], n, poly2, n, + poly3, len3, poly3inv, len3inv, ctx); + _TEMPLATE(T, vec_set) (A->rows[i], tmp, n, ctx); + } + _TEMPLATE(T, vec_clear) (tmp, 2 * n - 1, ctx); + + TEMPLATE(T, mat_mul) (C, B, A, ctx); + + /* Evaluate block composition using the Horner scheme */ + _TEMPLATE(T, vec_set) (res, C->rows[m - 1], n, ctx); + _TEMPLATE(T, poly_mulmod_preinv) (h, A->rows[m - 1], n, poly2, n, poly3, + len3, poly3inv, len3inv, ctx); + + for (i = m - 2; i >= 0; i--) + { + _TEMPLATE(T, poly_mulmod_preinv) (t, res, n, h, n, poly3, len3, + poly3inv, len3inv, ctx); + _TEMPLATE(T, poly_add) (res, t, n, C->rows[i], n, ctx); + } + + _TEMPLATE(T, vec_clear) (h, 2 * n - 1, ctx); + _TEMPLATE(T, vec_clear) (t, 2 * n - 1, ctx); + + TEMPLATE(T, mat_clear) (A, ctx); + TEMPLATE(T, mat_clear) (B, ctx); + TEMPLATE(T, mat_clear) (C, ctx); +} + +void +TEMPLATE(T, poly_compose_mod_brent_kung_preinv) ( + TEMPLATE(T, poly_t) res, + const TEMPLATE(T, poly_t) poly1, + const TEMPLATE(T, poly_t) poly2, + const TEMPLATE(T, poly_t) poly3, + const TEMPLATE(T, poly_t) poly3inv, + const TEMPLATE(T, ctx_t) ctx) +{ + slong len1 = poly1->length; + slong len2 = poly2->length; + slong len3 = poly3->length; + slong len3inv = poly3inv->length; + slong len = len3 - 1; + slong vec_len = FLINT_MAX(len3 - 1, len2); + + TEMPLATE(T, struct) * ptr2; + TEMPLATE(T, t) inv3; + + if (len3 == 0) + { + flint_printf("Exception: division by zero in "); + TEMPLATE_PRINTF("%s_poly_compose_mod_brent_kung_preinv\n", T); + abort(); + } + + if (len1 >= len3) + { + TEMPLATE_PRINTF + ("Exception: %s_poly_compose_brent_kung: the degree of the", T); + flint_printf + (" first polynomial must be smaller than that of the modulus\n"); + abort(); + } + + if (len1 == 0 || len3 == 1) + { + TEMPLATE(T, poly_zero) (res, ctx); + return; + } + + if (len1 == 1) + { + TEMPLATE(T, poly_set) (res, poly1, ctx); + return; + } + + if (res == poly3 || res == poly1) + { + TEMPLATE(T, poly_t) tmp; + TEMPLATE(T, poly_init) (tmp, ctx); + TEMPLATE(T, poly_compose_mod_brent_kung_preinv) (tmp, poly1, poly2, + poly3, poly3inv, ctx); + TEMPLATE(T, poly_swap) (tmp, res, ctx); + TEMPLATE(T, poly_clear) (tmp, ctx); + return; + } + + ptr2 = _TEMPLATE(T, vec_init) (vec_len, ctx); + + if (len2 <= len) + { + _TEMPLATE(T, vec_set) (ptr2, poly2->coeffs, len2, ctx); + _TEMPLATE(T, vec_zero) (ptr2 + len2, vec_len - len2, ctx); + } + else + { + TEMPLATE(T, init) (inv3, ctx); + TEMPLATE(T, inv) (inv3, poly3->coeffs + len, ctx); + _TEMPLATE(T, poly_rem) (ptr2, poly2->coeffs, len2, + poly3->coeffs, len3, inv3, ctx); + TEMPLATE(T, clear) (inv3, ctx); + } + + TEMPLATE(T, poly_fit_length) (res, len, ctx); + _TEMPLATE(T, poly_compose_mod_brent_kung_preinv) (res->coeffs, + poly1->coeffs, len1, + ptr2, poly3->coeffs, + len3, poly3inv->coeffs, + len3inv, ctx); + _TEMPLATE(T, poly_set_length) (res, len, ctx); + _TEMPLATE(T, poly_normalise) (res, ctx); + + _TEMPLATE(T, vec_clear) (ptr2, vec_len, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/compose_mod_horner.c b/external/flint-2.4.3/fq_poly_templates/compose_mod_horner.c new file mode 100644 index 0000000..2adffe1 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/compose_mod_horner.c @@ -0,0 +1,155 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include "flint.h" +#include "ulong_extras.h" +void +_TEMPLATE(T, poly_compose_mod_horner) ( + TEMPLATE(T, struct) * res, + const TEMPLATE(T, struct) * f, slong lenf, + const TEMPLATE(T, struct) * g, + const TEMPLATE(T, struct) * h, slong lenh, + const TEMPLATE(T, ctx_t) ctx) +{ + slong i, len; + TEMPLATE(T, struct) * t; + + if (lenh == 1) + return; + + if (lenf == 1) + { + TEMPLATE(T, set) (res, f, ctx); + return; + } + + if (lenh == 2) + { + _TEMPLATE(T, TEMPLATE(poly_evaluate, T)) (res, f, lenf, g, ctx); + return; + } + + len = lenh - 1; + i = lenf - 1; + t = _TEMPLATE(T, vec_init) (2 * lenh - 3, ctx); + + _TEMPLATE(T, TEMPLATE(poly_scalar_mul, T)) (res, g, len, f + i, ctx); + i--; + if (i >= 0) + { + TEMPLATE(T, add) (res, res, f + i, ctx); + } + + while (i > 0) + { + i--; + _TEMPLATE(T, poly_mulmod) (t, res, len, g, len, h, lenh, ctx); + _TEMPLATE(T, poly_add) (res, t, len, f + i, 1, ctx); + } + + _TEMPLATE(T, vec_clear) (t, 2 * lenh - 3, ctx); +} + +void +TEMPLATE(T, poly_compose_mod_horner) (TEMPLATE(T, poly_t) res, + const TEMPLATE(T, poly_t) poly1, + const TEMPLATE(T, poly_t) poly2, + const TEMPLATE(T, poly_t) poly3, + const TEMPLATE(T, ctx_t) ctx) +{ + TEMPLATE(T, t) inv3; + slong len1 = poly1->length; + slong len2 = poly2->length; + slong len3 = poly3->length; + slong len = len3 - 1; + slong vec_len = FLINT_MAX(len3 - 1, len2); + + TEMPLATE(T, struct) * ptr2; + + if (len3 == 0) + { + TEMPLATE_PRINTF + ("Exception: division by zero in %s_poly_compose_mod_horner\n", T); + abort(); + } + + if (len1 == 0 || len3 == 1) + { + TEMPLATE(T, poly_zero) (res, ctx); + return; + } + + if (len1 == 1) + { + TEMPLATE(T, poly_set) (res, poly1, ctx); + return; + } + + if (res == poly3 || res == poly1) + { + TEMPLATE(T, poly_t) tmp; + TEMPLATE(T, poly_init) (tmp, ctx); + TEMPLATE(T, poly_compose_mod_horner) (tmp, poly1, poly2, poly3, ctx); + TEMPLATE(T, poly_swap) (tmp, res, ctx); + TEMPLATE(T, poly_clear) (tmp, ctx); + return; + } + + ptr2 = _TEMPLATE(T, vec_init) (vec_len, ctx); + + if (len2 <= len3 - 1) + { + _TEMPLATE(T, vec_set) (ptr2, poly2->coeffs, len2, ctx); + _TEMPLATE(T, vec_zero) (ptr2 + len2, vec_len - len2, ctx); + } + else + { + TEMPLATE(T, init) (inv3, ctx); + TEMPLATE(T, inv) (inv3, poly3->coeffs + len, ctx); + _TEMPLATE(T, poly_rem) (ptr2, poly2->coeffs, len2, + poly3->coeffs, len3, inv3, ctx); + TEMPLATE(T, clear) (inv3, ctx); + } + + TEMPLATE(T, poly_fit_length) (res, len, ctx); + _TEMPLATE(T, poly_compose_mod_horner) (res->coeffs, + poly1->coeffs, len1, + ptr2, poly3->coeffs, len3, ctx); + _TEMPLATE(T, poly_set_length) (res, len, ctx); + _TEMPLATE(T, poly_normalise) (res, ctx); + + _TEMPLATE(T, vec_clear) (ptr2, vec_len, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/compose_mod_horner_preinv.c b/external/flint-2.4.3/fq_poly_templates/compose_mod_horner_preinv.c new file mode 100644 index 0000000..5849ac6 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/compose_mod_horner_preinv.c @@ -0,0 +1,164 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include "flint.h" +#include "ulong_extras.h" +void +_TEMPLATE(T, poly_compose_mod_horner_preinv) ( + TEMPLATE(T, struct) * res, + const TEMPLATE(T, struct) * f, slong lenf, + const TEMPLATE(T, struct) * g, + const TEMPLATE(T, struct) * h, slong lenh, + const TEMPLATE(T, struct) * hinv, slong lenhinv, + const TEMPLATE(T, ctx_t) ctx) +{ + slong i, len; + TEMPLATE(T, struct) * t; + + if (lenh == 1) + return; + + if (lenf == 1) + { + TEMPLATE(T, set) (res, f, ctx); + return; + } + + if (lenh == 2) + { + _TEMPLATE(T, TEMPLATE(poly_evaluate, T)) (res, f, lenf, g, ctx); + return; + } + + len = lenh - 1; + i = lenf - 1; + t = _TEMPLATE(T, vec_init) (2 * lenh - 3, ctx); + + _TEMPLATE(T, TEMPLATE(poly_scalar_mul, T)) (res, g, len, f + i, ctx); + i--; + if (i >= 0) + { + TEMPLATE(T, add) (res, res, f + i, ctx); + } + + while (i > 0) + { + i--; + _TEMPLATE(T, poly_mulmod_preinv) (t, res, len, g, len, h, lenh, hinv, + lenhinv, ctx); + _TEMPLATE(T, poly_add) (res, t, len, f + i, 1, ctx); + } + + _TEMPLATE(T, vec_clear) (t, 2 * lenh - 3, ctx); +} + +void +TEMPLATE(T, poly_compose_mod_horner_preinv) ( + TEMPLATE(T, poly_t) res, + const TEMPLATE(T, poly_t) poly1, + const TEMPLATE(T, poly_t) poly2, + const TEMPLATE(T, poly_t) poly3, + const TEMPLATE(T, poly_t) poly3inv, + const TEMPLATE(T, ctx_t) ctx) +{ + TEMPLATE(T, t) inv3; + slong len1 = poly1->length; + slong len2 = poly2->length; + slong len3 = poly3->length; + slong len3inv = poly3inv->length; + slong len = len3 - 1; + slong vec_len = FLINT_MAX(len3 - 1, len2); + + TEMPLATE(T, struct) * ptr2; + + if (len3 == 0) + { + TEMPLATE_PRINTF + ("Exception: division by zero in %s_poly_compose_mod_horner\n", T); + abort(); + } + + if (len1 == 0 || len3 == 1) + { + TEMPLATE(T, poly_zero) (res, ctx); + return; + } + + if (len1 == 1) + { + TEMPLATE(T, poly_set) (res, poly1, ctx); + return; + } + + if (res == poly3 || res == poly1) + { + TEMPLATE(T, poly_t) tmp; + TEMPLATE(T, poly_init) (tmp, ctx); + TEMPLATE(T, poly_compose_mod_horner_preinv) (tmp, poly1, poly2, poly3, + poly3inv, ctx); + TEMPLATE(T, poly_swap) (tmp, res, ctx); + TEMPLATE(T, poly_clear) (tmp, ctx); + return; + } + + ptr2 = _TEMPLATE(T, vec_init) (vec_len, ctx); + + if (len2 <= len3 - 1) + { + _TEMPLATE(T, vec_set) (ptr2, poly2->coeffs, len2, ctx); + _TEMPLATE(T, vec_zero) (ptr2 + len2, vec_len - len2, ctx); + } + else + { + TEMPLATE(T, init) (inv3, ctx); + TEMPLATE(T, inv) (inv3, poly3->coeffs + len, ctx); + _TEMPLATE(T, poly_rem) (ptr2, poly2->coeffs, len2, + poly3->coeffs, len3, inv3, ctx); + TEMPLATE(T, clear) (inv3, ctx); + } + + TEMPLATE(T, poly_fit_length) (res, len, ctx); + _TEMPLATE(T, poly_compose_mod_horner_preinv) (res->coeffs, + poly1->coeffs, len1, + ptr2, + poly3->coeffs, len3, + poly3inv->coeffs, len3inv, + ctx); + _TEMPLATE(T, poly_set_length) (res, len, ctx); + _TEMPLATE(T, poly_normalise) (res, ctx); + + _TEMPLATE(T, vec_clear) (ptr2, vec_len, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/compose_mod_preinv.c b/external/flint-2.4.3/fq_poly_templates/compose_mod_preinv.c new file mode 100644 index 0000000..6f8464d --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/compose_mod_preinv.c @@ -0,0 +1,131 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include "flint.h" +#include "ulong_extras.h" +void +_TEMPLATE(T, poly_compose_mod_preinv) ( + TEMPLATE(T, struct) * res, + const TEMPLATE(T, struct) * f, slong lenf, + const TEMPLATE(T, struct) * g, + const TEMPLATE(T, struct) * h, slong lenh, + const TEMPLATE(T, struct) * hinv, slong lenhinv, + const TEMPLATE(T, ctx_t) ctx) +{ + if (lenh < TEMPLATE(CAP_T, COMPOSE_MOD_PREINV_LENH_CUTOFF) || lenf >= lenh) + _TEMPLATE(T, poly_compose_mod_horner_preinv) (res, f, lenf, g, h, lenh, + hinv, lenhinv, ctx); + else + _TEMPLATE(T, poly_compose_mod_brent_kung_preinv) (res, f, lenf, g, h, + lenh, hinv, lenhinv, + ctx); +} + +void +TEMPLATE(T, poly_compose_mod_preinv) (TEMPLATE(T, poly_t) res, + const TEMPLATE(T, poly_t) poly1, + const TEMPLATE(T, poly_t) poly2, + const TEMPLATE(T, poly_t) poly3, + const TEMPLATE(T, poly_t) poly3inv, + const TEMPLATE(T, ctx_t) ctx) +{ + TEMPLATE(T, t) inv3; + slong len1 = poly1->length; + slong len2 = poly2->length; + slong len3 = poly3->length; + slong len3inv = poly3inv->length; + slong len = len3 - 1; + slong vec_len = FLINT_MAX(len3 - 1, len2); + + TEMPLATE(T, struct) * ptr2; + + if (len3 == 0) + { + TEMPLATE_PRINTF("Exception: division by zero in %s_poly_compose_mod\n", + T); + abort(); + } + + if (len1 == 0 || len3 == 1) + { + TEMPLATE(T, poly_zero) (res, ctx); + return; + } + + if (len1 == 1) + { + TEMPLATE(T, poly_set) (res, poly1, ctx); + return; + } + + if (res == poly3 || res == poly1) + { + TEMPLATE(T, poly_t) tmp; + TEMPLATE(T, poly_init) (tmp, ctx); + TEMPLATE(T, poly_compose_mod_preinv) (tmp, poly1, poly2, poly3, + poly3inv, ctx); + TEMPLATE(T, poly_swap) (tmp, res, ctx); + TEMPLATE(T, poly_clear) (tmp, ctx); + return; + } + + ptr2 = _TEMPLATE(T, vec_init) (vec_len, ctx); + + if (len2 <= len) + { + _TEMPLATE(T, vec_set) (ptr2, poly2->coeffs, len2, ctx); + _TEMPLATE(T, vec_zero) (ptr2 + len2, len - len2, ctx); + } + else + { + TEMPLATE(T, init) (inv3, ctx); + TEMPLATE(T, inv) (inv3, poly3->coeffs + len, ctx); + _TEMPLATE(T, poly_rem) (ptr2, poly2->coeffs, len2, + poly3->coeffs, len3, inv3, ctx); + TEMPLATE(T, clear) (inv3, ctx); + } + + TEMPLATE(T, poly_fit_length) (res, len, ctx); + _TEMPLATE(T, poly_compose_mod_preinv) (res->coeffs, + poly1->coeffs, len1, + ptr2, + poly3->coeffs, len3, + poly3inv->coeffs, len3inv, ctx); + _TEMPLATE(T, poly_set_length) (res, len, ctx); + _TEMPLATE(T, poly_normalise) (res, ctx); + + _TEMPLATE(T, vec_clear) (ptr2, vec_len, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/deflate.c b/external/flint-2.4.3/fq_poly_templates/deflate.c new file mode 100644 index 0000000..47bb923 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/deflate.c @@ -0,0 +1,61 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + Copyright (C) 2013 Mike Hansen +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +TEMPLATE(T, poly_deflate) (TEMPLATE(T, poly_t) result, + const TEMPLATE(T, poly_t) input, ulong deflation, + const TEMPLATE(T, ctx_t) ctx) +{ + slong res_length, i; + + if (deflation == 0) + { + TEMPLATE_PRINTF("Exception (%s_poly_deflate). Division by zero.\n", T); + abort(); + } + + if (input->length <= 1 || deflation == 1) + { + TEMPLATE(T, poly_set) (result, input, ctx); + return; + } + + res_length = (input->length - 1) / deflation + 1; + TEMPLATE(T, poly_fit_length) (result, res_length, ctx); + for (i = 0; i < res_length; i++) + TEMPLATE(T, set) (result->coeffs + i, input->coeffs + (i * deflation), + ctx); + + result->length = res_length; +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/deflation.c b/external/flint-2.4.3/fq_poly_templates/deflation.c new file mode 100644 index 0000000..0af8e09 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/deflation.c @@ -0,0 +1,65 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +ulong +TEMPLATE(T, poly_deflation) (const TEMPLATE(T, poly_t) input, + const TEMPLATE(T, ctx_t) ctx) +{ + ulong deflation; + slong i, coeff; + + if (input->length <= 1) + return input->length; + + coeff = 1; + while (TEMPLATE(T, is_zero) (input->coeffs + coeff, ctx)) + coeff++; + + deflation = n_gcd_full(input->length - 1, coeff); + + while ((deflation > 1) && (coeff + deflation < input->length)) + { + for (i = 0; i < deflation - 1; i++) + { + coeff++; + if (!TEMPLATE(T, is_zero) (input->coeffs + coeff, ctx)) + deflation = n_gcd_full(coeff, deflation); + } + if (i == deflation - 1) + coeff++; + } + + return deflation; +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/derivative.c b/external/flint-2.4.3/fq_poly_templates/derivative.c new file mode 100644 index 0000000..9261755 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/derivative.c @@ -0,0 +1,64 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +_TEMPLATE(T, poly_derivative) (TEMPLATE(T, struct) * rop, + const TEMPLATE(T, struct) * op, slong len, + const TEMPLATE(T, ctx_t) ctx) +{ + slong i; + + for (i = 1; i < len; i++) + TEMPLATE(T, mul_ui) (rop + (i - 1), op + i, i, ctx); +} + +void +TEMPLATE(T, poly_derivative) (TEMPLATE(T, poly_t) rop, + const TEMPLATE(T, poly_t) op, + const TEMPLATE(T, ctx_t) ctx) +{ + const slong len = op->length; + + if (len < 2) + { + TEMPLATE(T, poly_zero) (rop, ctx); + } + else + { + TEMPLATE(T, poly_fit_length) (rop, len - 1, ctx); + _TEMPLATE(T, poly_derivative) (rop->coeffs, op->coeffs, len, ctx); + _TEMPLATE(T, poly_set_length) (rop, len - 1, ctx); + _TEMPLATE(T, poly_normalise) (rop, ctx); + } +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/div_basecase.c b/external/flint-2.4.3/fq_poly_templates/div_basecase.c new file mode 100644 index 0000000..85ecdb3 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/div_basecase.c @@ -0,0 +1,125 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2010 Sebastian Pancratz + Copyright (C) 2008, 2009 William Hart + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +_TEMPLATE(T, poly_div_basecase) (TEMPLATE(T, struct) * Q, + TEMPLATE(T, struct) * R, + const TEMPLATE(T, struct) * A, slong lenA, + const TEMPLATE(T, struct) * B, slong lenB, + const TEMPLATE(T, t) invB, + const TEMPLATE(T, ctx_t) ctx) +{ + const slong alloc = (R == NULL) ? lenA : 0; + slong lenR = lenB - 1, iQ; + + if (alloc) + R = _TEMPLATE(T, vec_init) (alloc, ctx); + if (R != A) + _TEMPLATE(T, vec_set) (R + lenR, A + lenR, lenA - lenR, ctx); + + for (iQ = lenA - lenB; iQ >= 0; iQ--) + { + if (TEMPLATE(T, is_zero) (R + lenA - 1, ctx)) + { + TEMPLATE(T, zero) (Q + iQ, ctx); + } + else + { + TEMPLATE(T, mul) (Q + iQ, R + lenA - 1, invB, ctx); + + _TEMPLATE(T, TEMPLATE(vec_scalar_submul, T)) (R + lenA - lenR - 1, + B, lenR, Q + iQ, + ctx); + } + + if (lenR - 1 >= iQ) + { + B++; + lenR--; + } + + lenA--; + } + + if (alloc) + _TEMPLATE(T, vec_clear) (R, alloc, ctx); +} + +void +TEMPLATE(T, poly_div_basecase) (TEMPLATE(T, poly_t) Q, + const TEMPLATE(T, poly_t) A, + const TEMPLATE(T, poly_t) B, + const TEMPLATE(T, ctx_t) ctx) +{ + const slong lenA = A->length, lenB = B->length, lenQ = lenA - lenB + 1; + TEMPLATE(T, struct) * q; + TEMPLATE(T, t) invB; + + if (lenA < lenB) + { + TEMPLATE(T, poly_zero) (Q, ctx); + return; + } + + TEMPLATE(T, init) (invB, ctx); + TEMPLATE(T, inv) (invB, B->coeffs + (lenB - 1), ctx); + + if (Q == A || Q == B) + { + q = _TEMPLATE(T, vec_init) (lenQ, ctx); + } + else + { + TEMPLATE(T, poly_fit_length) (Q, lenQ, ctx); + q = Q->coeffs; + } + + _TEMPLATE(T, poly_div_basecase) (q, NULL, A->coeffs, lenA, + B->coeffs, lenB, invB, ctx); + + if (Q == A || Q == B) + { + _TEMPLATE(T, vec_clear) (Q->coeffs, Q->alloc, ctx); + Q->coeffs = q; + Q->alloc = lenQ; + Q->length = lenQ; + } + else + { + _TEMPLATE(T, poly_set_length) (Q, lenQ, ctx); + } + + TEMPLATE(T, clear) (invB, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/div_newton_n_preinv.c b/external/flint-2.4.3/fq_poly_templates/div_newton_n_preinv.c new file mode 100644 index 0000000..d53128e --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/div_newton_n_preinv.c @@ -0,0 +1,105 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Sebastian Pancratz + Copyright (C) 2013 Martin Lee + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +_TEMPLATE(T, poly_div_newton_n_preinv) ( + TEMPLATE(T, struct) *Q, + const TEMPLATE(T, struct) *A, slong lenA, + const TEMPLATE(T, struct) *B, slong lenB, + const TEMPLATE(T, struct) * Binv, slong lenBinv, + const TEMPLATE(T, ctx_t) ctx) +{ + const slong lenQ = lenA - lenB + 1; + TEMPLATE(T, struct) * Arev; + + Arev = _TEMPLATE(T, vec_init) (lenQ, ctx); + + _TEMPLATE(T, poly_reverse) (Arev, A + (lenA - lenQ), lenQ, lenQ, ctx); + + _TEMPLATE(T, poly_mullow) (Q, Arev, lenQ, Binv, FLINT_MIN(lenQ, lenBinv), + lenQ, ctx); + + _TEMPLATE(T, poly_reverse) (Q, Q, lenQ, lenQ, ctx); + + _TEMPLATE(T, vec_clear) (Arev, lenQ, ctx); +} + +void +TEMPLATE(T, poly_div_newton_n_preinv) (TEMPLATE(T, poly_t) Q, + const TEMPLATE(T, poly_t) A, + const TEMPLATE(T, poly_t) B, + const TEMPLATE(T, poly_t) Binv, + const TEMPLATE(T, ctx_t) ctx) +{ + const slong lenA = A->length, + lenB = B->length, lenQ = lenA - lenB + 1, lenBinv = Binv->length; + + TEMPLATE(T, struct) * q; + + if (lenB == 0) + { + TEMPLATE_PRINTF("Exception (%s_poly_div_newton). Division by zero.\n", + T); + abort(); + } + + if (lenA < lenB) + { + TEMPLATE(T, poly_zero) (Q, ctx); + return; + } + + if (Q == A || Q == B || Q == Binv) + { + q = _TEMPLATE(T, vec_init) (lenQ, ctx); + } + else + { + TEMPLATE(T, poly_fit_length) (Q, lenQ, ctx); + q = Q->coeffs; + } + + _TEMPLATE(T, poly_div_newton_n_preinv) (q, A->coeffs, lenA, B->coeffs, + lenB, Binv->coeffs, lenBinv, ctx); + + if (Q == A || Q == B || Q == Binv) + { + flint_free(Q->coeffs); + Q->coeffs = q; + Q->alloc = lenQ; + } + Q->length = lenQ; +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/divides.c b/external/flint-2.4.3/fq_poly_templates/divides.c new file mode 100644 index 0000000..372053d --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/divides.c @@ -0,0 +1,113 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +int +_TEMPLATE(T, poly_divides) ( + TEMPLATE(T, struct) * Q, + const TEMPLATE(T, struct) * A, slong lenA, + const TEMPLATE(T, struct) * B, slong lenB, + const TEMPLATE(T, t) invB, + const TEMPLATE(T, ctx_t) ctx) +{ + TEMPLATE(T, struct) * R; + slong lenR = 0; + + R = _TEMPLATE(T, vec_init) (lenA, ctx); + + _TEMPLATE(T, poly_divrem) (Q, R, A, lenA, B, lenB, invB, ctx); + + TEMPLATE(CAP_T, VEC_NORM) (R, lenR, ctx); + _TEMPLATE(T, vec_clear) (R, lenA, ctx); + + return (lenR == 0); +} + +int +TEMPLATE(T, poly_divides) (TEMPLATE(T, poly_t) Q, + const TEMPLATE(T, poly_t) A, + const TEMPLATE(T, poly_t) B, + const TEMPLATE(T, ctx_t) ctx) +{ + if (TEMPLATE(T, poly_is_zero) (B, ctx)) + { + TEMPLATE_PRINTF("Exception (%s_poly_divides). B is zero.\n", T); + abort(); + } + + if (TEMPLATE(T, poly_is_zero) (A, ctx)) + { + TEMPLATE(T, poly_zero) (Q, ctx); + return 1; + } + if (TEMPLATE(T, poly_length) (A, ctx) < TEMPLATE(T, poly_length) (B, ctx)) + { + return 0; + } + + { + const slong lenQ = + TEMPLATE(T, poly_length) (A, ctx) - TEMPLATE(T, poly_length) (B, + ctx) + + 1; + int ans; + TEMPLATE(T, t) invB; + + TEMPLATE(T, init) (invB, ctx); + TEMPLATE(T, inv) (invB, TEMPLATE(T, poly_lead) (B, ctx), ctx); + + if (Q == A || Q == B) + { + TEMPLATE(T, poly_t) T; + + TEMPLATE(T, poly_init2) (T, lenQ, ctx); + ans = _TEMPLATE(T, poly_divides) (T->coeffs, A->coeffs, A->length, + B->coeffs, B->length, invB, ctx); + _TEMPLATE(T, poly_set_length) (T, lenQ, ctx); + _TEMPLATE(T, poly_normalise) (T, ctx); + TEMPLATE(T, poly_swap) (Q, T, ctx); + TEMPLATE(T, poly_clear) (T, ctx); + } + else + { + TEMPLATE(T, poly_fit_length) (Q, lenQ, ctx); + ans = _TEMPLATE(T, poly_divides) (Q->coeffs, A->coeffs, A->length, + B->coeffs, B->length, invB, ctx); + _TEMPLATE(T, poly_set_length) (Q, lenQ, ctx); + _TEMPLATE(T, poly_normalise) (Q, ctx); + } + TEMPLATE(T, clear) (invB, ctx); + + return ans; + } +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/divrem_basecase.c b/external/flint-2.4.3/fq_poly_templates/divrem_basecase.c new file mode 100644 index 0000000..53fb904 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/divrem_basecase.c @@ -0,0 +1,127 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +_TEMPLATE(T, poly_divrem_basecase) (TEMPLATE(T, struct) * Q, + TEMPLATE(T, struct) * R, + const TEMPLATE(T, struct) * A, slong lenA, + const TEMPLATE(T, struct) * B, slong lenB, + const TEMPLATE(T, t) invB, + const TEMPLATE(T, ctx_t) ctx) +{ + slong iQ, iR; + + if (R != A) + _TEMPLATE(T, poly_set) (R, A, lenA, ctx); + + for (iQ = lenA - lenB, iR = lenA - 1; iQ >= 0; iQ--, iR--) + { + if (TEMPLATE(T, is_zero) (R + iR, ctx)) + TEMPLATE(T, zero) (Q + iQ, ctx); + else + { + TEMPLATE(T, mul) (Q + iQ, R + iR, invB, ctx); + + _TEMPLATE(T, TEMPLATE(poly_scalar_submul, T)) (R + iQ, B, lenB, + Q + iQ, ctx); + } + } +} + +void +TEMPLATE(T, poly_divrem_basecase) (TEMPLATE(T, poly_t) Q, + TEMPLATE(T, poly_t) R, + const TEMPLATE(T, poly_t) A, + const TEMPLATE(T, poly_t) B, + const TEMPLATE(T, ctx_t) ctx) +{ + const slong lenA = A->length, lenB = B->length, lenQ = lenA - lenB + 1; + TEMPLATE(T, struct) * q, *r; + TEMPLATE(T, t) invB; + + if (lenA < lenB) + { + TEMPLATE(T, poly_set) (R, A, ctx); + TEMPLATE(T, poly_zero) (Q, ctx); + return; + } + + TEMPLATE(T, init) (invB, ctx); + TEMPLATE(T, inv) (invB, TEMPLATE(T, poly_lead) (B, ctx), ctx); + + if (Q == A || Q == B) + { + q = _TEMPLATE(T, vec_init) (lenQ, ctx); + } + else + { + TEMPLATE(T, poly_fit_length) (Q, lenQ, ctx); + q = Q->coeffs; + } + if (R == B) + { + r = _TEMPLATE(T, vec_init) (lenA, ctx); + } + else + { + TEMPLATE(T, poly_fit_length) (R, lenA, ctx); + r = R->coeffs; + } + + _TEMPLATE(T, poly_divrem_basecase) (q, r, A->coeffs, lenA, + B->coeffs, lenB, invB, ctx); + + if (Q == A || Q == B) + { + _TEMPLATE(T, vec_clear) (Q->coeffs, Q->alloc, ctx); + Q->coeffs = q; + Q->alloc = lenQ; + Q->length = lenQ; + } + else + { + _TEMPLATE(T, poly_set_length) (Q, lenQ, ctx); + } + if (R == B) + { + _TEMPLATE(T, vec_clear) (R->coeffs, R->alloc, ctx); + R->coeffs = r; + R->alloc = lenA; + R->length = lenA; + } + _TEMPLATE(T, poly_set_length) (R, lenB - 1, ctx); + _TEMPLATE(T, poly_normalise) (R, ctx); + + TEMPLATE(T, clear) (invB, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/divrem_divconquer.c b/external/flint-2.4.3/fq_poly_templates/divrem_divconquer.c new file mode 100644 index 0000000..8e72609 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/divrem_divconquer.c @@ -0,0 +1,214 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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, 2011 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +static void +__TEMPLATE(T, poly_divrem_divconquer) (TEMPLATE(T, struct) * Q, + TEMPLATE(T, struct) * R, + const TEMPLATE(T, struct) * A, slong lenA, + const TEMPLATE(T, struct) * B, slong lenB, + const TEMPLATE(T, t) invB, + const TEMPLATE(T, ctx_t) ctx) +{ + if (lenA < 2 * lenB - 1) + { + /* + Convert unbalanced division into a 2 n1 - 1 by n1 division + */ + + const slong n1 = lenA - lenB + 1; + const slong n2 = lenB - n1; + + const TEMPLATE(T, struct) * p1 = A + n2; + const TEMPLATE(T, struct) * d1 = B + n2; + const TEMPLATE(T, struct) * d2 = B; + + TEMPLATE(T, struct) * W = + _TEMPLATE(T, vec_init) ((2 * n1 - 1) + lenB - 1, ctx); + + TEMPLATE(T, struct) * d1q1 = R + n2; + TEMPLATE(T, struct) * d2q1 = W + (2 * n1 - 1); + + _TEMPLATE(T, poly_divrem_divconquer_recursive) (Q, d1q1, W, p1, d1, n1, + invB, ctx); + + /* + Compute d2q1 = Q d2, of length lenB - 1 + */ + + if (n1 >= n2) + _TEMPLATE(T, poly_mul) (d2q1, Q, n1, d2, n2, ctx); + else + _TEMPLATE(T, poly_mul) (d2q1, d2, n2, Q, n1, ctx); + + /* + Compute BQ = d1q1 * x^n1 + d2q1, of length lenB - 1; + then compute R = A - BQ + */ + + _TEMPLATE(T, vec_swap) (R, d2q1, n2, ctx); + _TEMPLATE(T, poly_add) (R + n2, R + n2, n1 - 1, d2q1 + n2, n1 - 1, + ctx); + _TEMPLATE(T, poly_sub) (R, A, lenA, R, lenA, ctx); + + _TEMPLATE(T, vec_clear) (W, (2 * n1 - 1) + lenB - 1, ctx); + } + else /* lenA = 2 * lenB - 1 */ + { + TEMPLATE(T, struct) * W = _TEMPLATE(T, vec_init) (lenA, ctx); + + _TEMPLATE(T, poly_divrem_divconquer_recursive) (Q, R, W, A, B, lenB, + invB, ctx); + + _TEMPLATE(T, poly_sub) (R, A, lenB - 1, R, lenB - 1, ctx); + + _TEMPLATE(T, vec_clear) (W, lenA, ctx); + } +} + +void +_TEMPLATE(T, poly_divrem_divconquer) (TEMPLATE(T, struct) * Q, + TEMPLATE(T, struct) * R, + const TEMPLATE(T, struct) * A, + slong lenA, const TEMPLATE(T, + struct) * B, + slong lenB, const TEMPLATE(T, t) invB, + const TEMPLATE(T, ctx_t) ctx) +{ + if (lenA <= 2 * lenB - 1) + { + __TEMPLATE(T, poly_divrem_divconquer) (Q, R, A, lenA, B, lenB, invB, + ctx); + } + else /* lenA > 2 * lenB - 1 */ + { + slong shift, n = 2 * lenB - 1; + TEMPLATE(T, struct) * QB, *W; + + _TEMPLATE(T, vec_set) (R, A, lenA, ctx); + W = _TEMPLATE(T, vec_init) (2 * n, ctx); + QB = W + n; + + while (lenA >= n) + { + shift = lenA - n; + _TEMPLATE(T, poly_divrem_divconquer_recursive) (Q + shift, QB, + W, R + shift, B, + lenB, invB, ctx); + _TEMPLATE(T, poly_sub) (R + shift, R + shift, n, QB, n, ctx); + lenA -= lenB; + } + + if (lenA >= lenB) + { + __TEMPLATE(T, poly_divrem_divconquer) (Q, W, R, lenA, B, lenB, + invB, ctx); + _TEMPLATE(T, vec_swap) (W, R, lenA, ctx); + } + + _TEMPLATE(T, vec_clear) (W, 2 * n, ctx); + } +} + +void +TEMPLATE(T, poly_divrem_divconquer) (TEMPLATE(T, poly_t) Q, + TEMPLATE(T, poly_t) R, + const TEMPLATE(T, poly_t) A, + const TEMPLATE(T, poly_t) B, + const TEMPLATE(T, ctx_t) ctx) +{ + const slong lenA = A->length; + const slong lenB = B->length; + const slong lenQ = lenA - lenB + 1; + + TEMPLATE(T, struct) * q, *r; + TEMPLATE(T, t) invB; + + if (lenA < lenB) + { + TEMPLATE(T, poly_set) (R, A, ctx); + TEMPLATE(T, poly_zero) (Q, ctx); + return; + } + + TEMPLATE(T, init) (invB, ctx); + TEMPLATE(T, inv) (invB, TEMPLATE(T, poly_lead) (B, ctx), ctx); + + if (Q == A || Q == B) + { + q = _TEMPLATE(T, vec_init) (lenQ, ctx); + } + else + { + TEMPLATE(T, poly_fit_length) (Q, lenQ, ctx); + q = Q->coeffs; + } + + if (R == A || R == B) + { + r = _TEMPLATE(T, vec_init) (lenA, ctx); + } + else + { + TEMPLATE(T, poly_fit_length) (R, lenA, ctx); + r = R->coeffs; + } + + _TEMPLATE(T, poly_divrem_divconquer) (q, r, A->coeffs, lenA, + B->coeffs, lenB, invB, ctx); + + if (Q == A || Q == B) + { + _TEMPLATE(T, vec_clear) (Q->coeffs, Q->alloc, ctx); + Q->coeffs = q; + Q->alloc = lenQ; + Q->length = lenQ; + } + else + { + _TEMPLATE(T, poly_set_length) (Q, lenQ, ctx); + } + + if (R == A || R == B) + { + _TEMPLATE(T, vec_clear) (R->coeffs, R->alloc, ctx); + R->coeffs = r; + R->alloc = lenA; + R->length = lenA; + } + _TEMPLATE(T, poly_set_length) (R, lenB - 1, ctx); + _TEMPLATE(T, poly_normalise) (R, ctx); + + TEMPLATE(T, clear) (invB, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/divrem_divconquer_recursive.c b/external/flint-2.4.3/fq_poly_templates/divrem_divconquer_recursive.c new file mode 100644 index 0000000..e2abae9 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/divrem_divconquer_recursive.c @@ -0,0 +1,149 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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, 2011 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +_TEMPLATE(T, poly_divrem_divconquer_recursive) ( + TEMPLATE(T, struct) * Q, + TEMPLATE(T, struct) * BQ, + TEMPLATE(T, struct) * W, + const TEMPLATE(T, struct) * A, + const TEMPLATE(T, struct) * B, slong lenB, + const TEMPLATE(T, t) invB, + const TEMPLATE(T, ctx_t) ctx) +{ + if (lenB <= TEMPLATE(CAP_T, POLY_DIVREM_DIVCONQUER_CUTOFF)) + { + _TEMPLATE(T, vec_zero) (BQ, lenB - 1, ctx); + _TEMPLATE(T, vec_set) (BQ + (lenB - 1), A + (lenB - 1), lenB, ctx); + + _TEMPLATE(T, poly_divrem_basecase) (Q, BQ, BQ, 2 * lenB - 1, B, lenB, + invB, ctx); + + _TEMPLATE(T, poly_neg) (BQ, BQ, lenB - 1, ctx); + _TEMPLATE(T, vec_set) (BQ + (lenB - 1), A + (lenB - 1), lenB, ctx); + } + else + { + const slong n2 = lenB / 2; + const slong n1 = lenB - n2; + + TEMPLATE(T, struct) * W1 = W; + TEMPLATE(T, struct) * W2 = W + lenB; + + const TEMPLATE(T, struct) * p1 = A + 2 * n2; + const TEMPLATE(T, struct) * p2; + const TEMPLATE(T, struct) * d1 = B + n2; + const TEMPLATE(T, struct) * d2 = B; + const TEMPLATE(T, struct) * d3 = B + n1; + const TEMPLATE(T, struct) * d4 = B; + + TEMPLATE(T, struct) * q1 = Q + n2; + TEMPLATE(T, struct) * q2 = Q; + TEMPLATE(T, struct) * dq1 = BQ + n2; + TEMPLATE(T, struct) * d1q1 = BQ + 2 * n2; + + TEMPLATE(T, struct) * d2q1, *d3q2, *d4q2, *t; + + /* + Set q1 to p1 div d1, a 2 n1 - 1 by n1 division so q1 ends up + being of length n1; d1q1 = d1 q1 is of length 2 n1 - 1 + */ + + _TEMPLATE(T, poly_divrem_divconquer_recursive) (q1, d1q1, W1, + p1, d1, n1, invB, ctx); + + /* + Compute d2q1 = d2 q1, of length lenB - 1 + */ + + d2q1 = W1; + _TEMPLATE(T, poly_mul) (d2q1, q1, n1, d2, n2, ctx); + + /* + Compute dq1 = d1 q1 x^n2 + d2 q1, of length 2 n1 + n2 - 1 + */ + + _TEMPLATE(T, vec_swap) (dq1, d2q1, n2, ctx); + _TEMPLATE(T, poly_add) (dq1 + n2, dq1 + n2, n1 - 1, d2q1 + n2, n1 - 1, + ctx); + + /* + Compute t = A/x^n2 - dq1, which has length 2 n1 + n2 - 1, but we + are not interested in the top n1 coeffs as they will be zero, so + this has effective length n1 + n2 - 1 + + For the following division, we want to set {p2, 2 n2 - 1} to the + top 2 n2 - 1 coeffs of this + + Since the bottom n2 - 1 coeffs of p2 are irrelevant for the + division, we in fact set {t, n2} to the relevant coeffs + */ + + t = BQ; + _TEMPLATE(T, poly_sub) (t, A + n2 + (n1 - 1), n2, dq1 + (n1 - 1), n2, + ctx); + p2 = t - (n2 - 1); + + /* + Compute q2 = t div d3, a 2 n2 - 1 by n2 division, so q2 will have + length n2; let d3q2 = d3 q2, of length 2 n2 - 1 + */ + + d3q2 = W1; + _TEMPLATE(T, poly_divrem_divconquer_recursive) (q2, d3q2, W2, + p2, d3, n2, invB, ctx); + + /* + Compute d4q2 = d4 q2, of length n1 + n2 - 1 = lenB - 1 + */ + + d4q2 = W2; + _TEMPLATE(T, poly_mul) (d4q2, d4, n1, q2, n2, ctx); + + /* + Compute dq2 = d3q2 x^n1 + d4q2, of length n1 + 2 n2 - 1 + */ + + _TEMPLATE(T, vec_swap) (BQ, d4q2, n2, ctx); + _TEMPLATE(T, poly_add) (BQ + n2, BQ + n2, n1 - 1, d4q2 + n2, n1 - 1, + ctx); + _TEMPLATE(T, poly_add) (BQ + n1, BQ + n1, 2 * n2 - 1, d3q2, 2 * n2 - 1, + ctx); + + /* + Note Q = q1 x^n2 + q2, and BQ = dq1 x^n2 + dq2 + */ + } +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/divrem_newton_n_preinv.c b/external/flint-2.4.3/fq_poly_templates/divrem_newton_n_preinv.c new file mode 100644 index 0000000..6608afc --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/divrem_newton_n_preinv.c @@ -0,0 +1,131 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2013 Martin Lee + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +_TEMPLATE(T, poly_divrem_newton_n_preinv) ( + TEMPLATE(T, struct) * Q, + TEMPLATE(T, struct) * R, + const TEMPLATE(T, struct) * A, slong lenA, + const TEMPLATE(T, struct) * B, slong lenB, + const TEMPLATE(T, struct) * Binv, slong lenBinv, + const TEMPLATE(T, ctx_t) ctx) +{ + const slong lenQ = lenA - lenB + 1; + + _TEMPLATE(T, poly_div_newton_n_preinv) (Q, A, lenA, B, lenB, Binv, lenBinv, + ctx); + + if (lenB > 1) + { + if (lenQ >= lenB - 1) + _TEMPLATE(T, poly_mullow) (R, Q, lenQ, B, lenB - 1, lenB - 1, ctx); + else + _TEMPLATE(T, poly_mullow) (R, B, lenB - 1, Q, lenQ, lenB - 1, ctx); + + _TEMPLATE(T, vec_sub) (R, A, R, lenB - 1, ctx); + } +} + +void +TEMPLATE(T, poly_divrem_newton_n_preinv) (TEMPLATE(T, poly_t) Q, + TEMPLATE(T, poly_t) R, + const TEMPLATE(T, poly_t) A, + const TEMPLATE(T, poly_t) B, + const TEMPLATE(T, poly_t) Binv, + const TEMPLATE(T, ctx_t) ctx) +{ + const slong lenA = A->length, lenB = B->length, lenBinv = Binv->length; + TEMPLATE(T, struct) * q, *r; + + if (lenB == 0) + { + TEMPLATE_PRINTF + ("Exception (%s_poly_divrem_newton_n_preinv). Division by zero.\n", + T); + abort(); + } + + if (lenA < lenB) + { + TEMPLATE(T, poly_set) (R, A, ctx); + TEMPLATE(T, poly_zero) (Q, ctx); + return; + } + + if (lenA > 2 * lenB - 2) + { + TEMPLATE_PRINTF("Exception (%s_poly_divrem_newton_n_preinv).\n", T); + } + + if (Q == A || Q == B || Q == Binv) + { + q = _TEMPLATE(T, vec_init) (lenA - lenB + 1, ctx); + } + else + { + TEMPLATE(T, poly_fit_length) (Q, lenA - lenB + 1, ctx); + q = Q->coeffs; + } + if (R == A || R == B || R == Binv) + { + r = _TEMPLATE(T, vec_init) (lenB - 1, ctx); + } + else + { + TEMPLATE(T, poly_fit_length) (R, lenB - 1, ctx); + r = R->coeffs; + } + + _TEMPLATE(T, poly_divrem_newton_n_preinv) (q, r, A->coeffs, lenA, + B->coeffs, lenB, Binv->coeffs, + lenBinv, ctx); + + if (Q == A || Q == B || Q == Binv) + { + _TEMPLATE(T, vec_clear) (Q->coeffs, lenA - lenB + 1, ctx); + Q->coeffs = q; + Q->alloc = lenA - lenB + 1; + } + if (R == A || R == B || R == Binv) + { + _TEMPLATE(T, vec_clear) (R->coeffs, lenB - 1, ctx); + R->coeffs = r; + R->alloc = lenB - 1; + } + Q->length = lenA - lenB + 1; + R->length = lenB - 1; + + _TEMPLATE(T, poly_normalise) (R, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/equal.c b/external/flint-2.4.3/fq_poly_templates/equal.c new file mode 100644 index 0000000..9839959 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/equal.c @@ -0,0 +1,54 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +int +TEMPLATE(T, poly_equal) (const TEMPLATE(T, poly_t) op1, + const TEMPLATE(T, poly_t) op2, + const TEMPLATE(T, ctx_t) ctx) +{ + slong i; + + if (op1 == op2) + return 1; + + if (op1->length != op2->length) + return 0; + + for (i = 0; i < op1->length; i++) + if (!TEMPLATE(T, equal) (op1->coeffs + i, op2->coeffs + i, ctx)) + return 0; + + return 1; +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/evaluate_fq.c b/external/flint-2.4.3/fq_poly_templates/evaluate_fq.c new file mode 100644 index 0000000..618e31d --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/evaluate_fq.c @@ -0,0 +1,83 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +_TEMPLATE3(T, poly_evaluate, T) (TEMPLATE(T, t) rop, + const TEMPLATE(T, struct) * op, slong len, + const TEMPLATE(T, t) a, + const TEMPLATE(T, ctx_t) ctx) +{ + if (len == 0) + { + TEMPLATE(T, zero) (rop, ctx); + } + else if (len == 1 || TEMPLATE(T, is_zero) (a, ctx)) + { + TEMPLATE(T, set) (rop, op + 0, ctx); + } + else + { + slong i = len - 1; + TEMPLATE(T, t) t; + + TEMPLATE(T, init) (t, ctx); + TEMPLATE(T, set) (rop, op + i, ctx); + for (i = len - 2; i >= 0; i--) + { + TEMPLATE(T, mul) (t, rop, a, ctx); + TEMPLATE(T, add) (rop, op + i, t, ctx); + } + TEMPLATE(T, clear) (t, ctx); + } +} + +void +TEMPLATE3(T, poly_evaluate, T) (TEMPLATE(T, t) rop, + const TEMPLATE(T, poly_t) f, + const TEMPLATE(T, t) a, + const TEMPLATE(T, ctx_t) ctx) +{ + if (rop == a) + { + TEMPLATE(T, t) t; + TEMPLATE(T, init) (t, ctx); + _TEMPLATE3(T, poly_evaluate, T) (t, f->coeffs, f->length, a, ctx); + TEMPLATE(T, swap) (rop, t, ctx); + TEMPLATE(T, clear) (t, ctx); + } + else + { + _TEMPLATE3(T, poly_evaluate, T) (rop, f->coeffs, f->length, a, ctx); + } +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/fit_length.c b/external/flint-2.4.3/fq_poly_templates/fit_length.c new file mode 100644 index 0000000..f8212d1 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/fit_length.c @@ -0,0 +1,47 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +TEMPLATE(T, poly_fit_length) (TEMPLATE(T, poly_t) poly, slong len, + const TEMPLATE(T, ctx_t) ctx) +{ + if (len > poly->alloc) + { + /* At least double number of allocated coeffs */ + if (len < 2 * poly->alloc) + len = 2 * poly->alloc; + TEMPLATE(T, poly_realloc) (poly, len, ctx); + } +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/fprint.c b/external/flint-2.4.3/fq_poly_templates/fprint.c new file mode 100644 index 0000000..8fad41f --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/fprint.c @@ -0,0 +1,70 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include +#include "fmpz.h" +int +_TEMPLATE(T, poly_fprint) (FILE * file, const TEMPLATE(T, struct) * poly, + slong len, const TEMPLATE(T, ctx_t) ctx) +{ + int r; + slong i; + + r = flint_fprintf(file, "%wd ", len); + if (r <= 0) + return r; + + if (len == 0) + return r; + + for (i = 0; (r > 0) && (i < len); i++) + { + r = flint_fprintf(file, " "); + if (r <= 0) + return r; + r = TEMPLATE(T, fprint) (file, poly + i, ctx); + if (r <= 0) + return r; + } + + return r; +} + +int +TEMPLATE(T, poly_fprint) (FILE * file, const TEMPLATE(T, poly_t) poly, + const TEMPLATE(T, ctx_t) ctx) +{ + return _TEMPLATE(T, poly_fprint) (file, poly->coeffs, poly->length, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/fprint_pretty.c b/external/flint-2.4.3/fq_poly_templates/fprint_pretty.c new file mode 100644 index 0000000..ed596d4 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/fprint_pretty.c @@ -0,0 +1,138 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +/* + TODO: When op has only one non-zero term, this + function would omit the parentheses. + */ + +static void +__TEMPLATE(T, print) (FILE * file, const TEMPLATE(T, struct) * op, + const TEMPLATE(T, ctx_t) ctx) +{ + fputc('(', file); + TEMPLATE(T, fprint_pretty) (file, op, ctx); + fputc(')', file); +} + +int +_TEMPLATE(T, poly_fprint_pretty) (FILE * file, + const TEMPLATE(T, struct) * poly, slong len, + const char *x, const TEMPLATE(T, ctx_t) ctx) +{ + if (len == 0) + { + fputc('0', file); + } + else if (len == 1) + { + TEMPLATE(T, fprint_pretty) (file, poly + 0, ctx); + } + else if (len == 2) + { + if (TEMPLATE(T, is_one) (poly + 1, ctx)) + flint_fprintf(file, "%s", x); + else + { + __TEMPLATE(T, print) (file, poly + 1, ctx); + flint_fprintf(file, "*%s", x); + } + if (!TEMPLATE(T, is_zero) (poly + 0, ctx)) + { + fputc('+', file); + __TEMPLATE(T, print) (file, poly + 0, ctx); + } + } + else + { + slong i = len - 1; + + { + if (TEMPLATE(T, is_one) (poly + i, ctx)) + flint_fprintf(file, "%s^%wd", x, i); + else + { + __TEMPLATE(T, print) (file, poly + i, ctx); + flint_fprintf(file, "*%s^%wd", x, i); + } + --i; + } + + for (; i > 1; --i) + { + if (TEMPLATE(T, is_zero) (poly + i, ctx)) + continue; + + if (TEMPLATE(T, is_one) (poly + i, ctx)) + flint_fprintf(file, "+%s^%wd", x, i); + else + { + fputc('+', file); + __TEMPLATE(T, print) (file, poly + i, ctx); + flint_fprintf(file, "*%s^%wd", x, i); + } + } + + if (!TEMPLATE(T, is_zero) (poly + 1, ctx)) + { + if (TEMPLATE(T, is_one) (poly + 1, ctx)) + { + fputc('+', file); + fputs(x, file); + } + else + { + fputc('+', file); + __TEMPLATE(T, print) (file, poly + 1, ctx); + fputc('*', file); + fputs(x, file); + } + } + if (!TEMPLATE(T, is_zero) (poly + 0, ctx)) + { + fputc('+', file); + __TEMPLATE(T, print) (file, poly + 0, ctx); + } + } + + return 1; +} + +int +TEMPLATE(T, poly_fprint_pretty) (FILE * file, const TEMPLATE(T, poly_t) poly, + const char *x, const TEMPLATE(T, ctx_t) ctx) +{ + return _TEMPLATE(T, poly_fprint_pretty) (file, poly->coeffs, poly->length, + x, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/gcd_euclidean.c b/external/flint-2.4.3/fq_poly_templates/gcd_euclidean.c new file mode 100644 index 0000000..e378bee --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/gcd_euclidean.c @@ -0,0 +1,166 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include + +slong +_TEMPLATE(T, poly_gcd_euclidean) (TEMPLATE(T, struct) * G, + const TEMPLATE(T, struct) * A, slong lenA, + const TEMPLATE(T, struct) * B, slong lenB, + const TEMPLATE(T, t) invB, + const TEMPLATE(T, ctx_t) ctx) +{ + if (lenB == 1) + { + TEMPLATE(T, one) (G, ctx); + return 1; + } + else /* lenA >= lenB > 1 */ + { + const slong lenW = FLINT_MAX(lenA - lenB + 1, lenB) + lenA + 2 * lenB; + TEMPLATE(T, t) invR3; + TEMPLATE(T, struct) * Q, *R1, *R2, *R3, *T, *W; + slong lenR2, lenR3; + + W = _TEMPLATE(T, vec_init) (lenW, ctx); + Q = W; + R1 = W + FLINT_MAX(lenA - lenB + 1, lenB); + R2 = R1 + lenA; + R3 = R2 + lenB; + + _TEMPLATE(T, poly_divrem) (Q, R1, A, lenA, B, lenB, invB, ctx); + + lenR3 = lenB - 1; + TEMPLATE(CAP_T, VEC_NORM) (R1, lenR3, ctx); + + if (lenR3 == 0) + { + _TEMPLATE(T, vec_set) (G, B, lenB, ctx); + _TEMPLATE(T, vec_clear) (W, lenW, ctx); + return lenB; + } + + TEMPLATE(T, init) (invR3, ctx); + + T = R3; + R3 = R1; + R1 = T; + _TEMPLATE(T, vec_set) (R2, B, lenB, ctx); + lenR2 = lenB; + + do + { + TEMPLATE(T, inv) (invR3, R3 + (lenR3 - 1), ctx); + + _TEMPLATE(T, poly_divrem) (Q, R1, R2, lenR2, R3, lenR3, invR3, + ctx); + lenR2 = lenR3--; + TEMPLATE(CAP_T, VEC_NORM) (R1, lenR3, ctx); + T = R2; + R2 = R3; + R3 = R1; + R1 = T; + } + while (lenR3 > 0); + + _TEMPLATE(T, vec_set) (G, R2, lenR2, ctx); + + _TEMPLATE(T, vec_clear) (W, lenW, ctx); + TEMPLATE(T, clear) (invR3, ctx); + + return lenR2; + } + +} + +void +TEMPLATE(T, poly_gcd_euclidean) (TEMPLATE(T, poly_t) G, + const TEMPLATE(T, poly_t) A, + const TEMPLATE(T, poly_t) B, + const TEMPLATE(T, ctx_t) ctx) +{ + if (A->length < B->length) + { + TEMPLATE(T, poly_gcd_euclidean) (G, B, A, ctx); + } + else /* lenA >= lenB >= 0 */ + { + slong lenA = A->length, lenB = B->length, lenG; + TEMPLATE(T, t) invB; + TEMPLATE(T, struct) * g; + + if (lenA == 0) /* lenA = lenB = 0 */ + { + TEMPLATE(T, poly_zero) (G, ctx); + } + else if (lenB == 0) /* lenA > lenB = 0 */ + { + TEMPLATE(T, poly_make_monic) (G, A, ctx); + } + else /* lenA >= lenB >= 1 */ + { + if (G == A || G == B) + { + g = _TEMPLATE(T, vec_init) (FLINT_MIN(lenA, lenB), ctx); + } + else + { + TEMPLATE(T, poly_fit_length) (G, FLINT_MIN(lenA, lenB), ctx); + g = G->coeffs; + } + + TEMPLATE(T, init) (invB, ctx); + TEMPLATE(T, inv) (invB, TEMPLATE(T, poly_lead) (B, ctx), ctx); + lenG = _TEMPLATE(T, poly_gcd_euclidean) (g, A->coeffs, lenA, + B->coeffs, lenB, invB, + ctx); + TEMPLATE(T, clear) (invB, ctx); + + if (G == A || G == B) + { + _TEMPLATE(T, vec_clear) (G->coeffs, G->alloc, ctx); + G->coeffs = g; + G->alloc = FLINT_MIN(lenA, lenB); + G->length = FLINT_MIN(lenA, lenB); + } + _TEMPLATE(T, poly_set_length) (G, lenG, ctx); + + if (G->length == 1) + TEMPLATE(T, one) (G->coeffs, ctx); + else + TEMPLATE(T, poly_make_monic) (G, G, ctx); + } + } +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/gen.c b/external/flint-2.4.3/fq_poly_templates/gen.c new file mode 100644 index 0000000..26c31ea --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/gen.c @@ -0,0 +1,41 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +TEMPLATE(T, poly_gen) (TEMPLATE(T, poly_t) f, const TEMPLATE(T, ctx_t) ctx) +{ + TEMPLATE(T, poly_fit_length) (f, 2, ctx); + TEMPLATE(T, zero) (f->coeffs, ctx); + TEMPLATE(T, one) (f->coeffs + 1, ctx); + _TEMPLATE(T, poly_set_length) (f, 2, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/get_coeff.c b/external/flint-2.4.3/fq_poly_templates/get_coeff.c new file mode 100644 index 0000000..1620491 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/get_coeff.c @@ -0,0 +1,45 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +TEMPLATE(T, poly_get_coeff) (TEMPLATE(T, t) x, const TEMPLATE(T, poly_t) poly, + slong n, const TEMPLATE(T, ctx_t) ctx) +{ + if (n < poly->length) + TEMPLATE(T, set) (x, poly->coeffs + n, ctx); + else + TEMPLATE(T, zero) (x, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/get_str.c b/external/flint-2.4.3/fq_poly_templates/get_str.c new file mode 100644 index 0000000..33cb4e6 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/get_str.c @@ -0,0 +1,97 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include + +char *_TEMPLATE(T, poly_get_str) (const TEMPLATE(T, struct) * poly, slong len, + const TEMPLATE(T, ctx_t) ctx) +{ + char *str, **coeffstrs; + size_t off; + slong i, bound, nz; + + if (len == 0) + { + str = (char *)flint_malloc(2 * sizeof(char)); + str[0] = '0'; + str[1] = '\0'; + return str; + } + + coeffstrs = (char **)flint_malloc(len * sizeof(char *)); + + nz = 0; + bound = (slong) (ceil(log10((double)(len + 1)))) + 2; + for (i = 0; i < len; i++) + { + if (!TEMPLATE(T, is_zero) (poly + i, ctx)) + { + coeffstrs[i] = TEMPLATE(T, get_str) (poly + i, ctx); + bound += 1 + strlen(coeffstrs[i]); + nz++; + } + else + { + bound += 2; + } + } + + str = (char *)flint_malloc(bound * sizeof(char)); + off = 0; + + off += flint_sprintf(str + off, "%wd ", len); + for (i = 0; i < len; i++) + { + if (TEMPLATE(T, is_zero) (poly + i, ctx)) + { + off += flint_sprintf(str + off, " 0"); + } + else + { + off += flint_sprintf(str + off, " %s", coeffstrs[i]); + flint_free(coeffstrs[i]); + } + } + + flint_free(coeffstrs); + + return str; +} + +char *TEMPLATE(T, poly_get_str) (const TEMPLATE(T, poly_t) poly, + const TEMPLATE(T, ctx_t) ctx) +{ + return _TEMPLATE(T, poly_get_str) (poly->coeffs, poly->length, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/get_str_pretty.c b/external/flint-2.4.3/fq_poly_templates/get_str_pretty.c new file mode 100644 index 0000000..53b87fe --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/get_str_pretty.c @@ -0,0 +1,127 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include + +char *_TEMPLATE(T, poly_get_str_pretty) (const TEMPLATE(T, struct) * poly, + slong len, const char *x, + const TEMPLATE(T, ctx_t) ctx) +{ + char *str, **coeffstrs; + size_t off; + slong i, bound, nz; + + if (len == 0) + { + str = flint_malloc(2); + str[0] = '0'; + str[1] = '\0'; + return str; + } + + if (len == 1) + { + return TEMPLATE(T, get_str_pretty) (poly, ctx); + } + + coeffstrs = (char **)flint_malloc(len * sizeof(char *)); + + nz = 0; + bound = 1; + for (i = 0; i < len; i++) + if (!TEMPLATE(T, is_zero) (poly + i, ctx)) + { + coeffstrs[i] = TEMPLATE(T, get_str_pretty) (poly + i, ctx); + bound += strlen(coeffstrs[i]); + nz++; + } + bound += nz * (5 + strlen(x) + (slong) (ceil(log10(len)))); + + str = flint_malloc(bound); + off = 0; + i = len - 1; + + if (TEMPLATE(T, is_one) (poly + i, ctx)) + { + } + else + off += flint_sprintf(str + off, "*(%s)", coeffstrs[i]); + + if (i > 1) + off += flint_sprintf(str + off, "%s^%wd", x, i); + else + off += flint_sprintf(str + off, "%s", x); + + for (--i; i > 0; --i) + { + if (TEMPLATE(T, is_zero) (poly + i, ctx)) + continue; + if (!TEMPLATE(T, is_one) (poly + i, ctx)) + { + off += flint_sprintf(str + off, "+(%s)", coeffstrs[i]); + } + else + { + off += flint_sprintf(str + off, "+"); + } + if (i > 1) + off += flint_sprintf(str + off, "*%s^%wd", x, i); + else + off += flint_sprintf(str + off, "*%s", x); + } + + if (!TEMPLATE(T, is_zero) (poly + i, ctx)) + { + off += flint_sprintf(str + off, "+(%s)", coeffstrs[i]); + } + + for (i = 0; i < len; i++) + if (!TEMPLATE(T, is_zero) (poly + i, ctx)) + { + flint_free(coeffstrs[i]); + } + + flint_free(coeffstrs); + + return str; +} + +char *TEMPLATE(T, poly_get_str_pretty) (const TEMPLATE(T, poly_t) poly, + const char *x, + const TEMPLATE(T, ctx_t) ctx) +{ + return _TEMPLATE(T, poly_get_str_pretty) (poly->coeffs, poly->length, x, + ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/hamming_weight.c b/external/flint-2.4.3/fq_poly_templates/hamming_weight.c new file mode 100644 index 0000000..3ef3837 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/hamming_weight.c @@ -0,0 +1,52 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +slong +_TEMPLATE(T, poly_hamming_weight) (const TEMPLATE(T, struct) * op, slong len, + const TEMPLATE(T, ctx_t) ctx) +{ + slong i, sum = 0; + for (i = 0; i < len; i++) + sum += !TEMPLATE(T, is_zero) (op + i, ctx); + + return sum; +} + +slong +TEMPLATE(T, poly_hamming_weight) (const TEMPLATE(T, poly_t) op, + const TEMPLATE(T, ctx_t) ctx) +{ + + return _TEMPLATE(T, poly_hamming_weight) (op->coeffs, op->length, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/inflate.c b/external/flint-2.4.3/fq_poly_templates/inflate.c new file mode 100644 index 0000000..86c3a32 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/inflate.c @@ -0,0 +1,71 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +TEMPLATE(T, poly_inflate) (TEMPLATE(T, poly_t) result, + const TEMPLATE(T, poly_t) input, ulong inflation, + const TEMPLATE(T, ctx_t) ctx) +{ + if (input->length <= 1 || inflation == 1) + { + TEMPLATE(T, poly_set) (result, input, ctx); + } + else if (inflation == 0) + { + TEMPLATE(T, t) v; + TEMPLATE(T, init) (v, ctx); + TEMPLATE(T, one) (v, ctx); + TEMPLATE(T, TEMPLATE(poly_evaluate, T)) (v, input, v, ctx); + TEMPLATE(T, poly_zero) (result, ctx); + TEMPLATE(T, poly_set_coeff) (result, 0, v, ctx); + TEMPLATE(T, clear) (v, ctx); + } + else + { + slong i, j, res_length = (input->length - 1) * inflation + 1; + + TEMPLATE(T, poly_fit_length) (result, res_length, ctx); + + for (i = input->length - 1; i > 0; i--) + { + TEMPLATE(T, set) (result->coeffs + (i * inflation), + input->coeffs + i, ctx); + for (j = i * inflation - 1; j > (i - 1) * inflation; j--) + TEMPLATE(T, zero) (result->coeffs + j, ctx); + } + TEMPLATE(T, set) (result->coeffs, input->coeffs, ctx); + result->length = res_length; + } +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/init.c b/external/flint-2.4.3/fq_poly_templates/init.c new file mode 100644 index 0000000..d8d43bb --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/init.c @@ -0,0 +1,51 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Andres Goens + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +TEMPLATE(T, poly_init) (TEMPLATE(T, poly_t) poly, const TEMPLATE(T, ctx_t) ctx) +{ + poly->coeffs = NULL; + poly->alloc = 0; + poly->length = 0; +} + +void +TEMPLATE(T, poly_init2) (TEMPLATE(T, poly_t) poly, slong alloc, + const TEMPLATE(T, ctx_t) ctx) +{ + poly->coeffs = (alloc) ? _TEMPLATE(T, vec_init) (alloc, ctx) : NULL; + poly->alloc = alloc; + poly->length = 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/inv_series_newton.c b/external/flint-2.4.3/fq_poly_templates/inv_series_newton.c new file mode 100644 index 0000000..14dc644 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/inv_series_newton.c @@ -0,0 +1,137 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#define FQ_POLY_INV_NEWTON_CUTOFF 64 + +void +_TEMPLATE(T, poly_inv_series_newton) (TEMPLATE(T, struct) * Qinv, + const TEMPLATE(T, struct) * Q, slong n, + const TEMPLATE(T, t) cinv, + const TEMPLATE(T, ctx_t) ctx) +{ + if (n == 1) /* {Q,1} x* cinv == 1 mod (x) */ + { + TEMPLATE(T, set) (Qinv, cinv, ctx); + } + else + { + const slong alloc = FLINT_MAX(n, 3 * FQ_POLY_INV_NEWTON_CUTOFF); + slong *a, i, m; + TEMPLATE(T, struct) * W; + + W = _TEMPLATE(T, vec_init) (alloc, ctx); + + for (i = 1; (WORD(1) << i) < n; i++) ; + + a = (slong *) flint_malloc(i * sizeof(slong)); + a[i = 0] = n; + while (n >= FQ_POLY_INV_NEWTON_CUTOFF) + a[++i] = (n = (n + 1) / 2); + + /* Base case */ + { + TEMPLATE(T, struct) * Qrev = W + 2 * FQ_POLY_INV_NEWTON_CUTOFF; + + _TEMPLATE(T, poly_reverse) (Qrev, Q, n, n, ctx); + _TEMPLATE(T, vec_zero) (W, 2 * n - 2, ctx); + TEMPLATE(T, one) (W + (2 * n - 2), ctx); + _TEMPLATE(T, poly_div_basecase) (Qinv, W, W, 2 * n - 1, Qrev, n, + cinv, ctx); + _TEMPLATE(T, poly_reverse) (Qinv, Qinv, n, n, ctx); + } + + for (i--; i >= 0; i--) + { + m = n; + n = a[i]; + + _TEMPLATE(T, poly_mullow) (W, Q, n, Qinv, m, n, ctx); + _TEMPLATE(T, poly_mullow) (Qinv + m, Qinv, m, W + m, n - m, n - m, + ctx); + _TEMPLATE(T, poly_neg) (Qinv + m, Qinv + m, n - m, ctx); + } + + _TEMPLATE(T, vec_clear) (W, alloc, ctx); + flint_free(a); + } +} + +void +TEMPLATE(T, poly_inv_series_newton) (TEMPLATE(T, poly_t) Qinv, + const TEMPLATE(T, poly_t) Q, slong n, + const TEMPLATE(T, ctx_t) ctx) +{ + TEMPLATE(T, t) cinv; + TEMPLATE(T, struct) * Qcopy; + int Qalloc; + + if (Q->length >= n) + { + Qcopy = Q->coeffs; + Qalloc = 0; + } + else + { + Qcopy = _TEMPLATE(T, vec_init) (n, ctx); + _TEMPLATE(T, vec_set) (Qcopy, Q->coeffs, Q->length, ctx); + Qalloc = 1; + } + + TEMPLATE(T, init) (cinv, ctx); + TEMPLATE(T, inv) (cinv, Q->coeffs, ctx); + + if (Qinv != Q) + { + TEMPLATE(T, poly_fit_length) (Qinv, n, ctx); + _TEMPLATE(T, poly_inv_series_newton) (Qinv->coeffs, Qcopy, n, cinv, + ctx); + } + else + { + TEMPLATE(T, struct) * t = _TEMPLATE(T, vec_init) (n, ctx); + + _TEMPLATE(T, poly_inv_series_newton) (t, Qcopy, n, cinv, ctx); + + _TEMPLATE(T, vec_clear) (Qinv->coeffs, Qinv->alloc, ctx); + Qinv->coeffs = t; + Qinv->alloc = n; + Qinv->length = n; + } + _TEMPLATE(T, poly_set_length) (Qinv, n, ctx); + _TEMPLATE(T, poly_normalise) (Qinv, ctx); + + if (Qalloc) + _TEMPLATE(T, vec_clear) (Qcopy, n, ctx); + TEMPLATE(T, clear) (cinv, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/make_monic.c b/external/flint-2.4.3/fq_poly_templates/make_monic.c new file mode 100644 index 0000000..85d86df --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/make_monic.c @@ -0,0 +1,63 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007, David Howden. + Copyright (C) 2010 William Hart + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +_TEMPLATE(T, poly_make_monic) (TEMPLATE(T, struct) * rop, + const TEMPLATE(T, struct) * op, slong length, + const TEMPLATE(T, ctx_t) ctx) +{ + TEMPLATE(T, t) inv; + TEMPLATE(T, init) (inv, ctx); + TEMPLATE(T, inv) (inv, &op[length - 1], ctx); + _TEMPLATE(T, TEMPLATE(poly_scalar_mul, T)) (rop, op, length, inv, ctx); + TEMPLATE(T, clear) (inv, ctx); +} + +void +TEMPLATE(T, poly_make_monic) (TEMPLATE(T, poly_t) rop, + const TEMPLATE(T, poly_t) op, + const TEMPLATE(T, ctx_t) ctx) +{ + if (op->length == 0) + { + TEMPLATE(T, poly_zero) (rop, ctx); + return; + } + + TEMPLATE(T, poly_fit_length) (rop, op->length, ctx); + _TEMPLATE(T, poly_make_monic) (rop->coeffs, op->coeffs, op->length, ctx); + _TEMPLATE(T, poly_set_length) (rop, op->length, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/mul.c b/external/flint-2.4.3/fq_poly_templates/mul.c new file mode 100644 index 0000000..4e4bc8a --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/mul.c @@ -0,0 +1,91 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +_TEMPLATE(T, poly_mul) (TEMPLATE(T, struct) * rop, + const TEMPLATE(T, struct) * op1, slong len1, + const TEMPLATE(T, struct) * op2, slong len2, + const TEMPLATE(T, ctx_t) ctx) +{ + if (FLINT_MAX(len1, len2) < TEMPLATE(CAP_T, MUL_CLASSICAL_CUTOFF)) + { + _TEMPLATE(T, poly_mul_classical) (rop, op1, len1, op2, len2, ctx); + } +#ifdef USE_MUL_REORDER + else if (TEMPLATE(T, ctx_degree) (ctx) < 4) + { + _TEMPLATE(T, poly_mul_reorder) (rop, op1, len1, op2, len2, ctx); + } +#endif + else + { + _TEMPLATE(T, poly_mul_KS) (rop, op1, len1, op2, len2, ctx); + } +} + +void +TEMPLATE(T, poly_mul) (TEMPLATE(T, poly_t) rop, + const TEMPLATE(T, poly_t) op1, + const TEMPLATE(T, poly_t) op2, + const TEMPLATE(T, ctx_t) ctx) +{ + const slong len1 = op1->length; + const slong len2 = op2->length; + const slong rlen = op1->length + op2->length - 1; + + if (len1 == 0 || len2 == 0) + { + TEMPLATE(T, poly_zero) (rop, ctx); + return; + } + + if (rop == op1 || rop == op2) + { + TEMPLATE(T, poly_t) t; + + TEMPLATE(T, poly_init2) (t, rlen, ctx); + _TEMPLATE(T, poly_mul) (t->coeffs, op1->coeffs, len1, op2->coeffs, + len2, ctx); + TEMPLATE(T, poly_swap) (rop, t, ctx); + TEMPLATE(T, poly_clear) (t, ctx); + } + else + { + TEMPLATE(T, poly_fit_length) (rop, rlen, ctx); + _TEMPLATE(T, poly_mul) (rop->coeffs, op1->coeffs, len1, op2->coeffs, + len2, ctx); + } + + _TEMPLATE(T, poly_set_length) (rop, rlen, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/mul_KS.c b/external/flint-2.4.3/fq_poly_templates/mul_KS.c new file mode 100644 index 0000000..d7b2069 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/mul_KS.c @@ -0,0 +1,111 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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, 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" +#include "fmpz_poly.h" + +void +_TEMPLATE(T, poly_mul_KS) (TEMPLATE(T, struct) * rop, + const TEMPLATE(T, struct) * op1, slong len1, + const TEMPLATE(T, struct) * op2, slong len2, + const TEMPLATE(T, ctx_t) ctx) +{ + const slong in1_len = len1, in2_len = len2; + const slong d = TEMPLATE(T, ctx_degree) (ctx); + slong bits, i; + fmpz *f, *g, *h; + + TEMPLATE(CAP_T, VEC_NORM) (op1, len1, ctx); + TEMPLATE(CAP_T, VEC_NORM) (op2, len2, ctx); + + if (!len1 | !len2) + { + if (in1_len + in2_len - 1 > 0) + _TEMPLATE(T, poly_zero) (rop, in1_len + in2_len - 1, ctx); + return; + } + + bits = 2 * fmpz_bits(TEMPLATE(T, ctx_prime) (ctx)) + + FLINT_BIT_COUNT(d) + FLINT_BIT_COUNT(FLINT_MIN(len1, len2)); + + f = _fmpz_vec_init((len1 + len2 - 1) + (len1) + (len2)); + g = f + (len1 + len2 - 1); + h = g + len1; + + for (i = 0; i < len1; i++) + { + TEMPLATE(T, bit_pack) (g + i, op1 + i, bits, ctx); + } + for (i = 0; i < len2; i++) + { + TEMPLATE(T, bit_pack) (h + i, op2 + i, bits, ctx); + } + + if (len1 >= len2) + _fmpz_poly_mul(f, g, len1, h, len2); + else + _fmpz_poly_mul(f, h, len2, g, len1); + + for (i = 0; i < len1 + len2 - 1; i++) + { + TEMPLATE(T, bit_unpack) (rop + i, f + i, bits, ctx); + } + + _TEMPLATE(T, poly_zero) (rop + (len1 + len2 - 1), + (in1_len - len1) + (in2_len - len2), ctx); + + _fmpz_vec_clear(f, (len1 + len2 - 1) + (len1) + (len2)); +} + +void +TEMPLATE(T, poly_mul_KS) (TEMPLATE(T, poly_t) rop, + const TEMPLATE(T, poly_t) op1, + const TEMPLATE(T, poly_t) op2, + const TEMPLATE(T, ctx_t) ctx) +{ + const slong len1 = op1->length; + const slong len2 = op2->length; + const slong rlen = len1 + len2 - 1; + + if (len1 == 0 || len2 == 0) + { + TEMPLATE(T, poly_zero) (rop, ctx); + } + else + { + TEMPLATE(T, poly_fit_length) (rop, rlen, ctx); + _TEMPLATE(T, poly_mul_KS) (rop->coeffs, op1->coeffs, len1, + op2->coeffs, len2, ctx); + _TEMPLATE(T, poly_set_length) (rop, rlen, ctx); + } +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/mul_classical.c b/external/flint-2.4.3/fq_poly_templates/mul_classical.c new file mode 100644 index 0000000..122fd93 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/mul_classical.c @@ -0,0 +1,98 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +_TEMPLATE(T, poly_mul_classical) (TEMPLATE(T, struct) * rop, + const TEMPLATE(T, struct) * op1, slong len1, + const TEMPLATE(T, struct) * op2, slong len2, + const TEMPLATE(T, ctx_t) ctx) +{ + if (len1 == 1 && len2 == 1) + { + TEMPLATE(T, mul) (rop, op1, op2, ctx); + } + else + { + slong i; + + /* Set res[i] = poly1[i]*poly2[0] */ + _TEMPLATE(T, TEMPLATE(poly_scalar_mul, T)) (rop, op1, len1, op2, ctx); + + /* Set res[i+len1-1] = in1[len1-1]*in2[i] */ + _TEMPLATE(T, TEMPLATE(poly_scalar_mul, T)) (rop + len1, op2 + 1, + len2 - 1, op1 + len1 - 1, + ctx); + + /* out[i+j] += in1[i]*in2[j] */ + for (i = 0; i < len1 - 1; i++) + _TEMPLATE(T, TEMPLATE(poly_scalar_addmul, T)) (rop + i + 1, + op2 + 1, len2 - 1, + op1 + i, ctx); + } +} + +void +TEMPLATE(T, poly_mul_classical) (TEMPLATE(T, poly_t) rop, + const TEMPLATE(T, poly_t) op1, + const TEMPLATE(T, poly_t) op2, + const TEMPLATE(T, ctx_t) ctx) +{ + const slong len = op1->length + op2->length - 1; + + if (op1->length == 0 || op2->length == 0) + { + TEMPLATE(T, poly_zero) (rop, ctx); + return; + } + + if (rop == op1 || rop == op2) + { + TEMPLATE(T, poly_t) t; + + TEMPLATE(T, poly_init2) (t, len, ctx); + _TEMPLATE(T, poly_mul_classical) (t->coeffs, op1->coeffs, op1->length, + op2->coeffs, op2->length, ctx); + TEMPLATE(T, poly_swap) (rop, t, ctx); + TEMPLATE(T, poly_clear) (t, ctx); + } + else + { + TEMPLATE(T, poly_fit_length) (rop, len, ctx); + _TEMPLATE(T, poly_mul_classical) (rop->coeffs, op1->coeffs, + op1->length, op2->coeffs, + op2->length, ctx); + } + + _TEMPLATE(T, poly_set_length) (rop, len, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/mul_reorder.c b/external/flint-2.4.3/fq_poly_templates/mul_reorder.c new file mode 100644 index 0000000..e64314e --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/mul_reorder.c @@ -0,0 +1,243 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +/* + Include routines for vectors over \code{fmpz_poly_struct}, + for use in the classical multiplication routine in the + $X$-direction. + */ + +static fmpz_poly_struct * +__vec_init(slong len) +{ + slong i; + fmpz_poly_struct *v; + + v = flint_malloc(len * sizeof(fmpz_poly_struct)); + for (i = 0; i < len; i++) + fmpz_poly_init(v + i); + return v; +} + +static fmpz_poly_struct * +__vec_init2(slong len, slong n) +{ + slong i; + fmpz_poly_struct *v; + + v = flint_malloc(len * sizeof(fmpz_poly_struct)); + for (i = 0; i < len; i++) + fmpz_poly_init2(v + i, n); + return v; +} + +static void +__vec_clear(fmpz_poly_struct * v, slong len) +{ + slong i; + + for (i = 0; i < len; i++) + fmpz_poly_clear(v + i); + flint_free(v); +} + +static void +__scalar_addmul(fmpz_poly_struct * rop, + const fmpz_poly_struct * op, slong len, const fmpz_poly_t x) +{ + slong i; + + if (fmpz_poly_is_zero(x)) + { + return; + } + else if (fmpz_poly_is_one(x)) + { + for (i = 0; i < len; i++) + fmpz_poly_add(rop + i, rop + i, op + i); + } + else + { + fmpz_poly_t t; + + fmpz_poly_init(t); + for (i = 0; i < len; i++) + { + fmpz_poly_mul(t, op + i, x); + fmpz_poly_add(rop + i, rop + i, t); + } + fmpz_poly_clear(t); + } +} + +static void +__scalar_mul(fmpz_poly_struct * rop, + const fmpz_poly_struct * op, slong len, const fmpz_poly_t x) +{ + slong i; + + if (fmpz_poly_is_zero(x)) + { + for (i = 0; i < len; i++) + fmpz_poly_zero(rop + i); + } + else if (fmpz_poly_is_one(x)) + { + for (i = 0; i < len; i++) + fmpz_poly_set(rop + i, op + i); + } + else + { + for (i = 0; i < len; i++) + fmpz_poly_mul(rop + i, op + i, x); + } +} + +static void +__mul(fmpz_poly_struct * rop, + fmpz_poly_struct * op1, slong len1, fmpz_poly_struct * op2, slong len2) +{ + if (len1 == 1 && len2 == 1) + { + fmpz_poly_mul(rop, op1, op2); + } + else + { + slong i; + + __scalar_mul(rop, op1, len1, op2); + + __scalar_mul(rop + len1, op2 + 1, len2 - 1, op1 + len1 - 1); + + for (i = 0; i < len1 - 1; i++) + __scalar_addmul(rop + i + 1, op2 + 1, len2 - 1, op1 + i); + } +} + +void +_TEMPLATE(T, poly_mul_reorder) (TEMPLATE(T, struct) * rop, + const TEMPLATE(T, struct) * op1, slong len1, + const TEMPLATE(T, struct) * op2, slong len2, + const TEMPLATE(T, ctx_t) ctx) +{ + const slong d = TEMPLATE(T, ctx_degree) (ctx); + + fmpz_poly_struct *f, *g, *h; + slong i, j, k, len; + + f = __vec_init(2 * d - 1); + g = __vec_init2(d, len1); + h = __vec_init2(d, len2); + + /* Convert (op1, len1) to (g, d) */ + for (i = 0; i < len1; i++) + for (j = 0; j < fmpz_poly_length(op1 + i); j++) + fmpz_set((g + j)->coeffs + i, (op1 + i)->coeffs + j); + + /* Convert (op2, len2) to (h, d) */ + for (i = 0; i < len2; i++) + for (j = 0; j < fmpz_poly_length(op2 + i); j++) + fmpz_set((h + j)->coeffs + i, (op2 + i)->coeffs + j); + + for (j = 0; j < d; j++) + { + _fmpz_poly_set_length(g + j, len1); + _fmpz_poly_set_length(h + j, len2); + _fmpz_poly_normalise(g + j); + _fmpz_poly_normalise(h + j); + } + + __mul(f, g, d, h, d); + + /* Normalise (f, len) */ + len = 2 * d - 1; + while ((len) && fmpz_poly_is_zero(f + (len - 1))) + len--; + + /* Reduce (f, j) using polynomial operations */ + if (len > d) + { + for (i = len - 1; i >= d; i--) + { + for (k = ctx->len - 2; k >= 0; k--) + { + fmpz_poly_scalar_submul_fmpz(f + ctx->j[k] + i - d, f + i, + ctx->a + k); + } + fmpz_poly_zero(f + i); + } + } + for (j = 0; j < FLINT_MIN(d, len); j++) + fmpz_poly_scalar_mod_fmpz(f + j, f + j, TEMPLATE(T, ctx_prime) (ctx)); + + /* Convert (f, d) to (rop, len1 + len2 - 1) */ + for (i = 0; i < len1 + len2 - 1; i++) + { + fmpz_poly_fit_length(rop + i, d); + _fmpz_vec_zero((rop + i)->coeffs, d); + } + for (j = 0; j < d; j++) + for (i = 0; i < fmpz_poly_length(f + j); i++) + fmpz_set((rop + i)->coeffs + j, (f + j)->coeffs + i); + for (i = 0; i < len1 + len2 - 1; i++) + { + _fmpz_poly_set_length(rop + i, d); + _fmpz_poly_normalise(rop + i); + } + + __vec_clear(f, 2 * d - 1); + __vec_clear(g, d); + __vec_clear(h, d); +} + +void +TEMPLATE(T, poly_mul_reorder) (TEMPLATE(T, poly_t) rop, + const TEMPLATE(T, poly_t) op1, + const TEMPLATE(T, poly_t) op2, + const TEMPLATE(T, ctx_t) ctx) +{ + const slong len = op1->length + op2->length - 1; + + if (op1->length == 0 || op2->length == 0) + { + TEMPLATE(T, poly_zero) (rop, ctx); + } + else + { + TEMPLATE(T, poly_fit_length) (rop, len, ctx); + _TEMPLATE(T, poly_mul_reorder) (rop->coeffs, op1->coeffs, op1->length, + op2->coeffs, op2->length, ctx); + _TEMPLATE(T, poly_set_length) (rop, len, ctx); + } +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/mullow.c b/external/flint-2.4.3/fq_poly_templates/mullow.c new file mode 100644 index 0000000..7ab40fa --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/mullow.c @@ -0,0 +1,92 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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, 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +_TEMPLATE(T, poly_mullow) (TEMPLATE(T, struct) * rop, + const TEMPLATE(T, struct) * op1, slong len1, + const TEMPLATE(T, struct) * op2, slong len2, + slong n, const TEMPLATE(T, ctx_t) ctx) +{ + if (n < TEMPLATE(CAP_T, MULLOW_CLASSICAL_CUTOFF) + || FLINT_MAX(len1, len2) < 6) + { + _TEMPLATE(T, poly_mullow_classical) (rop, op1, len1, op2, len2, n, + ctx); + } + else + { + _TEMPLATE(T, poly_mullow_KS) (rop, op1, len1, op2, len2, n, ctx); + } +} + +void +TEMPLATE(T, poly_mullow) (TEMPLATE(T, poly_t) rop, + const TEMPLATE(T, poly_t) op1, + const TEMPLATE(T, poly_t) op2, + slong n, const TEMPLATE(T, ctx_t) ctx) +{ + const slong len1 = op1->length; + const slong len2 = op2->length; + const slong lenr = op1->length + op2->length - 1; + + if (len1 == 0 || len2 == 0 || n == 0) + { + TEMPLATE(T, poly_zero) (rop, ctx); + return; + } + + if (n > lenr) + n = lenr; + + if (rop == op1 || rop == op2) + { + TEMPLATE(T, poly_t) t; + + TEMPLATE(T, poly_init2) (t, n, ctx); + _TEMPLATE(T, poly_mullow) (t->coeffs, op1->coeffs, op1->length, + op2->coeffs, op2->length, n, ctx); + TEMPLATE(T, poly_swap) (rop, t, ctx); + TEMPLATE(T, poly_clear) (t, ctx); + } + else + { + TEMPLATE(T, poly_fit_length) (rop, n, ctx); + _TEMPLATE(T, poly_mullow) (rop->coeffs, op1->coeffs, op1->length, + op2->coeffs, op2->length, n, ctx); + } + + _TEMPLATE(T, poly_set_length) (rop, n, ctx); + _TEMPLATE(T, poly_normalise) (rop, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/mullow_KS.c b/external/flint-2.4.3/fq_poly_templates/mullow_KS.c new file mode 100644 index 0000000..6204efb --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/mullow_KS.c @@ -0,0 +1,117 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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, 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" +#include "fmpz_poly.h" + +void +_TEMPLATE(T, poly_mullow_KS) (TEMPLATE(T, struct) * rop, + const TEMPLATE(T, struct) * op1, slong len1, + const TEMPLATE(T, struct) * op2, slong len2, + slong n, const TEMPLATE(T, ctx_t) ctx) +{ + const slong d = TEMPLATE(T, ctx_degree) (ctx); + slong bits, i, m; + fmpz *f, *g, *h; + + TEMPLATE(CAP_T, VEC_NORM) (op1, len1, ctx); + TEMPLATE(CAP_T, VEC_NORM) (op2, len2, ctx); + + if (!len1 | !len2) + { + _TEMPLATE(T, poly_zero) (rop, n, ctx); + return; + } + + bits = 2 * fmpz_bits(TEMPLATE(T, ctx_prime) (ctx)) + + FLINT_BIT_COUNT(d) + FLINT_BIT_COUNT(FLINT_MIN(len1, len2)); + + f = _fmpz_vec_init(n + len1 + len2); + g = f + n; + h = g + len1; + + for (i = 0; i < len1; i++) + { + TEMPLATE(T, bit_pack) (g + i, op1 + i, bits, ctx); + } + for (i = 0; i < len2; i++) + { + TEMPLATE(T, bit_pack) (h + i, op2 + i, bits, ctx); + } + + m = FLINT_MIN(n, len1 + len2 - 1); + + if (len1 >= len2) + _fmpz_poly_mullow(f, g, len1, h, len2, m); + else + _fmpz_poly_mullow(f, h, len2, g, len1, m); + + for (i = 0; i < m; i++) + { + TEMPLATE(T, bit_unpack) (rop + i, f + i, bits, ctx); + } + for (; i < n; i++) + { + TEMPLATE(T, zero) (rop + i, ctx); + } + + _fmpz_vec_clear(f, n + len1 + len2); +} + +void +TEMPLATE(T, poly_mullow_KS) (TEMPLATE(T, poly_t) rop, + const TEMPLATE(T, poly_t) op1, + const TEMPLATE(T, poly_t) op2, + slong n, const TEMPLATE(T, ctx_t) ctx) +{ + const slong len1 = op1->length; + const slong len2 = op2->length; + + if (len1 == 0 || len2 == 0 || n == 0) + { + TEMPLATE(T, poly_zero) (rop, ctx); + } + else + { + const slong lenr = op1->length + op2->length - 1; + + if (n > lenr) + n = lenr; + + TEMPLATE(T, poly_fit_length) (rop, n, ctx); + _TEMPLATE(T, poly_mullow_KS) (rop->coeffs, op1->coeffs, len1, + op2->coeffs, len2, n, ctx); + _TEMPLATE(T, poly_set_length) (rop, n, ctx); + _TEMPLATE(T, poly_normalise) (rop, ctx); + } +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/mullow_classical.c b/external/flint-2.4.3/fq_poly_templates/mullow_classical.c new file mode 100644 index 0000000..4930a7e --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/mullow_classical.c @@ -0,0 +1,104 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +_TEMPLATE(T, poly_mullow_classical) ( + TEMPLATE(T, struct) * rop, + const TEMPLATE(T, struct) * op1, slong len1, + const TEMPLATE(T, struct) * op2, slong len2, + slong n, const TEMPLATE(T, ctx_t) ctx) +{ + if ((len1 == 1 && len2 == 1) || n == 1) + { + TEMPLATE(T, mul) (rop, op1, op2, ctx); + } + else + { + slong i; + + _TEMPLATE3(T, poly_scalar_mul, T)(rop, op1, FLINT_MIN(len1, n), + op2, ctx); + + if (n > len1) + _TEMPLATE3(T, poly_scalar_mul, T) (rop + len1, + op2 + 1, n - len1, + op1 + len1 - 1, ctx); + + for (i = 0; i < FLINT_MIN(len1, n) - 1; i++) + _TEMPLATE3(T, poly_scalar_addmul, T) (rop + i + 1, op2 + 1, + FLINT_MIN(len2, n - i) - 1, + op1 + i, ctx); + } +} + +void +TEMPLATE(T, poly_mullow_classical) (TEMPLATE(T, poly_t) rop, + const TEMPLATE(T, poly_t) op1, + const TEMPLATE(T, poly_t) op2, slong n, + const TEMPLATE(T, ctx_t) ctx) +{ + const slong len = op1->length + op2->length - 1; + + if (op1->length == 0 || op2->length == 0 || n == 0) + { + TEMPLATE(T, poly_zero) (rop, ctx); + return; + } + + if (n > len) + n = len; + + if (rop == op1 || rop == op2) + { + TEMPLATE(T, poly_t) t; + + TEMPLATE(T, poly_init2) (t, n, ctx); + _TEMPLATE(T, poly_mullow_classical) (t->coeffs, op1->coeffs, + op1->length, op2->coeffs, + op2->length, n, ctx); + TEMPLATE(T, poly_swap) (rop, t, ctx); + TEMPLATE(T, poly_clear) (t, ctx); + } + else + { + TEMPLATE(T, poly_fit_length) (rop, n, ctx); + _TEMPLATE(T, poly_mullow_classical) (rop->coeffs, op1->coeffs, + op1->length, op2->coeffs, + op2->length, n, ctx); + } + + _TEMPLATE(T, poly_set_length) (rop, n, ctx); + _TEMPLATE(T, poly_normalise) (rop, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/mulmod.c b/external/flint-2.4.3/fq_poly_templates/mulmod.c new file mode 100644 index 0000000..1f6fccb --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/mulmod.c @@ -0,0 +1,117 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +_TEMPLATE(T, poly_mulmod) (TEMPLATE(T, struct) * res, + const TEMPLATE(T, struct) * poly1, slong len1, + const TEMPLATE(T, struct) * poly2, slong len2, + const TEMPLATE(T, struct) * f, slong lenf, + const TEMPLATE(T, ctx_t) ctx) +{ + TEMPLATE(T, struct) * T, *Q; + TEMPLATE(T, t) invf; + slong lenT, lenQ; + + lenT = len1 + len2 - 1; + lenQ = lenT - lenf + 1; + + T = _TEMPLATE(T, vec_init) (lenT + lenQ, ctx); + Q = T + lenT; + + if (len1 >= len2) + _TEMPLATE(T, poly_mul) (T, poly1, len1, poly2, len2, ctx); + else + _TEMPLATE(T, poly_mul) (T, poly2, len2, poly1, len1, ctx); + + TEMPLATE(T, init) (invf, ctx); + TEMPLATE(T, inv) (invf, f + lenf - 1, ctx); + + _TEMPLATE(T, poly_divrem) (Q, res, T, lenT, f, lenf, invf, ctx); + + _TEMPLATE(T, vec_clear) (T, lenT + lenQ, ctx); + TEMPLATE(T, clear) (invf, ctx); +} + +void +TEMPLATE(T, poly_mulmod) (TEMPLATE(T, poly_t) res, + const TEMPLATE(T, poly_t) poly1, + const TEMPLATE(T, poly_t) poly2, + const TEMPLATE(T, poly_t) f, + const TEMPLATE(T, ctx_t) ctx) +{ + slong len1, len2, lenf; + TEMPLATE(T, struct) * fcoeffs; + + lenf = f->length; + len1 = poly1->length; + len2 = poly2->length; + + if (lenf == 0) + { + TEMPLATE_PRINTF("Exception: %s_poly_mulmod: divide by zero\n", T); + abort(); + } + + if (lenf == 1 || len1 == 0 || len2 == 0) + { + TEMPLATE(T, poly_zero) (res, ctx); + return; + } + + if (len1 + len2 - lenf > 0) + { + if (f == res) + { + fcoeffs = _TEMPLATE(T, vec_init) (lenf, ctx); + _TEMPLATE(T, vec_set) (fcoeffs, f->coeffs, lenf, ctx); + } + else + fcoeffs = f->coeffs; + + TEMPLATE(T, poly_fit_length) (res, len1 + len2 - 1, ctx); + _TEMPLATE(T, poly_mulmod) (res->coeffs, + poly1->coeffs, len1, + poly2->coeffs, len2, fcoeffs, lenf, ctx); + if (f == res) + _TEMPLATE(T, vec_clear) (fcoeffs, lenf, ctx); + + _TEMPLATE(T, poly_set_length) (res, lenf - 1, ctx); + _TEMPLATE(T, poly_normalise) (res, ctx); + } + else + { + TEMPLATE(T, poly_mul) (res, poly1, poly2, ctx); + } +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/mulmod_preinv.c b/external/flint-2.4.3/fq_poly_templates/mulmod_preinv.c new file mode 100644 index 0000000..9c1d29a --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/mulmod_preinv.c @@ -0,0 +1,117 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Martin Lee + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +_TEMPLATE(T, poly_mulmod_preinv) ( + TEMPLATE(T, struct) * res, + const TEMPLATE(T, struct) * poly1, slong len1, + const TEMPLATE(T, struct) * poly2, slong len2, + const TEMPLATE(T, struct) * f, slong lenf, + const TEMPLATE(T, struct) * finv, slong lenfinv, + const TEMPLATE(T, ctx_t) ctx) +{ + TEMPLATE(T, struct) * T, *Q; + slong lenT, lenQ; + + lenT = len1 + len2 - 1; + lenQ = lenT - lenf + 1; + + T = _TEMPLATE(T, vec_init) (lenT + lenQ, ctx); + Q = T + lenT; + + if (len1 >= len2) + _TEMPLATE(T, poly_mul) (T, poly1, len1, poly2, len2, ctx); + else + _TEMPLATE(T, poly_mul) (T, poly2, len2, poly1, len1, ctx); + + _TEMPLATE(T, poly_divrem_newton_n_preinv) (Q, res, T, lenT, f, lenf, + finv, lenfinv, ctx); + _TEMPLATE(T, vec_clear) (T, lenT + lenQ, ctx); +} + +void +TEMPLATE(T, poly_mulmod_preinv) (TEMPLATE(T, poly_t) res, + const TEMPLATE(T, poly_t) poly1, + const TEMPLATE(T, poly_t) poly2, + const TEMPLATE(T, poly_t) f, + const TEMPLATE(T, poly_t) finv, + const TEMPLATE(T, ctx_t) ctx) +{ + slong len1, len2, lenf; + TEMPLATE(T, struct) * fcoeffs; + + lenf = f->length; + len1 = poly1->length; + len2 = poly2->length; + + if (lenf == 0) + { + TEMPLATE_PRINTF("Exception (%s_poly_mulmod). Divide by zero.\n", T); + abort(); + } + + if (lenf == 1 || len1 == 0 || len2 == 0) + { + TEMPLATE(T, poly_zero) (res, ctx); + return; + } + + if (len1 + len2 - lenf > 0) + { + if (f == res) + { + fcoeffs = _TEMPLATE(T, vec_init) (lenf, ctx); + _TEMPLATE(T, vec_set) (fcoeffs, f->coeffs, lenf, ctx); + } + else + fcoeffs = f->coeffs; + + TEMPLATE(T, poly_fit_length) (res, lenf - 1, ctx); + _TEMPLATE(T, poly_mulmod_preinv) (res->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2, + fcoeffs, lenf, finv->coeffs, + finv->length, ctx); + if (f == res) + _TEMPLATE(T, vec_clear) (fcoeffs, lenf, ctx); + + res->length = lenf - 1; + _TEMPLATE(T, poly_normalise) (res, ctx); + } + else + { + TEMPLATE(T, poly_mul) (res, poly1, poly2, ctx); + } +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/neg.c b/external/flint-2.4.3/fq_poly_templates/neg.c new file mode 100644 index 0000000..013e287 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/neg.c @@ -0,0 +1,53 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +_TEMPLATE(T, poly_neg) (TEMPLATE(T, struct) * rop, + const TEMPLATE(T, struct) * op, slong len, + const TEMPLATE(T, ctx_t) ctx) +{ + slong i; + + for (i = 0; i < len; i++) + TEMPLATE(T, neg) (rop + i, op + i, ctx); +} + +void +TEMPLATE(T, poly_neg) (TEMPLATE(T, poly_t) rop, const TEMPLATE(T, poly_t) op, + const TEMPLATE(T, ctx_t) ctx) +{ + TEMPLATE(T, poly_fit_length) (rop, op->length, ctx); + _TEMPLATE(T, poly_neg) (rop->coeffs, op->coeffs, op->length, ctx); + _TEMPLATE(T, poly_set_length) (rop, op->length, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/normalise.c b/external/flint-2.4.3/fq_poly_templates/normalise.c new file mode 100644 index 0000000..b507d1e --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/normalise.c @@ -0,0 +1,55 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +_TEMPLATE(T, poly_normalise) (TEMPLATE(T, poly_t) poly, + const TEMPLATE(T, ctx_t) ctx) +{ + slong i; + + for (i = poly->length - 1; + (i >= 0) && TEMPLATE(T, is_zero) (poly->coeffs + i, ctx); i--) ; + poly->length = i + 1; +} + +void +_TEMPLATE(T, poly_normalise2) (TEMPLATE(T, struct) * poly, slong * length, + const TEMPLATE(T, ctx_t) ctx) +{ + slong i; + for (i = (*length) - 1; (i >= 0) && TEMPLATE(T, is_zero) (poly + i, ctx); + i--) ; + (*length) = i + 1; +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/one.c b/external/flint-2.4.3/fq_poly_templates/one.c new file mode 100644 index 0000000..445518a --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/one.c @@ -0,0 +1,41 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +TEMPLATE(T, poly_one) (TEMPLATE(T, poly_t) poly, const TEMPLATE(T, ctx_t) ctx) +{ + TEMPLATE(T, poly_fit_length) (poly, 1, ctx); + TEMPLATE(T, one) (poly->coeffs + 0, ctx); + _TEMPLATE(T, poly_set_length) (poly, 1, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/pow.c b/external/flint-2.4.3/fq_poly_templates/pow.c new file mode 100644 index 0000000..3e8f7b7 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/pow.c @@ -0,0 +1,166 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +_TEMPLATE(T, poly_pow) (TEMPLATE(T, struct) * rop, + const TEMPLATE(T, struct) * op, slong len, ulong e, + const TEMPLATE(T, ctx_t) ctx) +{ + ulong bit = ~((~UWORD(0)) >> 1); + slong rlen; + slong alloc = (slong) e * (len - 1) + 1; + TEMPLATE(T, struct) * v = _TEMPLATE(T, vec_init) (alloc, ctx); + TEMPLATE(T, struct) * R, *S, *T; + + /* + Set bits to the bitmask with a 1 one place lower than the msb of e + */ + + while ((bit & e) == UWORD(0)) + bit >>= 1; + + bit >>= 1; + + /* + Trial run without any polynomial arithmetic to determine the parity + of the number of swaps; then set R and S accordingly + */ + + { + unsigned int swaps = 0U; + ulong bit2 = bit; + if ((bit2 & e)) + swaps = ~swaps; + while (bit2 >>= 1) + if ((bit2 & e) == UWORD(0)) + swaps = ~swaps; + + if (swaps == 0U) + { + R = rop; + S = v; + } + else + { + R = v; + S = rop; + } + } + + /* + We unroll the first step of the loop, referring to {poly, len} + */ + + _TEMPLATE(T, poly_sqr) (R, op, len, ctx); + rlen = 2 * len - 1; + if ((bit & e)) + { + _TEMPLATE(T, poly_mul) (S, R, rlen, op, len, ctx); + rlen += len - 1; + T = R; + R = S; + S = T; + } + + while ((bit >>= 1)) + { + if ((bit & e)) + { + _TEMPLATE(T, poly_sqr) (S, R, rlen, ctx); + rlen += rlen - 1; + _TEMPLATE(T, poly_mul) (R, S, rlen, op, len, ctx); + rlen += len - 1; + } + else + { + _TEMPLATE(T, poly_sqr) (S, R, rlen, ctx); + rlen += rlen - 1; + T = R; + R = S; + S = T; + } + } + + _TEMPLATE(T, vec_clear) (v, alloc, ctx); +} + +void +TEMPLATE(T, poly_pow) (TEMPLATE(T, poly_t) rop, const TEMPLATE(T, poly_t) op, + ulong e, const TEMPLATE(T, ctx_t) ctx) +{ + const slong len = op->length; + + if ((len < 2) | (e < UWORD(3))) + { + if (e == UWORD(0)) + TEMPLATE(T, poly_one) (rop, ctx); + else if (len == 0) + TEMPLATE(T, poly_zero) (rop, ctx); + else if (len == 1) + { + fmpz_t f; + fmpz_init_set_ui(f, e); + + TEMPLATE(T, poly_fit_length) (rop, 1, ctx); + TEMPLATE(T, pow) (rop->coeffs + 0, op->coeffs + 0, f, ctx); + _TEMPLATE(T, poly_set_length) (rop, 1, ctx); + + fmpz_clear(f); + } + else if (e == UWORD(1)) + TEMPLATE(T, poly_set) (rop, op, ctx); + else /* e == UWORD(2) */ + TEMPLATE(T, poly_sqr) (rop, op, ctx); + } + else + { + const slong rlen = (slong) e * (len - 1) + 1; + + if (rop != op) + { + TEMPLATE(T, poly_fit_length) (rop, rlen, ctx); + _TEMPLATE(T, poly_pow) (rop->coeffs, op->coeffs, len, e, ctx); + _TEMPLATE(T, poly_set_length) (rop, rlen, ctx); + } + else + { + TEMPLATE(T, poly_t) t; + TEMPLATE(T, poly_init2) (t, rlen, ctx); + _TEMPLATE(T, poly_pow) (t->coeffs, op->coeffs, len, e, ctx); + _TEMPLATE(T, poly_set_length) (t, rlen, ctx); + TEMPLATE(T, poly_swap) (rop, t, ctx); + TEMPLATE(T, poly_clear) (t, ctx); + } + } +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/powmod_fmpz_binexp.c b/external/flint-2.4.3/fq_poly_templates/powmod_fmpz_binexp.c new file mode 100644 index 0000000..f459d37 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/powmod_fmpz_binexp.c @@ -0,0 +1,187 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include +#include "flint.h" +void +_TEMPLATE(T, poly_powmod_fmpz_binexp) ( + TEMPLATE(T, struct) * res, + const TEMPLATE(T, struct) * poly, + const fmpz_t e, + const TEMPLATE(T, struct) * f, slong lenf, + const TEMPLATE(T, ctx_t) ctx) +{ + TEMPLATE(T, struct) * T, *Q; + TEMPLATE(T, t) invf; + slong lenT, lenQ; + slong i; + + if (lenf == 2) + { + TEMPLATE(T, pow) (res, poly, e, ctx); + return; + } + + lenT = 2 * lenf - 3; + lenQ = lenT - lenf + 1; + + T = _TEMPLATE(T, vec_init) (lenT + lenQ, ctx); + Q = T + lenT; + + TEMPLATE(T, init) (invf, ctx); + TEMPLATE(T, inv) (invf, f + lenf - 1, ctx); + + _TEMPLATE(T, vec_set) (res, poly, lenf - 1, ctx); + + for (i = fmpz_sizeinbase(e, 2) - 2; i >= 0; i--) + { + _TEMPLATE(T, poly_sqr) (T, res, lenf - 1, ctx); + _TEMPLATE(T, poly_divrem) (Q, res, T, 2 * lenf - 3, f, lenf, invf, + ctx); + + if (fmpz_tstbit(e, i)) + { + _TEMPLATE(T, poly_mul) (T, res, lenf - 1, poly, lenf - 1, ctx); + _TEMPLATE(T, poly_divrem) (Q, res, T, 2 * lenf - 3, f, lenf, invf, + ctx); + } + } + + TEMPLATE(T, clear) (invf, ctx); + _TEMPLATE(T, vec_clear) (T, lenT + lenQ, ctx); +} + + +void +TEMPLATE(T, poly_powmod_fmpz_binexp) (TEMPLATE(T, poly_t) res, + const TEMPLATE(T, poly_t) poly, + const fmpz_t e, + const TEMPLATE(T, poly_t) f, + const TEMPLATE(T, ctx_t) ctx) +{ + TEMPLATE(T, struct) * q; + slong len = poly->length; + slong lenf = f->length; + slong trunc = lenf - 1; + int qcopy = 0; + + if (lenf == 0) + { + TEMPLATE_PRINTF + ("Exception: %s_poly_powmod_fmpz_binexp: divide by zero\n", T); + abort(); + } + + if (fmpz_sgn(e) < 0) + { + TEMPLATE_PRINTF + ("Exception: %s_poly_powmod_fmpz_binexp: negative exp not implemented\n", + T); + abort(); + } + + if (len >= lenf) + { + TEMPLATE(T, poly_t) t, r; + TEMPLATE(T, poly_init) (t, ctx); + TEMPLATE(T, poly_init) (r, ctx); + TEMPLATE(T, poly_divrem) (t, r, poly, f, ctx); + TEMPLATE(T, poly_powmod_fmpz_binexp) (res, r, e, f, ctx); + TEMPLATE(T, poly_clear) (t, ctx); + TEMPLATE(T, poly_clear) (r, ctx); + return; + } + + if (fmpz_abs_fits_ui(e)) + { + ulong exp = fmpz_get_ui(e); + + if (exp <= 2) + { + if (exp == UWORD(0)) + { + TEMPLATE(T, poly_fit_length) (res, 1, ctx); + TEMPLATE(T, one) (res->coeffs, ctx); + _TEMPLATE(T, poly_set_length) (res, 1, ctx); + } + else if (exp == UWORD(1)) + { + TEMPLATE(T, poly_set) (res, poly, ctx); + } + else + TEMPLATE(T, poly_mulmod) (res, poly, poly, f, ctx); + return; + } + } + + if (lenf == 1 || len == 0) + { + TEMPLATE(T, poly_zero) (res, ctx); + return; + } + + if (poly->length < trunc) + { + q = _TEMPLATE(T, vec_init) (trunc, ctx); + _TEMPLATE(T, vec_set) (q, poly->coeffs, len, ctx); + _TEMPLATE(T, vec_zero) (q + len, trunc - len, ctx); + qcopy = 1; + } + else + { + q = poly->coeffs; + } + + if ((res == poly && !qcopy) || (res == f)) + { + TEMPLATE(T, poly_t) t; + TEMPLATE(T, poly_init2) (t, 2 * lenf - 3, ctx); + _TEMPLATE(T, poly_powmod_fmpz_binexp) (t->coeffs, q, e, f->coeffs, + lenf, ctx); + TEMPLATE(T, poly_swap) (res, t, ctx); + TEMPLATE(T, poly_clear) (t, ctx); + } + else + { + TEMPLATE(T, poly_fit_length) (res, 2 * lenf - 3, ctx); + _TEMPLATE(T, poly_powmod_fmpz_binexp) (res->coeffs, q, e, f->coeffs, + lenf, ctx); + } + + if (qcopy) + _TEMPLATE(T, vec_clear) (q, trunc, ctx); + + _TEMPLATE(T, poly_set_length) (res, trunc, ctx); + _TEMPLATE(T, poly_normalise) (res, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/powmod_fmpz_binexp_preinv.c b/external/flint-2.4.3/fq_poly_templates/powmod_fmpz_binexp_preinv.c new file mode 100644 index 0000000..8a411a8 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/powmod_fmpz_binexp_preinv.c @@ -0,0 +1,188 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +_TEMPLATE(T, poly_powmod_fmpz_binexp_preinv) ( + TEMPLATE(T, struct) * res, + const TEMPLATE(T, struct) * poly, + const fmpz_t e, + const TEMPLATE(T, struct) * f, slong lenf, + const TEMPLATE(T, struct) * finv, slong lenfinv, + const TEMPLATE(T, ctx_t) ctx) +{ + TEMPLATE(T, struct) * T, *Q; + slong lenT, lenQ; + slong i; + + if (lenf == 2) + { + TEMPLATE(T, pow) (res, poly, e, ctx); + return; + } + + lenT = 2 * lenf - 3; + lenQ = lenT - lenf + 1; + + T = _TEMPLATE(T, vec_init) (lenT + lenQ, ctx); + Q = T + lenT; + + _TEMPLATE(T, vec_set) (res, poly, lenf - 1, ctx); + + for (i = fmpz_sizeinbase(e, 2) - 2; i >= 0; i--) + { + _TEMPLATE(T, poly_sqr) (T, res, lenf - 1, ctx); + _TEMPLATE(T, poly_divrem_newton_n_preinv) (Q, res, T, 2 * lenf - 3, f, + lenf, finv, lenfinv, ctx); + + if (fmpz_tstbit(e, i)) + { + _TEMPLATE(T, poly_mul) (T, res, lenf - 1, poly, lenf - 1, ctx); + _TEMPLATE(T, poly_divrem_newton_n_preinv) (Q, res, T, 2 * lenf - 3, + f, lenf, finv, lenfinv, + ctx); + } + } + + _TEMPLATE(T, vec_clear) (T, lenT + lenQ, ctx); +} + + +void +TEMPLATE(T, poly_powmod_fmpz_binexp_preinv) (TEMPLATE(T, poly_t) res, + const TEMPLATE(T, poly_t) poly, + const fmpz_t e, + const TEMPLATE(T, poly_t) f, + const TEMPLATE(T, poly_t) finv, + const TEMPLATE(T, ctx_t) ctx) +{ + TEMPLATE(T, struct) * q; + slong len = poly->length; + slong lenf = f->length; + slong trunc = lenf - 1; + int qcopy = 0; + + if (lenf == 0) + { + TEMPLATE_PRINTF + ("Exception: %s_poly_powmod_fmpz_binexp_preinv: divide by zero\n", + T); + abort(); + } + + if (fmpz_sgn(e) < 0) + { + TEMPLATE_PRINTF + ("Exception: %s_poly_powmod_fmpz_binexp_preinv: negative exp not implemented\n", + T); + abort(); + } + + if (len >= lenf) + { + TEMPLATE(T, poly_t) t, r; + TEMPLATE(T, poly_init) (t, ctx); + TEMPLATE(T, poly_init) (r, ctx); + TEMPLATE(T, poly_divrem) (t, r, poly, f, ctx); + TEMPLATE(T, poly_powmod_fmpz_binexp_preinv) (res, r, e, f, finv, ctx); + TEMPLATE(T, poly_clear) (t, ctx); + TEMPLATE(T, poly_clear) (r, ctx); + return; + } + + if (fmpz_abs_fits_ui(e)) + { + ulong exp = fmpz_get_ui(e); + + if (exp <= 2) + { + if (exp == UWORD(0)) + { + TEMPLATE(T, poly_fit_length) (res, 1, ctx); + TEMPLATE(T, one) (res->coeffs, ctx); + _TEMPLATE(T, poly_set_length) (res, 1, ctx); + } + else if (exp == UWORD(1)) + { + TEMPLATE(T, poly_set) (res, poly, ctx); + } + else + TEMPLATE(T, poly_mulmod_preinv) (res, poly, poly, f, finv, + ctx); + return; + } + } + + if (lenf == 1 || len == 0) + { + TEMPLATE(T, poly_zero) (res, ctx); + return; + } + + if (poly->length < trunc) + { + q = _TEMPLATE(T, vec_init) (trunc, ctx); + _TEMPLATE(T, vec_set) (q, poly->coeffs, len, ctx); + _TEMPLATE(T, vec_zero) (q + len, trunc - len, ctx); + qcopy = 1; + } + else + { + q = poly->coeffs; + } + + if ((res == poly && !qcopy) || (res == f)) + { + TEMPLATE(T, poly_t) t; + TEMPLATE(T, poly_init2) (t, 2 * lenf - 3, ctx); + _TEMPLATE(T, poly_powmod_fmpz_binexp_preinv) (t->coeffs, q, e, + f->coeffs, lenf, + finv->coeffs, + finv->length, ctx); + TEMPLATE(T, poly_swap) (res, t, ctx); + TEMPLATE(T, poly_clear) (t, ctx); + } + else + { + TEMPLATE(T, poly_fit_length) (res, 2 * lenf - 3, ctx); + _TEMPLATE(T, poly_powmod_fmpz_binexp_preinv) (res->coeffs, q, e, + f->coeffs, lenf, + finv->coeffs, + finv->length, ctx); + } + + if (qcopy) + _TEMPLATE(T, vec_clear) (q, trunc, ctx); + + _TEMPLATE(T, poly_set_length) (res, trunc, ctx); + _TEMPLATE(T, poly_normalise) (res, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/powmod_fmpz_sliding_preinv.c b/external/flint-2.4.3/fq_poly_templates/powmod_fmpz_sliding_preinv.c new file mode 100644 index 0000000..8bf3ba1 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/powmod_fmpz_sliding_preinv.c @@ -0,0 +1,274 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +_TEMPLATE(T, poly_powmod_fmpz_sliding_preinv) ( + TEMPLATE(T, struct) * res, + const TEMPLATE(T, struct) * poly, + const fmpz_t e, ulong k, + const TEMPLATE(T, struct) * f, slong lenf, + const TEMPLATE(T, struct) * finv, slong lenfinv, + const TEMPLATE(T, ctx_t) ctx) +{ + TEMPLATE(T, struct) * T, *Q; + TEMPLATE(T, poly_struct) * precomp; + TEMPLATE(T, poly_t) poly_squared; + ulong twokm1; + slong lenT, lenQ; + slong i, l, j; + int index; + + if (lenf == 2) + { + TEMPLATE(T, pow) (res, poly, e, ctx); + return; + } + + lenT = 2 * lenf - 3; + lenQ = lenT - lenf + 1; + + T = _TEMPLATE(T, vec_init) (lenT + lenQ, ctx); + Q = T + lenT; + + /* Precomputation */ + twokm1 = n_pow(2, k - 1); + precomp = flint_malloc(twokm1 * sizeof(TEMPLATE(T, poly_struct))); + TEMPLATE(T, poly_init) (precomp, ctx); + TEMPLATE(T, poly_fit_length) (precomp, lenf - 1, ctx); + _TEMPLATE(T, vec_set) (precomp->coeffs, poly, lenf - 1, ctx); + + TEMPLATE(T, poly_init) (poly_squared, ctx); + if (k > 1) + { + TEMPLATE(T, poly_fit_length) (poly_squared, lenf - 1, ctx); + _TEMPLATE(T, poly_mul) (T, poly, lenf - 1, poly, lenf - 1, ctx); + _TEMPLATE(T, poly_divrem_newton_n_preinv) (Q, poly_squared->coeffs, T, + 2 * lenf - 3, f, lenf, finv, + lenfinv, ctx); + } + for (i = 1; i < twokm1; i++) + { + TEMPLATE(T, poly_init) (precomp + i, ctx); + TEMPLATE(T, poly_fit_length) (precomp + i, lenf - 1, ctx); + _TEMPLATE(T, poly_mul) (T, (precomp + i - 1)->coeffs, lenf - 1, + poly_squared->coeffs, lenf - 1, ctx); + _TEMPLATE(T, poly_divrem_newton_n_preinv) (Q, (precomp + i)->coeffs, T, + 2 * lenf - 3, f, lenf, finv, + lenfinv, ctx); + } + + _TEMPLATE(T, vec_set) (res, poly, lenf - 1, ctx); + + i = fmpz_sizeinbase(e, 2) - 2; + while (i >= 0) + { + if (fmpz_tstbit(e, i) == 0) + { + _TEMPLATE(T, poly_sqr) (T, res, lenf - 1, ctx); + _TEMPLATE(T, poly_divrem_newton_n_preinv) (Q, res, T, 2 * lenf - 3, + f, lenf, finv, lenfinv, + ctx); + i -= 1; + } + else + { + l = FLINT_MAX(i - k + 1, 0); + while (fmpz_tstbit(e, l) == 0) + { + l += 1; + } + for (j = 0; j < i - l + 1; j++) + { + _TEMPLATE(T, poly_sqr) (T, res, lenf - 1, ctx); + _TEMPLATE(T, poly_divrem_newton_n_preinv) (Q, res, T, + 2 * lenf - 3, f, + lenf, finv, lenfinv, + ctx); + } + + index = fmpz_tstbit(e, i); + for (j = i - 1; j >= l; j--) + { + index = index << 1; + index += fmpz_tstbit(e, j); + } + index = (index - 1) / 2; + + _TEMPLATE(T, poly_mul) (T, res, lenf - 1, + (precomp + index)->coeffs, lenf - 1, ctx); + _TEMPLATE(T, poly_divrem_newton_n_preinv) (Q, res, T, 2 * lenf - 3, + f, lenf, finv, lenfinv, + ctx); + i = l - 1; + } + } + + for (j = 0; j < twokm1; j++) + { + TEMPLATE(T, poly_clear) (precomp + j, ctx); + } + flint_free(precomp); + TEMPLATE(T, poly_clear) (poly_squared, ctx); + _TEMPLATE(T, vec_clear) (T, lenT + lenQ, ctx); +} + + +void +TEMPLATE(T, poly_powmod_fmpz_sliding_preinv) (TEMPLATE(T, poly_t) res, + const TEMPLATE(T, poly_t) poly, + const fmpz_t e, ulong k, + const TEMPLATE(T, poly_t) f, + const TEMPLATE(T, poly_t) finv, + const TEMPLATE(T, ctx_t) ctx) +{ + TEMPLATE(T, struct) * q; + slong len = poly->length; + slong lenf = f->length; + slong trunc = lenf - 1; + int qcopy = 0; + mp_bitcnt_t bits; + + if (lenf == 0) + { + TEMPLATE_PRINTF("Exception: %s_poly_powmod_fmpz_sliding_preinv", T); + flint_printf(": divide by zero\n"); + abort(); + } + + if (fmpz_sgn(e) < 0) + { + TEMPLATE_PRINTF("Exception: %s_poly_powmod_fmpz_sliding_preinv:", T); + flint_printf(" negative exp not implemented\n"); + abort(); + } + + if (len >= lenf) + { + TEMPLATE(T, poly_t) t, r; + TEMPLATE(T, poly_init) (t, ctx); + TEMPLATE(T, poly_init) (r, ctx); + TEMPLATE(T, poly_divrem) (t, r, poly, f, ctx); + TEMPLATE(T, poly_powmod_fmpz_sliding_preinv) (res, r, e, k, f, finv, + ctx); + TEMPLATE(T, poly_clear) (t, ctx); + TEMPLATE(T, poly_clear) (r, ctx); + return; + } + + if (fmpz_abs_fits_ui(e)) + { + ulong exp = fmpz_get_ui(e); + + if (exp <= 2) + { + if (exp == UWORD(0)) + { + TEMPLATE(T, poly_fit_length) (res, 1, ctx); + TEMPLATE(T, one) (res->coeffs, ctx); + _TEMPLATE(T, poly_set_length) (res, 1, ctx); + } + else if (exp == UWORD(1)) + { + TEMPLATE(T, poly_set) (res, poly, ctx); + } + else + TEMPLATE(T, poly_mulmod_preinv) (res, poly, poly, f, finv, + ctx); + return; + } + } + + if (lenf == 1 || len == 0) + { + TEMPLATE(T, poly_zero) (res, ctx); + return; + } + + if (poly->length < trunc) + { + q = _TEMPLATE(T, vec_init) (trunc, ctx); + _TEMPLATE(T, vec_set) (q, poly->coeffs, len, ctx); + _TEMPLATE(T, vec_zero) (q + len, trunc - len, ctx); + qcopy = 1; + } + else + { + q = poly->coeffs; + } + + /* Determine "optimum" sliding window size */ + if (k == 0) + { + bits = fmpz_bits(e); + if (bits < 9) + k = 1; + else if (bits < 15) + k = 2; + else if (bits < 62) + k = 3; + else if (bits < 203) + k = 4; + else if (bits < 587) + k = 5; + else if (bits < 1560) + k = 6; + else + k = 7; + } + + if ((res == poly && !qcopy) || (res == f)) + { + TEMPLATE(T, poly_t) t; + TEMPLATE(T, poly_init2) (t, 2 * lenf - 3, ctx); + _TEMPLATE(T, poly_powmod_fmpz_sliding_preinv) (t->coeffs, q, e, k, + f->coeffs, lenf, + finv->coeffs, + finv->length, ctx); + TEMPLATE(T, poly_swap) (res, t, ctx); + TEMPLATE(T, poly_clear) (t, ctx); + } + else + { + TEMPLATE(T, poly_fit_length) (res, 2 * lenf - 3, ctx); + _TEMPLATE(T, poly_powmod_fmpz_sliding_preinv) (res->coeffs, q, e, k, + f->coeffs, lenf, + finv->coeffs, + finv->length, ctx); + } + + if (qcopy) + _TEMPLATE(T, vec_clear) (q, trunc, ctx); + + _TEMPLATE(T, poly_set_length) (res, trunc, ctx); + _TEMPLATE(T, poly_normalise) (res, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/powmod_ui_binexp.c b/external/flint-2.4.3/fq_poly_templates/powmod_ui_binexp.c new file mode 100644 index 0000000..3088351 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/powmod_ui_binexp.c @@ -0,0 +1,170 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include +#include "flint.h" +#include "ulong_extras.h" +void +_TEMPLATE(T, poly_powmod_ui_binexp) (TEMPLATE(T, struct) * res, + const TEMPLATE(T, struct) * poly, ulong e, + const TEMPLATE(T, struct) * f, slong lenf, + const TEMPLATE(T, ctx_t) ctx) +{ + TEMPLATE(T, struct) * T, *Q; + TEMPLATE(T, t) invf; + slong lenT, lenQ; + int i; + + if (lenf == 2) + { + TEMPLATE(T, pow_ui) (res, poly, e, ctx); + return; + } + + lenT = 2 * lenf - 3; + lenQ = FLINT_MAX(lenT - lenf + 1, 1); + + T = _TEMPLATE(T, vec_init) (lenT + lenQ, ctx); + Q = T + lenT; + + TEMPLATE(T, init) (invf, ctx); + TEMPLATE(T, inv) (invf, f + lenf - 1, ctx); + + _TEMPLATE(T, vec_set) (res, poly, lenf - 1, ctx); + + for (i = ((int)FLINT_BIT_COUNT(e) - 2); i >= 0; i--) + { + _TEMPLATE(T, poly_sqr) (T, res, lenf - 1, ctx); + _TEMPLATE(T, poly_divrem) (Q, res, T, 2 * lenf - 3, f, lenf, invf, + ctx); + + if (e & (UWORD(1) << i)) + { + _TEMPLATE(T, poly_mul) (T, res, lenf - 1, poly, lenf - 1, ctx); + _TEMPLATE(T, poly_divrem) (Q, res, T, 2 * lenf - 3, f, lenf, invf, + ctx); + } + } + + TEMPLATE(T, clear) (invf, ctx); + _TEMPLATE(T, vec_clear) (T, lenT + lenQ, ctx); +} + + +void +TEMPLATE(T, poly_powmod_ui_binexp) (TEMPLATE(T, poly_t) res, + const TEMPLATE(T, poly_t) poly, ulong e, + const TEMPLATE(T, poly_t) f, + const TEMPLATE(T, ctx_t) ctx) +{ + TEMPLATE(T, struct) * q; + slong len = poly->length; + slong lenf = f->length; + slong trunc = lenf - 1; + int qcopy = 0; + + if (lenf == 0) + { + TEMPLATE_PRINTF + ("Exception: %s_poly_powmod_ui_binexp: divide by zero\n", T); + abort(); + } + + if (len >= lenf) + { + TEMPLATE(T, poly_t) t, r; + TEMPLATE(T, poly_init) (t, ctx); + TEMPLATE(T, poly_init) (r, ctx); + TEMPLATE(T, poly_divrem) (t, r, poly, f, ctx); + TEMPLATE(T, poly_powmod_ui_binexp) (res, r, e, f, ctx); + TEMPLATE(T, poly_clear) (t, ctx); + TEMPLATE(T, poly_clear) (r, ctx); + return; + } + + if (e <= 2) + { + if (e == UWORD(0)) + { + TEMPLATE(T, poly_fit_length) (res, 1, ctx); + TEMPLATE(T, one) (res->coeffs, ctx); + _TEMPLATE(T, poly_set_length) (res, 1, ctx); + } + else if (e == UWORD(1)) + { + TEMPLATE(T, poly_set) (res, poly, ctx); + } + else + TEMPLATE(T, poly_mulmod) (res, poly, poly, f, ctx); + return; + } + + if (lenf == 1 || len == 0) + { + TEMPLATE(T, poly_zero) (res, ctx); + return; + } + + if (len < trunc) + { + q = _TEMPLATE(T, vec_init) (trunc, ctx); + _TEMPLATE(T, vec_set) (q, poly->coeffs, len, ctx); + _TEMPLATE(T, vec_zero) (q + len, trunc - len, ctx); + qcopy = 1; + } + else + q = poly->coeffs; + + if ((res == poly && !qcopy) || (res == f)) + { + TEMPLATE(T, poly_t) t; + TEMPLATE(T, poly_init2) (t, 2 * lenf - 3, ctx); + _TEMPLATE(T, poly_powmod_ui_binexp) (t->coeffs, q, e, f->coeffs, lenf, + ctx); + TEMPLATE(T, poly_swap) (res, t, ctx); + TEMPLATE(T, poly_clear) (t, ctx); + } + else + { + TEMPLATE(T, poly_fit_length) (res, 2 * lenf - 3, ctx); + _TEMPLATE(T, poly_powmod_ui_binexp) (res->coeffs, q, e, f->coeffs, + lenf, ctx); + } + + if (qcopy) + _TEMPLATE(T, vec_clear) (q, trunc, ctx); + + _TEMPLATE(T, poly_set_length) (res, trunc, ctx); + _TEMPLATE(T, poly_normalise) (res, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/powmod_ui_binexp_preinv.c b/external/flint-2.4.3/fq_poly_templates/powmod_ui_binexp_preinv.c new file mode 100644 index 0000000..407126b --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/powmod_ui_binexp_preinv.c @@ -0,0 +1,170 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +_TEMPLATE(T, poly_powmod_ui_binexp_preinv) ( + TEMPLATE(T, struct) * res, + const TEMPLATE(T, struct) * poly, + ulong e, + const TEMPLATE(T, struct) * f, slong lenf, + const TEMPLATE(T, struct) * finv, slong lenfinv, + const TEMPLATE(T, ctx_t) ctx) +{ + TEMPLATE(T, struct) * T, *Q; + slong lenT, lenQ; + int i; + + if (lenf == 2) + { + TEMPLATE(T, pow_ui) (res, poly, e, ctx); + return; + } + + lenT = 2 * lenf - 3; + lenQ = FLINT_MAX(lenT - lenf + 1, 1); + + T = _TEMPLATE(T, vec_init) (lenT + lenQ, ctx); + Q = T + lenT; + + _TEMPLATE(T, vec_set) (res, poly, lenf - 1, ctx); + + for (i = ((int)FLINT_BIT_COUNT(e) - 2); i >= 0; i--) + { + _TEMPLATE(T, poly_sqr) (T, res, lenf - 1, ctx); + _TEMPLATE(T, poly_divrem_newton_n_preinv) (Q, res, T, 2 * lenf - 3, f, + lenf, finv, lenfinv, ctx); + + if (e & (UWORD(1) << i)) + { + _TEMPLATE(T, poly_mul) (T, res, lenf - 1, poly, lenf - 1, ctx); + _TEMPLATE(T, poly_divrem_newton_n_preinv) (Q, res, T, 2 * lenf - 3, + f, lenf, finv, lenfinv, + ctx); + } + } + + _TEMPLATE(T, vec_clear) (T, lenT + lenQ, ctx); +} + + +void +TEMPLATE(T, poly_powmod_ui_binexp_preinv) (TEMPLATE(T, poly_t) res, + const TEMPLATE(T, poly_t) poly, + ulong e, + const TEMPLATE(T, poly_t) f, + const TEMPLATE(T, poly_t) finv, + const TEMPLATE(T, ctx_t) ctx) +{ + TEMPLATE(T, struct) * q; + slong len = poly->length; + slong lenf = f->length; + slong trunc = lenf - 1; + int qcopy = 0; + + if (lenf == 0) + { + TEMPLATE_PRINTF("Exception: %s_poly_powmod: divide by zero\n", T); + abort(); + } + + if (len >= lenf) + { + TEMPLATE(T, poly_t) t, r; + TEMPLATE(T, poly_init) (t, ctx); + TEMPLATE(T, poly_init) (r, ctx); + TEMPLATE(T, poly_divrem) (t, r, poly, f, ctx); + TEMPLATE(T, poly_powmod_ui_binexp_preinv) (res, r, e, f, finv, ctx); + TEMPLATE(T, poly_clear) (t, ctx); + TEMPLATE(T, poly_clear) (r, ctx); + return; + } + + if (e <= 2) + { + if (e == UWORD(0)) + { + TEMPLATE(T, poly_fit_length) (res, 1, ctx); + TEMPLATE(T, one) (res->coeffs, ctx); + _TEMPLATE(T, poly_set_length) (res, 1, ctx); + } + else if (e == UWORD(1)) + { + TEMPLATE(T, poly_set) (res, poly, ctx); + } + else + TEMPLATE(T, poly_mulmod_preinv) (res, poly, poly, f, finv, ctx); + return; + } + + if (lenf == 1 || len == 0) + { + TEMPLATE(T, poly_zero) (res, ctx); + return; + } + + if (len < trunc) + { + q = _TEMPLATE(T, vec_init) (trunc, ctx); + _TEMPLATE(T, vec_set) (q, poly->coeffs, len, ctx); + _TEMPLATE(T, vec_zero) (q + len, trunc - len, ctx); + qcopy = 1; + } + else + q = poly->coeffs; + + if ((res == poly && !qcopy) || (res == f)) + { + TEMPLATE(T, poly_t) t; + TEMPLATE(T, poly_init2) (t, 2 * lenf - 3, ctx); + _TEMPLATE(T, poly_powmod_ui_binexp_preinv) (t->coeffs, q, e, + f->coeffs, lenf, + finv->coeffs, finv->length, + ctx); + TEMPLATE(T, poly_swap) (res, t, ctx); + TEMPLATE(T, poly_clear) (t, ctx); + } + else + { + TEMPLATE(T, poly_fit_length) (res, 2 * lenf - 3, ctx); + _TEMPLATE(T, poly_powmod_ui_binexp_preinv) (res->coeffs, q, e, + f->coeffs, lenf, + finv->coeffs, finv->length, + ctx); + } + + if (qcopy) + _TEMPLATE(T, vec_clear) (q, trunc, ctx); + + _TEMPLATE(T, poly_set_length) (res, trunc, ctx); + _TEMPLATE(T, poly_normalise) (res, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/powmod_x_fmpz_preinv.c b/external/flint-2.4.3/fq_poly_templates/powmod_x_fmpz_preinv.c new file mode 100644 index 0000000..50e64f3 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/powmod_x_fmpz_preinv.c @@ -0,0 +1,212 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Martin Lee + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" +#include "long_extras.h" + +void +_TEMPLATE(T, poly_powmod_x_fmpz_preinv) ( + TEMPLATE(T, struct) * res, + const fmpz_t e, + const TEMPLATE(T, struct) * f, slong lenf, + const TEMPLATE(T, struct) * finv, slong lenfinv, + const TEMPLATE(T, ctx_t) ctx) +{ + TEMPLATE(T, struct) * T, *Q; + slong lenT, lenQ; + slong i, window, l, c; + + lenT = 2 * lenf - 3; + lenQ = lenT - lenf + 1; + + T = _TEMPLATE(T, vec_init) (lenT + lenQ, ctx); + Q = T + lenT; + + TEMPLATE(T, one) (res, ctx); + + l = z_sizeinbase(lenf - 1, 2) - 2; + window = 0; + window = (1 << l); + c = l; + i = fmpz_sizeinbase(e, 2) - 2; + + if (i <= l) + { + window = 0; + window = (1 << i); + c = i; + l = i; + } + + if (c == 0) + { + _TEMPLATE(T, poly_shift_left) (T, res, lenf - 1, window, ctx); + _TEMPLATE(T, poly_divrem_newton_n_preinv) (Q, res, T, + lenf - 1 + window, f, lenf, + finv, lenfinv, ctx); + c = l + 1; + window = 0; + } + + for (; i >= 0; i--) + { + _TEMPLATE(T, poly_sqr) (T, res, lenf - 1, ctx); + _TEMPLATE(T, poly_divrem_newton_n_preinv) (Q, res, T, 2 * lenf - 3, f, + lenf, finv, lenfinv, ctx); + + c--; + if (fmpz_tstbit(e, i)) + { + if (window == 0 && i <= l - 1) + c = i; + if (c >= 0) + window = window | (1 << c); + } + else if (window == 0) + { + c = l + 1; + } + if (c == 0) + { + _TEMPLATE(T, poly_shift_left) (T, res, lenf - 1, window, ctx); + + _TEMPLATE(T, poly_divrem_newton_n_preinv) (Q, res, T, + lenf - 1 + window, f, + lenf, finv, lenfinv, + ctx); + c = l + 1; + window = 0; + } + } + + _TEMPLATE(T, vec_clear) (T, lenT + lenQ, ctx); +} + + +void +TEMPLATE(T, poly_powmod_x_fmpz_preinv) (TEMPLATE(T, poly_t) res, + const fmpz_t e, + const TEMPLATE(T, poly_t) f, + const TEMPLATE(T, poly_t) finv, + const TEMPLATE(T, ctx_t) ctx) +{ + slong lenf = f->length; + slong trunc = lenf - 1; + TEMPLATE(T, poly_t) tmp; + + if (lenf == 0) + { + TEMPLATE_PRINTF("Exception: %s_poly_powmod_x_preinv:", T); + flint_printf(" divide by zero\n"); + abort(); + } + + if (fmpz_sgn(e) < 0) + { + TEMPLATE_PRINTF("Exception: %s_poly_powmod_x_preinv: ", T); + flint_printf(" negative exp not implemented\n"); + abort(); + } + + if (lenf == 1) + { + TEMPLATE(T, poly_zero) (res, ctx); + return; + } + + if (lenf == 2) + { + TEMPLATE(T, poly_t) r, poly; + TEMPLATE(T, poly_init) (tmp, ctx); + TEMPLATE(T, poly_init) (r, ctx); + TEMPLATE(T, poly_init2) (poly, 2, ctx); + TEMPLATE(T, poly_gen) (poly, ctx); + TEMPLATE(T, poly_divrem) (tmp, r, poly, f, ctx); + TEMPLATE(T, poly_powmod_fmpz_binexp_preinv) (res, r, e, f, finv, ctx); + TEMPLATE(T, poly_clear) (tmp, ctx); + TEMPLATE(T, poly_clear) (r, ctx); + TEMPLATE(T, poly_clear) (poly, ctx); + return; + } + + if (fmpz_abs_fits_ui(e)) + { + ulong exp = fmpz_get_ui(e); + + if (exp <= 2) + { + if (exp == UWORD(0)) + { + TEMPLATE(T, poly_fit_length) (res, 1, ctx); + TEMPLATE(T, one) (res->coeffs, ctx); + _TEMPLATE(T, poly_set_length) (res, 1, ctx); + } + else if (exp == UWORD(1)) + { + TEMPLATE(T, poly_t) r; + TEMPLATE(T, poly_init2) (r, 2, ctx); + TEMPLATE(T, poly_gen) (r, ctx); + TEMPLATE(T, poly_init) (tmp, ctx); + TEMPLATE(T, poly_divrem) (tmp, res, r, f, ctx); + TEMPLATE(T, poly_clear) (tmp, ctx); + TEMPLATE(T, poly_clear) (r, ctx); + } + else + { + TEMPLATE(T, poly_init2) (tmp, 3, ctx); + TEMPLATE(T, poly_gen) (tmp, ctx); + TEMPLATE(T, poly_mulmod) (res, tmp, tmp, f, ctx); + TEMPLATE(T, poly_clear) (tmp, ctx); + } + return; + } + } + + if ((res == f) || (res == finv)) + { + TEMPLATE(T, poly_init2) (tmp, trunc, ctx); + _TEMPLATE(T, poly_powmod_x_fmpz_preinv) (tmp->coeffs, e, f->coeffs, + lenf, finv->coeffs, + finv->length, ctx); + TEMPLATE(T, poly_swap) (res, tmp, ctx); + TEMPLATE(T, poly_clear) (tmp, ctx); + } + else + { + TEMPLATE(T, poly_fit_length) (res, trunc, ctx); + _TEMPLATE(T, poly_powmod_x_fmpz_preinv) (res->coeffs, e, f->coeffs, + lenf, finv->coeffs, + finv->length, ctx); + } + + _TEMPLATE(T, poly_set_length) (res, trunc, ctx); + _TEMPLATE(T, poly_normalise) (res, ctx); +} + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/profile/p-factor_xnpxp1.c b/external/flint-2.4.3/fq_poly_templates/profile/p-factor_xnpxp1.c new file mode 100644 index 0000000..89fd70a --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/profile/p-factor_xnpxp1.c @@ -0,0 +1,88 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "flint.h" +#include "templates.h" + +#include "profiler.h" + +#define nalgs 1 +#define ncases 1 +#define cpumin 2 + +int +main(int argc, char** argv) +{ + int len, ext; + fmpz_t p, temp; + TEMPLATE(T, poly_t) f; + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_factor_t) res; + timeit_t t; + + FLINT_TEST_INIT(state); + + fmpz_init(p); + fmpz_set_str(p, argv[1], 10); + + fmpz_init(temp); + + fmpz_set_str(temp, argv[2], 10); + ext = fmpz_get_si(temp); + + fmpz_set_str(temp, argv[3], 10); + len = fmpz_get_si(temp); + + TEMPLATE(T, ctx_init)(ctx, p, ext, "a"); + + TEMPLATE(T, poly_init)(f, ctx); + fmpz_one(temp); + TEMPLATE(T, poly_set_coeff_fmpz)(f, len + 1, temp, ctx); + TEMPLATE(T, poly_set_coeff_fmpz)(f, 1, temp, ctx); + TEMPLATE(T, poly_set_coeff_fmpz)(f, 0, temp, ctx); + + TEMPLATE(T, poly_factor_init)(res, ctx); + timeit_start(t); + TEMPLATE(T, poly_factor_kaltofen_shoup)(res, f, ctx); + timeit_stop(t); + TEMPLATE(T, poly_factor_clear)(res, ctx); + + flint_printf("%wd\n", t->cpu); + + TEMPLATE(T, poly_clear)(f, ctx); + TEMPLATE(T, ctx_clear)(ctx); + + fmpz_clear(p); + fmpz_clear(temp); + + FLINT_TEST_CLEANUP(state); + + return 0; +} + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/profile/p-is_irreducible.c b/external/flint-2.4.3/fq_poly_templates/profile/p-is_irreducible.c new file mode 100644 index 0000000..7a6ebd1 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/profile/p-is_irreducible.c @@ -0,0 +1,129 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#ifdef T + +#include "flint.h" +#include "templates.h" +#include "profiler.h" + +#define nalgs 2 +#define ncases 20 +#define cpumin 2 + +int +main(int argc, char** argv) +{ + double s[nalgs]; + + int c, n, lenf, ext, reps = 0; + fmpz_t p, temp; + TEMPLATE(T, poly_t) f; + TEMPLATE(T, ctx_t) ctx; + + FLINT_TEST_INIT(state); + + fmpz_init(p); + fmpz_set_str(p, argv[1], 10); + + fmpz_init(temp); + + fmpz_set_str(temp, argv[2], 10); + ext = fmpz_get_si(temp); + + lenf = atol(argv[3]); + + TEMPLATE(T, ctx_init)(ctx, p, ext, "a"); + + TEMPLATE(T, poly_init)(f, ctx); + + for (c = 0; c < nalgs; c++) + { + s[c] = 0.0; + } + + for (n = 0; n < ncases; n++) + { + double t[nalgs]; + int l, loops = 1; + + /* + Construct random elements of fq + */ + { + TEMPLATE(T, poly_randtest_monic)(f, state, lenf, ctx); + } + + loop: + t[0] = 0.0; + init_clock(0); + prof_start(); + for (l = 0; l < loops; l++) + { + TEMPLATE(T, poly_is_irreducible_ben_or)(f, ctx); + } + prof_stop(); + t[0] += get_clock(0); + + t[1] = 0.0; + init_clock(0); + prof_start(); + for (l = 0; l < loops; l++) + { + TEMPLATE(T, poly_is_irreducible_ddf)(f, ctx); + } + prof_stop(); + t[1] += get_clock(0); + + for (c = 0; c < nalgs; c++) + if (t[c] * FLINT_CLOCK_SCALE_FACTOR <= cpumin) + { + loops *= 10; + goto loop; + } + + for (c = 0; c < nalgs; c++) + s[c] += t[c]; + reps += loops; + } + + for (c = 0; c < nalgs; c++) + { + flint_printf("%20f ", s[c] / (double) reps); + fflush(stdout); + } + printf("\n"); + + TEMPLATE(T, poly_clear)(f, ctx); + TEMPLATE(T, ctx_clear)(ctx); + fmpz_clear(p); + fmpz_clear(temp); + + FLINT_TEST_CLEANUP(state); + + return 0; +} + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/profile/p-iterated_frobenius.c b/external/flint-2.4.3/fq_poly_templates/profile/p-iterated_frobenius.c new file mode 100644 index 0000000..adbb1e6 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/profile/p-iterated_frobenius.c @@ -0,0 +1,196 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#ifdef T + +#include "flint.h" +#include "templates.h" + +#include +#include "profiler.h" + +#define nalgs 2 +#define cpumin 2 +#define ncases 1 + +int +main(int argc, char** argv) +{ + fmpz_t p, q; + int c, n, reps = 0; + slong d, lenf; + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) f, *h, finv; + TEMPLATE(T, mat_t) HH; + slong i, l; + double beta; + + double s[nalgs]; + + FLINT_TEST_INIT(state); + + fmpz_init(p); + fmpz_set_str(p, argv[1], 10); + + d = atol(argv[2]); + lenf = atol(argv[3]); + + beta = 0.5 * (1. - (log(2) / log(lenf))); + l = ceil(pow(lenf, beta)); + + TEMPLATE(T, ctx_init)(ctx, p, d, "a"); + + TEMPLATE(T, poly_init)(f, ctx); + TEMPLATE(T, poly_init)(finv, ctx); + + fmpz_init(q); + TEMPLATE(T, ctx_order)(q, ctx); + + if (l < 2) + { + printf("l < 2!\n"); + } + + if (!(h = flint_malloc((l + 1) * sizeof(TEMPLATE(T, poly_struct))))) + { + printf("Exception (p-iterated_frobenius):\n"); + printf("Not enough memory.\n"); + abort(); + } + + for (i = 0; i < l + 1; i++) + TEMPLATE(T, poly_init)(h[i], ctx); + + for (c = 0; c < nalgs; c++) + s[c] = 0.0; + + for (n = 0; n < ncases; n++) + { + double t[nalgs]; + int lo, loops = 1; + + /* + Construct random elements of fq + */ + { + TEMPLATE(T, poly_randtest_monic)(f, state, lenf, ctx); + TEMPLATE(T, poly_reverse)(finv, f, f->length, ctx); + TEMPLATE(T, poly_inv_series_newton)(finv, finv, f->length, ctx); + } + + loop: + + t[0] = 0.0; + init_clock(0); + prof_start(); + for (lo = 0; lo < loops; lo++) + { + TEMPLATE(T, poly_gen)(h[0], ctx); + TEMPLATE(T, mat_init)(HH, n_sqrt(f->length - 1) + 1, f->length - 1, ctx); + TEMPLATE(T, poly_powmod_fmpz_sliding_preinv)(h[1], h[0], q, 0, f, finv, ctx); + TEMPLATE(T, poly_precompute_matrix)(HH, h[1], f, finv, ctx); + for (i = 2; i < l + 1; i++) + TEMPLATE(T, poly_compose_mod_brent_kung_precomp_preinv)(h[i], h[i - 1], + HH, f, finv, ctx); + TEMPLATE(T, mat_clear)(HH, ctx); + } + prof_stop(); + t[0] += get_clock(0); + + + t[1] = 0.0; + init_clock(0); + prof_start(); + for (lo = 0; lo < loops; lo++) + { + TEMPLATE(T, poly_gen)(h[0], ctx); + TEMPLATE(T, poly_powmod_fmpz_sliding_preinv)(h[1], h[0], q, 0, f, finv, ctx); + for (i = 2; i < l + 1; i++) + TEMPLATE(T, poly_powmod_fmpz_sliding_preinv)(h[i], h[i-1], q, 0, f, finv, ctx); + } + prof_stop(); + t[1] += get_clock(0); + + /*t[2] = 0.0; + init_clock(0); + prof_start(); + for (lo = 0; lo < loops; lo++) + { + TEMPLATE(T, poly_gen)(h[0], ctx); + TEMPLATE(T, poly_powmod_x_fmpz_preinv)(h[1], q, f, finv, ctx); + for (i = 2; i < l + 1; i++) + TEMPLATE(T, poly_compose_mod_preinv)(h[i], h[i-1], h[1], f, finv, ctx); + } + prof_stop(); + t[2] += get_clock(0); + + t[3] = 0.0; + init_clock(0); + prof_start(); + for (lo = 0; lo < loops; lo++) + { + TEMPLATE(T, poly_gen)(h[0], ctx); + TEMPLATE(T, poly_powmod_x_fmpz_preinv)(h[1], q, f, finv, ctx); + for (i = 2; i < l + 1; i++) + TEMPLATE(T, poly_powmod_fmpz_sliding_preinv)(h[i], h[i-1], q, 0, f, finv, ctx); + } + prof_stop(); + t[3] += get_clock(0); + */ + + for (c = 0; c < nalgs; c++) + if (t[c] * FLINT_CLOCK_SCALE_FACTOR <= cpumin) + { + loops *= 10; + goto loop; + } + + for (c = 0; c < nalgs; c++) + s[c] += t[c]; + reps += loops; + } + + for (c = 0; c < nalgs; c++) + { + printf("%20f", s[c] / (double) reps); + fflush(stdout); + } + printf("\n"); + + TEMPLATE(T, poly_clear)(f, ctx); + TEMPLATE(T, poly_clear)(finv, ctx); + for (i = 0; i < l + 1; i++) + TEMPLATE(T, poly_clear)(h[i], ctx); + flint_free(h); + TEMPLATE(T, ctx_clear)(ctx); + fmpz_clear(p); + fmpz_clear(q); + + FLINT_TEST_CLEANUP(state); + + return 0; +} + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/profile/p-iterated_frobenius_table.c b/external/flint-2.4.3/fq_poly_templates/profile/p-iterated_frobenius_table.c new file mode 100644 index 0000000..df8d0ab --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/profile/p-iterated_frobenius_table.c @@ -0,0 +1,412 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#ifdef T + +#include "flint.h" +#include "templates.h" + +#include +#include +#include "profiler.h" +#include "fmpz_mat.h" + +#define nalgs 2 +#define cpumin 1 +#define ncases 2 + +int +get_timings(double* s, slong degree, mp_bitcnt_t bits, slong length) +{ + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) f, *h, finv; + TEMPLATE(T, mat_t) HH; + fmpz_t p, q; + double beta; + slong i, l; + int n, c, reps = 0; + FLINT_TEST_INIT(state); + + fmpz_init(p); + fmpz_init(q); + + beta = 0.5 * (1. - (log(2) / log(length))); + l = ceil(pow(length, beta)); + + if (!(h = flint_malloc((l + 1) * sizeof(TEMPLATE(T, poly_struct))))) + { + flint_printf("Exception (p-iterated_frobenius):\n"); + flint_printf("Not enough memory.\n"); + abort(); + } + + flint_printf("Trying %d %d %d\n", degree, bits, length); + + for (c = 0; c < nalgs; c++) + s[c] = 0.0; + + reps = 0; + /* Compute the timings */ + for (n = 0; n < ncases; n++) + { + double t[nalgs]; + int lo, loops = 1; + +#ifdef FQ_ZECH_VEC_NORM + do + { + fmpz_set_ui(p, n_randprime(state, bits, 1)); + fmpz_pow_ui(q, p, degree); + } while (fmpz_cmp_ui(q, 1048576) > 0); +#else + fmpz_set_ui(p, n_randprime(state, bits, 1)); + fmpz_pow_ui(q, p, degree); +#endif + + TEMPLATE(T, ctx_init)(ctx, p, degree, "a"); + TEMPLATE(T, poly_init)(f, ctx); + TEMPLATE(T, poly_init)(finv, ctx); + + TEMPLATE(T, ctx_order)(q, ctx); + +#ifdef FQ_ZECH_VEC_NORM + if (fmpz_cmp_ui(q, 1048576) > 0) + { + flint_printf("Order too big for zech representation: "); + fmpz_print(q); + flint_printf("\n"); + abort(); + } +#endif + + for (i = 0; i < l + 1; i++) + TEMPLATE(T, poly_init)(h[i], ctx); + + /* + Construct random elements of fq + */ + { + TEMPLATE(T, poly_randtest_monic)(f, state, length, ctx); + TEMPLATE(T, poly_reverse)(finv, f, f->length, ctx); + TEMPLATE(T, poly_inv_series_newton)(finv, finv, f->length, ctx); + } + + loop: + + t[0] = 0.0; + init_clock(0); + prof_start(); + for (lo = 0; lo < loops; lo++) + { + TEMPLATE(T, poly_gen)(h[0], ctx); + TEMPLATE(T, mat_init)(HH, n_sqrt(f->length - 1) + 1, f->length - 1, ctx); + TEMPLATE(T, poly_powmod_fmpz_sliding_preinv)(h[1], h[0], q, 0, f, finv, ctx); + TEMPLATE(T, poly_precompute_matrix)(HH, h[1], f, finv, ctx); + for (i = 2; i < l + 1; i++) + TEMPLATE(T, poly_compose_mod_brent_kung_precomp_preinv)(h[i], h[i - 1], + HH, f, finv, ctx); + TEMPLATE(T, mat_clear)(HH, ctx); + } + prof_stop(); + t[0] += get_clock(0); + + + t[1] = 0.0; + init_clock(0); + prof_start(); + for (lo = 0; lo < loops; lo++) + { + TEMPLATE(T, poly_gen)(h[0], ctx); + TEMPLATE(T, poly_powmod_fmpz_sliding_preinv)(h[1], h[0], q, 0, f, finv, ctx); + for (i = 2; i < l + 1; i++) + TEMPLATE(T, poly_powmod_fmpz_sliding_preinv)(h[i], h[i-1], q, 0, f, finv, ctx); + } + prof_stop(); + t[1] += get_clock(0); + + for (c = 0; c < nalgs; c++) + if (t[c] * FLINT_CLOCK_SCALE_FACTOR <= cpumin) + { + loops *= 2; + goto loop; + } + + for (c = 0; c < nalgs; c++) + s[c] += t[c]; + reps += loops; + + TEMPLATE(T, poly_clear)(f, ctx); + TEMPLATE(T, poly_clear)(finv, ctx); + for (i = 0; i < l + 1; i++) + TEMPLATE(T, poly_clear)(h[i], ctx); + TEMPLATE(T, ctx_clear)(ctx); + + } + + for (c = 0; c < nalgs; c++) + { + s[c] = s[c] / (double) reps; + } + + fmpz_clear(p); + fmpz_clear(q); + + + flint_free(h); + + FLINT_TEST_CLEANUP(state); + + return s[0] > s[1]; +} + +long +a(fmpz_mat_t array, slong i, slong j) +{ + return fmpz_get_si(fmpz_mat_entry(array, i, j)); +} + +int +file_exists(char *filename) +{ + struct stat buffer; + return (stat (filename, &buffer) == 0); +} + +int +init_array(fmpz_mat_t array, slong max_degree, slong max_bits, slong max_length, char* filename) +{ + int bigger_length = 0; + fmpz_mat_t old_array; + slong i, j; + FILE * old_file; + + if( file_exists(filename) ) + { + flint_printf(filename); + /* old file exists */ + fmpz_mat_init(old_array, max_degree, max_bits); + old_file = fopen(filename, "r"); + fmpz_mat_fread(old_file, old_array); + fclose(old_file); + if (fmpz_get_ui(fmpz_mat_entry(old_array, 0, 2)) < max_length) + bigger_length = 1; + } + fmpz_mat_init(array, max_degree, max_bits); + max_bits = FLINT_MAX(max_bits, 3); + fmpz_set_si(fmpz_mat_entry(array, 0, 0), max_degree); + fmpz_set_si(fmpz_mat_entry(array, 0, 1), max_bits); + fmpz_set_si(fmpz_mat_entry(array, 0, 2), max_length); + + if( file_exists(filename) ) + { + for (i = 2; i < max_degree; i++) + { + for (j = 0; j < max_bits; j++) + { + fmpz_set(fmpz_mat_entry(array, i, j), + fmpz_mat_entry(old_array, i, j)); + + } + } + fmpz_mat_clear(old_array); + } + fmpz_mat_print_pretty(array); + return bigger_length; +} + + +void write_array(fmpz_mat_t array, char * filename) +{ + FILE * tmp; + tmp = fopen(filename, "w"); + fmpz_mat_fprint(tmp, array); + fclose(tmp); +} + + + +int +main(int argc, char** argv) +{ + mp_bitcnt_t bits, max_bits, max_bits_used, max_bits_e; + int is_hit, bigger_length; + slong degree, length, max_degree, max_length, imin, imax, imid, diff; + fmpz_mat_t array; + char* filename; + + double s[nalgs]; + + max_degree = atol(argv[1]); + max_bits = atol(argv[2]); + max_length = atol(argv[3]); + filename = argv[4]; + + bigger_length = init_array(array, max_degree, max_bits, max_length, filename); + + max_bits_used = 0; + max_bits_e = 0; + for (degree = 2; degree < max_degree; degree++) + { + flint_printf("Degree %d\n", degree); + fflush(stdout); + bits = 2; + length = 3; + while (bits < max_bits && (max_bits_e == 0 || bits < max_bits_e) ) + { + if (a(array, degree, bits) != 0 || + (!bigger_length && bits >= a(array, degree, 0))) + { + bits += 1; + continue; + } + +#ifdef FQ_ZECH_VEC_NORM + /* Don't make zech fields too big */ + if (degree * bits >= 20) + { + bits += 1; + continue; + } +#endif + + /* Set the initial state */ + if (bits == 2 || bits == 3) + { + if (degree == 2) + { + length = 3; + } + else + { + if (a(array, degree - 1, bits) > length) + length = a(array, degree - 1, bits); + } + diff = length; + } + else + { + length = a(array, degree, bits - 1); + diff = length - a(array, degree, bits - 2); + if (diff < degree) + { + diff = degree; + } + } + + /* Set the min */ + imax = 0; + imin = length; + is_hit = get_timings(s, degree, bits, imin); + while (is_hit != 0) + { + imax = imin; + imin -= 1; + if (imin < 3) + { + break; + } + is_hit = get_timings(s, degree, bits, imin); + } + + if (imin < 3) + { + bits += 1; + continue; + } + + /* Set the max */ + if (imax == 0) + { + imax = FLINT_MIN(imin + 2 * diff, max_length); + is_hit = get_timings(s, degree, bits, imax); + while (is_hit != 1) + { + flint_printf("Finding max, %d\n", diff); + if (imax == max_length) + { + imax = max_length + 1; + break; + } + imin = imax; + imax += 2 * diff; + imax = FLINT_MIN(imax, max_length); + is_hit = get_timings(s, degree, bits, imax); + } + } + if (imax > max_length) + { + max_bits_e = bits; + fmpz_set_si(fmpz_mat_entry(array, degree, 0), bits); + write_array(array, filename); + break; + } + + flint_printf("Min - Max: %d - %d\n", imin, imax); + + while (imin < imax) + { + imid = imin + ((imax - imin) / 2); + if (imid >= imax) + { + flint_printf("Error in computing midpoint\n"); + abort(); + } + + is_hit = get_timings(s, degree, bits, imid); + + if (is_hit) + { + imax = imid; + } + else + { + imin = imid + 1; + } + } + + length = imin; + + /* Set the array */ + flint_printf("%d - %d %d\n", degree, bits, length); + fmpz_set_si(fmpz_mat_entry(array, degree, bits), length); + fmpz_set_si(fmpz_mat_entry(array, degree, 0), bits); + if (degree == 2 && bits > max_bits_used) + max_bits_used = bits + 1; + fflush(stdout); + write_array(array, filename); + + bits += 1; + } + + + } + + + fmpz_mat_print_pretty(array); + fmpz_mat_clear(array); + return 0; +} + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/profile/p-mullow.c b/external/flint-2.4.3/fq_poly_templates/profile/p-mullow.c new file mode 100644 index 0000000..4461e81 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/profile/p-mullow.c @@ -0,0 +1,136 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#ifdef T + +#include "flint.h" +#include "templates.h" +#include "profiler.h" + +#define nalgs 2 +#define ncases 10 +#define cpumin 2 + +int +main(int argc, char** argv) +{ + double s[nalgs]; + + int c, n, lenf, leng, len, ext, reps = 0; + fmpz_t p, temp; + TEMPLATE(T, poly_t) f, g, h; + TEMPLATE(T, ctx_t) ctx; + + FLINT_TEST_INIT(state); + + fmpz_init(p); + fmpz_set_str(p, argv[1], 10); + + fmpz_init(temp); + + fmpz_set_str(temp, argv[2], 10); + ext = fmpz_get_si(temp); + + lenf = atol(argv[3]); + leng = atol(argv[4]); + len = atol(argv[5]); + + TEMPLATE(T, ctx_init)(ctx, p, ext, "a"); + + TEMPLATE(T, poly_init)(f, ctx); + TEMPLATE(T, poly_init)(g, ctx); + TEMPLATE(T, poly_init)(h, ctx); + + for (c = 0; c < nalgs; c++) + { + s[c] = 0.0; + } + + for (n = 0; n < ncases; n++) + { + double t[nalgs]; + int l, loops = 1; + + /* + Construct random elements of fq + */ + { + TEMPLATE(T, poly_randtest_monic)(f, state, lenf, ctx); + TEMPLATE(T, poly_randtest_monic)(g, state, leng, ctx); + } + + loop: + t[0] = 0.0; + init_clock(0); + prof_start(); + for (l = 0; l < loops; l++) + { + TEMPLATE(T, poly_mullow_classical)(h, f, g, len, ctx); + } + prof_stop(); + t[0] += get_clock(0); + + t[1] = 0.0; + init_clock(0); + prof_start(); + for (l = 0; l < loops; l++) + { + TEMPLATE(T, poly_mullow_KS)(h, f, g, len, ctx); + } + prof_stop(); + t[1] += get_clock(0); + + for (c = 0; c < nalgs; c++) + if (t[c] * FLINT_CLOCK_SCALE_FACTOR <= cpumin) + { + loops *= 10; + goto loop; + } + + for (c = 0; c < nalgs; c++) + s[c] += t[c]; + reps += loops; + } + + for (c = 0; c < nalgs; c++) + { + flint_printf("%20f ", s[c] / (double) reps); + fflush(stdout); + } + printf("\n"); + + TEMPLATE(T, poly_clear)(h, ctx); + TEMPLATE(T, poly_clear)(f, ctx); + TEMPLATE(T, poly_clear)(g, ctx); + TEMPLATE(T, ctx_clear)(ctx); + fmpz_clear(p); + fmpz_clear(temp); + + FLINT_TEST_CLEANUP(state); + + return 0; +} + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/profile/p-sqr.c b/external/flint-2.4.3/fq_poly_templates/profile/p-sqr.c new file mode 100644 index 0000000..3507cea --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/profile/p-sqr.c @@ -0,0 +1,131 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#ifdef T + +#include "flint.h" +#include "templates.h" +#include "profiler.h" + +#define nalgs 2 +#define ncases 10 +#define cpumin 2 + +int +main(int argc, char** argv) +{ + double s[nalgs]; + + int c, n, lenf, ext, reps = 0; + fmpz_t p, temp; + TEMPLATE(T, poly_t) f, h; + TEMPLATE(T, ctx_t) ctx; + + FLINT_TEST_INIT(state); + + fmpz_init(p); + fmpz_set_str(p, argv[1], 10); + + fmpz_init(temp); + + fmpz_set_str(temp, argv[2], 10); + ext = fmpz_get_si(temp); + + lenf = atol(argv[3]); + + TEMPLATE(T, ctx_init)(ctx, p, ext, "a"); + + TEMPLATE(T, poly_init)(f, ctx); + TEMPLATE(T, poly_init)(h, ctx); + + for (c = 0; c < nalgs; c++) + { + s[c] = 0.0; + } + + for (n = 0; n < ncases; n++) + { + double t[nalgs]; + int l, loops = 1; + + /* + Construct random elements of fq + */ + { + TEMPLATE(T, poly_randtest_monic)(f, state, lenf, ctx); + } + + loop: + t[0] = 0.0; + init_clock(0); + prof_start(); + for (l = 0; l < loops; l++) + { + TEMPLATE(T, poly_sqr_classical)(h, f, ctx); + } + prof_stop(); + t[0] += get_clock(0); + + t[1] = 0.0; + init_clock(0); + prof_start(); + for (l = 0; l < loops; l++) + { + TEMPLATE(T, poly_sqr_KS)(h, f, ctx); + } + prof_stop(); + t[1] += get_clock(0); + + for (c = 0; c < nalgs; c++) + if (t[c] * FLINT_CLOCK_SCALE_FACTOR <= cpumin) + { + loops *= 10; + goto loop; + } + + for (c = 0; c < nalgs; c++) + s[c] += t[c]; + reps += loops; + } + + for (c = 0; c < nalgs; c++) + { + flint_printf("%20f ", s[c] / (double) reps); + fflush(stdout); + } + printf("\n"); + + TEMPLATE(T, poly_clear)(h, ctx); + TEMPLATE(T, poly_clear)(f, ctx); + TEMPLATE(T, ctx_clear)(ctx); + fmpz_clear(p); + fmpz_clear(temp); + + FLINT_TEST_CLEANUP(state); + + return 0; +} + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/randtest.c b/external/flint-2.4.3/fq_poly_templates/randtest.c new file mode 100644 index 0000000..82ef592 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/randtest.c @@ -0,0 +1,69 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +TEMPLATE(T, poly_randtest) (TEMPLATE(T, poly_t) f, flint_rand_t state, + slong len, const TEMPLATE(T, ctx_t) ctx) +{ + slong i; + + TEMPLATE(T, poly_fit_length) (f, len, ctx); + for (i = 0; i < len; i++) + { + TEMPLATE(T, randtest) (f->coeffs + i, state, ctx); + } + _TEMPLATE(T, poly_set_length) (f, len, ctx); + _TEMPLATE(T, poly_normalise) (f, ctx); +} + +void +TEMPLATE(T, poly_randtest_not_zero) (TEMPLATE(T, poly_t) f, flint_rand_t state, + slong len, const TEMPLATE(T, ctx_t) ctx) +{ + slong i; + + if (len == 0) + { + TEMPLATE_PRINTF("Exception (%s_poly_randtest_not_zero). len = 0.\n", + T); + abort(); + } + + TEMPLATE(T, poly_randtest) (f, state, len, ctx); + for (i = 0; (i < 10) && TEMPLATE(T, poly_is_zero) (f, ctx); i++) + TEMPLATE(T, poly_randtest) (f, state, len, ctx); + if (TEMPLATE(T, poly_is_zero) (f, ctx)) + TEMPLATE(T, poly_one) (f, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/randtest_irreducible.c b/external/flint-2.4.3/fq_poly_templates/randtest_irreducible.c new file mode 100644 index 0000000..12b5948 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/randtest_irreducible.c @@ -0,0 +1,94 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +TEMPLATE(T, poly_randtest_irreducible) (TEMPLATE(T, poly_t) f, + flint_rand_t state, slong len, + const TEMPLATE(T, ctx_t) ctx) +{ + TEMPLATE(T, poly_t) xq, xqi, x, g_i, finv; + fmpz_t q; + slong i, restart; + + /* Compute q */ + fmpz_init_set(q, TEMPLATE(T, ctx_prime) (ctx)); + fmpz_pow_ui(q, q, TEMPLATE(T, ctx_degree) (ctx)); + + TEMPLATE(T, poly_init) (x, ctx); + TEMPLATE(T, poly_gen) (x, ctx); + TEMPLATE(T, poly_init) (xq, ctx); + TEMPLATE(T, poly_init) (xqi, ctx); + TEMPLATE(T, poly_init) (g_i, ctx); + TEMPLATE(T, poly_init) (finv, ctx); + + while (1) + { + restart = 0; + + /* Generate random monic polynomial of length len */ + TEMPLATE(T, poly_randtest_monic) (f, state, len, ctx); + + TEMPLATE(T, poly_reverse) (finv, f, f->length, ctx); + TEMPLATE(T, poly_inv_series_newton) (finv, finv, f->length, ctx); + + /* Compute xq = x^q mod f */ + TEMPLATE(T, poly_powmod_fmpz_binexp_preinv) (xq, x, q, f, finv, ctx); + TEMPLATE(T, poly_set) (xqi, xq, ctx); + + for (i = 1; i <= (len - 1) / 2; i++) + { + TEMPLATE(T, poly_sub) (xqi, xqi, x, ctx); + TEMPLATE(T, poly_gcd) (g_i, xqi, f, ctx); + TEMPLATE(T, poly_add) (xqi, xqi, x, ctx); + if (!TEMPLATE(T, poly_is_one) (g_i, ctx)) + { + restart = 1; + break; + } + TEMPLATE(T, poly_compose_mod_brent_kung_preinv) (xqi, xqi, xq, f, + finv, ctx); + + } + if (!restart) + { + break; + } + } + + TEMPLATE(T, poly_clear) (x, ctx); + TEMPLATE(T, poly_clear) (xq, ctx); + TEMPLATE(T, poly_clear) (xqi, ctx); + TEMPLATE(T, poly_clear) (g_i, ctx); + TEMPLATE(T, poly_clear) (finv, ctx); + fmpz_clear(q); +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/randtest_monic.c b/external/flint-2.4.3/fq_poly_templates/randtest_monic.c new file mode 100644 index 0000000..381fa86 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/randtest_monic.c @@ -0,0 +1,50 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +TEMPLATE(T, poly_randtest_monic) (TEMPLATE(T, poly_t) f, flint_rand_t state, + slong len, const TEMPLATE(T, ctx_t) ctx) +{ + slong i; + + TEMPLATE(T, poly_fit_length) (f, len, ctx); + for (i = 0; i < len - 1; i++) + { + TEMPLATE(T, randtest) (f->coeffs + i, state, ctx); + } + TEMPLATE(T, one) (f->coeffs + (len - 1), ctx); + _TEMPLATE(T, poly_set_length) (f, len, ctx); + _TEMPLATE(T, poly_normalise) (f, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/realloc.c b/external/flint-2.4.3/fq_poly_templates/realloc.c new file mode 100644 index 0000000..68f0cbe --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/realloc.c @@ -0,0 +1,73 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +TEMPLATE(T, poly_realloc) (TEMPLATE(T, poly_t) poly, slong alloc, + const TEMPLATE(T, ctx_t) ctx) +{ + slong i; + + if (alloc == 0) /* Clear up, reinitialise */ + { + TEMPLATE(T, poly_clear) (poly, ctx); + TEMPLATE(T, poly_init) (poly, ctx); + } + else if (poly->alloc) /* Realloc */ + { + for (i = alloc; i < poly->alloc; i++) + TEMPLATE(T, clear) (poly->coeffs + i, ctx); + + poly->coeffs = + (TEMPLATE(T, struct) *) flint_realloc(poly->coeffs, + alloc * + sizeof(TEMPLATE(T, struct))); + + for (i = poly->alloc; i < alloc; i++) + TEMPLATE(T, init) (poly->coeffs + i, ctx); + + poly->length = FLINT_MIN(poly->length, alloc); + _TEMPLATE(T, poly_normalise) (poly, ctx); + } + else /* Nothing allocated already so do it now */ + { + poly->coeffs = + (TEMPLATE(T, struct) *) flint_malloc(alloc * + sizeof(TEMPLATE(T, struct))); + + for (i = 0; i < alloc; i++) + TEMPLATE(T, init) (poly->coeffs + i, ctx); + } + poly->alloc = alloc; +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/remove.c b/external/flint-2.4.3/fq_poly_templates/remove.c new file mode 100644 index 0000000..750a8c2 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/remove.c @@ -0,0 +1,64 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +ulong +TEMPLATE(T, poly_remove) (TEMPLATE(T, poly_t) f, const TEMPLATE(T, poly_t) g, + const TEMPLATE(T, ctx_t) ctx) +{ + TEMPLATE(T, poly_t) q, r; + ulong i = 0; + + TEMPLATE(T, poly_init) (q, ctx); + TEMPLATE(T, poly_init) (r, ctx); + + while (1) + { + if (f->length < g->length) + break; + TEMPLATE(T, poly_divrem) (q, r, f, g, ctx); + if (r->length == 0) + TEMPLATE(T, poly_swap) (q, f, ctx); + else + break; + i++; + } + + TEMPLATE(T, poly_clear) (q, ctx); + TEMPLATE(T, poly_clear) (r, ctx); + + return i; +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/reverse.c b/external/flint-2.4.3/fq_poly_templates/reverse.c new file mode 100644 index 0000000..fbdcd97 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/reverse.c @@ -0,0 +1,83 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +_TEMPLATE(T, poly_reverse) (TEMPLATE(T, struct) * res, + const TEMPLATE(T, struct) * poly, slong len, + slong n, const TEMPLATE(T, ctx_t) ctx) +{ + if (res == poly) + { + slong i; + + for (i = 0; i < n / 2; i++) + { + TEMPLATE(T, struct) t = res[i]; + res[i] = res[n - 1 - i]; + res[n - 1 - i] = t; + } + + for (i = 0; i < n - len; i++) + TEMPLATE(T, zero) (res + i, ctx); + } + else + { + slong i; + + for (i = 0; i < n - len; i++) + TEMPLATE(T, zero) (res + i, ctx); + + for (i = 0; i < len; i++) + TEMPLATE(T, set) (res + (n - len) + i, poly + (len - 1) - i, ctx); + } +} + +void +TEMPLATE(T, poly_reverse) (TEMPLATE(T, poly_t) res, + const TEMPLATE(T, poly_t) poly, slong n, + const TEMPLATE(T, ctx_t) ctx) +{ + slong len = FLINT_MIN(n, poly->length); + if (len == 0) + { + TEMPLATE(T, poly_zero) (res, ctx); + return; + } + + TEMPLATE(T, poly_fit_length) (res, n, ctx); + + _TEMPLATE(T, poly_reverse) (res->coeffs, poly->coeffs, len, n, ctx); + + _TEMPLATE(T, poly_set_length) (res, n, ctx); + _TEMPLATE(T, poly_normalise) (res, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/scalar_addmul_fq.c b/external/flint-2.4.3/fq_poly_templates/scalar_addmul_fq.c new file mode 100644 index 0000000..406fdf7 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/scalar_addmul_fq.c @@ -0,0 +1,82 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +_TEMPLATE3(T, poly_scalar_addmul, T) (TEMPLATE(T, struct) * rop, + const TEMPLATE(T, struct) * op, slong len, + const TEMPLATE(T, t) x, + const TEMPLATE(T, ctx_t) ctx) +{ + if (TEMPLATE(T, is_zero) (x, ctx)) + return; + + if (TEMPLATE(T, is_one) (x, ctx)) + { + _TEMPLATE(T, poly_add) (rop, rop, len, op, len, ctx); + } + else + { + slong i; + TEMPLATE(T, t) t; + + TEMPLATE(T, init) (t, ctx); + + for (i = 0; i < len; i++) + { + TEMPLATE(T, mul) (t, op + i, x, ctx); + TEMPLATE(T, add) (rop + i, rop + i, t, ctx); + } + + TEMPLATE(T, clear) (t, ctx); + } +} + +void +TEMPLATE3(T, poly_scalar_addmul, T) (TEMPLATE(T, poly_t) rop, + const TEMPLATE(T, poly_t) op, + const TEMPLATE(T, t) x, + const TEMPLATE(T, ctx_t) ctx) +{ + if (! + (TEMPLATE(T, is_zero) (x, ctx) || TEMPLATE(T, poly_is_zero) (op, ctx))) + { + TEMPLATE(T, poly_fit_length) (rop, op->length, ctx); + _TEMPLATE3(T, poly_scalar_addmul, T) (rop->coeffs, op->coeffs, + op->length, x, ctx); + _TEMPLATE(T, poly_set_length) (rop, FLINT_MAX(rop->length, op->length), + ctx); + _TEMPLATE(T, poly_normalise) (rop, ctx); + } +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/scalar_mul_fq.c b/external/flint-2.4.3/fq_poly_templates/scalar_mul_fq.c new file mode 100644 index 0000000..005db92 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/scalar_mul_fq.c @@ -0,0 +1,65 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +_TEMPLATE(T, TEMPLATE(poly_scalar_mul, T)) (TEMPLATE(T, struct) * rop, + const TEMPLATE(T, struct) * op, + slong len, const TEMPLATE(T, t) x, + const TEMPLATE(T, ctx_t) ctx) +{ + slong i; + + for (i = 0; i < len; i++) + TEMPLATE(T, mul) (rop + i, op + i, x, ctx); +} + +void +TEMPLATE(T, TEMPLATE(poly_scalar_mul, T)) (TEMPLATE(T, poly_t) rop, + const TEMPLATE(T, poly_t) op, + const TEMPLATE(T, t) x, + const TEMPLATE(T, ctx_t) ctx) +{ + if (TEMPLATE(T, is_zero) (x, ctx) || TEMPLATE(T, poly_is_zero) (op, ctx)) + { + TEMPLATE(T, poly_zero) (rop, ctx); + } + else + { + TEMPLATE(T, poly_fit_length) (rop, op->length, ctx); + _TEMPLATE(T, TEMPLATE(poly_scalar_mul, T)) (rop->coeffs, op->coeffs, + op->length, x, ctx); + _TEMPLATE(T, poly_set_length) (rop, op->length, ctx); + } +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/scalar_submul_fq.c b/external/flint-2.4.3/fq_poly_templates/scalar_submul_fq.c new file mode 100644 index 0000000..f8b9de8 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/scalar_submul_fq.c @@ -0,0 +1,82 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +_TEMPLATE3(T, poly_scalar_submul, T) (TEMPLATE(T, struct) * rop, + const TEMPLATE(T, struct) * op, slong len, + const TEMPLATE(T, t) x, + const TEMPLATE(T, ctx_t) ctx) +{ + if (TEMPLATE(T, is_zero) (x, ctx)) + return; + + if (TEMPLATE(T, is_one) (x, ctx)) + { + _TEMPLATE(T, poly_sub) (rop, rop, len, op, len, ctx); + } + else + { + slong i; + TEMPLATE(T, t) t; + + TEMPLATE(T, init) (t, ctx); + + for (i = 0; i < len; i++) + { + TEMPLATE(T, mul) (t, op + i, x, ctx); + TEMPLATE(T, sub) (rop + i, rop + i, t, ctx); + } + + TEMPLATE(T, clear) (t, ctx); + } +} + +void +TEMPLATE3(T, poly_scalar_submul, T) (TEMPLATE(T, poly_t) rop, + const TEMPLATE(T, poly_t) op, + const TEMPLATE(T, t) x, + const TEMPLATE(T, ctx_t) ctx) +{ + if (! + (TEMPLATE(T, is_zero) (x, ctx) || TEMPLATE(T, poly_is_zero) (op, ctx))) + { + TEMPLATE(T, poly_fit_length) (rop, op->length, ctx); + _TEMPLATE3(T, poly_scalar_submul, T) (rop->coeffs, op->coeffs, + op->length, x, ctx); + _TEMPLATE(T, poly_set_length) (rop, FLINT_MAX(rop->length, op->length), + ctx); + _TEMPLATE(T, poly_normalise) (rop, ctx); + } +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/set.c b/external/flint-2.4.3/fq_poly_templates/set.c new file mode 100644 index 0000000..f983d36 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/set.c @@ -0,0 +1,62 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2012 Andres Goens + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +_TEMPLATE(T, poly_set) (TEMPLATE(T, struct) * rop, + const TEMPLATE(T, struct) * op, slong len, + const TEMPLATE(T, ctx_t) ctx) +{ + slong i; + + for (i = 0; i < len; i++) + TEMPLATE(T, set) (rop + i, op + i, ctx); +} + +void +TEMPLATE(T, poly_set) (TEMPLATE(T, poly_t) rop, const TEMPLATE(T, poly_t) op, + const TEMPLATE(T, ctx_t) ctx) +{ + if (rop != op) /* Aliasing is trivial */ + { + slong i, len = op->length; + + TEMPLATE(T, poly_fit_length) (rop, len, ctx); + _TEMPLATE(T, poly_set_length) (rop, len, ctx); + + for (i = 0; i < len; i++) + TEMPLATE(T, set) (rop->coeffs + i, op->coeffs + i, ctx); + } +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/set_coeff.c b/external/flint-2.4.3/fq_poly_templates/set_coeff.c new file mode 100644 index 0000000..3c1d425 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/set_coeff.c @@ -0,0 +1,54 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +TEMPLATE(T, poly_set_coeff) (TEMPLATE(T, poly_t) poly, slong n, + const TEMPLATE(T, t) x, + const TEMPLATE(T, ctx_t) ctx) +{ + slong i; + + TEMPLATE(T, poly_fit_length) (poly, n + 1, ctx); + + if (n + 1 > poly->length) /* Insert zeros if needed */ + { + for (i = poly->length; i < n; i++) + TEMPLATE(T, zero) (poly->coeffs + i, ctx); + poly->length = n + 1; + } + + TEMPLATE(T, set) (poly->coeffs + n, x, ctx); + _TEMPLATE(T, poly_normalise) (poly, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/set_fq.c b/external/flint-2.4.3/fq_poly_templates/set_fq.c new file mode 100644 index 0000000..6bac008 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/set_fq.c @@ -0,0 +1,50 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +TEMPLATE(T, TEMPLATE(poly_set, T)) (TEMPLATE(T, poly_t) poly, + const TEMPLATE(T, t) c, + const TEMPLATE(T, ctx_t) ctx) +{ + if (TEMPLATE(T, is_zero) (c, ctx)) + { + TEMPLATE(T, poly_zero) (poly, ctx); + } + else + { + TEMPLATE(T, poly_fit_length) (poly, 1, ctx); + TEMPLATE(T, set) (poly->coeffs + 0, c, ctx); + _TEMPLATE(T, poly_set_length) (poly, 1, ctx); + } +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/shift_left.c b/external/flint-2.4.3/fq_poly_templates/shift_left.c new file mode 100644 index 0000000..6db6ef1 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/shift_left.c @@ -0,0 +1,78 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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, 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +_TEMPLATE(T, poly_shift_left) (TEMPLATE(T, struct) * rop, + const TEMPLATE(T, struct) * op, slong len, + slong n, const TEMPLATE(T, ctx_t) ctx) +{ + slong i; + + if (rop != op) + { + for (i = len; i--;) + TEMPLATE(T, set) (rop + n + i, op + i, ctx); + } + else + { + for (i = len; i--;) + TEMPLATE(T, swap) (rop + n + i, rop + i, ctx); + } + + for (i = 0; i < n; i++) + TEMPLATE(T, zero) (rop + i, ctx); +} + +void +TEMPLATE(T, poly_shift_left) (TEMPLATE(T, poly_t) rop, + const TEMPLATE(T, poly_t) op, slong n, + const TEMPLATE(T, ctx_t) ctx) +{ + if (n == 0) + { + TEMPLATE(T, poly_set) (rop, op, ctx); + } + else if (TEMPLATE(T, poly_is_zero) (op, ctx)) + { + TEMPLATE(T, poly_zero) (rop, ctx); + } + else + { + TEMPLATE(T, poly_fit_length) (rop, op->length + n, ctx); + _TEMPLATE(T, poly_shift_left) (rop->coeffs, op->coeffs, op->length, n, + ctx); + _TEMPLATE(T, poly_set_length) (rop, op->length + n, ctx); + } +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/shift_right.c b/external/flint-2.4.3/fq_poly_templates/shift_right.c new file mode 100644 index 0000000..e47ab2a --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/shift_right.c @@ -0,0 +1,75 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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, 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +_TEMPLATE(T, poly_shift_right) (TEMPLATE(T, struct) * rop, + const TEMPLATE(T, struct) * op, slong len, + slong n, const TEMPLATE(T, ctx_t) ctx) +{ + slong i; + + if (rop != op) + { + for (i = 0; i < len - n; i++) + TEMPLATE(T, set) (rop + i, op + n + i, ctx); + } + else + { + for (i = 0; i < len - n; i++) + TEMPLATE(T, swap) (rop + i, rop + n + i, ctx); + } +} + +void +TEMPLATE(T, poly_shift_right) (TEMPLATE(T, poly_t) rop, + const TEMPLATE(T, poly_t) op, slong n, + const TEMPLATE(T, ctx_t) ctx) +{ + if (n == 0) + { + TEMPLATE(T, poly_set) (rop, op, ctx); + } + else if (op->length <= n) + { + TEMPLATE(T, poly_zero) (rop, ctx); + } + else + { + TEMPLATE(T, poly_fit_length) (rop, op->length - n, ctx); + _TEMPLATE(T, poly_shift_right) (rop->coeffs, op->coeffs, op->length, n, + ctx); + _TEMPLATE(T, poly_set_length) (rop, op->length - n, ctx); + } +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/sqr.c b/external/flint-2.4.3/fq_poly_templates/sqr.c new file mode 100644 index 0000000..7bae9c5 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/sqr.c @@ -0,0 +1,84 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +_TEMPLATE(T, poly_sqr) (TEMPLATE(T, struct) * rop, + const TEMPLATE(T, struct) * op, slong len, + const TEMPLATE(T, ctx_t) ctx) +{ + if (len < TEMPLATE(CAP_T, SQR_CLASSICAL_CUTOFF)) + { + _TEMPLATE(T, poly_sqr_classical) (rop, op, len, ctx); + } +#ifdef USE_SQR_REORDER + else if (TEMPLATE(T, ctx_degree) (ctx) < 4) + { + _TEMPLATE(T, poly_sqr_reorder) (rop, op, len, ctx); + } +#endif + else + { + _TEMPLATE(T, poly_sqr_KS) (rop, op, len, ctx); + } +} + +void +TEMPLATE(T, poly_sqr) (TEMPLATE(T, poly_t) rop, const TEMPLATE(T, poly_t) op, + const TEMPLATE(T, ctx_t) ctx) +{ + const slong rlen = 2 * op->length - 1; + + if (op->length == 0) + { + TEMPLATE(T, poly_zero) (rop, ctx); + return; + } + + if (rop == op) + { + TEMPLATE(T, poly_t) t; + + TEMPLATE(T, poly_init2) (t, rlen, ctx); + _TEMPLATE(T, poly_sqr) (t->coeffs, op->coeffs, op->length, ctx); + TEMPLATE(T, poly_swap) (rop, t, ctx); + TEMPLATE(T, poly_clear) (t, ctx); + } + else + { + TEMPLATE(T, poly_fit_length) (rop, rlen, ctx); + _TEMPLATE(T, poly_sqr) (rop->coeffs, op->coeffs, op->length, ctx); + } + + _TEMPLATE(T, poly_set_length) (rop, rlen, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/sqr_KS.c b/external/flint-2.4.3/fq_poly_templates/sqr_KS.c new file mode 100644 index 0000000..7676bac --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/sqr_KS.c @@ -0,0 +1,96 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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, 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" +#include "fmpz_poly.h" + +void +_TEMPLATE(T, poly_sqr_KS) (TEMPLATE(T, struct) * rop, + const TEMPLATE(T, struct) * op, slong len, + const TEMPLATE(T, ctx_t) ctx) +{ + const slong in_len = len; + const slong d = TEMPLATE(T, ctx_degree) (ctx); + slong bits, i; + fmpz *f, *g; + + TEMPLATE(CAP_T, VEC_NORM) (op, len, ctx); + + if (!len) + { + if (2 * in_len - 1 > 0) + _TEMPLATE(T, poly_zero) (rop, 2 * in_len - 1, ctx); + return; + } + + bits = 2 * fmpz_bits(TEMPLATE(T, ctx_prime) (ctx)) + + FLINT_BIT_COUNT(d) + FLINT_BIT_COUNT(len); + + f = _fmpz_vec_init((2 * len - 1) + len); + g = f + (2 * len - 1); + + for (i = 0; i < len; i++) + { + TEMPLATE(T, bit_pack) (g + i, op + i, bits, ctx); + } + + _fmpz_poly_sqr(f, g, len); + + for (i = 0; i < 2 * len - 1; i++) + { + TEMPLATE(T, bit_unpack) (rop + i, f + i, bits, ctx); + } + + _TEMPLATE(T, poly_zero) (rop + (2 * len - 1), 2 * (in_len - len), ctx); + + _fmpz_vec_clear(f, (2 * len - 1) + len); +} + +void +TEMPLATE(T, poly_sqr_KS) (TEMPLATE(T, poly_t) rop, + const TEMPLATE(T, poly_t) op, + const TEMPLATE(T, ctx_t) ctx) +{ + const slong len = 2 * op->length - 1; + + if (op->length == 0) + { + TEMPLATE(T, poly_zero) (rop, ctx); + } + else + { + TEMPLATE(T, poly_fit_length) (rop, len, ctx); + _TEMPLATE(T, poly_sqr_KS) (rop->coeffs, op->coeffs, op->length, ctx); + _TEMPLATE(T, poly_set_length) (rop, len, ctx); + } +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/sqr_classical.c b/external/flint-2.4.3/fq_poly_templates/sqr_classical.c new file mode 100644 index 0000000..a9c1ecc --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/sqr_classical.c @@ -0,0 +1,103 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +_TEMPLATE(T, poly_sqr_classical) (TEMPLATE(T, struct) * rop, + const TEMPLATE(T, struct) * op, slong len, + const TEMPLATE(T, ctx_t) ctx) +{ + if (len == 1) + { + TEMPLATE(T, mul) (rop, op, op, ctx); + } + else + { + slong i; + TEMPLATE(T, t) t; + + TEMPLATE(T, init) (t, ctx); + + _TEMPLATE(T, TEMPLATE(poly_scalar_mul, T)) (rop, op, len, op, ctx); + + _TEMPLATE(T, TEMPLATE(poly_scalar_mul, T)) (rop + len, op + 1, len - 1, + op + len - 1, ctx); + + for (i = 1; i < len - 1; i++) + _TEMPLATE(T, TEMPLATE(poly_scalar_addmul, T)) (rop + i + 1, op + 1, + i - 1, op + i, ctx); + + for (i = 1; i < 2 * len - 2; i++) + TEMPLATE(T, add) (rop + i, rop + i, rop + i, ctx); + + for (i = 1; i < len - 1; i++) + { + TEMPLATE(T, sqr) (t, op + i, ctx); + TEMPLATE(T, add) (rop + 2 * i, rop + 2 * i, t, ctx); + } + TEMPLATE(T, clear) (t, ctx); + } +} + +void +TEMPLATE(T, poly_sqr_classical) (TEMPLATE(T, poly_t) rop, + const TEMPLATE(T, poly_t) op, + const TEMPLATE(T, ctx_t) ctx) +{ + const slong len = 2 * op->length - 1; + + if (op->length == 0) + { + TEMPLATE(T, poly_zero) (rop, ctx); + return; + } + + if (rop == op) + { + TEMPLATE(T, poly_t) t; + + TEMPLATE(T, poly_init2) (t, len, ctx); + _TEMPLATE(T, poly_sqr_classical) (t->coeffs, op->coeffs, op->length, + ctx); + TEMPLATE(T, poly_swap) (rop, t, ctx); + TEMPLATE(T, poly_clear) (t, ctx); + } + else + { + TEMPLATE(T, poly_fit_length) (rop, len, ctx); + _TEMPLATE(T, poly_sqr_classical) (rop->coeffs, op->coeffs, op->length, + ctx); + } + + _TEMPLATE(T, poly_set_length) (rop, len, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/sqr_reorder.c b/external/flint-2.4.3/fq_poly_templates/sqr_reorder.c new file mode 100644 index 0000000..2474839 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/sqr_reorder.c @@ -0,0 +1,244 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +/* + Include routines for vectors over \code{fmpz_poly_struct}, + for use in the classical multiplication routine in the + $X$-direction. + */ + +static fmpz_poly_struct * +__vec_init(slong len) +{ + slong i; + fmpz_poly_struct *v; + + v = flint_malloc(len * sizeof(fmpz_poly_struct)); + for (i = 0; i < len; i++) + fmpz_poly_init(v + i); + return v; +} + +static fmpz_poly_struct * +__vec_init2(slong len, slong n) +{ + slong i; + fmpz_poly_struct *v; + + v = flint_malloc(len * sizeof(fmpz_poly_struct)); + for (i = 0; i < len; i++) + fmpz_poly_init2(v + i, n); + return v; +} + +static void +__vec_clear(fmpz_poly_struct * v, slong len) +{ + slong i; + + for (i = 0; i < len; i++) + fmpz_poly_clear(v + i); + flint_free(v); +} + +static void +__scalar_addmul(fmpz_poly_struct * rop, + const fmpz_poly_struct * op, slong len, const fmpz_poly_t x) +{ + slong i; + + if (fmpz_poly_is_zero(x)) + { + return; + } + else if (fmpz_poly_is_one(x)) + { + for (i = 0; i < len; i++) + fmpz_poly_add(rop + i, rop + i, op + i); + } + else + { + fmpz_poly_t t; + + fmpz_poly_init(t); + for (i = 0; i < len; i++) + { + fmpz_poly_mul(t, op + i, x); + fmpz_poly_add(rop + i, rop + i, t); + } + fmpz_poly_clear(t); + } +} + +static void +__scalar_mul(fmpz_poly_struct * rop, + const fmpz_poly_struct * op, slong len, const fmpz_poly_t x) +{ + slong i; + + if (fmpz_poly_is_zero(x)) + { + for (i = 0; i < len; i++) + fmpz_poly_zero(rop + i); + } + else if (fmpz_poly_is_one(x)) + { + for (i = 0; i < len; i++) + fmpz_poly_set(rop + i, op + i); + } + else + { + for (i = 0; i < len; i++) + fmpz_poly_mul(rop + i, op + i, x); + } +} + +static void +__sqr(fmpz_poly_struct * rop, fmpz_poly_struct * op, slong len) +{ + if (len == 1) + { + fmpz_poly_sqr(rop, op); + } + else + { + slong i; + fmpz_poly_t t; + + fmpz_poly_init(t); + + __scalar_mul(rop, op, len, op); + + __scalar_mul(rop + len, op + 1, len - 1, op + len - 1); + + for (i = 1; i < len - 1; i++) + __scalar_addmul(rop + i + 1, op + 1, i - 1, op + i); + + for (i = 1; i < 2 * len - 2; i++) + fmpz_poly_add(rop + i, rop + i, rop + i); + + for (i = 1; i < len - 1; i++) + { + fmpz_poly_sqr(t, op + i); + fmpz_poly_add(rop + 2 * i, rop + 2 * i, t); + } + fmpz_poly_clear(t); + } +} + +void +_TEMPLATE(T, poly_sqr_reorder) (TEMPLATE(T, struct) * rop, + const TEMPLATE(T, struct) * op, slong len, + const TEMPLATE(T, ctx_t) ctx) +{ + const slong d = TEMPLATE(T, ctx_degree) (ctx); + + fmpz_poly_struct *f, *g; + slong i, j, k, lenF; + + f = __vec_init(2 * d - 1); + g = __vec_init2(d, len); + + /* Convert (op, len) to (g, d) */ + for (i = 0; i < len; i++) + for (j = 0; j < fmpz_poly_length(op + i); j++) + fmpz_set((g + j)->coeffs + i, (op + i)->coeffs + j); + + for (j = 0; j < d; j++) + { + _fmpz_poly_set_length(g + j, len); + _fmpz_poly_normalise(g + j); + } + + __sqr(f, g, d); + + /* Normalise (f, len) */ + lenF = 2 * d - 1; + while ((lenF) && fmpz_poly_is_zero(f + (lenF - 1))) + lenF--; + + /* Reduce (f, j) using polynomial operations */ + if (lenF > d) + { + for (i = lenF - 1; i >= d; i--) + { + for (k = ctx->len - 2; k >= 0; k--) + { + fmpz_poly_scalar_submul_fmpz(f + ctx->j[k] + i - d, f + i, + ctx->a + k); + } + fmpz_poly_zero(f + i); + } + } + for (j = 0; j < FLINT_MIN(d, lenF); j++) + fmpz_poly_scalar_mod_fmpz(f + j, f + j, TEMPLATE(T, ctx_prime) (ctx)); + + /* Convert (f, d) to (rop, 2 * len - 1) */ + for (i = 0; i < 2 * len - 1; i++) + { + fmpz_poly_fit_length(rop + i, d); + _fmpz_vec_zero((rop + i)->coeffs, d); + } + for (j = 0; j < d; j++) + for (i = 0; i < fmpz_poly_length(f + j); i++) + fmpz_set((rop + i)->coeffs + j, (f + j)->coeffs + i); + for (i = 0; i < 2 * len - 1; i++) + { + _fmpz_poly_set_length(rop + i, d); + _fmpz_poly_normalise(rop + i); + } + + __vec_clear(f, 2 * d - 1); + __vec_clear(g, d); +} + +void +TEMPLATE(T, poly_sqr_reorder) (TEMPLATE(T, poly_t) rop, + const TEMPLATE(T, poly_t) op, + const TEMPLATE(T, ctx_t) ctx) +{ + const slong len = 2 * op->length - 1; + + if (op->length == 0) + { + TEMPLATE(T, poly_zero) (rop, ctx); + } + else + { + TEMPLATE(T, poly_fit_length) (rop, len, ctx); + _TEMPLATE(T, poly_sqr_reorder) (rop->coeffs, op->coeffs, op->length, + ctx); + _TEMPLATE(T, poly_set_length) (rop, len, ctx); + } +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/sub.c b/external/flint-2.4.3/fq_poly_templates/sub.c new file mode 100644 index 0000000..7856866 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/sub.c @@ -0,0 +1,70 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +_TEMPLATE(T, poly_sub) (TEMPLATE(T, struct) * res, + const TEMPLATE(T, struct) * poly1, slong len1, + const TEMPLATE(T, struct) * poly2, slong len2, + const TEMPLATE(T, ctx_t) ctx) +{ + const slong min = FLINT_MIN(len1, len2); + slong i; + + for (i = 0; i < min; i++) + TEMPLATE(T, sub) (res + i, poly1 + i, poly2 + i, ctx); + + if (poly1 != res) + for (i = min; i < len1; i++) + TEMPLATE(T, set) (res + i, poly1 + i, ctx); + + for (i = min; i < len2; i++) + TEMPLATE(T, neg) (res + i, poly2 + i, ctx); +} + +void +TEMPLATE(T, poly_sub) (TEMPLATE(T, poly_t) res, + const TEMPLATE(T, poly_t) poly1, + const TEMPLATE(T, poly_t) poly2, + const TEMPLATE(T, ctx_t) ctx) +{ + const slong max = FLINT_MAX(poly1->length, poly2->length); + + TEMPLATE(T, poly_fit_length) (res, max, ctx); + + _TEMPLATE(T, poly_sub) (res->coeffs, poly1->coeffs, poly1->length, + poly2->coeffs, poly2->length, ctx); + + _TEMPLATE(T, poly_set_length) (res, max, ctx); + _TEMPLATE(T, poly_normalise) (res, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/swap.c b/external/flint-2.4.3/fq_poly_templates/swap.c new file mode 100644 index 0000000..ad22ba8 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/swap.c @@ -0,0 +1,57 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +TEMPLATE(T, poly_swap) (TEMPLATE(T, poly_t) op1, TEMPLATE(T, poly_t) op2, + const TEMPLATE(T, ctx_t) ctx) +{ + if (op1 != op2) + { + slong temp; + TEMPLATE(T, struct) * temp_c; + + temp = op1->length; + op1->length = op2->length; + op2->length = temp; + + temp = op1->alloc; + op1->alloc = op2->alloc; + op2->alloc = temp; + + temp_c = op1->coeffs; + op1->coeffs = op2->coeffs; + op2->coeffs = temp_c; + } +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-add.c b/external/flint-2.4.3/fq_poly_templates/test/t-add.c new file mode 100644 index 0000000..9cd3bf9 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-add.c @@ -0,0 +1,263 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include + +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("add... "); + fflush(stdout); + + /* Check aliasing: a = a + b */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, c; + + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + TEMPLATE(T, poly_randtest) (b, state, len, ctx); + + TEMPLATE(T, poly_add) (c, a, b, ctx); + TEMPLATE(T, poly_add) (a, a, b, ctx); + + result = (TEMPLATE(T, poly_equal) (a, c, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check aliasing: b = a + b */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, c; + + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + TEMPLATE(T, poly_randtest) (b, state, len, ctx); + + TEMPLATE(T, poly_add) (c, a, b, ctx); + TEMPLATE(T, poly_add) (b, a, b, ctx); + + result = (TEMPLATE(T, poly_equal) (b, c, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check aliasing: a = a + a */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, c; + + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (c, ctx); + + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + + TEMPLATE(T, poly_add) (c, a, a, ctx); + TEMPLATE(T, poly_add) (a, a, a, ctx); + + result = (TEMPLATE(T, poly_equal) (a, c, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check that a + b == b + a */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, c, e; + + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + TEMPLATE(T, poly_init) (e, ctx); + + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + TEMPLATE(T, poly_randtest) (b, state, len, ctx); + + TEMPLATE(T, poly_add) (c, a, b, ctx); + TEMPLATE(T, poly_add) (e, b, a, ctx); + + result = (TEMPLATE(T, poly_equal) (e, c, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + flint_printf("e = "), TEMPLATE(T, poly_print_pretty) (e, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + TEMPLATE(T, poly_clear) (e, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check that (a + b) + c == a + (b + c) */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, c, lhs, rhs; + + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + TEMPLATE(T, poly_init) (lhs, ctx); + TEMPLATE(T, poly_init) (rhs, ctx); + + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + TEMPLATE(T, poly_randtest) (b, state, len, ctx); + TEMPLATE(T, poly_randtest) (c, state, len, ctx); + + TEMPLATE(T, poly_add) (lhs, a, b, ctx); + TEMPLATE(T, poly_add) (lhs, c, lhs, ctx); + + TEMPLATE(T, poly_add) (rhs, b, c, ctx); + TEMPLATE(T, poly_add) (rhs, a, rhs, ctx); + + + result = (TEMPLATE(T, poly_equal) (lhs, rhs, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + TEMPLATE(T, poly_clear) (lhs, ctx); + TEMPLATE(T, poly_clear) (rhs, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-compose.c b/external/flint-2.4.3/fq_poly_templates/test/t-compose.c new file mode 100644 index 0000000..4a0d984 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-compose.c @@ -0,0 +1,184 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include + +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("compose... "); + fflush(stdout); + + /* Check aliasing of the first argument */ + for (i = 0; i < 50; i++) + { + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) f, g, h; + + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (f, ctx); + TEMPLATE(T, poly_init) (g, ctx); + TEMPLATE(T, poly_init) (h, ctx); + + TEMPLATE(T, poly_randtest) (f, state, n_randint(state, 40), ctx); + TEMPLATE(T, poly_randtest) (g, state, n_randint(state, 20), ctx); + + TEMPLATE(T, poly_compose) (h, f, g, ctx); + TEMPLATE(T, poly_compose) (f, f, g, ctx); + + result = (TEMPLATE(T, poly_equal) (f, h, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("f = "), TEMPLATE(T, poly_print_pretty) (f, "X", ctx), + flint_printf("\n"); + flint_printf("g = "), TEMPLATE(T, poly_print_pretty) (g, "X", ctx), + flint_printf("\n"); + flint_printf("h = "), TEMPLATE(T, poly_print_pretty) (h, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (f, ctx); + TEMPLATE(T, poly_clear) (g, ctx); + TEMPLATE(T, poly_clear) (h, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check aliasing of the second argument */ + for (i = 0; i < 50; i++) + { + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) f, g, h; + + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (f, ctx); + TEMPLATE(T, poly_init) (g, ctx); + TEMPLATE(T, poly_init) (h, ctx); + + TEMPLATE(T, poly_randtest) (f, state, n_randint(state, 40), ctx); + TEMPLATE(T, poly_randtest) (g, state, n_randint(state, 20), ctx); + + TEMPLATE(T, poly_compose) (h, f, g, ctx); + TEMPLATE(T, poly_compose) (g, f, g, ctx); + + result = (TEMPLATE(T, poly_equal) (g, h, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("f = "), TEMPLATE(T, poly_print_pretty) (f, "X", ctx), + flint_printf("\n"); + flint_printf("g = "), TEMPLATE(T, poly_print_pretty) (g, "X", ctx), + flint_printf("\n"); + flint_printf("h = "), TEMPLATE(T, poly_print_pretty) (h, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (f, ctx); + TEMPLATE(T, poly_clear) (g, ctx); + TEMPLATE(T, poly_clear) (h, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Compare with the naive method */ + for (i = 0; i < 50; i++) + { + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) f, g, h, s, t; + slong k; + + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (f, ctx); + TEMPLATE(T, poly_init) (g, ctx); + TEMPLATE(T, poly_init) (h, ctx); + TEMPLATE(T, poly_init) (s, ctx); + TEMPLATE(T, poly_init) (t, ctx); + + TEMPLATE(T, poly_randtest) (g, state, n_randint(state, 40), ctx); + TEMPLATE(T, poly_randtest) (h, state, n_randint(state, 20), ctx); + + TEMPLATE(T, poly_one) (t, ctx); + for (k = 0; k < TEMPLATE(T, poly_length) (g, ctx); k++) + { + TEMPLATE(T, TEMPLATE(poly_scalar_addmul, T)) (s, t, g->coeffs + k, + ctx); + TEMPLATE(T, poly_mul) (t, t, h, ctx); + } + + TEMPLATE(T, poly_compose) (f, g, h, ctx); + + result = (TEMPLATE(T, poly_equal) (f, s, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("f = "), TEMPLATE(T, poly_print_pretty) (f, "X", ctx), + flint_printf("\n"); + flint_printf("g = "), TEMPLATE(T, poly_print_pretty) (g, "X", ctx), + flint_printf("\n"); + flint_printf("h = "), TEMPLATE(T, poly_print_pretty) (h, "X", ctx), + flint_printf("\n"); + flint_printf("s = "), TEMPLATE(T, poly_print_pretty) (s, "X", ctx), + flint_printf("\n"); + flint_printf("t = "), TEMPLATE(T, poly_print_pretty) (t, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (f, ctx); + TEMPLATE(T, poly_clear) (g, ctx); + TEMPLATE(T, poly_clear) (h, ctx); + TEMPLATE(T, poly_clear) (s, ctx); + TEMPLATE(T, poly_clear) (t, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-compose_divconquer.c b/external/flint-2.4.3/fq_poly_templates/test/t-compose_divconquer.c new file mode 100644 index 0000000..801dfbf --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-compose_divconquer.c @@ -0,0 +1,184 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include + +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("compose_divconquer... "); + fflush(stdout); + + /* Check aliasing of the first argument */ + for (i = 0; i < 50; i++) + { + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) f, g, h; + + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (f, ctx); + TEMPLATE(T, poly_init) (g, ctx); + TEMPLATE(T, poly_init) (h, ctx); + + TEMPLATE(T, poly_randtest) (f, state, n_randint(state, 40), ctx); + TEMPLATE(T, poly_randtest) (g, state, n_randint(state, 20), ctx); + + TEMPLATE(T, poly_compose_divconquer) (h, f, g, ctx); + TEMPLATE(T, poly_compose_divconquer) (f, f, g, ctx); + + result = (TEMPLATE(T, poly_equal) (f, h, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("f = "), TEMPLATE(T, poly_print_pretty) (f, "X", ctx), + flint_printf("\n"); + flint_printf("g = "), TEMPLATE(T, poly_print_pretty) (g, "X", ctx), + flint_printf("\n"); + flint_printf("h = "), TEMPLATE(T, poly_print_pretty) (h, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (f, ctx); + TEMPLATE(T, poly_clear) (g, ctx); + TEMPLATE(T, poly_clear) (h, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check aliasing of the second argument */ + for (i = 0; i < 50; i++) + { + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) f, g, h; + + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (f, ctx); + TEMPLATE(T, poly_init) (g, ctx); + TEMPLATE(T, poly_init) (h, ctx); + + TEMPLATE(T, poly_randtest) (f, state, n_randint(state, 40), ctx); + TEMPLATE(T, poly_randtest) (g, state, n_randint(state, 20), ctx); + + TEMPLATE(T, poly_compose_divconquer) (h, f, g, ctx); + TEMPLATE(T, poly_compose_divconquer) (g, f, g, ctx); + + result = (TEMPLATE(T, poly_equal) (g, h, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("f = "), TEMPLATE(T, poly_print_pretty) (f, "X", ctx), + flint_printf("\n"); + flint_printf("g = "), TEMPLATE(T, poly_print_pretty) (g, "X", ctx), + flint_printf("\n"); + flint_printf("h = "), TEMPLATE(T, poly_print_pretty) (h, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (f, ctx); + TEMPLATE(T, poly_clear) (g, ctx); + TEMPLATE(T, poly_clear) (h, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Compare with the naive method */ + for (i = 0; i < 50; i++) + { + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) f, g, h, s, t; + slong k; + + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (f, ctx); + TEMPLATE(T, poly_init) (g, ctx); + TEMPLATE(T, poly_init) (h, ctx); + TEMPLATE(T, poly_init) (s, ctx); + TEMPLATE(T, poly_init) (t, ctx); + + TEMPLATE(T, poly_randtest) (g, state, n_randint(state, 40), ctx); + TEMPLATE(T, poly_randtest) (h, state, n_randint(state, 20), ctx); + + TEMPLATE(T, poly_one) (t, ctx); + for (k = 0; k < TEMPLATE(T, poly_length) (g, ctx); k++) + { + TEMPLATE(T, TEMPLATE(poly_scalar_addmul, T)) (s, t, g->coeffs + k, + ctx); + TEMPLATE(T, poly_mul) (t, t, h, ctx); + } + + TEMPLATE(T, poly_compose_divconquer) (f, g, h, ctx); + + result = (TEMPLATE(T, poly_equal) (f, s, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("f = "), TEMPLATE(T, poly_print_pretty) (f, "X", ctx), + flint_printf("\n"); + flint_printf("g = "), TEMPLATE(T, poly_print_pretty) (g, "X", ctx), + flint_printf("\n"); + flint_printf("h = "), TEMPLATE(T, poly_print_pretty) (h, "X", ctx), + flint_printf("\n"); + flint_printf("s = "), TEMPLATE(T, poly_print_pretty) (s, "X", ctx), + flint_printf("\n"); + flint_printf("t = "), TEMPLATE(T, poly_print_pretty) (t, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (f, ctx); + TEMPLATE(T, poly_clear) (g, ctx); + TEMPLATE(T, poly_clear) (h, ctx); + TEMPLATE(T, poly_clear) (s, ctx); + TEMPLATE(T, poly_clear) (t, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-compose_horner.c b/external/flint-2.4.3/fq_poly_templates/test/t-compose_horner.c new file mode 100644 index 0000000..77fce30 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-compose_horner.c @@ -0,0 +1,184 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include + +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("compose_horner... "); + fflush(stdout); + + /* Check aliasing of the first argument */ + for (i = 0; i < 50; i++) + { + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) f, g, h; + + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (f, ctx); + TEMPLATE(T, poly_init) (g, ctx); + TEMPLATE(T, poly_init) (h, ctx); + + TEMPLATE(T, poly_randtest) (f, state, n_randint(state, 40), ctx); + TEMPLATE(T, poly_randtest) (g, state, n_randint(state, 20), ctx); + + TEMPLATE(T, poly_compose_horner) (h, f, g, ctx); + TEMPLATE(T, poly_compose_horner) (f, f, g, ctx); + + result = (TEMPLATE(T, poly_equal) (f, h, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("f = "), TEMPLATE(T, poly_print_pretty) (f, "X", ctx), + flint_printf("\n"); + flint_printf("g = "), TEMPLATE(T, poly_print_pretty) (g, "X", ctx), + flint_printf("\n"); + flint_printf("h = "), TEMPLATE(T, poly_print_pretty) (h, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (f, ctx); + TEMPLATE(T, poly_clear) (g, ctx); + TEMPLATE(T, poly_clear) (h, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check aliasing of the second argument */ + for (i = 0; i < 50; i++) + { + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) f, g, h; + + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (f, ctx); + TEMPLATE(T, poly_init) (g, ctx); + TEMPLATE(T, poly_init) (h, ctx); + + TEMPLATE(T, poly_randtest) (f, state, n_randint(state, 40), ctx); + TEMPLATE(T, poly_randtest) (g, state, n_randint(state, 20), ctx); + + TEMPLATE(T, poly_compose_horner) (h, f, g, ctx); + TEMPLATE(T, poly_compose_horner) (g, f, g, ctx); + + result = (TEMPLATE(T, poly_equal) (g, h, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("f = "), TEMPLATE(T, poly_print_pretty) (f, "X", ctx), + flint_printf("\n"); + flint_printf("g = "), TEMPLATE(T, poly_print_pretty) (g, "X", ctx), + flint_printf("\n"); + flint_printf("h = "), TEMPLATE(T, poly_print_pretty) (h, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (f, ctx); + TEMPLATE(T, poly_clear) (g, ctx); + TEMPLATE(T, poly_clear) (h, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Compare with the naive method */ + for (i = 0; i < 50; i++) + { + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) f, g, h, s, t; + slong k; + + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (f, ctx); + TEMPLATE(T, poly_init) (g, ctx); + TEMPLATE(T, poly_init) (h, ctx); + TEMPLATE(T, poly_init) (s, ctx); + TEMPLATE(T, poly_init) (t, ctx); + + TEMPLATE(T, poly_randtest) (g, state, n_randint(state, 40), ctx); + TEMPLATE(T, poly_randtest) (h, state, n_randint(state, 20), ctx); + + TEMPLATE(T, poly_one) (t, ctx); + for (k = 0; k < TEMPLATE(T, poly_length) (g, ctx); k++) + { + TEMPLATE(T, TEMPLATE(poly_scalar_addmul, T)) (s, t, g->coeffs + k, + ctx); + TEMPLATE(T, poly_mul) (t, t, h, ctx); + } + + TEMPLATE(T, poly_compose_horner) (f, g, h, ctx); + + result = (TEMPLATE(T, poly_equal) (f, s, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("f = "), TEMPLATE(T, poly_print_pretty) (f, "X", ctx), + flint_printf("\n"); + flint_printf("g = "), TEMPLATE(T, poly_print_pretty) (g, "X", ctx), + flint_printf("\n"); + flint_printf("h = "), TEMPLATE(T, poly_print_pretty) (h, "X", ctx), + flint_printf("\n"); + flint_printf("s = "), TEMPLATE(T, poly_print_pretty) (s, "X", ctx), + flint_printf("\n"); + flint_printf("t = "), TEMPLATE(T, poly_print_pretty) (t, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (f, ctx); + TEMPLATE(T, poly_clear) (g, ctx); + TEMPLATE(T, poly_clear) (h, ctx); + TEMPLATE(T, poly_clear) (s, ctx); + TEMPLATE(T, poly_clear) (t, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-compose_mod.c b/external/flint-2.4.3/fq_poly_templates/test/t-compose_mod.c new file mode 100644 index 0000000..c203130 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-compose_mod.c @@ -0,0 +1,246 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + flint_printf("compose_mod...."); + fflush(stdout); + + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, b, c, d, e; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + TEMPLATE(T, poly_init) (d, ctx); + TEMPLATE(T, poly_init) (e, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 20) + 1, ctx); + TEMPLATE(T, poly_randtest) (b, state, n_randint(state, 20) + 1, ctx); + TEMPLATE(T, poly_randtest_not_zero) (c, state, + n_randint(state, 20) + 1, ctx); + + TEMPLATE(T, poly_compose_mod) (d, a, b, c, ctx); + TEMPLATE(T, poly_compose) (e, a, b, ctx); + TEMPLATE(T, poly_rem) (e, e, c, ctx); + + if (!TEMPLATE(T, poly_equal) (d, e, ctx)) + { + flint_printf("FAIL (composition):\n"); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx); + flint_printf("\n"); + flint_printf("b:\n"); + TEMPLATE(T, poly_print) (b, ctx); + flint_printf("\n"); + flint_printf("c:\n"); + TEMPLATE(T, poly_print) (c, ctx); + flint_printf("\n"); + flint_printf("d:\n"); + TEMPLATE(T, poly_print) (d, ctx); + flint_printf("\n"); + flint_printf("e:\n"); + TEMPLATE(T, poly_print) (e, ctx); + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + TEMPLATE(T, poly_clear) (d, ctx); + TEMPLATE(T, poly_clear) (e, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Test aliasing of res and a */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, b, c, d; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + TEMPLATE(T, poly_init) (d, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 20) + 1, ctx); + TEMPLATE(T, poly_randtest) (b, state, n_randint(state, 20) + 1, ctx); + TEMPLATE(T, poly_randtest_not_zero) (c, state, + n_randint(state, 20) + 1, ctx); + + TEMPLATE(T, poly_compose_mod) (d, a, b, c, ctx); + TEMPLATE(T, poly_compose_mod) (a, a, b, c, ctx); + + if (!TEMPLATE(T, poly_equal) (d, a, ctx)) + { + flint_printf("FAIL (aliasing a):\n"); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx); + flint_printf("\n"); + flint_printf("b:\n"); + TEMPLATE(T, poly_print) (b, ctx); + flint_printf("\n"); + flint_printf("c:\n"); + TEMPLATE(T, poly_print) (c, ctx); + flint_printf("\n"); + flint_printf("d:\n"); + TEMPLATE(T, poly_print) (d, ctx); + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + TEMPLATE(T, poly_clear) (d, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Test aliasing of res and b */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, b, c, d; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + TEMPLATE(T, poly_init) (d, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 20) + 1, ctx); + TEMPLATE(T, poly_randtest) (b, state, n_randint(state, 20) + 1, ctx); + TEMPLATE(T, poly_randtest_not_zero) (c, state, + n_randint(state, 20) + 1, ctx); + + TEMPLATE(T, poly_compose_mod) (d, a, b, c, ctx); + TEMPLATE(T, poly_compose_mod) (b, a, b, c, ctx); + + if (!TEMPLATE(T, poly_equal) (d, b, ctx)) + { + flint_printf("FAIL (aliasing b)\n"); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx); + flint_printf("\n"); + flint_printf("b:\n"); + TEMPLATE(T, poly_print) (b, ctx); + flint_printf("\n"); + flint_printf("c:\n"); + TEMPLATE(T, poly_print) (c, ctx); + flint_printf("\n"); + flint_printf("d:\n"); + TEMPLATE(T, poly_print) (d, ctx); + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + TEMPLATE(T, poly_clear) (d, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Test aliasing of res and c */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, b, c, d; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + TEMPLATE(T, poly_init) (d, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 20) + 1, ctx); + TEMPLATE(T, poly_randtest) (b, state, n_randint(state, 20) + 1, ctx); + TEMPLATE(T, poly_randtest_not_zero) (c, state, + n_randint(state, 20) + 1, ctx); + + TEMPLATE(T, poly_compose_mod) (d, a, b, c, ctx); + TEMPLATE(T, poly_compose_mod) (c, a, b, c, ctx); + + if (!TEMPLATE(T, poly_equal) (d, c, ctx)) + { + flint_printf("FAIL (aliasing c)\n"); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx); + flint_printf("\n"); + flint_printf("b:\n"); + TEMPLATE(T, poly_print) (b, ctx); + flint_printf("\n"); + flint_printf("c:\n"); + TEMPLATE(T, poly_print) (c, ctx); + flint_printf("\n"); + flint_printf("d:\n"); + TEMPLATE(T, poly_print) (d, ctx); + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + TEMPLATE(T, poly_clear) (d, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-compose_mod_brent_kung.c b/external/flint-2.4.3/fq_poly_templates/test/t-compose_mod_brent_kung.c new file mode 100644 index 0000000..6c25d2e --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-compose_mod_brent_kung.c @@ -0,0 +1,250 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + flint_printf("compose_mod_brent_kung...."); + fflush(stdout); + + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, b, c, d, e; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + TEMPLATE(T, poly_init) (d, ctx); + TEMPLATE(T, poly_init) (e, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 20) + 1, ctx); + TEMPLATE(T, poly_randtest) (b, state, n_randint(state, 20) + 1, ctx); + TEMPLATE(T, poly_randtest_not_zero) (c, state, + n_randint(state, 20) + 1, ctx); + + TEMPLATE(T, poly_rem) (a, a, c, ctx); + TEMPLATE(T, poly_compose_mod_brent_kung) (d, a, b, c, ctx); + TEMPLATE(T, poly_compose) (e, a, b, ctx); + TEMPLATE(T, poly_rem) (e, e, c, ctx); + + if (!TEMPLATE(T, poly_equal) (d, e, ctx)) + { + flint_printf("FAIL (composition):\n"); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx); + flint_printf("\n"); + flint_printf("b:\n"); + TEMPLATE(T, poly_print) (b, ctx); + flint_printf("\n"); + flint_printf("c:\n"); + TEMPLATE(T, poly_print) (c, ctx); + flint_printf("\n"); + flint_printf("d:\n"); + TEMPLATE(T, poly_print) (d, ctx); + flint_printf("\n"); + flint_printf("e:\n"); + TEMPLATE(T, poly_print) (e, ctx); + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + TEMPLATE(T, poly_clear) (d, ctx); + TEMPLATE(T, poly_clear) (e, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Test aliasing of res and a */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, b, c, d; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + TEMPLATE(T, poly_init) (d, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 20) + 1, ctx); + TEMPLATE(T, poly_randtest) (b, state, n_randint(state, 20) + 1, ctx); + TEMPLATE(T, poly_randtest_not_zero) (c, state, + n_randint(state, 20) + 1, ctx); + + TEMPLATE(T, poly_rem) (a, a, c, ctx); + TEMPLATE(T, poly_compose_mod_brent_kung) (d, a, b, c, ctx); + TEMPLATE(T, poly_compose_mod_brent_kung) (a, a, b, c, ctx); + + if (!TEMPLATE(T, poly_equal) (d, a, ctx)) + { + flint_printf("FAIL (aliasing a):\n"); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx); + flint_printf("\n"); + flint_printf("b:\n"); + TEMPLATE(T, poly_print) (b, ctx); + flint_printf("\n"); + flint_printf("c:\n"); + TEMPLATE(T, poly_print) (c, ctx); + flint_printf("\n"); + flint_printf("d:\n"); + TEMPLATE(T, poly_print) (d, ctx); + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + TEMPLATE(T, poly_clear) (d, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Test aliasing of res and b */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, b, c, d; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + TEMPLATE(T, poly_init) (d, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 20) + 1, ctx); + TEMPLATE(T, poly_randtest) (b, state, n_randint(state, 20) + 1, ctx); + TEMPLATE(T, poly_randtest_not_zero) (c, state, + n_randint(state, 20) + 1, ctx); + + TEMPLATE(T, poly_rem) (a, a, c, ctx); + TEMPLATE(T, poly_compose_mod_brent_kung) (d, a, b, c, ctx); + TEMPLATE(T, poly_compose_mod_brent_kung) (b, a, b, c, ctx); + + if (!TEMPLATE(T, poly_equal) (d, b, ctx)) + { + flint_printf("FAIL (aliasing b)\n"); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx); + flint_printf("\n"); + flint_printf("b:\n"); + TEMPLATE(T, poly_print) (b, ctx); + flint_printf("\n"); + flint_printf("c:\n"); + TEMPLATE(T, poly_print) (c, ctx); + flint_printf("\n"); + flint_printf("d:\n"); + TEMPLATE(T, poly_print) (d, ctx); + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + TEMPLATE(T, poly_clear) (d, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Test aliasing of res and c */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, b, c, d; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + TEMPLATE(T, poly_init) (d, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 20) + 1, ctx); + TEMPLATE(T, poly_randtest) (b, state, n_randint(state, 20) + 1, ctx); + TEMPLATE(T, poly_randtest_not_zero) (c, state, + n_randint(state, 20) + 1, ctx); + + TEMPLATE(T, poly_rem) (a, a, c, ctx); + TEMPLATE(T, poly_compose_mod_brent_kung) (d, a, b, c, ctx); + TEMPLATE(T, poly_compose_mod_brent_kung) (c, a, b, c, ctx); + + if (!TEMPLATE(T, poly_equal) (d, c, ctx)) + { + flint_printf("FAIL (aliasing c)\n"); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx); + flint_printf("\n"); + flint_printf("b:\n"); + TEMPLATE(T, poly_print) (b, ctx); + flint_printf("\n"); + flint_printf("c:\n"); + TEMPLATE(T, poly_print) (c, ctx); + flint_printf("\n"); + flint_printf("d:\n"); + TEMPLATE(T, poly_print) (d, ctx); + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + TEMPLATE(T, poly_clear) (d, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-compose_mod_brent_kung_preinv.c b/external/flint-2.4.3/fq_poly_templates/test/t-compose_mod_brent_kung_preinv.c new file mode 100644 index 0000000..57bc94e --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-compose_mod_brent_kung_preinv.c @@ -0,0 +1,273 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Martin Lee + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + flint_printf("compose_mod_brent_kung_preinv...."); + fflush(stdout); + + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, b, c, cinv, d, e; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + TEMPLATE(T, poly_init) (cinv, ctx); + TEMPLATE(T, poly_init) (d, ctx); + TEMPLATE(T, poly_init) (e, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 20) + 1, ctx); + TEMPLATE(T, poly_randtest) (b, state, n_randint(state, 20) + 1, ctx); + TEMPLATE(T, poly_randtest_not_zero) (c, state, + n_randint(state, 20) + 1, ctx); + + TEMPLATE(T, poly_reverse) (cinv, c, c->length, ctx); + TEMPLATE(T, poly_inv_series_newton) (cinv, cinv, c->length, ctx); + + TEMPLATE(T, poly_rem) (a, a, c, ctx); + TEMPLATE(T, poly_compose_mod_brent_kung_preinv) (d, a, b, c, cinv, + ctx); + TEMPLATE(T, poly_compose) (e, a, b, ctx); + TEMPLATE(T, poly_rem) (e, e, c, ctx); + + if (!TEMPLATE(T, poly_equal) (d, e, ctx)) + { + flint_printf("FAIL (composition):\n"); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx); + flint_printf("\n"); + flint_printf("b:\n"); + TEMPLATE(T, poly_print) (b, ctx); + flint_printf("\n"); + flint_printf("c:\n"); + TEMPLATE(T, poly_print) (c, ctx); + flint_printf("\n"); + flint_printf("d:\n"); + TEMPLATE(T, poly_print) (d, ctx); + flint_printf("\n"); + flint_printf("e:\n"); + TEMPLATE(T, poly_print) (e, ctx); + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + TEMPLATE(T, poly_clear) (cinv, ctx); + TEMPLATE(T, poly_clear) (d, ctx); + TEMPLATE(T, poly_clear) (e, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Test aliasing of res and a */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, b, c, cinv, d; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + TEMPLATE(T, poly_init) (cinv, ctx); + TEMPLATE(T, poly_init) (d, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 20) + 1, ctx); + TEMPLATE(T, poly_randtest) (b, state, n_randint(state, 20) + 1, ctx); + TEMPLATE(T, poly_randtest_not_zero) (c, state, + n_randint(state, 20) + 1, ctx); + + TEMPLATE(T, poly_reverse) (cinv, c, c->length, ctx); + TEMPLATE(T, poly_inv_series_newton) (cinv, cinv, c->length, ctx); + + TEMPLATE(T, poly_rem) (a, a, c, ctx); + TEMPLATE(T, poly_compose_mod_brent_kung_preinv) (d, a, b, c, cinv, + ctx); + TEMPLATE(T, poly_compose_mod_brent_kung_preinv) (a, a, b, c, cinv, + ctx); + + if (!TEMPLATE(T, poly_equal) (d, a, ctx)) + { + flint_printf("FAIL (aliasing a):\n"); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx); + flint_printf("\n"); + flint_printf("b:\n"); + TEMPLATE(T, poly_print) (b, ctx); + flint_printf("\n"); + flint_printf("c:\n"); + TEMPLATE(T, poly_print) (c, ctx); + flint_printf("\n"); + flint_printf("d:\n"); + TEMPLATE(T, poly_print) (d, ctx); + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + TEMPLATE(T, poly_clear) (cinv, ctx); + TEMPLATE(T, poly_clear) (d, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Test aliasing of res and b */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, b, c, cinv, d; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + TEMPLATE(T, poly_init) (cinv, ctx); + TEMPLATE(T, poly_init) (d, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 20) + 1, ctx); + TEMPLATE(T, poly_randtest) (b, state, n_randint(state, 20) + 1, ctx); + TEMPLATE(T, poly_randtest_not_zero) (c, state, + n_randint(state, 20) + 1, ctx); + + TEMPLATE(T, poly_reverse) (cinv, c, c->length, ctx); + TEMPLATE(T, poly_inv_series_newton) (cinv, cinv, c->length, ctx); + + TEMPLATE(T, poly_rem) (a, a, c, ctx); + TEMPLATE(T, poly_compose_mod_brent_kung_preinv) (d, a, b, c, cinv, + ctx); + TEMPLATE(T, poly_compose_mod_brent_kung_preinv) (b, a, b, c, cinv, + ctx); + + if (!TEMPLATE(T, poly_equal) (d, b, ctx)) + { + flint_printf("FAIL (aliasing b)\n"); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx); + flint_printf("\n"); + flint_printf("b:\n"); + TEMPLATE(T, poly_print) (b, ctx); + flint_printf("\n"); + flint_printf("c:\n"); + TEMPLATE(T, poly_print) (c, ctx); + flint_printf("\n"); + flint_printf("d:\n"); + TEMPLATE(T, poly_print) (d, ctx); + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + TEMPLATE(T, poly_clear) (cinv, ctx); + TEMPLATE(T, poly_clear) (d, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Test aliasing of res and c */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, b, c, cinv, d; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + TEMPLATE(T, poly_init) (cinv, ctx); + TEMPLATE(T, poly_init) (d, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 20) + 1, ctx); + TEMPLATE(T, poly_randtest) (b, state, n_randint(state, 20) + 1, ctx); + TEMPLATE(T, poly_randtest_not_zero) (c, state, + n_randint(state, 20) + 1, ctx); + + TEMPLATE(T, poly_reverse) (cinv, c, c->length, ctx); + TEMPLATE(T, poly_inv_series_newton) (cinv, cinv, c->length, ctx); + + TEMPLATE(T, poly_rem) (a, a, c, ctx); + TEMPLATE(T, poly_compose_mod_brent_kung_preinv) (d, a, b, c, cinv, + ctx); + TEMPLATE(T, poly_compose_mod_brent_kung_preinv) (c, a, b, c, cinv, + ctx); + + if (!TEMPLATE(T, poly_equal) (d, c, ctx)) + { + flint_printf("FAIL (aliasing c)\n"); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx); + flint_printf("\n"); + flint_printf("b:\n"); + TEMPLATE(T, poly_print) (b, ctx); + flint_printf("\n"); + flint_printf("c:\n"); + TEMPLATE(T, poly_print) (c, ctx); + flint_printf("\n"); + flint_printf("d:\n"); + TEMPLATE(T, poly_print) (d, ctx); + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + TEMPLATE(T, poly_clear) (cinv, ctx); + TEMPLATE(T, poly_clear) (d, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-compose_mod_horner.c b/external/flint-2.4.3/fq_poly_templates/test/t-compose_mod_horner.c new file mode 100644 index 0000000..d5364b8 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-compose_mod_horner.c @@ -0,0 +1,246 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + flint_printf("compose_mod_horner...."); + fflush(stdout); + + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, b, c, d, e; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + TEMPLATE(T, poly_init) (d, ctx); + TEMPLATE(T, poly_init) (e, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 20) + 1, ctx); + TEMPLATE(T, poly_randtest) (b, state, n_randint(state, 20) + 1, ctx); + TEMPLATE(T, poly_randtest_not_zero) (c, state, + n_randint(state, 20) + 1, ctx); + + TEMPLATE(T, poly_compose_mod_horner) (d, a, b, c, ctx); + TEMPLATE(T, poly_compose) (e, a, b, ctx); + TEMPLATE(T, poly_rem) (e, e, c, ctx); + + if (!TEMPLATE(T, poly_equal) (d, e, ctx)) + { + flint_printf("FAIL (composition):\n"); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx); + flint_printf("\n"); + flint_printf("b:\n"); + TEMPLATE(T, poly_print) (b, ctx); + flint_printf("\n"); + flint_printf("c:\n"); + TEMPLATE(T, poly_print) (c, ctx); + flint_printf("\n"); + flint_printf("d:\n"); + TEMPLATE(T, poly_print) (d, ctx); + flint_printf("\n"); + flint_printf("e:\n"); + TEMPLATE(T, poly_print) (e, ctx); + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + TEMPLATE(T, poly_clear) (d, ctx); + TEMPLATE(T, poly_clear) (e, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Test aliasing of res and a */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, b, c, d; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + TEMPLATE(T, poly_init) (d, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 20) + 1, ctx); + TEMPLATE(T, poly_randtest) (b, state, n_randint(state, 20) + 1, ctx); + TEMPLATE(T, poly_randtest_not_zero) (c, state, + n_randint(state, 20) + 1, ctx); + + TEMPLATE(T, poly_compose_mod_horner) (d, a, b, c, ctx); + TEMPLATE(T, poly_compose_mod_horner) (a, a, b, c, ctx); + + if (!TEMPLATE(T, poly_equal) (d, a, ctx)) + { + flint_printf("FAIL (aliasing a):\n"); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx); + flint_printf("\n"); + flint_printf("b:\n"); + TEMPLATE(T, poly_print) (b, ctx); + flint_printf("\n"); + flint_printf("c:\n"); + TEMPLATE(T, poly_print) (c, ctx); + flint_printf("\n"); + flint_printf("d:\n"); + TEMPLATE(T, poly_print) (d, ctx); + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + TEMPLATE(T, poly_clear) (d, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Test aliasing of res and b */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, b, c, d; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + TEMPLATE(T, poly_init) (d, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 20) + 1, ctx); + TEMPLATE(T, poly_randtest) (b, state, n_randint(state, 20) + 1, ctx); + TEMPLATE(T, poly_randtest_not_zero) (c, state, + n_randint(state, 20) + 1, ctx); + + TEMPLATE(T, poly_compose_mod_horner) (d, a, b, c, ctx); + TEMPLATE(T, poly_compose_mod_horner) (b, a, b, c, ctx); + + if (!TEMPLATE(T, poly_equal) (d, b, ctx)) + { + flint_printf("FAIL (aliasing b)\n"); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx); + flint_printf("\n"); + flint_printf("b:\n"); + TEMPLATE(T, poly_print) (b, ctx); + flint_printf("\n"); + flint_printf("c:\n"); + TEMPLATE(T, poly_print) (c, ctx); + flint_printf("\n"); + flint_printf("d:\n"); + TEMPLATE(T, poly_print) (d, ctx); + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + TEMPLATE(T, poly_clear) (d, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Test aliasing of res and c */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, b, c, d; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + TEMPLATE(T, poly_init) (d, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 20) + 1, ctx); + TEMPLATE(T, poly_randtest) (b, state, n_randint(state, 20) + 1, ctx); + TEMPLATE(T, poly_randtest_not_zero) (c, state, + n_randint(state, 20) + 1, ctx); + + TEMPLATE(T, poly_compose_mod_horner) (d, a, b, c, ctx); + TEMPLATE(T, poly_compose_mod_horner) (c, a, b, c, ctx); + + if (!TEMPLATE(T, poly_equal) (d, c, ctx)) + { + flint_printf("FAIL (aliasing c)\n"); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx); + flint_printf("\n"); + flint_printf("b:\n"); + TEMPLATE(T, poly_print) (b, ctx); + flint_printf("\n"); + flint_printf("c:\n"); + TEMPLATE(T, poly_print) (c, ctx); + flint_printf("\n"); + flint_printf("d:\n"); + TEMPLATE(T, poly_print) (d, ctx); + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + TEMPLATE(T, poly_clear) (d, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-compose_mod_horner_preinv.c b/external/flint-2.4.3/fq_poly_templates/test/t-compose_mod_horner_preinv.c new file mode 100644 index 0000000..e5293d3 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-compose_mod_horner_preinv.c @@ -0,0 +1,265 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + flint_printf("compose_mod_horner_preinv...."); + fflush(stdout); + + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, b, c, cinv, d, e; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + TEMPLATE(T, poly_init) (cinv, ctx); + TEMPLATE(T, poly_init) (d, ctx); + TEMPLATE(T, poly_init) (e, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 20) + 1, ctx); + TEMPLATE(T, poly_randtest) (b, state, n_randint(state, 20) + 1, ctx); + TEMPLATE(T, poly_randtest_not_zero) (c, state, + n_randint(state, 20) + 1, ctx); + + TEMPLATE(T, poly_reverse) (cinv, c, c->length, ctx); + TEMPLATE(T, poly_inv_series_newton) (cinv, cinv, c->length, ctx); + + TEMPLATE(T, poly_rem) (a, a, c, ctx); + TEMPLATE(T, poly_compose_mod_horner_preinv) (d, a, b, c, cinv, ctx); + TEMPLATE(T, poly_compose) (e, a, b, ctx); + TEMPLATE(T, poly_rem) (e, e, c, ctx); + + if (!TEMPLATE(T, poly_equal) (d, e, ctx)) + { + flint_printf("FAIL (composition):\n"); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx); + flint_printf("\n"); + flint_printf("b:\n"); + TEMPLATE(T, poly_print) (b, ctx); + flint_printf("\n"); + flint_printf("c:\n"); + TEMPLATE(T, poly_print) (c, ctx); + flint_printf("\n"); + flint_printf("d:\n"); + TEMPLATE(T, poly_print) (d, ctx); + flint_printf("\n"); + flint_printf("e:\n"); + TEMPLATE(T, poly_print) (e, ctx); + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + TEMPLATE(T, poly_clear) (cinv, ctx); + TEMPLATE(T, poly_clear) (d, ctx); + TEMPLATE(T, poly_clear) (e, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Test aliasing of res and a */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, b, c, cinv, d; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + TEMPLATE(T, poly_init) (cinv, ctx); + TEMPLATE(T, poly_init) (d, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 20) + 1, ctx); + TEMPLATE(T, poly_randtest) (b, state, n_randint(state, 20) + 1, ctx); + TEMPLATE(T, poly_randtest_not_zero) (c, state, + n_randint(state, 20) + 1, ctx); + + TEMPLATE(T, poly_reverse) (cinv, c, c->length, ctx); + TEMPLATE(T, poly_inv_series_newton) (cinv, cinv, c->length, ctx); + + TEMPLATE(T, poly_rem) (a, a, c, ctx); + TEMPLATE(T, poly_compose_mod_horner_preinv) (d, a, b, c, cinv, ctx); + TEMPLATE(T, poly_compose_mod_horner_preinv) (a, a, b, c, cinv, ctx); + + if (!TEMPLATE(T, poly_equal) (d, a, ctx)) + { + flint_printf("FAIL (aliasing a):\n"); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx); + flint_printf("\n"); + flint_printf("b:\n"); + TEMPLATE(T, poly_print) (b, ctx); + flint_printf("\n"); + flint_printf("c:\n"); + TEMPLATE(T, poly_print) (c, ctx); + flint_printf("\n"); + flint_printf("d:\n"); + TEMPLATE(T, poly_print) (d, ctx); + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + TEMPLATE(T, poly_clear) (cinv, ctx); + TEMPLATE(T, poly_clear) (d, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Test aliasing of res and b */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, b, c, cinv, d; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + TEMPLATE(T, poly_init) (cinv, ctx); + TEMPLATE(T, poly_init) (d, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 20) + 1, ctx); + TEMPLATE(T, poly_randtest) (b, state, n_randint(state, 20) + 1, ctx); + TEMPLATE(T, poly_randtest_not_zero) (c, state, + n_randint(state, 20) + 1, ctx); + + TEMPLATE(T, poly_reverse) (cinv, c, c->length, ctx); + TEMPLATE(T, poly_inv_series_newton) (cinv, cinv, c->length, ctx); + + TEMPLATE(T, poly_rem) (a, a, c, ctx); + TEMPLATE(T, poly_compose_mod_horner_preinv) (d, a, b, c, cinv, ctx); + TEMPLATE(T, poly_compose_mod_horner_preinv) (b, a, b, c, cinv, ctx); + + if (!TEMPLATE(T, poly_equal) (d, b, ctx)) + { + flint_printf("FAIL (aliasing b)\n"); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx); + flint_printf("\n"); + flint_printf("b:\n"); + TEMPLATE(T, poly_print) (b, ctx); + flint_printf("\n"); + flint_printf("c:\n"); + TEMPLATE(T, poly_print) (c, ctx); + flint_printf("\n"); + flint_printf("d:\n"); + TEMPLATE(T, poly_print) (d, ctx); + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + TEMPLATE(T, poly_clear) (cinv, ctx); + TEMPLATE(T, poly_clear) (d, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Test aliasing of res and c */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, b, c, cinv, d; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + TEMPLATE(T, poly_init) (cinv, ctx); + TEMPLATE(T, poly_init) (d, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 20) + 1, ctx); + TEMPLATE(T, poly_randtest) (b, state, n_randint(state, 20) + 1, ctx); + TEMPLATE(T, poly_randtest_not_zero) (c, state, + n_randint(state, 20) + 1, ctx); + + TEMPLATE(T, poly_reverse) (cinv, c, c->length, ctx); + TEMPLATE(T, poly_inv_series_newton) (cinv, cinv, c->length, ctx); + + TEMPLATE(T, poly_rem) (a, a, c, ctx); + TEMPLATE(T, poly_compose_mod_horner_preinv) (d, a, b, c, cinv, ctx); + TEMPLATE(T, poly_compose_mod_horner_preinv) (c, a, b, c, cinv, ctx); + + if (!TEMPLATE(T, poly_equal) (d, c, ctx)) + { + flint_printf("FAIL (aliasing c)\n"); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx); + flint_printf("\n"); + flint_printf("b:\n"); + TEMPLATE(T, poly_print) (b, ctx); + flint_printf("\n"); + flint_printf("c:\n"); + TEMPLATE(T, poly_print) (c, ctx); + flint_printf("\n"); + flint_printf("d:\n"); + TEMPLATE(T, poly_print) (d, ctx); + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + TEMPLATE(T, poly_clear) (cinv, ctx); + TEMPLATE(T, poly_clear) (d, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-compose_mod_preinv.c b/external/flint-2.4.3/fq_poly_templates/test/t-compose_mod_preinv.c new file mode 100644 index 0000000..263d3fe --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-compose_mod_preinv.c @@ -0,0 +1,266 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Martin Lee + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + flint_printf("compose_mod_preinv...."); + fflush(stdout); + + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, b, c, cinv, d, e; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + TEMPLATE(T, poly_init) (cinv, ctx); + TEMPLATE(T, poly_init) (d, ctx); + TEMPLATE(T, poly_init) (e, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 20) + 1, ctx); + TEMPLATE(T, poly_randtest) (b, state, n_randint(state, 20) + 1, ctx); + TEMPLATE(T, poly_randtest_not_zero) (c, state, + n_randint(state, 20) + 1, ctx); + + TEMPLATE(T, poly_reverse) (cinv, c, c->length, ctx); + TEMPLATE(T, poly_inv_series_newton) (cinv, cinv, c->length, ctx); + + TEMPLATE(T, poly_rem) (a, a, c, ctx); + TEMPLATE(T, poly_compose_mod_preinv) (d, a, b, c, cinv, ctx); + TEMPLATE(T, poly_compose) (e, a, b, ctx); + TEMPLATE(T, poly_rem) (e, e, c, ctx); + + if (!TEMPLATE(T, poly_equal) (d, e, ctx)) + { + flint_printf("FAIL (composition):\n"); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx); + flint_printf("\n"); + flint_printf("b:\n"); + TEMPLATE(T, poly_print) (b, ctx); + flint_printf("\n"); + flint_printf("c:\n"); + TEMPLATE(T, poly_print) (c, ctx); + flint_printf("\n"); + flint_printf("d:\n"); + TEMPLATE(T, poly_print) (d, ctx); + flint_printf("\n"); + flint_printf("e:\n"); + TEMPLATE(T, poly_print) (e, ctx); + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + TEMPLATE(T, poly_clear) (cinv, ctx); + TEMPLATE(T, poly_clear) (d, ctx); + TEMPLATE(T, poly_clear) (e, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Test aliasing of res and a */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, b, c, cinv, d; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + TEMPLATE(T, poly_init) (cinv, ctx); + TEMPLATE(T, poly_init) (d, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 20) + 1, ctx); + TEMPLATE(T, poly_randtest) (b, state, n_randint(state, 20) + 1, ctx); + TEMPLATE(T, poly_randtest_not_zero) (c, state, + n_randint(state, 20) + 1, ctx); + + TEMPLATE(T, poly_reverse) (cinv, c, c->length, ctx); + TEMPLATE(T, poly_inv_series_newton) (cinv, cinv, c->length, ctx); + + TEMPLATE(T, poly_rem) (a, a, c, ctx); + TEMPLATE(T, poly_compose_mod_preinv) (d, a, b, c, cinv, ctx); + TEMPLATE(T, poly_compose_mod_preinv) (a, a, b, c, cinv, ctx); + + if (!TEMPLATE(T, poly_equal) (d, a, ctx)) + { + flint_printf("FAIL (aliasing a):\n"); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx); + flint_printf("\n"); + flint_printf("b:\n"); + TEMPLATE(T, poly_print) (b, ctx); + flint_printf("\n"); + flint_printf("c:\n"); + TEMPLATE(T, poly_print) (c, ctx); + flint_printf("\n"); + flint_printf("d:\n"); + TEMPLATE(T, poly_print) (d, ctx); + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + TEMPLATE(T, poly_clear) (cinv, ctx); + TEMPLATE(T, poly_clear) (d, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Test aliasing of res and b */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, b, c, cinv, d; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + TEMPLATE(T, poly_init) (cinv, ctx); + TEMPLATE(T, poly_init) (d, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 20) + 1, ctx); + TEMPLATE(T, poly_randtest) (b, state, n_randint(state, 20) + 1, ctx); + TEMPLATE(T, poly_randtest_not_zero) (c, state, + n_randint(state, 20) + 1, ctx); + + TEMPLATE(T, poly_reverse) (cinv, c, c->length, ctx); + TEMPLATE(T, poly_inv_series_newton) (cinv, cinv, c->length, ctx); + + TEMPLATE(T, poly_rem) (a, a, c, ctx); + TEMPLATE(T, poly_compose_mod_preinv) (d, a, b, c, cinv, ctx); + TEMPLATE(T, poly_compose_mod_preinv) (b, a, b, c, cinv, ctx); + + if (!TEMPLATE(T, poly_equal) (d, b, ctx)) + { + flint_printf("FAIL (aliasing b)\n"); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx); + flint_printf("\n"); + flint_printf("b:\n"); + TEMPLATE(T, poly_print) (b, ctx); + flint_printf("\n"); + flint_printf("c:\n"); + TEMPLATE(T, poly_print) (c, ctx); + flint_printf("\n"); + flint_printf("d:\n"); + TEMPLATE(T, poly_print) (d, ctx); + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + TEMPLATE(T, poly_clear) (cinv, ctx); + TEMPLATE(T, poly_clear) (d, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Test aliasing of res and c */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, b, c, cinv, d; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + TEMPLATE(T, poly_init) (cinv, ctx); + TEMPLATE(T, poly_init) (d, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 20) + 1, ctx); + TEMPLATE(T, poly_randtest) (b, state, n_randint(state, 20) + 1, ctx); + TEMPLATE(T, poly_randtest_not_zero) (c, state, + n_randint(state, 20) + 1, ctx); + + TEMPLATE(T, poly_reverse) (cinv, c, c->length, ctx); + TEMPLATE(T, poly_inv_series_newton) (cinv, cinv, c->length, ctx); + + TEMPLATE(T, poly_rem) (a, a, c, ctx); + TEMPLATE(T, poly_compose_mod_preinv) (d, a, b, c, cinv, ctx); + TEMPLATE(T, poly_compose_mod_preinv) (c, a, b, c, cinv, ctx); + + if (!TEMPLATE(T, poly_equal) (d, c, ctx)) + { + flint_printf("FAIL (aliasing c)\n"); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx); + flint_printf("\n"); + flint_printf("b:\n"); + TEMPLATE(T, poly_print) (b, ctx); + flint_printf("\n"); + flint_printf("c:\n"); + TEMPLATE(T, poly_print) (c, ctx); + flint_printf("\n"); + flint_printf("d:\n"); + TEMPLATE(T, poly_print) (d, ctx); + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + TEMPLATE(T, poly_clear) (cinv, ctx); + TEMPLATE(T, poly_clear) (d, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-deflate.c b/external/flint-2.4.3/fq_poly_templates/test/t-deflate.c new file mode 100644 index 0000000..e875ce5 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-deflate.c @@ -0,0 +1,135 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +int +main(void) +{ + int iter; + FLINT_TEST_INIT(state); + + flint_printf("deflate...."); + fflush(stdout); + + for (iter = 0; iter < 100 * flint_test_multiplier(); iter++) + { + TEMPLATE(T, poly_t) poly1, poly2, poly3; + TEMPLATE(T, ctx_t) ctx; + ulong infl1, infl, deflation; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (poly1, ctx); + TEMPLATE(T, poly_init) (poly2, ctx); + TEMPLATE(T, poly_init) (poly3, ctx); + + TEMPLATE(T, poly_randtest) (poly1, state, n_randint(state, 15), ctx); + + if (TEMPLATE(T, poly_length) (poly1, ctx) <= 1) + { + if (TEMPLATE(T, poly_deflation) (poly1, ctx) != + TEMPLATE(T, poly_length) (poly1, ctx)) + { + flint_printf + ("FAIL: wrong deflation for constant polynomial\n"); + abort(); + } + + TEMPLATE(T, poly_deflate) (poly2, poly1, n_randint(state, 5) + 1, + ctx); + if (!TEMPLATE(T, poly_equal) (poly2, poly1, ctx)) + { + flint_printf + ("FAIL: constant polynomial changed on deflation\n"); + abort(); + } + } + else + { + + infl = n_randint(state, 13) + 1; + infl1 = TEMPLATE(T, poly_deflation) (poly1, ctx); + + TEMPLATE(T, poly_inflate) (poly2, poly1, infl, ctx); + + deflation = TEMPLATE(T, poly_deflation) (poly2, ctx); + + if (deflation != infl * infl1) + { + flint_printf("FAIL: deflation = %wu, inflation: %wu, %wu\n", + deflation, infl, infl1); + flint_printf("poly1:\n"); + TEMPLATE(T, poly_print) (poly1, ctx); + flint_printf("\n\n"); + flint_printf("poly2:\n"); + TEMPLATE(T, poly_print) (poly2, ctx); + flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_deflate) (poly3, poly2, infl, ctx); + if (!TEMPLATE(T, poly_equal) (poly3, poly1, ctx)) + { + flint_printf("FAIL: deflation = %wu, inflation: %wu, %wu\n", + deflation, infl, infl1); + flint_printf("Deflated polynomial not equal to input:\n"); + flint_printf("poly1:\n"); + TEMPLATE(T, poly_print) (poly1, ctx); + flint_printf("\n\n"); + flint_printf("poly2:\n"); + TEMPLATE(T, poly_print) (poly2, ctx); + flint_printf("\n\n"); + flint_printf("poly3:\n"); + TEMPLATE(T, poly_print) (poly3, ctx); + flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_deflate) (poly2, poly2, infl, ctx); + if (!TEMPLATE(T, poly_equal) (poly3, poly2, ctx)) + { + flint_printf("FAIL: aliasing\n"); + abort(); + } + } + + TEMPLATE(T, poly_clear) (poly1, ctx); + TEMPLATE(T, poly_clear) (poly2, ctx); + TEMPLATE(T, poly_clear) (poly3, ctx); + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-derivative.c b/external/flint-2.4.3/fq_poly_templates/test/t-derivative.c new file mode 100644 index 0000000..3544dcb --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-derivative.c @@ -0,0 +1,185 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include + +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("derivative... "); + fflush(stdout); + + /* Check aliasing */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, c; + + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + TEMPLATE(T, poly_set) (b, a, ctx); + TEMPLATE(T, poly_derivative) (c, b, ctx); + TEMPLATE(T, poly_derivative) (b, b, ctx); + + result = (TEMPLATE(T, poly_equal) (b, c, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check constants have derivative zero */ + for (i = 0; i < 2000; i++) + { + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b; + + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 2), ctx); + TEMPLATE(T, poly_derivative) (b, a, ctx); + + result = (TEMPLATE(T, poly_is_zero) (b, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check (f g)' == f' g + f g' */ + for (i = 0; i < 2000; i++) + { + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, c, d, lhs, rhs; + + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + TEMPLATE(T, poly_init) (d, ctx); + TEMPLATE(T, poly_init) (lhs, ctx); + TEMPLATE(T, poly_init) (rhs, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 100), ctx); + TEMPLATE(T, poly_randtest) (b, state, n_randint(state, 100), ctx); + + TEMPLATE(T, poly_mul) (lhs, a, b, ctx); + TEMPLATE(T, poly_derivative) (lhs, lhs, ctx); + TEMPLATE(T, poly_derivative) (c, a, ctx); + TEMPLATE(T, poly_derivative) (d, b, ctx); + TEMPLATE(T, poly_mul) (c, c, b, ctx); + TEMPLATE(T, poly_mul) (d, a, d, ctx); + TEMPLATE(T, poly_add) (rhs, c, d, ctx); + + result = (TEMPLATE(T, poly_equal) (lhs, rhs, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", + ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", + ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", + ctx), + flint_printf("\n"); + flint_printf("d = "), TEMPLATE(T, poly_print_pretty) (d, "X", + ctx), + flint_printf("\n"); + flint_printf("lhs = "), TEMPLATE(T, poly_print_pretty) (lhs, "X", + ctx), + flint_printf("\n"); + flint_printf("rhs = "), TEMPLATE(T, poly_print_pretty) (rhs, "X", + ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + TEMPLATE(T, poly_clear) (d, ctx); + TEMPLATE(T, poly_clear) (lhs, ctx); + TEMPLATE(T, poly_clear) (rhs, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-div_basecase.c b/external/flint-2.4.3/fq_poly_templates/test/t-div_basecase.c new file mode 100644 index 0000000..fbd82bb --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-div_basecase.c @@ -0,0 +1,174 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2009 William Hart + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("div_basecase...."); + fflush(stdout); + + /* Compare to divrem_basecase */ + for (i = 0; i < 500; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, b, q, q2, r2; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (q, ctx); + TEMPLATE(T, poly_init) (q2, ctx); + TEMPLATE(T, poly_init) (r2, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 100), ctx); + TEMPLATE(T, poly_randtest_not_zero) (b, state, + n_randint(state, 100) + 1, ctx); + + TEMPLATE(T, poly_div_basecase) (q, a, b, ctx); + TEMPLATE(T, poly_divrem_basecase) (q2, r2, a, b, ctx); + + result = (TEMPLATE(T, poly_equal) (q, q2, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("ctx = "), TEMPLATE(T, ctx_print) (ctx), + flint_printf("\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print) (a, ctx), + flint_printf("\n\n"); + flint_printf("b = "), TEMPLATE(T, poly_print) (b, ctx), + flint_printf("\n\n"); + flint_printf("q = "), TEMPLATE(T, poly_print) (q, ctx), + flint_printf("\n\n"); + flint_printf("q2 = "), TEMPLATE(T, poly_print) (q2, ctx), + flint_printf("\n\n"); + flint_printf("r2 = "), TEMPLATE(T, poly_print) (r2, ctx), + flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (q, ctx); + TEMPLATE(T, poly_clear) (q2, ctx); + TEMPLATE(T, poly_clear) (r2, ctx); + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Alias a and q */ + for (i = 0; i < 500; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, b, q; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (q, ctx); + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 100), ctx); + TEMPLATE(T, poly_randtest_not_zero) (b, state, + n_randint(state, 100) + 1, ctx); + + TEMPLATE(T, poly_div_basecase) (q, a, b, ctx); + TEMPLATE(T, poly_div_basecase) (a, a, b, ctx); + + result = (TEMPLATE(T, poly_equal) (q, a, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("ctx = "), TEMPLATE(T, ctx_print) (ctx), + flint_printf("\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print) (a, ctx), + flint_printf("\n\n"); + flint_printf("b = "), TEMPLATE(T, poly_print) (b, ctx), + flint_printf("\n\n"); + flint_printf("q = "), TEMPLATE(T, poly_print) (q, ctx), + flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (q, ctx); + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Alias b and q */ + for (i = 0; i < 500; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, b, q; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (q, ctx); + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 100), ctx); + TEMPLATE(T, poly_randtest_not_zero) (b, state, + n_randint(state, 100) + 1, ctx); + + TEMPLATE(T, poly_div_basecase) (q, a, b, ctx); + TEMPLATE(T, poly_div_basecase) (b, a, b, ctx); + + result = (TEMPLATE(T, poly_equal) (q, b, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("ctx = "), TEMPLATE(T, ctx_print) (ctx), + flint_printf("\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print) (a, ctx), + flint_printf("\n\n"); + flint_printf("b = "), TEMPLATE(T, poly_print) (b, ctx), + flint_printf("\n\n"); + flint_printf("q = "), TEMPLATE(T, poly_print) (q, ctx), + flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (q, ctx); + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-div_newton_n_preinv.c b/external/flint-2.4.3/fq_poly_templates/test/t-div_newton_n_preinv.c new file mode 100644 index 0000000..9ad95f9 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-div_newton_n_preinv.c @@ -0,0 +1,230 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2013 Martin Lee + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("div_newton_n_preinv...."); + fflush(stdout); + + /* Check result of divrem */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + TEMPLATE(T, poly_t) a, b, binv, q, r, test; + + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (binv, ctx); + TEMPLATE(T, poly_init) (q, ctx); + TEMPLATE(T, poly_init) (r, ctx); + TEMPLATE(T, poly_init) (test, ctx); + + do + TEMPLATE(T, poly_randtest) (b, state, n_randint(state, 200), ctx); + while (b->length <= 2); + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 200), ctx); + if (a->length > 2 * (b->length) - 3) + TEMPLATE(T, poly_truncate) (a, 2 * (b->length) - 3, ctx); + + TEMPLATE(T, poly_reverse) (binv, b, b->length, ctx); + TEMPLATE(T, poly_inv_series_newton) (binv, binv, b->length, ctx); + TEMPLATE(T, poly_div_newton_n_preinv) (q, a, b, binv, ctx); + TEMPLATE(T, poly_divrem) (test, r, a, b, ctx); + + result = (TEMPLATE(T, poly_equal) (q, test, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + TEMPLATE(T, poly_print) (test, ctx), flint_printf("\n\n"); + TEMPLATE(T, poly_print) (q, ctx), flint_printf("\n\n"); + TEMPLATE(T, poly_print) (a, ctx), flint_printf("\n\n"); + TEMPLATE(T, poly_print) (b, ctx), flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (binv, ctx); + TEMPLATE(T, poly_clear) (q, ctx); + TEMPLATE(T, poly_clear) (r, ctx); + TEMPLATE(T, poly_clear) (test, ctx); + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check aliasing of a and q */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + TEMPLATE(T, poly_t) a, b, binv, q; + + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (binv, ctx); + TEMPLATE(T, poly_init) (q, ctx); + + do + TEMPLATE(T, poly_randtest) (b, state, n_randint(state, 200), ctx); + while (b->length <= 2); + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 200), ctx); + if (a->length > 2 * (b->length) - 3) + TEMPLATE(T, poly_truncate) (a, 2 * (b->length) - 3, ctx); + + TEMPLATE(T, poly_reverse) (binv, b, b->length, ctx); + TEMPLATE(T, poly_inv_series_newton) (binv, binv, b->length, ctx); + + TEMPLATE(T, poly_div_newton_n_preinv) (q, a, b, binv, ctx); + TEMPLATE(T, poly_div_newton_n_preinv) (a, a, b, binv, ctx); + + result = (TEMPLATE(T, poly_equal) (a, q, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + TEMPLATE(T, poly_print) (a, ctx), flint_printf("\n\n"); + TEMPLATE(T, poly_print) (b, ctx), flint_printf("\n\n"); + TEMPLATE(T, poly_print) (q, ctx), flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (binv, ctx); + TEMPLATE(T, poly_clear) (q, ctx); + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check aliasing of b and q */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + TEMPLATE(T, poly_t) a, b, binv, q; + + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (binv, ctx); + TEMPLATE(T, poly_init) (q, ctx); + + do + TEMPLATE(T, poly_randtest) (b, state, n_randint(state, 200), ctx); + while (b->length <= 2); + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 200), ctx); + if (a->length > 2 * (b->length) - 3) + TEMPLATE(T, poly_truncate) (a, 2 * (b->length) - 3, ctx); + + TEMPLATE(T, poly_reverse) (binv, b, b->length, ctx); + TEMPLATE(T, poly_inv_series_newton) (binv, binv, b->length, ctx); + + TEMPLATE(T, poly_div_newton_n_preinv) (q, a, b, binv, ctx); + TEMPLATE(T, poly_div_newton_n_preinv) (b, a, b, binv, ctx); + + result = (TEMPLATE(T, poly_equal) (b, q, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + TEMPLATE(T, poly_print) (a, ctx), flint_printf("\n\n"); + TEMPLATE(T, poly_print) (b, ctx), flint_printf("\n\n"); + TEMPLATE(T, poly_print) (q, ctx), flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (binv, ctx); + TEMPLATE(T, poly_clear) (q, ctx); + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check aliasing of binv and q */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + TEMPLATE(T, poly_t) a, b, binv, q; + + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (binv, ctx); + TEMPLATE(T, poly_init) (q, ctx); + + + do + TEMPLATE(T, poly_randtest) (b, state, n_randint(state, 200), ctx); + while (b->length <= 2); + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 200), ctx); + if (a->length > 2 * (b->length) - 3) + TEMPLATE(T, poly_truncate) (a, 2 * (b->length) - 3, ctx); + + TEMPLATE(T, poly_reverse) (binv, b, b->length, ctx); + TEMPLATE(T, poly_inv_series_newton) (binv, binv, b->length, ctx); + + TEMPLATE(T, poly_div_newton_n_preinv) (q, a, b, binv, ctx); + TEMPLATE(T, poly_div_newton_n_preinv) (binv, a, b, binv, ctx); + + result = (TEMPLATE(T, poly_equal) (binv, q, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + TEMPLATE(T, poly_print) (a, ctx), flint_printf("\n\n"); + TEMPLATE(T, poly_print) (b, ctx), flint_printf("\n\n"); + TEMPLATE(T, poly_print) (binv, ctx), flint_printf("\n\n"); + TEMPLATE(T, poly_print) (q, ctx), flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (binv, ctx); + TEMPLATE(T, poly_clear) (q, ctx); + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-divides.c b/external/flint-2.4.3/fq_poly_templates/test/t-divides.c new file mode 100644 index 0000000..1382b6f --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-divides.c @@ -0,0 +1,172 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include + +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("divides... "); + fflush(stdout); + + /* Check that b divides a b and that the quotient is a */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, c, q; + + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + TEMPLATE(T, poly_init) (q, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 50), ctx); + TEMPLATE(T, poly_randtest_not_zero) (b, state, + n_randint(state, 50) + 1, ctx); + TEMPLATE(T, poly_mul) (c, a, b, ctx); + + result = TEMPLATE(T, poly_divides) (q, c, b, ctx) + && TEMPLATE(T, poly_equal) (q, a, ctx); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + flint_printf("q = "), TEMPLATE(T, poly_print_pretty) (q, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + TEMPLATE(T, poly_clear) (q, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check aliasing of a and q */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, c; + + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 50), ctx); + TEMPLATE(T, poly_randtest_not_zero) (b, state, + n_randint(state, 50) + 1, ctx); + TEMPLATE(T, poly_mul) (c, a, b, ctx); + + result = TEMPLATE(T, poly_divides) (c, c, b, ctx) + && TEMPLATE(T, poly_equal) (c, a, ctx); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check aliasing of b and q */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, c; + + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 50), ctx); + TEMPLATE(T, poly_randtest_not_zero) (b, state, + n_randint(state, 50) + 1, ctx); + TEMPLATE(T, poly_mul) (c, a, b, ctx); + + result = TEMPLATE(T, poly_divides) (b, c, b, ctx) + && TEMPLATE(T, poly_equal) (b, a, ctx); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-divrem_basecase.c b/external/flint-2.4.3/fq_poly_templates/test/t-divrem_basecase.c new file mode 100644 index 0000000..82dfae6 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-divrem_basecase.c @@ -0,0 +1,274 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include + +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("divrem_basecase... "); + fflush(stdout); + + /* Check q*b + r == a */ + for (i = 0; i < 2000; i++) + { + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, c, q, r; + + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + TEMPLATE(T, poly_init) (q, ctx); + TEMPLATE(T, poly_init) (r, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 50), ctx); + TEMPLATE(T, poly_randtest_not_zero) (b, state, + n_randint(state, 50) + 1, ctx); + + TEMPLATE(T, poly_divrem_basecase) (q, r, a, b, ctx); + TEMPLATE(T, poly_mul) (c, q, b, ctx); + TEMPLATE(T, poly_add) (c, c, r, ctx); + + result = (TEMPLATE(T, poly_equal) (a, c, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + flint_printf("q = "), TEMPLATE(T, poly_print_pretty) (q, "X", ctx), + flint_printf("\n"); + flint_printf("r = "), TEMPLATE(T, poly_print_pretty) (r, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + TEMPLATE(T, poly_clear) (q, ctx); + TEMPLATE(T, poly_clear) (r, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check aliasing: a and r */ + for (i = 0; i < 2000; i++) + { + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, q, r; + + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (q, ctx); + TEMPLATE(T, poly_init) (r, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 50), ctx); + TEMPLATE(T, poly_randtest_not_zero) (b, state, + n_randint(state, 50) + 1, ctx); + + TEMPLATE(T, poly_divrem_basecase) (q, r, a, b, ctx); + TEMPLATE(T, poly_divrem_basecase) (q, a, a, b, ctx); + + result = (TEMPLATE(T, poly_equal) (a, r, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("q = "), TEMPLATE(T, poly_print_pretty) (q, "X", ctx), + flint_printf("\n"); + flint_printf("r = "), TEMPLATE(T, poly_print_pretty) (r, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (q, ctx); + TEMPLATE(T, poly_clear) (r, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check aliasing: b and r */ + for (i = 0; i < 2000; i++) + { + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, q, r; + + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (q, ctx); + TEMPLATE(T, poly_init) (r, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 50), ctx); + TEMPLATE(T, poly_randtest_not_zero) (b, state, + n_randint(state, 50) + 1, ctx); + + TEMPLATE(T, poly_divrem_basecase) (q, r, a, b, ctx); + TEMPLATE(T, poly_divrem_basecase) (q, b, a, b, ctx); + + result = (TEMPLATE(T, poly_equal) (b, r, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("q = "), TEMPLATE(T, poly_print_pretty) (q, "X", ctx), + flint_printf("\n"); + flint_printf("r = "), TEMPLATE(T, poly_print_pretty) (r, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (q, ctx); + TEMPLATE(T, poly_clear) (r, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check aliasing: a and q */ + for (i = 0; i < 2000; i++) + { + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, q, r; + + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (q, ctx); + TEMPLATE(T, poly_init) (r, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 50), ctx); + TEMPLATE(T, poly_randtest_not_zero) (b, state, + n_randint(state, 50) + 1, ctx); + + TEMPLATE(T, poly_divrem_basecase) (q, r, a, b, ctx); + TEMPLATE(T, poly_divrem_basecase) (a, r, a, b, ctx); + + result = (TEMPLATE(T, poly_equal) (a, q, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("q = "), TEMPLATE(T, poly_print_pretty) (q, "X", ctx), + flint_printf("\n"); + flint_printf("r = "), TEMPLATE(T, poly_print_pretty) (r, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (q, ctx); + TEMPLATE(T, poly_clear) (r, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check aliasing: b and q */ + for (i = 0; i < 2000; i++) + { + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, q, r; + + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (q, ctx); + TEMPLATE(T, poly_init) (r, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 50), ctx); + TEMPLATE(T, poly_randtest_not_zero) (b, state, + n_randint(state, 50) + 1, ctx); + + TEMPLATE(T, poly_divrem_basecase) (q, r, a, b, ctx); + TEMPLATE(T, poly_divrem_basecase) (b, r, a, b, ctx); + + result = (TEMPLATE(T, poly_equal) (b, q, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("q = "), TEMPLATE(T, poly_print_pretty) (q, "X", ctx), + flint_printf("\n"); + flint_printf("r = "), TEMPLATE(T, poly_print_pretty) (r, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (q, ctx); + TEMPLATE(T, poly_clear) (r, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-divrem_divconquer.c b/external/flint-2.4.3/fq_poly_templates/test/t-divrem_divconquer.c new file mode 100644 index 0000000..88a2ed9 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-divrem_divconquer.c @@ -0,0 +1,179 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2009 William Hart + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("divrem_divconquer...."); + fflush(stdout); + + /* Check q*b + r = a, no aliasing */ + for (i = 0; i < 5000; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, b, q, r, t; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (q, ctx); + TEMPLATE(T, poly_init) (r, ctx); + TEMPLATE(T, poly_init) (t, ctx); + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 100), ctx); + TEMPLATE(T, poly_randtest_not_zero) (b, state, + n_randint(state, 100) + 1, ctx); + + TEMPLATE(T, poly_divrem_divconquer) (q, r, a, b, ctx); + + TEMPLATE(T, poly_mul) (t, q, b, ctx); + TEMPLATE(T, poly_add) (t, t, r, ctx); + + result = (TEMPLATE(T, poly_equal) (a, t, ctx)); + if (!result) + { + flint_printf("FAIL #1:\n"); + flint_printf("a = "), TEMPLATE(T, poly_print) (a, ctx), + flint_printf("\n\n"); + flint_printf("b = "), TEMPLATE(T, poly_print) (b, ctx), + flint_printf("\n\n"); + flint_printf("q = "), TEMPLATE(T, poly_print) (q, ctx), + flint_printf("\n\n"); + flint_printf("r = "), TEMPLATE(T, poly_print) (r, ctx), + flint_printf("\n\n"); + flint_printf("t = "), TEMPLATE(T, poly_print) (t, ctx), + flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (q, ctx); + TEMPLATE(T, poly_clear) (r, ctx); + TEMPLATE(T, poly_clear) (t, ctx); + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Alias a and q, b and r */ + for (i = 0; i < 500; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, b, q, r; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (q, ctx); + TEMPLATE(T, poly_init) (r, ctx); + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 100), ctx); + TEMPLATE(T, poly_randtest_not_zero) (b, state, + n_randint(state, 100) + 1, ctx); + + TEMPLATE(T, poly_divrem_divconquer) (q, r, a, b, ctx); + TEMPLATE(T, poly_divrem_divconquer) (a, b, a, b, ctx); + + result = (TEMPLATE(T, poly_equal) (q, a, ctx) + && TEMPLATE(T, poly_equal) (r, b, ctx)); + if (!result) + { + flint_printf("FAIL #2:\n"); + flint_printf("a = "), TEMPLATE(T, poly_print) (a, ctx), + flint_printf("\n\n"); + flint_printf("b = "), TEMPLATE(T, poly_print) (b, ctx), + flint_printf("\n\n"); + flint_printf("q = "), TEMPLATE(T, poly_print) (q, ctx), + flint_printf("\n\n"); + flint_printf("r = "), TEMPLATE(T, poly_print) (r, ctx), + flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (q, ctx); + TEMPLATE(T, poly_clear) (r, ctx); + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Alias b and q, a and r */ + for (i = 0; i < 500; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, b, q, r; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (q, ctx); + TEMPLATE(T, poly_init) (r, ctx); + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 100), ctx); + TEMPLATE(T, poly_randtest_not_zero) (b, state, + n_randint(state, 100) + 1, ctx); + + TEMPLATE(T, poly_divrem_divconquer) (q, r, a, b, ctx); + TEMPLATE(T, poly_divrem_divconquer) (b, a, a, b, ctx); + + result = (TEMPLATE(T, poly_equal) (q, b, ctx) + && TEMPLATE(T, poly_equal) (r, a, ctx)); + if (!result) + { + flint_printf("FAIL #3:\n"); + flint_printf("a = "), TEMPLATE(T, poly_print) (a, ctx), + flint_printf("\n\n"); + flint_printf("b = "), TEMPLATE(T, poly_print) (b, ctx), + flint_printf("\n\n"); + flint_printf("q = "), TEMPLATE(T, poly_print) (q, ctx), + flint_printf("\n\n"); + flint_printf("r = "), TEMPLATE(T, poly_print) (r, ctx), + flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (q, ctx); + TEMPLATE(T, poly_clear) (r, ctx); + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-divrem_newton_n_preinv.c b/external/flint-2.4.3/fq_poly_templates/test/t-divrem_newton_n_preinv.c new file mode 100644 index 0000000..153405b --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-divrem_newton_n_preinv.c @@ -0,0 +1,381 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2013 Martin Lee + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("divrem_newton_n_preinv...."); + fflush(stdout); + + /* Check result of divrem */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + TEMPLATE(T, poly_t) a, b, binv, q, r, test; + + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (binv, ctx); + TEMPLATE(T, poly_init) (q, ctx); + TEMPLATE(T, poly_init) (r, ctx); + TEMPLATE(T, poly_init) (test, ctx); + + do + TEMPLATE(T, poly_randtest) (b, state, n_randint(state, 50), ctx); + while (b->length <= 2); + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 50), ctx); + if (a->length > 2 * (b->length) - 3) + TEMPLATE(T, poly_truncate) (a, 2 * (b->length) - 3, ctx); + + TEMPLATE(T, poly_reverse) (binv, b, b->length, ctx); + TEMPLATE(T, poly_inv_series_newton) (binv, binv, b->length, ctx); + TEMPLATE(T, poly_divrem_newton_n_preinv) (q, r, a, b, binv, ctx); + TEMPLATE(T, poly_mul) (test, q, b, ctx); + TEMPLATE(T, poly_add) (test, test, r, ctx); + + result = (TEMPLATE(T, poly_equal) (a, test, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + TEMPLATE(T, poly_print) (a, ctx), flint_printf("\n\n"); + TEMPLATE(T, poly_print) (test, ctx), flint_printf("\n\n"); + TEMPLATE(T, poly_print) (q, ctx), flint_printf("\n\n"); + TEMPLATE(T, poly_print) (r, ctx), flint_printf("\n\n"); + TEMPLATE(T, poly_print) (b, ctx), flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (binv, ctx); + TEMPLATE(T, poly_clear) (q, ctx); + TEMPLATE(T, poly_clear) (r, ctx); + TEMPLATE(T, poly_clear) (test, ctx); + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check aliasing of a and q */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + TEMPLATE(T, poly_t) a, b, binv, q, r; + + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (binv, ctx); + TEMPLATE(T, poly_init) (q, ctx); + TEMPLATE(T, poly_init) (r, ctx); + + do + TEMPLATE(T, poly_randtest) (b, state, n_randint(state, 50), ctx); + while (b->length <= 2); + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 50), ctx); + if (a->length > 2 * (b->length) - 3) + TEMPLATE(T, poly_truncate) (a, 2 * (b->length) - 3, ctx); + + TEMPLATE(T, poly_reverse) (binv, b, b->length, ctx); + TEMPLATE(T, poly_inv_series_newton) (binv, binv, b->length, ctx); + + TEMPLATE(T, poly_divrem_newton_n_preinv) (q, r, a, b, binv, ctx); + TEMPLATE(T, poly_divrem_newton_n_preinv) (a, r, a, b, binv, ctx); + + result = (TEMPLATE(T, poly_equal) (a, q, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + TEMPLATE(T, poly_print) (a, ctx), flint_printf("\n\n"); + TEMPLATE(T, poly_print) (b, ctx), flint_printf("\n\n"); + TEMPLATE(T, poly_print) (q, ctx), flint_printf("\n\n"); + TEMPLATE(T, poly_print) (r, ctx), flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (binv, ctx); + TEMPLATE(T, poly_clear) (q, ctx); + TEMPLATE(T, poly_clear) (r, ctx); + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check aliasing of b and q */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + TEMPLATE(T, poly_t) a, b, binv, q, r; + + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (binv, ctx); + TEMPLATE(T, poly_init) (q, ctx); + TEMPLATE(T, poly_init) (r, ctx); + + do + TEMPLATE(T, poly_randtest) (b, state, n_randint(state, 50), ctx); + while (b->length <= 2); + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 50), ctx); + if (a->length > 2 * (b->length) - 3) + TEMPLATE(T, poly_truncate) (a, 2 * (b->length) - 3, ctx); + + TEMPLATE(T, poly_reverse) (binv, b, b->length, ctx); + TEMPLATE(T, poly_inv_series_newton) (binv, binv, b->length, ctx); + + TEMPLATE(T, poly_divrem_newton_n_preinv) (q, r, a, b, binv, ctx); + TEMPLATE(T, poly_divrem_newton_n_preinv) (b, r, a, b, binv, ctx); + + result = (TEMPLATE(T, poly_equal) (b, q, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + TEMPLATE(T, poly_print) (a, ctx), flint_printf("\n\n"); + TEMPLATE(T, poly_print) (b, ctx), flint_printf("\n\n"); + TEMPLATE(T, poly_print) (q, ctx), flint_printf("\n\n"); + TEMPLATE(T, poly_print) (r, ctx), flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (binv, ctx); + TEMPLATE(T, poly_clear) (q, ctx); + TEMPLATE(T, poly_clear) (r, ctx); + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check aliasing of binv and q */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + TEMPLATE(T, poly_t) a, b, binv, q, r; + + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (binv, ctx); + TEMPLATE(T, poly_init) (q, ctx); + TEMPLATE(T, poly_init) (r, ctx); + + do + TEMPLATE(T, poly_randtest) (b, state, n_randint(state, 50), ctx); + while (b->length <= 2); + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 50), ctx); + if (a->length > 2 * (b->length) - 3) + TEMPLATE(T, poly_truncate) (a, 2 * (b->length) - 3, ctx); + + TEMPLATE(T, poly_reverse) (binv, b, b->length, ctx); + TEMPLATE(T, poly_inv_series_newton) (binv, binv, b->length, ctx); + + TEMPLATE(T, poly_divrem_newton_n_preinv) (q, r, a, b, binv, ctx); + TEMPLATE(T, poly_divrem_newton_n_preinv) (binv, r, a, b, binv, ctx); + + result = (TEMPLATE(T, poly_equal) (binv, q, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + TEMPLATE(T, poly_print) (a, ctx), flint_printf("\n\n"); + TEMPLATE(T, poly_print) (b, ctx), flint_printf("\n\n"); + TEMPLATE(T, poly_print) (binv, ctx), flint_printf("\n\n"); + TEMPLATE(T, poly_print) (q, ctx), flint_printf("\n\n"); + TEMPLATE(T, poly_print) (r, ctx), flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (binv, ctx); + TEMPLATE(T, poly_clear) (q, ctx); + TEMPLATE(T, poly_clear) (r, ctx); + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check aliasing of a and r */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + TEMPLATE(T, poly_t) a, b, binv, q, r; + + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (binv, ctx); + TEMPLATE(T, poly_init) (q, ctx); + TEMPLATE(T, poly_init) (r, ctx); + do + TEMPLATE(T, poly_randtest) (b, state, n_randint(state, 50), ctx); + while (b->length <= 2); + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 50), ctx); + if (a->length > 2 * (b->length) - 3) + TEMPLATE(T, poly_truncate) (a, 2 * (b->length) - 3, ctx); + + TEMPLATE(T, poly_reverse) (binv, b, b->length, ctx); + TEMPLATE(T, poly_inv_series_newton) (binv, binv, b->length, ctx); + + TEMPLATE(T, poly_divrem_newton_n_preinv) (q, r, a, b, binv, ctx); + TEMPLATE(T, poly_divrem_newton_n_preinv) (q, a, a, b, binv, ctx); + + result = (TEMPLATE(T, poly_equal) (a, r, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + TEMPLATE(T, poly_print) (a, ctx), flint_printf("\n\n"); + TEMPLATE(T, poly_print) (b, ctx), flint_printf("\n\n"); + TEMPLATE(T, poly_print) (q, ctx), flint_printf("\n\n"); + TEMPLATE(T, poly_print) (r, ctx), flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (binv, ctx); + TEMPLATE(T, poly_clear) (q, ctx); + TEMPLATE(T, poly_clear) (r, ctx); + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check aliasing of b and r */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + TEMPLATE(T, poly_t) a, b, binv, q, r; + + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (binv, ctx); + TEMPLATE(T, poly_init) (q, ctx); + TEMPLATE(T, poly_init) (r, ctx); + + do + TEMPLATE(T, poly_randtest) (b, state, n_randint(state, 50), ctx); + while (b->length <= 2); + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 50), ctx); + if (a->length > 2 * (b->length) - 3) + TEMPLATE(T, poly_truncate) (a, 2 * (b->length) - 3, ctx); + + TEMPLATE(T, poly_reverse) (binv, b, b->length, ctx); + TEMPLATE(T, poly_inv_series_newton) (binv, binv, b->length, ctx); + + TEMPLATE(T, poly_divrem_newton_n_preinv) (q, r, a, b, binv, ctx); + TEMPLATE(T, poly_divrem_newton_n_preinv) (q, b, a, b, binv, ctx); + + result = (TEMPLATE(T, poly_equal) (b, r, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + TEMPLATE(T, poly_print) (a, ctx), flint_printf("\n\n"); + TEMPLATE(T, poly_print) (b, ctx), flint_printf("\n\n"); + TEMPLATE(T, poly_print) (q, ctx), flint_printf("\n\n"); + TEMPLATE(T, poly_print) (r, ctx), flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (binv, ctx); + TEMPLATE(T, poly_clear) (q, ctx); + TEMPLATE(T, poly_clear) (r, ctx); + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check aliasing of binv and r */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + TEMPLATE(T, poly_t) a, b, binv, q, r; + + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (binv, ctx); + TEMPLATE(T, poly_init) (q, ctx); + TEMPLATE(T, poly_init) (r, ctx); + + do + TEMPLATE(T, poly_randtest) (b, state, n_randint(state, 50), ctx); + while (b->length <= 2); + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 50), ctx); + if (a->length > 2 * (b->length) - 3) + TEMPLATE(T, poly_truncate) (a, 2 * (b->length) - 3, ctx); + + TEMPLATE(T, poly_reverse) (binv, b, b->length, ctx); + TEMPLATE(T, poly_inv_series_newton) (binv, binv, b->length, ctx); + + TEMPLATE(T, poly_divrem_newton_n_preinv) (q, r, a, b, binv, ctx); + TEMPLATE(T, poly_divrem_newton_n_preinv) (q, binv, a, b, binv, ctx); + + result = (TEMPLATE(T, poly_equal) (binv, r, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + TEMPLATE(T, poly_print) (a, ctx), flint_printf("\n\n"); + TEMPLATE(T, poly_print) (b, ctx), flint_printf("\n\n"); + TEMPLATE(T, poly_print) (binv, ctx), flint_printf("\n\n"); + TEMPLATE(T, poly_print) (q, ctx), flint_printf("\n\n"); + TEMPLATE(T, poly_print) (r, ctx), flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (binv, ctx); + TEMPLATE(T, poly_clear) (q, ctx); + TEMPLATE(T, poly_clear) (r, ctx); + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-evaluate_fq.c b/external/flint-2.4.3/fq_poly_templates/test/t-evaluate_fq.c new file mode 100644 index 0000000..752e648 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-evaluate_fq.c @@ -0,0 +1,157 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include + +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("evaluate_fq... "); + fflush(stdout); + + /* Check aliasing */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) f; + TEMPLATE(T, t) x, y, z; + + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (f, ctx); + TEMPLATE(T, init) (x, ctx); + TEMPLATE(T, init) (y, ctx); + TEMPLATE(T, init) (z, ctx); + + TEMPLATE(T, poly_randtest) (f, state, len, ctx); + TEMPLATE(T, randtest) (x, state, ctx); + + TEMPLATE(T, set) (z, x, ctx); + TEMPLATE(T, TEMPLATE(poly_evaluate, T)) (y, f, x, ctx); + TEMPLATE(T, TEMPLATE(poly_evaluate, T)) (x, f, x, ctx); + + result = (TEMPLATE(T, equal) (x, y, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("f = "), TEMPLATE(T, poly_print_pretty) (f, "X", ctx), + flint_printf("\n"); + flint_printf("x = "), TEMPLATE(T, print_pretty) (x, ctx), + flint_printf("\n"); + flint_printf("y = "), TEMPLATE(T, print_pretty) (y, ctx), + flint_printf("\n"); + flint_printf("z = "), TEMPLATE(T, print_pretty) (z, ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (f, ctx); + TEMPLATE(T, clear) (x, ctx); + TEMPLATE(T, clear) (y, ctx); + TEMPLATE(T, clear) (z, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check (f + g)(a) == f(a) + g(a) */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) f, g, h; + TEMPLATE(T, t) x, y, z; + + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (f, ctx); + TEMPLATE(T, poly_init) (g, ctx); + TEMPLATE(T, poly_init) (h, ctx); + TEMPLATE(T, init) (x, ctx); + TEMPLATE(T, init) (y, ctx); + TEMPLATE(T, init) (z, ctx); + + TEMPLATE(T, poly_randtest) (f, state, len, ctx); + TEMPLATE(T, poly_randtest) (g, state, len, ctx); + TEMPLATE(T, randtest) (x, state, ctx); + + TEMPLATE(T, poly_add) (h, f, g, ctx); + TEMPLATE(T, TEMPLATE(poly_evaluate, T)) (y, f, x, ctx); + TEMPLATE(T, TEMPLATE(poly_evaluate, T)) (z, g, x, ctx); + TEMPLATE(T, add) (y, y, z, ctx); + TEMPLATE(T, TEMPLATE(poly_evaluate, T)) (z, h, x, ctx); + + result = (TEMPLATE(T, equal) (y, z, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("f = "), TEMPLATE(T, poly_print_pretty) (f, "X", ctx), + flint_printf("\n"); + flint_printf("g = "), TEMPLATE(T, poly_print_pretty) (g, "X", ctx), + flint_printf("\n"); + flint_printf("h = "), TEMPLATE(T, poly_print_pretty) (h, "X", ctx), + flint_printf("\n"); + flint_printf("x = "), TEMPLATE(T, print_pretty) (x, ctx), + flint_printf("\n"); + flint_printf("y = "), TEMPLATE(T, print_pretty) (y, ctx), + flint_printf("\n"); + flint_printf("z = "), TEMPLATE(T, print_pretty) (z, ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (f, ctx); + TEMPLATE(T, poly_clear) (g, ctx); + TEMPLATE(T, poly_clear) (h, ctx); + TEMPLATE(T, clear) (x, ctx); + TEMPLATE(T, clear) (y, ctx); + TEMPLATE(T, clear) (z, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-gcd_euclidean.c b/external/flint-2.4.3/fq_poly_templates/test/t-gcd_euclidean.c new file mode 100644 index 0000000..badd2d7 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-gcd_euclidean.c @@ -0,0 +1,254 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("gcd_euclidean...."); + fflush(stdout); + + /* Check that gcd(a,a) = a (made monic) */ + + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, g; + + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (g, ctx); + + + TEMPLATE(T, poly_randtest_not_zero) (a, state, len, ctx); + TEMPLATE(T, poly_make_monic) (b, a, ctx); + TEMPLATE(T, poly_gcd_euclidean) (g, a, a, ctx); + + result = (TEMPLATE(T, poly_equal) (g, b, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("g = "), TEMPLATE(T, poly_print_pretty) (g, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (g, ctx); + } + + + /* + Find coprime polys, multiply by another poly + and check the GCD is that poly + */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + slong len, j; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, c, g; + + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + TEMPLATE(T, poly_init) (g, ctx); + + + TEMPLATE(T, poly_randtest_not_zero) (a, state, len, ctx); + + + for (j = 0; + (j < 100 * flint_test_multiplier()) + && !TEMPLATE(T, poly_is_one) (g, ctx); j++) + { + TEMPLATE(T, poly_randtest_not_zero) (b, state, len, ctx); + TEMPLATE(T, poly_gcd_euclidean) (g, a, b, ctx); + + + } + + if (!TEMPLATE(T, poly_is_one) (g, ctx)) + { + flint_printf("FAIL:\n"); + flint_printf + ("could not find coprime polynomials after %wd tries\n", + j + 1); + abort(); + } + + for (j = 0; (j < 100 * flint_test_multiplier()) && (c->length < 2); + j++) + TEMPLATE(T, poly_randtest_not_zero) (c, state, len + 2, ctx); + + if (c->length < 2) + { + flint_printf("FAIL:\n"); + flint_printf + ("could not find non-unit polynomial after %wd tries\n", + j + 1); + abort(); + } + + TEMPLATE(T, poly_make_monic) (c, c, ctx); + + TEMPLATE(T, poly_mul) (a, a, c, ctx); + TEMPLATE(T, poly_mul) (b, b, c, ctx); + + TEMPLATE(T, poly_gcd_euclidean) (g, a, b, ctx); + + result = (TEMPLATE(T, poly_equal) (g, c, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + flint_printf("g = "), TEMPLATE(T, poly_print_pretty) (g, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + TEMPLATE(T, poly_clear) (g, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check aliasing of a and g */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, g; + + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (g, ctx); + + TEMPLATE(T, poly_randtest_not_zero) (a, state, len, ctx); + TEMPLATE(T, poly_randtest_not_zero) (b, state, len, ctx); + + TEMPLATE(T, poly_gcd_euclidean) (g, a, b, ctx); + TEMPLATE(T, poly_gcd_euclidean) (a, a, b, ctx); + + result = (TEMPLATE(T, poly_equal) (g, a, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("g = "), TEMPLATE(T, poly_print_pretty) (g, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (g, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + + /* Check aliasing of b and g */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, g; + + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (g, ctx); + + TEMPLATE(T, poly_randtest_not_zero) (a, state, len, ctx); + TEMPLATE(T, poly_randtest_not_zero) (b, state, len, ctx); + + TEMPLATE(T, poly_gcd_euclidean) (g, a, b, ctx); + TEMPLATE(T, poly_gcd_euclidean) (b, a, b, ctx); + + result = (TEMPLATE(T, poly_equal) (g, b, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("g = "), TEMPLATE(T, poly_print_pretty) (g, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (g, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-get_str.c b/external/flint-2.4.3/fq_poly_templates/test/t-get_str.c new file mode 100644 index 0000000..798f8ae --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-get_str.c @@ -0,0 +1,66 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +int +main(void) +{ + int i, len; + char *str; + TEMPLATE(T, poly_t) a; + TEMPLATE(T, ctx_t) ctx; + FLINT_TEST_INIT(state); + + flint_printf("get_str...."); + fflush(stdout); + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + for (len = 0; len < 100; len++) + for (i = 0; i < 10; i++) + { + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + str = TEMPLATE(T, poly_get_str) (a, ctx); + /* flint_printf("\n\n"); */ + /* TEMPLATE(T, poly_print)(a, ctx); */ + /* flint_printf("\n%s\n", str); */ + flint_free(str); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, ctx_clear) (ctx); + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-get_str_pretty.c b/external/flint-2.4.3/fq_poly_templates/test/t-get_str_pretty.c new file mode 100644 index 0000000..45a06b1 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-get_str_pretty.c @@ -0,0 +1,66 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +int +main(void) +{ + int i, len; + char *str; + TEMPLATE(T, poly_t) a; + TEMPLATE(T, ctx_t) ctx; + FLINT_TEST_INIT(state); + + flint_printf("get_str_pretty...."); + fflush(stdout); + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + for (len = 0; len < 100; len++) + for (i = 0; i < 10; i++) + { + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + str = TEMPLATE(T, poly_get_str_pretty) (a, "x", ctx); + /* flint_printf("\n\n"); */ + /* TEMPLATE(T, poly_print_pretty)(a, "x", ctx); */ + /* flint_printf("\n%s\n", str); */ + flint_free(str); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, ctx_clear) (ctx); + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-hamming_weight.c b/external/flint-2.4.3/fq_poly_templates/test/t-hamming_weight.c new file mode 100644 index 0000000..4125651 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-hamming_weight.c @@ -0,0 +1,135 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include + +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("hamming_weight... "); + fflush(stdout); + + /* Check consistency */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + slong w1, w2; + TEMPLATE(T, poly_t) a, b; + + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + TEMPLATE(T, poly_set) (b, a, ctx); + + w1 = TEMPLATE(T, poly_hamming_weight) (a, ctx); + w2 = TEMPLATE(T, poly_hamming_weight) (b, ctx); + + result = (w1 == w2); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("w1 = %wd \n w2 = %wd \n", w1, w2); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check that wt(a+b) \leq wt(a) + wt(b) */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + slong w1, w2, wsum; + TEMPLATE(T, poly_t) a, b, c; + + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + TEMPLATE(T, poly_randtest) (b, state, len, ctx); + TEMPLATE(T, poly_add) (c, a, b, ctx); + + w1 = TEMPLATE(T, poly_hamming_weight) (a, ctx); + w2 = TEMPLATE(T, poly_hamming_weight) (b, ctx); + wsum = TEMPLATE(T, poly_hamming_weight) (c, ctx); + + result = (wsum <= w1 + w2); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("w1 = %wd \n w2 = %wd \n wsum = %wd", w1, w2, wsum); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-inflate.c b/external/flint-2.4.3/fq_poly_templates/test/t-inflate.c new file mode 100644 index 0000000..3259d7f --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-inflate.c @@ -0,0 +1,108 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +int +main(void) +{ + int iter; + FLINT_TEST_INIT(state); + + flint_printf("inflate...."); + fflush(stdout); + + for (iter = 0; iter < 100 * flint_test_multiplier(); iter++) + { + TEMPLATE(T, poly_t) poly1, poly2, poly3, xp; + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, t) one; + ulong inflation; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (poly1, ctx); + TEMPLATE(T, poly_init) (poly2, ctx); + TEMPLATE(T, poly_init) (poly3, ctx); + TEMPLATE(T, poly_init) (xp, ctx); + + TEMPLATE(T, poly_randtest) (poly1, state, n_randint(state, 20), ctx); + inflation = n_randint(state, 10); + + TEMPLATE(T, poly_inflate) (poly2, poly1, inflation, ctx); + + TEMPLATE(T, init) (one, ctx); + TEMPLATE(T, one) (one, ctx); + TEMPLATE(T, poly_set_coeff) (xp, inflation, one, ctx); + TEMPLATE(T, poly_compose) (poly3, poly1, xp, ctx); + TEMPLATE(T, clear) (one, ctx); + + if (!TEMPLATE(T, poly_equal) (poly2, poly3, ctx)) + { + flint_printf("FAIL: not equal to compose (inflation = %wu)\n", + inflation); + flint_printf("poly1:\n"); + TEMPLATE(T, poly_print) (poly1, ctx); + flint_printf("\n\n"); + flint_printf("poly2:\n"); + TEMPLATE(T, poly_print) (poly2, ctx); + flint_printf("\n\n"); + flint_printf("poly3:\n"); + TEMPLATE(T, poly_print) (poly3, ctx); + flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_inflate) (poly1, poly1, inflation, ctx); + if (!TEMPLATE(T, poly_equal) (poly1, poly2, ctx)) + { + flint_printf("FAIL: aliasing (inflation = %wu)\n", inflation); + flint_printf("poly1:\n"); + TEMPLATE(T, poly_print) (poly1, ctx); + flint_printf("\n\n"); + flint_printf("poly2:\n"); + TEMPLATE(T, poly_print) (poly2, ctx); + flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (poly1, ctx); + TEMPLATE(T, poly_clear) (poly2, ctx); + TEMPLATE(T, poly_clear) (poly3, ctx); + TEMPLATE(T, poly_clear) (xp, ctx); + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-inv_series_newton.c b/external/flint-2.4.3/fq_poly_templates/test/t-inv_series_newton.c new file mode 100644 index 0000000..56d4b31 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-inv_series_newton.c @@ -0,0 +1,93 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("inv_series_newton...."); + fflush(stdout); + + /* Check Q^{-1} * Q is congruent 1 mod t^n */ + for (i = 0; i < 1000; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, b, c, one; + slong n = n_randint(state, 80) + 1; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + TEMPLATE(T, poly_init) (one, ctx); + + TEMPLATE(T, poly_randtest_not_zero) (a, state, + n_randint(state, 80) + 1, ctx); + TEMPLATE(T, randtest_not_zero) (a->coeffs, state, ctx); + TEMPLATE(T, poly_one) (one, ctx); + + TEMPLATE(T, poly_inv_series_newton) (b, a, n, ctx); + TEMPLATE(T, poly_mullow) (c, a, b, n, ctx); + + result = (TEMPLATE(T, poly_equal) (c, one, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), TEMPLATE(T, poly_print) (a, ctx), + flint_printf("\n\n"); + flint_printf("b = "), TEMPLATE(T, poly_print) (b, ctx), + flint_printf("\n\n"); + flint_printf("c = "), TEMPLATE(T, poly_print) (c, ctx), + flint_printf("\n\n"); + flint_printf("ctx = "), TEMPLATE(T, ctx_print) (ctx), + flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + TEMPLATE(T, poly_clear) (one, ctx); + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} + + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-make_monic.c b/external/flint-2.4.3/fq_poly_templates/test/t-make_monic.c new file mode 100644 index 0000000..d123632 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-make_monic.c @@ -0,0 +1,117 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("make_monic...."); + fflush(stdout); + + /* test aliasing */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b; + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + + TEMPLATE(T, poly_randtest_not_zero) (a, state, len, ctx); + TEMPLATE(T, poly_make_monic) (b, a, ctx); + TEMPLATE(T, poly_make_monic) (a, a, ctx); + result = TEMPLATE(T, poly_equal) (a, b, ctx); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, ctx_clear) (ctx); + } + + + + /* Check new leading coeff = 1 */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a; + + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + + TEMPLATE(T, poly_randtest_not_zero) (a, state, len, ctx); + TEMPLATE(T, poly_make_monic) (a, a, ctx); + + result = TEMPLATE(T, is_one) (TEMPLATE(T, poly_lead) (a, ctx), ctx); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("lead ="), TEMPLATE(T, + print_pretty) (TEMPLATE(T, + poly_lead) + (a, ctx), ctx), + flint_printf("\n"); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, ctx_clear) (ctx); + + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-mul.c b/external/flint-2.4.3/fq_poly_templates/test/t-mul.c new file mode 100644 index 0000000..474ad37 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-mul.c @@ -0,0 +1,272 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include + +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("mul... "); + fflush(stdout); + + /* Check aliasing: a = a * b */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, c; + + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + TEMPLATE(T, poly_randtest) (b, state, len, ctx); + + TEMPLATE(T, poly_mul) (c, a, b, ctx); + TEMPLATE(T, poly_mul) (a, a, b, ctx); + + result = (TEMPLATE(T, poly_equal) (a, c, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check aliasing: b = a * b */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, c; + + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + TEMPLATE(T, poly_randtest) (b, state, len, ctx); + + TEMPLATE(T, poly_mul) (c, a, b, ctx); + TEMPLATE(T, poly_mul) (b, a, b, ctx); + + result = (TEMPLATE(T, poly_equal) (b, c, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check aliasing: a = a * a */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, c; + + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (c, ctx); + + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + + TEMPLATE(T, poly_mul) (c, a, a, ctx); + TEMPLATE(T, poly_mul) (a, a, a, ctx); + + result = (TEMPLATE(T, poly_equal) (a, c, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check that a * b == b * a */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, c, e; + + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + TEMPLATE(T, poly_init) (e, ctx); + + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + TEMPLATE(T, poly_randtest) (b, state, len, ctx); + + TEMPLATE(T, poly_mul) (c, a, b, ctx); + TEMPLATE(T, poly_mul) (e, b, a, ctx); + + result = (TEMPLATE(T, poly_equal) (e, c, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + flint_printf("e = "), TEMPLATE(T, poly_print_pretty) (e, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + TEMPLATE(T, poly_clear) (e, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check that (b*c)+(b*d) = b*(c+d) */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a1, a2, b, c, d; + + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a1, ctx); + TEMPLATE(T, poly_init) (a2, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + TEMPLATE(T, poly_init) (d, ctx); + + TEMPLATE(T, poly_randtest) (b, state, len, ctx); + TEMPLATE(T, poly_randtest) (c, state, len, ctx); + TEMPLATE(T, poly_randtest) (d, state, len, ctx); + + TEMPLATE(T, poly_mul) (a1, b, c, ctx); + TEMPLATE(T, poly_mul) (a2, b, d, ctx); + TEMPLATE(T, poly_add) (a1, a1, a2, ctx); + + TEMPLATE(T, poly_add) (c, c, d, ctx); + TEMPLATE(T, poly_mul) (a2, b, c, ctx); + + result = (TEMPLATE(T, poly_equal) (a1, a2, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a1 = "), TEMPLATE(T, poly_print_pretty) (a1, "X", + ctx), + flint_printf("\n"); + flint_printf("a2 = "), TEMPLATE(T, poly_print_pretty) (a2, "X", + ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", + ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", + ctx), + flint_printf("\n"); + flint_printf("d = "), TEMPLATE(T, poly_print_pretty) (d, "X", + ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a1, ctx); + TEMPLATE(T, poly_clear) (a2, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + TEMPLATE(T, poly_clear) (d, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-mul_KS.c b/external/flint-2.4.3/fq_poly_templates/test/t-mul_KS.c new file mode 100644 index 0000000..eb14393 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-mul_KS.c @@ -0,0 +1,272 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include + +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("mul_KS... "); + fflush(stdout); + + /* Check aliasing: a = a * b */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, c; + + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + TEMPLATE(T, poly_randtest) (b, state, len, ctx); + + TEMPLATE(T, poly_mul_KS) (c, a, b, ctx); + TEMPLATE(T, poly_mul_KS) (a, a, b, ctx); + + result = (TEMPLATE(T, poly_equal) (a, c, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check aliasing: b = a * b */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, c; + + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + TEMPLATE(T, poly_randtest) (b, state, len, ctx); + + TEMPLATE(T, poly_mul_KS) (c, a, b, ctx); + TEMPLATE(T, poly_mul_KS) (b, a, b, ctx); + + result = (TEMPLATE(T, poly_equal) (b, c, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check aliasing: a = a * a */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, c; + + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (c, ctx); + + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + + TEMPLATE(T, poly_mul_KS) (c, a, a, ctx); + TEMPLATE(T, poly_mul_KS) (a, a, a, ctx); + + result = (TEMPLATE(T, poly_equal) (a, c, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check that a * b == b * a */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, c, e; + + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + TEMPLATE(T, poly_init) (e, ctx); + + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + TEMPLATE(T, poly_randtest) (b, state, len, ctx); + + TEMPLATE(T, poly_mul_KS) (c, a, b, ctx); + TEMPLATE(T, poly_mul_KS) (e, b, a, ctx); + + result = (TEMPLATE(T, poly_equal) (e, c, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + flint_printf("e = "), TEMPLATE(T, poly_print_pretty) (e, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + TEMPLATE(T, poly_clear) (e, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check that (b*c)+(b*d) = b*(c+d) */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a1, a2, b, c, d; + + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a1, ctx); + TEMPLATE(T, poly_init) (a2, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + TEMPLATE(T, poly_init) (d, ctx); + + TEMPLATE(T, poly_randtest) (b, state, len, ctx); + TEMPLATE(T, poly_randtest) (c, state, len, ctx); + TEMPLATE(T, poly_randtest) (d, state, len, ctx); + + TEMPLATE(T, poly_mul_KS) (a1, b, c, ctx); + TEMPLATE(T, poly_mul_KS) (a2, b, d, ctx); + TEMPLATE(T, poly_add) (a1, a1, a2, ctx); + + TEMPLATE(T, poly_add) (c, c, d, ctx); + TEMPLATE(T, poly_mul_KS) (a2, b, c, ctx); + + result = (TEMPLATE(T, poly_equal) (a1, a2, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a1 = "), TEMPLATE(T, poly_print_pretty) (a1, "X", + ctx), + flint_printf("\n"); + flint_printf("a2 = "), TEMPLATE(T, poly_print_pretty) (a2, "X", + ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", + ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", + ctx), + flint_printf("\n"); + flint_printf("d = "), TEMPLATE(T, poly_print_pretty) (d, "X", + ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a1, ctx); + TEMPLATE(T, poly_clear) (a2, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + TEMPLATE(T, poly_clear) (d, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-mul_classical.c b/external/flint-2.4.3/fq_poly_templates/test/t-mul_classical.c new file mode 100644 index 0000000..329c2a1 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-mul_classical.c @@ -0,0 +1,272 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include + +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("mul_classical... "); + fflush(stdout); + + /* Check aliasing: a = a * b */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, c; + + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + TEMPLATE(T, poly_randtest) (b, state, len, ctx); + + TEMPLATE(T, poly_mul_classical) (c, a, b, ctx); + TEMPLATE(T, poly_mul_classical) (a, a, b, ctx); + + result = (TEMPLATE(T, poly_equal) (a, c, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check aliasing: b = a * b */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, c; + + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + TEMPLATE(T, poly_randtest) (b, state, len, ctx); + + TEMPLATE(T, poly_mul_classical) (c, a, b, ctx); + TEMPLATE(T, poly_mul_classical) (b, a, b, ctx); + + result = (TEMPLATE(T, poly_equal) (b, c, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check aliasing: a = a * a */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, c; + + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (c, ctx); + + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + + TEMPLATE(T, poly_mul_classical) (c, a, a, ctx); + TEMPLATE(T, poly_mul_classical) (a, a, a, ctx); + + result = (TEMPLATE(T, poly_equal) (a, c, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check that a * b == b * a */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, c, e; + + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + TEMPLATE(T, poly_init) (e, ctx); + + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + TEMPLATE(T, poly_randtest) (b, state, len, ctx); + + TEMPLATE(T, poly_mul_classical) (c, a, b, ctx); + TEMPLATE(T, poly_mul_classical) (e, b, a, ctx); + + result = (TEMPLATE(T, poly_equal) (e, c, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + flint_printf("e = "), TEMPLATE(T, poly_print_pretty) (e, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + TEMPLATE(T, poly_clear) (e, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check that (b*c)+(b*d) = b*(c+d) */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a1, a2, b, c, d; + + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a1, ctx); + TEMPLATE(T, poly_init) (a2, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + TEMPLATE(T, poly_init) (d, ctx); + + TEMPLATE(T, poly_randtest) (b, state, len, ctx); + TEMPLATE(T, poly_randtest) (c, state, len, ctx); + TEMPLATE(T, poly_randtest) (d, state, len, ctx); + + TEMPLATE(T, poly_mul_classical) (a1, b, c, ctx); + TEMPLATE(T, poly_mul_classical) (a2, b, d, ctx); + TEMPLATE(T, poly_add) (a1, a1, a2, ctx); + + TEMPLATE(T, poly_add) (c, c, d, ctx); + TEMPLATE(T, poly_mul_classical) (a2, b, c, ctx); + + result = (TEMPLATE(T, poly_equal) (a1, a2, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a1 = "), TEMPLATE(T, poly_print_pretty) (a1, "X", + ctx), + flint_printf("\n"); + flint_printf("a2 = "), TEMPLATE(T, poly_print_pretty) (a2, "X", + ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", + ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", + ctx), + flint_printf("\n"); + flint_printf("d = "), TEMPLATE(T, poly_print_pretty) (d, "X", + ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a1, ctx); + TEMPLATE(T, poly_clear) (a2, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + TEMPLATE(T, poly_clear) (d, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-mul_reorder.c b/external/flint-2.4.3/fq_poly_templates/test/t-mul_reorder.c new file mode 100644 index 0000000..034f1e1 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-mul_reorder.c @@ -0,0 +1,272 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include + +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("mul_reorder... "); + fflush(stdout); + + /* Check aliasing: a = a * b */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, c; + + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + TEMPLATE(T, poly_randtest) (b, state, len, ctx); + + TEMPLATE(T, poly_mul_reorder) (c, a, b, ctx); + TEMPLATE(T, poly_mul_reorder) (a, a, b, ctx); + + result = (TEMPLATE(T, poly_equal) (a, c, ctx)); + if (!result) + { + flint_printf("FAIL (alias a = a * b):\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check aliasing: b = a * b */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, c; + + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + TEMPLATE(T, poly_randtest) (b, state, len, ctx); + + TEMPLATE(T, poly_mul_reorder) (c, a, b, ctx); + TEMPLATE(T, poly_mul_reorder) (b, a, b, ctx); + + result = (TEMPLATE(T, poly_equal) (b, c, ctx)); + if (!result) + { + flint_printf("FAIL (b = a * b):\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check aliasing: a = a * a */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, c; + + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (c, ctx); + + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + + TEMPLATE(T, poly_mul_reorder) (c, a, a, ctx); + TEMPLATE(T, poly_mul_reorder) (a, a, a, ctx); + + result = (TEMPLATE(T, poly_equal) (a, c, ctx)); + if (!result) + { + flint_printf("FAIL (alias a = a * a):\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check that a * b == b * a */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, c, e; + + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + TEMPLATE(T, poly_init) (e, ctx); + + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + TEMPLATE(T, poly_randtest) (b, state, len, ctx); + + TEMPLATE(T, poly_mul_reorder) (c, a, b, ctx); + TEMPLATE(T, poly_mul_reorder) (e, b, a, ctx); + + result = (TEMPLATE(T, poly_equal) (e, c, ctx)); + if (!result) + { + flint_printf("FAIL (a * b == b * a):\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + flint_printf("e = "), TEMPLATE(T, poly_print_pretty) (e, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + TEMPLATE(T, poly_clear) (e, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check that (b*c)+(b*d) = b*(c+d) */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a1, a2, b, c, d; + + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a1, ctx); + TEMPLATE(T, poly_init) (a2, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + TEMPLATE(T, poly_init) (d, ctx); + + TEMPLATE(T, poly_randtest) (b, state, len, ctx); + TEMPLATE(T, poly_randtest) (c, state, len, ctx); + TEMPLATE(T, poly_randtest) (d, state, len, ctx); + + TEMPLATE(T, poly_mul_reorder) (a1, b, c, ctx); + TEMPLATE(T, poly_mul_reorder) (a2, b, d, ctx); + TEMPLATE(T, poly_add) (a1, a1, a2, ctx); + + TEMPLATE(T, poly_add) (c, c, d, ctx); + TEMPLATE(T, poly_mul_reorder) (a2, b, c, ctx); + + result = (TEMPLATE(T, poly_equal) (a1, a2, ctx)); + if (!result) + { + flint_printf("FAIL ((b*c)+(b*d) == b*(c+d)):\n\n"); + flint_printf("a1 = "), TEMPLATE(T, poly_print_pretty) (a1, "X", + ctx), + flint_printf("\n"); + flint_printf("a2 = "), TEMPLATE(T, poly_print_pretty) (a2, "X", + ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", + ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", + ctx), + flint_printf("\n"); + flint_printf("d = "), TEMPLATE(T, poly_print_pretty) (d, "X", + ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a1, ctx); + TEMPLATE(T, poly_clear) (a2, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + TEMPLATE(T, poly_clear) (d, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-mullow.c b/external/flint-2.4.3/fq_poly_templates/test/t-mullow.c new file mode 100644 index 0000000..9ba4cd3 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-mullow.c @@ -0,0 +1,100 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include + +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("mullow... "); + fflush(stdout); + + /* Compare with truncated product of a and b */ + for (i = 0; i < 2000; i++) + { + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, c, d; + slong n; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + TEMPLATE(T, poly_init) (d, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 100), ctx); + TEMPLATE(T, poly_randtest) (b, state, n_randint(state, 100), ctx); + n = n_randint(state, 100); + + TEMPLATE(T, poly_mullow) (c, a, b, n, ctx); + TEMPLATE(T, poly_mul) (d, a, b, ctx); + TEMPLATE(T, poly_truncate) (d, n, ctx); + + result = (TEMPLATE(T, poly_equal) (c, d, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + flint_printf("d = "), TEMPLATE(T, poly_print_pretty) (d, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + TEMPLATE(T, poly_clear) (d, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-mullow_KS.c b/external/flint-2.4.3/fq_poly_templates/test/t-mullow_KS.c new file mode 100644 index 0000000..3f683fd --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-mullow_KS.c @@ -0,0 +1,100 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include + +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("mullow_KS... "); + fflush(stdout); + + /* Compare with truncated product of a and b */ + for (i = 0; i < 2000; i++) + { + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, c, d; + slong n; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + TEMPLATE(T, poly_init) (d, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 100), ctx); + TEMPLATE(T, poly_randtest) (b, state, n_randint(state, 100), ctx); + n = n_randint(state, 100); + + TEMPLATE(T, poly_mullow_KS) (c, a, b, n, ctx); + TEMPLATE(T, poly_mul) (d, a, b, ctx); + TEMPLATE(T, poly_truncate) (d, n, ctx); + + result = (TEMPLATE(T, poly_equal) (c, d, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + flint_printf("d = "), TEMPLATE(T, poly_print_pretty) (d, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + TEMPLATE(T, poly_clear) (d, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-mullow_classical.c b/external/flint-2.4.3/fq_poly_templates/test/t-mullow_classical.c new file mode 100644 index 0000000..b2fa94a --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-mullow_classical.c @@ -0,0 +1,100 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include + +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("mullow_classical... "); + fflush(stdout); + + /* Compare with truncated product of a and b */ + for (i = 0; i < 2000; i++) + { + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, c, d; + slong n; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + TEMPLATE(T, poly_init) (d, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 50), ctx); + TEMPLATE(T, poly_randtest) (b, state, n_randint(state, 50), ctx); + n = n_randint(state, 50); + + TEMPLATE(T, poly_mullow_classical) (c, a, b, n, ctx); + TEMPLATE(T, poly_mul) (d, a, b, ctx); + TEMPLATE(T, poly_truncate) (d, n, ctx); + + result = (TEMPLATE(T, poly_equal) (c, d, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + flint_printf("d = "), TEMPLATE(T, poly_print_pretty) (d, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + TEMPLATE(T, poly_clear) (d, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-mulmod.c b/external/flint-2.4.3/fq_poly_templates/test/t-mulmod.c new file mode 100644 index 0000000..e091bfe --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-mulmod.c @@ -0,0 +1,238 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011, 2010 Sebastian Pancratz + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "ulong_extras.h" +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("mulmod...."); + fflush(stdout); + + /* Check aliasing of res and a */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, b, res, f; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (f, ctx); + TEMPLATE(T, poly_init) (res, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 50), ctx); + TEMPLATE(T, poly_randtest) (b, state, n_randint(state, 50), ctx); + TEMPLATE(T, poly_randtest_not_zero) (f, state, + n_randint(state, 50) + 1, ctx); + + TEMPLATE(T, poly_mulmod) (res, a, b, f, ctx); + TEMPLATE(T, poly_mulmod) (a, a, b, f, ctx); + + result = (TEMPLATE(T, poly_equal) (res, a, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx), flint_printf("\n\n"); + flint_printf("b:\n"); + TEMPLATE(T, poly_print) (b, ctx), flint_printf("\n\n"); + flint_printf("f:\n"); + TEMPLATE(T, poly_print) (f, ctx), flint_printf("\n\n"); + flint_printf("res:\n"); + TEMPLATE(T, poly_print) (res, ctx), flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (f, ctx); + TEMPLATE(T, poly_clear) (res, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check aliasing of res and b */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, b, f, res; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (f, ctx); + TEMPLATE(T, poly_init) (res, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 50), ctx); + TEMPLATE(T, poly_randtest) (b, state, n_randint(state, 50), ctx); + TEMPLATE(T, poly_randtest_not_zero) (f, state, + n_randint(state, 50) + 1, ctx); + + TEMPLATE(T, poly_mulmod) (res, a, b, f, ctx); + TEMPLATE(T, poly_mulmod) (b, a, b, f, ctx); + + result = (TEMPLATE(T, poly_equal) (res, b, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx), flint_printf("\n\n"); + flint_printf("b:\n"); + TEMPLATE(T, poly_print) (b, ctx), flint_printf("\n\n"); + flint_printf("f:\n"); + TEMPLATE(T, poly_print) (f, ctx), flint_printf("\n\n"); + flint_printf("res:\n"); + TEMPLATE(T, poly_print) (res, ctx), flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (f, ctx); + TEMPLATE(T, poly_clear) (res, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check aliasing of res and f */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, b, f, res; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (f, ctx); + TEMPLATE(T, poly_init) (res, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 50), ctx); + TEMPLATE(T, poly_randtest) (b, state, n_randint(state, 50), ctx); + TEMPLATE(T, poly_randtest_not_zero) (f, state, + n_randint(state, 50) + 1, ctx); + + TEMPLATE(T, poly_mulmod) (res, a, b, f, ctx); + TEMPLATE(T, poly_mulmod) (f, a, b, f, ctx); + + result = (TEMPLATE(T, poly_equal) (res, f, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx), flint_printf("\n\n"); + flint_printf("b:\n"); + TEMPLATE(T, poly_print) (b, ctx), flint_printf("\n\n"); + flint_printf("f:\n"); + TEMPLATE(T, poly_print) (f, ctx), flint_printf("\n\n"); + flint_printf("res:\n"); + TEMPLATE(T, poly_print) (res, ctx), flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (f, ctx); + TEMPLATE(T, poly_clear) (res, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* No aliasing */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, b, res1, res2, t, f; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (f, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 50), ctx); + TEMPLATE(T, poly_randtest) (b, state, n_randint(state, 50), ctx); + TEMPLATE(T, poly_randtest_not_zero) (f, state, + n_randint(state, 50) + 1, ctx); + + TEMPLATE(T, poly_init) (res1, ctx); + TEMPLATE(T, poly_init) (res2, ctx); + TEMPLATE(T, poly_init) (t, ctx); + TEMPLATE(T, poly_mulmod) (res1, a, b, f, ctx); + TEMPLATE(T, poly_mul) (res2, a, b, ctx); + TEMPLATE(T, poly_divrem) (t, res2, res2, f, ctx); + + result = (TEMPLATE(T, poly_equal) (res1, res2, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx), flint_printf("\n\n"); + flint_printf("b:\n"); + TEMPLATE(T, poly_print) (b, ctx), flint_printf("\n\n"); + flint_printf("f:\n"); + TEMPLATE(T, poly_print) (f, ctx), flint_printf("\n\n"); + flint_printf("res1:\n"); + TEMPLATE(T, poly_print) (res1, ctx), flint_printf("\n\n"); + flint_printf("res2:\n"); + TEMPLATE(T, poly_print) (res2, ctx), flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (f, ctx); + TEMPLATE(T, poly_clear) (res1, ctx); + TEMPLATE(T, poly_clear) (res2, ctx); + TEMPLATE(T, poly_clear) (t, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-mulmod_preinv.c b/external/flint-2.4.3/fq_poly_templates/test/t-mulmod_preinv.c new file mode 100644 index 0000000..41c77de --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-mulmod_preinv.c @@ -0,0 +1,338 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + Copyright (C) 2013 Martin Lee + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("mulmod_preinv...."); + fflush(stdout); + + /* Aliasing res and a */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + TEMPLATE(T, poly_t) a, b, res, t, f, finv; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (f, ctx); + TEMPLATE(T, poly_init) (finv, ctx); + TEMPLATE(T, poly_init) (res, ctx); + TEMPLATE(T, poly_init) (t, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 50), ctx); + TEMPLATE(T, poly_randtest) (b, state, n_randint(state, 50), ctx); + do + { + TEMPLATE(T, poly_randtest) (f, state, n_randint(state, 50), ctx); + } while (TEMPLATE(T, poly_is_zero) (f, ctx)); + if (a->length >= f->length) + TEMPLATE(T, poly_rem) (a, a, f, ctx); + if (b->length >= f->length) + TEMPLATE(T, poly_rem) (b, b, f, ctx); + + TEMPLATE(T, poly_reverse) (finv, f, f->length, ctx); + TEMPLATE(T, poly_inv_series_newton) (finv, finv, f->length, ctx); + + TEMPLATE(T, poly_mulmod_preinv) (res, a, b, f, finv, ctx); + TEMPLATE(T, poly_mulmod_preinv) (a, a, b, f, finv, ctx); + + result = (TEMPLATE(T, poly_equal) (res, a, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx), flint_printf("\n\n"); + flint_printf("b:\n"); + TEMPLATE(T, poly_print) (b, ctx), flint_printf("\n\n"); + flint_printf("f:\n"); + TEMPLATE(T, poly_print) (f, ctx), flint_printf("\n\n"); + flint_printf("res1:\n"); + TEMPLATE(T, poly_print) (res, ctx), flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (f, ctx); + TEMPLATE(T, poly_clear) (finv, ctx); + TEMPLATE(T, poly_clear) (res, ctx); + TEMPLATE(T, poly_clear) (t, ctx); + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Aliasing res and b */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + TEMPLATE(T, poly_t) a, b, res, t, f, finv; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (f, ctx); + TEMPLATE(T, poly_init) (finv, ctx); + TEMPLATE(T, poly_init) (res, ctx); + TEMPLATE(T, poly_init) (t, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 50), ctx); + TEMPLATE(T, poly_randtest) (b, state, n_randint(state, 50), ctx); + do + { + TEMPLATE(T, poly_randtest) (f, state, n_randint(state, 50), ctx); + } while (TEMPLATE(T, poly_is_zero) (f, ctx)); + if (a->length >= f->length) + TEMPLATE(T, poly_rem) (a, a, f, ctx); + if (b->length >= f->length) + TEMPLATE(T, poly_rem) (b, b, f, ctx); + + TEMPLATE(T, poly_reverse) (finv, f, f->length, ctx); + TEMPLATE(T, poly_inv_series_newton) (finv, finv, f->length, ctx); + + TEMPLATE(T, poly_mulmod_preinv) (res, a, b, f, finv, ctx); + TEMPLATE(T, poly_mulmod_preinv) (b, a, b, f, finv, ctx); + + result = (TEMPLATE(T, poly_equal) (res, b, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx), flint_printf("\n\n"); + flint_printf("b:\n"); + TEMPLATE(T, poly_print) (b, ctx), flint_printf("\n\n"); + flint_printf("f:\n"); + TEMPLATE(T, poly_print) (f, ctx), flint_printf("\n\n"); + flint_printf("res1:\n"); + TEMPLATE(T, poly_print) (res, ctx), flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (f, ctx); + TEMPLATE(T, poly_clear) (finv, ctx); + TEMPLATE(T, poly_clear) (res, ctx); + TEMPLATE(T, poly_clear) (t, ctx); + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Aliasing res and f */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + TEMPLATE(T, poly_t) a, b, res, t, f, finv; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (f, ctx); + TEMPLATE(T, poly_init) (finv, ctx); + TEMPLATE(T, poly_init) (res, ctx); + TEMPLATE(T, poly_init) (t, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 50), ctx); + TEMPLATE(T, poly_randtest) (b, state, n_randint(state, 50), ctx); + do + { + TEMPLATE(T, poly_randtest) (f, state, n_randint(state, 50), ctx); + } while (TEMPLATE(T, poly_is_zero) (f, ctx)); + if (a->length >= f->length) + TEMPLATE(T, poly_rem) (a, a, f, ctx); + if (b->length >= f->length) + TEMPLATE(T, poly_rem) (b, b, f, ctx); + + TEMPLATE(T, poly_reverse) (finv, f, f->length, ctx); + TEMPLATE(T, poly_inv_series_newton) (finv, finv, f->length, ctx); + + TEMPLATE(T, poly_mulmod_preinv) (res, a, b, f, finv, ctx); + TEMPLATE(T, poly_mulmod_preinv) (f, a, b, f, finv, ctx); + + result = (TEMPLATE(T, poly_equal) (res, f, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx), flint_printf("\n\n"); + flint_printf("b:\n"); + TEMPLATE(T, poly_print) (b, ctx), flint_printf("\n\n"); + flint_printf("f:\n"); + TEMPLATE(T, poly_print) (f, ctx), flint_printf("\n\n"); + flint_printf("res1:\n"); + TEMPLATE(T, poly_print) (res, ctx), flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (f, ctx); + TEMPLATE(T, poly_clear) (finv, ctx); + TEMPLATE(T, poly_clear) (res, ctx); + TEMPLATE(T, poly_clear) (t, ctx); + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Aliasing res and finv */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + TEMPLATE(T, poly_t) a, b, res, t, f, finv; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (f, ctx); + TEMPLATE(T, poly_init) (finv, ctx); + TEMPLATE(T, poly_init) (res, ctx); + TEMPLATE(T, poly_init) (t, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 50), ctx); + TEMPLATE(T, poly_randtest) (b, state, n_randint(state, 50), ctx); + do + { + TEMPLATE(T, poly_randtest) (f, state, n_randint(state, 50), ctx); + } while (TEMPLATE(T, poly_is_zero) (f, ctx)); + if (a->length >= f->length) + TEMPLATE(T, poly_rem) (a, a, f, ctx); + if (b->length >= f->length) + TEMPLATE(T, poly_rem) (b, b, f, ctx); + + TEMPLATE(T, poly_reverse) (finv, f, f->length, ctx); + TEMPLATE(T, poly_inv_series_newton) (finv, finv, f->length, ctx); + + TEMPLATE(T, poly_mulmod_preinv) (res, a, b, f, finv, ctx); + TEMPLATE(T, poly_mulmod_preinv) (finv, a, b, f, finv, ctx); + + result = (TEMPLATE(T, poly_equal) (res, finv, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx), flint_printf("\n\n"); + flint_printf("b:\n"); + TEMPLATE(T, poly_print) (b, ctx), flint_printf("\n\n"); + flint_printf("f:\n"); + TEMPLATE(T, poly_print) (f, ctx), flint_printf("\n\n"); + flint_printf("finv:\n"); + TEMPLATE(T, poly_print) (finv, ctx), flint_printf("\n\n"); + flint_printf("res1:\n"); + TEMPLATE(T, poly_print) (res, ctx), flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (f, ctx); + TEMPLATE(T, poly_clear) (finv, ctx); + TEMPLATE(T, poly_clear) (res, ctx); + TEMPLATE(T, poly_clear) (t, ctx); + TEMPLATE(T, ctx_clear) (ctx); + } + + /* No aliasing */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + TEMPLATE(T, poly_t) a, b, res1, res2, t, f, finv; + + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (f, ctx); + TEMPLATE(T, poly_init) (finv, ctx); + TEMPLATE(T, poly_init) (res1, ctx); + TEMPLATE(T, poly_init) (res2, ctx); + TEMPLATE(T, poly_init) (t, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 50), ctx); + TEMPLATE(T, poly_randtest) (b, state, n_randint(state, 50), ctx); + do + { + TEMPLATE(T, poly_randtest) (f, state, n_randint(state, 50), ctx); + } while (TEMPLATE(T, poly_is_zero) (f, ctx)); + if (a->length >= f->length) + TEMPLATE(T, poly_rem) (a, a, f, ctx); + if (b->length >= f->length) + TEMPLATE(T, poly_rem) (b, b, f, ctx); + + TEMPLATE(T, poly_reverse) (finv, f, f->length, ctx); + TEMPLATE(T, poly_inv_series_newton) (finv, finv, f->length, ctx); + + TEMPLATE(T, poly_mulmod_preinv) (res1, a, b, f, finv, ctx); + + TEMPLATE(T, poly_mul) (res2, a, b, ctx); + TEMPLATE(T, poly_divrem) (t, res2, res2, f, ctx); + + result = (TEMPLATE(T, poly_equal) (res1, res2, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx), flint_printf("\n\n"); + flint_printf("b:\n"); + TEMPLATE(T, poly_print) (b, ctx), flint_printf("\n\n"); + flint_printf("f:\n"); + TEMPLATE(T, poly_print) (f, ctx), flint_printf("\n\n"); + flint_printf("res1:\n"); + TEMPLATE(T, poly_print) (res1, ctx), flint_printf("\n\n"); + flint_printf("res2:\n"); + TEMPLATE(T, poly_print) (res2, ctx), flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (f, ctx); + TEMPLATE(T, poly_clear) (finv, ctx); + TEMPLATE(T, poly_clear) (res1, ctx); + TEMPLATE(T, poly_clear) (res2, ctx); + TEMPLATE(T, poly_clear) (t, ctx); + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-neg.c b/external/flint-2.4.3/fq_poly_templates/test/t-neg.c new file mode 100644 index 0000000..d88b5c8 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-neg.c @@ -0,0 +1,160 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include + +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("neg... "); + fflush(stdout); + + /* Check aliasing: a = -a */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b; + + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + + TEMPLATE(T, poly_neg) (b, a, ctx); + TEMPLATE(T, poly_neg) (a, a, ctx); + + result = (TEMPLATE(T, poly_equal) (a, b, ctx)); + if (!result) + { + flint_printf("FAIL (aliasing):\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check that -(-a) == a */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b; + + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + + TEMPLATE(T, poly_neg) (b, a, ctx); + TEMPLATE(T, poly_neg) (b, b, ctx); + + result = (TEMPLATE(T, poly_equal) (a, b, ctx)); + if (!result) + { + flint_printf("FAIL (-(-a) == a):\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check that (a + (-a)) == 0 */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b; + + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + + TEMPLATE(T, poly_neg) (b, a, ctx); + TEMPLATE(T, poly_add) (a, a, b, ctx); + + result = (TEMPLATE(T, poly_is_zero) (a, ctx)); + if (!result) + { + flint_printf("FAIL (a + (-a) == 0):\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-pow.c b/external/flint-2.4.3/fq_poly_templates/test/t-pow.c new file mode 100644 index 0000000..3524f81 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-pow.c @@ -0,0 +1,152 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include + +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("pow... "); + fflush(stdout); + + /* Check aliasing */ + for (i = 0; i < 200; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, c; + ulong exp; + + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + exp = n_randtest(state) % UWORD(20); + TEMPLATE(T, poly_set) (b, a, ctx); + TEMPLATE(T, poly_pow) (c, b, exp, ctx); + TEMPLATE(T, poly_pow) (b, b, exp, ctx); + + result = (TEMPLATE(T, poly_equal) (b, c, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + flint_printf("exp = %wu\n", exp); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Compare with repeated multiplications by the base */ + for (i = 0; i < 1000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, c; + ulong exp; + + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + + TEMPLATE(T, poly_randtest) (b, state, len, ctx); + exp = n_randtest(state) % UWORD(20); + + TEMPLATE(T, poly_pow) (a, b, exp, ctx); + + if (exp == 0) + { + TEMPLATE(T, poly_one) (c, ctx); + } + else + { + slong j; + + TEMPLATE(T, poly_set) (c, b, ctx); + for (j = 1; j < exp; j++) + TEMPLATE(T, poly_mul) (c, c, b, ctx); + } + + result = (TEMPLATE(T, poly_equal) (a, c, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + flint_printf("exp = %wu\n", exp); + TEMPLATE(T, ctx_print) (ctx); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-powmod_fmpz_binexp.c b/external/flint-2.4.3/fq_poly_templates/test/t-powmod_fmpz_binexp.c new file mode 100644 index 0000000..be967e3 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-powmod_fmpz_binexp.c @@ -0,0 +1,265 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("powmod_fmpz_binexp...."); + fflush(stdout); + + /* Aliasing of res and a */ + for (i = 0; i < 5 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, res, t, f; + ulong exp; + fmpz_t expz; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + exp = n_randint(state, 50); + fmpz_init_set_ui(expz, exp); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (f, ctx); + TEMPLATE(T, poly_init) (res, ctx); + TEMPLATE(T, poly_init) (t, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 20), ctx); + TEMPLATE(T, poly_randtest_not_zero) (f, state, + n_randint(state, 20) + 1, ctx); + + TEMPLATE(T, poly_powmod_fmpz_binexp) (res, a, expz, f, ctx); + TEMPLATE(T, poly_powmod_fmpz_binexp) (a, a, expz, f, ctx); + + result = (TEMPLATE(T, poly_equal) (res, a, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx), flint_printf("\n\n"); + flint_printf("f:\n"); + TEMPLATE(T, poly_print) (f, ctx), flint_printf("\n\n"); + flint_printf("res:\n"); + TEMPLATE(T, poly_print) (res, ctx), flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (f, ctx); + TEMPLATE(T, poly_clear) (res, ctx); + TEMPLATE(T, poly_clear) (t, ctx); + fmpz_clear(expz); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Aliasing of res and f */ + for (i = 0; i < 5 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, res, t, f; + ulong exp; + fmpz_t expz; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + exp = n_randint(state, 50); + fmpz_init_set_ui(expz, exp); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (f, ctx); + TEMPLATE(T, poly_init) (res, ctx); + TEMPLATE(T, poly_init) (t, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 20), ctx); + TEMPLATE(T, poly_randtest_not_zero) (f, state, + n_randint(state, 20) + 1, ctx); + + TEMPLATE(T, poly_powmod_fmpz_binexp) (res, a, expz, f, ctx); + TEMPLATE(T, poly_powmod_fmpz_binexp) (f, a, expz, f, ctx); + + result = (TEMPLATE(T, poly_equal) (res, f, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx), flint_printf("\n\n"); + flint_printf("f:\n"); + TEMPLATE(T, poly_print) (f, ctx), flint_printf("\n\n"); + flint_printf("res:\n"); + TEMPLATE(T, poly_print) (res, ctx), flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (f, ctx); + TEMPLATE(T, poly_clear) (res, ctx); + TEMPLATE(T, poly_clear) (t, ctx); + fmpz_clear(expz); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* No aliasing */ + for (i = 0; i < 5 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, res1, res2, t, f; + ulong exp; + fmpz_t expz; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + exp = n_randint(state, 50); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (f, ctx); + TEMPLATE(T, poly_init) (res1, ctx); + TEMPLATE(T, poly_init) (res2, ctx); + TEMPLATE(T, poly_init) (t, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 20), ctx); + TEMPLATE(T, poly_randtest_not_zero) (f, state, + n_randint(state, 20) + 1, ctx); + fmpz_init_set_ui(expz, exp); + + TEMPLATE(T, poly_powmod_fmpz_binexp) (res1, a, expz, f, ctx); + TEMPLATE(T, poly_powmod_ui_binexp) (res2, a, exp, f, ctx); + + result = (TEMPLATE(T, poly_equal) (res1, res2, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx), flint_printf("\n\n"); + flint_printf("f:\n"); + TEMPLATE(T, poly_print) (f, ctx), flint_printf("\n\n"); + flint_printf("res1:\n"); + TEMPLATE(T, poly_print) (res1, ctx), flint_printf("\n\n"); + flint_printf("res2:\n"); + TEMPLATE(T, poly_print) (res2, ctx), flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (f, ctx); + TEMPLATE(T, poly_clear) (res1, ctx); + TEMPLATE(T, poly_clear) (res2, ctx); + TEMPLATE(T, poly_clear) (t, ctx); + fmpz_clear(expz); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check that a^(b+c) = a^b * a^c */ + for (i = 0; i < 5 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, res1, res2, res3, res4, t, f; + fmpz_t exp1, exp2, exp3; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + fmpz_init(exp1); + fmpz_init(exp2); + fmpz_randtest(exp1, state, 200); + if (fmpz_sgn(exp1) == -1) + fmpz_neg(exp1, exp1); + fmpz_randtest(exp2, state, 200); + if (fmpz_sgn(exp2) == -1) + fmpz_neg(exp2, exp2); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (f, ctx); + TEMPLATE(T, poly_init) (res1, ctx); + TEMPLATE(T, poly_init) (res2, ctx); + TEMPLATE(T, poly_init) (res3, ctx); + TEMPLATE(T, poly_init) (res4, ctx); + TEMPLATE(T, poly_init) (t, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 20), ctx); + TEMPLATE(T, poly_randtest_not_zero) (f, state, + n_randint(state, 20) + 1, ctx); + + TEMPLATE(T, poly_powmod_fmpz_binexp) (res1, a, exp1, f, ctx); + TEMPLATE(T, poly_powmod_fmpz_binexp) (res2, a, exp2, f, ctx); + TEMPLATE(T, poly_mulmod) (res4, res1, res2, f, ctx); + fmpz_init(exp3); + fmpz_add(exp3, exp1, exp2); + TEMPLATE(T, poly_powmod_fmpz_binexp) (res3, a, exp3, f, ctx); + + result = (TEMPLATE(T, poly_equal) (res4, res3, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx), flint_printf("\n\n"); + flint_printf("f:\n"); + TEMPLATE(T, poly_print) (f, ctx), flint_printf("\n\n"); + flint_printf("res3:\n"); + TEMPLATE(T, poly_print) (res3, ctx), flint_printf("\n\n"); + flint_printf("res4:\n"); + TEMPLATE(T, poly_print) (res4, ctx), flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (f, ctx); + TEMPLATE(T, poly_clear) (res1, ctx); + TEMPLATE(T, poly_clear) (res2, ctx); + TEMPLATE(T, poly_clear) (res3, ctx); + TEMPLATE(T, poly_clear) (res4, ctx); + TEMPLATE(T, poly_clear) (t, ctx); + fmpz_clear(exp1); + fmpz_clear(exp2); + fmpz_clear(exp3); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-powmod_fmpz_binexp_preinv.c b/external/flint-2.4.3/fq_poly_templates/test/t-powmod_fmpz_binexp_preinv.c new file mode 100644 index 0000000..916f7f6 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-powmod_fmpz_binexp_preinv.c @@ -0,0 +1,286 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("powmod_fmpz_binexp_preinv..."); + fflush(stdout); + + /* Aliasing of res and a */ + for (i = 0; i < 25; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, res, t, f, finv; + ulong exp; + fmpz_t expz; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + exp = n_randint(state, 50); + fmpz_init_set_ui(expz, exp); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (f, ctx); + TEMPLATE(T, poly_init) (finv, ctx); + TEMPLATE(T, poly_init) (res, ctx); + TEMPLATE(T, poly_init) (t, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 50), ctx); + TEMPLATE(T, poly_randtest_not_zero) (f, state, + n_randint(state, 50) + 1, ctx); + + TEMPLATE(T, poly_reverse) (finv, f, f->length, ctx); + TEMPLATE(T, poly_inv_series_newton) (finv, finv, f->length, ctx); + + TEMPLATE(T, poly_powmod_fmpz_binexp_preinv) (res, a, expz, f, finv, + ctx); + TEMPLATE(T, poly_powmod_fmpz_binexp_preinv) (a, a, expz, f, finv, ctx); + + result = (TEMPLATE(T, poly_equal) (res, a, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx), flint_printf("\n\n"); + flint_printf("f:\n"); + TEMPLATE(T, poly_print) (f, ctx), flint_printf("\n\n"); + flint_printf("res:\n"); + TEMPLATE(T, poly_print) (res, ctx), flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (f, ctx); + TEMPLATE(T, poly_clear) (finv, ctx); + TEMPLATE(T, poly_clear) (res, ctx); + TEMPLATE(T, poly_clear) (t, ctx); + fmpz_clear(expz); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Aliasing of res and f */ + for (i = 0; i < 25; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, res, t, f, finv; + ulong exp; + fmpz_t expz; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + exp = n_randint(state, 50); + fmpz_init_set_ui(expz, exp); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (f, ctx); + TEMPLATE(T, poly_init) (finv, ctx); + TEMPLATE(T, poly_init) (res, ctx); + TEMPLATE(T, poly_init) (t, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 50), ctx); + TEMPLATE(T, poly_randtest_not_zero) (f, state, + n_randint(state, 50) + 1, ctx); + + TEMPLATE(T, poly_reverse) (finv, f, f->length, ctx); + TEMPLATE(T, poly_inv_series_newton) (finv, finv, f->length, ctx); + + TEMPLATE(T, poly_powmod_fmpz_binexp_preinv) (res, a, expz, f, finv, + ctx); + TEMPLATE(T, poly_powmod_fmpz_binexp_preinv) (f, a, expz, f, finv, ctx); + + result = (TEMPLATE(T, poly_equal) (res, f, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx), flint_printf("\n\n"); + flint_printf("f:\n"); + TEMPLATE(T, poly_print) (f, ctx), flint_printf("\n\n"); + flint_printf("res:\n"); + TEMPLATE(T, poly_print) (res, ctx), flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (f, ctx); + TEMPLATE(T, poly_clear) (finv, ctx); + TEMPLATE(T, poly_clear) (res, ctx); + TEMPLATE(T, poly_clear) (t, ctx); + fmpz_clear(expz); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* No aliasing */ + for (i = 0; i < 50; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, res1, res2, t, f, finv; + ulong exp; + fmpz_t expz; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + exp = n_randint(state, 50); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (f, ctx); + TEMPLATE(T, poly_init) (finv, ctx); + TEMPLATE(T, poly_init) (res1, ctx); + TEMPLATE(T, poly_init) (res2, ctx); + TEMPLATE(T, poly_init) (t, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 50), ctx); + TEMPLATE(T, poly_randtest_not_zero) (f, state, + n_randint(state, 50) + 1, ctx); + fmpz_init_set_ui(expz, exp); + + TEMPLATE(T, poly_reverse) (finv, f, f->length, ctx); + TEMPLATE(T, poly_inv_series_newton) (finv, finv, f->length, ctx); + + TEMPLATE(T, poly_powmod_fmpz_binexp_preinv) (res1, a, expz, f, finv, + ctx); + TEMPLATE(T, poly_powmod_ui_binexp_preinv) (res2, a, exp, f, finv, ctx); + + result = (TEMPLATE(T, poly_equal) (res1, res2, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx), flint_printf("\n\n"); + flint_printf("f:\n"); + TEMPLATE(T, poly_print) (f, ctx), flint_printf("\n\n"); + flint_printf("res1:\n"); + TEMPLATE(T, poly_print) (res1, ctx), flint_printf("\n\n"); + flint_printf("res2:\n"); + TEMPLATE(T, poly_print) (res2, ctx), flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (f, ctx); + TEMPLATE(T, poly_clear) (finv, ctx); + TEMPLATE(T, poly_clear) (res1, ctx); + TEMPLATE(T, poly_clear) (res2, ctx); + TEMPLATE(T, poly_clear) (t, ctx); + fmpz_clear(expz); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check that a^(b+c) = a^b * a^c */ + for (i = 0; i < 50; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, res1, res2, res3, res4, t, f, finv; + fmpz_t exp1, exp2, exp3; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + fmpz_init(exp1); + fmpz_init(exp2); + fmpz_randtest(exp1, state, 200); + if (fmpz_sgn(exp1) == -1) + fmpz_neg(exp1, exp1); + fmpz_randtest(exp2, state, 200); + if (fmpz_sgn(exp2) == -1) + fmpz_neg(exp2, exp2); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (f, ctx); + TEMPLATE(T, poly_init) (finv, ctx); + TEMPLATE(T, poly_init) (res1, ctx); + TEMPLATE(T, poly_init) (res2, ctx); + TEMPLATE(T, poly_init) (res3, ctx); + TEMPLATE(T, poly_init) (res4, ctx); + TEMPLATE(T, poly_init) (t, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 50), ctx); + TEMPLATE(T, poly_randtest_not_zero) (f, state, + n_randint(state, 50) + 1, ctx); + + TEMPLATE(T, poly_reverse) (finv, f, f->length, ctx); + TEMPLATE(T, poly_inv_series_newton) (finv, finv, f->length, ctx); + + TEMPLATE(T, poly_powmod_fmpz_binexp_preinv) (res1, a, exp1, f, finv, + ctx); + TEMPLATE(T, poly_powmod_fmpz_binexp_preinv) (res2, a, exp2, f, finv, + ctx); + TEMPLATE(T, poly_mulmod) (res4, res1, res2, f, ctx); + fmpz_init(exp3); + fmpz_add(exp3, exp1, exp2); + TEMPLATE(T, poly_powmod_fmpz_binexp_preinv) (res3, a, exp3, f, finv, + ctx); + + result = (TEMPLATE(T, poly_equal) (res4, res3, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx), flint_printf("\n\n"); + flint_printf("f:\n"); + TEMPLATE(T, poly_print) (f, ctx), flint_printf("\n\n"); + flint_printf("res3:\n"); + TEMPLATE(T, poly_print) (res3, ctx), flint_printf("\n\n"); + flint_printf("res4:\n"); + TEMPLATE(T, poly_print) (res4, ctx), flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (f, ctx); + TEMPLATE(T, poly_clear) (finv, ctx); + TEMPLATE(T, poly_clear) (res1, ctx); + TEMPLATE(T, poly_clear) (res2, ctx); + TEMPLATE(T, poly_clear) (res3, ctx); + TEMPLATE(T, poly_clear) (res4, ctx); + TEMPLATE(T, poly_clear) (t, ctx); + fmpz_clear(exp1); + fmpz_clear(exp2); + fmpz_clear(exp3); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-powmod_fmpz_sliding_preinv.c b/external/flint-2.4.3/fq_poly_templates/test/t-powmod_fmpz_sliding_preinv.c new file mode 100644 index 0000000..e37d6c6 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-powmod_fmpz_sliding_preinv.c @@ -0,0 +1,304 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("powmod_fmpz_sliding_preinv..."); + fflush(stdout); + + /* Aliasing of res and a */ + for (i = 0; i < 25; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, res, t, f, finv; + ulong exp; + fmpz_t expz; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + exp = n_randint(state, 50); + fmpz_init_set_ui(expz, exp); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (f, ctx); + TEMPLATE(T, poly_init) (finv, ctx); + TEMPLATE(T, poly_init) (res, ctx); + TEMPLATE(T, poly_init) (t, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 50), ctx); + TEMPLATE(T, poly_randtest_not_zero) (f, state, + n_randint(state, 50) + 1, ctx); + + TEMPLATE(T, poly_reverse) (finv, f, f->length, ctx); + TEMPLATE(T, poly_inv_series_newton) (finv, finv, f->length, ctx); + + TEMPLATE(T, poly_powmod_fmpz_sliding_preinv) (res, a, expz, 0, f, finv, + ctx); + TEMPLATE(T, poly_powmod_fmpz_sliding_preinv) (a, a, expz, 0, f, finv, + ctx); + + result = (TEMPLATE(T, poly_equal) (res, a, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx), flint_printf("\n\n"); + flint_printf("f:\n"); + TEMPLATE(T, poly_print) (f, ctx), flint_printf("\n\n"); + flint_printf("res:\n"); + TEMPLATE(T, poly_print) (res, ctx), flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (f, ctx); + TEMPLATE(T, poly_clear) (finv, ctx); + TEMPLATE(T, poly_clear) (res, ctx); + TEMPLATE(T, poly_clear) (t, ctx); + fmpz_clear(expz); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Aliasing of res and f */ + for (i = 0; i < 25; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, res, t, f, finv; + ulong exp; + fmpz_t expz; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + exp = n_randint(state, 50); + fmpz_init_set_ui(expz, exp); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (f, ctx); + TEMPLATE(T, poly_init) (finv, ctx); + TEMPLATE(T, poly_init) (res, ctx); + TEMPLATE(T, poly_init) (t, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 50), ctx); + TEMPLATE(T, poly_randtest_not_zero) (f, state, + n_randint(state, 50) + 1, ctx); + + TEMPLATE(T, poly_reverse) (finv, f, f->length, ctx); + TEMPLATE(T, poly_inv_series_newton) (finv, finv, f->length, ctx); + + TEMPLATE(T, poly_powmod_fmpz_sliding_preinv) (res, a, expz, 0, f, finv, + ctx); + TEMPLATE(T, poly_powmod_fmpz_sliding_preinv) (f, a, expz, 0, f, finv, + ctx); + + result = (TEMPLATE(T, poly_equal) (res, f, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx), flint_printf("\n\n"); + flint_printf("f:\n"); + TEMPLATE(T, poly_print) (f, ctx), flint_printf("\n\n"); + flint_printf("res:\n"); + TEMPLATE(T, poly_print) (res, ctx), flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (f, ctx); + TEMPLATE(T, poly_clear) (finv, ctx); + TEMPLATE(T, poly_clear) (res, ctx); + TEMPLATE(T, poly_clear) (t, ctx); + fmpz_clear(expz); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* No aliasing */ + for (i = 0; i < 50; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, res1, res2, t, f, finv; + ulong exp; + fmpz_t expz; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + exp = n_randint(state, 50); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (f, ctx); + TEMPLATE(T, poly_init) (finv, ctx); + TEMPLATE(T, poly_init) (res1, ctx); + TEMPLATE(T, poly_init) (res2, ctx); + TEMPLATE(T, poly_init) (t, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 50), ctx); + TEMPLATE(T, poly_randtest_not_zero) (f, state, + n_randint(state, 50) + 1, ctx); + fmpz_init_set_ui(expz, exp); + + TEMPLATE(T, poly_reverse) (finv, f, f->length, ctx); + TEMPLATE(T, poly_inv_series_newton) (finv, finv, f->length, ctx); + + TEMPLATE(T, poly_powmod_fmpz_sliding_preinv) (res1, a, expz, 0, f, + finv, ctx); + TEMPLATE(T, poly_powmod_fmpz_sliding_preinv) (res2, a, expz, 0, f, finv, ctx); /* TODO: Fix */ + + result = (TEMPLATE(T, poly_equal) (res1, res2, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx), flint_printf("\n\n"); + flint_printf("f:\n"); + TEMPLATE(T, poly_print) (f, ctx), flint_printf("\n\n"); + flint_printf("res1:\n"); + TEMPLATE(T, poly_print) (res1, ctx), flint_printf("\n\n"); + flint_printf("res2:\n"); + TEMPLATE(T, poly_print) (res2, ctx), flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (f, ctx); + TEMPLATE(T, poly_clear) (finv, ctx); + TEMPLATE(T, poly_clear) (res1, ctx); + TEMPLATE(T, poly_clear) (res2, ctx); + TEMPLATE(T, poly_clear) (t, ctx); + fmpz_clear(expz); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check that a^(b+c) = a^b * a^c */ + for (i = 0; i < 50; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, res1, res2, res3, res4, t, f, finv; + fmpz_t exp1, exp2, exp3; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + fmpz_init(exp1); + fmpz_init(exp2); + fmpz_randtest(exp1, state, 200); + if (fmpz_sgn(exp1) == -1) + fmpz_neg(exp1, exp1); + fmpz_randtest(exp2, state, 200); + if (fmpz_sgn(exp2) == -1) + fmpz_neg(exp2, exp2); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (f, ctx); + TEMPLATE(T, poly_init) (finv, ctx); + TEMPLATE(T, poly_init) (res1, ctx); + TEMPLATE(T, poly_init) (res2, ctx); + TEMPLATE(T, poly_init) (res3, ctx); + TEMPLATE(T, poly_init) (res4, ctx); + TEMPLATE(T, poly_init) (t, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 50), ctx); + TEMPLATE(T, poly_randtest_not_zero) (f, state, + n_randint(state, 50) + 1, ctx); + + TEMPLATE(T, poly_reverse) (finv, f, f->length, ctx); + TEMPLATE(T, poly_inv_series_newton) (finv, finv, f->length, ctx); + + TEMPLATE(T, poly_powmod_fmpz_sliding_preinv) (res1, a, exp1, 0, f, + finv, ctx); + TEMPLATE(T, poly_powmod_fmpz_sliding_preinv) (res2, a, exp2, 0, f, + finv, ctx); + TEMPLATE(T, poly_mulmod) (res4, res1, res2, f, ctx); + fmpz_init(exp3); + fmpz_add(exp3, exp1, exp2); + TEMPLATE(T, poly_powmod_fmpz_sliding_preinv) (res3, a, exp3, 0, f, + finv, ctx); + + result = (TEMPLATE(T, poly_equal) (res4, res3, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + TEMPLATE(T, ctx_print) (ctx); + flint_printf("exp1:\n"); + fmpz_print(exp1); + flint_printf("\n\n"); + flint_printf("exp2:\n"); + fmpz_print(exp2); + flint_printf("\n\n"); + flint_printf("a:\n"); + TEMPLATE(T, poly_print_pretty) (a, "x", ctx), flint_printf("\n\n"); + flint_printf("f:\n"); + TEMPLATE(T, poly_print_pretty) (f, "x", ctx), flint_printf("\n\n"); + flint_printf("res1:\n"); + TEMPLATE(T, poly_print_pretty) (res1, "x", ctx), + flint_printf("\n\n"); + flint_printf("res2:\n"); + TEMPLATE(T, poly_print_pretty) (res2, "x", ctx), + flint_printf("\n\n"); + flint_printf("res3:\n"); + TEMPLATE(T, poly_print_pretty) (res3, "x", ctx), + flint_printf("\n\n"); + flint_printf("res4:\n"); + TEMPLATE(T, poly_print_pretty) (res4, "x", ctx), + flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (f, ctx); + TEMPLATE(T, poly_clear) (finv, ctx); + TEMPLATE(T, poly_clear) (res1, ctx); + TEMPLATE(T, poly_clear) (res2, ctx); + TEMPLATE(T, poly_clear) (res3, ctx); + TEMPLATE(T, poly_clear) (res4, ctx); + TEMPLATE(T, poly_clear) (t, ctx); + fmpz_clear(exp1); + fmpz_clear(exp2); + fmpz_clear(exp3); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-powmod_ui_binexp.c b/external/flint-2.4.3/fq_poly_templates/test/t-powmod_ui_binexp.c new file mode 100644 index 0000000..39b0e37 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-powmod_ui_binexp.c @@ -0,0 +1,256 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("powmod_ui_binexp...."); + fflush(stdout); + + /* Aliasing of res and a */ + for (i = 0; i < 5 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, res1, t, f; + ulong exp; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + exp = n_randint(state, 50); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (f, ctx); + TEMPLATE(T, poly_init) (res1, ctx); + TEMPLATE(T, poly_init) (t, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 20), ctx); + TEMPLATE(T, poly_randtest_not_zero) (f, state, + n_randint(state, 20) + 1, ctx); + + TEMPLATE(T, poly_powmod_ui_binexp) (res1, a, exp, f, ctx); + TEMPLATE(T, poly_powmod_ui_binexp) (a, a, exp, f, ctx); + + result = (TEMPLATE(T, poly_equal) (res1, a, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("exp: %wu\n\n", exp); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx), flint_printf("\n\n"); + flint_printf("f:\n"); + TEMPLATE(T, poly_print) (f, ctx), flint_printf("\n\n"); + flint_printf("res:\n"); + TEMPLATE(T, poly_print) (res1, ctx), flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (f, ctx); + TEMPLATE(T, poly_clear) (res1, ctx); + TEMPLATE(T, poly_clear) (t, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Aliasing of res and f */ + for (i = 0; i < 5 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, res1, t, f; + ulong exp; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + exp = n_randint(state, 50); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (f, ctx); + TEMPLATE(T, poly_init) (res1, ctx); + TEMPLATE(T, poly_init) (t, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 20), ctx); + TEMPLATE(T, poly_randtest_not_zero) (f, state, + n_randint(state, 20) + 1, ctx); + + TEMPLATE(T, poly_powmod_ui_binexp) (res1, a, exp, f, ctx); + TEMPLATE(T, poly_powmod_ui_binexp) (f, a, exp, f, ctx); + + result = (TEMPLATE(T, poly_equal) (res1, f, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("exp: %wu\n\n", exp); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx), flint_printf("\n\n"); + flint_printf("f:\n"); + TEMPLATE(T, poly_print) (f, ctx), flint_printf("\n\n"); + flint_printf("res1:\n"); + TEMPLATE(T, poly_print) (res1, ctx), flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (f, ctx); + TEMPLATE(T, poly_clear) (res1, ctx); + TEMPLATE(T, poly_clear) (t, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* No aliasing */ + for (i = 0; i < 5 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, res1, res2, t, f; + ulong exp; + int j; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + exp = n_randint(state, 50); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (f, ctx); + TEMPLATE(T, poly_init) (res1, ctx); + TEMPLATE(T, poly_init) (res2, ctx); + TEMPLATE(T, poly_init) (t, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 20), ctx); + TEMPLATE(T, poly_randtest_not_zero) (f, state, + n_randint(state, 20) + 1, ctx); + + TEMPLATE(T, poly_powmod_ui_binexp) (res1, a, exp, f, ctx); + + TEMPLATE(T, poly_zero) (res2, ctx); + TEMPLATE(T, poly_one) (res2, ctx); + + for (j = 1; j <= exp; j++) + TEMPLATE(T, poly_mulmod) (res2, res2, a, f, ctx); + + result = (TEMPLATE(T, poly_equal) (res1, res2, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("exp: %wu\n\n", exp); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx), flint_printf("\n\n"); + flint_printf("f:\n"); + TEMPLATE(T, poly_print) (f, ctx), flint_printf("\n\n"); + flint_printf("res1:\n"); + TEMPLATE(T, poly_print) (res1, ctx), flint_printf("\n\n"); + flint_printf("res2:\n"); + TEMPLATE(T, poly_print) (res2, ctx), flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (f, ctx); + TEMPLATE(T, poly_clear) (res1, ctx); + TEMPLATE(T, poly_clear) (res2, ctx); + TEMPLATE(T, poly_clear) (t, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check that a^(b+c) = a^b * a^c */ + for (i = 0; i < 5 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, res1, res2, res3, res4, t, f; + + ulong exp1, exp2, exp3; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + exp1 = n_randint(state, 50); + exp2 = n_randint(state, 50); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (f, ctx); + TEMPLATE(T, poly_init) (res1, ctx); + TEMPLATE(T, poly_init) (res2, ctx); + TEMPLATE(T, poly_init) (res3, ctx); + TEMPLATE(T, poly_init) (res4, ctx); + TEMPLATE(T, poly_init) (t, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 20), ctx); + TEMPLATE(T, poly_randtest_not_zero) (f, state, + n_randint(state, 20) + 1, ctx); + + TEMPLATE(T, poly_powmod_ui_binexp) (res1, a, exp1, f, ctx); + TEMPLATE(T, poly_powmod_ui_binexp) (res2, a, exp2, f, ctx); + TEMPLATE(T, poly_mulmod) (res4, res1, res2, f, ctx); + exp3 = exp1 + exp2; + TEMPLATE(T, poly_powmod_ui_binexp) (res3, a, exp3, f, ctx); + + result = (TEMPLATE(T, poly_equal) (res4, res3, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx), flint_printf("\n\n"); + flint_printf("f:\n"); + TEMPLATE(T, poly_print) (f, ctx), flint_printf("\n\n"); + flint_printf("res3:\n"); + TEMPLATE(T, poly_print) (res3, ctx), flint_printf("\n\n"); + flint_printf("res4:\n"); + TEMPLATE(T, poly_print) (res4, ctx), flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (f, ctx); + TEMPLATE(T, poly_clear) (res1, ctx); + TEMPLATE(T, poly_clear) (res2, ctx); + TEMPLATE(T, poly_clear) (res3, ctx); + TEMPLATE(T, poly_clear) (res4, ctx); + TEMPLATE(T, poly_clear) (t, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-powmod_ui_binexp_preinv.c b/external/flint-2.4.3/fq_poly_templates/test/t-powmod_ui_binexp_preinv.c new file mode 100644 index 0000000..dc94532 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-powmod_ui_binexp_preinv.c @@ -0,0 +1,276 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("powmod_ui_binexp_preinv...."); + fflush(stdout); + + /* Aliasing of res and a */ + for (i = 0; i < 50; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, res1, t, f, finv; + ulong exp; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + exp = n_randint(state, 50); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (f, ctx); + TEMPLATE(T, poly_init) (finv, ctx); + TEMPLATE(T, poly_init) (res1, ctx); + TEMPLATE(T, poly_init) (t, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 50), ctx); + TEMPLATE(T, poly_randtest_not_zero) (f, state, + n_randint(state, 50) + 1, ctx); + + TEMPLATE(T, poly_reverse) (finv, f, f->length, ctx); + TEMPLATE(T, poly_inv_series_newton) (finv, finv, f->length, ctx); + + TEMPLATE(T, poly_powmod_ui_binexp_preinv) (res1, a, exp, f, finv, ctx); + TEMPLATE(T, poly_powmod_ui_binexp_preinv) (a, a, exp, f, finv, ctx); + + result = (TEMPLATE(T, poly_equal) (res1, a, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("exp: %wu\n\n", exp); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx), flint_printf("\n\n"); + flint_printf("f:\n"); + TEMPLATE(T, poly_print) (f, ctx), flint_printf("\n\n"); + flint_printf("res:\n"); + TEMPLATE(T, poly_print) (res1, ctx), flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (f, ctx); + TEMPLATE(T, poly_clear) (finv, ctx); + TEMPLATE(T, poly_clear) (res1, ctx); + TEMPLATE(T, poly_clear) (t, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Aliasing of res and f */ + for (i = 0; i < 50; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, res1, t, f, finv; + ulong exp; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + exp = n_randint(state, 50); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (f, ctx); + TEMPLATE(T, poly_init) (finv, ctx); + TEMPLATE(T, poly_init) (res1, ctx); + TEMPLATE(T, poly_init) (t, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 50), ctx); + TEMPLATE(T, poly_randtest_not_zero) (f, state, + n_randint(state, 50) + 1, ctx); + + TEMPLATE(T, poly_reverse) (finv, f, f->length, ctx); + TEMPLATE(T, poly_inv_series_newton) (finv, finv, f->length, ctx); + + TEMPLATE(T, poly_powmod_ui_binexp_preinv) (res1, a, exp, f, finv, ctx); + TEMPLATE(T, poly_powmod_ui_binexp_preinv) (f, a, exp, f, finv, ctx); + + result = (TEMPLATE(T, poly_equal) (res1, f, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("exp: %wu\n\n", exp); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx), flint_printf("\n\n"); + flint_printf("f:\n"); + TEMPLATE(T, poly_print) (f, ctx), flint_printf("\n\n"); + flint_printf("res1:\n"); + TEMPLATE(T, poly_print) (res1, ctx), flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (f, ctx); + TEMPLATE(T, poly_clear) (finv, ctx); + TEMPLATE(T, poly_clear) (res1, ctx); + TEMPLATE(T, poly_clear) (t, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* No aliasing */ + for (i = 0; i < 1000; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, res1, res2, t, f, finv; + ulong exp; + int j; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + exp = n_randint(state, 50); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (f, ctx); + TEMPLATE(T, poly_init) (finv, ctx); + TEMPLATE(T, poly_init) (res1, ctx); + TEMPLATE(T, poly_init) (res2, ctx); + TEMPLATE(T, poly_init) (t, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 50), ctx); + TEMPLATE(T, poly_randtest_not_zero) (f, state, + n_randint(state, 50) + 1, ctx); + + TEMPLATE(T, poly_reverse) (finv, f, f->length, ctx); + TEMPLATE(T, poly_inv_series_newton) (finv, finv, f->length, ctx); + + TEMPLATE(T, poly_powmod_ui_binexp_preinv) (res1, a, exp, f, finv, ctx); + + TEMPLATE(T, poly_zero) (res2, ctx); + TEMPLATE(T, poly_one) (res2, ctx); + + for (j = 1; j <= exp; j++) + TEMPLATE(T, poly_mulmod) (res2, res2, a, f, ctx); + + result = (TEMPLATE(T, poly_equal) (res1, res2, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("exp: %wu\n\n", exp); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx), flint_printf("\n\n"); + flint_printf("f:\n"); + TEMPLATE(T, poly_print) (f, ctx), flint_printf("\n\n"); + flint_printf("res1:\n"); + TEMPLATE(T, poly_print) (res1, ctx), flint_printf("\n\n"); + flint_printf("res2:\n"); + TEMPLATE(T, poly_print) (res2, ctx), flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (f, ctx); + TEMPLATE(T, poly_clear) (finv, ctx); + TEMPLATE(T, poly_clear) (res1, ctx); + TEMPLATE(T, poly_clear) (res2, ctx); + TEMPLATE(T, poly_clear) (t, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check that a^(b+c) = a^b * a^c */ + for (i = 0; i < 50; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, res1, res2, res3, res4, t, f, finv; + + ulong exp1, exp2, exp3; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + exp1 = n_randint(state, 50); + exp2 = n_randint(state, 50); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (f, ctx); + TEMPLATE(T, poly_init) (finv, ctx); + TEMPLATE(T, poly_init) (res1, ctx); + TEMPLATE(T, poly_init) (res2, ctx); + TEMPLATE(T, poly_init) (res3, ctx); + TEMPLATE(T, poly_init) (res4, ctx); + TEMPLATE(T, poly_init) (t, ctx); + + TEMPLATE(T, poly_randtest) (a, state, n_randint(state, 50), ctx); + TEMPLATE(T, poly_randtest_not_zero) (f, state, + n_randint(state, 50) + 1, ctx); + + TEMPLATE(T, poly_reverse) (finv, f, f->length, ctx); + TEMPLATE(T, poly_inv_series_newton) (finv, finv, f->length, ctx); + + + TEMPLATE(T, poly_powmod_ui_binexp_preinv) (res1, a, exp1, f, finv, + ctx); + TEMPLATE(T, poly_powmod_ui_binexp_preinv) (res2, a, exp2, f, finv, + ctx); + + TEMPLATE(T, poly_mulmod_preinv) (res4, res1, res2, f, finv, ctx); + exp3 = exp1 + exp2; + TEMPLATE(T, poly_powmod_ui_binexp_preinv) (res3, a, exp3, f, finv, + ctx); + + result = (TEMPLATE(T, poly_equal) (res4, res3, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx), flint_printf("\n\n"); + flint_printf("f:\n"); + TEMPLATE(T, poly_print) (f, ctx), flint_printf("\n\n"); + flint_printf("res3:\n"); + TEMPLATE(T, poly_print) (res3, ctx), flint_printf("\n\n"); + flint_printf("res4:\n"); + TEMPLATE(T, poly_print) (res4, ctx), flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (f, ctx); + TEMPLATE(T, poly_clear) (finv, ctx); + TEMPLATE(T, poly_clear) (res1, ctx); + TEMPLATE(T, poly_clear) (res2, ctx); + TEMPLATE(T, poly_clear) (res3, ctx); + TEMPLATE(T, poly_clear) (res4, ctx); + TEMPLATE(T, poly_clear) (t, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-powmod_x_fmpz_preinv.c b/external/flint-2.4.3/fq_poly_templates/test/t-powmod_x_fmpz_preinv.c new file mode 100644 index 0000000..cd7cadf --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-powmod_x_fmpz_preinv.c @@ -0,0 +1,153 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("powmod_x_fmpz_preinv..."); + fflush(stdout); + + /* Aliasing of res and f */ + for (i = 0; i < 25; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) res, t, f, finv; + ulong exp; + fmpz_t expz; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + exp = n_randint(state, 50); + fmpz_init_set_ui(expz, exp); + + TEMPLATE(T, poly_init) (f, ctx); + TEMPLATE(T, poly_init) (finv, ctx); + TEMPLATE(T, poly_init) (res, ctx); + TEMPLATE(T, poly_init) (t, ctx); + + TEMPLATE(T, poly_randtest_not_zero) (f, state, + n_randint(state, 50) + 1, ctx); + + TEMPLATE(T, poly_reverse) (finv, f, f->length, ctx); + TEMPLATE(T, poly_inv_series_newton) (finv, finv, f->length, ctx); + + TEMPLATE(T, poly_powmod_x_fmpz_preinv) (res, expz, f, finv, ctx); + TEMPLATE(T, poly_powmod_x_fmpz_preinv) (f, expz, f, finv, ctx); + + result = (TEMPLATE(T, poly_equal) (res, f, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("f:\n"); + TEMPLATE(T, poly_print) (f, ctx), flint_printf("\n\n"); + flint_printf("res:\n"); + TEMPLATE(T, poly_print) (res, ctx), flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (f, ctx); + TEMPLATE(T, poly_clear) (finv, ctx); + TEMPLATE(T, poly_clear) (res, ctx); + TEMPLATE(T, poly_clear) (t, ctx); + fmpz_clear(expz); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* No aliasing -- compare with binexp */ + for (i = 0; i < 100; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) a, res1, res2, t, f, finv; + ulong exp; + fmpz_t expz; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + exp = n_randint(state, 50); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (f, ctx); + TEMPLATE(T, poly_init) (finv, ctx); + TEMPLATE(T, poly_init) (res1, ctx); + TEMPLATE(T, poly_init) (res2, ctx); + TEMPLATE(T, poly_init) (t, ctx); + + TEMPLATE(T, poly_gen) (a, ctx); + TEMPLATE(T, poly_randtest_not_zero) (f, state, + n_randint(state, 50) + 1, ctx); + fmpz_init_set_ui(expz, exp); + + TEMPLATE(T, poly_reverse) (finv, f, f->length, ctx); + TEMPLATE(T, poly_inv_series_newton) (finv, finv, f->length, ctx); + + TEMPLATE(T, poly_powmod_fmpz_binexp_preinv) (res1, a, expz, f, finv, + ctx); + TEMPLATE(T, poly_powmod_x_fmpz_preinv) (res2, expz, f, finv, ctx); + + result = (TEMPLATE(T, poly_equal) (res1, res2, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); + TEMPLATE(T, poly_print) (a, ctx), flint_printf("\n\n"); + flint_printf("f:\n"); + TEMPLATE(T, poly_print) (f, ctx), flint_printf("\n\n"); + flint_printf("res1:\n"); + TEMPLATE(T, poly_print) (res1, ctx), flint_printf("\n\n"); + flint_printf("res2:\n"); + TEMPLATE(T, poly_print) (res2, ctx), flint_printf("\n\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (f, ctx); + TEMPLATE(T, poly_clear) (finv, ctx); + TEMPLATE(T, poly_clear) (res1, ctx); + TEMPLATE(T, poly_clear) (res2, ctx); + TEMPLATE(T, poly_clear) (t, ctx); + fmpz_clear(expz); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-randtest_irreducible.c b/external/flint-2.4.3/fq_poly_templates/test/t-randtest_irreducible.c new file mode 100644 index 0000000..3bd6734 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-randtest_irreducible.c @@ -0,0 +1,74 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + + +int +main(void) +{ + int iter; + FLINT_TEST_INIT(state); + + flint_printf("randtest_irreducible...."); + fflush(stdout); + + for (iter = 0; iter < 10 * flint_test_multiplier(); iter++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, poly_t) poly; + slong length; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (poly, ctx); + + length = n_randint(state, 20) + 2; + TEMPLATE(T, poly_randtest_irreducible) (poly, state, length, ctx); + + if (!TEMPLATE(T, poly_is_irreducible) (poly, ctx)) + { + flint_printf("Error: reducible polynomial created!\n"); + flint_printf("poly:\n"); + TEMPLATE(T, poly_print_pretty) (poly, "x", ctx); + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (poly, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-scalar_addmul_fq.c b/external/flint-2.4.3/fq_poly_templates/test/t-scalar_addmul_fq.c new file mode 100644 index 0000000..0d7e885 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-scalar_addmul_fq.c @@ -0,0 +1,149 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include + +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("scalar_addmul_fq... "); + fflush(stdout); + + /* Check aliasing */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, c; + TEMPLATE(T, t) x; + + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + TEMPLATE(T, init) (x, ctx); + + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + TEMPLATE(T, poly_set) (b, a, ctx); + TEMPLATE(T, poly_set) (c, a, ctx); + + TEMPLATE(T, TEMPLATE(poly_scalar_addmul, T)) (b, a, x, ctx); + TEMPLATE(T, TEMPLATE(poly_scalar_addmul, T)) (a, a, x, ctx); + + result = (TEMPLATE(T, poly_equal) (a, b, ctx)); + if (!result) + { + flint_printf("FAIL (alias):\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + flint_printf("x = "), TEMPLATE(T, print_pretty) (x, ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + TEMPLATE(T, clear) (x, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check that b += x*a is the same as c = b + x*a */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, c; + TEMPLATE(T, t) x; + + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + TEMPLATE(T, init) (x, ctx); + + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + TEMPLATE(T, poly_randtest) (b, state, len, ctx); + TEMPLATE(T, poly_set) (a, c, ctx); + + TEMPLATE(T, TEMPLATE(poly_scalar_mul, T)) (c, a, x, ctx); + TEMPLATE(T, poly_add) (c, b, c, ctx); + TEMPLATE(T, TEMPLATE(poly_scalar_addmul, T)) (b, a, x, ctx); + + result = (TEMPLATE(T, poly_equal) (b, c, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + flint_printf("x = "), TEMPLATE(T, print_pretty) (x, ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + TEMPLATE(T, clear) (x, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-scalar_mul_fq.c b/external/flint-2.4.3/fq_poly_templates/test/t-scalar_mul_fq.c new file mode 100644 index 0000000..760c892 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-scalar_mul_fq.c @@ -0,0 +1,95 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include + +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("scalar_mul_fq... "); + fflush(stdout); + + /* Check aliasing */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b; + TEMPLATE(T, t) x; + + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, init) (x, ctx); + + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + + TEMPLATE(T, TEMPLATE(poly_scalar_mul, T)) (b, a, x, ctx); + TEMPLATE(T, TEMPLATE(poly_scalar_mul, T)) (a, a, x, ctx); + + result = (TEMPLATE(T, poly_equal) (a, b, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("x = "), TEMPLATE(T, print_pretty) (x, ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, clear) (x, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-scalar_submul_fq.c b/external/flint-2.4.3/fq_poly_templates/test/t-scalar_submul_fq.c new file mode 100644 index 0000000..1202c8d --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-scalar_submul_fq.c @@ -0,0 +1,149 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include + +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("scalar_submul_fq... "); + fflush(stdout); + + /* Check aliasing */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, c; + TEMPLATE(T, t) x; + + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + TEMPLATE(T, init) (x, ctx); + + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + TEMPLATE(T, poly_set) (b, a, ctx); + TEMPLATE(T, poly_set) (c, a, ctx); + + TEMPLATE(T, TEMPLATE(poly_scalar_submul, T)) (b, a, x, ctx); + TEMPLATE(T, TEMPLATE(poly_scalar_submul, T)) (a, a, x, ctx); + + result = (TEMPLATE(T, poly_equal) (a, b, ctx)); + if (!result) + { + flint_printf("FAIL (alias):\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + flint_printf("x = "), TEMPLATE(T, print_pretty) (x, ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + TEMPLATE(T, clear) (x, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check that b += x*a is the same as c = b + x*a */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, c; + TEMPLATE(T, t) x; + + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + TEMPLATE(T, init) (x, ctx); + + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + TEMPLATE(T, poly_randtest) (b, state, len, ctx); + TEMPLATE(T, poly_set) (a, c, ctx); + + TEMPLATE(T, TEMPLATE(poly_scalar_mul, T)) (c, a, x, ctx); + TEMPLATE(T, poly_sub) (c, b, c, ctx); + TEMPLATE(T, TEMPLATE(poly_scalar_submul, T)) (b, a, x, ctx); + + result = (TEMPLATE(T, poly_equal) (b, c, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + flint_printf("x = "), TEMPLATE(T, print_pretty) (x, ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + TEMPLATE(T, clear) (x, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-shift_left_right.c b/external/flint-2.4.3/fq_poly_templates/test/t-shift_left_right.c new file mode 100644 index 0000000..ff55734 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-shift_left_right.c @@ -0,0 +1,178 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include + +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("shift_left/right... "); + fflush(stdout); + + /* Check aliasing for left shift */ + for (i = 0; i < 2000; i++) + { + slong len = n_randint(state, 100); + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, c; + slong shift; + + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + TEMPLATE(T, poly_set) (b, a, ctx); + shift = n_randint(state, 100); + + TEMPLATE(T, poly_shift_left) (c, b, shift, ctx); + TEMPLATE(T, poly_shift_left) (b, b, shift, ctx); + + result = (TEMPLATE(T, poly_equal) (b, c, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check aliasing for right shift */ + for (i = 0; i < 2000; i++) + { + slong len = n_randint(state, 100); + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, c; + slong shift; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + TEMPLATE(T, poly_set) (b, a, ctx); + shift = n_randint(state, 100); + + TEMPLATE(T, poly_shift_right) (c, b, shift, ctx); + TEMPLATE(T, poly_shift_right) (b, b, shift, ctx); + + result = (TEMPLATE(T, poly_equal) (b, c, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check shift left then right does nothing */ + for (i = 0; i < 2000; i++) + { + slong len = n_randint(state, 100); + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, c; + slong shift; + + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + shift = n_randint(state, 100); + + TEMPLATE(T, poly_shift_left) (b, a, shift, ctx); + TEMPLATE(T, poly_shift_right) (c, b, shift, ctx); + + result = (TEMPLATE(T, poly_equal) (c, a, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-sqr.c b/external/flint-2.4.3/fq_poly_templates/test/t-sqr.c new file mode 100644 index 0000000..75ac1bd --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-sqr.c @@ -0,0 +1,175 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include + +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("sqr... "); + fflush(stdout); + + /* Check aliasing: a = a * a */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, c; + + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (c, ctx); + + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + + TEMPLATE(T, poly_sqr) (c, a, ctx); + TEMPLATE(T, poly_sqr) (a, a, ctx); + + result = (TEMPLATE(T, poly_equal) (a, c, ctx)); + if (!result) + { + flint_printf("FAIL (aliasing):\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check that a^2 + a^2 == a * (a + a) */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, c, d; + + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + TEMPLATE(T, poly_init) (d, ctx); + + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + + TEMPLATE(T, poly_sqr) (b, a, ctx); + TEMPLATE(T, poly_add) (c, b, b, ctx); + + TEMPLATE(T, poly_add) (d, a, a, ctx); + TEMPLATE(T, poly_mul) (d, a, d, ctx); + + result = (TEMPLATE(T, poly_equal) (c, d, ctx)); + if (!result) + { + flint_printf("FAIL (a^2 + a^2 == a(a + a)):\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + flint_printf("d = "), TEMPLATE(T, poly_print_pretty) (d, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + TEMPLATE(T, poly_clear) (d, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Compare mul() */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, c; + + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + + TEMPLATE(T, poly_mul) (b, a, a, ctx); + TEMPLATE(T, poly_sqr) (c, a, ctx); + + result = (TEMPLATE(T, poly_equal) (b, c, ctx)); + if (!result) + { + flint_printf("FAIL (cmp with mul):\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-sqr_KS.c b/external/flint-2.4.3/fq_poly_templates/test/t-sqr_KS.c new file mode 100644 index 0000000..24c2ebb --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-sqr_KS.c @@ -0,0 +1,175 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include + +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("sqr_KS... "); + fflush(stdout); + + /* Check aliasing: a = a * a */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, c; + + len = n_randint(state, 50) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (c, ctx); + + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + + TEMPLATE(T, poly_sqr_KS) (c, a, ctx); + TEMPLATE(T, poly_sqr_KS) (a, a, ctx); + + result = (TEMPLATE(T, poly_equal) (a, c, ctx)); + if (!result) + { + flint_printf("FAIL (aliasing):\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check that a^2 + a^2 == a * (a + a) */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, c, d; + + len = n_randint(state, 50) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + TEMPLATE(T, poly_init) (d, ctx); + + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + + TEMPLATE(T, poly_sqr_KS) (b, a, ctx); + TEMPLATE(T, poly_add) (c, b, b, ctx); + + TEMPLATE(T, poly_add) (d, a, a, ctx); + TEMPLATE(T, poly_mul) (d, a, d, ctx); + + result = (TEMPLATE(T, poly_equal) (c, d, ctx)); + if (!result) + { + flint_printf("FAIL (a^2 + a^2 == a(a + a)):\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + flint_printf("d = "), TEMPLATE(T, poly_print_pretty) (d, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + TEMPLATE(T, poly_clear) (d, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Compare mul() */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, c; + + len = n_randint(state, 50) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + + TEMPLATE(T, poly_mul) (b, a, a, ctx); + TEMPLATE(T, poly_sqr_KS) (c, a, ctx); + + result = (TEMPLATE(T, poly_equal) (b, c, ctx)); + if (!result) + { + flint_printf("FAIL (cmp with mul):\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-sqr_classical.c b/external/flint-2.4.3/fq_poly_templates/test/t-sqr_classical.c new file mode 100644 index 0000000..ea56004 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-sqr_classical.c @@ -0,0 +1,175 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include + +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("sqr_classical... "); + fflush(stdout); + + /* Check aliasing: a = a * a */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, c; + + len = n_randint(state, 50) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (c, ctx); + + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + + TEMPLATE(T, poly_sqr_classical) (c, a, ctx); + TEMPLATE(T, poly_sqr_classical) (a, a, ctx); + + result = (TEMPLATE(T, poly_equal) (a, c, ctx)); + if (!result) + { + flint_printf("FAIL (aliasing):\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check that a^2 + a^2 == a * (a + a) */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, c, d; + + len = n_randint(state, 50) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + TEMPLATE(T, poly_init) (d, ctx); + + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + + TEMPLATE(T, poly_sqr_classical) (b, a, ctx); + TEMPLATE(T, poly_add) (c, b, b, ctx); + + TEMPLATE(T, poly_add) (d, a, a, ctx); + TEMPLATE(T, poly_mul) (d, a, d, ctx); + + result = (TEMPLATE(T, poly_equal) (c, d, ctx)); + if (!result) + { + flint_printf("FAIL (a^2 + a^2 == a(a + a)):\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + flint_printf("d = "), TEMPLATE(T, poly_print_pretty) (d, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + TEMPLATE(T, poly_clear) (d, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Compare mul() */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, c; + + len = n_randint(state, 50) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + + TEMPLATE(T, poly_mul) (b, a, a, ctx); + TEMPLATE(T, poly_sqr_classical) (c, a, ctx); + + result = (TEMPLATE(T, poly_equal) (b, c, ctx)); + if (!result) + { + flint_printf("FAIL (cmp with mul):\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-sqr_reorder.c b/external/flint-2.4.3/fq_poly_templates/test/t-sqr_reorder.c new file mode 100644 index 0000000..d2bc9a4 --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-sqr_reorder.c @@ -0,0 +1,175 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include + +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("sqr_reorder... "); + fflush(stdout); + + /* Check aliasing: a = a * a */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, c; + + len = n_randint(state, 50) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (c, ctx); + + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + + TEMPLATE(T, poly_sqr_reorder) (c, a, ctx); + TEMPLATE(T, poly_sqr_reorder) (a, a, ctx); + + result = (TEMPLATE(T, poly_equal) (a, c, ctx)); + if (!result) + { + flint_printf("FAIL (aliasing):\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check that a^2 + a^2 == a * (a + a) */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, c, d; + + len = n_randint(state, 50) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + TEMPLATE(T, poly_init) (d, ctx); + + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + + TEMPLATE(T, poly_sqr_reorder) (b, a, ctx); + TEMPLATE(T, poly_add) (c, b, b, ctx); + + TEMPLATE(T, poly_add) (d, a, a, ctx); + TEMPLATE(T, poly_mul) (d, a, d, ctx); + + result = (TEMPLATE(T, poly_equal) (c, d, ctx)); + if (!result) + { + flint_printf("FAIL (a^2 + a^2 == a(a + a)):\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + flint_printf("d = "), TEMPLATE(T, poly_print_pretty) (d, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + TEMPLATE(T, poly_clear) (d, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Compare mul() */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, c; + + len = n_randint(state, 50) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + + TEMPLATE(T, poly_mul) (b, a, a, ctx); + TEMPLATE(T, poly_sqr_reorder) (c, a, ctx); + + result = (TEMPLATE(T, poly_equal) (b, c, ctx)); + if (!result) + { + flint_printf("FAIL (cmp with mul):\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/test/t-sub.c b/external/flint-2.4.3/fq_poly_templates/test/t-sub.c new file mode 100644 index 0000000..1d2aead --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/test/t-sub.c @@ -0,0 +1,215 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include + +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("sub... "); + fflush(stdout); + + /* Check aliasing: a = a - b */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, c; + + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + TEMPLATE(T, poly_randtest) (b, state, len, ctx); + + TEMPLATE(T, poly_sub) (c, a, b, ctx); + TEMPLATE(T, poly_sub) (a, a, b, ctx); + + result = (TEMPLATE(T, poly_equal) (a, c, ctx)); + if (!result) + { + flint_printf("FAIL (aliasing a = a - b):\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check aliasing: b = a - b */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, c; + + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + TEMPLATE(T, poly_randtest) (b, state, len, ctx); + + TEMPLATE(T, poly_sub) (c, a, b, ctx); + TEMPLATE(T, poly_sub) (b, a, b, ctx); + + result = (TEMPLATE(T, poly_equal) (b, c, ctx)); + if (!result) + { + flint_printf("FAIL (b = a - b):\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check aliasing: a = a - a */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, c; + + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (c, ctx); + + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + + TEMPLATE(T, poly_sub) (c, a, a, ctx); + TEMPLATE(T, poly_sub) (a, a, a, ctx); + + result = (TEMPLATE(T, poly_equal) (a, c, ctx)); + if (!result) + { + flint_printf("FAIL (a = a - a):\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check that a - b == -(b - a) */ + for (i = 0; i < 2000; i++) + { + slong len; + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, poly_t) a, b, c, e; + + len = n_randint(state, 15) + 1; + TEMPLATE(T, ctx_randtest) (ctx, state); + TEMPLATE(T, poly_init) (a, ctx); + TEMPLATE(T, poly_init) (b, ctx); + TEMPLATE(T, poly_init) (c, ctx); + TEMPLATE(T, poly_init) (e, ctx); + + TEMPLATE(T, poly_randtest) (a, state, len, ctx); + TEMPLATE(T, poly_randtest) (b, state, len, ctx); + + TEMPLATE(T, poly_sub) (c, a, b, ctx); + TEMPLATE(T, poly_sub) (e, b, a, ctx); + TEMPLATE(T, poly_neg) (e, e, ctx); + + result = (TEMPLATE(T, poly_equal) (e, c, ctx)); + if (!result) + { + flint_printf("FAIL (a - b == -(b - a)):\n\n"); + flint_printf("a = "), TEMPLATE(T, poly_print_pretty) (a, "X", ctx), + flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, poly_print_pretty) (b, "X", ctx), + flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, poly_print_pretty) (c, "X", ctx), + flint_printf("\n"); + flint_printf("e = "), TEMPLATE(T, poly_print_pretty) (e, "X", ctx), + flint_printf("\n"); + abort(); + } + + TEMPLATE(T, poly_clear) (a, ctx); + TEMPLATE(T, poly_clear) (b, ctx); + TEMPLATE(T, poly_clear) (c, ctx); + TEMPLATE(T, poly_clear) (e, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + + + +#endif diff --git a/external/flint-2.4.3/fq_poly_templates/truncate.c b/external/flint-2.4.3/fq_poly_templates/truncate.c new file mode 100644 index 0000000..100b38d --- /dev/null +++ b/external/flint-2.4.3/fq_poly_templates/truncate.c @@ -0,0 +1,49 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Andres Goens + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +TEMPLATE(T, poly_truncate) (TEMPLATE(T, poly_t) poly, slong len, + const TEMPLATE(T, ctx_t) ctx) +{ + if (poly->length > len) + { + slong i; + + for (i = len; i < poly->length; i++) + TEMPLATE(T, zero) (poly->coeffs + i, ctx); + poly->length = len; + _TEMPLATE(T, poly_normalise) (poly, ctx); + } +} + + +#endif diff --git a/external/flint-2.4.3/fq_templates/test/t-add.c b/external/flint-2.4.3/fq_templates/test/t-add.c new file mode 100644 index 0000000..7ce6671 --- /dev/null +++ b/external/flint-2.4.3/fq_templates/test/t-add.c @@ -0,0 +1,238 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include + +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("add... "); + fflush(stdout); + + /* Check aliasing: a = a + b */ + for (i = 0; i < 2000; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, t) a, b, c; + + TEMPLATE(T, ctx_randtest)(ctx, state); + + TEMPLATE(T, init)(a, ctx); + TEMPLATE(T, init)(b, ctx); + TEMPLATE(T, init)(c, ctx); + + TEMPLATE(T, randtest)(a, state, ctx); + TEMPLATE(T, randtest)(b, state, ctx); + + TEMPLATE(T, add)(c, a, b, ctx); + TEMPLATE(T, add)(a, a, b, ctx); + + result = (TEMPLATE(T, equal)(a, c, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, print_pretty)(a, ctx), flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, print_pretty)(b, ctx), flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, print_pretty)(c, ctx), flint_printf("\n"); + abort(); + } + + TEMPLATE(T, clear)(a, ctx); + TEMPLATE(T, clear)(b, ctx); + TEMPLATE(T, clear)(c, ctx); + + TEMPLATE(T, ctx_clear)(ctx); + } + + /* Check aliasing: b = a + b */ + for (i = 0; i < 2000; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, t) a, b, c; + + TEMPLATE(T, ctx_randtest)(ctx, state); + + TEMPLATE(T, init)(a, ctx); + TEMPLATE(T, init)(b, ctx); + TEMPLATE(T, init)(c, ctx); + + TEMPLATE(T, randtest)(a, state, ctx); + TEMPLATE(T, randtest)(b, state, ctx); + + TEMPLATE(T, add)(c, a, b, ctx); + TEMPLATE(T, add)(b, a, b, ctx); + + result = (TEMPLATE(T, equal)(b, c, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, print_pretty)(a, ctx), flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, print_pretty)(b, ctx), flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, print_pretty)(c, ctx), flint_printf("\n"); + abort(); + } + + TEMPLATE(T, clear)(a, ctx); + TEMPLATE(T, clear)(b, ctx); + TEMPLATE(T, clear)(c, ctx); + + TEMPLATE(T, ctx_clear)(ctx); + } + + /* Check aliasing: a = a + a */ + for (i = 0; i < 2000; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, t) a, c; + + TEMPLATE(T, ctx_randtest)(ctx, state); + + TEMPLATE(T, init)(a, ctx); + TEMPLATE(T, init)(c, ctx); + + TEMPLATE(T, randtest)(a, state, ctx); + + TEMPLATE(T, add)(c, a, a, ctx); + TEMPLATE(T, add)(a, a, a, ctx); + + result = (TEMPLATE(T, equal)(a, c, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, print_pretty)(a, ctx), flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, print_pretty)(c, ctx), flint_printf("\n"); + abort(); + } + + TEMPLATE(T, clear)(a, ctx); + TEMPLATE(T, clear)(c, ctx); + + TEMPLATE(T, ctx_clear)(ctx); + } + + /* Check that a + b == b + a */ + for (i = 0; i < 2000; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, t) a, b, c1, c2; + + TEMPLATE(T, ctx_randtest)(ctx, state); + + TEMPLATE(T, init)(a, ctx); + TEMPLATE(T, init)(b, ctx); + TEMPLATE(T, init)(c1, ctx); + TEMPLATE(T, init)(c2, ctx); + + TEMPLATE(T, randtest)(a, state, ctx); + TEMPLATE(T, randtest)(b, state, ctx); + + TEMPLATE(T, add)(c1, a, b, ctx); + TEMPLATE(T, add)(c2, b, a, ctx); + + result = (TEMPLATE(T, equal)(c1, c2, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, print_pretty)(a, ctx), flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, print_pretty)(b, ctx), flint_printf("\n"); + flint_printf("c1 = "), TEMPLATE(T, print_pretty)(c1, ctx), flint_printf("\n"); + flint_printf("c2 = "), TEMPLATE(T, print_pretty)(c2, ctx), flint_printf("\n"); + abort(); + } + + TEMPLATE(T, clear)(a, ctx); + TEMPLATE(T, clear)(b, ctx); + TEMPLATE(T, clear)(c1, ctx); + TEMPLATE(T, clear)(c2, ctx); + + TEMPLATE(T, ctx_clear)(ctx); + } + + /* Check that (a + b) + c == a + (b + c) */ + for (i = 0; i < 2000; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, t) a, b, c, lhs, rhs; + + TEMPLATE(T, ctx_randtest)(ctx, state); + + TEMPLATE(T, init)(a, ctx); + TEMPLATE(T, init)(b, ctx); + TEMPLATE(T, init)(c, ctx); + TEMPLATE(T, init)(lhs, ctx); + TEMPLATE(T, init)(rhs, ctx); + + TEMPLATE(T, randtest)(a, state, ctx); + TEMPLATE(T, randtest)(b, state, ctx); + TEMPLATE(T, randtest)(c, state, ctx); + + TEMPLATE(T, add)(lhs, a, b, ctx); + TEMPLATE(T, add)(lhs, lhs, c, ctx); + TEMPLATE(T, add)(rhs, b, c, ctx); + TEMPLATE(T, add)(rhs, a, rhs, ctx); + + result = (TEMPLATE(T, equal)(lhs, rhs, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, print_pretty)(a, ctx), flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, print_pretty)(b, ctx), flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, print_pretty)(c, ctx), flint_printf("\n"); + flint_printf("lhs = "), TEMPLATE(T, print_pretty)(lhs, ctx), flint_printf("\n"); + flint_printf("rhs = "), TEMPLATE(T, print_pretty)(rhs, ctx), flint_printf("\n"); + abort(); + } + + TEMPLATE(T, clear)(a, ctx); + TEMPLATE(T, clear)(b, ctx); + TEMPLATE(T, clear)(c, ctx); + TEMPLATE(T, clear)(lhs, ctx); + TEMPLATE(T, clear)(rhs, ctx); + + TEMPLATE(T, ctx_clear)(ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + + + +#endif diff --git a/external/flint-2.4.3/fq_templates/test/t-ctx_init.c b/external/flint-2.4.3/fq_templates/test/t-ctx_init.c new file mode 100644 index 0000000..5ffc073 --- /dev/null +++ b/external/flint-2.4.3/fq_templates/test/t-ctx_init.c @@ -0,0 +1,120 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include + +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, k, result; + FLINT_TEST_INIT(state); + + flint_printf("ctx_init... "); + fflush(stdout); + + for (i = 0; i < 30; i++) { + fmpz_t p; + slong d; + TEMPLATE(T, ctx_t) ctx; + + fmpz_init(p); + fmpz_set_ui(p, n_randprime(state, 2 + n_randint(state, + FLINT_MIN(FLINT_BITS - 1, 50)), 1)); + d = n_randint(state, 20) + 1; + + TEMPLATE(T, ctx_init)(ctx, p, d, "a"); + TEMPLATE(T, ctx_clear)(ctx); + } + + for (i = 0; i < 30; i++) { + fmpz_t p; + slong d; + TEMPLATE(T, ctx_t) ctx_conway, ctx_mod; + + TEMPLATE(T, t) a, b, lhs, rhs; + + fmpz_init(p); + fmpz_set_ui(p, n_randprime(state, 2 + n_randint(state, 3), 1)); + d = n_randint(state, 10) + 1; + TEMPLATE(T, ctx_init_conway)(ctx_conway, p, d, "a"); + + TEMPLATE(T, ctx_init_modulus)(ctx_mod, ctx_conway->modulus, "a"); + + TEMPLATE(T, init)(a, ctx_conway); + TEMPLATE(T, init)(b, ctx_mod); + TEMPLATE(T, init)(lhs, ctx_conway); + TEMPLATE(T, init)(rhs, ctx_mod); + + for (k = 0; k < 30; k++) + { + + TEMPLATE(T, randtest)(a, state, ctx_conway); + TEMPLATE(T, set)(b, a, ctx_mod); + + TEMPLATE(T, mul)(lhs, a, a, ctx_conway); + TEMPLATE(T, mul)(rhs, b, b, ctx_mod); + + result = (TEMPLATE(T, equal)(lhs, rhs, ctx_mod)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, print_pretty)(a, ctx_conway), flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, print_pretty)(b, ctx_mod), flint_printf("\n"); + flint_printf("lhs = "), TEMPLATE(T, print_pretty)(lhs, ctx_conway), flint_printf("\n"); + flint_printf("rhs = "), TEMPLATE(T, print_pretty)(rhs, ctx_mod), flint_printf("\n"); + abort(); + } + + } + + TEMPLATE(T, clear)(a, ctx_conway); + TEMPLATE(T, clear)(b, ctx_mod); + TEMPLATE(T, clear)(lhs, ctx_conway); + TEMPLATE(T, clear)(rhs, ctx_mod); + + TEMPLATE(T, ctx_clear)(ctx_conway); + TEMPLATE(T, ctx_clear)(ctx_mod); + + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + + return EXIT_SUCCESS; +} + + +#endif diff --git a/external/flint-2.4.3/fq_templates/test/t-frobenius.c b/external/flint-2.4.3/fq_templates/test/t-frobenius.c new file mode 100644 index 0000000..a996605 --- /dev/null +++ b/external/flint-2.4.3/fq_templates/test/t-frobenius.c @@ -0,0 +1,246 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include + +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("frobenius... "); + fflush(stdout); + + /* Check aliasing */ + for (i = 0; i < 1000; i++) + { + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, t) a, b, c; + slong e; + + TEMPLATE(T, ctx_randtest)(ctx, state); + + TEMPLATE(T, init)(a, ctx); + TEMPLATE(T, init)(b, ctx); + TEMPLATE(T, init)(c, ctx); + + TEMPLATE(T, randtest)(a, state, ctx); + TEMPLATE(T, set)(b, a, ctx); + e = n_randint(state, 10) % TEMPLATE(T, ctx_degree)(ctx); + + TEMPLATE(T, frobenius)(c, b, e, ctx); + TEMPLATE(T, frobenius)(b, b, e, ctx); + + result = (TEMPLATE(T, equal)(b, c, ctx)); + if (!result) + { + flint_printf("FAIL (alias):\n\n"); + flint_printf("a = "), TEMPLATE(T, print_pretty)(a, ctx), flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, print_pretty)(b, ctx), flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, print_pretty)(c, ctx), flint_printf("\n"); + flint_printf("e = %wd\n", e); + abort(); + } + + TEMPLATE(T, clear)(a, ctx); + TEMPLATE(T, clear)(b, ctx); + TEMPLATE(T, clear)(c, ctx); + + TEMPLATE(T, ctx_clear)(ctx); + } + + /* Check sigma^e(x) == x^{p^e} */ + for (i = 0; i < 1000; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, t) a, b, c; + slong e; + + TEMPLATE(T, ctx_randtest)(ctx, state); + + TEMPLATE(T, init)(a, ctx); + TEMPLATE(T, init)(b, ctx); + TEMPLATE(T, init)(c, ctx); + + TEMPLATE(T, randtest)(a, state, ctx); + e = n_randint(state, 10) % TEMPLATE(T, ctx_degree)(ctx); + + TEMPLATE(T, frobenius)(b, a, e, ctx); + { + fmpz_t t; + + fmpz_init(t); + fmpz_pow_ui(t, TEMPLATE(T, ctx_prime)(ctx), e); + TEMPLATE(T, pow)(c, a, t, ctx); + fmpz_clear(t); + } + + result = (TEMPLATE(T, equal)(b,c,ctx)); + if (!result) + { + flint_printf("FAIL (sigma^e(x) = x^{p^e}):\n\n"); + flint_printf("a = "), TEMPLATE(T, print_pretty)(a, ctx), flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, print_pretty)(b, ctx), flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, print_pretty)(c, ctx), flint_printf("\n"); + flint_printf("e = %wd\n", e); + abort(); + } + + TEMPLATE(T, clear)(a, ctx); + TEMPLATE(T, clear)(b, ctx); + TEMPLATE(T, clear)(c, ctx); + + TEMPLATE(T, ctx_clear)(ctx); + } + + /* Check sigma^e(x + y) = sigma^e(x) + sigma^e(y) */ + for (i = 0; i < 1000; i++) + { + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, t) a, b, s, s1, s2, lhs, rhs; + slong e; + + TEMPLATE(T, ctx_randtest)(ctx, state); + + TEMPLATE(T, init)(a, ctx); + TEMPLATE(T, init)(b, ctx); + TEMPLATE(T, init)(s, ctx); + TEMPLATE(T, init)(s1, ctx); + TEMPLATE(T, init)(s2, ctx); + TEMPLATE(T, init)(lhs, ctx); + TEMPLATE(T, init)(rhs, ctx); + + TEMPLATE(T, randtest)(a, state, ctx); + TEMPLATE(T, randtest)(b, state, ctx); + e = n_randint(state, 10) % TEMPLATE(T, ctx_degree)(ctx); + + TEMPLATE(T, add)(s, a, b, ctx); + TEMPLATE(T, frobenius)(lhs, s, e, ctx); + TEMPLATE(T, frobenius)(s1, a, e, ctx); + TEMPLATE(T, frobenius)(s2, b, e, ctx); + TEMPLATE(T, add)(rhs, s1, s2, ctx); + + result = (TEMPLATE(T, equal)(lhs, rhs, ctx)); + if (!result) + { + flint_printf("FAIL (sigma(a+b) = sigma(a) + sigma(b)):\n\n"); + flint_printf("a = "), TEMPLATE(T, print_pretty)(a, ctx), flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, print_pretty)(b, ctx), flint_printf("\n"); + flint_printf("s = "), TEMPLATE(T, print_pretty)(s, ctx), flint_printf("\n"); + flint_printf("s1 = "), TEMPLATE(T, print_pretty)(s1, ctx), flint_printf("\n"); + flint_printf("s2 = "), TEMPLATE(T, print_pretty)(s2, ctx), flint_printf("\n"); + flint_printf("lhs = "), TEMPLATE(T, print_pretty)(lhs, ctx), flint_printf("\n"); + flint_printf("rhs = "), TEMPLATE(T, print_pretty)(rhs, ctx), flint_printf("\n"); + flint_printf("e = %wd\n", e); + abort(); + } + + TEMPLATE(T, clear)(a, ctx); + TEMPLATE(T, clear)(b, ctx); + TEMPLATE(T, clear)(s, ctx); + TEMPLATE(T, clear)(s1, ctx); + TEMPLATE(T, clear)(s2, ctx); + TEMPLATE(T, clear)(lhs, ctx); + TEMPLATE(T, clear)(rhs, ctx); + + TEMPLATE(T, ctx_clear)(ctx); + } + + /* Check sigma^e(x * y) = sigma^e(x) * sigma^e(y) on Zq */ + for (i = 0; i < 1000; i++) + { + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, t) a, b, s, s1, s2, lhs, rhs; + slong e; + + TEMPLATE(T, ctx_randtest)(ctx, state); + + TEMPLATE(T, init)(a, ctx); + TEMPLATE(T, init)(b, ctx); + TEMPLATE(T, init)(s, ctx); + TEMPLATE(T, init)(s1, ctx); + TEMPLATE(T, init)(s2, ctx); + TEMPLATE(T, init)(lhs, ctx); + TEMPLATE(T, init)(rhs, ctx); + + TEMPLATE(T, randtest)(a, state, ctx); + TEMPLATE(T, randtest)(b, state, ctx); + e = n_randint(state, 10) % TEMPLATE(T, ctx_degree)(ctx); + + TEMPLATE(T, mul)(s, a, b, ctx); + TEMPLATE(T, frobenius)(lhs, s, e, ctx); + TEMPLATE(T, frobenius)(s1, a, e, ctx); + TEMPLATE(T, frobenius)(s2, b, e, ctx); + TEMPLATE(T, mul)(rhs, s1, s2, ctx); + + result = (TEMPLATE(T, equal)(lhs, rhs, ctx)); + if (!result) + { + flint_printf("FAIL (sigma(a*b) = sigma(a) * sigma(b)):\n\n"); + flint_printf("a = "), TEMPLATE(T, print_pretty)(a, ctx), flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, print_pretty)(b, ctx), flint_printf("\n"); + flint_printf("s = "), TEMPLATE(T, print_pretty)(s, ctx), flint_printf("\n"); + flint_printf("s1 = "), TEMPLATE(T, print_pretty)(s1, ctx), flint_printf("\n"); + flint_printf("s2 = "), TEMPLATE(T, print_pretty)(s2, ctx), flint_printf("\n"); + flint_printf("lhs = "), TEMPLATE(T, print_pretty)(lhs, ctx), flint_printf("\n"); + flint_printf("rhs = "), TEMPLATE(T, print_pretty)(rhs, ctx), flint_printf("\n"); + flint_printf("e = %wd\n", e); + abort(); + } + + TEMPLATE(T, clear)(a, ctx); + TEMPLATE(T, clear)(b, ctx); + TEMPLATE(T, clear)(s, ctx); + TEMPLATE(T, clear)(s1, ctx); + TEMPLATE(T, clear)(s2, ctx); + TEMPLATE(T, clear)(lhs, ctx); + TEMPLATE(T, clear)(rhs, ctx); + + TEMPLATE(T, ctx_clear)(ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + + + +#endif diff --git a/external/flint-2.4.3/fq_templates/test/t-inv.c b/external/flint-2.4.3/fq_templates/test/t-inv.c new file mode 100644 index 0000000..21c247b --- /dev/null +++ b/external/flint-2.4.3/fq_templates/test/t-inv.c @@ -0,0 +1,125 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include + +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("inv... "); + fflush(stdout); + + /* Check aliasing: a = ~a */ + for (i = 0; i < 2000; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, t) a, b, c; + + TEMPLATE(T, ctx_randtest)(ctx, state); + + TEMPLATE(T, init)(a, ctx); + TEMPLATE(T, init)(b, ctx); + TEMPLATE(T, init)(c, ctx); + + TEMPLATE(T, randtest_not_zero)(a, state, ctx); + TEMPLATE(T, set)(b, a, ctx); + + TEMPLATE(T, inv)(c, b, ctx); + TEMPLATE(T, inv)(b, b, ctx); + + result = (TEMPLATE(T, equal)(b, c, ctx)); + if (!result) + { + flint_printf("FAIL (aliasing):\n\n"); + flint_printf("a = "), TEMPLATE(T, print_pretty)(a, ctx), flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, print_pretty)(b, ctx), flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, print_pretty)(c, ctx), flint_printf("\n"); + TEMPLATE(T, ctx_print)(ctx); + abort(); + } + + TEMPLATE(T, clear)(a, ctx); + TEMPLATE(T, clear)(b, ctx); + TEMPLATE(T, clear)(c, ctx); + + TEMPLATE(T, ctx_clear)(ctx); + } + + /* Check a * ~a == 1 for units*/ + for (i = 0; i < 2000; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, t) a, b, c; + + TEMPLATE(T, ctx_randtest)(ctx, state); + + TEMPLATE(T, init)(a, ctx); + TEMPLATE(T, init)(b, ctx); + TEMPLATE(T, init)(c, ctx); + + TEMPLATE(T, randtest_not_zero)(a, state, ctx); + + TEMPLATE(T, inv)(b, a, ctx); + TEMPLATE(T, mul)(c, a, b, ctx); + + result = (TEMPLATE(T, is_one)(c, ctx)); + if (!result) + { + flint_printf("FAIL (a * (~a) == 1):\n\n"); + flint_printf("a = "), TEMPLATE(T, print_pretty)(a, ctx), flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, print_pretty)(b, ctx), flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, print_pretty)(c, ctx), flint_printf("\n"); + abort(); + } + + TEMPLATE(T, clear)(a, ctx); + TEMPLATE(T, clear)(b, ctx); + TEMPLATE(T, clear)(c, ctx); + + TEMPLATE(T, ctx_clear)(ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + + + +#endif diff --git a/external/flint-2.4.3/fq_templates/test/t-mul.c b/external/flint-2.4.3/fq_templates/test/t-mul.c new file mode 100644 index 0000000..b50b4d9 --- /dev/null +++ b/external/flint-2.4.3/fq_templates/test/t-mul.c @@ -0,0 +1,240 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include + +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("mul... "); + fflush(stdout); + + /* Check aliasing: a = a * b */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, t) a, b, c; + + TEMPLATE(T, ctx_randtest)(ctx, state); + + TEMPLATE(T, init)(a, ctx); + TEMPLATE(T, init)(b, ctx); + TEMPLATE(T, init)(c, ctx); + + TEMPLATE(T, randtest)(a, state, ctx); + TEMPLATE(T, randtest)(b, state, ctx); + + TEMPLATE(T, mul)(c, a, b, ctx); + TEMPLATE(T, mul)(a, a, b, ctx); + + result = (TEMPLATE(T, equal)(a, c, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, print_pretty)(a, ctx), flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, print_pretty)(b, ctx), flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, print_pretty)(c, ctx), flint_printf("\n"); + abort(); + } + + TEMPLATE(T, clear)(a, ctx); + TEMPLATE(T, clear)(b, ctx); + TEMPLATE(T, clear)(c, ctx); + + TEMPLATE(T, ctx_clear)(ctx); + } + + /* Check aliasing: b = a * b */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, t) a, b, c; + + TEMPLATE(T, ctx_randtest)(ctx, state); + + TEMPLATE(T, init)(a, ctx); + TEMPLATE(T, init)(b, ctx); + TEMPLATE(T, init)(c, ctx); + + TEMPLATE(T, randtest)(a, state, ctx); + TEMPLATE(T, randtest)(b, state, ctx); + + TEMPLATE(T, mul)(c, a, b, ctx); + TEMPLATE(T, mul)(b, a, b, ctx); + + result = (TEMPLATE(T, equal)(b, c, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, print_pretty)(a, ctx), flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, print_pretty)(b, ctx), flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, print_pretty)(c, ctx), flint_printf("\n"); + abort(); + } + + TEMPLATE(T, clear)(a, ctx); + TEMPLATE(T, clear)(b, ctx); + TEMPLATE(T, clear)(c, ctx); + + TEMPLATE(T, ctx_clear)(ctx); + } + + /* Check aliasing: a = a * a */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, t) a, c; + + TEMPLATE(T, ctx_randtest)(ctx, state); + + TEMPLATE(T, init)(a, ctx); + TEMPLATE(T, init)(c, ctx); + + TEMPLATE(T, randtest)(a, state, ctx); + + TEMPLATE(T, mul)(c, a, a, ctx); + TEMPLATE(T, mul)(a, a, a, ctx); + + result = (TEMPLATE(T, equal)(a, c, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, print_pretty)(a, ctx), flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, print_pretty)(c, ctx), flint_printf("\n"); + abort(); + } + + TEMPLATE(T, clear)(a, ctx); + TEMPLATE(T, clear)(c, ctx); + + TEMPLATE(T, ctx_clear)(ctx); + } + + /* Check that a * b == b * a */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, t) a, b, c1, c2; + + TEMPLATE(T, ctx_randtest)(ctx, state); + + TEMPLATE(T, init)(a, ctx); + TEMPLATE(T, init)(b, ctx); + TEMPLATE(T, init)(c1, ctx); + TEMPLATE(T, init)(c2, ctx); + + TEMPLATE(T, randtest)(a, state, ctx); + TEMPLATE(T, randtest)(b, state, ctx); + + TEMPLATE(T, mul)(c1, a, b, ctx); + TEMPLATE(T, mul)(c2, b, a, ctx); + + result = (TEMPLATE(T, equal)(c1, c2, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, print_pretty)(a, ctx), flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, print_pretty)(b, ctx), flint_printf("\n"); + flint_printf("c1 = "), TEMPLATE(T, print_pretty)(c1, ctx), flint_printf("\n"); + flint_printf("c2 = "), TEMPLATE(T, print_pretty)(c2, ctx), flint_printf("\n"); + abort(); + } + + TEMPLATE(T, clear)(a, ctx); + TEMPLATE(T, clear)(b, ctx); + TEMPLATE(T, clear)(c1, ctx); + TEMPLATE(T, clear)(c2, ctx); + + TEMPLATE(T, ctx_clear)(ctx); + } + + /* Check that (a * b) * c == a * (b * c) */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, t) a, b, c, lhs, rhs; + + TEMPLATE(T, ctx_randtest)(ctx, state); + + TEMPLATE(T, init)(a, ctx); + TEMPLATE(T, init)(b, ctx); + TEMPLATE(T, init)(c, ctx); + TEMPLATE(T, init)(lhs, ctx); + TEMPLATE(T, init)(rhs, ctx); + + TEMPLATE(T, randtest)(a, state, ctx); + TEMPLATE(T, randtest)(b, state, ctx); + TEMPLATE(T, randtest)(c, state, ctx); + + TEMPLATE(T, mul)(lhs, a, b, ctx); + TEMPLATE(T, mul)(lhs, lhs, c, ctx); + TEMPLATE(T, mul)(rhs, b, c, ctx); + TEMPLATE(T, mul)(rhs, a, rhs, ctx); + + result = (TEMPLATE(T, equal)(lhs, rhs, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, print_pretty)(a, ctx), flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, print_pretty)(b, ctx), flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, print_pretty)(c, ctx), flint_printf("\n"); + flint_printf("lhs = "), TEMPLATE(T, print_pretty)(lhs, ctx), flint_printf("\n"); + flint_printf("rhs = "), TEMPLATE(T, print_pretty)(rhs, ctx), flint_printf("\n"); + abort(); + } + + TEMPLATE(T, clear)(a, ctx); + TEMPLATE(T, clear)(b, ctx); + TEMPLATE(T, clear)(c, ctx); + TEMPLATE(T, clear)(lhs, ctx); + TEMPLATE(T, clear)(rhs, ctx); + + TEMPLATE(T, ctx_clear)(ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + + + +#endif diff --git a/external/flint-2.4.3/fq_templates/test/t-mul_fmpz.c b/external/flint-2.4.3/fq_templates/test/t-mul_fmpz.c new file mode 100644 index 0000000..53d1baf --- /dev/null +++ b/external/flint-2.4.3/fq_templates/test/t-mul_fmpz.c @@ -0,0 +1,128 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("mul_fmpz...."); + fflush(stdout); + + /* Check aliasing of a, b */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + fmpz_t x; + TEMPLATE(T, t) a, b; + + TEMPLATE(T, ctx_randtest)(ctx, state); + + TEMPLATE(T, init)(a, ctx); + TEMPLATE(T, init)(b, ctx); + fmpz_init(x); + + TEMPLATE(T, randtest)(a, state, ctx); + fmpz_randtest_mod_signed(x,state,TEMPLATE(T, ctx_prime)(ctx)); + TEMPLATE(T, mul_fmpz)(b, a, x, ctx); + TEMPLATE(T, mul_fmpz)(a, a, x, ctx); + + result = (TEMPLATE(T, equal)(a, b, ctx)); + if (!result) + { + flint_printf("fail:\n\n"); + flint_printf("a = "), TEMPLATE(T, print_pretty)(a, ctx), flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, print_pretty)(b, ctx), flint_printf("\n"); + flint_printf("x = "), fmpz_print(x), flint_printf("\n"); + abort(); + } + + TEMPLATE(T, clear)(a, ctx); + TEMPLATE(T, clear)(b, ctx); + fmpz_clear(x); + TEMPLATE(T, ctx_clear)(ctx); + } + + /* compare with direct multiplication */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + fmpz_t x; + TEMPLATE(T, t) a, c; + fmpz_poly_t b; + + TEMPLATE(T, ctx_randtest)(ctx, state); + + TEMPLATE(T, init)(a, ctx); + TEMPLATE(T, init)(c, ctx); + fmpz_init(x); + fmpz_poly_init(b); + + TEMPLATE(T, randtest)(a, state, ctx); + fmpz_randtest_mod_signed(x,state,TEMPLATE(T, ctx_prime)(ctx)); + TEMPLATE(T, mul_fmpz)(c, a, x, ctx); + fmpz_poly_scalar_mul_fmpz(b,a,x); + TEMPLATE(T, reduce)(b,ctx); + + + result = (TEMPLATE(T, equal)(c, b, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, print_pretty)(a, ctx), flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, print_pretty)(b, ctx), flint_printf("\n"); + flint_printf("x = "), fmpz_print(x), flint_printf("\n"); + abort(); + } + + TEMPLATE(T, clear)(a, ctx); + TEMPLATE(T, clear)(c, ctx); + fmpz_poly_clear(b); + fmpz_clear(x); + TEMPLATE(T, ctx_clear)(ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_templates/test/t-mul_si.c b/external/flint-2.4.3/fq_templates/test/t-mul_si.c new file mode 100644 index 0000000..ae512f8 --- /dev/null +++ b/external/flint-2.4.3/fq_templates/test/t-mul_si.c @@ -0,0 +1,125 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("mul_si...."); + fflush(stdout); + + /* Check aliasing of a, b */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + slong x; + TEMPLATE(T, t) a, b; + + TEMPLATE(T, ctx_randtest)(ctx, state); + + TEMPLATE(T, init)(a, ctx); + TEMPLATE(T, init)(b, ctx); + + TEMPLATE(T, randtest)(a, state, ctx); + x = z_randtest(state); + TEMPLATE(T, mul_si)(b, a, x, ctx); + TEMPLATE(T, mul_si)(a, a, x, ctx); + + result = (TEMPLATE(T, equal)(a, b, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, print_pretty)(a, ctx), flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, print_pretty)(b, ctx), flint_printf("\n"); + flint_printf("x = %wd\n",x); + abort(); + } + + TEMPLATE(T, clear)(a, ctx); + TEMPLATE(T, clear)(b, ctx); + + TEMPLATE(T, ctx_clear)(ctx); + } + + /* compare with direct multiplication */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + slong x; + TEMPLATE(T, t) a, c; + fmpz_poly_t b; + + TEMPLATE(T, ctx_randtest)(ctx, state); + + TEMPLATE(T, init)(a, ctx); + TEMPLATE(T, init)(c, ctx); + fmpz_poly_init(b); + + TEMPLATE(T, randtest)(a, state, ctx); + x = z_randtest(state); + TEMPLATE(T, mul_si)(c, a, x, ctx); + fmpz_poly_scalar_mul_si(b,a,x); + TEMPLATE(T, reduce)(b,ctx); + + + result = (TEMPLATE(T, equal)(c, b, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, print_pretty)(a, ctx), flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, print_pretty)(b, ctx), flint_printf("\n"); + flint_printf("x = %wd\n",x); + abort(); + } + + TEMPLATE(T, clear)(a, ctx); + TEMPLATE(T, clear)(c, ctx); + fmpz_poly_clear(b); + TEMPLATE(T, ctx_clear)(ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_templates/test/t-mul_ui.c b/external/flint-2.4.3/fq_templates/test/t-mul_ui.c new file mode 100644 index 0000000..e2d7538 --- /dev/null +++ b/external/flint-2.4.3/fq_templates/test/t-mul_ui.c @@ -0,0 +1,125 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("mul_ui...."); + fflush(stdout); + + /* Check aliasing of a, b */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + ulong x; + TEMPLATE(T, t) a, b; + + TEMPLATE(T, ctx_randtest)(ctx, state); + + TEMPLATE(T, init)(a, ctx); + TEMPLATE(T, init)(b, ctx); + + TEMPLATE(T, randtest)(a, state, ctx); + x = z_randtest(state); + TEMPLATE(T, mul_ui)(b, a, x, ctx); + TEMPLATE(T, mul_ui)(a, a, x, ctx); + + result = (TEMPLATE(T, equal)(a, b, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, print_pretty)(a, ctx), flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, print_pretty)(b, ctx), flint_printf("\n"); + flint_printf("x = %wu\n",x); + abort(); + } + + TEMPLATE(T, clear)(a, ctx); + TEMPLATE(T, clear)(b, ctx); + + TEMPLATE(T, ctx_clear)(ctx); + } + + /* compare with direct multiplication */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + TEMPLATE(T, ctx_t) ctx; + ulong x; + TEMPLATE(T, t) a, c; + fmpz_poly_t b; + + TEMPLATE(T, ctx_randtest)(ctx, state); + + TEMPLATE(T, init)(a, ctx); + TEMPLATE(T, init)(c, ctx); + fmpz_poly_init(b); + + TEMPLATE(T, randtest)(a, state, ctx); + x = z_randtest(state); + TEMPLATE(T, mul_ui)(c, a, x, ctx); + fmpz_poly_scalar_mul_ui(b,a,x); + TEMPLATE(T, reduce)(b,ctx); + + + result = (TEMPLATE(T, equal)(c, b, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, print_pretty)(a, ctx), flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, print_pretty)(b, ctx), flint_printf("\n"); + flint_printf("x = %wu\n",x); + abort(); + } + + TEMPLATE(T, clear)(a, ctx); + TEMPLATE(T, clear)(c, ctx); + fmpz_poly_clear(b); + TEMPLATE(T, ctx_clear)(ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_templates/test/t-neg.c b/external/flint-2.4.3/fq_templates/test/t-neg.c new file mode 100644 index 0000000..418faf0 --- /dev/null +++ b/external/flint-2.4.3/fq_templates/test/t-neg.c @@ -0,0 +1,129 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include + +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("neg... "); + fflush(stdout); + + /* Check aliasing: a = -a */ + for (i = 0; i < 2000; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, t) a, b, c; + + TEMPLATE(T, ctx_randtest)(ctx, state); + + TEMPLATE(T, init)(a, ctx); + TEMPLATE(T, init)(b, ctx); + TEMPLATE(T, init)(c, ctx); + + TEMPLATE(T, randtest)(a, state, ctx); + TEMPLATE(T, set)(b, a, ctx); + + TEMPLATE(T, neg)(c, b, ctx); + TEMPLATE(T, neg)(b, b, ctx); + + result = (TEMPLATE(T, equal)(b, c, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, print_pretty)(a, ctx), flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, print_pretty)(b, ctx), flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, print_pretty)(c, ctx), flint_printf("\n"); + abort(); + } + + TEMPLATE(T, clear)(a, ctx); + TEMPLATE(T, clear)(b, ctx); + TEMPLATE(T, clear)(c, ctx); + + TEMPLATE(T, ctx_clear)(ctx); + } + + /* Check a - b == a + (-b) */ + for (i = 0; i < 2000; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, t) a, b, c1, c2; + + TEMPLATE(T, ctx_randtest)(ctx, state); + + TEMPLATE(T, init)(a, ctx); + TEMPLATE(T, init)(b, ctx); + TEMPLATE(T, init)(c1, ctx); + TEMPLATE(T, init)(c2, ctx); + + TEMPLATE(T, randtest)(a, state, ctx); + TEMPLATE(T, randtest)(b, state, ctx); + + TEMPLATE(T, sub)(c1, a, b, ctx); + TEMPLATE(T, neg)(c2, b, ctx); + TEMPLATE(T, add)(c2, a, c2, ctx); + + result = (TEMPLATE(T, equal)(c1, c2, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, print_pretty)(a, ctx), flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, print_pretty)(b, ctx), flint_printf("\n"); + flint_printf("c1 = "), TEMPLATE(T, print_pretty)(c1, ctx), flint_printf("\n"); + flint_printf("c2 = "), TEMPLATE(T, print_pretty)(c2, ctx), flint_printf("\n"); + abort(); + } + + TEMPLATE(T, clear)(a, ctx); + TEMPLATE(T, clear)(b, ctx); + TEMPLATE(T, clear)(c1, ctx); + TEMPLATE(T, clear)(c2, ctx); + + TEMPLATE(T, ctx_clear)(ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + + + +#endif diff --git a/external/flint-2.4.3/fq_templates/test/t-norm.c b/external/flint-2.4.3/fq_templates/test/t-norm.c new file mode 100644 index 0000000..170447f --- /dev/null +++ b/external/flint-2.4.3/fq_templates/test/t-norm.c @@ -0,0 +1,110 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include + +#include "ulong_extras.h" +#include "long_extras.h" +#include "fmpz_poly.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("norm... "); + fflush(stdout); + + /* Compare with product of Galois conjugates */ + for (i = 0; i < 2000; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, t) a, b, c; + fmpz_t x, y; + slong j; + + TEMPLATE(T, ctx_randtest)(ctx, state); + + TEMPLATE(T, init)(a, ctx); + TEMPLATE(T, init)(b, ctx); + TEMPLATE(T, init)(c, ctx); + fmpz_init(x); + fmpz_init(y); + + TEMPLATE(T, randtest)(a, state, ctx); + TEMPLATE(T, reduce)(a, ctx); + + TEMPLATE(T, norm)(x, a, ctx); + + TEMPLATE(T, one)(b, ctx); + for (j = 0; j < TEMPLATE(T, ctx_degree)(ctx); j++) + { + TEMPLATE(T, frobenius)(c, a, j, ctx); + TEMPLATE(T, mul)(b, b, c, ctx); + } + + TEMPLATE(T, zero)(c, ctx); + TEMPLATE(T, set_fmpz)(c, x, ctx); + + result = TEMPLATE(T, equal)(b, c, ctx); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, print_pretty)(a, ctx), flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, print_pretty)(b, ctx), flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, print_pretty)(c, ctx), flint_printf("\n"); + flint_printf("x = "), fmpz_print(x), flint_printf("\n"); + for (j = 0; j < TEMPLATE(T, ctx_degree)(ctx); j++) + { + TEMPLATE(T, frobenius)(c, a, j, ctx); + flint_printf("sigma^%wd = ", j), TEMPLATE(T, print_pretty)(c, ctx), flint_printf("\n"); + } + abort(); + } + + TEMPLATE(T, clear)(a, ctx); + TEMPLATE(T, clear)(b, ctx); + TEMPLATE(T, clear)(c, ctx); + fmpz_clear(x); + fmpz_clear(y); + + TEMPLATE(T, ctx_clear)(ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + + +#endif diff --git a/external/flint-2.4.3/fq_templates/test/t-pow.c b/external/flint-2.4.3/fq_templates/test/t-pow.c new file mode 100644 index 0000000..e22cd61 --- /dev/null +++ b/external/flint-2.4.3/fq_templates/test/t-pow.c @@ -0,0 +1,136 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include + +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("pow... "); + fflush(stdout); + + /* Check aliasing: a = a^e */ + for (i = 0; i < 1000; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, t) a, b; + fmpz_t e; + + TEMPLATE(T, ctx_randtest)(ctx, state); + + TEMPLATE(T, init)(a, ctx); + TEMPLATE(T, init)(b, ctx); + fmpz_init(e); + + TEMPLATE(T, randtest)(a, state, ctx); + fmpz_randtest_unsigned(e, state, 6); + + TEMPLATE(T, pow)(b, a, e, ctx); + TEMPLATE(T, pow)(a, a, e, ctx); + + result = (TEMPLATE(T, equal)(a, b, ctx)); + if (!result) + { + flint_printf("FAIL (alias):\n\n"); + flint_printf("a = "), TEMPLATE(T, print_pretty)(a, ctx), flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, print_pretty)(b, ctx), flint_printf("\n"); + abort(); + } + + TEMPLATE(T, clear)(a, ctx); + TEMPLATE(T, clear)(b, ctx); + fmpz_clear(e); + + TEMPLATE(T, ctx_clear)(ctx); + } + + /* Compare with multiplication, for integral values */ + for (i = 0; i < 1000; i++) + { + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, t) a, b, c; + fmpz_t e, f; + + TEMPLATE(T, ctx_randtest)(ctx, state); + + TEMPLATE(T, init)(a, ctx); + TEMPLATE(T, init)(b, ctx); + TEMPLATE(T, init)(c, ctx); + fmpz_init(f); + fmpz_init(e); + + TEMPLATE(T, randtest)(a, state, ctx); + fmpz_randtest_unsigned(e, state, 6); + + TEMPLATE(T, pow)(b, a, e, ctx); + TEMPLATE(T, one)(c, ctx); + for (fmpz_one(f); fmpz_cmp(f, e) <= 0; fmpz_add_ui(f, f, 1)) + { + TEMPLATE(T, mul)(c, c, a, ctx); + } + + result = (TEMPLATE(T, equal)(b, c, ctx)); + if (!result) + { + flint_printf("FAIL (cmp with mul):\n\n"); + flint_printf("a = "), TEMPLATE(T, print_pretty)(a, ctx), flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, print_pretty)(b, ctx), flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, print_pretty)(b, ctx), flint_printf("\n"); + flint_printf("e = "), fmpz_print(e), flint_printf("\n"); + abort(); + } + + TEMPLATE(T, clear)(a, ctx); + TEMPLATE(T, clear)(b, ctx); + TEMPLATE(T, clear)(c, ctx); + fmpz_clear(e); + fmpz_clear(f); + + TEMPLATE(T, ctx_clear)(ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + + + +#endif diff --git a/external/flint-2.4.3/fq_templates/test/t-pth_root.c b/external/flint-2.4.3/fq_templates/test/t-pth_root.c new file mode 100644 index 0000000..8aab41f --- /dev/null +++ b/external/flint-2.4.3/fq_templates/test/t-pth_root.c @@ -0,0 +1,84 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include + +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("pth_root... "); + fflush(stdout); + + /* Compare with sum of Galois conjugates */ + for (i = 0; i < 1000; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, t) a, b; + + TEMPLATE(T, ctx_randtest)(ctx, state); + + TEMPLATE(T, init)(a, ctx); + TEMPLATE(T, init)(b, ctx); + + TEMPLATE(T, randtest)(a, state, ctx); + TEMPLATE(T, pth_root)(b, a, ctx); + TEMPLATE(T, pow)(b, b, TEMPLATE(T, ctx_prime)(ctx), ctx); + + result = TEMPLATE(T, equal)(a, b, ctx); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, print_pretty)(a, ctx), flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, print_pretty)(b, ctx), flint_printf("\n"); + abort(); + } + + TEMPLATE(T, clear)(a, ctx); + TEMPLATE(T, clear)(b, ctx); + + TEMPLATE(T, ctx_clear)(ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + + + +#endif diff --git a/external/flint-2.4.3/fq_templates/test/t-sqr.c b/external/flint-2.4.3/fq_templates/test/t-sqr.c new file mode 100644 index 0000000..e7f0ce9 --- /dev/null +++ b/external/flint-2.4.3/fq_templates/test/t-sqr.c @@ -0,0 +1,127 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include + +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("sqr... "); + fflush(stdout); + + /* Check aliasing: a = a * a */ + for (i = 0; i < 2000; i++) + { + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, t) a, c; + + TEMPLATE(T, ctx_randtest)(ctx, state); + + TEMPLATE(T, init)(a, ctx); + TEMPLATE(T, init)(c, ctx); + + TEMPLATE(T, randtest)(a, state, ctx); + + TEMPLATE(T, sqr)(c, a, ctx); + TEMPLATE(T, sqr)(a, a, ctx); + + result = (TEMPLATE(T, equal)(a, c, ctx)); + if (!result) + { + flint_printf("FAIL (aliasing):\n\n"); + flint_printf("a = "), TEMPLATE(T, print_pretty)(a, ctx), flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, print_pretty)(c, ctx), flint_printf("\n"); + abort(); + } + + TEMPLATE(T, clear)(a, ctx); + TEMPLATE(T, clear)(c, ctx); + + TEMPLATE(T, ctx_clear)(ctx); + } + + /* Check a^2 + a^2 = a(a + a) */ + for (i = 0; i < 2000; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, t) a, b, c, d; + + TEMPLATE(T, ctx_randtest)(ctx, state); + + TEMPLATE(T, init)(a, ctx); + TEMPLATE(T, init)(b, ctx); + TEMPLATE(T, init)(c, ctx); + TEMPLATE(T, init)(d, ctx); + + TEMPLATE(T, randtest)(a, state, ctx); + + TEMPLATE(T, sqr)(b, a, ctx); + TEMPLATE(T, add)(c, b, b, ctx); + + TEMPLATE(T, add)(d, a, a, ctx); + TEMPLATE(T, mul)(d, a, d, ctx); + + result = (TEMPLATE(T, equal)(c, d, ctx)); + if (!result) + { + flint_printf("FAIL (a^2 + a^2 == a(a + a)):\n\n"); + flint_printf("a = "), TEMPLATE(T, print_pretty)(a, ctx), flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, print_pretty)(b, ctx), flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, print_pretty)(c, ctx), flint_printf("\n"); + flint_printf("d = "), TEMPLATE(T, print_pretty)(d, ctx), flint_printf("\n"); + abort(); + } + + TEMPLATE(T, clear)(a, ctx); + TEMPLATE(T, clear)(b, ctx); + TEMPLATE(T, clear)(c, ctx); + TEMPLATE(T, clear)(d, ctx); + + TEMPLATE(T, ctx_clear)(ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + + + +#endif diff --git a/external/flint-2.4.3/fq_templates/test/t-sub.c b/external/flint-2.4.3/fq_templates/test/t-sub.c new file mode 100644 index 0000000..158131e --- /dev/null +++ b/external/flint-2.4.3/fq_templates/test/t-sub.c @@ -0,0 +1,240 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include + +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("sub... "); + fflush(stdout); + + /* Check aliasing: a = a - b */ + for (i = 0; i < 2000; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, t) a, b, c; + + TEMPLATE(T, ctx_randtest)(ctx, state); + + TEMPLATE(T, init)(a, ctx); + TEMPLATE(T, init)(b, ctx); + TEMPLATE(T, init)(c, ctx); + + TEMPLATE(T, randtest)(a, state, ctx); + TEMPLATE(T, randtest)(b, state, ctx); + + TEMPLATE(T, sub)(c, a, b, ctx); + TEMPLATE(T, sub)(a, a, b, ctx); + + result = (TEMPLATE(T, equal)(a, c, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, print_pretty)(a, ctx), flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, print_pretty)(b, ctx), flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, print_pretty)(c, ctx), flint_printf("\n"); + abort(); + } + + TEMPLATE(T, clear)(a, ctx); + TEMPLATE(T, clear)(b, ctx); + TEMPLATE(T, clear)(c, ctx); + + TEMPLATE(T, ctx_clear)(ctx); + } + + /* Check aliasing: b = a - b */ + for (i = 0; i < 2000; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, t) a, b, c; + + TEMPLATE(T, ctx_randtest)(ctx, state); + + TEMPLATE(T, init)(a, ctx); + TEMPLATE(T, init)(b, ctx); + TEMPLATE(T, init)(c, ctx); + + TEMPLATE(T, randtest)(a, state, ctx); + TEMPLATE(T, randtest)(b, state, ctx); + + TEMPLATE(T, sub)(c, a, b, ctx); + TEMPLATE(T, sub)(b, a, b, ctx); + + result = (TEMPLATE(T, equal)(b, c, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, print_pretty)(a, ctx), flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, print_pretty)(b, ctx), flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, print_pretty)(c, ctx), flint_printf("\n"); + abort(); + } + + TEMPLATE(T, clear)(a, ctx); + TEMPLATE(T, clear)(b, ctx); + TEMPLATE(T, clear)(c, ctx); + + TEMPLATE(T, ctx_clear)(ctx); + } + + /* Check aliasing: a = a - a */ + for (i = 0; i < 2000; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, t) a, c; + + TEMPLATE(T, ctx_randtest)(ctx, state); + + TEMPLATE(T, init)(a, ctx); + TEMPLATE(T, init)(c, ctx); + + TEMPLATE(T, randtest)(a, state, ctx); + + TEMPLATE(T, sub)(c, a, a, ctx); + TEMPLATE(T, sub)(a, a, a, ctx); + + result = (TEMPLATE(T, equal)(a, c, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, print_pretty)(a, ctx), flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, print_pretty)(c, ctx), flint_printf("\n"); + abort(); + } + + TEMPLATE(T, clear)(a, ctx); + TEMPLATE(T, clear)(c, ctx); + + TEMPLATE(T, ctx_clear)(ctx); + } + + /* Check that a - b == -(b - a) */ + for (i = 0; i < 2000; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, t) a, b, c1, c2; + + TEMPLATE(T, ctx_randtest)(ctx, state); + + TEMPLATE(T, init)(a, ctx); + TEMPLATE(T, init)(b, ctx); + TEMPLATE(T, init)(c1, ctx); + TEMPLATE(T, init)(c2, ctx); + + TEMPLATE(T, randtest)(a, state, ctx); + TEMPLATE(T, randtest)(b, state, ctx); + + TEMPLATE(T, sub)(c1, a, b, ctx); + TEMPLATE(T, sub)(c2, b, a, ctx); + TEMPLATE(T, neg)(c2, c2, ctx); + + result = (TEMPLATE(T, equal)(c1, c2, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, print_pretty)(a, ctx), flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, print_pretty)(b, ctx), flint_printf("\n"); + flint_printf("c1 = "), TEMPLATE(T, print_pretty)(c1, ctx), flint_printf("\n"); + flint_printf("c2 = "), TEMPLATE(T, print_pretty)(c2, ctx), flint_printf("\n"); + abort(); + } + + TEMPLATE(T, clear)(a, ctx); + TEMPLATE(T, clear)(b, ctx); + TEMPLATE(T, clear)(c1, ctx); + TEMPLATE(T, clear)(c2, ctx); + + TEMPLATE(T, ctx_clear)(ctx); + } + + /* Check that (a - b) - c == a - (b + c) */ + for (i = 0; i < 2000; i++) + { + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, t) a, b, c, lhs, rhs; + + TEMPLATE(T, ctx_randtest)(ctx, state); + + TEMPLATE(T, init)(a, ctx); + TEMPLATE(T, init)(b, ctx); + TEMPLATE(T, init)(c, ctx); + TEMPLATE(T, init)(lhs, ctx); + TEMPLATE(T, init)(rhs, ctx); + + TEMPLATE(T, randtest)(a, state, ctx); + TEMPLATE(T, randtest)(b, state, ctx); + TEMPLATE(T, randtest)(c, state, ctx); + + TEMPLATE(T, sub)(lhs, a, b, ctx); + TEMPLATE(T, sub)(lhs, lhs, c, ctx); + TEMPLATE(T, add)(rhs, b, c, ctx); + TEMPLATE(T, sub)(rhs, a, rhs, ctx); + + result = (TEMPLATE(T, equal)(lhs, rhs, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, print_pretty)(a, ctx), flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, print_pretty)(b, ctx), flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, print_pretty)(c, ctx), flint_printf("\n"); + flint_printf("lhs = "), TEMPLATE(T, print_pretty)(lhs, ctx), flint_printf("\n"); + flint_printf("rhs = "), TEMPLATE(T, print_pretty)(rhs, ctx), flint_printf("\n"); + abort(); + } + + TEMPLATE(T, clear)(a, ctx); + TEMPLATE(T, clear)(b, ctx); + TEMPLATE(T, clear)(c, ctx); + TEMPLATE(T, clear)(lhs, ctx); + TEMPLATE(T, clear)(rhs, ctx); + + TEMPLATE(T, ctx_clear)(ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + + + +#endif diff --git a/external/flint-2.4.3/fq_templates/test/t-trace.c b/external/flint-2.4.3/fq_templates/test/t-trace.c new file mode 100644 index 0000000..f075c2c --- /dev/null +++ b/external/flint-2.4.3/fq_templates/test/t-trace.c @@ -0,0 +1,109 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include + +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("trace... "); + fflush(stdout); + + /* Compare with sum of Galois conjugates */ + for (i = 0; i < 2000; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, t) a, b, c; + fmpz_t x, y; + slong j; + + TEMPLATE(T, ctx_randtest)(ctx, state); + + TEMPLATE(T, init)(a, ctx); + TEMPLATE(T, init)(b, ctx); + TEMPLATE(T, init)(c, ctx); + fmpz_init(x); + fmpz_init(y); + + TEMPLATE(T, randtest)(a, state, ctx); + + TEMPLATE(T, trace)(x, a, ctx); + + TEMPLATE(T, zero)(b, ctx); + for (j = 0; j < TEMPLATE(T, ctx_degree)(ctx); j++) + { + TEMPLATE(T, frobenius)(c, a, j, ctx); + TEMPLATE(T, add)(b, b, c, ctx); + } + + TEMPLATE(T, zero)(c, ctx); + TEMPLATE(T, set_fmpz)(c, x, ctx); + + result = TEMPLATE(T, equal)(b, c, ctx); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), TEMPLATE(T, print_pretty)(a, ctx), flint_printf("\n"); + flint_printf("b = "), TEMPLATE(T, print_pretty)(b, ctx), flint_printf("\n"); + flint_printf("c = "), TEMPLATE(T, print_pretty)(c, ctx), flint_printf("\n"); + flint_printf("x = "), fmpz_print(x), flint_printf("\n"); + for (j = 0; j < TEMPLATE(T, ctx_degree)(ctx); j++) + { + TEMPLATE(T, frobenius)(c, a, j, ctx); + flint_printf("sigma^%wd = ", j), TEMPLATE(T, print_pretty)(c, ctx), flint_printf("\n"); + } + abort(); + } + + TEMPLATE(T, clear)(a, ctx); + TEMPLATE(T, clear)(b, ctx); + TEMPLATE(T, clear)(c, ctx); + fmpz_clear(x); + fmpz_clear(y); + + TEMPLATE(T, ctx_clear)(ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + + + +#endif diff --git a/external/flint-2.4.3/fq_vec.h b/external/flint-2.4.3/fq_vec.h new file mode 100644 index 0000000..aa155b6 --- /dev/null +++ b/external/flint-2.4.3/fq_vec.h @@ -0,0 +1,57 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#ifndef FQ_VEC_H +#define FQ_VEC_H + +#include "fq.h" + +#define FQ_VEC_NORM(vec, i, ctx) \ +do { \ + while ((i) && fq_is_zero((vec) + (i) - 1, ctx)) \ + (i)--; \ +} while (0) + + +#define FQ_VEC_SWAP(vec1, len1, vec2, len2) \ +do { \ + fq_struct *__t; \ + slong __tn; \ + __t = (vec1); \ + (vec1) = (vec2); \ + (vec2) = __t; \ + __tn = (len1); \ + (len1) = (len2); \ + (len2) = __tn; \ +} while (0); + + +#define T fq +#define CAP_T FQ +#include "fq_vec_templates.h" +#undef CAP_T +#undef T + +#endif diff --git a/external/flint-2.4.3/fq_vec/add.c b/external/flint-2.4.3/fq_vec/add.c new file mode 100644 index 0000000..23c9098 --- /dev/null +++ b/external/flint-2.4.3/fq_vec/add.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_vec_templates/add.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_vec/clear.c b/external/flint-2.4.3/fq_vec/clear.c new file mode 100644 index 0000000..f916e1f --- /dev/null +++ b/external/flint-2.4.3/fq_vec/clear.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_vec_templates/clear.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_vec/doc/fq_vec.txt b/external/flint-2.4.3/fq_vec/doc/fq_vec.txt new file mode 100644 index 0000000..a520aeb --- /dev/null +++ b/external/flint-2.4.3/fq_vec/doc/fq_vec.txt @@ -0,0 +1,159 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ +******************************************************************************* + + Memory management + +******************************************************************************* + +fq_struct * _fq_vec_init(slong len, const fq_ctx_t ctx) + + Returns an initialised vector of \code{fq}'s of given length. + +void _fq_vec_clear(fq * vec, slong len, const fq_ctx_t ctx) + + Clears the entries of \code{(vec, len)} and frees the space allocated + for \code{vec}. + +******************************************************************************* + + Randomisation + +******************************************************************************* + +void _fq_vec_randtest(fq_struct * f, flint_rand_t state, + slong len, const fq_ctx_t ctx) + + Sets the entries of a vector of the given length to elements of + the finite field. + +******************************************************************************* + + Input and output + +******************************************************************************* + +int _fq_vec_fprint(FILE * file, const fq_struct * vec, slong len, + const fq_ctx_t ctx) + + Prints the vector of given length to the stream \code{file}. The + format is the length followed by two spaces, then a space separated + list of coefficients. If the length is zero, only $0$ is printed. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + +int _fq_vec_print(const fq_struct * vec, slong len, const fq_ctx_t ctx) + + Prints the vector of given length to \code{stdout}. + + For further details, see \code{_fq_vec_fprint()}. + +******************************************************************************* + + Assignment and basic manipulation + +******************************************************************************* + +void _fq_vec_set(fq_struct * vec1, const fq_struct * vec2, slong len2, + const fq_ctx_t ctx) + + Makes a copy of \code{(vec2, len2)} into \code{vec1}. + +void _fq_vec_swap(fq_struct * vec1, fq_struct * vec2, slong len2, + const fq_ctx_t ctx) + + Swaps the elements in \code{(vec1, len2)} and \code{(vec2, len2)}. + +void _fq_vec_zero(fq_struct * vec, slong len, const fq_ctx_t ctx) + + Zeros the entries of \code{(vec, len)}. + +void _fq_vec_neg(fq_struct * vec1, const fq_struct * vec2, slong len2, + const fq_ctx_t ctx) + + Negates \code{(vec2, len2)} and places it into \code{vec1}. + +******************************************************************************* + + Comparison + +******************************************************************************* + +int _fq_vec_equal(const fq_struct * vec1, const fq_struct * vec2, slong len, + const fq_ctx_t ctx) + + Compares two vectors of the given length and returns $1$ if they are + equal, otherwise returns $0$. + +int _fq_vec_is_zero(const fq_struct * vec, slong len, const ctx_ctx) + + Returns $1$ if \code{(vec, len)} is zero, and $0$ otherwise. + +******************************************************************************* + + Addition and subtraction + +******************************************************************************* + +void _fq_vec_add(fq_struct * res, const fq_struct * vec1, + const fq_struct * vec2, slong len2, const fq_ctx_t ctx) + + Sets \code{(res, len2)} to the sum of \code{(vec1, len2)} + and \code{(vec2, len2)}. + +void _fq_vec_sub(fq_struct * res, const fq_struct * vec1, + const fq_struct * vec2, slong len2, const fq_ctx_t ctx) + + Sets \code{(res, len2)} to \code{(vec1, len2)} minus \code{(vec2, len2)}. + +******************************************************************************* + + Scalar multiplication and division + +******************************************************************************* +void _fq_vec_scalar_addmul_fq(fq_struct * vec1, const fq_struct * vec2, + slong len2, const fq_t c, const fq_ctx_t ctx) + + Adds \code{(vec2, len2)} times $c$ to \code{(vec1, len2)}, where + $c$ is a \code{fq_t}. + +void _fq_vec_scalar_submul_fq(fq_struct * vec1, const fq_struct * vec2, + slong len2, const fq_t c, const fq_ctx_t ctx) + + Subtracts \code{(vec2, len2)} times $c$ from \code{(vec1, len2)}, + where $c$ is a \code{fq_t}. + +******************************************************************************* + + Dot products + +******************************************************************************* + +void _fq_vec_dot(fq_t res, const fq_struct * vec1, const fq_struct * vec2, + slong len2, const fq_ctx_t ctx) + + Sets \code{res} to the dot product of (\code{vec1}, \code{len}) + and (\code{vec2}, \code{len}). diff --git a/external/flint-2.4.3/fq_vec/dot.c b/external/flint-2.4.3/fq_vec/dot.c new file mode 100644 index 0000000..449a52b --- /dev/null +++ b/external/flint-2.4.3/fq_vec/dot.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_vec_templates/dot.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_vec/equal.c b/external/flint-2.4.3/fq_vec/equal.c new file mode 100644 index 0000000..94f0c6a --- /dev/null +++ b/external/flint-2.4.3/fq_vec/equal.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_vec_templates/equal.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_vec/fprint.c b/external/flint-2.4.3/fq_vec/fprint.c new file mode 100644 index 0000000..bb99607 --- /dev/null +++ b/external/flint-2.4.3/fq_vec/fprint.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_vec_templates/fprint.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_vec/init.c b/external/flint-2.4.3/fq_vec/init.c new file mode 100644 index 0000000..950049b --- /dev/null +++ b/external/flint-2.4.3/fq_vec/init.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_vec_templates/init.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_vec/is_zero.c b/external/flint-2.4.3/fq_vec/is_zero.c new file mode 100644 index 0000000..2a40aea --- /dev/null +++ b/external/flint-2.4.3/fq_vec/is_zero.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_vec_templates/is_zero.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_vec/neg.c b/external/flint-2.4.3/fq_vec/neg.c new file mode 100644 index 0000000..9b202d6 --- /dev/null +++ b/external/flint-2.4.3/fq_vec/neg.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_vec_templates/neg.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_vec/randtest.c b/external/flint-2.4.3/fq_vec/randtest.c new file mode 100644 index 0000000..299607c --- /dev/null +++ b/external/flint-2.4.3/fq_vec/randtest.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_vec_templates/randtest.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_vec/scalar_addmul_fq.c b/external/flint-2.4.3/fq_vec/scalar_addmul_fq.c new file mode 100644 index 0000000..d79a887 --- /dev/null +++ b/external/flint-2.4.3/fq_vec/scalar_addmul_fq.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_vec_templates/scalar_addmul_fq.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_vec/scalar_submul_fq.c b/external/flint-2.4.3/fq_vec/scalar_submul_fq.c new file mode 100644 index 0000000..29f5108 --- /dev/null +++ b/external/flint-2.4.3/fq_vec/scalar_submul_fq.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_vec_templates/scalar_submul_fq.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_vec/set.c b/external/flint-2.4.3/fq_vec/set.c new file mode 100644 index 0000000..df0bfec --- /dev/null +++ b/external/flint-2.4.3/fq_vec/set.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_vec_templates/set.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_vec/sub.c b/external/flint-2.4.3/fq_vec/sub.c new file mode 100644 index 0000000..c97cdcb --- /dev/null +++ b/external/flint-2.4.3/fq_vec/sub.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_vec_templates/sub.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_vec/swap.c b/external/flint-2.4.3/fq_vec/swap.c new file mode 100644 index 0000000..7b1649d --- /dev/null +++ b/external/flint-2.4.3/fq_vec/swap.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_vec_templates/swap.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_vec/test/t-add.c b/external/flint-2.4.3/fq_vec/test/t-add.c new file mode 100644 index 0000000..5d01375 --- /dev/null +++ b/external/flint-2.4.3/fq_vec/test/t-add.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_vec_templates/test/t-add.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_vec/test/t-is_zero.c b/external/flint-2.4.3/fq_vec/test/t-is_zero.c new file mode 100644 index 0000000..cbeddfc --- /dev/null +++ b/external/flint-2.4.3/fq_vec/test/t-is_zero.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_vec_templates/test/t-is_zero.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_vec/test/t-neg.c b/external/flint-2.4.3/fq_vec/test/t-neg.c new file mode 100644 index 0000000..f8a9145 --- /dev/null +++ b/external/flint-2.4.3/fq_vec/test/t-neg.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_vec_templates/test/t-neg.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_vec/test/t-sub.c b/external/flint-2.4.3/fq_vec/test/t-sub.c new file mode 100644 index 0000000..1263acb --- /dev/null +++ b/external/flint-2.4.3/fq_vec/test/t-sub.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_vec_templates/test/t-sub.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_vec/test/t-swap.c b/external/flint-2.4.3/fq_vec/test/t-swap.c new file mode 100644 index 0000000..21c08bd --- /dev/null +++ b/external/flint-2.4.3/fq_vec/test/t-swap.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_vec_templates/test/t-swap.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_vec/test/t-zero.c b/external/flint-2.4.3/fq_vec/test/t-zero.c new file mode 100644 index 0000000..00e43bc --- /dev/null +++ b/external/flint-2.4.3/fq_vec/test/t-zero.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_vec_templates/test/t-zero.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_vec/zero.c b/external/flint-2.4.3/fq_vec/zero.c new file mode 100644 index 0000000..1e26d35 --- /dev/null +++ b/external/flint-2.4.3/fq_vec/zero.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq +#define CAP_T FQ +#include "fq_vec_templates/zero.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_vec_templates.h b/external/flint-2.4.3/fq_vec_templates.h new file mode 100644 index 0000000..7083da5 --- /dev/null +++ b/external/flint-2.4.3/fq_vec_templates.h @@ -0,0 +1,141 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#ifdef T + +#include "flint.h" +#include "templates.h" +#include "ulong_extras.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/* Memory management *******************************************************/ + +TEMPLATE(T, struct) * _TEMPLATE(T, vec_init)(slong len, const TEMPLATE(T, ctx_t) ctx); + +void _TEMPLATE(T, vec_clear)(TEMPLATE(T, struct) * vec, slong len, + const TEMPLATE(T, ctx_t) ctx); + +/* Randomisation ***********************************************************/ +void +_TEMPLATE(T, vec_randtest)(TEMPLATE(T, struct) * f, + flint_rand_t state, + slong len, + const TEMPLATE(T, ctx_t) ctx); + +/* Norms *******************************************************************/ + +/* Input and output ********************************************************/ +int _TEMPLATE(T, vec_fprint)(FILE * file, + const TEMPLATE(T, struct) * vec, + slong len, + const TEMPLATE(T, ctx_t) ctx); + +static __inline__ +int _TEMPLATE(T, vec_print)(const TEMPLATE(T, struct) * vec, slong len, + const TEMPLATE(T, ctx_t) ctx) +{ + return _TEMPLATE(T, vec_fprint)(stdout, vec, len, ctx); +} + +/* Conversions *************************************************************/ + +/* Assignment and basic manipulation ***************************************/ +void +_TEMPLATE(T, vec_set)(TEMPLATE(T, struct) * v, + const TEMPLATE(T, struct) * f, + slong len, const TEMPLATE(T, ctx_t) ctx); + +void +_TEMPLATE(T, vec_swap)(TEMPLATE(T, struct) * vec1, + TEMPLATE(T, struct) * vec2, + slong len2, const TEMPLATE(T, ctx_t) ctx); + +void +_TEMPLATE(T, vec_zero)(TEMPLATE(T, struct) * v, + slong len, + const TEMPLATE(T, ctx_t) ctx); + +void +_TEMPLATE(T, vec_neg)(TEMPLATE(T, struct) * vec1, + const TEMPLATE(T, struct) * vec2, + slong len2, + const TEMPLATE(T, ctx_t) ctx); + +/* Comparison **************************************************************/ +int +_TEMPLATE(T, vec_is_zero)(const TEMPLATE(T, struct) * vec, slong len, + const TEMPLATE(T, ctx_t) ctx); + +int +_TEMPLATE(T, vec_equal)(const TEMPLATE(T, struct) * vec1, + const TEMPLATE(T, struct) * vec2, slong len, + const TEMPLATE(T, ctx_t) ctx); + +/* Sorting *****************************************************************/ + +/* Addition ****************************************************************/ + +void _TEMPLATE(T, vec_add)(TEMPLATE(T, struct) * res, + const TEMPLATE(T, struct) * vec1, + const TEMPLATE(T, struct) * vec2, + slong len2, + const TEMPLATE(T, ctx_t) ctx); + +void _TEMPLATE(T, vec_sub)(TEMPLATE(T, struct) * res, + const TEMPLATE(T, struct) * vec1, + const TEMPLATE(T, struct) * vec2, + slong len2, + const TEMPLATE(T, ctx_t) ctx); + +void +_TEMPLATE(T, TEMPLATE(vec_scalar_addmul, T))(TEMPLATE(T, struct) * poly1, + const TEMPLATE(T, struct) * poly2, + slong len2, + const TEMPLATE(T, t) x, + const TEMPLATE(T, ctx_t) ctx); + +void +_TEMPLATE(T, TEMPLATE(vec_scalar_submul, T))(TEMPLATE(T, struct) * poly1, + const TEMPLATE(T, struct) * poly2, + slong len2, + const TEMPLATE(T, t) x, + const TEMPLATE(T, ctx_t) ctx); + +/* ****************************************************************************/ +void +_TEMPLATE(T, vec_dot)(TEMPLATE(T, t) res, + const TEMPLATE(T, struct) * vec1, + const TEMPLATE(T, struct) * vec2, + slong len2, + const TEMPLATE(T, ctx_t) ctx); + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/external/flint-2.4.3/fq_vec_templates/add.c b/external/flint-2.4.3/fq_vec_templates/add.c new file mode 100644 index 0000000..6b68625 --- /dev/null +++ b/external/flint-2.4.3/fq_vec_templates/add.c @@ -0,0 +1,44 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +_TEMPLATE(T, vec_add) (TEMPLATE(T, struct) * res, + const TEMPLATE(T, struct) * vec1, + const TEMPLATE(T, struct) * vec2, + slong len2, const TEMPLATE(T, ctx_t) ctx) +{ + slong i; + for (i = 0; i < len2; i++) + TEMPLATE(T, add) (res + i, vec1 + i, vec2 + i, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_vec_templates/clear.c b/external/flint-2.4.3/fq_vec_templates/clear.c new file mode 100644 index 0000000..bd50347 --- /dev/null +++ b/external/flint-2.4.3/fq_vec_templates/clear.c @@ -0,0 +1,42 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +_TEMPLATE(T, vec_clear) (TEMPLATE(T, struct) * vec, slong len, + const TEMPLATE(T, ctx_t) ctx) +{ + slong i; + for (i = 0; i < len; i++) + TEMPLATE(T, clear) (vec + i, ctx); + flint_free(vec); +} + +#endif diff --git a/external/flint-2.4.3/fq_vec_templates/dot.c b/external/flint-2.4.3/fq_vec_templates/dot.c new file mode 100644 index 0000000..8319f39 --- /dev/null +++ b/external/flint-2.4.3/fq_vec_templates/dot.c @@ -0,0 +1,52 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +_TEMPLATE(T, vec_dot) (TEMPLATE(T, t) res, + const TEMPLATE(T, struct) * vec1, + const TEMPLATE(T, struct) * vec2, + slong len2, const TEMPLATE(T, ctx_t) ctx) +{ + slong i; + TEMPLATE(T, t) x; + TEMPLATE(T, init) (x, ctx); + + TEMPLATE(T, zero) (res, ctx); + + for (i = 0; i < len2; i++) + { + TEMPLATE(T, mul) (x, vec1 + i, vec2 + i, ctx); + TEMPLATE(T, add) (res, res, x, ctx); + } + + TEMPLATE(T, clear) (x, ctx); +} + +#endif diff --git a/external/flint-2.4.3/fq_vec_templates/equal.c b/external/flint-2.4.3/fq_vec_templates/equal.c new file mode 100644 index 0000000..806e1ab --- /dev/null +++ b/external/flint-2.4.3/fq_vec_templates/equal.c @@ -0,0 +1,49 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2008, 2009, 2010 William Hart + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +int +_TEMPLATE(T, vec_equal) (const TEMPLATE(T, struct) * vec1, + const TEMPLATE(T, struct) * vec2, slong len, + const TEMPLATE(T, ctx_t) ctx) +{ + slong i; + if (vec1 == vec2) + return 1; + + for (i = 0; i < len; i++) + if (!TEMPLATE(T, equal) (vec1 + i, vec2 + i, ctx)) + return 0; + + return 1; +} + + +#endif diff --git a/external/flint-2.4.3/fq_vec_templates/fprint.c b/external/flint-2.4.3/fq_vec_templates/fprint.c new file mode 100644 index 0000000..4c832dc --- /dev/null +++ b/external/flint-2.4.3/fq_vec_templates/fprint.c @@ -0,0 +1,72 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2008, 2009, 2010 William Hart + Copyright (C) 2010 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include + +/* + Recall the return value conventions for fputc (of type int) + + ``If there are no errors, the same character that has been written is + returned. If an error occurs, EOF is returned and the error indicator + is set'' + + where the EOF macro expands to a negative int, and fprintf (of type int) + + ``On success, the total number of characters written is returned. + On failure, a negative number is returned.'' + */ + +int _TEMPLATE(T, vec_fprint) (FILE * file, + const TEMPLATE(T, struct) * vec, + slong len, const TEMPLATE(T, ctx_t) ctx) +{ + int r; + slong i; + + r = fprintf(file, "%li", len); + if ((len > 0) && (r > 0)) + { + r = fputc(' ', file); + for (i = 0; (i < len) && (r > 0); i++) + { + r = fputc(' ', file); + if (r > 0) + r = TEMPLATE(T, fprint) (file, vec + i, ctx); + } + } + + return r; +} + + +#endif diff --git a/external/flint-2.4.3/fq_vec_templates/init.c b/external/flint-2.4.3/fq_vec_templates/init.c new file mode 100644 index 0000000..1df2990 --- /dev/null +++ b/external/flint-2.4.3/fq_vec_templates/init.c @@ -0,0 +1,43 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +TEMPLATE(T, struct)* +_TEMPLATE(T, vec_init) (slong len, const TEMPLATE(T, ctx_t) ctx) +{ + slong i; + TEMPLATE(T, struct) * v; + v = flint_malloc(len * sizeof(TEMPLATE(T, struct))); + for (i = 0; i < len; i++) + TEMPLATE(T, init) (v + i, ctx); + return v; +} + + +#endif diff --git a/external/flint-2.4.3/fq_vec_templates/is_zero.c b/external/flint-2.4.3/fq_vec_templates/is_zero.c new file mode 100644 index 0000000..e931291 --- /dev/null +++ b/external/flint-2.4.3/fq_vec_templates/is_zero.c @@ -0,0 +1,44 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +int +_TEMPLATE(T, vec_is_zero) (const TEMPLATE(T, struct) * vec, slong len, + const TEMPLATE(T, ctx_t) ctx) +{ + slong i; + for (i = 0; i < len; i++) + if (!TEMPLATE(T, is_zero) (vec + i, ctx)) + return 0; + return 1; +} + + +#endif diff --git a/external/flint-2.4.3/fq_vec_templates/neg.c b/external/flint-2.4.3/fq_vec_templates/neg.c new file mode 100644 index 0000000..fa6e61e --- /dev/null +++ b/external/flint-2.4.3/fq_vec_templates/neg.c @@ -0,0 +1,43 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +_TEMPLATE(T, vec_neg) (TEMPLATE(T, struct) * vec1, + const TEMPLATE(T, struct) * vec2, + slong len2, const TEMPLATE(T, ctx_t) ctx) +{ + slong i; + for (i = 0; i < len2; i++) + TEMPLATE(T, neg) (vec1 + i, vec2 + i, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_vec_templates/randtest.c b/external/flint-2.4.3/fq_vec_templates/randtest.c new file mode 100644 index 0000000..1b7a195 --- /dev/null +++ b/external/flint-2.4.3/fq_vec_templates/randtest.c @@ -0,0 +1,60 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009, 2010 William Hart + Copyright (C) 2010 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + + +void +_TEMPLATE(T, vec_randtest) (TEMPLATE(T, struct) * f, + flint_rand_t state, + slong len, const TEMPLATE(T, ctx_t) ctx) +{ + slong i, sparseness; + + if (n_randint(state, 2)) + { + for (i = 0; i < len; i++) + TEMPLATE(T, randtest) (f + i, state, ctx); + } + else + { + sparseness = 1 + n_randint(state, FLINT_MAX(2, len)); + + for (i = 0; i < len; i++) + { + if (n_randint(state, sparseness)) + TEMPLATE(T, zero) (f + i, ctx); + else + TEMPLATE(T, randtest) (f + i, state, ctx); + } + } +} + +#endif diff --git a/external/flint-2.4.3/fq_vec_templates/scalar_addmul_fq.c b/external/flint-2.4.3/fq_vec_templates/scalar_addmul_fq.c new file mode 100644 index 0000000..3e61655 --- /dev/null +++ b/external/flint-2.4.3/fq_vec_templates/scalar_addmul_fq.c @@ -0,0 +1,52 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +_TEMPLATE3(T, vec_scalar_addmul, T) (TEMPLATE(T, struct) * poly1, + const TEMPLATE(T, struct) * poly2, + slong len2, const TEMPLATE(T, t) x, + const TEMPLATE(T, ctx_t) ctx) +{ + slong i; + TEMPLATE(T, t) y; + + TEMPLATE(T, init) (y, ctx); + + for (i = 0; i < len2; i++) + { + TEMPLATE(T, mul) (y, poly2 + i, x, ctx); + TEMPLATE(T, add) (poly1 + i, poly1 + i, y, ctx); + } + + TEMPLATE(T, clear) (y, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_vec_templates/scalar_submul_fq.c b/external/flint-2.4.3/fq_vec_templates/scalar_submul_fq.c new file mode 100644 index 0000000..5be8604 --- /dev/null +++ b/external/flint-2.4.3/fq_vec_templates/scalar_submul_fq.c @@ -0,0 +1,52 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +_TEMPLATE3(T, vec_scalar_submul, T) (TEMPLATE(T, struct) * poly1, + const TEMPLATE(T, struct) * poly2, + slong len2, const TEMPLATE(T, t) x, + const TEMPLATE(T, ctx_t) ctx) +{ + slong i; + TEMPLATE(T, t) y; + + TEMPLATE(T, init) (y, ctx); + + for (i = 0; i < len2; i++) + { + TEMPLATE(T, mul) (y, poly2 + i, x, ctx); + TEMPLATE(T, sub) (poly1 + i, poly1 + i, y, ctx); + } + + TEMPLATE(T, clear) (y, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_vec_templates/set.c b/external/flint-2.4.3/fq_vec_templates/set.c new file mode 100644 index 0000000..8a7b22e --- /dev/null +++ b/external/flint-2.4.3/fq_vec_templates/set.c @@ -0,0 +1,43 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +_TEMPLATE(T, vec_set) (TEMPLATE(T, struct) * vec1, + const TEMPLATE(T, struct) * vec2, + slong len2, const TEMPLATE(T, ctx_t) ctx) +{ + slong i; + for (i = 0; i < len2; i++) + TEMPLATE(T, set) (vec1 + i, vec2 + i, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_vec_templates/sub.c b/external/flint-2.4.3/fq_vec_templates/sub.c new file mode 100644 index 0000000..acd3163 --- /dev/null +++ b/external/flint-2.4.3/fq_vec_templates/sub.c @@ -0,0 +1,44 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +_TEMPLATE(T, vec_sub) (TEMPLATE(T, struct) * res, + const TEMPLATE(T, struct) * vec1, + const TEMPLATE(T, struct) * vec2, + slong len2, const TEMPLATE(T, ctx_t) ctx) +{ + slong i; + for (i = 0; i < len2; i++) + TEMPLATE(T, sub) (res + i, vec1 + i, vec2 + i, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_vec_templates/swap.c b/external/flint-2.4.3/fq_vec_templates/swap.c new file mode 100644 index 0000000..7cad0db --- /dev/null +++ b/external/flint-2.4.3/fq_vec_templates/swap.c @@ -0,0 +1,42 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +_TEMPLATE(T, vec_swap) (TEMPLATE(T, struct) * vec1, TEMPLATE(T, struct) * vec2, + slong len2, const TEMPLATE(T, ctx_t) ctx) +{ + slong i; + for (i = 0; i < len2; i++) + TEMPLATE(T, swap) (vec1 + i, vec2 + i, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_vec_templates/test/t-add.c b/external/flint-2.4.3/fq_vec_templates/test/t-add.c new file mode 100644 index 0000000..9693bbb --- /dev/null +++ b/external/flint-2.4.3/fq_vec_templates/test/t-add.c @@ -0,0 +1,121 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009, 2010 William Hart + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + printf("add...."); + fflush(stdout); + + /* Check aliasing of a and c */ + for (i = 0; i < 50; i++) + { + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, struct) * a, *b, *c; + slong len = n_randint(state, 100); + + TEMPLATE(T, ctx_randtest) (ctx, state); + + a = _TEMPLATE(T, vec_init) (len, ctx); + b = _TEMPLATE(T, vec_init) (len, ctx); + c = _TEMPLATE(T, vec_init) (len, ctx); + _TEMPLATE(T, vec_randtest) (a, state, len, ctx); + _TEMPLATE(T, vec_randtest) (b, state, len, ctx); + + _TEMPLATE(T, vec_add) (c, a, b, len, ctx); + _TEMPLATE(T, vec_add) (a, a, b, len, ctx); + + result = (_TEMPLATE(T, vec_equal) (a, c, len, ctx)); + if (!result) + { + printf("FAIL:\n"); + _TEMPLATE(T, vec_print) (a, len, ctx), printf("\n\n"); + _TEMPLATE(T, vec_print) (c, len, ctx), printf("\n\n"); + abort(); + } + + _TEMPLATE(T, vec_clear) (a, len, ctx); + _TEMPLATE(T, vec_clear) (b, len, ctx); + _TEMPLATE(T, vec_clear) (c, len, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check aliasing of b and c */ + for (i = 0; i < 50; i++) + { + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, struct) * a, *b, *c; + slong len = n_randint(state, 100); + + TEMPLATE(T, ctx_randtest) (ctx, state); + + a = _TEMPLATE(T, vec_init) (len, ctx); + b = _TEMPLATE(T, vec_init) (len, ctx); + c = _TEMPLATE(T, vec_init) (len, ctx); + _TEMPLATE(T, vec_randtest) (a, state, len, ctx); + _TEMPLATE(T, vec_randtest) (b, state, len, ctx); + + _TEMPLATE(T, vec_add) (c, a, b, len, ctx); + _TEMPLATE(T, vec_add) (b, a, b, len, ctx); + + result = (_TEMPLATE(T, vec_equal) (b, c, len, ctx)); + if (!result) + { + printf("FAIL:\n"); + _TEMPLATE(T, vec_print) (b, len, ctx), printf("\n\n"); + _TEMPLATE(T, vec_print) (c, len, ctx), printf("\n\n"); + abort(); + } + + _TEMPLATE(T, vec_clear) (a, len, ctx); + _TEMPLATE(T, vec_clear) (b, len, ctx); + _TEMPLATE(T, vec_clear) (c, len, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_vec_templates/test/t-is_zero.c b/external/flint-2.4.3/fq_vec_templates/test/t-is_zero.c new file mode 100644 index 0000000..8598ed0 --- /dev/null +++ b/external/flint-2.4.3/fq_vec_templates/test/t-is_zero.c @@ -0,0 +1,102 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009, 2010 William Hart + Copyright (C) 2010 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + printf("is_zero...."); + fflush(stdout); + + /* Check zero vector */ + for (i = 0; i < 50; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, struct) * a; + slong len = n_randint(state, 100); + + TEMPLATE(T, ctx_randtest) (ctx, state); + + a = _TEMPLATE(T, vec_init) (len, ctx); + _TEMPLATE(T, vec_zero) (a, len, ctx); + + result = (_TEMPLATE(T, vec_is_zero) (a, len, ctx)); + if (!result) + { + printf("FAIL1:\n"); + _TEMPLATE(T, vec_print) (a, len, ctx), printf("\n\n"); + abort(); + } + + _TEMPLATE(T, vec_clear) (a, len, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check non-zero vector */ + for (i = 0; i < 50; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, struct) * a; + slong len = n_randint(state, 100) + 1; + + TEMPLATE(T, ctx_randtest) (ctx, state); + + a = _TEMPLATE(T, vec_init) (len, ctx); + TEMPLATE(T, one) (a + (len - 1), ctx); + + result = (!_TEMPLATE(T, vec_is_zero) (a, len, ctx)); + if (!result) + { + printf("FAIL2:\n"); + _TEMPLATE(T, vec_print) (a, len, ctx), printf("\n\n"); + abort(); + } + + _TEMPLATE(T, vec_clear) (a, len, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_vec_templates/test/t-neg.c b/external/flint-2.4.3/fq_vec_templates/test/t-neg.c new file mode 100644 index 0000000..9d7757e --- /dev/null +++ b/external/flint-2.4.3/fq_vec_templates/test/t-neg.c @@ -0,0 +1,111 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009, 2010 William Hart + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + printf("neg...."); + fflush(stdout); + + /* Check aliasing of a and b */ + for (i = 0; i < 100; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, struct) * a, *b; + slong len = n_randint(state, 100); + + TEMPLATE(T, ctx_randtest) (ctx, state); + + a = _TEMPLATE(T, vec_init) (len, ctx); + b = _TEMPLATE(T, vec_init) (len, ctx); + _TEMPLATE(T, vec_randtest) (a, state, len, ctx); + + _TEMPLATE(T, vec_neg) (b, a, len, ctx); + _TEMPLATE(T, vec_neg) (a, a, len, ctx); + + result = (_TEMPLATE(T, vec_equal) (a, b, len, ctx)); + if (!result) + { + printf("FAIL:\n"); + _TEMPLATE(T, vec_print) (a, len, ctx), printf("\n\n"); + _TEMPLATE(T, vec_print) (b, len, ctx), printf("\n\n"); + abort(); + } + + _TEMPLATE(T, vec_clear) (a, len, ctx); + _TEMPLATE(T, vec_clear) (b, len, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check -(-a) == a */ + for (i = 0; i < 100; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, struct) * a, *b; + slong len = n_randint(state, 100); + + TEMPLATE(T, ctx_randtest) (ctx, state); + + a = _TEMPLATE(T, vec_init) (len, ctx); + b = _TEMPLATE(T, vec_init) (len, ctx); + _TEMPLATE(T, vec_randtest) (a, state, len, ctx); + + _TEMPLATE(T, vec_neg) (b, a, len, ctx); + _TEMPLATE(T, vec_neg) (b, b, len, ctx); + + result = (_TEMPLATE(T, vec_equal) (a, b, len, ctx)); + if (!result) + { + printf("FAIL:\n"); + _TEMPLATE(T, vec_print) (a, len, ctx), printf("\n\n"); + _TEMPLATE(T, vec_print) (b, len, ctx), printf("\n\n"); + abort(); + } + + _TEMPLATE(T, vec_clear) (a, len, ctx); + _TEMPLATE(T, vec_clear) (b, len, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_vec_templates/test/t-sub.c b/external/flint-2.4.3/fq_vec_templates/test/t-sub.c new file mode 100644 index 0000000..0e53683 --- /dev/null +++ b/external/flint-2.4.3/fq_vec_templates/test/t-sub.c @@ -0,0 +1,158 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009, 2010 William Hart + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + printf("sub...."); + fflush(stdout); + + /* Check aliasing of a and c */ + for (i = 0; i < 100; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, struct) * a, *b, *c; + slong len = n_randint(state, 100); + + TEMPLATE(T, ctx_randtest) (ctx, state); + + a = _TEMPLATE(T, vec_init) (len, ctx); + b = _TEMPLATE(T, vec_init) (len, ctx); + c = _TEMPLATE(T, vec_init) (len, ctx); + + _TEMPLATE(T, vec_randtest) (a, state, len, ctx); + _TEMPLATE(T, vec_randtest) (b, state, len, ctx); + + _TEMPLATE(T, vec_sub) (c, a, b, len, ctx); + _TEMPLATE(T, vec_sub) (a, a, b, len, ctx); + + result = (_TEMPLATE(T, vec_equal) (a, c, len, ctx)); + if (!result) + { + printf("FAIL:\n"); + _TEMPLATE(T, vec_print) (a, len, ctx), printf("\n\n"); + _TEMPLATE(T, vec_print) (c, len, ctx), printf("\n\n"); + abort(); + } + + _TEMPLATE(T, vec_clear) (a, len, ctx); + _TEMPLATE(T, vec_clear) (b, len, ctx); + _TEMPLATE(T, vec_clear) (c, len, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check aliasing of b and c */ + for (i = 0; i < 100; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, struct) * a, *b, *c; + slong len = n_randint(state, 100); + + TEMPLATE(T, ctx_randtest) (ctx, state); + + a = _TEMPLATE(T, vec_init) (len, ctx); + b = _TEMPLATE(T, vec_init) (len, ctx); + c = _TEMPLATE(T, vec_init) (len, ctx); + _TEMPLATE(T, vec_randtest) (a, state, len, ctx); + _TEMPLATE(T, vec_randtest) (b, state, len, ctx); + + _TEMPLATE(T, vec_sub) (c, a, b, len, ctx); + _TEMPLATE(T, vec_sub) (b, a, b, len, ctx); + + result = (_TEMPLATE(T, vec_equal) (b, c, len, ctx)); + if (!result) + { + printf("FAIL:\n"); + _TEMPLATE(T, vec_print) (b, len, ctx), printf("\n\n"); + _TEMPLATE(T, vec_print) (c, len, ctx), printf("\n\n"); + abort(); + } + + _TEMPLATE(T, vec_clear) (a, len, ctx); + _TEMPLATE(T, vec_clear) (b, len, ctx); + _TEMPLATE(T, vec_clear) (c, len, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + /* Check a + b - b = a */ + for (i = 0; i < 100; i++) + { + TEMPLATE(T, ctx_t) ctx; + + TEMPLATE(T, struct) * a, *b, *c, *d; + slong len = n_randint(state, 100); + + TEMPLATE(T, ctx_randtest) (ctx, state); + + a = _TEMPLATE(T, vec_init) (len, ctx); + b = _TEMPLATE(T, vec_init) (len, ctx); + c = _TEMPLATE(T, vec_init) (len, ctx); + d = _TEMPLATE(T, vec_init) (len, ctx); + + _TEMPLATE(T, vec_randtest) (a, state, len, ctx); + _TEMPLATE(T, vec_randtest) (b, state, len, ctx); + + _TEMPLATE(T, vec_add) (c, a, b, len, ctx); + _TEMPLATE(T, vec_sub) (d, c, b, len, ctx); + + result = (_TEMPLATE(T, vec_equal) (d, a, len, ctx)); + if (!result) + { + printf("FAIL:\n"); + _TEMPLATE(T, vec_print) (a, len, ctx), printf("\n\n"); + _TEMPLATE(T, vec_print) (d, len, ctx), printf("\n\n"); + abort(); + } + + _TEMPLATE(T, vec_clear) (a, len, ctx); + _TEMPLATE(T, vec_clear) (b, len, ctx); + _TEMPLATE(T, vec_clear) (c, len, ctx); + _TEMPLATE(T, vec_clear) (d, len, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + + FLINT_TEST_CLEANUP(state); + printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_vec_templates/test/t-swap.c b/external/flint-2.4.3/fq_vec_templates/test/t-swap.c new file mode 100644 index 0000000..66326db --- /dev/null +++ b/external/flint-2.4.3/fq_vec_templates/test/t-swap.c @@ -0,0 +1,86 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + printf("swap...."); + fflush(stdout); + + for (i = 0; i < 100; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, struct) * a, *b, *c; + slong len = n_randint(state, 100); + + TEMPLATE(T, ctx_randtest) (ctx, state); + + a = _TEMPLATE(T, vec_init) (len, ctx); + b = _TEMPLATE(T, vec_init) (len, ctx); + c = _TEMPLATE(T, vec_init) (len, ctx); + + _TEMPLATE(T, vec_randtest) (a, state, len, ctx); + _TEMPLATE(T, vec_randtest) (b, state, len, ctx); + + _TEMPLATE(T, vec_set) (c, b, len, ctx); + _TEMPLATE(T, vec_swap) (a, b, len, ctx); + + result = (_TEMPLATE(T, vec_equal) (a, c, len, ctx)); + if (!result) + { + printf("FAIL:\n"); + _TEMPLATE(T, vec_print) (a, len, ctx), printf("\n\n"); + _TEMPLATE(T, vec_print) (b, len, ctx), printf("\n\n"); + _TEMPLATE(T, vec_print) (c, len, ctx), printf("\n\n"); + abort(); + } + + _TEMPLATE(T, vec_clear) (a, len, ctx); + _TEMPLATE(T, vec_clear) (b, len, ctx); + _TEMPLATE(T, vec_clear) (c, len, ctx); + + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_vec_templates/test/t-zero.c b/external/flint-2.4.3/fq_vec_templates/test/t-zero.c new file mode 100644 index 0000000..0ff0d61 --- /dev/null +++ b/external/flint-2.4.3/fq_vec_templates/test/t-zero.c @@ -0,0 +1,77 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009, 2010 William Hart + Copyright (C) 2010 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +#include +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + printf("zero...."); + fflush(stdout); + + /* Check it's zero */ + for (i = 0; i < 100; i++) + { + TEMPLATE(T, ctx_t) ctx; + TEMPLATE(T, struct) * a; + slong len = n_randint(state, 100); + + TEMPLATE(T, ctx_randtest) (ctx, state); + + a = _TEMPLATE(T, vec_init) (len, ctx); + _TEMPLATE(T, vec_randtest) (a, state, len, ctx); + + _TEMPLATE(T, vec_zero) (a, len, ctx); + + result = (_TEMPLATE(T, vec_is_zero) (a, len, ctx)); + if (!result) + { + printf("FAIL:\n"); + _TEMPLATE(T, vec_print) (a, len, ctx), printf("\n\n"); + abort(); + } + + _TEMPLATE(T, vec_clear) (a, len, ctx); + TEMPLATE(T, ctx_clear) (ctx); + } + + FLINT_TEST_CLEANUP(state); + printf("PASS\n"); + return 0; +} + + +#endif diff --git a/external/flint-2.4.3/fq_vec_templates/zero.c b/external/flint-2.4.3/fq_vec_templates/zero.c new file mode 100644 index 0000000..1925fcb --- /dev/null +++ b/external/flint-2.4.3/fq_vec_templates/zero.c @@ -0,0 +1,42 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2013 Mike Hansen + +******************************************************************************/ + + +#ifdef T + +#include "templates.h" + +void +_TEMPLATE(T, vec_zero) (TEMPLATE(T, struct) * vec, + slong len, const TEMPLATE(T, ctx_t) ctx) +{ + slong i; + for (i = 0; i < len; i++) + TEMPLATE(T, zero) (vec + i, ctx); +} + + +#endif diff --git a/external/flint-2.4.3/fq_zech.h b/external/flint-2.4.3/fq_zech.h new file mode 100644 index 0000000..a50a054 --- /dev/null +++ b/external/flint-2.4.3/fq_zech.h @@ -0,0 +1,321 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#ifndef FQ_ZECH_H +#define FQ_ZECH_H + +#include "fq_nmod.h" + +/* Data types and context ****************************************************/ +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct +{ + mp_limb_t value; +} fq_zech_struct; + +typedef fq_zech_struct fq_zech_t[1]; + +typedef struct +{ + mp_limb_t qm1; /* q - 1 */ + mp_limb_t qm1o2; /* (q - 1) / 2 or 1 when p == 2 */ + mp_limb_t qm1opm1; /* (q - 1) / (p - 1) */ + mp_limb_t p; + double ppre; + mp_limb_t prime_root; /* primitive root for prime subfield */ + mp_limb_t *zech_log_table; + mp_limb_t *prime_field_table; + mp_limb_t *eval_table; + + fq_nmod_ctx_struct *fq_nmod_ctx; + int owns_fq_nmod_ctx; + +} fq_zech_ctx_struct; + +typedef fq_zech_ctx_struct fq_zech_ctx_t[1]; + +void fq_zech_ctx_init(fq_zech_ctx_t ctx, const fmpz_t p, slong d, const char *var); + +void fq_zech_ctx_init_fq_nmod_ctx(fq_zech_ctx_t ctx, fq_nmod_ctx_t ctxn); + +int _fq_zech_ctx_init_conway(fq_zech_ctx_t ctx, const fmpz_t p, slong d, const char *var); + +void fq_zech_ctx_init_conway(fq_zech_ctx_t ctx, const fmpz_t p, slong d, const char *var); + +void fq_zech_ctx_init_modulus(fq_zech_ctx_t ctx, + const nmod_poly_t modulus, + const char *var); + +void fq_zech_ctx_randtest(fq_zech_ctx_t ctx, flint_rand_t state); + +void fq_zech_ctx_clear(fq_zech_ctx_t ctx); + +static __inline__ slong +fq_zech_ctx_degree(const fq_zech_ctx_t ctx) +{ + return fq_nmod_ctx_degree(ctx->fq_nmod_ctx); +} + +static __inline__ void +fq_zech_ctx_order(fmpz_t f, const fq_zech_ctx_t ctx) +{ + fq_nmod_ctx_order(f, ctx->fq_nmod_ctx); +} + +static __inline__ mp_limb_t +fq_zech_ctx_order_ui(const fq_zech_ctx_t ctx) +{ + return ctx->qm1 + 1; +} + +#define fq_zech_ctx_prime(ctx) fq_nmod_ctx_prime(ctx->fq_nmod_ctx) + +static __inline__ int +fq_zech_ctx_fprint(FILE * file, const fq_zech_ctx_t ctx) +{ + int r; + r = flint_fprintf(file, "Zech Representation:\n"); + if (r <= 0) + return r; + return fq_nmod_ctx_fprint(file, ctx->fq_nmod_ctx); +} + +static __inline__ void +fq_zech_ctx_print(const fq_zech_ctx_t ctx) +{ + fq_zech_ctx_fprint(stdout, ctx); +} + +/* Memory managment *********************************************************/ + +static __inline__ void +fq_zech_init(fq_zech_t rop, const fq_zech_ctx_t ctx) +{ + rop->value = ctx->qm1; +} + +static __inline__ void +fq_zech_init2(fq_zech_t rop, const fq_zech_ctx_t ctx) +{ + rop->value = ctx->qm1; +} + +static __inline__ void +fq_zech_clear(fq_zech_t rop, const fq_zech_ctx_t ctx) +{ +} + +static __inline__ void +fq_zech_reduce(fq_zech_t rop, const fq_zech_ctx_t ctx) +{ + mp_limb_t order = fq_zech_ctx_order_ui(ctx); + if (rop->value >= order) + { + rop->value -= order; + } +} + +/* Basic arithmetic **********************************************************/ + +void fq_zech_add(fq_zech_t rop, const fq_zech_t op1, const fq_zech_t op2, + const fq_zech_ctx_t ctx); + +void fq_zech_sub(fq_zech_t rop, const fq_zech_t op1, const fq_zech_t op2, + const fq_zech_ctx_t ctx); + +void fq_zech_sub_one(fq_zech_t rop, const fq_zech_t op1, + const fq_zech_ctx_t ctx); + +void fq_zech_neg(fq_zech_t rop, const fq_zech_t op1, const fq_zech_ctx_t ctx); + +void fq_zech_mul(fq_zech_t rop, const fq_zech_t op1, const fq_zech_t op2, + const fq_zech_ctx_t ctx); + +void fq_zech_mul_fmpz(fq_zech_t rop, const fq_zech_t op, const fmpz_t x, + const fq_zech_ctx_t ctx); + +void fq_zech_mul_si(fq_zech_t rop, const fq_zech_t op, slong x, + const fq_zech_ctx_t ctx); + +void fq_zech_mul_ui(fq_zech_t rop, const fq_zech_t op, ulong x, + const fq_zech_ctx_t ctx); + +void fq_zech_sqr(fq_zech_t rop, const fq_zech_t op, const fq_zech_ctx_t ctx); + +void fq_zech_inv(fq_zech_t rop, const fq_zech_t op1, const fq_zech_ctx_t ctx); + +void _fq_zech_pow(fmpz * rop, const fmpz * op, slong len, const fmpz_t e, + const fmpz * a, const slong *j, slong lena, const fmpz_t p); + +void fq_zech_pow(fq_zech_t rop, const fq_zech_t op1, const fmpz_t e, + const fq_zech_ctx_t ctx); + +void fq_zech_pow_ui(fq_zech_t rop, const fq_zech_t op1, const ulong e, + const fq_zech_ctx_t ctx); + +void +fq_zech_pth_root(fq_zech_t rop, const fq_zech_t op1, const fq_zech_ctx_t ctx); + +/* Randomisation *************************************************************/ + +void fq_zech_randtest(fq_zech_t rop, flint_rand_t state, + const fq_zech_ctx_t ctx); + +void fq_zech_randtest_not_zero(fq_zech_t rop, flint_rand_t state, + const fq_zech_ctx_t ctx); + +/* Comparison ****************************************************************/ + +static __inline__ int +fq_zech_equal(const fq_zech_t op1, const fq_zech_t op2, const fq_zech_ctx_t ctx) +{ + return op1->value == op2->value; +} + +static __inline__ int +fq_zech_is_zero(const fq_zech_t op, const fq_zech_ctx_t ctx) +{ + return op->value == ctx->qm1; +} + +static __inline__ int +fq_zech_is_one(const fq_zech_t op, const fq_zech_ctx_t ctx) +{ + return op->value == 0; +} + +/* Assignments and conversions ***********************************************/ + +static __inline__ void +fq_zech_set(fq_zech_t rop, const fq_zech_t op, const fq_zech_ctx_t ctx) +{ + rop->value = op->value; +} + +void +fq_zech_set_fmpz(fq_zech_t rop, const fmpz_t x, const fq_zech_ctx_t ctx); + +static __inline__ void +fq_zech_set_ui(fq_zech_t rop, const ulong x, const fq_zech_ctx_t ctx) +{ + fmpz_t xx; + fmpz_init_set_ui(xx, x); + fq_zech_set_fmpz(rop, xx, ctx); + fmpz_clear(xx); +} + +static __inline__ void +fq_zech_swap(fq_zech_t op1, fq_zech_t op2, const fq_zech_ctx_t ctx) +{ + slong temp; + temp = op2->value; + op2->value = op1->value; + op1->value = temp; +} + +static __inline__ void +fq_zech_zero(fq_zech_t rop, const fq_zech_ctx_t ctx) +{ + rop->value = ctx->qm1; +} + +static __inline__ void +fq_zech_one(fq_zech_t rop, const fq_zech_ctx_t ctx) +{ + rop->value = 0; +} + +static __inline__ void +fq_zech_gen(fq_zech_t rop, const fq_zech_ctx_t ctx) +{ + rop->value = 1; +} + +void +fq_zech_set_fq_nmod(fq_zech_t rop, const fq_nmod_t op, const fq_zech_ctx_t ctx); + +void +fq_zech_get_fq_nmod(fq_nmod_t rop, const fq_zech_t op, const fq_zech_ctx_t ctx); + + +/* Output ********************************************************************/ +static __inline__ int +fq_zech_fprint_pretty(FILE * file, const fq_zech_t op, const fq_zech_ctx_t ctx) +{ + return flint_fprintf(file, "%s^%wd", ctx->fq_nmod_ctx->var, op->value); +} + +static __inline__ void +fq_zech_print_pretty(const fq_zech_t op, const fq_zech_ctx_t ctx) +{ + fq_zech_fprint_pretty(stdout, op, ctx); +} + +static __inline__ int +fq_zech_fprint(FILE * file, const fq_zech_t op, const fq_zech_ctx_t ctx) +{ + return flint_fprintf(file, "%wd", op->value); +} + +static __inline__ void +fq_zech_print(const fq_zech_t op, const fq_zech_ctx_t ctx) +{ + fq_zech_fprint(stdout, op, ctx); +} + +char * +fq_zech_get_str(const fq_zech_t op, const fq_zech_ctx_t ctx); + +char * +fq_zech_get_str_pretty(const fq_zech_t op, const fq_zech_ctx_t ctx); + + +/* Special functions *********************************************************/ + +void fq_zech_trace(fmpz_t rop, const fq_zech_t op, const fq_zech_ctx_t ctx); + +void fq_zech_frobenius(fq_zech_t rop, const fq_zech_t op, slong e, + const fq_zech_ctx_t ctx); + +void fq_zech_norm(fmpz_t rop, const fq_zech_t op, const fq_zech_ctx_t ctx); + +/* Bit packing ******************************************************/ + +void +fq_zech_bit_pack(fmpz_t f, const fq_zech_t op, mp_bitcnt_t bit_size, + const fq_zech_ctx_t ctx); + +void +fq_zech_bit_unpack(fq_zech_t rop, const fmpz_t f, mp_bitcnt_t bit_size, + const fq_zech_ctx_t ctx); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/flint-2.4.3/fq_zech/add.c b/external/flint-2.4.3/fq_zech/add.c new file mode 100644 index 0000000..c090e1c --- /dev/null +++ b/external/flint-2.4.3/fq_zech/add.c @@ -0,0 +1,52 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech.h" + +void +fq_zech_add(fq_zech_t rop, const fq_zech_t op1, const fq_zech_t op2, + const fq_zech_ctx_t ctx) +{ + mp_limb_t index, c; + if (op1->value == ctx->qm1) + { + rop->value = op2->value; + } + else if (op2->value == ctx->qm1) + { + rop->value = op1->value; + } + else + { + index = n_submod(op1->value, op2->value, ctx->qm1); + + c = ctx->zech_log_table[index]; + if (c != ctx->qm1) + { + c = n_addmod(c, op2->value, ctx->qm1); + } + rop->value = c; + } +} diff --git a/external/flint-2.4.3/fq_zech/bit_pack.c b/external/flint-2.4.3/fq_zech/bit_pack.c new file mode 100644 index 0000000..34c9f7f --- /dev/null +++ b/external/flint-2.4.3/fq_zech/bit_pack.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech.h" + +void +fq_zech_bit_pack(fmpz_t f, const fq_zech_t op, mp_bitcnt_t bit_size, + const fq_zech_ctx_t ctx) +{ + fq_nmod_t opn; + fq_nmod_init(opn, ctx->fq_nmod_ctx); + fq_zech_get_fq_nmod(opn, op, ctx); + fq_nmod_bit_pack(f, opn, bit_size, ctx->fq_nmod_ctx); + fq_nmod_clear(opn, ctx->fq_nmod_ctx); +} + diff --git a/external/flint-2.4.3/fq_zech/bit_unpack.c b/external/flint-2.4.3/fq_zech/bit_unpack.c new file mode 100644 index 0000000..a227b89 --- /dev/null +++ b/external/flint-2.4.3/fq_zech/bit_unpack.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech.h" + +void +fq_zech_bit_unpack(fq_zech_t rop, const fmpz_t f, mp_bitcnt_t bit_size, + const fq_zech_ctx_t ctx) +{ + fq_nmod_t ropn; + fq_nmod_init(ropn, ctx->fq_nmod_ctx); + + fq_nmod_bit_unpack(ropn, f, bit_size, ctx->fq_nmod_ctx); + fq_zech_set_fq_nmod(rop, ropn, ctx); + + fq_nmod_clear(ropn, ctx->fq_nmod_ctx); +} diff --git a/external/flint-2.4.3/fq_zech/clear.c b/external/flint-2.4.3/fq_zech/clear.c new file mode 100644 index 0000000..3a3bd10 --- /dev/null +++ b/external/flint-2.4.3/fq_zech/clear.c @@ -0,0 +1,28 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ +#include +#include + +#include "fq_zech.h" diff --git a/external/flint-2.4.3/fq_zech/ctx_clear.c b/external/flint-2.4.3/fq_zech/ctx_clear.c new file mode 100644 index 0000000..a389cac --- /dev/null +++ b/external/flint-2.4.3/fq_zech/ctx_clear.c @@ -0,0 +1,42 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ +#include +#include + +#include "fq_zech.h" + +void +fq_zech_ctx_clear(fq_zech_ctx_t ctx) +{ + flint_free(ctx->zech_log_table); + flint_free(ctx->prime_field_table); + flint_free(ctx->eval_table); + + if (ctx->owns_fq_nmod_ctx) + { + fq_nmod_ctx_clear(ctx->fq_nmod_ctx); + flint_free(ctx->fq_nmod_ctx); + } +} diff --git a/external/flint-2.4.3/fq_zech/ctx_init.c b/external/flint-2.4.3/fq_zech/ctx_init.c new file mode 100644 index 0000000..db691f6 --- /dev/null +++ b/external/flint-2.4.3/fq_zech/ctx_init.c @@ -0,0 +1,187 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ +#include +#include + +#include "flint.h" +#include "fq_zech.h" + +void +fq_zech_ctx_init(fq_zech_ctx_t ctx, const fmpz_t p, slong d, const char *var) +{ + fq_nmod_ctx_struct * fq_nmod_ctx; + + fq_nmod_ctx = flint_malloc(sizeof(fq_nmod_ctx_struct)); + + fq_nmod_ctx_init(fq_nmod_ctx, p, d, var); + fq_zech_ctx_init_fq_nmod_ctx(ctx, fq_nmod_ctx); + ctx->owns_fq_nmod_ctx = 1; +} + +void +fq_zech_ctx_init_conway(fq_zech_ctx_t ctx, const fmpz_t p, slong d, + const char *var) +{ + fq_nmod_ctx_struct * fq_nmod_ctx; + + fq_nmod_ctx = flint_malloc(sizeof(fq_nmod_ctx_struct)); + + fq_nmod_ctx_init_conway(fq_nmod_ctx, p, d, var); + fq_zech_ctx_init_fq_nmod_ctx(ctx, fq_nmod_ctx); + ctx->owns_fq_nmod_ctx = 1; +} + +int +_fq_zech_ctx_init_conway(fq_zech_ctx_t ctx, const fmpz_t p, slong d, + const char *var) +{ + int result; + fq_nmod_ctx_struct * fq_nmod_ctx; + + fq_nmod_ctx = flint_malloc(sizeof(fq_nmod_ctx_struct)); + + result = _fq_nmod_ctx_init_conway(fq_nmod_ctx, p, d, var); + if (!result) + { + flint_free(fq_nmod_ctx); + return result; + } + + fq_zech_ctx_init_fq_nmod_ctx(ctx, fq_nmod_ctx); + ctx->owns_fq_nmod_ctx = 1; + return result; +} + + +void +fq_zech_ctx_init_modulus(fq_zech_ctx_t ctx, + const nmod_poly_t modulus, + const char *var) +{ + fq_nmod_ctx_struct * fq_nmod_ctx; + + fq_nmod_ctx = flint_malloc(sizeof(fq_nmod_ctx_struct)); + + fq_nmod_ctx_init_modulus(fq_nmod_ctx, modulus, var); + fq_zech_ctx_init_fq_nmod_ctx(ctx, fq_nmod_ctx); + ctx->owns_fq_nmod_ctx = 1; +} + + +void +fq_zech_ctx_init_fq_nmod_ctx(fq_zech_ctx_t ctx, + fq_nmod_ctx_t fq_nmod_ctx) +{ + ulong i, n; + fq_nmod_t r, gen; + slong up, q; + fmpz_t result, order; + mp_limb_t j, nz, result_ui; + mp_limb_t *n_reverse_table; + + ctx->fq_nmod_ctx = fq_nmod_ctx; + ctx->owns_fq_nmod_ctx = 0; + + fmpz_init(order); + fq_nmod_ctx_order(order, fq_nmod_ctx); + + if (fmpz_bits(order) > FLINT_BITS) + { + flint_printf("Exception (fq_zech_ctx_init_nmod_ctx). Requires q < 2^FLINT_BITS\n"); + abort(); + } + + q = fmpz_get_ui(order); + up = fmpz_get_ui(fq_nmod_ctx_prime(fq_nmod_ctx)); + + ctx->p = up; + ctx->ppre = n_precompute_inverse(ctx->p); + ctx->qm1 = q - 1; + + if (up == 2) + { + ctx->qm1o2 = 0; + } + else + { + ctx->qm1o2 = ctx->qm1 / 2; + } + + ctx->qm1opm1 = ctx->qm1 / (up - 1); + + ctx->prime_root = n_primitive_root_prime(ctx->p); + + ctx->zech_log_table = (mp_limb_t *) flint_malloc(q * sizeof(mp_limb_t)); + ctx->prime_field_table = (mp_limb_t *) flint_malloc(up * sizeof(mp_limb_t)); + n_reverse_table = (mp_limb_t *) flint_malloc(q * sizeof(mp_limb_t)); + ctx->eval_table = (mp_limb_t *) flint_malloc(q * sizeof(mp_limb_t)); + + ctx->zech_log_table[ctx->qm1] = 0; + ctx->prime_field_table[0] = ctx->qm1; + n_reverse_table[0] = ctx->qm1; + ctx->eval_table[ctx->qm1] = 0; + + fq_nmod_init(r, ctx->fq_nmod_ctx); + fq_nmod_init(gen, ctx->fq_nmod_ctx); + fq_nmod_one(r, ctx->fq_nmod_ctx); + fq_nmod_gen(gen, ctx->fq_nmod_ctx); + + fmpz_init(result); + + for (i = 0; i < ctx->qm1; i++) + { + nmod_poly_evaluate_fmpz(result, r, fq_nmod_ctx_prime(fq_nmod_ctx)); + result_ui = fmpz_get_ui(result); + n_reverse_table[result_ui] = i; + ctx->eval_table[i] = result_ui; + if (r->length == 1) + { + ctx->prime_field_table[result_ui] = i; + } + fq_nmod_mul(r, r, gen, fq_nmod_ctx); + } + + i = 1; + for (i = 0; i < q; i++) + { + j = n_reverse_table[i]; + n = i; + if (n % up == up - 1) + { + nz = n - up + 1; + } + else + { + nz = n + 1; + } + ctx->zech_log_table[j] = n_reverse_table[nz]; + } + + fq_nmod_clear(r, fq_nmod_ctx); + fq_nmod_clear(gen, fq_nmod_ctx); + flint_free(n_reverse_table); + fmpz_clear(result); + fmpz_clear(order); +} diff --git a/external/flint-2.4.3/fq_zech/ctx_randtest.c b/external/flint-2.4.3/fq_zech/ctx_randtest.c new file mode 100644 index 0000000..6b1853c --- /dev/null +++ b/external/flint-2.4.3/fq_zech/ctx_randtest.c @@ -0,0 +1,51 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech.h" +#include "fq_nmod.h" +#include "ulong_extras.h" +#include "long_extras.h" +#include + +void +fq_zech_ctx_randtest(fq_zech_ctx_t ctx, flint_rand_t state) +{ + fmpz_t p; + slong max_d, d; + + fq_nmod_ctx_struct * fq_nmod_ctx; + + fq_nmod_ctx = flint_malloc(sizeof(fq_nmod_ctx_struct)); + + fmpz_init(p); + fmpz_set_ui(p, n_randprime(state, 2 + n_randint(state, 4), 1)); + max_d = floor(log(n_pow(2, 16)) / log(fmpz_get_ui(p))); + d = n_randint(state, max_d - 1) + 2; + fq_nmod_ctx_init(fq_nmod_ctx, p, d, "a"); + fq_zech_ctx_init_fq_nmod_ctx(ctx, fq_nmod_ctx); + fmpz_clear(p); + + ctx->owns_fq_nmod_ctx = 1; +} diff --git a/external/flint-2.4.3/fq_zech/doc/fq_zech.txt b/external/flint-2.4.3/fq_zech/doc/fq_zech.txt new file mode 100644 index 0000000..3fb595f --- /dev/null +++ b/external/flint-2.4.3/fq_zech/doc/fq_zech.txt @@ -0,0 +1,484 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +******************************************************************************* + + Context Management + +******************************************************************************* + +void fq_zech_ctx_init(fq_zech_ctx_t ctx, const fmpz_t p, + slong d, const char *var) + + Initialises the context for prime~$p$ and extension degree~$d$, + with name \code{var} for the generator. By default, it will try + use a Conway polynomial; if one is not available, a random + irreducible polynomial will be used. + + Assumes that $p$ is a prime and $p^d < 2^{FLINT_BITS}$. + + Assumes that the string \code{var} is a null-terminated string + of length at least one. + +int _fq_zech_ctx_init_conway(fq_zech_ctx_t ctx, const fmpz_t p, + slong d, const char *var) + + Attempts to initialise the context for prime~$p$ and extension + degree~$d$, with name \code{var} for the generator using a Conway + polynomial for the modulus. + + Returns $1$ if the Conway polynomial is in the database for the + given size and the initialization is successful; otherwise, + returns $0$. + + Assumes that $p$ is a prime and $p^d < 2^{FLINT_BITS}$. + + Assumes that the string \code{var} is a null-terminated string + of length at least one. + + +void fq_zech_ctx_init_conway(fq_zech_ctx_t ctx, const fmpz_t p, + slong d, const char *var) + + Initialises the context for prime~$p$ and extension degree~$d$, + with name \code{var} for the generator using a Conway polynomial + for the modulus. + + Assumes that $p$ is a prime and $p^d < 2^{FLINT_BITS}$. + + Assumes that the string \code{var} is a null-terminated string + of length at least one. + +void fq_zech_ctx_init_modulus(fq_zech_ctx_t ctx + nmod_poly_t modulus, + const char *var) + + Initialises the context for given \code{modulus} with name + \code{var} for the generator. + + Assumes that \code{modulus} is and irreducible polynomial over + $\mathbf{F}_{p}$. + + Assumes that the string \code{var} is a null-terminated string + of length at least one. + +void fq_zech_ctx_init_fq_nmod_ctx(fq_zech_ctx_t ctx, fq_nmod_ctx_t ctxn); + + Initializes the context \code{ctx} to be the Zech representation + for the finite field given by \code{ctxn}. + +void fq_zech_ctx_clear(fq_zech_ctx_t ctx) + + Clears all memory that has been allocated as part of the context. + +long fq_zech_ctx_degree(const fq_zech_ctx_t ctx) + + Returns the degree of the field extension + $[\mathbf{F}_{q} : \mathbf{F}_{p}]$, which + is equal to $\log_{p} q$. + +fmpz * fq_zech_ctx_prime(const fq_zech_ctx_t ctx) + + Returns a pointer to the prime $p$ in the context. + +void fq_zech_ctx_order(fmpz_t f, const fq_zech_ctx_t ctx) + + Sets $f$ to be the size of the finite field. + +mp_limb_t fq_zech_ctx_order_ui(const fq_zech_ctx_t ctx) + + Returns the size of the finite field. + +int fq_zech_ctx_fprint(FILE * file, const fq_zech_ctx_t ctx) + + Prints the context information to {\tt{file}}. Returns 1 for a + success and a negative number for an error. + +void fq_zech_ctx_print(const fq_zech_ctx_t ctx) + + Prints the context information to {\tt{stdout}}. + +void fq_zech_ctx_randtest(fq_zech_ctx_t ctx) + + Initializes \code{ctx} to a random finite field. Assumes that + \code{fq_zech_ctx_init} as not been called on \code{ctx} already. + +void fq_zech_ctx_randtest_reducible(fq_zech_ctx_t ctx) + + Since the Zech logarithm representation does not work with a + non-irreducible modulus, does the same as + \code{fq_zech_ctx_randtest}. + +******************************************************************************* + + Memory management + +******************************************************************************* + +void fq_zech_init(fq_zech_t rop, const fq_zech_ctx_t ctx) + + Initialises the element \code{rop}, setting its value to~$0$. + +void fq_zech_init2(fq_zech_t rop, const fq_zech_ctx_t ctx) + + Initialises \code{poly} with at least enough space for it to be an element + of \code{ctx} and sets it to~$0$. + +void fq_zech_clear(fq_zech_t rop, const fq_zech_ctx_t ctx) + + Clears the element \code{rop}. + +void _fq_zech_sparse_reduce(mp_ptr R, slong lenR, const fq_zech_ctx_t ctx) + + Reduces \code{(R, lenR)} modulo the polynomial $f$ given by the + modulus of \code{ctx}. + +void _fq_zech_dense_reduce(mp_ptr R, slong lenR, const fq_zech_ctx_t ctx) + + Reduces \code{(R, lenR)} modulo the polynomial $f$ given by the + modulus of \code{ctx} using Newton division. + +void _fq_zech_reduce(mp_ptr r, slong lenR, const fq_zech_ctx_t ctx) + + Reduces \code{(R, lenR)} modulo the polynomial $f$ given by the + modulus of \code{ctx}. Does either sparse or dense reduction + based on \code{ctx->sparse_modulus}. + +void fq_zech_reduce(fq_zech_t rop, const fq_zech_ctx_t ctx) + + Reduces the polynomial \code{rop} as an element of + $\mathbf{F}_p[X] / (f(X))$. + +******************************************************************************* + + Basic arithmetic + +******************************************************************************* + +void fq_zech_add(fq_zech_t rop, const fq_zech_t op1, const fq_zech_t op2, + const fq_zech_ctx_t ctx) + + Sets \code{rop} to the sum of \code{op1} and \code{op2}. + +void fq_zech_sub(fq_zech_t rop, const fq_zech_t op1, const fq_zech_t op2, + const fq_zech_ctx_t ctx) + + Sets \code{rop} to the difference of \code{op1} and \code{op2}. + +void fq_zech_sub_one(fq_zech_t rop, const fq_zech_t op1, const fq_zech_ctx_t ctx) + + Sets \code{rop} to the difference of \code{op1} and $1$. + +void fq_zech_neg(fq_zech_t rop, const fq_zech_t op, const fq_zech_ctx_t ctx) + + Sets \code{rop} to the negative of \code{op}. + +void fq_zech_mul(fq_zech_t rop, const fq_zech_t op1, const fq_zech_t op2, + const fq_zech_ctx_t ctx) + + Sets \code{rop} to the product of \code{op1} and \code{op2}, + reducing the output in the given context. + +void fq_zech_mul_fmpz(fq_zech_t rop, const fq_zech_t op, const fmpz_t x, + const fq_zech_ctx_t ctx) + + Sets \code{rop} to the product of \code{op} and $x$, + reducing the output in the given context. + +void fq_zech_mul_si(fq_zech_t rop, const fq_zech_t op, slong x, + const fq_zech_ctx_t ctx) + + Sets \code{rop} to the product of \code{op} and $x$, + reducing the output in the given context. + +void fq_zech_mul_ui(fq_zech_t rop, const fq_zech_t op, ulong x, + const fq_zech_ctx_t ctx) + + Sets \code{rop} to the product of \code{op} and $x$, + reducing the output in the given context. + +void fq_zech_sqr(fq_zech_t rop, const fq_zech_t op, const fq_zech_ctx_t ctx) + + Sets \code{rop} to the square of \code{op}, + reducing the output in the given context. + +void _fq_zech_inv(mp_ptr *rop, mp_srcptr *op, slong len, const fq_zech_ctx_t ctx) + + Sets \code{(rop, d)} to the inverse of the non-zero element + \code{(op, len)}. + +void fq_zech_inv(fq_zech_t rop, const fq_zech_t op, const fq_zech_ctx_t ctx) + + Sets \code{rop} to the inverse of the non-zero element \code{op}. + +void _fq_zech_pow(mp_ptr *rop, mp_srcptr *op, slong len, const fmpz_t e, + const fq_zech_ctx_t ctx) + + Sets \code{(rop, 2*d-1)} to \code{(op,len)} raised to the power~$e$, + reduced modulo $f(X)$, the modulus of \code{ctx}. + + Assumes that $e \geq 0$ and that \code{len} is positive and at most~$d$. + + Although we require that \code{rop} provides space for + $2d - 1$ coefficients, the output will be reduced modulo + $f(X)$, which is a polynomial of degree~$d$. + + Does not support aliasing. + +void fq_zech_pow(fq_zech_t rop, const fq_zech_t op, const fmpz_t e, + const fq_zech_ctx_t ctx) + + Sets \code{rop} the \code{op} raised to the power~$e$. + + Currently assumes that $e \geq 0$. + + Note that for any input \code{op}, \code{rop} is set to~$1$ + whenever $e = 0$. + +void fq_zech_pow_ui(fq_zech_t rop, const fq_zech_t op, const ulong e, + const fq_zech_ctx_t ctx) + + Sets \code{rop} the \code{op} raised to the power~$e$. + + Currently assumes that $e \geq 0$. + + Note that for any input \code{op}, \code{rop} is set to~$1$ + whenever $e = 0$. + +******************************************************************************* + + Roots + +******************************************************************************* + +void fq_zech_pth_root(fq_zech_t rop, const fq_zech_t op1, + const fq_zech_ctx_t ctx) + + Sets \code{rop} to a $p^{th}$ root root of \code{op1}. Currently, + this computes the root by raising \code{op1} to $p^{d-1}$ where + $d$ is the degree of the extension. + +******************************************************************************* + + Output + +******************************************************************************* + +int fq_zech_fprint_pretty(FILE *file, const fq_zech_t op, + const fq_zech_ctx_t ctx) + + Prints a pretty representation of \code{op} to \code{file}. + + In the current implementation, always returns~$1$. The return code is + part of the function's signature to allow for a later implementation to + return the number of characters printed or a non-positive error code. + +int fq_zech_print_pretty(const fq_zech_t op, const fq_zech_ctx_t ctx) + + Prints a pretty representation of \code{op} to \code{stdout}. + + In the current implementation, always returns~$1$. The return code is + part of the function's signature to allow for a later implementation to + return the number of characters printed or a non-positive error code. + +void fq_zech_fprint(FILE * file, const fq_zech_t op, const fq_zech_ctx_t ctx) + + Prints a representation of \code{op} to \code{file}. + +void fq_zech_print(const fq_zech_t op, const fq_zech_ctx_t ctx) + + Prints a representation of \code{op} to \code{stdout}. + +char * fq_zech_get_str(const fq_zech_t op, const fq_zech_ctx_t ctx) + + Returns the plain FLINT string representation of the element + \code{op}. + +char * fq_zech_get_str_pretty(const fq_zech_t op, const fq_zech_ctx_t ctx) + + Returns a pretty representation of the element~\code{op} using the + null-terminated string \code{x} as the variable name. + +******************************************************************************* + + Randomisation + +******************************************************************************* + +void fq_zech_randtest(fq_zech_t rop, flint_rand_t state, + const fq_zech_ctx_t ctx) + + Generates a random element of $\mathbb{F}_q$. + +void fq_zech_randtest_not_zero(fq_zech_t rop, flint_rand_t state, + const fq_zech_ctx_t ctx) + + Generates a random non-zero element of $\mathbb{F}_q$. + +void fq_zech_randtest_dense(fq_zech_t rop, flint_rand_t state, + const fq_zech_ctx_t ctx) + + Generates a random element of $\mathbb{F}_q$ which has an + underlying polynomial with dense coefficients. + +******************************************************************************* + + Assignments and conversions + +******************************************************************************* + +void fq_zech_set(fq_zech_t rop, const fq_zech_t op, const fq_zech_ctx_t ctx) + + Sets \code{rop} to \code{op}. + +void fq_zech_set_ui(fq_zech_t rop, const ulong x, const fq_zech_ctx_t ctx) + + Sets \code{rop} to \code{x}, considered as an element of + $\mathbb{F}_p$. + +void fq_zech_set_fmpz(fq_zech_t rop, const fmpz_t x, const fq_zech_ctx_t ctx) + + Sets \code{rop} to \code{x}, considered as an element of + $\mathbb{F}_p$. + +void fq_zech_swap(fq_zech_t op1, fq_zech_t op2, const fq_zech_ctx_t ctx) + + Swaps the two elements \code{op1} and \code{op2}. + +void fq_zech_zero(fq_zech_t rop, const fq_zech_ctx_t ctx) + + Sets \code{rop} to zero. + +void fq_zech_one(fq_zech_t rop, const fq_zech_ctx_t ctx) + + Sets \code{rop} to one, reduced in the given context. + +void fq_zech_gen(fq_zech_t rop, const fq_zech_ctx_t ctx) + + Sets \code{rop} to a multiplicative generator for the finite field. + +void fq_zech_get_fq_nmod(fq_nmod_t rop, const fq_zech_t op, + const fq_zech_ctx_t ctx) + + Sets \code{rop} to the \code{fq_nmod_t} element corresponding to + \code{op}. + +void fq_zech_set_fq_nmod(fq_zech_t rop, const fq_nmod_t op, + const fq_zech_ctx_t ctx) + + Sets \code{rop} to the \code{fq_zech_t} element corresponding to + \code{op}. + + +******************************************************************************* + + Comparison + +******************************************************************************* + +int fq_zech_is_zero(const fq_zech_t op, const fq_zech_ctx_t ctx) + + Returns whether \code{op} is equal to zero. + +int fq_zech_is_one(const fq_zech_t op, const fq_zech_ctx_t ctx) + + Returns whether \code{op} is equal to one. + +int fq_zech_equal(const fq_zech_t op1, const fq_zech_t op2, + const fq_zech_ctx_t ctx) + + Returns whether \code{op1} and \code{op2} are equal. + +int fq_zech_is_invertible(const fq_zech_t op, const fq_zech_ctx_t ctx) + + Returns whether \code{op} is an invertible element. + +int fq_zech_is_invertible_f(fq_zech_t f, const fq_zech_t op, + const fq_zech_ctx_t ctx) + + Returns whether \code{op} is an invertible element. If it is not, + then \code{f} is set of a factor of the modulus. Since the + modulus for an \code{fq_zech_ctx_t} is always irreducible, then + any non-zero \code{op} will be invertible. + +******************************************************************************* + + Special functions + +******************************************************************************* + +void fq_zech_trace(fq_zech_t rop, const fq_zech_t op, const fq_zech_ctx_t ctx) + + Sets \code{rop} to the trace of \code{op}. + + For an element $a \in \mathbb{F}_q$, multiplication by $a$ defines + a $\mathbb{F}_p$-linear map on $\mathbb{F}_q$. We define the + trace of $a$ as the trace of this map. Equivalently, if $\Sigma$ + generates $\Gal(\mathbb{F}_q / \mathbb{F}_p)$ then the trace of + $a$ is equal to $\sum_{i=0}^{d-1} \Sigma^i (a)$, where $d = + \log_{p} q$. + +void fq_zech_norm(fq_zech_t rop, const fq_zech_t op, const fq_zech_ctx_t ctx) + + Computes the norm of \code{op}. + + For an element $a \in \mathbb{F}_q$, multiplication by $a$ defines + a $\mathbb{F}_p$-linear map on $\mathbb{F}_q$. We define the norm + of $a$ as the determinant of this map. Equivalently, if $\Sigma$ generates + $\Gal(\mathbb{F}_q / \mathbb{F}_p)$ then the trace of $a$ is equal to + $\prod_{i=0}^{d-1} \Sigma^i (a)$, where + $d = \text{dim}_{\mathbb{F}_p}(\mathbb{F}_q)$. + + Algorithm selection is automatic depending on the input. + +void fq_zech_frobenius(fq_zech_t rop, const fq_zech_t op, slong e, + const fq_zech_ctx_t ctx) + + Evaluates the homomorphism $\Sigma^e$ at \code{op}. + + Recall that $\mathbb{F}_q / \mathbb{F}_p$ is Galois with Galois group + $\langle \sigma \rangle$, which is also isomorphic to + $\mathbf{Z}/d\mathbf{Z}$, where + $\sigma \in \Gal(\mathbf{F}_q/\mathbf{F}_p)$ is the Frobenius element + $\sigma \colon x \mapsto x^p$. + +******************************************************************************* + + Bit packing + +******************************************************************************* + +void fq_zech_bit_pack(fmpz_t f, const fq_zech_t op, mp_bitcnt_t bit_size, + const fq_zech_ctx_t ctx) + + Packs \code{op} into bitfields of size \code{bit_size}, writing the + result to \code{f}. + +void fq_zech_bit_unpack(fq_zech_t rop, const fmpz_t f, mp_bitcnt_t bit_size, + const fq_zech_ctx_t ctx) + + Unpacks into \code{rop} the element with coefficients packed into + fields of size \code{bit_size} as represented by the integer + \code{f}. diff --git a/external/flint-2.4.3/fq_zech/frobenius.c b/external/flint-2.4.3/fq_zech/frobenius.c new file mode 100644 index 0000000..932a23d --- /dev/null +++ b/external/flint-2.4.3/fq_zech/frobenius.c @@ -0,0 +1,53 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech.h" + +void +fq_zech_frobenius(fq_zech_t rop, const fq_zech_t op, slong e, + const fq_zech_ctx_t ctx) +{ + double qm1_inv; + slong d = fq_zech_ctx_degree(ctx); + + e = e % d; + if (e < 0) + e += d; + + if (fq_zech_is_zero(op, ctx)) + { + fq_zech_zero(rop, ctx); + } + else if (e == 0) + { + fq_zech_set(rop, op, ctx); + } + else + { + qm1_inv = n_precompute_inverse(ctx->qm1); + e = n_powmod(ctx->p, e, ctx->qm1); + rop->value = n_mulmod_precomp(op->value, e, ctx->qm1, qm1_inv); + } +} diff --git a/external/flint-2.4.3/fq_zech/get_fq_nmod.c b/external/flint-2.4.3/fq_zech/get_fq_nmod.c new file mode 100644 index 0000000..1bed397 --- /dev/null +++ b/external/flint-2.4.3/fq_zech/get_fq_nmod.c @@ -0,0 +1,46 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech.h" + +void +fq_zech_get_fq_nmod(fq_nmod_t rop, const fq_zech_t op, const fq_zech_ctx_t ctx) +{ + slong i; + mp_limb_t q, r; + + nmod_poly_fit_length(rop, fq_zech_ctx_degree(ctx)); + + q = ctx->eval_table[op->value]; + i = 0; + while (q >= ctx->p) + { + r = n_divrem2_precomp(&q, q, ctx->p, ctx->ppre); + nmod_poly_set_coeff_ui(rop, i, r); + i ++; + } + nmod_poly_set_coeff_ui(rop, i, q); + +} diff --git a/external/flint-2.4.3/fq_zech/get_str.c b/external/flint-2.4.3/fq_zech/get_str.c new file mode 100644 index 0000000..2711708 --- /dev/null +++ b/external/flint-2.4.3/fq_zech/get_str.c @@ -0,0 +1,34 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech.h" + +char * +fq_zech_get_str(const fq_zech_t op, const fq_zech_ctx_t ctx) +{ + char *s = flint_malloc(n_clog(op->value, 10) * sizeof(char)); + flint_sprintf(s, "%wd", op->value); + return s; +} diff --git a/external/flint-2.4.3/fq_zech/get_str_pretty.c b/external/flint-2.4.3/fq_zech/get_str_pretty.c new file mode 100644 index 0000000..6073408 --- /dev/null +++ b/external/flint-2.4.3/fq_zech/get_str_pretty.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech.h" +#include + +char * +fq_zech_get_str_pretty(const fq_zech_t op, const fq_zech_ctx_t ctx) +{ + char *s = flint_malloc((n_clog(op->value, 10) + strlen(ctx->fq_nmod_ctx->var) + 1) * + sizeof(char)); + flint_sprintf(s, "%s^%wd", ctx->fq_nmod_ctx->var, op->value); + return s; +} diff --git a/external/flint-2.4.3/fq_zech/inv.c b/external/flint-2.4.3/fq_zech/inv.c new file mode 100644 index 0000000..74166b4 --- /dev/null +++ b/external/flint-2.4.3/fq_zech/inv.c @@ -0,0 +1,45 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ +#include +#include + +#include "fq_zech.h" + +void +fq_zech_inv(fq_zech_t rop, const fq_zech_t op, const fq_zech_ctx_t ctx) +{ + if (fq_zech_is_zero(op, ctx)) + { + flint_printf("Exception (fq_inv). Zero is not invertible.\n"); + abort(); + } + if (fq_zech_is_one(op, ctx)) + { + fq_zech_one(rop, ctx); + return; + } + + rop->value = ctx->qm1 - op->value; +} diff --git a/external/flint-2.4.3/fq_zech/mul.c b/external/flint-2.4.3/fq_zech/mul.c new file mode 100644 index 0000000..23a3665 --- /dev/null +++ b/external/flint-2.4.3/fq_zech/mul.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ +#include +#include + +#include "fq_zech.h" + +void +fq_zech_mul(fq_zech_t rop, const fq_zech_t op1, const fq_zech_t op2, + const fq_zech_ctx_t ctx) +{ + if (op1->value == ctx->qm1 || op2->value == ctx->qm1) + { + rop->value = ctx->qm1; + return; + } + rop->value = n_addmod(op1->value, op2->value, ctx->qm1); +} diff --git a/external/flint-2.4.3/fq_zech/mul_fmpz.c b/external/flint-2.4.3/fq_zech/mul_fmpz.c new file mode 100644 index 0000000..1fc5733 --- /dev/null +++ b/external/flint-2.4.3/fq_zech/mul_fmpz.c @@ -0,0 +1,43 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech.h" + +void +fq_zech_mul_fmpz(fq_zech_t rop, const fq_zech_t op, const fmpz_t x, + const fq_zech_ctx_t ctx) +{ + mp_limb_t ux; + fmpz_t y; + + fmpz_init(y); + fmpz_mod_ui(y, x, ctx->p); + + ux = fmpz_get_ui(y); + + fmpz_clear(y); + + fq_zech_mul_ui(rop, op, ux, ctx); +} diff --git a/external/flint-2.4.3/fq_zech/mul_si.c b/external/flint-2.4.3/fq_zech/mul_si.c new file mode 100644 index 0000000..3864ce3 --- /dev/null +++ b/external/flint-2.4.3/fq_zech/mul_si.c @@ -0,0 +1,49 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech.h" + +void +fq_zech_mul_si(fq_zech_t rop, const fq_zech_t op, const slong x, + const fq_zech_ctx_t ctx) +{ + mp_limb_t y; + if (x == 0 || fq_zech_is_zero(op, ctx)) + { + fq_zech_zero(rop, ctx); + return; + } + if (x < 0) + { + y = -x; + fq_zech_mul_ui(rop, op, y, ctx); + fq_zech_neg(rop, rop, ctx); + } + else + { + y = x; + fq_zech_mul_ui(rop, op, y, ctx); + } +} diff --git a/external/flint-2.4.3/fq_zech/mul_ui.c b/external/flint-2.4.3/fq_zech/mul_ui.c new file mode 100644 index 0000000..28d6cfe --- /dev/null +++ b/external/flint-2.4.3/fq_zech/mul_ui.c @@ -0,0 +1,48 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech.h" + +void +fq_zech_mul_ui(fq_zech_t rop, const fq_zech_t op, const mp_limb_t x, + const fq_zech_ctx_t ctx) +{ + mp_limb_t b; + + if (x == 0 || fq_zech_is_zero(op, ctx)) + { + fq_zech_zero(rop, ctx); + return; + } + + b = x; + if (x >= ctx->p) + b = n_mod2_precomp(x, ctx->p, ctx->ppre); + + if (b == 0) + fq_zech_zero(rop, ctx); + else + rop->value = n_addmod(op->value, ctx->prime_field_table[b], ctx->qm1); +} diff --git a/external/flint-2.4.3/fq_zech/neg.c b/external/flint-2.4.3/fq_zech/neg.c new file mode 100644 index 0000000..ab101e1 --- /dev/null +++ b/external/flint-2.4.3/fq_zech/neg.c @@ -0,0 +1,43 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ +#include +#include + +#include "fq_zech.h" + +void +fq_zech_neg(fq_zech_t rop, const fq_zech_t op1, const fq_zech_ctx_t ctx) +{ + if (op1->value == ctx->qm1) + { + rop->value = ctx->qm1; + return; + } + rop->value = op1->value + ctx->qm1o2; + if (rop->value >= ctx->qm1) + { + rop->value -= ctx->qm1; + } +} diff --git a/external/flint-2.4.3/fq_zech/norm.c b/external/flint-2.4.3/fq_zech/norm.c new file mode 100644 index 0000000..a68d158 --- /dev/null +++ b/external/flint-2.4.3/fq_zech/norm.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech.h" + +void fq_zech_norm(fmpz_t rop, const fq_zech_t op, const fq_zech_ctx_t ctx) +{ + if (fq_zech_is_zero(op, ctx)) + { + fmpz_zero(rop); + } + else + { + fmpz_set_ui(rop, n_powmod(ctx->prime_root, op->value, ctx->p)); + } +} diff --git a/external/flint-2.4.3/fq_zech/pow.c b/external/flint-2.4.3/fq_zech/pow.c new file mode 100644 index 0000000..8435a85 --- /dev/null +++ b/external/flint-2.4.3/fq_zech/pow.c @@ -0,0 +1,68 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech.h" + +void +fq_zech_pow(fq_zech_t rop, const fq_zech_t op, const fmpz_t e, + const fq_zech_ctx_t ctx) +{ + if (fmpz_sgn(e) < 0) + { + flint_printf("Exception (fq_zech_pow). e < 0.\n"); + abort(); + } + if (fmpz_is_zero(e)) + { + fq_zech_one(rop, ctx); + } + else if (fq_zech_is_zero(op, ctx)) + { + fq_zech_zero(rop, ctx); + } + else if (fmpz_is_one(e)) + { + fq_zech_set(rop, op, ctx); + } + else + { + fmpz_t new_e; + fmpz_init(new_e); + fmpz_mul_ui(new_e, e, op->value); + fmpz_mod_ui(new_e, new_e, ctx->qm1); + rop->value = fmpz_get_ui(new_e); + fmpz_clear(new_e); + } +} + +/* TODO: Move into separate function and optimize */ +void fq_zech_pow_ui(fq_zech_t rop, const fq_zech_t op, + const ulong e, const fq_zech_ctx_t ctx) +{ + fmpz_t exp; + fmpz_init_set_ui(exp, e); + fq_zech_pow(rop, op, exp, ctx); + fmpz_clear(exp); +} diff --git a/external/flint-2.4.3/fq_zech/pth_root.c b/external/flint-2.4.3/fq_zech/pth_root.c new file mode 100644 index 0000000..b2fd81e --- /dev/null +++ b/external/flint-2.4.3/fq_zech/pth_root.c @@ -0,0 +1,51 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech.h" + +void +fq_zech_pth_root(fq_zech_t rop, const fq_zech_t op1, const fq_zech_ctx_t ctx) +{ + slong i, d; + mp_limb_t e; + double qm1inv; + + if (fq_zech_is_zero(op1, ctx) || fq_zech_is_one(op1, ctx)) + { + rop->value = op1->value; + return; + } + + d = fq_zech_ctx_degree(ctx) - 1; + qm1inv = n_precompute_inverse(ctx->qm1); + + e = op1->value; + for (i = 0; i < d; i++) + { + e = n_mulmod_precomp(ctx->p, e, ctx->qm1, qm1inv); + } + + rop->value = e; +} diff --git a/external/flint-2.4.3/fq_zech/randtest.c b/external/flint-2.4.3/fq_zech/randtest.c new file mode 100644 index 0000000..0710005 --- /dev/null +++ b/external/flint-2.4.3/fq_zech/randtest.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech.h" + +void +fq_zech_randtest(fq_zech_t rop, flint_rand_t state, const fq_zech_ctx_t ctx) +{ + rop->value = n_randint(state, ctx->qm1 + 1); +} + +void +fq_zech_randtest_not_zero(fq_zech_t rop, flint_rand_t state, + const fq_zech_ctx_t ctx) +{ + rop->value = n_randint(state, ctx->qm1); +} diff --git a/external/flint-2.4.3/fq_zech/set_fmpz.c b/external/flint-2.4.3/fq_zech/set_fmpz.c new file mode 100644 index 0000000..32fa845 --- /dev/null +++ b/external/flint-2.4.3/fq_zech/set_fmpz.c @@ -0,0 +1,43 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech.h" + +void +fq_zech_set_fmpz(fq_zech_t rop, const fmpz_t x, const fq_zech_ctx_t ctx) +{ + /* TODO: Clean this up */ + mp_limb_t ux; + fmpz_t y; + + fmpz_init(y); + fmpz_mod_ui(y, x, ctx->p); + + ux = fmpz_get_ui(y); + fq_zech_one(rop, ctx); + fq_zech_mul_ui(rop, rop, ux, ctx); + + fmpz_clear(y); +} diff --git a/external/flint-2.4.3/fq_zech/set_fq_nmod.c b/external/flint-2.4.3/fq_zech/set_fq_nmod.c new file mode 100644 index 0000000..52c78b6 --- /dev/null +++ b/external/flint-2.4.3/fq_zech/set_fq_nmod.c @@ -0,0 +1,46 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include + +#include "fq_zech.h" + +void +fq_zech_set_fq_nmod(fq_zech_t rop, const fq_nmod_t op, const fq_zech_ctx_t ctx) +{ + mp_limb_t i; + fq_zech_t t; + fq_zech_zero(rop, ctx); + for (i = 0; i < op->length; i++) + { + if (op->coeffs[i] == 0) + { + continue; + } + t->value = i; + fq_zech_mul_ui(t, t, op->coeffs[i], ctx); + fq_zech_add(rop, rop, t, ctx); + } +} diff --git a/external/flint-2.4.3/fq_zech/sqr.c b/external/flint-2.4.3/fq_zech/sqr.c new file mode 100644 index 0000000..7736031 --- /dev/null +++ b/external/flint-2.4.3/fq_zech/sqr.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ +#include "fq_zech.h" + +void +fq_zech_sqr(fq_zech_t rop, const fq_zech_t op, const fq_zech_ctx_t ctx) +{ + if (op->value == ctx->qm1) + { + rop->value = ctx->qm1; + } + else + { + rop->value = n_addmod(op->value, op->value, ctx->qm1); + } +} diff --git a/external/flint-2.4.3/fq_zech/sub.c b/external/flint-2.4.3/fq_zech/sub.c new file mode 100644 index 0000000..6a969c5 --- /dev/null +++ b/external/flint-2.4.3/fq_zech/sub.c @@ -0,0 +1,53 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech.h" + +void +fq_zech_sub(fq_zech_t rop, const fq_zech_t op1, const fq_zech_t op2, + const fq_zech_ctx_t ctx) +{ + mp_limb_t index, c; + if (op2->value == ctx->qm1) + { + rop->value = op1->value; + } + else if (op1->value == ctx->qm1) + { + fq_zech_neg(rop, op2, ctx); + } + else + { + index = n_submod(op2->value, op1->value, ctx->qm1); + index = n_submod(index, ctx->qm1o2, ctx->qm1); + + c = ctx->zech_log_table[index]; + if (c != ctx->qm1) + { + c = n_addmod(c, op1->value, ctx->qm1); + } + rop->value = c; + } +} diff --git a/external/flint-2.4.3/fq_zech/sub_one.c b/external/flint-2.4.3/fq_zech/sub_one.c new file mode 100644 index 0000000..12e9e73 --- /dev/null +++ b/external/flint-2.4.3/fq_zech/sub_one.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech.h" + +void fq_zech_sub_one(fq_zech_t rop, const fq_zech_t op1, const fq_zech_ctx_t ctx) +{ + fq_zech_t one; + + fq_zech_init(one, ctx); + fq_zech_one(one, ctx); + fq_zech_sub(rop, op1, one, ctx); + fq_zech_clear(one, ctx); +} diff --git a/external/flint-2.4.3/fq_zech/test/t-add.c b/external/flint-2.4.3/fq_zech/test/t-add.c new file mode 100644 index 0000000..4aa57c2 --- /dev/null +++ b/external/flint-2.4.3/fq_zech/test/t-add.c @@ -0,0 +1,224 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include +#include + +#include "fq_zech.h" +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int j, i, result; + fq_zech_ctx_t ctx; + FLINT_TEST_INIT(state); + + flint_printf("add... "); + fflush(stdout); + + for (j = 0; j < 10; j++) + { + fq_zech_ctx_randtest(ctx, state); + + /* Check aliasing: a = a + b */ + for (i = 0; i < 200; i++) + { + fq_zech_t a, b, c; + + fq_zech_init(a, ctx); + fq_zech_init(b, ctx); + fq_zech_init(c, ctx); + + fq_zech_randtest(a, state, ctx); + fq_zech_randtest(b, state, ctx); + + fq_zech_add(c, a, b, ctx); + fq_zech_add(a, a, b, ctx); + + result = (fq_zech_equal(a, c, ctx)); + if (!result) + { + flint_printf("FAIL a = a + b:\n\n"); + fq_zech_ctx_print(ctx); + flint_printf("\n"); + flint_printf("a = "), fq_zech_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), fq_zech_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), fq_zech_print_pretty(c, ctx), flint_printf("\n"); + abort(); + } + + fq_zech_clear(a, ctx); + fq_zech_clear(b, ctx); + fq_zech_clear(c, ctx); + } + + /* Check aliasing: b = a + b */ + for (i = 0; i < 200; i++) + { + fq_zech_t a, b, c; + + fq_zech_init(a, ctx); + fq_zech_init(b, ctx); + fq_zech_init(c, ctx); + + fq_zech_randtest(a, state, ctx); + fq_zech_randtest(b, state, ctx); + + fq_zech_add(c, a, b, ctx); + fq_zech_add(b, a, b, ctx); + + result = (fq_zech_equal(b, c, ctx)); + if (!result) + { + flint_printf("FAIL b = a + b:\n\n"); + fq_zech_ctx_print(ctx); + flint_printf("\n"); + flint_printf("a = "), fq_zech_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), fq_zech_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), fq_zech_print_pretty(c, ctx), flint_printf("\n"); + abort(); + } + + fq_zech_clear(a, ctx); + fq_zech_clear(b, ctx); + fq_zech_clear(c, ctx); + } + + /* Check aliasing: a = a + a */ + for (i = 0; i < 2000; i++) + { + fq_zech_t a, c; + + fq_zech_init(a, ctx); + fq_zech_init(c, ctx); + + fq_zech_randtest(a, state, ctx); + + fq_zech_add(c, a, a, ctx); + fq_zech_add(a, a, a, ctx); + + result = (fq_zech_equal(a, c, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + fq_zech_ctx_print(ctx); + flint_printf("\n"); + flint_printf("a = "), fq_zech_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("c = "), fq_zech_print_pretty(c, ctx), flint_printf("\n"); + abort(); + } + + fq_zech_clear(a, ctx); + fq_zech_clear(c, ctx); + } + + /* Check that a + b == b + a */ + for (i = 0; i < 200; i++) + { + fq_zech_t a, b, c1, c2; + + fq_zech_init(a, ctx); + fq_zech_init(b, ctx); + fq_zech_init(c1, ctx); + fq_zech_init(c2, ctx); + + fq_zech_randtest(a, state, ctx); + fq_zech_randtest(b, state, ctx); + + fq_zech_add(c1, a, b, ctx); + fq_zech_add(c2, b, a, ctx); + + result = (fq_zech_equal(c1, c2, ctx)); + if (!result) + { + flint_printf("FAIL a + b = b + a\n\n"); + fq_zech_ctx_print(ctx); + flint_printf("\n"); + flint_printf("a = "), fq_zech_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), fq_zech_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c1 = "), fq_zech_print_pretty(c1, ctx), flint_printf("\n"); + flint_printf("c2 = "), fq_zech_print_pretty(c2, ctx), flint_printf("\n"); + abort(); + } + + fq_zech_clear(a, ctx); + fq_zech_clear(b, ctx); + fq_zech_clear(c1, ctx); + fq_zech_clear(c2, ctx); + } + + /* Check that (a + b) + c == a + (b + c) */ + for (i = 0; i < 2000; i++) + { + fq_zech_t a, b, c, lhs, rhs; + + fq_zech_init(a, ctx); + fq_zech_init(b, ctx); + fq_zech_init(c, ctx); + fq_zech_init(lhs, ctx); + fq_zech_init(rhs, ctx); + + fq_zech_randtest(a, state, ctx); + fq_zech_randtest(b, state, ctx); + fq_zech_randtest(c, state, ctx); + + fq_zech_add(lhs, a, b, ctx); + fq_zech_add(lhs, lhs, c, ctx); + fq_zech_add(rhs, b, c, ctx); + fq_zech_add(rhs, a, rhs, ctx); + + result = (fq_zech_equal(lhs, rhs, ctx)); + if (!result) + { + flint_printf("FAIL (a+b)+c == a + (b+c):\n\n"); + fq_zech_ctx_print(ctx); + flint_printf("\n"); + flint_printf("a = "), fq_zech_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), fq_zech_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), fq_zech_print_pretty(c, ctx), flint_printf("\n"); + flint_printf("lhs = "), fq_zech_print_pretty(lhs, ctx), flint_printf("\n"); + flint_printf("rhs = "), fq_zech_print_pretty(rhs, ctx), flint_printf("\n"); + abort(); + } + + fq_zech_clear(a, ctx); + fq_zech_clear(b, ctx); + fq_zech_clear(c, ctx); + fq_zech_clear(lhs, ctx); + fq_zech_clear(rhs, ctx); + } + + fq_zech_ctx_clear(ctx); + } + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fq_zech/test/t-ctx_init.c b/external/flint-2.4.3/fq_zech/test/t-ctx_init.c new file mode 100644 index 0000000..df172eb --- /dev/null +++ b/external/flint-2.4.3/fq_zech/test/t-ctx_init.c @@ -0,0 +1,121 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include +#include + +#include "fq_zech.h" +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + slong primes[10] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29 }; + slong exponents[10] = { 16, 10, 6, 5, 4, 4, 3, 3, 3, 3 }; + int i, j; + slong d; + fmpz_t p, e; + fq_nmod_ctx_t fq_nmod_ctx; + fq_nmod_t lhs, rhs, one; + fq_zech_ctx_t ctx; + FLINT_TEST_INIT(state); + + flint_printf("ctx_init... "); + + fflush(stdout); + + fmpz_init(p); + fmpz_init(e); + + for (i = 0; i < 10; i++) + { + fmpz_set_ui(p, primes[i]); + + for (d = 2; d < exponents[i]; d++) + { + fq_nmod_ctx_init_conway(fq_nmod_ctx, p, d, "a"); + fq_zech_ctx_init_fq_nmod_ctx(ctx, fq_nmod_ctx); + fq_nmod_init(lhs, fq_nmod_ctx); + fq_nmod_init(rhs, fq_nmod_ctx); + fq_nmod_init(one, fq_nmod_ctx); + + fq_nmod_one(one, fq_nmod_ctx); + + + for (j = 0; j < ctx->qm1; j++) + { + /* Skip the cases where a^j + 1 == 0 */ + if (primes[i] == 2 && i == 0) + { + continue; + } + if (j == ctx->qm1 / 2) + { + continue; + } + + /* lhs = a^Z(j) */ + fmpz_set_ui(e, ctx->zech_log_table[j]); + fq_nmod_gen(lhs, fq_nmod_ctx); + fq_nmod_pow(lhs, lhs, e, fq_nmod_ctx); + + /* rhs = a^j + 1 */ + fmpz_set_ui(e, j); + fq_nmod_gen(rhs, fq_nmod_ctx); + fq_nmod_pow(rhs, rhs, e, fq_nmod_ctx); + fq_nmod_add(rhs, rhs, one, fq_nmod_ctx); + + if (!fq_nmod_equal(lhs, rhs, fq_nmod_ctx)) + { + flint_printf("FAIL:\n\n"); + flint_printf("K = GF(%wd^%wd)\n", primes[i], d); + flint_printf("Z(%d) = %wd\n", j, ctx->zech_log_table[j]); + flint_printf("LHS: "); + fq_nmod_print_pretty(lhs, fq_nmod_ctx); + flint_printf("\n"); + flint_printf("RHS: "); + fq_nmod_print_pretty(rhs, fq_nmod_ctx); + flint_printf("\n"); + abort(); + } + } + + fq_nmod_clear(lhs, fq_nmod_ctx); + fq_nmod_clear(rhs, fq_nmod_ctx); + fq_nmod_clear(one, fq_nmod_ctx); + + fq_zech_ctx_clear(ctx); + fq_nmod_ctx_clear(fq_nmod_ctx); + } + } + + fmpz_clear(p); + fmpz_clear(e); + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fq_zech/test/t-frobenius.c b/external/flint-2.4.3/fq_zech/test/t-frobenius.c new file mode 100644 index 0000000..d20c079 --- /dev/null +++ b/external/flint-2.4.3/fq_zech/test/t-frobenius.c @@ -0,0 +1,122 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include +#include + +#include "fq_zech.h" +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int j, i, result; + fq_zech_ctx_t ctx; + FLINT_TEST_INIT(state); + + flint_printf("frobenius... "); + fflush(stdout); + + for (j = 0; j < 10; j++) + { + fq_zech_ctx_randtest(ctx, state); + + /* Check aliasing: a = frob(a, e) */ + for (i = 0; i < 100; i++) + { + fq_zech_t a, b; + fmpz_t e; + + fq_zech_init(a, ctx); + fq_zech_init(b, ctx); + fmpz_init(e); + + fq_zech_randtest(a, state, ctx); + fmpz_randtest_unsigned(e, state, 6); + + fq_zech_frobenius(b, a, fmpz_get_ui(e), ctx); + fq_zech_frobenius(a, a, fmpz_get_ui(e), ctx); + + result = (fq_zech_equal(a, b, ctx)); + if (!result) + { + flint_printf("FAIL (alias):\n\n"); + flint_printf("a = "), fq_zech_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), fq_zech_print_pretty(b, ctx), flint_printf("\n"); + abort(); + } + + fq_zech_clear(a, ctx); + fq_zech_clear(b, ctx); + fmpz_clear(e); + } + + /* Compare with exponentiation, for integral values */ + for (i = 0; i < 100; i++) + { + fq_zech_t a, b, c; + fmpz_t e, f; + + fq_zech_init(a, ctx); + fq_zech_init(b, ctx); + fq_zech_init(c, ctx); + fmpz_init(f); + fmpz_init(e); + + fq_zech_randtest(a, state, ctx); + fmpz_randtest_unsigned(e, state, 6); + + fq_zech_frobenius(b, a, fmpz_get_ui(e), ctx); + + fmpz_pow_ui(e, fq_zech_ctx_prime(ctx), fmpz_get_ui(e)); + fq_zech_pow(c, a, e, ctx); + + result = (fq_zech_equal(b, c, ctx)); + if (!result) + { + flint_printf("FAIL (cmp with pow):\n\n"); + flint_printf("a = "), fq_zech_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), fq_zech_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), fq_zech_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("e = "), fmpz_print(e), flint_printf("\n"); + abort(); + } + + fq_zech_clear(a, ctx); + fq_zech_clear(b, ctx); + fq_zech_clear(c, ctx); + fmpz_clear(e); + fmpz_clear(f); + } + + + fq_zech_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fq_zech/test/t-get_set_fq_nmod.c b/external/flint-2.4.3/fq_zech/test/t-get_set_fq_nmod.c new file mode 100644 index 0000000..57ac43d --- /dev/null +++ b/external/flint-2.4.3/fq_zech/test/t-get_set_fq_nmod.c @@ -0,0 +1,86 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include +#include + +#include "fq_zech.h" +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, j, result; + fq_zech_ctx_t ctx; + FLINT_TEST_INIT(state); + + flint_printf("get_fq_nmod/set_fq_nmod... "); + fflush(stdout); + + for (j = 0; j < 10; j++) + { + fq_zech_ctx_randtest(ctx, state); + + /* Check aliasing: a = -a */ + for (i = 0; i < 200; i++) + { + fq_zech_t a, b; + fq_nmod_t c; + + fq_zech_init(a, ctx); + fq_zech_init(b, ctx); + fq_nmod_init(c, ctx->fq_nmod_ctx); + + + fq_zech_randtest(a, state, ctx); + fq_zech_get_fq_nmod(c, a, ctx); + fq_zech_set_fq_nmod(b, c, ctx); + + result = (fq_zech_equal(a, b, ctx)); + if (!result) + { + flint_printf("FAIL:n\n"); + fq_zech_ctx_print(ctx); + flint_printf("\n"); + flint_printf("a = "), fq_zech_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), fq_zech_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), fq_nmod_print_pretty(c, ctx->fq_nmod_ctx), flint_printf("\n"); + flint_printf("table = %wd\n", ctx->eval_table[a->value]); + abort(); + } + + fq_zech_clear(a, ctx); + fq_zech_clear(b, ctx); + fq_nmod_clear(c, ctx->fq_nmod_ctx); + } + + fq_zech_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fq_zech/test/t-inv.c b/external/flint-2.4.3/fq_zech/test/t-inv.c new file mode 100644 index 0000000..88e592d --- /dev/null +++ b/external/flint-2.4.3/fq_zech/test/t-inv.c @@ -0,0 +1,118 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include +#include + +#include "fq_zech.h" +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int j, i, result; + fq_zech_ctx_t ctx; + FLINT_TEST_INIT(state); + + flint_printf("inv... "); + fflush(stdout); + + for (j = 0; j < 10; j++) + { + fq_zech_ctx_randtest(ctx, state); + + /* Check aliasing: a = ~a */ + for (i = 0; i < 200; i++) + { + fq_zech_t a, b, c; + + fq_zech_init(a, ctx); + fq_zech_init(b, ctx); + fq_zech_init(c, ctx); + + fq_zech_randtest_not_zero(a, state, ctx); + fq_zech_set(b, a, ctx); + + fq_zech_inv(c, b, ctx); + fq_zech_inv(b, b, ctx); + + result = (fq_zech_equal(b, c, ctx)); + if (!result) + { + flint_printf("FAIL (aliasing):\n\n"); + fq_zech_ctx_print(ctx); + flint_printf("\n"); + flint_printf("a = "), fq_zech_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), fq_zech_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), fq_zech_print_pretty(c, ctx), flint_printf("\n"); + fq_zech_ctx_print(ctx); + abort(); + } + + fq_zech_clear(a, ctx); + fq_zech_clear(b, ctx); + fq_zech_clear(c, ctx); + } + + /* Check a * ~a == 1 for units */ + for (i = 0; i < 200; i++) + { + fq_zech_t a, b, c; + + fq_zech_init(a, ctx); + fq_zech_init(b, ctx); + fq_zech_init(c, ctx); + + fq_zech_randtest_not_zero(a, state, ctx); + + fq_zech_inv(b, a, ctx); + fq_zech_mul(c, a, b, ctx); + + result = (fq_zech_is_one(c, ctx)); + if (!result) + { + flint_printf("FAIL (a * (~a) == 1):\n\n"); + fq_zech_ctx_print(ctx); + flint_printf("\n"); + flint_printf("a = "), fq_zech_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), fq_zech_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), fq_zech_print_pretty(c, ctx), flint_printf("\n"); + abort(); + } + + fq_zech_clear(a, ctx); + fq_zech_clear(b, ctx); + fq_zech_clear(c, ctx); + } + + fq_zech_ctx_clear(ctx); + } + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fq_zech/test/t-mul.c b/external/flint-2.4.3/fq_zech/test/t-mul.c new file mode 100644 index 0000000..c5138f8 --- /dev/null +++ b/external/flint-2.4.3/fq_zech/test/t-mul.c @@ -0,0 +1,213 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include +#include + +#include "fq_zech.h" +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int j, i, result; + fq_zech_ctx_t ctx; + FLINT_TEST_INIT(state); + + flint_printf("mul... "); + fflush(stdout); + + for (j = 0; j < 10; j++) + { + fq_zech_ctx_randtest(ctx, state); + + /* Check aliasing: a = a * b */ + for (i = 0; i < 200; i++) + { + fq_zech_t a, b, c; + + fq_zech_init(a, ctx); + fq_zech_init(b, ctx); + fq_zech_init(c, ctx); + + fq_zech_randtest(a, state, ctx); + fq_zech_randtest(b, state, ctx); + + fq_zech_mul(c, a, b, ctx); + fq_zech_mul(a, a, b, ctx); + + result = (fq_zech_equal(a, c, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), fq_zech_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), fq_zech_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), fq_zech_print_pretty(c, ctx), flint_printf("\n"); + abort(); + } + + fq_zech_clear(a, ctx); + fq_zech_clear(b, ctx); + fq_zech_clear(c, ctx); + } + + /* Check aliasing: b = a * b */ + for (i = 0; i < 200; i++) + { + fq_zech_t a, b, c; + + fq_zech_init(a, ctx); + fq_zech_init(b, ctx); + fq_zech_init(c, ctx); + + fq_zech_randtest(a, state, ctx); + fq_zech_randtest(b, state, ctx); + + fq_zech_mul(c, a, b, ctx); + fq_zech_mul(b, a, b, ctx); + + result = (fq_zech_equal(b, c, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), fq_zech_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), fq_zech_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), fq_zech_print_pretty(c, ctx), flint_printf("\n"); + abort(); + } + + fq_zech_clear(a, ctx); + fq_zech_clear(b, ctx); + fq_zech_clear(c, ctx); + } + + /* Check aliasing: a = a * a */ + for (i = 0; i < 200; i++) + { + fq_zech_t a, c; + + fq_zech_init(a, ctx); + fq_zech_init(c, ctx); + + fq_zech_randtest(a, state, ctx); + + fq_zech_mul(c, a, a, ctx); + fq_zech_mul(a, a, a, ctx); + + result = (fq_zech_equal(a, c, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), fq_zech_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("c = "), fq_zech_print_pretty(c, ctx), flint_printf("\n"); + abort(); + } + + fq_zech_clear(a, ctx); + fq_zech_clear(c, ctx); + } + + /* Check that a * b == b * a */ + for (i = 0; i < 200; i++) + { + fq_zech_t a, b, c1, c2; + + fq_zech_init(a, ctx); + fq_zech_init(b, ctx); + fq_zech_init(c1, ctx); + fq_zech_init(c2, ctx); + + fq_zech_randtest(a, state, ctx); + fq_zech_randtest(b, state, ctx); + + fq_zech_mul(c1, a, b, ctx); + fq_zech_mul(c2, b, a, ctx); + + result = (fq_zech_equal(c1, c2, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), fq_zech_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), fq_zech_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c1 = "), fq_zech_print_pretty(c1, ctx), flint_printf("\n"); + flint_printf("c2 = "), fq_zech_print_pretty(c2, ctx), flint_printf("\n"); + abort(); + } + + fq_zech_clear(a, ctx); + fq_zech_clear(b, ctx); + fq_zech_clear(c1, ctx); + fq_zech_clear(c2, ctx); + } + + /* Check that (a * b) * c == a * (b * c) */ + for (i = 0; i < 200; i++) + { + fq_zech_t a, b, c, lhs, rhs; + + fq_zech_init(a, ctx); + fq_zech_init(b, ctx); + fq_zech_init(c, ctx); + fq_zech_init(lhs, ctx); + fq_zech_init(rhs, ctx); + + fq_zech_randtest(a, state, ctx); + fq_zech_randtest(b, state, ctx); + fq_zech_randtest(c, state, ctx); + + fq_zech_mul(lhs, a, b, ctx); + fq_zech_mul(lhs, lhs, c, ctx); + fq_zech_mul(rhs, b, c, ctx); + fq_zech_mul(rhs, a, rhs, ctx); + + result = (fq_zech_equal(lhs, rhs, ctx)); + if (!result) + { + flint_printf("FAIL (a * b) * c == a * (b * c) :\n\n"); + fq_zech_ctx_print(ctx); + flint_printf("\n"); + flint_printf("a = "), fq_zech_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), fq_zech_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), fq_zech_print_pretty(c, ctx), flint_printf("\n"); + flint_printf("lhs = "), fq_zech_print_pretty(lhs, ctx), flint_printf("\n"); + flint_printf("rhs = "), fq_zech_print_pretty(rhs, ctx), flint_printf("\n"); + abort(); + } + + fq_zech_clear(a, ctx); + fq_zech_clear(b, ctx); + fq_zech_clear(c, ctx); + fq_zech_clear(lhs, ctx); + fq_zech_clear(rhs, ctx); + } + + fq_zech_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fq_zech/test/t-mul_fmpz.c b/external/flint-2.4.3/fq_zech/test/t-mul_fmpz.c new file mode 100644 index 0000000..9db55c1 --- /dev/null +++ b/external/flint-2.4.3/fq_zech/test/t-mul_fmpz.c @@ -0,0 +1,143 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include +#include + +#include "fq_zech.h" +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int j, i, result; + fq_zech_ctx_t ctx; + FLINT_TEST_INIT(state); + + flint_printf("mul_fmpz... "); + fflush(stdout); + + for (j = 0; j < 50; j++) + { + fq_zech_ctx_randtest(ctx, state); + + for (i = 0; i < 200; i++) + { + fmpz_t x; + fq_nmod_t aa, bb; + fq_zech_t a, b, c; + + fq_nmod_init(aa, ctx->fq_nmod_ctx); + fq_nmod_init(bb, ctx->fq_nmod_ctx); + + fmpz_init(x); + fmpz_randtest_mod_signed(x, state, fq_zech_ctx_prime(ctx)); + + fq_nmod_randtest(aa, state, ctx->fq_nmod_ctx); + fq_zech_set_fq_nmod(a, aa, ctx); + + fq_nmod_mul_fmpz(bb, aa, x, ctx->fq_nmod_ctx); + fq_zech_set_fq_nmod(b, bb, ctx); + + fq_zech_mul_fmpz(c, a, x, ctx); + + result = (fq_zech_equal(b, c, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + fq_zech_ctx_print(ctx); + flint_printf("\n"); + flint_printf("aa = "); + fq_nmod_print_pretty(aa, ctx->fq_nmod_ctx); + flint_printf("\n"); + flint_printf("a = "); + fq_zech_print_pretty(a, ctx); + flint_printf("\n"); + flint_printf("b = "); + fq_zech_print_pretty(b, ctx); + flint_printf("\n"); + flint_printf("c = "); + fq_zech_print_pretty(c, ctx); + flint_printf("\n"); + abort(); + } + + fmpz_clear(x); + fq_nmod_clear(bb, ctx->fq_nmod_ctx); + fq_nmod_clear(aa, ctx->fq_nmod_ctx); + } + + for (i = 0; i < 200; i++) + { + fmpz_t x; + fq_nmod_t aa, bb; + fq_zech_t a, b; + + fq_nmod_init(aa, ctx->fq_nmod_ctx); + fq_nmod_init(bb, ctx->fq_nmod_ctx); + + fmpz_init(x); + fmpz_randtest_mod_signed(x, state, fq_zech_ctx_prime(ctx)); + + fq_nmod_randtest(aa, state, ctx->fq_nmod_ctx); + fq_zech_set_fq_nmod(a, aa, ctx); + + fq_nmod_mul_fmpz(bb, aa, x, ctx->fq_nmod_ctx); + fq_zech_set_fq_nmod(b, bb, ctx); + + fq_zech_mul_fmpz(a, a, x, ctx); + + result = (fq_zech_equal(b, a, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + fq_zech_ctx_print(ctx); + flint_printf("\n"); + flint_printf("aa = "); + fq_nmod_print_pretty(aa, ctx->fq_nmod_ctx); + flint_printf("\n"); + flint_printf("a = "); + fq_zech_print_pretty(a, ctx); + flint_printf("\n"); + flint_printf("b = "); + fq_zech_print_pretty(b, ctx); + flint_printf("\n"); + abort(); + } + + fmpz_clear(x); + fq_nmod_clear(bb, ctx->fq_nmod_ctx); + fq_nmod_clear(aa, ctx->fq_nmod_ctx); + } + + fq_zech_ctx_clear(ctx); + } + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fq_zech/test/t-mul_ui.c b/external/flint-2.4.3/fq_zech/test/t-mul_ui.c new file mode 100644 index 0000000..d18c445 --- /dev/null +++ b/external/flint-2.4.3/fq_zech/test/t-mul_ui.c @@ -0,0 +1,141 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include +#include + +#include "fq_zech.h" +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int j, i, result; + fq_zech_ctx_t ctx; + FLINT_TEST_INIT(state); + + flint_printf("mul_ui... "); + fflush(stdout); + + for (j = 0; j < 50; j++) + { + fq_zech_ctx_randtest(ctx, state); + + for (i = 0; i < 200; i++) + { + mp_limb_t x; + fq_nmod_t aa, bb; + fq_zech_t a, b, c; + + fq_nmod_init(aa, ctx->fq_nmod_ctx); + fq_nmod_init(bb, ctx->fq_nmod_ctx); + + x = z_randtest(state); + + fq_nmod_randtest(aa, state, ctx->fq_nmod_ctx); + fq_zech_set_fq_nmod(a, aa, ctx); + + fq_nmod_mul_ui(bb, aa, x, ctx->fq_nmod_ctx); + fq_zech_set_fq_nmod(b, bb, ctx); + + fq_zech_mul_ui(c, a, x, ctx); + + result = (fq_zech_equal(b, c, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + fq_zech_ctx_print(ctx); + flint_printf("\nx = %wu\n", x); + flint_printf("aa = "); + fq_nmod_print_pretty(aa, ctx->fq_nmod_ctx); + flint_printf("\nbb = "); + fq_nmod_print_pretty(bb, ctx->fq_nmod_ctx); + flint_printf("\n"); + flint_printf("a = "); + fq_zech_print_pretty(a, ctx); + flint_printf("\n"); + flint_printf("b = "); + fq_zech_print_pretty(b, ctx); + flint_printf("\n"); + flint_printf("c = "); + fq_zech_print_pretty(c, ctx); + flint_printf("\n"); + abort(); + } + + fq_nmod_clear(bb, ctx->fq_nmod_ctx); + fq_nmod_clear(aa, ctx->fq_nmod_ctx); + } + + for (i = 0; i < 200; i++) + { + mp_limb_t x; + fq_nmod_t aa, bb; + fq_zech_t a, b; + + fq_nmod_init(aa, ctx->fq_nmod_ctx); + fq_nmod_init(bb, ctx->fq_nmod_ctx); + + x = z_randtest(state); + + fq_nmod_randtest(aa, state, ctx->fq_nmod_ctx); + fq_zech_set_fq_nmod(a, aa, ctx); + + fq_nmod_mul_ui(bb, aa, x, ctx->fq_nmod_ctx); + fq_zech_set_fq_nmod(b, bb, ctx); + + fq_zech_mul_ui(a, a, x, ctx); + + result = (fq_zech_equal(b, a, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + fq_zech_ctx_print(ctx); + flint_printf("\n"); + flint_printf("aa = "); + fq_nmod_print_pretty(aa, ctx->fq_nmod_ctx); + flint_printf("\n"); + flint_printf("a = "); + fq_zech_print_pretty(a, ctx); + flint_printf("\n"); + flint_printf("b = "); + fq_zech_print_pretty(b, ctx); + flint_printf("\n"); + abort(); + } + + fq_nmod_clear(bb, ctx->fq_nmod_ctx); + fq_nmod_clear(aa, ctx->fq_nmod_ctx); + } + + fq_zech_ctx_clear(ctx); + } + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fq_zech/test/t-neg.c b/external/flint-2.4.3/fq_zech/test/t-neg.c new file mode 100644 index 0000000..9017d32 --- /dev/null +++ b/external/flint-2.4.3/fq_zech/test/t-neg.c @@ -0,0 +1,121 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include +#include + +#include "fq_zech.h" +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, j, result; + fq_zech_ctx_t ctx; + FLINT_TEST_INIT(state); + + flint_printf("neg... "); + fflush(stdout); + + for (j = 0; j < 10; j++) + { + fq_zech_ctx_randtest(ctx, state); + + /* Check aliasing: a = -a */ + for (i = 0; i < 200; i++) + { + fq_zech_t a, b, c; + + fq_zech_init(a, ctx); + fq_zech_init(b, ctx); + fq_zech_init(c, ctx); + + fq_zech_randtest(a, state, ctx); + fq_zech_set(b, a, ctx); + + fq_zech_neg(c, b, ctx); + fq_zech_neg(b, b, ctx); + + result = (fq_zech_equal(b, c, ctx)); + if (!result) + { + flint_printf("FAIL a = -a:\n\n"); + fq_zech_ctx_print(ctx); + flint_printf("\n"); + flint_printf("a = "), fq_zech_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), fq_zech_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), fq_zech_print_pretty(c, ctx), flint_printf("\n"); + abort(); + } + + fq_zech_clear(a, ctx); + fq_zech_clear(b, ctx); + fq_zech_clear(c, ctx); + } + + /* Check a - b == a + (-b) */ + for (i = 0; i < 2000; i++) + { + fq_zech_t a, b, c1, c2; + + fq_zech_init(a, ctx); + fq_zech_init(b, ctx); + fq_zech_init(c1, ctx); + fq_zech_init(c2, ctx); + + fq_zech_randtest(a, state, ctx); + fq_zech_randtest(b, state, ctx); + + fq_zech_sub(c1, a, b, ctx); + fq_zech_neg(c2, b, ctx); + fq_zech_add(c2, a, c2, ctx); + + result = (fq_zech_equal(c1, c2, ctx)); + if (!result) + { + flint_printf("FAIL a - b == a + (-b):\n\n"); + fq_zech_ctx_print(ctx); + flint_printf("\n"); + flint_printf("a = "), fq_zech_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), fq_zech_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c1 = "), fq_zech_print_pretty(c1, ctx), flint_printf("\n"); + flint_printf("c2 = "), fq_zech_print_pretty(c2, ctx), flint_printf("\n"); + abort(); + } + + fq_zech_clear(a, ctx); + fq_zech_clear(b, ctx); + fq_zech_clear(c1, ctx); + fq_zech_clear(c2, ctx); + } + + fq_zech_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fq_zech/test/t-norm.c b/external/flint-2.4.3/fq_zech/test/t-norm.c new file mode 100644 index 0000000..acc3e35 --- /dev/null +++ b/external/flint-2.4.3/fq_zech/test/t-norm.c @@ -0,0 +1,98 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include +#include + +#include "fq_zech.h" +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int j, i, result; + fq_zech_ctx_t ctx; + FLINT_TEST_INIT(state); + + flint_printf("norm... "); + fflush(stdout); + + for (j = 0; j < 50; j++) + { + fq_zech_ctx_randtest(ctx, state); + + for (i = 0; i < 200; i++) + { + fmpz_t t1, t2; + fq_nmod_t aa; + fq_zech_t a; + + fmpz_init(t1); + fmpz_init(t2); + + fq_nmod_init(aa, ctx->fq_nmod_ctx); + fq_zech_init(a, ctx); + + fq_nmod_randtest(aa, state, ctx->fq_nmod_ctx); + fq_zech_set_fq_nmod(a, aa, ctx); + + fq_nmod_norm(t1, aa, ctx->fq_nmod_ctx); + fq_zech_norm(t2, a, ctx); + + result = fmpz_equal(t1, t2); + if (!result) + { + flint_printf("FAIL:\n\n"); + fq_zech_ctx_print(ctx); + flint_printf("\n"); + flint_printf("aa = "); + fq_nmod_print_pretty(aa, ctx->fq_nmod_ctx); + flint_printf("\n"); + flint_printf("N(aa) = "); fmpz_print(t1); + flint_printf("\na = "); + fq_zech_print_pretty(a, ctx); + flint_printf("\n"); + flint_printf("N(a) = "); fmpz_print(t2); + flint_printf("\n"); + abort(); + } + + fq_zech_clear(a, ctx); + fq_nmod_clear(aa, ctx->fq_nmod_ctx); + fmpz_clear(t1); + fmpz_clear(t2); + } + + fq_zech_ctx_clear(ctx); + } + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fq_zech/test/t-pow.c b/external/flint-2.4.3/fq_zech/test/t-pow.c new file mode 100644 index 0000000..597677f --- /dev/null +++ b/external/flint-2.4.3/fq_zech/test/t-pow.c @@ -0,0 +1,124 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include +#include + +#include "fq_zech.h" +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int j, i, result; + fq_zech_ctx_t ctx; + FLINT_TEST_INIT(state); + + flint_printf("pow... "); + fflush(stdout); + + for (j = 0; j < 10; j++) + { + fq_zech_ctx_randtest(ctx, state); + + /* Check aliasing: a = a^e */ + for (i = 0; i < 100; i++) + { + fq_zech_t a, b; + fmpz_t e; + + fq_zech_init(a, ctx); + fq_zech_init(b, ctx); + fmpz_init(e); + + fq_zech_randtest(a, state, ctx); + fmpz_randtest_unsigned(e, state, 6); + + fq_zech_pow(b, a, e, ctx); + fq_zech_pow(a, a, e, ctx); + + result = (fq_zech_equal(a, b, ctx)); + if (!result) + { + flint_printf("FAIL (alias):\n\n"); + flint_printf("a = "), fq_zech_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), fq_zech_print_pretty(b, ctx), flint_printf("\n"); + abort(); + } + + fq_zech_clear(a, ctx); + fq_zech_clear(b, ctx); + fmpz_clear(e); + } + + /* Compare with multiplication, for integral values */ + for (i = 0; i < 100; i++) + { + fq_zech_t a, b, c; + fmpz_t e, f; + + fq_zech_init(a, ctx); + fq_zech_init(b, ctx); + fq_zech_init(c, ctx); + fmpz_init(f); + fmpz_init(e); + + fq_zech_randtest(a, state, ctx); + fmpz_randtest_unsigned(e, state, 6); + + fq_zech_pow(b, a, e, ctx); + fq_zech_one(c, ctx); + for (fmpz_one(f); fmpz_cmp(f, e) <= 0; fmpz_add_ui(f, f, 1)) + { + fq_zech_mul(c, c, a, ctx); + } + + result = (fq_zech_equal(b, c, ctx)); + if (!result) + { + flint_printf("FAIL (cmp with mul):\n\n"); + flint_printf("a = "), fq_zech_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), fq_zech_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), fq_zech_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("e = "), fmpz_print(e), flint_printf("\n"); + abort(); + } + + fq_zech_clear(a, ctx); + fq_zech_clear(b, ctx); + fq_zech_clear(c, ctx); + fmpz_clear(e); + fmpz_clear(f); + } + + + fq_zech_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fq_zech/test/t-sqr.c b/external/flint-2.4.3/fq_zech/test/t-sqr.c new file mode 100644 index 0000000..87e3605 --- /dev/null +++ b/external/flint-2.4.3/fq_zech/test/t-sqr.c @@ -0,0 +1,115 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include +#include + +#include "fq_zech.h" +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int j, i, result; + fq_zech_ctx_t ctx; + FLINT_TEST_INIT(state); + + flint_printf("sqr... "); + fflush(stdout); + + for (j = 0; j < 10; j++) + { + fq_zech_ctx_randtest(ctx, state); + + /* Check aliasing: a = a * a */ + for (i = 0; i < 200; i++) + { + fq_zech_t a, c; + + fq_zech_init(a, ctx); + fq_zech_init(c, ctx); + + fq_zech_randtest(a, state, ctx); + + fq_zech_sqr(c, a, ctx); + fq_zech_sqr(a, a, ctx); + + result = (fq_zech_equal(a, c, ctx)); + if (!result) + { + flint_printf("FAIL (aliasing):\n\n"); + flint_printf("a = "), fq_zech_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("c = "), fq_zech_print_pretty(c, ctx), flint_printf("\n"); + abort(); + } + + fq_zech_clear(a, ctx); + fq_zech_clear(c, ctx); + } + + /* Check a^2 + a^2 = a(a + a) */ + for (i = 0; i < 200; i++) + { + fq_zech_t a, b, c, d; + + fq_zech_init(a, ctx); + fq_zech_init(b, ctx); + fq_zech_init(c, ctx); + fq_zech_init(d, ctx); + + fq_zech_randtest(a, state, ctx); + + fq_zech_sqr(b, a, ctx); + fq_zech_add(c, b, b, ctx); + + fq_zech_add(d, a, a, ctx); + fq_zech_mul(d, a, d, ctx); + + result = (fq_zech_equal(c, d, ctx)); + if (!result) + { + flint_printf("FAIL (a^2 + a^2 == a(a + a)):\n\n"); + flint_printf("a = "), fq_zech_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), fq_zech_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), fq_zech_print_pretty(c, ctx), flint_printf("\n"); + flint_printf("d = "), fq_zech_print_pretty(d, ctx), flint_printf("\n"); + abort(); + } + + fq_zech_clear(a, ctx); + fq_zech_clear(b, ctx); + fq_zech_clear(c, ctx); + fq_zech_clear(d, ctx); + + } + + fq_zech_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fq_zech/test/t-sub.c b/external/flint-2.4.3/fq_zech/test/t-sub.c new file mode 100644 index 0000000..ef44416 --- /dev/null +++ b/external/flint-2.4.3/fq_zech/test/t-sub.c @@ -0,0 +1,214 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include +#include + +#include "fq_zech.h" +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int j, i, result; + fq_zech_ctx_t ctx; + FLINT_TEST_INIT(state); + + flint_printf("sub... "); + fflush(stdout); + + for (j = 0; j < 10; j++) + { + fq_zech_ctx_randtest(ctx, state); + + /* Check aliasing: a = a - b */ + for (i = 0; i < 200; i++) + { + fq_zech_t a, b, c; + + fq_zech_init(a, ctx); + fq_zech_init(b, ctx); + fq_zech_init(c, ctx); + + fq_zech_randtest(a, state, ctx); + fq_zech_randtest(b, state, ctx); + + fq_zech_sub(c, a, b, ctx); + fq_zech_sub(a, a, b, ctx); + + result = (fq_zech_equal(a, c, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), fq_zech_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), fq_zech_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), fq_zech_print_pretty(c, ctx), flint_printf("\n"); + abort(); + } + + fq_zech_clear(a, ctx); + fq_zech_clear(b, ctx); + fq_zech_clear(c, ctx); + } + + /* Check aliasing: b = a - b */ + for (i = 0; i < 200; i++) + { + fq_zech_t a, b, c; + + fq_zech_init(a, ctx); + fq_zech_init(b, ctx); + fq_zech_init(c, ctx); + + fq_zech_randtest(a, state, ctx); + fq_zech_randtest(b, state, ctx); + + fq_zech_sub(c, a, b, ctx); + fq_zech_sub(b, a, b, ctx); + + result = (fq_zech_equal(b, c, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), fq_zech_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), fq_zech_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), fq_zech_print_pretty(c, ctx), flint_printf("\n"); + abort(); + } + + fq_zech_clear(a, ctx); + fq_zech_clear(b, ctx); + fq_zech_clear(c, ctx); + } + + /* Check aliasing: a = a - a */ + for (i = 0; i < 2000; i++) + { + fq_zech_t a, c; + + fq_zech_init(a, ctx); + fq_zech_init(c, ctx); + + fq_zech_randtest(a, state, ctx); + + fq_zech_sub(c, a, a, ctx); + fq_zech_sub(a, a, a, ctx); + + result = (fq_zech_equal(a, c, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), fq_zech_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("c = "), fq_zech_print_pretty(c, ctx), flint_printf("\n"); + abort(); + } + + fq_zech_clear(a, ctx); + fq_zech_clear(c, ctx); + } + + /* Check that a - b == -(b - a) */ + for (i = 0; i < 2000; i++) + { + fq_zech_t a, b, c1, c2; + + fq_zech_init(a, ctx); + fq_zech_init(b, ctx); + fq_zech_init(c1, ctx); + fq_zech_init(c2, ctx); + + fq_zech_randtest(a, state, ctx); + fq_zech_randtest(b, state, ctx); + + fq_zech_sub(c1, a, b, ctx); + fq_zech_sub(c2, b, a, ctx); + fq_zech_neg(c2, c2, ctx); + + result = (fq_zech_equal(c1, c2, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), fq_zech_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), fq_zech_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c1 = "), fq_zech_print_pretty(c1, ctx), flint_printf("\n"); + flint_printf("c2 = "), fq_zech_print_pretty(c2, ctx), flint_printf("\n"); + abort(); + } + + fq_zech_clear(a, ctx); + fq_zech_clear(b, ctx); + fq_zech_clear(c1, ctx); + fq_zech_clear(c2, ctx); + + } + + /* Check that (a - b) - c == a - (b + c) */ + for (i = 0; i < 2000; i++) + { + fq_zech_t a, b, c, lhs, rhs; + + fq_zech_init(a, ctx); + fq_zech_init(b, ctx); + fq_zech_init(c, ctx); + fq_zech_init(lhs, ctx); + fq_zech_init(rhs, ctx); + + fq_zech_randtest(a, state, ctx); + fq_zech_randtest(b, state, ctx); + fq_zech_randtest(c, state, ctx); + + fq_zech_sub(lhs, a, b, ctx); + fq_zech_sub(lhs, lhs, c, ctx); + fq_zech_add(rhs, b, c, ctx); + fq_zech_sub(rhs, a, rhs, ctx); + + result = (fq_zech_equal(lhs, rhs, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), fq_zech_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), fq_zech_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), fq_zech_print_pretty(c, ctx), flint_printf("\n"); + flint_printf("lhs = "), fq_zech_print_pretty(lhs, ctx), flint_printf("\n"); + flint_printf("rhs = "), fq_zech_print_pretty(rhs, ctx), flint_printf("\n"); + abort(); + } + + fq_zech_clear(a, ctx); + fq_zech_clear(b, ctx); + fq_zech_clear(c, ctx); + fq_zech_clear(lhs, ctx); + fq_zech_clear(rhs, ctx); + + } + + fq_zech_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fq_zech/test/t-trace.c b/external/flint-2.4.3/fq_zech/test/t-trace.c new file mode 100644 index 0000000..02140a3 --- /dev/null +++ b/external/flint-2.4.3/fq_zech/test/t-trace.c @@ -0,0 +1,95 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include +#include + +#include "fq_zech.h" +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int j, i, result; + fq_zech_ctx_t ctx; + FLINT_TEST_INIT(state); + + flint_printf("trace... "); + fflush(stdout); + + for (j = 0; j < 50; j++) + { + fq_zech_ctx_randtest(ctx, state); + + for (i = 0; i < 200; i++) + { + fmpz_t t1, t2; + fq_nmod_t aa; + fq_zech_t a; + + fmpz_init(t1); + fmpz_init(t2); + + fq_nmod_init(aa, ctx->fq_nmod_ctx); + fq_zech_init(a, ctx); + + fq_nmod_randtest(aa, state, ctx->fq_nmod_ctx); + fq_zech_set_fq_nmod(a, aa, ctx); + + fq_nmod_trace(t1, aa, ctx->fq_nmod_ctx); + fq_zech_trace(t2, a, ctx); + + result = fmpz_equal(t1, t2); + if (!result) + { + flint_printf("FAIL:\n\n"); + fq_zech_ctx_print(ctx); + flint_printf("\n"); + flint_printf("aa = "); + fq_nmod_print_pretty(aa, ctx->fq_nmod_ctx); + flint_printf("\n"); + flint_printf("Tr(aa) = "); fmpz_print(t1); + flint_printf("a = "); + fq_zech_print_pretty(a, ctx); + flint_printf("\n"); + flint_printf("Tr(a) = "); fmpz_print(t2); + flint_printf("\n"); + abort(); + } + + fq_zech_clear(a, ctx); + fq_nmod_clear(aa, ctx->fq_nmod_ctx); + fmpz_clear(t1); + fmpz_clear(t2); + } + + fq_zech_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/fq_zech/trace.c b/external/flint-2.4.3/fq_zech/trace.c new file mode 100644 index 0000000..208d7f5 --- /dev/null +++ b/external/flint-2.4.3/fq_zech/trace.c @@ -0,0 +1,62 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech.h" + +void +fq_zech_trace(fmpz_t rop, const fq_zech_t op, const fq_zech_ctx_t ctx) +{ + mp_limb_t p_i, trace; + fq_zech_t t, op_p_i; + double qm1inv; + if (fq_zech_is_zero(op, ctx)) + { + fmpz_zero(rop); + return; + } + + fq_zech_zero(t, ctx); + qm1inv = n_precompute_inverse(ctx->qm1); + + for (p_i = 1; p_i <= ctx->qm1; p_i *= ctx->p) + { + /* op_q_i = op ^ (p ^ i) */ + op_p_i->value = n_mulmod_precomp(op->value, p_i, ctx->qm1, qm1inv); + + /* t += op_p_i */ + fq_zech_add(t, t, op_p_i, ctx); + } + + if (fq_zech_is_zero(t, ctx)) + { + fmpz_zero(rop); + } + else + { + trace = t->value / ctx->qm1opm1; + trace = n_powmod(ctx->prime_root, trace, ctx->p); + fmpz_set_ui(rop, trace); + } +} diff --git a/external/flint-2.4.3/fq_zech_mat.h b/external/flint-2.4.3/fq_zech_mat.h new file mode 100644 index 0000000..e90d019 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_mat.h @@ -0,0 +1,53 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#ifndef FQ_ZECH_MAT_H +#define FQ_ZECH_MAT_H + +#include "fq_zech.h" +#include "fq_zech_vec.h" + +/* Cutoff between classical and recursive triangular solving */ +#define FQ_ZECH_MAT_SOLVE_TRI_ROWS_CUTOFF 64 +#define FQ_ZECH_MAT_SOLVE_TRI_COLS_CUTOFF 64 + +/* Cutoff between classical and recursive LU decomposition */ +#define FQ_ZECH_MAT_LU_RECURSIVE_CUTOFF 4 + +static __inline__ int FQ_ZECH_MAT_MUL_KS_CUTOFF(slong r, slong c, const fq_zech_ctx_t ctx) +{ + if (5 * FLINT_MIN(r, c) > 8 * fq_zech_ctx_degree(ctx) + 29) + return 1; + else + return 0; +} + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_mat_templates.h" +#undef CAP_T +#undef T + +#endif diff --git a/external/flint-2.4.3/fq_zech_mat/add.c b/external/flint-2.4.3/fq_zech_mat/add.c new file mode 100644 index 0000000..fd48517 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_mat/add.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_mat_templates/add.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_mat/clear.c b/external/flint-2.4.3/fq_zech_mat/clear.c new file mode 100644 index 0000000..4e5a5a8 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_mat/clear.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_mat_templates/clear.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_mat/doc/fq_zech_mat.txt b/external/flint-2.4.3/fq_zech_mat/doc/fq_zech_mat.txt new file mode 100644 index 0000000..ccb0e5b --- /dev/null +++ b/external/flint-2.4.3/fq_zech_mat/doc/fq_zech_mat.txt @@ -0,0 +1,442 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +******************************************************************************* + + Memory management + +******************************************************************************* + +void fq_zech_mat_init(fq_zech_mat_t mat, slong rows, slong cols, + const fq_zech_ctx_t ctx) + + Initialises \code{mat} to a \code{rows}-by-\code{cols} matrix with + coefficients in $\mathbb{F}_{q}$ given by \code{ctx}. All elements + are set to zero. + +void fq_zech_mat_init_set(fq_zech_mat_t mat, fq_zech_mat_t src, + const fq_zech_ctx_t ctx) + + Initialises \code{mat} and sets its dimensions and elements to + those of \code{src}. + +void fq_zech_mat_clear(fq_zech_mat_t mat, const fq_zech_ctx_t ctx) + + Clears the matrix and releases any memory it used. The matrix + cannot be used again until it is initialised. This function must be + called exactly once when finished using an \code{fq_zech_mat_t} object. + +void fq_zech_mat_set(fq_zech_mat_t mat, fq_zech_mat_t src, + const fq_zech_ctx_t ctx) + + Sets \code{mat} to a copy of \code{src}. It is assumed + that \code{mat} and \code{src} have identical dimensions. + +******************************************************************************* + + Basic properties and manipulation + +******************************************************************************* + +fq_zech_struct * fq_zech_mat_entry(fq_zech_mat_t mat, slong i, slong j) + + Directly accesses the entry in \code{mat} in row $i$ and column $j$, + indexed from zero. No bounds checking is performed. + +fq_zech_struct * fq_zech_mat_entry_set(fq_zech_mat_t mat, slong i, slong j, + fq_zech_t x, const fq_zech_ctx_t ctx) + + Sets the entry in \code{mat} in row $i$ and column $j$ to \code{x}. + +slong fq_zech_mat_nrows(fq_zech_mat_t mat, const fq_zech_ctx_t ctx) + + Returns the number of rows in \code{mat}. + +slong fq_zech_mat_ncols(fq_zech_mat_t mat, const fq_zech_ctx_t ctx) + + Returns the number of columns in \code{mat}. + +void fq_zech_mat_swap(fq_zech_mat_t mat1, fq_zech_mat_t mat2, + const fq_zech_ctx_t ctx) + + Swaps two matrices. The dimensions of \code{mat1} and \code{mat2} + are allowed to be different. + +void fq_zech_mat_zero(fq_zech_mat_t mat, const fq_zech_ctx_t ctx) + + Sets all entries of \code{mat} to 0. + + +******************************************************************************* + + Printing + +******************************************************************************* + +void fq_zech_mat_print_pretty(const fq_zech_mat_t mat, const fq_zech_ctx_t ctx) + + Pretty-prints \code{mat} to \code{stdout}. A header is printed + followed by the rows enclosed in brackets. + +int fq_zech_mat_fprint_pretty(FILE * file, const fq_zech_mat_t mat, + const fq_zech_ctx_t ctx) + + Pretty-prints \code{mat} to \code{file}. A header is printed + followed by the rows enclosed in brackets. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + +void fq_zech_mat_print(const fq_zech_mat_t mat, const fq_zech_ctx_t ctx) + + Prints \code{mat} to \code{stdout}. A header is printed followed + by the rows enclosed in brackets. + +int fq_zech_mat_fprint(FILE * file, const fq_zech_mat_t mat, + const fq_zech_ctx_t ctx) + + Prints \code{mat} to \code{file}. A header is printed followed by + the rows enclosed in brackets. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + +******************************************************************************* + + Window + +******************************************************************************* + +void fq_zech_mat_window_init(fq_zech_mat_t window, const fq_zech_mat_t mat, + slong r1, slong c1, slong r2, slong c2, + const fq_zech_ctx_t ctx) + + Initializes the matrix \code{window} to be an \code{r2 - r1} by + \code{c2 - c1} submatrix of \code{mat} whose \code{(0,0)} entry + is the \code{(r1, c1)} entry of \code{mat}. The memory for the + elements of \code{window} is shared with \code{mat}. + + +void fq_zech_mat_window_clear(fq_zech_mat_t window, const fq_zech_ctx_t ctx) + + Clears the matrix \code{window} and releases any memory that it + uses. Note that the memory to the underlying matrix that + \code{window} points to is not freed. + + +******************************************************************************* + + Random matrix generation + +******************************************************************************* + +void fq_zech_mat_randtest(fq_zech_mat_t mat, flint_rand_t state, + const fq_zech_ctx_t ctx) + + Sets the elements of \code{mat} to random elements of + $\mathbb{F}_{q}$, given by \code{ctx}. + +int fq_zech_mat_randpermdiag(fq_zech_mat_t mat, fq_zech_struct * diag, slong n, + flint_rand_t state, const fq_zech_ctx_t ctx) + + Sets \code{mat} to a random permutation of the diagonal matrix + with $n$ leading entries given by the vector \code{diag}. It is + assumed that the main diagonal of \code{mat} has room for at + least $n$ entries. + + Returns $0$ or $1$, depending on whether the permutation is even + or odd respectively. + +void fq_zech_mat_randrank(fq_zech_mat_t mat, slong rank, flint_rand_t state, + const fq_zech_ctx_t ctx) + + Sets \code{mat} to a random sparse matrix with the given rank, + having exactly as many non-zero elements as the rank, with the + non-zero elements being uniformly random elements of + $\mathbb{F}_{q}$. + + The matrix can be transformed into a dense matrix with unchanged + rank by subsequently calling \code{fq_zech_mat_randops()}. + +void fq_zech_mat_randops(fq_zech_mat_t mat, slong count, flint_rand_t state, + const fq_zech_ctx_t ctx) + + Randomises \code{mat} by performing elementary row or column + operations. More precisely, at most \code{count} random additions + or subtractions of distinct rows and columns will be performed. + This leaves the rank (and for square matrices, determinant) + unchanged. + +void fq_zech_mat_randtril(fq_zech_mat_t mat, flint_rand_t state, int unit, + const fq_zech_ctx_t ctx) + + Sets \code{mat} to a random lower triangular matrix. If + \code{unit} is 1, it will have ones on the main diagonal, + otherwise it will have random nonzero entries on the main + diagonal. + +void fq_zech_mat_randtriu(fq_zech_mat_t mat, flint_rand_t state, int unit, + x const fq_zech_ctx_t ctx) + + Sets \code{mat} to a random upper triangular matrix. If + \code{unit} is 1, it will have ones on the main diagonal, + otherwise it will have random nonzero entries on the main + diagonal. + +******************************************************************************* + + Comparison + +******************************************************************************* + +int fq_zech_mat_equal(fq_zech_mat_t mat1, fq_zech_mat_t mat2, + const fq_zech_ctx_t ctx) + + Returns nonzero if mat1 and mat2 have the same dimensions and elements, + and zero otherwise. + +int fq_zech_mat_is_zero(const fq_zech_mat_t mat, const fq_zech_ctx_t ctx) + + Returns a non-zero value if all entries \code{mat} are zero, and + otherwise returns zero. + +int fq_zech_mat_is_empty(const fq_zech_mat_t mat, const fq_zech_ctx_t ctx) + + Returns a non-zero value if the number of rows or the number of + columns in \code{mat} is zero, and otherwise returns zero. + +int fq_zech_mat_is_square(const fq_zech_mat_t mat, const fq_zech_ctx_t ctx) + + Returns a non-zero value if the number of rows is equal to the + number of columns in \code{mat}, and otherwise returns zero. + + + +******************************************************************************* + + Addition and subtraction + +******************************************************************************* + +void fq_zech_mat_add(fq_zech_mat_t C, const fq_zech_mat_t A, + const fq_zech_mat_t B, const fq_zech_ctx_t ctx) + + Computes $C = A + B$. Dimensions must be identical. + +void fq_zech_mat_sub(fq_zech_mat_t C, const fq_zech_mat_t A, + const fq_zech_mat_t B, const fq_zech_ctx_t ctx) + + Computes $C = A - B$. Dimensions must be identical. + +void fq_zech_mat_neg(fq_zech_mat_t A, const fq_zech_mat_t B, + const fq_zech_ctx_t ctx) + + Sets $B = -A$. Dimensions must be identical. + +******************************************************************************* + + Matrix multiplication + +******************************************************************************* + +void fq_zech_mat_mul(fq_zech_mat_t C, const fq_zech_mat_t A, + const fq_zech_mat_t B, const fq_zech_ctx_t ctx) + + Sets $C = AB$. Dimensions must be compatible for matrix + multiplication. $C$ is not allowed to be aliased with $A$ or + $B$. This function automatically chooses between classical and + KS multiplication. + +void fq_zech_mat_mul_classical(fq_zech_mat_t C, const fq_zech_mat_t A, + const fq_zech_mat_t B, const fq_zech_ctx_t ctx) + + Sets $C = AB$. Dimensions must be compatible for matrix multiplication. + $C$ is not allowed to be aliased with $A$ or $B$. Uses classical + matrix multiplication. + +void fq_zech_mat_mul_KS(fq_zech_mat_t C, const fq_zech_mat_t A, + const fq_zech_mat_t B, const fq_zech_ctx_t ctx) + + Sets $C = AB$. Dimensions must be compatible for matrix + multiplication. $C$ is not allowed to be aliased with $A$ or + $B$. Uses Kronecker substitution to perform the multiplication + over the integers. + +void fq_zech_mat_submul(fq_zech_mat_t D, const fq_zech_mat_t C, + const fq_zech_mat_t A, const fq_zech_mat_t B, + const fq_zech_ctx_t ctx) + + Sets $D = C + AB$. $C$ and $D$ may be aliased with each other but + not with $A$ or $B$. + +******************************************************************************* + + LU decomposition + +******************************************************************************* + +slong fq_zech_mat_lu(slong * P, fq_zech_mat_t A, int rank_check, + const fq_zech_ctx_t ctx) + + Computes a generalised LU decomposition $LU = PA$ of a given + matrix $A$, returning the rank of $A$. + + If $A$ is a nonsingular square matrix, it will be overwritten with + a unit diagonal lower triangular matrix $L$ and an upper + triangular matrix $U$ (the diagonal of $L$ will not be stored + explicitly). + + If $A$ is an arbitrary matrix of rank $r$, $U$ will be in row + echelon form having $r$ nonzero rows, and $L$ will be lower + triangular but truncated to $r$ columns, having implicit ones on + the $r$ first entries of the main diagonal. All other entries will + be zero. + + If a nonzero value for \code{rank_check} is passed, the function + will abandon the output matrix in an undefined state and return 0 + if $A$ is detected to be rank-deficient. + + This function calls \code{fq_zech_mat_lu_recursive}. + +slong fq_zech_mat_lu_classical(slong * P, fq_zech_mat_t A, int rank_check, + const fq_zech_ctx_t ctx) + + Computes a generalised LU decomposition $LU = PA$ of a given + matrix $A$, returning the rank of $A$. The behavior of this + function is identical to that of \code{fq_zech_mat_lu}. Uses Gaussian + elimination. + +slong fq_zech_mat_lu_recursive(slong * P, fq_zech_mat_t A, int rank_check, + const fq_zech_ctx_t ctx) + + Computes a generalised LU decomposition $LU = PA$ of a given + matrix $A$, returning the rank of $A$. The behavior of this + function is identical to that of \code{fq_zech_mat_lu}. Uses recursive + block decomposition, switching to classical Gaussian elimination + for sufficiently small blocks. + +******************************************************************************* + + Reduced row echelon form + +******************************************************************************* + +slong fq_zech_mat_rref(fq_zech_mat_t A, const fq_zech_ctx_t ctx) + + Puts $A$ in reduced row echelon form and returns the rank of $A$. + + The rref is computed by first obtaining an unreduced row echelon + form via LU decomposition and then solving an additional + triangular system. + +******************************************************************************* + + Triangular solving + +******************************************************************************* + +void fq_zech_mat_solve_tril(fq_zech_mat_t X, const fq_zech_mat_t L, + const fq_zech_mat_t B, int unit, + const fq_zech_ctx_t ctx) + + Sets $X = L^{-1} B$ where $L$ is a full rank lower triangular + square matrix. If \code{unit} = 1, $L$ is assumed to have ones on + its main diagonal, and the main diagonal will not be read. $X$ + and $B$ are allowed to be the same matrix, but no other aliasing + is allowed. Automatically chooses between the classical and + recursive algorithms. + +void fq_zech_mat_solve_tril_classical(fq_zech_mat_t X, const fq_zech_mat_t L, + const fq_zech_mat_t B, int unit, + const fq_zech_ctx_t ctx) + + Sets $X = L^{-1} B$ where $L$ is a full rank lower triangular + square matrix. If \code{unit} = 1, $L$ is assumed to have ones on + its main diagonal, and the main diagonal will not be read. $X$ + and $B$ are allowed to be the same matrix, but no other aliasing + is allowed. Uses forward substitution. + +void fq_zech_mat_solve_tril_recursive(fq_zech_mat_t X, const fq_zech_mat_t L, + const fq_zech_mat_t B, int unit, + const fq_zech_ctx_t ctx) + + Sets $X = L^{-1} B$ where $L$ is a full rank lower triangular + square matrix. If \code{unit} = 1, $L$ is assumed to have ones on + its main diagonal, and the main diagonal will not be read. $X$ + and $B$ are allowed to be the same matrix, but no other aliasing + is allowed. + + Uses the block inversion formula + + $$ + \begin{pmatrix} A & 0 \\ C & D \end{pmatrix}^{-1} + \begin{pmatrix} X \\ Y \end{pmatrix} = + \begin{pmatrix} A^{-1} X \\ D^{-1} ( Y - C A^{-1} X ) \end{pmatrix} + $$ + + to reduce the problem to matrix multiplication and triangular + solving of smaller systems. + +void fq_zech_mat_solve_triu(fq_zech_mat_t X, const fq_zech_mat_t U, + const fq_zech_mat_t B, int unit, + const fq_zech_ctx_t ctx) + + Sets $X = U^{-1} B$ where $U$ is a full rank upper triangular + square matrix. If \code{unit} = 1, $U$ is assumed to have ones on + its main diagonal, and the main diagonal will not be read. $X$ + and $B$ are allowed to be the same matrix, but no other aliasing + is allowed. Automatically chooses between the classical and + recursive algorithms. + +void fq_zech_mat_solve_triu_classical(fq_zech_mat_t X, const fq_zech_mat_t U, + const fq_zech_mat_t B, int unit, + const fq_zech_ctx_t ctx) + + Sets $X = U^{-1} B$ where $U$ is a full rank upper triangular + square matrix. If \code{unit} = 1, $U$ is assumed to have ones on + its main diagonal, and the main diagonal will not be read. $X$ + and $B$ are allowed to be the same matrix, but no other aliasing + is allowed. Uses forward substitution. + +void fq_zech_mat_solve_triu_recursive(fq_zech_mat_t X, const fq_zech_mat_t U, + const fq_zech_mat_t B, int unit, + const fq_zech_ctx_t ctx) + + Sets $X = U^{-1} B$ where $U$ is a full rank upper triangular + square matrix. If \code{unit} = 1, $U$ is assumed to have ones on + its main diagonal, and the main diagonal will not be read. $X$ + and $B$ are allowed to be the same matrix, but no other aliasing + is allowed. + + Uses the block inversion formula + + $$ + \begin{pmatrix} A & B \\ 0 & D \end{pmatrix}^{-1} + \begin{pmatrix} X \\ Y \end{pmatrix} = + \begin{pmatrix} A^{-1} (X - B D^{-1} Y) \\ D^{-1} Y \end{pmatrix} + $$ + + to reduce the problem to matrix multiplication and triangular + solving of smaller systems. diff --git a/external/flint-2.4.3/fq_zech_mat/equal.c b/external/flint-2.4.3/fq_zech_mat/equal.c new file mode 100644 index 0000000..bd344ff --- /dev/null +++ b/external/flint-2.4.3/fq_zech_mat/equal.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_mat_templates/equal.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_mat/fprint.c b/external/flint-2.4.3/fq_zech_mat/fprint.c new file mode 100644 index 0000000..265b0b5 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_mat/fprint.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_mat_templates/fprint.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_mat/init.c b/external/flint-2.4.3/fq_zech_mat/init.c new file mode 100644 index 0000000..36573d6 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_mat/init.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_mat_templates/init.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_mat/init_set.c b/external/flint-2.4.3/fq_zech_mat/init_set.c new file mode 100644 index 0000000..493c249 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_mat/init_set.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_mat_templates/init_set.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_mat/is_zero.c b/external/flint-2.4.3/fq_zech_mat/is_zero.c new file mode 100644 index 0000000..39c2904 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_mat/is_zero.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_mat_templates/is_zero.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_mat/lu.c b/external/flint-2.4.3/fq_zech_mat/lu.c new file mode 100644 index 0000000..0da03a9 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_mat/lu.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_mat_templates/lu.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_mat/lu_classical.c b/external/flint-2.4.3/fq_zech_mat/lu_classical.c new file mode 100644 index 0000000..4b1f507 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_mat/lu_classical.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_mat_templates/lu_classical.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_mat/lu_recursive.c b/external/flint-2.4.3/fq_zech_mat/lu_recursive.c new file mode 100644 index 0000000..441593a --- /dev/null +++ b/external/flint-2.4.3/fq_zech_mat/lu_recursive.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_mat_templates/lu_recursive.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_mat/mul.c b/external/flint-2.4.3/fq_zech_mat/mul.c new file mode 100644 index 0000000..54c44e3 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_mat/mul.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_mat_templates/mul.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_mat/mul_KS.c b/external/flint-2.4.3/fq_zech_mat/mul_KS.c new file mode 100644 index 0000000..be1fbc4 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_mat/mul_KS.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_mat_templates/mul_KS.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_mat/mul_classical.c b/external/flint-2.4.3/fq_zech_mat/mul_classical.c new file mode 100644 index 0000000..09d6b9f --- /dev/null +++ b/external/flint-2.4.3/fq_zech_mat/mul_classical.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_mat_templates/mul_classical.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_mat/neg.c b/external/flint-2.4.3/fq_zech_mat/neg.c new file mode 100644 index 0000000..c5c80ec --- /dev/null +++ b/external/flint-2.4.3/fq_zech_mat/neg.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_mat_templates/neg.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_mat/randops.c b/external/flint-2.4.3/fq_zech_mat/randops.c new file mode 100644 index 0000000..8f2a433 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_mat/randops.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_mat_templates/randops.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_mat/randpermdiag.c b/external/flint-2.4.3/fq_zech_mat/randpermdiag.c new file mode 100644 index 0000000..a0c3471 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_mat/randpermdiag.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_mat_templates/randpermdiag.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_mat/randrank.c b/external/flint-2.4.3/fq_zech_mat/randrank.c new file mode 100644 index 0000000..7da53ba --- /dev/null +++ b/external/flint-2.4.3/fq_zech_mat/randrank.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_mat_templates/randrank.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_mat/randtest.c b/external/flint-2.4.3/fq_zech_mat/randtest.c new file mode 100644 index 0000000..e664493 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_mat/randtest.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_mat_templates/randtest.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_mat/randtril.c b/external/flint-2.4.3/fq_zech_mat/randtril.c new file mode 100644 index 0000000..66c0125 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_mat/randtril.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_mat_templates/randtril.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_mat/randtriu.c b/external/flint-2.4.3/fq_zech_mat/randtriu.c new file mode 100644 index 0000000..04cc6fd --- /dev/null +++ b/external/flint-2.4.3/fq_zech_mat/randtriu.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_mat_templates/randtriu.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_mat/rref.c b/external/flint-2.4.3/fq_zech_mat/rref.c new file mode 100644 index 0000000..45ba0fa --- /dev/null +++ b/external/flint-2.4.3/fq_zech_mat/rref.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_mat_templates/rref.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_mat/set.c b/external/flint-2.4.3/fq_zech_mat/set.c new file mode 100644 index 0000000..063c8cb --- /dev/null +++ b/external/flint-2.4.3/fq_zech_mat/set.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_mat_templates/set.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_mat/solve_tril.c b/external/flint-2.4.3/fq_zech_mat/solve_tril.c new file mode 100644 index 0000000..42ab057 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_mat/solve_tril.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_mat_templates/solve_tril.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_mat/solve_tril_classical.c b/external/flint-2.4.3/fq_zech_mat/solve_tril_classical.c new file mode 100644 index 0000000..756178c --- /dev/null +++ b/external/flint-2.4.3/fq_zech_mat/solve_tril_classical.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_mat_templates/solve_tril_classical.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_mat/solve_tril_recursive.c b/external/flint-2.4.3/fq_zech_mat/solve_tril_recursive.c new file mode 100644 index 0000000..98dcd65 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_mat/solve_tril_recursive.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_mat_templates/solve_tril_recursive.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_mat/solve_triu.c b/external/flint-2.4.3/fq_zech_mat/solve_triu.c new file mode 100644 index 0000000..ae93363 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_mat/solve_triu.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_mat_templates/solve_triu.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_mat/solve_triu_classical.c b/external/flint-2.4.3/fq_zech_mat/solve_triu_classical.c new file mode 100644 index 0000000..4f4d9e7 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_mat/solve_triu_classical.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_mat_templates/solve_triu_classical.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_mat/solve_triu_recursive.c b/external/flint-2.4.3/fq_zech_mat/solve_triu_recursive.c new file mode 100644 index 0000000..524867e --- /dev/null +++ b/external/flint-2.4.3/fq_zech_mat/solve_triu_recursive.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_mat_templates/solve_triu_recursive.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_mat/sub.c b/external/flint-2.4.3/fq_zech_mat/sub.c new file mode 100644 index 0000000..f3a5bcc --- /dev/null +++ b/external/flint-2.4.3/fq_zech_mat/sub.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_mat_templates/sub.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_mat/submul.c b/external/flint-2.4.3/fq_zech_mat/submul.c new file mode 100644 index 0000000..bfaef21 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_mat/submul.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_mat_templates/submul.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_mat/swap.c b/external/flint-2.4.3/fq_zech_mat/swap.c new file mode 100644 index 0000000..6153b1d --- /dev/null +++ b/external/flint-2.4.3/fq_zech_mat/swap.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_mat_templates/swap.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_mat/test/t-add_sub.c b/external/flint-2.4.3/fq_zech_mat/test/t-add_sub.c new file mode 100644 index 0000000..e5f0c9b --- /dev/null +++ b/external/flint-2.4.3/fq_zech_mat/test/t-add_sub.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_mat_templates/test/t-add_sub.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_mat/test/t-equal.c b/external/flint-2.4.3/fq_zech_mat/test/t-equal.c new file mode 100644 index 0000000..1fe66ef --- /dev/null +++ b/external/flint-2.4.3/fq_zech_mat/test/t-equal.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_mat_templates/test/t-equal.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_mat/test/t-is_zero.c b/external/flint-2.4.3/fq_zech_mat/test/t-is_zero.c new file mode 100644 index 0000000..2300176 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_mat/test/t-is_zero.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_mat_templates/test/t-is_zero.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_mat/test/t-lu_classical.c b/external/flint-2.4.3/fq_zech_mat/test/t-lu_classical.c new file mode 100644 index 0000000..24b4482 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_mat/test/t-lu_classical.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_mat_templates/test/t-lu_classical.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_mat/test/t-lu_recursive.c b/external/flint-2.4.3/fq_zech_mat/test/t-lu_recursive.c new file mode 100644 index 0000000..3f53e7f --- /dev/null +++ b/external/flint-2.4.3/fq_zech_mat/test/t-lu_recursive.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_mat_templates/test/t-lu_recursive.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_mat/test/t-mul.c b/external/flint-2.4.3/fq_zech_mat/test/t-mul.c new file mode 100644 index 0000000..42d819e --- /dev/null +++ b/external/flint-2.4.3/fq_zech_mat/test/t-mul.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_mat_templates/test/t-mul.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_mat/test/t-mul_KS.c b/external/flint-2.4.3/fq_zech_mat/test/t-mul_KS.c new file mode 100644 index 0000000..c6656c9 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_mat/test/t-mul_KS.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_mat_templates/test/t-mul_KS.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_mat/test/t-rref.c b/external/flint-2.4.3/fq_zech_mat/test/t-rref.c new file mode 100644 index 0000000..619fcce --- /dev/null +++ b/external/flint-2.4.3/fq_zech_mat/test/t-rref.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_mat_templates/test/t-rref.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_mat/test/t-solve_tril.c b/external/flint-2.4.3/fq_zech_mat/test/t-solve_tril.c new file mode 100644 index 0000000..e524e06 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_mat/test/t-solve_tril.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_mat_templates/test/t-solve_tril.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_mat/test/t-solve_tril_classical.c b/external/flint-2.4.3/fq_zech_mat/test/t-solve_tril_classical.c new file mode 100644 index 0000000..d627827 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_mat/test/t-solve_tril_classical.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_mat_templates/test/t-solve_tril_classical.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_mat/test/t-solve_tril_recursive.c b/external/flint-2.4.3/fq_zech_mat/test/t-solve_tril_recursive.c new file mode 100644 index 0000000..5fcb261 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_mat/test/t-solve_tril_recursive.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_mat_templates/test/t-solve_tril_recursive.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_mat/test/t-solve_triu.c b/external/flint-2.4.3/fq_zech_mat/test/t-solve_triu.c new file mode 100644 index 0000000..5dbf96e --- /dev/null +++ b/external/flint-2.4.3/fq_zech_mat/test/t-solve_triu.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_mat_templates/test/t-solve_triu.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_mat/test/t-solve_triu_classical.c b/external/flint-2.4.3/fq_zech_mat/test/t-solve_triu_classical.c new file mode 100644 index 0000000..896f28b --- /dev/null +++ b/external/flint-2.4.3/fq_zech_mat/test/t-solve_triu_classical.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_mat_templates/test/t-solve_triu_classical.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_mat/test/t-solve_triu_recursive.c b/external/flint-2.4.3/fq_zech_mat/test/t-solve_triu_recursive.c new file mode 100644 index 0000000..f2023f2 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_mat/test/t-solve_triu_recursive.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_mat_templates/test/t-solve_triu_recursive.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_mat/test/t-submul.c b/external/flint-2.4.3/fq_zech_mat/test/t-submul.c new file mode 100644 index 0000000..7f39075 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_mat/test/t-submul.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_mat_templates/test/t-submul.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_mat/test/t-zero.c b/external/flint-2.4.3/fq_zech_mat/test/t-zero.c new file mode 100644 index 0000000..215a49b --- /dev/null +++ b/external/flint-2.4.3/fq_zech_mat/test/t-zero.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_mat_templates/test/t-zero.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_mat/window_clear.c b/external/flint-2.4.3/fq_zech_mat/window_clear.c new file mode 100644 index 0000000..af830c7 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_mat/window_clear.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_mat_templates/window_clear.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_mat/window_init.c b/external/flint-2.4.3/fq_zech_mat/window_init.c new file mode 100644 index 0000000..4a48354 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_mat/window_init.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_mat_templates/window_init.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_mat/zero.c b/external/flint-2.4.3/fq_zech_mat/zero.c new file mode 100644 index 0000000..d56032c --- /dev/null +++ b/external/flint-2.4.3/fq_zech_mat/zero.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_mat.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_mat_templates/zero.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly.h b/external/flint-2.4.3/fq_zech_poly.h new file mode 100644 index 0000000..6d8ddfb --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly.h @@ -0,0 +1,51 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Andres Goens + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ +#ifndef FQ_ZECH_POLY_H +#define FQ_ZECH_POLY_H + +#include "fq_zech_mat.h" + +#define FQ_ZECH_POLY_DIVREM_DIVCONQUER_CUTOFF 16 +#define FQ_ZECH_COMPOSE_MOD_LENH_CUTOFF 6 +#define FQ_ZECH_COMPOSE_MOD_PREINV_LENH_CUTOFF 6 +#define FQ_ZECH_SQR_CLASSICAL_CUTOFF 100 +#define FQ_ZECH_MUL_CLASSICAL_CUTOFF 90 +#define FQ_ZECH_MULLOW_CLASSICAL_CUTOFF 90 + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates.h" +#undef CAP_T +#undef T + +#include "fq_zech_poly_factor.h" + +#endif diff --git a/external/flint-2.4.3/fq_zech_poly/add.c b/external/flint-2.4.3/fq_zech_poly/add.c new file mode 100644 index 0000000..65f7685 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/add.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/add.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/clear.c b/external/flint-2.4.3/fq_zech_poly/clear.c new file mode 100644 index 0000000..8fffced --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/clear.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/clear.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/compose.c b/external/flint-2.4.3/fq_zech_poly/compose.c new file mode 100644 index 0000000..c13dfe7 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/compose.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/compose.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/compose_divconquer.c b/external/flint-2.4.3/fq_zech_poly/compose_divconquer.c new file mode 100644 index 0000000..d112b61 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/compose_divconquer.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/compose_divconquer.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/compose_horner.c b/external/flint-2.4.3/fq_zech_poly/compose_horner.c new file mode 100644 index 0000000..bd7a50c --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/compose_horner.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/compose_horner.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/compose_mod.c b/external/flint-2.4.3/fq_zech_poly/compose_mod.c new file mode 100644 index 0000000..5ac6fdb --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/compose_mod.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/compose_mod.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/compose_mod_brent_kung.c b/external/flint-2.4.3/fq_zech_poly/compose_mod_brent_kung.c new file mode 100644 index 0000000..8f25f25 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/compose_mod_brent_kung.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/compose_mod_brent_kung.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/compose_mod_brent_kung_precomp_preinv.c b/external/flint-2.4.3/fq_zech_poly/compose_mod_brent_kung_precomp_preinv.c new file mode 100644 index 0000000..b402e31 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/compose_mod_brent_kung_precomp_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/compose_mod_brent_kung_precomp_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/compose_mod_brent_kung_preinv.c b/external/flint-2.4.3/fq_zech_poly/compose_mod_brent_kung_preinv.c new file mode 100644 index 0000000..6e47152 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/compose_mod_brent_kung_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/compose_mod_brent_kung_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/compose_mod_horner.c b/external/flint-2.4.3/fq_zech_poly/compose_mod_horner.c new file mode 100644 index 0000000..b4399d2 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/compose_mod_horner.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/compose_mod_horner.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/compose_mod_horner_preinv.c b/external/flint-2.4.3/fq_zech_poly/compose_mod_horner_preinv.c new file mode 100644 index 0000000..1879e83 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/compose_mod_horner_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/compose_mod_horner_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/compose_mod_preinv.c b/external/flint-2.4.3/fq_zech_poly/compose_mod_preinv.c new file mode 100644 index 0000000..af711b1 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/compose_mod_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/compose_mod_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/deflate.c b/external/flint-2.4.3/fq_zech_poly/deflate.c new file mode 100644 index 0000000..82437e5 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/deflate.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/deflate.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/deflation.c b/external/flint-2.4.3/fq_zech_poly/deflation.c new file mode 100644 index 0000000..b3fa06a --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/deflation.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/deflation.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/derivative.c b/external/flint-2.4.3/fq_zech_poly/derivative.c new file mode 100644 index 0000000..5ac31fd --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/derivative.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/derivative.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/div_basecase.c b/external/flint-2.4.3/fq_zech_poly/div_basecase.c new file mode 100644 index 0000000..af39387 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/div_basecase.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/div_basecase.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/div_newton_n_preinv.c b/external/flint-2.4.3/fq_zech_poly/div_newton_n_preinv.c new file mode 100644 index 0000000..d2a1491 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/div_newton_n_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/div_newton_n_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/divides.c b/external/flint-2.4.3/fq_zech_poly/divides.c new file mode 100644 index 0000000..4b4ff3f --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/divides.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/divides.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/divrem_basecase.c b/external/flint-2.4.3/fq_zech_poly/divrem_basecase.c new file mode 100644 index 0000000..0b8d36b --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/divrem_basecase.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/divrem_basecase.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/divrem_divconquer.c b/external/flint-2.4.3/fq_zech_poly/divrem_divconquer.c new file mode 100644 index 0000000..6d8be25 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/divrem_divconquer.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/divrem_divconquer.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/divrem_divconquer_recursive.c b/external/flint-2.4.3/fq_zech_poly/divrem_divconquer_recursive.c new file mode 100644 index 0000000..e2ec62e --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/divrem_divconquer_recursive.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/divrem_divconquer_recursive.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/divrem_newton_n_preinv.c b/external/flint-2.4.3/fq_zech_poly/divrem_newton_n_preinv.c new file mode 100644 index 0000000..f89fd35 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/divrem_newton_n_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/divrem_newton_n_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/doc/fq_zech_poly.txt b/external/flint-2.4.3/fq_zech_poly/doc/fq_zech_poly.txt new file mode 100644 index 0000000..627df8c --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/doc/fq_zech_poly.txt @@ -0,0 +1,1596 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009, 2008 William Hart + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012,2013 Andres Goens + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +******************************************************************************* + + Memory management + +******************************************************************************* + +void fq_zech_poly_init(fq_zech_poly_t poly, const fq_zech_ctx_t ctx) + + Initialises \code{poly} for use, with context ctx, and setting its + length to zero. A corresponding call to \code{fq_zech_poly_clear()} + must be made after finishing with the \code{fq_zech_poly_t} to free the + memory used by the polynomial. + +void fq_zech_poly_init2(fq_zech_poly_t poly, slong alloc, + const fq_zech_ctx_t ctx) + + Initialises \code{poly} with space for at least \code{alloc} + coefficients and sets the length to zero. The allocated + coefficients are all set to zero. A corresponding call to + \code{fq_zech_poly_clear()} must be made after finishing with the + \code{fq_zech_poly_t} to free the memory used by the polynomial. + +void fq_zech_poly_realloc(fq_zech_poly_t poly, slong alloc, + const fq_zech_ctx_t ctx) + + Reallocates the given polynomial to have space for \code{alloc} + coefficients. If \code{alloc} is zero the polynomial is cleared + and then reinitialised. If the current length is greater than + \code{alloc} the polynomial is first truncated to length + \code{alloc}. + +void fq_zech_poly_fit_length(fq_zech_poly_t poly, slong len, + const fq_zech_ctx_t ctx) + + If \code{len} is greater than the number of coefficients currently + allocated, then the polynomial is reallocated to have space for at + least \code{len} coefficients. No data is lost when calling this + function. + + The function efficiently deals with the case where + \code{fit_length} is called many times in small increments by at + least doubling the number of allocated coefficients when length is + larger than the number of coefficients currently allocated. + +void _fq_zech_poly_set_length(fq_zech_poly_t poly, slong newlen, + const fq_zech_ctx_t ctx) + + Sets the coefficients of \code{poly} beyond \code{len} to zero and + sets the length of \code{poly} to \code{len}. + +void fq_zech_poly_clear(fq_zech_poly_t poly, const fq_zech_ctx_t ctx) + + Clears the given polynomial, releasing any memory used. It must + be reinitialised in order to be used again. + +void _fq_zech_poly_normalise(fq_zech_poly_t poly, const fq_zech_ctx_t ctx) + + Sets the length of \code{poly} so that the top coefficient is + non-zero. If all coefficients are zero, the length is set to + zero. This function is mainly used internally, as all functions + guarantee normalisation. + +void _fq_zech_poly_normalise2(fq_zech_struct *poly, slong *length, + const fq_zech_ctx_t ctx) + + Sets the length \code{length} of \code{(poly,length)} so that the + top coefficient is non-zero. If all coefficients are zero, the + length is set to zero. This function is mainly used internally, as + all functions guarantee normalisation. + +void fq_zech_poly_truncate(fq_zech_poly_t poly, slong newlen, + const fq_zech_ctx_t ctx) + + Truncates the polynomial to length at most~$n$. + +void _fq_zech_poly_reverse(fq_zech_struct* output, const fq_zech_struct* input, + slong len, slong m, const fq_zech_ctx_t ctx) + + Sets \code{output} to the reverse of \code{input}, which is of + length \code{len}, but thinking of it as a polynomial of + length~\code{m}, notionally zero-padded if necessary. The + length~\code{m} must be non-negative, but there are no other + restrictions. The polynomial \code{output} must have space for + \code{m} coefficients. + +void fq_zech_poly_reverse(fq_zech_poly_t output, const fq_zech_poly_t input, + slong m, const fq_zech_ctx_t ctx) + + Sets \code{output} to the reverse of \code{input}, thinking of it + as a polynomial of length~\code{m}, notionally zero-padded if + necessary). The length~\code{m} must be non-negative, but there + are no other restrictions. The output polynomial will be set to + length~\code{m} and then normalised. + +******************************************************************************* + + Polynomial parameters + +******************************************************************************* + +long fq_zech_poly_degree(fq_zech_poly_t poly, const fq_zech_ctx_t ctx) + + Returns the degree of the polynomial \code{poly}. + +long fq_zech_poly_length(fq_zech_poly_t poly, const fq_zech_ctx_t ctx) + + Returns the length of the polynomial \code{poly}. + +fq_zech_struct * fq_zech_poly_lead(const fq_zech_poly_t poly, + const fq_zech_ctx_t ctx) + + Returns a pointer to the leading coefficient of \code{poly}, or + \code{NULL} if \code{poly} is the zero polynomial. + +******************************************************************************* + + Randomisation + +******************************************************************************* + +void fq_zech_poly_randtest(fq_zech_poly_t f, flint_rand_t state, + slong len, const fq_zech_ctx_t ctx) + + Sets $f$ to a random polynomial of length at most \code{len} + with entries in the field described by \code{ctx}. + +void fq_zech_poly_randtest_not_zero(fq_zech_poly_t f, flint_rand_t state, + slong len, const fq_zech_ctx_t ctx) + + Same as \code{fq_zech_poly_randtest} but guarantees that the polynomial + is not zero. + +void fq_zech_poly_randtest_monic(fq_zech_poly_t f, flint_rand_t state, + slong len, const fq_zech_ctx_t ctx) + + Sets $f$ to a random monic polynomial of length \code{len} with + entries in the field described by \code{ctx}. + +void fq_zech_poly_randtest_irreducible(fq_zech_poly_t f, flint_rand_t state, + slong len, const fq_zech_ctx_t ctx) + + Sets $f$ to a random monic, irreducible polynomial of length + \code{len} with entries in the field described by \code{ctx}. + +******************************************************************************* + + Assignment and basic manipulation + +******************************************************************************* + +void _fq_zech_poly_set(fq_zech_struct *rop, const fq_zech_struct *op, slong len, + const fq_zech_ctx_t ctx) + + Sets \code{(rop, len}) to \code{(op, len)}. + +void fq_zech_poly_set(fq_zech_poly_t poly1, const fq_zech_poly_t poly2, + const fq_zech_ctx_t ctx) + + Sets the polynomial \code{poly1} to the polynomial \code{poly2}. + +void fq_zech_poly_set_fq_zech(fq_zech_poly_t poly, const fq_zech_t c, + const fq_zech_ctx_t ctx) + + Sets the polynomial \code{poly} to \code{c}. + +void fq_zech_poly_swap(fq_zech_poly_t op1, fq_zech_poly_t op2, + const fq_zech_ctx_t ctx) + + Swaps the two polynomials \code{op1} and \code{op2}. + +void _fq_zech_poly_zero(fq_zech_struct *rop, slong len, const fq_zech_ctx_t ctx) + + Sets \code{(rop, len)} to the zero polynomial. + +void fq_zech_poly_zero(fq_zech_poly_t poly, const fq_zech_ctx_t ctx) + + Sets \code{poly} to the zero polynomial. + +void void fq_zech_poly_one(fq_zech_poly_t poly, const fq_zech_ctx_t ctx) + + Sets \code{poly} to the constant polynomial~$1$. + +void void fq_zech_poly_gen(fq_zech_poly_t poly, const fq_zech_ctx_t ctx) + + Sets \code{poly} to the polynomial~$x$. + +void fq_zech_poly_make_monic(fq_zech_poly_t rop, const fq_zech_poly_t op, + const fq_zech_ctx_t ctx) + + Sets \code{rop} to \code{op}, normed to have leading coefficient 1. + +void _fq_zech_poly_make_monic(fq_zech_struct *rop, const fq_zech_struct *op, + slong length, const fq_zech_ctx_t ctx) + + Sets \code{rop} to \code{(op,length)}, normed to have leading coefficient 1. + Assumes that \code{rop} has enough space for the polynomial, assumes that + \code{op} is not zero (and thus has an invertible leading coefficient). + +******************************************************************************* + + Getting and setting coefficients + +******************************************************************************* + +void fq_zech_poly_get_coeff(fq_zech_t x, const fq_zech_poly_t poly, slong n, + const fq_zech_ctx_t ctx) + + Sets $x$ to the coefficient of $X^n$ in \code{poly}. + +void fq_zech_poly_set_coeff(fq_zech_poly_t poly, slong n, const fq_zech_t x, + const fq_zech_ctx_t ctx) + + Sets the coefficient of $X^n$ in \code{poly} to $x$. + +void +fq_zech_poly_set_coeff_fmpz(fq_zech_poly_t poly, slong n, const fmpz_t x, + const fq_zech_ctx_t ctx) + + Sets the coefficient of $X^n$ in the polynomial to $x$, + assuming $n \geq 0$. + +******************************************************************************* + + Comparison + +******************************************************************************* + +int fq_zech_poly_equal(const fq_zech_poly_t poly1, const fq_zech_poly_t poly2, + const fq_zech_ctx_t ctx) + + Returns whether the two polynomials \code{poly1} and \code{poly2} + are equal. + +int fq_zech_poly_is_zero(const fq_zech_poly_t poly, const fq_zech_ctx_t ctx) + + Returns whether the polynomial \code{poly} is the zero polynomial. + +int fq_zech_poly_is_one(const fq_zech_poly_t op) + + Returns whether the polynomial \code{poly} is equal + to the constant polynomial~$1$. + +int fq_zech_poly_is_gen(const fq_zech_poly_t op, const fq_zech_ctx_t ctx) + + Returns whether the polynomial \code{poly} is equal + to the polynomial~$x$. + +int fq_zech_poly_is_unit(const fq_zech_poly_t op, const fq_zech_ctx_t ctx) + + Returns whether the polynomial \code{poly} is a unit in the polynomial + ring $\mathbf{F}_q[X]$, i.e. if it has degree $0$ and is non-zero. + +int fq_zech_poly_equal_fq_zech(const fq_zech_poly_t poly, const fq_zech_t c, + const fq_zech_ctx_t ctx) + + Returns whether the polynomial \code{poly} is equal the (constant) + $\mathbf{F}_q$ element \code{c} + +******************************************************************************* + + Addition and subtraction + +******************************************************************************* + +void _fq_zech_poly_add(fq_zech_struct *res, + const fq_zech_struct *poly1, slong len1, + const fq_zech_struct *poly2, slong len2, + const fq_zech_ctx_t ctx) + + Sets \code{res} to the sum of \code{(poly1,len1)} and \code{(poly2,len2)}. + +void fq_zech_poly_add(fq_zech_poly_t res, const fq_zech_poly_t poly1, + const fq_zech_poly_t poly2, const fq_zech_ctx_t ctx) + + Sets \code{res} to the sum of \code{poly1} and \code{poly2}. + +void _fq_zech_poly_sub(fq_zech_struct *res, + const fq_zech_struct *poly1, slong len1, + const fq_zech_struct *poly2, slong len2, + const fq_zech_ctx_t ctx) + + Sets \code{res} to the difference of \code{(poly1,len1)} and + \code{(poly2,len2)}. + +void fq_zech_poly_sub(fq_zech_poly_t res, const fq_zech_poly_t poly1, + const fq_zech_poly_t poly2, const fq_zech_ctx_t ctx) + + Sets \code{res} to the difference of \code{poly1} and \code{poly2}. + +void _fq_zech_poly_neg(fq_zech_struct *rop, const fq_zech_struct *op, slong len, + const fq_zech_ctx_t ctx) + + Sets \code{res} to the additive inverse of \code{(poly,len)}. + +void fq_zech_poly_neg(fq_zech_poly_t res, const fq_zech_poly_t poly, + const fq_zech_ctx_t ctx) + + Sets \code{res} to the additive inverse of \code{poly}. + +******************************************************************************* + + Scalar multiplication and division + +******************************************************************************* + +void _fq_zech_poly_scalar_mul_fq_zech(fq_zech_struct *rop, + const fq_zech_struct *op, slong len, const fq_zech_t x, + const fq_zech_ctx_t ctx) + + Sets \code{(rop,len)} to the product of \code{(op,len)} by the + scalar \code{x}, in the context defined by \code{ctx}. + +void fq_zech_poly_scalar_mul_fq_zech(fq_zech_poly_t rop, + const fq_zech_poly_t op, const fq_zech_t x, const fq_zech_ctx_t ctx) + + Sets \code{(rop,len)} to the product of \code{(op,len)} by the + scalar \code{x}, in the context defined by \code{ctx}. + +void _fq_zech_poly_scalar_addmul_fq_zech(fq_zech_struct *rop, + const fq_zech_struct *op, slong len, const fq_zech_t x, + const fq_zech_ctx_t ctx) + + Adds to \code{(rop,len)} the product of \code{(op,len)} by the + scalar \code{x}, in the context defined by \code{ctx}. + In particular, assumes the same length for \code{op} and + \code{rop}. + +void fq_zech_poly_scalar_addmul_fq_zech(fq_zech_poly_t rop, + const fq_zech_poly_t op, const fq_zech_t x, + const fq_zech_ctx_t ctx) + + Adds to \code{rop} the product of \code{op} by the + scalar \code{x}, in the context defined by \code{ctx}. + +void _fq_zech_poly_scalar_submul_fq_zech(fq_zech_struct *rop, + const fq_zech_struct *op, slong len, const fq_zech_t x, + const fq_zech_ctx_t ctx) + + Substracts from \code{(rop,len)} the product of \code{(op,len)} by the + scalar \code{x}, in the context defined by \code{ctx}. + In particular, assumes the same length for \code{op} and + \code{rop}. + +void fq_zech_poly_scalar_submul_fq_zech(fq_zech_poly_t rop, + const fq_zech_poly_t op, const fq_zech_t x, const fq_zech_ctx_t ctx) + + Substracts from \code{rop} the product of \code{op} by the + scalar \code{x}, in the context defined by \code{ctx}. + +******************************************************************************* + + Multiplication + +******************************************************************************* + +void _fq_zech_poly_mul_classical(fq_zech_struct *rop, + const fq_zech_struct *op1, slong len1, + const fq_zech_struct *op2, slong len2, + const fq_zech_ctx_t ctx) + + Sets \code{(rop, len1 + len2 - 1)} to the product of \code{(op1, len1)} + and \code{(op2, len2)}, assuming that \code{len1} is at least \code{len2} + and neither is zero. + + Permits zero padding. Does not support aliasing of \code{rop} + with either \code{op1} or \code{op2}. + +void fq_zech_poly_mul_classical(fq_zech_poly_t rop, + const fq_zech_poly_t op1, + const fq_zech_poly_t op2, + const fq_zech_ctx_t ctx) + + Sets \code{rop} to the product of \code{op1} and \code{op2} + using classical polynomial multiplication. + +void _fq_zech_poly_mul_reorder(fq_zech_struct *rop, + const fq_zech_struct *op1, slong len1, + const fq_zech_struct *op2, slong len2, + const fq_zech_ctx_t ctx) + + Sets \code{(rop, len1 + len2 - 1)} to the product of \code{(op1, len1)} + and \code{(op2, len2)}, assuming that \code{len1} and \code{len2} are + non-zero. + + Permits zero padding. Supports aliasing. + +void fq_zech_poly_mul_reorder(fq_zech_poly_t rop, + const fq_zech_poly_t op1, const fq_zech_poly_t op2, + const fq_zech_ctx_t ctx) + + Sets \code{rop} to the product of \code{op1} and \code{op2}, + reordering the two indeterminates $X$ and $Y$ when viewing + the polynomials as elements of $\mathbf{F}_p[X,Y]$. + + Suppose $\mathbf{F}_q = \mathbf{F}_p[X]/ (f(X))$ and recall + that elements of $\mathbf{F}_q$ are internally represented + by elements of type \code{fmpz_poly}. For small degree extensions + but polynomials in $\mathbf{F}_q[Y]$ of large degree~$n$, we + change the representation to + + \begin{equation*} + \begin{split} + g(Y) & = \sum_{i=0}^{n} a_i(X) Y^i \\ + & = \sum_{j=0}^{d} \sum_{i=0}^{n} \text{Coeff}(a_i(X), j) Y^i. + \end{split} + \end{equation*} + + This allows us to use a poor algorithm (such as classical multiplication) + in the $X$-direction and leverage the existing fast integer + multiplication routines in the $Y$-direction where the polynomial + degree~$n$ is large. + +void _fq_zech_poly_mul_KS(fq_zech_struct *rop, const fq_zech_struct *op1, + slong len1, const fq_zech_struct *op2, slong len2, + const fq_zech_ctx_t ctx) + + Sets \code{(rop, len1 + len2 - 1)} to the product of \code{(op1, len1)} + and \code{(op2, len2)}. + + Permits zero padding and places no assumptions on the + lengths \code{len1} and \code{len2}. Supports aliasing. + +void fq_zech_poly_mul_KS(fq_zech_poly_t rop, + const fq_zech_poly_t op1, const fq_zech_poly_t op2, + const fq_zech_ctx_t ctx) + + Sets \code{rop} to the product of \code{op1} and \code{op2} + using Kronecker substitution, that is, by encoding each + coefficient in $\mathbf{F}_{q}$ as an integer and reducing + this problem to multiplying two polynomials over the integers. + +void _fq_zech_poly_mul(fq_zech_struct *rop, + const fq_zech_struct *op1, slong len1, + const fq_zech_struct *op2, slong len2, + const fq_zech_ctx_t ctx) + + Sets \code{(rop, len1 + len2 - 1)} to the product of \code{(op1, len1)} + and \code{(op2, len2)}, choosing an appropriate algorithm. + + Permits zero padding. Does not support aliasing. + +void fq_zech_poly_mul(fq_zech_poly_t rop, + const fq_zech_poly_t op1, const fq_zech_poly_t op2, const fq_zech_ctx_t ctx) + + Sets \code{rop} to the product of \code{op1} and \code{op2}, + choosing an appropriate algorithm. + +void _fq_zech_poly_mullow_classical(fq_zech_struct *rop, + const fq_zech_struct *op1, slong len1, + const fq_zech_struct *op2, slong len2, slong n, + const fq_zech_ctx_t ctx) + + Sets \code{(res, n)} to the first $n$ coefficients of + \code{(poly1, len1)} multiplied by \code{(poly2, len2)}. + + Assumes \code{0 < n <= len1 + len2 - 1}. Assumes neither + \code{len1} nor \code{len2} is zero. + +void fq_zech_poly_mullow_classical(fq_zech_poly_t rop, + const fq_zech_poly_t op1, const fq_zech_poly_t op2, slong n, const fq_zech_ctx_t ctx) + + Sets \code{res} to the product of \code{poly1} and \code{poly2}, + computed using the classical or schoolbook method. + +void _fq_zech_poly_mullow_KS(fq_zech_struct *rop, + const fq_zech_struct *op1, slong len1, + const fq_zech_struct *op2, slong len2, slong n, + const fq_zech_ctx_t ctx) + + Sets \code{(res, n)} to the lowest $n$ coefficients of the product of + \code{(poly1, len1)} and \code{(poly2, len2)}. + + Assumes that \code{len1} and \code{len2} are positive, but does allow + for the polynomials to be zero-padded. The polynomials may be zero, + too. Assumes $n$ is positive. Supports aliasing between \code{res}, + \code{poly1} and \code{poly2}. + +void fq_zech_poly_mullow_KS(fq_zech_poly_t rop, + const fq_zech_poly_t op1, const fq_zech_poly_t op2, + slong n, const fq_zech_ctx_t ctx) + + Sets \code{res} to the product of \code{poly1} and \code{poly2}. + +void _fq_zech_poly_mullow(fq_zech_struct *rop, + const fq_zech_struct *op1, slong len1, + const fq_zech_struct *op2, slong len2, slong n, + const fq_zech_ctx_t ctx) + + Sets \code{(res, n)} to the lowest $n$ coefficients of the product of + \code{(poly1, len1)} and \code{(poly2, len2)}. + + Assumes \code{0 < n <= len1 + len2 - 1}. Allows for zero-padding in + the inputs. Does not support aliasing between the inputs and the output. + +void fq_zech_poly_mullow(fq_zech_poly_t rop, + const fq_zech_poly_t op1, const fq_zech_poly_t op2, slong n, + const fq_zech_ctx_t ctx) + + Sets \code{res} to the lowest $n$ coefficients of the product of + \code{poly1} and \code{poly2}. + +void _fq_zech_poly_mulmod(fq_zech_struct* res, + const fq_zech_struct* poly1, slong len1, + const fq_zech_struct* poly2, slong len2, + const fq_zech_struct* f, slong lenf, + const fq_zech_ctx_t ctx) + + Sets \code{res} to the remainder of the product of \code{poly1} + and \code{poly2} upon polynomial division by \code{f}. + + It is required that \code{len1 + len2 - lenf > 0}, which is + equivalent to requiring that the result will actually be + reduced. Otherwise, simply use \code{_fq_zech_poly_mul} instead. + + Aliasing of \code{f} and \code{res} is not permitted. + +void fq_zech_poly_mulmod(fq_zech_poly_t res,const fq_zech_poly_t poly1, + const fq_zech_poly_t poly2, const fq_zech_poly_t f, + const fq_zech_ctx_t ctx) + + Sets \code{res} to the remainder of the product of \code{poly1} + and \code{poly2} upon polynomial division by \code{f}. + +void _fq_zech_poly_mulmod_preinv(fq_zech_struct* res, + const fq_zech_struct* poly1, slong len1, + const fq_zech_struct* poly2, slong len2, + const fq_zech_struct* f, slong lenf, + const fq_zech_struct* finv, slong lenfinv, + const fq_zech_ctx_t ctx) + + Sets \code{res} to the remainder of the product of \code{poly1} + and \code{poly2} upon polynomial division by \code{f}. + + It is required that \code{finv} is the inverse of the reverse of + \code{f} mod \code{x^lenf}. It is required that + \code{len1 + len2 - lenf > 0}, which is equivalent to requiring that + the result will actually be reduced. Otherwise, simply use + \code{_fq_zech_poly_mul} instead. + + Aliasing of \code{f} or \code{finv} and \code{res} is not + permitted. + +void fq_zech_poly_mulmod_preinv(fq_zech_poly_t res, const fq_zech_poly_t poly1, + const fq_zech_poly_t poly2, + const fq_zech_poly_t f, + const fq_zech_poly_t finv, + const fq_zech_ctx_t ctx) + + Sets \code{res} to the remainder of the product of \code{poly1} + and \code{poly2} upon polynomial division by \code{f}. \code{finv} + is the inverse of the reverse of \code{f}. + +******************************************************************************* + + Squaring + +******************************************************************************* + +void _fq_zech_poly_sqr_classical(fq_zech_struct *rop, + const fq_zech_struct *op, slong len, + const fq_zech_ctx_t ctx) + + Sets \code{(rop, 2*len - 1)} to the square of \code{(op, len)}, + assuming that \code{(op,len)} is not zero and using classical + polynomial multiplication. + + Permits zero padding. Does not support aliasing of \code{rop} + with either \code{op1} or \code{op2}. + +void fq_zech_poly_sqr_classical(fq_zech_poly_t rop, const fq_zech_poly_t op, + const fq_zech_ctx_t ctx) + + Sets \code{rop} to the square of \code{op} using classical + polynomial multiplication. + + +void _fq_zech_poly_sqr_KS(fq_zech_struct *rop, const fq_zech_struct *op, + slong len, const fq_zech_ctx_t ctx) + + Sets \code{(rop, 2*len - 1)} to the square of \code{(op, len)}. + + Permits zero padding and places no assumptions on the + lengths \code{len1} and \code{len2}. Supports aliasing. + +void fq_zech_poly_sqr_KS(fq_zech_poly_t rop, const fq_zech_poly_t op, + const fq_zech_ctx_t ctx) + + Sets \code{rop} to the square \code{op} using Kronecker substitution, + that is, by encoding each coefficient in $\mathbf{F}_{q}$ as an integer + and reducing this problem to multiplying two polynomials over the integers. + +void _fq_zech_poly_sqr(fq_zech_struct *rop, const fq_zech_struct *op, slong len, + const fq_zech_ctx_t ctx) + + Sets \code{(rop, 2* len - 1)} to the square of \code{(op, len)}, + choosing an appropriate algorithm. + + Permits zero padding. Does not support aliasing. + +void fq_zech_poly_sqr(fq_zech_poly_t rop, const fq_zech_poly_t op, + const fq_zech_ctx_t ctx) + + Sets \code{rop} to the square of \code{op}, + choosing an appropriate algorithm. + + +******************************************************************************* + + Powering + +******************************************************************************* + +void _fq_zech_poly_pow(fq_zech_struct *rop, const fq_zech_struct *op, slong len, + ulong e, const fq_zech_ctx_t ctx) + + Sets \code{res = poly^e}, assuming that \code{e, len > 0} and that + \code{res} has space for \code{e*(len - 1) + 1} coefficients. Does + not support aliasing. + +void fq_zech_poly_pow(fq_zech_poly_t rop, const fq_zech_poly_t op, ulong e, + const fq_zech_ctx_t ctx) + + Computes \code{res = poly^e}. If $e$ is zero, returns one, + so that in particular \code{0^0 = 1}. + +void _fq_zech_poly_powmod_ui_binexp(fq_zech_struct* res, + const fq_zech_struct* poly, ulong e, + const fq_zech_struct* f, slong lenf, + const fq_zech_ctx_t ctx) + + Sets \code{res} to \code{poly} raised to the power \code{e} modulo + \code{f}, using binary exponentiation. We require \code{e > 0}. + + We require \code{lenf > 1}. It is assumed that \code{poly} is + already reduced modulo \code{f} and zero-padded as necessary to + have length exactly \code{lenf - 1}. The output \code{res} must + have room for \code{lenf - 1} coefficients. + +void fq_zech_poly_powmod_ui_binexp(fq_zech_poly_t res, + const fq_zech_poly_t poly, ulong e, + const fq_zech_poly_t f, + const fq_zech_ctx_t ctx) + + Sets \code{res} to \code{poly} raised to the power \code{e} modulo + \code{f}, using binary exponentiation. We require \code{e >= 0}. + +void +_fq_zech_poly_powmod_ui_binexp_preinv(fq_zech_struct* res, + const fq_zech_struct* poly, ulong e, + const fq_zech_struct* f, slong lenf, + const fq_zech_struct* finv, slong lenfinv, + const fq_zech_ctx_t ctx) + + Sets \code{res} to \code{poly} raised to the power \code{e} modulo + \code{f}, using binary exponentiation. We require \code{e > 0}. + We require \code{finv} to be the inverse of the reverse of + \code{f}. + + We require \code{lenf > 1}. It is assumed that \code{poly} is + already reduced modulo \code{f} and zero-padded as necessary to + have length exactly \code{lenf - 1}. The output \code{res} must + have room for \code{lenf - 1} coefficients. + +void +fq_zech_poly_powmod_ui_binexp_preinv(fq_zech_poly_t res, + const fq_zech_poly_t poly, ulong e, + const fq_zech_poly_t f, const fq_zech_poly_t finv, + const fq_zech_ctx_t ctx) + + Sets \code{res} to \code{poly} raised to the power \code{e} modulo + \code{f}, using binary exponentiation. We require \code{e >= 0}. + We require \code{finv} to be the inverse of the reverse of + \code{f}. + +void _fq_zech_poly_powmod_fmpz_binexp(fq_zech_struct* res, + const fq_zech_struct* poly, + fmpz_t e, const fq_zech_struct* f, + slong lenf, const fq_zech_ctx_t ctx) + + Sets \code{res} to \code{poly} raised to the power \code{e} modulo + \code{f}, using binary exponentiation. We require \code{e > 0}. + + We require \code{lenf > 1}. It is assumed that \code{poly} is + already reduced modulo \code{f} and zero-padded as necessary to + have length exactly \code{lenf - 1}. The output \code{res} must + have room for \code{lenf - 1} coefficients. + +void fq_zech_poly_powmod_fmpz_binexp(fq_zech_poly_t res, + const fq_zech_poly_t poly, fmpz_t e, + const fq_zech_poly_t f, + const fq_zech_ctx_t ctx) + + Sets \code{res} to \code{poly} raised to the power \code{e} modulo + \code{f}, using binary exponentiation. We require \code{e >= 0}. + +void +_fq_zech_poly_powmod_fmpz_binexp_preinv(fq_zech_struct* res, const fq_zech_struct* poly, + fmpz_t e, const fq_zech_struct* f, slong lenf, + const fq_zech_struct* finv, slong lenfinv, + const fq_zech_ctx_t ctx) + + Sets \code{res} to \code{poly} raised to the power \code{e} modulo + \code{f}, using binary exponentiation. We require \code{e > 0}. + We require \code{finv} to be the inverse of the reverse of + \code{f}. + + We require \code{lenf > 1}. It is assumed that \code{poly} is + already reduced modulo \code{f} and zero-padded as necessary to + have length exactly \code{lenf - 1}. The output \code{res} must + have room for \code{lenf - 1} coefficients. + +void +fq_zech_poly_powmod_fmpz_binexp_preinv(fq_zech_poly_t res, + const fq_zech_poly_t poly, fmpz_t e, + const fq_zech_poly_t f, + const fq_zech_poly_t finv, + const fq_zech_ctx_t ctx) + + Sets \code{res} to \code{poly} raised to the power \code{e} modulo + \code{f}, using binary exponentiation. We require \code{e >= 0}. + We require \code{finv} to be the inverse of the reverse of + \code{f}. + +void +_fq_zech_poly_powmod_fmpz_sliding_preinv(fq_zech_struct* res, + const fq_zech_struct* poly, + fmpz_t e, ulong k, + const fq_zech_struct* f, slong lenf, + const fq_zech_struct* finv, slong lenfinv, + const fq_zech_ctx_t ctx) + + Sets \code{res} to \code{poly} raised to the power \code{e} modulo + \code{f}, using sliding-window exponentiation with window size + \code{k}. We require \code{e > 0}. We require \code{finv} to be + the inverse of the reverse of \code{f}. If \code{k} is set to + zero, then an "optimum" size will be selected automatically base + on \code{e}. + + We require \code{lenf > 1}. It is assumed that \code{poly} is + already reduced modulo \code{f} and zero-padded as necessary to + have length exactly \code{lenf - 1}. The output \code{res} must + have room for \code{lenf - 1} coefficients. + +void +fq_zech_poly_powmod_fmpz_sliding_preinv(fq_zech_poly_t res, + const fq_zech_poly_t poly, fmpz_t e, + ulong k, const fq_zech_poly_t f, + const fq_zech_poly_t finv, + const fq_zech_ctx_t ctx) + + Sets \code{res} to \code{poly} raised to the power \code{e} modulo + \code{f}, using sliding-window exponentiation with window size + \code{k}. We require \code{e >= 0}. We require \code{finv} to be + the inverse of the reverse of \code{f}. If \code{k} is set to + zero, then an "optimum" size will be selected automatically base + on \code{e}. + +void +_fq_zech_poly_powmod_x_fmpz_preinv(fq_zech_struct * res, const fmpz_t e, + const fq_zech_struct * f, slong lenf, + const fq_zech_struct * finv, slong lenfinv, + const fq_zech_ctx_t ctx) + + Sets \code{res} to \code{x} raised to the power \code{e} modulo \code{f}, + using sliding window exponentiation. We require \code{e > 0}. + We require \code{finv} to be the inverse of the reverse of \code{f}. + + We require \code{lenf > 2}. The output \code{res} must have room for + \code{lenf - 1} coefficients. + +void +fq_zech_poly_powmod_x_fmpz_preinv(fq_zech_poly_t res, const fmpz_t e, + const fq_zech_poly_t f, const fq_zech_poly_t finv, + const fq_zech_ctx_t ctx) + + Sets \code{res} to \code{x} raised to the power \code{e} + modulo \code{f}, using sliding window exponentiation. We require + \code{e >= 0}. We require \code{finv} to be the inverse of the reverse of + \code{f}. + +******************************************************************************* + + Shifting + +******************************************************************************* + +void _fq_zech_poly_shift_left(fq_zech_struct *rop, const fq_zech_struct *op, + slong len, slong n, const fq_zech_ctx_t ctx) + + Sets \code{(res, len + n)} to \code{(poly, len)} shifted left by + $n$ coefficients. + + Inserts zero coefficients at the lower end. Assumes that + \code{len} and $n$ are positive, and that \code{res} fits + \code{len + n} elements. Supports aliasing between \code{res} and + \code{poly}. + +void fq_zech_poly_shift_left(fq_zech_poly_t rop, const fq_zech_poly_t op, slong n, + const fq_zech_ctx_t ctx) + + Sets \code{res} to \code{poly} shifted left by $n$ coeffs. Zero + coefficients are inserted. + +void _fq_zech_poly_shift_right(fq_zech_struct *rop, const fq_zech_struct *op, + slong len, slong n, const fq_zech_ctx_t ctx) + + Sets \code{(res, len - n)} to \code{(poly, len)} shifted right by + $n$ coefficients. + + Assumes that \code{len} and $n$ are positive, that \code{len > n}, + and that \code{res} fits \code{len - n} elements. Supports + aliasing between \code{res} and \code{poly}, although in this case + the top coefficients of \code{poly} are not set to zero. + +void fq_zech_poly_shift_right(fq_zech_poly_t rop, const fq_zech_poly_t op, + slong n, const fq_zech_ctx_t ctx) + + Sets \code{res} to \code{poly} shifted right by $n$ coefficients. + If $n$ is equal to or greater than the current length of + \code{poly}, \code{res} is set to the zero polynomial. + +******************************************************************************* + + Norms + +******************************************************************************* + +long _fq_zech_poly_hamming_weight(const fq_zech_poly *op, slong len, + const fq_zech_ctx_t ctx) + + Returns the number of non-zero entries in \code{(op, len)}. + +long fq_zech_poly_hamming_weight(const fq_zech_poly_t op, + const fq_zech_ctx_t ctx) + + Returns the number of non-zero entries in the polynomial \code{op}. + +******************************************************************************* + + Euclidean division + +******************************************************************************* + +void _fq_zech_poly_divrem_basecase(fq_zech_struct *Q, fq_zech_struct *R, + const fq_zech_struct *A, slong lenA, const fq_zech_struct *B, slong lenB, + const fq_zech_t invB, const fq_zech_ctx_t ctx) + + Computes \code{(Q, lenA - lenB + 1)}, \code{(R, lenA)} such that + $A = B Q + R$ with $0 \leq \len(R) < \len(B)$. + + Assumes that the leading coefficient of $B$ is invertible + and that \code{invB} is its inverse. + + Assumes that $\len(A), \len(B) > 0$. Allows zero-padding in + \code{(A, lenA)}. $R$ and $A$ may be aliased, but apart from + this no aliasing of input and output operands is allowed. + +void fq_zech_poly_divrem_basecase(fq_zech_poly_t Q, fq_zech_poly_t R, + const fq_zech_poly_t A, const fq_zech_poly_t B, + const fq_zech_ctx_t ctx) + + Computes $Q$, $R$ such that $A = B Q + R$ with + $0 \leq \len(R) < \len(B)$. + + Assumes that the leading coefficient of $B$ is invertible. This can + be taken for granted the context is for a finite field, that is, when + $p$ is prime and $f(X)$ is irreducible. + +void _fq_zech_poly_divrem(fq_zech_struct *Q, fq_zech_struct *R, + const fq_zech_struct *A, slong lenA, const fq_zech_struct *B, slong lenB, + const fq_zech_t invB, const fq_zech_ctx_t ctx) + + Computes \code{(Q, lenA - lenB + 1)}, \code{(R, lenA)} such that + $A = B Q + R$ with $0 \leq \len(R) < \len(B)$. + + Assumes that the leading coefficient of $B$ is invertible + and that \code{invB} is its inverse. + + Assumes that $\len(A), \len(B) > 0$. Allows zero-padding in + \code{(A, lenA)}. $R$ and $A$ may be aliased, but apart from + this no aliasing of input and output operands is allowed. + +void fq_zech_poly_divrem(fq_zech_poly_t Q, fq_zech_poly_t R, + const fq_zech_poly_t A, const fq_zech_poly_t B, + const fq_zech_ctx_t ctx) + + Computes $Q$, $R$ such that $A = B Q + R$ with + $0 \leq \len(R) < \len(B)$. + + Assumes that the leading coefficient of $B$ is invertible. This can + be taken for granted the context is for a finite field, that is, when + $p$ is prime and $f(X)$ is irreducible. + +void _fq_zech_poly_rem(fq_zech_struct *R, const fq_zech_struct *A, slong lenA, + const fq_zech_struct *B, slong lenB, const fq_zech_t invB, + const fq_zech_ctx_t ctx) + + Sets \code{R} to the remainder of the division of \code{(A,lenA)} by + \code{(B,lenB)}. Assumes that the leading coefficient of \code{(B,lenB)} + is invertible and that \code{invB} is its inverse. + +void fq_zech_poly_rem(fq_zech_poly_t R, + const fq_zech_poly_t A, const fq_zech_poly_t B, + const fq_zech_ctx_t ctx) + + Sets \code{R} to the remainder of the division of \code{A} by + \code{B} in the context described by \code{ctx}. + +void _fq_zech_poly_div_basecase(fq_zech_struct *Q, fq_zech_struct *R, + const fq_zech_struct *A, slong lenA, + const fq_zech_struct *B, slong lenB, + const fq_zech_t invB, const fq_zech_ctx_t ctx) + + Notationally, computes $Q$, $R$ such that $A = B Q + R$ with $0 + \leq \len(R) < \len(B)$ but only sets \code{(Q, lenA - lenB + 1)}. + + Requires temporary space \code{(R, lenA)}. If \code{R} is + \code{NULL}, then the temporary space will be allocated. Allows + aliasing only between $A$ and $R$. Allows zero-padding in $A$ but + not in $B$. Assumes that the leading coefficient of $B$ is a + unit. + +void fq_zech_poly_div_basecase(fq_zech_poly_t Q, const fq_zech_poly_t A, + const fq_zech_poly_t B, const fq_zech_ctx_t ctx) + + Notionally finds polynomials $Q$ and $R$ such that $A = B Q + R$ with + $\len(R) < \len(B)$, but returns only \code{Q}. If $\len(B) = 0$ an + exception is raised. + +void _fq_zech_poly_divrem_divconquer_recursive(fq_zech_struct * Q, fq_zech_struct * BQ, + fq_zech_struct * W, const fq_zech_struct * A, + const fq_zech_struct * B, slong lenB, + const fq_zech_t invB, const fq_zech_ctx_t ctx) + + Computes \code{(Q, lenB)}, \code{(BQ, 2 lenB - 1)} such that + $BQ = B \times Q$ and $A = B Q + R$ where $0 \leq \len(R) < \len(B)$. + + Assumes that the leading coefficient of $B$ is invertible and that + \code{invB} is the inverse. + + Assumes $\len(B) > 0$. Allows zero-padding in \code{(A, lenA)}. Requires + a temporary array \code{(W, 2 lenB - 1)}. No aliasing of input and output + operands is allowed. + + This function does not read the bottom $\len(B) - 1$ coefficients from + $A$, which means that they might not even need to exist in allocated + memory. + +void _fq_zech_poly_divrem_divconquer(fq_zech_struct * Q, fq_zech_struct * R, + const fq_zech_struct * A, slong lenA, + const fq_zech_struct * B, slong lenB, + const fq_zech_t invB, const fq_zech_ctx_t ctx) + + Computes \code{(Q, lenA - lenB + 1)}, \code{(R, lenA)} such that + $A = B Q + R$ and $0 \leq \len(R) < \len(B)$. + + Assumes that the leading coefficient of $B$ is invertible and that + \code{invB} is the inverse. + + Assumes $\len(A) \geq \len(B) > 0$. Allows zero-padding in + \code{(A, lenA)}. No aliasing of input and output operands is + allowed. + +void fq_zech_poly_divrem_divconquer(fq_zech_poly_t Q, fq_zech_poly_t R, + const fq_zech_poly_t A, const fq_zech_poly_t B, + const fq_zech_ctx_t ctx) + + Computes $Q$, $R$ such that $A = B Q + R$ and $0 \leq \len(R) < \len(B)$. + + Assumes that $B$ is non-zero and that the leading coefficient of + $B$ is invertible. + +void _fq_zech_poly_div_newton_n_preinv(fq_zech_struct* Q, + const fq_zech_struct* A, slong lenA, + const fq_zech_struct* B, slong lenB, + const fq_zech_struct* Binv, slong lenBinv, + const fq_zech_struct ctx_t) + + Notionally computes polynomials $Q$ and $R$ such that $A = BQ + R$ with + $\len(R)$ less than \code{lenB}, where \code{A} is of length \code{lenA} + and \code{B} is of length \code{lenB}, but return only $Q$. + + We require that $Q$ have space for \code{lenA - lenB + 1} coefficients + and assume that the leading coefficient of $B$ is a unit. Furthermore, we + assume that $Binv$ is the inverse of the reverse of $B$ mod $x^{\len(B)}$. + + The algorithm used is to reverse the polynomials and divide the + resulting power series, then reverse the result. + +void fq_zech_poly_div_newton_n_preinv(fq_zech_poly_t Q, const fq_zech_poly_t A, + const fq_zech_poly_t B, const fq_zech_poly_t Binv, + const fq_zech_ctx_t ctx) + + Notionally computes $Q$ and $R$ such that $A = BQ + R$ with + $\len(R) < \len(B)$, but returns only $Q$. + + We assume that the leading coefficient of $B$ is a unit and that $Binv$ is + the inverse of the reverse of $B$ mod $x^{\len(B)}$. + + It is required that the length of $A$ is less than or equal to + 2*the length of $B$ - 2. + + The algorithm used is to reverse the polynomials and divide the + resulting power series, then reverse the result. + +void _fq_zech_poly_divrem_newton_n_preinv(fq_zech_struct* Q, fq_zech_struct* R, + const fq_zech_struct* A, slong lenA, + const fq_zech_struct* B, slong lenB, + const fq_zech_struct* Binv, slong lenBinv, + const fq_zech_ctx_t ctx) + + Computes $Q$ and $R$ such that $A = BQ + R$ with $\len(R)$ less + than \code{lenB}, where $A$ is of length \code{lenA} and $B$ is of + length \code{lenB}. We require that $Q$ have space for + \code{lenA - lenB + 1} coefficients. Furthermore, we assume that $Binv$ is + the inverse of the reverse of $B$ mod $x^{\len(B)}$. The algorithm + used is to call \code{div_newton_preinv()} and then multiply out + and compute the remainder. + +void fq_zech_poly_divrem_newton_n_preinv(fq_zech_poly_t Q, fq_zech_poly_t R, + const fq_zech_poly_t A, const fq_zech_poly_t B, + const fq_zech_poly_t Binv, const fq_zech_ctx_t ctx) + + Computes $Q$ and $R$ such that $A = BQ + R$ with $\len(R) < + \len(B)$. We assume $Binv$ is the inverse of the reverse of $B$ + mod $x^{\len(B)}$. + + It is required that the length of $A$ is less than or equal to + 2*the length of $B$ - 2. + + The algorithm used is to call \code{div_newton()} and then + multiply out and compute the remainder. + +void +_fq_zech_poly_inv_series_newton(fq_zech_struct* Qinv, const fq_zech_struct* Q, slong n, + const fq_zech_ctx_t ctx) + + Given \code{Q} of length \code{n} whose constant coefficient is + invertible modulo the given modulus, find a polynomial \code{Qinv} + of length \code{n} such that \code{Q * Qinv} is \code{1} modulo + $x^n$. Requires \code{n > 0}. This function can be viewed as + inverting a power series via Newton iteration. + +void +fq_zech_poly_inv_series_newton(fq_zech_poly_t Qinv, const fq_zech_poly_t Q, slong n, + const fq_zech_ctx_t ctx) + + Given \code{Q} find \code{Qinv} such that \code{Q * Qinv} is + \code{1} modulo $x^n$. The constant coefficient of \code{Q} must + be invertible modulo the modulus of \code{Q}. An exception is + raised if this is not the case or if \code{n = 0}. This function + can be viewed as inverting a power series via Newton iteration. + +******************************************************************************* + + Greatest common divisor + +******************************************************************************* + +void fq_zech_poly_gcd(fq_zech_poly_t rop, const fq_zech_poly_t op1, + const fq_zech_poly_t op2, const fq_zech_ctx_t ctx) + + Sets \code{rop} to the greatest common divisor of \code{op1} and + \code{op2}, using the either the Euclidean or HGCD algorithm. The + GCD of zero polynomials is defined to be zero, whereas the GCD of + the zero polynomial and some other polynomial $P$ is defined to be + $P$. Except in the case where the GCD is zero, the GCD $G$ is made + monic. + +long _fq_zech_poly_gcd(fq_zech_struct* G,const fq_zech_struct* A, slong lenA, + const fq_zech_struct* B, slong lenB, + const fq_zech_ctx_t ctx) + + Computes the GCD of $A$ of length \code{lenA} and $B$ of length + \code{lenB}, where \code{lenA >= lenB > 0} and sets $G$ to it. The + length of the GCD $G$ is returned by the function. No attempt is + made to make the GCD monic. It is required that $G$ have space for + \code{lenB} coefficients. + +void fq_zech_poly_gcd_euclidean(fq_zech_poly_t rop, const fq_zech_poly_t op1, + const fq_zech_poly_t op2, + const fq_zech_ctx_t ctx) + + Sets \code{rop} to the greatest common divisor of \code{op1} and + \code{op2}, using the Euclidean algorithm. The GCD of zero + polynomials is defined to be zero, whereas the GCD of the zero + polynomial and some other polynomial $P$ is defined to be + $P$. Except in the case where the GCD is zero, the GCD $G$ is made + monic. + +long _fq_zech_poly_gcd_euclidean(fq_zech_struct* G, + const fq_zech_struct* A, slong lenA, + const fq_zech_struct* B, slong lenB, + const fq_zech_ctx_t ctx) + + Computes the GCD of $A$ of length \code{lenA} and $B$ of length + \code{lenB}, where \code{lenA >= lenB > 0} and sets $G$ to it. The + length of the GCD $G$ is returned by the function. No attempt is + made to make the GCD monic. It is required that $G$ have space for + \code{lenB} coefficients. + +******************************************************************************* + + Divisibility testing + +******************************************************************************* + +int _fq_zech_poly_divides(fq_zech_struct *Q, + const fq_zech_struct *A, slong lenA, + const fq_zech_struct *B, slong lenB, const fq_zech_t invB, + const fq_zech_ctx_t ctx) + + Returns $1$ if \code{(B, lenB)} divides \code{(A, lenA)} exactly and + sets $Q$ to the quotient, otherwise returns $0$. + + It is assumed that $\len(A) \geq \len(B) > 0$ and that $Q$ has space + for $\len(A) - \len(B) + 1$ coefficients. + + Aliasing of $Q$ with either of the inputs is not permitted. + + This function is currently unoptimised and provided for convenience + only. + +int fq_zech_poly_divides(fq_zech_poly_t Q, const fq_zech_poly_t A, const fq_zech_poly_t B, + const fq_zech_ctx_t ctx) + + + Returns $1$ if $B$ divides $A$ exactly and sets $Q$ to the quotient, + otherwise returns $0$. + + This function is currently unoptimised and provided for convenience + only. + +******************************************************************************* + + Derivative + +******************************************************************************* + +void _fq_zech_poly_derivative(fq_zech_struct *rop, const fq_zech_struct *op, slong len, + const fq_zech_ctx_t ctx) + + Sets \code{(rpoly, len - 1)} to the derivative of \code{(poly, len)}. + Also handles the cases where \code{len} is $0$ or $1$ correctly. + Supports aliasing of \code{rpoly} and \code{poly}. + +void fq_zech_poly_derivative(fq_zech_poly_t rop, const fq_zech_poly_t op, const fq_zech_ctx_t ctx) + + Sets \code{res} to the derivative of \code{poly}. + +******************************************************************************* + + Evaluation + +******************************************************************************* + +void _fq_zech_poly_evaluate_fq_zech(fq_zech_t rop, const fq_zech_struct *op, slong len, + const fq_zech_t a, const fq_zech_ctx_t ctx) + + Sets \code{rop} to \code{(op, len)} evaluated at $a$. + + Supports zero padding. There are no restrictions on \code{len}, that + is, \code{len} is allowed to be zero, too. + +void fq_zech_poly_evaluate_fq_zech(fq_zech_t rop, const fq_zech_poly_t f, const fq_zech_t a, + const fq_zech_ctx_t ctx) + + Sets \code{rop} to the value of $f(a)$. + + As the coefficient ring $\mathbf{F}_q$ is finite, Horner's method + is sufficient. + +******************************************************************************* + + Composition + +******************************************************************************* + +void _fq_zech_poly_compose_divconquer(fq_zech_struct *rop, + const fq_zech_struct *op1, slong len1, + const fq_zech_struct *op2, slong len2, + const fq_zech_ctx_t ctx) + + Computes the composition of \code{(op1, len1)} and \code{(op2, len2)} + using a divide and conquer approach and places the result into \code{rop}, + assuming \code{rop} can hold the output of length + \code{(len1 - 1) * (len2 - 1) + 1}. + + Assumes \code{len1, len2 > 0}. Does not support aliasing between + \code{rop} and any of \code{(op1, len1)} and \code{(op2, len2)}. + +void fq_zech_poly_compose_divconquer(fq_zech_poly_t rop, + const fq_zech_poly_t op1, const fq_zech_poly_t op2, + const fq_zech_ctx_t ctx) + + Sets \code{rop} to the composition of \code{op1} and \code{op2}. + To be precise about the order of composition, denoting \code{rop}, + \code{op1}, and \code{op2} by $f$, $g$, and $h$, respectively, + sets $f(t) = g(h(t))$. + +void _fq_zech_poly_compose_horner(fq_zech_struct *rop, const fq_zech_struct *op1, slong len1, + const fq_zech_struct *op2, slong len2, + const fq_zech_ctx_t ctx) + + Sets \code{rop} to the composition of \code{(op1, len1)} and + \code{(op2, len2)}. + + Assumes that \code{rop} has space for \code{(len1-1)*(len2-1) + 1} + coefficients. Assumes that \code{op1} and \code{op2} are non-zero + polynomials. Does not support aliasing between any of the inputs and + the output. + +void fq_zech_poly_compose_horner(fq_zech_poly_t rop, + const fq_zech_poly_t op1, const fq_zech_poly_t op2, + const fq_zech_ctx_t ctx) + + Sets \code{rop} to the composition of \code{op1} and \code{op2}. + To be more precise, denoting \code{rop}, \code{op1}, and \code{op2} + by $f$, $g$, and $h$, sets $f(t) = g(h(t))$. + + This implementation uses Horner's method. + +void _fq_zech_poly_compose(fq_zech_struct *rop, const fq_zech_struct *op1, slong len1, + const fq_zech_struct *op2, slong len2, + const fq_zech_ctx_t ctx) + + Sets \code{rop} to the composition of \code{(op1, len1)} and + \code{(op2, len2)}. + + Assumes that \code{rop} has space for \code{(len1-1)*(len2-1) + 1} + coefficients. Assumes that \code{op1} and \code{op2} are non-zero + polynomials. Does not support aliasing between any of the inputs and + the output. + +void fq_zech_poly_compose(fq_zech_poly_t rop, const fq_zech_poly_t op1, const fq_zech_poly_t op2, + const fq_zech_ctx_t ctx) + + Sets \code{rop} to the composition of \code{op1} and \code{op2}. + To be precise about the order of composition, denoting \code{rop}, + \code{op1}, and \code{op2} by $f$, $g$, and $h$, respectively, + sets $f(t) = g(h(t))$. + +void _fq_zech_poly_compose_mod_horner(fq_zech_struct * res, + const fq_zech_struct * f, slong lenf, + const fq_zech_struct * g, + const fq_zech_struct * h, slong lenh, + const fq_zech_ctx_t ctx) + + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require that + $h$ is nonzero and that the length of $g$ is one less than the + length of $h$ (possibly with zero padding). The output is not allowed + to be aliased with any of the inputs. + + The algorithm used is Horner's rule. + +void fq_zech_poly_compose_mod_horner(fq_zech_poly_t res, const fq_zech_poly_t f, + const fq_zech_poly_t g, const fq_zech_poly_t h, + const fq_zech_ctx_t ctx) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require that + $h$ is nonzero. The algorithm used is Horner's rule. + +void _fq_zech_poly_compose_mod_horner_preinv(fq_zech_struct * res, + const fq_zech_struct * f, slong lenf, + const fq_zech_struct * g, + const fq_zech_struct * h, slong lenh, + const fq_zech_struct * hinv, slong lenhiv, + const fq_zech_ctx_t ctx) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require + that $h$ is nonzero and that the length of $g$ is one less than + the length of $h$ (possibly with zero padding). We also require + that the length of $f$ is less than the length of + $h$. Furthermore, we require \code{hinv} to be the inverse of the + reverse of \code{h}. The output is not allowed to be aliased with + any of the inputs. + + The algorithm used is Horner's rule. + +void fq_zech_poly_compose_mod_horner_preinv(fq_zech_poly_t res, const fq_zech_poly_t f, + const fq_zech_poly_t g, const fq_zech_poly_t h, + const fq_zech_poly_t hinv, + const fq_zech_ctx_t ctx) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require + that $h$ is nonzero and that $f$ has smaller degree than + $h$. Furthermore, we require \code{hinv} to be the inverse of the + reverse of \code{h}. The algorithm used is Horner's rule. + + +void _fq_zech_poly_compose_mod_brent_kung(fq_zech_struct * res, + const fq_zech_struct * f, slong lenf, + const fq_zech_struct * g, + const fq_zech_struct * h, slong lenh, + const fq_zech_ctx_t ctx) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require + that $h$ is nonzero and that the length of $g$ is one less than + the length of $h$ (possibly with zero padding). We also require + that the length of $f$ is less than the length of $h$. The output + is not allowed to be aliased with any of the inputs. + + The algorithm used is the Brent-Kung matrix algorithm. + +void fq_zech_poly_compose_mod_brent_kung(fq_zech_poly_t res, const fq_zech_poly_t f, + const fq_zech_poly_t g, const fq_zech_poly_t h, + const fq_zech_ctx_t ctx) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require + that $h$ is nonzero and that $f$ has smaller degree than $h$. The + algorithm used is the Brent-Kung matrix algorithm. + +void _fq_zech_poly_compose_mod_brent_kung_preinv(fq_zech_struct * res, + const fq_zech_struct * f, slong lenf, + const fq_zech_struct * g, + const fq_zech_struct * h, slong lenh, + const fq_zech_struct * hinv, slong lenhiv, + const fq_zech_ctx_t ctx) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require + that $h$ is nonzero and that the length of $g$ is one less than + the length of $h$ (possibly with zero padding). We also require + that the length of $f$ is less than the length of + $h$. Furthermore, we require \code{hinv} to be the inverse of the + reverse of \code{h}. The output is not allowed to be aliased with + any of the inputs. + + The algorithm used is the Brent-Kung matrix algorithm. + +void fq_zech_poly_compose_mod_brent_kung_preinv(fq_zech_poly_t res, const fq_zech_poly_t f, + const fq_zech_poly_t g, const fq_zech_poly_t h, + const fq_zech_poly_t hinv, + const fq_zech_ctx_t ctx) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require + that $h$ is nonzero and that $f$ has smaller degree than + $h$. Furthermore, we require \code{hinv} to be the inverse of the + reverse of \code{h}. The algorithm used is the Brent-Kung matrix + algorithm. + +void _fq_zech_poly_compose_mod(fq_zech_struct * res, const fq_zech_struct * f, slong lenf, + const fq_zech_struct * g, const fq_zech_struct * h, slong lenh, + const fq_zech_ctx_t ctx) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require + that $h$ is nonzero and that the length of $g$ is one less than + the length of $h$ (possibly with zero padding). The output is not + allowed to be aliased with any of the inputs. + +void fq_zech_poly_compose_mod(fq_zech_poly_t res, const fq_zech_poly_t f, const fq_zech_poly_t g, + const fq_zech_poly_t h, const fq_zech_ctx_t ctx) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require + that $h$ is nonzero. + +void _fq_zech_poly_compose_mod_preinv(fq_zech_struct * res, + const fq_zech_struct * f, slong lenf, + const fq_zech_struct * g, + const fq_zech_struct * h, slong lenh, + const fq_zech_struct * hinv, slong lenhiv, + const fq_zech_ctx_t ctx) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require + that $h$ is nonzero and that the length of $g$ is one less than + the length of $h$ (possibly with zero padding). We also require + that the length of $f$ is less than the length of + $h$. Furthermore, we require \code{hinv} to be the inverse of the + reverse of \code{h}. The output is not allowed to be aliased with + any of the inputs. + +void fq_zech_poly_compose_mod_preinv(fq_zech_poly_t res, const fq_zech_poly_t f, + const fq_zech_poly_t g, const fq_zech_poly_t h, + const fq_zech_poly_t hinv, + const fq_zech_ctx_t ctx) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require + that $h$ is nonzero and that $f$ has smaller degree than + $h$. Furthermore, we require \code{hinv} to be the inverse of the + reverse of \code{h}. + +void +_fq_zech_poly_reduce_matrix_mod_poly (fq_zech_mat_t A, const fq_zech_mat_t B, + const fq_zech_poly_t f, const fq_zech_ctx_t ctx) + + Sets the ith row of \code{A} to the reduction of the ith row of $B$ modulo + $f$ for $i=1,\ldots,\sqrt{\deg(f)}$. We require $B$ to be at least + a $\sqrt{\deg(f)}\times \deg(f)$ matrix and $f$ to be nonzero. + +void +_fq_zech_poly_precompute_matrix (fq_zech_mat_t A, const fq_zech_struct* f, const fq_zech_struct* g, + slong leng, const fq_zech_struct* ginv, slong lenginv, + const fq_zech_ctx_t ctx) + + Sets the ith row of \code{A} to $f^i$ modulo $g$ for + $i=1,\ldots,\sqrt{\deg(g)}$. We require $A$ to be a + $\sqrt{\deg(g)}\times \deg(g)$ matrix. We require \code{ginv} to + be the inverse of the reverse of \code{g} and $g$ to be nonzero. + +void +fq_zech_poly_precompute_matrix (fq_zech_mat_t A, const fq_zech_poly_t f, + const fq_zech_poly_t g, const fq_zech_poly_t ginv, + const fq_zech_ctx_t ctx) + + Sets the ith row of \code{A} to $f^i$ modulo $g$ for + $i=1,\ldots,\sqrt{\deg(g)}$. We require $A$ to be a + $\sqrt{\deg(g)}\times \deg(g)$ matrix. We require \code{ginv} to + be the inverse of the reverse of \code{g}. + + +void +_fq_zech_poly_compose_mod_brent_kung_precomp_preinv(fq_zech_struct* res, const fq_zech_struct* f, + slong lenf, const fq_zech_mat_t A, const fq_zech_struct* h, + slong h, const fq_zech_struct* hinv, slong lenhinv, + const fq_zech_ctx_t ctx) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require + that $h$ is nonzero. We require that the ith row of $A$ contains + $g^i$ for $i=1,\ldots,\sqrt{\deg(h)}$, i.e. $A$ is a + $\sqrt{\deg(h)}\times \deg(h)$ matrix. We also require that the + length of $f$ is less than the length of $h$. Furthermore, we + require \code{hinv} to be the inverse of the reverse of \code{h}. + The output is not allowed to be aliased with any of the inputs. + + The algorithm used is the Brent-Kung matrix algorithm. + +void +fq_zech_poly_compose_mod_brent_kung_precomp_preinv(fq_zech_poly_t res, + const fq_zech_poly_t f, const fq_zech_mat_t A, + const fq_zech_poly_t h, const fq_zech_poly_t hinv, + const fq_zech_ctx_t ctx) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require + that the ith row of $A$ contains $g^i$ for + $i=1,\ldots,\sqrt{\deg(h)}$, i.e. $A$ is a $\sqrt{\deg(h)}\times + \deg(h)$ matrix. We require that $h$ is nonzero and that $f$ has + smaller degree than $h$. Furthermore, we require \code{hinv} to be + the inverse of the reverse of \code{h}. This version of Brent-Kung + modular composition is particularly useful if one has to perform + several modular composition of the form $f(g)$ modulo $h$ for + fixed $g$ and $h$. + + +******************************************************************************* + + Output + +******************************************************************************* + +int _fq_zech_poly_fprint_pretty(FILE *file, const fq_zech_struct *poly, slong len, + const char *x, const fq_zech_ctx_t ctx) + + Prints the pretty representation of \code{(poly, len)} to the stream + \code{file}, using the string \code{x} to represent the indeterminate. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + +int fq_zech_poly_fprint_pretty(FILE * file, const fq_zech_poly_t poly, const char *x, + const fq_zech_ctx_t ctx) + + Prints the pretty representation of \code{poly} to the stream + \code{file}, using the string \code{x} to represent the indeterminate. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + + +int _fq_zech_poly_print_pretty(const fq_zech_struct *poly, slong len, + const char *x, const fq_zech_ctx_t ctx) + + Prints the pretty representation of \code{(poly, len)} to \code{stdout}, + using the string \code{x} to represent the indeterminate. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + + +int fq_zech_poly_print_pretty(const fq_zech_poly_t poly, const char *x, + const fq_zech_ctx_t ctx) + + Prints the pretty representation of \code{poly} to \code{stdout}, + using the string \code{x} to represent the indeterminate. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + +int _fq_zech_poly_fprint(FILE *file, const fq_zech_struct *poly, slong len, + const fq_zech_ctx_t ctx) + + Prints the pretty representation of \code{(poly, len)} to the stream + \code{file}. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + +int fq_zech_poly_fprint(FILE * file, const fq_zech_poly_t poly, const fq_zech_ctx_t ctx) + + Prints the pretty representation of \code{poly} to the stream + \code{file}. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + + +int _fq_zech_poly_print(const fq_zech_struct *poly, slong len, const fq_zech_ctx_t ctx) + + Prints the pretty representation of \code{(poly, len)} to \code{stdout}. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + + +int fq_zech_poly_print(const fq_zech_poly_t poly, const fq_zech_ctx_t ctx) + + Prints the representation of \code{poly} to \code{stdout}. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + +char * _fq_zech_poly_get_str(const fq_zech_struct * poly, slong len, const fq_zech_ctx_t ctx) + + Returns the plain FLINT string representation of the polynomial + \code{(poly, len)}. + +char * fq_zech_poly_get_str(const fq_zech_poly_t poly, const fq_zech_ctx_t ctx) + + Returns the plain FLINT string representation of the polynomial + \code{poly}. + +char * _fq_zech_poly_get_str_pretty(const fq_zech_struct * poly, slong len, + const char * x, const fq_zech_ctx_t ctx) + + Returns a pretty representation of the polynomial + \code{(poly, len)} using the null-terminated string~\code{x} as the + variable name. + +char * fq_zech_poly_get_str_pretty(const fq_zech_poly_t poly, const char * x, + const fq_zech_ctx_t ctx) + + Returns a pretty representation of the polynomial~\code{poly} using the + null-terminated string \code{x} as the variable name + +******************************************************************************* + + Inflation and deflation + +******************************************************************************* + +void fq_zech_poly_inflate(fq_zech_poly_t result, const fq_zech_poly_t input, + ulong inflation, const fq_zech_ctx_t ctx) + + Sets \code{result} to the inflated polynomial $p(x^n)$ where + $p$ is given by \code{input} and $n$ is given by \code{inflation}. + +void fq_zech_poly_deflate(fq_zech_poly_t result, const fq_zech_poly_t input, + ulong deflation, const fq_zech_ctx_t ctx) + + Sets \code{result} to the deflated polynomial $p(x^{1/n})$ where + $p$ is given by \code{input} and $n$ is given by \code{deflation}. + Requires $n > 0$. + +ulong fq_zech_poly_deflation(const fq_zech_poly_t input, const fq_zech_ctx_t ctx) + + Returns the largest integer by which \code{input} can be deflated. + As special cases, returns 0 if \code{input} is the zero polynomial + and 1 of \code{input} is a constant polynomial. diff --git a/external/flint-2.4.3/fq_zech_poly/equal.c b/external/flint-2.4.3/fq_zech_poly/equal.c new file mode 100644 index 0000000..a1cad62 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/equal.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/equal.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/evaluate_fq.c b/external/flint-2.4.3/fq_zech_poly/evaluate_fq.c new file mode 100644 index 0000000..f048927 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/evaluate_fq.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/evaluate_fq.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/fit_length.c b/external/flint-2.4.3/fq_zech_poly/fit_length.c new file mode 100644 index 0000000..5f31b86 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/fit_length.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/fit_length.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/fprint.c b/external/flint-2.4.3/fq_zech_poly/fprint.c new file mode 100644 index 0000000..21d2e77 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/fprint.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/fprint.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/fprint_pretty.c b/external/flint-2.4.3/fq_zech_poly/fprint_pretty.c new file mode 100644 index 0000000..06fbb75 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/fprint_pretty.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/fprint_pretty.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/gcd_euclidean.c b/external/flint-2.4.3/fq_zech_poly/gcd_euclidean.c new file mode 100644 index 0000000..ce874f3 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/gcd_euclidean.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/gcd_euclidean.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/gen.c b/external/flint-2.4.3/fq_zech_poly/gen.c new file mode 100644 index 0000000..2591fab --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/gen.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/gen.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/get_coeff.c b/external/flint-2.4.3/fq_zech_poly/get_coeff.c new file mode 100644 index 0000000..96b5f7a --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/get_coeff.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/get_coeff.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/get_str.c b/external/flint-2.4.3/fq_zech_poly/get_str.c new file mode 100644 index 0000000..6c2a2c9 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/get_str.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/get_str.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/get_str_pretty.c b/external/flint-2.4.3/fq_zech_poly/get_str_pretty.c new file mode 100644 index 0000000..c2ea6b7 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/get_str_pretty.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/get_str_pretty.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/hamming_weight.c b/external/flint-2.4.3/fq_zech_poly/hamming_weight.c new file mode 100644 index 0000000..310a1a6 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/hamming_weight.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/hamming_weight.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/inflate.c b/external/flint-2.4.3/fq_zech_poly/inflate.c new file mode 100644 index 0000000..2070cad --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/inflate.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/inflate.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/init.c b/external/flint-2.4.3/fq_zech_poly/init.c new file mode 100644 index 0000000..e5de821 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/init.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/init.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/inv_series_newton.c b/external/flint-2.4.3/fq_zech_poly/inv_series_newton.c new file mode 100644 index 0000000..850e14e --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/inv_series_newton.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/inv_series_newton.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/make_monic.c b/external/flint-2.4.3/fq_zech_poly/make_monic.c new file mode 100644 index 0000000..8348043 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/make_monic.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/make_monic.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/mul.c b/external/flint-2.4.3/fq_zech_poly/mul.c new file mode 100644 index 0000000..87d9329 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/mul.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/mul.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/mul_KS.c b/external/flint-2.4.3/fq_zech_poly/mul_KS.c new file mode 100644 index 0000000..22d73c4 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/mul_KS.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/mul_KS.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/mul_classical.c b/external/flint-2.4.3/fq_zech_poly/mul_classical.c new file mode 100644 index 0000000..e159fad --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/mul_classical.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/mul_classical.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/mullow.c b/external/flint-2.4.3/fq_zech_poly/mullow.c new file mode 100644 index 0000000..978ac91 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/mullow.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/mullow.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/mullow_KS.c b/external/flint-2.4.3/fq_zech_poly/mullow_KS.c new file mode 100644 index 0000000..d7e1af2 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/mullow_KS.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/mullow_KS.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/mullow_classical.c b/external/flint-2.4.3/fq_zech_poly/mullow_classical.c new file mode 100644 index 0000000..65ca4ee --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/mullow_classical.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/mullow_classical.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/mulmod.c b/external/flint-2.4.3/fq_zech_poly/mulmod.c new file mode 100644 index 0000000..b436882 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/mulmod.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/mulmod.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/mulmod_preinv.c b/external/flint-2.4.3/fq_zech_poly/mulmod_preinv.c new file mode 100644 index 0000000..6d14fa3 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/mulmod_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/mulmod_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/neg.c b/external/flint-2.4.3/fq_zech_poly/neg.c new file mode 100644 index 0000000..09e62cb --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/neg.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/neg.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/normalise.c b/external/flint-2.4.3/fq_zech_poly/normalise.c new file mode 100644 index 0000000..159d817 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/normalise.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/normalise.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/one.c b/external/flint-2.4.3/fq_zech_poly/one.c new file mode 100644 index 0000000..1b2ec46 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/one.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/one.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/pow.c b/external/flint-2.4.3/fq_zech_poly/pow.c new file mode 100644 index 0000000..c86a2a6 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/pow.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/pow.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/powmod_fmpz_binexp.c b/external/flint-2.4.3/fq_zech_poly/powmod_fmpz_binexp.c new file mode 100644 index 0000000..02d7725 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/powmod_fmpz_binexp.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/powmod_fmpz_binexp.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/powmod_fmpz_binexp_preinv.c b/external/flint-2.4.3/fq_zech_poly/powmod_fmpz_binexp_preinv.c new file mode 100644 index 0000000..b763371 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/powmod_fmpz_binexp_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/powmod_fmpz_binexp_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/powmod_fmpz_sliding_preinv.c b/external/flint-2.4.3/fq_zech_poly/powmod_fmpz_sliding_preinv.c new file mode 100644 index 0000000..1a59810 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/powmod_fmpz_sliding_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/powmod_fmpz_sliding_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/powmod_ui_binexp.c b/external/flint-2.4.3/fq_zech_poly/powmod_ui_binexp.c new file mode 100644 index 0000000..3633dd6 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/powmod_ui_binexp.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/powmod_ui_binexp.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/powmod_ui_binexp_preinv.c b/external/flint-2.4.3/fq_zech_poly/powmod_ui_binexp_preinv.c new file mode 100644 index 0000000..f29df5b --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/powmod_ui_binexp_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/powmod_ui_binexp_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/powmod_x_fmpz_preinv.c b/external/flint-2.4.3/fq_zech_poly/powmod_x_fmpz_preinv.c new file mode 100644 index 0000000..f98cc6b --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/powmod_x_fmpz_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/powmod_x_fmpz_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/profile/p-factor_kaltofen_shoup_vs_fq_nmod_poly.c b/external/flint-2.4.3/fq_zech_poly/profile/p-factor_kaltofen_shoup_vs_fq_nmod_poly.c new file mode 100644 index 0000000..1028606 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/profile/p-factor_kaltofen_shoup_vs_fq_nmod_poly.c @@ -0,0 +1,155 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ +#include +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "ulong_extras.h" +#include "profiler.h" + +#include "fq_zech_poly.h" +#include "fq_nmod_poly.h" + +#define nalgs 2 +#define ncases 1 +#define cpumin 2 + +int +main(int argc, char** argv) +{ + slong s[nalgs]; + + int c, n, len, ext, reps = 0; + slong j; + fmpz_t p, temp; + fq_zech_poly_t f, g; + fq_nmod_poly_t fn; + fq_zech_ctx_t ctx; + fq_nmod_ctx_t ctxn; + + FLINT_TEST_INIT(state); + + fmpz_init(p); + fmpz_set_str(p, argv[1], 10); + + fmpz_init(temp); + + fmpz_set_str(temp, argv[2], 10); + ext = fmpz_get_si(temp); + + fmpz_set_str(temp, argv[3], 10); + len = fmpz_get_si(temp); + + fq_nmod_ctx_init(ctxn, p, ext, "a"); + fq_zech_ctx_init_fq_nmod_ctx(ctx, ctxn); + + fq_zech_poly_init(f, ctx); + fq_zech_poly_init(g, ctx); + fq_nmod_poly_init(fn, ctxn); + + for (c = 0; c < nalgs; c++) + { + s[c] = WORD(0); + } + + for (n = 0; n < ncases; n++) + { + timeit_t t[nalgs]; + int l, loops = 1; + fq_zech_poly_factor_t res; + fq_nmod_poly_factor_t resn; + + /* + Construct random elements of fq + */ + { + fq_zech_poly_randtest_irreducible(f, state, len + 1, ctx); + fq_zech_poly_randtest_irreducible(g, state, len + 2, ctx); + fq_zech_poly_mul(f, f, g, ctx); + fq_zech_poly_make_monic(f, f, ctx); + + fq_nmod_poly_fit_length(fn, f->length, ctxn); + for (j = 0; j < f->length; j++) + { + fq_zech_get_fq_nmod(fn->coeffs + j, f->coeffs + j, ctx); + + } + _fq_nmod_poly_set_length(fn, f->length, ctxn); + } + + loop: + fflush(stdout); + timeit_start(t[0]); + for (l = 0; l < loops; l++) + { + fq_zech_poly_factor_init(res, ctx); + fq_zech_poly_factor_kaltofen_shoup(res, f, ctx); + fq_zech_poly_factor_clear(res, ctx); + } + timeit_stop(t[0]); + + timeit_start(t[1]); + for (l = 0; l < loops; l++) + { + fq_nmod_poly_factor_init(resn, ctxn); + fq_nmod_poly_factor_kaltofen_shoup(resn, fn, ctxn); + fq_nmod_poly_factor_clear(resn, ctxn); + + } + timeit_stop(t[1]); + + for (c = 0; c < nalgs; c++) + if (t[c]->cpu <= cpumin) + { + loops += 2; + goto loop; + } + + for (c = 0; c < nalgs; c++) + s[c] += t[c]->cpu; + reps += loops; + } + + for (c = 0; c < nalgs; c++) + { + flint_printf("%20f ", s[c] / (double) reps); + fflush(stdout); + } + printf("\n"); + + fq_zech_poly_clear(f, ctx); + fq_zech_poly_clear(g, ctx); + fq_nmod_poly_clear(fn, ctxn); + fq_zech_ctx_clear(ctx); + fq_nmod_ctx_clear(ctxn); + fmpz_clear(p); + fmpz_clear(temp); + + FLINT_TEST_CLEANUP(state); + + return 0; +} diff --git a/external/flint-2.4.3/fq_zech_poly/profile/p-factor_vs_fq_nmod.c b/external/flint-2.4.3/fq_zech_poly/profile/p-factor_vs_fq_nmod.c new file mode 100644 index 0000000..945ee5f --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/profile/p-factor_vs_fq_nmod.c @@ -0,0 +1,145 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "flint.h" +#include "fq_nmod_poly.h" +#include "fq_zech_poly.h" +#include "profiler.h" + +#define nalgs 2 +#define cpumin 2 +#define ncases 10 + +int +main(int argc, char** argv) +{ + fmpz_t p; + int c, n, reps = 0; + slong d, len, i; + fq_nmod_ctx_t ctx; + fq_zech_ctx_t ctx_zech; + fq_nmod_poly_t f, g; + fq_zech_poly_t fz, gz; + + double s[nalgs]; + + FLINT_TEST_INIT(state); + + fmpz_init(p); + fmpz_set_str(p, argv[1], 10); + + d = atol(argv[2]); + len = atol(argv[3]); + + fq_nmod_ctx_init(ctx, p, d, "a"); + fq_zech_ctx_init_fq_nmod_ctx(ctx_zech, ctx); + + fq_nmod_poly_init(f, ctx); + fq_nmod_poly_init(g, ctx); + fq_zech_poly_init(fz, ctx_zech); + fq_zech_poly_init(gz, ctx_zech); + + + for (c = 0; c < nalgs; c++) + s[c] = 0.0; + + for (n = 0; n < ncases; n++) + { + double t[nalgs]; + int l, loops = 1; + fq_nmod_poly_factor_t res; + fq_zech_poly_factor_t resz; + + /* + Construct random elements of fq[x] + */ + { + fq_nmod_poly_randtest_monic(f, state, len, ctx); + fq_zech_poly_fit_length(fz, len, ctx_zech); + for (i = 0; i < f->length; i++) + fq_zech_set_fq_nmod(fz->coeffs + i, f->coeffs + i, ctx_zech); + _fq_zech_poly_set_length(fz, len, ctx_zech); + _fq_zech_poly_normalise(fz, ctx_zech); + } + + loop: + + t[0] = 0.0; + init_clock(0); + prof_start(); + for (l = 0; l < loops; l++) + { + fq_nmod_poly_factor_init(res, ctx); + fq_nmod_poly_factor_kaltofen_shoup(res, f, ctx); + fq_nmod_poly_factor_clear(res, ctx); + } + prof_stop(); + t[0] += get_clock(0); + + t[1] = 0.0; + init_clock(0); + prof_start(); + for (l = 0; l < loops; l++) + { + fq_zech_poly_factor_init(resz, ctx_zech); + fq_zech_poly_factor_kaltofen_shoup(resz, fz, ctx_zech); + fq_zech_poly_factor_clear(resz, ctx_zech); + } + prof_stop(); + t[1] += get_clock(0); + + for (c = 0; c < nalgs; c++) + if (t[c] * FLINT_CLOCK_SCALE_FACTOR <= cpumin) + { + loops *= 10; + goto loop; + } + + for (c = 0; c < nalgs; c++) + s[c] += t[c]; + reps += loops; + } + + for (c = 0; c < nalgs; c++) + { + printf("%20f", s[c] / (double) reps); + fflush(stdout); + } + printf("\n"); + + + fq_nmod_poly_clear(f, ctx); + fq_nmod_poly_clear(g, ctx); + fq_zech_poly_clear(fz, ctx_zech); + fq_zech_poly_clear(gz, ctx_zech); + + fq_nmod_ctx_clear(ctx); + fq_zech_ctx_clear(ctx_zech); + fmpz_clear(p); + + FLINT_TEST_CLEANUP(state); + + return 0; +} diff --git a/external/flint-2.4.3/fq_zech_poly/profile/p-factor_xnpxp1.c b/external/flint-2.4.3/fq_zech_poly/profile/p-factor_xnpxp1.c new file mode 100644 index 0000000..71b453c --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/profile/p-factor_xnpxp1.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/profile/p-factor_xnpxp1.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/profile/p-is_irreducible.c b/external/flint-2.4.3/fq_zech_poly/profile/p-is_irreducible.c new file mode 100644 index 0000000..00abac8 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/profile/p-is_irreducible.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/profile/p-is_irreducible.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/profile/p-iterated_frobenius.c b/external/flint-2.4.3/fq_zech_poly/profile/p-iterated_frobenius.c new file mode 100644 index 0000000..933ac9a --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/profile/p-iterated_frobenius.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/profile/p-iterated_frobenius.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/profile/p-iterated_frobenius_table.c b/external/flint-2.4.3/fq_zech_poly/profile/p-iterated_frobenius_table.c new file mode 100644 index 0000000..60b5d80 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/profile/p-iterated_frobenius_table.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/profile/p-iterated_frobenius_table.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/profile/p-mullow.c b/external/flint-2.4.3/fq_zech_poly/profile/p-mullow.c new file mode 100644 index 0000000..8a2c11d --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/profile/p-mullow.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/profile/p-mullow.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/profile/p-sqr.c b/external/flint-2.4.3/fq_zech_poly/profile/p-sqr.c new file mode 100644 index 0000000..6b3c77d --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/profile/p-sqr.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/profile/p-sqr.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/randtest.c b/external/flint-2.4.3/fq_zech_poly/randtest.c new file mode 100644 index 0000000..e7f880f --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/randtest.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/randtest.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/randtest_irreducible.c b/external/flint-2.4.3/fq_zech_poly/randtest_irreducible.c new file mode 100644 index 0000000..3329d20 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/randtest_irreducible.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/randtest_irreducible.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/randtest_monic.c b/external/flint-2.4.3/fq_zech_poly/randtest_monic.c new file mode 100644 index 0000000..8c931da --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/randtest_monic.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/randtest_monic.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/realloc.c b/external/flint-2.4.3/fq_zech_poly/realloc.c new file mode 100644 index 0000000..0a45abe --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/realloc.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/realloc.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/remove.c b/external/flint-2.4.3/fq_zech_poly/remove.c new file mode 100644 index 0000000..e6e54b9 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/remove.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/remove.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/reverse.c b/external/flint-2.4.3/fq_zech_poly/reverse.c new file mode 100644 index 0000000..f8db1bc --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/reverse.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/reverse.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/scalar_addmul_fq.c b/external/flint-2.4.3/fq_zech_poly/scalar_addmul_fq.c new file mode 100644 index 0000000..6a16126 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/scalar_addmul_fq.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/scalar_addmul_fq.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/scalar_mul_fq.c b/external/flint-2.4.3/fq_zech_poly/scalar_mul_fq.c new file mode 100644 index 0000000..2ea09b0 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/scalar_mul_fq.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/scalar_mul_fq.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/scalar_submul_fq.c b/external/flint-2.4.3/fq_zech_poly/scalar_submul_fq.c new file mode 100644 index 0000000..7fd878d --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/scalar_submul_fq.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/scalar_submul_fq.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/set.c b/external/flint-2.4.3/fq_zech_poly/set.c new file mode 100644 index 0000000..28337e4 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/set.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/set.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/set_coeff.c b/external/flint-2.4.3/fq_zech_poly/set_coeff.c new file mode 100644 index 0000000..13fa401 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/set_coeff.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/set_coeff.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/set_fq.c b/external/flint-2.4.3/fq_zech_poly/set_fq.c new file mode 100644 index 0000000..a93ce9d --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/set_fq.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/set_fq.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/shift_left.c b/external/flint-2.4.3/fq_zech_poly/shift_left.c new file mode 100644 index 0000000..e274f13 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/shift_left.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/shift_left.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/shift_right.c b/external/flint-2.4.3/fq_zech_poly/shift_right.c new file mode 100644 index 0000000..778827e --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/shift_right.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/shift_right.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/sqr.c b/external/flint-2.4.3/fq_zech_poly/sqr.c new file mode 100644 index 0000000..e201b4a --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/sqr.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/sqr.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/sqr_KS.c b/external/flint-2.4.3/fq_zech_poly/sqr_KS.c new file mode 100644 index 0000000..1dd3a75 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/sqr_KS.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/sqr_KS.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/sqr_classical.c b/external/flint-2.4.3/fq_zech_poly/sqr_classical.c new file mode 100644 index 0000000..7156595 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/sqr_classical.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/sqr_classical.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/sub.c b/external/flint-2.4.3/fq_zech_poly/sub.c new file mode 100644 index 0000000..f9b596f --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/sub.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/sub.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/swap.c b/external/flint-2.4.3/fq_zech_poly/swap.c new file mode 100644 index 0000000..ab99137 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/swap.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/swap.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/test/t-add.c b/external/flint-2.4.3/fq_zech_poly/test/t-add.c new file mode 100644 index 0000000..8317ec8 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/test/t-add.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/test/t-add.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/test/t-compose.c b/external/flint-2.4.3/fq_zech_poly/test/t-compose.c new file mode 100644 index 0000000..6a3e615 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/test/t-compose.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/test/t-compose.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/test/t-compose_divconquer.c b/external/flint-2.4.3/fq_zech_poly/test/t-compose_divconquer.c new file mode 100644 index 0000000..89147c1 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/test/t-compose_divconquer.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/test/t-compose_divconquer.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/test/t-compose_horner.c b/external/flint-2.4.3/fq_zech_poly/test/t-compose_horner.c new file mode 100644 index 0000000..b99f6b5 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/test/t-compose_horner.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/test/t-compose_horner.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/test/t-compose_mod.c b/external/flint-2.4.3/fq_zech_poly/test/t-compose_mod.c new file mode 100644 index 0000000..5d2ba19 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/test/t-compose_mod.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/test/t-compose_mod.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/test/t-compose_mod_brent_kung.c b/external/flint-2.4.3/fq_zech_poly/test/t-compose_mod_brent_kung.c new file mode 100644 index 0000000..9a42f3f --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/test/t-compose_mod_brent_kung.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/test/t-compose_mod_brent_kung.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/test/t-compose_mod_brent_kung_preinv.c b/external/flint-2.4.3/fq_zech_poly/test/t-compose_mod_brent_kung_preinv.c new file mode 100644 index 0000000..cf34bb7 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/test/t-compose_mod_brent_kung_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/test/t-compose_mod_brent_kung_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/test/t-compose_mod_horner.c b/external/flint-2.4.3/fq_zech_poly/test/t-compose_mod_horner.c new file mode 100644 index 0000000..7ec91ec --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/test/t-compose_mod_horner.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/test/t-compose_mod_horner.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/test/t-compose_mod_horner_preinv.c b/external/flint-2.4.3/fq_zech_poly/test/t-compose_mod_horner_preinv.c new file mode 100644 index 0000000..b50fb68 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/test/t-compose_mod_horner_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/test/t-compose_mod_horner_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/test/t-compose_mod_preinv.c b/external/flint-2.4.3/fq_zech_poly/test/t-compose_mod_preinv.c new file mode 100644 index 0000000..1177790 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/test/t-compose_mod_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/test/t-compose_mod_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/test/t-deflate.c b/external/flint-2.4.3/fq_zech_poly/test/t-deflate.c new file mode 100644 index 0000000..b310e2c --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/test/t-deflate.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/test/t-deflate.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/test/t-derivative.c b/external/flint-2.4.3/fq_zech_poly/test/t-derivative.c new file mode 100644 index 0000000..02ced88 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/test/t-derivative.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/test/t-derivative.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/test/t-div_basecase.c b/external/flint-2.4.3/fq_zech_poly/test/t-div_basecase.c new file mode 100644 index 0000000..cc4a56c --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/test/t-div_basecase.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/test/t-div_basecase.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/test/t-div_newton_n_preinv.c b/external/flint-2.4.3/fq_zech_poly/test/t-div_newton_n_preinv.c new file mode 100644 index 0000000..4811701 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/test/t-div_newton_n_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/test/t-div_newton_n_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/test/t-divides.c b/external/flint-2.4.3/fq_zech_poly/test/t-divides.c new file mode 100644 index 0000000..411e993 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/test/t-divides.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/test/t-divides.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/test/t-divrem_basecase.c b/external/flint-2.4.3/fq_zech_poly/test/t-divrem_basecase.c new file mode 100644 index 0000000..b6f00a4 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/test/t-divrem_basecase.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/test/t-divrem_basecase.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/test/t-divrem_divconquer.c b/external/flint-2.4.3/fq_zech_poly/test/t-divrem_divconquer.c new file mode 100644 index 0000000..5255fba --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/test/t-divrem_divconquer.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/test/t-divrem_divconquer.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/test/t-divrem_newton_n_preinv.c b/external/flint-2.4.3/fq_zech_poly/test/t-divrem_newton_n_preinv.c new file mode 100644 index 0000000..f9f2535 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/test/t-divrem_newton_n_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/test/t-divrem_newton_n_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/test/t-evaluate_fq.c b/external/flint-2.4.3/fq_zech_poly/test/t-evaluate_fq.c new file mode 100644 index 0000000..0a47c40 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/test/t-evaluate_fq.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/test/t-evaluate_fq.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/test/t-gcd_euclidean.c b/external/flint-2.4.3/fq_zech_poly/test/t-gcd_euclidean.c new file mode 100644 index 0000000..f83aae1 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/test/t-gcd_euclidean.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/test/t-gcd_euclidean.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/test/t-get_str.c b/external/flint-2.4.3/fq_zech_poly/test/t-get_str.c new file mode 100644 index 0000000..5185772 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/test/t-get_str.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/test/t-get_str.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/test/t-get_str_pretty.c b/external/flint-2.4.3/fq_zech_poly/test/t-get_str_pretty.c new file mode 100644 index 0000000..9652b58 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/test/t-get_str_pretty.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/test/t-get_str_pretty.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/test/t-hamming_weight.c b/external/flint-2.4.3/fq_zech_poly/test/t-hamming_weight.c new file mode 100644 index 0000000..51c31a3 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/test/t-hamming_weight.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/test/t-hamming_weight.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/test/t-inflate.c b/external/flint-2.4.3/fq_zech_poly/test/t-inflate.c new file mode 100644 index 0000000..aa7c66f --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/test/t-inflate.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/test/t-inflate.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/test/t-inv_series_newton.c b/external/flint-2.4.3/fq_zech_poly/test/t-inv_series_newton.c new file mode 100644 index 0000000..e0d6bf6 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/test/t-inv_series_newton.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/test/t-inv_series_newton.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/test/t-make_monic.c b/external/flint-2.4.3/fq_zech_poly/test/t-make_monic.c new file mode 100644 index 0000000..ae6a427 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/test/t-make_monic.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/test/t-make_monic.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/test/t-mul.c b/external/flint-2.4.3/fq_zech_poly/test/t-mul.c new file mode 100644 index 0000000..2c1ee52 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/test/t-mul.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/test/t-mul.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/test/t-mul_KS.c b/external/flint-2.4.3/fq_zech_poly/test/t-mul_KS.c new file mode 100644 index 0000000..4941a6f --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/test/t-mul_KS.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/test/t-mul_KS.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/test/t-mul_classical.c b/external/flint-2.4.3/fq_zech_poly/test/t-mul_classical.c new file mode 100644 index 0000000..0f21eca --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/test/t-mul_classical.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/test/t-mul_classical.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/test/t-mullow.c b/external/flint-2.4.3/fq_zech_poly/test/t-mullow.c new file mode 100644 index 0000000..3081d62 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/test/t-mullow.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/test/t-mullow.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/test/t-mullow_KS.c b/external/flint-2.4.3/fq_zech_poly/test/t-mullow_KS.c new file mode 100644 index 0000000..3de667b --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/test/t-mullow_KS.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/test/t-mullow_KS.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/test/t-mullow_classical.c b/external/flint-2.4.3/fq_zech_poly/test/t-mullow_classical.c new file mode 100644 index 0000000..c07f295 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/test/t-mullow_classical.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/test/t-mullow_classical.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/test/t-mulmod.c b/external/flint-2.4.3/fq_zech_poly/test/t-mulmod.c new file mode 100644 index 0000000..214d5a0 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/test/t-mulmod.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/test/t-mulmod.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/test/t-mulmod_preinv.c b/external/flint-2.4.3/fq_zech_poly/test/t-mulmod_preinv.c new file mode 100644 index 0000000..122425f --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/test/t-mulmod_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/test/t-mulmod_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/test/t-neg.c b/external/flint-2.4.3/fq_zech_poly/test/t-neg.c new file mode 100644 index 0000000..ebc5c4d --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/test/t-neg.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/test/t-neg.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/test/t-pow.c b/external/flint-2.4.3/fq_zech_poly/test/t-pow.c new file mode 100644 index 0000000..e2f4575 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/test/t-pow.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/test/t-pow.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/test/t-powmod_fmpz_binexp.c b/external/flint-2.4.3/fq_zech_poly/test/t-powmod_fmpz_binexp.c new file mode 100644 index 0000000..2fa4d54 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/test/t-powmod_fmpz_binexp.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/test/t-powmod_fmpz_binexp.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/test/t-powmod_fmpz_binexp_preinv.c b/external/flint-2.4.3/fq_zech_poly/test/t-powmod_fmpz_binexp_preinv.c new file mode 100644 index 0000000..f7e2b78 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/test/t-powmod_fmpz_binexp_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/test/t-powmod_fmpz_binexp_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/test/t-powmod_fmpz_sliding_preinv.c b/external/flint-2.4.3/fq_zech_poly/test/t-powmod_fmpz_sliding_preinv.c new file mode 100644 index 0000000..ee662ff --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/test/t-powmod_fmpz_sliding_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/test/t-powmod_fmpz_sliding_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/test/t-powmod_ui_binexp.c b/external/flint-2.4.3/fq_zech_poly/test/t-powmod_ui_binexp.c new file mode 100644 index 0000000..b3d9e7b --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/test/t-powmod_ui_binexp.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/test/t-powmod_ui_binexp.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/test/t-powmod_ui_binexp_preinv.c b/external/flint-2.4.3/fq_zech_poly/test/t-powmod_ui_binexp_preinv.c new file mode 100644 index 0000000..6bb1658 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/test/t-powmod_ui_binexp_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/test/t-powmod_ui_binexp_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/test/t-powmod_x_fmpz_preinv.c b/external/flint-2.4.3/fq_zech_poly/test/t-powmod_x_fmpz_preinv.c new file mode 100644 index 0000000..b3735ca --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/test/t-powmod_x_fmpz_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/test/t-powmod_x_fmpz_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/test/t-randtest_irreducible.c b/external/flint-2.4.3/fq_zech_poly/test/t-randtest_irreducible.c new file mode 100644 index 0000000..47eca99 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/test/t-randtest_irreducible.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/test/t-randtest_irreducible.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/test/t-scalar_addmul_fq.c b/external/flint-2.4.3/fq_zech_poly/test/t-scalar_addmul_fq.c new file mode 100644 index 0000000..88dacc8 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/test/t-scalar_addmul_fq.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/test/t-scalar_addmul_fq.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/test/t-scalar_mul_fq.c b/external/flint-2.4.3/fq_zech_poly/test/t-scalar_mul_fq.c new file mode 100644 index 0000000..de7de1e --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/test/t-scalar_mul_fq.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/test/t-scalar_mul_fq.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/test/t-scalar_submul_fq.c b/external/flint-2.4.3/fq_zech_poly/test/t-scalar_submul_fq.c new file mode 100644 index 0000000..5d13e64 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/test/t-scalar_submul_fq.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/test/t-scalar_submul_fq.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/test/t-shift_left_right.c b/external/flint-2.4.3/fq_zech_poly/test/t-shift_left_right.c new file mode 100644 index 0000000..db94557 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/test/t-shift_left_right.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/test/t-shift_left_right.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/test/t-sqr.c b/external/flint-2.4.3/fq_zech_poly/test/t-sqr.c new file mode 100644 index 0000000..9613f47 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/test/t-sqr.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/test/t-sqr.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/test/t-sqr_KS.c b/external/flint-2.4.3/fq_zech_poly/test/t-sqr_KS.c new file mode 100644 index 0000000..a312872 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/test/t-sqr_KS.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/test/t-sqr_KS.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/test/t-sqr_classical.c b/external/flint-2.4.3/fq_zech_poly/test/t-sqr_classical.c new file mode 100644 index 0000000..0c45c60 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/test/t-sqr_classical.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/test/t-sqr_classical.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/test/t-sub.c b/external/flint-2.4.3/fq_zech_poly/test/t-sub.c new file mode 100644 index 0000000..8c34a6a --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/test/t-sub.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/test/t-sub.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly/truncate.c b/external/flint-2.4.3/fq_zech_poly/truncate.c new file mode 100644 index 0000000..07e0eca --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly/truncate.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_templates/truncate.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly_factor.h b/external/flint-2.4.3/fq_zech_poly_factor.h new file mode 100644 index 0000000..ac881fe --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly_factor.h @@ -0,0 +1,53 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#ifndef FQ_ZECH_POLY_FACTOR_H +#define FQ_ZECH_POLY_FACTOR_H + +static __inline__ int FQ_ZECH_POLY_ITERATED_FROBENIUS_CUTOFF(const fq_zech_ctx_t ctx, slong length) +{ + int result; + fmpz_t q; + fmpz_init(q); + fq_zech_ctx_order(q, ctx); + if ( 2 * fmpz_sizeinbase(q, 2) < 3 * (n_sqrt(length) + 1)) + result = 1; + else + result = 0; + fmpz_clear(q); + return result; +} + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_factor_templates.h" +#undef CAP_T +#undef T + +#endif diff --git a/external/flint-2.4.3/fq_zech_poly_factor/clear.c b/external/flint-2.4.3/fq_zech_poly_factor/clear.c new file mode 100644 index 0000000..bcd8c9a --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly_factor/clear.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_factor_templates/clear.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly_factor/concat.c b/external/flint-2.4.3/fq_zech_poly_factor/concat.c new file mode 100644 index 0000000..2fe5de9 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly_factor/concat.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_factor_templates/concat.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly_factor/doc/fq_zech_poly_factor.txt b/external/flint-2.4.3/fq_zech_poly_factor/doc/fq_zech_poly_factor.txt new file mode 100644 index 0000000..4c2cd5d --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly_factor/doc/fq_zech_poly_factor.txt @@ -0,0 +1,254 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012,2013 Andres Goens + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +******************************************************************************* + + Memory Management + +******************************************************************************* + +void fq_zech_poly_factor_init(fq_zech_poly_factor_t fac, const fq_zech_ctx_t ctx) + + Initialises \code{fac} for use. An \code{fq_zech_poly_factor_t} + represents a polynomial in factorised form as a product of + polynomials with associated exponents. + +void fq_zech_poly_factor_clear(fq_zech_poly_factor_t fac, const fq_zech_ctx_t ctx) + + Frees all memory associated with \code{fac}. + +void fq_zech_poly_factor_realloc(fq_zech_poly_factor_t fac, slong alloc, + const fq_zech_ctx_t ctx) + + Reallocates the factor structure to provide space for + precisely \code{alloc} factors. + +void fq_zech_poly_factor_fit_length(fq_zech_poly_factor_t fac, slong len, + const fq_zech_ctx_t ctx) + + Ensures that the factor structure has space for at least + \code{len} factors. This functions takes care of the case of + repeated calls by always at least doubling the number of factors + the structure can hold. + +******************************************************************************* + + Basic Operations + +******************************************************************************* + +void fq_zech_poly_factor_set(fq_zech_poly_factor_t res, const fq_zech_poly_factor_t fac, + const fq_zech_ctx_t ctx) + + Sets \code{res} to the same factorisation as \code{fac}. + +void fq_zech_poly_factor_print_pretty(const fq_zech_poly_factor_t fac, const fq_zech_ctx_t ctx) + + Pretty-prints the entries of \code{fac} to standard output. + +void fq_zech_poly_factor_print(const fq_zech_poly_factor_t fac, const fq_zech_ctx_t ctx) + + Prints the entries of \code{fac} to standard output. + +void fq_zech_poly_factor_insert(fq_zech_poly_factor_t fac, const fq_zech_poly_t poly, + slong exp, const fq_zech_ctx_t ctx) + + Inserts the factor \code{poly} with multiplicity \code{exp} into + the factorisation \code{fac}. + + If \code{fac} already contains \code{poly}, then \code{exp} simply + gets added to the exponent of the existing entry. + +void fq_zech_poly_factor_concat(fq_zech_poly_factor_t res, const fq_zech_poly_factor_t fac, + const fq_zech_ctx_t ctx) + + Concatenates two factorisations. + + This is equivalent to calling \code{fq_zech_poly_factor_insert()} + repeatedly with the individual factors of \code{fac}. + + Does not support aliasing between \code{res} and \code{fac}. + +void fq_zech_poly_factor_pow(fq_zech_poly_factor_t fac, slong exp, const fq_zech_ctx_t ctx) + + Raises \code{fac} to the power \code{exp}. + +ulong fq_zech_poly_remove(fq_zech_poly_t f, const fq_zech_poly_t p, const fq_zech_ctx_t ctx) + + Removes the highest possible power of \code{p} from \code{f} and + returns the exponent. + +******************************************************************************* + + Irreducibility Testing + +******************************************************************************* + +int fq_zech_poly_is_irreducible(const fq_zech_poly_t f, const fq_zech_ctx_t ctx) + + Returns 1 if the polynomial \code{f} is irreducible, otherwise returns 0. + +int fq_zech_poly_is_irreducible_ddf(const fq_zech_poly_t f, const fq_zech_ctx_t ctx) + + Returns 1 if the polynomial \code{f} is irreducible, otherwise returns 0. + Uses fast distinct-degree factorisation. + +int fq_zech_poly_is_irreducible_ben_or(const fq_zech_poly_t f, const fq_zech_ctx_t ctx) + + Returns 1 if the polynomial \code{f} is irreducible, otherwise returns 0. + Uses Ben-Or's irreducibility test. + +int _fq_zech_poly_is_squarefree(const fq_zech_struct * f, slong len, const fq_zech_ctx_t ctx) + + Returns 1 if \code{(f, len)} is squarefree, and 0 otherwise. As a + special case, the zero polynomial is not considered squarefree. + There are no restrictions on the length. + +int fq_zech_poly_is_squarefree(const fq_zech_poly_t f, const fq_zech_ctx_t ctx) + + Returns 1 if \code{f} is squarefree, and 0 otherwise. As a special + case, the zero polynomial is not considered squarefree. + +******************************************************************************* + + Factorisation + +******************************************************************************* + +int fq_zech_poly_factor_equal_deg_prob(fq_zech_poly_t factor, flint_rand_t state, + const fq_zech_poly_t pol, slong d, + const fq_zech_ctx_t ctx) + + Probabilistic equal degree factorisation of \code{pol} into + irreducible factors of degree \code{d}. If it passes, a factor is + placed in factor and 1 is returned, otherwise 0 is returned and + the value of factor is undetermined. + + Requires that \code{pol} be monic, non-constant and squarefree. + +void fq_zech_poly_factor_equal_deg(fq_zech_poly_factor_t factors, const fq_zech_poly_t pol, + slong d, const fq_zech_ctx_t ctx) + + Assuming \code{pol} is a product of irreducible factors all of + degree \code{d}, finds all those factors and places them in + factors. Requires that \code{pol} be monic, non-constant and + squarefree. + +void fq_zech_poly_factor_distinct_deg(fq_zech_poly_factor_t res, const fq_zech_poly_t poly, + slong * const *degs, const fq_zech_ctx_t ctx) + + Factorises a monic non-constant squarefree polymnomial \code{poly} + of degree n into factors $f[d]$ such that for $1 \leq d \leq n$ + $f[d]$ is the product of the monic irreducible factors of + \code{poly} of degree $d$. Factors are stored in \code{res}, + assotiated powers of irreducible polynomials are stored in + \code{degs} in the same order as factors. + + Requires that \code{degs} have enough space for irreducible polynomials' + powers (maximum space required is $n * sizeof(slong)$). + +void fq_zech_poly_factor_squarefree(fq_zech_poly_factor_t res, const fq_zech_poly_t f, + const fq_zech_ctx_t ctx) + + Sets \code{res} to a squarefree factorization of \code{f}. + +void fq_zech_poly_factor(fq_zech_poly_factor_t res, const fq_zech_poly_t f, const fq_zech_ctx_t ctx) + + Factorises a non-constant polynomial \code{f} into monic + irreducible factors choosing the best algorithm for given modulo + and degree. Choise is based on heuristic measurments. + +void fq_zech_poly_factor_cantor_zassenhaus(fq_zech_poly_factor_t res, const fq_zech_poly_t f, + const fq_zech_ctx_t ctx) + + Factorises a non-constant polynomial \code{f} into monic + irreducible factors using the Cantor-Zassenhaus algorithm. + +void fq_zech_poly_factor_kaltofen_shoup(fq_zech_poly_factor_t res, const fq_zech_poly_t poly, + const fq_zech_ctx_t ctx) + + Factorises a non-constant polynomial \code{f} into monic + irreducible factors using the fast version of Cantor-Zassenhaus + algorithm proposed by Kaltofen and Shoup (1998). More precisely + this algorithm uses a “baby step/giant step†strategy for the + distinct-degree factorization step. + +void fq_zech_poly_factor_berlekamp(fq_zech_poly_factor_t factors, const fq_zech_poly_t f, + const fq_zech_ctx_t ctx) + + Factorises a non-constant polynomial \code{f} into monic + irreducible factors using the Berlekamp algorithm. + +void fq_zech_poly_factor_with_berlekamp(fq_zech_poly_factor_t res, fq_zech_t leading_coeff, + const fq_zech_poly_t f, const fq_zech_ctx_t) + + Factorises a general polynomial \code{f} into monic irreducible + factors and sets \code{leading_coeff} to the leading coefficient + of \code{f}, or 0 if \code{f} is the zero polynomial. + + This function first checks for small special cases, deflates + \code{f} if it is of the form $p(x^m)$ for some $m > 1$, then + performs a square-free factorisation, and finally runs Berlekamp + on all the individual square-free factors. + +void fq_zech_poly_factor_with_cantor_zassenhaus(fq_zech_poly_factor_t res, + fq_zech_t leading_coeff + const fq_zech_poly_t f, + const fq_zech_ctx_t ctx) + + Factorises a general polynomial \code{f} into monic irreducible + factors and sets \code{leading_coeff} to the leading coefficient + of \code{f}, or 0 if \code{f} is the zero polynomial. + + This function first checks for small special cases, deflates + \code{f} if it is of the form $p(x^m)$ for some $m > 1$, then + performs a square-free factorisation, and finally runs + Cantor-Zassenhaus on all the individual square-free factors. + +void fq_zech_poly_factor_with_kaltofen_shoup(fq_zech_poly_factor_t res, + fq_zech_t leading_coeff, + const fq_zech_poly_t f, + const fq_zech_ctx_t ctx) + + Factorises a general polynomial \code{f} into monic irreducible + factors and sets \code{leading_coeff} to the leading coefficient + of \code{f}, or 0 if \code{f} is the zero polynomial. + + This function first checks for small special cases, deflates + \code{f} if it is of the form $p(x^m)$ for some $m > 1$, then + performs a square-free factorisation, and finally runs + Kaltofen-Shoup on all the individual square-free factors. + +void fq_zech_poly_iterated_frobenius_preinv(fq_zech_poly_t *rop, slong n, + const fq_zech_poly_t v, + const fq_zech_poly_t vinv, + const fq_zech_ctx_t ctx) + + Sets \code{rop[i]} to be $x^{q^i} mod v$ for $0 <= i < n$. + + It is required that \code{vinv} is the inverse of the reverse of + \code{v} mod \code{x^lenv}. diff --git a/external/flint-2.4.3/fq_zech_poly_factor/factor.c b/external/flint-2.4.3/fq_zech_poly_factor/factor.c new file mode 100644 index 0000000..b1a8f55 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly_factor/factor.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_factor_templates/factor.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly_factor/factor_berlekamp.c b/external/flint-2.4.3/fq_zech_poly_factor/factor_berlekamp.c new file mode 100644 index 0000000..9bbbdd7 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly_factor/factor_berlekamp.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_factor_templates/factor_berlekamp.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly_factor/factor_cantor_zassenhaus.c b/external/flint-2.4.3/fq_zech_poly_factor/factor_cantor_zassenhaus.c new file mode 100644 index 0000000..543cdb3 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly_factor/factor_cantor_zassenhaus.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_factor_templates/factor_cantor_zassenhaus.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly_factor/factor_distinct_deg.c b/external/flint-2.4.3/fq_zech_poly_factor/factor_distinct_deg.c new file mode 100644 index 0000000..e48edbd --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly_factor/factor_distinct_deg.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_factor_templates/factor_distinct_deg.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly_factor/factor_equal_deg.c b/external/flint-2.4.3/fq_zech_poly_factor/factor_equal_deg.c new file mode 100644 index 0000000..0310c8c --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly_factor/factor_equal_deg.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_factor_templates/factor_equal_deg.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly_factor/factor_equal_deg_prob.c b/external/flint-2.4.3/fq_zech_poly_factor/factor_equal_deg_prob.c new file mode 100644 index 0000000..78ac8ab --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly_factor/factor_equal_deg_prob.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_factor_templates/factor_equal_deg_prob.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly_factor/factor_kaltofen_shoup.c b/external/flint-2.4.3/fq_zech_poly_factor/factor_kaltofen_shoup.c new file mode 100644 index 0000000..db9da93 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly_factor/factor_kaltofen_shoup.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_factor_templates/factor_kaltofen_shoup.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly_factor/factor_squarefree.c b/external/flint-2.4.3/fq_zech_poly_factor/factor_squarefree.c new file mode 100644 index 0000000..4fdb31a --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly_factor/factor_squarefree.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_factor_templates/factor_squarefree.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly_factor/fit_length.c b/external/flint-2.4.3/fq_zech_poly_factor/fit_length.c new file mode 100644 index 0000000..adb4578 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly_factor/fit_length.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_factor_templates/fit_length.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly_factor/init.c b/external/flint-2.4.3/fq_zech_poly_factor/init.c new file mode 100644 index 0000000..659ce0d --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly_factor/init.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_factor_templates/init.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly_factor/insert.c b/external/flint-2.4.3/fq_zech_poly_factor/insert.c new file mode 100644 index 0000000..9cd4cbe --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly_factor/insert.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_factor_templates/insert.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly_factor/is_irreducible.c b/external/flint-2.4.3/fq_zech_poly_factor/is_irreducible.c new file mode 100644 index 0000000..70bbafd --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly_factor/is_irreducible.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_factor_templates/is_irreducible.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly_factor/is_irreducible_ben_or.c b/external/flint-2.4.3/fq_zech_poly_factor/is_irreducible_ben_or.c new file mode 100644 index 0000000..5ed3dd8 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly_factor/is_irreducible_ben_or.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_factor_templates/is_irreducible_ben_or.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly_factor/is_irreducible_ddf.c b/external/flint-2.4.3/fq_zech_poly_factor/is_irreducible_ddf.c new file mode 100644 index 0000000..d410654 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly_factor/is_irreducible_ddf.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_factor_templates/is_irreducible_ddf.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly_factor/is_squarefree.c b/external/flint-2.4.3/fq_zech_poly_factor/is_squarefree.c new file mode 100644 index 0000000..d168a7f --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly_factor/is_squarefree.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_factor_templates/is_squarefree.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly_factor/iterated_frobenius_preinv.c b/external/flint-2.4.3/fq_zech_poly_factor/iterated_frobenius_preinv.c new file mode 100644 index 0000000..aaab001 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly_factor/iterated_frobenius_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_factor_templates/iterated_frobenius_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly_factor/pow.c b/external/flint-2.4.3/fq_zech_poly_factor/pow.c new file mode 100644 index 0000000..ccddcb6 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly_factor/pow.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_factor_templates/pow.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly_factor/print.c b/external/flint-2.4.3/fq_zech_poly_factor/print.c new file mode 100644 index 0000000..b78eb77 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly_factor/print.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_factor_templates/print.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly_factor/print_pretty.c b/external/flint-2.4.3/fq_zech_poly_factor/print_pretty.c new file mode 100644 index 0000000..e244265 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly_factor/print_pretty.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_factor_templates/print_pretty.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly_factor/realloc.c b/external/flint-2.4.3/fq_zech_poly_factor/realloc.c new file mode 100644 index 0000000..e39ed49 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly_factor/realloc.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_factor_templates/realloc.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly_factor/set.c b/external/flint-2.4.3/fq_zech_poly_factor/set.c new file mode 100644 index 0000000..9ae777c --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly_factor/set.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_factor_templates/set.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly_factor/test/t-factor.c b/external/flint-2.4.3/fq_zech_poly_factor/test/t-factor.c new file mode 100644 index 0000000..5a71c6e --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly_factor/test/t-factor.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_factor_templates/test/t-factor.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly_factor/test/t-factor_berlekamp.c b/external/flint-2.4.3/fq_zech_poly_factor/test/t-factor_berlekamp.c new file mode 100644 index 0000000..0a83e4c --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly_factor/test/t-factor_berlekamp.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_factor_templates/test/t-factor_berlekamp.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly_factor/test/t-factor_cantor_zassenhaus.c b/external/flint-2.4.3/fq_zech_poly_factor/test/t-factor_cantor_zassenhaus.c new file mode 100644 index 0000000..bc94a84 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly_factor/test/t-factor_cantor_zassenhaus.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_factor_templates/test/t-factor_cantor_zassenhaus.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly_factor/test/t-factor_distinct_deg.c b/external/flint-2.4.3/fq_zech_poly_factor/test/t-factor_distinct_deg.c new file mode 100644 index 0000000..c6702d4 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly_factor/test/t-factor_distinct_deg.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_factor_templates/test/t-factor_distinct_deg.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly_factor/test/t-factor_equal_deg_prob.c b/external/flint-2.4.3/fq_zech_poly_factor/test/t-factor_equal_deg_prob.c new file mode 100644 index 0000000..a5a97e8 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly_factor/test/t-factor_equal_deg_prob.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_factor_templates/test/t-factor_equal_deg_prob.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly_factor/test/t-factor_kaltofen_shoup.c b/external/flint-2.4.3/fq_zech_poly_factor/test/t-factor_kaltofen_shoup.c new file mode 100644 index 0000000..7ad4fdf --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly_factor/test/t-factor_kaltofen_shoup.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_factor_templates/test/t-factor_kaltofen_shoup.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly_factor/test/t-factor_squarefree.c b/external/flint-2.4.3/fq_zech_poly_factor/test/t-factor_squarefree.c new file mode 100644 index 0000000..ba36db2 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly_factor/test/t-factor_squarefree.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_factor_templates/test/t-factor_squarefree.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly_factor/test/t-is_irreducible.c b/external/flint-2.4.3/fq_zech_poly_factor/test/t-is_irreducible.c new file mode 100644 index 0000000..43c4802 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly_factor/test/t-is_irreducible.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_factor_templates/test/t-is_irreducible.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly_factor/test/t-is_irreducible_ben_or.c b/external/flint-2.4.3/fq_zech_poly_factor/test/t-is_irreducible_ben_or.c new file mode 100644 index 0000000..ba113e3 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly_factor/test/t-is_irreducible_ben_or.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_factor_templates/test/t-is_irreducible_ben_or.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly_factor/test/t-is_irreducible_ddf.c b/external/flint-2.4.3/fq_zech_poly_factor/test/t-is_irreducible_ddf.c new file mode 100644 index 0000000..f4fc70b --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly_factor/test/t-is_irreducible_ddf.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_factor_templates/test/t-is_irreducible_ddf.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly_factor/test/t-is_squarefree.c b/external/flint-2.4.3/fq_zech_poly_factor/test/t-is_squarefree.c new file mode 100644 index 0000000..4a70654 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly_factor/test/t-is_squarefree.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_factor_templates/test/t-is_squarefree.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_poly_factor/test/t-iterated_frobenius_preinv.c b/external/flint-2.4.3/fq_zech_poly_factor/test/t-iterated_frobenius_preinv.c new file mode 100644 index 0000000..b934a2f --- /dev/null +++ b/external/flint-2.4.3/fq_zech_poly_factor/test/t-iterated_frobenius_preinv.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_poly.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_poly_factor_templates/test/t-iterated_frobenius_preinv.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_vec.h b/external/flint-2.4.3/fq_zech_vec.h new file mode 100644 index 0000000..b56a628 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_vec.h @@ -0,0 +1,57 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#ifndef FQ_ZECH_VEC_H +#define FQ_ZECH_VEC_H + +#include "fq_zech.h" + +#define FQ_ZECH_VEC_NORM(vec, i, ctx) \ +do { \ + while ((i) && fq_zech_is_zero((vec) + (i) - 1, ctx)) \ + (i)--; \ +} while (0) + + +#define FQ_ZECH_VEC_SWAP(vec1, len1, vec2, len2) \ +do { \ + fq_zech_struct *__t; \ + slong __tn; \ + __t = (vec1); \ + (vec1) = (vec2); \ + (vec2) = __t; \ + __tn = (len1); \ + (len1) = (len2); \ + (len2) = __tn; \ +} while (0); + + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_vec_templates.h" +#undef CAP_T +#undef T + +#endif diff --git a/external/flint-2.4.3/fq_zech_vec/add.c b/external/flint-2.4.3/fq_zech_vec/add.c new file mode 100644 index 0000000..453c837 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_vec/add.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_vec_templates/add.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_vec/clear.c b/external/flint-2.4.3/fq_zech_vec/clear.c new file mode 100644 index 0000000..dac0d8d --- /dev/null +++ b/external/flint-2.4.3/fq_zech_vec/clear.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_vec_templates/clear.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_vec/doc/fq_zech_vec.txt b/external/flint-2.4.3/fq_zech_vec/doc/fq_zech_vec.txt new file mode 100644 index 0000000..be6b197 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_vec/doc/fq_zech_vec.txt @@ -0,0 +1,168 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +******************************************************************************* + + Memory management + +******************************************************************************* + +fq_zech_struct * _fq_zech_vec_init(slong len, const fq_zech_ctx_t ctx) + + Returns an initialised vector of \code{fq_zech}'s of given length. + +void _fq_zech_vec_clear(fq_zech * vec, slong len, const fq_zech_ctx_t ctx) + + Clears the entries of \code{(vec, len)} and frees the space allocated + for \code{vec}. + +******************************************************************************* + + Randomisation + +******************************************************************************* + +void _fq_zech_vec_randtest(fq_zech_struct * f, flint_rand_t state, + slong len, const fq_zech_ctx_t ctx) + + Sets the entries of a vector of the given length to elements of + the finite field. + +******************************************************************************* + + Input and output + +******************************************************************************* + +int _fq_zech_vec_fprint(FILE * file, const fq_zech_struct * vec, slong len, + const fq_zech_ctx_t ctx) + + Prints the vector of given length to the stream \code{file}. The + format is the length followed by two spaces, then a space separated + list of coefficients. If the length is zero, only $0$ is printed. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + +int _fq_zech_vec_print(const fq_zech_struct * vec, slong len, + const fq_zech_ctx_t ctx) + + Prints the vector of given length to \code{stdout}. + + For further details, see \code{_fq_zech_vec_fprint()}. + +******************************************************************************* + + Assignment and basic manipulation + +******************************************************************************* + +void _fq_zech_vec_set(fq_zech_struct * vec1, const fq_zech_struct * vec2, + slong len2, const fq_zech_ctx_t ctx) + + Makes a copy of \code{(vec2, len2)} into \code{vec1}. + +void _fq_zech_vec_swap(fq_zech_struct * vec1, fq_zech_struct * vec2, slong len2, + const fq_zech_ctx_t ctx) + + Swaps the elements in \code{(vec1, len2)} and \code{(vec2, len2)}. + +void _fq_zech_vec_zero(fq_zech_struct * vec, slong len, const fq_zech_ctx_t ctx) + + Zeros the entries of \code{(vec, len)}. + +void _fq_zech_vec_neg(fq_zech_struct * vec1, const fq_zech_struct * vec2, + slong len2, const fq_zech_ctx_t ctx) + + Negates \code{(vec2, len2)} and places it into \code{vec1}. + +******************************************************************************* + + Comparison + +******************************************************************************* + +int _fq_zech_vec_equal(const fq_zech_struct * vec1, const fq_zech_struct * vec2, + slong len, const fq_zech_ctx_t ctx) + + Compares two vectors of the given length and returns $1$ if they are + equal, otherwise returns $0$. + +int _fq_zech_vec_is_zero(const fq_zech_struct * vec, slong len, const ctx_ctx) + + Returns $1$ if \code{(vec, len)} is zero, and $0$ otherwise. + +******************************************************************************* + + Addition and subtraction + +******************************************************************************* + +void _fq_zech_vec_add(fq_zech_struct * res, const fq_zech_struct * vec1, + const fq_zech_struct * vec2, slong len2, + const fq_zech_ctx_t ctx) + + Sets \code{(res, len2)} to the sum of \code{(vec1, len2)} + and \code{(vec2, len2)}. + +void _fq_zech_vec_sub(fq_zech_struct * res, const fq_zech_struct * vec1, + const fq_zech_struct * vec2, slong len2, + const fq_zech_ctx_t ctx) + + Sets \code{(res, len2)} to \code{(vec1, len2)} minus \code{(vec2, len2)}. + +******************************************************************************* + + Scalar multiplication and division + +******************************************************************************* +void _fq_zech_vec_scalar_addmul_fq_zech(fq_zech_struct * vec1, + const fq_zech_struct * vec2, slong len2, + const fq_zech_t c, + const fq_zech_ctx_t ctx) + + Adds \code{(vec2, len2)} times $c$ to \code{(vec1, len2)}, where + $c$ is a \code{fq_zech_t}. + +void _fq_zech_vec_scalar_submul_fq_zech(fq_zech_struct * vec1, + const fq_zech_struct * vec2, slong len2, + const fq_zech_t c, + const fq_zech_ctx_t ctx) + + Subtracts \code{(vec2, len2)} times $c$ from \code{(vec1, len2)}, + where $c$ is a \code{fq_zech_t}. + +******************************************************************************* + + Dot products + +******************************************************************************* + +void _fq_zech_vec_dot(fq_zech_t res, const fq_zech_struct * vec1, + const fq_zech_struct * vec2, slong len2, + const fq_zech_ctx_t ctx) + + Sets \code{res} to the dot product of (\code{vec1}, \code{len}) + and (\code{vec2}, \code{len}). diff --git a/external/flint-2.4.3/fq_zech_vec/dot.c b/external/flint-2.4.3/fq_zech_vec/dot.c new file mode 100644 index 0000000..8f683cb --- /dev/null +++ b/external/flint-2.4.3/fq_zech_vec/dot.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_vec_templates/dot.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_vec/equal.c b/external/flint-2.4.3/fq_zech_vec/equal.c new file mode 100644 index 0000000..d7458ae --- /dev/null +++ b/external/flint-2.4.3/fq_zech_vec/equal.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_vec_templates/equal.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_vec/fprint.c b/external/flint-2.4.3/fq_zech_vec/fprint.c new file mode 100644 index 0000000..c3a57e7 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_vec/fprint.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_vec_templates/fprint.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_vec/init.c b/external/flint-2.4.3/fq_zech_vec/init.c new file mode 100644 index 0000000..92a8685 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_vec/init.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_vec_templates/init.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_vec/is_zero.c b/external/flint-2.4.3/fq_zech_vec/is_zero.c new file mode 100644 index 0000000..c060f12 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_vec/is_zero.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_vec_templates/is_zero.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_vec/neg.c b/external/flint-2.4.3/fq_zech_vec/neg.c new file mode 100644 index 0000000..786ed82 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_vec/neg.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_vec_templates/neg.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_vec/randtest.c b/external/flint-2.4.3/fq_zech_vec/randtest.c new file mode 100644 index 0000000..b6c5bc2 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_vec/randtest.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_vec_templates/randtest.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_vec/scalar_addmul_fq.c b/external/flint-2.4.3/fq_zech_vec/scalar_addmul_fq.c new file mode 100644 index 0000000..0d49d37 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_vec/scalar_addmul_fq.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_vec_templates/scalar_addmul_fq.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_vec/scalar_submul_fq.c b/external/flint-2.4.3/fq_zech_vec/scalar_submul_fq.c new file mode 100644 index 0000000..f1f7872 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_vec/scalar_submul_fq.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_vec_templates/scalar_submul_fq.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_vec/set.c b/external/flint-2.4.3/fq_zech_vec/set.c new file mode 100644 index 0000000..4a8fcb0 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_vec/set.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_vec_templates/set.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_vec/sub.c b/external/flint-2.4.3/fq_zech_vec/sub.c new file mode 100644 index 0000000..7b6ee00 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_vec/sub.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_vec_templates/sub.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_vec/swap.c b/external/flint-2.4.3/fq_zech_vec/swap.c new file mode 100644 index 0000000..5026624 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_vec/swap.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_vec_templates/swap.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_vec/test/t-add.c b/external/flint-2.4.3/fq_zech_vec/test/t-add.c new file mode 100644 index 0000000..8e47bc0 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_vec/test/t-add.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_vec_templates/test/t-add.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_vec/test/t-is_zero.c b/external/flint-2.4.3/fq_zech_vec/test/t-is_zero.c new file mode 100644 index 0000000..e0a7aa2 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_vec/test/t-is_zero.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_vec_templates/test/t-is_zero.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_vec/test/t-neg.c b/external/flint-2.4.3/fq_zech_vec/test/t-neg.c new file mode 100644 index 0000000..6772531 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_vec/test/t-neg.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_vec_templates/test/t-neg.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_vec/test/t-sub.c b/external/flint-2.4.3/fq_zech_vec/test/t-sub.c new file mode 100644 index 0000000..285ee64 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_vec/test/t-sub.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_vec_templates/test/t-sub.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_vec/test/t-swap.c b/external/flint-2.4.3/fq_zech_vec/test/t-swap.c new file mode 100644 index 0000000..50f577d --- /dev/null +++ b/external/flint-2.4.3/fq_zech_vec/test/t-swap.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_vec_templates/test/t-swap.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_vec/test/t-zero.c b/external/flint-2.4.3/fq_zech_vec/test/t-zero.c new file mode 100644 index 0000000..055eda0 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_vec/test/t-zero.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_vec_templates/test/t-zero.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fq_zech_vec/zero.c b/external/flint-2.4.3/fq_zech_vec/zero.c new file mode 100644 index 0000000..34b90c0 --- /dev/null +++ b/external/flint-2.4.3/fq_zech_vec/zero.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include "fq_zech_vec.h" + +#ifdef T +#undef T +#endif + +#define T fq_zech +#define CAP_T FQ_ZECH +#include "fq_vec_templates/zero.c" +#undef CAP_T +#undef T diff --git a/external/flint-2.4.3/fscanf.c b/external/flint-2.4.3/fscanf.c new file mode 100644 index 0000000..26e4dca --- /dev/null +++ b/external/flint-2.4.3/fscanf.c @@ -0,0 +1,138 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 William Hart + +******************************************************************************/ + +#include +#include +#include +#include +#include +#include "flint.h" + +int flint_fscanf(FILE * f, const char * str, ...) +{ + va_list ap; + size_t len = strlen(str); + char * str2 = flint_malloc(len + 1); + int * w1 = NULL, * w2 = NULL; + void * w3; + double * d; + ulong * wu; + slong * w; + int args, floating; + int ret; + + /* deal with first substring */ + size_t n = strcspn(str, "%"); + strncpy(str2, str, n); + str2[n] = '\0'; + ret = 0; + if (!fread(str2, 1, n, f) && n > 0) + goto cleanup; + len -= n; + str += n; + + va_start(ap, str); + + while (len) /* deal with fmt spec prefixed strings */ + { + n = strcspn(str + 2, "%") + 2; /* be sure to skip a %% */ + strncpy(str2, str, n); + str2[n] = '\0'; + + switch (str[1]) + { + case 'w': + if (str[2] == 'x') + { + wu = (ulong *) va_arg(ap, ulong *); + ret += fscanf(f, WORD_FMT "x", wu); + if (!fread(str2 + 3, 1, n - 3, f) && n > 3) + goto cleanup; + } else if (str[2] == 'u') + { + wu = (ulong *) va_arg(ap, ulong *); + ret += fscanf(f, WORD_FMT "u", wu); + if (!fread(str2 + 3, 1, n - 3, f) && n > 3) + goto cleanup; + } else if (str[2] == 'd') + { + w = (slong *) va_arg(ap, slong *); + ret += fscanf(f, WORD_FMT "d", w); + if (!fread(str2 + 3, 1, n - 3, f) && n > 3) + goto cleanup; + } else + { + w = (slong *) va_arg(ap, slong *); + ret += fscanf(f, WORD_FMT "d", w); + if (!fread(str2 + 2, 1, n - 2, f) && n > 2) + goto cleanup; + } + break; + default: /* pass to printf */ + args = parse_fmt(&floating, str2); + if (args) + { + if (args == 3) + w1 = va_arg(ap, int *); + if (args >= 2) + w2 = va_arg(ap, int *); + if (floating) + { + d = va_arg(ap, double *); + if (args == 2) + ret += fscanf(f, str2, w2, d); + else if (args == 3) + ret += fscanf(f, str2, w1, w2, d); + else + ret += fscanf(f, str2, d); + } else + { + w3 = va_arg(ap, void *); + if (args == 2) + ret += fscanf(f, str2, w2, w3); + else if (args == 3) + ret += fscanf(f, str2, w1, w2, w3); + else + ret += fscanf(f, str2, w3); + } + } else + { + if (!fread(str2, 1, n, f) && n > 0) /* zero args */ + goto cleanup; + } + + } + + len -= n; + str += n; + } + + va_end(ap); + +cleanup: + flint_free(str2); + + return ret; +} diff --git a/external/flint-2.4.3/gmpcompat.h b/external/flint-2.4.3/gmpcompat.h new file mode 100644 index 0000000..538f39e --- /dev/null +++ b/external/flint-2.4.3/gmpcompat.h @@ -0,0 +1,524 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 William Hart + +******************************************************************************/ + +#include +#include +#include + +#ifndef GMP_COMPAT_H +#define GMP_COMPAT_H + +#if defined(__MINGW64__) && !defined(__MPIR_VERSION) + +#define FLINT_MOCK_MPZ_UI(xxx, yyy) \ + __mpz_struct (xxx)[1] = {{ 1, 0, NULL }}; \ + do { \ + (xxx)->_mp_d = (mp_ptr) &(yyy); \ + if ((yyy) > 0) \ + (xxx)->_mp_size = 1; \ + }while (0) + +#define FLINT_MOCK_MPZ_SI(xxx, yyy) \ + __mpz_struct (xxx)[1] = {{ 1, 0, NULL }}; \ + do { \ + (xxx)->_mp_d = (mp_ptr) &(yyy); \ + if ((yyy) < 0) (xxx)->_mp_size = -1, (yyy) = -(yyy); \ + else (xxx)->_mp_size = (yyy) != 0; \ + } while (0) + +#define flint_mpz_get_si(xxx) \ + ((xxx)->_mp_size == 0 ? (slong) WORD(0) : \ + ((xxx)->_mp_size > 0 ? (slong) (xxx)->_mp_d[0] : (slong) -(xxx)->_mp_d[0])) + +#define flint_mpz_get_ui(xxx) \ + ((xxx)->_mp_size == 0 ? WORD(0) : (xxx)->_mp_d[0]) + +static __inline__ +void flint_mpz_set_si(mpz_ptr r, slong s) +{ + if (s < 0) { + r->_mp_size = -1; + r->_mp_d[0] = -s; + } else { + r->_mp_size = s != 0; + r->_mp_d[0] = s; + } +} + +static __inline__ +void flint_mpz_set_ui(mpz_ptr r, ulong u) +{ + r->_mp_d[0] = u; + r->_mp_size = u != 0; +} + +static __inline__ +void flint_mpz_init_set_si(mpz_ptr r, slong s) +{ + r->_mp_d = (mp_ptr) flint_malloc(sizeof(mp_limb_t)); + r->_mp_alloc = 1; + + if (s < 0) { + r->_mp_size = -1; + r->_mp_d[0] = -s; + } else { + r->_mp_size = s != 0; + r->_mp_d[0] = s; + } +} + +static __inline__ +void flint_mpz_init_set_ui(mpz_ptr r, ulong u) +{ + r->_mp_d = (mp_ptr) flint_malloc(sizeof(mp_limb_t)); + r->_mp_alloc = 1; + + r->_mp_d[0] = u; + r->_mp_size = u != 0; +} + +static __inline__ +void flint_mpz_add_ui(mpz_ptr a, mpz_srcptr b, ulong c) +{ + FLINT_MOCK_MPZ_UI(tc, c); + + mpz_add(a, b, tc); +} + +static __inline__ +void flint_mpz_sub_ui(mpz_ptr a, mpz_srcptr b, ulong c) +{ + FLINT_MOCK_MPZ_UI(tc, c); + + mpz_sub(a, b, tc); +} + +static __inline__ +void flint_mpz_mul_ui(mpz_ptr a, mpz_srcptr b, ulong c) +{ + FLINT_MOCK_MPZ_UI(tc, c); + + mpz_mul(a, b, tc); +} + +static __inline__ +void flint_mpz_mul_si(mpz_ptr a, mpz_srcptr b, slong c) +{ + FLINT_MOCK_MPZ_SI(tc, c); + + mpz_mul(a, b, tc); +} + +static __inline__ +void flint_mpz_addmul_ui(mpz_ptr a, mpz_srcptr b, ulong c) +{ + FLINT_MOCK_MPZ_UI(tc, c); + + mpz_addmul(a, b, tc); +} + +static __inline__ +void flint_mpz_submul_ui(mpz_ptr a, mpz_srcptr b, ulong c) +{ + FLINT_MOCK_MPZ_UI(tc, c); + + mpz_submul(a, b, tc); +} + +static __inline__ +void flint_mpz_ui_sub(mpz_ptr a, ulong b, mpz_srcptr c) +{ + FLINT_MOCK_MPZ_UI(tb, b); + + mpz_sub(a, tb, c); +} + +static __inline__ +void flint_mpz_ui_pow_ui(mpz_ptr a, ulong b, ulong c) +{ + FLINT_MOCK_MPZ_UI(tb, b); + + mpz_pow_ui(a, tb, c); +} + +static __inline__ +void flint_mpz_divexact_ui(mpz_ptr a, mpz_srcptr b, ulong c) +{ + FLINT_MOCK_MPZ_UI(tc, c); + + mpz_divexact(a, b, tc); +} + +static __inline__ +int flint_mpz_divisible_ui_p(mpz_srcptr a, ulong c) +{ + FLINT_MOCK_MPZ_UI(tc, c); + + return mpz_divisible_p(a, tc); +} + +static __inline__ +int flint_mpz_congruent_ui_p(mpz_srcptr a, ulong b, ulong c) +{ + FLINT_MOCK_MPZ_UI(tc, c); + { + FLINT_MOCK_MPZ_UI(tb, b); + + return mpz_congruent_p(a, tb, tc); + } +} + +static __inline__ +int flint_mpz_cmp_ui(mpz_srcptr a, ulong c) +{ + FLINT_MOCK_MPZ_UI(tc, c); + + return mpz_cmp(a, tc); +} + +static __inline__ +int flint_mpz_cmp_si(mpz_srcptr a, slong c) +{ + FLINT_MOCK_MPZ_SI(tc, c); + + return mpz_cmp(a, tc); +} + +static __inline__ +int flint_mpq_cmp_si(mpq_srcptr a, slong b, ulong c) +{ + mpq_t tq; + int res; + FLINT_MOCK_MPZ_SI(tb, b); + { + FLINT_MOCK_MPZ_UI(tc, c); + mpq_init(tq); + mpq_set_num(tq, tb); + mpq_set_den(tq, tc); + + res = mpq_cmp(a, tq); + + mpq_clear(tq); + + return res; + } +} + +static __inline__ +int flint_mpq_cmp_ui(mpq_srcptr a, ulong b, ulong c) +{ + mpq_t tq; + int res; + FLINT_MOCK_MPZ_UI(tb, b); + { + FLINT_MOCK_MPZ_UI(tc, c); + mpq_init(tq); + mpq_set_num(tq, tb); + mpq_set_den(tq, tc); + + res = mpq_cmp(a, tq); + + mpq_clear(tq); + + return res; + } +} + +static __inline__ +void flint_mpq_set_si(mpq_ptr a, slong b, ulong c) +{ + FLINT_MOCK_MPZ_SI(tb, b); + { + FLINT_MOCK_MPZ_UI(tc, c); + + mpq_set_num(a, tb); + mpq_set_den(a, tc); + } +} + +static __inline__ +void flint_mpq_set_ui(mpq_ptr a, ulong b, ulong c) +{ + FLINT_MOCK_MPZ_UI(tb, b); + { + FLINT_MOCK_MPZ_UI(tc, c); + + mpq_set_num(a, tb); + mpq_set_den(a, tc); + } +} + +static __inline__ +void flint_mpz_cdiv_q_ui(mpz_ptr q, mpz_srcptr n, ulong c) +{ + FLINT_MOCK_MPZ_UI(tc, c); + + mpz_cdiv_q(q, n, tc); +} + +static __inline__ +void flint_mpz_fdiv_q_ui(mpz_ptr q, mpz_srcptr n, ulong c) +{ + FLINT_MOCK_MPZ_UI(tc, c); + + mpz_fdiv_q(q, n, tc); +} + +static __inline__ +void flint_mpz_tdiv_q_ui(mpz_ptr q, mpz_srcptr n, ulong c) +{ + FLINT_MOCK_MPZ_UI(tc, c); + + mpz_tdiv_q(q, n, tc); +} + +static __inline__ +ulong flint_mpz_cdiv_r_ui(mpz_ptr r, mpz_srcptr n, ulong c) +{ + FLINT_MOCK_MPZ_UI(tc, c); + + mpz_cdiv_r(r, n, tc); + + return flint_mpz_get_ui(r); +} + +static __inline__ +ulong flint_mpz_fdiv_r_ui(mpz_ptr r, mpz_srcptr n, ulong c) +{ + FLINT_MOCK_MPZ_UI(tc, c); + + mpz_fdiv_r(r, n, tc); + + return flint_mpz_get_ui(r); +} + +static __inline__ +ulong flint_mpz_tdiv_r_ui(mpz_ptr r, mpz_srcptr n, ulong c) +{ + FLINT_MOCK_MPZ_UI(tc, c); + + mpz_tdiv_r(r, n, tc); + + return flint_mpz_get_ui(r); +} + +static __inline__ +ulong flint_mpz_cdiv_qr_ui(mpz_ptr q, mpz_ptr r, mpz_srcptr n, ulong c) +{ + FLINT_MOCK_MPZ_UI(tc, c); + + mpz_cdiv_qr(q, r, n, tc); + + return flint_mpz_get_ui(r); +} + +static __inline__ +ulong flint_mpz_fdiv_qr_ui(mpz_ptr q, mpz_ptr r, mpz_srcptr n, ulong c) +{ + FLINT_MOCK_MPZ_UI(tc, c); + + mpz_fdiv_qr(q, r, n, tc); + + return flint_mpz_get_ui(r); +} + +static __inline__ +ulong flint_mpz_tdiv_qr_ui(mpz_ptr q, mpz_ptr r, mpz_srcptr n, ulong c) +{ + FLINT_MOCK_MPZ_UI(tc, c); + + mpz_tdiv_qr(q, r, n, tc); + + return flint_mpz_get_ui(r); +} + +static __inline__ +ulong flint_mpz_cdiv_ui(mpz_srcptr n, ulong c) +{ + mpz_t r; + ulong res; + + mpz_init(r); + FLINT_MOCK_MPZ_UI(tc, c); + + mpz_cdiv_r(r, n, tc); + + res = flint_mpz_get_ui(r); + + mpz_clear(r); + + return res; +} + +static __inline__ +ulong flint_mpz_fdiv_ui(mpz_srcptr n, ulong c) +{ + mpz_t r; + ulong res; + + mpz_init(r); + FLINT_MOCK_MPZ_UI(tc, c); + + mpz_fdiv_r(r, n, tc); + + res = flint_mpz_get_ui(r); + + mpz_clear(r); + + return res; +} + +static __inline__ +ulong flint_mpz_tdiv_ui(mpz_srcptr n, ulong c) +{ + mpz_t r; + ulong res; + + mpz_init(r); + FLINT_MOCK_MPZ_UI(tc, c); + + mpz_tdiv_r(r, n, tc); + + res = flint_mpz_get_ui(r); + + mpz_clear(r); + + return res; +} + +static __inline__ +ulong flint_mpz_mod_ui(mpz_ptr r, mpz_srcptr n, ulong c) +{ + FLINT_MOCK_MPZ_UI(tc, c); + + mpz_fdiv_r(r, n, tc); + + return flint_mpz_get_ui(r); +} + +static __inline__ +void flint_mpz_powm_ui(mpz_ptr r, mpz_srcptr b, ulong exp, mpz_srcptr mod) +{ + FLINT_MOCK_MPZ_UI(texp, exp); + + mpz_powm(r, b, texp, mod); +} + +static __inline__ +void flint_mpz_pow_ui(mpz_ptr r, mpz_srcptr b, ulong exp) +{ + if (exp >= (UWORD(1) << 32)) { + printf("Exception (flint_mpz_pow_ui). Power too large.\n"); + abort(); + } + + mpz_pow_ui(r, b, (unsigned long) exp); +} + +static __inline__ +void flint_mpz_fac_ui(mpz_ptr r, ulong n) +{ + if (n >= (UWORD(1) << 32)) { + printf("Exception (flint_mpz_fac_ui). Value n too large.\n"); + abort(); + } + + mpz_fac_ui(r, (unsigned long) n); +} + +static __inline__ +void flint_mpz_bin_uiui(mpz_ptr r, ulong n, ulong k) +{ + if (n >= (UWORD(1) << 32)) { + printf("Exception (flint_mpz_bin_uiui). Value n too large.\n"); + abort(); + } + + if (k >= (UWORD(1) << 32)) { + printf("Exception (flint_mpz_bin_uiui). Value k too large.\n"); + abort(); + } + + mpz_bin_uiui(r, (unsigned long) n, (unsigned long) k); +} + +static __inline__ +void flint_mpz_fib_ui(mpz_ptr r, ulong n) +{ + if (n >= (UWORD(1) << 32)) { + printf("Exception (flint_mpz_fib_ui). Value n too large.\n"); + abort(); + } + + mpz_fib_ui(r, (unsigned long) n); +} + +#else + +#define flint_mpz_get_si mpz_get_si +#define flint_mpz_get_ui mpz_get_ui +#define flint_mpz_set_si mpz_set_si +#define flint_mpz_set_ui mpz_set_ui +#define flint_mpz_init_set_si mpz_init_set_si +#define flint_mpz_init_set_ui mpz_init_set_ui +#define flint_mpz_add_ui mpz_add_ui +#define flint_mpz_sub_ui mpz_sub_ui +#define flint_mpz_mul_si mpz_mul_si +#define flint_mpz_mul_ui mpz_mul_ui +#define flint_mpz_addmul_ui mpz_addmul_ui +#define flint_mpz_submul_ui mpz_submul_ui +#define flint_mpz_ui_sub mpz_ui_sub +#define flint_mpz_ui_pow_ui mpz_ui_pow_ui +#define flint_mpz_cdiv_q_ui mpz_cdiv_q_ui +#define flint_mpz_cdiv_r_ui mpz_cdiv_r_ui +#define flint_mpz_cdiv_qr_ui mpz_cdiv_qr_ui +#define flint_mpz_cdiv_ui mpz_cdiv_ui +#define flint_mpz_fdiv_q_ui mpz_fdiv_q_ui +#define flint_mpz_fdiv_r_ui mpz_fdiv_r_ui +#define flint_mpz_fdiv_qr_ui mpz_fdiv_qr_ui +#define flint_mpz_fdiv_ui mpz_fdiv_ui +#define flint_mpz_tdiv_q_ui mpz_tdiv_q_ui +#define flint_mpz_tdiv_r_ui mpz_tdiv_r_ui +#define flint_mpz_tdiv_qr_ui mpz_tdiv_qr_ui +#define flint_mpz_tdiv_ui mpz_tdiv_ui +#define flint_mpz_mod_ui mpz_mod_ui +#define flint_mpz_divexact_ui mpz_divexact_ui +#define flint_mpz_divisible_ui_p mpz_divisible_ui_p +#define flint_mpz_congruent_ui_p mpz_congruent_ui_p +#define flint_mpz_powm_ui mpz_powm_ui +#define flint_mpz_pow_ui mpz_pow_ui +#define flint_mpz_fac_ui mpz_fac_ui +#define flint_mpz_bin_uiui mpz_bin_uiui +#define flint_mpz_fib_ui mpz_fib_ui +#define flint_mpz_cmp_si mpz_cmp_si +#define flint_mpz_cmp_ui mpz_cmp_ui +#define flint_mpq_cmp_si mpq_cmp_si +#define flint_mpq_cmp_ui mpq_cmp_ui +#define flint_mpq_set_si mpq_set_si +#define flint_mpq_set_ui mpq_set_ui + +#endif + +#endif diff --git a/external/flint-2.4.3/gpl-2.0.txt b/external/flint-2.4.3/gpl-2.0.txt new file mode 100644 index 0000000..98d3737 --- /dev/null +++ b/external/flint-2.4.3/gpl-2.0.txt @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated provided such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program 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. + + This program 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 this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/external/flint-2.4.3/interfaces/NTL-interface.cpp b/external/flint-2.4.3/interfaces/NTL-interface.cpp new file mode 100644 index 0000000..c95ca3c --- /dev/null +++ b/external/flint-2.4.3/interfaces/NTL-interface.cpp @@ -0,0 +1,468 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + NTL-interface.cpp: Functions for conversion between NTL and FLINT format + + Copyright (C) 2007 William Hart + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "NTL-interface.h" + +#define ZZ_SIZE(p) (((slong *) (p))[1]) +#define ZZ_DATA(p) ((mp_limb_t *) (((slong *) (p)) + 2)) + +NTL_CLIENT + +static void fmpz_set_limbs(fmpz_t f, mp_srcptr x, mp_size_t limbs) +{ + if (limbs == 0) + fmpz_zero(f); + else if (limbs == 1) + fmpz_set_ui(f, x[0]); + else + { + __mpz_struct *mpz_ptr = _fmpz_promote(f); + + mpz_import(mpz_ptr, limbs, -1, sizeof(mp_limb_t), 0, 0, x); + } +} + +void fmpz_set_ZZ(fmpz_t rop, const ZZ& op) +{ + const _ntl_gbigint x = op.rep; + + if (!x) + fmpz_zero(rop); + else + { + const mp_size_t lw = op.size(); + const mp_limb_t *xp = ZZ_DATA(x); + + fmpz_set_limbs(rop, xp, lw); + + if (op < WORD(0)) + fmpz_neg(rop, rop); + } +} + +void fmpz_set_ZZ_p(fmpz_t rop, const ZZ_p& op) +{ + fmpz_set_ZZ(rop, rep(op)); +} + +void fmpz_set_zz_p(fmpz_t rop, const zz_p& op) +{ + fmpz_set_si(rop, rep(op)); +} + +void fmpz_get_ZZ(ZZ& rop, const fmpz_t op) +{ + mp_limb_t *xp; + _ntl_gbigint *x = &rop.rep; + slong lw = fmpz_size(op); + fmpz c = *op; + + if (lw == 0) + { + if (*x) ZZ_SIZE(*x) = 0; + return; + } + + _ntl_gsetlength(x, lw); + xp = ZZ_DATA(*x); + + if (COEFF_IS_MPZ(c)) + { + __mpz_struct * m = COEFF_TO_PTR(c); + mpn_copyi(xp, m->_mp_d, lw); + } else + { + if (c < WORD(0)) + xp[0] = -c; + else + xp[0] = c; + } + + if (fmpz_sgn(op) < 0) ZZ_SIZE(*x) = -lw; + else ZZ_SIZE(*x) = lw; +} + +void fmpz_get_ZZ_p(ZZ_p& rop, const fmpz_t op) +{ + ZZ a; + fmpz_get_ZZ(a, op); + conv(rop, a); +} + +void fmpz_get_zz_p(zz_p& rop, const fmpz_t op) +{ + conv(rop, fmpz_get_si(op)); +} + +void fmpz_poly_get_ZZX(ZZX& rop, const fmpz_poly_t op) +{ + const slong len = op->length; + + if (len == 0) + { + rop = 0; + } + else + { + slong i; + ZZ *ap; + + rop.rep.SetLength(len); + + for (i = 0, ap = rop.rep.elts(); i < len; i++, ap++) + { + fmpz_get_ZZ(*ap, op->coeffs + i); + } + } +} + +void fmpz_poly_set_ZZX(fmpz_poly_t rop, const ZZX& op) +{ + const slong len = deg(op) + 1; + + if (len == 0) + { + fmpz_poly_zero(rop); + } + else + { + slong i; + const ZZ *ap; + + fmpz_poly_fit_length(rop, len); + _fmpz_poly_set_length(rop, len); + + for (i = 0, ap = op.rep.elts(); i < len; i++, ap++) + { + fmpz_set_ZZ(rop->coeffs + i, *ap); + } + } +} + + +void fmpz_mod_poly_get_ZZ_pX(ZZ_pX& rop, const fmpz_mod_poly_t op) +{ + const slong len = op->length; + + if (len == 0) + { + rop = 0; + } + else + { + slong i; + ZZ_p *ap; + + rop.rep.SetLength(len); + + for (i = 0, ap = rop.rep.elts(); i < len; i++, ap++) + { + fmpz_get_ZZ_p(*ap, op->coeffs + i); + } + } +} + +void fmpz_mod_poly_set_ZZ_pX(fmpz_mod_poly_t rop, const ZZ_pX& op) +{ + const slong len = deg(op) + 1; + + if (len == 0) + { + fmpz_mod_poly_zero(rop); + } + else + { + slong i; + const ZZ_p *ap; + + fmpz_mod_poly_fit_length(rop, len); + _fmpz_mod_poly_set_length(rop, len); + + for (i = 0, ap = op.rep.elts(); i < len; i++, ap++) + { + fmpz_set_ZZ_p(rop->coeffs + i, *ap); + } + } +} + +void fmpz_mod_poly_get_zz_pX(zz_pX& rop, const fmpz_mod_poly_t op) +{ + const slong len = op->length; + + if (len == 0) + { + rop = 0; + } + else + { + slong i; + zz_p *ap; + + rop.rep.SetLength(len); + + for (i = 0, ap = rop.rep.elts(); i < len; i++, ap++) + { + fmpz_get_zz_p(*ap, op->coeffs + i); + } + } +} + +void fmpz_mod_poly_set_zz_pX(fmpz_mod_poly_t rop, const zz_pX& op) +{ + const slong len = deg(op) + 1; + + if (len == 0) + { + fmpz_mod_poly_zero(rop); + } + else + { + slong i; + const zz_p *ap; + + fmpz_mod_poly_fit_length(rop, len); + _fmpz_mod_poly_set_length(rop, len); + + for (i = 0, ap = op.rep.elts(); i < len; i++, ap++) + { + fmpz_set_zz_p(rop->coeffs + i, *ap); + } + } +} + +void fq_get_ZZ_pE(ZZ_pE& rop, const fq_t op, const fq_ctx_t ctx) +{ + ZZ_pX p; + + const slong len = op->length; + + if (len == 0) + { + rop = 0; + } + else + { + slong i; + ZZ_p *ap; + + p.rep.SetLength(len); + + for (i = 0, ap = p.rep.elts(); i < len; i++, ap++) + { + fmpz_get_ZZ_p(*ap, op->coeffs + i); + } + conv(rop, p); + } +} + +void fq_set_ZZ_pE(fq_t rop, const ZZ_pE& op, const fq_ctx_t ctx) +{ + const slong len = deg(rep(op)) + 1; + + if (len == 0) + { + fq_zero(rop, ctx); + } + else + { + slong i; + const ZZ_p *ap; + + fmpz_poly_fit_length(rop, len); + _fmpz_poly_set_length(rop, len); + + for (i = 0, ap = rep(op).rep.elts(); i < len; i++, ap++) + { + fmpz_set_ZZ_p(rop->coeffs + i, *ap); + } + _fmpz_poly_normalise(rop); + } +} + + +void fq_poly_get_ZZ_pEX(ZZ_pEX& rop, const fq_poly_t op, const fq_ctx_t ctx) +{ + const slong len = op->length; + + if (len == 0) + { + rop = 0; + } + else + { + slong i; + ZZ_pE *ap; + + rop.rep.SetLength(len); + + for (i = 0, ap = rop.rep.elts(); i < len; i++, ap++) + { + fq_get_ZZ_pE(*ap, op->coeffs + i, ctx); + } + } +} + +void fq_poly_set_ZZ_pEX(fq_poly_t rop, const ZZ_pEX& op, const fq_ctx_t ctx) +{ + const slong len = deg(op) + 1; + + if (len == 0) + { + fq_poly_zero(rop, ctx); + } + else + { + slong i; + const ZZ_pE *ap; + + fq_poly_fit_length(rop, len, ctx); + _fq_poly_set_length(rop, len, ctx); + + for (i = 0, ap = op.rep.elts(); i < len; i++, ap++) + { + fq_set_ZZ_pE(rop->coeffs + i, *ap, ctx); + } + _fq_poly_normalise(rop, ctx); + } +} + +/* ----------------------------------------- */ +void fq_get_zz_pE(zz_pE& rop, const fq_t op, const fq_ctx_t ctx) +{ + zz_pX p; + + const slong len = op->length; + + if (len == 0) + { + rop = 0; + } + else + { + slong i; + zz_p *ap; + + p.rep.SetLength(len); + + for (i = 0, ap = p.rep.elts(); i < len; i++, ap++) + { + fmpz_get_zz_p(*ap, op->coeffs + i); + } + conv(rop, p); + } +} + +void fq_set_zz_pE(fq_t rop, const zz_pE& op, const fq_ctx_t ctx) +{ + const slong len = deg(rep(op)) + 1; + + if (len == 0) + { + fq_zero(rop, ctx); + } + else + { + slong i; + const zz_p *ap; + + fmpz_poly_fit_length(rop, len); + _fmpz_poly_set_length(rop, len); + + for (i = 0, ap = rep(op).rep.elts(); i < len; i++, ap++) + { + fmpz_set_zz_p(rop->coeffs + i, *ap); + } + _fmpz_poly_normalise(rop); + } +} + + +void fq_poly_get_zz_pEX(zz_pEX& rop, const fq_poly_t op, const fq_ctx_t ctx) +{ + const slong len = op->length; + + if (len == 0) + { + rop = 0; + } + else + { + slong i; + zz_pE *ap; + + rop.rep.SetLength(len); + + for (i = 0, ap = rop.rep.elts(); i < len; i++, ap++) + { + fq_get_zz_pE(*ap, op->coeffs + i, ctx); + } + } +} + +void fq_poly_set_zz_pEX(fq_poly_t rop, const zz_pEX& op, const fq_ctx_t ctx) +{ + const slong len = deg(op) + 1; + + if (len == 0) + { + fq_poly_zero(rop, ctx); + } + else + { + slong i; + const zz_pE *ap; + + fq_poly_fit_length(rop, len, ctx); + _fq_poly_set_length(rop, len, ctx); + + for (i = 0, ap = op.rep.elts(); i < len; i++, ap++) + { + fq_set_zz_pE(rop->coeffs + i, *ap, ctx); + } + _fq_poly_normalise(rop, ctx); + } +} + + +#undef ZZ_SIZE +#undef ZZ_DATA + diff --git a/external/flint-2.4.3/interfaces/doc/interfaces.txt b/external/flint-2.4.3/interfaces/doc/interfaces.txt new file mode 100644 index 0000000..3232f5c --- /dev/null +++ b/external/flint-2.4.3/interfaces/doc/interfaces.txt @@ -0,0 +1,117 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +******************************************************************************* + + NTL Interface + + The NTL interface allows conversion between NTL objects and FLINT objects + and vice versa. The interface is built using C$++$ and is not built as a + part of the FLINT library library by default. To build the NTL interface + one must specify the location of NTL with the \code{--with-ntl=path} option + to configure. NTL version 5.5.2 or later is required. + +******************************************************************************* + +void fmpz_set_ZZ(fmpz_t rop, const ZZ& op) + + Converts an NTL \code{ZZ} to an \code{fmpz_t}. + + Assumes the \code{fmpz_t} has already been allocated to have + sufficient space. + +void fmpz_get_ZZ(ZZ& rop, const fmpz_t op) + + Converts an \code{fmpz_t} to an NTL \code{ZZ}. Allocation is + automatically handled. + +void fmpz_set_ZZ_p(fmpz_t rop, const ZZ_p& op) + + Converts an NTL \code{ZZ_p} to an \code{fmpz_t}. + + Assumes the \code{fmpz_t} has already been allocated to have + sufficient space. + +void fmpz_get_ZZ_p(ZZ_p& rop, const fmpz_t op) + + Converts an \code{fmpz_t} to an NTL \code{ZZ_p}. Allocation is + automatically handled. Requires that \code{ZZ_p::init()} has + already been called. + +void fmpz_poly_get_ZZX(ZZX& rop, const fmpz_poly_t op) + + Converts an \code{fmpz_poly_t} to an NTL \code{ZZX}. + +void fmpz_poly_set_ZZX(fmpz_poly_t rop, const ZZX& op) + + Converts an NTL \code{ZZX} to an \code{fmpz_poly_t}. + +void fmpz_mod_poly_get_ZZ_pX(ZZ_pX& rop, const fmpz_mod_poly_t op) + + Converts an \code{fmpz_mod_poly_t} to an NTL + \code{ZZ_pX}. Requires that \code{ZZ_p::init()} has already been + called. + +void fmpz_mod_poly_set_ZZ_pX(fmpz_mod_poly_t rop, const ZZ_pX& op) + + Converts an NTL \code{ZZ_pX} to an \code{fmpz_mod_poly_t}. + +void fq_get_ZZ_pE(ZZ_pE& rop, const fq_t op, const fq_ctx_t ctx) + + Converts an \code{fq_t} to an NTL \code{ZZ_pE}. Requires that + \code{ZZ_pE::init()} has already been called. + +void fq_set_ZZ_pE(fq_t rop, const ZZ_pE& op, const fq_ctx_t ctx) + + Converts and NTL \code{ZZ_pE} to an \code{fq_t}. + +void fq_poly_get_ZZ_pEX(ZZ_pEX& rop, const fq_poly_t op, const fq_ctx_t ctx) + + Converts an \code{fq_poly_t} to an NTL \code{ZZ_pEX}. Requires + that \code{ZZ_pE::init()} has already been called. + +void fq_poly_set_ZZ_pE(fq_poly_t rop, const ZZ_pE& op, const fq_ctx_t ctx) + + Converts and NTL \code{ZZ_pEX} to an \code{fq_poly_t}. + +void fq_get_zz_pE(zz_pE& rop, const fq_t op, const fq_ctx_t ctx) + + Converts an \code{fq_t} to an NTL \code{zz_pE}. Requires that + \code{zz_pE::init()} has already been called. + +void fq_set_zz_pE(fq_t rop, const zz_pE& op, const fq_ctx_t ctx) + + Converts and NTL \code{zz_pE} to an \code{fq_t}. + +void fq_poly_get_zz_pEX(zz_pEX& rop, const fq_poly_t op, const fq_ctx_t ctx) + + Converts an \code{fq_poly_t} to an NTL \code{zz_pEX}. Requires + that \code{zz_pE::init()} has already been called. + +void fq_poly_set_zz_pE(fq_poly_t rop, const zz_pE& op, const fq_ctx_t ctx) + + Converts and NTL \code{zz_pEX} to an \code{fq_poly_t}. diff --git a/external/flint-2.4.3/interfaces/test/t-NTL-interface.cpp b/external/flint-2.4.3/interfaces/test/t-NTL-interface.cpp new file mode 100644 index 0000000..1beffc3 --- /dev/null +++ b/external/flint-2.4.3/interfaces/test/t-NTL-interface.cpp @@ -0,0 +1,547 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2013 Mike Hansen + +******************************************************************************/ + +#include +#include + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" +#include "NTL-interface.h" + +NTL_CLIENT + +int test_ZZ_to_fmpz() +{ + int i, result; + mp_bitcnt_t bits, randbits; + fmpz_t int1, int2; + + ZZ z; + FLINT_TEST_INIT(state); + + flint_printf("ZZ_to_fmpz...."); + fflush(stdout); + + + + /* Check conversion */ + for (i = 0; i < 10000; i++) + { + bits = n_randint(state, 1000) + 1; + randbits = n_randint(state, bits); + + fmpz_init(int1); + fmpz_init(int2); + + fmpz_randbits(int1, state, randbits); + + fmpz_get_ZZ(z, int1); + fmpz_set_ZZ(int2, z); + + result = fmpz_equal(int1, int2); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("int1 = %wd ", *int1); fmpz_print(int1); flint_printf("\n"); + flint_printf("int2 = %wd ", *int2); fmpz_print(int2); flint_printf("\n"); + return 0; + } + + fmpz_clear(int1); + fmpz_clear(int2); + } + + FLINT_TEST_CLEANUP(state); + + return 1; +} + +int test_ZZX_to_fmpz_poly() +{ + fmpz_poly_t f_poly1, f_poly2; + slong length; + mp_bitcnt_t bits; + int i, result; + + FLINT_TEST_INIT(state); + + flint_printf("ZZX_to_fmpz_poly...."); + fflush(stdout); + + + + /* Check aliasing of a and c */ + for (i = 0; i < 10000; i++) + { + bits = n_randint(state, 1000) + 1; + length = n_randint(state, 1000); + + fmpz_poly_init(f_poly1); + fmpz_poly_init(f_poly2); + + ZZX ZZX_poly; + + fmpz_poly_randtest(f_poly1, state, length, bits); + + fmpz_poly_get_ZZX(ZZX_poly, f_poly1); + fmpz_poly_set_ZZX(f_poly2, ZZX_poly); + + result = fmpz_poly_equal(f_poly1, f_poly2); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("f_poly1 = "); fmpz_poly_print(f_poly1); flint_printf("\n"); + flint_printf("f_poly2 = "); fmpz_poly_print(f_poly2); flint_printf("\n"); + return 0; + } + + fmpz_poly_clear(f_poly1); + fmpz_poly_clear(f_poly2); + } + + FLINT_TEST_CLEANUP(state); + + return 1; +} + +int test_ZZ_pX_to_fmpz_mod_poly() +{ + fmpz_t p; + fmpz_mod_poly_t f_poly1, f_poly2; + slong length; + int i, result; + + FLINT_TEST_INIT(state); + + flint_printf("ZZ_pX_to_fmpz_mod_poly...."); + fflush(stdout); + + /* Check aliasing of a and c */ + for (i = 0; i < 10000; i++) + { + ZZ_pX ZZ_pX_poly; + ZZ mod; + + length = n_randint(state, 1000); + + fmpz_init(p); + fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); + fmpz_add_ui(p, p, 2); + + fmpz_get_ZZ(mod, p); + ZZ_p::init(mod); + + fmpz_mod_poly_init(f_poly1, p); + fmpz_mod_poly_init(f_poly2, p); + + fmpz_mod_poly_randtest(f_poly1, state, length); + + fmpz_mod_poly_get_ZZ_pX(ZZ_pX_poly, f_poly1); + fmpz_mod_poly_set_ZZ_pX(f_poly2, ZZ_pX_poly); + + result = fmpz_mod_poly_equal(f_poly1, f_poly2); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("f_poly1 = "); fmpz_mod_poly_print(f_poly1); flint_printf("\n"); + flint_printf("f_poly2 = "); fmpz_mod_poly_print(f_poly2); flint_printf("\n"); + return 0; + } + + fmpz_clear(p); + fmpz_mod_poly_clear(f_poly1); + fmpz_mod_poly_clear(f_poly2); + } + + FLINT_TEST_CLEANUP(state); + + return 1; +} + +int test_zz_pX_to_fmpz_mod_poly() +{ + fmpz_t p; + fmpz_mod_poly_t f_poly1, f_poly2; + slong length; + int i, result; + + FLINT_TEST_INIT(state); + + flint_printf("zz_pX_to_fmpz_mod_poly...."); + fflush(stdout); + + /* Check aliasing of a and c */ + for (i = 0; i < 10000; i++) + { + zz_pX zz_pX_poly; + + length = n_randint(state, 1000); + + fmpz_init(p); + fmpz_set_ui(p, n_randprime(state, 16, 1)); + + zz_p::init(fmpz_get_si(p)); + + fmpz_mod_poly_init(f_poly1, p); + fmpz_mod_poly_init(f_poly2, p); + + fmpz_mod_poly_randtest(f_poly1, state, length); + + fmpz_mod_poly_get_zz_pX(zz_pX_poly, f_poly1); + fmpz_mod_poly_set_zz_pX(f_poly2, zz_pX_poly); + + result = fmpz_mod_poly_equal(f_poly1, f_poly2); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("f_poly1 = "); fmpz_mod_poly_print(f_poly1); flint_printf("\n"); + flint_printf("f_poly2 = "); fmpz_mod_poly_print(f_poly2); flint_printf("\n"); + return 0; + } + + fmpz_clear(p); + fmpz_mod_poly_clear(f_poly1); + fmpz_mod_poly_clear(f_poly2); + } + + FLINT_TEST_CLEANUP(state); + + return 1; +} + +int test_ZZ_pE_to_fq() +{ + fmpz_t p; + fq_t f1, f2; + int i, result; + + fq_ctx_t ctx; + + FLINT_TEST_INIT(state); + + flint_printf("ZZ_pE_to_fq...."); + fflush(stdout); + + /* Check aliasing of a and c */ + for (i = 0; i < 10000; i++) + { + fmpz_mod_poly_t fmod; + slong d; + ZZ prime; + ZZ_pX mod; + + fmpz_init(p); + fmpz_set_ui(p, n_randprime(state, 2 + n_randint(state, 6), 1)); + + d = n_randint(state, 10) + 1; + + fmpz_get_ZZ(prime, p); + ZZ_p::init(prime); + + BuildIrred(mod, d); + ZZ_pE::init(mod); + + fmpz_mod_poly_init(fmod, p); + fmpz_mod_poly_set_ZZ_pX(fmod, mod); + + fq_ctx_init_modulus(ctx, fmod, "a"); + + ZZ_pE zzpe; + + fq_init(f1, ctx); + fq_init(f2, ctx); + + fq_randtest(f1, state, ctx); + + fq_get_ZZ_pE(zzpe, f1, ctx); + fq_set_ZZ_pE(f2, zzpe, ctx); + + result = fq_equal(f1, f2, ctx); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("p = "); fmpz_print(p); flint_printf("\n"); + flint_printf("mod = "); fmpz_mod_poly_print_pretty(fmod, "x"); flint_printf("\n"); + flint_printf("f1 = "); fq_print_pretty(f1, ctx); flint_printf(" - %wd", f1->length); flint_printf("\n"); + flint_printf("zzpe:"); cout << zzpe; flint_printf("\n"); + flint_printf("f2 = "); fq_print_pretty(f2, ctx); flint_printf(" - %wd", f2->length); flint_printf("\n"); + return 0; + } + + fmpz_clear(p); + fq_clear(f1, ctx); + fq_clear(f2, ctx); + + fmpz_mod_poly_clear(fmod); + fq_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + return 1; +} + +int test_ZZ_pEX_to_fq_poly() +{ + fmpz_t p; + fq_poly_t f1, f2; + slong length; + int i, result; + + fq_ctx_t ctx; + + FLINT_TEST_INIT(state); + + flint_printf("ZZ_pEX_to_fq_poly...."); + fflush(stdout); + + for (i = 0; i < 10000; i++) + { + fmpz_mod_poly_t fmod; + slong d; + ZZ prime; + ZZ_pX mod; + + fmpz_init(p); + fmpz_set_ui(p, n_randprime(state, 2 + n_randint(state, 6), 1)); + + d = n_randint(state, 10) + 1; + + fmpz_get_ZZ(prime, p); + ZZ_p::init(prime); + + BuildIrred(mod, d); + ZZ_pE::init(mod); + + fmpz_mod_poly_init(fmod, p); + fmpz_mod_poly_set_ZZ_pX(fmod, mod); + + fq_ctx_init_modulus(ctx, fmod, "a"); + + ZZ_pEX zzpex; + + fq_poly_init(f1, ctx); + fq_poly_init(f2, ctx); + + length = n_randint(state, 1000); + + fq_poly_randtest(f1, state, length, ctx); + + fq_poly_get_ZZ_pEX(zzpex, f1, ctx); + fq_poly_set_ZZ_pEX(f2, zzpex, ctx); + + result = fq_poly_equal(f1, f2, ctx); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("p = "); fmpz_print(p); flint_printf("\n"); + flint_printf("mod = "); fmpz_mod_poly_print_pretty(fmod, "x"); flint_printf("\n"); + flint_printf("f1 = "); fq_poly_print_pretty(f1, "x", ctx); flint_printf("\n"); + flint_printf("zzpex:"); cout << zzpex; flint_printf("\n"); + flint_printf("f2 = "); fq_poly_print_pretty(f2, "x", ctx); flint_printf("\n"); + return 0; + } + + fmpz_clear(p); + fq_poly_clear(f1, ctx); + fq_poly_clear(f2, ctx); + + fmpz_mod_poly_clear(fmod); + fq_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + return 1; +} + +int test_zz_pE_to_fq() +{ + fmpz_t p; + fq_t f1, f2; + int i, result; + + fq_ctx_t ctx; + + FLINT_TEST_INIT(state); + + flint_printf("zz_pE_to_fq...."); + fflush(stdout); + + /* Check aliasing of a and c */ + for (i = 0; i < 10000; i++) + { + fmpz_mod_poly_t fmod; + slong d; + zz_pX mod; + + fmpz_init(p); + fmpz_set_ui(p, n_randprime(state, 2 + n_randint(state, 6), 1)); + + d = n_randint(state, 10) + 1; + + zz_p::init(fmpz_get_si(p)); + + BuildIrred(mod, d); + zz_pE::init(mod); + + fmpz_mod_poly_init(fmod, p); + fmpz_mod_poly_set_zz_pX(fmod, mod); + + fq_ctx_init_modulus(ctx, fmod, "a"); + + zz_pE zzpe; + + fq_init(f1, ctx); + fq_init(f2, ctx); + + fq_randtest(f1, state, ctx); + + fq_get_zz_pE(zzpe, f1, ctx); + fq_set_zz_pE(f2, zzpe, ctx); + + result = fq_equal(f1, f2, ctx); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("p = "); fmpz_print(p); flint_printf("\n"); + flint_printf("mod = "); fmpz_mod_poly_print_pretty(fmod, "x"); flint_printf("\n"); + flint_printf("f1 = "); fq_print_pretty(f1, ctx); flint_printf(" - %wd", f1->length); flint_printf("\n"); + flint_printf("zzpe:"); cout << zzpe; flint_printf("\n"); + flint_printf("f2 = "); fq_print_pretty(f2, ctx); flint_printf(" - %wd", f2->length); flint_printf("\n"); + return 0; + } + + fmpz_clear(p); + fq_clear(f1, ctx); + fq_clear(f2, ctx); + + fmpz_mod_poly_clear(fmod); + fq_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + return 1; +} + +int test_zz_pEX_to_fq_poly() +{ + fmpz_t p; + fq_poly_t f1, f2; + slong length; + int i, result; + + fq_ctx_t ctx; + + FLINT_TEST_INIT(state); + + flint_printf("zz_pEX_to_fq_poly...."); + fflush(stdout); + + for (i = 0; i < 10000; i++) + { + fmpz_mod_poly_t fmod; + slong d; + zz_pX mod; + + fmpz_init(p); + fmpz_set_ui(p, n_randprime(state, 2 + n_randint(state, 6), 1)); + + d = n_randint(state, 10) + 1; + + zz_p::init(fmpz_get_si(p)); + + BuildIrred(mod, d); + zz_pE::init(mod); + + fmpz_mod_poly_init(fmod, p); + fmpz_mod_poly_set_zz_pX(fmod, mod); + + fq_ctx_init_modulus(ctx, fmod, "a"); + + zz_pEX zzpex; + + fq_poly_init(f1, ctx); + fq_poly_init(f2, ctx); + + length = n_randint(state, 1000); + + fq_poly_randtest(f1, state, length, ctx); + + fq_poly_get_zz_pEX(zzpex, f1, ctx); + fq_poly_set_zz_pEX(f2, zzpex, ctx); + + result = fq_poly_equal(f1, f2, ctx); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("p = "); fmpz_print(p); flint_printf("\n"); + flint_printf("mod = "); fmpz_mod_poly_print_pretty(fmod, "x"); flint_printf("\n"); + flint_printf("f1 = "); fq_poly_print_pretty(f1, "x", ctx); flint_printf("\n"); + flint_printf("zzpex:"); cout << zzpex; flint_printf("\n"); + flint_printf("f2 = "); fq_poly_print_pretty(f2, "x", ctx); flint_printf("\n"); + return 0; + } + + fmpz_clear(p); + fq_poly_clear(f1, ctx); + fq_poly_clear(f2, ctx); + + fmpz_mod_poly_clear(fmod); + fq_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + return 1; +} + + +int +main(void) +{ + int r = 1; + + if ((r &= test_ZZ_to_fmpz())) flint_printf("PASS\n"); + if ((r &= test_ZZX_to_fmpz_poly())) flint_printf("PASS\n"); + if ((r &= test_ZZ_pX_to_fmpz_mod_poly())) flint_printf("PASS\n"); + if ((r &= test_ZZ_pE_to_fq())) flint_printf("PASS\n"); + if ((r &= test_ZZ_pEX_to_fq_poly())) flint_printf("PASS\n"); + if ((r &= test_zz_pX_to_fmpz_mod_poly())) flint_printf("PASS\n"); + if ((r &= test_zz_pE_to_fq())) flint_printf("PASS\n"); + if ((r &= test_zz_pEX_to_fq_poly())) flint_printf("PASS\n"); + + if (!r) abort(); + + return 0; +} diff --git a/external/flint-2.4.3/long_extras.h b/external/flint-2.4.3/long_extras.h new file mode 100644 index 0000000..5c4e332 --- /dev/null +++ b/external/flint-2.4.3/long_extras.h @@ -0,0 +1,53 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#ifndef LONG_EXTRAS_H +#define LONG_EXTRAS_H + +#include +#include "flint.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/* Properties ****************************************************************/ + +size_t z_sizeinbase(slong n, int b); + +/* Randomisation ************************************************************/ + +mp_limb_signed_t z_randtest(flint_rand_t state); + +mp_limb_signed_t z_randtest_not_zero(flint_rand_t state); + +mp_limb_signed_t z_randint(flint_rand_t state, mp_limb_t limit); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/external/flint-2.4.3/long_extras/doc/long_extras.txt b/external/flint-2.4.3/long_extras/doc/long_extras.txt new file mode 100644 index 0000000..0dee60d --- /dev/null +++ b/external/flint-2.4.3/long_extras/doc/long_extras.txt @@ -0,0 +1,63 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +******************************************************************************* + + Properties + +******************************************************************************* + +size_t z_sizeinbase(slong n, int b) + + Returns the number of digits in the base $b$ representation + of the absolute value of the integer $n$. + + Assumes that $b \geq 2$. + +******************************************************************************* + + Random functions + +******************************************************************************* + +mp_limb_signed_t z_randtest(flint_rand_t state) + + Returns a pseudo random number with a random number of bits, from + $0$ to \code{FLINT_BITS}. The probability of the special values $0$, + $\pm 1$, \code{COEFF_MAX}, \code{COEFF_MIN}, \code{WORD_MAX} and + \code{WORD_MIN} is increased. + + This random function is mainly used for testing purposes. + +mp_limb_signed_t z_randtest_not_zero(flint_rand_t state) + + As for \code{z_randtest(state)}, but does not return $0$. + +mp_limb_t z_randint(flint_rand_t state, mp_limb_t limit) + + Returns a pseudo random number of absolute value less than + \code{limit}. If \code{limit} is zero or exceeds \code{WORD_MAX}, + it is interpreted as \code{WORD_MAX}. + diff --git a/external/flint-2.4.3/long_extras/randint.c b/external/flint-2.4.3/long_extras/randint.c new file mode 100644 index 0000000..a698d4e --- /dev/null +++ b/external/flint-2.4.3/long_extras/randint.c @@ -0,0 +1,44 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include + +#include "flint.h" +#include "ulong_extras.h" + +mp_limb_t z_randint(flint_rand_t state, mp_limb_t limit) +{ + mp_limb_t z; + + if ((limit == UWORD(0)) || (limit > WORD_MAX)) + limit = WORD_MAX; + + z = n_randlimb(state) % limit; + if (n_randint(state, 2)) + z = -z; + + return z; +} diff --git a/external/flint-2.4.3/long_extras/randtest.c b/external/flint-2.4.3/long_extras/randtest.c new file mode 100644 index 0000000..a48928d --- /dev/null +++ b/external/flint-2.4.3/long_extras/randtest.c @@ -0,0 +1,71 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include + +#include "flint.h" +#include "fmpz.h" +#include "ulong_extras.h" + +mp_limb_signed_t z_randtest(flint_rand_t state) +{ + mp_limb_t m; + mp_limb_signed_t z; + + m = n_randlimb(state); + + if (m & UWORD(7)) + { + z = n_randbits(state, n_randint(state, FLINT_BITS)); + } + else + { + m >>= 3; + + switch (m % UWORD(7)) + { + case 0: z = 0; break; + case 1: z = 1; break; + case 2: z = -1; break; + case 3: z = COEFF_MAX; break; + case 4: z = COEFF_MIN; break; + case 5: z = WORD_MAX; break; + case 6: z = WORD_MIN; break; + default: z = 0; + } + } + + return z; +} + +mp_limb_signed_t z_randtest_not_zero(flint_rand_t state) +{ + mp_limb_signed_t z; + + while ((z = z_randtest(state)) == 0) ; + return z; +} + diff --git a/external/flint-2.4.3/long_extras/sizeinbase.c b/external/flint-2.4.3/long_extras/sizeinbase.c new file mode 100644 index 0000000..187d6d5 --- /dev/null +++ b/external/flint-2.4.3/long_extras/sizeinbase.c @@ -0,0 +1,63 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" + +size_t z_sizeinbase(slong n, int b) +{ + slong c = 0; + + if (n == 0) + { + return 1; + } + + if (n <= 0) + { + if (n > WORD_MIN) + { + n = -n; + } + else /* n == WORD_MIN */ + { + if (n % b) + { + n = - (n + 1); + } + else + { + n = - (n / b); + c = 1; + } + } + } + + for ( ; n > 0; n /= b, c++) ; + + return c; +} + diff --git a/external/flint-2.4.3/long_extras/test/t-sizeinbase.c b/external/flint-2.4.3/long_extras/test/t-sizeinbase.c new file mode 100644 index 0000000..a13f42c --- /dev/null +++ b/external/flint-2.4.3/long_extras/test/t-sizeinbase.c @@ -0,0 +1,78 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "long_extras.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("sizeinbase...."); + fflush(stdout); + + + + for (i = 0; i < 100000; i++) + { + slong a; + mpz_t b; + int base; + size_t r1, r2; + + a = z_randtest(state); + flint_mpz_init_set_si(b, a); + base = (int) (n_randint(state, 61) + 2); + + r1 = z_sizeinbase(a, base); + r2 = mpz_sizeinbase(b, base); + result = (r1 == r2 || r1 + 1 == r2); + + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("b = %Zd\n", b); + flint_printf("base = %d\n", base); + flint_printf("r1 = %wu\n, r2 = %wu\n", (ulong) r1, (ulong) r2); + abort(); + } + + mpz_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/longlong.h b/external/flint-2.4.3/longlong.h new file mode 100644 index 0000000..7fcb546 --- /dev/null +++ b/external/flint-2.4.3/longlong.h @@ -0,0 +1,533 @@ +/* + Copyright 1991, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001, 2002, 2003, + 2004, 2005 Free Software Foundation, Inc. + + Copyright 2009 William Hart + Copyright 2011 Fredrik Johansson + + This file is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or (at your + option) any later version. + + This file 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 Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this file; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. +*/ + +/* + N.B: This file has been adapted from code found in GMP 4.2.1. +*/ + +#ifndef FLINT_LONGLONG_H +#define FLINT_LONGLONG_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* x86 : 64 bit */ +#if (GMP_LIMB_BITS == 64 && defined (__amd64__)) + +#define add_sssaaaaaa(sh, sm, sl, ah, am, al, bh, bm, bl) \ + __asm__ ("addq %8,%q2\n\tadcq %6,%q1\n\tadcq %4,%q0" \ + : "=r" (sh), "=r" (sm), "=&r" (sl) \ + : "0" ((mp_limb_t)(ah)), "rme" ((mp_limb_t)(bh)), \ + "1" ((mp_limb_t)(am)), "rme" ((mp_limb_t)(bm)), \ + "2" ((mp_limb_t)(al)), "rme" ((mp_limb_t)(bl))) \ + +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("addq %5,%q1\n\tadcq %3,%q0" \ + : "=r" (sh), "=&r" (sl) \ + : "0" ((mp_limb_t)(ah)), "rme" ((mp_limb_t)(bh)), \ + "%1" ((mp_limb_t)(al)), "rme" ((mp_limb_t)(bl))) + +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("subq %5,%q1\n\tsbbq %3,%q0" \ + : "=r" (sh), "=&r" (sl) \ + : "0" ((mp_limb_t)(ah)), "rme" ((mp_limb_t)(bh)), \ + "1" ((mp_limb_t)(al)), "rme" ((mp_limb_t)(bl))) + +#define umul_ppmm(w1, w0, u, v) \ + __asm__ ("mulq %3" \ + : "=a" (w0), "=d" (w1) \ + : "%0" ((mp_limb_t)(u)), "rm" ((mp_limb_t)(v))) + +#define udiv_qrnnd(q, r, n1, n0, dx) \ + __asm__ ("divq %4" \ + : "=a" (q), "=d" (r) \ + : "0" ((mp_limb_t)(n0)), "1" ((mp_limb_t)(n1)), "rm" ((mp_limb_t)(dx))) + +#define sdiv_qrnnd(q, r, n1, n0, dx) \ + __asm__ ("idivq %4" \ + : "=a" (q), "=d" (r) \ + : "0" ((mp_limb_t)(n0)), "1" ((mp_limb_t)(n1)), "rm" ((mp_limb_t)(dx))) + +/* bsrq destination must be a 64-bit register, hence mp_limb_t for __cbtmp. */ +#define count_leading_zeros(count, x) \ + do { \ + mp_limb_t __cbtmp; \ + FLINT_ASSERT ((x) != 0); \ + __asm__ ("bsrq %1,%0" : "=r" (__cbtmp) : "rm" ((mp_limb_t)(x))); \ + (count) = __cbtmp ^ (mp_limb_t) 63; \ + } while (0) + +/* bsfq destination must be a 64-bit register, "%q0" forces this in case + count is only an int. */ +#define count_trailing_zeros(count, x) \ + do { \ + FLINT_ASSERT ((x) != 0); \ + __asm__ ("bsfq %1,%q0" : "=r" (count) : "rm" ((mp_limb_t)(x))); \ + } while (0) + +#endif /* x86_64 */ + +/* x86 : 32 bit */ +#if (GMP_LIMB_BITS == 32 && (defined (__i386__) \ + || defined (__i486__) || defined(__amd64__))) + +#define add_sssaaaaaa(sh, sm, sl, ah, am, al, bh, bm, bl) \ + __asm__ ("addl %8,%k2\n\tadcl %6,%k1\n\tadcl %4,%k0" \ + : "=r" (sh), "=r" (sm), "=&r" (sl) \ + : "0" ((mp_limb_t)(ah)), "g" ((mp_limb_t)(bh)), \ + "1" ((mp_limb_t)(am)), "g" ((mp_limb_t)(bm)), \ + "2" ((mp_limb_t)(al)), "g" ((mp_limb_t)(bl))) \ + +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("addl %5,%k1\n\tadcl %3,%k0" \ + : "=r" (sh), "=&r" (sl) \ + : "0" ((mp_limb_t)(ah)), "g" ((mp_limb_t)(bh)), \ + "%1" ((mp_limb_t)(al)), "g" ((mp_limb_t)(bl))) + +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("subl %5,%k1\n\tsbbl %3,%k0" \ + : "=r" (sh), "=&r" (sl) \ + : "0" ((mp_limb_t)(ah)), "g" ((mp_limb_t)(bh)), \ + "1" ((mp_limb_t)(al)), "g" ((mp_limb_t)(bl))) + +#define umul_ppmm(w1, w0, u, v) \ + __asm__ ("mull %3" \ + : "=a" (w0), "=d" (w1) \ + : "%0" ((mp_limb_t)(u)), "rm" ((mp_limb_t)(v))) + +#define udiv_qrnnd(q, r, n1, n0, dx) \ + __asm__ ("divl %4" \ + : "=a" (q), "=d" (r) \ + : "0" ((mp_limb_t)(n0)), "1" ((mp_limb_t)(n1)), "rm" ((mp_limb_t)(dx))) + +#define sdiv_qrnnd(q, r, n1, n0, dx) \ + __asm__ ("idivl %4" \ + : "=a" (q), "=d" (r) \ + : "0" ((mp_limb_t)(n0)), "1" ((mp_limb_t)(n1)), "rm" ((mp_limb_t)(dx))) + +#define count_leading_zeros(count, x) \ + do { \ + mp_limb_t __cbtmp; \ + FLINT_ASSERT ((x) != 0); \ + __asm__ ("bsrl %1,%0" : "=r" (__cbtmp) : "rm" ((mp_limb_t)(x))); \ + (count) = __cbtmp ^ (mp_limb_t) 31; \ + } while (0) + +#define count_trailing_zeros(count, x) \ + do { \ + FLINT_ASSERT ((x) != 0); \ + __asm__ ("bsfl %1,%0" : "=r" (count) : "rm" ((mp_limb_t)(x))); \ + } while (0) + +#endif /* x86 */ + +/* Itanium */ +#if (GMP_LIMB_BITS == 64 && defined (__ia64)) + +/* This form encourages gcc (pre-release 3.4 at least) to emit predicated + "sub r=r,r" and "sub r=r,r,1", giving a 2 cycle latency. The generic + code using "al> (GMP_LIMB_BITS / 2)) +#define __highbit (~(mp_limb_t)0 ^ ((~(mp_limb_t)0) >> 1)) + +#define NEED_CLZ_TAB + +#if !(GMP_LIMB_BITS == 32 && defined (__arm__)) +#if !(GMP_LIMB_BITS == 64 && defined (__ia64)) + +#define umul_ppmm(w1, w0, u, v) \ + do { \ + mp_limb_t __x0, __x1, __x2, __x3; \ + mp_limb_t __ul, __vl, __uh, __vh; \ + mp_limb_t __u = (u), __v = (v); \ + \ + __ul = __ll_lowpart (__u); \ + __uh = __ll_highpart (__u); \ + __vl = __ll_lowpart (__v); \ + __vh = __ll_highpart (__v); \ + \ + __x0 = (mp_limb_t) __ul * __vl; \ + __x1 = (mp_limb_t) __ul * __vh; \ + __x2 = (mp_limb_t) __uh * __vl; \ + __x3 = (mp_limb_t) __uh * __vh; \ + \ + __x1 += __ll_highpart (__x0);/* this can't give carry */ \ + __x1 += __x2; /* but this indeed can */ \ + if (__x1 < __x2) /* did we get it? */ \ + __x3 += __ll_B; /* yes, add it in the proper pos. */ \ + \ + (w1) = __x3 + __ll_highpart (__x1); \ + (w0) = (__x1 << GMP_LIMB_BITS/2) + __ll_lowpart (__x0); \ + } while (0) + +#endif +#endif + +#if !(GMP_LIMB_BITS == 32 && defined (__arm__)) + +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + do { \ + mp_limb_t __x; \ + __x = (al) + (bl); \ + (sh) = (ah) + (bh) + (__x < (al)); \ + (sl) = __x; \ + } while (0) + +#endif + +#define add_sssaaaaaa(sh, sm, sl, ah, am, al, bh, bm, bl) \ + do { \ + mp_limb_t __t, __u; \ + add_ssaaaa(__t, sl, (mp_limb_t) 0, al, (mp_limb_t) 0, bl); \ + add_ssaaaa(__u, sm, (mp_limb_t) 0, am, (mp_limb_t) 0, bm); \ + add_ssaaaa(sh, sm, ah + bh, sm, __u, __t); \ + } while (0) + +#if !((GMP_LIMB_BITS == 64 && defined (__ia64)) || \ + (GMP_LIMB_BITS == 32 && defined (__arm__))) + +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + do { \ + mp_limb_t __x; \ + __x = (al) - (bl); \ + (sh) = (ah) - (bh) - ((al) < (bl)); \ + (sl) = __x; \ + } while (0) + +#endif + +#define udiv_qrnnd_int(q, r, n1, n0, d) \ + do { \ + mp_limb_t __d1, __d0, __q1, __q0, __r1, __r0, __m; \ + \ + FLINT_ASSERT ((d) != 0); \ + FLINT_ASSERT ((n1) < (d)); \ + \ + __d1 = __ll_highpart (d); \ + __d0 = __ll_lowpart (d); \ + \ + __q1 = (n1) / __d1; \ + __r1 = (n1) - __q1 * __d1; \ + __m = __q1 * __d0; \ + __r1 = __r1 * __ll_B | __ll_highpart (n0); \ + if (__r1 < __m) \ + { \ + __q1--, __r1 += (d); \ + if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */ \ + if (__r1 < __m) \ + __q1--, __r1 += (d); \ + } \ + __r1 -= __m; \ + \ + __q0 = __r1 / __d1; \ + __r0 = __r1 - __q0 * __d1; \ + __m = __q0 * __d0; \ + __r0 = __r0 * __ll_B | __ll_lowpart (n0); \ + if (__r0 < __m) \ + { \ + __q0--, __r0 += (d); \ + if (__r0 >= (d)) \ + if (__r0 < __m) \ + __q0--, __r0 += (d); \ + } \ + __r0 -= __m; \ + \ + (q) = __q1 * __ll_B | __q0; \ + (r) = __r0; \ + } while (0) + +#define count_leading_zeros(count, x) \ + do { \ + mp_limb_t __xr = (x); \ + mp_limb_t __a; \ + \ + if (GMP_LIMB_BITS == 32) \ + { \ + __a = __xr < ((mp_limb_t) 1 << 2*__BITS4) \ + ? (__xr < ((mp_limb_t) 1 << __BITS4) ? 1 : __BITS4 + 1) \ + : (__xr < ((mp_limb_t) 1 << 3*__BITS4) ? 2*__BITS4 + 1 \ + : 3*__BITS4 + 1); \ + } \ + else \ + { \ + for (__a = GMP_LIMB_BITS - 8; __a > 0; __a -= 8) \ + if (((__xr >> __a) & 0xff) != 0) \ + break; \ + ++__a; \ + } \ + \ + (count) = GMP_LIMB_BITS + 1 - __a - __flint_clz_tab[__xr >> __a]; \ + } while (0) + +#if !(GMP_LIMB_BITS == 64 && defined (__ia64)) + +#define count_trailing_zeros(count, x) \ + do { \ + mp_limb_t __ctz_x = (x); \ + mp_limb_t __ctz_c; \ + FLINT_ASSERT (__ctz_x != 0); \ + count_leading_zeros (__ctz_c, __ctz_x & -__ctz_x); \ + (count) = GMP_LIMB_BITS - 1 - __ctz_c; \ + } while (0) + +#endif + +#define udiv_qrnnd(q, r, n1, n0, d) \ + do { \ + mp_limb_t __norm; \ + count_leading_zeros(__norm, (d)); \ + if (__norm) \ + { \ + udiv_qrnnd_int((q), (r), ((n1) << __norm) + ((n0) >> (GMP_LIMB_BITS - __norm)), (n0) << __norm, (d) << __norm); \ + (r) = ((mp_limb_t) (r) >> __norm); \ + } else \ + udiv_qrnnd_int((q), (r), (n1), (n0), (d)); \ + } while (0) + +#define sdiv_qrnnd(q, r, n1, n0, d) \ + do { \ + mp_limb_t __n1, __n0, __d; \ + int __sgn1 = 0, __sgn2 = 0; \ + if ((n1) & __highbit) \ + { \ + __n0 = -(n0); \ + __n1 = ~(n1) + (__n0 == 0); \ + __sgn1 = ~__sgn1; \ + } else \ + { \ + __n0 = (n0); \ + __n1 = (n1); \ + } \ + if ((d) & __highbit) \ + { \ + __d = -(d); \ + __sgn2 = ~__sgn2; \ + } else \ + { \ + __d = (d); \ + } \ + udiv_qrnnd((q), (r), (mp_limb_t) __n1, (mp_limb_t) __n0, (mp_limb_t) __d); \ + if (__sgn1 ^ __sgn2) \ + { \ + (q) = -(q); \ + if (!__sgn2) \ + { \ + (q)--; \ + (r) = (__d) - (r); \ + } \ + } else if (__sgn1 && __sgn2) \ + { \ + (q)++; \ + (r) = (__d) - (r); \ + } \ + } while (0) + +#endif /* non x86 fallback code */ + +#if !(GMP_LIMB_BITS == 32 && defined (__arm__)) + +#define smul_ppmm(w1, w0, u, v) \ + do { \ + mp_limb_t __w1; \ + mp_limb_t __xm0 = (u), __xm1 = (v); \ + umul_ppmm (__w1, w0, __xm0, __xm1); \ + (w1) = __w1 - (-(__xm0 >> (FLINT_BITS-1)) & __xm1) \ + - (-(__xm1 >> (FLINT_BITS-1)) & __xm0); \ + } while (0) + +#endif + +#define invert_limb(invxl, xl) \ + do { \ + mp_limb_t dummy; \ + udiv_qrnnd (invxl, dummy, ~(xl), ~(WORD(0)), xl); \ + } while (0) + +/* + Branch free variant + */ +#if 1 +#define udiv_qrnnd_preinv(q, r, nh, nl, d, di) \ + do { \ + mp_limb_t _n2, _n10, _nmask, _nadj, _q1; \ + mp_limb_t _xh, _xl; \ + _n2 = (nh); \ + _n10 = (nl); \ + _nmask = (mp_limb_signed_t) (_n10) >> (FLINT_BITS - 1); \ + _nadj = _n10 + (_nmask & (d)); \ + umul_ppmm (_xh, _xl, di, _n2 - _nmask); \ + add_ssaaaa (_xh, _xl, _xh, _xl, _n2, _nadj); \ + _q1 = ~_xh; \ + umul_ppmm (_xh, _xl, _q1, d); \ + add_ssaaaa (_xh, _xl, _xh, _xl, nh, nl); \ + _xh -= (d); /* xh = 0 or -1 */ \ + (r) = _xl + ((d) & _xh); \ + (q) = _xh - _q1; \ + } while (0) + +/* + Branched variant, slower on K10 for general inputs + */ +#else +#define udiv_qrnnd_preinv(q, r, nh, nl, d, di) \ + do { \ + mp_limb_t _q, _ql, _r; \ + mp_limb_t _xh, _xl; \ + FLINT_ASSERT ((d) != 0); \ + umul_ppmm (_q, _ql, (nh), (di)); \ + _q += (nh); /* Compensate, di is 2^64 too small */ \ + umul_ppmm (_xh, _xl, _q, (d)); \ + sub_ddmmss (_xh, _r, (nh), (nl), _xh, _xl); \ + if (_xh != 0) \ + { \ + sub_ddmmss (_xh, _r, _xh, _r, 0, (d)); \ + _q += 1; \ + if (_xh != 0) \ + { \ + _r -= (d); \ + _q += 1; \ + } \ + } \ + if (_r >= (d)) \ + { \ + _r -= (d); \ + _q += 1; \ + } \ + (r) = _r; \ + (q) = _q; \ + } while (0) +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/flint-2.4.3/memory_manager.c b/external/flint-2.4.3/memory_manager.c new file mode 100644 index 0000000..04abf8a --- /dev/null +++ b/external/flint-2.4.3/memory_manager.c @@ -0,0 +1,159 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" + +#if HAVE_GC +#include "gc.h" +#endif + +#if FLINT_REENTRANT && !HAVE_TLS +#include + +static pthread_once_t register_initialised = PTHREAD_ONCE_INIT; +pthread_mutex_t register_lock; +#endif + +static void flint_memory_error() +{ + flint_printf("Exception (FLINT memory_manager). Unable to allocate memory.\n"); + abort(); +} + +void * flint_malloc(size_t size) +{ + void * ptr; + +#if HAVE_GC + ptr = GC_malloc(size); +#else + ptr = malloc(size); +#endif + + if (ptr == NULL) + flint_memory_error(); + + return ptr; +} + +void * flint_realloc(void * ptr, size_t size) +{ + void * ptr2; + +#if HAVE_GC + ptr2 = GC_realloc(ptr, size); +#else + ptr2 = realloc(ptr, size); +#endif + + if (ptr2 == NULL) + flint_memory_error(); + + return ptr2; +} + +void * flint_calloc(size_t num, size_t size) +{ + void * ptr; + +#if HAVE_GC + ptr = GC_malloc(num*size); +#else + ptr = calloc(num, size); +#endif + + if (ptr == NULL) + flint_memory_error(); + + return ptr; +} + +void flint_free(void * ptr) +{ +#if !HAVE_GC + free(ptr); +#endif +} + + +FLINT_TLS_PREFIX size_t flint_num_cleanup_functions = 0; + +FLINT_TLS_PREFIX flint_cleanup_function_t * flint_cleanup_functions = NULL; + +#if FLINT_REENTRANT && !HAVE_TLS +void register_init() +{ + pthread_mutex_init(®ister_lock, NULL); +} +#endif + +void flint_register_cleanup_function(flint_cleanup_function_t cleanup_function) +{ +#if FLINT_REENTRANT && !HAVE_TLS + pthread_once(®ister_initialised, register_init); + pthread_mutex_lock(®ister_lock); +#endif + + flint_cleanup_functions = flint_realloc(flint_cleanup_functions, + (flint_num_cleanup_functions + 1) * sizeof(flint_cleanup_function_t)); + + flint_cleanup_functions[flint_num_cleanup_functions] = cleanup_function; + + flint_num_cleanup_functions++; + +#if FLINT_REENTRANT && !HAVE_TLS + pthread_mutex_unlock(®ister_lock); +#endif +} + +void _fmpz_cleanup(); + +void flint_cleanup() +{ + size_t i; + +#if FLINT_REENTRANT && !HAVE_TLS + pthread_mutex_lock(®ister_lock); +#endif + + for (i = 0; i < flint_num_cleanup_functions; i++) + flint_cleanup_functions[i](); + + flint_free(flint_cleanup_functions); + flint_cleanup_functions = NULL; + flint_num_cleanup_functions = 0; + + mpfr_free_cache(); + _fmpz_cleanup(); + +#if FLINT_REENTRANT && !HAVE_TLS + pthread_mutex_unlock(®ister_lock); +#endif + +} + + diff --git a/external/flint-2.4.3/mpfr_mat.h b/external/flint-2.4.3/mpfr_mat.h new file mode 100644 index 0000000..a2f5f63 --- /dev/null +++ b/external/flint-2.4.3/mpfr_mat.h @@ -0,0 +1,57 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#ifndef MFPR_MAT_H +#define MPFR_MAT_H + +#include +#include + +#ifdef __cplusplus + extern "C" { +#endif + +typedef struct +{ + __mpfr_struct * entries; + slong r; + slong c; + mp_bitcnt_t prec; + __mpfr_struct ** rows; +} mpfr_mat_struct; + +/* fmpz_mat_t allows reference-like semantics for fmpz_mat_struct */ +typedef mpfr_mat_struct mpfr_mat_t[1]; + +void mpfr_mat_init(mpfr_mat_t mat, slong rows, slong cols, mpfr_prec_t prec); + +void mpfr_mat_clear(mpfr_mat_t mat); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/external/flint-2.4.3/mpfr_mat/clear.c b/external/flint-2.4.3/mpfr_mat/clear.c new file mode 100644 index 0000000..848b058 --- /dev/null +++ b/external/flint-2.4.3/mpfr_mat/clear.c @@ -0,0 +1,43 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "mpfr_mat.h" + +void +mpfr_mat_clear(mpfr_mat_t mat) +{ + if (mat->entries) + { + slong i; + for (i = 0; i < mat->r * mat->c; i++) + mpfr_clear(mat->entries + i); /* Clear all coefficients */ + flint_free(mat->entries); /* Clean up array of entries */ + flint_free(mat->rows); /* Clean up row array */ + } +} diff --git a/external/flint-2.4.3/mpfr_mat/doc/mpfr_mat.txt b/external/flint-2.4.3/mpfr_mat/doc/mpfr_mat.txt new file mode 100644 index 0000000..c78abd1 --- /dev/null +++ b/external/flint-2.4.3/mpfr_mat/doc/mpfr_mat.txt @@ -0,0 +1,42 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Andy Novocin + +******************************************************************************/ + +******************************************************************************* + + Memory management + +******************************************************************************* + +void mpfr_mat_init(mpfr_mat_t mat, slong rows, slong cols, mpfr_prec_t prec) + + Initialises a matrix with the given number of rows and columns and the + given precision for use. The precision is the exact precision of the + entries. + +void mpfr_mat_clear(mpfr_mat_t mat) + + Clears the given matrix. + diff --git a/external/flint-2.4.3/mpfr_mat/init.c b/external/flint-2.4.3/mpfr_mat/init.c new file mode 100644 index 0000000..cfaadbe --- /dev/null +++ b/external/flint-2.4.3/mpfr_mat/init.c @@ -0,0 +1,54 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "mpfr_mat.h" + +void +mpfr_mat_init(mpfr_mat_t mat, slong rows, slong cols, mpfr_prec_t prec) +{ + + if ((rows) && (cols)) /* Allocate space for r*c small entries */ + { + slong i; + mat->entries = + (__mpfr_struct *) flint_malloc(rows * cols * sizeof(__mpfr_struct)); + mat->rows = (__mpfr_struct **) flint_malloc(rows * sizeof(__mpfr_struct *)); /* Initialise rows */ + + for (i = 0; i < rows * cols; i++) + mpfr_init2(mat->entries + i, prec); + for (i = 0; i < rows; i++) + mat->rows[i] = mat->entries + i * cols; + } + else + mat->entries = NULL; + + mat->r = rows; + mat->c = cols; + mat->prec = prec; +} diff --git a/external/flint-2.4.3/mpfr_mat/test/t-init_clear.c b/external/flint-2.4.3/mpfr_mat/test/t-init_clear.c new file mode 100644 index 0000000..9935e37 --- /dev/null +++ b/external/flint-2.4.3/mpfr_mat/test/t-init_clear.c @@ -0,0 +1,65 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "mpfr_mat.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("init/clear...."); + fflush(stdout); + + for (i = 0; i < 10000; i++) + { + mpfr_mat_t a; + slong j, k; + slong rows = n_randint(state, 100); + slong cols = n_randint(state, 100); + mp_prec_t prec = n_randint(state, 200) + MPFR_PREC_MIN; + + mpfr_mat_init(a, rows, cols, prec); + + for (j = 0; j < rows; j++) + for (k = 0; k < cols; k++) + mpfr_set_ui(a->rows[j] + k, 0, GMP_RNDN); + + mpfr_mat_clear(a); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/mpfr_poly.h b/external/flint-2.4.3/mpfr_poly.h new file mode 100644 index 0000000..f5bfe8b --- /dev/null +++ b/external/flint-2.4.3/mpfr_poly.h @@ -0,0 +1,138 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#ifndef MFPR_POLY_H +#define MPFR_POLY_H + +#include +#include +#include "flint.h" + +#ifdef __cplusplus + extern "C" { +#endif + +typedef struct +{ + __mpfr_struct * coeffs; + slong length; + slong alloc; + mpfr_prec_t prec; +} mpfr_poly_struct; + +/* fmpz_poly_t allows reference-like semantics for fmpz_poly_struct */ +typedef mpfr_poly_struct mpfr_poly_t[1]; + +extern gmp_randstate_t mpfr_poly_randstate; + +#define MUL_INPLACE_CUTOFF 1000 + +void mpfr_poly_init(mpfr_poly_t poly, mpfr_prec_t prec); + +void mpfr_poly_init2(mpfr_poly_t poly, slong alloc, mpfr_prec_t prec); + +void mpfr_poly_realloc(mpfr_poly_t poly, slong alloc); + +void mpfr_poly_fit_length(mpfr_poly_t poly, slong length); + +void mpfr_poly_clear(mpfr_poly_t poly); + +static __inline__ +void _mpfr_poly_set_length(mpfr_poly_t poly, slong length) +{ + poly->length = length; +} + +static __inline__ +void mpfr_poly_set_prec(mpfr_poly_t poly, mpfr_prec_t prec) +{ + slong i; + for (i = 0; i < poly->alloc; i++) + mpfr_prec_round(poly->coeffs + i, prec, GMP_RNDN); + poly->prec = prec; +} + +void mpfr_poly_randinit(void); + +void mpfr_poly_randclear(void); + +void mpfr_poly_randtest(mpfr_poly_t poly, slong length); + +static __inline__ +void mpfr_poly_swap(mpfr_poly_t poly1, mpfr_poly_t poly2) +{ + mpfr * tc; + slong t; + mpfr_prec_t tp; + + tc = poly1->coeffs; + poly1->coeffs = poly2->coeffs; + poly2->coeffs = tc; + + t = poly1->length; + poly1->length = poly2->length; + poly2->length = t; + + t = poly1->alloc; + poly1->alloc = poly2->alloc; + poly2->alloc = t; + + tp = poly1->prec; + poly1->prec = poly2->prec; + poly2->prec = tp; +} + +void _mpfr_poly_mul_classical(mpfr * res, mpfr * in1, slong len1, + mpfr * in2, slong len2, mpfr_prec_t prec); + +void mpfr_poly_mul_classical(mpfr_poly_t res, mpfr_poly_t poly1, + mpfr_poly_t poly2); + +void _mpfr_poly_FHT(mpfr * coeffs, slong n, mpfr_prec_t prec); + +void _mpfr_poly_convolution_trans(mpfr * coeffs1, + mpfr * coeffs2, slong n, mpfr_prec_t prec); + +void _mpfr_poly_revbin(mpfr * coeffs, slong n); + +void _mpfr_poly_scale(mpfr * coeffs, slong n); + +void _mpfr_poly_convolution_FHT(mpfr * coeffs1, + mpfr * coeffs2, slong n, mpfr_prec_t prec); + +void mpfr_poly_mul_FHT(mpfr_poly_t res, mpfr_poly_t poly1, + mpfr_poly_t poly2); + +int _mpfr_poly_bound_newton(double * inter, double * slope, + mpfr * poly, slong len, mpfr_prec_t prec); + +void mpfr_poly_mul(mpfr_poly_t res, mpfr_poly_t poly1, + mpfr_poly_t poly2, mpfr_prec_t fb); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/flint-2.4.3/mpfr_vec.h b/external/flint-2.4.3/mpfr_vec.h new file mode 100644 index 0000000..ac8a178 --- /dev/null +++ b/external/flint-2.4.3/mpfr_vec.h @@ -0,0 +1,62 @@ +/*============================================================================ + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +===============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#ifndef MFPR_VEC_H +#define MPFR_VEC_H + +#include +#include + +#ifdef __cplusplus + extern "C" { +#endif + +mpfr * _mpfr_vec_init(slong length, mp_bitcnt_t prec); + +void _mpfr_vec_clear(mpfr * vec, slong length); + +void _mpfr_vec_zero(mpfr * vec, slong length); + +void _mpfr_vec_set(mpfr * vec1, const mpfr * vec2, slong length); + +void _mpfr_vec_add(mpfr * res, const mpfr * vec1, const mpfr * vec2, slong length); + +void _mpfr_vec_scalar_mul_2exp(mpfr * res, const mpfr * vec, slong length, mp_bitcnt_t exp); + +void _mpfr_vec_scalar_mul_mpfr(mpfr * res, const mpfr * vec, slong length, mpfr_t c); + +void _mpfr_vec_scalar_product(mpfr_t res, const mpfr * vec1, const mpfr * vec2, slong length); + +#ifdef __cplusplus +} +#endif + +#endif + + + + + + diff --git a/external/flint-2.4.3/mpfr_vec/add.c b/external/flint-2.4.3/mpfr_vec/add.c new file mode 100644 index 0000000..73a9b32 --- /dev/null +++ b/external/flint-2.4.3/mpfr_vec/add.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "mpfr_vec.h" + +void +_mpfr_vec_add(mpfr * res, const mpfr * vec1, const mpfr * vec2, slong length) +{ + slong i; + for (i = 0; i < length; i++) + mpfr_add(res + i, vec1 + i, vec2 + i, GMP_RNDN); +} diff --git a/external/flint-2.4.3/mpfr_vec/clear.c b/external/flint-2.4.3/mpfr_vec/clear.c new file mode 100644 index 0000000..a90537c --- /dev/null +++ b/external/flint-2.4.3/mpfr_vec/clear.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "mpfr_vec.h" + +void +_mpfr_vec_clear(mpfr * vec, slong length) +{ + slong i; + for (i = 0; i < length; i++) + mpfr_clear(vec + i); + flint_free(vec); +} diff --git a/external/flint-2.4.3/mpfr_vec/doc/mpfr_vec.txt b/external/flint-2.4.3/mpfr_vec/doc/mpfr_vec.txt new file mode 100644 index 0000000..43c0d45 --- /dev/null +++ b/external/flint-2.4.3/mpfr_vec/doc/mpfr_vec.txt @@ -0,0 +1,78 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Andy Novocin + +******************************************************************************/ + +******************************************************************************* + + Memory management + +******************************************************************************* + +mpfr * _mpfr_vec_init(slong len, mp_bitcnt_t prec) + + Returns a vector of the given length of initialised \code{mpfr}'s + with the given exact precision. + +void _mpfr_vec_clear(mpfr * vec, slong len) + + Clears the given vector. + +******************************************************************************* + + Arithmetic + +******************************************************************************* + +void _mpfr_vec_zero(mpfr * vec, slong len) + + Zeros the vector \code{(vec, len)}. + +void _mpfr_vec_set(mpfr * vec1, const mpfr * vec2, slong len) + + Copies the vector \code{vec2} of the given length into \code{vec1}. + No check is made to ensure \code{vec1} and \code{vec2} are different. + +void _mpfr_vec_add(mpfr * res, const mpfr * vec1, const mpfr * vec2, slong len) + + Adds the given vectors of the given length together and stores the + result in \code{res}. + +void _mpfr_vec_scalar_mul_mpfr(mpfr * res, const mpfr * vec, + slong len, mpfr_t c) + + Multiplies the vector with given length by the scalar $c$ and + sets \code{res} to the result. + +void _mpfr_vec_scalar_mul_2exp(mpfr * res, + const mpfr * vec, slong len, mp_bitcnt_t exp) + + Multiplies the given vector of the given length by \code{2^exp}. + +void _mpfr_vec_scalar_product(mpfr_t res, const mpfr * vec1, + const mpfr * vec2, slong len) + + Sets \code{res} to the scalar product of \code{(vec1, len)} with + \code{(vec2, len)}. Assumes \code{len > 0}. + diff --git a/external/flint-2.4.3/mpfr_vec/init.c b/external/flint-2.4.3/mpfr_vec/init.c new file mode 100644 index 0000000..e548885 --- /dev/null +++ b/external/flint-2.4.3/mpfr_vec/init.c @@ -0,0 +1,44 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "mpfr_vec.h" + +mpfr * +_mpfr_vec_init(slong length, mp_bitcnt_t prec) +{ + slong i; + + __mpfr_struct *vec = + (__mpfr_struct *) flint_malloc(length * sizeof(__mpfr_struct)); + + for (i = 0; i < length; i++) + mpfr_init2(vec + i, prec); + + return vec; +} diff --git a/external/flint-2.4.3/mpfr_vec/scalar_mul_2exp.c b/external/flint-2.4.3/mpfr_vec/scalar_mul_2exp.c new file mode 100644 index 0000000..3ea759f --- /dev/null +++ b/external/flint-2.4.3/mpfr_vec/scalar_mul_2exp.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/***************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "mpfr_vec.h" + +void +_mpfr_vec_scalar_mul_2exp(mpfr * res, const mpfr * vec, slong length, mp_bitcnt_t exp) +{ + slong i; + for (i = 0; i < length; i++) + mpfr_mul_2exp(res + i, vec + i, exp, GMP_RNDN); +} diff --git a/external/flint-2.4.3/mpfr_vec/scalar_mul_mpfr.c b/external/flint-2.4.3/mpfr_vec/scalar_mul_mpfr.c new file mode 100644 index 0000000..74cc116 --- /dev/null +++ b/external/flint-2.4.3/mpfr_vec/scalar_mul_mpfr.c @@ -0,0 +1,38 @@ +/*============================================================================ + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +===============================================================================*/ +/**************************************************************************** + + Copyright (C) 2010 William Hart + +*****************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "mpfr_vec.h" + +void +_mpfr_vec_scalar_mul_mpfr(mpfr * res, const mpfr * vec, slong length, mpfr_t c) +{ + slong i; + for (i = 0; i < length; i++) + mpfr_mul(res + i, vec + i, c, GMP_RNDN); +} diff --git a/external/flint-2.4.3/mpfr_vec/scalar_product.c b/external/flint-2.4.3/mpfr_vec/scalar_product.c new file mode 100644 index 0000000..ecb8c5e --- /dev/null +++ b/external/flint-2.4.3/mpfr_vec/scalar_product.c @@ -0,0 +1,48 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "mpfr_vec.h" + +void +_mpfr_vec_scalar_product(mpfr_t res, const mpfr * vec1, + const mpfr * vec2, slong length) +{ + slong i; + mpfr_t tmp; + mpfr_init(tmp); + + mpfr_mul(res, vec1, vec2, GMP_RNDN); + for (i = 1; i < length; i++) + { + mpfr_mul(tmp, vec1 + i, vec2 + i, GMP_RNDN); + mpfr_add(res, res, tmp, GMP_RNDN); + } + + mpfr_clear(tmp); +} diff --git a/external/flint-2.4.3/mpfr_vec/set.c b/external/flint-2.4.3/mpfr_vec/set.c new file mode 100644 index 0000000..fb47b75 --- /dev/null +++ b/external/flint-2.4.3/mpfr_vec/set.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "mpfr_vec.h" + +void +_mpfr_vec_set(mpfr * vec1, const mpfr * vec2, slong length) +{ + slong i; + for (i = 0; i < length; i++) + mpfr_set(vec1 + i, vec2 + i, GMP_RNDN); +} diff --git a/external/flint-2.4.3/mpfr_vec/test/t-init_clear.c b/external/flint-2.4.3/mpfr_vec/test/t-init_clear.c new file mode 100644 index 0000000..5a0a715 --- /dev/null +++ b/external/flint-2.4.3/mpfr_vec/test/t-init_clear.c @@ -0,0 +1,62 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "mpfr_vec.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("init/clear...."); + fflush(stdout); + + for (i = 0; i < 10000; i++) + { + __mpfr_struct *a; + slong j, length = n_randint(state, 100); + mp_prec_t prec = n_randint(state, 200) + MPFR_PREC_MIN; + + a = _mpfr_vec_init(length, prec); + + for (j = 0; j < length; j++) + mpfr_set_ui(a + j, 0, GMP_RNDN); + + _mpfr_vec_clear(a, length); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/mpfr_vec/zero.c b/external/flint-2.4.3/mpfr_vec/zero.c new file mode 100644 index 0000000..9046b12 --- /dev/null +++ b/external/flint-2.4.3/mpfr_vec/zero.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "mpfr_vec.h" + +void +_mpfr_vec_zero(mpfr * vec, slong length) +{ + slong i; + for (i = 0; i < length; i++) + mpfr_set_ui(vec + i, 0, GMP_RNDN); +} diff --git a/external/flint-2.4.3/mpn_extras.h b/external/flint-2.4.3/mpn_extras.h new file mode 100644 index 0000000..8993954 --- /dev/null +++ b/external/flint-2.4.3/mpn_extras.h @@ -0,0 +1,246 @@ +/*============================================================================ + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +===============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#ifndef MPN_EXTRAS_H +#define MPN_EXTRAS_H + +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" + +#ifdef __cplusplus + extern "C" { +#endif + +#define MPN_NORM(a, an) \ + do { \ + while ((an) != 0 && (a)[(an) - 1] == 0) \ + (an)--; \ + } while (0) + +#define MPN_SWAP(a, an, b, bn) \ + do { \ + mp_ptr __t; \ + mp_size_t __tn; \ + __t = (a); \ + (a) = (b); \ + (b) = __t; \ + __tn = (an); \ + (an) = (bn); \ + (bn) = __tn; \ + } while (0) + +#define BITS_TO_LIMBS(b) (((b) + GMP_NUMB_BITS - 1) / GMP_NUMB_BITS) + +/* Not defined in gmp.h +mp_limb_t __gmpn_modexact_1_odd(mp_srcptr src, mp_size_t size, + mp_limb_t divisor); +#define mpn_modexact_1_odd __gmpn_modexact_1_odd +*/ + +#ifdef mpn_modexact_1_odd +#define flint_mpn_divisible_1_p(x, xsize, d) (mpn_modexact_1_odd(x, xsize, d) == 0) +#else +static __inline__ int +flint_mpn_divisible_1_p(mp_srcptr x, mp_size_t xsize, mp_limb_t d) +{ + __mpz_struct s; + s._mp_size = xsize; + s._mp_d = (mp_ptr) x; + return flint_mpz_divisible_ui_p(&s, d); +} +#endif + +static __inline__ +int flint_mpn_zero_p(mp_srcptr x, mp_size_t xsize) +{ + slong i; + for (i = 0; i < xsize; i++) + { + if (x[i]) + return 0; + } + return 1; +} + +static __inline__ +mp_size_t flint_mpn_divexact_1(mp_ptr x, mp_size_t xsize, mp_limb_t d) +{ + mpn_divrem_1(x, 0, x, xsize, d); + if (x[xsize - 1] == UWORD(0)) + xsize -= 1; + return xsize; +} + +void flint_mpn_debug(mp_srcptr x, mp_size_t xsize); + +mp_size_t flint_mpn_remove_2exp(mp_ptr x, mp_size_t xsize, mp_bitcnt_t *bits); + +mp_size_t flint_mpn_remove_power_ascending(mp_ptr x, mp_size_t xsize, + mp_ptr p, mp_size_t psize, ulong *exp); + +int flint_mpn_factor_trial(mp_srcptr x, mp_size_t xsize, slong start, slong stop); + +int flint_mpn_divides(mp_ptr q, mp_srcptr array1, + mp_size_t limbs1, mp_srcptr arrayg, mp_size_t limbsg, mp_ptr temp); + +mp_size_t flint_mpn_gcd_full(mp_ptr arrayg, + mp_ptr array1, mp_size_t limbs1, mp_ptr array2, mp_size_t limbs2); + +/* +Macros for common operations with carry management. +Also automatically order the large operand first in mpn_mul +and mpn_add. +*/ + +#define MPN_SET(xx, xs, yy, ys) \ +do { \ + xs = ys; \ + flint_mpn_copyi(xx, yy, ys); \ +} while (0) + +#define CARRY(cy,xx,xs) if (cy) { xx[xs++] = cy; } + +#define MPN_MUL_1(xx, xs, yy, ys, dd) \ +do { \ + mp_limb_t __cy; \ + __cy = mpn_mul_1(xx, yy, ys, dd); \ + xs = ys; \ + CARRY(__cy, xx, xs); \ +} while (0) + +#define MPN_MUL(xx, xs, yy, ys, zz, zs) \ +do { \ + mp_limb_t __top; \ + xs = ys + zs; \ + if (ys >= zs) \ + __top = mpn_mul(xx, yy, ys, zz, zs); \ + else \ + __top = mpn_mul(xx, zz, zs, yy, ys); \ + if (!__top) \ + xs--; \ +} while (0) + +#define MPN_ADD(xx, xs, yy, ys, zz, zs) \ +do { \ + mp_limb_t __cy; \ + if (ys >= zs) \ + { \ + xs = ys; \ + __cy = mpn_add(xx, yy, ys, zz, zs); \ + } \ + else \ + { \ + xs = zs; \ + __cy = mpn_add(xx, zz, zs, yy, ys); \ + } \ + CARRY(__cy, xx, xs); \ +} while (0) + +/* + Note: still assumes xs >= ys +*/ +#define MPN_ADDMUL_1(xx, xs, yy, ys, dd) \ +do { \ + mp_limb_t __cy; \ + __cy = mpn_addmul_1(xx, yy, ys, dd); \ + if (__cy) \ + { \ + if (xs == ys) \ + xx[xs++] = __cy; \ + else \ + { \ + __cy = mpn_add_1(xx+ys, xx+ys, xs-ys, __cy); \ + CARRY(__cy, xx, xs); \ + } \ + } \ +} while (0) + + + +void +flint_mpn_harmonic_odd_balanced(mp_ptr t, mp_size_t * tsize, + mp_ptr v, mp_size_t * vsize, + slong a, slong b, slong n, int d); + +mp_limb_t flint_mpn_preinv1(mp_limb_t d, mp_limb_t d2); + +mp_limb_t flint_mpn_divrem_preinv1(mp_ptr q, mp_ptr a, + mp_size_t m, mp_srcptr b, mp_size_t n, mp_limb_t dinv); + +#define flint_mpn_divrem21_preinv(q, a_hi, a_lo, dinv) \ + do { \ + mp_limb_t __q2, __q3, __q4; \ + umul_ppmm((q), __q2, (a_hi), (dinv)); \ + umul_ppmm(__q3, __q4, (a_lo), (dinv)); \ + add_ssaaaa((q), __q2, (q), __q2, 0, __q3); \ + add_ssaaaa((q), __q2, (q), __q2, (a_hi), (a_lo)); \ + } while (0) + +void flint_mpn_mulmod_preinv1(mp_ptr r, + mp_srcptr a, mp_srcptr b, mp_size_t n, + mp_srcptr d, mp_limb_t dinv, ulong norm); + +void flint_mpn_preinvn(mp_ptr dinv, mp_srcptr d, mp_size_t n); + +void flint_mpn_mod_preinvn(mp_ptr r, mp_srcptr a, mp_size_t m, + mp_srcptr d, mp_size_t n, mp_srcptr dinv); + +mp_limb_t flint_mpn_divrem_preinvn(mp_ptr q, mp_ptr r, mp_srcptr a, mp_size_t m, + mp_srcptr d, mp_size_t n, mp_srcptr dinv); + +void flint_mpn_mulmod_preinvn(mp_ptr r, + mp_srcptr a, mp_srcptr b, mp_size_t n, + mp_srcptr d, mp_srcptr dinv, ulong norm); + +int flint_mpn_mulmod_2expp1_basecase(mp_ptr xp, mp_srcptr yp, mp_srcptr zp, + int c, mp_bitcnt_t b, mp_ptr tp); + +static __inline__ +void flint_mpn_rrandom(mp_limb_t *rp, gmp_randstate_t state, mp_size_t n) +{ + __mpz_struct str; + str._mp_d = rp; + str._mp_alloc = n; + str._mp_size =n; + mpz_rrandomb(&str,state,FLINT_BITS*n); +} + +static __inline__ +void flint_mpn_urandomb(mp_limb_t *rp, gmp_randstate_t state, mp_bitcnt_t n) +{ + __mpz_struct str; + str._mp_d = rp; + str._mp_alloc = (n + FLINT_BITS - 1)/FLINT_BITS; + str._mp_size = (n + FLINT_BITS - 1)/FLINT_BITS; + mpz_rrandomb(&str,state,n); +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/flint-2.4.3/mpn_extras/debug.c b/external/flint-2.4.3/mpn_extras/debug.c new file mode 100644 index 0000000..e76ab1d --- /dev/null +++ b/external/flint-2.4.3/mpn_extras/debug.c @@ -0,0 +1,50 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "mpn_extras.h" + + +void flint_mpn_debug(mp_srcptr x, mp_size_t xsize) +{ + int i, j; + char byte[9]; + byte[8] = 0; + + flint_printf("\n"); + for (i = 0; i < xsize; i++) + { + flint_printf("DIGIT %3d/%wd: ", i, xsize); + for (j = 0; j < FLINT_BITS; j++) + { + byte[j % 8] = (x[i] & (UWORD(1)< +#include +#include "flint.h" +#include "fmpz.h" +#include "mpn_extras.h" + +int flint_mpn_divides(mp_ptr q, mp_srcptr array1, + mp_size_t limbs1, mp_srcptr arrayg, mp_size_t limbsg, mp_ptr temp) +{ + mpn_tdiv_qr(q, temp, 0, array1, limbs1, arrayg, limbsg); + while ((limbsg) && temp[limbsg - 1] == 0) limbsg--; + + return (limbsg == 0); +} diff --git a/external/flint-2.4.3/mpn_extras/divrem_preinv1.c b/external/flint-2.4.3/mpn_extras/divrem_preinv1.c new file mode 100644 index 0000000..6280d55 --- /dev/null +++ b/external/flint-2.4.3/mpn_extras/divrem_preinv1.c @@ -0,0 +1,59 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "longlong.h" +#include "mpn_extras.h" + +#pragma GCC diagnostic ignored "-Wunused-variable" + +mp_limb_t flint_mpn_divrem_preinv1(mp_ptr q, mp_ptr a, mp_size_t m, + mp_srcptr b, mp_size_t n, mp_limb_t dinv) +{ + mp_limb_t ret; + mp_size_t i; + + /* ensure { a + i, n } < { b, n } */ + if ((ret = (mpn_cmp(a + m - n, b, n) >= 0))) + mpn_sub_n(a + m - n, a + m - n, b, n); + + for (i = m - 1; i >= n; i--) + { + flint_mpn_divrem21_preinv(q[i - n], a[i], a[i - 1], dinv); + a[i] -= mpn_submul_1(a + i - n, b, n, q[i - n]); + + if (mpn_cmp(a + i - n, b, n) >= 0 || a[i] != 0) + { + q[i - n]++; + a[i] -= mpn_sub_n(a + i - n, a + i - n, b, n); + } + } + + return ret; +} + +#pragma GCC diagnostic warning "-Wunused-variable" diff --git a/external/flint-2.4.3/mpn_extras/divrem_preinvn.c b/external/flint-2.4.3/mpn_extras/divrem_preinvn.c new file mode 100644 index 0000000..c6b2726 --- /dev/null +++ b/external/flint-2.4.3/mpn_extras/divrem_preinvn.c @@ -0,0 +1,120 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "longlong.h" +#include "mpn_extras.h" + +/* + TODO: speedup mpir's mullow and mulhigh and use instead of mul/mul_n +*/ + +mp_limb_t flint_mpn_divrem_preinvn(mp_ptr qp, mp_ptr rp, mp_srcptr ap, mp_size_t m, + mp_srcptr d, mp_size_t n, mp_srcptr dinv) +{ + mp_limb_t cy, hi = 0; + mp_ptr t, q, r, a; + mp_size_t size; + TMP_INIT; + + a = (mp_ptr) ap + m - 2*n; + r = rp + m - 2*n; + + /* check if top n limbs of a exceed d */ + if (mpn_cmp(a + n, d, n) >= 0) + { + mpn_sub_n(r + n, a + n, d, n); + hi = 1; + } else if (r != a) + mpn_copyi(r + n, a + n, n); + + q = qp + m - 2*n; + + TMP_START; + t = TMP_ALLOC(2*n*sizeof(mp_limb_t)); + + /* 2n by n division */ + while (m >= 2*n) + { + mpn_mul_n(t, dinv, r + n, n); + cy = mpn_add_n(q, t + n, r + n, n); + + mpn_mul_n(t, d, q, n); + cy = r[n] - t[n] - mpn_sub_n(r, a, t, n); + + while (cy > 0) + { + cy -= mpn_sub_n(r, r, d, n); + mpn_add_1(q, q, n, 1); + } + + if (mpn_cmp(r, d, n) >= 0) + { + mpn_sub_n(r, r, d, n); + mpn_add_1(q, q, n, 1); + } + + m -= n; + r -= n; + a -= n; + q -= n; + } + + size = m - n; + + /* m by n division with 2n > m > n */ + if (size) + { + if (rp != ap) + mpn_copyi(rp, ap, size); + + mpn_mul(t, dinv, n, rp + n, size); + cy = mpn_add_n(qp, t + n, rp + n, size); + + mpn_mul(t, d, n, qp, size); + if (cy) + mpn_add_n(t + size, t + size, d, n + 1 - size); + + cy = rp[n] - t[n] - mpn_sub_n(rp, rp, t, n); + + while (cy > 0) + { + cy -= mpn_sub_n(rp, rp, d, n); + mpn_add_1(qp, qp, size, 1); + } + + if (mpn_cmp(rp, d, n) >= 0) + { + mpn_sub_n(rp, rp, d, n); + mpn_add_1(qp, qp, size, 1); + } + } + + TMP_END; + + return hi; +} diff --git a/external/flint-2.4.3/mpn_extras/doc/mpn_extras.txt b/external/flint-2.4.3/mpn_extras/doc/mpn_extras.txt new file mode 100644 index 0000000..debc2ff --- /dev/null +++ b/external/flint-2.4.3/mpn_extras/doc/mpn_extras.txt @@ -0,0 +1,262 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +******************************************************************************* + + Macros + +******************************************************************************* + +MACRO MPN_NORM(a, an) + + Normalise \code{(a, an)} so that either \code{an} is zero or + \code{a[an - 1]} is nonzero. + +MACRO MPN_SWAP(a, an, b, bn) + + Swap \code{(a, an)} and \code{(b, bn)}, i.e. swap pointers and sizes. + +******************************************************************************* + + Utility functions + +******************************************************************************* + +void flint_mpn_debug(mp_srcptr x, mp_size_t xsize) + + Prints debug information about \code{(x, xsize)} to \code{stdout}. + In particular, this will print binary representations of all the limbs. + +int flint_mpn_zero_p(mp_srcptr x, mp_size_t xsize) + + Returns $1$ if all limbs of \code{(x, xsize)} are zero, otherwise $0$. + +******************************************************************************* + + Divisibility + +******************************************************************************* + +int flint_mpn_divisible_1_p(x, xsize, d) (macro) + + Expression determining whether \code{(x, xsize)} is divisible by the + \code{mp_limb_t d} which is assumed to be odd-valued and at least~$3$. + + This function is implemented as a macro. + +mp_size_t flint_mpn_divexact_1(mp_ptr x, mp_size_t xsize, mp_limb_t d) + + Divides $x$ once by a known single-limb divisor, returns the new size. + +mp_size_t flint_mpn_remove_2exp(mp_ptr x, mp_size_t xsize, mp_bitcnt_t *bits) + + Divides \code{(x, xsize)} by $2^n$ where $n$ is the number of trailing + zero bits in $x$. The new size of $x$ is returned, and $n$ is stored in + the bits argument. $x$ may not be zero. + +mp_size_t flint_mpn_remove_power_ascending(mp_ptr x, mp_size_t xsize, + mp_ptr p, mp_size_t psize, ulong *exp) + + Divides \code{(x, xsize)} by the largest power $n$ of \code{(p, psize)} + that is an exact divisor of $x$. The new size of $x$ is returned, and + $n$ is stored in the \code{exp} argument. $x$ may not be zero, and $p$ + must be greater than $2$. + + This function works by testing divisibility by ascending squares + $p, p^2, p^4, p^8, \dotsc$, making it efficient for removing potentially + large powers. Because of its high overhead, it should not be used as + the first stage of trial division. + +int +flint_mpn_factor_trial(mp_srcptr x, mp_size_t xsize, slong start, slong stop) + + Searches for a factor of \code{(x, xsize)} among the primes in positions + \code{start, ..., stop-1} of \code{flint_primes}. Returns $i$ if + \code{flint_primes[i]} is a factor, otherwise returns $0$ if no factor + is found. It is assumed that \code{start >= 1}. + +******************************************************************************* + + Division + +******************************************************************************* + +int flint_mpn_divides(mp_ptr q, mp_srcptr array1, + mp_size_t limbs1, mp_srcptr arrayg, mp_size_t limbsg, mp_ptr temp) + + If \code{(arrayg, limbsg)} divides \code{(array1, limbs1)} then + \code{(q, limbs1 - limbsg + 1)} is set to the quotient and 1 is + returned, otherwise 0 is returned. The temporary space \code{temp} + must have space for \code{limbsg} limbs. + + Assumes limbs1 \code{limbs1 >= limbsg > 0}. + +mp_limb_t flint_mpn_preinv1(mp_limb_t d, mp_limb_t d2) + + Computes a precomputed inverse from the leading two limbs of the + divisor \code{b, n} to be used with the \code{preinv1} functions. + We require the most significant bit of \code{b, n} to be 1. + +mp_limb_t flint_mpn_divrem_preinv1(mp_ptr q, mp_ptr a, + mp_size_t m, mp_srcptr b, mp_size_t n, mp_limb_t dinv) + + Divide \code{a, m} by \code{b, n}, returning the high limb of the + quotient (which will either be 0 or 1), storing the remainder in-place + in \code{a, n} and the rest of the quotient in \code{q, m - n}. + We require the most significant bit of \code{b, n} to be 1. + dinv must be computed from \code{b[n - 1]}, \code{b[n - 2]} by + \code{flint_mpn_preinv1}. We also require \code{m >= n >= 2}. + +void flint_mpn_mulmod_preinv1(mp_ptr r, + mp_srcptr a, mp_srcptr b, mp_size_t n, + mp_srcptr d, mp_limb_t dinv, ulong norm) + + Given a normalised integer $d$ with precomputed inverse \code{dinv} + provided by \code{flint_mpn_preinv1}, computes $ab \pmod{d}$ and + stores the result in $r$. Each of $a$, $b$ and $r$ is expected to + have $n$ limbs of space, with zero padding if necessary. + + The value \code{norm} is provided for convenience. If $a$, $b$ and + $d$ have been shifted left by \code{norm} bits so that $d$ is + normalised, then $r$ will be shifted right by \code{norm} bits + so that it has the same shift as all the inputs. + + We require $a$ and $b$ to be reduced modulo $n$ before calling the + function. + +void flint_mpn_preinvn(mp_ptr dinv, mp_srcptr d, mp_size_t n) + + Compute an $n$ limb precomputed inverse \code{dinv} of the $n$ limb + integer $d$. + + We require that $d$ is normalised, i.e. with the most significant + bit of the most significant limb set. + +void flint_mpn_mod_preinvn(mp_ptr r, mp_srcptr a, mp_size_t m, + mp_srcptr d, mp_size_t n, mp_srcptr dinv) + + Given a normalised integer $d$ of $n$ limbs, with precomputed inverse + \code{dinv} provided by \code{flint_mpn_preinvn} and integer $a$ of $m$ + limbs, computes $a \pmod{d}$ and stores the result in-place in the lower + $n$ limbs of $a$. The remaining limbs of $a$ are destroyed. + + We require $m \geq n$. No aliasing of $a$ with any of the other operands + is permitted. + + Note that this function is not always as fast as ordinary division. + +mp_limb_t flint_mpn_divrem_preinvn(mp_ptr q, mp_ptr r, mp_srcptr a, + mp_size_t m, mp_srcptr d, mp_size_t n, mp_srcptr dinv) + + Given a normalised integer $d$ with precomputed inverse \code{dinv} + provided by \code{flint_mpn_preinvn}, computes the quotient of $a$ by $d$ + and stores the result in $q$ and the remainder in the lower $n$ limbs of + $a$. The remaining limbs of $a$ are destroyed. + + The value $q$ is expected to have space for $m - n$ limbs and we require + $m >= n$. No aliasing is permitted between $q$ and $a$ or between these + and any of the other operands. + + Note that this function is not always as fast as ordinary division. + +void flint_mpn_mulmod_preinvn(mp_ptr r, + mp_srcptr a, mp_srcptr b, mp_size_t n, + mp_srcptr d, mp_srcptr dinv, ulong norm) + + Given a normalised integer $d$ with precomputed inverse \code{dinv} + provided by \code{flint_mpn_preinvn}, computes $ab \pmod{d}$ and + stores the result in $r$. Each of $a$, $b$ and $r$ is expected to + have $n$ limbs of space, with zero padding if necessary. + + The value \code{norm} is provided for convenience. If $a$, $b$ and + $d$ have been shifted left by \code{norm} bits so that $d$ is + normalised, then $r$ will be shifted right by \code{norm} bits + so that it has the same shift as all the inputs. + + We require $a$ and $b$ to be reduced modulo $n$ before calling the + function. + + Note that this function is not always as fast as ordinary division. + +******************************************************************************* + + GCD + +******************************************************************************* + +mp_size_t flint_mpn_gcd_full(mp_ptr arrayg, + mp_ptr array1, mp_size_t limbs1, mp_ptr array2, mp_size_t limbs2) + + Sets \code{(arrayg, retvalue)} to the gcd of \code{(array1, limbs1)} and + \code{(array2, limbs2)}. + + The only assumption is that neither \code{limbs1} or \code{limbs2} is + zero. + +******************************************************************************* + + Special numbers + +******************************************************************************* + +void flint_mpn_harmonic_odd_balanced(mp_ptr t, mp_size_t * tsize, + mp_ptr v, mp_size_t * vsize, + slong a, slong b, slong n, int d) + + Computes \code{(t,tsize)} and \code{(v,vsize)} such that + $t/v = H_n = 1 + 1/2 + \dotsb + 1/n$. + The computation is performed using recursive balanced summation + over the odd terms. The resulting fraction will not generally be + normalized. At the top level, this function should be called with + $n > 0$, $a = 1$, $b = n$, and $d = 1$. + + Enough space should be allocated for $t$ and $v$ to fit the entire sum + $1 + 1/2 + \dotsb + 1/n$ computed without normalization; i.e.\ $t$ and $v$ + should have room to fit $n!$ plus one extra limb. + + +******************************************************************************* + + Random Number Generation + +******************************************************************************* + +void flint_mpn_rrandom(mp_limb_t *rp, + gmp_randstate_t state, mp_size_t n) + + Generates a random number with \code{n} limbs and stores + it on \code{rp}. The number it generates will tend to have + long strings of zeros and ones in the binary representation. + + Useful for testing functions and algorithms, since this kind of random + numbers have proven to be more likely to trigger corner-case bugs. + + +void flint_mpn_urandomb(mp_limb_t *rp, + gmp_randstate_t state, mp_bitcnt_t n) + + Generates a uniform random number \code{n} bits and stores + it on \code{rp}. + diff --git a/external/flint-2.4.3/mpn_extras/factor_trial.c b/external/flint-2.4.3/mpn_extras/factor_trial.c new file mode 100644 index 0000000..9966928 --- /dev/null +++ b/external/flint-2.4.3/mpn_extras/factor_trial.c @@ -0,0 +1,48 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "mpn_extras.h" +#include "ulong_extras.h" + + +int flint_mpn_factor_trial(mp_srcptr x, mp_size_t xsize, slong start, slong stop) +{ + slong i; + const mp_limb_t * primes; + + primes = n_primes_arr_readonly(stop); + + for (i = start; i < stop; i++) + { + if (flint_mpn_divisible_1_p(x, xsize, primes[i])) + return i; + } + return 0; +} diff --git a/external/flint-2.4.3/mpn_extras/gcd_full.c b/external/flint-2.4.3/mpn_extras/gcd_full.c new file mode 100644 index 0000000..269feca --- /dev/null +++ b/external/flint-2.4.3/mpn_extras/gcd_full.c @@ -0,0 +1,91 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "mpn_extras.h" + +mp_size_t flint_mpn_gcd_full(mp_ptr arrayg, + mp_ptr array1, mp_size_t limbs1, mp_ptr array2, mp_size_t limbs2) +{ + mp_size_t s1 = 0, s2 = 0, m, b1, b2, mb, len1, len2, leng; + mp_ptr in1, in2; + mp_limb_t cy; + + /* find maximum power of 2 dividing inputs */ + b1 = mpn_scan1(array1 + s1, 0); + b2 = mpn_scan1(array2 + s2, 0); + + /* get bit shifts [0, FLINT_BITS) and limb shifts */ + mb = FLINT_MIN(b1, b2) % FLINT_BITS; + s1 = b1 / FLINT_BITS; b1 = b1 % FLINT_BITS; len1 = limbs1 - s1; + s2 = b2 / FLINT_BITS; b2 = b2 % FLINT_BITS; len2 = limbs2 - s2; + m = FLINT_MIN(s1, s2); + + /* this many output limbs will be zero */ + flint_mpn_zero(arrayg, m); + + /* set in1 to shifted array1 */ + if (b1 == 0) + in1 = array1 + s1; + else + { + in1 = flint_malloc(len1*sizeof(mp_limb_t)); + mpn_rshift(in1, array1 + s1, len1, b1); + len1 -= (in1[len1 - 1] == 0); + } + + /* set in2 to shifted array2 */ + if (b2 == 0) + in2 = array2 + s2; + else + { + in2 = flint_malloc(len2*sizeof(mp_limb_t)); + mpn_rshift(in2, array2 + s2, len2, b2); + len2 -= (in2[len2 - 1] == 0); + } + + /* compute gcd of shifted values */ + if (len1 >= len2) + leng = mpn_gcd(arrayg + m, in1, len1, in2, len2); + else + leng = mpn_gcd(arrayg + m, in2, len2, in1, len1); + + if (mb) /* shift back by mb bits */ + { + cy = mpn_lshift(arrayg + m, arrayg + m, leng, mb); + if (cy) + arrayg[m + leng++] = cy; + } + + /* clean up */ + if (b1) flint_free(in1); + if (b2) flint_free(in2); + + /* return total number of limbs in output */ + return m + leng; +} diff --git a/external/flint-2.4.3/mpn_extras/harmonic.c b/external/flint-2.4.3/mpn_extras/harmonic.c new file mode 100644 index 0000000..a0c962f --- /dev/null +++ b/external/flint-2.4.3/mpn_extras/harmonic.c @@ -0,0 +1,190 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "mpn_extras.h" + +/* +The basic approach to compute H(n) quickly is to use a balanced sum +S(a,b) = S(a,m) + S(m,b) where m = floor((a+b)/2), analogous to using a +balanced product for n factorial. To reduce overhead, we can work with +unnormalized numerators and denominators and perform a final GCD reduction +only at the end. In fact, this way the computation of the denominator +(before the final GCD reduction) exactly amounts to a balanced product +for n factorial. + +To save some more time, we note that we only have to sum over the odd +terms since H(n) = H(floor(n/2))/2 + H_odd(n). Recursive application of this +formula results in a geometric series for the weight of each odd term 1/k: + + n/2 < k <= n : weight 1 + n/4 < k <= n/2 : weight 3/2 + n/8 < k <= n/4 : weight 7/4 + n/16 < k <= n/8 : weight 15/8 + ... + n/2^d < k <= n/2^(d-1) : weight (2^d-1)/2^(d-1) + +Although not necessary, the implementation is simplified by always splitting +the interval exactly in half, since we then just have to increment d on every +subinterval that starts with a = 1. Below a threshold, we fall back to direct +summation of the odd fractions. + +A basic Python implementation: + +def harmonic_odd_direct(a, b, n, d): + t, v = 0, 1 + if a == 1: + for k in range(b-1-(b%2), 0, -2): + while k <= (n >> d): + d += 1 + r = 2**(d-1)*k + t, v = ((2**d-1)*v + r*t), r*v + return t, v + else: + a += (a % 2 == 0) + for k in range(a, b, 2): + t, v = (v+k*t), k*v + return (2**d - 1) * t, 2**(d-1) * v + +def harmonic_odd_balanced(a, b, n, d): + if b - a < 50: + return harmonic_odd_direct(a, b, n, d) + m = (a+b) // 2 + t, v = harmonic_odd_balanced(a, m, n, d + (a==1)) + u, w = harmonic_odd_balanced(m, b, n, d) + return (t*w + u*v), v*w + +def harmonic(n): + return harmonic_odd_balanced(1, n+1, n, 1) + +Note on memory allocation: + +The maximum size in bits required for each partial numerator/denominator +between a and b can be bounded by bits(n)*(b-a+2), since each +denominator product is bounded by bits(n)*(b-a+1) and H_n is bounded +in magnitude by bits(n). This assumes that we don't introduce any spurious +factors. + +Some more optimization is possible: ++ At the bottom level, we could add two terms in one step most of the + time since 1/k + 1/(k+2) will usually have single-limb + numerator and denominator. ++ More generally, we could remove multiples of 3, 5, ... from the summation, + although this would result in a considerably more complicated algorithm, and + the returns would probably diminish quickly. ++ Some more trailing zeros could be eliminated from numerators/denominators. + However, these account for less than 1% of the operand sizes for reasonably + large inputs. ++ It may be faster to normalize some of the partial sums. ++ The memory management could be improved. + +*/ + +void +flint_mpn_harmonic_odd_direct(mp_ptr t, mp_size_t * tsize, + mp_ptr v, mp_size_t * vsize, + slong a, slong b, slong n, int d) +{ + mp_size_t ts, vs; + + *t = UWORD(0); + *v = UWORD(1); + ts = 1; + vs = 1; + + if (a == 1) + { + mp_limb_t r, s; + slong k; + for (k = b - 1 - (b % 2); k > 0; k -= 2) + { + while (k <= (n >> d)) + d += 1; + r = ((mp_limb_t) k) << (d-1); + s = (UWORD(1) << d) - UWORD(1); + MPN_MUL_1(t, ts, t, ts, r); + MPN_ADDMUL_1(t, ts, v, vs, s); + MPN_MUL_1(v, vs, v, vs, r); + } + } + else + { + a += (a % 2 == 0); + for ( ; a < b; a += 2) + { + MPN_MUL_1(t, ts, t, ts, a); + MPN_ADD(t, ts, t, ts, v, vs); + MPN_MUL_1(v, vs, v, vs, a); + } + MPN_MUL_1(t, ts, t, ts, (UWORD(1)< +#include +#include "flint.h" +#include "longlong.h" +#include "mpn_extras.h" + +/* + TODO: speedup mpir's mullow and mulhigh and use instead of mul/mul_n +*/ + +void flint_mpn_mod_preinvn(mp_ptr rp, mp_srcptr ap, mp_size_t m, + mp_srcptr d, mp_size_t n, mp_srcptr dinv) +{ + mp_limb_t cy; + mp_ptr t, r, a; + mp_size_t size; + TMP_INIT; + + a = (mp_ptr) ap + m - 2*n; + r = rp + m - 2*n; + + /* check if top n limbs of a exceed d */ + if (mpn_cmp(a + n, d, n) >= 0) + mpn_sub_n(r + n, a + n, d, n); + else if (r != a) + mpn_copyi(r + n, a + n, n); + + TMP_START; + t = TMP_ALLOC(3*n*sizeof(mp_limb_t)); + + /* 2n by n division */ + while (m >= 2*n) + { + mpn_mul_n(t, dinv, r + n, n); + cy = mpn_add_n(t + 2*n, t + n, r + n, n); + + mpn_mul_n(t, d, t + 2*n, n); + cy = r[n] - t[n] - mpn_sub_n(r, a, t, n); + + while (cy > 0) + cy -= mpn_sub_n(r, r, d, n); + + if (mpn_cmp(r, d, n) >= 0) + mpn_sub_n(r, r, d, n); + + m -= n; + r -= n; + a -= n; + } + + size = m - n; + + /* m by n division with 2n > m > n */ + if (size) + { + if (rp != ap) + mpn_copyi(rp, ap, size); + + mpn_mul(t, dinv, n, rp + n, size); + cy = mpn_add_n(t + 2*n, t + n, rp + n, size); + + mpn_mul(t, d, n, t + 2*n, size); + if (cy) + mpn_add_n(t + size, t + size, d, n + 1 - size); + + cy = rp[n] - t[n] - mpn_sub_n(rp, rp, t, n); + + while (cy > 0) + cy -= mpn_sub_n(rp, rp, d, n); + + if (mpn_cmp(rp, d, n) >= 0) + mpn_sub_n(rp, rp, d, n); + } + + TMP_END; +} diff --git a/external/flint-2.4.3/mpn_extras/mulmod_2expp1_basecase.c b/external/flint-2.4.3/mpn_extras/mulmod_2expp1_basecase.c new file mode 100644 index 0000000..767846d --- /dev/null +++ b/external/flint-2.4.3/mpn_extras/mulmod_2expp1_basecase.c @@ -0,0 +1,115 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright 2009 Jason Moxham + +******************************************************************************/ + +#include "gmp.h" +#include "flint.h" +#include "mpn_extras.h" + +/* ret + (xp,n) = (yp,n)*(zp,n) % 2^b+1 + needs (tp,2n) temp space, everything reduced mod 2^b + inputs, outputs are fully reduced + NOTE: 2n is not the same as 2b rounded up to nearest limb +*/ +static __inline__ int +flint_mpn_mulmod_2expp1_internal(mp_ptr xp, mp_srcptr yp, mp_srcptr zp, + mp_bitcnt_t b, mp_ptr tp) +{ + mp_size_t n, k; + mp_limb_t c; + + n = BITS_TO_LIMBS(b); + k = GMP_NUMB_BITS * n - b; + + mpn_mul_n(tp, yp, zp, n); + + if (k == 0) + { + c = mpn_sub_n(xp, tp, tp + n, n); + return mpn_add_1 (xp, xp, n, c); + } + + c = tp[n - 1]; + tp[n - 1] &= GMP_NUMB_MASK >> k; + +#if HAVE_NATIVE_mpn_sublsh_nc + c = mpn_sublsh_nc (xp, tp, tp + n, n, k, c); +#else + { + mp_limb_t c1; + c1 = mpn_lshift (tp + n, tp + n, n, k); + tp[n] |= c >> (GMP_NUMB_BITS - k); + c = mpn_sub_n (xp, tp, tp + n, n) + c1; + } +#endif + c = mpn_add_1 (xp, xp, n, c); + xp[n - 1] &= GMP_NUMB_MASK >> k; + return c; +} + +/* c is the top bits of the inputs, must be fully reduced */ +int +flint_mpn_mulmod_2expp1_basecase (mp_ptr xp, mp_srcptr yp, mp_srcptr zp, int c, + mp_bitcnt_t b, mp_ptr tp) +{ + int cy, cz; + mp_size_t n, k; + + cy = c & 2; + cz = c & 1; + n = BITS_TO_LIMBS(b); + k = GMP_NUMB_BITS * n - b; + + if (cy == 0) + { + if (cz == 0) + { + c = flint_mpn_mulmod_2expp1_internal(xp, yp, zp, b, tp); + } + else + { + c = mpn_neg_n(xp, yp, n); + c = mpn_add_1 (xp, xp, n, c); + xp[n - 1] &= GMP_NUMB_MASK >> k; + } + } + else + { + if (cz == 0) + { + c = mpn_neg_n(xp, zp, n); + c = mpn_add_1(xp, xp, n, c); + xp[n - 1] &= GMP_NUMB_MASK >> k; + } + else + { + c = 0; + xp[0] = 1; + flint_mpn_zero(xp + 1, n - 1); + } + } + + return c; +} + diff --git a/external/flint-2.4.3/mpn_extras/mulmod_preinv1.c b/external/flint-2.4.3/mpn_extras/mulmod_preinv1.c new file mode 100644 index 0000000..0b35bf7 --- /dev/null +++ b/external/flint-2.4.3/mpn_extras/mulmod_preinv1.c @@ -0,0 +1,67 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "longlong.h" +#include "mpn_extras.h" + +#pragma GCC diagnostic ignored "-Wunused-variable" + +void flint_mpn_mulmod_preinv1(mp_ptr r, + mp_srcptr a, mp_srcptr b, mp_size_t n, + mp_srcptr d, mp_limb_t dinv, ulong norm) +{ + mp_limb_t q; + mp_limb_t ts[150]; + mp_ptr t; + slong i; + + if (n <= 30) + t = ts; + else + t = flint_malloc(5*n*sizeof(mp_limb_t)); + + mpn_mul_n(t, a, b, n); + if (norm) + mpn_rshift(t, t, 2*n, norm); + + for (i = 2*n - 1; i >= n; i--) + { + flint_mpn_divrem21_preinv(q, t[i], t[i - 1], dinv); + t[i] -= mpn_submul_1(t + i - n, d, n, q); + + if (mpn_cmp(t + i - n, d, n) >= 0 || t[i] != 0) + { + q++; + t[i] -= mpn_sub_n(t + i - n, t + i - n, d, n); + } + } + + mpn_copyi(r, t, n); +} + +#pragma GCC diagnostic warning "-Wunused-variable" diff --git a/external/flint-2.4.3/mpn_extras/mulmod_preinvn.c b/external/flint-2.4.3/mpn_extras/mulmod_preinvn.c new file mode 100644 index 0000000..e1ec2b5 --- /dev/null +++ b/external/flint-2.4.3/mpn_extras/mulmod_preinvn.c @@ -0,0 +1,64 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "longlong.h" +#include "mpn_extras.h" + +/* + TODO: speedup mpir's mullow and mulhigh and use instead of mul/mul_n +*/ + +void flint_mpn_mulmod_preinvn(mp_ptr r, + mp_srcptr a, mp_srcptr b, mp_size_t n, + mp_srcptr d, mp_srcptr dinv, ulong norm) +{ + mp_limb_t cy; + mp_ptr t; + TMP_INIT; + + TMP_START; + t = TMP_ALLOC(5*n*sizeof(mp_limb_t)); + + mpn_mul_n(t, a, b, n); + if (norm) + mpn_rshift(t, t, 2*n, norm); + + mpn_mul_n(t + 3*n, t + n, dinv, n); + mpn_add_n(t + 4*n, t + 4*n, t + n, n); + + mpn_mul_n(t + 2*n, t + 4*n, d, n); + cy = t[n] - t[3*n] - mpn_sub_n(r, t, t + 2*n, n); + + while (cy > 0) + cy -= mpn_sub_n(r, r, d, n); + + if (mpn_cmp(r, d, n) >= 0) + mpn_sub_n(r, r, d, n); + + TMP_END; +} diff --git a/external/flint-2.4.3/mpn_extras/preinv1.c b/external/flint-2.4.3/mpn_extras/preinv1.c new file mode 100644 index 0000000..ee49c98 --- /dev/null +++ b/external/flint-2.4.3/mpn_extras/preinv1.c @@ -0,0 +1,60 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "longlong.h" +#include "mpn_extras.h" + +mp_limb_t flint_mpn_preinv1(mp_limb_t d1, mp_limb_t d2) +{ + mp_limb_t q, r[2], p[2], cy; + + if (d2 + 1 == 0 && d1 + 1 == 0) + return 0; + + if (d1 + 1 == 0) + q = ~d1, r[1] = ~d2; + else + udiv_qrnnd(q, r[1], ~d1, ~d2, d1 + 1); + + if (d2 + 1 == 0) + return q; + + r[0] = 0; + + umul_ppmm(p[1], p[0], q, ~d2); + cy = mpn_add_n(r, r, p, 2); + + p[0] = d2 + 1, p[1] = d1 + (d2 + 1 == 0); + while (cy || mpn_cmp(r, p, 2) >= 0) + { + q++; + cy -= mpn_sub_n(r, r, p, 2); + } + + return q; +} diff --git a/external/flint-2.4.3/mpn_extras/preinvn.c b/external/flint-2.4.3/mpn_extras/preinvn.c new file mode 100644 index 0000000..cb3ed01 --- /dev/null +++ b/external/flint-2.4.3/mpn_extras/preinvn.c @@ -0,0 +1,56 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "longlong.h" +#include "mpn_extras.h" + +void flint_mpn_preinvn(mp_ptr dinv, mp_srcptr d, mp_size_t n) +{ + mp_ptr q, r, d1; + + d1 = flint_malloc(n*sizeof(mp_limb_t)); + if (mpn_add_1(d1, d, n, 1)) /* check for d + 1 == 0 */ + { + mpn_zero(dinv, n); + flint_free(d1); + return; + } + + r = flint_malloc((2*n + 1)*sizeof(mp_limb_t)); + q = flint_malloc((n + 2)*sizeof(mp_limb_t)); + + mpn_zero(r, 2*n); + r[2*n] = 1; + + mpn_tdiv_qr(q, r, 0, r, 2*n + 1, d1, n); + mpn_copyi(dinv, q, n); + + flint_free(r); + flint_free(q); + flint_free(d1); +} diff --git a/external/flint-2.4.3/mpn_extras/profile/p-mulmod_preinvn.c b/external/flint-2.4.3/mpn_extras/profile/p-mulmod_preinvn.c new file mode 100644 index 0000000..70ef816 --- /dev/null +++ b/external/flint-2.4.3/mpn_extras/profile/p-mulmod_preinvn.c @@ -0,0 +1,169 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 William Hart + +******************************************************************************/ + +#include +#include +#include +#include +#include "profiler.h" +#include "flint.h" +#include "longlong.h" +#include "mpn_extras.h" +#include "ulong_extras.h" + +#define mock_mulmod_preinvn(rxx, axx, bxx, nnn, nxx, ninv, norm) \ + do { \ + mp_ptr __t; \ + TMP_INIT; \ + \ + TMP_START; \ + __t = TMP_ALLOC(3*(nnn)*sizeof(mp_limb_t)); \ + \ + mpn_mul_n(__t, axx, bxx, nnn); \ + if (norm) \ + mpn_rshift(__t, __t, 2*(nnn), norm); \ + \ + mpn_tdiv_qr(__t + 2*(nnn), rxx, 0, __t, 2*(nnn), nxx, nnn); \ + TMP_END; \ + } while (0) + +typedef struct +{ + slong limbs; + int algo; +} info_t; + +void sample(void * arg, ulong count) +{ + info_t * info = (info_t *) arg; + slong size = info->limbs, i, j; + int algo = info->algo; + int scale = 200; + + mpz_t a, b, d, r2; + + gmp_randstate_t st; + FLINT_TEST_INIT(state); + + mp_ptr dinv; + mp_bitcnt_t norm; + + mpz_init(a); + mpz_init(b); + mpz_init(d); + /* don't init r2 */ + + gmp_randinit_default(st); + + + for (i = 0; i < count; i++) + { + mpz_rrandomb(a, st, size*FLINT_BITS); + mpz_rrandomb(b, st, size*FLINT_BITS); + do { + mpz_rrandomb(d, st, size*FLINT_BITS); + } while (mpz_sgn(d) == 0); + + /* reduce a, b mod d */ + mpz_fdiv_r(a, a, d); + mpz_fdiv_r(b, b, d); + + /* normalise */ + count_leading_zeros(norm, d->_mp_d[d->_mp_size - 1]); + mpz_mul_2exp(a, a, norm); + mpz_mul_2exp(b, b, norm); + mpz_mul_2exp(d, d, norm); + + dinv = flint_malloc(size*sizeof(mp_limb_t)); + flint_mpn_preinvn(dinv, d->_mp_d, size); + + r2->_mp_d = flint_malloc(size*sizeof(mp_limb_t)); + + prof_start(); + if (algo == 1) + { + for (j = 0; j < scale; j++) + { + flint_mpn_mulmod_preinvn(r2->_mp_d, a->_mp_d, b->_mp_d, size, d->_mp_d, dinv, norm); + } + } else + { + for (j = 0; j < scale; j++) + { + mock_mulmod_preinvn(r2->_mp_d, a->_mp_d, b->_mp_d, size, d->_mp_d, dinv, norm); + } + } + prof_stop(); + + flint_free(r2->_mp_d); + flint_free(dinv); + } + + mpz_clear(a); + mpz_clear(b); + mpz_clear(d); + /* don't init r2 */ + + gmp_randclear(st); + flint_randclear(state); +} + +int main(void) +{ + double min, max; + info_t info; + slong k, scale; + + printf("1: With precomputed inverse\n"); + printf("2: Without precomputed inverse\n\n"); + + for (k = 1; k <= 10000; k = (slong) ceil(1.1*k)) + { + info.limbs = k; + info.algo = 1; + + scale = 200; + + prof_repeat(&min, &max, sample, (void *) &info); + + flint_printf("1: limbs %wd, min %.3g ms, max %.3g ms\n", + info.limbs, + ((min/(double)FLINT_CLOCK_SCALE_FACTOR)/scale)/2400000.0, + ((max/(double)FLINT_CLOCK_SCALE_FACTOR)/scale)/2400000.0 + ); + + info.algo = 2; + + prof_repeat(&min, &max, sample, (void *) &info); + + flint_printf("2: limbs %wd, min %.3g ms, max %.3g ms\n\n", + info.limbs, + ((min/(double)FLINT_CLOCK_SCALE_FACTOR)/scale)/2400000.0, + ((max/(double)FLINT_CLOCK_SCALE_FACTOR)/scale)/2400000.0 + ); + } + + return 0; +} diff --git a/external/flint-2.4.3/mpn_extras/remove_2exp.c b/external/flint-2.4.3/mpn_extras/remove_2exp.c new file mode 100644 index 0000000..0641c7a --- /dev/null +++ b/external/flint-2.4.3/mpn_extras/remove_2exp.c @@ -0,0 +1,56 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "mpn_extras.h" + + +mp_size_t flint_mpn_remove_2exp(mp_ptr x, mp_size_t xsize, mp_bitcnt_t *bits) +{ + mp_size_t shift_limbs, reduced_size; + mp_bitcnt_t shift_bits; + + *bits = mpn_scan1(x, 0); + + if (*bits == 0) + return xsize; + + shift_limbs = *bits / FLINT_BITS; + shift_bits = *bits % FLINT_BITS; + reduced_size = xsize - shift_limbs; + + if (shift_bits) + { + mpn_rshift(x, x + shift_limbs, reduced_size, shift_bits); + if (x[reduced_size - 1] == 0) + reduced_size -= 1; + } + else + { + flint_mpn_copyi(x, x + shift_limbs, reduced_size); + } + return reduced_size; +} diff --git a/external/flint-2.4.3/mpn_extras/remove_power.c b/external/flint-2.4.3/mpn_extras/remove_power.c new file mode 100644 index 0000000..ed02108 --- /dev/null +++ b/external/flint-2.4.3/mpn_extras/remove_power.c @@ -0,0 +1,107 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "mpn_extras.h" + + +mp_size_t flint_mpn_remove_power_ascending(mp_ptr x, mp_size_t xsize, + mp_ptr p, mp_size_t psize, ulong *exp) +{ + int i, maxi; + mp_ptr div; + mp_ptr rem; + mp_ptr square[FLINT_BITS]; + mp_size_t square_size[FLINT_BITS]; + mp_size_t sqsize; + + *exp = 0; + + if (psize > xsize) + return xsize; + + maxi = 0; + square[0] = p; + square_size[0] = psize; + + /* Most likely less memory will be needed, but this way we + avoid reallocations */ + div = flint_malloc(sizeof(mp_limb_t) * xsize); + rem = flint_malloc(sizeof(mp_limb_t) * xsize); + + /* Remove ascending powers */ + for (i = 0; i < FLINT_BITS && xsize >= square_size[i]; i++) + { + mpn_tdiv_qr(div, rem, 0, x, xsize, square[i], square_size[i]); + if (!flint_mpn_zero_p(rem, square_size[i])) + { + i -= 1; + break; + } + + *exp += (1 << i); + xsize = xsize - square_size[i] + 1; + if (div[xsize-1] == 0) + xsize--; + flint_mpn_copyi(x, div, xsize); + + /* Form next square if needed */ + sqsize = square_size[i] * 2; + if (sqsize - 1 > xsize) + break; + maxi = i + 1; + square[i + 1] = flint_malloc(sizeof(mp_limb_t) * sqsize); + mpn_sqr(square[i + 1], square[i], square_size[i]); + if (square[i + 1][sqsize - 1] == 0) + sqsize -= 1; + square_size[i + 1] = sqsize; + } + + /* Remove descending powers */ + for ( ; i >= 0; i--) + { + if (xsize >= square_size[i]) + { + mpn_tdiv_qr(div, rem, 0, x, xsize, square[i], square_size[i]); + if (flint_mpn_zero_p(rem, square_size[i])) + { + *exp += (1 << i); + xsize = xsize - square_size[i] + 1; + if (div[xsize-1] == 0) + xsize--; + flint_mpn_copyi(x, div, xsize); + } + } + } + + for (i = 1; i <= maxi; i++) + flint_free(square[i]); + flint_free(div); + flint_free(rem); + return xsize; +} diff --git a/external/flint-2.4.3/mpn_extras/test/t-divides.c b/external/flint-2.4.3/mpn_extras/test/t-divides.c new file mode 100644 index 0000000..46bbd1b --- /dev/null +++ b/external/flint-2.4.3/mpn_extras/test/t-divides.c @@ -0,0 +1,136 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "mpn_extras.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + mpz_t a, b, c, g, s; + mp_ptr temp; + gmp_randstate_t st; + FLINT_TEST_INIT(state); + + flint_printf("divides...."); + fflush(stdout); + + mpz_init(a); + mpz_init(b); + mpz_init(c); + mpz_init(s); + /* don't init g */ + gmp_randinit_default(st); + + + /* check if b divides a*b */ + for (i = 0; i < 10000; i++) + { + do { + mpz_urandomb(a, st, n_randint(state, 200)); + } while (mpz_sgn(a) == 0); + do { + mpz_urandomb(b, st, n_randint(state, 200)); + } while (mpz_sgn(b) == 0); + do { + mpz_urandomb(c, st, n_randint(state, 200)); + } while (mpz_sgn(c) == 0); + + mpz_mul(c, a, b); + + g->_mp_d = flint_malloc((c->_mp_size - b->_mp_size + 1)*sizeof(mp_limb_t)); + temp = flint_malloc(b->_mp_size * sizeof(mp_limb_t)); + + result = flint_mpn_divides(g->_mp_d, c->_mp_d, c->_mp_size, b->_mp_d, b->_mp_size, temp); + g->_mp_size = c->_mp_size - b->_mp_size + 1; + g->_mp_size -= (g->_mp_d[g->_mp_size - 1] == 0); + + result &= (mpz_cmp(g, a) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("%Zd\n", c); + gmp_printf("%Zd\n", a); + gmp_printf("%Zd\n", b); + abort(); + } + + flint_free(g->_mp_d); + flint_free(temp); + } + + /* check b does not divide a*b + s for s < b */ + for (i = 0; i < 10000; i++) + { + do { + mpz_urandomb(a, st, n_randint(state, 200)); + } while (mpz_sgn(a) == 0); + do { + mpz_urandomb(b, st, n_randint(state, 200) + 2); + } while (mpz_sgn(b) == 0 || b->_mp_size == 1); + do { + mpz_urandomb(c, st, n_randint(state, 200)); + } while (mpz_sgn(c) == 0); + do { + mpz_urandomb(s, st, n_randint(state, b->_mp_size)); + } while (mpz_sgn(s) == 0); + + mpz_mul(c, a, b); + mpz_add(c, c, s); + + g->_mp_d = flint_malloc((c->_mp_size - b->_mp_size + 1)*sizeof(mp_limb_t)); + temp = flint_malloc(b->_mp_size * sizeof(mp_limb_t)); + + result = !flint_mpn_divides(g->_mp_d, c->_mp_d, c->_mp_size, b->_mp_d, b->_mp_size, temp); + + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("%Zd\n", c); + gmp_printf("%Zd\n", a); + gmp_printf("%Zd\n", b); + gmp_printf("%Zd\n", s); + abort(); + } + + flint_free(g->_mp_d); + flint_free(temp); + } + + mpz_clear(a); + mpz_clear(b); + mpz_clear(c); + mpz_clear(s); + /* don't clear g */ + gmp_randclear(st); + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/mpn_extras/test/t-divrem_preinv1.c b/external/flint-2.4.3/mpn_extras/test/t-divrem_preinv1.c new file mode 100644 index 0000000..c3eb3ab --- /dev/null +++ b/external/flint-2.4.3/mpn_extras/test/t-divrem_preinv1.c @@ -0,0 +1,118 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "mpn_extras.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + mpz_t a, a2, b, q, r, q2; + gmp_randstate_t st; + mp_limb_t d1, d2, inv; + slong s1, s2; + + FLINT_TEST_INIT(state); + + flint_printf("divrem_preinv1...."); + fflush(stdout); + + mpz_init(a); + mpz_init(a2); + mpz_init(b); + mpz_init(q); + mpz_init(r); + + gmp_randinit_default(st); + + for (i = 0; i < 10000; i++) + { + do { + mpz_rrandomb(a, st, n_randint(state, 200)); + do { + mpz_rrandomb(b, st, n_randint(state, 200)); + } while (mpz_sgn(b) == 0); + + s1 = a->_mp_size; + s2 = b->_mp_size; + } while (s1 < s2 || s2 < 2); + + mpz_set(a2, a); + + /* normalise b */ + b->_mp_d[b->_mp_size - 1] |= ((mp_limb_t) 1 << (GMP_LIMB_BITS - 1)); + + d1 = b->_mp_d[b->_mp_size - 1]; + d2 = b->_mp_d[b->_mp_size - 2]; + + mpz_fdiv_qr(q, r, a, b); + + inv = flint_mpn_preinv1(d1, d2); + + q2->_mp_d = flint_malloc((s1 - s2 + 1)*sizeof(mp_limb_t)); + + q2->_mp_d[s1 - s2] = flint_mpn_divrem_preinv1(q2->_mp_d, a2->_mp_d, a2->_mp_size, b->_mp_d, b->_mp_size, inv); + + /* normalise */ + s1 -= (s2 - 1); + while (s1 && q2->_mp_d[s1 - 1] == 0) s1--; + q2->_mp_size = s1; + q2->_mp_alloc = s1; + + while (s2 && a2->_mp_d[s2 - 1] == 0) s2--; + a2->_mp_size = s2; + + result = (mpz_cmp(q, q2) == 0 && mpz_cmp(a2, r) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("%Zd\n", a); + gmp_printf("%Zd\n", b); + gmp_printf("%Zd\n", q); + gmp_printf("%Zd\n", r); + gmp_printf("%Zd\n", q2); + gmp_printf("%Zd\n", a2); + abort(); + } + + flint_free(q2->_mp_d); + } + + mpz_clear(a); + mpz_clear(a2); + mpz_clear(b); + mpz_clear(q); + mpz_clear(r); + /* don't clear g */ + gmp_randclear(st); + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/mpn_extras/test/t-divrem_preinvn.c b/external/flint-2.4.3/mpn_extras/test/t-divrem_preinvn.c new file mode 100644 index 0000000..bdf5dbb --- /dev/null +++ b/external/flint-2.4.3/mpn_extras/test/t-divrem_preinvn.c @@ -0,0 +1,183 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "longlong.h" +#include "mpn_extras.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + mpz_t a, d, q1, q2, r1, r2; + gmp_randstate_t st; + mp_ptr dinv; + mp_size_t size, size2; + mp_bitcnt_t norm; + + FLINT_TEST_INIT(state); + + flint_printf("divrem_preinvn...."); + fflush(stdout); + + mpz_init(a); + mpz_init(d); + mpz_init(q1); + mpz_init(r1); + /* don't init r2, q2 */ + + gmp_randinit_default(st); + + + /* test flint_mpn_divrem_preinvn alias r and a */ + for (i = 0; i < 10000; i++) + { + size = n_randint(state, 200) + 1; + size2 = n_randint(state, 200) + size; + + mpz_rrandomb(a, st, size2*FLINT_BITS); + do { + mpz_rrandomb(d, st, size*FLINT_BITS); + } while (mpz_sgn(d) == 0); + + /* normalise */ + count_leading_zeros(norm, d->_mp_d[d->_mp_size - 1]); + mpz_mul_2exp(d, d, norm); + mpz_mul_2exp(a, a, norm); + size2 = a->_mp_size; + + /* allocate space */ + q2->_mp_size = size2 - size + 1; + q2->_mp_d = flint_malloc(q2->_mp_size*sizeof(mp_limb_t)); + + /* reduce a mod d */ + mpz_fdiv_qr(q1, r1, a, d); + + dinv = flint_malloc(size*sizeof(mp_limb_t)); + flint_mpn_preinvn(dinv, d->_mp_d, size); + + q2->_mp_d[q2->_mp_size - 1] = flint_mpn_divrem_preinvn(q2->_mp_d, a->_mp_d, a->_mp_d, size2, d->_mp_d, size, dinv); + + /* normalise */ + while (size && a->_mp_d[size - 1] == 0) size--; + a->_mp_size = size; + + size2 = q2->_mp_size; + while (size2 && q2->_mp_d[size2 - 1] == 0) size2--; + q2->_mp_size = size2; + + result = (mpz_cmp(r1, a) == 0 && mpz_cmp(q1, q2) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("%Zd\n", a); + gmp_printf("%Zd\n", d); + gmp_printf("%Zd\n", r1); + gmp_printf("%Zd\n", q1); + gmp_printf("%Zd\n", q2); + flint_printf("size = %wd\n", size); + flint_printf("size2 = %wd\n", size2); + abort(); + } + + flint_free(dinv); + flint_free(q2->_mp_d); + } + + /* test flint_mpn_divrem_preinvn */ + for (i = 0; i < 10000; i++) + { + size = n_randint(state, 200) + 1; + size2 = n_randint(state, 200) + size; + + mpz_rrandomb(a, st, size2*FLINT_BITS); + do { + mpz_rrandomb(d, st, size*FLINT_BITS); + } while (mpz_sgn(d) == 0); + + /* normalise */ + count_leading_zeros(norm, d->_mp_d[d->_mp_size - 1]); + mpz_mul_2exp(d, d, norm); + mpz_mul_2exp(a, a, norm); + size2 = a->_mp_size; + + /* allocate space */ + q2->_mp_size = size2 - size + 1; + q2->_mp_d = flint_malloc(q2->_mp_size*sizeof(mp_limb_t)); + + r2->_mp_size = size2; + r2->_mp_d = flint_malloc(r2->_mp_size*sizeof(mp_limb_t)); + + /* reduce a mod d */ + mpz_fdiv_qr(q1, r1, a, d); + + dinv = flint_malloc(size*sizeof(mp_limb_t)); + flint_mpn_preinvn(dinv, d->_mp_d, size); + + q2->_mp_d[q2->_mp_size - 1] = flint_mpn_divrem_preinvn(q2->_mp_d, r2->_mp_d, a->_mp_d, size2, d->_mp_d, size, dinv); + + /* normalise */ + while (size && r2->_mp_d[size - 1] == 0) size--; + r2->_mp_size = size; + + size2 = q2->_mp_size; + while (size2 && q2->_mp_d[size2 - 1] == 0) size2--; + q2->_mp_size = size2; + + result = (mpz_cmp(r1, r2) == 0 && mpz_cmp(q1, q2) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("%Zd\n", a); + gmp_printf("%Zd\n", d); + gmp_printf("%Zd\n", r1); + gmp_printf("%Zd\n", r2); + gmp_printf("%Zd\n", q1); + gmp_printf("%Zd\n", q2); + flint_printf("size = %wd\n", size); + flint_printf("size2 = %wd\n", size2); + abort(); + } + + flint_free(dinv); + flint_free(q2->_mp_d); + flint_free(r2->_mp_d); + } + + mpz_clear(a); + mpz_clear(d); + mpz_clear(q1); + mpz_clear(r1); + /* don't clear r2, q2 */ + + gmp_randclear(st); + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/mpn_extras/test/t-gcd_full.c b/external/flint-2.4.3/mpn_extras/test/t-gcd_full.c new file mode 100644 index 0000000..1e8984a --- /dev/null +++ b/external/flint-2.4.3/mpn_extras/test/t-gcd_full.c @@ -0,0 +1,98 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "mpn_extras.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + mpz_t a, b, c, g; + gmp_randstate_t st; + slong s1, s2; + + FLINT_TEST_INIT(state); + + flint_printf("gcd_full...."); + fflush(stdout); + + mpz_init(a); + mpz_init(b); + mpz_init(c); + /* don't init g */ + gmp_randinit_default(st); + + for (i = 0; i < 10000; i++) + { + do { + mpz_urandomb(a, st, n_randint(state, 200)); + } while (mpz_sgn(a) == 0); + do { + mpz_urandomb(b, st, n_randint(state, 200)); + } while (mpz_sgn(b) == 0); + do { + mpz_urandomb(c, st, n_randint(state, 200)); + } while (mpz_sgn(c) == 0); + + mpz_mul(a, a, c); + mpz_mul(b, b, c); + mpz_mul_2exp(a, a, n_randint(state, 200)); + mpz_mul_2exp(b, b, n_randint(state, 200)); + + mpz_gcd(c, a, b); + + s1 = (mpz_sizeinbase(a, 2) - 1)/FLINT_BITS + 1; + s2 = (mpz_sizeinbase(b, 2) - 1)/FLINT_BITS + 1; + + g->_mp_d = flint_malloc(FLINT_MIN(s1, s2)*sizeof(mp_limb_t)); + + g->_mp_size = flint_mpn_gcd_full(g->_mp_d, a->_mp_d, a->_mp_size, b->_mp_d, b->_mp_size); + + result = (mpz_cmp(g, c) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("%Zd\n", g); + gmp_printf("%Zd\n", c); + abort(); + } + + flint_free(g->_mp_d); + } + + mpz_clear(a); + mpz_clear(b); + mpz_clear(c); + /* don't clear g */ + gmp_randclear(st); + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/mpn_extras/test/t-mod_preinvn.c b/external/flint-2.4.3/mpn_extras/test/t-mod_preinvn.c new file mode 100644 index 0000000..d5be52e --- /dev/null +++ b/external/flint-2.4.3/mpn_extras/test/t-mod_preinvn.c @@ -0,0 +1,158 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "longlong.h" +#include "mpn_extras.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + mpz_t a, d, r1, r2; + gmp_randstate_t st; + mp_ptr dinv; + mp_size_t size, size2; + mp_bitcnt_t norm; + + FLINT_TEST_INIT(state); + + flint_printf("mod_preinvn...."); + fflush(stdout); + + mpz_init(a); + mpz_init(d); + mpz_init(r1); + /* don't init r2 */ + + gmp_randinit_default(st); + + /* test flint_mpn_mod_preinvn */ + for (i = 0; i < 10000; i++) + { + size = n_randint(state, 200) + 1; + size2 = n_randint(state, 200) + size; + + mpz_rrandomb(a, st, size2*FLINT_BITS); + do { + mpz_rrandomb(d, st, size*FLINT_BITS); + } while (mpz_sgn(d) == 0); + + /* normalise */ + count_leading_zeros(norm, d->_mp_d[d->_mp_size - 1]); + mpz_mul_2exp(d, d, norm); + mpz_mul_2exp(a, a, norm); + size2 = a->_mp_size; + + /* make space for r */ + r2->_mp_size = size2; + r2->_mp_d = flint_malloc(r2->_mp_size*sizeof(mp_limb_t)); + + /* reduce a mod d */ + mpz_fdiv_r(r1, a, d); + + dinv = flint_malloc(size*sizeof(mp_limb_t)); + flint_mpn_preinvn(dinv, d->_mp_d, size); + + flint_mpn_mod_preinvn(r2->_mp_d, a->_mp_d, size2, d->_mp_d, size, dinv); + + /* normalise */ + while (size && r2->_mp_d[size - 1] == 0) size--; + r2->_mp_size = size; + + result = (mpz_cmp(r1, r2) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("%Zd\n", a); + gmp_printf("%Zd\n", d); + gmp_printf("%Zd\n", r1); + flint_printf("size = %wd\n", size); + flint_printf("size2 = %wd\n", size2); + abort(); + } + + flint_free(dinv); + flint_free(r2->_mp_d); + } + + /* test flint_mpn_mod_preinvn alias r and a */ + for (i = 0; i < 10000; i++) + { + size = n_randint(state, 200) + 1; + size2 = n_randint(state, 200) + size; + + mpz_rrandomb(a, st, size2*FLINT_BITS); + do { + mpz_rrandomb(d, st, size*FLINT_BITS); + } while (mpz_sgn(d) == 0); + + /* normalise */ + count_leading_zeros(norm, d->_mp_d[d->_mp_size - 1]); + mpz_mul_2exp(d, d, norm); + mpz_mul_2exp(a, a, norm); + size2 = a->_mp_size; + + /* reduce a mod d */ + mpz_fdiv_r(r1, a, d); + + dinv = flint_malloc(size*sizeof(mp_limb_t)); + flint_mpn_preinvn(dinv, d->_mp_d, size); + + flint_mpn_mod_preinvn(a->_mp_d, a->_mp_d, size2, d->_mp_d, size, dinv); + + /* normalise */ + while (size && a->_mp_d[size - 1] == 0) size--; + a->_mp_size = size; + + result = (mpz_cmp(r1, a) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("%Zd\n", a); + gmp_printf("%Zd\n", d); + gmp_printf("%Zd\n", r1); + flint_printf("size = %wd\n", size); + flint_printf("size2 = %wd\n", size2); + abort(); + } + + flint_free(dinv); + } + + mpz_clear(a); + mpz_clear(d); + mpz_clear(r1); + /* don't clear r2 */ + + gmp_randclear(st); + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/mpn_extras/test/t-mulmod_2expp1.c b/external/flint-2.4.3/mpn_extras/test/t-mulmod_2expp1.c new file mode 100644 index 0000000..05c66ff --- /dev/null +++ b/external/flint-2.4.3/mpn_extras/test/t-mulmod_2expp1.c @@ -0,0 +1,257 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright 2009 Jason Moxham + Copyright 2013 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "longlong.h" +#include "mpn_extras.h" +#include "ulong_extras.h" + +int main(void) +{ + ulong xn, yn, b, zn, c, dn; + gmp_randstate_t rands; + int k, cc; + mp_limb_t xp[10000], dp[10000], qp[10000], yp[10000]; + mp_limb_t rp[10000], zp[10000], tp[10000], tb; + int result = 1; + + FLINT_TEST_INIT(state); + + gmp_randinit_default(rands); + + flint_printf("mulmod_2expp1_basecase...."); + fflush(stdout); + + b = 1; + tb = 1; + tb <<= b; + + for ( ; b < 600; b++, tb*=2) { + xn = BITS_TO_LIMBS(b); + k = xn*GMP_NUMB_BITS - b; + + if (tb == 0 || tb > GMP_NUMB_MASK) + tb=1; + + mpn_zero(dp, xn); + mpn_com_n(dp, dp, xn); + dp[xn-1] &= GMP_NUMB_MASK >> k; /* dp is 2^b-1 */ + dn = xn; + dp[xn] = mpn_add_1(dp, dp, xn, 2); + + if (dp[dn] != 0) + dn++; /* dp is 2^b+1 */ + + for (c = 0; c < 20; c++) { + mpn_random2(xp, xn); + mpn_random2(yp, xn); + xp[xn-1] &= GMP_NUMB_MASK >> k; + yp[xn-1] &= GMP_NUMB_MASK >> k; + mpn_mul_n(zp, xp, yp, xn); + zn = xn*2; + MPN_NORM(zp, zn); + + if (zn >= dn) + mpn_tdiv_qr(qp, rp, 0, zp, zn, dp, dn); + else + mpn_copyi(rp, zp, dn); + + cc = tp[xn] = flint_mpn_mulmod_2expp1_basecase(tp, xp, yp, 0, b, qp); + + if (cc != 0 && dn == xn) + tp[xn-1] |= tb; + + result = (mpn_cmp(tp, rp, dn) == 0); + if (!result) { + flint_printf("FAIL:\n"); + flint_printf("b = %wd\n", b); + abort(); + } + } + } + + b = 1; + tb = 1; + tb <<= b; + + for ( ; b < 600; b++, tb*=2) { + xn = BITS_TO_LIMBS(b); + k = xn*GMP_NUMB_BITS - b; + + if (tb == 0 || tb > GMP_NUMB_MASK) + tb = 1; + + mpn_zero(dp, xn); + mpn_com_n(dp, dp, xn); + dp[xn-1] &= GMP_NUMB_MASK >> k; /* dp is 2^b-1 */ + dn = xn; + dp[xn] = mpn_add_1(dp, dp, xn, 2); + + if (dp[dn] != 0) + dn++; /* dp is 2^b+1 */ + + for (c = 0; c < 20; c++) { + mpn_random2(xp, xn); + mpn_zero(yp, xn); /* set yp to 2^b */ + xp[xn-1] &= GMP_NUMB_MASK >> k; + yp[xn-1] &= GMP_NUMB_MASK >> k; + yn = xn; + + if (tb == 1) + yn++; + + yp[yn-1] = tb; + + mpn_mul(zp, yp, yn, xp, xn); + zn = xn*2; + MPN_NORM(zp, zn); + mpn_zero(yp, xn); /* set yp to 2^b */ + + if (zn >= dn) + mpn_tdiv_qr(qp, rp, 0, zp, zn, dp, dn); + else + mpn_copyi(rp, zp, dn); + + cc = tp[xn] = flint_mpn_mulmod_2expp1_basecase(tp, xp, yp, 1, b, qp); + + if (cc != 0 && dn == xn) + tp[xn-1] |= tb; + + result = (mpn_cmp(tp, rp, dn) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("b = %wd\n", b); + abort(); + } + } + } + + b = 1; + tb = 1; + tb <<= b; + + for ( ; b < 600; b++, tb*=2) { + xn = BITS_TO_LIMBS(b); + k = xn*GMP_NUMB_BITS - b; + + if (tb == 0 || tb > GMP_NUMB_MASK) + tb = 1; + + mpn_zero(dp, xn); + mpn_com_n(dp, dp, xn); + dp[xn-1] &= GMP_NUMB_MASK >> k; /* dp is 2^b-1 */ + dn = xn; + dp[xn] = mpn_add_1(dp, dp, xn, 2); + + if (dp[dn] != 0) + dn++; /* dp is 2^b+1 */ + + for (c = 0; c < 20; c++) { + mpn_random2(xp, xn); + mpn_zero(yp, xn); /* set yp to 2^b */ + xp[xn-1] &= GMP_NUMB_MASK >> k; + yp[xn-1] &= GMP_NUMB_MASK >> k; + yn = xn; + + if (tb == 1) + yn++; + + yp[yn-1] = tb; + + mpn_mul(zp, yp, yn, xp, xn); + zn = xn*2; + MPN_NORM(zp, zn); + mpn_zero(yp, xn); /* set yp to 2^b */ + + if (zn >= dn) + mpn_tdiv_qr(qp, rp, 0, zp, zn, dp, dn); + else + mpn_copyi(rp, zp, dn); + + cc = tp[xn] = flint_mpn_mulmod_2expp1_basecase(tp, yp, xp, 2, b, qp); + + if (cc != 0 && dn == xn) + tp[xn-1] |= tb; + + result = (mpn_cmp(tp, rp, dn) == 0); + if (!result) { + flint_printf("FAIL\n"); + flint_printf("b = %wd\n", b); + abort(); + } + } + } + + rp[0] = 1; + mpn_zero(rp + 1, 1000); + b = 1; + tb = 1; + tb <<= b; + + for ( ; b < 600; b++, tb*=2) { + xn = BITS_TO_LIMBS(b); + k = xn*GMP_NUMB_BITS - b; + + if (tb == 0 || tb > GMP_NUMB_MASK) + tb = 1; + + mpn_zero(dp, xn); + mpn_com_n(dp, dp, xn); + dp[xn-1] &= GMP_NUMB_MASK >> k; /* dp is 2^b-1 */ + dn = xn; + dp[xn] = mpn_add_1(dp, dp, xn, 2); + + if (dp[dn] != 0) + dn++; /* dp is 2^b+1 */ + + for (c = 0; c < 1; c++) { + mpn_zero(xp, xn); + mpn_zero(yp, xn); /* set xp, yp to 2^b */ + xp[xn-1] &= GMP_NUMB_MASK >> k; + yp[xn-1] &= GMP_NUMB_MASK >> k; + cc = tp[xn] = flint_mpn_mulmod_2expp1_basecase(tp, yp, xp, 3, b, qp); + + if (cc != 0 && dn == xn) + tp[xn-1] |= tb; + + result = (mpn_cmp(tp, rp, dn) == 0); + if (!result) { + flint_printf("FAIL\n"); + flint_printf("b = %wd\n", b); + abort(); + } + } + } + + gmp_randclear(rands); + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/mpn_extras/test/t-mulmod_preinv1.c b/external/flint-2.4.3/mpn_extras/test/t-mulmod_preinv1.c new file mode 100644 index 0000000..8928eed --- /dev/null +++ b/external/flint-2.4.3/mpn_extras/test/t-mulmod_preinv1.c @@ -0,0 +1,118 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "longlong.h" +#include "mpn_extras.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + mpz_t a, b, d, r1, r2; + gmp_randstate_t st; + mp_limb_t d1, d2, dinv; + mp_size_t size; + mp_bitcnt_t norm; + + FLINT_TEST_INIT(state); + + flint_printf("mulmod_preinv1...."); + fflush(stdout); + + mpz_init(a); + mpz_init(b); + mpz_init(d); + mpz_init(r1); + /* don't init r2 */ + + gmp_randinit_default(st); + + for (i = 0; i < 10000; i++) + { + size = n_randint(state, 200) + 2; + + mpz_rrandomb(a, st, size*FLINT_BITS); + mpz_rrandomb(b, st, size*FLINT_BITS); + do { + mpz_rrandomb(d, st, size*FLINT_BITS); + } while (mpz_sgn(d) == 0); + + /* reduce a, b mod d */ + mpz_fdiv_r(a, a, d); + mpz_fdiv_r(b, b, d); + + mpz_mul(r1, a, b); + mpz_fdiv_r(r1, r1, d); + + /* normalise */ + count_leading_zeros(norm, d->_mp_d[d->_mp_size - 1]); + mpz_mul_2exp(a, a, norm); + mpz_mul_2exp(b, b, norm); + mpz_mul_2exp(d, d, norm); + + d1 = d->_mp_d[size - 1]; + d2 = d->_mp_d[size - 2]; + dinv = flint_mpn_preinv1(d1, d2); + + r2->_mp_d = flint_malloc(size*sizeof(mp_limb_t)); + + flint_mpn_mulmod_preinv1(r2->_mp_d, a->_mp_d, b->_mp_d, size, d->_mp_d, dinv, norm); + + /* normalise */ + while (size && r2->_mp_d[size - 1] == 0) size--; + r2->_mp_size = size; + r2->_mp_alloc = size; + + result = (mpz_cmp(r1, r2) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("%Zd\n", a); + gmp_printf("%Zd\n", b); + gmp_printf("%Zd\n", d); + gmp_printf("%Zd\n", r1); + gmp_printf("%Zd\n", r2); + abort(); + } + + flint_free(r2->_mp_d); + } + + mpz_clear(a); + mpz_clear(b); + mpz_clear(d); + mpz_clear(r1); + /* don't init r2 */ + + gmp_randclear(st); + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/mpn_extras/test/t-mulmod_preinvn.c b/external/flint-2.4.3/mpn_extras/test/t-mulmod_preinvn.c new file mode 100644 index 0000000..b48fe64 --- /dev/null +++ b/external/flint-2.4.3/mpn_extras/test/t-mulmod_preinvn.c @@ -0,0 +1,119 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "longlong.h" +#include "mpn_extras.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + mpz_t a, b, d, r1, r2; + gmp_randstate_t st; + mp_ptr dinv; + mp_size_t size; + mp_bitcnt_t norm; + + FLINT_TEST_INIT(state); + + flint_printf("mulmod_preinvn...."); + fflush(stdout); + + mpz_init(a); + mpz_init(b); + mpz_init(d); + mpz_init(r1); + /* don't init r2 */ + + gmp_randinit_default(st); + + for (i = 0; i < 10000; i++) + { + size = n_randint(state, 200) + 1; + + mpz_rrandomb(a, st, size*FLINT_BITS); + mpz_rrandomb(b, st, size*FLINT_BITS); + do { + mpz_rrandomb(d, st, size*FLINT_BITS); + } while (mpz_sgn(d) == 0); + + /* reduce a, b mod d */ + mpz_fdiv_r(a, a, d); + mpz_fdiv_r(b, b, d); + + mpz_mul(r1, a, b); + mpz_fdiv_r(r1, r1, d); + + /* normalise */ + count_leading_zeros(norm, d->_mp_d[d->_mp_size - 1]); + mpz_mul_2exp(a, a, norm); + mpz_mul_2exp(b, b, norm); + mpz_mul_2exp(d, d, norm); + + dinv = flint_malloc(size*sizeof(mp_limb_t)); + flint_mpn_preinvn(dinv, d->_mp_d, size); + + r2->_mp_d = flint_malloc(size*sizeof(mp_limb_t)); + + flint_mpn_mulmod_preinvn(r2->_mp_d, a->_mp_d, b->_mp_d, size, d->_mp_d, dinv, norm); + + /* normalise */ + while (size && r2->_mp_d[size - 1] == 0) size--; + r2->_mp_size = size; + r2->_mp_alloc = size; + + result = (mpz_cmp(r1, r2) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + gmp_printf("%Zd\n", a); + gmp_printf("%Zd\n", b); + gmp_printf("%Zd\n", d); + gmp_printf("%Zd\n", r1); + gmp_printf("%Zd\n", r2); + flint_printf("size = %wd\n", size); + abort(); + } + + flint_free(r2->_mp_d); + flint_free(dinv); + } + + mpz_clear(a); + mpz_clear(b); + mpz_clear(d); + mpz_clear(r1); + /* don't init r2 */ + + gmp_randclear(st); + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/mpn_extras/test/t-remove_2exp.c b/external/flint-2.4.3/mpn_extras/test/t-remove_2exp.c new file mode 100644 index 0000000..7ee15b3 --- /dev/null +++ b/external/flint-2.4.3/mpn_extras/test/t-remove_2exp.c @@ -0,0 +1,70 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "mpn_extras.h" +#include "ulong_extras.h" + +int main(void) +{ + int zero, nonzero; + mp_bitcnt_t check; + mpz_t a; + mpz_t b; + + FLINT_TEST_INIT(state); + + flint_printf("remove_2exp...."); + fflush(stdout); + + mpz_init(a); + mpz_init(b); + + for (zero=0; zero<300; zero++) + { + for (nonzero=0; nonzero<300; nonzero++) + { + flint_mpz_set_ui(a, 1); + mpz_setbit(a, nonzero); + mpz_set(b, a); + mpz_mul_2exp(a, a, zero); + a->_mp_size = flint_mpn_remove_2exp(a->_mp_d, a->_mp_size, &check); + if (check != zero || mpz_cmp(a,b)) + { + gmp_printf("%d %d \n", zero, nonzero); + abort(); + } + } + } + + mpz_clear(a); + mpz_clear(b); + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/mpn_extras/test/t-remove_power.c b/external/flint-2.4.3/mpn_extras/test/t-remove_power.c new file mode 100644 index 0000000..1b9b209 --- /dev/null +++ b/external/flint-2.4.3/mpn_extras/test/t-remove_power.c @@ -0,0 +1,85 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "mpn_extras.h" +#include "ulong_extras.h" + +void test_exact(int d) +{ + int i, j; + ulong exp, exact; + mpz_t a, a2, b, c; + mpz_init(a); + mpz_init(a2); + mpz_init(b); + mpz_init(c); + for (i=0; i<100; i++) + { + for (j=1; j<100; j++) + { + exact = i / j; + flint_mpz_set_ui(a, d); + flint_mpz_pow_ui(a, a, i); + mpz_set(a2, a); + flint_mpz_set_ui(b, d); + flint_mpz_pow_ui(b, b, j); + a->_mp_size = flint_mpn_remove_power_ascending(a->_mp_d, a->_mp_size, + b->_mp_d, b->_mp_size, &exp); + flint_mpz_pow_ui(b, b, exact); + mpz_tdiv_q(c, a2, b); + if (exp != i/j || mpz_cmp(a, c)) + { + gmp_printf("%d^%d / %d^%d\n", d, i, d, j); + abort(); + } + } + } + + mpz_clear(a); + mpz_clear(a2); + mpz_clear(b); + mpz_clear(c); +} + + +int main(void) +{ + FLINT_TEST_INIT(state); + + flint_printf("remove_power...."); + fflush(stdout); + + test_exact(3); + test_exact(10); + test_exact(7429); + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_mat.h b/external/flint-2.4.3/nmod_mat.h new file mode 100644 index 0000000..3ee06c3 --- /dev/null +++ b/external/flint-2.4.3/nmod_mat.h @@ -0,0 +1,217 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010,2011 Fredrik Johansson + +******************************************************************************/ + +#ifndef NMOD_MAT_H +#define NMOD_MAT_H + +#undef ulong +#define ulong ulongxx /* interferes with system includes */ +#include +#undef ulong +#include +#define ulong mp_limb_t + +#include "flint.h" +#include "longlong.h" +#include "ulong_extras.h" +#include "nmod_vec.h" + +#ifdef __cplusplus + extern "C" { +#endif + +typedef struct +{ + mp_limb_t * entries; + slong r; + slong c; + mp_limb_t ** rows; + nmod_t mod; +} +nmod_mat_struct; + +/* nmod_mat_t allows reference-like semantics for nmod_mat_struct */ +typedef nmod_mat_struct nmod_mat_t[1]; + +#define nmod_mat_entry(mat,i,j) ((mat)->rows[(i)][(j)]) +#define nmod_mat_nrows(mat) ((mat)->r) +#define nmod_mat_ncols(mat) ((mat)->c) + +static __inline__ +void +_nmod_mat_set_mod(nmod_mat_t mat, mp_limb_t n) +{ + mat->mod.n = n; + mat->mod.ninv = n_preinvert_limb(n); + count_leading_zeros(mat->mod.norm, n); +} + +/* Memory management */ +void nmod_mat_init(nmod_mat_t mat, slong rows, slong cols, mp_limb_t n); +void nmod_mat_init_set(nmod_mat_t mat, const nmod_mat_t src); +void nmod_mat_clear(nmod_mat_t mat); + +void nmod_mat_window_init(nmod_mat_t window, const nmod_mat_t mat, slong r1, slong c1, slong r2, slong c2); +void nmod_mat_window_clear(nmod_mat_t window); + +/* Random matrix generation */ +void nmod_mat_randtest(nmod_mat_t mat, flint_rand_t state); +void nmod_mat_randfull(nmod_mat_t mat, flint_rand_t state); +int nmod_mat_randpermdiag(nmod_mat_t mat, flint_rand_t state, + mp_srcptr diag, slong n); +void nmod_mat_randrank(nmod_mat_t, flint_rand_t state, slong rank); +void nmod_mat_randops(nmod_mat_t mat, slong count, flint_rand_t state); +void nmod_mat_randtril(nmod_mat_t mat, flint_rand_t state, int unit); +void nmod_mat_randtriu(nmod_mat_t mat, flint_rand_t state, int unit); + + +void nmod_mat_print_pretty(const nmod_mat_t mat); + +int nmod_mat_equal(const nmod_mat_t mat1, const nmod_mat_t mat2); + +void nmod_mat_zero(nmod_mat_t mat); + +int nmod_mat_is_zero(const nmod_mat_t mat); + +static __inline__ int +nmod_mat_is_empty(const nmod_mat_t mat) +{ + return (mat->r == 0) || (mat->c == 0); +} + +static __inline__ int +nmod_mat_is_square(const nmod_mat_t mat) +{ + return (mat->r == mat->c); +} + + +void nmod_mat_set(nmod_mat_t B, const nmod_mat_t A); +void nmod_mat_transpose(nmod_mat_t B, const nmod_mat_t A); + +/* Addition and subtraction */ + +void nmod_mat_add(nmod_mat_t C, const nmod_mat_t A, const nmod_mat_t B); +void nmod_mat_sub(nmod_mat_t C, const nmod_mat_t A, const nmod_mat_t B); +void nmod_mat_neg(nmod_mat_t B, const nmod_mat_t A); + +/* Matrix-scalar arithmetic */ + +void nmod_mat_scalar_mul(nmod_mat_t B, const nmod_mat_t A, mp_limb_t c); + +/* Matrix multiplication */ + +void nmod_mat_mul(nmod_mat_t C, const nmod_mat_t A, const nmod_mat_t B); +void nmod_mat_mul_classical(nmod_mat_t C, const nmod_mat_t A, const nmod_mat_t B); +void nmod_mat_mul_strassen(nmod_mat_t C, const nmod_mat_t A, const nmod_mat_t B); + +void +_nmod_mat_mul_classical(nmod_mat_t D, const nmod_mat_t C, + const nmod_mat_t A, const nmod_mat_t B, int op); + +void nmod_mat_addmul(nmod_mat_t D, const nmod_mat_t C, + const nmod_mat_t A, const nmod_mat_t B); + +void nmod_mat_submul(nmod_mat_t D, const nmod_mat_t C, + const nmod_mat_t A, const nmod_mat_t B); + +/* Trace */ + +mp_limb_t nmod_mat_trace(const nmod_mat_t mat); + +/* Determinant */ + +mp_limb_t _nmod_mat_det(nmod_mat_t A); +mp_limb_t nmod_mat_det(const nmod_mat_t A); + +/* Rank */ + +slong nmod_mat_rank(const nmod_mat_t A); + +/* Inverse */ + +int nmod_mat_inv(nmod_mat_t B, const nmod_mat_t A); + +/* Triangular solving */ + +void nmod_mat_solve_tril(nmod_mat_t X, const nmod_mat_t L, const nmod_mat_t B, int unit); +void nmod_mat_solve_tril_recursive(nmod_mat_t X, const nmod_mat_t L, const nmod_mat_t B, int unit); +void nmod_mat_solve_tril_classical(nmod_mat_t X, const nmod_mat_t L, const nmod_mat_t B, int unit); + +void nmod_mat_solve_triu(nmod_mat_t X, const nmod_mat_t U, const nmod_mat_t B, int unit); +void nmod_mat_solve_triu_recursive(nmod_mat_t X, const nmod_mat_t U, const nmod_mat_t B, int unit); +void nmod_mat_solve_triu_classical(nmod_mat_t X, const nmod_mat_t U, const nmod_mat_t B, int unit); + +/* LU decomposition */ + +slong nmod_mat_lu(slong * P, nmod_mat_t A, int rank_check); +slong nmod_mat_lu_classical(slong * P, nmod_mat_t A, int rank_check); +slong nmod_mat_lu_recursive(slong * P, nmod_mat_t A, int rank_check); + +/* Nonsingular solving */ + +int nmod_mat_solve(nmod_mat_t X, const nmod_mat_t A, const nmod_mat_t B); +int nmod_mat_solve_vec(mp_ptr x, const nmod_mat_t A, mp_srcptr b); + +/* Reduced row echelon form */ + +slong nmod_mat_rref(nmod_mat_t A); + +/* Nullspace */ + +slong nmod_mat_nullspace(nmod_mat_t X, const nmod_mat_t A); + + +/* Tuning parameters *********************************************************/ + +/* Size at which pre-transposing becomes faster in classical multiplication */ +#define NMOD_MAT_MUL_TRANSPOSE_CUTOFF 20 + +/* Strassen multiplication */ +#define NMOD_MAT_MUL_STRASSEN_CUTOFF 256 + +/* Cutoff between classical and recursive triangular solving */ +#define NMOD_MAT_SOLVE_TRI_ROWS_CUTOFF 64 +#define NMOD_MAT_SOLVE_TRI_COLS_CUTOFF 64 + +/* Cutoff between classical and recursive LU decomposition */ +#define NMOD_MAT_LU_RECURSIVE_CUTOFF 4 + +/* + Suggested initial modulus size for multimodular algorithms. This should + be chosen so that we get the most number of bits per cycle + in matrix multiplication. On x86-64 it appears to be optimal to use + moduli giving nlimbs = 2. This should hold both in the classical + range and in Strassen blocks. + */ +#define NMOD_MAT_OPTIMAL_MODULUS_BITS (FLINT_BITS-5) + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/external/flint-2.4.3/nmod_mat/add.c b/external/flint-2.4.3/nmod_mat/add.c new file mode 100644 index 0000000..9f6f74c --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/add.c @@ -0,0 +1,44 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_mat.h" +#include "nmod_vec.h" + +void +nmod_mat_add(nmod_mat_t C, const nmod_mat_t A, const nmod_mat_t B) +{ + slong i; + + if (C->c == 0) + return; + + for (i = 0; i < C->r; i++) + { + _nmod_vec_add(C->rows[i], A->rows[i], B->rows[i], C->c, C->mod); + } +} diff --git a/external/flint-2.4.3/nmod_mat/addmul.c b/external/flint-2.4.3/nmod_mat/addmul.c new file mode 100644 index 0000000..f0a54ea --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/addmul.c @@ -0,0 +1,56 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_mat.h" +#include "nmod_vec.h" + +void +nmod_mat_addmul(nmod_mat_t D, const nmod_mat_t C, + const nmod_mat_t A, const nmod_mat_t B) +{ + slong m, k, n; + + m = A->r; + k = A->c; + n = B->c; + + if (m < NMOD_MAT_MUL_STRASSEN_CUTOFF || + n < NMOD_MAT_MUL_STRASSEN_CUTOFF || + k < NMOD_MAT_MUL_STRASSEN_CUTOFF) + { + _nmod_mat_mul_classical(D, C, A, B, 1); + } + else + { + nmod_mat_t tmp; + nmod_mat_init(tmp, m, n, A->mod.n); + nmod_mat_mul_strassen(tmp, A, B); + nmod_mat_add(D, C, tmp); + nmod_mat_clear(tmp); + } +} diff --git a/external/flint-2.4.3/nmod_mat/clear.c b/external/flint-2.4.3/nmod_mat/clear.c new file mode 100644 index 0000000..cdd9f24 --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/clear.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_mat.h" + +void +nmod_mat_clear(nmod_mat_t mat) +{ + if (mat->entries) + { + flint_free(mat->entries); + flint_free(mat->rows); + } +} diff --git a/external/flint-2.4.3/nmod_mat/det.c b/external/flint-2.4.3/nmod_mat/det.c new file mode 100644 index 0000000..90f9d23 --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/det.c @@ -0,0 +1,86 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_vec.h" +#include "nmod_mat.h" +#include "perm.h" + + +mp_limb_t +_nmod_mat_det(nmod_mat_t A) +{ + mp_limb_t det; + slong * P; + + slong m = A->r; + slong rank; + slong i; + + P = flint_malloc(sizeof(slong) * m); + rank = nmod_mat_lu(P, A, 1); + + det = UWORD(0); + + if (rank == m) + { + det = UWORD(1); + for (i = 0; i < m; i++) + det = n_mulmod2_preinv(det, nmod_mat_entry(A, i, i), + A->mod.n, A->mod.ninv); + } + + if (_perm_parity(P, m) == 1) + det = nmod_neg(det, A->mod); + + flint_free(P); + return det; +} + +mp_limb_t +nmod_mat_det(const nmod_mat_t A) +{ + nmod_mat_t tmp; + mp_limb_t det; + slong dim = A->r; + + if (dim != A->c) + { + flint_printf("Exception (nmod_mat_det). Non-square matrix.\n"); + abort(); + } + + if (dim == 0) return UWORD(1); + if (dim == 1) return nmod_mat_entry(A, 0, 0); + + nmod_mat_init_set(tmp, A); + det = _nmod_mat_det(tmp); + nmod_mat_clear(tmp); + + return det; +} diff --git a/external/flint-2.4.3/nmod_mat/doc/nmod_mat.txt b/external/flint-2.4.3/nmod_mat/doc/nmod_mat.txt new file mode 100644 index 0000000..74e6f9c --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/doc/nmod_mat.txt @@ -0,0 +1,472 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +******************************************************************************* + + Memory management + +******************************************************************************* + +void nmod_mat_init(nmod_mat_t mat, slong rows, slong cols, mp_limb_t n) + + Initialises \code{mat} to a \code{rows}-by-\code{cols} matrix with + coefficients modulo~$n$, where $n$ can be any nonzero integer that + fits in a limb. All elements are set to zero. + +void nmod_mat_init_set(nmod_mat_t mat, nmod_mat_t src) + + Initialises \code{mat} and sets its dimensions, modulus and elements + to those of \code{src}. + +void nmod_mat_clear(nmod_mat_t mat) + + Clears the matrix and releases any memory it used. The matrix + cannot be used again until it is initialised. This function must be + called exactly once when finished using an \code{nmod_mat_t} object. + +void nmod_mat_set(nmod_mat_t mat, nmod_mat_t src) + + Sets \code{mat} to a copy of \code{src}. It is assumed + that \code{mat} and \code{src} have identical dimensions. + +******************************************************************************* + + Basic properties and manipulation + +******************************************************************************* + +MACRO nmod_mat_entry(nmod_mat_t mat, slong i, slong j) + + Directly accesses the entry in \code{mat} in row $i$ and column $j$, + indexed from zero. No bounds checking is performed. This macro can be + used both for reading and writing coefficients. + +slong nmod_mat_nrows(nmod_mat_t mat) + + Returns the number of rows in \code{mat}. This function is implemented + as a macro. + +slong nmod_mat_ncols(nmod_mat_t mat) + + Returns the number of columns in \code{mat}. This function is implemented + as a macro. + +******************************************************************************* + + Printing + +******************************************************************************* + +void nmod_mat_print_pretty(nmod_mat_t mat) + + Pretty-prints \code{mat} to \code{stdout}. A header is printed followed + by the rows enclosed in brackets. Each column is right-aligned to the + width of the modulus written in decimal, and the columns are separated by + spaces. + For example: + \begin{lstlisting} + <2 x 3 integer matrix mod 2903> + [ 0 0 2607] + [ 622 0 0] + \end{lstlisting} + +******************************************************************************* + + Random matrix generation + +******************************************************************************* + +void nmod_mat_randtest(nmod_mat_t mat, flint_rand_t state) + + Sets the elements to a random matrix with entries between $0$ and $m-1$ + inclusive, where $m$ is the modulus of \code{mat}. A sparse matrix is + generated with increased probability. + +void nmod_mat_randfull(nmod_mat_t mat, flint_rand_t state) + + Sets the element to random numbers likely to be close to the modulus + of the matrix. This is used to test potential overflow-related bugs. + +int nmod_mat_randpermdiag(nmod_mat_t mat, + mp_limb_t * diag, slong n, flint_rand_t state) + + Sets \code{mat} to a random permutation of the diagonal matrix + with $n$ leading entries given by the vector \code{diag}. It is + assumed that the main diagonal of \code{mat} has room for at + least $n$ entries. + + Returns $0$ or $1$, depending on whether the permutation is even + or odd respectively. + +void nmod_mat_randrank(nmod_mat_t mat, slong rank, flint_rand_t state) + + Sets \code{mat} to a random sparse matrix with the given rank, + having exactly as many non-zero elements as the rank, with the + non-zero elements being uniformly random integers between $0$ + and $m-1$ inclusive, where $m$ is the modulus of \code{mat}. + + The matrix can be transformed into a dense matrix with unchanged + rank by subsequently calling \code{nmod_mat_randops()}. + +void nmod_mat_randops(nmod_mat_t mat, slong count, flint_rand_t state) + + Randomises \code{mat} by performing elementary row or column + operations. More precisely, at most \code{count} random additions + or subtractions of distinct rows and columns will be performed. + This leaves the rank (and for square matrices, determinant) + unchanged. + +void nmod_mat_randtril(nmod_mat_t mat, flint_rand_t state, int unit) + + Sets \code{mat} to a random lower triangular matrix. If \code{unit} is 1, + it will have ones on the main diagonal, otherwise it will have random + nonzero entries on the main diagonal. + +void nmod_mat_randtriu(nmod_mat_t mat, flint_rand_t state, int unit) + + Sets \code{mat} to a random upper triangular matrix. If \code{unit} is 1, + it will have ones on the main diagonal, otherwise it will have random + nonzero entries on the main diagonal. + + +******************************************************************************* + + Comparison + +******************************************************************************* + +int nmod_mat_equal(nmod_mat_t mat1, nmod_mat_t mat2) + + Returns nonzero if mat1 and mat2 have the same dimensions and elements, + and zero otherwise. The moduli are ignored. + +******************************************************************************* + + Transpose + +******************************************************************************* + +void nmod_mat_transpose(nmod_mat_t B, nmod_mat_t A) + + Sets $B$ to the transpose of $A$. Dimensions must be compatible. + $B$ and $A$ may be the same object if and only if the matrix is square. + + +******************************************************************************* + + Addition and subtraction + +******************************************************************************* + +void nmod_mat_add(nmod_mat_t C, nmod_mat_t A, nmod_mat_t B) + + Computes $C = A + B$. Dimensions must be identical. + +void nmod_mat_sub(nmod_mat_t C, nmod_mat_t A, nmod_mat_t B) + + Computes $C = A - B$. Dimensions must be identical. + +void nmod_mat_neg(nmod_mat_t A, nmod_mat_t B) + + Sets $B = -A$. Dimensions must be identical. + +******************************************************************************* + + Matrix-scalar arithmetic + +******************************************************************************* + +void nmod_mat_scalar_mul(nmod_mat_t B, const nmod_mat_t A, mp_limb_t c) + + Sets $B = cA$, where the scalar $c$ is assumed to be reduced + modulo the modulus. Dimensions of $A$ and $B$ must be identical. + + +******************************************************************************* + + Matrix multiplication + +******************************************************************************* + +void nmod_mat_mul(nmod_mat_t C, nmod_mat_t A, nmod_mat_t B) + + Sets $C = AB$. Dimensions must be compatible for matrix multiplication. + $C$ is not allowed to be aliased with $A$ or $B$. This function + automatically chooses between classical and Strassen multiplication. + +void nmod_mat_mul_classical(nmod_mat_t C, nmod_mat_t A, nmod_mat_t B) + + Sets $C = AB$. Dimensions must be compatible for matrix multiplication. + $C$ is not allowed to be aliased with $A$ or $B$. Uses classical + matrix multiplication, creating a temporary transposed copy of $B$ + to improve memory locality if the matrices are large enough, + and packing several entries of $B$ into each word if the modulus + is very small. + +void nmod_mat_mul_strassen(nmod_mat_t C, nmod_mat_t A, nmod_mat_t B) + + Sets $C = AB$. Dimensions must be compatible for matrix multiplication. + $C$ is not allowed to be aliased with $A$ or $B$. Uses Strassen + multiplication (the Strassen-Winograd variant). + +void nmod_mat_addmul(nmod_mat_t D, const nmod_mat_t C, + const nmod_mat_t A, const nmod_mat_t B) + + Sets $D = C + AB$. $C$ and $D$ may be aliased with each other but + not with $A$ or $B$. Automatically selects between classical + and Strassen multiplication. + +void nmod_mat_submul(nmod_mat_t D, const nmod_mat_t C, + const nmod_mat_t A, const nmod_mat_t B) + + Sets $D = C + AB$. $C$ and $D$ may be aliased with each other but + not with $A$ or $B$. + +******************************************************************************* + + Trace + +******************************************************************************* + +mp_limb_t nmod_mat_trace(const nmod_mat_t mat) + + Computes the trace of the matrix, i.e. the sum of the entries on + the main diagonal. The matrix is required to be square. + +******************************************************************************* + + Determinant and rank + +******************************************************************************* + +mp_limb_t nmod_mat_det(nmod_mat_t A) + + Returns the determinant of $A$. The modulus of $A$ must be a prime number. + +slong nmod_mat_rank(nmod_mat_t A) + + Returns the rank of $A$. The modulus of $A$ must be a prime number. + + +******************************************************************************* + + Inverse + +******************************************************************************* + +int nmod_mat_inv(nmod_mat_t B, nmod_mat_t A) + + Sets $B = A^{-1}$ and returns $1$ if $A$ is invertible. + If $A$ is singular, returns $0$ and sets the elements of + $B$ to undefined values. + + $A$ and $B$ must be square matrices with the same dimensions + and modulus. The modulus must be prime. + + +******************************************************************************* + + Triangular solving + +******************************************************************************* + +void nmod_mat_solve_tril(nmod_mat_t X, const nmod_mat_t L, + const nmod_mat_t B, int unit) + + Sets $X = L^{-1} B$ where $L$ is a full rank lower triangular square + matrix. If \code{unit} = 1, $L$ is assumed to have ones on its + main diagonal, and the main diagonal will not be read. + $X$ and $B$ are allowed to be the same matrix, but no other + aliasing is allowed. Automatically chooses between the classical and + recursive algorithms. + +void nmod_mat_solve_tril_classical(nmod_mat_t X, const nmod_mat_t L, + const nmod_mat_t B, int unit) + + Sets $X = L^{-1} B$ where $L$ is a full rank lower triangular square + matrix. If \code{unit} = 1, $L$ is assumed to have ones on its + main diagonal, and the main diagonal will not be read. + $X$ and $B$ are allowed to be the same matrix, but no other + aliasing is allowed. Uses forward substitution. + +void nmod_mat_solve_tril_recursive(nmod_mat_t X, const nmod_mat_t L, + const nmod_mat_t B, int unit) + + Sets $X = L^{-1} B$ where $L$ is a full rank lower triangular square + matrix. If \code{unit} = 1, $L$ is assumed to have ones on its + main diagonal, and the main diagonal will not be read. + $X$ and $B$ are allowed to be the same matrix, but no other + aliasing is allowed. + + Uses the block inversion formula + + $$ + \begin{pmatrix} A & 0 \\ C & D \end{pmatrix}^{-1} + \begin{pmatrix} X \\ Y \end{pmatrix} = + \begin{pmatrix} A^{-1} X \\ D^{-1} ( Y - C A^{-1} X ) \end{pmatrix} + $$ + + to reduce the problem to matrix multiplication and triangular solving + of smaller systems. + +void nmod_mat_solve_triu(nmod_mat_t X, const nmod_mat_t U, + const nmod_mat_t B, int unit) + + Sets $X = U^{-1} B$ where $U$ is a full rank upper triangular square + matrix. If \code{unit} = 1, $U$ is assumed to have ones on its + main diagonal, and the main diagonal will not be read. + $X$ and $B$ are allowed to be the same matrix, but no other + aliasing is allowed. Automatically chooses between the classical and + recursive algorithms. + +void nmod_mat_solve_triu_classical(nmod_mat_t X, const nmod_mat_t U, + const nmod_mat_t B, int unit) + + Sets $X = U^{-1} B$ where $U$ is a full rank upper triangular square + matrix. If \code{unit} = 1, $U$ is assumed to have ones on its + main diagonal, and the main diagonal will not be read. + $X$ and $B$ are allowed to be the same matrix, but no other + aliasing is allowed. Uses forward substitution. + +void nmod_mat_solve_triu_recursive(nmod_mat_t X, const nmod_mat_t U, + const nmod_mat_t B, int unit) + + Sets $X = U^{-1} B$ where $U$ is a full rank upper triangular square + matrix. If \code{unit} = 1, $U$ is assumed to have ones on its + main diagonal, and the main diagonal will not be read. + $X$ and $B$ are allowed to be the same matrix, but no other + aliasing is allowed. + + Uses the block inversion formula + + $$ + \begin{pmatrix} A & B \\ 0 & D \end{pmatrix}^{-1} + \begin{pmatrix} X \\ Y \end{pmatrix} = + \begin{pmatrix} A^{-1} (X - B D^{-1} Y) \\ D^{-1} Y \end{pmatrix} + $$ + + to reduce the problem to matrix multiplication and triangular solving + of smaller systems. + + +******************************************************************************* + + Nonsingular square solving + +******************************************************************************* + +int nmod_mat_solve(nmod_mat_t X, nmod_mat_t A, nmod_mat_t B) + + Solves the matrix-matrix equation $AX = B$ over $\Z / p \Z$ where $p$ + is the modulus of $X$ which must be a prime number. $X$, $A$, and $B$ + should have the same moduli. + + Returns $1$ if $A$ has full rank; otherwise returns $0$ and sets the + elements of $X$ to undefined values. + +int nmod_mat_solve_vec(mp_limb_t * x, nmod_mat_t A, mp_limb_t * b) + + Solves the matrix-vector equation $Ax = b$ over $\Z / p \Z$ where $p$ + is the modulus of $A$ which must be a prime number. + + Returns $1$ if $A$ has full rank; otherwise returns $0$ and sets the + elements of $x$ to undefined values. + + +******************************************************************************* + + LU decomposition + +******************************************************************************* + +slong nmod_mat_lu(slong * P, nmod_mat_t A, int rank_check) + + Computes a generalised LU decomposition $LU = PA$ of a given + matrix $A$, returning the rank of $A$. + + If $A$ is a nonsingular square matrix, it will be overwritten with + a unit diagonal lower triangular matrix $L$ and an upper triangular + matrix $U$ (the diagonal of $L$ will not be stored explicitly). + + If $A$ is an arbitrary matrix of rank $r$, $U$ will be in row echelon + form having $r$ nonzero rows, and $L$ will be lower triangular + but truncated to $r$ columns, having implicit ones on the $r$ first + entries of the main diagonal. All other entries will be zero. + + If a nonzero value for \code{rank_check} is passed, the + function will abandon the output matrix in an undefined state and + return 0 if $A$ is detected to be rank-deficient. + + This function calls \code{nmod_mat_lu_recursive}. + +slong nmod_mat_lu_classical(slong * P, nmod_mat_t A, int rank_check) + + Computes a generalised LU decomposition $LU = PA$ of a given + matrix $A$, returning the rank of $A$. The behavior of this function + is identical to that of \code{nmod_mat_lu}. Uses Gaussian elimination. + +slong nmod_mat_lu_recursive(slong * P, nmod_mat_t A, int rank_check) + + Computes a generalised LU decomposition $LU = PA$ of a given + matrix $A$, returning the rank of $A$. The behavior of this function + is identical to that of \code{nmod_mat_lu}. Uses recursive block + decomposition, switching to classical Gaussian elimination for + sufficiently small blocks. + + +******************************************************************************* + + Reduced row echelon form + +******************************************************************************* + +slong nmod_mat_rref(nmod_mat_t A) + + Puts $A$ in reduced row echelon form and returns the rank of $A$. + + The rref is computed by first obtaining an unreduced row echelon + form via LU decomposition and then solving an additional + triangular system. + + +******************************************************************************* + + Nullspace + +******************************************************************************* + +slong nmod_mat_nullspace(nmod_mat_t X, const nmod_mat_t A) + + Computes the nullspace of $A$ and returns the nullity. + + More precisely, this function sets $X$ to a maximum rank matrix + such that $AX = 0$ and returns the rank of $X$. The columns of + $X$ will form a basis for the nullspace of $A$. + + $X$ must have sufficient space to store all basis vectors + in the nullspace. + + This function computes the reduced row echelon form and then reads + off the basis vectors. diff --git a/external/flint-2.4.3/nmod_mat/equal.c b/external/flint-2.4.3/nmod_mat/equal.c new file mode 100644 index 0000000..0a9ad90 --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/equal.c @@ -0,0 +1,58 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_mat.h" +#include "nmod_vec.h" + +int +nmod_mat_equal(const nmod_mat_t mat1, const nmod_mat_t mat2) +{ + slong i, j; + + if (mat1->r != mat2->r || mat1->c != mat2->c) + return 0; + + if (mat1->r == 0 || mat1->c == 0) + return 1; + + for (i = 0; i < mat1->r; i++) + { + for (j = 0; j < mat1->c; j++) + { + if (mat1->rows[i][j] != mat2->rows[i][j]) + return 0; + } + + /* + if (!_nmod_vec_equal(mat1->rows[i], mat2->rows[i], mat1->c)) + return 0; + */ + } + + return 1; +} diff --git a/external/flint-2.4.3/nmod_mat/init.c b/external/flint-2.4.3/nmod_mat/init.c new file mode 100644 index 0000000..be4475f --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/init.c @@ -0,0 +1,52 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010,2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_mat.h" + + +void +nmod_mat_init(nmod_mat_t mat, slong rows, slong cols, mp_limb_t n) +{ + if ((rows) && (cols)) + { + slong i; + mat->entries = flint_calloc(rows * cols, sizeof(mp_limb_t)); + mat->rows = flint_malloc(rows * sizeof(mp_limb_t *)); + + for (i = 0; i < rows; i++) + mat->rows[i] = mat->entries + i * cols; + } + else + mat->entries = NULL; + + mat->r = rows; + mat->c = cols; + + _nmod_mat_set_mod(mat, n); +} diff --git a/external/flint-2.4.3/nmod_mat/init_set.c b/external/flint-2.4.3/nmod_mat/init_set.c new file mode 100644 index 0000000..57f8b2d --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/init_set.c @@ -0,0 +1,57 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_mat.h" + +void +nmod_mat_init_set(nmod_mat_t mat, const nmod_mat_t src) +{ + slong rows = src->r; + slong cols = src->c; + + if ((rows) && (cols)) + { + slong i; + mat->entries = flint_malloc(rows * cols * sizeof(mp_limb_t)); + mat->rows = flint_malloc(rows * sizeof(mp_limb_t *)); + + for (i = 0; i < rows; i++) + { + mat->rows[i] = mat->entries + i * cols; + flint_mpn_copyi(mat->rows[i], src->rows[i], cols); + } + } + else + mat->entries = NULL; + + mat->r = rows; + mat->c = cols; + + mat->mod = src->mod; +} diff --git a/external/flint-2.4.3/nmod_mat/inv.c b/external/flint-2.4.3/nmod_mat/inv.c new file mode 100644 index 0000000..a7527ec --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/inv.c @@ -0,0 +1,70 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_vec.h" +#include "nmod_mat.h" + + +int nmod_mat_inv(nmod_mat_t B, const nmod_mat_t A) +{ + nmod_mat_t I; + slong i, dim; + int result; + + dim = A->r; + + switch (dim) + { + case 0: + result = 1; + break; + + case 1: + if (nmod_mat_entry(A, 0, 0) == UWORD(0)) + { + result = 0; + } + else + { + nmod_mat_entry(B, 0, 0) = + n_invmod(nmod_mat_entry(A, 0, 0), B->mod.n); + result = 1; + } + break; + + default: + nmod_mat_init(I, dim, dim, B->mod.n); + for (i = 0; i < dim; i++) + nmod_mat_entry(I, i, i) = UWORD(1); + result = nmod_mat_solve(B, A, I); + nmod_mat_clear(I); + } + + return result; +} diff --git a/external/flint-2.4.3/nmod_mat/is_zero.c b/external/flint-2.4.3/nmod_mat/is_zero.c new file mode 100644 index 0000000..4233dcd --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/is_zero.c @@ -0,0 +1,48 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_mat.h" +#include "ulong_extras.h" + +int +nmod_mat_is_zero(const nmod_mat_t mat) +{ + slong j; + + if (mat->r == 0 || mat->c == 0) + return 1; + + for (j = 0; j < mat->r; j++) + { + if (!_nmod_vec_is_zero(mat->rows[j], mat->c)) + return 0; + } + + return 1; +} + diff --git a/external/flint-2.4.3/nmod_mat/lu.c b/external/flint-2.4.3/nmod_mat/lu.c new file mode 100644 index 0000000..70f2581 --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/lu.c @@ -0,0 +1,37 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_vec.h" +#include "nmod_mat.h" + +slong +nmod_mat_lu(slong * P, nmod_mat_t A, int rank_check) +{ + return nmod_mat_lu_recursive(P, A, rank_check); +} diff --git a/external/flint-2.4.3/nmod_mat/lu_classical.c b/external/flint-2.4.3/nmod_mat/lu_classical.c new file mode 100644 index 0000000..d01ed84 --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/lu_classical.c @@ -0,0 +1,110 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_vec.h" +#include "nmod_mat.h" + + +static __inline__ int +nmod_mat_pivot(nmod_mat_t A, slong * P, slong start_row, slong col) +{ + slong j, t; + mp_ptr u; + + if (nmod_mat_entry(A, start_row, col) != 0) + return 1; + + for (j = start_row + 1; j < A->r; j++) + { + if (nmod_mat_entry(A, j, col) != 0) + { + u = A->rows[j]; + A->rows[j] = A->rows[start_row]; + A->rows[start_row] = u; + + t = P[j]; + P[j] = P[start_row]; + P[start_row] = t; + + return -1; + } + } + return 0; +} + + +slong +nmod_mat_lu_classical(slong * P, nmod_mat_t A, int rank_check) +{ + mp_limb_t d, e, **a; + nmod_t mod; + slong i, m, n, rank, length, row, col; + + m = A->r; + n = A->c; + a = A->rows; + mod = A->mod; + + rank = row = col = 0; + + for (i = 0; i < m; i++) + P[i] = i; + + while (row < m && col < n) + { + if (nmod_mat_pivot(A, P, row, col) == 0) + { + if (rank_check) + return 0; + col++; + continue; + } + + rank++; + + d = a[row][col]; + d = n_invmod(d, mod.n); + length = n - col - 1; + + for (i = row + 1; i < m; i++) + { + e = n_mulmod2_preinv(a[i][col], d, mod.n, mod.ninv); + if (length != 0) + _nmod_vec_scalar_addmul_nmod(a[i] + col + 1, + a[row] + col + 1, length, nmod_neg(e, mod), mod); + + a[i][col] = 0; + a[i][rank - 1] = e; + } + row++; + col++; + } + + return rank; +} diff --git a/external/flint-2.4.3/nmod_mat/lu_recursive.c b/external/flint-2.4.3/nmod_mat/lu_recursive.c new file mode 100644 index 0000000..64493d9 --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/lu_recursive.c @@ -0,0 +1,147 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + + Loosely based on the recursive PLS implementation in M4RI, + Copyright (C) 2008 Clement Pernet. + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_vec.h" +#include "nmod_mat.h" + + +static void +_apply_permutation(slong * AP, nmod_mat_t A, slong * P, + slong n, slong offset) +{ + if (n != 0) + { + mp_ptr * Atmp; + slong * APtmp; + slong i; + + Atmp = flint_malloc(sizeof(mp_ptr) * n); + APtmp = flint_malloc(sizeof(slong) * n); + + for (i = 0; i < n; i++) Atmp[i] = A->rows[P[i] + offset]; + for (i = 0; i < n; i++) A->rows[i + offset] = Atmp[i]; + + for (i = 0; i < n; i++) APtmp[i] = AP[P[i] + offset]; + for (i = 0; i < n; i++) AP[i + offset] = APtmp[i]; + + flint_free(Atmp); + flint_free(APtmp); + } +} + + +slong +nmod_mat_lu_recursive(slong * P, nmod_mat_t A, int rank_check) +{ + slong i, j, m, n, r1, r2, n1; + nmod_mat_t A0, A1, A00, A01, A10, A11; + slong * P1; + + m = A->r; + n = A->c; + + if (m < NMOD_MAT_LU_RECURSIVE_CUTOFF || n < NMOD_MAT_LU_RECURSIVE_CUTOFF) + { + r1 = nmod_mat_lu_classical(P, A, rank_check); + return r1; + } + + n1 = n / 2; + + for (i = 0; i < m; i++) + P[i] = i; + + P1 = flint_malloc(sizeof(slong) * m); + nmod_mat_window_init(A0, A, 0, 0, m, n1); + nmod_mat_window_init(A1, A, 0, n1, m, n); + + r1 = nmod_mat_lu(P1, A0, rank_check); + + if (rank_check && (r1 != n1)) + { + flint_free(P1); + nmod_mat_window_clear(A0); + nmod_mat_window_clear(A1); + return 0; + } + + if (r1 != 0) + { + _apply_permutation(P, A, P1, m, 0); + } + + nmod_mat_window_init(A00, A, 0, 0, r1, r1); + nmod_mat_window_init(A10, A, r1, 0, m, r1); + nmod_mat_window_init(A01, A, 0, n1, r1, n); + nmod_mat_window_init(A11, A, r1, n1, m, n); + + if (r1 != 0) + { + nmod_mat_solve_tril(A01, A00, A01, 1); + nmod_mat_submul(A11, A11, A10, A01); + } + + r2 = nmod_mat_lu(P1, A11, rank_check); + + if (rank_check && (r1 + r2 < FLINT_MIN(m, n))) + { + r1 = r2 = 0; + } + else + { + _apply_permutation(P, A, P1, m - r1, r1); + + /* Compress L */ + if (r1 != n1) + { + for (i = 0; i < m - r1; i++) + { + mp_ptr row = A->rows[r1 + i]; + for (j = 0; j < FLINT_MIN(i, r2); j++) + { + row[r1 + j] = row[n1 + j]; + row[n1 + j] = 0; + } + } + } + } + + flint_free(P1); + nmod_mat_window_clear(A00); + nmod_mat_window_clear(A01); + nmod_mat_window_clear(A10); + nmod_mat_window_clear(A11); + nmod_mat_window_clear(A0); + nmod_mat_window_clear(A1); + + return r1 + r2; +} diff --git a/external/flint-2.4.3/nmod_mat/mul.c b/external/flint-2.4.3/nmod_mat/mul.c new file mode 100644 index 0000000..047199e --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/mul.c @@ -0,0 +1,51 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_mat.h" +#include "nmod_vec.h" + +void +nmod_mat_mul(nmod_mat_t C, const nmod_mat_t A, const nmod_mat_t B) +{ + slong m, k, n; + + m = A->r; + k = A->c; + n = B->c; + + if (m < NMOD_MAT_MUL_STRASSEN_CUTOFF || + n < NMOD_MAT_MUL_STRASSEN_CUTOFF || + k < NMOD_MAT_MUL_STRASSEN_CUTOFF) + { + nmod_mat_mul_classical(C, A, B); + } + else + { + nmod_mat_mul_strassen(C, A, B); + } +} diff --git a/external/flint-2.4.3/nmod_mat/mul_classical.c b/external/flint-2.4.3/nmod_mat/mul_classical.c new file mode 100644 index 0000000..b89248b --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/mul_classical.c @@ -0,0 +1,223 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010,2012 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_mat.h" +#include "nmod_vec.h" + +/* +with op = 0, computes D = A*B +with op = 1, computes D = C + A*B +with op = -1, computes D = C - A*B +*/ + +static __inline__ void +_nmod_mat_addmul_basic(mp_ptr * D, mp_ptr * const C, mp_ptr * const A, + mp_ptr * const B, slong m, slong k, slong n, int op, nmod_t mod, int nlimbs) +{ + slong i, j; + mp_limb_t c; + + for (i = 0; i < m; i++) + { + for (j = 0; j < n; j++) + { + c = _nmod_vec_dot_ptr(A[i], B, j, k, mod, nlimbs); + + if (op == 1) + c = nmod_add(C[i][j], c, mod); + else if (op == -1) + c = nmod_sub(C[i][j], c, mod); + + D[i][j] = c; + } + } +} + +static __inline__ void +_nmod_mat_addmul_transpose(mp_ptr * D, const mp_ptr * C, const mp_ptr * A, + const mp_ptr * B, slong m, slong k, slong n, int op, nmod_t mod, int nlimbs) +{ + mp_ptr tmp; + mp_limb_t c; + slong i, j; + + tmp = flint_malloc(sizeof(mp_limb_t) * k * n); + + for (i = 0; i < k; i++) + for (j = 0; j < n; j++) + tmp[j*k + i] = B[i][j]; + + for (i = 0; i < m; i++) + { + for (j = 0; j < n; j++) + { + c = _nmod_vec_dot(A[i], tmp + j*k, k, mod, nlimbs); + + if (op == 1) + c = nmod_add(C[i][j], c, mod); + else if (op == -1) + c = nmod_sub(C[i][j], c, mod); + + D[i][j] = c; + } + } + + flint_free(tmp); +} + +/* requires nlimbs = 1 */ +void +_nmod_mat_addmul_packed(mp_ptr * D, const mp_ptr * C, const mp_ptr * A, + const mp_ptr * B, slong M, slong N, slong K, int op, nmod_t mod, int nlimbs) +{ + slong i, j, k; + slong Kpack; + int pack, pack_bits; + mp_limb_t c, d, mask; + mp_ptr tmp; + mp_ptr Aptr, Tptr; + + /* bound unreduced entry */ + c = N * (mod.n-1) * (mod.n-1); + pack_bits = FLINT_BIT_COUNT(c); + pack = FLINT_BITS / pack_bits; + Kpack = (K + pack - 1) / pack; + + if (pack_bits == FLINT_BITS) + mask = UWORD(-1); + else + mask = (UWORD(1) << pack_bits) - 1; + + tmp = _nmod_vec_init(Kpack * N); + + /* pack and transpose B */ + for (i = 0; i < Kpack; i++) + { + for (k = 0; k < N; k++) + { + c = B[k][i * pack]; + + for (j = 1; j < pack && i * pack + j < K; j++) + c |= B[k][i * pack + j] << (pack_bits * j); + + tmp[i * N + k] = c; + } + } + + /* multiply */ + for (i = 0; i < M; i++) + { + for (j = 0; j < Kpack; j++) + { + Aptr = A[i]; + Tptr = tmp + j * N; + + c = 0; + + /* unroll by 4 */ + for (k = 0; k + 4 <= N; k += 4) + { + c += Aptr[k + 0] * Tptr[k + 0]; + c += Aptr[k + 1] * Tptr[k + 1]; + c += Aptr[k + 2] * Tptr[k + 2]; + c += Aptr[k + 3] * Tptr[k + 3]; + } + + for ( ; k < N; k++) + c += Aptr[k] * Tptr[k]; + + /* unpack and reduce */ + for (k = 0; k < pack && j * pack + k < K; k++) + { + d = (c >> (k * pack_bits)) & mask; + NMOD_RED(d, d, mod); + + if (op == 1) + d = nmod_add(C[i][j * pack + k], d, mod); + else if (op == -1) + d = nmod_sub(C[i][j * pack + k], d, mod); + + D[i][j * pack + k] = d; + } + } + } + + _nmod_vec_clear(tmp); +} + + + +void +_nmod_mat_mul_classical(nmod_mat_t D, const nmod_mat_t C, + const nmod_mat_t A, const nmod_mat_t B, int op) +{ + slong m, k, n; + int nlimbs; + nmod_t mod; + + mod = A->mod; + m = A->r; + k = A->c; + n = B->c; + + if (k == 0) + { + if (op == 0) + nmod_mat_zero(D); + else + nmod_mat_set(D, C); + return; + } + + nlimbs = _nmod_vec_dot_bound_limbs(k, mod); + + if (nlimbs == 1 && m > 10 && k > 10 && n > 10) + { + _nmod_mat_addmul_packed(D->rows, (op == 0) ? NULL : C->rows, + A->rows, B->rows, m, k, n, op, D->mod, nlimbs); + } + else if (m < NMOD_MAT_MUL_TRANSPOSE_CUTOFF + || n < NMOD_MAT_MUL_TRANSPOSE_CUTOFF + || k < NMOD_MAT_MUL_TRANSPOSE_CUTOFF) + { + _nmod_mat_addmul_basic(D->rows, (op == 0) ? NULL : C->rows, + A->rows, B->rows, m, k, n, op, D->mod, nlimbs); + } + else + { + _nmod_mat_addmul_transpose(D->rows, (op == 0) ? NULL : C->rows, + A->rows, B->rows, m, k, n, op, D->mod, nlimbs); + } +} + + +void +nmod_mat_mul_classical(nmod_mat_t C, const nmod_mat_t A, const nmod_mat_t B) +{ + _nmod_mat_mul_classical(C, NULL, A, B, 0); +} diff --git a/external/flint-2.4.3/nmod_mat/mul_strassen.c b/external/flint-2.4.3/nmod_mat/mul_strassen.c new file mode 100644 index 0000000..9af1b2d --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/mul_strassen.c @@ -0,0 +1,169 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2008, Martin Albrecht + Copyright (C) 2008, 2009 William Hart. + Copyright (C) 2010, Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_mat.h" + + +void +nmod_mat_mul_strassen(nmod_mat_t C, const nmod_mat_t A, const nmod_mat_t B) +{ + slong a, b, c; + slong anr, anc, bnr, bnc; + + nmod_mat_t A11, A12, A21, A22; + nmod_mat_t B11, B12, B21, B22; + nmod_mat_t C11, C12, C21, C22; + nmod_mat_t X1, X2; + + a = A->r; + b = A->c; + c = B->c; + + if (a <= 4 || b <= 4 || c <= 4) + { + nmod_mat_mul(C, A, B); + return; + } + + anr = a / 2; + anc = b / 2; + bnr = anc; + bnc = c / 2; + + nmod_mat_window_init(A11, A, 0, 0, anr, anc); + nmod_mat_window_init(A12, A, 0, anc, anr, 2*anc); + nmod_mat_window_init(A21, A, anr, 0, 2*anr, anc); + nmod_mat_window_init(A22, A, anr, anc, 2*anr, 2*anc); + + nmod_mat_window_init(B11, B, 0, 0, bnr, bnc); + nmod_mat_window_init(B12, B, 0, bnc, bnr, 2*bnc); + nmod_mat_window_init(B21, B, bnr, 0, 2*bnr, bnc); + nmod_mat_window_init(B22, B, bnr, bnc, 2*bnr, 2*bnc); + + nmod_mat_window_init(C11, C, 0, 0, anr, bnc); + nmod_mat_window_init(C12, C, 0, bnc, anr, 2*bnc); + nmod_mat_window_init(C21, C, anr, 0, 2*anr, bnc); + nmod_mat_window_init(C22, C, anr, bnc, 2*anr, 2*bnc); + + nmod_mat_init(X1, anr, FLINT_MAX(bnc, anc), A->mod.n); + nmod_mat_init(X2, anc, bnc, A->mod.n); + + X1->c = anc; + + /* + See Jean-Guillaume Dumas, Clement Pernet, Wei Zhou; "Memory + efficient scheduling of Strassen-Winograd's matrix multiplication + algorithm"; http://arxiv.org/pdf/0707.2347v3 for reference on the + used operation scheduling. + */ + + nmod_mat_sub(X1, A11, A21); + nmod_mat_sub(X2, B22, B12); + nmod_mat_mul(C21, X1, X2); + + nmod_mat_add(X1, A21, A22); + nmod_mat_sub(X2, B12, B11); + nmod_mat_mul(C22, X1, X2); + + nmod_mat_sub(X1, X1, A11); + nmod_mat_sub(X2, B22, X2); + nmod_mat_mul(C12, X1, X2); + + nmod_mat_sub(X1, A12, X1); + nmod_mat_mul(C11, X1, B22); + + X1->c = bnc; + nmod_mat_mul(X1, A11, B11); + + nmod_mat_add(C12, X1, C12); + nmod_mat_add(C21, C12, C21); + nmod_mat_add(C12, C12, C22); + nmod_mat_add(C22, C21, C22); + nmod_mat_add(C12, C12, C11); + nmod_mat_sub(X2, X2, B21); + nmod_mat_mul(C11, A22, X2); + + nmod_mat_clear(X2); + + nmod_mat_sub(C21, C21, C11); + nmod_mat_mul(C11, A12, B21); + + nmod_mat_add(C11, X1, C11); + + nmod_mat_clear(X1); + + nmod_mat_window_clear(A11); + nmod_mat_window_clear(A12); + nmod_mat_window_clear(A21); + nmod_mat_window_clear(A22); + + nmod_mat_window_clear(B11); + nmod_mat_window_clear(B12); + nmod_mat_window_clear(B21); + nmod_mat_window_clear(B22); + + nmod_mat_window_clear(C11); + nmod_mat_window_clear(C12); + nmod_mat_window_clear(C21); + nmod_mat_window_clear(C22); + + if (c > 2*bnc) /* A by last col of B -> last col of C */ + { + nmod_mat_t Bc, Cc; + nmod_mat_window_init(Bc, B, 0, 2*bnc, b, c); + nmod_mat_window_init(Cc, C, 0, 2*bnc, a, c); + nmod_mat_mul(Cc, A, Bc); + nmod_mat_window_clear(Bc); + nmod_mat_window_clear(Cc); + } + + if (a > 2*anr) /* last row of A by B -> last row of C */ + { + nmod_mat_t Ar, Cr; + nmod_mat_window_init(Ar, A, 2*anr, 0, a, b); + nmod_mat_window_init(Cr, C, 2*anr, 0, a, c); + nmod_mat_mul(Cr, Ar, B); + nmod_mat_window_clear(Ar); + nmod_mat_window_clear(Cr); + } + + if (b > 2*anc) /* last col of A by last row of B -> C */ + { + nmod_mat_t Ac, Br, Cb; + nmod_mat_window_init(Ac, A, 0, 2*anc, 2*anr, b); + nmod_mat_window_init(Br, B, 2*bnr, 0, b, 2*bnc); + nmod_mat_window_init(Cb, C, 0, 0, 2*anr, 2*bnc); + nmod_mat_addmul(Cb, Cb, Ac, Br); + nmod_mat_window_clear(Ac); + nmod_mat_window_clear(Br); + nmod_mat_window_clear(Cb); + } +} diff --git a/external/flint-2.4.3/nmod_mat/neg.c b/external/flint-2.4.3/nmod_mat/neg.c new file mode 100644 index 0000000..6dc3c8e --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/neg.c @@ -0,0 +1,42 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_mat.h" +#include "nmod_vec.h" + +void +nmod_mat_neg(nmod_mat_t B, const nmod_mat_t A) +{ + slong i; + + if (A->c == 0) + return; + + for (i = 0; i < A->r; i++) + _nmod_vec_neg(B->rows[i], A->rows[i], A->c, A->mod); +} diff --git a/external/flint-2.4.3/nmod_mat/nullspace.c b/external/flint-2.4.3/nmod_mat/nullspace.c new file mode 100644 index 0000000..692b576 --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/nullspace.c @@ -0,0 +1,95 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_mat.h" + +slong +nmod_mat_nullspace(nmod_mat_t X, const nmod_mat_t A) +{ + slong i, j, k, m, n, rank, nullity; + slong * p; + slong * pivots; + slong * nonpivots; + nmod_mat_t tmp; + + m = A->r; + n = A->c; + + p = flint_malloc(sizeof(slong) * FLINT_MAX(m, n)); + + nmod_mat_init_set(tmp, A); + rank = nmod_mat_rref(tmp); + nullity = n - rank; + + nmod_mat_zero(X); + + if (rank == 0) + { + for (i = 0; i < nullity; i++) + nmod_mat_entry(X, i, i) = UWORD(1); + } + else if (nullity) + { + pivots = p; /* length = rank */ + nonpivots = p + rank; /* length = nullity */ + + for (i = j = k = 0; i < rank; i++) + { + while (nmod_mat_entry(tmp, i, j) == UWORD(0)) + { + nonpivots[k] = j; + k++; + j++; + } + pivots[i] = j; + j++; + } + while (k < nullity) + { + nonpivots[k] = j; + k++; + j++; + } + + for (i = 0; i < nullity; i++) + { + for (j = 0; j < rank; j++) + { + mp_limb_t c = nmod_mat_entry(tmp, j, nonpivots[i]); + nmod_mat_entry(X, pivots[j], i) = nmod_neg(c, A->mod); + } + + nmod_mat_entry(X, nonpivots[i], i) = UWORD(1); + } + } + + flint_free(p); + nmod_mat_clear(tmp); + + return nullity; +} diff --git a/external/flint-2.4.3/nmod_mat/print_pretty.c b/external/flint-2.4.3/nmod_mat/print_pretty.c new file mode 100644 index 0000000..bcd77d8 --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/print_pretty.c @@ -0,0 +1,63 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_mat.h" +#include "nmod_vec.h" +#include "ulong_extras.h" + +void +nmod_mat_print_pretty(const nmod_mat_t mat) +{ + slong i, j; + int width; + char fmt[FLINT_BITS + 5]; + + flint_printf("<%wd x %wd integer matrix mod %wu>\n", mat->r, mat->c, mat->mod.n); + + if (!(mat->c) || !(mat->r)) + return; + + width = n_sizeinbase(mat->mod.n, 10); + + flint_sprintf(fmt, "%%%dlu", width); + + for (i = 0; i < mat->r; i++) + { + flint_printf("["); + + for (j = 0; j < mat->c; j++) + { + flint_printf(fmt, mat->rows[i][j]); + if (j + 1 < mat->c) + flint_printf(" "); + } + + flint_printf("]\n"); + } +} diff --git a/external/flint-2.4.3/nmod_mat/profile/p-mul.c b/external/flint-2.4.3/nmod_mat/profile/p-mul.c new file mode 100644 index 0000000..fe178fc --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/profile/p-mul.c @@ -0,0 +1,100 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright 2009 William Hart + Copyright 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "profiler.h" +#include "flint.h" +#include "nmod_mat.h" +#include "ulong_extras.h" + +typedef struct +{ + ulong dim; + mp_limb_t modulus; + int algorithm; +} mat_mul_t; + +void sample(void * arg, ulong count) +{ + mat_mul_t * params = (mat_mul_t *) arg; + mp_limb_t n = params->modulus; + ulong i, dim = params->dim; + int algorithm = params->algorithm; + + nmod_mat_t A, B, C; + + nmod_mat_init(A, dim, dim, n); + nmod_mat_init(B, dim, dim, n); + nmod_mat_init(C, dim, dim, n); + + prof_start(); + + if (algorithm == 0) + for (i = 0; i < count; i++) + nmod_mat_mul(C, A, B); + else if (algorithm == 1) + for (i = 0; i < count; i++) + nmod_mat_mul_classical(C, A, B); + else + for (i = 0; i < count; i++) + nmod_mat_mul_strassen(C, A, B); + + prof_stop(); + + if (C->entries[0] == WORD(5893479483)) abort(); + + nmod_mat_clear(A); + nmod_mat_clear(B); + nmod_mat_clear(C); +} + +int main(void) +{ + double min_classical, min_strassen, max; + mat_mul_t params; + slong dim; + + flint_printf("nmod_mat_mul:\n"); + + params.modulus = 40000; + + for (dim = 2; dim <= 512; dim = (slong) ((double) dim * 1.1) + 1) + { + params.dim = dim; + + params.algorithm = 1; + prof_repeat(&min_classical, &max, sample, ¶ms); + + params.algorithm = 2; + prof_repeat(&min_strassen, &max, sample, ¶ms); + + flint_printf("dim = %wd, classical %.2f us strassen %.2f us\n", + dim, min_classical, min_strassen); + } + + return 0; +} diff --git a/external/flint-2.4.3/nmod_mat/randfull.c b/external/flint-2.4.3/nmod_mat/randfull.c new file mode 100644 index 0000000..3c41312 --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/randfull.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_mat.h" + +void +nmod_mat_randfull(nmod_mat_t mat, flint_rand_t state) +{ + slong i; + + for (i = 0; i < mat->r * mat->c; i++) + { + mat->entries[i] = FLINT_MAX(1, n_randint(state, mat->mod.n)); + } +} diff --git a/external/flint-2.4.3/nmod_mat/randops.c b/external/flint-2.4.3/nmod_mat/randops.c new file mode 100644 index 0000000..d8ac19f --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/randops.c @@ -0,0 +1,73 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_mat.h" +#include "nmod_vec.h" + + + +void +nmod_mat_randops(nmod_mat_t mat, slong count, flint_rand_t state) +{ + slong c, i, j, k; + slong m = mat->r; + slong n = mat->c; + + if (mat->r == 0 || mat->c == 0) + return; + + for (c = 0; c < count; c++) + { + if (n_randint(state, 2)) + { + if ((i = n_randint(state, m)) == (j = n_randint(state, m))) + continue; + + if (n_randint(state, 2)) + for (k = 0; k < n; k++) + mat->rows[j][k] = nmod_add(mat->rows[j][k], + mat->rows[i][k], mat->mod); + else + for (k = 0; k < n; k++) + mat->rows[j][k] = nmod_sub(mat->rows[j][k], + mat->rows[i][k], mat->mod); + } + else + { + if ((i = n_randint(state, n)) == (j = n_randint(state, n))) + continue; + if (n_randint(state, 2)) + for (k = 0; k < m; k++) + mat->rows[k][j] = nmod_add(mat->rows[k][j], + mat->rows[k][i], mat->mod); + else + for (k = 0; k < m; k++) + mat->rows[k][j] = nmod_sub(mat->rows[k][j], + mat->rows[k][i], mat->mod); + } + } +} diff --git a/external/flint-2.4.3/nmod_mat/randpermdiag.c b/external/flint-2.4.3/nmod_mat/randpermdiag.c new file mode 100644 index 0000000..317e03f --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/randpermdiag.c @@ -0,0 +1,55 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010,2011 Fredrik Johansson + +******************************************************************************/ + +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_mat.h" +#include "nmod_vec.h" +#include "perm.h" + +int +nmod_mat_randpermdiag(nmod_mat_t mat, flint_rand_t state, + mp_srcptr diag, slong n) +{ + int parity; + slong i; + slong * rows; + slong * cols; + + rows = _perm_init(mat->r); + cols = _perm_init(mat->c); + + parity = _perm_randtest(rows, mat->r, state); + parity ^= _perm_randtest(cols, mat->c, state); + + nmod_mat_zero(mat); + for (i = 0; i < n; i++) + nmod_mat_entry(mat, rows[i], cols[i]) = diag[i]; + + _perm_clear(rows); + _perm_clear(cols); + + return parity; +} diff --git a/external/flint-2.4.3/nmod_mat/randrank.c b/external/flint-2.4.3/nmod_mat/randrank.c new file mode 100644 index 0000000..a9d5dfb --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/randrank.c @@ -0,0 +1,52 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_mat.h" +#include "nmod_vec.h" + + +void +nmod_mat_randrank(nmod_mat_t mat, flint_rand_t state, slong rank) +{ + slong i; + mp_limb_t * diag; + + if (rank < 0 || rank > mat->r || rank > mat->c) + { + flint_printf("Exception (nmod_mat_randrank). Impossible rank.\n"); + abort(); + } + + diag = _nmod_vec_init(rank); + for (i = 0; i < rank; i++) + diag[i] = 1 + n_randint(state, mat->mod.n - 1); + + nmod_mat_randpermdiag(mat, state, diag, rank); + + _nmod_vec_clear(diag); +} diff --git a/external/flint-2.4.3/nmod_mat/randtest.c b/external/flint-2.4.3/nmod_mat/randtest.c new file mode 100644 index 0000000..262a87a --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/randtest.c @@ -0,0 +1,35 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_mat.h" + +void +nmod_mat_randtest(nmod_mat_t mat, flint_rand_t state) +{ + _nmod_vec_randtest(mat->entries, state, mat->r * mat->c, mat->mod); +} diff --git a/external/flint-2.4.3/nmod_mat/randtril.c b/external/flint-2.4.3/nmod_mat/randtril.c new file mode 100644 index 0000000..9ead832 --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/randtril.c @@ -0,0 +1,56 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_mat.h" + +void +nmod_mat_randtril(nmod_mat_t mat, flint_rand_t state, int unit) +{ + slong i, j; + + for (i = 0; i < mat->r; i++) + { + for (j = 0; j < mat->c; j++) + { + if (j < i) + { + nmod_mat_entry(mat, i, j) = n_randlimb(state) % (mat->mod.n); + } + else if (i == j) + { + nmod_mat_entry(mat, i, j) = n_randlimb(state) % (mat->mod.n); + if (unit || nmod_mat_entry(mat, i, j) == UWORD(0)) + nmod_mat_entry(mat, i, j) = UWORD(1); + } + else + { + nmod_mat_entry(mat, i, j) = UWORD(0); + } + } + } +} diff --git a/external/flint-2.4.3/nmod_mat/randtriu.c b/external/flint-2.4.3/nmod_mat/randtriu.c new file mode 100644 index 0000000..fc82bca --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/randtriu.c @@ -0,0 +1,56 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_mat.h" + +void +nmod_mat_randtriu(nmod_mat_t mat, flint_rand_t state, int unit) +{ + slong i, j; + + for (i = 0; i < mat->r; i++) + { + for (j = 0; j < mat->c; j++) + { + if (j > i) + { + nmod_mat_entry(mat, i, j) = n_randlimb(state) % (mat->mod.n); + } + else if (i == j) + { + nmod_mat_entry(mat, i, j) = n_randlimb(state) % (mat->mod.n); + if (unit || nmod_mat_entry(mat, i, j) == UWORD(0)) + nmod_mat_entry(mat, i, j) = UWORD(1); + } + else + { + nmod_mat_entry(mat, i, j) = UWORD(0); + } + } + } +} diff --git a/external/flint-2.4.3/nmod_mat/rank.c b/external/flint-2.4.3/nmod_mat/rank.c new file mode 100644 index 0000000..312895c --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/rank.c @@ -0,0 +1,54 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_vec.h" +#include "nmod_mat.h" + + +slong +nmod_mat_rank(const nmod_mat_t A) +{ + slong m, n, rank; + slong * perm; + nmod_mat_t tmp; + + m = A->r; + n = A->c; + + if (m == 0 || n == 0) + return 0; + + nmod_mat_init_set(tmp, A); + perm = flint_malloc(sizeof(slong) * m); + + rank = nmod_mat_lu(perm, tmp, 0); + + flint_free(perm); + nmod_mat_clear(tmp); + return rank; +} diff --git a/external/flint-2.4.3/nmod_mat/rref.c b/external/flint-2.4.3/nmod_mat/rref.c new file mode 100644 index 0000000..7d1406c --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/rref.c @@ -0,0 +1,122 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_mat.h" +#include "perm.h" + +slong +nmod_mat_rref(nmod_mat_t A) +{ + slong i, j, k, n, rank; + slong * pivots; + slong * nonpivots; + slong * P; + + nmod_mat_t U, V; + + n = A->c; + + P = _perm_init(nmod_mat_nrows(A)); + rank = nmod_mat_lu(P, A, 0); + _perm_clear(P); + + if (rank == 0) + return rank; + + /* Clear L */ + for (i = 0; i < A->r; i++) + for (j = 0; j < FLINT_MIN(i, rank); j++) + nmod_mat_entry(A, i, j) = UWORD(0); + + /* We now reorder U to proper upper triangular form U | V + with U full-rank triangular, set V = U^(-1) V, and then + put the column back in the original order. + + An improvement for some matrices would be to compress V by + discarding columns containing nothing but zeros. */ + + nmod_mat_init(U, rank, rank, A->mod.n); + nmod_mat_init(V, rank, n - rank, A->mod.n); + + pivots = flint_malloc(sizeof(slong) * rank); + nonpivots = flint_malloc(sizeof(slong) * (n - rank)); + + for (i = j = k = 0; i < rank; i++) + { + while (nmod_mat_entry(A, i, j) == UWORD(0)) + { + nonpivots[k] = j; + k++; + j++; + } + pivots[i] = j; + j++; + } + while (k < n - rank) + { + nonpivots[k] = j; + k++; + j++; + } + + for (i = 0; i < rank; i++) + { + for (j = 0; j <= i; j++) + nmod_mat_entry(U, j, i) = nmod_mat_entry(A, j, pivots[i]); + } + + for (i = 0; i < n - rank; i++) + { + for (j = 0; j < rank; j++) + nmod_mat_entry(V, j, i) = nmod_mat_entry(A, j, nonpivots[i]); + } + + nmod_mat_solve_triu(V, U, V, 0); + + /* Clear pivot columns */ + for (i = 0; i < rank; i++) + { + for (j = 0; j <= i; j++) + nmod_mat_entry(A, j, pivots[i]) = (i == j); + } + + /* Write back the actual content */ + for (i = 0; i < n - rank; i++) + { + for (j = 0; j < rank; j++) + nmod_mat_entry(A, j, nonpivots[i]) = nmod_mat_entry(V, j, i); + } + + nmod_mat_clear(U); + nmod_mat_clear(V); + + flint_free(pivots); + flint_free(nonpivots); + + return rank; +} diff --git a/external/flint-2.4.3/nmod_mat/scalar_mul.c b/external/flint-2.4.3/nmod_mat/scalar_mul.c new file mode 100644 index 0000000..d6d585b --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/scalar_mul.c @@ -0,0 +1,56 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_mat.h" +#include "nmod_vec.h" + +void +nmod_mat_scalar_mul(nmod_mat_t B, const nmod_mat_t A, mp_limb_t c) +{ + if (c == UWORD(0)) + { + nmod_mat_zero(B); + } + else if (c == UWORD(1)) + { + nmod_mat_set(B, A); + } + else if (c == A->mod.n - UWORD(1)) + { + nmod_mat_neg(B, A); + } + else + { + slong i, j; + + for (i = 0; i < A->r; i++) + for (j = 0; j < A->c; j++) + nmod_mat_entry(B, i, j) = n_mulmod2_preinv( + nmod_mat_entry(A, i, j), c, A->mod.n, A->mod.ninv); + } +} diff --git a/external/flint-2.4.3/nmod_mat/set.c b/external/flint-2.4.3/nmod_mat/set.c new file mode 100644 index 0000000..7df7751 --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/set.c @@ -0,0 +1,42 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_mat.h" +#include "nmod_vec.h" + +void +nmod_mat_set(nmod_mat_t B, const nmod_mat_t A) +{ + slong i; + + if (B == A || A->c == 0) + return; + + for (i = 0; i < A->r; i++) + _nmod_vec_set(B->rows[i], A->rows[i], A->c); +} diff --git a/external/flint-2.4.3/nmod_mat/solve.c b/external/flint-2.4.3/nmod_mat/solve.c new file mode 100644 index 0000000..fb90777 --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/solve.c @@ -0,0 +1,73 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010,2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_vec.h" +#include "nmod_mat.h" + + +int +nmod_mat_solve(nmod_mat_t X, const nmod_mat_t A, const nmod_mat_t B) +{ + slong i, rank, *perm; + nmod_mat_t LU; + int result; + + if (A->r == 0 || B->c == 0) + return 1; + + nmod_mat_init_set(LU, A); + perm = flint_malloc(sizeof(slong) * A->r); + for (i = 0; i < A->r; i++) + perm[i] = i; + + rank = nmod_mat_lu(perm, LU, 1); + + if (rank == A->r) + { + nmod_mat_t PB; + nmod_mat_window_init(PB, B, 0, 0, B->r, B->c); + for (i = 0; i < A->r; i++) + PB->rows[i] = B->rows[perm[i]]; + + nmod_mat_solve_tril(X, LU, PB, 1); + nmod_mat_solve_triu(X, LU, X, 0); + + nmod_mat_window_clear(PB); + result = 1; + } + else + { + result = 0; + } + + nmod_mat_clear(LU); + flint_free(perm); + + return result; +} diff --git a/external/flint-2.4.3/nmod_mat/solve_tril.c b/external/flint-2.4.3/nmod_mat/solve_tril.c new file mode 100644 index 0000000..ef2f089 --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/solve_tril.c @@ -0,0 +1,45 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010,2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_mat.h" +#include "nmod_vec.h" + +void +nmod_mat_solve_tril(nmod_mat_t X, const nmod_mat_t L, + const nmod_mat_t B, int unit) +{ + if (B->r < NMOD_MAT_SOLVE_TRI_ROWS_CUTOFF || + B->c < NMOD_MAT_SOLVE_TRI_COLS_CUTOFF) + { + nmod_mat_solve_tril_classical(X, L, B, unit); + } + else + { + nmod_mat_solve_tril_recursive(X, L, B, unit); + } +} diff --git a/external/flint-2.4.3/nmod_mat/solve_tril_classical.c b/external/flint-2.4.3/nmod_mat/solve_tril_classical.c new file mode 100644 index 0000000..c2b6359 --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/solve_tril_classical.c @@ -0,0 +1,79 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010,2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_mat.h" +#include "nmod_vec.h" + +void +nmod_mat_solve_tril_classical(nmod_mat_t X, const nmod_mat_t L, + const nmod_mat_t B, int unit) +{ + int nlimbs; + slong i, j, n, m; + nmod_t mod; + mp_ptr inv, tmp; + + n = L->r; + m = B->c; + mod = L->mod; + + if (!unit) + { + inv = _nmod_vec_init(n); + for (i = 0; i < n; i++) + inv[i] = n_invmod(nmod_mat_entry(L, i, i), mod.n); + } + else + inv = NULL; + + nlimbs = _nmod_vec_dot_bound_limbs(n, mod); + tmp = _nmod_vec_init(n); + + for (i = 0; i < m; i++) + { + for (j = 0; j < n; j++) + tmp[j] = nmod_mat_entry(X, j, i); + + for (j = 0; j < n; j++) + { + mp_limb_t s; + s = _nmod_vec_dot(L->rows[j], tmp, j, mod, nlimbs); + s = nmod_sub(nmod_mat_entry(B, j, i), s, mod); + if (!unit) + s = n_mulmod2_preinv(s, inv[j], mod.n, mod.ninv); + tmp[j] = s; + } + + for (j = 0; j < n; j++) + nmod_mat_entry(X, j, i) = tmp[j]; + } + + _nmod_vec_clear(tmp); + if (!unit) + _nmod_vec_clear(inv); +} diff --git a/external/flint-2.4.3/nmod_mat/solve_tril_recursive.c b/external/flint-2.4.3/nmod_mat/solve_tril_recursive.c new file mode 100644 index 0000000..89cb79b --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/solve_tril_recursive.c @@ -0,0 +1,75 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010,2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_mat.h" +#include "nmod_vec.h" + + +void +nmod_mat_solve_tril_recursive(nmod_mat_t X, + const nmod_mat_t L, const nmod_mat_t B, + int unit) +{ + nmod_mat_t LA, LC, LD, XX, XY, BX, BY; + slong r, n, m; + + n = L->r; + m = B->c; + r = n / 2; + + if (n == 0 || m == 0) + return; + + /* + Denoting inv(M) by M^, we have: + + [A 0]^ [X] == [A^ 0 ] [X] == [A^ X] + [C D] [Y] == [-D^ C A^ D^] [Y] == [D^ (Y - C A^ X)] + */ + + nmod_mat_window_init(LA, L, 0, 0, r, r); + nmod_mat_window_init(LC, L, r, 0, n, r); + nmod_mat_window_init(LD, L, r, r, n, n); + nmod_mat_window_init(BX, B, 0, 0, r, m); + nmod_mat_window_init(BY, B, r, 0, n, m); + nmod_mat_window_init(XX, X, 0, 0, r, m); + nmod_mat_window_init(XY, X, r, 0, n, m); + + nmod_mat_solve_tril(XX, LA, BX, unit); + nmod_mat_submul(XY, BY, LC, XX); + nmod_mat_solve_tril(XY, LD, XY, unit); + + nmod_mat_window_clear(LA); + nmod_mat_window_clear(LC); + nmod_mat_window_clear(LD); + nmod_mat_window_clear(BX); + nmod_mat_window_clear(BY); + nmod_mat_window_clear(XX); + nmod_mat_window_clear(XY); +} diff --git a/external/flint-2.4.3/nmod_mat/solve_triu.c b/external/flint-2.4.3/nmod_mat/solve_triu.c new file mode 100644 index 0000000..07bc08a --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/solve_triu.c @@ -0,0 +1,45 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010,2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_mat.h" +#include "nmod_vec.h" + +void +nmod_mat_solve_triu(nmod_mat_t X, const nmod_mat_t U, + const nmod_mat_t B, int unit) +{ + if (B->r < NMOD_MAT_SOLVE_TRI_ROWS_CUTOFF || + B->c < NMOD_MAT_SOLVE_TRI_COLS_CUTOFF) + { + nmod_mat_solve_triu_classical(X, U, B, unit); + } + else + { + nmod_mat_solve_triu_recursive(X, U, B, unit); + } +} diff --git a/external/flint-2.4.3/nmod_mat/solve_triu_classical.c b/external/flint-2.4.3/nmod_mat/solve_triu_classical.c new file mode 100644 index 0000000..1351168 --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/solve_triu_classical.c @@ -0,0 +1,80 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010,2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_mat.h" +#include "nmod_vec.h" + +void +nmod_mat_solve_triu_classical(nmod_mat_t X, const nmod_mat_t U, + const nmod_mat_t B, int unit) +{ + int nlimbs; + slong i, j, n, m; + nmod_t mod; + mp_ptr inv, tmp; + + n = U->r; + m = B->c; + mod = U->mod; + + if (!unit) + { + inv = _nmod_vec_init(n); + for (i = 0; i < n; i++) + inv[i] = n_invmod(nmod_mat_entry(U, i, i), mod.n); + } + else + inv = NULL; + + nlimbs = _nmod_vec_dot_bound_limbs(n, mod); + tmp = _nmod_vec_init(n); + + for (i = 0; i < m; i++) + { + for (j = 0; j < n; j++) + tmp[j] = nmod_mat_entry(X, j, i); + + for (j = n - 1; j >= 0; j--) + { + mp_limb_t s; + s = _nmod_vec_dot(U->rows[j] + j + 1, + tmp + j + 1, n - j - 1, mod, nlimbs); + s = nmod_sub(nmod_mat_entry(B, j, i), s, mod); + if (!unit) + s = n_mulmod2_preinv(s, inv[j], mod.n, mod.ninv); + tmp[j] = s; + } + + for (j = 0; j < n; j++) + nmod_mat_entry(X, j, i) = tmp[j]; + } + + _nmod_vec_clear(tmp); + if (!unit) + _nmod_vec_clear(inv); +} diff --git a/external/flint-2.4.3/nmod_mat/solve_triu_recursive.c b/external/flint-2.4.3/nmod_mat/solve_triu_recursive.c new file mode 100644 index 0000000..ff330d6 --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/solve_triu_recursive.c @@ -0,0 +1,73 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010,2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_mat.h" +#include "nmod_vec.h" + +void +nmod_mat_solve_triu_recursive(nmod_mat_t X, + const nmod_mat_t U, const nmod_mat_t B, + int unit) +{ + nmod_mat_t UA, UB, UD, XX, XY, BX, BY; + slong r, n, m; + + n = U->r; + m = B->c; + r = n / 2; + + if (n == 0 || m == 0) + return; + + /* + Denoting inv(M) by M^, we have: + + [A B]^ [X] == [A^ (X - B D^ Y)] + [0 D] [Y] == [ D^ Y ] + */ + + nmod_mat_window_init(UA, U, 0, 0, r, r); + nmod_mat_window_init(UB, U, 0, r, r, n); + nmod_mat_window_init(UD, U, r, r, n, n); + nmod_mat_window_init(BX, B, 0, 0, r, m); + nmod_mat_window_init(BY, B, r, 0, n, m); + nmod_mat_window_init(XX, X, 0, 0, r, m); + nmod_mat_window_init(XY, X, r, 0, n, m); + + nmod_mat_solve_triu(XY, UD, BY, unit); + nmod_mat_submul(XX, BX, UB, XY); + nmod_mat_solve_triu(XX, UA, XX, unit); + + nmod_mat_window_clear(UA); + nmod_mat_window_clear(UB); + nmod_mat_window_clear(UD); + nmod_mat_window_clear(BX); + nmod_mat_window_clear(BY); + nmod_mat_window_clear(XX); + nmod_mat_window_clear(XY); +} diff --git a/external/flint-2.4.3/nmod_mat/solve_vec.c b/external/flint-2.4.3/nmod_mat/solve_vec.c new file mode 100644 index 0000000..b8d6860 --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/solve_vec.c @@ -0,0 +1,59 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010,2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_vec.h" +#include "nmod_mat.h" + +int +nmod_mat_solve_vec(mp_ptr x, const nmod_mat_t A, mp_srcptr b) +{ + nmod_mat_t X, B; + int result; + slong i, m; + + m = A->r; + + if (m == 0) + return 1; + + /* This is a bit of a hack. There should be a function to create + a window into a vector */ + nmod_mat_window_init(X, A, 0, 0, m, 1); + nmod_mat_window_init(B, A, 0, 0, m, 1); + + for (i = 0; i < m; i++) X->rows[i] = x + i; + for (i = 0; i < m; i++) B->rows[i] = (mp_ptr) (b + i); + + result = nmod_mat_solve(X, A, B); + + nmod_mat_window_clear(X); + nmod_mat_window_clear(B); + + return result; +} diff --git a/external/flint-2.4.3/nmod_mat/sub.c b/external/flint-2.4.3/nmod_mat/sub.c new file mode 100644 index 0000000..9487e03 --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/sub.c @@ -0,0 +1,44 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_mat.h" +#include "nmod_vec.h" + +void +nmod_mat_sub(nmod_mat_t C, const nmod_mat_t A, const nmod_mat_t B) +{ + slong i; + + if (C->c == 0) + return; + + for (i = 0; i < C->r; i++) + { + _nmod_vec_sub(C->rows[i], A->rows[i], B->rows[i], C->c, C->mod); + } +} diff --git a/external/flint-2.4.3/nmod_mat/submul.c b/external/flint-2.4.3/nmod_mat/submul.c new file mode 100644 index 0000000..6e28c9b --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/submul.c @@ -0,0 +1,56 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_mat.h" +#include "nmod_vec.h" + +void +nmod_mat_submul(nmod_mat_t D, const nmod_mat_t C, + const nmod_mat_t A, const nmod_mat_t B) +{ + slong m, k, n; + + m = A->r; + k = A->c; + n = B->c; + + if (m < NMOD_MAT_MUL_STRASSEN_CUTOFF || + n < NMOD_MAT_MUL_STRASSEN_CUTOFF || + k < NMOD_MAT_MUL_STRASSEN_CUTOFF) + { + _nmod_mat_mul_classical(D, C, A, B, -1); + } + else + { + nmod_mat_t tmp; + nmod_mat_init(tmp, m, n, A->mod.n); + nmod_mat_mul_strassen(tmp, A, B); + nmod_mat_sub(D, C, tmp); + nmod_mat_clear(tmp); + } +} diff --git a/external/flint-2.4.3/nmod_mat/test/t-add.c b/external/flint-2.4.3/nmod_mat/test/t-add.c new file mode 100644 index 0000000..f39b498 --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/test/t-add.c @@ -0,0 +1,79 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "nmod_mat.h" +#include "ulong_extras.h" + +int +main(void) +{ + slong m, n, mod, rep; + FLINT_TEST_INIT(state); + + + flint_printf("add/sub...."); + fflush(stdout); + + for (rep = 0; rep < 1000 * flint_test_multiplier(); rep++) + { + nmod_mat_t A, B, C, D; + + m = n_randint(state, 20); + n = n_randint(state, 20); + mod = n_randtest_not_zero(state); + + nmod_mat_init(A, m, n, mod); + nmod_mat_init(B, m, n, mod); + nmod_mat_init(C, m, n, mod); + nmod_mat_init(D, m, n, mod); + + nmod_mat_randtest(A, state); + nmod_mat_randtest(B, state); + + nmod_mat_add(C, A, B); + nmod_mat_sub(C, C, B); + + if (!nmod_mat_equal(C, A)) + { + flint_printf("FAIL\n"); + abort(); + } + + nmod_mat_clear(A); + nmod_mat_clear(B); + nmod_mat_clear(C); + nmod_mat_clear(D); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_mat/test/t-addmul.c b/external/flint-2.4.3/nmod_mat/test/t-addmul.c new file mode 100644 index 0000000..7076f8c --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/test/t-addmul.c @@ -0,0 +1,116 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "nmod_mat.h" +#include "ulong_extras.h" + +int +main(void) +{ + slong i; + FLINT_TEST_INIT(state); + + + flint_printf("addmul...."); + fflush(stdout); + + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + nmod_mat_t A, B, C, D, T, E; + mp_limb_t mod = n_randtest_not_zero(state); + + slong m, k, n; + + m = n_randint(state, 100); + k = n_randint(state, 100); + n = n_randint(state, 100); + + /* Force Strassen test */ + if (i < 5) + { + m += 300; + k += 300; + n += 300; + } + + nmod_mat_init(A, m, k, mod); + nmod_mat_init(B, k, n, mod); + nmod_mat_init(C, m, n, mod); + nmod_mat_init(D, m, n, mod); + nmod_mat_init(T, m, n, mod); + nmod_mat_init(E, m, n, mod); + + nmod_mat_randtest(A, state); + nmod_mat_randtest(B, state); + nmod_mat_randtest(C, state); + + nmod_mat_addmul(D, C, A, B); + + nmod_mat_mul(T, A, B); + nmod_mat_add(E, C, T); + + if (!nmod_mat_equal(D, E)) + { + flint_printf("FAIL: results not equal\n"); + nmod_mat_print_pretty(A); + nmod_mat_print_pretty(B); + nmod_mat_print_pretty(C); + nmod_mat_print_pretty(D); + nmod_mat_print_pretty(E); + abort(); + } + + /* Check aliasing */ + nmod_mat_addmul(C, C, A, B); + + if (!nmod_mat_equal(C, E)) + { + flint_printf("FAIL: results not equal (aliasing)\n"); + nmod_mat_print_pretty(A); + nmod_mat_print_pretty(B); + nmod_mat_print_pretty(C); + nmod_mat_print_pretty(D); + nmod_mat_print_pretty(E); + abort(); + } + + nmod_mat_clear(A); + nmod_mat_clear(B); + nmod_mat_clear(C); + nmod_mat_clear(D); + nmod_mat_clear(E); + nmod_mat_clear(T); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_mat/test/t-det.c b/external/flint-2.4.3/nmod_mat/test/t-det.c new file mode 100644 index 0000000..c632c39 --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/test/t-det.c @@ -0,0 +1,100 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "nmod_mat.h" +#include "ulong_extras.h" +#include "fmpz.h" +#include "fmpz_mat.h" + +int +main(void) +{ + slong m, mod, rep; + FLINT_TEST_INIT(state); + + + flint_printf("det...."); + fflush(stdout); + + for (rep = 0; rep < 1000 * flint_test_multiplier(); rep++) + { + nmod_mat_t A; + fmpz_mat_t B; + mp_limb_t Adet; + fmpz_t Bdet; + ulong t; + + m = n_randint(state, 30); + mod = n_randtest_prime(state, 0); + + nmod_mat_init(A, m, m, mod); + fmpz_mat_init(B, m, m); + + switch (rep % 3) + { + case 0: + nmod_mat_randrank(A, state, m); + nmod_mat_randops(A, n_randint(state, 2*m + 1), state); + break; + case 1: + t = n_randint(state, m); + t = FLINT_MIN(t, m); + nmod_mat_randrank(A, state, m); + nmod_mat_randops(A, n_randint(state, 2*m + 1), state); + break; + default: + nmod_mat_randtest(A, state); + } + + fmpz_mat_set_nmod_mat_unsigned(B, A); + + Adet = nmod_mat_det(A); + + fmpz_init(Bdet); + fmpz_mat_det_bareiss(Bdet, B); + fmpz_mod_ui(Bdet, Bdet, mod); + + if (Adet != fmpz_get_ui(Bdet)) + { + flint_printf("FAIL\n"); + abort(); + } + + nmod_mat_clear(A); + fmpz_mat_clear(B); + fmpz_clear(Bdet); + } + + + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_mat/test/t-init_clear.c b/external/flint-2.4.3/nmod_mat/test/t-init_clear.c new file mode 100644 index 0000000..8399cb2 --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/test/t-init_clear.c @@ -0,0 +1,79 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "nmod_mat.h" +#include "ulong_extras.h" + +int +main(void) +{ + slong m, n, mod, i, j, rep; + FLINT_TEST_INIT(state); + + + flint_printf("init/clear...."); + fflush(stdout); + + for (rep = 0; rep < 100 * flint_test_multiplier(); rep++) + { + nmod_mat_t A; + + m = n_randint(state, 50); + n = n_randint(state, 50); + mod = n_randtest_not_zero(state); + + nmod_mat_init(A, m, n, mod); + + for (i = 0; i < m; i++) + { + for (j = 0; j < n; j++) + { + if (A->rows[i][j] != UWORD(0)) + { + flint_printf("FAIL: entries not zero!\n"); + abort(); + } + } + } + + if (A->mod.n != mod) + { + flint_printf("FAIL: bad modulus\n"); + abort(); + } + + nmod_mat_clear(A); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_mat/test/t-inv.c b/external/flint-2.4.3/nmod_mat/test/t-inv.c new file mode 100644 index 0000000..d9b9ac1 --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/test/t-inv.c @@ -0,0 +1,146 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_mat.h" +#include "ulong_extras.h" + + +int +main(void) +{ + nmod_mat_t A, B, C, I; + slong i, j, m, r; + mp_limb_t mod; + int result; + FLINT_TEST_INIT(state); + + + flint_printf("inv...."); + fflush(stdout); + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + m = n_randint(state, 20); + mod = n_randtest_prime(state, 0); + + nmod_mat_init(A, m, m, mod); + nmod_mat_init(B, m, m, mod); + nmod_mat_init(C, m, m, mod); + nmod_mat_init(I, m, m, mod); + + for (j = 0; j < m; j++) + I->rows[j][j] = UWORD(1); + + /* Verify that A * A^-1 = I for random matrices */ + + nmod_mat_randrank(A, state, m); + /* Dense or sparse? */ + if (n_randint(state, 2)) + nmod_mat_randops(A, 1+n_randint(state, 1+m*m), state); + + result = nmod_mat_inv(B, A); + nmod_mat_mul(C, A, B); + + if (!nmod_mat_equal(C, I) || !result) + { + flint_printf("FAIL:\n"); + flint_printf("A * A^-1 != I!\n"); + flint_printf("A:\n"); + nmod_mat_print_pretty(A); + flint_printf("A^-1:\n"); + nmod_mat_print_pretty(B); + flint_printf("A * A^-1:\n"); + nmod_mat_print_pretty(C); + flint_printf("\n"); + abort(); + } + + /* Test aliasing */ + nmod_mat_set(C, A); + nmod_mat_inv(A, A); + nmod_mat_mul(B, A, C); + + if (!nmod_mat_equal(B, I)) + { + flint_printf("FAIL:\n"); + flint_printf("aliasing failed!\n"); + nmod_mat_print_pretty(C); + abort(); + } + + nmod_mat_clear(A); + nmod_mat_clear(B); + nmod_mat_clear(C); + nmod_mat_clear(I); + } + + /* Test singular systems */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + m = 1 + n_randint(state, 20); + mod = n_randtest_prime(state, 0); + r = n_randint(state, m); + + nmod_mat_init(A, m, m, mod); + nmod_mat_init(B, m, m, mod); + + nmod_mat_randrank(A, state, r); + + /* Dense */ + if (n_randint(state, 2)) + nmod_mat_randops(A, 1+n_randint(state, 1+m*m), state); + + result = nmod_mat_inv(B, A); + + if (result) + { + flint_printf("FAIL:\n"); + flint_printf("singular matrix reported as invertible\n"); + abort(); + } + + /* Aliasing */ + result = nmod_mat_inv(A, A); + if (result) + { + flint_printf("FAIL:\n"); + flint_printf("singular matrix reported as invertiblen"); + abort(); + } + + nmod_mat_clear(A); + nmod_mat_clear(B); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_mat/test/t-lu_classical.c b/external/flint-2.4.3/nmod_mat/test/t-lu_classical.c new file mode 100644 index 0000000..cd55e0a --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/test/t-lu_classical.c @@ -0,0 +1,169 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010,2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_mat.h" +#include "ulong_extras.h" + +void perm(nmod_mat_t A, slong * P) +{ + slong i; + mp_ptr * tmp; + + if (A->c == 0 || A->r == 0) + return; + + tmp = flint_malloc(sizeof(mp_ptr) * A->r); + + for (i = 0; i < A->r; i++) tmp[P[i]] = A->rows[i]; + for (i = 0; i < A->r; i++) A->rows[i] = tmp[i]; + + flint_free(tmp); +} + +void check(slong * P, nmod_mat_t LU, const nmod_mat_t A, slong rank) +{ + nmod_mat_t B, L, U; + slong m, n, i, j; + + m = A->r; + n = A->c; + + nmod_mat_init(B, m, n, A->mod.n); + nmod_mat_init(L, m, m, A->mod.n); + nmod_mat_init(U, m, n, A->mod.n); + + rank = FLINT_ABS(rank); + + for (i = rank; i < FLINT_MIN(m, n); i++) + { + for (j = i; j < n; j++) + { + if (nmod_mat_entry(LU, i, j) != 0) + { + flint_printf("FAIL: wrong shape!\n"); + abort(); + } + } + } + + for (i = 0; i < m; i++) + { + for (j = 0; j < FLINT_MIN(i, n); j++) + nmod_mat_entry(L, i, j) = nmod_mat_entry(LU, i, j); + if (i < rank) + nmod_mat_entry(L, i, i) = UWORD(1); + for (j = i; j < n; j++) + nmod_mat_entry(U, i, j) = nmod_mat_entry(LU, i, j); + } + + nmod_mat_mul(B, L, U); + perm(B, P); + + if (!nmod_mat_equal(A, B)) + { + flint_printf("FAIL\n"); + flint_printf("A:\n"); + nmod_mat_print_pretty(A); + flint_printf("LU:\n"); + nmod_mat_print_pretty(LU); + flint_printf("B:\n"); + nmod_mat_print_pretty(B); + abort(); + } + + nmod_mat_clear(B); + nmod_mat_clear(L); + nmod_mat_clear(U); +} + + + +int +main(void) +{ + slong i; + + FLINT_TEST_INIT(state); + + + flint_printf("lu_classical...."); + fflush(stdout); + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_mat_t A, LU; + mp_limb_t mod; + slong m, n, r, d, rank; + slong * P; + + m = n_randint(state, 20); + n = n_randint(state, 20); + mod = n_randtest_prime(state, 0); + + for (r = 0; r <= FLINT_MIN(m, n); r++) + { + nmod_mat_init(A, m, n, mod); + nmod_mat_randrank(A, state, r); + + if (n_randint(state, 2)) + { + d = n_randint(state, 2*m*n + 1); + nmod_mat_randops(A, d, state); + } + + nmod_mat_init_set(LU, A); + P = flint_malloc(sizeof(slong) * m); + + rank = nmod_mat_lu_classical(P, LU, 0); + + if (r != rank) + { + flint_printf("FAIL:\n"); + flint_printf("wrong rank!\n"); + flint_printf("A:"); + nmod_mat_print_pretty(A); + flint_printf("LU:"); + nmod_mat_print_pretty(LU); + abort(); + } + + check(P, LU, A, rank); + + nmod_mat_clear(A); + nmod_mat_clear(LU); + flint_free(P); + } + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_mat/test/t-lu_recursive.c b/external/flint-2.4.3/nmod_mat/test/t-lu_recursive.c new file mode 100644 index 0000000..52a9421 --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/test/t-lu_recursive.c @@ -0,0 +1,169 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010,2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_mat.h" +#include "ulong_extras.h" + +void perm(nmod_mat_t A, slong * P) +{ + slong i; + mp_ptr * tmp; + + if (A->c == 0 || A->r == 0) + return; + + tmp = flint_malloc(sizeof(mp_ptr) * A->r); + + for (i = 0; i < A->r; i++) tmp[P[i]] = A->rows[i]; + for (i = 0; i < A->r; i++) A->rows[i] = tmp[i]; + + flint_free(tmp); +} + +void check(slong * P, nmod_mat_t LU, const nmod_mat_t A, slong rank) +{ + nmod_mat_t B, L, U; + slong m, n, i, j; + + m = A->r; + n = A->c; + + nmod_mat_init(B, m, n, A->mod.n); + nmod_mat_init(L, m, m, A->mod.n); + nmod_mat_init(U, m, n, A->mod.n); + + rank = FLINT_ABS(rank); + + for (i = rank; i < FLINT_MIN(m, n); i++) + { + for (j = i; j < n; j++) + { + if (nmod_mat_entry(LU, i, j) != 0) + { + flint_printf("FAIL: wrong shape!\n"); + abort(); + } + } + } + + for (i = 0; i < m; i++) + { + for (j = 0; j < FLINT_MIN(i, n); j++) + nmod_mat_entry(L, i, j) = nmod_mat_entry(LU, i, j); + if (i < rank) + nmod_mat_entry(L, i, i) = UWORD(1); + for (j = i; j < n; j++) + nmod_mat_entry(U, i, j) = nmod_mat_entry(LU, i, j); + } + + nmod_mat_mul(B, L, U); + perm(B, P); + + if (!nmod_mat_equal(A, B)) + { + flint_printf("FAIL\n"); + flint_printf("A:\n"); + nmod_mat_print_pretty(A); + flint_printf("LU:\n"); + nmod_mat_print_pretty(LU); + flint_printf("B:\n"); + nmod_mat_print_pretty(B); + abort(); + } + + nmod_mat_clear(B); + nmod_mat_clear(L); + nmod_mat_clear(U); +} + + + +int +main(void) +{ + slong i; + + FLINT_TEST_INIT(state); + + + flint_printf("lu_recursive...."); + fflush(stdout); + + for (i = 0; i < 2000 * flint_test_multiplier(); i++) + { + nmod_mat_t A, LU; + mp_limb_t mod; + slong m, n, r, d, rank; + slong * P; + + m = n_randint(state, 30); + n = n_randint(state, 30); + mod = n_randtest_prime(state, 0); + + for (r = 0; r <= FLINT_MIN(m, n); r++) + { + nmod_mat_init(A, m, n, mod); + nmod_mat_randrank(A, state, r); + + if (n_randint(state, 2)) + { + d = n_randint(state, 2*m*n + 1); + nmod_mat_randops(A, d, state); + } + + nmod_mat_init_set(LU, A); + P = flint_malloc(sizeof(slong) * m); + + rank = nmod_mat_lu_recursive(P, LU, 0); + + if (r != rank) + { + flint_printf("FAIL:\n"); + flint_printf("wrong rank!\n"); + flint_printf("A:"); + nmod_mat_print_pretty(A); + flint_printf("LU:"); + nmod_mat_print_pretty(LU); + abort(); + } + + check(P, LU, A, rank); + + nmod_mat_clear(A); + nmod_mat_clear(LU); + flint_free(P); + } + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_mat/test/t-mul.c b/external/flint-2.4.3/nmod_mat/test/t-mul.c new file mode 100644 index 0000000..ad6ca46 --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/test/t-mul.c @@ -0,0 +1,138 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "nmod_mat.h" +#include "ulong_extras.h" + +void +nmod_mat_mul_check(nmod_mat_t C, const nmod_mat_t A, const nmod_mat_t B) +{ + slong i, j, k; + + mp_limb_t s0, s1, s2; + mp_limb_t t0, t1; + + for (i = 0; i < A->r; i++) + { + for (j = 0; j < B->c; j++) + { + s0 = s1 = s2 = UWORD(0); + + for (k = 0; k < A->c; k++) + { + umul_ppmm(t1, t0, A->rows[i][k], B->rows[k][j]); + add_sssaaaaaa(s2, s1, s0, s2, s1, s0, 0, t1, t0); + } + + NMOD_RED(s2, s2, C->mod); + NMOD_RED3(s0, s2, s1, s0, C->mod); + C->rows[i][j] = s0; + } + } +} + +int +main(void) +{ + slong i; + FLINT_TEST_INIT(state); + + + flint_printf("mul...."); + fflush(stdout); + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_mat_t A, B, C, D; + mp_limb_t mod; + + slong m, k, n; + + m = n_randint(state, 50); + k = n_randint(state, 50); + n = n_randint(state, 50); + + /* We want to generate matrices with many entries close to half + or full limbs with high probability, to stress overflow handling */ + switch (n_randint(state, 3)) + { + case 0: + mod = n_randtest_not_zero(state); + break; + case 1: + mod = UWORD_MAX/2 + 1 - n_randbits(state, 4); + break; + case 2: + default: + mod = UWORD_MAX - n_randbits(state, 4); + break; + } + + nmod_mat_init(A, m, n, mod); + nmod_mat_init(B, n, k, mod); + nmod_mat_init(C, m, k, mod); + nmod_mat_init(D, m, k, mod); + + if (n_randint(state, 2)) + nmod_mat_randtest(A, state); + else + nmod_mat_randfull(A, state); + + if (n_randint(state, 2)) + nmod_mat_randtest(B, state); + else + nmod_mat_randfull(B, state); + + nmod_mat_randtest(C, state); /* make sure noise in the output is ok */ + + nmod_mat_mul(C, A, B); + nmod_mat_mul_check(D, A, B); + + if (!nmod_mat_equal(C, D)) + { + flint_printf("FAIL: results not equal\n"); + nmod_mat_print_pretty(A); + nmod_mat_print_pretty(B); + nmod_mat_print_pretty(C); + nmod_mat_print_pretty(D); + abort(); + } + + nmod_mat_clear(A); + nmod_mat_clear(B); + nmod_mat_clear(C); + nmod_mat_clear(D); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_mat/test/t-mul_strassen.c b/external/flint-2.4.3/nmod_mat/test/t-mul_strassen.c new file mode 100644 index 0000000..92bd19d --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/test/t-mul_strassen.c @@ -0,0 +1,86 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "nmod_mat.h" +#include "ulong_extras.h" + +int +main(void) +{ + slong i; + FLINT_TEST_INIT(state); + + + flint_printf("mul_strassen...."); + fflush(stdout); + + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + nmod_mat_t A, B, C, D; + mp_limb_t mod = n_randtest_not_zero(state); + + slong m, k, n; + + m = n_randint(state, 400); + k = n_randint(state, 400); + n = n_randint(state, 400); + + nmod_mat_init(A, m, n, mod); + nmod_mat_init(B, n, k, mod); + nmod_mat_init(C, m, k, mod); + nmod_mat_init(D, m, k, mod); + + nmod_mat_randtest(A, state); + nmod_mat_randtest(B, state); + + nmod_mat_mul_classical(C, A, B); + nmod_mat_mul_strassen(D, A, B); + + if (!nmod_mat_equal(C, D)) + { + flint_printf("FAIL: results not equal\n"); + nmod_mat_print_pretty(A); + nmod_mat_print_pretty(B); + nmod_mat_print_pretty(C); + nmod_mat_print_pretty(D); + abort(); + } + + nmod_mat_clear(A); + nmod_mat_clear(B); + nmod_mat_clear(C); + nmod_mat_clear(D); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_mat/test/t-neg.c b/external/flint-2.4.3/nmod_mat/test/t-neg.c new file mode 100644 index 0000000..2f14fc0 --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/test/t-neg.c @@ -0,0 +1,90 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "nmod_mat.h" +#include "ulong_extras.h" + +int +main(void) +{ + slong m, n, mod, rep; + FLINT_TEST_INIT(state); + + + flint_printf("neg...."); + fflush(stdout); + + for (rep = 0; rep < 1000 * flint_test_multiplier(); rep++) + { + nmod_mat_t A, B, C, D; + + m = n_randint(state, 20); + n = n_randint(state, 20); + mod = n_randtest_not_zero(state); + + nmod_mat_init(A, m, n, mod); + nmod_mat_init(B, m, n, mod); + nmod_mat_init(C, m, n, mod); + nmod_mat_init(D, m, n, mod); + + nmod_mat_randtest(A, state); + nmod_mat_randtest(B, state); + + nmod_mat_sub(C, A, B); + + nmod_mat_neg(B, B); + nmod_mat_add(D, A, B); + + if (!nmod_mat_equal(C, D)) + { + flint_printf("FAIL\n"); + abort(); + } + + nmod_mat_neg(C, B); + nmod_mat_neg(B, B); + + if (!nmod_mat_equal(C, B)) + { + flint_printf("FAIL\n"); + abort(); + } + + nmod_mat_clear(A); + nmod_mat_clear(B); + nmod_mat_clear(C); + nmod_mat_clear(D); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_mat/test/t-nullspace.c b/external/flint-2.4.3/nmod_mat/test/t-nullspace.c new file mode 100644 index 0000000..91a7944 --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/test/t-nullspace.c @@ -0,0 +1,110 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_mat.h" +#include "ulong_extras.h" + + +int +main(void) +{ + slong i; + + FLINT_TEST_INIT(state); + + flint_printf("nullspace...."); + fflush(stdout); + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_mat_t A, B, ker; + mp_limb_t mod; + slong m, n, d, r, nullity, nulrank; + + m = n_randint(state, 30); + n = n_randint(state, 30); + + for (r = 0; r <= FLINT_MIN(m,n); r++) + { + mod = n_randtest_prime(state, 0); + d = n_randint(state, 2*m*n + 1); + + nmod_mat_init(A, m, n, mod); + nmod_mat_init(ker, n, n, mod); + nmod_mat_init(B, m, n, mod); + + nmod_mat_randrank(A, state, r); + /* Densify */ + if (n_randlimb(state) % 2) + nmod_mat_randops(A, d, state); + + nullity = nmod_mat_nullspace(ker, A); + nulrank = nmod_mat_rank(ker); + + if (nullity != nulrank) + { + flint_printf("FAIL:\n"); + flint_printf("rank(ker) != nullity!\n"); + nmod_mat_print_pretty(A); + flint_printf("\n"); + abort(); + } + + if (nullity + r != n) + { + flint_printf("FAIL:\n"); + flint_printf("nullity + rank != n\n"); + nmod_mat_print_pretty(A); + flint_printf("\n"); + abort(); + } + + nmod_mat_mul(B, A, ker); + + if (nmod_mat_rank(B) != 0) + { + flint_printf("FAIL:\n"); + flint_printf("A * ker != 0\n"); + nmod_mat_print_pretty(A); + flint_printf("\n"); + abort(); + } + + nmod_mat_clear(A); + nmod_mat_clear(ker); + nmod_mat_clear(B); + } + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_mat/test/t-rank.c b/external/flint-2.4.3/nmod_mat/test/t-rank.c new file mode 100644 index 0000000..c61ee9e --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/test/t-rank.c @@ -0,0 +1,100 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_mat.h" +#include "ulong_extras.h" + + +int +main(void) +{ + nmod_mat_t A; + slong i, m, n, d, r; + mp_limb_t mod; + FLINT_TEST_INIT(state); + + + flint_printf("rank...."); + fflush(stdout); + + /* Maximally sparse matrices of given rank */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + m = n_randint(state, 20); + n = n_randint(state, 20); + mod = n_randtest_prime(state, 0); + + for (r = 0; r <= FLINT_MIN(m,n); r++) + { + nmod_mat_init(A, m, n, mod); + nmod_mat_randrank(A, state, r); + /* flint_printf("SPARSE %wd\n", r); + nmod_mat_print_pretty(A); */ + if (r != nmod_mat_rank(A)) + { + flint_printf("FAIL:\n"); + flint_printf("wrong rank!\n"); + abort(); + } + nmod_mat_clear(A); + } + } + + /* Dense */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + m = n_randint(state, 20); + n = n_randint(state, 20); + mod = n_randtest_prime(state, 0); + + for (r = 0; r <= FLINT_MIN(m,n); r++) + { + d = n_randint(state, 2*m*n + 1); + nmod_mat_init(A, m, n, mod); + nmod_mat_randrank(A, state, r); + nmod_mat_randops(A, d, state); + /* + flint_printf("DENSE %wd %wd\n", r, d); + nmod_mat_print_pretty(A); */ + if (r != nmod_mat_rank(A)) + { + flint_printf("FAIL:\n"); + flint_printf("wrong rank!\n"); + abort(); + } + nmod_mat_clear(A); + } + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_mat/test/t-rref.c b/external/flint-2.4.3/nmod_mat/test/t-rref.c new file mode 100644 index 0000000..5cb4a48 --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/test/t-rref.c @@ -0,0 +1,167 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_mat.h" +#include "ulong_extras.h" +#include "perm.h" + +int check_rref_form(slong * perm, nmod_mat_t A, slong rank) +{ + slong i, j, k, prev_pivot; + + /* bottom should be zero */ + for (i = rank; i < A->r; i++) + for (j = 0; j < A->c; j++) + if (nmod_mat_entry(A, i, j) != 0) + return 0; + + prev_pivot = -1; + + for (i = 0; i < rank; i++) + { + for (j = 0; j < A->c; j++) + { + if (nmod_mat_entry(A, i, j) != 0) + { + /* pivot should have a higher column index than previous */ + if (j <= prev_pivot) + return 0; + + /* column should be 0 ... 0 1 0 ... 0 */ + for (k = 0; k < rank; k++) + if (nmod_mat_entry(A, k, j) != (i == k)) + return 0; + + prev_pivot = j; + break; + } + } + } + + return 1; +} + +int +main(void) +{ + slong i; + + FLINT_TEST_INIT(state); + + flint_printf("rref...."); + fflush(stdout); + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_mat_t A, B, C, D; + mp_limb_t mod; + slong j, k, m, n, rank1, rank2; + slong *perm; + int equal; + mp_limb_t c; + + mod = n_randtest_prime(state, 0); + + m = n_randint(state, 20); + n = n_randint(state, 20); + perm = _perm_init(2*m); + + nmod_mat_init(A, m, n, mod); + nmod_mat_init(D, 2*m, n, mod); + + nmod_mat_randtest(A, state); + nmod_mat_init_set(B, A); + nmod_mat_init_set(C, A); + + rank1 = nmod_mat_rref(B); + + if (!check_rref_form(perm, B, rank1)) + { + flint_printf("FAIL (malformed rref)\n"); + nmod_mat_print_pretty(A); flint_printf("\n\n"); + nmod_mat_print_pretty(B); flint_printf("\n\n"); + abort(); + } + + /* Concatenate the original matrix with the rref, scramble the rows, + and check that the rref is the same */ + _perm_randtest(perm, 2 * m, state); + + for (j = 0; j < m; j++) + { + do { c = n_randint(state, mod); } while (c == 0); + for (k = 0; k < n; k++) + nmod_mat_entry(D, perm[j], k) = + nmod_mul(nmod_mat_entry(A, j, k), c, A->mod); + } + + for (j = 0; j < m; j++) + { + do { c = n_randint(state, mod); } while (c == 0); + for (k = 0; k < n; k++) + nmod_mat_entry(D, perm[m + j], k) = + nmod_mul(nmod_mat_entry(B, j, k), c, A->mod); + } + + rank2 = nmod_mat_rref(D); + equal = (rank1 == rank2); + + if (equal) + { + for (j = 0; j < rank2; j++) + for (k = 0; k < n; k++) + equal = equal && (nmod_mat_entry(B, j, k) == + nmod_mat_entry(D, j, k)); + for (j = rank2; j < 2 * rank2; j++) + for (k = 0; k < n; k++) + equal = equal && (nmod_mat_entry(D, j, k) == 0); + } + + if (!equal) + { + flint_printf("FAIL (rank1 = %wd, rank2 = %wd)!\n", rank1, rank2); + nmod_mat_print_pretty(A); flint_printf("\n\n"); + nmod_mat_print_pretty(B); flint_printf("\n\n"); + nmod_mat_print_pretty(D); flint_printf("\n\n"); + abort(); + } + + _perm_clear(perm); + nmod_mat_clear(A); + nmod_mat_clear(B); + nmod_mat_clear(C); + nmod_mat_clear(D); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_mat/test/t-scalar_mul.c b/external/flint-2.4.3/nmod_mat/test/t-scalar_mul.c new file mode 100644 index 0000000..155b5dc --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/test/t-scalar_mul.c @@ -0,0 +1,96 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "nmod_mat.h" +#include "nmod_vec.h" +#include "ulong_extras.h" + +int +main(void) +{ + slong m, n, mod, rep; + FLINT_TEST_INIT(state); + + + flint_printf("scalar_mul...."); + fflush(stdout); + + for (rep = 0; rep < 1000 * flint_test_multiplier(); rep++) + { + nmod_mat_t A, B, C, D; + mp_limb_t c; + + m = n_randint(state, 20); + n = n_randint(state, 20); + mod = n_randtest_not_zero(state); + + c = n_randint(state, mod); + + nmod_mat_init(A, m, n, mod); + nmod_mat_init(B, m, n, mod); + nmod_mat_init(C, m, n, mod); + nmod_mat_init(D, m, n, mod); + + nmod_mat_randtest(A, state); + nmod_mat_randtest(B, state); + + nmod_mat_scalar_mul(C, A, c); + nmod_mat_scalar_mul(D, A, nmod_sub(c, UWORD(1), A->mod)); + + /* c*A - (c-1)*A == A */ + nmod_mat_sub(D, C, D); + + if (!nmod_mat_equal(A, D)) + { + flint_printf("FAIL\n"); + abort(); + } + + /* Aliasing */ + nmod_mat_scalar_mul(C, A, c); + nmod_mat_scalar_mul(A, A, c); + + if (!nmod_mat_equal(A, C)) + { + flint_printf("FAIL\n"); + abort(); + } + + nmod_mat_clear(A); + nmod_mat_clear(B); + nmod_mat_clear(C); + nmod_mat_clear(D); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_mat/test/t-solve.c b/external/flint-2.4.3/nmod_mat/test/t-solve.c new file mode 100644 index 0000000..15f307d --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/test/t-solve.c @@ -0,0 +1,134 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_mat.h" +#include "ulong_extras.h" + + +int +main(void) +{ + nmod_mat_t A, X, B, AX; + slong i, m, n, r; + mp_limb_t mod; + int solved; + FLINT_TEST_INIT(state); + + + flint_printf("solve...."); + fflush(stdout); + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + m = n_randint(state, 20); + n = n_randint(state, 20); + mod = n_randtest_prime(state, 0); + + nmod_mat_init(A, m, m, mod); + nmod_mat_init(B, m, n, mod); + nmod_mat_init(X, m, n, mod); + nmod_mat_init(AX, m, n, mod); + + nmod_mat_randrank(A, state, m); + nmod_mat_randtest(B, state); + + /* Dense */ + if (n_randint(state, 2)) + nmod_mat_randops(A, 1+n_randint(state, 1+m*m), state); + + solved = nmod_mat_solve(X, A, B); + + nmod_mat_mul(AX, A, X); + + if (!nmod_mat_equal(AX, B) || !solved) + { + flint_printf("FAIL:\n"); + flint_printf("AX != B!\n"); + flint_printf("A:\n"); + nmod_mat_print_pretty(A); + flint_printf("B:\n"); + nmod_mat_print_pretty(B); + flint_printf("X:\n"); + nmod_mat_print_pretty(X); + flint_printf("AX:\n"); + nmod_mat_print_pretty(AX); + flint_printf("\n"); + abort(); + } + + nmod_mat_clear(A); + nmod_mat_clear(B); + nmod_mat_clear(X); + nmod_mat_clear(AX); + } + + /* Test singular systems */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + m = 1 + n_randint(state, 20); + n = 1 + n_randint(state, 20); + r = n_randint(state, m); + mod = n_randtest_prime(state, 0); + + nmod_mat_init(A, m, m, mod); + nmod_mat_init(B, m, n, mod); + nmod_mat_init(X, m, n, mod); + nmod_mat_init(AX, m, n, mod); + + nmod_mat_randrank(A, state, r); + nmod_mat_randtest(B, state); + + /* Dense */ + if (n_randint(state, 2)) + nmod_mat_randops(A, 1+n_randint(state, 1+m*m), state); + + solved = nmod_mat_solve(X, A, B); + + if (solved) + { + flint_printf("FAIL:\n"); + flint_printf("singular system was 'solved'\n"); + nmod_mat_print_pretty(A); + nmod_mat_print_pretty(X); + nmod_mat_print_pretty(B); + abort(); + } + + nmod_mat_clear(A); + nmod_mat_clear(B); + nmod_mat_clear(X); + nmod_mat_clear(AX); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_mat/test/t-solve_tril.c b/external/flint-2.4.3/nmod_mat/test/t-solve_tril.c new file mode 100644 index 0000000..1dae667 --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/test/t-solve_tril.c @@ -0,0 +1,104 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010,2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "nmod_mat.h" +#include "ulong_extras.h" + +int +main(void) +{ + slong i; + FLINT_TEST_INIT(state); + + + flint_printf("solve_tril...."); + fflush(stdout); + + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + nmod_mat_t A, X, B, Y; + mp_limb_t m; + slong rows, cols; + int unit; + + m = n_randtest_prime(state, 0); + rows = n_randint(state, 200); + cols = n_randint(state, 200); + unit = n_randint(state, 2); + + nmod_mat_init(A, rows, rows, m); + nmod_mat_init(B, rows, cols, m); + nmod_mat_init(X, rows, cols, m); + nmod_mat_init(Y, rows, cols, m); + + nmod_mat_randtril(A, state, unit); + nmod_mat_randtest(X, state); + nmod_mat_mul(B, A, X); + + /* Check Y = A^(-1) * (A * X) = X */ + nmod_mat_solve_tril(Y, A, B, unit); + if (!nmod_mat_equal(Y, X)) + { + flint_printf("FAIL!\n"); + flint_printf("A:\n"); + nmod_mat_print_pretty(A); + flint_printf("X:\n"); + nmod_mat_print_pretty(X); + flint_printf("B:\n"); + nmod_mat_print_pretty(B); + flint_printf("Y:\n"); + nmod_mat_print_pretty(Y); + abort(); + } + + /* Check aliasing */ + nmod_mat_solve_tril(B, A, B, unit); + if (!nmod_mat_equal(B, X)) + { + flint_printf("FAIL!\n"); + flint_printf("aliasing test failed"); + flint_printf("A:\n"); + nmod_mat_print_pretty(A); + flint_printf("B:\n"); + nmod_mat_print_pretty(B); + abort(); + } + + nmod_mat_clear(A); + nmod_mat_clear(B); + nmod_mat_clear(X); + nmod_mat_clear(Y); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_mat/test/t-solve_tril_classical.c b/external/flint-2.4.3/nmod_mat/test/t-solve_tril_classical.c new file mode 100644 index 0000000..fce5d71 --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/test/t-solve_tril_classical.c @@ -0,0 +1,104 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010,2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "nmod_mat.h" +#include "ulong_extras.h" + +int +main(void) +{ + slong i; + FLINT_TEST_INIT(state); + + + flint_printf("solve_tril_classical...."); + fflush(stdout); + + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_mat_t A, X, B, Y; + mp_limb_t m; + slong rows, cols; + int unit; + + m = n_randtest_prime(state, 0); + rows = n_randint(state, 100); + cols = n_randint(state, 100); + unit = n_randint(state, 2); + + nmod_mat_init(A, rows, rows, m); + nmod_mat_init(B, rows, cols, m); + nmod_mat_init(X, rows, cols, m); + nmod_mat_init(Y, rows, cols, m); + + nmod_mat_randtril(A, state, unit); + nmod_mat_randtest(X, state); + nmod_mat_mul(B, A, X); + + /* Check Y = A^(-1) * (A * X) = X */ + nmod_mat_solve_tril_classical(Y, A, B, unit); + if (!nmod_mat_equal(Y, X)) + { + flint_printf("FAIL!\n"); + flint_printf("A:\n"); + nmod_mat_print_pretty(A); + flint_printf("X:\n"); + nmod_mat_print_pretty(X); + flint_printf("B:\n"); + nmod_mat_print_pretty(B); + flint_printf("Y:\n"); + nmod_mat_print_pretty(Y); + abort(); + } + + /* Check aliasing */ + nmod_mat_solve_tril_classical(B, A, B, unit); + if (!nmod_mat_equal(B, X)) + { + flint_printf("FAIL!\n"); + flint_printf("aliasing test failed"); + flint_printf("A:\n"); + nmod_mat_print_pretty(A); + flint_printf("B:\n"); + nmod_mat_print_pretty(B); + abort(); + } + + nmod_mat_clear(A); + nmod_mat_clear(B); + nmod_mat_clear(X); + nmod_mat_clear(Y); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_mat/test/t-solve_tril_recursive.c b/external/flint-2.4.3/nmod_mat/test/t-solve_tril_recursive.c new file mode 100644 index 0000000..3a2f1aa --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/test/t-solve_tril_recursive.c @@ -0,0 +1,104 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010,2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "nmod_mat.h" +#include "ulong_extras.h" + +int +main(void) +{ + slong i; + FLINT_TEST_INIT(state); + + + flint_printf("solve_tril_recursive...."); + fflush(stdout); + + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_mat_t A, X, B, Y; + mp_limb_t m; + slong rows, cols; + int unit; + + m = n_randtest_prime(state, 0); + rows = n_randint(state, 100); + cols = n_randint(state, 100); + unit = n_randint(state, 2); + + nmod_mat_init(A, rows, rows, m); + nmod_mat_init(B, rows, cols, m); + nmod_mat_init(X, rows, cols, m); + nmod_mat_init(Y, rows, cols, m); + + nmod_mat_randtril(A, state, unit); + nmod_mat_randtest(X, state); + nmod_mat_mul(B, A, X); + + /* Check Y = A^(-1) * (A * X) = X */ + nmod_mat_solve_tril_recursive(Y, A, B, unit); + if (!nmod_mat_equal(Y, X)) + { + flint_printf("FAIL!\n"); + flint_printf("A:\n"); + nmod_mat_print_pretty(A); + flint_printf("X:\n"); + nmod_mat_print_pretty(X); + flint_printf("B:\n"); + nmod_mat_print_pretty(B); + flint_printf("Y:\n"); + nmod_mat_print_pretty(Y); + abort(); + } + + /* Check aliasing */ + nmod_mat_solve_tril_recursive(B, A, B, unit); + if (!nmod_mat_equal(B, X)) + { + flint_printf("FAIL!\n"); + flint_printf("aliasing test failed"); + flint_printf("A:\n"); + nmod_mat_print_pretty(A); + flint_printf("B:\n"); + nmod_mat_print_pretty(B); + abort(); + } + + nmod_mat_clear(A); + nmod_mat_clear(B); + nmod_mat_clear(X); + nmod_mat_clear(Y); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_mat/test/t-solve_triu.c b/external/flint-2.4.3/nmod_mat/test/t-solve_triu.c new file mode 100644 index 0000000..ff68dce --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/test/t-solve_triu.c @@ -0,0 +1,104 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010,2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "nmod_mat.h" +#include "ulong_extras.h" + +int +main(void) +{ + slong i; + FLINT_TEST_INIT(state); + + + flint_printf("solve_triu...."); + fflush(stdout); + + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + nmod_mat_t A, X, B, Y; + mp_limb_t m; + slong rows, cols; + int unit; + + m = n_randtest_prime(state, 0); + rows = n_randint(state, 200); + cols = n_randint(state, 200); + unit = n_randint(state, 2); + + nmod_mat_init(A, rows, rows, m); + nmod_mat_init(B, rows, cols, m); + nmod_mat_init(X, rows, cols, m); + nmod_mat_init(Y, rows, cols, m); + + nmod_mat_randtriu(A, state, unit); + nmod_mat_randtest(X, state); + nmod_mat_mul(B, A, X); + + /* Check Y = A^(-1) * (A * X) = X */ + nmod_mat_solve_triu(Y, A, B, unit); + if (!nmod_mat_equal(Y, X)) + { + flint_printf("FAIL!\n"); + flint_printf("A:\n"); + nmod_mat_print_pretty(A); + flint_printf("X:\n"); + nmod_mat_print_pretty(X); + flint_printf("B:\n"); + nmod_mat_print_pretty(B); + flint_printf("Y:\n"); + nmod_mat_print_pretty(Y); + abort(); + } + + /* Check aliasing */ + nmod_mat_solve_triu(B, A, B, unit); + if (!nmod_mat_equal(B, X)) + { + flint_printf("FAIL!\n"); + flint_printf("aliasing test failed"); + flint_printf("A:\n"); + nmod_mat_print_pretty(A); + flint_printf("B:\n"); + nmod_mat_print_pretty(B); + abort(); + } + + nmod_mat_clear(A); + nmod_mat_clear(B); + nmod_mat_clear(X); + nmod_mat_clear(Y); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_mat/test/t-solve_triu_classical.c b/external/flint-2.4.3/nmod_mat/test/t-solve_triu_classical.c new file mode 100644 index 0000000..39818f4 --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/test/t-solve_triu_classical.c @@ -0,0 +1,104 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010,2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "nmod_mat.h" +#include "ulong_extras.h" + +int +main(void) +{ + slong i; + FLINT_TEST_INIT(state); + + + flint_printf("solve_triu_classical...."); + fflush(stdout); + + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_mat_t A, X, B, Y; + mp_limb_t m; + slong rows, cols; + int unit; + + m = n_randtest_prime(state, 0); + rows = n_randint(state, 100); + cols = n_randint(state, 100); + unit = n_randint(state, 2); + + nmod_mat_init(A, rows, rows, m); + nmod_mat_init(B, rows, cols, m); + nmod_mat_init(X, rows, cols, m); + nmod_mat_init(Y, rows, cols, m); + + nmod_mat_randtriu(A, state, unit); + nmod_mat_randtest(X, state); + nmod_mat_mul(B, A, X); + + /* Check Y = A^(-1) * (A * X) = X */ + nmod_mat_solve_triu_classical(Y, A, B, unit); + if (!nmod_mat_equal(Y, X)) + { + flint_printf("FAIL!\n"); + flint_printf("A:\n"); + nmod_mat_print_pretty(A); + flint_printf("X:\n"); + nmod_mat_print_pretty(X); + flint_printf("B:\n"); + nmod_mat_print_pretty(B); + flint_printf("Y:\n"); + nmod_mat_print_pretty(Y); + abort(); + } + + /* Check aliasing */ + nmod_mat_solve_triu_classical(B, A, B, unit); + if (!nmod_mat_equal(B, X)) + { + flint_printf("FAIL!\n"); + flint_printf("aliasing test failed"); + flint_printf("A:\n"); + nmod_mat_print_pretty(A); + flint_printf("B:\n"); + nmod_mat_print_pretty(B); + abort(); + } + + nmod_mat_clear(A); + nmod_mat_clear(B); + nmod_mat_clear(X); + nmod_mat_clear(Y); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_mat/test/t-solve_triu_recursive.c b/external/flint-2.4.3/nmod_mat/test/t-solve_triu_recursive.c new file mode 100644 index 0000000..2b9b4af --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/test/t-solve_triu_recursive.c @@ -0,0 +1,104 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010,2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "nmod_mat.h" +#include "ulong_extras.h" + +int +main(void) +{ + slong i; + FLINT_TEST_INIT(state); + + + flint_printf("solve_triu_recursive...."); + fflush(stdout); + + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_mat_t A, X, B, Y; + mp_limb_t m; + slong rows, cols; + int unit; + + m = n_randtest_prime(state, 0); + rows = n_randint(state, 100); + cols = n_randint(state, 100); + unit = n_randint(state, 2); + + nmod_mat_init(A, rows, rows, m); + nmod_mat_init(B, rows, cols, m); + nmod_mat_init(X, rows, cols, m); + nmod_mat_init(Y, rows, cols, m); + + nmod_mat_randtriu(A, state, unit); + nmod_mat_randtest(X, state); + nmod_mat_mul(B, A, X); + + /* Check Y = A^(-1) * (A * X) = X */ + nmod_mat_solve_triu_recursive(Y, A, B, unit); + if (!nmod_mat_equal(Y, X)) + { + flint_printf("FAIL!\n"); + flint_printf("A:\n"); + nmod_mat_print_pretty(A); + flint_printf("X:\n"); + nmod_mat_print_pretty(X); + flint_printf("B:\n"); + nmod_mat_print_pretty(B); + flint_printf("Y:\n"); + nmod_mat_print_pretty(Y); + abort(); + } + + /* Check aliasing */ + nmod_mat_solve_triu_recursive(B, A, B, unit); + if (!nmod_mat_equal(B, X)) + { + flint_printf("FAIL!\n"); + flint_printf("aliasing test failed"); + flint_printf("A:\n"); + nmod_mat_print_pretty(A); + flint_printf("B:\n"); + nmod_mat_print_pretty(B); + abort(); + } + + nmod_mat_clear(A); + nmod_mat_clear(B); + nmod_mat_clear(X); + nmod_mat_clear(Y); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_mat/test/t-solve_vec.c b/external/flint-2.4.3/nmod_mat/test/t-solve_vec.c new file mode 100644 index 0000000..0050ebc --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/test/t-solve_vec.c @@ -0,0 +1,128 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_mat.h" +#include "ulong_extras.h" + + +int +main(void) +{ + nmod_mat_t A, x, b, Ax; + slong i, m, r; + int solved; + mp_limb_t mod; + FLINT_TEST_INIT(state); + + + flint_printf("solve_vec...."); + fflush(stdout); + + for (i = 0; i < 2000 * flint_test_multiplier(); i++) + { + m = n_randint(state, 20); + mod = n_randtest_prime(state, 0); + + nmod_mat_init(A, m, m, mod); + nmod_mat_init(b, m, 1, mod); + nmod_mat_init(x, m, 1, mod); + nmod_mat_init(Ax, m, 1, mod); + + nmod_mat_randrank(A, state, m); + nmod_mat_randtest(b, state); + + /* Dense */ + if (n_randint(state, 2)) + nmod_mat_randops(A, 1+n_randint(state, 1+m*m), state); + + solved = nmod_mat_solve_vec(x->entries, A, b->entries); + nmod_mat_mul(Ax, A, x); + + if (!nmod_mat_equal(Ax, b) || !solved) + { + flint_printf("FAIL:\n"); + flint_printf("Ax != b!\n"); + flint_printf("A:\n"); + nmod_mat_print_pretty(A); + flint_printf("b:\n"); + nmod_mat_print_pretty(b); + flint_printf("x:\n"); + nmod_mat_print_pretty(x); + flint_printf("Ax:\n"); + nmod_mat_print_pretty(Ax); + flint_printf("\n"); + abort(); + } + + nmod_mat_clear(A); + nmod_mat_clear(b); + nmod_mat_clear(x); + nmod_mat_clear(Ax); + } + + /* Test singular systems */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + m = 1 + n_randint(state, 20); + r = n_randint(state, m); + mod = n_randtest_prime(state, 0); + + nmod_mat_init(A, m, m, mod); + nmod_mat_init(b, m, 1, mod); + nmod_mat_init(x, m, 1, mod); + nmod_mat_init(Ax, m, 1, mod); + + nmod_mat_randrank(A, state, r); + nmod_mat_randtest(b, state); + + /* Dense */ + if (n_randint(state, 2)) + nmod_mat_randops(A, 1+n_randint(state, 1+m*m), state); + + solved = nmod_mat_solve_vec(x->entries, A, b->entries); + + if (solved) + { + flint_printf("FAIL:\n"); + flint_printf("singular system was 'solved'\n"); + abort(); + } + + nmod_mat_clear(A); + nmod_mat_clear(b); + nmod_mat_clear(x); + nmod_mat_clear(Ax); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_mat/test/t-submul.c b/external/flint-2.4.3/nmod_mat/test/t-submul.c new file mode 100644 index 0000000..8a9d2f8 --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/test/t-submul.c @@ -0,0 +1,116 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "nmod_mat.h" +#include "ulong_extras.h" + +int +main(void) +{ + slong i; + FLINT_TEST_INIT(state); + + + flint_printf("submul...."); + fflush(stdout); + + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + nmod_mat_t A, B, C, D, T, E; + mp_limb_t mod = n_randtest_not_zero(state); + + slong m, k, n; + + m = n_randint(state, 100); + k = n_randint(state, 100); + n = n_randint(state, 100); + + /* Force Strassen test */ + if (i < 5) + { + m += 300; + k += 300; + n += 300; + } + + nmod_mat_init(A, m, k, mod); + nmod_mat_init(B, k, n, mod); + nmod_mat_init(C, m, n, mod); + nmod_mat_init(D, m, n, mod); + nmod_mat_init(T, m, n, mod); + nmod_mat_init(E, m, n, mod); + + nmod_mat_randtest(A, state); + nmod_mat_randtest(B, state); + nmod_mat_randtest(C, state); + + nmod_mat_submul(D, C, A, B); + + nmod_mat_mul(T, A, B); + nmod_mat_sub(E, C, T); + + if (!nmod_mat_equal(D, E)) + { + flint_printf("FAIL: results not equal\n"); + nmod_mat_print_pretty(A); + nmod_mat_print_pretty(B); + nmod_mat_print_pretty(C); + nmod_mat_print_pretty(D); + nmod_mat_print_pretty(E); + abort(); + } + + /* Check aliasing */ + nmod_mat_submul(C, C, A, B); + + if (!nmod_mat_equal(C, E)) + { + flint_printf("FAIL: results not equal (aliasing)\n"); + nmod_mat_print_pretty(A); + nmod_mat_print_pretty(B); + nmod_mat_print_pretty(C); + nmod_mat_print_pretty(D); + nmod_mat_print_pretty(E); + abort(); + } + + nmod_mat_clear(A); + nmod_mat_clear(B); + nmod_mat_clear(C); + nmod_mat_clear(D); + nmod_mat_clear(E); + nmod_mat_clear(T); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_mat/test/t-trace.c b/external/flint-2.4.3/nmod_mat/test/t-trace.c new file mode 100644 index 0000000..cf9eddf --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/test/t-trace.c @@ -0,0 +1,91 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_mat.h" +#include "ulong_extras.h" + +int +main(void) +{ + slong i; + FLINT_TEST_INIT(state); + + flint_printf("trace...."); + fflush(stdout); + + + + /* Test trace(AB) = trace(BA) */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_mat_t A, B, AB, BA; + mp_limb_t mod, trab, trba; + slong m, n; + + mod = n_randtest_prime(state, 0); + m = n_randint(state, 10); + n = n_randint(state, 10); + + nmod_mat_init(A, m, n, mod); + nmod_mat_init(B, n, m, mod); + nmod_mat_init(AB, m, m, mod); + nmod_mat_init(BA, n, n, mod); + + nmod_mat_randtest(A, state); + nmod_mat_randtest(B, state); + + nmod_mat_mul(AB, A, B); + nmod_mat_mul(BA, B, A); + + trab = nmod_mat_trace(AB); + trba = nmod_mat_trace(BA); + + if (trab != trba) + { + flint_printf("FAIL:\n"); + nmod_mat_print_pretty(A), flint_printf("\n"); + nmod_mat_print_pretty(B), flint_printf("\n"); + nmod_mat_print_pretty(AB), flint_printf("\n"); + nmod_mat_print_pretty(BA), flint_printf("\n"); + flint_printf("tr(AB): %wu\n", trab); + flint_printf("tr(BA): %wu\n", trba); + abort(); + } + + nmod_mat_clear(A); + nmod_mat_clear(B); + nmod_mat_clear(AB); + nmod_mat_clear(BA); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_mat/test/t-transpose.c b/external/flint-2.4.3/nmod_mat/test/t-transpose.c new file mode 100644 index 0000000..93f9a95 --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/test/t-transpose.c @@ -0,0 +1,144 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "nmod_mat.h" +#include "ulong_extras.h" + +int +main(void) +{ + slong m, n, mod, mod2, rep; + FLINT_TEST_INIT(state); + + + flint_printf("transpose...."); + fflush(stdout); + + /* Rectangular transpose, same modulus */ + for (rep = 0; rep < 100 * flint_test_multiplier(); rep++) + { + nmod_mat_t A, B, C; + + m = n_randint(state, 20); + n = n_randint(state, 20); + + mod = n_randtest_not_zero(state); + + nmod_mat_init(A, m, n, mod); + nmod_mat_init(B, n, m, mod); + nmod_mat_init(C, m, n, mod); + + nmod_mat_randtest(A, state); + nmod_mat_randtest(B, state); + + nmod_mat_transpose(B, A); + nmod_mat_transpose(C, B); + + if (!nmod_mat_equal(C, A)) + { + flint_printf("FAIL: C != A\n"); + abort(); + } + + nmod_mat_clear(A); + nmod_mat_clear(B); + nmod_mat_clear(C); + } + + /* Rectangular transpose, different modulus */ + for (rep = 0; rep < 100 * flint_test_multiplier(); rep++) + { + nmod_mat_t A, AT, B, BT, AT2; + + m = n_randint(state, 20); + n = n_randint(state, 20); + + mod = n_randtest_not_zero(state); + mod2 = n_randtest_not_zero(state); + + nmod_mat_init(A, m, n, mod); + nmod_mat_init(AT, n, m, mod); + nmod_mat_init(B, m, n, mod2); + nmod_mat_init(BT, n, m, mod2); + nmod_mat_init(AT2, n, m, mod2); + + nmod_mat_randtest(A, state); + nmod_mat_set(B, A); + + nmod_mat_transpose(AT, A); + nmod_mat_transpose(BT, B); + + nmod_mat_set(AT2, AT); + + if (!nmod_mat_equal(BT, AT2)) + { + flint_printf("FAIL: AT != BT\n"); + abort(); + } + + nmod_mat_clear(A); + nmod_mat_clear(AT); + nmod_mat_clear(AT2); + nmod_mat_clear(B); + nmod_mat_clear(BT); + } + + /* Self-transpose */ + for (rep = 0; rep < 100 * flint_test_multiplier(); rep++) + { + nmod_mat_t A, B; + + m = n_randint(state, 20); + mod = n_randtest_not_zero(state); + + nmod_mat_init(A, m, m, mod); + nmod_mat_init(B, m, m, mod); + + nmod_mat_randtest(A, state); + nmod_mat_set(B, A); + + nmod_mat_transpose(B, B); + nmod_mat_transpose(B, B); + + if (!nmod_mat_equal(B, A)) + { + flint_printf("FAIL: B != A\n"); + abort(); + } + + nmod_mat_clear(A); + nmod_mat_clear(B); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_mat/trace.c b/external/flint-2.4.3/nmod_mat/trace.c new file mode 100644 index 0000000..c5e9ef6 --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/trace.c @@ -0,0 +1,47 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_mat.h" +#include "nmod_vec.h" + +mp_limb_t +nmod_mat_trace(const nmod_mat_t mat) +{ + mp_limb_t t; + slong i, n = nmod_mat_nrows(mat); + + if (n == 0) + return 0; + + t = nmod_mat_entry(mat, 0, 0); + + for (i = 1; i < n; i++) + t = nmod_add(t, nmod_mat_entry(mat, i, i), mat->mod); + + return t; +} diff --git a/external/flint-2.4.3/nmod_mat/transpose.c b/external/flint-2.4.3/nmod_mat/transpose.c new file mode 100644 index 0000000..b163c35 --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/transpose.c @@ -0,0 +1,62 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_mat.h" +#include "nmod_vec.h" + +void +nmod_mat_transpose(nmod_mat_t B, const nmod_mat_t A) +{ + mp_limb_t tmp; + + slong i, j; + + if (B->r != A->c || B->c != A->r) + { + flint_printf("Exception (nmod_mat_transpose). Incompatible dimensions.\n"); + abort(); + } + + if (A == B) /* In-place, guaranteed to be square */ + { + for (i = 0; i < A->r - 1; i++) + for (j = i + 1; j < A->c; j++) + { + tmp = A->rows[i][j]; + A->rows[i][j] = A->rows[j][i]; + A->rows[j][i] = tmp; + } + } + else /* Not aliased; general case */ + { + for (i = 0; i < B->r; i++) + for (j = 0; j < B->c; j++) + B->rows[i][j] = A->rows[j][i]; + } +} diff --git a/external/flint-2.4.3/nmod_mat/window_clear.c b/external/flint-2.4.3/nmod_mat/window_clear.c new file mode 100644 index 0000000..2435643 --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/window_clear.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2008, Richard Howell-Peak + Copyright (C) 2008, Martin Albrecht + Copyright (C) 2010, Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_mat.h" + +void +nmod_mat_window_clear(nmod_mat_t window) +{ + flint_free(window->rows); +} diff --git a/external/flint-2.4.3/nmod_mat/window_init.c b/external/flint-2.4.3/nmod_mat/window_init.c new file mode 100644 index 0000000..73c7c99 --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/window_init.c @@ -0,0 +1,49 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2008, Richard Howell-Peak + Copyright (C) 2008, Martin Albrecht + Copyright (C) 2010, Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_mat.h" + +void +nmod_mat_window_init(nmod_mat_t window, const nmod_mat_t mat, + slong r1, slong c1, slong r2, slong c2) +{ + slong i; + window->entries = NULL; + + window->rows = flint_malloc((r2 - r1) * sizeof(mp_limb_t *)); + + for (i = 0; i < r2 - r1; i++) + window->rows[i] = mat->rows[r1 + i] + c1; + + window->r = r2 - r1; + window->c = c2 - c1; + window->mod = mat->mod; +} diff --git a/external/flint-2.4.3/nmod_mat/zero.c b/external/flint-2.4.3/nmod_mat/zero.c new file mode 100644 index 0000000..093549b --- /dev/null +++ b/external/flint-2.4.3/nmod_mat/zero.c @@ -0,0 +1,45 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_mat.h" +#include "nmod_vec.h" + +void +nmod_mat_zero(nmod_mat_t mat) +{ + slong i, m, n; + + m = mat->r; + n = mat->c; + + if (n == 0) + return; + + for (i = 0; i < m; i++) + _nmod_vec_zero(mat->rows[i], n); +} diff --git a/external/flint-2.4.3/nmod_matxx.h b/external/flint-2.4.3/nmod_matxx.h new file mode 100644 index 0000000..825af51 --- /dev/null +++ b/external/flint-2.4.3/nmod_matxx.h @@ -0,0 +1,555 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#ifndef NMOD_MATXX_H +#define NMOD_MATXX_H + +#include +#include + +#include "nmod_mat.h" + +#include "nmod_vecxx.h" +#include "fmpz_matxx.h" // for modular reduction +#include "permxx.h" + +#include "flintxx/flint_exception.h" +#include "flintxx/ltuple.h" +#include "flintxx/matrix.h" + +// TODO addmul +// TODO default argument for mat_solve_triu etc? +// TODO nullspace member +// TODO unnecessary perm copies in set_lu* + +namespace flint { +FLINT_DEFINE_BINOP(solve_vec) +FLINT_DEFINE_BINOP(mul_strassen) +FLINT_DEFINE_THREEARY(solve_tril) +FLINT_DEFINE_THREEARY(solve_tril_classical) +FLINT_DEFINE_THREEARY(solve_tril_recursive) +FLINT_DEFINE_THREEARY(solve_triu) +FLINT_DEFINE_THREEARY(solve_triu_classical) +FLINT_DEFINE_THREEARY(solve_triu_recursive) + +FLINT_DEFINE_THREEARY(multi_CRT_precomp) + +namespace detail { +template +struct nmod_matxx_traits : matrices::generic_traits { }; +} // detail + +template +class nmod_matxx_expression + : public expression, Operation, Data> +{ +public: + typedef expression, + Operation, Data> base_t; + typedef detail::nmod_matxx_traits traits_t; + + FLINTXX_DEFINE_BASICS(nmod_matxx_expression) + FLINTXX_DEFINE_CTORS(nmod_matxx_expression) + FLINTXX_DEFINE_C_REF(nmod_matxx_expression, nmod_mat_struct, _mat) + + // These only make sense with immediates + nmodxx_ctx_srcref _ctx() const + {return nmodxx_ctx_srcref::make(_mat()->mod);} + + // These work on any expression without evaluation + nmodxx_ctx_srcref estimate_ctx() const + { + return tools::find_nmodxx_ctx(*this); + } + mp_limb_t modulus() const {return estimate_ctx().n();} + + template + static evaluated_t create_temporary_rowscols( + const Expr& e, slong rows, slong cols) + { + return evaluated_t(rows, cols, tools::find_nmodxx_ctx(e).n()); + } + FLINTXX_DEFINE_MATRIX_METHODS(traits_t) + + template + static nmod_matxx_expression reduce(const Fmpz_mat& mat, + mp_limb_t modulus, + typename mp::enable_if >::type* = 0) + { + nmod_matxx_expression res(mat.rows(), mat.cols(), modulus); + fmpz_mat_get_nmod_mat(res._mat(), mat.evaluate()._mat()); + return res; + } + + static nmod_matxx_expression randtest(slong rows, slong cols, mp_limb_t n, + frandxx& state) + { + nmod_matxx_expression res(rows, cols, n); + res.set_randtest(state); + return res; + } + static nmod_matxx_expression randfull(slong rows, slong cols, mp_limb_t n, + frandxx& state) + { + nmod_matxx_expression res(rows, cols, n); + res.set_randfull(state); + return res; + } + static nmod_matxx_expression randrank(slong rows, slong cols, mp_limb_t n, + frandxx& state, slong rank) + { + nmod_matxx_expression res(rows, cols, n); + res.set_randrank(state, rank); + return res; + } + static nmod_matxx_expression randtril(slong rows, slong cols, mp_limb_t n, + frandxx& state, bool unit) + { + nmod_matxx_expression res(rows, cols, n); + res.set_randtril(state, unit); + return res; + } + static nmod_matxx_expression randtriu(slong rows, slong cols, mp_limb_t n, + frandxx& state, + bool unit) + { + nmod_matxx_expression res(rows, cols, n); + res.set_randtriu(state, unit); + return res; + } + + template + static nmod_matxx_expression randpermdiag(slong rows, slong cols, mp_limb_t n, + frandxx& state, const Vec& v) + { + nmod_matxx_expression res(rows, cols, n); + res.set_randpermdiag(state, v); + return res; + } + + static nmod_matxx_expression zero(slong rows, slong cols, mp_limb_t n) + {return nmod_matxx_expression(rows, cols, n);} + + // these only make sense with targets + void set_randtest(frandxx& state) + {nmod_mat_randtest(_mat(), state._data());} + void set_randfull(frandxx& state) + {nmod_mat_randfull(_mat(), state._data());} + void set_randrank(frandxx& state, slong rank) + {nmod_mat_randrank(_mat(), state._data(), rank);} + void set_randtril(frandxx& state, bool unit) + {nmod_mat_randtril(_mat(), state._data(), unit);} + void set_randtriu(frandxx& state, bool unit) + {nmod_mat_randtriu(_mat(), state._data(), unit);} + + template + int set_randpermdiag(frandxx& state, const Vec& v) + { + return nmod_mat_randpermdiag(_mat(), state._data(), v._array(), v.size()); + } + + void apply_randops(frandxx& state, slong count) + {nmod_mat_randops(_mat(), count, state._data());} + + slong set_rref() {return nmod_mat_rref(_mat());} + void set_zero() {nmod_mat_zero(_mat());} + + typedef mp::make_tuple::type lu_rt; + lu_rt set_lu(bool rank_check = false) + { + lu_rt res = mp::make_tuple::make(0, permxx(rows())); + res.first() = nmod_mat_lu(res.second()._data(), _mat(), rank_check); + return res; + } + lu_rt set_lu_classical(bool rank_check = false) + { + lu_rt res = mp::make_tuple::make(0, permxx(rows())); + res.first() = nmod_mat_lu_classical( + res.second()._data(), _mat(), rank_check); + return res; + } + lu_rt set_lu_recursive(bool rank_check = false) + { + lu_rt res = mp::make_tuple::make(0, permxx(rows())); + res.first() = nmod_mat_lu_recursive( + res.second()._data(), _mat(), rank_check); + return res; + } + + + // these cause evaluation + slong rank() const {return nmod_mat_rank(this->evaluate()._mat());} + bool is_zero() const {return nmod_mat_is_zero(this->evaluate()._mat());} + bool is_empty() const {return nmod_mat_is_empty(this->evaluate()._mat());} + bool is_square() const {return nmod_mat_is_square(this->evaluate()._mat());} + + // lazy members + FLINTXX_DEFINE_MEMBER_BINOP(solve) + FLINTXX_DEFINE_MEMBER_BINOP(mul_classical) + FLINTXX_DEFINE_MEMBER_BINOP(mul_strassen) + FLINTXX_DEFINE_MEMBER_UNOP(inv) + FLINTXX_DEFINE_MEMBER_UNOP(transpose) + FLINTXX_DEFINE_MEMBER_UNOP_RTYPE(nmodxx, trace) + FLINTXX_DEFINE_MEMBER_UNOP_RTYPE(nmodxx, det) + //FLINTXX_DEFINE_MEMBER_UNOP_RTYPE(???, nullspace) // TODO + FLINTXX_DEFINE_MEMBER_3OP(solve_tril) + FLINTXX_DEFINE_MEMBER_3OP(solve_tril_recursive) + FLINTXX_DEFINE_MEMBER_3OP(solve_tril_classical) + FLINTXX_DEFINE_MEMBER_3OP(solve_triu) + FLINTXX_DEFINE_MEMBER_3OP(solve_triu_recursive) + FLINTXX_DEFINE_MEMBER_3OP(solve_triu_classical) +}; + +namespace detail { +struct nmod_mat_data; +} // detail + +typedef nmod_matxx_expression nmod_matxx; +typedef nmod_matxx_expression > nmod_matxx_ref; +typedef nmod_matxx_expression > nmod_matxx_srcref; + +template<> +struct matrix_traits +{ + template static slong rows(const M& m) + { + return nmod_mat_nrows(m._mat()); + } + template static slong cols(const M& m) + { + return nmod_mat_ncols(m._mat()); + } + + template static nmodxx_srcref at(const M& m, slong i, slong j) + { + return nmodxx_srcref::make(nmod_mat_entry(m._mat(), i, j), + m.estimate_ctx()); + } + template static nmodxx_ref at(M& m, slong i, slong j) + { + return nmodxx_ref::make(nmod_mat_entry(m._mat(), i, j), + m.estimate_ctx()); + } +}; + +namespace traits { +template<> struct has_nmodxx_ctx : mp::true_ { }; +template<> struct has_nmodxx_ctx : mp::true_ { }; +template<> struct has_nmodxx_ctx : mp::true_ { }; +} // traits + +namespace detail { +template<> +struct nmod_matxx_traits + : matrices::generic_traits_srcref { }; +template<> +struct nmod_matxx_traits + : matrices::generic_traits_ref { }; +template<> struct nmod_matxx_traits + : matrices::generic_traits_nonref { }; + +struct nmod_mat_data +{ + typedef nmod_mat_t& data_ref_t; + typedef const nmod_mat_t& data_srcref_t; + + nmod_mat_t inner; + + nmod_mat_data(slong m, slong n, mp_limb_t modulus) + { + nmod_mat_init(inner, m, n, modulus); + } + + nmod_mat_data(const nmod_mat_data& o) + { + nmod_mat_init_set(inner, o.inner); + } + + nmod_mat_data(nmod_matxx_srcref o) + { + nmod_mat_init_set(inner, o._data().inner); + } + + ~nmod_mat_data() {nmod_mat_clear(inner);} +}; +} // detail + +namespace matrices { +template<> +struct outsize + : outsize { }; + +template<> struct outsize + : outsize { }; +template<> struct outsize + : outsize { }; +template<> struct outsize + : outsize { }; +template<> struct outsize + : outsize { }; +template<> struct outsize + : outsize { }; +template<> struct outsize + : outsize { }; +} + +// temporary instantiation stuff +FLINTXX_DEFINE_TEMPORARY_RULES(nmod_matxx) + +#define NMOD_MATXX_COND_S FLINTXX_COND_S(nmod_matxx) +#define NMOD_MATXX_COND_T FLINTXX_COND_T(nmod_matxx) + +namespace traits { +template struct is_nmod_matxx + : flint_classes::is_Base { }; +} // traits + +namespace rules { +FLINT_DEFINE_DOIT_COND2(assignment, NMOD_MATXX_COND_T, NMOD_MATXX_COND_S, + nmod_mat_set(to._mat(), from._mat())) + +FLINTXX_DEFINE_SWAP(nmod_matxx, nmod_mat_swap(e1._mat(), e2._mat())) + +FLINTXX_DEFINE_EQUALS(nmod_matxx, nmod_mat_equal(e1._mat(), e2._mat())) + +FLINT_DEFINE_PRINT_PRETTY_COND(NMOD_MATXX_COND_S, + (nmod_mat_print_pretty(from._mat()), 1)) + +FLINT_DEFINE_THREEARY_EXPR_COND3(mat_at_op, nmodxx, + NMOD_MATXX_COND_S, traits::fits_into_slong, traits::fits_into_slong, + to.set_nored(nmod_mat_entry(e1._mat(), e2, e3))) + +FLINT_DEFINE_BINARY_EXPR_COND2(times, nmod_matxx, + NMOD_MATXX_COND_S, NMOD_MATXX_COND_S, + nmod_mat_mul(to._mat(), e1._mat(), e2._mat())) +FLINT_DEFINE_CBINARY_EXPR_COND2(times, nmod_matxx, + NMOD_MATXX_COND_S, NMODXX_COND_S, + nmod_mat_scalar_mul(to._mat(), e1._mat(), e2._limb())) + +FLINT_DEFINE_BINARY_EXPR_COND2(plus, nmod_matxx, + NMOD_MATXX_COND_S, NMOD_MATXX_COND_S, + nmod_mat_add(to._mat(), e1._mat(), e2._mat())) +FLINT_DEFINE_BINARY_EXPR_COND2(minus, nmod_matxx, + NMOD_MATXX_COND_S, NMOD_MATXX_COND_S, + nmod_mat_sub(to._mat(), e1._mat(), e2._mat())) + +FLINT_DEFINE_UNARY_EXPR_COND(negate, nmod_matxx, NMOD_MATXX_COND_S, + nmod_mat_neg(to._mat(), from._mat())) + +FLINT_DEFINE_UNARY_EXPR_COND(transpose_op, nmod_matxx, NMOD_MATXX_COND_S, + nmod_mat_transpose(to._mat(), from._mat())) +FLINT_DEFINE_UNARY_EXPR_COND(trace_op, nmodxx, NMOD_MATXX_COND_S, + to.set_nored(nmod_mat_trace(from._mat()))) + +FLINT_DEFINE_BINARY_EXPR_COND2(mul_classical_op, nmod_matxx, + NMOD_MATXX_COND_S, NMOD_MATXX_COND_S, + nmod_mat_mul(to._mat(), e1._mat(), e2._mat())) +FLINT_DEFINE_BINARY_EXPR_COND2(mul_strassen_op, nmod_matxx, + NMOD_MATXX_COND_S, NMOD_MATXX_COND_S, + nmod_mat_mul(to._mat(), e1._mat(), e2._mat())) + +FLINT_DEFINE_UNARY_EXPR_COND(det_op, nmodxx, NMOD_MATXX_COND_S, + to.set_nored(nmod_mat_det(from._mat()))) + +FLINT_DEFINE_UNARY_EXPR_COND(inv_op, nmod_matxx, NMOD_MATXX_COND_S, + execution_check(nmod_mat_inv(to._mat(), from._mat()), + "inv", "nmod_mat")) + +#define NMOD_MATXX_DEFINE_SOLVE_TRI(name) \ +FLINT_DEFINE_THREEARY_EXPR_COND3(name##_op, nmod_matxx, \ + NMOD_MATXX_COND_S, NMOD_MATXX_COND_S, tools::is_bool, \ + nmod_mat_##name(to._mat(), e1._mat(), e2._mat(), e3)) +NMOD_MATXX_DEFINE_SOLVE_TRI(solve_tril) +NMOD_MATXX_DEFINE_SOLVE_TRI(solve_tril_classical) +NMOD_MATXX_DEFINE_SOLVE_TRI(solve_tril_recursive) +NMOD_MATXX_DEFINE_SOLVE_TRI(solve_triu) +NMOD_MATXX_DEFINE_SOLVE_TRI(solve_triu_classical) +NMOD_MATXX_DEFINE_SOLVE_TRI(solve_triu_recursive) + +FLINT_DEFINE_BINARY_EXPR_COND2(solve_op, nmod_matxx, + NMOD_MATXX_COND_S, NMOD_MATXX_COND_S, + execution_check(nmod_mat_solve(to._mat(), e1._mat(), e2._mat()), + "solve", "nmod_mat")) + +FLINT_DEFINE_BINARY_EXPR_COND2(solve_op, nmod_vecxx, + NMOD_MATXX_COND_S, NMOD_VECXX_COND_S, + execution_check(nmod_mat_solve_vec(to._array(), e1._mat(), e2._array()), + "solve_vec", "nmod_mat")) + +namespace rdetail { +typedef make_ltuple::type >::type + nmod_mat_nullspace_rt; +} // rdetail +FLINT_DEFINE_UNARY_EXPR_COND(nullspace_op, rdetail::nmod_mat_nullspace_rt, + NMOD_MATXX_COND_S, to.template get<0>() = nmod_mat_nullspace( + to.template get<1>()._mat(), from._mat())) +} // rules + +////////////////////////////////////////////////////////////////////////////// +// nmod_mat_vector class +////////////////////////////////////////////////////////////////////////////// +// This class stores a vector of nmod_matxx with differing moduli. It is *not* +// an expression template class! + +class nmod_mat_vector +{ +private: + nmod_mat_t* data; + std::size_t size_; + + void init(const nmod_mat_vector& o) + { + size_ = o.size_; + data = new nmod_mat_t[size_]; + for(std::size_t i = 0;i < size_;++i) + nmod_mat_init_set(data[i], o.data[i]); + } + +public: + ~nmod_mat_vector() {delete[] data;} + nmod_mat_vector(slong rows, slong cols, const std::vector& primes) + { + size_ = primes.size(); + data = new nmod_mat_t[primes.size()]; + for(std::size_t i = 0;i < primes.size();++i) + nmod_mat_init(data[i], rows, cols, primes[i]); + } + + nmod_mat_vector(const nmod_mat_vector& o) + { + init(o); + } + + nmod_mat_vector& operator=(const nmod_mat_vector& o) + { + delete[] data; + init(o); + return *this; + } + + nmod_matxx_ref operator[](std::size_t idx) + {return nmod_matxx_ref::make(data[idx]);} + nmod_matxx_srcref operator[](std::size_t idx) const + {return nmod_matxx_srcref::make(data[idx]);} + + std::size_t size() const {return size_;} + + const nmod_mat_t* _data() const {return data;} + nmod_mat_t* _data() {return data;} + + bool operator==(const nmod_mat_vector& o) + { + if(size() != o.size()) + return false; + for(std::size_t i = 0;i < size();++i) + if((*this)[i] != o[i]) + return false; + return true; + } + bool operator!=(const nmod_mat_vector& o) + { + return !(*this == o); + } + + template + void set_multi_mod(const Fmpz_mat& m, + typename mp::enable_if >::type* = 0) + { + fmpz_mat_multi_mod_ui(data, size(), m.evaluate()._mat()); + } + template + void set_multi_mod_precomp(const Fmpz_mat& m, + const fmpz_combxx& comb, + typename mp::enable_if >::type* = 0) + { + fmpz_mat_multi_mod_ui_precomp(data, size(), m.evaluate()._mat(), + comb._comb(), comb._temp()); + } +}; + +///////////////////////////////////////////////////////////////////////////// +// chinese remaindering +///////////////////////////////////////////////////////////////////////////// +// Note this operates on fmpz_matxx and fmpz_combxx (as well as nmod_matxx). +// We define it here to deal with the circular dependencies. fmpz_matxx.h +// includes nmod_matxx.h at the bottom. + +template +inline nmod_mat_vector multi_mod(const Fmpz_mat& m, + const std::vector& primes, + typename mp::enable_if >::type* = 0) +{ + nmod_mat_vector res(m.rows(), m.cols(), primes); + res.set_multi_mod(m); + return res; +} +template +inline nmod_mat_vector multi_mod_precomp(const Fmpz_mat& m, + const std::vector& primes, + const fmpz_combxx& comb, + typename mp::enable_if >::type* = 0) +{ + nmod_mat_vector res(m.rows(), m.cols(), primes); + res.set_multi_mod_precomp(m, comb); + return res; +} + +namespace matrices { +// outsize computation for multi-CRT +struct outsize_CRT +{ + template + static slong rows(const Mat& m) + { + return m._data().first()[0].rows(); + } + template + static slong cols(const Mat& m) + { + return m._data().first()[0].cols(); + } +}; + +template<> struct outsize : outsize_CRT { }; +template<> struct outsize : outsize_CRT { }; +} + +namespace rules { +FLINT_DEFINE_FOURARY_EXPR_COND4(CRT_op, fmpz_matxx, + FMPZ_MATXX_COND_T, FMPZXX_COND_S, NMOD_MATXX_COND_S, tools::is_bool, + fmpz_mat_CRT_ui(to._mat(), e1._mat(), e2._fmpz(), e3._mat(), e4)) + +FLINT_DEFINE_BINARY_EXPR2(multi_CRT_op, fmpz_matxx, nmod_mat_vector, bool, + fmpz_mat_multi_CRT_ui(to._mat(), (nmod_mat_t * const) e1._data(), e1.size(), e2)) +FLINT_DEFINE_THREEARY_EXPR(multi_CRT_precomp_op, fmpz_matxx, + nmod_mat_vector, fmpz_combxx, bool, + fmpz_mat_multi_CRT_ui_precomp(to._mat(), (nmod_mat_t * const) e1._data(), e1.size(), + e2._comb(), e2._temp(), e3)) +} // rules +} // flint + +#endif diff --git a/external/flint-2.4.3/nmod_poly.h b/external/flint-2.4.3/nmod_poly.h new file mode 100644 index 0000000..41b81b7 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly.h @@ -0,0 +1,1162 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007, David Howden + Copyright (C) 2010, 2011 William Hart + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#ifndef NMOD_POLY_H +#define NMOD_POLY_H + +#undef ulong +#define ulong ulongxx /* interferes with system includes */ +#include +#undef ulong +#include +#define ulong mp_limb_t + +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_mat.h" +#include "ulong_extras.h" +#include "fmpz.h" + +#ifdef __cplusplus + extern "C" { +#endif + +#define NMOD_DIVREM_DIVCONQUER_CUTOFF 300 +#define NMOD_DIV_DIVCONQUER_CUTOFF 300 /* Must be <= NMOD_DIVREM_DIVCONQUER_CUTOFF */ + +#define NMOD_POLY_HGCD_CUTOFF 100 /* HGCD: Basecase -> Recursion */ +#define NMOD_POLY_GCD_CUTOFF 340 /* GCD: Euclidean -> HGCD */ +#define NMOD_POLY_SMALL_GCD_CUTOFF 200 /* GCD (small n): Euclidean -> HGCD */ + +static __inline__ +slong NMOD_DIVREM_BC_ITCH(slong lenA, slong lenB, nmod_t mod) +{ + const mp_bitcnt_t bits = + 2 * (FLINT_BITS - mod.norm) + FLINT_BIT_COUNT(lenA - lenB + 1); + + if (bits <= FLINT_BITS) + return lenA; + else if (bits <= 2 * FLINT_BITS) + return 2*(lenA + lenB - 1); + else + return 3*(lenA + lenB - 1); +} + +static __inline__ +slong NMOD_DIV_BC_ITCH(slong lenA, slong lenB, nmod_t mod) +{ + const mp_bitcnt_t bits = + 2 * (FLINT_BITS - mod.norm) + FLINT_BIT_COUNT(lenA - lenB + 1); + + if (bits <= FLINT_BITS) + return lenA - lenB + 1; + else if (bits <= 2 * FLINT_BITS) + return 2*lenA; + else + return 3*lenA; +} + +static __inline__ +slong NMOD_DIVREM_DC_ITCH(slong lenB, nmod_t mod) +{ + slong i = 0; + + while (lenB > NMOD_DIVREM_DIVCONQUER_CUTOFF + i) + { + lenB = (lenB + 1)/2; + i++; + } + if (lenB > NMOD_DIVREM_DIVCONQUER_CUTOFF) + lenB = NMOD_DIVREM_DIVCONQUER_CUTOFF; + + return NMOD_DIVREM_BC_ITCH(2*lenB - 1, lenB, mod) + 2*lenB - 1; +} + +typedef struct +{ + mp_ptr coeffs; + slong alloc; + slong length; + nmod_t mod; +} nmod_poly_struct; + +typedef nmod_poly_struct nmod_poly_t[1]; + +/* zn_poly helper functions ************************************************ + +Copyright (C) 2007, 2008 David Harvey + +*/ + +static __inline__ +int signed_mpn_sub_n(mp_ptr res, mp_srcptr op1, mp_srcptr op2, slong n) +{ + if (mpn_cmp(op1, op2, n) >= 0) + { + mpn_sub_n(res, op1, op2, n); + return 0; + } + else + { + mpn_sub_n(res, op2, op1, n); + return 1; + } +} + +/* Memory management ********************************************************/ + +void nmod_poly_init(nmod_poly_t poly, mp_limb_t n); + +void nmod_poly_init_preinv(nmod_poly_t poly, mp_limb_t n, mp_limb_t ninv); + +void nmod_poly_init2(nmod_poly_t poly, mp_limb_t n, slong alloc); + +void nmod_poly_init2_preinv(nmod_poly_t poly, + mp_limb_t n, mp_limb_t ninv, slong alloc); + +void nmod_poly_realloc(nmod_poly_t poly, slong alloc); + +void nmod_poly_clear(nmod_poly_t poly); + +void nmod_poly_fit_length(nmod_poly_t poly, slong alloc); + +static __inline__ +void _nmod_poly_set_length(nmod_poly_t poly, slong len) +{ + poly->length = len; +} + +static __inline__ +void _nmod_poly_normalise(nmod_poly_t poly) +{ + while (poly->length && (poly->coeffs[poly->length - 1] == WORD(0))) + poly->length--; +} + +/* Polynomial parameters ****************************************************/ + +static __inline__ +slong nmod_poly_length(const nmod_poly_t poly) +{ + return poly->length; +} + +static __inline__ +slong nmod_poly_degree(const nmod_poly_t poly) +{ + return poly->length - 1; +} + +static __inline__ +mp_limb_t nmod_poly_modulus(const nmod_poly_t poly) +{ + return poly->mod.n; +} + +static __inline__ +mp_bitcnt_t nmod_poly_max_bits(const nmod_poly_t poly) +{ + return _nmod_vec_max_bits(poly->coeffs, poly->length); +} + +static __inline__ +mp_ptr nmod_poly_lead(const nmod_poly_t poly) +{ + if (poly->length) + return poly->coeffs + (poly->length - 1); + else + return NULL; +} + +/* Assignment and basic manipulation ****************************************/ + +static __inline__ +void nmod_poly_set(nmod_poly_t a, const nmod_poly_t b) +{ + if (a != b) + { + nmod_poly_fit_length(a, b->length); + flint_mpn_copyi(a->coeffs, b->coeffs, b->length); + a->length = b->length; + } +} + +static __inline__ +void nmod_poly_swap(nmod_poly_t poly1, nmod_poly_t poly2) +{ + slong t; + mp_ptr tp; + + t = poly1->alloc; + poly1->alloc = poly2->alloc; + poly2->alloc = t; + + t = poly1->length; + poly1->length = poly2->length; + poly2->length = t; + + tp = poly1->coeffs; + poly1->coeffs = poly2->coeffs; + poly2->coeffs = tp; +} + +static __inline__ +void nmod_poly_zero(nmod_poly_t res) +{ + res->length = 0; +} + +static __inline__ +void nmod_poly_one(nmod_poly_t res) +{ + nmod_poly_fit_length(res, 1); + res->length = 1; + res->coeffs[0] = 1; +} + +static __inline__ +void nmod_poly_truncate(nmod_poly_t poly, slong len) +{ + if (poly->length > len) + { + poly->length = len; + _nmod_poly_normalise(poly); + } +} + +void _nmod_poly_reverse(mp_ptr output, mp_srcptr input, slong len, slong m); + +void nmod_poly_reverse(nmod_poly_t output, const nmod_poly_t input, slong m); + +/* Comparison ***************************************************************/ + +static __inline__ +int nmod_poly_equal(const nmod_poly_t a, const nmod_poly_t b) +{ + if (a->length != b->length) + return 0; + + if (a != b) + if (!_nmod_vec_equal(a->coeffs, b->coeffs, a->length)) + return 0; + + return 1; +} + +static __inline__ +int nmod_poly_is_zero(const nmod_poly_t poly) +{ + return (poly->length == 0); +} + +static __inline__ int +nmod_poly_is_one(const nmod_poly_t poly) +{ + return (poly->length == 1) && (poly->coeffs[0] == 1); +} + +/* Randomisation ************************************************************/ + +void nmod_poly_randtest(nmod_poly_t poly, flint_rand_t state, slong len); + +static __inline__ void +nmod_poly_randtest_not_zero(nmod_poly_t poly, flint_rand_t state, slong len) +{ + do { + nmod_poly_randtest(poly, state, len); + } while (nmod_poly_is_zero(poly)); +} + +void +nmod_poly_randtest_irreducible(nmod_poly_t poly, flint_rand_t state, slong len); + +void +nmod_poly_randtest_monic(nmod_poly_t poly, flint_rand_t state, slong len); + +void +nmod_poly_randtest_monic_irreducible(nmod_poly_t poly, flint_rand_t state, slong len); + +void +nmod_poly_randtest_trinomial(nmod_poly_t poly, flint_rand_t state, slong len); + +int +nmod_poly_randtest_trinomial_irreducible(nmod_poly_t poly, flint_rand_t state, + slong len, slong max_attempts); + +void +nmod_poly_randtest_pentomial(nmod_poly_t poly, flint_rand_t state, slong len); + +int +nmod_poly_randtest_pentomial_irreducible(nmod_poly_t poly, flint_rand_t state, + slong len, slong max_attempts); + +void +nmod_poly_randtest_sparse_irreducible(nmod_poly_t poly, flint_rand_t state, slong len); + +/* Getting and setting coefficients *****************************************/ + +static __inline__ +ulong nmod_poly_get_coeff_ui(const nmod_poly_t poly, slong j) +{ + return (j >= poly->length) ? 0 : poly->coeffs[j]; +} + +void nmod_poly_set_coeff_ui(nmod_poly_t poly, slong j, ulong c); + +/* Input and output *********************************************************/ + +char * nmod_poly_get_str(const nmod_poly_t poly); + +int nmod_poly_set_str(nmod_poly_t poly, const char * s); + +static __inline__ +int nmod_poly_print(const nmod_poly_t a) +{ + size_t r; + slong i; + + r = flint_printf("%wd %wu", a->length, a->mod.n); + + if (a->length == 0) + return r; + else + if (r > 0) + r = flint_printf(" "); + + for (i = 0; (r > 0) && (i < a->length); i++) + r = flint_printf(" %wu", a->coeffs[i]); + + return (int) r; +} + +int nmod_poly_fread(FILE * f, nmod_poly_t poly); + +static __inline__ +int nmod_poly_fprint(FILE * f, const nmod_poly_t poly) +{ + char *s; + int r; + + s = nmod_poly_get_str(poly); + r = fputs(s, f); + flint_free(s); + + return (r < 0) ? r : 1; +} + +static __inline__ +int nmod_poly_read(nmod_poly_t poly) +{ + return nmod_poly_fread(stdin, poly); +} + +/* Shifting *****************************************************************/ + +void _nmod_poly_shift_left(mp_ptr res, mp_srcptr poly, slong len, slong k); + +void nmod_poly_shift_left(nmod_poly_t res, const nmod_poly_t poly, slong k); + +void _nmod_poly_shift_right(mp_ptr res, mp_srcptr poly, slong len, slong k); + +void nmod_poly_shift_right(nmod_poly_t res, const nmod_poly_t poly, slong k); + +/* Addition and subtraction *************************************************/ + +void _nmod_poly_add(mp_ptr res, mp_srcptr poly1, slong len1, + mp_srcptr poly2, slong len2, nmod_t mod); + +void nmod_poly_add(nmod_poly_t res, const nmod_poly_t poly1, + const nmod_poly_t poly2); + +void _nmod_poly_sub(mp_ptr res, mp_srcptr poly1, slong len1, + mp_srcptr poly2, slong len2, nmod_t mod); + +void nmod_poly_sub(nmod_poly_t res, const nmod_poly_t poly1, + const nmod_poly_t poly2); + +void nmod_poly_neg(nmod_poly_t res, const nmod_poly_t poly1); + +/* Scalar multiplication and division ***************************************/ + +void nmod_poly_scalar_mul_nmod(nmod_poly_t res, + const nmod_poly_t poly1, mp_limb_t c); + +void _nmod_poly_make_monic(mp_ptr output, + mp_srcptr input, slong len, nmod_t mod); + +void nmod_poly_make_monic(nmod_poly_t output, const nmod_poly_t input); + +/* Bit packing and unpacking aand reduction **********************************/ + +void _nmod_poly_KS2_pack1(mp_ptr res, mp_srcptr op, slong n, slong s, + ulong b, ulong k, slong r); + +void _nmod_poly_KS2_pack(mp_ptr res, mp_srcptr op, slong n, slong s, + ulong b, ulong k, slong r); + +void _nmod_poly_KS2_unpack1(mp_ptr res, mp_srcptr op, slong n, ulong b, + ulong k); + +void _nmod_poly_KS2_unpack2(mp_ptr res, mp_srcptr op, slong n, ulong b, + ulong k); + +void _nmod_poly_KS2_unpack3(mp_ptr res, mp_srcptr op, slong n, ulong b, + ulong k); + +void _nmod_poly_KS2_unpack(mp_ptr res, mp_srcptr op, slong n, ulong b, + ulong k); + +void _nmod_poly_KS2_reduce(mp_ptr res, slong s, mp_srcptr op, + slong n, ulong w, nmod_t mod); + +void _nmod_poly_KS2_recover_reduce1(mp_ptr res, slong s, mp_srcptr op1, + mp_srcptr op2, slong n, ulong b, nmod_t mod); + +void _nmod_poly_KS2_recover_reduce1(mp_ptr res, slong s, mp_srcptr op1, + mp_srcptr op2, slong n, ulong b, nmod_t mod); + +void _nmod_poly_KS2_recover_reduce2(mp_ptr res, slong s, mp_srcptr op1, + mp_srcptr op2, slong n, ulong b, nmod_t mod); + +void _nmod_poly_KS2_recover_reduce2b(mp_ptr res, slong s, mp_srcptr op1, + mp_srcptr op2, slong n, ulong b, nmod_t mod); + +void _nmod_poly_KS2_recover_reduce(mp_ptr res, slong s, mp_srcptr op1, + mp_srcptr op2, slong n, ulong b, nmod_t mod); + +void _nmod_poly_bit_pack(mp_ptr res, mp_srcptr poly, + slong len, mp_bitcnt_t bits); + +void _nmod_poly_bit_unpack(mp_ptr res, slong len, + mp_srcptr mpn, mp_bitcnt_t bits, nmod_t mod); + +void nmod_poly_bit_pack(fmpz_t f, const nmod_poly_t poly, + mp_bitcnt_t bit_size); + +void +nmod_poly_bit_unpack(nmod_poly_t poly, const fmpz_t f, mp_bitcnt_t bit_size); + +void +_nmod_poly_KS2_pack(mp_ptr res, mp_srcptr op, slong n, slong s, + ulong b, ulong k, slong r); + +/* Multiplication ***********************************************************/ + +void _nmod_poly_mul_classical(mp_ptr res, mp_srcptr poly1, slong len1, + mp_srcptr poly2, slong len2, nmod_t mod); + +void nmod_poly_mul_classical(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_poly_t poly2); + +void _nmod_poly_mullow_classical(mp_ptr res, mp_srcptr poly1, slong len1, + mp_srcptr poly2, slong len2, slong trunc, nmod_t mod); + +void nmod_poly_mullow_classical(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_poly_t poly2, slong trunc); + +void _nmod_poly_mulhigh_classical(mp_ptr res, mp_srcptr poly1, slong len1, + mp_srcptr poly2, slong len2, slong start, nmod_t mod); + +void nmod_poly_mulhigh_classical(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_poly_t poly2, slong start); + +void _nmod_poly_mul_KS(mp_ptr out, mp_srcptr in1, slong len1, + mp_srcptr in2, slong len2, mp_bitcnt_t bits, nmod_t mod); + +void nmod_poly_mul_KS(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_poly_t poly2, mp_bitcnt_t bits); + +void _nmod_poly_mul_KS2(mp_ptr res, mp_srcptr op1, slong n1, + mp_srcptr op2, slong n2, nmod_t mod); + +void nmod_poly_mul_KS2(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_poly_t poly2); + +void _nmod_poly_mul_KS4(mp_ptr res, mp_srcptr op1, slong n1, + mp_srcptr op2, slong n2, nmod_t mod); + +void nmod_poly_mul_KS4(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_poly_t poly2); + +void _nmod_poly_mullow_KS(mp_ptr out, mp_srcptr in1, slong len1, + mp_srcptr in2, slong len2, mp_bitcnt_t bits, slong n, nmod_t mod); + +void nmod_poly_mullow_KS(nmod_poly_t res, const nmod_poly_t poly1, + const nmod_poly_t poly2, mp_bitcnt_t bits, slong n); + +void _nmod_poly_mul(mp_ptr res, mp_srcptr poly1, slong len1, + mp_srcptr poly2, slong len2, nmod_t mod); + +void nmod_poly_mul(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_poly_t poly2); + +void _nmod_poly_mullow(mp_ptr res, mp_srcptr poly1, slong len1, + mp_srcptr poly2, slong len2, slong trunc, nmod_t mod); + +void nmod_poly_mullow(nmod_poly_t res, const nmod_poly_t poly1, + const nmod_poly_t poly2, slong trunc); + +void _nmod_poly_mulhigh(mp_ptr res, mp_srcptr poly1, slong len1, + mp_srcptr poly2, slong len2, slong n, nmod_t mod); + +void nmod_poly_mulhigh(nmod_poly_t res, const nmod_poly_t poly1, + const nmod_poly_t poly2, slong n); + +void _nmod_poly_mulmod(mp_ptr res, mp_srcptr poly1, slong len1, + mp_srcptr poly2, slong len2, mp_srcptr f, + slong lenf, nmod_t mod); + +void nmod_poly_mulmod(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_poly_t poly2, const nmod_poly_t f); + +void _nmod_poly_mulmod_preinv(mp_ptr res, mp_srcptr poly1, slong len1, + mp_srcptr poly2, slong len2, mp_srcptr f, + slong lenf, mp_srcptr finv, slong lenfinv, nmod_t mod); + +void +nmod_poly_mulmod_preinv(nmod_poly_t res, const nmod_poly_t poly1, + const nmod_poly_t poly2, const nmod_poly_t f, + const nmod_poly_t finv); + +int _nmod_poly_invmod(mp_limb_t *A, + const mp_limb_t *B, slong lenB, + const mp_limb_t *P, slong lenP, const nmod_t mod); + +int nmod_poly_invmod(nmod_poly_t A, + const nmod_poly_t B, const nmod_poly_t P); + +/* Powering *****************************************************************/ + +void _nmod_poly_pow_binexp(mp_ptr res, + mp_srcptr poly, slong len, ulong e, nmod_t mod); + +void nmod_poly_pow_binexp(nmod_poly_t res, const nmod_poly_t poly, ulong e); + +void _nmod_poly_pow(mp_ptr res, mp_srcptr poly, slong len, ulong e, nmod_t mod); + +void nmod_poly_pow(nmod_poly_t res, const nmod_poly_t poly, ulong e); + +void _nmod_poly_pow_trunc_binexp(mp_ptr res, mp_srcptr poly, + ulong e, slong trunc, nmod_t mod); + +void nmod_poly_pow_trunc_binexp(nmod_poly_t res, + const nmod_poly_t poly, ulong e, slong trunc); + +void _nmod_poly_pow_trunc(mp_ptr res, mp_srcptr poly, + ulong e, slong trunc, nmod_t mod); + +void nmod_poly_pow_trunc(nmod_poly_t res, + const nmod_poly_t poly, ulong e, slong trunc); + +void +nmod_poly_powmod_ui_binexp(nmod_poly_t res, + const nmod_poly_t poly, ulong e, + const nmod_poly_t f); + +void +_nmod_poly_powmod_ui_binexp(mp_ptr res, mp_srcptr poly, + ulong e, mp_srcptr f, slong lenf, nmod_t mod); + +void +_nmod_poly_powmod_mpz_binexp(mp_ptr res, mp_srcptr poly, + mpz_srcptr e, mp_srcptr f, + slong lenf, nmod_t mod); + +void +nmod_poly_powmod_mpz_binexp(nmod_poly_t res, + const nmod_poly_t poly, mpz_srcptr e, + const nmod_poly_t f); + +void +_nmod_poly_powmod_ui_binexp_preinv (mp_ptr res, mp_srcptr poly, + ulong e, mp_srcptr f, slong lenf, + mp_srcptr finv, slong lenfinv, nmod_t mod); + +void +nmod_poly_powmod_ui_binexp_preinv(nmod_poly_t res, + const nmod_poly_t poly, ulong e, + const nmod_poly_t f, const nmod_poly_t finv); + +void +_nmod_poly_powmod_x_ui_preinv (mp_ptr res, ulong e, mp_srcptr f, slong lenf, + mp_srcptr finv, slong lenfinv, nmod_t mod); + +void +nmod_poly_powmod_x_ui_preinv(nmod_poly_t res, ulong e, const nmod_poly_t f, + const nmod_poly_t finv); + +void +_nmod_poly_powmod_mpz_binexp_preinv (mp_ptr res, mp_srcptr poly, + mpz_srcptr e, mp_srcptr f, slong lenf, + mp_srcptr finv, slong lenfinv, nmod_t mod); + +void +nmod_poly_powmod_mpz_binexp_preinv(nmod_poly_t res, + const nmod_poly_t poly, mpz_srcptr e, + const nmod_poly_t f, const nmod_poly_t finv); + +/* Division *****************************************************************/ + +void _nmod_poly_divrem_basecase(mp_ptr Q, mp_ptr R, mp_ptr W, + mp_srcptr A, slong A_len, mp_srcptr B, slong B_len, nmod_t mod); + +void nmod_poly_divrem_basecase(nmod_poly_t Q, nmod_poly_t R, + const nmod_poly_t A, const nmod_poly_t B); + +void _nmod_poly_divrem_divconquer_recursive(mp_ptr Q, mp_ptr BQ, mp_ptr W, + mp_ptr V, mp_srcptr A, mp_srcptr B, slong lenB, nmod_t mod); + +void _nmod_poly_divrem_divconquer(mp_ptr Q, mp_ptr R, + mp_srcptr A, slong lenA, mp_srcptr B, slong lenB, nmod_t mod); + +void nmod_poly_divrem_divconquer(nmod_poly_t Q, nmod_poly_t R, + const nmod_poly_t A, const nmod_poly_t B); + +void _nmod_poly_divrem_q0(mp_ptr Q, mp_ptr R, + mp_srcptr A, mp_srcptr B, slong lenA, nmod_t mod); + +void _nmod_poly_divrem_q1(mp_ptr Q, mp_ptr R, + mp_srcptr A, slong lenA, mp_srcptr B, slong lenB, + nmod_t mod); + +void _nmod_poly_divrem(mp_ptr Q, mp_ptr R, mp_srcptr A, slong lenA, + mp_srcptr B, slong lenB, nmod_t mod); + +void nmod_poly_divrem(nmod_poly_t Q, nmod_poly_t R, + const nmod_poly_t A, const nmod_poly_t B); + +void _nmod_poly_div_basecase(mp_ptr Q, mp_ptr W, mp_srcptr A, slong A_len, + mp_srcptr B, slong B_len, nmod_t mod); + +void nmod_poly_div_basecase(nmod_poly_t Q, const nmod_poly_t A, + const nmod_poly_t B); + +void _nmod_poly_div_divconquer_recursive(mp_ptr Q, mp_ptr W, mp_ptr V, + mp_srcptr A, mp_srcptr B, slong lenB, nmod_t mod); + +void _nmod_poly_div_divconquer(mp_ptr Q, mp_srcptr A, slong lenA, + mp_srcptr B, slong lenB, nmod_t mod); + +void nmod_poly_div_divconquer(nmod_poly_t Q, + const nmod_poly_t A, const nmod_poly_t B); + +void _nmod_poly_div(mp_ptr Q, mp_srcptr A, slong lenA, + mp_srcptr B, slong lenB, nmod_t mod); + +void nmod_poly_div(nmod_poly_t Q, const nmod_poly_t A, const nmod_poly_t B); + +void _nmod_poly_rem_basecase(mp_ptr R, mp_ptr W, mp_srcptr A, slong lenA, + mp_srcptr B, slong lenB, nmod_t mod); + +void nmod_poly_rem_basecase(nmod_poly_t R, const nmod_poly_t A, const nmod_poly_t B); + +void _nmod_poly_rem_q1(mp_ptr R, + mp_srcptr A, slong lenA, mp_srcptr B, slong lenB, + nmod_t mod); + +void _nmod_poly_rem(mp_ptr R, mp_srcptr A, slong lenA, + mp_srcptr B, slong lenB, nmod_t mod); + +void nmod_poly_rem(nmod_poly_t R, const nmod_poly_t A, const nmod_poly_t B); + +void _nmod_poly_inv_series_basecase(mp_ptr Qinv, + mp_srcptr Q, slong n, nmod_t mod); + +void nmod_poly_inv_series_basecase(nmod_poly_t Qinv, + const nmod_poly_t Q, slong n); + +void _nmod_poly_inv_series_newton(mp_ptr Qinv, + mp_srcptr Q, slong n, nmod_t mod); + +void nmod_poly_inv_series_newton(nmod_poly_t Qinv, + const nmod_poly_t Q, slong n); + +static __inline__ +void _nmod_poly_inv_series(mp_ptr Qinv, mp_srcptr Q, slong n, nmod_t mod) +{ + _nmod_poly_inv_series_newton(Qinv, Q, n, mod); +} + +static __inline__ +void nmod_poly_inv_series(nmod_poly_t Qinv, const nmod_poly_t Q, slong n) +{ + nmod_poly_inv_series_newton(Qinv, Q, n); +} + +void _nmod_poly_div_series(mp_ptr Q, mp_srcptr A, mp_srcptr B, + slong n, nmod_t mod); + +void nmod_poly_div_series(nmod_poly_t Q, const nmod_poly_t A, + const nmod_poly_t B, slong n); + +void _nmod_poly_div_newton(mp_ptr Q, mp_srcptr A, slong Alen, + mp_srcptr B, slong Blen, nmod_t mod); + +void nmod_poly_div_newton(nmod_poly_t Q, const nmod_poly_t A, + const nmod_poly_t B); + +void _nmod_poly_divrem_newton(mp_ptr Q, mp_ptr R, + mp_srcptr A, slong Alen, mp_srcptr B, slong Blen, nmod_t mod); + +void nmod_poly_divrem_newton(nmod_poly_t Q, nmod_poly_t R, + const nmod_poly_t A, const nmod_poly_t B); + +void _nmod_poly_div_newton_n_preinv (mp_ptr Q, mp_srcptr A, slong lenA, + mp_srcptr B, slong lenB, mp_srcptr Binv, slong lenBinv, nmod_t mod); + +void nmod_poly_div_newton_n_preinv (nmod_poly_t Q, const nmod_poly_t A, + const nmod_poly_t B, const nmod_poly_t Binv); + +void _nmod_poly_divrem_newton_n_preinv (mp_ptr Q, mp_ptr R, mp_srcptr A, + slong lenA, mp_srcptr B, slong lenB, mp_srcptr Binv, slong lenBinv, nmod_t mod); + +void nmod_poly_divrem_newton_n_preinv(nmod_poly_t Q, nmod_poly_t R, + const nmod_poly_t A, const nmod_poly_t B, const nmod_poly_t Binv); + +mp_limb_t +_nmod_poly_div_root(mp_ptr Q, mp_srcptr A, slong len, mp_limb_t c, nmod_t mod); + +mp_limb_t +nmod_poly_div_root(nmod_poly_t Q, const nmod_poly_t A, mp_limb_t c); + +/* Derivative ***************************************************************/ + +void _nmod_poly_derivative(mp_ptr x_prime, mp_srcptr x, slong len, nmod_t mod); + +void nmod_poly_derivative(nmod_poly_t x_prime, const nmod_poly_t x); + +void _nmod_poly_integral(mp_ptr x_int, mp_srcptr x, slong len, nmod_t mod); + +void nmod_poly_integral(nmod_poly_t x_int, const nmod_poly_t x); + +/* Evaluation ***************************************************************/ +void +_nmod_poly_evaluate_fmpz(fmpz_t rop, const mp_srcptr poly, const slong len, const fmpz_t c); + +void +nmod_poly_evaluate_fmpz(fmpz_t rop, const nmod_poly_t poly, const fmpz_t c); + +mp_limb_t _nmod_poly_evaluate_nmod(mp_srcptr poly, + slong len, mp_limb_t c, nmod_t mod); + +mp_limb_t nmod_poly_evaluate_nmod(const nmod_poly_t poly, mp_limb_t c); + +void _nmod_poly_evaluate_nmod_vec(mp_ptr ys, mp_srcptr coeffs, slong len, + mp_srcptr xs, slong n, nmod_t mod); + +void nmod_poly_evaluate_nmod_vec(mp_ptr ys, + const nmod_poly_t poly, mp_srcptr xs, slong n); + +void nmod_poly_evaluate_nmod_vec(mp_ptr ys, const nmod_poly_t poly, + mp_srcptr xs, slong n); + +void _nmod_poly_evaluate_nmod_vec_iter(mp_ptr ys, mp_srcptr coeffs, slong len, + mp_srcptr xs, slong n, nmod_t mod); + +void nmod_poly_evaluate_nmod_vec_iter(mp_ptr ys, + const nmod_poly_t poly, mp_srcptr xs, slong n); + +void +_nmod_poly_evaluate_nmod_vec_fast_precomp(mp_ptr vs, mp_srcptr poly, + slong plen, const mp_ptr * tree, slong len, nmod_t mod); + +void _nmod_poly_evaluate_nmod_vec_fast(mp_ptr ys, mp_srcptr coeffs, slong len, + mp_srcptr xs, slong n, nmod_t mod); + +void nmod_poly_evaluate_nmod_vec_fast(mp_ptr ys, + const nmod_poly_t poly, mp_srcptr xs, slong n); + +/* Subproduct tree **********************************************************/ + +mp_ptr * _nmod_poly_tree_alloc(slong len); + +void _nmod_poly_tree_free(mp_ptr * tree, slong len); + +void _nmod_poly_tree_build(mp_ptr * tree, mp_srcptr roots, + slong len, nmod_t mod); + +/* Interpolation ************************************************************/ + +void _nmod_poly_interpolate_nmod_vec_newton(mp_ptr poly, mp_srcptr xs, + mp_srcptr ys, slong n, nmod_t mod); + +void nmod_poly_interpolate_nmod_vec_newton(nmod_poly_t poly, + mp_srcptr xs, mp_srcptr ys, slong n); + +void _nmod_poly_interpolate_nmod_vec_barycentric(mp_ptr poly, mp_srcptr xs, + mp_srcptr ys, slong n, nmod_t mod); + +void nmod_poly_interpolate_nmod_vec_barycentric(nmod_poly_t poly, + mp_srcptr xs, mp_srcptr ys, slong n); + +void _nmod_poly_interpolate_nmod_vec(mp_ptr poly, mp_srcptr xs, + mp_srcptr ys, slong n, nmod_t mod); + +void nmod_poly_interpolate_nmod_vec(nmod_poly_t poly, + mp_srcptr xs, mp_srcptr ys, slong n); + +void nmod_poly_interpolate_nmod_vec_fast(nmod_poly_t poly, + mp_srcptr xs, mp_srcptr ys, slong n); + +void _nmod_poly_interpolate_nmod_vec_fast(mp_ptr poly, + mp_srcptr xs, mp_srcptr ys, slong len, nmod_t mod); + +void +_nmod_poly_interpolate_nmod_vec_fast_precomp(mp_ptr poly, mp_srcptr ys, + const mp_ptr * tree, mp_srcptr weights, slong len, nmod_t mod); + +void _nmod_poly_interpolation_weights(mp_ptr w, const mp_ptr * tree, + slong len, nmod_t mod); + +/* Composition **************************************************************/ + +void _nmod_poly_compose_horner(mp_ptr res, mp_srcptr poly1, + slong len1, mp_srcptr poly2, slong len2, nmod_t mod); + +void nmod_poly_compose_horner(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_poly_t poly2); + +void _nmod_poly_compose_divconquer(mp_ptr res, mp_srcptr poly1, slong len1, + mp_srcptr poly2, slong len2, nmod_t mod); +void nmod_poly_compose_divconquer(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_poly_t poly2); + +void _nmod_poly_compose(mp_ptr res, mp_srcptr poly1, slong len1, + mp_srcptr poly2, slong len2, nmod_t mod); + +void nmod_poly_compose(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_poly_t poly2); + +/* Taylor shift *************************************************************/ + +void _nmod_poly_taylor_shift_horner(mp_ptr poly, mp_limb_t c, + slong len, nmod_t mod); + +void nmod_poly_taylor_shift_horner(nmod_poly_t g, + const nmod_poly_t f, mp_limb_t c); + +void _nmod_poly_taylor_shift_convolution(mp_ptr poly, mp_limb_t c, + slong len, nmod_t mod); + +void nmod_poly_taylor_shift_convolution(nmod_poly_t g, + const nmod_poly_t f, mp_limb_t c); + +void _nmod_poly_taylor_shift(mp_ptr poly, mp_limb_t c, slong len, nmod_t mod); + +void nmod_poly_taylor_shift(nmod_poly_t g, const nmod_poly_t f, mp_limb_t c); + +/* Modular composition ******************************************************/ + +void +_nmod_poly_compose_mod_brent_kung(mp_ptr res, mp_srcptr f, slong lenf, + mp_srcptr g, mp_srcptr h, slong lenh, nmod_t mod); + +void +nmod_poly_compose_mod_brent_kung(nmod_poly_t res, + const nmod_poly_t f, const nmod_poly_t g, + const nmod_poly_t h); + +void +_nmod_poly_reduce_matrix_mod_poly (nmod_mat_t A, const nmod_mat_t B, + const nmod_poly_t f); + +void +_nmod_poly_precompute_matrix (nmod_mat_t A, mp_srcptr poly1, mp_srcptr poly2, + slong len2, mp_srcptr poly2inv, slong len2inv, nmod_t mod); + +void +nmod_poly_precompute_matrix (nmod_mat_t A, const nmod_poly_t poly1, + const nmod_poly_t poly2, const nmod_poly_t poly2inv); + +void +_nmod_poly_compose_mod_brent_kung_precomp_preinv(mp_ptr res, mp_srcptr poly1, + slong len1, const nmod_mat_t A, mp_srcptr poly3, + slong len3, mp_srcptr poly3inv, slong len3inv, + nmod_t mod); + +void +nmod_poly_compose_mod_brent_kung_precomp_preinv(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_mat_t A, + const nmod_poly_t poly3, const nmod_poly_t poly3inv); + +void +_nmod_poly_compose_mod_brent_kung_preinv(mp_ptr res, mp_srcptr poly1, slong len1, + mp_srcptr poly2, mp_srcptr poly3, slong len3, + mp_srcptr poly3inv, slong len3inv, nmod_t mod); + +void +nmod_poly_compose_mod_brent_kung_preinv(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_poly_t poly2, + const nmod_poly_t poly3, const nmod_poly_t poly3inv); + +void +_nmod_poly_compose_mod_horner(mp_ptr res, + mp_srcptr f, slong lenf, mp_srcptr g, mp_srcptr h, slong lenh, nmod_t mod); + +void +nmod_poly_compose_mod_horner(nmod_poly_t res, + const nmod_poly_t f, const nmod_poly_t g, + const nmod_poly_t h); + +void +_nmod_poly_compose_mod(mp_ptr res, mp_srcptr f, slong lenf, + mp_srcptr g, + mp_srcptr h, slong lenh, nmod_t mod); + +void +nmod_poly_compose_mod(nmod_poly_t res, + const nmod_poly_t f, const nmod_poly_t g, + const nmod_poly_t h); + +/* Power series composition and reversion ************************************/ + +void +_nmod_poly_compose_series_horner(mp_ptr res, mp_srcptr poly1, slong len1, + mp_srcptr poly2, slong len2, slong n, nmod_t mod); +void +nmod_poly_compose_series_horner(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_poly_t poly2, slong n); + +void +_nmod_poly_compose_series_brent_kung(mp_ptr res, mp_srcptr poly1, slong len1, + mp_srcptr poly2, slong len2, slong n, nmod_t mod); +void +nmod_poly_compose_series_brent_kung(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_poly_t poly2, slong n); + +void +_nmod_poly_compose_series(mp_ptr res, mp_srcptr poly1, slong len1, + mp_srcptr poly2, slong len2, slong n, nmod_t mod); +void +nmod_poly_compose_series(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_poly_t poly2, slong n); + +void +_nmod_poly_revert_series_lagrange(mp_ptr Qinv, mp_srcptr Q, slong n, nmod_t mod); + +void +nmod_poly_revert_series_lagrange(nmod_poly_t Qinv, + const nmod_poly_t Q, slong n); + +void +_nmod_poly_revert_series_lagrange_fast(mp_ptr Qinv, mp_srcptr Q, + slong n, nmod_t mod); + +void +nmod_poly_revert_series_lagrange_fast(nmod_poly_t Qinv, + const nmod_poly_t Q, slong n); + +void +_nmod_poly_revert_series_newton(mp_ptr Qinv, mp_srcptr Q, slong n, nmod_t mod); + +void +nmod_poly_revert_series_newton(nmod_poly_t Qinv, + const nmod_poly_t Q, slong n); + +void +_nmod_poly_revert_series(mp_ptr Qinv, mp_srcptr Q, slong n, nmod_t mod); + +void +nmod_poly_revert_series(nmod_poly_t Qinv, + const nmod_poly_t Q, slong n); + +void +_nmod_poly_compose_series_divconquer(mp_ptr res, mp_srcptr poly1, slong len1, + mp_srcptr poly2, slong len2, + slong N, nmod_t mod); + +void +nmod_poly_compose_series_divconquer(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_poly_t poly2, slong N); + +/* Greatest common divisor **************************************************/ + +slong _nmod_poly_gcd_euclidean(mp_ptr G, + mp_srcptr A, slong lenA, mp_srcptr B, slong lenB, nmod_t mod); + +void nmod_poly_gcd_euclidean(nmod_poly_t G, + const nmod_poly_t A, const nmod_poly_t B); + +slong _nmod_poly_hgcd(mp_ptr *M, slong *lenM, + mp_ptr A, slong *lenA, mp_ptr B, slong *lenB, + mp_srcptr a, slong lena, mp_srcptr b, slong lenb, + nmod_t mod); + +slong _nmod_poly_gcd_hgcd(mp_ptr G, mp_srcptr A, slong lenA, + mp_srcptr B, slong lenB, nmod_t mod); + +void nmod_poly_gcd_hgcd(nmod_poly_t G, const nmod_poly_t A, const nmod_poly_t B); + +slong _nmod_poly_gcd(mp_ptr G, mp_srcptr A, slong lenA, + mp_srcptr B, slong lenB, nmod_t mod); + +void nmod_poly_gcd(nmod_poly_t G, const nmod_poly_t A, const nmod_poly_t B); + +slong _nmod_poly_xgcd_euclidean(mp_ptr res, mp_ptr s, mp_ptr t, + mp_srcptr poly1, slong len1, mp_srcptr poly2, slong len2, nmod_t mod); + +void nmod_poly_xgcd_euclidean(nmod_poly_t G, nmod_poly_t S, nmod_poly_t T, + const nmod_poly_t A, const nmod_poly_t B); + +slong _nmod_poly_xgcd_hgcd(mp_ptr G, mp_ptr S, mp_ptr T, + mp_srcptr A, slong lenA, mp_srcptr B, slong lenB, + nmod_t mod); + +void nmod_poly_xgcd_hgcd(nmod_poly_t G, nmod_poly_t S, nmod_poly_t T, + const nmod_poly_t A, const nmod_poly_t B); + +slong _nmod_poly_xgcd(mp_ptr G, mp_ptr S, mp_ptr T, + mp_srcptr A, slong lenA, mp_srcptr B, slong lenB, nmod_t mod); + +void nmod_poly_xgcd(nmod_poly_t G, nmod_poly_t S, nmod_poly_t T, + const nmod_poly_t A, const nmod_poly_t B); + +mp_limb_t +_nmod_poly_resultant_euclidean(mp_srcptr poly1, slong len1, + mp_srcptr poly2, slong len2, nmod_t mod); + +mp_limb_t +nmod_poly_resultant_euclidean(const nmod_poly_t f, const nmod_poly_t g); + +static __inline__ mp_limb_t +_nmod_poly_resultant(mp_srcptr poly1, slong len1, + mp_srcptr poly2, slong len2, nmod_t mod) +{ + return _nmod_poly_resultant_euclidean(poly1, len1, poly2, len2, mod); +} + +static __inline__ mp_limb_t +nmod_poly_resultant(const nmod_poly_t f, const nmod_poly_t g) +{ + return nmod_poly_resultant_euclidean(f, g); +} + +slong _nmod_poly_gcdinv(mp_limb_t *G, mp_limb_t *S, + const mp_limb_t *A, slong lenA, + const mp_limb_t *B, slong lenB, + const nmod_t mod); + +void nmod_poly_gcdinv(nmod_poly_t G, nmod_poly_t S, + const nmod_poly_t A, const nmod_poly_t B); + +/* Square roots **************************************************************/ + +void _nmod_poly_invsqrt_series(mp_ptr g, mp_srcptr h, slong n, nmod_t mod); + +void nmod_poly_invsqrt_series(nmod_poly_t g, const nmod_poly_t h, slong n); + +void _nmod_poly_sqrt_series(mp_ptr g, mp_srcptr h, slong n, nmod_t mod); + +void nmod_poly_sqrt_series(nmod_poly_t g, const nmod_poly_t h, slong n); + +int _nmod_poly_sqrt(mp_ptr s, mp_srcptr p, slong len, nmod_t mod); + +int nmod_poly_sqrt(nmod_poly_t b, const nmod_poly_t a); + +/* Transcendental functions **************************************************/ + +void _nmod_poly_atan_series(mp_ptr g, mp_srcptr h, slong n, nmod_t mod); +void nmod_poly_atan_series(nmod_poly_t g, const nmod_poly_t h, slong n); + +void _nmod_poly_tan_series(mp_ptr g, mp_srcptr h, slong n, nmod_t mod); +void nmod_poly_tan_series(nmod_poly_t g, const nmod_poly_t h, slong n); + +void _nmod_poly_asin_series(mp_ptr g, mp_srcptr h, slong n, nmod_t mod); +void nmod_poly_asin_series(nmod_poly_t g, const nmod_poly_t h, slong n); + +void _nmod_poly_sin_series(mp_ptr g, mp_srcptr h, slong n, nmod_t mod); +void nmod_poly_sin_series(nmod_poly_t g, const nmod_poly_t h, slong n); + +void _nmod_poly_cos_series(mp_ptr g, mp_srcptr h, slong n, nmod_t mod); +void nmod_poly_cos_series(nmod_poly_t g, const nmod_poly_t h, slong n); + +void _nmod_poly_asinh_series(mp_ptr g, mp_srcptr h, slong n, nmod_t mod); +void nmod_poly_asinh_series(nmod_poly_t g, const nmod_poly_t h, slong n); + +void _nmod_poly_atanh_series(mp_ptr g, mp_srcptr h, slong n, nmod_t mod); +void nmod_poly_atanh_series(nmod_poly_t g, const nmod_poly_t h, slong n); + +void _nmod_poly_sinh_series(mp_ptr g, mp_srcptr h, slong n, nmod_t mod); +void nmod_poly_sinh_series(nmod_poly_t g, const nmod_poly_t h, slong n); + +void _nmod_poly_cosh_series(mp_ptr g, mp_srcptr h, slong n, nmod_t mod); +void nmod_poly_cosh_series(nmod_poly_t g, const nmod_poly_t h, slong n); + +void _nmod_poly_tanh_series(mp_ptr g, mp_srcptr h, slong n, nmod_t mod); +void nmod_poly_tanh_series(nmod_poly_t g, const nmod_poly_t h, slong n); + +void _nmod_poly_log_series_monomial_ui(mp_ptr res, mp_limb_t coeff, + ulong power, slong n, nmod_t mod); +void nmod_poly_log_series_monomial_ui(nmod_poly_t res, mp_limb_t coeff, + ulong power, slong n); + +void _nmod_poly_log_series(mp_ptr res, mp_srcptr f, slong n, nmod_t mod); +void nmod_poly_log_series(nmod_poly_t res, const nmod_poly_t f, slong n); + +void _nmod_poly_exp_series_monomial_ui(mp_ptr res, mp_limb_t coeff, + ulong power, slong n, nmod_t mod); +void nmod_poly_exp_series_monomial_ui(nmod_poly_t res, mp_limb_t coeff, + ulong power, slong n); + + +void +_nmod_poly_exp_series_basecase(mp_ptr f, mp_srcptr h, + slong hlen, slong n, nmod_t mod); +void nmod_poly_exp_series_basecase(nmod_poly_t f, const nmod_poly_t h, slong n); + +void _nmod_poly_exp_expinv_series(mp_ptr f, mp_ptr g, mp_srcptr h, slong n, nmod_t mod); + +void _nmod_poly_exp_series(mp_ptr f, mp_srcptr h, slong n, nmod_t mod); +void nmod_poly_exp_series(nmod_poly_t f, const nmod_poly_t h, slong n); + +/* Products *****************************************************************/ + +void +nmod_poly_product_roots_nmod_vec(nmod_poly_t poly, mp_srcptr xs, slong n); + +void +_nmod_poly_product_roots_nmod_vec(mp_ptr poly, + mp_srcptr xs, slong n, nmod_t mod); + +/* Inflation and deflation ***************************************************/ + +ulong nmod_poly_deflation(const nmod_poly_t input); + +void nmod_poly_deflate(nmod_poly_t result, const nmod_poly_t input, + ulong deflation); + +void nmod_poly_inflate(nmod_poly_t result, const nmod_poly_t input, + ulong inflation); + +#ifdef __cplusplus + } +#endif + +#include "nmod_poly_factor.h" + +#endif diff --git a/external/flint-2.4.3/nmod_poly/KS2_pack.c b/external/flint-2.4.3/nmod_poly/KS2_pack.c new file mode 100644 index 0000000..f79d819 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/KS2_pack.c @@ -0,0 +1,163 @@ +/*============================================================================= + +Copyright (C) 2007, 2008 David Harvey (zn_poly) +Copyright (C) 2013 William Hart + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +/* + Same as _nmod_poly_KS2_pack(), but requires b <= FLINT_BITS. +*/ +void +_nmod_poly_KS2_pack1(mp_ptr res, mp_srcptr op, slong n, slong s, + ulong b, ulong k, slong r) +{ + /* where to write the next limb */ + mp_ptr dest = res; + + /* limb currently being filled */ + mp_limb_t buf; + + /* number of bits used in buf; always in [0, FLINT_BITS) */ + ulong buf_b, buf_b_old; + + /* write leading zero-padding */ + while (k >= FLINT_BITS) + { + *dest++ = 0; + k -= FLINT_BITS; + } + + buf = 0; + + buf_b = k; + + for (; n > 0; n--, op += s) + { + /* put low bits of current input into buffer */ + buf += *op << buf_b; + buf_b_old = buf_b; + buf_b += b; + if (buf_b >= FLINT_BITS) + { + /* buffer is full; flush it */ + *dest++ = buf; + buf_b -= FLINT_BITS; + /* put remaining bits of current input into buffer */ + buf = buf_b_old ? (*op >> (FLINT_BITS - buf_b_old)) : 0; + } + } + + /* write last limb if it's non-empty */ + if (buf_b) + *dest++ = buf; + + /* zero-pad up to requested length */ + if (r) + { + slong written = dest - res; + for (; written < r; written++) + *dest++ = 0; + } +} + +void +_nmod_poly_KS2_pack(mp_ptr res, mp_srcptr op, slong n, slong s, + ulong b, ulong k, slong r) +{ + /* where to write the next limb */ + mp_ptr dest = res; + + /* limb currently being filled */ + mp_limb_t buf; + + /* number of bits used in buf; always in [0, FLINT_BITS) */ + ulong buf_b, buf_b_old; + + if (b <= FLINT_BITS) + { + /* use specialised version if b is small enough */ + _nmod_poly_KS2_pack1(res, op, n, s, b, k, r); + return; + } + + /* write leading zero-padding */ + while (k >= FLINT_BITS) + { + *dest++ = 0; + k -= FLINT_BITS; + } + + buf = 0; + + buf_b = k; + + for (; n > 0; n--, op += s) + { + /* put low bits of current input into buffer */ + buf += *op << buf_b; + buf_b_old = buf_b; + buf_b += b; + if (buf_b >= FLINT_BITS) + { + /* buffer is full; flush it */ + *dest++ = buf; + buf_b -= FLINT_BITS; + /* put remaining bits of current input into buffer */ + buf = buf_b_old ? (*op >> (FLINT_BITS - buf_b_old)) : 0; + + /* write as many extra zeroes as necessary */ + if (buf_b >= FLINT_BITS) + { + *dest++ = buf; + buf = 0; + buf_b -= FLINT_BITS; + if (buf_b >= FLINT_BITS) + { + *dest++ = 0; + buf_b -= FLINT_BITS; + } + } + } + } + + /* write last limb if it's non-empty */ + if (buf_b) + *dest++ = buf; + + /* zero-pad up to requested length */ + if (r) + { + slong written = dest - res; + for (; written < r; written++) + *dest++ = 0; + } +} \ No newline at end of file diff --git a/external/flint-2.4.3/nmod_poly/KS2_reduce.c b/external/flint-2.4.3/nmod_poly/KS2_reduce.c new file mode 100644 index 0000000..746e2ba --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/KS2_reduce.c @@ -0,0 +1,248 @@ +/*============================================================================= + +Copyright (C) 2007, 2008 David Harvey (zn_poly) +Copyright (C) 2013 William Hart + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +void +_nmod_poly_KS2_reduce(mp_ptr res, slong s, mp_srcptr op, slong n, ulong w, + nmod_t mod) +{ + if (w == 1) + { + for (; n; n--, res += s, op++) + NMOD_RED(*res, *op, mod); + } + else if (w == 2) + { + for (; n; n--, res += s, op += 2) + NMOD2_RED2(*res, op[1], op[0], mod); + } + else /* w == 3 */ + { + for (; n; n--, res += s, op += 3) + NMOD_RED3(*res, op[2], op[1], op[0], mod); + } +} + +/* + Same as _nmod_poly_KS2_recover_reduce(), but requires 0 < 2 * b <= FLINT_BITS +*/ +void +_nmod_poly_KS2_recover_reduce1(mp_ptr res, slong s, mp_srcptr op1, + mp_srcptr op2, slong n, ulong b, + nmod_t mod) +{ + ulong mask = (UWORD(1) << b) - 1; + + /* (x0, x1) and (y0, y1) are two-digit windows into X and Y. */ + ulong x1, x0 = *op1++; + ulong y0, y1, borrow; + + op2 += n; + y1 = *op2--; + + borrow = 0; + + /* plain reduction version */ + for (; n; n--) + { + y0 = *op2--; + x1 = *op1++; + if (y0 < x0) + y1--; + NMOD_RED(*res, x0 + (y1 << b), mod); + res += s; + y1 += borrow; + borrow = (x1 < y1); + x1 -= y1; + y1 = (y0 - x0) & mask; + x0 = x1 & mask; + } +} + + +/* + Same as _nmod_poly_KS2_recover_reduce(), but requires + FLINT_BITS < 2 * b < 2*FLINT_BITS +*/ +void +_nmod_poly_KS2_recover_reduce2(mp_ptr res, slong s, mp_srcptr op1, + mp_srcptr op2, slong n, ulong b, + nmod_t mod) +{ + /* + The main loop is the same as in _nmod_poly_KS2_recover_reduce1(), but the + modular reduction step needs to handle two input words. + */ + ulong mask = (UWORD(1) << b) - 1; + + ulong x1, x0 = *op1++; + ulong y0, y1, borrow, b2; + + op2 += n; + y1 = *op2--; + + borrow = 0; + + b2 = FLINT_BITS - b; + + /* plain reduction version */ + for (; n; n--) + { + y0 = *op2--; + x1 = *op1++; + if (y0 < x0) + y1--; + NMOD2_RED2(*res, y1 >> b2, x0 + (y1 << b), mod); + res += s; + y1 += borrow; + borrow = (x1 < y1); + x1 -= y1; + y1 = (y0 - x0) & mask; + x0 = x1 & mask; + } +} + + +/* + Same as _nmod_poly_KS2_recover_reduce(), but requires b == FLINT_BITS +*/ +void +_nmod_poly_KS2_recover_reduce2b(mp_ptr res, slong s, mp_srcptr op1, + mp_srcptr op2, slong n, ulong b, + nmod_t mod) +{ + /* + Basically the same code as _nmod_poly_KS2_recover_reduce2(), specialised + for b == FLINT_BITS. + */ + ulong x1, x0 = *op1++; + ulong y0, y1, borrow; + + op2 += n; + y1 = *op2--; + + borrow = 0; + + /* plain reduction version */ + for (; n; n--) + { + y0 = *op2--; + x1 = *op1++; + if (y0 < x0) + y1--; + NMOD2_RED2(*res, y1, x0, mod); + res += s; + y1 += borrow; + borrow = (x1 < y1); + x1 -= y1; + y1 = y0 - x0; + x0 = x1; + } +} + +/* + Same as _nmod_poly_KS2_recover_reduce(), but requires + 2 * FLINT_BITS < 2 * b <= 3 * FLINT_BITS. +*/ +void +_nmod_poly_KS2_recover_reduce3(mp_ptr res, slong s, mp_srcptr op1, + mp_srcptr op2, slong n, ulong b, + nmod_t mod) +{ + /* + The main loop is the same as in zn_array_recover_reduce1(), but needs + to operate on double-word quantities everywhere, i.e. we simulate + double-word registers. The suffixes L and H stand for low and high words + of each. + */ + + ulong maskH = (UWORD(1) << (b - FLINT_BITS)) - 1; + + ulong x1L, x0L = *op1++; + ulong x1H, x0H = *op1++; + ulong y0H, y1H, y0L, y1L; + ulong borrow, b1, b2; + + op2 += 2 * n + 1; + y1H = *op2--; + y1L = *op2--; + + borrow = 0; + + b1 = b - FLINT_BITS; + b2 = 2 * FLINT_BITS - b; + + /* plain reduction version */ + for (; n; n--) + { + y0H = *op2--; + y0L = *op2--; + x1L = *op1++; + x1H = *op1++; + if ((y0H < x0H) || (y0H == x0H && y0L < x0L)) + y1H -= (y1L-- == 0); + + NMOD_RED3(*res, (y1H << b1) + (y1L >> b2), + (y1L << b1) + x0H, x0L, mod); + res += s; + + if (borrow) + y1H += (++y1L == 0); + borrow = ((x1H < y1H) || (x1H == y1H && x1L < y1L)); + sub_ddmmss(x1H, x1L, x1H, x1L, y1H, y1L); + sub_ddmmss(y1H, y1L, y0H, y0L, x0H, x0L); + y1H &= maskH; + x0L = x1L; + x0H = x1H & maskH; + } +} + + +/* + Dispatches to one of the above routines depending on b. +*/ +void +_nmod_poly_KS2_recover_reduce(mp_ptr res, slong s, mp_srcptr op1, + mp_srcptr op2, slong n, ulong b, + nmod_t mod) +{ + if (2 * b <= FLINT_BITS) + _nmod_poly_KS2_recover_reduce1(res, s, op1, op2, n, b, mod); + else if (b < FLINT_BITS) + _nmod_poly_KS2_recover_reduce2(res, s, op1, op2, n, b, mod); + else if (b == FLINT_BITS) + _nmod_poly_KS2_recover_reduce2b(res, s, op1, op2, n, b, mod); + else + _nmod_poly_KS2_recover_reduce3(res, s, op1, op2, n, b, mod); +} diff --git a/external/flint-2.4.3/nmod_poly/KS2_unpack.c b/external/flint-2.4.3/nmod_poly/KS2_unpack.c new file mode 100644 index 0000000..44d7882 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/KS2_unpack.c @@ -0,0 +1,284 @@ +/*============================================================================= + +Copyright (C) 2007, 2008 David Harvey (zn_poly) +Copyright (C) 2013 William Hart + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +/* + Same as _nmod_poly_KS2_unpack(), but requires b <= FLINT_BITS + (i.e. writes one word per coefficient) +*/ +void +_nmod_poly_KS2_unpack1(mp_ptr res, mp_srcptr op, slong n, ulong b, + ulong k) +{ + /* limb we're currently extracting bits from */ + mp_limb_t buf = 0; + /* number of bits currently in buf; always in [0, FLINT_BITS) */ + ulong buf_b = 0; + + /* skip over k leading bits */ + while (k >= FLINT_BITS) + { + k -= FLINT_BITS; + op++; + } + + if (k) + { + buf = *op++; + buf >>= k; + buf_b = FLINT_BITS - k; + } + + if (b == FLINT_BITS) + { + /* various special cases */ + if (buf_b) + { + for (; n > 0; n--) + { + /* we need bits from both sides of a limb boundary */ + ulong temp = buf; + buf = *op++; + *res++ = temp + (buf << buf_b); + buf >>= (FLINT_BITS - buf_b); + } + } + else + { + for (; n > 0; n--) + *res++ = *op++; + } + } + else + { + ulong mask = (UWORD(1) << b) - 1; + + for (; n > 0; n--) + { + if (b <= buf_b) + { + /* buf contains all the bits we need */ + *res++ = buf & mask; + buf >>= b; + buf_b -= b; + } + else + { + /* we need bits from both sides of a limb boundary */ + ulong temp = buf; + buf = *op++; + *res++ = temp + ((buf << buf_b) & mask); + buf >>= (b - buf_b); + buf_b = FLINT_BITS - (b - buf_b); + } + } + } +} + + + +/* + Same as _nmod_poly_KS2_unpack(), but requires FLINT_BITS < b <= 2 * FLINT_BITS + (i.e. writes two words per coefficient) +*/ +void +_nmod_poly_KS2_unpack2(mp_ptr res, mp_srcptr op, slong n, ulong b, + ulong k) +{ + /* limb we're currently extracting bits from */ + mp_limb_t buf = 0; + /* number of bits currently in buf; always in [0, FLINT_BITS) */ + ulong buf_b = 0; + + /* skip over k leading bits */ + while (k >= FLINT_BITS) + { + k -= FLINT_BITS; + op++; + } + + if (k) + { + buf = *op++; + buf >>= k; + buf_b = FLINT_BITS - k; + } + + if (b == 2 * FLINT_BITS) + { + n *= 2; + + /* various special cases */ + if (buf_b) + { + for (; n > 0; n--) + { + /* we need bits from both sides of a limb boundary */ + ulong temp = buf; + buf = *op++; + *res++ = temp + (buf << buf_b); + buf >>= (FLINT_BITS - buf_b); + } + } + else + { + for (; n > 0; n--) + *res++ = *op++; + } + } + else + { + ulong mask; + b -= FLINT_BITS; + mask = (UWORD(1) << b) - 1; + + for (; n > 0; n--) + { + /* shunt one whole limb through first */ + if (buf_b) + { + ulong temp = buf; + buf = *op++; + *res++ = temp + (buf << buf_b); + buf >>= (FLINT_BITS - buf_b); + } + else + *res++ = *op++; + + /* now handle the fractional limb */ + if (b <= buf_b) + { + /* buf contains all the bits we need */ + *res++ = buf & mask; + buf >>= b; + buf_b -= b; + } + else + { + /* we need bits from both sides of a limb boundary */ + ulong temp = buf; + buf = *op++; + *res++ = temp + ((buf << buf_b) & mask); + buf >>= (b - buf_b); + buf_b = FLINT_BITS - (b - buf_b); + } + } + } +} + + + +/* + Same as _nmod_poly_KS2_unpack(), but requires 2 * FLINT_BITS < b < 3 * FLINT_BITS + (i.e. writes three words per coefficient) +*/ +void +_nmod_poly_KS2_unpack3(mp_ptr res, mp_srcptr op, slong n, ulong b, + ulong k) +{ + /* limb we're currently extracting bits from */ + mp_limb_t buf = 0; + /* number of bits currently in buf; always in [0, FLINT_BITS) */ + ulong buf_b = 0, mask; + + /* skip over k leading bits */ + while (k >= FLINT_BITS) + { + k -= FLINT_BITS; + op++; + } + + if (k) + { + buf = *op++; + buf >>= k; + buf_b = FLINT_BITS - k; + } + + b -= 2 * FLINT_BITS; + mask = (UWORD(1) << b) - 1; + + for (; n > 0; n--) + { + /* shunt two whole limbs through first */ + if (buf_b) + { + ulong temp = buf; + buf = *op++; + *res++ = temp + (buf << buf_b); + buf >>= (FLINT_BITS - buf_b); + + temp = buf; + buf = *op++; + *res++ = temp + (buf << buf_b); + buf >>= (FLINT_BITS - buf_b); + } + else + { + *res++ = *op++; + *res++ = *op++; + } + + /* now handle the fractional limb */ + if (b <= buf_b) + { + /* buf contains all the bits we need */ + *res++ = buf & mask; + buf >>= b; + buf_b -= b; + } + else + { + /* we need bits from both sides of a limb boundary */ + ulong temp = buf; + buf = *op++; + *res++ = temp + ((buf << buf_b) & mask); + buf >>= (b - buf_b); + buf_b = FLINT_BITS - (b - buf_b); + } + } +} + + +void +_nmod_poly_KS2_unpack(mp_ptr res, mp_srcptr op, slong n, ulong b, + ulong k) +{ + if (b <= FLINT_BITS) + _nmod_poly_KS2_unpack1 (res, op, n, b, k); + else if (b <= 2 * FLINT_BITS) + _nmod_poly_KS2_unpack2 (res, op, n, b, k); + else /* b < 3 * FLINT_BITS */ + _nmod_poly_KS2_unpack3 (res, op, n, b, k); +} \ No newline at end of file diff --git a/external/flint-2.4.3/nmod_poly/add.c b/external/flint-2.4.3/nmod_poly/add.c new file mode 100644 index 0000000..51888a4 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/add.c @@ -0,0 +1,63 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007, David Howden. + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +void +_nmod_poly_add(mp_ptr res, mp_srcptr poly1, slong len1, mp_srcptr poly2, + slong len2, nmod_t mod) +{ + slong i, min = FLINT_MIN(len1, len2); + + _nmod_vec_add(res, poly1, poly2, min, mod); + + if (poly1 != res) /* copy any remaining coefficients from poly1 */ + for (i = min; i < len1; i++) + res[i] = poly1[i]; + + if (poly2 != res) /* copy any remaining coefficients from poly2 */ + for (i = min; i < len2; i++) + res[i] = poly2[i]; +} + +void +nmod_poly_add(nmod_poly_t res, const nmod_poly_t poly1, + const nmod_poly_t poly2) +{ + slong max = FLINT_MAX(poly1->length, poly2->length); + + nmod_poly_fit_length(res, max); + + _nmod_poly_add(res->coeffs, poly1->coeffs, poly1->length, poly2->coeffs, + poly2->length, poly1->mod); + + res->length = max; + _nmod_poly_normalise(res); /* there may have been cancellation */ +} diff --git a/external/flint-2.4.3/nmod_poly/asin_series.c b/external/flint-2.4.3/nmod_poly/asin_series.c new file mode 100644 index 0000000..b99a8de --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/asin_series.c @@ -0,0 +1,88 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +void +_nmod_poly_asin_series(mp_ptr g, mp_srcptr h, slong n, nmod_t mod) +{ + mp_ptr t, u; + + t = _nmod_vec_init(n); + u = _nmod_vec_init(n); + + /* asin(h(x)) = integral(h'(x)/sqrt(1-h(x)^2)) */ + _nmod_poly_mullow(u, h, n, h, n, n, mod); + _nmod_vec_neg(u, u, n, mod); u[0] = UWORD(1); + _nmod_poly_invsqrt_series(t, u, n, mod); + _nmod_poly_derivative(u, h, n, mod); u[n-1] = UWORD(0); + _nmod_poly_mullow(g, t, n, u, n, n, mod); + _nmod_poly_integral(g, g, n, mod); + + _nmod_vec_clear(t); + _nmod_vec_clear(u); +} + +void +nmod_poly_asin_series(nmod_poly_t g, const nmod_poly_t h, slong n) +{ + mp_ptr h_coeffs; + slong h_len = h->length; + + if (h_len > 0 && h->coeffs[0] != UWORD(0)) + { + flint_printf("Exception (nmod_poly_asin_series). Constant term != 0.\n"); + abort(); + } + + if (h_len == 1 || n < 2) + { + nmod_poly_zero(g); + return; + } + + nmod_poly_fit_length(g, n); + + if (h_len < n) + { + h_coeffs = _nmod_vec_init(n); + flint_mpn_copyi(h_coeffs, h->coeffs, h_len); + flint_mpn_zero(h_coeffs + h_len, n - h_len); + } + else + h_coeffs = h->coeffs; + + _nmod_poly_asin_series(g->coeffs, h_coeffs, n, h->mod); + + if (h_len < n) + _nmod_vec_clear(h_coeffs); + + g->length = n; + _nmod_poly_normalise(g); +} diff --git a/external/flint-2.4.3/nmod_poly/asinh_series.c b/external/flint-2.4.3/nmod_poly/asinh_series.c new file mode 100644 index 0000000..1fbe92b --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/asinh_series.c @@ -0,0 +1,87 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +void +_nmod_poly_asinh_series(mp_ptr g, mp_srcptr h, slong n, nmod_t mod) +{ + mp_ptr t, u; + + t = _nmod_vec_init(n); + u = _nmod_vec_init(n); + + /* asinh(h(x)) = integral(h'(x)/sqrt(1+h(x)^2)) */ + _nmod_poly_mullow(u, h, n, h, n, n, mod); u[0] = UWORD(1); + _nmod_poly_invsqrt_series(t, u, n, mod); + _nmod_poly_derivative(u, h, n, mod); u[n-1] = UWORD(0); + _nmod_poly_mullow(g, t, n, u, n, n, mod); + _nmod_poly_integral(g, g, n, mod); + + _nmod_vec_clear(t); + _nmod_vec_clear(u); +} + +void +nmod_poly_asinh_series(nmod_poly_t g, const nmod_poly_t h, slong n) +{ + mp_ptr h_coeffs; + slong h_len = h->length; + + if (h_len > 0 && h->coeffs[0] != UWORD(0)) + { + flint_printf("Exception (nmod_poly_asinh_series). Constant term != 0.\n"); + abort(); + } + + if (h_len == 1 || n < 2) + { + nmod_poly_zero(g); + return; + } + + nmod_poly_fit_length(g, n); + + if (h_len < n) + { + h_coeffs = _nmod_vec_init(n); + flint_mpn_copyi(h_coeffs, h->coeffs, h_len); + flint_mpn_zero(h_coeffs + h_len, n - h_len); + } + else + h_coeffs = h->coeffs; + + _nmod_poly_asinh_series(g->coeffs, h_coeffs, n, h->mod); + + if (h_len < n) + _nmod_vec_clear(h_coeffs); + + g->length = n; + _nmod_poly_normalise(g); +} diff --git a/external/flint-2.4.3/nmod_poly/atan_series.c b/external/flint-2.4.3/nmod_poly/atan_series.c new file mode 100644 index 0000000..66d4d23 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/atan_series.c @@ -0,0 +1,86 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +void +_nmod_poly_atan_series(mp_ptr g, mp_srcptr h, slong n, nmod_t mod) +{ + mp_ptr t, u; + + t = _nmod_vec_init(n); + u = _nmod_vec_init(n); + + /* atan(h(x)) = integral(h'(x)/(1+h(x)^2)) */ + _nmod_poly_mullow(u, h, n, h, n, n, mod); u[0] = UWORD(1); + _nmod_poly_derivative(t, h, n, mod); t[n-1] = UWORD(0); + _nmod_poly_div_series(g, t, u, n, mod); + _nmod_poly_integral(g, g, n, mod); + + _nmod_vec_clear(t); + _nmod_vec_clear(u); +} + +void +nmod_poly_atan_series(nmod_poly_t g, const nmod_poly_t h, slong n) +{ + mp_ptr h_coeffs; + slong h_len = h->length; + + if (h_len > 0 && h->coeffs[0] != UWORD(0)) + { + flint_printf("Exception (nmod_poly_atan_series): Constant term != 0.\n"); + abort(); + } + + if (h_len == 1 || n < 2) + { + nmod_poly_zero(g); + return; + } + + nmod_poly_fit_length(g, n); + + if (h_len < n) + { + h_coeffs = _nmod_vec_init(n); + flint_mpn_copyi(h_coeffs, h->coeffs, h_len); + flint_mpn_zero(h_coeffs + h_len, n - h_len); + } + else + h_coeffs = h->coeffs; + + _nmod_poly_atan_series(g->coeffs, h_coeffs, n, h->mod); + + if (h_len < n) + _nmod_vec_clear(h_coeffs); + + g->length = n; + _nmod_poly_normalise(g); +} diff --git a/external/flint-2.4.3/nmod_poly/atanh_series.c b/external/flint-2.4.3/nmod_poly/atanh_series.c new file mode 100644 index 0000000..87c5c5c --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/atanh_series.c @@ -0,0 +1,87 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +void +_nmod_poly_atanh_series(mp_ptr g, mp_srcptr h, slong n, nmod_t mod) +{ + mp_ptr t, u; + + t = _nmod_vec_init(n); + u = _nmod_vec_init(n); + + /* atanh(h(x)) = integral(h'(x)/(1-h(x)^2)) */ + _nmod_poly_mullow(u, h, n, h, n, n, mod); + _nmod_vec_neg(u, u, n, mod); u[0] = UWORD(1); + _nmod_poly_derivative(t, h, n, mod); t[n-1] = UWORD(0); + _nmod_poly_div_series(g, t, u, n, mod); + _nmod_poly_integral(g, g, n, mod); + + _nmod_vec_clear(t); + _nmod_vec_clear(u); +} + +void +nmod_poly_atanh_series(nmod_poly_t g, const nmod_poly_t h, slong n) +{ + mp_ptr h_coeffs; + slong h_len = h->length; + + if (h_len > 0 && h->coeffs[0] != UWORD(0)) + { + flint_printf("Exception (nmod_poly_atanh_series): Constant term != 0.\n"); + abort(); + } + + if (h_len == 1 || n < 2) + { + nmod_poly_zero(g); + return; + } + + nmod_poly_fit_length(g, n); + + if (h_len < n) + { + h_coeffs = _nmod_vec_init(n); + flint_mpn_copyi(h_coeffs, h->coeffs, h_len); + flint_mpn_zero(h_coeffs + h_len, n - h_len); + } + else + h_coeffs = h->coeffs; + + _nmod_poly_atanh_series(g->coeffs, h_coeffs, n, h->mod); + + if (h_len < n) + _nmod_vec_clear(h_coeffs); + + g->length = n; + _nmod_poly_normalise(g); +} diff --git a/external/flint-2.4.3/nmod_poly/bit_pack.c b/external/flint-2.4.3/nmod_poly/bit_pack.c new file mode 100644 index 0000000..7ffab8f --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/bit_pack.c @@ -0,0 +1,173 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "fmpz.h" + +/* Assumes length > 0, bits > 0. */ +void +_nmod_poly_bit_pack(mp_ptr res, mp_srcptr poly, slong len, mp_bitcnt_t bits) +{ + slong i; + ulong current_bit = 0, current_limb = 0; + ulong total_limbs = (len * bits - 1) / FLINT_BITS + 1; + mp_limb_t temp_lower, temp_upper; + + res[0] = WORD(0); + + if (bits < FLINT_BITS) + { + ulong boundary_limit_bit = FLINT_BITS - bits; + + for (i = 0; i < len; i++) + { + if (current_bit > boundary_limit_bit) + { + /* the coefficient will be added accross a limb boundary */ + temp_lower = (poly[i] << current_bit); + temp_upper = (poly[i] >> (FLINT_BITS - current_bit)); + + res[current_limb] |= temp_lower; + + current_limb++; + res[current_limb] = temp_upper; + + current_bit += bits - FLINT_BITS; + } + else + { + /* the coefficient will fit in the current limb */ + temp_lower = poly[i] << current_bit; + res[current_limb] |= temp_lower; + + current_bit += bits; + + if (current_bit == FLINT_BITS) + { + current_limb++; + if (current_limb < total_limbs) + res[current_limb] = WORD(0); + current_bit = 0; + } + } + } + } + else if (bits == FLINT_BITS) + { + for (i = 0; i < len; i++) + res[i] = poly[i]; + } + else if (bits == 2 * FLINT_BITS) + { + for (i = 0; i < len; i++) + { + res[current_limb++] = poly[i]; + res[current_limb++] = WORD(0); + } + } + else if (bits < 2 * FLINT_BITS) + { + for (i = 0; i < len; i++) + { + /* the coefficient will be added accross a limb boundary */ + temp_lower = poly[i] << current_bit; + temp_upper = r_shift(poly[i], FLINT_BITS - current_bit); + + res[current_limb++] |= temp_lower; + res[current_limb] = temp_upper; + + current_bit += bits - FLINT_BITS; + + if (current_bit >= FLINT_BITS) + { + current_bit -= FLINT_BITS; + current_limb++; + if (current_limb < total_limbs) + res[current_limb] = WORD(0); + } + } + } + else /* 2*FLINT_BITS < bits < 3*FLINT_BITS */ + { + for (i = 0; i < len; i++) + { + temp_lower = poly[i] << current_bit; + temp_upper = r_shift(poly[i], FLINT_BITS - current_bit); + + res[current_limb++] |= temp_lower; + res[current_limb++] = temp_upper; + + if (current_limb < total_limbs) + res[current_limb] = WORD(0); + current_bit += bits - 2 * FLINT_BITS; + + if (current_bit >= FLINT_BITS) + { + current_bit -= FLINT_BITS; + current_limb++; + if (current_limb < total_limbs) + res[current_limb] = WORD(0); + } + } + } +} + +void +nmod_poly_bit_pack(fmpz_t f, const nmod_poly_t poly, + mp_bitcnt_t bit_size) +{ + slong len, limbs; + __mpz_struct * mpz; + slong i; + + len = nmod_poly_length(poly); + + if (len == 0 || bit_size == 0) + { + fmpz_zero(f); + return; + } + + mpz = _fmpz_promote(f); + mpz_realloc2(mpz, len * bit_size); + + limbs = (len * bit_size - 1) / FLINT_BITS + 1; + + _nmod_poly_bit_pack(mpz->_mp_d, poly->coeffs, len, bit_size); + + for (i = limbs - 1; i >= 0; i--) + { + if (mpz->_mp_d[i] != 0) + break; + } + + mpz->_mp_size = i + 1; + _fmpz_demote_val(f); +} diff --git a/external/flint-2.4.3/nmod_poly/bit_unpack.c b/external/flint-2.4.3/nmod_poly/bit_unpack.c new file mode 100644 index 0000000..80b43b0 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/bit_unpack.c @@ -0,0 +1,246 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "fmpz.h" + +/* Assumes len > 0, bits > 0. */ +void +_nmod_poly_bit_unpack(mp_ptr res, slong len, mp_srcptr mpn, mp_bitcnt_t bits, + nmod_t mod) +{ + slong i; + ulong current_bit = 0, current_limb = 0; + mp_limb_t temp_lower, temp_upper, temp_upper2; + + if (bits < FLINT_BITS) + { + ulong boundary_limit_bit = FLINT_BITS - bits; + + mp_limb_t mask = (WORD(1) << bits) - WORD(1); + + for (i = 0; i < len; i++) + { + if (current_bit > boundary_limit_bit) + { + temp_lower = mpn[current_limb++] >> current_bit; + temp_upper = mpn[current_limb] << (FLINT_BITS - current_bit); + + temp_upper |= temp_lower; + temp_upper &= mask; + + NMOD_RED(res[i], temp_upper, mod); + + current_bit += bits - FLINT_BITS; + } + else + { + /* the coeff will fit in the current limb */ + temp_upper = (mpn[current_limb] >> current_bit) & mask; + + NMOD_RED(res[i], temp_upper, mod); + + current_bit += bits; + + if (current_bit == FLINT_BITS) + { + current_bit = 0; + current_limb++; + } + } + } + } + else if (bits == FLINT_BITS) + { + for (i = 0; i < len; i++) + NMOD_RED(res[i], mpn[i], mod); + } + else if (bits == 2 * FLINT_BITS) + { + for (i = 0; i < len; i++) + { + NMOD2_RED2(res[i], mpn[current_limb + 1], mpn[current_limb], mod); + current_limb += 2; + } + } + else if (bits < 2 * FLINT_BITS) /* FLINT_BITS < bits < 2*FLINT_BITS */ + { + ulong double_boundary_limit_bit = 2 * FLINT_BITS - bits; + + mp_limb_t mask = (WORD(1) << (bits - FLINT_BITS)) - WORD(1); + + for (i = 0; i < len; i++) + { + if (current_bit == 0) + { + temp_lower = mpn[current_limb++]; + temp_upper = mpn[current_limb] & mask; + + NMOD2_RED2(res[i], temp_upper, temp_lower, mod); + + current_bit = bits - FLINT_BITS; + } + else if (current_bit > double_boundary_limit_bit) + { + /* the coeff will be across two limb boundaries */ + temp_lower = mpn[current_limb++] >> current_bit; + temp_lower |= + (mpn[current_limb] << (FLINT_BITS - current_bit)); + + temp_upper = mpn[current_limb++] >> current_bit; + temp_upper |= + (mpn[current_limb] << (FLINT_BITS - current_bit)); + temp_upper &= mask; + + NMOD2_RED2(res[i], temp_upper, temp_lower, mod); + + current_bit += bits - 2 * FLINT_BITS; + } + else + { + /* the coeff will be across one limb boundary */ + temp_lower = + (mpn[current_limb] >> current_bit) | (mpn[current_limb + 1] + << (FLINT_BITS - + current_bit)); + current_limb++; + + temp_upper = mpn[current_limb] >> current_bit; + temp_upper &= mask; + + NMOD2_RED2(res[i], temp_upper, temp_lower, mod); + + current_bit += bits - FLINT_BITS; + if (current_bit == FLINT_BITS) + { + current_bit = 0; + current_limb++; + } + } + } + } + else /* 2*FLINT_BITS < bits < 3*FLINT_BITS */ + { + ulong double_boundary_limit_bit = 3 * FLINT_BITS - bits; + + mp_limb_t mask = (WORD(1) << (bits - 2 * FLINT_BITS)) - WORD(1); + + for (i = 0; i < len; i++) + { + if (current_bit == 0) + { + temp_lower = mpn[current_limb++]; + temp_upper = mpn[current_limb++]; + temp_upper2 = mpn[current_limb] & mask; + + NMOD_RED3(res[i], temp_upper2, temp_upper, temp_lower, mod); + + current_bit = bits - 2 * FLINT_BITS; + } + else if (current_bit <= double_boundary_limit_bit) + { + /* the coeff will be across two limb boundaries */ + temp_lower = mpn[current_limb++] >> current_bit; + temp_lower |= + (mpn[current_limb] << (FLINT_BITS - current_bit)); + + temp_upper = mpn[current_limb++] >> current_bit; + temp_upper |= + (mpn[current_limb] << (FLINT_BITS - current_bit)); + + temp_upper2 = mpn[current_limb] >> current_bit; + temp_upper2 &= mask; + + NMOD_RED3(res[i], temp_upper2, temp_upper, temp_lower, mod); + + current_bit += bits - 2 * FLINT_BITS; + if (current_bit == FLINT_BITS) + { + current_bit = 0; + current_limb++; + } + } + else + { + /* the coeff will be across three limb boundaries */ + temp_lower = mpn[current_limb++] >> current_bit; + temp_lower |= + (mpn[current_limb] << (FLINT_BITS - current_bit)); + + temp_upper = mpn[current_limb++] >> current_bit; + temp_upper |= + (mpn[current_limb] << (FLINT_BITS - current_bit)); + + temp_upper2 = mpn[current_limb++] >> current_bit; + temp_upper2 |= + (mpn[current_limb] << (FLINT_BITS - current_bit)); + + temp_upper2 &= mask; + + NMOD_RED3(res[i], temp_upper2, temp_upper, temp_lower, mod); + + current_bit += bits - 3 * FLINT_BITS; + } + } + } +} + +void +nmod_poly_bit_unpack(nmod_poly_t poly, const fmpz_t f, mp_bitcnt_t bit_size) +{ + slong len; + mpz_t tmp; + + if (fmpz_sgn(f) < 0) + { + flint_printf("Exception (nmod_poly_bit_unpack). f < 0.\n"); + abort(); + } + + if (bit_size == 0 || fmpz_is_zero(f)) + { + nmod_poly_zero(poly); + return; + } + + len = (fmpz_bits(f) + bit_size - 1) / bit_size; + + mpz_init2(tmp, bit_size*len); + flint_mpn_zero(tmp->_mp_d, tmp->_mp_alloc); + fmpz_get_mpz(tmp, f); + + nmod_poly_fit_length(poly, len); + + _nmod_poly_bit_unpack(poly->coeffs, len, tmp->_mp_d, bit_size, poly->mod); + poly->length = len; + _nmod_poly_normalise(poly); + + mpz_clear(tmp); +} diff --git a/external/flint-2.4.3/nmod_poly/clear.c b/external/flint-2.4.3/nmod_poly/clear.c new file mode 100644 index 0000000..765b4af --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/clear.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007, David Howden. + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_poly.h" + +void +nmod_poly_clear(nmod_poly_t poly) +{ + if (poly->coeffs) + flint_free(poly->coeffs); +} diff --git a/external/flint-2.4.3/nmod_poly/compose.c b/external/flint-2.4.3/nmod_poly/compose.c new file mode 100644 index 0000000..2da8de4 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/compose.c @@ -0,0 +1,82 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "nmod_poly.h" + +void +_nmod_poly_compose(mp_ptr res, mp_srcptr poly1, slong len1, + mp_srcptr poly2, slong len2, nmod_t mod) +{ + if (len1 == 1) + res[0] = poly1[0]; + else if (len2 == 1) + res[0] = _nmod_poly_evaluate_nmod(poly1, len1, poly2[0], mod); + else if (len1 <= 7) + _nmod_poly_compose_horner(res, poly1, len1, poly2, len2, mod); + else + _nmod_poly_compose_divconquer(res, poly1, len1, poly2, len2, mod); +} + +void nmod_poly_compose(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_poly_t poly2) +{ + const slong len1 = poly1->length; + const slong len2 = poly2->length; + + if (len1 == 0) + { + nmod_poly_zero(res); + } + else if (len1 == 1 || len2 == 0) + { + nmod_poly_fit_length(res, 1); + res->coeffs[0] = poly1->coeffs[0]; + res->length = (res->coeffs[0] != 0); + } + else + { + const slong lenr = (len1 - 1) * (len2 - 1) + 1; + + if (res != poly1 && res != poly2) + { + nmod_poly_fit_length(res, lenr); + _nmod_poly_compose_horner(res->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2, poly1->mod); + } + else + { + nmod_poly_t t; + nmod_poly_init2(t, poly1->mod.n, lenr); + _nmod_poly_compose_horner(t->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2, poly1->mod); + nmod_poly_swap(res, t); + nmod_poly_clear(t); + } + + res->length = lenr; + _nmod_poly_normalise(res); + } +} diff --git a/external/flint-2.4.3/nmod_poly/compose_divconquer.c b/external/flint-2.4.3/nmod_poly/compose_divconquer.c new file mode 100644 index 0000000..e90e5b0 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/compose_divconquer.c @@ -0,0 +1,258 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +/* + Assumptions. + + Suppose that $len1 \geq 3$ and $len2 \geq 2$. + + + Definitions. + + Define a sequence $(n_i)$ by $n_1 = \ceil{len1 / 2}$, + $n_2 = \ceil{n_1 / 2}$, etc. all the way to + $n_K = \ceil{n_{K-1} / 2} = 2$. Thus, $K = \ceil{\log_2 len1} - 1$. + Note that we can write $n_i = \ceil{len1 / 2^i}$. + + + Rough description (of the allocation process, or the algorithm). + + Step 1. + For $0 \leq i < n_1$, set h[i] to something of length at most len2. + Set pow to $poly2^2$. + + Step n. + For $0 \leq i < n_n$, set h[i] to something of length at most the length + of $poly2^{2^n - 1}$. + Set pow to $poly^{2^n}$. + + Step K. + For $0 \leq i < n_K$, set h[i] to something of length at most the length + of $poly2^{2^K - 1}$. + Set pow to $poly^{2^K}$. + + + Analysis of the space requirements. + + Let $S$ be the over all space we need, measured in number of coefficients. + Then + \begin{align*} + S & = 2 \times \bigl[ (2^K - 1) (len2 - 1) + 1 \bigr] + + \sum_{i=1}^{K-1} (n_i - n_{i+1}) \bigl[(2^i - 1) (len2 - 1) + 1\bigr] \\ + & = 2 \times \bigl[ (2^K - 1) (len2 - 1) + 1 \bigr] + + (len2 - 1) \sum_{i=1}^{K-1} (n_i - n_{i+1}) (2^i - 1) + n_1 - n_K. + \end{align*} + + If $K = 1$, or equivalently $len1$ is 3 or 4, then $S = 2 \times len2$. + Otherwise, we can bound $n_i - n_{i+1}$ from above as follows. For any + non-negative integer $x$, + \begin{equation*} + \ceil{x / 2^i} - \ceil{x / 2^{i+1}} \leq x/2^i - x/2^{i+1} = x / 2^{i+1}. + \end{equation*} + + Thus, + \begin{align*} + S & \leq 2 \times \bigl[ (2^K - 1) (len2 - 1) + 1 \bigr] + + (len2 - 1) \times len1 \times \sum_{i=1}^{K-1} (1/2 - 1/2^{i+1}) \\ + & \leq 2 \times \bigl[ (2^K - 1) (len2 - 1) + 1 \bigr] + + (len2 - 1) \times len1 \times (K/2 + 1). + \end{align*} + */ + +void +_nmod_poly_compose_divconquer(mp_ptr res, mp_srcptr poly1, slong len1, + mp_srcptr poly2, slong len2, nmod_t mod) +{ + slong i, j, k, n; + slong * hlen, alloc, powlen; + mp_ptr v, * h, pow, temp; + + if (len1 == 1) + { + res[0] = poly1[0]; + return; + } + if (len2 == 1) + { + res[0] = _nmod_poly_evaluate_nmod(poly1, len1, poly2[0], mod); + return; + } + if (len1 == 2) + { + _nmod_poly_compose_horner(res, poly1, len1, poly2, len2, mod); + return; + } + + /* Initialisation */ + + hlen = (slong *) flint_malloc(((len1 + 1) / 2) * sizeof(slong)); + + for (k = 1; (2 << k) < len1; k++) ; + + hlen[0] = hlen[1] = ((1 << k) - 1) * (len2 - 1) + 1; + for (i = k - 1; i > 0; i--) + { + slong 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 = _nmod_vec_init(alloc + 2 * powlen); + h = (mp_ptr *) flint_malloc(((len1 + 1) / 2) * sizeof(mp_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 (poly1[j + 1] != WORD(0)) + { + _nmod_vec_scalar_mul_nmod(h[i], poly2, len2, poly1[j + 1], mod); + h[i][0] = n_addmod(h[i][0], poly1[j], mod.n); + hlen[i] = len2; + } + else if (poly1[j] != WORD(0)) + { + h[i][0] = poly1[j]; + hlen[i] = 1; + } + } + if ((len1 & WORD(1))) + { + if (poly1[j] != WORD(0)) + { + h[i][0] = poly1[j]; + hlen[i] = 1; + } + } + + _nmod_poly_mul(pow, poly2, len2, poly2, len2, mod); + powlen = 2 * len2 - 1; + + for (n = (len1 + 1) / 2; n > 2; n = (n + 1) / 2) + { + if (hlen[1] > 0) + { + slong templen = powlen + hlen[1] - 1; + _nmod_poly_mul(temp, pow, powlen, h[1], hlen[1], mod); + _nmod_poly_add(h[0], temp, templen, h[0], hlen[0], mod); + hlen[0] = FLINT_MAX(hlen[0], templen); + } + + for (i = 1; i < n / 2; i++) + { + if (hlen[2*i + 1] > 0) + { + _nmod_poly_mul(h[i], pow, powlen, h[2*i + 1], hlen[2*i + 1], mod); + hlen[i] = hlen[2*i + 1] + powlen - 1; + } else + hlen[i] = 0; + _nmod_poly_add(h[i], h[i], hlen[i], h[2*i], hlen[2*i], mod); + hlen[i] = FLINT_MAX(hlen[i], hlen[2*i]); + } + if ((n & WORD(1))) + { + flint_mpn_copyi(h[i], h[2*i], hlen[2*i]); + hlen[i] = hlen[2*i]; + } + + _nmod_poly_mul(temp, pow, powlen, pow, powlen, mod); + powlen += powlen - 1; + { + mp_ptr t = pow; + pow = temp; + temp = t; + } + } + + _nmod_poly_mul(res, pow, powlen, h[1], hlen[1], mod); + _nmod_vec_add(res, res, h[0], hlen[0], mod); + + _nmod_vec_clear(v); + flint_free(h); + flint_free(hlen); +} + +void +nmod_poly_compose_divconquer(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_poly_t poly2) +{ + const slong len1 = poly1->length; + const slong len2 = poly2->length; + + if (len1 == 0) + { + nmod_poly_zero(res); + } + else if (len1 == 1 || len2 == 0) + { + nmod_poly_fit_length(res, 1); + res->coeffs[0] = poly1->coeffs[0]; + res->length = (res->coeffs[0] != 0); + } + else + { + const slong lenr = (len1 - 1) * (len2 - 1) + 1; + + if (res != poly1 && res != poly2) + { + nmod_poly_fit_length(res, lenr); + _nmod_poly_compose_horner(res->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2, poly1->mod); + } + else + { + nmod_poly_t t; + nmod_poly_init2(t, poly1->mod.n, lenr); + _nmod_poly_compose_horner(t->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2, poly1->mod); + nmod_poly_swap(res, t); + nmod_poly_clear(t); + } + + res->length = lenr; + _nmod_poly_normalise(res); + } +} diff --git a/external/flint-2.4.3/nmod_poly/compose_horner.c b/external/flint-2.4.3/nmod_poly/compose_horner.c new file mode 100644 index 0000000..165f884 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/compose_horner.c @@ -0,0 +1,122 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 + +******************************************************************************/ + +#include "nmod_poly.h" +#include "ulong_extras.h" + +void +_nmod_poly_compose_horner(mp_ptr res, mp_srcptr poly1, slong len1, + mp_srcptr poly2, slong len2, nmod_t mod) +{ + if (len1 == 1) + { + res[0] = poly1[0]; + } + else if (len2 == 1) + { + res[0] = _nmod_poly_evaluate_nmod(poly1, len1, poly2[0], mod); + } + else if (len1 == 2) + { + _nmod_vec_scalar_mul_nmod(res, poly2, len2, poly1[1], mod); + res[0] = n_addmod(res[0], poly1[0], mod.n); + } + else + { + const slong alloc = (len1 - 1) * (len2 - 1) + 1; + slong i = len1 - 1, lenr = len2; + mp_limb_t *t, *t1, *t2; + t = _nmod_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)". */ + { + _nmod_vec_scalar_mul_nmod(t1, poly2, len2, poly1[i], mod); + i--; + t1[0] = n_addmod(t1[0], poly1[i], mod.n); + } + while (i--) + { + _nmod_poly_mul(t2, t1, lenr, poly2, len2, mod); + lenr += len2 - 1; + MP_PTR_SWAP(t1, t2); + t1[0] = n_addmod(t1[0], poly1[i], mod.n); + } + _nmod_vec_clear(t); + } +} + +void nmod_poly_compose_horner(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_poly_t poly2) +{ + const slong len1 = poly1->length; + const slong len2 = poly2->length; + + if (len1 == 0) + { + nmod_poly_zero(res); + } + else if (len1 == 1 || len2 == 0) + { + nmod_poly_fit_length(res, 1); + res->coeffs[0] = poly1->coeffs[0]; + res->length = (res->coeffs[0] != 0); + } + else + { + const slong lenr = (len1 - 1) * (len2 - 1) + 1; + + if (res != poly1 && res != poly2) + { + nmod_poly_fit_length(res, lenr); + _nmod_poly_compose_horner(res->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2, poly1->mod); + } + else + { + nmod_poly_t t; + nmod_poly_init2(t, poly1->mod.n, lenr); + _nmod_poly_compose_horner(t->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2, poly1->mod); + nmod_poly_swap(res, t); + nmod_poly_clear(t); + } + + res->length = lenr; + _nmod_poly_normalise(res); + } +} diff --git a/external/flint-2.4.3/nmod_poly/compose_mod.c b/external/flint-2.4.3/nmod_poly/compose_mod.c new file mode 100644 index 0000000..8618864 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/compose_mod.c @@ -0,0 +1,102 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +void +_nmod_poly_compose_mod(mp_ptr res, + mp_srcptr f, slong lenf, mp_srcptr g, mp_srcptr h, slong lenh, nmod_t mod) +{ + if (lenh < 8 || lenf >= lenh) + _nmod_poly_compose_mod_horner(res, f, lenf, g, h, lenh, mod); + else + _nmod_poly_compose_mod_brent_kung(res, f, lenf, g, h, lenh, mod); +} + +void +nmod_poly_compose_mod(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_poly_t poly2, + const nmod_poly_t poly3) +{ + slong len1 = poly1->length; + slong len2 = poly2->length; + slong len3 = poly3->length; + slong len = len3 - 1; + + mp_ptr ptr2; + + if (len3 == 0) + { + flint_printf("Exception (nmod_poly_compose_mod). Division by zero.\n"); + abort(); + } + + if (len1 == 0 || len3 == 1) + { + nmod_poly_zero(res); + return; + } + + if (len1 == 1) + { + nmod_poly_set(res, poly1); + return; + } + + if (res == poly3 || res == poly1) + { + nmod_poly_t tmp; + nmod_poly_init_preinv(tmp, res->mod.n, res->mod.ninv); + nmod_poly_compose_mod(tmp, poly1, poly2, poly3); + nmod_poly_swap(tmp, res); + nmod_poly_clear(tmp); + return; + } + + ptr2 = _nmod_vec_init(len); + + if (len2 <= len) + { + flint_mpn_copyi(ptr2, poly2->coeffs, len2); + flint_mpn_zero(ptr2 + len2, len - len2); + } + else + { + _nmod_poly_rem(ptr2, poly2->coeffs, len2, + poly3->coeffs, len3, res->mod); + } + + nmod_poly_fit_length(res, len); + _nmod_poly_compose_mod(res->coeffs, + poly1->coeffs, len1, ptr2, poly3->coeffs, len3, res->mod); + res->length = len; + _nmod_poly_normalise(res); + + _nmod_vec_clear(ptr2); +} diff --git a/external/flint-2.4.3/nmod_poly/compose_mod_brent_kung.c b/external/flint-2.4.3/nmod_poly/compose_mod_brent_kung.c new file mode 100644 index 0000000..82681ab --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/compose_mod_brent_kung.c @@ -0,0 +1,168 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "nmod_mat.h" +#include "ulong_extras.h" + +void +_nmod_poly_compose_mod_brent_kung(mp_ptr res, mp_srcptr poly1, slong len1, + mp_srcptr poly2, + mp_srcptr poly3, slong len3, nmod_t mod) +{ + nmod_mat_t A, B, C; + mp_ptr t, h; + slong i, n, m; + + n = len3 - 1; + + if (len3 == 1) + return; + + if (len1 == 1) + { + res[0] = poly1[0]; + return; + } + + if (len3 == 2) + { + res[0] = _nmod_poly_evaluate_nmod(poly1, len1, poly2[0], mod); + return; + } + + m = n_sqrt(n) + 1; + + nmod_mat_init(A, m, n, mod.n); + nmod_mat_init(B, m, m, mod.n); + nmod_mat_init(C, m, n, mod.n); + + h = _nmod_vec_init(n); + t = _nmod_vec_init(n); + + /* Set rows of B to the segments of poly1 */ + for (i = 0; i < len1 / m; i++) + _nmod_vec_set(B->rows[i], poly1 + i*m, m); + + _nmod_vec_set(B->rows[i], poly1 + i*m, len1 % m); + + /* Set rows of A to powers of poly2 */ + A->rows[0][0] = UWORD(1); + _nmod_vec_set(A->rows[1], poly2, n); + for (i = 2; i < m; i++) + _nmod_poly_mulmod(A->rows[i], A->rows[i-1], + n, poly2, n, poly3, len3, mod); + + nmod_mat_mul(C, B, A); + + /* Evaluate block composition using the Horner scheme */ + _nmod_vec_set(res, C->rows[m - 1], n); + _nmod_poly_mulmod(h, A->rows[m - 1], n, poly2, n, poly3, len3, mod); + + for (i = m - 2; i >= 0; i--) + { + _nmod_poly_mulmod(t, res, n, h, n, poly3, len3, mod); + _nmod_poly_add(res, t, n, C->rows[i], n, mod); + } + + _nmod_vec_clear(h); + _nmod_vec_clear(t); + + nmod_mat_clear(A); + nmod_mat_clear(B); + nmod_mat_clear(C); +} + +void +nmod_poly_compose_mod_brent_kung(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_poly_t poly2, + const nmod_poly_t poly3) +{ + slong len1 = poly1->length; + slong len2 = poly2->length; + slong len3 = poly3->length; + slong len = len3 - 1; + + mp_ptr ptr2; + + if (len3 == 0) + { + flint_printf("Exception (nmod_poly_compose_mod_brent_kung). Division by zero.\n"); + abort(); + } + + if (len1 >= len3) + { + flint_printf("Exception (nmod_poly_compose_brent_kung). The degree of the \n" + "first polynomial must be smaller than that of the modulus.\n"); + abort(); + } + + if (len1 == 0 || len3 == 1) + { + nmod_poly_zero(res); + return; + } + + if (len1 == 1) + { + nmod_poly_set(res, poly1); + return; + } + + if (res == poly3 || res == poly1) + { + nmod_poly_t tmp; + nmod_poly_init_preinv(tmp, res->mod.n, res->mod.ninv); + nmod_poly_compose_mod_brent_kung(tmp, poly1, poly2, poly3); + nmod_poly_swap(tmp, res); + nmod_poly_clear(tmp); + return; + } + + ptr2 = _nmod_vec_init(len); + + if (len2 <= len) + { + flint_mpn_copyi(ptr2, poly2->coeffs, len2); + flint_mpn_zero(ptr2 + len2, len - len2); + } + else + { + _nmod_poly_rem(ptr2, poly2->coeffs, len2, + poly3->coeffs, len3, res->mod); + } + + nmod_poly_fit_length(res, len); + _nmod_poly_compose_mod_brent_kung(res->coeffs, + poly1->coeffs, len1, ptr2, poly3->coeffs, len3, res->mod); + res->length = len; + _nmod_poly_normalise(res); + + _nmod_vec_clear(ptr2); +} diff --git a/external/flint-2.4.3/nmod_poly/compose_mod_brent_kung_precomp_preinv.c b/external/flint-2.4.3/nmod_poly/compose_mod_brent_kung_precomp_preinv.c new file mode 100644 index 0000000..197c403 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/compose_mod_brent_kung_precomp_preinv.c @@ -0,0 +1,236 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2013 Martin Lee + +******************************************************************************/ + +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "nmod_mat.h" +#include "ulong_extras.h" + +void +_nmod_poly_reduce_matrix_mod_poly (nmod_mat_t A, const nmod_mat_t B, + const nmod_poly_t f) +{ + mp_ptr tmp1; + slong n = f->length - 1; + slong i, m = n_sqrt(n) + 1; + + nmod_mat_init(A, m, n, f->mod.n); + + A->rows[0][0] = UWORD(1); + tmp1 = _nmod_vec_init(B->c - f->length + 1); + for (i= 1; i < m; i++) + _nmod_poly_divrem (tmp1, A->rows[i], B->rows[i], B->c, f->coeffs, + f->length, f->mod); + + _nmod_vec_clear (tmp1); +} + +void +_nmod_poly_precompute_matrix (nmod_mat_t A, mp_srcptr poly1, mp_srcptr poly2, + slong len2, mp_srcptr poly2inv, slong len2inv, + nmod_t mod) +{ + /* Set rows of A to powers of poly1 */ + slong i, n, m; + + n = len2 - 1; + + m = n_sqrt(n) + 1; + + A->rows[0][0] = UWORD(1); + _nmod_vec_set(A->rows[1], poly1, n); + for (i = 2; i < m; i++) + _nmod_poly_mulmod_preinv(A->rows[i], A->rows[i - 1], + n, poly1, n, poly2, len2, poly2inv, len2inv, mod); +} + +void +nmod_poly_precompute_matrix (nmod_mat_t A, const nmod_poly_t poly1, + const nmod_poly_t poly2, const nmod_poly_t poly2inv) +{ + slong len1 = poly1->length; + slong len2 = poly2->length; + slong len = len2 - 1; + slong m = n_sqrt(len) + 1; + + mp_ptr ptr1; + + if (len2 == 0) + { + flint_printf("Exception (nmod_poly_precompute_matrix). Division by zero.\n"); + abort(); + } + + if (A->r != m || A->c != len) + { + flint_printf("Exception (nmod_poly_precompute_matrix). Wrong dimensions.\n"); + abort(); + } + + if (len2 == 1) + { + nmod_mat_zero(A); + return; + } + + ptr1 = _nmod_vec_init(len); + + if (len1 <= len) + { + flint_mpn_copyi(ptr1, poly1->coeffs, len1); + flint_mpn_zero(ptr1 + len1, len - len1); + } + else + { + _nmod_poly_rem(ptr1, poly1->coeffs, len1, + poly2->coeffs, len2, A->mod); + } + + _nmod_poly_precompute_matrix (A, ptr1, poly2->coeffs, len2, poly2inv->coeffs, + poly2inv->length, A->mod); + + _nmod_vec_clear (ptr1); +} + +void +_nmod_poly_compose_mod_brent_kung_precomp_preinv + (mp_ptr res, mp_srcptr poly1, slong len1, + const nmod_mat_t A, mp_srcptr poly3, slong len3, + mp_srcptr poly3inv, slong len3inv, nmod_t mod) +{ + nmod_mat_t B, C; + mp_ptr t, h; + slong i, n, m; + + n = len3 - 1; + + if (len3 == 1) + return; + + if (len1 == 1) + { + res[0] = poly1[0]; + return; + } + + if (len3 == 2) + { + res[0] = _nmod_poly_evaluate_nmod(poly1, len1, A->rows[1][0], mod); + return; + } + + m = n_sqrt(n) + 1; + + /* TODO check A*/ + + nmod_mat_init(B, m, m, mod.n); + nmod_mat_init(C, m, n, mod.n); + + h = _nmod_vec_init(n); + t = _nmod_vec_init(n); + + /* Set rows of B to the segments of poly1 */ + for (i = 0; i < len1 / m; i++) + _nmod_vec_set(B->rows[i], poly1 + i*m, m); + + _nmod_vec_set(B->rows[i], poly1 + i*m, len1 % m); + + nmod_mat_mul(C, B, A); + + /* Evaluate block composition using the Horner scheme */ + _nmod_vec_set(res, C->rows[m - 1], n); + _nmod_poly_mulmod_preinv(h, A->rows[m - 1], n, A->rows[1], n, + poly3, len3, poly3inv, len3inv,mod); + + for (i = m - 2; i >= 0; i--) + { + _nmod_poly_mulmod_preinv(t, res, n, h, n, poly3, len3, + poly3inv, len3inv, mod); + _nmod_poly_add(res, t, n, C->rows[i], n, mod); + } + + _nmod_vec_clear(h); + _nmod_vec_clear(t); + + nmod_mat_clear(B); + nmod_mat_clear(C); +} + +void +nmod_poly_compose_mod_brent_kung_precomp_preinv(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_mat_t A, + const nmod_poly_t poly3, const nmod_poly_t poly3inv) +{ + slong len1 = poly1->length; + slong len3 = poly3->length; + slong len = len3 - 1; + + if (len3 == 0) + { + flint_printf("Exception (nmod_poly_compose_mod_brent_kung_precomp_preinv). Division by zero.\n"); + abort(); + } + + if (len1 >= len3) + { + flint_printf("Exception (nmod_poly_compose_mod_brent_kung_precomp_preinv). The degree of the \n" + "first polynomial must be smaller than that of the modulus.\n"); + abort(); + } + + if (len1 == 0 || len3 == 1) + { + nmod_poly_zero(res); + return; + } + + if (len1 == 1) + { + nmod_poly_set(res, poly1); + return; + } + + if (res == poly3 || res == poly1 || res == poly3inv) + { + nmod_poly_t tmp; + nmod_poly_init_preinv(tmp, res->mod.n, res->mod.ninv); + nmod_poly_compose_mod_brent_kung_precomp_preinv(tmp, poly1, A, + poly3, poly3inv); + nmod_poly_swap(tmp, res); + nmod_poly_clear(tmp); + return; + } + + nmod_poly_fit_length(res, len); + _nmod_poly_compose_mod_brent_kung_precomp_preinv(res->coeffs, + poly1->coeffs, len1, A, poly3->coeffs, len3, + poly3inv->coeffs, poly3inv->length, res->mod); + res->length = len; + _nmod_poly_normalise(res); + +} diff --git a/external/flint-2.4.3/nmod_poly/compose_mod_brent_kung_preinv.c b/external/flint-2.4.3/nmod_poly/compose_mod_brent_kung_preinv.c new file mode 100644 index 0000000..0fec548 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/compose_mod_brent_kung_preinv.c @@ -0,0 +1,173 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2013 Martin Lee + +******************************************************************************/ + +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "nmod_mat.h" +#include "ulong_extras.h" + +void +_nmod_poly_compose_mod_brent_kung_preinv(mp_ptr res, mp_srcptr poly1, slong len1, + mp_srcptr poly2, mp_srcptr poly3, slong len3, + mp_srcptr poly3inv, slong len3inv, nmod_t mod) +{ + nmod_mat_t A, B, C; + mp_ptr t, h; + slong i, n, m; + + n = len3 - 1; + + if (len3 == 1) + return; + + if (len1 == 1) + { + res[0] = poly1[0]; + return; + } + + if (len3 == 2) + { + res[0] = _nmod_poly_evaluate_nmod(poly1, len1, poly2[0], mod); + return; + } + + m = n_sqrt(n) + 1; + + nmod_mat_init(A, m, n, mod.n); + nmod_mat_init(B, m, m, mod.n); + nmod_mat_init(C, m, n, mod.n); + + h = _nmod_vec_init(n); + t = _nmod_vec_init(n); + + /* Set rows of B to the segments of poly1 */ + for (i = 0; i < len1 / m; i++) + _nmod_vec_set(B->rows[i], poly1 + i*m, m); + + _nmod_vec_set(B->rows[i], poly1 + i*m, len1 % m); + + /* Set rows of A to powers of poly2 */ + A->rows[0][0] = UWORD(1); + _nmod_vec_set(A->rows[1], poly2, n); + for (i = 2; i < m; i++) + _nmod_poly_mulmod_preinv(A->rows[i], A->rows[i-1], + n, poly2, n, poly3, len3, poly3inv, len3inv, mod); + + nmod_mat_mul(C, B, A); + + /* Evaluate block composition using the Horner scheme */ + _nmod_vec_set(res, C->rows[m - 1], n); + _nmod_poly_mulmod_preinv(h, A->rows[m - 1], n, poly2, n, + poly3, len3, poly3inv, len3inv,mod); + + for (i = m - 2; i >= 0; i--) + { + _nmod_poly_mulmod_preinv(t, res, n, h, n, poly3, len3, + poly3inv, len3inv, mod); + _nmod_poly_add(res, t, n, C->rows[i], n, mod); + } + + _nmod_vec_clear(h); + _nmod_vec_clear(t); + + nmod_mat_clear(A); + nmod_mat_clear(B); + nmod_mat_clear(C); +} + +void +nmod_poly_compose_mod_brent_kung_preinv(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_poly_t poly2, + const nmod_poly_t poly3, const nmod_poly_t poly3inv) +{ + slong len1 = poly1->length; + slong len2 = poly2->length; + slong len3 = poly3->length; + slong len = len3 - 1; + + mp_ptr ptr2; + + if (len3 == 0) + { + flint_printf("Exception (nmod_poly_compose_mod_brent_kung_preinv). Division by zero.\n"); + abort(); + } + + if (len1 >= len3) + { + flint_printf("Exception (nmod_poly_compose_mod_brent_kung_preinv). The degree of the \n" + "first polynomial must be smaller than that of the modulus.\n"); + abort(); + } + + if (len1 == 0 || len3 == 1) + { + nmod_poly_zero(res); + return; + } + + if (len1 == 1) + { + nmod_poly_set(res, poly1); + return; + } + + if (res == poly3 || res == poly1 || res == poly3inv) + { + nmod_poly_t tmp; + nmod_poly_init_preinv(tmp, res->mod.n, res->mod.ninv); + nmod_poly_compose_mod_brent_kung_preinv(tmp, poly1, poly2, + poly3, poly3inv); + nmod_poly_swap(tmp, res); + nmod_poly_clear(tmp); + return; + } + + ptr2 = _nmod_vec_init(len); + + if (len2 <= len) + { + flint_mpn_copyi(ptr2, poly2->coeffs, len2); + flint_mpn_zero(ptr2 + len2, len - len2); + } + else + { + _nmod_poly_rem(ptr2, poly2->coeffs, len2, + poly3->coeffs, len3, res->mod); + } + + nmod_poly_fit_length(res, len); + _nmod_poly_compose_mod_brent_kung_preinv(res->coeffs, + poly1->coeffs, len1, ptr2, poly3->coeffs, len3, + poly3inv->coeffs, poly3inv->length, res->mod); + res->length = len; + _nmod_poly_normalise(res); + + _nmod_vec_clear(ptr2); +} diff --git a/external/flint-2.4.3/nmod_poly/compose_mod_horner.c b/external/flint-2.4.3/nmod_poly/compose_mod_horner.c new file mode 100644 index 0000000..74af7e5 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/compose_mod_horner.c @@ -0,0 +1,133 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +void +_nmod_poly_compose_mod_horner(mp_ptr res, + mp_srcptr f, slong lenf, mp_srcptr g, mp_srcptr h, slong lenh, nmod_t mod) +{ + slong i, len; + mp_ptr t; + + if (lenh == 1) + return; + + if (lenf == 1) + { + res[0] = f[0]; + return; + } + + if (lenh == 2) + { + res[0] = _nmod_poly_evaluate_nmod(f, lenf, g[0], mod); + return; + } + + len = lenh - 1; + i = lenf - 1; + t = _nmod_vec_init(len); + + _nmod_vec_scalar_mul_nmod(res, g, len, f[i], mod); + i--; + if (i >= 0) + res[0] = nmod_add(res[0], f[i], mod); + + while (i > 0) + { + i--; + _nmod_poly_mulmod(t, res, len, g, len, h, lenh, mod); + _nmod_poly_add(res, t, len, f + i, 1, mod); + } + + _nmod_vec_clear(t); +} + +void +nmod_poly_compose_mod_horner(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_poly_t poly2, + const nmod_poly_t poly3) +{ + slong len1 = poly1->length; + slong len2 = poly2->length; + slong len3 = poly3->length; + slong len = len3 - 1; + + mp_ptr ptr2; + + if (len3 == 0) + { + flint_printf("Exception (nmod_poly_compose_mod_horner). Division by zero.\n"); + abort(); + } + + if (len1 == 0 || len3 == 1) + { + nmod_poly_zero(res); + return; + } + + if (len1 == 1) + { + nmod_poly_set(res, poly1); + return; + } + + if (res == poly3 || res == poly1) + { + nmod_poly_t tmp; + nmod_poly_init_preinv(tmp, res->mod.n, res->mod.ninv); + nmod_poly_compose_mod_horner(tmp, poly1, poly2, poly3); + nmod_poly_swap(tmp, res); + nmod_poly_clear(tmp); + return; + } + + ptr2 = _nmod_vec_init(len); + + if (len2 <= len) + { + flint_mpn_copyi(ptr2, poly2->coeffs, len2); + flint_mpn_zero(ptr2 + len2, len - len2); + } + else + { + _nmod_poly_rem(ptr2, poly2->coeffs, len2, + poly3->coeffs, len3, res->mod); + } + + nmod_poly_fit_length(res, len); + _nmod_poly_compose_mod_horner(res->coeffs, + poly1->coeffs, len1, ptr2, poly3->coeffs, len3, res->mod); + res->length = len; + _nmod_poly_normalise(res); + + _nmod_vec_clear(ptr2); +} diff --git a/external/flint-2.4.3/nmod_poly/compose_series.c b/external/flint-2.4.3/nmod_poly/compose_series.c new file mode 100644 index 0000000..cad3751 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/compose_series.c @@ -0,0 +1,98 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +void +_nmod_poly_compose_series(mp_ptr res, mp_srcptr poly1, slong len1, + mp_srcptr poly2, slong len2, slong n, nmod_t mod) +{ + if (len1 < 24 || len2 < 8) + _nmod_poly_compose_series_horner(res, poly1, len1, + poly2, len2, n, mod); + else + _nmod_poly_compose_series_brent_kung(res, poly1, len1, + poly2, len2, n, mod); +} + +void +nmod_poly_compose_series(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_poly_t poly2, slong n) +{ + slong len1 = poly1->length; + slong len2 = poly2->length; + slong lenr; + + if (len2 != 0 && poly2->coeffs[0] != 0) + { + flint_printf("Exception (nmod_poly_compose_series). Inner polynomial \n" + "must have zero constant term.\n"); + abort(); + } + + if (len1 == 0 || n == 0) + { + nmod_poly_zero(res); + return; + } + + if (len2 == 0 || len1 == 1) + { + nmod_poly_fit_length(res, 1); + res->coeffs[0] = poly1->coeffs[0]; + res->length = 1; + _nmod_poly_normalise(res); + 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)) + { + nmod_poly_fit_length(res, lenr); + _nmod_poly_compose_series(res->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2, lenr, res->mod); + res->length = lenr; + _nmod_poly_normalise(res); + } + else + { + nmod_poly_t t; + nmod_poly_init2_preinv(t, res->mod.n, res->mod.ninv, lenr); + _nmod_poly_compose_series(t->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2, lenr, res->mod); + t->length = lenr; + _nmod_poly_normalise(t); + nmod_poly_swap(res, t); + nmod_poly_clear(t); + } +} diff --git a/external/flint-2.4.3/nmod_poly/compose_series_brent_kung.c b/external/flint-2.4.3/nmod_poly/compose_series_brent_kung.c new file mode 100644 index 0000000..54781b8 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/compose_series_brent_kung.c @@ -0,0 +1,140 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "nmod_mat.h" +#include "ulong_extras.h" + +void +_nmod_poly_compose_series_brent_kung(mp_ptr res, mp_srcptr poly1, slong len1, + mp_srcptr poly2, slong len2, slong n, nmod_t mod) +{ + nmod_mat_t A, B, C; + mp_ptr t, h; + slong i, m; + + if (n == 1) + { + res[0] = poly1[0]; + return; + } + + m = n_sqrt(n) + 1; + + nmod_mat_init(A, m, n, mod.n); + nmod_mat_init(B, m, m, mod.n); + nmod_mat_init(C, m, n, mod.n); + + h = _nmod_vec_init(n); + t = _nmod_vec_init(n); + + /* Set rows of B to the segments of poly1 */ + for (i = 0; i < len1 / m; i++) + _nmod_vec_set(B->rows[i], poly1 + i*m, m); + _nmod_vec_set(B->rows[i], poly1 + i*m, len1 % m); + + /* Set rows of A to powers of poly2 */ + A->rows[0][0] = UWORD(1); + _nmod_vec_set(A->rows[1], poly2, len2); + for (i = 2; i < m; i++) + _nmod_poly_mullow(A->rows[i], A->rows[i-1], n, poly2, len2, n, mod); + + nmod_mat_mul(C, B, A); + + /* Evaluate block composition using the Horner scheme */ + _nmod_vec_set(res, C->rows[m - 1], n); + _nmod_poly_mullow(h, A->rows[m - 1], n, poly2, len2, n, mod); + + for (i = m - 2; i >= 0; i--) + { + _nmod_poly_mullow(t, res, n, h, n, n, mod); + _nmod_poly_add(res, t, n, C->rows[i], n, mod); + } + + _nmod_vec_clear(h); + _nmod_vec_clear(t); + + nmod_mat_clear(A); + nmod_mat_clear(B); + nmod_mat_clear(C); +} + +void +nmod_poly_compose_series_brent_kung(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_poly_t poly2, slong n) +{ + slong len1 = poly1->length; + slong len2 = poly2->length; + slong lenr; + + if (len2 != 0 && poly2->coeffs[0] != 0) + { + flint_printf("Exception (nmod_poly_compose_series_brent_kung). Inner \n" + "polynomial must have zero constant term.\n"); + abort(); + } + + if (len1 == 0 || n == 0) + { + nmod_poly_zero(res); + return; + } + + if (len2 == 0 || len1 == 1) + { + nmod_poly_fit_length(res, 1); + res->coeffs[0] = poly1->coeffs[0]; + res->length = 1; + _nmod_poly_normalise(res); + 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)) + { + nmod_poly_fit_length(res, lenr); + _nmod_poly_compose_series_brent_kung(res->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2, lenr, res->mod); + res->length = lenr; + _nmod_poly_normalise(res); + } + else + { + nmod_poly_t t; + nmod_poly_init2_preinv(t, res->mod.n, res->mod.ninv, lenr); + _nmod_poly_compose_series_brent_kung(t->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2, lenr, res->mod); + t->length = lenr; + _nmod_poly_normalise(t); + nmod_poly_swap(res, t); + nmod_poly_clear(t); + } +} diff --git a/external/flint-2.4.3/nmod_poly/compose_series_divconquer.c b/external/flint-2.4.3/nmod_poly/compose_series_divconquer.c new file mode 100644 index 0000000..dec253f --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/compose_series_divconquer.c @@ -0,0 +1,215 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +/* + See fmpz_poly/compose_divconquer.c + */ + +void +_nmod_poly_compose_series_divconquer(mp_ptr res, mp_srcptr poly1, slong len1, + mp_srcptr poly2, slong len2, + slong N, nmod_t mod) +{ + slong i, j, k, n; + slong *hlen, alloc, powlen; + mp_ptr v, *h, pow, temp; + + if (len1 == 1) + { + res[0] = poly1[0]; + return; + } + if (len2 == 1) + { + res[0] = _nmod_poly_evaluate_nmod(poly1, len1, poly2[0], mod); + return; + } + if (len1 == 2) + { + mp_limb_t t = poly1[0]; + _nmod_vec_scalar_mul_nmod(res, poly2, len2, poly1[1], mod); + res[0] = n_addmod(res[0], t, mod.n); + return; + + } + + /* Initialisation */ + + hlen = (slong *) flint_malloc(((len1 + 1) / 2) * sizeof(slong)); + + for (k = 1; (2 << k) < len1; k++) ; + + hlen[0] = hlen[1] = FLINT_MIN(N, ((1 << k) - 1) * (len2 - 1) + 1); + for (i = k - 1; i > 0; i--) + { + slong hi = (len1 + (1 << i) - 1) / (1 << i); + slong t = FLINT_MIN(N, ((1 << i) - 1) * (len2 - 1) + 1); + for (n = (hi + 1) / 2; n < hi; n++) + hlen[n] = t; + } + powlen = FLINT_MIN(N, (1 << k) * (len2 - 1) + 1); + + alloc = 0; + for (i = 0; i < (len1 + 1) / 2; i++) + alloc += hlen[i]; + + v = _nmod_vec_init(alloc + 2 * powlen); + h = (mp_ptr *) flint_malloc(((len1 + 1) / 2) * sizeof(mp_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 (poly1[j + 1] != WORD(0)) + { + _nmod_vec_scalar_mul_nmod(h[i], poly2, len2, poly1[j + 1], mod); + h[i][0] = n_addmod(h[i][0], poly1[j], mod.n); + hlen[i] = len2; + } + else if (poly1[j] != WORD(0)) + { + h[i][0] = poly1[j]; + hlen[i] = 1; + } + } + if ((len1 & WORD(1))) + { + if (poly1[j] != WORD(0)) + { + h[i][0] = poly1[j]; + hlen[i] = 1; + } + } + + powlen = FLINT_MIN(N, 2 * len2 - 1); + _nmod_poly_mullow(pow, poly2, len2, poly2, len2, powlen, mod); + + for (n = (len1 + 1) / 2; n > 2; n = (n + 1) / 2) + { + if (hlen[1] > 0) + { + slong templen = FLINT_MIN(N, powlen + hlen[1] - 1); + _nmod_poly_mullow(temp, pow, powlen, h[1], hlen[1], templen, mod); + _nmod_poly_add(h[0], temp, templen, h[0], hlen[0], mod); + hlen[0] = FLINT_MAX(hlen[0], templen); + } + + for (i = 1; i < n / 2; i++) + { + if (hlen[2*i + 1] > 0) + { + hlen[i] = FLINT_MIN(N, hlen[2*i + 1] + powlen - 1); + _nmod_poly_mullow(h[i], pow, powlen, h[2*i + 1], hlen[2*i + 1], + hlen[i], mod); + } + else + { + hlen[i] = 0; + } + _nmod_poly_add(h[i], h[i], hlen[i], h[2*i], hlen[2*i], mod); + hlen[i] = FLINT_MAX(hlen[i], hlen[2*i]); + } + if ((n & WORD(1))) + { + hlen[i] = FLINT_MIN(N, hlen[2*i]); + flint_mpn_copyi(h[i], h[2*i], hlen[i]); + } + + _nmod_poly_mullow(temp, pow, powlen, pow, powlen, + FLINT_MIN(N, 2 * powlen - 1), mod); + powlen = FLINT_MIN(N, 2 * powlen - 1); + { + mp_ptr t = pow; + pow = temp; + temp = t; + } + } + + _nmod_poly_mullow(res, pow, powlen, h[1], hlen[1], + FLINT_MIN(N, powlen + hlen[1] - 1), mod); + _nmod_vec_add(res, res, h[0], hlen[0], mod); + + _nmod_vec_clear(v); + flint_free(h); + flint_free(hlen); +} + +void +nmod_poly_compose_series_divconquer(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_poly_t poly2, slong N) +{ + const slong len1 = poly1->length; + const slong len2 = FLINT_MIN(N, poly2->length); + slong lenr; + + if (len1 == 0 || N == 0) + { + nmod_poly_zero(res); + return; + } + if (len1 == 1 || len2 == 0) + { + nmod_poly_set_coeff_ui(res, 0, poly1->coeffs[0]); + nmod_poly_truncate(res, 1); + return; + } + + lenr = FLINT_MIN(N, (len1 - 1) * (len2 - 1) + 1); + + if (res != poly1 && res != poly2) + { + nmod_poly_fit_length(res, lenr); + _nmod_poly_compose_series_divconquer(res->coeffs, + poly1->coeffs, len1, poly2->coeffs, len2, N, poly1->mod); + } + else + { + nmod_poly_t t; + nmod_poly_init2(t, poly1->mod.n, lenr); + _nmod_poly_compose_series_divconquer(t->coeffs, + poly1->coeffs, len1, poly2->coeffs, len2, N, poly1->mod); + nmod_poly_swap(res, t); + nmod_poly_clear(t); + } + + res->length = lenr; + _nmod_poly_normalise(res); +} diff --git a/external/flint-2.4.3/nmod_poly/compose_series_horner.c b/external/flint-2.4.3/nmod_poly/compose_series_horner.c new file mode 100644 index 0000000..fc4a4cd --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/compose_series_horner.c @@ -0,0 +1,127 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +void +_nmod_poly_compose_series_horner(mp_ptr res, mp_srcptr poly1, slong len1, + mp_srcptr poly2, slong len2, slong n, nmod_t mod) +{ + if (n == 1) + { + res[0] = poly1[0]; + } + else + { + slong i = len1 - 1; + slong lenr; + + mp_ptr t = _nmod_vec_init(n); + + lenr = len2; + _nmod_vec_scalar_mul_nmod(res, poly2, len2, poly1[i], mod); + i--; + res[0] = nmod_add(res[0], poly1[i], mod); + + while (i > 0) + { + i--; + if (lenr + len2 - 1 < n) + { + _nmod_poly_mul(t, res, lenr, poly2, len2, mod); + lenr = lenr + len2 - 1; + } + else + { + _nmod_poly_mullow(t, res, lenr, poly2, len2, n, mod); + lenr = n; + } + _nmod_poly_add(res, t, lenr, poly1 + i, 1, mod); + } + + _nmod_vec_zero(res + lenr, n - lenr); + _nmod_vec_clear(t); + } +} + +void +nmod_poly_compose_series_horner(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_poly_t poly2, slong n) +{ + slong len1 = poly1->length; + slong len2 = poly2->length; + slong lenr; + + if (len2 != 0 && poly2->coeffs[0] != 0) + { + flint_printf("Exception (nmod_poly_compose_series_horner). Inner polynomial " + "must have zero constant term.\n"); + abort(); + } + + if (len1 == 0 || n == 0) + { + nmod_poly_zero(res); + return; + } + + if (len2 == 0 || len1 == 1) + { + nmod_poly_fit_length(res, 1); + res->coeffs[0] = poly1->coeffs[0]; + res->length = 1; + _nmod_poly_normalise(res); + 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)) + { + nmod_poly_fit_length(res, lenr); + _nmod_poly_compose_series_horner(res->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2, lenr, res->mod); + res->length = lenr; + _nmod_poly_normalise(res); + } + else + { + nmod_poly_t t; + nmod_poly_init2_preinv(t, res->mod.n, res->mod.ninv, lenr); + _nmod_poly_compose_series_horner(t->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2, lenr, res->mod); + t->length = lenr; + _nmod_poly_normalise(t); + nmod_poly_swap(res, t); + nmod_poly_clear(t); + } +} diff --git a/external/flint-2.4.3/nmod_poly/cos_series.c b/external/flint-2.4.3/nmod_poly/cos_series.c new file mode 100644 index 0000000..7e4dab5 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/cos_series.c @@ -0,0 +1,90 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +void +_nmod_poly_cos_series(mp_ptr g, mp_srcptr h, slong n, nmod_t mod) +{ + mp_ptr t, u; + + t = _nmod_vec_init(n); + u = _nmod_vec_init(n); + + /* cos(x) = (1-tan(x/2)^2)/(1+tan(x/2)^2) */ + _nmod_vec_scalar_mul_nmod(u, h, n, n_invmod(UWORD(2), mod.n), mod); + _nmod_poly_tan_series(t, u, n, mod); + _nmod_poly_mullow(u, t, n, t, n, n, mod); + _nmod_vec_neg(t, u, n, mod); + t[0] = u[0] = UWORD(1); + _nmod_poly_div_series(g, t, u, n, mod); + + _nmod_vec_clear(t); + _nmod_vec_clear(u); +} + +void +nmod_poly_cos_series(nmod_poly_t g, const nmod_poly_t h, slong n) +{ + mp_ptr h_coeffs; + slong h_len = h->length; + + if (h_len > 0 && h->coeffs[0] != UWORD(0)) + { + flint_printf("Exception (nmod_poly_cos_series). Constant term != 0.\n"); + abort(); + } + + if (h_len == 1 || n < 2) + { + nmod_poly_zero(g); + if (n > 0) + nmod_poly_set_coeff_ui(g, 0, UWORD(1)); + return; + } + + nmod_poly_fit_length(g, n); + + if (h_len < n) + { + h_coeffs = _nmod_vec_init(n); + flint_mpn_copyi(h_coeffs, h->coeffs, h_len); + flint_mpn_zero(h_coeffs + h_len, n - h_len); + } + else + h_coeffs = h->coeffs; + + _nmod_poly_cos_series(g->coeffs, h_coeffs, n, h->mod); + + if (h_len < n) + _nmod_vec_clear(h_coeffs); + + g->length = n; + _nmod_poly_normalise(g); +} diff --git a/external/flint-2.4.3/nmod_poly/cosh_series.c b/external/flint-2.4.3/nmod_poly/cosh_series.c new file mode 100644 index 0000000..388eb91 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/cosh_series.c @@ -0,0 +1,99 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +void +_nmod_poly_cosh_series(mp_ptr f, mp_srcptr h, slong n, nmod_t mod) +{ + mp_ptr g = _nmod_vec_init(n); + _nmod_poly_exp_expinv_series(f, g, h, n, mod); + _nmod_vec_add(f, f, g, n, mod); + _nmod_vec_scalar_mul_nmod(f, f, n, n_invmod(UWORD(2), mod.n), mod); + _nmod_vec_clear(g); +} + +void +nmod_poly_cosh_series(nmod_poly_t g, const nmod_poly_t h, slong n) +{ + mp_ptr g_coeffs, h_coeffs; + nmod_poly_t t1; + slong h_len; + + h_len = h->length; + + if (h_len > 0 && h->coeffs[0] != UWORD(0)) + { + flint_printf("Exception (nmod_poly_cosh_series). Constant term != 0.\n"); + abort(); + } + + if (h_len == 1 || n < 2) + { + nmod_poly_zero(g); + if (n > 0) + nmod_poly_set_coeff_ui(g, 0, UWORD(1)); + return; + } + + if (h_len < n) + { + h_coeffs = _nmod_vec_init(n); + flint_mpn_copyi(h_coeffs, h->coeffs, h_len); + flint_mpn_zero(h_coeffs + h_len, n - h_len); + } + else + h_coeffs = h->coeffs; + + if (h == g && h_len >= n) + { + nmod_poly_init2(t1, h->mod.n, n); + g_coeffs = t1->coeffs; + } + else + { + nmod_poly_fit_length(g, n); + g_coeffs = g->coeffs; + } + + _nmod_poly_cosh_series(g_coeffs, h_coeffs, n, h->mod); + + if (h == g && h_len >= n) + { + nmod_poly_swap(g, t1); + nmod_poly_clear(t1); + } + + g->length = n; + + if (h_len < n) + _nmod_vec_clear(h_coeffs); + + _nmod_poly_normalise(g); +} diff --git a/external/flint-2.4.3/nmod_poly/deflate.c b/external/flint-2.4.3/nmod_poly/deflate.c new file mode 100644 index 0000000..6b47798 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/deflate.c @@ -0,0 +1,56 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + + +void +nmod_poly_deflate(nmod_poly_t result, const nmod_poly_t input, ulong deflation) +{ + slong res_length, i; + + if (deflation == 0) + { + flint_printf("Exception (nmod_poly_deflate). Division by zero.\n"); + abort(); + } + + if (input->length <= 1 || deflation == 1) + { + nmod_poly_set(result, input); + return; + } + + res_length = (input->length - 1) / deflation + 1; + nmod_poly_fit_length(result, res_length); + for (i = 0; i < res_length; i++) + result->coeffs[i] = input->coeffs[i*deflation]; + + result->length = res_length; +} diff --git a/external/flint-2.4.3/nmod_poly/deflation.c b/external/flint-2.4.3/nmod_poly/deflation.c new file mode 100644 index 0000000..49c0420 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/deflation.c @@ -0,0 +1,60 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +ulong +nmod_poly_deflation(const nmod_poly_t input) +{ + ulong deflation; + slong i, coeff; + + if (input->length <= 1) + return input->length; + + coeff = 1; + while (!input->coeffs[coeff]) + coeff++; + + deflation = n_gcd_full(input->length - 1, coeff); + + while ((deflation > 1) && (coeff + deflation < input->length)) + { + for (i = 0; i < deflation - 1; i++) + { + coeff++; + if (input->coeffs[coeff]) + deflation = n_gcd_full(coeff, deflation); + } + if (i == deflation - 1) + coeff++; + } + + return deflation; +} diff --git a/external/flint-2.4.3/nmod_poly/derivative.c b/external/flint-2.4.3/nmod_poly/derivative.c new file mode 100644 index 0000000..70f7be0 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/derivative.c @@ -0,0 +1,63 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_poly.h" + +void _nmod_poly_derivative(mp_ptr x_prime, mp_srcptr x, slong len, nmod_t mod) +{ + slong j; + mp_limb_t k = 1; + + for (j = 1; j < len; j++) + { + if (k <= 1) + x_prime[j - 1] = k == 0 ? WORD(0) : x[j]; + else + x_prime[j - 1] = n_mulmod2_preinv(x[j], k, mod.n, mod.ninv); + + if (++k == mod.n) k = WORD(0); + } + +} + +void nmod_poly_derivative(nmod_poly_t x_prime, const nmod_poly_t x) +{ + if (x->length <= 1) + { + nmod_poly_zero(x_prime); + return; + } + + nmod_poly_fit_length(x_prime, x->length - 1); + + _nmod_poly_derivative(x_prime->coeffs, x->coeffs, x->length, x->mod); + + x_prime->length = x->length - 1; + _nmod_poly_normalise(x_prime); +} + diff --git a/external/flint-2.4.3/nmod_poly/div.c b/external/flint-2.4.3/nmod_poly/div.c new file mode 100644 index 0000000..890c5ff --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/div.c @@ -0,0 +1,99 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +void +_nmod_poly_div(mp_ptr Q, mp_srcptr A, slong lenA, + mp_srcptr B, slong lenB, nmod_t mod) +{ + TMP_INIT; + + if (lenB < 15) + { + mp_ptr W; + + TMP_START; + W = TMP_ALLOC(NMOD_DIV_BC_ITCH(lenA, lenB, mod)*sizeof(mp_limb_t)); + _nmod_poly_div_basecase(Q, W, A, lenA, B, lenB, mod); + TMP_END; + } + else if (lenB < 6000) + _nmod_poly_div_divconquer(Q, A, lenA, B, lenB, mod); + else + _nmod_poly_div_newton(Q, A, lenA, B, lenB, mod); +} + +void +nmod_poly_div(nmod_poly_t Q, + const nmod_poly_t A, const nmod_poly_t B) +{ + nmod_poly_t tQ; + mp_ptr q; + slong A_len, B_len; + + B_len = B->length; + + if (B_len == 0) + { + flint_printf("Exception (nmod_poly_divrem). Division by zero.\n"); + abort(); + } + + A_len = A->length; + + if (A_len < B_len) + { + nmod_poly_zero(Q); + return; + } + + if (Q == A || Q == B) + { + nmod_poly_init2(tQ, A->mod.n, A_len - B_len + 1); + q = tQ->coeffs; + } + else + { + nmod_poly_fit_length(Q, A_len - B_len + 1); + q = Q->coeffs; + } + + _nmod_poly_div(q, A->coeffs, A_len, + B->coeffs, B_len, A->mod); + + if (Q == A || Q == B) + { + nmod_poly_swap(tQ, Q); + nmod_poly_clear(tQ); + } + + Q->length = A_len - B_len + 1; +} diff --git a/external/flint-2.4.3/nmod_poly/div_basecase.c b/external/flint-2.4.3/nmod_poly/div_basecase.c new file mode 100644 index 0000000..ffd16cd --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/div_basecase.c @@ -0,0 +1,271 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +void +_nmod_poly_div_basecase_1(mp_ptr Q, mp_ptr W, + mp_srcptr A, slong A_len, mp_srcptr B, slong B_len, + nmod_t mod) +{ + mp_limb_t lead_inv = n_invmod(B[B_len - 1], mod.n); + slong len, coeff = A_len - B_len; + + mp_ptr R1 = W; + mp_srcptr Btop = B + B_len - 1; + + flint_mpn_copyi(R1, A + B_len - 1, A_len - B_len + 1); + + while (coeff >= 0) + { + R1[coeff] = n_mod2_preinv(R1[coeff], mod.n, mod.ninv); + + while (coeff >= 0 && R1[coeff] == WORD(0)) + { + Q[coeff--] = WORD(0); + if (coeff >= 0) + R1[coeff] = n_mod2_preinv(R1[coeff], mod.n, mod.ninv); + } + + if (coeff >= 0) + { + mp_limb_t c, * R_sub; + + Q[coeff] = + n_mulmod2_preinv(R1[coeff], lead_inv, mod.n, mod.ninv); + + c = n_negmod(Q[coeff], mod.n); + + len = FLINT_MIN(B_len - 1, coeff); + R_sub = R1 + coeff - len; + if (len > 0) + mpn_addmul_1(R_sub, Btop - len, len, c); + + coeff--; + } + } +} + +void +_nmod_poly_div_basecase_2(mp_ptr Q, mp_ptr W, + mp_srcptr A, slong A_len, mp_srcptr B, slong B_len, + nmod_t mod) +{ + slong coeff, i, len; + mp_limb_t lead_inv = n_invmod(B[B_len - 1], mod.n); + mp_ptr B2, R2; + mp_srcptr Btop; + + B2 = W; + for (i = 0; i < B_len - 1; i++) + { + B2[2 * i] = B[i]; + B2[2 * i + 1] = 0; + } + Btop = B2 + 2*(B_len - 1); + + R2 = W + 2*(B_len - 1); + for (i = 0; i < A_len - B_len + 1; i++) + { + R2[2 * i] = A[B_len + i - 1]; + R2[2 * i + 1] = 0; + } + + coeff = A_len - B_len; + + while (coeff >= 0) + { + mp_limb_t r_coeff; + r_coeff = + n_ll_mod_preinv(R2[2 * coeff + 1], R2[2 * coeff], mod.n, mod.ninv); + + while (coeff >= 0 && r_coeff == WORD(0)) + { + Q[coeff--] = WORD(0); + if (coeff >= 0) + r_coeff = + n_ll_mod_preinv(R2[2 * coeff + 1], R2[2 * coeff], mod.n, + mod.ninv); + } + + if (coeff >= 0) + { + mp_limb_t c, * R_sub; + + Q[coeff] = + n_mulmod2_preinv(r_coeff, lead_inv, mod.n, mod.ninv); + + c = n_negmod(Q[coeff], mod.n); + + len = FLINT_MIN(B_len - 1, coeff); + R_sub = R2 + 2 * (coeff - len); + if (len > 0) + mpn_addmul_1(R_sub, Btop - 2*len, 2 * len, c); + + coeff--; + } + } +} + +void +_nmod_poly_div_basecase_3(mp_ptr Q, mp_ptr W, + mp_srcptr A, slong A_len, mp_srcptr B, slong B_len, + nmod_t mod) +{ + slong coeff, i, len; + mp_limb_t lead_inv = n_invmod(B[B_len - 1], mod.n); + mp_limb_t r_coeff; + mp_ptr B3, R3; + mp_srcptr Btop; + + B3 = W; + for (i = 0; i < B_len - 1; i++) + { + B3[3 * i] = B[i]; + B3[3 * i + 1] = 0; + B3[3 * i + 2] = 0; + } + Btop = B3 + 3*(B_len - 1); + + R3 = W + 3*(B_len - 1); + for (i = 0; i < A_len - B_len + 1; i++) + { + R3[3 * i] = A[B_len + i - 1]; + R3[3 * i + 1] = 0; + R3[3 * i + 2] = 0; + } + + coeff = A_len - B_len; + + while (coeff >= 0) + { + r_coeff = + n_lll_mod_preinv(R3[3 * coeff + 2], R3[3 * coeff + 1], + R3[3 * coeff], mod.n, mod.ninv); + + while (coeff >= 0 && r_coeff == WORD(0)) + { + Q[coeff--] = WORD(0); + if (coeff >= 0) + r_coeff = + n_lll_mod_preinv(R3[3 * coeff + 2], R3[3 * coeff + 1], + R3[3 * coeff], mod.n, mod.ninv); + } + + if (coeff >= 0) + { + mp_limb_t c, * R_sub; + + Q[coeff] = + n_mulmod2_preinv(r_coeff, lead_inv, mod.n, mod.ninv); + + c = n_negmod(Q[coeff], mod.n); + + len = FLINT_MIN(B_len - 1, coeff); + R_sub = R3 + 3 * (coeff - len); + if (len > 0) + mpn_addmul_1(R_sub, Btop - 3*len, 3 * len, c); + + coeff--; + } + } +} + +void +_nmod_poly_div_basecase(mp_ptr Q, mp_ptr W, + mp_srcptr A, slong A_len, mp_srcptr B, slong B_len, + nmod_t mod) +{ + slong bits = + 2 * (FLINT_BITS - mod.norm) + FLINT_BIT_COUNT(A_len - B_len + 1); + + if (bits <= FLINT_BITS) + _nmod_poly_div_basecase_1(Q, W, A, A_len, B, B_len, mod); + else if (bits <= 2 * FLINT_BITS) + _nmod_poly_div_basecase_2(Q, W, A, A_len, B, B_len, mod); + else + _nmod_poly_div_basecase_3(Q, W, A, A_len, B, B_len, mod); +} + +void +nmod_poly_div_basecase(nmod_poly_t Q, const nmod_poly_t A, + const nmod_poly_t B) +{ + mp_ptr Q_coeffs, W; + nmod_poly_t t1; + slong Alen, Blen; + TMP_INIT; + + Blen = B->length; + + if (Blen == 0) + { + flint_printf("Exception (nmod_poly_div_base). Division by zero.\n"); + abort(); + } + + Alen = A->length; + + if (Alen < Blen) + { + nmod_poly_zero(Q); + + return; + } + + if (Q == A || Q == B) + { + nmod_poly_init2_preinv(t1, B->mod.n, B->mod.ninv, + Alen - Blen + 1); + Q_coeffs = t1->coeffs; + } + else + { + nmod_poly_fit_length(Q, Alen - Blen + 1); + Q_coeffs = Q->coeffs; + } + + TMP_START; + W = TMP_ALLOC(NMOD_DIV_BC_ITCH(Alen, Blen, A->mod)*sizeof(mp_limb_t)); + + _nmod_poly_div_basecase(Q_coeffs, W, A->coeffs, Alen, + B->coeffs, Blen, B->mod); + + if (Q == A || Q == B) + { + nmod_poly_swap(Q, t1); + nmod_poly_clear(t1); + } + + Q->length = Alen - Blen + 1; + + TMP_END; + _nmod_poly_normalise(Q); +} diff --git a/external/flint-2.4.3/nmod_poly/div_divconquer.c b/external/flint-2.4.3/nmod_poly/div_divconquer.c new file mode 100644 index 0000000..d551c33 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/div_divconquer.c @@ -0,0 +1,162 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2008, 2009, 2011 William Hart + Copyright (C) 2012 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +static void +__nmod_poly_div_divconquer(mp_ptr Q, mp_srcptr A, slong lenA, + mp_srcptr B, slong lenB, nmod_t mod) +{ + if (lenA < 2 * lenB - 1) + { + /* + Convert unbalanced division into a 2 n1 - 1 by n1 division + */ + + const slong n1 = lenA - lenB + 1; + const slong n2 = lenB - n1; + + mp_srcptr p1 = A + n2; + mp_srcptr d1 = B + n2; + + mp_ptr V = _nmod_vec_init(n1 - 1 + NMOD_DIVREM_DC_ITCH(n1, mod)); + mp_ptr W = V + NMOD_DIVREM_DC_ITCH(n1, mod); + + _nmod_poly_div_divconquer_recursive(Q, W, V, p1, d1, n1, mod); + + _nmod_vec_clear(V); + } + else /* lenA = 2 * lenB - 1 */ + { + mp_ptr V = _nmod_vec_init(lenB - 1 + NMOD_DIVREM_DC_ITCH(lenB, mod)); + mp_ptr W = V + NMOD_DIVREM_DC_ITCH(lenB, mod); + + _nmod_poly_div_divconquer_recursive(Q, W, V, A, B, lenB, mod); + + _nmod_vec_clear(V); + } +} + + +/* needed due to partial overlap */ +static void +_nmod_vec_sub_dec(mp_ptr a, mp_srcptr b, mp_srcptr c, slong n, nmod_t mod) +{ + slong i; + + for (i = n - 1; i >= 0; i--) + a[i] = n_submod(b[i], c[i], mod.n); +} + +void +_nmod_poly_div_divconquer(mp_ptr Q, mp_srcptr A, slong lenA, + mp_srcptr B, slong lenB, nmod_t mod) +{ + if (lenA <= 2 * lenB - 1) + { + __nmod_poly_div_divconquer(Q, A, lenA, B, lenB, mod); + } + else /* lenA > 2 * lenB - 1 */ + { + mp_ptr S, T, V, R; + slong shift, next, n = 2 * lenB - 1; + + S = _nmod_vec_init(2 * n + (lenB - 1) + NMOD_DIVREM_DC_ITCH(lenB, mod)); + T = S + n; + R = T + n; + V = R + (lenB - 1); + + shift = lenA - n; + _nmod_vec_set(S, A + shift, n); + + while (lenA >= n) + { + shift = lenA - n; + _nmod_poly_divrem_divconquer_recursive(Q + shift, T, R, V, S, B, lenB, mod); + next = FLINT_MIN(lenB, shift); + _nmod_vec_sub_dec(S + next, S, T, lenB - 1, mod); + _nmod_vec_set(S, A + shift - next, next); + lenA -= lenB; + } + + if (lenA >= lenB) + __nmod_poly_div_divconquer(Q, S, lenA, B, lenB, mod); + + _nmod_vec_clear(S); + } +} + + +void +nmod_poly_div_divconquer(nmod_poly_t Q, + const nmod_poly_t A, const nmod_poly_t B) +{ + nmod_poly_t tQ; + mp_ptr q; + slong Alen, Blen; + + Blen = B->length; + + if (Blen == 0) + { + flint_printf("Exception (nmod_poly_div_divconquer). Division by zero.\n"); + abort(); + } + + Alen = A->length; + + if (Alen < Blen) + { + nmod_poly_zero(Q); + return; + } + + if (Q == A || Q == B) + { + nmod_poly_init2(tQ, A->mod.n, Alen - Blen + 1); + q = tQ->coeffs; + } + else + { + nmod_poly_fit_length(Q, Alen - Blen + 1); + q = Q->coeffs; + } + + _nmod_poly_div_divconquer(q, A->coeffs, Alen, + B->coeffs, Blen, A->mod); + + if (Q == A || Q == B) + { + nmod_poly_swap(tQ, Q); + nmod_poly_clear(tQ); + } + + Q->length = Alen - Blen + 1; +} diff --git a/external/flint-2.4.3/nmod_poly/div_divconquer_recursive.c b/external/flint-2.4.3/nmod_poly/div_divconquer_recursive.c new file mode 100644 index 0000000..b45393f --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/div_divconquer_recursive.c @@ -0,0 +1,113 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2008, 2009, 2011 William Hart + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +void +_nmod_poly_div_divconquer_recursive(mp_ptr Q, mp_ptr W, mp_ptr V, + mp_srcptr A, mp_srcptr B, slong lenB, nmod_t mod) +{ + if (lenB <= NMOD_DIV_DIVCONQUER_CUTOFF) + { + _nmod_poly_div_basecase(Q, V, A, 2 * lenB - 1, B, lenB, mod); + } + else + { + const slong n2 = lenB / 2; + const slong n1 = lenB - n2; + + mp_ptr W1 = W; + mp_ptr W2 = W + n2; + + mp_srcptr p1 = A + 2 * n2; + mp_srcptr p2; + mp_srcptr d1 = B + n2; + mp_srcptr d2 = B; + mp_srcptr d3 = B + n1; + + mp_ptr q1 = Q + n2; + mp_ptr q2 = Q; + mp_ptr d1q1 = q2 + n2 - (n1 - 1); + + mp_ptr d2q1, t; + + /* + Set q1 to p1 div d1, a 2 n1 - 1 by n1 division so q1 ends up + being of length n1; low(d1q1) = d1 q1 is of length n1 - 1 + */ + + _nmod_poly_divrem_divconquer_recursive(q1, d1q1, W1, V, p1, d1, n1, mod); + + /* + Compute bottom n1 + n2 - 1 coeffs of d2q1 = d2 q1 + */ + + d2q1 = W1; + _nmod_poly_mullow(d2q1, q1, n1, d2, n2, n1 + n2 - 1, mod); + + /* + Compute dq1 = d1 q1 x^n2 + d2 q1, of length n1 + n2 - 1 + Split it into a segment of length n1 - 1 at which is ignored + and a piece of length n2 at BQ. + */ + + if (n2 > n1 - 1) + W1[0] = d2q1[n1 - 1]; + + _nmod_vec_add(W1 + n2 - (n1 - 1), d1q1, d2q1 + n2, n1 - 1, mod); + + /* + Compute t = A/x^n2 - dq1, which has length 2 n1 + n2 - 1, but we + are not interested in the top n1 coeffs as they will be zero, so + this has effective length n1 + n2 - 1 + + For the following division, we want to set {p2, 2 n2 - 1} to the + top 2 n2 - 1 coeffs of this + + Since the bottom n2 - 1 coeffs of p2 are irrelevant for the + division, we in fact set {t, n2} to the relevant coeffs + */ + + t = W1; + _nmod_vec_sub(t, A + n2 + (n1 - 1), t, n2, mod); + p2 = t - (n2 - 1); + + /* + Compute q2 = t div d3, a 2 n2 - 1 by n2 division, so q2 will have + length n2; + */ + + _nmod_poly_div_divconquer_recursive(q2, W2, V, p2, d3, n2, mod); + + /* + Note Q = q1 x^n2 + q2 + */ + } +} diff --git a/external/flint-2.4.3/nmod_poly/div_newton.c b/external/flint-2.4.3/nmod_poly/div_newton.c new file mode 100644 index 0000000..0b98e1e --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/div_newton.c @@ -0,0 +1,100 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +void _nmod_poly_div_newton(mp_ptr Q, mp_srcptr A, slong lenA, + mp_srcptr B, slong lenB, nmod_t mod) +{ + const slong lenQ = lenA - lenB + 1; + mp_ptr Arev, Brev; + + Arev = _nmod_vec_init(2 * lenQ); + Brev = Arev + lenQ; + + _nmod_poly_reverse(Arev, A + (lenA - lenQ), lenQ, lenQ); + + if (lenB >= lenQ) + { + _nmod_poly_reverse(Brev, B + (lenB - lenQ), lenQ, lenQ); + } + else + { + _nmod_poly_reverse(Brev, B, lenB, lenB); + flint_mpn_zero(Brev + lenB, lenQ - lenB); + } + + _nmod_poly_div_series(Q, Arev, Brev, lenQ, mod); + + _nmod_poly_reverse(Q, Q, lenQ, lenQ); + + _nmod_vec_clear(Arev); +} + +void nmod_poly_div_newton(nmod_poly_t Q, const nmod_poly_t A, + const nmod_poly_t B) +{ + const slong lenA = A->length, lenB = B->length, lenQ = lenA - lenB + 1; + + mp_ptr q; + + if (lenB == 0) + { + flint_printf("Exception (nmod_poly_div_newton). Division by zero.\n"); + abort(); + } + + if (lenA < lenB) + { + nmod_poly_zero(Q); + return; + } + + if (Q == A || Q == B) + { + q = flint_malloc(lenQ * sizeof(mp_limb_t)); + } + else + { + nmod_poly_fit_length(Q, lenQ); + q = Q->coeffs; + } + + _nmod_poly_div_newton(q, A->coeffs, lenA, B->coeffs, lenB, B->mod); + + if (Q == A || Q == B) + { + flint_free(Q->coeffs); + Q->coeffs = q; + Q->alloc = lenQ; + } + Q->length = lenQ; +} diff --git a/external/flint-2.4.3/nmod_poly/div_newton_n_preinv.c b/external/flint-2.4.3/nmod_poly/div_newton_n_preinv.c new file mode 100644 index 0000000..58b626a --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/div_newton_n_preinv.c @@ -0,0 +1,106 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Sebastian Pancratz + Copyright (C) 2013 Martin Lee + +******************************************************************************/ + +#undef ulong +#define ulong ulongxx/* interferes with system includes */ + +#include + +#undef ulong + +#include + +#define ulong mp_limb_t + +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +void _nmod_poly_div_newton_n_preinv (mp_ptr Q, mp_srcptr A, slong lenA, + mp_srcptr B, slong lenB, mp_srcptr Binv, + slong lenBinv, nmod_t mod) +{ + const slong lenQ = lenA - lenB + 1; + mp_ptr Arev; + + Arev = _nmod_vec_init(lenQ); + _nmod_poly_reverse(Arev, A + (lenA - lenQ), lenQ, lenQ); + + _nmod_poly_mullow(Q, Arev, lenQ, Binv, FLINT_MIN (lenQ,lenBinv), lenQ, mod); + + _nmod_poly_reverse(Q, Q, lenQ, lenQ); + + _nmod_vec_clear(Arev); +} + +void nmod_poly_div_newton_n_preinv (nmod_poly_t Q, const nmod_poly_t A, + const nmod_poly_t B, const nmod_poly_t Binv) +{ + const slong lenA = A->length, lenB = B->length, lenQ = lenA - lenB + 1, + lenBinv = Binv->length; + + mp_ptr q; + + if (lenB == 0) + { + flint_printf("Exception (nmod_poly_div_newton_n_preinv). Division by zero.\n"); + abort(); + } + + if (lenA < lenB) + { + nmod_poly_zero(Q); + return; + } + + if (lenA > 2 * lenB - 2) + { + flint_printf ("Exception (nmod_poly_div_newton_n_preinv).\n"); + } + + if (Q == A || Q == B || Q == Binv) + { + q = flint_malloc(lenQ * sizeof(mp_limb_t)); + } + else + { + nmod_poly_fit_length(Q, lenQ); + q = Q->coeffs; + } + + _nmod_poly_div_newton_n_preinv (q, A->coeffs, lenA, B->coeffs, lenB, + Binv->coeffs, lenBinv, B->mod); + + if (Q == A || Q == B || Q == Binv) + { + flint_free(Q->coeffs); + Q->coeffs = q; + Q->alloc = lenQ; + } + Q->length = lenQ; +} diff --git a/external/flint-2.4.3/nmod_poly/div_root.c b/external/flint-2.4.3/nmod_poly/div_root.c new file mode 100644 index 0000000..96defbc --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/div_root.c @@ -0,0 +1,86 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +mp_limb_t +_nmod_poly_div_root(mp_ptr Q, mp_srcptr A, slong len, mp_limb_t c, nmod_t mod) +{ + mp_limb_t r, t; + slong i; + + if (len < 2) + return UWORD(0); + + t = A[len - 2]; + r = Q[len - 2] = A[len - 1]; + + for (i = len - 2; i > 0; i--) + { + r = nmod_add(nmod_mul(r, c, mod), t, mod); + t = A[i-1]; + Q[i-1] = r; + } + + r = nmod_add(nmod_mul(r, c, mod), t, mod); + return r; +} + +mp_limb_t +nmod_poly_div_root(nmod_poly_t Q, + const nmod_poly_t A, mp_limb_t c) +{ + mp_limb_t rem; + + slong len = A->length; + + if (len == 0) + { + nmod_poly_zero(Q); + return UWORD(0); + } + + if (len == 1) + { + rem = A->coeffs[0]; + nmod_poly_zero(Q); + return rem; + } + + if (c == 0) + { + rem = A->coeffs[0]; + nmod_poly_shift_right(Q, A, 1); + return rem; + } + + nmod_poly_fit_length(Q, len - 1); + rem = _nmod_poly_div_root(Q->coeffs, A->coeffs, len, c, Q->mod); + Q->length = len - 1; + return rem; +} diff --git a/external/flint-2.4.3/nmod_poly/div_series.c b/external/flint-2.4.3/nmod_poly/div_series.c new file mode 100644 index 0000000..9dcc1c6 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/div_series.c @@ -0,0 +1,109 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +void +_nmod_poly_div_series(mp_ptr Q, mp_srcptr A, mp_srcptr B, + slong n, nmod_t mod) +{ + mp_ptr Binv = _nmod_vec_init(n); + + _nmod_poly_inv_series(Binv, B, n, mod); + _nmod_poly_mullow(Q, Binv, n, A, n, n, mod); + + _nmod_vec_clear(Binv); +} + +void +nmod_poly_div_series(nmod_poly_t Q, const nmod_poly_t A, + const nmod_poly_t B, slong n) +{ + mp_ptr A_coeffs, B_coeffs, Q_coeffs; + nmod_poly_t t1; + slong Alen, Blen; + + Blen = B->length; + + if (n == 0 || Blen == 0 || B->coeffs[0] == 0) + { + flint_printf("Exception (nmod_poly_div_series). Division by zero.\n"); + abort(); + } + + Alen = A->length; + + if (Alen < n) + { + A_coeffs = _nmod_vec_init(n); + flint_mpn_copyi(A_coeffs, A->coeffs, Alen); + flint_mpn_zero(A_coeffs + Alen, n - Alen); + } + else + A_coeffs = A->coeffs; + + if (Blen < n) + { + B_coeffs = _nmod_vec_init(n); + flint_mpn_copyi(B_coeffs, B->coeffs, Blen); + flint_mpn_zero(B_coeffs + Blen, n - Blen); + } + else + B_coeffs = B->coeffs; + + if ((Q == A || Q == B) && Q->length >= n) + { + nmod_poly_init2(t1, Q->mod.n, n); + Q_coeffs = t1->coeffs; + } + else + { + nmod_poly_fit_length(Q, n); + Q_coeffs = Q->coeffs; + } + + _nmod_poly_div_series(Q_coeffs, A_coeffs, B_coeffs, n, Q->mod); + + if ((Q == A || Q == B) && Q->length >= n) + { + nmod_poly_swap(Q, t1); + nmod_poly_clear(t1); + } + + Q->length = n; + + if (Alen < n) + _nmod_vec_clear(A_coeffs); + + if (Blen < n) + _nmod_vec_clear(B_coeffs); + + _nmod_poly_normalise(Q); +} diff --git a/external/flint-2.4.3/nmod_poly/divrem.c b/external/flint-2.4.3/nmod_poly/divrem.c new file mode 100644 index 0000000..aac62c1 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/divrem.c @@ -0,0 +1,120 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +#include "mpn_extras.h" + +void +_nmod_poly_divrem(mp_ptr Q, mp_ptr R, mp_srcptr A, slong lenA, + mp_srcptr B, slong lenB, nmod_t mod) +{ + TMP_INIT; + + if (lenA == lenB) + _nmod_poly_divrem_q0(Q, R, A, B, lenB, mod); + else if (lenA == lenB + 1) + _nmod_poly_divrem_q1(Q, R, A, lenA, B, lenB, mod); + else if (lenB < 15) + { + mp_ptr W; + + TMP_START; + W = TMP_ALLOC(NMOD_DIVREM_BC_ITCH(lenA, lenB, mod)*sizeof(mp_limb_t)); + _nmod_poly_divrem_basecase(Q, R, W, A, lenA, B, lenB, mod); + TMP_END; + } + else if (lenB < 6000) + _nmod_poly_divrem_divconquer(Q, R, A, lenA, B, lenB, mod); + else + _nmod_poly_divrem_newton(Q, R, A, lenA, B, lenB, mod); +} + +void nmod_poly_divrem(nmod_poly_t Q, nmod_poly_t R, + const nmod_poly_t A, const nmod_poly_t B) +{ + const slong lenA = A->length, lenB = B->length; + nmod_poly_t tQ, tR; + mp_ptr q, r; + + if (lenB == 0) + { + flint_printf("Exception (nmod_poly_divrem). Division by zero."); + abort(); + } + + if (lenA < lenB) + { + nmod_poly_set(R, A); + nmod_poly_zero(Q); + return; + } + + if (Q == A || Q == B) + { + nmod_poly_init2_preinv(tQ, A->mod.n, A->mod.ninv, lenA - lenB + 1); + q = tQ->coeffs; + } + else + { + nmod_poly_fit_length(Q, lenA - lenB + 1); + q = Q->coeffs; + } + + if (R == A || R == B) + { + nmod_poly_init2_preinv(tR, B->mod.n, B->mod.ninv, lenB - 1); + r = tR->coeffs; + } + else + { + nmod_poly_fit_length(R, lenB - 1); + r = R->coeffs; + } + + _nmod_poly_divrem(q, r, A->coeffs, lenA, B->coeffs, lenB, A->mod); + + if (Q == A || Q == B) + { + nmod_poly_swap(Q, tQ); + nmod_poly_clear(tQ); + } + if (R == A || R == B) + { + nmod_poly_swap(R, tR); + nmod_poly_clear(tR); + } + + Q->length = lenA - lenB + 1; + R->length = lenB - 1; + + _nmod_poly_normalise(R); +} + diff --git a/external/flint-2.4.3/nmod_poly/divrem_basecase.c b/external/flint-2.4.3/nmod_poly/divrem_basecase.c new file mode 100644 index 0000000..b07b8ef --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/divrem_basecase.c @@ -0,0 +1,253 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 William Hart + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +void +_nmod_poly_divrem_basecase_1(mp_ptr Q, mp_ptr R, mp_ptr W, + mp_srcptr A, slong lenA, mp_srcptr B, slong lenB, + nmod_t mod) +{ + const mp_limb_t invL = n_invmod(B[lenB - 1], mod.n); + slong iR; + mp_ptr ptrQ = Q - lenB + 1; + mp_ptr R1 = W; + + flint_mpn_copyi(R1, A, lenA); + + for (iR = lenA - 1; iR >= lenB - 1; iR--) + { + if (R1[iR] == 0) + { + ptrQ[iR] = WORD(0); + } + else + { + ptrQ[iR] = n_mulmod2_preinv(R1[iR], invL, mod.n, mod.ninv); + + if (lenB > 1) + { + const mp_limb_t c = n_negmod(ptrQ[iR], mod.n); + mpn_addmul_1(R1 + iR - lenB + 1, B, lenB - 1, c); + } + } + } + + if (lenB > 1) + _nmod_vec_reduce(R, R1, lenB - 1, mod); +} + +void +_nmod_poly_divrem_basecase_2(mp_ptr Q, mp_ptr R, mp_ptr W, + mp_srcptr A, slong lenA, mp_srcptr B, slong lenB, + nmod_t mod) +{ + const mp_limb_t invL = n_invmod(B[lenB - 1], mod.n); + slong iR, i; + mp_ptr B2 = W, R2 = W + 2*(lenB - 1), ptrQ = Q - lenB + 1; + + for (i = 0; i < lenB - 1; i++) + { + B2[2 * i] = B[i]; + B2[2 * i + 1] = 0; + } + for (i = 0; i < lenA; i++) + { + R2[2 * i] = A[i]; + R2[2 * i + 1] = 0; + } + + for (iR = lenA - 1; iR >= lenB - 1; ) + { + mp_limb_t r = + n_ll_mod_preinv(R2[2 * iR + 1], R2[2 * iR], mod.n, mod.ninv); + + while ((iR + 1 >= lenB) && (r == WORD(0))) + { + ptrQ[iR--] = WORD(0); + if (iR + 1 >= lenB) + r = n_ll_mod_preinv(R2[2 * iR + 1], R2[2 * iR], mod.n, + mod.ninv); + } + + if (iR + 1 >= lenB) + { + ptrQ[iR] = n_mulmod2_preinv(r, invL, mod.n, mod.ninv); + + if (lenB > 1) + { + const mp_limb_t c = n_negmod(ptrQ[iR], mod.n); + mpn_addmul_1(R2 + 2 * (iR - lenB + 1), B2, 2 * lenB - 2, c); + } + iR--; + } + } + + for (iR = 0; iR < lenB - 1; iR++) + R[iR] = n_ll_mod_preinv(R2[2*iR+1], R2[2*iR], mod.n, mod.ninv); +} + +void +_nmod_poly_divrem_basecase_3(mp_ptr Q, mp_ptr R, mp_ptr W, + mp_srcptr A, slong lenA, mp_srcptr B, slong lenB, + nmod_t mod) +{ + const mp_limb_t invL = n_invmod(B[lenB - 1], mod.n); + slong iR, i; + mp_ptr B3 = W, R3 = W + 3*(lenB - 1), ptrQ = Q - lenB + 1; + + for (i = 0; i < lenB - 1; i++) + { + B3[3 * i] = B[i]; + B3[3 * i + 1] = 0; + B3[3 * i + 2] = 0; + } + for (i = 0; i < lenA; i++) + { + R3[3 * i] = A[i]; + R3[3 * i + 1] = 0; + R3[3 * i + 2] = 0; + } + + for (iR = lenA - 1; iR >= lenB - 1; ) + { + mp_limb_t r = + n_lll_mod_preinv(R3[3 * iR + 2], R3[3 * iR + 1], + R3[3 * iR], mod.n, mod.ninv); + + while ((iR + 1 >= lenB) && (r == WORD(0))) + { + ptrQ[iR--] = WORD(0); + if (iR + 1 >= lenB) + r = n_lll_mod_preinv(R3[3 * iR + 2], R3[3 * iR + 1], + R3[3 * iR], mod.n, mod.ninv); + } + + if (iR + 1 >= lenB) + { + ptrQ[iR] = n_mulmod2_preinv(r, invL, mod.n, mod.ninv); + + if (lenB > 1) + { + const mp_limb_t c = n_negmod(ptrQ[iR], mod.n); + mpn_addmul_1(R3 + 3 * (iR - lenB + 1), B3, 3 * lenB - 3, c); + } + iR--; + } + } + + for (iR = 0; iR < lenB - 1; iR++) + R[iR] = n_lll_mod_preinv(R3[3 * iR + 2], R3[3 * iR + 1], + R3[3 * iR], mod.n, mod.ninv); +} + +void +_nmod_poly_divrem_basecase(mp_ptr Q, mp_ptr R, mp_ptr W, + mp_srcptr A, slong lenA, mp_srcptr B, slong lenB, + nmod_t mod) +{ + const slong bits = + 2 * (FLINT_BITS - mod.norm) + FLINT_BIT_COUNT(lenA - lenB + 1); + + if (bits <= FLINT_BITS) + _nmod_poly_divrem_basecase_1(Q, R, W, A, lenA, B, lenB, mod); + else if (bits <= 2 * FLINT_BITS) + _nmod_poly_divrem_basecase_2(Q, R, W, A, lenA, B, lenB, mod); + else + _nmod_poly_divrem_basecase_3(Q, R, W, A, lenA, B, lenB, mod); +} + +void +nmod_poly_divrem_basecase(nmod_poly_t Q, nmod_poly_t R, const nmod_poly_t A, + const nmod_poly_t B) +{ + const slong lenA = A->length, lenB = B->length; + mp_ptr Q_coeffs, R_coeffs, W; + nmod_poly_t t1, t2; + TMP_INIT; + + if (lenB == 0) + { + flint_printf("Exception (nmod_poly_divrem). Division by zero.\n"); + abort(); + } + + if (lenA < lenB) + { + nmod_poly_set(R, A); + nmod_poly_zero(Q); + return; + } + + if (Q == A || Q == B) + { + nmod_poly_init2_preinv(t1, B->mod.n, B->mod.ninv, lenA - lenB + 1); + Q_coeffs = t1->coeffs; + } + else + { + nmod_poly_fit_length(Q, lenA - lenB + 1); + Q_coeffs = Q->coeffs; + } + + if (R == A || R == B) + { + nmod_poly_init2_preinv(t2, B->mod.n, B->mod.ninv, lenB - 1); + R_coeffs = t2->coeffs; + } + else + { + nmod_poly_fit_length(R, lenB - 1); + R_coeffs = R->coeffs; + } + + TMP_START; + W = TMP_ALLOC(NMOD_DIVREM_BC_ITCH(lenA, lenB, A->mod)*sizeof(mp_limb_t)); + + _nmod_poly_divrem_basecase(Q_coeffs, R_coeffs, W, A->coeffs, lenA, + B->coeffs, lenB, B->mod); + + if (Q == A || Q == B) + { + nmod_poly_swap(Q, t1); + nmod_poly_clear(t1); + } + if (R == A || R == B) + { + nmod_poly_swap(R, t2); + nmod_poly_clear(t2); + } + Q->length = lenA - lenB + 1; + R->length = lenB - 1; + + TMP_END; + _nmod_poly_normalise(R); +} diff --git a/external/flint-2.4.3/nmod_poly/divrem_divconquer.c b/external/flint-2.4.3/nmod_poly/divrem_divconquer.c new file mode 100644 index 0000000..20a2c5d --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/divrem_divconquer.c @@ -0,0 +1,195 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2008, 2009, 2011 William Hart + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2012 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +static +void __nmod_poly_divrem_divconquer(mp_ptr Q, mp_ptr R, + mp_srcptr A, slong lenA, + mp_srcptr B, slong lenB, nmod_t mod) +{ + if (lenA < 2 * lenB - 1) + { + /* + Convert unbalanced division into a 2 n1 - 1 by n1 division + */ + + const slong n1 = lenA - lenB + 1; + const slong n2 = lenB - n1; + + mp_srcptr p1 = A + n2; + mp_srcptr d1 = B + n2; + mp_srcptr d2 = B; + + mp_ptr V = _nmod_vec_init((n1 - 1) + lenB - 1 + NMOD_DIVREM_DC_ITCH(n1, mod)); + mp_ptr W = V + NMOD_DIVREM_DC_ITCH(n1, mod); + + mp_ptr d1q1 = R + n2; + mp_ptr d2q1 = W; + + _nmod_poly_divrem_divconquer_recursive(Q, d1q1, W, V, p1, d1, n1, mod); + + /* + Compute d2q1 = Q d2, of length lenB - 1 + */ + + if (n1 >= n2) + _nmod_poly_mul(d2q1, Q, n1, d2, n2, mod); + else + _nmod_poly_mul(d2q1, d2, n2, Q, n1, mod); + + /* + Compute BQ = d1q1 * x^n1 + d2q1, of length lenB - 1; + then compute R = A - BQ + */ + + flint_mpn_copyi(R, d2q1, n2); + _nmod_vec_add(R + n2, R + n2, d2q1 + n2, n1 - 1, mod); + _nmod_vec_sub(R, A, R, lenB - 1, mod); + + _nmod_vec_clear(V); + } + else /* lenA = 2 * lenB - 1 */ + { + mp_ptr V = _nmod_vec_init(lenB - 1 + NMOD_DIVREM_DC_ITCH(lenB, mod)); + mp_ptr W = V + NMOD_DIVREM_DC_ITCH(lenB, mod); + + _nmod_poly_divrem_divconquer_recursive(Q, R, W, V, A, B, lenB, mod); + _nmod_vec_sub(R, A, R, lenB - 1, mod); + + _nmod_vec_clear(V); + } +} + +void _nmod_poly_divrem_divconquer(mp_ptr Q, mp_ptr R, + mp_srcptr A, slong lenA, + mp_srcptr B, slong lenB, nmod_t mod) +{ + if (lenA <= 2 * lenB - 1) + { + __nmod_poly_divrem_divconquer(Q, R, A, lenA, B, lenB, mod); + } + else /* lenA > 2 * lenB - 1 */ + { + slong shift, n = 2 * lenB - 1; + mp_ptr S, QB, W, V, T; + + S = _nmod_vec_init(lenA + 2 * (lenB - 1) + n + NMOD_DIVREM_DC_ITCH(lenB, mod)); + QB = S + lenA; + W = QB + (lenB - 1); + T = W + (lenB - 1); + V = T + n; + + _nmod_vec_set(S, A, lenA); + + while (lenA >= n) + { + shift = lenA - n; + _nmod_poly_divrem_divconquer_recursive(Q + shift, QB, W, V, S + shift, B, lenB, mod); + _nmod_vec_sub(S + shift, S + shift, QB, lenB - 1, mod); + lenA -= lenB; + } + + if (lenA >= lenB) + { + __nmod_poly_divrem_divconquer(Q, T, S, lenA, B, lenB, mod); + _nmod_vec_set(S, T, lenA); + } + + _nmod_vec_set(R, S, lenB - 1); + _nmod_vec_clear(S); + } +} + +void nmod_poly_divrem_divconquer(nmod_poly_t Q, nmod_poly_t R, + const nmod_poly_t A, const nmod_poly_t B) +{ + nmod_poly_t tQ, tR; + mp_ptr q, r; + slong lenA, lenB; + + lenA = A->length; + lenB = B->length; + + if (lenB == 0) + { + flint_printf("Exception (nmod_poly_divrem_divconquer). Division by zero.\n"); + abort(); + } + + if (lenA < lenB) + { + nmod_poly_set(R, A); + nmod_poly_zero(Q); + return; + } + + if (Q == A || Q == B) + { + nmod_poly_init2(tQ, A->mod.n, lenA - lenB + 1); + q = tQ->coeffs; + } + else + { + nmod_poly_fit_length(Q, lenA - lenB + 1); + q = Q->coeffs; + } + + if (R == A || R == B) + { + nmod_poly_init2(tR, A->mod.n, lenB - 1); + r = tR->coeffs; + } + else + { + nmod_poly_fit_length(R, lenB - 1); + r = R->coeffs; + } + + _nmod_poly_divrem_divconquer(q, r, A->coeffs, lenA, + B->coeffs, lenB, A->mod); + + if (Q == A || Q == B) + { + nmod_poly_swap(tQ, Q); + nmod_poly_clear(tQ); + } + if (R == A || R == B) + { + nmod_poly_swap(tR, R); + nmod_poly_clear(tR); + } + + Q->length = lenA - lenB + 1; + R->length = lenB - 1; + + _nmod_poly_normalise(R); +} diff --git a/external/flint-2.4.3/nmod_poly/divrem_divconquer_recursive.c b/external/flint-2.4.3/nmod_poly/divrem_divconquer_recursive.c new file mode 100644 index 0000000..dca3248 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/divrem_divconquer_recursive.c @@ -0,0 +1,141 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2008, 2009, 2011 William Hart + Copyright (C) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +void +_nmod_poly_divrem_divconquer_recursive(mp_ptr Q, mp_ptr BQ, mp_ptr W, mp_ptr V, + mp_srcptr A, mp_srcptr B, slong lenB, nmod_t mod) +{ + if (lenB <= NMOD_DIVREM_DIVCONQUER_CUTOFF) + { + mp_ptr t = V; + mp_ptr w = t + 2*lenB - 1; + + flint_mpn_copyi(t + lenB - 1, A + lenB - 1, lenB); + flint_mpn_zero(t, lenB - 1); + + _nmod_poly_divrem_basecase(Q, BQ, w, t, 2 * lenB - 1, B, lenB, mod); + + /* BQ = A - R */ + _nmod_vec_neg(BQ, BQ, lenB - 1, mod); + } + else + { + const slong n2 = lenB / 2; + const slong n1 = lenB - n2; + + mp_ptr W1 = W; + mp_ptr W2 = W + n2; + + mp_srcptr p1 = A + 2 * n2; + mp_srcptr p2; + mp_srcptr d1 = B + n2; + mp_srcptr d2 = B; + mp_srcptr d3 = B + n1; + mp_srcptr d4 = B; + + mp_ptr q1 = Q + n2; + mp_ptr q2 = Q; + mp_ptr dq1 = BQ + n2; + mp_ptr d1q1 = BQ + n2 - (n1 - 1); + + mp_ptr d2q1, d3q2, d4q2, t; + + /* + Set q1 to p1 div d1, a 2 n1 - 1 by n1 division so q1 ends up + being of length n1; low(d1q1) = d1 q1 is of length n1 - 1 + */ + + _nmod_poly_divrem_divconquer_recursive(q1, d1q1, W1, V, p1, d1, n1, mod); + + /* + Compute bottom n1 + n2 - 1 coeffs of d2q1 = d2 q1 + */ + + d2q1 = W1; + _nmod_poly_mullow(d2q1, q1, n1, d2, n2, n1 + n2 - 1, mod); + + /* + Compute dq1 = d1 q1 x^n2 + d2 q1, of length n1 + n2 - 1 + Split it into a segment of length n1 - 1 at dq1 and a piece + of length n2 at BQ. + */ + + flint_mpn_copyi(dq1, d2q1, n1 - 1); + if (n2 > n1 - 1) + BQ[0] = d2q1[n1 - 1]; + + _nmod_vec_add(d1q1, d1q1, d2q1 + n2, n1 - 1, mod); + + /* + Compute t = A/x^n2 - dq1, which has length 2 n1 + n2 - 1, but we + are not interested in the top n1 coeffs as they will be zero, so + this has effective length n1 + n2 - 1 + + For the following division, we want to set {p2, 2 n2 - 1} to the + top 2 n2 - 1 coeffs of this + + Since the bottom n2 - 1 coeffs of p2 are irrelevant for the + division, we in fact set {t, n2} to the relevant coeffs + */ + + t = W1; + _nmod_vec_sub(t, A + n2 + (n1 - 1), BQ, n2, mod); + p2 = t - (n2 - 1); + + /* + Compute q2 = t div d3, a 2 n2 - 1 by n2 division, so q2 will have + length n2; let low(d3q2) = d3 q2, of length n2 - 1 + */ + + d3q2 = BQ; + _nmod_poly_divrem_divconquer_recursive(q2, d3q2, W2, V, p2, d3, n2, mod); + + /* + Compute d4q2 = d4 q2, of length n1 + n2 - 1 + */ + + d4q2 = W1; + _nmod_poly_mullow(d4q2, d4, n1, q2, n2, n1 + n2 - 1, mod); + + /* + Compute dq2 = d3q2 x^n1 + d4q2, of length n1 + n2 - 1 + */ + + _nmod_vec_add(BQ + n1, BQ + n1, d3q2, n2 - 1, mod); + flint_mpn_copyi(BQ, d4q2, n2); + _nmod_vec_add(BQ + n2, BQ + n2, d4q2 + n2, n1 - 1, mod); + + /* + Note Q = q1 x^n2 + q2, and BQ = dq1 x^n2 + dq2 + */ + } +} diff --git a/external/flint-2.4.3/nmod_poly/divrem_newton.c b/external/flint-2.4.3/nmod_poly/divrem_newton.c new file mode 100644 index 0000000..3c164cc --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/divrem_newton.c @@ -0,0 +1,108 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +void _nmod_poly_divrem_newton(mp_ptr Q, mp_ptr R, mp_srcptr A, slong lenA, + mp_srcptr B, slong lenB, nmod_t mod) +{ + const slong lenQ = lenA - lenB + 1; + + _nmod_poly_div_newton(Q, A, lenA, B, lenB, mod); + + if (lenB > 1) + { + if (lenQ >= lenB - 1) + _nmod_poly_mullow(R, Q, lenQ, B, lenB - 1, lenB - 1, mod); + else + _nmod_poly_mullow(R, B, lenB - 1, Q, lenQ, lenB - 1, mod); + + _nmod_vec_sub(R, A, R, lenB - 1, mod); + } +} + +void nmod_poly_divrem_newton(nmod_poly_t Q, nmod_poly_t R, + const nmod_poly_t A, const nmod_poly_t B) +{ + const slong lenA = A->length, lenB = B->length; + mp_ptr q, r; + + if (lenB == 0) + { + flint_printf("Exception (nmod_poly_divrem_newton). Division by zero.\n"); + abort(); + } + + if (lenA < lenB) + { + nmod_poly_set(R, A); + nmod_poly_zero(Q); + return; + } + + if (Q == A || Q == B) + { + q = _nmod_vec_init(lenA - lenB + 1); + } + else + { + nmod_poly_fit_length(Q, lenA - lenB + 1); + q = Q->coeffs; + } + if (R == A || R == B) + { + r = _nmod_vec_init(lenB - 1); + } + else + { + nmod_poly_fit_length(R, lenB - 1); + r = R->coeffs; + } + + _nmod_poly_divrem_newton(q, r, A->coeffs, lenA, + B->coeffs, lenB, B->mod); + + if (Q == A || Q == B) + { + _nmod_vec_clear(Q->coeffs); + Q->coeffs = q; + Q->alloc = lenA - lenB + 1; + } + if (R == A || R == B) + { + _nmod_vec_clear(R->coeffs); + R->coeffs = r; + R->alloc = lenB - 1; + } + Q->length = lenA - lenB + 1; + R->length = lenB - 1; + + _nmod_poly_normalise(R); +} diff --git a/external/flint-2.4.3/nmod_poly/divrem_newton_n_preinv.c b/external/flint-2.4.3/nmod_poly/divrem_newton_n_preinv.c new file mode 100644 index 0000000..9265aca --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/divrem_newton_n_preinv.c @@ -0,0 +1,132 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2013 Martin Lee + +******************************************************************************/ + +#undef ulong +#define ulong ulongxx/* interferes with system includes */ + +#include + +#undef ulong + +#include + +#define ulong mp_limb_t + +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +void _nmod_poly_divrem_newton_n_preinv (mp_ptr Q, mp_ptr R, mp_srcptr A, + slong lenA, mp_srcptr B, slong lenB, + mp_srcptr Binv, slong lenBinv, nmod_t mod) +{ + const slong lenQ = lenA - lenB + 1; + + if (lenA == lenB + 1) + { + _nmod_poly_divrem_q1 (Q, R, A, lenA, B, lenB, mod); + return; + } + + _nmod_poly_div_newton_n_preinv (Q, A, lenA, B, lenB, Binv, lenBinv, mod); + + if (lenB > 1) + { + if (lenQ >= lenB - 1) + _nmod_poly_mullow(R, Q, lenQ, B, lenB - 1, lenB - 1, mod); + else + _nmod_poly_mullow(R, B, lenB - 1, Q, lenQ, lenB - 1, mod); + + _nmod_vec_sub(R, A, R, lenB - 1, mod); + } +} + +void nmod_poly_divrem_newton_n_preinv(nmod_poly_t Q, nmod_poly_t R, + const nmod_poly_t A, const nmod_poly_t B, + const nmod_poly_t Binv) +{ + const slong lenA = A->length, lenB = B->length, lenBinv = Binv->length; + mp_ptr q, r; + + if (lenB == 0) + { + flint_printf("Exception (nmod_poly_divrem_newton_n_preinv). Division by zero.\n"); + abort(); + } + + if (lenA < lenB) + { + nmod_poly_set(R, A); + nmod_poly_zero(Q); + return; + } + + if (lenA > 2 * lenB - 2) + { + flint_printf ("Exception (nmod_poly_divrem_newton_n_preinv).\n"); + } + + if (Q == A || Q == B || Q == Binv) + { + q = _nmod_vec_init(lenA - lenB + 1); + } + else + { + nmod_poly_fit_length(Q, lenA - lenB + 1); + q = Q->coeffs; + } + if (R == A || R == B || R == Binv) + { + r = _nmod_vec_init(lenB - 1); + } + else + { + nmod_poly_fit_length(R, lenB - 1); + r = R->coeffs; + } + + _nmod_poly_divrem_newton_n_preinv (q, r, A->coeffs, lenA, + B->coeffs, lenB, Binv->coeffs, + lenBinv, B->mod); + + if (Q == A || Q == B || Q == Binv) + { + _nmod_vec_clear(Q->coeffs); + Q->coeffs = q; + Q->alloc = lenA - lenB + 1; + } + if (R == A || R == B || R == Binv) + { + _nmod_vec_clear(R->coeffs); + R->coeffs = r; + R->alloc = lenB - 1; + } + Q->length = lenA - lenB + 1; + R->length = lenB - 1; + + _nmod_poly_normalise(R); +} diff --git a/external/flint-2.4.3/nmod_poly/divrem_q0.c b/external/flint-2.4.3/nmod_poly/divrem_q0.c new file mode 100644 index 0000000..27fb98c --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/divrem_q0.c @@ -0,0 +1,50 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +void _nmod_poly_divrem_q0(mp_ptr Q, mp_ptr R, + mp_srcptr A, mp_srcptr B, slong lenA, nmod_t mod) +{ + const mp_limb_t invL = (B[lenA-1] == 1) ? 1 : n_invmod(B[lenA-1], mod.n); + + if (lenA == 1) + { + _nmod_vec_scalar_mul_nmod(Q, A, lenA, invL, mod); + } + else + { + Q[0] = n_mulmod2_preinv(A[lenA-1], invL, mod.n, mod.ninv); + + _nmod_vec_scalar_mul_nmod(R, B, lenA - 1, Q[0], mod); + _nmod_vec_sub(R, A, R, lenA - 1, mod); + } +} + diff --git a/external/flint-2.4.3/nmod_poly/divrem_q1.c b/external/flint-2.4.3/nmod_poly/divrem_q1.c new file mode 100644 index 0000000..57104f4 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/divrem_q1.c @@ -0,0 +1,69 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +void _nmod_poly_divrem_q1(mp_ptr Q, mp_ptr R, + mp_srcptr A, slong lenA, mp_srcptr B, slong lenB, + nmod_t mod) +{ + const mp_limb_t invL = (B[lenB-1] == 1) ? 1 : n_invmod(B[lenB-1], mod.n); + + if (lenB == 1) + { + _nmod_vec_scalar_mul_nmod(Q, A, lenA, invL, mod); + } + else + { + mp_limb_t t; + + Q[1] = n_mulmod2_preinv(A[lenA-1], invL, mod.n, mod.ninv); + t = n_mulmod2_preinv(Q[1], B[lenB-2], mod.n, mod.ninv); + t = n_submod(A[lenA-2], t, mod.n); + Q[0] = n_mulmod2_preinv(t, invL, mod.n, mod.ninv); + + if (FLINT_BITS + 2 <= 2 * mod.norm) + { + mpn_mul_1(R, B, lenB - 1, Q[0]); + if (lenB > 2) + mpn_addmul_1(R + 1, B, lenB - 2, Q[1]); + _nmod_vec_reduce(R, R, lenB - 1, mod); + } + else + { + _nmod_vec_scalar_mul_nmod(R, B, lenB - 1, Q[0], mod); + if (lenB > 2) + _nmod_vec_scalar_addmul_nmod(R + 1, B, lenB - 2, Q[1], mod); + } + + _nmod_vec_sub(R, A, R, lenB - 1, mod); + } +} + diff --git a/external/flint-2.4.3/nmod_poly/doc/nmod_poly.txt b/external/flint-2.4.3/nmod_poly/doc/nmod_poly.txt new file mode 100644 index 0000000..adc6887 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/doc/nmod_poly.txt @@ -0,0 +1,2473 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +******************************************************************************* + + Helper functions + +******************************************************************************* + +int signed_mpn_sub_n(mp_ptr res, mp_srcptr op1, mp_srcptr op2, slong n) + + If \code{op1 >= op2} return 0 and set \code{res} to \code{op1 - op2} + else return 1 and set \code{res} to \code{op2 - op1}. + +******************************************************************************* + + Memory management + +******************************************************************************* + +void nmod_poly_init(nmod_poly_t poly, mp_limb_t n) + + Initialises \code{poly}. It will have coefficients modulo~$n$. + +void nmod_poly_init_preinv(nmod_poly_t poly, mp_limb_t n, mp_limb_t ninv) + + Initialises \code{poly}. It will have coefficients modulo~$n$. + The caller supplies a precomputed inverse limb generated by + \code{n_preinvert_limb()}. + +void nmod_poly_init2(nmod_poly_t poly, mp_limb_t n, slong alloc) + + Initialises \code{poly}. It will have coefficients modulo~$n$. + Up to \code{alloc} coefficients may be stored in \code{poly}. + +void nmod_poly_init2_preinv(nmod_poly_t poly, + mp_limb_t n, mp_limb_t ninv, slong alloc) + + Initialises \code{poly}. It will have coefficients modulo~$n$. + The caller supplies a precomputed inverse limb generated by + \code{n_preinvert_limb()}. Up to \code{alloc} coefficients may + be stored in \code{poly}. + +void nmod_poly_realloc(nmod_poly_t poly, slong alloc) + + Reallocates \code{poly} to the given length. If the current + length is less than \code{alloc}, the polynomial is truncated + and normalised. If \code{alloc} is zero, the polynomial is + cleared. + +void nmod_poly_clear(nmod_poly_t poly) + + Clears the polynomial and releases any memory it used. The polynomial + cannot be used again until it is initialised. + +void nmod_poly_fit_length(nmod_poly_t poly, slong alloc) + + Ensures \code{poly} has space for at least \code{alloc} coefficients. + This function only ever grows the allocated space, so no data loss can + occur. + +void _nmod_poly_normalise(nmod_poly_t poly) + + Internal function for normalising a polynomial so that the top + coefficient, if there is one at all, is not zero. + +******************************************************************************* + + Polynomial properties + +******************************************************************************* + +slong nmod_poly_length(const nmod_poly_t poly) + + Returns the length of the polynomial \code{poly}. The zero polynomial + has length zero. + +slong nmod_poly_degree(const nmod_poly_t poly) + + Returns the degree of the polynomial \code{poly}. The zero polynomial + is deemed to have degree~$-1$. + +mp_limb_t nmod_poly_modulus(const nmod_poly_t poly) + + Returns the modulus of the polynomial \code{poly}. This will be a + positive integer. + +mp_bitcnt_t nmod_poly_max_bits(const nmod_poly_t poly) + + Returns the maximum number of bits of any coefficient of \code{poly}. + +******************************************************************************* + + Assignment and basic manipulation + +******************************************************************************* + +void nmod_poly_set(nmod_poly_t a, const nmod_poly_t b) + + Sets \code{a} to a copy of \code{b}. + +void nmod_poly_swap(nmod_poly_t poly1, nmod_poly_t poly2) + + Efficiently swaps \code{poly1} and \code{poly2} by swapping pointers + internally. + +void nmod_poly_zero(nmod_poly_t res) + + Sets \code{res} to the zero polynomial. + +void nmod_poly_truncate(nmod_poly_t poly, slong len) + + Truncates \code{poly} to the given length and normalises it. + If \code{len} is greater than the current length of \code{poly}, + then nothing happens. + +void _nmod_poly_reverse(mp_ptr output, mp_srcptr input, slong len, slong m) + + Sets \code{output} to the reverse of \code{input}, which is of length + \code{len}, but thinking of it as a polynomial of length~\code{m}, + notionally zero-padded if necessary. The length~\code{m} must be + non-negative, but there are no other restrictions. The polynomial + \code{output} must have space for \code{m} coefficients. + +void nmod_poly_reverse(nmod_poly_t output, const nmod_poly_t input, slong m) + + Sets \code{output} to the reverse of \code{input}, thinking of it as + a polynomial of length~\code{m}, notionally zero-padded if necessary). + The length~\code{m} must be non-negative, but there are no other + restrictions. The output polynomial will be set to length~\code{m} + and then normalised. + +******************************************************************************* + + Randomization + +******************************************************************************* + +void nmod_poly_randtest(nmod_poly_t poly, flint_rand_t state, slong len) + + Generates a random polynomial with length up to \code{len}. + +void +nmod_poly_randtest_irreducible(nmod_poly_t poly, flint_rand_t state, slong len) + + Generates a random irreducible polynomial with length up to \code{len}. + +void nmod_poly_randtest_monic(nmod_poly_t poly, flint_rand_t state, slong len) + + Generates a random monic polynomial with length \code{len}. + +void +nmod_poly_randtest_monic_irreducible(nmod_poly_t poly, flint_rand_t state, + slong len) + + Generates a random monic irreducible polynomial with length \code{len}. + + +void +nmod_poly_randtest_trinomial(nmod_poly_t poly, flint_rand_t state, slong len) + + Generates a random monic trinomial of length \code{len}. + +int +nmod_poly_randtest_trinomial_irreducible(nmod_poly_t poly, flint_rand_t state, + slong len, slong max_attempts) + + Attempts to set \code{poly} to a monic irreducible trinomial of + length \code{len}. It will generate up to \code{max_attempts} + trinomials in attempt to find an irreducible one. If + \code{max_attempts} is \code{0}, then it will keep generating + trinomials until an irreducible one is found. Returns $1$ if one + is found and $0$ otherwise. + +void +nmod_poly_randtest_pentomial(nmod_poly_t poly, flint_rand_t state, slong len) + + Generates a random monic pentomial of length \code{len}. + +int +nmod_poly_randtest_pentomial_irreducible(nmod_poly_t poly, flint_rand_t state, + slong len, slong max_attempts) + + Attempts to set \code{poly} to a monic irreducible pentomial of + length \code{len}. It will generate up to \code{max_attempts} + pentomials in attempt to find an irreducible one. If + \code{max_attempts} is \code{0}, then it will keep generating + pentomials until an irreducible one is found. Returns $1$ if one + is found and $0$ otherwise. + +void +nmod_poly_randtest_sparse_irreducible(nmod_poly_t poly, flint_rand_t state, + slong len) + + Attempts to set \code{poly} to a sparse, monic irreducible polynomial + with length \code{len}. It attempts to find an irreducible + trinomial. If that does not succeed, it attempts to find a + irreducible pentomial. If that fails, then \code{poly} is just + set to a random monic irreducible polynomial. + +******************************************************************************* + + Getting and setting coefficients + +******************************************************************************* + +ulong nmod_poly_get_coeff_ui(const nmod_poly_t poly, slong j) + + Returns the coefficient of \code{poly} at index~\code{j}, where + coefficients are numbered with zero being the constant coefficient, + and returns it as an \code{ulong}. If \code{j} refers to a + coefficient beyond the end of \code{poly}, zero is returned. + +void nmod_poly_set_coeff_ui(nmod_poly_t poly, slong j, ulong c) + + Sets the coefficient of \code{poly} at index \code{j}, where + coefficients are numbered with zero being the constant coefficient, + to the value \code{c} reduced modulo the modulus of \code{poly}. + If \code{j} refers to a coefficient beyond the current end of \code{poly}, + the polynomial is first resized, with intervening coefficients being + set to zero. + +******************************************************************************* + + Input and output + +******************************************************************************* + +char * nmod_poly_get_str(const nmod_poly_t poly) + + Writes \code{poly} to a string representation. The format is as + described for \code{nmod_poly_print()}. The string must be freed by the + user when finished. For this it is sufficient to call \code{flint_free()}. + +int nmod_poly_set_str(nmod_poly_t poly, const char * s) + + Reads \code{poly} from a string \code{s}. The format is as described + for \code{nmod_poly_print()}. If a polynomial in the correct format + is read, a positive value is returned, otherwise a non-positive value + is returned. + +int nmod_poly_print(const nmod_poly_t a) + + Prints the polynomial to \code{stdout}. The length is printed, + followed by a space, then the modulus. If the length is zero this is + all that is printed, otherwise two spaces followed by a space + separated list of coefficients is printed, beginning with the constant + coefficient. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + +int nmod_poly_fread(FILE * f, nmod_poly_t poly) + + Reads \code{poly} from the file stream \code{f}. If this is a file + that has just been written, the file should be closed then opened + again. The format is as described for \code{nmod_poly_print()}. If a + polynomial in the correct format is read, a positive value is returned, + otherwise a non-positive value is returned. + +int nmod_poly_fprint(FILE * f, const nmod_poly_t poly) + + Writes a polynomial to the file stream \code{f}. If this is a file + then the file should be closed and reopened before being read. + The format is as described for \code{nmod_poly_print()}. If a + polynomial in the correct format is read, a positive value is returned, + otherwise a non-positive value is returned. If an error occurs + whilst writing to the file, an error message is printed. + + In case of success, returns a positive value. In case of failure, + returns a non-positive value. + +int nmod_poly_read(nmod_poly_t poly) + + Read \code{poly} from \code{stdin}. The format is as described for + \code{nmod_poly_print()}. If a polynomial in the correct format is read, a + positive value is returned, otherwise a non-positive value is returned. + +******************************************************************************* + + Comparison + +******************************************************************************* + +int nmod_poly_equal(const nmod_poly_t a, const nmod_poly_t b) + + Returns~$1$ if the polynomials are equal, otherwise~$0$. + +int nmod_poly_is_zero(const nmod_poly_t poly) + + Returns~$1$ if the polynomial \code{poly} is the zero polynomial, + otherwise returns~$0$. + +int nmod_poly_is_one(const nmod_poly_t poly) + + Returns~$1$ if the polynomial \code{poly} is the constant polynomial 1, + otherwise returns~$0$. + +******************************************************************************* + + Shifting + +******************************************************************************* + +void _nmod_poly_shift_left(mp_ptr res, mp_srcptr poly, slong len, slong k) + + Sets \code{(res, len + k)} to \code{(poly, len)} shifted left by + \code{k} coefficients. Assumes that \code{res} has space for + \code{len + k} coefficients. + +void nmod_poly_shift_left(nmod_poly_t res, const nmod_poly_t poly, slong k) + + Sets \code{res} to \code{poly} shifted left by \code{k} coefficients, + i.e.\ multiplied by $x^k$. + +void _nmod_poly_shift_right(mp_ptr res, mp_srcptr poly, slong len, slong k) + + Sets \code{(res, len - k)} to \code{(poly, len)} shifted left by + \code{k} coefficients. It is assumed that \code{k <= len} and that + \code{res} has space for at least \code{len - k} coefficients. + +void nmod_poly_shift_right(nmod_poly_t res, const nmod_poly_t poly, slong k) + + Sets \code{res} to \code{poly} shifted right by \code{k} coefficients, + i.e.\ divide by $x^k$ and throws away the remainder. If \code{k} is + greater than or equal to the length of \code{poly}, the result is the + zero polynomial. + +******************************************************************************* + + Addition and subtraction + +******************************************************************************* + +void _nmod_poly_add(mp_ptr res, mp_srcptr poly1, slong len1, + mp_srcptr poly2, slong len2, nmod_t mod) + + Sets \code{res} to the sum of \code{(poly1, len1)} and + \code{(poly2, len2)}. There are no restrictions on the lengths. + +void nmod_poly_add(nmod_poly_t res, const nmod_poly_t poly1, + const nmod_poly_t poly2) + + Sets \code{res} to the sum of \code{poly1} and \code{poly2}. + +void _nmod_poly_sub(mp_ptr res, mp_srcptr poly1, slong len1, + mp_srcptr poly2, slong len2, nmod_t mod) + + Sets \code{res} to the difference of \code{(poly1, len1)} and + \code{(poly2, len2)}. There are no restrictions on the lengths. + +void nmod_poly_sub(nmod_poly_t res, const nmod_poly_t poly1, + const nmod_poly_t poly2) + + Sets \code{res} to the difference of \code{poly1} and \code{poly2}. + +void nmod_poly_neg(nmod_poly_t res, const nmod_poly_t poly) + + Sets \code{res} to the negation of \code{poly}. + +******************************************************************************* + + Scalar multiplication and division + +******************************************************************************* + +void nmod_poly_scalar_mul_nmod(nmod_poly_t res, + const nmod_poly_t poly, ulong c) + + Sets \code{res} to \code{(poly, len)} multiplied by~$c$, + where~$c$ is reduced modulo the modulus of \code{poly}. + +void _nmod_poly_make_monic(mp_ptr output, + mp_srcptr input, slong len, nmod_t mod) + + Sets \code{output} to be the scalar multiple of \code{input} of + length \code{len > 0} that has leading coefficient one, if such a + polynomial exists. If the leading coefficient of \code{input} is not + invertible, \code{output} is set to the multiple of \code{input} whose + leading coefficient is the greatest common divisor of the leading + coefficient and the modulus of \code{input}. + +void nmod_poly_make_monic(nmod_poly_t output, const nmod_poly_t input) + + Sets \code{output} to be the scalar multiple of \code{input} with leading + coefficient one, if such a polynomial exists. If \code{input} is zero + an exception is raised. If the leading coefficient of \code{input} is not + invertible, \code{output} is set to the multiple of \code{input} whose + leading coefficient is the greatest common divisor of the leading + coefficient and the modulus of \code{input}. + +******************************************************************************* + + Bit packing and unpacking + +******************************************************************************* + +void _nmod_poly_bit_pack(mp_ptr res, mp_srcptr poly, slong len, + mp_bitcnt_t bits) + + Packs \code{len} coefficients of \code{poly} into fields of the given + number of bits in the large integer \code{res}, i.e.\ evaluates + \code{poly} at \code{2^bits} and store the result in \code{res}. + Assumes \code{len > 0} and \code{bits > 0}. Also assumes that no + coefficient of \code{poly} is bigger than \code{bits/2} bits. We + also assume \code{bits < 3 * FLINT_BITS}. + +void _nmod_poly_bit_unpack(mp_ptr res, slong len, + mp_srcptr mpn, ulong bits, nmod_t mod) + + Unpacks \code{len} coefficients stored in the big integer \code{mpn} + in bit fields of the given number of bits, reduces them modulo the + given modulus, then stores them in the polynomial \code{res}. + We assume \code{len > 0} and \code{3 * FLINT_BITS > bits > 0}. + There are no restrictions on the size of the actual coefficients as + stored within the bitfields. + +void nmod_poly_bit_pack(fmpz_t f, const nmod_poly_t poly, mp_bitcnt_t bit_size) + + Packs \code{poly} into bitfields of size \code{bit_size}, writing the + result to \code{f}. + +void nmod_poly_bit_unpack(nmod_poly_t poly, const fmpz_t f, + mp_bitcnt_t bit_size) + + Unpacks the polynomial from fields of size \code{bit_size} as + represented by the integer \code{f}. + + +void _nmod_poly_KS2_pack1(mp_ptr res, mp_srcptr op, slong n, slong s, + ulong b, ulong k, slong r) + + Same as \code{_nmod_poly_KS2_pack}, but requires \code{b <= FLINT_BITS}. + +void _nmod_poly_KS2_pack(mp_ptr res, mp_srcptr op, slong n, slong s, + ulong b, ulong k, slong r) + + Bit packing routine used by KS2 and KS4 multiplication. + +void _nmod_poly_KS2_unpack1(mp_ptr res, mp_srcptr op, slong n, ulong b, + ulong k) + + Same as \code{_nmod_poly_KS2_unpack}, but requires \code{b <= FLINT_BITS} + (i.e. writes one word per coefficient). + +void _nmod_poly_KS2_unpack2(mp_ptr res, mp_srcptr op, slong n, ulong b, + ulong k) + + Same as \code{_nmod_poly_KS2_unpack}, but requires + \code{FLINT_BITS < b <= 2 * FLINT_BITS} (i.e. writes two words per + coefficient). + +void _nmod_poly_KS2_unpack3(mp_ptr res, mp_srcptr op, slong n, ulong b, + ulong k) + + Same as \code{_nmod_poly_KS2_unpack}, but requires + \code{2 * FLINT_BITS < b < 3 * FLINT_BITS} (i.e. writes three words per + coefficient). + +void _nmod_poly_KS2_unpack(mp_ptr res, mp_srcptr op, slong n, ulong b, + ulong k) + + Bit unpacking code used by KS2 and KS4 multiplication. + + +******************************************************************************* + + KS2/KS4 Reduction + +******************************************************************************* + +void _nmod_poly_KS2_reduce(mp_ptr res, slong s, mp_srcptr op, slong n, ulong w, + nmod_t mod) + + Reduction code used by KS2 and KS4 multiplication. + +void _nmod_poly_KS2_recover_reduce1(mp_ptr res, slong s, mp_srcptr op1, + mp_srcptr op2, slong n, ulong b, nmod_t mod) + + Same as \code{_nmod_poly_KS2_recover_reduce}, but requires + \code{0 < 2 * b <= FLINT_BITS}. + +void _nmod_poly_KS2_recover_reduce2(mp_ptr res, slong s, mp_srcptr op1, + mp_srcptr op2, slong n, ulong b, nmod_t mod) + + Same as \code{_nmod_poly_KS2_recover_reduce}, but requires + \code{FLINT_BITS < 2 * b < 2*FLINT_BITS}. + +void _nmod_poly_KS2_recover_reduce2b(mp_ptr res, slong s, mp_srcptr op1, + mp_srcptr op2, slong n, ulong b, nmod_t mod) + + Same as \code{_nmod_poly_KS2_recover_reduce}, but requires + \code{b == FLINT_BITS}. + +void _nmod_poly_KS2_recover_reduce3(mp_ptr res, slong s, mp_srcptr op1, + mp_srcptr op2, slong n, ulong b, nmod_t mod) + + Same as \code{_nmod_poly_KS2_recover_reduce}, but requires + \code{2 * FLINT_BITS < 2 * b <= 3 * FLINT_BITS}. + +void _nmod_poly_KS2_recover_reduce(mp_ptr res, slong s, mp_srcptr op1, + mp_srcptr op2, slong n, ulong b, nmod_t mod) + + Reduction code used by KS4 multiplication. + + +******************************************************************************* + + Multiplication + +******************************************************************************* + +void _nmod_poly_mul_classical(mp_ptr res, mp_srcptr poly1, + slong len1, mp_srcptr poly2, slong len2, nmod_t mod) + + Sets \code{(res, len1 + len2 - 1)} to the product of \code{(poly1, len1)} + and \code{(poly2, len2)}. Assumes \code{len1 >= len2 > 0}. Aliasing of + inputs and output is not permitted. + +void nmod_poly_mul_classical(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_poly_t poly2) + + Sets \code{res} to the product of \code{poly1} and \code{poly2}. + +void _nmod_poly_mullow_classical(mp_ptr res, mp_srcptr poly1, slong len1, + mp_srcptr poly2, slong len2, slong trunc, nmod_t mod) + + Sets \code{res} to the lower \code{trunc} coefficients of the product of + \code{(poly1, len1)} and \code{(poly2, len2)}. Assumes that + \code{len1 >= len2 > 0} and \code{trunc > 0}. Aliasing of inputs and + output is not permitted. + +void nmod_poly_mullow_classical(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_poly_t poly2, slong trunc) + + Sets \code{res} to the lower \code{trunc} coefficients of the product + of \code{poly1} and \code{poly2}. + +void _nmod_poly_mulhigh_classical(mp_ptr res, mp_srcptr poly1, + slong len1, mp_srcptr poly2, slong len2, slong start, nmod_t mod) + + Computes the product of \code{(poly1, len1)} and \code{(poly2, len2)} + and writes the coefficients from \code{start} onwards into the high + coefficients of \code{res}, the remaining coefficients being arbitrary + but reduced. Assumes that \code{len1 >= len2 > 0}. Aliasing of inputs + and output is not permitted. + +void nmod_poly_mulhigh_classical(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_poly_t poly2, slong start) + + Computes the product of \code{poly1} and \code{poly2} and writes the + coefficients from \code{start} onwards into the high coefficients of + \code{res}, the remaining coefficients being arbitrary but reduced. + +void _nmod_poly_mul_KS(mp_ptr out, mp_srcptr in1, slong len1, + mp_srcptr in2, slong len2, mp_bitcnt_t bits, nmod_t mod) + + Sets \code{res} to the product of \code{in1} and \code{in2} + assuming the output coefficients are at most the given number of + bits wide. If \code{bits} is set to $0$ an appropriate value is + computed automatically. Assumes that \code{len1 >= len2 > 0}. + +void nmod_poly_mul_KS(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_poly_t poly2, mp_bitcnt_t bits) + + Sets \code{res} to the product of \code{poly1} and \code{poly2} + assuming the output coefficients are at most the given number of + bits wide. If \code{bits} is set to $0$ an appropriate value + is computed automatically. + +void _nmod_poly_mul_KS2(mp_ptr res, mp_srcptr op1, slong n1, + mp_srcptr op2, slong n2, nmod_t mod) + + Sets \code{res} to the product of \code{op1} and \code{op2}. + Assumes that \code{len1 >= len2 > 0}. + +void nmod_poly_mul_KS2(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_poly_t poly2) + + Sets \code{res} to the product of \code{poly1} and \code{poly2}. + +void _nmod_poly_mul_KS4(mp_ptr res, mp_srcptr op1, slong n1, + mp_srcptr op2, slong n2, nmod_t mod) + + Sets \code{res} to the product of \code{op1} and \code{op2}. + Assumes that \code{len1 >= len2 > 0}. + +void nmod_poly_mul_KS4(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_poly_t poly2) + + Sets \code{res} to the product of \code{poly1} and \code{poly2}. + +void _nmod_poly_mullow_KS(mp_ptr out, mp_srcptr in1, slong len1, + mp_srcptr in2, slong len2, mp_bitcnt_t bits, slong n, nmod_t mod) + + Sets \code{out} to the low $n$ coefficients of \code{in1} of length + \code{len1} times \code{in2} of length \code{len2}. The output must have + space for \code{n} coefficients. We assume that \code{len1 >= len2 > 0} + and that \code{0 < n <= len1 + len2 - 1}. + +void nmod_poly_mullow_KS(nmod_poly_t res, const nmod_poly_t poly1, + const nmod_poly_t poly2, mp_bitcnt_t bits, slong n) + + Set \code{res} to the low $n$ coefficients of \code{in1} of length + \code{len1} times \code{in2} of length \code{len2}. + +void _nmod_poly_mul(mp_ptr res, mp_srcptr poly1, slong len1, + mp_srcptr poly2, slong len2, nmod_t mod) + + Sets \code{res} to the product of \code{poly1} of length \code{len1} + and \code{poly2} of length \code{len2}. Assumes \code{len1 >= len2 > 0}. + No aliasing is permitted between the inputs and the output. + +void nmod_poly_mul(nmod_poly_t res, + const nmod_poly_t poly, const nmod_poly_t poly2) + + Sets \code{res} to the product of \code{poly1} and \code{poly2}. + +void _nmod_poly_mullow(mp_ptr res, mp_srcptr poly1, slong len1, + mp_srcptr poly2, slong len2, slong n, nmod_t mod) + + Sets \code{res} to the first \code{n} coefficients of the + product of \code{poly1} of length \code{len1} and \code{poly2} of + length \code{len2}. It is assumed that \code{0 < n <= len1 + len2 - 1} + and that \code{len1 >= len2 > 0}. No aliasing of inputs and output + is permitted. + +void nmod_poly_mullow(nmod_poly_t res, const nmod_poly_t poly1, + const nmod_poly_t poly2, slong trunc) + + Sets \code{res} to the first \code{trunc} coefficients of the + product of \code{poly1} and \code{poly2}. + +void _nmod_poly_mulhigh(mp_ptr res, mp_srcptr poly1, slong len1, + mp_srcptr poly2, slong len2, slong n, nmod_t mod) + + Sets all but the low $n$ coefficients of \code{res} to the + corresponding coefficients of the product of \code{poly1} of length + \code{len1} and \code{poly2} of length \code{len2}, the other + coefficients being arbitrary. It is assumed that + \code{len1 >= len2 > 0} and that \code{0 < n <= len1 + len2 - 1}. + Aliasing of inputs and output is not permitted. + +void nmod_poly_mulhigh(nmod_poly_t res, const nmod_poly_t poly1, + const nmod_poly_t poly2, slong n) + + Sets all but the low $n$ coefficients of \code{res} to the + corresponding coefficients of the product of \code{poly1} and + \code{poly2}, the remaining coefficients being arbitrary. + +void _nmod_poly_mulmod(mp_ptr res, mp_srcptr poly1, slong len1, + mp_srcptr poly2, slong len2, mp_srcptr f, + slong lenf, nmod_t mod) + + Sets \code{res} to the remainder of the product of \code{poly1} and + \code{poly2} upon polynomial division by \code{f}. + + It is required that \code{len1 + len2 - lenf > 0}, which is equivalent + to requiring that the result will actually be reduced. Otherwise, simply + use \code{_nmod_poly_mul} instead. + + Aliasing of \code{f} and \code{res} is not permitted. + +void nmod_poly_mulmod(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_poly_t poly2, const nmod_poly_t f) + + Sets \code{res} to the remainder of the product of \code{poly1} and + \code{poly2} upon polynomial division by \code{f}. + +void _nmod_poly_mulmod_preinv(mp_ptr res, mp_srcptr poly1, slong len1, + mp_srcptr poly2, slong len2, mp_srcptr f, + slong lenf, mp_srcptr finv, slong lenfinv, nmod_t mod) + + Sets \code{res} to the remainder of the product of \code{poly1} and + \code{poly2} upon polynomial division by \code{f}. + + It is required that \code{finv} is the inverse of the reverse of \code{f} + mod \code{x^lenf}. It is required that \code{len1 + len2 - lenf > 0}, + which is equivalent to requiring that the result will actually be reduced. + It is required that \code{len1 < lenf} and \code{len2 < lenf}. + Otherwise, simply use \code{_nmod_poly_mul} instead. + + Aliasing of \code{f} or \code{finv} and \code{res} is not permitted. + +void nmod_poly_mulmod_preinv(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_poly_t poly2, const nmod_poly_t f, + const nmod_poly_t finv) + + Sets \code{res} to the remainder of the product of \code{poly1} and + \code{poly2} upon polynomial division by \code{f}. \code{finv} is the + inverse of the reverse of \code{f}. It is required that \code{poly1} and + \code{poly2} are reduced modulo \code{f}. + +******************************************************************************* + + Powering + +******************************************************************************* + +void _nmod_poly_pow_binexp(mp_ptr res, + mp_srcptr poly, slong len, ulong e, nmod_t mod) + + Raises \code{poly} of length \code{len} to the power \code{e} and sets + \code{res} to the result. We require that \code{res} has enough space + for \code{(len - 1)*e + 1} coefficients. Assumes that \code{len > 0}, + \code{e > 1}. Aliasing is not permitted. Uses the binary exponentiation + method. + +void nmod_poly_pow_binexp(nmod_poly_t res, const nmod_poly_t poly, ulong e) + + Raises \code{poly} to the power \code{e} and sets \code{res} to the + result. Uses the binary exponentiation method. + +void _nmod_poly_pow(mp_ptr res, + mp_srcptr poly, slong len, ulong e, nmod_t mod) + + Raises \code{poly} of length \code{len} to the power \code{e} and sets + \code{res} to the result. We require that \code{res} has enough space + for \code{(len - 1)*e + 1} coefficients. Assumes that \code{len > 0}, + \code{e > 1}. Aliasing is not permitted. + +void nmod_poly_pow(nmod_poly_t res, const nmod_poly_t poly, ulong e) + + Raises \code{poly} to the power \code{e} and sets \code{res} to the + result. + +void _nmod_poly_pow_trunc_binexp(mp_ptr res, mp_srcptr poly, + ulong e, slong trunc, nmod_t mod) + + Sets \code{res} to the low \code{trunc} coefficients of \code{poly} + (assumed to be zero padded if necessary to length \code{trunc}) to + the power \code{e}. This is equivalent to doing a powering followed + by a truncation. We require that \code{res} has enough space for + \code{trunc} coefficients, that \code{trunc > 0} and that + \code{e > 1}. Aliasing is not permitted. Uses the binary + exponentiation method. + +void nmod_poly_pow_trunc_binexp(nmod_poly_t res, + const nmod_poly_t poly, ulong e, slong trunc) + + Sets \code{res} to the low \code{trunc} coefficients of \code{poly} + to the power \code{e}. This is equivalent to doing a powering + followed by a truncation. Uses the binary exponentiation method. + +void _nmod_poly_pow_trunc(mp_ptr res, mp_srcptr poly, + ulong e, slong trunc, nmod_t mod) + + Sets \code{res} to the low \code{trunc} coefficients of \code{poly} + (assumed to be zero padded if necessary to length \code{trunc}) to + the power \code{e}. This is equivalent to doing a powering followed + by a truncation. We require that \code{res} has enough space for + \code{trunc} coefficients, that \code{trunc > 0} and that + \code{e > 1}. Aliasing is not permitted. + +void nmod_poly_pow_trunc(nmod_poly_t res, + const nmod_poly_t poly, ulong e, slong trunc) + + Sets \code{res} to the low \code{trunc} coefficients of \code{poly} + to the power \code{e}. This is equivalent to doing a powering + followed by a truncation. + +void _nmod_poly_powmod_ui_binexp(mp_ptr res, mp_srcptr poly, + ulong e, mp_srcptr f, + slong lenf, nmod_t mod) + + Sets \code{res} to \code{poly} raised to the power \code{e} + modulo \code{f}, using binary exponentiation. We require \code{e > 0}. + + We require \code{lenf > 1}. It is assumed that \code{poly} is already + reduced modulo \code{f} and zero-padded as necessary to have length + exactly \code{lenf - 1}. The output \code{res} must have room for + \code{lenf - 1} coefficients. + +void nmod_poly_powmod_ui_binexp(nmod_poly_t res, + const nmod_poly_t poly, ulong e, + const nmod_poly_t f) + + Sets \code{res} to \code{poly} raised to the power \code{e} + modulo \code{f}, using binary exponentiation. We require \code{e >= 0}. + +void +_nmod_poly_powmod_ui_binexp_preinv (mp_ptr res, mp_srcptr poly, + ulong e, mp_srcptr f, slong lenf, + mp_srcptr finv, slong lenfinv, nmod_t mod) + + Sets \code{res} to \code{poly} raised to the power \code{e} + modulo \code{f}, using binary exponentiation. We require \code{e > 0}. + We require \code{finv} to be the inverse of the reverse of \code{f}. + + We require \code{lenf > 1}. It is assumed that \code{poly} is already + reduced modulo \code{f} and zero-padded as necessary to have length + exactly \code{lenf - 1}. The output \code{res} must have room for + \code{lenf - 1} coefficients. + +void +nmod_poly_powmod_ui_binexp_preinv(nmod_poly_t res, + const nmod_poly_t poly, ulong e, + const nmod_poly_t f, const nmod_poly_t finv) + + Sets \code{res} to \code{poly} raised to the power \code{e} + modulo \code{f}, using binary exponentiation. We require \code{e >= 0}. + We require \code{finv} to be the inverse of the reverse of \code{f}. + +void +_nmod_poly_powmod_x_ui_preinv (mp_ptr res, ulong e, mp_srcptr f, slong lenf, + mp_srcptr finv, slong lenfinv, nmod_t mod) + + Sets \code{res} to \code{x} raised to the power \code{e} modulo \code{f}, + using sliding window exponentiation. We require \code{e > 0}. + We require \code{finv} to be the inverse of the reverse of \code{f}. + + We require \code{lenf > 2}. The output \code{res} must have room for + \code{lenf - 1} coefficients. + +void +nmod_poly_powmod_x_ui_preinv(nmod_poly_t res, ulong e, const nmod_poly_t f, + const nmod_poly_t finv) + + Sets \code{res} to \code{x} raised to the power \code{e} + modulo \code{f}, using sliding window exponentiation. We require + \code{e >= 0}. We require \code{finv} to be the inverse of the reverse of + \code{f}. + +void _nmod_poly_powmod_mpz_binexp(mp_ptr res, mp_srcptr poly, + mpz_srcptr e, mp_srcptr f, + slong lenf, nmod_t mod) + + Sets \code{res} to \code{poly} raised to the power \code{e} + modulo \code{f}, using binary exponentiation. We require \code{e > 0}. + + We require \code{lenf > 1}. It is assumed that \code{poly} is already + reduced modulo \code{f} and zero-padded as necessary to have length + exactly \code{lenf - 1}. The output \code{res} must have room for + \code{lenf - 1} coefficients. + +void nmod_poly_powmod_mpz_binexp(nmod_poly_t res, + const nmod_poly_t poly, mpz_srcptr e, + const nmod_poly_t f) + + Sets \code{res} to \code{poly} raised to the power \code{e} + modulo \code{f}, using binary exponentiation. We require \code{e >= 0}. + +void +_nmod_poly_powmod_mpz_binexp_preinv (mp_ptr res, mp_srcptr poly, + mpz_srcptr e, mp_srcptr f, slong lenf, + mp_srcptr finv, slong lenfinv, nmod_t mod) + + Sets \code{res} to \code{poly} raised to the power \code{e} + modulo \code{f}, using binary exponentiation. We require \code{e > 0}. + We require \code{finv} to be the inverse of the reverse of \code{f}. + + We require \code{lenf > 1}. It is assumed that \code{poly} is already + reduced modulo \code{f} and zero-padded as necessary to have length + exactly \code{lenf - 1}. The output \code{res} must have room for + \code{lenf - 1} coefficients. + +void +nmod_poly_powmod_mpz_binexp_preinv(nmod_poly_t res, + const nmod_poly_t poly, mpz_srcptr e, + const nmod_poly_t f, const nmod_poly_t finv) + + Sets \code{res} to \code{poly} raised to the power \code{e} + modulo \code{f}, using binary exponentiation. We require \code{e >= 0}. + We require \code{finv} to be the inverse of the reverse of \code{f}. + +******************************************************************************* + + Division + +******************************************************************************* + +void _nmod_poly_divrem_basecase(mp_ptr Q, mp_ptr R, mp_ptr W, + mp_srcptr A, slong A_len, mp_srcptr B, slong B_len, nmod_t mod) + + Finds $Q$ and $R$ such that $A = B Q + R$ with $\len(R) < \len(B)$. + If $\len(B) = 0$ an exception is raised. We require that \code{W} + is temporary space of \code{NMOD_DIVREM_BC_ITCH(A_len, B_len, mod)} + coefficients. + +void nmod_poly_divrem_basecase(nmod_poly_t Q, + nmod_poly_t R, const nmod_poly_t A, const nmod_poly_t B) + + Finds $Q$ and $R$ such that $A = B Q + R$ with $\len(R) < \len(B)$. + If $\len(B) = 0$ an exception is raised. + +void _nmod_poly_div_basecase(mp_ptr Q, mp_ptr W, mp_srcptr A, slong A_len, + mp_srcptr B, slong B_len, nmod_t mod); + + Notionally finds polynomials $Q$ and $R$ such that $A = B Q + R$ with + $\len(R) < \len(B)$, but returns only \code{Q}. If $\len(B) = 0$ an + exception is raised. We require that \code{W} is temporary space of + \code{NMOD_DIV_BC_ITCH(A_len, B_len, mod)} coefficients. + +void nmod_poly_div_basecase(nmod_poly_t Q, const nmod_poly_t A, + const nmod_poly_t B); + + Notionally finds polynomials $Q$ and $R$ such that $A = B Q + R$ with + $\len(R) < \len(B)$, but returns only \code{Q}. If $\len(B) = 0$ an + exception is raised. + +void _nmod_poly_divrem_divconquer_recursive(mp_ptr Q, mp_ptr BQ, mp_ptr W, + mp_ptr V, mp_srcptr A, mp_srcptr B, slong lenB, nmod_t mod) + + Computes $Q$ and $R$ such that $A = BQ + R$ with $\len(R)$ less than + \code{lenB}, where \code{A} is of length \code{2 * lenB - 1} and \code{B} + is of length \code{lenB}. Sets \code{BQ} to the low \code{lenB - 1} + coefficients of \code{B * Q}. We require that \code{Q} have space for + \code{lenB} coefficients, that \code{W} be temporary space of size + \code{lenB - 1} and \code{V} be temporary space for a number of + coefficients computed by \code{NMOD_DIVREM_DC_ITCH(lenB, mod)}. + +void _nmod_poly_divrem_divconquer(mp_ptr Q, mp_ptr R, + mp_srcptr A, slong lenA, mp_srcptr B, slong lenB, nmod_t mod) + + Computes $Q$ and $R$ such that $A = BQ + R$ with $\len(R)$ less than + \code{lenB}, where \code{A} is of length \code{lenA} and \code{B} is of + length \code{lenB}. We require that \code{Q} have space for + \code{lenA - lenB + 1} coefficients. + +void nmod_poly_divrem_divconquer(nmod_poly_t Q, nmod_poly_t R, + const nmod_poly_t A, const nmod_poly_t B) + + Computes $Q$ and $R$ such that $A = BQ + R$ with $\len(R) < \len(B)$. + +void _nmod_poly_divrem_q0(mp_ptr Q, mp_ptr R, + mp_srcptr A, mp_srcptr B, slong lenA, nmod_t mod) + + Computes $Q$ and $R$ such that $A = BQ + R$ with $\len(R) < \len(B)$, + where $\len(A) = \len(B) > 0$. + + Requires that $Q$ and $R$ have space for $1$ and $\len(B) - 1$ + coefficients, respectively. + + Does not support aliasing or zero-padding. + +void _nmod_poly_divrem_q1(mp_ptr Q, mp_ptr R, + mp_srcptr A, slong lenA, mp_srcptr B, slong lenB, + nmod_t mod) + + Computes $Q$ and $R$ such that $A = BQ + R$ with $\len(R) < \len(B)$, + where $\len(A) = \len(B) + 1 \geq \len(B) > 0$. + + Requires that $Q$ and $R$ have space for $\len(A) - \len(B) + 1$ and + $\len(B) - 1$ coefficients, respectively. + + Does not support aliasing or zero-padding. + +void _nmod_poly_divrem(mp_ptr Q, mp_ptr R, + mp_srcptr A, slong lenA, mp_srcptr B, slong lenB, nmod_t mod) + + Computes $Q$ and $R$ such that $A = BQ + R$ with $\len(R)$ less than + \code{lenB}, where \code{A} is of length \code{lenA} and \code{B} is of + length \code{lenB}. We require that \code{Q} have space for + \code{lenA - lenB + 1} coefficients. + +void nmod_poly_divrem(nmod_poly_t Q, nmod_poly_t R, + const nmod_poly_t A, const nmod_poly_t B) + + Computes $Q$ and $R$ such that $A = BQ + R$ with $\len(R) < \len(B)$. + +void _nmod_poly_div_divconquer_recursive(mp_ptr Q, mp_ptr W, mp_ptr V, + mp_srcptr A, mp_srcptr B, slong lenB, nmod_t mod) + + Computes $Q$ and $R$ such that $A = BQ + R$ with $\len(R)$ less than + \code{lenB}, where \code{A} is of length \code{2 * lenB - 1} and \code{B} + is of length \code{lenB}. We require that \code{Q} have space for + \code{lenB} coefficients and that \code{W} be temporary space of size + \code{lenB - 1} and \code{V} be temporary space for a number of + coefficients computed by \code{NMOD_DIV_DC_ITCH(lenB, mod)}. + +void _nmod_poly_div_divconquer(mp_ptr Q, mp_srcptr A, slong lenA, + mp_srcptr B, slong lenB, nmod_t mod) + + Notionally computes polynomials $Q$ and $R$ such that $A = BQ + R$ with + $\len(R)$ less than \code{lenB}, where \code{A} is of length \code{lenA} + and \code{B} is of length \code{lenB}, but returns only \code{Q}. We + require that \code{Q} have space for \code{lenA - lenB + 1} coefficients. + +void nmod_poly_div_divconquer(nmod_poly_t Q, + const nmod_poly_t A, const nmod_poly_t B) + + Notionally computes $Q$ and $R$ such that $A = BQ + R$ with + $\len(R) < \len(B)$, but returns only $Q$. + +void _nmod_poly_div(mp_ptr Q, mp_srcptr A, slong lenA, + mp_srcptr B, slong lenB, nmod_t mod) + + Notionally computes polynomials $Q$ and $R$ such that $A = BQ + R$ with + $\len(R)$ less than \code{lenB}, where \code{A} is of length \code{lenA} + and \code{B} is of length \code{lenB}, but returns only \code{Q}. We + require that \code{Q} have space for \code{lenA - lenB + 1} coefficients. + + +void nmod_poly_div(nmod_poly_t Q, const nmod_poly_t A, const nmod_poly_t B) + + Computes the quotient $Q$ on polynomial division of $A$ and $B$. + +void _nmod_poly_rem_basecase(mp_ptr R, mp_ptr W, mp_srcptr A, slong lenA, + mp_srcptr B, slong lenB, nmod_t mod) + +void nmod_poly_rem_basecase(nmod_poly_t R, + const nmod_poly_t A, const nmod_poly_t B) + +void _nmod_poly_rem_q1(mp_ptr R, + mp_srcptr A, slong lenA, mp_srcptr B, slong lenB, + nmod_t mod) + + Notationally, computes $Q$ and $R$ such that $A = BQ + R$ with + $\len(R) < \len(B)$, where $\len(A) = \len(B) + 1 \geq \len(B) > 0$, + but returns only the remainder. + + Requires that $R$ has space for $\len(B) - 1$ coefficients, + respectively. + + Does not support aliasing or zero-padding. + +void _nmod_poly_rem(mp_ptr R, mp_srcptr A, slong lenA, + mp_srcptr B, slong lenB, nmod_t mod) + + Computes the remainder $R$ on polynomial division of $A$ by $B$. + +void nmod_poly_rem(nmod_poly_t R, const nmod_poly_t A, const nmod_poly_t B) + + Computes the remainder $R$ on polynomial division of $A$ by $B$. + +void _nmod_poly_inv_series_basecase(mp_ptr Qinv, + mp_srcptr Q, slong n, nmod_t mod) + + Given \code{Q} of length \code{n} whose leading coefficient is invertible + modulo the given modulus, finds a polynomial \code{Qinv} of length \code{n} + such that the top \code{n} coefficients of the product \code{Q * Qinv} is + $x^{n - 1}$. Requires that \code{n > 0}. This function can be viewed as + inverting a power series. + +void nmod_poly_inv_series_basecase(nmod_poly_t Qinv, + const nmod_poly_t Q, slong n) + + Given \code{Q} of length at least \code{n} find \code{Qinv} of length + \code{n} such that the top \code{n} coefficients of the product + \code{Q * Qinv} is $x^{n - 1}$. An exception is raised if \code{n = 0} + or if the length of \code{Q} is less than \code{n}. The leading + coefficient of \code{Q} must be invertible modulo the modulus of + \code{Q}. This function can be viewed as inverting a power series. + +void +_nmod_poly_inv_series_newton(mp_ptr Qinv, mp_srcptr Q, slong n, nmod_t mod) + + Given \code{Q} of length \code{n} whose constant coefficient is invertible + modulo the given modulus, find a polynomial \code{Qinv} of length \code{n} + such that \code{Q * Qinv} is \code{1} modulo $x^n$. Requires \code{n > 0}. + This function can be viewed as inverting a power series via Newton + iteration. + +void +nmod_poly_inv_series_newton(nmod_poly_t Qinv, const nmod_poly_t Q, slong n) + + Given \code{Q} find \code{Qinv} such that \code{Q * Qinv} is \code{1} + modulo $x^n$. The constant coefficient of \code{Q} must be invertible + modulo the modulus of \code{Q}. An exception is raised if this is not + the case or if \code{n = 0}. This function can be viewed as inverting + a power series via Newton iteration. + +void _nmod_poly_inv_series(mp_ptr Qinv, mp_srcptr Q, slong n, nmod_t mod) + + Given \code{Q} of length \code{n} whose constant coefficient is invertible + modulo the given modulus, find a polynomial \code{Qinv} of length \code{n} + such that \code{Q * Qinv} is \code{1} modulo $x^n$. Requires \code{n > 0}. + This function can be viewed as inverting a power series. + +void nmod_poly_inv_series(nmod_poly_t Qinv, const nmod_poly_t Q, slong n) + + Given \code{Q} find \code{Qinv} such that \code{Q * Qinv} is \code{1} + modulo $x^n$. The constant coefficient of \code{Q} must be invertible + modulo the modulus of \code{Q}. An exception is raised if this is not + the case or if \code{n = 0}. This function can be viewed as inverting + a power series. + +void _nmod_poly_div_series(mp_ptr Q, mp_srcptr A, mp_srcptr B, + slong n, nmod_t mod) + + Given polynomials \code{A} and \code{B} of length \code{n}, finds the + polynomial \code{Q} of length \code{n} such that \code{Q * B = A} + modulo $x^n$. We assume \code{n > 0} and that the constant coefficient + of \code{B} is invertible modulo the given modulus. The polynomial + \code{Q} must have space for \code{n} coefficients. + +void nmod_poly_div_series(nmod_poly_t Q, const nmod_poly_t A, + const nmod_poly_t B, slong n) + + Given polynomials \code{A} and \code{B} considered modulo \code{n}, + finds the polynomial \code{Q} of length at most \code{n} such that + \code{Q * B = A} modulo $x^n$. We assume \code{n > 0} and that the + constant coefficient of \code{B} is invertible modulo the modulus. + An exception is raised if \code{n == 0} or the constant coefficient + of \code{B} is zero. + +void _nmod_poly_div_newton(mp_ptr Q, mp_srcptr A, slong Alen, + mp_srcptr B, slong Blen, nmod_t mod) + + Notionally computes polynomials $Q$ and $R$ such that $A = BQ + R$ with + $\len(R)$ less than \code{lenB}, where \code{A} is of length \code{lenA} + and \code{B} is of length \code{lenB}, but return only $Q$. + + We require that $Q$ have space for \code{lenA - lenB + 1} coefficients + and assume that the leading coefficient of $B$ is a unit. + + The algorithm used is to reverse the polynomials and divide the + resulting power series, then reverse the result. + +void nmod_poly_div_newton(nmod_poly_t Q, const nmod_poly_t A, + const nmod_poly_t B) + + Notionally computes $Q$ and $R$ such that $A = BQ + R$ with + $\len(R) < \len(B)$, but returns only $Q$. + + We assume that the leading coefficient of $B$ is a unit. + + The algorithm used is to reverse the polynomials and divide the + resulting power series, then reverse the result. + +void _nmod_poly_div_newton_n_preinv (mp_ptr Q, mp_srcptr A, slong lenA, + mp_srcptr B, slong lenB, mp_srcptr Binv, slong lenBinv, nmod_t mod) + + Notionally computes polynomials $Q$ and $R$ such that $A = BQ + R$ with + $\len(R)$ less than \code{lenB}, where \code{A} is of length \code{lenA} + and \code{B} is of length \code{lenB}, but return only $Q$. + + We require that $Q$ have space for \code{lenA - lenB + 1} coefficients + and assume that the leading coefficient of $B$ is a unit. Furthermore, we + assume that $Binv$ is the inverse of the reverse of $B$ mod $x^{\len(B)}$. + + The algorithm used is to reverse the polynomials and divide the + resulting power series, then reverse the result. + +void nmod_poly_div_newton_n_preinv (nmod_poly_t Q, const nmod_poly_t A, + const nmod_poly_t B, const nmod_poly_t Binv) + + Notionally computes $Q$ and $R$ such that $A = BQ + R$ with + $\len(R) < \len(B)$, but returns only $Q$. + + We assume that the leading coefficient of $B$ is a unit and that $Binv$ is + the inverse of the reverse of $B$ mod $x^{\len(B)}$. + + It is required that the length of $A$ is less than or equal to + 2*the length of $B$ - 2. + + The algorithm used is to reverse the polynomials and divide the + resulting power series, then reverse the result. + +void _nmod_poly_divrem_newton(mp_ptr Q, mp_ptr R, mp_srcptr A, slong Alen, + mp_srcptr B, slong Blen, nmod_t mod) + + Computes $Q$ and $R$ such that $A = BQ + R$ with $\len(R)$ less than + \code{lenB}, where $A$ is of length \code{lenA} and $B$ is of length + \code{lenB}. We require that $Q$ have space for \code{lenA - lenB + 1} + coefficients. The algorithm used is to call \code{div_newton()} and then + multiply out and compute the remainder. + +void nmod_poly_divrem_newton(nmod_poly_t Q, nmod_poly_t R, + const nmod_poly_t A, const nmod_poly_t B) + + Computes $Q$ and $R$ such that $A = BQ + R$ with $\len(R) < \len(B)$. + The algorithm used is to call \code{div_newton()} and then multiply out + and compute the remainder. + +void _nmod_poly_divrem_newton_n_preinv (mp_ptr Q, mp_ptr R, mp_srcptr A, +slong lenA, mp_srcptr B, slong lenB, mp_srcptr Binv, slong lenBinv, nmod_t mod) + + Computes $Q$ and $R$ such that $A = BQ + R$ with $\len(R)$ less than + \code{lenB}, where $A$ is of length \code{lenA} and $B$ is of length + \code{lenB}. We require that $Q$ have space for \code{lenA - lenB + 1} + coefficients. Furthermore, we assume that $Binv$ is the inverse of the + reverse of $B$ mod $x^{\len(B)}$. The algorithm used is to call + \code{div_newton_n_preinv()} and then multiply out and compute + the remainder. + +void nmod_poly_divrem_newton_n_preinv(nmod_poly_t Q, nmod_poly_t R, + const nmod_poly_t A, const nmod_poly_t B, const nmod_poly_t Binv) + + Computes $Q$ and $R$ such that $A = BQ + R$ with $\len(R) < \len(B)$. + We assume $Binv$ is the inverse of the reverse of $B$ mod $x^{\len(B)}$. + + It is required that the length of $A$ is less than or equal to + 2*the length of $B$ - 2. + + The algorithm used is to call \code{div_newton_n()} and then multiply out + and compute the remainder. + +mp_limb_t _nmod_poly_div_root(mp_ptr Q, mp_srcptr A, slong len, + mp_limb_t c, nmod_t mod) + + Sets \code{(Q, len-1)} to the quotient of \code{(A, len)} on division + by $(x - c)$, and returns the remainder, equal to the value of $A$ + evaluated at $c$. $A$ and $Q$ are allowed to be the same, but may + not overlap partially in any other way. + +mp_limb_t nmod_poly_div_root(nmod_poly_t Q, const nmod_poly_t A, mp_limb_t c) + + Sets $Q$ to the quotient of $A$ on division by $(x - c)$, and returns + the remainder, equal to the value of $A$ evaluated at $c$. + +******************************************************************************* + + Derivative and integral + +******************************************************************************* + +void _nmod_poly_derivative(mp_ptr x_prime, mp_srcptr x, slong len, nmod_t mod) + + Sets the first \code{len - 1} coefficients of \code{x_prime} to the + derivative of \code{x} which is assumed to be of length \code{len}. + It is assumed that \code{len > 0}. + +void nmod_poly_derivative(nmod_poly_t x_prime, const nmod_poly_t x) + + Sets \code{x_prime} to the derivative of \code{x}. + +void _nmod_poly_integral(mp_ptr x_int, mp_srcptr x, slong len, nmod_t mod) + + Set the first \code{len} coefficients of \code{x_int} to the + integral of \code{x} which is assumed to be of length \code{len - 1}. + The constant term of \code{x_int} is set to zero. + It is assumed that \code{len > 0}. The result is only well-defined + if the modulus is a prime number strictly larger than the degree of + \code{x}. + +void nmod_poly_integral(nmod_poly_t x_int, const nmod_poly_t x) + + Set \code{x_int} to the indefinite integral of \code{x} with constant + term zero. The result is only well-defined if the modulus + is a prime number strictly larger than the degree of \code{x}. + + +******************************************************************************* + + Evaluation + +******************************************************************************* + +mp_limb_t _nmod_poly_evaluate_nmod(mp_srcptr poly, slong len, mp_limb_t c, + nmod_t mod) + + Evaluates \code{poly} at the value~\code{c} and reduces modulo the + given modulus of \code{poly}. The value~\code{c} should be reduced + modulo the modulus. The algorithm used is Horner's method. + +mp_limb_t nmod_poly_evaluate_nmod(nmod_poly_t poly, mp_limb_t c) + + Evaluates \code{poly} at the value~\code{c} and reduces modulo the + modulus of \code{poly}. The value~\code{c} should be reduced modulo + the modulus. The algorithm used is Horner's method. + +******************************************************************************* + + Multipoint evaluation + +******************************************************************************* + +void _nmod_poly_evaluate_nmod_vec_iter(mp_ptr ys, mp_srcptr poly, slong len, + mp_srcptr xs, slong n, nmod_t mod) + + Evaluates (\code{coeffs}, \code{len}) at the \code{n} values + given in the vector \code{xs}, writing the output values + to \code{ys}. The values in \code{xs} should be reduced + modulo the modulus. + + Uses Horner's method iteratively. + +void nmod_poly_evaluate_nmod_vec_iter(mp_ptr ys, const nmod_poly_t poly, + mp_srcptr xs, slong n) + + Evaluates \code{poly} at the \code{n} values given in the vector + \code{xs}, writing the output values to \code{ys}. The values in + \code{xs} should be reduced modulo the modulus. + + Uses Horner's method iteratively. + +void _nmod_poly_evaluate_nmod_vec_fast_precomp(mp_ptr vs, mp_srcptr poly, + slong plen, const mp_ptr * tree, slong len, nmod_t mod) + + Evaluates (\code{poly}, \code{plen}) at the \code{len} values given + by the precomputed subproduct tree \code{tree}. + +void _nmod_poly_evaluate_nmod_vec_fast(mp_ptr ys, mp_srcptr poly, + slong len, mp_srcptr xs, slong n, nmod_t mod) + + Evaluates (\code{coeffs}, \code{len}) at the \code{n} values + given in the vector \code{xs}, writing the output values + to \code{ys}. The values in \code{xs} should be reduced + modulo the modulus. + + Uses fast multipoint evaluation, building a temporary subproduct tree. + +void nmod_poly_evaluate_nmod_vec_fast(mp_ptr ys, const nmod_poly_t poly, + mp_srcptr xs, slong n) + + Evaluates \code{poly} at the \code{n} values given in the vector + \code{xs}, writing the output values to \code{ys}. The values in + \code{xs} should be reduced modulo the modulus. + + Uses fast multipoint evaluation, building a temporary subproduct tree. + + +void _nmod_poly_evaluate_nmod_vec(mp_ptr ys, mp_srcptr poly, slong len, + mp_srcptr xs, slong n, nmod_t mod) + + Evaluates (\code{poly}, \code{len}) at the \code{n} values + given in the vector \code{xs}, writing the output values + to \code{ys}. The values in \code{xs} should be reduced + modulo the modulus. + +void nmod_poly_evaluate_nmod_vec(mp_ptr ys, const nmod_poly_t poly, + mp_srcptr xs, slong n) + + Evaluates \code{poly} at the \code{n} values given in the vector + \code{xs}, writing the output values to \code{ys}. The values in + \code{xs} should be reduced modulo the modulus. + +******************************************************************************* + + Interpolation + +******************************************************************************* + +void _nmod_poly_interpolate_nmod_vec(mp_ptr poly, + mp_srcptr xs, mp_srcptr ys, slong n, nmod_t mod) + + Sets \code{poly} to the unique polynomial of length at most \code{n} + that interpolates the \code{n} given evaluation points \code{xs} and + values \code{ys}. If the interpolating polynomial is shorter than + length \code{n}, the leading coefficients are set to zero. + + The values in \code{xs} and \code{ys} should be reduced modulo the + modulus, and all \code{xs} must be distinct. Aliasing between + \code{poly} and \code{xs} or \code{ys} is not allowed. + +void nmod_poly_interpolate_nmod_vec(nmod_poly_t poly, + mp_srcptr xs, mp_srcptr ys, slong n) + + Sets \code{poly} to the unique polynomial of length \code{n} that + interpolates the \code{n} given evaluation points \code{xs} and + values \code{ys}. The values in \code{xs} and \code{ys} should be + reduced modulo the modulus, and all \code{xs} must be distinct. + +void _nmod_poly_interpolation_weights(mp_ptr w, const mp_ptr * tree, + slong len, nmod_t mod) + + Sets \code{w} to the barycentric interpolation weights for fast + Lagrange interpolation with respect to a given subproduct tree. + +void _nmod_poly_interpolate_nmod_vec_fast_precomp(mp_ptr poly, mp_srcptr ys, + const mp_ptr * tree, mp_srcptr weights, slong len, nmod_t mod) + + Performs interpolation using the fast Lagrange interpolation + algorithm, generating a temporary subproduct tree. + + The function values are given as \code{ys}. The function takes + a precomputed subproduct tree \code{tree} and barycentric + interpolation weights \code{weights} corresponding to the + roots. + +void _nmod_poly_interpolate_nmod_vec_fast(mp_ptr poly, + mp_srcptr xs, mp_srcptr ys, slong n, nmod_t mod) + + Performs interpolation using the fast Lagrange interpolation + algorithm, generating a temporary subproduct tree. + +void nmod_poly_interpolate_nmod_vec_fast(nmod_poly_t poly, + mp_srcptr xs, mp_srcptr ys, slong n) + + Performs interpolation using the fast Lagrange interpolation algorithm, + generating a temporary subproduct tree. + +void _nmod_poly_interpolate_nmod_vec_newton(mp_ptr poly, + mp_srcptr xs, mp_srcptr ys, slong n, nmod_t mod) + + Forms the interpolating polynomial in the Newton basis using + the method of divided differences and then converts it to + monomial form. + +void nmod_poly_interpolate_nmod_vec_newton(nmod_poly_t poly, + mp_srcptr xs, mp_srcptr ys, slong n) + + Forms the interpolating polynomial in the Newton basis using + the method of divided differences and then converts it to + monomial form. + +void _nmod_poly_interpolate_nmod_vec_barycentric(mp_ptr poly, + mp_srcptr xs, mp_srcptr ys, slong n, nmod_t mod) + + Forms the interpolating polynomial using a naive implementation + of the barycentric form of Lagrange interpolation. + +void nmod_poly_interpolate_nmod_vec_barycentric(nmod_poly_t poly, + mp_srcptr xs, mp_srcptr ys, slong n) + + Forms the interpolating polynomial using a naive implementation + of the barycentric form of Lagrange interpolation. + + +******************************************************************************* + + Composition + +******************************************************************************* + +void _nmod_poly_compose_horner(mp_ptr res, mp_srcptr poly1, slong len1, + mp_srcptr poly2, slong len2, nmod_t mod) + + Composes \code{poly1} of length \code{len1} with \code{poly2} of length + \code{len2} and sets \code{res} to the result, i.e.\ evaluates + \code{poly1} at \code{poly2}. The algorithm used is Horner's algorithm. + We require that \code{res} have space for \code{(len1 - 1)*(len2 - 1) + 1} + coefficients. It is assumed that \code{len1 > 0} and \code{len2 > 0}. + +void nmod_poly_compose_horner(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_poly_t poly2) + + Composes \code{poly1} with \code{poly2} and sets \code{res} to the result, + i.e.\ evaluates \code{poly1} at \code{poly2}. The algorithm used is + Horner's algorithm. + +void _nmod_poly_compose_divconquer(mp_ptr res, mp_srcptr poly1, slong len1, + mp_srcptr poly2, slong len2, nmod_t mod) + + Composes \code{poly1} of length \code{len1} with \code{poly2} of length + \code{len2} and sets \code{res} to the result, i.e.\ evaluates + \code{poly1} at \code{poly2}. The algorithm used is the divide and + conquer algorithm. We require that \code{res} have space for + \code{(len1 - 1)*(len2 - 1) + 1} coefficients. It is assumed that + \code{len1 > 0} and \code{len2 > 0}. + +void nmod_poly_compose_divconquer(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_poly_t poly2) + + Composes \code{poly1} with \code{poly2} and sets \code{res} to the result, + i.e.\ evaluates \code{poly1} at \code{poly2}. The algorithm used is + the divide and conquer algorithm. + +void _nmod_poly_compose(mp_ptr res, mp_srcptr poly1, slong len1, + mp_srcptr poly2, slong len2, nmod_t mod) + + Composes \code{poly1} of length \code{len1} with \code{poly2} of length + \code{len2} and sets \code{res} to the result, i.e.\ evaluates \code{poly1} + at \code{poly2}. We require that \code{res} have space for + \code{(len1 - 1)*(len2 - 1) + 1} coefficients. It is assumed that + \code{len1 > 0} and \code{len2 > 0}. + +void nmod_poly_compose(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_poly_t poly2) + + Composes \code{poly1} with \code{poly2} and sets \code{res} to the result, + that is, evaluates \code{poly1} at \code{poly2}. + +******************************************************************************* + + Taylor shift + +******************************************************************************* + +void _nmod_poly_taylor_shift_horner(mp_ptr poly, mp_limb_t c, + slong len, nmod_t mod) + + Performs the Taylor shift composing \code{poly} by $x+c$ in-place. + Uses an efficient version Horner's rule. + +void nmod_poly_taylor_shift_horner(nmod_poly_t g, + const nmod_poly_t f, mp_limb_t c) + + Performs the Taylor shift composing \code{f} by $x+c$. + +void _nmod_poly_taylor_shift_convolution(mp_ptr poly, mp_limb_t c, + slong len, nmod_t mod) + + Performs the Taylor shift composing \code{poly} by $x+c$ in-place. + Writes the composition as a single convolution with cost $O(M(n))$. + We require that the modulus is a prime at least as large as the length. + +void nmod_poly_taylor_shift_convolution(nmod_poly_t g, + const nmod_poly_t f, mp_limb_t c) + + Performs the Taylor shift composing \code{f} by $x+c$. + Writes the composition as a single convolution with cost $O(M(n))$. + We require that the modulus is a prime at least as large as the length. + +void _nmod_poly_taylor_shift(mp_ptr poly, mp_limb_t c, slong len, nmod_t mod) + + Performs the Taylor shift composing \code{poly} by $x+c$ in-place. + We require that the modulus is a prime. + +void nmod_poly_taylor_shift(nmod_poly_t g, const nmod_poly_t f, mp_limb_t c) + + Performs the Taylor shift composing \code{f} by $x+c$. + We require that the modulus is a prime. + +******************************************************************************* + + Modular composition + +******************************************************************************* + +void _nmod_poly_compose_mod_horner(mp_ptr res, + mp_srcptr f, slong lenf, mp_srcptr g, mp_srcptr h, slong lenh, nmod_t mod) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require that + $h$ is nonzero and that the length of $g$ is one less than the + length of $h$ (possibly with zero padding). The output is not allowed + to be aliased with any of the inputs. + + The algorithm used is Horner's rule. + +void nmod_poly_compose_mod_horner(nmod_poly_t res, + const nmod_poly_t f, const nmod_poly_t g, + const nmod_poly_t h) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require that + $h$ is nonzero. The algorithm used is Horner's rule. + + +void _nmod_poly_compose_mod_brent_kung(mp_ptr res, + mp_srcptr f, slong lenf, mp_srcptr g, mp_srcptr h, slong lenh, nmod_t mod) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require that + $h$ is nonzero and that the length of $g$ is one less than the + length of $h$ (possibly with zero padding). We also require that + the length of $f$ is less than the length of $h$. The output is not allowed + to be aliased with any of the inputs. + + The algorithm used is the Brent-Kung matrix algorithm. + +void nmod_poly_compose_mod_brent_kung(nmod_poly_t res, + const nmod_poly_t f, const nmod_poly_t g, + const nmod_poly_t h) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require that + $h$ is nonzero and that $f$ has smaller degree than $h$. + The algorithm used is the Brent-Kung matrix algorithm. + +void _nmod_poly_compose_mod_brent_kung_preinv(mp_ptr res, mp_srcptr f, + slong lenf, + mp_srcptr g, mp_srcptr h, slong lenh, + mp_srcptr hinv, slong lenhinv, nmod_t mod) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require that + $h$ is nonzero and that the length of $g$ is one less than the + length of $h$ (possibly with zero padding). We also require that + the length of $f$ is less than the length of $h$. Furthermore, we require + \code{hinv} to be the inverse of the reverse of \code{h}. + The output is not allowed to be aliased with any of the inputs. + + The algorithm used is the Brent-Kung matrix algorithm. + +void nmod_poly_compose_mod_brent_kung_preinv(nmod_poly_t res, + const nmod_poly_t f, const nmod_poly_t g, + const nmod_poly_t h, const nmod_poly_t hinv) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require that + $h$ is nonzero and that $f$ has smaller degree than $h$. Furthermore, + we require \code{hinv} to be the inverse of the reverse of \code{h}. + The algorithm used is the Brent-Kung matrix algorithm. + +void +_nmod_poly_reduce_matrix_mod_poly (nmod_mat_t A, const nmod_mat_t B, + const nmod_poly_t f) + + Sets the ith row of \code{A} to the reduction of the ith row of $B$ modulo + $f$ for $i=1,\ldots,\sqrt{\deg(f)}$. We require $B$ to be at least + a $\sqrt{\deg(f)}\times \deg(f)$ matrix and $f$ to be nonzero. + +void +_nmod_poly_precompute_matrix (nmod_mat_t A, mp_srcptr f, mp_srcptr g, + slong leng, mp_srcptr ginv, slong lenginv, nmod_t mod) + + Sets the ith row of \code{A} to $f^i$ modulo $g$ for + $i=1,\ldots,\sqrt{\deg(g)}$. We require $A$ to be + a $\sqrt{\deg(g)}\times \deg(g)$ matrix. We require + \code{ginv} to be the inverse of the reverse of \code{g} and $g$ to be + nonzero. + +void +nmod_poly_precompute_matrix (nmod_mat_t A, const nmod_poly_t f, + const nmod_poly_t g, const nmod_poly_t ginv) + + Sets the ith row of \code{A} to $f^i$ modulo $g$ for + $i=1,\ldots,\sqrt{\deg(g)}$. We require $A$ to be + a $\sqrt{\deg(g)}\times \deg(g)$ matrix. We require + \code{ginv} to be the inverse of the reverse of \code{g}. + + +void +_nmod_poly_compose_mod_brent_kung_precomp_preinv(mp_ptr res, mp_srcptr f, + slong lenf, const nmod_mat_t A, mp_srcptr h, + slong h, mp_srcptr hinv, slong lenhinv, + nmod_t mod) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require that + $h$ is nonzero. We require that the ith row of $A$ contains $g^i$ for + $i=1,\ldots,\sqrt{\deg(h)}$, i.e. $A$ is a + $\sqrt{\deg(h)}\times \deg(h)$ matrix. We also require that + the length of $f$ is less than the length of $h$. Furthermore, we require + \code{hinv} to be the inverse of the reverse of \code{h}. + The output is not allowed to be aliased with any of the inputs. + + The algorithm used is the Brent-Kung matrix algorithm. + +void +nmod_poly_compose_mod_brent_kung_precomp_preinv(nmod_poly_t res, + const nmod_poly_t f, const nmod_mat_t A, + const nmod_poly_t h, const nmod_poly_t hinv) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require that the + ith row of $A$ contains $g^i$ for $i=1,\ldots,\sqrt{\deg(h)}$, i.e. $A$ is a + $\sqrt{\deg(h)}\times \deg(h)$ matrix. We require that $h$ is nonzero and + that $f$ has smaller degree than $h$. Furthermore, we require \code{hinv} to + be the inverse of the reverse of \code{h}. This version of Brent-Kung + modular composition is particularly useful if one has to perform several + modular composition of the form $f(g)$ modulo $h$ for fixed $g$ and $h$. + +void _nmod_poly_compose_mod(mp_ptr res, + mp_srcptr f, slong lenf, mp_srcptr g, mp_srcptr h, slong lenh, nmod_t mod) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require that + $h$ is nonzero and that the length of $g$ is one less than the + length of $h$ (possibly with zero padding). The output is not allowed + to be aliased with any of the inputs. + +void nmod_poly_compose_mod(nmod_poly_t res, + const nmod_poly_t f, const nmod_poly_t g, + const nmod_poly_t h) + + Sets \code{res} to the composition $f(g)$ modulo $h$. We require that + $h$ is nonzero. + + +******************************************************************************* + + Greatest common divisor + +******************************************************************************* + +slong _nmod_poly_gcd_euclidean(mp_ptr G, + mp_srcptr A, slong lenA, mp_srcptr B, slong lenB, nmod_t mod) + + Computes the GCD of $A$ of length \code{lenA} and $B$ of length + \code{lenB}, where \code{lenA >= lenB > 0}. The length of the GCD $G$ + is returned by the function. No attempt is made to make the GCD monic. It + is required that $G$ have space for \code{lenB} coefficients. + +void nmod_poly_gcd_euclidean(nmod_poly_t G, + const nmod_poly_t A, const nmod_poly_t B) + + Computes the GCD of $A$ and $B$. The GCD of zero polynomials is + defined to be zero, whereas the GCD of the zero polynomial and some other + polynomial $P$ is defined to be $P$. Except in the case where + the GCD is zero, the GCD $G$ is made monic. + +slong _nmod_poly_hgcd(mp_ptr *M, slong *lenM, + mp_ptr A, slong *lenA, mp_ptr B, slong *lenB, + mp_srcptr a, slong lena, mp_srcptr b, slong lenb, + nmod_t mod) + + Computes the HGCD of $a$ and $b$, that is, a matrix~$M$, a sign~$\sigma$ + and two polynomials $A$ and $B$ such that + \begin{equation*} + (A,B)^t = \sigma M^{-1} (a,b)^t. + \end{equation*} + + Assumes that $\len(a) > \len(b) > 0$. + + Assumes that $A$ and $B$ have space of size at least $\len(a)$ + and $\len(b)$, respectively. On exit, \code{*lenA} and \code{*lenB} + will contain the correct lengths of $A$ and $B$. + + Assumes that \code{M[0]}, \code{M[1]}, \code{M[2]}, and \code{M[3]} + each point to a vector of size at least $\len(a)$. + +slong _nmod_poly_gcd_hgcd(mp_ptr G, mp_srcptr A, slong lenA, + mp_srcptr B, slong lenB, nmod_t mod) + + Computes the monic GCD of $A$ and $B$, assuming that + $\len(A) \geq \len(B) > 0$. + + Assumes that $G$ has space for $\len(B)$ coefficients and + returns the length of $G$ on output. + +void nmod_poly_gcd_hgcd(nmod_poly_t G, + const nmod_poly_t A, const nmod_poly_t B) + + Computes the monic GCD of $A$ and $B$ using the HGCD algorithm. + + As a special case, the GCD of two zero polynomials is defined to be + the zero polynomial. + + The time complexity of the algorithm is $\mathcal{O}(n \log^2 n)$. + For further details, see~\citep{ThullYap1990}. + +slong _nmod_poly_gcd(mp_ptr G, + mp_srcptr A, slong lenA, mp_srcptr B, slong lenB, nmod_t mod) + + Computes the GCD of $A$ of length \code{lenA} and $B$ of length + \code{lenB}, where \code{lenA >= lenB > 0}. The length of the GCD $G$ + is returned by the function. No attempt is made to make the GCD monic. It + is required that $G$ have space for \code{lenB} coefficients. + +void nmod_poly_gcd(nmod_poly_t G, + const nmod_poly_t A, const nmod_poly_t B) + + Computes the GCD of $A$ and $B$. The GCD of zero polynomials is + defined to be zero, whereas the GCD of the zero polynomial and some other + polynomial $P$ is defined to be $P$. Except in the case where + the GCD is zero, the GCD $G$ is made monic. + +slong _nmod_poly_xgcd_euclidean(mp_ptr G, mp_ptr S, mp_ptr T, + mp_srcptr A, slong A_len, mp_srcptr B, slong B_len, nmod_t mod) + + Computes the GCD of $A$ and $B$ together with cofactors $S$ and $T$ + such that $S A + T B = G$. Returns the length of $G$. + + Assumes that $\len(A) \geq \len(B) \geq 1$ and + $(\len(A),\len(B)) \neq (1,1)$. + + No attempt is made to make the GCD monic. + + Requires that $G$ have space for $\len(B)$ coefficients. Writes + $\len(B)-1$ and $\len(A)-1$ coefficients to $S$ and $T$, respectively. + Note that, in fact, $\len(S) \leq \max(\len(B) - \len(G), 1)$ and + $\len(T) \leq \max(\len(A) - \len(G), 1)$. + + No aliasing of input and output operands is permitted. + +void nmod_poly_xgcd_euclidean(nmod_poly_t G, nmod_poly_t S, nmod_poly_t T, + const nmod_poly_t A, const nmod_poly_t B) + + Computes the GCD of $A$ and $B$. The GCD of zero polynomials is + defined to be zero, whereas the GCD of the zero polynomial and some other + polynomial $P$ is defined to be $P$. Except in the case where + the GCD is zero, the GCD $G$ is made monic. + + Polynomials \code{S} and \code{T} are computed such that + \code{S*A + T*B = G}. The length of \code{S} will be at most + \code{lenB} and the length of \code{T} will be at most \code{lenA}. + +slong _nmod_poly_xgcd_hgcd(mp_ptr G, mp_ptr S, mp_ptr T, + mp_srcptr A, slong A_len, mp_srcptr B, slong B_len, nmod_t mod) + + Computes the GCD of $A$ and $B$, where $\len(A) \geq \len(B) > 0$, + together with cofactors $S$ and $T$ such that $S A + T B = G$. Returns + the length of $G$. + + No attempt is made to make the GCD monic. + + Requires that $G$ have space for $\len(B)$ coefficients. Writes + $\len(B) - 1$ and $\len(A) - 1$ coefficients to $S$ and $T$, + respectively. Note that, in fact, $\len(S) \leq \len(B) - \len(G)$ + and $\len(T) \leq \len(A) - \len(G)$. + + Both $S$ and $T$ must have space for at least $2$ coefficients. + + No aliasing of input and output operands is permitted. + +void nmod_poly_xgcd_hgcd(nmod_poly_t G, nmod_poly_t S, nmod_poly_t T, + const nmod_poly_t A, const nmod_poly_t B) + + Computes the GCD of $A$ and $B$. The GCD of zero polynomials is + defined to be zero, whereas the GCD of the zero polynomial and some other + polynomial $P$ is defined to be $P$. Except in the case where + the GCD is zero, the GCD $G$ is made monic. + + Polynomials \code{S} and \code{T} are computed such that + \code{S*A + T*B = G}. The length of \code{S} will be at most + \code{lenB} and the length of \code{T} will be at most \code{lenA}. + +slong _nmod_poly_xgcd(mp_ptr G, mp_ptr S, mp_ptr T, + mp_srcptr A, slong lenA, mp_srcptr B, slong lenB, + nmod_t mod) + + Computes the GCD of $A$ and $B$, where $\len(A) \geq \len(B) > 0$, + together with cofactors $S$ and $T$ such that $S A + T B = G$. Returns + the length of $G$. + + No attempt is made to make the GCD monic. + + Requires that $G$ have space for $\len(B)$ coefficients. Writes + $\len(B) - 1$ and $\len(A) - 1$ coefficients to $S$ and $T$, + respectively. Note that, in fact, $\len(S) \leq \len(B) - \len(G)$ + and $\len(T) \leq \len(A) - \len(G)$. + + No aliasing of input and output operands is permitted. + +void nmod_poly_xgcd(nmod_poly_t G, nmod_poly_t S, nmod_poly_t T, + const nmod_poly_t A, const nmod_poly_t B) + + Computes the GCD of $A$ and $B$. The GCD of zero polynomials is + defined to be zero, whereas the GCD of the zero polynomial and some other + polynomial $P$ is defined to be $P$. Except in the case where + the GCD is zero, the GCD $G$ is made monic. + + The polynomials \code{S} and \code{T} are set such that + \code{S*A + T*B = G}. The length of \code{S} will be at most + \code{lenB} and the length of \code{T} will be at most \code{lenA}. + +mp_limb_t +_nmod_poly_resultant_euclidean(mp_srcptr poly1, slong len1, + mp_srcptr poly2, slong len2, nmod_t mod) + + Returns the resultant of \code{(poly1, len1)} and + \code{(poly2, len2)} using the Euclidean algorithm. + + Assumes that \code{len1 >= len2 > 0}. + + Asumes that the modulus is prime. + +mp_limb_t +nmod_poly_resultant_euclidean(const nmod_poly_t f, const nmod_poly_t g) + + Computes the resultant of $f$ and $g$ using the Euclidean algorithm. + + For two non-zero polynomials $f(x) = a_m x^m + \dotsb + a_0$ and + $g(x) = b_n x^n + \dotsb + b_0$ of degrees $m$ and $n$, the resultant + is defined to be + \begin{equation*} + a_m^n b_n^m \prod_{(x, y) : f(x) = g(y) = 0} (x - y). + \end{equation*} + For convenience, we define the resultant to be equal to zero if either + of the two polynomials is zero. + +mp_limb_t +_nmod_poly_resultant(mp_srcptr poly1, slong len1, + mp_srcptr poly2, slong len2, nmod_t mod) + + Returns the resultant of \code{(poly1, len1)} and + \code{(poly2, len2)}. + + Assumes that \code{len1 >= len2 > 0}. + + Asumes that the modulus is prime. + +mp_limb_t +nmod_poly_resultant(const nmod_poly_t f, const nmod_poly_t g) + + Computes the resultant of $f$ and $g$. + + For two non-zero polynomials $f(x) = a_m x^m + \dotsb + a_0$ and + $g(x) = b_n x^n + \dotsb + b_0$ of degrees $m$ and $n$, the resultant + is defined to be + \begin{equation*} + a_m^n b_n^m \prod_{(x, y) : f(x) = g(y) = 0} (x - y). + \end{equation*} + For convenience, we define the resultant to be equal to zero if either + of the two polynomials is zero. + +slong _nmod_poly_gcdinv(mp_ptr G, mp_ptr S, + mp_srcptr A, slong lenA, mp_srcptr B, slong lenB, + const nmod_t mod) + + Computes \code{(G, lenA)}, \code{(S, lenB-1)} such that + $G \cong S A \pmod{B}$, returning the actual length of $G$. + + Assumes that $0 < \len(A) < \len(B)$. + +void nmod_poly_gcdinv(nmod_poly_t G, nmod_poly_t S, + const nmod_poly_t A, const nmod_poly_t B) + + Computes polynomials $G$ and $S$, both reduced modulo~$B$, + such that $G \cong S A \pmod{B}$, where $B$ is assumed to + have $\len(B) \geq 2$. + + In the case that $A = 0 \pmod{B}$, returns $G = S = 0$. + +int _nmod_poly_invmod(mp_ptr A, mp_srcptr B, slong lenB, + mp_srcptr P, slong lenP, const nmod_t mod) + + Attempts to set \code{(A, lenP-1)} to the inverse of \code{(B, lenB)} + modulo the polynomial \code{(P, lenP)}. Returns $1$ if \code{(B, lenB)} + is invertible and $0$ otherwise. + + Assumes that $0 < \len(B) < \len(P)$, and hence also $\len(P) \geq 2$, + but supports zero-padding in \code{(B, lenB)}. + + Does not support aliasing. + + Assumes that $mod$ is a prime number. + +int nmod_poly_invmod(nmod_poly_t A, const nmod_poly_t B, const nmod_poly_t P) + + Attempts to set $A$ to the inverse of $B$ modulo $P$ in the polynomial + ring $(\mathbf{Z}/p\mathbf{Z})[X]$, where we assume that $p$ is a prime + number. + + If $\deg(P) < 2$, raises an exception. + + If the greatest common divisor of $B$ and $P$ is~$1$, returns~$1$ and + sets $A$ to the inverse of $B$. Otherwise, returns~$0$ and the value + of $A$ on exit is undefined. + + +******************************************************************************* + + Power series composition + +******************************************************************************* + +void _nmod_poly_compose_series_horner(mp_ptr res, + mp_srcptr poly1, slong len1, mp_srcptr poly2, slong len2, slong n) + + Sets \code{res} to the composition of \code{poly1} and \code{poly2} + modulo $x^n$, where the constant term of \code{poly2} is required + to be zero. + + Assumes that \code{len1, len2, n > 0}, that \code{len1, len2 <= n}, + and that \code{(len1-1) * (len2-1) + 1 <= n}, and that \code{res} has + space for \code{n} coefficients. Does not support aliasing between any + of the inputs and the output. + + This implementation uses the Horner scheme. + +void nmod_poly_compose_series_horner(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_poly_t poly2, slong n) + + Sets \code{res} to the composition of \code{poly1} and \code{poly2} + modulo $x^n$, where the constant term of \code{poly2} is required + to be zero. + + This implementation uses the Horner scheme. + +void _nmod_poly_compose_series_brent_kung(mp_ptr res, mp_srcptr poly1, + slong len1, mp_srcptr poly2, slong len2, slong n) + + Sets \code{res} to the composition of \code{poly1} and \code{poly2} + modulo $x^n$, where the constant term of \code{poly2} is required + to be zero. + + Assumes that \code{len1, len2, n > 0}, that \code{len1, len2 <= n}, + and that\\ \code{(len1-1) * (len2-1) + 1 <= n}, and that \code{res} has + space for \code{n} coefficients. Does not support aliasing between any + of the inputs and the output. + + This implementation uses Brent-Kung algorithm 2.1 \cite{BrentKung1978}. + +void nmod_poly_compose_series_brent_kung(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_poly_t poly2, slong n) + + Sets \code{res} to the composition of \code{poly1} and \code{poly2} + modulo $x^n$, where the constant term of \code{poly2} is required + to be zero. + + This implementation uses Brent-Kung algorithm 2.1 \cite{BrentKung1978}. + +void _nmod_poly_compose_series_divconquer(mp_ptr res, + mp_srcptr poly1, slong len1, + mp_srcptr poly2, slong len2, slong N, nmod_t mod) + + Composes \code{poly1} of length $\ell_1$ with \code{poly2} of + length $\ell_2$ modulo $x^N$ and sets \code{res} to the result, + i.e.\ evaluates \code{poly1} at \code{poly2}. + + Writes $\min\{(\ell_1 - 1)(\ell_2 - 2) + 1, N\}$ coefficients + to the vector \code{res}. + + The algorithm used is the divide and conquer algorithm. + It is assumed that $0 < \ell_1$ and $0 < \ell_2 \leq N$. + + Does not support aliasing between the inputs and the output. + +void nmod_poly_compose_series_divconquer(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_poly_t poly2, slong N) + + Composes \code{poly1} with \code{poly2} modulo $x^N$ and sets \code{res} + to the result, i.e.\ evaluates \code{poly1} at \code{poly2}. + + The algorithm used is the divide and conquer algorithm. + +void _nmod_poly_compose_series(mp_ptr res, mp_srcptr poly1, slong len1, + mp_srcptr poly2, slong len2, slong n) + + Sets \code{res} to the composition of \code{poly1} and \code{poly2} + modulo $x^n$, where the constant term of \code{poly2} is required + to be zero. + + Assumes that \code{len1, len2, n > 0}, that \code{len1, len2 <= n}, + and that\\ \code{(len1-1) * (len2-1) + 1 <= n}, and that \code{res} has + space for \code{n} coefficients. Does not support aliasing between any + of the inputs and the output. + + This implementation automatically switches between the Horner scheme + and Brent-Kung algorithm 2.1 depending on the size of the inputs. + +void nmod_poly_compose_series(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_poly_t poly2, slong n) + + Sets \code{res} to the composition of \code{poly1} and \code{poly2} + modulo $x^n$, where the constant term of \code{poly2} is required + to be zero. + + This implementation automatically switches between the Horner scheme + and Brent-Kung algorithm 2.1 depending on the size of the inputs. + +******************************************************************************* + + Power series reversion + +******************************************************************************* + +void _nmod_poly_revert_series_lagrange(mp_ptr Qinv, mp_srcptr Q, + slong n, nmod_t mod) + + Sets \code{Qinv} to the compositional inverse or reversion of \code{Q} + as a power series, i.e. computes $Q^{-1}$ such that + $Q(Q^{-1}(x)) = Q^{-1}(Q(x)) = x \bmod x^n$. The arguments must + both have length \code{n} and may not be aliased. + + It is required that $Q_0 = 0$ and that $Q_1$ as well as the integers + $1, 2, \ldots, n-1$ are invertible modulo the modulus. + + This implementation uses the Lagrange inversion formula. + +void nmod_poly_revert_series_lagrange(nmod_poly_t Qinv, + const nmod_poly_t Q, slong n) + + Sets \code{Qinv} to the compositional inverse or reversion of \code{Q} + as a power series, i.e. computes $Q^{-1}$ such that + $Q(Q^{-1}(x)) = Q^{-1}(Q(x)) = x \bmod x^n$. + + It is required that $Q_0 = 0$ and that $Q_1$ as well as the integers + $1, 2, \ldots, n-1$ are invertible modulo the modulus. + + This implementation uses the Lagrange inversion formula. + +void _nmod_poly_revert_series_lagrange_fast(mp_ptr Qinv, mp_srcptr Q, + slong n, nmod_t mod) + + Sets \code{Qinv} to the compositional inverse or reversion of \code{Q} + as a power series, i.e. computes $Q^{-1}$ such that + $Q(Q^{-1}(x)) = Q^{-1}(Q(x)) = x \bmod x^n$. The arguments must + both have length \code{n} and may not be aliased. + + It is required that $Q_0 = 0$ and that $Q_1$ as well as the integers + $1, 2, \ldots, n-1$ are invertible modulo the modulus. + + This implementation uses a reduced-complexity implementation + of the Lagrange inversion formula. + +void nmod_poly_revert_series_lagrange_fast(nmod_poly_t Qinv, + const nmod_poly_t Q, slong n) + + Sets \code{Qinv} to the compositional inverse or reversion of \code{Q} + as a power series, i.e. computes $Q^{-1}$ such that + $Q(Q^{-1}(x)) = Q^{-1}(Q(x)) = x \bmod x^n$. + + It is required that $Q_0 = 0$ and that $Q_1$ as well as the integers + $1, 2, \ldots, n-1$ are invertible modulo the modulus. + + This implementation uses a reduced-complexity implementation + of the Lagrange inversion formula. + +void _nmod_poly_revert_series_newton(mp_ptr Qinv, mp_srcptr Q, + slong n, nmod_t mod) + + Sets \code{Qinv} to the compositional inverse or reversion of \code{Q} + as a power series, i.e. computes $Q^{-1}$ such that + $Q(Q^{-1}(x)) = Q^{-1}(Q(x)) = x \bmod x^n$. The arguments must + both have length \code{n} and may not be aliased. + + It is required that $Q_0 = 0$ and that $Q_1$ as well as the integers + $1, 2, \ldots, n-1$ are invertible modulo the modulus. + + This implementation uses Newton iteration \cite{BrentKung1978}. + +void nmod_poly_revert_series_newton(nmod_poly_t Qinv, + const nmod_poly_t Q, slong n) + + Sets \code{Qinv} to the compositional inverse or reversion of \code{Q} + as a power series, i.e. computes $Q^{-1}$ such that + $Q(Q^{-1}(x)) = Q^{-1}(Q(x)) = x \bmod x^n$. + + It is required that $Q_0 = 0$ and that $Q_1$ as well as the integers + $1, 2, \ldots, n-1$ are invertible modulo the modulus. + + This implementation uses Newton iteration \cite{BrentKung1978}. + +void _nmod_poly_revert_series(mp_ptr Qinv, mp_srcptr Q, slong n, nmod_t mod) + + Sets \code{Qinv} to the compositional inverse or reversion of \code{Q} + as a power series, i.e. computes $Q^{-1}$ such that + $Q(Q^{-1}(x)) = Q^{-1}(Q(x)) = x \bmod x^n$. The arguments must + both have length \code{n} and may not be aliased. + + It is required that $Q_0 = 0$ and that $Q_1$ as well as the integers + $1, 2, \ldots, n-1$ are invertible modulo the modulus. + + This implementation automatically chooses between the Lagrange + inversion formula and Newton iteration based on the size of the + input. + +void nmod_poly_revert_series(nmod_poly_t Qinv, const nmod_poly_t Q, slong n) + + Sets \code{Qinv} to the compositional inverse or reversion of \code{Q} + as a power series, i.e. computes $Q^{-1}$ such that + $Q(Q^{-1}(x)) = Q^{-1}(Q(x)) = x \bmod x^n$. + + It is required that $Q_0 = 0$ and that $Q_1$ as well as the integers + $1, 2, \ldots, n-1$ are invertible modulo the modulus. + + This implementation automatically chooses between the Lagrange + inversion formula and Newton iteration based on the size of the + input. + +******************************************************************************* + + Square roots + + The series expansions for $\sqrt{h}$ and $1/\sqrt{h}$ are defined + by means of the generalised binomial theorem + $$h^r = (1+y)^r = + \sum_{k=0}^{\infty} {r \choose k} y^k.$$ + It is assumed that $h$ has constant term $1$ and that the coefficients + $2^{-k}$ exist in the coefficient ring (i.e. $2$ must be invertible). + + +******************************************************************************* + +void _nmod_poly_invsqrt_series(mp_ptr g, mp_srcptr h, slong n, nmod_t mod) + + Set the first $n$ terms of $g$ to the series expansion of $1/\sqrt{h}$. + It is assumed that $n > 0$, that $h$ has constant term 1 and that $h$ + is zero-padded as necessary to length $n$. Aliasing is not permitted. + +void nmod_poly_invsqrt_series(nmod_poly_t g, const nmod_poly_t h, slong n) + + Set $g$ to the series expansion of $1/\sqrt{h}$ to order $O(x^n)$. + It is assumed that $h$ has constant term 1. + +void _nmod_poly_sqrt_series(mp_ptr g, mp_srcptr h, slong n, nmod_t mod) + + Set the first $n$ terms of $g$ to the series expansion of $\sqrt{h}$. + It is assumed that $n > 0$, that $h$ has constant term 1 and that $h$ + is zero-padded as necessary to length $n$. Aliasing is not permitted. + +void nmod_poly_sqrt_series(nmod_poly_t g, const nmod_poly_t h, slong n) + + Set $g$ to the series expansion of $\sqrt{h}$ to order $O(x^n)$. + It is assumed that $h$ has constant term 1. + +int _nmod_poly_sqrt(mp_ptr s, mp_srcptr p, slong n, nmod_t mod) + + If \code{(p, n)} is a perfect square, sets \code{(s, n / 2 + 1)} + to a square root of $p$ and returns 1. Otherwise returns 0. + +int nmod_poly_sqrt(nmod_poly_t s, const nmod_poly_t p) + + If $p$ is a perfect square, sets $s$ to a square root of $p$ + and returns 1. Otherwise returns 0. + +******************************************************************************* + + Transcendental functions + + The elementary transcendental functions of a formal power series $h$ + are defined as + + $$\exp(h(x)) = \sum_{k=0}^{\infty} \frac{(h(x))^k}{k!}$$ + + $$\log(h(x)) = \int_0^x \frac{h'(t)}{h(t)} dt$$ + + $$\operatorname{atan}(h(x)) = \int_0^x\frac{h'(t)}{1+(h(t))^2} dt$$ + + $$\operatorname{atanh}(h(x)) = \int_0^x\frac{h'(t)}{1-(h(t))^2} dt$$ + + $$\operatorname{asin}(h(x)) = \int_0^x\frac{h'(t)}{\sqrt{1-(h(t))^2}} dt$$ + + $$\operatorname{asinh}(h(x)) = \int_0^x\frac{h'(t)}{\sqrt{1+(h(t))^2}} dt$$ + + The functions sin, cos, tan, etc. are defined using standard inverse + or functional relations. + + The logarithm function assumes that $h$ has constant term $1$. All + other functions assume that $h$ has constant term $0$. + + All functions assume that the coefficient $1/k$ or $1/k!$ exists + for all indices $k$. When computing to order $O(x^n)$, the modulus $p$ + must therefore be a prime satisfying $p \ge n$. Further, we always + require that $p > 2$ in order to be able to multiply by $1/2$ for + internal purposes. + + If the input does not satisfy all these conditions, results are undefined. + + Except where otherwise noted, functions are implemented with optimal + (up to constants) complexity $O(M(n))$, where $M(n)$ is the cost + of polynomial multiplication. + +******************************************************************************* + +void _nmod_poly_log_series_monomial_ui(mp_ptr g, + mp_limb_t c, ulong r, slong n, nmod_t mod) + + Set $g = \log(1+cx^r) + O(x^n)$. Assumes $n > 0$, $r > 0$, and that + the coefficient is reduced by the modulus. Works efficiently in linear + time. + +void nmod_poly_log_series_monomial_ui(nmod_poly_t g, + mp_limb_t c, ulong r, slong n) + + Set $g = \log(1+cx^r) + O(x^n)$. Works efficiently in linear time. + +void _nmod_poly_log_series(mp_ptr g, mp_srcptr h, slong n, nmod_t mod) + + Set $g = \log(h) + O(x^n)$. Assumes $n > 0$ and that $h$ is zero-padded + as necessary to length $n$. Aliasing of $g$ and $h$ is allowed. + +void nmod_poly_log_series(nmod_poly_t g, const nmod_poly_t h, slong n) + + Set $g = \log(h) + O(x^n)$. The case $h = 1+cx^r$ is automatically + detected and handled efficiently. + +void _nmod_poly_exp_series_monomial_ui(mp_ptr g, + mp_limb_t c, ulong r, slong n, nmod_t mod) + + Set $g = \exp(cx^r) + O(x^n)$. Assumes $n > 0$, $r > 0$, and that + the coefficient is reduced by the modulus. Works efficiently + in linear time. + +void nmod_poly_exp_series_monomial_ui(nmod_poly_t g, + mp_limb_t c, ulong r, slong n) + + Set $g = \exp(cx^r) + O(x^n)$. Works efficiently in linear time. + +void _nmod_poly_exp_series_basecase(mp_ptr g, mp_srcptr h, slong hlen, + slong n, nmod_t mod) + + Set $g = \exp(h) + O(x^n)$ using a simple $O(n^2)$ algorithm. + Assumes $n > 0$ and $\operatorname{hlen} > 0$. Only the first + $\operatorname{hlen}$ coefficients of $h$ will be read. + Aliasing of $f$ and $h$ is allowed. + +void nmod_poly_exp_series_basecase(nmod_poly_t g, const nmod_poly_t h, slong n) + + Set $g = \exp(h) + O(x^n)$ using a simple $O(n^2)$ algorithm. + +void _nmod_poly_exp_series(mp_ptr g, mp_srcptr h, slong n, nmod_t mod) + + Set $g = \exp(h) + O(x^n)$. Assumes $n > 0$ and that $h$ is zero-padded + as necessary to length $n$. Aliasing of $g$ and $h$ is not allowed. + + Uses Newton iteration (the version given in \cite{HanZim2004}). + For small $n$, falls back to the basecase algorithm. + +void _nmod_poly_exp_expinv_series(mp_ptr f, mp_ptr g, mp_srcptr h, + slong n, nmod_t mod) + + Set $f = \exp(h) + O(x^n)$ and $g = \exp(-h) + O(x^n)$, more efficiently + for large $n$ than performing a separate inversion to obtain $g$. + Assumes $n > 0$ and that $h$ is zero-padded + as necessary to length $n$. Aliasing is not allowed. + + Uses Newton iteration (the version given in \cite{HanZim2004}). + For small $n$, falls back to the basecase algorithm. + +void nmod_poly_exp_series(nmod_poly_t g, const nmod_poly_t h, slong n) + + Set $g = \exp(h) + O(x^n)$. The case $h = cx^r$ is automatically + detected and handled efficiently. Otherwise this function automatically + uses the basecase algorithm for small $n$ and Newton iteration otherwise. + +void _nmod_poly_atan_series(mp_ptr g, mp_srcptr h, slong n, nmod_t mod) + + Set $g = \operatorname{atan}(h) + O(x^n)$. Assumes $n > 0$ and that $h$ + is zero-padded as necessary to length $n$. Aliasing of $g$ and $h$ is + allowed. + +void nmod_poly_atan_series(nmod_poly_t g, const nmod_poly_t h, slong n) + + Set $g = \operatorname{atan}(h) + O(x^n)$. + +void _nmod_poly_atanh_series(mp_ptr g, mp_srcptr h, slong n, nmod_t mod) + + Set $g = \operatorname{atanh}(h) + O(x^n)$. Assumes $n > 0$ and that $h$ + is zero-padded as necessary to length $n$. Aliasing of $g$ and $h$ is + allowed. + +void nmod_poly_atanh_series(nmod_poly_t g, const nmod_poly_t h, slong n) + + Set $g = \operatorname{atanh}(h) + O(x^n)$. + +void _nmod_poly_asin_series(mp_ptr g, mp_srcptr h, slong n, nmod_t mod) + + Set $g = \operatorname{asin}(h) + O(x^n)$. Assumes $n > 0$ and that $h$ + is zero-padded as necessary to length $n$. Aliasing of $g$ and $h$ is + allowed. + +void nmod_poly_asin_series(nmod_poly_t g, const nmod_poly_t h, slong n) + + Set $g = \operatorname{asin}(h) + O(x^n)$. + +void _nmod_poly_asinh_series(mp_ptr g, mp_srcptr h, slong n, nmod_t mod) + + Set $g = \operatorname{asinh}(h) + O(x^n)$. Assumes $n > 0$ and that $h$ + is zero-padded as necessary to length $n$. Aliasing of $g$ and $h$ is + allowed. + +void nmod_poly_asinh_series(nmod_poly_t g, const nmod_poly_t h, slong n) + + Set $g = \operatorname{asinh}(h) + O(x^n)$. + +void _nmod_poly_sin_series(mp_ptr g, mp_srcptr h, slong n, nmod_t mod) + + Set $g = \operatorname{sin}(h) + O(x^n)$. Assumes $n > 0$ and that $h$ + is zero-padded as necessary to length $n$. Aliasing of $g$ and $h$ is + allowed. The value is computed using the identity + $\sin(x) = 2 \tan(x/2)) / (1 + \tan^2(x/2)).$ + +void nmod_poly_sin_series(nmod_poly_t g, const nmod_poly_t h, slong n) + + Set $g = \operatorname{sin}(h) + O(x^n)$. + +void _nmod_poly_cos_series(mp_ptr g, mp_srcptr h, slong n, nmod_t mod) + + Set $g = \operatorname{cos}(h) + O(x^n)$. Assumes $n > 0$ and that $h$ + is zero-padded as necessary to length $n$. Aliasing of $g$ and $h$ is + allowed. The value is computed using the identity + $\cos(x) = (1-\tan^2(x/2)) / (1 + \tan^2(x/2)).$ + +void nmod_poly_cos_series(nmod_poly_t g, const nmod_poly_t h, slong n) + + Set $g = \operatorname{cos}(h) + O(x^n)$. + +void _nmod_poly_tan_series(mp_ptr g, mp_srcptr h, slong n, nmod_t mod) + + Set $g = \operatorname{tan}(h) + O(x^n)$. Assumes $n > 0$ and that $h$ + is zero-padded as necessary to length $n$. Aliasing of $g$ and $h$ is + not allowed. Uses Newton iteration to invert the atan function. + +void nmod_poly_tan_series(nmod_poly_t g, const nmod_poly_t h, slong n) + + Set $g = \operatorname{tan}(h) + O(x^n)$. + +void _nmod_poly_sinh_series(mp_ptr g, mp_srcptr h, slong n, nmod_t mod) + + Set $g = \operatorname{sinh}(h) + O(x^n)$. Assumes $n > 0$ and that $h$ + is zero-padded as necessary to length $n$. Aliasing of $g$ and $h$ is + not allowed. Uses the identity $\sinh(x) = (e^x - e^{-x})/2$. + +void nmod_poly_sinh_series(nmod_poly_t g, const nmod_poly_t h, slong n) + + Set $g = \operatorname{sinh}(h) + O(x^n)$. + +void _nmod_poly_cosh_series(mp_ptr g, mp_srcptr h, slong n, nmod_t mod) + + Set $g = \operatorname{cos}(h) + O(x^n)$. Assumes $n > 0$ and that $h$ + is zero-padded as necessary to length $n$. Aliasing of $g$ and $h$ is + not allowed. Uses the identity $\cosh(x) = (e^x + e^{-x})/2$. + +void nmod_poly_cosh_series(nmod_poly_t g, const nmod_poly_t h, slong n) + + Set $g = \operatorname{cosh}(h) + O(x^n)$. + +void _nmod_poly_tanh_series(mp_ptr g, mp_srcptr h, slong n, nmod_t mod) + + Set $g = \operatorname{tanh}(h) + O(x^n)$. Assumes $n > 0$ and that $h$ + is zero-padded as necessary to length $n$. Uses the identity + $\tanh(x) = (e^{2x}-1)/(e^{2x}+1)$. + +void nmod_poly_tanh_series(nmod_poly_t g, const nmod_poly_t h, slong n) + + Set $g = \operatorname{tanh}(h) + O(x^n)$. + +******************************************************************************* + + Products + +******************************************************************************* + +void _nmod_poly_product_roots_nmod_vec(mp_ptr poly, mp_srcptr xs, + slong n, nmod_t mod) + + Sets \code{(poly, n + 1)} to the monic polynomial which is the product + of $(x - x_0)(x - x_1) \cdots (x - x_{n-1})$, the roots $x_i$ being + given by \code{xs}. + + Aliasing of the input and output is not allowed. + +void nmod_poly_product_roots_nmod_vec(nmod_poly_t poly, mp_srcptr xs, slong n) + + Sets \code{poly} to the monic polynomial which is the product + of $(x - x_0)(x - x_1) \cdots (x - x_{n-1})$, the roots $x_i$ being + given by \code{xs}. + +******************************************************************************* + + Subproduct trees + +******************************************************************************* + +mp_ptr * _nmod_poly_tree_alloc(slong len) + + Allocates space for a subproduct tree of the given length, having + linear factors at the lowest level. + + Entry $i$ in the tree is a pointer to a single array of limbs, + capable of storing $\lfloor n / 2^i \rfloor$ subproducts of + degree $2^i$ adjacently, plus a trailing entry if $n / 2^i$ is + not an integer. + + For example, a tree of length 7 built from monic linear factors has + the following structure, where spaces have been inserted + for illustrative purposes: + + \begin{verbatim} + X1 X1 X1 X1 X1 X1 X1 + XX1 XX1 XX1 X1 + XXXX1 XX1 X1 + XXXXXXX1 + \end{verbatim} + +void _nmod_poly_tree_free(mp_ptr * tree, slong len) + + Free the allocated space for the subproduct. + +void _nmod_poly_tree_build(mp_ptr * tree, mp_srcptr roots, slong len, + nmod_t mod) + + Builds a subproduct tree in the preallocated space from + the \code{len} monic linear factors $(x-r_i)$. The top level + product is not computed. + + +******************************************************************************* + + Inflation and deflation + +******************************************************************************* + +void nmod_poly_inflate(nmod_poly_t result, const nmod_poly_t input, + ulong inflation) + + Sets \code{result} to the inflated polynomial $p(x^n)$ where + $p$ is given by \code{input} and $n$ is given by \code{deflation}. + +void nmod_poly_deflate(nmod_poly_t result, const nmod_poly_t input, + ulong deflation) + + Sets \code{result} to the deflated polynomial $p(x^{1/n})$ where + $p$ is given by \code{input} and $n$ is given by \code{deflation}. + Requires $n > 0$. + +ulong nmod_poly_deflation(const nmod_poly_t input) + + Returns the largest integer by which \code{input} can be deflated. + As special cases, returns 0 if \code{input} is the zero polynomial + and 1 of \code{input} is a constant polynomial. diff --git a/external/flint-2.4.3/nmod_poly/evaluate_fmpz.c b/external/flint-2.4.3/nmod_poly/evaluate_fmpz.c new file mode 100644 index 0000000..39e2588 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/evaluate_fmpz.c @@ -0,0 +1,72 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2013 Mike Hansen + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_poly.h" + +/* TODO: Add a divconquer method */ + +void +_nmod_poly_evaluate_fmpz(fmpz_t rop, const mp_srcptr poly, const slong len, const fmpz_t c) +{ + fmpz_t t; + slong m; + + if (len == 0) + { + fmpz_zero(rop); + return; + } + + if (len == 1 || c == 0) + { + fmpz_set_ui(rop, poly[0]); + return; + } + + m = len - 1; + + + fmpz_init(t); + fmpz_set_ui(rop, poly[m]); + m--; + + for ( ; m >= 0; m--) + { + fmpz_mul(t, rop, c); + fmpz_add_ui(rop, t, poly[m]); + } + fmpz_clear(t); +} + +void +nmod_poly_evaluate_fmpz(fmpz_t rop, const nmod_poly_t poly, const fmpz_t c) +{ + _nmod_poly_evaluate_fmpz(rop, poly->coeffs, poly->length, c); +} + diff --git a/external/flint-2.4.3/nmod_poly/evaluate_nmod.c b/external/flint-2.4.3/nmod_poly/evaluate_nmod.c new file mode 100644 index 0000000..f1b8aa9 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/evaluate_nmod.c @@ -0,0 +1,62 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_poly.h" + +mp_limb_t +_nmod_poly_evaluate_nmod(mp_srcptr poly, slong len, mp_limb_t c, nmod_t mod) +{ + slong m; + mp_limb_t val; + + if (len == 0) + return 0; + + if (len == 1 || c == 0) + return poly[0]; + + m = len - 1; + + val = poly[m]; + m--; + + for ( ; m >= 0; m--) + { + val = n_mulmod2_preinv(val, c, mod.n, mod.ninv); + val = n_addmod(val, poly[m], mod.n); + } + + return val; +} + +mp_limb_t +nmod_poly_evaluate_nmod(const nmod_poly_t poly, mp_limb_t c) +{ + return _nmod_poly_evaluate_nmod(poly->coeffs, poly->length, c, poly->mod); +} + diff --git a/external/flint-2.4.3/nmod_poly/evaluate_nmod_vec.c b/external/flint-2.4.3/nmod_poly/evaluate_nmod_vec.c new file mode 100644 index 0000000..5ce96df --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/evaluate_nmod_vec.c @@ -0,0 +1,47 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_poly.h" + +void +_nmod_poly_evaluate_nmod_vec(mp_ptr ys, mp_srcptr coeffs, slong len, + mp_srcptr xs, slong n, nmod_t mod) +{ + if (len < 32) + _nmod_poly_evaluate_nmod_vec_iter(ys, coeffs, len, xs, n, mod); + else + _nmod_poly_evaluate_nmod_vec_fast(ys, coeffs, len, xs, n, mod); +} + +void +nmod_poly_evaluate_nmod_vec(mp_ptr ys, + const nmod_poly_t poly, mp_srcptr xs, slong n) +{ + _nmod_poly_evaluate_nmod_vec(ys, poly->coeffs, + poly->length, xs, n, poly->mod); +} diff --git a/external/flint-2.4.3/nmod_poly/evaluate_nmod_vec_fast.c b/external/flint-2.4.3/nmod_poly/evaluate_nmod_vec_fast.c new file mode 100644 index 0000000..59b4fa3 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/evaluate_nmod_vec_fast.c @@ -0,0 +1,137 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_poly.h" + +/* This gives some speedup for small lengths. */ +static __inline__ void _nmod_poly_rem_2(mp_ptr r, mp_srcptr a, slong al, + mp_srcptr b, slong bl, nmod_t mod) +{ + if (al == 2) + r[0] = nmod_sub(a[0], nmod_mul(a[1], b[0], mod), mod); + else + _nmod_poly_rem(r, a, al, b, bl, mod); +} + +void +_nmod_poly_evaluate_nmod_vec_fast_precomp(mp_ptr vs, mp_srcptr poly, + slong plen, const mp_ptr * tree, slong len, nmod_t mod) +{ + slong height, i, j, pow, left; + slong tree_height; + slong tlen; + mp_ptr t, u, swap, pa, pb, pc; + + /* avoid worrying about some degenerate cases */ + if (len < 2 || plen < 2) + { + if (len == 1) + vs[0] = _nmod_poly_evaluate_nmod(poly, plen, + nmod_neg(tree[0][0], mod), mod); + else if (len != 0 && plen == 0) + _nmod_vec_zero(vs, len); + else if (len != 0 && plen == 1) + for (i = 0; i < len; i++) + vs[i] = poly[0]; + return; + } + + t = _nmod_vec_init(len); + u = _nmod_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 = WORD(1) << height; + + for (i = j = 0; i < len; i += pow, j += (pow + 1)) + { + tlen = ((i + pow) <= len) ? pow : len % pow; + _nmod_poly_rem(t + i, poly, plen, tree[height] + j, tlen + 1, mod); + } + + for (i = height - 1; i >= 0; i--) + { + pow = WORD(1) << i; + left = len; + pa = tree[i]; + pb = t; + pc = u; + + while (left >= 2 * pow) + { + _nmod_poly_rem_2(pc, pb, 2 * pow, pa, pow + 1, mod); + _nmod_poly_rem_2(pc + pow, pb, 2 * pow, pa + pow + 1, pow + 1, mod); + + pa += 2 * pow + 2; + pb += 2 * pow; + pc += 2 * pow; + left -= 2 * pow; + } + + if (left > pow) + { + _nmod_poly_rem(pc, pb, left, pa, pow + 1, mod); + _nmod_poly_rem(pc + pow, pb, left, pa + pow + 1, left - pow + 1, mod); + } + else if (left > 0) + _nmod_vec_set(pc, pb, left); + + swap = t; + t = u; + u = swap; + } + + _nmod_vec_set(vs, t, len); + _nmod_vec_clear(t); + _nmod_vec_clear(u); +} + +void _nmod_poly_evaluate_nmod_vec_fast(mp_ptr ys, mp_srcptr poly, slong plen, + mp_srcptr xs, slong n, nmod_t mod) +{ + mp_ptr * tree; + + tree = _nmod_poly_tree_alloc(n); + _nmod_poly_tree_build(tree, xs, n, mod); + _nmod_poly_evaluate_nmod_vec_fast_precomp(ys, poly, plen, tree, n, mod); + _nmod_poly_tree_free(tree, n); +} + +void +nmod_poly_evaluate_nmod_vec_fast(mp_ptr ys, + const nmod_poly_t poly, mp_srcptr xs, slong n) +{ + _nmod_poly_evaluate_nmod_vec_fast(ys, poly->coeffs, + poly->length, xs, n, poly->mod); +} diff --git a/external/flint-2.4.3/nmod_poly/evaluate_nmod_vec_iter.c b/external/flint-2.4.3/nmod_poly/evaluate_nmod_vec_iter.c new file mode 100644 index 0000000..33e938a --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/evaluate_nmod_vec_iter.c @@ -0,0 +1,46 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_poly.h" + +void +_nmod_poly_evaluate_nmod_vec_iter(mp_ptr ys, mp_srcptr coeffs, slong len, + mp_srcptr xs, slong n, nmod_t mod) +{ + slong i; + for (i = 0; i < n; i++) + ys[i] = _nmod_poly_evaluate_nmod(coeffs, len, xs[i], mod); +} + +void +nmod_poly_evaluate_nmod_vec_iter(mp_ptr ys, + const nmod_poly_t poly, mp_srcptr xs, slong n) +{ + _nmod_poly_evaluate_nmod_vec_iter(ys, poly->coeffs, + poly->length, xs, n, poly->mod); +} diff --git a/external/flint-2.4.3/nmod_poly/exp_series.c b/external/flint-2.4.3/nmod_poly/exp_series.c new file mode 100644 index 0000000..f8adc2a --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/exp_series.c @@ -0,0 +1,215 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +#define NMOD_POLY_NEWTON_EXP_CUTOFF 200 + +/* 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 +_nmod_poly_exp_series_newton(mp_ptr f, mp_ptr g, + mp_srcptr h, slong n, nmod_t mod, int inverse) +{ + slong a[FLINT_BITS]; + slong i, m, m2, l; + mp_ptr T, U, hprime; + + T = _nmod_vec_init(n); + U = _nmod_vec_init(n); + hprime = _nmod_vec_init(n); + + _nmod_poly_derivative(hprime, h, n, mod); + hprime[n-1] = UWORD(0); + + for (i = 1; (WORD(1) << i) < n; i++); + a[i = 0] = n; + while (n >= NMOD_POLY_NEWTON_EXP_CUTOFF) + a[++i] = (n = (n + 1) / 2); + + /* f := exp(h) + O(x^m), g := exp(-h) + O(x^m2) */ + _nmod_poly_exp_series_basecase(f, h, n, n, mod); + _nmod_poly_inv_series_basecase(g, f, (n + 1) / 2, mod); + + for (i--; i >= 0; i--) + { + m = n; /* previous length */ + n = a[i]; /* new length */ + m2 = (m + 1) / 2; + l = m - 1; /* shifted for derivative */ + + /* g := exp(-h) + O(x^m) */ + _nmod_poly_mullow(T, f, m, g, m2, m, mod); + _nmod_poly_mullow(g + m2, g, m2, T + m2, m - m2, m - m2, mod); + _nmod_vec_neg(g + m2, g + m2, m - m2, mod); + + /* U := h' + g (f' - f h') + O(x^(n-1)) + Note: should replace h' by h' mod x^(m-1) */ + _nmod_vec_zero(f + m, n - m); + _nmod_poly_mullow(T, f, n, hprime, n, n, mod); /* should be mulmid */ + _nmod_poly_derivative(U, f, n, mod); U[n - 1] = 0; /* should skip low terms */ + _nmod_vec_sub(U + l, U + l, T + l, n - l, mod); + _nmod_poly_mullow(T + l, g, n - m, U + l, n - m, n - m, mod); + _nmod_vec_add(U + l, hprime + l, T + l, n - m, mod); + + /* f := f + f * (h - int U) + O(x^n) = exp(h) + O(x^n) */ + _nmod_poly_integral(U, U, n, mod); /* should skip low terms */ + _nmod_vec_sub(U + m, h + m, U + m, n - m, mod); + _nmod_poly_mullow(f + m, f, n - m, U + m, n - m, n - m, mod); + + /* g := exp(-h) + O(x^n) */ + /* not needed if we only want exp(x) */ + if (i == 0 && inverse) + { + _nmod_poly_mullow(T, f, n, g, m, n, mod); + _nmod_poly_mullow(g + m, g, m, T + m, n - m, n - m, mod); + _nmod_vec_neg(g + m, g + m, n - m, mod); + } + } + + _nmod_vec_clear(hprime); + _nmod_vec_clear(T); + _nmod_vec_clear(U); +} + +void +_nmod_poly_exp_expinv_series(mp_ptr f, mp_ptr g, mp_srcptr h, slong n, nmod_t mod) +{ + if (n < NMOD_POLY_NEWTON_EXP_CUTOFF) + { + _nmod_poly_exp_series_basecase(f, h, n, n, mod); + _nmod_poly_inv_series(g, f, n, mod); + } + else + { + _nmod_poly_exp_series_newton(f, g, h, n, mod, 1); + } +} + +void +_nmod_poly_exp_series(mp_ptr f, mp_srcptr h, slong n, nmod_t mod) +{ + if (n < NMOD_POLY_NEWTON_EXP_CUTOFF) + { + _nmod_poly_exp_series_basecase(f, h, n, n, mod); + } + else + { + mp_ptr g = _nmod_vec_init((n + 1) / 2); + _nmod_poly_exp_series_newton(f, g, h, n, mod, 0); + _nmod_vec_clear(g); + } +} + +void +nmod_poly_exp_series(nmod_poly_t f, const nmod_poly_t h, slong n) +{ + mp_ptr f_coeffs, h_coeffs; + nmod_poly_t t1; + slong hlen, k; + + nmod_poly_fit_length(f, n); + hlen = h->length; + + if (hlen > 0 && h->coeffs[0] != UWORD(0)) + { + flint_printf("Exception (nmod_poly_exp_series). Constant term != 0.\n"); + abort(); + } + + if (n <= 1 || hlen == 0) + { + if (n == 0) + { + nmod_poly_zero(f); + } + else + { + f->coeffs[0] = UWORD(1); + f->length = 1; + } + return; + } + + /* Handle monomials */ + for (k = 0; h->coeffs[k] == UWORD(0) && k < n - 1; k++); + if (k == hlen - 1 || k == n - 1) + { + hlen = FLINT_MIN(hlen, n); + _nmod_poly_exp_series_monomial_ui(f->coeffs, + h->coeffs[hlen-1], hlen - 1, n, f->mod); + f->length = n; + _nmod_poly_normalise(f); + return; + } + + if (n < NMOD_POLY_NEWTON_EXP_CUTOFF) + { + _nmod_poly_exp_series_basecase(f->coeffs, h->coeffs, hlen, n, f->mod); + f->length = n; + _nmod_poly_normalise(f); + return; + } + + if (hlen < n) + { + h_coeffs = _nmod_vec_init(n); + flint_mpn_copyi(h_coeffs, h->coeffs, hlen); + flint_mpn_zero(h_coeffs + hlen, n - hlen); + } + else + h_coeffs = h->coeffs; + + if (h == f && hlen >= n) + { + nmod_poly_init2(t1, h->mod.n, n); + f_coeffs = t1->coeffs; + } + else + { + nmod_poly_fit_length(f, n); + f_coeffs = f->coeffs; + } + + _nmod_poly_exp_series(f_coeffs, h_coeffs, n, f->mod); + + if (h == f && hlen >= n) + { + nmod_poly_swap(f, t1); + nmod_poly_clear(t1); + } + + f->length = n; + + if (hlen < n) + _nmod_vec_clear(h_coeffs); + + _nmod_poly_normalise(f); +} diff --git a/external/flint-2.4.3/nmod_poly/exp_series_basecase.c b/external/flint-2.4.3/nmod_poly/exp_series_basecase.c new file mode 100644 index 0000000..167558c --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/exp_series_basecase.c @@ -0,0 +1,89 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + + +void +_nmod_poly_exp_series_basecase(mp_ptr f, mp_srcptr h, + slong hlen, slong n, nmod_t mod) +{ + slong j, k; + mp_ptr a; + mp_limb_t s; + + f[0] = UWORD(1); + + a = _nmod_vec_init(FLINT_MIN(n, hlen)); + for (k = 1; k < FLINT_MIN(n, hlen); k++) + a[k] = n_mulmod2_preinv(h[k], k, mod.n, mod.ninv); + + for (k = 1; k < n; k++) + { + s = n_mulmod2_preinv(a[1], f[k-1], mod.n, mod.ninv); + for (j = 2; j < FLINT_MIN(k + 1, hlen); j++) + NMOD_ADDMUL(s, a[j], f[k - j], mod); + f[k] = n_mulmod2_preinv(s, n_invmod(k, mod.n), mod.n, mod.ninv); + } + + _nmod_vec_clear(a); +} + +void +nmod_poly_exp_series_basecase(nmod_poly_t f, const nmod_poly_t h, slong n) +{ + slong hlen; + + nmod_poly_fit_length(f, n); + hlen = h->length; + + if (hlen > 0 && h->coeffs[0] != UWORD(0)) + { + flint_printf("Exception (nmod_poly_exp_series_basecase). Constant term != 0.\n"); + abort(); + } + + if (n <= 1 || hlen == 0) + { + if (n == 0) + { + nmod_poly_zero(f); + } + else + { + f->coeffs[0] = UWORD(1); + f->length = 1; + } + return; + } + + _nmod_poly_exp_series_basecase(f->coeffs, h->coeffs, hlen, n, f->mod); + f->length = n; + _nmod_poly_normalise(f); +} diff --git a/external/flint-2.4.3/nmod_poly/exp_series_monomial_ui.c b/external/flint-2.4.3/nmod_poly/exp_series_monomial_ui.c new file mode 100644 index 0000000..ba2751a --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/exp_series_monomial_ui.c @@ -0,0 +1,116 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +void +_nmod_poly_exp_series_monomial_ui(mp_ptr res, mp_limb_t coeff, ulong power, + slong n, nmod_t mod) +{ + slong k, r; + mp_limb_t rfac; + mp_limb_t a; + + r = (n - 1) / power; + rfac = n_factorial_mod2_preinv(r, mod.n, mod.ninv); + rfac = n_invmod(rfac, mod.n); + + if (power > 1) + _nmod_vec_zero(res, n); + + res[0] = UWORD(1); + + if (coeff == UWORD(1)) + { + a = rfac; + for (k = r; k >= 1; k--) + { + res[k * power] = a; + a = n_mulmod2_preinv(a, k, mod.n, mod.ninv); + } + } + else + { + a = coeff; + for (k = power; k < n; k += power) + { + res[k] = a; + a = n_mulmod2_preinv(a, coeff, mod.n, mod.ninv); + } + + a = rfac; + for (k = r; k >= 1; k--) + { + res[k * power] = n_mulmod2_preinv(res[k * power], + a, mod.n, mod.ninv); + a = n_mulmod2_preinv(a, k, mod.n, mod.ninv); + } + } +} + +void +nmod_poly_exp_series_monomial_ui(nmod_poly_t res, mp_limb_t coeff, + ulong power, slong n) +{ + if (n == 0) + { + nmod_poly_zero(res); + return; + } + + if (coeff == UWORD(0)) + { + nmod_poly_fit_length(res, 1); + res->coeffs[0] = UWORD(1); + res->length = 1; + return; + } + + if (power == 0) + { + flint_printf("Exception (nmod_poly_exp_series_monomial_ui). \n" + "Constant term != 0.\n"); + abort(); + } + + if (coeff != UWORD(1)) + coeff = n_mod2_preinv(coeff, res->mod.n, res->mod.ninv); + + if (n == 1 || power >= n) + { + nmod_poly_fit_length(res, 1); + res->coeffs[0] = UWORD(1); + res->length = 1; + } + + nmod_poly_fit_length(res, n); + _nmod_poly_exp_series_monomial_ui(res->coeffs, coeff, power, n, res->mod); + res->length = n; + _nmod_poly_normalise(res); +} diff --git a/external/flint-2.4.3/nmod_poly/fit_length.c b/external/flint-2.4.3/nmod_poly/fit_length.c new file mode 100644 index 0000000..60c25e2 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/fit_length.c @@ -0,0 +1,43 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007, David Howden. + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_poly.h" + +void +nmod_poly_fit_length(nmod_poly_t poly, slong alloc) +{ + if (alloc > poly->alloc) + { + if (alloc < 2 * poly->alloc) + alloc = 2 * poly->alloc; + + nmod_poly_realloc(poly, alloc); + } +} diff --git a/external/flint-2.4.3/nmod_poly/fread.c b/external/flint-2.4.3/nmod_poly/fread.c new file mode 100644 index 0000000..160e08f --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/fread.c @@ -0,0 +1,57 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007, David Howden. + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_poly.h" + +int nmod_poly_fread(FILE * f, nmod_poly_t poly) +{ + slong i, length; + mp_limb_t n; + + if (flint_fscanf(f, "%wd %wu", &length, &n) != 2) + return 0; + + nmod_poly_clear(poly); + nmod_poly_init(poly,n); + nmod_poly_fit_length(poly, length); + poly->length = length; + + for (i = 0; i < length; i++) + { + if (!flint_fscanf(f, "%wu", &poly->coeffs[i])) + { + poly->length = i; + return 0; + } + } + + _nmod_poly_normalise(poly); + + return 1; +} diff --git a/external/flint-2.4.3/nmod_poly/gcd.c b/external/flint-2.4.3/nmod_poly/gcd.c new file mode 100644 index 0000000..9e8ce07 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/gcd.c @@ -0,0 +1,90 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "nmod_poly.h" + +slong _nmod_poly_gcd(mp_ptr G, mp_srcptr A, slong lenA, + mp_srcptr B, slong lenB, nmod_t mod) +{ + const slong cutoff = FLINT_BIT_COUNT(mod.n) <= 8 ? + NMOD_POLY_SMALL_GCD_CUTOFF : NMOD_POLY_GCD_CUTOFF; + + if (lenA < cutoff) + return _nmod_poly_gcd_euclidean(G, A, lenA, B, lenB, mod); + else + return _nmod_poly_gcd_hgcd(G, A, lenA, B, lenB, mod); +} + +void nmod_poly_gcd(nmod_poly_t G, + const nmod_poly_t A, const nmod_poly_t B) +{ + if (A->length < B->length) + { + nmod_poly_gcd(G, B, A); + } + else /* lenA >= lenB >= 0 */ + { + slong lenA = A->length, lenB = B->length, lenG; + nmod_poly_t tG; + mp_ptr g; + + if (lenA == 0) /* lenA = lenB = 0 */ + { + nmod_poly_zero(G); + } + else if (lenB == 0) /* lenA > lenB = 0 */ + { + nmod_poly_make_monic(G, A); + } + else /* lenA >= lenB >= 1 */ + { + if (G == A || G == B) + { + nmod_poly_init2(tG, A->mod.n, FLINT_MIN(lenA, lenB)); + g = tG->coeffs; + } + else + { + nmod_poly_fit_length(G, FLINT_MIN(lenA, lenB)); + g = G->coeffs; + } + + lenG = _nmod_poly_gcd(g, A->coeffs, lenA, + B->coeffs, lenB, A->mod); + + if (G == A || G == B) + { + nmod_poly_swap(tG, G); + nmod_poly_clear(tG); + } + G->length = lenG; + + if (G->length == 1) + G->coeffs[0] = 1; + else + nmod_poly_make_monic(G, G); + } + } +} diff --git a/external/flint-2.4.3/nmod_poly/gcd_euclidean.c b/external/flint-2.4.3/nmod_poly/gcd_euclidean.c new file mode 100644 index 0000000..92618b8 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/gcd_euclidean.c @@ -0,0 +1,149 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 William Hart + +******************************************************************************/ + +#include +#include "nmod_poly.h" +#include "mpn_extras.h" + +slong _nmod_poly_gcd_euclidean(mp_ptr G, mp_srcptr A, slong lenA, + mp_srcptr B, slong lenB, nmod_t mod) +{ + slong steps; + slong lenR1, lenR2 = 0, lenG = 0; + + mp_ptr F, R1, R2, R3 = G, T; + + if (lenB == 1) + { + G[0] = B[0]; + return 1; + } + + F = _nmod_vec_init(2*lenB - 3); + R1 = F; + R2 = R1 + lenB - 1; + + _nmod_poly_rem(R1, A, lenA, B, lenB, mod); + lenR1 = lenB - 1; + MPN_NORM(R1, lenR1); + + if (lenR1 > 1) + { + _nmod_poly_rem(R2, B, lenB, R1, lenR1, mod); + lenR2 = lenR1 - 1; + MPN_NORM(R2, lenR2); + } + else + { + if (lenR1 == 0) + { + flint_mpn_copyi(G, B, lenB); + _nmod_vec_clear(F); + return lenB; + } + else + { + G[0] = R1[0]; + _nmod_vec_clear(F); + return 1; + } + } + + for (steps = 2; lenR2 > 1; steps++) + { + _nmod_poly_rem(R3, R1, lenR1, R2, lenR2, mod); + lenR1 = lenR2--; + MPN_NORM(R3, lenR2); + T = R1; R1 = R2; R2 = R3; R3 = T; + } + + if (lenR2 == 1) + { + lenG = 1; + if (steps % 3) + G[0] = R2[0]; + } + else + { + lenG = lenR1; + if (steps % 3 != 1) + flint_mpn_copyi(G, R1, lenR1); + } + + _nmod_vec_clear(F); + return lenG; +} + +void nmod_poly_gcd_euclidean(nmod_poly_t G, + const nmod_poly_t A, const nmod_poly_t B) +{ + if (A->length < B->length) + { + nmod_poly_gcd_euclidean(G, B, A); + } + else /* lenA >= lenB >= 0 */ + { + slong lenA = A->length, lenB = B->length, lenG; + nmod_poly_t tG; + mp_ptr g; + + if (lenA == 0) /* lenA = lenB = 0 */ + { + nmod_poly_zero(G); + } + else if (lenB == 0) /* lenA > lenB = 0 */ + { + nmod_poly_make_monic(G, A); + } + else /* lenA >= lenB >= 1 */ + { + if (G == A || G == B) + { + nmod_poly_init2(tG, A->mod.n, FLINT_MIN(lenA, lenB)); + g = tG->coeffs; + } + else + { + nmod_poly_fit_length(G, FLINT_MIN(lenA, lenB)); + g = G->coeffs; + } + + lenG = _nmod_poly_gcd_euclidean(g, A->coeffs, lenA, + B->coeffs, lenB, A->mod); + + if (G == A || G == B) + { + nmod_poly_swap(tG, G); + nmod_poly_clear(tG); + } + G->length = lenG; + + if (G->length == 1) + G->coeffs[0] = 1; + else + nmod_poly_make_monic(G, G); + } + } +} diff --git a/external/flint-2.4.3/nmod_poly/gcd_hgcd.c b/external/flint-2.4.3/nmod_poly/gcd_hgcd.c new file mode 100644 index 0000000..8d9ad30 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/gcd_hgcd.c @@ -0,0 +1,156 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "nmod_poly.h" +#include "mpn_extras.h" + +#define __set(B, lenB, A, lenA) \ +do { \ + _nmod_vec_set((B), (A), (lenA)); \ + (lenB) = (lenA); \ +} while (0) + +#define __rem(R, lenR, A, lenA, B, lenB) \ +do { \ + if ((lenA) >= (lenB)) \ + { \ + _nmod_poly_rem((R), (A), (lenA), (B), (lenB), mod); \ + (lenR) = (lenB) - 1; \ + MPN_NORM((R), (lenR)); \ + } \ + else \ + { \ + _nmod_vec_set((R), (A), (lenA)); \ + (lenR) = (lenA); \ + } \ +} while (0) + +/* + XXX: Incidentally, this implementation currently supports aliasing. + But since this may change in the future, no function other than + nmod_poly_gcd_hgcd() should rely on this. + */ + +slong _nmod_poly_gcd_hgcd(mp_ptr G, mp_srcptr A, slong lenA, + mp_srcptr B, slong lenB, nmod_t mod) +{ + const slong cutoff = FLINT_BIT_COUNT(mod.n) <= 8 ? + NMOD_POLY_SMALL_GCD_CUTOFF : NMOD_POLY_GCD_CUTOFF; + + mp_ptr J = _nmod_vec_init(2 * lenB); + mp_ptr R = J + lenB; + + slong lenG, lenJ, lenR; + + __rem(R, lenR, A, lenA, B, lenB); + + if (lenR == 0) + { + __set(G, lenG, B, lenB); + } + else + { + _nmod_poly_hgcd(NULL, NULL, G, &(lenG), J, &(lenJ), B, lenB, R, lenR, mod); + + while (lenJ != 0) + { + __rem(R, lenR, G, lenG, J, lenJ); + + if (lenR == 0) + { + __set(G, lenG, J, lenJ); + break; + } + if (lenJ < cutoff) + { + lenG = _nmod_poly_gcd_euclidean(G, J, lenJ, R, lenR, mod); + break; + } + + _nmod_poly_hgcd(NULL, NULL, G, &(lenG), J, &(lenJ), J, lenJ, R, lenR, mod); + } + } + _nmod_vec_clear(J); + + return lenG; +} + +void nmod_poly_gcd_hgcd(nmod_poly_t G, + const nmod_poly_t A, const nmod_poly_t B) +{ + if (A->length < B->length) + { + nmod_poly_gcd_hgcd(G, B, A); + } + else /* lenA >= lenB >= 0 */ + { + slong lenA = A->length, lenB = B->length, lenG; + nmod_poly_t tG; + mp_ptr g; + + if (lenA == 0) /* lenA = lenB = 0 */ + { + nmod_poly_zero(G); + } + else if (lenB == 0) /* lenA > lenB = 0 */ + { + nmod_poly_make_monic(G, A); + } + else /* lenA >= lenB >= 1 */ + { + if (G == A || G == B) + { + nmod_poly_init2(tG, A->mod.n, FLINT_MIN(lenA, lenB)); + g = tG->coeffs; + } + else + { + nmod_poly_fit_length(G, FLINT_MIN(lenA, lenB)); + g = G->coeffs; + } + + lenG = _nmod_poly_gcd_hgcd(g, A->coeffs, lenA, + B->coeffs, lenB, A->mod); + + if (G == A || G == B) + { + nmod_poly_swap(tG, G); + nmod_poly_clear(tG); + } + G->length = lenG; + + if (G->length == 1) + G->coeffs[0] = 1; + else + nmod_poly_make_monic(G, G); + } + } +} + +#undef __set +#undef __rem + diff --git a/external/flint-2.4.3/nmod_poly/gcdinv.c b/external/flint-2.4.3/nmod_poly/gcdinv.c new file mode 100644 index 0000000..375374c --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/gcdinv.c @@ -0,0 +1,132 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include +#include "nmod_vec.h" +#include "nmod_poly.h" + +slong _nmod_poly_gcdinv(mp_limb_t *G, mp_limb_t *S, + const mp_limb_t *A, slong lenA, + const mp_limb_t *B, slong lenB, + const nmod_t mod) +{ + mp_limb_t *T; + slong ans; + + T = _nmod_vec_init(lenA - 1); + + ans = _nmod_poly_xgcd(G, T, S, B, lenB, A, lenA, mod); + + _nmod_vec_clear(T); + + return ans; +} + +void nmod_poly_gcdinv(nmod_poly_t G, nmod_poly_t S, + const nmod_poly_t A, const nmod_poly_t B) +{ + const slong lenA = A->length, lenB = B->length; + + if (lenB < 2) + { + printf("Exception (nmod_poly_gcdinv). lenB < 2.\n"); + abort(); + } + if (lenA >= lenB) + { + nmod_poly_t T; + + /* TODO: We can probably use init_preinv here */ + nmod_poly_init(T, A->mod.n); + nmod_poly_rem(T, A, B); + nmod_poly_gcdinv(G, S, T, B); + nmod_poly_clear(T); + return; + } + + if (lenA == 0) + { + nmod_poly_zero(G); + nmod_poly_zero(S); + } + else + { + mp_limb_t *g, *s; + slong lenG; + + if (G == A || G == B) + { + g = _nmod_vec_init(lenA); + } + else + { + nmod_poly_fit_length(G, lenA); + g = G->coeffs; + } + if (S == A || S == B) + { + s = _nmod_vec_init(lenB - 1); + } + else + { + nmod_poly_fit_length(S, lenB - 1); + s = S->coeffs; + } + + lenG = _nmod_poly_gcdinv(g, s, + A->coeffs, lenA, + B->coeffs, lenB, + A->mod); + + if (G == A || G == B) + { + _nmod_vec_clear(G->coeffs); + G->coeffs = g; + G->alloc = lenA; + } + if (S == A || S == B) + { + _nmod_vec_clear(S->coeffs); + S->coeffs = s; + S->alloc = lenB - 1; + } + + _nmod_poly_set_length(G, lenG); + _nmod_poly_set_length(S, lenB - lenG); + _nmod_poly_normalise(S); + + if (nmod_poly_lead(G)[0] != WORD(1)) + { + mp_limb_t inv; + + inv = n_invmod(nmod_poly_lead(G)[0], A->mod.n); + nmod_poly_scalar_mul_nmod(G, G, inv); + nmod_poly_scalar_mul_nmod(S, S, inv); + } + } +} + diff --git a/external/flint-2.4.3/nmod_poly/get_str.c b/external/flint-2.4.3/nmod_poly/get_str.c new file mode 100644 index 0000000..7d43442 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/get_str.c @@ -0,0 +1,64 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007, David Howden. + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" + +char * nmod_poly_get_str(const nmod_poly_t poly) +{ + slong i; + char * buf, * ptr; + + /* estimate for the length, n and three spaces */ +#if FLINT64 + slong size = 21*2 + 1; +#else + slong size = 11*2 + 1; +#endif + + for (i = 0; i < poly->length; i++) + { + if (poly->coeffs[i]) /* log(2)/log(10) < 0.30103, +1 for space/null */ + size += (ulong) ceil(0.30103*FLINT_BIT_COUNT(poly->coeffs[i])) + 1; + else size += 2; + } + + buf = (char *) flint_malloc(size); + ptr = buf + flint_sprintf(buf, "%wd %wu", poly->length, poly->mod.n); + + if (poly->length) + ptr += flint_sprintf(ptr, " "); + + for (i = 0; i < poly->length; i++) + ptr += flint_sprintf(ptr, " %wu", poly->coeffs[i]); + + return buf; +} + diff --git a/external/flint-2.4.3/nmod_poly/hgcd.c b/external/flint-2.4.3/nmod_poly/hgcd.c new file mode 100644 index 0000000..7755380 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/hgcd.c @@ -0,0 +1,507 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" +#include "mpn_extras.h" + +/* + We define a whole bunch of macros here which essentially provide + the nmod_poly functionality as far as the setting of coefficient + data and lengths is concerned, but which do not do any separate + memory allocation. None of these macros support aliasing. + */ + +#define __attach_shift(B, lenB, A, lenA, m) \ +do { \ + (B) = (A) + (m); \ + (lenB) = ((lenA) >= (m)) ? (lenA) - (m) : 0; \ +} while (0) + +#define __attach_truncate(B, lenB, A, lenA, m) \ +do { \ + (B) = (A); \ + (lenB) = ((lenA) < (m)) ? (lenA) : (m); \ +} while (0) + +#define __set(B, lenB, A, lenA) \ +do { \ + _nmod_vec_set((B), (A), (lenA)); \ + (lenB) = (lenA); \ +} while (0) + +#define __swap MPN_SWAP + +#define __add(C, lenC, A, lenA, B, lenB) \ +do { \ + _nmod_poly_add((C), (A), (lenA), (B), (lenB), mod); \ + (lenC) = FLINT_MAX((lenA), (lenB)); \ + MPN_NORM((C), (lenC)); \ +} while (0) + +#define __sub(C, lenC, A, lenA, B, lenB) \ +do { \ + _nmod_poly_sub((C), (A), (lenA), (B), (lenB), mod); \ + (lenC) = FLINT_MAX((lenA), (lenB)); \ + MPN_NORM((C), (lenC)); \ +} while (0) + +#define __mul(C, lenC, A, lenA, B, lenB) \ +do { \ + if ((lenA) != 0 && (lenB) != 0) \ + { \ + if ((lenA) >= (lenB)) \ + _nmod_poly_mul((C), (A), (lenA), (B), (lenB), mod); \ + else \ + _nmod_poly_mul((C), (B), (lenB), (A), (lenA), mod); \ + (lenC) = (lenA) + (lenB) - 1; \ + } \ + else \ + { \ + (lenC) = 0; \ + } \ +} while (0) + +#define __divrem(Q, lenQ, R, lenR, A, lenA, B, lenB) \ +do { \ + if ((lenA) >= (lenB)) \ + { \ + _nmod_poly_divrem((Q), (R), (A), (lenA), (B), (lenB), mod); \ + (lenQ) = (lenA) - (lenB) + 1; \ + (lenR) = (lenB) - 1; \ + MPN_NORM((R), (lenR)); \ + } \ + else \ + { \ + _nmod_vec_set((R), (A), (lenA)); \ + (lenQ) = 0; \ + (lenR) = (lenA); \ + } \ +} while (0) + +static __inline__ void __mat_one(mp_ptr *M, slong *lenM) +{ + M[0][0] = WORD(1); + M[3][0] = WORD(1); + lenM[0] = 1; + lenM[1] = 0; + lenM[2] = 0; + lenM[3] = 1; +} + +/* + Computes the matrix product C of the two 2x2 matrices A and B, + using classical multiplication. + + Does not support aliasing. + + Expects T to be temporary space sufficient for any of the + polynomial products involved. + */ + +static void __mat_mul_classical(mp_ptr *C, slong *lenC, + mp_ptr *A, slong *lenA, mp_ptr *B, slong *lenB, mp_ptr T, nmod_t mod) +{ + slong lenT; + + __mul(C[0], lenC[0], A[0], lenA[0], B[0], lenB[0]); + __mul(T, lenT, A[1], lenA[1], B[2], lenB[2]); + __add(C[0], lenC[0], C[0], lenC[0], T, lenT); + + __mul(C[1], lenC[1], A[0], lenA[0], B[1], lenB[1]); + __mul(T, lenT, A[1], lenA[1], B[3], lenB[3]); + __add(C[1], lenC[1], C[1], lenC[1], T, lenT); + + __mul(C[2], lenC[2], A[2], lenA[2], B[0], lenB[0]); + __mul(T, lenT, A[3], lenA[3], B[2], lenB[2]); + __add(C[2], lenC[2], C[2], lenC[2], T, lenT); + + __mul(C[3], lenC[3], A[2], lenA[2], B[1], lenB[1]); + __mul(T, lenT, A[3], lenA[3], B[3], lenB[3]); + __add(C[3], lenC[3], C[3], lenC[3], T, lenT); +} + +/* + Computes the matrix product C of the two 2x2 matrices A and B, + using Strassen multiplication. + + Does not support aliasing. + + Expects T0, T1 to be temporary space sufficient for any of the + polynomial products involved. + */ + +static void __mat_mul_strassen(mp_ptr *C, slong *lenC, + mp_ptr *A, slong *lenA, mp_ptr *B, slong *lenB, mp_ptr T0, mp_ptr T1, + nmod_t mod) +{ + slong lenT0, lenT1; + + __sub(T0, lenT0, A[0], lenA[0], A[2], lenA[2]); + __sub(T1, lenT1, B[3], lenB[3], B[1], lenB[1]); + __mul(C[2], lenC[2], T0, lenT0, T1, lenT1); + + __add(T0, lenT0, A[2], lenA[2], A[3], lenA[3]); + __sub(T1, lenT1, B[1], lenB[1], B[0], lenB[0]); + __mul(C[3], lenC[3], T0, lenT0, T1, lenT1); + + __sub(T0, lenT0, T0, lenT0, A[0], lenA[0]); + __sub(T1, lenT1, B[3], lenB[3], T1, lenT1); + __mul(C[1], lenC[1], T0, lenT0, T1, lenT1); + + __sub(T0, lenT0, A[1], lenA[1], T0, lenT0); + __mul(C[0], lenC[0], T0, lenT0, B[3], lenB[3]); + + __mul(T0, lenT0, A[0], lenA[0], B[0], lenB[0]); + + __add(C[1], lenC[1], T0, lenT0, C[1], lenC[1]); + __add(C[2], lenC[2], C[1], lenC[1], C[2], lenC[2]); + __add(C[1], lenC[1], C[1], lenC[1], C[3], lenC[3]); + __add(C[3], lenC[3], C[2], lenC[2], C[3], lenC[3]); + __add(C[1], lenC[1], C[1], lenC[1], C[0], lenC[0]); + __sub(T1, lenT1, T1, lenT1, B[2], lenB[2]); + __mul(C[0], lenC[0], A[3], lenA[3], T1, lenT1); + + __sub(C[2], lenC[2], C[2], lenC[2], C[0], lenC[0]); + __mul(C[0], lenC[0], A[1], lenA[1], B[2], lenB[2]); + + __add(C[0], lenC[0], C[0], lenC[0], T0, lenT0); +} + +/* + Computs the matrix product C of the two 2x2 matrices A and B, + using either classical or Strassen multiplication depending + on the degrees of the input polynomials. + + Does not support aliasing. + + Expects T0, T1 to be temporary space sufficient for any of the + polynomial products involved. + */ + +static void __mat_mul(mp_ptr *C, slong *lenC, + mp_ptr *A, slong *lenA, mp_ptr *B, slong *lenB, mp_ptr T0, mp_ptr T1, + nmod_t mod) +{ + slong min = lenA[0]; + + min = FLINT_MIN(min, lenA[1]); + min = FLINT_MIN(min, lenA[2]); + min = FLINT_MIN(min, lenA[3]); + min = FLINT_MIN(min, lenB[0]); + min = FLINT_MIN(min, lenB[1]); + min = FLINT_MIN(min, lenB[2]); + min = FLINT_MIN(min, lenB[3]); + + if (min < 20) + { + __mat_mul_classical(C, lenC, A, lenA, B, lenB, T0, mod); + } + else + { + __mat_mul_strassen(C, lenC, A, lenA, B, lenB, T0, T1, mod); + } +} + +/* + HGCD Iterative step. + + Only supports aliasing in {*A,a} and {*B,b}. + + Assumes that lena > lenb > 0. + + Assumes that the pointers {*A, *B, *T} as well as + {M + 0, M + 1, M + 2, M + 3, t} may be swapped. + With the underlying HGCD implementation in mind, + this is to say that the blocks of memory implicitly + reserved for these pointers probably should have + the same size. + + Expects {*A, *B, *T} to be of size at least lena, + {M + 0, M + 1, M + 2, M + 3, *t} and Q of size at + least (lena + 1)/2. + */ + +slong _nmod_poly_hgcd_recursive_iter(mp_ptr *M, slong *lenM, + mp_ptr *A, slong *lenA, mp_ptr *B, slong *lenB, + mp_srcptr a, slong lena, mp_srcptr b, slong lenb, + mp_ptr Q, mp_ptr *T, mp_ptr *t, nmod_t mod) +{ + const slong m = lena / 2; + slong sgn = 1; + + __mat_one(M, lenM); + __set(*A, *lenA, a, lena); + __set(*B, *lenB, b, lenb); + + while (*lenB >= m + 1) + { + slong lenQ, lenT, lent; + + __divrem(Q, lenQ, *T, lenT, *A, *lenA, *B, *lenB); + __swap(*B, *lenB, *T, lenT); + __swap(*A, *lenA, *T, lenT); + + __mul(*T, lenT, Q, lenQ, M[2], lenM[2]); + __add(*t, lent, M[3], lenM[3], *T, lenT); + __swap(M[3], lenM[3], M[2], lenM[2]); + __swap(M[2], lenM[2], *t, lent); + + __mul(*T, lenT, Q, lenQ, M[0], lenM[0]); + __add(*t, lent, M[1], lenM[1], *T, lenT); + __swap(M[1], lenM[1], M[0], lenM[0]); + __swap(M[0], lenM[0], *t, lent); + + sgn = -sgn; + } + + return sgn; +} + +/* + Assumes that lena > lenb > 0. + + The current implementation requires P to point to a memory pool + of size at least 6 lena + 10 (lena + 1)/2 just in this iteration. + + Supports aliasing only between {*A, a} and {*B, b}. + + Only computes the matrix {M, lenM} if flag is non-zero, in + which case these arrays are supposed to be sufficiently allocated. + Does not permute the pointers in {M, lenM}. When flag is zero, + the first two arguments are allowed to be NULL. + */ + +slong _nmod_poly_hgcd_recursive(mp_ptr *M, slong *lenM, + mp_ptr A, slong *lenA, mp_ptr B, slong *lenB, + mp_srcptr a, slong lena, mp_srcptr b, slong lenb, + mp_ptr P, nmod_t mod, int flag) +{ + const slong m = lena / 2; + + if (lenb < m + 1) + { + if (flag) + { + __mat_one(M, lenM); + } + __set(A, *lenA, a, lena); + __set(B, *lenB, b, lenb); + return 1; + } + else + { + /* Readonly pointers */ + mp_ptr a0, b0, s, t, a4, b4, c0, d0; + slong lena0, lenb0, lens, lent, lena4, lenb4, lenc0, lend0; + + /* Pointers to independently allocated memory */ + mp_ptr a2, b2, a3, b3, q, d, T0, T1; + slong lena2, lenb2, lena3, lenb3, lenq, lend, lenT0; + + mp_ptr R[4], S[4]; + slong lenR[4], lenS[4]; + slong sgnR, sgnS; + + a2 = P; + b2 = a2 + lena; + a3 = b2 + lena; + b3 = a3 + lena; + q = b3 + lena; + d = q + (lena + 1)/2; + T0 = d + lena; + T1 = T0 + lena; + + R[0] = T1 + (lena + 1)/2; + R[1] = R[0] + (lena + 1)/2; + R[2] = R[1] + (lena + 1)/2; + R[3] = R[2] + (lena + 1)/2; + S[0] = R[3] + (lena + 1)/2; + S[1] = S[0] + (lena + 1)/2; + S[2] = S[1] + (lena + 1)/2; + S[3] = S[2] + (lena + 1)/2; + + P += 6 * lena + 10 * (lena + 1)/2; + + __attach_shift(a0, lena0, (mp_ptr) a, lena, m); + __attach_shift(b0, lenb0, (mp_ptr) b, lenb, m); + + if (lena0 < NMOD_POLY_HGCD_CUTOFF) + sgnR = _nmod_poly_hgcd_recursive_iter(R, lenR, &a3, &lena3, &b3, &lenb3, + a0, lena0, b0, lenb0, + q, &T0, &T1, mod); + else + sgnR = _nmod_poly_hgcd_recursive(R, lenR, a3, &lena3, b3, &lenb3, + a0, lena0, b0, lenb0, P, mod, 1); + + __attach_truncate(s, lens, (mp_ptr) a, lena, m); + __attach_truncate(t, lent, (mp_ptr) b, lenb, m); + + __mul(b2, lenb2, R[2], lenR[2], s, lens); + __mul(T0, lenT0, R[0], lenR[0], t, lent); + + if (sgnR < 0) + __sub(b2, lenb2, b2, lenb2, T0, lenT0); + else + __sub(b2, lenb2, T0, lenT0, b2, lenb2); + + flint_mpn_zero(b2 + lenb2, m + lenb3 - lenb2); + + __attach_shift(b4, lenb4, b2, lenb2, m); + __add(b4, lenb4, b4, lenb4, b3, lenb3); + lenb2 = FLINT_MAX(m + lenb3, lenb2); + MPN_NORM(b2, lenb2); + + __mul(a2, lena2, R[3], lenR[3], s, lens); + __mul(T0, lenT0, R[1], lenR[1], t, lent); + + if (sgnR < 0) + __sub(a2, lena2, T0, lenT0, a2, lena2); + else + __sub(a2, lena2, a2, lena2, T0, lenT0); + + flint_mpn_zero(a2 + lena2, m + lena3 - lena2); + __attach_shift(a4, lena4, a2, lena2, m); + __add(a4, lena4, a4, lena4, a3, lena3); + lena2 = FLINT_MAX(m + lena3, lena2); + MPN_NORM(a2, lena2); + + if (lenb2 < m + 1) + { + __set(A, *lenA, a2, lena2); + __set(B, *lenB, b2, lenb2); + + if (flag) + { + __set(M[0], lenM[0], R[0], lenR[0]); + __set(M[1], lenM[1], R[1], lenR[1]); + __set(M[2], lenM[2], R[2], lenR[2]); + __set(M[3], lenM[3], R[3], lenR[3]); + } + + return sgnR; + } + else + { + slong k = 2 * m - lenb2 + 1; + + __divrem(q, lenq, d, lend, a2, lena2, b2, lenb2); + + __attach_shift(c0, lenc0, b2, lenb2, k); + __attach_shift(d0, lend0, d, lend, k); + + if (lenc0 < NMOD_POLY_HGCD_CUTOFF) + sgnS = _nmod_poly_hgcd_recursive_iter(S, lenS, &a3, &lena3, &b3, &lenb3, + c0, lenc0, d0, lend0, + a2, &T0, &T1, mod); /* a2 as temp */ + else + sgnS = _nmod_poly_hgcd_recursive(S, lenS, a3, &lena3, b3, &lenb3, + c0, lenc0, d0, lend0, P, mod, 1); + + __attach_truncate(s, lens, b2, lenb2, k); + __attach_truncate(t, lent, d, lend, k); + + __mul(B, *lenB, S[2], lenS[2], s, lens); + __mul(T0, lenT0, S[0], lenS[0], t, lent); + + if (sgnS < 0) + __sub(B, *lenB, B, *lenB, T0, lenT0); + else + __sub(B, *lenB, T0, lenT0, B, *lenB); + + flint_mpn_zero(B + *lenB, k + lenb3 - *lenB); + __attach_shift(b4, lenb4, B, *lenB, k); + __add(b4, lenb4, b4, lenb4, b3, lenb3); + *lenB = FLINT_MAX(k + lenb3, *lenB); + MPN_NORM(B, *lenB); + + __mul(A, *lenA, S[3], lenS[3], s, lens); + __mul(T0, lenT0, S[1], lenS[1], t, lent); + + if (sgnS < 0) + __sub(A, *lenA, T0, lenT0, A, *lenA); + else + __sub(A, *lenA, A, *lenA, T0, lenT0); + + flint_mpn_zero(A + *lenA, k + lena3 - *lenA); + __attach_shift(a4, lena4, A, *lenA, k); + __add(a4, lena4, a4, lena4, a3, lena3); + *lenA = FLINT_MAX(k + lena3, *lenA); + MPN_NORM(A, *lenA); + + if (flag) + { + __swap(S[0], lenS[0], S[2], lenS[2]); + __swap(S[1], lenS[1], S[3], lenS[3]); + __mul(T0, lenT0, S[2], lenS[2], q, lenq); + __add(S[0], lenS[0], S[0], lenS[0], T0, lenT0); + __mul(T0, lenT0, S[3], lenS[3], q, lenq); + __add(S[1], lenS[1], S[1], lenS[1], T0, lenT0); + + __mat_mul(M, lenM, R, lenR, S, lenS, a2, b2, mod); + } + + return - (sgnR * sgnS); + } + } +} + +/* + XXX: Currently supports aliasing between {A,a} and {B,b}. + */ + +slong _nmod_poly_hgcd(mp_ptr *M, slong *lenM, + mp_ptr A, slong *lenA, mp_ptr B, slong *lenB, + mp_srcptr a, slong lena, mp_srcptr b, slong lenb, + nmod_t mod) +{ + const slong lenW = 22 * lena + 16 * (FLINT_CLOG2(lena) + 1); + slong sgnM; + mp_ptr W; + + W = _nmod_vec_init(lenW); + + if (M == NULL) + { + sgnM = _nmod_poly_hgcd_recursive(NULL, NULL, + A, lenA, B, lenB, + a, lena, b, lenb, W, mod, 0); + } + else + { + sgnM = _nmod_poly_hgcd_recursive(M, lenM, + A, lenA, B, lenB, + a, lena, b, lenb, W, mod, 1); + } + _nmod_vec_clear(W); + + return sgnM; +} + diff --git a/external/flint-2.4.3/nmod_poly/inflate.c b/external/flint-2.4.3/nmod_poly/inflate.c new file mode 100644 index 0000000..50d9d87 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/inflate.c @@ -0,0 +1,58 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "nmod_poly.h" +#include "ulong_extras.h" + +void +nmod_poly_inflate(nmod_poly_t result, const nmod_poly_t input, ulong inflation) +{ + if (input->length <= 1 || inflation == 1) + { + nmod_poly_set(result, input); + } + else if (inflation == 0) + { + mp_limb_t v = nmod_poly_evaluate_nmod(input, 1); + nmod_poly_zero(result); + nmod_poly_set_coeff_ui(result, 0, v); + } + else + { + slong i, j, res_length = (input->length - 1) * inflation + 1; + + nmod_poly_fit_length(result, res_length); + + for (i = input->length - 1; i > 0; i--) + { + result->coeffs[i * inflation] = input->coeffs[i]; + for (j = i * inflation - 1; j > (i - 1) * inflation; j--) + result->coeffs[j] = 0; + } + result->coeffs[0] = input->coeffs[0]; + result->length = res_length; + } +} diff --git a/external/flint-2.4.3/nmod_poly/init.c b/external/flint-2.4.3/nmod_poly/init.c new file mode 100644 index 0000000..df7cd14 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/init.c @@ -0,0 +1,50 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007, David Howden. + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_poly.h" + +void +nmod_poly_init_preinv(nmod_poly_t poly, mp_limb_t n, mp_limb_t ninv) +{ + poly->coeffs = NULL; + + poly->alloc = 0; + poly->length = 0; + + poly->mod.n = n; + poly->mod.ninv = ninv; + count_leading_zeros(poly->mod.norm, n); +} + +void +nmod_poly_init(nmod_poly_t poly, mp_limb_t n) +{ + nmod_poly_init_preinv(poly, n, n_preinvert_limb(n)); +} diff --git a/external/flint-2.4.3/nmod_poly/init2.c b/external/flint-2.4.3/nmod_poly/init2.c new file mode 100644 index 0000000..5c9eb19 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/init2.c @@ -0,0 +1,55 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007, David Howden. + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_poly.h" + +void +nmod_poly_init2_preinv(nmod_poly_t poly, + mp_limb_t n, mp_limb_t ninv, slong alloc) +{ + if (alloc) + poly->coeffs = (mp_ptr) flint_malloc(alloc * sizeof(mp_limb_t)); + else + poly->coeffs = NULL; + + poly->mod.n = n; + poly->mod.ninv = ninv; + + count_leading_zeros(poly->mod.norm, n); + + poly->alloc = alloc; + poly->length = 0; +} + +void +nmod_poly_init2(nmod_poly_t poly, mp_limb_t n, slong alloc) +{ + nmod_poly_init2_preinv(poly, n, n_preinvert_limb(n), alloc); +} diff --git a/external/flint-2.4.3/nmod_poly/integral.c b/external/flint-2.4.3/nmod_poly/integral.c new file mode 100644 index 0000000..6fefc5e --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/integral.c @@ -0,0 +1,94 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +/* Avoid computing every reciprocal */ +#if FLINT64 +#define PROD_TAKE4 UWORD(65535) +#define PROD_TAKE3 UWORD(2642245) +#define PROD_TAKE2 UWORD(4294967295) +#else +#define PROD_TAKE4 UWORD(255) +#define PROD_TAKE3 UWORD(1625) +#define PROD_TAKE2 UWORD(65535) +#endif + +#define MUL3(xx,yy,zz) n_mulmod2_preinv(xx,\ + n_mulmod2_preinv(yy,zz,mod.n,mod.ninv),mod.n,mod.ninv); + +void _nmod_poly_integral(mp_ptr x_int, mp_srcptr x, slong len, nmod_t mod) +{ + mp_limb_t r; + slong k = len - 1; + + while (k > 0) + { + if (k > 3 && k < PROD_TAKE4) + { + r = n_invmod(k*(k-1)*(k-2)*(k-3), mod.n); + x_int[k] = MUL3(x[k-1], r, (k-1)*(k-2)*(k-3)); + x_int[k-1] = MUL3(x[k-2], r, k*(k-2)*(k-3)); + x_int[k-2] = MUL3(x[k-3], r, k*(k-1)*(k-3)); + x_int[k-3] = MUL3(x[k-4], r, k*(k-1)*(k-2)); + k -= 4; + } + else if (k > 2 && k < PROD_TAKE3) + { + r = n_invmod(k*(k-1)*(k-2), mod.n); + x_int[k] = MUL3(x[k-1], r, (k-1)*(k-2)); + x_int[k-1] = MUL3(x[k-2], r, k*(k-2)); + x_int[k-2] = MUL3(x[k-3], r, k*(k-1)); + k -= 3; + } + else if (k > 1 && k < PROD_TAKE2) + { + r = n_invmod(k*(k-1), mod.n); + x_int[k] = MUL3(x[k-1], r, k-1); + x_int[k-1] = MUL3(x[k-2], r, k); + k -= 2; + } + else + { + r = n_invmod(k, mod.n); + x_int[k] = n_mulmod2_preinv(x[k-1], r, mod.n, mod.ninv); + k -= 1; + } + } + + x_int[0] = UWORD(0); +} + +void nmod_poly_integral(nmod_poly_t x_int, const nmod_poly_t x) +{ + nmod_poly_fit_length(x_int, x->length + 1); + _nmod_poly_integral(x_int->coeffs, x->coeffs, x->length + 1, x->mod); + x_int->length = x->length + 1; + _nmod_poly_normalise(x_int); +} diff --git a/external/flint-2.4.3/nmod_poly/interpolate_nmod_vec.c b/external/flint-2.4.3/nmod_poly/interpolate_nmod_vec.c new file mode 100644 index 0000000..7bd8dbe --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/interpolate_nmod_vec.c @@ -0,0 +1,61 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + + +void +_nmod_poly_interpolate_nmod_vec(mp_ptr poly, + mp_srcptr xs, mp_srcptr ys, slong n, nmod_t mod) +{ + if (n < 6) + _nmod_poly_interpolate_nmod_vec_newton(poly, xs, ys, n, mod); + else if (n < 16) + _nmod_poly_interpolate_nmod_vec_barycentric(poly, xs, ys, n, mod); + else + _nmod_poly_interpolate_nmod_vec_fast(poly, xs, ys, n, mod); +} + +void +nmod_poly_interpolate_nmod_vec(nmod_poly_t poly, + mp_srcptr xs, mp_srcptr ys, slong n) +{ + if (n == 0) + { + nmod_poly_zero(poly); + } + else + { + nmod_poly_fit_length(poly, n); + poly->length = n; + _nmod_poly_interpolate_nmod_vec(poly->coeffs, + xs, ys, n, poly->mod); + _nmod_poly_normalise(poly); + } +} diff --git a/external/flint-2.4.3/nmod_poly/interpolate_nmod_vec_barycentric.c b/external/flint-2.4.3/nmod_poly/interpolate_nmod_vec_barycentric.c new file mode 100644 index 0000000..46ccf9d --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/interpolate_nmod_vec_barycentric.c @@ -0,0 +1,93 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + + +void +_nmod_poly_interpolate_nmod_vec_barycentric(mp_ptr poly, + mp_srcptr xs, mp_srcptr ys, slong n, nmod_t mod) +{ + mp_ptr P, Q, w; + slong i, j; + + if (n == 1) + { + poly[0] = ys[0]; + return; + } + + P = _nmod_vec_init(n + 1); + Q = _nmod_vec_init(n); + w = _nmod_vec_init(n); + + _nmod_poly_product_roots_nmod_vec(P, xs, n, mod); + + for (i = 0; i < n; i++) + { + w[i] = UWORD(1); + for (j = 0; j < n; j++) + { + if (i != j) + w[i] = nmod_mul(w[i], nmod_sub(xs[i], xs[j], mod), mod); + } + w[i] = n_invmod(w[i], mod.n); + } + + _nmod_vec_zero(poly, n); + + for (i = 0; i < n; i++) + { + _nmod_poly_div_root(Q, P, n + 1, xs[i], mod); + _nmod_vec_scalar_addmul_nmod(poly, Q, n, + nmod_mul(w[i], ys[i], mod), mod); + } + + _nmod_vec_clear(P); + _nmod_vec_clear(Q); + _nmod_vec_clear(w); +} + +void +nmod_poly_interpolate_nmod_vec_barycentric(nmod_poly_t poly, + mp_srcptr xs, mp_srcptr ys, slong n) +{ + if (n == 0) + { + nmod_poly_zero(poly); + } + else + { + nmod_poly_fit_length(poly, n); + poly->length = n; + _nmod_poly_interpolate_nmod_vec_barycentric(poly->coeffs, + xs, ys, n, poly->mod); + _nmod_poly_normalise(poly); + } +} diff --git a/external/flint-2.4.3/nmod_poly/interpolate_nmod_vec_fast.c b/external/flint-2.4.3/nmod_poly/interpolate_nmod_vec_fast.c new file mode 100644 index 0000000..21c265e --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/interpolate_nmod_vec_fast.c @@ -0,0 +1,145 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +void +_nmod_poly_interpolation_weights(mp_ptr w, const mp_ptr * tree, slong len, nmod_t mod) +{ + mp_ptr tmp; + slong i, n, height; + + if (len == 0) + return; + + if (len == 1) + { + w[0] = 1; + return; + } + + tmp = _nmod_vec_init(len + 1); + height = FLINT_CLOG2(len); + n = WORD(1) << (height - 1); + + _nmod_poly_mul(tmp, tree[height-1], n + 1, + tree[height-1] + (n + 1), (len - n + 1), mod); + + _nmod_poly_derivative(tmp, tmp, len + 1, mod); + _nmod_poly_evaluate_nmod_vec_fast_precomp(w, tmp, len, tree, len, mod); + + for (i = 0; i < len; i++) + w[i] = n_invmod(w[i], mod.n); + + _nmod_vec_clear(tmp); +} + +void +_nmod_poly_interpolate_nmod_vec_fast_precomp(mp_ptr poly, mp_srcptr ys, + const mp_ptr * tree, mp_srcptr weights, slong len, nmod_t mod) +{ + mp_ptr t, u, pa, pb; + slong i, pow, left; + + if (len == 0) + return; + + t = _nmod_vec_init(len); + u = _nmod_vec_init(len); + + for (i = 0; i < len; i++) + poly[i] = nmod_mul(weights[i], ys[i], mod); + + for (i = 0; i < FLINT_CLOG2(len); i++) + { + pow = (WORD(1) << i); + pa = tree[i]; + pb = poly; + left = len; + + while (left >= 2 * pow) + { + _nmod_poly_mul(t, pa, pow + 1, pb + pow, pow, mod); + _nmod_poly_mul(u, pa + pow + 1, pow + 1, pb, pow, mod); + _nmod_vec_add(pb, t, u, 2 * pow, mod); + + left -= 2 * pow; + pa += 2 * pow + 2; + pb += 2 * pow; + } + + if (left > pow) + { + _nmod_poly_mul(t, pa, pow + 1, pb + pow, left - pow, mod); + _nmod_poly_mul(u, pb, pow, pa + pow + 1, left - pow + 1, mod); + _nmod_vec_add(pb, t, u, left, mod); + } + } + + _nmod_vec_clear(t); + _nmod_vec_clear(u); +} + + +void +_nmod_poly_interpolate_nmod_vec_fast(mp_ptr poly, + mp_srcptr xs, mp_srcptr ys, slong len, nmod_t mod) +{ + mp_ptr * tree; + mp_ptr w; + + tree = _nmod_poly_tree_alloc(len); + _nmod_poly_tree_build(tree, xs, len, mod); + + w = _nmod_vec_init(len); + _nmod_poly_interpolation_weights(w, tree, len, mod); + + _nmod_poly_interpolate_nmod_vec_fast_precomp(poly, ys, tree, w, len, mod); + + _nmod_vec_clear(w); + _nmod_poly_tree_free(tree, len); +} + +void +nmod_poly_interpolate_nmod_vec_fast(nmod_poly_t poly, + mp_srcptr xs, mp_srcptr ys, slong n) +{ + if (n == 0) + { + nmod_poly_zero(poly); + } + else + { + nmod_poly_fit_length(poly, n); + poly->length = n; + _nmod_poly_interpolate_nmod_vec_fast(poly->coeffs, + xs, ys, n, poly->mod); + _nmod_poly_normalise(poly); + } +} diff --git a/external/flint-2.4.3/nmod_poly/interpolate_nmod_vec_newton.c b/external/flint-2.4.3/nmod_poly/interpolate_nmod_vec_newton.c new file mode 100644 index 0000000..e8992a9 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/interpolate_nmod_vec_newton.c @@ -0,0 +1,111 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + + +static void +_interpolate_newton(mp_ptr ys, mp_srcptr xs, slong n, nmod_t mod) +{ + mp_limb_t p, q, t; + slong i, j; + + for (i = 1; i < n; i++) + { + t = ys[i - 1]; + + for (j = i; j < n; j++) + { + p = nmod_sub(ys[j], t, mod); + q = nmod_sub(xs[j], xs[j - i], mod); + t = ys[j]; + q = n_invmod(q, mod.n); + ys[j] = n_mulmod2_preinv(p, q, mod.n, mod.ninv); + } + } +} + +static void +_newton_to_monomial(mp_ptr ys, mp_srcptr xs, slong n, nmod_t mod) +{ + mp_limb_t t; + slong i, j; + + for (i = n - 2; i >= 0; i--) + { + t = ys[i]; + ys[i] = ys[i + 1]; + + for (j = i + 1; j < n - 1; j++) + { + ys[j] = nmod_sub(ys[j + 1], + n_mulmod2_preinv(ys[j], xs[i], mod.n, mod.ninv), mod); + } + + ys[n - 1] = nmod_sub(t, + n_mulmod2_preinv(ys[n - 1], xs[i], mod.n, mod.ninv), mod); + } + + _nmod_poly_reverse(ys, ys, n, n); +} + +void +_nmod_poly_interpolate_nmod_vec_newton(mp_ptr poly, mp_srcptr xs, + mp_srcptr ys, slong n, nmod_t mod) +{ + if (n == 1) + { + poly[0] = ys[0]; + } + else + { + _nmod_vec_set(poly, ys, n); + _interpolate_newton(poly, xs, n, mod); + while (n > 0 && !poly[n-1]) n--; + _newton_to_monomial(poly, xs, n, mod); + } +} + +void +nmod_poly_interpolate_nmod_vec_newton(nmod_poly_t poly, + mp_srcptr xs, mp_srcptr ys, slong n) +{ + if (n == 0) + { + nmod_poly_zero(poly); + } + else + { + nmod_poly_fit_length(poly, n); + poly->length = n; + _nmod_poly_interpolate_nmod_vec_newton(poly->coeffs, + xs, ys, n, poly->mod); + _nmod_poly_normalise(poly); + } +} diff --git a/external/flint-2.4.3/nmod_poly/inv_series_basecase.c b/external/flint-2.4.3/nmod_poly/inv_series_basecase.c new file mode 100644 index 0000000..0719b01 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/inv_series_basecase.c @@ -0,0 +1,105 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +void +_nmod_poly_inv_series_basecase(mp_ptr Qinv, + mp_srcptr Q, slong n, nmod_t mod) +{ + mp_ptr X2n, Qrev; + + X2n = _nmod_vec_init(2*n); + Qrev = X2n + n; + + _nmod_poly_reverse(Qrev, Q, n, n); + + X2n[n - 1] = 1; + flint_mpn_zero(X2n, n - 1); + X2n -= (n - 1); + + _nmod_poly_div_divconquer(Qinv, X2n, 2*n - 1, Qrev, n, mod); + + _nmod_poly_reverse(Qinv, Qinv, n, n); + + _nmod_vec_clear(X2n + n - 1); +} + +void +nmod_poly_inv_series_basecase(nmod_poly_t Qinv, + const nmod_poly_t Q, slong n) +{ + mp_ptr Qinv_coeffs, Q_coeffs; + nmod_poly_t t1; + slong Qlen; + + Qlen = Q->length; + + if (n == 0 || Q->length == 0 || Q->coeffs[0] == 0) + { + flint_printf("Exception (nmod_poly_inv_series_basecase). Division by zero.\n"); + abort(); + } + + if (Qlen < n) + { + Q_coeffs = _nmod_vec_init(n); + flint_mpn_copyi(Q_coeffs, Q->coeffs, Qlen); + flint_mpn_zero(Q_coeffs + Qlen, n - Qlen); + } + else + Q_coeffs = Q->coeffs; + + if (Q == Qinv && Qlen >= n) + { + nmod_poly_init2(t1, Q->mod.n, n); + Qinv_coeffs = t1->coeffs; + } + else + { + nmod_poly_fit_length(Qinv, n); + Qinv_coeffs = Qinv->coeffs; + } + + _nmod_poly_inv_series_basecase(Qinv_coeffs, Q_coeffs, n, Q->mod); + + if (Q == Qinv && Qlen >= n) + { + nmod_poly_swap(Qinv, t1); + nmod_poly_clear(t1); + } + + Qinv->length = n; + + if (Qlen < n) + _nmod_vec_clear(Q_coeffs); + + _nmod_poly_normalise(Qinv); +} diff --git a/external/flint-2.4.3/nmod_poly/inv_series_newton.c b/external/flint-2.4.3/nmod_poly/inv_series_newton.c new file mode 100644 index 0000000..3964d80 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/inv_series_newton.c @@ -0,0 +1,130 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +#define NMOD_POLY_INV_NEWTON_CUTOFF 400 + +void +_nmod_poly_inv_series_newton(mp_ptr Qinv, mp_srcptr Q, slong n, nmod_t mod) +{ + if (n < NMOD_POLY_INV_NEWTON_CUTOFF) + { + _nmod_poly_inv_series_basecase(Qinv, Q, n, mod); + } + else + { + slong *a, i, m; + mp_ptr W; + + for (i = 1; (WORD(1) << i) < n; i++) ; + + W = flint_malloc(n * sizeof(mp_limb_t) + i * sizeof(slong)); + a = (slong *) (W + n); + + a[i = 0] = n; + while (n >= NMOD_POLY_INV_NEWTON_CUTOFF) + a[++i] = (n = (n + 1) / 2); + + _nmod_poly_inv_series_basecase(Qinv, Q, n, mod); + + for (i--; i >= 0; i--) + { + m = n; + n = a[i]; + + _nmod_poly_mullow(W, Q, n, Qinv, m, n, mod); + _nmod_poly_mullow(Qinv + m, Qinv, m, W + m, n - m, n - m, mod); + _nmod_vec_neg(Qinv + m, Qinv + m, n - m, mod); + } + + flint_free(W); + } +} + +void +nmod_poly_inv_series_newton(nmod_poly_t Qinv, const nmod_poly_t Q, slong n) +{ + const slong Qlen = Q->length; + + mp_ptr q, qinv; + + if (n == 0 || Q->length == 0 || Q->coeffs[0] == 0) + { + flint_printf("Exception (nmod_poly_inv_series_newton). Division by zero.\n"); + abort(); + } + + if (Qlen < n) + { + q = _nmod_vec_init(n); + + flint_mpn_copyi(q, Q->coeffs, Qlen); + flint_mpn_zero(q + Qlen, n - Qlen); + } + else + { + q = Q->coeffs; + } + + if (Q == Qinv && Qlen >= n) + { + qinv = _nmod_vec_init(n); + } + else + { + nmod_poly_fit_length(Qinv, n); + qinv = Qinv->coeffs; + } + + _nmod_poly_inv_series_newton(qinv, q, n, Q->mod); + + if (Q == Qinv && Qlen >= n) + { + flint_free(Qinv->coeffs); + Qinv->coeffs = qinv; + Qinv->alloc = n; + Qinv->length = n; + } + else + { + Qinv->length = n; + } + + if (Qlen < n) + { + _nmod_vec_clear(q); + } + + _nmod_poly_normalise(Qinv); +} + diff --git a/external/flint-2.4.3/nmod_poly/invmod.c b/external/flint-2.4.3/nmod_poly/invmod.c new file mode 100644 index 0000000..e08d5fd --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/invmod.c @@ -0,0 +1,107 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include +#include "nmod_poly.h" + +int _nmod_poly_invmod(mp_limb_t *A, + const mp_limb_t *B, slong lenB, + const mp_limb_t *P, slong lenP, const nmod_t mod) +{ + mp_limb_t *G; + slong lenG; + + NMOD_VEC_NORM(B, lenB); + + G = _nmod_vec_init(lenB); + + lenG = _nmod_poly_gcdinv(G, A, B, lenB, P, lenP, mod); + + if (lenG == 1 && G[0] != WORD(1)) + { + mp_limb_t invG; + + invG = n_invmod(G[0], mod.n); + _nmod_vec_scalar_mul_nmod(A, A, lenP - 1, invG, mod); + } + + _nmod_vec_clear(G); + + return (lenG == 1); +} + +int nmod_poly_invmod(nmod_poly_t A, + const nmod_poly_t B, const nmod_poly_t P) +{ + const slong lenB = B->length, lenP = P->length; + mp_limb_t *t; + int ans; + + if (lenP < 2) + { + printf("Exception (nmod_poly_invmod). lenP < 2.\n"); + abort(); + } + if (lenB == 0) + { + nmod_poly_zero(A); + return 0; + } + if (lenB >= lenP) + { + nmod_poly_t T; + + nmod_poly_init(T, A->mod.n); + nmod_poly_rem(T, B, P); + ans = nmod_poly_invmod(A, T, P); + nmod_poly_clear(T); + return ans; + } + + if (A != B && A != P) + { + nmod_poly_fit_length(A, lenP - 1); + t = A->coeffs; + } + else + { + t = _nmod_vec_init(lenP); + } + + ans = _nmod_poly_invmod(t, B->coeffs, lenB, P->coeffs, lenP, A->mod); + + if (A == B || A == P) + { + _nmod_vec_clear(A->coeffs); + A->coeffs = t; + A->alloc = lenP - 1; + } + _nmod_poly_set_length(A, lenP - 1); + _nmod_poly_normalise(A); + return ans; +} + diff --git a/external/flint-2.4.3/nmod_poly/invsqrt_series.c b/external/flint-2.4.3/nmod_poly/invsqrt_series.c new file mode 100644 index 0000000..40ec077 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/invsqrt_series.c @@ -0,0 +1,130 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "nmod_poly.h" +#include "ulong_extras.h" + +static void +__nmod_poly_invsqrt_series_prealloc(mp_ptr g, + mp_srcptr h, mp_ptr t, mp_ptr u, + slong n, nmod_t mod) +{ + const int alloc = (t == NULL); + const slong m = (n + 1) / 2; + mp_limb_t c; + + if (n == 1) + { + g[0] = UWORD(1); + return; + } + + if (alloc) + { + t = _nmod_vec_init(n); + u = _nmod_vec_init(n); + } + + __nmod_poly_invsqrt_series_prealloc(g, h, t, u, m, mod); + + _nmod_vec_zero(g + m, n - m); + + _nmod_poly_mul(t, g, m, g, m, mod); + if (2*m - 1 < n) + t[n-1] = UWORD(0); + + _nmod_poly_mullow(u, t, n, g, n, n, mod); + _nmod_poly_mullow(t, u, n, h, n, n, mod); + + c = n_invmod(mod.n - UWORD(2), mod.n); + _nmod_vec_scalar_mul_nmod(g + m, t + m, n - m, c, mod); + + if (alloc) + { + _nmod_vec_clear(t); + _nmod_vec_clear(u); + } +} + +void _nmod_poly_invsqrt_series(mp_ptr g, mp_srcptr h, slong n, nmod_t mod) +{ + __nmod_poly_invsqrt_series_prealloc(g, h, NULL, NULL, n, mod); +} + +void nmod_poly_invsqrt_series(nmod_poly_t g, const nmod_poly_t h, slong n) +{ + const slong hlen = h->length; + mp_ptr g_coeffs, h_coeffs; + nmod_poly_t t1; + + if (n == 0 || h->length == 0 || h->coeffs[0] == 0) + { + flint_printf("Exception (nmod_poly_invsqrt). Division by zero.\n"); + abort(); + } + + if (h->coeffs[0] != UWORD(1)) + { + flint_printf("Exception (nmod_poly_invsqrt_series). Constant term != 1.\n"); + abort(); + } + + if (hlen < n) + { + h_coeffs = _nmod_vec_init(n); + flint_mpn_copyi(h_coeffs, h->coeffs, hlen); + flint_mpn_zero(h_coeffs + hlen, n - hlen); + } + else + h_coeffs = h->coeffs; + + if (h == g && hlen >= n) + { + nmod_poly_init2(t1, h->mod.n, n); + g_coeffs = t1->coeffs; + } + else + { + nmod_poly_fit_length(g, n); + g_coeffs = g->coeffs; + } + + _nmod_poly_invsqrt_series(g_coeffs, h_coeffs, n, h->mod); + + if (h == g && hlen >= n) + { + nmod_poly_swap(g, t1); + nmod_poly_clear(t1); + } + + g->length = n; + + if (hlen < n) + _nmod_vec_clear(h_coeffs); + + _nmod_poly_normalise(g); +} diff --git a/external/flint-2.4.3/nmod_poly/log_series.c b/external/flint-2.4.3/nmod_poly/log_series.c new file mode 100644 index 0000000..d46fee1 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/log_series.c @@ -0,0 +1,98 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +void +_nmod_poly_log_series(mp_ptr res, mp_srcptr f, slong n, nmod_t mod) +{ + mp_ptr f_diff; + mp_ptr f_inv; + + f_diff = _nmod_vec_init(n); + f_inv = _nmod_vec_init(n); + + _nmod_poly_derivative(f_diff, f, n, mod); f_diff[n-1] = UWORD(0); + _nmod_poly_inv_series(f_inv, f, n, mod); + _nmod_poly_mullow(res, f_diff, n - 1, f_inv, n - 1, n - 1, mod); + _nmod_poly_integral(res, res, n, mod); + + _nmod_vec_clear(f_diff); + _nmod_vec_clear(f_inv); +} + +void +nmod_poly_log_series(nmod_poly_t res, const nmod_poly_t f, slong n) +{ + mp_ptr f_coeffs; + slong k; + slong flen = f->length; + + if (flen < 1 || f->coeffs[0] != UWORD(1)) + { + flint_printf("Exception (nmod_poly_log_series). Constant term != 1.\n"); + abort(); + } + + if (flen == 1 || n < 2) + { + nmod_poly_zero(res); + return; + } + + nmod_poly_fit_length(res, n); + + /* Efficiently handle monomials */ + for (k = 1; f->coeffs[k] == UWORD(0) && k < n - 1; k++); + if (k == flen - 1 || k == n - 1) + { + flen = FLINT_MIN(flen, n); + _nmod_poly_log_series_monomial_ui(res->coeffs, + f->coeffs[flen-1], flen - 1, n, res->mod); + } + else + { + if (flen < n) + { + f_coeffs = _nmod_vec_init(n); + flint_mpn_copyi(f_coeffs, f->coeffs, flen); + flint_mpn_zero(f_coeffs + flen, n - flen); + } + else + f_coeffs = f->coeffs; + + _nmod_poly_log_series(res->coeffs, f_coeffs, n, res->mod); + + if (flen < n) + _nmod_vec_clear(f_coeffs); + } + + res->length = n; + _nmod_poly_normalise(res); +} diff --git a/external/flint-2.4.3/nmod_poly/log_series_monomial_ui.c b/external/flint-2.4.3/nmod_poly/log_series_monomial_ui.c new file mode 100644 index 0000000..51a53b2 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/log_series_monomial_ui.c @@ -0,0 +1,109 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +void +_nmod_poly_log_series_monomial_ui(mp_ptr res, mp_limb_t coeff, ulong power, + slong n, nmod_t mod) +{ + slong j, k, rlen; + mp_limb_t a; + + _nmod_vec_zero(res, n); + + if (power >= n) + return; + + rlen = (n - 1) / power; + a = coeff; + coeff = n_negmod(coeff, mod.n); + + /* Construct geometric series */ + if (coeff == UWORD(1)) + { + for (j = 0; j < rlen; j++) + res[j] = a; + } + else if (a == UWORD(1)) + { + for (j = 0; j < rlen; j++) + res[j] = (j % 2) ? coeff : a; + } + else + { + for (j = 0; j < rlen; j++) + { + res[j] = a; + a = n_mulmod2_preinv(a, coeff, mod.n, mod.ninv); + } + } + + /* Integrate */ + _nmod_poly_integral(res, res, rlen + 1, mod); + + /* Expand */ + if (power != 1) + { + for (j = rlen * power + 1; j < n; j++) + res[j] = UWORD(0); + for (j = rlen; j > 0; j--) + { + res[j * power] = res[j]; + for (k = power; k > 0; k--) + res[j * power - k] = UWORD(0); + } + } +} + +void +nmod_poly_log_series_monomial_ui(nmod_poly_t res, mp_limb_t coeff, + ulong power, slong n) +{ + if (power == 0) + { + flint_printf("Exception (nmod_poly_log_series_monomial_ui). \n" + "Constant term != 1.\n"); + abort(); + } + + if (coeff != UWORD(1)) + coeff = n_mod2_preinv(coeff, res->mod.n, res->mod.ninv); + + if (n <= 1 || coeff == UWORD(0)) + { + nmod_poly_zero(res); + return; + } + + nmod_poly_fit_length(res, n); + _nmod_poly_log_series_monomial_ui(res->coeffs, coeff, power, n, res->mod); + res->length = n; + _nmod_poly_normalise(res); +} diff --git a/external/flint-2.4.3/nmod_poly/make_monic.c b/external/flint-2.4.3/nmod_poly/make_monic.c new file mode 100644 index 0000000..7449c1a --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/make_monic.c @@ -0,0 +1,55 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007, David Howden. + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" + +void _nmod_poly_make_monic(mp_ptr output, + mp_srcptr input, slong len, nmod_t mod) +{ + mp_limb_t inv; + + inv = n_invmod(input[len - 1], mod.n); + _nmod_vec_scalar_mul_nmod(output, input, len, inv, mod); +} + +void nmod_poly_make_monic(nmod_poly_t output, const nmod_poly_t input) +{ + if (input->length == 0) + { + flint_printf("Exception (nmod_poly_make_monic). Division by zero.\n"); + abort(); + } + + nmod_poly_fit_length(output, input->length); + _nmod_poly_make_monic(output->coeffs, + input->coeffs, input->length, input->mod); + output->length = input->length; +} + diff --git a/external/flint-2.4.3/nmod_poly/mul.c b/external/flint-2.4.3/nmod_poly/mul.c new file mode 100644 index 0000000..803a57c --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/mul.c @@ -0,0 +1,101 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +void _nmod_poly_mul(mp_ptr res, mp_srcptr poly1, slong len1, + mp_srcptr poly2, slong len2, nmod_t mod) +{ + slong bits, bits2; + + if (len1 + len2 <= 6 || len2 <= 2) + { + _nmod_poly_mul_classical(res, poly1, len1, poly2, len2, mod); + return; + } + + bits = FLINT_BITS - (slong) mod.norm; + bits2 = FLINT_BIT_COUNT(len1); + + if (2 * bits + bits2 <= FLINT_BITS && len1 + len2 < 16) + _nmod_poly_mul_classical(res, poly1, len1, poly2, len2, mod); + else if (bits * len2 > 2000) + _nmod_poly_mul_KS4(res, poly1, len1, poly2, len2, mod); + else if (bits * len2 > 200) + _nmod_poly_mul_KS2(res, poly1, len1, poly2, len2, mod); + else + _nmod_poly_mul_KS(res, poly1, len1, poly2, len2, 0, mod); +} + +void nmod_poly_mul(nmod_poly_t res, const nmod_poly_t poly1, const nmod_poly_t poly2) +{ + slong len1, len2, len_out; + + len1 = poly1->length; + len2 = poly2->length; + + if (len1 == 0 || len2 == 0) + { + nmod_poly_zero(res); + + return; + } + + len_out = poly1->length + poly2->length - 1; + + if (res == poly1 || res == poly2) + { + nmod_poly_t temp; + + nmod_poly_init2(temp, poly1->mod.n, len_out); + + if (len1 >= len2) + _nmod_poly_mul(temp->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2, poly1->mod); + else + _nmod_poly_mul(temp->coeffs, poly2->coeffs, len2, + poly1->coeffs, len1, poly1->mod); + + nmod_poly_swap(temp, res); + nmod_poly_clear(temp); + } else + { + nmod_poly_fit_length(res, len_out); + + if (len1 >= len2) + _nmod_poly_mul(res->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2, poly1->mod); + else + _nmod_poly_mul(res->coeffs, poly2->coeffs, len2, + poly1->coeffs, len1, poly1->mod); + } + + res->length = len_out; + _nmod_poly_normalise(res); +} diff --git a/external/flint-2.4.3/nmod_poly/mul_KS.c b/external/flint-2.4.3/nmod_poly/mul_KS.c new file mode 100644 index 0000000..0bd1865 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/mul_KS.c @@ -0,0 +1,118 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +void +_nmod_poly_mul_KS(mp_ptr out, mp_srcptr in1, slong len1, + mp_srcptr in2, slong len2, mp_bitcnt_t bits, nmod_t mod) +{ + slong len_out = len1 + len2 - 1, limbs1, limbs2; + mp_ptr mpn1, mpn2, res; + + if (bits == 0) + { + mp_bitcnt_t bits1, bits2, loglen; + bits1 = _nmod_vec_max_bits(in1, len1); + bits2 = (in1 == in2) ? bits1 : _nmod_vec_max_bits(in2, len2); + loglen = FLINT_BIT_COUNT(len2); + + bits = bits1 + bits2 + loglen; + } + + limbs1 = (len1 * bits - 1) / FLINT_BITS + 1; + limbs2 = (len2 * bits - 1) / FLINT_BITS + 1; + + mpn1 = (mp_ptr) flint_malloc(sizeof(mp_limb_t) * limbs1); + mpn2 = (in1 == in2) ? mpn1 : (mp_ptr) flint_malloc(sizeof(mp_limb_t) * limbs2); + + _nmod_poly_bit_pack(mpn1, in1, len1, bits); + if (in1 != in2) + _nmod_poly_bit_pack(mpn2, in2, len2, bits); + + res = (mp_ptr) flint_malloc(sizeof(mp_limb_t) * (limbs1 + limbs2)); + + mpn_mul(res, mpn1, limbs1, mpn2, limbs2); + + _nmod_poly_bit_unpack(out, len_out, res, bits, mod); + + flint_free(mpn2); + if (in1 != in2) + flint_free(mpn1); + + flint_free(res); +} + +void +nmod_poly_mul_KS(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_poly_t poly2, + mp_bitcnt_t bits) +{ + slong len_out; + + if ((poly1->length == 0) || (poly2->length == 0)) + { + nmod_poly_zero(res); + return; + } + + len_out = poly1->length + poly2->length - 1; + + if (res == poly1 || res == poly2) + { + nmod_poly_t temp; + nmod_poly_init2_preinv(temp, poly1->mod.n, poly1->mod.ninv, len_out); + if (poly1->length >= poly2->length) + _nmod_poly_mul_KS(temp->coeffs, poly1->coeffs, poly1->length, + poly2->coeffs, poly2->length, bits, + poly1->mod); + else + _nmod_poly_mul_KS(temp->coeffs, poly2->coeffs, poly2->length, + poly1->coeffs, poly1->length, bits, + poly1->mod); + nmod_poly_swap(res, temp); + nmod_poly_clear(temp); + } + else + { + nmod_poly_fit_length(res, len_out); + if (poly1->length >= poly2->length) + _nmod_poly_mul_KS(res->coeffs, poly1->coeffs, poly1->length, + poly2->coeffs, poly2->length, bits, + poly1->mod); + else + _nmod_poly_mul_KS(res->coeffs, poly2->coeffs, poly2->length, + poly1->coeffs, poly1->length, bits, + poly1->mod); + } + + res->length = len_out; + _nmod_poly_normalise(res); +} diff --git a/external/flint-2.4.3/nmod_poly/mul_KS2.c b/external/flint-2.4.3/nmod_poly/mul_KS2.c new file mode 100644 index 0000000..eb95de5 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/mul_KS2.c @@ -0,0 +1,255 @@ +/*============================================================================= + +Copyright (C) 2007, 2008 David Harvey (zn_poly) +Copyright (C) 2013 William Hart + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +/* + Multiplication/squaring using Kronecker substitution at 2^b and -2^b. +*/ +void +_nmod_poly_mul_KS2(mp_ptr res, mp_srcptr op1, slong n1, + mp_srcptr op2, slong n2, nmod_t mod) +{ + int sqr, v3m_neg; + ulong bits, b, w; + slong n1o, n1e, n2o, n2e, n3o, n3e, n3, k1, k2, k3; + mp_ptr v1_buf0, v2_buf0, v1_buf1, v2_buf1, v1_buf2, v2_buf2; + mp_ptr v1o, v1e, v1p, v1m, v2o, v2e, v2p, v2m, v3o, v3e, v3p, v3m; + mp_ptr z; + + if (n2 == 1) + { + /* code below needs n2 > 1, so fall back on scalar multiplication */ + _nmod_vec_scalar_mul_nmod(res, op1, n1, op2[0], mod); + return; + } + + sqr = (op1 == op2 && n1 == n2); + + /* bits in each output coefficient */ + bits = 2 * (FLINT_BITS - mod.norm) + FLINT_CLOG2(n2); + + /* we're evaluating at x = B and -B, where B = 2^b, and b = ceil(bits / 2) */ + b = (bits + 1) / 2; + + /* number of ulongs required to store each output coefficient */ + w = (2*b - 1)/FLINT_BITS + 1; + + /* + Write f1(x) = f1e(x^2) + x * f1o(x^2) + f2(x) = f2e(x^2) + x * f2o(x^2) + h(x) = he(x^2) + x * ho(x^2) + "e" = even, "o" = odd + */ + + n1o = n1 / 2; + n1e = n1 - n1o; + + n2o = n2 / 2; + n2e = n2 - n2o; + + n3 = n1 + n2 - 1; /* length of h */ + n3o = n3 / 2; + n3e = n3 - n3o; + + /* + f1(B) and |f1(-B)| are at most ((n1 - 1) * b + mod->bits) bits long. + However, when evaluating f1e(B^2) and B * f1o(B^2) the bitpacking + routine needs room for the last chunk of 2b bits. Therefore we need to + allow room for (n1 + 1) * b bits. Ditto for f2. + */ + k1 = ((n1 + 1)*b - 1)/FLINT_BITS + 1; + k2 = ((n2 + 1)*b - 1)/FLINT_BITS + 1; + k3 = k1 + k2; + + /* allocate space */ + v1_buf0 = _nmod_vec_init(3*k3); /* k1 limbs */ + v2_buf0 = v1_buf0 + k1; /* k2 limbs */ + v1_buf1 = v2_buf0 + k2; /* k1 limbs */ + v2_buf1 = v1_buf1 + k1; /* k2 limbs */ + v1_buf2 = v2_buf1 + k2; /* k1 limbs */ + v2_buf2 = v1_buf2 + k1; /* k2 limbs */ + + /* + arrange overlapping buffers to minimise memory use + "p" = plus, "m" = minus + */ + v1e = v1_buf0; + v2e = v2_buf0; + v1o = v1_buf1; + v2o = v2_buf1; + v1p = v1_buf2; + v2p = v2_buf2; + v1m = v1_buf0; + v2m = v2_buf0; + v3m = v1_buf1; + v3p = v1_buf0; + v3e = v1_buf2; + v3o = v1_buf0; + + z = _nmod_vec_init(w*n3e); + + if (!sqr) + { + /* multiplication version */ + + /* evaluate f1e(B^2) and B * f1o(B^2) */ + _nmod_poly_KS2_pack(v1e, op1, n1e, 2, 2 * b, 0, k1); + _nmod_poly_KS2_pack(v1o, op1 + 1, n1o, 2, 2 * b, b, k1); + + /* evaluate f2e(B^2) and B * f2o(B^2) */ + _nmod_poly_KS2_pack(v2e, op2, n2e, 2, 2 * b, 0, k2); + _nmod_poly_KS2_pack(v2o, op2 + 1, n2o, 2, 2 * b, b, k2); + + /* + compute f1(B) = f1e(B^2) + B * f1o(B^2) + and f2(B) = f2e(B^2) + B * f2o(B^2) + */ + mpn_add_n(v1p, v1e, v1o, k1); + mpn_add_n(v2p, v2e, v2o, k2); + + /* + compute |f1(-B)| = |f1e(B^2) - B * f1o(B^2)| + and |f2(-B)| = |f2e(B^2) - B * f2o(B^2)| + */ + v3m_neg = signed_mpn_sub_n(v1m, v1e, v1o, k1); + v3m_neg ^= signed_mpn_sub_n(v2m, v2e, v2o, k2); + + /* + compute h(B) = f1(B) * f2(B) + compute |h(-B)| = |f1(-B)| * |f2(-B)| + v3m_neg is set if h(-B) is negative + */ + mpn_mul(v3m, v1m, k1, v2m, k2); + mpn_mul(v3p, v1p, k1, v2p, k2); + } + else + { + /* squaring version */ + + /* evaluate f1e(B^2) and B * f1o(B^2) */ + _nmod_poly_KS2_pack(v1e, op1, n1e, 2, 2 * b, 0, k1); + _nmod_poly_KS2_pack(v1o, op1 + 1, n1o, 2, 2 * b, b, k1); + + /* compute f1(B) = f1e(B^2) + B * f1o(B^2) */ + mpn_add_n(v1p, v1e, v1o, k1); + + /* compute |f1(-B)| = |f1e(B^2) - B * f1o(B^2)| */ + signed_mpn_sub_n(v1m, v1e, v1o, k1); + + /* + compute h(B) = f1(B)^2 + compute h(-B) = f1(-B)^2 + v3m_neg is cleared (since f1(-B)^2 is never negative) + */ + mpn_mul(v3m, v1m, k1, v1m, k1); + mpn_mul(v3p, v1p, k1, v1p, k1); + v3m_neg = 0; + } + + /* + he(B^2) and B * ho(B^2) are both at most b * (n3 + 1) bits long (since + the coefficients don't overlap). The buffers used below are at least + b * (n1 + n2 + 2) = b * (n3 + 3) bits long. So we definitely have + enough room for 2 * he(B^2) and 2 * B * ho(B^2). + */ + + /* compute 2 * he(B^2) = h(B) + h(-B) */ + if (v3m_neg) + mpn_sub_n(v3e, v3p, v3m, k3); + else + mpn_add_n(v3e, v3p, v3m, k3); + + /* unpack coefficients of he, and reduce mod m */ + _nmod_poly_KS2_unpack(z, v3e, n3e, 2 * b, 1); + _nmod_poly_KS2_reduce(res, 2, z, n3e, w, mod); + + /* compute 2 * b * ho(B^2) = h(B) - h(-B) */ + if (v3m_neg) + mpn_add_n(v3o, v3p, v3m, k3); + else + mpn_sub_n(v3o, v3p, v3m, k3); + + /* unpack coefficients of ho, and reduce mod m */ + _nmod_poly_KS2_unpack(z, v3o, n3o, 2 * b, b + 1); + _nmod_poly_KS2_reduce(res + 1, 2, z, n3o, w, mod); + + _nmod_vec_clear(z); + _nmod_vec_clear(v1_buf0); +} + +void +nmod_poly_mul_KS2(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_poly_t poly2) +{ + slong len_out; + + if ((poly1->length == 0) || (poly2->length == 0)) + { + nmod_poly_zero(res); + return; + } + + len_out = poly1->length + poly2->length - 1; + + if (res == poly1 || res == poly2) + { + nmod_poly_t temp; + nmod_poly_init2_preinv(temp, poly1->mod.n, poly1->mod.ninv, len_out); + if (poly1->length >= poly2->length) + _nmod_poly_mul_KS2(temp->coeffs, poly1->coeffs, poly1->length, + poly2->coeffs, poly2->length, + poly1->mod); + else + _nmod_poly_mul_KS2(temp->coeffs, poly2->coeffs, poly2->length, + poly1->coeffs, poly1->length, + poly1->mod); + nmod_poly_swap(res, temp); + nmod_poly_clear(temp); + } + else + { + nmod_poly_fit_length(res, len_out); + if (poly1->length >= poly2->length) + _nmod_poly_mul_KS2(res->coeffs, poly1->coeffs, poly1->length, + poly2->coeffs, poly2->length, + poly1->mod); + else + _nmod_poly_mul_KS2(res->coeffs, poly2->coeffs, poly2->length, + poly1->coeffs, poly1->length, + poly1->mod); + } + + res->length = len_out; + _nmod_poly_normalise(res); +} diff --git a/external/flint-2.4.3/nmod_poly/mul_KS4.c b/external/flint-2.4.3/nmod_poly/mul_KS4.c new file mode 100644 index 0000000..9ce725c --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/mul_KS4.c @@ -0,0 +1,400 @@ +/*============================================================================= + +Copyright (C) 2007, 2008 David Harvey (zn_poly) +Copyright (C) 2013 William Hart + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +/* + Multiplication/squaring using Kronecker substitution at 2^b, -2^b, + 2^(-b) and -2^(-b). +*/ +void +_nmod_poly_mul_KS4(mp_ptr res, mp_srcptr op1, slong n1, + mp_srcptr op2, slong n2, nmod_t mod) +{ + int sqr, v3m_neg; + ulong bits, b, w, a1, a2, a3; + slong n1o, n1e, n2o, n2e, n3o, n3e, n3, k1, k2, k3; + mp_ptr v1_buf0, v2_buf0, v1_buf1, v2_buf1, v1_buf2, v2_buf2, v1_buf3, v2_buf3, v1_buf4, v2_buf4; + mp_ptr v1on, v1en, v1pn, v1mn, v2on, v2en, v2pn, v2mn, v3on, v3en, v3pn, v3mn; + mp_ptr v1or, v1er, v1pr, v1mr, v2or, v2er, v2pr, v2mr, v3or, v3er, v3pr, v3mr; + mp_ptr z, zn, zr; + + if (n2 == 1) + { + /* code below needs n2 > 1, so fall back on scalar multiplication */ + _nmod_vec_scalar_mul_nmod(res, op1, n1, op2[0], mod); + return; + } + + sqr = (op1 == op2 && n1 == n2); + + /* bits in each output coefficient */ + bits = 2 * (FLINT_BITS - mod.norm) + FLINT_CLOG2(n2); + + /* + we're evaluating at x = B, -B, 1/B, -1/B, + where B = 2^b, and b = ceil(bits / 4) + */ + b = (bits + 3) / 4; + + /* number of ulongs required to store each base-B^2 digit */ + w = (2*b - 1)/FLINT_BITS + 1; + + /* + Write f1(x) = f1e(x^2) + x * f1o(x^2) + f2(x) = f2e(x^2) + x * f2o(x^2) + h(x) = he(x^2) + x * ho(x^2) + "e" = even, "o" = odd + */ + + n1o = n1 / 2; + n1e = n1 - n1o; + + n2o = n2 / 2; + n2e = n2 - n2o; + + n3 = n1 + n2 - 1; /* length of h */ + n3o = n3 / 2; + n3e = n3 - n3o; + + /* + Put k1 = number of limbs needed to store f1(B) and |f1(-B)|. + In f1(B), the leading coefficient starts at bit position b * (n1 - 1) + and has length 2b, and the coefficients overlap so we need an extra bit + for the carry: this gives (n1 + 1) * b + 1 bits. Ditto for f2. + */ + k1 = ((n1 + 1) * b)/FLINT_BITS + 1; + k2 = ((n2 + 1) * b)/FLINT_BITS + 1; + k3 = k1 + k2; + + /* allocate space */ + v1_buf0 = _nmod_vec_init(5*k3); /* k1 limbs */ + v2_buf0 = v1_buf0 + k1; /* k2 limbs */ + v1_buf1 = v2_buf0 + k2; /* k1 limbs */ + v2_buf1 = v1_buf1 + k1; /* k2 limbs */ + v1_buf2 = v2_buf1 + k2; /* k1 limbs */ + v2_buf2 = v1_buf2 + k1; /* k2 limbs */ + v1_buf3 = v2_buf2 + k2; /* k1 limbs */ + v2_buf3 = v1_buf3 + k1; /* k2 limbs */ + v1_buf4 = v2_buf3 + k2; /* k1 limbs */ + v2_buf4 = v1_buf4 + k1; /* k2 limbs */ + + /* + arrange overlapping buffers to minimise memory use + "p" = plus, "m" = minus + "n" = normal order, "r" = reciprocal order + */ + v1en = v1_buf0; + v1on = v1_buf1; + v1pn = v1_buf2; + v1mn = v1_buf0; + v2en = v2_buf0; + v2on = v2_buf1; + v2pn = v2_buf2; + v2mn = v2_buf0; + v3pn = v1_buf1; + v3mn = v1_buf2; + v3en = v1_buf0; + v3on = v1_buf1; + + v1er = v1_buf2; + v1or = v1_buf3; + v1pr = v1_buf4; + v1mr = v1_buf2; + v2er = v2_buf2; + v2or = v2_buf3; + v2pr = v2_buf4; + v2mr = v2_buf2; + v3pr = v1_buf3; + v3mr = v1_buf4; + v3er = v1_buf2; + v3or = v1_buf3; + + z = _nmod_vec_init(2*w*(n3e + 1)); + zn = z; + zr = z + w*(n3e + 1); + + /* ------------------------------------------------------------------------- + "normal" evaluation points + */ + + if (!sqr) + { + /* multiplication version */ + + /* + evaluate f1e(B^2) and B * f1o(B^2) + We need max(2 * b*n1e, 2 * b*n1o + b) bits for this packing step, + which is safe since (n1 + 1) * b + 1 >= max(2 * b*n1e, 2 * b*n1o + b). + Ditto for f2 below. + */ + _nmod_poly_KS2_pack(v1en, op1, n1e, 2, 2 * b, 0, k1); + _nmod_poly_KS2_pack(v1on, op1 + 1, n1o, 2, 2 * b, b, k1); + + /* + compute f1(B) = f1e(B^2) + B * f1o(B^2) + and |f1(-B)| = |f1e(B^2) - B * f1o(B^2)| + */ + mpn_add_n (v1pn, v1en, v1on, k1); + v3m_neg = signed_mpn_sub_n(v1mn, v1en, v1on, k1); + + /* evaluate f2e(B^2) and B * f2o(B^2) */ + _nmod_poly_KS2_pack(v2en, op2, n2e, 2, 2 * b, 0, k2); + _nmod_poly_KS2_pack(v2on, op2 + 1, n2o, 2, 2 * b, b, k2); + + /* + compute f2(B) = f2e(B^2) + B * f2o(B^2) + and |f2(-B)| = |f2e(B^2) - B * f2o(B^2)| + */ + mpn_add_n(v2pn, v2en, v2on, k2); + v3m_neg ^= signed_mpn_sub_n(v2mn, v2en, v2on, k2); + + /* + compute h(B) = f1(B) * f2(B) + and |h(-B)| = |f1(-B)| * |f2(-B)| + hn_neg is set if h(-B) is negative + */ + mpn_mul(v3pn, v1pn, k1, v2pn, k2); + mpn_mul(v3mn, v1mn, k1, v2mn, k2); + } + else + { + /* squaring version */ + + /* evaluate f1e(B^2) and B * f1o(B^2) */ + _nmod_poly_KS2_pack(v1en, op1, n1e, 2, 2 * b, 0, k1); + _nmod_poly_KS2_pack(v1on, op1 + 1, n1o, 2, 2 * b, b, k1); + + /* + compute f1(B) = f1e(B^2) + B * f1o(B^2) + and |f1(-B)| = |f1e(B^2) - B * f1o(B^2)| + */ + mpn_add_n (v1pn, v1en, v1on, k1); + signed_mpn_sub_n(v1mn, v1en, v1on, k1); + + /* + compute h(B) = f1(B)^2 + and h(-B) = |f1(-B)|^2 + hn_neg is cleared since h(-B) is never negative + */ + mpn_mul(v3pn, v1pn, k1, v1pn, k1); + mpn_mul(v3mn, v1mn, k1, v1mn, k1); + v3m_neg = 0; + } + + /* + Each coefficient of h(B) is up to 4b bits long, so h(B) needs at most + ((n1 + n2 + 2) * b + 1) bits. (The extra +1 is to accommodate carries + generated by overlapping coefficients.) The buffer has at least + ((n1 + n2 + 2) * b + 2) bits. Therefore we can safely store 2*h(B) etc. + */ + + /* + compute 2 * he(B^2) = h(B) + h(-B) + and B * 2 * ho(B^2) = h(B) - h(-B) + */ + if (v3m_neg) + { + mpn_sub_n(v3en, v3pn, v3mn, k3); + mpn_add_n (v3on, v3pn, v3mn, k3); + } + else + { + mpn_add_n (v3en, v3pn, v3mn, k3); + mpn_sub_n (v3on, v3pn, v3mn, k3); + } + + /* ------------------------------------------------------------------------- + "reciprocal" evaluation points + */ + + /* + correction factors to take into account that if a polynomial has even + length, its even and odd coefficients are swapped when the polynomial + is reversed + */ + a1 = (n1 & 1) ? 0 : b; + a2 = (n2 & 1) ? 0 : b; + a3 = (n3 & 1) ? 0 : b; + + if (!sqr) + { + /* multiplication version */ + + /* evaluate B^(n1-1) * f1e(1/B^2) and B^(n1-2) * f1o(1/B^2) */ + _nmod_poly_KS2_pack(v1er, op1 + 2*(n1e - 1), n1e, -2, 2 * b, a1, k1); + _nmod_poly_KS2_pack(v1or, op1 + 1 + 2*(n1o - 1), n1o, -2, 2 * b, b - a1, k1); + + /* + compute B^(n1-1) * f1(1/B) = + B^(n1-1) * f1e(1/B^2) + B^(n1-2) * f1o(1/B^2) + and |B^(n1-1) * f1(-1/B)| = + |B^(n1-1) * f1e(1/B^2) - B^(n1-2) * f1o(1/B^2)| + */ + mpn_add_n(v1pr, v1er, v1or, k1); + v3m_neg = signed_mpn_sub_n(v1mr, v1er, v1or, k1); + + /* evaluate B^(n2-1) * f2e(1/B^2) and B^(n2-2) * f2o(1/B^2) */ + _nmod_poly_KS2_pack(v2er, op2 + 2*(n2e - 1), n2e, -2, 2 * b, a2, k2); + _nmod_poly_KS2_pack(v2or, op2 + 1 + 2*(n2o - 1), n2o, -2, 2 * b, b - a2, k2); + + /* + compute B^(n2-1) * f2(1/B) = + B^(n2-1) * f2e(1/B^2) + B^(n2-2) * f2o(1/B^2) + and |B^(n1-1) * f2(-1/B)| = + |B^(n2-1) * f2e(1/B^2) - B^(n2-2) * f2o(1/B^2)| + */ + mpn_add_n (v2pr, v2er, v2or, k2); + v3m_neg ^= signed_mpn_sub_n(v2mr, v2er, v2or, k2); + + /* + compute B^(n3-1) * h(1/B) = + (B^(n1-1) * f1(1/B)) * (B^(n2-1) * f2(1/B)) + and |B^(n3-1) * h(-1/B)| = + |B^(n1-1) * f1(-1/B)| * |B^(n2-1) * f2(-1/B)| + hr_neg is set if h(-1/B) is negative + */ + mpn_mul(v3pr, v1pr, k1, v2pr, k2); + mpn_mul(v3mr, v1mr, k1, v2mr, k2); + } + else + { + /* squaring version */ + + /* evaluate B^(n1-1) * f1e(1/B^2) and B^(n1-2) * f1o(1/B^2) */ + _nmod_poly_KS2_pack(v1er, op1 + 2*(n1e - 1), n1e, -2, 2 * b, a1, k1); + _nmod_poly_KS2_pack(v1or, op1 + 1 + 2*(n1o - 1), n1o, -2, 2 * b, b - a1, k1); + + /* + compute B^(n1-1) * f1(1/B) = + B^(n1-1) * f1e(1/B^2) + B^(n1-2) * f1o(1/B^2) + and |B^(n1-1) * f1(-1/B)| = + |B^(n1-1) * f1e(1/B^2) - B^(n1-2) * f1o(1/B^2)| + */ + mpn_add_n(v1pr, v1er, v1or, k1); + signed_mpn_sub_n(v1mr, v1er, v1or, k1); + + /* + compute B^(n3-1) * h(1/B) = (B^(n1-1) * f1(1/B))^2 + and B^(n3-1) * h(-1/B) = |B^(n1-1) * f1(-1/B)|^2 + hr_neg is cleared since h(-1/B) is never negative + */ + mpn_mul(v3pr, v1pr, k1, v1pr, k1); + mpn_mul(v3mr, v1mr, k1, v1mr, k1); + v3m_neg = 0; + } + + /* + compute 2 * B^(n3-1) * he(1/B^2) + = B^(n3-1) * h(1/B) + B^(n3-1) * h(-1/B) + and 2 * B^(n3-2) * ho(1/B^2) + = B^(n3-1) * h(1/B) - B^(n3-1) * h(-1/B) + */ + if (v3m_neg) + { + mpn_sub_n(v3er, v3pr, v3mr, k3); + mpn_add_n(v3or, v3pr, v3mr, k3); + } + else + { + mpn_add_n (v3er, v3pr, v3mr, k3); + mpn_sub_n (v3or, v3pr, v3mr, k3); + } + + /* ------------------------------------------------------------------------- + combine "normal" and "reciprocal" information + */ + + /* decompose he(B^2) and B^(2*(n3e-1)) * he(1/B^2) into base-B^2 digits */ + _nmod_poly_KS2_unpack(zn, v3en, n3e + 1, 2 * b, 1); + _nmod_poly_KS2_unpack(zr, v3er, n3e + 1, 2 * b, a3 + 1); + + /* combine he(B^2) and he(1/B^2) information to get even coefficients of h */ + _nmod_poly_KS2_recover_reduce(res, 2, zn, zr, n3e, 2 * b, mod); + + /* decompose ho(B^2) and B^(2*(n3o-1)) * ho(1/B^2) into base-B^2 digits */ + _nmod_poly_KS2_unpack(zn, v3on, n3o + 1, 2 * b, b + 1); + _nmod_poly_KS2_unpack(zr, v3or, n3o + 1, 2 * b, b - a3 + 1); + + /* combine ho(B^2) and ho(1/B^2) information to get odd coefficients of h */ + _nmod_poly_KS2_recover_reduce(res + 1, 2, zn, zr, n3o, 2 * b, mod); + + _nmod_vec_clear(z); + _nmod_vec_clear(v1_buf0); +} + +void +nmod_poly_mul_KS4(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_poly_t poly2) +{ + slong len_out; + + if ((poly1->length == 0) || (poly2->length == 0)) + { + nmod_poly_zero(res); + return; + } + + len_out = poly1->length + poly2->length - 1; + + if (res == poly1 || res == poly2) + { + nmod_poly_t temp; + nmod_poly_init2_preinv(temp, poly1->mod.n, poly1->mod.ninv, len_out); + if (poly1->length >= poly2->length) + _nmod_poly_mul_KS4(temp->coeffs, poly1->coeffs, poly1->length, + poly2->coeffs, poly2->length, + poly1->mod); + else + _nmod_poly_mul_KS4(temp->coeffs, poly2->coeffs, poly2->length, + poly1->coeffs, poly1->length, + poly1->mod); + nmod_poly_swap(res, temp); + nmod_poly_clear(temp); + } + else + { + nmod_poly_fit_length(res, len_out); + if (poly1->length >= poly2->length) + _nmod_poly_mul_KS4(res->coeffs, poly1->coeffs, poly1->length, + poly2->coeffs, poly2->length, + poly1->mod); + else + _nmod_poly_mul_KS4(res->coeffs, poly2->coeffs, poly2->length, + poly1->coeffs, poly1->length, + poly1->mod); + } + + res->length = len_out; + _nmod_poly_normalise(res); +} diff --git a/external/flint-2.4.3/nmod_poly/mul_classical.c b/external/flint-2.4.3/nmod_poly/mul_classical.c new file mode 100644 index 0000000..8c9823b --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/mul_classical.c @@ -0,0 +1,119 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +/* Assumes poly1 and poly2 are not length 0. */ +void +_nmod_poly_mul_classical(mp_ptr res, mp_srcptr poly1, + slong len1, mp_srcptr poly2, slong len2, nmod_t mod) +{ + slong i; + slong log_len = FLINT_BIT_COUNT(len2); + slong bits = FLINT_BITS - (slong) mod.norm; + + if (2 * bits + log_len <= FLINT_BITS) + { + /* Set res[i] = poly1[i]*poly2[0] */ + mpn_mul_1(res, poly1, len1, poly2[0]); + + if (len2 != 1) + { + /* Set res[i+len1-1] = in1[len1-1]*in2[i] */ + mpn_mul_1(res + len1, poly2 + 1, len2 - 1, poly1[len1 - 1]); + + /* out[i+j] += in1[i]*in2[j] */ + for (i = 0; i < len1 - 1; i++) + mpn_addmul_1(res + i + 1, poly2 + 1, len2 - 1, poly1[i]); + } + + /* final reduction */ + _nmod_vec_reduce(res, res, len1 + len2 - 1, mod); + } + else + { + /* Set res[i] = poly1[i]*poly2[0] */ + _nmod_vec_scalar_mul_nmod(res, poly1, len1, poly2[0], mod); + if (len2 == 1) + return; + + /* Set res[i+len1-1] = in1[len1-1]*in2[i] */ + _nmod_vec_scalar_mul_nmod(res + len1, poly2 + 1, len2 - 1, + poly1[len1 - 1], mod); + + /* out[i+j] += in1[i]*in2[j] */ + for (i = 0; i < len1 - 1; i++) + _nmod_vec_scalar_addmul_nmod(res + i + 1, poly2 + 1, len2 - 1, + poly1[i], mod); + } +} + +void +nmod_poly_mul_classical(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_poly_t poly2) +{ + slong len_out; + + if ((poly1->length == 0) || (poly2->length == 0)) + { + nmod_poly_zero(res); + return; + } + + len_out = poly1->length + poly2->length - 1; + + if (res == poly1 || res == poly2) + { + nmod_poly_t temp; + nmod_poly_init2_preinv(temp, poly1->mod.n, poly1->mod.ninv, len_out); + if (poly1->length >= poly2->length) + _nmod_poly_mul_classical(temp->coeffs, poly1->coeffs, + poly1->length, poly2->coeffs, + poly2->length, poly1->mod); + else + _nmod_poly_mul_classical(temp->coeffs, poly2->coeffs, + poly2->length, poly1->coeffs, + poly1->length, poly1->mod); + nmod_poly_swap(res, temp); + nmod_poly_clear(temp); + } + else + { + nmod_poly_fit_length(res, len_out); + if (poly1->length >= poly2->length) + _nmod_poly_mul_classical(res->coeffs, poly1->coeffs, poly1->length, + poly2->coeffs, poly2->length, poly1->mod); + else + _nmod_poly_mul_classical(res->coeffs, poly2->coeffs, poly2->length, + poly1->coeffs, poly1->length, poly1->mod); + } + + res->length = len_out; + _nmod_poly_normalise(res); +} diff --git a/external/flint-2.4.3/nmod_poly/mulhigh.c b/external/flint-2.4.3/nmod_poly/mulhigh.c new file mode 100644 index 0000000..04bb5ba --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/mulhigh.c @@ -0,0 +1,96 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +void _nmod_poly_mulhigh(mp_ptr res, mp_srcptr poly1, slong len1, + mp_srcptr poly2, slong len2, slong n, nmod_t mod) +{ + slong bits, bits2; + + if (len1 + len2 <= 6) + { + _nmod_poly_mulhigh_classical(res, poly1, len1, poly2, len2, n, mod); + return; + } + + bits = FLINT_BITS - (slong) mod.norm; + bits2 = FLINT_BIT_COUNT(len1); + + if (2 * bits + bits2 <= FLINT_BITS && len1 + len2 < 16) + _nmod_poly_mulhigh_classical(res, poly1, len1, poly2, len2, n, mod); + else + _nmod_poly_mul_KS(res, poly1, len1, poly2, len2, 0, mod); +} + +void nmod_poly_mulhigh(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_poly_t poly2, slong start) +{ + slong len1, len2, len_out; + + len1 = poly1->length; + len2 = poly2->length; + len_out = len1 + len2 - 1; + + if (len1 == 0 || len2 == 0 || start >= len_out) + { + nmod_poly_zero(res); + return; + } + + if (res == poly1 || res == poly2) + { + nmod_poly_t temp; + + nmod_poly_init2(temp, poly1->mod.n, len_out); + + if (len1 >= len2) + _nmod_poly_mulhigh(temp->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2, start, poly1->mod); + else + _nmod_poly_mulhigh(temp->coeffs, poly2->coeffs, len2, + poly1->coeffs, len1, start, poly1->mod); + + nmod_poly_swap(temp, res); + nmod_poly_clear(temp); + } else + { + nmod_poly_fit_length(res, len_out); + + if (len1 >= len2) + _nmod_poly_mulhigh(res->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2, start, poly1->mod); + else + _nmod_poly_mulhigh(res->coeffs, poly2->coeffs, len2, + poly1->coeffs, len1, start, poly1->mod); + } + + res->length = len_out; + _nmod_poly_normalise(res); +} diff --git a/external/flint-2.4.3/nmod_poly/mulhigh_classical.c b/external/flint-2.4.3/nmod_poly/mulhigh_classical.c new file mode 100644 index 0000000..fc5c0bd --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/mulhigh_classical.c @@ -0,0 +1,150 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +/* Assumes poly1 and poly2 are not length 0. */ +void +_nmod_poly_mulhigh_classical(mp_ptr res, mp_srcptr poly1, + slong len1, mp_srcptr poly2, slong len2, slong start, + nmod_t mod) +{ + slong m, n; + + _nmod_vec_zero(res, start); + + if (len1 == 1) /* Special case if the length of both inputs is 1 */ + { + if (start == 0) + res[0] = n_mulmod2_preinv(poly1[0], poly2[0], mod.n, mod.ninv); + } + else /* Ordinary case */ + { + slong i; + slong bits = FLINT_BITS - (slong) mod.norm; + slong log_len = FLINT_BIT_COUNT(len2); + + if (2 * bits + log_len <= FLINT_BITS) + { + /* Set res[i] = poly1[i]*poly2[0] */ + if (start < len1) + mpn_mul_1(res + start, poly1 + start, len1 - start, poly2[0]); + + if (len2 != 1) + { + /* Set res[i+len1-1] = in1[len1-1]*in2[i] */ + m = FLINT_MAX(len1 - 1, start); + + mpn_mul_1(res + m, poly2 + m - len1 + 1, len2 - 1 + len1 - m, + poly1[len1 - 1]); + + /* out[i+j] += in1[i]*in2[j] */ + m = FLINT_MAX(start, len2 - 1); + for (i = m - len2 + 1; i < len1 - 1; i++) + { + n = FLINT_MAX(i + 1, start); + mpn_addmul_1(res + n, poly2 + n - i, len2 + i - n, + poly1[i]); + } + } + + _nmod_vec_reduce(res, res, len1 + len2 - 1, mod); + } + else + { + /* Set res[i] = poly1[i]*poly2[0] */ + if (start < len1) + _nmod_vec_scalar_mul_nmod(res + start, poly1 + start, len1 - start, + poly2[0], mod); + + if (len2 == 1) + return; + + /* Set res[i+len1-1] = in1[len1-1]*in2[i] */ + m = FLINT_MAX(len1 - 1, start); + _nmod_vec_scalar_mul_nmod(res + m, poly2 + m - len1 + 1, + len2 - 1 + len1 - m, poly1[len1 - 1], mod); + + /* out[i+j] += in1[i]*in2[j] */ + m = FLINT_MAX(start, len2 - 1); + for (i = m - len2 + 1; i < len1 - 1; i++) + { + n = FLINT_MAX(i + 1, start); + _nmod_vec_scalar_addmul_nmod(res + n, poly2 + n - i, len2 + i - n, + poly1[i], mod); + } + } + } +} + +void +nmod_poly_mulhigh_classical(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_poly_t poly2, + slong start) +{ + slong len_out = poly1->length + poly2->length - 1; + + if (poly1->length == 0 || poly2->length == 0 || start >= len_out) + { + nmod_poly_zero(res); + return; + } + + if (res == poly1 || res == poly2) + { + nmod_poly_t temp; + nmod_poly_init2_preinv(temp, poly1->mod.n, poly1->mod.ninv, len_out); + if (poly1->length >= poly2->length) + _nmod_poly_mulhigh_classical(temp->coeffs, poly1->coeffs, + poly1->length, poly2->coeffs, + poly2->length, start, poly1->mod); + else + _nmod_poly_mulhigh_classical(temp->coeffs, poly2->coeffs, + poly2->length, poly1->coeffs, + poly1->length, start, poly1->mod); + nmod_poly_swap(res, temp); + nmod_poly_clear(temp); + } + else + { + nmod_poly_fit_length(res, len_out); + if (poly1->length >= poly2->length) + _nmod_poly_mulhigh_classical(res->coeffs, poly1->coeffs, + poly1->length, poly2->coeffs, + poly2->length, start, poly1->mod); + else + _nmod_poly_mulhigh_classical(res->coeffs, poly2->coeffs, + poly2->length, poly1->coeffs, + poly1->length, start, poly1->mod); + } + + res->length = len_out; + _nmod_poly_normalise(res); +} diff --git a/external/flint-2.4.3/nmod_poly/mullow.c b/external/flint-2.4.3/nmod_poly/mullow.c new file mode 100644 index 0000000..9867047 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/mullow.c @@ -0,0 +1,100 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/***************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +void _nmod_poly_mullow(mp_ptr res, mp_srcptr poly1, slong len1, + mp_srcptr poly2, slong len2, slong n, nmod_t mod) +{ + slong bits, bits2; + + if (len1 + len2 <= 6 || n <= 6) + { + _nmod_poly_mullow_classical(res, poly1, len1, poly2, len2, n, mod); + return; + } + + bits = FLINT_BITS - (slong) mod.norm; + bits2 = FLINT_BIT_COUNT(len1); + + if (2 * bits + bits2 <= FLINT_BITS && len1 + len2 < 16) + _nmod_poly_mullow_classical(res, poly1, len1, poly2, len2, n, mod); + else + _nmod_poly_mullow_KS(res, poly1, len1, poly2, len2, 0, n, mod); +} + +void nmod_poly_mullow(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_poly_t poly2, slong trunc) +{ + slong len1, len2, len_out; + + len1 = poly1->length; + len2 = poly2->length; + + len_out = poly1->length + poly2->length - 1; + if (trunc > len_out) + trunc = len_out; + + if (len1 == 0 || len2 == 0 || trunc == 0) + { + nmod_poly_zero(res); + + return; + } + + if (res == poly1 || res == poly2) + { + nmod_poly_t temp; + + nmod_poly_init2(temp, poly1->mod.n, trunc); + + if (len1 >= len2) + _nmod_poly_mullow(temp->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2, trunc, poly1->mod); + else + _nmod_poly_mullow(temp->coeffs, poly2->coeffs, len2, + poly1->coeffs, len1, trunc, poly1->mod); + + nmod_poly_swap(temp, res); + nmod_poly_clear(temp); + } else + { + nmod_poly_fit_length(res, trunc); + + if (len1 >= len2) + _nmod_poly_mullow(res->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2, trunc, poly1->mod); + else + _nmod_poly_mullow(res->coeffs, poly2->coeffs, len2, + poly1->coeffs, len1, trunc, poly1->mod); + } + + res->length = trunc; + _nmod_poly_normalise(res); +} diff --git a/external/flint-2.4.3/nmod_poly/mullow_KS.c b/external/flint-2.4.3/nmod_poly/mullow_KS.c new file mode 100644 index 0000000..f23e7bd --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/mullow_KS.c @@ -0,0 +1,120 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +void +_nmod_poly_mullow_KS(mp_ptr out, mp_srcptr in1, slong len1, + mp_srcptr in2, slong len2, mp_bitcnt_t bits, slong n, nmod_t mod) +{ + slong limbs1, limbs2; + mp_ptr mpn1, mpn2, res; + + if (bits == 0) + { + mp_bitcnt_t bits1, bits2, loglen; + bits1 = _nmod_vec_max_bits(in1, len1); + bits2 = (in1 == in2) ? bits1 : _nmod_vec_max_bits(in2, len2); + loglen = FLINT_BIT_COUNT(len2); + + bits = bits1 + bits2 + loglen; + } + + limbs1 = (len1 * bits - 1) / FLINT_BITS + 1; + limbs2 = (len2 * bits - 1) / FLINT_BITS + 1; + + mpn1 = (mp_ptr) flint_malloc(sizeof(mp_limb_t) * limbs1); + mpn2 = (in1 == in2) ? mpn1 : (mp_ptr) flint_malloc(sizeof(mp_limb_t) * limbs2); + + _nmod_poly_bit_pack(mpn1, in1, len1, bits); + if (in1 != in2) + _nmod_poly_bit_pack(mpn2, in2, len2, bits); + + res = (mp_ptr) flint_malloc(sizeof(mp_limb_t) * (limbs1 + limbs2)); + + mpn_mul(res, mpn1, limbs1, mpn2, limbs2); + + _nmod_poly_bit_unpack(out, n, res, bits, mod); + + flint_free(mpn2); + if (in1 != in2) + flint_free(mpn1); + + flint_free(res); +} + +void +nmod_poly_mullow_KS(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_poly_t poly2, + mp_bitcnt_t bits, slong n) +{ + slong len_out; + + if ((poly1->length == 0) || (poly2->length == 0)) + { + nmod_poly_zero(res); + return; + } + + len_out = poly1->length + poly2->length - 1; + if (n > len_out) + n = len_out; + + if (res == poly1 || res == poly2) + { + nmod_poly_t temp; + nmod_poly_init2_preinv(temp, poly1->mod.n, poly1->mod.ninv, len_out); + if (poly1->length >= poly2->length) + _nmod_poly_mullow_KS(temp->coeffs, poly1->coeffs, poly1->length, + poly2->coeffs, poly2->length, bits, + n, poly1->mod); + else + _nmod_poly_mullow_KS(temp->coeffs, poly2->coeffs, poly2->length, + poly1->coeffs, poly1->length, bits, + n, poly1->mod); + nmod_poly_swap(res, temp); + nmod_poly_clear(temp); + } + else + { + nmod_poly_fit_length(res, len_out); + if (poly1->length >= poly2->length) + _nmod_poly_mullow_KS(res->coeffs, poly1->coeffs, poly1->length, + poly2->coeffs, poly2->length, bits, + n, poly1->mod); + else + _nmod_poly_mullow_KS(res->coeffs, poly2->coeffs, poly2->length, + poly1->coeffs, poly1->length, bits, + n, poly1->mod); + } + + res->length = n; + _nmod_poly_normalise(res); +} diff --git a/external/flint-2.4.3/nmod_poly/mullow_classical.c b/external/flint-2.4.3/nmod_poly/mullow_classical.c new file mode 100644 index 0000000..195136c --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/mullow_classical.c @@ -0,0 +1,139 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +/* Assumes poly1 and poly2 are not length 0 and 0 < trunc <= len1 + len2 - 1 */ +void +_nmod_poly_mullow_classical(mp_ptr res, mp_srcptr poly1, slong len1, + mp_srcptr poly2, slong len2, slong trunc, nmod_t mod) +{ + if (len1 == 1 || trunc == 1) /* Special case if the length of output is 1 */ + { + res[0] = n_mulmod2_preinv(poly1[0], poly2[0], mod.n, mod.ninv); + } + else /* Ordinary case */ + { + slong i; + + slong bits = FLINT_BITS - (slong) mod.norm; + slong log_len = FLINT_BIT_COUNT(len2); + + if (2 * bits + log_len <= FLINT_BITS) + { + /* Set res[i] = poly1[i]*poly2[0] */ + mpn_mul_1(res, poly1, FLINT_MIN(len1, trunc), poly2[0]); + + if (len2 != 1) + { + /* Set res[i+len1-1] = in1[len1-1]*in2[i] */ + if (trunc > len1) + mpn_mul_1(res + len1, poly2 + 1, trunc - len1, + poly1[len1 - 1]); + + /* out[i+j] += in1[i]*in2[j] */ + for (i = 0; i < FLINT_MIN(len1, trunc) - 1; i++) + mpn_addmul_1(res + i + 1, poly2 + 1, + FLINT_MIN(len2, trunc - i) - 1, poly1[i]); + } + + _nmod_vec_reduce(res, res, trunc, mod); + } + else + { + /* Set res[i] = poly1[i]*poly2[0] */ + _nmod_vec_scalar_mul_nmod(res, poly1, FLINT_MIN(len1, trunc), + poly2[0], mod); + + if (len2 == 1) + return; + + /* Set res[i+len1-1] = in1[len1-1]*in2[i] */ + if (trunc > len1) + _nmod_vec_scalar_mul_nmod(res + len1, poly2 + 1, trunc - len1, + poly1[len1 - 1], mod); + + /* out[i+j] += in1[i]*in2[j] */ + for (i = 0; i < FLINT_MIN(len1, trunc) - 1; i++) + _nmod_vec_scalar_addmul_nmod(res + i + 1, poly2 + 1, + FLINT_MIN(len2, trunc - i) - 1, + poly1[i], mod); + } + } +} + +void +nmod_poly_mullow_classical(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_poly_t poly2, + slong trunc) +{ + slong len_out; + + if (poly1->length == 0 || poly2->length == 0 || trunc == 0) + { + nmod_poly_zero(res); + return; + } + + len_out = poly1->length + poly2->length - 1; + if (trunc > len_out) + trunc = len_out; + + if (res == poly1 || res == poly2) + { + nmod_poly_t temp; + nmod_poly_init2_preinv(temp, poly1->mod.n, poly1->mod.ninv, trunc); + if (poly1->length >= poly2->length) + _nmod_poly_mullow_classical(temp->coeffs, poly1->coeffs, + poly1->length, poly2->coeffs, + poly2->length, trunc, poly1->mod); + else + _nmod_poly_mullow_classical(temp->coeffs, poly2->coeffs, + poly2->length, poly1->coeffs, + poly1->length, trunc, poly1->mod); + nmod_poly_swap(res, temp); + nmod_poly_clear(temp); + } + else + { + nmod_poly_fit_length(res, trunc); + if (poly1->length >= poly2->length) + _nmod_poly_mullow_classical(res->coeffs, poly1->coeffs, + poly1->length, poly2->coeffs, + poly2->length, trunc, poly1->mod); + else + _nmod_poly_mullow_classical(res->coeffs, poly2->coeffs, + poly2->length, poly1->coeffs, + poly1->length, trunc, poly1->mod); + } + + res->length = trunc; + _nmod_poly_normalise(res); +} diff --git a/external/flint-2.4.3/nmod_poly/mulmod.c b/external/flint-2.4.3/nmod_poly/mulmod.c new file mode 100644 index 0000000..058d521 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/mulmod.c @@ -0,0 +1,102 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +void _nmod_poly_mulmod(mp_ptr res, mp_srcptr poly1, slong len1, + mp_srcptr poly2, slong len2, mp_srcptr f, + slong lenf, nmod_t mod) +{ + mp_ptr T, Q; + slong lenT, lenQ; + + lenT = len1 + len2 - 1; + lenQ = lenT - lenf + 1; + + T = _nmod_vec_init(lenT + lenQ); + Q = T + lenT; + + if (len1 >= len2) + _nmod_poly_mul(T, poly1, len1, poly2, len2, mod); + else + _nmod_poly_mul(T, poly2, len2, poly1, len1, mod); + + _nmod_poly_divrem(Q, res, T, lenT, f, lenf, mod); + _nmod_vec_clear(T); +} + +void +nmod_poly_mulmod(nmod_poly_t res, + const nmod_poly_t poly1, const nmod_poly_t poly2, const nmod_poly_t f) +{ + slong len1, len2, lenf; + mp_ptr fcoeffs; + + lenf = f->length; + len1 = poly1->length; + len2 = poly2->length; + + if (lenf == 0) + { + flint_printf("Exception (nmod_poly_mulmod). Divide by zero.\n"); + abort(); + } + + if (lenf == 1 || len1 == 0 || len2 == 0) + { + nmod_poly_zero(res); + return; + } + + if (len1 + len2 - lenf > 0) + { + if (f == res) + { + fcoeffs = flint_malloc(sizeof(mp_limb_t) * lenf); + _nmod_vec_set(fcoeffs, f->coeffs, lenf); + } + else + fcoeffs = f->coeffs; + + nmod_poly_fit_length(res, lenf - 1); + _nmod_poly_mulmod(res->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2, + fcoeffs, lenf, + res->mod); + if (f == res) + flint_free(fcoeffs); + + res->length = lenf - 1; + _nmod_poly_normalise(res); + } + else + { + nmod_poly_mul(res, poly1, poly2); + } +} diff --git a/external/flint-2.4.3/nmod_poly/mulmod_preinv.c b/external/flint-2.4.3/nmod_poly/mulmod_preinv.c new file mode 100644 index 0000000..a33f6ed --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/mulmod_preinv.c @@ -0,0 +1,121 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2013 Martin Lee + +******************************************************************************/ + +#undef ulong +#define ulong ulongxx/* interferes with system includes */ + +#include + +#undef ulong + +#include + +#define ulong mp_limb_t + +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +void _nmod_poly_mulmod_preinv(mp_ptr res, mp_srcptr poly1, slong len1, + mp_srcptr poly2, slong len2, mp_srcptr f, + slong lenf, mp_srcptr finv, slong lenfinv, nmod_t mod) +{ + mp_ptr T, Q; + slong lenT, lenQ; + + lenT = len1 + len2 - 1; + lenQ = lenT - lenf + 1; + + T = _nmod_vec_init(lenT + lenQ); + Q = T + lenT; + + if (len1 >= len2) + _nmod_poly_mul(T, poly1, len1, poly2, len2, mod); + else + _nmod_poly_mul(T, poly2, len2, poly1, len1, mod); + + _nmod_poly_divrem_newton_n_preinv(Q, res, T, lenT, f, lenf, + finv, lenfinv, mod); + _nmod_vec_clear(T); +} + +void +nmod_poly_mulmod_preinv(nmod_poly_t res, const nmod_poly_t poly1, + const nmod_poly_t poly2, const nmod_poly_t f, + const nmod_poly_t finv) +{ + slong len1, len2, lenf; + mp_ptr fcoeffs; + + lenf = f->length; + len1 = poly1->length; + len2 = poly2->length; + + if (lenf == 0) + { + flint_printf("Exception (nmod_poly_mulmod_preinv). Divide by zero.\n"); + abort(); + } + + if (lenf <= len1 || lenf <= len2) + { + flint_printf("Exception (nmod_poly_mulmod_preinv). Input larger than modulus.\n"); + abort(); + } + + if (lenf == 1 || len1 == 0 || len2 == 0) + { + nmod_poly_zero(res); + return; + } + + if (len1 + len2 - lenf > 0) + { + if (f == res) + { + fcoeffs = flint_malloc(sizeof(mp_limb_t) * lenf); + _nmod_vec_set(fcoeffs, f->coeffs, lenf); + } + else + fcoeffs = f->coeffs; + + nmod_poly_fit_length(res, lenf - 1); + _nmod_poly_mulmod_preinv(res->coeffs, poly1->coeffs, len1, + poly2->coeffs, len2, + fcoeffs, lenf, + finv->coeffs, finv->length, + res->mod); + if (f == res) + flint_free(fcoeffs); + + res->length = lenf - 1; + _nmod_poly_normalise(res); + } + else + { + nmod_poly_mul(res, poly1, poly2); + } +} diff --git a/external/flint-2.4.3/nmod_poly/neg.c b/external/flint-2.4.3/nmod_poly/neg.c new file mode 100644 index 0000000..e5797d3 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/neg.c @@ -0,0 +1,41 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007, David Howden. + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +void +nmod_poly_neg(nmod_poly_t res, const nmod_poly_t poly1) +{ + nmod_poly_fit_length(res, poly1->length); + + _nmod_vec_neg(res->coeffs, poly1->coeffs, poly1->length, poly1->mod); + + res->length = poly1->length; +} diff --git a/external/flint-2.4.3/nmod_poly/pow.c b/external/flint-2.4.3/nmod_poly/pow.c new file mode 100644 index 0000000..6869bba --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/pow.c @@ -0,0 +1,88 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +void +_nmod_poly_pow(mp_ptr res, mp_srcptr poly, slong len, ulong e, nmod_t mod) +{ + _nmod_poly_pow_binexp(res, poly, len, e, mod); +} + +void +nmod_poly_pow(nmod_poly_t res, const nmod_poly_t poly, ulong e) +{ + const slong len = poly->length; + slong rlen; + + if ((len < 2) | (e < UWORD(3))) + { + if (len == 0) + nmod_poly_zero(res); + else if (len == 1) + { + nmod_poly_fit_length(res, 1); + res->coeffs[0] = n_powmod2_ui_preinv(poly->coeffs[0], e, + poly->mod.n, poly->mod.ninv); + res->length = 1; + _nmod_poly_normalise(res); + } + else if (e == UWORD(0)) + { + nmod_poly_set_coeff_ui(res, 0, UWORD(1)); + res->length = 1; + _nmod_poly_normalise(res); + } + else if (e == UWORD(1)) + nmod_poly_set(res, poly); + else /* e == UWORD(2) */ + nmod_poly_mul(res, poly, poly); + + return; + } + + rlen = (slong) e * (len - 1) + 1; + + if (res != poly) + { + nmod_poly_fit_length(res, rlen); + _nmod_poly_pow(res->coeffs, poly->coeffs, len, e, poly->mod); + } + else + { + nmod_poly_t t; + nmod_poly_init2(t, poly->mod.n, rlen); + _nmod_poly_pow(t->coeffs, poly->coeffs, len, e, poly->mod); + nmod_poly_swap(res, t); + nmod_poly_clear(t); + } + + res->length = rlen; + _nmod_poly_normalise(res); +} diff --git a/external/flint-2.4.3/nmod_poly/pow_binexp.c b/external/flint-2.4.3/nmod_poly/pow_binexp.c new file mode 100644 index 0000000..fda9795 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/pow_binexp.c @@ -0,0 +1,164 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +void +_nmod_poly_pow_binexp(mp_ptr res, mp_srcptr poly, slong len, ulong e, nmod_t mod) +{ + ulong bit = ~((~UWORD(0)) >> 1); + slong rlen; + slong alloc = (slong) e * (len - 1) + 1; + mp_ptr v = _nmod_vec_init(alloc); + mp_ptr R, S, T; + + /* + Set bits to the bitmask with a 1 one place lower than the msb of e + */ + + while ((bit & e) == UWORD(0)) + bit >>= 1; + + bit >>= 1; + + /* + Trial run without any polynomial arithmetic to determine the parity + of the number of swaps; then set R and S accordingly + */ + + { + unsigned int swaps = 0U; + ulong bit2 = bit; + if ((bit2 & e)) + swaps = ~swaps; + while (bit2 >>= 1) + if ((bit2 & e) == UWORD(0)) + swaps = ~swaps; + + if (swaps == 0U) + { + R = res; + S = v; + } + else + { + R = v; + S = res; + } + } + + /* + We unroll the first step of the loop, referring to {poly, len} + */ + + _nmod_poly_mul(R, poly, len, poly, len, mod); + rlen = 2 * len - 1; + if ((bit & e)) + { + _nmod_poly_mul(S, R, rlen, poly, len, mod); + rlen += len - 1; + T = R; + R = S; + S = T; + } + + while ((bit >>= 1)) + { + if ((bit & e)) + { + _nmod_poly_mul(S, R, rlen, R, rlen, mod); + rlen += rlen - 1; + _nmod_poly_mul(R, S, rlen, poly, len, mod); + rlen += len - 1; + } + else + { + _nmod_poly_mul(S, R, rlen, R, rlen, mod); + rlen += rlen - 1; + T = R; + R = S; + S = T; + } + } + + _nmod_vec_clear(v); +} + +void +nmod_poly_pow_binexp(nmod_poly_t res, const nmod_poly_t poly, ulong e) +{ + const slong len = poly->length; + slong rlen; + + if ((len < 2) | (e < UWORD(3))) + { + if (len == 0) + nmod_poly_zero(res); + else if (len == 1) + { + nmod_poly_fit_length(res, 1); + res->coeffs[0] = n_powmod2_preinv(poly->coeffs[0], e, + poly->mod.n, poly->mod.ninv); + res->length = 1; + _nmod_poly_normalise(res); + } + else if (e == UWORD(0)) + { + nmod_poly_set_coeff_ui(res, 0, UWORD(1)); + res->length = 1; + _nmod_poly_normalise(res); + } + else if (e == UWORD(1)) + nmod_poly_set(res, poly); + else /* e == UWORD(2) */ + nmod_poly_mul(res, poly, poly); + + return; + } + + rlen = (slong) e * (len - 1) + 1; + + if (res != poly) + { + nmod_poly_fit_length(res, rlen); + _nmod_poly_pow_binexp(res->coeffs, poly->coeffs, len, e, poly->mod); + } + else + { + nmod_poly_t t; + nmod_poly_init2(t, poly->mod.n, rlen); + _nmod_poly_pow_binexp(t->coeffs, poly->coeffs, len, e, poly->mod); + nmod_poly_swap(res, t); + nmod_poly_clear(t); + } + + res->length = rlen; + _nmod_poly_normalise(res); +} diff --git a/external/flint-2.4.3/nmod_poly/pow_trunc.c b/external/flint-2.4.3/nmod_poly/pow_trunc.c new file mode 100644 index 0000000..6ccf706 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/pow_trunc.c @@ -0,0 +1,104 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +void +_nmod_poly_pow_trunc(mp_ptr res, mp_srcptr poly, + ulong e, slong trunc, nmod_t mod) +{ + _nmod_poly_pow_trunc_binexp(res, poly, e, trunc, mod); +} + +void +nmod_poly_pow_trunc(nmod_poly_t res, + const nmod_poly_t poly, ulong e, slong trunc) +{ + const slong len = poly->length; + mp_ptr p; + int pcopy = 0; + + if (len < 2 || e < UWORD(3) || trunc == 0) + { + if (len == 0 || trunc == 0) + nmod_poly_zero(res); + else if (len == 1) + { + nmod_poly_fit_length(res, 1); + res->coeffs[0] = n_powmod2_ui_preinv(poly->coeffs[0], e, + poly->mod.n, poly->mod.ninv); + res->length = 1; + _nmod_poly_normalise(res); + } + else if (e == UWORD(0)) + { + nmod_poly_set_coeff_ui(res, 0, UWORD(1)); + res->length = 1; + _nmod_poly_normalise(res); + } + else if (e == UWORD(1)) + { + nmod_poly_set(res, poly); + nmod_poly_truncate(res, trunc); + } + else /* e == UWORD(2) */ + nmod_poly_mullow(res, poly, poly, trunc); + + return; + } + + if (poly->length < trunc) + { + p = _nmod_vec_init(trunc); + flint_mpn_copyi(p, poly->coeffs, poly->length); + flint_mpn_zero(p + poly->length, trunc - poly->length); + pcopy = 1; + } else + p = poly->coeffs; + + if (res != poly || pcopy) + { + nmod_poly_fit_length(res, trunc); + _nmod_poly_pow_trunc(res->coeffs, p, e, trunc, poly->mod); + } + else + { + nmod_poly_t t; + nmod_poly_init2(t, poly->mod.n, trunc); + _nmod_poly_pow_trunc(t->coeffs, p, e, trunc, poly->mod); + nmod_poly_swap(res, t); + nmod_poly_clear(t); + } + + if (pcopy) + _nmod_vec_clear(p); + + res->length = trunc; + _nmod_poly_normalise(res); +} diff --git a/external/flint-2.4.3/nmod_poly/pow_trunc_binexp.c b/external/flint-2.4.3/nmod_poly/pow_trunc_binexp.c new file mode 100644 index 0000000..c9e6efa --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/pow_trunc_binexp.c @@ -0,0 +1,173 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +void +_nmod_poly_pow_trunc_binexp(mp_ptr res, mp_srcptr poly, + ulong e, slong trunc, nmod_t mod) +{ + ulong bit = ~((~UWORD(0)) >> 1); + mp_ptr v = _nmod_vec_init(trunc); + mp_ptr R, S, T; + + /* + Set bits to the bitmask with a 1 one place lower than the msb of e + */ + + while ((bit & e) == UWORD(0)) + bit >>= 1; + + bit >>= 1; + + /* + Trial run without any polynomial arithmetic to determine the parity + of the number of swaps; then set R and S accordingly + */ + + { + unsigned int swaps = 0U; + ulong bit2 = bit; + if ((bit2 & e)) + swaps = ~swaps; + while (bit2 >>= 1) + if ((bit2 & e) == UWORD(0)) + swaps = ~swaps; + + if (swaps == 0U) + { + R = res; + S = v; + } + else + { + R = v; + S = res; + } + } + + /* + We unroll the first step of the loop, referring to {poly, len} + */ + + _nmod_poly_mullow(R, poly, trunc, poly, trunc, trunc, mod); + if ((bit & e)) + { + _nmod_poly_mullow(S, R, trunc, poly, trunc, trunc, mod); + T = R; + R = S; + S = T; + } + + while ((bit >>= 1)) + { + if ((bit & e)) + { + _nmod_poly_mullow(S, R, trunc, R, trunc, trunc, mod); + _nmod_poly_mullow(R, S, trunc, poly, trunc, trunc, mod); + } + else + { + _nmod_poly_mullow(S, R, trunc, R, trunc, trunc, mod); + T = R; + R = S; + S = T; + } + } + + _nmod_vec_clear(v); +} + +void +nmod_poly_pow_trunc_binexp(nmod_poly_t res, + const nmod_poly_t poly, ulong e, slong trunc) +{ + const slong len = poly->length; + mp_ptr p; + int pcopy = 0; + + if (len < 2 || e < UWORD(3) || trunc == 0) + { + if (len == 0 || trunc == 0) + nmod_poly_zero(res); + else if (len == 1) + { + nmod_poly_fit_length(res, 1); + res->coeffs[0] = n_powmod2_ui_preinv(poly->coeffs[0], e, + poly->mod.n, poly->mod.ninv); + res->length = 1; + _nmod_poly_normalise(res); + } + else if (e == UWORD(0)) + { + nmod_poly_set_coeff_ui(res, 0, UWORD(1)); + res->length = 1; + _nmod_poly_normalise(res); + } + else if (e == UWORD(1)) + { + nmod_poly_set(res, poly); + nmod_poly_truncate(res, trunc); + } + else /* e == UWORD(2) */ + nmod_poly_mullow(res, poly, poly, trunc); + + return; + } + + if (poly->length < trunc) + { + p = _nmod_vec_init(trunc); + flint_mpn_copyi(p, poly->coeffs, poly->length); + flint_mpn_zero(p + poly->length, trunc - poly->length); + pcopy = 1; + } else + p = poly->coeffs; + + if (res != poly || pcopy) + { + nmod_poly_fit_length(res, trunc); + _nmod_poly_pow_trunc_binexp(res->coeffs, p, e, trunc, poly->mod); + } + else + { + nmod_poly_t t; + nmod_poly_init2(t, poly->mod.n, trunc); + _nmod_poly_pow_trunc_binexp(t->coeffs, p, e, trunc, poly->mod); + nmod_poly_swap(res, t); + nmod_poly_clear(t); + } + + if (pcopy) + _nmod_vec_clear(p); + + res->length = trunc; + _nmod_poly_normalise(res); +} diff --git a/external/flint-2.4.3/nmod_poly/powmod_mpz_binexp.c b/external/flint-2.4.3/nmod_poly/powmod_mpz_binexp.c new file mode 100644 index 0000000..0763637 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/powmod_mpz_binexp.c @@ -0,0 +1,190 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 William Hart + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + + +static __inline__ mp_limb_t +n_powmod2_mpz(mp_limb_t a, mpz_srcptr exp, mp_limb_t n, mp_limb_t ninv) +{ + if (mpz_fits_slong_p(exp)) + { + return n_powmod2_preinv(a, flint_mpz_get_si(exp), n, ninv); + } + else + { + mpz_t t, m; + mp_limb_t y; + mpz_init(t); + mpz_init(m); + flint_mpz_set_ui(t, a); + flint_mpz_set_ui(m, n); + mpz_powm(t, t, exp, m); + y = flint_mpz_get_ui(t); + mpz_clear(t); + mpz_clear(m); + return y; + } +} + +void +_nmod_poly_powmod_mpz_binexp(mp_ptr res, mp_srcptr poly, + mpz_srcptr e, mp_srcptr f, + slong lenf, nmod_t mod) +{ + mp_ptr T, Q; + slong lenT, lenQ; + slong i; + + if (lenf == 2) + { + res[0] = n_powmod2_mpz(poly[0], e, mod.n, mod.ninv); + return; + } + + lenT = 2 * lenf - 3; + lenQ = lenT - lenf + 1; + + T = _nmod_vec_init(lenT + lenQ); + Q = T + lenT; + + _nmod_vec_set(res, poly, lenf - 1); + + for (i = mpz_sizeinbase(e, 2) - 2; i >= 0; i--) + { + _nmod_poly_mul(T, res, lenf - 1, res, lenf - 1, mod); + _nmod_poly_divrem(Q, res, T, 2 * lenf - 3, f, lenf, mod); + + if (mpz_tstbit(e, i)) + { + _nmod_poly_mul(T, res, lenf - 1, poly, lenf - 1, mod); + _nmod_poly_divrem(Q, res, T, 2 * lenf - 3, f, lenf, mod); + } + } + + _nmod_vec_clear(T); +} + + +void +nmod_poly_powmod_mpz_binexp(nmod_poly_t res, + const nmod_poly_t poly, mpz_srcptr e, + const nmod_poly_t f) +{ + mp_ptr p; + slong len = poly->length; + slong lenf = f->length; + slong trunc = lenf - 1; + int pcopy = 0; + + if (lenf == 0) + { + flint_printf("Exception (nmod_poly_powmod). Divide by zero.\n"); + abort(); + } + + if (mpz_sgn(e) < 0) + { + flint_printf("Exception (nmod_poly_powmod). Negative exp not implemented.\n"); + abort(); + } + + if (len >= lenf) + { + nmod_poly_t t, r; + nmod_poly_init_preinv(t, res->mod.n, res->mod.ninv); + nmod_poly_init_preinv(r, res->mod.n, res->mod.ninv); + nmod_poly_divrem(t, r, poly, f); + nmod_poly_powmod_mpz_binexp(res, r, e, f); + nmod_poly_clear(t); + nmod_poly_clear(r); + return; + } + + if (mpz_fits_ulong_p(e)) + { + ulong exp = flint_mpz_get_ui(e); + + if (exp <= 2) + { + if (exp == UWORD(0)) + { + nmod_poly_fit_length(res, 1); + res->coeffs[0] = UWORD(1); + res->length = 1; + } + else if (exp == UWORD(1)) + { + nmod_poly_set(res, poly); + } + else + nmod_poly_mulmod(res, poly, poly, f); + return; + } + } + + if (lenf == 1 || len == 0) + { + nmod_poly_zero(res); + return; + } + + if (poly->length < trunc) + { + p = _nmod_vec_init(trunc); + flint_mpn_copyi(p, poly->coeffs, poly->length); + flint_mpn_zero(p + poly->length, trunc - poly->length); + pcopy = 1; + } else + p = poly->coeffs; + + if ((res == poly && !pcopy) || (res == f)) + { + nmod_poly_t t; + nmod_poly_init2(t, poly->mod.n, trunc); + _nmod_poly_powmod_mpz_binexp(t->coeffs, + p, e, f->coeffs, lenf, poly->mod); + nmod_poly_swap(res, t); + nmod_poly_clear(t); + } + else + { + nmod_poly_fit_length(res, trunc); + _nmod_poly_powmod_mpz_binexp(res->coeffs, + p, e, f->coeffs, lenf, poly->mod); + } + + if (pcopy) + _nmod_vec_clear(p); + + res->length = trunc; + _nmod_poly_normalise(res); +} diff --git a/external/flint-2.4.3/nmod_poly/powmod_mpz_binexp_preinv.c b/external/flint-2.4.3/nmod_poly/powmod_mpz_binexp_preinv.c new file mode 100644 index 0000000..336f33e --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/powmod_mpz_binexp_preinv.c @@ -0,0 +1,202 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 William Hart + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2013 Martin Lee + +******************************************************************************/ + +#undef ulong +#define ulong ulongxx/* interferes with system includes */ + +#include + +#undef ulong + +#include + +#define ulong mp_limb_t + +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + + +static __inline__ mp_limb_t +n_powmod2_mpz(mp_limb_t a, mpz_srcptr exp, mp_limb_t n, mp_limb_t ninv) +{ + if (mpz_fits_slong_p(exp)) + { + return n_powmod2_preinv(a, flint_mpz_get_si(exp), n, ninv); + } + else + { + mpz_t t, m; + mp_limb_t y; + mpz_init(t); + mpz_init(m); + flint_mpz_set_ui(t, a); + flint_mpz_set_ui(m, n); + mpz_powm(t, t, exp, m); + y = flint_mpz_get_ui(t); + mpz_clear(t); + mpz_clear(m); + return y; + } +} + +void +_nmod_poly_powmod_mpz_binexp_preinv(mp_ptr res, mp_srcptr poly, mpz_srcptr e, + mp_srcptr f, slong lenf, mp_srcptr finv, + slong lenfinv, nmod_t mod) +{ + mp_ptr T, Q; + slong lenT, lenQ; + slong i; + + if (lenf == 2) + { + res[0] = n_powmod2_mpz(poly[0], e, mod.n, mod.ninv); + return; + } + + lenT = 2 * lenf - 3; + lenQ = lenT - lenf + 1; + + T = _nmod_vec_init(lenT + lenQ); + Q = T + lenT; + + _nmod_vec_set(res, poly, lenf - 1); + + for (i = mpz_sizeinbase(e, 2) - 2; i >= 0; i--) + { + _nmod_poly_mul(T, res, lenf - 1, res, lenf - 1, mod); + _nmod_poly_divrem_newton_n_preinv (Q, res, T, 2 * lenf - 3, f, lenf, + finv, lenfinv, mod); + + if (mpz_tstbit(e, i)) + { + _nmod_poly_mul(T, res, lenf - 1, poly, lenf - 1, mod); + _nmod_poly_divrem_newton_n_preinv(Q, res, T, 2 * lenf - 3, f, lenf, + finv, lenfinv, mod); + } + } + + _nmod_vec_clear(T); +} + + +void +nmod_poly_powmod_mpz_binexp_preinv(nmod_poly_t res, + const nmod_poly_t poly, mpz_srcptr e, + const nmod_poly_t f, const nmod_poly_t finv) +{ + mp_ptr p; + slong len = poly->length; + slong lenf = f->length; + slong trunc = lenf - 1; + int pcopy = 0; + + if (lenf == 0) + { + flint_printf("Exception (nmod_poly_powmod_mpz_binexp_preinv). Divide by zero.\n"); + abort(); + } + + if (mpz_sgn(e) < 0) + { + flint_printf("Exception (nmod_poly_powmod_mpz_binexp_preinv). Negative exp not implemented.\n"); + abort(); + } + + if (len >= lenf) + { + nmod_poly_t t, r; + nmod_poly_init_preinv(t, res->mod.n, res->mod.ninv); + nmod_poly_init_preinv(r, res->mod.n, res->mod.ninv); + nmod_poly_divrem(t, r, poly, f); + nmod_poly_powmod_mpz_binexp(res, r, e, f); + nmod_poly_clear(t); + nmod_poly_clear(r); + return; + } + + if (mpz_fits_ulong_p(e)) + { + ulong exp = flint_mpz_get_ui(e); + + if (exp <= 2) + { + if (exp == UWORD (0)) + { + nmod_poly_fit_length(res, 1); + res->coeffs[0] = UWORD (1); + res->length = 1; + } + else if (exp == UWORD (1)) + { + nmod_poly_set(res, poly); + } + else + nmod_poly_mulmod_preinv(res, poly, poly, f, finv); + return; + } + } + + if (lenf == 1 || len == 0) + { + nmod_poly_zero(res); + return; + } + + if (poly->length < trunc) + { + p = _nmod_vec_init(trunc); + flint_mpn_copyi(p, poly->coeffs, poly->length); + flint_mpn_zero(p + poly->length, trunc - poly->length); + pcopy = 1; + } else + p = poly->coeffs; + + if ((res == poly && !pcopy) || (res == f) || (res == finv)) + { + nmod_poly_t t; + nmod_poly_init2(t, poly->mod.n, trunc); + _nmod_poly_powmod_mpz_binexp_preinv(t->coeffs, + p, e, f->coeffs, lenf, finv->coeffs, finv->length, poly->mod); + nmod_poly_swap(res, t); + nmod_poly_clear(t); + } + else + { + nmod_poly_fit_length(res, trunc); + _nmod_poly_powmod_mpz_binexp_preinv(res->coeffs, + p, e, f->coeffs, lenf, finv->coeffs, finv->length, poly->mod); + } + + if (pcopy) + _nmod_vec_clear(p); + + res->length = trunc; + _nmod_poly_normalise(res); +} diff --git a/external/flint-2.4.3/nmod_poly/powmod_ui_binexp.c b/external/flint-2.4.3/nmod_poly/powmod_ui_binexp.c new file mode 100644 index 0000000..b96a2db --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/powmod_ui_binexp.c @@ -0,0 +1,155 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 William Hart + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +void +_nmod_poly_powmod_ui_binexp(mp_ptr res, mp_srcptr poly, + ulong e, mp_srcptr f, slong lenf, nmod_t mod) +{ + mp_ptr T, Q; + slong lenT, lenQ; + int i; + + if (lenf == 2) + { + res[0] = n_powmod2_ui_preinv(poly[0], e, mod.n, mod.ninv); + return; + } + + lenT = 2 * lenf - 3; + lenQ = FLINT_MAX(lenT - lenf + 1, 1); + + T = _nmod_vec_init(lenT + lenQ); + Q = T + lenT; + + _nmod_vec_set(res, poly, lenf - 1); + + for (i = ((int) FLINT_BIT_COUNT(e) - 2); i >= 0; i--) + { + _nmod_poly_mul(T, res, lenf - 1, res, lenf - 1, mod); + _nmod_poly_divrem(Q, res, T, 2 * lenf - 3, f, lenf, mod); + + if (e & (UWORD(1) << i)) + { + _nmod_poly_mul(T, res, lenf - 1, poly, lenf - 1, mod); + _nmod_poly_divrem(Q, res, T, 2 * lenf - 3, f, lenf, mod); + } + } + + _nmod_vec_clear(T); +} + + +void +nmod_poly_powmod_ui_binexp(nmod_poly_t res, + const nmod_poly_t poly, ulong e, + const nmod_poly_t f) +{ + mp_ptr p; + slong len = poly->length; + slong lenf = f->length; + slong trunc = lenf - 1; + int pcopy = 0; + + if (lenf == 0) + { + flint_printf("Exception (nmod_poly_powmod). Divide by zero.\n"); + abort(); + } + + if (len >= lenf) + { + nmod_poly_t t, r; + nmod_poly_init_preinv(t, res->mod.n, res->mod.ninv); + nmod_poly_init_preinv(r, res->mod.n, res->mod.ninv); + nmod_poly_divrem(t, r, poly, f); + nmod_poly_powmod_ui_binexp(res, r, e, f); + nmod_poly_clear(t); + nmod_poly_clear(r); + return; + } + + if (e <= 2) + { + if (e == UWORD(0)) + { + nmod_poly_fit_length(res, 1); + res->coeffs[0] = UWORD(1); + res->length = 1; + } + else if (e == UWORD(1)) + { + nmod_poly_set(res, poly); + } + else + nmod_poly_mulmod(res, poly, poly, f); + return; + } + + if (lenf == 1 || len == 0) + { + nmod_poly_zero(res); + return; + } + + if (len < trunc) + { + p = _nmod_vec_init(trunc); + flint_mpn_copyi(p, poly->coeffs, len); + flint_mpn_zero(p + len, trunc - len); + pcopy = 1; + } else + p = poly->coeffs; + + if ((res == poly && !pcopy) || (res == f)) + { + nmod_poly_t t; + nmod_poly_init2(t, poly->mod.n, trunc); + _nmod_poly_powmod_ui_binexp(t->coeffs, + p, e, f->coeffs, lenf, poly->mod); + nmod_poly_swap(res, t); + nmod_poly_clear(t); + } + else + { + nmod_poly_fit_length(res, trunc); + _nmod_poly_powmod_ui_binexp(res->coeffs, + p, e, f->coeffs, lenf, poly->mod); + } + + if (pcopy) + _nmod_vec_clear(p); + + res->length = trunc; + _nmod_poly_normalise(res); +} diff --git a/external/flint-2.4.3/nmod_poly/powmod_ui_binexp_preinv.c b/external/flint-2.4.3/nmod_poly/powmod_ui_binexp_preinv.c new file mode 100644 index 0000000..046d67e --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/powmod_ui_binexp_preinv.c @@ -0,0 +1,168 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 William Hart + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2013 Martin Lee + +******************************************************************************/ + +#undef ulong +#define ulong ulongxx/* interferes with system includes */ + +#include + +#undef ulong + +#include + +#define ulong mp_limb_t + +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +void +_nmod_poly_powmod_ui_binexp_preinv (mp_ptr res, mp_srcptr poly, + ulong e, mp_srcptr f, slong lenf, + mp_srcptr finv, slong lenfinv, nmod_t mod) +{ + mp_ptr T, Q; + slong lenT, lenQ; + int i; + + if (lenf == 2) + { + res[0] = n_powmod2_ui_preinv(poly[0], e, mod.n, mod.ninv); + return; + } + + lenT = 2 * lenf - 3; + lenQ = FLINT_MAX(lenT - lenf + 1, 1); + + T = _nmod_vec_init(lenT + lenQ); + Q = T + lenT; + + _nmod_vec_set(res, poly, lenf - 1); + + for (i = ((int) FLINT_BIT_COUNT(e) - 2); i >= 0; i--) + { + _nmod_poly_mul(T, res, lenf - 1, res, lenf - 1, mod); + _nmod_poly_divrem_newton_n_preinv(Q, res, T, 2 * lenf - 3, f, + lenf, finv, lenfinv, mod); + + if (e & (UWORD(1) << i)) + { + _nmod_poly_mul(T, res, lenf - 1, poly, lenf - 1, mod); + _nmod_poly_divrem_newton_n_preinv(Q, res, T, 2 * lenf - 3, f, + lenf, finv, lenfinv, mod); + } + } + + _nmod_vec_clear(T); +} + + +void +nmod_poly_powmod_ui_binexp_preinv(nmod_poly_t res, + const nmod_poly_t poly, ulong e, + const nmod_poly_t f, const nmod_poly_t finv) +{ + mp_ptr p; + slong len = poly->length; + slong lenf = f->length; + slong trunc = lenf - 1; + int pcopy = 0; + + if (lenf == 0) + { + flint_printf("Exception (nmod_poly_powmod_ui_binexp_preinv). Divide by zero.\n"); + abort(); + } + + if (len >= lenf) + { + nmod_poly_t t, r; + nmod_poly_init_preinv(t, res->mod.n, res->mod.ninv); + nmod_poly_init_preinv(r, res->mod.n, res->mod.ninv); + nmod_poly_divrem(t, r, poly, f); + nmod_poly_powmod_ui_binexp_preinv(res, r, e, f, finv); + nmod_poly_clear(t); + nmod_poly_clear(r); + return; + } + + if (e <= 2) + { + if (e == UWORD(0)) + { + nmod_poly_fit_length(res, 1); + res->coeffs[0] = UWORD(1); + res->length = 1; + } + else if (e == UWORD(1)) + { + nmod_poly_set(res, poly); + } + else + nmod_poly_mulmod_preinv(res, poly, poly, f, finv); + return; + } + + if (lenf == 1 || len == 0) + { + nmod_poly_zero(res); + return; + } + + if (len < trunc) + { + p = _nmod_vec_init(trunc); + flint_mpn_copyi(p, poly->coeffs, len); + flint_mpn_zero(p + len, trunc - len); + pcopy = 1; + } else + p = poly->coeffs; + + if ((res == poly && !pcopy) || (res == f) || (res == finv)) + { + nmod_poly_t t; + nmod_poly_init2(t, poly->mod.n, trunc); + _nmod_poly_powmod_ui_binexp_preinv(t->coeffs, + p, e, f->coeffs, lenf, finv->coeffs, finv->length, poly->mod); + nmod_poly_swap(res, t); + nmod_poly_clear(t); + } + else + { + nmod_poly_fit_length(res, trunc); + _nmod_poly_powmod_ui_binexp_preinv(res->coeffs, + p, e, f->coeffs, lenf, finv->coeffs, finv->length, poly->mod); + } + + if (pcopy) + _nmod_vec_clear(p); + + res->length = trunc; + _nmod_poly_normalise(res); +} diff --git a/external/flint-2.4.3/nmod_poly/powmod_x_ui_preinv.c b/external/flint-2.4.3/nmod_poly/powmod_x_ui_preinv.c new file mode 100644 index 0000000..295da59 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/powmod_x_ui_preinv.c @@ -0,0 +1,196 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 William Hart + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2013 Martin Lee + +******************************************************************************/ + +#undef ulong +#define ulong ulongxx/* interferes with system includes */ + +#include + +#undef ulong + +#include + +#define ulong mp_limb_t + +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" +#include "long_extras.h" + +void +_nmod_poly_powmod_x_ui_preinv (mp_ptr res, ulong e, mp_srcptr f, slong lenf, + mp_srcptr finv, slong lenfinv, nmod_t mod) +{ + mp_ptr T, Q; + slong lenT, lenQ, window; + int i, l, c; + + lenT = 2 * lenf - 3; + lenQ = FLINT_MAX(lenT - lenf + 1, 1); + + T = _nmod_vec_init(lenT + lenQ); + Q = T + lenT; + + flint_mpn_zero (res, lenf - 1); + res[0] = WORD(1); + + l = (int) z_sizeinbase (lenf - 1, 2) - 2; + window = WORD(0); + window = (WORD(1) << l); + c = l; + i = (int) FLINT_BIT_COUNT(e) - 2; + if (i <= l) + { + window = WORD(0); + window = (WORD(1) << i); + c = i; + l = i; + } + + if (c == 0) + { + _nmod_poly_shift_left(T, res, lenf - 1, window); + _nmod_poly_divrem_newton_n_preinv(Q, res, T, lenf - 1 + window, f, + lenf, finv, lenfinv, mod); + c = l + 1; + window= WORD(0); + } + + for (; i >= 0; i--) + { + _nmod_poly_mul(T, res, lenf - 1, res, lenf - 1, mod); + _nmod_poly_divrem_newton_n_preinv(Q, res, T, 2 * lenf - 3, f, + lenf, finv, lenfinv, mod); + + c--; + if (e & (UWORD(1) << i)) + { + if (window == WORD(0) && i <= l - 1) + c = i; + if ( c >= 0) + window = window | (WORD(1) << c); + } + else if (window == WORD(0)) + c= l + 1; + if (c == 0) + { + _nmod_poly_shift_left(T, res, lenf - 1, window); + _nmod_poly_divrem_newton_n_preinv(Q, res, T, lenf - 1 + window, f, + lenf, finv, lenfinv, mod); + + c= l + 1; + window= WORD(0); + } + } + + _nmod_vec_clear(T); +} + + +void +nmod_poly_powmod_x_ui_preinv(nmod_poly_t res, ulong e, const nmod_poly_t f, + const nmod_poly_t finv) +{ + slong lenf = f->length; + slong trunc = lenf - 1; + nmod_poly_t tmp; + + if (lenf == 0) + { + flint_printf("Exception (nmod_poly_powmod_x_ui_preinv). Divide by zero.\n"); + abort(); + } + + if (lenf == 1) + { + nmod_poly_zero(res); + return; + } + + if (lenf == 2) + { + nmod_poly_t r, poly; + nmod_poly_init_preinv(tmp, res->mod.n, res->mod.ninv); + nmod_poly_init_preinv(r, res->mod.n, res->mod.ninv); + nmod_poly_init2_preinv(poly, res->mod.n, res->mod.ninv, 2); + nmod_poly_set_coeff_ui (poly, 1, 1); + nmod_poly_divrem(tmp, r, poly, f); + nmod_poly_powmod_ui_binexp_preinv(res, r, e, f, finv); + nmod_poly_clear(tmp); + nmod_poly_clear(r); + nmod_poly_clear(poly); + return; + } + + if (e <= 2) + { + if (e == UWORD(0)) + { + nmod_poly_fit_length(res, 1); + res->coeffs[0] = UWORD(1); + res->length = 1; + } + else if (e == UWORD(1)) + { + nmod_poly_t r; + nmod_poly_init2_preinv (r, res->mod.n, res->mod.ninv, 2); + nmod_poly_set_coeff_ui (r, 1, 1); + nmod_poly_init_preinv(tmp, res->mod.n, res->mod.ninv); + nmod_poly_divrem (tmp, res, r, f); + nmod_poly_clear(tmp); + nmod_poly_clear(r); + } + else + { + nmod_poly_init2_preinv (tmp, res->mod.n, res->mod.ninv, 3); + nmod_poly_set_coeff_ui (tmp, 1, 1); + nmod_poly_mulmod (res, tmp, tmp, f); + nmod_poly_clear(tmp); + } + return; + } + + if ((res == f) || (res == finv)) + { + nmod_poly_init2(tmp, res->mod.n, trunc); + _nmod_poly_powmod_x_ui_preinv(tmp->coeffs, e, f->coeffs, lenf, + finv->coeffs, finv->length, f->mod); + nmod_poly_swap(res, tmp); + nmod_poly_clear(tmp); + } + else + { + nmod_poly_fit_length(res, trunc); + _nmod_poly_powmod_x_ui_preinv(res->coeffs, e, f->coeffs, lenf, + finv->coeffs, finv->length, f->mod); + } + + res->length = trunc; + _nmod_poly_normalise(res); +} diff --git a/external/flint-2.4.3/nmod_poly/product_roots_nmod_vec.c b/external/flint-2.4.3/nmod_poly/product_roots_nmod_vec.c new file mode 100644 index 0000000..8e71867 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/product_roots_nmod_vec.c @@ -0,0 +1,79 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "nmod_poly.h" +#include "ulong_extras.h" + +void +_nmod_poly_product_roots_nmod_vec(mp_ptr poly, mp_srcptr xs, slong n, nmod_t mod) +{ + if (n == 0) + { + poly[0] = UWORD(1); + } + else if (n < 20) + { + slong i, j; + + poly[n] = UWORD(1); + poly[n - 1] = nmod_neg(xs[0], mod); + + for (i = 1; i < n; i++) + { + poly[n-i-1] = nmod_neg(n_mulmod2_preinv(poly[n-i], xs[i], + mod.n, mod.ninv), mod); + + for (j = 0; j < i - 1; j++) + { + poly[n-i+j] = nmod_sub(poly[n-i+j], + n_mulmod2_preinv(poly[n-i+j+1], xs[i], mod.n, mod.ninv), + mod); + } + + poly[n-1] = nmod_sub(poly[n-1], xs[i], mod); + } + } + else + { + const slong m = (n + 1) / 2; + mp_ptr tmp; + + tmp = _nmod_vec_init(n + 2); + + _nmod_poly_product_roots_nmod_vec(tmp, xs, m, mod); + _nmod_poly_product_roots_nmod_vec(tmp + m + 1, xs + m, n - m, mod); + _nmod_poly_mul(poly, tmp, m + 1, tmp + m + 1, n - m + 1, mod); + + _nmod_vec_clear(tmp); + } +} + +void +nmod_poly_product_roots_nmod_vec(nmod_poly_t poly, mp_srcptr xs, slong n) +{ + nmod_poly_fit_length(poly, n + 1); + _nmod_poly_product_roots_nmod_vec(poly->coeffs, xs, n, poly->mod); + poly->length = n + 1; +} diff --git a/external/flint-2.4.3/nmod_poly/profile/p-gcd.c b/external/flint-2.4.3/nmod_poly/profile/p-gcd.c new file mode 100644 index 0000000..8c79b60 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/profile/p-gcd.c @@ -0,0 +1,150 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include "flint.h" +#include "nmod_poly.h" + +/* + Profiling and benchmarking code for GCD in nmod_poly. + + For three different prime moduli p[i], for a sequence of degrees degs[k], + we create 100 random polynomials A, B, C of degree degs[k]/2 and then + compute GCD(AC, BC) repeatedly, runs[i][k] times. + */ + +#define N 50 + +int main(void) +{ + FLINT_TEST_INIT(state); + + mp_limb_t p[] = {17ul, 2147483659ul, 9223372036854775837ul}; + const slong degs[] = { 20, 40, 60, 80, 100, 120, 140, 160, 180, 200, + 220, 240, 260, 280, 300, 320, 340, 360, 380, 400, + 420, 440, 460, 480, 500, 520, 540, 560, 580, 600, + 620, 640, 660, 680, 700, 720, 740, 760, 780, 800, + 820, 840, 860, 880, 900, 920, 940, 960, 980, 1000}; + const slong runs[3][N] = {{ 2000, 1000, 500, 300, 200, 200, 200, 180, 140, 140, + 100, 80, 80, 80, 50, 50, 40, 30, 30, 20, + 18, 16, 14, 12, 10, 10, 10, 10, 10, 10, + 9, 9, 9, 9, 8, 8, 8, 8, 7, 7, + 7, 7, 6, 6, 6, 6, 5, 5, 5, 5}, + { 1400, 800, 400, 260, 160, 140, 120, 100, 60, 60, + 50, 50, 40, 40, 30, 30, 20, 20, 20, 15, + 14, 13, 12, 11, 10, 10, 10, 10, 10, 10, + 9, 9, 8, 8, 8, 7, 7, 7, 6, 6, + 6, 6, 6, 5, 5, 5, 5, 5, 4, 4}, + { 1400, 800, 400, 260, 160, 120, 100, 80, 60, 50, + 50, 40, 30, 20, 20, 20, 15, 15, 15, 12, + 12, 11, 11, 10, 10, 10, 10, 10, 10, 10, + 9, 9, 8, 8, 8, 7, 7, 7, 6, 6, + 6, 6, 6, 5, 5, 5, 5, 5, 4, 4}}; + + clock_t c0, c1; + long double cpu[3][2][N]; + slong i, k, c, n; + + nmod_poly_t A, B, C, G; + + + + for (i = 0; i < 3; i++) + { + flint_printf("---[Modulus %wu]---\n", p[i]), fflush(stdout); + + for (k = 0; k < N; k++) + { + const slong d = degs[k]; + const slong r = runs[i][k]; + + cpu[i][0][k] = 0; + cpu[i][1][k] = 0; + + nmod_poly_init(A, p[i]); + nmod_poly_init(B, p[i]); + nmod_poly_init(C, p[i]); + nmod_poly_init(G, p[i]); + + for (c = 0; c < 100; c++) + { + nmod_poly_randtest(A, state, d/2); + nmod_poly_randtest(B, state, d/2); + nmod_poly_randtest(C, state, d/2); + nmod_poly_mul(A, A, C); + nmod_poly_mul(B, B, C); + + c0 = clock(); + for (n = 0; n < r; n++) + nmod_poly_gcd_euclidean(G, A, B); + c1 = clock(); + cpu[i][0][k] += (c1 - c0); + + c0 = clock(); + for (n = 0; n < r; n++) + nmod_poly_gcd_hgcd(G, A, B); + c1 = clock(); + cpu[i][1][k] += (c1 - c0); + } + + cpu[i][0][k] = (long double) cpu[i][0][k] / (long double) CLOCKS_PER_SEC; + cpu[i][1][k] = (long double) cpu[i][1][k] / (long double) CLOCKS_PER_SEC; + + cpu[i][0][k] = (long double) cpu[i][0][k] / (long double) (100*r); + cpu[i][1][k] = (long double) cpu[i][1][k] / (long double) (100*r); + + flint_printf("%4ld %10.WORD(8)f %10.WORD(8)f\n", A->length, cpu[i][0][k], cpu[i][1][k]); + fflush(stdout); + + nmod_poly_clear(A); + nmod_poly_clear(B); + nmod_poly_clear(G); + } + } + + flint_printf("cpu = ["); + for (i = 0; i < 3; i++) + { + flint_printf("[["); + for (k = 0; k < N; k++) + flint_printf("%.WORD(8)f,", cpu[i][0][k]); + flint_printf("],"); + flint_printf("["); + for (k = 0; k < N; k++) + flint_printf("%.WORD(8)f,", cpu[i][1][k]); + flint_printf("]],"); + } + flint_printf("]\n"); + + flint_randclear(state); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/nmod_poly/profile/p-mul.c b/external/flint-2.4.3/nmod_poly/profile/p-mul.c new file mode 100644 index 0000000..4be33b6 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/profile/p-mul.c @@ -0,0 +1,111 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright 2010 William Hart + +******************************************************************************/ + +#include +#include +#include "profiler.h" +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_poly.h" + +typedef struct +{ + slong n; +} info_t; + +void sample(void * arg, ulong count) +{ + info_t * info = (info_t *) arg; + slong n = info->n, i, j; + slong scale; + + FLINT_TEST_INIT(state); + + nmod_poly_t a, b, c; + mp_limb_t m = n_randint(state, 1<<((48-FLINT_BIT_COUNT(n))/2)); + if (m == 0) m = 2; + + nmod_poly_init2(a, m, n); + nmod_poly_init2(b, m, n); + nmod_poly_init2(c, m, 2*n - 1); + + for (i = 0; i < n; i++) + { + a->coeffs[i] = n_randint(state, m); + b->coeffs[i] = n_randint(state, m); + } + a->length = n; + b->length = n; + + scale = 1; + if (n < 100000) scale = 10; + if (n < 10000) scale = 100; + if (n < 100) scale = 1000; + + for (i = 0; i < count; i++) + { + prof_start(); + for (j = 0; j < scale; j++) + { + nmod_poly_mul(c, a, b); + } + prof_stop(); + if (c->coeffs[n - 2] == 123) abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + flint_randclear(state); +} + +int main(void) +{ + double min, max; + info_t info; + slong k, scale; + + for (k = 2; k <= 30; k++) + { + info.n = 1< +#include +#include "profiler.h" +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_poly.h" + +typedef struct +{ + slong n; + slong s; + slong alg; +} info_t; + +void sample(void * arg, ulong count) +{ + info_t * info = (info_t *) arg; + slong n = info->n, i, j, s= info->s, alg=info->alg; + slong scale; + + FLINT_TEST_INIT(state); + + nmod_poly_t a, b, c, d, dinv; + mp_limb_t m = n_randint(state, 1<<((48-FLINT_BIT_COUNT(n))/2)); /* modulus */ + if (m == 0) m = 2; + + nmod_poly_init2(a, m, n); + nmod_poly_init2(b, m, n); + nmod_poly_init2(c, m, 2*n - 1); + nmod_poly_init2(d, m, s); + nmod_poly_init2(dinv, m, s); + + for (i = 0; i < n; i++) + { + a->coeffs[i] = n_randint(state, m); + b->coeffs[i] = n_randint(state, m); + } + for (i = 0; i < s; i++) + d->coeffs[i] = n_randint(state, m); + a->length = n; + b->length = n; + d->length = s; + + nmod_poly_reverse(dinv, d, s); + nmod_poly_inv_series(dinv, dinv, s); + + scale = 1; + if (n < 100000) scale = 10; + if (n < 10000) scale = 100; + if (n < 100) scale = 1000; + + for (i = 0; i < count; i++) + { + if (alg == 1) + { + prof_start(); + for (j = 0; j < scale; j++) + { + nmod_poly_mulmod_preinv(c, a, b, d, dinv); + } + prof_stop(); + } + else + { + prof_start(); + for (j = 0; j < scale; j++) + { + nmod_poly_mulmod(c, a, b, d); + } + prof_stop(); + } + if (c->coeffs[n - 2] == 123) abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + nmod_poly_clear(d); + nmod_poly_clear(dinv); + flint_randclear(state); +} + +int main(void) +{ + double min, max; + info_t info; + slong i, k, scale; + + + for (k = 2; k <= 30; k++) + { + info.n = 1< +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_poly.h" + +void +nmod_poly_randtest(nmod_poly_t poly, flint_rand_t state, slong len) +{ + nmod_poly_fit_length(poly, len); + _nmod_vec_randtest(poly->coeffs, state, len, poly->mod); + poly->length = len; + _nmod_poly_normalise(poly); +} + +void +nmod_poly_randtest_monic(nmod_poly_t poly, flint_rand_t state, slong len) +{ + nmod_poly_fit_length(poly, len); + _nmod_vec_randtest(poly->coeffs, state, len - 1, poly->mod); + poly->coeffs[len - 1] = 1; + poly->length = len; +} + +void +nmod_poly_randtest_irreducible(nmod_poly_t poly, flint_rand_t state, slong len) +{ + do { + nmod_poly_randtest(poly, state, len); + } while (nmod_poly_is_zero(poly) || !(nmod_poly_is_irreducible(poly))); +} + +void +nmod_poly_randtest_monic_irreducible(nmod_poly_t poly, flint_rand_t state, slong len) +{ + do { + nmod_poly_randtest_monic(poly, state, len); + } while (nmod_poly_is_zero(poly) || !(nmod_poly_is_irreducible(poly))); +} + +void +nmod_poly_randtest_trinomial(nmod_poly_t poly, flint_rand_t state, slong len) +{ + ulong k; + nmod_poly_fit_length(poly, len); + _nmod_vec_zero(poly->coeffs, len); + poly->coeffs[0] = n_randtest(state) % poly->mod.n; + poly->coeffs[len - 1] = 1; + k = (n_randtest(state) % (len - 2)) + 1; + poly->coeffs[k] = n_randtest(state) % poly->mod.n; + _nmod_poly_set_length(poly, len); +} + +void +nmod_poly_randtest_pentomial(nmod_poly_t poly, flint_rand_t state, slong len) +{ + nmod_poly_fit_length(poly, len); + _nmod_vec_zero(poly->coeffs, len); + poly->coeffs[0] = n_randtest(state) % poly->mod.n; + poly->coeffs[1] = n_randtest(state) % poly->mod.n; + poly->coeffs[2] = n_randtest(state) % poly->mod.n; + poly->coeffs[3] = n_randtest(state) % poly->mod.n; + poly->coeffs[len - 1] = 1; + _nmod_poly_set_length(poly, len); +} + +int +nmod_poly_randtest_trinomial_irreducible(nmod_poly_t poly, flint_rand_t state, + slong len, slong max_attempts) +{ + slong i = 0; + + while (max_attempts == 0 || i < max_attempts) + { + nmod_poly_randtest_trinomial(poly, state, len); + if (!nmod_poly_is_zero(poly) && nmod_poly_is_irreducible(poly)) + { + return 1; + } + i++; + + } + return 0; +} + +int +nmod_poly_randtest_pentomial_irreducible(nmod_poly_t poly, flint_rand_t state, + slong len, slong max_attempts) +{ + slong i = 0; + + while (max_attempts == 0 || i < max_attempts) + { + nmod_poly_randtest_pentomial(poly, state, len); + if (!nmod_poly_is_zero(poly) && nmod_poly_is_irreducible(poly)) + { + return 1; + } + i++; + + } + return 0; +} + +void +nmod_poly_randtest_sparse_irreducible(nmod_poly_t poly, flint_rand_t state, slong len) +{ + if (len < 3) + { + nmod_poly_randtest_monic_irreducible(poly, state, len); + return; + } + + /* Try trinomials */ + if (nmod_poly_randtest_trinomial_irreducible(poly, state, len, 2*len)) + return; + + if (len < 5) + { + nmod_poly_randtest_monic_irreducible(poly, state, len); + return; + } + + /* Try pentomials */ + if (nmod_poly_randtest_pentomial_irreducible(poly, state, len, 2*len)) + return; + + /* Give up */ + nmod_poly_randtest_monic_irreducible(poly, state, len); +} diff --git a/external/flint-2.4.3/nmod_poly/realloc.c b/external/flint-2.4.3/nmod_poly/realloc.c new file mode 100644 index 0000000..47897b6 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/realloc.c @@ -0,0 +1,56 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007, David Howden. + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_poly.h" + +void +nmod_poly_realloc(nmod_poly_t poly, slong alloc) +{ + if (alloc == 0) + { + nmod_poly_clear(poly); + poly->length = 0; + poly->alloc = 0; + poly->coeffs = NULL; + + return; + } + + poly->coeffs = (mp_ptr) flint_realloc(poly->coeffs, alloc * sizeof(mp_limb_t)); + + poly->alloc = alloc; + + /* truncate poly if necessary */ + if (poly->length > alloc) + { + poly->length = alloc; + _nmod_poly_normalise(poly); + } +} diff --git a/external/flint-2.4.3/nmod_poly/rem.c b/external/flint-2.4.3/nmod_poly/rem.c new file mode 100644 index 0000000..65d11b0 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/rem.c @@ -0,0 +1,99 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +void _nmod_poly_rem(mp_ptr R, mp_srcptr A, slong lenA, + mp_srcptr B, slong lenB, nmod_t mod) +{ + TMP_INIT; + + if (lenA - lenB == 1) + { + _nmod_poly_rem_q1(R, A, lenA, B, lenB, mod); + } + else if (lenA < NMOD_DIVREM_DIVCONQUER_CUTOFF) + { + mp_ptr W; + + TMP_START; + W = TMP_ALLOC(NMOD_DIVREM_BC_ITCH(lenA, lenB, mod)*sizeof(mp_limb_t)); + + _nmod_poly_rem_basecase(R, W, A, lenA, B, lenB, mod); + TMP_END; + } + else + { + mp_ptr Q = _nmod_vec_init(lenA - lenB + 1); + + _nmod_poly_divrem(Q, R, A, lenA, B, lenB, mod); + _nmod_vec_clear(Q); + } +} + +void nmod_poly_rem(nmod_poly_t R, const nmod_poly_t A, const nmod_poly_t B) +{ + const slong lenA = A->length, lenB = B->length; + nmod_poly_t tR; + mp_ptr r; + + if (lenB == 0) + { + flint_printf("Exception (nmod_poly_rem). Division by zero.\n"); + abort(); + } + if (lenA < lenB) + { + nmod_poly_set(R, A); + return; + } + + if (R == A || R == B) + { + nmod_poly_init2_preinv(tR, B->mod.n, B->mod.ninv, lenB - 1); + r = tR->coeffs; + } + else + { + nmod_poly_fit_length(R, lenB - 1); + r = R->coeffs; + } + + _nmod_poly_rem(r, A->coeffs, lenA, B->coeffs, lenB, A->mod); + + if (R == A || R == B) + { + nmod_poly_swap(R, tR); + nmod_poly_clear(tR); + } + + R->length = lenB - 1; + _nmod_poly_normalise(R); +} diff --git a/external/flint-2.4.3/nmod_poly/rem_basecase.c b/external/flint-2.4.3/nmod_poly/rem_basecase.c new file mode 100644 index 0000000..bf4b66f --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/rem_basecase.c @@ -0,0 +1,201 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 William Hart + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +void _nmod_poly_rem_basecase_1(mp_ptr R, mp_ptr W, + mp_srcptr A, slong lenA, mp_srcptr B, slong lenB, + nmod_t mod) +{ + if (lenB > 1) + { + const mp_limb_t invL = n_invmod(B[lenB - 1], mod.n); + slong iR; + mp_ptr R1 = W; + + flint_mpn_copyi(R1, A, lenA); + + for (iR = lenA - 1; iR >= lenB - 1; iR--) + { + if (R1[iR] != 0) + { + const mp_limb_t q = n_mulmod2_preinv(R1[iR], invL, mod.n, mod.ninv); + const mp_limb_t c = n_negmod(q, mod.n); + + mpn_addmul_1(R1 + iR - lenB + 1, B, lenB - 1, c); + } + } + _nmod_vec_reduce(R, R1, lenB - 1, mod); + } +} + +void _nmod_poly_rem_basecase_2(mp_ptr R, mp_ptr W, + mp_srcptr A, slong lenA, mp_srcptr B, slong lenB, + nmod_t mod) +{ + if (lenB > 1) + { + const mp_limb_t invL = n_invmod(B[lenB - 1], mod.n); + slong iR, i; + mp_ptr B2 = W, R2 = W + 2*(lenB - 1); + + for (i = 0; i < lenB - 1; i++) + { + B2[2 * i] = B[i]; + B2[2 * i + 1] = 0; + } + for (i = 0; i < lenA; i++) + { + R2[2 * i] = A[i]; + R2[2 * i + 1] = 0; + } + + for (iR = lenA - 1; iR >= lenB - 1; iR--) + { + const mp_limb_t r = + n_ll_mod_preinv(R2[2 * iR + 1], R2[2 * iR], mod.n, mod.ninv); + + if (r != 0) + { + const mp_limb_t q = n_mulmod2_preinv(r, invL, mod.n, mod.ninv); + const mp_limb_t c = n_negmod(q, mod.n); + mpn_addmul_1(R2 + 2 * (iR - lenB + 1), B2, 2 * lenB - 2, c); + } + } + + for (iR = 0; iR < lenB - 1; iR++) + R[iR] = n_ll_mod_preinv(R2[2*iR+1], R2[2*iR], mod.n, mod.ninv); + } +} + +void _nmod_poly_rem_basecase_3(mp_ptr R, mp_ptr W, + mp_srcptr A, slong lenA, mp_srcptr B, slong lenB, + nmod_t mod) +{ + if (lenB > 1) + { + const mp_limb_t invL = n_invmod(B[lenB - 1], mod.n); + slong iR, i; + mp_ptr B3 = W, R3 = W + 3*(lenB - 1); + + for (i = 0; i < lenB - 1; i++) + { + B3[3 * i] = B[i]; + B3[3 * i + 1] = 0; + B3[3 * i + 2] = 0; + } + for (i = 0; i < lenA; i++) + { + R3[3 * i] = A[i]; + R3[3 * i + 1] = 0; + R3[3 * i + 2] = 0; + } + + for (iR = lenA - 1; iR >= lenB - 1; iR--) + { + const mp_limb_t r = n_lll_mod_preinv(R3[3*iR + 2], R3[3*iR + 1], + R3[3*iR], mod.n, mod.ninv); + + if (r != 0) + { + const mp_limb_t q = n_mulmod2_preinv(r, invL, mod.n, mod.ninv); + const mp_limb_t c = n_negmod(q, mod.n); + mpn_addmul_1(R3 + 3 * (iR - lenB + 1), B3, 3 * lenB - 3, c); + } + } + + for (iR = 0; iR < lenB - 1; iR++) + R[iR] = n_lll_mod_preinv(R3[3 * iR + 2], R3[3 * iR + 1], + R3[3 * iR], mod.n, mod.ninv); + } +} + +void _nmod_poly_rem_basecase(mp_ptr R, mp_ptr W, + mp_srcptr A, slong lenA, mp_srcptr B, slong lenB, + nmod_t mod) +{ + const slong bits = + 2 * (FLINT_BITS - mod.norm) + FLINT_BIT_COUNT(lenA - lenB + 1); + + if (bits <= FLINT_BITS) + _nmod_poly_rem_basecase_1(R, W, A, lenA, B, lenB, mod); + else if (bits <= 2 * FLINT_BITS) + _nmod_poly_rem_basecase_2(R, W, A, lenA, B, lenB, mod); + else + _nmod_poly_rem_basecase_3(R, W, A, lenA, B, lenB, mod); +} + +void +nmod_poly_rem_basecase(nmod_poly_t R, const nmod_poly_t A, const nmod_poly_t B) +{ + const slong lenA = A->length, lenB = B->length; + mp_ptr r, W; + nmod_poly_t t; + TMP_INIT; + + if (lenB == 0) + { + flint_printf("Exception (nmod_poly_rem_basecase). Division by zero.\n"); + abort(); + } + if (lenA < lenB) + { + nmod_poly_set(R, A); + return; + } + + if (R == A || R == B) + { + nmod_poly_init2_preinv(t, B->mod.n, B->mod.ninv, lenB - 1); + r = t->coeffs; + } + else + { + nmod_poly_fit_length(R, lenB - 1); + r = R->coeffs; + } + + TMP_START; + W = TMP_ALLOC(NMOD_DIVREM_BC_ITCH(lenA, lenB, A->mod)*sizeof(mp_limb_t)); + + _nmod_poly_rem_basecase(r, W, A->coeffs, lenA, + B->coeffs, lenB, B->mod); + + if (R == A || R == B) + { + nmod_poly_swap(R, t); + nmod_poly_clear(t); + } + R->length = lenB - 1; + + TMP_END; + _nmod_poly_normalise(R); +} diff --git a/external/flint-2.4.3/nmod_poly/rem_q1.c b/external/flint-2.4.3/nmod_poly/rem_q1.c new file mode 100644 index 0000000..791e56c --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/rem_q1.c @@ -0,0 +1,65 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +void _nmod_poly_rem_q1(mp_ptr R, + mp_srcptr A, slong lenA, mp_srcptr B, slong lenB, + nmod_t mod) +{ + const mp_limb_t invL = (B[lenB-1] == 1) ? 1 : n_invmod(B[lenB-1], mod.n); + + if (lenB > 1) + { + mp_limb_t t, q0, q1; + + q1 = n_mulmod2_preinv(A[lenA-1], invL, mod.n, mod.ninv); + t = n_mulmod2_preinv(q1, B[lenB-2], mod.n, mod.ninv); + t = n_submod(A[lenA-2], t, mod.n); + q0 = n_mulmod2_preinv(t, invL, mod.n, mod.ninv); + + if (FLINT_BITS + 2 <= 2 * mod.norm) + { + mpn_mul_1(R, B, lenB - 1, q0); + if (lenB > 2) + mpn_addmul_1(R + 1, B, lenB - 2, q1); + _nmod_vec_reduce(R, R, lenB - 1, mod); + } + else + { + _nmod_vec_scalar_mul_nmod(R, B, lenB - 1, q0, mod); + if (lenB > 2) + _nmod_vec_scalar_addmul_nmod(R + 1, B, lenB - 2, q1, mod); + } + + _nmod_vec_sub(R, A, R, lenB - 1, mod); + } +} + diff --git a/external/flint-2.4.3/nmod_poly/remove.c b/external/flint-2.4.3/nmod_poly/remove.c new file mode 100644 index 0000000..ec124c4 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/remove.c @@ -0,0 +1,55 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "nmod_poly.h" + +ulong nmod_poly_remove(nmod_poly_t f, const nmod_poly_t p) +{ + nmod_poly_t q, r; + ulong i = 0; + + nmod_poly_init_preinv(q, p->mod.n, p->mod.ninv); + nmod_poly_init_preinv(r, p->mod.n, p->mod.ninv); + + while (1) + { + if (f->length < p->length) + break; + nmod_poly_divrem(q, r, f, p); + if (r->length == 0) + nmod_poly_swap(q, f); + else + break; + i++; + } + + nmod_poly_clear(q); + nmod_poly_clear(r); + + return i; +} diff --git a/external/flint-2.4.3/nmod_poly/resultant_euclidean.c b/external/flint-2.4.3/nmod_poly/resultant_euclidean.c new file mode 100644 index 0000000..717ac81 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/resultant_euclidean.c @@ -0,0 +1,152 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007, 2008 William Hart + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "mpn_extras.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +mp_limb_t +_nmod_poly_resultant_euclidean(mp_srcptr poly1, slong len1, + mp_srcptr poly2, slong len2, nmod_t mod) +{ + if (poly1 == poly2) + { + return 0; + } + else if (len2 == 1) + { + if (len1 == 1) + { + return 1; + } + else if (len1 == 2) + { + return poly2[0]; + } + else + { + return n_powmod2_ui_preinv(poly2[0], len1 - 1, mod.n, mod.ninv); + } + } + else /* len1 >= len2 >= 2 */ + { + mp_limb_t res = 1; + + mp_ptr u, v, r, t, w; + slong l0, l1, l2; + mp_limb_t lc; + + w = _nmod_vec_init(3 * len1); + u = w; + v = w + len1; + r = v + len1; + + _nmod_vec_set(u, poly1, len1); + _nmod_vec_set(v, poly2, len2); + l1 = len1; + l2 = len2; + + do + { + l0 = l1; + l1 = l2; + lc = v[l1 - 1]; + + _nmod_poly_rem(r, u, l0, v, l1, mod); + l2 = l1 - 1; + MPN_NORM(r, l2); + { + t = u; + u = v; + v = r; + r = t; + } + + if (l2 >= 1) + { + lc = n_powmod2_preinv(lc, l0 - l2, mod.n, mod.ninv); + res = n_mulmod2_preinv(res, lc, mod.n, mod.ninv); + + if (((l0 | l1) & 1) == 0) + { + res = nmod_neg(res, mod); + } + } + else + { + if (l1 == 1) + { + lc = n_powmod2_preinv(lc, l0 - 1, mod.n, mod.ninv); + res = n_mulmod2_preinv(res, lc, mod.n, mod.ninv); + } + else + { + res = 0; + } + } + } + while (l2 > 0); + + _nmod_vec_clear(w); + + return res; + } +} + +mp_limb_t +nmod_poly_resultant_euclidean(const nmod_poly_t f, const nmod_poly_t g) +{ + const slong len1 = f->length; + const slong len2 = g->length; + mp_limb_t r; + + if (len1 == 0 || len2 == 0) + { + r = 0; + } + else + { + if (len1 >= len2) + { + r = _nmod_poly_resultant_euclidean(f->coeffs, len1, + g->coeffs, len2, f->mod); + } + else + { + r = _nmod_poly_resultant_euclidean(g->coeffs, len2, + f->coeffs, len1, f->mod); + + if (((len1 | len2) & WORD(1)) == WORD(0)) + r = nmod_neg(r, f->mod); + } + } + + return r; +} + diff --git a/external/flint-2.4.3/nmod_poly/reverse.c b/external/flint-2.4.3/nmod_poly/reverse.c new file mode 100644 index 0000000..945f0b5 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/reverse.c @@ -0,0 +1,66 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "nmod_poly.h" + +void _nmod_poly_reverse(mp_ptr output, mp_srcptr input, slong len, slong m) +{ + slong i, min; + mp_limb_t temp; + + if (input != output) + { + min = FLINT_MIN(m, len); + + for (i = 0; i < min; i++) + output[m - i - 1] = input[i]; + + for ( ; i < m; i++) + output[m - i - 1] = WORD(0); + } else + { + for (i = 0; i < m/2; i++) + { + temp = i < len ? input[i] : 0; + + output[i] = m - i - 1 < len ? input[m - i - 1] : 0; + + output[m - i - 1] = temp; + } + if (m & 1 && i >= len) output[i] = 0; + } +} + +void nmod_poly_reverse(nmod_poly_t output, const nmod_poly_t input, slong m) +{ + nmod_poly_fit_length(output, m); + + _nmod_poly_reverse(output->coeffs, input->coeffs, input->length, m); + + output->length = m; + _nmod_poly_normalise(output); +} diff --git a/external/flint-2.4.3/nmod_poly/revert_series.c b/external/flint-2.4.3/nmod_poly/revert_series.c new file mode 100644 index 0000000..47c873d --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/revert_series.c @@ -0,0 +1,91 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + + +void +_nmod_poly_revert_series(mp_ptr Qinv, mp_srcptr Q, slong n, nmod_t mod) +{ + _nmod_poly_revert_series_lagrange_fast(Qinv, Q, n, mod); +} + +void +nmod_poly_revert_series(nmod_poly_t Qinv, + const nmod_poly_t Q, slong n) +{ + mp_ptr Qinv_coeffs, Q_coeffs; + nmod_poly_t t1; + slong Qlen; + + Qlen = Q->length; + + if (Qlen < 2 || Q->coeffs[0] != 0 || Q->coeffs[1] == 0) + { + flint_printf("Exception (nmod_poly_revert_series). Input must have \n" + "zero constant and an invertible coefficient of x^1.\n"); + abort(); + } + + if (Qlen < n) + { + Q_coeffs = _nmod_vec_init(n); + flint_mpn_copyi(Q_coeffs, Q->coeffs, Qlen); + flint_mpn_zero(Q_coeffs + Qlen, n - Qlen); + } + else + Q_coeffs = Q->coeffs; + + if (Q == Qinv && Qlen >= n) + { + nmod_poly_init2(t1, Q->mod.n, n); + Qinv_coeffs = t1->coeffs; + } + else + { + nmod_poly_fit_length(Qinv, n); + Qinv_coeffs = Qinv->coeffs; + } + + _nmod_poly_revert_series(Qinv_coeffs, Q_coeffs, n, Q->mod); + + if (Q == Qinv && Qlen >= n) + { + nmod_poly_swap(Qinv, t1); + nmod_poly_clear(t1); + } + + Qinv->length = n; + + if (Qlen < n) + _nmod_vec_clear(Q_coeffs); + + _nmod_poly_normalise(Qinv); +} diff --git a/external/flint-2.4.3/nmod_poly/revert_series_lagrange.c b/external/flint-2.4.3/nmod_poly/revert_series_lagrange.c new file mode 100644 index 0000000..cb6408d --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/revert_series_lagrange.c @@ -0,0 +1,114 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +void +_nmod_poly_revert_series_lagrange(mp_ptr Qinv, mp_srcptr Q, slong n, nmod_t mod) +{ + slong i; + mp_ptr R, S, T, tmp; + + if (n >= 1) Qinv[0] = UWORD(0); + if (n >= 2) Qinv[1] = n_invmod(Q[1], mod.n); + if (n <= 2) + return; + + R = _nmod_vec_init(n - 1); + S = _nmod_vec_init(n - 1); + T = _nmod_vec_init(n - 1); + + _nmod_poly_inv_series(R, Q + 1, n - 1, mod); + _nmod_vec_set(S, R, n - 1); + + for (i = 2; i < n; i++) + { + _nmod_poly_mullow(T, S, n - 1, R, n - 1, n - 1, mod); + Qinv[i] = nmod_div(T[i - 1], i, mod); + tmp = S; S = T; T = tmp; + } + + _nmod_vec_clear(R); + _nmod_vec_clear(S); + _nmod_vec_clear(T); +} + +void +nmod_poly_revert_series_lagrange(nmod_poly_t Qinv, + const nmod_poly_t Q, slong n) +{ + mp_ptr Qinv_coeffs, Q_coeffs; + nmod_poly_t t1; + slong Qlen; + + Qlen = Q->length; + + if (Qlen < 2 || Q->coeffs[0] != 0 || Q->coeffs[1] == 0) + { + flint_printf("Exception (nmod_poly_revert_series_lagrange). Input must \n" + "have zero constant and an invertible coefficient of x^1.\n"); + abort(); + } + + if (Qlen < n) + { + Q_coeffs = _nmod_vec_init(n); + flint_mpn_copyi(Q_coeffs, Q->coeffs, Qlen); + flint_mpn_zero(Q_coeffs + Qlen, n - Qlen); + } + else + Q_coeffs = Q->coeffs; + + if (Q == Qinv && Qlen >= n) + { + nmod_poly_init2(t1, Q->mod.n, n); + Qinv_coeffs = t1->coeffs; + } + else + { + nmod_poly_fit_length(Qinv, n); + Qinv_coeffs = Qinv->coeffs; + } + + _nmod_poly_revert_series_lagrange(Qinv_coeffs, Q_coeffs, n, Q->mod); + + if (Q == Qinv && Qlen >= n) + { + nmod_poly_swap(Qinv, t1); + nmod_poly_clear(t1); + } + + Qinv->length = n; + + if (Qlen < n) + _nmod_vec_clear(Q_coeffs); + + _nmod_poly_normalise(Qinv); +} diff --git a/external/flint-2.4.3/nmod_poly/revert_series_lagrange_fast.c b/external/flint-2.4.3/nmod_poly/revert_series_lagrange_fast.c new file mode 100644 index 0000000..877a3be --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/revert_series_lagrange_fast.c @@ -0,0 +1,137 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + + +/* pointer to (x/Q)^i */ +#define Ri(ii) (R + (n-1)*((ii)-1)) + +void +_nmod_poly_revert_series_lagrange_fast(mp_ptr Qinv, + mp_srcptr Q, slong n, nmod_t mod) +{ + slong i, j, k, m; + mp_ptr R, S, T, tmp; + + if (n >= 1) Qinv[0] = UWORD(0); + if (n >= 2) Qinv[1] = n_invmod(Q[1], mod.n); + if (n <= 2) + return; + + m = n_sqrt(n); + + R = _nmod_vec_init((n - 1) * m); + S = _nmod_vec_init(n - 1); + T = _nmod_vec_init(n - 1); + + _nmod_poly_inv_series(Ri(1), Q + 1, n - 1, mod); + for (i = 2; i <= m; i++) + _nmod_poly_mullow(Ri(i), Ri(i-1), n - 1, Ri(1), n - 1, n - 1, mod); + for (i = 2; i < m; i++) + Qinv[i] = nmod_div(Ri(i)[i-1], i, mod); + + _nmod_vec_set(S, Ri(m), n - 1); + + for (i = m; i < n; i += m) + { + Qinv[i] = nmod_div(S[i-1], i, mod); + for (j = 1; j < m && i + j < n; j++) + { + mp_limb_t s; + int nlimbs = _nmod_vec_dot_bound_limbs(i + j, mod); + NMOD_VEC_DOT(s, k, i + j, S[k], Ri(j)[i+j-1-k], mod, nlimbs); + Qinv[i+j] = nmod_div(s, i+j, mod); + } + + if (i + 1 < n) + { + _nmod_poly_mullow(T, S, n - 1, Ri(m), n - 1, n - 1, mod); + tmp = S; S = T; T = tmp; + } + } + + _nmod_vec_clear(R); + _nmod_vec_clear(S); + _nmod_vec_clear(T); +} + +void +nmod_poly_revert_series_lagrange_fast(nmod_poly_t Qinv, + const nmod_poly_t Q, slong n) +{ + mp_ptr Qinv_coeffs, Q_coeffs; + nmod_poly_t t1; + slong Qlen; + + Qlen = Q->length; + + if (Qlen < 2 || Q->coeffs[0] != 0 || Q->coeffs[1] == 0) + { + flint_printf("Exception (nmod_poly_revert_series_lagrange_fast). Input must \n" + "have zero constant and an invertible coefficient of x^1.\n"); + abort(); + } + + if (Qlen < n) + { + Q_coeffs = _nmod_vec_init(n); + flint_mpn_copyi(Q_coeffs, Q->coeffs, Qlen); + flint_mpn_zero(Q_coeffs + Qlen, n - Qlen); + } + else + Q_coeffs = Q->coeffs; + + if (Q == Qinv && Qlen >= n) + { + nmod_poly_init2(t1, Q->mod.n, n); + Qinv_coeffs = t1->coeffs; + } + else + { + nmod_poly_fit_length(Qinv, n); + Qinv_coeffs = Qinv->coeffs; + } + + _nmod_poly_revert_series_lagrange_fast(Qinv_coeffs, Q_coeffs, n, Q->mod); + + if (Q == Qinv && Qlen >= n) + { + nmod_poly_swap(Qinv, t1); + nmod_poly_clear(t1); + } + + Qinv->length = n; + + if (Qlen < n) + _nmod_vec_clear(Q_coeffs); + + _nmod_poly_normalise(Qinv); +} diff --git a/external/flint-2.4.3/nmod_poly/revert_series_newton.c b/external/flint-2.4.3/nmod_poly/revert_series_newton.c new file mode 100644 index 0000000..855ff77 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/revert_series_newton.c @@ -0,0 +1,129 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +#define FLINT_REVERSE_NEWTON_CUTOFF 15 + +void +_nmod_poly_revert_series_newton(mp_ptr Qinv, mp_srcptr Q, slong n, nmod_t mod) +{ + slong *a, i, k; + mp_ptr T, U, V; + + if (n >= 1) Qinv[0] = UWORD(0); + if (n >= 2) Qinv[1] = n_invmod(Q[1], mod.n); + if (n <= 2) + return; + + T = _nmod_vec_init(n); + U = _nmod_vec_init(n); + V = _nmod_vec_init(n); + + k = n; + for (i = 1; (WORD(1) << i) < k; i++); + a = (slong *) flint_malloc(i * sizeof(slong)); + a[i = 0] = k; + while (k >= FLINT_REVERSE_NEWTON_CUTOFF) + a[++i] = (k = (k + 1) / 2); + + _nmod_poly_revert_series_lagrange(Qinv, Q, k, mod); + _nmod_vec_zero(Qinv + k, n - k); + + for (i--; i >= 0; i--) + { + k = a[i]; + _nmod_poly_compose_series(T, Q, k, Qinv, k, k, mod); + _nmod_poly_derivative(U, T, k, mod); U[k - 1] = UWORD(0); + T[1] = UWORD(0); + _nmod_poly_div_series(V, T, U, k, mod); + _nmod_poly_derivative(T, Qinv, k, mod); + _nmod_poly_mullow(U, V, k, T, k, k, mod); + _nmod_vec_sub(Qinv, Qinv, U, k, mod); + } + + flint_free(a); + _nmod_vec_clear(T); + _nmod_vec_clear(U); + _nmod_vec_clear(V); +} + +void +nmod_poly_revert_series_newton(nmod_poly_t Qinv, + const nmod_poly_t Q, slong n) +{ + mp_ptr Qinv_coeffs, Q_coeffs; + nmod_poly_t t1; + slong Qlen; + + Qlen = Q->length; + + if (Qlen < 2 || Q->coeffs[0] != 0 || Q->coeffs[1] == 0) + { + flint_printf("Exception (nmod_poly_revert_series_newton). Input must have \n" + "zero constant and an invertible coefficient of x^1.\n"); + abort(); + } + + if (Qlen < n) + { + Q_coeffs = _nmod_vec_init(n); + flint_mpn_copyi(Q_coeffs, Q->coeffs, Qlen); + flint_mpn_zero(Q_coeffs + Qlen, n - Qlen); + } + else + Q_coeffs = Q->coeffs; + + if (Q == Qinv && Qlen >= n) + { + nmod_poly_init2(t1, Q->mod.n, n); + Qinv_coeffs = t1->coeffs; + } + else + { + nmod_poly_fit_length(Qinv, n); + Qinv_coeffs = Qinv->coeffs; + } + + _nmod_poly_revert_series_newton(Qinv_coeffs, Q_coeffs, n, Q->mod); + + if (Q == Qinv && Qlen >= n) + { + nmod_poly_swap(Qinv, t1); + nmod_poly_clear(t1); + } + + Qinv->length = n; + + if (Qlen < n) + _nmod_vec_clear(Q_coeffs); + + _nmod_poly_normalise(Qinv); +} diff --git a/external/flint-2.4.3/nmod_poly/scalar_mul_nmod.c b/external/flint-2.4.3/nmod_poly/scalar_mul_nmod.c new file mode 100644 index 0000000..8c4edc4 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/scalar_mul_nmod.c @@ -0,0 +1,48 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +void +nmod_poly_scalar_mul_nmod(nmod_poly_t res, const nmod_poly_t poly1, mp_limb_t c) +{ + if ((poly1->length == 0) || (c == 0)) + { + nmod_poly_zero(res); + return; + } + + nmod_poly_fit_length(res, poly1->length); + + _nmod_vec_scalar_mul_nmod(res->coeffs, poly1->coeffs, poly1->length, + c, poly1->mod); + + res->length = poly1->length; + _nmod_poly_normalise(res); /* there may have been cancellation */ +} diff --git a/external/flint-2.4.3/nmod_poly/set_coeff_ui.c b/external/flint-2.4.3/nmod_poly/set_coeff_ui.c new file mode 100644 index 0000000..68c941e --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/set_coeff_ui.c @@ -0,0 +1,61 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007, David Howden. + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +void nmod_poly_set_coeff_ui(nmod_poly_t poly, slong j, ulong c) +{ + if (c >= poly->mod.n) + NMOD_RED(c, c, poly->mod); + + nmod_poly_fit_length(poly, j + 1); + + if (j + 1 < poly->length) /* interior */ + poly->coeffs[j] = c; + else if (j + 1 == poly->length) /* leadiung coeff */ + { + if (c != 0) + poly->coeffs[j] = c; + else + { + poly->length--; + _nmod_poly_normalise(poly); + } + } else /* extend polynomial */ + { + if (c == 0) return; + else + { + flint_mpn_zero(poly->coeffs + poly->length, j - poly->length); + + poly->coeffs[j] = c; + poly->length = j + 1; + } + } +} diff --git a/external/flint-2.4.3/nmod_poly/set_str.c b/external/flint-2.4.3/nmod_poly/set_str.c new file mode 100644 index 0000000..982ea91 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/set_str.c @@ -0,0 +1,64 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007, David Howden. + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" + +int nmod_poly_set_str(nmod_poly_t poly, const char * s) +{ + const char * whitespace = " \t\n\r"; + slong i, length; + mp_limb_t n; + + if (flint_sscanf(s, "%wd %wu", &length, &n) != 2) + return 0; + + /* jump past length (n will be skipped in first loop iter) */ + s += strcspn(s, whitespace); + s += strspn(s, whitespace); + + nmod_poly_fit_length(poly, length); + poly->length = length; + + for (i = 0; i < length; i++) + { + s += strcspn(s, whitespace); /* jump to next whitespace */ + s += strspn(s, whitespace); /* skip whitespace */ + + if (!flint_sscanf(s, "%wu", &poly->coeffs[i])) + { + poly->length = i; + return 0; + } + } + + _nmod_poly_normalise(poly); + + return 1; +} diff --git a/external/flint-2.4.3/nmod_poly/shift_left.c b/external/flint-2.4.3/nmod_poly/shift_left.c new file mode 100644 index 0000000..b32fd07 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/shift_left.c @@ -0,0 +1,45 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +void _nmod_poly_shift_left(mp_ptr res, mp_srcptr poly, slong len, slong k) +{ + flint_mpn_copyd(res + k, poly, len); + flint_mpn_zero(res, k); +} + +void nmod_poly_shift_left(nmod_poly_t res, const nmod_poly_t poly, slong k) +{ + nmod_poly_fit_length(res, poly->length + k); + + _nmod_poly_shift_left(res->coeffs, poly->coeffs, poly->length, k); + + res->length = poly->length + k; +} + diff --git a/external/flint-2.4.3/nmod_poly/shift_right.c b/external/flint-2.4.3/nmod_poly/shift_right.c new file mode 100644 index 0000000..143ba9a --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/shift_right.c @@ -0,0 +1,49 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +void _nmod_poly_shift_right(mp_ptr res, mp_srcptr poly, slong len, slong k) +{ + flint_mpn_copyi(res, poly + k, len); +} + +void nmod_poly_shift_right(nmod_poly_t res, const nmod_poly_t poly, slong k) +{ + if (k >= poly->length) /* shift all coeffs out */ + res->length = 0; + else + { + const slong len = poly->length - k; + nmod_poly_fit_length(res, len); + + _nmod_poly_shift_right(res->coeffs, poly->coeffs, len, k); + + res->length = len; + } +} diff --git a/external/flint-2.4.3/nmod_poly/sin_series.c b/external/flint-2.4.3/nmod_poly/sin_series.c new file mode 100644 index 0000000..debeaa5 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/sin_series.c @@ -0,0 +1,87 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +void +_nmod_poly_sin_series(mp_ptr g, mp_srcptr h, slong n, nmod_t mod) +{ + mp_ptr t, u; + + t = _nmod_vec_init(n); + u = _nmod_vec_init(n); + + /* sin(x) = 2*tan(x/2)/(1+tan(x/2)^2) */ + _nmod_vec_scalar_mul_nmod(u, h, n, n_invmod(UWORD(2), mod.n), mod); + _nmod_poly_tan_series(t, u, n, mod); + _nmod_poly_mullow(u, t, n, t, n, n, mod); u[0] = UWORD(1); + _nmod_poly_div_series(g, t, u, n, mod); + _nmod_vec_add(g, g, g, n, mod); + + _nmod_vec_clear(t); + _nmod_vec_clear(u); +} + +void +nmod_poly_sin_series(nmod_poly_t g, const nmod_poly_t h, slong n) +{ + mp_ptr h_coeffs; + slong h_len = h->length; + + if (h_len > 0 && h->coeffs[0] != UWORD(0)) + { + flint_printf("Exception (nmod_poly_sin_series). Constant term != 0.\n"); + abort(); + } + + if (h_len == 1 || n < 2) + { + nmod_poly_zero(g); + return; + } + + nmod_poly_fit_length(g, n); + + if (h_len < n) + { + h_coeffs = _nmod_vec_init(n); + flint_mpn_copyi(h_coeffs, h->coeffs, h_len); + flint_mpn_zero(h_coeffs + h_len, n - h_len); + } + else + h_coeffs = h->coeffs; + + _nmod_poly_sin_series(g->coeffs, h_coeffs, n, h->mod); + + if (h_len < n) + _nmod_vec_clear(h_coeffs); + + g->length = n; + _nmod_poly_normalise(g); +} diff --git a/external/flint-2.4.3/nmod_poly/sinh_series.c b/external/flint-2.4.3/nmod_poly/sinh_series.c new file mode 100644 index 0000000..0959f0c --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/sinh_series.c @@ -0,0 +1,97 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +void +_nmod_poly_sinh_series(mp_ptr f, mp_srcptr h, slong n, nmod_t mod) +{ + mp_ptr g = _nmod_vec_init(n); + _nmod_poly_exp_expinv_series(f, g, h, n, mod); + _nmod_vec_sub(f, f, g, n, mod); + _nmod_vec_scalar_mul_nmod(f, f, n, n_invmod(UWORD(2), mod.n), mod); + _nmod_vec_clear(g); +} + +void +nmod_poly_sinh_series(nmod_poly_t g, const nmod_poly_t h, slong n) +{ + mp_ptr g_coeffs, h_coeffs; + nmod_poly_t t1; + slong h_len; + + h_len = h->length; + + if (h_len > 0 && h->coeffs[0] != UWORD(0)) + { + flint_printf("Exception (nmod_poly_sinh_series). Constant term != 0.\n"); + abort(); + } + + if (h_len == 1 || n < 2) + { + nmod_poly_zero(g); + return; + } + + if (h_len < n) + { + h_coeffs = _nmod_vec_init(n); + flint_mpn_copyi(h_coeffs, h->coeffs, h_len); + flint_mpn_zero(h_coeffs + h_len, n - h_len); + } + else + h_coeffs = h->coeffs; + + if (h == g && h_len >= n) + { + nmod_poly_init2(t1, h->mod.n, n); + g_coeffs = t1->coeffs; + } + else + { + nmod_poly_fit_length(g, n); + g_coeffs = g->coeffs; + } + + _nmod_poly_sinh_series(g_coeffs, h_coeffs, n, h->mod); + + if (h == g && h_len >= n) + { + nmod_poly_swap(g, t1); + nmod_poly_clear(t1); + } + + g->length = n; + + if (h_len < n) + _nmod_vec_clear(h_coeffs); + + _nmod_poly_normalise(g); +} diff --git a/external/flint-2.4.3/nmod_poly/sqrt.c b/external/flint-2.4.3/nmod_poly/sqrt.c new file mode 100644 index 0000000..124c9e4 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/sqrt.c @@ -0,0 +1,136 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 "flint.h" +#include "nmod_poly.h" + +static __inline__ +int _nmod_poly_sqrt_2(mp_ptr s, mp_srcptr p, slong len) +{ + slong i; + + for (i = 1; i < len; i += 2) + if (p[i] != 0) + return 0; + + for (i = 0; i < len; i += 2) + s[i / 2] = p[i]; + + return 1; +} + +int +_nmod_poly_sqrt(mp_ptr s, mp_srcptr p, slong len, nmod_t mod) +{ + slong slen; + int result; + mp_ptr t; + mp_limb_t c, d; + + if (len % 2 == 0) + return len == 0; + + if (mod.n == 2) + return _nmod_poly_sqrt_2(s, p, len); + + /* valuation must be even, and then can be reduced to 0 */ + while (p[0] == 0) + { + if (p[1] != 0) + return 0; + + s[0] = 0; + p += 2; + len -= 2; + s++; + } + + c = d = p[0]; + if (c != 1) + { + c = n_sqrtmod(c, mod.n); + if (c == 0) + return 0; + } + + if (len == 1) + { + s[0] = c; + return 1; + } + + slen = len / 2 + 1; + + t = _nmod_vec_init(len); + + if (c == 1) + _nmod_poly_sqrt_series(s, p, slen, mod); + else + { + _nmod_vec_scalar_mul_nmod(t, p, slen, n_invmod(d, mod.n), mod); + _nmod_poly_sqrt_series(s, t, slen, mod); + } + + if (c != 1) + _nmod_vec_scalar_mul_nmod(s, s, slen, c, mod); + + _nmod_poly_mulhigh(t, s, slen, s, slen, slen, mod); + + + result = _nmod_vec_equal(t + slen, p + slen, len - slen); + _nmod_vec_clear(t); + return result; +} + +int +nmod_poly_sqrt(nmod_poly_t b, const nmod_poly_t a) +{ + slong blen, len = a->length; + int result; + + if (len % 2 == 0) + { + nmod_poly_zero(b); + return len == 0; + } + + if (b == a) + { + nmod_poly_t tmp; + nmod_poly_init_preinv(tmp, a->mod.n, a->mod.ninv); + result = nmod_poly_sqrt(tmp, a); + nmod_poly_swap(b, tmp); + nmod_poly_clear(tmp); + return result; + } + + blen = len / 2 + 1; + nmod_poly_fit_length(b, blen); + b->length = blen; + result = _nmod_poly_sqrt(b->coeffs, a->coeffs, len, a->mod); + if (!result) + b->length = 0; + return result; +} diff --git a/external/flint-2.4.3/nmod_poly/sqrt_series.c b/external/flint-2.4.3/nmod_poly/sqrt_series.c new file mode 100644 index 0000000..ed60060 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/sqrt_series.c @@ -0,0 +1,99 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + + +void +_nmod_poly_sqrt_series(mp_ptr g, mp_srcptr h, slong n, nmod_t mod) +{ + mp_ptr t = _nmod_vec_init(n); + _nmod_poly_invsqrt_series(t, h, n, mod); + _nmod_poly_mullow(g, t, n, h, n, n, mod); + _nmod_vec_clear(t); +} + +void +nmod_poly_sqrt_series(nmod_poly_t g, const nmod_poly_t h, slong n) +{ + mp_ptr g_coeffs, h_coeffs; + nmod_poly_t t1; + slong hlen; + + hlen = h->length; + + if (n == 0) + { + flint_printf("Exception (nmod_poly_sqrt_series). Division by zero.\n"); + abort(); + } + + if (h->length == 0 || h->coeffs[0] != UWORD(1)) + { + flint_printf("Exception (nmod_poly_sqrt_series). Requires constant term 1.\n"); + abort(); + } + + if (hlen < n) + { + h_coeffs = _nmod_vec_init(n); + flint_mpn_copyi(h_coeffs, h->coeffs, hlen); + flint_mpn_zero(h_coeffs + hlen, n - hlen); + } + else + h_coeffs = h->coeffs; + + if (h == g && hlen >= n) + { + nmod_poly_init2(t1, h->mod.n, n); + g_coeffs = t1->coeffs; + } + else + { + nmod_poly_fit_length(g, n); + g_coeffs = g->coeffs; + } + + _nmod_poly_sqrt_series(g_coeffs, h_coeffs, n, h->mod); + + if (h == g && hlen >= n) + { + nmod_poly_swap(g, t1); + nmod_poly_clear(t1); + } + + g->length = n; + + if (hlen < n) + _nmod_vec_clear(h_coeffs); + + _nmod_poly_normalise(g); +} diff --git a/external/flint-2.4.3/nmod_poly/sub.c b/external/flint-2.4.3/nmod_poly/sub.c new file mode 100644 index 0000000..dbfa7bb --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/sub.c @@ -0,0 +1,66 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007, David Howden. + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +void +_nmod_poly_sub(mp_ptr res, mp_srcptr poly1, slong len1, mp_srcptr poly2, + slong len2, nmod_t mod) +{ + slong i, min = FLINT_MIN(len1, len2); + + _nmod_vec_sub(res, poly1, poly2, min, mod); + + if (poly1 != res) /* Copy any remaining coefficients from poly1 */ + for (i = min; i < len1; i++) + res[i] = poly1[i]; + + /* + Careful, it is *always* necessary to negate coeffs from poly2, + even if this is already res. + */ + for (i = min; i < len2; i++) + res[i] = nmod_neg(poly2[i], mod); +} + +void +nmod_poly_sub(nmod_poly_t res, const nmod_poly_t poly1, + const nmod_poly_t poly2) +{ + slong max = FLINT_MAX(poly1->length, poly2->length); + + nmod_poly_fit_length(res, max); + + _nmod_poly_sub(res->coeffs, poly1->coeffs, poly1->length, poly2->coeffs, + poly2->length, poly1->mod); + + res->length = max; + _nmod_poly_normalise(res); /* there may have been cancellation */ +} diff --git a/external/flint-2.4.3/nmod_poly/tan_series.c b/external/flint-2.4.3/nmod_poly/tan_series.c new file mode 100644 index 0000000..79e4674 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/tan_series.c @@ -0,0 +1,122 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + + +void +_nmod_poly_tan_series(mp_ptr g, mp_srcptr h, slong n, nmod_t mod) +{ + slong m; + mp_ptr t, u; + + if (n <= 3) + { + g[0] = UWORD(0); + if (n >= 2) g[1] = h[1]; + if (n >= 3) g[2] = h[2]; + return; + } + + m = (n + 1) / 2; + + _nmod_poly_tan_series(g, h, m, mod); + _nmod_vec_zero(g + m, n - m); + + t = _nmod_vec_init(n); + u = _nmod_vec_init(n); + + _nmod_poly_mul(u, g, m, g, m, mod); + u[0] = UWORD(1); + if (2*m - 1 < n) u[n-1] = UWORD(0); + + _nmod_poly_atan_series(t, g, n, mod); + _nmod_vec_sub(t + m, h + m, t + m, n - m, mod); + _nmod_poly_mullow(g + m, u, n, t + m, n - m, n - m, mod); + + _nmod_vec_clear(t); + _nmod_vec_clear(u); +} + +void +nmod_poly_tan_series(nmod_poly_t g, const nmod_poly_t h, slong n) +{ + mp_ptr g_coeffs, h_coeffs; + nmod_poly_t t1; + slong h_len; + + h_len = h->length; + + if (h_len > 0 && h->coeffs[0] != UWORD(0)) + { + flint_printf("Exception (nmod_poly_tan_series). Constant term != 0.\n"); + abort(); + } + + if (h_len == 1 || n < 2) + { + nmod_poly_zero(g); + return; + } + + if (h_len < n) + { + h_coeffs = _nmod_vec_init(n); + flint_mpn_copyi(h_coeffs, h->coeffs, h_len); + flint_mpn_zero(h_coeffs + h_len, n - h_len); + } + else + h_coeffs = h->coeffs; + + if (h == g && h_len >= n) + { + nmod_poly_init2(t1, h->mod.n, n); + g_coeffs = t1->coeffs; + } + else + { + nmod_poly_fit_length(g, n); + g_coeffs = g->coeffs; + } + + _nmod_poly_tan_series(g_coeffs, h_coeffs, n, h->mod); + + if (h == g && h_len >= n) + { + nmod_poly_swap(g, t1); + nmod_poly_clear(t1); + } + + g->length = n; + + if (h_len < n) + _nmod_vec_clear(h_coeffs); + + _nmod_poly_normalise(g); +} diff --git a/external/flint-2.4.3/nmod_poly/tanh_series.c b/external/flint-2.4.3/nmod_poly/tanh_series.c new file mode 100644 index 0000000..362d4e0 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/tanh_series.c @@ -0,0 +1,87 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +void +_nmod_poly_tanh_series(mp_ptr f, mp_srcptr h, slong n, nmod_t mod) +{ + mp_ptr t, u; + + t = _nmod_vec_init(n); + u = _nmod_vec_init(n); + + _nmod_vec_add(t, h, h, n, mod); + _nmod_poly_exp_series(u, t, n, mod); + _nmod_vec_set(t, u, n); + t[0] = UWORD(0); + u[0] = UWORD(2); + _nmod_poly_div_series(f, t, u, n, mod); + + _nmod_vec_clear(t); + _nmod_vec_clear(u); +} + +void +nmod_poly_tanh_series(nmod_poly_t g, const nmod_poly_t h, slong n) +{ + mp_ptr h_coeffs; + slong h_len = h->length; + + if (h_len > 0 && h->coeffs[0] != UWORD(0)) + { + flint_printf("Exception (nmod_poly_tanh_series). Constant term != 0.\n"); + abort(); + } + + if (h_len == 1 || n < 2) + { + nmod_poly_zero(g); + return; + } + + nmod_poly_fit_length(g, n); + + if (h_len < n) + { + h_coeffs = _nmod_vec_init(n); + flint_mpn_copyi(h_coeffs, h->coeffs, h_len); + flint_mpn_zero(h_coeffs + h_len, n - h_len); + } + else + h_coeffs = h->coeffs; + + _nmod_poly_tanh_series(g->coeffs, h_coeffs, n, h->mod); + + if (h_len < n) + _nmod_vec_clear(h_coeffs); + + g->length = n; + _nmod_poly_normalise(g); +} diff --git a/external/flint-2.4.3/nmod_poly/taylor_shift.c b/external/flint-2.4.3/nmod_poly/taylor_shift.c new file mode 100644 index 0000000..9abd3a5 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/taylor_shift.c @@ -0,0 +1,47 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 "flint.h" +#include "nmod_poly.h" + +void +_nmod_poly_taylor_shift(mp_ptr poly, mp_limb_t c, slong len, nmod_t mod) +{ + if (len < 100 || len > mod.n) + _nmod_poly_taylor_shift_horner(poly, c, len, mod); + else if ((c == 1 || c == mod.n - 1) && len < 1000) + _nmod_poly_taylor_shift_horner(poly, c, len, mod); + else + _nmod_poly_taylor_shift_convolution(poly, c, len, mod); +} + +void +nmod_poly_taylor_shift(nmod_poly_t g, const nmod_poly_t f, mp_limb_t c) +{ + if (f != g) + nmod_poly_set(g, f); + + _nmod_poly_taylor_shift(g->coeffs, c, g->length, g->mod); +} diff --git a/external/flint-2.4.3/nmod_poly/taylor_shift_convolution.c b/external/flint-2.4.3/nmod_poly/taylor_shift_convolution.c new file mode 100644 index 0000000..eb9192f --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/taylor_shift_convolution.c @@ -0,0 +1,96 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +void +_nmod_poly_taylor_shift_convolution(mp_ptr p, mp_limb_t c, slong len, nmod_t mod) +{ + slong i, n = len - 1; + mp_limb_t f, d; + mp_ptr t, u; + + if (c == 0 || len <= 1) + return; + + t = _nmod_vec_init(len); + u = _nmod_vec_init(len); + + f = 1; + for (i = 2; i <= n; i++) + { + f = n_mulmod2_preinv(f, i, mod.n, mod.ninv); + p[i] = n_mulmod2_preinv(p[i], f, mod.n, mod.ninv); + } + + _nmod_poly_reverse(p, p, len, len); + + t[n] = 1; + for (i = n; i > 0; i--) + t[i - 1] = n_mulmod2_preinv(t[i], i, mod.n, mod.ninv); + + if (c == mod.n - 1) + { + for (i = 1; i <= n; i += 2) + t[i] = nmod_neg(t[i], mod); + } + else if (c != 1) + { + d = c; + + for (i = 1; i <= n; i++) + { + t[i] = n_mulmod2_preinv(t[i], d, mod.n, mod.ninv); + d = n_mulmod2_preinv(d, c, mod.n, mod.ninv); + } + } + + _nmod_poly_mullow(u, p, len, t, len, len, mod); + + f = n_mulmod2_preinv(f, f, mod.n, mod.ninv); + f = n_invmod(f, mod.n); + + for (i = n; i >= 0; i--) + { + p[i] = n_mulmod2_preinv(u[n - i], f, mod.n, mod.ninv); + f = n_mulmod2_preinv(f, (i == 0) ? 1 : i, mod.n, mod.ninv); + } + + _nmod_vec_clear(t); + _nmod_vec_clear(u); +} + +void +nmod_poly_taylor_shift_convolution(nmod_poly_t g, const nmod_poly_t f, + mp_limb_t c) +{ + if (f != g) + nmod_poly_set(g, f); + + _nmod_poly_taylor_shift_convolution(g->coeffs, c, g->length, g->mod); +} diff --git a/external/flint-2.4.3/nmod_poly/taylor_shift_horner.c b/external/flint-2.4.3/nmod_poly/taylor_shift_horner.c new file mode 100644 index 0000000..ab1cbf2 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/taylor_shift_horner.c @@ -0,0 +1,61 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 "flint.h" +#include "nmod_poly.h" + +void +_nmod_poly_taylor_shift_horner(mp_ptr poly, mp_limb_t c, slong n, nmod_t mod) +{ + slong i, j; + + if (c == 1) + { + for (i = n - 2; i >= 0; i--) + for (j = i; j < n - 1; j++) + poly[j] = nmod_add(poly[j], poly[j + 1], mod); + } + else if (c == mod.n - 1) + { + for (i = n - 2; i >= 0; i--) + for (j = i; j < n - 1; j++) + poly[j] = nmod_sub(poly[j], poly[j + 1], mod); + } + else if (c != 0) + { + for (i = n - 2; i >= 0; i--) + for (j = i; j < n - 1; j++) + NMOD_ADDMUL(poly[j], poly[j + 1], c, mod); + } +} + +void +nmod_poly_taylor_shift_horner(nmod_poly_t g, const nmod_poly_t f, mp_limb_t c) +{ + if (f != g) + nmod_poly_set(g, f); + + _nmod_poly_taylor_shift_horner(g->coeffs, c, g->length, g->mod); +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-add.c b/external/flint-2.4.3/nmod_poly/test/t-add.c new file mode 100644 index 0000000..978137c --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-add.c @@ -0,0 +1,107 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("add...."); + fflush(stdout); + + /* Check aliasing of a and c */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c; + mp_limb_t n = n_randtest_not_zero(state); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(c, n); + nmod_poly_randtest(a, state, n_randint(state, 100)); + nmod_poly_randtest(b, state, n_randint(state, 100)); + + nmod_poly_add(c, a, b); + nmod_poly_add(a, a, b); + + result = (nmod_poly_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(c), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + } + + /* Check aliasing of b and c */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c; + mp_limb_t n = n_randtest_not_zero(state); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(c, n); + nmod_poly_randtest(a, state, n_randint(state, 100)); + nmod_poly_randtest(b, state, n_randint(state, 100)); + + nmod_poly_add(c, a, b); + nmod_poly_add(b, a, b); + + result = (nmod_poly_equal(b, c)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(c), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-asin_series.c b/external/flint-2.4.3/nmod_poly/test/t-asin_series.c new file mode 100644 index 0000000..d039efd --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-asin_series.c @@ -0,0 +1,126 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result = 1; + FLINT_TEST_INIT(state); + + + flint_printf("asin_series...."); + fflush(stdout); + + /* Check asin(A) = atan(A/sqrt(1-A^2)) */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t A, B, asinA, atanB; + slong n; + mp_limb_t mod; + + mod = n_randtest_prime(state, 0); + n = 1 + n_randtest(state) % 100; + n = FLINT_MIN(n, mod); + + nmod_poly_init(A, mod); + nmod_poly_init(B, mod); + nmod_poly_init(asinA, mod); + nmod_poly_init(atanB, mod); + + nmod_poly_randtest(A, state, n_randint(state, 100)); + nmod_poly_set_coeff_ui(A, 0, UWORD(0)); + + nmod_poly_mullow(B, A, A, n); + nmod_poly_neg(B, B); + nmod_poly_set_coeff_ui(B, 0, UWORD(1)); + nmod_poly_invsqrt_series(B, B, n); + nmod_poly_mullow(B, A, B, n); + + nmod_poly_asin_series(asinA, A, n); + nmod_poly_atan_series(atanB, B, n); + + result = nmod_poly_equal(asinA, atanB); + + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("n = %wd, mod = %wu\n", n, mod); + flint_printf("A: "); nmod_poly_print(A), flint_printf("\n\n"); + flint_printf("B: "); nmod_poly_print(B), flint_printf("\n\n"); + flint_printf("asin(A): "); nmod_poly_print(asinA), flint_printf("\n\n"); + flint_printf("atan(B): "); nmod_poly_print(atanB), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(A); + nmod_poly_clear(B); + nmod_poly_clear(asinA); + nmod_poly_clear(atanB); + } + + /* Check aliasing */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t A, B; + slong n; + mp_limb_t mod; + mod = n_randtest_prime(state, 0); + n = n_randtest(state) % 50; + n = FLINT_MIN(n, mod); + + nmod_poly_init(A, mod); + nmod_poly_init(B, mod); + nmod_poly_randtest(A, state, n_randint(state, 50)); + nmod_poly_set_coeff_ui(A, 0, UWORD(0)); + + nmod_poly_asin_series(B, A, n); + nmod_poly_asin_series(A, A, n); + + result = nmod_poly_equal(A, B); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(A), flint_printf("\n\n"); + nmod_poly_print(B), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(A); + nmod_poly_clear(B); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-asinh_series.c b/external/flint-2.4.3/nmod_poly/test/t-asinh_series.c new file mode 100644 index 0000000..fcbd0ae --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-asinh_series.c @@ -0,0 +1,125 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result = 1; + FLINT_TEST_INIT(state); + + + flint_printf("asinh_series...."); + fflush(stdout); + + /* Check asinh(A) = atanh(A/sqrt(1+A^2)) */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t A, B, asinhA, atanhB; + slong n; + mp_limb_t mod; + + mod = n_randtest_prime(state, 0); + n = 1 + n_randtest(state) % 100; + n = FLINT_MIN(n, mod); + + nmod_poly_init(A, mod); + nmod_poly_init(B, mod); + nmod_poly_init(asinhA, mod); + nmod_poly_init(atanhB, mod); + + nmod_poly_randtest(A, state, n_randint(state, 100)); + nmod_poly_set_coeff_ui(A, 0, UWORD(0)); + + nmod_poly_mullow(B, A, A, n); + nmod_poly_set_coeff_ui(B, 0, UWORD(1)); + nmod_poly_invsqrt_series(B, B, n); + nmod_poly_mullow(B, A, B, n); + + nmod_poly_asinh_series(asinhA, A, n); + nmod_poly_atanh_series(atanhB, B, n); + + result = nmod_poly_equal(asinhA, atanhB); + + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("n = %wd, mod = %wu\n", n, mod); + flint_printf("A: "); nmod_poly_print(A), flint_printf("\n\n"); + flint_printf("B: "); nmod_poly_print(B), flint_printf("\n\n"); + flint_printf("asinh(A): "); nmod_poly_print(asinhA), flint_printf("\n\n"); + flint_printf("atanh(B): "); nmod_poly_print(atanhB), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(A); + nmod_poly_clear(B); + nmod_poly_clear(asinhA); + nmod_poly_clear(atanhB); + } + + /* Check aliasing */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t A, B; + slong n; + mp_limb_t mod; + mod = n_randtest_prime(state, 0); + n = n_randtest(state) % 50; + n = FLINT_MIN(n, mod); + + nmod_poly_init(A, mod); + nmod_poly_init(B, mod); + nmod_poly_randtest(A, state, n_randint(state, 50)); + nmod_poly_set_coeff_ui(A, 0, UWORD(0)); + + nmod_poly_asinh_series(B, A, n); + nmod_poly_asinh_series(A, A, n); + + result = nmod_poly_equal(A, B); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(A), flint_printf("\n\n"); + nmod_poly_print(B), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(A); + nmod_poly_clear(B); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-atan_series.c b/external/flint-2.4.3/nmod_poly/test/t-atan_series.c new file mode 100644 index 0000000..79fc3f3 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-atan_series.c @@ -0,0 +1,127 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result = 1; + FLINT_TEST_INIT(state); + + + flint_printf("atan_series...."); + fflush(stdout); + + /* Check 2*atan(A) = atan(2*A/(1-A^2)) */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t A, B, atanA, atanB; + slong n; + mp_limb_t mod; + + mod = n_randtest_prime(state, 0); + n = 1 + n_randtest(state) % 100; + n = FLINT_MIN(n, mod); + + nmod_poly_init(A, mod); + nmod_poly_init(B, mod); + nmod_poly_init(atanA, mod); + nmod_poly_init(atanB, mod); + + nmod_poly_randtest(A, state, n_randint(state, 100)); + nmod_poly_set_coeff_ui(A, 0, UWORD(0)); + + nmod_poly_mullow(B, A, A, n); + nmod_poly_neg(B, B); + nmod_poly_set_coeff_ui(B, 0, UWORD(1)); + nmod_poly_div_series(B, A, B, n); + nmod_poly_add(B, B, B); + + nmod_poly_atan_series(atanA, A, n); + nmod_poly_atan_series(atanB, B, n); + nmod_poly_add(atanA, atanA, atanA); + + result = nmod_poly_equal(atanA, atanB); + + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("n = %wd, mod = %wu\n", n, mod); + flint_printf("A: "); nmod_poly_print(A), flint_printf("\n\n"); + flint_printf("B: "); nmod_poly_print(B), flint_printf("\n\n"); + flint_printf("2*atan(A): "); nmod_poly_print(atanA), flint_printf("\n\n"); + flint_printf("atan(B): "); nmod_poly_print(atanB), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(A); + nmod_poly_clear(B); + nmod_poly_clear(atanA); + nmod_poly_clear(atanB); + } + + /* Check aliasing */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t A, B; + slong n; + mp_limb_t mod; + mod = n_randtest_prime(state, 0); + n = n_randtest(state) % 50; + n = FLINT_MIN(n, mod); + + nmod_poly_init(A, mod); + nmod_poly_init(B, mod); + nmod_poly_randtest(A, state, n_randint(state, 50)); + nmod_poly_set_coeff_ui(A, 0, UWORD(0)); + + nmod_poly_atan_series(B, A, n); + nmod_poly_atan_series(A, A, n); + + result = nmod_poly_equal(A, B); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(A), flint_printf("\n\n"); + nmod_poly_print(B), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(A); + nmod_poly_clear(B); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-atanh_series.c b/external/flint-2.4.3/nmod_poly/test/t-atanh_series.c new file mode 100644 index 0000000..0264ae5 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-atanh_series.c @@ -0,0 +1,126 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result = 1; + FLINT_TEST_INIT(state); + + + flint_printf("atanh_series...."); + fflush(stdout); + + /* Check 2*atanh(A) = atanh(2*A/(1+A^2)) */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t A, B, atanhA, atanhB; + slong n; + mp_limb_t mod; + + mod = n_randtest_prime(state, 0); + n = 1 + n_randtest(state) % 100; + n = FLINT_MIN(n, mod); + + nmod_poly_init(A, mod); + nmod_poly_init(B, mod); + nmod_poly_init(atanhA, mod); + nmod_poly_init(atanhB, mod); + + nmod_poly_randtest(A, state, n_randint(state, 100)); + nmod_poly_set_coeff_ui(A, 0, UWORD(0)); + + nmod_poly_mullow(B, A, A, n); + nmod_poly_set_coeff_ui(B, 0, UWORD(1)); + nmod_poly_div_series(B, A, B, n); + nmod_poly_add(B, B, B); + + nmod_poly_atanh_series(atanhA, A, n); + nmod_poly_atanh_series(atanhB, B, n); + nmod_poly_add(atanhA, atanhA, atanhA); + + result = nmod_poly_equal(atanhA, atanhB); + + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("n = %wd, mod = %wu\n", n, mod); + flint_printf("A: "); nmod_poly_print(A), flint_printf("\n\n"); + flint_printf("B: "); nmod_poly_print(B), flint_printf("\n\n"); + flint_printf("2*atanh(A): "); nmod_poly_print(atanhA), flint_printf("\n\n"); + flint_printf("atanh(B): "); nmod_poly_print(atanhB), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(A); + nmod_poly_clear(B); + nmod_poly_clear(atanhA); + nmod_poly_clear(atanhB); + } + + /* Check aliasing */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t A, B; + slong n; + mp_limb_t mod; + mod = n_randtest_prime(state, 0); + n = n_randtest(state) % 50; + n = FLINT_MIN(n, mod); + + nmod_poly_init(A, mod); + nmod_poly_init(B, mod); + nmod_poly_randtest(A, state, n_randint(state, 50)); + nmod_poly_set_coeff_ui(A, 0, UWORD(0)); + + nmod_poly_atanh_series(B, A, n); + nmod_poly_atanh_series(A, A, n); + + result = nmod_poly_equal(A, B); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(A), flint_printf("\n\n"); + nmod_poly_print(B), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(A); + nmod_poly_clear(B); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-bit_pack.c b/external/flint-2.4.3/nmod_poly/test/t-bit_pack.c new file mode 100644 index 0000000..f58b6ac --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-bit_pack.c @@ -0,0 +1,137 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("bit_pack/bit_unpack...."); + fflush(stdout); + + /* Check aliasing of a and c */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b; + mp_limb_t n; + ulong bits; + mp_ptr mpn; + + do + { + n = n_randtest_not_zero(state); + } while (n == 1); + bits = 2 * FLINT_BIT_COUNT(n) + n_randint(state, FLINT_BITS); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + do + { + nmod_poly_randtest(a, state, n_randint(state, 100)); + } while (a->length == 0); + + mpn = + flint_malloc(sizeof(mp_limb_t) * + ((bits * a->length - 1) / FLINT_BITS + 1)); + + _nmod_poly_bit_pack(mpn, a->coeffs, a->length, bits); + nmod_poly_fit_length(b, a->length); + _nmod_poly_bit_unpack(b->coeffs, a->length, mpn, bits, a->mod); + b->length = a->length; + + result = (nmod_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + flint_free(mpn); + } + + for (i = 0; i < 2000 * flint_test_multiplier(); i++) + { + fmpz_t f; + nmod_poly_t A, B; + slong b; + mp_limb_t n; + + do + { + n = n_randtest_not_zero(state); + } while (n == 1); + + fmpz_init(f); + nmod_poly_init(A, n); + nmod_poly_init(B, n); + + nmod_poly_randtest(A, state, 1+n_randint(state,100)); + + b = FLINT_BIT_COUNT(n) + n_randint(state, FLINT_BITS); + + nmod_poly_bit_pack(f, A, b); + nmod_poly_bit_unpack(B, f, b); + + if (!nmod_poly_equal(A, B)) + { + mpz_t zz; + flint_printf("FAIL:\n"); + flint_printf("INPUT: "); + nmod_poly_print(A); + flint_printf("\n"); + mpz_init(zz); fmpz_get_mpz(zz, f); + flint_printf("PACKED: "); + mpz_out_str(stdout, 2, zz); + flint_printf("\n"); + flint_printf("OUTPUT: "); + nmod_poly_print(B); + flint_printf("\n\n"); + abort(); + } + + fmpz_clear(f); + nmod_poly_clear(A); + nmod_poly_clear(B); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-compose.c b/external/flint-2.4.3/nmod_poly/test/t-compose.c new file mode 100644 index 0000000..2c3be16 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-compose.c @@ -0,0 +1,183 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result = 1; + FLINT_TEST_INIT(state); + + + flint_printf("compose...."); + fflush(stdout); + + /* Check (f(x-1))(x+1) == f */ + for (i = 0; i < 500 * flint_test_multiplier(); i++) + { + nmod_poly_t a, r, xp1, xm1; + mp_limb_t n = n_randtest_not_zero(state); + + nmod_poly_init(a, n); + nmod_poly_init(r, n); + nmod_poly_init(xm1, n); + nmod_poly_init(xp1, n); + nmod_poly_randtest(a, state, n_randint(state, 100)); + + nmod_poly_set_coeff_ui(xm1, 1, 1); + nmod_poly_set_coeff_ui(xm1, 0, n - 1); + nmod_poly_set_coeff_ui(xp1, 1, 1); + nmod_poly_set_coeff_ui(xp1, 0, 1); + + nmod_poly_compose(r, a, xm1); + nmod_poly_compose(r, r, xp1); + + result = nmod_poly_equal(a, r); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a->length = %wd, n = %wu\n", a->length, a->mod.n); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(r), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(r); + nmod_poly_clear(xm1); + nmod_poly_clear(xp1); + } + + /* Check a(c) + b(c) = (a + b)(c) */ + for (i = 0; i < 500 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c, r1, r2; + mp_limb_t n = n_randtest_not_zero(state); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(c, n); + nmod_poly_init(r1, n); + nmod_poly_init(r2, n); + nmod_poly_randtest(a, state, n_randint(state, 30)); + nmod_poly_randtest(b, state, n_randint(state, 30)); + nmod_poly_randtest(c, state, n_randint(state, 10)); + + nmod_poly_compose(r1, a, c); + nmod_poly_compose(r2, b, c); + nmod_poly_add(r1, r1, r2); + + nmod_poly_add(a, a, b); + nmod_poly_compose(r2, a, c); + + result = nmod_poly_equal(r1, r2); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(r1), flint_printf("\n\n"); + nmod_poly_print(r2), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + nmod_poly_clear(r1); + nmod_poly_clear(r2); + } + + /* Compare aliasing */ + for (i = 0; i < 500 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, r1; + mp_limb_t n = n_randtest_not_zero(state); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(r1, n); + nmod_poly_randtest(a, state, n_randint(state, 30)); + nmod_poly_randtest(b, state, n_randint(state, 15)); + + nmod_poly_compose(r1, a, b); + nmod_poly_compose(a, a, b); + + result = nmod_poly_equal(r1, a); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a->length = %wd, n = %wu\n", a->length, a->mod.n); + nmod_poly_print(r1), flint_printf("\n\n"); + nmod_poly_print(a), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(r1); + } + + /* Compare other aliasing */ + for (i = 0; i < 500 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, r1; + mp_limb_t n = n_randtest_not_zero(state); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(r1, n); + nmod_poly_randtest(a, state, n_randint(state, 30)); + nmod_poly_randtest(b, state, n_randint(state, 15)); + + nmod_poly_compose(r1, a, b); + nmod_poly_compose(b, a, b); + + result = nmod_poly_equal(r1, b); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a->length = %wd, n = %wu\n", a->length, a->mod.n); + nmod_poly_print(r1), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(r1); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-compose_divconquer.c b/external/flint-2.4.3/nmod_poly/test/t-compose_divconquer.c new file mode 100644 index 0000000..bb9a698 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-compose_divconquer.c @@ -0,0 +1,139 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result = 1; + FLINT_TEST_INIT(state); + + + flint_printf("compose_divconquer...."); + fflush(stdout); + + /* Compare aliasing */ + for (i = 0; i < 500 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, r1; + mp_limb_t n = n_randtest_not_zero(state); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(r1, n); + nmod_poly_randtest(a, state, n_randint(state, 30)); + nmod_poly_randtest(b, state, n_randint(state, 15)); + + nmod_poly_compose_divconquer(r1, a, b); + nmod_poly_compose_divconquer(a, a, b); + + result = nmod_poly_equal(r1, a); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a->length = %wd, n = %wu\n", a->length, a->mod.n); + nmod_poly_print(r1), flint_printf("\n\n"); + nmod_poly_print(a), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(r1); + } + + /* Compare other aliasing */ + for (i = 0; i < 500 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, r1; + mp_limb_t n = n_randtest_not_zero(state); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(r1, n); + nmod_poly_randtest(a, state, n_randint(state, 30)); + nmod_poly_randtest(b, state, n_randint(state, 15)); + + nmod_poly_compose_divconquer(r1, a, b); + nmod_poly_compose_divconquer(b, a, b); + + result = nmod_poly_equal(r1, b); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a->length = %wd, n = %wu\n", a->length, a->mod.n); + nmod_poly_print(r1), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(r1); + } + + /* Compare with compose_horner */ + for (i = 0; i < 500 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, r1, r2; + mp_limb_t n = n_randtest_not_zero(state); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(r1, n); + nmod_poly_init(r2, n); + nmod_poly_randtest(a, state, n_randint(state, 30)); + nmod_poly_randtest(b, state, n_randint(state, 15)); + + nmod_poly_compose_divconquer(r1, a, b); + nmod_poly_compose_horner(r2, a, b); + + result = nmod_poly_equal(r1, r2); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a->length = %wd, n = %wu\n", a->length, a->mod.n); + nmod_poly_print(r1), flint_printf("\n\n"); + nmod_poly_print(r2), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(r1); + nmod_poly_clear(r2); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-compose_horner.c b/external/flint-2.4.3/nmod_poly/test/t-compose_horner.c new file mode 100644 index 0000000..d3482c8 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-compose_horner.c @@ -0,0 +1,123 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result = 1; + FLINT_TEST_INIT(state); + + + flint_printf("compose_horner...."); + fflush(stdout); + + /* Check (f(x-1))(x+1) == f */ + for (i = 0; i < 500 * flint_test_multiplier(); i++) + { + nmod_poly_t a, r, xp1, xm1; + mp_limb_t n = n_randtest_not_zero(state); + + nmod_poly_init(a, n); + nmod_poly_init(r, n); + nmod_poly_init(xm1, n); + nmod_poly_init(xp1, n); + nmod_poly_randtest(a, state, n_randint(state, 100)); + + nmod_poly_set_coeff_ui(xm1, 1, 1); + nmod_poly_set_coeff_ui(xm1, 0, n - 1); + nmod_poly_set_coeff_ui(xp1, 1, 1); + nmod_poly_set_coeff_ui(xp1, 0, 1); + + nmod_poly_compose_horner(r, a, xm1); + nmod_poly_compose_horner(r, r, xp1); + + result = nmod_poly_equal(a, r); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a->length = %wd, n = %wu\n", a->length, a->mod.n); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(r), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(r); + nmod_poly_clear(xm1); + nmod_poly_clear(xp1); + } + + /* Check a(c) + b(c) = (a + b)(c) */ + for (i = 0; i < 500 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c, r1, r2; + mp_limb_t n = n_randtest_not_zero(state); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(c, n); + nmod_poly_init(r1, n); + nmod_poly_init(r2, n); + nmod_poly_randtest(a, state, n_randint(state, 30)); + nmod_poly_randtest(b, state, n_randint(state, 30)); + nmod_poly_randtest(c, state, n_randint(state, 10)); + + nmod_poly_compose_horner(r1, a, c); + nmod_poly_compose_horner(r2, b, c); + nmod_poly_add(r1, r1, r2); + + nmod_poly_add(a, a, b); + nmod_poly_compose_horner(r2, a, c); + + result = nmod_poly_equal(r1, r2); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(r1), flint_printf("\n\n"); + nmod_poly_print(r2), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + nmod_poly_clear(r1); + nmod_poly_clear(r2); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-compose_mod.c b/external/flint-2.4.3/nmod_poly/test/t-compose_mod.c new file mode 100644 index 0000000..ce4e86a --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-compose_mod.c @@ -0,0 +1,185 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + flint_printf("compose_mod...."); + fflush(stdout); + + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c, d, e; + mp_limb_t m = n_randtest_prime(state, 0); + + nmod_poly_init(a, m); + nmod_poly_init(b, m); + nmod_poly_init(c, m); + nmod_poly_init(d, m); + nmod_poly_init(e, m); + + nmod_poly_randtest(a, state, 1+n_randint(state, 20)); + nmod_poly_randtest(b, state, 1+n_randint(state, 20)); + nmod_poly_randtest_not_zero(c, state, 1+n_randint(state, 20)); + + nmod_poly_compose_mod(d, a, b, c); + nmod_poly_compose(e, a, b); + nmod_poly_rem(e, e, c); + + if (!nmod_poly_equal(d, e)) + { + flint_printf("FAIL (composition):\n"); + nmod_poly_print(a); flint_printf("\n"); + nmod_poly_print(b); flint_printf("\n"); + nmod_poly_print(c); flint_printf("\n"); + nmod_poly_print(d); flint_printf("\n"); + nmod_poly_print(e); flint_printf("\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + nmod_poly_clear(d); + nmod_poly_clear(e); + } + + /* Test aliasing of res and a */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c, d; + mp_limb_t m = n_randtest_prime(state, 0); + + nmod_poly_init(a, m); + nmod_poly_init(b, m); + nmod_poly_init(c, m); + nmod_poly_init(d, m); + + nmod_poly_randtest(a, state, 1+n_randint(state, 20)); + nmod_poly_randtest(b, state, 1+n_randint(state, 20)); + nmod_poly_randtest_not_zero(c, state, 1+n_randint(state, 20)); + + nmod_poly_compose_mod(d, a, b, c); + nmod_poly_compose_mod(a, a, b, c); + + if (!nmod_poly_equal(d, a)) + { + flint_printf("FAIL (aliasing a):\n"); + nmod_poly_print(a); flint_printf("\n"); + nmod_poly_print(b); flint_printf("\n"); + nmod_poly_print(c); flint_printf("\n"); + nmod_poly_print(d); flint_printf("\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + nmod_poly_clear(d); + } + + /* Test aliasing of res and b */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c, d; + mp_limb_t m = n_randtest_prime(state, 0); + + nmod_poly_init(a, m); + nmod_poly_init(b, m); + nmod_poly_init(c, m); + nmod_poly_init(d, m); + + nmod_poly_randtest(a, state, 1+n_randint(state, 20)); + nmod_poly_randtest(b, state, 1+n_randint(state, 20)); + nmod_poly_randtest_not_zero(c, state, 1+n_randint(state, 20)); + + nmod_poly_compose_mod(d, a, b, c); + nmod_poly_compose_mod(b, a, b, c); + + if (!nmod_poly_equal(d, b)) + { + flint_printf("FAIL (aliasing b)\n"); + nmod_poly_print(a); flint_printf("\n"); + nmod_poly_print(b); flint_printf("\n"); + nmod_poly_print(c); flint_printf("\n"); + nmod_poly_print(d); flint_printf("\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + nmod_poly_clear(d); + } + + /* Test aliasing of res and c */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c, d; + mp_limb_t m = n_randtest_prime(state, 0); + + nmod_poly_init(a, m); + nmod_poly_init(b, m); + nmod_poly_init(c, m); + nmod_poly_init(d, m); + + nmod_poly_randtest(a, state, 1+n_randint(state, 20)); + nmod_poly_randtest(b, state, 1+n_randint(state, 20)); + nmod_poly_randtest_not_zero(c, state, 1+n_randint(state, 20)); + + nmod_poly_compose_mod(d, a, b, c); + nmod_poly_compose_mod(c, a, b, c); + + if (!nmod_poly_equal(d, c)) + { + flint_printf("FAIL (aliasing c)\n"); + nmod_poly_print(a); flint_printf("\n"); + nmod_poly_print(b); flint_printf("\n"); + nmod_poly_print(c); flint_printf("\n"); + nmod_poly_print(d); flint_printf("\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + nmod_poly_clear(d); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-compose_mod_brent_kung.c b/external/flint-2.4.3/nmod_poly/test/t-compose_mod_brent_kung.c new file mode 100644 index 0000000..290d99c --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-compose_mod_brent_kung.c @@ -0,0 +1,189 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + flint_printf("compose_mod_brent_kung...."); + fflush(stdout); + + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c, d, e; + mp_limb_t m = n_randtest_prime(state, 0); + + nmod_poly_init(a, m); + nmod_poly_init(b, m); + nmod_poly_init(c, m); + nmod_poly_init(d, m); + nmod_poly_init(e, m); + + nmod_poly_randtest(a, state, 1+n_randint(state, 20)); + nmod_poly_randtest(b, state, 1+n_randint(state, 20)); + nmod_poly_randtest_not_zero(c, state, 1+n_randint(state, 20)); + + nmod_poly_rem(a, a, c); + nmod_poly_compose_mod_brent_kung(d, a, b, c); + nmod_poly_compose(e, a, b); + nmod_poly_rem(e, e, c); + + if (!nmod_poly_equal(d, e)) + { + flint_printf("FAIL (composition):\n"); + nmod_poly_print(a); flint_printf("\n"); + nmod_poly_print(b); flint_printf("\n"); + nmod_poly_print(c); flint_printf("\n"); + nmod_poly_print(d); flint_printf("\n"); + nmod_poly_print(e); flint_printf("\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + nmod_poly_clear(d); + nmod_poly_clear(e); + } + + /* Test aliasing of res and a */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c, d; + mp_limb_t m = n_randtest_prime(state, 0); + + nmod_poly_init(a, m); + nmod_poly_init(b, m); + nmod_poly_init(c, m); + nmod_poly_init(d, m); + + nmod_poly_randtest(a, state, 1+n_randint(state, 20)); + nmod_poly_randtest(b, state, 1+n_randint(state, 20)); + nmod_poly_randtest_not_zero(c, state, 1+n_randint(state, 20)); + + nmod_poly_rem(a, a, c); + nmod_poly_compose_mod_brent_kung(d, a, b, c); + nmod_poly_compose_mod_brent_kung(a, a, b, c); + + if (!nmod_poly_equal(d, a)) + { + flint_printf("FAIL (aliasing a):\n"); + nmod_poly_print(a); flint_printf("\n"); + nmod_poly_print(b); flint_printf("\n"); + nmod_poly_print(c); flint_printf("\n"); + nmod_poly_print(d); flint_printf("\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + nmod_poly_clear(d); + } + + /* Test aliasing of res and b */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c, d; + mp_limb_t m = n_randtest_prime(state, 0); + + nmod_poly_init(a, m); + nmod_poly_init(b, m); + nmod_poly_init(c, m); + nmod_poly_init(d, m); + + nmod_poly_randtest(a, state, 1+n_randint(state, 20)); + nmod_poly_randtest(b, state, 1+n_randint(state, 20)); + nmod_poly_randtest_not_zero(c, state, 1+n_randint(state, 20)); + + nmod_poly_rem(a, a, c); + nmod_poly_compose_mod_brent_kung(d, a, b, c); + nmod_poly_compose_mod_brent_kung(b, a, b, c); + + if (!nmod_poly_equal(d, b)) + { + flint_printf("FAIL (aliasing b)\n"); + nmod_poly_print(a); flint_printf("\n"); + nmod_poly_print(b); flint_printf("\n"); + nmod_poly_print(c); flint_printf("\n"); + nmod_poly_print(d); flint_printf("\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + nmod_poly_clear(d); + } + + /* Test aliasing of res and c */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c, d; + mp_limb_t m = n_randtest_prime(state, 0); + + nmod_poly_init(a, m); + nmod_poly_init(b, m); + nmod_poly_init(c, m); + nmod_poly_init(d, m); + + nmod_poly_randtest(a, state, 1+n_randint(state, 20)); + nmod_poly_randtest(b, state, 1+n_randint(state, 20)); + nmod_poly_randtest_not_zero(c, state, 1+n_randint(state, 20)); + + nmod_poly_rem(a, a, c); + nmod_poly_compose_mod_brent_kung(d, a, b, c); + nmod_poly_compose_mod_brent_kung(c, a, b, c); + + if (!nmod_poly_equal(d, c)) + { + flint_printf("FAIL (aliasing c)\n"); + nmod_poly_print(a); flint_printf("\n"); + nmod_poly_print(b); flint_printf("\n"); + nmod_poly_print(c); flint_printf("\n"); + nmod_poly_print(d); flint_printf("\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + nmod_poly_clear(d); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-compose_mod_brent_kung_precomp_preinv.c b/external/flint-2.4.3/nmod_poly/test/t-compose_mod_brent_kung_precomp_preinv.c new file mode 100644 index 0000000..adf2c53 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-compose_mod_brent_kung_precomp_preinv.c @@ -0,0 +1,235 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2013 Martin Lee + +******************************************************************************/ + +#undef ulong +#define ulong ulongxx/* interferes with system includes */ + +#include +#include + +#undef ulong + +#include + +#define ulong mp_limb_t + +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + flint_printf("compose_mod_brent_kung_precomp_preinv...."); + fflush(stdout); + + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c, cinv, d, e; + nmod_mat_t B; + mp_limb_t m = n_randtest_prime(state, 0); + + nmod_poly_init(a, m); + nmod_poly_init(b, m); + nmod_poly_init(c, m); + nmod_poly_init(cinv, m); + nmod_poly_init(d, m); + nmod_poly_init(e, m); + + nmod_poly_randtest(a, state, 1+n_randint(state, 20)); + nmod_poly_randtest(b, state, 1+n_randint(state, 20)); + nmod_poly_randtest_not_zero(c, state, 1+n_randint(state, 20)); + + nmod_poly_rem(a, a, c); + nmod_poly_reverse(cinv, c, c->length); + nmod_poly_inv_series(cinv, cinv, c->length); + nmod_mat_init (B, n_sqrt (c->length-1)+1, c->length-1, m); + nmod_poly_precompute_matrix (B, b, c, cinv); + nmod_poly_compose_mod_brent_kung_precomp_preinv(d, a, B, c, cinv); + nmod_poly_compose(e, a, b); + nmod_poly_rem(e, e, c); + + if (!nmod_poly_equal(d, e)) + { + flint_printf("FAIL (composition):\n"); + nmod_poly_print(a); flint_printf("\n"); + nmod_poly_print(b); flint_printf("\n"); + nmod_poly_print(c); flint_printf("\n"); + nmod_poly_print(cinv); flint_printf("\n"); + nmod_poly_print(d); flint_printf("\n"); + nmod_poly_print(e); flint_printf("\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_mat_clear (B); + nmod_poly_clear(c); + nmod_poly_clear(cinv); + nmod_poly_clear(d); + nmod_poly_clear(e); + } + + /* Test aliasing of res and a */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c, cinv, d; + nmod_mat_t B; + mp_limb_t m = n_randtest_prime(state, 0); + + nmod_poly_init(a, m); + nmod_poly_init(b, m); + nmod_poly_init(c, m); + nmod_poly_init(cinv, m); + nmod_poly_init(d, m); + + nmod_poly_randtest(a, state, 1+n_randint(state, 20)); + nmod_poly_randtest(b, state, 1+n_randint(state, 20)); + nmod_poly_randtest_not_zero(c, state, 1+n_randint(state, 20)); + + nmod_poly_rem(a, a, c); + nmod_poly_reverse(cinv, c, c->length); + nmod_poly_inv_series(cinv, cinv, c->length); + nmod_mat_init (B, n_sqrt (c->length-1)+1, c->length-1, m); + nmod_poly_precompute_matrix (B, b, c, cinv); + nmod_poly_compose_mod_brent_kung_precomp_preinv(d, a, B, c, cinv); + nmod_poly_compose_mod_brent_kung_precomp_preinv(a, a, B, c, cinv); + + if (!nmod_poly_equal(d, a)) + { + flint_printf("FAIL (aliasing a):\n"); + nmod_poly_print(a); flint_printf("\n"); + nmod_poly_print(b); flint_printf("\n"); + nmod_poly_print(c); flint_printf("\n"); + nmod_poly_print(cinv); flint_printf("\n"); + nmod_poly_print(d); flint_printf("\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_mat_clear (B); + nmod_poly_clear(c); + nmod_poly_clear(cinv); + nmod_poly_clear(d); + } + + /* Test aliasing of res and c */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c, cinv, d; + nmod_mat_t B; + mp_limb_t m = n_randtest_prime(state, 0); + + nmod_poly_init(a, m); + nmod_poly_init(b, m); + nmod_poly_init(c, m); + nmod_poly_init(cinv, m); + nmod_poly_init(d, m); + + nmod_poly_randtest(a, state, 1+n_randint(state, 20)); + nmod_poly_randtest(b, state, 1+n_randint(state, 20)); + nmod_poly_randtest_not_zero(c, state, 1+n_randint(state, 20)); + + nmod_poly_rem(a, a, c); + nmod_poly_reverse(cinv, c, c->length); + nmod_poly_inv_series(cinv, cinv, c->length); + nmod_mat_init (B, n_sqrt (c->length-1)+1, c->length-1, m); + nmod_poly_precompute_matrix (B, b, c, cinv); + nmod_poly_compose_mod_brent_kung_precomp_preinv(d, a, B, c, cinv); + nmod_poly_compose_mod_brent_kung_precomp_preinv(c, a, B, c, cinv); + + if (!nmod_poly_equal(d, c)) + { + flint_printf("FAIL (aliasing c)\n"); + nmod_poly_print(a); flint_printf("\n"); + nmod_poly_print(b); flint_printf("\n"); + nmod_poly_print(c); flint_printf("\n"); + nmod_poly_print(cinv); flint_printf("\n"); + nmod_poly_print(d); flint_printf("\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_mat_clear (B); + nmod_poly_clear(c); + nmod_poly_clear(cinv); + nmod_poly_clear(d); + } + + /* Test aliasing of res and cinv */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c, cinv, d; + nmod_mat_t B; + mp_limb_t m = n_randtest_prime(state, 0); + + nmod_poly_init(a, m); + nmod_poly_init(b, m); + nmod_poly_init(c, m); + nmod_poly_init(cinv, m); + nmod_poly_init(d, m); + + nmod_poly_randtest(a, state, 1+n_randint(state, 20)); + nmod_poly_randtest(b, state, 1+n_randint(state, 20)); + nmod_poly_randtest_not_zero(c, state, 1+n_randint(state, 20)); + + nmod_poly_rem(a, a, c); + nmod_poly_reverse(cinv, c, c->length); + nmod_poly_inv_series(cinv, cinv, c->length); + nmod_mat_init (B, n_sqrt (c->length-1)+1, c->length-1, m); + nmod_poly_precompute_matrix (B, b, c, cinv); + nmod_poly_compose_mod_brent_kung_precomp_preinv(d, a, B, c, cinv); + nmod_poly_compose_mod_brent_kung_precomp_preinv(cinv, a, B, c, cinv); + + if (!nmod_poly_equal(d, cinv)) + { + flint_printf("FAIL (aliasing cinv)\n"); + nmod_poly_print(a); flint_printf("\n"); + nmod_poly_print(b); flint_printf("\n"); + nmod_poly_print(c); flint_printf("\n"); + nmod_poly_print(cinv); flint_printf("\n"); + nmod_poly_print(d); flint_printf("\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_mat_clear (B); + nmod_poly_clear(c); + nmod_poly_clear(cinv); + nmod_poly_clear(d); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-compose_mod_brent_kung_preinv.c b/external/flint-2.4.3/nmod_poly/test/t-compose_mod_brent_kung_preinv.c new file mode 100644 index 0000000..9b14a8f --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-compose_mod_brent_kung_preinv.c @@ -0,0 +1,259 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2013 Martin Lee + +******************************************************************************/ + +#undef ulong +#define ulong ulongxx/* interferes with system includes */ + +#include +#include + +#undef ulong + +#include + +#define ulong mp_limb_t + +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + flint_printf("compose_mod_brent_kung_preinv...."); + fflush(stdout); + + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c, cinv, d, e; + mp_limb_t m = n_randtest_prime(state, 0); + + nmod_poly_init(a, m); + nmod_poly_init(b, m); + nmod_poly_init(c, m); + nmod_poly_init(cinv, m); + nmod_poly_init(d, m); + nmod_poly_init(e, m); + + nmod_poly_randtest(a, state, 1+n_randint(state, 20)); + nmod_poly_randtest(b, state, 1+n_randint(state, 20)); + nmod_poly_randtest_not_zero(c, state, 1+n_randint(state, 20)); + + nmod_poly_rem(a, a, c); + nmod_poly_reverse(cinv, c, c->length); + nmod_poly_inv_series(cinv, cinv, c->length); + nmod_poly_compose_mod_brent_kung_preinv(d, a, b, c, cinv); + nmod_poly_compose(e, a, b); + nmod_poly_rem(e, e, c); + + if (!nmod_poly_equal(d, e)) + { + flint_printf("FAIL (composition):\n"); + nmod_poly_print(a); flint_printf("\n"); + nmod_poly_print(b); flint_printf("\n"); + nmod_poly_print(c); flint_printf("\n"); + nmod_poly_print(cinv); flint_printf("\n"); + nmod_poly_print(d); flint_printf("\n"); + nmod_poly_print(e); flint_printf("\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + nmod_poly_clear(cinv); + nmod_poly_clear(d); + nmod_poly_clear(e); + } + + /* Test aliasing of res and a */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c, cinv, d; + mp_limb_t m = n_randtest_prime(state, 0); + + nmod_poly_init(a, m); + nmod_poly_init(b, m); + nmod_poly_init(c, m); + nmod_poly_init(cinv, m); + nmod_poly_init(d, m); + + nmod_poly_randtest(a, state, 1+n_randint(state, 20)); + nmod_poly_randtest(b, state, 1+n_randint(state, 20)); + nmod_poly_randtest_not_zero(c, state, 1+n_randint(state, 20)); + + nmod_poly_rem(a, a, c); + nmod_poly_reverse(cinv, c, c->length); + nmod_poly_inv_series(cinv, cinv, c->length); + nmod_poly_compose_mod_brent_kung_preinv(d, a, b, c, cinv); + nmod_poly_compose_mod_brent_kung_preinv(a, a, b, c, cinv); + + if (!nmod_poly_equal(d, a)) + { + flint_printf("FAIL (aliasing a):\n"); + nmod_poly_print(a); flint_printf("\n"); + nmod_poly_print(b); flint_printf("\n"); + nmod_poly_print(c); flint_printf("\n"); + nmod_poly_print(cinv); flint_printf("\n"); + nmod_poly_print(d); flint_printf("\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + nmod_poly_clear(cinv); + nmod_poly_clear(d); + } + + /* Test aliasing of res and b */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c, cinv, d; + mp_limb_t m = n_randtest_prime(state, 0); + + nmod_poly_init(a, m); + nmod_poly_init(b, m); + nmod_poly_init(c, m); + nmod_poly_init(cinv, m); + nmod_poly_init(d, m); + + nmod_poly_randtest(a, state, 1+n_randint(state, 20)); + nmod_poly_randtest(b, state, 1+n_randint(state, 20)); + nmod_poly_randtest_not_zero(c, state, 1+n_randint(state, 20)); + + nmod_poly_rem(a, a, c); + nmod_poly_reverse(cinv, c, c->length); + nmod_poly_inv_series(cinv, cinv, c->length); + nmod_poly_compose_mod_brent_kung_preinv(d, a, b, c, cinv); + nmod_poly_compose_mod_brent_kung_preinv(b, a, b, c, cinv); + + if (!nmod_poly_equal(d, b)) + { + flint_printf("FAIL (aliasing b)\n"); + nmod_poly_print(a); flint_printf("\n"); + nmod_poly_print(b); flint_printf("\n"); + nmod_poly_print(c); flint_printf("\n"); + nmod_poly_print(cinv); flint_printf("\n"); + nmod_poly_print(d); flint_printf("\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + nmod_poly_clear(cinv); + nmod_poly_clear(d); + } + + /* Test aliasing of res and c */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c, cinv, d; + mp_limb_t m = n_randtest_prime(state, 0); + + nmod_poly_init(a, m); + nmod_poly_init(b, m); + nmod_poly_init(c, m); + nmod_poly_init(cinv, m); + nmod_poly_init(d, m); + + nmod_poly_randtest(a, state, 1+n_randint(state, 20)); + nmod_poly_randtest(b, state, 1+n_randint(state, 20)); + nmod_poly_randtest_not_zero(c, state, 1+n_randint(state, 20)); + + nmod_poly_rem(a, a, c); + nmod_poly_reverse(cinv, c, c->length); + nmod_poly_inv_series(cinv, cinv, c->length); + nmod_poly_compose_mod_brent_kung_preinv(d, a, b, c, cinv); + nmod_poly_compose_mod_brent_kung_preinv(c, a, b, c, cinv); + + if (!nmod_poly_equal(d, c)) + { + flint_printf("FAIL (aliasing c)\n"); + nmod_poly_print(a); flint_printf("\n"); + nmod_poly_print(b); flint_printf("\n"); + nmod_poly_print(c); flint_printf("\n"); + nmod_poly_print(cinv); flint_printf("\n"); + nmod_poly_print(d); flint_printf("\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + nmod_poly_clear(cinv); + nmod_poly_clear(d); + } + + /* Test aliasing of res and cinv */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c, cinv, d; + mp_limb_t m = n_randtest_prime(state, 0); + + nmod_poly_init(a, m); + nmod_poly_init(b, m); + nmod_poly_init(c, m); + nmod_poly_init(cinv, m); + nmod_poly_init(d, m); + + nmod_poly_randtest(a, state, 1+n_randint(state, 20)); + nmod_poly_randtest(b, state, 1+n_randint(state, 20)); + nmod_poly_randtest_not_zero(c, state, 1+n_randint(state, 20)); + + nmod_poly_rem(a, a, c); + nmod_poly_reverse(cinv, c, c->length); + nmod_poly_inv_series(cinv, cinv, c->length); + nmod_poly_compose_mod_brent_kung_preinv(d, a, b, c, cinv); + nmod_poly_compose_mod_brent_kung_preinv(cinv, a, b, c, cinv); + + if (!nmod_poly_equal(d, cinv)) + { + flint_printf("FAIL (aliasing cinv)\n"); + nmod_poly_print(a); flint_printf("\n"); + nmod_poly_print(b); flint_printf("\n"); + nmod_poly_print(c); flint_printf("\n"); + nmod_poly_print(cinv); flint_printf("\n"); + nmod_poly_print(d); flint_printf("\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + nmod_poly_clear(cinv); + nmod_poly_clear(d); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-compose_mod_horner.c b/external/flint-2.4.3/nmod_poly/test/t-compose_mod_horner.c new file mode 100644 index 0000000..e4a5806 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-compose_mod_horner.c @@ -0,0 +1,185 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + flint_printf("compose_mod_horner...."); + fflush(stdout); + + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c, d, e; + mp_limb_t m = n_randtest_prime(state, 0); + + nmod_poly_init(a, m); + nmod_poly_init(b, m); + nmod_poly_init(c, m); + nmod_poly_init(d, m); + nmod_poly_init(e, m); + + nmod_poly_randtest(a, state, 1+n_randint(state, 20)); + nmod_poly_randtest(b, state, 1+n_randint(state, 20)); + nmod_poly_randtest_not_zero(c, state, 1+n_randint(state, 20)); + + nmod_poly_compose_mod_horner(d, a, b, c); + nmod_poly_compose(e, a, b); + nmod_poly_rem(e, e, c); + + if (!nmod_poly_equal(d, e)) + { + flint_printf("FAIL (composition):\n"); + nmod_poly_print(a); flint_printf("\n"); + nmod_poly_print(b); flint_printf("\n"); + nmod_poly_print(c); flint_printf("\n"); + nmod_poly_print(d); flint_printf("\n"); + nmod_poly_print(e); flint_printf("\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + nmod_poly_clear(d); + nmod_poly_clear(e); + } + + /* Test aliasing of res and a */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c, d; + mp_limb_t m = n_randtest_prime(state, 0); + + nmod_poly_init(a, m); + nmod_poly_init(b, m); + nmod_poly_init(c, m); + nmod_poly_init(d, m); + + nmod_poly_randtest(a, state, 1+n_randint(state, 20)); + nmod_poly_randtest(b, state, 1+n_randint(state, 20)); + nmod_poly_randtest_not_zero(c, state, 1+n_randint(state, 20)); + + nmod_poly_compose_mod_horner(d, a, b, c); + nmod_poly_compose_mod_horner(a, a, b, c); + + if (!nmod_poly_equal(d, a)) + { + flint_printf("FAIL (aliasing a):\n"); + nmod_poly_print(a); flint_printf("\n"); + nmod_poly_print(b); flint_printf("\n"); + nmod_poly_print(c); flint_printf("\n"); + nmod_poly_print(d); flint_printf("\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + nmod_poly_clear(d); + } + + /* Test aliasing of res and b */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c, d; + mp_limb_t m = n_randtest_prime(state, 0); + + nmod_poly_init(a, m); + nmod_poly_init(b, m); + nmod_poly_init(c, m); + nmod_poly_init(d, m); + + nmod_poly_randtest(a, state, 1+n_randint(state, 20)); + nmod_poly_randtest(b, state, 1+n_randint(state, 20)); + nmod_poly_randtest_not_zero(c, state, 1+n_randint(state, 20)); + + nmod_poly_compose_mod_horner(d, a, b, c); + nmod_poly_compose_mod_horner(b, a, b, c); + + if (!nmod_poly_equal(d, b)) + { + flint_printf("FAIL (aliasing b)\n"); + nmod_poly_print(a); flint_printf("\n"); + nmod_poly_print(b); flint_printf("\n"); + nmod_poly_print(c); flint_printf("\n"); + nmod_poly_print(d); flint_printf("\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + nmod_poly_clear(d); + } + + /* Test aliasing of res and c */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c, d; + mp_limb_t m = n_randtest_prime(state, 0); + + nmod_poly_init(a, m); + nmod_poly_init(b, m); + nmod_poly_init(c, m); + nmod_poly_init(d, m); + + nmod_poly_randtest(a, state, 1+n_randint(state, 20)); + nmod_poly_randtest(b, state, 1+n_randint(state, 20)); + nmod_poly_randtest_not_zero(c, state, 1+n_randint(state, 20)); + + nmod_poly_compose_mod_horner(d, a, b, c); + nmod_poly_compose_mod_horner(c, a, b, c); + + if (!nmod_poly_equal(d, c)) + { + flint_printf("FAIL (aliasing c)\n"); + nmod_poly_print(a); flint_printf("\n"); + nmod_poly_print(b); flint_printf("\n"); + nmod_poly_print(c); flint_printf("\n"); + nmod_poly_print(d); flint_printf("\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + nmod_poly_clear(d); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-compose_series.c b/external/flint-2.4.3/nmod_poly/test/t-compose_series.c new file mode 100644 index 0000000..beef22f --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-compose_series.c @@ -0,0 +1,157 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("compose_series...."); + fflush(stdout); + + + + /* Check aliasing of the first argument */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + nmod_poly_t f, g, h; + mp_limb_t m; + slong n; + + m = n_randtest_prime(state, 0); + nmod_poly_init(f, m); + nmod_poly_init(g, m); + nmod_poly_init(h, m); + nmod_poly_randtest(g, state, n_randint(state, 50)); + nmod_poly_randtest(h, state, n_randint(state, 30)); + nmod_poly_set_coeff_ui(h, 0, 0); + n = n_randint(state, 40); + + nmod_poly_compose_series(f, g, h, n); + nmod_poly_compose_series(g, g, h, n); + + result = (nmod_poly_equal(f, g)); + if (!result) + { + flint_printf("FAIL (aliasing 1):\n"); + nmod_poly_print(f), flint_printf("\n\n"); + nmod_poly_print(g), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(f); + nmod_poly_clear(g); + nmod_poly_clear(h); + } + + /* Check aliasing of the second argument */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + nmod_poly_t f, g, h; + mp_limb_t m; + slong n; + + m = n_randtest_prime(state, 0); + nmod_poly_init(f, m); + nmod_poly_init(g, m); + nmod_poly_init(h, m); + nmod_poly_randtest(g, state, n_randint(state, 50)); + nmod_poly_randtest(h, state, n_randint(state, 30)); + nmod_poly_set_coeff_ui(h, 0, 0); + n = n_randint(state, 40); + + nmod_poly_compose_series(f, g, h, n); + nmod_poly_compose_series(h, g, h, n); + + result = (nmod_poly_equal(f, h)); + if (!result) + { + flint_printf("FAIL (aliasing 2):\n"); + nmod_poly_print(f), flint_printf("\n\n"); + nmod_poly_print(h), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(f); + nmod_poly_clear(g); + nmod_poly_clear(h); + } + + /* Compare with compose */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + nmod_poly_t f, g, h, s, t; + mp_limb_t m; + slong n; + + m = n_randtest_prime(state, 0); + nmod_poly_init(f, m); + nmod_poly_init(g, m); + nmod_poly_init(h, m); + nmod_poly_init(s, m); + nmod_poly_init(t, m); + nmod_poly_randtest(g, state, n_randint(state, 50)); + nmod_poly_randtest(h, state, n_randint(state, 30)); + nmod_poly_set_coeff_ui(h, 0, 0); + n = n_randint(state, 40); + + nmod_poly_compose(s, g, h); + nmod_poly_truncate(s, n); + nmod_poly_compose_series(f, g, h, n); + + result = (nmod_poly_equal(f, s)); + if (!result) + { + flint_printf("FAIL (comparison):\n"); + flint_printf("n = %wd\n", n); + flint_printf("g = "), nmod_poly_print(g), flint_printf("\n\n"); + flint_printf("h = "), nmod_poly_print(h), flint_printf("\n\n"); + flint_printf("f = "), nmod_poly_print(f), flint_printf("\n\n"); + flint_printf("s = "), nmod_poly_print(s), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(f); + nmod_poly_clear(g); + nmod_poly_clear(h); + nmod_poly_clear(s); + nmod_poly_clear(t); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-compose_series_brent_kung.c b/external/flint-2.4.3/nmod_poly/test/t-compose_series_brent_kung.c new file mode 100644 index 0000000..3f08643 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-compose_series_brent_kung.c @@ -0,0 +1,157 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("compose_series_brent_kung...."); + fflush(stdout); + + + + /* Check aliasing of the first argument */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + nmod_poly_t f, g, h; + mp_limb_t m; + slong n; + + m = n_randtest_prime(state, 0); + nmod_poly_init(f, m); + nmod_poly_init(g, m); + nmod_poly_init(h, m); + nmod_poly_randtest(g, state, n_randint(state, 40)); + nmod_poly_randtest(h, state, n_randint(state, 20)); + nmod_poly_set_coeff_ui(h, 0, 0); + n = n_randint(state, 20); + + nmod_poly_compose_series_brent_kung(f, g, h, n); + nmod_poly_compose_series_brent_kung(g, g, h, n); + + result = (nmod_poly_equal(f, g)); + if (!result) + { + flint_printf("FAIL (aliasing 1):\n"); + nmod_poly_print(f), flint_printf("\n\n"); + nmod_poly_print(g), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(f); + nmod_poly_clear(g); + nmod_poly_clear(h); + } + + /* Check aliasing of the second argument */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + nmod_poly_t f, g, h; + mp_limb_t m; + slong n; + + m = n_randtest_prime(state, 0); + nmod_poly_init(f, m); + nmod_poly_init(g, m); + nmod_poly_init(h, m); + nmod_poly_randtest(g, state, n_randint(state, 40)); + nmod_poly_randtest(h, state, n_randint(state, 20)); + nmod_poly_set_coeff_ui(h, 0, 0); + n = n_randint(state, 20); + + nmod_poly_compose_series_brent_kung(f, g, h, n); + nmod_poly_compose_series_brent_kung(h, g, h, n); + + result = (nmod_poly_equal(f, h)); + if (!result) + { + flint_printf("FAIL (aliasing 2):\n"); + nmod_poly_print(f), flint_printf("\n\n"); + nmod_poly_print(h), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(f); + nmod_poly_clear(g); + nmod_poly_clear(h); + } + + /* Compare with compose */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + nmod_poly_t f, g, h, s, t; + mp_limb_t m; + slong n; + + m = n_randtest_prime(state, 0); + nmod_poly_init(f, m); + nmod_poly_init(g, m); + nmod_poly_init(h, m); + nmod_poly_init(s, m); + nmod_poly_init(t, m); + nmod_poly_randtest(g, state, n_randint(state, 40)); + nmod_poly_randtest(h, state, n_randint(state, 20)); + nmod_poly_set_coeff_ui(h, 0, 0); + n = n_randint(state, 20); + + nmod_poly_compose(s, g, h); + nmod_poly_truncate(s, n); + nmod_poly_compose_series_brent_kung(f, g, h, n); + + result = (nmod_poly_equal(f, s)); + if (!result) + { + flint_printf("FAIL (comparison):\n"); + flint_printf("n = %wd\n", n); + flint_printf("g = "), nmod_poly_print(g), flint_printf("\n\n"); + flint_printf("h = "), nmod_poly_print(h), flint_printf("\n\n"); + flint_printf("f = "), nmod_poly_print(f), flint_printf("\n\n"); + flint_printf("s = "), nmod_poly_print(s), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(f); + nmod_poly_clear(g); + nmod_poly_clear(h); + nmod_poly_clear(s); + nmod_poly_clear(t); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-compose_series_divconquer.c b/external/flint-2.4.3/nmod_poly/test/t-compose_series_divconquer.c new file mode 100644 index 0000000..f5ee15f --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-compose_series_divconquer.c @@ -0,0 +1,145 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result = 1; + FLINT_TEST_INIT(state); + + + flint_printf("compose_series_divconquer...."); + fflush(stdout); + + /* Aliasing */ + for (i = 0; i < 500 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c; + mp_limb_t n = n_randtest_not_zero(state); + slong N = n_randint(state, 50); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(c, n); + nmod_poly_randtest(a, state, n_randint(state, 30)); + nmod_poly_randtest(b, state, n_randint(state, 15)); + + nmod_poly_compose_series_divconquer(c, a, b, N); + nmod_poly_compose_series_divconquer(a, a, b, N); + + result = nmod_poly_equal(c, a); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a->length = %wd, n = %wu\n", a->length, a->mod.n); + nmod_poly_print(c), flint_printf("\n\n"); + nmod_poly_print(a), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + } + + /* Aliasing */ + for (i = 0; i < 500 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c; + mp_limb_t n = n_randtest_not_zero(state); + slong N = n_randint(state, 50); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(c, n); + nmod_poly_randtest(a, state, n_randint(state, 30)); + nmod_poly_randtest(b, state, n_randint(state, 15)); + + nmod_poly_compose_series_divconquer(c, a, b, N); + nmod_poly_compose_series_divconquer(b, a, b, N); + + result = nmod_poly_equal(c, b); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a->length = %wd, n = %wu\n", a->length, a->mod.n); + nmod_poly_print(c), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + } + + /* Compare with compose */ + for (i = 0; i < 500 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, r1, r2; + mp_limb_t n = n_randtest_not_zero(state); + slong N = n_randint(state, 50); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(r1, n); + nmod_poly_init(r2, n); + nmod_poly_randtest(a, state, n_randint(state, 30)); + nmod_poly_randtest(b, state, n_randint(state, 15)); + + nmod_poly_compose_series_divconquer(r1, a, b, N); + nmod_poly_compose(r2, a, b); + nmod_poly_truncate(r2, N); + + result = nmod_poly_equal(r1, r2); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a->length = %wd, n = %wu\n", a->length, a->mod.n); + nmod_poly_print(r1), flint_printf("\n\n"); + nmod_poly_print(r2), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(r1); + nmod_poly_clear(r2); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/nmod_poly/test/t-compose_series_horner.c b/external/flint-2.4.3/nmod_poly/test/t-compose_series_horner.c new file mode 100644 index 0000000..9a19507 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-compose_series_horner.c @@ -0,0 +1,157 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("compose_series_horner...."); + fflush(stdout); + + + + /* Check aliasing of the first argument */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + nmod_poly_t f, g, h; + mp_limb_t m; + slong n; + + m = n_randtest_prime(state, 0); + nmod_poly_init(f, m); + nmod_poly_init(g, m); + nmod_poly_init(h, m); + nmod_poly_randtest(g, state, n_randint(state, 40)); + nmod_poly_randtest(h, state, n_randint(state, 20)); + nmod_poly_set_coeff_ui(h, 0, 0); + n = n_randint(state, 20); + + nmod_poly_compose_series_horner(f, g, h, n); + nmod_poly_compose_series_horner(g, g, h, n); + + result = (nmod_poly_equal(f, g)); + if (!result) + { + flint_printf("FAIL (aliasing 1):\n"); + nmod_poly_print(f), flint_printf("\n\n"); + nmod_poly_print(g), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(f); + nmod_poly_clear(g); + nmod_poly_clear(h); + } + + /* Check aliasing of the second argument */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + nmod_poly_t f, g, h; + mp_limb_t m; + slong n; + + m = n_randtest_prime(state, 0); + nmod_poly_init(f, m); + nmod_poly_init(g, m); + nmod_poly_init(h, m); + nmod_poly_randtest(g, state, n_randint(state, 40)); + nmod_poly_randtest(h, state, n_randint(state, 20)); + nmod_poly_set_coeff_ui(h, 0, 0); + n = n_randint(state, 20); + + nmod_poly_compose_series_horner(f, g, h, n); + nmod_poly_compose_series_horner(h, g, h, n); + + result = (nmod_poly_equal(f, h)); + if (!result) + { + flint_printf("FAIL (aliasing 2):\n"); + nmod_poly_print(f), flint_printf("\n\n"); + nmod_poly_print(h), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(f); + nmod_poly_clear(g); + nmod_poly_clear(h); + } + + /* Compare with compose */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + nmod_poly_t f, g, h, s, t; + mp_limb_t m; + slong n; + + m = n_randtest_prime(state, 0); + nmod_poly_init(f, m); + nmod_poly_init(g, m); + nmod_poly_init(h, m); + nmod_poly_init(s, m); + nmod_poly_init(t, m); + nmod_poly_randtest(g, state, n_randint(state, 40)); + nmod_poly_randtest(h, state, n_randint(state, 20)); + nmod_poly_set_coeff_ui(h, 0, 0); + n = n_randint(state, 20); + + nmod_poly_compose(s, g, h); + nmod_poly_truncate(s, n); + nmod_poly_compose_series_horner(f, g, h, n); + + result = (nmod_poly_equal(f, s)); + if (!result) + { + flint_printf("FAIL (comparison):\n"); + flint_printf("n = %wd\n", n); + flint_printf("g = "), nmod_poly_print(g), flint_printf("\n\n"); + flint_printf("h = "), nmod_poly_print(h), flint_printf("\n\n"); + flint_printf("f = "), nmod_poly_print(f), flint_printf("\n\n"); + flint_printf("s = "), nmod_poly_print(s), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(f); + nmod_poly_clear(g); + nmod_poly_clear(h); + nmod_poly_clear(s); + nmod_poly_clear(t); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-cos_series.c b/external/flint-2.4.3/nmod_poly/test/t-cos_series.c new file mode 100644 index 0000000..f8c6baa --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-cos_series.c @@ -0,0 +1,128 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result = 1; + FLINT_TEST_INIT(state); + + + flint_printf("cos_series...."); + fflush(stdout); + + /* Check 1-cos(A)^2 = sin(A)^2 */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t A, cosA, sinA, B, C, one; + slong n; + mp_limb_t mod; + + do { mod = n_randtest_prime(state, 0); } while (mod == 2); + n = 1 + n_randtest(state) % 100; + n = FLINT_MIN(n, mod); + + nmod_poly_init(A, mod); + nmod_poly_init(cosA, mod); + nmod_poly_init(sinA, mod); + nmod_poly_init(B, mod); + nmod_poly_init(C, mod); + nmod_poly_init(one, mod); + + nmod_poly_randtest(A, state, n_randint(state, 100)); + nmod_poly_set_coeff_ui(A, 0, UWORD(0)); + + nmod_poly_cos_series(cosA, A, n); + nmod_poly_sin_series(sinA, A, n); + nmod_poly_mullow(B, cosA, cosA, n); + nmod_poly_set_coeff_ui(one, 0, UWORD(1)); + nmod_poly_sub(B, one, B); + nmod_poly_mullow(C, sinA, sinA, n); + + result = nmod_poly_equal(B, C); + + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("n = %wd, mod = %wu\n", n, mod); + flint_printf("A: "); nmod_poly_print(A), flint_printf("\n\n"); + flint_printf("cos(A): "); nmod_poly_print(cosA), flint_printf("\n\n"); + flint_printf("1-cos(A)^2: "); nmod_poly_print(B), flint_printf("\n\n"); + flint_printf("sin(A)^2: "); nmod_poly_print(C), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(A); + nmod_poly_clear(cosA); + nmod_poly_clear(sinA); + nmod_poly_clear(B); + nmod_poly_clear(C); + nmod_poly_clear(one); + } + + /* Check aliasing */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t A, B; + slong n; + mp_limb_t mod; + mod = n_randtest_prime(state, 0); + n = n_randtest(state) % 50; + n = FLINT_MIN(n, mod); + + nmod_poly_init(A, mod); + nmod_poly_init(B, mod); + nmod_poly_randtest(A, state, n_randint(state, 50)); + nmod_poly_set_coeff_ui(A, 0, UWORD(0)); + + nmod_poly_cos_series(B, A, n); + nmod_poly_cos_series(A, A, n); + + result = nmod_poly_equal(A, B); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(A), flint_printf("\n\n"); + nmod_poly_print(B), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(A); + nmod_poly_clear(B); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-cosh_series.c b/external/flint-2.4.3/nmod_poly/test/t-cosh_series.c new file mode 100644 index 0000000..d161c59 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-cosh_series.c @@ -0,0 +1,128 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result = 1; + FLINT_TEST_INIT(state); + + + flint_printf("cosh_series...."); + fflush(stdout); + + /* Check cosh(A)^2-1 = sinh(A)^2 */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t A, coshA, sinhA, B, C, one; + slong n; + mp_limb_t mod; + + do { mod = n_randtest_prime(state, 0); } while (mod == 2); + n = 1 + n_randtest(state) % 100; + n = FLINT_MIN(n, mod); + + nmod_poly_init(A, mod); + nmod_poly_init(coshA, mod); + nmod_poly_init(sinhA, mod); + nmod_poly_init(B, mod); + nmod_poly_init(C, mod); + nmod_poly_init(one, mod); + + nmod_poly_randtest(A, state, n_randint(state, 100)); + nmod_poly_set_coeff_ui(A, 0, UWORD(0)); + + nmod_poly_cosh_series(coshA, A, n); + nmod_poly_sinh_series(sinhA, A, n); + nmod_poly_mullow(B, coshA, coshA, n); + nmod_poly_set_coeff_ui(one, 0, UWORD(1)); + nmod_poly_sub(B, B, one); + nmod_poly_mullow(C, sinhA, sinhA, n); + + result = nmod_poly_equal(B, C); + + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("n = %wd, mod = %wu\n", n, mod); + flint_printf("A: "); nmod_poly_print(A), flint_printf("\n\n"); + flint_printf("cosh(A): "); nmod_poly_print(coshA), flint_printf("\n\n"); + flint_printf("cosh(A)^2-1: "); nmod_poly_print(B), flint_printf("\n\n"); + flint_printf("sinh(A)^2: "); nmod_poly_print(C), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(A); + nmod_poly_clear(coshA); + nmod_poly_clear(sinhA); + nmod_poly_clear(B); + nmod_poly_clear(C); + nmod_poly_clear(one); + } + + /* Check aliasing */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t A, B; + slong n; + mp_limb_t mod; + mod = n_randtest_prime(state, 0); + n = n_randtest(state) % 50; + n = FLINT_MIN(n, mod); + + nmod_poly_init(A, mod); + nmod_poly_init(B, mod); + nmod_poly_randtest(A, state, n_randint(state, 50)); + nmod_poly_set_coeff_ui(A, 0, UWORD(0)); + + nmod_poly_cosh_series(B, A, n); + nmod_poly_cosh_series(A, A, n); + + result = nmod_poly_equal(A, B); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(A), flint_printf("\n\n"); + nmod_poly_print(B), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(A); + nmod_poly_clear(B); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-deflate.c b/external/flint-2.4.3/nmod_poly/test/t-deflate.c new file mode 100644 index 0000000..ecab628 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-deflate.c @@ -0,0 +1,121 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int iter; + FLINT_TEST_INIT(state); + + + flint_printf("deflate...."); + fflush(stdout); + + for (iter = 0; iter < 100 * flint_test_multiplier(); iter++) + { + nmod_poly_t poly1, poly2, poly3; + mp_limb_t modulus; + ulong infl1, infl, deflation; + + modulus = n_randtest_prime(state, 0); + + nmod_poly_init(poly1, modulus); + nmod_poly_init(poly2, modulus); + nmod_poly_init(poly3, modulus); + + nmod_poly_randtest(poly1, state, n_randint(state, 15)); + + if (nmod_poly_length(poly1) <= 1) + { + if (nmod_poly_deflation(poly1) != nmod_poly_length(poly1)) + { + flint_printf("FAIL: wrong deflation for constant polynomial\n"); + abort(); + } + + nmod_poly_deflate(poly2, poly1, n_randint(state, 5) + 1); + if (!nmod_poly_equal(poly2, poly1)) + { + flint_printf("FAIL: constant polynomial changed on deflation\n"); + abort(); + } + } + else + { + + infl = n_randint(state, 13) + 1; + infl1 = nmod_poly_deflation(poly1); + + nmod_poly_inflate(poly2, poly1, infl); + + deflation = nmod_poly_deflation(poly2); + + if (deflation != infl * infl1) + { + flint_printf("FAIL: deflation = %wu, inflation: %wu, %wu\n", + deflation, infl, infl1); + flint_printf("poly1:\n"); nmod_poly_print(poly1); flint_printf("\n\n"); + flint_printf("poly2:\n"); nmod_poly_print(poly2); flint_printf("\n\n"); + abort(); + } + + nmod_poly_deflate(poly3, poly2, infl); + if (!nmod_poly_equal(poly3, poly1)) + { + flint_printf("FAIL: deflation = %wu, inflation: %wu, %wu\n", + deflation, infl, infl1); + flint_printf("Deflated polynomial not equal to input:\n"); + flint_printf("poly1:\n"); nmod_poly_print(poly1); flint_printf("\n\n"); + flint_printf("poly2:\n"); nmod_poly_print(poly2); flint_printf("\n\n"); + flint_printf("poly3:\n"); nmod_poly_print(poly2); flint_printf("\n\n"); + abort(); + } + + nmod_poly_deflate(poly2, poly2, infl); + if (!nmod_poly_equal(poly3, poly2)) + { + flint_printf("FAIL: aliasing\n"); + abort(); + } + } + + nmod_poly_clear(poly1); + nmod_poly_clear(poly2); + nmod_poly_clear(poly3); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-derivative.c b/external/flint-2.4.3/nmod_poly/test/t-derivative.c new file mode 100644 index 0000000..6c7fd22 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-derivative.c @@ -0,0 +1,118 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, j, result = 1; + fmpz_t t; + FLINT_TEST_INIT(state); + + + flint_printf("derivative...."); + fflush(stdout); + + fmpz_init(t); + + /* Check derivative by hand */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b; + mp_limb_t n = n_randtest_not_zero(state); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_randtest(a, state, n_randint(state, 100)); + + nmod_poly_derivative(b, a); + + if (a->length <= 1) + result = (b->length == 0); + else + { + for (j = 1; j < a->length; j++) + { + fmpz_set_ui(t, nmod_poly_get_coeff_ui(a, j)); + fmpz_mul_ui(t, t, j); + fmpz_mod_ui(t, t, n); + result &= (fmpz_get_ui(t) == nmod_poly_get_coeff_ui(b, j - 1)); + } + } + + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a->length = %wd, n = %wu\n", a->length, a->mod.n); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + } + + fmpz_clear(t); + + /* Check aliasing */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b; + mp_limb_t n = n_randtest_not_zero(state); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_randtest(a, state, n_randint(state, 100)); + + nmod_poly_derivative(b, a); + nmod_poly_derivative(a, a); + + result = nmod_poly_equal(a, b); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a->length = %wd, n = %wu\n", a->length, a->mod.n); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-div.c b/external/flint-2.4.3/nmod_poly/test/t-div.c new file mode 100644 index 0000000..5b0d827 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-div.c @@ -0,0 +1,158 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("div...."); + fflush(stdout); + + /* Check result of div against divrem */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, q, r, q2; + + mp_limb_t n; + do n = n_randtest_not_zero(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(q, n); + nmod_poly_init(r, n); + nmod_poly_init(q2, n); + + nmod_poly_randtest(a, state, n_randint(state, 2000)); + do nmod_poly_randtest(b, state, n_randint(state, 2000)); + while (b->length == 0); + + nmod_poly_divrem(q, r, a, b); + nmod_poly_div(q2, a, b); + + result = (nmod_poly_equal(q, q2)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(q), flint_printf("\n\n"); + nmod_poly_print(q2), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(q); + nmod_poly_clear(r); + nmod_poly_clear(q2); + } + + /* Check aliasing of a and q */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, q; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(q, n); + nmod_poly_randtest(a, state, n_randint(state, 2000)); + do nmod_poly_randtest(b, state, n_randint(state, 2000)); + while (b->length == 0); + + nmod_poly_div(q, a, b); + nmod_poly_div(a, a, b); + + result = (nmod_poly_equal(a, q)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(q), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(q); + } + + /* Check aliasing of b and q */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, q; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(q, n); + nmod_poly_randtest(a, state, n_randint(state, 2000)); + do nmod_poly_randtest(b, state, n_randint(state, 2000)); + while (b->length == 0); + + nmod_poly_div(q, a, b); + nmod_poly_div(b, a, b); + + result = (nmod_poly_equal(b, q)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(q), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(q); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-div_basecase.c b/external/flint-2.4.3/nmod_poly/test/t-div_basecase.c new file mode 100644 index 0000000..7ba7c00 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-div_basecase.c @@ -0,0 +1,168 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("div_basecase...."); + fflush(stdout); + + /* Check result of div against divrem */ + for (i = 0; i < 500 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, q, r, q2; + + mp_limb_t n; + do + { + n = n_randtest_not_zero(state); + } while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(q, n); + nmod_poly_init(r, n); + nmod_poly_init(q2, n); + + nmod_poly_randtest(a, state, n_randint(state, 200)); + do nmod_poly_randtest(b, state, n_randint(state, 200)); + while (b->length == 0); + + nmod_poly_divrem_basecase(q, r, a, b); + nmod_poly_div_basecase(q2, a, b); + + result = (nmod_poly_equal(q, q2)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(q), flint_printf("\n\n"); + nmod_poly_print(q2), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(q); + nmod_poly_clear(r); + nmod_poly_clear(q2); + } + + /* Check aliasing of a and q */ + for (i = 0; i < 500 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, q; + + mp_limb_t n; + do + { + n = n_randtest(state); + } while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(q, n); + nmod_poly_randtest(a, state, n_randint(state, 200)); + do + { + nmod_poly_randtest(b, state, n_randint(state, 200)); + } while (b->length == 0); + + nmod_poly_div_basecase(q, a, b); + nmod_poly_div_basecase(a, a, b); + + result = (nmod_poly_equal(a, q)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(q), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(q); + } + + /* Check aliasing of b and q */ + for (i = 0; i < 500 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, q; + + mp_limb_t n; + do + { + n = n_randtest(state); + } while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(q, n); + nmod_poly_randtest(a, state, n_randint(state, 200)); + do + { + nmod_poly_randtest(b, state, n_randint(state, 200)); + } while (b->length == 0); + + nmod_poly_div_basecase(q, a, b); + nmod_poly_div_basecase(b, a, b); + + result = (nmod_poly_equal(b, q)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(q), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(q); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-div_divconquer.c b/external/flint-2.4.3/nmod_poly/test/t-div_divconquer.c new file mode 100644 index 0000000..380033a --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-div_divconquer.c @@ -0,0 +1,158 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("div_divconquer...."); + fflush(stdout); + + /* Check result of div against divrem */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, q, q2, r; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(q, n); + nmod_poly_init(q2, n); + nmod_poly_init(r, n); + + nmod_poly_randtest(a, state, n_randint(state, 2000)); + do nmod_poly_randtest(b, state, n_randint(state, 2000)); + while (b->length == 0); + + nmod_poly_divrem_divconquer(q, r, a, b); + nmod_poly_div_divconquer(q2, a, b); + + result = (nmod_poly_equal(q, q2)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(q), flint_printf("\n\n"); + nmod_poly_print(q2), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(q); + nmod_poly_clear(r); + nmod_poly_clear(q2); + } + + /* Check aliasing of a and q */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, q; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(q, n); + nmod_poly_randtest(a, state, n_randint(state, 2000)); + do nmod_poly_randtest(b, state, n_randint(state, 2000)); + while (b->length == 0); + + nmod_poly_div_divconquer(q, a, b); + nmod_poly_div_divconquer(a, a, b); + + result = (nmod_poly_equal(a, q)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(q), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(q); + } + + /* Check aliasing of b and q */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, q; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(q, n); + nmod_poly_randtest(a, state, n_randint(state, 2000)); + do nmod_poly_randtest(b, state, n_randint(state, 2000)); + while (b->length == 0); + + nmod_poly_div_divconquer(q, a, b); + nmod_poly_div_divconquer(b, a, b); + + result = (nmod_poly_equal(b, q)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(q), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(q); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-div_newton.c b/external/flint-2.4.3/nmod_poly/test/t-div_newton.c new file mode 100644 index 0000000..414a291 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-div_newton.c @@ -0,0 +1,158 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("div_newton...."); + fflush(stdout); + + /* Check result of div against divrem */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, q, q2, r; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(q, n); + nmod_poly_init(q2, n); + nmod_poly_init(r, n); + + nmod_poly_randtest(a, state, n_randint(state, 2000)); + do nmod_poly_randtest(b, state, n_randint(state, 2000)); + while (b->length == 0); + + nmod_poly_divrem_divconquer(q, r, a, b); + nmod_poly_div_newton(q2, a, b); + + result = (nmod_poly_equal(q, q2)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(q), flint_printf("\n\n"); + nmod_poly_print(q2), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(q); + nmod_poly_clear(r); + nmod_poly_clear(q2); + } + + /* Check aliasing of a and q */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, q; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(q, n); + nmod_poly_randtest(a, state, n_randint(state, 2000)); + do nmod_poly_randtest(b, state, n_randint(state, 2000)); + while (b->length == 0); + + nmod_poly_div_newton(q, a, b); + nmod_poly_div_newton(a, a, b); + + result = (nmod_poly_equal(a, q)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(q), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(q); + } + + /* Check aliasing of b and q */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, q; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(q, n); + nmod_poly_randtest(a, state, n_randint(state, 2000)); + do nmod_poly_randtest(b, state, n_randint(state, 2000)); + while (b->length == 0); + + nmod_poly_div_newton(q, a, b); + nmod_poly_div_newton(b, a, b); + + result = (nmod_poly_equal(b, q)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(q), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(q); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-div_newton_n_preinv.c b/external/flint-2.4.3/nmod_poly/test/t-div_newton_n_preinv.c new file mode 100644 index 0000000..741a435 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-div_newton_n_preinv.c @@ -0,0 +1,235 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2013 Martin Lee + +******************************************************************************/ + +#undef ulong +#define ulong ulongxx/* interferes with system includes */ + +#include +#include + +#undef ulong + +#include + +#define ulong mp_limb_t + +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("div_newton_n_preinv...."); + fflush(stdout); + + /* Check result of divrem */ + for (i = 0; i < 500 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, binv, q, r, test; + + mp_limb_t n; + do n = n_randtest_not_zero(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(binv, n); + nmod_poly_init(q, n); + nmod_poly_init(r, n); + nmod_poly_init(test, n); + + do + nmod_poly_randtest(b, state, n_randint(state, 200)); + while (b->length <= 2); + nmod_poly_randtest(a, state, n_randint(state, 200)); + if (a->length > 2*(b->length)-3) + nmod_poly_truncate (a, 2*(b->length)-3); + + nmod_poly_reverse (binv, b, b->length); + nmod_poly_inv_series (binv, binv, b->length); + nmod_poly_div_newton_n_preinv(q, a, b, binv); + nmod_poly_divrem (test, r, a, b); + + result = (nmod_poly_equal(q, test)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(test), flint_printf("\n\n"); + nmod_poly_print(q), flint_printf("\n\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(binv); + nmod_poly_clear(q); + nmod_poly_clear(r); + nmod_poly_clear(test); + } + + /* Check aliasing of a and q */ + for (i = 0; i < 500 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, binv, q; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(binv, n); + nmod_poly_init(q, n); + do + nmod_poly_randtest(b, state, n_randint(state, 200)); + while (b->length <= 2); + nmod_poly_randtest(a, state, n_randint(state, 200)); + if (a->length > 2*(b->length)-3) + nmod_poly_truncate (a, 2*(b->length)-3); + + nmod_poly_reverse (binv, b, b->length); + nmod_poly_inv_series (binv, binv, b->length); + + nmod_poly_div_newton_n_preinv(q, a, b, binv); + nmod_poly_div_newton_n_preinv(a, a, b, binv); + + result = (nmod_poly_equal(a, q)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(q), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(binv); + nmod_poly_clear(q); + } + + /* Check aliasing of b and q */ + for (i = 0; i < 500 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, binv, q; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(binv, n); + nmod_poly_init(q, n); + do + nmod_poly_randtest(b, state, n_randint(state, 200)); + while (b->length <= 2); + nmod_poly_randtest(a, state, n_randint(state, 200)); + if (a->length > 2*(b->length)-3) + nmod_poly_truncate (a, 2*(b->length)-3); + + nmod_poly_reverse (binv, b, b->length); + nmod_poly_inv_series (binv, binv, b->length); + + nmod_poly_div_newton_n_preinv(q, a, b, binv); + nmod_poly_div_newton_n_preinv(b, a, b, binv); + + result = (nmod_poly_equal(b, q)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(q), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(binv); + nmod_poly_clear(q); + } + + /* Check aliasing of binv and q */ + for (i = 0; i < 500 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, binv, q; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(binv, n); + nmod_poly_init(q, n); + do + nmod_poly_randtest(b, state, n_randint(state, 200)); + while (b->length <= 2); + nmod_poly_randtest(a, state, n_randint(state, 200)); + if (a->length > 2*(b->length)-3) + nmod_poly_truncate (a, 2*(b->length)-3); + + nmod_poly_reverse (binv, b, b->length); + nmod_poly_inv_series (binv, binv, b->length); + + nmod_poly_div_newton_n_preinv(q, a, b, binv); + nmod_poly_div_newton_n_preinv(binv, a, b, binv); + + result = (nmod_poly_equal(binv, q)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(binv), flint_printf("\n\n"); + nmod_poly_print(q), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(binv); + nmod_poly_clear(q); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-div_root.c b/external/flint-2.4.3/nmod_poly/test/t-div_root.c new file mode 100644 index 0000000..9555d9b --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-div_root.c @@ -0,0 +1,133 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("div_root...."); + fflush(stdout); + + + + /* Compare with standard divrem */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t P, Q, D, DQ, DR; + mp_limb_t mod, r, rem; + slong n; + + mod = n_randtest_prime(state, 0); + n = n_randint(state, 100); + r = n_randint(state, mod); + + nmod_poly_init(P, mod); + nmod_poly_init(Q, mod); + nmod_poly_init(D, mod); + nmod_poly_init(DQ, mod); + nmod_poly_init(DR, mod); + + nmod_poly_randtest(P, state, n); + + rem = nmod_poly_div_root(Q, P, r); + + nmod_poly_set_coeff_ui(D, 0, n_negmod(r, mod)); + nmod_poly_set_coeff_ui(D, 1, UWORD(1)); + + nmod_poly_divrem(DQ, DR, P, D); + + result = nmod_poly_equal(Q, DQ) && + (rem == nmod_poly_get_coeff_ui(DR, 0)); + + if (!result) + { + flint_printf("FAIL!\n"); + flint_printf("P:\n"); nmod_poly_print(P); flint_printf("\n\n"); + flint_printf("Q:\n"); nmod_poly_print(Q); flint_printf("\n\n"); + flint_printf("D:\n"); nmod_poly_print(D); flint_printf("\n\n"); + flint_printf("DQ:\n"); nmod_poly_print(DQ); flint_printf("\n\n"); + flint_printf("DR:\n"); nmod_poly_print(DR); flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(P); + nmod_poly_clear(Q); + nmod_poly_clear(D); + nmod_poly_clear(DQ); + nmod_poly_clear(DR); + } + + /* Check aliasing */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t P, Q1, Q2; + mp_limb_t mod, r, rem1, rem2; + slong n; + + mod = n_randtest_prime(state, 0); + n = n_randint(state, 100); + r = n_randint(state, mod); + + nmod_poly_init(P, mod); + nmod_poly_init(Q1, mod); + nmod_poly_init(Q2, mod); + + nmod_poly_randtest(P, state, n); + nmod_poly_set(Q2, P); + + rem1 = nmod_poly_div_root(Q1, P, r); + rem2 = nmod_poly_div_root(Q2, Q2, r); + + result = nmod_poly_equal(Q1, Q2) && (rem1 == rem2); + + if (!result) + { + flint_printf("FAIL (aliasing)!\n"); + flint_printf("P:\n"); nmod_poly_print(P); flint_printf("\n\n"); + flint_printf("Q1:\n"); nmod_poly_print(Q1); flint_printf("\n\n"); + flint_printf("Q2:\n"); nmod_poly_print(Q2); flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(P); + nmod_poly_clear(Q1); + nmod_poly_clear(Q2); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-div_series.c b/external/flint-2.4.3/nmod_poly/test/t-div_series.c new file mode 100644 index 0000000..e0d228f --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-div_series.c @@ -0,0 +1,168 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("div_series...."); + fflush(stdout); + + /* Check A/B * B = A */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t q, a, b, prod; + slong m; + + mp_limb_t n; + do n = n_randtest_not_zero(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(prod, n); + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(q, n); + + nmod_poly_randtest(a, state, n_randint(state, 2000)); + do nmod_poly_randtest(b, state, n_randint(state, 2000)); + while (b->length == 0 || b->coeffs[0] == 0); + + m = n_randint(state, 2000) + 1; + + nmod_poly_div_series(q, a, b, m); + nmod_poly_mullow(prod, q, b, m); + nmod_poly_truncate(a, m); + + result = (nmod_poly_equal(a, prod)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(q), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(prod), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(q); + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(prod); + } + + /* Check aliasing of q and a */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t q, a, b; + slong m; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(q, n); + nmod_poly_init(a, n); + nmod_poly_init(b, n); + + nmod_poly_randtest(a, state, n_randint(state, 1000)); + do nmod_poly_randtest(b, state, n_randint(state, 1000)); + while (b->length == 0 || b->coeffs[0] == 0); + + m = n_randint(state, 1000) + 1; + + nmod_poly_div_series(q, a, b, m); + nmod_poly_div_series(a, a, b, m); + + result = (nmod_poly_equal(q, a)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(q), flint_printf("\n\n"); + nmod_poly_print(a), flint_printf("\n\n"); + flint_printf("n = %wd, m = %wd\n", n, m); + abort(); + } + + nmod_poly_clear(q); + nmod_poly_clear(a); + nmod_poly_clear(b); + } + + /* Check aliasing of q and b */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t q, a, b; + slong m; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(q, n); + nmod_poly_init(a, n); + nmod_poly_init(b, n); + + nmod_poly_randtest(a, state, n_randint(state, 1000)); + do nmod_poly_randtest(b, state, n_randint(state, 1000)); + while (b->length == 0 || b->coeffs[0] == 0); + + m = n_randint(state, 1000) + 1; + + nmod_poly_div_series(q, a, b, m); + nmod_poly_div_series(b, a, b, m); + + result = (nmod_poly_equal(q, b)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(q), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + flint_printf("n = %wd, m = %wd\n", n, m); + abort(); + } + + nmod_poly_clear(q); + nmod_poly_clear(a); + nmod_poly_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-divrem.c b/external/flint-2.4.3/nmod_poly/test/t-divrem.c new file mode 100644 index 0000000..e56cf4d --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-divrem.c @@ -0,0 +1,327 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("divrem...."); + fflush(stdout); + + /* Check result of divrem */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, q, r, prod; + + mp_limb_t n; + do n = n_randtest_not_zero(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(q, n); + nmod_poly_init(r, n); + nmod_poly_init(prod, n); + + nmod_poly_randtest(a, state, n_randint(state, 2000)); + do nmod_poly_randtest(b, state, n_randint(state, 2000)); + while (b->length == 0); + + nmod_poly_divrem(q, r, a, b); + nmod_poly_mul(prod, q, b); + nmod_poly_add(prod, prod, r); + + result = (nmod_poly_equal(a, prod)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(prod), flint_printf("\n\n"); + nmod_poly_print(q), flint_printf("\n\n"); + nmod_poly_print(r), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(q); + nmod_poly_clear(r); + nmod_poly_clear(prod); + } + + /* Check aliasing of a and q */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, q, r; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(q, n); + nmod_poly_init(r, n); + nmod_poly_randtest(a, state, n_randint(state, 2000)); + do nmod_poly_randtest(b, state, n_randint(state, 2000)); + while (b->length == 0); + + nmod_poly_divrem(q, r, a, b); + nmod_poly_divrem(a, r, a, b); + + result = (nmod_poly_equal(a, q)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(q), flint_printf("\n\n"); + nmod_poly_print(r), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(q); + nmod_poly_clear(r); + } + + /* Check aliasing of b and q */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, q, r; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(q, n); + nmod_poly_init(r, n); + nmod_poly_randtest(a, state, n_randint(state, 2000)); + do nmod_poly_randtest(b, state, n_randint(state, 2000)); + while (b->length == 0); + + nmod_poly_divrem(q, r, a, b); + nmod_poly_divrem(b, r, a, b); + + result = (nmod_poly_equal(b, q)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(q), flint_printf("\n\n"); + nmod_poly_print(r), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(q); + nmod_poly_clear(r); + } + + /* Check aliasing of a and r */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, q, r; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(q, n); + nmod_poly_init(r, n); + nmod_poly_randtest(a, state, n_randint(state, 2000)); + do nmod_poly_randtest(b, state, n_randint(state, 2000)); + while (b->length == 0); + + nmod_poly_divrem(q, r, a, b); + nmod_poly_divrem(q, a, a, b); + + result = (nmod_poly_equal(a, r)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(q), flint_printf("\n\n"); + nmod_poly_print(r), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(q); + nmod_poly_clear(r); + } + + /* Check aliasing of b and r */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, q, r; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(q, n); + nmod_poly_init(r, n); + nmod_poly_randtest(a, state, n_randint(state, 2000)); + do nmod_poly_randtest(b, state, n_randint(state, 2000)); + while (b->length == 0); + + nmod_poly_divrem(q, r, a, b); + nmod_poly_divrem(q, b, a, b); + + result = (nmod_poly_equal(b, r)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(q), flint_printf("\n\n"); + nmod_poly_print(r), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(q); + nmod_poly_clear(r); + } + + /* Check result of divrem_q0 */ + for (i = 0; i < 500 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, q, r, prod; + + mp_limb_t n = n_randprime(state, n_randint(state,FLINT_BITS-1)+2, 0); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(q, n); + nmod_poly_init(r, n); + nmod_poly_init(prod, n); + + do nmod_poly_randtest(a, state, n_randint(state, 400)); + while (a->length < 1); + nmod_poly_randtest(b, state, a->length); + do b->coeffs[a->length - 1] = n_randint(state, n); + while (b->coeffs[a->length - 1] == 0); + b->length = a->length; + + nmod_poly_divrem(q, r, a, b); + nmod_poly_mul(prod, q, b); + nmod_poly_add(prod, prod, r); + + result = (nmod_poly_equal(a, prod) && r->length < b->length); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(prod), flint_printf("\n\n"); + nmod_poly_print(q), flint_printf("\n\n"); + nmod_poly_print(r), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(q); + nmod_poly_clear(r); + nmod_poly_clear(prod); + } + + /* Check result of divrem_q1 */ + for (i = 0; i < 500 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, q, r, prod; + + mp_limb_t n = n_randprime(state, n_randint(state,FLINT_BITS-1)+2, 0); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(q, n); + nmod_poly_init(r, n); + nmod_poly_init(prod, n); + do nmod_poly_randtest(a, state, n_randint(state, 1000)); + while (a->length < 2); + nmod_poly_fit_length(b, a->length - 1); + flint_mpn_zero(b->coeffs, a->length - 1); + nmod_poly_randtest_not_zero(b, state, n_randint(state, 1000) + 1); + do b->coeffs[a->length - 2] = n_randint(state, n); + while (b->coeffs[a->length - 2] == 0); + b->length = a->length - 1; + + nmod_poly_divrem(q, r, a, b); + nmod_poly_mul(prod, q, b); + nmod_poly_add(prod, prod, r); + + result = (nmod_poly_equal(a, prod) && r->length < b->length); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(prod), flint_printf("\n\n"); + nmod_poly_print(q), flint_printf("\n\n"); + nmod_poly_print(r), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(q); + nmod_poly_clear(r); + nmod_poly_clear(prod); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-divrem_basecase.c b/external/flint-2.4.3/nmod_poly/test/t-divrem_basecase.c new file mode 100644 index 0000000..a25168f --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-divrem_basecase.c @@ -0,0 +1,261 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("divrem_basecase...."); + fflush(stdout); + + /* Check result of divrem */ + for (i = 0; i < 500 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, q, r, prod; + + mp_limb_t n; + do + { + n = n_randtest_not_zero(state); + } while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(q, n); + nmod_poly_init(r, n); + nmod_poly_init(prod, n); + + nmod_poly_randtest(a, state, n_randint(state, 200)); + do + { + nmod_poly_randtest(b, state, n_randint(state, 200)); + } while (b->length == 0); + + nmod_poly_divrem_basecase(q, r, a, b); + nmod_poly_mul(prod, q, b); + nmod_poly_add(prod, prod, r); + + result = (nmod_poly_equal(a, prod)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(prod), flint_printf("\n\n"); + nmod_poly_print(q), flint_printf("\n\n"); + nmod_poly_print(r), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(q); + nmod_poly_clear(r); + nmod_poly_clear(prod); + } + + /* Check aliasing of a and q */ + for (i = 0; i < 500 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, q, r; + + mp_limb_t n; + do + { + n = n_randtest(state); + } while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(q, n); + nmod_poly_init(r, n); + nmod_poly_randtest(a, state, n_randint(state, 200)); + do + { + nmod_poly_randtest(b, state, n_randint(state, 200)); + } while (b->length == 0); + + nmod_poly_divrem_basecase(q, r, a, b); + nmod_poly_divrem_basecase(a, r, a, b); + + result = (nmod_poly_equal(a, q)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(q), flint_printf("\n\n"); + nmod_poly_print(r), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(q); + nmod_poly_clear(r); + } + + /* Check aliasing of b and q */ + for (i = 0; i < 500 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, q, r; + + mp_limb_t n; + do + { + n = n_randtest(state); + } while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(q, n); + nmod_poly_init(r, n); + nmod_poly_randtest(a, state, n_randint(state, 200)); + do + { + nmod_poly_randtest(b, state, n_randint(state, 200)); + } while (b->length == 0); + + nmod_poly_divrem_basecase(q, r, a, b); + nmod_poly_divrem_basecase(b, r, a, b); + + result = (nmod_poly_equal(b, q)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(q), flint_printf("\n\n"); + nmod_poly_print(r), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(q); + nmod_poly_clear(r); + } + + /* Check aliasing of a and r */ + for (i = 0; i < 500 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, q, r; + + mp_limb_t n; + do + { + n = n_randtest(state); + } while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(q, n); + nmod_poly_init(r, n); + nmod_poly_randtest(a, state, n_randint(state, 200)); + do + { + nmod_poly_randtest(b, state, n_randint(state, 200)); + } while (b->length == 0); + + nmod_poly_divrem_basecase(q, r, a, b); + nmod_poly_divrem_basecase(q, a, a, b); + + result = (nmod_poly_equal(a, r)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(q), flint_printf("\n\n"); + nmod_poly_print(r), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(q); + nmod_poly_clear(r); + } + + /* Check aliasing of b and r */ + for (i = 0; i < 500 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, q, r; + + mp_limb_t n; + do + { + n = n_randtest(state); + } while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(q, n); + nmod_poly_init(r, n); + nmod_poly_randtest(a, state, n_randint(state, 200)); + do + { + nmod_poly_randtest(b, state, n_randint(state, 200)); + } while (b->length == 0); + + nmod_poly_divrem_basecase(q, r, a, b); + nmod_poly_divrem_basecase(q, b, a, b); + + result = (nmod_poly_equal(b, r)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(q), flint_printf("\n\n"); + nmod_poly_print(r), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(q); + nmod_poly_clear(r); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-divrem_divconquer.c b/external/flint-2.4.3/nmod_poly/test/t-divrem_divconquer.c new file mode 100644 index 0000000..8c9ae57 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-divrem_divconquer.c @@ -0,0 +1,241 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("divrem_divconquer...."); + fflush(stdout); + + /* Check result of divrem */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, q, r, prod; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(q, n); + nmod_poly_init(r, n); + nmod_poly_init(prod, n); + + nmod_poly_randtest(a, state, n_randint(state, 2000)); + do nmod_poly_randtest(b, state, n_randint(state, 2000)); + while (b->length == 0); + + nmod_poly_divrem_divconquer(q, r, a, b); + nmod_poly_mul(prod, q, b); + nmod_poly_add(prod, prod, r); + + result = (nmod_poly_equal(a, prod)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(prod), flint_printf("\n\n"); + nmod_poly_print(q), flint_printf("\n\n"); + nmod_poly_print(r), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(q); + nmod_poly_clear(r); + nmod_poly_clear(prod); + } + + /* Check aliasing of a and q */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, q, r; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(q, n); + nmod_poly_init(r, n); + nmod_poly_randtest(a, state, n_randint(state, 2000)); + do nmod_poly_randtest(b, state, n_randint(state, 2000)); + while (b->length == 0); + + nmod_poly_divrem_divconquer(q, r, a, b); + nmod_poly_divrem_divconquer(a, r, a, b); + + result = (nmod_poly_equal(a, q)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(q), flint_printf("\n\n"); + nmod_poly_print(r), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(q); + nmod_poly_clear(r); + } + + /* Check aliasing of b and q */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, q, r; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(q, n); + nmod_poly_init(r, n); + nmod_poly_randtest(a, state, n_randint(state, 2000)); + do nmod_poly_randtest(b, state, n_randint(state, 2000)); + while (b->length == 0); + + nmod_poly_divrem_divconquer(q, r, a, b); + nmod_poly_divrem_divconquer(b, r, a, b); + + result = (nmod_poly_equal(b, q)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(q), flint_printf("\n\n"); + nmod_poly_print(r), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(q); + nmod_poly_clear(r); + } + + /* Check aliasing of a and r */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, q, r; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(q, n); + nmod_poly_init(r, n); + nmod_poly_randtest(a, state, n_randint(state, 2000)); + do nmod_poly_randtest(b, state, n_randint(state, 2000)); + while (b->length == 0); + + nmod_poly_divrem_divconquer(q, r, a, b); + nmod_poly_divrem_divconquer(q, a, a, b); + + result = (nmod_poly_equal(a, r)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(q), flint_printf("\n\n"); + nmod_poly_print(r), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(q); + nmod_poly_clear(r); + } + + /* Check aliasing of b and r */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, q, r; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(q, n); + nmod_poly_init(r, n); + nmod_poly_randtest(a, state, n_randint(state, 2000)); + do nmod_poly_randtest(b, state, n_randint(state, 2000)); + while (b->length == 0); + + nmod_poly_divrem_divconquer(q, r, a, b); + nmod_poly_divrem_divconquer(q, b, a, b); + + result = (nmod_poly_equal(b, r)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(q), flint_printf("\n\n"); + nmod_poly_print(r), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(q); + nmod_poly_clear(r); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-divrem_newton.c b/external/flint-2.4.3/nmod_poly/test/t-divrem_newton.c new file mode 100644 index 0000000..8066d24 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-divrem_newton.c @@ -0,0 +1,241 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("divrem_newton...."); + fflush(stdout); + + /* Check result of divrem */ + for (i = 0; i < 500 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, q, r, prod; + + mp_limb_t n; + do n = n_randtest_not_zero(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(q, n); + nmod_poly_init(r, n); + nmod_poly_init(prod, n); + + nmod_poly_randtest(a, state, n_randint(state, 200)); + do nmod_poly_randtest(b, state, n_randint(state, 200)); + while (b->length == 0); + + nmod_poly_divrem_newton(q, r, a, b); + nmod_poly_mul(prod, q, b); + nmod_poly_add(prod, prod, r); + + result = (nmod_poly_equal(a, prod)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(prod), flint_printf("\n\n"); + nmod_poly_print(q), flint_printf("\n\n"); + nmod_poly_print(r), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(q); + nmod_poly_clear(r); + nmod_poly_clear(prod); + } + + /* Check aliasing of a and q */ + for (i = 0; i < 500 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, q, r; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(q, n); + nmod_poly_init(r, n); + nmod_poly_randtest(a, state, n_randint(state, 200)); + do nmod_poly_randtest(b, state, n_randint(state, 200)); + while (b->length == 0); + + nmod_poly_divrem_newton(q, r, a, b); + nmod_poly_divrem_newton(a, r, a, b); + + result = (nmod_poly_equal(a, q)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(q), flint_printf("\n\n"); + nmod_poly_print(r), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(q); + nmod_poly_clear(r); + } + + /* Check aliasing of b and q */ + for (i = 0; i < 500 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, q, r; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(q, n); + nmod_poly_init(r, n); + nmod_poly_randtest(a, state, n_randint(state, 200)); + do nmod_poly_randtest(b, state, n_randint(state, 200)); + while (b->length == 0); + + nmod_poly_divrem_newton(q, r, a, b); + nmod_poly_divrem_newton(b, r, a, b); + + result = (nmod_poly_equal(b, q)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(q), flint_printf("\n\n"); + nmod_poly_print(r), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(q); + nmod_poly_clear(r); + } + + /* Check aliasing of a and r */ + for (i = 0; i < 500 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, q, r; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(q, n); + nmod_poly_init(r, n); + nmod_poly_randtest(a, state, n_randint(state, 200)); + do nmod_poly_randtest(b, state, n_randint(state, 200)); + while (b->length == 0); + + nmod_poly_divrem_newton(q, r, a, b); + nmod_poly_divrem_newton(q, a, a, b); + + result = (nmod_poly_equal(a, r)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(q), flint_printf("\n\n"); + nmod_poly_print(r), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(q); + nmod_poly_clear(r); + } + + /* Check aliasing of b and r */ + for (i = 0; i < 500 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, q, r; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(q, n); + nmod_poly_init(r, n); + nmod_poly_randtest(a, state, n_randint(state, 200)); + do nmod_poly_randtest(b, state, n_randint(state, 200)); + while (b->length == 0); + + nmod_poly_divrem_newton(q, r, a, b); + nmod_poly_divrem_newton(q, b, a, b); + + result = (nmod_poly_equal(b, r)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(q), flint_printf("\n\n"); + nmod_poly_print(r), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(q); + nmod_poly_clear(r); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-divrem_newton_n_preinv.c b/external/flint-2.4.3/nmod_poly/test/t-divrem_newton_n_preinv.c new file mode 100644 index 0000000..99366d2 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-divrem_newton_n_preinv.c @@ -0,0 +1,385 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2013 Martin Lee + +******************************************************************************/ + +#undef ulong +#define ulong ulongxx/* interferes with system includes */ + +#include +#include + +#undef ulong + +#include + +#define ulong mp_limb_t + +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("divrem_newton_n_preinv...."); + fflush(stdout); + + /* Check result of divrem */ + for (i = 0; i < 500 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, binv, q, r, test; + + mp_limb_t n; + do n = n_randtest_not_zero(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(binv, n); + nmod_poly_init(q, n); + nmod_poly_init(r, n); + nmod_poly_init(test, n); + + do + nmod_poly_randtest(b, state, n_randint(state, 200)); + while (b->length <= 2); + nmod_poly_randtest(a, state, n_randint(state, 200)); + if (a->length > 2*(b->length)-3) + nmod_poly_truncate (a, 2*(b->length)-3); + + nmod_poly_reverse (binv, b, b->length); + nmod_poly_inv_series (binv, binv, b->length); + nmod_poly_divrem_newton_n_preinv(q, r, a, b, binv); + nmod_poly_mul(test, q, b); + nmod_poly_add(test, test, r); + + result = (nmod_poly_equal(a, test)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(test), flint_printf("\n\n"); + nmod_poly_print(q), flint_printf("\n\n"); + nmod_poly_print(r), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(binv); + nmod_poly_clear(q); + nmod_poly_clear(r); + nmod_poly_clear(test); + } + + /* Check aliasing of a and q */ + for (i = 0; i < 500 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, binv, q, r; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(binv, n); + nmod_poly_init(q, n); + nmod_poly_init(r, n); + do + nmod_poly_randtest(b, state, n_randint(state, 200)); + while (b->length <= 2); + nmod_poly_randtest(a, state, n_randint(state, 200)); + if (a->length > 2*(b->length)-3) + nmod_poly_truncate (a, 2*(b->length)-3); + + nmod_poly_reverse (binv, b, b->length); + nmod_poly_inv_series (binv, binv, b->length); + + nmod_poly_divrem_newton_n_preinv(q, r, a, b, binv); + nmod_poly_divrem_newton_n_preinv(a, r, a, b, binv); + + result = (nmod_poly_equal(a, q)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(q), flint_printf("\n\n"); + nmod_poly_print(r), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(binv); + nmod_poly_clear(q); + nmod_poly_clear(r); + } + + /* Check aliasing of b and q */ + for (i = 0; i < 500 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, binv, q, r; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(binv, n); + nmod_poly_init(q, n); + nmod_poly_init(r, n); + do + nmod_poly_randtest(b, state, n_randint(state, 200)); + while (b->length <= 2); + nmod_poly_randtest(a, state, n_randint(state, 200)); + if (a->length > 2*(b->length)-3) + nmod_poly_truncate (a, 2*(b->length)-3); + + nmod_poly_reverse (binv, b, b->length); + nmod_poly_inv_series (binv, binv, b->length); + + nmod_poly_divrem_newton_n_preinv(q, r, a, b, binv); + nmod_poly_divrem_newton_n_preinv(b, r, a, b, binv); + + result = (nmod_poly_equal(b, q)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(q), flint_printf("\n\n"); + nmod_poly_print(r), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(binv); + nmod_poly_clear(q); + nmod_poly_clear(r); + } + + /* Check aliasing of binv and q */ + for (i = 0; i < 500 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, binv, q, r; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(binv, n); + nmod_poly_init(q, n); + nmod_poly_init(r, n); + do + nmod_poly_randtest(b, state, n_randint(state, 200)); + while (b->length <= 2); + nmod_poly_randtest(a, state, n_randint(state, 200)); + if (a->length > 2*(b->length)-3) + nmod_poly_truncate (a, 2*(b->length)-3); + + nmod_poly_reverse (binv, b, b->length); + nmod_poly_inv_series (binv, binv, b->length); + + nmod_poly_divrem_newton_n_preinv(q, r, a, b, binv); + nmod_poly_divrem_newton_n_preinv(binv, r, a, b, binv); + + result = (nmod_poly_equal(binv, q)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(binv), flint_printf("\n\n"); + nmod_poly_print(q), flint_printf("\n\n"); + nmod_poly_print(r), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(binv); + nmod_poly_clear(q); + nmod_poly_clear(r); + } + + /* Check aliasing of a and r */ + for (i = 0; i < 500 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, binv, q, r; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(binv, n); + nmod_poly_init(q, n); + nmod_poly_init(r, n); + do + nmod_poly_randtest(b, state, n_randint(state, 200)); + while (b->length <= 2); + nmod_poly_randtest(a, state, n_randint(state, 200)); + if (a->length > 2*(b->length)-3) + nmod_poly_truncate (a, 2*(b->length)-3); + + nmod_poly_reverse (binv, b, b->length); + nmod_poly_inv_series (binv, binv, b->length); + + nmod_poly_divrem_newton_n_preinv(q, r, a, b, binv); + nmod_poly_divrem_newton_n_preinv(q, a, a, b, binv); + + result = (nmod_poly_equal(a, r)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(q), flint_printf("\n\n"); + nmod_poly_print(r), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(binv); + nmod_poly_clear(q); + nmod_poly_clear(r); + } + + /* Check aliasing of b and r */ + for (i = 0; i < 500 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, binv, q, r; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(binv, n); + nmod_poly_init(q, n); + nmod_poly_init(r, n); + do + nmod_poly_randtest(b, state, n_randint(state, 200)); + while (b->length <= 2); + nmod_poly_randtest(a, state, n_randint(state, 200)); + if (a->length > 2*(b->length)-3) + nmod_poly_truncate (a, 2*(b->length)-3); + + nmod_poly_reverse (binv, b, b->length); + nmod_poly_inv_series (binv, binv, b->length); + + nmod_poly_divrem_newton_n_preinv(q, r, a, b, binv); + nmod_poly_divrem_newton_n_preinv(q, b, a, b, binv); + + result = (nmod_poly_equal(b, r)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(q), flint_printf("\n\n"); + nmod_poly_print(r), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(binv); + nmod_poly_clear(q); + nmod_poly_clear(r); + } + + /* Check aliasing of binv and r */ + for (i = 0; i < 500 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, binv, q, r; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(binv, n); + nmod_poly_init(q, n); + nmod_poly_init(r, n); + do + nmod_poly_randtest(b, state, n_randint(state, 200)); + while (b->length <= 2); + nmod_poly_randtest(a, state, n_randint(state, 200)); + if (a->length > 2*(b->length)-3) + nmod_poly_truncate (a, 2*(b->length)-3); + + nmod_poly_reverse (binv, b, b->length); + nmod_poly_inv_series (binv, binv, b->length); + + nmod_poly_divrem_newton_n_preinv(q, r, a, b, binv); + nmod_poly_divrem_newton_n_preinv(q, binv, a, b, binv); + + result = (nmod_poly_equal(binv, r)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(binv), flint_printf("\n\n"); + nmod_poly_print(q), flint_printf("\n\n"); + nmod_poly_print(r), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(binv); + nmod_poly_clear(q); + nmod_poly_clear(r); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-evaluate_nmod.c b/external/flint-2.4.3/nmod_poly/test/t-evaluate_nmod.c new file mode 100644 index 0000000..c244408 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-evaluate_nmod.c @@ -0,0 +1,112 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, j, result = 1; + FLINT_TEST_INIT(state); + + + flint_printf("evaluate_nmod...."); + fflush(stdout); + + /* Check evaluation at 1 gives sum of coeffs */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t a; + mp_limb_t n = n_randtest_not_zero(state); + mp_limb_t sum, eval; + + nmod_poly_init(a, n); + nmod_poly_randtest(a, state, n_randint(state, 100)); + + eval = nmod_poly_evaluate_nmod(a, 1); + + sum = 0; + for (j = 0; j < a->length; j++) + sum = n_addmod(sum, nmod_poly_get_coeff_ui(a, j), n); + + result = (sum == eval); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a->length = %wd, n = %wu\n", a->length, a->mod.n); + flint_printf("sum = %wu, eval = %wu\n", sum, eval); + nmod_poly_print(a), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + } + + /* Check a(c) + b(c) = (a + b)(c) */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b; + mp_limb_t n = n_randtest_not_zero(state); + mp_limb_t eval1, eval2, c; + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_randtest(a, state, n_randint(state, 100)); + nmod_poly_randtest(b, state, n_randint(state, 100)); + + c = n_randint(state, n); + + eval1 = nmod_poly_evaluate_nmod(a, c); + eval1 = n_addmod(eval1, nmod_poly_evaluate_nmod(b, c), n); + + nmod_poly_add(a, a, b); + eval2 = nmod_poly_evaluate_nmod(a, c); + + + result = (eval1 == eval2); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("eval1 = %wu, eval2 = %wu\n", eval1, eval2); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-evaluate_nmod_vec_fast.c b/external/flint-2.4.3/nmod_poly/test/t-evaluate_nmod_vec_fast.c new file mode 100644 index 0000000..0857ee6 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-evaluate_nmod_vec_fast.c @@ -0,0 +1,90 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011, 2012 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result = 1; + FLINT_TEST_INIT(state); + + + flint_printf("evaluate_nmod_vec_fast...."); + fflush(stdout); + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t P, Q; + mp_ptr x, y, z; + mp_limb_t mod; + slong j, n, npoints; + + mod = n_randtest_prime(state, 0); + npoints = n_randint(state, 100); + n = n_randint(state, 100); + + nmod_poly_init(P, mod); + nmod_poly_init(Q, mod); + x = _nmod_vec_init(npoints); + y = _nmod_vec_init(npoints); + z = _nmod_vec_init(npoints); + + nmod_poly_randtest(P, state, n); + + for (j = 0; j < npoints; j++) + x[j] = n_randint(state, mod); + + nmod_poly_evaluate_nmod_vec_iter(y, P, x, npoints); + nmod_poly_evaluate_nmod_vec_fast(z, P, x, npoints); + + result = _nmod_vec_equal(y, z, npoints); + + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("mod=%wu, n=%wd, npoints=%wd\n\n", mod, n, npoints); + flint_printf("P: "); nmod_poly_print(P); flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(P); + nmod_poly_clear(Q); + _nmod_vec_clear(x); + _nmod_vec_clear(y); + _nmod_vec_clear(z); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-exp_series.c b/external/flint-2.4.3/nmod_poly/test/t-exp_series.c new file mode 100644 index 0000000..2fc84ca --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-exp_series.c @@ -0,0 +1,147 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result = 1; + FLINT_TEST_INIT(state); + + + flint_printf("exp_series...."); + fflush(stdout); + + /* Check exp(A+B) = exp(A) * exp(B) */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t A, B, AB, expA, expB, expAB, S; + slong n; + slong N = 100; + mp_limb_t mod; + + /* Make sure to workout the Newton code */ + if (n_randint(state, 10) == 1) + N = 2000; + + mod = n_randtest_prime(state, 0); + n = n_randtest(state) % N; + n = FLINT_MIN(n, mod); + + nmod_poly_init(A, mod); + nmod_poly_init(B, mod); + nmod_poly_init(AB, mod); + nmod_poly_init(expA, mod); + nmod_poly_init(expB, mod); + nmod_poly_init(expAB, mod); + nmod_poly_init(S, mod); + + nmod_poly_randtest(A, state, n_randint(state, N)); + nmod_poly_set_coeff_ui(A, 0, UWORD(0)); + nmod_poly_randtest(B, state, n_randint(state, N)); + nmod_poly_set_coeff_ui(B, 0, UWORD(0)); + + /* Randomly generate a monomial */ + if (n_randlimb(state) % 100 == 0) + { + nmod_poly_zero(A); + nmod_poly_set_coeff_ui(A, n_randlimb(state) % (n+5), \ + n_randtest_not_zero(state) % mod); + nmod_poly_set_coeff_ui(A, 0, UWORD(0)); + } + + nmod_poly_exp_series(expA, A, n); + nmod_poly_exp_series(expB, B, n); + nmod_poly_add(AB, A, B); + nmod_poly_exp_series(expAB, AB, n); + nmod_poly_mullow(S, expA, expB, n); + + result = nmod_poly_equal(S, expAB); + + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("n = %wd, mod = %wu\n", n, mod); + flint_printf("A: "); nmod_poly_print(A), flint_printf("\n\n"); + flint_printf("B: "); nmod_poly_print(B), flint_printf("\n\n"); + flint_printf("exp(A): "); nmod_poly_print(expA), flint_printf("\n\n"); + flint_printf("exp(B): "); nmod_poly_print(expB), flint_printf("\n\n"); + flint_printf("exp(A+B): "); nmod_poly_print(expAB), flint_printf("\n\n"); + flint_printf("exp(A)*exp(B): "); nmod_poly_print(S), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(A); + nmod_poly_clear(B); + nmod_poly_clear(AB); + nmod_poly_clear(expA); + nmod_poly_clear(expB); + nmod_poly_clear(expAB); + nmod_poly_clear(S); + } + + /* Check aliasing */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t A, B; + slong n; + mp_limb_t mod; + mod = n_randtest_prime(state, 0); + n = n_randtest(state) % 50; + n = FLINT_MIN(n, mod); + + nmod_poly_init(A, mod); + nmod_poly_init(B, mod); + nmod_poly_randtest(A, state, n_randint(state, 50)); + nmod_poly_set_coeff_ui(A, 0, UWORD(0)); + + nmod_poly_exp_series(B, A, n); + nmod_poly_exp_series(A, A, n); + + result = nmod_poly_equal(A, B); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(A), flint_printf("\n\n"); + nmod_poly_print(B), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(A); + nmod_poly_clear(B); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-exp_series_basecase.c b/external/flint-2.4.3/nmod_poly/test/t-exp_series_basecase.c new file mode 100644 index 0000000..660c68d --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-exp_series_basecase.c @@ -0,0 +1,141 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result = 1; + FLINT_TEST_INIT(state); + + + flint_printf("exp_series_basecase...."); + fflush(stdout); + + /* Check exp(A+B) = exp(A) * exp(B) */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t A, B, AB, expA, expB, expAB, S; + slong n; + mp_limb_t mod; + + mod = n_randtest_prime(state, 0); + n = n_randtest(state) % 100; + n = FLINT_MIN(n, mod); + + nmod_poly_init(A, mod); + nmod_poly_init(B, mod); + nmod_poly_init(AB, mod); + nmod_poly_init(expA, mod); + nmod_poly_init(expB, mod); + nmod_poly_init(expAB, mod); + nmod_poly_init(S, mod); + + nmod_poly_randtest(A, state, n_randint(state, 100)); + nmod_poly_set_coeff_ui(A, 0, UWORD(0)); + nmod_poly_randtest(B, state, n_randint(state, 100)); + nmod_poly_set_coeff_ui(B, 0, UWORD(0)); + + if (n_randlimb(state) % 100 == 0) + { + nmod_poly_zero(A); + nmod_poly_set_coeff_ui(A, n_randlimb(state) % (n+5), \ + n_randtest_not_zero(state) % mod); + nmod_poly_set_coeff_ui(A, 0, UWORD(0)); + } + + nmod_poly_exp_series_basecase(expA, A, n); + nmod_poly_exp_series_basecase(expB, B, n); + nmod_poly_add(AB, A, B); + nmod_poly_exp_series(expAB, AB, n); + nmod_poly_mullow(S, expA, expB, n); + + result = nmod_poly_equal(S, expAB); + + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("n = %wd, mod = %wu\n", n, mod); + flint_printf("A: "); nmod_poly_print(A), flint_printf("\n\n"); + flint_printf("B: "); nmod_poly_print(B), flint_printf("\n\n"); + flint_printf("exp(A): "); nmod_poly_print(expA), flint_printf("\n\n"); + flint_printf("exp(B): "); nmod_poly_print(expB), flint_printf("\n\n"); + flint_printf("exp(A+B): "); nmod_poly_print(expAB), flint_printf("\n\n"); + flint_printf("exp(A)*exp(B): "); nmod_poly_print(S), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(A); + nmod_poly_clear(B); + nmod_poly_clear(AB); + nmod_poly_clear(expA); + nmod_poly_clear(expB); + nmod_poly_clear(expAB); + nmod_poly_clear(S); + } + + /* Check aliasing */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t A, B; + slong n; + mp_limb_t mod; + mod = n_randtest_prime(state, 0); + n = n_randtest(state) % 50; + n = FLINT_MIN(n, mod); + + nmod_poly_init(A, mod); + nmod_poly_init(B, mod); + nmod_poly_randtest(A, state, n_randint(state, 50)); + nmod_poly_set_coeff_ui(A, 0, UWORD(0)); + + nmod_poly_exp_series_basecase(B, A, n); + nmod_poly_exp_series_basecase(A, A, n); + + result = nmod_poly_equal(A, B); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(A), flint_printf("\n\n"); + nmod_poly_print(B), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(A); + nmod_poly_clear(B); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-exp_series_monomial_ui.c b/external/flint-2.4.3/nmod_poly/test/t-exp_series_monomial_ui.c new file mode 100644 index 0000000..49d3aa1 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-exp_series_monomial_ui.c @@ -0,0 +1,90 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result = 1; + FLINT_TEST_INIT(state); + + + flint_printf("exp_series_monomial_ui...."); + fflush(stdout); + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t A, expA, res; + slong n; + mp_limb_t mod; + ulong power; + mp_limb_t coeff; + + mod = n_randtest_prime(state, 0); + n = n_randtest(state) % 100; + n = FLINT_MIN(n, mod); + + nmod_poly_init(A, mod); + nmod_poly_init(expA, mod); + nmod_poly_init(res, mod); + + coeff = n_randlimb(state) % mod; + power = 1 + n_randint(state, 2*n + 1); + + nmod_poly_set_coeff_ui(A, power, coeff); + + nmod_poly_exp_series(expA, A, n); + nmod_poly_exp_series_monomial_ui(res, coeff, power, n); + + result = nmod_poly_equal(expA, res); + + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("n = %wd, mod = %wu\n", n, mod); + flint_printf("power = %wu, coeff = %wu\n", power, coeff); + flint_printf("A: "); nmod_poly_print(A), flint_printf("\n\n"); + flint_printf("exp(A): "); nmod_poly_print(expA), flint_printf("\n\n"); + flint_printf("res: "); nmod_poly_print(res), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(A); + nmod_poly_clear(expA); + nmod_poly_clear(res); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-fread_print.c b/external/flint-2.4.3/nmod_poly/test/t-fread_print.c new file mode 100644 index 0000000..803fe17 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-fread_print.c @@ -0,0 +1,106 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +#if !defined (__WIN32) && !defined (__CYGWIN__) + +int +main(void) +{ + int i, result, r1; + FLINT_TEST_INIT(state); + + + flint_printf("fread_print...."); + fflush(stdout); + + /* Check reading and writing to a file */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b; + mp_limb_t n = n_randtest_not_zero(state); + FILE * f = fopen("nmod_poly_test", "w+"); + + if (!f) + { + flint_printf("Error: unable to open file for writing.\n"); + abort(); + } + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_randtest(a, state, n_randint(state, 100)); + + nmod_poly_fprint(f, a); + fflush(f); + fclose(f); + f = fopen("nmod_poly_test", "r"); + r1 = nmod_poly_fread(f, b); + + result = (r1 && nmod_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("r1 = %d, n = %wu\n", r1, a->mod.n); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + fclose(f); + remove("nmod_poly_test"); + abort(); + } + + fclose(f); + if (remove("nmod_poly_test")) + { + flint_printf("Error, unable to delete file nmod_poly_test\n"); + abort(); + } + nmod_poly_clear(a); + nmod_poly_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} + +#else + +int main(void) +{ + flint_printf("print/ read...."); + fflush(stdout); + flint_printf("SKIPPED\n"); + return EXIT_SUCCESS; +} + +#endif diff --git a/external/flint-2.4.3/nmod_poly/test/t-gcd.c b/external/flint-2.4.3/nmod_poly/test/t-gcd.c new file mode 100644 index 0000000..47ccdf8 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-gcd.c @@ -0,0 +1,167 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("gcd...."); + fflush(stdout); + + /* + Find coprime polys, multiply by another poly + and check the GCD is that poly + */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c, g; + + mp_limb_t n; + do n = n_randtest_not_zero(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(c, n); + nmod_poly_init(g, n); + + do { + nmod_poly_randtest(a, state, n_randint(state, 1000)); + nmod_poly_randtest(b, state, n_randint(state, 1000)); + nmod_poly_gcd_euclidean(g, a, b); + } while (g->length != 1); + + do { + nmod_poly_randtest(c, state, n_randint(state, 1000)); + } while (c->length < 2); + nmod_poly_make_monic(c, c); + + nmod_poly_mul(a, a, c); + nmod_poly_mul(b, b, c); + + nmod_poly_gcd_euclidean(g, a, b); + + result = (nmod_poly_equal(g, c)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(c), flint_printf("\n\n"); + nmod_poly_print(g), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + nmod_poly_clear(g); + } + + /* Check aliasing of a and g */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, g; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(g, n); + nmod_poly_randtest(a, state, n_randint(state, 1000)); + nmod_poly_randtest(b, state, n_randint(state, 1000)); + + nmod_poly_gcd_euclidean(g, a, b); + nmod_poly_gcd_euclidean(a, a, b); + + result = (nmod_poly_equal(a, g)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(g), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(g); + } + + /* Check aliasing of b and g */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, g; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(g, n); + nmod_poly_randtest(a, state, n_randint(state, 1000)); + nmod_poly_randtest(b, state, n_randint(state, 1000)); + + nmod_poly_gcd_euclidean(g, a, b); + nmod_poly_gcd_euclidean(b, a, b); + + result = (nmod_poly_equal(b, g)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(g), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(g); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-gcd_euclidean.c b/external/flint-2.4.3/nmod_poly/test/t-gcd_euclidean.c new file mode 100644 index 0000000..531129f --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-gcd_euclidean.c @@ -0,0 +1,166 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("gcd_euclidean...."); + fflush(stdout); + + /* + Find coprime polys, multiply by another poly + and check the GCD is that poly + */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c, g; + + mp_limb_t n; + do n = n_randtest_not_zero(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(c, n); + nmod_poly_init(g, n); + + do { + nmod_poly_randtest(a, state, n_randint(state, 200)); + nmod_poly_randtest(b, state, n_randint(state, 200)); + nmod_poly_gcd_euclidean(g, a, b); + } while (g->length != 1); + + do { + nmod_poly_randtest(c, state, n_randint(state, 200)); + } while (c->length < 2); + nmod_poly_make_monic(c, c); + + nmod_poly_mul(a, a, c); + nmod_poly_mul(b, b, c); + + nmod_poly_gcd_euclidean(g, a, b); + + result = (nmod_poly_equal(g, c)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(c), flint_printf("\n\n"); + nmod_poly_print(g), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + nmod_poly_clear(g); + } + + /* Check aliasing of a and g */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, g; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(g, n); + nmod_poly_randtest(a, state, n_randint(state, 200)); + nmod_poly_randtest(b, state, n_randint(state, 200)); + + nmod_poly_gcd_euclidean(g, a, b); + nmod_poly_gcd_euclidean(a, a, b); + + result = (nmod_poly_equal(a, g)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(g), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(g); + } + + /* Check aliasing of b and g */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, g; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(g, n); + nmod_poly_randtest(a, state, n_randint(state, 200)); + nmod_poly_randtest(b, state, n_randint(state, 200)); + + nmod_poly_gcd_euclidean(g, a, b); + nmod_poly_gcd_euclidean(b, a, b); + + result = (nmod_poly_equal(b, g)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(g), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(g); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-gcd_hgcd.c b/external/flint-2.4.3/nmod_poly/test/t-gcd_hgcd.c new file mode 100644 index 0000000..e4e2c50 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-gcd_hgcd.c @@ -0,0 +1,168 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("gcd_hgcd...."); + fflush(stdout); + + /* + Find coprime polys, multiply by another poly + and check the GCD is that poly + */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c, g; + + mp_limb_t n; + do n = n_randtest_not_zero(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(c, n); + nmod_poly_init(g, n); + + do { + nmod_poly_randtest(a, state, n_randint(state, 1000)); + nmod_poly_randtest(b, state, n_randint(state, 1000)); + nmod_poly_gcd_hgcd(g, a, b); + } while (g->length != 1); + + do { + nmod_poly_randtest(c, state, n_randint(state, 1000)); + } while (c->length < 2); + nmod_poly_make_monic(c, c); + + nmod_poly_mul(a, a, c); + nmod_poly_mul(b, b, c); + + nmod_poly_gcd_hgcd(g, a, b); + + result = (nmod_poly_equal(g, c)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(c), flint_printf("\n\n"); + nmod_poly_print(g), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + nmod_poly_clear(g); + } + + /* Check aliasing of a and g */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, g; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(g, n); + nmod_poly_randtest(a, state, n_randint(state, 1000)); + nmod_poly_randtest(b, state, n_randint(state, 1000)); + + nmod_poly_gcd_hgcd(g, a, b); + nmod_poly_gcd_hgcd(a, a, b); + + result = (nmod_poly_equal(a, g)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(g), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(g); + } + + /* Check aliasing of b and g */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, g; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(g, n); + nmod_poly_randtest(a, state, n_randint(state, 1000)); + nmod_poly_randtest(b, state, n_randint(state, 1000)); + + nmod_poly_gcd_hgcd(g, a, b); + nmod_poly_gcd_hgcd(b, a, b); + + result = (nmod_poly_equal(b, g)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(g), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(g); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} + diff --git a/external/flint-2.4.3/nmod_poly/test/t-gcdinv.c b/external/flint-2.4.3/nmod_poly/test/t-gcdinv.c new file mode 100644 index 0000000..969f672 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-gcdinv.c @@ -0,0 +1,154 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + printf("gcdinv...."); + fflush(stdout); + + /* Generic case, most likely co-prime arguments ******************************/ + + /* Compare with result from XGCD */ + for (i = 0; i < 1000; i++) + { + mp_limb_t p; + nmod_poly_t a, b, d, g, s, t, u; + + + p = n_randtest_prime(state, 0); + + nmod_poly_init(a, p); + nmod_poly_init(b, p); + nmod_poly_init(d, p); + nmod_poly_init(g, p); + nmod_poly_init(s, p); + nmod_poly_init(t, p); + nmod_poly_init(u, p); + + nmod_poly_randtest(a, state, n_randint(state, 100)); + do + nmod_poly_randtest(b, state, n_randint(state, 100)); + while (b->length < 2); + + nmod_poly_gcdinv(d, u, a, b); + nmod_poly_xgcd(g, s, t, a, b); + + result = ((nmod_poly_equal(d, g) && nmod_poly_equal(u, s)) + || (nmod_poly_is_zero(d))); + if (!result) + { + printf("FAIL:\n"); + printf("a = "), nmod_poly_print(a), printf("\n\n"); + printf("b = "), nmod_poly_print(b), printf("\n\n"); + printf("d = "), nmod_poly_print(d), printf("\n\n"); + printf("g = "), nmod_poly_print(g), printf("\n\n"); + printf("s = "), nmod_poly_print(s), printf("\n\n"); + printf("t = "), nmod_poly_print(t), printf("\n\n"); + printf("u = "), nmod_poly_print(u), printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(d); + nmod_poly_clear(g); + nmod_poly_clear(s); + nmod_poly_clear(t); + nmod_poly_clear(u); + } + + /* Special case, arguments share a factor ********************************/ + + /* Compare with result from XGCD */ + for (i = 0; i < 1000; i++) + { + mp_limb_t p; + nmod_poly_t a, b, d, f, g, s, t, u; + + p = n_randtest_prime(state, 0); + + nmod_poly_init(a, p); + nmod_poly_init(b, p); + nmod_poly_init(d, p); + nmod_poly_init(f, p); + nmod_poly_init(g, p); + nmod_poly_init(s, p); + nmod_poly_init(t, p); + nmod_poly_init(u, p); + + nmod_poly_randtest(a, state, n_randint(state, 100)); + do + nmod_poly_randtest(b, state, n_randint(state, 100)); + while (b->length < 2); + nmod_poly_randtest_not_zero(f, state, n_randint(state, 20) + 1); + nmod_poly_mul(a, f, a); + nmod_poly_mul(b, f, b); + + nmod_poly_gcdinv(d, u, a, b); + nmod_poly_xgcd(g, s, t, a, b); + + result = ((nmod_poly_equal(d, g) && nmod_poly_equal(u, s)) + || (nmod_poly_is_zero(d))); + if (!result) + { + printf("FAIL:\n"); + printf("a = "), nmod_poly_print(a), printf("\n\n"); + printf("b = "), nmod_poly_print(b), printf("\n\n"); + printf("d = "), nmod_poly_print(d), printf("\n\n"); + printf("f = "), nmod_poly_print(f), printf("\n\n"); + printf("g = "), nmod_poly_print(g), printf("\n\n"); + printf("s = "), nmod_poly_print(s), printf("\n\n"); + printf("t = "), nmod_poly_print(t), printf("\n\n"); + printf("u = "), nmod_poly_print(u), printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(d); + nmod_poly_clear(f); + nmod_poly_clear(g); + nmod_poly_clear(s); + nmod_poly_clear(t); + nmod_poly_clear(u); + } + + FLINT_TEST_CLEANUP(state); + printf("PASS\n"); + return 0; +} + diff --git a/external/flint-2.4.3/nmod_poly/test/t-get_set_coeff_ui.c b/external/flint-2.4.3/nmod_poly/test/t-get_set_coeff_ui.c new file mode 100644 index 0000000..83cb1e6 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-get_set_coeff_ui.c @@ -0,0 +1,75 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + ulong j; + FLINT_TEST_INIT(state); + + + flint_printf("get/set_coeff_ui...."); + fflush(stdout); + + /* Check aliasing of a and b */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t a; + mp_limb_t n = n_randtest_not_zero(state); + mp_limb_t c1 = n_randtest(state), c2; + + j = n_randint(state, 100); + + nmod_poly_init(a, n); + nmod_poly_randtest(a, state, n_randint(state, 100)); + + nmod_poly_set_coeff_ui(a, j, c1); + c2 = nmod_poly_get_coeff_ui(a, j); + + result = (c2 == c1 % n); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("j = %wu, c1 = %wu, c2 = %wu, n = %wu\n", j, c1, c2, a->mod.n); + nmod_poly_print(a), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-get_set_str.c b/external/flint-2.4.3/nmod_poly/test/t-get_set_str.c new file mode 100644 index 0000000..c660a91 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-get_set_str.c @@ -0,0 +1,77 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result, r1; + FLINT_TEST_INIT(state); + + + flint_printf("get/set_str...."); + fflush(stdout); + + /* Check to and from string */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b; + mp_limb_t n = n_randtest_not_zero(state); + char * str; + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_randtest(a, state, n_randint(state, 100)); + + str = nmod_poly_get_str(a); + r1 = nmod_poly_set_str(b, str); + + result = (r1 && nmod_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("r1 = %d, n = %wu\n", r1, a->mod.n); + flint_printf("%s\n", str); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + abort(); + } + + flint_free(str); + nmod_poly_clear(a); + nmod_poly_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-hgcd.c b/external/flint-2.4.3/nmod_poly/test/t-hgcd.c new file mode 100644 index 0000000..9bb9b23 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-hgcd.c @@ -0,0 +1,164 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" +#include "mpn_extras.h" + +#define __mul(C, lenC, A, lenA, B, lenB) \ +do { \ + if ((lenA) != 0 && (lenB) != 0) \ + { \ + if ((lenA) >= (lenB)) \ + _nmod_poly_mul((C), (A), (lenA), (B), (lenB), mod); \ + else \ + _nmod_poly_mul((C), (B), (lenB), (A), (lenA), mod); \ + (lenC) = (lenA) + (lenB) - 1; \ + } \ + else \ + { \ + (lenC) = 0; \ + } \ +} while (0) + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("hgcd...."); + fflush(stdout); + + /* + Find coprime polys, multiply by another poly + and check the GCD is that poly + */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c, d, c1, d1, s, t; + + mp_ptr M[4]; + slong lenM[4]; + slong sgnM; + + mp_limb_t n = n_randprime(state, FLINT_BITS, 0); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(c, n); + nmod_poly_init(d, n); + nmod_poly_init(c1, n); + nmod_poly_init(d1, n); + nmod_poly_init(s, n); + nmod_poly_init(t, n); + + do { + nmod_poly_randtest_not_zero(a, state, n_randint(state, 800) + 1); + nmod_poly_randtest_not_zero(b, state, n_randint(state, 800) + 1); + } while (a->length == b->length); + + if (a->length < b->length) + nmod_poly_swap(a, b); + + M[0] = _nmod_vec_init(a->length); + M[1] = _nmod_vec_init(a->length); + M[2] = _nmod_vec_init(a->length); + M[3] = _nmod_vec_init(a->length); + + nmod_poly_fit_length(c, a->length); + nmod_poly_fit_length(d, b->length); + + sgnM = _nmod_poly_hgcd(M, lenM, + c->coeffs, &(c->length), d->coeffs, &(d->length), + a->coeffs, a->length, b->coeffs, b->length, a->mod); + + nmod_poly_fit_length(s, 2 * a->length); + nmod_poly_fit_length(t, 2 * a->length); + + /* [c1,d1] := sgnM * M^{-1} [a,b] */ + { + const nmod_t mod = a->mod; + + MPN_SWAP(M[0], lenM[0], M[3], lenM[3]); + _nmod_vec_neg(M[1], M[1], lenM[1], mod); + _nmod_vec_neg(M[2], M[2], lenM[2], mod); + + __mul(s->coeffs, s->length, M[0], lenM[0], a->coeffs, a->length); + __mul(t->coeffs, t->length, M[1], lenM[1], b->coeffs, b->length); + nmod_poly_add(c1, s, t); + __mul(s->coeffs, s->length, M[2], lenM[2], a->coeffs, a->length); + __mul(t->coeffs, t->length, M[3], lenM[3], b->coeffs, b->length); + nmod_poly_add(d1, s, t); + } + + if (sgnM < 0) + { + nmod_poly_neg(c1, c1); + nmod_poly_neg(d1, d1); + } + + result = (nmod_poly_equal(c, c1) && nmod_poly_equal(d, d1)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), nmod_poly_print(a), flint_printf("\n\n"); + flint_printf("b = "), nmod_poly_print(b), flint_printf("\n\n"); + flint_printf("c = "), nmod_poly_print(c), flint_printf("\n\n"); + flint_printf("d = "), nmod_poly_print(d), flint_printf("\n\n"); + flint_printf("c1 = "), nmod_poly_print(c1), flint_printf("\n\n"); + flint_printf("d1 = "), nmod_poly_print(d1), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + nmod_poly_clear(d); + nmod_poly_clear(c1); + nmod_poly_clear(d1); + nmod_poly_clear(s); + nmod_poly_clear(t); + + _nmod_vec_clear(M[0]); + _nmod_vec_clear(M[1]); + _nmod_vec_clear(M[2]); + _nmod_vec_clear(M[3]); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} + +#undef __mul + diff --git a/external/flint-2.4.3/nmod_poly/test/t-inflate.c b/external/flint-2.4.3/nmod_poly/test/t-inflate.c new file mode 100644 index 0000000..03a4d2a --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-inflate.c @@ -0,0 +1,93 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int iter; + FLINT_TEST_INIT(state); + + + flint_printf("inflate...."); + fflush(stdout); + + for (iter = 0; iter < 100 * flint_test_multiplier(); iter++) + { + nmod_poly_t poly1, poly2, poly3, xp; + mp_limb_t modulus; + ulong inflation; + + modulus = n_randtest_prime(state, 0); + + nmod_poly_init(poly1, modulus); + nmod_poly_init(poly2, modulus); + nmod_poly_init(poly3, modulus); + nmod_poly_init(xp, modulus); + + nmod_poly_randtest(poly1, state, n_randint(state, 20)); + inflation = n_randint(state, 10); + + nmod_poly_inflate(poly2, poly1, inflation); + + nmod_poly_set_coeff_ui(xp, inflation, 1); + nmod_poly_compose(poly3, poly1, xp); + + if (!nmod_poly_equal(poly2, poly3)) + { + flint_printf("FAIL: not equal to compose (inflation = %wu)\n", inflation); + flint_printf("poly1:\n"); nmod_poly_print(poly1); flint_printf("\n\n"); + flint_printf("poly2:\n"); nmod_poly_print(poly2); flint_printf("\n\n"); + flint_printf("poly3:\n"); nmod_poly_print(poly3); flint_printf("\n\n"); + abort(); + } + + nmod_poly_inflate(poly1, poly1, inflation); + if (!nmod_poly_equal(poly1, poly2)) + { + flint_printf("FAIL: aliasing (inflation = %wu)\n", inflation); + flint_printf("poly1:\n"); nmod_poly_print(poly1); flint_printf("\n\n"); + flint_printf("poly2:\n"); nmod_poly_print(poly2); flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(poly1); + nmod_poly_clear(poly2); + nmod_poly_clear(poly3); + nmod_poly_clear(xp); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-init_realloc_clear.c b/external/flint-2.4.3/nmod_poly/test/t-init_realloc_clear.c new file mode 100644 index 0000000..8b3d5ce --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-init_realloc_clear.c @@ -0,0 +1,77 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("init/init2/realloc/clear...."); + fflush(stdout); + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t a; + mp_limb_t n = n_randtest_not_zero(state); + + nmod_poly_init2(a, n, n_randint(state, 100)); + nmod_poly_clear(a); + } + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t a; + mp_limb_t n = n_randtest_not_zero(state); + + nmod_poly_init2(a, n, n_randint(state, 100)); + nmod_poly_realloc(a, n_randint(state, 100)); + nmod_poly_realloc(a, n_randint(state, 100)); + nmod_poly_clear(a); + } + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t a; + mp_limb_t n = n_randtest_not_zero(state); + + nmod_poly_init(a, n); + nmod_poly_randtest(a, state, n_randint(state, 100)); + nmod_poly_clear(a); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-integral.c b/external/flint-2.4.3/nmod_poly/test/t-integral.c new file mode 100644 index 0000000..7df630b --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-integral.c @@ -0,0 +1,114 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" +#include "fmpz.h" + +int +main(void) +{ + int i, result = 1; + FLINT_TEST_INIT(state); + + + flint_printf("integral...."); + fflush(stdout); + + /* Check with derivative */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c; + ulong len; + mp_limb_t c0; + mp_limb_t n = n_randtest_prime(state, 0); + + len = n_randint(state, 100); + len = FLINT_MIN(len, n - 1); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(c, n); + + nmod_poly_randtest(a, state, len); + + nmod_poly_integral(b, a); + c0 = nmod_poly_get_coeff_ui(b, 0); + nmod_poly_derivative(c, b); + + result = (c0 == UWORD(0)) && nmod_poly_equal(a, c); + + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a->length = %wd, n = %wu\n", a->length, a->mod.n); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(c), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + } + + /* Check aliasing */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b; + mp_limb_t n = n_randtest_prime(state, 0); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_randtest(a, state, n_randint(state, 100)); + + nmod_poly_integral(b, a); + nmod_poly_integral(a, a); + + result = nmod_poly_equal(a, b); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a->length = %wd, n = %wu\n", a->length, a->mod.n); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-interpolate_nmod_vec.c b/external/flint-2.4.3/nmod_poly/test/t-interpolate_nmod_vec.c new file mode 100644 index 0000000..13884e2 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-interpolate_nmod_vec.c @@ -0,0 +1,89 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result = 1; + FLINT_TEST_INIT(state); + + + flint_printf("interpolate_nmod_vec...."); + fflush(stdout); + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t P, Q; + mp_ptr x, y; + mp_limb_t mod; + slong j, n, npoints; + + mod = n_randtest_prime(state, 0); + npoints = n_randint(state, FLINT_MIN(100, mod)); + n = n_randint(state, npoints + 1); + + nmod_poly_init(P, mod); + nmod_poly_init(Q, mod); + x = _nmod_vec_init(npoints); + y = _nmod_vec_init(npoints); + + nmod_poly_randtest(P, state, n); + + for (j = 0; j < npoints; j++) + x[j] = j; + + nmod_poly_evaluate_nmod_vec(y, P, x, npoints); + nmod_poly_interpolate_nmod_vec(Q, x, y, npoints); + + result = nmod_poly_equal(P, Q); + + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("mod=%wu, n=%wd, npoints=%wd\n\n", mod, n, npoints); + nmod_poly_print(P), flint_printf("\n\n"); + nmod_poly_print(Q), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(P); + nmod_poly_clear(Q); + _nmod_vec_clear(x); + _nmod_vec_clear(y); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-interpolate_nmod_vec_barycentric.c b/external/flint-2.4.3/nmod_poly/test/t-interpolate_nmod_vec_barycentric.c new file mode 100644 index 0000000..d23dea1 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-interpolate_nmod_vec_barycentric.c @@ -0,0 +1,91 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" +#include "fmpz.h" + + +int +main(void) +{ + int i, result = 1; + FLINT_TEST_INIT(state); + + + flint_printf("interpolate_nmod_vec_barycentric...."); + fflush(stdout); + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t P, Q; + mp_ptr x, y; + mp_limb_t mod; + slong j, n, npoints; + + mod = n_randtest_prime(state, 0); + npoints = n_randint(state, FLINT_MIN(100, mod)); + n = n_randint(state, npoints + 1); + + nmod_poly_init(P, mod); + nmod_poly_init(Q, mod); + x = _nmod_vec_init(npoints); + y = _nmod_vec_init(npoints); + + nmod_poly_randtest(P, state, n); + + for (j = 0; j < npoints; j++) + x[j] = j; + + nmod_poly_evaluate_nmod_vec(y, P, x, npoints); + nmod_poly_interpolate_nmod_vec_barycentric(Q, x, y, npoints); + + result = nmod_poly_equal(P, Q); + + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("mod=%wu, n=%wd, npoints=%wd\n\n", mod, n, npoints); + nmod_poly_print(P), flint_printf("\n\n"); + nmod_poly_print(Q), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(P); + nmod_poly_clear(Q); + _nmod_vec_clear(x); + _nmod_vec_clear(y); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-interpolate_nmod_vec_fast.c b/external/flint-2.4.3/nmod_poly/test/t-interpolate_nmod_vec_fast.c new file mode 100644 index 0000000..74960d5 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-interpolate_nmod_vec_fast.c @@ -0,0 +1,89 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011, 2012 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result = 1; + FLINT_TEST_INIT(state); + + + flint_printf("interpolate_nmod_vec_fast...."); + fflush(stdout); + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t P, Q; + mp_ptr x, y; + mp_limb_t mod; + slong j, n, npoints; + + mod = n_randtest_prime(state, 0); + npoints = n_randint(state, FLINT_MIN(100, mod)); + n = n_randint(state, npoints + 1); + + nmod_poly_init(P, mod); + nmod_poly_init(Q, mod); + x = _nmod_vec_init(npoints); + y = _nmod_vec_init(npoints); + + nmod_poly_randtest(P, state, n); + + for (j = 0; j < npoints; j++) + x[j] = j; + + nmod_poly_evaluate_nmod_vec_fast(y, P, x, npoints); + nmod_poly_interpolate_nmod_vec_fast(Q, x, y, npoints); + + result = nmod_poly_equal(P, Q); + + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("mod=%wu, n=%wd, npoints=%wd\n\n", mod, n, npoints); + nmod_poly_print(P), flint_printf("\n\n"); + nmod_poly_print(Q), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(P); + nmod_poly_clear(Q); + _nmod_vec_clear(x); + _nmod_vec_clear(y); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-interpolate_nmod_vec_newton.c b/external/flint-2.4.3/nmod_poly/test/t-interpolate_nmod_vec_newton.c new file mode 100644 index 0000000..7c1afb3 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-interpolate_nmod_vec_newton.c @@ -0,0 +1,91 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" +#include "fmpz.h" + + +int +main(void) +{ + int i, result = 1; + FLINT_TEST_INIT(state); + + + flint_printf("interpolate_nmod_vec_newton...."); + fflush(stdout); + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t P, Q; + mp_ptr x, y; + mp_limb_t mod; + slong j, n, npoints; + + mod = n_randtest_prime(state, 0); + npoints = n_randint(state, FLINT_MIN(100, mod)); + n = n_randint(state, npoints + 1); + + nmod_poly_init(P, mod); + nmod_poly_init(Q, mod); + x = _nmod_vec_init(npoints); + y = _nmod_vec_init(npoints); + + nmod_poly_randtest(P, state, n); + + for (j = 0; j < npoints; j++) + x[j] = j; + + nmod_poly_evaluate_nmod_vec(y, P, x, npoints); + nmod_poly_interpolate_nmod_vec_newton(Q, x, y, npoints); + + result = nmod_poly_equal(P, Q); + + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("mod=%wu, n=%wd, npoints=%wd\n\n", mod, n, npoints); + nmod_poly_print(P), flint_printf("\n\n"); + nmod_poly_print(Q), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(P); + nmod_poly_clear(Q); + _nmod_vec_clear(x); + _nmod_vec_clear(y); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-inv_series_basecase.c b/external/flint-2.4.3/nmod_poly/test/t-inv_series_basecase.c new file mode 100644 index 0000000..907f9b4 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-inv_series_basecase.c @@ -0,0 +1,122 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("inv_series_basecase...."); + fflush(stdout); + + /* Check Q * Qinv = 1 mod x^n */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t q, qinv, prod; + slong m; + + mp_limb_t n; + do n = n_randtest_not_zero(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(prod, n); + nmod_poly_init(qinv, n); + nmod_poly_init(q, n); + + do nmod_poly_randtest(q, state, n_randint(state, 2000)); + while (q->length == 0 || q->coeffs[0] == 0); + + m = n_randint(state, q->length) + 1; + + nmod_poly_inv_series_basecase(qinv, q, m); + + nmod_poly_mul(prod, q, qinv); + nmod_poly_truncate(prod, m); + + result = (prod->length == 1 && prod->coeffs[0] == 1); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(q), flint_printf("\n\n"); + nmod_poly_print(qinv), flint_printf("\n\n"); + nmod_poly_print(prod), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(q); + nmod_poly_clear(qinv); + nmod_poly_clear(prod); + } + + /* Check aliasing of q and qinv */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t q, qinv; + slong m; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(q, n); + nmod_poly_init(qinv, n); + do nmod_poly_randtest(q, state, n_randint(state, 1000)); + while (q->length == 0 || q->coeffs[0] == 0); + + m = n_randint(state, q->length) + 1; + + nmod_poly_inv_series_basecase(qinv, q, m); + nmod_poly_inv_series_basecase(q, q, m); + + result = (nmod_poly_equal(q, qinv)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(q), flint_printf("\n\n"); + nmod_poly_print(qinv), flint_printf("\n\n"); + nmod_poly_print(q), flint_printf("\n\n"); + flint_printf("n = %wd, m = %wd\n", n, m); + abort(); + } + + nmod_poly_clear(q); + nmod_poly_clear(qinv); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-inv_series_newton.c b/external/flint-2.4.3/nmod_poly/test/t-inv_series_newton.c new file mode 100644 index 0000000..5847fcc --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-inv_series_newton.c @@ -0,0 +1,122 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("inv_series_newton...."); + fflush(stdout); + + /* Check Q * Qinv = 1 mod x^n */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t q, qinv, prod; + slong m; + + mp_limb_t n; + do n = n_randtest_not_zero(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(prod, n); + nmod_poly_init(qinv, n); + nmod_poly_init(q, n); + + do nmod_poly_randtest(q, state, n_randint(state, 2000)); + while (q->length == 0 || q->coeffs[0] == 0); + + m = n_randint(state, q->length) + 1; + + nmod_poly_inv_series_newton(qinv, q, m); + + nmod_poly_mul(prod, q, qinv); + nmod_poly_truncate(prod, m); + + result = (prod->length == 1 && prod->coeffs[0] == 1); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(q), flint_printf("\n\n"); + nmod_poly_print(qinv), flint_printf("\n\n"); + nmod_poly_print(prod), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(q); + nmod_poly_clear(qinv); + nmod_poly_clear(prod); + } + + /* Check aliasing of q and qinv */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t q, qinv; + slong m; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(q, n); + nmod_poly_init(qinv, n); + do nmod_poly_randtest(q, state, n_randint(state, 1000)); + while (q->length == 0 || q->coeffs[0] == 0); + + m = n_randint(state, q->length) + 1; + + nmod_poly_inv_series_newton(qinv, q, m); + nmod_poly_inv_series_newton(q, q, m); + + result = (nmod_poly_equal(q, qinv)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(q), flint_printf("\n\n"); + nmod_poly_print(qinv), flint_printf("\n\n"); + nmod_poly_print(q), flint_printf("\n\n"); + flint_printf("n = %wd, m = %wd\n", n, m); + abort(); + } + + nmod_poly_clear(q); + nmod_poly_clear(qinv); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-invmod.c b/external/flint-2.4.3/nmod_poly/test/t-invmod.c new file mode 100644 index 0000000..bdf861d --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-invmod.c @@ -0,0 +1,221 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + + FLINT_TEST_INIT(state); + + printf("invmod...."); + fflush(stdout); + + /* Test aliasing *************************************************************/ + + /* Aliasing c and a */ + for (i = 0; i < 500; i++) + { + mp_limb_t p; + nmod_poly_t a, b, c; + int ans1, ans2; + + p = n_randtest_prime(state, 0); + + nmod_poly_init(a, p); + nmod_poly_init(b, p); + nmod_poly_init(c, p); + + do + nmod_poly_randtest(b, state, n_randint(state, 100)); + while (b->length < 3); + nmod_poly_randtest(a, state, n_randint(state, 100)); + + ans1 = nmod_poly_invmod(c, a, b); + ans2 = nmod_poly_invmod(a, a, b); + + result = (ans1 == ans2 && nmod_poly_equal(a, c)); + if (!result) + { + printf("FAIL (alias a and c):\n"); + nmod_poly_print(a), printf("\n\n"); + nmod_poly_print(b), printf("\n\n"); + nmod_poly_print(c), printf("\n\n"); + printf("ans1 = %d\n\n", ans1); + printf("ans2 = %d\n\n", ans2); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + } + + /* Aliasing c and b */ + for (i = 0; i < 500; i++) + { + mp_limb_t p; + nmod_poly_t a, b, c; + int ans1, ans2; + + p = n_randtest_prime(state, 0); + + nmod_poly_init(a, p); + nmod_poly_init(b, p); + nmod_poly_init(c, p); + + do + nmod_poly_randtest(b, state, n_randint(state, 100)); + while (b->length < 3); + nmod_poly_randtest(a, state, n_randint(state, 100)); + + ans1 = nmod_poly_invmod(c, a, b); + ans2 = nmod_poly_invmod(b, a, b); + + result = ((ans1 == ans2) && nmod_poly_equal(b, c)); + if (!result) + { + printf("FAIL (alias b and c):\n"); + nmod_poly_print(a), printf("\n\n"); + nmod_poly_print(b), printf("\n\n"); + nmod_poly_print(c), printf("\n\n"); + printf("ans1 = %d\n\n", ans1); + printf("ans2 = %d\n\n", ans2); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + } + + /* Compare with result from XGCD */ + for (i = 0; i < 1000; i++) + { + mp_limb_t p; + nmod_poly_t a, b, g, s, t, u; + int ans; + + p = n_randtest_prime(state, 0); + + nmod_poly_init(a, p); + nmod_poly_init(b, p); + nmod_poly_init(g, p); + nmod_poly_init(s, p); + nmod_poly_init(t, p); + nmod_poly_init(u, p); + + do + nmod_poly_randtest(b, state, n_randint(state, 100)); + while (b->length < 3); + nmod_poly_randtest(a, state, n_randint(state, 100)); + + ans = nmod_poly_invmod(u, a, b); + nmod_poly_xgcd(g, s, t, a, b); + + result = (((ans) && g->length == 1 + && g->coeffs[0] == WORD(1) && nmod_poly_equal(s, u)) + || (!(ans) && g->length > 1)); + + if (!result) + { + printf("FAIL:\n"); + nmod_poly_print(a), printf("\n\n"); + nmod_poly_print(b), printf("\n\n"); + nmod_poly_print(g), printf("\n\n"); + nmod_poly_print(s), printf("\n\n"); + nmod_poly_print(t), printf("\n\n"); + nmod_poly_print(u), printf("\n\n"); + printf("ans = %d\n\n", ans); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(g); + nmod_poly_clear(s); + nmod_poly_clear(t); + nmod_poly_clear(u); + } + + /* Special case, arguments share a factor ********************************/ + + /* Check correctness */ + for (i = 0; i < 1000; i++) + { + mp_limb_t p; + nmod_poly_t a, b, f, u; + int ans; + + p = n_randtest_prime(state, 0); + + nmod_poly_init(a, p); + nmod_poly_init(b, p); + nmod_poly_init(f, p); + nmod_poly_init(u, p); + + do + nmod_poly_randtest(b, state, n_randint(state, 100)); + while (b->length < 2); + nmod_poly_randtest(a, state, n_randint(state, 100)); + do + nmod_poly_randtest_not_zero(f, state, n_randint(state, 20) + 1); + while (f->length < 2); + nmod_poly_mul(a, f, a); + nmod_poly_mul(b, f, b); + + ans = nmod_poly_invmod(u, a, b); + + result = (!ans); + if (!result) + { + printf("FAIL:\n"); + nmod_poly_print(a), printf("\n\n"); + nmod_poly_print(b), printf("\n\n"); + nmod_poly_print(f), printf("\n\n"); + nmod_poly_print(u), printf("\n\n"); + printf("ans = %d\n\n", ans); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(f); + nmod_poly_clear(u); + } + + FLINT_TEST_CLEANUP(state); + printf("PASS\n"); + return 0; +} + diff --git a/external/flint-2.4.3/nmod_poly/test/t-invsqrt_series.c b/external/flint-2.4.3/nmod_poly/test/t-invsqrt_series.c new file mode 100644 index 0000000..feb7a62 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-invsqrt_series.c @@ -0,0 +1,125 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("invsqrt_series...."); + fflush(stdout); + + /* Check 1/g^2 = h mod x^m */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t h, g, r; + slong m; + + mp_limb_t n; + do n = n_randtest_prime(state, 0); + while (n == UWORD(2)); + + nmod_poly_init(h, n); + nmod_poly_init(g, n); + nmod_poly_init(r, n); + + do nmod_poly_randtest(h, state, n_randint(state, 1000)); + while (h->length == 0); + nmod_poly_set_coeff_ui(h, 0, UWORD(1)); + + m = n_randint(state, h->length) + 1; + + nmod_poly_invsqrt_series(g, h, m); + + nmod_poly_mullow(r, g, g, m); + nmod_poly_inv_series(r, r, m); + nmod_poly_truncate(h, m); + + result = (nmod_poly_equal(r, h)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(h), flint_printf("\n\n"); + nmod_poly_print(g), flint_printf("\n\n"); + nmod_poly_print(r), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(h); + nmod_poly_clear(g); + nmod_poly_clear(r); + } + + /* Check aliasing of h and g */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t g, h; + slong m; + + mp_limb_t n; + do n = n_randtest_prime(state, 0); + while (n == UWORD(2)); + + nmod_poly_init(h, n); + nmod_poly_init(g, n); + do nmod_poly_randtest(h, state, n_randint(state, 500)); + while (h->length == 0); + nmod_poly_set_coeff_ui(h, 0, UWORD(1)); + + m = n_randint(state, h->length) + 1; + + nmod_poly_invsqrt_series(g, h, m); + nmod_poly_invsqrt_series(h, h, m); + + result = (nmod_poly_equal(g, h)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(h), flint_printf("\n\n"); + nmod_poly_print(g), flint_printf("\n\n"); + flint_printf("n = %wd, m = %wd\n", n, m); + abort(); + } + + nmod_poly_clear(g); + nmod_poly_clear(h); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-log_series.c b/external/flint-2.4.3/nmod_poly/test/t-log_series.c new file mode 100644 index 0000000..31a6237 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-log_series.c @@ -0,0 +1,141 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result = 1; + FLINT_TEST_INIT(state); + + + flint_printf("log_series...."); + fflush(stdout); + + /* Check log(AB) = log(A) + log(B) */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t A, B, AB, logA, logB, logAB, S; + slong n; + mp_limb_t mod; + + mod = n_randtest_prime(state, 0); + n = n_randtest(state) % 100; + n = FLINT_MIN(n, mod); + + nmod_poly_init(A, mod); + nmod_poly_init(B, mod); + nmod_poly_init(AB, mod); + nmod_poly_init(logA, mod); + nmod_poly_init(logB, mod); + nmod_poly_init(logAB, mod); + nmod_poly_init(S, mod); + + nmod_poly_randtest(A, state, n_randint(state, 100)); + nmod_poly_set_coeff_ui(A, 0, UWORD(1)); + nmod_poly_randtest(B, state, n_randint(state, 100)); + nmod_poly_set_coeff_ui(B, 0, UWORD(1)); + + if (n_randlimb(state) % 100 == 0) + { + nmod_poly_zero(A); + nmod_poly_set_coeff_ui(A, n_randlimb(state) % (n+5), \ + n_randtest_not_zero(state) % mod); + nmod_poly_set_coeff_ui(A, 0, UWORD(1)); + } + + nmod_poly_log_series(logA, A, n); + nmod_poly_log_series(logB, B, n); + nmod_poly_mul(AB, A, B); + nmod_poly_log_series(logAB, AB, n); + nmod_poly_add(S, logA, logB); + + result = nmod_poly_equal(S, logAB); + + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("n = %wd, mod = %wu\n", n, mod); + flint_printf("A: "); nmod_poly_print(A), flint_printf("\n\n"); + flint_printf("B: "); nmod_poly_print(B), flint_printf("\n\n"); + flint_printf("log(A): "); nmod_poly_print(logA), flint_printf("\n\n"); + flint_printf("log(B): "); nmod_poly_print(logB), flint_printf("\n\n"); + flint_printf("log(AB): "); nmod_poly_print(logAB), flint_printf("\n\n"); + flint_printf("log(A)+log(B): "); nmod_poly_print(S), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(A); + nmod_poly_clear(B); + nmod_poly_clear(AB); + nmod_poly_clear(logA); + nmod_poly_clear(logB); + nmod_poly_clear(logAB); + nmod_poly_clear(S); + } + + /* Check aliasing */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t A, B; + slong n; + mp_limb_t mod; + mod = n_randtest_prime(state, 0); + n = n_randtest(state) % 50; + n = FLINT_MIN(n, mod); + + nmod_poly_init(A, mod); + nmod_poly_init(B, mod); + nmod_poly_randtest(A, state, n_randint(state, 50)); + nmod_poly_set_coeff_ui(A, 0, UWORD(1)); + + nmod_poly_log_series(B, A, n); + nmod_poly_log_series(A, A, n); + + result = nmod_poly_equal(A, B); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(A), flint_printf("\n\n"); + nmod_poly_print(B), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(A); + nmod_poly_clear(B); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-log_series_monomial_ui.c b/external/flint-2.4.3/nmod_poly/test/t-log_series_monomial_ui.c new file mode 100644 index 0000000..3f71897 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-log_series_monomial_ui.c @@ -0,0 +1,91 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result = 1; + FLINT_TEST_INIT(state); + + + flint_printf("log_series_monomial_ui...."); + fflush(stdout); + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t A, logA, res; + slong n; + mp_limb_t mod; + ulong power; + mp_limb_t coeff; + + mod = n_randtest_prime(state, 0); + n = n_randtest(state) % 100; + n = FLINT_MIN(n, mod); + + nmod_poly_init(A, mod); + nmod_poly_init(logA, mod); + nmod_poly_init(res, mod); + + coeff = n_randlimb(state) % mod; + power = 1 + n_randint(state, 2*n + 1); + + nmod_poly_set_coeff_ui(A, 0, UWORD(1)); + nmod_poly_set_coeff_ui(A, power, coeff); + + nmod_poly_log_series(logA, A, n); + nmod_poly_log_series_monomial_ui(res, coeff, power, n); + + result = nmod_poly_equal(logA, res); + + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("n = %wd, mod = %wu\n", n, mod); + flint_printf("power = %wu, coeff = %wu\n", power, coeff); + flint_printf("A: "); nmod_poly_print(A), flint_printf("\n\n"); + flint_printf("log(A): "); nmod_poly_print(logA), flint_printf("\n\n"); + flint_printf("res: "); nmod_poly_print(res), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(A); + nmod_poly_clear(logA); + nmod_poly_clear(res); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-make_monic.c b/external/flint-2.4.3/nmod_poly/test/t-make_monic.c new file mode 100644 index 0000000..ac75fc3 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-make_monic.c @@ -0,0 +1,106 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("make_monic...."); + fflush(stdout); + + /* Check new leading coeff = gcd old leading coeff and modulus */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b; + mp_limb_t n = n_randtest_not_zero(state); + mp_limb_t l; + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + + if (n == 1) continue; + do { nmod_poly_randtest(a, state, n_randint(state, 100) + 1); } while (a->length == 0); + + nmod_poly_make_monic(b, a); + l = n_gcd(a->mod.n, a->coeffs[a->length - 1]); + + result = (l == b->coeffs[b->length - 1]); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("l = %wu, a->lead = %wd, n = %wu\n", + l, a->coeffs[a->length - 1], a->mod.n); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + } + + /* test aliasing */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t a; + mp_limb_t n = n_randtest_not_zero(state); + mp_limb_t l; + + nmod_poly_init(a, n); + + if (n == 1) continue; + do { nmod_poly_randtest(a, state, n_randint(state, 100) + 1); } while (a->length == 0); + + l = n_gcd(a->mod.n, a->coeffs[a->length - 1]); + nmod_poly_make_monic(a, a); + + result = (l == a->coeffs[a->length - 1]); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("l = %wu, a->lead = %wd, n = %wu\n", + l, a->coeffs[a->length - 1], a->mod.n); + nmod_poly_print(a), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-mul.c b/external/flint-2.4.3/nmod_poly/test/t-mul.c new file mode 100644 index 0000000..f375323 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-mul.c @@ -0,0 +1,147 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("mul...."); + fflush(stdout); + + /* Check aliasing of a and b */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c; + + mp_limb_t n = n_randtest_not_zero(state); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(c, n); + nmod_poly_randtest(b, state, n_randint(state, 50)); + nmod_poly_randtest(c, state, n_randint(state, 50)); + + nmod_poly_mul(a, b, c); + nmod_poly_mul(b, b, c); + + result = (nmod_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + } + + /* Check aliasing of a and c */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c; + + mp_limb_t n = n_randtest_not_zero(state); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(c, n); + nmod_poly_randtest(b, state, n_randint(state, 50)); + nmod_poly_randtest(c, state, n_randint(state, 50)); + + nmod_poly_mul(a, b, c); + nmod_poly_mul(c, b, c); + + result = (nmod_poly_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(c), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + } + + /* Check (b*c)+(b*d) = b*(c+d) */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + nmod_poly_t a1, a2, b, c, d; + + mp_limb_t n = n_randtest_not_zero(state); + + nmod_poly_init(a1, n); + nmod_poly_init(a2, n); + nmod_poly_init(b, n); + nmod_poly_init(c, n); + nmod_poly_init(d, n); + nmod_poly_randtest(b, state, n_randint(state, 100)); + nmod_poly_randtest(c, state, n_randint(state, 100)); + nmod_poly_randtest(d, state, n_randint(state, 100)); + + nmod_poly_mul(a1, b, c); + nmod_poly_mul(a2, b, d); + nmod_poly_add(a1, a1, a2); + + nmod_poly_add(c, c, d); + nmod_poly_mul(a2, b, c); + + result = (nmod_poly_equal(a1, a2)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a1), flint_printf("\n\n"); + nmod_poly_print(a2), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a1); + nmod_poly_clear(a2); + nmod_poly_clear(b); + nmod_poly_clear(c); + nmod_poly_clear(d); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-mul_KS.c b/external/flint-2.4.3/nmod_poly/test/t-mul_KS.c new file mode 100644 index 0000000..7ac3769 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-mul_KS.c @@ -0,0 +1,137 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("mul_KS...."); + fflush(stdout); + + /* Check aliasing of a and b */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c; + mp_limb_t n = n_randtest_not_zero(state); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(c, n); + nmod_poly_randtest(b, state, n_randint(state, 50)); + nmod_poly_randtest(c, state, n_randint(state, 50)); + + nmod_poly_mul_KS(a, b, c, 0); + nmod_poly_mul_KS(b, b, c, 0); + + result = (nmod_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + } + + /* Check aliasing of a and c */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c; + mp_limb_t n = n_randtest_not_zero(state); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(c, n); + nmod_poly_randtest(b, state, n_randint(state, 50)); + nmod_poly_randtest(c, state, n_randint(state, 50)); + + nmod_poly_mul_KS(a, b, c, 0); + nmod_poly_mul_KS(c, b, c, 0); + + result = (nmod_poly_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(c), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + } + + /* Compare with mul_classical */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + nmod_poly_t a1, a2, b, c; + mp_limb_t n = n_randtest_not_zero(state); + + nmod_poly_init(a1, n); + nmod_poly_init(a2, n); + nmod_poly_init(b, n); + nmod_poly_init(c, n); + nmod_poly_randtest(b, state, n_randint(state, 50)); + nmod_poly_randtest(c, state, n_randint(state, 50)); + + nmod_poly_mul_classical(a1, b, c); + nmod_poly_mul_KS(a2, b, c, 0); + + result = (nmod_poly_equal(a1, a2)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a1), flint_printf("\n\n"); + nmod_poly_print(a2), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a1); + nmod_poly_clear(a2); + nmod_poly_clear(b); + nmod_poly_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-mul_KS2.c b/external/flint-2.4.3/nmod_poly/test/t-mul_KS2.c new file mode 100644 index 0000000..56d899a --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-mul_KS2.c @@ -0,0 +1,170 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +#pragma GCC diagnostic ignored "-Woverlength-strings" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("mul_KS2...."); + fflush(stdout); + + /* Check aliasing of a and b */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c; + mp_limb_t n = n_randtest_not_zero(state); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(c, n); + nmod_poly_randtest(b, state, n_randint(state, 50)); + nmod_poly_randtest(c, state, n_randint(state, 50)); + + nmod_poly_mul_KS2(a, b, c); + nmod_poly_mul_KS2(b, b, c); + + result = (nmod_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + } + + /* Check aliasing of a and c */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c; + mp_limb_t n = n_randtest_not_zero(state); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(c, n); + nmod_poly_randtest(b, state, n_randint(state, 50)); + nmod_poly_randtest(c, state, n_randint(state, 50)); + + nmod_poly_mul_KS2(a, b, c); + nmod_poly_mul_KS2(c, b, c); + + result = (nmod_poly_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(c), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + } + + /* Compare with mul_classical */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + nmod_poly_t a1, a2, b, c; + mp_limb_t n = n_randtest_not_zero(state); + + nmod_poly_init(a1, n); + nmod_poly_init(a2, n); + nmod_poly_init(b, n); + nmod_poly_init(c, n); + nmod_poly_randtest(b, state, n_randint(state, 50)); + nmod_poly_randtest(c, state, n_randint(state, 50)); + + nmod_poly_mul_classical(a1, b, c); + nmod_poly_mul_KS2(a2, b, c); + + result = (nmod_poly_equal(a1, a2)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a1), flint_printf("\n\n"); + nmod_poly_print(a2), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a1); + nmod_poly_clear(a2); + nmod_poly_clear(b); + nmod_poly_clear(c); + } + + /* Test bug */ +#if FLINT64 + { + nmod_poly_t a, b, c, d; + mp_limb_t mod = UWORD(2289285083314003039); + + nmod_poly_init(a, mod); + nmod_poly_init(b, mod); + nmod_poly_init(c, mod); + nmod_poly_init(d, mod); + + nmod_poly_set_str(a, "33 1904046980750977501 45214318121847844 54776012950656710 1873599154826904295 870135259339956207 1979537227904177235 1077518167660740425 1914467488553877071 590032441505981152 615648453231634975 1569207985886566133 787136232386763586 263398180027397052 1072218041043012468 1506848477788670239 1400920451698857943 1647489479045838018 916805681536849287 418919486780459023 1905019227786610376 521214770020411309 1686949157600795332 1694792566051380615 859359964104912916 379633023194464188 1707896212900599917 2116886930226258819 1784312697572836983 1657809908840472396 187671865737908075 24295635882237532 1236324514297047805 1"); + + nmod_poly_set_str(b, "33 1248232897348310716 2007649684622883320 1745423566053694824 377131386390909586 510000530211074748 2252357745328136405 121845726568848648 1776552397423576952 1087867787512095029 1542258909416820365 333466255708033066 1369137418799234940 1019757368632255267 1708944472854199555 424720899313432606 1832061349660947209 1680133579237359807 1011480105427615896 469487889066997171 250011917413341143 1528554661920601095 1534412092525363608 1513772824610977843 1546061195142719878 2202390411223099645 1876123527101934779 777483746883723994 1298099847659446396 1845415258502877349 82593368833294076 7103430832858844 1414221645839662896 1"); + + nmod_poly_mul_classical(c, a, b); + nmod_poly_mul_KS2(d, a, b); + + if (!nmod_poly_equal(c, d)) + { + flint_printf("FAIL: NMOD_RED2 bug!\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + nmod_poly_clear(d); + } +#endif + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-mul_KS4.c b/external/flint-2.4.3/nmod_poly/test/t-mul_KS4.c new file mode 100644 index 0000000..2616727 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-mul_KS4.c @@ -0,0 +1,170 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +#pragma GCC diagnostic ignored "-Woverlength-strings" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("mul_KS4...."); + fflush(stdout); + + /* Check aliasing of a and b */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c; + mp_limb_t n = n_randtest_not_zero(state); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(c, n); + nmod_poly_randtest(b, state, n_randint(state, 50)); + nmod_poly_randtest(c, state, n_randint(state, 50)); + + nmod_poly_mul_KS4(a, b, c); + nmod_poly_mul_KS4(b, b, c); + + result = (nmod_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + } + + /* Check aliasing of a and c */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c; + mp_limb_t n = n_randtest_not_zero(state); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(c, n); + nmod_poly_randtest(b, state, n_randint(state, 50)); + nmod_poly_randtest(c, state, n_randint(state, 50)); + + nmod_poly_mul_KS4(a, b, c); + nmod_poly_mul_KS4(c, b, c); + + result = (nmod_poly_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(c), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + } + + /* Compare with mul_classical */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + nmod_poly_t a1, a2, b, c; + mp_limb_t n = n_randtest_not_zero(state); + + nmod_poly_init(a1, n); + nmod_poly_init(a2, n); + nmod_poly_init(b, n); + nmod_poly_init(c, n); + nmod_poly_randtest(b, state, n_randint(state, 50)); + nmod_poly_randtest(c, state, n_randint(state, 50)); + + nmod_poly_mul_classical(a1, b, c); + nmod_poly_mul_KS4(a2, b, c); + + result = (nmod_poly_equal(a1, a2)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a1), flint_printf("\n\n"); + nmod_poly_print(a2), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a1); + nmod_poly_clear(a2); + nmod_poly_clear(b); + nmod_poly_clear(c); + } + + /* Test bug */ +#if FLINT64 + { + nmod_poly_t a, b, c, d; + mp_limb_t mod = UWORD(2289285083314003039); + + nmod_poly_init(a, mod); + nmod_poly_init(b, mod); + nmod_poly_init(c, mod); + nmod_poly_init(d, mod); + + nmod_poly_set_str(a, "33 1904046980750977501 45214318121847844 54776012950656710 1873599154826904295 870135259339956207 1979537227904177235 1077518167660740425 1914467488553877071 590032441505981152 615648453231634975 1569207985886566133 787136232386763586 263398180027397052 1072218041043012468 1506848477788670239 1400920451698857943 1647489479045838018 916805681536849287 418919486780459023 1905019227786610376 521214770020411309 1686949157600795332 1694792566051380615 859359964104912916 379633023194464188 1707896212900599917 2116886930226258819 1784312697572836983 1657809908840472396 187671865737908075 24295635882237532 1236324514297047805 1"); + + nmod_poly_set_str(b, "33 1248232897348310716 2007649684622883320 1745423566053694824 377131386390909586 510000530211074748 2252357745328136405 121845726568848648 1776552397423576952 1087867787512095029 1542258909416820365 333466255708033066 1369137418799234940 1019757368632255267 1708944472854199555 424720899313432606 1832061349660947209 1680133579237359807 1011480105427615896 469487889066997171 250011917413341143 1528554661920601095 1534412092525363608 1513772824610977843 1546061195142719878 2202390411223099645 1876123527101934779 777483746883723994 1298099847659446396 1845415258502877349 82593368833294076 7103430832858844 1414221645839662896 1"); + + nmod_poly_mul_classical(c, a, b); + nmod_poly_mul_KS4(d, a, b); + + if (!nmod_poly_equal(c, d)) + { + flint_printf("FAIL: NMOD_RED2 bug!\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + nmod_poly_clear(d); + } +#endif + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-mul_classical.c b/external/flint-2.4.3/nmod_poly/test/t-mul_classical.c new file mode 100644 index 0000000..df35304 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-mul_classical.c @@ -0,0 +1,147 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("mul_classical...."); + fflush(stdout); + + /* Check aliasing of a and b */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c; + + mp_limb_t n = n_randtest_not_zero(state); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(c, n); + nmod_poly_randtest(b, state, n_randint(state, 50)); + nmod_poly_randtest(c, state, n_randint(state, 50)); + + nmod_poly_mul_classical(a, b, c); + nmod_poly_mul_classical(b, b, c); + + result = (nmod_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + } + + /* Check aliasing of a and c */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c; + + mp_limb_t n = n_randtest_not_zero(state); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(c, n); + nmod_poly_randtest(b, state, n_randint(state, 50)); + nmod_poly_randtest(c, state, n_randint(state, 50)); + + nmod_poly_mul_classical(a, b, c); + nmod_poly_mul_classical(c, b, c); + + result = (nmod_poly_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(c), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + } + + /* Check (b*c)+(b*d) = b*(c+d) */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + nmod_poly_t a1, a2, b, c, d; + + mp_limb_t n = n_randtest_not_zero(state); + + nmod_poly_init(a1, n); + nmod_poly_init(a2, n); + nmod_poly_init(b, n); + nmod_poly_init(c, n); + nmod_poly_init(d, n); + nmod_poly_randtest(b, state, n_randint(state, 50)); + nmod_poly_randtest(c, state, n_randint(state, 50)); + nmod_poly_randtest(d, state, n_randint(state, 50)); + + nmod_poly_mul_classical(a1, b, c); + nmod_poly_mul_classical(a2, b, d); + nmod_poly_add(a1, a1, a2); + + nmod_poly_add(c, c, d); + nmod_poly_mul_classical(a2, b, c); + + result = (nmod_poly_equal(a1, a2)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a1), flint_printf("\n\n"); + nmod_poly_print(a2), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a1); + nmod_poly_clear(a2); + nmod_poly_clear(b); + nmod_poly_clear(c); + nmod_poly_clear(d); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-mulhigh.c b/external/flint-2.4.3/nmod_poly/test/t-mulhigh.c new file mode 100644 index 0000000..7ab5f76 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-mulhigh.c @@ -0,0 +1,89 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("mulhigh...."); + fflush(stdout); + + /* Compare with left truncated product of a and b */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c; + slong j, n; + + mp_limb_t m = n_randtest_not_zero(state); + + nmod_poly_init(a, m); + nmod_poly_init(b, m); + nmod_poly_init(c, m); + n = n_randint(state, 50); + nmod_poly_randtest(b, state, n); + nmod_poly_randtest(c, state, n); + + nmod_poly_mulhigh(a, b, c, n); + nmod_poly_mul(b, b, c); + for (j = 0; j < n; j++) + { + if (j < a->length) + a->coeffs[j] = 0; + if (j < b->length) + b->coeffs[j] = 0; + } + _nmod_poly_normalise(a); + _nmod_poly_normalise(b); + + result = (nmod_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-mulhigh_classical.c b/external/flint-2.4.3/nmod_poly/test/t-mulhigh_classical.c new file mode 100644 index 0000000..3980bd7 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-mulhigh_classical.c @@ -0,0 +1,176 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("mulhigh_classical...."); + fflush(stdout); + + /* Check aliasing of a and b */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c; + slong j, start; + + mp_limb_t n = n_randtest_not_zero(state); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(c, n); + nmod_poly_randtest(b, state, n_randint(state, 50)); + nmod_poly_randtest(c, state, n_randint(state, 50)); + start = n_randint(state, 50); + + nmod_poly_mulhigh_classical(a, b, c, start); + nmod_poly_mulhigh_classical(b, b, c, start); + + for (j = 0; j < start; j++) + { + if (j < a->length) + a->coeffs[j] = 0; + if (j < b->length) + b->coeffs[j] = 0; + } + _nmod_poly_normalise(a); + _nmod_poly_normalise(b); + + result = (nmod_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + } + + /* Check aliasing of a and c */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c; + slong j, start; + mp_limb_t n = n_randtest_not_zero(state); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(c, n); + nmod_poly_randtest(b, state, n_randint(state, 50)); + nmod_poly_randtest(c, state, n_randint(state, 50)); + start = n_randint(state, 50); + + nmod_poly_mulhigh_classical(a, b, c, start); + nmod_poly_mulhigh_classical(c, b, c, start); + + for (j = 0; j < start; j++) + { + if (j < a->length) + a->coeffs[j] = 0; + if (j < c->length) + c->coeffs[j] = 0; + } + _nmod_poly_normalise(a); + _nmod_poly_normalise(c); + + result = (nmod_poly_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(c), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + } + + /* Compare with mul_basecase */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c, d; + slong j, start; + mp_limb_t n = n_randtest_not_zero(state); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(c, n); + nmod_poly_init(d, n); + nmod_poly_randtest(b, state, n_randint(state, 50)); + nmod_poly_randtest(c, state, n_randint(state, 50)); + start = n_randint(state, 50); + + nmod_poly_mul_classical(a, b, c); + nmod_poly_mulhigh_classical(d, b, c, start); + + for (j = 0; j < start; j++) + { + if (j < a->length) + a->coeffs[j] = 0; + if (j < d->length) + d->coeffs[j] = 0; + } + _nmod_poly_normalise(a); + _nmod_poly_normalise(d); + + result = (nmod_poly_equal(a, d)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(c), flint_printf("\n\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(d), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + nmod_poly_clear(d); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-mullow.c b/external/flint-2.4.3/nmod_poly/test/t-mullow.c new file mode 100644 index 0000000..1f783da --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-mullow.c @@ -0,0 +1,80 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("mullow...."); + fflush(stdout); + + /* Compare with truncated product of a and b */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c; + slong trunc; + mp_limb_t n = n_randtest_not_zero(state); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(c, n); + trunc = n_randint(state, 50); + nmod_poly_randtest(b, state, trunc); + nmod_poly_randtest(c, state, trunc); + + nmod_poly_mullow(a, b, c, trunc); + nmod_poly_mul(b, b, c); + nmod_poly_truncate(b, trunc); + + result = (nmod_poly_equal(a, b)); + if (!result) + { + flint_printf(":\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-mullow_KS.c b/external/flint-2.4.3/nmod_poly/test/t-mullow_KS.c new file mode 100644 index 0000000..b2db6de --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-mullow_KS.c @@ -0,0 +1,149 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("mullow_KS...."); + fflush(stdout); + + /* Check aliasing of a and b */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c; + mp_limb_t n = n_randtest_not_zero(state); + slong trunc = 0; + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(c, n); + nmod_poly_randtest(b, state, n_randint(state, 50)); + nmod_poly_randtest(c, state, n_randint(state, 50)); + + if (b->length > 0 && c->length > 0) + trunc = n_randint(state, b->length + c->length); + + nmod_poly_mullow_KS(a, b, c, 0, trunc); + nmod_poly_mullow_KS(b, b, c, 0, trunc); + + result = (nmod_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + } + + /* Check aliasing of a and c */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c; + mp_limb_t n = n_randtest_not_zero(state); + slong trunc = 0; + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(c, n); + nmod_poly_randtest(b, state, n_randint(state, 50)); + nmod_poly_randtest(c, state, n_randint(state, 50)); + + if (b->length > 0 && c->length > 0) + trunc = n_randint(state, b->length + c->length); + + nmod_poly_mullow_KS(a, b, c, 0, trunc); + nmod_poly_mullow_KS(c, b, c, 0, trunc); + + result = (nmod_poly_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(c), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + } + + /* Compare with mul_classical */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + nmod_poly_t a1, a2, b, c; + mp_limb_t n = n_randtest_not_zero(state); + slong trunc = 0; + + nmod_poly_init(a1, n); + nmod_poly_init(a2, n); + nmod_poly_init(b, n); + nmod_poly_init(c, n); + nmod_poly_randtest(b, state, n_randint(state, 50)); + nmod_poly_randtest(c, state, n_randint(state, 50)); + + if (b->length > 0 && c->length > 0) + trunc = n_randint(state, b->length + c->length); + + nmod_poly_mullow_classical(a1, b, c, trunc); + nmod_poly_mullow_KS(a2, b, c, 0, trunc); + + result = (nmod_poly_equal(a1, a2)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a1), flint_printf("\n\n"); + nmod_poly_print(a2), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a1); + nmod_poly_clear(a2); + nmod_poly_clear(b); + nmod_poly_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-mullow_classical.c b/external/flint-2.4.3/nmod_poly/test/t-mullow_classical.c new file mode 100644 index 0000000..fd70ee5 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-mullow_classical.c @@ -0,0 +1,159 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("mullow_classical...."); + fflush(stdout); + + /* Check aliasing of a and b */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c; + slong len, trunc; + mp_limb_t n = n_randtest_not_zero(state); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(c, n); + nmod_poly_randtest(b, state, n_randint(state, 50)); + nmod_poly_randtest(c, state, n_randint(state, 50)); + + len = b->length + c->length - 1; + if (len <= 0) + trunc = 0; + else + trunc = n_randint(state, b->length + c->length); + + nmod_poly_mullow_classical(a, b, c, trunc); + nmod_poly_mullow_classical(b, b, c, trunc); + + result = (nmod_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + } + + /* Check aliasing of a and c */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c; + slong len, trunc; + mp_limb_t n = n_randtest_not_zero(state); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(c, n); + nmod_poly_randtest(b, state, n_randint(state, 50)); + nmod_poly_randtest(c, state, n_randint(state, 50)); + + len = b->length + c->length - 1; + if (len <= 0) + trunc = 0; + else + trunc = n_randint(state, b->length + c->length - 1); + + nmod_poly_mullow_classical(a, b, c, trunc); + nmod_poly_mullow_classical(c, b, c, trunc); + + result = (nmod_poly_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(c), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + } + + /* Compare with mul_basecase */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c, d; + slong len, trunc; + mp_limb_t n = n_randtest_not_zero(state); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(c, n); + nmod_poly_init(d, n); + nmod_poly_randtest(b, state, n_randint(state, 50)); + nmod_poly_randtest(c, state, n_randint(state, 50)); + + len = b->length + c->length - 1; + if (len <= 0) + trunc = 0; + else + trunc = n_randint(state, b->length + c->length - 1); + + nmod_poly_mul_classical(a, b, c); + nmod_poly_truncate(a, trunc); + nmod_poly_mullow_classical(d, b, c, trunc); + + result = (nmod_poly_equal(a, d)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(d), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + nmod_poly_clear(d); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-mulmod.c b/external/flint-2.4.3/nmod_poly/test/t-mulmod.c new file mode 100644 index 0000000..45d2b89 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-mulmod.c @@ -0,0 +1,213 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("mulmod...."); + fflush(stdout); + + /* Aliasing res and a */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, res, t, f; + + mp_limb_t n = n_randtest_prime(state, 0); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(f, n); + nmod_poly_init(res, n); + nmod_poly_init(t, n); + + nmod_poly_randtest(a, state, n_randint(state, 50)); + nmod_poly_randtest(b, state, n_randint(state, 50)); + do { + nmod_poly_randtest(f, state, n_randint(state, 50)); + } while (nmod_poly_is_zero(f)); + + nmod_poly_mulmod(res, a, b, f); + nmod_poly_mulmod(a, a, b, f); + + result = (nmod_poly_equal(res, a)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); nmod_poly_print(a), flint_printf("\n\n"); + flint_printf("b:\n"); nmod_poly_print(b), flint_printf("\n\n"); + flint_printf("f:\n"); nmod_poly_print(f), flint_printf("\n\n"); + flint_printf("res1:\n"); nmod_poly_print(res), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(f); + nmod_poly_clear(res); + nmod_poly_clear(t); + } + + /* Aliasing res and b */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, res, t, f; + + mp_limb_t n = n_randtest_prime(state, 0); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(f, n); + nmod_poly_init(res, n); + nmod_poly_init(t, n); + + nmod_poly_randtest(a, state, n_randint(state, 50)); + nmod_poly_randtest(b, state, n_randint(state, 50)); + do { + nmod_poly_randtest(f, state, n_randint(state, 50)); + } while (nmod_poly_is_zero(f)); + + nmod_poly_mulmod(res, a, b, f); + nmod_poly_mulmod(b, a, b, f); + + result = (nmod_poly_equal(res, b)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); nmod_poly_print(a), flint_printf("\n\n"); + flint_printf("b:\n"); nmod_poly_print(b), flint_printf("\n\n"); + flint_printf("f:\n"); nmod_poly_print(f), flint_printf("\n\n"); + flint_printf("res1:\n"); nmod_poly_print(res), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(f); + nmod_poly_clear(res); + nmod_poly_clear(t); + } + + /* Aliasing res and f */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, res, t, f; + + mp_limb_t n = n_randtest_prime(state, 0); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(f, n); + nmod_poly_init(res, n); + nmod_poly_init(t, n); + + nmod_poly_randtest(a, state, n_randint(state, 50)); + nmod_poly_randtest(b, state, n_randint(state, 50)); + do { + nmod_poly_randtest(f, state, n_randint(state, 50)); + } while (nmod_poly_is_zero(f)); + + nmod_poly_mulmod(res, a, b, f); + nmod_poly_mulmod(f, a, b, f); + + result = (nmod_poly_equal(res, f)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); nmod_poly_print(a), flint_printf("\n\n"); + flint_printf("b:\n"); nmod_poly_print(b), flint_printf("\n\n"); + flint_printf("f:\n"); nmod_poly_print(f), flint_printf("\n\n"); + flint_printf("res1:\n"); nmod_poly_print(res), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(f); + nmod_poly_clear(res); + nmod_poly_clear(t); + } + + /* No aliasing */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, res1, res2, t, f; + + mp_limb_t n = n_randtest_prime(state, 0); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(f, n); + nmod_poly_init(res1, n); + nmod_poly_init(res2, n); + nmod_poly_init(t, n); + + nmod_poly_randtest(a, state, n_randint(state, 50)); + nmod_poly_randtest(b, state, n_randint(state, 50)); + do { + nmod_poly_randtest(f, state, n_randint(state, 50)); + } while (nmod_poly_is_zero(f)); + + nmod_poly_mulmod(res1, a, b, f); + nmod_poly_mul(res2, a, b); + nmod_poly_divrem(t, res2, res2, f); + + result = (nmod_poly_equal(res1, res2)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); nmod_poly_print(a), flint_printf("\n\n"); + flint_printf("b:\n"); nmod_poly_print(b), flint_printf("\n\n"); + flint_printf("f:\n"); nmod_poly_print(f), flint_printf("\n\n"); + flint_printf("res1:\n"); nmod_poly_print(res1), flint_printf("\n\n"); + flint_printf("res2:\n"); nmod_poly_print(res2), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(f); + nmod_poly_clear(res1); + nmod_poly_clear(res2); + nmod_poly_clear(t); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-mulmod_preinv.c b/external/flint-2.4.3/nmod_poly/test/t-mulmod_preinv.c new file mode 100644 index 0000000..1d0a924 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-mulmod_preinv.c @@ -0,0 +1,301 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + Copyright (C) 2013 Martin Lee + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("mulmod_preinv...."); + fflush(stdout); + + /* Aliasing res and a */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, res, t, f, finv; + + mp_limb_t n = n_randtest_prime(state, 0); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(f, n); + nmod_poly_init(finv, n); + nmod_poly_init(res, n); + nmod_poly_init(t, n); + + nmod_poly_randtest(a, state, n_randint(state, 50)); + nmod_poly_randtest(b, state, n_randint(state, 50)); + do { + nmod_poly_randtest(f, state, n_randint(state, 50)); + } while (nmod_poly_is_zero(f)); + if (a->length >= f->length) + nmod_poly_rem (a, a, f); + if (b->length >= f->length) + nmod_poly_rem (b, b, f); + + nmod_poly_reverse(finv, f, f->length); + nmod_poly_inv_series(finv, finv, f->length); + + nmod_poly_mulmod_preinv(res, a, b, f, finv); + nmod_poly_mulmod_preinv(a, a, b, f, finv); + + result = (nmod_poly_equal(res, a)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); nmod_poly_print(a), flint_printf("\n\n"); + flint_printf("b:\n"); nmod_poly_print(b), flint_printf("\n\n"); + flint_printf("f:\n"); nmod_poly_print(f), flint_printf("\n\n"); + flint_printf("res1:\n"); nmod_poly_print(res), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(f); + nmod_poly_clear(finv); + nmod_poly_clear(res); + nmod_poly_clear(t); + } + + /* Aliasing res and b */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, res, t, f, finv; + + mp_limb_t n = n_randtest_prime(state, 0); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(f, n); + nmod_poly_init(finv, n); + nmod_poly_init(res, n); + nmod_poly_init(t, n); + + nmod_poly_randtest(a, state, n_randint(state, 50)); + nmod_poly_randtest(b, state, n_randint(state, 50)); + do { + nmod_poly_randtest(f, state, n_randint(state, 50)); + } while (nmod_poly_is_zero(f)); + if (a->length >= f->length) + nmod_poly_rem (a, a, f); + if (b->length >= f->length) + nmod_poly_rem (b, b, f); + + nmod_poly_reverse(finv, f, f->length); + nmod_poly_inv_series(finv, finv, f->length); + + nmod_poly_mulmod_preinv(res, a, b, f, finv); + nmod_poly_mulmod_preinv(b, a, b, f, finv); + + result = (nmod_poly_equal(res, b)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); nmod_poly_print(a), flint_printf("\n\n"); + flint_printf("b:\n"); nmod_poly_print(b), flint_printf("\n\n"); + flint_printf("f:\n"); nmod_poly_print(f), flint_printf("\n\n"); + flint_printf("res1:\n"); nmod_poly_print(res), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(f); + nmod_poly_clear(finv); + nmod_poly_clear(res); + nmod_poly_clear(t); + } + + /* Aliasing res and f */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, res, t, f, finv; + + mp_limb_t n = n_randtest_prime(state, 0); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(f, n); + nmod_poly_init(finv, n); + nmod_poly_init(res, n); + nmod_poly_init(t, n); + + nmod_poly_randtest(a, state, n_randint(state, 50)); + nmod_poly_randtest(b, state, n_randint(state, 50)); + do { + nmod_poly_randtest(f, state, n_randint(state, 50)); + } while (nmod_poly_is_zero(f)); + if (a->length >= f->length) + nmod_poly_rem (a, a, f); + if (b->length >= f->length) + nmod_poly_rem (b, b, f); + + nmod_poly_reverse(finv, f, f->length); + nmod_poly_inv_series(finv, finv, f->length); + + nmod_poly_mulmod_preinv(res, a, b, f, finv); + nmod_poly_mulmod_preinv(f, a, b, f, finv); + + result = (nmod_poly_equal(res, f)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); nmod_poly_print(a), flint_printf("\n\n"); + flint_printf("b:\n"); nmod_poly_print(b), flint_printf("\n\n"); + flint_printf("f:\n"); nmod_poly_print(f), flint_printf("\n\n"); + flint_printf("res1:\n"); nmod_poly_print(res), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(f); + nmod_poly_clear(finv); + nmod_poly_clear(res); + nmod_poly_clear(t); + } + + /* Aliasing res and finv */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, res, t, f, finv; + + mp_limb_t n = n_randtest_prime(state, 0); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(f, n); + nmod_poly_init(finv, n); + nmod_poly_init(res, n); + nmod_poly_init(t, n); + + nmod_poly_randtest(a, state, n_randint(state, 50)); + nmod_poly_randtest(b, state, n_randint(state, 50)); + do { + nmod_poly_randtest(f, state, n_randint(state, 50)); + } while (nmod_poly_is_zero(f)); + if (a->length >= f->length) + nmod_poly_rem (a, a, f); + if (b->length >= f->length) + nmod_poly_rem (b, b, f); + + nmod_poly_reverse(finv, f, f->length); + nmod_poly_inv_series(finv, finv, f->length); + + nmod_poly_mulmod_preinv(res, a, b, f, finv); + nmod_poly_mulmod_preinv(finv, a, b, f, finv); + + result = (nmod_poly_equal(res, finv)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); nmod_poly_print(a), flint_printf("\n\n"); + flint_printf("b:\n"); nmod_poly_print(b), flint_printf("\n\n"); + flint_printf("f:\n"); nmod_poly_print(f), flint_printf("\n\n"); + flint_printf("finv:\n"); nmod_poly_print(finv), flint_printf("\n\n"); + flint_printf("res1:\n"); nmod_poly_print(res), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(f); + nmod_poly_clear(finv); + nmod_poly_clear(res); + nmod_poly_clear(t); + } + + /* No aliasing */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, res1, res2, t, f, finv; + + mp_limb_t n = n_randtest_prime(state, 0); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(f, n); + nmod_poly_init(finv, n); + nmod_poly_init(res1, n); + nmod_poly_init(res2, n); + nmod_poly_init(t, n); + + nmod_poly_randtest(a, state, n_randint(state, 50)); + nmod_poly_randtest(b, state, n_randint(state, 50)); + do { + nmod_poly_randtest(f, state, n_randint(state, 50)); + } while (nmod_poly_is_zero(f)); + if (a->length >= f->length) + nmod_poly_rem (a, a, f); + if (b->length >= f->length) + nmod_poly_rem (b, b, f); + + nmod_poly_reverse(finv, f, f->length); + nmod_poly_inv_series(finv, finv, f->length); + + nmod_poly_mulmod_preinv(res1, a, b, f, finv); + + nmod_poly_mul(res2, a, b); + nmod_poly_divrem(t, res2, res2, f); + + result = (nmod_poly_equal(res1, res2)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); nmod_poly_print(a), flint_printf("\n\n"); + flint_printf("b:\n"); nmod_poly_print(b), flint_printf("\n\n"); + flint_printf("f:\n"); nmod_poly_print(f), flint_printf("\n\n"); + flint_printf("res1:\n"); nmod_poly_print(res1), flint_printf("\n\n"); + flint_printf("res2:\n"); nmod_poly_print(res2), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(f); + nmod_poly_clear(finv); + nmod_poly_clear(res1); + nmod_poly_clear(res2); + nmod_poly_clear(t); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-neg.c b/external/flint-2.4.3/nmod_poly/test/t-neg.c new file mode 100644 index 0000000..a4a0b50 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-neg.c @@ -0,0 +1,74 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("neg...."); + fflush(stdout); + + /* Check neg neg a == a */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b; + mp_limb_t n = n_randtest_not_zero(state); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_randtest(a, state, n_randint(state, 100)); + + nmod_poly_neg(b, a); + nmod_poly_neg(b, b); + + result = (nmod_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a->length = %wd, n = %wu\n", a->length, a->mod.n); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-pow.c b/external/flint-2.4.3/nmod_poly/test/t-pow.c new file mode 100644 index 0000000..2070b01 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-pow.c @@ -0,0 +1,117 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, j, result; + FLINT_TEST_INIT(state); + + + flint_printf("pow...."); + fflush(stdout); + + /* Check powering against naive method */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c; + mp_limb_t n = n_randtest_not_zero(state); + slong e; + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(c, n); + nmod_poly_randtest(a, state, n_randint(state, 30)); + e = n_randint(state, 20); + + nmod_poly_pow(b, a, e); + + nmod_poly_set_coeff_ui(c, 0, 1); + for (j = 0; j < e; j++) + nmod_poly_mul(c, c, a); + + result = (nmod_poly_equal(b, c) + || (a->length == 0 && e == 0 && c->length == 1 && c->coeffs[0] == 1)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a->length = %wd, n = %wu, exp = %wd\n", a->length, a->mod.n, e); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(c), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + } + + /* Check aliasing */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c; + mp_limb_t n = n_randtest_not_zero(state); + slong e; + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(c, n); + nmod_poly_randtest(a, state, n_randint(state, 30)); + e = n_randint(state, 20); + + nmod_poly_pow(b, a, e); + + nmod_poly_set(c, a); + nmod_poly_pow(c, c, e); + + result = (nmod_poly_equal(b, c)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a->length = %wd, n = %wu, exp = %wd\n", a->length, a->mod.n, e); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(c), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-pow_binexp.c b/external/flint-2.4.3/nmod_poly/test/t-pow_binexp.c new file mode 100644 index 0000000..98b6db6 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-pow_binexp.c @@ -0,0 +1,117 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, j, result; + FLINT_TEST_INIT(state); + + + flint_printf("pow_binexp...."); + fflush(stdout); + + /* Check powering against naive method */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c; + mp_limb_t n = n_randtest_not_zero(state); + slong e; + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(c, n); + nmod_poly_randtest(a, state, n_randint(state, 30)); + e = n_randint(state, 20); + + nmod_poly_pow_binexp(b, a, e); + + nmod_poly_set_coeff_ui(c, 0, 1); + for (j = 0; j < e; j++) + nmod_poly_mul(c, c, a); + + result = (nmod_poly_equal(b, c) + || (a->length == 0 && e == 0 && c->length == 1 && c->coeffs[0] == 1)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a->length = %wd, n = %wu, exp = %wd\n", a->length, a->mod.n, e); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(c), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + } + + /* Check aliasing */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c; + mp_limb_t n = n_randtest_not_zero(state); + slong e; + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(c, n); + nmod_poly_randtest(a, state, n_randint(state, 30)); + e = n_randint(state, 20); + + nmod_poly_pow_binexp(b, a, e); + + nmod_poly_set(c, a); + nmod_poly_pow_binexp(c, c, e); + + result = (nmod_poly_equal(b, c)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a->length = %wd, n = %wu, exp = %wd\n", a->length, a->mod.n, e); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(c), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-pow_trunc.c b/external/flint-2.4.3/nmod_poly/test/t-pow_trunc.c new file mode 100644 index 0000000..3242591 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-pow_trunc.c @@ -0,0 +1,120 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("pow_trunc...."); + fflush(stdout); + + /* Check powering against naive method */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c; + mp_limb_t n = n_randtest_not_zero(state); + slong e, trunc; + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(c, n); + nmod_poly_randtest(a, state, n_randint(state, 30)); + e = n_randint(state, 20); + trunc = n_randint(state, 30); + + nmod_poly_pow_trunc(b, a, e, trunc); + + nmod_poly_pow(c, a, e); + nmod_poly_truncate(c, trunc); + + result = (nmod_poly_equal(b, c) + || (a->length == 0 && e == 0 && c->length == 1 && c->coeffs[0] == 1)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a->length = %wd, n = %wu, exp = %wd, trunc = %wd\n", + a->length, a->mod.n, e, trunc); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(c), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + } + + /* Check aliasing */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c; + mp_limb_t n = n_randtest_not_zero(state); + slong e, trunc; + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(c, n); + nmod_poly_randtest(a, state, n_randint(state, 30)); + e = n_randint(state, 20); + trunc = n_randint(state, 30); + + nmod_poly_pow_trunc(b, a, e, trunc); + + nmod_poly_set(c, a); + nmod_poly_pow_trunc(c, c, e, trunc); + + result = (nmod_poly_equal(b, c)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a->length = %wd, n = %wu, exp = %wd, trunc = %wd\n", + a->length, a->mod.n, e, trunc); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(c), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-pow_trunc_binexp.c b/external/flint-2.4.3/nmod_poly/test/t-pow_trunc_binexp.c new file mode 100644 index 0000000..e638fa4 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-pow_trunc_binexp.c @@ -0,0 +1,120 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("pow_trunc_binexp...."); + fflush(stdout); + + /* Check powering against naive method */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c; + mp_limb_t n = n_randtest_not_zero(state); + slong e, trunc; + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(c, n); + nmod_poly_randtest(a, state, n_randint(state, 30)); + e = n_randint(state, 20); + trunc = n_randint(state, 30); + + nmod_poly_pow_trunc_binexp(b, a, e, trunc); + + nmod_poly_pow(c, a, e); + nmod_poly_truncate(c, trunc); + + result = (nmod_poly_equal(b, c) + || (a->length == 0 && e == 0 && c->length == 1 && c->coeffs[0] == 1)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a->length = %wd, n = %wu, exp = %wd, trunc = %wd\n", + a->length, a->mod.n, e, trunc); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(c), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + } + + /* Check aliasing */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c; + mp_limb_t n = n_randtest_not_zero(state); + slong e, trunc; + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(c, n); + nmod_poly_randtest(a, state, n_randint(state, 30)); + e = n_randint(state, 20); + trunc = n_randint(state, 30); + + nmod_poly_pow_trunc_binexp(b, a, e, trunc); + + nmod_poly_set(c, a); + nmod_poly_pow_trunc_binexp(c, c, e, trunc); + + result = (nmod_poly_equal(b, c)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a->length = %wd, n = %wu, exp = %wd, trunc = %wd\n", + a->length, a->mod.n, e, trunc); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(c), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-powmod_mpz_binexp.c b/external/flint-2.4.3/nmod_poly/test/t-powmod_mpz_binexp.c new file mode 100644 index 0000000..acf574b --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-powmod_mpz_binexp.c @@ -0,0 +1,178 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("powmod_mpz_binexp...."); + fflush(stdout); + + /* Aliasing of res and a */ + for (i = 0; i < 25 * flint_test_multiplier(); i++) + { + nmod_poly_t a, res1, t, f; + mp_limb_t n; + ulong exp; + mpz_t expz; + + n = n_randtest_prime(state, 0); + exp = n_randlimb(state); + flint_mpz_init_set_ui(expz, exp); + + nmod_poly_init(a, n); + nmod_poly_init(f, n); + nmod_poly_init(res1, n); + nmod_poly_init(t, n); + + nmod_poly_randtest(a, state, n_randint(state, 50)); + do { + nmod_poly_randtest(f, state, n_randint(state, 50)); + } while (nmod_poly_is_zero(f)); + + nmod_poly_powmod_mpz_binexp(res1, a, expz, f); + nmod_poly_powmod_mpz_binexp(a, a, expz, f); + + result = (nmod_poly_equal(res1, a)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); nmod_poly_print(a), flint_printf("\n\n"); + flint_printf("f:\n"); nmod_poly_print(f), flint_printf("\n\n"); + flint_printf("res1:\n"); nmod_poly_print(res1), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(f); + nmod_poly_clear(res1); + nmod_poly_clear(t); + mpz_clear(expz); + } + + /* Aliasing of res and f */ + for (i = 0; i < 25 * flint_test_multiplier(); i++) + { + nmod_poly_t a, res1, t, f; + mp_limb_t n; + ulong exp; + mpz_t expz; + + n = n_randtest_prime(state, 0); + exp = n_randlimb(state); + flint_mpz_init_set_ui(expz, exp); + + nmod_poly_init(a, n); + nmod_poly_init(f, n); + nmod_poly_init(res1, n); + nmod_poly_init(t, n); + + nmod_poly_randtest(a, state, n_randint(state, 50)); + do { + nmod_poly_randtest(f, state, n_randint(state, 50)); + } while (nmod_poly_is_zero(f)); + + nmod_poly_powmod_mpz_binexp(res1, a, expz, f); + nmod_poly_powmod_mpz_binexp(f, a, expz, f); + + result = (nmod_poly_equal(res1, f)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); nmod_poly_print(a), flint_printf("\n\n"); + flint_printf("f:\n"); nmod_poly_print(f), flint_printf("\n\n"); + flint_printf("res1:\n"); nmod_poly_print(res1), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(f); + nmod_poly_clear(res1); + nmod_poly_clear(t); + mpz_clear(expz); + } + + /* No aliasing */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + nmod_poly_t a, res1, res2, t, f; + mp_limb_t n; + ulong exp; + mpz_t expz; + + n = n_randtest_prime(state, 0); + exp = n_randlimb(state); + + nmod_poly_init(a, n); + nmod_poly_init(f, n); + nmod_poly_init(res1, n); + nmod_poly_init(res2, n); + nmod_poly_init(t, n); + + nmod_poly_randtest(a, state, n_randint(state, 50)); + do { + nmod_poly_randtest(f, state, n_randint(state, 50)); + } while (nmod_poly_is_zero(f)); + flint_mpz_init_set_ui(expz, exp); + + nmod_poly_powmod_mpz_binexp(res1, a, expz, f); + nmod_poly_powmod_ui_binexp(res2, a, exp, f); + + result = (nmod_poly_equal(res1, res2)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); nmod_poly_print(a), flint_printf("\n\n"); + flint_printf("f:\n"); nmod_poly_print(f), flint_printf("\n\n"); + flint_printf("res1:\n"); nmod_poly_print(res1), flint_printf("\n\n"); + flint_printf("res2:\n"); nmod_poly_print(res2), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(f); + nmod_poly_clear(res1); + nmod_poly_clear(res2); + nmod_poly_clear(t); + mpz_clear(expz); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-powmod_mpz_binexp_preinv.c b/external/flint-2.4.3/nmod_poly/test/t-powmod_mpz_binexp_preinv.c new file mode 100644 index 0000000..78aa7dd --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-powmod_mpz_binexp_preinv.c @@ -0,0 +1,251 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + Copyright (C) 2013 Martin Lee + +******************************************************************************/ + +#undef ulong +#define ulong ulongxx/* interferes with system includes */ + +#include +#include + +#undef ulong + +#include + +#define ulong mp_limb_t + +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("powmod_mpz_binexp_preinv...."); + fflush(stdout); + + /* Aliasing of res and a */ + for (i = 0; i < 25 * flint_test_multiplier(); i++) + { + nmod_poly_t a, res1, t, f, finv; + mp_limb_t n; + ulong exp; + mpz_t expz; + + n = n_randtest_prime(state, 0); + exp = n_randlimb(state); + flint_mpz_init_set_ui(expz, exp); + + nmod_poly_init(a, n); + nmod_poly_init(f, n); + nmod_poly_init(finv, n); + nmod_poly_init(res1, n); + nmod_poly_init(t, n); + + nmod_poly_randtest(a, state, n_randint(state, 50)); + do { + nmod_poly_randtest(f, state, n_randint(state, 50)); + } while (nmod_poly_is_zero(f)); + + nmod_poly_reverse(finv, f, f->length); + nmod_poly_inv_series(finv, finv, f->length); + + nmod_poly_powmod_mpz_binexp_preinv(res1, a, expz, f, finv); + nmod_poly_powmod_mpz_binexp_preinv(a, a, expz, f, finv); + + result = (nmod_poly_equal(res1, a)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); nmod_poly_print(a), flint_printf("\n\n"); + flint_printf("f:\n"); nmod_poly_print(f), flint_printf("\n\n"); + flint_printf("res1:\n"); nmod_poly_print(res1), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(f); + nmod_poly_clear(finv); + nmod_poly_clear(res1); + nmod_poly_clear(t); + mpz_clear(expz); + } + + /* Aliasing of res and f */ + for (i = 0; i < 25 * flint_test_multiplier(); i++) + { + nmod_poly_t a, res1, t, f, finv; + mp_limb_t n; + ulong exp; + mpz_t expz; + + n = n_randtest_prime(state, 0); + exp = n_randlimb(state); + flint_mpz_init_set_ui(expz, exp); + + nmod_poly_init(a, n); + nmod_poly_init(f, n); + nmod_poly_init(finv, n); + nmod_poly_init(res1, n); + nmod_poly_init(t, n); + + nmod_poly_randtest(a, state, n_randint(state, 50)); + do { + nmod_poly_randtest(f, state, n_randint(state, 50)); + } while (nmod_poly_is_zero(f)); + + nmod_poly_reverse(finv, f, f->length); + nmod_poly_inv_series(finv, finv, f->length); + + nmod_poly_powmod_mpz_binexp_preinv(res1, a, expz, f, finv); + nmod_poly_powmod_mpz_binexp_preinv(f, a, expz, f, finv); + + result = (nmod_poly_equal(res1, f)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); nmod_poly_print(a), flint_printf("\n\n"); + flint_printf("f:\n"); nmod_poly_print(f), flint_printf("\n\n"); + flint_printf("res1:\n"); nmod_poly_print(res1), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(f); + nmod_poly_clear(finv); + nmod_poly_clear(res1); + nmod_poly_clear(t); + mpz_clear(expz); + } + + /* Aliasing of res and finv */ + for (i = 0; i < 25 * flint_test_multiplier(); i++) + { + nmod_poly_t a, res1, t, f, finv; + mp_limb_t n; + ulong exp; + mpz_t expz; + + n = n_randtest_prime(state, 0); + exp = n_randlimb(state); + flint_mpz_init_set_ui(expz, exp); + + nmod_poly_init(a, n); + nmod_poly_init(f, n); + nmod_poly_init(finv, n); + nmod_poly_init(res1, n); + nmod_poly_init(t, n); + + nmod_poly_randtest(a, state, n_randint(state, 50)); + do { + nmod_poly_randtest(f, state, n_randint(state, 50)); + } while (nmod_poly_is_zero(f)); + + nmod_poly_reverse(finv, f, f->length); + nmod_poly_inv_series(finv, finv, f->length); + + nmod_poly_powmod_mpz_binexp_preinv(res1, a, expz, f, finv); + nmod_poly_powmod_mpz_binexp_preinv(finv, a, expz, f, finv); + + result = (nmod_poly_equal(res1, finv)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); nmod_poly_print(a), flint_printf("\n\n"); + flint_printf("f:\n"); nmod_poly_print(f), flint_printf("\n\n"); + flint_printf("res1:\n"); nmod_poly_print(res1), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(f); + nmod_poly_clear(finv); + nmod_poly_clear(res1); + nmod_poly_clear(t); + mpz_clear(expz); + } + + /* No aliasing */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + nmod_poly_t a, res1, res2, t, f, finv; + mp_limb_t n; + ulong exp; + mpz_t expz; + + n = n_randtest_prime(state, 0); + exp = n_randlimb(state); + + nmod_poly_init(a, n); + nmod_poly_init(f, n); + nmod_poly_init(finv, n); + nmod_poly_init(res1, n); + nmod_poly_init(res2, n); + nmod_poly_init(t, n); + + nmod_poly_randtest(a, state, n_randint(state, 50)); + do { + nmod_poly_randtest(f, state, n_randint(state, 50)); + } while (nmod_poly_is_zero(f)); + flint_mpz_init_set_ui(expz, exp); + + + nmod_poly_reverse(finv, f, f->length); + nmod_poly_inv_series(finv, finv, f->length); + + nmod_poly_powmod_mpz_binexp_preinv(res1, a, expz, f, finv); + nmod_poly_powmod_ui_binexp_preinv(res2, a, exp, f, finv); + + result = (nmod_poly_equal(res1, res2)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a:\n"); nmod_poly_print(a), flint_printf("\n\n"); + flint_printf("f:\n"); nmod_poly_print(f), flint_printf("\n\n"); + flint_printf("res1:\n"); nmod_poly_print(res1), flint_printf("\n\n"); + flint_printf("res2:\n"); nmod_poly_print(res2), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(f); + nmod_poly_clear(finv); + nmod_poly_clear(res1); + nmod_poly_clear(res2); + nmod_poly_clear(t); + mpz_clear(expz); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-powmod_ui_binexp.c b/external/flint-2.4.3/nmod_poly/test/t-powmod_ui_binexp.c new file mode 100644 index 0000000..d4c3376 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-powmod_ui_binexp.c @@ -0,0 +1,177 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("powmod_ui_binexp...."); + fflush(stdout); + + /* Aliasing of res and a */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + nmod_poly_t a, res1, t, f; + mp_limb_t n; + ulong exp; + + n = n_randtest_prime(state, 0); + exp = n_randlimb(state) % 32; + + nmod_poly_init(a, n); + nmod_poly_init(f, n); + nmod_poly_init(res1, n); + nmod_poly_init(t, n); + + nmod_poly_randtest(a, state, n_randint(state, 50)); + do { + nmod_poly_randtest(f, state, n_randint(state, 50)); + } while (nmod_poly_is_zero(f)); + + nmod_poly_powmod_ui_binexp(res1, a, exp, f); + nmod_poly_powmod_ui_binexp(a, a, exp, f); + + result = (nmod_poly_equal(res1, a)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("exp: %wu\n\n", exp); + flint_printf("a:\n"); nmod_poly_print(a), flint_printf("\n\n"); + flint_printf("f:\n"); nmod_poly_print(f), flint_printf("\n\n"); + flint_printf("res1:\n"); nmod_poly_print(res1), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(f); + nmod_poly_clear(res1); + nmod_poly_clear(t); + } + + /* Aliasing of res and f */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + nmod_poly_t a, res1, t, f; + mp_limb_t n; + ulong exp; + + n = n_randtest_prime(state, 0); + exp = n_randlimb(state) % 32; + + nmod_poly_init(a, n); + nmod_poly_init(f, n); + nmod_poly_init(res1, n); + nmod_poly_init(t, n); + + nmod_poly_randtest(a, state, n_randint(state, 50)); + do { + nmod_poly_randtest(f, state, n_randint(state, 50)); + } while (nmod_poly_is_zero(f)); + + nmod_poly_powmod_ui_binexp(res1, a, exp, f); + nmod_poly_powmod_ui_binexp(f, a, exp, f); + + result = (nmod_poly_equal(res1, f)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("exp: %wu\n\n", exp); + flint_printf("a:\n"); nmod_poly_print(a), flint_printf("\n\n"); + flint_printf("f:\n"); nmod_poly_print(f), flint_printf("\n\n"); + flint_printf("res1:\n"); nmod_poly_print(res1), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(f); + nmod_poly_clear(res1); + nmod_poly_clear(t); + } + + /* No aliasing */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, res1, res2, t, f; + mp_limb_t n; + ulong exp; + int j; + + n = n_randtest_prime(state, 0); + exp = n_randlimb(state) % 32; + + nmod_poly_init(a, n); + nmod_poly_init(f, n); + nmod_poly_init(res1, n); + nmod_poly_init(res2, n); + nmod_poly_init(t, n); + + nmod_poly_randtest(a, state, n_randint(state, 50)); + do { + nmod_poly_randtest(f, state, n_randint(state, 50)); + } while (nmod_poly_is_zero(f)); + + nmod_poly_powmod_ui_binexp(res1, a, exp, f); + + nmod_poly_zero(res2); + nmod_poly_set_coeff_ui(res2, 0, 1); + for (j = 1; j <= exp; j++) + nmod_poly_mulmod(res2, res2, a, f); + + result = (nmod_poly_equal(res1, res2)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("exp: %wu\n\n", exp); + flint_printf("a:\n"); nmod_poly_print(a), flint_printf("\n\n"); + flint_printf("f:\n"); nmod_poly_print(f), flint_printf("\n\n"); + flint_printf("res1:\n"); nmod_poly_print(res1), flint_printf("\n\n"); + flint_printf("res2:\n"); nmod_poly_print(res2), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(f); + nmod_poly_clear(res1); + nmod_poly_clear(res2); + nmod_poly_clear(t); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-powmod_ui_binexp_preinv.c b/external/flint-2.4.3/nmod_poly/test/t-powmod_ui_binexp_preinv.c new file mode 100644 index 0000000..aa27f57 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-powmod_ui_binexp_preinv.c @@ -0,0 +1,248 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + Copyright (C) 2013 Martin Lee + +******************************************************************************/ + +#undef ulong +#define ulong ulongxx/* interferes with system includes */ + +#include +#include + +#undef ulong + +#include + +#define ulong mp_limb_t + +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("powmod_ui_binexp_preinv...."); + fflush(stdout); + + /* Aliasing of res and a */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + nmod_poly_t a, res1, t, f, finv; + mp_limb_t n; + ulong exp; + + n = n_randtest_prime(state, 0); + exp = n_randlimb(state) % 32; + + nmod_poly_init(a, n); + nmod_poly_init(f, n); + nmod_poly_init(finv, n); + nmod_poly_init(res1, n); + nmod_poly_init(t, n); + + nmod_poly_randtest(a, state, n_randint(state, 50)); + do { + nmod_poly_randtest(f, state, n_randint(state, 50)); + } while (nmod_poly_is_zero(f)); + + nmod_poly_reverse(finv, f, f->length); + nmod_poly_inv_series(finv, finv, f->length); + + nmod_poly_powmod_ui_binexp_preinv(res1, a, exp, f, finv); + nmod_poly_powmod_ui_binexp_preinv(a, a, exp, f, finv); + + result = (nmod_poly_equal(res1, a)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("exp: %wu\n\n", exp); + flint_printf("a:\n"); nmod_poly_print(a), flint_printf("\n\n"); + flint_printf("f:\n"); nmod_poly_print(f), flint_printf("\n\n"); + flint_printf("res1:\n"); nmod_poly_print(res1), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(f); + nmod_poly_clear(finv); + nmod_poly_clear(res1); + nmod_poly_clear(t); + } + + /* Aliasing of res and f */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + nmod_poly_t a, res1, t, f, finv; + mp_limb_t n; + ulong exp; + + n = n_randtest_prime(state, 0); + exp = n_randlimb(state) % 32; + + nmod_poly_init(a, n); + nmod_poly_init(f, n); + nmod_poly_init(finv, n); + nmod_poly_init(res1, n); + nmod_poly_init(t, n); + + nmod_poly_randtest(a, state, n_randint(state, 50)); + do { + nmod_poly_randtest(f, state, n_randint(state, 50)); + } while (nmod_poly_is_zero(f)); + + nmod_poly_reverse(finv, f, f->length); + nmod_poly_inv_series(finv, finv, f->length); + + nmod_poly_powmod_ui_binexp_preinv(res1, a, exp, f, finv); + nmod_poly_powmod_ui_binexp_preinv(f, a, exp, f, finv); + + result = (nmod_poly_equal(res1, f)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("exp: %wu\n\n", exp); + flint_printf("a:\n"); nmod_poly_print(a), flint_printf("\n\n"); + flint_printf("f:\n"); nmod_poly_print(f), flint_printf("\n\n"); + flint_printf("res1:\n"); nmod_poly_print(res1), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(f); + nmod_poly_clear(finv); + nmod_poly_clear(res1); + nmod_poly_clear(t); + } + + /* Aliasing of res and finv */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + nmod_poly_t a, res1, t, f, finv; + mp_limb_t n; + ulong exp; + + n = n_randtest_prime(state, 0); + exp = n_randlimb(state) % 32; + + nmod_poly_init(a, n); + nmod_poly_init(f, n); + nmod_poly_init(finv, n); + nmod_poly_init(res1, n); + nmod_poly_init(t, n); + + nmod_poly_randtest(a, state, n_randint(state, 50)); + do { + nmod_poly_randtest(f, state, n_randint(state, 50)); + } while (nmod_poly_is_zero(f)); + + nmod_poly_reverse(finv, f, f->length); + nmod_poly_inv_series(finv, finv, f->length); + + nmod_poly_powmod_ui_binexp_preinv(res1, a, exp, f, finv); + nmod_poly_powmod_ui_binexp_preinv(finv, a, exp, f, finv); + + result = (nmod_poly_equal(res1, finv)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("exp: %wu\n\n", exp); + flint_printf("a:\n"); nmod_poly_print(a), flint_printf("\n\n"); + flint_printf("f:\n"); nmod_poly_print(f), flint_printf("\n\n"); + flint_printf("finv:\n"); nmod_poly_print(finv), flint_printf("\n\n"); + flint_printf("res1:\n"); nmod_poly_print(res1), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(f); + nmod_poly_clear(finv); + nmod_poly_clear(res1); + nmod_poly_clear(t); + } + + /* No aliasing */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, res1, res2, t, f, finv; + mp_limb_t n; + ulong exp; + int j; + + n = n_randtest_prime(state, 0); + exp = n_randlimb(state) % 32; + + nmod_poly_init(a, n); + nmod_poly_init(f, n); + nmod_poly_init(finv, n); + nmod_poly_init(res1, n); + nmod_poly_init(res2, n); + nmod_poly_init(t, n); + + nmod_poly_randtest(a, state, n_randint(state, 50)); + do { + nmod_poly_randtest(f, state, n_randint(state, 50)); + } while (nmod_poly_is_zero(f)); + + nmod_poly_reverse(finv, f, f->length); + nmod_poly_inv_series(finv, finv, f->length); + + nmod_poly_powmod_ui_binexp_preinv(res1, a, exp, f, finv); + + nmod_poly_zero(res2); + nmod_poly_set_coeff_ui(res2, 0, 1); + for (j = 1; j <= exp; j++) + nmod_poly_mulmod(res2, res2, a, f); + + result = (nmod_poly_equal(res1, res2)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("exp: %wu\n\n", exp); + flint_printf("a:\n"); nmod_poly_print(a), flint_printf("\n\n"); + flint_printf("f:\n"); nmod_poly_print(f), flint_printf("\n\n"); + flint_printf("res1:\n"); nmod_poly_print(res1), flint_printf("\n\n"); + flint_printf("res2:\n"); nmod_poly_print(res2), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(f); + nmod_poly_clear(finv); + nmod_poly_clear(res1); + nmod_poly_clear(res2); + nmod_poly_clear(t); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-powmod_x_ui_binexp.c b/external/flint-2.4.3/nmod_poly/test/t-powmod_x_ui_binexp.c new file mode 100644 index 0000000..7aa5d9d --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-powmod_x_ui_binexp.c @@ -0,0 +1,192 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + Copyright (C) 2013 Martin Lee + +******************************************************************************/ + +#undef ulong +#define ulong ulongxx/* interferes with system includes */ + +#include +#include + +#undef ulong + +#include + +#define ulong mp_limb_t + +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("powmod_x_ui_preinv...."); + fflush(stdout); + + + /* No aliasing */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, res1, res2, t, f, finv; + mp_limb_t n; + ulong exp; + + n = n_randtest_prime(state, 0); + exp = n_randlimb(state) % 32; + + nmod_poly_init(f, n); + nmod_poly_init(finv, n); + nmod_poly_init(res1, n); + nmod_poly_init(res2, n); + nmod_poly_init(t, n); + + do { + nmod_poly_randtest(f, state, n_randint(state, 50)); + } while (nmod_poly_is_zero(f)); + + nmod_poly_reverse(finv, f, f->length); + nmod_poly_inv_series(finv, finv, f->length); + + nmod_poly_init2 (a, n, f->length-1); + nmod_poly_set_coeff_ui (a, 1, 1); + + nmod_poly_powmod_x_ui_preinv(res1, exp, f, finv); + nmod_poly_powmod_ui_binexp_preinv (res2, a, exp, f, finv); + + result = (nmod_poly_equal(res1, res2)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("exp: %wu\n\n", exp); + flint_printf("a:\n"); nmod_poly_print(a), flint_printf("\n\n"); + flint_printf("f:\n"); nmod_poly_print(f), flint_printf("\n\n"); + flint_printf("res1:\n"); nmod_poly_print(res1), flint_printf("\n\n"); + flint_printf("res2:\n"); nmod_poly_print(res2), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(f); + nmod_poly_clear(finv); + nmod_poly_clear(res1); + nmod_poly_clear(res2); + nmod_poly_clear(t); + } + + /* Aliasing of res and f */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + nmod_poly_t res1, t, f, finv; + mp_limb_t n; + ulong exp; + + n = n_randtest_prime(state, 0); + exp = n_randlimb(state) % 32; + + nmod_poly_init(f, n); + nmod_poly_init(finv, n); + nmod_poly_init(res1, n); + nmod_poly_init(t, n); + + do { + nmod_poly_randtest(f, state, n_randint(state, 50)); + } while (nmod_poly_is_zero(f)); + + nmod_poly_reverse(finv, f, f->length); + nmod_poly_inv_series(finv, finv, f->length); + + nmod_poly_powmod_x_ui_preinv(res1, exp, f, finv); + nmod_poly_powmod_x_ui_preinv(f, exp, f, finv); + + result = (nmod_poly_equal(res1, f)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("exp: %wu\n\n", exp); + flint_printf("f:\n"); nmod_poly_print(f), flint_printf("\n\n"); + flint_printf("res1:\n"); nmod_poly_print(res1), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(f); + nmod_poly_clear(finv); + nmod_poly_clear(res1); + nmod_poly_clear(t); + } + + /* Aliasing of res and finv */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + nmod_poly_t res1, t, f, finv; + mp_limb_t n; + ulong exp; + + n = n_randtest_prime(state, 0); + exp = n_randlimb(state) % 32; + + nmod_poly_init(f, n); + nmod_poly_init(finv, n); + nmod_poly_init(res1, n); + nmod_poly_init(t, n); + + do { + nmod_poly_randtest(f, state, n_randint(state, 50)); + } while (nmod_poly_is_zero(f)); + + nmod_poly_reverse(finv, f, f->length); + nmod_poly_inv_series(finv, finv, f->length); + + nmod_poly_powmod_x_ui_preinv(res1, exp, f, finv); + nmod_poly_powmod_x_ui_preinv(finv, exp, f, finv); + + result = (nmod_poly_equal(res1, finv)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("exp: %wu\n\n", exp); + flint_printf("f:\n"); nmod_poly_print(f), flint_printf("\n\n"); + flint_printf("finv:\n"); nmod_poly_print(finv), flint_printf("\n\n"); + flint_printf("res1:\n"); nmod_poly_print(res1), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(f); + nmod_poly_clear(finv); + nmod_poly_clear(res1); + nmod_poly_clear(t); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-product_roots_nmod_vec.c b/external/flint-2.4.3/nmod_poly/test/t-product_roots_nmod_vec.c new file mode 100644 index 0000000..80a44f2 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-product_roots_nmod_vec.c @@ -0,0 +1,92 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("product_roots_nmod_vec...."); + fflush(stdout); + + + + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t P, Q, tmp; + mp_ptr x; + mp_limb_t mod; + slong j, n; + + n = n_randint(state, 100); + mod = n_randtest_prime(state, 0); + + nmod_poly_init(P, mod); + nmod_poly_init(Q, mod); + nmod_poly_init(tmp, mod); + x = _nmod_vec_init(n); + _nmod_vec_randtest(x, state, n, P->mod); + + nmod_poly_product_roots_nmod_vec(P, x, n); + + nmod_poly_set_coeff_ui(Q, 0, UWORD(1)); + + for (j = 0; j < n; j++) + { + nmod_poly_zero(tmp); + nmod_poly_set_coeff_ui(tmp, 1, UWORD(1)); + nmod_poly_set_coeff_ui(tmp, 0, n_negmod(x[j], mod)); + nmod_poly_mul(Q, Q, tmp); + } + + result = (nmod_poly_equal(P, Q)); + if (!result) + { + flint_printf("FAIL (P != Q):\n"); + nmod_poly_print(P), flint_printf("\n\n"); + nmod_poly_print(Q), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(P); + nmod_poly_clear(Q); + nmod_poly_clear(tmp); + _nmod_vec_clear(x); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-rem.c b/external/flint-2.4.3/nmod_poly/test/t-rem.c new file mode 100644 index 0000000..879dfc0 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-rem.c @@ -0,0 +1,203 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("rem...."); + fflush(stdout); + + /* Check result of rem */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, q, r, prod; + + mp_limb_t n; + do n = n_randtest_not_zero(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(q, n); + nmod_poly_init(r, n); + nmod_poly_init(prod, n); + + nmod_poly_randtest(a, state, n_randint(state, 2000)); + do nmod_poly_randtest(b, state, n_randint(state, 2000)); + while (b->length == 0); + + nmod_poly_div(q, a, b); + nmod_poly_rem(r, a, b); + nmod_poly_mul(prod, q, b); + nmod_poly_add(prod, prod, r); + + result = (nmod_poly_equal(a, prod)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(prod), flint_printf("\n\n"); + nmod_poly_print(q), flint_printf("\n\n"); + nmod_poly_print(r), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(q); + nmod_poly_clear(r); + nmod_poly_clear(prod); + } + + /* Check aliasing of a and r */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, r; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(r, n); + nmod_poly_randtest(a, state, n_randint(state, 2000)); + do nmod_poly_randtest(b, state, n_randint(state, 2000)); + while (b->length == 0); + + nmod_poly_rem(r, a, b); + nmod_poly_rem(a, a, b); + + result = (nmod_poly_equal(a, r)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(r), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(r); + } + + /* Check aliasing of b and r */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, r; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(r, n); + nmod_poly_randtest(a, state, n_randint(state, 2000)); + do nmod_poly_randtest(b, state, n_randint(state, 2000)); + while (b->length == 0); + + nmod_poly_rem(r, a, b); + nmod_poly_rem(b, a, b); + + result = (nmod_poly_equal(b, r)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(r), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(r); + } + + /* Check result of rem_q1 */ + for (i = 0; i < 500 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, q0, r0, r; + + mp_limb_t n = n_randprime(state, n_randint(state,FLINT_BITS-1)+2, 0); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(q0, n); + nmod_poly_init(r0, n); + nmod_poly_init(r, n); + do nmod_poly_randtest(a, state, n_randint(state, 1000)); + while (a->length < 2); + nmod_poly_fit_length(b, a->length - 1); + flint_mpn_zero(b->coeffs, a->length - 1); + nmod_poly_randtest_not_zero(b, state, n_randint(state, 1000) + 1); + do b->coeffs[a->length - 2] = n_randint(state, n); + while (b->coeffs[a->length - 2] == 0); + b->length = a->length - 1; + + nmod_poly_divrem(q0, r0, a, b); + nmod_poly_rem(r, a, b); + + result = (nmod_poly_equal(r0, r)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(q0), flint_printf("\n\n"); + nmod_poly_print(r0), flint_printf("\n\n"); + nmod_poly_print(r), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(q0); + nmod_poly_clear(r0); + nmod_poly_clear(r); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-rem_basecase.c b/external/flint-2.4.3/nmod_poly/test/t-rem_basecase.c new file mode 100644 index 0000000..5af1ad6 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-rem_basecase.c @@ -0,0 +1,173 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("rem_basecase...."); + fflush(stdout); + + /* Check result of divrem */ + for (i = 0; i < 500 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, q0, r0, r; + + mp_limb_t n; + do + { + n = n_randtest_not_zero(state); + } while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(q0, n); + nmod_poly_init(r0, n); + nmod_poly_init(r, n); + + nmod_poly_randtest(a, state, n_randint(state, 200)); + do + { + nmod_poly_randtest(b, state, n_randint(state, 200)); + } while (b->length == 0); + + nmod_poly_divrem_basecase(q0, r0, a, b); + nmod_poly_rem_basecase(r, a, b); + + result = (nmod_poly_equal(r0, r)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(q0), flint_printf("\n\n"); + nmod_poly_print(r0), flint_printf("\n\n"); + nmod_poly_print(r), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(q0); + nmod_poly_clear(r0); + nmod_poly_clear(r); + } + + /* Check aliasing of a and r */ + for (i = 0; i < 500 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, r; + + mp_limb_t n; + do + { + n = n_randtest(state); + } while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(r, n); + nmod_poly_randtest(a, state, n_randint(state, 200)); + do + { + nmod_poly_randtest(b, state, n_randint(state, 200)); + } while (b->length == 0); + + nmod_poly_rem_basecase(r, a, b); + nmod_poly_rem_basecase(a, a, b); + + result = (nmod_poly_equal(a, r)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(r), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(r); + } + + /* Check aliasing of b and r */ + for (i = 0; i < 500 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, r; + + mp_limb_t n; + do + { + n = n_randtest(state); + } while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(r, n); + nmod_poly_randtest(a, state, n_randint(state, 200)); + do + { + nmod_poly_randtest(b, state, n_randint(state, 200)); + } while (b->length == 0); + + nmod_poly_rem_basecase(r, a, b); + nmod_poly_rem_basecase(b, a, b); + + result = (nmod_poly_equal(b, r)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(r), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(r); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} + diff --git a/external/flint-2.4.3/nmod_poly/test/t-resultant.c b/external/flint-2.4.3/nmod_poly/test/t-resultant.c new file mode 100644 index 0000000..7ec20ed --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-resultant.c @@ -0,0 +1,128 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("resultant...."); + fflush(stdout); + + /* Check res(f, g) == (-1)^(deg f deg g) res(g, f) */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t f, g; + mp_limb_t x, y; + mp_limb_t n; + + do n = n_randtest_not_zero(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(f, n); + nmod_poly_init(g, n); + + nmod_poly_randtest(f, state, n_randint(state, 200)); + nmod_poly_randtest(g, state, n_randint(state, 200)); + + x = nmod_poly_resultant(f, g); + y = nmod_poly_resultant(g, f); + + if ((nmod_poly_degree(f) * nmod_poly_degree(g)) % 2) + y = nmod_neg(y, f->mod); + + result = (x == y); + if (!result) + { + flint_printf("FAIL (res(f, g) == (-1)^(deg f deg g) res(g, f)):\n"); + nmod_poly_print(f), flint_printf("\n\n"); + nmod_poly_print(g), flint_printf("\n\n"); + flint_printf("x = %wu\n", x); + flint_printf("y = %wu\n", y); + flint_printf("n = %wu\n", n); + abort(); + } + + nmod_poly_clear(f); + nmod_poly_clear(g); + } + + /* Check res(f h, g) == res(f, g) res(h, g) */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + nmod_poly_t f, g, h; + mp_limb_t x, y, z; + mp_limb_t n; + + do n = n_randtest_not_zero(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(f, n); + nmod_poly_init(g, n); + nmod_poly_init(h, n); + + nmod_poly_randtest(f, state, n_randint(state, 200)); + nmod_poly_randtest(g, state, n_randint(state, 200)); + nmod_poly_randtest(h, state, n_randint(state, 200)); + + y = nmod_poly_resultant(f, g); + z = nmod_poly_resultant(h, g); + y = nmod_mul(y, z, f->mod); + nmod_poly_mul(f, f, h); + x = nmod_poly_resultant(f, g); + + result = (x == y); + if (!result) + { + flint_printf("FAIL (res(f h, g) == res(f, g) res(h, g)):\n"); + nmod_poly_print(f), flint_printf("\n\n"); + nmod_poly_print(g), flint_printf("\n\n"); + nmod_poly_print(h), flint_printf("\n\n"); + flint_printf("x = %wu\n", x); + flint_printf("y = %wu\n", y); + flint_printf("z = %wd\n", z); + flint_printf("n = %wu\n", n); + abort(); + } + + nmod_poly_clear(f); + nmod_poly_clear(g); + nmod_poly_clear(h); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-resultant_euclidean.c b/external/flint-2.4.3/nmod_poly/test/t-resultant_euclidean.c new file mode 100644 index 0000000..1e46807 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-resultant_euclidean.c @@ -0,0 +1,128 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("resultant_euclidean...."); + fflush(stdout); + + /* Check res(f, g) == (-1)^(deg f deg g) res(g, f) */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t f, g; + mp_limb_t x, y; + mp_limb_t n; + + do n = n_randtest_not_zero(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(f, n); + nmod_poly_init(g, n); + + nmod_poly_randtest(f, state, n_randint(state, 200)); + nmod_poly_randtest(g, state, n_randint(state, 200)); + + x = nmod_poly_resultant_euclidean(f, g); + y = nmod_poly_resultant_euclidean(g, f); + + if ((nmod_poly_degree(f) * nmod_poly_degree(g)) % 2) + y = nmod_neg(y, f->mod); + + result = (x == y); + if (!result) + { + flint_printf("FAIL (res(f, g) == (-1)^(deg f deg g) res(g, f)):\n"); + nmod_poly_print(f), flint_printf("\n\n"); + nmod_poly_print(g), flint_printf("\n\n"); + flint_printf("x = %wu\n", x); + flint_printf("y = %wu\n", y); + flint_printf("n = %wu\n", n); + abort(); + } + + nmod_poly_clear(f); + nmod_poly_clear(g); + } + + /* Check res(f h, g) == res(f, g) res(h, g) */ + for (i = 0; i < 50 * flint_test_multiplier(); i++) + { + nmod_poly_t f, g, h; + mp_limb_t x, y, z; + mp_limb_t n; + + do n = n_randtest_not_zero(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(f, n); + nmod_poly_init(g, n); + nmod_poly_init(h, n); + + nmod_poly_randtest(f, state, n_randint(state, 200)); + nmod_poly_randtest(g, state, n_randint(state, 200)); + nmod_poly_randtest(h, state, n_randint(state, 200)); + + y = nmod_poly_resultant_euclidean(f, g); + z = nmod_poly_resultant_euclidean(h, g); + y = nmod_mul(y, z, f->mod); + nmod_poly_mul(f, f, h); + x = nmod_poly_resultant_euclidean(f, g); + + result = (x == y); + if (!result) + { + flint_printf("FAIL (res(f h, g) == res(f, g) res(h, g)):\n"); + nmod_poly_print(f), flint_printf("\n\n"); + nmod_poly_print(g), flint_printf("\n\n"); + nmod_poly_print(h), flint_printf("\n\n"); + flint_printf("x = %wu\n", x); + flint_printf("y = %wu\n", y); + flint_printf("z = %wd\n", z); + flint_printf("n = %wu\n", n); + abort(); + } + + nmod_poly_clear(f); + nmod_poly_clear(g); + nmod_poly_clear(h); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-reverse.c b/external/flint-2.4.3/nmod_poly/test/t-reverse.c new file mode 100644 index 0000000..41c4df2 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-reverse.c @@ -0,0 +1,106 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("reverse...."); + fflush(stdout); + + /* Check rev rev a == a */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b; + mp_limb_t n = n_randtest_not_zero(state); + slong len; + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_randtest(a, state, n_randint(state, 100)); + + len = nmod_poly_length(a); + + nmod_poly_reverse(b, a, len); + nmod_poly_reverse(b, b, len); + + result = (nmod_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("len = %wd, n = %wu\n", len, a->mod.n); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + } + + /* check reversal for m > a->len */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b; + mp_limb_t n = n_randtest_not_zero(state); + slong m = n_randint(state, 100) + 1; + slong len = n_randint(state, m); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_randtest(a, state, len); + + nmod_poly_reverse(b, a, m); + nmod_poly_reverse(b, b, m); + + result = (nmod_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("len = %wd, m = %wd, n = %wu\n", a->length, m, a->mod.n); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-revert_series.c b/external/flint-2.4.3/nmod_poly/test/t-revert_series.c new file mode 100644 index 0000000..3cb4de7 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-revert_series.c @@ -0,0 +1,123 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("revert_series...."); + fflush(stdout); + + + + /* Check aliasing */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + nmod_poly_t f, g; + mp_limb_t m; + slong n; + + m = n_randtest_prime(state, 0); + nmod_poly_init(f, m); + nmod_poly_init(g, m); + do { + nmod_poly_randtest(g, state, n_randint(state, 100)); + } while (nmod_poly_get_coeff_ui(g, 1) == 0); + nmod_poly_set_coeff_ui(g, 0, 0); + do { + n = n_randint(state, 100); + } while (n >= m); + + nmod_poly_revert_series(f, g, n); + nmod_poly_revert_series(g, g, n); + + result = (nmod_poly_equal(f, g)); + if (!result) + { + flint_printf("FAIL (aliasing):\n"); + nmod_poly_print(f), flint_printf("\n\n"); + nmod_poly_print(g), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(f); + nmod_poly_clear(g); + } + + /* Check f(f^(-1)) = id */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t f, g, h; + mp_limb_t m; + slong n; + + m = n_randtest_prime(state, 0); + nmod_poly_init(f, m); + nmod_poly_init(g, m); + nmod_poly_init(h, m); + do { + nmod_poly_randtest(g, state, n_randint(state, 100)); + } while (nmod_poly_get_coeff_ui(g, 1) == 0); + nmod_poly_set_coeff_ui(g, 0, 0); + do { + n = n_randint(state, 100); + } while (n >= m); + + nmod_poly_revert_series(f, g, n); + nmod_poly_compose_series(h, g, f, n); + + result = ((n <= 1 && nmod_poly_is_zero(h)) || + (h->length == 2 && h->coeffs[0] == 0 && h->coeffs[1] == 1)); + if (!result) + { + flint_printf("FAIL (comparison):\n"); + nmod_poly_print(g), flint_printf("\n\n"); + nmod_poly_print(f), flint_printf("\n\n"); + nmod_poly_print(h), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(f); + nmod_poly_clear(g); + nmod_poly_clear(h); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-revert_series_lagrange.c b/external/flint-2.4.3/nmod_poly/test/t-revert_series_lagrange.c new file mode 100644 index 0000000..5539a36 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-revert_series_lagrange.c @@ -0,0 +1,124 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("revert_series_lagrange...."); + fflush(stdout); + + + + /* Check aliasing */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + nmod_poly_t f, g; + mp_limb_t m; + slong n; + + m = n_randtest_prime(state, 0); + nmod_poly_init(f, m); + nmod_poly_init(g, m); + do { + nmod_poly_randtest(g, state, n_randint(state, 100)); + } while (nmod_poly_get_coeff_ui(g, 1) == 0); + nmod_poly_set_coeff_ui(g, 0, 0); + do { + n = n_randint(state, 100); + } while (n >= m); + + + nmod_poly_revert_series_lagrange(f, g, n); + nmod_poly_revert_series_lagrange(g, g, n); + + result = (nmod_poly_equal(f, g)); + if (!result) + { + flint_printf("FAIL (aliasing):\n"); + nmod_poly_print(f), flint_printf("\n\n"); + nmod_poly_print(g), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(f); + nmod_poly_clear(g); + } + + /* Check f(f^(-1)) = id */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t f, g, h; + mp_limb_t m; + slong n; + + m = n_randtest_prime(state, 0); + nmod_poly_init(f, m); + nmod_poly_init(g, m); + nmod_poly_init(h, m); + do { + nmod_poly_randtest(g, state, n_randint(state, 100)); + } while (nmod_poly_get_coeff_ui(g, 1) == 0); + nmod_poly_set_coeff_ui(g, 0, 0); + do { + n = n_randint(state, 100); + } while (n >= m); + + nmod_poly_revert_series_lagrange(f, g, n); + nmod_poly_compose_series(h, g, f, n); + + result = ((n <= 1 && nmod_poly_is_zero(h)) || + (h->length == 2 && h->coeffs[0] == 0 && h->coeffs[1] == 1)); + if (!result) + { + flint_printf("FAIL (comparison):\n"); + nmod_poly_print(g), flint_printf("\n\n"); + nmod_poly_print(f), flint_printf("\n\n"); + nmod_poly_print(h), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(f); + nmod_poly_clear(g); + nmod_poly_clear(h); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-revert_series_lagrange_fast.c b/external/flint-2.4.3/nmod_poly/test/t-revert_series_lagrange_fast.c new file mode 100644 index 0000000..1daec4e --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-revert_series_lagrange_fast.c @@ -0,0 +1,124 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("revert_series_lagrange_fast...."); + fflush(stdout); + + + + /* Check aliasing */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + nmod_poly_t f, g; + mp_limb_t m; + slong n; + + m = n_randtest_prime(state, 0); + nmod_poly_init(f, m); + nmod_poly_init(g, m); + do { + nmod_poly_randtest(g, state, n_randint(state, 100)); + } while (nmod_poly_get_coeff_ui(g, 1) == 0); + nmod_poly_set_coeff_ui(g, 0, 0); + do { + n = n_randint(state, 100); + } while (n >= m); + + + nmod_poly_revert_series_lagrange_fast(f, g, n); + nmod_poly_revert_series_lagrange_fast(g, g, n); + + result = (nmod_poly_equal(f, g)); + if (!result) + { + flint_printf("FAIL (aliasing):\n"); + nmod_poly_print(f), flint_printf("\n\n"); + nmod_poly_print(g), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(f); + nmod_poly_clear(g); + } + + /* Check f(f^(-1)) = id */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t f, g, h; + mp_limb_t m; + slong n; + + m = n_randtest_prime(state, 0); + nmod_poly_init(f, m); + nmod_poly_init(g, m); + nmod_poly_init(h, m); + do { + nmod_poly_randtest(g, state, n_randint(state, 100)); + } while (nmod_poly_get_coeff_ui(g, 1) == 0); + nmod_poly_set_coeff_ui(g, 0, 0); + do { + n = n_randint(state, 100); + } while (n >= m); + + nmod_poly_revert_series_lagrange_fast(f, g, n); + nmod_poly_compose_series(h, g, f, n); + + result = ((n <= 1 && nmod_poly_is_zero(h)) || + (h->length == 2 && h->coeffs[0] == 0 && h->coeffs[1] == 1)); + if (!result) + { + flint_printf("FAIL (comparison):\n"); + nmod_poly_print(g), flint_printf("\n\n"); + nmod_poly_print(f), flint_printf("\n\n"); + nmod_poly_print(h), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(f); + nmod_poly_clear(g); + nmod_poly_clear(h); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-revert_series_newton.c b/external/flint-2.4.3/nmod_poly/test/t-revert_series_newton.c new file mode 100644 index 0000000..7c11664 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-revert_series_newton.c @@ -0,0 +1,124 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("revert_series_newton...."); + fflush(stdout); + + + + /* Check aliasing */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + nmod_poly_t f, g; + mp_limb_t m; + slong n; + + m = n_randtest_prime(state, 0); + nmod_poly_init(f, m); + nmod_poly_init(g, m); + do { + nmod_poly_randtest(g, state, n_randint(state, 100)); + } while (nmod_poly_get_coeff_ui(g, 1) == 0); + nmod_poly_set_coeff_ui(g, 0, 0); + do { + n = n_randint(state, 100); + } while (n >= m); + + + nmod_poly_revert_series_newton(f, g, n); + nmod_poly_revert_series_newton(g, g, n); + + result = (nmod_poly_equal(f, g)); + if (!result) + { + flint_printf("FAIL (aliasing):\n"); + nmod_poly_print(f), flint_printf("\n\n"); + nmod_poly_print(g), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(f); + nmod_poly_clear(g); + } + + /* Check f(f^(-1)) = id */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t f, g, h; + mp_limb_t m; + slong n; + + m = n_randtest_prime(state, 0); + nmod_poly_init(f, m); + nmod_poly_init(g, m); + nmod_poly_init(h, m); + do { + nmod_poly_randtest(g, state, n_randint(state, 100)); + } while (nmod_poly_get_coeff_ui(g, 1) == 0); + nmod_poly_set_coeff_ui(g, 0, 0); + do { + n = n_randint(state, 100); + } while (n >= m); + + nmod_poly_revert_series_newton(f, g, n); + nmod_poly_compose_series(h, g, f, n); + + result = ((n <= 1 && nmod_poly_is_zero(h)) || + (h->length == 2 && h->coeffs[0] == 0 && h->coeffs[1] == 1)); + if (!result) + { + flint_printf("FAIL (comparison):\n"); + nmod_poly_print(g), flint_printf("\n\n"); + nmod_poly_print(f), flint_printf("\n\n"); + nmod_poly_print(h), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(f); + nmod_poly_clear(g); + nmod_poly_clear(h); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-scalar_mul_nmod.c b/external/flint-2.4.3/nmod_poly/test/t-scalar_mul_nmod.c new file mode 100644 index 0000000..e0033fe --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-scalar_mul_nmod.c @@ -0,0 +1,110 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("scalar_mul_nmod...."); + fflush(stdout); + + /* Check aliasing of a and b */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b; + mp_limb_t n = n_randtest_not_zero(state); + mp_limb_t c = n_randint(state, n); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_randtest(a, state, n_randint(state, 100)); + + nmod_poly_scalar_mul_nmod(b, a, c); + nmod_poly_scalar_mul_nmod(a, a, c); + + result = (nmod_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + } + + /* Check (a + b)*c = a*c + b*c */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, d1, d2; + mp_limb_t n = n_randtest_not_zero(state); + mp_limb_t c = n_randint(state, n); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(d1, n); + nmod_poly_init(d2, n); + nmod_poly_randtest(a, state, n_randint(state, 100)); + nmod_poly_randtest(b, state, n_randint(state, 100)); + + nmod_poly_add(d1, a, b); + nmod_poly_scalar_mul_nmod(d1, d1, c); + + nmod_poly_scalar_mul_nmod(d2, a, c); + nmod_poly_scalar_mul_nmod(b, b, c); + nmod_poly_add(d2, d2, b); + + result = (nmod_poly_equal(d1, d2)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(d1), flint_printf("\n\n"); + nmod_poly_print(d2), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(d1); + nmod_poly_clear(d2); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-shift_left_right.c b/external/flint-2.4.3/nmod_poly/test/t-shift_left_right.c new file mode 100644 index 0000000..81df220 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-shift_left_right.c @@ -0,0 +1,108 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("shift_left_right...."); + fflush(stdout); + + /* Check a << shift >> shift == a */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b; + mp_limb_t n = n_randtest_not_zero(state); + slong shift = n_randint(state, 100); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_randtest(a, state, n_randint(state, 100)); + + nmod_poly_shift_left(b, a, shift); + nmod_poly_shift_right(b, b, shift); + + result = (nmod_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("shift = %wd, a->length = %wd, n = %wu\n", + shift, a->length, a->mod.n); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + } + + /* Check a << shift >> shift == a aliasing the other way */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c; + mp_limb_t n = n_randtest_not_zero(state); + slong shift = n_randint(state, 100); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(c, n); + nmod_poly_randtest(c, state, n_randint(state, 100)); + + nmod_poly_set(a, c); + nmod_poly_shift_left(c, c, shift); + nmod_poly_shift_right(b, c, shift); + + result = (nmod_poly_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("shift = %wd, c->length = %wd, n = %wu\n", + shift, c->length, a->mod.n); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-sin_series.c b/external/flint-2.4.3/nmod_poly/test/t-sin_series.c new file mode 100644 index 0000000..3967600 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-sin_series.c @@ -0,0 +1,119 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result = 1; + FLINT_TEST_INIT(state); + + + flint_printf("sin_series...."); + fflush(stdout); + + /* Check asin(sin(A)) = A */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t A, sinA, B; + slong n; + mp_limb_t mod; + + do { mod = n_randtest_prime(state, 0); } while (mod == 2); + n = 1 + n_randtest(state) % 100; + n = FLINT_MIN(n, mod); + + nmod_poly_init(A, mod); + nmod_poly_init(sinA, mod); + nmod_poly_init(B, mod); + + nmod_poly_randtest(A, state, n_randint(state, 100)); + nmod_poly_set_coeff_ui(A, 0, UWORD(0)); + + nmod_poly_sin_series(sinA, A, n); + nmod_poly_asin_series(B, sinA, n); + + nmod_poly_truncate(A, n); + + result = nmod_poly_equal(A, B); + + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("n = %wd, mod = %wu\n", n, mod); + flint_printf("A: "); nmod_poly_print(A), flint_printf("\n\n"); + flint_printf("sin(A): "); nmod_poly_print(sinA), flint_printf("\n\n"); + flint_printf("B: "); nmod_poly_print(B), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(A); + nmod_poly_clear(sinA); + nmod_poly_clear(B); + } + + /* Check aliasing */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t A, B; + slong n; + mp_limb_t mod; + mod = n_randtest_prime(state, 0); + n = n_randtest(state) % 50; + n = FLINT_MIN(n, mod); + + nmod_poly_init(A, mod); + nmod_poly_init(B, mod); + nmod_poly_randtest(A, state, n_randint(state, 50)); + nmod_poly_set_coeff_ui(A, 0, UWORD(0)); + + nmod_poly_sin_series(B, A, n); + nmod_poly_sin_series(A, A, n); + + result = nmod_poly_equal(A, B); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(A), flint_printf("\n\n"); + nmod_poly_print(B), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(A); + nmod_poly_clear(B); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-sinh_series.c b/external/flint-2.4.3/nmod_poly/test/t-sinh_series.c new file mode 100644 index 0000000..b260faa --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-sinh_series.c @@ -0,0 +1,119 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result = 1; + FLINT_TEST_INIT(state); + + + flint_printf("sinh_series...."); + fflush(stdout); + + /* Check asinh(sinh(A)) = A */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t A, sinhA, B; + slong n; + mp_limb_t mod; + + do { mod = n_randtest_prime(state, 0); } while (mod == 2); + n = 1 + n_randtest(state) % 100; + n = FLINT_MIN(n, mod); + + nmod_poly_init(A, mod); + nmod_poly_init(sinhA, mod); + nmod_poly_init(B, mod); + + nmod_poly_randtest(A, state, n_randint(state, 100)); + nmod_poly_set_coeff_ui(A, 0, UWORD(0)); + + nmod_poly_sinh_series(sinhA, A, n); + nmod_poly_asinh_series(B, sinhA, n); + + nmod_poly_truncate(A, n); + + result = nmod_poly_equal(A, B); + + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("n = %wd, mod = %wu\n", n, mod); + flint_printf("A: "); nmod_poly_print(A), flint_printf("\n\n"); + flint_printf("sinh(A): "); nmod_poly_print(sinhA), flint_printf("\n\n"); + flint_printf("B: "); nmod_poly_print(B), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(A); + nmod_poly_clear(sinhA); + nmod_poly_clear(B); + } + + /* Check aliasing */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t A, B; + slong n; + mp_limb_t mod; + mod = n_randtest_prime(state, 0); + n = n_randtest(state) % 50; + n = FLINT_MIN(n, mod); + + nmod_poly_init(A, mod); + nmod_poly_init(B, mod); + nmod_poly_randtest(A, state, n_randint(state, 50)); + nmod_poly_set_coeff_ui(A, 0, UWORD(0)); + + nmod_poly_sinh_series(B, A, n); + nmod_poly_sinh_series(A, A, n); + + result = nmod_poly_equal(A, B); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(A), flint_printf("\n\n"); + nmod_poly_print(B), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(A); + nmod_poly_clear(B); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-sqrt.c b/external/flint-2.4.3/nmod_poly/test/t-sqrt.c new file mode 100644 index 0000000..137138c --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-sqrt.c @@ -0,0 +1,160 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + flint_printf("sqrt... "); + fflush(stdout); + + + + /* Test aliasing */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b; + int square1, square2; + mp_limb_t mod; + mod = n_randtest_prime(state, 0); + + nmod_poly_init(a, mod); + nmod_poly_init(b, mod); + + nmod_poly_randtest(a, state, 1 + n_randint(state, 50)); + + if (n_randint(state, 2)) + nmod_poly_mul(a, a, a); + + square1 = nmod_poly_sqrt(b, a); + square2 = nmod_poly_sqrt(a, a); + + if ((square1 != square2) || (square1 && !nmod_poly_equal(a, b))) + { + flint_printf("FAIL: aliasing:\n"); + flint_printf("square1 = %d, square2 = %d\n\n", square1, square2); + flint_printf("a: "); nmod_poly_print(a); flint_printf("\n\n"); + flint_printf("b: "); nmod_poly_print(b); flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + } + + /* Test random squares */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c; + int square; + mp_limb_t mod; + mod = n_randtest_prime(state, 0); + + nmod_poly_init(a, mod); + nmod_poly_init(b, mod); + nmod_poly_init(c, mod); + + nmod_poly_randtest(a, state, 1 + n_randint(state, 50)); + nmod_poly_mul(b, a, a); + square = nmod_poly_sqrt(c, b); + + if (!square) + { + flint_printf("FAIL: square reported nonsquare:\n"); + flint_printf("a: "); nmod_poly_print(a); flint_printf("\n\n"); + flint_printf("b: "); nmod_poly_print(b); flint_printf("\n\n"); + flint_printf("c: "); nmod_poly_print(c); flint_printf("\n\n"); + abort(); + } + + nmod_poly_mul(c, c, c); + if (!nmod_poly_equal(c, b)) + { + flint_printf("FAIL: sqrt(b)^2 != b:\n"); + flint_printf("a: "); nmod_poly_print(a); flint_printf("\n\n"); + flint_printf("b: "); nmod_poly_print(b); flint_printf("\n\n"); + flint_printf("c: "); nmod_poly_print(c); flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + } + + /* Test "almost" squares */ + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c; + slong j; + int square; + mp_limb_t mod; + mod = n_randtest_prime(state, 0); + + nmod_poly_init(a, mod); + nmod_poly_init(b, mod); + nmod_poly_init(c, mod); + + nmod_poly_randtest_not_zero(a, state, 1 + n_randint(state, 50)); + nmod_poly_mul(b, a, a); + + j = n_randint(state, nmod_poly_length(b)); + b->coeffs[j] = n_randint(state, mod); + _nmod_poly_normalise(b); + + square = nmod_poly_sqrt(c, b); + + if (square) + { + nmod_poly_mul(c, c, c); + if (!nmod_poly_equal(c, b)) + { + flint_printf("FAIL: sqrt(b)^2 != b:\n"); + flint_printf("a: "); nmod_poly_print(a); flint_printf("\n\n"); + flint_printf("b: "); nmod_poly_print(b); flint_printf("\n\n"); + flint_printf("c: "); nmod_poly_print(c); flint_printf("\n\n"); + abort(); + } + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-sqrt_series.c b/external/flint-2.4.3/nmod_poly/test/t-sqrt_series.c new file mode 100644 index 0000000..f1ff689 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-sqrt_series.c @@ -0,0 +1,123 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("sqrt_series...."); + fflush(stdout); + + /* Check g^2 = h mod x^m */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t h, g, r; + slong m; + + mp_limb_t n; + do n = n_randtest_prime(state, 0); + while (n == UWORD(2)); + + nmod_poly_init(h, n); + nmod_poly_init(g, n); + nmod_poly_init(r, n); + + do nmod_poly_randtest(h, state, n_randint(state, 1000)); + while (h->length == 0); + nmod_poly_set_coeff_ui(h, 0, UWORD(1)); + + m = n_randint(state, h->length) + 1; + + nmod_poly_sqrt_series(g, h, m); + nmod_poly_mullow(r, g, g, m); + nmod_poly_truncate(h, m); + + result = (nmod_poly_equal(r, h)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(h), flint_printf("\n\n"); + nmod_poly_print(g), flint_printf("\n\n"); + nmod_poly_print(r), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(h); + nmod_poly_clear(g); + nmod_poly_clear(r); + } + + /* Check aliasing of h and g */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t g, h; + slong m; + + mp_limb_t n; + do n = n_randtest_prime(state, 0); + while (n == UWORD(2)); + + nmod_poly_init(h, n); + nmod_poly_init(g, n); + do nmod_poly_randtest(h, state, n_randint(state, 500)); + while (h->length == 0); + nmod_poly_set_coeff_ui(h, 0, UWORD(1)); + + m = n_randint(state, h->length) + 1; + + nmod_poly_sqrt_series(g, h, m); + nmod_poly_sqrt_series(h, h, m); + + result = (nmod_poly_equal(g, h)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(h), flint_printf("\n\n"); + nmod_poly_print(g), flint_printf("\n\n"); + flint_printf("n = %wd, m = %wd\n", n, m); + abort(); + } + + nmod_poly_clear(g); + nmod_poly_clear(h); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-sub.c b/external/flint-2.4.3/nmod_poly/test/t-sub.c new file mode 100644 index 0000000..3200d1d --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-sub.c @@ -0,0 +1,142 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("sub...."); + fflush(stdout); + + /* Check a - b = a + neg(b) */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c, d; + mp_limb_t n = n_randtest_not_zero(state); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(c, n); + nmod_poly_init(d, n); + nmod_poly_randtest(a, state, n_randint(state, 100)); + nmod_poly_randtest(b, state, n_randint(state, 100)); + + nmod_poly_sub(c, a, b); + nmod_poly_neg(b, b); + nmod_poly_add(d, a, b); + + result = (nmod_poly_equal(d, d)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(c), flint_printf("\n\n"); + nmod_poly_print(d), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + nmod_poly_clear(d); + } + + /* Check aliasing of a and c */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c; + mp_limb_t n = n_randtest_not_zero(state); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(c, n); + nmod_poly_randtest(a, state, n_randint(state, 100)); + nmod_poly_randtest(b, state, n_randint(state, 100)); + + nmod_poly_sub(c, a, b); + nmod_poly_sub(a, a, b); + + result = (nmod_poly_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(c), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + } + + /* Check aliasing of b and c */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c; + mp_limb_t n = n_randtest_not_zero(state); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(c, n); + nmod_poly_randtest(a, state, n_randint(state, 100)); + nmod_poly_randtest(b, state, n_randint(state, 100)); + + nmod_poly_sub(c, a, b); + nmod_poly_sub(b, a, b); + + result = (nmod_poly_equal(b, c)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(c), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-tan_series.c b/external/flint-2.4.3/nmod_poly/test/t-tan_series.c new file mode 100644 index 0000000..55e4885 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-tan_series.c @@ -0,0 +1,119 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result = 1; + FLINT_TEST_INIT(state); + + + flint_printf("tan_series...."); + fflush(stdout); + + /* Check atan(tan(A)) = A */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t A, tanA, B; + slong n; + mp_limb_t mod; + + mod = n_randtest_prime(state, 0); + n = 1 + n_randtest(state) % 100; + n = FLINT_MIN(n, mod); + + nmod_poly_init(A, mod); + nmod_poly_init(tanA, mod); + nmod_poly_init(B, mod); + + nmod_poly_randtest(A, state, n_randint(state, 100)); + nmod_poly_set_coeff_ui(A, 0, UWORD(0)); + + nmod_poly_tan_series(tanA, A, n); + nmod_poly_atan_series(B, tanA, n); + + nmod_poly_truncate(A, n); + + result = nmod_poly_equal(A, B); + + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("n = %wd, mod = %wu\n", n, mod); + flint_printf("A: "); nmod_poly_print(A), flint_printf("\n\n"); + flint_printf("tan(A): "); nmod_poly_print(tanA), flint_printf("\n\n"); + flint_printf("B: "); nmod_poly_print(B), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(A); + nmod_poly_clear(tanA); + nmod_poly_clear(B); + } + + /* Check aliasing */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t A, B; + slong n; + mp_limb_t mod; + mod = n_randtest_prime(state, 0); + n = n_randtest(state) % 50; + n = FLINT_MIN(n, mod); + + nmod_poly_init(A, mod); + nmod_poly_init(B, mod); + nmod_poly_randtest(A, state, n_randint(state, 50)); + nmod_poly_set_coeff_ui(A, 0, UWORD(0)); + + nmod_poly_tan_series(B, A, n); + nmod_poly_tan_series(A, A, n); + + result = nmod_poly_equal(A, B); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(A), flint_printf("\n\n"); + nmod_poly_print(B), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(A); + nmod_poly_clear(B); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-tanh_series.c b/external/flint-2.4.3/nmod_poly/test/t-tanh_series.c new file mode 100644 index 0000000..660c1ed --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-tanh_series.c @@ -0,0 +1,119 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result = 1; + FLINT_TEST_INIT(state); + + + flint_printf("tanh_series...."); + fflush(stdout); + + /* Check atanh(tanh(A)) = A */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t A, tanhA, B; + slong n; + mp_limb_t mod; + + do { mod = n_randtest_prime(state, 0); } while (mod == 2); + n = 1 + n_randtest(state) % 100; + n = FLINT_MIN(n, mod); + + nmod_poly_init(A, mod); + nmod_poly_init(tanhA, mod); + nmod_poly_init(B, mod); + + nmod_poly_randtest(A, state, n_randint(state, 100)); + nmod_poly_set_coeff_ui(A, 0, UWORD(0)); + + nmod_poly_tanh_series(tanhA, A, n); + nmod_poly_atanh_series(B, tanhA, n); + + nmod_poly_truncate(A, n); + + result = nmod_poly_equal(A, B); + + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("n = %wd, mod = %wu\n", n, mod); + flint_printf("A: "); nmod_poly_print(A), flint_printf("\n\n"); + flint_printf("tanh(A): "); nmod_poly_print(tanhA), flint_printf("\n\n"); + flint_printf("B: "); nmod_poly_print(B), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(A); + nmod_poly_clear(tanhA); + nmod_poly_clear(B); + } + + /* Check aliasing */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_t A, B; + slong n; + mp_limb_t mod; + mod = n_randtest_prime(state, 0); + n = n_randtest(state) % 50; + n = FLINT_MIN(n, mod); + + nmod_poly_init(A, mod); + nmod_poly_init(B, mod); + nmod_poly_randtest(A, state, n_randint(state, 50)); + nmod_poly_set_coeff_ui(A, 0, UWORD(0)); + + nmod_poly_tanh_series(B, A, n); + nmod_poly_tanh_series(A, A, n); + + result = nmod_poly_equal(A, B); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(A), flint_printf("\n\n"); + nmod_poly_print(B), flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(A); + nmod_poly_clear(B); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-taylor_shift.c b/external/flint-2.4.3/nmod_poly/test/t-taylor_shift.c new file mode 100644 index 0000000..8737d32 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-taylor_shift.c @@ -0,0 +1,153 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_poly.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + flint_printf("taylor_shift...."); + fflush(stdout); + + + + /* Check aliasing */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t f, g; + mp_limb_t c, mod; + + mod = n_randtest_prime(state, 0); + + nmod_poly_init(f, mod); + nmod_poly_init(g, mod); + + nmod_poly_randtest(f, state, 1 + n_randint(state, 50)); + c = n_randtest(state) % mod; + + nmod_poly_taylor_shift(g, f, c); + nmod_poly_taylor_shift(f, f, c); + + if (!nmod_poly_equal(g, f)) + { + flint_printf("FAIL\n"); + nmod_poly_print(f); flint_printf("\n"); + nmod_poly_print(g); flint_printf("\n"); + abort(); + } + + nmod_poly_clear(f); + nmod_poly_clear(g); + } + + /* Compare with composition */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t f, g, h1, h2; + mp_limb_t mod, c; + + mod = n_randtest_prime(state, 0); + + nmod_poly_init(f, mod); + nmod_poly_init(g, mod); + nmod_poly_init(h1, mod); + nmod_poly_init(h2, mod); + + nmod_poly_randtest(f, state, 1 + n_randint(state, 50)); + c = n_randtest(state) % mod; + + nmod_poly_set_coeff_ui(g, 1, 1); + nmod_poly_set_coeff_ui(g, 0, c); + + nmod_poly_taylor_shift(h1, f, c); + nmod_poly_compose(h2, f, g); + + if (!nmod_poly_equal(h1, h2)) + { + flint_printf("FAIL\n"); + nmod_poly_print(f); flint_printf("\n"); + nmod_poly_print(g); flint_printf("\n"); + nmod_poly_print(h1); flint_printf("\n"); + nmod_poly_print(h2); flint_printf("\n"); + abort(); + } + + nmod_poly_clear(f); + nmod_poly_clear(g); + nmod_poly_clear(h1); + nmod_poly_clear(h2); + } + + /* Check some large cases */ + for (i = 0; i < 10 * flint_test_multiplier(); i++) + { + nmod_poly_t f, g, h1, h2; + mp_limb_t mod, c; + + mod = n_randtest_prime(state, 0); + + nmod_poly_init(f, mod); + nmod_poly_init(g, mod); + nmod_poly_init(h1, mod); + nmod_poly_init(h2, mod); + + nmod_poly_randtest(f, state, 1 + n_randint(state, 2000)); + c = n_randtest(state) % mod; + + nmod_poly_set_coeff_ui(g, 1, 1); + nmod_poly_set_coeff_ui(g, 0, c); + + nmod_poly_taylor_shift(h1, f, c); + nmod_poly_compose(h2, f, g); + + if (!nmod_poly_equal(h1, h2)) + { + flint_printf("FAIL\n"); + nmod_poly_print(f); flint_printf("\n"); + nmod_poly_print(g); flint_printf("\n"); + nmod_poly_print(h1); flint_printf("\n"); + nmod_poly_print(h2); flint_printf("\n"); + abort(); + } + + nmod_poly_clear(f); + nmod_poly_clear(g); + nmod_poly_clear(h1); + nmod_poly_clear(h2); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-taylor_shift_convolution.c b/external/flint-2.4.3/nmod_poly/test/t-taylor_shift_convolution.c new file mode 100644 index 0000000..87589aa --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-taylor_shift_convolution.c @@ -0,0 +1,123 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_poly.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + flint_printf("taylor_shift_convolution...."); + fflush(stdout); + + + + /* Check aliasing */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t f, g; + slong n; + mp_limb_t c, mod; + + n = n_randint(state, 100); + do { + mod = n_randtest_prime(state, 0); + } while (mod <= n); + + nmod_poly_init(f, mod); + nmod_poly_init(g, mod); + + nmod_poly_randtest(f, state, n); + c = n_randtest(state) % mod; + + nmod_poly_taylor_shift_convolution(g, f, c); + nmod_poly_taylor_shift_convolution(f, f, c); + + if (!nmod_poly_equal(g, f)) + { + flint_printf("FAIL\n"); + nmod_poly_print(f); flint_printf("\n"); + nmod_poly_print(g); flint_printf("\n"); + abort(); + } + + nmod_poly_clear(f); + nmod_poly_clear(g); + } + + /* Compare with composition */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t f, g, h1, h2; + mp_limb_t mod, c; + slong n; + + n = n_randint(state, 100); + do { + mod = n_randtest_prime(state, 0); + } while (mod <= n); + + nmod_poly_init(f, mod); + nmod_poly_init(g, mod); + nmod_poly_init(h1, mod); + nmod_poly_init(h2, mod); + + nmod_poly_randtest(f, state, n); + c = n_randtest(state) % mod; + + nmod_poly_set_coeff_ui(g, 1, 1); + nmod_poly_set_coeff_ui(g, 0, c); + + nmod_poly_taylor_shift_convolution(h1, f, c); + nmod_poly_compose(h2, f, g); + + if (!nmod_poly_equal(h1, h2)) + { + flint_printf("FAIL\n"); + nmod_poly_print(f); flint_printf("\n"); + nmod_poly_print(g); flint_printf("\n"); + nmod_poly_print(h1); flint_printf("\n"); + nmod_poly_print(h2); flint_printf("\n"); + abort(); + } + + nmod_poly_clear(f); + nmod_poly_clear(g); + nmod_poly_clear(h1); + nmod_poly_clear(h2); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-taylor_shift_horner.c b/external/flint-2.4.3/nmod_poly/test/t-taylor_shift_horner.c new file mode 100644 index 0000000..e236a91 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-taylor_shift_horner.c @@ -0,0 +1,115 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_poly.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + flint_printf("taylor_shift_horner...."); + fflush(stdout); + + + + /* Check aliasing */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t f, g; + mp_limb_t c, mod; + + mod = n_randtest_prime(state, 0); + + nmod_poly_init(f, mod); + nmod_poly_init(g, mod); + + nmod_poly_randtest(f, state, 1 + n_randint(state, 50)); + c = n_randtest(state) % mod; + + nmod_poly_taylor_shift_horner(g, f, c); + nmod_poly_taylor_shift_horner(f, f, c); + + if (!nmod_poly_equal(g, f)) + { + flint_printf("FAIL\n"); + nmod_poly_print(f); flint_printf("\n"); + nmod_poly_print(g); flint_printf("\n"); + abort(); + } + + nmod_poly_clear(f); + nmod_poly_clear(g); + } + + /* Compare with composition */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t f, g, h1, h2; + mp_limb_t mod, c; + + mod = n_randtest_prime(state, 0); + + nmod_poly_init(f, mod); + nmod_poly_init(g, mod); + nmod_poly_init(h1, mod); + nmod_poly_init(h2, mod); + + nmod_poly_randtest(f, state, 1 + n_randint(state, 50)); + c = n_randtest(state) % mod; + + nmod_poly_set_coeff_ui(g, 1, 1); + nmod_poly_set_coeff_ui(g, 0, c); + + nmod_poly_taylor_shift_horner(h1, f, c); + nmod_poly_compose(h2, f, g); + + if (!nmod_poly_equal(h1, h2)) + { + flint_printf("FAIL\n"); + nmod_poly_print(f); flint_printf("\n"); + nmod_poly_print(g); flint_printf("\n"); + nmod_poly_print(h1); flint_printf("\n"); + nmod_poly_print(h2); flint_printf("\n"); + abort(); + } + + nmod_poly_clear(f); + nmod_poly_clear(g); + nmod_poly_clear(h1); + nmod_poly_clear(h2); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-xgcd.c b/external/flint-2.4.3/nmod_poly/test/t-xgcd.c new file mode 100644 index 0000000..69a8c00 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-xgcd.c @@ -0,0 +1,333 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("xgcd...."); + fflush(stdout); + + /* + Compare with result from gcd and check a*s + b*t = g + */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c, g1, g2, s, t, sum, temp; + + mp_limb_t n; + do n = n_randtest_not_zero(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(c, n); + nmod_poly_init(g1, n); + nmod_poly_init(g2, n); + nmod_poly_init(s, n); + nmod_poly_init(t, n); + nmod_poly_init(sum, n); + nmod_poly_init(temp, n); + + nmod_poly_randtest(a, state, n_randtest(state) % 600); + nmod_poly_randtest(b, state, n_randtest(state) % 600); + nmod_poly_randtest(c, state, n_randtest(state) % 400); + + nmod_poly_mul(a, a, c); + nmod_poly_mul(b, b, c); + + nmod_poly_gcd(g1, a, b); + nmod_poly_xgcd(g2, s, t, a, b); + + nmod_poly_mul(sum, s, a); + nmod_poly_mul(temp, t, b); + nmod_poly_add(sum, sum, temp); + + result = (nmod_poly_equal(g1, g2) && nmod_poly_equal(g1, sum) + && (g1->length == 0 || g1->coeffs[g1->length - 1] == 1)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(c), flint_printf("\n\n"); + nmod_poly_print(g1), flint_printf("\n\n"); + nmod_poly_print(g2), flint_printf("\n\n"); + nmod_poly_print(sum), flint_printf("\n\n"); + nmod_poly_print(s), flint_printf("\n\n"); + nmod_poly_print(t), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + nmod_poly_clear(g1); + nmod_poly_clear(g2); + nmod_poly_clear(s); + nmod_poly_clear(t); + nmod_poly_clear(sum); + nmod_poly_clear(temp); + } + + /* Check aliasing of a and g */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, g, s, t; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(g, n); + nmod_poly_init(s, n); + nmod_poly_init(t, n); + nmod_poly_randtest(a, state, n_randtest(state) % 600); + nmod_poly_randtest(b, state, n_randtest(state) % 600); + + nmod_poly_xgcd(g, s, t, a, b); + nmod_poly_xgcd(a, s, t, a, b); + + result = (nmod_poly_equal(a, g)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(g), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(g); + nmod_poly_clear(s); + nmod_poly_clear(t); + } + + /* Check aliasing of b and g */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, g, s, t; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(g, n); + nmod_poly_init(s, n); + nmod_poly_init(t, n); + nmod_poly_randtest(a, state, n_randtest(state) % 600); + nmod_poly_randtest(b, state, n_randtest(state) % 600); + + nmod_poly_xgcd(g, s, t, a, b); + nmod_poly_xgcd(b, s, t, a, b); + + result = (nmod_poly_equal(b, g)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(g), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(g); + nmod_poly_clear(s); + nmod_poly_clear(t); + } + + /* Check aliasing of s and a */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, g, s, t; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(g, n); + nmod_poly_init(s, n); + nmod_poly_init(t, n); + nmod_poly_randtest(a, state, n_randtest(state) % 600); + nmod_poly_randtest(b, state, n_randtest(state) % 600); + + nmod_poly_xgcd(g, s, t, a, b); + nmod_poly_xgcd(g, a, t, a, b); + + result = (nmod_poly_equal(s, a)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(s), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(g); + nmod_poly_clear(s); + nmod_poly_clear(t); + } + + /* Check aliasing of s and b */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, g, s, t; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(g, n); + nmod_poly_init(s, n); + nmod_poly_init(t, n); + nmod_poly_randtest(a, state, n_randtest(state) % 600); + nmod_poly_randtest(b, state, n_randtest(state) % 600); + + nmod_poly_xgcd(g, s, t, a, b); + nmod_poly_xgcd(g, b, t, a, b); + + result = (nmod_poly_equal(s, b)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(s), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(g); + nmod_poly_clear(s); + nmod_poly_clear(t); + } + + /* Check aliasing of t and a */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, g, s, t; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(g, n); + nmod_poly_init(s, n); + nmod_poly_init(t, n); + nmod_poly_randtest(a, state, n_randtest(state) % 600); + nmod_poly_randtest(b, state, n_randtest(state) % 600); + + nmod_poly_xgcd(g, s, t, a, b); + nmod_poly_xgcd(g, s, a, a, b); + + result = (nmod_poly_equal(t, a)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(t), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(g); + nmod_poly_clear(s); + nmod_poly_clear(t); + } + + /* Check aliasing of t and b */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, g, s, t; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(g, n); + nmod_poly_init(s, n); + nmod_poly_init(t, n); + nmod_poly_randtest(a, state, n_randtest(state) % 600); + nmod_poly_randtest(b, state, n_randtest(state) % 600); + + nmod_poly_xgcd(g, s, t, a, b); + nmod_poly_xgcd(g, s, b, a, b); + + result = (nmod_poly_equal(t, b)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(t), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(g); + nmod_poly_clear(s); + nmod_poly_clear(t); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-xgcd_euclidean.c b/external/flint-2.4.3/nmod_poly/test/t-xgcd_euclidean.c new file mode 100644 index 0000000..87717c9 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-xgcd_euclidean.c @@ -0,0 +1,327 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 William Hart + +******************************************************************************/ + +#include +#include +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("xgcd_euclidean...."); + fflush(stdout); + + /* + Compare with result from gcd and check a*s + b*t = g + */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c, g1, s, t, g2; + + mp_limb_t n; + do n = n_randtest_not_zero(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(c, n); + nmod_poly_init(g1, n); + nmod_poly_init(g2, n); + nmod_poly_init(s, n); + nmod_poly_init(t, n); + + nmod_poly_randtest(a, state, n_randtest(state) % 200); + nmod_poly_randtest(b, state, n_randtest(state) % 200); + nmod_poly_randtest(c, state, n_randtest(state) % 200); + + nmod_poly_mul(a, a, c); + nmod_poly_mul(b, b, c); + + nmod_poly_gcd_euclidean(g1, a, b); + nmod_poly_xgcd_euclidean(g2, s, t, a, b); + + nmod_poly_mul(s, s, a); + nmod_poly_mul(t, t, b); + nmod_poly_add(s, s, t); + + result = (nmod_poly_equal(g1, g2) && nmod_poly_equal(s, g1) + && (g1->length == 0 || g1->coeffs[g1->length - 1] == 1)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(c), flint_printf("\n\n"); + nmod_poly_print(g1), flint_printf("\n\n"); + nmod_poly_print(g2), flint_printf("\n\n"); + nmod_poly_print(s), flint_printf("\n\n"); + nmod_poly_print(t), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + nmod_poly_clear(g1); + nmod_poly_clear(g2); + nmod_poly_clear(s); + nmod_poly_clear(t); + } + + /* Check aliasing of a and g */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, g, s, t; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(g, n); + nmod_poly_init(s, n); + nmod_poly_init(t, n); + nmod_poly_randtest(a, state, n_randtest(state) % 200); + nmod_poly_randtest(b, state, n_randtest(state) % 200); + + nmod_poly_xgcd_euclidean(g, s, t, a, b); + nmod_poly_xgcd_euclidean(a, s, t, a, b); + + result = (nmod_poly_equal(a, g)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(g), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(g); + nmod_poly_clear(s); + nmod_poly_clear(t); + } + + /* Check aliasing of b and g */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, g, s, t; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(g, n); + nmod_poly_init(s, n); + nmod_poly_init(t, n); + nmod_poly_randtest(a, state, n_randtest(state) % 200); + nmod_poly_randtest(b, state, n_randtest(state) % 200); + + nmod_poly_xgcd_euclidean(g, s, t, a, b); + nmod_poly_xgcd_euclidean(b, s, t, a, b); + + result = (nmod_poly_equal(b, g)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(g), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(g); + nmod_poly_clear(s); + nmod_poly_clear(t); + } + + /* Check aliasing of s and a */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, g, s, t; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(g, n); + nmod_poly_init(s, n); + nmod_poly_init(t, n); + nmod_poly_randtest(a, state, n_randtest(state) % 200); + nmod_poly_randtest(b, state, n_randtest(state) % 200); + + nmod_poly_xgcd_euclidean(g, s, t, a, b); + nmod_poly_xgcd_euclidean(g, a, t, a, b); + + result = (nmod_poly_equal(s, a)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(s), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(g); + nmod_poly_clear(s); + nmod_poly_clear(t); + } + + /* Check aliasing of s and b */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, g, s, t; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(g, n); + nmod_poly_init(s, n); + nmod_poly_init(t, n); + nmod_poly_randtest(a, state, n_randtest(state) % 200); + nmod_poly_randtest(b, state, n_randtest(state) % 200); + + nmod_poly_xgcd_euclidean(g, s, t, a, b); + nmod_poly_xgcd_euclidean(g, b, t, a, b); + + result = (nmod_poly_equal(s, b)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(s), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(g); + nmod_poly_clear(s); + nmod_poly_clear(t); + } + + /* Check aliasing of t and a */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, g, s, t; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(g, n); + nmod_poly_init(s, n); + nmod_poly_init(t, n); + nmod_poly_randtest(a, state, n_randtest(state) % 200); + nmod_poly_randtest(b, state, n_randtest(state) % 200); + + nmod_poly_xgcd_euclidean(g, s, t, a, b); + nmod_poly_xgcd_euclidean(g, s, a, a, b); + + result = (nmod_poly_equal(t, a)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(t), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(g); + nmod_poly_clear(s); + nmod_poly_clear(t); + } + + /* Check aliasing of t and b */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, g, s, t; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(g, n); + nmod_poly_init(s, n); + nmod_poly_init(t, n); + nmod_poly_randtest(a, state, n_randtest(state) % 200); + nmod_poly_randtest(b, state, n_randtest(state) % 200); + + nmod_poly_xgcd_euclidean(g, s, t, a, b); + nmod_poly_xgcd_euclidean(g, s, b, a, b); + + result = (nmod_poly_equal(t, b)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(t), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(g); + nmod_poly_clear(s); + nmod_poly_clear(t); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/test/t-xgcd_hgcd.c b/external/flint-2.4.3/nmod_poly/test/t-xgcd_hgcd.c new file mode 100644 index 0000000..a83f20e --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/test/t-xgcd_hgcd.c @@ -0,0 +1,332 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 William Hart + +******************************************************************************/ + +#include +#include +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("xgcd_hgcd...."); + fflush(stdout); + + /* + Compare with result from gcd and check a*s + b*t = g + */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, c, g1, g2, s, t, sum, temp; + + mp_limb_t n; + do n = n_randtest_not_zero(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(c, n); + nmod_poly_init(g1, n); + nmod_poly_init(g2, n); + nmod_poly_init(s, n); + nmod_poly_init(t, n); + nmod_poly_init(sum, n); + nmod_poly_init(temp, n); + + nmod_poly_randtest(a, state, n_randtest(state) % 600); + nmod_poly_randtest(b, state, n_randtest(state) % 600); + nmod_poly_randtest(c, state, n_randtest(state) % 400); + + nmod_poly_mul(a, a, c); + nmod_poly_mul(b, b, c); + + nmod_poly_gcd(g1, a, b); + nmod_poly_xgcd_hgcd(g2, s, t, a, b); + + nmod_poly_mul(sum, s, a); + nmod_poly_mul(temp, t, b); + nmod_poly_add(sum, sum, temp); + + result = (nmod_poly_equal(g1, g2) && nmod_poly_equal(g1, sum) + && (g1->length == 0 || g1->coeffs[g1->length - 1] == 1)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(c), flint_printf("\n\n"); + nmod_poly_print(g1), flint_printf("\n\n"); + nmod_poly_print(g2), flint_printf("\n\n"); + nmod_poly_print(sum), flint_printf("\n\n"); + nmod_poly_print(s), flint_printf("\n\n"); + nmod_poly_print(t), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(c); + nmod_poly_clear(g1); + nmod_poly_clear(g2); + nmod_poly_clear(s); + nmod_poly_clear(t); + nmod_poly_clear(sum); + nmod_poly_clear(temp); + } + + /* Check aliasing of a and g */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, g, s, t; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(g, n); + nmod_poly_init(s, n); + nmod_poly_init(t, n); + nmod_poly_randtest(a, state, n_randtest(state) % 200); + nmod_poly_randtest(b, state, n_randtest(state) % 200); + + nmod_poly_xgcd_hgcd(g, s, t, a, b); + nmod_poly_xgcd_hgcd(a, s, t, a, b); + + result = (nmod_poly_equal(a, g)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(g), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(g); + nmod_poly_clear(s); + nmod_poly_clear(t); + } + + /* Check aliasing of b and g */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, g, s, t; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(g, n); + nmod_poly_init(s, n); + nmod_poly_init(t, n); + nmod_poly_randtest(a, state, n_randtest(state) % 200); + nmod_poly_randtest(b, state, n_randtest(state) % 200); + + nmod_poly_xgcd_hgcd(g, s, t, a, b); + nmod_poly_xgcd_hgcd(b, s, t, a, b); + + result = (nmod_poly_equal(b, g)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(g), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(g); + nmod_poly_clear(s); + nmod_poly_clear(t); + } + + /* Check aliasing of s and a */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, g, s, t; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(g, n); + nmod_poly_init(s, n); + nmod_poly_init(t, n); + nmod_poly_randtest(a, state, n_randtest(state) % 200); + nmod_poly_randtest(b, state, n_randtest(state) % 200); + + nmod_poly_xgcd_hgcd(g, s, t, a, b); + nmod_poly_xgcd_hgcd(g, a, t, a, b); + + result = (nmod_poly_equal(s, a)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(s), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(g); + nmod_poly_clear(s); + nmod_poly_clear(t); + } + + /* Check aliasing of s and b */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, g, s, t; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(g, n); + nmod_poly_init(s, n); + nmod_poly_init(t, n); + nmod_poly_randtest(a, state, n_randtest(state) % 200); + nmod_poly_randtest(b, state, n_randtest(state) % 200); + + nmod_poly_xgcd_hgcd(g, s, t, a, b); + nmod_poly_xgcd_hgcd(g, b, t, a, b); + + result = (nmod_poly_equal(s, b)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(s), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(g); + nmod_poly_clear(s); + nmod_poly_clear(t); + } + + /* Check aliasing of t and a */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, g, s, t; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(g, n); + nmod_poly_init(s, n); + nmod_poly_init(t, n); + nmod_poly_randtest(a, state, n_randtest(state) % 200); + nmod_poly_randtest(b, state, n_randtest(state) % 200); + + nmod_poly_xgcd_hgcd(g, s, t, a, b); + nmod_poly_xgcd_hgcd(g, s, a, a, b); + + result = (nmod_poly_equal(t, a)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(a), flint_printf("\n\n"); + nmod_poly_print(t), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(g); + nmod_poly_clear(s); + nmod_poly_clear(t); + } + + /* Check aliasing of t and b */ + for (i = 0; i < 20 * flint_test_multiplier(); i++) + { + nmod_poly_t a, b, g, s, t; + + mp_limb_t n; + do n = n_randtest(state); + while (!n_is_probabprime(n)); + + nmod_poly_init(a, n); + nmod_poly_init(b, n); + nmod_poly_init(g, n); + nmod_poly_init(s, n); + nmod_poly_init(t, n); + nmod_poly_randtest(a, state, n_randtest(state) % 200); + nmod_poly_randtest(b, state, n_randtest(state) % 200); + + nmod_poly_xgcd_hgcd(g, s, t, a, b); + nmod_poly_xgcd_hgcd(g, s, b, a, b); + + result = (nmod_poly_equal(t, b)); + if (!result) + { + flint_printf("FAIL:\n"); + nmod_poly_print(b), flint_printf("\n\n"); + nmod_poly_print(t), flint_printf("\n\n"); + flint_printf("n = %wd\n", n); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(g); + nmod_poly_clear(s); + nmod_poly_clear(t); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly/tree.c b/external/flint-2.4.3/nmod_poly/tree.c new file mode 100644 index 0000000..f3dfe4e --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/tree.c @@ -0,0 +1,123 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +mp_ptr * _nmod_poly_tree_alloc(slong len) +{ + mp_ptr * tree = NULL; + + if (len) + { + slong i, height = FLINT_CLOG2(len); + + tree = flint_malloc(sizeof(mp_ptr) * (height + 1)); + for (i = 0; i <= height; i++) + tree[i] = _nmod_vec_init(len + (len >> i) + 1); + } + + return tree; +} + +void _nmod_poly_tree_free(mp_ptr * tree, slong len) +{ + if (len) + { + slong i, height = FLINT_CLOG2(len); + + for (i = 0; i <= height; i++) + flint_free(tree[i]); + + flint_free(tree); + } +} + +void +_nmod_poly_tree_build(mp_ptr * tree, mp_srcptr roots, slong len, nmod_t mod) +{ + slong height, pow, left, i; + mp_ptr pa, pb; + + if (len == 0) + return; + + height = FLINT_CLOG2(len); + + /* zeroth level, (x-a) */ + for (i = 0; i < len; i++) + { + tree[0][2 * i + 1] = 1; + tree[0][2 * i] = nmod_neg(roots[i], mod); + } + + /* 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++) + { + mp_limb_t a, b; + + a = roots[2 * i]; + b = roots[2 * i + 1]; + + pa[3 * i] = nmod_mul(a, b, mod); + pa[3 * i + 1] = nmod_neg(nmod_add(a, b, mod), mod); + pa[3 * i + 2] = 1; + } + + if (len & 1) + { + pa[3 * (len / 2)] = nmod_neg(roots[len-1], mod); + pa[3 * (len / 2) + 1] = 1; + } + } + + for (i = 1; i < height - 1; i++) + { + left = len; + pow = WORD(1) << i; + pa = tree[i]; + pb = tree[i + 1]; + + while (left >= 2 * pow) + { + _nmod_poly_mul(pb, pa, pow + 1, pa + pow + 1, pow + 1, mod); + left -= 2 * pow; + pa += 2 * pow + 2; + pb += 2 * pow + 1; + } + + if (left > pow) + _nmod_poly_mul(pb, pa, pow + 1, pa + pow + 1, left - pow + 1, mod); + else if (left > 0) + _nmod_vec_set(pb, pa, left + 1); + } +} diff --git a/external/flint-2.4.3/nmod_poly/xgcd.c b/external/flint-2.4.3/nmod_poly/xgcd.c new file mode 100644 index 0000000..6f01db8 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/xgcd.c @@ -0,0 +1,153 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "nmod_poly.h" +#include "mpn_extras.h" + +slong _nmod_poly_xgcd(mp_ptr G, mp_ptr S, mp_ptr T, + mp_srcptr A, slong lenA, mp_srcptr B, slong lenB, nmod_t mod) +{ + const slong cutoff = FLINT_BIT_COUNT(mod.n) <= 8 ? + NMOD_POLY_SMALL_GCD_CUTOFF : NMOD_POLY_GCD_CUTOFF; + + if (lenA < cutoff) + return _nmod_poly_xgcd_euclidean(G, S, T, A, lenA, B, lenB, mod); + else + return _nmod_poly_xgcd_hgcd(G, S, T, A, lenA, B, lenB, mod); +} + +void +nmod_poly_xgcd(nmod_poly_t G, nmod_poly_t S, nmod_poly_t T, + const nmod_poly_t A, const nmod_poly_t B) +{ + if (A->length < B->length) + { + nmod_poly_xgcd(G, T, S, B, A); + } + else /* lenA >= lenB >= 0 */ + { + const slong lenA = A->length, lenB = B->length; + mp_limb_t inv; + + if (lenA == 0) /* lenA = lenB = 0 */ + { + nmod_poly_zero(G); + nmod_poly_zero(S); + nmod_poly_zero(T); + } + else if (lenB == 0) /* lenA > lenB = 0 */ + { + inv = n_invmod(A->coeffs[lenA - 1], A->mod.n); + nmod_poly_scalar_mul_nmod(G, A, inv); + nmod_poly_zero(T); + nmod_poly_set_coeff_ui(S, 0, inv); + S->length = 1; + } + else if (lenB == 1) /* lenA >= lenB = 1 */ + { + nmod_poly_fit_length(T, 1); + T->length = 1; + T->coeffs[0] = n_invmod(B->coeffs[0], A->mod.n); + nmod_poly_one(G); + nmod_poly_zero(S); + } + else /* lenA >= lenB >= 2 */ + { + mp_ptr g, s, t; + slong lenG; + + if (G == A || G == B) + { + g = _nmod_vec_init(FLINT_MIN(lenA, lenB)); + } + else + { + nmod_poly_fit_length(G, FLINT_MIN(lenA, lenB)); + g = G->coeffs; + } + if (S == A || S == B) + { + s = _nmod_vec_init(lenB - 1); + } + else + { + nmod_poly_fit_length(S, lenB - 1); + s = S->coeffs; + } + if (T == A || T == B) + { + t = _nmod_vec_init(lenA - 1); + } + else + { + nmod_poly_fit_length(T, lenA - 1); + t = T->coeffs; + } + + if (lenA >= lenB) + lenG = _nmod_poly_xgcd(g, s, t, A->coeffs, lenA, + B->coeffs, lenB, A->mod); + else + lenG = _nmod_poly_xgcd(g, t, s, B->coeffs, lenB, + A->coeffs, lenA, A->mod); + + if (G == A || G == B) + { + flint_free(G->coeffs); + G->coeffs = g; + G->alloc = FLINT_MIN(lenA, lenB); + } + if (S == A || S == B) + { + flint_free(S->coeffs); + S->coeffs = s; + S->alloc = lenB - 1; + } + if (T == A || T == B) + { + flint_free(T->coeffs); + T->coeffs = t; + T->alloc = lenA - 1; + } + + G->length = lenG; + S->length = FLINT_MAX(lenB - lenG, 1); + T->length = FLINT_MAX(lenA - lenG, 1); + MPN_NORM(S->coeffs, S->length); + MPN_NORM(T->coeffs, T->length); + + if (G->coeffs[lenG - 1] != 1) + { + inv = n_invmod(G->coeffs[lenG - 1], A->mod.n); + nmod_poly_scalar_mul_nmod(G, G, inv); + nmod_poly_scalar_mul_nmod(S, S, inv); + nmod_poly_scalar_mul_nmod(T, T, inv); + } + } + } +} + diff --git a/external/flint-2.4.3/nmod_poly/xgcd_euclidean.c b/external/flint-2.4.3/nmod_poly/xgcd_euclidean.c new file mode 100644 index 0000000..ed0e1f2 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/xgcd_euclidean.c @@ -0,0 +1,247 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "nmod_poly.h" +#include "mpn_extras.h" + +slong _nmod_poly_xgcd_euclidean(mp_ptr G, mp_ptr S, mp_ptr T, + mp_srcptr A, slong lenA, + mp_srcptr B, slong lenB, nmod_t mod) +{ + flint_mpn_zero(G, lenB); + flint_mpn_zero(S, lenB - 1); + flint_mpn_zero(T, lenA - 1); + + if (lenB == 1) + { + G[0] = B[0]; + T[0] = 1; + return 1; + } + else + { + mp_ptr Q, R; + slong lenQ, lenR, lenG; + + Q = _nmod_vec_init(2 * lenA); + R = Q + lenA; + + _nmod_poly_divrem(Q, R, A, lenA, B, lenB, mod); + lenR = lenB - 1; + MPN_NORM(R, lenR); + + if (lenR == 0) + { + _nmod_vec_set(G, B, lenB); + T[0] = 1; + lenG = lenB; + } + else + { + mp_ptr D, U, V1, V3, W; + slong lenD, lenU, lenV1, lenV3, lenW; + + W = _nmod_vec_init(FLINT_MAX(5 * lenB, lenA + lenB)); + D = W + lenB; + U = D + lenB; + V1 = U + lenB; + V3 = V1 + lenB; + + lenU = 0; + _nmod_vec_set(D, B, lenB); + lenD = lenB; + V1[0] = 1; + lenV1 = 1; + lenV3 = 0; + MPN_SWAP(V3, lenV3, R, lenR); + + do { + _nmod_poly_divrem(Q, R, D, lenD, V3, lenV3, mod); + lenQ = lenD - lenV3 + 1; + lenR = lenV3 - 1; + MPN_NORM(R, lenR); + + if (lenV1 >= lenQ) + _nmod_poly_mul(W, V1, lenV1, Q, lenQ, mod); + else + _nmod_poly_mul(W, Q, lenQ, V1, lenV1, mod); + lenW = lenQ + lenV1 - 1; + + _nmod_poly_sub(U, U, lenU, W, lenW, mod); + lenU = FLINT_MAX(lenU, lenW); + MPN_NORM(U, lenU); + + MPN_SWAP(U, lenU, V1, lenV1); + { + mp_ptr __t; + slong __tn; + + __t = D; + D = V3; + V3 = R; + R = __t; + __tn = lenD; + lenD = lenV3; + lenV3 = lenR; + lenR = __tn; + } + + } while (lenV3 != 0); + + _nmod_vec_set(G, D, lenD); + _nmod_vec_set(S, U, lenU); + + { + lenQ = lenA + lenU - 1; + + _nmod_poly_mul(Q, A, lenA, S, lenU, mod); + _nmod_vec_neg(Q, Q, lenQ, mod); + _nmod_poly_add(Q, G, lenD, Q, lenQ, mod); + + _nmod_poly_divrem(T, W, Q, lenQ, B, lenB, mod); + } + + _nmod_vec_clear(W); + lenG = lenD; + } + + _nmod_vec_clear(Q); + return lenG; + } +} + +void +nmod_poly_xgcd_euclidean(nmod_poly_t G, nmod_poly_t S, nmod_poly_t T, + const nmod_poly_t A, const nmod_poly_t B) +{ + if (A->length < B->length) + { + nmod_poly_xgcd_euclidean(G, T, S, B, A); + } + else /* lenA >= lenB >= 0 */ + { + const slong lenA = A->length, lenB = B->length; + mp_limb_t inv; + + if (lenA == 0) /* lenA = lenB = 0 */ + { + nmod_poly_zero(G); + nmod_poly_zero(S); + nmod_poly_zero(T); + } + else if (lenB == 0) /* lenA > lenB = 0 */ + { + inv = n_invmod(A->coeffs[lenA - 1], A->mod.n); + nmod_poly_scalar_mul_nmod(G, A, inv); + nmod_poly_zero(T); + nmod_poly_set_coeff_ui(S, 0, inv); + S->length = 1; + } + else if (lenB == 1) /* lenA >= lenB = 1 */ + { + nmod_poly_fit_length(T, 1); + T->length = 1; + T->coeffs[0] = n_invmod(B->coeffs[0], A->mod.n); + nmod_poly_one(G); + nmod_poly_zero(S); + } + else /* lenA >= lenB >= 2 */ + { + mp_ptr g, s, t; + slong lenG; + + if (G == A || G == B) + { + g = _nmod_vec_init(FLINT_MIN(lenA, lenB)); + } + else + { + nmod_poly_fit_length(G, FLINT_MIN(lenA, lenB)); + g = G->coeffs; + } + if (S == A || S == B) + { + s = _nmod_vec_init(lenB - 1); + } + else + { + nmod_poly_fit_length(S, lenB - 1); + s = S->coeffs; + } + if (T == A || T == B) + { + t = _nmod_vec_init(lenA - 1); + } + else + { + nmod_poly_fit_length(T, lenA - 1); + t = T->coeffs; + } + + if (lenA >= lenB) + lenG = _nmod_poly_xgcd_euclidean(g, s, t, A->coeffs, lenA, + B->coeffs, lenB, A->mod); + else + lenG = _nmod_poly_xgcd_euclidean(g, t, s, B->coeffs, lenB, + A->coeffs, lenA, A->mod); + + if (G == A || G == B) + { + flint_free(G->coeffs); + G->coeffs = g; + G->alloc = FLINT_MIN(lenA, lenB); + } + if (S == A || S == B) + { + flint_free(S->coeffs); + S->coeffs = s; + S->alloc = lenB - 1; + } + if (T == A || T == B) + { + flint_free(T->coeffs); + T->coeffs = t; + T->alloc = lenA - 1; + } + + G->length = lenG; + S->length = FLINT_MAX(lenB - lenG, 1); + T->length = FLINT_MAX(lenA - lenG, 1); + MPN_NORM(S->coeffs, S->length); + MPN_NORM(T->coeffs, T->length); + + if (G->coeffs[lenG - 1] != 1) + { + inv = n_invmod(G->coeffs[lenG - 1], A->mod.n); + nmod_poly_scalar_mul_nmod(G, G, inv); + nmod_poly_scalar_mul_nmod(S, S, inv); + nmod_poly_scalar_mul_nmod(T, T, inv); + } + } + } +} + diff --git a/external/flint-2.4.3/nmod_poly/xgcd_hgcd.c b/external/flint-2.4.3/nmod_poly/xgcd_hgcd.c new file mode 100644 index 0000000..042ec34 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly/xgcd_hgcd.c @@ -0,0 +1,361 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" +#include "mpn_extras.h" + +/* + We define a whole bunch of macros here which essentially provide + the nmod_poly functionality as far as the setting of coefficient + data and lengths is concerned, but which do not do any separate + memory allocation. None of these macros support aliasing. + */ + +#define __set(B, lenB, A, lenA) \ +do { \ + _nmod_vec_set((B), (A), (lenA)); \ + (lenB) = (lenA); \ +} while (0) + +#define __add(C, lenC, A, lenA, B, lenB) \ +do { \ + _nmod_poly_add((C), (A), (lenA), (B), (lenB), mod); \ + (lenC) = FLINT_MAX((lenA), (lenB)); \ + MPN_NORM((C), (lenC)); \ +} while (0) + +#define __sub(C, lenC, A, lenA, B, lenB) \ +do { \ + _nmod_poly_sub((C), (A), (lenA), (B), (lenB), mod); \ + (lenC) = FLINT_MAX((lenA), (lenB)); \ + MPN_NORM((C), (lenC)); \ +} while (0) + +#define __mul(C, lenC, A, lenA, B, lenB) \ +do { \ + if ((lenA) != 0 && (lenB) != 0) \ + { \ + if ((lenA) >= (lenB)) \ + _nmod_poly_mul((C), (A), (lenA), (B), (lenB), mod); \ + else \ + _nmod_poly_mul((C), (B), (lenB), (A), (lenA), mod); \ + (lenC) = (lenA) + (lenB) - 1; \ + } \ + else \ + { \ + (lenC) = 0; \ + } \ +} while (0) + +#define __divrem(Q, lenQ, R, lenR, A, lenA, B, lenB) \ +do { \ + if ((lenA) >= (lenB)) \ + { \ + _nmod_poly_divrem((Q), (R), (A), (lenA), (B), (lenB), mod); \ + (lenQ) = (lenA) - (lenB) + 1; \ + (lenR) = (lenB) - 1; \ + MPN_NORM((R), (lenR)); \ + } \ + else \ + { \ + _nmod_vec_set((R), (A), (lenA)); \ + (lenQ) = 0; \ + (lenR) = (lenA); \ + } \ +} while (0) + +#define __div(Q, lenQ, A, lenA, B, lenB) \ +do { \ + if ((lenA) >= (lenB)) \ + { \ + _nmod_poly_div((Q), (A), (lenA), (B), (lenB), mod); \ + (lenQ) = (lenA) - (lenB) + 1; \ + } \ + else \ + { \ + (lenQ) = 0; \ + } \ +} while (0) + +slong _nmod_poly_xgcd_hgcd(mp_ptr G, mp_ptr S, mp_ptr T, + mp_srcptr A, slong lenA, mp_srcptr B, slong lenB, + nmod_t mod) +{ + const slong cutoff = FLINT_BIT_COUNT(mod.n) <= 8 ? + NMOD_POLY_SMALL_GCD_CUTOFF : NMOD_POLY_GCD_CUTOFF; + + slong lenG, lenS, lenT; + + if (lenB == 1) + { + G[0] = B[0]; + T[0] = 1; + lenG = 1; + lenS = 0; + lenT = 1; + } + else + { + mp_ptr q = _nmod_vec_init(lenA + lenB); + mp_ptr r = q + lenA; + + slong lenq, lenr; + + __divrem(q, lenq, r, lenr, A, lenA, B, lenB); + + if (lenr == 0) + { + __set(G, lenG, B, lenB); + T[0] = 1; + lenS = 0; + lenT = 1; + } + else + { + mp_ptr h, j, v, w, R[4], X; + slong lenh, lenj, lenv, lenw, lenR[4]; + int sgnR; + + lenh = lenj = lenB; + lenv = lenw = lenA + lenB - 2; + lenR[0] = lenR[1] = lenR[2] = lenR[3] = (lenB + 1) / 2; + + X = _nmod_vec_init(2 * lenh + 2 * lenv + 4 * lenR[0]); + h = X; + j = h + lenh; + v = j + lenj; + w = v + lenv; + R[0] = w + lenw; + R[1] = R[0] + lenR[0]; + R[2] = R[1] + lenR[1]; + R[3] = R[2] + lenR[2]; + + sgnR = _nmod_poly_hgcd(R, lenR, h, &lenh, j, &lenj, B, lenB, r, lenr, mod); + + if (sgnR > 0) + { + _nmod_vec_neg(S, R[1], lenR[1], mod); + _nmod_vec_set(T, R[0], lenR[0]); + } + else + { + _nmod_vec_set(S, R[1], lenR[1]); + _nmod_vec_neg(T, R[0], lenR[0], mod); + } + lenS = lenR[1]; + lenT = lenR[0]; + + while (lenj != 0) + { + __divrem(q, lenq, r, lenr, h, lenh, j, lenj); + __mul(v, lenv, q, lenq, T, lenT); + { + slong l; + _nmod_vec_swap(S, T, FLINT_MAX(lenS, lenT)); + l = lenS; lenS = lenT; lenT = l; + } + __sub(T, lenT, T, lenT, v, lenv); + + if (lenr == 0) + { + __set(G, lenG, j, lenj); + + goto cofactor; + } + if (lenj < cutoff) + { + mp_ptr u0 = R[0], u1 = R[1]; + slong lenu0 = lenr - 1, lenu1 = lenj - 1; + + lenG = _nmod_poly_xgcd_euclidean(G, u0, u1, j, lenj, r, lenr, mod); + MPN_NORM(u0, lenu0); + MPN_NORM(u1, lenu1); + + __mul(v, lenv, S, lenS, u0, lenu0); + __mul(w, lenw, T, lenT, u1, lenu1); + __add(S, lenS, v, lenv, w, lenw); + + goto cofactor; + } + + sgnR = _nmod_poly_hgcd(R, lenR, h, &lenh, j, &lenj, j,lenj, r, lenr, mod); + + __mul(v, lenv, R[1], lenR[1], T, lenT); + __mul(w, lenw, R[2], lenR[2], S, lenS); + + __mul(q, lenq, S, lenS, R[3], lenR[3]); + if (sgnR > 0) + __sub(S, lenS, q, lenq, v, lenv); + else + __sub(S, lenS, v, lenv, q, lenq); + + __mul(q, lenq, T, lenT, R[0], lenR[0]); + if (sgnR > WORD(0)) + __sub(T, lenT, q, lenq, w, lenw); + else + __sub(T, lenT, w, lenw, q, lenq); + } + __set(G, lenG, h, lenh); + + cofactor: + + __mul(v, lenv, S, lenS, A, lenA); + __sub(w, lenw, G, lenG, v, lenv); + __div(T, lenT, w, lenw, B, lenB); + + _nmod_vec_clear(X); + } + _nmod_vec_clear(q); + } + flint_mpn_zero(S + lenS, lenB - 1 - lenS); + flint_mpn_zero(T + lenT, lenA - 1 - lenT); + + return lenG; +} + +void +nmod_poly_xgcd_hgcd(nmod_poly_t G, nmod_poly_t S, nmod_poly_t T, + const nmod_poly_t A, const nmod_poly_t B) +{ + if (A->length < B->length) + { + nmod_poly_xgcd_hgcd(G, T, S, B, A); + } + else /* lenA >= lenB >= 0 */ + { + const slong lenA = A->length, lenB = B->length; + mp_limb_t inv; + + if (lenA == 0) /* lenA = lenB = 0 */ + { + nmod_poly_zero(G); + nmod_poly_zero(S); + nmod_poly_zero(T); + } + else if (lenB == 0) /* lenA > lenB = 0 */ + { + inv = n_invmod(A->coeffs[lenA - 1], A->mod.n); + nmod_poly_scalar_mul_nmod(G, A, inv); + nmod_poly_zero(T); + nmod_poly_set_coeff_ui(S, 0, inv); + S->length = 1; + } + else if (lenB == 1) /* lenA >= lenB = 1 */ + { + nmod_poly_fit_length(T, 1); + T->length = 1; + T->coeffs[0] = n_invmod(B->coeffs[0], A->mod.n); + nmod_poly_one(G); + nmod_poly_zero(S); + } + else /* lenA >= lenB >= 2 */ + { + mp_ptr g, s, t; + slong lenG; + + if (G == A || G == B) + { + g = _nmod_vec_init(FLINT_MIN(lenA, lenB)); + } + else + { + nmod_poly_fit_length(G, FLINT_MIN(lenA, lenB)); + g = G->coeffs; + } + if (S == A || S == B) + { + s = _nmod_vec_init(FLINT_MAX(lenB - 1, 2)); + } + else + { + nmod_poly_fit_length(S, FLINT_MAX(lenB - 1, 2)); + s = S->coeffs; + } + if (T == A || T == B) + { + t = _nmod_vec_init(FLINT_MAX(lenA - 1, 2)); + } + else + { + nmod_poly_fit_length(T, FLINT_MAX(lenA - 1, 2)); + t = T->coeffs; + } + + if (lenA >= lenB) + lenG = _nmod_poly_xgcd_hgcd(g, s, t, A->coeffs, lenA, + B->coeffs, lenB, A->mod); + else + lenG = _nmod_poly_xgcd_hgcd(g, t, s, B->coeffs, lenB, + A->coeffs, lenA, A->mod); + + if (G == A || G == B) + { + flint_free(G->coeffs); + G->coeffs = g; + G->alloc = FLINT_MIN(lenA, lenB); + } + if (S == A || S == B) + { + flint_free(S->coeffs); + S->coeffs = s; + S->alloc = FLINT_MAX(lenB - 1, 2); + } + if (T == A || T == B) + { + flint_free(T->coeffs); + T->coeffs = t; + T->alloc = FLINT_MAX(lenA - 1, 2); + } + + G->length = lenG; + S->length = FLINT_MAX(lenB - lenG, 1); + T->length = FLINT_MAX(lenA - lenG, 1); + MPN_NORM(S->coeffs, S->length); + MPN_NORM(T->coeffs, T->length); + + if (G->coeffs[lenG - 1] != 1) + { + inv = n_invmod(G->coeffs[lenG - 1], A->mod.n); + nmod_poly_scalar_mul_nmod(G, G, inv); + nmod_poly_scalar_mul_nmod(S, S, inv); + nmod_poly_scalar_mul_nmod(T, T, inv); + } + } + } +} + +#undef __set +#undef __add +#undef __sub +#undef __mul +#undef __divrem +#undef __div + diff --git a/external/flint-2.4.3/nmod_poly_factor.h b/external/flint-2.4.3/nmod_poly_factor.h new file mode 100644 index 0000000..99165fa --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_factor.h @@ -0,0 +1,129 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007, David Howden + Copyright (C) 2010, 2011 William Hart + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#ifndef NMOD_POLY_FACTOR_H +#define NMOD_POLY_FACTOR_H + +#undef ulong +#define ulong ulongxx /* interferes with system includes */ +#include +#undef ulong +#include +#define ulong mp_limb_t + +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_mat.h" +#include "ulong_extras.h" +#include "fmpz.h" + +#ifdef __cplusplus + extern "C" { +#endif + +typedef struct +{ + nmod_poly_struct *p; + slong *exp; + slong num; + slong alloc; +} nmod_poly_factor_struct; + +/* Factoring ****************************************************************/ + +typedef nmod_poly_factor_struct nmod_poly_factor_t[1]; + +void nmod_poly_factor_init(nmod_poly_factor_t fac); + +void nmod_poly_factor_clear(nmod_poly_factor_t fac); + +void nmod_poly_factor_realloc(nmod_poly_factor_t fac, slong alloc); + +void nmod_poly_factor_fit_length(nmod_poly_factor_t fac, slong len); + +void nmod_poly_factor_set(nmod_poly_factor_t res, const nmod_poly_factor_t fac); + +void nmod_poly_factor_insert(nmod_poly_factor_t fac, + const nmod_poly_t poly, slong exp); + +void nmod_poly_factor_print(const nmod_poly_factor_t fac); + +void nmod_poly_factor_concat(nmod_poly_factor_t res, + const nmod_poly_factor_t fac); + +void nmod_poly_factor_pow(nmod_poly_factor_t fac, slong exp); + +void nmod_poly_factor_equal_deg(nmod_poly_factor_t factors, + const nmod_poly_t pol, slong d); + +int nmod_poly_factor_equal_deg_prob(nmod_poly_t factor, + flint_rand_t state, const nmod_poly_t pol, slong d); + +void nmod_poly_factor_distinct_deg(nmod_poly_factor_t res, + const nmod_poly_t poly, slong * const *degs); + +ulong nmod_poly_remove(nmod_poly_t f, const nmod_poly_t p); + +int nmod_poly_is_irreducible(const nmod_poly_t f); + +int nmod_poly_is_irreducible_rabin(const nmod_poly_t f); + +int nmod_poly_is_irreducible_ddf(const nmod_poly_t f); + +int _nmod_poly_is_squarefree(mp_srcptr f, slong len, nmod_t mod); + +int nmod_poly_is_squarefree(const nmod_poly_t f); + +void nmod_poly_factor_cantor_zassenhaus(nmod_poly_factor_t res, + const nmod_poly_t f); + +void nmod_poly_factor_berlekamp(nmod_poly_factor_t factors, + const nmod_poly_t f); + +void nmod_poly_factor_kaltofen_shoup(nmod_poly_factor_t res, + const nmod_poly_t poly); + +void nmod_poly_factor_squarefree(nmod_poly_factor_t res, const nmod_poly_t f); + +mp_limb_t nmod_poly_factor_with_berlekamp(nmod_poly_factor_t result, + const nmod_poly_t input); + +mp_limb_t nmod_poly_factor_with_cantor_zassenhaus(nmod_poly_factor_t result, + const nmod_poly_t input); + +mp_limb_t nmod_poly_factor_with_kaltofen_shoup(nmod_poly_factor_t result, + const nmod_poly_t input); + +mp_limb_t nmod_poly_factor(nmod_poly_factor_t result, + const nmod_poly_t input); + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/external/flint-2.4.3/nmod_poly_factor/clear.c b/external/flint-2.4.3/nmod_poly_factor/clear.c new file mode 100644 index 0000000..cd2bd8d --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_factor/clear.c @@ -0,0 +1,43 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "nmod_poly.h" + +void +nmod_poly_factor_clear(nmod_poly_factor_t fac) +{ + slong i; + + for (i = 0; i < fac->alloc; i++) + nmod_poly_clear(fac->p + i); + + flint_free(fac->p); + flint_free(fac->exp); +} diff --git a/external/flint-2.4.3/nmod_poly_factor/concat.c b/external/flint-2.4.3/nmod_poly_factor/concat.c new file mode 100644 index 0000000..7afad8d --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_factor/concat.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "nmod_poly.h" + +void +nmod_poly_factor_concat(nmod_poly_factor_t res, const nmod_poly_factor_t fac) +{ + slong i; + + for (i = 0; i < fac->num; i++) + nmod_poly_factor_insert(res, fac->p + i, fac->exp[i]); +} diff --git a/external/flint-2.4.3/nmod_poly_factor/doc/nmod_poly_factor.txt b/external/flint-2.4.3/nmod_poly_factor/doc/nmod_poly_factor.txt new file mode 100644 index 0000000..00682a1 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_factor/doc/nmod_poly_factor.txt @@ -0,0 +1,218 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +******************************************************************************* + + Factorisation + +******************************************************************************* + +void nmod_poly_factor_init(nmod_poly_factor_t fac) + + Initialises \code{fac} for use. An \code{nmod_poly_factor_t} + represents a polynomial in factorised form as a product of + polynomials with associated exponents. + +void nmod_poly_factor_clear(nmod_poly_factor_t fac) + + Frees all memory associated with \code{fac}. + +void nmod_poly_factor_realloc(nmod_poly_factor_t fac, slong alloc) + + Reallocates the factor structure to provide space for + precisely \code{alloc} factors. + +void nmod_poly_factor_fit_length(nmod_poly_factor_t fac, slong len) + + Ensures that the factor structure has space for at + least \code{len} factors. This functions takes care + of the case of repeated calls by always at least + doubling the number of factors the structure can hold. + +void nmod_poly_factor_set(nmod_poly_factor_t res, const nmod_poly_factor_t fac) + + Sets \code{res} to the same factorisation as \code{fac}. + +void nmod_poly_factor_print(const nmod_poly_factor_t fac) + + Prints the entries of \code{fac} to standard output. + +void nmod_poly_factor_insert(nmod_poly_factor_t fac, + const nmod_poly_t poly, slong exp) + + Inserts the factor \code{poly} with multiplicity \code{exp} into + the factorisation \code{fac}. + + If \code{fac} already contains \code{poly}, then \code{exp} simply + gets added to the exponent of the existing entry. + +void nmod_poly_factor_concat(nmod_poly_factor_t res, + const nmod_poly_factor_t fac) + + Concatenates two factorisations. + + This is equivalent to calling \code{nmod_poly_factor_insert()} + repeatedly with the individual factors of \code{fac}. + + Does not support aliasing between \code{res} and \code{fac}. + +void nmod_poly_factor_pow(nmod_poly_factor_t fac, slong exp) + + Raises \code{fac} to the power \code{exp}. + +ulong nmod_poly_remove(nmod_poly_t f, const nmod_poly_t p) + + Removes the highest possible power of \code{p} from \code{f} and + returns the exponent. + +int nmod_poly_is_irreducible(const nmod_poly_t f) + + Returns 1 if the polynomial \code{f} is irreducible, otherwise returns 0. + +int nmod_poly_is_irreducible_ddf(const nmod_poly_t f) + + Returns 1 if the polynomial \code{f} is irreducible, otherwise returns 0. + Uses fast distinct-degree factorisation. + +int nmod_poly_is_irreducible_rabin(const nmod_poly_t f) + + Returns 1 if the polynomial \code{f} is irreducible, otherwise returns 0. + Uses Rabin irreducibility test. + +int _nmod_poly_is_squarefree(mp_srcptr f, slong len, nmod_t mod) + + Returns 1 if \code{(f, len)} is squarefree, and 0 otherwise. As a + special case, the zero polynomial is not considered squarefree. + There are no restrictions on the length. + +int nmod_poly_is_squarefree(const nmod_poly_t f) + + Returns 1 if \code{f} is squarefree, and 0 otherwise. As a special + case, the zero polynomial is not considered squarefree. + +void nmod_poly_factor_squarefree(nmod_poly_factor_t res, const nmod_poly_t f) + + Sets \code{res} to a square-free factorization of \code{f}. + +int nmod_poly_factor_equal_deg_prob(nmod_poly_t factor, + flint_rand_t state, const nmod_poly_t pol, slong d) + + Probabilistic equal degree factorisation of \code{pol} into + irreducible factors of degree \code{d}. If it passes, a factor is + placed in factor and 1 is returned, otherwise 0 is returned and + the value of factor is undetermined. + + Requires that \code{pol} be monic, non-constant and squarefree. + +void nmod_poly_factor_equal_deg(nmod_poly_factor_t factors, + const nmod_poly_t pol, slong d) + + Assuming \code{pol} is a product of irreducible factors all of + degree \code{d}, finds all those factors and places them in factors. + Requires that \code{pol} be monic, non-constant and squarefree. + +void nmod_poly_factor_distinct_deg(nmod_poly_factor_t res, + const nmod_poly_t poly, slong * const *degs) + + Factorises a monic non-constant squarefree polymnomial \code{poly} + of degree n into factors $f[d]$ such that for $1 \leq d \leq n$ + $f[d]$ is the product of the monic irreducible factors of \code{poly} + of degree $d$. Factors $f[d]$ are stored in \code{res}, and the degree $d$ + of the irreducible factors is stored in \code{degs} in the same order + as the factors. + + Requires that \code{degs} has enough space for $(n/2)+1 * sizeof(slong)$. + +void nmod_poly_factor_cantor_zassenhaus(nmod_poly_factor_t res, + const nmod_poly_t f) + + Factorises a non-constant polynomial \code{f} into monic irreducible + factors using the Cantor-Zassenhaus algorithm. + +void nmod_poly_factor_berlekamp(nmod_poly_factor_t res, const nmod_poly_t f) + + Factorises a non-constant, squarefree polynomial \code{f} into monic + irreducible factors using the Berlekamp algorithm. + +void nmod_poly_factor_kaltofen_shoup(nmod_poly_factor_t res, + const nmod_poly_t poly) + + Factorises a non-constant polynomial \code{f} into monic irreducible + factors using the fast version of Cantor-Zassenhaus algorithm proposed by + Kaltofen and Shoup (1998). More precisely this algorithm uses a + “baby step/giant step†strategy for the distinct-degree factorization + step. + +mp_limb_t nmod_poly_factor_with_berlekamp(nmod_poly_factor_t res, + const nmod_poly_t f) + + Factorises a general polynomial \code{f} into monic irreducible factors + and returns the leading coefficient of \code{f}, or 0 if \code{f} + is the zero polynomial. + + This function first checks for small special cases, deflates \code{f} + if it is of the form $p(x^m)$ for some $m > 1$, then performs a + square-free factorisation, and finally runs Berlekamp on all the + individual square-free factors. + +mp_limb_t nmod_poly_factor_with_cantor_zassenhaus(nmod_poly_factor_t res, + const nmod_poly_t f) + + Factorises a general polynomial \code{f} into monic irreducible factors + and returns the leading coefficient of \code{f}, or 0 if \code{f} + is the zero polynomial. + + This function first checks for small special cases, deflates \code{f} + if it is of the form $p(x^m)$ for some $m > 1$, then performs a + square-free factorisation, and finally runs Cantor-Zassenhaus on all the + individual square-free factors. + +mp_limb_t nmod_poly_factor_with_kaltofen_shoup(nmod_poly_factor_t res, + const nmod_poly_t f) + + Factorises a general polynomial \code{f} into monic irreducible factors + and returns the leading coefficient of \code{f}, or 0 if \code{f} + is the zero polynomial. + + This function first checks for small special cases, deflates \code{f} + if it is of the form $p(x^m)$ for some $m > 1$, then performs a + square-free factorisation, and finally runs Kaltofen-Shoup on all the + individual square-free factors. + +mp_limb_t nmod_poly_factor(nmod_poly_factor_t res, const nmod_poly_t f) + + Factorises a general polynomial \code{f} into monic irreducible factors + and returns the leading coefficient of \code{f}, or 0 if \code{f} + is the zero polynomial. + + This function first checks for small special cases, deflates \code{f} + if it is of the form $p(x^m)$ for some $m > 1$, then performs a + square-free factorisation, and finally runs either Cantor-Zassenhaus + or Berlekamp on all the individual square-free factors. + Currently Cantor-Zassenhaus is used by default unless the modulus is 2, in + which case Berlekamp is used. + diff --git a/external/flint-2.4.3/nmod_poly_factor/factor.c b/external/flint-2.4.3/nmod_poly_factor/factor.c new file mode 100644 index 0000000..1c60239 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_factor/factor.c @@ -0,0 +1,191 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +#define ZASSENHAUS 0 +#define BERLEKAMP 1 +#define KALTOFEN 2 + +static __inline__ void +__nmod_poly_factor1(nmod_poly_factor_t res, const nmod_poly_t f, int algorithm) +{ + if (algorithm == KALTOFEN) + nmod_poly_factor_kaltofen_shoup(res, f); + else if (algorithm == ZASSENHAUS) + nmod_poly_factor_cantor_zassenhaus(res, f); + else + nmod_poly_factor_berlekamp(res, f); +} + +mp_limb_t +__nmod_poly_factor(nmod_poly_factor_t result, + const nmod_poly_t input, int algorithm) +{ + nmod_poly_t monic_input; + nmod_poly_factor_t sqfree_factors, factors; + mp_limb_t leading_coeff; + slong i, len; + + len = input->length; + + if (len <= 1) + { + if (len == 0) + return 0; + else + return input->coeffs[0]; + } + + leading_coeff = *nmod_poly_lead(input); + + nmod_poly_init_preinv(monic_input, input->mod.n, input->mod.ninv); + nmod_poly_make_monic(monic_input, input); + + if (len == 2) + { + nmod_poly_factor_insert(result, monic_input, 1); + nmod_poly_clear(monic_input); + return input->coeffs[1]; + } + + nmod_poly_factor_init(sqfree_factors); + nmod_poly_factor_squarefree(sqfree_factors, monic_input); + nmod_poly_clear(monic_input); + + /* Run CZ on each of the square-free factors */ + for (i = 0; i < sqfree_factors->num; i++) + { + nmod_poly_factor_init(factors); + __nmod_poly_factor1(factors, sqfree_factors->p + i, algorithm); + nmod_poly_factor_pow(factors, sqfree_factors->exp[i]); + nmod_poly_factor_concat(result, factors); + nmod_poly_factor_clear(factors); + } + + nmod_poly_factor_clear(sqfree_factors); + return leading_coeff; +} + +mp_limb_t +__nmod_poly_factor_deflation(nmod_poly_factor_t result, + const nmod_poly_t input, int algorithm) +{ + slong i; + ulong deflation; + + if (input->length <= 1) + { + if (input->length == 0) + return 0; + else + return input->coeffs[0]; + } + + deflation = nmod_poly_deflation(input); + if (deflation == 1) + { + return __nmod_poly_factor(result, input, algorithm); + } + else + { + nmod_poly_factor_t def_res; + nmod_poly_t def; + mp_limb_t leading_coeff; + + nmod_poly_init_preinv(def, input->mod.n, input->mod.ninv); + nmod_poly_deflate(def, input, deflation); + nmod_poly_factor_init(def_res); + leading_coeff = __nmod_poly_factor(def_res, def, algorithm); + nmod_poly_clear(def); + + for (i = 0; i < def_res->num; i++) + { + /* Inflate */ + nmod_poly_t pol; + nmod_poly_init_preinv(pol, input->mod.n, input->mod.ninv); + nmod_poly_inflate(pol, def_res->p + i, deflation); + + /* Factor inflation */ + if (def_res->exp[i] == 1) + __nmod_poly_factor(result, pol, algorithm); + else + { + nmod_poly_factor_t t; + nmod_poly_factor_init(t); + __nmod_poly_factor(t, pol, algorithm); + nmod_poly_factor_pow(t, def_res->exp[i]); + nmod_poly_factor_concat(result, t); + nmod_poly_factor_clear(t); + } + nmod_poly_clear(pol); + } + + nmod_poly_factor_clear(def_res); + return leading_coeff; + } +} + +mp_limb_t +nmod_poly_factor_with_berlekamp(nmod_poly_factor_t result, + const nmod_poly_t input) +{ + return __nmod_poly_factor_deflation(result, input, BERLEKAMP); +} + +mp_limb_t +nmod_poly_factor_with_cantor_zassenhaus(nmod_poly_factor_t result, + const nmod_poly_t input) +{ + return __nmod_poly_factor_deflation(result, input, ZASSENHAUS); +} + +mp_limb_t +nmod_poly_factor_with_kaltofen_shoup(nmod_poly_factor_t result, + const nmod_poly_t input) +{ + return __nmod_poly_factor_deflation(result, input, KALTOFEN); +} + +mp_limb_t +nmod_poly_factor(nmod_poly_factor_t result, const nmod_poly_t input) +{ + mp_limb_t p = input->mod.n; + unsigned int bits = FLINT_BIT_COUNT (p); + slong n = nmod_poly_degree(input); + + if (n < 10 + 50 / bits) + return __nmod_poly_factor_deflation(result, input, ZASSENHAUS); + else + return __nmod_poly_factor_deflation(result, input, KALTOFEN); +} diff --git a/external/flint-2.4.3/nmod_poly_factor/factor_berlekamp.c b/external/flint-2.4.3/nmod_poly_factor/factor_berlekamp.c new file mode 100644 index 0000000..79d1deb --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_factor/factor_berlekamp.c @@ -0,0 +1,238 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "nmod_poly.h" +#include "nmod_mat.h" +#include "ulong_extras.h" +#include "profiler.h" +#include "perm.h" + +static void +nmod_poly_to_nmod_mat_col(nmod_mat_t mat, slong col, nmod_poly_t poly) +{ + slong i; + + for (i = 0; i < poly->length; i++) + nmod_mat_entry(mat, i, col) = poly->coeffs[i]; + + for ( ; i < mat->r; i++) + nmod_mat_entry(mat, i, col) = UWORD(0); +} + +static void +nmod_mat_col_to_nmod_poly_shifted(nmod_poly_t poly, nmod_mat_t mat, + slong col, slong * shift) +{ + slong i, j, rows = mat->r; + + nmod_poly_fit_length(poly, rows); + + for (i = 0, j = 0; j < rows; j++) + { + if (shift[j]) + poly->coeffs[j] = 0; + else + { + poly->coeffs[j] = nmod_mat_entry(mat, i, col); + i++; + } + } + + poly->length = rows; + _nmod_poly_normalise(poly); +} + +static void +__nmod_poly_factor_berlekamp(nmod_poly_factor_t factors, + flint_rand_t state, const nmod_poly_t f) +{ + const mp_limb_t p = nmod_poly_modulus(f); + const slong n = nmod_poly_degree(f); + + nmod_poly_factor_t fac1, fac2; + nmod_poly_t x, x_p; + nmod_poly_t x_pi, x_pi2; + nmod_poly_t Q; + nmod_mat_t matrix; + mp_limb_t coeff; + slong i, nullity, col, row, *shift; + nmod_poly_t *basis; + + if (f->length <= 2) + { + nmod_poly_factor_insert(factors, f, 1); + return; + } + + /* Step 1, we compute x^p mod f in F_p[X]/ */ + nmod_poly_init(x, p); + nmod_poly_init(x_p, p); + + nmod_poly_set_coeff_ui(x, 1, 1); + nmod_poly_powmod_ui_binexp(x_p, x, p, f); + nmod_poly_clear(x); + + /* Step 2, compute the matrix for the Berlekamp Map */ + nmod_mat_init(matrix, n, n, p); + nmod_poly_init(x_pi, p); + nmod_poly_init(x_pi2, p); + nmod_poly_set_coeff_ui(x_pi, 0, 1); + + for (i = 0; i < n; i++) + { + /* Q - I */ + nmod_poly_set(x_pi2, x_pi); + coeff = nmod_poly_get_coeff_ui(x_pi2, i); + if (coeff) + nmod_poly_set_coeff_ui(x_pi2, i, coeff - 1); + else + nmod_poly_set_coeff_ui(x_pi2, i, p - 1); + nmod_poly_to_nmod_mat_col(matrix, i, x_pi2); + nmod_poly_mulmod(x_pi, x_pi, x_p, f); + } + + nmod_poly_clear(x_p); + nmod_poly_clear(x_pi); + nmod_poly_clear(x_pi2); + + /* Row reduce Q - I */ + nullity = n - nmod_mat_rref(matrix); + + /* Find a basis for the nullspace */ + basis = (nmod_poly_t *) flint_malloc(nullity * sizeof(nmod_poly_t)); + shift = (slong *) flint_calloc(n, sizeof(slong)); + + col = 1; /* first column is always zero */ + row = 0; + shift[0] = 1; + + for (i = 1; i < nullity; i++) + { + nmod_poly_init(basis[i], p); + while (nmod_mat_entry(matrix, row, col)) + { + row++; + col++; + } + nmod_mat_col_to_nmod_poly_shifted(basis[i], matrix, col, shift); + nmod_poly_set_coeff_ui(basis[i], col, p - 1); + shift[col] = 1; + col++; + } + + flint_free(shift); + nmod_mat_clear(matrix); + + /* we are done */ + if (nullity == 1) + { + nmod_poly_factor_insert(factors, f, 1); + flint_free(basis); + } + else + { + /* Generate random linear combinations */ + nmod_poly_t factor, b, power, g; + nmod_poly_init(factor, p); + nmod_poly_init(b, p); + nmod_poly_init(power, p); + nmod_poly_init(g, p); + + while (1) + { + do + { + nmod_poly_zero(factor); + for (i = 1; i < nullity; i++) + { + nmod_poly_scalar_mul_nmod(b, basis[i], n_randint(state, p)); + nmod_poly_add(factor, factor, b); + } + + nmod_poly_set_coeff_ui(factor, 0, n_randint(state, p)); + if (!nmod_poly_is_zero(factor)) + nmod_poly_make_monic(factor, factor); + } + while (nmod_poly_is_one(factor) || nmod_poly_is_zero(factor)); + + nmod_poly_gcd(g, f, factor); + + if (nmod_poly_length(g) != 1) break; + + if (p > 3) + nmod_poly_powmod_ui_binexp(power, factor, p >> 1, f); + else + nmod_poly_set(power, factor); + + power->coeffs[0] = n_addmod(power->coeffs[0], p - 1, p); + _nmod_poly_normalise(power); + nmod_poly_gcd(g, power, f); + + if (nmod_poly_length(g) != 1) + break; + } + + for (i = 1; i < nullity; i++) + nmod_poly_clear(basis[i]); + + flint_free(basis); + nmod_poly_clear(power); + nmod_poly_clear(factor); + nmod_poly_clear(b); + + if (!nmod_poly_is_zero(g)) + nmod_poly_make_monic(g, g); + + nmod_poly_factor_init(fac1); + nmod_poly_factor_init(fac2); + __nmod_poly_factor_berlekamp(fac1, state, g); + nmod_poly_init(Q, p); + nmod_poly_div(Q, f, g); + + if (!nmod_poly_is_zero(Q)) + nmod_poly_make_monic(Q, Q); + + __nmod_poly_factor_berlekamp(fac2, state, Q); + nmod_poly_factor_concat(factors, fac1); + nmod_poly_factor_concat(factors, fac2); + nmod_poly_factor_clear(fac1); + nmod_poly_factor_clear(fac2); + nmod_poly_clear(Q); + nmod_poly_clear(g); + } +} + +void +nmod_poly_factor_berlekamp(nmod_poly_factor_t factors, const nmod_poly_t f) +{ + flint_rand_t r; + flint_randinit(r); + __nmod_poly_factor_berlekamp(factors, r, f); + flint_randclear(r); +} diff --git a/external/flint-2.4.3/nmod_poly_factor/factor_cantor_zassenhaus.c b/external/flint-2.4.3/nmod_poly_factor/factor_cantor_zassenhaus.c new file mode 100644 index 0000000..eeb81bd --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_factor/factor_cantor_zassenhaus.c @@ -0,0 +1,76 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "nmod_poly.h" + +void +nmod_poly_factor_cantor_zassenhaus(nmod_poly_factor_t res, const nmod_poly_t f) +{ + nmod_poly_t h, v, g, x; + slong i, j, num; + + nmod_poly_init_preinv(h, f->mod.n, f->mod.ninv); + nmod_poly_init_preinv(g, f->mod.n, f->mod.ninv); + nmod_poly_init_preinv(v, f->mod.n, f->mod.ninv); + nmod_poly_init_preinv(x, f->mod.n, f->mod.ninv); + + nmod_poly_set_coeff_ui(h, 1, 1); + nmod_poly_set_coeff_ui(x, 1, 1); + + nmod_poly_make_monic(v, f); + + i = 0; + do + { + i++; + nmod_poly_powmod_ui_binexp(h, h, f->mod.n, v); + + nmod_poly_sub(h, h, x); + nmod_poly_gcd(g, h, v); + nmod_poly_add(h, h, x); + + if (g->length != 1) + { + nmod_poly_make_monic(g, g); + num = res->num; + nmod_poly_factor_equal_deg(res, g, i); + + for (j = num; j < res->num; j++) + res->exp[j] = nmod_poly_remove(v, res->p + j); + } + } + while (v->length >= 2*i + 3); + + if (v->length > 1) + nmod_poly_factor_insert(res, v, 1); + + nmod_poly_clear(g); + nmod_poly_clear(h); + nmod_poly_clear(v); + nmod_poly_clear(x); +} diff --git a/external/flint-2.4.3/nmod_poly_factor/factor_distinct_deg.c b/external/flint-2.4.3/nmod_poly_factor/factor_distinct_deg.c new file mode 100644 index 0000000..1f17467 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_factor/factor_distinct_deg.c @@ -0,0 +1,213 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Martin Lee + +******************************************************************************/ + +#undef ulong +#define ulong ulongxx/* interferes with system includes */ + +#include + +#undef ulong + +#include + +#define ulong mp_limb_t + +#include "nmod_poly.h" + +void nmod_poly_factor_distinct_deg(nmod_poly_factor_t res, + const nmod_poly_t poly, slong * const *degs) +{ + nmod_poly_t f, g, v, vinv, reducedH0, tmp; + nmod_poly_t *h, *H, *I; + slong i, j, l, m, n, index, d; + nmod_mat_t HH, HHH; + double beta; + + n = nmod_poly_degree(poly); + nmod_poly_init_preinv(v, poly->mod.n, poly->mod.ninv); + + nmod_poly_make_monic(v, poly); + if (n == 1) + { + nmod_poly_factor_insert (res, v, 1); + (*degs)[0]= 1; + nmod_poly_clear (v); + return; + } + beta = 0.5 * (1. - (log(2) / log(n))); + l = ceil(pow (n, beta)); + m = ceil(0.5 * n / l); + + /* initialization */ + nmod_poly_init_preinv(f, poly->mod.n, poly->mod.ninv); + nmod_poly_init_preinv(g, poly->mod.n, poly->mod.ninv); + nmod_poly_init_preinv(vinv, poly->mod.n, poly->mod.ninv); + nmod_poly_init_preinv(reducedH0, poly->mod.n, poly->mod.ninv); + nmod_poly_init_preinv(tmp, poly->mod.n, poly->mod.ninv); + + if (!(h = flint_malloc((2 * m + l + 1) * sizeof(nmod_poly_struct)))) + { + flint_printf("Exception (nmod_poly_factor_distinct_deg):\n"); + flint_printf("Not enough memory.\n"); + abort(); + } + H = h + (l + 1); + I = H + m; + for (i = 0; i < l + 1; i++) + nmod_poly_init_preinv(h[i], poly->mod.n, poly->mod.ninv); + for (i = 0; i < m; i++) + { + nmod_poly_init_preinv(H[i], poly->mod.n, poly->mod.ninv); + nmod_poly_init_preinv(I[i], poly->mod.n, poly->mod.ninv); + } + + nmod_poly_reverse(vinv, v, v->length); + nmod_poly_inv_series(vinv, vinv, v->length); + /* compute baby steps: h[i]=x^{p^i}mod v */ + nmod_poly_set_coeff_ui(h[0], 1, 1); + nmod_poly_powmod_x_ui_preinv(h[1], poly->mod.n, v, vinv); + if (FLINT_BIT_COUNT(poly->mod.n) > ((n_sqrt(v->length - 1) + 1) * 3) / 4) + { + nmod_mat_init(HH, n_sqrt (v->length - 1) + 1, v->length - 1, + poly->mod.n); + nmod_poly_precompute_matrix(HH, h[1], v, vinv); + for (i = 2; i < l + 1; i++) + nmod_poly_compose_mod_brent_kung_precomp_preinv(h[i], h[i - 1], + HH, v, vinv); + nmod_mat_clear(HH); + } + else + { + for (i = 2; i < l + 1; i++) + nmod_poly_powmod_ui_binexp_preinv(h[i], h[i - 1], poly->mod.n, + v, vinv); + } + + /* compute coarse distinct-degree factorisation */ + index = 0; + nmod_poly_set(H[0], h[l]); + nmod_poly_set(reducedH0, H[0]); + nmod_mat_init(HH, n_sqrt(v->length - 1) + 1, v->length - 1, poly->mod.n); + nmod_poly_precompute_matrix(HH, reducedH0, v, vinv); + d = 1; + for (j = 0; j < m; j++) + { + /* compute giant steps: H[j]=x^{p^(lj)}mod v */ + if (j > 0) + { + if (I[j - 1]->length > 1) + { + _nmod_poly_reduce_matrix_mod_poly(HHH, HH, v); + nmod_mat_clear(HH); + nmod_mat_init_set(HH, HHH); + nmod_mat_clear(HHH); + nmod_poly_rem(reducedH0, reducedH0, v); + nmod_poly_rem(tmp, H[j - 1], v); + nmod_poly_compose_mod_brent_kung_precomp_preinv(H[j], tmp, HH, + v, vinv); + } + else + nmod_poly_compose_mod_brent_kung_precomp_preinv(H[j], H[j - 1], + HH, v, vinv); + } + /* compute interval polynomials */ + nmod_poly_set_coeff_ui(I[j], 0, 1); + for (i = l - 1; (i >= 0) && (2 * d <= v->length - 1); i--, d++) + { + nmod_poly_rem(tmp, h[i], v); + nmod_poly_sub(tmp, H[j], tmp); + nmod_poly_mulmod_preinv(I[j], tmp, I[j], v, vinv); + } + + /* compute F_j=f^{[j*l+1]} * ... * f^{[j*l+l]} */ + /* F_j is stored on the place of I_j */ + nmod_poly_gcd(I[j], v, I[j]); + if (I[j]->length > 1) + { + nmod_poly_remove(v, I[j]); + nmod_poly_reverse(vinv, v, v->length); + nmod_poly_inv_series(vinv, vinv, v->length); + } + if (v->length - 1 < 2 * d) + { + break; + } + } + if (v->length > 1) + { + nmod_poly_factor_insert(res, v, 1); + (*degs)[index++] = v->length - 1; + } + + /* compute fine distinct-degree factorisation */ + for (j = 0; j < m; j++) + { + if (I[j]->length - 1 > (j + 1) * l || j == 0) + { + nmod_poly_set(g, I[j]); + for (i = l - 1; i >= 0 && (g->length > 1); i-- ) + { + /* compute f^{[l*(j+1)-i]} */ + nmod_poly_sub(tmp, H[j], h[i]); + nmod_poly_gcd(f, g, tmp); + if (f->length > 1) + { + /* insert f^{[l*(j+1)-i]} into res */ + nmod_poly_make_monic(f, f); + nmod_poly_factor_insert(res, f, 1); + (*degs)[index++] = l * (j + 1) - i; + + nmod_poly_remove(g, f); + } + } + } + else if (I[j]->length > 1) + { + nmod_poly_make_monic(I[j], I[j]); + nmod_poly_factor_insert(res, I[j], 1); + (*degs)[index++] = I[j]->length-1; + } + } + + /* cleanup */ + nmod_poly_clear(f); + nmod_poly_clear(g); + nmod_poly_clear(reducedH0); + nmod_poly_clear(v); + nmod_poly_clear(vinv); + nmod_poly_clear(tmp); + + nmod_mat_clear (HH); + + for (i = 0; i < l + 1; i++) + nmod_poly_clear(h[i]); + for (i = 0; i < m; i++) + { + nmod_poly_clear(H[i]); + nmod_poly_clear(I[i]); + } + flint_free(h); +} diff --git a/external/flint-2.4.3/nmod_poly_factor/factor_equal_deg.c b/external/flint-2.4.3/nmod_poly_factor/factor_equal_deg.c new file mode 100644 index 0000000..a1a1d8d --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_factor/factor_equal_deg.c @@ -0,0 +1,61 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "nmod_poly.h" +#include "ulong_extras.h" + +void +nmod_poly_factor_equal_deg(nmod_poly_factor_t factors, + const nmod_poly_t pol, slong d) +{ + if (pol->length == d + 1) + { + nmod_poly_factor_insert(factors, pol, 1); + } + else + { + nmod_poly_t f, g; + flint_rand_t state; + + nmod_poly_init_preinv(f, pol->mod.n, pol->mod.ninv); + + flint_randinit(state); + + while (!nmod_poly_factor_equal_deg_prob(f, state, pol, d)) {}; + + flint_randclear(state); + + nmod_poly_init_preinv(g, pol->mod.n, pol->mod.ninv); + nmod_poly_div(g, pol, f); + + nmod_poly_factor_equal_deg(factors, f, d); + nmod_poly_clear(f); + nmod_poly_factor_equal_deg(factors, g, d); + nmod_poly_clear(g); + } +} diff --git a/external/flint-2.4.3/nmod_poly_factor/factor_equal_deg_prob.c b/external/flint-2.4.3/nmod_poly_factor/factor_equal_deg_prob.c new file mode 100644 index 0000000..f7a38f9 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_factor/factor_equal_deg_prob.c @@ -0,0 +1,107 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + +******************************************************************************/ + +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +nmod_poly_factor_equal_deg_prob(nmod_poly_t factor, + flint_rand_t state, const nmod_poly_t pol, slong d) +{ + nmod_poly_t a, b, c, polinv; + mpz_t exp; + int res = 1; + slong i; + + if (pol->length <= 1) + { + flint_printf("Exception (nmod_poly_factor_equal_deg_prob). \n"); + flint_printf("Input polynomial is linear.\n"); + abort(); + } + + nmod_poly_init_preinv(a, pol->mod.n, pol->mod.ninv); + + do { + nmod_poly_randtest(a, state, pol->length - 1); + } while (a->length <= 1); + + nmod_poly_gcd(factor, a, pol); + + if (factor->length != 1) + { + nmod_poly_clear(a); + return 1; + } + + nmod_poly_init_preinv(b, pol->mod.n, pol->mod.ninv); + nmod_poly_init_preinv(polinv, pol->mod.n, pol->mod.ninv); + + nmod_poly_reverse(polinv, pol, pol->length); + nmod_poly_inv_series(polinv, polinv, polinv->length); + + mpz_init(exp); + if (pol->mod.n > 2) + { + /* compute a^{(p^d-1)/2} rem pol */ + flint_mpz_ui_pow_ui(exp, pol->mod.n, d); + flint_mpz_sub_ui(exp, exp, 1); + mpz_tdiv_q_2exp(exp, exp, 1); + + nmod_poly_powmod_mpz_binexp_preinv(b, a, exp, pol, polinv); + } + else + { + /* compute b = (a^{2^{d-1}}+a^{2^{d-2}}+...+a^4+a^2+a) rem pol */ + nmod_poly_rem(b, a, pol); + nmod_poly_init_preinv(c, pol->mod.n, pol->mod.ninv); + nmod_poly_set(c, b); + for (i = 1; i < d; i++) + { + /* c = a^{2^i} = (a^{2^{i-1}})^2 */ + nmod_poly_powmod_ui_binexp_preinv(c, c, 2, pol, polinv); + nmod_poly_add(b, b, c); + } + nmod_poly_rem(b, b, pol); + nmod_poly_clear(c); + } + mpz_clear(exp); + + b->coeffs[0] = n_submod(b->coeffs[0], 1, pol->mod.n); + + nmod_poly_gcd(factor, b, pol); + + if ((factor->length <= 1) || (factor->length == pol->length)) res = 0; + + nmod_poly_clear(polinv); + nmod_poly_clear(a); + nmod_poly_clear(b); + + return res; +} diff --git a/external/flint-2.4.3/nmod_poly_factor/factor_kaltofen_shoup.c b/external/flint-2.4.3/nmod_poly_factor/factor_kaltofen_shoup.c new file mode 100644 index 0000000..2df8843 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_factor/factor_kaltofen_shoup.c @@ -0,0 +1,82 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Lina Kulakova + +******************************************************************************/ + +#include +#include "nmod_poly.h" + +void nmod_poly_factor_kaltofen_shoup(nmod_poly_factor_t res, + const nmod_poly_t poly) +{ + nmod_poly_t v; + nmod_poly_factor_t sq_free, dist_deg; + slong i, j, k, l, res_num, dist_deg_num; + slong *degs; + + nmod_poly_init_preinv(v, poly->mod.n, poly->mod.ninv); + + nmod_poly_make_monic(v, poly); + + if (poly->length <= 2) + { + nmod_poly_factor_insert (res, v, 1); + nmod_poly_clear (v); + return; + } + + if (!(degs = flint_malloc(nmod_poly_degree(poly) * sizeof(slong)))) + { + flint_printf("Exception (nmod_poly_factor_kaltofen_shoup): \n"); + flint_printf("Not enough memory.\n"); + abort(); + } + + /* compute squarefree factorisation */ + nmod_poly_factor_init(sq_free); + nmod_poly_factor_squarefree(sq_free, v); + + /* compute distinct-degree factorisation */ + nmod_poly_factor_init(dist_deg); + for (i = 0; i < sq_free->num; i++) + { + dist_deg_num = dist_deg->num; + + nmod_poly_factor_distinct_deg(dist_deg, sq_free->p + i, °s); + + /* compute equal-degree factorisation */ + for (j = dist_deg_num, l = 0; j < dist_deg->num; j++, l++) + { + res_num = res->num; + + nmod_poly_factor_equal_deg(res, dist_deg->p + j, degs[l]); + for (k = res_num; k < res->num; k++) + res->exp[k] = nmod_poly_remove(v, res->p + k); + } + } + + flint_free(degs); + nmod_poly_clear(v); + nmod_poly_factor_clear(dist_deg); + nmod_poly_factor_clear(sq_free); +} diff --git a/external/flint-2.4.3/nmod_poly_factor/factor_squarefree.c b/external/flint-2.4.3/nmod_poly_factor/factor_squarefree.c new file mode 100644 index 0000000..f6d8a72 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_factor/factor_squarefree.c @@ -0,0 +1,150 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "nmod_poly.h" +#include "ulong_extras.h" + +void +nmod_poly_factor_squarefree(nmod_poly_factor_t res, const nmod_poly_t f) +{ + nmod_poly_t f_d, g, g_1; + mp_limb_t p; + slong deg, i; + + if (f->length <= 1) + { + res->num = 0; + return; + } + + if (f->length == 2) + { + nmod_poly_factor_insert(res, f, 1); + return; + } + + p = nmod_poly_modulus(f); + deg = nmod_poly_degree(f); + + + /* Step 1, look at f', if it is zero then we are done since f = h(x)^p + for some particular h(x), clearly f(x) = sum a_k x^kp, k <= deg(f) */ + + nmod_poly_init(g_1, p); + nmod_poly_init(f_d, p); + nmod_poly_init(g, p); + nmod_poly_derivative(f_d, f); + + /* Case 1 */ + if (nmod_poly_is_zero(f_d)) + { + nmod_poly_factor_t new_res; + nmod_poly_t h; + + nmod_poly_init(h, p); + + for (i = 0; i <= deg / p; i++) /* this will be an integer since f'=0 */ + { + nmod_poly_set_coeff_ui(h, i, nmod_poly_get_coeff_ui(f, i * p)); + } + + /* Now run square-free on h, and return it to the pth power */ + nmod_poly_factor_init(new_res); + + nmod_poly_factor_squarefree(new_res, h); + nmod_poly_factor_pow(new_res, p); + + nmod_poly_factor_concat(res, new_res); + nmod_poly_clear(h); + nmod_poly_factor_clear(new_res); + } + else + { + nmod_poly_t h, z; + + nmod_poly_gcd(g, f, f_d); + nmod_poly_div(g_1, f, g); + + i = 1; + + nmod_poly_init(h, p); + nmod_poly_init(z, p); + + /* Case 2 */ + while (!nmod_poly_is_one(g_1)) + { + nmod_poly_gcd(h, g_1, g); + nmod_poly_div(z, g_1, h); + + /* out <- out.z */ + if (z->length > 1) + { + nmod_poly_factor_insert(res, z, 1); + nmod_poly_make_monic(res->p + (res->num - 1), + res->p + (res->num - 1)); + if (res->num) + res->exp[res->num - 1] *= i; + } + + i++; + nmod_poly_set(g_1, h); + nmod_poly_div(g, g, h); + } + + nmod_poly_clear(h); + nmod_poly_clear(z); + + nmod_poly_make_monic(g, g); + + if (!nmod_poly_is_one(g)) + { + /* so now we multiply res with square-free(g^1/p) ^ p */ + nmod_poly_t g_p; /* g^(1/p) */ + nmod_poly_factor_t new_res_2; + + nmod_poly_init(g_p, p); + + for (i = 0; i <= nmod_poly_degree(g) / p; i++) + nmod_poly_set_coeff_ui(g_p, i, nmod_poly_get_coeff_ui(g, i*p)); + + nmod_poly_factor_init(new_res_2); + + /* square-free(g^(1/p)) */ + nmod_poly_factor_squarefree(new_res_2, g_p); + nmod_poly_factor_pow(new_res_2, p); + + nmod_poly_factor_concat(res, new_res_2); + nmod_poly_clear(g_p); + nmod_poly_factor_clear(new_res_2); + } + } + + nmod_poly_clear(g_1); + nmod_poly_clear(f_d); + nmod_poly_clear(g); +} diff --git a/external/flint-2.4.3/nmod_poly_factor/fit_length.c b/external/flint-2.4.3/nmod_poly_factor/fit_length.c new file mode 100644 index 0000000..67e5fd3 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_factor/fit_length.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2008, 2009 William Hart + +******************************************************************************/ + +#include +#include "nmod_poly.h" + +void nmod_poly_factor_fit_length(nmod_poly_factor_t fac, slong len) +{ + if (len > fac->alloc) + { + /* At least double number of allocated coeffs */ + if (len < 2 * fac->alloc) + len = 2 * fac->alloc; + nmod_poly_factor_realloc(fac, len); + } +} diff --git a/external/flint-2.4.3/nmod_poly_factor/init.c b/external/flint-2.4.3/nmod_poly_factor/init.c new file mode 100644 index 0000000..94b2604 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_factor/init.c @@ -0,0 +1,46 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_poly.h" + +void +nmod_poly_factor_init(nmod_poly_factor_t fac) +{ + slong i; + + fac->alloc = 5; + fac->num = 0; + fac->p = flint_malloc(sizeof(nmod_poly_struct) * 5); + fac->exp = flint_malloc(sizeof(slong) * 5); + + for (i = 0; i < 5; i++) + nmod_poly_init_preinv(fac->p + i, 1, 0); +} diff --git a/external/flint-2.4.3/nmod_poly_factor/insert.c b/external/flint-2.4.3/nmod_poly_factor/insert.c new file mode 100644 index 0000000..c9ba991 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_factor/insert.c @@ -0,0 +1,67 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "nmod_poly.h" + +void +nmod_poly_factor_insert(nmod_poly_factor_t fac, + const nmod_poly_t poly, slong exp) +{ + slong i; + + if (poly->length <= 1) + return; + + for (i = 0; i < fac->num; i++) + { + if (nmod_poly_equal(poly, fac->p + i)) + { + fac->exp[i] += exp; + return; + } + } + + if (fac->alloc == fac->num) + { + slong new_size = 2 * fac->alloc; + + fac->p = flint_realloc(fac->p, sizeof(nmod_poly_struct) * new_size); + fac->exp = flint_realloc(fac->exp, sizeof(slong) * new_size); + + for (i = fac->alloc; i < new_size; i++) + nmod_poly_init_preinv(fac->p + i, 1, 0); + + fac->alloc = new_size; + } + + nmod_poly_set(fac->p + (fac->num), poly); + (fac->p + (fac->num))->mod = poly->mod; + fac->exp[fac->num] = exp; + fac->num++; +} diff --git a/external/flint-2.4.3/nmod_poly_factor/is_irreducible.c b/external/flint-2.4.3/nmod_poly_factor/is_irreducible.c new file mode 100644 index 0000000..1bb38c6 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_factor/is_irreducible.c @@ -0,0 +1,42 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Martin Lee + +******************************************************************************/ + +#include "nmod_poly.h" + +int +nmod_poly_is_irreducible(const nmod_poly_t f) +{ + if (nmod_poly_length(f) > 2) + { + return nmod_poly_is_irreducible_ddf(f); + } + + return 1; +} diff --git a/external/flint-2.4.3/nmod_poly_factor/is_irreducible_ddf.c b/external/flint-2.4.3/nmod_poly_factor/is_irreducible_ddf.c new file mode 100644 index 0000000..f3d92cc --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_factor/is_irreducible_ddf.c @@ -0,0 +1,140 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Lina Kulakova + Copyright (C) 2013 Martin Lee + +******************************************************************************/ + +#undef ulong +#define ulong ulongxx/* interferes with system includes */ + +#include + +#undef ulong + +#include + +#define ulong mp_limb_t + +#include "nmod_poly.h" + +int nmod_poly_is_irreducible_ddf(const nmod_poly_t poly) +{ + + nmod_poly_t f, v, vinv, reducedH0, tmp; + nmod_poly_t *h, *H, *I; + slong i, j, l, m, n, d; + double beta; + int result= 1; + n = nmod_poly_degree(poly); + + if (n < 2) + return 1; + + if (!nmod_poly_is_squarefree(poly)) + return 0; + + beta = 0.5 * (1. - (log(2) / log(n))); + l = ceil(pow (n, beta)); + m = ceil(0.5 * n / l); + + /* initialization */ + nmod_poly_init_preinv(f, poly->mod.n, poly->mod.ninv); + nmod_poly_init_preinv(v, poly->mod.n, poly->mod.ninv); + nmod_poly_init_preinv(vinv, poly->mod.n, poly->mod.ninv); + nmod_poly_init_preinv(reducedH0, poly->mod.n, poly->mod.ninv); + nmod_poly_init_preinv(tmp, poly->mod.n, poly->mod.ninv); + + if (!(h = flint_malloc((2 * m + l + 1) * sizeof(nmod_poly_struct)))) + { + flint_printf("Exception (nmod_poly_is_irreducible_ddf):\n"); + flint_printf("Not enough memory.\n"); + abort(); + } + H = h + (l + 1); + I = H + m; + for (i = 0; i < l + 1; i++) + nmod_poly_init_preinv(h[i], poly->mod.n, poly->mod.ninv); + for (i = 0; i < m; i++) + { + nmod_poly_init_preinv(H[i], poly->mod.n, poly->mod.ninv); + nmod_poly_init_preinv(I[i], poly->mod.n, poly->mod.ninv); + } + + nmod_poly_make_monic(v, poly); + + nmod_poly_reverse(vinv, v, v->length); + nmod_poly_inv_series(vinv, vinv, v->length); + /* compute baby steps: h[i]=x^{p^i}mod v */ + nmod_poly_set_coeff_ui(h[0], 1, 1); + for (i = 1; i < l + 1; i++) + nmod_poly_powmod_ui_binexp_preinv(h[i], h[i - 1], poly->mod.n, v, vinv); /* may be for large l use compose_mod instead */ + + /* compute coarse distinct-degree factorisation */ + nmod_poly_set(H[0], h[l]); + nmod_poly_set(reducedH0, H[0]); + d= 1; + for (j = 0; j < m; j++) + { + /* compute giant steps: H[j]=x^{p^(lj)}mod s */ + if (j > 0) + { + nmod_poly_rem (reducedH0, reducedH0, v); + nmod_poly_rem (tmp, H[j - 1], v); + nmod_poly_compose_mod_brent_kung_preinv(H[j], tmp, reducedH0, v, vinv); + } + /* compute interval polynomials */ + nmod_poly_set_coeff_ui(I[j], 0, 1); + for (i = l - 1; (i >= 0) && (2 * d <= v->length - 1); i--, d++) + { + nmod_poly_rem(tmp, h[i], v); + nmod_poly_sub(tmp, H[j], tmp); + nmod_poly_mulmod_preinv (I[j], tmp, I[j], v, vinv); + } + + /* compute F_j=f^{[j*l+1]} * ... * f^{[j*l+l]} */ + /* F_j is stored on the place of I_j */ + nmod_poly_gcd(I[j], v, I[j]); + if (I[j]->length > 1) + { + result= 0; + break; + } + } + + nmod_poly_clear(f); + nmod_poly_clear(reducedH0); + nmod_poly_clear(v); + nmod_poly_clear(vinv); + nmod_poly_clear(tmp); + + for (i = 0; i < l + 1; i++) + nmod_poly_clear(h[i]); + for (i = 0; i < m; i++) + { + nmod_poly_clear(H[i]); + nmod_poly_clear(I[i]); + } + flint_free (h); + + return result; +} diff --git a/external/flint-2.4.3/nmod_poly_factor/is_irreducible_rabin.c b/external/flint-2.4.3/nmod_poly_factor/is_irreducible_rabin.c new file mode 100644 index 0000000..53ee6ce --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_factor/is_irreducible_rabin.c @@ -0,0 +1,111 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "nmod_poly.h" +#include "ulong_extras.h" + +void +nmod_poly_powpowmod(nmod_poly_t res, const nmod_poly_t pol, + ulong exp, ulong exp2, const nmod_poly_t f) +{ + nmod_poly_t pow; + ulong i; + + nmod_poly_init_preinv(pow, f->mod.n, f->mod.ninv); + nmod_poly_powmod_ui_binexp(pow, pol, exp, f); + nmod_poly_set(res, pow); + + if (!nmod_poly_equal(pow, pol)) + for (i = 1; i < exp2; i++) + nmod_poly_powmod_ui_binexp(res, res, exp, f); + + nmod_poly_clear(pow); +} + +int +nmod_poly_is_irreducible_rabin(const nmod_poly_t f) +{ + if (nmod_poly_length(f) > 2) + { + const mp_limb_t p = nmod_poly_modulus(f); + const slong n = nmod_poly_degree(f); + nmod_poly_t a, x, x_p; + + nmod_poly_init(a, p); + nmod_poly_init(x, p); + nmod_poly_init(x_p, p); + nmod_poly_set_coeff_ui(x, 1, 1); + + /* Compute x^q mod f */ + nmod_poly_powpowmod(x_p, x, p, n, f); + if (!nmod_poly_is_zero(x_p)) + nmod_poly_make_monic(x_p, x_p); + + /* Now do the irreducibility test */ + if (!nmod_poly_equal(x_p, x)) + { + nmod_poly_clear(a); + nmod_poly_clear(x); + nmod_poly_clear(x_p); + return 0; + } + else + { + n_factor_t factors; + slong i; + + n_factor_init(&factors); + n_factor(&factors, n, 1); + + for (i = 0; i < factors.num; i++) + { + nmod_poly_powpowmod(a, x, p, n / factors.p[i], f); + nmod_poly_sub(a, a, x); + + if (!nmod_poly_is_zero(a)) + nmod_poly_make_monic(a, a); + + nmod_poly_gcd(a, a, f); + + if (a->length != 1) + { + nmod_poly_clear(a); + nmod_poly_clear(x); + nmod_poly_clear(x_p); + return 0; + } + } + } + + nmod_poly_clear(a); + nmod_poly_clear(x); + nmod_poly_clear(x_p); + } + + return 1; +} diff --git a/external/flint-2.4.3/nmod_poly_factor/is_squarefree.c b/external/flint-2.4.3/nmod_poly_factor/is_squarefree.c new file mode 100644 index 0000000..69ca234 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_factor/is_squarefree.c @@ -0,0 +1,60 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "nmod_poly.h" +#include "mpn_extras.h" +#include "ulong_extras.h" + +int +_nmod_poly_is_squarefree(mp_srcptr f, slong len, nmod_t mod) +{ + mp_ptr fd, g; + slong dlen; + int res; + + if (len <= 2) + return len != 0; + + fd = flint_malloc(sizeof(mp_limb_t) * 2 * (len - 1)); + g = fd + len - 1; + + _nmod_poly_derivative(fd, f, len, mod); + dlen = len - 1; + MPN_NORM(fd, dlen); + + if (dlen) + res = (_nmod_poly_gcd(g, f, len, fd, dlen, mod) == 1); + else + res = 0; /* gcd(f, 0) = f, and len(f) > 2 */ + + flint_free(fd); + return res; +} + +int +nmod_poly_is_squarefree(const nmod_poly_t f) +{ + return _nmod_poly_is_squarefree(f->coeffs, f->length, f->mod); +} diff --git a/external/flint-2.4.3/nmod_poly_factor/pow.c b/external/flint-2.4.3/nmod_poly_factor/pow.c new file mode 100644 index 0000000..34df386 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_factor/pow.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "nmod_poly.h" + +void +nmod_poly_factor_pow(nmod_poly_factor_t fac, slong exp) +{ + slong i; + + for (i = 0; i < fac->num; i++) + fac->exp[i] *= exp; +} diff --git a/external/flint-2.4.3/nmod_poly_factor/print.c b/external/flint-2.4.3/nmod_poly_factor/print.c new file mode 100644 index 0000000..6b88654 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_factor/print.c @@ -0,0 +1,44 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_poly.h" + +void +nmod_poly_factor_print(const nmod_poly_factor_t fac) +{ + slong i; + + for (i = 0; i < fac->num; i++) + { + nmod_poly_print(fac->p + i); + flint_printf(" ^ %wd\n", fac->exp[i]); + } +} diff --git a/external/flint-2.4.3/nmod_poly_factor/profile/p-factor.c b/external/flint-2.4.3/nmod_poly_factor/profile/p-factor.c new file mode 100644 index 0000000..0194783 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_factor/profile/p-factor.c @@ -0,0 +1,353 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Lina Kulakova + +******************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include "flint.h" +#include "nmod_poly.h" + +#define NP 100 /* number of moduli */ +#define ND 8 /* number of degrees */ + +/* + Benchmarking code for factorisation in nmod_poly. + + Test how the relation between n (degree of polynomial) and p + affects working time for Cantor-Zassenhaus, Berlekamp and + Kaltofen-Shoup algorithms. p and n are chosen independently. +*/ + +int main(void) +{ + FLINT_TEST_INIT(state); + nmod_poly_t f, g; + nmod_poly_factor_t res; + mp_limb_t modulus; + int i, j, k, n, num; + double t, T1, T2, T3, T4; + + const slong degs[] = {8, 16, 32, 64, 128, 256, 512, 1024}; + const int iter_count[] = {10000, 5000, 1000, 500, 300, 100, 50, 20}; + + + + flint_printf("Random polynomials\n"); + for (i = 0; i < NP; i++) + { + modulus = n_randtest_prime(state, 0); + flint_printf("========== p: %wu\n", modulus); + fflush(stdout); + + for (j = 0; j < ND; j++) + { + n = degs[j]; + flint_printf(">>>>>n: %d\n", n); + fflush(stdout); + + T1 = 0; + T2 = 0; + T3 = 0; + for (k = 0; k < iter_count[j]; k++) + { + nmod_poly_init(f, modulus); + nmod_poly_randtest_not_zero(f, state, n); + + t = clock(); + nmod_poly_factor_init(res); + nmod_poly_factor_with_cantor_zassenhaus(res, f); + nmod_poly_factor_clear(res); + t = (clock() - t) / CLOCKS_PER_SEC; + T1 += t; + + t = clock(); + nmod_poly_factor_init(res); + nmod_poly_factor_with_berlekamp(res, f); + nmod_poly_factor_clear(res); + t = (clock() - t) / CLOCKS_PER_SEC; + T2 += t; + + t = clock(); + nmod_poly_factor_init(res); + nmod_poly_factor_kaltofen_shoup(res, f); + nmod_poly_factor_clear(res); + t = (clock() - t) / CLOCKS_PER_SEC; + T3 += t; + + nmod_poly_clear(f); + } + + flint_printf("CZ: %.2lf B: %.2lf KS: %.2lf\n", T1, T2, T3); + fflush(stdout); + + if (T1 > T3 + 1) + break; + + } + } + + /* This code checks whether nmod_poly_factor + made a correct choice between CZ, B and KS */ + + flint_printf("Check choice correctness\n"); + for (i = 0; i < NP; i++) + { + modulus = n_randtest_prime(state, 0); + flint_printf("========== p: %wu\n", modulus); + fflush(stdout); + + for (j = 0; j < ND; j++) + { + n = degs[j]; + flint_printf(">>>>>n: %d\n", n); + fflush(stdout); + + T1 = 0; + T2 = 0; + T3 = 0; + T4 = 0; + for (k = 0; k < iter_count[j]; k++) + { + nmod_poly_init(f, modulus); + nmod_poly_randtest_not_zero(f, state, n); + + t = clock(); + nmod_poly_factor_init(res); + nmod_poly_factor_with_cantor_zassenhaus(res, f); + nmod_poly_factor_clear(res); + t = (clock() - t) / CLOCKS_PER_SEC; + T1 += t; + + t = clock(); + nmod_poly_factor_init(res); + nmod_poly_factor_berlekamp(res, f); + nmod_poly_factor_clear(res); + t = (clock() - t) / CLOCKS_PER_SEC; + T2 += t; + + t = clock(); + nmod_poly_factor_init(res); + nmod_poly_factor_kaltofen_shoup(res, f); + nmod_poly_factor_clear(res); + t = (clock() - t) / CLOCKS_PER_SEC; + T3 += t; + + t = clock(); + nmod_poly_factor_init(res); + nmod_poly_factor(res, f); + nmod_poly_factor_clear(res); + t = (clock() - t) / CLOCKS_PER_SEC; + T4 += t; + + nmod_poly_clear(f); + } + + flint_printf("CZ: %.2lf B: %.2lf KS: %.2lf F: %.2lf\n", T1, T2, T3, T4); + fflush(stdout); + + if (T1 > T3 + 1) + break; + + } + } + + flint_printf("Irreducible polynomials\n"); + for (i = 0; i < NP; i++) + { + modulus = n_randtest_prime(state, 0); + flint_printf("========== p: %wu\n", modulus); + fflush(stdout); + + for (j = 0; j < ND; j++) + { + n = degs[j]; + flint_printf(">>>>>n: %d\n", n); + fflush(stdout); + + T1 = 0; + T2 = 0; + T3 = 0; + for (k = 0; k < iter_count[j]; k++) + { + nmod_poly_init(f, modulus); + nmod_poly_randtest_irreducible(f, state, n); + + t = clock(); + nmod_poly_factor_init(res); + nmod_poly_factor_with_cantor_zassenhaus(res, f); + nmod_poly_factor_clear(res); + t = (clock() - t) / CLOCKS_PER_SEC; + T1 += t; + + t = clock(); + nmod_poly_factor_init(res); + nmod_poly_factor_with_berlekamp(res, f); + nmod_poly_factor_clear(res); + t = (clock() - t) / CLOCKS_PER_SEC; + T2 += t; + + t = clock(); + nmod_poly_factor_init(res); + nmod_poly_factor_kaltofen_shoup(res, f); + nmod_poly_factor_clear(res); + t = (clock() - t) / CLOCKS_PER_SEC; + T3 += t; + + nmod_poly_clear(f); + } + + flint_printf("CZ: %.2lf B: %.2lf KS: %.2lf\n", T1, T2, T3); + fflush(stdout); + + if (T1 > T3 + 1) + break; + } + } + + flint_printf("Product of two irreducible polynomials\n"); + for (i = 0; i < NP; i++) + { + modulus = n_randtest_prime(state, 0); + flint_printf("========== p: %wu\n", modulus); + fflush(stdout); + + for (j = 0; j < ND; j++) + { + n = (degs[j] >> 1); + flint_printf(">>>>>n: %d\n", n); + fflush(stdout); + + T1 = 0; + T2 = 0; + T3 = 0; + for (k = 0; k < iter_count[j]; k++) + { + nmod_poly_init(f, modulus); + nmod_poly_init(g, modulus); + nmod_poly_randtest_irreducible(f, state, n); + nmod_poly_randtest_irreducible(g, state, n); + nmod_poly_mul(f, f, g); + + t = clock(); + nmod_poly_factor_init(res); + nmod_poly_factor_with_cantor_zassenhaus(res, f); + nmod_poly_factor_clear(res); + t = (clock() - t) / CLOCKS_PER_SEC; + T1 += t; + + t = clock(); + nmod_poly_factor_init(res); + nmod_poly_factor_with_berlekamp(res, f); + nmod_poly_factor_clear(res); + t = (clock() - t) / CLOCKS_PER_SEC; + T2 += t; + + t = clock(); + nmod_poly_factor_init(res); + nmod_poly_factor_kaltofen_shoup(res, f); + nmod_poly_factor_clear(res); + t = (clock() - t) / CLOCKS_PER_SEC; + T3 += t; + + nmod_poly_clear(f); + nmod_poly_clear(g); + } + + flint_printf("CZ: %.2lf B: %.2lf KS: %.2lf\n", T1, T2, T3); + fflush(stdout); + + if (T1 > T3 + 1) + break; + } + } + + flint_printf("Product of 8 small irreducible polynomials\n"); + for (i = 0; i < NP; i++) + { + modulus = n_randtest_prime(state, 0); + flint_printf("========== p: %wu\n", modulus); + fflush(stdout); + + for (j = 1; j < ND; j++) + { + n = (degs[j] >> 3); + flint_printf(">>>>>n: %d\n", n); + fflush(stdout); + + T1 = 0; + T2 = 0; + T3 = 0; + for (k = 0; k < iter_count[j]; k++) + { + nmod_poly_init(f, modulus); + nmod_poly_init(g, modulus); + nmod_poly_randtest_irreducible(f, state, n); + for (num = 1; num < 8; num++) + { + nmod_poly_randtest_irreducible(g, state, n); + nmod_poly_mul(f, f, g); + } + + t = clock(); + nmod_poly_factor_init(res); + nmod_poly_factor_with_cantor_zassenhaus(res, f); + nmod_poly_factor_clear(res); + t = (clock() - t) / CLOCKS_PER_SEC; + T1 += t; + + t = clock(); + nmod_poly_factor_init(res); + nmod_poly_factor_with_berlekamp(res, f); + nmod_poly_factor_clear(res); + t = (clock() - t) / CLOCKS_PER_SEC; + T2 += t; + + t = clock(); + nmod_poly_factor_init(res); + nmod_poly_factor_kaltofen_shoup(res, f); + nmod_poly_factor_clear(res); + t = (clock() - t) / CLOCKS_PER_SEC; + T3 += t; + + nmod_poly_clear(f); + nmod_poly_clear(g); + } + + flint_printf("CZ: %.2lf B: %.2lf KS: %.2lf\n", T1, T2, T3); + fflush(stdout); + + if (T1 > T3 + 1) + break; + } + } + + flint_randclear(state); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/nmod_poly_factor/profile/p-factorbench.c b/external/flint-2.4.3/nmod_poly_factor/profile/p-factorbench.c new file mode 100644 index 0000000..888c131 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_factor/profile/p-factorbench.c @@ -0,0 +1,75 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Martin Lee + +******************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include "flint.h" +#include "nmod_poly.h" + +int main (void) +{ + + double t; + nmod_poly_t f, g, h; + for (int i= 15001;i < 16000; i++) + { + nmod_poly_init2 (f, 17, i/2+1); + nmod_poly_init2 (g, 17, i+1); + + nmod_poly_set_coeff_ui (f, i/2, 1); + nmod_poly_set_coeff_ui (f, 1, 1); + nmod_poly_set_coeff_ui (f, 0, ((i%17)*(i%17)+3) % 17); + + nmod_poly_set_coeff_ui (g, i, 1); + nmod_poly_set_coeff_ui (g, i/2+1, 1); + nmod_poly_set_coeff_ui (g, 1, ((i % 17)+1)%17); + nmod_poly_set_coeff_ui (g, 0, 15); + + nmod_poly_init (h, 17); + nmod_poly_gcd (h, f, g); + + if (!nmod_poly_is_one (h)) + { + flint_printf ("i= %d\n", i); + nmod_poly_factor_t factors; + nmod_poly_factor_init (factors); + t= clock(); + nmod_poly_factor (factors, h); + t = (clock() - t) / CLOCKS_PER_SEC; + flint_printf("factorization %.2lf\n", t); + nmod_poly_factor_clear (factors); + } + + nmod_poly_clear (f); + nmod_poly_clear (g); + nmod_poly_clear (h); + } + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/nmod_poly_factor/realloc.c b/external/flint-2.4.3/nmod_poly_factor/realloc.c new file mode 100644 index 0000000..d4e5759 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_factor/realloc.c @@ -0,0 +1,77 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "nmod_poly.h" + +void nmod_poly_factor_realloc(nmod_poly_factor_t fac, slong alloc) +{ + if (alloc == 0) /* Clear up, reinitialise */ + { + nmod_poly_factor_clear(fac); + nmod_poly_factor_init(fac); + } + else if (fac->alloc) /* Realloc */ + { + if (fac->alloc > alloc) + { + slong i; + + for (i = alloc; i < fac->num; i++) + nmod_poly_clear(fac->p + i); + + fac->p = flint_realloc(fac->p, alloc * sizeof(nmod_poly_struct)); + fac->exp = flint_realloc(fac->exp, alloc * sizeof(slong)); + fac->alloc = alloc; + } + else if (fac->alloc < alloc) + { + slong i; + + fac->p = flint_realloc(fac->p, alloc * sizeof(nmod_poly_struct)); + fac->exp = flint_realloc(fac->exp, alloc * sizeof(slong)); + + for (i = fac->alloc; i < alloc; i++) + { + nmod_poly_init_preinv(fac->p + i, 1, 0); + fac->exp[i] = WORD(0); + } + fac->alloc = alloc; + } + } + else /* Nothing allocated already so do it now */ + { + slong i; + + fac->p = flint_malloc(alloc * sizeof(nmod_poly_struct)); + fac->exp = flint_calloc(alloc, sizeof(slong)); + + for (i = 0; i < alloc; i++) + nmod_poly_init_preinv(fac->p + i, 1, 0); + fac->num = 0; + fac->alloc = alloc; + } +} + diff --git a/external/flint-2.4.3/nmod_poly_factor/set.c b/external/flint-2.4.3/nmod_poly_factor/set.c new file mode 100644 index 0000000..731aa89 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_factor/set.c @@ -0,0 +1,58 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "flint.h" +#include "nmod_poly.h" + +void nmod_poly_factor_set(nmod_poly_factor_t res, const nmod_poly_factor_t fac) +{ + if (res != fac) + { + if (fac->num == 0) + { + nmod_poly_factor_clear(res); + nmod_poly_factor_init(res); + } + else + { + slong i; + + nmod_poly_factor_fit_length(res, fac->num); + for (i = 0; i < fac->num; i++) + { + nmod_poly_set(res->p + i, fac->p + i); + (res->p + i)->mod = (fac->p + i)->mod; + res->exp[i] = fac->exp[i]; + } + for ( ; i < res->num; i++) + { + nmod_poly_zero(res->p + i); + res->exp[i] = 0; + } + res->num = fac->num; + } + } +} + diff --git a/external/flint-2.4.3/nmod_poly_factor/test/t-factor.c b/external/flint-2.4.3/nmod_poly_factor/test/t-factor.c new file mode 100644 index 0000000..024cd07 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_factor/test/t-factor.c @@ -0,0 +1,271 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int iter; + FLINT_TEST_INIT(state); + + + flint_printf("factor...."); + fflush(stdout); + + /* Default algorithm */ + for (iter = 0; iter < 10 * flint_test_multiplier(); iter++) + { + int result = 1; + nmod_poly_t pol1, poly, quot, rem, product; + nmod_poly_factor_t res; + mp_limb_t modulus, lead = 1; + slong length, num, i, j; + ulong exp[5], prod1; + + modulus = n_randtest_prime(state, 0); + + nmod_poly_init(pol1, modulus); + nmod_poly_init(poly, modulus); + nmod_poly_init(quot, modulus); + nmod_poly_init(rem, modulus); + + nmod_poly_zero(pol1); + nmod_poly_set_coeff_ui(pol1, 0, 1); + + length = n_randint(state, 7) + 2; + do + { + nmod_poly_randtest(poly, state, length); + if (poly->length) + nmod_poly_make_monic(poly, poly); + } + while ((!nmod_poly_is_irreducible(poly)) || (poly->length < 2)); + + exp[0] = n_randint(state, 30) + 1; + prod1 = exp[0]; + for (i = 0; i < exp[0]; i++) + nmod_poly_mul(pol1, pol1, poly); + + num = n_randint(state, 5) + 1; + for (i = 1; i < num; i++) + { + do + { + length = n_randint(state, 7) + 2; + nmod_poly_randtest(poly, state, length); + if (poly->length) + { + nmod_poly_make_monic(poly, poly); + nmod_poly_divrem(quot, rem, pol1, poly); + } + } + while ((!nmod_poly_is_irreducible(poly)) || + (poly->length < 2) || (rem->length == 0)); + exp[i] = n_randint(state, 30) + 1; + prod1 *= exp[i]; + + for (j = 0; j < exp[i]; j++) + nmod_poly_mul(pol1, pol1, poly); + } + + nmod_poly_factor_init(res); + + switch (n_randint(state, 3)) + { + case 0: + lead = nmod_poly_factor(res, pol1); + break; + case 1: + lead = nmod_poly_factor_with_berlekamp(res, pol1); + break; + case 2: + if (modulus == 2) + lead = nmod_poly_factor(res, pol1); + else + lead = nmod_poly_factor_with_cantor_zassenhaus(res, pol1); + break; + } + + result &= (res->num == num); + if (!result) + { + flint_printf("Error: number of factors incorrect, %wd, %wd\n", + res->num, num); + abort(); + } + + nmod_poly_init(product, pol1->mod.n); + nmod_poly_set_coeff_ui(product, 0, 1); + for (i = 0; i < res->num; i++) + for (j = 0; j < res->exp[i]; j++) + nmod_poly_mul(product, product, res->p + i); + nmod_poly_scalar_mul_nmod(product, product, lead); + result &= nmod_poly_equal(pol1, product); + if (!result) + { + flint_printf("Error: product of factors does not equal original polynomial\n"); + nmod_poly_print(pol1); flint_printf("\n"); + nmod_poly_print(product); flint_printf("\n"); + abort(); + } + nmod_poly_clear(product); + + nmod_poly_clear(quot); + nmod_poly_clear(rem); + nmod_poly_clear(pol1); + nmod_poly_clear(poly); + nmod_poly_factor_clear(res); + } + + /* Test deflation trick */ + for (iter = 0; iter < 10 * flint_test_multiplier(); iter++) + { + nmod_poly_t pol1, poly, quot, rem; + nmod_poly_factor_t res, res2; + mp_limb_t modulus; + slong length, num, i, j; + slong exp[5], prod1; + ulong inflation; + int found; + + do { + modulus = n_randtest_prime(state, 0); + } while (modulus == 2); /* To compare with CZ */ + + nmod_poly_init(pol1, modulus); + nmod_poly_init(poly, modulus); + nmod_poly_init(quot, modulus); + nmod_poly_init(rem, modulus); + + nmod_poly_zero(pol1); + nmod_poly_set_coeff_ui(pol1, 0, 1); + + inflation = n_randint(state, 7) + 1; + + length = n_randint(state, 7) + 2; + do + { + nmod_poly_randtest(poly, state, length); + if (poly->length) + nmod_poly_make_monic(poly, poly); + } + while ((!nmod_poly_is_irreducible(poly)) || (poly->length < 2)); + nmod_poly_inflate(poly, poly, inflation); + + exp[0] = n_randint(state, 6) + 1; + prod1 = exp[0]; + for (i = 0; i < exp[0]; i++) + nmod_poly_mul(pol1, pol1, poly); + + num = n_randint(state, 5) + 1; + for (i = 1; i < num; i++) + { + do + { + length = n_randint(state, 6) + 2; + nmod_poly_randtest(poly, state, length); + if (poly->length) + { + nmod_poly_make_monic(poly, poly); + nmod_poly_divrem(quot, rem, pol1, poly); + } + } + while ((!nmod_poly_is_irreducible(poly)) || + (poly->length < 2) || (rem->length == 0)); + exp[i] = n_randint(state, 6) + 1; + prod1 *= exp[i]; + nmod_poly_inflate(poly, poly, inflation); + + for (j = 0; j < exp[i]; j++) + nmod_poly_mul(pol1, pol1, poly); + } + + nmod_poly_factor_init(res); + nmod_poly_factor_init(res2); + + switch (n_randint(state, 3)) + { + case 0: + nmod_poly_factor(res, pol1); + break; + case 1: + nmod_poly_factor_with_berlekamp(res, pol1); + break; + case 2: + nmod_poly_factor_with_cantor_zassenhaus(res, pol1); + break; + } + + nmod_poly_factor_cantor_zassenhaus(res2, pol1); + + if (res->num != res2->num) + { + flint_printf("FAIL: different number of factors found\n"); + abort(); + } + + for (i = 0; i < res->num; i++) + { + found = 0; + for (j = 0; j < res2->num; j++) + { + if (nmod_poly_equal(res->p + i, res2->p + j) && + res->exp[i] == res2->exp[j]) + { + found = 1; + break; + } + } + + if (!found) + { + flint_printf("FAIL: factor not found\n"); + abort(); + } + } + + nmod_poly_clear(quot); + nmod_poly_clear(rem); + nmod_poly_clear(pol1); + nmod_poly_clear(poly); + nmod_poly_factor_clear(res); + nmod_poly_factor_clear(res2); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly_factor/test/t-factor_berlekamp.c b/external/flint-2.4.3/nmod_poly_factor/test/t-factor_berlekamp.c new file mode 100644 index 0000000..dcf1114 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_factor/test/t-factor_berlekamp.c @@ -0,0 +1,110 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int iter; + FLINT_TEST_INIT(state); + + + flint_printf("factor_berlekamp...."); + fflush(stdout); + + for (iter = 0; iter < 20 * flint_test_multiplier(); iter++) + { + int result = 1; + nmod_poly_t pol1, poly, quot, rem; + nmod_poly_factor_t res; + mp_limb_t modulus; + slong i, length, num; + + modulus = n_randtest_prime(state, 0); + + nmod_poly_init(pol1, modulus); + nmod_poly_init(poly, modulus); + nmod_poly_init(quot, modulus); + nmod_poly_init(rem, modulus); + + length = n_randint(state, 10) + 2; + do + { + nmod_poly_randtest(pol1, state, length); + if (pol1->length) + nmod_poly_make_monic(pol1, pol1); + } + while ((!nmod_poly_is_irreducible(pol1)) || (pol1->length < 2)); + + num = n_randint(state, 5) + 1; + for (i = 1; i < num; i++) + { + do + { + length = n_randint(state, 10) + 2; + nmod_poly_randtest(poly, state, length); + if (poly->length) + { + nmod_poly_make_monic(poly, poly); + nmod_poly_divrem(quot, rem, pol1, poly); + } + } + while ((!nmod_poly_is_irreducible(poly)) || (poly->length < 2) + || (rem->length == 0)); + nmod_poly_mul(pol1, pol1, poly); + } + + nmod_poly_factor_init(res); + nmod_poly_factor_berlekamp(res, pol1); + + result = (res->num == num); + if (!result) + { + flint_printf("FAIL: %wu, %wd, %wd\n", modulus, num, res->num); + abort(); + } + + nmod_poly_clear(quot); + nmod_poly_clear(rem); + nmod_poly_clear(pol1); + nmod_poly_clear(poly); + nmod_poly_factor_clear(res); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly_factor/test/t-factor_cantor_zassenhaus.c b/external/flint-2.4.3/nmod_poly_factor/test/t-factor_cantor_zassenhaus.c new file mode 100644 index 0000000..6f2912b --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_factor/test/t-factor_cantor_zassenhaus.c @@ -0,0 +1,144 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int iter; + FLINT_TEST_INIT(state); + + + flint_printf("factor_cantor_zassenhaus...."); + fflush(stdout); + + for (iter = 0; iter < 20 * flint_test_multiplier(); iter++) + { + int result = 1; + nmod_poly_t pol1, poly, quot, rem; + nmod_poly_t product; + nmod_poly_factor_t res; + mp_limb_t modulus, lead; + slong i, j, length, num; + slong prod1, exp[5]; + + modulus = n_randtest_prime(state, 0); + + nmod_poly_init(pol1, modulus); + nmod_poly_init(poly, modulus); + nmod_poly_init(quot, modulus); + nmod_poly_init(rem, modulus); + + nmod_poly_zero(pol1); + nmod_poly_set_coeff_ui(pol1, 0, 1); + + length = n_randint(state, 7) + 2; + + do + { + nmod_poly_randtest(poly, state, length); + if(!nmod_poly_is_zero(poly)) + nmod_poly_make_monic(poly, poly); + } + while ((poly->length < 2) || (!nmod_poly_is_irreducible(poly))); + + exp[0] = n_randint(state, 30) + 1; + prod1 = exp[0]; + for (i = 0; i < exp[0]; i++) + nmod_poly_mul(pol1, pol1, poly); + + num = n_randint(state, 5) + 1; + + for (i = 1; i < num; i++) + { + do + { + length = n_randint(state, 7) + 2; + nmod_poly_randtest(poly, state, length); + if(!nmod_poly_is_zero(poly)) + { + nmod_poly_make_monic(poly, poly); + nmod_poly_divrem(quot, rem, pol1, poly); + } + } + while ((!nmod_poly_is_irreducible(poly)) || (poly->length < 2) || + (rem->length == 0)); + + exp[i] = n_randint(state, 30) + 1; + prod1 *= exp[i]; + for (j = 0; j < exp[i]; j++) + nmod_poly_mul(pol1, pol1, poly); + } + + nmod_poly_factor_init(res); + nmod_poly_factor_cantor_zassenhaus(res, pol1); + result &= (res->num == num); + + if (!result) + { + flint_printf("Error: number of factors incorrect, %wd, %wd\n", + res->num, num); + } + + nmod_poly_init(product, pol1->mod.n); + nmod_poly_set_coeff_ui(product, 0, 1); + for (i = 0; i < res->num; i++) + for (j = 0; j < res->exp[i]; j++) + nmod_poly_mul(product, product, res->p + i); + + lead = pol1->coeffs[pol1->length - 1]; + nmod_poly_scalar_mul_nmod(product, product, lead); + result &= nmod_poly_equal(pol1, product); + + if (!result) + { + flint_printf("Error: product of factors does not equal original polynomial\n"); + nmod_poly_print(pol1); flint_printf("\n"); + nmod_poly_print(product); flint_printf("\n"); + } + + if (!result) + abort(); + + + nmod_poly_clear(product); + nmod_poly_clear(quot); + nmod_poly_clear(rem); + nmod_poly_clear(pol1); + nmod_poly_clear(poly); + nmod_poly_factor_clear(res); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly_factor/test/t-factor_distinct_deg.c b/external/flint-2.4.3/nmod_poly_factor/test/t-factor_distinct_deg.c new file mode 100644 index 0000000..c4f0a8a --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_factor/test/t-factor_distinct_deg.c @@ -0,0 +1,130 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + +******************************************************************************/ + +#include +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int iter; + FLINT_TEST_INIT(state); + + + flint_printf("factor_distinct_deg...."); + fflush(stdout); + + for (iter = 0; iter < 200; iter++) + { + nmod_poly_t poly1, poly, q, r, product; + nmod_poly_factor_t res; + mp_limb_t modulus, lead; + slong i, length, num; + slong *degs; + + modulus = n_randtest_prime(state, 0); + + nmod_poly_init(poly1, modulus); + nmod_poly_init(poly, modulus); + nmod_poly_init(q, modulus); + nmod_poly_init(r, modulus); + + nmod_poly_zero(poly1); + nmod_poly_set_coeff_ui(poly1, 0, 1); + + length = n_randint(state, 7) + 2; + do + { + nmod_poly_randtest(poly, state, length); + if (poly->length) + nmod_poly_make_monic(poly, poly); + } + while ((poly->length < 2) || (!nmod_poly_is_irreducible(poly))); + + nmod_poly_mul(poly1, poly1, poly); + + num = n_randint(state, 5) + 1; + + for (i = 1; i < num; i++) + { + do + { + length = n_randint(state, 7) + 2; + nmod_poly_randtest(poly, state, length); + if (poly->length) + { + nmod_poly_make_monic(poly, poly); + nmod_poly_divrem(q, r, poly1, poly); + } + } + while ((poly->length < 2) || (!nmod_poly_is_irreducible(poly)) || + (r->length == 0)); + + nmod_poly_mul(poly1, poly1, poly); + } + + if (!(degs = flint_malloc((poly1->length - 1) * sizeof(slong)))) + { + flint_printf("Fatal error: not enough memory."); + abort(); + } + nmod_poly_factor_init(res); + nmod_poly_factor_distinct_deg(res, poly1, °s); + + nmod_poly_init_preinv(product, poly1->mod.n, poly1->mod.ninv); + nmod_poly_set_coeff_ui(product, 0, 1); + for (i = 0; i < res->num; i++) + nmod_poly_mul(product, product, res->p + i); + + lead = poly1->coeffs[poly1->length - 1]; + nmod_poly_scalar_mul_nmod(product, product, lead); + + if (!nmod_poly_equal(poly1, product)) + { + flint_printf("Error: product of factors does not equal to the original polynomial\n"); + flint_printf("poly:\n"); nmod_poly_print(poly1); flint_printf("\n"); + flint_printf("product:\n"); nmod_poly_print(product); flint_printf("\n"); + abort(); + } + + flint_free(degs); + nmod_poly_clear(product); + nmod_poly_clear(q); + nmod_poly_clear(r); + nmod_poly_clear(poly1); + nmod_poly_clear(poly); + nmod_poly_factor_clear(res); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly_factor/test/t-factor_kaltofen_shoup.c b/external/flint-2.4.3/nmod_poly_factor/test/t-factor_kaltofen_shoup.c new file mode 100644 index 0000000..03fb188 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_factor/test/t-factor_kaltofen_shoup.c @@ -0,0 +1,135 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2012 Lina Kulakova + +******************************************************************************/ + +#include +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int iter; + FLINT_TEST_INIT(state); + + + flint_printf("factor_kaltofen_shoup...."); + fflush(stdout); + + for (iter = 0; iter < 200; iter++) + { + nmod_poly_t poly1, poly, q, r, product; + nmod_poly_factor_t res; + mp_limb_t modulus, lead; + slong i, j, length, num; + slong exp[5]; + + modulus = n_randtest_prime(state, 0); + + nmod_poly_init(poly1, modulus); + nmod_poly_init(poly, modulus); + nmod_poly_init(q, modulus); + nmod_poly_init(r, modulus); + + nmod_poly_zero(poly1); + nmod_poly_set_coeff_ui(poly1, 0, 1); + + length = n_randint(state, 7) + 2; + do + { + nmod_poly_randtest(poly, state, length); + if (poly->length) + nmod_poly_make_monic(poly, poly); + } + while ((poly->length < 2) || (!nmod_poly_is_irreducible(poly))); + + exp[0] = n_randint(state, 30) + 1; + for (i = 0; i < exp[0]; i++) + nmod_poly_mul(poly1, poly1, poly); + + num = n_randint(state, 5) + 1; + + for (i = 1; i < num; i++) + { + do + { + length = n_randint(state, 7) + 2; + nmod_poly_randtest(poly, state, length); + if (poly->length) + { + nmod_poly_make_monic(poly, poly); + nmod_poly_divrem(q, r, poly1, poly); + } + } + while ((poly->length < 2) || (!nmod_poly_is_irreducible(poly)) || + (r->length == 0)); + + exp[i] = n_randint(state, 30) + 1; + for (j = 0; j < exp[i]; j++) + nmod_poly_mul(poly1, poly1, poly); + } + + nmod_poly_factor_init(res); + nmod_poly_factor_kaltofen_shoup(res, poly1); + + if (res->num != num) + { + flint_printf("Error: number of factors incorrect: %wd != %wd\n", res->num, num); + abort(); + } + + nmod_poly_init_preinv(product, poly1->mod.n, poly1->mod.ninv); + nmod_poly_set_coeff_ui(product, 0, 1); + for (i = 0; i < res->num; i++) + for (j = 0; j < res->exp[i]; j++) + nmod_poly_mul(product, product, res->p + i); + + lead = poly1->coeffs[poly1->length - 1]; + nmod_poly_scalar_mul_nmod(product, product, lead); + + if (!nmod_poly_equal(poly1, product)) + { + flint_printf("Error: product of factors does not equal to the original polynomial\n"); + flint_printf("poly:\n"); nmod_poly_print(poly1); flint_printf("\n"); + flint_printf("product:\n"); nmod_poly_print(product); flint_printf("\n"); + abort(); + } + + nmod_poly_clear(product); + nmod_poly_clear(q); + nmod_poly_clear(r); + nmod_poly_clear(poly1); + nmod_poly_clear(poly); + nmod_poly_factor_clear(res); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly_factor/test/t-factor_squarefree.c b/external/flint-2.4.3/nmod_poly_factor/test/t-factor_squarefree.c new file mode 100644 index 0000000..0c04695 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_factor/test/t-factor_squarefree.c @@ -0,0 +1,140 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 David Howden + Copyright (C) 2007, 2008, 2009, 2010 William Hart + Copyright (C) 2008 Richard Howell-Peak + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int iter; + FLINT_TEST_INIT(state); + + + flint_printf("factor_squarefree...."); + fflush(stdout); + + for (iter = 0; iter < 30 * flint_test_multiplier(); iter++) + { + int result = 1; + nmod_poly_t pol1, poly, quot, rem; + nmod_poly_factor_t res; + mp_limb_t modulus; + slong exp[5], prod1; + slong length, i, j, num; + + modulus = n_randtest_prime(state, 0); + + nmod_poly_init(pol1, modulus); + nmod_poly_init(poly, modulus); + nmod_poly_init(quot, modulus); + nmod_poly_init(rem, modulus); + + nmod_poly_zero(pol1); + nmod_poly_set_coeff_ui(pol1, 0, 1); + + length = n_randint(state, 7) + 2; + + do + { + nmod_poly_randtest(poly, state, length); + if(!nmod_poly_is_zero(poly)) + nmod_poly_make_monic(poly, poly); + } + while ((!nmod_poly_is_irreducible(poly)) || (poly->length < 2)); + exp[0] = n_randprime(state, 5, 0); + + prod1 = exp[0]; + for (i = 0; i < exp[0]; i++) + nmod_poly_mul(pol1, pol1, poly); + + num = n_randint(state, 5) + 1; + for (i = 1; i < num; i++) + { + do + { + length = n_randint(state, 7) + 2; + nmod_poly_randtest(poly, state, length); + if (poly->length) + { + nmod_poly_make_monic(poly, poly); + nmod_poly_divrem(quot, rem, pol1, poly); + } + } + while ((!nmod_poly_is_irreducible(poly)) || + (poly->length < 2) || (rem->length == 0)); + + do exp[i] = n_randprime(state, 5, 0); + while (prod1 % exp[i] == 0); + + prod1 *= exp[i]; + for (j = 0; j < exp[i]; j++) + nmod_poly_mul(pol1, pol1, poly); + } + + nmod_poly_factor_init(res); + nmod_poly_factor_squarefree(res, pol1); + + result &= (res->num == num); + if (result) + { + ulong prod2 = 1; + for (i = 0; i < num; i++) + prod2 *= res->exp[i]; + result &= (prod1 == prod2); + } + + if (!result) + { + flint_printf("Error: exp don't match. Modulus = %wu\n", modulus); + for (i = 0; i < res->num; i++) + flint_printf("%wd ", res->exp[i]); + flint_printf("\n"); + for (i = 0; i < num; i++) + flint_printf("%wd ", exp[i]); + flint_printf("\n"); + abort(); + } + + nmod_poly_clear(quot); + nmod_poly_clear(rem); + nmod_poly_clear(pol1); + nmod_poly_clear(poly); + nmod_poly_factor_clear(res); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly_factor/test/t-is_irreducible.c b/external/flint-2.4.3/nmod_poly_factor/test/t-is_irreducible.c new file mode 100644 index 0000000..c50105d --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_factor/test/t-is_irreducible.c @@ -0,0 +1,109 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int iter; + FLINT_TEST_INIT(state); + + + flint_printf("is_irreducible...."); + fflush(stdout); + + for (iter = 0; iter < 200 * flint_test_multiplier(); iter++) + { + nmod_poly_t poly, poly2, poly3; + nmod_poly_factor_t factors; + mp_limb_t modulus; + slong length, length2; + int result = 1; + + modulus = n_randtest_prime(state, 0); + + nmod_poly_init(poly, modulus); + nmod_poly_init(poly2, modulus); + nmod_poly_init(poly3, modulus); + + length = n_randint(state, 10) + 2; + + do + { + nmod_poly_randtest(poly, state, length); + if(!nmod_poly_is_zero(poly)) + nmod_poly_make_monic(poly, poly); + } + while ((!nmod_poly_is_irreducible(poly)) || (poly->length < 2)); + + nmod_poly_factor_init(factors); + nmod_poly_factor_berlekamp(factors, poly); + result &= (factors->num == 1); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("Irreducible polynomial should not have non-trivial factors!\n"); + flint_printf("poly = "), nmod_poly_print(poly), flint_printf("\n"); + abort(); + } + nmod_poly_factor_clear(factors); + + length2 = n_randint(state, 10) + 2; + + do + { + nmod_poly_randtest(poly2, state, length2); + if(!nmod_poly_is_zero(poly2)) + nmod_poly_make_monic(poly2, poly2); + } + while ((!nmod_poly_is_irreducible(poly2)) || (poly2->length < 2)); + + nmod_poly_mul(poly3, poly, poly2); + + result &= !nmod_poly_is_irreducible(poly3); + if (!result) + { + flint_printf("Error: reducible polynomial declared irreducible!\n"); + nmod_poly_print(poly3); flint_printf("\n"); + abort(); + } + + nmod_poly_clear(poly); + nmod_poly_clear(poly2); + nmod_poly_clear(poly3); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly_factor/test/t-is_irreducible_ddf.c b/external/flint-2.4.3/nmod_poly_factor/test/t-is_irreducible_ddf.c new file mode 100644 index 0000000..b677fe6 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_factor/test/t-is_irreducible_ddf.c @@ -0,0 +1,115 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + Copyright (C) 2013 Martin Lee + +******************************************************************************/ + +#undef ulong +#define ulong ulongxx/* interferes with system includes */ + +#include +#include + +#undef ulong + +#include + +#define ulong mp_limb_t + +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int iter; + FLINT_TEST_INIT(state); + + + flint_printf("is_irreducible_ddf...."); + fflush(stdout); + + for (iter = 0; iter < 200 * flint_test_multiplier(); iter++) + { + nmod_poly_t poly, poly2, poly3; + mp_limb_t modulus; + slong length, length2; + int result = 1; + + modulus = n_randtest_prime(state, 0); + + nmod_poly_init(poly, modulus); + nmod_poly_init(poly2, modulus); + nmod_poly_init(poly3, modulus); + + length = n_randint(state, 10) + 2; + + do + { + nmod_poly_randtest(poly, state, length); + if(!nmod_poly_is_zero(poly)) + nmod_poly_make_monic(poly, poly); + } + while ((poly->length < 2)); + + result &= (nmod_poly_is_irreducible_rabin (poly) == nmod_poly_is_irreducible_ddf (poly)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("result of is_irreducible and is_irreducible_ddf does not coincide\n"); + flint_printf("poly = "), nmod_poly_print(poly), flint_printf("\n"); + abort(); + } + + length2 = n_randint(state, 10) + 2; + + do + { + nmod_poly_randtest(poly2, state, length2); + if(!nmod_poly_is_zero(poly2)) + nmod_poly_make_monic(poly2, poly2); + } + while ((!nmod_poly_is_irreducible_rabin(poly2)) || (poly2->length < 2)); + + nmod_poly_mul(poly3, poly, poly2); + + result &= !nmod_poly_is_irreducible_ddf(poly3); + if (!result) + { + flint_printf("Error: reducible polynomial declared irreducible!\n"); + nmod_poly_print(poly3); flint_printf("\n"); + abort(); + } + + nmod_poly_clear(poly); + nmod_poly_clear(poly2); + nmod_poly_clear(poly3); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly_factor/test/t-is_irreducible_rabin.c b/external/flint-2.4.3/nmod_poly_factor/test/t-is_irreducible_rabin.c new file mode 100644 index 0000000..8d4412b --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_factor/test/t-is_irreducible_rabin.c @@ -0,0 +1,118 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#undef ulong +#define ulong ulongxx/* interferes with system includes */ + +#include +#include + +#undef ulong + +#include + +#define ulong mp_limb_t + +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int iter; + FLINT_TEST_INIT(state); + + + flint_printf("is_irreducible_rabin...."); + fflush(stdout); + + for (iter = 0; iter < 200 * flint_test_multiplier(); iter++) + { + nmod_poly_t poly, poly2, poly3; + nmod_poly_factor_t factors; + mp_limb_t modulus; + slong length, length2; + int result = 1; + + modulus = n_randtest_prime(state, 0); + + nmod_poly_init(poly, modulus); + nmod_poly_init(poly2, modulus); + nmod_poly_init(poly3, modulus); + + length = n_randint(state, 10) + 2; + + do + { + nmod_poly_randtest(poly, state, length); + if(!nmod_poly_is_zero(poly)) + nmod_poly_make_monic(poly, poly); + } + while ((!nmod_poly_is_irreducible_rabin(poly)) || (poly->length < 2)); + + nmod_poly_factor_init(factors); + nmod_poly_factor_berlekamp(factors, poly); + result &= (factors->num == 1); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("Irreducible polynomial should not have non-trivial factors!\n"); + flint_printf("poly = "), nmod_poly_print(poly), flint_printf("\n"); + abort(); + } + nmod_poly_factor_clear(factors); + + length2 = n_randint(state, 10) + 2; + + do + { + nmod_poly_randtest(poly2, state, length2); + if(!nmod_poly_is_zero(poly2)) + nmod_poly_make_monic(poly2, poly2); + } + while ((!nmod_poly_is_irreducible_rabin(poly2)) || (poly2->length < 2)); + + nmod_poly_mul(poly3, poly, poly2); + + result &= !nmod_poly_is_irreducible_rabin(poly3); + if (!result) + { + flint_printf("Error: reducible polynomial declared irreducible!\n"); + nmod_poly_print(poly3); flint_printf("\n"); + abort(); + } + + nmod_poly_clear(poly); + nmod_poly_clear(poly2); + nmod_poly_clear(poly3); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly_factor/test/t-is_squarefree.c b/external/flint-2.4.3/nmod_poly_factor/test/t-is_squarefree.c new file mode 100644 index 0000000..5fc2508 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_factor/test/t-is_squarefree.c @@ -0,0 +1,106 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "ulong_extras.h" + +int +main(void) +{ + int iter; + FLINT_TEST_INIT(state); + + + flint_printf("is_squarefree...."); + fflush(stdout); + + for (iter = 0; iter < 200 * flint_test_multiplier(); iter++) + { + nmod_poly_t poly, Q, R, t; + mp_limb_t modulus; + slong i, num_factors, exp, max_exp; + int v, result; + + modulus = n_randtest_prime(state, 0); + + nmod_poly_init(poly, modulus); + nmod_poly_init(t, modulus); + nmod_poly_init(Q, modulus); + nmod_poly_init(R, modulus); + + nmod_poly_set_coeff_ui(poly, 0, n_randint(state, modulus)); + num_factors = n_randint(state, 5); + + max_exp = 0; + for (i = 0; i < num_factors; i++) + { + do { + nmod_poly_randtest(t, state, n_randint(state, 10)); + } while (!nmod_poly_is_irreducible(t) || + (nmod_poly_length(t) < 2)); + + exp = n_randint(state, 4) + 1; + if (n_randint(state, 2) == 0) + exp = 1; + + nmod_poly_divrem(Q, R, poly, t); + if (!nmod_poly_is_zero(R)) + { + nmod_poly_pow(t, t, exp); + nmod_poly_mul(poly, poly, t); + max_exp = FLINT_MAX(exp, max_exp); + } + } + + v = nmod_poly_is_squarefree(poly); + + if (v == 1) + result = (max_exp <= 1 && !nmod_poly_is_zero(poly)); + else + result = (max_exp > 1 || nmod_poly_is_zero(poly)); + + if (!result) + { + flint_printf("FAIL: %wu, %wd, %d\n", modulus, max_exp, v); + nmod_poly_print(poly); flint_printf("\n"); + abort(); + } + + nmod_poly_clear(poly); + nmod_poly_clear(t); + nmod_poly_clear(Q); + nmod_poly_clear(R); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly_mat.h b/external/flint-2.4.3/nmod_poly_mat.h new file mode 100644 index 0000000..e9def4b --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat.h @@ -0,0 +1,227 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#ifndef NMOD_POLY_MAT_H +#define NMOD_POLY_MAT_H + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "nmod_mat.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/* Types *********************************************************************/ + +typedef struct +{ + nmod_poly_struct * entries; + slong r; + slong c; + nmod_poly_struct ** rows; + mp_limb_t modulus; +} nmod_poly_mat_struct; + +typedef nmod_poly_mat_struct nmod_poly_mat_t[1]; + +#define nmod_poly_mat_entry(mat,i,j) ((mat)->rows[(i)] + (j)) + +/* Memory management *********************************************************/ + +void nmod_poly_mat_init(nmod_poly_mat_t mat, slong rows, slong cols, mp_limb_t n); + +void nmod_poly_mat_init_set(nmod_poly_mat_t mat, const nmod_poly_mat_t src); + +void nmod_poly_mat_swap(nmod_poly_mat_t mat1, nmod_poly_mat_t mat2); + +void nmod_poly_mat_set(nmod_poly_mat_t mat1, const nmod_poly_mat_t mat2); + +void nmod_poly_mat_clear(nmod_poly_mat_t mat); + +/* Basic properties **********************************************************/ + +static __inline__ slong +nmod_poly_mat_nrows(const nmod_poly_mat_t mat) +{ + return mat->r; +} + +static __inline__ slong +nmod_poly_mat_ncols(const nmod_poly_mat_t mat) +{ + return mat->c; +} + +static __inline__ mp_limb_t +nmod_poly_mat_modulus(const nmod_poly_mat_t mat) +{ + return mat->modulus; +} + +/* Comparison ****************************************************************/ + +int nmod_poly_mat_equal(const nmod_poly_mat_t mat1, + const nmod_poly_mat_t mat2); + +int nmod_poly_mat_is_zero(const nmod_poly_mat_t mat); + +int nmod_poly_mat_is_one(const nmod_poly_mat_t mat); + +static __inline__ int +nmod_poly_mat_is_empty(const nmod_poly_mat_t mat) +{ + return (mat->r == 0) || (mat->c == 0); +} + +static __inline__ int +nmod_poly_mat_is_square(const nmod_poly_mat_t mat) +{ + return (mat->r == mat->c); +} + +/* Standard matrices *********************************************************/ + +void nmod_poly_mat_zero(nmod_poly_mat_t mat); + +void nmod_poly_mat_one(nmod_poly_mat_t mat); + +/* Random matrices ***********************************************************/ + +void nmod_poly_mat_randtest(nmod_poly_mat_t mat, flint_rand_t state, + slong len); + +void nmod_poly_mat_randtest_sparse(nmod_poly_mat_t A, flint_rand_t state, + slong len, float density); + +/* Input and output **********************************************************/ + +void nmod_poly_mat_print(const nmod_poly_mat_t mat, const char * x); + +/* Norms *********************************************************************/ + +slong nmod_poly_mat_max_length(const nmod_poly_mat_t A); + +/* Scalar arithmetic *********************************************************/ + +void nmod_poly_mat_scalar_mul_nmod_poly(nmod_poly_mat_t B, + const nmod_poly_mat_t A, const nmod_poly_t c); + +void nmod_poly_mat_scalar_mul_nmod(nmod_poly_mat_t B, + const nmod_poly_mat_t A, mp_limb_t c); + +/* Matrix arithmetic *********************************************************/ + +void nmod_poly_mat_add(nmod_poly_mat_t C, const nmod_poly_mat_t A, + const nmod_poly_mat_t B); + +void nmod_poly_mat_sub(nmod_poly_mat_t C, const nmod_poly_mat_t A, + const nmod_poly_mat_t B); + +void nmod_poly_mat_neg(nmod_poly_mat_t B, const nmod_poly_mat_t A); + +void nmod_poly_mat_mul(nmod_poly_mat_t C, const nmod_poly_mat_t A, + const nmod_poly_mat_t B); + +void nmod_poly_mat_mul_interpolate(nmod_poly_mat_t C, const nmod_poly_mat_t A, + const nmod_poly_mat_t B); + +void nmod_poly_mat_mul_classical(nmod_poly_mat_t C, const nmod_poly_mat_t A, + const nmod_poly_mat_t B); + +void nmod_poly_mat_mul_KS(nmod_poly_mat_t C, const nmod_poly_mat_t A, + const nmod_poly_mat_t B); + +void nmod_poly_mat_sqr(nmod_poly_mat_t B, const nmod_poly_mat_t A); + +void nmod_poly_mat_sqr_classical(nmod_poly_mat_t B, const nmod_poly_mat_t A); + +void nmod_poly_mat_sqr_KS(nmod_poly_mat_t B, const nmod_poly_mat_t A); + +void nmod_poly_mat_sqr_interpolate(nmod_poly_mat_t B, const nmod_poly_mat_t A); + +void nmod_poly_mat_pow(nmod_poly_mat_t B, const nmod_poly_mat_t A, ulong exp); + +/* Evaluation ****************************************************************/ + +void nmod_poly_mat_evaluate_nmod(nmod_mat_t B, const nmod_poly_mat_t A, mp_limb_t x); + +/* Row reduction *************************************************************/ + +slong nmod_poly_mat_find_pivot_any(const nmod_poly_mat_t mat, + slong start_row, slong end_row, slong c); + +slong nmod_poly_mat_find_pivot_partial(const nmod_poly_mat_t mat, + slong start_row, slong end_row, slong c); + +slong nmod_poly_mat_fflu(nmod_poly_mat_t B, nmod_poly_t den, slong * perm, + const nmod_poly_mat_t A, int rank_check); + +slong nmod_poly_mat_rref(nmod_poly_mat_t B, nmod_poly_t den, + const nmod_poly_mat_t A); + +/* Trace *********************************************************************/ + +void nmod_poly_mat_trace(nmod_poly_t trace, const nmod_poly_mat_t mat); + +/* Determinant and rank ******************************************************/ + +void nmod_poly_mat_det(nmod_poly_t det, const nmod_poly_mat_t A); + +void nmod_poly_mat_det_fflu(nmod_poly_t det, const nmod_poly_mat_t A); + +void nmod_poly_mat_det_interpolate(nmod_poly_t det, const nmod_poly_mat_t A); + +slong nmod_poly_mat_rank(const nmod_poly_mat_t A); + +/* Inverse *******************************************************************/ + +int nmod_poly_mat_inv(nmod_poly_mat_t Ainv, nmod_poly_t den, + const nmod_poly_mat_t A); + +/* Nullspace *****************************************************************/ + +slong nmod_poly_mat_nullspace(nmod_poly_mat_t res, const nmod_poly_mat_t mat); + +/* Solving *******************************************************************/ + +int nmod_poly_mat_solve(nmod_poly_mat_t X, nmod_poly_t den, + const nmod_poly_mat_t A, const nmod_poly_mat_t B); + +int nmod_poly_mat_solve_fflu(nmod_poly_mat_t X, nmod_poly_t den, + const nmod_poly_mat_t A, const nmod_poly_mat_t B); + +void nmod_poly_mat_solve_fflu_precomp(nmod_poly_mat_t X, + const slong * perm, + const nmod_poly_mat_t FFLU, const nmod_poly_mat_t B); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/flint-2.4.3/nmod_poly_mat/add.c b/external/flint-2.4.3/nmod_poly_mat/add.c new file mode 100644 index 0000000..e210756 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/add.c @@ -0,0 +1,41 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "flint.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" + +void +nmod_poly_mat_add(nmod_poly_mat_t C, + const nmod_poly_mat_t A, const nmod_poly_mat_t B) +{ + slong i, j; + + for (i = 0; i < A->r; i++) + for (j = 0; j < A->c; j++) + nmod_poly_add(nmod_poly_mat_entry(C, i, j), + nmod_poly_mat_entry(A, i, j), + nmod_poly_mat_entry(B, i, j)); +} diff --git a/external/flint-2.4.3/nmod_poly_mat/clear.c b/external/flint-2.4.3/nmod_poly_mat/clear.c new file mode 100644 index 0000000..c032f94 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/clear.c @@ -0,0 +1,43 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "flint.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" + +void +nmod_poly_mat_clear(nmod_poly_mat_t A) +{ + if (A->entries) + { + slong i; + + for (i = 0; i < A->r * A->c; i++) + nmod_poly_clear(A->entries + i); + + flint_free(A->entries); + flint_free(A->rows); + } +} diff --git a/external/flint-2.4.3/nmod_poly_mat/det.c b/external/flint-2.4.3/nmod_poly_mat/det.c new file mode 100644 index 0000000..ce890f1 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/det.c @@ -0,0 +1,62 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "flint.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" + +void +nmod_poly_mat_det(nmod_poly_t det, const nmod_poly_mat_t A) +{ + slong n = A->r; + + if (n == 0) + { + nmod_poly_one(det); + } + else if (n == 1) + { + nmod_poly_set(det, nmod_poly_mat_entry(A, 0, 0)); + } + else if (n == 2) + { + nmod_poly_t tmp; + nmod_poly_init(tmp, nmod_poly_mat_modulus(A)); + nmod_poly_mul(det, nmod_poly_mat_entry(A, 0, 0), + nmod_poly_mat_entry(A, 1, 1)); + nmod_poly_mul(tmp, nmod_poly_mat_entry(A, 0, 1), + nmod_poly_mat_entry(A, 1, 0)); + nmod_poly_sub(det, det, tmp); + nmod_poly_clear(tmp); + } + else if (n < 15) /* should be entry sensitive too */ + { + nmod_poly_mat_det_fflu(det, A); + } + else + { + nmod_poly_mat_det_interpolate(det, A); + } +} diff --git a/external/flint-2.4.3/nmod_poly_mat/det_fflu.c b/external/flint-2.4.3/nmod_poly_mat/det_fflu.c new file mode 100644 index 0000000..b2ba37c --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/det_fflu.c @@ -0,0 +1,52 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "flint.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" +#include "perm.h" + +void +nmod_poly_mat_det_fflu(nmod_poly_t det, const nmod_poly_mat_t A) +{ + slong n = nmod_poly_mat_nrows(A); + + if (n == 0) + nmod_poly_one(det); + else + { + nmod_poly_mat_t tmp; + slong * perm; + nmod_poly_mat_init_set(tmp, A); + perm = _perm_init(n); + + nmod_poly_mat_fflu(tmp, det, perm, tmp, 1); + if (_perm_parity(perm, n)) + nmod_poly_neg(det, det); + + _perm_clear(perm); + nmod_poly_mat_clear(tmp); + } +} diff --git a/external/flint-2.4.3/nmod_poly_mat/det_interpolate.c b/external/flint-2.4.3/nmod_poly_mat/det_interpolate.c new file mode 100644 index 0000000..29d3319 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/det_interpolate.c @@ -0,0 +1,82 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "nmod_vec.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" + +void +nmod_poly_mat_det_interpolate(nmod_poly_t det, const nmod_poly_mat_t A) +{ + slong i, l, n, len; + + nmod_mat_t X; + mp_ptr x, d; + + n = A->r; + + if (n == 0) + { + nmod_poly_one(det); + return; + } + + l = nmod_poly_mat_max_length(A); + + if (l == 0) + { + nmod_poly_zero(det); + return; + } + + /* Bound degree based on Laplace expansion */ + len = n*(l - 1) + 1; + + /* Not enough points to interpolate */ + if (len > nmod_poly_mat_modulus(A)) + { + nmod_poly_mat_det_fflu(det, A); + return; + } + + x = _nmod_vec_init(len); + d = _nmod_vec_init(len); + nmod_mat_init(X, n, n, nmod_poly_mat_modulus(A)); + + for (i = 0; i < len; i++) + { + x[i] = i; + nmod_poly_mat_evaluate_nmod(X, A, x[i]); + d[i] = nmod_mat_det(X); + } + + nmod_poly_interpolate_nmod_vec(det, x, d, len); + + _nmod_vec_clear(x); + _nmod_vec_clear(d); + nmod_mat_clear(X); +} diff --git a/external/flint-2.4.3/nmod_poly_mat/doc/nmod_poly_mat.txt b/external/flint-2.4.3/nmod_poly_mat/doc/nmod_poly_mat.txt new file mode 100644 index 0000000..d621920 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/doc/nmod_poly_mat.txt @@ -0,0 +1,471 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + + +******************************************************************************* + + Memory management + +******************************************************************************* + +void nmod_poly_mat_init(nmod_poly_mat_t mat, slong rows, slong cols, mp_limb_t n) + + Initialises a matrix with the given number of rows and columns for use. + The modulus is set to $n$. + +void nmod_poly_mat_init_set(nmod_poly_mat_t mat, const nmod_poly_mat_t src) + + Initialises a matrix \code{mat} of the same dimensions and modulus + as \code{src}, and sets it to a copy of \code{src}. + +void nmod_poly_mat_clear(nmod_poly_mat_t mat) + + Frees all memory associated with the matrix. The matrix must be + reinitialised if it is to be used again. + +******************************************************************************* + + Basic properties + +******************************************************************************* + +slong nmod_poly_mat_nrows(const nmod_poly_mat_t mat) + + Returns the number of rows in \code{mat}. + +slong nmod_poly_mat_ncols(const nmod_poly_mat_t mat) + + Returns the number of columns in \code{mat}. + +mp_limb_t nmod_poly_mat_modulus(const nmod_poly_mat_t mat) + + Returns the modulus of \code{mat}. + +******************************************************************************* + + Basic assignment and manipulation + +******************************************************************************* + +MACRO nmod_poly_mat_entry(mat,i,j) + + Gives a reference to the entry at row \code{i} and column \code{j}. + The reference can be passed as an input or output variable to any + \code{nmod_poly} function for direct manipulation of the matrix element. + No bounds checking is performed. + +void nmod_poly_mat_set(nmod_poly_mat_t mat1, const nmod_poly_mat_t mat2) + + Sets \code{mat1} to a copy of \code{mat2}. + +void nmod_poly_mat_swap(nmod_poly_mat_t mat1, nmod_poly_mat_t mat2) + + Swaps \code{mat1} and \code{mat2} efficiently. + + +******************************************************************************* + + Input and output + +******************************************************************************* + +void nmod_poly_mat_print(const nmod_poly_mat_t mat, const char * x) + + Prints the matrix \code{mat} to standard output, using the + variable \code{x}. + +******************************************************************************* + + Random matrix generation + +******************************************************************************* + +void nmod_poly_mat_randtest(nmod_poly_mat_t mat, flint_rand_t state, slong len) + + This is equivalent to applying \code{nmod_poly_randtest} to all entries + in the matrix. + +void nmod_poly_mat_randtest_sparse(nmod_poly_mat_t A, flint_rand_t state, + slong len, float density) + + Creates a random matrix with the amount of nonzero entries given + approximately by the \code{density} variable, which should be a fraction + between 0 (most sparse) and 1 (most dense). + + The nonzero entries will have random lengths between 1 and \code{len}. + +******************************************************************************* + + Special matrices + +******************************************************************************* + +void nmod_poly_mat_zero(nmod_poly_mat_t mat) + + Sets \code{mat} to the zero matrix. + +void nmod_poly_mat_one(nmod_poly_mat_t mat) + + Sets \code{mat} to the unit or identity matrix of given shape, + having the element 1 on the main diagonal and zeros elsewhere. + If \code{mat} is nonsquare, it is set to the truncation of a unit matrix. + +******************************************************************************* + + Basic comparison and properties + +******************************************************************************* + +int nmod_poly_mat_equal(const nmod_poly_mat_t mat1, const nmod_poly_mat_t mat2) + + Returns nonzero if \code{mat1} and \code{mat2} have the same shape and + all their entries agree, and returns zero otherwise. + +int nmod_poly_mat_is_zero(const nmod_poly_mat_t mat) + + Returns nonzero if all entries in \code{mat} are zero, and returns + zero otherwise. + +int nmod_poly_mat_is_one(const nmod_poly_mat_t mat) + + Returns nonzero if all entry of \code{mat} on the main diagonal + are the constant polynomial 1 and all remaining entries are zero, + and returns zero otherwise. The matrix need not be square. + +int nmod_poly_mat_is_empty(const nmod_poly_mat_t mat) + + Returns a non-zero value if the number of rows or the number of + columns in \code{mat} is zero, and otherwise returns + zero. + +int nmod_poly_mat_is_square(const nmod_poly_mat_t mat) + + Returns a non-zero value if the number of rows is equal to the + number of columns in \code{mat}, and otherwise returns zero. + + +******************************************************************************* + + Norms + +******************************************************************************* + +slong nmod_poly_mat_max_length(const nmod_poly_mat_t A) + + Returns the maximum polynomial length among all the entries in \code{A}. + + +******************************************************************************* + + Evaluation + +******************************************************************************* + +void nmod_poly_mat_evaluate_nmod(nmod_mat_t B, const nmod_poly_mat_t A, + mp_limb_t x) + + Sets the \code{nmod_mat_t} \code{B} to \code{A} evaluated entrywise + at the point \code{x}. + + +******************************************************************************* + + Arithmetic + +******************************************************************************* + +void nmod_poly_mat_scalar_mul_nmod_poly(nmod_poly_mat_t B, + const nmod_poly_mat_t A, const nmod_poly_t c) + + Sets \code{B} to \code{A} multiplied entrywise by the polynomial \code{c}. + +void nmod_poly_mat_scalar_mul_nmod(nmod_poly_mat_t B, + const nmod_poly_mat_t A, mp_limb_t c) + + Sets \code{B} to \code{A} multiplied entrywise by the coefficient + \code{c}, which is assumed to be reduced modulo the modulus. + +void nmod_poly_mat_add(nmod_poly_mat_t C, const nmod_poly_mat_t A, + const nmod_poly_mat_t B) + + Sets \code{C} to the sum of \code{A} and \code{B}. + All matrices must have the same shape. Aliasing is allowed. + +void nmod_poly_mat_sub(nmod_poly_mat_t C, const nmod_poly_mat_t A, + const nmod_poly_mat_t B) + + Sets \code{C} to the sum of \code{A} and \code{B}. + All matrices must have the same shape. Aliasing is allowed. + +void nmod_poly_mat_neg(nmod_poly_mat_t B, const nmod_poly_mat_t A) + + Sets \code{B} to the negation of \code{A}. + The matrices must have the same shape. Aliasing is allowed. + +void nmod_poly_mat_mul(nmod_poly_mat_t C, const nmod_poly_mat_t A, + const nmod_poly_mat_t B) + + Sets \code{C} to the matrix product of \code{A} and \code{B}. + The matrices must have compatible dimensions for matrix multiplication. + Aliasing is allowed. This function automatically chooses between + classical, KS and evaluation-interpolation multiplication. + +void nmod_poly_mat_mul_classical(nmod_poly_mat_t C, const nmod_poly_mat_t A, + const nmod_poly_mat_t B) + + Sets \code{C} to the matrix product of \code{A} and \code{B}, + computed using the classical algorithm. The matrices must have + compatible dimensions for matrix multiplication. Aliasing is allowed. + +void nmod_poly_mat_mul_KS(nmod_poly_mat_t C, const nmod_poly_mat_t A, + const nmod_poly_mat_t B) + + Sets \code{C} to the matrix product of \code{A} and \code{B}, + computed using Kronecker segmentation. The matrices must have + compatible dimensions for matrix multiplication. Aliasing is allowed. + +void nmod_poly_mat_mul_interpolate(nmod_poly_mat_t C, const nmod_poly_mat_t A, + const nmod_poly_mat_t B) + + Sets \code{C} to the matrix product of \code{A} and \code{B}, + computed through evaluation and interpolation. The matrices must have + compatible dimensions for matrix multiplication. For interpolation + to be well-defined, we require that the modulus is a prime at least as + large as $m + n - 1$ where $m$ and $n$ are the maximum lengths of + polynomials in the input matrices. Aliasing is allowed. + +void nmod_poly_mat_sqr(nmod_poly_mat_t B, const nmod_poly_mat_t A) + + Sets \code{B} to the square of \code{A}, which must be a square matrix. + Aliasing is allowed. This function automatically chooses between + classical and KS squaring. + +void nmod_poly_mat_sqr_classical(nmod_poly_mat_t B, const nmod_poly_mat_t A) + + Sets \code{B} to the square of \code{A}, which must be a square matrix. + Aliasing is allowed. This function uses direct formulas for very small + matrices, and otherwise classical matrix multiplication. + +void nmod_poly_mat_sqr_KS(nmod_poly_mat_t B, const nmod_poly_mat_t A) + + Sets \code{B} to the square of \code{A}, which must be a square matrix. + Aliasing is allowed. This function uses Kronecker segmentation. + +void nmod_poly_mat_sqr_interpolate(nmod_poly_mat_t B, const nmod_poly_mat_t A) + + Sets \code{B} to the square of \code{A}, which must be a square matrix, + computed through evaluation and interpolation. For interpolation + to be well-defined, we require that the modulus is a prime at least as + large as $2n - 1$ where $n$ is the maximum length of + polynomials in the input matrix. Aliasing is allowed. + +void nmod_poly_mat_pow(nmod_poly_mat_t B, const nmod_poly_mat_t A, ulong exp) + + Sets \code{B} to \code{A} raised to the power \code{exp}, where \code{A} + is a square matrix. Uses exponentiation by squaring. Aliasing is allowed. + +******************************************************************************* + + Row reduction + +******************************************************************************* + +slong nmod_poly_mat_find_pivot_any(const nmod_poly_mat_t mat, + slong start_row, slong end_row, slong c) + + Attempts to find a pivot entry for row reduction. + Returns a row index $r$ between \code{start_row} (inclusive) and + \code{stop_row} (exclusive) such that column $c$ in \code{mat} has + a nonzero entry on row $r$, or returns -1 if no such entry exists. + + This implementation simply chooses the first nonzero entry from + it encounters. This is likely to be a nearly optimal choice if all + entries in the matrix have roughly the same size, but can lead to + unnecessary coefficient growth if the entries vary in size. + +slong nmod_poly_mat_find_pivot_partial(const nmod_poly_mat_t mat, + slong start_row, slong end_row, slong c) + + Attempts to find a pivot entry for row reduction. + Returns a row index $r$ between \code{start_row} (inclusive) and + \code{stop_row} (exclusive) such that column $c$ in \code{mat} has + a nonzero entry on row $r$, or returns -1 if no such entry exists. + + This implementation searches all the rows in the column and + chooses the nonzero entry of smallest degree. This heuristic + typically reduces coefficient growth when the matrix entries + vary in size. + +slong nmod_poly_mat_fflu(nmod_poly_mat_t B, nmod_poly_t den, slong * perm, + const nmod_poly_mat_t A, int rank_check) + + Uses fraction-free Gaussian elimination to set (\code{B}, \code{den}) to a + fraction-free LU decomposition of \code{A} and returns the + rank of \code{A}. Aliasing of \code{A} and \code{B} is allowed. + + Pivot elements are chosen with \code{nmod_poly_mat_find_pivot_partial}. + If \code{perm} is non-\code{NULL}, the permutation of + rows in the matrix will also be applied to \code{perm}. + + If \code{rank_check} is set, the function aborts and returns 0 if the + matrix is detected not to have full rank without completing the + elimination. + + The denominator \code{den} is set to $\pm \operatorname{det}(A)$, where + the sign is decided by the parity of the permutation. Note that the + determinant is not generally the minimal denominator. + +slong nmod_poly_mat_rref(nmod_poly_mat_t B, nmod_poly_t den, + const nmod_poly_mat_t A) + + Sets (\code{B}, \code{den}) to the reduced row echelon form of \code{A} + and returns the rank of \code{A}. + Aliasing of \code{A} and \code{B} is allowed. + + The denominator \code{den} is set to $\pm \operatorname{det}(A)$. + Note that the determinant is not generally the minimal denominator. + +******************************************************************************* + + Trace + +******************************************************************************* + +void nmod_poly_mat_trace(nmod_poly_t trace, const nmod_poly_mat_t mat) + + Computes the trace of the matrix, i.e. the sum of the entries on + the main diagonal. The matrix is required to be square. + +******************************************************************************* + + Determinant and rank + +******************************************************************************* + +void nmod_poly_mat_det(nmod_poly_t det, const nmod_poly_mat_t A) + + Sets \code{det} to the determinant of the square matrix \code{A}. Uses + a direct formula, fraction-free LU decomposition, or interpolation, + depending on the size of the matrix. + +void nmod_poly_mat_det_fflu(nmod_poly_t det, const nmod_poly_mat_t A) + + Sets \code{det} to the determinant of the square matrix \code{A}. + The determinant is computed by performing a fraction-free LU + decomposition on a copy of \code{A}. + +void nmod_poly_mat_det_interpolate(nmod_poly_t det, const nmod_poly_mat_t A) + + Sets \code{det} to the determinant of the square matrix \code{A}. + The determinant is computed by determing a bound $n$ for its length, + evaluating the matrix at $n$ distinct points, computing the determinant + of each coefficient matrix, and forming the interpolating polynomial. + + If the coefficient ring does not contain $n$ distinct points (that is, + if working over $\mathbb{Z}/p\mathbb{Z}$ where $p < n$), + this function automatically falls back to \code{nmod_poly_mat_det_fflu}. + +slong nmod_poly_mat_rank(const nmod_poly_mat_t A) + + Returns the rank of \code{A}. Performs fraction-free LU decomposition + on a copy of \code{A}. + + +******************************************************************************* + + Inverse + +******************************************************************************* + +int nmod_poly_mat_inv(nmod_poly_mat_t Ainv, nmod_poly_t den, + const nmod_poly_mat_t A) + + Sets (\code{Ainv}, \code{den}) to the inverse matrix of \code{A}. + Returns 1 if \code{A} is nonsingular and 0 if \code{A} is singular. + Aliasing of \code{Ainv} and \code{A} is allowed. + + More precisely, \code{det} will be set to the determinant of \code{A} + and \code{Ainv} will be set to the adjugate matrix of \code{A}. + Note that the determinant is not necessarily the minimal denominator. + + Uses fraction-free LU decomposition, followed by solving for + the identity matrix. + + +******************************************************************************* + + Nullspace + +******************************************************************************* + +slong nmod_poly_mat_nullspace(nmod_poly_mat_t res, const nmod_poly_mat_t mat) + + Computes the right rational nullspace of the matrix \code{mat} and + returns the nullity. + + More precisely, assume that \code{mat} has rank $r$ and nullity $n$. + Then this function sets the first $n$ columns of \code{res} + to linearly independent vectors spanning the nullspace of \code{mat}. + As a result, we always have rank(\code{res}) $= n$, and + \code{mat} $\times$ \code{res} is the zero matrix. + + The computed basis vectors will not generally be in a reduced form. + In general, the polynomials in each column vector in the result + will have a nontrivial common GCD. + +******************************************************************************* + + Solving + +******************************************************************************* + +int nmod_poly_mat_solve(nmod_poly_mat_t X, nmod_poly_t den, + const nmod_poly_mat_t A, const nmod_poly_mat_t B) + + Solves the equation $AX = B$ for nonsingular $A$. More precisely, computes + (\code{X}, \code{den}) such that $AX = B \times \operatorname{den}$. + Returns 1 if $A$ is nonsingular and 0 if $A$ is singular. + The computed denominator will not generally be minimal. + + Uses fraction-free LU decomposition followed by fraction-free + forward and back substitution. + +int nmod_poly_mat_solve_fflu(nmod_poly_mat_t X, nmod_poly_t den, + const nmod_poly_mat_t A, const nmod_poly_mat_t B); + + Solves the equation $AX = B$ for nonsingular $A$. More precisely, computes + (\code{X}, \code{den}) such that $AX = B \times \operatorname{den}$. + Returns 1 if $A$ is nonsingular and 0 if $A$ is singular. + The computed denominator will not generally be minimal. + + Uses fraction-free LU decomposition followed by fraction-free + forward and back substitution. + +void nmod_poly_mat_solve_fflu_precomp(nmod_poly_mat_t X, + const slong * perm, + const nmod_poly_mat_t FFLU, const nmod_poly_mat_t B); + + Performs fraction-free forward and back substitution given a precomputed + fraction-free LU decomposition and corresponding permutation. diff --git a/external/flint-2.4.3/nmod_poly_mat/equal.c b/external/flint-2.4.3/nmod_poly_mat/equal.c new file mode 100644 index 0000000..b1fdf98 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/equal.c @@ -0,0 +1,44 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "flint.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" + +int +nmod_poly_mat_equal(const nmod_poly_mat_t A, const nmod_poly_mat_t B) +{ + slong i, j; + + if (A->r != B->r || A->c != B->c) + return 0; + + for (i = 0; i < A->r; i++) + for (j = 0; j < A->c; j++) + if (!nmod_poly_equal(nmod_poly_mat_entry(A, i, j), + nmod_poly_mat_entry(B, i, j))) + return 0; + return 1; +} diff --git a/external/flint-2.4.3/nmod_poly_mat/evaluate_nmod.c b/external/flint-2.4.3/nmod_poly_mat/evaluate_nmod.c new file mode 100644 index 0000000..8c528f2 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/evaluate_nmod.c @@ -0,0 +1,41 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "nmod_mat.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" + +void +nmod_poly_mat_evaluate_nmod(nmod_mat_t B, const nmod_poly_mat_t A, mp_limb_t x) +{ + slong i, j; + + for (i = 0; i < A->r; i++) + for (j = 0; j < A->c; j++) + nmod_mat_entry(B, i, j) = nmod_poly_evaluate_nmod( + nmod_poly_mat_entry(A, i, j), x); +} diff --git a/external/flint-2.4.3/nmod_poly_mat/fflu.c b/external/flint-2.4.3/nmod_poly_mat/fflu.c new file mode 100644 index 0000000..c73982e --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/fflu.c @@ -0,0 +1,112 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "flint.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" + +#define E(j,k) nmod_poly_mat_entry(B,j,k) + +static __inline__ void +nmod_poly_mat_swap_rows(nmod_poly_mat_t mat, slong * perm, slong r, slong s) +{ + if (r != s) + { + nmod_poly_struct * u; + slong t; + + if (perm) + { + t = perm[s]; + perm[s] = perm[r]; + perm[r] = t; + } + + u = mat->rows[s]; + mat->rows[s] = mat->rows[r]; + mat->rows[r] = u; + } +} + +slong +nmod_poly_mat_fflu(nmod_poly_mat_t B, nmod_poly_t den, slong * perm, + const nmod_poly_mat_t A, int rank_check) +{ + nmod_poly_t t; + slong m, n, j, k, rank, r, pivot_row, pivot_col; + + if (nmod_poly_mat_is_empty(A)) + { + nmod_poly_one(den); + return 0; + } + + nmod_poly_mat_set(B, A); + m = B->r; + n = B->c; + rank = pivot_row = pivot_col = 0; + + nmod_poly_init(t, nmod_poly_mat_modulus(A)); + + while (pivot_row < m && pivot_col < n) + { + r = nmod_poly_mat_find_pivot_partial(B, pivot_row, m, pivot_col); + + if (r == -1) + { + if (rank_check) + { + nmod_poly_zero(den); + rank = 0; + break; + } + pivot_col++; + continue; + } + else if (r != pivot_row) + nmod_poly_mat_swap_rows(B, perm, pivot_row, r); + + rank++; + + for (j = pivot_row + 1; j < m; j++) + { + for (k = pivot_col + 1; k < n; k++) + { + nmod_poly_mul(E(j, k), E(j, k), E(pivot_row, pivot_col)); + nmod_poly_mul(t, E(j, pivot_col), E(pivot_row, k)); + nmod_poly_sub(E(j, k), E(j, k), t); + if (pivot_row > 0) + nmod_poly_div(E(j, k), E(j, k), den); + } + } + + nmod_poly_set(den, E(pivot_row, pivot_col)); + pivot_row++; + pivot_col++; + } + + nmod_poly_clear(t); + return rank; +} diff --git a/external/flint-2.4.3/nmod_poly_mat/find_pivot_any.c b/external/flint-2.4.3/nmod_poly_mat/find_pivot_any.c new file mode 100644 index 0000000..5da9c49 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/find_pivot_any.c @@ -0,0 +1,43 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "flint.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" + +slong +nmod_poly_mat_find_pivot_any(const nmod_poly_mat_t mat, + slong start_row, slong end_row, slong c) +{ + slong r; + + for (r = start_row; r < end_row; r++) + { + if (!nmod_poly_is_zero(nmod_poly_mat_entry(mat, r, c))) + return r; + } + + return -1; +} diff --git a/external/flint-2.4.3/nmod_poly_mat/find_pivot_partial.c b/external/flint-2.4.3/nmod_poly_mat/find_pivot_partial.c new file mode 100644 index 0000000..1e18d60 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/find_pivot_partial.c @@ -0,0 +1,56 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "flint.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" + +slong +nmod_poly_mat_find_pivot_partial(const nmod_poly_mat_t mat, + slong start_row, slong end_row, slong c) +{ + slong best_row, best_length, i; + + best_row = start_row; + best_length = nmod_poly_length(nmod_poly_mat_entry(mat, start_row, c)); + + for (i = start_row + 1; i < end_row; i++) + { + slong l; + + l = nmod_poly_length(nmod_poly_mat_entry(mat, i, c)); + + if (l != 0 && (best_length == 0 || l <= best_length)) + { + best_row = i; + best_length = l; + } + } + + if (best_length == 0) + return -1; + + return best_row; +} diff --git a/external/flint-2.4.3/nmod_poly_mat/init.c b/external/flint-2.4.3/nmod_poly_mat/init.c new file mode 100644 index 0000000..c97f5b8 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/init.c @@ -0,0 +1,53 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" + +void +nmod_poly_mat_init(nmod_poly_mat_t A, slong rows, slong cols, mp_limb_t n) +{ + if (rows && cols) + { + slong i; + + A->entries = (nmod_poly_struct *) flint_malloc(rows * cols * sizeof(nmod_poly_struct)); + A->rows = (nmod_poly_struct **) flint_malloc(rows * sizeof(nmod_poly_struct *)); + + for (i = 0; i < rows * cols; i++) + nmod_poly_init(A->entries + i, n); + + for (i = 0; i < rows; i++) + A->rows[i] = A->entries + i * cols; + } + else + A->entries = NULL; + + A->modulus = n; + A->r = rows; + A->c = cols; +} diff --git a/external/flint-2.4.3/nmod_poly_mat/init_set.c b/external/flint-2.4.3/nmod_poly_mat/init_set.c new file mode 100644 index 0000000..87cf1bb --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/init_set.c @@ -0,0 +1,35 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "flint.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" + +void +nmod_poly_mat_init_set(nmod_poly_mat_t A, const nmod_poly_mat_t B) +{ + nmod_poly_mat_init(A, B->r, B->c, nmod_poly_mat_modulus(B)); + nmod_poly_mat_set(A, B); +} diff --git a/external/flint-2.4.3/nmod_poly_mat/inv.c b/external/flint-2.4.3/nmod_poly_mat/inv.c new file mode 100644 index 0000000..5b29de1 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/inv.c @@ -0,0 +1,104 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include "flint.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" +#include "perm.h" + +#define E nmod_poly_mat_entry + +int +nmod_poly_mat_inv(nmod_poly_mat_t Ainv, nmod_poly_t den, + const nmod_poly_mat_t A) +{ + slong n = nmod_poly_mat_nrows(A); + + if (n == 0) + { + nmod_poly_one(den); + return 1; + } + else if (n == 1) + { + nmod_poly_set(den, E(A, 0, 0)); + nmod_poly_one(E(Ainv, 0, 0)); + return !nmod_poly_is_zero(den); + } + else if (n == 2) + { + nmod_poly_mat_det(den, A); + + if (nmod_poly_is_zero(den)) + { + return 0; + } + else if (Ainv == A) + { + nmod_poly_swap(E(A, 0, 0), E(A, 1, 1)); + nmod_poly_neg(E(A, 0, 1), E(A, 0, 1)); + nmod_poly_neg(E(A, 1, 0), E(A, 1, 0)); + return 1; + } + else + { + nmod_poly_set(E(Ainv, 0, 0), E(A, 1, 1)); + nmod_poly_set(E(Ainv, 1, 1), E(A, 0, 0)); + nmod_poly_neg(E(Ainv, 0, 1), E(A, 0, 1)); + nmod_poly_neg(E(Ainv, 1, 0), E(A, 1, 0)); + return 1; + } + } + else + { + nmod_poly_mat_t LU, I; + slong * perm; + int result; + + perm = _perm_init(n); + nmod_poly_mat_init_set(LU, A); + result = (nmod_poly_mat_fflu(LU, den, perm, LU, 1) == n); + + if (result) + { + nmod_poly_mat_init(I, n, n, nmod_poly_mat_modulus(A)); + nmod_poly_mat_one(I); + nmod_poly_mat_solve_fflu_precomp(Ainv, perm, LU, I); + nmod_poly_mat_clear(I); + } + else + nmod_poly_zero(den); + + if (_perm_parity(perm, n)) + { + nmod_poly_mat_neg(Ainv, Ainv); + nmod_poly_neg(den, den); + } + + _perm_clear(perm); + nmod_poly_mat_clear(LU); + return result; + } +} diff --git a/external/flint-2.4.3/nmod_poly_mat/is_one.c b/external/flint-2.4.3/nmod_poly_mat/is_one.c new file mode 100644 index 0000000..764fc28 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/is_one.c @@ -0,0 +1,56 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "flint.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" + +int +nmod_poly_mat_is_one(const nmod_poly_mat_t A) +{ + slong i, j; + + if (A->r == 0 || A->c == 0) + return 1; + + for (i = 0; i < A->r; i++) + { + for (j = 0; j < A->c; j++) + { + if (i == j) + { + if (!nmod_poly_is_one(nmod_poly_mat_entry(A, i, j))) + return 0; + } + else + { + if (!nmod_poly_is_zero(nmod_poly_mat_entry(A, i, j))) + return 0; + } + } + } + + return 1; +} diff --git a/external/flint-2.4.3/nmod_poly_mat/is_zero.c b/external/flint-2.4.3/nmod_poly_mat/is_zero.c new file mode 100644 index 0000000..d2ba893 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/is_zero.c @@ -0,0 +1,44 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "flint.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" + +int +nmod_poly_mat_is_zero(const nmod_poly_mat_t A) +{ + slong i, j; + + if (A->r == 0 || A->c == 0) + return 1; + + for (i = 0; i < A->r; i++) + for (j = 0; j < A->c; j++) + if (!nmod_poly_is_zero(nmod_poly_mat_entry(A, i, j))) + return 0; + + return 1; +} diff --git a/external/flint-2.4.3/nmod_poly_mat/max_length.c b/external/flint-2.4.3/nmod_poly_mat/max_length.c new file mode 100644 index 0000000..7753c22 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/max_length.c @@ -0,0 +1,47 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "flint.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" + +slong +nmod_poly_mat_max_length(const nmod_poly_mat_t A) +{ + slong i, j, len, max; + + max = 0; + + for (i = 0; i < A->r; i++) + { + for (j = 0; j < A->c; j++) + { + len = nmod_poly_length(nmod_poly_mat_entry(A, i, j)); + max = FLINT_MAX(len, max); + } + } + + return max; +} diff --git a/external/flint-2.4.3/nmod_poly_mat/mul.c b/external/flint-2.4.3/nmod_poly_mat/mul.c new file mode 100644 index 0000000..f10d099 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/mul.c @@ -0,0 +1,68 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "flint.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" + +#define KS_MIN_DIM 10 +#define INTERPOLATE_MIN_DIM 60 +#define KS_MAX_LENGTH 128 + +void +nmod_poly_mat_mul(nmod_poly_mat_t C, const nmod_poly_mat_t A, + const nmod_poly_mat_t B) +{ + slong ar, bc, br, dim; + + ar = A->r; + br = B->r; + bc = B->c; + + dim = FLINT_MIN(FLINT_MIN(ar, br), bc); + + if (dim < KS_MIN_DIM) + { + nmod_poly_mat_mul_classical(C, A, B); + } + else + { + slong Alen, Blen; + mp_limb_t mod = nmod_poly_mat_modulus(A); + + Alen = nmod_poly_mat_max_length(A); + Blen = nmod_poly_mat_max_length(B); + + if ((FLINT_BIT_COUNT(mod) > FLINT_BITS / 4) + && (dim > INTERPOLATE_MIN_DIM + n_sqrt(FLINT_MIN(Alen, Blen))) + && (mod >= Alen + Blen - 1) && n_is_prime(mod)) + nmod_poly_mat_mul_interpolate(C, A, B); + + else if (Alen > KS_MAX_LENGTH || Blen > KS_MAX_LENGTH) + nmod_poly_mat_mul_classical(C, A, B); + else + nmod_poly_mat_mul_KS(C, A, B); + } +} diff --git a/external/flint-2.4.3/nmod_poly_mat/mul_KS.c b/external/flint-2.4.3/nmod_poly_mat/mul_KS.c new file mode 100644 index 0000000..698b719 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/mul_KS.c @@ -0,0 +1,80 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" +#include "fmpz.h" +#include "fmpz_mat.h" + +void +nmod_poly_mat_mul_KS(nmod_poly_mat_t C, const nmod_poly_mat_t A, + const nmod_poly_mat_t B) +{ + slong i, j; + slong A_len, B_len; + mp_bitcnt_t bit_size; + + fmpz_mat_t AA, BB, CC; + + if (B->r == 0) + { + nmod_poly_mat_zero(C); + return; + } + + A_len = nmod_poly_mat_max_length(A); + B_len = nmod_poly_mat_max_length(B); + + bit_size = 2 * FLINT_BIT_COUNT(nmod_poly_mat_modulus(A)); + bit_size += FLINT_BIT_COUNT(FLINT_MIN(A_len, B_len)); + bit_size += FLINT_BIT_COUNT(B->r); + + fmpz_mat_init(AA, A->r, A->c); + fmpz_mat_init(BB, B->r, B->c); + fmpz_mat_init(CC, C->r, C->c); + + for (i = 0; i < A->r; i++) + for (j = 0; j < A->c; j++) + nmod_poly_bit_pack(fmpz_mat_entry(AA, i, j), + nmod_poly_mat_entry(A, i, j), bit_size); + + for (i = 0; i < B->r; i++) + for (j = 0; j < B->c; j++) + nmod_poly_bit_pack(fmpz_mat_entry(BB, i, j), + nmod_poly_mat_entry(B, i, j), bit_size); + + fmpz_mat_mul(CC, AA, BB); + + for (i = 0; i < C->r; i++) + for (j = 0; j < C->c; j++) + nmod_poly_bit_unpack(nmod_poly_mat_entry(C, i, j), + fmpz_mat_entry(CC, i, j), bit_size); + + fmpz_mat_clear(AA); + fmpz_mat_clear(BB); + fmpz_mat_clear(CC); +} diff --git a/external/flint-2.4.3/nmod_poly_mat/mul_classical.c b/external/flint-2.4.3/nmod_poly_mat/mul_classical.c new file mode 100644 index 0000000..bd1ee87 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/mul_classical.c @@ -0,0 +1,80 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "flint.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" + +void +nmod_poly_mat_mul_classical(nmod_poly_mat_t C, const nmod_poly_mat_t A, + const nmod_poly_mat_t B) +{ + slong ar, bc, br; + slong i, j, k; + nmod_poly_t t; + + ar = A->r; + br = B->r; + bc = B->c; + + if (br == 0 || ar == 0 || bc == 0) + { + nmod_poly_mat_zero(C); + return; + } + + if (C == A || C == B) + { + nmod_poly_mat_t T; + nmod_poly_mat_init(T, ar, bc, nmod_poly_mat_modulus(A)); + nmod_poly_mat_mul_classical(T, A, B); + nmod_poly_mat_swap(C, T); + nmod_poly_mat_clear(T); + return; + } + + nmod_poly_init(t, nmod_poly_mat_modulus(A)); + + for (i = 0; i < ar; i++) + { + for (j = 0; j < bc; j++) + { + nmod_poly_mul(nmod_poly_mat_entry(C, i, j), + nmod_poly_mat_entry(A, i, 0), + nmod_poly_mat_entry(B, 0, j)); + + for (k = 1; k < br; k++) + { + nmod_poly_mul(t, nmod_poly_mat_entry(A, i, k), + nmod_poly_mat_entry(B, k, j)); + + nmod_poly_add(nmod_poly_mat_entry(C, i, j), + nmod_poly_mat_entry(C, i, j), t); + } + } + } + + nmod_poly_clear(t); +} diff --git a/external/flint-2.4.3/nmod_poly_mat/mul_interpolate.c b/external/flint-2.4.3/nmod_poly_mat/mul_interpolate.c new file mode 100644 index 0000000..3988de5 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/mul_interpolate.c @@ -0,0 +1,157 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 "flint.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" + +void +nmod_poly_mat_mul_interpolate(nmod_poly_mat_t C, const nmod_poly_mat_t A, + const nmod_poly_mat_t B) +{ + slong i, j, k; + slong A_len, B_len, len; + + nmod_mat_t *C_mod, *A_mod, *B_mod; + + mp_ptr xs; + mp_ptr tt, uu; + mp_ptr * tree; + mp_ptr weights; + nmod_t mod; + + if (B->r == 0) + { + nmod_poly_mat_zero(C); + return; + } + + A_len = nmod_poly_mat_max_length(A); + B_len = nmod_poly_mat_max_length(B); + + if (A_len == 0 || B_len == 0) + { + nmod_poly_mat_zero(C); + return; + } + + len = A_len + B_len - 1; + nmod_init(&mod, nmod_poly_mat_modulus(A)); + + if (mod.n < len) + { + flint_printf("Exception (nmod_poly_mat_mul_interpolate). \n" + "Characteristic is too small.\n"); + abort(); + } + + xs = _nmod_vec_init(len); + tt = _nmod_vec_init(len); + uu = _nmod_vec_init(len); + weights = _nmod_vec_init(len); + + A_mod = flint_malloc(sizeof(nmod_mat_t) * len); + B_mod = flint_malloc(sizeof(nmod_mat_t) * len); + C_mod = flint_malloc(sizeof(nmod_mat_t) * len); + + for (i = 0; i < len; i++) + { + xs[i] = i; + nmod_mat_init(A_mod[i], A->r, A->c, mod.n); + nmod_mat_init(B_mod[i], B->r, B->c, mod.n); + nmod_mat_init(C_mod[i], C->r, C->c, mod.n); + } + + tree = _nmod_poly_tree_alloc(len); + _nmod_poly_tree_build(tree, xs, len, mod); + _nmod_poly_interpolation_weights(weights, tree, len, mod); + + for (i = 0; i < A->r; i++) + { + for (j = 0; j < A->c; j++) + { + _nmod_poly_evaluate_nmod_vec_fast_precomp(tt, + nmod_poly_mat_entry(A, i, j)->coeffs, + nmod_poly_mat_entry(A, i, j)->length, + tree, len, mod); + + for (k = 0; k < len; k++) + A_mod[k]->rows[i][j] = tt[k]; + } + } + + for (i = 0; i < B->r; i++) + { + for (j = 0; j < B->c; j++) + { + _nmod_poly_evaluate_nmod_vec_fast_precomp(tt, + nmod_poly_mat_entry(B, i, j)->coeffs, + nmod_poly_mat_entry(B, i, j)->length, + tree, len, mod); + + for (k = 0; k < len; k++) + B_mod[k]->rows[i][j] = tt[k]; + } + } + + for (i = 0; i < len; i++) + nmod_mat_mul(C_mod[i], A_mod[i], B_mod[i]); + + for (i = 0; i < C->r; i++) + { + for (j = 0; j < C->c; j++) + { + nmod_poly_struct * poly; + + for (k = 0; k < len; k++) + tt[k] = C_mod[k]->rows[i][j]; + + poly = nmod_poly_mat_entry(C, i, j); + nmod_poly_fit_length(poly, len); + _nmod_poly_interpolate_nmod_vec_fast_precomp(poly->coeffs, + tt, tree, weights, len, mod); + poly->length = len; + _nmod_poly_normalise(poly); + } + } + + _nmod_poly_tree_free(tree, len); + + for (i = 0; i < len; i++) + { + nmod_mat_clear(A_mod[i]); + nmod_mat_clear(B_mod[i]); + nmod_mat_clear(C_mod[i]); + } + + flint_free(A_mod); + flint_free(B_mod); + flint_free(C_mod); + + _nmod_vec_clear(xs); + _nmod_vec_clear(tt); + _nmod_vec_clear(uu); + _nmod_vec_clear(weights); +} diff --git a/external/flint-2.4.3/nmod_poly_mat/neg.c b/external/flint-2.4.3/nmod_poly_mat/neg.c new file mode 100644 index 0000000..6789440 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/neg.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "flint.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" + +void +nmod_poly_mat_neg(nmod_poly_mat_t B, const nmod_poly_mat_t A) +{ + slong i, j; + + for (i = 0; i < A->r; i++) + for (j = 0; j < A->c; j++) + nmod_poly_neg(nmod_poly_mat_entry(B, i, j), + nmod_poly_mat_entry(A, i, j)); +} diff --git a/external/flint-2.4.3/nmod_poly_mat/nullspace.c b/external/flint-2.4.3/nmod_poly_mat/nullspace.c new file mode 100644 index 0000000..ac89854 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/nullspace.c @@ -0,0 +1,93 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "flint.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" + +slong +nmod_poly_mat_nullspace(nmod_poly_mat_t res, const nmod_poly_mat_t mat) +{ + slong i, j, k, n, rank, nullity; + slong * pivots; + slong * nonpivots; + nmod_poly_mat_t tmp; + nmod_poly_t den; + + n = mat->c; + + nmod_poly_init(den, nmod_poly_mat_modulus(mat)); + nmod_poly_mat_init_set(tmp, mat); + rank = nmod_poly_mat_rref(tmp, den, tmp); + nullity = n - rank; + + nmod_poly_mat_zero(res); + + if (rank == 0) + { + for (i = 0; i < nullity; i++) + nmod_poly_one(res->rows[i] + i); + } + else if (nullity) + { + pivots = flint_malloc(rank * sizeof(slong)); + nonpivots = flint_malloc(nullity * sizeof(slong)); + + for (i = j = k = 0; i < rank; i++) + { + while (nmod_poly_is_zero(tmp->rows[i] + j)) + { + nonpivots[k] = j; + k++; + j++; + } + pivots[i] = j; + j++; + } + while (k < nullity) + { + nonpivots[k] = j; + k++; + j++; + } + + nmod_poly_set(den, tmp->rows[0] + pivots[0]); + + for (i = 0; i < nullity; i++) + { + for (j = 0; j < rank; j++) + nmod_poly_set(res->rows[pivots[j]] + i, + tmp->rows[j] + nonpivots[i]); + nmod_poly_neg(res->rows[nonpivots[i]] + i, den); + } + + flint_free(pivots); + flint_free(nonpivots); + } + + nmod_poly_clear(den); + nmod_poly_mat_clear(tmp); + return nullity; +} diff --git a/external/flint-2.4.3/nmod_poly_mat/one.c b/external/flint-2.4.3/nmod_poly_mat/one.c new file mode 100644 index 0000000..a8da25a --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/one.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "flint.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" + +void +nmod_poly_mat_one(nmod_poly_mat_t A) +{ + slong i, n; + + nmod_poly_mat_zero(A); + n = FLINT_MIN(A->r, A->c); + + for (i = 0; i < n; i++) + nmod_poly_one(nmod_poly_mat_entry(A, i, i)); +} diff --git a/external/flint-2.4.3/nmod_poly_mat/pow.c b/external/flint-2.4.3/nmod_poly_mat/pow.c new file mode 100644 index 0000000..d3e58e3 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/pow.c @@ -0,0 +1,74 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "flint.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" + +void +nmod_poly_mat_pow(nmod_poly_mat_t B, const nmod_poly_mat_t A, ulong exp) +{ + slong d = nmod_poly_mat_nrows(A); + + if (exp == 0 || d == 0) + { + nmod_poly_mat_one(B); + } + else if (exp == 1) + { + nmod_poly_mat_set(B, A); + } + else if (exp == 2) + { + nmod_poly_mat_sqr(B, A); + } + else if (d == 1) + { + nmod_poly_pow(nmod_poly_mat_entry(B, 0, 0), + nmod_poly_mat_entry(A, 0, 0), exp); + } + else + { + nmod_poly_mat_t T, U; + slong i; + + nmod_poly_mat_init_set(T, A); + nmod_poly_mat_init(U, d, d, nmod_poly_mat_modulus(A)); + + for (i = ((slong) FLINT_BIT_COUNT(exp)) - 2; i >= 0; i--) + { + nmod_poly_mat_sqr(U, T); + + if (exp & (WORD(1) << i)) + nmod_poly_mat_mul(T, U, A); + else + nmod_poly_mat_swap(T, U); + } + + nmod_poly_mat_swap(B, T); + nmod_poly_mat_clear(T); + nmod_poly_mat_clear(U); + } +} diff --git a/external/flint-2.4.3/nmod_poly_mat/print.c b/external/flint-2.4.3/nmod_poly_mat/print.c new file mode 100644 index 0000000..854410a --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/print.c @@ -0,0 +1,51 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" + +void +nmod_poly_mat_print(const nmod_poly_mat_t A, const char * x) +{ + slong i, j; + + flint_printf("<%wd x %wd matrix over Z/nZ[%s]>\n", A->r, A->c, x); + + for (i = 0; i < A->r; i++) + { + flint_printf("["); + for (j = 0; j < A->c; j++) + { + /* TODO: pretty */ + nmod_poly_print(nmod_poly_mat_entry(A, i, j)); + if (j + 1 < A->c) + flint_printf(", "); + } + flint_printf("]\n"); + } + flint_printf("\n"); +} diff --git a/external/flint-2.4.3/nmod_poly_mat/randtest.c b/external/flint-2.4.3/nmod_poly_mat/randtest.c new file mode 100644 index 0000000..e08cbe1 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/randtest.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" + +void +nmod_poly_mat_randtest(nmod_poly_mat_t A, flint_rand_t state, slong len) +{ + slong i, j; + + for (i = 0; i < A->r; i++) + for (j = 0; j < A->c; j++) + nmod_poly_randtest(nmod_poly_mat_entry(A, i, j), state, len); +} diff --git a/external/flint-2.4.3/nmod_poly_mat/randtest_sparse.c b/external/flint-2.4.3/nmod_poly_mat/randtest_sparse.c new file mode 100644 index 0000000..06c76b1 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/randtest_sparse.c @@ -0,0 +1,53 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "flint.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" +#include "ulong_extras.h" + +void +nmod_poly_mat_randtest_sparse(nmod_poly_mat_t A, flint_rand_t state, slong len, + float density) +{ + slong i, j; + + for (i = 0; i < A->r; i++) + { + for (j = 0; j < A->c; j++) + { + if (n_randint(state, 1000) < density * 1000) + { + slong l = n_randint(state, len + 1); + l = FLINT_MAX(l, 1); + nmod_poly_randtest(nmod_poly_mat_entry(A, i, j), state, l); + } + else + { + nmod_poly_zero(nmod_poly_mat_entry(A, i, j)); + } + } + } +} diff --git a/external/flint-2.4.3/nmod_poly_mat/rank.c b/external/flint-2.4.3/nmod_poly_mat/rank.c new file mode 100644 index 0000000..7810455 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/rank.c @@ -0,0 +1,47 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "flint.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" + + +slong +nmod_poly_mat_rank(const nmod_poly_mat_t A) +{ + nmod_poly_mat_t tmp; + nmod_poly_t den; + slong rank; + + if (nmod_poly_mat_is_empty(A)) + return 0; + + nmod_poly_mat_init_set(tmp, A); + nmod_poly_init(den, nmod_poly_mat_modulus(A)); + rank = nmod_poly_mat_fflu(tmp, den, NULL, tmp, 0); + nmod_poly_mat_clear(tmp); + nmod_poly_clear(den); + return rank; +} diff --git a/external/flint-2.4.3/nmod_poly_mat/rref.c b/external/flint-2.4.3/nmod_poly_mat/rref.c new file mode 100644 index 0000000..78c2e40 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/rref.c @@ -0,0 +1,111 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011-2012 Fredrik Johansson + +******************************************************************************/ + +#include "flint.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" + +slong +nmod_poly_mat_rref(nmod_poly_mat_t R, nmod_poly_t den, const nmod_poly_mat_t A) +{ + slong i, j, k, m, n, rank; + slong *pivots, *nonpivots; + + rank = nmod_poly_mat_fflu(R, den, NULL, A, 0); + m = nmod_poly_mat_nrows(R); + n = nmod_poly_mat_ncols(R); + + /* clear bottom */ + for (i = rank; i < m; i++) + for (j = 0; j < n; j++) + nmod_poly_zero(nmod_poly_mat_entry(R, i, j)); + + /* Convert row echelon form to reduced row echelon form */ + if (rank > 1) + { + nmod_poly_t tmp, tmp2; + nmod_poly_init(tmp, nmod_poly_mat_modulus(R)); + nmod_poly_init(tmp2, nmod_poly_mat_modulus(R)); + + pivots = flint_malloc(sizeof(slong) * n); + nonpivots = pivots + rank; + + /* find pivot positions */ + for (i = j = k = 0; i < rank; i++) + { + while (nmod_poly_is_zero(nmod_poly_mat_entry(R, i, j))) + { + nonpivots[k] = j; + k++; + j++; + } + pivots[i] = j; + j++; + } + while (k < n - rank) + { + nonpivots[k] = j; + k++; + j++; + } + + for (k = 0; k < n - rank; k++) + { + for (i = rank - 2; i >= 0; i--) + { + nmod_poly_mul(tmp, den, nmod_poly_mat_entry(R, i, nonpivots[k])); + + for (j = i + 1; j < rank; j++) + { + nmod_poly_mul(tmp2, nmod_poly_mat_entry(R, i, pivots[j]), + nmod_poly_mat_entry(R, j, nonpivots[k])); + nmod_poly_sub(tmp, tmp, tmp2); + } + + nmod_poly_div(nmod_poly_mat_entry(R, i, nonpivots[k]), + tmp, nmod_poly_mat_entry(R, i, pivots[i])); + } + } + + /* clear pivot columns */ + for (i = 0; i < rank; i++) + { + for (j = 0; j < rank; j++) + { + if (i == j) + nmod_poly_set(nmod_poly_mat_entry(R, j, pivots[i]), den); + else + nmod_poly_zero(nmod_poly_mat_entry(R, j, pivots[i])); + } + } + + flint_free(pivots); + nmod_poly_clear(tmp); + nmod_poly_clear(tmp2); + } + + return rank; +} + diff --git a/external/flint-2.4.3/nmod_poly_mat/scalar_mul_nmod.c b/external/flint-2.4.3/nmod_poly_mat/scalar_mul_nmod.c new file mode 100644 index 0000000..533a90a --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/scalar_mul_nmod.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "flint.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" + +void +nmod_poly_mat_scalar_mul_nmod(nmod_poly_mat_t B, const nmod_poly_mat_t A, + mp_limb_t c) +{ + slong i, j; + + for (i = 0; i < nmod_poly_mat_nrows(B); i++) + for (j = 0; j < nmod_poly_mat_ncols(B); j++) + nmod_poly_scalar_mul_nmod(nmod_poly_mat_entry(B, i, j), + nmod_poly_mat_entry(A, i, j), c); +} diff --git a/external/flint-2.4.3/nmod_poly_mat/scalar_mul_nmod_poly.c b/external/flint-2.4.3/nmod_poly_mat/scalar_mul_nmod_poly.c new file mode 100644 index 0000000..cca0cf7 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/scalar_mul_nmod_poly.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "flint.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" + +void +nmod_poly_mat_scalar_mul_nmod_poly(nmod_poly_mat_t B, const nmod_poly_mat_t A, + const nmod_poly_t c) +{ + slong i, j; + + for (i = 0; i < nmod_poly_mat_nrows(B); i++) + for (j = 0; j < nmod_poly_mat_ncols(B); j++) + nmod_poly_mul(nmod_poly_mat_entry(B, i, j), + nmod_poly_mat_entry(A, i, j), c); +} diff --git a/external/flint-2.4.3/nmod_poly_mat/set.c b/external/flint-2.4.3/nmod_poly_mat/set.c new file mode 100644 index 0000000..5bf4203 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/set.c @@ -0,0 +1,42 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "flint.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" + +void +nmod_poly_mat_set(nmod_poly_mat_t B, const nmod_poly_mat_t A) +{ + if (A != B) + { + slong i, j; + + for (i = 0; i < A->r; i++) + for (j = 0; j < A->c; j++) + nmod_poly_set(nmod_poly_mat_entry(B, i, j), + nmod_poly_mat_entry(A, i, j)); + } +} diff --git a/external/flint-2.4.3/nmod_poly_mat/solve.c b/external/flint-2.4.3/nmod_poly_mat/solve.c new file mode 100644 index 0000000..aed682e --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/solve.c @@ -0,0 +1,36 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "flint.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" +#include "perm.h" + +int +nmod_poly_mat_solve(nmod_poly_mat_t X, nmod_poly_t den, + const nmod_poly_mat_t A, const nmod_poly_mat_t B) +{ + return nmod_poly_mat_solve_fflu(X, den, A, B); +} diff --git a/external/flint-2.4.3/nmod_poly_mat/solve_fflu.c b/external/flint-2.4.3/nmod_poly_mat/solve_fflu.c new file mode 100644 index 0000000..e91ab31 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/solve_fflu.c @@ -0,0 +1,58 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "flint.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" +#include "perm.h" + +int +nmod_poly_mat_solve_fflu(nmod_poly_mat_t X, nmod_poly_t den, + const nmod_poly_mat_t A, const nmod_poly_mat_t B) +{ + nmod_poly_mat_t LU; + slong dim, *perm; + int result; + + if (nmod_poly_mat_is_empty(B)) + { + nmod_poly_one(den); + return 1; + } + + dim = nmod_poly_mat_nrows(A); + perm = _perm_init(dim); + nmod_poly_mat_init_set(LU, A); + result = (nmod_poly_mat_fflu(LU, den, perm, LU, 1) == dim); + + if (result) + nmod_poly_mat_solve_fflu_precomp(X, perm, LU, B); + else + nmod_poly_zero(den); + + _perm_clear(perm); + nmod_poly_mat_clear(LU); + return result; +} diff --git a/external/flint-2.4.3/nmod_poly_mat/solve_fflu_precomp.c b/external/flint-2.4.3/nmod_poly_mat/solve_fflu_precomp.c new file mode 100644 index 0000000..c2e101a --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/solve_fflu_precomp.c @@ -0,0 +1,102 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" +#include "perm.h" + +#define XX(ii,jj) nmod_poly_mat_entry(X,(ii),(jj)) +#define BB(ii,jj) nmod_poly_mat_entry(B,(ii),(jj)) +#define LU(ii,jj) nmod_poly_mat_entry(FFLU,(ii),(jj)) + +void +nmod_poly_mat_set_perm(nmod_poly_mat_t X, const slong * perm, + const nmod_poly_mat_t B) +{ + if (X == B) + { + /* Not implemented */ + abort(); + } + else + { + slong i, j; + + if (perm == NULL) + abort(); + + for (i = 0; i < nmod_poly_mat_nrows(B); i++) + for (j = 0; j < nmod_poly_mat_ncols(B); j++) + nmod_poly_set(nmod_poly_mat_entry(X, i, j), + nmod_poly_mat_entry(B, perm[i], j)); + } +} + +void +nmod_poly_mat_solve_fflu_precomp(nmod_poly_mat_t X, + const slong * perm, + const nmod_poly_mat_t FFLU, const nmod_poly_mat_t B) +{ + nmod_poly_t T; + slong i, j, k, m, n; + + n = X->r; + m = X->c; + + nmod_poly_init(T, nmod_poly_mat_modulus(B)); + nmod_poly_mat_set_perm(X, perm, B); + + for (k = 0; k < m; k++) + { + /* Fraction-free forward substitution */ + for (i = 0; i < n - 1; i++) + { + for (j = i + 1; j < n; j++) + { + nmod_poly_mul(XX(j, k), XX(j, k), LU(i, i)); + nmod_poly_mul(T, LU(j, i), XX(i, k)); + nmod_poly_sub(XX(j, k), XX(j, k), T); + if (i > 0) + nmod_poly_div(XX(j, k), XX(j, k), LU(i-1, i-1)); + } + } + + /* Fraction-free back substitution */ + for (i = n - 2; i >= 0; i--) + { + nmod_poly_mul(XX(i, k), XX(i, k), LU(n-1, n-1)); + for (j = i + 1; j < n; j++) + { + nmod_poly_mul(T, XX(j, k), LU(i, j)); + nmod_poly_sub(XX(i, k), XX(i, k), T); + } + nmod_poly_div(XX(i, k), XX(i, k), LU(i, i)); + } + } + + nmod_poly_clear(T); +} diff --git a/external/flint-2.4.3/nmod_poly_mat/sqr.c b/external/flint-2.4.3/nmod_poly_mat/sqr.c new file mode 100644 index 0000000..951dfaf --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/sqr.c @@ -0,0 +1,61 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" + +#define KS_MIN_DIM 10 +#define INTERPOLATE_MIN_DIM 80 +#define KS_MAX_LENGTH 128 + +void +nmod_poly_mat_sqr(nmod_poly_mat_t C, const nmod_poly_mat_t A) +{ + slong dim = A->r; + + if (dim < KS_MIN_DIM) + { + nmod_poly_mat_sqr_classical(C, A); + } + else + { + slong Alen; + mp_limb_t mod = nmod_poly_mat_modulus(A); + + Alen = nmod_poly_mat_max_length(A); + + if ((FLINT_BIT_COUNT(mod) > FLINT_BITS / 4) + && (dim > INTERPOLATE_MIN_DIM + n_sqrt(Alen)) + && (mod >= 2 * Alen - 1) && n_is_prime(mod)) + nmod_poly_mat_sqr_interpolate(C, A); + + if (Alen > KS_MAX_LENGTH) + nmod_poly_mat_sqr_classical(C, A); + else + nmod_poly_mat_sqr_KS(C, A); + } +} diff --git a/external/flint-2.4.3/nmod_poly_mat/sqr_KS.c b/external/flint-2.4.3/nmod_poly_mat/sqr_KS.c new file mode 100644 index 0000000..742ee58 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/sqr_KS.c @@ -0,0 +1,73 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" +#include "fmpz.h" +#include "fmpz_mat.h" + +void +nmod_poly_mat_sqr_KS(nmod_poly_mat_t B, const nmod_poly_mat_t A) +{ + slong i, j, n; + slong A_len; + mp_bitcnt_t bit_size; + fmpz_mat_t AA, BB; + + n = A->r; + + if (n == 0) + { + nmod_poly_mat_zero(B); + return; + } + + A_len = nmod_poly_mat_max_length(A); + + bit_size = 2 * FLINT_BIT_COUNT(nmod_poly_mat_modulus(A)); + bit_size += FLINT_BIT_COUNT(A_len); + bit_size += FLINT_BIT_COUNT(n); + + fmpz_mat_init(AA, n, n); + fmpz_mat_init(BB, n, n); + + for (i = 0; i < n; i++) + for (j = 0; j < A->c; j++) + nmod_poly_bit_pack(fmpz_mat_entry(AA, i, j), + nmod_poly_mat_entry(A, i, j), bit_size); + + /* Should use fmpz_mat_sqr */ + fmpz_mat_mul(BB, AA, AA); + + for (i = 0; i < n; i++) + for (j = 0; j < n; j++) + nmod_poly_bit_unpack(nmod_poly_mat_entry(B, i, j), + fmpz_mat_entry(BB, i, j), bit_size); + + fmpz_mat_clear(AA); + fmpz_mat_clear(BB); +} diff --git a/external/flint-2.4.3/nmod_poly_mat/sqr_classical.c b/external/flint-2.4.3/nmod_poly_mat/sqr_classical.c new file mode 100644 index 0000000..afb6838 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/sqr_classical.c @@ -0,0 +1,78 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" + +static __inline__ void +nmod_poly_sqr(nmod_poly_t y, const nmod_poly_t x) +{ + nmod_poly_mul(y, x, x); +} + +#define E nmod_poly_mat_entry + +void +nmod_poly_mat_sqr_classical(nmod_poly_mat_t B, const nmod_poly_mat_t A) +{ + slong n = A->r; + + if (n == 0) + return; + + if (n == 1) + { + nmod_poly_sqr(E(B, 0, 0), E(A, 0, 0)); + return; + } + + if (n == 2) + { + nmod_poly_t t, u; + + nmod_poly_init(t, nmod_poly_mat_modulus(A)); + nmod_poly_init(u, nmod_poly_mat_modulus(A)); + + nmod_poly_add(t, E(A, 0, 0), E(A, 1, 1)); + nmod_poly_mul(u, E(A, 0, 1), E(A, 1, 0)); + + nmod_poly_sqr(E(B, 0, 0), E(A, 0, 0)); + nmod_poly_add(E(B, 0, 0), E(B, 0, 0), u); + + nmod_poly_sqr(E(B, 1, 1), E(A, 1, 1)); + nmod_poly_add(E(B, 1, 1), E(B, 1, 1), u); + + nmod_poly_mul(E(B, 0, 1), E(A, 0, 1), t); + nmod_poly_mul(E(B, 1, 0), E(A, 1, 0), t); + + nmod_poly_clear(t); + nmod_poly_clear(u); + return; + } + + nmod_poly_mat_mul_classical(B, A, A); +} diff --git a/external/flint-2.4.3/nmod_poly_mat/sqr_interpolate.c b/external/flint-2.4.3/nmod_poly_mat/sqr_interpolate.c new file mode 100644 index 0000000..33b7499 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/sqr_interpolate.c @@ -0,0 +1,138 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 "flint.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" + +void +nmod_poly_mat_sqr_interpolate(nmod_poly_mat_t C, const nmod_poly_mat_t A) +{ + slong i, j, k; + slong A_len, len; + + nmod_mat_t *C_mod, *A_mod; + + mp_ptr xs; + mp_ptr tt, uu; + mp_ptr * tree; + mp_ptr weights; + nmod_t mod; + + if (A->c == 0) + { + nmod_poly_mat_zero(C); + return; + } + + A_len = nmod_poly_mat_max_length(A); + + if (A_len == 0) + { + nmod_poly_mat_zero(C); + return; + } + + len = 2 * A_len - 1; + nmod_init(&mod, nmod_poly_mat_modulus(A)); + + if (mod.n < len) + { + flint_printf("Exception (nmod_poly_mat_sqr_interpolate). \n" + "Characteristic is too small.\n"); + abort(); + } + + xs = _nmod_vec_init(len); + tt = _nmod_vec_init(len); + uu = _nmod_vec_init(len); + weights = _nmod_vec_init(len); + + A_mod = flint_malloc(sizeof(nmod_mat_t) * len); + C_mod = flint_malloc(sizeof(nmod_mat_t) * len); + + for (i = 0; i < len; i++) + { + xs[i] = i; + nmod_mat_init(A_mod[i], A->r, A->c, mod.n); + nmod_mat_init(C_mod[i], C->r, C->c, mod.n); + } + + tree = _nmod_poly_tree_alloc(len); + _nmod_poly_tree_build(tree, xs, len, mod); + _nmod_poly_interpolation_weights(weights, tree, len, mod); + + for (i = 0; i < A->r; i++) + { + for (j = 0; j < A->c; j++) + { + _nmod_poly_evaluate_nmod_vec_fast_precomp(tt, + nmod_poly_mat_entry(A, i, j)->coeffs, + nmod_poly_mat_entry(A, i, j)->length, + tree, len, mod); + + for (k = 0; k < len; k++) + A_mod[k]->rows[i][j] = tt[k]; + } + } + + /* should be nmod_mat_sqr */ + for (i = 0; i < len; i++) + nmod_mat_mul(C_mod[i], A_mod[i], A_mod[i]); + + for (i = 0; i < C->r; i++) + { + for (j = 0; j < C->c; j++) + { + nmod_poly_struct * poly; + + for (k = 0; k < len; k++) + tt[k] = C_mod[k]->rows[i][j]; + + poly = nmod_poly_mat_entry(C, i, j); + nmod_poly_fit_length(poly, len); + _nmod_poly_interpolate_nmod_vec_fast_precomp(poly->coeffs, + tt, tree, weights, len, mod); + poly->length = len; + _nmod_poly_normalise(poly); + } + } + + _nmod_poly_tree_free(tree, len); + + for (i = 0; i < len; i++) + { + nmod_mat_clear(A_mod[i]); + nmod_mat_clear(C_mod[i]); + } + + flint_free(A_mod); + flint_free(C_mod); + + _nmod_vec_clear(xs); + _nmod_vec_clear(tt); + _nmod_vec_clear(uu); + _nmod_vec_clear(weights); +} diff --git a/external/flint-2.4.3/nmod_poly_mat/sub.c b/external/flint-2.4.3/nmod_poly_mat/sub.c new file mode 100644 index 0000000..3f1ac31 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/sub.c @@ -0,0 +1,42 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" + +void +nmod_poly_mat_sub(nmod_poly_mat_t C, + const nmod_poly_mat_t A, const nmod_poly_mat_t B) +{ + slong i, j; + + for (i = 0; i < A->r; i++) + for (j = 0; j < A->c; j++) + nmod_poly_sub(nmod_poly_mat_entry(C, i, j), + nmod_poly_mat_entry(A, i, j), + nmod_poly_mat_entry(B, i, j)); +} diff --git a/external/flint-2.4.3/nmod_poly_mat/swap.c b/external/flint-2.4.3/nmod_poly_mat/swap.c new file mode 100644 index 0000000..d566ba7 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/swap.c @@ -0,0 +1,42 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" + +void +nmod_poly_mat_swap(nmod_poly_mat_t A, nmod_poly_mat_t B) +{ + if (A != B) + { + nmod_poly_mat_struct tmp; + + tmp = *A; + *A = *B; + *B = tmp; + } +} diff --git a/external/flint-2.4.3/nmod_poly_mat/test/t-add.c b/external/flint-2.4.3/nmod_poly_mat/test/t-add.c new file mode 100644 index 0000000..1022c36 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/test/t-add.c @@ -0,0 +1,183 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_mat.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" + +int +main(void) +{ + slong i; + + FLINT_TEST_INIT(state); + + flint_printf("add...."); + fflush(stdout); + + /* Check evaluation homomorphism */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_mat_t A, B, C; + nmod_mat_t a, b, c, d; + mp_limb_t mod, x; + slong m, n, deg; + + m = n_randint(state, 20); + n = n_randint(state, 20); + deg = 1 + n_randint(state, 10); + mod = n_randtest_prime(state, 0); + + nmod_poly_mat_init(A, m, n, mod); + nmod_poly_mat_init(B, m, n, mod); + nmod_poly_mat_init(C, m, n, mod); + + nmod_mat_init(a, m, n, mod); + nmod_mat_init(b, m, n, mod); + nmod_mat_init(c, m, n, mod); + nmod_mat_init(d, m, n, mod); + + nmod_poly_mat_randtest(A, state, deg); + nmod_poly_mat_randtest(B, state, deg); + nmod_poly_mat_add(C, A, B); + + x = n_randint(state, mod); + + nmod_poly_mat_evaluate_nmod(a, A, x); + nmod_poly_mat_evaluate_nmod(b, B, x); + nmod_poly_mat_evaluate_nmod(d, C, x); + nmod_mat_add(c, a, b); + + if (!nmod_mat_equal(c, d)) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"); + nmod_poly_mat_print(A, "x"); + flint_printf("B:\n"); + nmod_poly_mat_print(B, "x"); + flint_printf("C:\n"); + nmod_poly_mat_print(C, "x"); + flint_printf("\n"); + abort(); + } + + nmod_poly_mat_clear(A); + nmod_poly_mat_clear(B); + nmod_poly_mat_clear(C); + + nmod_mat_clear(a); + nmod_mat_clear(b); + nmod_mat_clear(c); + nmod_mat_clear(d); + } + + /* Check aliasing C and A */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_mat_t A, B, C; + slong m, n, deg; + mp_limb_t mod; + + mod = n_randtest_prime(state, 0); + m = n_randint(state, 20); + n = n_randint(state, 20); + deg = 1 + n_randint(state, 10); + + nmod_poly_mat_init(A, m, n, mod); + nmod_poly_mat_init(B, m, n, mod); + nmod_poly_mat_init(C, m, n, mod); + + nmod_poly_mat_randtest(A, state, deg); + nmod_poly_mat_randtest(B, state, deg); + + nmod_poly_mat_add(C, A, B); + nmod_poly_mat_add(A, A, B); + + if (!nmod_poly_mat_equal(C, A)) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"); + nmod_poly_mat_print(A, "x"); + flint_printf("B:\n"); + nmod_poly_mat_print(B, "x"); + flint_printf("C:\n"); + nmod_poly_mat_print(C, "x"); + flint_printf("\n"); + abort(); + } + + nmod_poly_mat_clear(A); + nmod_poly_mat_clear(B); + nmod_poly_mat_clear(C); + } + + /* Check aliasing C and B */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_mat_t A, B, C; + slong m, n, deg; + mp_limb_t mod; + + mod = n_randtest_prime(state, 0); + m = n_randint(state, 20); + n = n_randint(state, 20); + deg = 1 + n_randint(state, 10); + + nmod_poly_mat_init(A, m, n, mod); + nmod_poly_mat_init(B, m, n, mod); + nmod_poly_mat_init(C, m, n, mod); + + nmod_poly_mat_randtest(A, state, deg); + nmod_poly_mat_randtest(B, state, deg); + + nmod_poly_mat_add(C, A, B); + nmod_poly_mat_add(B, A, B); + + if (!nmod_poly_mat_equal(C, B)) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"); + nmod_poly_mat_print(A, "x"); + flint_printf("B:\n"); + nmod_poly_mat_print(B, "x"); + flint_printf("C:\n"); + nmod_poly_mat_print(C, "x"); + flint_printf("\n"); + abort(); + } + + nmod_poly_mat_clear(A); + nmod_poly_mat_clear(B); + nmod_poly_mat_clear(C); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly_mat/test/t-det.c b/external/flint-2.4.3/nmod_poly_mat/test/t-det.c new file mode 100644 index 0000000..f4337d0 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/test/t-det.c @@ -0,0 +1,110 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" +#include "fmpz.h" + +int +main(void) +{ + slong i; + + FLINT_TEST_INIT(state); + + flint_printf("det...."); + fflush(stdout); + + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_mat_t A, B, C; + nmod_poly_t a, b, ab, c; + slong n, deg; + mp_limb_t mod; + float density; + + mod = n_randtest_prime(state, 0); + n = n_randint(state, 10); + deg = 1 + n_randint(state, 5); + density = n_randint(state, 100) * 0.01; + + nmod_poly_mat_init(A, n, n, mod); + nmod_poly_mat_init(B, n, n, mod); + nmod_poly_mat_init(C, n, n, mod); + + nmod_poly_init(a, mod); + nmod_poly_init(b, mod); + nmod_poly_init(ab, mod); + nmod_poly_init(c, mod); + + nmod_poly_mat_randtest_sparse(A, state, deg, density); + nmod_poly_mat_randtest_sparse(B, state, deg, density); + nmod_poly_mat_mul(C, A, B); + + nmod_poly_mat_det(a, A); + nmod_poly_mat_det(b, B); + nmod_poly_mat_det(c, C); + nmod_poly_mul(ab, a, b); + + if (!nmod_poly_equal(c, ab)) + { + flint_printf("FAIL:\n"); + flint_printf("determinants don't agree!\n"); + flint_printf("A:\n"); + nmod_poly_mat_print(A, "x"); + flint_printf("B:\n"); + nmod_poly_mat_print(B, "x"); + flint_printf("C:\n"); + nmod_poly_mat_print(C, "x"); + flint_printf("det(A):\n"); + nmod_poly_print(a); + flint_printf("\ndet(B):\n"); + nmod_poly_print(b); + flint_printf("\ndet(C):\n"); + nmod_poly_print(c); + flint_printf("\ndet(A)*det(B):\n"); + nmod_poly_print(ab); + flint_printf("\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + nmod_poly_clear(ab); + nmod_poly_clear(c); + + nmod_poly_mat_clear(A); + nmod_poly_mat_clear(B); + nmod_poly_mat_clear(C); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly_mat/test/t-det_interpolate.c b/external/flint-2.4.3/nmod_poly_mat/test/t-det_interpolate.c new file mode 100644 index 0000000..47f5b01 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/test/t-det_interpolate.c @@ -0,0 +1,88 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" + + +int +main(void) +{ + slong i; + + FLINT_TEST_INIT(state); + + flint_printf("det_interpolate...."); + fflush(stdout); + + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_mat_t A; + nmod_poly_t a, b; + slong n, deg; + mp_limb_t mod; + + mod = n_randtest_prime(state, 0); + n = n_randint(state, 10); + deg = 1 + n_randint(state, 5); + + nmod_poly_mat_init(A, n, n, mod); + + nmod_poly_init(a, mod); + nmod_poly_init(b, mod); + + nmod_poly_mat_randtest(A, state, deg); + + nmod_poly_mat_det(a, A); + nmod_poly_mat_det_interpolate(b, A); + + if (!nmod_poly_equal(a, b)) + { + flint_printf("FAIL:\n"); + flint_printf("determinants don't agree!\n"); + flint_printf("A:\n"); + nmod_poly_mat_print(A, "x"); + flint_printf("det(A):\n"); + nmod_poly_print(a); + flint_printf("\ndet_interpolate(A):\n"); + nmod_poly_print(b); + flint_printf("\n"); + abort(); + } + + nmod_poly_clear(a); + nmod_poly_clear(b); + + nmod_poly_mat_clear(A); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly_mat/test/t-init_clear.c b/external/flint-2.4.3/nmod_poly_mat/test/t-init_clear.c new file mode 100644 index 0000000..5bee7bd --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/test/t-init_clear.c @@ -0,0 +1,67 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("init/clear...."); + fflush(stdout); + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + nmod_poly_mat_t a; + mp_limb_t mod; + slong j, k; + slong rows = n_randint(state, 100); + slong cols = n_randint(state, 100); + mod = n_randtest_prime(state, 0); + + nmod_poly_mat_init(a, rows, cols, mod); + + for (j = 0; j < rows; j++) + for (k = 0; k < cols; k++) + nmod_poly_zero(nmod_poly_mat_entry(a, j, k)); + + nmod_poly_mat_clear(a); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly_mat/test/t-inv.c b/external/flint-2.4.3/nmod_poly_mat/test/t-inv.c new file mode 100644 index 0000000..36c2cfc --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/test/t-inv.c @@ -0,0 +1,164 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" +#include "fmpz.h" + +int +main(void) +{ + slong i; + + FLINT_TEST_INIT(state); + + flint_printf("inv...."); + fflush(stdout); + + /* Test aliasing */ + for (i = 0; i < 40 * flint_test_multiplier(); i++) + { + nmod_poly_mat_t A, Ainv; + nmod_poly_t den1, den2; + slong n, deg; + float density; + int ns1, ns2, result; + mp_limb_t mod; + + mod = n_randtest_prime(state, 0); + n = n_randint(state, 8); + deg = 1 + n_randint(state, 5); + density = n_randint(state, 100) * 0.01; + + nmod_poly_mat_init(A, n, n, mod); + nmod_poly_mat_init(Ainv, n, n, mod); + nmod_poly_init(den1, mod); + nmod_poly_init(den2, mod); + + nmod_poly_mat_randtest_sparse(A, state, deg, density); + + ns1 = nmod_poly_mat_inv(Ainv, den1, A); + ns2 = nmod_poly_mat_inv(A, den2, A); + + result = ns1 == ns2; + + if (result && ns1 != 0) + { + result = nmod_poly_equal(den1, den2) && + nmod_poly_mat_equal(A, Ainv); + } + + if (!result) + { + flint_printf("FAIL (aliasing)!\n"); + nmod_poly_mat_print(A, "x"); flint_printf("\n"); + nmod_poly_mat_print(Ainv, "x"); flint_printf("\n"); + abort(); + } + + nmod_poly_mat_clear(A); + nmod_poly_mat_clear(Ainv); + nmod_poly_clear(den1); + nmod_poly_clear(den2); + } + + /* Check A^(-1) = A = 1 */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_mat_t A, Ainv, B, Iden; + nmod_poly_t den, det; + slong n, deg; + float density; + int nonsingular; + mp_limb_t mod; + + mod = n_randtest_prime(state, 0); + n = n_randint(state, 10); + deg = 1 + n_randint(state, 5); + density = n_randint(state, 100) * 0.01; + + nmod_poly_mat_init(A, n, n, mod); + nmod_poly_mat_init(Ainv, n, n, mod); + nmod_poly_mat_init(B, n, n, mod); + nmod_poly_mat_init(Iden, n, n, mod); + nmod_poly_init(den, mod); + nmod_poly_init(det, mod); + + nmod_poly_mat_randtest_sparse(A, state, deg, density); + nonsingular = nmod_poly_mat_inv(Ainv, den, A); + nmod_poly_mat_det_interpolate(det, A); + + if (n == 0) + { + if (nonsingular == 0 || !nmod_poly_is_one(den)) + { + flint_printf("FAIL: expected empty matrix to pass\n"); + abort(); + } + } + else + { + if (!nmod_poly_equal(den, det)) + { + nmod_poly_neg(det, det); + flint_printf("FAIL: den != det(A)\n"); + abort(); + } + + nmod_poly_mat_mul(B, Ainv, A); + nmod_poly_mat_one(Iden); + nmod_poly_mat_scalar_mul_nmod_poly(Iden, Iden, den); + + if (!nmod_poly_mat_equal(B, Iden)) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"); + nmod_poly_mat_print(A, "x"); + flint_printf("Ainv:\n"); + nmod_poly_mat_print(Ainv, "x"); + flint_printf("B:\n"); + nmod_poly_mat_print(B, "x"); + flint_printf("den:\n"); + nmod_poly_print(den); + abort(); + } + } + + nmod_poly_clear(den); + nmod_poly_clear(det); + nmod_poly_mat_clear(A); + nmod_poly_mat_clear(Ainv); + nmod_poly_mat_clear(B); + nmod_poly_mat_clear(Iden); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly_mat/test/t-mul.c b/external/flint-2.4.3/nmod_poly_mat/test/t-mul.c new file mode 100644 index 0000000..cd708cd --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/test/t-mul.c @@ -0,0 +1,189 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_mat.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" +#include "fmpz.h" + +int +main(void) +{ + slong i; + + FLINT_TEST_INIT(state); + + flint_printf("mul...."); + fflush(stdout); + + /* Check evaluation homomorphism */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_mat_t A, B, C; + nmod_mat_t a, b, c, d; + mp_limb_t mod, x; + slong m, n, k, deg; + + mod = n_randtest_prime(state, 0); + m = n_randint(state, 20); + n = n_randint(state, 20); + k = n_randint(state, 20); + deg = 1 + n_randint(state, 10); + + nmod_poly_mat_init(A, m, n, mod); + nmod_poly_mat_init(B, n, k, mod); + nmod_poly_mat_init(C, m, k, mod); + + nmod_mat_init(a, m, n, mod); + nmod_mat_init(b, n, k, mod); + nmod_mat_init(c, m, k, mod); + nmod_mat_init(d, m, k, mod); + + nmod_poly_mat_randtest(A, state, deg); + nmod_poly_mat_randtest(B, state, deg); + nmod_poly_mat_randtest(C, state, deg); /* noise in output */ + + nmod_poly_mat_mul(C, A, B); + + x = n_randint(state, mod); + + nmod_poly_mat_evaluate_nmod(a, A, x); + nmod_poly_mat_evaluate_nmod(b, B, x); + nmod_poly_mat_evaluate_nmod(d, C, x); + nmod_mat_mul(c, a, b); + + if (!nmod_mat_equal(c, d)) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"); + nmod_poly_mat_print(A, "x"); + flint_printf("B:\n"); + nmod_poly_mat_print(B, "x"); + flint_printf("C:\n"); + nmod_poly_mat_print(C, "x"); + flint_printf("\n"); + abort(); + } + + nmod_poly_mat_clear(A); + nmod_poly_mat_clear(B); + nmod_poly_mat_clear(C); + + nmod_mat_clear(a); + nmod_mat_clear(b); + nmod_mat_clear(c); + nmod_mat_clear(d); + } + + /* Check aliasing C and A */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_mat_t A, B, C; + slong m, n, deg; + mp_limb_t mod; + + mod = n_randtest_prime(state, 0); + m = n_randint(state, 20); + n = n_randint(state, 20); + deg = 1 + n_randint(state, 10); + + nmod_poly_mat_init(A, m, n, mod); + nmod_poly_mat_init(B, n, n, mod); + nmod_poly_mat_init(C, m, n, mod); + + nmod_poly_mat_randtest(A, state, deg); + nmod_poly_mat_randtest(B, state, deg); + nmod_poly_mat_randtest(C, state, deg); /* noise in output */ + + nmod_poly_mat_mul(C, A, B); + nmod_poly_mat_mul(A, A, B); + + if (!nmod_poly_mat_equal(C, A)) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"); + nmod_poly_mat_print(A, "x"); + flint_printf("B:\n"); + nmod_poly_mat_print(B, "x"); + flint_printf("C:\n"); + nmod_poly_mat_print(C, "x"); + flint_printf("\n"); + abort(); + } + + nmod_poly_mat_clear(A); + nmod_poly_mat_clear(B); + nmod_poly_mat_clear(C); + } + + /* Check aliasing C and B */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_mat_t A, B, C; + slong m, n, deg; + mp_limb_t mod; + + mod = n_randtest_prime(state, 0); + m = n_randint(state, 20); + n = n_randint(state, 20); + deg = 1 + n_randint(state, 10); + + nmod_poly_mat_init(A, m, m, mod); + nmod_poly_mat_init(B, m, n, mod); + nmod_poly_mat_init(C, m, n, mod); + + nmod_poly_mat_randtest(A, state, deg); + nmod_poly_mat_randtest(B, state, deg); + nmod_poly_mat_randtest(C, state, deg); /* noise in output */ + + nmod_poly_mat_mul(C, A, B); + nmod_poly_mat_mul(B, A, B); + + if (!nmod_poly_mat_equal(C, B)) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"); + nmod_poly_mat_print(A, "x"); + flint_printf("B:\n"); + nmod_poly_mat_print(B, "x"); + flint_printf("C:\n"); + nmod_poly_mat_print(C, "x"); + flint_printf("\n"); + abort(); + } + + nmod_poly_mat_clear(A); + nmod_poly_mat_clear(B); + nmod_poly_mat_clear(C); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly_mat/test/t-mul_KS.c b/external/flint-2.4.3/nmod_poly_mat/test/t-mul_KS.c new file mode 100644 index 0000000..7e2ae0d --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/test/t-mul_KS.c @@ -0,0 +1,175 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" +#include "fmpz.h" + +int +main(void) +{ + slong i; + + FLINT_TEST_INIT(state); + + flint_printf("mul_KS...."); + fflush(stdout); + + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + nmod_poly_mat_t A, B, C, D; + slong m, n, k, deg; + mp_limb_t mod; + + mod = n_randtest_prime(state, 0); + m = n_randint(state, 15); + n = n_randint(state, 15); + k = n_randint(state, 15); + deg = 1 + n_randint(state, 15); + + nmod_poly_mat_init(A, m, n, mod); + nmod_poly_mat_init(B, n, k, mod); + nmod_poly_mat_init(C, m, k, mod); + nmod_poly_mat_init(D, m, k, mod); + + nmod_poly_mat_randtest(A, state, deg); + nmod_poly_mat_randtest(B, state, deg); + nmod_poly_mat_randtest(C, state, deg); /* noise in output */ + + nmod_poly_mat_mul_classical(C, A, B); + nmod_poly_mat_mul_KS(D, A, B); + + if (!nmod_poly_mat_equal(C, D)) + { + flint_printf("FAIL:\n"); + flint_printf("products don't agree!\n"); + flint_printf("A:\n"); + nmod_poly_mat_print(A, "x"); + flint_printf("B:\n"); + nmod_poly_mat_print(B, "x"); + flint_printf("C:\n"); + nmod_poly_mat_print(C, "x"); + flint_printf("D:\n"); + nmod_poly_mat_print(D, "x"); + flint_printf("\n"); + abort(); + } + + nmod_poly_mat_clear(A); + nmod_poly_mat_clear(B); + nmod_poly_mat_clear(C); + nmod_poly_mat_clear(D); + } + + /* Check aliasing C and A */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_mat_t A, B, C; + slong m, n, deg; + mp_limb_t mod; + + mod = n_randtest_prime(state, 0); + m = n_randint(state, 20); + n = n_randint(state, 20); + deg = 1 + n_randint(state, 10); + + nmod_poly_mat_init(A, m, n, mod); + nmod_poly_mat_init(B, n, n, mod); + nmod_poly_mat_init(C, m, n, mod); + + nmod_poly_mat_randtest(A, state, deg); + nmod_poly_mat_randtest(B, state, deg); + nmod_poly_mat_randtest(C, state, deg); /* noise in output */ + + nmod_poly_mat_mul_KS(C, A, B); + nmod_poly_mat_mul_KS(A, A, B); + + if (!nmod_poly_mat_equal(C, A)) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"); + nmod_poly_mat_print(A, "x"); + flint_printf("B:\n"); + nmod_poly_mat_print(B, "x"); + flint_printf("C:\n"); + nmod_poly_mat_print(C, "x"); + flint_printf("\n"); + abort(); + } + + nmod_poly_mat_clear(A); + nmod_poly_mat_clear(B); + nmod_poly_mat_clear(C); + } + + /* Check aliasing C and B */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_mat_t A, B, C; + slong m, n, deg; + mp_limb_t mod; + + mod = n_randtest_prime(state, 0); + m = n_randint(state, 20); + n = n_randint(state, 20); + deg = 1 + n_randint(state, 10); + + nmod_poly_mat_init(A, m, m, mod); + nmod_poly_mat_init(B, m, n, mod); + nmod_poly_mat_init(C, m, n, mod); + + nmod_poly_mat_randtest(A, state, deg); + nmod_poly_mat_randtest(B, state, deg); + nmod_poly_mat_randtest(C, state, deg); /* noise in output */ + + nmod_poly_mat_mul_KS(C, A, B); + nmod_poly_mat_mul_KS(B, A, B); + + if (!nmod_poly_mat_equal(C, B)) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"); + nmod_poly_mat_print(A, "x"); + flint_printf("B:\n"); + nmod_poly_mat_print(B, "x"); + flint_printf("C:\n"); + nmod_poly_mat_print(C, "x"); + flint_printf("\n"); + abort(); + } + + nmod_poly_mat_clear(A); + nmod_poly_mat_clear(B); + nmod_poly_mat_clear(C); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly_mat/test/t-mul_interpolate.c b/external/flint-2.4.3/nmod_poly_mat/test/t-mul_interpolate.c new file mode 100644 index 0000000..87ad199 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/test/t-mul_interpolate.c @@ -0,0 +1,202 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_mat.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" +#include "fmpz.h" + +int +main(void) +{ + slong i; + + FLINT_TEST_INIT(state); + + flint_printf("mul_interpolate...."); + fflush(stdout); + + /* Check evaluation homomorphism */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_mat_t A, B, C; + nmod_mat_t a, b, c, d; + mp_limb_t mod, x; + slong m, n, k, deg; + + mod = n_randtest_prime(state, 0); + m = n_randint(state, 20); + n = n_randint(state, 20); + k = n_randint(state, 20); + deg = 1 + n_randint(state, 10); + + nmod_poly_mat_init(A, m, n, mod); + nmod_poly_mat_init(B, n, k, mod); + nmod_poly_mat_init(C, m, k, mod); + + nmod_mat_init(a, m, n, mod); + nmod_mat_init(b, n, k, mod); + nmod_mat_init(c, m, k, mod); + nmod_mat_init(d, m, k, mod); + + nmod_poly_mat_randtest(A, state, deg); + nmod_poly_mat_randtest(B, state, deg); + nmod_poly_mat_randtest(C, state, deg); /* noise in output */ + + if (nmod_poly_mat_max_length(A) + + nmod_poly_mat_max_length(B) - 1 <= mod) + { + nmod_poly_mat_mul_interpolate(C, A, B); + + x = n_randint(state, mod); + + nmod_poly_mat_evaluate_nmod(a, A, x); + nmod_poly_mat_evaluate_nmod(b, B, x); + nmod_poly_mat_evaluate_nmod(d, C, x); + nmod_mat_mul(c, a, b); + + if (!nmod_mat_equal(c, d)) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"); + nmod_poly_mat_print(A, "x"); + flint_printf("B:\n"); + nmod_poly_mat_print(B, "x"); + flint_printf("C:\n"); + nmod_poly_mat_print(C, "x"); + flint_printf("\n"); + abort(); + } + } + + nmod_poly_mat_clear(A); + nmod_poly_mat_clear(B); + nmod_poly_mat_clear(C); + + nmod_mat_clear(a); + nmod_mat_clear(b); + nmod_mat_clear(c); + nmod_mat_clear(d); + } + + /* Check aliasing C and A */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_mat_t A, B, C; + slong m, n, deg; + mp_limb_t mod; + + mod = n_randtest_prime(state, 0); + m = n_randint(state, 20); + n = n_randint(state, 20); + deg = 1 + n_randint(state, 10); + + nmod_poly_mat_init(A, m, n, mod); + nmod_poly_mat_init(B, n, n, mod); + nmod_poly_mat_init(C, m, n, mod); + + nmod_poly_mat_randtest(A, state, deg); + nmod_poly_mat_randtest(B, state, deg); + nmod_poly_mat_randtest(C, state, deg); /* noise in output */ + + if (nmod_poly_mat_max_length(A) + + nmod_poly_mat_max_length(B) - 1 <= mod) + { + + nmod_poly_mat_mul_interpolate(C, A, B); + nmod_poly_mat_mul_interpolate(A, A, B); + + if (!nmod_poly_mat_equal(C, A)) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"); + nmod_poly_mat_print(A, "x"); + flint_printf("B:\n"); + nmod_poly_mat_print(B, "x"); + flint_printf("C:\n"); + nmod_poly_mat_print(C, "x"); + flint_printf("\n"); + abort(); + } + } + + nmod_poly_mat_clear(A); + nmod_poly_mat_clear(B); + nmod_poly_mat_clear(C); + } + + /* Check aliasing C and B */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_mat_t A, B, C; + slong m, n, deg; + mp_limb_t mod; + + mod = n_randtest_prime(state, 0); + m = n_randint(state, 20); + n = n_randint(state, 20); + deg = 1 + n_randint(state, 10); + + nmod_poly_mat_init(A, m, m, mod); + nmod_poly_mat_init(B, m, n, mod); + nmod_poly_mat_init(C, m, n, mod); + + nmod_poly_mat_randtest(A, state, deg); + nmod_poly_mat_randtest(B, state, deg); + nmod_poly_mat_randtest(C, state, deg); /* noise in output */ + + if (nmod_poly_mat_max_length(A) + + nmod_poly_mat_max_length(B) - 1 <= mod) + { + nmod_poly_mat_mul_interpolate(C, A, B); + nmod_poly_mat_mul_interpolate(B, A, B); + + if (!nmod_poly_mat_equal(C, B)) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"); + nmod_poly_mat_print(A, "x"); + flint_printf("B:\n"); + nmod_poly_mat_print(B, "x"); + flint_printf("C:\n"); + nmod_poly_mat_print(C, "x"); + flint_printf("\n"); + abort(); + } + } + + nmod_poly_mat_clear(A); + nmod_poly_mat_clear(B); + nmod_poly_mat_clear(C); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly_mat/test/t-neg.c b/external/flint-2.4.3/nmod_poly_mat/test/t-neg.c new file mode 100644 index 0000000..3a76aa9 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/test/t-neg.c @@ -0,0 +1,130 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_mat.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" + +int +main(void) +{ + slong i; + + FLINT_TEST_INIT(state); + + flint_printf("neg...."); + fflush(stdout); + + /* Check evaluation homomorphism */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_mat_t A, B; + nmod_mat_t a, b, c; + mp_limb_t x, mod; + slong m, n, deg; + + mod = n_randtest_prime(state, 0); + m = n_randint(state, 20); + n = n_randint(state, 20); + deg = 1 + n_randint(state, 10); + + nmod_poly_mat_init(A, m, n, mod); + nmod_poly_mat_init(B, m, n, mod); + + nmod_mat_init(a, m, n, mod); + nmod_mat_init(b, m, n, mod); + nmod_mat_init(c, m, n, mod); + + nmod_poly_mat_randtest(A, state, deg); + nmod_poly_mat_neg(B, A); + + x = n_randint(state, mod); + + nmod_poly_mat_evaluate_nmod(a, A, x); + nmod_poly_mat_evaluate_nmod(b, B, x); + nmod_mat_neg(c, a); + + if (!nmod_mat_equal(b, c)) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"); + nmod_poly_mat_print(A, "x"); + flint_printf("B:\n"); + nmod_poly_mat_print(B, "x"); + flint_printf("\n"); + abort(); + } + + nmod_poly_mat_clear(A); + nmod_poly_mat_clear(B); + + nmod_mat_clear(a); + nmod_mat_clear(b); + nmod_mat_clear(c); + } + + /* Check aliasing B and A */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_mat_t A, B; + slong m, n, deg; + mp_limb_t mod; + + mod = n_randtest_prime(state, 0); + m = n_randint(state, 20); + n = n_randint(state, 20); + deg = 1 + n_randint(state, 10); + + nmod_poly_mat_init(A, m, n, mod); + nmod_poly_mat_init(B, m, n, mod); + + nmod_poly_mat_randtest(A, state, deg); + + nmod_poly_mat_neg(B, A); + nmod_poly_mat_neg(A, A); + + if (!nmod_poly_mat_equal(B, A)) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"); + nmod_poly_mat_print(A, "x"); + flint_printf("B:\n"); + nmod_poly_mat_print(B, "x"); + flint_printf("\n"); + abort(); + } + + nmod_poly_mat_clear(A); + nmod_poly_mat_clear(B); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly_mat/test/t-nullspace.c b/external/flint-2.4.3/nmod_poly_mat/test/t-nullspace.c new file mode 100644 index 0000000..ade3d49 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/test/t-nullspace.c @@ -0,0 +1,100 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" +#include "fmpz.h" + +int +main(void) +{ + slong i; + + FLINT_TEST_INIT(state); + + flint_printf("nullspace...."); + fflush(stdout); + + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + nmod_poly_mat_t A, N, AN; + slong n, m, deg, rank, nullity; + float density; + mp_limb_t mod; + + mod = n_randtest_prime(state, 0); + m = n_randint(state, 13); + n = n_randint(state, 13); + deg = 1 + n_randint(state, 5); + density = n_randint(state, 100) * 0.01; + + nmod_poly_mat_init(A, m, n, mod); + nmod_poly_mat_init(N, n, n, mod); + nmod_poly_mat_init(AN, m, n, mod); + + nmod_poly_mat_randtest_sparse(A, state, deg, density); + + rank = nmod_poly_mat_rank(A); + nullity = nmod_poly_mat_nullspace(N, A); + + if (nullity + rank != n) + { + flint_printf("FAIL: wrong nullity!\n"); + flint_printf("rank = %wd\n", rank); + flint_printf("nullity = %wd\n", nullity); + nmod_poly_mat_print(A, "x"); + flint_printf("\n"); + nmod_poly_mat_print(N, "x"); + flint_printf("\n"); + abort(); + } + + if (nmod_poly_mat_rank(N) != nullity) + { + flint_printf("FAIL: wrong rank(N) != nullity!\n"); + abort(); + } + + nmod_poly_mat_mul(AN, A, N); + + if (!nmod_poly_mat_is_zero(AN)) + { + flint_printf("FAIL: A * N != 0\n"); + abort(); + } + + nmod_poly_mat_clear(A); + nmod_poly_mat_clear(N); + nmod_poly_mat_clear(AN); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly_mat/test/t-one.c b/external/flint-2.4.3/nmod_poly_mat/test/t-one.c new file mode 100644 index 0000000..3e12e65 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/test/t-one.c @@ -0,0 +1,91 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_mat.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" +#include "fmpz.h" + +int +main(void) +{ + int iter; + + FLINT_TEST_INIT(state); + + flint_printf("one/is_one...."); + fflush(stdout); + + for (iter = 0; iter < 100 * flint_test_multiplier(); iter++) + { + nmod_poly_mat_t A; + slong m, n; + mp_limb_t mod; + + mod = n_randtest_prime(state, 0); + m = n_randint(state, 10); + n = n_randint(state, 10); + + nmod_poly_mat_init(A, m, n, mod); + nmod_poly_mat_randtest(A, state, n_randint(state, 5)); + nmod_poly_mat_one(A); + + if (!nmod_poly_mat_is_one(A)) + { + flint_printf("FAIL: expected matrix to be one\n"); + abort(); + } + + if (m > 0 && n > 0) + { + m = n_randint(state, m); + n = n_randint(state, n); + + if (m != n) + nmod_poly_randtest_not_zero(nmod_poly_mat_entry(A, m, n), + state, 5); + else + do { nmod_poly_randtest_not_zero(nmod_poly_mat_entry(A, m, n), + state, 5); } + while (nmod_poly_is_one(nmod_poly_mat_entry(A, m, n))); + + if (nmod_poly_mat_is_one(A)) + { + flint_printf("FAIL: expected matrix not to be one\n"); + abort(); + } + } + + nmod_poly_mat_clear(A); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly_mat/test/t-pow.c b/external/flint-2.4.3/nmod_poly_mat/test/t-pow.c new file mode 100644 index 0000000..1d0cb9a --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/test/t-pow.c @@ -0,0 +1,125 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_mat.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" + +int +main(void) +{ + slong i; + + FLINT_TEST_INIT(state); + + flint_printf("pow...."); + fflush(stdout); + + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_mat_t A, B, C; + slong m, j, exp, deg; + mp_limb_t mod; + + mod = n_randtest_prime(state, 0); + m = n_randint(state, 6); + deg = 1 + n_randint(state, 6); + exp = n_randint(state, 20); + + nmod_poly_mat_init(A, m, m, mod); + nmod_poly_mat_init(B, m, m, mod); + nmod_poly_mat_init(C, m, m, mod); + + nmod_poly_mat_randtest(A, state, deg); + + nmod_poly_mat_pow(B, A, exp); + + nmod_poly_mat_one(C); + for (j = 0; j < exp; j++) + nmod_poly_mat_mul(C, C, A); + + if (!nmod_poly_mat_equal(C, B)) + { + flint_printf("FAIL:\n"); + flint_printf("exp = %wd\n", exp); + flint_printf("A:\n"); + nmod_poly_mat_print(A, "x"); + flint_printf("B:\n"); + nmod_poly_mat_print(B, "x"); + flint_printf("C:\n"); + nmod_poly_mat_print(C, "x"); + flint_printf("\n"); + abort(); + } + + nmod_poly_mat_clear(A); + nmod_poly_mat_clear(B); + nmod_poly_mat_clear(C); + } + + /* Check aliasing B and A */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_mat_t A, B; + slong m, exp, deg; + mp_limb_t mod; + + mod = n_randtest_prime(state, 0); + m = n_randint(state, 6); + deg = 1 + n_randint(state, 6); + exp = n_randint(state, 20); + + nmod_poly_mat_init(A, m, m, mod); + nmod_poly_mat_init(B, m, m, mod); + + nmod_poly_mat_randtest(A, state, deg); + + nmod_poly_mat_pow(B, A, exp); + nmod_poly_mat_pow(A, A, exp); + + if (!nmod_poly_mat_equal(A, B)) + { + flint_printf("FAIL (aliasing)\n"); + flint_printf("exp = %wd\n", exp); + flint_printf("A:\n"); + nmod_poly_mat_print(A, "x"); + flint_printf("B:\n"); + nmod_poly_mat_print(B, "x"); + flint_printf("\n"); + abort(); + } + + nmod_poly_mat_clear(A); + nmod_poly_mat_clear(B); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly_mat/test/t-rank.c b/external/flint-2.4.3/nmod_poly_mat/test/t-rank.c new file mode 100644 index 0000000..f1587d7 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/test/t-rank.c @@ -0,0 +1,99 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_mat.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" +#include "fmpz.h" + +int +main(void) +{ + slong i; + + FLINT_TEST_INIT(state); + + flint_printf("rank...."); + fflush(stdout); + + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_mat_t A; + nmod_mat_t Ax; + mp_limb_t mod, x; + slong j, m, n, deg, rank, zrank; + float density; + + /* Don't pick a too small modulus, to avoid failure in + the probabilistic rank computation (todo: test + for small moduli) */ + do { + mod = n_randtest_prime(state, 0); + } while (mod < 20); + + m = n_randint(state, 15); + n = n_randint(state, 15); + deg = 1 + n_randint(state, 5); + density = n_randint(state, 100) * 0.01; + + nmod_poly_mat_init(A, m, n, mod); + nmod_mat_init(Ax, m, n, mod); + + nmod_poly_mat_randtest_sparse(A, state, deg, density); + + /* Probabilistic rank computation */ + zrank = 0; + for (j = 0; j < 5; j++) + { + slong r; + x = n_randint(state, mod); + nmod_poly_mat_evaluate_nmod(Ax, A, x); + r = nmod_mat_rank(Ax); + zrank = FLINT_MAX(zrank, r); + } + + rank = nmod_poly_mat_rank(A); + + if (rank != zrank) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"); + nmod_poly_mat_print(A, "x"); + flint_printf("Computed rank: %wd (zrank = %wd)\n", rank, zrank); + abort(); + } + + nmod_mat_clear(Ax); + nmod_poly_mat_clear(A); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly_mat/test/t-rref.c b/external/flint-2.4.3/nmod_poly_mat/test/t-rref.c new file mode 100644 index 0000000..2183f2a --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/test/t-rref.c @@ -0,0 +1,180 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010-2012 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_poly_mat.h" +#include "perm.h" +#include "ulong_extras.h" + +/* checks that the rref has the right form */ +int check_rref(const nmod_poly_mat_t A, const nmod_poly_t den, slong rank) +{ + slong i, j, k, prev_pivot; + + /* bottom should be zero */ + for (i = rank; i < A->r; i++) + for (j = 0; j < A->c; j++) + if (!nmod_poly_is_zero(nmod_poly_mat_entry(A, i, j))) + return 0; + + prev_pivot = -1; + + for (i = 0; i < rank; i++) + { + for (j = 0; j < A->c; j++) + { + if (!nmod_poly_is_zero(nmod_poly_mat_entry(A, i, j))) + { + /* pivot should have a higher column index than previous */ + if (j <= prev_pivot) + return 0; + + /* column should be 0 ... 0 1 0 ... 0 */ + for (k = 0; k < rank; k++) + { + if (i == k && !nmod_poly_equal(nmod_poly_mat_entry(A, k, j), den)) + return 0; + if (i != k && !nmod_poly_is_zero(nmod_poly_mat_entry(A, k, j))) + return 0; + } + + prev_pivot = j; + break; + } + } + } + + return 1; +} + +int +main(void) +{ + slong iter; + FLINT_TEST_INIT(state); + + flint_printf("rref...."); + fflush(stdout); + + + + for (iter = 0; iter < 1000 * flint_test_multiplier(); iter++) + { + nmod_poly_mat_t A, R, B, R2; + nmod_poly_t den, c, den2; + slong j, k, m, n, deg, rank1, rank2; + slong *perm; + float density; + int equal; + mp_limb_t p; + + m = n_randint(state, 10); + n = n_randint(state, 10); + deg = 1 + n_randint(state, 5); + density = n_randint(state, 100) * 0.01; + p = n_randtest_prime(state, 0); + + nmod_poly_mat_init(A, m, n, p); + nmod_poly_mat_init(R, m, n, p); + nmod_poly_mat_init(B, 2 * m, n, p); + nmod_poly_mat_init(R2, 2 * m, n, p); + + nmod_poly_init(c, p); + nmod_poly_init(den, p); + nmod_poly_init(den2, p); + + perm = _perm_init(2 * m); + + nmod_poly_mat_randtest_sparse(A, state, deg, density); + + rank1 = nmod_poly_mat_rref(R, den, A); + + check_rref(R, den, rank1); + + /* Concatenate the original matrix with the rref, scramble the rows, + and check that the rref is the same */ + _perm_randtest(perm, 2 * m, state); + + for (j = 0; j < m; j++) + { + nmod_poly_randtest_not_zero(c, state, deg); + for (k = 0; k < n; k++) + nmod_poly_mul(nmod_poly_mat_entry(B, perm[j], k), nmod_poly_mat_entry(A, j, k), c); + } + + for (j = 0; j < m; j++) + { + nmod_poly_randtest_not_zero(c, state, deg); + for (k = 0; k < n; k++) + nmod_poly_mul(nmod_poly_mat_entry(B, perm[m + j], k), nmod_poly_mat_entry(R, j, k), c); + } + + rank2 = nmod_poly_mat_rref(R2, den2, B); + equal = (rank1 == rank2); + + if (equal) + { + nmod_poly_mat_scalar_mul_nmod_poly(R, R, den2); + nmod_poly_mat_scalar_mul_nmod_poly(R2, R2, den); + + for (j = 0; j < rank2; j++) + for (k = 0; k < n; k++) + equal = equal && + nmod_poly_equal(nmod_poly_mat_entry(R, j, k), nmod_poly_mat_entry(R2, j, k)); + for (j = rank2; j < 2 * rank2; j++) + for (k = 0; k < n; k++) + equal = equal && nmod_poly_is_zero(nmod_poly_mat_entry(R2, j, k)); + } + + if (!equal) + { + flint_printf("FAIL (rank1 = %wd, rank2 = %wd)!\n", rank1, rank2); + nmod_poly_mat_print(A, "x"); flint_printf("\n\n"); + nmod_poly_mat_print(R, "x"); flint_printf("\n\n"); + nmod_poly_mat_print(R2, "x"); flint_printf("\n\n"); + abort(); + } + + nmod_poly_clear(c); + nmod_poly_clear(den); + nmod_poly_clear(den2); + + _perm_clear(perm); + + nmod_poly_mat_clear(A); + nmod_poly_mat_clear(R); + nmod_poly_mat_clear(B); + nmod_poly_mat_clear(R2); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} + diff --git a/external/flint-2.4.3/nmod_poly_mat/test/t-solve_fflu.c b/external/flint-2.4.3/nmod_poly_mat/test/t-solve_fflu.c new file mode 100644 index 0000000..5496f96 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/test/t-solve_fflu.c @@ -0,0 +1,142 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" +#include "fmpz.h" + +int +main(void) +{ + slong i; + + FLINT_TEST_INIT(state); + + flint_printf("solve...."); + fflush(stdout); + + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + nmod_poly_mat_t A, X, B, AX, Bden; + nmod_poly_t den, det; + slong n, m, deg; + float density; + int solved; + mp_limb_t mod; + + mod = n_randtest_prime(state, 0); + n = n_randint(state, 15); + m = n_randint(state, 5); + deg = 1 + n_randint(state, 5); + density = n_randint(state, 100) * 0.01; + + nmod_poly_mat_init(A, n, n, mod); + nmod_poly_mat_init(B, n, m, mod); + nmod_poly_mat_init(X, n, m, mod); + nmod_poly_mat_init(AX, n, m, mod); + nmod_poly_mat_init(Bden, n, m, mod); + nmod_poly_init(den, mod); + nmod_poly_init(det, mod); + + nmod_poly_mat_randtest_sparse(A, state, deg, density); + nmod_poly_mat_randtest_sparse(B, state, deg, density); + + solved = nmod_poly_mat_solve_fflu(X, den, A, B); + nmod_poly_mat_det_interpolate(det, A); + + if (m == 0 || n == 0) + { + if (solved == 0) + { + flint_printf("FAIL: expected empty system to pass\n"); + abort(); + } + } + else + { + if (!nmod_poly_equal(den, det)) + { + nmod_poly_neg(det, det); + if (!nmod_poly_equal(den, det)) + { + nmod_poly_neg(det, det); + flint_printf("FAIL: den != +/- det(A)\n"); + flint_printf("den:\n"); nmod_poly_print(den); + flint_printf("\n\n"); + flint_printf("det:\n"); nmod_poly_print(det); + flint_printf("\n\n"); + flint_printf("A:\n"); + nmod_poly_mat_print(A, "x"); + flint_printf("B:\n"); + nmod_poly_mat_print(B, "x"); + flint_printf("X:\n"); + nmod_poly_mat_print(X, "x"); + abort(); + } + } + } + + if (solved != !nmod_poly_is_zero(den)) + { + flint_printf("FAIL: return value does not match denominator\n"); + abort(); + } + + nmod_poly_mat_mul(AX, A, X); + nmod_poly_mat_scalar_mul_nmod_poly(Bden, B, den); + + if (!nmod_poly_mat_equal(AX, Bden)) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"); + nmod_poly_mat_print(A, "x"); + flint_printf("B:\n"); + nmod_poly_mat_print(B, "x"); + flint_printf("X:\n"); + nmod_poly_mat_print(X, "x"); + flint_printf("AX:\n"); + nmod_poly_mat_print(AX, "x"); + flint_printf("Bden:\n"); + nmod_poly_mat_print(Bden, "x"); + abort(); + } + + nmod_poly_clear(den); + nmod_poly_clear(det); + nmod_poly_mat_clear(A); + nmod_poly_mat_clear(B); + nmod_poly_mat_clear(X); + nmod_poly_mat_clear(AX); + nmod_poly_mat_clear(Bden); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly_mat/test/t-sqr.c b/external/flint-2.4.3/nmod_poly_mat/test/t-sqr.c new file mode 100644 index 0000000..172008f --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/test/t-sqr.c @@ -0,0 +1,132 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_mat.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" +#include "fmpz.h" + +int +main(void) +{ + slong i; + + FLINT_TEST_INIT(state); + + flint_printf("sqr...."); + fflush(stdout); + + /* Check evaluation homomorphism */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_mat_t A, C; + nmod_mat_t a, c, d; + mp_limb_t x, mod; + slong m, deg; + + mod = n_randtest_prime(state, 0); + m = n_randint(state, 20); + deg = 1 + n_randint(state, 10); + + nmod_poly_mat_init(A, m, m, mod); + nmod_poly_mat_init(C, m, m, mod); + + nmod_mat_init(a, m, m, mod); + nmod_mat_init(c, m, m, mod); + nmod_mat_init(d, m, m, mod); + + nmod_poly_mat_randtest(A, state, deg); + nmod_poly_mat_randtest(C, state, deg); /* noise in output */ + + nmod_poly_mat_sqr(C, A); + + x = n_randint(state, 0); + + nmod_poly_mat_evaluate_nmod(a, A, x); + nmod_poly_mat_evaluate_nmod(d, C, x); + nmod_mat_mul(c, a, a); + + if (!nmod_mat_equal(c, d)) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"); + nmod_poly_mat_print(A, "x"); + flint_printf("C:\n"); + nmod_poly_mat_print(C, "x"); + flint_printf("\n"); + abort(); + } + + nmod_poly_mat_clear(A); + nmod_poly_mat_clear(C); + + nmod_mat_clear(a); + nmod_mat_clear(c); + nmod_mat_clear(d); + } + + /* Check aliasing B and A */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_mat_t A, B; + slong m, deg; + mp_limb_t mod; + + mod = n_randtest_prime(state, 0); + m = n_randint(state, 20); + deg = 1 + n_randint(state, 10); + + nmod_poly_mat_init(A, m, m, mod); + nmod_poly_mat_init(B, m, m, mod); + + nmod_poly_mat_randtest(A, state, deg); + nmod_poly_mat_randtest(B, state, deg); /* noise in output */ + + nmod_poly_mat_sqr(B, A); + nmod_poly_mat_sqr(A, A); + + if (!nmod_poly_mat_equal(B, A)) + { + flint_printf("FAIL (aliasing):\n"); + flint_printf("A:\n"); + nmod_poly_mat_print(A, "x"); + flint_printf("B:\n"); + nmod_poly_mat_print(B, "x"); + flint_printf("\n"); + abort(); + } + + nmod_poly_mat_clear(A); + nmod_poly_mat_clear(B); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly_mat/test/t-sqr_KS.c b/external/flint-2.4.3/nmod_poly_mat/test/t-sqr_KS.c new file mode 100644 index 0000000..7130e68 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/test/t-sqr_KS.c @@ -0,0 +1,122 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" +#include "fmpz.h" + +int +main(void) +{ + slong i; + + FLINT_TEST_INIT(state); + + flint_printf("sqr_KS...."); + fflush(stdout); + + for (i = 0; i < 200 * flint_test_multiplier(); i++) + { + nmod_poly_mat_t A, B, C; + slong n, deg; + mp_limb_t mod; + + mod = n_randtest_prime(state, 0); + n = n_randint(state, 15); + deg = 1 + n_randint(state, 15); + + nmod_poly_mat_init(A, n, n, mod); + nmod_poly_mat_init(B, n, n, mod); + nmod_poly_mat_init(C, n, n, mod); + + nmod_poly_mat_randtest(A, state, deg); + nmod_poly_mat_randtest(B, state, deg); + nmod_poly_mat_randtest(C, state, deg); /* noise in output */ + + nmod_poly_mat_sqr_classical(B, A); + nmod_poly_mat_sqr_KS(C, A); + + if (!nmod_poly_mat_equal(B, C)) + { + flint_printf("FAIL:\n"); + flint_printf("products don't agree!\n"); + flint_printf("A:\n"); + nmod_poly_mat_print(A, "x"); + flint_printf("B:\n"); + nmod_poly_mat_print(B, "x"); + flint_printf("C:\n"); + nmod_poly_mat_print(C, "x"); + flint_printf("\n"); + abort(); + } + + nmod_poly_mat_clear(A); + nmod_poly_mat_clear(B); + nmod_poly_mat_clear(C); + } + + /* Check aliasing B and A */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_mat_t A, B; + slong m, deg; + mp_limb_t mod; + + mod = n_randtest_prime(state, 0); + m = n_randint(state, 20); + deg = 1 + n_randint(state, 10); + + nmod_poly_mat_init(A, m, m, mod); + nmod_poly_mat_init(B, m, m, mod); + + nmod_poly_mat_randtest(A, state, deg); + nmod_poly_mat_randtest(B, state, deg); /* noise in output */ + + nmod_poly_mat_sqr_KS(B, A); + nmod_poly_mat_sqr_KS(A, A); + + if (!nmod_poly_mat_equal(B, A)) + { + flint_printf("FAIL (aliasing):\n"); + flint_printf("A:\n"); + nmod_poly_mat_print(A, "x"); + flint_printf("B:\n"); + nmod_poly_mat_print(B, "x"); + flint_printf("\n"); + abort(); + } + + nmod_poly_mat_clear(A); + nmod_poly_mat_clear(B); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly_mat/test/t-sqr_interpolate.c b/external/flint-2.4.3/nmod_poly_mat/test/t-sqr_interpolate.c new file mode 100644 index 0000000..0016743 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/test/t-sqr_interpolate.c @@ -0,0 +1,138 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_mat.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" +#include "fmpz.h" + +int +main(void) +{ + slong i; + + FLINT_TEST_INIT(state); + + flint_printf("sqr_interpolate...."); + fflush(stdout); + + /* Check evaluation homomorphism */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_mat_t A, C; + nmod_mat_t a, c, d; + mp_limb_t x, mod; + slong m, deg; + + mod = n_randtest_prime(state, 0); + m = n_randint(state, 20); + deg = 1 + n_randint(state, 10); + + nmod_poly_mat_init(A, m, m, mod); + nmod_poly_mat_init(C, m, m, mod); + + nmod_mat_init(a, m, m, mod); + nmod_mat_init(c, m, m, mod); + nmod_mat_init(d, m, m, mod); + + nmod_poly_mat_randtest(A, state, deg); + nmod_poly_mat_randtest(C, state, deg); /* noise in output */ + + if (2 * nmod_poly_mat_max_length(A) - 1 <= mod) + { + nmod_poly_mat_sqr_interpolate(C, A); + + x = n_randint(state, 0); + + nmod_poly_mat_evaluate_nmod(a, A, x); + nmod_poly_mat_evaluate_nmod(d, C, x); + nmod_mat_mul(c, a, a); + + if (!nmod_mat_equal(c, d)) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"); + nmod_poly_mat_print(A, "x"); + flint_printf("C:\n"); + nmod_poly_mat_print(C, "x"); + flint_printf("\n"); + abort(); + } + } + + nmod_poly_mat_clear(A); + nmod_poly_mat_clear(C); + + nmod_mat_clear(a); + nmod_mat_clear(c); + nmod_mat_clear(d); + } + + /* Check aliasing B and A */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_mat_t A, B; + slong m, deg; + mp_limb_t mod; + + mod = n_randtest_prime(state, 0); + m = n_randint(state, 20); + deg = 1 + n_randint(state, 10); + + nmod_poly_mat_init(A, m, m, mod); + nmod_poly_mat_init(B, m, m, mod); + + nmod_poly_mat_randtest(A, state, deg); + nmod_poly_mat_randtest(B, state, deg); /* noise in output */ + + if (2 * nmod_poly_mat_max_length(A) - 1 <= mod) + { + nmod_poly_mat_sqr_interpolate(B, A); + nmod_poly_mat_sqr_interpolate(A, A); + + if (!nmod_poly_mat_equal(B, A)) + { + flint_printf("FAIL (aliasing):\n"); + flint_printf("A:\n"); + nmod_poly_mat_print(A, "x"); + flint_printf("B:\n"); + nmod_poly_mat_print(B, "x"); + flint_printf("\n"); + abort(); + } + } + + nmod_poly_mat_clear(A); + nmod_poly_mat_clear(B); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly_mat/test/t-sub.c b/external/flint-2.4.3/nmod_poly_mat/test/t-sub.c new file mode 100644 index 0000000..c7e9a11 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/test/t-sub.c @@ -0,0 +1,183 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_mat.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" + +int +main(void) +{ + slong i; + + FLINT_TEST_INIT(state); + + flint_printf("sub...."); + fflush(stdout); + + /* Check evaluation homomorphism */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_mat_t A, B, C; + nmod_mat_t a, b, c, d; + mp_limb_t mod, x; + slong m, n, deg; + + m = n_randint(state, 20); + n = n_randint(state, 20); + deg = 1 + n_randint(state, 10); + mod = n_randtest_prime(state, 0); + + nmod_poly_mat_init(A, m, n, mod); + nmod_poly_mat_init(B, m, n, mod); + nmod_poly_mat_init(C, m, n, mod); + + nmod_mat_init(a, m, n, mod); + nmod_mat_init(b, m, n, mod); + nmod_mat_init(c, m, n, mod); + nmod_mat_init(d, m, n, mod); + + nmod_poly_mat_randtest(A, state, deg); + nmod_poly_mat_randtest(B, state, deg); + nmod_poly_mat_sub(C, A, B); + + x = n_randint(state, mod); + + nmod_poly_mat_evaluate_nmod(a, A, x); + nmod_poly_mat_evaluate_nmod(b, B, x); + nmod_poly_mat_evaluate_nmod(d, C, x); + nmod_mat_sub(c, a, b); + + if (!nmod_mat_equal(c, d)) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"); + nmod_poly_mat_print(A, "x"); + flint_printf("B:\n"); + nmod_poly_mat_print(B, "x"); + flint_printf("C:\n"); + nmod_poly_mat_print(C, "x"); + flint_printf("\n"); + abort(); + } + + nmod_poly_mat_clear(A); + nmod_poly_mat_clear(B); + nmod_poly_mat_clear(C); + + nmod_mat_clear(a); + nmod_mat_clear(b); + nmod_mat_clear(c); + nmod_mat_clear(d); + } + + /* Check aliasing C and A */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_mat_t A, B, C; + slong m, n, deg; + mp_limb_t mod; + + mod = n_randtest_prime(state, 0); + m = n_randint(state, 20); + n = n_randint(state, 20); + deg = 1 + n_randint(state, 10); + + nmod_poly_mat_init(A, m, n, mod); + nmod_poly_mat_init(B, m, n, mod); + nmod_poly_mat_init(C, m, n, mod); + + nmod_poly_mat_randtest(A, state, deg); + nmod_poly_mat_randtest(B, state, deg); + + nmod_poly_mat_sub(C, A, B); + nmod_poly_mat_sub(A, A, B); + + if (!nmod_poly_mat_equal(C, A)) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"); + nmod_poly_mat_print(A, "x"); + flint_printf("B:\n"); + nmod_poly_mat_print(B, "x"); + flint_printf("C:\n"); + nmod_poly_mat_print(C, "x"); + flint_printf("\n"); + abort(); + } + + nmod_poly_mat_clear(A); + nmod_poly_mat_clear(B); + nmod_poly_mat_clear(C); + } + + /* Check aliasing C and B */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_mat_t A, B, C; + slong m, n, deg; + mp_limb_t mod; + + mod = n_randtest_prime(state, 0); + m = n_randint(state, 20); + n = n_randint(state, 20); + deg = 1 + n_randint(state, 10); + + nmod_poly_mat_init(A, m, n, mod); + nmod_poly_mat_init(B, m, n, mod); + nmod_poly_mat_init(C, m, n, mod); + + nmod_poly_mat_randtest(A, state, deg); + nmod_poly_mat_randtest(B, state, deg); + + nmod_poly_mat_sub(C, A, B); + nmod_poly_mat_sub(B, A, B); + + if (!nmod_poly_mat_equal(C, B)) + { + flint_printf("FAIL:\n"); + flint_printf("A:\n"); + nmod_poly_mat_print(A, "x"); + flint_printf("B:\n"); + nmod_poly_mat_print(B, "x"); + flint_printf("C:\n"); + nmod_poly_mat_print(C, "x"); + flint_printf("\n"); + abort(); + } + + nmod_poly_mat_clear(A); + nmod_poly_mat_clear(B); + nmod_poly_mat_clear(C); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly_mat/test/t-trace.c b/external/flint-2.4.3/nmod_poly_mat/test/t-trace.c new file mode 100644 index 0000000..dc8c1c5 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/test/t-trace.c @@ -0,0 +1,99 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" +#include "ulong_extras.h" + +int +main(void) +{ + slong i; + FLINT_TEST_INIT(state); + + flint_printf("trace...."); + fflush(stdout); + + + + /* Test trace(AB) = trace(BA) */ + for (i = 0; i < 100 * flint_test_multiplier(); i++) + { + nmod_poly_mat_t A, B, AB, BA; + nmod_poly_t trab, trba; + mp_limb_t mod; + slong m, n; + + mod = n_randtest_prime(state, 0); + m = n_randint(state, 10); + n = n_randint(state, 10); + + nmod_poly_mat_init(A, m, n, mod); + nmod_poly_mat_init(B, n, m, mod); + nmod_poly_mat_init(AB, m, m, mod); + nmod_poly_mat_init(BA, n, n, mod); + + nmod_poly_init(trab, mod); + nmod_poly_init(trba, mod); + + nmod_poly_mat_randtest(A, state, 1 + n_randint(state, 10)); + nmod_poly_mat_randtest(B, state, 1 + n_randint(state, 10)); + + nmod_poly_mat_mul(AB, A, B); + nmod_poly_mat_mul(BA, B, A); + + nmod_poly_mat_trace(trab, AB); + nmod_poly_mat_trace(trba, BA); + + if (!nmod_poly_equal(trab, trba)) + { + flint_printf("FAIL:\n"); + nmod_poly_mat_print(A, "x"), flint_printf("\n"); + nmod_poly_mat_print(B, "x"), flint_printf("\n"); + nmod_poly_mat_print(AB, "x"), flint_printf("\n"); + nmod_poly_mat_print(BA, "x"), flint_printf("\n"); + flint_printf("tr(AB): "), nmod_poly_print(trab), flint_printf("\n"); + flint_printf("tr(BA): "), nmod_poly_print(trba), flint_printf("\n"); + abort(); + } + + nmod_poly_mat_clear(A); + nmod_poly_mat_clear(B); + nmod_poly_mat_clear(AB); + nmod_poly_mat_clear(BA); + nmod_poly_clear(trab); + nmod_poly_clear(trba); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly_mat/test/t-zero.c b/external/flint-2.4.3/nmod_poly_mat/test/t-zero.c new file mode 100644 index 0000000..91d4c0d --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/test/t-zero.c @@ -0,0 +1,83 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_mat.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" + +int +main(void) +{ + int iter; + + FLINT_TEST_INIT(state); + + flint_printf("zero/is_zero...."); + fflush(stdout); + + for (iter = 0; iter < 100 * flint_test_multiplier(); iter++) + { + nmod_poly_mat_t A; + slong m, n; + mp_limb_t mod; + + mod = n_randtest_prime(state, 0); + m = n_randint(state, 10); + n = n_randint(state, 10); + + nmod_poly_mat_init(A, m, n, mod); + nmod_poly_mat_randtest(A, state, n_randint(state, 5)); + nmod_poly_mat_zero(A); + + if (!nmod_poly_mat_is_zero(A)) + { + flint_printf("FAIL: expected matrix to be zero\n"); + abort(); + } + + if (m > 0 && n > 0) + { + m = n_randint(state, m); + n = n_randint(state, n); + nmod_poly_randtest_not_zero(nmod_poly_mat_entry(A, m, n), state, 5); + + if (nmod_poly_mat_is_zero(A)) + { + flint_printf("FAIL: expected matrix not to be zero\n"); + abort(); + } + } + + nmod_poly_mat_clear(A); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_poly_mat/trace.c b/external/flint-2.4.3/nmod_poly_mat/trace.c new file mode 100644 index 0000000..50a6c7c --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/trace.c @@ -0,0 +1,43 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "flint.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" + +void +nmod_poly_mat_trace(nmod_poly_t trace, const nmod_poly_mat_t mat) +{ + slong i, n = nmod_poly_mat_nrows(mat); + + if (n == 0) + nmod_poly_zero(trace); + else + { + nmod_poly_set(trace, nmod_poly_mat_entry(mat, 0, 0)); + for (i = 1; i < n; i++) + nmod_poly_add(trace, trace, nmod_poly_mat_entry(mat, i, i)); + } +} diff --git a/external/flint-2.4.3/nmod_poly_mat/zero.c b/external/flint-2.4.3/nmod_poly_mat/zero.c new file mode 100644 index 0000000..275cbb3 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_mat/zero.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "nmod_poly.h" +#include "nmod_poly_mat.h" + +void +nmod_poly_mat_zero(nmod_poly_mat_t A) +{ + slong i, j; + + for (i = 0; i < A->r; i++) + for (j = 0; j < A->c; j++) + nmod_poly_zero(nmod_poly_mat_entry(A, i, j)); +} diff --git a/external/flint-2.4.3/nmod_poly_matxx.h b/external/flint-2.4.3/nmod_poly_matxx.h new file mode 100644 index 0000000..43e7037 --- /dev/null +++ b/external/flint-2.4.3/nmod_poly_matxx.h @@ -0,0 +1,412 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#ifndef NMOD_POLY_MATXX_H +#define NMOD_POLY_MATXX_H + +#include "nmod_poly_mat.h" + +#include "nmod_matxx.h" +#include "nmod_polyxx.h" +#include "permxx.h" + +#include "flintxx/matrix.h" +#include "flintxx/stdmath.h" + +// NOTE: it is *not* valid to use empty nmod_poly_matxx matrices! +// TODO nullspace member + +namespace flint { +FLINT_DEFINE_UNOP(sqr_interpolate) +FLINT_DEFINE_BINOP(mul_interpolate) + +namespace detail { +template +struct nmod_poly_matxx_traits : matrices::generic_traits { }; +} // detail + +template +class nmod_poly_matxx_expression + : public expression, Operation, Data> +{ +public: + typedef expression, + Operation, Data> base_t; + typedef detail::nmod_poly_matxx_traits traits_t; + + FLINTXX_DEFINE_BASICS(nmod_poly_matxx_expression) + FLINTXX_DEFINE_CTORS(nmod_poly_matxx_expression) + FLINTXX_DEFINE_C_REF(nmod_poly_matxx_expression, nmod_poly_mat_struct, _mat) + + // These only make sense with immediates + nmodxx_ctx_srcref _ctx() const + { + return nmodxx_ctx_srcref::make(nmod_poly_mat_entry(_mat(), 0, 0)->mod); + } + + // These work on any expression without evaluation + nmodxx_ctx_srcref estimate_ctx() const + { + return tools::find_nmodxx_ctx(*this); + } + mp_limb_t modulus() const {return estimate_ctx().n();} + + template + static evaluated_t create_temporary_rowscols( + const Expr& e, slong rows, slong cols) + { + return evaluated_t(rows, cols, tools::find_nmodxx_ctx(e).n()); + } + FLINTXX_DEFINE_MATRIX_METHODS(traits_t) + + FLINTXX_DEFINE_FORWARD_STATIC(from_ground) + + static nmod_poly_matxx_expression randtest(slong rows, slong cols, + mp_limb_t M, frandxx& state, slong len) + { + nmod_poly_matxx_expression res(rows, cols, M); + res.set_randtest(state, len); + return res; + } + static nmod_poly_matxx_expression randtest_sparse(slong rows, slong cols, + mp_limb_t M, frandxx& state, slong len, float density) + { + nmod_poly_matxx_expression res(rows, cols, M); + res.set_randtest_sparse(state, len, density); + return res; + } + + static nmod_poly_matxx_expression zero(slong rows, slong cols, mp_limb_t n) + {return nmod_poly_matxx_expression(rows, cols, n);} + static nmod_poly_matxx_expression one(slong rows, slong cols, mp_limb_t n) + { + nmod_poly_matxx_expression res(rows, cols, n); + res.set_one(); + return res; + } + + // these only make sense with targets + void set_randtest(frandxx& state, slong len) + {nmod_poly_mat_randtest(_mat(), state._data(), len);} + void set_randtest_sparse(frandxx& state, slong len, float density) + {nmod_poly_mat_randtest_sparse(_mat(), state._data(), len, density);} + void set_zero() {nmod_poly_mat_zero(_mat());} + void set_one() {nmod_poly_mat_one(_mat());} + + // these cause evaluation + bool is_zero() const + {return nmod_poly_mat_is_zero(this->evaluate()._mat());} + bool is_one() const + {return nmod_poly_mat_is_one(this->evaluate()._mat());} + bool is_square() const + {return nmod_poly_mat_is_square(this->evaluate()._mat());} + bool is_empty() const + {return nmod_poly_mat_is_empty(this->evaluate()._mat());} + slong max_length() const + {return nmod_poly_mat_max_length(this->evaluate()._mat());} + slong rank() const {return nmod_poly_mat_rank(this->evaluate()._mat());} + slong find_pivot_any(slong start, slong end, slong c) const + { + return nmod_poly_mat_find_pivot_any( + this->evaluate()._mat(), start, end, c); + } + slong find_pivot_partial(slong start, slong end, slong c) const + { + return nmod_poly_mat_find_pivot_partial( + this->evaluate()._mat(), start, end, c); + } + + // lazy members + FLINTXX_DEFINE_MEMBER_UNOP_RTYPE(nmod_polyxx, det) + FLINTXX_DEFINE_MEMBER_UNOP_RTYPE(nmod_polyxx, det_fflu) + FLINTXX_DEFINE_MEMBER_UNOP_RTYPE(nmod_polyxx, det_interpolate) + FLINTXX_DEFINE_MEMBER_UNOP_RTYPE(nmod_polyxx, trace) + FLINTXX_DEFINE_MEMBER_UNOP(sqr) + FLINTXX_DEFINE_MEMBER_UNOP(sqr_classical) + FLINTXX_DEFINE_MEMBER_UNOP(sqr_interpolate) + FLINTXX_DEFINE_MEMBER_UNOP(sqr_KS) + FLINTXX_DEFINE_MEMBER_UNOP(transpose) + //FLINTXX_DEFINE_MEMBER_UNOP_RTYPE(???, nullspace) // TODO + FLINTXX_DEFINE_MEMBER_BINOP_(operator(), compeval) + FLINTXX_DEFINE_MEMBER_BINOP(solve) + FLINTXX_DEFINE_MEMBER_BINOP(solve_fflu) + FLINTXX_DEFINE_MEMBER_BINOP(mul_classical) + FLINTXX_DEFINE_MEMBER_BINOP(mul_interpolate) + FLINTXX_DEFINE_MEMBER_BINOP(mul_KS) + FLINTXX_DEFINE_MEMBER_BINOP(pow) + + //FLINTXX_DEFINE_MEMBER_UNOP_RTYPE(???, rref) // TODO + + FLINTXX_DEFINE_MEMBER_FFLU +}; + +namespace detail { +struct nmod_poly_mat_data; +} // detail + +typedef nmod_poly_matxx_expression< + operations::immediate, detail::nmod_poly_mat_data> nmod_poly_matxx; +typedef nmod_poly_matxx_expression > nmod_poly_matxx_ref; +typedef nmod_poly_matxx_expression > nmod_poly_matxx_srcref; + +template<> +struct matrix_traits +{ + template static slong rows(const M& m) + { + return nmod_poly_mat_nrows(m._mat()); + } + template static slong cols(const M& m) + { + return nmod_poly_mat_ncols(m._mat()); + } + + template static nmod_polyxx_srcref at(const M& m, slong i, slong j) + { + return nmod_polyxx_srcref::make(nmod_poly_mat_entry(m._mat(), i, j)); + } + template static nmod_polyxx_ref at(M& m, slong i, slong j) + { + return nmod_polyxx_ref::make(nmod_poly_mat_entry(m._mat(), i, j)); + } +}; + +namespace traits { +template<> struct has_nmodxx_ctx : mp::true_ { }; +template<> struct has_nmodxx_ctx : mp::true_ { }; +template<> struct has_nmodxx_ctx : mp::true_ { }; +} // traits + +namespace detail { +template<> +struct nmod_poly_matxx_traits + : matrices::generic_traits_srcref { }; +template<> +struct nmod_poly_matxx_traits + : matrices::generic_traits_ref { }; +template<> struct nmod_poly_matxx_traits + : matrices::generic_traits_nonref { }; + +struct nmod_poly_mat_data +{ + typedef nmod_poly_mat_t& data_ref_t; + typedef const nmod_poly_mat_t& data_srcref_t; + + nmod_poly_mat_t inner; + + nmod_poly_mat_data(slong m, slong n, mp_limb_t modulus) + { + nmod_poly_mat_init(inner, m, n, modulus); + } + + nmod_poly_mat_data(const nmod_poly_mat_data& o) + { + nmod_poly_mat_init_set(inner, o.inner); + } + + nmod_poly_mat_data(nmod_poly_matxx_srcref o) + { + nmod_poly_mat_init_set(inner, o._data().inner); + } + + ~nmod_poly_mat_data() {nmod_poly_mat_clear(inner);} + + template + static nmod_poly_mat_data _from_ground(const Nmod_mat& m) + { + nmod_poly_mat_data res(m.rows(), m.cols(), m.modulus()); + for(slong i = 0;i < m.rows();++i) + for(slong j = 0;j < m.cols();++j) + nmod_poly_set_coeff_ui(nmod_poly_mat_entry(res.inner, i, j), 0, + nmod_mat_entry(m._mat(), i, j)); + return res; + } + template + static nmod_poly_mat_data from_ground(const Nmod_mat& m, + typename mp::enable_if >::type* = 0) + { + return _from_ground(m.evaluate()); + } +}; +} // detail + +// temporary instantiation stuff +FLINTXX_DEFINE_TEMPORARY_RULES(nmod_poly_matxx) + +#define NMOD_POLY_MATXX_COND_S FLINTXX_COND_S(nmod_poly_matxx) +#define NMOD_POLY_MATXX_COND_T FLINTXX_COND_T(nmod_poly_matxx) + +namespace rules { +FLINT_DEFINE_DOIT_COND2(assignment, NMOD_POLY_MATXX_COND_T, NMOD_POLY_MATXX_COND_S, + nmod_poly_mat_set(to._mat(), from._mat())) + +FLINTXX_DEFINE_SWAP(nmod_poly_matxx, nmod_poly_mat_swap(e1._mat(), e2._mat())) + +FLINTXX_DEFINE_EQUALS(nmod_poly_matxx, nmod_poly_mat_equal(e1._mat(), e2._mat())) + +FLINT_DEFINE_PRINT_PRETTY_COND_2(NMOD_POLY_MATXX_COND_S, const char*, + (nmod_poly_mat_print(from._mat(), extra), 1)) + +FLINT_DEFINE_THREEARY_EXPR_COND3(mat_at_op, nmod_polyxx, + NMOD_POLY_MATXX_COND_S, traits::fits_into_slong, traits::fits_into_slong, + nmod_poly_set(to._poly(), nmod_poly_mat_entry(e1._mat(), e2, e3))) + +FLINT_DEFINE_BINARY_EXPR_COND2(times, nmod_poly_matxx, + NMOD_POLY_MATXX_COND_S, NMOD_POLY_MATXX_COND_S, + nmod_poly_mat_mul(to._mat(), e1._mat(), e2._mat())) +FLINT_DEFINE_CBINARY_EXPR_COND2(times, nmod_poly_matxx, + NMOD_POLY_MATXX_COND_S, NMOD_POLYXX_COND_S, + nmod_poly_mat_scalar_mul_nmod_poly(to._mat(), e1._mat(), e2._poly())) +FLINT_DEFINE_CBINARY_EXPR_COND2(times, nmod_poly_matxx, + NMOD_POLY_MATXX_COND_S, NMODXX_COND_S, + nmod_poly_mat_scalar_mul_nmod(to._mat(), e1._mat(), e2._limb())) + +FLINT_DEFINE_BINARY_EXPR_COND2(plus, nmod_poly_matxx, + NMOD_POLY_MATXX_COND_S, NMOD_POLY_MATXX_COND_S, + nmod_poly_mat_add(to._mat(), e1._mat(), e2._mat())) +FLINT_DEFINE_BINARY_EXPR_COND2(minus, nmod_poly_matxx, + NMOD_POLY_MATXX_COND_S, NMOD_POLY_MATXX_COND_S, + nmod_poly_mat_sub(to._mat(), e1._mat(), e2._mat())) + +FLINT_DEFINE_UNARY_EXPR_COND(negate, nmod_poly_matxx, NMOD_POLY_MATXX_COND_S, + nmod_poly_mat_neg(to._mat(), from._mat())) + +namespace rdetail { +inline void nmod_poly_mat_transpose(nmod_poly_mat_t to, + const nmod_poly_mat_t from) +{ + if(from == to) // guaranteed to be square + { + for(slong i = 0;i < nmod_poly_mat_nrows(to) - 1;++i) + for(slong j = i + 1;j < nmod_poly_mat_ncols(to);++j) + nmod_poly_swap(nmod_poly_mat_entry(to, i, j), + nmod_poly_mat_entry(to, j, i)); + } + else + { + for(slong i = 0;i < nmod_poly_mat_nrows(to);++i) + for(slong j = 0;j < nmod_poly_mat_ncols(to);++j) + nmod_poly_set(nmod_poly_mat_entry(to, i, j), + nmod_poly_mat_entry(from, j, i)); + } +} +} +// TODO update this when nmod_poly_mat has transpose +FLINT_DEFINE_UNARY_EXPR_COND(transpose_op, nmod_poly_matxx, NMOD_POLY_MATXX_COND_S, + rdetail::nmod_poly_mat_transpose(to._mat(), from._mat())) +FLINT_DEFINE_UNARY_EXPR_COND(trace_op, nmod_polyxx, NMOD_POLY_MATXX_COND_S, + nmod_poly_mat_trace(to._poly(), from._mat())) + +FLINT_DEFINE_BINARY_EXPR_COND2(evaluate_op, nmod_matxx, + NMOD_POLY_MATXX_COND_S, NMODXX_COND_S, + nmod_poly_mat_evaluate_nmod(to._mat(), e1._mat(), e2._limb())) + +#define NMOD_POLY_MATXX_DEFINE_MUL(name) \ +FLINT_DEFINE_BINARY_EXPR_COND2(name##_op, nmod_poly_matxx, \ + NMOD_POLY_MATXX_COND_S, NMOD_POLY_MATXX_COND_S, \ + nmod_poly_mat_##name(to._mat(), e1._mat(), e2._mat())) +NMOD_POLY_MATXX_DEFINE_MUL(mul_classical) +NMOD_POLY_MATXX_DEFINE_MUL(mul_KS) +NMOD_POLY_MATXX_DEFINE_MUL(mul_interpolate) + +FLINT_DEFINE_UNARY_EXPR_COND(sqr_op, nmod_poly_matxx, NMOD_POLY_MATXX_COND_S, + nmod_poly_mat_sqr(to._mat(), from._mat())) +FLINT_DEFINE_UNARY_EXPR_COND(sqr_KS_op, nmod_poly_matxx, NMOD_POLY_MATXX_COND_S, + nmod_poly_mat_sqr_KS(to._mat(), from._mat())) +FLINT_DEFINE_UNARY_EXPR_COND(sqr_classical_op, nmod_poly_matxx, + NMOD_POLY_MATXX_COND_S, + nmod_poly_mat_sqr_classical(to._mat(), from._mat())) +FLINT_DEFINE_UNARY_EXPR_COND(sqr_interpolate_op, nmod_poly_matxx, + NMOD_POLY_MATXX_COND_S, + nmod_poly_mat_sqr_interpolate(to._mat(), from._mat())) + +FLINT_DEFINE_BINARY_EXPR_COND2(pow_op, nmod_poly_matxx, + NMOD_POLY_MATXX_COND_S, traits::is_unsigned_integer, + nmod_poly_mat_pow(to._mat(), e1._mat(), e2)) + +FLINT_DEFINE_UNARY_EXPR_COND(det_op, nmod_polyxx, NMOD_POLY_MATXX_COND_S, + nmod_poly_mat_det(to._poly(), from._mat())) +FLINT_DEFINE_UNARY_EXPR_COND(det_fflu_op, nmod_polyxx, NMOD_POLY_MATXX_COND_S, + nmod_poly_mat_det_fflu(to._poly(), from._mat())) +FLINT_DEFINE_UNARY_EXPR_COND(det_interpolate_op, nmod_polyxx, + NMOD_POLY_MATXX_COND_S, + nmod_poly_mat_det_interpolate(to._poly(), from._mat())) + +namespace rdetail { +typedef make_ltuple::type >::type + nmod_poly_mat_inv_rt; +} // rdetail + +FLINT_DEFINE_UNARY_EXPR_COND(inv_op, rdetail::nmod_poly_mat_inv_rt, + NMOD_POLY_MATXX_COND_S, + to.template get<0>() = nmod_poly_mat_inv(to.template get<1>()._mat(), + to.template get<2>()._poly(), from._mat())) + +namespace rdetail { +typedef make_ltuple::type >::type + nmod_poly_mat_nullspace_rt; +} // rdetail +FLINT_DEFINE_UNARY_EXPR_COND(nullspace_op, rdetail::nmod_poly_mat_nullspace_rt, + NMOD_POLY_MATXX_COND_S, to.template get<0>() = nmod_poly_mat_nullspace( + to.template get<1>()._mat(), from._mat())) + +FLINT_DEFINE_BINARY_EXPR_COND2(solve_op, rdetail::nmod_poly_mat_inv_rt, + NMOD_POLY_MATXX_COND_S, NMOD_POLY_MATXX_COND_S, + to.template get<0>() = nmod_poly_mat_solve(to.template get<1>()._mat(), + to.template get<2>()._poly(), e1._mat(), e2._mat())) +FLINT_DEFINE_BINARY_EXPR_COND2(solve_fflu_op, rdetail::nmod_poly_mat_inv_rt, + NMOD_POLY_MATXX_COND_S, NMOD_POLY_MATXX_COND_S, + to.template get<0>() = nmod_poly_mat_solve_fflu( + to.template get<1>()._mat(), + to.template get<2>()._poly(), e1._mat(), e2._mat())) + +namespace rdetail { +typedef make_ltuple::type>::type + nmod_poly_matxx_fflu_rt; +} // rdetail + +FLINT_DEFINE_THREEARY_EXPR_COND3(fflu_op, rdetail::nmod_poly_matxx_fflu_rt, + NMOD_POLY_MATXX_COND_S, traits::is_maybe_perm, tools::is_bool, + to.template get<0>() = nmod_poly_mat_fflu(to.template get<1>()._mat(), + to.template get<2>()._poly(), maybe_perm_data(e2), e1._mat(), e3)) + +FLINT_DEFINE_UNARY_EXPR_COND(rref_op, rdetail::nmod_poly_matxx_fflu_rt, + NMOD_POLY_MATXX_COND_S, + to.template get<0>() = nmod_poly_mat_rref(to.template get<1>()._mat(), + to.template get<2>()._poly(), from._mat())) + +FLINT_DEFINE_THREEARY_EXPR_COND3(solve_fflu_precomp_op, nmod_poly_matxx, + traits::is_permxx, NMOD_POLY_MATXX_COND_S, NMOD_POLY_MATXX_COND_S, + nmod_poly_mat_solve_fflu_precomp(to._mat(), e1._data(), + e2._mat(), e3._mat())) +} // rules +} // flint + +#endif diff --git a/external/flint-2.4.3/nmod_polyxx.h b/external/flint-2.4.3/nmod_polyxx.h new file mode 100644 index 0000000..e293011 --- /dev/null +++ b/external/flint-2.4.3/nmod_polyxx.h @@ -0,0 +1,935 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#ifndef NMOD_POLYXX_H +#define NMOD_POLYXX_H + +#include +#include + +#include "nmod_poly.h" + +#include "fmpzxx.h" +#include "nmod_vecxx.h" +#include "fmpz_polyxx.h" +#include "fmpq_polyxx.h" + +#include "flintxx/expression.h" +#include "flintxx/ltuple.h" +#include "flintxx/flint_classes.h" +#include "flintxx/flint_exception.h" +#include "flintxx/frandxx.h" +#include "flintxx/stdmath.h" +#include "flintxx/traits.h" + +// TODO exhibit this as a specialisation of a generic poly +// TODO input +// TODO automatic mulmod, powmod etc? +// TODO use underscore function versions? +// TODO nmod_series class? +// TODO subproduct trees? + +namespace flint { +FLINT_DEFINE_BINOP(div_newton) +FLINT_DEFINE_BINOP(divrem_newton) +FLINT_DEFINE_BINOP(evaluate_fast) +FLINT_DEFINE_BINOP(evaluate_iter) +FLINT_DEFINE_BINOP(exp_series_basecase) +FLINT_DEFINE_BINOP(gcd_euclidean) +FLINT_DEFINE_BINOP(gcd_hgcd) +FLINT_DEFINE_BINOP(inv_series_basecase) +FLINT_DEFINE_BINOP(nmod_polyxx_get_coeff) +FLINT_DEFINE_BINOP(deflate) +FLINT_DEFINE_BINOP(inflate) +FLINT_DEFINE_BINOP(resultant_euclidean) +FLINT_DEFINE_BINOP(taylor_shift_convolution) +FLINT_DEFINE_BINOP(xgcd_euclidean) +FLINT_DEFINE_BINOP(xgcd_hgcd) + +FLINT_DEFINE_THREEARY(compose_mod) +FLINT_DEFINE_THREEARY(compose_mod_brent_kung) +FLINT_DEFINE_THREEARY(compose_mod_horner) +FLINT_DEFINE_THREEARY(div_newton_n_preinv) +FLINT_DEFINE_THREEARY(divrem_newton_n_preinv) +FLINT_DEFINE_THREEARY(exp_series_monomial) +FLINT_DEFINE_THREEARY(log_series_monomial) +FLINT_DEFINE_THREEARY(mulmod) +FLINT_DEFINE_THREEARY(powmod_binexp) + +FLINT_DEFINE_BINOP(nmod_polyxx_interpolate) +FLINT_DEFINE_BINOP(nmod_polyxx_interpolate_barycentric) +FLINT_DEFINE_BINOP(nmod_polyxx_interpolate_fast) +FLINT_DEFINE_BINOP(nmod_polyxx_interpolate_newton) +FLINT_DEFINE_UNOP(nmod_polyxx_product_roots) + +FLINT_DEFINE_FOURARY(compose_mod_brent_kung_preinv) +FLINT_DEFINE_FOURARY(mulmod_preinv) +FLINT_DEFINE_FOURARY(powmod_binexp_preinv) + +template +class nmod_polyxx_expression + : public expression, + Operation, Data> +{ +public: + typedef expression, + Operation, Data> base_t; + + FLINTXX_DEFINE_BASICS(nmod_polyxx_expression) + FLINTXX_DEFINE_CTORS(nmod_polyxx_expression) + FLINTXX_DEFINE_C_REF(nmod_polyxx_expression, nmod_poly_struct, _poly) + + // static functions for nmod_polyxx + template + static FLINT_BINOP_ENABLE_RETTYPE(nmod_polyxx_interpolate, + Nmod_vec1, Nmod_vec2) + interpolate(const Nmod_vec1& xs, const Nmod_vec2& ys) + { + return nmod_polyxx_interpolate(xs, ys); + } + template + static FLINT_BINOP_ENABLE_RETTYPE(nmod_polyxx_interpolate_fast, + Nmod_vec1, Nmod_vec2) + interpolate_fast(const Nmod_vec1& xs, const Nmod_vec2& ys) + { + return nmod_polyxx_interpolate_fast(xs, ys); + } + template + static FLINT_BINOP_ENABLE_RETTYPE(nmod_polyxx_interpolate_newton, + Nmod_vec1, Nmod_vec2) + interpolate_newton(const Nmod_vec1& xs, const Nmod_vec2& ys) + { + return nmod_polyxx_interpolate_newton(xs, ys); + } + template + static FLINT_BINOP_ENABLE_RETTYPE(nmod_polyxx_interpolate_barycentric, + Nmod_vec1, Nmod_vec2) + interpolate_barycentric(const Nmod_vec1& xs, const Nmod_vec2& ys) + { + return nmod_polyxx_interpolate_barycentric(xs, ys); + } + + template + static FLINT_UNOP_ENABLE_RETTYPE(nmod_polyxx_product_roots, Nmod_vec) + product_roots(const Nmod_vec& xs) + { + return nmod_polyxx_product_roots(xs); + } + + // XXX this is difficult to make lazy + template + static typename mp::enable_if, + nmod_polyxx_expression>::type + bit_unpack(const Fmpz& a, mp_bitcnt_t bits, nmodxx_ctx_srcref modulus) + { + nmod_polyxx_expression res(modulus); + nmod_poly_bit_unpack(res._poly(), a.evaluate()._fmpz(), bits); + return res; + } + + FLINTXX_DEFINE_FORWARD_STATIC(from_ground) + FLINTXX_DEFINE_FORWARD_STATIC(reduce) + + static nmod_polyxx_expression zero(mp_limb_t n) + {return nmod_polyxx_expression(n);} + static nmod_polyxx_expression one(mp_limb_t n) + { + nmod_polyxx_expression res(n); + res.set_one(); + return res; + } + + static nmod_polyxx_expression randtest(mp_limb_t n, + frandxx& state, slong len) + { + nmod_polyxx_expression res(n); + res.set_randtest(state, len); + return res; + } + + static nmod_polyxx_expression randtest_irreducible(mp_limb_t n, + frandxx& state, slong len) + { + nmod_polyxx_expression res(n); + res.set_randtest_irreducible(state, len); + return res; + } + + // these only make sense with immediates + void realloc(slong alloc) {nmod_poly_realloc(_poly(), alloc);} + void fit_length(slong len) {nmod_poly_fit_length(_poly(), len);} + void _normalise() {_nmod_poly_normalise(_poly());} + nmodxx_ctx_srcref _ctx() const + {return nmodxx_ctx_srcref::make(_poly()->mod);} + void set_zero() {nmod_poly_zero(_poly());} + void set_one() {nmod_poly_one(_poly());} + + // These only make sense with target immediates + void set_coeff(slong n, ulong c) {nmod_poly_set_coeff_ui(_poly(), n, c);} + template + typename mp::enable_if >::type + set_coeff(slong j, const Nmod& c) + { + // TODO this does not need reduction + nmod_poly_set_coeff_ui(_poly(), j, c.template to()); + } + void truncate(slong n) {nmod_poly_truncate(_poly(), n);} + + void set_randtest(frandxx& state, slong len) + {nmod_poly_randtest(_poly(), state._data(), len);} + void set_randtest_irreducible(frandxx& state, slong len) + {nmod_poly_randtest_irreducible(_poly(), state._data(), len);} + + template + slong remove(const Poly& p) + { + return nmod_poly_remove(_poly(), p.evaluate()._poly()); + } + + // These work on any expression without evaluation + nmodxx_ctx_srcref estimate_ctx() const; + mp_limb_t modulus() const {return estimate_ctx().n();} + + evaluated_t create_temporary() const + { + return evaluated_t(estimate_ctx()); + } + + // These cause evaluation + slong length() const {return nmod_poly_length(this->evaluate()._poly());} + slong degree() const {return nmod_poly_degree(this->evaluate()._poly());} + bool is_one() const {return nmod_poly_is_one(this->evaluate()._poly());} + bool is_zero() const {return nmod_poly_is_zero(this->evaluate()._poly());} + bool is_squarefree() const + {return nmod_poly_is_squarefree(this->evaluate()._poly());} + bool is_irreducible() const + {return nmod_poly_is_irreducible(this->evaluate()._poly());} + slong max_bits() const {return nmod_poly_max_bits(this->evaluate()._poly());} + ulong deflation() const + {return nmod_poly_deflation(this->evaluate()._poly());} + + // Lazy members + FLINTXX_DEFINE_MEMBER_BINOP_(get_coeff, nmod_polyxx_get_coeff) + FLINTXX_DEFINE_MEMBER_BINOP_(operator(), compeval) + FLINTXX_DEFINE_MEMBER_BINOP(inflate) + FLINTXX_DEFINE_MEMBER_BINOP(deflate) + + FLINTXX_DEFINE_MEMBER_BINOP(compose_divconquer) + FLINTXX_DEFINE_MEMBER_BINOP(compose_horner) + FLINTXX_DEFINE_MEMBER_BINOP(div_basecase) + FLINTXX_DEFINE_MEMBER_BINOP(div_divconquer) + FLINTXX_DEFINE_MEMBER_BINOP(div_newton) + FLINTXX_DEFINE_MEMBER_BINOP(divrem) + FLINTXX_DEFINE_MEMBER_BINOP(divrem_basecase) + FLINTXX_DEFINE_MEMBER_BINOP(divrem_divconquer) + FLINTXX_DEFINE_MEMBER_BINOP(divrem_newton) + FLINTXX_DEFINE_MEMBER_BINOP(div_root) + FLINTXX_DEFINE_MEMBER_BINOP(evaluate_fast) + FLINTXX_DEFINE_MEMBER_BINOP(evaluate_iter) + FLINTXX_DEFINE_MEMBER_BINOP(gcd) + FLINTXX_DEFINE_MEMBER_BINOP(gcd_euclidean) + FLINTXX_DEFINE_MEMBER_BINOP(gcd_hgcd) + FLINTXX_DEFINE_MEMBER_BINOP(inv_series) + FLINTXX_DEFINE_MEMBER_BINOP(inv_series_basecase) + FLINTXX_DEFINE_MEMBER_BINOP(inv_series_newton) + FLINTXX_DEFINE_MEMBER_BINOP(invsqrt_series) + FLINTXX_DEFINE_MEMBER_BINOP(mul_classical) + FLINTXX_DEFINE_MEMBER_BINOP(mul_KS) + FLINTXX_DEFINE_MEMBER_BINOP(shift_left) + FLINTXX_DEFINE_MEMBER_BINOP(shift_right) + FLINTXX_DEFINE_MEMBER_BINOP(pow) + FLINTXX_DEFINE_MEMBER_BINOP(pow_binexp) + FLINTXX_DEFINE_MEMBER_BINOP(rem_basecase) + FLINTXX_DEFINE_MEMBER_BINOP(resultant) + FLINTXX_DEFINE_MEMBER_BINOP(resultant_euclidean) + FLINTXX_DEFINE_MEMBER_BINOP(reverse) + FLINTXX_DEFINE_MEMBER_BINOP(revert_series) + FLINTXX_DEFINE_MEMBER_BINOP(revert_series_lagrange) + FLINTXX_DEFINE_MEMBER_BINOP(revert_series_lagrange_fast) + FLINTXX_DEFINE_MEMBER_BINOP(revert_series_newton) + FLINTXX_DEFINE_MEMBER_BINOP(sqrt_series) + FLINTXX_DEFINE_MEMBER_BINOP(taylor_shift) + FLINTXX_DEFINE_MEMBER_BINOP(taylor_shift_convolution) + FLINTXX_DEFINE_MEMBER_BINOP(taylor_shift_horner) + FLINTXX_DEFINE_MEMBER_BINOP(xgcd) + FLINTXX_DEFINE_MEMBER_BINOP(xgcd_euclidean) + FLINTXX_DEFINE_MEMBER_BINOP(xgcd_hgcd) + FLINTXX_DEFINE_MEMBER_BINOP(log_series) + FLINTXX_DEFINE_MEMBER_BINOP(exp_series) + FLINTXX_DEFINE_MEMBER_BINOP(exp_series_basecase) + FLINTXX_DEFINE_MEMBER_BINOP(atan_series) + FLINTXX_DEFINE_MEMBER_BINOP(atanh_series) + FLINTXX_DEFINE_MEMBER_BINOP(asin_series) + FLINTXX_DEFINE_MEMBER_BINOP(asinh_series) + FLINTXX_DEFINE_MEMBER_BINOP(sin_series) + FLINTXX_DEFINE_MEMBER_BINOP(cos_series) + FLINTXX_DEFINE_MEMBER_BINOP(tan_series) + FLINTXX_DEFINE_MEMBER_BINOP(sinh_series) + FLINTXX_DEFINE_MEMBER_BINOP(cosh_series) + FLINTXX_DEFINE_MEMBER_BINOP(tanh_series) + + FLINTXX_DEFINE_MEMBER_BINOP(bit_pack) + + FLINTXX_DEFINE_MEMBER_UNOP(derivative) + FLINTXX_DEFINE_MEMBER_UNOP(integral) + FLINTXX_DEFINE_MEMBER_UNOP(make_monic) + FLINTXX_DEFINE_MEMBER_UNOP(sqrt) + + FLINTXX_DEFINE_MEMBER_3OP(compose_mod) + FLINTXX_DEFINE_MEMBER_3OP(compose_mod_horner) + FLINTXX_DEFINE_MEMBER_3OP(compose_mod_brent_kung) + FLINTXX_DEFINE_MEMBER_3OP(compose_series) + FLINTXX_DEFINE_MEMBER_3OP(compose_series_brent_kung) + FLINTXX_DEFINE_MEMBER_3OP(compose_series_divconquer) + FLINTXX_DEFINE_MEMBER_3OP(compose_series_horner) + FLINTXX_DEFINE_MEMBER_3OP(div_newton_n_preinv) + FLINTXX_DEFINE_MEMBER_3OP(divrem_newton_n_preinv) + FLINTXX_DEFINE_MEMBER_3OP(div_series) + FLINTXX_DEFINE_MEMBER_3OP(mulhigh) + FLINTXX_DEFINE_MEMBER_3OP(mulhigh_classical) + FLINTXX_DEFINE_MEMBER_3OP(mullow) + FLINTXX_DEFINE_MEMBER_3OP(mullow_classical) + FLINTXX_DEFINE_MEMBER_3OP(mullow_KS) + FLINTXX_DEFINE_MEMBER_3OP(mulmod) + FLINTXX_DEFINE_MEMBER_3OP(powmod_binexp) + FLINTXX_DEFINE_MEMBER_3OP(pow_trunc) + FLINTXX_DEFINE_MEMBER_3OP(pow_trunc_binexp) + + FLINTXX_DEFINE_MEMBER_4OP(compose_mod_brent_kung_preinv) + FLINTXX_DEFINE_MEMBER_4OP(mulmod_preinv) + FLINTXX_DEFINE_MEMBER_4OP(powmod_binexp_preinv) +}; + +namespace detail { +struct nmod_poly_data; +} + +typedef nmod_polyxx_expression + nmod_polyxx; +typedef nmod_polyxx_expression > + nmod_polyxx_ref; +typedef nmod_polyxx_expression > + nmod_polyxx_srcref; + +namespace detail { +struct nmod_poly_data +{ + nmod_poly_t inner; + typedef nmod_poly_t& data_ref_t; + typedef const nmod_poly_t& data_srcref_t; + + nmod_poly_data(mp_limb_t n) {nmod_poly_init(inner, n);} + nmod_poly_data(nmodxx_ctx_srcref c) + { + nmod_poly_init_preinv(inner, c.n(), c._nmod().ninv); + } + nmod_poly_data(mp_limb_t n, slong alloc) {nmod_poly_init2(inner, n, alloc);} + nmod_poly_data(nmodxx_ctx_srcref c, slong alloc) + { + nmod_poly_init2_preinv(inner, c.n(), c._nmod().ninv, alloc); + } + ~nmod_poly_data() {nmod_poly_clear(inner);} + + nmod_poly_data(const nmod_poly_data& o) + { + nmod_poly_init2_preinv(inner, o.inner->mod.n, + o.inner->mod.ninv, o.inner->length); + nmod_poly_set(inner, o.inner); + } + + nmod_poly_data(nmod_polyxx_srcref r) + { + nmod_poly_init2_preinv(inner, r.modulus(), + r._poly()->mod.ninv, r.length()); + nmod_poly_set(inner, r._poly()); + } + + nmod_poly_data(const char* str) + { + mp_limb_t n;slong length; + execution_check(flint_sscanf(str, "%wd %wu", &length, &n) == 2 + && (nmod_poly_init2(inner, n, length), nmod_poly_set_str(inner, str)), + "construct from string", "nmod_polyxx"); + } + + template + static nmod_poly_data from_ground(const Nmod& x, + typename mp::enable_if >::type* = 0) + { + nmod_poly_data res(x.estimate_ctx()); + nmod_poly_set_coeff_ui(res.inner, 0, x.template to()); + return res; + } + static nmod_poly_data from_ground(mp_limb_t x, nmodxx_ctx_srcref c) + { + nmod_poly_data res(c); + nmod_poly_set_coeff_ui(res.inner, 0, x); + return res; + } + + // TODO maybe make these lazy + template + static nmod_poly_data reduce(const Fmpz_poly& p, nmodxx_ctx_srcref c, + typename mp::enable_if >::type* = 0) + { + nmod_poly_data res(c); + fmpz_poly_get_nmod_poly(res.inner, p.evaluate()._poly()); + return res; + } + template + static nmod_poly_data reduce(const Fmpz_poly& p, mp_limb_t m, + typename mp::enable_if >::type* = 0) + { + nmod_poly_data res(m); + fmpz_poly_get_nmod_poly(res.inner, p.evaluate()._poly()); + return res; + } + + template + static nmod_poly_data reduce_(const Fmpq_poly& p, nmodxx_ctx_srcref c, + typename mp::enable_if >::type* = 0) + { + nmod_poly_data res(c, p.length()); + for(slong i = 0;i < p.length();++i) + nmod_poly_set_coeff_ui(res. inner, i, + nmodxx::red(p.get_coeff(i), c).template to()); + return res; + } + template + static nmod_poly_data reduce(const Fmpq_poly& p, nmodxx_ctx_srcref c, + typename mp::enable_if >::type* = 0) + { + return reduce_(p.evaluate(), c); + } + template + static nmod_poly_data reduce(const Fmpq_poly& p, mp_limb_t m, + typename mp::enable_if >::type* = 0) + { + return reduce_(p.evaluate(), nmodxx_ctx(m)); + } +}; +} // detail +namespace traits { +template<> struct has_nmodxx_ctx : mp::true_ { }; +template<> struct has_nmodxx_ctx : mp::true_ { }; +template<> struct has_nmodxx_ctx : mp::true_ { }; + +template struct is_nmod_polyxx : mp::or_< + traits::is_T_expr, + flint_classes::is_source > { }; +} // traits +template +inline nmodxx_ctx_srcref +nmod_polyxx_expression::estimate_ctx() const +{ + return tools::find_nmodxx_ctx(*this); +} + +namespace rules { +#define NMOD_POLYXX_COND_S FLINTXX_COND_S(nmod_polyxx) +#define NMOD_POLYXX_COND_T FLINTXX_COND_T(nmod_polyxx) + +NMODXX_DEFINE_INSTANTIATE_TEMPORARIES(nmod_polyxx) + +FLINT_DEFINE_DOIT_COND2(assignment, NMOD_POLYXX_COND_T, NMOD_POLYXX_COND_S, + nmod_poly_set(to._poly(), from._poly())) + +FLINTXX_DEFINE_ASSIGN_STR(nmod_polyxx, execution_check( + nmod_poly_set_str(to._poly(), from), "assign string", "nmod_polyxx")) + +FLINT_DEFINE_PRINT_COND(NMOD_POLYXX_COND_S, nmod_poly_fprint(to, from._poly())) +FLINT_DEFINE_READ_COND(NMOD_POLYXX_COND_T, nmod_poly_fread(from, to._poly())) + +FLINTXX_DEFINE_EQUALS(nmod_polyxx, nmod_poly_equal(e1._poly(), e2._poly())) +FLINTXX_DEFINE_TO_STR(nmod_polyxx, nmod_poly_get_str(from._poly())) +FLINTXX_DEFINE_SWAP(nmod_polyxx, nmod_poly_swap(e1._poly(), e2._poly())) + +FLINT_DEFINE_BINARY_EXPR_COND2(nmod_polyxx_get_coeff_op, nmodxx, + NMOD_POLYXX_COND_S, traits::fits_into_slong, + to.set_nored(nmod_poly_get_coeff_ui(e1._poly(), e2))) + +FLINT_DEFINE_BINARY_EXPR_COND2(plus, nmod_polyxx, + NMOD_POLYXX_COND_S, NMOD_POLYXX_COND_S, + nmod_poly_add(to._poly(), e1._poly(), e2._poly())) +FLINT_DEFINE_BINARY_EXPR_COND2(minus, nmod_polyxx, + NMOD_POLYXX_COND_S, NMOD_POLYXX_COND_S, + nmod_poly_sub(to._poly(), e1._poly(), e2._poly())) + +FLINT_DEFINE_UNARY_EXPR_COND(negate, nmod_polyxx, NMOD_POLYXX_COND_S, + nmod_poly_neg(to._poly(), from._poly())) + +FLINT_DEFINE_BINARY_EXPR_COND2(reverse_op, nmod_polyxx, + NMOD_POLYXX_COND_S, traits::fits_into_slong, + nmod_poly_reverse(to._poly(), e1._poly(), e2)) + +FLINT_DEFINE_BINARY_EXPR_COND2(shift_left_op, nmod_polyxx, + NMOD_POLYXX_COND_S, traits::fits_into_slong, + nmod_poly_shift_left(to._poly(), e1._poly(), e2)) +FLINT_DEFINE_BINARY_EXPR_COND2(shift_right_op, nmod_polyxx, + NMOD_POLYXX_COND_S, traits::fits_into_slong, + nmod_poly_shift_right(to._poly(), e1._poly(), e2)) + +FLINT_DEFINE_CBINARY_EXPR_COND2(times, nmod_polyxx, + NMOD_POLYXX_COND_S, NMODXX_COND_S, + nmod_poly_scalar_mul_nmod(to._poly(), e1._poly(), e2._limb())) +FLINT_DEFINE_UNARY_EXPR_COND(make_monic_op, nmod_polyxx, NMOD_POLYXX_COND_S, + nmod_poly_make_monic(to._poly(), from._poly())) + +FLINT_DEFINE_BINARY_EXPR_COND2(bit_pack_op, fmpzxx, + NMOD_POLYXX_COND_S, traits::fits_into_mp_bitcnt_t, + nmod_poly_bit_pack(to._fmpz(), e1._poly(), e2)) + +FLINT_DEFINE_BINARY_EXPR_COND2(times, nmod_polyxx, + NMOD_POLYXX_COND_S, NMOD_POLYXX_COND_S, + nmod_poly_mul(to._poly(), e1._poly(), e2._poly())) +FLINT_DEFINE_BINARY_EXPR_COND2(mul_classical_op, nmod_polyxx, + NMOD_POLYXX_COND_S, NMOD_POLYXX_COND_S, + nmod_poly_mul_classical(to._poly(), e1._poly(), e2._poly())) +FLINT_DEFINE_BINARY_EXPR_COND2(mul_KS_op, nmod_polyxx, + NMOD_POLYXX_COND_S, NMOD_POLYXX_COND_S, + nmod_poly_mul_KS(to._poly(), e1._poly(), e2._poly(), 0 /* TODO */)) + +#define NMOD_POLYXX_DEFINE_MULFUNC(name) \ +FLINT_DEFINE_THREEARY_EXPR_COND3(name##_op, nmod_polyxx, \ + NMOD_POLYXX_COND_S, NMOD_POLYXX_COND_S, traits::fits_into_slong, \ + nmod_poly_##name(to._poly(), e1._poly(), e2._poly(), e3)) +NMOD_POLYXX_DEFINE_MULFUNC(mullow_classical) +NMOD_POLYXX_DEFINE_MULFUNC(mullow) +NMOD_POLYXX_DEFINE_MULFUNC(mulhigh_classical) +NMOD_POLYXX_DEFINE_MULFUNC(mulhigh) + +FLINT_DEFINE_THREEARY_EXPR_COND3(mullow_KS_op, nmod_polyxx, + NMOD_POLYXX_COND_S, NMOD_POLYXX_COND_S, traits::fits_into_slong, + nmod_poly_mullow_KS(to._poly(), e1._poly(), e2._poly(), 0 /* TODO */, e3)) + +FLINT_DEFINE_THREEARY_EXPR_COND3(mulmod_op, nmod_polyxx, + NMOD_POLYXX_COND_S, NMOD_POLYXX_COND_S, NMOD_POLYXX_COND_S, + nmod_poly_mulmod(to._poly(), e1._poly(), e2._poly(), e3._poly())) + +FLINT_DEFINE_FOURARY_EXPR_COND4(mulmod_preinv_op, nmod_polyxx, + NMOD_POLYXX_COND_S, NMOD_POLYXX_COND_S, + NMOD_POLYXX_COND_S, NMOD_POLYXX_COND_S, + nmod_poly_mulmod_preinv(to._poly(), e1._poly(), e2._poly(), + e3._poly(), e4._poly())) + +FLINT_DEFINE_BINARY_EXPR_COND2(pow_binexp_op, nmod_polyxx, + NMOD_POLYXX_COND_S, traits::is_unsigned_integer, + nmod_poly_pow_binexp(to._poly(), e1._poly(), e2)) +FLINT_DEFINE_BINARY_EXPR_COND2(pow_op, nmod_polyxx, + NMOD_POLYXX_COND_S, traits::is_unsigned_integer, + nmod_poly_pow(to._poly(), e1._poly(), e2)) + +FLINT_DEFINE_THREEARY_EXPR_COND3(powmod_binexp_op, nmod_polyxx, + NMOD_POLYXX_COND_S, traits::is_unsigned_integer, NMOD_POLYXX_COND_S, + nmod_poly_powmod_ui_binexp(to._poly(), e1._poly(), e2, e3._poly())) + +FLINT_DEFINE_FOURARY_EXPR_COND4(powmod_binexp_preinv_op, nmod_polyxx, + NMOD_POLYXX_COND_S, traits::is_unsigned_integer, + NMOD_POLYXX_COND_S, NMOD_POLYXX_COND_S, + nmod_poly_powmod_ui_binexp_preinv(to._poly(), e1._poly(), e2, + e3._poly(), e4._poly())) + +FLINT_DEFINE_THREEARY_EXPR_COND3(pow_trunc_op, nmod_polyxx, + NMOD_POLYXX_COND_S, traits::is_unsigned_integer, traits::fits_into_slong, + nmod_poly_pow_trunc(to._poly(), e1._poly(), e2, e3)) +FLINT_DEFINE_THREEARY_EXPR_COND3(pow_trunc_binexp_op, nmod_polyxx, + NMOD_POLYXX_COND_S, traits::is_unsigned_integer, traits::fits_into_slong, + nmod_poly_pow_trunc_binexp(to._poly(), e1._poly(), e2, e3)) + +FLINT_DEFINE_UNARY_EXPR_COND(derivative_op, nmod_polyxx, NMOD_POLYXX_COND_S, + nmod_poly_derivative(to._poly(), from._poly())) +FLINT_DEFINE_UNARY_EXPR_COND(integral_op, nmod_polyxx, NMOD_POLYXX_COND_S, + nmod_poly_integral(to._poly(), from._poly())) + +FLINT_DEFINE_BINARY_EXPR_COND2(evaluate_op, nmodxx, + NMOD_POLYXX_COND_S, NMODXX_COND_S, + to.set_nored(nmod_poly_evaluate_nmod(e1._poly(), e2._limb()))) + +FLINT_DEFINE_BINARY_EXPR_COND2(evaluate_op, nmod_vecxx, + NMOD_POLYXX_COND_S, NMOD_VECXX_COND_S, + nmod_poly_evaluate_nmod_vec(to._array(), e1._poly(), e2._array(), + to.size())) +FLINT_DEFINE_BINARY_EXPR_COND2(evaluate_fast_op, nmod_vecxx, + NMOD_POLYXX_COND_S, NMOD_VECXX_COND_S, + nmod_poly_evaluate_nmod_vec_fast(to._array(), e1._poly(), e2._array(), + to.size())) +FLINT_DEFINE_BINARY_EXPR_COND2(evaluate_iter_op, nmod_vecxx, + NMOD_POLYXX_COND_S, NMOD_VECXX_COND_S, + nmod_poly_evaluate_nmod_vec_iter(to._array(), e1._poly(), e2._array(), + to.size())) + +namespace rdetail { +typedef make_ltuple::type>::type + nmod_polyxx_pair; +} // rdetail +#define NMOD_POLYXX_DEFINE_DIVREM(name) \ +FLINT_DEFINE_BINARY_EXPR_COND2(name##_op, rdetail::nmod_polyxx_pair, \ + NMOD_POLYXX_COND_S, NMOD_POLYXX_COND_S, \ + nmod_poly_##name(to.template get<0>()._poly(), to.template get<1>()._poly(), \ + e1._poly(), e2._poly())) +NMOD_POLYXX_DEFINE_DIVREM(divrem_basecase) +NMOD_POLYXX_DEFINE_DIVREM(divrem_divconquer) +NMOD_POLYXX_DEFINE_DIVREM(divrem_newton) +NMOD_POLYXX_DEFINE_DIVREM(divrem) + +FLINT_DEFINE_BINARY_EXPR_COND2(div_basecase_op, nmod_polyxx, + NMOD_POLYXX_COND_S, NMOD_POLYXX_COND_S, + nmod_poly_div_basecase(to._poly(), e1._poly(), e2._poly())) +FLINT_DEFINE_BINARY_EXPR_COND2(div_divconquer_op, nmod_polyxx, + NMOD_POLYXX_COND_S, NMOD_POLYXX_COND_S, + nmod_poly_div_divconquer(to._poly(), e1._poly(), e2._poly())) +FLINT_DEFINE_BINARY_EXPR_COND2(div_newton_op, nmod_polyxx, + NMOD_POLYXX_COND_S, NMOD_POLYXX_COND_S, + nmod_poly_div_newton(to._poly(), e1._poly(), e2._poly())) +FLINT_DEFINE_BINARY_EXPR_COND2(divided_by, nmod_polyxx, + NMOD_POLYXX_COND_S, NMOD_POLYXX_COND_S, + nmod_poly_div_divconquer(to._poly(), e1._poly(), e2._poly())) + +FLINT_DEFINE_THREEARY_EXPR_COND3(div_newton_n_preinv_op, nmod_polyxx, + NMOD_POLYXX_COND_S, NMOD_POLYXX_COND_S, NMOD_POLYXX_COND_S, + nmod_poly_div_newton_n_preinv(to._poly(), + e1._poly(), e2._poly(), e3._poly())) +FLINT_DEFINE_THREEARY_EXPR_COND3(divrem_newton_n_preinv_op, + rdetail::nmod_polyxx_pair, + NMOD_POLYXX_COND_S, NMOD_POLYXX_COND_S, NMOD_POLYXX_COND_S, + nmod_poly_divrem_newton_n_preinv(to.template get<0>()._poly(), + to.template get<1>()._poly(), e1._poly(), e2._poly(), e3._poly())) + +FLINT_DEFINE_BINARY_EXPR_COND2(rem_basecase_op, nmod_polyxx, + NMOD_POLYXX_COND_S, NMOD_POLYXX_COND_S, + nmod_poly_rem_basecase(to._poly(), e1._poly(), e2._poly())) +FLINT_DEFINE_BINARY_EXPR_COND2(modulo, nmod_polyxx, + NMOD_POLYXX_COND_S, NMOD_POLYXX_COND_S, + nmod_poly_rem(to._poly(), e1._poly(), e2._poly())) + +FLINT_DEFINE_BINARY_EXPR_COND2(inv_series_newton_op, nmod_polyxx, + NMOD_POLYXX_COND_S, traits::fits_into_slong, + nmod_poly_inv_series_newton(to._poly(), e1._poly(), e2)) +FLINT_DEFINE_BINARY_EXPR_COND2(inv_series_op, nmod_polyxx, + NMOD_POLYXX_COND_S, traits::fits_into_slong, + nmod_poly_inv_series(to._poly(), e1._poly(), e2)) +FLINT_DEFINE_BINARY_EXPR_COND2(inv_series_basecase_op, nmod_polyxx, + NMOD_POLYXX_COND_S, traits::fits_into_slong, + nmod_poly_inv_series_basecase(to._poly(), e1._poly(), e2)) + +#define NMOD_POLYXX_DEFINE_SERIES(name) \ +FLINT_DEFINE_THREEARY_EXPR_COND3(name##_op, nmod_polyxx, \ + NMOD_POLYXX_COND_S, NMOD_POLYXX_COND_S, traits::fits_into_slong, \ + nmod_poly_##name(to._poly(), e1._poly(), e2._poly(), e3)) +NMOD_POLYXX_DEFINE_SERIES(div_series) + +FLINT_DEFINE_BINARY_EXPR_COND2(compose_op, nmod_polyxx, + NMOD_POLYXX_COND_S, NMOD_POLYXX_COND_S, + nmod_poly_compose(to._poly(), e1._poly(), e2._poly())) +FLINT_DEFINE_BINARY_EXPR_COND2(compose_divconquer_op, nmod_polyxx, + NMOD_POLYXX_COND_S, NMOD_POLYXX_COND_S, + nmod_poly_compose_divconquer(to._poly(), e1._poly(), e2._poly())) +FLINT_DEFINE_BINARY_EXPR_COND2(compose_horner_op, nmod_polyxx, + NMOD_POLYXX_COND_S, NMOD_POLYXX_COND_S, + nmod_poly_compose_horner(to._poly(), e1._poly(), e2._poly())) + +FLINT_DEFINE_BINARY_EXPR_COND2(div_root_op, nmod_polyxx, + NMOD_POLYXX_COND_S, NMODXX_COND_S, + nmod_poly_div_root(to._poly(), e1._poly(), e2._limb())) + +FLINT_DEFINE_BINARY_EXPR_COND2(nmod_polyxx_interpolate_op, nmod_polyxx, + NMOD_VECXX_COND_S, NMOD_VECXX_COND_S, + nmod_poly_interpolate_nmod_vec(to._poly(), e1._data().array, + e2._data().array, e2.size())) +FLINT_DEFINE_BINARY_EXPR_COND2(nmod_polyxx_interpolate_fast_op, nmod_polyxx, + NMOD_VECXX_COND_S, NMOD_VECXX_COND_S, + nmod_poly_interpolate_nmod_vec_fast(to._poly(), e1._data().array, + e2._data().array, e2.size())) +FLINT_DEFINE_BINARY_EXPR_COND2(nmod_polyxx_interpolate_newton_op, nmod_polyxx, + NMOD_VECXX_COND_S, NMOD_VECXX_COND_S, + nmod_poly_interpolate_nmod_vec_newton(to._poly(), e1._data().array, + e2._data().array, e2.size())) +FLINT_DEFINE_BINARY_EXPR_COND2(nmod_polyxx_interpolate_barycentric_op, nmod_polyxx, + NMOD_VECXX_COND_S, NMOD_VECXX_COND_S, + nmod_poly_interpolate_nmod_vec_barycentric(to._poly(), e1._data().array, + e2._data().array, e2.size())) + +FLINT_DEFINE_BINARY_EXPR_COND2(taylor_shift_horner_op, nmod_polyxx, + NMOD_POLYXX_COND_S, NMODXX_COND_S, + nmod_poly_taylor_shift_horner(to._poly(), e1._poly(), e2._limb())) +FLINT_DEFINE_BINARY_EXPR_COND2(taylor_shift_convolution_op, nmod_polyxx, + NMOD_POLYXX_COND_S, NMODXX_COND_S, + nmod_poly_taylor_shift_convolution(to._poly(), e1._poly(), e2._limb())) +FLINT_DEFINE_BINARY_EXPR_COND2(taylor_shift_op, nmod_polyxx, + NMOD_POLYXX_COND_S, NMODXX_COND_S, + nmod_poly_taylor_shift(to._poly(), e1._poly(), e2._limb())) + +FLINT_DEFINE_THREEARY_EXPR_COND3(compose_mod_op, nmod_polyxx, + NMOD_POLYXX_COND_S, NMOD_POLYXX_COND_S, NMOD_POLYXX_COND_S, + nmod_poly_compose_mod(to._poly(), e1._poly(), e2._poly(), e3._poly())) +FLINT_DEFINE_THREEARY_EXPR_COND3(compose_mod_horner_op, nmod_polyxx, + NMOD_POLYXX_COND_S, NMOD_POLYXX_COND_S, NMOD_POLYXX_COND_S, + nmod_poly_compose_mod_horner( + to._poly(), e1._poly(), e2._poly(), e3._poly())) +FLINT_DEFINE_THREEARY_EXPR_COND3(compose_mod_brent_kung_op, nmod_polyxx, + NMOD_POLYXX_COND_S, NMOD_POLYXX_COND_S, NMOD_POLYXX_COND_S, + nmod_poly_compose_mod_brent_kung( + to._poly(), e1._poly(), e2._poly(), e3._poly())) +FLINT_DEFINE_FOURARY_EXPR_COND4(compose_mod_brent_kung_preinv_op, nmod_polyxx, + NMOD_POLYXX_COND_S, NMOD_POLYXX_COND_S, + NMOD_POLYXX_COND_S, NMOD_POLYXX_COND_S, + nmod_poly_compose_mod_brent_kung_preinv( + to._poly(), e1._poly(), e2._poly(), e3._poly(), e4._poly())) + +FLINT_DEFINE_BINARY_EXPR_COND2(gcd_op, nmod_polyxx, + NMOD_POLYXX_COND_S, NMOD_POLYXX_COND_S, + nmod_poly_gcd(to._poly(), e1._poly(), e2._poly())) +FLINT_DEFINE_BINARY_EXPR_COND2(gcd_hgcd_op, nmod_polyxx, + NMOD_POLYXX_COND_S, NMOD_POLYXX_COND_S, + nmod_poly_gcd_hgcd(to._poly(), e1._poly(), e2._poly())) +FLINT_DEFINE_BINARY_EXPR_COND2(gcd_euclidean_op, nmod_polyxx, + NMOD_POLYXX_COND_S, NMOD_POLYXX_COND_S, + nmod_poly_gcd_euclidean(to._poly(), e1._poly(), e2._poly())) + +namespace rdetail { +typedef make_ltuple::type>::type + nmod_polyxx_triple; +} // rdetail +FLINT_DEFINE_BINARY_EXPR_COND2(xgcd_op, rdetail::nmod_polyxx_triple, + NMOD_POLYXX_COND_S, NMOD_POLYXX_COND_S, + nmod_poly_xgcd(to.template get<0>()._poly(), to.template get<1>()._poly(), + to.template get<2>()._poly(), e1._poly(), e2._poly())) +FLINT_DEFINE_BINARY_EXPR_COND2(xgcd_hgcd_op, rdetail::nmod_polyxx_triple, + NMOD_POLYXX_COND_S, NMOD_POLYXX_COND_S, + nmod_poly_xgcd_hgcd(to.template get<0>()._poly(), + to.template get<1>()._poly(), + to.template get<2>()._poly(), e1._poly(), e2._poly())) +FLINT_DEFINE_BINARY_EXPR_COND2(xgcd_euclidean_op, rdetail::nmod_polyxx_triple, + NMOD_POLYXX_COND_S, NMOD_POLYXX_COND_S, + nmod_poly_xgcd_euclidean(to.template get<0>()._poly(), + to.template get<1>()._poly(), + to.template get<2>()._poly(), e1._poly(), e2._poly())) + +FLINT_DEFINE_BINARY_EXPR_COND2(resultant_op, nmodxx, + NMOD_POLYXX_COND_S, NMOD_POLYXX_COND_S, + to.set_nored(nmod_poly_resultant(e1._poly(), e2._poly()))) +FLINT_DEFINE_BINARY_EXPR_COND2(resultant_euclidean_op, nmodxx, + NMOD_POLYXX_COND_S, NMOD_POLYXX_COND_S, + to.set_nored(nmod_poly_resultant_euclidean(e1._poly(), e2._poly()))) + +NMOD_POLYXX_DEFINE_SERIES(compose_series) +NMOD_POLYXX_DEFINE_SERIES(compose_series_horner) +NMOD_POLYXX_DEFINE_SERIES(compose_series_brent_kung) +NMOD_POLYXX_DEFINE_SERIES(compose_series_divconquer) + +#define NMOD_POLYXX_DEFINE_SERIESUN(name) \ +FLINT_DEFINE_BINARY_EXPR_COND2(name##_op, nmod_polyxx, \ + NMOD_POLYXX_COND_S, traits::fits_into_slong, \ + nmod_poly_##name(to._poly(), e1._poly(), e2)) +NMOD_POLYXX_DEFINE_SERIESUN(revert_series) +NMOD_POLYXX_DEFINE_SERIESUN(revert_series_newton) +NMOD_POLYXX_DEFINE_SERIESUN(revert_series_lagrange_fast) +NMOD_POLYXX_DEFINE_SERIESUN(revert_series_lagrange) + +#define NMOD_POLYXX_DEFINE_SERIES_F(name) \ +FLINT_DEFINE_BINARY_EXPR_COND2(name##_series_op, nmod_polyxx, \ + NMOD_POLYXX_COND_S, traits::fits_into_slong, \ + nmod_poly_##name##_series(to._poly(), e1._poly(), e2)) +NMOD_POLYXX_DEFINE_SERIES_F(sqrt) +NMOD_POLYXX_DEFINE_SERIES_F(invsqrt) +NMOD_POLYXX_DEFINE_SERIES_F(log) +NMOD_POLYXX_DEFINE_SERIES_F(exp) +NMOD_POLYXX_DEFINE_SERIES_F(atan) +NMOD_POLYXX_DEFINE_SERIES_F(atanh) +NMOD_POLYXX_DEFINE_SERIES_F(asin) +NMOD_POLYXX_DEFINE_SERIES_F(asinh) +NMOD_POLYXX_DEFINE_SERIES_F(sin) +NMOD_POLYXX_DEFINE_SERIES_F(cos) +NMOD_POLYXX_DEFINE_SERIES_F(tan) +NMOD_POLYXX_DEFINE_SERIES_F(sinh) +NMOD_POLYXX_DEFINE_SERIES_F(cosh) +NMOD_POLYXX_DEFINE_SERIES_F(tanh) + +FLINT_DEFINE_BINARY_EXPR_COND2(exp_series_basecase_op, nmod_polyxx, + NMOD_POLYXX_COND_S, traits::fits_into_slong, + nmod_poly_exp_series_basecase(to._poly(), e1._poly(), e2)) + +FLINT_DEFINE_THREEARY_EXPR_COND3(log_series_monomial_op, nmod_polyxx, + NMODXX_COND_S, traits::is_unsigned_integer, traits::fits_into_slong, + nmod_poly_log_series_monomial_ui(to._poly(), e1._limb(), e2, e3)) +FLINT_DEFINE_THREEARY_EXPR_COND3(exp_series_monomial_op, nmod_polyxx, + NMODXX_COND_S, traits::is_unsigned_integer, traits::fits_into_slong, + nmod_poly_exp_series_monomial_ui(to._poly(), e1._limb(), e2, e3)) + +FLINT_DEFINE_UNARY_EXPR_COND(sqrt_op, nmod_polyxx, NMOD_POLYXX_COND_S, + execution_check(nmod_poly_sqrt(to._poly(), from._poly()), + "sqrt", "nmod_polyxx")) + +FLINT_DEFINE_UNARY_EXPR_COND(nmod_polyxx_product_roots_op, nmod_polyxx, + NMOD_VECXX_COND_S, + nmod_poly_product_roots_nmod_vec(to._poly(), + from._data().array, from.size())) + +FLINT_DEFINE_BINARY_EXPR_COND2(deflate_op, nmod_polyxx, + NMOD_POLYXX_COND_S, traits::is_unsigned_integer, + nmod_poly_deflate(to._poly(), e1._poly(), e2)) +FLINT_DEFINE_BINARY_EXPR_COND2(inflate_op, nmod_polyxx, + NMOD_POLYXX_COND_S, traits::is_unsigned_integer, + nmod_poly_inflate(to._poly(), e1._poly(), e2)) +} // rules + + +////////////////////////////////////////////////////////////////////////////// +// FACTORISATION +////////////////////////////////////////////////////////////////////////////// + +class nmod_poly_factorxx +{ +private: + nmod_poly_factor_t inner; + +public: + nmod_poly_factorxx() {nmod_poly_factor_init(inner);} + ~nmod_poly_factorxx() {nmod_poly_factor_clear(inner);} + + nmod_poly_factorxx(const nmod_poly_factorxx& o) + { + nmod_poly_factor_init(inner); + nmod_poly_factor_set(inner, o.inner); + } + + bool operator==(const nmod_poly_factorxx& o) + { + if(o.size() != size()) + return false; + for(slong i = 0;i < size();++i) + if(p(i) != o.p(i) || exp(i) != o.exp(i)) + return false; + return true; + } + + nmod_poly_factorxx& operator=(const nmod_poly_factorxx& o) + { + nmod_poly_factor_set(inner, o.inner); + return *this; + } + + slong size() const {return inner->num;} + slong exp(slong i) const {return inner->exp[i];} + slong& exp(slong i) {return inner->exp[i];} + nmod_polyxx_srcref p(slong i) const + {return nmod_polyxx_srcref::make(inner->p + i);} + nmod_polyxx_ref p(slong i) {return nmod_polyxx_ref::make(inner->p + i);} + + nmod_poly_factor_t& _data() {return inner;} + const nmod_poly_factor_t& _data() const {return inner;} + + void realloc(slong a) {nmod_poly_factor_realloc(inner, a);} + void fit_length(slong a) {nmod_poly_factor_fit_length(inner, a);} + + void print() const {nmod_poly_factor_print(inner);} + + template + void insert(const Nmod_poly& p, slong e, + typename mp::enable_if >::type* = 0) + {nmod_poly_factor_insert(_data(), p.evaluate()._poly(), e);} + + void concat(const nmod_poly_factorxx& o) + {nmod_poly_factor_concat(_data(), o._data());} + + void pow(slong exp) {nmod_poly_factor_pow(_data(), exp);} + +#define NMOD_POLY_FACTORXX_DEFINE_SET_FACTOR(name) \ + template \ + void set_##name(const Nmod_poly& p, \ + typename mp::enable_if >::type* = 0) \ + {nmod_poly_##name(_data(), p.evaluate()._poly());} + + NMOD_POLY_FACTORXX_DEFINE_SET_FACTOR(factor) + NMOD_POLY_FACTORXX_DEFINE_SET_FACTOR(factor_squarefree) + NMOD_POLY_FACTORXX_DEFINE_SET_FACTOR(factor_cantor_zassenhaus) + NMOD_POLY_FACTORXX_DEFINE_SET_FACTOR(factor_berlekamp) + NMOD_POLY_FACTORXX_DEFINE_SET_FACTOR(factor_kaltofen_shoup) + NMOD_POLY_FACTORXX_DEFINE_SET_FACTOR(factor_with_cantor_zassenhaus) + NMOD_POLY_FACTORXX_DEFINE_SET_FACTOR(factor_with_berlekamp) + NMOD_POLY_FACTORXX_DEFINE_SET_FACTOR(factor_with_kaltofen_shoup) + + template + bool set_factor_equal_deg_probab(frandxx& state, const Nmod_poly& p, slong d, + typename mp::enable_if >::type* = 0) + { + return nmod_poly_factor_equal_deg_prob(_data(), state._data(), + p.evaluate()._poly(), d); + } + template + void set_factor_equal_deg(const Nmod_poly& p, slong d, + typename mp::enable_if >::type* = 0) + { + nmod_poly_factor_equal_deg(_data(), p.evaluate()._poly(), d); + } + + template + void set_factor_distinct_deg(const Nmod_poly& p, std::vector& degs, + typename mp::enable_if >::type* = 0) + { + slong* dgs = °s.front(); + nmod_poly_factor_distinct_deg(_data(), p.evaluate()._poly(), &dgs); + } +}; + +#define NMOD_POLY_FACTORXX_DEFINE_FACTOR(name) \ +template \ +nmod_poly_factorxx name(const Nmod_poly& p, \ + typename mp::enable_if >::type* = 0) \ +{ \ + nmod_poly_factorxx res; \ + res.set_##name(p); \ + return res; \ +} +NMOD_POLY_FACTORXX_DEFINE_FACTOR(factor) +NMOD_POLY_FACTORXX_DEFINE_FACTOR(factor_squarefree) +NMOD_POLY_FACTORXX_DEFINE_FACTOR(factor_cantor_zassenhaus) +NMOD_POLY_FACTORXX_DEFINE_FACTOR(factor_berlekamp) +NMOD_POLY_FACTORXX_DEFINE_FACTOR(factor_kaltofen_shoup) +NMOD_POLY_FACTORXX_DEFINE_FACTOR(factor_with_cantor_zassenhaus) +NMOD_POLY_FACTORXX_DEFINE_FACTOR(factor_with_berlekamp) +NMOD_POLY_FACTORXX_DEFINE_FACTOR(factor_with_kaltofen_shoup) + +// TODO do we want global versions of factor_distinct_deg etc? + +inline void print(const nmod_poly_factorxx& f) +{ + f.print(); +} + + +// CRT stuff +// Here for circular dependency reasons +namespace rules { +FLINT_DEFINE_FOURARY_EXPR_COND4(CRT_op, fmpz_polyxx, + FMPZ_POLYXX_COND_T, FMPZXX_COND_S, NMOD_POLYXX_COND_S, tools::is_bool, + fmpz_poly_CRT_ui(to._poly(), e1._poly(), e2._fmpz(), e3._poly(), e4)) +} // rules +} // flint + +#endif diff --git a/external/flint-2.4.3/nmod_vec.h b/external/flint-2.4.3/nmod_vec.h new file mode 100644 index 0000000..41a3f44 --- /dev/null +++ b/external/flint-2.4.3/nmod_vec.h @@ -0,0 +1,317 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#ifndef NMOD_VEC_H +#define NMOD_VEC_H + +#undef ulong +#define ulong ulongxx /* interferes with system includes */ +#include +#undef ulong +#include +#define ulong mp_limb_t + +#include "longlong.h" +#include "ulong_extras.h" +#include "flint.h" + +#ifdef __cplusplus + extern "C" { +#endif + +typedef struct +{ + mp_limb_t n; + mp_limb_t ninv; + mp_bitcnt_t norm; +} nmod_t; + + +#define NMOD_VEC_NORM(vec, i) \ +do { \ + while ((i) && vec[(i) - 1] == UWORD(0)) \ + (i)--; \ +} while (0) + +#define NMOD_RED2(r, a_hi, a_lo, mod) \ + do { \ + mp_limb_t q0, q1, r1; \ + const mp_limb_t u1 = ((a_hi)<<(mod).norm) + r_shift((a_lo), FLINT_BITS - (mod).norm); \ + const mp_limb_t u0 = ((a_lo)<<(mod).norm); \ + const mp_limb_t nxx = ((mod).n<<(mod).norm); \ + umul_ppmm(q1, q0, (mod).ninv, u1); \ + add_ssaaaa(q1, q0, q1, q0, u1, u0); \ + r1 = (u0 - (q1 + 1)*nxx); \ + if (r1 >= q0) r1 += nxx; \ + if (r1 < nxx) r = (r1>>(mod).norm); \ + else r = ((r1 - nxx)>>(mod).norm); \ + } while (0) + +#define NMOD_RED(r, a, mod) \ + do { \ + NMOD_RED2(r, 0, a, mod); \ + } while (0) + +#define NMOD2_RED2(r, a_hi, a_lo, mod) \ + do { \ + mp_limb_t v_hi; \ + NMOD_RED(v_hi, a_hi, mod); \ + NMOD_RED2(r, v_hi, a_lo, mod); \ + } while (0) + +#define NMOD_RED3(r, a_hi, a_me, a_lo, mod) \ + do { \ + mp_limb_t v_hi; \ + NMOD_RED2(v_hi, a_hi, a_me, mod); \ + NMOD_RED2(r, v_hi, a_lo, mod); \ + } while (0) + +#define NMOD_ADDMUL(r, a, b, mod) \ + do { \ + mp_limb_t a_hi, a_lo; \ + umul_ppmm(a_hi, a_lo, a, b); \ + add_ssaaaa(a_hi, a_lo, a_hi, a_lo, (mp_limb_t) 0, r); \ + NMOD_RED2(r, a_hi, a_lo, mod); \ + } while (0) + +static __inline__ +mp_limb_t _nmod_add(mp_limb_t a, mp_limb_t b, nmod_t mod) +{ + const mp_limb_t sum = a + b; + return sum - mod.n + ((((mp_limb_signed_t)(sum - mod.n))>>(FLINT_BITS - 1)) & mod.n); +} + +static __inline__ +mp_limb_t _nmod_sub(mp_limb_t a, mp_limb_t b, nmod_t mod) +{ + const mp_limb_t diff = a - b; + return ((((mp_limb_signed_t)diff)>>(FLINT_BITS - 1)) & mod.n) + diff; +} + +static __inline__ +mp_limb_t nmod_add(mp_limb_t a, mp_limb_t b, nmod_t mod) +{ + const mp_limb_t neg = mod.n - a; + if (neg > b) + return a + b; + else + return b - neg; +} + +static __inline__ +mp_limb_t nmod_sub(mp_limb_t a, mp_limb_t b, nmod_t mod) +{ + const mp_limb_t diff = a - b; + + if (a < b) + return mod.n + diff; + else + return diff; +} + +static __inline__ +mp_limb_t nmod_neg(mp_limb_t a, nmod_t mod) +{ + if (a) + return mod.n - a; + else + return 0; +} + +static __inline__ +mp_limb_t nmod_mul(mp_limb_t a, mp_limb_t b, nmod_t mod) +{ + return n_mulmod2_preinv(a, b, mod.n, mod.ninv); +} + +static __inline__ +mp_limb_t nmod_inv(mp_limb_t a, nmod_t mod) +{ + return n_invmod(a, mod.n); +} + +static __inline__ +mp_limb_t nmod_div(mp_limb_t a, mp_limb_t b, nmod_t mod) +{ + b = n_invmod(b, mod.n); + return n_mulmod2_preinv(a, b, mod.n, mod.ninv); +} + +static __inline__ +mp_limb_t nmod_pow_ui(mp_limb_t a, ulong exp, nmod_t mod) +{ + return n_powmod2_ui_preinv(a, exp, mod.n, mod.ninv); +} + +static __inline__ +void nmod_init(nmod_t * mod, mp_limb_t n) +{ + mod->n = n; + mod->ninv = n_preinvert_limb(n); + count_leading_zeros(mod->norm, n); +} + +static __inline__ +mp_ptr _nmod_vec_init(slong len) +{ + return (mp_ptr) flint_malloc(len * sizeof(mp_limb_t)); +} + +static __inline__ +void _nmod_vec_clear(mp_ptr vec) +{ + flint_free(vec); +} + +void _nmod_vec_randtest(mp_ptr vec, flint_rand_t state, slong len, nmod_t mod); + +static __inline__ +void _nmod_vec_zero(mp_ptr vec, slong len) +{ + flint_mpn_zero(vec, len); +} + +mp_bitcnt_t _nmod_vec_max_bits(mp_srcptr vec, slong len); + +static __inline__ +void _nmod_vec_set(mp_ptr res, mp_srcptr vec, slong len) +{ + flint_mpn_copyi(res, vec, len); +} + +static __inline__ +void _nmod_vec_swap(mp_ptr a, mp_ptr b, slong length) +{ + slong i; + for (i = 0; i < length; i++) + { + mp_limb_t t = a[i]; + a[i] = b[i]; + b[i] = t; + } +} + +static __inline__ +int _nmod_vec_equal(mp_srcptr vec, mp_srcptr vec2, slong len) +{ + slong i; + + for (i = 0; i < len; i++) + if (vec[i] != vec2[i]) return 0; + + return 1; +} + +static __inline__ +int _nmod_vec_is_zero(mp_srcptr vec, slong len) +{ + slong i; + + for (i = 0; i < len; i++) + if (vec[i] != 0) return 0; + + return 1; +} + +void _nmod_vec_reduce(mp_ptr res, mp_srcptr vec, + slong len, nmod_t mod); + +void _nmod_vec_add(mp_ptr res, mp_srcptr vec1, + mp_srcptr vec2, slong len, nmod_t mod); + +void _nmod_vec_sub(mp_ptr res, mp_srcptr vec1, + mp_srcptr vec2, slong len, nmod_t mod); + +void _nmod_vec_neg(mp_ptr res, mp_srcptr vec, + slong len, nmod_t mod); + +void _nmod_vec_scalar_mul_nmod(mp_ptr res, mp_srcptr vec, + slong len, mp_limb_t c, nmod_t mod); + +void _nmod_vec_scalar_addmul_nmod(mp_ptr res, mp_srcptr vec, + slong len, mp_limb_t c, nmod_t mod); + + +int _nmod_vec_dot_bound_limbs(slong len, nmod_t mod); + + +#define NMOD_VEC_DOT(res, i, len, expr1, expr2, mod, nlimbs) \ + do \ + { \ + mp_limb_t s0, s1, s2, t0, t1; \ + s0 = s1 = s2 = UWORD(0); \ + switch (nlimbs) \ + { \ + case 1: \ + for (i = 0; i < len; i++) \ + { \ + s0 += (expr1) * (expr2); \ + } \ + NMOD_RED(s0, s0, mod); \ + break; \ + case 2: \ + if (mod.n <= (UWORD(1) << (FLINT_BITS / 2))) \ + { \ + for (i = 0; i < len; i++) \ + { \ + t0 = (expr1) * (expr2); \ + add_ssaaaa(s1, s0, s1, s0, 0, t0); \ + } \ + } \ + else \ + { \ + for (i = 0; i < len; i++) \ + { \ + umul_ppmm(t1, t0, (expr1), (expr2)); \ + add_ssaaaa(s1, s0, s1, s0, t1, t0); \ + } \ + } \ + NMOD2_RED2(s0, s1, s0, mod); \ + break; \ + default: \ + for (i = 0; i < len; i++) \ + { \ + umul_ppmm(t1, t0, (expr1), (expr2)); \ + add_sssaaaaaa(s2, s1, s0, s2, s1, s0, 0, t1, t0); \ + } \ + NMOD_RED(s2, s2, mod); \ + NMOD_RED3(s0, s2, s1, s0, mod); \ + break; \ + } \ + res = s0; \ + } while (0); + +mp_limb_t _nmod_vec_dot(mp_srcptr vec1, mp_srcptr vec2, + slong len, nmod_t mod, int nlimbs); + +mp_limb_t _nmod_vec_dot_ptr(mp_srcptr vec1, const mp_ptr * vec2, slong offset, + slong len, nmod_t mod, int nlimbs); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/external/flint-2.4.3/nmod_vec/add.c b/external/flint-2.4.3/nmod_vec/add.c new file mode 100644 index 0000000..8fd7f2a --- /dev/null +++ b/external/flint-2.4.3/nmod_vec/add.c @@ -0,0 +1,46 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_vec.h" + +void _nmod_vec_add(mp_ptr res, mp_srcptr vec1, + mp_srcptr vec2, slong len, nmod_t mod) +{ + slong i; + + if (mod.norm) + { + for (i = 0 ; i < len; i++) + res[i] = _nmod_add(vec1[i], vec2[i], mod); + } else + { + for (i = 0 ; i < len; i++) + res[i] = nmod_add(vec1[i], vec2[i], mod); + } +} diff --git a/external/flint-2.4.3/nmod_vec/doc/nmod_vec.txt b/external/flint-2.4.3/nmod_vec/doc/nmod_vec.txt new file mode 100644 index 0000000..92f385b --- /dev/null +++ b/external/flint-2.4.3/nmod_vec/doc/nmod_vec.txt @@ -0,0 +1,257 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +******************************************************************************* + + Memory management + +******************************************************************************* + +mp_ptr _nmod_vec_init(slong len) + + Returns a vector of the given length. The entries are not necessarily + zero. + +void _nmod_vec_clear(mp_ptr vec) + + Frees the memory used by the given vector. + +******************************************************************************* + + Modular reduction and arithmetic + +******************************************************************************* + +void nmod_init(nmod_t * mod, mp_limb_t n) + + Initialises the given \code{nmod_t} structure for reduction modulo $n$ + with a precomputed inverse. + +NMOD_RED2(r, a_hi, a_lo, mod) + + Macro to set $r$ to $a$ reduced modulo \code{mod.n}, where $a$ + consists of two limbs \code{(a_hi, a_lo)}. The \code{mod} parameter + must be a valid \code{nmod_t} structure. It is assumed that \code{a_hi} + is already reduced modulo \code{mod.n}. + +NMOD_RED(r, a, mod) + + Macro to set $r$ to $a$ reduced modulo \code{mod.n}. The \code{mod} + parameter must be a valid \code{nmod_t} structure. + +NMOD2_RED2(r, a_hi, a_lo, mod) + + Macro to set $r$ to $a$ reduced modulo \code{mod.n}, where $a$ + consists of two limbs \code{(a_hi, a_lo)}. The \code{mod} parameter + must be a valid \code{nmod_t} structure. No assumptions are made + about \code{a_hi}. + +NMOD_RED3(r, a_hi, a_me, a_lo, mod) + + Macro to set $r$ to $a$ reduced modulo \code{mod.n}, where $a$ + consists of three limbs \code{(a_hi, a_me, a_lo)}. The \code{mod} + parameter must be a valid \code{nmod_t} structure. It is assumed + that \code{a_hi} is already reduced modulo \code{mod.n}. + +NMOD_ADDMUL(r, a, b, mod) + + Macro to set $r$ to $r + ab$ reduced modulo \code{mod.n}. The + \code{mod} parameter must be a valid \code{nmod_t} structure. It is + assumed that $r$, $a$, $b$ are already reduced modulo \code{mod.n}. + +mp_limb_t _nmod_add(mp_limb_t a, mp_limb_t b, nmod_t mod) + + Returns $a + b$ modulo \code{mod.n}. It is assumed that \code{mod} is + no more than \code{FLINT_BITS - 1} bits. It is assumed that $a$ and $b$ + are already reduced modulo \code{mod.n}. + +mp_limb_t nmod_add(mp_limb_t a, mp_limb_t b, nmod_t mod) + + Returns $a + b$ modulo \code{mod.n}. No assumptions are made about + \code{mod.n}. It is assumed that $a$ and $b$ are already reduced + modulo \code{mod.n}. + +mp_limb_t _nmod_sub(mp_limb_t a, mp_limb_t b, nmod_t mod) + + Returns $a - b$ modulo \code{mod.n}. It is assumed that \code{mod} + is no more than \code{FLINT_BITS - 1} bits. It is assumed that + $a$ and $b$ are already reduced modulo \code{mod.n}. + +mp_limb_t nmod_sub(mp_limb_t a, mp_limb_t b, nmod_t mod) + + Returns $a - b$ modulo \code{mod.n}. No assumptions are made about + \code{mod.n}. It is assumed that $a$ and $b$ are already reduced + modulo \code{mod.n}. + +mp_limb_t nmod_neg(mp_limb_t a, nmod_t mod) + + Returns $-a$ modulo \code{mod.n}. It is assumed that $a$ is already + reduced modulo \code{mod.n}, but no assumptions are made about the + latter. + +mp_limb_t nmod_mul(mp_limb_t a, mp_limb_t b, nmod_t mod) + + Returns $ab$ modulo \code{mod.n}. No assumptions are made about + \code{mod.n}. It is assumed that $a$ and $b$ are already reduced + modulo \code{mod.n}. + +mp_limb_t nmod_inv(mp_limb_t a, nmod_t mod) + + Returns $a^{-1}$ modulo \code{mod.n}. The inverse is assumed to exist. + +mp_limb_t nmod_div(mp_limb_t a, mp_limb_t b, nmod_t mod) + + Returns $a^{-1}$ modulo \code{mod.n}. The inverse of $b$ is assumed to + exist. It is assumed that $a$ is already reduced modulo \code{mod.n}. + +mp_limb_t nmod_pow_ui(mp_limb_t a, ulong e, nmod_t mod) + + Returns $a^e$ modulo \code{mod.n}. No assumptions are made about + \code{mod.n}. It is assumed that $a$ is already reduced + modulo \code{mod.n}. + + +******************************************************************************* + + Random functions + +******************************************************************************* + +void _nmod_vec_randtest(mp_ptr vec, flint_rand_t state, slong len, nmod_t mod) + + Sets \code{vec} to a random vector of the given length with entries + reduced modulo \code{mod.n}. + +******************************************************************************* + + Basic manipulation and comparison + +******************************************************************************* + +void _nmod_vec_set(mp_ptr res, mp_srcptr vec, slong len) + + Copies \code{len} entries from the vector \code{vec} to \code{res}. + +void _nmod_vec_zero(mp_ptr vec, slong len) + + Zeros the given vector of the given length. + +void _nmod_vec_swap(mp_ptr a, mp_ptr b, slong length) + + Swaps the vectors \code{a} and \code{b} of length $n$ by actually + swapping the entries. + +void _nmod_vec_reduce(mp_ptr res, mp_srcptr vec, slong len, nmod_t mod) + + Reduces the entries of \code{(vec, len)} modulo \code{mod.n} and set + \code{res} to the result. + +mp_bitcnt_t _nmod_vec_max_bits(mp_srcptr vec, slong len) + + Returns the maximum number of bits of any entry in the vector. + +int _nmod_vec_equal(mp_srcptr vec, mp_srcptr vec2, slong len) + + Returns~$1$ if \code{(vec, len)} is equal to \code{(vec2, len)}, + otherwise returns~$0$. + +******************************************************************************* + + Arithmetic operations + +******************************************************************************* + +void _nmod_vec_add(mp_ptr res, mp_srcptr vec1, + mp_srcptr vec2, slong len, nmod_t mod) + + Sets \code{(res, len)} to the sum of \code{(vec1, len)} + and \code{(vec2, len)}. + +void _nmod_vec_sub(mp_ptr res, mp_srcptr vec1, + mp_srcptr vec2, slong len, nmod_t mod) + + Sets \code{(res, len)} to the difference of \code{(vec1, len)} + and \code{(vec2, len)}. + +void _nmod_vec_neg(mp_ptr res, mp_srcptr vec, slong len, nmod_t mod) + + Sets \code{(res, len)} to the negation of \code{(vec, len)}. + +void _nmod_vec_scalar_mul_nmod(mp_ptr res, mp_srcptr vec, + slong len, mp_limb_t c, nmod_t mod) + + Sets \code{(res, len)} to \code{(vec, len)} multiplied by $c$. + +void _nmod_vec_scalar_addmul_nmod(mp_ptr res, mp_srcptr vec, + slong len, mp_limb_t c, nmod_t mod) + + Adds \code{(vec, len)} times $c$ to the vector \code{(res, len)}. + + +******************************************************************************* + + Dot products + +******************************************************************************* + +int _nmod_vec_dot_bound_limbs(slong len, nmod_t mod) + + Returns the number of limbs (0, 1, 2 or 3) needed to represent the + unreduced dot product of two vectors of length \code{len} having entries + modulo \code{mod.n}, assuming that \code{len} is nonnegative and that + \code{mod.n} is nonzero. The computed bound is tight. In other words, + this function returns the precise limb size of \code{len} times + \code{(mod.n - 1) ^ 2}. + +macro NMOD_VEC_DOT(res, i, len, expr1, expr2, mod, nlimbs) + + Effectively performs the computation + + \begin{verbatim} + res = 0; + for (i = 0; i < len; i++) + res += (expr1) * (expr2); + \end{verbatim} + + but with the arithmetic performed modulo \code{mod}. + The \code{nlimbs} parameter should be 0, 1, 2 or 3, specifying the + number of limbs needed to represent the unreduced result. + +mp_limb_t _nmod_vec_dot(mp_srcptr vec1, mp_srcptr vec2, + slong len, nmod_t mod, int nlimbs) + + Returns the dot product of (\code{vec1}, \code{len}) and + (\code{vec2}, \code{len}). The \code{nlimbs} parameter should be + 0, 1, 2 or 3, specifying the number of limbs needed to represent the + unreduced result. + +mp_limb_t +_nmod_vec_dot_ptr(mp_srcptr vec1, const mp_ptr * vec2, slong offset, slong len, + nmod_t mod, int nlimbs) + + Returns the dot product of (\code{vec1}, \code{len}) and the values at + \code{vec2[i][offset]}. The \code{nlimbs} parameter should be + 0, 1, 2 or 3, specifying the number of limbs needed to represent the + unreduced result. diff --git a/external/flint-2.4.3/nmod_vec/dot.c b/external/flint-2.4.3/nmod_vec/dot.c new file mode 100644 index 0000000..64bd14c --- /dev/null +++ b/external/flint-2.4.3/nmod_vec/dot.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_vec.h" + +mp_limb_t +_nmod_vec_dot(mp_srcptr vec1, mp_srcptr vec2, slong len, nmod_t mod, int nlimbs) +{ + mp_limb_t res; + slong i; + NMOD_VEC_DOT(res, i, len, vec1[i], vec2[i], mod, nlimbs); + return res; +} diff --git a/external/flint-2.4.3/nmod_vec/dot_bound_limbs.c b/external/flint-2.4.3/nmod_vec/dot_bound_limbs.c new file mode 100644 index 0000000..7ee52b0 --- /dev/null +++ b/external/flint-2.4.3/nmod_vec/dot_bound_limbs.c @@ -0,0 +1,45 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_vec.h" + +int +_nmod_vec_dot_bound_limbs(slong len, nmod_t mod) +{ + mp_limb_t t2, t1, t0, u1, u0; + + umul_ppmm(t1, t0, mod.n - 1, mod.n - 1); + umul_ppmm(t2, t1, t1, len); + umul_ppmm(u1, u0, t0, len); + add_sssaaaaaa(t2, t1, t0, t2, t1, UWORD(0), UWORD(0), u1, u0); + + if (t2 != 0) return 3; + if (t1 != 0) return 2; + return (t0 != 0); +} diff --git a/external/flint-2.4.3/nmod_vec/dot_ptr.c b/external/flint-2.4.3/nmod_vec/dot_ptr.c new file mode 100644 index 0000000..3e135a2 --- /dev/null +++ b/external/flint-2.4.3/nmod_vec/dot_ptr.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_vec.h" + +mp_limb_t +_nmod_vec_dot_ptr(mp_srcptr vec1, const mp_ptr * vec2, slong offset, + slong len, nmod_t mod, int nlimbs) +{ + mp_limb_t res; + slong i; + NMOD_VEC_DOT(res, i, len, vec1[i], vec2[i][offset], mod, nlimbs); + return res; +} diff --git a/external/flint-2.4.3/nmod_vec/max_bits.c b/external/flint-2.4.3/nmod_vec/max_bits.c new file mode 100644 index 0000000..3be9e71 --- /dev/null +++ b/external/flint-2.4.3/nmod_vec/max_bits.c @@ -0,0 +1,48 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "nmod_vec.h" + +mp_bitcnt_t _nmod_vec_max_bits(mp_srcptr vec, slong len) +{ + mp_bitcnt_t bits = 0; + mp_limb_t mask = ~(mp_limb_t) 0; + slong i; + + for (i = 0; i < len; i++) + { + if (vec[i] & mask) + { + bits = FLINT_BIT_COUNT(vec[i]); + if (bits == FLINT_BITS) break; + else mask = ~(mp_limb_t) 0 - ((UWORD(1) << bits) - UWORD(1)); + } + } + + return bits; +} diff --git a/external/flint-2.4.3/nmod_vec/neg.c b/external/flint-2.4.3/nmod_vec/neg.c new file mode 100644 index 0000000..1f2f6ff --- /dev/null +++ b/external/flint-2.4.3/nmod_vec/neg.c @@ -0,0 +1,37 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_vec.h" + +void _nmod_vec_neg(mp_ptr res, mp_srcptr vec, slong len, nmod_t mod) +{ + slong i; + for (i = 0 ; i < len; i++) + res[i] = nmod_neg(vec[i], mod); +} diff --git a/external/flint-2.4.3/nmod_vec/profile/p-add_sub_neg.c b/external/flint-2.4.3/nmod_vec/profile/p-add_sub_neg.c new file mode 100644 index 0000000..decce84 --- /dev/null +++ b/external/flint-2.4.3/nmod_vec/profile/p-add_sub_neg.c @@ -0,0 +1,128 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright 2010 William Hart + +******************************************************************************/ + +#include +#include +#include "profiler.h" +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_vec.h" + +typedef struct +{ + mp_bitcnt_t bits; + int type; +} info_t; + +void sample(void * arg, ulong count) +{ + mp_limb_t n, r = 0; + nmod_t mod; + info_t * info = (info_t *) arg; + mp_bitcnt_t bits = info->bits; + int type = info->type; + mp_size_t j; + slong i; + FLINT_TEST_INIT(state); + + + n = n_randbits(state, bits); + if (n == UWORD(0)) n++; + + nmod_init(&mod, n); + + mp_ptr vec1 = _nmod_vec_init(1000); + mp_ptr vec2 = _nmod_vec_init(1000); + mp_ptr res = _nmod_vec_init(1000); + + for (j = 0; j < 1000; j++) + vec1[j] = n_randint(state, n); + + for (j = 0; j < 1000; j++) + vec2[j] = n_randint(state, n); + + switch (type) + { + case 1: + prof_start(); + for (i = 0; i < count; i++) + { + _nmod_vec_add(res, vec1, vec2, 1000, mod); + } + prof_stop(); + break; + + case 2: + prof_start(); + for (i = 0; i < count; i++) + { + _nmod_vec_sub(res, vec1, vec2, 1000, mod); + } + prof_stop(); + break; + + case 3: + prof_start(); + for (i = 0; i < count; i++) + { + _nmod_vec_neg(res, vec1, 1000, mod); + } + prof_stop(); + break; + } + + flint_randclear(state); + _nmod_vec_clear(vec1); + _nmod_vec_clear(vec2); +} + +int main(void) +{ + double min1, min2, min3, max; + info_t info; + mp_bitcnt_t i; + + for (i = 2; i <= FLINT_BITS; i++) + { + info.bits = i; + + info.type = 1; + prof_repeat(&min1, &max, sample, (void *) &info); + + info.type = 2; + prof_repeat(&min2, &max, sample, (void *) &info); + + info.type = 3; + prof_repeat(&min3, &max, sample, (void *) &info); + + flint_printf("bits %wd, add = %.1lf c/l, sub = %.1lf c/l, neg = %.1lf c/l\n", + i, (min1/(double)FLINT_CLOCK_SCALE_FACTOR)/1000, + (min2/(double)FLINT_CLOCK_SCALE_FACTOR)/1000, + (min3/(double)FLINT_CLOCK_SCALE_FACTOR)/1000 + ); + } + + return 0; +} diff --git a/external/flint-2.4.3/nmod_vec/profile/p-reduce.c b/external/flint-2.4.3/nmod_vec/profile/p-reduce.c new file mode 100644 index 0000000..d50025d --- /dev/null +++ b/external/flint-2.4.3/nmod_vec/profile/p-reduce.c @@ -0,0 +1,88 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright 2010 William Hart + +******************************************************************************/ + +#include +#include +#include "profiler.h" +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_vec.h" + +typedef struct +{ + mp_bitcnt_t bits; +} info_t; + +void sample(void * arg, ulong count) +{ + mp_limb_t n; + nmod_t mod; + info_t * info = (info_t *) arg; + mp_bitcnt_t bits = info->bits; + mp_ptr vec = _nmod_vec_init(1000); + mp_ptr vec2 = _nmod_vec_init(1000); + mp_size_t j; + slong i; + FLINT_TEST_INIT(state); + + + for (j = 0; j < 1000; j++) + vec[j] = n_randlimb(state); + + prof_start(); + for (i = 0; i < count; i++) + { + n = n_randbits(state, bits); + if (n == UWORD(0)) n++; + + nmod_init(&mod, n); + _nmod_vec_reduce(vec2, vec, 1000, mod); + } + prof_stop(); + + flint_randclear(state); + _nmod_vec_clear(vec); + _nmod_vec_clear(vec2); +} + +int main(void) +{ + double min, max; + info_t info; + mp_bitcnt_t i; + + for (i = 2; i <= FLINT_BITS; i++) + { + info.bits = i; + + prof_repeat(&min, &max, sample, (void *) &info); + + flint_printf("bits %wd, c/l = %.1lf\n", + i, (min/(double)FLINT_CLOCK_SCALE_FACTOR)/1000 + ); + } + + return 0; +} diff --git a/external/flint-2.4.3/nmod_vec/profile/p-scalar_mul.c b/external/flint-2.4.3/nmod_vec/profile/p-scalar_mul.c new file mode 100644 index 0000000..9bfdd8c --- /dev/null +++ b/external/flint-2.4.3/nmod_vec/profile/p-scalar_mul.c @@ -0,0 +1,96 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright 2010 William Hart + +******************************************************************************/ + +#include +#include +#include "profiler.h" +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_vec.h" + +typedef struct +{ + mp_bitcnt_t bits; + slong length; +} info_t; + +void sample(void * arg, ulong count) +{ + mp_limb_t n, c; + nmod_t mod; + info_t * info = (info_t *) arg; + mp_bitcnt_t bits = info->bits; + slong length = info->length; + slong i, j; + mp_ptr vec = _nmod_vec_init(length); + mp_ptr vec2 = _nmod_vec_init(length); + FLINT_TEST_INIT(state); + + + for (i = 0; i < count; i++) + { + n = n_randbits(state, bits); + if (n == UWORD(0)) n++; + c = n_randint(state, n); + for (j = 0; j < length; j++) + vec[j] = n_randint(state, n); + + nmod_init(&mod, n); + + prof_start(); + for (j = 0; j < 30; j++) + _nmod_vec_scalar_mul_nmod(vec2, vec, length, c, mod); + prof_stop(); + } + + flint_randclear(state); + _nmod_vec_clear(vec); + _nmod_vec_clear(vec2); +} + +int main(void) +{ + double min1, min2, max; + info_t info; + mp_bitcnt_t i; + + for (i = 2; i <= FLINT_BITS; i++) + { + info.bits = i; + + info.length = 1024; + prof_repeat(&min1, &max, sample, (void *) &info); + + info.length = 65536; + prof_repeat(&min2, &max, sample, (void *) &info); + + flint_printf("bits %wd, length 128 %.1lf c/l, length 65536 %.1lf c/l\n", + i, (min1/(double)FLINT_CLOCK_SCALE_FACTOR)/(1024*30), + (min2/(double)FLINT_CLOCK_SCALE_FACTOR)/(65536*30) + ); + } + + return 0; +} diff --git a/external/flint-2.4.3/nmod_vec/randtest.c b/external/flint-2.4.3/nmod_vec/randtest.c new file mode 100644 index 0000000..ea2f91f --- /dev/null +++ b/external/flint-2.4.3/nmod_vec/randtest.c @@ -0,0 +1,53 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_vec.h" + +void _nmod_vec_randtest(mp_ptr vec, flint_rand_t state, slong len, nmod_t mod) +{ + slong i, sparseness; + + if (n_randint(state, 2)) + { + for (i = 0; i < len; i++) + vec[i] = n_randtest(state) % mod.n; + } + else + { + sparseness = 1 + n_randint(state, FLINT_MAX(2, len)); + + for (i = 0; i < len; i++) + { + if (n_randint(state, sparseness)) + vec[i] = 0; + else + vec[i] = n_randtest(state) % mod.n; + } + } +} diff --git a/external/flint-2.4.3/nmod_vec/reduce.c b/external/flint-2.4.3/nmod_vec/reduce.c new file mode 100644 index 0000000..bd84eec --- /dev/null +++ b/external/flint-2.4.3/nmod_vec/reduce.c @@ -0,0 +1,37 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_vec.h" + +void _nmod_vec_reduce(mp_ptr res, mp_srcptr vec, slong len, nmod_t mod) +{ + slong i; + for (i = 0 ; i < len; i++) + NMOD_RED(res[i], vec[i], mod); +} diff --git a/external/flint-2.4.3/nmod_vec/scalar_addmul_nmod.c b/external/flint-2.4.3/nmod_vec/scalar_addmul_nmod.c new file mode 100644 index 0000000..c1ecbbb --- /dev/null +++ b/external/flint-2.4.3/nmod_vec/scalar_addmul_nmod.c @@ -0,0 +1,46 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_vec.h" + +void _nmod_vec_scalar_addmul_nmod(mp_ptr res, mp_srcptr vec, + slong len, mp_limb_t c, nmod_t mod) +{ + if (mod.norm >= FLINT_BITS/2) /* addmul will fit in a limb */ + { + mpn_addmul_1(res, vec, len, c); + _nmod_vec_reduce(res, res, len, mod); + } + else /* products may take two limbs */ + { + slong i; + for (i = 0; i < len; i++) + NMOD_ADDMUL(res[i], vec[i], c, mod); /* hi already reduced mod n */ + } +} diff --git a/external/flint-2.4.3/nmod_vec/scalar_mul_nmod.c b/external/flint-2.4.3/nmod_vec/scalar_mul_nmod.c new file mode 100644 index 0000000..d5622f9 --- /dev/null +++ b/external/flint-2.4.3/nmod_vec/scalar_mul_nmod.c @@ -0,0 +1,49 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_vec.h" + +void _nmod_vec_scalar_mul_nmod(mp_ptr res, mp_srcptr vec, + slong len, mp_limb_t c, nmod_t mod) +{ + if (mod.norm >= FLINT_BITS/2) /* products will fit in a limb */ + { + mpn_mul_1(res, vec, len, c); + _nmod_vec_reduce(res, res, len, mod); + } else /* products may take two limbs */ + { + slong i; + for (i = 0; i < len; i++) + { + mp_limb_t hi, lo; + umul_ppmm(hi, lo, vec[i], c); + NMOD_RED2(res[i], hi, lo, mod); /* hi already reduced mod n */ + } + } +} diff --git a/external/flint-2.4.3/nmod_vec/sub.c b/external/flint-2.4.3/nmod_vec/sub.c new file mode 100644 index 0000000..758c7be --- /dev/null +++ b/external/flint-2.4.3/nmod_vec/sub.c @@ -0,0 +1,45 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_vec.h" + +void _nmod_vec_sub(mp_ptr res, mp_srcptr vec1, + mp_srcptr vec2, slong len, nmod_t mod) +{ + slong i; + if (mod.norm) + { + for (i = 0 ; i < len; i++) + res[i] = _nmod_sub(vec1[i], vec2[i], mod); + } else + { + for (i = 0 ; i < len; i++) + res[i] = nmod_sub(vec1[i], vec2[i], mod); + } +} diff --git a/external/flint-2.4.3/nmod_vec/test/t-add_sub_neg.c b/external/flint-2.4.3/nmod_vec/test/t-add_sub_neg.c new file mode 100644 index 0000000..b62d87f --- /dev/null +++ b/external/flint-2.4.3/nmod_vec/test/t-add_sub_neg.c @@ -0,0 +1,112 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("add/sub/neg...."); + fflush(stdout); + + /* Check (a + b) - b == a */ + for (i = 0; i < 10000; i++) + { + slong len = n_randint(state, 100) + 1; + nmod_t mod; + mp_limb_t n = n_randtest_not_zero(state); + + mp_ptr vec = _nmod_vec_init(len); + mp_ptr vec2 = _nmod_vec_init(len); + mp_ptr vec3 = _nmod_vec_init(len); + + nmod_init(&mod, n); + + _nmod_vec_randtest(vec, state, len, mod); + _nmod_vec_randtest(vec2, state, len, mod); + + _nmod_vec_add(vec3, vec, vec2, len, mod); + _nmod_vec_sub(vec3, vec3, vec2, len, mod); + + result = _nmod_vec_equal(vec, vec3, len); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("len = %wd, n = %wd\n", len, n); + abort(); + } + + _nmod_vec_clear(vec); + _nmod_vec_clear(vec2); + _nmod_vec_clear(vec3); + } + + /* Check (a + -b) == a - b */ + for (i = 0; i < 10000; i++) + { + slong len = n_randint(state, 100) + 1; + mp_limb_t n = n_randtest_not_zero(state); + nmod_t mod; + + mp_ptr vec = _nmod_vec_init(len); + mp_ptr vec2 = _nmod_vec_init(len); + mp_ptr vec3 = _nmod_vec_init(len); + + nmod_init(&mod, n); + + _nmod_vec_randtest(vec, state, len, mod); + _nmod_vec_randtest(vec2, state, len, mod); + + _nmod_vec_sub(vec3, vec, vec2, len, mod); + _nmod_vec_neg(vec2, vec2, len, mod); + _nmod_vec_add(vec, vec, vec2, len, mod); + + result = _nmod_vec_equal(vec, vec3, len); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("len = %wd, n = %wd\n", len, n); + abort(); + } + + _nmod_vec_clear(vec); + _nmod_vec_clear(vec2); + _nmod_vec_clear(vec3); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_vec/test/t-dot.c b/external/flint-2.4.3/nmod_vec/test/t-dot.c new file mode 100644 index 0000000..aa20a45 --- /dev/null +++ b/external/flint-2.4.3/nmod_vec/test/t-dot.c @@ -0,0 +1,99 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("dot...."); + fflush(stdout); + + for (i = 0; i < 10000; i++) + { + slong len; + nmod_t mod; + mp_limb_t m, res; + mp_ptr x, y; + int limbs1; + mpz_t s, t; + slong j; + + len = n_randint(state, 1000) + 1; + m = n_randtest_not_zero(state); + + nmod_init(&mod, m); + + x = _nmod_vec_init(len); + y = _nmod_vec_init(len); + + _nmod_vec_randtest(x, state, len, mod); + _nmod_vec_randtest(y, state, len, mod); + + limbs1 = _nmod_vec_dot_bound_limbs(len, mod); + + res = _nmod_vec_dot(x, y, len, mod, limbs1); + + mpz_init(s); + mpz_init(t); + + for (j = 0; j < len; j++) + { + flint_mpz_set_ui(t, x[j]); + flint_mpz_addmul_ui(s, t, y[j]); + } + + flint_mpz_mod_ui(s, s, m); + + if (flint_mpz_get_ui(s) != res) + { + flint_printf("FAIL:\n"); + flint_printf("m = %wu\n", m); + flint_printf("len = %wd\n", len); + flint_printf("limbs1 = %d\n", limbs1); + abort(); + } + + mpz_clear(s); + mpz_clear(t); + + _nmod_vec_clear(x); + _nmod_vec_clear(y); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_vec/test/t-dot_bound_limbs.c b/external/flint-2.4.3/nmod_vec/test/t-dot_bound_limbs.c new file mode 100644 index 0000000..b8ed2c1 --- /dev/null +++ b/external/flint-2.4.3/nmod_vec/test/t-dot_bound_limbs.c @@ -0,0 +1,82 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("dot_bound_limbs...."); + fflush(stdout); + + for (i = 0; i < 1000000; i++) + { + slong len; + nmod_t mod; + mp_limb_t m; + int limbs1, limbs2; + mpz_t t; + + len = n_randint(state, 10000) + 1; + m = n_randtest_not_zero(state); + + nmod_init(&mod, m); + + limbs1 = _nmod_vec_dot_bound_limbs(len, mod); + + mpz_init2(t, 4*FLINT_BITS); + flint_mpz_set_ui(t, m-1); + mpz_mul(t, t, t); + flint_mpz_mul_ui(t, t, len); + limbs2 = mpz_size(t); + + if (limbs1 != limbs2) + { + flint_printf("FAIL:\n"); + flint_printf("m = %wu\n", m); + flint_printf("len = %wd\n", len); + flint_printf("limbs1 = %d\n", limbs1); + flint_printf("limbs2 = %d\n", limbs2); + gmp_printf("bound: %Zd\n", t); + abort(); + } + + mpz_clear(t); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_vec/test/t-dot_ptr.c b/external/flint-2.4.3/nmod_vec/test/t-dot_ptr.c new file mode 100644 index 0000000..b95ea92 --- /dev/null +++ b/external/flint-2.4.3/nmod_vec/test/t-dot_ptr.c @@ -0,0 +1,92 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("dot_ptr...."); + fflush(stdout); + + for (i = 0; i < 10000; i++) + { + slong len; + nmod_t mod; + mp_limb_t m, res, res2; + mp_ptr x, y; + mp_ptr * z; + int limbs1; + slong j, offset; + + len = n_randint(state, 1000) + 1; + m = n_randtest_not_zero(state); + offset = n_randint(state, 10); + + nmod_init(&mod, m); + + x = _nmod_vec_init(len); + y = _nmod_vec_init(len); + z = flint_malloc(sizeof(mp_ptr) * len); + + _nmod_vec_randtest(x, state, len, mod); + _nmod_vec_randtest(y, state, len, mod); + + for (j = 0; j < len; j++) + z[j] = &y[j] + offset; + + limbs1 = _nmod_vec_dot_bound_limbs(len, mod); + + res = _nmod_vec_dot_ptr(x, z, -offset, len, mod, limbs1); + res2 = _nmod_vec_dot(x, y, len, mod, limbs1); + + if (res != res2) + { + flint_printf("FAIL:\n"); + flint_printf("m = %wu\n", m); + flint_printf("len = %wd\n", len); + flint_printf("limbs1 = %d\n", limbs1); + abort(); + } + + _nmod_vec_clear(x); + _nmod_vec_clear(y); + flint_free(z); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_vec/test/t-nmod.c b/external/flint-2.4.3/nmod_vec/test/t-nmod.c new file mode 100644 index 0000000..85f9d50 --- /dev/null +++ b/external/flint-2.4.3/nmod_vec/test/t-nmod.c @@ -0,0 +1,263 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 +#include +#include "flint.h" +#include "nmod_vec.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("nmod...."); + fflush(stdout); + + /* nmod_add */ + for (i = 0; i < 10000; i++) + { + nmod_t mod; + mp_limb_t m, a, b, c; + mpz_t x, y, z; + + m = n_randtest_not_zero(state); + + nmod_init(&mod, m); + a = n_randlimb(state) % m; + b = n_randlimb(state) % m; + + c = nmod_add(a, b, mod); + + mpz_init(x); + mpz_init(y); + mpz_init(z); + + flint_mpz_set_ui(x, a); + flint_mpz_set_ui(y, b); + mpz_add(z, x, y); + flint_mpz_mod_ui(z, z, m); + + if (flint_mpz_cmp_ui(z, c) != 0) + { + flint_printf("FAIL (add):\n"); + flint_printf("m = %wu\n", m); + abort(); + } + + mpz_clear(x); + mpz_clear(y); + mpz_clear(z); + } + + /* nmod_sub */ + for (i = 0; i < 10000; i++) + { + nmod_t mod; + mp_limb_t m, a, b, c; + mpz_t x, y, z; + + m = n_randtest_not_zero(state); + + nmod_init(&mod, m); + a = n_randlimb(state) % m; + b = n_randlimb(state) % m; + + c = nmod_sub(a, b, mod); + + mpz_init(x); + mpz_init(y); + mpz_init(z); + + flint_mpz_set_ui(x, a); + flint_mpz_set_ui(y, b); + mpz_sub(z, x, y); + flint_mpz_mod_ui(z, z, m); + + if (flint_mpz_cmp_ui(z, c) != 0) + { + flint_printf("FAIL (sub):\n"); + flint_printf("m = %wu\n", m); + abort(); + } + + mpz_clear(x); + mpz_clear(y); + mpz_clear(z); + } + + /* nmod_mul */ + for (i = 0; i < 10000; i++) + { + nmod_t mod; + mp_limb_t m, a, b, c; + mpz_t x, y, z; + + m = n_randtest_not_zero(state); + + nmod_init(&mod, m); + a = n_randlimb(state) % m; + b = n_randlimb(state) % m; + + c = nmod_mul(a, b, mod); + + mpz_init(x); + mpz_init(y); + mpz_init(z); + + flint_mpz_set_ui(x, a); + flint_mpz_set_ui(y, b); + mpz_mul(z, x, y); + flint_mpz_mod_ui(z, z, m); + + if (flint_mpz_cmp_ui(z, c) != 0) + { + flint_printf("FAIL (mul):\n"); + flint_printf("m = %wu\n", m); + abort(); + } + + mpz_clear(x); + mpz_clear(y); + mpz_clear(z); + } + + /* nmod_div */ + for (i = 0; i < 10000; i++) + { + nmod_t mod; + mp_limb_t m, a, b, c; + mpz_t x, y, z; + + m = n_randtest_prime(state, 0); + + nmod_init(&mod, m); + + a = n_randlimb(state) % m; + do { b = n_randlimb(state) % m; } while (b == 0); + + c = nmod_div(a, b, mod); + + mpz_init(x); + mpz_init(y); + mpz_init(z); + + flint_mpz_set_ui(x, a); + flint_mpz_set_ui(y, b); + flint_mpz_set_ui(z, m); + mpz_invert(z, y, z); + mpz_mul(z, x, z); + flint_mpz_mod_ui(z, z, m); + + if (flint_mpz_cmp_ui(z, c) != 0) + { + flint_printf("FAIL (div):\n"); + flint_printf("m = %wu\n", m); + abort(); + } + + mpz_clear(x); + mpz_clear(y); + mpz_clear(z); + } + + /* nmod_inv */ + for (i = 0; i < 10000; i++) + { + nmod_t mod; + mp_limb_t m, b, c; + mpz_t y, z; + + m = n_randtest_prime(state, 0); + + nmod_init(&mod, m); + + do { b = n_randlimb(state) % m; } while (b == 0); + + c = nmod_inv(b, mod); + + mpz_init(y); + mpz_init(z); + + flint_mpz_set_ui(y, b); + flint_mpz_set_ui(z, m); + mpz_invert(z, y, z); + + if (flint_mpz_cmp_ui(z, c) != 0) + { + flint_printf("FAIL (div):\n"); + flint_printf("m = %wu\n", m); + abort(); + } + + mpz_clear(y); + mpz_clear(z); + } + + /* nmod_pow_ui */ + for (i = 0; i < 10000; i++) + { + nmod_t mod; + mp_limb_t m, b, c; + mpz_t y, z; + ulong exp; + + m = n_randtest_prime(state, 0); + exp = n_randtest(state); + + nmod_init(&mod, m); + + b = n_randlimb(state) % m; + + c = nmod_pow_ui(b, exp, mod); + + mpz_init(y); + mpz_init(z); + + flint_mpz_set_ui(y, b); + flint_mpz_set_ui(z, m); + flint_mpz_powm_ui(z, y, exp, z); + + if (flint_mpz_cmp_ui(z, c) != 0) + { + flint_printf("FAIL (pow):\n"); + flint_printf("m = %wu\n", m); + abort(); + } + + mpz_clear(y); + mpz_clear(z); + } + + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_vec/test/t-reduce.c b/external/flint-2.4.3/nmod_vec/test/t-reduce.c new file mode 100644 index 0000000..6a5c906 --- /dev/null +++ b/external/flint-2.4.3/nmod_vec/test/t-reduce.c @@ -0,0 +1,79 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("reduce...."); + fflush(stdout); + + for (i = 0; i < 10000; i++) + { + slong j, len = n_randint(state, 100) + 1; + mp_ptr vec = _nmod_vec_init(len); + mp_ptr vec2 = _nmod_vec_init(len); + + mp_limb_t n = n_randtest_not_zero(state); + nmod_t mod; + nmod_init(&mod, n); + + for (j = 0; j < len; j++) + { + vec[j] = n_randtest(state); + vec2[j] = vec[j]; + } + + _nmod_vec_reduce(vec, vec, len, mod); + for (j = 0; j < len; j++) + vec2[j] = n_mod2_preinv(vec2[j], mod.n, mod.ninv); + + result = _nmod_vec_equal(vec, vec2, len); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("len = %wd, n = %wd\n", len, n); + abort(); + } + + _nmod_vec_clear(vec); + _nmod_vec_clear(vec2); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_vec/test/t-scalar_addmul_nmod.c b/external/flint-2.4.3/nmod_vec/test/t-scalar_addmul_nmod.c new file mode 100644 index 0000000..5bc5000 --- /dev/null +++ b/external/flint-2.4.3/nmod_vec/test/t-scalar_addmul_nmod.c @@ -0,0 +1,83 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("scalar_addmul_nmod...."); + fflush(stdout); + + /* Check (a + b*c) == a + (b*c) */ + for (i = 0; i < 10000; i++) + { + slong len = n_randint(state, 100) + 1; + mp_limb_t n = n_randtest_not_zero(state); + mp_limb_t c = n_randint(state, n); + nmod_t mod; + + mp_ptr vec = _nmod_vec_init(len); + mp_ptr vec2 = _nmod_vec_init(len); + mp_ptr vec3 = _nmod_vec_init(len); + + nmod_init(&mod, n); + + _nmod_vec_randtest(vec, state, len, mod); + _nmod_vec_randtest(vec2, state, len, mod); + flint_mpn_copyi(vec3, vec2, len); + + _nmod_vec_scalar_mul_nmod(vec3, vec, len, c, mod); + _nmod_vec_add(vec3, vec3, vec2, len, mod); + + _nmod_vec_scalar_addmul_nmod(vec2, vec, len, c, mod); + + result = _nmod_vec_equal(vec2, vec3, len); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("len = %wd, n = %wd\n", len, n); + abort(); + } + + _nmod_vec_clear(vec); + _nmod_vec_clear(vec2); + _nmod_vec_clear(vec3); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_vec/test/t-scalar_mul_nmod.c b/external/flint-2.4.3/nmod_vec/test/t-scalar_mul_nmod.c new file mode 100644 index 0000000..95110da --- /dev/null +++ b/external/flint-2.4.3/nmod_vec/test/t-scalar_mul_nmod.c @@ -0,0 +1,84 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "nmod_vec.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("scalar_mul_nmod...."); + fflush(stdout); + + /* Check (a + b)*c == a*c + b*c */ + for (i = 0; i < 10000; i++) + { + slong len = n_randint(state, 100) + 1; + mp_limb_t n = n_randtest_not_zero(state); + mp_limb_t c = n_randint(state, n); + nmod_t mod; + + mp_ptr vec = _nmod_vec_init(len); + mp_ptr vec2 = _nmod_vec_init(len); + mp_ptr vec3 = _nmod_vec_init(len); + + nmod_init(&mod, n); + + _nmod_vec_randtest(vec, state, len, mod); + _nmod_vec_randtest(vec2, state, len, mod); + + _nmod_vec_add(vec3, vec, vec2, len, mod); + _nmod_vec_scalar_mul_nmod(vec3, vec3, len, c, mod); + + _nmod_vec_scalar_mul_nmod(vec, vec, len, c, mod); + _nmod_vec_scalar_mul_nmod(vec2, vec2, len, c, mod); + _nmod_vec_add(vec, vec, vec2, len, mod); + + result = _nmod_vec_equal(vec, vec3, len); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("len = %wd, n = %wd\n", len, n); + abort(); + } + + _nmod_vec_clear(vec); + _nmod_vec_clear(vec2); + _nmod_vec_clear(vec3); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/nmod_vecxx.h b/external/flint-2.4.3/nmod_vecxx.h new file mode 100644 index 0000000..c630cfe --- /dev/null +++ b/external/flint-2.4.3/nmod_vecxx.h @@ -0,0 +1,417 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +// TODO reference types +// TODO addmul + +// TODO document nmod_vecxx + +#ifndef NMOD_VECXX_H +#define NMOD_VECXX_H + +#include + +#include "nmod_vec.h" + +// TODO reduce dependencies? +#include "fmpzxx.h" +#include "fmpqxx.h" + +#include "flintxx/expression.h" +#include "flintxx/evaluation_tools.h" +#include "flintxx/flint_classes.h" +#include "flintxx/stdmath.h" +#include "flintxx/vector.h" + +namespace flint { +////////////////////////////////////////////////////////////////////////////// +// NMOD CLASS AND RULES +////////////////////////////////////////////////////////////////////////////// +class nmodxx_ctx +{ +private: + nmod_t nmod; + +public: + const nmod_t& _nmod() const {return nmod;} + explicit nmodxx_ctx(mp_limb_t n) {nmod_init(&nmod, n);} + // no destruction necessary + + bool operator==(const nmodxx_ctx& o) const {return nmod.n == o.nmod.n;} + mp_limb_t n() const {return nmod.n;} +}; + +class nmodxx_ctx_srcref +{ +private: + const nmod_t& nmod; + + nmodxx_ctx_srcref(const nmod_t& nm) : nmod(nm) {} + +public: + const nmod_t& _nmod() const {return nmod;} + nmodxx_ctx_srcref(const nmodxx_ctx& c) : nmod(c._nmod()) {} + + static nmodxx_ctx_srcref make(const nmod_t& nm) + {return nmodxx_ctx_srcref(nm);} + + bool operator==(const nmodxx_ctx_srcref& o) const {return nmod.n == o.nmod.n;} + mp_limb_t n() const {return nmod.n;} +}; + +namespace detail { +struct nmodxx_fake_c_type { }; +} // detail +template +class nmodxx_expression + : public expression, Operation, Data> +{ +public: + typedef expression, + Operation, Data> base_t; + + FLINTXX_DEFINE_BASICS(nmodxx_expression) + FLINTXX_DEFINE_CTORS(nmodxx_expression) + FLINTXX_DEFINE_C_REF(nmodxx_expression, detail::nmodxx_fake_c_type, _limb) + + // static functions for nmodxx + static nmodxx_expression make_nored(mp_limb_t n, nmodxx_ctx_srcref c) + { + return nmodxx_expression(Data::make_nored(n, c)); + } + static nmodxx_expression red(mp_limb_t n, nmodxx_ctx_srcref c) + { + nmodxx_expression res = make_nored(n, c); + res.reduce(); + return res; + } + template + static typename mp::enable_if< + traits::is_fmpzxx, nmodxx_expression>::type red( + const Fmpz& n, nmodxx_ctx_srcref c) + { + return make_nored((n % c.n()).template to(), c); + } + template + static typename mp::enable_if< + traits::is_fmpqxx, nmodxx_expression>::type red( + const Fmpq& n, nmodxx_ctx_srcref c) + { + return make_nored((n % fmpzxx(c.n())).template to(), c); + } + // TODO more + + // only makes sense on immediates + nmodxx_ctx_srcref _ctx() const {return this->_data().ctx;} + const nmod_t& _nmod() const {return this->_data().ctx._nmod();} + void reduce() {NMOD_RED(_limb(), _limb(), _nmod());} + void set_nored(mp_limb_t n) {this->_data().inner = n;} + + nmodxx_ctx_srcref estimate_ctx() const; + + evaluated_t create_temporary() const + { + return evaluated_t(estimate_ctx()); + } + + FLINTXX_DEFINE_MEMBER_BINOP(pow) + FLINTXX_DEFINE_MEMBER_UNOP(inv) +}; + +namespace detail { +struct nmodxx_data; +} // detail + +typedef nmodxx_expression nmodxx; +typedef nmodxx_expression > nmodxx_ref; +typedef nmodxx_expression > nmodxx_srcref; + +namespace flint_classes { +template +struct ref_data +{ + typedef void IS_REF_OR_CREF; + typedef Nmod wrapped_t; + + typedef mp_limb_t& data_ref_t; + typedef const mp_limb_t& data_srcref_t; + + mp_limb_t& inner; + nmodxx_ctx_srcref ctx; + + ref_data(Nmod& o) : inner(o._data().inner), ctx(o._data().ctx) {} + + static ref_data make(mp_limb_t& f, nmodxx_ctx_srcref ctx) + { + return ref_data(f, ctx); + } + +private: + ref_data(mp_limb_t& fp, nmodxx_ctx_srcref c) : inner(fp), ctx(c) {} +}; + +template +struct srcref_data +{ + typedef void IS_REF_OR_CREF; + typedef Nmod wrapped_t; + + typedef const mp_limb_t& data_ref_t; + typedef const mp_limb_t& data_srcref_t; + + const mp_limb_t& inner; + nmodxx_ctx_srcref ctx; + + srcref_data(const Nmod& o) : inner(o._data().inner), ctx(o._data().ctx) {} + srcref_data(Ref o) : inner(o._data().inner) {} + + static srcref_data make(const mp_limb_t& f, nmodxx_ctx_srcref ctx) + { + return srcref_data(f, ctx); + } + +private: + srcref_data(const mp_limb_t& fp, nmodxx_ctx_srcref c) : inner(fp), ctx(c) {} +}; +} // flint_classes +namespace detail { +struct nmodxx_data +{ + nmodxx_ctx_srcref ctx; + mp_limb_t inner; + typedef mp_limb_t& data_ref_t; + typedef const mp_limb_t& data_srcref_t; + + nmodxx_data(nmodxx_ctx_srcref c) : ctx(c), inner(0) {} + +private: + nmodxx_data(mp_limb_t n, nmodxx_ctx_srcref c) + : ctx(c), inner(n) {} + +public: + static nmodxx_data make_nored(mp_limb_t n, nmodxx_ctx_srcref c) + { + return nmodxx_data(n, c); + } + + nmodxx_data(const nmodxx_srcref& r) + : ctx(r.estimate_ctx()), inner(r._limb()) {} +}; +} // detail + +// Temporary merging isn't really any use here. On the other hand, it does +// not seem to hurt. Let's leave this for now. -- Tom Bachmann (15/10/2013) +#if 0 +namespace traits { +template<> struct use_temporary_merging : mp::false_ { }; +} // traits +#endif + +namespace traits { +template struct has_nmodxx_ctx : mp::false_ { }; + +template<> struct has_nmodxx_ctx : mp::true_ { }; +template<> struct has_nmodxx_ctx : mp::true_ { }; +template<> struct has_nmodxx_ctx : mp::true_ { }; +} // traits + +namespace detail { +struct has_nmodxx_ctx_predicate +{ + template struct type : traits::has_nmodxx_ctx { }; +}; + +// XXX this is needed for vectors ... +template +struct get_nmodxx_ctx +{ + static nmodxx_ctx_srcref get(const T& t) {return t._ctx();} +}; +template +nmodxx_ctx_srcref get_nmodxx_ctx_func(const T& t) +{ + return get_nmodxx_ctx::get(t); +} +} // detail +namespace tools { +template +nmodxx_ctx_srcref find_nmodxx_ctx(const Expr& e) +{ + return detail::get_nmodxx_ctx_func( + tools::find_subexpr(e)); +} +} // tools +template +inline nmodxx_ctx_srcref +nmodxx_expression::estimate_ctx() const +{ + return tools::find_nmodxx_ctx(*this); +} + +namespace traits { +template struct is_nmodxx : mp::or_< + traits::is_T_expr, + flint_classes::is_source > { }; +} // traits + +namespace rules { +#define NMODXX_COND_S FLINTXX_COND_S(nmodxx) +#define NMODXX_COND_T FLINTXX_COND_T(nmodxx) + +#define NMODXX_DEFINE_INSTANTIATE_TEMPORARIES(Classname) \ +template \ +struct use_default_temporary_instantiation : mp::false_ { }; \ +template \ +struct instantiate_temporaries \ +{ \ + static Classname get(const Expr& e) \ + { \ + return Classname(tools::find_nmodxx_ctx(e)); \ + } \ +}; + +// This is in order to make temporary allocation work even if there is no +// immediate subexpression - c/f test_temporaries +NMODXX_DEFINE_INSTANTIATE_TEMPORARIES(nmodxx) + +FLINTXX_DEFINE_EQUALS(nmodxx, e1._limb() == e2._limb()) + +FLINT_DEFINE_GET_COND(conversion, mp_limb_t, NMODXX_COND_S, from._limb()) + +template +struct to_string >::type> +{ + static std::string get(const Nmod& i, int base /* ignored */) + { + std::ostringstream oss; + oss << i._limb() << " mod " << i._nmod().n; + return oss.str(); + } +}; + +FLINT_DEFINE_DOIT_COND2(assignment, NMODXX_COND_T, NMODXX_COND_S, + to._limb() = from._limb()) + +FLINT_DEFINE_CBINARY_EXPR_COND2(plus, nmodxx, NMODXX_COND_S, NMODXX_COND_S, + to.set_nored(nmod_add(e1._limb(), e2._limb(), to._nmod()))) +FLINT_DEFINE_CBINARY_EXPR_COND2(times, nmodxx, NMODXX_COND_S, NMODXX_COND_S, + to.set_nored(nmod_mul(e1._limb(), e2._limb(), to._nmod()))) +FLINT_DEFINE_BINARY_EXPR_COND2(minus, nmodxx, NMODXX_COND_S, NMODXX_COND_S, + to.set_nored(nmod_sub(e1._limb(), e2._limb(), to._nmod()))) +FLINT_DEFINE_BINARY_EXPR_COND2(divided_by, nmodxx, NMODXX_COND_S, NMODXX_COND_S, + to.set_nored(nmod_div(e1._limb(), e2._limb(), to._nmod()))) + +FLINT_DEFINE_UNARY_EXPR_COND(negate, nmodxx, NMODXX_COND_S, + to.set_nored(nmod_neg(from._limb(), to._nmod()))) + +FLINT_DEFINE_UNARY_EXPR_COND(inv_op, nmodxx, NMODXX_COND_S, + to.set_nored(nmod_inv(from._limb(), to._nmod()))) + +FLINT_DEFINE_BINARY_EXPR_COND2(pow_op, nmodxx, NMODXX_COND_S, + traits::is_unsigned_integer, + to.set_nored(nmod_pow_ui(e1._limb(), e2, to._nmod()))) +} + +////////////////////////////////////////////////////////////////////////////// +// NMOD_VEC CLASS AND RULES +////////////////////////////////////////////////////////////////////////////// +namespace detail { +struct nmod_vector_data +{ + slong size; + mp_limb_t* array; + nmodxx_ctx_srcref ctx; + + nmod_vector_data(slong n, nmodxx_ctx_srcref c) + : size(n), array(_nmod_vec_init(n)), ctx(c) {} + + ~nmod_vector_data() {_nmod_vec_clear(array);} + + nmod_vector_data(const nmod_vector_data& o) + : size(o.size), array(_nmod_vec_init(o.size)), ctx(o.ctx) + { + _nmod_vec_set(array, o.array, size); + } + + nmodxx_ref at(slong i) {return nmodxx_ref::make(array[i], ctx);} + nmodxx_srcref at(slong i) const {return nmodxx_srcref::make(array[i], ctx);} +}; + +struct nmod_vector_traits + : wrapped_vector_traits +{ + template + static typename Expr::evaluated_t create_temporary(const Expr& e) + { + return typename Expr::evaluated_t(e.size(), tools::find_nmodxx_ctx(e)); + } +}; +} // detail + +// TODO would it make more sense to have this have its own class? +typedef vector_expression< + detail::nmod_vector_traits, operations::immediate, + detail::nmod_vector_data> nmod_vecxx; +// TODO references + +namespace traits { +template<> struct has_nmodxx_ctx : mp::true_ { }; +} // traits +namespace detail { +template<> +struct get_nmodxx_ctx +{ + static nmodxx_ctx_srcref get(const nmod_vecxx& v) + { + return v._data().ctx; + } +}; +} // detail + +template<> +struct enable_vector_rules : mp::false_ { }; + +namespace rules { +// TODO hack to make code look like references are implemented +template struct NMOD_VECXX_COND_S : mp::equal_types { }; +#define NMOD_VECXX_COND_T NMOD_VECXX_COND_S + +// TODO references +FLINT_DEFINE_GET(equals, bool, nmod_vecxx, + e1.size() == e2.size() + && _nmod_vec_equal(e1._data().array, e2._data().array, e1.size())) + +FLINT_DEFINE_BINARY_EXPR_COND2(plus, nmod_vecxx, + NMOD_VECXX_COND_S, NMOD_VECXX_COND_S, + _nmod_vec_add(to._data().array, e1._data().array, e2._data().array, + to.size(), to._data().ctx._nmod())) + +// TODO more +} // rules +} // flint + +#endif diff --git a/external/flint-2.4.3/padic.h b/external/flint-2.4.3/padic.h new file mode 100644 index 0000000..aeecf23 --- /dev/null +++ b/external/flint-2.4.3/padic.h @@ -0,0 +1,343 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#ifndef PADIC_H +#define PADIC_H + +#undef ulong +#define ulong ulongxx /* interferes with system includes */ +#include +#include +#undef ulong + +#include +#define ulong mp_limb_t + +#include "flint.h" +#include "fmpz.h" +#include "fmpq.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" + +#ifdef __cplusplus + extern "C" { +#endif + +#define PADIC_DEFAULT_PREC WORD(20) + +#define PADIC_TEST_PREC_MIN WORD(-100) +#define PADIC_TEST_PREC_MAX WORD(100) + +typedef struct { + fmpz u; + slong v; + slong N; +} padic_struct; + +typedef padic_struct padic_t[1]; + +#define padic_unit(x) (&((x)->u)) +#define padic_val(x) ((x)->v) +#define padic_prec(x) ((x)->N) + +enum padic_print_mode +{ + PADIC_TERSE, + PADIC_SERIES, + PADIC_VAL_UNIT +}; + +typedef struct { + + fmpz_t p; + + double pinv; + + fmpz *pow; + slong min; + slong max; + + enum padic_print_mode mode; + +} padic_ctx_struct; + +typedef padic_ctx_struct padic_ctx_t[1]; + +typedef struct { + slong n; + fmpz *pow; +} padic_inv_struct; + +typedef padic_inv_struct padic_inv_t[1]; + +/* Context *******************************************************************/ + +void padic_ctx_init(padic_ctx_t ctx, const fmpz_t p, slong min, slong max, + enum padic_print_mode mode); + +void padic_ctx_clear(padic_ctx_t ctx); + +static __inline__ +int _padic_ctx_pow_ui(fmpz_t rop, ulong e, const padic_ctx_t ctx) +{ + if (ctx->min <= (slong) e && (slong) e < ctx->max) + { + *rop = *(ctx->pow + (e - ctx->min)); + return 0; + } + else + { + slong l = (slong) e; + if (l < 0) + { + flint_printf("WTF??\n"); + flint_printf("e = %wu\n", e); + flint_printf("l = %wd\n", l); + abort(); + } + + fmpz_init(rop); + fmpz_pow_ui(rop, ctx->p, e); + return 1; + } +} + +/* Memory management *********************************************************/ + +void padic_init(padic_t rop); + +void padic_init2(padic_t rop, slong N); + +void padic_clear(padic_t rop); + +static __inline__ void _padic_canonicalise(padic_t rop, const padic_ctx_t ctx) +{ + if (!fmpz_is_zero(padic_unit(rop))) + { + padic_val(rop) += _fmpz_remove(padic_unit(rop), ctx->p, ctx->pinv); + } + else + { + padic_val(rop) = 0; + } +} + +void _padic_reduce(padic_t rop, const padic_ctx_t ctx); + +void padic_reduce(padic_t rop, const padic_ctx_t ctx); + +/* Randomisation *************************************************************/ + +void padic_randtest(padic_t rop, flint_rand_t state, const padic_ctx_t ctx); + +void padic_randtest_not_zero(padic_t rop, flint_rand_t state, + const padic_ctx_t ctx); + +void padic_randtest_int(padic_t rop, flint_rand_t state, + const padic_ctx_t ctx); + +/* Assignments and conversions ***********************************************/ + +void padic_set(padic_t rop, const padic_t op, const padic_ctx_t ctx); + +void padic_set_si(padic_t rop, slong op, const padic_ctx_t ctx); + +void padic_set_ui(padic_t rop, ulong op, const padic_ctx_t ctx); + +void padic_set_fmpz(padic_t rop, const fmpz_t op, const padic_ctx_t ctx); + +void padic_set_fmpq(padic_t rop, const fmpq_t op, const padic_ctx_t ctx); + +void padic_set_mpz(padic_t rop, const mpz_t op, const padic_ctx_t ctx); + +void padic_set_mpq(padic_t rop, const mpq_t op, const padic_ctx_t ctx); + +void padic_get_fmpz(fmpz_t rop, const padic_t op, const padic_ctx_t ctx); + +void padic_get_fmpq(fmpq_t rop, const padic_t op, const padic_ctx_t ctx); + +void padic_get_mpz(mpz_t rop, const padic_t op, const padic_ctx_t ctx); + +void padic_get_mpq(mpq_t rop, const padic_t op, const padic_ctx_t ctx); + +static __inline__ void padic_swap(padic_t op1, padic_t op2) +{ + slong t; + + fmpz_swap(padic_unit(op1), padic_unit(op2)); + + t = padic_val(op1); + padic_val(op1) = padic_val(op2); + padic_val(op2) = t; + + t = padic_prec(op1); + padic_prec(op1) = padic_prec(op2); + padic_prec(op2) = t; +} + +static __inline__ void padic_zero(padic_t rop) +{ + fmpz_zero(padic_unit(rop)); + padic_val(rop) = 0; +} + +static __inline__ void padic_one(padic_t rop) +{ + if (padic_prec(rop) > 0) + { + fmpz_one(padic_unit(rop)); + padic_val(rop) = 0; + } + else + { + padic_zero(rop); + } +} + +/* Comparison ****************************************************************/ + +static __inline__ int padic_is_zero(const padic_t op) +{ + return fmpz_is_zero(padic_unit(op)); +} + +static __inline__ int padic_is_one(const padic_t op) +{ + return fmpz_is_one(padic_unit(op)) && (padic_val(op) == 0); +} + +static __inline__ int padic_equal(const padic_t op1, const padic_t op2) +{ + return (padic_val(op1) == padic_val(op2)) && + (fmpz_equal(padic_unit(op1), padic_unit(op2))); +} + +/* Arithmetic operations *****************************************************/ + +slong * _padic_lifts_exps(slong *n, slong N); + +void _padic_lifts_pows(fmpz *pow, const slong *a, slong n, const fmpz_t p); + +void padic_add(padic_t rop, const padic_t op1, const padic_t op2, + const padic_ctx_t ctx); + +void padic_sub(padic_t rop, const padic_t op1, const padic_t op2, + const padic_ctx_t ctx); + +void padic_neg(padic_t rop, const padic_t op, const padic_ctx_t ctx); + +void padic_mul(padic_t rop, const padic_t op1, const padic_t op2, + const padic_ctx_t ctx); + +void padic_shift(padic_t rop, const padic_t op, slong v, const padic_ctx_t ctx); + +void padic_div(padic_t rop, const padic_t op1, const padic_t op2, + const padic_ctx_t ctx); + +void _padic_inv_precompute(padic_inv_t S, const fmpz_t p, slong N); + +void _padic_inv_clear(padic_inv_t S); + +void _padic_inv_precomp(fmpz_t rop, const fmpz_t op, const padic_inv_t S); + +void _padic_inv(fmpz_t rop, const fmpz_t op, const fmpz_t p, slong N); + +void padic_inv(padic_t rop, const padic_t op, const padic_ctx_t ctx); + +int padic_sqrt(padic_t rop, const padic_t op, const padic_ctx_t ctx); + +void padic_pow_si(padic_t rop, const padic_t op, slong e, + const padic_ctx_t ctx); + +/* Exponential ***************************************************************/ + +slong _padic_exp_bound(slong v, slong N, const fmpz_t p); + +void _padic_exp(fmpz_t rop, const fmpz_t u, slong v, const fmpz_t p, slong N); +void _padic_exp_rectangular(fmpz_t rop, const fmpz_t u, slong v, const fmpz_t p, slong N); +void _padic_exp_balanced(fmpz_t rop, const fmpz_t u, slong v, const fmpz_t p, slong N); + +int padic_exp(padic_t rop, const padic_t op, const padic_ctx_t ctx); +int padic_exp_rectangular(padic_t rop, const padic_t op, const padic_ctx_t ctx); +int padic_exp_balanced(padic_t rop, const padic_t op, const padic_ctx_t ctx); + +/* Logarithm *****************************************************************/ + +slong _padic_log_bound(slong v, slong N, const fmpz_t p); + +void _padic_log(fmpz_t z, const fmpz_t y, slong v, const fmpz_t p, slong N); +void _padic_log_rectangular(fmpz_t z, const fmpz_t y, slong v, const fmpz_t p, slong N); +void _padic_log_satoh(fmpz_t z, const fmpz_t y, slong v, const fmpz_t p, slong N); +void _padic_log_balanced(fmpz_t z, const fmpz_t y, slong v, const fmpz_t p, slong N); + +int padic_log(padic_t rop, const padic_t op, const padic_ctx_t ctx); +int padic_log_rectangular(padic_t rop, const padic_t op, const padic_ctx_t ctx); +int padic_log_satoh(padic_t rop, const padic_t op, const padic_ctx_t ctx); +int padic_log_balanced(padic_t rop, const padic_t op, const padic_ctx_t ctx); + +/* Special functions *********************************************************/ + +void _padic_teichmuller(fmpz_t rop, const fmpz_t op, const fmpz_t p, slong N); + +void padic_teichmuller(padic_t rop, const padic_t op, const padic_ctx_t ctx); + +ulong padic_val_fac_ui_2(ulong N); + +ulong padic_val_fac_ui(ulong N, const fmpz_t p); + +void padic_val_fac(fmpz_t rop, const fmpz_t op, const fmpz_t p); + +/* Input and output **********************************************************/ + +char * padic_get_str(char * str, const padic_t op, const padic_ctx_t ctx); + +int _padic_fprint(FILE * file, const fmpz_t u, slong v, const padic_ctx_t ctx); + +int padic_fprint(FILE * file, const padic_t op, const padic_ctx_t ctx); + +static __inline__ +int _padic_print(const fmpz_t u, slong v, const padic_ctx_t ctx) +{ + return _padic_fprint(stdout, u, v, ctx); +} + +static __inline__ int padic_print(const padic_t op, const padic_ctx_t ctx) +{ + return padic_fprint(stdout, op, ctx); +} + +static __inline__ void padic_debug(const padic_t op) +{ + flint_printf("("); + fmpz_print(padic_unit(op)); + flint_printf(" %wd %wd)", padic_val(op), padic_prec(op)); +} + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/external/flint-2.4.3/padic/add.c b/external/flint-2.4.3/padic/add.c new file mode 100644 index 0000000..d6bdd1a --- /dev/null +++ b/external/flint-2.4.3/padic/add.c @@ -0,0 +1,127 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "padic.h" + +void padic_add(padic_t rop, const padic_t op1, const padic_t op2, + const padic_ctx_t ctx) +{ + if (padic_prec(rop) <= FLINT_MIN(padic_val(op1), padic_val(op2))) + { + padic_zero(rop); + return; + } + + if (padic_is_zero(op1)) + { + padic_set(rop, op2, ctx); + } + else if (padic_is_zero(op2)) + { + padic_set(rop, op1, ctx); + } + else + { + if (padic_val(op1) == padic_val(op2)) + { + + fmpz_add(padic_unit(rop), padic_unit(op1), padic_unit(op2)); + padic_val(rop) = padic_val(op1); + + _padic_canonicalise(rop, ctx); + + if (padic_prec(rop) <= padic_val(rop)) + { + padic_zero(rop); + return; + } + } + else if (padic_val(op1) < padic_val(op2)) + { + fmpz_t f; + + fmpz_init(f); + fmpz_pow_ui(f, ctx->p, padic_val(op2) - padic_val(op1)); + if (rop != op2) + { + fmpz_set(padic_unit(rop), padic_unit(op1)); + fmpz_addmul(padic_unit(rop), f, padic_unit(op2)); + } + else + { + fmpz_mul(padic_unit(rop), f, padic_unit(op2)); + fmpz_add(padic_unit(rop), padic_unit(rop), padic_unit(op1)); + } + fmpz_clear(f); + + padic_val(rop) = padic_val(op1); + } + else /* padic_val(op1) > padic_val(op2) */ + { + fmpz_t f; + + fmpz_init(f); + fmpz_pow_ui(f, ctx->p, padic_val(op1) - padic_val(op2)); + if (rop != op1) + { + fmpz_set(padic_unit(rop), padic_unit(op2)); + fmpz_addmul(padic_unit(rop), f, padic_unit(op1)); + } + else + { + fmpz_mul(padic_unit(rop), f, padic_unit(op1)); + fmpz_add(padic_unit(rop), padic_unit(rop), padic_unit(op2)); + } + fmpz_clear(f); + + padic_val(rop) = padic_val(op2); + } + + /* Reduce */ + { + int alloc; + fmpz_t pow; + + alloc = _padic_ctx_pow_ui(pow, padic_prec(rop) - padic_val(rop), ctx); + + if (padic_prec(rop) >= FLINT_MAX(padic_prec(op1), padic_prec(op2))) + { + if (fmpz_cmpabs(padic_unit(rop), pow) >= 0) + fmpz_sub(padic_unit(rop), padic_unit(rop), pow); + } + else + { + fmpz_mod(padic_unit(rop), padic_unit(rop), pow); + } + + if (fmpz_is_zero(padic_unit(rop))) + padic_val(rop) = 0; + + if (alloc) + fmpz_clear(pow); + } + } +} + diff --git a/external/flint-2.4.3/padic/clear.c b/external/flint-2.4.3/padic/clear.c new file mode 100644 index 0000000..2921f09 --- /dev/null +++ b/external/flint-2.4.3/padic/clear.c @@ -0,0 +1,32 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "padic.h" + +void padic_clear(padic_t rop) +{ + fmpz_clear(padic_unit(rop)); +} + diff --git a/external/flint-2.4.3/padic/ctx_clear.c b/external/flint-2.4.3/padic/ctx_clear.c new file mode 100644 index 0000000..5a98853 --- /dev/null +++ b/external/flint-2.4.3/padic/ctx_clear.c @@ -0,0 +1,37 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "padic.h" + +void padic_ctx_clear(padic_ctx_t ctx) +{ + fmpz_clear(ctx->p); + + if (ctx->pow) + { + _fmpz_vec_clear(ctx->pow, ctx->max - ctx->min); + } +} + diff --git a/external/flint-2.4.3/padic/ctx_init.c b/external/flint-2.4.3/padic/ctx_init.c new file mode 100644 index 0000000..e0cca26 --- /dev/null +++ b/external/flint-2.4.3/padic/ctx_init.c @@ -0,0 +1,63 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "padic.h" + +void padic_ctx_init(padic_ctx_t ctx, const fmpz_t p, slong min, slong max, + enum padic_print_mode mode) +{ + if (!(0 <= min && min <= max)) + { + flint_printf("Exception (padic_ctx_init). Require 0 <= min <= max."); + abort(); + } + + fmpz_init_set(ctx->p, p); + + ctx->min = min; + ctx->max = max; + + ctx->pinv = (!COEFF_IS_MPZ(*p)) ? n_precompute_inverse(fmpz_get_ui(p)) : 0; + + if (max - min > 0) + { + slong i, len = max - min; + + ctx->pow = _fmpz_vec_init(len); + + fmpz_pow_ui(ctx->pow, p, ctx->min); + for (i = 1; i < len; i++) + fmpz_mul(ctx->pow + i, ctx->pow + (i - 1), p); + } + else + { + ctx->min = 0; + ctx->max = 0; + ctx->pow = NULL; + } + + ctx->mode = mode; +} + diff --git a/external/flint-2.4.3/padic/div.c b/external/flint-2.4.3/padic/div.c new file mode 100644 index 0000000..23f7ce5 --- /dev/null +++ b/external/flint-2.4.3/padic/div.c @@ -0,0 +1,55 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "padic.h" + +void padic_div(padic_t rop, const padic_t op1, const padic_t op2, + const padic_ctx_t ctx) +{ + if (padic_is_zero(op2)) + { + flint_printf("Exception (padic_div). op2 is zero.\n"); + abort(); + } + + if (padic_is_zero(op1) || padic_val(op1) - padic_val(op2) >= padic_prec(rop)) + { + padic_zero(rop); + } + else + { + padic_t inv; + + padic_init(inv); + + _padic_inv(padic_unit(inv), padic_unit(op2), ctx->p, + padic_prec(rop) - padic_val(op1) + padic_val(op2)); + padic_val(inv) = - padic_val(op2); + padic_mul(rop, op1, inv, ctx); + + padic_clear(inv); + } +} + diff --git a/external/flint-2.4.3/padic/doc/padic.txt b/external/flint-2.4.3/padic/doc/padic.txt new file mode 100644 index 0000000..86cd4e3 --- /dev/null +++ b/external/flint-2.4.3/padic/doc/padic.txt @@ -0,0 +1,628 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +******************************************************************************* + + Data structures + + A $p$-adic number of type \code{padic_t} comprises a unit~$u$, + a valuation~$v$, and a precision~$N$. + + We provide the following macros to access these fields, so that + code can be developed somewhat independently from the underlying + data layout. + +******************************************************************************* + +fmpz * padic_unit(const padic_t op) + + Returns the unit part of the $p$-adic number as a FLINT integer, which + can be used as an operand for the \code{fmpz} functions. + + Note that this function is implemented as a macro, but it can only be + used as an \emph{rvalue}. + +slong padic_val(const padic_t op) + + Returns the valuation part of the $p$-adic number. + + Note that this function is implemented as a macro and that + the expression \code{padic_val(op)} can be used as both an + \emph{lvalue} and an \emph{rvalue}. + +slong padic_prec(const padic_t op) + + Returns the precision of the $p$-adic number. + + Note that this function is implemented as a macro and that + the expression \code{padic_prec(op)} can be used as both an + \emph{lvalue} and an \emph{rvalue}. + +******************************************************************************* + + Context + + A context object for $p$-adic arithmetic contains data pertinent to + $p$-adic computations, but which we choose not to store with each + element individually. + + Currently, this includes the prime number~$p$, its \code{double} + inverse in case of word-sized primes, precomputed powers of $p$ + in the range given by \code{min} and \code{max}, and the printing + mode. + +******************************************************************************* + +void padic_ctx_init(padic_ctx_t ctx, const fmpz_t p, slong min, slong max, + enum padic_print_mode mode) + + Initialises the context \code{ctx} with the given data. + + Assumes that $p$ is a prime. This is not verified but the subsequent + behaviour is undefined if $p$ is a composite number. + + Assumes that \code{min} and \code{max} are non-negative and that + \code{min} is at most \code{max}, raising and \code{abort} signal + otherwise. + + Assumes that the printing mode is one of \code{PADIC_TERSE}, + \code{PADIC_SERIES}, or\\ \code{PADIC_VAL_UNIT}. Using the example + $x = 7^{-1} 12$ in $\mathbf{Q}_7$, these behave as follows: + \begin{itemize} + \item In \code{PADIC_TERSE} mode, a $p$-adic number is printed + in the same way as a rational number, e.g.\ \code{12/7}. + \item In \code{PADIC_SERIES} mode, a $p$-adic number is printed + digit by digit, e.g.\ \code{5*7^-1 + 1}. + \item In \code{PADIC_VAL_UNIT} mode, a $p$-adic number is + printed showing the valuation and unit parts separately, + e.g.\ \code{12*7^-1}. + \end{itemize} + +void padic_ctx_clear(padic_ctx_t ctx); + + Clears all memory that has been allocated as part of the context. + +int _padic_ctx_pow_ui(fmpz_t rop, ulong e, const padic_ctx_t ctx) + + Sets \code{rop} to $p^e$ as efficiently as possible, where + \code{rop} is expected to be an uninitialised \code{fmpz_t}. + + If the return value is non-zero, it is the responsibility of + the caller to clear the returned integer. + +******************************************************************************* + + Memory management + +******************************************************************************* + +void padic_init(padic_t rop) + + Initialises the $p$-adic number with the precision set to + \code{PADIC_DEFAULT_PREC}, which is defined as~$20$. + +void padic_init2(padic_t rop, slong N) + + Initialises the $p$-adic number \code{rop} with precision~$N$. + +void padic_clear(padic_t rop) + + Clears all memory used by the $p$-adic number \code{rop}. + +void _padic_canonicalise(padic_t rop, const padic_ctx_t ctx) + + Brings the $p$-adic number \code{rop} into canonical form. + + That is to say, ensures that either $u = v = 0$ or + $p \nmid u$. There is no reduction modulo a power + of $p$. + +void _padic_reduce(padic_t rop, const padic_ctx_t ctx) + + Given a $p$-adic number \code{rop} in canonical form, + reduces it modulo $p^N$. + +void padic_reduce(padic_t rop, const padic_ctx_t ctx) + + Ensures that the $p$-adic number \code{rop} is reduced. + +******************************************************************************* + + Randomisation + +******************************************************************************* + +void padic_randtest(padic_t rop, flint_rand_t state, const padic_ctx_t ctx) + + Sets \code{rop} to a random $p$-adic number modulo $p^N$ with valuation + in the range $[- \ceil{N/10}, N)$, $[N - \ceil{-N/10}, N)$, or $[-10, 0)$ + as $N$ is positive, negative or zero, whenever \code{rop} is non-zero. + +void padic_randtest_not_zero(padic_t rop, flint_rand_t state, + const padic_ctx_t ctx) + + Sets \code{rop} to a random non-zero $p$-adic number modulo $p^N$, + where the range of the valuation is as for the function + \code{padic_randtest()}. + +void padic_randtest_int(padic_t rop, flint_rand_t state, + const padic_ctx_t ctx) + + Sets \code{rop} to a random $p$-adic integer modulo $p^N$. + + Note that whenever $N \leq 0$, \code{rop} is set to zero. + +******************************************************************************* + + Assignments and conversions + + All assignment functions set the value of \code{rop} from \code{op}, + reduced to the precision of \code{rop}. + +******************************************************************************* + +void padic_set(padic_t rop, const padic_t op, const padic_ctx_t ctx) + + Sets \code{rop} to the $p$-adic number \code{op}. + +void padic_set_si(padic_t rop, slong op, const padic_ctx_t ctx) + + Sets the $p$-adic number \code{rop} to the + \code{slong} integer \code{op}. + +void padic_set_ui(padic_t rop, ulong op, const padic_ctx_t ctx) + + Sets the $p$-adic number \code{rop} to the \code{ulong} + integer \code{op}. + +void padic_set_fmpz(padic_t rop, const fmpz_t op, const padic_ctx_t ctx) + + Sets the $p$-adic number \code{rop} to the integer \code{op}. + +void padic_set_fmpq(padic_t rop, const fmpq_t op, const padic_ctx_t ctx) + + Sets \code{rop} to the rational \code{op}. + +void padic_set_mpz(padic_t rop, const mpz_t op, const padic_ctx_t ctx) + + Sets the $p$-adic number \code{rop} to the MPIR integer \code{op}. + +void padic_set_mpq(padic_t rop, const mpq_t op, const padic_ctx_t ctx) + + Sets \code{rop} to the MPIR rational \code{op}. + +void padic_get_fmpz(fmpz_t rop, const padic_t op, const padic_ctx_t ctx) + + Sets the integer \code{rop} to the exact $p$-adic integer \code{op}. + + If \code{op} is not a $p$-adic integer, raises an \code{abort} signal. + +void padic_get_fmpq(fmpq_t rop, const padic_t op, const padic_ctx_t ctx) + + Sets the rational \code{rop} to the $p$-adic number \code{op}. + +void padic_get_mpz(mpz_t rop, const padic_t op, const padic_ctx_t ctx) + + Sets the MPIR integer \code{rop} to the $p$-adic integer \code{op}. + + If \code{op} is not a $p$-adic integer, raises an \code{abort} signal. + +void padic_get_mpq(mpq_t rop, const padic_t op, const padic_ctx_t ctx) + + Sets the MPIR rational \code{rop} to the value of \code{op}. + +void padic_swap(padic_t op1, padic_t op2) + + Swaps the two $p$-adic numbers \code{op1} and \code{op2}. + + Note that this includes swapping the precisions. In particular, this + operation is not equivalent to swapping \code{op1} and \code{op2} + using \code{padic_set()} and an auxiliary variable whenever the + precisions of the two elements are different. + +void padic_zero(padic_t rop) + + Sets the $p$-adic number \code{rop} to zero. + +void padic_one(padic_t rop) + + Sets the $p$-adic number \code{rop} to one, reduced modulo the + precision of \code{rop}. + +******************************************************************************* + + Comparison + +******************************************************************************* + +int padic_is_zero(const padic_t op) + + Returns whether \code{op} is equal to zero. + +int padic_is_one(const padic_t op) + + Returns whether \code{op} is equal to one, that is, whether + $u = 1$ and $v = 0$. + +int padic_equal(const padic_t op1, const padic_t op2) + + Returns whether \code{op1} and \code{op2} are equal, that is, + whether $u_1 = u_2$ and $v_1 = v_2$. + +******************************************************************************* + + Arithmetic operations + +******************************************************************************* + +slong * _padic_lifts_exps(slong *n, slong N) + + Given a positive integer $N$ define the sequence + $a_0 = N, a_1 = \ceil{a_0/2}, \dotsc, a_{n-1} = \ceil{a_{n-2}/2} = 1$. + Then $n = \ceil{\log_2 N} + 1$. + + This function sets $n$ and allocates and returns the array~$a$. + +void _padic_lifts_pows(fmpz *pow, const slong *a, slong n, const fmpz_t p) + + Given an array~$a$ as computed above, this function + computes the corresponding powers of $p$, that is, + \code{pow[i]} is equal to $p^{a_i}$. + +void padic_add(padic_t rop, const padic_t op1, const padic_t op2, + const padic_ctx_t ctx) + + Sets \code{rop} to the sum of \code{op1} and \code{op2}. + +void padic_sub(padic_t rop, const padic_t op1, const padic_t op2, + const padic_ctx_t ctx) + + Sets \code{rop} to the difference of \code{op1} and \code{op2}. + +void padic_neg(padic_t rop, const padic_t op, const padic_ctx_t ctx) + + Sets \code{rop} to the additive inverse of \code{op}. + +void padic_mul(padic_t rop, const padic_t op1, const padic_t op2, + const padic_ctx_t ctx) + + Sets \code{rop} to the product of \code{op1} and \code{op2}. + +void padic_shift(padic_t rop, const padic_t op, slong v, const padic_ctx_t ctx) + + Sets \code{rop} to the product of \code{op} and $p^v$. + +void padic_div(padic_t rop, const padic_t op1, const padic_t op2, + const padic_ctx_t ctx) + + Sets \code{rop} to the quotient of \code{op1} and \code{op2}. + +void _padic_inv_precompute(padic_inv_t S, const fmpz_t p, slong N) + + Pre-computes some data and allocates temporary space for + $p$-adic inversion using Hensel lifting. + +void _padic_inv_clear(padic_inv_t S) + + Frees the memory used by $S$. + +void _padic_inv_precomp(fmpz_t rop, const fmpz_t op, const padic_inv_t S) + + Sets \code{rop} to the inverse of \code{op} modulo $p^N$, + assuming that \code{op} is a unit and $N \geq 1$. + + In the current implementation, allows aliasing, but this might + change in future versions. + + Uses some data $S$ precomputed by calling the function + \code{_padic_inv_precompute()}. Note that this object + is not declared \code{const} and in fact it carries a field + providing temporary work space. This allows repeated calls of + this function to avoid repeated memory allocations, as used + e.g.\ by the function \code{padic_log()}. + +void _padic_inv(fmpz_t rop, const fmpz_t op, const fmpz_t p, slong N) + + Sets \code{rop} to the inverse of \code{op} modulo $p^N$, + assuming that \code{op} is a unit and $N \geq 1$. + + In the current implementation, allows aliasing, but this might + change in future versions. + +void padic_inv(padic_t rop, const padic_t op, const padic_ctx_t ctx) + + Computes the inverse of \code{op} modulo $p^N$. + + Suppose that \code{op} is given as $x = u p^v$. + Raises an \code{abort} signal if $v < -N$. Otherwise, + computes the inverse of $u$ modulo $p^{N+v}$. + + This function employs Hensel lifting of an inverse modulo $p$. + +int padic_sqrt(padic_rop, const padic_t op, const padic_ctx_t ctx) + + Returns whether \code{op} is a $p$-adic square. If this is + the case, sets \code{rop} to one of the square roots; otherwise, + the value of \code{rop} is undefined. + + We have the following theorem: + + Let $u \in \mathbf{Z}^{\times}$. Then $u$ is a + square if and only if $u \bmod p$ is a square in + $\mathbf{Z} / p \mathbf{Z}$, for $p > 2$, or if + $u \bmod 8$ is a square in $\mathbf{Z} / 8 \mathbf{Z}$, + for $p = 2$. + +void padic_pow_si(padic_t rop, const padic_t op, slong e, + const padic_ctx_t ctx) + + Sets \code{rop} to \code{op} raised to the power~$e$, + which is defined as one whenever $e = 0$. + + Assumes that some computations involving $e$ and the + valuation of \code{op} do not overflow in the \code{slong} + range. + + Note that if the input $x = p^v u$ is defined modulo $p^N$ + then $x^e = p^{ev} u^e$ is defined modulo $p^{N + (e - 1) v}$, + which is a precision loss in case $v < 0$. + +******************************************************************************* + + Exponential + +******************************************************************************* + +slong _padic_exp_bound(slong v, slong N, const fmpz_t p) + + Returns an integer $i$ such that for all $j \geq i$ we have + $\ord_p(x^j / j!) \geq N$, where $\ord_p(x) = v$. + + When $p$ is a word-sized prime, + returns $\ceil{\frac{(p-1)N - 1}{(p-1)v - 1}}$. + Otherwise, returns $\ceil{N/v}$. + + Assumes that $v < N$. Moreover, $v$ has to be at least $2$ or $1$, + depending on whether $p$ is $2$ or odd. + +void _padic_exp_rectangular(fmpz_t rop, const fmpz_t u, slong v, + const fmpz_t p, slong N) + +void _padic_exp_balanced(fmpz_t rop, const fmpz_t u, slong v, + const fmpz_t p, slong N) + +void _padic_exp(fmpz_t rop, const fmpz_t u, slong v, const fmpz_t p, slong N) + + Sets \code{rop} to the $p$-exponential function evaluated at + $x = p^v u$, reduced modulo~$p^N$. + + Assumes that $x \neq 0$, that $\ord_p(x) < N$ and that + $\exp(x)$ converges, that is, that $\ord_p(x)$ is at least + $2$ or $1$ depending on whether the prime~$p$ is $2$ or odd. + + Supports aliasing between \code{rop} and $u$. + +int padic_exp(padic_t y, const padic_t x, const padic_ctx_t ctx) + + Returns whether the $p$-adic exponential function converges at + the $p$-adic number $x$, and if so sets $y$ to its value. + + The $p$-adic exponential function is defined by the usual series + \begin{equation*} + \exp_p(x) = \sum_{i = 0}^{\infty} \frac{x^i}{i!} + \end{equation*} + but this only converges only when $\ord_p(x) > 1 / (p - 1)$. For + elements $x \in \mathbf{Q}_p$, this means that $\ord_p(x) \geq 1$ + when $p \geq 3$ and $\ord_2(x) \geq 2$ when $p = 2$. + +int padic_exp_rectangular(padic_t y, const padic_t x, const padic_ctx_t ctx) + + Returns whether the $p$-adic exponential function converges at + the $p$-adic number $x$, and if so sets $y$ to its value. + + Uses a rectangular splitting algorithm to evaluate the series + expression of $\exp(x) \bmod{p^N}$. + +int padic_exp_balanced(padic_t y, const padic_t x, const padic_ctx_t ctx) + + Returns whether the $p$-adic exponential function converges at + the $p$-adic number $x$, and if so sets $y$ to its value. + + Uses a balanced approach, balancing the size of chunks of $x$ + with the valuation and hence the rate of convergence, which + results in a quasi-linear algorithm in $N$, for fixed $p$. + +******************************************************************************* + + Logarithm + +******************************************************************************* + +slong _padic_log_bound(slong v, slong N, const fmpz_t p) + + Returns $b$ such that for all $i \geq b$ we have + \begin{equation*} + i v - \ord_p(i) \geq N + \end{equation*} + where $v \geq 1$. + + Assumes that $1 \leq v < N$ or $2 \leq v < N$ when $p$ is + odd or $p = 2$, respectively, and also that $N < 2^{f-2}$ + where $f$ is \code{FLINT_BITS}. + +void _padic_log(fmpz_t z, const fmpz_t y, slong v, const fmpz_t p, slong N) + +void _padic_log_rectangular(fmpz_t z, + const fmpz_t y, slong v, const fmpz_t p, slong N) + +void _padic_log_satoh(fmpz_t z, + const fmpz_t y, slong v, const fmpz_t p, slong N) + +void _padic_log_balanced(fmpz_t z, + const fmpz_t y, slong v, const fmpz_t p, slong N) + + Computes + \begin{equation*} + z = - \sum_{i = 1}^{\infty} \frac{y^i}{i} \pmod{p^N}, + \end{equation*} + reduced modulo $p^N$. + + Note that this can be used to compute the $p$-adic logarithm + via the equation + \begin{align*} + \log(x) & = \sum_{i=1}^{\infty} (-1)^{i-1} \frac{(x-1)^i}{i} \\ + & = - \sum_{i=1}^{\infty} \frac{(1-x)^i}{i}. + \end{align*} + + Assumes that $y = 1 - x$ is non-zero and that $v = \ord_p(y)$ + is at least $1$ when $p$ is odd and at least $2$ when $p = 2$ + so that the series converges. + + Assumes that $v < N$, and hence in particular $N \geq 2$. + + Does not support aliasing between $y$ and $z$. + +int padic_log(padic_t rop, const padic_t op, const padic_ctx_t ctx) + + Returns whether the $p$-adic logarithm function converges at + the $p$-adic number \code{op}, and if so sets \code{rop} to its + value. + + The $p$-adic logarithm function is defined by the usual series + \begin{equation*} + \log_p(x) = \sum_{i=1}^{\infty} (-1)^{i-1} \frac{(x-1)^i}{i} + \end{equation*} + but this only converges when $\ord_p(x)$ is at least $2$ or $1$ + when $p = 2$ or $p > 2$, respectively. + +int padic_log_rectangular(padic_t rop, const padic_t op, const padic_ctx_t ctx) + + Returns whether the $p$-adic logarithm function converges at + the $p$-adic number \code{op}, and if so sets \code{rop} to its + value. + + Uses a rectangular splitting algorithm to evaluate the series + expression of $\log(x) \bmod{p^N}$. + +int padic_log_satoh(padic_t rop, const padic_t op, const padic_ctx_t ctx) + + Returns whether the $p$-adic logarithm function converges at + the $p$-adic number \code{op}, and if so sets \code{rop} to its + value. + + Uses an algorithm based on a result of Satoh, Skjernaa and Taguchi + that $\ord_p\bigl(a^{p^k} - 1\bigr) > k$, which implies that + \begin{equation*} + \log(a) \equiv p^{-k} \Bigl( \log\bigl(a^{p^k}\bigr) \pmod{p^{N+k}} + \Bigr) \pmod{p^N}. + \end{equation*} + +int padic_log_balanced(padic_t rop, const padic_t op, const padic_ctx_t ctx) + + Returns whether the $p$-adic logarithm function converges at + the $p$-adic number \code{op}, and if so sets \code{rop} to its + value. + +******************************************************************************* + + Special functions + +******************************************************************************* + +void _padic_teichmuller(fmpz_t rop, const fmpz_t op, const fmpz_t p, slong N) + + Computes the Teichmuller lift of the $p$-adic unit \code{op}, + assuming that $N \geq 1$. + + Supports aliasing between \code{rop} and \code{op}. + +void padic_teichmuller(padic_t rop, const padic_t op, const padic_ctx_t ctx) + + Computes the Teichmuller lift of the $p$-adic unit \code{op}. + + If \code{op} is a $p$-adic integer divisible by $p$, sets \code{rop} + to zero, which satisfies $t^p - t = 0$, although it is clearly not + a $(p-1)$-st root of unity. + + If \code{op} has negative valuation, raises an \code{abort} signal. + +ulong padic_val_fac_ui_2(ulong n) + + Computes the $2$-adic valuation of $n!$. + + Note that since $n$ fits into an \code{ulong}, so does + $\ord_2(n!)$ since $\ord_2(n!) \leq (n - 1) / (p - 1) = n - 1$. + +ulong padic_val_fac_ui(ulong n, const fmpz_t p) + + Computes the $p$-adic valuation of $n!$. + + Note that since $n$ fits into an \code{ulong}, so does + $\ord_p(n!)$ since $\ord_p(n!) \leq (n - 1) / (p - 1)$. + +void padic_val_fac(fmpz_t rop, const fmpz_t op, const fmpz_t p) + + Sets \code{rop} to the $p$-adic valuation of the factorial + of \code{op}, assuming that \code{op} is non-negative. + +******************************************************************************* + + Input and output + +******************************************************************************* + +char * padic_get_str(char * str, const padic_t op, const padic_ctx_t ctx) + + Returns the string representation of the $p$-adic number \code{op} + according to the printing mode set in the context. + + If \code{str} is \code{NULL} then a new block of memory is allocated + and a pointer to this is returned. Otherwise, it is assumed that + the string \code{str} is large enough to hold the representation and + it is also the return value. + +int _padic_fprint(FILE * file, const fmpz_t u, slong v, const padic_ctx_t ctx) + +int padic_fprint(FILE * file, const padic_t op, const padic_ctx_t ctx) + + Prints the string representation of the $p$-adic number \code{op} + to the stream \code{file}. + + In the current implementation, always returns $1$. + +int _padic_print(const fmpz_t u, slong v, const padic_ctx_t ctx) + +int padic_print(const padic_t op, const padic_ctx_t ctx) + + Prints the string representation of the $p$-adic number \code{op} + to the stream \code{stdout}. + + In the current implementation, always returns $1$. + +void padic_debug(const padic_t op) + + Prints debug information about \code{op} to the stream \code{stdout}, + in the format \code{"(u v N)"}. + diff --git a/external/flint-2.4.3/padic/exp.c b/external/flint-2.4.3/padic/exp.c new file mode 100644 index 0000000..20f9697 --- /dev/null +++ b/external/flint-2.4.3/padic/exp.c @@ -0,0 +1,98 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + Copyright (C) 2012 Fredrik Johansson + +******************************************************************************/ + +#include "padic.h" + +slong _padic_exp_bound(slong v, slong N, const fmpz_t p) +{ + if (fmpz_fits_si(p)) + { + fmpz_t n, d, f; + slong i; + + fmpz_init(n); + fmpz_init(d); + fmpz_init(f); + + fmpz_sub_ui(f, p, 1); + fmpz_mul_ui(n, f, N); + fmpz_sub_ui(n, n, 1); + fmpz_mul_ui(d, f, v); + fmpz_sub_ui(d, d, 1); + fmpz_cdiv_q(f, n, d); + i = fmpz_get_si(f); + + fmpz_clear(n); + fmpz_clear(d); + fmpz_clear(f); + + return i; + } + else + { + return (N + (v - 1)) / v; + } +} + +void _padic_exp(fmpz_t rop, const fmpz_t u, slong v, const fmpz_t p, slong N) +{ + if (N < 1024) + _padic_exp_rectangular(rop, u, v, p, N); + else + _padic_exp_balanced(rop, u, v, p, N); +} + +int padic_exp(padic_t rop, const padic_t op, const padic_ctx_t ctx) +{ + const slong N = padic_prec(rop); + const slong v = padic_val(op); + const fmpz *p = ctx->p; + + if (padic_is_zero(op)) + { + padic_one(rop); + return 1; + } + + if ((fmpz_equal_ui(p, 2) && v <= 1) || (v <= 0)) + { + return 0; + } + else + { + if (v < N) + { + _padic_exp(padic_unit(rop), padic_unit(op), padic_val(op), p, N); + padic_val(rop) = 0; + } + else + { + padic_one(rop); + } + return 1; + } +} + diff --git a/external/flint-2.4.3/padic/exp_balanced.c b/external/flint-2.4.3/padic/exp_balanced.c new file mode 100644 index 0000000..fe5b930 --- /dev/null +++ b/external/flint-2.4.3/padic/exp_balanced.c @@ -0,0 +1,263 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Fredrik Johansson + +******************************************************************************/ + +#include "padic.h" + +/* + Computes the sum + \begin{equation*} + (a-1)! x^{1-a} \sum_{i=a}^{b-1} \frac{x^i}{i!}. + \end{equation*} + in the rational $(T, Q)$. + + Assumes that $1 \leq a < b$. + + If $a + 1 = b$, sets $P = x$, $Q = a$, and $T = x$. + If $a + 2 = b$, sets $P = x^2$, $Q = a (a + 1)$, $T = x (a + 1) + x^2$. + In general, sets + \begin{align*} + P & = x^{b-a}, \\ + Q & = \frac{(b-1)!}{(a-1)!}, \\ + T & = (b-1)! x^{1-a} \sum_{i=a}^{b-1} \frac{x^i}{i!}. + \end{align*} + */ + +static void +_padic_exp_bsplit_series(fmpz_t P, fmpz_t Q, fmpz_t T, + const fmpz_t x, slong a, slong b) +{ + if (b - a == 1) + { + fmpz_set(P, x); + fmpz_set_ui(Q, a); + fmpz_set(T, x); + } + else if (b - a == 2) + { + fmpz_mul(P, x, x); + fmpz_set_ui(Q, a); + fmpz_mul_ui(Q, Q, a + 1); + fmpz_mul_ui(T, x, a + 1); + fmpz_add(T, T, P); + } + else + { + const slong m = (a + b) / 2; + + fmpz_t PR, QR, TR; + + fmpz_init(PR); + fmpz_init(QR); + fmpz_init(TR); + + _padic_exp_bsplit_series(P, Q, T, x, a, m); + _padic_exp_bsplit_series(PR, QR, TR, x, m, b); + + fmpz_mul(T, T, QR); + fmpz_addmul(T, P, TR); + fmpz_mul(P, P, PR); + fmpz_mul(Q, Q, QR); + + fmpz_clear(PR); + fmpz_clear(QR); + fmpz_clear(TR); + } +} + +/* + Assumes that $x$ is such that $\exp(x)$ converges. + + Assumes that $v = \ord_p(x)$ with $v < N$, + which also forces $N$ to positive. + + The result $y$ might not be reduced modulo $p^N$. + + Supports aliasing between $x$ and $y$. + */ + +static void +_padic_exp_bsplit(fmpz_t y, const fmpz_t x, slong v, const fmpz_t p, slong N) +{ + const slong n = _padic_exp_bound(v, N, p); + + if (n == 1) + { + fmpz_one(y); + } + else + { + fmpz_t P, Q, T; + + fmpz_init(P); + fmpz_init(Q); + fmpz_init(T); + + _padic_exp_bsplit_series(P, Q, T, x, 1, n); + + fmpz_add(T, T, Q); /* (T,Q) := (T,Q) + 1 */ + + /* Note exp(x) is a unit so val(T) == val(Q). */ + if (fmpz_remove(T, T, p)) + fmpz_remove(Q, Q, p); + + _padic_inv(Q, Q, p, N); + fmpz_mul(y, T, Q); + + fmpz_clear(P); + fmpz_clear(Q); + fmpz_clear(T); + } +} + +void _padic_exp_balanced_2(fmpz_t rop, const fmpz_t xu, slong xv, slong N) +{ + const fmpz_t p = {WORD(2)}; + + fmpz_t r, t; + slong w; + + fmpz_init(r); + fmpz_init(t); + + w = 1; + + fmpz_mul_2exp(t, xu, xv); + fmpz_fdiv_r_2exp(t, t, N); + + fmpz_one(rop); + + while (!fmpz_is_zero(t)) + { + fmpz_fdiv_r_2exp(r, t, 2*w); + fmpz_sub(t, t, r); + + if (!fmpz_is_zero(r)) + { + _padic_exp_bsplit(r, r, w, p, N); + fmpz_mul(rop, rop, r); + fmpz_fdiv_r_2exp(rop, rop, N); + } + + w *= 2; + } + + fmpz_clear(r); + fmpz_clear(t); +} + +void _padic_exp_balanced_p(fmpz_t rop, const fmpz_t xu, slong xv, + const fmpz_t p, slong N) +{ + fmpz_t r, t, pw, pN; + slong w; + + fmpz_init(r); + fmpz_init(t); + fmpz_init(pw); + fmpz_init(pN); + + fmpz_set(pw, p); + fmpz_pow_ui(pN, p, N); + w = 1; + + fmpz_pow_ui(t, p, xv); + fmpz_mul(t, t, xu); + fmpz_mod(t, t, pN); + + fmpz_one(rop); + + while (!fmpz_is_zero(t)) + { + fmpz_mul(pw, pw, pw); + + fmpz_fdiv_r(r, t, pw); + fmpz_sub(t, t, r); + + if (!fmpz_is_zero(r)) + { + _padic_exp_bsplit(r, r, w, p, N); + fmpz_mul(rop, rop, r); + fmpz_mod(rop, rop, pN); + } + + w *= 2; + } + + fmpz_clear(r); + fmpz_clear(t); + fmpz_clear(pw); + fmpz_clear(pN); +} + +/* + Assumes that the exponential series converges at $x \neq 0$, + and that $\ord_p(x) < N$. + + Supports aliasing between $x$ and $y$. + + TODO: Take advantage of additional factors of $p$ in $x$. + */ + +void _padic_exp_balanced(fmpz_t rop, const fmpz_t u, slong v, + const fmpz_t p, slong N) +{ + if (fmpz_equal_ui(p, 2)) + _padic_exp_balanced_2(rop, u, v, N); + else + _padic_exp_balanced_p(rop, u, v, p, N); +} + +int padic_exp_balanced(padic_t rop, const padic_t op, const padic_ctx_t ctx) +{ + const slong N = padic_prec(rop); + const slong v = padic_val(op); + const fmpz *p = ctx->p; + + if (padic_is_zero(op)) + { + padic_one(rop); + return 1; + } + + if ((fmpz_equal_ui(p, 2) && v <= 1) || (v <= 0)) + { + return 0; + } + else + { + if (v < N) + { + _padic_exp_balanced(padic_unit(rop), + padic_unit(op), padic_val(op), p, N); + padic_val(rop) = 0; + } + else + { + padic_one(rop); + } + return 1; + } +} diff --git a/external/flint-2.4.3/padic/exp_rectangular.c b/external/flint-2.4.3/padic/exp_rectangular.c new file mode 100644 index 0000000..8385d56 --- /dev/null +++ b/external/flint-2.4.3/padic/exp_rectangular.c @@ -0,0 +1,197 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Fredrik Johansson + +******************************************************************************/ + +#include "padic.h" + +/* + Computes the sum $1 + x + x^2 / 2$ reduced modulo $p^N$, + where $x = p^v u$. + + Supports aliasing between \code{rop} and $u$. + */ + +static void _padic_exp_small(fmpz_t rop, const fmpz_t u, slong v, slong n, + const fmpz_t p, const fmpz_t pN) +{ + if (n == 1) /* rop = 1 */ + { + fmpz_one(rop); + } + else if (n == 2) /* rop = 1 + x */ + { + fmpz_t f; + + fmpz_init(f); + fmpz_pow_ui(f, p, v); + fmpz_mul(rop, f, u); + fmpz_add_ui(rop, rop, 1); + fmpz_mod(rop, rop, pN); + fmpz_clear(f); + } + else /* n == 3, rop = 1 + x + x^2 / 2 */ + { + fmpz_t f; + + fmpz_init(f); + fmpz_pow_ui(f, p, v); + fmpz_mul(rop, f, u); + fmpz_mul(f, rop, rop); + if (fmpz_is_odd(f)) + fmpz_add(f, f, pN); + fmpz_fdiv_q_2exp(f, f, 1); + fmpz_add(rop, rop, f); + fmpz_add_ui(rop, rop, 1); + fmpz_clear(f); + } +} + +void _padic_exp_rectangular(fmpz_t rop, const fmpz_t u, slong v, + const fmpz_t p, slong N) +{ + const slong n = _padic_exp_bound(v, N, p); + + fmpz_t pN; + + fmpz_init(pN); + fmpz_pow_ui(pN, p, N); + + if (n <= 3) + { + _padic_exp_small(rop, u, v, n, p, pN); + } + else + { + const slong k = fmpz_fits_si(p) ? + (n - 1 - 1) / (fmpz_get_si(p) - 1) : 0; + + slong i, npows, nsums; + + fmpz_t c, f, s, t, sum, pNk; + fmpz *pows; + + fmpz_init(pNk); + fmpz_pow_ui(pNk, p, N + k); + + npows = n_sqrt(n); + nsums = (n + npows - 1) / npows; + + fmpz_init(c); + fmpz_init(f); + fmpz_init(s); + fmpz_init(t); + fmpz_init(sum); + + /* Compute pows; pows[i] = x^i. */ + pows = _fmpz_vec_init(npows + 1); + fmpz_one(pows + 0); + fmpz_pow_ui(f, p, v); + fmpz_mul(pows + 1, f, u); + for (i = 2; i <= npows; i++) + { + fmpz_mul(pows + i, pows + i - 1, pows + 1); + fmpz_mod(pows + i, pows + i, pNk); + } + + fmpz_zero(sum); + fmpz_one(f); + + for (i = nsums - 1; i >= 0; i--) + { + slong lo = i * npows; + slong hi = FLINT_MIN(n - 1, lo + npows - 1); + + fmpz_zero(s); + fmpz_one(c); + + for ( ; hi >= lo; hi--) + { + fmpz_addmul(s, pows + hi - lo, c); + if (hi != 0) + fmpz_mul_ui(c, c, hi); + } + + fmpz_mul(t, pows + npows, sum); + fmpz_mul(sum, s, f); + fmpz_add(sum, sum, t); + fmpz_mod(sum, sum, pNk); + + fmpz_mul(f, f, c); + } + + /* Divide by factorial, TODO: Improve */ + + /* Note exp(x) is a unit so val(sum) == val(f) */ + if (fmpz_remove(sum, sum, p)) + fmpz_remove(f, f, p); + + _padic_inv(f, f, p, N); + fmpz_mul(rop, sum, f); + + _fmpz_vec_clear(pows, npows + 1); + fmpz_clear(c); + fmpz_clear(f); + fmpz_clear(s); + fmpz_clear(t); + fmpz_clear(sum); + fmpz_clear(pNk); + } + + fmpz_mod(rop, rop, pN); + fmpz_clear(pN); +} + +int padic_exp_rectangular(padic_t rop, const padic_t op, const padic_ctx_t ctx) +{ + const slong N = padic_prec(rop); + const slong v = padic_val(op); + const fmpz *p = ctx->p; + + if (padic_is_zero(op)) + { + padic_one(rop); + return 1; + } + + if ((fmpz_equal_ui(p, 2) && v <= 1) || (v <= 0)) + { + return 0; + } + else + { + if (v < N) + { + _padic_exp_rectangular(padic_unit(rop), + padic_unit(op), padic_val(op), p, N); + padic_val(rop) = 0; + } + else + { + padic_one(rop); + } + return 1; + } +} + diff --git a/external/flint-2.4.3/padic/fprint.c b/external/flint-2.4.3/padic/fprint.c new file mode 100644 index 0000000..86d55f2 --- /dev/null +++ b/external/flint-2.4.3/padic/fprint.c @@ -0,0 +1,162 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include + +#include "padic.h" + +int _padic_fprint(FILE * file, const fmpz_t u, slong v, const padic_ctx_t ctx) +{ + const fmpz *p = ctx->p; + + if (fmpz_is_zero(u)) + { + fputc('0', file); + return 1; + } + + if (ctx->mode == PADIC_TERSE) + { + if (v == 0) + { + fmpz_fprint(file, u); + } + else if (v > 0) + { + fmpz_t t; + + fmpz_init(t); + fmpz_pow_ui(t, p, v); + fmpz_mul(t, t, u); + fmpz_fprint(file, t); + fmpz_clear(t); + } + else /* v < 0 */ + { + fmpz_t t; + + fmpz_init(t); + fmpz_pow_ui(t, p, -v); + _fmpq_fprint(file, u, t); + fmpz_clear(t); + } + } + else if (ctx->mode == PADIC_SERIES) + { + fmpz_t x; + fmpz_t d; + slong j; + + fmpz_init(d); + fmpz_init(x); + + fmpz_set(x, u); + + /* Unroll first step */ + j = 0; + { + fmpz_mod(d, x, p); /* d = u mod p^{j+1} */ + fmpz_sub(x, x, d); /* x = x - d */ + fmpz_divexact(x, x, p); /* x = x / p */ + + if (!fmpz_is_zero(d)) + { + if (j + v != 0) + { + fmpz_fprint(file, d); + fputc('*', file); + fmpz_fprint(file, p); + flint_fprintf(file, "^%wd", j + v); + } + else + { + fmpz_fprint(file, d); + } + } + + j++; + } + + for ( ; !fmpz_is_zero(x); j++) + { + fmpz_mod(d, x, p); /* d = u mod p^{j+1} */ + fmpz_sub(x, x, d); /* x = x - d */ + fmpz_divexact(x, x, p); /* x = x / p */ + + if (!fmpz_is_zero(d)) + { + if (j + v != 0) + { + flint_fprintf(file, " + "); + fmpz_fprint(file, d); + fputc('*', file); + fmpz_fprint(file, p); + flint_fprintf(file, "^%wd", j + v); + } + else + { + flint_fprintf(file, " + "); + fmpz_fprint(file, d); + } + } + } + + fmpz_clear(x); + fmpz_clear(d); + } + else if (ctx->mode == PADIC_VAL_UNIT) + { + if (v == 0) + { + fmpz_fprint(file, u); + } + else if (v == 1) + { + fmpz_fprint(file, u); + fputc('*', file); + fmpz_fprint(file, p); + } + else + { + fmpz_fprint(file, u); + fputc('*', file); + fmpz_fprint(file, p); + flint_fprintf(file, "^%wd", v); + } + } + else + { + flint_printf("Exception (_padic_fprint). Unknown print mode.\n"); + abort(); + } + + return 1; +} + +int padic_fprint(FILE * file, const padic_t op, const padic_ctx_t ctx) +{ + return _padic_fprint(file, padic_unit(op), padic_val(op), ctx); +} + diff --git a/external/flint-2.4.3/padic/get_fmpq.c b/external/flint-2.4.3/padic/get_fmpq.c new file mode 100644 index 0000000..64d3bb1 --- /dev/null +++ b/external/flint-2.4.3/padic/get_fmpq.c @@ -0,0 +1,61 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "padic.h" + +void padic_get_fmpq(fmpq_t rop, const padic_t op, const padic_ctx_t ctx) +{ + if (padic_is_zero(op)) + { + fmpq_zero(rop); + } + else + { + fmpz_t pow; + int alloc = 0; + + if (padic_val(op) == 0) + { + fmpz_set(fmpq_numref(rop), padic_unit(op)); + fmpz_one(fmpq_denref(rop)); + } + else if (padic_val(op) > 0) + { + alloc = _padic_ctx_pow_ui(pow, padic_val(op), ctx); + fmpz_mul(fmpq_numref(rop), padic_unit(op), pow); + fmpz_one(fmpq_denref(rop)); + } + else /* padic_val(op) < 0 */ + { + alloc = _padic_ctx_pow_ui(pow, - padic_val(op), ctx); + fmpz_set(fmpq_numref(rop), padic_unit(op)); + fmpz_set(fmpq_denref(rop), pow); + } + + if (alloc) + fmpz_clear(pow); + } +} + diff --git a/external/flint-2.4.3/padic/get_fmpz.c b/external/flint-2.4.3/padic/get_fmpz.c new file mode 100644 index 0000000..ba9715e --- /dev/null +++ b/external/flint-2.4.3/padic/get_fmpz.c @@ -0,0 +1,56 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "padic.h" + +void padic_get_fmpz(fmpz_t rop, const padic_t op, const padic_ctx_t ctx) +{ + if (padic_val(op) < 0) + { + flint_printf("Exception (padic_get_fmpz). Negative valuation.\n"); + abort(); + } + + if (padic_is_zero(op)) + { + fmpz_zero(rop); + } + else if (padic_val(op) == 0) + { + fmpz_set(rop, padic_unit(op)); + } + else + { + fmpz_t pow; + int alloc; + + alloc = _padic_ctx_pow_ui(pow, padic_val(op), ctx); + fmpz_mul(rop, padic_unit(op), pow); + + if (alloc) + fmpz_clear(pow); + } +} + diff --git a/external/flint-2.4.3/padic/get_mpq.c b/external/flint-2.4.3/padic/get_mpq.c new file mode 100644 index 0000000..d2ef010 --- /dev/null +++ b/external/flint-2.4.3/padic/get_mpq.c @@ -0,0 +1,37 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "padic.h" + +void padic_get_mpq(mpq_t rop, const padic_t op, const padic_ctx_t ctx) +{ + fmpq_t t; + + fmpq_init(t); + padic_get_fmpq(t, op, ctx); + fmpq_get_mpq(rop, t); + fmpq_clear(t); +} + diff --git a/external/flint-2.4.3/padic/get_mpz.c b/external/flint-2.4.3/padic/get_mpz.c new file mode 100644 index 0000000..b68e8e2 --- /dev/null +++ b/external/flint-2.4.3/padic/get_mpz.c @@ -0,0 +1,37 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "padic.h" + +void padic_get_mpz(mpz_t rop, const padic_t op, const padic_ctx_t ctx) +{ + fmpz_t t; + + fmpz_init(t); + padic_get_fmpz(t, op, ctx); + fmpz_get_mpz(rop, t); + fmpz_clear(t); +} + diff --git a/external/flint-2.4.3/padic/get_str.c b/external/flint-2.4.3/padic/get_str.c new file mode 100644 index 0000000..02a797a --- /dev/null +++ b/external/flint-2.4.3/padic/get_str.c @@ -0,0 +1,214 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include + +#include "padic.h" +#include "long_extras.h" + +char * padic_get_str(char *str, const padic_t op, const padic_ctx_t ctx) +{ + const fmpz *u = padic_unit(op); + const slong v = padic_val(op); + const fmpz *p = ctx->p; + + if (fmpz_is_zero(u)) + { + if (!str) + { + str = flint_malloc(2); + } + str[0] = '0'; + str[1] = '\0'; + return str; + } + + if (ctx->mode == PADIC_TERSE) + { + if (v == 0) + { + str = fmpz_get_str(str, 10, u); + } + else if (v > 0) + { + fmpz_t t; + + fmpz_init(t); + fmpz_pow_ui(t, p, v); + fmpz_mul(t, t, u); + str = fmpz_get_str(str, 10, t); + fmpz_clear(t); + } + else /* v < 0 */ + { + fmpz_t t; + + fmpz_init(t); + fmpz_pow_ui(t, p, -v); + str = _fmpq_get_str(str, 10, u, t); + fmpz_clear(t); + } + } + else if (ctx->mode == PADIC_SERIES) + { + char *s; + fmpz_t x; + fmpz_t d; + slong j, N; + + N = fmpz_clog(u, p) + v; + + if (!str) + { + slong b = (N - v) * (2 * fmpz_sizeinbase(p, 10) + + z_sizeinbase(FLINT_MAX(FLINT_ABS(v), FLINT_ABS(N)), 10) + + 5) + 1; + + str = flint_malloc(b); + if (!str) + { + flint_printf("Exception (padic_get_str). Memory allocation failed.\n"); + abort(); + } + } + + s = str; + + fmpz_init(d); + fmpz_init(x); + + fmpz_set(x, u); + + /* Unroll first step */ + j = 0; + { + fmpz_mod(d, x, p); /* d = u mod p^{j+1} */ + fmpz_sub(x, x, d); /* x = x - d */ + fmpz_divexact(x, x, p); /* x = x / p */ + + if (!fmpz_is_zero(d)) + { + if (j + v != 0) + { + fmpz_get_str(s, 10, d); + while (*++s != '\0') ; + *s++ = '*'; + fmpz_get_str(s, 10, p); + while (*++s != '\0') ; + *s++ = '^'; + flint_sprintf(s, "%wd", j + v); + while (*++s != '\0') ; + } + else + { + fmpz_get_str(s, 10, d); + while (*++s != '\0') ; + } + } + + j++; + } + + for ( ; !fmpz_is_zero(x); j++) + { + fmpz_mod(d, x, p); /* d = u mod p^{j+1} */ + fmpz_sub(x, x, d); /* x = x - d */ + fmpz_divexact(x, x, p); /* x = x / p */ + + if (!fmpz_is_zero(d)) + { + if (j + v != 0) + { + *s++ = ' '; + *s++ = '+'; + *s++ = ' '; + fmpz_get_str(s, 10, d); + while (*++s != '\0') ; + *s++ = '*'; + fmpz_get_str(s, 10, p); + while (*++s != '\0') ; + *s++ = '^'; + flint_sprintf(s, "%wd", j + v); + while (*++s != '\0') ; + } + else + { + *s++ = ' '; + *s++ = '+'; + *s++ = ' '; + fmpz_get_str(s, 10, d); + while (*++s != '\0') ; + } + } + } + + fmpz_clear(x); + fmpz_clear(d); + } + else /* ctx->mode == PADIC_VAL_UNIT */ + { + if (!str) + { + slong b = fmpz_sizeinbase(u, 10) + fmpz_sizeinbase(p, 10) + + z_sizeinbase(v, 10) + 4; + + str = flint_malloc(b); + if (!str) + { + flint_printf("Exception (padic_get_str). Memory allocation failed.\n"); + abort(); + } + } + + if (v == 0) + { + str = fmpz_get_str(str, 10, u); + } + else if (v == 1) + { + char *s = str; + + fmpz_get_str(s, 10, u); + while (*++s != '\0') ; + *s++ = '*'; + fmpz_get_str(s, 10, p); + } + else + { + char *s = str; + + fmpz_get_str(s, 10, u); + while (*++s != '\0') ; + *s++ = '*'; + fmpz_get_str(s, 10, p); + while (*++s != '\0') ; + *s++ = '^'; + flint_sprintf(s, "%wd", v); + } + } + + return str; +} + diff --git a/external/flint-2.4.3/padic/init.c b/external/flint-2.4.3/padic/init.c new file mode 100644 index 0000000..a7d11d1 --- /dev/null +++ b/external/flint-2.4.3/padic/init.c @@ -0,0 +1,41 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "padic.h" + +void padic_init(padic_t rop) +{ + fmpz_init(padic_unit(rop)); + padic_val(rop) = 0; + padic_prec(rop) = PADIC_DEFAULT_PREC; +} + +void padic_init2(padic_t rop, slong N) +{ + fmpz_init(padic_unit(rop)); + padic_val(rop) = 0; + padic_prec(rop) = N; +} + diff --git a/external/flint-2.4.3/padic/inv.c b/external/flint-2.4.3/padic/inv.c new file mode 100644 index 0000000..571ff7a --- /dev/null +++ b/external/flint-2.4.3/padic/inv.c @@ -0,0 +1,125 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Jan Tuitman + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "padic.h" + +#define n (S->n) +#define pow (S->pow) + +void _padic_inv_precompute(padic_inv_t S, const fmpz_t p, slong N) +{ + slong *a; + + a = _padic_lifts_exps(&n, N); + + pow = _fmpz_vec_init(2 * n + 2); + + _padic_lifts_pows(pow, a, n, p); + + flint_free(a); +} + +void _padic_inv_clear(padic_inv_t S) +{ + _fmpz_vec_clear(pow, 2 * n + 2); +} + +void _padic_inv_precomp(fmpz_t rop, const fmpz_t op, const padic_inv_t S) +{ + slong i; + fmpz *t, *u; + + u = pow + n; + t = pow + 2 * n; + + /* Compute reduced units */ + { + fmpz_mod(u + 0, op, pow + 0); + } + for (i = 1; i < n; i++) + { + fmpz_mod(u + i, u + (i - 1), pow + i); + } + + /* Run Newton iteration */ + i = n - 1; + { + fmpz_invmod(rop, u + i, pow + i); + } + for (i--; i >= 0; i--) + { + fmpz_mul(t, rop, rop); + fmpz_mul(t + 1, u + i, t); + fmpz_mul_2exp(rop, rop, 1); + fmpz_sub(rop, rop, t + 1); + fmpz_mod(rop, rop, pow + i); + } +} + +#undef n +#undef pow + +void _padic_inv(fmpz_t rop, const fmpz_t op, const fmpz_t p, slong N) +{ + if (N == 1) + { + fmpz_invmod(rop, op, p); + } + else + { + padic_inv_t S; + + _padic_inv_precompute(S, p, N); + _padic_inv_precomp(rop, op, S); + _padic_inv_clear(S); + } +} + +void padic_inv(padic_t rop, const padic_t op, const padic_ctx_t ctx) +{ + if (padic_is_zero(op)) + { + flint_printf("Exception (padic_inv). Zero is not invertible.\n"); + abort(); + } + + /* + If x = u p^v has negative valuation with N <= -v then the + exact inverse of x is zero when reduced modulo $p^N$ + */ + if (padic_prec(rop) + padic_val(op) <= 0) + { + padic_zero(rop); + } + else + { + _padic_inv(padic_unit(rop), + padic_unit(op), ctx->p, padic_prec(rop) + padic_val(op)); + + padic_val(rop) = - padic_val(op); + } +} + diff --git a/external/flint-2.4.3/padic/lifts.c b/external/flint-2.4.3/padic/lifts.c new file mode 100644 index 0000000..ec37c29 --- /dev/null +++ b/external/flint-2.4.3/padic/lifts.c @@ -0,0 +1,76 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz.h" + +slong * _padic_lifts_exps(slong *n, slong N) +{ + slong *a, i; + + *n = FLINT_CLOG2(N) + 1; + + a = flint_malloc((*n) * sizeof(slong)); + for (a[i = 0] = N; a[i] > 1; i++) + a[i + 1] = (a[i] + 1) / 2; + + return a; +} + +void _padic_lifts_pows(fmpz *pow, const slong *a, slong n, const fmpz_t p) +{ + if (n == 1) + { + fmpz_set(pow + 0, p); + } + else /* n > 1 */ + { + slong i = n - 1; + fmpz_t t = {WORD(1)}; + + fmpz_set(pow + i, p); + + for (i--; i >= 1; i--) + { + if (a[i] & WORD(1)) + { + fmpz_mul(pow + i, t, pow + (i + 1)); + fmpz_mul(t, t, t); + } + else + { + fmpz_mul(t, t, pow + (i + 1)); + fmpz_mul(pow + i, pow + (i + 1), pow + (i + 1)); + } + } + { + if (a[i] & WORD(1)) + fmpz_mul(pow + i, t, pow + (i + 1)); + else + fmpz_mul(pow + i, pow + (i + 1), pow + (i + 1)); + } + fmpz_clear(t); + } +} + diff --git a/external/flint-2.4.3/padic/log.c b/external/flint-2.4.3/padic/log.c new file mode 100644 index 0000000..57c6ff5 --- /dev/null +++ b/external/flint-2.4.3/padic/log.c @@ -0,0 +1,162 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "padic.h" +#include "ulong_extras.h" + +/* + Assumes that $1 \leq v$ or $2 \leq v$ as $p$ is even + or odd, respectively, and that $v < N < 2^{f-2}$ where + $f$ is \code{FLINT_BITS}. + + Under the assumption that $1 \leq v < N$, or $2 \leq v < N$, + one can easily prove that with $c = N - \floor{\log_p v}$ + the number $b = \ceil{(c + \ceil{\log_p c} + 1) / b}$ is such + that for all $i \geq b$, $i v - \ord_p(i) \geq N$. + + Under the additional condition that $N < 2^{f-2}$ one can + show that the code branch for primes that fit into a + \code{slong} does not cause overflow. Moreover, + independently of this, it follows that the above value $b$ + is less than $2^{f-1}$. + + In the first branch, we have that $b v - log_p(b) \geq N$. + We need to show that we can replace $\log_p$ by $\ord_p$ here. + That is, we need that $iv - \ord_p(i) \geq iv - \log_p(i) \geq N$, + i.e., $\log_p(i) \geq \ord_p(i)$, which is true. We then work + backwards to find the first $i$ such that this fails, then + using that the function is strictly increasing for $i \geq 2$. + + In the second branch we use that using signed indices in the + summation is still sufficient and hence that all terms $1/i$ + are units. + Then $ord_p(x^i/i) \geq N$ provided that $i v \geq N$. + */ + +slong _padic_log_bound(slong v, slong N, const fmpz_t prime) +{ + if (N >= (WORD(1) << (FLINT_BITS - 2))) + { + flint_printf("Exception (_padic_log_bound). N = %wd is too large.\n", N); + abort(); + } + + if (fmpz_fits_si(prime)) + { + slong b, c, p = fmpz_get_si(prime); + + c = N - n_flog(v, p); + b = ((c + n_clog(c, p) + 1) + (v - 1)) / v; + + while (--b >= 2) + { + slong t = b * v - n_clog(b, p); + + if (t < N) + return b + 1; + } + + return 2; + } + else + { + return (N + v - 1) / v; + } +} + +void _padic_log(fmpz_t z, const fmpz_t y, slong v, const fmpz_t p, slong N) +{ + if (N < (WORD(1) << 9) / (slong) fmpz_bits(p)) + { + _padic_log_rectangular(z, y, v, p, N); + } + else + { + _padic_log_balanced(z, y, v, p, N); + } +} + +int padic_log(padic_t rop, const padic_t op, const padic_ctx_t ctx) +{ + const fmpz *p = ctx->p; + const slong N = padic_prec(rop); + + if (padic_val(op) < 0) + { + return 0; + } + else + { + fmpz_t x; + int ans; + + fmpz_init(x); + + padic_get_fmpz(x, op, ctx); + fmpz_sub_ui(x, x, 1); + fmpz_neg(x, x); + + if (fmpz_is_zero(x)) + { + padic_zero(rop); + ans = 1; + } + else + { + fmpz_t t; + slong v; + + fmpz_init(t); + v = fmpz_remove(t, x, p); + fmpz_clear(t); + + if (v >= 2 || (!fmpz_equal_ui(p, 2) && v >= 1)) + { + if (v >= N) + { + padic_zero(rop); + } + else + { + _padic_log(padic_unit(rop), x, v, p, N); + padic_val(rop) = 0; + _padic_canonicalise(rop, ctx); + } + ans = 1; + } + else + { + ans = 0; + } + } + + fmpz_clear(x); + return ans; + } +} + diff --git a/external/flint-2.4.3/padic/log_balanced.c b/external/flint-2.4.3/padic/log_balanced.c new file mode 100644 index 0000000..58b1dcb --- /dev/null +++ b/external/flint-2.4.3/padic/log_balanced.c @@ -0,0 +1,224 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + Copyright (C) 2012 Fredrik Johansson + +******************************************************************************/ + +#include "padic.h" +#include "ulong_extras.h" + +static void +_padic_log_bsplit_series(fmpz_t P, fmpz_t B, fmpz_t T, + const fmpz_t x, slong a, slong b) +{ + if (b - a == 1) + { + fmpz_set(P, x); + fmpz_set_si(B, a); + fmpz_set(T, x); + } + else if (b - a == 2) + { + fmpz_mul(P, x, x); + fmpz_set_si(B, a); + fmpz_mul_si(B, B, a + 1); + fmpz_mul_si(T, x, a + 1); + fmpz_addmul_ui(T, P, a); + } + else + { + const slong m = (a + b) / 2; + + fmpz_t RP, RB, RT; + + _padic_log_bsplit_series(P, B, T, x, a, m); + + fmpz_init(RP); + fmpz_init(RB); + fmpz_init(RT); + + _padic_log_bsplit_series(RP, RB, RT, x, m, b); + + fmpz_mul(RT, RT, P); + fmpz_mul(T, T, RB); + fmpz_addmul(T, RT, B); + fmpz_mul(P, P, RP); + fmpz_mul(B, B, RB); + + fmpz_clear(RP); + fmpz_clear(RB); + fmpz_clear(RT); + } +} + +/* + Assumes that $y = 1 - x$ is such that $\log(x)$ + converges. + + Assumes that $v = \ord_p(y)$ with $v < N$, which + also forces $N$ to be positive. + + The result $z$ might not be reduced modulo $p^N$. + + Supports aliasing between $y$ and $z$. + */ + +static void +_padic_log_bsplit(fmpz_t z, const fmpz_t y, slong v, const fmpz_t p, slong N) +{ + fmpz_t P, B, T; + slong k, n; + + n = _padic_log_bound(v, N, p); + n = FLINT_MAX(n, 2); + + fmpz_init(P); + fmpz_init(B); + fmpz_init(T); + + _padic_log_bsplit_series(P, B, T, y, 1, n); + + k = fmpz_remove(B, B, p); + fmpz_pow_ui(P, p, k); + fmpz_divexact(T, T, P); + + _padic_inv(B, B, p, N); + fmpz_mul(z, T, B); + + fmpz_clear(P); + fmpz_clear(B); + fmpz_clear(T); +} + +void +_padic_log_balanced(fmpz_t z, const fmpz_t y, slong v, const fmpz_t p, slong N) +{ + fmpz_t pv, pN, r, t, u; + slong w; + padic_inv_t S; + + fmpz_init(pv); + fmpz_init(pN); + fmpz_init(r); + fmpz_init(t); + fmpz_init(u); + _padic_inv_precompute(S, p, N); + + fmpz_set(pv, p); + fmpz_pow_ui(pN, p, N); + fmpz_mod(t, y, pN); + fmpz_zero(z); + w = 1; + + while (!fmpz_is_zero(t)) + { + fmpz_mul(pv, pv, pv); + fmpz_fdiv_qr(t, r, t, pv); + + if (!fmpz_is_zero(t)) + { + fmpz_mul(t, t, pv); + fmpz_sub_ui(u, r, 1); + fmpz_neg(u, u); + _padic_inv_precomp(u, u, S); + fmpz_mul(t, t, u); + fmpz_mod(t, t, pN); + } + + if (!fmpz_is_zero(r)) + { + _padic_log_bsplit(r, r, w, p, N); + fmpz_sub(z, z, r); + } + w *= 2; + } + + fmpz_mod(z, z, pN); + + fmpz_clear(pv); + fmpz_clear(pN); + fmpz_clear(r); + fmpz_clear(t); + fmpz_clear(u); + _padic_inv_clear(S); +} + +int padic_log_balanced(padic_t rop, const padic_t op, const padic_ctx_t ctx) +{ + const fmpz *p = ctx->p; + const slong N = padic_prec(rop); + + if (padic_val(op) < 0) + { + return 0; + } + else + { + fmpz_t x; + int ans; + + fmpz_init(x); + + padic_get_fmpz(x, op, ctx); + fmpz_sub_ui(x, x, 1); + fmpz_neg(x, x); + + if (fmpz_is_zero(x)) + { + padic_zero(rop); + ans = 1; + } + else + { + fmpz_t t; + slong v; + + fmpz_init(t); + v = fmpz_remove(t, x, p); + fmpz_clear(t); + + if (v >= 2 || (!fmpz_equal_ui(p, 2) && v >= 1)) + { + if (v >= N) + { + padic_zero(rop); + } + else + { + _padic_log_balanced(padic_unit(rop), x, v, p, N); + padic_val(rop) = 0; + _padic_canonicalise(rop, ctx); + } + ans = 1; + } + else + { + ans = 0; + } + } + + fmpz_clear(x); + return ans; + } +} + diff --git a/external/flint-2.4.3/padic/log_rectangular.c b/external/flint-2.4.3/padic/log_rectangular.c new file mode 100644 index 0000000..7632f97 --- /dev/null +++ b/external/flint-2.4.3/padic/log_rectangular.c @@ -0,0 +1,214 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "padic.h" +#include "ulong_extras.h" + +/* + Carries out the finite series evaluation for the logarithm + \begin{equation*} + \sum_{i=1}^{n} a_i x^i + = \sum_{j=0}^{\ceil{n/b} - 1} \Bigl( \sum_{i=1}^b a_{i+jb} x^i \Bigr) x^{jb} + \end{equation*} + where $a_i = 1/i$ with the choice $b = \floor{\sqrt{n}}$, + all modulo $p^N$, where also $P = p^N$. + + Does not support aliasing. + */ +static void +_padic_log_rectangular_series(fmpz_t z, const fmpz_t y, slong n, + const fmpz_t p, slong N, const fmpz_t P0) +{ + if (n <= 2) + { + if (n == 1) + { + fmpz_mod(z, y, P0); + } + else /* n == 2; z = y(1 + y/2) */ + { + if (fmpz_is_even(y)) + { + fmpz_fdiv_q_2exp(z, y, 1); + } + else /* => p and y are odd */ + { + fmpz_add(z, y, P0); + fmpz_fdiv_q_2exp(z, z, 1); + } + fmpz_add_ui(z, z, 1); + fmpz_mul(z, z, y); + fmpz_mod(z, z, P0); + } + } + else + { + const slong b = n_sqrt(n); + const slong k = fmpz_fits_si(p) ? n_flog(n, fmpz_get_si(p)) : 0; + + slong i, j; + fmpz_t c, f, t, P1; + fmpz *ypow; + + ypow = _fmpz_vec_init(b + 1); + fmpz_init(c); + fmpz_init(f); + fmpz_init(t); + fmpz_init(P1); + + fmpz_pow_ui(P1, p, N + k); + + fmpz_one(ypow + 0); + for (i = 1; i <= b; i++) + { + fmpz_mul(ypow + i, ypow + (i - 1), y); + fmpz_mod(ypow + i, ypow + i, P1); + } + + fmpz_zero(z); + + for (j = (n + (b - 1)) / b - 1; j >= 0; j--) + { + const slong hi = FLINT_MIN(b, n - j*b); + slong w; + + /* Compute inner sum in c */ + fmpz_rfac_uiui(f, 1 + j*b, hi); + + fmpz_zero(c); + for (i = 1; i <= hi; i++) + { + fmpz_divexact_ui(t, f, i + j*b); + fmpz_addmul(c, t, ypow + i); + } + + /* Multiply c by p^k f^{-1} */ + w = fmpz_remove(f, f, p); + _padic_inv(f, f, p, N); + if (w > k) + { + fmpz_pow_ui(t, p, w - k); + fmpz_divexact(c, c, t); + } + else + { + fmpz_pow_ui(t, p, k - w); + fmpz_mul(c, c, t); + } + fmpz_mul(c, c, f); + + /* Set z = z y^b + c */ + fmpz_mul(t, z, ypow + b); + fmpz_add(z, c, t); + fmpz_mod(z, z, P1); + } + + fmpz_pow_ui(f, p, k); + fmpz_divexact(z, z, f); + + fmpz_clear(c); + fmpz_clear(f); + fmpz_clear(t); + fmpz_clear(P1); + _fmpz_vec_clear(ypow, b + 1); + } +} + +void _padic_log_rectangular(fmpz_t z, const fmpz_t y, slong v, const fmpz_t p, slong N) +{ + const slong n = _padic_log_bound(v, N, p) - 1; + fmpz_t pN; + + fmpz_init(pN); + fmpz_pow_ui(pN, p, N); + + _padic_log_rectangular_series(z, y, n, p, N, pN); + + fmpz_sub(z, pN, z); + fmpz_clear(pN); +} + +int padic_log_rectangular(padic_t rop, const padic_t op, const padic_ctx_t ctx) +{ + const fmpz *p = ctx->p; + const slong N = padic_prec(rop); + + if (padic_val(op) < 0) + { + return 0; + } + else + { + fmpz_t x; + int ans; + + fmpz_init(x); + + padic_get_fmpz(x, op, ctx); + fmpz_sub_ui(x, x, 1); + fmpz_neg(x, x); + + if (fmpz_is_zero(x)) + { + padic_zero(rop); + ans = 1; + } + else + { + fmpz_t t; + slong v; + + fmpz_init(t); + v = fmpz_remove(t, x, p); + fmpz_clear(t); + + if (v >= 2 || (!fmpz_equal_ui(p, 2) && v >= 1)) + { + if (v >= N) + { + padic_zero(rop); + } + else + { + _padic_log_rectangular(padic_unit(rop), x, v, p, N); + padic_val(rop) = 0; + _padic_canonicalise(rop, ctx); + } + ans = 1; + } + else + { + ans = 0; + } + } + + fmpz_clear(x); + return ans; + } +} + diff --git a/external/flint-2.4.3/padic/log_satoh.c b/external/flint-2.4.3/padic/log_satoh.c new file mode 100644 index 0000000..0d23fc6 --- /dev/null +++ b/external/flint-2.4.3/padic/log_satoh.c @@ -0,0 +1,125 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "fmpz.h" +#include "padic.h" +#include "ulong_extras.h" + +void _padic_log_satoh(fmpz_t z, const fmpz_t y, slong v, const fmpz_t p, slong N) +{ + if (N < 16) + { + _padic_log_rectangular(z, y, v, p, N); + } + else + { + const slong k = n_sqrt(N); + + fmpz_t t, pk, pNk; + + fmpz_init(t); + fmpz_init(pk); + fmpz_init(pNk); + fmpz_pow_ui(pk, p, k); + fmpz_pow_ui(pNk, p, N + k); + + fmpz_sub_ui(t, y, 1); + fmpz_neg(t, t); + fmpz_powm(t, t, pk, pNk); + fmpz_sub_ui(t, t, 1); + fmpz_neg(t, t); + + /* TODO: Improve suggested valuation */ + _padic_log_rectangular(z, t, k + 1, p, N + k); + + fmpz_divexact(z, z, pk); + + fmpz_clear(t); + fmpz_clear(pk); + fmpz_clear(pNk); + } +} + +int padic_log_satoh(padic_t rop, const padic_t op, const padic_ctx_t ctx) +{ + const fmpz *p = ctx->p; + const slong N = padic_prec(rop); + + if (padic_val(op) < 0) + { + return 0; + } + else + { + fmpz_t y; + int ans; + + fmpz_init(y); + + padic_get_fmpz(y, op, ctx); + fmpz_sub_ui(y, y, 1); + fmpz_neg(y, y); + + if (fmpz_is_zero(y)) + { + padic_zero(rop); + ans = 1; + } + else + { + fmpz_t t; + slong v; + + fmpz_init(t); + v = fmpz_remove(t, y, ctx->p); + fmpz_clear(t); + + if (v >= 2 || (!fmpz_equal_ui(p, 2) && v >= 1)) + { + if (v >= N) + { + padic_zero(rop); + } + else + { + _padic_log_satoh(padic_unit(rop), y, v, p, N); + padic_val(rop) = 0; + padic_reduce(rop, ctx); + } + ans = 1; + } + else + { + ans = 0; + } + } + + fmpz_clear(y); + return ans; + } +} + diff --git a/external/flint-2.4.3/padic/mul.c b/external/flint-2.4.3/padic/mul.c new file mode 100644 index 0000000..2884917 --- /dev/null +++ b/external/flint-2.4.3/padic/mul.c @@ -0,0 +1,44 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "padic.h" + +void padic_mul(padic_t rop, const padic_t op1, const padic_t op2, + const padic_ctx_t ctx) +{ + if (padic_is_zero(op1) || padic_is_zero(op2) || + padic_val(op1) + padic_val(op2) >= padic_prec(rop)) + { + padic_zero(rop); + } + else + { + fmpz_mul(padic_unit(rop), padic_unit(op1), padic_unit(op2)); + padic_val(rop) = padic_val(op1) + padic_val(op2); + + _padic_reduce(rop, ctx); + } +} + diff --git a/external/flint-2.4.3/padic/neg.c b/external/flint-2.4.3/padic/neg.c new file mode 100644 index 0000000..8ca2348 --- /dev/null +++ b/external/flint-2.4.3/padic/neg.c @@ -0,0 +1,52 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "padic.h" + +void padic_neg(padic_t rop, const padic_t op, const padic_ctx_t ctx) +{ + if (padic_is_zero(op) || padic_val(op) >= padic_prec(rop)) + { + padic_zero(rop); + } + else + { + fmpz_t pow; + int alloc; + + padic_val(rop) = padic_val(op); + + alloc = _padic_ctx_pow_ui(pow, padic_prec(rop) - padic_val(rop), ctx); + fmpz_sub(padic_unit(rop), pow, padic_unit(op)); + if (alloc) + fmpz_clear(pow); + + if (padic_prec(rop) < padic_prec(op)) + { + _padic_reduce(rop, ctx); + } + } +} + diff --git a/external/flint-2.4.3/padic/pow_si.c b/external/flint-2.4.3/padic/pow_si.c new file mode 100644 index 0000000..abe8919 --- /dev/null +++ b/external/flint-2.4.3/padic/pow_si.c @@ -0,0 +1,62 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "padic.h" + +void padic_pow_si(padic_t rop, const padic_t op, slong e, const padic_ctx_t ctx) +{ + if (e == 0) + { + padic_one(rop); + } + else if (padic_is_zero(op) || e * padic_val(op) >= padic_prec(rop)) + { + padic_zero(rop); + } + else + { + fmpz_t pow; + int alloc; + + padic_val(rop) = e * padic_val(op); + + alloc = _padic_ctx_pow_ui(pow, padic_prec(rop) - padic_val(rop), ctx); + if (e > 0) + { + fmpz_powm_ui(padic_unit(rop), padic_unit(op), e, pow); + } + else /* e < 0 */ + { + /* u^{-1} to precision ceil((N - v e) / -e) */ + _padic_inv(padic_unit(rop), padic_unit(op), + ctx->p, (padic_prec(rop) - padic_val(rop) + (-e - 1)) / -e); + + fmpz_powm_ui(padic_unit(rop), padic_unit(rop), -e, pow); + } + if (alloc) + fmpz_clear(pow); + } +} + diff --git a/external/flint-2.4.3/padic/profile/p-exp_balanced_2.c b/external/flint-2.4.3/padic/profile/p-exp_balanced_2.c new file mode 100644 index 0000000..7b1c0e2 --- /dev/null +++ b/external/flint-2.4.3/padic/profile/p-exp_balanced_2.c @@ -0,0 +1,126 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +/* + Benchmarks for the p-adic exponential method, balanced. + + We consider the set-up with p = 2, N = 2^i, i = 0, ..., 19, + and compute the exponential of d = 4 a, a = 3^{3 N} mod p^N. + */ + +#include +#include +#include +#include +#include +#include + +#include "flint.h" +#include "fmpz.h" +#include "padic.h" + +int +main(void) +{ + long l, len = 20; + long runs[] = { + 100000000, 100000000, 1000000, 100000, 100000, + 100000, 10000, 10000, 10000, 10000, + 1000, 1000, 100, 100, 10, + 10, 1, 1, 1, 1 + }; + long N[] = { + 1, 2, 4, 8, 16, + 32, 64, 128, 256, 512, + 1024, WORD(1) << 11, WORD(1) << 12, WORD(1) << 13, WORD(1) << 14, + WORD(1) << 15, WORD(1) << 16, WORD(1) << 17, WORD(1) << 18, WORD(1) << 19 + }; + long T[20] = {0}; + + flint_printf("Benchmark for p-adic exponential (balanced).\n"); + fflush(stdout); + +for (l = 0; l < len; l++) +{ + FLINT_TEST_INIT(state); + long n = N[l], r; + clock_t c0, c1; + long double cputime; + + fmpz_t p; + padic_ctx_t ctx; + padic_t d, z; + + + + fmpz_init_set_ui(p, 2); + + padic_ctx_init(ctx, p, n, n, PADIC_VAL_UNIT); + + padic_init(d); + padic_init(z); + + if (n > 1) + { + fmpz_t f = {WORD(3)}, pow; + + fmpz_init(pow); + fmpz_pow_ui(pow, p, n - 2); + fmpz_pow_ui(padic_unit(d), f, 3 * n); + fmpz_mod(padic_unit(d), padic_unit(d), pow); + padic_val(d) = 2; + + fmpz_clear(pow); + } + + c0 = clock(); + for (r = runs[l]; (r); r--) + { + padic_exp_balanced(z, d, ctx); + padic_zero(z); + } + c1 = clock(); + + cputime = (long double) (c1 - c0) / (long double) CLOCKS_PER_SEC; + + T[l] = (slong) (cputime * (1000000000 / runs[l])); + + flint_printf("%2ld, %4XYXYXYXY, %9ld, %wd\n", + l, cputime, runs[l], T[l]); + + padic_clear(d); + padic_clear(z); + + fmpz_clear(p); + padic_ctx_clear(ctx); + flint_randclear(state); +} + + flint_printf("Output as a list:\n"); + for (l = 0; l < len; l++) + flint_printf("%wd, ", T[l]); + flint_printf("\n"); +} + diff --git a/external/flint-2.4.3/padic/profile/p-exp_balanced_p.c b/external/flint-2.4.3/padic/profile/p-exp_balanced_p.c new file mode 100644 index 0000000..4009c1c --- /dev/null +++ b/external/flint-2.4.3/padic/profile/p-exp_balanced_p.c @@ -0,0 +1,126 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +/* + Benchmarks for the p-adic exponential method, balanced. + + We consider the set-up with p = 17, N = 2^i, i = 0, ..., 19, + and compute the exponential of d = 17 a, a = 3^{3 N} mod p^N. + */ + +#include +#include +#include +#include +#include +#include + +#include "flint.h" +#include "fmpz.h" +#include "padic.h" + +int +main(void) +{ + long l, len = 20; + long runs[] = { + 100000000, 1000000, 100000, 100000, 100000, + 10000, 10000, 10000, 10000, 1000, + 1000, 100, 100, 10, 10, + 1, 1, 1, 1, 1 + }; + long N[] = { + 1, 2, 4, 8, 16, + 32, 64, 128, 256, 512, + 1024, WORD(1) << 11, WORD(1) << 12, WORD(1) << 13, WORD(1) << 14, + WORD(1) << 15, WORD(1) << 16, WORD(1) << 17, WORD(1) << 18, WORD(1) << 19 + }; + long T[20] = {0}; + + flint_printf("Benchmark for p-adic exponential (balanced).\n"); + fflush(stdout); + +for (l = 0; l < len; l++) +{ + FLINT_TEST_INIT(state); + long n = N[l], r; + clock_t c0, c1; + long double cputime; + + fmpz_t p; + padic_ctx_t ctx; + padic_t d, z; + + + + fmpz_init_set_ui(p, 17); + + padic_ctx_init(ctx, p, n, n, PADIC_VAL_UNIT); + + padic_init(d); + padic_init(z); + + if (n > 1) + { + fmpz_t f = {WORD(3)}, pow; + + fmpz_init(pow); + fmpz_pow_ui(pow, p, n - 1); + fmpz_pow_ui(padic_unit(d), f, 3 * n); + fmpz_mod(padic_unit(d), padic_unit(d), pow); + padic_val(d) = 1; + + fmpz_clear(pow); + } + + c0 = clock(); + for (r = runs[l]; (r); r--) + { + padic_exp_balanced(z, d, ctx); + padic_zero(z); + } + c1 = clock(); + + cputime = (long double) (c1 - c0) / (long double) CLOCKS_PER_SEC; + + T[l] = (slong) (cputime * (1000000000 / runs[l])); + + flint_printf("%2ld, %4XYXYXYXY, %9ld, %wd\n", + l, cputime, runs[l], T[l]); + + padic_clear(d); + padic_clear(z); + + fmpz_clear(p); + padic_ctx_clear(ctx); + flint_randclear(state); +} + + flint_printf("Output as a list:\n"); + for (l = 0; l < len; l++) + flint_printf("%wd, ", T[l]); + flint_printf("\n"); +} + diff --git a/external/flint-2.4.3/padic/profile/p-exp_rectangular.c b/external/flint-2.4.3/padic/profile/p-exp_rectangular.c new file mode 100644 index 0000000..0205b43 --- /dev/null +++ b/external/flint-2.4.3/padic/profile/p-exp_rectangular.c @@ -0,0 +1,126 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +/* + Benchmarks for the p-adic exponential method, rectangular. + + We consider the set-up with p = 17, N = 2^i, i = 0, ..., 19, + and compute the exponential of d = 17 a, a = 3^{3 N} mod p^N. + */ + +#include +#include +#include +#include +#include +#include + +#include "flint.h" +#include "fmpz.h" +#include "padic.h" + +int +main(void) +{ + long l, len = 20; + long runs[] = { + 100000000, 1000000, 1000000, 1000000, 100000, + 100000, 10000, 10000, 10000, 1000, + 100, 100, 10, 1, 1, + 1, 1, 1, 1, 1 + }; + long N[] = { + 1, 2, 4, 8, 16, + 32, 64, 128, 256, 512, + 1024, WORD(1) << 11, WORD(1) << 12, WORD(1) << 13, WORD(1) << 14, + WORD(1) << 15, WORD(1) << 16, WORD(1) << 17, WORD(1) << 18, WORD(1) << 19 + }; + long T[20] = {0}; + + flint_printf("Benchmark for p-adic exponential (rectangular).\n"); + fflush(stdout); + +for (l = 0; l < FLINT_MIN(17, len); l++) +{ + FLINT_TEST_INIT(state); + long n = N[l], r; + clock_t c0, c1; + long double cputime; + + fmpz_t p; + padic_ctx_t ctx; + padic_t d, z; + + + + fmpz_init_set_ui(p, 17); + + padic_ctx_init(ctx, p, n, n, PADIC_VAL_UNIT); + + padic_init(d); + padic_init(z); + + if (n > 1) + { + fmpz_t f = {WORD(3)}, pow; + + fmpz_init(pow); + fmpz_pow_ui(pow, p, n - 1); + fmpz_pow_ui(padic_unit(d), f, 3 * n); + fmpz_mod(padic_unit(d), padic_unit(d), pow); + padic_val(d) = 1; + + fmpz_clear(pow); + } + + c0 = clock(); + for (r = runs[l]; (r); r--) + { + padic_exp_rectangular(z, d, ctx); + padic_zero(z); + } + c1 = clock(); + + cputime = (long double) (c1 - c0) / (long double) CLOCKS_PER_SEC; + + T[l] = (slong) (cputime * (1000000000 / runs[l])); + + flint_printf("%2ld, %4XYXYXYXY, %9ld, %wd\n", + l, cputime, runs[l], T[l]); + + padic_clear(d); + padic_clear(z); + + fmpz_clear(p); + padic_ctx_clear(ctx); + flint_randclear(state); +} + + flint_printf("Output as a list:\n"); + for (l = 0; l < len; l++) + flint_printf("%wd, ", T[l]); + flint_printf("\n"); +} + diff --git a/external/flint-2.4.3/padic/profile/p-inv.c b/external/flint-2.4.3/padic/profile/p-inv.c new file mode 100644 index 0000000..aab1101 --- /dev/null +++ b/external/flint-2.4.3/padic/profile/p-inv.c @@ -0,0 +1,123 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +/* + Benchmarks for the p-adic inversion routine. + + We consider the set-up with p = 17, N = 2^i, i = 0, ..., 19, + and invert a = 3^{3 N} mod p^N. + */ + +#include +#include +#include +#include +#include +#include + +#include "flint.h" +#include "fmpz.h" +#include "padic.h" + +int +main(void) +{ + slong l, len = 20; + slong runs[] = { + 10000000, 1000000, 1000000, 1000000, 1000000, + 100000, 100000, 100000, 100000, 10000, + 10000, 1000, 1000, 1000, 10, + 10, 10, 10, 10, 1 + }; + slong N[] = { + 1, 2, 4, 8, 16, + 32, 64, 128, 256, 512, + 1024, WORD(1) << 11, WORD(1) << 12, WORD(1) << 13, WORD(1) << 14, + WORD(1) << 15, WORD(1) << 16, WORD(1) << 17, WORD(1) << 18, WORD(1) << 19 + }; + slong T[20] = {0}; + + flint_printf("Benchmark for p-adic inversion.\n"); + fflush(stdout); + +for (l = 0; l < len; l++) +{ + FLINT_TEST_INIT(state); + slong n = N[l], r; + clock_t c0, c1; + long double cputime; + + fmpz_t p; + padic_ctx_t ctx; + padic_t a, z; + + + + fmpz_init_set_ui(p, 17); + + padic_ctx_init(ctx, p, n, n, PADIC_VAL_UNIT); + + padic_init(a); + padic_init(z); + + { + fmpz_t f = {WORD(3)}, pow; + + fmpz_init(pow); + fmpz_pow_ui(pow, p, n); + fmpz_pow_ui(padic_unit(a), f, 3 * n); + fmpz_mod(padic_unit(a), padic_unit(a), pow); + fmpz_clear(pow); + } + + c0 = clock(); + for (r = runs[l]; (r); r--) + { + padic_inv(z, a, ctx); + padic_zero(z); + } + c1 = clock(); + + cputime = (long double) (c1 - c0) / (long double) CLOCKS_PER_SEC; + + T[l] = (slong) (cputime * (1000000000 / runs[l])); + + flint_printf("%2ld, %4XYXYXYXY, %8ld, %wd\n", + l, cputime, runs[l], T[l]); + + padic_clear(a); + padic_clear(z); + + fmpz_clear(p); + padic_ctx_clear(ctx); + flint_randclear(state); +} + + flint_printf("Output as a list:\n"); + for (l = 0; l < len; l++) + flint_printf("%wd, ", T[l]); + flint_printf("\n"); +} + diff --git a/external/flint-2.4.3/padic/profile/p-log_balanced.c b/external/flint-2.4.3/padic/profile/p-log_balanced.c new file mode 100644 index 0000000..9d48bd0 --- /dev/null +++ b/external/flint-2.4.3/padic/profile/p-log_balanced.c @@ -0,0 +1,137 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +/* + Benchmarks for the p-adic exponential method, balanced. + + We consider the set-up with p = 17, N = 2^i, i = 0, ..., 19, + and compute the logarithm of e = 17 a + 1, a = 3^{3 N} mod p^N. + */ + +#include +#include +#include +#include +#include +#include + +#include "flint.h" +#include "fmpz.h" +#include "padic.h" + +int +main(void) +{ + long l, len = 20; + long runs[] = { + 10000000, 1000000, 100000, 100000, 100000, + 10000, 10000, 10000, 1000, 1000, + 1000, 100, 100, 10, 10, + 1, 1, 1, 1, 1 + }; + long N[] = { + 1, 2, 4, 8, 16, + 32, 64, 128, 256, 512, + 1024, WORD(1) << 11, WORD(1) << 12, WORD(1) << 13, WORD(1) << 14, + WORD(1) << 15, WORD(1) << 16, WORD(1) << 17, WORD(1) << 18, WORD(1) << 19 + }; + long T[20] = {0}; + + flint_printf("Benchmark for p-adic logarithm (balanced).\n"); + fflush(stdout); + +for (l = 0; l < len; l++) +{ + FLINT_TEST_INIT(state); + long n = N[l], r; + clock_t c0, c1; + long double cputime; + + fmpz_t p; + padic_ctx_t ctx; + padic_t e, z; + + + + fmpz_init_set_ui(p, 17); + + padic_ctx_init(ctx, p, n, n, PADIC_VAL_UNIT); + + padic_init(e); + padic_init(z); + + { + fmpz_t f = {WORD(3)}, pow; + + fmpz_init(pow); + fmpz_pow_ui(pow, p, n); + fmpz_pow_ui(padic_unit(e), f, 3 * n); + fmpz_mul_ui(padic_unit(e), padic_unit(e), 17); + fmpz_add_ui(padic_unit(e), padic_unit(e), 1); + fmpz_mod(padic_unit(e), padic_unit(e), pow); + fmpz_clear(pow); + } + + c0 = clock(); + for (r = runs[l]; (r); r--) + { + padic_log_balanced(z, e, ctx); + padic_zero(z); + } + c1 = clock(); + + padic_log_balanced(z, e, ctx); + padic_exp_balanced(z, z, ctx); + if (!padic_equal(e, z)) + { + flint_printf("FAIL:\n"); + flint_printf("e = "), padic_print(e, ctx), flint_printf("\n"); + flint_printf("z = "), padic_print(z, ctx), flint_printf("\n"); + flint_printf("p = %wd\n", *p), flint_printf("\n"); + flint_printf("N = %wd\n", n), flint_printf("\n"); + abort(); + } + + cputime = (long double) (c1 - c0) / (long double) CLOCKS_PER_SEC; + + T[l] = (slong) (cputime * (1000000000 / runs[l])); + + flint_printf("%2ld, %4XYXYXYXY, %8ld, %wd\n", + l, cputime, runs[l], T[l]); + + padic_clear(e); + padic_clear(z); + + fmpz_clear(p); + padic_ctx_clear(ctx); + flint_randclear(state); +} + + flint_printf("Output as a list:\n"); + for (l = 0; l < len; l++) + flint_printf("%wd, ", T[l]); + flint_printf("\n"); +} + diff --git a/external/flint-2.4.3/padic/profile/p-log_rectangular.c b/external/flint-2.4.3/padic/profile/p-log_rectangular.c new file mode 100644 index 0000000..4d66121 --- /dev/null +++ b/external/flint-2.4.3/padic/profile/p-log_rectangular.c @@ -0,0 +1,137 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +/* + Benchmarks for the p-adic exponential method, rectangular. + + We consider the set-up with p = 17, N = 2^i, i = 0, ..., 19, + and compute the logarithm of e = 17 a + 1, a = 3^{3 N} mod p^N. + */ + +#include +#include +#include +#include +#include +#include + +#include "flint.h" +#include "fmpz.h" +#include "padic.h" + +int +main(void) +{ + long l, len = 20; + long runs[] = { + 10000000, 1000000, 1000000, 100000, 100000, + 10000, 10000, 10000, 1000, 1000, + 100, 100, 10, 1, 1, + 1, 1, 1, 1, 1 + }; + long N[] = { + 1, 2, 4, 8, 16, + 32, 64, 128, 256, 512, + 1024, WORD(1) << 11, WORD(1) << 12, WORD(1) << 13, WORD(1) << 14, + WORD(1) << 15, WORD(1) << 16, WORD(1) << 17, WORD(1) << 18, WORD(1) << 19 + }; + long T[20] = {0}; + + flint_printf("Benchmark for p-adic logarithm (rectangular).\n"); + fflush(stdout); + +for (l = 0; l < FLINT_MIN(16, len); l++) +{ + FLINT_TEST_INIT(state); + long n = N[l], r; + clock_t c0, c1; + long double cputime; + + fmpz_t p; + padic_ctx_t ctx; + padic_t e, z; + + + + fmpz_init_set_ui(p, 17); + + padic_ctx_init(ctx, p, n, n, PADIC_VAL_UNIT); + + padic_init(e); + padic_init(z); + + { + fmpz_t f = {WORD(3)}, pow; + + fmpz_init(pow); + fmpz_pow_ui(pow, p, n); + fmpz_pow_ui(padic_unit(e), f, 3 * n); + fmpz_mul_ui(padic_unit(e), padic_unit(e), 17); + fmpz_add_ui(padic_unit(e), padic_unit(e), 1); + fmpz_mod(padic_unit(e), padic_unit(e), pow); + fmpz_clear(pow); + } + + c0 = clock(); + for (r = runs[l]; (r); r--) + { + padic_log_rectangular(z, e, ctx); + padic_zero(z); + } + c1 = clock(); + + padic_log_rectangular(z, e, ctx); + padic_exp_rectangular(z, z, ctx); + if (!padic_equal(e, z)) + { + flint_printf("FAIL:\n"); + flint_printf("e = "), padic_print(e, ctx), flint_printf("\n"); + flint_printf("z = "), padic_print(z, ctx), flint_printf("\n"); + flint_printf("p = %wd\n", *p), flint_printf("\n"); + flint_printf("N = %wd\n", n), flint_printf("\n"); + abort(); + } + + cputime = (long double) (c1 - c0) / (long double) CLOCKS_PER_SEC; + + T[l] = (slong) (cputime * (1000000000 / runs[l])); + + flint_printf("%2ld, %4XYXYXYXY, %8ld, %wd\n", + l, cputime, runs[l], T[l]); + + padic_clear(e); + padic_clear(z); + + fmpz_clear(p); + padic_ctx_clear(ctx); + flint_randclear(state); +} + + flint_printf("Output as a list:\n"); + for (l = 0; l < len; l++) + flint_printf("%wd, ", T[l]); + flint_printf("\n"); +} + diff --git a/external/flint-2.4.3/padic/profile/p-mul.c b/external/flint-2.4.3/padic/profile/p-mul.c new file mode 100644 index 0000000..d045f29 --- /dev/null +++ b/external/flint-2.4.3/padic/profile/p-mul.c @@ -0,0 +1,127 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +/* + Benchmarks for the p-adic multiplication routine. + + We consider the set-up with p = 17, N = 2^i, i = 0, ..., 19, + and multiply a = 3^{3 N}, b = 5^{3 N} mod p^N. + */ + +#include +#include +#include +#include +#include +#include + +#include "flint.h" +#include "fmpz.h" +#include "padic.h" + +int +main(void) +{ + long l, len = 20; + long runs[] = { + 10000000, 10000000, 10000000, 10000000, 1000000, + 1000000, 1000000, 1000000, 100000, 100000, + 100000, 10000, 10000, 1000, 1000, + 100, 100, 10, 10, 10 + }; + long N[] = { + 1, 2, 4, 8, 16, + 32, 64, 128, 256, 512, + 1024, WORD(1) << 11, WORD(1) << 12, WORD(1) << 13, WORD(1) << 14, + WORD(1) << 15, WORD(1) << 16, WORD(1) << 17, WORD(1) << 18, WORD(1) << 19 + }; + long T[20] = {0}; + + flint_printf("Benchmark for p-adic multiplication.\n"); + fflush(stdout); + +for (l = 0; l < len; l++) +{ + FLINT_TEST_INIT(state); + long n = N[l], r; + clock_t c0, c1; + long double cputime; + + fmpz_t p; + padic_ctx_t ctx; + padic_t a, b, z; + + + + fmpz_init_set_ui(p, 17); + + padic_ctx_init(ctx, p, n, n, PADIC_VAL_UNIT); + + padic_init(a); + padic_init(b); + padic_init(z); + + { + fmpz_t f = {WORD(3)}, g = {WORD(5)}, pow; + + fmpz_init(pow); + fmpz_pow_ui(pow, p, n); + fmpz_pow_ui(padic_unit(a), f, 3 * n); + fmpz_pow_ui(padic_unit(b), g, 3 * n); + fmpz_mod(padic_unit(a), padic_unit(a), pow); + fmpz_mod(padic_unit(b), padic_unit(b), pow); + fmpz_clear(pow); + } + + c0 = clock(); + for (r = runs[l]; (r); r--) + { + padic_mul(z, a, b, ctx); + padic_zero(z); + } + c1 = clock(); + + cputime = (long double) (c1 - c0) / (long double) CLOCKS_PER_SEC; + + T[l] = (slong) (cputime * (1000000000 / runs[l])); + + flint_printf("%2ld, %4XYXYXYXY, %8ld, %wd\n", + l, cputime, runs[l], T[l]); + + padic_clear(a); + padic_clear(b); + padic_clear(z); + + fmpz_clear(p); + padic_ctx_clear(ctx); + flint_randclear(state); +} + + flint_printf("Output as a list:\n"); + for (l = 0; l < len; l++) + flint_printf("%wd, ", T[l]); + flint_printf("\n"); +} + diff --git a/external/flint-2.4.3/padic/profile/p-sqrt.c b/external/flint-2.4.3/padic/profile/p-sqrt.c new file mode 100644 index 0000000..74427bb --- /dev/null +++ b/external/flint-2.4.3/padic/profile/p-sqrt.c @@ -0,0 +1,127 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +/* + Benchmarks for the p-adic square root routine. + + We consider the set-up with p = 17, N = 2^i, i = 0, ..., 19, + and compute a square root of b = a^2, a = 3^{3 N} mod p^N. + */ + +#include +#include +#include +#include +#include +#include + +#include "flint.h" +#include "fmpz.h" +#include "padic.h" + +int +main(void) +{ + long l, len = 20; + long runs[] = { + 1000000, 1000000, 1000000, 1000000, 1000000, + 100000, 100000, 100000, 100000, 10000, + 10000, 1000, 1000, 1000, 10, + 10, 10, 10, 10, 1 + }; + long N[] = { + 1, 2, 4, 8, 16, + 32, 64, 128, 256, 512, + 1024, WORD(1) << 11, WORD(1) << 12, WORD(1) << 13, WORD(1) << 14, + WORD(1) << 15, WORD(1) << 16, WORD(1) << 17, WORD(1) << 18, WORD(1) << 19 + }; + long T[20] = {0}; + + flint_printf("Benchmark for p-adic square root.\n"); + fflush(stdout); + +for (l = 0; l < len; l++) +{ + FLINT_TEST_INIT(state); + long n = N[l], r; + clock_t c0, c1; + long double cputime; + + fmpz_t p; + padic_ctx_t ctx; + padic_t a, b, z; + + + + fmpz_init_set_ui(p, 17); + + padic_ctx_init(ctx, p, n, n, PADIC_VAL_UNIT); + + padic_init(a); + padic_init(b); + padic_init(z); + + { + fmpz_t f = {WORD(3)}, pow; + + fmpz_init(pow); + fmpz_pow_ui(pow, p, n); + fmpz_pow_ui(padic_unit(a), f, 3 * n); + fmpz_mod(padic_unit(a), padic_unit(a), pow); + fmpz_pow_ui(padic_unit(b), padic_unit(a), 2); + fmpz_mod(padic_unit(b), padic_unit(b), pow); + fmpz_clear(pow); + } + + c0 = clock(); + for (r = runs[l]; (r); r--) + { + padic_sqrt(z, b, ctx); + padic_zero(z); + } + c1 = clock(); + + cputime = (long double) (c1 - c0) / (long double) CLOCKS_PER_SEC; + + T[l] = (slong) (cputime * (1000000000 / runs[l])); + + flint_printf("%2ld, %4XYXYXYXY, %8ld, %wd\n", + l, cputime, runs[l], T[l]); + + padic_clear(a); + padic_clear(b); + padic_clear(z); + + fmpz_clear(p); + padic_ctx_clear(ctx); + flint_randclear(state); +} + + flint_printf("Output as a list:\n"); + for (l = 0; l < len; l++) + flint_printf("%wd, ", T[l]); + flint_printf("\n"); +} + diff --git a/external/flint-2.4.3/padic/profile/p-teichmuller.c b/external/flint-2.4.3/padic/profile/p-teichmuller.c new file mode 100644 index 0000000..044c331 --- /dev/null +++ b/external/flint-2.4.3/padic/profile/p-teichmuller.c @@ -0,0 +1,115 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +/* + Benchmarks for the p-adic Teichmuller routine. + + We consider the set-up with p = 17, N = 2^i, i = 0, ..., 19, + and compute the Teichmuller lift of c = 3. + */ + +#include +#include +#include +#include +#include +#include + +#include "flint.h" +#include "fmpz.h" +#include "padic.h" + +int +main(void) +{ + long l, len = 20; + long runs[] = { + 1000000, 1000000, 1000000, 1000000, 100000, + 100000, 100000, 100000, 10000, 10000, + 10000, 1000, 1000, 100, 100, + 10, 10, 1, 1, 1 + }; + long N[] = { + 1, 2, 4, 8, 16, + 32, 64, 128, 256, 512, + 1024, WORD(1) << 11, WORD(1) << 12, WORD(1) << 13, WORD(1) << 14, + WORD(1) << 15, WORD(1) << 16, WORD(1) << 17, WORD(1) << 18, WORD(1) << 19 + }; + long T[20] = {0}; + + flint_printf("Benchmark for p-adic Teichmuller.\n"); + fflush(stdout); + +for (l = 0; l < len; l++) +{ + FLINT_TEST_INIT(state); + long n = N[l], r; + clock_t c0, c1; + long double cputime; + + fmpz_t p; + padic_ctx_t ctx; + padic_t c, z; + + + + fmpz_init_set_ui(p, 17); + + padic_ctx_init(ctx, p, n, n, PADIC_VAL_UNIT); + + padic_init(c); + padic_init(z); + + fmpz_set_ui(padic_unit(c), 3); + + c0 = clock(); + for (r = runs[l]; (r); r--) + { + padic_teichmuller(z, c, ctx); + padic_zero(z); + } + c1 = clock(); + + cputime = (long double) (c1 - c0) / (long double) CLOCKS_PER_SEC; + + T[l] = (slong) (cputime * (1000000000 / runs[l])); + + flint_printf("%2ld, %4XYXYXYXY, %7ld, %wd\n", + l, cputime, runs[l], T[l]); + + padic_clear(c); + padic_clear(z); + + fmpz_clear(p); + padic_ctx_clear(ctx); + flint_randclear(state); +} + + flint_printf("Output as a list:\n"); + for (l = 0; l < len; l++) + flint_printf("%wd, ", T[l]); + flint_printf("\n"); +} + diff --git a/external/flint-2.4.3/padic/randtest.c b/external/flint-2.4.3/padic/randtest.c new file mode 100644 index 0000000..27b3d5e --- /dev/null +++ b/external/flint-2.4.3/padic/randtest.c @@ -0,0 +1,103 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "padic.h" + +#define PADIC_RANDTEST_TRIES 10 + +void padic_randtest(padic_t rop, flint_rand_t state, const padic_ctx_t ctx) +{ + const slong N = padic_prec(rop); + + slong min, max; + fmpz_t pow; + int alloc; + + if (N > 0) + { + min = - ((N + 9) / 10); + max = N; + } + else if (N < 0) + { + min = N - ((-N + 9) / 10); + max = N; + } + else /* ctx->N == 0 */ + { + min = -10; + max = 0; + } + + padic_val(rop) = n_randint(state, max - min) + min; + + alloc = _padic_ctx_pow_ui(pow, N - padic_val(rop), ctx); + fmpz_randm(padic_unit(rop), state, pow); + _padic_canonicalise(rop, ctx); + if (alloc) + fmpz_clear(pow); +} + +void padic_randtest_not_zero(padic_t rop, flint_rand_t state, + const padic_ctx_t ctx) +{ + slong i; + + padic_randtest(rop, state, ctx); + + for (i = 1; !padic_is_zero(rop) && i < PADIC_RANDTEST_TRIES; i++) + padic_randtest(rop, state, ctx); + + if (padic_is_zero(rop)) + { + fmpz_one(padic_unit(rop)); + padic_val(rop) = padic_prec(rop) - 1; + } +} + +void padic_randtest_int(padic_t rop, flint_rand_t state, + const padic_ctx_t ctx) +{ + const slong N = padic_prec(rop); + + if (N <= 0) + { + padic_zero(rop); + } + else + { + fmpz_t pow; + int alloc; + + padic_val(rop) = n_randint(state, N); + + alloc = _padic_ctx_pow_ui(pow, N - padic_val(rop), ctx); + fmpz_randm(padic_unit(rop), state, pow); + _padic_canonicalise(rop, ctx); + if (alloc) + fmpz_clear(pow); + } +} + diff --git a/external/flint-2.4.3/padic/reduce.c b/external/flint-2.4.3/padic/reduce.c new file mode 100644 index 0000000..5c76b96 --- /dev/null +++ b/external/flint-2.4.3/padic/reduce.c @@ -0,0 +1,54 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "padic.h" + +void _padic_reduce(padic_t rop, const padic_ctx_t ctx) +{ + if (!fmpz_is_zero(padic_unit(rop))) + { + if (padic_val(rop) < padic_prec(rop)) + { + int c; + fmpz_t pow; + + c = _padic_ctx_pow_ui(pow, padic_prec(rop) - padic_val(rop), ctx); + fmpz_mod(padic_unit(rop), padic_unit(rop), pow); + if (c) + fmpz_clear(pow); + } + else + { + padic_zero(rop); + } + } +} + +void padic_reduce(padic_t rop, const padic_ctx_t ctx) +{ + _padic_canonicalise(rop, ctx); + _padic_reduce(rop, ctx); +} + diff --git a/external/flint-2.4.3/padic/set.c b/external/flint-2.4.3/padic/set.c new file mode 100644 index 0000000..e64d16a --- /dev/null +++ b/external/flint-2.4.3/padic/set.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "padic.h" + +void padic_set(padic_t rop, const padic_t op, const padic_ctx_t ctx) +{ + fmpz_set(padic_unit(rop), padic_unit(op)); + padic_val(rop) = padic_val(op); + + if (padic_prec(rop) < padic_prec(op)) + { + _padic_reduce(rop, ctx); + } +} + diff --git a/external/flint-2.4.3/padic/set_fmpq.c b/external/flint-2.4.3/padic/set_fmpq.c new file mode 100644 index 0000000..f526be5 --- /dev/null +++ b/external/flint-2.4.3/padic/set_fmpq.c @@ -0,0 +1,57 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "padic.h" + +void padic_set_fmpq(padic_t rop, const fmpq_t op, const padic_ctx_t ctx) +{ + if (fmpq_is_zero(op)) + { + padic_zero(rop); + } + else + { + fmpq_t t; + + fmpq_init(t); + + padic_val(rop) = fmpz_remove(fmpq_numref(t), fmpq_numref(op), ctx->p); + padic_val(rop) -= fmpz_remove(fmpq_denref(t), fmpq_denref(op), ctx->p); + + if (padic_val(rop) >= padic_prec(rop)) + { + padic_zero(rop); + } + else + { + _padic_inv(fmpq_denref(t), + fmpq_denref(t), ctx->p, padic_prec(rop) - padic_val(rop)); + fmpz_mul(padic_unit(rop), fmpq_numref(t), fmpq_denref(t)); + _padic_reduce(rop, ctx); + } + fmpq_clear(t); + } +} + diff --git a/external/flint-2.4.3/padic/set_fmpz.c b/external/flint-2.4.3/padic/set_fmpz.c new file mode 100644 index 0000000..0392157 --- /dev/null +++ b/external/flint-2.4.3/padic/set_fmpz.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "padic.h" + +void padic_set_fmpz(padic_t rop, const fmpz_t op, const padic_ctx_t ctx) +{ + if (!fmpz_is_zero(op)) + { + padic_val(rop) = fmpz_remove(padic_unit(rop), op, ctx->p); + _padic_reduce(rop, ctx); + } + else + { + padic_zero(rop); + } +} + diff --git a/external/flint-2.4.3/padic/set_mpq.c b/external/flint-2.4.3/padic/set_mpq.c new file mode 100644 index 0000000..5697a8c --- /dev/null +++ b/external/flint-2.4.3/padic/set_mpq.c @@ -0,0 +1,37 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "padic.h" + +void padic_set_mpq(padic_t rop, const mpq_t op, const padic_ctx_t ctx) +{ + fmpq_t t; + + fmpq_init(t); + fmpq_set_mpq(t, op); + padic_set_fmpq(rop, t, ctx); + fmpq_clear(t); +} + diff --git a/external/flint-2.4.3/padic/set_mpz.c b/external/flint-2.4.3/padic/set_mpz.c new file mode 100644 index 0000000..3413637 --- /dev/null +++ b/external/flint-2.4.3/padic/set_mpz.c @@ -0,0 +1,37 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "padic.h" + +void padic_set_mpz(padic_t rop, const mpz_t op, const padic_ctx_t ctx) +{ + fmpz_t t; + + fmpz_init(t); + fmpz_set_mpz(t, op); + padic_set_fmpz(rop, t, ctx); + fmpz_clear(t); +} + diff --git a/external/flint-2.4.3/padic/set_si.c b/external/flint-2.4.3/padic/set_si.c new file mode 100644 index 0000000..58c1048 --- /dev/null +++ b/external/flint-2.4.3/padic/set_si.c @@ -0,0 +1,34 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "padic.h" + +void padic_set_si(padic_t rop, slong op, const padic_ctx_t ctx) +{ + fmpz_set_si(padic_unit(rop), op); + padic_val(rop) = 0; + padic_reduce(rop, ctx); +} + diff --git a/external/flint-2.4.3/padic/set_ui.c b/external/flint-2.4.3/padic/set_ui.c new file mode 100644 index 0000000..e656175 --- /dev/null +++ b/external/flint-2.4.3/padic/set_ui.c @@ -0,0 +1,58 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "padic.h" + +void padic_set_ui(padic_t rop, ulong op, const padic_ctx_t ctx) +{ + if (op == 0) + { + padic_zero(rop); + } + else if (fmpz_cmp_ui(ctx->p, op) > 0) + { + fmpz_set_ui(padic_unit(rop), op); + padic_val(rop) = 0; + } + else + { + ulong p = fmpz_get_ui(ctx->p), q, r; + + /* Remove factors of p */ + padic_val(rop) = 0; + r = n_divrem2_precomp(&q, op, p, ctx->pinv); + while (r == 0) + { + op = q; + padic_val(rop)++; + r = n_divrem2_precomp(&q, op, p, ctx->pinv); + } + + fmpz_set_ui(padic_unit(rop), op); + + _padic_reduce(rop, ctx); + } +} + diff --git a/external/flint-2.4.3/padic/shift.c b/external/flint-2.4.3/padic/shift.c new file mode 100644 index 0000000..ee3e05b --- /dev/null +++ b/external/flint-2.4.3/padic/shift.c @@ -0,0 +1,41 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "padic.h" + +void padic_shift(padic_t rop, const padic_t op, slong v, const padic_ctx_t ctx) +{ + if (padic_is_zero(op) || (padic_val(op) + v >= padic_prec(rop))) + { + padic_zero(rop); + } + else + { + fmpz_set(padic_unit(rop), padic_unit(op)); + padic_val(rop) = padic_val(op) + v; + _padic_reduce(rop, ctx); + } +} + diff --git a/external/flint-2.4.3/padic/sqrt.c b/external/flint-2.4.3/padic/sqrt.c new file mode 100644 index 0000000..d5d58cc --- /dev/null +++ b/external/flint-2.4.3/padic/sqrt.c @@ -0,0 +1,242 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Jan Tuitman + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "padic.h" + +/* + Returns whether \code{op} has a square root modulo $p^N$ and if + so sets \code{rop} to such an element. + + Assumes that \code{op} is a unit modulo $p^N$. Assumes $p$ is an + odd prime. + + In the current implementation, allows aliasing. + */ +static int _padic_sqrt_p(fmpz_t rop, const fmpz_t op, const fmpz_t p, slong N) +{ + int ans; + + if (N == 1) + { + ans = fmpz_sqrtmod(rop, op, p); + return ans; + } + else + { + slong *e, i, n; + fmpz *W, *pow, *u; + + e = _padic_lifts_exps(&n, N); + + W = _fmpz_vec_init(2 + 2 * n); + pow = W + 2; + u = W + (2 + n); + + _padic_lifts_pows(pow, e, n, p); + + /* Compute reduced units */ + { + fmpz_mod(u, op, pow); + } + for (i = 1; i < n; i++) + { + fmpz_mod(u + i, u + (i - 1), pow + i); + } + + /* + Run Newton iteration for the inverse square root, + using the update formula + z := z - z (u z^2 - 1) / 2 + for all but the last step. The last step is + replaced with + b := u z mod p^{N'} + z := b + z (u - b^2) / 2 mod p^{N}. + */ + i = n - 1; + { + ans = fmpz_sqrtmod(rop, u + i, p); + if (!ans) + goto exit; + fmpz_invmod(rop, rop, p); + } + for (i--; i >= 1; i--) + { + fmpz_mul(W, rop, rop); + fmpz_mul(W + 1, u + i, W); + fmpz_sub_ui(W + 1, W + 1, 1); + + if (fmpz_is_odd(W + 1)) + fmpz_add(W + 1, W + 1, pow + i); + fmpz_fdiv_q_2exp(W + 1, W + 1, 1); + + fmpz_mul(W, W + 1, rop); + fmpz_sub(rop, rop, W); + fmpz_mod(rop, rop, pow + i); + } + { + fmpz_mul(W, u + 1, rop); + fmpz_mul(W + 1, W, W); + fmpz_sub(W + 1, u + 0, W + 1); + if (fmpz_is_odd(W + 1)) + fmpz_add(W + 1, W + 1, pow + 0); + fmpz_fdiv_q_2exp(W + 1, W + 1, 1); + fmpz_mul(rop, rop, W + 1); + fmpz_add(rop, W, rop); + fmpz_mod(rop, rop, pow + 0); + } + + exit: + + flint_free(e); + _fmpz_vec_clear(W, 2 + 2 * n); + + return ans; + } +} + +/* + Returns whether \code{op} has a square root modulo $2^N$ and if + so sets \code{rop} to such an element. + + Assumes that \code{op} is a unit modulo $2^N$. + + In the current implementation, allows aliasing. + */ +static int _padic_sqrt_2(fmpz_t rop, const fmpz_t op, slong N) +{ + if (fmpz_fdiv_ui(op, 8) != 1) + return 0; + + if (N <= 3) + { + fmpz_one(rop); + } + else + { + slong *e, i, n; + fmpz *W, *u; + + i = FLINT_CLOG2(N); + + /* Compute sequence of exponents */ + e = flint_malloc((i + 2) * sizeof(slong)); + for (e[i = 0] = N; e[i] > 3; i++) + e[i + 1] = (e[i] + 3) / 2; + n = i + 1; + + W = _fmpz_vec_init(2 + n); + u = W + 2; + + /* Compute reduced units */ + { + fmpz_fdiv_r_2exp(u, op, e[0]); + } + for (i = 1; i < n; i++) + { + fmpz_fdiv_r_2exp(u + i, u + (i - 1), e[i]); + } + + /* Run Newton iteration */ + fmpz_one(rop); + for (i = n - 2; i >= 1; i--) /* z := z - z (a z^2 - 1) / 2 */ + { + fmpz_mul(W, rop, rop); + fmpz_mul(W + 1, u + i, W); + fmpz_sub_ui(W + 1, W + 1, 1); + fmpz_fdiv_q_2exp(W + 1, W + 1, 1); + fmpz_mul(W, W + 1, rop); + fmpz_sub(rop, rop, W); + fmpz_fdiv_r_2exp(rop, rop, e[i]); + } + { + fmpz_mul(W, u + 1, rop); + fmpz_mul(W + 1, W, W); + fmpz_sub(W + 1, u + 0, W + 1); + fmpz_fdiv_q_2exp(W + 1, W + 1, 1); + fmpz_mul(rop, rop, W + 1); + fmpz_add(rop, W, rop); + } + fmpz_fdiv_r_2exp(rop, rop, e[0]); + + flint_free(e); + _fmpz_vec_clear(W, 2 + n); + + } + return 1; +} + +int _padic_sqrt(fmpz_t rop, const fmpz_t op, const fmpz_t p, slong N) +{ + if (fmpz_equal_ui(p, 2)) + { + return _padic_sqrt_2(rop, op, N); + } + else + { + return _padic_sqrt_p(rop, op, p, N); + } +} + +int padic_sqrt(padic_t rop, const padic_t op, const padic_ctx_t ctx) +{ + if (padic_is_zero(op)) + { + padic_zero(rop); + return 1; + } + if (padic_val(op) & WORD(1)) + { + return 0; + } + + padic_val(rop) = padic_val(op) / 2; + + /* + In this case, if there is a square root it will be + zero modulo $p^N$. We only have to establish whether + or not the element \code{op} is a square. + */ + if (padic_val(rop) >= padic_prec(rop)) + { + int ans; + + if (fmpz_equal_ui(ctx->p, 2)) + { + ans = (fmpz_fdiv_ui(padic_unit(op), 8) == 1); + } + else + { + ans = fmpz_sqrtmod(padic_unit(rop), padic_unit(op), ctx->p); + } + padic_zero(rop); + + return ans; + } + + return _padic_sqrt(padic_unit(rop), + padic_unit(op), ctx->p, padic_prec(rop) - padic_val(rop)); +} + diff --git a/external/flint-2.4.3/padic/sub.c b/external/flint-2.4.3/padic/sub.c new file mode 100644 index 0000000..8a5a4bc --- /dev/null +++ b/external/flint-2.4.3/padic/sub.c @@ -0,0 +1,126 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "padic.h" + +void padic_sub(padic_t rop, const padic_t op1, const padic_t op2, + const padic_ctx_t ctx) +{ + if (padic_prec(rop) <= FLINT_MIN(padic_val(op1), padic_val(op2))) + { + padic_zero(rop); + return; + } + + if (padic_is_zero(op1)) + { + padic_neg(rop, op2, ctx); + } + else if (padic_is_zero(op2)) + { + padic_set(rop, op1, ctx); + } + else + { + if (padic_val(op1) == padic_val(op2)) + { + fmpz_sub(padic_unit(rop), padic_unit(op1), padic_unit(op2)); + padic_val(rop) = padic_val(op1); + + _padic_canonicalise(rop, ctx); + + if (padic_prec(rop) <= padic_val(rop)) + { + padic_zero(rop); + return; + } + } + else if (padic_val(op1) < padic_val(op2)) + { + fmpz_t f; + + fmpz_init(f); + fmpz_pow_ui(f, ctx->p, padic_val(op2) - padic_val(op1)); + if (rop != op2) + { + fmpz_set(padic_unit(rop), padic_unit(op1)); + fmpz_submul(padic_unit(rop), f, padic_unit(op2)); + } + else + { + fmpz_mul(padic_unit(rop), f, padic_unit(op2)); + fmpz_sub(padic_unit(rop), padic_unit(rop), padic_unit(op1)); + fmpz_neg(padic_unit(rop), padic_unit(rop)); + } + fmpz_clear(f); + + padic_val(rop) = padic_val(op1); + } + else /* padic_val(op1) > padic_val(op2) */ + { + fmpz_t f; + + fmpz_init(f); + fmpz_pow_ui(f, ctx->p, padic_val(op1) - padic_val(op2)); + if (rop != op1) + { + fmpz_neg(padic_unit(rop), padic_unit(op2)); + fmpz_addmul(padic_unit(rop), f, padic_unit(op1)); + } + else + { + fmpz_mul(padic_unit(rop), f, padic_unit(op1)); + fmpz_sub(padic_unit(rop), padic_unit(rop), padic_unit(op2)); + } + fmpz_clear(f); + + padic_val(rop) = padic_val(op2); + } + + { + int alloc; + fmpz_t pow; + + alloc = _padic_ctx_pow_ui(pow, padic_prec(rop) - padic_val(rop), ctx); + + if (padic_prec(rop) >= FLINT_MAX(padic_prec(op1), padic_prec(op2))) + { + if (fmpz_sgn(padic_unit(rop)) < 0) + fmpz_add(padic_unit(rop), padic_unit(rop), pow); + } + else + { + fmpz_mod(padic_unit(rop), padic_unit(rop), pow); + } + + if (fmpz_is_zero(padic_unit(rop))) + padic_val(rop) = 0; + + if (alloc) + fmpz_clear(pow); + } + } +} + diff --git a/external/flint-2.4.3/padic/teichmuller.c b/external/flint-2.4.3/padic/teichmuller.c new file mode 100644 index 0000000..873dbc4 --- /dev/null +++ b/external/flint-2.4.3/padic/teichmuller.c @@ -0,0 +1,123 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "padic.h" + +void _padic_teichmuller(fmpz_t rop, const fmpz_t op, const fmpz_t p, slong N) +{ + if (fmpz_equal_ui(p, 2)) + { + fmpz_one(rop); + } + else if (N == 1) + { + fmpz_mod(rop, op, p); + } + else + { + slong *a, i, n; + fmpz *pow, *u; + fmpz_t s, t; + fmpz_t inv; + fmpz_t pm1; + + a = _padic_lifts_exps(&n, N); + + pow = _fmpz_vec_init(2 * n); + u = pow + n; + + _padic_lifts_pows(pow, a, n, p); + + fmpz_init(s); + fmpz_init(t); + fmpz_init(inv); + fmpz_init(pm1); + + fmpz_sub_ui(pm1, p, 1); + + /* Compute reduced units for (p-1) */ + { + fmpz_mod(u + 0, pm1, pow + 0); + } + for (i = 1; i < n; i++) + { + fmpz_mod(u + i, u + (i - 1), pow + i); + } + + /* Run Newton iteration */ + i = n - 1; + { + fmpz_mod(rop, op, pow + i); + + fmpz_set(inv, pm1); + } + for (i--; i >= 0; i--) + { + /* Lift rop */ + fmpz_powm(s, rop, p, pow + i); + fmpz_sub(s, s, rop); + fmpz_mul(t, s, inv); + fmpz_sub(rop, rop, t); + fmpz_mod(rop, rop, pow + i); + + /* Lift inv */ + if (i > 0) + { + fmpz_mul(s, inv, inv); + fmpz_mul(t, u + i, s); + fmpz_mul_2exp(inv, inv, 1); + fmpz_sub(inv, inv, t); + fmpz_mod(inv, inv, pow + i); + } + } + + fmpz_clear(s); + fmpz_clear(t); + fmpz_clear(inv); + fmpz_clear(pm1); + _fmpz_vec_clear(pow, 2 * n); + flint_free(a); + } +} + +void padic_teichmuller(padic_t rop, const padic_t op, const padic_ctx_t ctx) +{ + if (padic_val(op) < 0) + { + flint_printf("Exception (padic_teichmuller). op is not a p-adic integer.\n"); + abort(); + } + + if (padic_is_zero(op) || padic_val(op) > 0 || padic_prec(rop) <= 0) + { + padic_zero(rop); + } + else + { + _padic_teichmuller(padic_unit(rop), padic_unit(op), ctx->p, padic_prec(rop)); + padic_val(rop) = 0; + } +} + diff --git a/external/flint-2.4.3/padic/test/t-add.c b/external/flint-2.4.3/padic/test/t-add.c new file mode 100644 index 0000000..2cf8e42 --- /dev/null +++ b/external/flint-2.4.3/padic/test/t-add.c @@ -0,0 +1,303 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "ulong_extras.h" +#include "long_extras.h" +#include "padic.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("add... "); + fflush(stdout); + + + + /* Check aliasing: a = a + b */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b, d; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + padic_init2(d, N); + + padic_randtest(a, state, ctx); + padic_randtest(b, state, ctx); + + padic_add(d, a, b, ctx); + padic_add(a, a, b, ctx); + + result = (padic_equal(a, d)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("d = "), padic_print(d, ctx), flint_printf("\n"); + abort(); + } + + padic_clear(a); + padic_clear(b); + padic_clear(d); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Check aliasing: b = a + b */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b, d; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + padic_init2(d, N); + + padic_randtest(a, state, ctx); + padic_randtest(b, state, ctx); + + padic_add(d, a, b, ctx); + padic_add(b, a, b, ctx); + + result = (padic_equal(b, d)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("d = "), padic_print(d, ctx), flint_printf("\n"); + abort(); + } + + padic_clear(a); + padic_clear(b); + padic_clear(d); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Check aliasing: a = a + a */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, d; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(d, N); + + padic_randtest(a, state, ctx); + + padic_add(d, a, a, ctx); + padic_add(a, a, a, ctx); + + result = (padic_equal(a, d)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("d = "), padic_print(d, ctx), flint_printf("\n"); + abort(); + } + + padic_clear(a); + padic_clear(d); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Check that a + b == b + a */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b, c, d; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + padic_init2(c, N); + padic_init2(d, N); + + padic_randtest(a, state, ctx); + padic_randtest(b, state, ctx); + + padic_add(c, a, b, ctx); + padic_add(d, b, a, ctx); + + result = (padic_equal(c, d)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("c = "), padic_print(c, ctx), flint_printf("\n"); + flint_printf("d = "), padic_print(d, ctx), flint_printf("\n"); + abort(); + } + + padic_clear(a); + padic_clear(b); + padic_clear(c); + padic_clear(d); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Check that (a + b) + c == a + (b + c) */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b, c, d, e; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + padic_init2(c, N); + padic_init2(d, N); + padic_init2(e, N); + + padic_randtest(a, state, ctx); + padic_randtest(b, state, ctx); + padic_randtest(c, state, ctx); + + padic_add(d, a, b, ctx); + padic_add(d, d, c, ctx); + + padic_add(e, b, c, ctx); + padic_add(e, a, e, ctx); + + result = (padic_equal(d, e)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("c = "), padic_print(c, ctx), flint_printf("\n"); + flint_printf("d = "), padic_print(d, ctx), flint_printf("\n"); + flint_printf("e = "), padic_print(e, ctx), flint_printf("\n"); + abort(); + } + + padic_clear(a); + padic_clear(b); + padic_clear(c); + padic_clear(d); + padic_clear(e); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Check that a + 0 == a */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + + padic_randtest(a, state, ctx); + padic_zero(b); + + padic_add(b, a, b, ctx); + + result = (padic_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + abort(); + } + + padic_clear(a); + padic_clear(b); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/padic/test/t-div.c b/external/flint-2.4.3/padic/test/t-div.c new file mode 100644 index 0000000..fdfc487 --- /dev/null +++ b/external/flint-2.4.3/padic/test/t-div.c @@ -0,0 +1,209 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "ulong_extras.h" +#include "long_extras.h" +#include "padic.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("div... "); + fflush(stdout); + + + + /* Check aliasing: a = a / b (mod p^N) */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b, d; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + padic_init2(d, N); + + padic_randtest(a, state, ctx); + padic_randtest_not_zero(b, state, ctx); + + padic_div(d, a, b, ctx); + padic_div(a, a, b, ctx); + + result = (padic_equal(a, d)); + if (!result) + { + flint_printf("FAIL (aliasing a = a/b) :\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("d = "), padic_print(d, ctx), flint_printf("\n"); + abort(); + } + + padic_clear(a); + padic_clear(b); + padic_clear(d); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Check aliasing: b = a / b (mod p^N) */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b, d; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + padic_init2(d, N); + + padic_randtest(a, state, ctx); + padic_randtest_not_zero(b, state, ctx); + + padic_div(d, a, b, ctx); + padic_div(b, a, b, ctx); + + result = (padic_equal(b, d)); + if (!result) + { + flint_printf("FAIL (aliasing b = a/b):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("d = "), padic_print(d, ctx), flint_printf("\n"); + abort(); + } + + padic_clear(a); + padic_clear(b); + padic_clear(d); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Check aliasing: a = a / a (mod p^N) */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, d; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(d, N); + + padic_randtest_not_zero(a, state, ctx); + + padic_div(d, a, a, ctx); + padic_div(a, a, a, ctx); + + result = (padic_equal(a, d)); + if (!result) + { + flint_printf("FAIL (aliasing a = a/a):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("d = "), padic_print(d, ctx), flint_printf("\n"); + abort(); + } + + padic_clear(a); + padic_clear(d); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Check that a / 1 == a */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b, c; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(c, N); + padic_init2(b, FLINT_MAX(N, 1)); + + padic_randtest(a, state, ctx); + padic_one(b); + + padic_div(c, a, b, ctx); + + result = (padic_equal(a, c)); + if (!result) + { + flint_printf("FAIL (a/1 == a):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("c = "), padic_print(b, ctx), flint_printf("\n"); + abort(); + } + + padic_clear(a); + padic_clear(b); + padic_clear(c); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/padic/test/t-exp.c b/external/flint-2.4.3/padic/test/t-exp.c new file mode 100644 index 0000000..c687f4e --- /dev/null +++ b/external/flint-2.4.3/padic/test/t-exp.c @@ -0,0 +1,257 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "ulong_extras.h" +#include "padic.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("exp... "); + fflush(stdout); + + + +/** p == 2 *******************************************************************/ + + /* Check aliasing: a = exp(a) */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b; + int ans1, ans2; + + fmpz_init_set_ui(p, 2); + + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + + padic_randtest(a, state, ctx); + + ans1 = padic_exp(b, a, ctx); + ans2 = padic_exp(a, a, ctx); + + result = ((ans1 == ans2) && (!ans1 || padic_equal(a, b))); + if (!result) + { + flint_printf("FAIL (aliasing):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("ans1 = %d\n", ans1); + flint_printf("ans2 = %d\n", ans2); + abort(); + } + + padic_clear(a); + padic_clear(b); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Functional equation: exp(a + b) == exp(a) exp(b) */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b, c, d, e, f, g; + int ans1, ans2, ans3; + + fmpz_init_set_ui(p, 2); + + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + padic_init2(c, N); + padic_init2(d, N); + padic_init2(e, N); + padic_init2(f, N); + padic_init2(g, N); + + padic_randtest(a, state, ctx); + padic_randtest(b, state, ctx); + padic_add(c, a, b, ctx); + + ans1 = padic_exp(d, a, ctx); + ans2 = padic_exp(e, b, ctx); + padic_mul(f, d, e, ctx); + + ans3 = padic_exp(g, c, ctx); + + result = (!ans1 || !ans2 || (ans3 && padic_equal(f, g))); + if (!result) + { + flint_printf("FAIL (functional equation):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("c = a + b = "), padic_print(c, ctx), flint_printf("\n"); + flint_printf("d = exp(a) = "), padic_print(d, ctx), flint_printf("\n"); + flint_printf("e = exp(b) = "), padic_print(e, ctx), flint_printf("\n"); + flint_printf("f = exp(a) exp(b) = "), padic_print(f, ctx), flint_printf("\n"); + flint_printf("g = exp(a + b) = "), padic_print(g, ctx), flint_printf("\n"); + abort(); + } + + padic_clear(a); + padic_clear(b); + padic_clear(c); + padic_clear(d); + padic_clear(e); + padic_clear(f); + padic_clear(g); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + +/** p > 2 ********************************************************************/ + + /* Check aliasing: a = exp(a) */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b; + int ans1, ans2; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + + padic_randtest(a, state, ctx); + + ans1 = padic_exp(b, a, ctx); + ans2 = padic_exp(a, a, ctx); + + result = ((ans1 == ans2) && (!ans1 || padic_equal(a, b))); + if (!result) + { + flint_printf("FAIL (aliasing):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("ans1 = %d\n", ans1); + flint_printf("ans2 = %d\n", ans2); + abort(); + } + + padic_clear(a); + padic_clear(b); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Functional equation: exp(a + b) == exp(a) exp(b) */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b, c, d, e, f, g; + int ans1, ans2, ans3; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + padic_init2(c, N); + padic_init2(d, N); + padic_init2(e, N); + padic_init2(f, N); + padic_init2(g, N); + + padic_randtest(a, state, ctx); + padic_randtest(b, state, ctx); + padic_add(c, a, b, ctx); + + ans1 = padic_exp(d, a, ctx); + ans2 = padic_exp(e, b, ctx); + padic_mul(f, d, e, ctx); + + ans3 = padic_exp(g, c, ctx); + + result = (!ans1 || !ans2 || (ans3 && padic_equal(f, g))); + if (!result) + { + flint_printf("FAIL (functional equation):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("c = a + b = "), padic_print(c, ctx), flint_printf("\n"); + flint_printf("d = exp(a) = "), padic_print(d, ctx), flint_printf("\n"); + flint_printf("e = exp(b) = "), padic_print(e, ctx), flint_printf("\n"); + flint_printf("f = exp(a) exp(b) = "), padic_print(f, ctx), flint_printf("\n"); + flint_printf("g = exp(a + b) = "), padic_print(g, ctx), flint_printf("\n"); + abort(); + } + + padic_clear(a); + padic_clear(b); + padic_clear(c); + padic_clear(d); + padic_clear(e); + padic_clear(f); + padic_clear(g); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/padic/test/t-exp_balanced.c b/external/flint-2.4.3/padic/test/t-exp_balanced.c new file mode 100644 index 0000000..9fe5a9a --- /dev/null +++ b/external/flint-2.4.3/padic/test/t-exp_balanced.c @@ -0,0 +1,257 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "ulong_extras.h" +#include "padic.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("exp_balanced... "); + fflush(stdout); + + + +/** p == 2 *******************************************************************/ + + /* Check aliasing: a = exp(a) */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b; + int ans1, ans2; + + fmpz_init_set_ui(p, 2); + + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + + padic_randtest(a, state, ctx); + + ans1 = padic_exp_balanced(b, a, ctx); + ans2 = padic_exp_balanced(a, a, ctx); + + result = ((ans1 == ans2) && (!ans1 || padic_equal(a, b))); + if (!result) + { + flint_printf("FAIL (aliasing):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("ans1 = %d\n", ans1); + flint_printf("ans2 = %d\n", ans2); + abort(); + } + + padic_clear(a); + padic_clear(b); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Functional equation: exp(a + b) == exp(a) exp(b) */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b, c, d, e, f, g; + int ans1, ans2, ans3; + + fmpz_init_set_ui(p, 2); + + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + padic_init2(c, N); + padic_init2(d, N); + padic_init2(e, N); + padic_init2(f, N); + padic_init2(g, N); + + padic_randtest(a, state, ctx); + padic_randtest(b, state, ctx); + padic_add(c, a, b, ctx); + + ans1 = padic_exp_balanced(d, a, ctx); + ans2 = padic_exp_balanced(e, b, ctx); + padic_mul(f, d, e, ctx); + + ans3 = padic_exp_balanced(g, c, ctx); + + result = (!ans1 || !ans2 || (ans3 && padic_equal(f, g))); + if (!result) + { + flint_printf("FAIL (functional equation):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("c = a + b = "), padic_print(c, ctx), flint_printf("\n"); + flint_printf("d = exp(a) = "), padic_print(d, ctx), flint_printf("\n"); + flint_printf("e = exp(b) = "), padic_print(e, ctx), flint_printf("\n"); + flint_printf("f = exp(a) exp(b) = "), padic_print(f, ctx), flint_printf("\n"); + flint_printf("g = exp(a + b) = "), padic_print(g, ctx), flint_printf("\n"); + abort(); + } + + padic_clear(a); + padic_clear(b); + padic_clear(c); + padic_clear(d); + padic_clear(e); + padic_clear(f); + padic_clear(g); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + +/** p > 2 ********************************************************************/ + + /* Check aliasing: a = exp(a) */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b; + int ans1, ans2; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + + padic_randtest(a, state, ctx); + + ans1 = padic_exp_balanced(b, a, ctx); + ans2 = padic_exp_balanced(a, a, ctx); + + result = ((ans1 == ans2) && (!ans1 || padic_equal(a, b))); + if (!result) + { + flint_printf("FAIL (aliasing):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("ans1 = %d\n", ans1); + flint_printf("ans2 = %d\n", ans2); + abort(); + } + + padic_clear(a); + padic_clear(b); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Functional equation: exp(a + b) == exp(a) exp(b) */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b, c, d, e, f, g; + int ans1, ans2, ans3; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + padic_init2(c, N); + padic_init2(d, N); + padic_init2(e, N); + padic_init2(f, N); + padic_init2(g, N); + + padic_randtest(a, state, ctx); + padic_randtest(b, state, ctx); + padic_add(c, a, b, ctx); + + ans1 = padic_exp_balanced(d, a, ctx); + ans2 = padic_exp_balanced(e, b, ctx); + padic_mul(f, d, e, ctx); + + ans3 = padic_exp_balanced(g, c, ctx); + + result = (!ans1 || !ans2 || (ans3 && padic_equal(f, g))); + if (!result) + { + flint_printf("FAIL (functional equation):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("c = a + b = "), padic_print(c, ctx), flint_printf("\n"); + flint_printf("d = exp(a) = "), padic_print(d, ctx), flint_printf("\n"); + flint_printf("e = exp(b) = "), padic_print(e, ctx), flint_printf("\n"); + flint_printf("f = exp(a) exp(b) = "), padic_print(f, ctx), flint_printf("\n"); + flint_printf("g = exp(a + b) = "), padic_print(g, ctx), flint_printf("\n"); + abort(); + } + + padic_clear(a); + padic_clear(b); + padic_clear(c); + padic_clear(d); + padic_clear(e); + padic_clear(f); + padic_clear(g); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/padic/test/t-exp_rectangular.c b/external/flint-2.4.3/padic/test/t-exp_rectangular.c new file mode 100644 index 0000000..75ad77c --- /dev/null +++ b/external/flint-2.4.3/padic/test/t-exp_rectangular.c @@ -0,0 +1,257 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "ulong_extras.h" +#include "padic.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("exp_rectangular... "); + fflush(stdout); + + + +/** p == 2 *******************************************************************/ + + /* Check aliasing: a = exp(a) */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b; + int ans1, ans2; + + fmpz_init_set_ui(p, 2); + + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + + padic_randtest(a, state, ctx); + + ans1 = padic_exp_rectangular(b, a, ctx); + ans2 = padic_exp_rectangular(a, a, ctx); + + result = ((ans1 == ans2) && (!ans1 || padic_equal(a, b))); + if (!result) + { + flint_printf("FAIL (aliasing):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("ans1 = %d\n", ans1); + flint_printf("ans2 = %d\n", ans2); + abort(); + } + + padic_clear(a); + padic_clear(b); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Functional equation: exp(a + b) == exp(a) exp(b) */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b, c, d, e, f, g; + int ans1, ans2, ans3; + + fmpz_init_set_ui(p, 2); + + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + padic_init2(c, N); + padic_init2(d, N); + padic_init2(e, N); + padic_init2(f, N); + padic_init2(g, N); + + padic_randtest(a, state, ctx); + padic_randtest(b, state, ctx); + padic_add(c, a, b, ctx); + + ans1 = padic_exp_rectangular(d, a, ctx); + ans2 = padic_exp_rectangular(e, b, ctx); + padic_mul(f, d, e, ctx); + + ans3 = padic_exp_rectangular(g, c, ctx); + + result = (!ans1 || !ans2 || (ans3 && padic_equal(f, g))); + if (!result) + { + flint_printf("FAIL (functional equation):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("c = a + b = "), padic_print(c, ctx), flint_printf("\n"); + flint_printf("d = exp(a) = "), padic_print(d, ctx), flint_printf("\n"); + flint_printf("e = exp(b) = "), padic_print(e, ctx), flint_printf("\n"); + flint_printf("f = exp(a) exp(b) = "), padic_print(f, ctx), flint_printf("\n"); + flint_printf("g = exp(a + b) = "), padic_print(g, ctx), flint_printf("\n"); + abort(); + } + + padic_clear(a); + padic_clear(b); + padic_clear(c); + padic_clear(d); + padic_clear(e); + padic_clear(f); + padic_clear(g); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + +/** p > 2 ********************************************************************/ + + /* Check aliasing: a = exp(a) */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b; + int ans1, ans2; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + + padic_randtest(a, state, ctx); + + ans1 = padic_exp_rectangular(b, a, ctx); + ans2 = padic_exp_rectangular(a, a, ctx); + + result = ((ans1 == ans2) && (!ans1 || padic_equal(a, b))); + if (!result) + { + flint_printf("FAIL (aliasing):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("ans1 = %d\n", ans1); + flint_printf("ans2 = %d\n", ans2); + abort(); + } + + padic_clear(a); + padic_clear(b); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Functional equation: exp(a + b) == exp(a) exp(b) */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b, c, d, e, f, g; + int ans1, ans2, ans3; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + padic_init2(c, N); + padic_init2(d, N); + padic_init2(e, N); + padic_init2(f, N); + padic_init2(g, N); + + padic_randtest(a, state, ctx); + padic_randtest(b, state, ctx); + padic_add(c, a, b, ctx); + + ans1 = padic_exp_rectangular(d, a, ctx); + ans2 = padic_exp_rectangular(e, b, ctx); + padic_mul(f, d, e, ctx); + + ans3 = padic_exp_rectangular(g, c, ctx); + + result = (!ans1 || !ans2 || (ans3 && padic_equal(f, g))); + if (!result) + { + flint_printf("FAIL (functional equation):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("c = a + b = "), padic_print(c, ctx), flint_printf("\n"); + flint_printf("d = exp(a) = "), padic_print(d, ctx), flint_printf("\n"); + flint_printf("e = exp(b) = "), padic_print(e, ctx), flint_printf("\n"); + flint_printf("f = exp(a) exp(b) = "), padic_print(f, ctx), flint_printf("\n"); + flint_printf("g = exp(a + b) = "), padic_print(g, ctx), flint_printf("\n"); + abort(); + } + + padic_clear(a); + padic_clear(b); + padic_clear(c); + padic_clear(d); + padic_clear(e); + padic_clear(f); + padic_clear(g); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/padic/test/t-get_set_fmpz.c b/external/flint-2.4.3/padic/test/t-get_set_fmpz.c new file mode 100644 index 0000000..84b6ee6 --- /dev/null +++ b/external/flint-2.4.3/padic/test/t-get_set_fmpz.c @@ -0,0 +1,89 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "ulong_extras.h" +#include "padic.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("get_set_fmpz... "); + fflush(stdout); + + + + /* Check that Zp(ZZ(x)) == x. */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b; + fmpz_t c; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + fmpz_init(c); + + padic_randtest_int(a, state, ctx); + + padic_get_fmpz(c, a, ctx); + padic_set_fmpz(b, c, ctx); + + result = (padic_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("c = "), fmpz_print(c), flint_printf("\n"); + abort(); + } + + padic_clear(a); + padic_clear(b); + fmpz_clear(c); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/padic/test/t-get_set_mpq.c b/external/flint-2.4.3/padic/test/t-get_set_mpq.c new file mode 100644 index 0000000..3303b49 --- /dev/null +++ b/external/flint-2.4.3/padic/test/t-get_set_mpq.c @@ -0,0 +1,90 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "ulong_extras.h" +#include "long_extras.h" +#include "padic.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("get_set_mpq... "); + fflush(stdout); + + + + /* Check that Zp(QQ(x)) == x. */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b; + mpq_t c; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + mpq_init(c); + + padic_randtest(a, state, ctx); + + padic_get_mpq(c, a, ctx); + padic_set_mpq(b, c, ctx); + + result = (padic_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("c = "), padic_print(b, ctx), flint_printf("\n"); + gmp_printf("b = %Qd\n", b); + abort(); + } + + padic_clear(a); + padic_clear(b); + mpq_clear(c); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/padic/test/t-get_set_mpz.c b/external/flint-2.4.3/padic/test/t-get_set_mpz.c new file mode 100644 index 0000000..7750d5f --- /dev/null +++ b/external/flint-2.4.3/padic/test/t-get_set_mpz.c @@ -0,0 +1,93 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "padic.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("get_set_mpz... "); + fflush(stdout); + + + + /* Check that Zp(QQ(x)) == x. */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b; + mpz_t c; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + mpz_init(c); + + padic_randtest_int(a, state, ctx); + + padic_get_mpz(c, a, ctx); + padic_set_mpz(b, c, ctx); + + result = (padic_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + gmp_printf("c = %Zd\n", c); + abort(); + } + + padic_clear(a); + padic_clear(b); + mpz_clear(c); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/padic/test/t-get_str.c b/external/flint-2.4.3/padic/test/t-get_str.c new file mode 100644 index 0000000..11f5b7f --- /dev/null +++ b/external/flint-2.4.3/padic/test/t-get_str.c @@ -0,0 +1,89 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "ulong_extras.h" +#include "long_extras.h" +#include "padic.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("get_str... "); + fflush(stdout); + + + + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t x; + fmpq_t y; + + char *s, *t; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_TERSE); + + padic_init2(x, N); + fmpq_init(y); + + padic_randtest(x, state, ctx); + padic_get_fmpq(y, x, ctx); + + s = padic_get_str(NULL, x, ctx); + t = fmpq_get_str(NULL, 10, y); + + result = strcmp(s, t) == 0; + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("x = "), padic_print(x, ctx), flint_printf("\n"); + flint_printf("y = "), fmpq_print(y), flint_printf("\n"); + abort(); + } + + flint_free(s); + flint_free(t); + padic_clear(x); + fmpq_clear(y); + padic_ctx_clear(ctx); + fmpz_clear(p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/padic/test/t-inv.c b/external/flint-2.4.3/padic/test/t-inv.c new file mode 100644 index 0000000..fa9809e --- /dev/null +++ b/external/flint-2.4.3/padic/test/t-inv.c @@ -0,0 +1,238 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "long_extras.h" +#include "padic.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("inv... "); + fflush(stdout); + + + +/* PRIME p = 2 ***************************************************************/ + + /* Check aliasing: a = a^{-1} (mod p^N) */ + for (i = 0; i < 1000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, d; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(d, N); + + padic_randtest_not_zero(a, state, ctx); + + padic_inv(d, a, ctx); + padic_inv(a, a, ctx); + + result = (padic_equal(a, d)); + if (!result) + { + flint_printf("FAIL (aliasing):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("d = "), padic_print(d, ctx), flint_printf("\n"); + abort(); + } + + padic_clear(a); + padic_clear(d); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Check that correct only mod p^{N} */ + for (i = 0; i < 1000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b, d; + slong v; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + padic_init2(d, N); + + padic_randtest_not_zero(a, state, ctx); + v = padic_val(a); + + if (-v < N) /* Otherwise, no precision left */ + { + slong N2 = N - FLINT_ABS(v); + + padic_prec(d) = N2; + + padic_inv(b, a, ctx); + padic_mul(d, a, b, ctx); + + result = (padic_is_one(d)); + if (!result) + { + flint_printf("FAIL (a * a^{-1} == 1):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("d = "), padic_print(d, ctx), flint_printf("\n"); + abort(); + } + } + + padic_clear(a); + padic_clear(b); + padic_clear(d); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + +/* PRIME p > 2 ***************************************************************/ + + /* Check aliasing: a = a^{-1} (mod p^N) */ + for (i = 0; i < 1000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, d; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(d, N); + + padic_randtest_not_zero(a, state, ctx); + + padic_inv(d, a, ctx); + padic_inv(a, a, ctx); + + result = (padic_equal(a, d)); + if (!result) + { + flint_printf("FAIL (aliasing):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("d = "), padic_print(d, ctx), flint_printf("\n"); + abort(); + } + + padic_clear(a); + padic_clear(d); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Check that correct only mod p^{N} */ + for (i = 0; i < 1000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b, d; + slong v; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + padic_init2(d, N); + + padic_randtest_not_zero(a, state, ctx); + v = padic_val(a); + + if (-v < N) /* Otherwise, no precision left */ + { + slong N2 = N - FLINT_ABS(v); + + padic_prec(d) = N2; + + padic_inv(b, a, ctx); + padic_mul(d, a, b, ctx); + + result = (padic_is_one(d)); + if (!result) + { + flint_printf("FAIL (a * a^{-1} == 1):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("d = "), padic_print(d, ctx), flint_printf("\n"); + abort(); + } + } + + padic_clear(a); + padic_clear(b); + padic_clear(d); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/padic/test/t-log.c b/external/flint-2.4.3/padic/test/t-log.c new file mode 100644 index 0000000..3040001 --- /dev/null +++ b/external/flint-2.4.3/padic/test/t-log.c @@ -0,0 +1,359 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "ulong_extras.h" +#include "padic.h" + +/* + Set-up. Currently we only test the logarithm for positive values of N. + This is important as for negative N, exp(0) is 1, which is 0 mod p^N, + and then log(0) does not converge. + */ +static slong __rand_prec(flint_rand_t state, slong i) +{ + slong N; + + N = n_randint(state, PADIC_TEST_PREC_MAX) + 1; + + return N; +} + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("log... "); + fflush(stdout); + + + +/** p == 2 *******************************************************************/ + + /* Check aliasing: a = log(a) */ + for (i = 0; i < 1000; i++) + { + fmpz_t p = {WORD(2)}; + slong N; + padic_ctx_t ctx; + + padic_t a, b; + int ans1, ans2; + + N = __rand_prec(state, i); + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + + padic_randtest(a, state, ctx); + + padic_one(b); + padic_add(a, a, b, ctx); + + ans1 = padic_log(b, a, ctx); + ans2 = padic_log(a, a, ctx); + + result = (ans1 == ans2) && (!ans1 || padic_equal(a, b)); + if (!result) + { + flint_printf("FAIL (aliasing):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + abort(); + } + + padic_clear(a); + padic_clear(b); + + padic_ctx_clear(ctx); + } + + /* Check: log(a) + log(b) == log(a * b) */ + for (i = 0; i < 10000; i++) + { + fmpz_t p = {WORD(2)}; + slong N; + padic_ctx_t ctx; + + padic_t a, b, c, d, e, f, g; + int ans1, ans2, ans3; + + N = __rand_prec(state, i); + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + padic_init2(c, N); + padic_init2(d, N); + padic_init2(e, N); + padic_init2(f, N); + padic_init2(g, N); + + padic_randtest(a, state, ctx); + padic_randtest(b, state, ctx); + + padic_one(c); + padic_add(a, a, c, ctx); + padic_add(b, b, c, ctx); + + padic_mul(c, a, b, ctx); + + ans1 = padic_log(d, a, ctx); + ans2 = padic_log(e, b, ctx); + padic_add(f, d, e, ctx); + + ans3 = padic_log(g, c, ctx); + + result = (!ans1 || !ans2 || (ans3 && padic_equal(f, g))); + if (!result) + { + flint_printf("FAIL (functional equation):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("c = a * b = "), padic_print(c, ctx), flint_printf("\n"); + flint_printf("d = log(a) = "), padic_print(d, ctx), flint_printf("\n"); + flint_printf("e = log(b) = "), padic_print(e, ctx), flint_printf("\n"); + flint_printf("f = log(a) + log(b) = "), padic_print(f, ctx), flint_printf("\n"); + flint_printf("g = log(a * b) = "), padic_print(g, ctx), flint_printf("\n"); + abort(); + } + + padic_clear(a); + padic_clear(b); + padic_clear(c); + padic_clear(d); + padic_clear(e); + padic_clear(f); + padic_clear(g); + + padic_ctx_clear(ctx); + } + + /* Check: log(exp(x)) == x */ + for (i = 0; i < 10000; i++) + { + fmpz_t p = {WORD(2)}; + slong N; + padic_ctx_t ctx; + + padic_t a, b, c; + int ans1, ans2; + + N = __rand_prec(state, i); + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + padic_init2(c, N); + + padic_randtest(a, state, ctx); + + ans1 = padic_exp(b, a, ctx); + if (ans1) + ans2 = padic_log(c, b, ctx); + + result = !ans1 || (ans1 == ans2 && padic_equal(a, c)); + if (!result) + { + flint_printf("FAIL (log(exp(x)) == x):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("c = "), padic_print(c, ctx), flint_printf("\n"); + flint_printf("ans1 = %d\n", ans1); + flint_printf("ans2 = %d\n", ans2); + abort(); + } + + padic_clear(a); + padic_clear(b); + padic_clear(c); + + padic_ctx_clear(ctx); + } + +/** p > 2 ********************************************************************/ + + /* Check aliasing: a = log(a) */ + for (i = 0; i < 1000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b; + int ans1, ans2; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = __rand_prec(state, i); + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + + padic_randtest(a, state, ctx); + + padic_one(b); + padic_add(a, a, b, ctx); + + ans1 = padic_log(b, a, ctx); + ans2 = padic_log(a, a, ctx); + + result = (ans1 == ans2) && (!ans1 || padic_equal(a, b)); + if (!result) + { + flint_printf("FAIL (aliasing):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + abort(); + } + + padic_clear(a); + padic_clear(b); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Check: log(a) + log(b) == log(a * b) */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b, c, d, e, f, g; + int ans1, ans2, ans3; + +/* fmpz_init_set_ui(p, n_randtest_prime(state, 0)); */ + fmpz_init_set_ui(p, n_randprime(state, 5, 1)); + N = __rand_prec(state, i); + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + padic_init2(c, N); + padic_init2(d, N); + padic_init2(e, N); + padic_init2(f, N); + padic_init2(g, N); + + padic_randtest(a, state, ctx); + padic_randtest(b, state, ctx); + + padic_one(c); + padic_add(a, a, c, ctx); + + padic_one(c); + padic_add(b, b, c, ctx); + + padic_mul(c, a, b, ctx); + + ans1 = padic_log(d, a, ctx); + ans2 = padic_log(e, b, ctx); + padic_add(f, d, e, ctx); + + ans3 = padic_log(g, c, ctx); + + result = (!ans1 || !ans2 || (ans3 && padic_equal(f, g))); + if (!result) + { + flint_printf("FAIL (functional equation):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("c = a * b = "), padic_print(c, ctx), flint_printf("\n"); + flint_printf("d = log(a) = "), padic_print(d, ctx), flint_printf("\n"); + flint_printf("e = log(b) = "), padic_print(e, ctx), flint_printf("\n"); + flint_printf("f = log(a) + log(b) = "), padic_print(f, ctx), flint_printf("\n"); + flint_printf("g = log(a * b) = "), padic_print(g, ctx), flint_printf("\n"); + flint_printf("ans1 = %d\n", ans1); + flint_printf("ans2 = %d\n", ans2); + flint_printf("ans3 = %d\n", ans3); + abort(); + } + + padic_clear(a); + padic_clear(b); + padic_clear(c); + padic_clear(d); + padic_clear(e); + padic_clear(f); + padic_clear(g); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Check: log(exp(x)) == x */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b, c; + int ans1, ans2; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = __rand_prec(state, i); + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + padic_init2(c, N); + + padic_randtest(a, state, ctx); + + ans1 = padic_exp(b, a, ctx); + if (ans1) + ans2 = padic_log(c, b, ctx); + + result = !ans1 || (ans1 == ans2 && padic_equal(a, c)); + if (!result) + { + flint_printf("FAIL (log(exp(x)) == x):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("c = "), padic_print(c, ctx), flint_printf("\n"); + flint_printf("ans1 = %d\n", ans1); + flint_printf("ans2 = %d\n", ans2); + abort(); + } + + padic_clear(a); + padic_clear(b); + padic_clear(c); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/padic/test/t-log_balanced.c b/external/flint-2.4.3/padic/test/t-log_balanced.c new file mode 100644 index 0000000..a4534aa --- /dev/null +++ b/external/flint-2.4.3/padic/test/t-log_balanced.c @@ -0,0 +1,360 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "ulong_extras.h" +#include "padic.h" + +/* + Set-up. Currently we only test the logarithm for positive values of N. + This is important as for negative N, exp(0) is 1, which is 0 mod p^N, + and then log(0) does not converge. + */ +static slong __rand_prec(flint_rand_t state, slong i) +{ + slong N; + + N = n_randint(state, PADIC_TEST_PREC_MAX) + 1; + + return N; +} + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("log_balanced... "); + fflush(stdout); + + + +/** p == 2 *******************************************************************/ + + /* Check aliasing: a = log(a) */ + for (i = 0; i < 1000; i++) + { + fmpz_t p = {WORD(2)}; + slong N; + padic_ctx_t ctx; + + padic_t a, b; + int ans1, ans2; + + N = __rand_prec(state, i); + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + + padic_randtest(a, state, ctx); + + padic_one(b); + padic_add(a, a, b, ctx); + + ans1 = padic_log_balanced(b, a, ctx); + ans2 = padic_log_balanced(a, a, ctx); + + result = (ans1 == ans2) && (!ans1 || padic_equal(a, b)); + if (!result) + { + flint_printf("FAIL (aliasing):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + abort(); + } + + padic_clear(a); + padic_clear(b); + + padic_ctx_clear(ctx); + } + + /* Check: log(a) + log(b) == log(a * b) */ + for (i = 0; i < 10000; i++) + { + fmpz_t p = {WORD(2)}; + slong N; + padic_ctx_t ctx; + + padic_t a, b, c, d, e, f, g; + int ans1, ans2, ans3; + + N = __rand_prec(state, i); + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + padic_init2(c, N); + padic_init2(d, N); + padic_init2(e, N); + padic_init2(f, N); + padic_init2(g, N); + + padic_randtest(a, state, ctx); + padic_randtest(b, state, ctx); + + padic_one(c); + padic_add(a, a, c, ctx); + padic_add(b, b, c, ctx); + + padic_mul(c, a, b, ctx); + + ans1 = padic_log_balanced(d, a, ctx); + ans2 = padic_log_balanced(e, b, ctx); + padic_add(f, d, e, ctx); + + ans3 = padic_log_balanced(g, c, ctx); + + result = (!ans1 || !ans2 || (ans3 && padic_equal(f, g))); + if (!result) + { + flint_printf("FAIL (functional equation):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("c = a * b = "), padic_print(c, ctx), flint_printf("\n"); + flint_printf("d = log(a) = "), padic_print(d, ctx), flint_printf("\n"); + flint_printf("e = log(b) = "), padic_print(e, ctx), flint_printf("\n"); + flint_printf("f = log(a) + log(b) = "), padic_print(f, ctx), flint_printf("\n"); + flint_printf("g = log(a * b) = "), padic_print(g, ctx), flint_printf("\n"); + abort(); + } + + padic_clear(a); + padic_clear(b); + padic_clear(c); + padic_clear(d); + padic_clear(e); + padic_clear(f); + padic_clear(g); + + padic_ctx_clear(ctx); + } + + /* Check: log(exp(x)) == x */ + for (i = 0; i < 10000; i++) + { + fmpz_t p = {WORD(2)}; + slong N; + padic_ctx_t ctx; + + padic_t a, b, c; + int ans1, ans2; + + N = __rand_prec(state, i); + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + padic_init2(c, N); + + padic_randtest(a, state, ctx); + + ans1 = padic_exp(b, a, ctx); + if (ans1) + ans2 = padic_log_balanced(c, b, ctx); + + result = !ans1 || (ans1 == ans2 && padic_equal(a, c)); + if (!result) + { + flint_printf("FAIL (log(exp(x)) == x):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("c = "), padic_print(c, ctx), flint_printf("\n"); + flint_printf("ans1 = %d\n", ans1); + flint_printf("ans2 = %d\n", ans2); + abort(); + } + + padic_clear(a); + padic_clear(b); + padic_clear(c); + + padic_ctx_clear(ctx); + } + +/** p > 2 ********************************************************************/ + + /* Check aliasing: a = log(a) */ + for (i = 0; i < 1000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b; + int ans1, ans2; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = __rand_prec(state, i); + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + + padic_randtest(a, state, ctx); + + padic_one(b); + padic_add(a, a, b, ctx); + + ans1 = padic_log_balanced(b, a, ctx); + ans2 = padic_log_balanced(a, a, ctx); + + result = (ans1 == ans2) && (!ans1 || padic_equal(a, b)); + if (!result) + { + flint_printf("FAIL (aliasing):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + abort(); + } + + padic_clear(a); + padic_clear(b); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Check: log(a) + log(b) == log(a * b) */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b, c, d, e, f, g; + int ans1, ans2, ans3; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); +/* fmpz_init_set_ui(p, n_randprime(state, 5, 1));*/ + N = __rand_prec(state, i); + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + padic_init2(c, N); + padic_init2(d, N); + padic_init2(e, N); + padic_init2(f, N); + padic_init2(g, N); + + padic_randtest(a, state, ctx); + padic_randtest(b, state, ctx); + + padic_one(c); + padic_add(a, a, c, ctx); + + padic_one(c); + padic_add(b, b, c, ctx); + + padic_mul(c, a, b, ctx); + + ans1 = padic_log_balanced(d, a, ctx); + ans2 = padic_log_balanced(e, b, ctx); + padic_add(f, d, e, ctx); + + ans3 = padic_log_balanced(g, c, ctx); + + result = (!ans1 || !ans2 || (ans3 && padic_equal(f, g))); + if (!result) + { + flint_printf("FAIL (functional equation):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("c = a * b = "), padic_print(c, ctx), flint_printf("\n"); + flint_printf("d = log(a) = "), padic_print(d, ctx), flint_printf("\n"); + flint_printf("e = log(b) = "), padic_print(e, ctx), flint_printf("\n"); + flint_printf("f = log(a) + log(b) = "), padic_print(f, ctx), flint_printf("\n"); + flint_printf("g = log(a * b) = "), padic_print(g, ctx), flint_printf("\n"); + flint_printf("ans1 = %d\n", ans1); + flint_printf("ans2 = %d\n", ans2); + flint_printf("ans3 = %d\n", ans3); + abort(); + } + + padic_clear(a); + padic_clear(b); + padic_clear(c); + padic_clear(d); + padic_clear(e); + padic_clear(f); + padic_clear(g); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Check: log(exp(x)) == x */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b, c; + int ans1, ans2; + +/* fmpz_init_set_ui(p, n_randtest_prime(state, 0)); */ + fmpz_init_set_ui(p, n_randprime(state, 5, 1)); + N = __rand_prec(state, i); + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + padic_init2(c, N); + + padic_randtest(a, state, ctx); + + ans1 = padic_exp(b, a, ctx); + if (ans1) + ans2 = padic_log_balanced(c, b, ctx); + + result = !ans1 || (ans1 == ans2 && padic_equal(a, c)); + if (!result) + { + flint_printf("FAIL (log(exp(x)) == x):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("c = "), padic_print(c, ctx), flint_printf("\n"); + flint_printf("ans1 = %d\n", ans1); + flint_printf("ans2 = %d\n", ans2); + abort(); + } + + padic_clear(a); + padic_clear(b); + padic_clear(c); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/padic/test/t-log_rectangular.c b/external/flint-2.4.3/padic/test/t-log_rectangular.c new file mode 100644 index 0000000..455f104 --- /dev/null +++ b/external/flint-2.4.3/padic/test/t-log_rectangular.c @@ -0,0 +1,359 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "ulong_extras.h" +#include "padic.h" + +/* + Set-up. Currently we only test the logarithm for positive values of N. + This is important as for negative N, exp(0) is 1, which is 0 mod p^N, + and then log(0) does not converge. + */ +static slong __rand_prec(flint_rand_t state, slong i) +{ + slong N; + + N = n_randint(state, PADIC_TEST_PREC_MAX) + 1; + + return N; +} + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("log_rectangular... "); + fflush(stdout); + + + +/** p == 2 *******************************************************************/ + + /* Check aliasing: a = log(a) */ + for (i = 0; i < 1000; i++) + { + fmpz_t p = {WORD(2)}; + slong N; + padic_ctx_t ctx; + + padic_t a, b; + int ans1, ans2; + + N = __rand_prec(state, i); + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + + padic_randtest(a, state, ctx); + + padic_one(b); + padic_add(a, a, b, ctx); + + ans1 = padic_log_rectangular(b, a, ctx); + ans2 = padic_log_rectangular(a, a, ctx); + + result = (ans1 == ans2) && (!ans1 || padic_equal(a, b)); + if (!result) + { + flint_printf("FAIL (aliasing):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + abort(); + } + + padic_clear(a); + padic_clear(b); + + padic_ctx_clear(ctx); + } + + /* Check: log(a) + log(b) == log(a * b) */ + for (i = 0; i < 10000; i++) + { + fmpz_t p = {WORD(2)}; + slong N; + padic_ctx_t ctx; + + padic_t a, b, c, d, e, f, g; + int ans1, ans2, ans3; + + N = __rand_prec(state, i); + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + padic_init2(c, N); + padic_init2(d, N); + padic_init2(e, N); + padic_init2(f, N); + padic_init2(g, N); + + padic_randtest(a, state, ctx); + padic_randtest(b, state, ctx); + + padic_one(c); + padic_add(a, a, c, ctx); + padic_add(b, b, c, ctx); + + padic_mul(c, a, b, ctx); + + ans1 = padic_log_rectangular(d, a, ctx); + ans2 = padic_log_rectangular(e, b, ctx); + padic_add(f, d, e, ctx); + + ans3 = padic_log_rectangular(g, c, ctx); + + result = (!ans1 || !ans2 || (ans3 && padic_equal(f, g))); + if (!result) + { + flint_printf("FAIL (functional equation):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("c = a * b = "), padic_print(c, ctx), flint_printf("\n"); + flint_printf("d = log(a) = "), padic_print(d, ctx), flint_printf("\n"); + flint_printf("e = log(b) = "), padic_print(e, ctx), flint_printf("\n"); + flint_printf("f = log(a) + log(b) = "), padic_print(f, ctx), flint_printf("\n"); + flint_printf("g = log(a * b) = "), padic_print(g, ctx), flint_printf("\n"); + abort(); + } + + padic_clear(a); + padic_clear(b); + padic_clear(c); + padic_clear(d); + padic_clear(e); + padic_clear(f); + padic_clear(g); + + padic_ctx_clear(ctx); + } + + /* Check: log(exp(x)) == x */ + for (i = 0; i < 10000; i++) + { + fmpz_t p = {WORD(2)}; + slong N; + padic_ctx_t ctx; + + padic_t a, b, c; + int ans1, ans2; + + N = __rand_prec(state, i); + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + padic_init2(c, N); + + padic_randtest(a, state, ctx); + + ans1 = padic_exp(b, a, ctx); + if (ans1) + ans2 = padic_log_rectangular(c, b, ctx); + + result = !ans1 || (ans1 == ans2 && padic_equal(a, c)); + if (!result) + { + flint_printf("FAIL (log(exp(x)) == x):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("c = "), padic_print(c, ctx), flint_printf("\n"); + flint_printf("ans1 = %d\n", ans1); + flint_printf("ans2 = %d\n", ans2); + abort(); + } + + padic_clear(a); + padic_clear(b); + padic_clear(c); + + padic_ctx_clear(ctx); + } + +/** p > 2 ********************************************************************/ + + /* Check aliasing: a = log(a) */ + for (i = 0; i < 1000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b; + int ans1, ans2; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = __rand_prec(state, i); + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + + padic_randtest(a, state, ctx); + + padic_one(b); + padic_add(a, a, b, ctx); + + ans1 = padic_log_rectangular(b, a, ctx); + ans2 = padic_log_rectangular(a, a, ctx); + + result = (ans1 == ans2) && (!ans1 || padic_equal(a, b)); + if (!result) + { + flint_printf("FAIL (aliasing):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + abort(); + } + + padic_clear(a); + padic_clear(b); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Check: log(a) + log(b) == log(a * b) */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b, c, d, e, f, g; + int ans1, ans2, ans3; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = __rand_prec(state, i); + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + padic_init2(c, N); + padic_init2(d, N); + padic_init2(e, N); + padic_init2(f, N); + padic_init2(g, N); + + padic_randtest(a, state, ctx); + padic_randtest(b, state, ctx); + + padic_one(c); + padic_add(a, a, c, ctx); + + padic_one(c); + padic_add(b, b, c, ctx); + + padic_mul(c, a, b, ctx); + + ans1 = padic_log_rectangular(d, a, ctx); + ans2 = padic_log_rectangular(e, b, ctx); + padic_add(f, d, e, ctx); + + ans3 = padic_log_rectangular(g, c, ctx); + + result = (!ans1 || !ans2 || (ans3 && padic_equal(f, g))); + if (!result) + { + flint_printf("FAIL (functional equation):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("c = a * b = "), padic_print(c, ctx), flint_printf("\n"); + flint_printf("d = log(a) = "), padic_print(d, ctx), flint_printf("\n"); + flint_printf("e = log(b) = "), padic_print(e, ctx), flint_printf("\n"); + flint_printf("f = log(a) + log(b) = "), padic_print(f, ctx), flint_printf("\n"); + flint_printf("g = log(a * b) = "), padic_print(g, ctx), flint_printf("\n"); + flint_printf("ans1 = %d\n", ans1); + flint_printf("ans2 = %d\n", ans2); + flint_printf("ans3 = %d\n", ans3); + abort(); + } + + padic_clear(a); + padic_clear(b); + padic_clear(c); + padic_clear(d); + padic_clear(e); + padic_clear(f); + padic_clear(g); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Check: log(exp(x)) == x */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b, c; + int ans1, ans2; + +/* fmpz_init_set_ui(p, n_randtest_prime(state, 0)); */ + fmpz_init_set_ui(p, n_randprime(state, 5, 1)); + N = __rand_prec(state, i); + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + padic_init2(c, N); + + padic_randtest(a, state, ctx); + + ans1 = padic_exp(b, a, ctx); + if (ans1) + ans2 = padic_log_rectangular(c, b, ctx); + + result = !ans1 || (ans1 == ans2 && padic_equal(a, c)); + if (!result) + { + flint_printf("FAIL (log(exp(x)) == x):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("c = "), padic_print(c, ctx), flint_printf("\n"); + flint_printf("ans1 = %d\n", ans1); + flint_printf("ans2 = %d\n", ans2); + abort(); + } + + padic_clear(a); + padic_clear(b); + padic_clear(c); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/padic/test/t-log_satoh.c b/external/flint-2.4.3/padic/test/t-log_satoh.c new file mode 100644 index 0000000..5080425 --- /dev/null +++ b/external/flint-2.4.3/padic/test/t-log_satoh.c @@ -0,0 +1,360 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "ulong_extras.h" +#include "padic.h" + +/* + Set-up. Currently we only test the logarithm for positive values of N. + This is important as for negative N, exp(0) is 1, which is 0 mod p^N, + and then log(0) does not converge. + */ +static slong __rand_prec(flint_rand_t state, slong i) +{ + slong N; + + N = n_randint(state, PADIC_TEST_PREC_MAX) + 1; + + return N; +} + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("log_satoh... "); + fflush(stdout); + + + +/** p == 2 *******************************************************************/ + + /* Check aliasing: a = log(a) */ + for (i = 0; i < 1000; i++) + { + fmpz_t p = {WORD(2)}; + slong N; + padic_ctx_t ctx; + + padic_t a, b; + int ans1, ans2; + + N = __rand_prec(state, i); + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + + padic_randtest(a, state, ctx); + + padic_one(b); + padic_add(a, a, b, ctx); + + ans1 = padic_log_satoh(b, a, ctx); + ans2 = padic_log_satoh(a, a, ctx); + + result = (ans1 == ans2) && (!ans1 || padic_equal(a, b)); + if (!result) + { + flint_printf("FAIL (aliasing):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + abort(); + } + + padic_clear(a); + padic_clear(b); + + padic_ctx_clear(ctx); + } + + /* Check: log(a) + log(b) == log(a * b) */ + for (i = 0; i < 1000; i++) + { + fmpz_t p = {WORD(2)}; + slong N; + padic_ctx_t ctx; + + padic_t a, b, c, d, e, f, g; + int ans1, ans2, ans3; + + N = __rand_prec(state, i); + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + padic_init2(c, N); + padic_init2(d, N); + padic_init2(e, N); + padic_init2(f, N); + padic_init2(g, N); + + padic_randtest(a, state, ctx); + padic_randtest(b, state, ctx); + + padic_one(c); + padic_add(a, a, c, ctx); + padic_add(b, b, c, ctx); + + padic_mul(c, a, b, ctx); + + ans1 = padic_log_satoh(d, a, ctx); + ans2 = padic_log_satoh(e, b, ctx); + padic_add(f, d, e, ctx); + + ans3 = padic_log_satoh(g, c, ctx); + + result = (!ans1 || !ans2 || (ans3 && padic_equal(f, g))); + if (!result) + { + flint_printf("FAIL (functional equation):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("c = a * b = "), padic_print(c, ctx), flint_printf("\n"); + flint_printf("d = log(a) = "), padic_print(d, ctx), flint_printf("\n"); + flint_printf("e = log(b) = "), padic_print(e, ctx), flint_printf("\n"); + flint_printf("f = log(a) + log(b) = "), padic_print(f, ctx), flint_printf("\n"); + flint_printf("g = log(a * b) = "), padic_print(g, ctx), flint_printf("\n"); + abort(); + } + + padic_clear(a); + padic_clear(b); + padic_clear(c); + padic_clear(d); + padic_clear(e); + padic_clear(f); + padic_clear(g); + + padic_ctx_clear(ctx); + } + + /* Check: log(exp(x)) == x */ + for (i = 0; i < 1000; i++) + { + fmpz_t p = {WORD(2)}; + slong N; + padic_ctx_t ctx; + + padic_t a, b, c; + int ans1, ans2; + + N = __rand_prec(state, i); + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + padic_init2(c, N); + + padic_randtest(a, state, ctx); + + ans1 = padic_exp(b, a, ctx); + if (ans1) + ans2 = padic_log_satoh(c, b, ctx); + + result = !ans1 || (ans1 == ans2 && padic_equal(a, c)); + if (!result) + { + flint_printf("FAIL (log(exp(x)) == x):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("c = "), padic_print(c, ctx), flint_printf("\n"); + flint_printf("ans1 = %d\n", ans1); + flint_printf("ans2 = %d\n", ans2); + abort(); + } + + padic_clear(a); + padic_clear(b); + padic_clear(c); + + padic_ctx_clear(ctx); + } + +/** p > 2 ********************************************************************/ + + /* Check aliasing: a = log(a) */ + for (i = 0; i < 1000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b; + int ans1, ans2; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = __rand_prec(state, i); + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + + padic_randtest(a, state, ctx); + + padic_one(b); + padic_add(a, a, b, ctx); + + ans1 = padic_log_satoh(b, a, ctx); + ans2 = padic_log_satoh(a, a, ctx); + + result = (ans1 == ans2) && (!ans1 || padic_equal(a, b)); + if (!result) + { + flint_printf("FAIL (aliasing):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + abort(); + } + + padic_clear(a); + padic_clear(b); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Check: log(a) + log(b) == log(a * b) */ + for (i = 0; i < 1000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b, c, d, e, f, g; + int ans1, ans2, ans3; + +/* fmpz_init_set_ui(p, n_randtest_prime(state, 0)); */ + fmpz_init_set_ui(p, n_randprime(state, 5, 1)); + N = __rand_prec(state, i); + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + padic_init2(c, N); + padic_init2(d, N); + padic_init2(e, N); + padic_init2(f, N); + padic_init2(g, N); + + padic_randtest(a, state, ctx); + padic_randtest(b, state, ctx); + + padic_one(c); + padic_add(a, a, c, ctx); + + padic_one(c); + padic_add(b, b, c, ctx); + + padic_mul(c, a, b, ctx); + + ans1 = padic_log_satoh(d, a, ctx); + ans2 = padic_log_satoh(e, b, ctx); + padic_add(f, d, e, ctx); + + ans3 = padic_log_satoh(g, c, ctx); + + result = (!ans1 || !ans2 || (ans3 && padic_equal(f, g))); + if (!result) + { + flint_printf("FAIL (functional equation):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("c = a * b = "), padic_print(c, ctx), flint_printf("\n"); + flint_printf("d = log(a) = "), padic_print(d, ctx), flint_printf("\n"); + flint_printf("e = log(b) = "), padic_print(e, ctx), flint_printf("\n"); + flint_printf("f = log(a) + log(b) = "), padic_print(f, ctx), flint_printf("\n"); + flint_printf("g = log(a * b) = "), padic_print(g, ctx), flint_printf("\n"); + flint_printf("ans1 = %d\n", ans1); + flint_printf("ans2 = %d\n", ans2); + flint_printf("ans3 = %d\n", ans3); + abort(); + } + + padic_clear(a); + padic_clear(b); + padic_clear(c); + padic_clear(d); + padic_clear(e); + padic_clear(f); + padic_clear(g); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Check: log(exp(x)) == x */ + for (i = 0; i < 1000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b, c; + int ans1, ans2; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + fmpz_init_set_ui(p, n_randprime(state, 5, 1)); + N = __rand_prec(state, i); + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + padic_init2(c, N); + + padic_randtest(a, state, ctx); + + ans1 = padic_exp(b, a, ctx); + if (ans1) + ans2 = padic_log_satoh(c, b, ctx); + + result = !ans1 || (ans1 == ans2 && padic_equal(a, c)); + if (!result) + { + flint_printf("FAIL (log(exp(x)) == x):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("c = "), padic_print(c, ctx), flint_printf("\n"); + flint_printf("ans1 = %d\n", ans1); + flint_printf("ans2 = %d\n", ans2); + abort(); + } + + padic_clear(a); + padic_clear(b); + padic_clear(c); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/padic/test/t-mul.c b/external/flint-2.4.3/padic/test/t-mul.c new file mode 100644 index 0000000..8f69ecf --- /dev/null +++ b/external/flint-2.4.3/padic/test/t-mul.c @@ -0,0 +1,311 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "ulong_extras.h" +#include "long_extras.h" +#include "padic.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("mul... "); + fflush(stdout); + + + + /* Check aliasing: a = a * b (mod p^N) */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b, d; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + padic_init2(d, N); + + padic_randtest(a, state, ctx); + padic_randtest(b, state, ctx); + + padic_mul(d, a, b, ctx); + padic_mul(a, a, b, ctx); + + result = (padic_equal(a, d)); + if (!result) + { + flint_printf("FAIL (alias a = a*b):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("d = "), padic_print(d, ctx), flint_printf("\n"); + abort(); + } + + padic_clear(a); + padic_clear(b); + padic_clear(d); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Check aliasing: b = a * b (mod p^N) */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b, d; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + padic_init2(d, N); + + padic_randtest(a, state, ctx); + padic_randtest(b, state, ctx); + + padic_mul(d, a, b, ctx); + padic_mul(b, a, b, ctx); + + result = (padic_equal(b, d)); + if (!result) + { + flint_printf("FAIL (alias b = a*b):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("d = "), padic_print(d, ctx), flint_printf("\n"); + abort(); + } + + padic_clear(a); + padic_clear(b); + padic_clear(d); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Check aliasing: a = a * a (mod p^N) */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, d; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(d, N); + + padic_randtest(a, state, ctx); + + padic_mul(d, a, a, ctx); + padic_mul(a, a, a, ctx); + + result = (padic_equal(a, d)); + if (!result) + { + flint_printf("FAIL (alias a = a*a):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("d = "), padic_print(d, ctx), flint_printf("\n"); + abort(); + } + + padic_clear(a); + padic_clear(d); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Check that a * b == b * a (mod p^N) */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b, c, d; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + padic_init2(c, N); + padic_init2(d, N); + + padic_randtest(a, state, ctx); + padic_randtest(b, state, ctx); + + padic_mul(c, a, b, ctx); + padic_mul(d, b, a, ctx); + + result = (padic_equal(c, d)); + if (!result) + { + flint_printf("FAIL (a*b = b*a):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("c = "), padic_print(c, ctx), flint_printf("\n"); + flint_printf("d = "), padic_print(d, ctx), flint_printf("\n"); + abort(); + } + + padic_clear(a); + padic_clear(b); + padic_clear(c); + padic_clear(d); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Check that (a * b) * c == a * (b * c) (mod p^N) */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b, c, lhs1, lhs2, rhs1, rhs2; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + padic_init2(c, N); + + padic_randtest(a, state, ctx); + padic_randtest(b, state, ctx); + padic_randtest(c, state, ctx); + + padic_init2(lhs1, N - padic_val(c)); + padic_init2(lhs2, N); + padic_init2(rhs1, N - padic_val(a)); + padic_init2(rhs2, N); + + padic_mul(lhs1, a, b, ctx); + padic_mul(lhs2, lhs1, c, ctx); + padic_mul(rhs1, b, c, ctx); + padic_mul(rhs2, a, rhs1, ctx); + + result = (padic_equal(lhs2, rhs2)); + if (!result) + { + flint_printf("FAIL ((a*b)*c = a*(b*c) mod p^N):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("c = "), padic_print(c, ctx), flint_printf("\n"); + flint_printf("lhs1 = "), padic_print(lhs1, ctx), flint_printf("\n"); + flint_printf("lhs2 = "), padic_print(lhs2, ctx), flint_printf("\n"); + flint_printf("rhs1 = "), padic_print(rhs1, ctx), flint_printf("\n"); + flint_printf("rhs2 = "), padic_print(rhs2, ctx), flint_printf("\n"); + abort(); + } + + padic_clear(a); + padic_clear(b); + padic_clear(c); + padic_clear(lhs1); + padic_clear(lhs2); + padic_clear(rhs1); + padic_clear(rhs2); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Check that a * 1 == a */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b, c; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, 1); + padic_init2(c, N); + + padic_randtest(a, state, ctx); + + padic_one(b); + padic_mul(c, a, b, ctx); + + result = (padic_equal(a, c)); + if (!result) + { + flint_printf("FAIL (a*1 = a):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("c = "), padic_print(c, ctx), flint_printf("\n"); + abort(); + } + + padic_clear(a); + padic_clear(b); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/padic/test/t-neg.c b/external/flint-2.4.3/padic/test/t-neg.c new file mode 100644 index 0000000..473ecc3 --- /dev/null +++ b/external/flint-2.4.3/padic/test/t-neg.c @@ -0,0 +1,161 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "ulong_extras.h" +#include "long_extras.h" +#include "padic.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("neg... "); + fflush(stdout); + + + + /* Check aliasing: a = - a */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, d; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(d, N); + + padic_randtest(a, state, ctx); + + padic_neg(d, a, ctx); + padic_neg(a, a, ctx); + + result = (padic_equal(a, d)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("d = "), padic_print(d, ctx), flint_printf("\n"); + abort(); + } + + padic_clear(a); + padic_clear(d); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Check that - (- a) == a */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, d; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(d, N); + + padic_randtest(a, state, ctx); + + padic_neg(d, a, ctx); + padic_neg(d, d, ctx); + + result = (padic_equal(a, d)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("d = "), padic_print(d, ctx), flint_printf("\n"); + abort(); + } + + padic_clear(a); + padic_clear(d); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Check that a + (-a) == 0 */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + + padic_randtest(a, state, ctx); + + padic_neg(b, a, ctx); + padic_add(b, a, b, ctx); + + result = (padic_is_zero(b)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + abort(); + } + + padic_clear(a); + padic_clear(b); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/padic/test/t-pow_si.c b/external/flint-2.4.3/padic/test/t-pow_si.c new file mode 100644 index 0000000..9c726c1 --- /dev/null +++ b/external/flint-2.4.3/padic/test/t-pow_si.c @@ -0,0 +1,257 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "padic.h" +#include "long_extras.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("pow_si... "); + fflush(stdout); + + + + /* Check aliasing */ + for (i = 0; i < 2000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b, c; + slong e; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + padic_init2(c, N); + + padic_randtest(a, state, ctx); + padic_set(b, a, ctx); + + e = z_randint(state, 20); + + padic_pow_si(c, b, e, ctx); + padic_pow_si(b, b, e, ctx); + + result = (padic_equal(b, c)); + if (!result) + { + flint_printf("FAIL (aliasing):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("c = "), padic_print(c, ctx), flint_printf("\n"); + flint_printf("e = %wd\n", e); + abort(); + } + + padic_clear(a); + padic_clear(b); + padic_clear(c); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Compare with multiplication for e >= 0 and val(a) >= 0 */ + for (i = 0; i < 2000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b, c; + slong j, e; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + padic_init2(c, N); + + padic_randtest_int(a, state, ctx); + padic_val(a) = FLINT_ABS(padic_val(a)); + + e = n_randint(state, 50); + + padic_pow_si(b, a, e, ctx); + padic_one(c); + for (j = 0; j < e; j++) + padic_mul(c, c, a, ctx); + + result = (padic_equal(b, c)); + if (!result) + { + flint_printf("FAIL (cmp with multiplication):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("c = "), padic_print(c, ctx), flint_printf("\n"); + flint_printf("e = %wd\n", e); + abort(); + } + + padic_clear(a); + padic_clear(b); + padic_clear(c); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Compare with fmpq, check precision */ + for (i = 0; i < 2000; i++) + { + fmpz_t p; + slong N, N2; + padic_ctx_t ctx; + + padic_t a, b, c; + fmpq_t s, t; + slong e; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + padic_init2(c, N); + fmpq_init(s); + fmpq_init(t); + + padic_randtest(a, state, ctx); + e = n_randint(state, 50) + 1; + + N2 = N + (e - 1) * padic_val(a); + + padic_prec(b) = N2; + padic_prec(c) = N2; + padic_pow_si(b, a, e, ctx); + + padic_get_fmpq(s, a, ctx); + fmpq_pow_si(t, s, e); + padic_set_fmpq(c, t, ctx); + + result = (padic_equal(b, c)); + if (!result) + { + flint_printf("FAIL (cmp with fmpq):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("c = "), padic_print(c, ctx), flint_printf("\n"); + flint_printf("s = "), fmpq_print(s), flint_printf("\n"); + flint_printf("t = "), fmpq_print(t), flint_printf("\n"); + flint_printf("e = %wd\n", e); + abort(); + } + + padic_clear(a); + padic_clear(b); + padic_clear(c); + fmpq_clear(s); + fmpq_clear(t); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Check precision */ + for (i = 0; i < 2000; i++) + { + fmpz_t p; + slong N_lo, N_hi, N_res; + padic_ctx_t ctx; + + padic_t a, b, c, d, t; + slong e; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N_lo = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + N_hi = N_lo + n_randint(state, 20); + padic_ctx_init(ctx, p, FLINT_MAX(0, N_lo-10), FLINT_MAX(0, N_hi+10), PADIC_SERIES); + + padic_init2(a, N_hi); + padic_init2(b, N_hi); + padic_init2(t, N_lo); + + padic_randtest(a, state, ctx); + padic_randtest(b, state, ctx); + padic_sub(t, a, b, ctx); + padic_add(b, b, t, ctx); + e = n_randint(state, 50) + 1; + + N_res = N_lo + (e - 1) * FLINT_MIN(padic_val(a), padic_val(b)); + + padic_init2(c, N_res); + padic_init2(d, N_res); + + padic_pow_si(c, a, e, ctx); + padic_pow_si(d, b, e, ctx); + + result = (padic_equal(c, d)); + if (!result) + { + flint_printf("FAIL (cmp with fmpq):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("c = "), padic_print(c, ctx), flint_printf("\n"); + flint_printf("d = "), padic_print(d, ctx), flint_printf("\n"); + flint_printf("e = %wd\n", e); + flint_printf("N_lo = %wd\n", N_lo); + flint_printf("N_hi = %wd\n", N_hi); + flint_printf("N_res = %wd\n", N_res); + abort(); + } + + padic_clear(a); + padic_clear(b); + padic_clear(c); + padic_clear(d); + padic_clear(t); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/padic/test/t-randtest.c b/external/flint-2.4.3/padic/test/t-randtest.c new file mode 100644 index 0000000..6307f8f --- /dev/null +++ b/external/flint-2.4.3/padic/test/t-randtest.c @@ -0,0 +1,142 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "ulong_extras.h" +#include "long_extras.h" +#include "padic.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("randtest... "); + fflush(stdout); + + + + /* Check randtest() */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong lo, hi, N; + padic_ctx_t ctx; + + padic_t a; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_randtest(a, state, ctx); + + if (N > 0) + { + lo = -((N + 9) / 10); + hi = N; + } + else if (N < 0) + { + lo = N - ((-N + 9) / 10); + hi = N; + } + else + { + lo = -10; + hi = 0; + } + + result = padic_is_zero(a) || (lo <= padic_val(a) && padic_val(a) < hi); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("N = %wd\n", N); + abort(); + } + + padic_clear(a); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Check randtest_not_zero() */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong lo, hi, N; + padic_ctx_t ctx; + + padic_t a; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_randtest_not_zero(a, state, ctx); + + if (N > 0) + { + lo = -((N + 9) / 10); + hi = N; + } + else if (N < 0) + { + lo = N - ((-N + 9) / 10); + hi = N; + } + else + { + lo = -10; + hi = 0; + } + + result = !padic_is_zero(a) && (lo <= padic_val(a) && padic_val(a) < hi); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("N = %wd\n", N); + abort(); + } + + padic_clear(a); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/padic/test/t-shift.c b/external/flint-2.4.3/padic/test/t-shift.c new file mode 100644 index 0000000..55ca8f1 --- /dev/null +++ b/external/flint-2.4.3/padic/test/t-shift.c @@ -0,0 +1,152 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "ulong_extras.h" +#include "long_extras.h" +#include "padic.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("shift... "); + fflush(stdout); + + + + /* Check aliasing */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b, c; + slong v; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + padic_init2(c, N); + + padic_randtest(a, state, ctx); + v = z_randint(state, (FLINT_ABS(N) + 4) / 3); + + padic_set(b, a, ctx); + padic_shift(c, b, v, ctx); + padic_shift(b, b, v, ctx); + + result = (padic_equal(b, c)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("c = "), padic_print(c, ctx), flint_printf("\n"); + abort(); + } + + padic_clear(a); + padic_clear(b); + padic_clear(c); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Check that (a * b) * c == a * (b * c), correct only mod p^{N-v} */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b, c; + slong v, v1, v2; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + padic_init2(c, N); + + padic_randtest(a, state, ctx); + v1 = z_randint(state, (FLINT_ABS(N) + 4) / 3); + v2 = z_randint(state, (FLINT_ABS(N) + 4) / 3); + + padic_shift(b, a, v1, ctx); + padic_shift(b, b, v2, ctx); + + padic_shift(c, a, v2, ctx); + padic_shift(c, c, v1, ctx); + + v = FLINT_MIN(v1, v2); + v = FLINT_MIN(v, padic_val(a)); + v = FLINT_MIN(v, 0); + + if ((v >= 0) || (-v < N)) /* Otherwise, no precision left */ + { + slong N2 = (v >= 0) ? N : N + v; + + padic_prec(b) = N2; + padic_prec(c) = N2; + + padic_reduce(b, ctx); + padic_reduce(c, ctx); + + result = (padic_equal(b, c)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("c = "), padic_print(c, ctx), flint_printf("\n"); + abort(); + } + } + + padic_clear(a); + padic_clear(b); + padic_clear(c); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/padic/test/t-sqrt.c b/external/flint-2.4.3/padic/test/t-sqrt.c new file mode 100644 index 0000000..f2afdd6 --- /dev/null +++ b/external/flint-2.4.3/padic/test/t-sqrt.c @@ -0,0 +1,440 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "padic.h" +#include "ulong_extras.h" +#include "long_extras.h" + +int main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("sqrt... "); + fflush(stdout); + + + +/* PRIME p = 2 ***************************************************************/ + + /* Check aliasing: a = sqrt(a) */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + int ans1, ans2; + padic_t a, d; + + fmpz_init_set_ui(p, 2); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(d, N); + + padic_randtest(a, state, ctx); + + ans1 = padic_sqrt(d, a, ctx); + ans2 = padic_sqrt(a, a, ctx); + + result = ((ans1 == ans2) && (!ans1 || padic_equal(a, d))); + if (!result) + { + flint_printf("FAIL (aliasing):\n\n"); + flint_printf("p = "), fmpz_print(p), flint_printf("\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("d = "), padic_print(d, ctx), flint_printf("\n"); + abort(); + } + + padic_clear(a); + padic_clear(d); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Test random elements */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + int ans; + padic_t a, b, d; + + fmpz_init_set_ui(p, 2); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + padic_init2(d, N); + + padic_randtest(a, state, ctx); + + ans = padic_sqrt(b, a, ctx); + + padic_mul(d, b, b, ctx); + + if (ans && padic_val(a) < 0) + { + slong N2 = N + padic_val(a); + padic_t a2, d2; + + padic_init2(a2, N2); + padic_init2(d2, N2); + + padic_set(a2, a, ctx); + padic_set(d2, d, ctx); + + result = (padic_equal(a2, d2)); + if (!result) + { + flint_printf("FAIL (random elements):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("d = "), padic_print(d, ctx), flint_printf("\n"); + flint_printf("a2 = "), padic_print(a2, ctx), flint_printf("\n"); + flint_printf("d2 = "), padic_print(d2, ctx), flint_printf("\n"); + flint_printf("p = "), fmpz_print(p), flint_printf("\n"); + flint_printf("ans = %d\n", ans); + abort(); + } + + padic_clear(a2); + padic_clear(d2); + } + else + { + result = (!ans || padic_equal(a, d)); + if (!result) + { + flint_printf("FAIL (random elements):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("d = "), padic_print(d, ctx), flint_printf("\n"); + flint_printf("p = "), fmpz_print(p), flint_printf("\n"); + flint_printf("ans = %d\n", ans); + abort(); + } + } + + padic_clear(a); + padic_clear(b); + padic_clear(d); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Test random squares */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + int ans; + padic_t a, b, c, d; + + fmpz_init_set_ui(p, 2); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + padic_init2(c, N); + padic_init2(d, N); + + padic_randtest(b, state, ctx); + padic_mul(a, b, b, ctx); + + ans = padic_sqrt(c, a, ctx); + + padic_mul(d, c, c, ctx); + + if (ans && padic_val(a) < 0) + { + slong N2 = N + padic_val(a); + padic_t a2, d2; + + padic_init2(a2, N2); + padic_init2(d2, N2); + + padic_set(a2, a, ctx); + padic_set(d2, d, ctx); + + result = (padic_equal(a2, d2)); + if (!result) + { + flint_printf("FAIL (random elements):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("c = "), padic_print(c, ctx), flint_printf("\n"); + flint_printf("d = "), padic_print(d, ctx), flint_printf("\n"); + flint_printf("a2 = "), padic_print(a2, ctx), flint_printf("\n"); + flint_printf("d2 = "), padic_print(d2, ctx), flint_printf("\n"); + flint_printf("p = "), fmpz_print(p), flint_printf("\n"); + flint_printf("ans = %d\n", ans); + abort(); + } + + padic_clear(a2); + padic_clear(d2); + } + else + { + result = (ans && padic_equal(a, d)); + if (!result) + { + flint_printf("FAIL (random squares):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("c = "), padic_print(c, ctx), flint_printf("\n"); + flint_printf("d = "), padic_print(d, ctx), flint_printf("\n"); + flint_printf("p = "), fmpz_print(p), flint_printf("\n"); + flint_printf("ans = %d\n", ans); + abort(); + } + } + + padic_clear(a); + padic_clear(b); + padic_clear(c); + padic_clear(d); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + +/* PRIME p > 2 ***************************************************************/ + + /* Check aliasing: a = sqrt(a) */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + int ans1, ans2; + padic_t a, d; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(d, N); + + padic_randtest(a, state, ctx); + + ans1 = padic_sqrt(d, a, ctx); + ans2 = padic_sqrt(a, a, ctx); + + result = ((ans1 == ans2) && (!ans1 || padic_equal(a, d))); + if (!result) + { + flint_printf("FAIL (aliasing):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("d = "), padic_print(d, ctx), flint_printf("\n"); + abort(); + } + + padic_clear(a); + padic_clear(d); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Test random elements */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + int ans; + padic_t a, b, d; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + padic_init2(d, N); + + padic_randtest(a, state, ctx); + + ans = padic_sqrt(b, a, ctx); + + padic_mul(d, b, b, ctx); + + if (ans && padic_val(a) < 0) + { + slong N2 = N + padic_val(a); + padic_t a2, d2; + + padic_init2(a2, N2); + padic_init2(d2, N2); + + padic_set(a2, a, ctx); + padic_set(d2, d, ctx); + + result = (padic_equal(a2, d2)); + if (!result) + { + flint_printf("FAIL (random elements):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("d = "), padic_print(d, ctx), flint_printf("\n"); + flint_printf("a2 = "), padic_print(a2, ctx), flint_printf("\n"); + flint_printf("d2 = "), padic_print(d2, ctx), flint_printf("\n"); + flint_printf("p = "), fmpz_print(p), flint_printf("\n"); + flint_printf("ans = %d\n", ans); + abort(); + } + + padic_clear(a2); + padic_clear(d2); + } + else + { + result = (!ans || padic_equal(a, d)); + if (!result) + { + flint_printf("FAIL (random elements):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("d = "), padic_print(d, ctx), flint_printf("\n"); + flint_printf("p = "), fmpz_print(p), flint_printf("\n"); + flint_printf("ans = %d\n", ans); + abort(); + } + } + + padic_clear(a); + padic_clear(b); + padic_clear(d); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Test random squares */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + int ans; + padic_t a, b, c, d; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + padic_init2(c, N); + padic_init2(d, N); + + padic_randtest(b, state, ctx); + padic_mul(a, b, b, ctx); + + ans = padic_sqrt(c, a, ctx); + + padic_mul(d, c, c, ctx); + + if (ans && padic_val(a) < 0) + { + slong N2 = N + padic_val(a); + padic_t a2, d2; + + padic_init2(a2, N2); + padic_init2(d2, N2); + padic_set(a2, a, ctx); + padic_set(d2, d, ctx); + + result = (padic_equal(a2, d2)); + if (!result) + { + flint_printf("FAIL (random elements):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("c = "), padic_print(c, ctx), flint_printf("\n"); + flint_printf("d = "), padic_print(d, ctx), flint_printf("\n"); + flint_printf("a2 = "), padic_print(a2, ctx), flint_printf("\n"); + flint_printf("d2 = "), padic_print(d2, ctx), flint_printf("\n"); + flint_printf("p = "), fmpz_print(p), flint_printf("\n"); + flint_printf("ans = %d\n", ans); + abort(); + } + + padic_clear(a2); + padic_clear(d2); + } + else + { + result = (ans && padic_equal(a, d)); + if (!result) + { + flint_printf("FAIL (random squares):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("c = "), padic_print(c, ctx), flint_printf("\n"); + flint_printf("d = "), padic_print(d, ctx), flint_printf("\n"); + flint_printf("p = "), fmpz_print(p), flint_printf("\n"); + flint_printf("ans = %d\n", ans); + abort(); + } + } + + padic_clear(a); + padic_clear(b); + padic_clear(c); + padic_clear(d); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/padic/test/t-sub.c b/external/flint-2.4.3/padic/test/t-sub.c new file mode 100644 index 0000000..b82a55b --- /dev/null +++ b/external/flint-2.4.3/padic/test/t-sub.c @@ -0,0 +1,304 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "ulong_extras.h" +#include "long_extras.h" +#include "padic.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("sub... "); + fflush(stdout); + + + + /* Check aliasing: a = a - b */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b, d; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + padic_init2(d, N); + + padic_randtest(a, state, ctx); + padic_randtest(b, state, ctx); + + padic_sub(d, a, b, ctx); + padic_sub(a, a, b, ctx); + + result = (padic_equal(a, d)); + if (!result) + { + flint_printf("FAIL (alias a = a - b):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("d = "), padic_print(d, ctx), flint_printf("\n"); + abort(); + } + + padic_clear(a); + padic_clear(b); + padic_clear(d); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Check aliasing: b = a - b */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b, d; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + padic_init2(d, N); + + padic_randtest(a, state, ctx); + padic_randtest(b, state, ctx); + + padic_sub(d, a, b, ctx); + padic_sub(b, a, b, ctx); + + result = (padic_equal(b, d)); + if (!result) + { + flint_printf("FAIL (alias b = a - b):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("d = "), padic_print(d, ctx), flint_printf("\n"); + abort(); + } + + padic_clear(a); + padic_clear(b); + padic_clear(d); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Check aliasing: a = a - a */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, d; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(d, N); + + padic_randtest(a, state, ctx); + + padic_sub(d, a, a, ctx); + padic_sub(a, a, a, ctx); + + result = (padic_equal(a, d)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("d = "), padic_print(d, ctx), flint_printf("\n"); + abort(); + } + + padic_clear(a); + padic_clear(d); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Check that a - b == -(b - a) */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b, c, d; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + padic_init2(c, N); + padic_init2(d, N); + + padic_randtest(a, state, ctx); + padic_randtest(b, state, ctx); + + padic_sub(c, a, b, ctx); + padic_sub(d, b, a, ctx); + padic_neg(d, d, ctx); + + result = (padic_equal(c, d)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("c = "), padic_print(c, ctx), flint_printf("\n"); + flint_printf("d = "), padic_print(d, ctx), flint_printf("\n"); + abort(); + } + + padic_clear(a); + padic_clear(b); + padic_clear(c); + padic_clear(d); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Check that (a - b) - c == a - (b + c) */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b, c, d, e; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + padic_init2(c, N); + padic_init2(d, N); + padic_init2(e, N); + + padic_randtest(a, state, ctx); + padic_randtest(b, state, ctx); + padic_randtest(c, state, ctx); + + padic_sub(d, a, b, ctx); + padic_sub(d, d, c, ctx); + + padic_add(e, b, c, ctx); + padic_sub(e, a, e, ctx); + + result = (padic_equal(d, e)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("c = "), padic_print(c, ctx), flint_printf("\n"); + flint_printf("d = "), padic_print(d, ctx), flint_printf("\n"); + flint_printf("e = "), padic_print(e, ctx), flint_printf("\n"); + abort(); + } + + padic_clear(a); + padic_clear(b); + padic_clear(c); + padic_clear(d); + padic_clear(e); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Check that a - 0 == a */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + + padic_randtest(a, state, ctx); + padic_zero(b); + + padic_sub(b, a, b, ctx); + + result = (padic_equal(a, b)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + abort(); + } + + padic_clear(a); + padic_clear(b); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/padic/test/t-teichmuller.c b/external/flint-2.4.3/padic/test/t-teichmuller.c new file mode 100644 index 0000000..b7b61d6 --- /dev/null +++ b/external/flint-2.4.3/padic/test/t-teichmuller.c @@ -0,0 +1,127 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "ulong_extras.h" +#include "padic.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("teichmuller... "); + fflush(stdout); + + + + /* Check aliasing (x 1,000) */ + for (i = 0; i < 1000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_t a, b, c; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX); + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + padic_init2(c, N); + + padic_randtest_int(a, state, ctx); + padic_set(b, a, ctx); + + padic_teichmuller(c, b, ctx); + padic_teichmuller(b, b, ctx); + + result = (padic_equal(b, c)); + if (!result) + { + flint_printf("FAIL (aliasing):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("c = "), padic_print(c, ctx), flint_printf("\n"); + abort(); + } + + padic_clear(a); + padic_clear(b); + padic_clear(c); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Check x^p == x for word-sized p (x 10,000)*/ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong prime, N; + padic_ctx_t ctx; + + padic_t a, b, c; + + prime = n_randprime(state, 2 + n_randint(state, FLINT_BITS - 2), 0); + fmpz_init_set_ui(p, prime); + N = n_randint(state, PADIC_TEST_PREC_MAX); + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_init2(a, N); + padic_init2(b, N); + padic_init2(c, N); + + padic_randtest_int(a, state, ctx); + + padic_teichmuller(b, a, ctx); + padic_pow_si(c, b, fmpz_get_si(p), ctx); + + result = (padic_equal(b, c)); + if (!result) + { + flint_printf("FAIL (x^p == x):\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_print(b, ctx), flint_printf("\n"); + flint_printf("c = "), padic_print(c, ctx), flint_printf("\n"); + abort(); + } + + padic_clear(a); + padic_clear(b); + padic_clear(c); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/padic/test/t-val_fac.c b/external/flint-2.4.3/padic/test/t-val_fac.c new file mode 100644 index 0000000..5a0899b --- /dev/null +++ b/external/flint-2.4.3/padic/test/t-val_fac.c @@ -0,0 +1,188 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "ulong_extras.h" +#include "padic.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("padic_val_fac... "); + fflush(stdout); + + + + /* Check aliasing for padic_val_fac() */ + for (i = 0; i < 1000; i++) + { + fmpz_t a, b, c, p; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(c); + fmpz_init(p); + + fmpz_randtest_unsigned(a, state, (mp_bitcnt_t) (1.5 * FLINT_BITS)); + fmpz_set(b, a); + fmpz_set_ui(p, n_randtest_prime(state, 0)); + + padic_val_fac(c, b, p); + padic_val_fac(b, b, p); + + result = fmpz_equal(b, c); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), fmpz_print(a), flint_printf("\n"); + flint_printf("b = "), fmpz_print(b), flint_printf("\n"); + flint_printf("c = "), fmpz_print(c), flint_printf("\n"); + flint_printf("p = "), fmpz_print(p), flint_printf("\n"); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(c); + fmpz_clear(p); + } + + /* Check correctness for padic_val_fac_ui(), p == 2 */ + for (i = 0; i < 1000; i++) + { + fmpz_t a, b, p; + + ulong s, t, N; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(p); + + N = n_randint(state, WORD(1) < 13); + fmpz_set_ui(p, 2); + fmpz_fac_ui(a, N); + + s = padic_val_fac_ui_2(N); + t = fmpz_remove(b, a, p); + + result = (s == t); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), fmpz_print(a), flint_printf("\n"); + flint_printf("b = "), fmpz_print(b), flint_printf("\n"); + flint_printf("N = %wu\n", N); + flint_printf("s = %wu\n", s); + flint_printf("t = %wu\n", t); + flint_printf("p = "), fmpz_print(p), flint_printf("\n"); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(p); + } + + /* Check correctness for padic_val_fac_ui(), any p */ + for (i = 0; i < 1000; i++) + { + fmpz_t a, b, p; + + ulong s, t, N; + + fmpz_init(a); + fmpz_init(b); + fmpz_init(p); + + N = n_randint(state, WORD(1) < 13); + fmpz_set_ui(p, n_randprime(state, 2 + n_randint(state, FLINT_BITS - 4), 0)); + fmpz_fac_ui(a, N); + + s = padic_val_fac_ui(N, p); + t = fmpz_remove(b, a, p); + + result = (s == t); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), fmpz_print(a), flint_printf("\n"); + flint_printf("b = "), fmpz_print(b), flint_printf("\n"); + flint_printf("N = %wu\n", N); + flint_printf("s = %wu\n", s); + flint_printf("t = %wu\n", t); + flint_printf("p = "), fmpz_print(p), flint_printf("\n"); + abort(); + } + + fmpz_clear(a); + fmpz_clear(b); + fmpz_clear(p); + } + + /* Compare padic_val_fac_ui() with padic_val_fac() */ + for (i = 0; i < 1000; i++) + { + fmpz_t a, p, t, z; + + ulong s, n; + + fmpz_init(a); + fmpz_init(p); + fmpz_init(t); + fmpz_init(z); + + n = n_randint(state, WORD(1) < 13); + fmpz_set_ui(z, n); + fmpz_set_ui(p, n_randprime(state, 2 + n_randint(state, FLINT_BITS - 4), 0)); + fmpz_fac_ui(a, n); + + s = padic_val_fac_ui(n, p); + padic_val_fac(t, z, p); + + result = (fmpz_equal_ui(t, s)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), fmpz_print(a), flint_printf("\n"); + flint_printf("n = %wu\n", n); + flint_printf("s = %wu\n", s); + flint_printf("t = "), fmpz_print(t), flint_printf("\n"); + flint_printf("p = "), fmpz_print(p), flint_printf("\n"); + abort(); + } + + fmpz_clear(a); + fmpz_clear(p); + fmpz_clear(t); + fmpz_clear(z); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/padic/val_fac.c b/external/flint-2.4.3/padic/val_fac.c new file mode 100644 index 0000000..324cc2f --- /dev/null +++ b/external/flint-2.4.3/padic/val_fac.c @@ -0,0 +1,87 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "padic.h" + +ulong padic_val_fac_ui_2(ulong N) +{ + ulong s = 0, t = N; + + do + { + t /= 2; + s += t; + } + while (t); + + return s; +} + +ulong padic_val_fac_ui(ulong N, const fmpz_t prime) +{ + if (fmpz_abs_fits_ui(prime)) + { + const ulong p = fmpz_get_ui(prime); + + ulong s = 0, t = N; + + do + { + t /= p; + s += t; + } + while (t); + + return s; + } + else + { + return 0; + } +} + +void padic_val_fac(fmpz_t rop, const fmpz_t op, const fmpz_t p) +{ + fmpz_t s, t; + + if (fmpz_sgn(op) < 0) + { + flint_printf("Exception (padic_val_fac). op is negative.\n"); + abort(); + } + + fmpz_init(s); + fmpz_init_set(t, op); + + do + { + fmpz_fdiv_q(t, t, p); + fmpz_add(s, s, t); + } + while (!fmpz_is_zero(t)); + + fmpz_swap(rop, s); +} + diff --git a/external/flint-2.4.3/padic_mat.h b/external/flint-2.4.3/padic_mat.h new file mode 100644 index 0000000..f23eda2 --- /dev/null +++ b/external/flint-2.4.3/padic_mat.h @@ -0,0 +1,262 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012, 2013 Sebastian Pancratz + +******************************************************************************/ + +#ifndef PADIC_MAT_H +#define PADIC_MAT_H + +#undef ulong +#define ulong ulongxx /* interferes with system includes */ +#include +#undef ulong +#include +#define ulong mp_limb_t + +#include "flint.h" +#include "fmpz.h" +#include "fmpz_mat.h" +#include "fmpq_mat.h" +#include "padic.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +typedef struct +{ + fmpz_mat_struct mat; + slong val; + slong N; +} padic_mat_struct; + +typedef padic_mat_struct padic_mat_t[1]; + +/* Macros *******************************************************************/ + +#define padic_mat(A) (&((A)->mat)) +#define padic_mat_entry(A, i, j) ((A)->mat.rows[i] + (j)) +#define padic_mat_val(A) ((A)->val) +#define padic_mat_prec(A) ((A)->N) + +#define padic_mat_nrows(A) (((A)->mat).r) +#define padic_mat_ncols(A) (((A)->mat).c) + +/* Memory management ********************************************************/ + +void padic_mat_init(padic_mat_t A, slong r, slong c); + +void padic_mat_init2(padic_mat_t A, slong r, slong c, slong prec); + +void padic_mat_clear(padic_mat_t A); + +void _padic_mat_canonicalise(padic_mat_t A, const padic_ctx_t ctx); + +void _padic_mat_reduce(padic_mat_t A, const padic_ctx_t ctx); + +void padic_mat_reduce(padic_mat_t A, const padic_ctx_t ctx); + +static __inline__ int +padic_mat_is_empty(const padic_mat_t A) +{ + return fmpz_mat_is_empty(padic_mat(A)); +} + +static __inline__ int +padic_mat_is_square(const padic_mat_t A) +{ + return fmpz_mat_is_square(padic_mat(A)); +} + +static __inline__ int +padic_mat_is_canonical(const padic_mat_t A, const padic_ctx_t ctx) +{ + if (fmpz_mat_is_zero(padic_mat(A))) + { + return (padic_mat_val(A) == 0); + } + else + { + slong i, j; + int canonical = 0; + + for (i = 0; i < padic_mat(A)->r; i++) + for (j = 0; j < padic_mat(A)->c; j++) + if (!fmpz_divisible(padic_mat_entry(A, i, j), ctx->p)) + canonical = 1; + return canonical; + } +} + +static __inline__ int +padic_mat_is_reduced(const padic_mat_t A, const padic_ctx_t ctx) +{ + if (padic_mat_is_empty(A)) + { + return 1; + } + else if (fmpz_mat_is_zero(padic_mat(A))) + { + return (padic_mat_val(A) == 0); + } + else if (padic_mat_is_canonical(A, ctx)) + { + const slong v = padic_mat_val(A); + const slong N = padic_mat_prec(A); + + if (v >= N) + { + return 0; + } + else + { + slong i, j; + fmpz_t pN; + int reduced = 1; + int alloc = _padic_ctx_pow_ui(pN, N - v, ctx); + + for (i = 0; (i < padic_mat_nrows(A)) && reduced; i++) + for (j = 0; (j < padic_mat_ncols(A)) && reduced; j++) + reduced = (fmpz_cmp(padic_mat_entry(A, i, j), pN) < 0); + + if (alloc) + fmpz_clear(pN); + + return reduced; + } + } + else + { + return 0; + } +} + +/* Basic assignment **********************************************************/ + +void padic_mat_set(padic_mat_t B, const padic_mat_t A, const padic_ctx_t ctx); + +void padic_mat_swap(padic_mat_t A, padic_mat_t B); + +void padic_mat_zero(padic_mat_t A); + +void padic_mat_one(padic_mat_t A); + +/* Conversions ***************************************************************/ + +void padic_mat_set_fmpq_mat(padic_mat_t B, + const fmpq_mat_t A, const padic_ctx_t ctx); + +void padic_mat_get_fmpq_mat(fmpq_mat_t B, + const padic_mat_t A, const padic_ctx_t ctx); + +/* Entries *******************************************************************/ + +void padic_mat_get_entry_padic(padic_t rop, + const padic_mat_t op, slong i, slong j, + const padic_ctx_t ctx); + +void padic_mat_set_entry_padic(padic_mat_t rop, slong i, slong j, + const padic_t op, const padic_ctx_t ctx); + +/* Comparison ****************************************************************/ + +int padic_mat_equal(const padic_mat_t A, const padic_mat_t B); + +int padic_mat_is_zero(const padic_mat_t A); + +/* Input and output *********************************************************/ + +int padic_mat_fprint(FILE * file, + const padic_mat_t A, const padic_ctx_t ctx); + +int padic_mat_fprint_pretty(FILE * file, const padic_mat_t A, + const padic_ctx_t ctx); + +static __inline__ +int padic_mat_print(const padic_mat_t A, const padic_ctx_t ctx) +{ + return padic_mat_fprint(stdout, A, ctx); +} + +static __inline__ +int padic_mat_print_pretty(const padic_mat_t A, const padic_ctx_t ctx) +{ + return padic_mat_fprint_pretty(stdout, A, ctx); +} + +/* Random matrix generation *************************************************/ + +void padic_mat_randtest(padic_mat_t mat, flint_rand_t state, + const padic_ctx_t ctx); + +/* Transpose *****************************************************************/ + +void padic_mat_transpose(padic_mat_t B, const padic_mat_t A); + +/* Addition and subtraction **************************************************/ + +void _padic_mat_add(padic_mat_t C, const padic_mat_t A, const padic_mat_t B, + const padic_ctx_t ctx); +void padic_mat_add(padic_mat_t C, const padic_mat_t A, const padic_mat_t B, + const padic_ctx_t ctx); + +void _padic_mat_sub(padic_mat_t C, const padic_mat_t A, const padic_mat_t B, + const padic_ctx_t ctx); +void padic_mat_sub(padic_mat_t C, const padic_mat_t A, const padic_mat_t B, + const padic_ctx_t ctx); + +void _padic_mat_neg(padic_mat_t B, const padic_mat_t A); +void padic_mat_neg(padic_mat_t B, const padic_mat_t A, const padic_ctx_t ctx); + +/* Scalar operations *********************************************************/ + +void _padic_mat_scalar_mul_padic(padic_mat_t B, + const padic_mat_t A, const padic_t c, + const padic_ctx_t ctx); +void padic_mat_scalar_mul_padic(padic_mat_t B, + const padic_mat_t A, const padic_t c, + const padic_ctx_t ctx); + +void _padic_mat_scalar_mul_fmpz(padic_mat_t B, + const padic_mat_t A, const fmpz_t c, + const padic_ctx_t ctx); +void padic_mat_scalar_mul_fmpz(padic_mat_t B, + const padic_mat_t A, const fmpz_t c, + const padic_ctx_t ctx); + +void padic_mat_scalar_div_fmpz(padic_mat_t B, + const padic_mat_t A, const fmpz_t c, + const padic_ctx_t ctx); + +/* Multiplication ************************************************************/ + +void padic_mat_mul(padic_mat_t C, const padic_mat_t A, const padic_mat_t B, + const padic_ctx_t ctx); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/external/flint-2.4.3/padic_mat/Makefile b/external/flint-2.4.3/padic_mat/Makefile new file mode 100644 index 0000000..6969798 --- /dev/null +++ b/external/flint-2.4.3/padic_mat/Makefile @@ -0,0 +1,54 @@ +SOURCES = $(wildcard *.c) + +OBJS = $(patsubst %.c, $(BUILD_DIR)/$(MOD_DIR)_%.o, $(SOURCES)) + +LOBJS = $(patsubst %.c, $(BUILD_DIR)/%.lo, $(SOURCES)) +MOD_LOBJ = $(BUILD_DIR)/../$(MOD_DIR).lo + +TEST_SOURCES = $(wildcard test/*.c) + +PROF_SOURCES = $(wildcard profile/*.c) + +TUNE_SOURCES = $(wildcard tune/*.c) + +TESTS = $(patsubst %.c, $(BUILD_DIR)/%, $(TEST_SOURCES)) + +TESTS_RUN = $(patsubst %, %_RUN, $(TESTS)) + +PROFS = $(patsubst %.c, %, $(PROF_SOURCES)) + +TUNE = $(patsubst %.c, %, $(TUNE_SOURCES)) + +all: shared static + +shared: $(MOD_LOBJ) + +static: $(OBJS) + +profile: $(PROF_SOURCES) + $(foreach prog, $(PROFS), $(CC) $(ABI_FLAG) -O2 -std=c99 $(INCS) $(prog).c ../profiler.o -o $(BUILD_DIR)/$(prog) $(LIBS) || exit $$?;) + +tune: $(TUNE_SOURCES) + $(foreach prog, $(TUNE), $(CC) $(ABI_FLAG) -O2 -std=c99 $(INCS) $(prog).c -o $(BUILD_DIR)/$(prog) $(LIBS) || exit $$?;) + +$(BUILD_DIR)/$(MOD_DIR)_%.o: %.c + $(CC) $(CFLAGS) -c $(INCS) $< -o $@ + +$(MOD_LOBJ): $(LOBJS) + $(CC) $(ABI_FLAG) -Wl,-r $^ -o $@ -nostdlib + +$(BUILD_DIR)/%.lo: %.c + $(CC) $(PICFLAG) $(CFLAGS) $(INCS) -c $< -o $@ + +clean: + rm -rf $(BUILD_DIR) $(MOD_LOBJ) + +check: $(TESTS) $(TESTS_RUN) + +$(BUILD_DIR)/test/%: test/%.c + $(CC) $(CFLAGS) $(INCS) $< ../test_helpers.o -o $@ $(LIBS) + +%_RUN: % + @$< + +.PHONY: profile tune clean check all shared static %_RUN diff --git a/external/flint-2.4.3/padic_mat/add.c b/external/flint-2.4.3/padic_mat/add.c new file mode 100644 index 0000000..a0fa0fa --- /dev/null +++ b/external/flint-2.4.3/padic_mat/add.c @@ -0,0 +1,127 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2013 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_mat.h" +#include "padic_mat.h" + +/* + Assumptions: + + o That the matrix dimensions be compatible. + o That the matrices be non-empty. + o That ord_p(A) >= ord_p(B). + */ + +void _padic_mat_add(padic_mat_t C, const padic_mat_t A, const padic_mat_t B, + const padic_ctx_t ctx) +{ + if (padic_mat_is_zero(A)) + { + padic_mat_set(C, B, ctx); + return; + } + if (padic_mat_is_zero(B)) + { + padic_mat_set(C, A, ctx); + return; + } + if (padic_mat_val(B) >= padic_mat_prec(C)) + { + padic_mat_zero(C); + return; + } + + + if (padic_mat_val(A) == padic_mat_val(B)) + { + fmpz_mat_add(padic_mat(C), padic_mat(A), padic_mat(B)); + padic_mat_val(C) = padic_mat_val(B); + _padic_mat_canonicalise(C, ctx); + } + else /* padic_mat_val(A) > padic_mat_val(B) */ + { + fmpz_t x; + + fmpz_init(x); + fmpz_pow_ui(x, ctx->p, padic_mat_val(A) - padic_mat_val(B)); + + if (C == B) + { + fmpz_mat_scalar_addmul_fmpz(padic_mat(C), padic_mat(A), x); + } + else if (C == A) + { + fmpz_mat_scalar_mul_fmpz(padic_mat(C), padic_mat(A), x); + fmpz_mat_add(padic_mat(C), padic_mat(B), padic_mat(C)); + padic_mat_val(C) = padic_mat_val(B); + } + else + { + fmpz_mat_set(padic_mat(C), padic_mat(B)); + fmpz_mat_scalar_addmul_fmpz(padic_mat(C), padic_mat(A), x); + padic_mat_val(C) = padic_mat_val(B); + } + + fmpz_clear(x); + } + + /* Reduction */ + { + fmpz_t pow; + int alloc = _padic_ctx_pow_ui(pow, padic_mat_prec(C)- padic_mat_val(C), ctx); + + /* TODO: Improve, use input precision */ + _fmpz_vec_scalar_mod_fmpz(padic_mat(C)->entries, + padic_mat(C)->entries, padic_mat_nrows(C)*padic_mat_ncols(C), pow); + + if (fmpz_mat_is_zero(padic_mat(C))) + { + padic_mat_val(C) = 0; + } + + + if (alloc) + fmpz_clear(pow); + } +} + +void padic_mat_add(padic_mat_t C, const padic_mat_t A, const padic_mat_t B, + const padic_ctx_t ctx) +{ + if (padic_mat_is_empty(C)) + { + return; + } + + if (padic_mat_val(A) >= padic_mat_val(B)) + { + _padic_mat_add(C, A, B, ctx); + } + else + { + _padic_mat_add(C, B, A, ctx); + } +} + diff --git a/external/flint-2.4.3/padic_mat/canonicalise.c b/external/flint-2.4.3/padic_mat/canonicalise.c new file mode 100644 index 0000000..4b5a4f7 --- /dev/null +++ b/external/flint-2.4.3/padic_mat/canonicalise.c @@ -0,0 +1,131 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_mat.h" +#include "padic_poly.h" +#include "padic_mat.h" + +static void +_padic_mat_canonicalise_fmpz(fmpz *vec, slong len, slong *val, const fmpz_t p) +{ + int nonzero = 0; + slong i; + + for (i = 0; i < len; i++) + { + if (vec[i] != WORD(0)) + { + nonzero = 1; + if (!fmpz_divisible(vec + i, p)) + { + return; + } + } + } + + if (nonzero) + { + _fmpz_vec_scalar_divexact_fmpz(vec, vec, len, p); + (*val)++; + + while (1) + { + for (i = 0; i < len; i++) + { + if (!fmpz_divisible(vec + i, p)) + { + return; + } + } + + _fmpz_vec_scalar_divexact_fmpz(vec, vec, len, p); + (*val)++; + } + } + else + { + *val = 0; + } +} + +static void +_padic_mat_canonicalise_si(fmpz *vec, slong len, slong *val, slong p) +{ + int nonzero = 0; + slong i; + + for (i = 0; i < len; i++) + { + if (vec[i] != WORD(0)) + { + nonzero = 1; + if (!fmpz_divisible_si(vec + i, p)) + { + return; + } + } + } + + if (nonzero) + { + _fmpz_vec_scalar_divexact_ui(vec, vec, len, p); + (*val)++; + + while (1) + { + for (i = 0; i < len; i++) + { + if (!fmpz_divisible_si(vec + i, p)) + { + return; + } + } + + _fmpz_vec_scalar_divexact_ui(vec, vec, len, p); + (*val)++; + } + } + else + { + *val = 0; + } +} + +void _padic_mat_canonicalise(padic_mat_t A, const padic_ctx_t ctx) +{ + if (COEFF_IS_MPZ(*(ctx->p))) + { + _padic_mat_canonicalise_fmpz(padic_mat(A)->entries, + padic_mat(A)->r * padic_mat(A)->c, + &(A->val), ctx->p); + } + else + { + _padic_mat_canonicalise_si(padic_mat(A)->entries, + padic_mat(A)->r * padic_mat(A)->c, + &(A->val), *(ctx->p)); + } +} + diff --git a/external/flint-2.4.3/padic_mat/clear.c b/external/flint-2.4.3/padic_mat/clear.c new file mode 100644 index 0000000..827fc2d --- /dev/null +++ b/external/flint-2.4.3/padic_mat/clear.c @@ -0,0 +1,34 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_mat.h" +#include "padic_mat.h" + +void padic_mat_clear(padic_mat_t A) +{ + fmpz_mat_clear(padic_mat(A)); + A->val = 0; +} + diff --git a/external/flint-2.4.3/padic_mat/doc/padic_mat.txt b/external/flint-2.4.3/padic_mat/doc/padic_mat.txt new file mode 100644 index 0000000..aa4e406 --- /dev/null +++ b/external/flint-2.4.3/padic_mat/doc/padic_mat.txt @@ -0,0 +1,349 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012, 2013 Sebastian Pancratz + +******************************************************************************/ + +******************************************************************************* + + Module documentation + + We represent a matrix over $\mathbf{Q}_p$ as a product $p^v M$, + where $p$ is a prime number, $v \in \mathbf{Z}$ and $M$ a matrix + over $\mathbf{Z}$. + + We say this matrix is in \emph{canonical form} if either $M$ is zero, + in which case we choose $v = 0$, too, or if $M$ contains at least one + $p$-adic unit. + + We say this matrix is \emph{reduced} modulo $p^N$ if it is canonical + form and if all coefficients of $M$ lie in the range $[0, p^{N-v})$. + +******************************************************************************* + +******************************************************************************* + + Macros + +******************************************************************************* + +fmpz_mat_struct * padic_mat(const padic_mat_t A) + + Returns a pointer to the unit part of the matrix, which + is a matrix over $\mathbf{Z}$. + + The return value can be used as an argument to + the functions in the \code{fmpz_mat} module. + +fmpz * padic_mat_entry(const padic_mat_t A, slong i, slong j) + + Returns a pointer to unit part of the entry in position $(i, j)$. + Note that this is not necessarily a unit. + + The return value can be used as an argument to + the functions in the \code{fmpz} module. + +slong padic_mat_val(const padic_mat_t A) + + Returns the valuation of the matrix. + + This is implemented as a macro and can be used as an \emph{lvalue} + as well as an \emph{rvalue}. + +slong padic_mat_nrows(const padic_mat_t A) + + Returns the number of rows of the matrix $A$. + +slong padic_mat_ncols(const padic_mat_t A) + + Returns the number of columns of the matrix $A$. + +******************************************************************************* + + Memory management + +******************************************************************************* + +void padic_mat_init(padic_mat_t A, slong r, slong c) + + Initialises the matrix $A$ as a zero matrix with the specified numbers + of rows and columns and precision \code{PADIC_DEFAULT_PREC}. + +void padic_mat_init2(padic_mat_t A, slong r, slong c, slong prec) + + Initialises the matrix $A$ as a zero matrix with the specified numbers + of rows and columns and the given precision. + +void padic_mat_clear(padic_mat_t A) + + Clears the matrix $A$. + +void _padic_mat_canonicalise(padic_mat_t A, const padic_ctx_t ctx) + + Ensures that the matrix $A$ is in canonical form. + +void _padic_mat_reduce(padic_mat_t A, const padic_ctx_t ctx) + + Ensures that the matrix $A$ is reduced modulo $p^N$, + assuming that it is in canonical form already. + +void padic_mat_reduce(padic_mat_t A, const padic_ctx_t ctx) + + Ensures that the matrix $A$ is reduced modulo $p^N$, + without assuming that it is necessarily in canonical form. + +int padic_mat_is_empty(const padic_mat_t A) + + Returns whether the matrix $A$ is empty, that is, + whether it has zero rows or zero columns. + +int padic_mat_is_square(const padic_mat_t A) + + Returns whether the matrix $A$ is square. + +int padic_mat_is_canonical(const padic_mat_t A, const fmpz_t p) + + Returns whether the matrix $A$ is in canonical form. + +******************************************************************************* + + Basic assignment + +******************************************************************************* + +void padic_mat_set(padic_mat_t B, const padic_mat_t A) + + Sets $B$ to a copy of $A$, respecting the precision of $B$. + +void padic_mat_swap(padic_mat_t A, padic_mat_t B) + + Swaps the two matrices $A$ and $B$. This is done efficiently by + swapping pointers. + +void padic_mat_zero(padic_mat_t A) + + Sets the matrix $A$ to zero. + +void padic_mat_one(padic_mat_t A) + + Sets the matrix $A$ to the identity matrix. If the precision + is negative then the matrix will be the zero matrix. + +******************************************************************************* + + Conversions + +******************************************************************************* + +void padic_mat_set_fmpq_mat(padic_mat_t B, + const fmpq_mat_t A, const padic_ctx_t ctx) + + Sets the $p$-adic matrix $B$ to the rational matrix $A$, reduced + according to the given context. + +void padic_mat_get_fmpq_mat(fmpq_mat_t B, + const padic_mat_t A, const padic_ctx_t ctx) + + Sets the rational matrix $B$ to the $p$-adic matrices $A$; + no reduction takes place. + +******************************************************************************* + + Entries + + Because of the choice of the data structure, representing the matrix + as $p^v M$, setting an entry of the matrix might lead to changes in + all entries in the matrix $M$. Also, a specific entry is not readily + available as a $p$-adic number. Thus, there are separate functions + available for getting and setting entries. + +******************************************************************************* + +void padic_mat_get_entry_padic(padic_t rop, + const padic_mat_t op, slong i, slong j, + const padic_ctx_t ctx) + + Sets \code{rop} to the entry in position $(i, j)$ in the matrix \code{op}. + +void padic_mat_set_entry_padic(padic_mat_t rop, slong i, slong j, + const padic_t op, const padic_ctx_t ctx) + + Sets the entry in position $(i, j)$ in the matrix to \code{rop}. + +******************************************************************************* + + Comparison + +******************************************************************************* + +int padic_mat_equal(const padic_mat_t A, const padic_mat_t B) + + Returns whether the two matrices $A$ and $B$ are equal. + +int padic_mat_is_zero(const padic_mat_t A) + + Returns whether the matrix $A$ is zero. + +******************************************************************************* + + Input and output + +******************************************************************************* + +int padic_mat_fprint(FILE * file, + const padic_mat_t A, const padic_ctx_t ctx) + + Prints a simple representation of the matrix $A$ to the + output stream \code{file}. The format is the number of rows, + a space, the number of columns, two spaces, followed by a list + of all the entries, one row after the other. + + In the current implementation, always returns $1$. + +int padic_mat_fprint_pretty(FILE * file, const padic_mat_t A, + const padic_ctx_t ctx) + + Prints a \emph{pretty} representation of the matrix $A$ + to the output stream \code{file}. + + In the current implementation, always returns $1$. + +int padic_mat_print(const padic_mat_t A, const padic_ctx_t ctx) + +int padic_mat_print_pretty(const padic_mat_t A, const padic_ctx_t ctx) + +******************************************************************************* + + Random matrix generation + +******************************************************************************* + +void padic_mat_randtest(padic_mat_t A, flint_rand_t state, + const padic_ctx_t ctx) + + Sets $A$ to a random matrix. + + The valuation will be in the range $[- \ceil{N/10}, N)$, + $[N - \ceil{-N/10}, N)$, or $[-10, 0)$ as $N$ is positive, + negative or zero. + +******************************************************************************* + + Transpose + +******************************************************************************* + +void padic_mat_transpose(padic_mat_t B, const padic_mat_t A) + + Sets $B$ to $A^t$. + +******************************************************************************* + + Addition and subtraction + +******************************************************************************* + +void _padic_mat_add(padic_mat_t C, const padic_mat_t A, const padic_mat_t B, + const padic_ctx_t ctx) + + Sets $C$ to the exact sum $A + B$, ensuring that the result is in + canonical form. + +void padic_mat_add(padic_mat_t C, const padic_mat_t A, const padic_mat_t B, + const padic_ctx_t ctx) + + Sets $C$ to the sum $A + B$ modulo $p^N$. + +void _padic_mat_sub(padic_mat_t C, const padic_mat_t A, const padic_mat_t B, + const padic_ctx_t ctx) + + Sets $C$ to the exact difference $A - B$, ensuring that the result is in + canonical form. + +void padic_mat_sub(padic_mat_t C, const padic_mat_t A, const padic_mat_t B, + const padic_ctx_t ctx) + + Sets $C$ to $A - B$, ensuring that the result is reduced. + +void _padic_mat_neg(padic_mat_t B, const padic_mat_t A) + + Sets $B$ to $-A$ in canonical form. + +void padic_mat_neg(padic_mat_t B, const padic_mat_t A, const padic_ctx_t ctx) + + Sets $B$ to $-A$, ensuring the result is reduced. + +******************************************************************************* + + Scalar operations + +******************************************************************************* + +void _padic_mat_scalar_mul_padic(padic_mat_t B, + const padic_mat_t A, const padic_t c, + const padic_ctx_t ctx) + + Sets $B$ to $c A$, ensuring that the result is in canonical form. + +void padic_mat_scalar_mul_padic(padic_mat_t B, + const padic_mat_t A, const padic_t c, + const padic_ctx_t ctx) + + Sets $B$ to $c A$, ensuring that the result is reduced. + +void _padic_mat_scalar_mul_fmpz(padic_mat_t B, + const padic_mat_t A, const fmpz_t c, + const padic_ctx_t ctx) + + Sets $B$ to $c A$, ensuring that the result is in canonical form. + +void padic_mat_scalar_mul_fmpz(padic_mat_t B, + const padic_mat_t A, const fmpz_t c, + const padic_ctx_t ctx) + + Sets $B$ to $c A$, ensuring that the result is reduced. + +void padic_mat_scalar_div_fmpz(padic_mat_t B, + const padic_mat_t A, const fmpz_t c, + const padic_ctx_t ctx) + + Sets $B$ to $c^{-1} A$, assuming that $c \neq 0$. + Ensures that the result $B$ is reduced. + +******************************************************************************* + + Multiplication + +******************************************************************************* + +void _padic_mat_mul(padic_mat_t C, const padic_mat_t A, const padic_mat_t B, + const padic_ctx_t ctx) + + Sets $C$ to the product $A B$ of the two matrices $A$ and $B$, + ensuring that $C$ is in canonical form. + +void padic_mat_mul(padic_mat_t C, const padic_mat_t A, const padic_mat_t B, + const padic_ctx_t ctx) + + Sets $C$ to the product $A B$ of the two matrices $A$ and $B$, + ensuring that $C$ is reduced. + diff --git a/external/flint-2.4.3/padic_mat/equal.c b/external/flint-2.4.3/padic_mat/equal.c new file mode 100644 index 0000000..499b8d7 --- /dev/null +++ b/external/flint-2.4.3/padic_mat/equal.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_mat.h" +#include "padic_mat.h" + +int padic_mat_equal(const padic_mat_t A, const padic_mat_t B) +{ + if (A->val == B->val) + { + return fmpz_mat_equal(padic_mat(A), padic_mat(B)); + } + else + { + return 0; + } +} + diff --git a/external/flint-2.4.3/padic_mat/fprint.c b/external/flint-2.4.3/padic_mat/fprint.c new file mode 100644 index 0000000..6dae311 --- /dev/null +++ b/external/flint-2.4.3/padic_mat/fprint.c @@ -0,0 +1,142 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_mat.h" +#include "padic_mat.h" + +int padic_mat_fprint(FILE * file, const padic_mat_t A, const padic_ctx_t ctx) +{ + const slong r = padic_mat(A)->r; + const slong c = padic_mat(A)->c; + + if (padic_mat_is_empty(A)) + { + flint_fprintf(file, "%wd %wd\n", r, c); + return 1; + } + + if (ctx->mode == PADIC_TERSE) + { + slong i, j, v; + fmpz_t s, t; + + fmpz_init(s); + fmpz_init(t); + + flint_fprintf(file, "%wd %wd ", r, c); + + for (i = 0; i < r; i++) + for (j = 0; j < c; j++) + { + flint_fprintf(file, " "); + + if (fmpz_is_zero(padic_mat_entry(A, i, j))) + { + flint_fprintf(file, "0"); + } + else + { + v = A->val + + fmpz_remove(t, padic_mat_entry(A, i, j), ctx->p); + + if (v == 0) + { + fmpz_fprint(file, t); + } + else if (v > 0) + { + fmpz_pow_ui(s, ctx->p, v); + fmpz_mul(t, s, t); + fmpz_fprint(file, t); + } + else /* v < 0 */ + { + fmpz_pow_ui(s, ctx->p, -v); + _fmpq_fprint(file, t, s); + } + } + } + + fmpz_clear(s); + fmpz_clear(t); + } + else if (ctx->mode == PADIC_SERIES) + { + flint_printf("ERROR (_padic_mat_fprint). Mode PADIC_SERIES not implemented yet.\n"); + abort(); + } + else if (ctx->mode == PADIC_VAL_UNIT) + { + slong i, j, v; + fmpz_t t; + + fmpz_init(t); + + flint_fprintf(file, "%wd %wd ", r, c); + + for (i = 0; i < r; i++) + for (j = 0; j < c; j++) + { + flint_fprintf(file, " "); + + if (fmpz_is_zero(padic_mat_entry(A, i, j))) + { + flint_fprintf(file, "0"); + } + else + { + v = A->val + + fmpz_remove(t, padic_mat_entry(A, i, j), ctx->p); + + if (v == 0) + { + fmpz_fprint(file, t); + } + else if (v == 1) + { + fmpz_fprint(file, ctx->p); + flint_fprintf(file, "*"); + fmpz_fprint(file, t); + } + else + { + fmpz_fprint(file, ctx->p); + flint_fprintf(file, "^%wd*", v); + fmpz_fprint(file, t); + } + } + } + + fmpz_clear(t); + } + else + { + flint_printf("ERROR (_padic_mat_fprint). Unknown print mode.\n"); + abort(); + } + + return 1; +} + diff --git a/external/flint-2.4.3/padic_mat/fprint_pretty.c b/external/flint-2.4.3/padic_mat/fprint_pretty.c new file mode 100644 index 0000000..7592f6c --- /dev/null +++ b/external/flint-2.4.3/padic_mat/fprint_pretty.c @@ -0,0 +1,63 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_mat.h" +#include "padic_mat.h" + +int padic_mat_fprint_pretty(FILE * file, + const padic_mat_t A, const padic_ctx_t ctx) +{ + const slong r = padic_mat(A)->r; + const slong c = padic_mat(A)->c; + + slong i, j, v; + fmpz_t u; + + fmpz_init(u); + + fputc('[', file); + for (i = 0; i < r; i++) + { + fputc('[', file); + for (j = 0; j < c; j++) + { + v = A->val + fmpz_remove(u, padic_mat_entry(A, i, j), ctx->p); + + _padic_fprint(file, u, v, ctx); + + if (j != c - 1) + fputc(' ', file); + } + fputc(']', file); + if (i != r - 1) + fputc('\n', file); + } + fputc(']', file); + + fmpz_clear(u); + + return 1; +} + diff --git a/external/flint-2.4.3/padic_mat/get_entry_padic.c b/external/flint-2.4.3/padic_mat/get_entry_padic.c new file mode 100644 index 0000000..3ed4b7c --- /dev/null +++ b/external/flint-2.4.3/padic_mat/get_entry_padic.c @@ -0,0 +1,37 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2013 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_mat.h" +#include "padic_mat.h" + +void padic_mat_get_entry_padic(padic_t rop, + const padic_mat_t op, slong i, slong j, + const padic_ctx_t ctx) +{ + fmpz_set(padic_unit(rop), padic_mat_entry(op, i, j)); + padic_val(rop) = padic_mat_val(op); + padic_reduce(rop, ctx); +} + diff --git a/external/flint-2.4.3/padic_mat/get_fmpq_mat.c b/external/flint-2.4.3/padic_mat/get_fmpq_mat.c new file mode 100644 index 0000000..818859b --- /dev/null +++ b/external/flint-2.4.3/padic_mat/get_fmpq_mat.c @@ -0,0 +1,63 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "padic_mat.h" + +void padic_mat_get_fmpq_mat(fmpq_mat_t B, + const padic_mat_t A, const padic_ctx_t ctx) +{ + if (!padic_mat_is_empty(A)) + { + if (padic_mat_is_zero(A)) + { + fmpq_mat_zero(B); + } + else + { + fmpz_t f; + slong i, j; + + fmpz_init(f); + fmpz_pow_ui(f, ctx->p, FLINT_ABS(padic_mat_val(A))); + for (i = 0; i < B->r; i++) + for (j = 0; j < B->c; j++) + { + if (padic_mat_val(A) >= 0) + { + fmpz_mul(fmpq_mat_entry_num(B, i, j), padic_mat_entry(A, i, j), f); + fmpz_one(fmpq_mat_entry_den(B, i, j)); + } + else + { + fmpz_set(fmpq_mat_entry_num(B, i, j), padic_mat_entry(A, i, j)); + fmpz_set(fmpq_mat_entry_den(B, i, j), f); + fmpq_canonicalise(fmpq_mat_entry(B, i, j)); + } + } + fmpz_clear(f); + } + } +} + diff --git a/external/flint-2.4.3/padic_mat/init.c b/external/flint-2.4.3/padic_mat/init.c new file mode 100644 index 0000000..688ec51 --- /dev/null +++ b/external/flint-2.4.3/padic_mat/init.c @@ -0,0 +1,42 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_mat.h" +#include "padic_mat.h" + +void padic_mat_init(padic_mat_t A, slong r, slong c) +{ + fmpz_mat_init(padic_mat(A), r, c); + A->val = 0; + A->N = PADIC_DEFAULT_PREC; +} + +void padic_mat_init2(padic_mat_t A, slong r, slong c, slong prec) +{ + fmpz_mat_init(padic_mat(A), r, c); + A->val = 0; + A->N = prec; +} + diff --git a/external/flint-2.4.3/padic_mat/is_zero.c b/external/flint-2.4.3/padic_mat/is_zero.c new file mode 100644 index 0000000..6fcc526 --- /dev/null +++ b/external/flint-2.4.3/padic_mat/is_zero.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_mat.h" +#include "padic_mat.h" + +int padic_mat_is_zero(const padic_mat_t A) +{ + if (A->val == 0) + { + return fmpz_mat_is_zero(padic_mat(A)); + } + else + { + return 0; + } +} + diff --git a/external/flint-2.4.3/padic_mat/mul.c b/external/flint-2.4.3/padic_mat/mul.c new file mode 100644 index 0000000..2a143d8 --- /dev/null +++ b/external/flint-2.4.3/padic_mat/mul.c @@ -0,0 +1,50 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2013 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_mat.h" +#include "padic_mat.h" + +void padic_mat_mul(padic_mat_t C, const padic_mat_t A, const padic_mat_t B, + const padic_ctx_t ctx) +{ + if (padic_mat_is_empty(C)) + { + return; + } + + if (padic_mat_is_zero(A) || padic_mat_is_zero(B)) + { + padic_mat_zero(C); + } + else + { + fmpz_mat_mul(padic_mat(C), padic_mat(A), padic_mat(B)); + + padic_mat_val(C) = padic_mat_val(A) + padic_mat_val(B); + + padic_mat_reduce(C, ctx); + } +} + diff --git a/external/flint-2.4.3/padic_mat/neg.c b/external/flint-2.4.3/padic_mat/neg.c new file mode 100644 index 0000000..53cfe2e --- /dev/null +++ b/external/flint-2.4.3/padic_mat/neg.c @@ -0,0 +1,43 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_mat.h" +#include "padic_mat.h" + +void _padic_mat_neg(padic_mat_t B, const padic_mat_t A) +{ + if (padic_mat_is_empty(B)) + return; + + fmpz_mat_neg(padic_mat(B), padic_mat(A)); + B->val = A->val; +} + +void padic_mat_neg(padic_mat_t B, const padic_mat_t A, const padic_ctx_t ctx) +{ + _padic_mat_neg(B, A); + _padic_mat_reduce(B, ctx); +} + diff --git a/external/flint-2.4.3/padic_mat/one.c b/external/flint-2.4.3/padic_mat/one.c new file mode 100644 index 0000000..fbc885c --- /dev/null +++ b/external/flint-2.4.3/padic_mat/one.c @@ -0,0 +1,42 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_mat.h" +#include "padic_mat.h" + +void padic_mat_one(padic_mat_t A) +{ + if (padic_mat_prec(A) > 0) + { + fmpz_mat_one(padic_mat(A)); + A->val = 0; + } + else + { + fmpz_mat_zero(padic_mat(A)); + A->val = 0; + } +} + diff --git a/external/flint-2.4.3/padic_mat/randtest.c b/external/flint-2.4.3/padic_mat/randtest.c new file mode 100644 index 0000000..873d142 --- /dev/null +++ b/external/flint-2.4.3/padic_mat/randtest.c @@ -0,0 +1,68 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_mat.h" +#include "padic_mat.h" + +void padic_mat_randtest(padic_mat_t mat, flint_rand_t state, const padic_ctx_t ctx) +{ + if (!padic_mat_is_empty(mat)) + { + const slong N = padic_mat_prec(mat); + + slong i, j, min, max; + fmpz_t pow; + + if (N > 0) + { + min = - ((N + 9) / 10); + max = N; + } + else if (N < 0) + { + min = N - ((-N + 9) / 10); + max = N; + } + else /* ctx->N == 0 */ + { + min = -10; + max = 0; + } + + padic_mat_val(mat) = n_randint(state, max - min) + min; + + fmpz_init(pow); + fmpz_pow_ui(pow, ctx->p, N - padic_mat_val(mat)); + + for (i = 0; i < padic_mat(mat)->r; i++) + for (j = 0; j < padic_mat(mat)->c; j++) + fmpz_randm(padic_mat_entry(mat, i, j), state, pow); + + fmpz_clear(pow); + + _padic_mat_canonicalise(mat, ctx); + } +} + diff --git a/external/flint-2.4.3/padic_mat/reduce.c b/external/flint-2.4.3/padic_mat/reduce.c new file mode 100644 index 0000000..dafd6be --- /dev/null +++ b/external/flint-2.4.3/padic_mat/reduce.c @@ -0,0 +1,64 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_mat.h" +#include "padic_mat.h" + +void _padic_mat_reduce(padic_mat_t mat, const padic_ctx_t ctx) +{ + if (!padic_mat_is_empty(mat) && !padic_mat_is_zero(mat)) + { + if (mat->val >= padic_mat_prec(mat)) + { + padic_mat_zero(mat); + } + else + { + slong i; + fmpz_t pow; + + fmpz_init(pow); + fmpz_pow_ui(pow, ctx->p, padic_mat_prec(mat) - mat->val); + for (i = 0; i < padic_mat(mat)->r * padic_mat(mat)->c; i++) + { + fmpz_mod(padic_mat(mat)->entries + i, + padic_mat(mat)->entries + i, pow); + } + fmpz_clear(pow); + + if (padic_mat_is_zero(mat)) + { + mat->val = 0; + } + } + } +} + +void padic_mat_reduce(padic_mat_t mat, const padic_ctx_t ctx) +{ + _padic_mat_canonicalise(mat, ctx); + _padic_mat_reduce(mat, ctx); +} + diff --git a/external/flint-2.4.3/padic_mat/scalar_div_fmpz.c b/external/flint-2.4.3/padic_mat/scalar_div_fmpz.c new file mode 100644 index 0000000..6404b57 --- /dev/null +++ b/external/flint-2.4.3/padic_mat/scalar_div_fmpz.c @@ -0,0 +1,73 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_mat.h" +#include "padic_mat.h" + +void padic_mat_scalar_div_fmpz(padic_mat_t B, + const padic_mat_t A, const fmpz_t c, + const padic_ctx_t ctx) +{ + if (padic_mat_is_empty(B)) + { + return; + } + + if (fmpz_is_zero(c)) + { + flint_printf("ERROR (padic_mat_scalar_div_fmpz). c is zero.\n"); + abort(); + } + + if (padic_mat_is_zero(A)) + { + padic_mat_zero(B); + } + else + { + fmpz_t d; + slong v; + + fmpz_init(d); + v = fmpz_remove(d, c, ctx->p); + + if (padic_mat_val(A) - v >= padic_mat_prec(B)) + { + padic_mat_zero(B); + } + else + { + _padic_inv(d, d, ctx->p, padic_mat_prec(B) - padic_mat_val(A) + v); + + fmpz_mat_scalar_mul_fmpz(padic_mat(B), padic_mat(A), d); + padic_mat_val(B) = padic_mat_val(A) - v; + + _padic_mat_reduce(B, ctx); + } + + fmpz_clear(d); + } +} + diff --git a/external/flint-2.4.3/padic_mat/scalar_mul_fmpz.c b/external/flint-2.4.3/padic_mat/scalar_mul_fmpz.c new file mode 100644 index 0000000..ad54b9e --- /dev/null +++ b/external/flint-2.4.3/padic_mat/scalar_mul_fmpz.c @@ -0,0 +1,64 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_mat.h" +#include "padic_mat.h" + +void _padic_mat_scalar_mul_fmpz(padic_mat_t B, + const padic_mat_t A, const fmpz_t c, + const padic_ctx_t ctx) +{ + if (padic_mat_is_empty(B)) + { + return; + } + + if (fmpz_is_zero(c) || padic_mat_is_zero(A)) + { + padic_mat_zero(B); + } + else + { + fmpz_t d; + slong v; + + fmpz_init(d); + v = fmpz_remove(d, c, ctx->p); + + fmpz_mat_scalar_mul_fmpz(padic_mat(B), padic_mat(A), d); + padic_mat_val(B) = padic_mat_val(A) + v; + + fmpz_clear(d); + } +} + +void padic_mat_scalar_mul_fmpz(padic_mat_t B, + const padic_mat_t A, const fmpz_t c, + const padic_ctx_t ctx) +{ + _padic_mat_scalar_mul_fmpz(B, A, c, ctx); + _padic_mat_reduce(B, ctx); +} + diff --git a/external/flint-2.4.3/padic_mat/scalar_mul_padic.c b/external/flint-2.4.3/padic_mat/scalar_mul_padic.c new file mode 100644 index 0000000..f46aec1 --- /dev/null +++ b/external/flint-2.4.3/padic_mat/scalar_mul_padic.c @@ -0,0 +1,55 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_mat.h" +#include "padic_mat.h" + +void _padic_mat_scalar_mul_padic(padic_mat_t B, + const padic_mat_t A, const padic_t c, + const padic_ctx_t ctx) +{ + if (padic_mat_is_empty(B)) + { + return; + } + + if (padic_is_zero(c) || padic_mat_is_zero(A)) + { + padic_mat_zero(B); + return; + } + + fmpz_mat_scalar_mul_fmpz(padic_mat(B), padic_mat(A), padic_unit(c)); + padic_mat_val(B) = padic_mat_val(A) + padic_val(c); +} + +void padic_mat_scalar_mul_padic(padic_mat_t B, + const padic_mat_t A, const padic_t c, + const padic_ctx_t ctx) +{ + _padic_mat_scalar_mul_padic(B, A, c, ctx); + _padic_mat_reduce(B, ctx); +} + diff --git a/external/flint-2.4.3/padic_mat/set.c b/external/flint-2.4.3/padic_mat/set.c new file mode 100644 index 0000000..85b1b69 --- /dev/null +++ b/external/flint-2.4.3/padic_mat/set.c @@ -0,0 +1,51 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2013 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_mat.h" +#include "padic_mat.h" + +void padic_mat_set(padic_mat_t rop, const padic_mat_t op, const padic_ctx_t ctx) +{ + if (op != rop) + { + if (padic_mat_val(op) >= padic_mat_prec(rop)) + { + padic_mat_zero(rop); + } + else if (padic_mat_prec(rop) >= padic_mat_prec(op)) + { + fmpz_mat_set(padic_mat(rop), padic_mat(op)); + padic_mat_val(rop) = padic_mat_val(op); + } + else + { + fmpz_mat_set(padic_mat(rop), padic_mat(op)); + padic_mat_val(rop) = padic_mat_val(op); + + _padic_mat_reduce(rop, ctx); + } + } +} + diff --git a/external/flint-2.4.3/padic_mat/set_entry_padic.c b/external/flint-2.4.3/padic_mat/set_entry_padic.c new file mode 100644 index 0000000..2abf867 --- /dev/null +++ b/external/flint-2.4.3/padic_mat/set_entry_padic.c @@ -0,0 +1,69 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_mat.h" +#include "padic_mat.h" + +void padic_mat_set_entry_padic(padic_mat_t rop, slong i, slong j, + const padic_t op, const padic_ctx_t ctx) +{ + if (padic_is_zero(op)) + { + fmpz_zero(padic_mat_entry(rop, i, j)); + _padic_mat_canonicalise(rop, ctx); + return; + } + + if (padic_mat_val(rop) == padic_val(op)) + { + fmpz_set(padic_mat_entry(rop, i, j), padic_unit(op)); + } + else if (padic_mat_val(rop) < padic_val(op)) + { + fmpz_t t; + + fmpz_init(t); + fmpz_pow_ui(t, ctx->p, padic_val(op) - padic_mat_val(rop)); + fmpz_mul(padic_mat_entry(rop, i, j), padic_unit(op), t); + fmpz_clear(t); + + _padic_mat_canonicalise(rop, ctx); + } + else /* rop->val > op->val */ + { + fmpz_t pow; + + fmpz_init(pow); + fmpz_pow_ui(pow, ctx->p, padic_mat_val(rop) - padic_val(op)); + _fmpz_vec_scalar_mul_fmpz(padic_mat(rop)->entries, + padic_mat(rop)->entries, + padic_mat(rop)->r * padic_mat(rop)->c, pow); + fmpz_clear(pow); + + fmpz_set(padic_mat_entry(rop, i, j), padic_unit(op)); + padic_mat_val(rop) = padic_val(op); + } +} + diff --git a/external/flint-2.4.3/padic_mat/set_fmpq_mat.c b/external/flint-2.4.3/padic_mat/set_fmpq_mat.c new file mode 100644 index 0000000..746cd12 --- /dev/null +++ b/external/flint-2.4.3/padic_mat/set_fmpq_mat.c @@ -0,0 +1,94 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012, 2013 Sebastian Pancratz + +******************************************************************************/ + +#include + +#include "padic_mat.h" + +void padic_mat_set_fmpq_mat(padic_mat_t B, + const fmpq_mat_t A, const padic_ctx_t ctx) +{ + if (!fmpq_mat_is_empty(A)) + { + const slong N = padic_mat_prec(B); + + slong i, j, m = WORD_MAX, v, w; + fmpz_t f, g, s, t; + + fmpz_init(f); + fmpz_init(g); + fmpz_init(s); + fmpz_init(t); + + /* Find min valuation m */ + for (i = 0; i < A->r; i++) + for (j = 0; j < A->c; j++) + if (!fmpq_is_zero(fmpq_mat_entry(A, i, j))) + { + v = fmpz_remove(t, fmpq_mat_entry_num(A, i, j), ctx->p); + w = fmpz_remove(t, fmpq_mat_entry_den(A, i, j), ctx->p); + m = FLINT_MIN(m, v - w); + } + + if (m >= N) + { + padic_mat_zero(B); + } + else + { + for (i = 0; i < A->r; i++) + for (j = 0; j < A->c; j++) + if (fmpq_is_zero(fmpq_mat_entry(A, i, j))) + { + fmpz_zero(padic_mat_entry(B, i, j)); + } + else + { + v = fmpz_remove(s, fmpq_mat_entry_num(A, i, j), ctx->p); + w = fmpz_remove(t, fmpq_mat_entry_den(A, i, j), ctx->p); + if (v - w >= N) + { + fmpz_zero(padic_mat_entry(B, i, j)); + } + else + { + fmpz_pow_ui(f, ctx->p, (v - w) - m); + fmpz_pow_ui(g, ctx->p, N - (v - w)); + _padic_inv(t, t, ctx->p, N - (v - w)); + fmpz_mul(padic_mat_entry(B, i, j), s, t); + fmpz_mod(padic_mat_entry(B, i, j), padic_mat_entry(B, i, j), g); + fmpz_mul(padic_mat_entry(B, i, j), padic_mat_entry(B, i, j), f); + } + } + padic_mat_val(B) = m; + } + + fmpz_clear(f); + fmpz_clear(g); + fmpz_clear(s); + fmpz_clear(t); + } +} + diff --git a/external/flint-2.4.3/padic_mat/sub.c b/external/flint-2.4.3/padic_mat/sub.c new file mode 100644 index 0000000..f06bb65 --- /dev/null +++ b/external/flint-2.4.3/padic_mat/sub.c @@ -0,0 +1,121 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2013 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_mat.h" +#include "padic_mat.h" + +/* + Assumptions: + + o That the matrix dimensions be compatible. + o That the matrices be non-empty. + o That ord_p(A) >= ord_p(B). + */ + +void _padic_mat_sub(padic_mat_t C, const padic_mat_t A, const padic_mat_t B, + const padic_ctx_t ctx) +{ + if (padic_mat_is_zero(A)) + { + padic_mat_neg(C, B, ctx); + return; + } + if (padic_mat_is_zero(B)) + { + padic_mat_set(C, A, ctx); + return; + } + if (FLINT_MIN(padic_mat_val(A), padic_mat_val(B)) >= padic_mat_prec(C)) + { + padic_mat_zero(C); + return; + } + + if (padic_mat_val(A) == padic_mat_val(B)) + { + fmpz_mat_sub(padic_mat(C), padic_mat(A), padic_mat(B)); + padic_mat_val(C) = padic_mat_val(A); + _padic_mat_canonicalise(C, ctx); + } + else + { + fmpz_t x; + fmpz_init(x); + + if (padic_mat_val(A) < padic_mat_val(B)) + { + fmpz_pow_ui(x, ctx->p, padic_mat_val(B) - padic_mat_val(A)); + + if (C == A) + { + fmpz_mat_scalar_submul_fmpz(padic_mat(C), padic_mat(B), x); + } + else if (C == B) + { + fmpz_neg(x, x); + fmpz_mat_scalar_mul_fmpz(padic_mat(C), padic_mat(B), x); + fmpz_mat_add(padic_mat(C), padic_mat(A), padic_mat(C)); + padic_mat_val(C) = padic_mat_val(A); + } + else + { + fmpz_mat_set(padic_mat(C), padic_mat(A)); + fmpz_mat_scalar_submul_fmpz(padic_mat(C), padic_mat(B), x); + padic_mat_val(C) = padic_mat_val(A); + } + } + else /* A->val > B->val */ + { + fmpz_pow_ui(x, ctx->p, padic_mat_val(A) - padic_mat_val(B)); + + if (C == B) + { + fmpz_mat_scalar_submul_fmpz(padic_mat(C), padic_mat(A), x); + fmpz_mat_neg(padic_mat(C), padic_mat(C)); + } + else + { + fmpz_mat_scalar_mul_fmpz(padic_mat(C), padic_mat(A), x); + fmpz_mat_sub(padic_mat(C), padic_mat(C), padic_mat(B)); + padic_mat_val(C) = padic_mat_val(B); + } + } + fmpz_clear(x); + } + +} + +void padic_mat_sub(padic_mat_t C, const padic_mat_t A, const padic_mat_t B, + const padic_ctx_t ctx) +{ + if (padic_mat_is_empty(C)) + { + return; + } + + _padic_mat_sub(C, A, B, ctx); + _padic_mat_reduce(C, ctx); +} + diff --git a/external/flint-2.4.3/padic_mat/swap.c b/external/flint-2.4.3/padic_mat/swap.c new file mode 100644 index 0000000..637447c --- /dev/null +++ b/external/flint-2.4.3/padic_mat/swap.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_mat.h" +#include "padic_mat.h" + +void padic_mat_swap(padic_mat_t A, padic_mat_t B) +{ + slong t; + + fmpz_mat_swap(padic_mat(A), padic_mat(B)); + + t = A->val; + A->val = B->val; + B->val = t; +} + diff --git a/external/flint-2.4.3/padic_mat/test/t-add.c b/external/flint-2.4.3/padic_mat/test/t-add.c new file mode 100644 index 0000000..0970553 --- /dev/null +++ b/external/flint-2.4.3/padic_mat/test/t-add.c @@ -0,0 +1,259 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2013 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "long_extras.h" +#include "padic.h" +#include "padic_mat.h" + +int main(void) +{ + int i, result; + + fmpz_t p; + slong N; + padic_ctx_t ctx; + slong m, n; + + FLINT_TEST_INIT(state); + + flint_printf("add... "); + fflush(stdout); + + /* Check aliasing: a = a + b */ + for (i = 0; i < 10000; i++) + { + padic_mat_t a, b, d; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_VAL_UNIT); + + m = n_randint(state, 20); + n = n_randint(state, 20); + + padic_mat_init2(a, m, n, N); + padic_mat_init2(b, m, n, N); + padic_mat_init2(d, m, n, N); + + padic_mat_randtest(a, state, ctx); + padic_mat_randtest(b, state, ctx); + + padic_mat_add(d, a, b, ctx); + padic_mat_add(a, a, b, ctx); + + result = (padic_mat_equal(a, d) && padic_mat_is_reduced(a, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), padic_mat_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_mat_print(b, ctx), flint_printf("\n"); + flint_printf("d = "), padic_mat_print(d, ctx), flint_printf("\n"); + abort(); + } + + padic_mat_clear(a); + padic_mat_clear(b); + padic_mat_clear(d); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Check aliasing: b = a + b */ + for (i = 0; i < 10000; i++) + { + padic_mat_t a, b, d; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_VAL_UNIT); + + m = n_randint(state, 20); + n = n_randint(state, 20); + + padic_mat_init2(a, m, n, N); + padic_mat_init2(b, m, n, N); + padic_mat_init2(d, m, n, N); + + padic_mat_randtest(a, state, ctx); + padic_mat_randtest(b, state, ctx); + + padic_mat_add(d, a, b, ctx); + padic_mat_add(b, a, b, ctx); + + result = (padic_mat_equal(b, d) && padic_mat_is_reduced(b, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), padic_mat_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_mat_print(b, ctx), flint_printf("\n"); + flint_printf("d = "), padic_mat_print(d, ctx), flint_printf("\n"); + abort(); + } + + padic_mat_clear(a); + padic_mat_clear(b); + padic_mat_clear(d); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Check aliasing: a = a + a */ + for (i = 0; i < 10000; i++) + { + padic_mat_t a, b, c; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_VAL_UNIT); + + m = n_randint(state, 20); + n = n_randint(state, 20); + + padic_mat_init2(a, m, n, N); + padic_mat_init2(b, m, n, N); + padic_mat_init2(c, m, n, N); + + padic_mat_randtest(a, state, ctx); + padic_mat_set(b, a, ctx); + + padic_mat_add(c, b, b, ctx); + padic_mat_add(b, b, b, ctx); + + result = (padic_mat_equal(b, c) && padic_mat_is_reduced(b, ctx)); + if (!result) + { + flint_printf("FAIL (alias b = b + b):\n\n"); + flint_printf("a = "), padic_mat_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_mat_print(b, ctx), flint_printf("\n"); + flint_printf("c = "), padic_mat_print(c, ctx), flint_printf("\n"); + flint_printf("N = %wd\n", N); + flint_printf("p = "), fmpz_print(p), flint_printf("\n"); + abort(); + } + + padic_mat_clear(a); + padic_mat_clear(b); + padic_mat_clear(c); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Check commutativity: a + b == b + a */ + for (i = 0; i < 10000; i++) + { + padic_mat_t a, b, c, d; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_VAL_UNIT); + + m = n_randint(state, 10); + n = n_randint(state, 10); + + padic_mat_init2(a, m, n, N); + padic_mat_init2(b, m, n, N); + padic_mat_init2(c, m, n, N); + padic_mat_init2(d, m, n, N); + + padic_mat_randtest(a, state, ctx); + padic_mat_randtest(b, state, ctx); + + padic_mat_add(c, a, b, ctx); + padic_mat_add(d, b, a, ctx); + + result = (padic_mat_equal(c, d) && padic_mat_is_reduced(c, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), padic_mat_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_mat_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), padic_mat_print_pretty(c, ctx), flint_printf("\n"); + flint_printf("d = "), padic_mat_print_pretty(d, ctx), flint_printf("\n"); + abort(); + } + + padic_mat_clear(a); + padic_mat_clear(b); + padic_mat_clear(c); + padic_mat_clear(d); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Check zero element: a + 0 == a */ + for (i = 0; i < 10000; i++) + { + padic_mat_t a, b; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_VAL_UNIT); + + m = n_randint(state, 20); + n = n_randint(state, 20); + + padic_mat_init2(a, m, n, N); + padic_mat_init2(b, m, n, N); + + padic_mat_randtest(a, state, ctx); + + padic_mat_add(b, a, b, ctx); + + result = (padic_mat_equal(a, b) && padic_mat_is_canonical(a, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), padic_mat_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_mat_print(b, ctx), flint_printf("\n"); + abort(); + } + + padic_mat_clear(a); + padic_mat_clear(b); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/padic_mat/test/t-get_set_entry_padic.c b/external/flint-2.4.3/padic_mat/test/t-get_set_entry_padic.c new file mode 100644 index 0000000..1fbba57 --- /dev/null +++ b/external/flint-2.4.3/padic_mat/test/t-get_set_entry_padic.c @@ -0,0 +1,100 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "long_extras.h" +#include "padic.h" +#include "padic_mat.h" + +int +main(void) +{ + int i, result; + + fmpz_t p; + slong N; + padic_ctx_t ctx; + slong m, n; + + FLINT_TEST_INIT(state); + + flint_printf("get/ set_entry_padic... "); + fflush(stdout); + + for (i = 0; i < 10000; i++) + { + padic_mat_t a; + padic_t x, y; + slong r, c; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + m = n_randint(state, 20) + 1; + n = n_randint(state, 20) + 1; + + padic_mat_init2(a, m, n, N); + padic_init2(x, N); + padic_init2(y, N); + + padic_mat_randtest(a, state, ctx); + padic_randtest_not_zero(x, state, ctx); + + r = n_randint(state, m); + c = n_randint(state, n); + + padic_mat_set_entry_padic(a, r, c, x, ctx); + padic_mat_get_entry_padic(y, a, r, c, ctx); + + result = (padic_equal(x, y) && padic_mat_is_reduced(a, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), padic_mat_print(a, ctx), flint_printf("\n"); + flint_printf("x = "), padic_print(x, ctx), flint_printf("\n"); + flint_printf("y = "), padic_print(y, ctx), flint_printf("\n"); + abort(); + } + + padic_mat_clear(a); + padic_clear(x); + padic_clear(y); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/padic_mat/test/t-get_set_fmpq_mat.c b/external/flint-2.4.3/padic_mat/test/t-get_set_fmpq_mat.c new file mode 100644 index 0000000..26ffdbb --- /dev/null +++ b/external/flint-2.4.3/padic_mat/test/t-get_set_fmpq_mat.c @@ -0,0 +1,96 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012, 2013 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "long_extras.h" +#include "padic.h" +#include "padic_mat.h" + +int +main(void) +{ + int i, result; + + fmpz_t p; + slong N; + padic_ctx_t ctx; + slong m, n; + + FLINT_TEST_INIT(state); + + flint_printf("get/ set_fmpq_mat... "); + fflush(stdout); + + /* Qp -> QQ -> Qp */ + for (i = 0; i < 1000; i++) + { + padic_mat_t a, c; + fmpq_mat_t b; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + m = n_randint(state, 10); + n = n_randint(state, 10); + + padic_mat_init2(a, m, n, N); + padic_mat_init2(c, m, n, N); + fmpq_mat_init(b, m, n); + + padic_mat_randtest(a, state, ctx); + padic_mat_get_fmpq_mat(b, a, ctx); + padic_mat_set_fmpq_mat(c, b, ctx); + + result = (padic_mat_equal(a, c) && padic_mat_is_reduced(a, ctx)); + + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), padic_mat_print(a, ctx), flint_printf("\n"); + flint_printf("c = "), padic_mat_print(c, ctx), flint_printf("\n"); + flint_printf("b = "), fmpq_mat_print(b), flint_printf("\n"); + abort(); + } + + padic_mat_clear(a); + padic_mat_clear(c); + fmpq_mat_clear(b); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/padic_mat/test/t-mul.c b/external/flint-2.4.3/padic_mat/test/t-mul.c new file mode 100644 index 0000000..c5d6e47 --- /dev/null +++ b/external/flint-2.4.3/padic_mat/test/t-mul.c @@ -0,0 +1,358 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2013 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "long_extras.h" +#include "padic.h" +#include "padic_mat.h" + +int +main(void) +{ + int i, result; + + fmpz_t p; + slong N; + padic_ctx_t ctx; + slong m, n; + + FLINT_TEST_INIT(state); + + flint_printf("mul... "); + fflush(stdout); + + /* Check aliasing: a = a * b */ + for (i = 0; i < 1000; i++) + { + padic_mat_t a, b, d; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_VAL_UNIT); + + m = n_randint(state, 10); + n = m; + + padic_mat_init2(a, m, n, N); + padic_mat_init2(b, m, n, N); + padic_mat_init2(d, m, n, N); + + padic_mat_randtest(a, state, ctx); + padic_mat_randtest(b, state, ctx); + + padic_mat_mul(d, a, b, ctx); + padic_mat_mul(a, a, b, ctx); + + result = (padic_mat_equal(a, d) && padic_mat_is_reduced(a, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), padic_mat_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_mat_print(b, ctx), flint_printf("\n"); + flint_printf("d = "), padic_mat_print(d, ctx), flint_printf("\n"); + abort(); + } + + padic_mat_clear(a); + padic_mat_clear(b); + padic_mat_clear(d); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Check aliasing: b = a * b */ + for (i = 0; i < 1000; i++) + { + padic_mat_t a, b, d; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_VAL_UNIT); + + m = n_randint(state, 10); + n = m; + + padic_mat_init2(a, m, n, N); + padic_mat_init2(b, m, n, N); + padic_mat_init2(d, m, n, N); + + padic_mat_randtest(a, state, ctx); + padic_mat_randtest(b, state, ctx); + + padic_mat_mul(d, a, b, ctx); + padic_mat_mul(b, a, b, ctx); + + result = (padic_mat_equal(b, d) && padic_mat_is_reduced(b, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), padic_mat_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_mat_print(b, ctx), flint_printf("\n"); + flint_printf("d = "), padic_mat_print(d, ctx), flint_printf("\n"); + abort(); + } + + padic_mat_clear(a); + padic_mat_clear(b); + padic_mat_clear(d); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Check aliasing: a = a * a */ + for (i = 0; i < 1000; i++) + { + padic_mat_t a, d; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_VAL_UNIT); + + m = n_randint(state, 10); + n = m; + + padic_mat_init2(a, m, n, N); + padic_mat_init2(d, m, n, N); + + padic_mat_randtest(a, state, ctx); + + padic_mat_mul(d, a, a, ctx); + padic_mat_mul(a, a, a, ctx); + + result = (padic_mat_equal(a, d) && padic_mat_is_reduced(a, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), padic_mat_print(a, ctx), flint_printf("\n"); + flint_printf("d = "), padic_mat_print(d, ctx), flint_printf("\n"); + abort(); + } + + padic_mat_clear(a); + padic_mat_clear(d); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Check identity: a * Id == a, for N > 0 */ + for (i = 0; i < 1000; i++) + { + padic_mat_t a, b; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + N = FLINT_MAX(1, N); + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_VAL_UNIT); + + padic_mat_init2(a, m, n, N); + padic_mat_init2(b, m, n, N); + + padic_mat_randtest(a, state, ctx); + + padic_mat_one(b); + padic_mat_mul(b, a, b, ctx); + + result = (padic_mat_equal(a, b) && padic_mat_is_reduced(a, ctx)); + if (!result) + { + flint_printf("FAIL (A * Id == A):\n\n"); + flint_printf("a = "), padic_mat_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_mat_print(b, ctx), flint_printf("\n"); + flint_printf("p = "), fmpz_print(p), flint_printf("\n"); + flint_printf("N = %wd\n", N); + abort(); + } + + padic_mat_clear(a); + padic_mat_clear(b); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Check associativity: (a*b)*c == a*(b*c) mod p^{N-v} */ + for (i = 0; i < 1000; i++) + { + padic_mat_t a, b, c, d, e, t1, t2; + slong k, l, v; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_VAL_UNIT); + + k = n_randint(state, 10); + l = n_randint(state, 10); + m = n_randint(state, 10); + n = n_randint(state, 10); + + padic_mat_init2(a, k, l, N); + padic_mat_init2(b, l, m, N); + padic_mat_init2(c, m, n, N); + + padic_mat_randtest(a, state, ctx); + padic_mat_randtest(b, state, ctx); + padic_mat_randtest(c, state, ctx); + + /* v = min(val(a), val(b), val(c), 0) */ + v = FLINT_MIN(padic_mat_val(a), padic_mat_val(b)); + v = FLINT_MIN(v, padic_mat_val(c)); + v = FLINT_MIN(v, 0); + + if ((v >= 0) || (-v < N)) /* Otherwise, no precision left */ + { + slong N2 = (v >= 0) ? N : N + v; + + padic_mat_init2(d, k, n, N2); + padic_mat_init2(e, k, n, N2); + padic_mat_init2(t1, k, m, N); + padic_mat_init2(t2, l, n, N); + + padic_mat_mul(t1, a, b, ctx); + padic_mat_mul(d, t1, c, ctx); + padic_mat_mul(t2, b, c, ctx); + padic_mat_mul(e, a, t2, ctx); + + result = (padic_mat_equal(d, e) && padic_mat_is_reduced(d, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), padic_mat_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_mat_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), padic_mat_print_pretty(c, ctx), flint_printf("\n"); + flint_printf("d = "), padic_mat_print_pretty(d, ctx), flint_printf("\n"); + flint_printf("e = "), padic_mat_print_pretty(e, ctx), flint_printf("\n"); + flint_printf("t1 = "), padic_mat_print_pretty(t1, ctx), flint_printf("\n"); + flint_printf("t2 = "), padic_mat_print_pretty(t2, ctx), flint_printf("\n"); + abort(); + } + + padic_mat_clear(d); + padic_mat_clear(e); + padic_mat_clear(t1); + padic_mat_clear(t2); + } + + padic_mat_clear(a); + padic_mat_clear(b); + padic_mat_clear(c); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Check distributivity: a(b + c) == ab + ac, precision loss */ + for (i = 0; i < 1000; i++) + { + padic_mat_t a, b, c; + slong l; + slong v; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_VAL_UNIT); + + l = n_randint(state, 10); + m = n_randint(state, 10); + n = n_randint(state, 10); + + padic_mat_init2(a, l, m, N); + padic_mat_init2(b, m, n, N); + padic_mat_init2(c, m, n, N); + + padic_mat_randtest(a, state, ctx); + padic_mat_randtest(b, state, ctx); + padic_mat_randtest(c, state, ctx); + + v = FLINT_MIN(a->val, b->val); + v = FLINT_MIN(v, c->val); + v = FLINT_MIN(v, 0); + + if (v >= 0 || -v < N) /* Otherwise, no precision left */ + { + slong N2 = (v >= 0) ? N : N + v; + + padic_mat_t lhs, rhs, s, t; + + padic_mat_init2(lhs, l, n, N2); + padic_mat_init2(rhs, l, n, N2); + padic_mat_init2(s, m, n, N); + padic_mat_init2(t, l, n, N2); + + padic_mat_add(s, b, c, ctx); + padic_mat_mul(lhs, a, s, ctx); + + padic_mat_mul(rhs, a, b, ctx); + padic_mat_mul(t, a, c, ctx); + padic_mat_add(rhs, rhs, t, ctx); + + result = (padic_mat_equal(lhs, rhs) && padic_mat_is_reduced(lhs, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("Hier...\n"); + flint_printf("l m n = %wd %wd %wd\n", l, m, n); + flint_printf("N = %wd\n", N); + flint_printf("N2 = %wd\n", N2); + flint_printf("a = "), padic_mat_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_mat_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), padic_mat_print_pretty(c, ctx), flint_printf("\n"); + flint_printf("lhs = "), padic_mat_print_pretty(lhs, ctx), flint_printf("\n"); + flint_printf("rhs = "), padic_mat_print_pretty(rhs, ctx), flint_printf("\n"); + abort(); + } + + padic_mat_clear(lhs); + padic_mat_clear(rhs); + padic_mat_clear(s); + padic_mat_clear(t); + } + + padic_mat_clear(a); + padic_mat_clear(b); + padic_mat_clear(c); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/padic_mat/test/t-neg.c b/external/flint-2.4.3/padic_mat/test/t-neg.c new file mode 100644 index 0000000..8c758da --- /dev/null +++ b/external/flint-2.4.3/padic_mat/test/t-neg.c @@ -0,0 +1,132 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2013 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "long_extras.h" +#include "padic.h" +#include "padic_mat.h" + +int +main(void) +{ + int i, result; + + fmpz_t p; + slong N; + padic_ctx_t ctx; + slong m, n; + + FLINT_TEST_INIT(state); + + flint_printf("neg... "); + fflush(stdout); + + /* Check aliasing */ + for (i = 0; i < 10000; i++) + { + padic_mat_t a, b; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + m = n_randint(state, 20); + n = n_randint(state, 20); + + padic_mat_init2(a, m, n, N); + padic_mat_init2(b, m, n, N); + + padic_mat_randtest(a, state, ctx); + + padic_mat_neg(b, a, ctx); + padic_mat_neg(a, a, ctx); + + result = (padic_mat_equal(a, b) && padic_mat_is_reduced(a, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), padic_mat_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_mat_print(b, ctx), flint_printf("\n"); + abort(); + } + + padic_mat_clear(a); + padic_mat_clear(b); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Check a + (-a) == 0 */ + for (i = 0; i < 10000; i++) + { + padic_mat_t a, b, c; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + m = n_randint(state, 20); + n = n_randint(state, 20); + + padic_mat_init2(a, m, n, N); + padic_mat_init2(b, m, n, N); + padic_mat_init2(c, m, n, N); + + padic_mat_randtest(a, state, ctx); + + padic_mat_neg(b, a, ctx); + padic_mat_add(c, a, b, ctx); + + result = (padic_mat_is_zero(c) && padic_mat_is_reduced(c, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), padic_mat_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_mat_print(b, ctx), flint_printf("\n"); + flint_printf("c = "), padic_mat_print(c, ctx), flint_printf("\n"); + abort(); + } + + padic_mat_clear(a); + padic_mat_clear(b); + padic_mat_clear(c); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/padic_mat/test/t-scalar_div_fmpz.c b/external/flint-2.4.3/padic_mat/test/t-scalar_div_fmpz.c new file mode 100644 index 0000000..cfd9641 --- /dev/null +++ b/external/flint-2.4.3/padic_mat/test/t-scalar_div_fmpz.c @@ -0,0 +1,97 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "long_extras.h" +#include "padic.h" +#include "padic_mat.h" + +int +main(void) +{ + int i, result; + + fmpz_t p; + slong N; + padic_ctx_t ctx; + slong m, n; + + FLINT_TEST_INIT(state); + + flint_printf("scalar_div_fmpz... "); + fflush(stdout); + + /* Check aliasing */ + for (i = 0; i < 10000; i++) + { + padic_mat_t a, b; + fmpz_t x; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + m = n_randint(state, 20); + n = n_randint(state, 20); + + padic_mat_init2(a, m, n, N); + padic_mat_init2(b, m, n, N); + fmpz_init(x); + + padic_mat_randtest(a, state, ctx); + fmpz_randtest_not_zero(x, state, 10); + + padic_mat_scalar_div_fmpz(b, a, x, ctx); + padic_mat_scalar_div_fmpz(a, a, x, ctx); + + result = (padic_mat_equal(a, b) && padic_mat_is_reduced(a, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), padic_mat_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_mat_print(b, ctx), flint_printf("\n"); + flint_printf("x = "), fmpz_print(x), flint_printf("\n"); + abort(); + } + + padic_mat_clear(a); + padic_mat_clear(b); + fmpz_clear(x); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/padic_mat/test/t-scalar_mul_fmpz.c b/external/flint-2.4.3/padic_mat/test/t-scalar_mul_fmpz.c new file mode 100644 index 0000000..2913005 --- /dev/null +++ b/external/flint-2.4.3/padic_mat/test/t-scalar_mul_fmpz.c @@ -0,0 +1,97 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "long_extras.h" +#include "padic.h" +#include "padic_mat.h" + +int +main(void) +{ + int i, result; + + fmpz_t p; + slong N; + padic_ctx_t ctx; + slong m, n; + + FLINT_TEST_INIT(state); + + flint_printf("scalar_mul_fmpz... "); + fflush(stdout); + + /* Check aliasing */ + for (i = 0; i < 10000; i++) + { + padic_mat_t a, b; + fmpz_t x; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + m = n_randint(state, 20); + n = n_randint(state, 20); + + padic_mat_init2(a, m, n, N); + padic_mat_init2(b, m, n, N); + fmpz_init(x); + + padic_mat_randtest(a, state, ctx); + fmpz_randtest(x, state, 10); + + padic_mat_scalar_mul_fmpz(b, a, x, ctx); + padic_mat_scalar_mul_fmpz(a, a, x, ctx); + + result = (padic_mat_equal(a, b) && padic_mat_is_reduced(a, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), padic_mat_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_mat_print(b, ctx), flint_printf("\n"); + flint_printf("x = "), fmpz_print(x), flint_printf("\n"); + abort(); + } + + padic_mat_clear(a); + padic_mat_clear(b); + fmpz_clear(x); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/padic_mat/test/t-scalar_mul_padic.c b/external/flint-2.4.3/padic_mat/test/t-scalar_mul_padic.c new file mode 100644 index 0000000..15a340b --- /dev/null +++ b/external/flint-2.4.3/padic_mat/test/t-scalar_mul_padic.c @@ -0,0 +1,97 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "long_extras.h" +#include "padic.h" +#include "padic_mat.h" + +int +main(void) +{ + int i, result; + + fmpz_t p; + slong N; + padic_ctx_t ctx; + slong m, n; + + FLINT_TEST_INIT(state); + + flint_printf("scalar_mul_padic... "); + fflush(stdout); + + /* Check aliasing */ + for (i = 0; i < 10000; i++) + { + padic_mat_t a, b; + padic_t x; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + m = n_randint(state, 20); + n = n_randint(state, 20); + + padic_mat_init2(a, m, n, N); + padic_mat_init2(b, m, n, N); + padic_init2(x, N); + + padic_mat_randtest(a, state, ctx); + padic_randtest(x, state, ctx); + + padic_mat_scalar_mul_padic(b, a, x, ctx); + padic_mat_scalar_mul_padic(a, a, x, ctx); + + result = (padic_mat_equal(a, b) && padic_mat_is_reduced(a, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), padic_mat_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_mat_print(b, ctx), flint_printf("\n"); + flint_printf("x = "), padic_print(x, ctx), flint_printf("\n"); + abort(); + } + + padic_mat_clear(a); + padic_mat_clear(b); + padic_clear(x); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/padic_mat/test/t-sub.c b/external/flint-2.4.3/padic_mat/test/t-sub.c new file mode 100644 index 0000000..0e23005 --- /dev/null +++ b/external/flint-2.4.3/padic_mat/test/t-sub.c @@ -0,0 +1,255 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2013 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "long_extras.h" +#include "padic.h" +#include "padic_mat.h" + +int +main(void) +{ + int i, result; + + fmpz_t p; + slong N; + padic_ctx_t ctx; + slong m, n; + + FLINT_TEST_INIT(state); + + flint_printf("sub... "); + fflush(stdout); + + /* Check aliasing: a = a - b */ + for (i = 0; i < 10000; i++) + { + padic_mat_t a, b, d; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + m = n_randint(state, 20); + n = n_randint(state, 20); + + padic_mat_init2(a, m, n, N); + padic_mat_init2(b, m, n, N); + padic_mat_init2(d, m, n, N); + + padic_mat_randtest(a, state, ctx); + padic_mat_randtest(b, state, ctx); + + padic_mat_sub(d, a, b, ctx); + padic_mat_sub(a, a, b, ctx); + + result = (padic_mat_equal(a, d) && padic_mat_is_reduced(a, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), padic_mat_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_mat_print(b, ctx), flint_printf("\n"); + flint_printf("d = "), padic_mat_print(d, ctx), flint_printf("\n"); + abort(); + } + + padic_mat_clear(a); + padic_mat_clear(b); + padic_mat_clear(d); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Check aliasing: b = a - b */ + for (i = 0; i < 10000; i++) + { + padic_mat_t a, b, d; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + m = n_randint(state, 20); + n = n_randint(state, 20); + + padic_mat_init2(a, m, n, N); + padic_mat_init2(b, m, n, N); + padic_mat_init2(d, m, n, N); + + padic_mat_randtest(a, state, ctx); + padic_mat_randtest(b, state, ctx); + + padic_mat_sub(d, a, b, ctx); + padic_mat_sub(b, a, b, ctx); + + result = (padic_mat_equal(b, d) && padic_mat_is_reduced(b, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), padic_mat_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_mat_print(b, ctx), flint_printf("\n"); + flint_printf("d = "), padic_mat_print(d, ctx), flint_printf("\n"); + abort(); + } + + padic_mat_clear(a); + padic_mat_clear(b); + padic_mat_clear(d); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Check aliasing: a = a - a == 0 */ + for (i = 0; i < 10000; i++) + { + padic_mat_t a, d; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + m = n_randint(state, 20); + n = n_randint(state, 20); + + padic_mat_init2(a, m, n, N); + padic_mat_init2(d, m, n, N); + + padic_mat_randtest(a, state, ctx); + + padic_mat_sub(d, a, a, ctx); + padic_mat_sub(a, a, a, ctx); + + result = (padic_mat_equal(a, d) && padic_mat_is_zero(a)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), padic_mat_print(a, ctx), flint_printf("\n"); + flint_printf("d = "), padic_mat_print(d, ctx), flint_printf("\n"); + abort(); + } + + padic_mat_clear(a); + padic_mat_clear(d); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Check commutativity: a - b == -(b - a) */ + for (i = 0; i < 10000; i++) + { + padic_mat_t a, b, c, d; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + m = n_randint(state, 10); + n = n_randint(state, 10); + + padic_mat_init2(a, m, n, N); + padic_mat_init2(b, m, n, N); + padic_mat_init2(c, m, n, N); + padic_mat_init2(d, m, n, N); + + padic_mat_randtest(a, state, ctx); + padic_mat_randtest(b, state, ctx); + + padic_mat_sub(c, a, b, ctx); + padic_mat_sub(d, b, a, ctx); + padic_mat_neg(d, d, ctx); + + result = (padic_mat_equal(c, d) && padic_mat_is_reduced(c, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), padic_mat_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_mat_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), padic_mat_print_pretty(c, ctx), flint_printf("\n"); + flint_printf("d = "), padic_mat_print_pretty(d, ctx), flint_printf("\n"); + abort(); + } + + padic_mat_clear(a); + padic_mat_clear(b); + padic_mat_clear(c); + padic_mat_clear(d); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Check a - 0 == a */ + for (i = 0; i < 10000; i++) + { + padic_mat_t a, b; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + m = n_randint(state, 20); + n = n_randint(state, 20); + + padic_mat_init2(a, m, n, N); + padic_mat_init2(b, m, n, N); + + padic_mat_randtest(a, state, ctx); + + padic_mat_sub(b, a, b, ctx); + + result = (padic_mat_equal(a, b) && padic_mat_is_reduced(a, ctx)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), padic_mat_print(a, ctx), flint_printf("\n"); + flint_printf("b = "), padic_mat_print(b, ctx), flint_printf("\n"); + abort(); + } + + padic_mat_clear(a); + padic_mat_clear(b); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/padic_mat/transpose.c b/external/flint-2.4.3/padic_mat/transpose.c new file mode 100644 index 0000000..118be3d --- /dev/null +++ b/external/flint-2.4.3/padic_mat/transpose.c @@ -0,0 +1,34 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_mat.h" +#include "padic_mat.h" + +void padic_mat_transpose(padic_mat_t B, const padic_mat_t A) +{ + fmpz_mat_transpose(padic_mat(B), padic_mat(A)); + B->val = A->val; +} + diff --git a/external/flint-2.4.3/padic_mat/zero.c b/external/flint-2.4.3/padic_mat/zero.c new file mode 100644 index 0000000..8aa46fe --- /dev/null +++ b/external/flint-2.4.3/padic_mat/zero.c @@ -0,0 +1,34 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_mat.h" +#include "padic_mat.h" + +void padic_mat_zero(padic_mat_t A) +{ + fmpz_mat_zero(padic_mat(A)); + A->val = 0; +} + diff --git a/external/flint-2.4.3/padic_matxx.h b/external/flint-2.4.3/padic_matxx.h new file mode 100644 index 0000000..4b92b25 --- /dev/null +++ b/external/flint-2.4.3/padic_matxx.h @@ -0,0 +1,349 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#ifndef PADIC_MATXX_H +#define PADIC_MATXX_H + +#include "padic_mat.h" + +#include "padicxx.h" +#include "fmpq_matxx.h" + +#include "flintxx/matrix.h" + +// TODO input and output + +namespace flint { +FLINT_DEFINE_THREEARY(padic_matxx_get_entry) + +namespace detail { +template +struct padic_mat_traits + : matrices::generic_traits +{ + typedef slong prec_ref_t; + typedef slong prec_srcref_t; + + typedef slong val_ref_t; + typedef slong val_srcref_t; + + static slong prec(const Padic& p) {return tools::padic_output_prec(p);} + static slong val(const Padic& p) {return padic_mat_val(p.evaluate()._mat());} +}; +} //detail + +template +class padic_matxx_expression + : public expression, Operation, Data> +{ +public: + typedef expression, + Operation, Data> base_t; + + FLINTXX_DEFINE_BASICS(padic_matxx_expression) + FLINTXX_DEFINE_CTORS(padic_matxx_expression) + FLINTXX_DEFINE_C_REF(padic_matxx_expression, padic_mat_struct, _mat) + +public: + typedef detail::padic_mat_traits traits_t; + + PADICXX_DEFINE_STD + + static padic_matxx_expression zero(padicxx_ctx_srcref ctx, + slong rows, slong cols) + {return padic_matxx_expression(ctx, rows, cols);} + static padic_matxx_expression zero(padicxx_ctx_srcref ctx, + slong rows, slong cols, slong N) + {return padic_matxx_expression(ctx, rows, cols, N);} + + static padic_matxx_expression one(padicxx_ctx_srcref ctx, + slong rows, slong cols) + { + padic_matxx_expression res(ctx, rows, cols); + res.set_one(); + return res; + } + static padic_matxx_expression one(padicxx_ctx_srcref ctx, + slong rows, slong cols, slong N) + { + padic_matxx_expression res(ctx, rows, cols, N); + res.set_one(); + return res; + } + + template + static padic_matxx_expression from_QQ(const T& q, padicxx_ctx_srcref ctx, + typename mp::enable_if >::type* = 0) + { + padic_matxx_expression res(ctx, q.rows(), q.cols()); + res = q; + return res; + } + template + static padic_matxx_expression from_QQ(const T& q, padicxx_ctx_srcref ctx, + slong N, + typename mp::enable_if >::type* = 0) + { + padic_matxx_expression res(ctx, q.rows(), q.cols(), N); + res = q; + return res; + } + + template + static evaluated_t create_temporary_rowscols( + const Expr& e, slong rows, slong cols) + { + return evaluated_t(tools::find_padicxx_ctx(e), + rows, cols, tools::padic_output_prec(e)); + } + FLINTXX_DEFINE_MATRIX_METHODS(traits_t) + + // static methods which only make sense with padicxx + static padic_matxx_expression randtest(slong rows, slong cols, + frandxx& state, + padicxx_ctx_srcref ctx, slong prec = PADIC_DEFAULT_PREC) + { + padic_matxx_expression res(ctx, rows, cols, prec); + padic_mat_randtest(res._mat(), state._data(), ctx._ctx()); + return res; + } + + // These only make sense with immediates + void reduce() {padic_mat_reduce(_mat(), _ctx());} + void set_zero() {padic_mat_zero(_mat());} + void set_one() {padic_mat_one(_mat());} + void truncate(slong n) {fmpz_poly_truncate(_mat(), n);} + void canonicalise() {padic_mat_canonicalise(_mat());} + bool is_canonical() const {return padic_mat_is_canonical(_mat());} + bool is_reduced() const {return padic_mat_is_reduced(_mat());} + + template + void set_entry(slong i, slong j, const Padic& p, + typename mp::enable_if >::type* = 0) + { + padic_mat_set_entry_padic(_mat(), i, j, p.evaluate()._padic(), _ctx()); + } + + // these cause evaluation + bool is_zero() const {return padic_mat_is_zero(this->evaluate()._mat());} + bool is_empty() const {return padic_mat_is_empty(this->evaluate()._mat());} + bool is_square() const {return padic_mat_is_square(this->evaluate()._mat());} + + // forwarding of lazy functions + FLINTXX_DEFINE_MEMBER_UNOP(transpose) + FLINTXX_DEFINE_MEMBER_3OP_(get_entry, padic_matxx_get_entry) +}; + +namespace detail { +struct padic_mat_data; +} + +typedef padic_matxx_expression padic_matxx; +typedef padic_matxx_expression > + padic_matxx_ref; +typedef padic_matxx_expression > padic_matxx_srcref; + +template<> +struct matrix_traits +{ + template static slong rows(const M& m) + { + return padic_mat_nrows(m._mat()); + } + template static slong cols(const M& m) + { + return padic_mat_ncols(m._mat()); + } + + template static fmpzxx_srcref at(const M& m, slong i, slong j) + { + return fmpzxx_srcref::make(padic_mat_entry(m._mat(), i, j)); + } + template static fmpzxx_ref at(M& m, slong i, slong j) + { + return fmpzxx_ref::make(padic_mat_entry(m._mat(), i, j)); + } +}; + +namespace traits { +template<> struct has_padicxx_ctx : mp::true_ { }; +template<> struct has_padicxx_ctx : mp::true_ { }; +template<> struct has_padicxx_ctx : mp::true_ { }; +} // traits + +namespace detail { +struct padic_matxx_srcref_traits_no_std_matrix +{ + typedef slong prec_ref_t; + typedef slong prec_srcref_t; + + typedef slong val_ref_t; + typedef slong val_srcref_t; + + template + static slong prec(P p) {return p._data().N;} + template + static slong val(P p) {return padic_mat_val(p._mat());} +}; +struct padic_matxx_ref_traits_no_std_matrix + : padic_matxx_srcref_traits_no_std_matrix +{ + typedef slong& prec_ref_t; + typedef slong& val_ref_t; + + template + static slong& prec(P& p) {return padic_mat_prec(p._mat());} + template + static slong prec(const P& p) {return padic_mat_prec(p._mat());} + + template + static slong& val(P& p) {return padic_mat_val(p._mat());} + template + static slong val(const P& p) {return padic_mat_val(p._mat());} +}; +template<> +struct padic_mat_traits + : matrices::generic_traits_srcref, + padic_matxx_srcref_traits_no_std_matrix { }; +template<> +struct padic_mat_traits + : matrices::generic_traits_ref, + padic_matxx_ref_traits_no_std_matrix { }; +template<> +struct padic_mat_traits + : matrices::generic_traits_nonref, + padic_matxx_ref_traits_no_std_matrix { }; +} // detail + +PADICXX_DEFINE_REF_STRUCTS(padic_matxx, padic_mat_struct, padic_mat_prec) + +namespace detail { +struct padic_mat_data +{ + typedef padic_mat_t& data_ref_t; + typedef const padic_mat_t& data_srcref_t; + + padicxx_ctx_srcref ctx; + padic_mat_t inner; + + padic_mat_data(padicxx_ctx_srcref c, slong rows, slong cols) + : ctx(c) + { + padic_mat_init(inner, rows, cols); + } + + padic_mat_data(padicxx_ctx_srcref c, slong rows, slong cols, slong N) + : ctx(c) + { + padic_mat_init2(inner, rows, cols, N); + } + + padic_mat_data(const padic_mat_data& o) + : ctx(o.ctx) + { + padic_mat_init2(inner, padic_mat_nrows(o.inner), + padic_mat_ncols(o.inner), padic_mat_prec(o.inner)); + padic_mat_set(inner, o.inner, ctx._ctx()); + } + + ~padic_mat_data() {padic_mat_clear(inner);} + + padic_mat_data(padic_matxx_srcref c) + : ctx(c.get_ctx()) + { + padic_mat_init2(inner, c.rows(), c.cols(), c.prec()); + padic_mat_set(inner, c._mat(), ctx._ctx()); + } +}; +} // detail + +// matrix temporary stuff +FLINTXX_DEFINE_TEMPORARY_RULES(padic_matxx) + +#define PADIC_MATXX_COND_S FLINTXX_COND_S(padic_matxx) +#define PADIC_MATXX_COND_T FLINTXX_COND_T(padic_matxx) + +namespace rules { +FLINT_DEFINE_DOIT_COND2(assignment, PADIC_MATXX_COND_T, PADIC_MATXX_COND_S, + padic_mat_set(to._mat(), from._mat(), to._ctx())) +FLINT_DEFINE_DOIT_COND2(assignment, PADIC_MATXX_COND_T, FMPQ_MATXX_COND_S, + padic_mat_set_fmpq_mat(to._mat(), from._mat(), to._ctx())) + +FLINTXX_DEFINE_SWAP(padic_matxx, padic_mat_swap(e1._mat(), e2._mat())) + +FLINTXX_DEFINE_EQUALS(padic_matxx, padic_mat_equal(e1._mat(), e2._mat())) + +FLINT_DEFINE_PRINT_COND(PADIC_MATXX_COND_S, + padic_mat_fprint(to, from._mat(), from._ctx())) +FLINT_DEFINE_PRINT_PRETTY_COND(PADIC_MATXX_COND_S, + padic_mat_fprint_pretty(to, from._mat(), from._ctx())) + +template +struct conversion >::type> +{ + static fmpq_matxx get(const T& from) + { + fmpq_matxx to(from.rows(), from.cols()); + padic_mat_get_fmpq_mat(to._mat(), from._mat(), from._ctx()); + return to; + } +}; + +FLINT_DEFINE_THREEARY_EXPR_COND3(padic_matxx_get_entry_op, padicxx, + PADIC_MATXX_COND_S, traits::fits_into_slong, traits::fits_into_slong, + padic_mat_get_entry_padic(to._padic(), e1._mat(), e2, e3, to._ctx())) + +FLINT_DEFINE_UNARY_EXPR_COND(transpose_op, padic_matxx, PADIC_MATXX_COND_S, + padic_mat_transpose(to._mat(), from._mat())) + +FLINT_DEFINE_CBINARY_EXPR_COND2(plus, padic_matxx, + PADIC_MATXX_COND_S, PADIC_MATXX_COND_S, + padic_mat_add(to._mat(), e1._mat(), e2._mat(), to._ctx())) +FLINT_DEFINE_BINARY_EXPR_COND2(minus, padic_matxx, + PADIC_MATXX_COND_S, PADIC_MATXX_COND_S, + padic_mat_sub(to._mat(), e1._mat(), e2._mat(), to._ctx())) +FLINT_DEFINE_UNARY_EXPR_COND(negate, padic_matxx, PADIC_MATXX_COND_S, + padic_mat_neg(to._mat(), from._mat(), to._ctx())) + +FLINT_DEFINE_CBINARY_EXPR_COND2(times, padic_matxx, + PADIC_MATXX_COND_S, PADICXX_COND_S, + padic_mat_scalar_mul_padic(to._mat(), e1._mat(), e2._padic(), to._ctx())) +FLINT_DEFINE_CBINARY_EXPR_COND2(times, padic_matxx, + PADIC_MATXX_COND_S, FMPZXX_COND_S, + padic_mat_scalar_mul_fmpz(to._mat(), e1._mat(), e2._fmpz(), to._ctx())) +FLINT_DEFINE_BINARY_EXPR_COND2(divided_by, padic_matxx, + PADIC_MATXX_COND_S, FMPZXX_COND_S, + padic_mat_scalar_div_fmpz(to._mat(), e1._mat(), e2._fmpz(), to._ctx())) +FLINT_DEFINE_CBINARY_EXPR_COND2(times, padic_matxx, + PADIC_MATXX_COND_S, PADIC_MATXX_COND_S, + padic_mat_mul(to._mat(), e1._mat(), e2._mat(), to._ctx())) +} // rules +} + +#endif diff --git a/external/flint-2.4.3/padic_poly.h b/external/flint-2.4.3/padic_poly.h new file mode 100644 index 0000000..4a25b0a --- /dev/null +++ b/external/flint-2.4.3/padic_poly.h @@ -0,0 +1,429 @@ +/*============================================================================ + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#ifndef PADIC_POLY_H +#define PADIC_POLY_H + +#include + +#include +#include "fmpz.h" +#include "fmpq.h" +#include "padic.h" +#include "fmpz_vec.h" +#include "fmpz_poly.h" +#include "fmpq_poly.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +/* Type definitions ********************************************************/ + +typedef struct +{ + fmpz *coeffs; + slong alloc; + slong length; + slong val; + slong N; +} padic_poly_struct; + +typedef padic_poly_struct padic_poly_t[1]; + +/* Helper functions ********************************************************/ + +/* + Returns the minimum $p$-adic valuation of \code{(vec, len)}, + assuming this fits into a \code{signed long}. + + If \code{len} is zero, returns $0$. + */ +static __inline__ slong _fmpz_vec_ord_p(const fmpz *vec, slong len, const fmpz_t p) +{ + if (len == 0) + { + return 0; + } + else + { + fmpz_t t; + slong i, min = WORD_MAX, v; + + fmpz_init(t); + for (i = 0; (min > 0) && (i < len); i++) + { + if (!fmpz_is_zero(vec + i)) + { + v = fmpz_remove(t, vec + i, p); + min = FLINT_MIN(min, v); + } + } + fmpz_clear(t); + return (min < WORD_MAX) ? min : 0; + } +} + +/* Memory management *******************************************************/ + +void padic_poly_init(padic_poly_t poly); + +void padic_poly_init2(padic_poly_t poly, slong alloc, slong prec); + +void padic_poly_clear(padic_poly_t poly); + +void padic_poly_realloc(padic_poly_t f, slong alloc, const fmpz_t p); + +void padic_poly_fit_length(padic_poly_t f, slong len); + +static __inline__ +void _padic_poly_set_length(padic_poly_t poly, slong len) +{ + if (poly->length > len) + { + slong i; + + for (i = len; i < poly->length; i++) + _fmpz_demote(poly->coeffs + i); + } + poly->length = len; +} + +void _padic_poly_normalise(padic_poly_t f); + +void _padic_poly_canonicalise(fmpz *poly, slong *v, slong len, const fmpz_t p); + +void padic_poly_canonicalise(padic_poly_t poly, const fmpz_t p); + +void padic_poly_reduce(padic_poly_t f, const padic_ctx_t ctx); + +static __inline__ +void padic_poly_truncate(padic_poly_t poly, slong n, const fmpz_t p) +{ + if (poly->length > n) + { + slong i; + + for (i = n; i < poly->length; i++) + _fmpz_demote(poly->coeffs + i); + poly->length = n; + _padic_poly_normalise(poly); + padic_poly_canonicalise(poly, p); + } +} + +/* Polynomial parameters ***************************************************/ + +static __inline__ slong padic_poly_degree(const padic_poly_t poly) +{ + return poly->length - 1; +} + +static __inline__ slong padic_poly_length(const padic_poly_t poly) +{ + return poly->length; +} + +static __inline__ slong padic_poly_val(const padic_poly_t poly) +{ + return poly->val; +} + +#define padic_poly_val(poly) ((poly)->val) + +#define padic_poly_prec(poly) ((poly)->N) + +/* Randomisation ***********************************************************/ + +void padic_poly_randtest(padic_poly_t f, flint_rand_t state, + slong len, const padic_ctx_t ctx); + +void padic_poly_randtest_not_zero(padic_poly_t f, flint_rand_t state, + slong len, const padic_ctx_t ctx); + +void padic_poly_randtest_val(padic_poly_t f, flint_rand_t state, + slong val, slong len, const padic_ctx_t ctx); + +/* Assignment and basic manipulation ***************************************/ + +void padic_poly_set(padic_poly_t f, const padic_poly_t g, + const padic_ctx_t ctx); + +void padic_poly_set_padic(padic_poly_t poly, const padic_t x, + const padic_ctx_t ctx); + +void padic_poly_set_si(padic_poly_t poly, slong x, const padic_ctx_t ctx); + +void padic_poly_set_ui(padic_poly_t poly, ulong x, const padic_ctx_t ctx); + +void padic_poly_set_fmpz(padic_poly_t poly, const fmpz_t x, + const padic_ctx_t ctx); + +void padic_poly_set_fmpq(padic_poly_t poly, const fmpq_t x, + const padic_ctx_t ctx); + +void padic_poly_set_fmpz_poly(padic_poly_t rop, const fmpz_poly_t op, + const padic_ctx_t ctx); + +void padic_poly_set_fmpq_poly(padic_poly_t rop, + const fmpq_poly_t op, const padic_ctx_t ctx); + +int padic_poly_get_fmpz_poly(fmpz_poly_t rop, const padic_poly_t op, + const padic_ctx_t ctx); + +void padic_poly_get_fmpq_poly(fmpq_poly_t rop, + const padic_poly_t op, const padic_ctx_t ctx); + +static __inline__ void padic_poly_zero(padic_poly_t poly) +{ + _padic_poly_set_length(poly, 0); + poly->val = 0; +} + +static __inline__ void padic_poly_one(padic_poly_t poly) +{ + if (padic_poly_prec(poly) > 0) + { + padic_poly_fit_length(poly, 1); + fmpz_one(poly->coeffs); + _padic_poly_set_length(poly, 1); + poly->val = 0; + } + else + { + padic_poly_zero(poly); + } +} + +void padic_poly_swap(padic_poly_t poly1, padic_poly_t poly2); + +/* Getting and setting coefficients ****************************************/ + +void padic_poly_get_coeff_padic(padic_t c, const padic_poly_t poly, slong n, + const padic_ctx_t ctx); + +void padic_poly_set_coeff_padic(padic_poly_t f, slong n, const padic_t c, + const padic_ctx_t ctx); + +/* Comparison **************************************************************/ + +int padic_poly_equal(const padic_poly_t f, const padic_poly_t g); + +static __inline__ int padic_poly_is_zero(const padic_poly_t poly) +{ + return poly->length == 0; +} + +static __inline__ int padic_poly_is_one(const padic_poly_t poly) +{ + return (poly->length == 1) && fmpz_is_one(poly->coeffs) && + (poly->val == 0); +} + +/* Addition and subtraction ************************************************/ + +void _padic_poly_add(fmpz *rop, slong *rval, slong N, + const fmpz *op1, slong val1, slong len1, slong N1, + const fmpz *op2, slong val2, slong len2, slong N2, + const padic_ctx_t ctx); + +void padic_poly_add(padic_poly_t f, + const padic_poly_t g, const padic_poly_t h, + const padic_ctx_t ctx); + +void _padic_poly_sub(fmpz *rop, slong *rval, slong N, + const fmpz *op1, slong val1, slong len1, slong N1, + const fmpz *op2, slong val2, slong len2, slong N2, + const padic_ctx_t ctx); + +void padic_poly_sub(padic_poly_t f, + const padic_poly_t g, const padic_poly_t h, + const padic_ctx_t ctx); + +void padic_poly_neg(padic_poly_t f, const padic_poly_t g, + const padic_ctx_t ctx); + +/* Scalar multiplication and division **************************************/ + +void _padic_poly_scalar_mul_padic(fmpz *rop, slong *rval, slong N, + const fmpz *op, slong val, slong len, + const padic_t c, const padic_ctx_t ctx); + +void padic_poly_scalar_mul_padic(padic_poly_t rop, const padic_poly_t op, + const padic_t c, const padic_ctx_t ctx); + +/* Multiplication **********************************************************/ + +void _padic_poly_mul(fmpz *rop, slong *rval, slong N, + const fmpz *op1, slong val1, slong len1, + const fmpz *op2, slong val2, slong len2, + const padic_ctx_t ctx); + +void padic_poly_mul(padic_poly_t f, + const padic_poly_t g, const padic_poly_t h, + const padic_ctx_t ctx); + +/* Powering ****************************************************************/ + +void _padic_poly_pow(fmpz *rop, slong *rval, slong N, + const fmpz *op, slong val, slong len, ulong e, + const padic_ctx_t ctx); + +void padic_poly_pow(padic_poly_t rop, const padic_poly_t op, ulong e, + const padic_ctx_t ctx); + +/* Series inversion ********************************************************/ + +void padic_poly_inv_series(padic_poly_t Qinv, const padic_poly_t Q, slong n, + const padic_ctx_t ctx); + +/* Derivative **************************************************************/ + +void _padic_poly_derivative(fmpz *rop, slong *rval, slong N, + const fmpz *op, slong val, slong len, + const padic_ctx_t ctx); + +void padic_poly_derivative(padic_poly_t rop, + const padic_poly_t op, const padic_ctx_t ctx); + +/* Shifting ****************************************************************/ + +void padic_poly_shift_left(padic_poly_t rop, const padic_poly_t op, slong n, + const padic_ctx_t ctx); + +void padic_poly_shift_right(padic_poly_t rop, const padic_poly_t op, slong n, + const padic_ctx_t ctx); + +/* Evaluation **************************************************************/ + +void _padic_poly_evaluate_padic(fmpz_t u, slong *v, slong N, + const fmpz *poly, slong val, slong len, + const fmpz_t a, slong b, const padic_ctx_t ctx); + +void padic_poly_evaluate_padic(padic_t y, const padic_poly_t poly, + const padic_t x, const padic_ctx_t ctx); + +/* Composition *************************************************************/ + +void _padic_poly_compose(fmpz *rop, slong *rval, slong N, + const fmpz *op1, slong val1, slong len1, + const fmpz *op2, slong val2, slong len2, + const padic_ctx_t ctx); + +void padic_poly_compose(padic_poly_t rop, + const padic_poly_t op1, const padic_poly_t op2, + const padic_ctx_t ctx); + +void _padic_poly_compose_pow(fmpz *rop, slong *rval, slong N, + const fmpz *op, slong val, slong len, slong k, + const padic_ctx_t ctx); + +void padic_poly_compose_pow(padic_poly_t rop, const padic_poly_t op, slong k, + const padic_ctx_t ctx); + +/* Input and output ********************************************************/ + +static __inline__ int padic_poly_debug(const padic_poly_t poly) +{ + flint_printf("(alloc = %wd, length = %wd, val = %wd, N = %wd, vec = ", + poly->alloc, poly->length, poly->val, poly->N); + if (poly->coeffs) + { + flint_printf("{"); + _fmpz_vec_print(poly->coeffs, poly->alloc); + flint_printf("}"); + } + else + { + flint_printf("NULL"); + } + flint_printf(")"); + + return 1; +} + +int _padic_poly_fprint(FILE *file, const fmpz *poly, slong val, slong len, + const padic_ctx_t ctx); + +int padic_poly_fprint(FILE *file, const padic_poly_t poly, + const padic_ctx_t ctx); + +static __inline__ +int _padic_poly_print(const fmpz *poly, slong val, slong len, + const padic_ctx_t ctx) +{ + return _padic_poly_fprint(stdout, poly, val, len, ctx); +} + +static __inline__ +int padic_poly_print(const padic_poly_t poly, const padic_ctx_t ctx) +{ + return padic_poly_fprint(stdout, poly, ctx); +} + +int _padic_poly_fprint_pretty(FILE *file, + const fmpz *poly, slong val, slong len, + const char *var, + const padic_ctx_t ctx); + +int padic_poly_fprint_pretty(FILE *file, + const padic_poly_t poly, const char *var, + const padic_ctx_t ctx); + +static __inline__ +int _padic_poly_print_pretty(FILE *file, + const fmpz *poly, slong val, slong len, + const char *var, + const padic_ctx_t ctx) +{ + return _padic_poly_fprint_pretty(stdout, poly, val, len, var, ctx); +} + +static __inline__ +int padic_poly_print_pretty(const padic_poly_t poly, const char *var, + const padic_ctx_t ctx) +{ + return padic_poly_fprint_pretty(stdout, poly, var, ctx); +} + +/* Testing *****************************************************************/ + +int _padic_poly_is_canonical(const fmpz *op, slong val, slong len, + const padic_ctx_t ctx); + +int padic_poly_is_canonical(const padic_poly_t op, const padic_ctx_t ctx); + +int _padic_poly_is_reduced(const fmpz *op, slong val, slong len, slong N, + const padic_ctx_t ctx); + +int padic_poly_is_reduced(const padic_poly_t op, const padic_ctx_t ctx); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/external/flint-2.4.3/padic_poly/Makefile b/external/flint-2.4.3/padic_poly/Makefile new file mode 100644 index 0000000..6969798 --- /dev/null +++ b/external/flint-2.4.3/padic_poly/Makefile @@ -0,0 +1,54 @@ +SOURCES = $(wildcard *.c) + +OBJS = $(patsubst %.c, $(BUILD_DIR)/$(MOD_DIR)_%.o, $(SOURCES)) + +LOBJS = $(patsubst %.c, $(BUILD_DIR)/%.lo, $(SOURCES)) +MOD_LOBJ = $(BUILD_DIR)/../$(MOD_DIR).lo + +TEST_SOURCES = $(wildcard test/*.c) + +PROF_SOURCES = $(wildcard profile/*.c) + +TUNE_SOURCES = $(wildcard tune/*.c) + +TESTS = $(patsubst %.c, $(BUILD_DIR)/%, $(TEST_SOURCES)) + +TESTS_RUN = $(patsubst %, %_RUN, $(TESTS)) + +PROFS = $(patsubst %.c, %, $(PROF_SOURCES)) + +TUNE = $(patsubst %.c, %, $(TUNE_SOURCES)) + +all: shared static + +shared: $(MOD_LOBJ) + +static: $(OBJS) + +profile: $(PROF_SOURCES) + $(foreach prog, $(PROFS), $(CC) $(ABI_FLAG) -O2 -std=c99 $(INCS) $(prog).c ../profiler.o -o $(BUILD_DIR)/$(prog) $(LIBS) || exit $$?;) + +tune: $(TUNE_SOURCES) + $(foreach prog, $(TUNE), $(CC) $(ABI_FLAG) -O2 -std=c99 $(INCS) $(prog).c -o $(BUILD_DIR)/$(prog) $(LIBS) || exit $$?;) + +$(BUILD_DIR)/$(MOD_DIR)_%.o: %.c + $(CC) $(CFLAGS) -c $(INCS) $< -o $@ + +$(MOD_LOBJ): $(LOBJS) + $(CC) $(ABI_FLAG) -Wl,-r $^ -o $@ -nostdlib + +$(BUILD_DIR)/%.lo: %.c + $(CC) $(PICFLAG) $(CFLAGS) $(INCS) -c $< -o $@ + +clean: + rm -rf $(BUILD_DIR) $(MOD_LOBJ) + +check: $(TESTS) $(TESTS_RUN) + +$(BUILD_DIR)/test/%: test/%.c + $(CC) $(CFLAGS) $(INCS) $< ../test_helpers.o -o $@ $(LIBS) + +%_RUN: % + @$< + +.PHONY: profile tune clean check all shared static %_RUN diff --git a/external/flint-2.4.3/padic_poly/add.c b/external/flint-2.4.3/padic_poly/add.c new file mode 100644 index 0000000..3a2be84 --- /dev/null +++ b/external/flint-2.4.3/padic_poly/add.c @@ -0,0 +1,147 @@ +/*============================================================================ + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_mod_poly.h" +#include "padic_poly.h" + +void _padic_poly_add(fmpz *rop, slong *val, slong N, + const fmpz *op1, slong val1, slong len1, slong N1, + const fmpz *op2, slong val2, slong len2, slong N2, + const padic_ctx_t ctx) +{ + const slong len = FLINT_MAX(len1, len2); + + *val = FLINT_MIN(val1, val2); + + if (val1 == val2) + { + _fmpz_poly_add(rop, op1, len1, op2, len2); + _padic_poly_canonicalise(rop, val, len, ctx->p); + } + else /* => (op1 != op2) */ + { + fmpz_t x; + + fmpz_init(x); + if (val1 < val2) /* F := p^g (G + p^{h-g} H) */ + { + fmpz_pow_ui(x, ctx->p, val2 - val1); + + if (rop == op1) + { + _fmpz_vec_zero(rop + len1, len2 - len1); + _fmpz_vec_scalar_addmul_fmpz(rop, op2, len2, x); + } + else + { + _fmpz_vec_scalar_mul_fmpz(rop, op2, len2, x); + _fmpz_poly_add(rop, op1, len1, rop, len2); + } + } + else /* F := p^h (p^{g-h} G + H) */ + { + fmpz_pow_ui(x, ctx->p, val1 - val2); + + if (rop == op2) + { + _fmpz_vec_zero(rop + len2, len1 - len2); + _fmpz_vec_scalar_addmul_fmpz(rop, op1, len1, x); + } + else + { + _fmpz_vec_scalar_mul_fmpz(rop, op1, len1, x); + _fmpz_poly_add(rop, rop, len1, op2, len2); + } + } + fmpz_clear(x); + } + + /* Reduce */ + if (N - *val > 0) + { + fmpz_t pow; + int alloc; + + alloc = _padic_ctx_pow_ui(pow, N - *val, ctx); + + if (N >= N1 && N >= N2) + { + slong i; + for (i = 0; i < len; i++) + if (fmpz_cmpabs(rop + i, pow) >= 0) + fmpz_sub(rop + i, rop + i, pow); + } + else + { + _fmpz_vec_scalar_mod_fmpz(rop, rop, len, pow); + } + + if (_fmpz_vec_is_zero(rop, len)) + *val = 0; + + if (alloc) + fmpz_clear(pow); + } + else + { + _fmpz_vec_zero(rop, len); + *val = 0; + } +} + +void padic_poly_add(padic_poly_t f, + const padic_poly_t g, const padic_poly_t h, + const padic_ctx_t ctx) +{ + const slong lenG = g->length; + const slong lenH = h->length; + const slong lenF = FLINT_MAX(lenG, lenH); + + if (lenG == 0) + { + padic_poly_set(f, h, ctx); + return; + } + if (lenH == 0) + { + padic_poly_set(f, g, ctx); + return; + } + if ((lenG == 0 && lenH == 0) || (FLINT_MIN(g->val, h->val) >= f->N)) + { + padic_poly_zero(f); + return; + } + + padic_poly_fit_length(f, lenF); + + _padic_poly_add(f->coeffs, &(f->val), f->N, + g->coeffs, g->val, lenG, g->N, + h->coeffs, h->val, lenH, h->N, ctx); + + _padic_poly_set_length(f, lenF); + _padic_poly_normalise(f); +} + diff --git a/external/flint-2.4.3/padic_poly/canonicalise.c b/external/flint-2.4.3/padic_poly/canonicalise.c new file mode 100644 index 0000000..64e1b6e --- /dev/null +++ b/external/flint-2.4.3/padic_poly/canonicalise.c @@ -0,0 +1,54 @@ +/*============================================================================ + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "padic_poly.h" + +void _padic_poly_canonicalise(fmpz *poly, slong *v, slong len, const fmpz_t p) +{ + const slong min = _fmpz_vec_ord_p(poly, len, p); + + if (min == 0) + { + if (_fmpz_vec_is_zero(poly, len)) + *v = 0; + } + else /* min > 0 */ + { + fmpz_t pow; + + fmpz_init(pow); + fmpz_pow_ui(pow, p, min); + _fmpz_vec_scalar_divexact_fmpz(poly, poly, len, pow); + fmpz_clear(pow); + + *v += min; + } +} + +void padic_poly_canonicalise(padic_poly_t poly, const fmpz_t p) +{ + _padic_poly_canonicalise(poly->coeffs, &(poly->val), poly->length, p); +} + diff --git a/external/flint-2.4.3/padic_poly/clear.c b/external/flint-2.4.3/padic_poly/clear.c new file mode 100644 index 0000000..5992a47 --- /dev/null +++ b/external/flint-2.4.3/padic_poly/clear.c @@ -0,0 +1,42 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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, 2011 Sebastian Pancratz + +******************************************************************************/ + +#include + +#include "fmpz.h" +#include "padic_poly.h" + +void padic_poly_clear(padic_poly_t poly) +{ + if (poly->coeffs) + { + slong i; + + for (i = 0; i < poly->alloc; i++) + _fmpz_demote(poly->coeffs + i); + flint_free(poly->coeffs); + } +} diff --git a/external/flint-2.4.3/padic_poly/compose.c b/external/flint-2.4.3/padic_poly/compose.c new file mode 100644 index 0000000..6b00094 --- /dev/null +++ b/external/flint-2.4.3/padic_poly/compose.c @@ -0,0 +1,195 @@ +/*============================================================================ + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_mod_poly.h" +#include "padic_poly.h" + +/* + TODO: Move this bit of code into "padic". + */ +static void __padic_reduce(fmpz_t u, slong *v, slong N, const padic_ctx_t ctx) +{ + if (!fmpz_is_zero(u)) + { + if (*v < N) + { + int alloc; + fmpz_t pow; + + alloc = _padic_ctx_pow_ui(pow, N - *v, ctx); + fmpz_mod(u, u, pow); + if (alloc) + fmpz_clear(pow); + } + else + { + fmpz_zero(u); + *v = 0; + } + } +} + +/* Assumes that len1 > 0. */ + +void _padic_poly_compose(fmpz *rop, slong *rval, slong N, + const fmpz *op1, slong val1, slong len1, + const fmpz *op2, slong val2, slong len2, + const padic_ctx_t ctx) +{ + const slong lenr = (len1 - 1) * (len2 - 1) + 1; + + if (len1 == 1 || len2 == 0) + { + fmpz_set(rop, op1); + *rval = val1; + + __padic_reduce(rop, rval, N, ctx); + } + else if (val2 >= 0) + { + if (val1 >= N) + { + _fmpz_vec_zero(rop, lenr); + *rval = 0; + } + else + { + fmpz *vec2; + fmpz_t f; + fmpz_t pow; + int alloc; + + vec2 = _fmpz_vec_init(len2); + fmpz_init(f); + + fmpz_pow_ui(f, ctx->p, val2); + _fmpz_vec_scalar_mul_fmpz(vec2, op2, len2, f); + + alloc = _padic_ctx_pow_ui(pow, N - val1, ctx); + + _fmpz_mod_poly_compose(rop, op1, len1, vec2, len2, pow); + *rval= val1; + + _padic_poly_canonicalise(rop, rval, lenr, ctx->p); + + _fmpz_vec_clear(vec2, len2); + fmpz_clear(f); + if (alloc) + fmpz_clear(pow); + } + } + else /* val2 < 0 */ + { + const slong n = len1 - 1; + + if (val1 + n*val2 >= N) + { + _fmpz_vec_zero(rop, lenr); + *rval = 0; + } + else + { + fmpz_t pow; + int alloc; + fmpz *vec1; + fmpz_t s, t; + slong i; + + vec1 = _fmpz_vec_init(len1); + fmpz_init(s); + fmpz_init(t); + + alloc = _padic_ctx_pow_ui(pow, N - val1 - n*val2, ctx); + + fmpz_pow_ui(s, ctx->p, -val2); + fmpz_one(t); + fmpz_set(vec1 + (len1 - 1), op1 + (len1 - 1)); + for (i = len1 - 2; i >= 0; i--) + { + fmpz_mul(t, t, s); + fmpz_mul(vec1 + i, op1 + i, t); + } + + _fmpz_mod_poly_compose(rop, vec1, len1, op2, len2, pow); + *rval = val1 + n*val2; + + _padic_poly_canonicalise(rop, rval, lenr, ctx->p); + + _fmpz_vec_clear(vec1, len1); + fmpz_clear(s); + fmpz_clear(t); + if (alloc) + fmpz_clear(pow); + } + } +} + +void padic_poly_compose(padic_poly_t rop, + const padic_poly_t op1, const padic_poly_t op2, + const padic_ctx_t ctx) +{ + const slong len1 = op1->length, len2 = op2->length; + + if (len1 == 0) + { + padic_poly_zero(rop); + } + else if (len1 == 1 || len2 == 0) + { + padic_poly_fit_length(rop, 1); + fmpz_set(rop->coeffs, op1->coeffs); + rop->val = op1->val; + _padic_poly_set_length(rop, 1); + padic_poly_canonicalise(rop, ctx->p); + padic_poly_reduce(rop, ctx); + } + else + { + const slong lenr = (len1 - 1) * (len2 - 1) + 1; + + if (rop != op1 && rop != op2) + { + padic_poly_fit_length(rop, lenr); + _padic_poly_compose(rop->coeffs, &(rop->val), rop->N, + op1->coeffs, op1->val, op1->length, + op2->coeffs, op2->val, op2->length, ctx); + _padic_poly_set_length(rop, lenr); + } + else + { + fmpz *t = _fmpz_vec_init(lenr); + + _padic_poly_compose(t, &(rop->val), rop->N, + op1->coeffs, op1->val, op1->length, + op2->coeffs, op2->val, op2->length, ctx); + _fmpz_vec_clear(rop->coeffs, rop->alloc); + rop->coeffs = t; + rop->alloc = lenr; + rop->length = lenr; + } + _padic_poly_normalise(rop); + } +} + diff --git a/external/flint-2.4.3/padic_poly/compose_pow.c b/external/flint-2.4.3/padic_poly/compose_pow.c new file mode 100644 index 0000000..dd46262 --- /dev/null +++ b/external/flint-2.4.3/padic_poly/compose_pow.c @@ -0,0 +1,106 @@ +/*============================================================================ + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_mod_poly.h" +#include "padic_poly.h" + +/* + TODO: Move this bit of code into "padic". + */ +static void __padic_reduce(fmpz_t u, slong *v, slong N, const padic_ctx_t ctx) +{ + if (!fmpz_is_zero(u)) + { + if (*v < N) + { + int alloc; + fmpz_t pow; + + alloc = _padic_ctx_pow_ui(pow, N - *v, ctx); + fmpz_mod(u, u, pow); + if (alloc) + fmpz_clear(pow); + } + else + { + fmpz_zero(u); + *v = 0; + } + } +} + +void _padic_poly_compose_pow(fmpz *rop, slong *rval, slong N, + const fmpz *op, slong val, slong len, slong k, + const padic_ctx_t ctx) +{ + if (k == 1) + { + if (rop != op) + { + _fmpz_vec_set(rop, op, len); + *rval = val; + } + } + else if (len == 1) + { + fmpz_set(rop, op); + *rval = val; + + __padic_reduce(rop, rval, N, ctx); + } + else + { + slong i, j, h; + + for (i = len - 1, j = (len - 1) * k ; i >= 0; i--, j -= k) + { + fmpz_set(rop + j, op + i); + if (i) + for (h = 1; h < k; h++) + fmpz_zero(rop + (j - h)); + } + *rval = val; + } +} + +void padic_poly_compose_pow(padic_poly_t rop, const padic_poly_t op, slong k, + const padic_ctx_t ctx) +{ + const slong len = op->length; + const slong lenr = (len - 1) * k + 1; + + if (len == 0) + { + padic_poly_zero(rop); + } + else + { + padic_poly_fit_length(rop, lenr); + _padic_poly_compose_pow(rop->coeffs, &(rop->val), rop->N, + op->coeffs, op->val, op->length, k, ctx); + _padic_poly_set_length(rop, lenr); + } +} + diff --git a/external/flint-2.4.3/padic_poly/derivative.c b/external/flint-2.4.3/padic_poly/derivative.c new file mode 100644 index 0000000..adba01f --- /dev/null +++ b/external/flint-2.4.3/padic_poly/derivative.c @@ -0,0 +1,66 @@ +/*============================================================================ + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_mod_poly.h" +#include "padic_poly.h" + +void _padic_poly_derivative(fmpz *rop, slong *rval, slong N, + const fmpz *op, slong val, slong len, + const padic_ctx_t ctx) +{ + fmpz_t pow; + int alloc; + + _fmpz_poly_derivative(rop, op, len); + *rval = val; + + alloc = _padic_ctx_pow_ui(pow, N - *rval, ctx); + + _fmpz_vec_scalar_mod_fmpz(rop, rop, len - 1, pow); + _padic_poly_canonicalise(rop, rval, len - 1, ctx->p); + + if (alloc) + fmpz_clear(pow); +} + +void padic_poly_derivative(padic_poly_t rop, + const padic_poly_t op, const padic_ctx_t ctx) +{ + const slong len = op->length; + + if (len < 2 || op->val >= rop->N) + { + padic_poly_zero(rop); + } + else + { + padic_poly_fit_length(rop, len - 1); + _padic_poly_derivative(rop->coeffs, &(rop->val), rop->N, + op->coeffs, op->val, len, ctx); + _padic_poly_set_length(rop, len - 1); + _padic_poly_normalise(rop); + } +} + diff --git a/external/flint-2.4.3/padic_poly/doc/padic_poly.txt b/external/flint-2.4.3/padic_poly/doc/padic_poly.txt new file mode 100644 index 0000000..4705007 --- /dev/null +++ b/external/flint-2.4.3/padic_poly/doc/padic_poly.txt @@ -0,0 +1,662 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +******************************************************************************* + + Module documentation + + We represent a polynomial in $\mathbf{Q}_p[x]$ as a + product $p^v f(x)$, where $p$ is a prime number, + $v \in \mathbf{Z}$ and $f(x) \in \mathbf{Z}[x]$. + + As a data structure, we call this polynomial \emph{normalised} + if the polynomial $f(x)$ is \emph{normalised}, that is, if the top + coefficient is non-zero. + + We say this polynomial is in \emph{canonical form} if one of the + coefficients of $f(x)$ is a $p$-adic unit. If $f(x)$ is the zero + polynomial, we require that $v = 0$. + + We say this polynomial is \emph{reduced} modulo $p^N$ if it is + canonical form and if all coefficients lie in the range $[0, p^N)$. + +******************************************************************************* + +******************************************************************************* + + Memory management + +******************************************************************************* + +void padic_poly_init(padic_poly_t poly) + + Initialises \code{poly} for use, setting its length to zero. + The precision of the polynomial is set to \code{PADIC_DEFAULT_PREC}. + A corresponding call to \code{padic_poly_clear()} must be made + after finishing with the \code{padic_poly_t} to free the memory + used by the polynomial. + +void padic_poly_init2(padic_poly_t poly, slong alloc, slong prec) + + Initialises \code{poly} with space for at least \code{alloc} coefficients + and sets the length to zero. The allocated coefficients are all set to + zero. The precision is set to \code{prec}. + +void padic_poly_realloc(padic_poly_t poly, slong alloc, const fmpz_t p) + + Reallocates the given polynomial to have space for \code{alloc} + coefficients. If \code{alloc} is zero the polynomial is cleared + and then reinitialised. If the current length is greater than + \code{alloc} the polynomial is first truncated to length \code{alloc}. + +void padic_poly_fit_length(padic_poly_t poly, slong len) + + If \code{len} is greater than the number of coefficients currently + allocated, then the polynomial is reallocated to have space for at + least \code{len} coefficients. No data is lost when calling this + function. + + The function efficiently deals with the case where \code{fit_length} is + called many times in small increments by at least doubling the number + of allocated coefficients when length is larger than the number of + coefficients currently allocated. + +void _padic_poly_set_length(padic_poly_t poly, slong len) + + Demotes the coefficients of \code{poly} beyond \code{len} and sets + the length of \code{poly} to \code{len}. + + Note that if the current length is greater than \code{len} the + polynomial may no slonger be in canonical form. + +void padic_poly_clear(padic_poly_t poly) + + Clears the given polynomial, releasing any memory used. It must + be reinitialised in order to be used again. + +void _padic_poly_normalise(padic_poly_t poly) + + Sets the length of \code{poly} so that the top coefficient is non-zero. + If all coefficients are zero, the length is set to zero. This function + is mainly used internally, as all functions guarantee normalisation. + +void _padic_poly_canonicalise(fmpz *poly, slong *v, slong len, const fmpz_t p) + +void padic_poly_canonicalise(padic_poly_t poly, const fmpz_t p) + + Brings the polynomial \code{poly} into canonical form, + assuming that it is normalised already. Does \emph{not} + carry out any reduction. + +void padic_poly_reduce(padic_poly_t poly, const padic_ctx_t ctx) + + Reduces the polynomial \code{poly} modulo $p^N$, assuming + that it is in canonical form already. + +void padic_poly_truncate(padic_poly_t poly, slong n, const fmpz_t p) + + Truncates the polynomial to length at most~$n$. + +******************************************************************************* + + Polynomial parameters + +******************************************************************************* + +slong padic_poly_degree(padic_poly_t poly) + + Returns the degree of the polynomial \code{poly}. + +slong padic_poly_length(padic_poly_t poly) + + Returns the length of the polynomial \code{poly}. + +slong padic_poly_val(padic_poly_t poly) + + Returns the valuation of the polynomial \code{poly}, + which is defined to be the minimum valuation of all + its coefficients. + + The valuation of the zero polynomial is~$0$. + + Note that this is implemented as a macro and can be + used as either a \code{lvalue} or a \code{rvalue}. + +slong padic_poly_prec(padic_poly_t poly) + + Returns the precision of the polynomial \code{poly}. + + Note that this is implemented as a macro and can be + used as either a \code{lvalue} or a \code{rvalue}. + + Note that increasing the precision might require + a call to \code{padic_poly_reduce()}. + +******************************************************************************* + + Randomisation + +******************************************************************************* + +void padic_poly_randtest(padic_poly_t f, flint_rand_t state, + slong len, const padic_ctx_t ctx) + + Sets $f$ to a random polynomial of length at most \code{len} + with entries reduced modulo $p^N$. + +void padic_poly_randtest_not_zero(padic_poly_t f, flint_rand_t state, + slong len, const padic_ctx_t ctx) + + Sets $f$ to a non-zero random polynomial of length at most \code{len} + with entries reduced modulo $p^N$. + +void padic_poly_randtest_val(padic_poly_t f, flint_rand_t state, + slong val, slong len, const padic_ctx_t ctx) + + Sets $f$ to a random polynomial of length at most \code{len} + with at most the prescribed valuation \code{val} and entries + reduced modulo $p^N$. + + Specifically, we aim to set the valuation to be exactly equal + to \code{val}, but do not check for additional cancellation + when creating the coefficients. + +******************************************************************************* + + Assignment and basic manipulation + +******************************************************************************* + +void padic_poly_set_padic(padic_poly_t poly, const padic_t x, + const padic_ctx_t ctx) + + Sets the polynomial \code{poly} to the $p$-adic number $x$, + reduced to the precision of the polynomial. + +void padic_poly_set(padic_poly_t poly1, const padic_poly_t poly2, + const padic_ctx_t ctx) + + Sets the polynomial \code{poly1} to the polynomial \code{poly2}, + reduced to the precision of \code{poly1}. + +void padic_poly_set_si(padic_poly_t poly, slong x, const padic_ctx_t ctx) + + Sets the polynomial \code{poly} to the \code{signed slong} + integer $x$ reduced to the precision of the polynomial. + +void padic_poly_set_ui(padic_poly_t poly, ulong x, const padic_ctx_t ctx) + + Sets the polynomial \code{poly} to the \code{unsigned slong} + integer $x$ reduced to the precision of the polynomial. + +void padic_poly_set_fmpz(padic_poly_t poly, const fmpz_t x, + const padic_ctx_t ctx) + + Sets the polynomial \code{poly} to the integer $x$ + reduced to the precision of the polynomial. + +void padic_poly_set_fmpq(padic_poly_t poly, const fmpq_t x, + const padic_ctx_t ctx) + + Sets the polynomial \code{poly} to the value of the rational $x$, + reduced to the precision of the polynomial. + +void padic_poly_set_fmpz_poly(padic_poly_t rop, const fmpz_poly_t op, + const padic_ctx_t ctx) + + Sets the polynomial \code{rop} to the integer polynomial \code{op} + reduced to the precision of the polynomial. + +void padic_poly_set_fmpq_poly(padic_poly_t rop, + const fmpq_poly_t op, const padic_ctx_t ctx) + + Sets the polynomial \code{rop} to the value of the rational + polynomial \code{op}, reduced to the precision of the polynomial. + +int padic_poly_get_fmpz_poly(fmpz_poly_t rop, const padic_poly_t op, + const padic_ctx_t ctx) + + Sets the integer polynomial \code{rop} to the value of the $p$-adic + polynomial \code{op} and returns $1$ if the polynomial is $p$-adically + integral. Otherwise, returns $0$. + +void padic_poly_get_fmpq_poly(fmpq_poly_t rop, + const padic_poly_t op, const padic_ctx_t ctx) + + Sets \code{rop} to the rational polynomial corresponding to + the $p$-adic polynomial \code{op}. + +void padic_poly_zero(padic_poly_t poly) + + Sets \code{poly} to the zero polynomial. + +void padic_poly_one(padic_poly_t poly) + + Sets \code{poly} to the constant polynomial $1$, + reduced to the precision of the polynomial. + +void padic_poly_swap(padic_poly_t poly1, padic_poly_t poly2) + + Swaps the two polynomials \code{poly1} and \code{poly2}, + including their precisions. + + This is done efficiently by swapping pointers. + +******************************************************************************* + + Getting and setting coefficients + +******************************************************************************* + +void padic_poly_get_coeff_padic(padic_t c, const padic_poly_t poly, slong n, + const padic_ctx_t ctx) + + Sets $c$ to the coefficient of $x^n$ in the polynomial, + reduced modulo the precision of $c$. + +void padic_poly_set_coeff_padic(padic_poly_t f, slong n, const padic_t c, + const padic_ctx_t ctx) + + Sets the coefficient of $x^n$ in the polynomial $f$ to $c$, + reduced to the precision of the polynomial $f$. + + Note that this operation can take linear time in the length + of the polynomial. + +******************************************************************************* + + Comparison + +******************************************************************************* + +int padic_poly_equal(const padic_poly_t poly1, const padic_poly_t poly2) + + Returns whether the two polynomials \code{poly1} and \code{poly2} + are equal. + +int padic_poly_is_zero(const padic_poly_t poly) + + Returns whether the polynomial \code{poly} is the zero polynomial. + +int padic_poly_is_one(const padic_poly_t poly, const padic_ctx_t ctx) + + Returns whether the polynomial \code{poly} is equal + to the constant polynomial~$1$, taking the precision + of the polynomial into account. + +******************************************************************************* + + Addition and subtraction + +******************************************************************************* + +void _padic_poly_add(fmpz *rop, slong *rval, slong N, + const fmpz *op1, slong val1, slong len1, slong N1, + const fmpz *op2, slong val2, slong len2, slong N2, + const padic_ctx_t ctx) + + Sets \code{(rop, *val, FLINT_MAX(len1, len2)} to the sum of + \code{(op1, val1, len1)} and \code{(op2, val2, len2)}. + + Assumes that the input is reduced and guarantees that this is + also the case for the output. + + Assumes that $\min\{v_1, v_2\} < N$. + + Supports aliasing between the output and input arguments. + +void padic_poly_add(padic_poly_t f, + const padic_poly_t g, const padic_poly_t h, + const padic_ctx_t ctx); + + Sets $f$ to the sum $g + h$. + +void _padic_poly_sub(fmpz *rop, slong *rval, + const fmpz *op1, slong val1, slong len1, + const fmpz *op2, slong val2, slong len2, + const padic_ctx_t ctx); + + Sets \code{(rop, *val, FLINT_MAX(len1, len2)} to the difference of + \code{(op1, val1, len1)} and \code{(op2, val2, len2)}. + + Assumes that the input is reduced and guarantees that this is + also the case for the output. + + Assumes that $\min\{v_1, v_2\} < N$. + + Support aliasing between the output and input arguments. + +void padic_poly_sub(padic_poly_t f, + const padic_poly_t g, const padic_poly_t h, + const padic_ctx_t ctx); + + Sets $f$ to the difference $g - h$. + +void padic_poly_neg(padic_poly_t f, const padic_poly_t g, + const padic_ctx_t ctx); + + Sets $f$ to $-g$. + +******************************************************************************* + + Scalar multiplication + +******************************************************************************* + +void _padic_poly_scalar_mul_padic(fmpz *rop, slong *rval, + const fmpz *op, slong val, slong len, + const padic_t c, const padic_ctx_t ctx) + + Sets \code{(rop, *rval, len)} to \code{(op, val, len)} multiplied + by the scalar $c$. + + The result will only be correctly reduced if the polynomial + is non-zero. Otherwise, the array \code{(rop, len)} will be + set to zero but the valuation \code{*rval} might be wrong. + +void padic_poly_scalar_mul_padic(padic_poly_t rop, const padic_poly_t op, + const padic_t c, const padic_ctx_t ctx) + + Sets the polynomial \code{rop} to the product of the + polynomial \code{op} and the $p$-adic number $c$, + reducing the result modulo $p^N$. + +******************************************************************************* + + Multiplication + +******************************************************************************* + +void _padic_poly_mul(fmpz *rop, slong *rval, slong N, + const fmpz *op1, slong val1, slong len1, + const fmpz *op2, slong val2, slong len2, + const padic_ctx_t ctx) + + Sets \code{(rop, *rval, len1 + len2 - 1)} to the product of + \code{(op1, val1, len1)} and \code{(op2, val2, len2)}. + + Assumes that the resulting valuation \code{*rval}, which is + the sum of the valuations \code{val1} and \code{val2}, is less + than the precision~$N$ of the context. + + Assumes that \code{len1 >= len2 > 0}. + +void padic_poly_mul(padic_poly_t res, + const padic_poly_t poly1, const padic_poly_t poly2, + const padic_ctx_t ctx) + + Sets the polynomial \code{res} to the product of the two polynomials + \code{poly1} and \code{poly2}, reduced modulo $p^N$. + +******************************************************************************* + + Powering + +******************************************************************************* + +void _padic_poly_pow(fmpz *rop, slong *rval, slong N, + const fmpz *op, slong val, slong len, ulong e, + const padic_ctx_t ctx) + + Sets the polynomial \code{(rop, *rval, e (len - 1) + 1)} to the + polynomial \code{(op, val, len)} raised to the power~$e$. + + Assumes that $e > 1$ and \code{len > 0}. + + Does not support aliasing between the input and output arguments. + +void padic_poly_pow(padic_poly_t rop, const padic_poly_t op, ulong e, + const padic_ctx_t ctx) + + Sets the polynomial \code{rop} to the polynomial \code{op} raised + to the power~$e$, reduced to the precision in \code{rop}. + + In the special case $e = 0$, sets \code{rop} to the constant + polynomial one reduced to the precision of \code{rop}. + Also note that when $e = 1$, this operation sets \code{rop} to + \code{op} and then reduces \code{rop}. + + When the valuation of the input polynomial is negative, + this results in a loss of $p$-adic precision. Suppose + that the input polynomial is given to precision~$N$ and + has valuation~$v < 0$. The result then has valuation + $e v < 0$ but is only correct to precision $N + (e - 1) v$. + +******************************************************************************* + + Series inversion + +******************************************************************************* + +void padic_poly_inv_series(padic_poly_t g, const padic_poly_t f, slong n, + const padic_ctx_t ctx) + + Computes the power series inverse $g$ of $f$ modulo $X^n$, + where $n \geq 1$. + + Given the polynomial $f \in \mathbf{Q}[X] \subset \mathbf{Q}_p[X]$, + there exists a unique polynomial $f^{-1} \in \mathbf{Q}[X]$ such that + $f f^{-1} = 1$ modulo $X^n$. This function sets $g$ to $f^{-1}$ + reduced modulo $p^N$. + + Assumes that the constant coefficient of $f$ is non-zero. + + Moreover, assumes that the valuation of the constant coefficient + of $f$ is minimal among the coefficients of $f$. + + Note that the result $g$ is zero if and only if $- \ord_p(f) \geq N$. + +******************************************************************************* + + Derivative + +******************************************************************************* + +void _padic_poly_derivative(fmpz *rop, slong *rval, slong N, + const fmpz *op, slong val, slong len, + const padic_ctx_t ctx) + + Sets \code{(rop, rval)} to the derivative of \code{(op, val)} reduced + modulo $p^N$. + + Supports aliasing of the input and the output parameters. + +void padic_poly_derivative(padic_poly_t rop, + const padic_poly_t op, const padic_ctx_t ctx) + + Sets \code{rop} to the derivative of \code{op}, reducing the + result modulo the precision of \code{rop}. + +******************************************************************************* + + Shifting + +******************************************************************************* + +void padic_poly_shift_left(padic_poly_t rop, const padic_poly_t op, slong n, + const padic_ctx_t ctx) + + Notationally, sets the polynomial \code{rop} to the polynomial \code{op} + multiplied by $x^n$, where $n \geq 0$, and reduces the result. + +void padic_poly_shift_right(padic_poly_t rop, const padic_poly_t op, slong n) + + Notationally, sets the polynomial \code{rop} to the polynomial + \code{op} after floor division by $x^n$, where $n \geq 0$, ensuring + the result is reduced. + +******************************************************************************* + + Evaluation + +******************************************************************************* + +void _padic_poly_evaluate_padic(fmpz_t u, slong *v, slong N, + const fmpz *poly, slong val, slong len, + const fmpz_t a, slong b, const padic_ctx_t ctx) + +void padic_poly_evaluate_padic(padic_t y, const padic_poly_t poly, + const padic_t a, const padic_ctx_t ctx) + + Sets the $p$-adic number \code{y} to \code{poly} evaluated at $a$, + reduced in the given context. + + Suppose that the polynomial can be written as $F(X) = p^w f(X)$ + with $\ord_p(f) = 1$, that $\ord_p(a) = b$ and that both are + defined to precision~$N$. Then $f$ is defined to precision + $N-w$ and so $f(a)$ is defined to precision $N-w$ when $a$ is + integral and $N-w+(n-1)b$ when $b < 0$, where $n = \deg(f)$. Thus, + $y = F(a)$ is defined to precision $N$ when $a$ is integral and + $N+(n-1)b$ when $b < 0$. + +******************************************************************************* + + Composition + +******************************************************************************* + +void _padic_poly_compose(fmpz *rop, slong *rval, slong N, + const fmpz *op1, slong val1, slong len1, + const fmpz *op2, slong val2, slong len2, + const padic_ctx_t ctx) + + Sets \code{(rop, *rval, (len1-1)*(len2-1)+1)} to the composition + of the two input polynomials, reducing the result modulo $p^N$. + + Assumes that \code{len1} is non-zero. + + Does not support aliasing. + +void padic_poly_compose(padic_poly_t rop, + const padic_poly_t op1, const padic_poly_t op2, + const padic_ctx_t ctx) + + Sets \code{rop} to the composition of \code{op1} and \code{op2}, + reducing the result in the given context. + + To be clear about the order of composition, let $f(X)$ and $g(X)$ + denote the polynomials \code{op1} and \code{op2}, respectively. + Then \code{rop} is set to $f(g(X))$. + +void _padic_poly_compose_pow(fmpz *rop, slong *rval, slong N, + const fmpz *op, slong val, slong len, slong k, + const padic_ctx_t ctx) + + Sets \code{(rop, *rval, (len - 1)*k + 1)} to the composition of + \code{(op, val, len)} and the monomial $x^k$, where $k \geq 1$. + + Assumes that \code{len} is positive. + + Supports aliasing between the input and output polynomials. + +void padic_poly_compose_pow(padic_poly_t rop, const padic_poly_t op, slong k, + const padic_ctx_t ctx) + + Sets \code{rop} to the composition of \code{op} and the monomial $x^k$, + where $k \geq 1$. + + Note that no reduction takes place. + +******************************************************************************* + + Input and output + +******************************************************************************* + +int padic_poly_debug(const padic_poly_t poly) + + Prints the data defining the $p$-adic polynomial \code{poly} + in a simple format useful for debugging purposes. + + In the current implementation, always returns $1$. + +int _padic_poly_fprint(FILE *file, const fmpz *poly, slong val, slong len, + const padic_ctx_t ctx) + +int padic_poly_fprint(FILE *file, const padic_poly_t poly, + const padic_ctx_t ctx) + + Prints a simple representation of the polynomial \code{poly} + to the stream \code{file}. + + A non-zero polynomial is represented by the number of coeffients, + two spaces, followed by a list of the coefficients, which are printed + in a way depending on the print mode, + \begin{itemize} + \item In the \code{PADIC_TERSE} mode, the coefficients are printed as + rational numbers. + \item The \code{PADIC_SERIES} mode is currently not supported and will + raise an abort signal. + \item In the \code{PADIC_VAL_UNIT} mode, the coefficients are printed + in the form $p^v u$. + \end{itemize} + + The zero polynomial is represented by \code{"0"}. + + In the current implementation, always returns $1$. + +int _padic_poly_print(const fmpz *poly, slong val, slong len, + const padic_ctx_t ctx) + +int padic_poly_print(const padic_poly_t poly, const padic_ctx_t ctx) + + Prints a simple representation of the polynomial \code{poly} + to \code{stdout}. + + In the current implementation, always returns $1$. + +int _padic_poly_fprint_pretty(FILE *file, + const fmpz *poly, slong val, slong len, + const char *var, + const padic_ctx_t ctx) + +int padic_poly_fprint_pretty(FILE *file, + const padic_poly_t poly, const char *var, + const padic_ctx_t ctx) + +int _padic_poly_print_pretty(FILE *file, + const fmpz *poly, slong val, slong len, + const char *var, + const padic_ctx_t ctx) + +int padic_poly_print_pretty(const padic_poly_t poly, const char *var, + const padic_ctx_t ctx) + +******************************************************************************* + + Testing + +******************************************************************************* + +int _padic_poly_is_canonical(const fmpz *op, slong val, slong len, + const padic_ctx_t ctx); + +int padic_poly_is_canonical(const padic_poly_t op, const padic_ctx_t ctx); + +int _padic_poly_is_reduced(const fmpz *op, slong val, slong len, slong N, + const padic_ctx_t ctx); + +int padic_poly_is_reduced(const padic_poly_t op, const padic_ctx_t ctx); + diff --git a/external/flint-2.4.3/padic_poly/equal.c b/external/flint-2.4.3/padic_poly/equal.c new file mode 100644 index 0000000..0d5e2df --- /dev/null +++ b/external/flint-2.4.3/padic_poly/equal.c @@ -0,0 +1,42 @@ +/*============================================================================ + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "padic_poly.h" + +int padic_poly_equal(const padic_poly_t f, const padic_poly_t g) +{ + if (f == g) + { + return 1; + } + + if (f->length != g->length || f->val != g->val) + { + return 0; + } + + return _fmpz_vec_equal(f->coeffs, g->coeffs, f->length); +} + diff --git a/external/flint-2.4.3/padic_poly/evaluate_padic.c b/external/flint-2.4.3/padic_poly/evaluate_padic.c new file mode 100644 index 0000000..9337067 --- /dev/null +++ b/external/flint-2.4.3/padic_poly/evaluate_padic.c @@ -0,0 +1,188 @@ +/*============================================================================ + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_mod_poly.h" +#include "padic_poly.h" + +/* + TODO: Move this bit of code into "padic". + */ +static void __padic_reduce(fmpz_t u, slong *v, slong N, const padic_ctx_t ctx) +{ + if (!fmpz_is_zero(u)) + { + if (*v < N) + { + int alloc; + fmpz_t pow; + + alloc = _padic_ctx_pow_ui(pow, N - *v, ctx); + fmpz_mod(u, u, pow); + if (alloc) + fmpz_clear(pow); + } + else + { + fmpz_zero(u); + *v = 0; + } + } +} + +/* + Evaluates the polynomial $F(x) = p^w f(x)$ at $x = p^b a$, setting + $y = p^v u$ to the result reduced modulo $p^N$. + + Suppose first that $b \geq 0$, in which case we can quickly relay + the call to the \code{fmpz_mod_poly} module. Namely, we need to + compute $f(x) \bmod {p^{N-w}}$ where we know $f(x)$ to be integral. + + Otherwise, suppose now that $b < 0$ and we still wish to evaluate + $f(x) \bmod {p^{N-w}}$. + \begin{align*} + f(x) & = \sum_{i = 0}^{n} a_i x^i \\ + & = \sum_{i = 0}^{n} a_i p^{i b} a^i \\ + \intertext{Multiplying through by $p^{- n b} \in \mathbf{Z}$, } + p^{-nb} f(x) & = \sum_{i = 0}^{n} a_i p^{-(n-i)b} a + \end{align*} + which leaves the right hand side integral. As we want to + compute $f(x)$ to precision $N-w$, we have to compute + $p^{-nb} f(x)$ to precision $N-w-nb$. + */ + +void _padic_poly_evaluate_padic(fmpz_t u, slong *v, slong N, + const fmpz *poly, slong val, slong len, + const fmpz_t a, slong b, const padic_ctx_t ctx) +{ + if (len == 0) + { + fmpz_zero(u); + *v = 0; + } + else if (len == 1) + { + fmpz_set(u, poly); + *v = val; + + __padic_reduce(u, v, N, ctx); + } + else if (b >= 0) + { + if (val >= N) + { + fmpz_zero(u); + *v = 0; + } + else + { + fmpz_t x; + fmpz_t pow; + int alloc; + + fmpz_init(x); + alloc = _padic_ctx_pow_ui(pow, N - val, ctx); + + fmpz_pow_ui(x, ctx->p, b); + fmpz_mul(x, x, a); + + _fmpz_mod_poly_evaluate_fmpz(u, poly, len, x, pow); + if (!fmpz_is_zero(u)) + *v = val + _fmpz_remove(u, ctx->p, ctx->pinv); + else + *v = 0; + + fmpz_clear(x); + if (alloc) + fmpz_clear(pow); + } + } + else /* b < 0 */ + { + const slong n = len - 1; + + if (val + n*b >= N) + { + fmpz_zero(u); + *v = 0; + } + else + { + fmpz_t pow; + int alloc; + slong i; + fmpz_t s, t; + + fmpz *vec = _fmpz_vec_init(len); + fmpz_init(s); + fmpz_init(t); + + alloc = _padic_ctx_pow_ui(pow, N - val - n*b, ctx); + + fmpz_pow_ui(s, ctx->p, -b); + fmpz_one(t); + fmpz_set(vec + (len - 1), poly + (len - 1)); + for (i = len - 2; i >= 0; i--) + { + fmpz_mul(t, t, s); + fmpz_mul(vec + i, poly + i, t); + } + + _fmpz_mod_poly_evaluate_fmpz(u, vec, len, a, pow); + if (!fmpz_is_zero(u)) + *v = val + n*b + _fmpz_remove(u, ctx->p, ctx->pinv); + else + *v = 0; + + if (alloc) + fmpz_clear(pow); + fmpz_clear(s); + fmpz_clear(t); + _fmpz_vec_clear(vec, len); + } + } +} + +void padic_poly_evaluate_padic(padic_t y, const padic_poly_t poly, + const padic_t x, const padic_ctx_t ctx) +{ + if (y == x) + { + padic_t t; + + padic_init2(t, padic_prec(y)); + _padic_poly_evaluate_padic(padic_unit(t), &padic_val(t), padic_prec(t), + poly->coeffs, poly->val, poly->length, + padic_unit(x), padic_val(x), ctx); + padic_swap(y, t); + padic_clear(t); + } + else + { + _padic_poly_evaluate_padic(padic_unit(y), &padic_val(y), padic_prec(y), + poly->coeffs, poly->val, poly->length, + padic_unit(x), padic_val(x), ctx); + } +} + diff --git a/external/flint-2.4.3/padic_poly/fit_length.c b/external/flint-2.4.3/padic_poly/fit_length.c new file mode 100644 index 0000000..f6eeb89 --- /dev/null +++ b/external/flint-2.4.3/padic_poly/fit_length.c @@ -0,0 +1,52 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 + +******************************************************************************/ + +#include + +#include "fmpz.h" +#include "padic_poly.h" + +void padic_poly_fit_length(padic_poly_t poly, slong len) +{ + if (len > poly->alloc) + { + if (len < 2 * poly->alloc) + len = 2 * poly->alloc; + + if (poly->alloc) /* Realloc */ + { + poly->coeffs = (fmpz *) flint_realloc(poly->coeffs, len * sizeof(fmpz)); + mpn_zero((mp_ptr) (poly->coeffs + poly->alloc), len - poly->alloc); + } + else /* Nothing allocated already so do it now */ + { + poly->coeffs = (fmpz *) flint_calloc(len, sizeof(fmpz)); + } + + poly->alloc = len; + } +} + diff --git a/external/flint-2.4.3/padic_poly/fprint.c b/external/flint-2.4.3/padic_poly/fprint.c new file mode 100644 index 0000000..7c1c15f --- /dev/null +++ b/external/flint-2.4.3/padic_poly/fprint.c @@ -0,0 +1,75 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include +#include + +#include "padic_poly.h" + +int _padic_poly_fprint(FILE *file, const fmpz *poly, slong val, slong len, + const padic_ctx_t ctx) +{ + slong i, v; + fmpz_t u; + + if (len == 0) + { + flint_fprintf(file, "0"); + return 1; + } + + fmpz_init(u); + + flint_fprintf(file, "%wd ", len); + + for (i = 0; i < len; i++) + { + flint_fprintf(file, " "); + + if (fmpz_is_zero(poly + i)) + { + flint_fprintf(file, "0"); + } + else + { + v = val + fmpz_remove(u, poly + i, ctx->p); + + _padic_fprint(file, u, v, ctx); + } + } + + fmpz_clear(u); + + return 1; +} + +int padic_poly_fprint(FILE *file, const padic_poly_t poly, + const padic_ctx_t ctx) +{ + _padic_poly_fprint(file, poly->coeffs, poly->val, poly->length, ctx); + + return 1; +} + diff --git a/external/flint-2.4.3/padic_poly/fprint_pretty.c b/external/flint-2.4.3/padic_poly/fprint_pretty.c new file mode 100644 index 0000000..65f0a86 --- /dev/null +++ b/external/flint-2.4.3/padic_poly/fprint_pretty.c @@ -0,0 +1,174 @@ +/*============================================================================ + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "padic_poly.h" + +int _padic_poly_fprint_pretty(FILE *file, + const fmpz *poly, slong len, slong val, + const char *var, + const padic_ctx_t ctx) +{ + slong i; + padic_t x; + + padic_init(x); /* Precision is not used anywhere! */ + + if (len == 0) + { + fputc('0', file); + } + else if (len == 1) + { + _padic_fprint(file, poly + 0, val, ctx); + } + else if (len == 2) + { + fmpz_set(padic_unit(x), poly + 1); + padic_val(x) = val; + _padic_canonicalise(x, ctx); + + if (padic_is_one(x)) + { + flint_fprintf(file, "%s", var); + } + else if (*(padic_unit(x)) == WORD(-1) && padic_val(x) == 0) + { + flint_fprintf(file, "-%s", var); + } + else + { + fputc('(', file); + padic_fprint(file, x, ctx); + fputc(')', file); + flint_fprintf(file, "*%s", var); + } + + fmpz_abs(padic_unit(x), poly); + padic_val(x) = val; + _padic_canonicalise(x, ctx); + + if (fmpz_sgn(poly) > 0) + { + fputc('+', file); + } + else if (fmpz_sgn(poly) < 0) + { + fputc('-', file); + } + fputc('(', file); + padic_fprint(file, x, ctx); + fputc(')', file); + } + else /* len >= 3 */ + { + i = len - 1; /* i >= 2 */ + { + fmpz_set(padic_unit(x), poly + i); + padic_val(x) = val; + _padic_canonicalise(x, ctx); + + if (padic_is_one(x)) + flint_fprintf(file, "%s^%wd", var, i); + else if (*(padic_unit(x)) == WORD(-1) && padic_val(x) == 0) + flint_fprintf(file, "-%s^%wd", var, i); + else + { + fputc('(', file); + padic_fprint(file, x, ctx); + fputc(')', file); + flint_fprintf(file, "*%s^%wd", var, i); + } + --i; + } + + for (; i > 1; --i) + { + if (*(poly + i) == 0) + continue; + + fmpz_abs(padic_unit(x), poly + i); + padic_val(x) = val; + _padic_canonicalise(x, ctx); + + if (fmpz_sgn(poly + i) > 0) + fputc('+', file); + else + fputc('-', file); + + if (padic_is_one(x)) + flint_fprintf(file, "%s^%wd", var, i); + else + { + fputc('(', file); + padic_fprint(file, x, ctx); + fputc(')', file); + flint_fprintf(file, "*%s^%wd", var, i); + } + } + + if (*(poly + 1)) + { + fmpz_abs(padic_unit(x), poly + 1); + padic_val(x) = val; + _padic_canonicalise(x, ctx); + + fputc(fmpz_sgn(poly + 1) > 0 ? '+' : '-', file); + + if (padic_is_one(x)) + fputs(var, file); + else + { + fputc('(', file); + padic_fprint(file, x, ctx); + fputc(')', file); + fputc('*', file); + fputs(var, file); + } + } + if (*(poly)) + { + fmpz_abs(padic_unit(x), poly); + padic_val(x) = val; + _padic_canonicalise(x, ctx); + + fputc(fmpz_sgn(poly) > 0 ? '+' : '-', file); + fputc('(', file); + padic_fprint(file, x, ctx); + fputc(')', file); + } + } + + padic_clear(x); + return 1; +} + +int padic_poly_fprint_pretty(FILE *file, + const padic_poly_t poly, const char *var, + const padic_ctx_t ctx) +{ + return _padic_poly_fprint_pretty(file, + poly->coeffs, poly->length, poly->val, var, ctx); +} + diff --git a/external/flint-2.4.3/padic_poly/get_coeff_padic.c b/external/flint-2.4.3/padic_poly/get_coeff_padic.c new file mode 100644 index 0000000..75e0bde --- /dev/null +++ b/external/flint-2.4.3/padic_poly/get_coeff_padic.c @@ -0,0 +1,42 @@ +/*============================================================================ + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "padic_poly.h" + +void padic_poly_get_coeff_padic(padic_t x, const padic_poly_t f, slong n, + const padic_ctx_t ctx) +{ + if (n < f->length && !fmpz_is_zero(f->coeffs + n)) + { + fmpz_set(padic_unit(x), f->coeffs + n); + padic_val(x) = f->val; + padic_reduce(x, ctx); + } + else + { + padic_zero(x); + } +} + diff --git a/external/flint-2.4.3/padic_poly/get_fmpq_poly.c b/external/flint-2.4.3/padic_poly/get_fmpq_poly.c new file mode 100644 index 0000000..b70f253 --- /dev/null +++ b/external/flint-2.4.3/padic_poly/get_fmpq_poly.c @@ -0,0 +1,83 @@ +/*============================================================================ + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpq_poly.h" +#include "padic_poly.h" + +/* + Assumes that len > 0. + */ + +static void _padic_poly_get_fmpq_poly(fmpz *rop, fmpz_t den, + const fmpz *op, slong val, slong len, + const fmpz_t p) +{ + if (val == 0) + { + _fmpz_vec_set(rop, op, len); + fmpz_one(den); + } + else if (val == 1) + { + _fmpz_vec_scalar_mul_fmpz(rop, op, len, p); + fmpz_one(den); + } + else if (val > 1) + { + fmpz_t t; + + fmpz_init(t); + fmpz_pow_ui(t, p, val); + + _fmpz_vec_scalar_mul_fmpz(rop, op, len, t); + fmpz_one(den); + + fmpz_clear(t); + } + else + { + _fmpz_vec_set(rop, op, len); + fmpz_pow_ui(den, p, -val); + } +} + +void padic_poly_get_fmpq_poly(fmpq_poly_t rop, + const padic_poly_t op, const padic_ctx_t ctx) +{ + const slong len = op->length; + + if (len == 0) + { + fmpq_poly_zero(rop); + } + else + { + fmpq_poly_fit_length(rop, len); + _padic_poly_get_fmpq_poly(rop->coeffs, rop->den, + op->coeffs, op->val, op->length, ctx->p); + _fmpq_poly_set_length(rop, len); + } +} + diff --git a/external/flint-2.4.3/padic_poly/get_fmpz_poly.c b/external/flint-2.4.3/padic_poly/get_fmpz_poly.c new file mode 100644 index 0000000..8159fa3 --- /dev/null +++ b/external/flint-2.4.3/padic_poly/get_fmpz_poly.c @@ -0,0 +1,63 @@ +/*============================================================================ + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "padic_poly.h" + +int padic_poly_get_fmpz_poly(fmpz_poly_t rop, const padic_poly_t op, + const padic_ctx_t ctx) +{ + const slong len = op->length; + + if (op->val < 0) + { + return 0; + } + + if (padic_poly_is_zero(op)) + { + fmpz_poly_zero(rop); + return 1; + } + + fmpz_poly_fit_length(rop, len); + _fmpz_poly_set_length(rop, len); + + if (op->val == 0) + { + _fmpz_vec_set(rop->coeffs, op->coeffs, len); + } + else /* op->val > 0 */ + { + fmpz_t pow; + + fmpz_init(pow); + fmpz_pow_ui(pow, ctx->p, op->val); + _fmpz_vec_scalar_mul_fmpz(rop->coeffs, op->coeffs, len, pow); + fmpz_clear(pow); + } + + return 1; +} + diff --git a/external/flint-2.4.3/padic_poly/init.c b/external/flint-2.4.3/padic_poly/init.c new file mode 100644 index 0000000..54fb4e3 --- /dev/null +++ b/external/flint-2.4.3/padic_poly/init.c @@ -0,0 +1,50 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "padic_poly.h" + +void padic_poly_init(padic_poly_t poly) +{ + poly->coeffs = NULL; + poly->alloc = 0; + poly->length = 0; + poly->val = 0; + poly->N = PADIC_DEFAULT_PREC; +} + +void padic_poly_init2(padic_poly_t poly, slong alloc, slong prec) +{ + poly->coeffs = alloc ? (fmpz *) flint_calloc(alloc, sizeof(fmpz)) : NULL; + poly->alloc = alloc; + poly->length = 0; + poly->val = 0; + poly->N = prec; +} + diff --git a/external/flint-2.4.3/padic_poly/inv_series.c b/external/flint-2.4.3/padic_poly/inv_series.c new file mode 100644 index 0000000..10f8aa2 --- /dev/null +++ b/external/flint-2.4.3/padic_poly/inv_series.c @@ -0,0 +1,108 @@ +/*============================================================================ + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_mod_poly.h" +#include "padic_poly.h" + +void padic_poly_inv_series(padic_poly_t Qinv, const padic_poly_t Q, slong n, + const padic_ctx_t ctx) +{ + fmpz_t cinv; + + fmpz_t pow; + int palloc; + + fmpz *Qcopy; + int Qalloc; + + if (Q->length == 0 || fmpz_is_zero(Q->coeffs + 0)) + { + flint_printf("Exception (padic_poly_inv_series): Constant term is zero.\n"); + abort(); + } + if (fmpz_divisible(Q->coeffs + 0, ctx->p)) + { + flint_printf("Exception (padic_poly_inv_series):\n"); + flint_printf("Valuation of constant term is not minimal.\n"); + abort(); + } + + if (- Q->val >= Qinv->N) + { + padic_poly_zero(Qinv); + return; + } + + if (Q->length >= n) + { + Qcopy = Q->coeffs; + Qalloc = 0; + } + else + { + slong i; + + Qcopy = (fmpz *) flint_malloc(n * sizeof(fmpz)); + for (i = 0; i < Q->length; i++) + Qcopy[i] = Q->coeffs[i]; + mpn_zero((mp_ptr) Qcopy + i, n - i); + Qalloc = 1; + } + + fmpz_init(cinv); + fmpz_init(pow); + + _padic_inv(cinv, Q->coeffs, ctx->p, Qinv->N + Q->val); + palloc = _padic_ctx_pow_ui(pow, Qinv->N + Q->val, ctx); + + if (Qinv != Q) + { + padic_poly_fit_length(Qinv, n); + _fmpz_mod_poly_inv_series_newton(Qinv->coeffs, Qcopy, n, cinv, pow); + } + else + { + fmpz *t = _fmpz_vec_init(n); + + _fmpz_mod_poly_inv_series_newton(t, Qcopy, n, cinv, pow); + + _fmpz_vec_clear(Qinv->coeffs, Qinv->alloc); + Qinv->coeffs = t; + Qinv->alloc = n; + Qinv->length = n; + } + + Qinv->val = - Q->val; + + _padic_poly_set_length(Qinv, n); + _padic_poly_normalise(Qinv); + + fmpz_clear(cinv); + if (palloc) + fmpz_clear(pow); + if (Qalloc) + flint_free(Qcopy); +} + diff --git a/external/flint-2.4.3/padic_poly/is_canonical.c b/external/flint-2.4.3/padic_poly/is_canonical.c new file mode 100644 index 0000000..479a844 --- /dev/null +++ b/external/flint-2.4.3/padic_poly/is_canonical.c @@ -0,0 +1,47 @@ +/*============================================================================ + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "padic_poly.h" + +int _padic_poly_is_canonical(const fmpz *op, slong val, slong len, + const padic_ctx_t ctx) +{ + if (len == 0) + { + return (val == 0); + } + else + { + slong w = _fmpz_vec_ord_p(op, len, ctx->p); + + return (w == 0); + } +} + +int padic_poly_is_canonical(const padic_poly_t op, const padic_ctx_t ctx) +{ + return _padic_poly_is_canonical(op->coeffs, op->val, op->length, ctx); +} + diff --git a/external/flint-2.4.3/padic_poly/is_reduced.c b/external/flint-2.4.3/padic_poly/is_reduced.c new file mode 100644 index 0000000..bc0ddd6 --- /dev/null +++ b/external/flint-2.4.3/padic_poly/is_reduced.c @@ -0,0 +1,68 @@ +/*============================================================================ + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "padic_poly.h" + +int _padic_poly_is_reduced(const fmpz *op, slong val, slong len, slong N, + const padic_ctx_t ctx) +{ + slong w; + + if (len == 0) + { + return (val == 0); + } + + w = _fmpz_vec_ord_p(op, len, ctx->p); + + if (w != 0 || val >= N) + { + return 0; + } + + { + fmpz_t pow; + int r, alloc; + slong i; + + alloc = _padic_ctx_pow_ui(pow, N - val, ctx); + + r = 1; + for (i = 0; (i < len) && (r); i++) + if (fmpz_sgn(op + i) < 0 || fmpz_cmp(op + i, pow) >= 0) + r = 0; + + if (alloc) + fmpz_clear(pow); + + return r; + } +} + +int padic_poly_is_reduced(const padic_poly_t op, const padic_ctx_t ctx) +{ + return _padic_poly_is_reduced(op->coeffs, op->val, op->length, op->N, ctx); +} + diff --git a/external/flint-2.4.3/padic_poly/mul.c b/external/flint-2.4.3/padic_poly/mul.c new file mode 100644 index 0000000..283d254 --- /dev/null +++ b/external/flint-2.4.3/padic_poly/mul.c @@ -0,0 +1,91 @@ +/*============================================================================ + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "padic_poly.h" + +void _padic_poly_mul(fmpz *rop, slong *rval, slong N, + const fmpz *op1, slong val1, slong len1, + const fmpz *op2, slong val2, slong len2, + const padic_ctx_t ctx) +{ + fmpz_t pow; + int alloc; + + *rval = val1 + val2; + + alloc = _padic_ctx_pow_ui(pow, N - *rval, ctx); + + _fmpz_poly_mul(rop, op1, len1, op2, len2); + _fmpz_vec_scalar_mod_fmpz(rop, rop, len1 + len2 - 1, pow); + + if (alloc) + fmpz_clear(pow); +} + +void padic_poly_mul(padic_poly_t f, + const padic_poly_t g, const padic_poly_t h, + const padic_ctx_t ctx) +{ + const slong lenG = g->length; + const slong lenH = h->length; + const slong lenF = lenG + lenH - 1; + + if (lenG == 0 || lenH == 0 || g->val + h->val >= f->N) + { + padic_poly_zero(f); + } + else + { + fmpz *t; + + if (f == g || f == h) + { + t = _fmpz_vec_init(lenF); + } + else + { + padic_poly_fit_length(f, lenF); + t = f->coeffs; + } + + if (lenG >= lenH) + _padic_poly_mul(t, &(f->val), f->N, g->coeffs, g->val, lenG, + h->coeffs, h->val, lenH, ctx); + else + _padic_poly_mul(t, &(f->val), f->N, h->coeffs, h->val, lenH, + g->coeffs, g->val, lenG, ctx); + + if (f == g || f == h) + { + _fmpz_vec_clear(f->coeffs, f->alloc); + f->coeffs = t; + f->alloc = lenF; + } + + _padic_poly_set_length(f, lenF); + _padic_poly_normalise(f); + } +} + diff --git a/external/flint-2.4.3/padic_poly/neg.c b/external/flint-2.4.3/padic_poly/neg.c new file mode 100644 index 0000000..309596b --- /dev/null +++ b/external/flint-2.4.3/padic_poly/neg.c @@ -0,0 +1,64 @@ +/*============================================================================ + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_mod_poly.h" +#include "padic_poly.h" + +void padic_poly_neg(padic_poly_t f, const padic_poly_t g, + const padic_ctx_t ctx) +{ + const slong len = g->length; + + if (len == 0 || g->val >= padic_poly_prec(f)) + { + padic_poly_zero(f); + } + else + { + fmpz_t pow; + int alloc; + + padic_poly_fit_length(f, len); + _padic_poly_set_length(f, len); + f->val = g->val; + + alloc = _padic_ctx_pow_ui(pow, padic_poly_prec(f) - f->val, ctx); + + if (padic_poly_prec(f) >= padic_poly_prec(g)) /* No reduction */ + { + _fmpz_mod_poly_neg(f->coeffs, g->coeffs, len, pow); + } + else /* Reduction necessary? */ + { + _fmpz_vec_scalar_mod_fmpz(f->coeffs, g->coeffs, len, pow); + _fmpz_mod_poly_neg(f->coeffs, f->coeffs, len, pow); + _padic_poly_normalise(f); + } + + if (alloc) + fmpz_clear(pow); + } +} + diff --git a/external/flint-2.4.3/padic_poly/normalise.c b/external/flint-2.4.3/padic_poly/normalise.c new file mode 100644 index 0000000..670d496 --- /dev/null +++ b/external/flint-2.4.3/padic_poly/normalise.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 + +******************************************************************************/ + +#include "fmpz_vec.h" +#include "padic_poly.h" + +void _padic_poly_normalise(padic_poly_t poly) +{ + slong len = poly->length; + + FMPZ_VEC_NORM(poly->coeffs, len); + + poly->length = len; +} + diff --git a/external/flint-2.4.3/padic_poly/pow.c b/external/flint-2.4.3/padic_poly/pow.c new file mode 100644 index 0000000..0a3e9b3 --- /dev/null +++ b/external/flint-2.4.3/padic_poly/pow.c @@ -0,0 +1,89 @@ +/*============================================================================ + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_mod_poly.h" +#include "padic_poly.h" + +void _padic_poly_pow(fmpz *rop, slong *rval, slong N, + const fmpz *op, slong val, slong len, ulong e, + const padic_ctx_t ctx) +{ + fmpz_t pow; + int alloc; + + *rval = (slong) e * val; + + alloc = _padic_ctx_pow_ui(pow, N - *rval, ctx); + + _fmpz_mod_poly_pow(rop, op, len, e, pow); + + if (alloc) + fmpz_clear(pow); +} + +void padic_poly_pow(padic_poly_t rop, const padic_poly_t op, ulong e, + const padic_ctx_t ctx) +{ + if (e == 0) + { + padic_poly_one(rop); + } + else if (op->length == 0 || (slong) e * op->val >= rop->N) + { + padic_poly_zero(rop); + } + else if (e == 1) + { + padic_poly_set(rop, op, ctx); + } + else + { + const slong rlen = (slong) e * (op->length - 1) + 1; + fmpz *t; + + if (rop == op) + { + t = _fmpz_vec_init(rlen); + } + else + { + padic_poly_fit_length(rop, rlen); + t = rop->coeffs; + } + + _padic_poly_pow(t, &(rop->val), rop->N, + op->coeffs, op->val, op->length, e, ctx); + + if (rop == op) + { + _fmpz_vec_clear(rop->coeffs, rop->alloc); + rop->coeffs = t; + rop->alloc = rlen; + } + _padic_poly_set_length(rop, rlen); + _padic_poly_normalise(rop); + } +} + diff --git a/external/flint-2.4.3/padic_poly/randtest.c b/external/flint-2.4.3/padic_poly/randtest.c new file mode 100644 index 0000000..02958c6 --- /dev/null +++ b/external/flint-2.4.3/padic_poly/randtest.c @@ -0,0 +1,127 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include + +#include "flint.h" +#include "padic_poly.h" + +void padic_poly_randtest_val(padic_poly_t f, flint_rand_t state, + slong val, slong len, const padic_ctx_t ctx) +{ + const slong N = padic_poly_prec(f); + + if (len == 0) + return; + + if (val >= N) + { + padic_poly_zero(f); + } + else + { + slong i; + fmpz_t pow; + int alloc; + + f->val = val; + + padic_poly_fit_length(f, len); + + alloc = _padic_ctx_pow_ui(pow, N - f->val, ctx); + + for (i = 0; i < len; i++) + fmpz_randm(f->coeffs + i, state, pow); + + if (alloc) + fmpz_clear(pow); + + for (i = 0; i < len; i++) + if (!fmpz_divisible(f->coeffs + i, ctx->p)) + break; + if (i == len) + fmpz_one(f->coeffs + n_randint(state, len)); + + _padic_poly_set_length(f, len); + _padic_poly_normalise(f); + + padic_poly_reduce(f, ctx); + } +} + +void padic_poly_randtest(padic_poly_t f, flint_rand_t state, + slong len, const padic_ctx_t ctx) +{ + const slong N = padic_poly_prec(f); + + slong min, max, val; + + if (N > 0) + { + min = - ((N + 9) / 10); + max = N; + } + else if (N < 0) + { + min = N - ((-N + 9) / 10); + max = N; + } + else /* N == 0 */ + { + min = -10; + max = 0; + } + + val = n_randint(state, max - min) + min; + + padic_poly_randtest_val(f, state, val, len, ctx); +} + +void padic_poly_randtest_not_zero(padic_poly_t f, flint_rand_t state, + slong len, const padic_ctx_t ctx) +{ + slong i; + + if (len == 0) + { + flint_printf("Exception (padic_poly_randtest_not_zero). len == 0.\n"); + abort(); + } + + padic_poly_randtest(f, state, len, ctx); + for (i = 0; !padic_poly_is_zero(f) && (i < 10); i++) + padic_poly_randtest(f, state, len, ctx); + + if (padic_poly_is_zero(f)) + { + padic_poly_fit_length(f, 1); + _padic_poly_set_length(f, 1); + fmpz_one(f->coeffs + 0); + f->val = f->N - 1; + } +} + diff --git a/external/flint-2.4.3/padic_poly/realloc.c b/external/flint-2.4.3/padic_poly/realloc.c new file mode 100644 index 0000000..5f6d797 --- /dev/null +++ b/external/flint-2.4.3/padic_poly/realloc.c @@ -0,0 +1,57 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "padic_poly.h" + +void padic_poly_realloc(padic_poly_t poly, slong alloc, const fmpz_t p) +{ + if (alloc == 0) /* Clear up, reinitialise */ + { + padic_poly_clear(poly); + padic_poly_init(poly); + return; + } + + if (poly->alloc) /* Realloc */ + { + padic_poly_truncate(poly, alloc, p); + + poly->coeffs = (fmpz *) flint_realloc(poly->coeffs, alloc * sizeof(fmpz)); + if (alloc > poly->alloc) + mpn_zero((mp_ptr) (poly->coeffs + poly->alloc), + alloc - poly->alloc); + } + else /* Nothing allocated already so do it now */ + { + poly->coeffs = (fmpz *) flint_calloc(alloc, sizeof(fmpz)); + } + + poly->alloc = alloc; +} diff --git a/external/flint-2.4.3/padic_poly/reduce.c b/external/flint-2.4.3/padic_poly/reduce.c new file mode 100644 index 0000000..55f103f --- /dev/null +++ b/external/flint-2.4.3/padic_poly/reduce.c @@ -0,0 +1,59 @@ +/*============================================================================ + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "padic_poly.h" + +void padic_poly_reduce(padic_poly_t poly, const padic_ctx_t ctx) +{ + const slong N = padic_poly_prec(poly); + + if (poly->length > 0) + { + if (poly->val >= N) + { + padic_poly_zero(poly); + } + else + { + fmpz_t pow; + int alloc; + + alloc = _padic_ctx_pow_ui(pow, N - poly->val, ctx); + + _fmpz_vec_scalar_mod_fmpz(poly->coeffs, poly->coeffs, poly->length, pow); + + if (alloc) + fmpz_clear(pow); + + _padic_poly_normalise(poly); + + if (poly->length == 0) + { + poly->val = 0; + } + } + } +} + diff --git a/external/flint-2.4.3/padic_poly/scalar_mul_padic.c b/external/flint-2.4.3/padic_poly/scalar_mul_padic.c new file mode 100644 index 0000000..3985450 --- /dev/null +++ b/external/flint-2.4.3/padic_poly/scalar_mul_padic.c @@ -0,0 +1,72 @@ +/*============================================================================ + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "padic_poly.h" + +void _padic_poly_scalar_mul_padic(fmpz *rop, slong *rval, slong N, + const fmpz *op, slong val, slong len, + const padic_t c, const padic_ctx_t ctx) +{ + if (padic_is_zero(c) || val + padic_val(c) >= N) + { + _fmpz_vec_zero(rop, len); + *rval = 0; + } + else + { + fmpz_t pow; + int alloc; + + *rval = val + padic_val(c); + + alloc = _padic_ctx_pow_ui(pow, N - *rval, ctx); + + _fmpz_vec_scalar_mul_fmpz(rop, op, len, padic_unit(c)); + + _fmpz_vec_scalar_mod_fmpz(rop, rop, len, pow); + + if (alloc) + fmpz_clear(pow); + } +} + +void padic_poly_scalar_mul_padic(padic_poly_t rop, const padic_poly_t op, + const padic_t c, const padic_ctx_t ctx) +{ + if (padic_poly_is_zero(op) || padic_is_zero(c) || + op->val + padic_val(c) >= rop->N) + { + padic_poly_zero(rop); + } + else + { + padic_poly_fit_length(rop, op->length); + _padic_poly_set_length(rop, op->length); + + _padic_poly_scalar_mul_padic(rop->coeffs, &(rop->val), rop->N, + op->coeffs, op->val, op->length, c, ctx); + } +} + diff --git a/external/flint-2.4.3/padic_poly/set.c b/external/flint-2.4.3/padic_poly/set.c new file mode 100644 index 0000000..4788e5e --- /dev/null +++ b/external/flint-2.4.3/padic_poly/set.c @@ -0,0 +1,69 @@ +/*============================================================================ + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "padic_poly.h" + +void padic_poly_set(padic_poly_t poly1, + const padic_poly_t poly2, const padic_ctx_t ctx) +{ + if (poly1 != poly2) /* Aliasing is trivial */ + { + slong len2 = poly2->length, N1 = padic_poly_prec(poly1); + + if (len2 == 0 || poly2->val >= N1) + { + padic_poly_zero(poly1); + } + else + { + padic_poly_fit_length(poly1, len2); + _padic_poly_set_length(poly1, len2); + poly1->val = poly2->val; + + if (N1 >= padic_poly_prec(poly2)) /* No reduction */ + { + _fmpz_vec_set(poly1->coeffs, poly2->coeffs, len2); + } + else /* Reduction necessary */ + { + fmpz_t pow; + int alloc; + + alloc = _padic_ctx_pow_ui(pow, N1 - poly1->val, ctx); + + _fmpz_vec_scalar_mod_fmpz(poly1->coeffs, poly2->coeffs, len2, pow); + + if (alloc) + fmpz_clear(pow); + + _padic_poly_normalise(poly1); + /* Length cannot be zero, so no need to check */ + /* if (poly->length == 0) */ + /* poly->val = 0; */ + } + } + } +} + diff --git a/external/flint-2.4.3/padic_poly/set_coeff_padic.c b/external/flint-2.4.3/padic_poly/set_coeff_padic.c new file mode 100644 index 0000000..0dc70c0 --- /dev/null +++ b/external/flint-2.4.3/padic_poly/set_coeff_padic.c @@ -0,0 +1,89 @@ +/*============================================================================ + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "padic_poly.h" + +void padic_poly_set_coeff_padic(padic_poly_t poly, slong n, const padic_t x, + const padic_ctx_t ctx) +{ + if (padic_is_zero(x) || padic_val(x) >= padic_poly_prec(poly)) + { + if (n < poly->length) + { + fmpz_zero(poly->coeffs + n); + padic_poly_canonicalise(poly, ctx->p); + } + return; + } + + padic_poly_fit_length(poly, n + 1); + + if (n + 1 > poly->length) + { + mpn_zero((mp_ptr) (poly->coeffs + poly->length), n - poly->length); + poly->length = n + 1; + } + + if (padic_val(x) == poly->val) + { + fmpz_set(poly->coeffs + n, padic_unit(x)); + } + else if (poly->val < padic_val(x)) + { + fmpz_t y; + + fmpz_init(y); + fmpz_pow_ui(y, ctx->p, padic_val(x) - poly->val); + fmpz_mul(poly->coeffs + n, padic_unit(x), y); + fmpz_clear(y); + padic_poly_canonicalise(poly, ctx->p); + } + else /* poly->val > x->val */ + { + fmpz_t pow; + + fmpz_init(pow); + fmpz_pow_ui(pow, ctx->p, poly->val - padic_val(x)); + _fmpz_vec_scalar_mul_fmpz(poly->coeffs, + poly->coeffs, poly->length, pow); + fmpz_set(poly->coeffs + n, padic_unit(x)); + fmpz_clear(pow); + poly->val = padic_val(x); + } + + if (padic_poly_prec(poly) < padic_prec(x)) /* Reduction? */ + { + int c; + fmpz_t pow; + + c = _padic_ctx_pow_ui(pow, padic_poly_prec(poly) - padic_poly_val(poly), ctx); + fmpz_mod(poly->coeffs + n, poly->coeffs + n, pow); + if (c) + fmpz_clear(pow); + } + + _padic_poly_normalise(poly); +} + diff --git a/external/flint-2.4.3/padic_poly/set_fmpq.c b/external/flint-2.4.3/padic_poly/set_fmpq.c new file mode 100644 index 0000000..363694a --- /dev/null +++ b/external/flint-2.4.3/padic_poly/set_fmpq.c @@ -0,0 +1,38 @@ +/*============================================================================ + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "padic_poly.h" + +void padic_poly_set_fmpq(padic_poly_t poly, const fmpq_t x, + const padic_ctx_t ctx) +{ + padic_t y; + + padic_init2(y, padic_poly_prec(poly)); + padic_set_fmpq(y, x, ctx); + padic_poly_set_padic(poly, y, ctx); + padic_clear(y); +} + diff --git a/external/flint-2.4.3/padic_poly/set_fmpq_poly.c b/external/flint-2.4.3/padic_poly/set_fmpq_poly.c new file mode 100644 index 0000000..577e67d --- /dev/null +++ b/external/flint-2.4.3/padic_poly/set_fmpq_poly.c @@ -0,0 +1,68 @@ +/*============================================================================ + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_vec.h" +#include "fmpq_poly.h" +#include "padic_poly.h" + +void padic_poly_set_fmpq_poly(padic_poly_t f, + const fmpq_poly_t g, const padic_ctx_t ctx) +{ + const slong len = g->length; + + if (len == 0) + { + padic_poly_zero(f); + } + else + { + const slong N = padic_poly_prec(f); + fmpz_t t; + + fmpz_init(t); + + f->val = - fmpz_remove(t, g->den, ctx->p); + + if (f->val < N) + { + padic_poly_fit_length(f, len); + _padic_poly_set_length(f, len); + + _padic_inv(t, t, ctx->p, N - f->val); + _fmpz_vec_scalar_mul_fmpz(f->coeffs, g->coeffs, len, t); + if (f->val == 0) + padic_poly_canonicalise(f, ctx->p); + + padic_poly_reduce(f, ctx); + } + else + { + padic_poly_zero(f); + } + + fmpz_clear(t); + } +} + diff --git a/external/flint-2.4.3/padic_poly/set_fmpz.c b/external/flint-2.4.3/padic_poly/set_fmpz.c new file mode 100644 index 0000000..c8507d0 --- /dev/null +++ b/external/flint-2.4.3/padic_poly/set_fmpz.c @@ -0,0 +1,38 @@ +/*============================================================================ + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "padic_poly.h" + +void padic_poly_set_fmpz(padic_poly_t poly, const fmpz_t x, + const padic_ctx_t ctx) +{ + padic_t y; + + padic_init2(y, padic_poly_prec(poly)); + padic_set_fmpz(y, x, ctx); + padic_poly_set_padic(poly, y, ctx); + padic_clear(y); +} + diff --git a/external/flint-2.4.3/padic_poly/set_fmpz_poly.c b/external/flint-2.4.3/padic_poly/set_fmpz_poly.c new file mode 100644 index 0000000..d76849e --- /dev/null +++ b/external/flint-2.4.3/padic_poly/set_fmpz_poly.c @@ -0,0 +1,42 @@ +/*============================================================================ + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_poly.h" +#include "padic_poly.h" + +void padic_poly_set_fmpz_poly(padic_poly_t f, const fmpz_poly_t g, + const padic_ctx_t ctx) +{ + const slong len = g->length; + + padic_poly_fit_length(f, len); + _padic_poly_set_length(f, len); + _fmpz_vec_set(f->coeffs, g->coeffs, len); + f->val = 0; + + padic_poly_canonicalise(f, ctx->p); + padic_poly_reduce(f, ctx); +} + diff --git a/external/flint-2.4.3/padic_poly/set_padic.c b/external/flint-2.4.3/padic_poly/set_padic.c new file mode 100644 index 0000000..98bd08f --- /dev/null +++ b/external/flint-2.4.3/padic_poly/set_padic.c @@ -0,0 +1,61 @@ +/*============================================================================ + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "padic_poly.h" + +void padic_poly_set_padic(padic_poly_t poly, + const padic_t x, const padic_ctx_t ctx) +{ + slong N1 = padic_poly_prec(poly); + + if (padic_is_zero(x) || padic_val(x) >= N1) + { + padic_poly_zero(poly); + } + else + { + padic_poly_fit_length(poly, 1); + _padic_poly_set_length(poly, 1); + poly->val = padic_val(x); + + if (N1 >= padic_prec(x)) /* No reduction */ + { + fmpz_set(poly->coeffs, padic_unit(x)); + } + else /* Reduction */ + { + fmpz_t pow; + int alloc; + + alloc = _padic_ctx_pow_ui(pow, N1 - padic_val(x), ctx); + + fmpz_mod(poly->coeffs, padic_unit(x), pow); + + if (alloc) + fmpz_clear(pow); + } + } +} + diff --git a/external/flint-2.4.3/padic_poly/set_si.c b/external/flint-2.4.3/padic_poly/set_si.c new file mode 100644 index 0000000..69b31ff --- /dev/null +++ b/external/flint-2.4.3/padic_poly/set_si.c @@ -0,0 +1,37 @@ +/*============================================================================ + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "padic_poly.h" + +void padic_poly_set_si(padic_poly_t poly, slong x, const padic_ctx_t ctx) +{ + padic_t y; + + padic_init2(y, padic_poly_prec(poly)); + padic_set_si(y, x, ctx); + padic_poly_set_padic(poly, y, ctx); + padic_clear(y); +} + diff --git a/external/flint-2.4.3/padic_poly/set_ui.c b/external/flint-2.4.3/padic_poly/set_ui.c new file mode 100644 index 0000000..519f2a2 --- /dev/null +++ b/external/flint-2.4.3/padic_poly/set_ui.c @@ -0,0 +1,37 @@ +/*============================================================================ + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "padic_poly.h" + +void padic_poly_set_ui(padic_poly_t poly, ulong x, const padic_ctx_t ctx) +{ + padic_t y; + + padic_init2(y, padic_poly_prec(poly)); + padic_set_ui(y, x, ctx); + padic_poly_set_padic(poly, y, ctx); + padic_clear(y); +} + diff --git a/external/flint-2.4.3/padic_poly/shift_left.c b/external/flint-2.4.3/padic_poly/shift_left.c new file mode 100644 index 0000000..addef14 --- /dev/null +++ b/external/flint-2.4.3/padic_poly/shift_left.c @@ -0,0 +1,54 @@ +/*============================================================================ + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "padic_poly.h" + +void padic_poly_shift_left(padic_poly_t rop, const padic_poly_t op, slong n, + const padic_ctx_t ctx) +{ + if (rop->N < op->N) + { + flint_printf("Exception (padic_poly_shift_left). rop->N < op->N.\n"); + abort(); + } + + if (n == 0) + { + padic_poly_set(rop, op, ctx); + } + else if (op->length == 0) + { + padic_poly_zero(rop); + } + else + { + padic_poly_fit_length(rop, op->length + n); + _fmpz_poly_shift_left(rop->coeffs, op->coeffs, op->length, n); + rop->val = op->val; + _padic_poly_set_length(rop, op->length + n); + /* TODO: Reduce */ + } +} + diff --git a/external/flint-2.4.3/padic_poly/shift_right.c b/external/flint-2.4.3/padic_poly/shift_right.c new file mode 100644 index 0000000..33f15ff --- /dev/null +++ b/external/flint-2.4.3/padic_poly/shift_right.c @@ -0,0 +1,50 @@ +/*============================================================================ + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "padic_poly.h" + +void padic_poly_shift_right(padic_poly_t rop, const padic_poly_t op, slong n, + const padic_ctx_t ctx) +{ + if (n == 0) + { + padic_poly_set(rop, op, ctx); + } + else if (op->length <= n) + { + padic_poly_zero(rop); + } + else + { + padic_poly_fit_length(rop, op->length - n); + _fmpz_poly_shift_right(rop->coeffs, op->coeffs, op->length, n); + rop->val = op->val; + _padic_poly_set_length(rop, op->length - n); + _padic_poly_normalise(rop); + padic_poly_canonicalise(rop, ctx->p); + /* TODO: Reduce */ + } +} + diff --git a/external/flint-2.4.3/padic_poly/sub.c b/external/flint-2.4.3/padic_poly/sub.c new file mode 100644 index 0000000..43e0d94 --- /dev/null +++ b/external/flint-2.4.3/padic_poly/sub.c @@ -0,0 +1,146 @@ +/*============================================================================ + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_mod_poly.h" +#include "padic_poly.h" + +void _padic_poly_sub(fmpz *rop, slong *val, slong N, + const fmpz *op1, slong val1, slong len1, slong N1, + const fmpz *op2, slong val2, slong len2, slong N2, + const padic_ctx_t ctx) +{ + const slong len = FLINT_MAX(len1, len2); + + *val = FLINT_MIN(val1, val2); + + if (val1 == val2) + { + _fmpz_poly_sub(rop, op1, len1, op2, len2); + _padic_poly_canonicalise(rop, val, len, ctx->p); + } + else + { + fmpz_t x; + + fmpz_init(x); + if (val1 < val2) /* F := p^g (G - p^{h-g} H) */ + { + fmpz_pow_ui(x, ctx->p, val2 - val1); + + if (rop == op1) + { + _fmpz_vec_zero(rop + len1, len2 - len1); + _fmpz_vec_scalar_submul_fmpz(rop, op2, len2, x); + } + else + { + _fmpz_vec_scalar_mul_fmpz(rop, op2, len2, x); + _fmpz_vec_neg(rop, rop, len2); + _fmpz_poly_add(rop, op1, len1, rop, len2); + } + } + else /* F := p^h (p^(g-h) G - H) */ + { + fmpz_pow_ui(x, ctx->p, val1 - val2); + + if (rop == op2) + { + _fmpz_vec_neg(rop, op2, len2); + _fmpz_vec_zero(rop + len2, len1 - len2); + _fmpz_vec_scalar_addmul_fmpz(rop, op1, len1, x); + } + else + { + _fmpz_vec_scalar_mul_fmpz(rop, op1, len1, x); + _fmpz_poly_sub(rop, rop, len1, op2, len2); + } + } + fmpz_clear(x); + } + + /* Reduce */ + if (N - *val > 0) + { + fmpz_t pow; + int alloc; + + alloc = _padic_ctx_pow_ui(pow, N - *val, ctx); + + if (N >= N1 && N >= N2) + { + slong i; + for (i = 0; i < len; i++) + if (fmpz_sgn(rop + i) < 0) + fmpz_add(rop + i, rop + i, pow); + } + else + { + _fmpz_vec_scalar_mod_fmpz(rop, rop, len, pow); + } + + if (alloc) + fmpz_clear(pow); + } + else + { + _fmpz_vec_zero(rop, len); + *val = 0; + } +} + +void padic_poly_sub(padic_poly_t f, + const padic_poly_t g, const padic_poly_t h, + const padic_ctx_t ctx) +{ + const slong lenG = g->length; + const slong lenH = h->length; + const slong lenF = FLINT_MAX(lenG, lenH); + + if (lenG == 0) + { + padic_poly_neg(f, h, ctx); + return; + } + if (lenH == 0) + { + padic_poly_set(f, g, ctx); + return; + } + if ((lenG == 0 && lenH == 0) || (FLINT_MIN(g->val, h->val) >= f->N)) + { + padic_poly_zero(f); + return; + } + + padic_poly_fit_length(f, lenF); + + _padic_poly_sub(f->coeffs, &(f->val), f->N, + g->coeffs, g->val, lenG, g->N, + h->coeffs, h->val, lenH, h->N, ctx); + + _padic_poly_set_length(f, lenF); + _padic_poly_normalise(f); +} + diff --git a/external/flint-2.4.3/padic_poly/swap.c b/external/flint-2.4.3/padic_poly/swap.c new file mode 100644 index 0000000..818276e --- /dev/null +++ b/external/flint-2.4.3/padic_poly/swap.c @@ -0,0 +1,56 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "padic_poly.h" + +void padic_poly_swap(padic_poly_t poly1, padic_poly_t poly2) +{ + if (poly1 != poly2) + { + slong t; + fmpz *c; + + t = poly1->length; + poly1->length = poly2->length; + poly2->length = t; + + t = poly1->alloc; + poly1->alloc = poly2->alloc; + poly2->alloc = t; + + t = poly1->val; + poly1->val = poly2->val; + poly2->val = t; + + t = poly1->N; + poly1->N = poly2->N; + poly2->N = t; + + c = poly1->coeffs; + poly1->coeffs = poly2->coeffs; + poly2->coeffs = c; + } +} + diff --git a/external/flint-2.4.3/padic_poly/test/t-add.c b/external/flint-2.4.3/padic_poly/test/t-add.c new file mode 100644 index 0000000..b8c7d1a --- /dev/null +++ b/external/flint-2.4.3/padic_poly/test/t-add.c @@ -0,0 +1,193 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "long_extras.h" +#include "ulong_extras.h" +#include "padic_poly.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("add... "); + fflush(stdout); + + + + /* Check aliasing of a and c */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_poly_t a, b, c; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_poly_init2(a, 0, N); + padic_poly_init2(b, 0, N); + padic_poly_init2(c, 0, N); + + padic_poly_randtest(a, state, n_randint(state, 100), ctx); + padic_poly_randtest(b, state, n_randint(state, 100), ctx); + + padic_poly_add(c, a, b, ctx); + padic_poly_add(a, a, b, ctx); + + result = (padic_poly_equal(a, c) && padic_poly_is_reduced(a, ctx)); + if (!result) + { + flint_printf("FAIL (alias a, c):\n"); + flint_printf("a = "), padic_poly_print(a, ctx), flint_printf("\n\n"); + flint_printf("b = "), padic_poly_print(b, ctx), flint_printf("\n\n"); + flint_printf("c = "), padic_poly_print(c, ctx), flint_printf("\n\n"); + abort(); + } + + padic_poly_clear(a); + padic_poly_clear(b); + padic_poly_clear(c); + + padic_ctx_clear(ctx); + fmpz_clear(p); + } + + /* Check aliasing of b and c */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_poly_t a, b, c; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_poly_init2(a, 0, N); + padic_poly_init2(b, 0, N); + padic_poly_init2(c, 0, N); + + padic_poly_randtest(a, state, n_randint(state, 100), ctx); + padic_poly_randtest(b, state, n_randint(state, 100), ctx); + + padic_poly_add(c, a, b, ctx); + padic_poly_add(b, a, b, ctx); + + result = (padic_poly_equal(b, c) && padic_poly_is_reduced(b, ctx)); + if (!result) + { + flint_printf("FAIL (alias b, c):\n"); + padic_poly_print(a, ctx), flint_printf("\n\n"); + padic_poly_print(b, ctx), flint_printf("\n\n"); + padic_poly_print(c, ctx), flint_printf("\n\n"); + abort(); + } + + padic_poly_clear(a); + padic_poly_clear(b); + padic_poly_clear(c); + + padic_ctx_clear(ctx); + fmpz_clear(p); + } + + /* Compare with Q */ + for (i = 0; i < 10000; i++) + { + fmpz_t p; + slong N; + padic_ctx_t ctx; + + padic_poly_t a, b, c, d; + fmpq_poly_t x, y, z; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_poly_init2(a, 0, N); + padic_poly_init2(b, 0, N); + padic_poly_init2(c, 0, N); + padic_poly_init2(d, 0, N); + + fmpq_poly_init(x); + fmpq_poly_init(y); + fmpq_poly_init(z); + + padic_poly_randtest(b, state, n_randint(state, 50), ctx); + padic_poly_randtest(c, state, n_randint(state, 50), ctx); + + padic_poly_add(a, b, c, ctx); + + padic_poly_get_fmpq_poly(y, b, ctx); + padic_poly_get_fmpq_poly(z, c, ctx); + + fmpq_poly_add(x, y, z); + padic_poly_set_fmpq_poly(d, x, ctx); + + result = (padic_poly_equal(a, d) && padic_poly_is_reduced(a, ctx)); + if (!result) + { + flint_printf("FAIL (cmp with Q):\n"); + flint_printf("N = %wd, val(b) = %wd, val(c) = %wd\n", N, b->val, c->val); + padic_poly_print(c, ctx), flint_printf("\n\n"); + padic_poly_print(d, ctx), flint_printf("\n\n"); + abort(); + } + + padic_poly_clear(a); + padic_poly_clear(b); + padic_poly_clear(c); + padic_poly_clear(d); + + fmpq_poly_clear(x); + fmpq_poly_clear(y); + fmpq_poly_clear(z); + + padic_ctx_clear(ctx); + fmpz_clear(p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/padic_poly/test/t-compose.c b/external/flint-2.4.3/padic_poly/test/t-compose.c new file mode 100644 index 0000000..07a1d89 --- /dev/null +++ b/external/flint-2.4.3/padic_poly/test/t-compose.c @@ -0,0 +1,138 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "long_extras.h" +#include "ulong_extras.h" +#include "padic_poly.h" + +int +main(void) +{ + int i, result; + + padic_ctx_t ctx; + fmpz_t p; + slong N; + + FLINT_TEST_INIT(state); + + flint_printf("compose... "); + fflush(stdout); + + /* Compare with the computation over QQ */ + for (i = 0; i < 100; i++) + { + padic_poly_t f, g, h, h2; + fmpq_poly_t fQQ, gQQ, hQQ; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_poly_init2(f, 0, N); + padic_poly_init2(g, 0, N); + padic_poly_init2(h, 0, N); + padic_poly_init2(h2, 0, N); + fmpq_poly_init(fQQ); + fmpq_poly_init(gQQ); + fmpq_poly_init(hQQ); + + padic_poly_randtest(f, state, n_randint(state, 40), ctx); + padic_poly_randtest(g, state, n_randint(state, 15), ctx); + + padic_poly_get_fmpq_poly(fQQ, f, ctx); + padic_poly_get_fmpq_poly(gQQ, g, ctx); + + padic_poly_compose(h, f, g, ctx); + fmpq_poly_compose(hQQ, fQQ, gQQ); + + padic_poly_set_fmpq_poly(h2, hQQ, ctx); + + if (padic_poly_val(g) >= 0) + { + result = (padic_poly_equal(h, h2) && padic_poly_is_reduced(h, ctx)); + if (!result) + { + flint_printf("FAIL (cmp with QQ, ord_p(g) >= 0):\n"); + flint_printf("f = "), padic_poly_print(f, ctx), flint_printf("\n\n"); + flint_printf("g = "), padic_poly_print(g, ctx), flint_printf("\n\n"); + flint_printf("h = "), padic_poly_debug(h), flint_printf("\n\n"); + flint_printf("h2 = "), padic_poly_debug(h2), flint_printf("\n\n"); + flint_printf("p = "), fmpz_print(p), flint_printf("\n\n"); + flint_printf("N = %wd\n\n", N); + abort(); + } + } + else + { + slong N2 = N + (f->length - 1) * padic_poly_val(g); + padic_poly_t hX, h2X; + + padic_poly_init2(hX, 0, N2); + padic_poly_init2(h2X, 0, N2); + + padic_poly_set(hX, h, ctx); + padic_poly_set(h2X, h2, ctx); + + result = (padic_poly_equal(hX, h2X) && padic_poly_is_reduced(hX, ctx)); + if (!result) + { + flint_printf("FAIL (cmp with QQ, ord_p(g) < 0):\n"); + flint_printf("f = "), padic_poly_print(f, ctx), flint_printf("\n\n"); + flint_printf("g = "), padic_poly_print(g, ctx), flint_printf("\n\n"); + flint_printf("h = "), padic_poly_print(h, ctx), flint_printf("\n\n"); + flint_printf("h2 = "), padic_poly_print(h2, ctx), flint_printf("\n\n"); + flint_printf("hX = "), padic_poly_print(hX, ctx), flint_printf("\n\n"); + flint_printf("h2X = "), padic_poly_print(h2X, ctx), flint_printf("\n\n"); + flint_printf("p = "), fmpz_print(p), flint_printf("\n\n"); + flint_printf("N = %wd\n\n", N); + flint_printf("N2 = %wd\n\n", N2); + abort(); + } + + padic_poly_clear(hX); + padic_poly_clear(h2X); + } + + padic_poly_clear(f); + padic_poly_clear(g); + padic_poly_clear(h); + padic_poly_clear(h2); + fmpq_poly_clear(fQQ); + fmpq_poly_clear(gQQ); + fmpq_poly_clear(hQQ); + + padic_ctx_clear(ctx); + fmpz_clear(p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/padic_poly/test/t-compose_pow.c b/external/flint-2.4.3/padic_poly/test/t-compose_pow.c new file mode 100644 index 0000000..1c0dc84 --- /dev/null +++ b/external/flint-2.4.3/padic_poly/test/t-compose_pow.c @@ -0,0 +1,140 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "long_extras.h" +#include "ulong_extras.h" +#include "padic_poly.h" + +int +main(void) +{ + int i, result; + + padic_ctx_t ctx; + fmpz_t p; + slong N; + + FLINT_TEST_INIT(state); + + flint_printf("compose_pow... "); + fflush(stdout); + + /* Aliasing */ + for (i = 0; i < 1000; i++) + { + padic_poly_t a, b, c; + slong k; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_poly_init2(a, 0, N); + padic_poly_init2(b, 0, N); + padic_poly_init2(c, 0, N); + + padic_poly_randtest(a, state, n_randint(state, 100), ctx); + padic_poly_set(b, a, ctx); + k = n_randint(state, 20) + 1; + + padic_poly_compose_pow(c, b, k, ctx); + padic_poly_compose_pow(b, b, k, ctx); + + result = (padic_poly_equal(b, c) && padic_poly_is_reduced(b, ctx)); + if (!result) + { + flint_printf("FAIL (aliasing):\n"); + padic_poly_print(a, ctx), flint_printf("\n\n"); + padic_poly_print(b, ctx), flint_printf("\n\n"); + padic_poly_print(c, ctx), flint_printf("\n\n"); + abort(); + } + + padic_poly_clear(a); + padic_poly_clear(b); + padic_poly_clear(c); + + padic_ctx_clear(ctx); + fmpz_clear(p); + } + + /* Compare with usual composition */ + for (i = 0; i < 1000; i++) + { + padic_poly_t f, g, h1, h2; + slong k; + padic_t one; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_poly_init2(f, 0, N); + padic_poly_init2(g, 0, WORD_MAX); /* TODO: Check this is OK */ + padic_poly_init2(h1, 0, N); + padic_poly_init2(h2, 0, N); + + padic_poly_randtest(f, state, n_randint(state, 40), ctx); + k = n_randint(state, 20) + 1; + + padic_poly_compose_pow(h1, f, k, ctx); + + padic_init(one); + padic_one(one); + padic_poly_set_coeff_padic(g, k, one, ctx); + padic_clear(one); + padic_poly_compose(h2, f, g, ctx); + + result = (padic_poly_equal(h1, h2) && padic_poly_is_reduced(h1, ctx)); + if (!result) + { + flint_printf("FAIL (cmp with composition):\n"); + flint_printf("f = "), padic_poly_print(f, ctx), flint_printf("\n\n"); + flint_printf("g = "), padic_poly_print(g, ctx), flint_printf("\n\n"); + flint_printf("h1 = "), padic_poly_print(h1, ctx), flint_printf("\n\n"); + flint_printf("h2 = "), padic_poly_print(h2, ctx), flint_printf("\n\n"); + flint_printf("p = "), fmpz_print(p), flint_printf("\n\n"); + flint_printf("N = %wd\n\n", N); + abort(); + } + + padic_poly_clear(f); + padic_poly_clear(g); + padic_poly_clear(h1); + padic_poly_clear(h2); + + padic_ctx_clear(ctx); + fmpz_clear(p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/padic_poly/test/t-derivative.c b/external/flint-2.4.3/padic_poly/test/t-derivative.c new file mode 100644 index 0000000..0b1c784 --- /dev/null +++ b/external/flint-2.4.3/padic_poly/test/t-derivative.c @@ -0,0 +1,138 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "padic_poly.h" +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + + padic_ctx_t ctx; + fmpz_t p; + slong N; + + FLINT_TEST_INIT(state); + + flint_printf("derivative... "); + fflush(stdout); + + /* Aliasing */ + for (i = 0; i < 10000; i++) + { + padic_poly_t a, b, c; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_poly_init2(a, 0, N); + padic_poly_init2(b, 0, N); + padic_poly_init2(c, 0, N); + + padic_poly_randtest(a, state, n_randint(state, 100), ctx); + padic_poly_set(b, a, ctx); + + padic_poly_derivative(c, b, ctx); + padic_poly_derivative(b, b, ctx); + + result = (padic_poly_equal(b, c) && padic_poly_is_reduced(b, ctx)); + if (!result) + { + flint_printf("FAIL (alias):\n"); + flint_printf("a = "), padic_poly_print(a, ctx), flint_printf("\n\n"); + flint_printf("b = "), padic_poly_print(b, ctx), flint_printf("\n\n"); + flint_printf("c = "), padic_poly_print(c, ctx), flint_printf("\n\n"); + abort(); + } + + padic_poly_clear(a); + padic_poly_clear(b); + padic_poly_clear(c); + + padic_ctx_clear(ctx); + fmpz_clear(p); + } + + /* Compare with derivative over QQ */ + for (i = 0; i < 10000; i++) + { + padic_poly_t a, b, c; + fmpq_poly_t aQQ, bQQ; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_poly_init2(a, 0, N); + padic_poly_init2(b, 0, N); + padic_poly_init2(c, 0, N); + + padic_poly_randtest(a, state, n_randint(state, 100), ctx); + + fmpq_poly_init(aQQ); + fmpq_poly_init(bQQ); + + padic_poly_derivative(b, a, ctx); + + padic_poly_get_fmpq_poly(aQQ, a, ctx); + fmpq_poly_derivative(bQQ, aQQ); + padic_poly_set_fmpq_poly(c, bQQ, ctx); + + result = (padic_poly_equal(b, c) && padic_poly_is_reduced(b, ctx)); + if (!result) + { + flint_printf("FAIL (cmp with QQ):\n"); + flint_printf("a = "), padic_poly_print(a, ctx), flint_printf("\n\n"); + flint_printf("b = "), padic_poly_print(b, ctx), flint_printf("\n\n"); + flint_printf("c = "), padic_poly_print(c, ctx), flint_printf("\n\n"); + flint_printf("aQQ = "), fmpq_poly_print(aQQ), flint_printf("\n\n"); + flint_printf("bQQ = "), fmpq_poly_print(bQQ), flint_printf("\n\n"); + abort(); + } + + padic_poly_clear(a); + padic_poly_clear(b); + padic_poly_clear(c); + fmpq_poly_clear(aQQ); + fmpq_poly_clear(bQQ); + + padic_ctx_clear(ctx); + fmpz_clear(p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/padic_poly/test/t-evaluate_padic.c b/external/flint-2.4.3/padic_poly/test/t-evaluate_padic.c new file mode 100644 index 0000000..7bade7f --- /dev/null +++ b/external/flint-2.4.3/padic_poly/test/t-evaluate_padic.c @@ -0,0 +1,135 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "long_extras.h" +#include "ulong_extras.h" +#include "padic_poly.h" + +int +main(void) +{ + int i, result; + + padic_ctx_t ctx; + fmpz_t p; + slong N; + + FLINT_TEST_INIT(state); + + flint_printf("evaluate_padic... "); + fflush(stdout); + + /* Compare with the computation over QQ */ + for (i = 0; i < 200; i++) + { + padic_poly_t f; + fmpq_poly_t fQQ; + padic_t a, y, z; + fmpq_t aQQ, yQQ; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_poly_init2(f, 0, N); + fmpq_poly_init(fQQ); + padic_init2(a, N); + padic_init2(y, N); + padic_init2(z, N); + fmpq_init(aQQ); + fmpq_init(yQQ); + + padic_poly_randtest(f, state, n_randint(state, 80), ctx); + padic_randtest(a, state, ctx); + + padic_poly_get_fmpq_poly(fQQ, f, ctx); + padic_get_fmpq(aQQ, a, ctx); + + padic_poly_evaluate_padic(y, f, a, ctx); + fmpq_poly_evaluate_fmpq(yQQ, fQQ, aQQ); + + padic_set_fmpq(z, yQQ, ctx); + + if (padic_val(a) >= 0) + { + result = (padic_equal(y, z)); + if (!result) + { + flint_printf("FAIL (cmp with QQ):\n"); + flint_printf("f = "), padic_poly_print(f, ctx), flint_printf("\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n\n"); + flint_printf("y = "), padic_print(y, ctx), flint_printf("\n\n"); + flint_printf("z = "), padic_print(z, ctx), flint_printf("\n\n"); + abort(); + } + } + else + { + slong N2 = N + (f->length - 1) * padic_val(a); + padic_t y2, z2; + + padic_init2(y2, N2); + padic_init2(z2, N2); + + padic_set(y2, y, ctx); + padic_set(z2, z, ctx); + + result = (padic_equal(y2, z2)); + if (!result) + { + flint_printf("FAIL (cmp with QQ):\n"); + flint_printf("f = "), padic_poly_print(f, ctx), flint_printf("\n\n"); + flint_printf("a = "), padic_print(a, ctx), flint_printf("\n\n"); + flint_printf("y = "), padic_print(y, ctx), flint_printf("\n\n"); + flint_printf("z = "), padic_print(z, ctx), flint_printf("\n\n"); + flint_printf("y2 = "), padic_print(y2, ctx), flint_printf("\n\n"); + flint_printf("z2 = "), padic_print(z2, ctx), flint_printf("\n\n"); + abort(); + } + + padic_clear(y2); + padic_clear(z2); + } + + padic_poly_clear(f); + fmpq_poly_clear(fQQ); + padic_clear(a); + padic_clear(y); + padic_clear(z); + fmpq_clear(aQQ); + fmpq_clear(yQQ); + + padic_ctx_clear(ctx); + fmpz_clear(p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/padic_poly/test/t-get_set_fmpq_poly.c b/external/flint-2.4.3/padic_poly/test/t-get_set_fmpq_poly.c new file mode 100644 index 0000000..c78031b --- /dev/null +++ b/external/flint-2.4.3/padic_poly/test/t-get_set_fmpq_poly.c @@ -0,0 +1,90 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include +#include + +#include "flint.h" +#include "long_extras.h" +#include "ulong_extras.h" +#include "padic_poly.h" + +int +main(void) +{ + int i, result; + + padic_ctx_t ctx; + fmpz_t p; + slong N; + + FLINT_TEST_INIT(state); + + flint_printf("get/set_fmpq_poly... "); + fflush(stdout); + + /* Qp -> Q -> Qp */ + for (i = 0; i < 10000; i++) + { + padic_poly_t a, b; + fmpq_poly_t c; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_poly_init2(a, 0, N); + padic_poly_init2(b, 0, N); + fmpq_poly_init(c); + + padic_poly_randtest(a, state, n_randint(state, 10), ctx); + + padic_poly_get_fmpq_poly(c, a, ctx); + padic_poly_set_fmpq_poly(b, c, ctx); + + result = (padic_poly_equal(a, b) && padic_poly_is_reduced(a, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), padic_poly_debug(a), flint_printf("\n\n"); + flint_printf("b = "), padic_poly_debug(b), flint_printf("\n\n"); + flint_printf("c = "), fmpq_poly_print(c), flint_printf("\n\n"); + abort(); + } + + padic_poly_clear(a); + padic_poly_clear(b); + fmpq_poly_clear(c); + + padic_ctx_clear(ctx); + fmpz_clear(p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/padic_poly/test/t-init_realloc_clear.c b/external/flint-2.4.3/padic_poly/test/t-init_realloc_clear.c new file mode 100644 index 0000000..21f5f59 --- /dev/null +++ b/external/flint-2.4.3/padic_poly/test/t-init_realloc_clear.c @@ -0,0 +1,98 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "long_extras.h" +#include "ulong_extras.h" +#include "padic_poly.h" + +int +main(void) +{ + int i; + FLINT_TEST_INIT(state); + + flint_printf("init/init2/realloc/clear... "); + fflush(stdout); + + + + for (i = 0; i < 10000; i++) + { + padic_poly_t a; + + padic_poly_init2(a, n_randint(state, 100), PADIC_DEFAULT_PREC); + padic_poly_clear(a); + } + + for (i = 0; i < 10000; i++) + { + slong N; + fmpz_t p; + padic_poly_t a; + + fmpz_init_set_ui(p, 7); + + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + + padic_poly_init2(a, n_randint(state, 100), N); + padic_poly_realloc(a, n_randint(state, 100), p); + padic_poly_clear(a); + + fmpz_clear(p); + } + + for (i = 0; i < 10000; i++) + { + padic_ctx_t ctx; + fmpz_t p; + slong N; + + padic_poly_t a; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_poly_init2(a, 0, N); + padic_poly_randtest(a, state, n_randint(state, 100), ctx); + padic_poly_clear(a); + + padic_ctx_clear(ctx); + fmpz_clear(p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/padic_poly/test/t-inv_series.c b/external/flint-2.4.3/padic_poly/test/t-inv_series.c new file mode 100644 index 0000000..c8a3a4b --- /dev/null +++ b/external/flint-2.4.3/padic_poly/test/t-inv_series.c @@ -0,0 +1,170 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "long_extras.h" +#include "ulong_extras.h" +#include "padic_poly.h" + +int +main(void) +{ + int i, result; + + padic_ctx_t ctx; + fmpz_t p; + slong N; + + FLINT_TEST_INIT(state); + + flint_printf("inv_series... "); + fflush(stdout); + + /* Check aliasing */ + for (i = 0; i < 1000; i++) + { + padic_poly_t a, b, c; + slong n; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_poly_init2(a, 0, N); + padic_poly_init2(b, 0, N); + padic_poly_init2(c, 0, N); + + padic_poly_randtest(a, state, n_randint(state, 100) + 1, ctx); + if (fmpz_is_zero(a->coeffs)) + { + fmpz_randtest_not_zero(a->coeffs, state, 20); + fmpz_remove(a->coeffs, a->coeffs, p); + padic_poly_reduce(a, ctx); + } else + fmpz_remove(a->coeffs, a->coeffs, p); + + padic_poly_set(b, a, ctx); + n = n_randint(state, 100) + 1; + + padic_poly_inv_series(c, b, n, ctx); + padic_poly_inv_series(b, b, n, ctx); + + result = (padic_poly_equal(b, c) && padic_poly_is_reduced(b, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), padic_poly_print(a, ctx), flint_printf("\n\n"); + flint_printf("b = "), padic_poly_print(b, ctx), flint_printf("\n\n"); + flint_printf("c = "), padic_poly_print(c, ctx), flint_printf("\n\n"); + abort(); + } + + padic_poly_clear(a); + padic_poly_clear(b); + padic_poly_clear(c); + + padic_ctx_clear(ctx); + fmpz_clear(p); + } + + /* + Check correctness: + + If ord_p(a) = v then we can compute b = a^{-1} mod p^N + and we will have a b = 1 mod p^{N-|v|}. Thus, require + that N - |v| > 0. + */ + for (i = 0; i < 1000; i++) + { + padic_poly_t a, b, c; + slong n, N2; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - 1) + 1; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_poly_init2(a, 0, N); + padic_poly_init2(b, 0, N); + + { + slong i, len = n_randint(state, 10) + 1; + int alloc; + fmpz_t pow; + + padic_poly_fit_length(a, len); + _padic_poly_set_length(a, len); + a->val = n_randint(state, N); + if (n_randint(state, 2)) + a->val = - a->val; + + alloc = _padic_ctx_pow_ui(pow, N - a->val, ctx); + + for (i = 0; i < len; i++) + fmpz_randm(a->coeffs + i, state, pow); + while (fmpz_is_zero(a->coeffs)) + fmpz_randm(a->coeffs, state, pow); + fmpz_remove(a->coeffs, a->coeffs, p); + _padic_poly_normalise(a); + + if (alloc) + fmpz_clear(pow); + } + + n = n_randint(state, 100) + 1; + + N2 = N - FLINT_ABS(a->val); + padic_poly_init2(c, 0, N2); + + padic_poly_inv_series(b, a, n, ctx); + padic_poly_mul(c, a, b, ctx); + padic_poly_truncate(c, n, p); + + result = (padic_poly_is_one(c) && padic_poly_is_reduced(b, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), padic_poly_print(a, ctx), flint_printf("\n\n"); + flint_printf("b = "), padic_poly_print(b, ctx), flint_printf("\n\n"); + flint_printf("c = "), padic_poly_print(c, ctx), flint_printf("\n\n"); + flint_printf("N = %wd\n", N); + flint_printf("N2 = %wd\n", N2); + abort(); + } + + padic_poly_clear(a); + padic_poly_clear(b); + padic_poly_clear(c); + + padic_ctx_clear(ctx); + fmpz_clear(p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/padic_poly/test/t-mul.c b/external/flint-2.4.3/padic_poly/test/t-mul.c new file mode 100644 index 0000000..8a6768e --- /dev/null +++ b/external/flint-2.4.3/padic_poly/test/t-mul.c @@ -0,0 +1,247 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "padic_poly.h" +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + + padic_ctx_t ctx; + fmpz_t p; + slong N; + + FLINT_TEST_INIT(state); + + flint_printf("mul... "); + fflush(stdout); + + /* Check aliasing of a and b */ + for (i = 0; i < 1000; i++) + { + padic_poly_t a, b, c; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_poly_init2(a, 0, N); + padic_poly_init2(b, 0, N); + padic_poly_init2(c, 0, N); + + padic_poly_randtest(b, state, n_randint(state, 50), ctx); + padic_poly_randtest(c, state, n_randint(state, 50), ctx); + + padic_poly_mul(a, b, c, ctx); + padic_poly_mul(b, b, c, ctx); + + result = (padic_poly_equal(a, b) && padic_poly_is_reduced(a, ctx)); + if (!result) + { + flint_printf("FAIL (aliasing a and b):\n"); + padic_poly_print(a, ctx), flint_printf("\n\n"); + padic_poly_print(b, ctx), flint_printf("\n\n"); + abort(); + } + + padic_poly_clear(a); + padic_poly_clear(b); + padic_poly_clear(c); + + padic_ctx_clear(ctx); + fmpz_clear(p); + } + + /* Check aliasing of a and c */ + for (i = 0; i < 1000; i++) + { + padic_poly_t a, b, c; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_poly_init2(a, 0, N); + padic_poly_init2(b, 0, N); + padic_poly_init2(c, 0, N); + + padic_poly_randtest(b, state, n_randint(state, 50), ctx); + padic_poly_randtest(c, state, n_randint(state, 50), ctx); + + padic_poly_mul(a, b, c, ctx); + padic_poly_mul(c, b, c, ctx); + + result = (padic_poly_equal(a, c) && padic_poly_is_reduced(a, ctx)); + if (!result) + { + flint_printf("FAIL (aliasing a and c):\n"); + padic_poly_print(a, ctx), flint_printf("\n\n"); + padic_poly_print(c, ctx), flint_printf("\n\n"); + abort(); + } + + padic_poly_clear(a); + padic_poly_clear(b); + padic_poly_clear(c); + + padic_ctx_clear(ctx); + fmpz_clear(p); + } + + /* Check (b * c) + (b * d) = b * (c + d) */ + for (i = 0; i < 1000; i++) + { + padic_poly_t a1, a2, b, c, d, t; + slong v; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_poly_init2(b, 0, N); + padic_poly_init2(c, 0, N); + padic_poly_init2(d, 0, N); + padic_poly_init2(t, 0, N); + + padic_poly_randtest(b, state, n_randint(state, 100), ctx); + padic_poly_randtest(c, state, n_randint(state, 100), ctx); + padic_poly_randtest(d, state, n_randint(state, 100), ctx); + + v = FLINT_MIN(b->val, c->val); + v = FLINT_MIN(v, d->val); + v = FLINT_MIN(v, 0); + + if (v >= 0 || -v < N) /* Otherwise, no precision left */ + { + slong N2 = (v >= 0) ? N : N + v; + + padic_poly_init2(a1, 0, N2); + padic_poly_init2(a2, 0, N2); + + padic_poly_mul(a1, b, c, ctx); + padic_poly_mul(t, b, d, ctx); + padic_poly_add(a1, a1, t, ctx); /* Lower precision */ + + padic_poly_add(t, c, d, ctx); + padic_poly_mul(a2, b, t, ctx); /* Lower precision */ + + result = (padic_poly_equal(a1, a2) && padic_poly_is_reduced(a1, ctx)); + if (!result) + { + flint_printf("FAIL (distributivity):\n"); + flint_printf("p = "), fmpz_print(ctx->p), flint_printf("\n\n"); + flint_printf("N = %wd\n\n", N); + flint_printf("b = "), padic_poly_print(b, ctx), flint_printf("\n\n"); + flint_printf("c = "), padic_poly_print(c, ctx), flint_printf("\n\n"); + flint_printf("d = "), padic_poly_print(d, ctx), flint_printf("\n\n"); + flint_printf("a1 = "), padic_poly_print(a1, ctx), flint_printf("\n\n"); + flint_printf("a2 = "), padic_poly_print(a2, ctx), flint_printf("\n\n"); + abort(); + } + + padic_poly_clear(a1); + padic_poly_clear(a2); + } + + padic_poly_clear(b); + padic_poly_clear(c); + padic_poly_clear(d); + + padic_ctx_clear(ctx); + fmpz_clear(p); + } + + /* Compare with Q */ + for (i = 0; i < 10000; i++) + { + padic_poly_t a, b, c, d; + fmpq_poly_t x, y, z; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_poly_init2(a, 0, N); + padic_poly_init2(b, 0, N); + padic_poly_init2(c, 0, N); + padic_poly_init2(d, 0, N); + + fmpq_poly_init(x); + fmpq_poly_init(y); + fmpq_poly_init(z); + + padic_poly_randtest(b, state, n_randint(state, 50), ctx); + padic_poly_randtest(c, state, n_randint(state, 50), ctx); + + padic_poly_mul(a, b, c, ctx); + + padic_poly_get_fmpq_poly(y, b, ctx); + padic_poly_get_fmpq_poly(z, c, ctx); + + fmpq_poly_mul(x, y, z); + padic_poly_set_fmpq_poly(d, x, ctx); + + result = (padic_poly_equal(a, d) && padic_poly_is_reduced(a, ctx)); + if (!result) + { + flint_printf("FAIL (cmp with Q):\n"); + flint_printf("N = %wd, val(b) = %wd, val(c) = %wd\n", N, b->val, c->val); + padic_poly_print(c, ctx), flint_printf("\n\n"); + padic_poly_print(d, ctx), flint_printf("\n\n"); + abort(); + } + + padic_poly_clear(a); + padic_poly_clear(b); + padic_poly_clear(c); + padic_poly_clear(d); + + fmpq_poly_clear(x); + fmpq_poly_clear(y); + fmpq_poly_clear(z); + + padic_ctx_clear(ctx); + fmpz_clear(p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/padic_poly/test/t-neg.c b/external/flint-2.4.3/padic_poly/test/t-neg.c new file mode 100644 index 0000000..0e9c304 --- /dev/null +++ b/external/flint-2.4.3/padic_poly/test/t-neg.c @@ -0,0 +1,126 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "padic_poly.h" +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + + fmpz_t p; + slong N; + padic_ctx_t ctx; + + FLINT_TEST_INIT(state); + + flint_printf("neg... "); + fflush(stdout); + + /* Aliasing */ + for (i = 0; i < 10000; i++) + { + padic_poly_t a, b, c; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_poly_init2(a, 0, N); + padic_poly_init2(b, 0, N); + padic_poly_init2(c, 0, N); + + padic_poly_randtest(a, state, n_randint(state, 100), ctx); + padic_poly_set(b, a, ctx); + + padic_poly_neg(c, b, ctx); + padic_poly_neg(b, b, ctx); + + result = (padic_poly_equal(b, c) && padic_poly_is_reduced(b, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + padic_poly_print(a, ctx), flint_printf("\n\n"); + padic_poly_print(b, ctx), flint_printf("\n\n"); + padic_poly_print(c, ctx), flint_printf("\n\n"); + abort(); + } + + padic_poly_clear(a); + padic_poly_clear(b); + padic_poly_clear(c); + + padic_ctx_clear(ctx); + fmpz_clear(p); + } + + /* Check that --a = a */ + for (i = 0; i < 10000; i++) + { + padic_poly_t a, b, c; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_poly_init2(a, 0, N); + padic_poly_init2(b, 0, N); + padic_poly_init2(c, 0, N); + + padic_poly_randtest(a, state, n_randint(state, 100), ctx); + + padic_poly_neg(b, a, ctx); + padic_poly_neg(c, b, ctx); + + result = (padic_poly_equal(a, c) && padic_poly_is_reduced(a, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + padic_poly_print(a, ctx), flint_printf("\n\n"); + padic_poly_print(b, ctx), flint_printf("\n\n"); + padic_poly_print(c, ctx), flint_printf("\n\n"); + abort(); + } + + padic_poly_clear(a); + padic_poly_clear(b); + padic_poly_clear(c); + + padic_ctx_clear(ctx); + fmpz_clear(p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/padic_poly/test/t-one.c b/external/flint-2.4.3/padic_poly/test/t-one.c new file mode 100644 index 0000000..639bebd --- /dev/null +++ b/external/flint-2.4.3/padic_poly/test/t-one.c @@ -0,0 +1,83 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "padic_poly.h" +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + + padic_ctx_t ctx; + fmpz_t p; + slong N; + + FLINT_TEST_INIT(state); + + flint_printf("one...."); + fflush(stdout); + + for (i = 0; i < 10000; i++) + { + padic_poly_t a; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_poly_init2(a, 0, N); + padic_poly_randtest(a, state, n_randint(state, 100), ctx); + padic_poly_one(a); + + result = (padic_poly_is_one(a) || N <= 0); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), padic_poly_print(a, ctx), flint_printf("\n\n"); + flint_printf("N = %wd\n\n", N); + abort(); + } + + padic_poly_clear(a); + + padic_ctx_clear(ctx); + fmpz_clear(p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/padic_poly/test/t-pow.c b/external/flint-2.4.3/padic_poly/test/t-pow.c new file mode 100644 index 0000000..cd854c8 --- /dev/null +++ b/external/flint-2.4.3/padic_poly/test/t-pow.c @@ -0,0 +1,172 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "padic_poly.h" +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + + padic_ctx_t ctx; + fmpz_t p; + slong N; + + FLINT_TEST_INIT(state); + + flint_printf("pow... "); + fflush(stdout); + + /* Aliasing */ + for (i = 0; i < 1000; i++) + { + padic_poly_t a, b, c; + slong e; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_poly_init2(a, 0, N); + padic_poly_init2(b, 0, N); + padic_poly_init2(c, 0, N); + + padic_poly_randtest(a, state, n_randint(state, 100), ctx); + padic_poly_set(b, a, ctx); + e = n_randint(state, 10); + + padic_poly_pow(c, b, e, ctx); + padic_poly_pow(b, b, e, ctx); + + result = (padic_poly_equal(b, c) && padic_poly_is_reduced(b, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + padic_poly_print(a, ctx), flint_printf("\n\n"); + padic_poly_print(b, ctx), flint_printf("\n\n"); + padic_poly_print(c, ctx), flint_printf("\n\n"); + flint_printf("e = %wd\n\n", e); + abort(); + } + + padic_poly_clear(a); + padic_poly_clear(b); + padic_poly_clear(c); + + padic_ctx_clear(ctx); + fmpz_clear(p); + } + + /* Compare with the computation over QQ */ + for (i = 0; i < 1000; i++) + { + padic_poly_t a, b, c; + fmpq_poly_t aQQ, bQQ; + slong e; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_poly_init2(a, 0, N); + padic_poly_init2(b, 0, N); + padic_poly_init2(c, 0, N); + fmpq_poly_init(aQQ); + fmpq_poly_init(bQQ); + + padic_poly_randtest(a, state, n_randint(state, 10), ctx); + e = n_randint(state, 10); + + padic_poly_pow(b, a, e, ctx); + + padic_poly_get_fmpq_poly(aQQ, a, ctx); + fmpq_poly_pow(bQQ, aQQ, e); + padic_poly_set_fmpq_poly(c, bQQ, ctx); + + if (e == 0) + { + result = (padic_poly_equal(b, c) && padic_poly_is_reduced(b, ctx)); + if (!result) + { + flint_printf("FAIL (cmp with QQ):\n"); + padic_poly_print(a, ctx), flint_printf("\n\n"); + padic_poly_print(b, ctx), flint_printf("\n\n"); + padic_poly_print(c, ctx), flint_printf("\n\n"); + abort(); + } + } + else + { + padic_poly_t blo, clo; + + slong N2 = N + (e - 1) * a->val; + + padic_poly_init2(blo, 0, N2); + padic_poly_init2(clo, 0, N2); + + padic_poly_set(blo, b, ctx); + padic_poly_set(clo, c, ctx); + + result = (padic_poly_equal(blo, clo) && padic_poly_is_reduced(blo, ctx)); + if (!result) + { + flint_printf("FAIL (cmp with QQ):\n"); + flint_printf("a = "), padic_poly_print(a, ctx), flint_printf("\n\n"); + flint_printf("b = "), padic_poly_print(b, ctx), flint_printf("\n\n"); + flint_printf("c = "), padic_poly_print(c, ctx), flint_printf("\n\n"); + flint_printf("blo = "), padic_poly_print(blo, ctx), flint_printf("\n\n"); + flint_printf("clo = "), padic_poly_print(clo, ctx), flint_printf("\n\n"); + flint_printf("N = %wd\n\n", N); + flint_printf("e = %wd\n\n", e); + flint_printf("N + (e - 1) v = %wd\n\n", N + (e - 1) * a->val); + abort(); + } + + padic_poly_clear(blo); + padic_poly_clear(clo); + } + + padic_poly_clear(a); + padic_poly_clear(b); + padic_poly_clear(c); + fmpq_poly_clear(aQQ); + fmpq_poly_clear(bQQ); + + padic_ctx_clear(ctx); + fmpz_clear(p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/padic_poly/test/t-shift_left_right.c b/external/flint-2.4.3/padic_poly/test/t-shift_left_right.c new file mode 100644 index 0000000..20e0bcf --- /dev/null +++ b/external/flint-2.4.3/padic_poly/test/t-shift_left_right.c @@ -0,0 +1,167 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include "padic_poly.h" +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + + padic_ctx_t ctx; + fmpz_t p; + slong N; + + FLINT_TEST_INIT(state); + + flint_printf("shift_left/right... "); + fflush(stdout); + + /* Aliasing for left shift */ + for (i = 0; i < 10000; i++) + { + padic_poly_t a, b, c; + slong shift = n_randint(state, 100); + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_poly_init2(a, 0, N); + padic_poly_init2(b, 0, N); + padic_poly_init2(c, 0, N); + + padic_poly_randtest(a, state, n_randint(state, 100), ctx); + padic_poly_set(b, a, ctx); + + padic_poly_shift_left(c, b, shift, ctx); + padic_poly_shift_left(b, b, shift, ctx); + + result = (padic_poly_equal(b, c) && padic_poly_is_reduced(b, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + padic_poly_print(a, ctx), flint_printf("\n\n"); + padic_poly_print(b, ctx), flint_printf("\n\n"); + padic_poly_print(c, ctx), flint_printf("\n\n"); + abort(); + } + + padic_poly_clear(a); + padic_poly_clear(b); + padic_poly_clear(c); + + padic_ctx_clear(ctx); + fmpz_clear(p); + } + + /* Aliasing for shift right */ + for (i = 0; i < 10000; i++) + { + padic_poly_t a, b, c; + slong shift = n_randint(state, 100); + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_poly_init2(a, 0, N); + padic_poly_init2(b, 0, N); + padic_poly_init2(c, 0, N); + + padic_poly_randtest(a, state, n_randint(state, 100), ctx); + padic_poly_set(b, a, ctx); + + padic_poly_shift_right(c, b, shift, ctx); + padic_poly_shift_right(b, b, shift, ctx); + + result = (padic_poly_equal(b, c) && padic_poly_is_reduced(b, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + padic_poly_print(a, ctx), flint_printf("\n\n"); + padic_poly_print(b, ctx), flint_printf("\n\n"); + padic_poly_print(c, ctx), flint_printf("\n\n"); + abort(); + } + + padic_poly_clear(a); + padic_poly_clear(b); + padic_poly_clear(c); + + padic_ctx_clear(ctx); + fmpz_clear(p); + } + + /* Check shift left then right does nothing */ + for (i = 0; i < 10000; i++) + { + padic_poly_t a, b, c; + slong shift = n_randint(state, 100); + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_poly_init2(a, 0, N); + padic_poly_init2(b, 0, N); + padic_poly_init2(c, 0, N); + + padic_poly_randtest(a, state, n_randint(state, 100), ctx); + + padic_poly_shift_left(b, a, shift, ctx); + padic_poly_shift_right(c, b, shift, ctx); + + result = (padic_poly_equal(a, c) && padic_poly_is_reduced(a, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + padic_poly_print(a, ctx), flint_printf("\n\n"); + padic_poly_print(b, ctx), flint_printf("\n\n"); + padic_poly_print(c, ctx), flint_printf("\n\n"); + abort(); + } + + padic_poly_clear(a); + padic_poly_clear(b); + padic_poly_clear(c); + + padic_ctx_clear(ctx); + fmpz_clear(p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/padic_poly/test/t-sub.c b/external/flint-2.4.3/padic_poly/test/t-sub.c new file mode 100644 index 0000000..32a2d86 --- /dev/null +++ b/external/flint-2.4.3/padic_poly/test/t-sub.c @@ -0,0 +1,170 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2009 Bill Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "ulong_extras.h" +#include "long_extras.h" +#include "padic_poly.h" + +int +main(void) +{ + int i, result; + + fmpz_t p; + slong N; + padic_ctx_t ctx; + + FLINT_TEST_INIT(state); + + flint_printf("sub... "); + fflush(stdout); + + /* Check a - b = a + neg(b) */ + for (i = 0; i < 10000; i++) + { + padic_poly_t a, b, c, d; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_poly_init2(a, 0, N); + padic_poly_init2(b, 0, N); + padic_poly_init2(c, 0, N); + padic_poly_init2(d, 0, N); + + padic_poly_randtest(a, state, n_randint(state, 100), ctx); + padic_poly_randtest(b, state, n_randint(state, 100), ctx); + + padic_poly_sub(c, a, b, ctx); + padic_poly_neg(b, b, ctx); + padic_poly_add(d, a, b, ctx); + + result = (padic_poly_equal(c, d) && padic_poly_is_reduced(c, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + padic_poly_print(a, ctx), flint_printf("\n\n"); + padic_poly_print(b, ctx), flint_printf("\n\n"); + padic_poly_print(c, ctx), flint_printf("\n\n"); + padic_poly_print(d, ctx), flint_printf("\n\n"); + abort(); + } + + padic_poly_clear(a); + padic_poly_clear(b); + padic_poly_clear(c); + padic_poly_clear(d); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Check aliasing of a and c */ + for (i = 0; i < 10000; i++) + { + padic_poly_t a, b, c; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_poly_init2(a, 0, N); + padic_poly_init2(b, 0, N); + padic_poly_init2(c, 0, N); + padic_poly_randtest(a, state, n_randint(state, 100), ctx); + padic_poly_randtest(b, state, n_randint(state, 100), ctx); + + padic_poly_sub(c, a, b, ctx); + padic_poly_sub(a, a, b, ctx); + + result = (padic_poly_equal(a, c) && padic_poly_is_reduced(a, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + padic_poly_print(a, ctx), flint_printf("\n\n"); + padic_poly_print(b, ctx), flint_printf("\n\n"); + padic_poly_print(c, ctx), flint_printf("\n\n"); + abort(); + } + + padic_poly_clear(a); + padic_poly_clear(b); + padic_poly_clear(c); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + /* Check aliasing of b and c */ + for (i = 0; i < 10000; i++) + { + padic_poly_t a, b, c; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_poly_init2(a, 0, N); + padic_poly_init2(b, 0, N); + padic_poly_init2(c, 0, N); + padic_poly_randtest(a, state, n_randint(state, 100), ctx); + padic_poly_randtest(b, state, n_randint(state, 100), ctx); + + padic_poly_sub(c, a, b, ctx); + padic_poly_sub(b, a, b, ctx); + + result = (padic_poly_equal(b, c) && padic_poly_is_reduced(b, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + padic_poly_print(a, ctx), flint_printf("\n\n"); + padic_poly_print(b, ctx), flint_printf("\n\n"); + padic_poly_print(c, ctx), flint_printf("\n\n"); + abort(); + } + + padic_poly_clear(a); + padic_poly_clear(b); + padic_poly_clear(c); + + fmpz_clear(p); + padic_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/padic_poly/test/t-truncate.c b/external/flint-2.4.3/padic_poly/test/t-truncate.c new file mode 100644 index 0000000..ccf8a66 --- /dev/null +++ b/external/flint-2.4.3/padic_poly/test/t-truncate.c @@ -0,0 +1,142 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "fmpz_poly.h" +#include "long_extras.h" +#include "ulong_extras.h" +#include "padic_poly.h" + +int +main(void) +{ + int i, result; + + padic_ctx_t ctx; + fmpz_t p; + slong N; + + FLINT_TEST_INIT(state); + + flint_printf("truncate... "); + fflush(stdout); + + /* Check repeated truncating */ + for (i = 0; i < 10000; i++) + { + padic_poly_t a, b, c; + slong m, n; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_poly_init2(a, 0, N); + padic_poly_init2(b, 0, N); + padic_poly_init2(c, 0, N); + + padic_poly_randtest(a, state, n_randint(state, 100), ctx); + padic_poly_set(b, a, ctx); + padic_poly_set(c, a, ctx); + + m = n_randint(state, 100); + n = n_randint(state, m + 1); + + padic_poly_truncate(b, m, ctx->p); + padic_poly_truncate(b, n, ctx->p); + padic_poly_truncate(c, n, ctx->p); + + result = (padic_poly_equal(b, c) && padic_poly_is_reduced(b, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + padic_poly_print(a, ctx), flint_printf("\n\n"); + padic_poly_print(b, ctx), flint_printf("\n\n"); + padic_poly_print(c, ctx), flint_printf("\n\n"); + abort(); + } + + padic_poly_clear(a); + padic_poly_clear(b); + padic_poly_clear(c); + + padic_ctx_clear(ctx); + fmpz_clear(p); + } + + /* Compare with Q */ + for (i = 0; i < 10000; i++) + { + padic_poly_t a; + fmpq_poly_t b, c; + slong n; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_poly_init2(a, 0, N); + fmpq_poly_init(b); + fmpq_poly_init(c); + + padic_poly_randtest(a, state, n_randint(state, 100), ctx); + + n = n_randint(state, 100); + + padic_poly_get_fmpq_poly(b, a, ctx); + fmpq_poly_truncate(b, n); + padic_poly_truncate(a, n, ctx->p); + padic_poly_get_fmpq_poly(c, a, ctx); + + result = (fmpq_poly_equal(b, c) && padic_poly_is_reduced(a, ctx)); + if (!result) + { + flint_printf("FAIL:\n"); + padic_poly_print(a, ctx), flint_printf("\n\n"); + fmpq_poly_print(b), flint_printf("\n\n"); + fmpq_poly_print(c), flint_printf("\n\n"); + abort(); + } + + padic_poly_clear(a); + fmpq_poly_clear(b); + fmpq_poly_clear(c); + + padic_ctx_clear(ctx); + fmpz_clear(p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/padic_poly/test/t-zero.c b/external/flint-2.4.3/padic_poly/test/t-zero.c new file mode 100644 index 0000000..ad90347 --- /dev/null +++ b/external/flint-2.4.3/padic_poly/test/t-zero.c @@ -0,0 +1,82 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010, 2011 Sebastian Pancratz + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "fmpz.h" +#include "padic_poly.h" +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + + padic_ctx_t ctx; + fmpz_t p; + slong N; + + FLINT_TEST_INIT(state); + + flint_printf("zero...."); + fflush(stdout); + + for (i = 0; i < 10000; i++) + { + padic_poly_t a; + + fmpz_init_set_ui(p, n_randtest_prime(state, 0)); + N = n_randint(state, PADIC_TEST_PREC_MAX - PADIC_TEST_PREC_MIN) + + PADIC_TEST_PREC_MIN; + padic_ctx_init(ctx, p, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), PADIC_SERIES); + + padic_poly_init2(a, 0, N); + padic_poly_randtest(a, state, n_randint(state, 100), ctx); + padic_poly_zero(a); + + result = (padic_poly_is_zero(a)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = "), padic_poly_print(a, ctx), flint_printf("\n\n"); + abort(); + } + + padic_poly_clear(a); + + padic_ctx_clear(ctx); + fmpz_clear(p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/padic_polyxx.h b/external/flint-2.4.3/padic_polyxx.h new file mode 100644 index 0000000..4e6fd69 --- /dev/null +++ b/external/flint-2.4.3/padic_polyxx.h @@ -0,0 +1,398 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#ifndef PADIC_POLYXX_H +#define PADIC_POLYXX_H + +#include "padic_poly.h" + +#include "padicxx.h" +#include "fmpz_polyxx.h" +#include "fmpq_polyxx.h" + +#include "flintxx/stdmath.h" + +// TODO input and output + +namespace flint { +FLINT_DEFINE_BINOP(padic_polyxx_get_coeff) +FLINT_DEFINE_BINOP(compose_pow) + +namespace detail { +template +struct padic_poly_traits +{ + typedef slong prec_ref_t; + typedef slong prec_srcref_t; + + typedef slong val_ref_t; + typedef slong val_srcref_t; + + static slong prec(const Padic& p) {return tools::padic_output_prec(p);} + static slong val(const Padic& p) {return padic_poly_val(p.evaluate()._poly());} +}; +} //detail + +template +class padic_polyxx_expression + : public expression, Operation, Data> +{ +public: + typedef expression, + Operation, Data> base_t; + + FLINTXX_DEFINE_BASICS(padic_polyxx_expression) + FLINTXX_DEFINE_CTORS(padic_polyxx_expression) + FLINTXX_DEFINE_C_REF(padic_polyxx_expression, padic_poly_struct, _poly) + +public: + typedef detail::padic_poly_traits traits_t; + + PADICXX_DEFINE_STD + + static padic_polyxx_expression zero(padicxx_ctx_srcref ctx) + {return padic_polyxx_expression(ctx);} + static padic_polyxx_expression zero(padicxx_ctx_srcref ctx, slong N) + {return padic_polyxx_expression(ctx, N);} + static padic_polyxx_expression one(padicxx_ctx_srcref ctx) + { + padic_polyxx_expression res(ctx); + res.set_one(); + return res; + } + static padic_polyxx_expression one(padicxx_ctx_srcref ctx, slong N) + { + padic_polyxx_expression res(ctx, N); + res.set_one(); + return res; + } + + template + static padic_polyxx_expression from_QQ(const T& q, padicxx_ctx_srcref ctx, + typename mp::enable_if, + traits::is_fmpzxx, traits::is_integer > >::type* = 0) + { + padic_polyxx_expression res(ctx); + res = q; + return res; + } + template + static padic_polyxx_expression from_QQ(const T& q, padicxx_ctx_srcref ctx, + slong N, + typename mp::enable_if, + traits::is_fmpzxx, traits::is_integer > >::type* = 0) + { + padic_polyxx_expression res(ctx, N); + res = q; + return res; + } + template + static padic_polyxx_expression from_QQX(const T& q, padicxx_ctx_srcref ctx, + typename mp::enable_if, + traits::is_fmpz_polyxx > >::type* = 0) + { + padic_polyxx_expression res(ctx); + res = q; + return res; + } + template + static padic_polyxx_expression from_QQX(const T& q, padicxx_ctx_srcref ctx, + slong N, + typename mp::enable_if, + traits::is_fmpz_polyxx > >::type* = 0) + { + padic_polyxx_expression res(ctx, N); + res = q; + return res; + } + template + static padic_polyxx_expression _from_ground(const T& q) + { + padic_polyxx_expression res(q.get_ctx(), q.prec()); + res = q; + return res; + } + template + static padic_polyxx_expression from_ground(const T& q, + typename mp::enable_if >::type* = 0) + { + return _from_ground(q.evaluate()); + } + + // Create a temporary. The context will be estimated, and the precision + // will be the maximum of all subexpressions. + evaluated_t create_temporary() const + { + return evaluated_t(estimate_ctx(), prec()); + } + + // static methods which only make sense with padicxx + static padic_polyxx_expression randtest(frandxx& state, + slong len, + padicxx_ctx_srcref ctx, slong prec = PADIC_DEFAULT_PREC) + { + padic_polyxx_expression res(ctx, prec); + padic_poly_randtest(res._poly(), state._data(), len, ctx._ctx()); + return res; + } + static padic_polyxx_expression randtest_not_zero(frandxx& state, + slong len, + padicxx_ctx_srcref ctx, slong prec = PADIC_DEFAULT_PREC) + { + padic_polyxx_expression res(ctx, prec); + padic_poly_randtest_not_zero(res._poly(), state._data(), len, ctx._ctx()); + return res; + } + static padic_polyxx_expression randtest_val(frandxx& state, + slong val, slong len, + padicxx_ctx_srcref ctx, slong prec = PADIC_DEFAULT_PREC) + { + padic_polyxx_expression res(ctx, prec); + padic_poly_randtest_val(res._poly(), state._data(), val, len, ctx._ctx()); + return res; + } + + // These only make sense with immediates + void reduce() {padic_poly_reduce(_poly(), _ctx());} + void realloc(slong alloc) {padic_poly_realloc(_poly(), alloc);} + void fit_length(slong len) {padic_poly_fit_length(_poly(), len);} + void _normalise() {_padic_poly_normalise(_poly());} + void _set_length(slong len) {_padic_poly_set_length(_poly(), len);} + void set_zero() {padic_poly_zero(_poly());} + void set_one() {padic_poly_one(_poly());} + void truncate(slong n) {fmpz_poly_truncate(_poly(), n);} + void canonicalise() {padic_poly_canonicalise(_poly());} + bool is_canonical() const {return padic_poly_is_canonical(_poly());} + bool is_reduced() const {return padic_poly_is_reduced(_poly());} + + template + void set_coeff(slong n, const Padic& p, + typename mp::enable_if >::type* = 0) + {padic_poly_set_coeff_padic(_poly(), n, p._padic(), _ctx());} + + // these cause evaluation + bool is_zero() const {return padic_poly_is_zero(this->evaluate()._poly());} + bool is_one() const {return padic_poly_is_one(this->evaluate()._poly());} + slong length() const {return padic_poly_length(this->evaluate()._poly());} + slong degree() const {return padic_poly_degree(this->evaluate()._poly());} + + // forwarding of lazy functions + FLINTXX_DEFINE_MEMBER_BINOP_(get_coeff, padic_polyxx_get_coeff) + FLINTXX_DEFINE_MEMBER_BINOP_(operator(), compeval) + FLINTXX_DEFINE_MEMBER_BINOP(pow) + FLINTXX_DEFINE_MEMBER_BINOP(compose_pow) + FLINTXX_DEFINE_MEMBER_BINOP(inv_series) + FLINTXX_DEFINE_MEMBER_BINOP(shift_left) + FLINTXX_DEFINE_MEMBER_BINOP(shift_right) + FLINTXX_DEFINE_MEMBER_UNOP(derivative) +}; + +namespace detail { +struct padic_poly_data; +} + +typedef padic_polyxx_expression padic_polyxx; +typedef padic_polyxx_expression > + padic_polyxx_ref; +typedef padic_polyxx_expression > padic_polyxx_srcref; + +namespace traits { +template<> struct has_padicxx_ctx : mp::true_ { }; +template<> struct has_padicxx_ctx : mp::true_ { }; +template<> struct has_padicxx_ctx : mp::true_ { }; +} // traits + +namespace detail { +template<> +struct padic_poly_traits +{ + typedef slong prec_ref_t; + typedef slong prec_srcref_t; + + typedef slong val_ref_t; + typedef slong val_srcref_t; + + template + static slong prec(P p) {return p._data().N;} + template + static slong val(P p) {return padic_poly_val(p._poly());} +}; + +template<> +struct padic_poly_traits + : padic_poly_traits +{ + typedef slong& prec_ref_t; + typedef slong& val_ref_t; + + template + static slong& prec(P& p) {return padic_poly_prec(p._poly());} + template + static slong prec(const P& p) {return padic_poly_prec(p._poly());} + + template + static slong& val(P& p) {return padic_poly_val(p._poly());} + template + static slong val(const P& p) {return padic_poly_val(p._poly());} +}; +template<> +struct padic_poly_traits + : padic_poly_traits { }; +} // detail + +PADICXX_DEFINE_REF_STRUCTS(padic_polyxx, padic_poly_struct, padic_poly_prec) + +namespace detail { +struct padic_poly_data +{ + typedef padic_poly_t& data_ref_t; + typedef const padic_poly_t& data_srcref_t; + + padicxx_ctx_srcref ctx; + padic_poly_t inner; + + padic_poly_data(padicxx_ctx_srcref c) + : ctx(c) + { + padic_poly_init(inner); + } + + padic_poly_data(padicxx_ctx_srcref c, slong N, slong alloc = 0) + : ctx(c) + { + padic_poly_init2(inner, alloc, N); + } + + padic_poly_data(const padic_poly_data& o) + : ctx(o.ctx) + { + padic_poly_init2(inner, padic_poly_length(o.inner), + padic_poly_prec(o.inner)); + padic_poly_set(inner, o.inner, ctx._ctx()); + } + + ~padic_poly_data() {padic_poly_clear(inner);} + + padic_poly_data(padic_polyxx_srcref c) + : ctx(c.get_ctx()) + { + padic_poly_init2(inner, c.length(), c.prec()); + padic_poly_set(inner, c._poly(), ctx._ctx()); + } +}; +} // detail + +#define PADIC_POLYXX_COND_S FLINTXX_COND_S(padic_polyxx) +#define PADIC_POLYXX_COND_T FLINTXX_COND_T(padic_polyxx) + +namespace rules { +FLINT_DEFINE_DOIT_COND2(assignment, PADIC_POLYXX_COND_T, PADIC_POLYXX_COND_S, + padic_poly_set(to._poly(), from._poly(), to._ctx())) +FLINT_DEFINE_DOIT_COND2(assignment, PADIC_POLYXX_COND_T, PADICXX_COND_S, + padic_poly_set_padic(to._poly(), from._padic(), to._ctx())) +FLINT_DEFINE_DOIT_COND2(assignment, PADIC_POLYXX_COND_T, traits::is_signed_integer, + padic_poly_set_si(to._poly(), from, to._ctx())) +FLINT_DEFINE_DOIT_COND2(assignment, PADIC_POLYXX_COND_T, traits::is_unsigned_integer, + padic_poly_set_ui(to._poly(), from, to._ctx())) +FLINT_DEFINE_DOIT_COND2(assignment, PADIC_POLYXX_COND_T, FMPZXX_COND_S, + padic_poly_set_fmpz(to._poly(), from._fmpz(), to._ctx())) +FLINT_DEFINE_DOIT_COND2(assignment, PADIC_POLYXX_COND_T, FMPQXX_COND_S, + padic_poly_set_fmpq(to._poly(), from._fmpq(), to._ctx())) +FLINT_DEFINE_DOIT_COND2(assignment, PADIC_POLYXX_COND_T, FMPZ_POLYXX_COND_S, + padic_poly_set_fmpz_poly(to._poly(), from._poly(), to._ctx())) +FLINT_DEFINE_DOIT_COND2(assignment, PADIC_POLYXX_COND_T, FMPQ_POLYXX_COND_S, + padic_poly_set_fmpq_poly(to._poly(), from._poly(), to._ctx())) + +FLINTXX_DEFINE_SWAP(padic_polyxx, padic_poly_swap(e1._poly(), e2._poly())) + +FLINTXX_DEFINE_EQUALS(padic_polyxx, padic_poly_equal(e1._poly(), e2._poly())) + +FLINT_DEFINE_PRINT_COND(PADIC_POLYXX_COND_S, + padic_poly_fprint(to, from._poly(), from._ctx())) +FLINT_DEFINE_PRINT_PRETTY_COND_2(PADIC_POLYXX_COND_S, const char*, + padic_poly_fprint_pretty(to, from._poly(), extra, from._ctx())) + +FLINTXX_DEFINE_CONVERSION_TMP(fmpz_polyxx, padic_polyxx, + execution_check(padic_poly_get_fmpz_poly( + to._poly(), from._poly(), from._ctx()), + "to", "padic_polyxx")) +FLINTXX_DEFINE_CONVERSION_TMP(fmpq_polyxx, padic_polyxx, + padic_poly_get_fmpq_poly(to._poly(), from._poly(), from._ctx())) + +FLINT_DEFINE_BINARY_EXPR_COND2(padic_polyxx_get_coeff_op, padicxx, + PADIC_POLYXX_COND_S, traits::fits_into_slong, + padic_poly_get_coeff_padic(to._padic(), e1._poly(), e2, to._ctx())) + +FLINT_DEFINE_CBINARY_EXPR_COND2(plus, padic_polyxx, + PADIC_POLYXX_COND_S, PADIC_POLYXX_COND_S, + padic_poly_add(to._poly(), e1._poly(), e2._poly(), to._ctx())) +FLINT_DEFINE_BINARY_EXPR_COND2(minus, padic_polyxx, + PADIC_POLYXX_COND_S, PADIC_POLYXX_COND_S, + padic_poly_sub(to._poly(), e1._poly(), e2._poly(), to._ctx())) +FLINT_DEFINE_UNARY_EXPR_COND(negate, padic_polyxx, PADIC_POLYXX_COND_S, + padic_poly_neg(to._poly(), from._poly(), to._ctx())) + +FLINT_DEFINE_CBINARY_EXPR_COND2(times, padic_polyxx, + PADIC_POLYXX_COND_S, PADICXX_COND_S, + padic_poly_scalar_mul_padic(to._poly(), e1._poly(), e2._padic(), to._ctx())) +FLINT_DEFINE_CBINARY_EXPR_COND2(times, padic_polyxx, + PADIC_POLYXX_COND_S, PADIC_POLYXX_COND_S, + padic_poly_mul(to._poly(), e1._poly(), e2._poly(), to._ctx())) + +FLINT_DEFINE_BINARY_EXPR_COND2(pow_op, padic_polyxx, PADIC_POLYXX_COND_S, + traits::is_unsigned_integer, + padic_poly_pow(to._poly(), e1._poly(), e2, to._ctx())) + +FLINT_DEFINE_BINARY_EXPR_COND2(inv_series_op, padic_polyxx, + PADIC_POLYXX_COND_S, traits::fits_into_slong, + padic_poly_inv_series(to._poly(), e1._poly(), e2, to._ctx())) + +FLINT_DEFINE_UNARY_EXPR_COND(derivative_op, padic_polyxx, PADIC_POLYXX_COND_S, + padic_poly_derivative(to._poly(), from._poly(), to._ctx())) + +FLINT_DEFINE_BINARY_EXPR_COND2(shift_left_op, padic_polyxx, + PADIC_POLYXX_COND_S, traits::fits_into_slong, + padic_poly_shift_left(to._poly(), e1._poly(), e2, to._ctx())) +FLINT_DEFINE_BINARY_EXPR_COND2(shift_right_op, padic_polyxx, + PADIC_POLYXX_COND_S, traits::fits_into_slong, + padic_poly_shift_right(to._poly(), e1._poly(), e2, to._ctx())) + +FLINT_DEFINE_BINARY_EXPR_COND2(evaluate_op, padicxx, + PADIC_POLYXX_COND_S, PADICXX_COND_S, + padic_poly_evaluate_padic(to._padic(), e1._poly(), e2._padic(), to._ctx())) + +FLINT_DEFINE_BINARY_EXPR_COND2(compose_op, padic_polyxx, + PADIC_POLYXX_COND_S, PADIC_POLYXX_COND_S, + padic_poly_compose(to._poly(), e1._poly(), e2._poly(), to._ctx())) +FLINT_DEFINE_BINARY_EXPR_COND2(compose_pow_op, padic_polyxx, + PADIC_POLYXX_COND_S, traits::fits_into_slong, + padic_poly_compose_pow(to._poly(), e1._poly(), e2, to._ctx())) +} // rules +} // flint + +#endif diff --git a/external/flint-2.4.3/padicxx.h b/external/flint-2.4.3/padicxx.h new file mode 100644 index 0000000..3128ae2 --- /dev/null +++ b/external/flint-2.4.3/padicxx.h @@ -0,0 +1,634 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#ifndef CXX_PADICXX_H +#define CXX_PADICXX_H CXX_PADICXX_H + +#include // std::max +#include + +#include "padic.h" + +#include "flintxx/expression.h" +#include "flintxx/flint_classes.h" +#include "flintxx/flint_exception.h" +#include "flintxx/frandxx.h" +#include "flintxx/stdmath.h" +#include "flintxx/traits.h" +#include "flintxx/tuple.h" + +#include "fmpzxx.h" +#include "fmpqxx.h" + +// TODO check codegen ... +// TODO padic_output_prec does not work on non-padic expressions, +// is that a problem? + +namespace flint { +// function "declarations" +FLINT_DEFINE_UNOP(exp_rectangular) +FLINT_DEFINE_UNOP(exp_balanced) +FLINT_DEFINE_UNOP(log_rectangular) +FLINT_DEFINE_UNOP(log_balanced) +FLINT_DEFINE_UNOP(log_satoh) +FLINT_DEFINE_UNOP(teichmuller) +FLINT_DEFINE_BINOP(padic_val_fac) + +class padicxx_ctx +{ +private: + mutable padic_ctx_t ctx; + +public: + // NB: you must not modify user-visible state of ctx through a constant + // instance of padicxx_ctx + padic_ctx_t& _ctx() const {return ctx;} + + // XXX these two are not actually exposed in the C api ... + fmpzxx_ref get_p() {return fmpzxx_ref::make(ctx[0].p);} + fmpzxx_srcref get_p() const {return fmpzxx_srcref::make(ctx[0].p);} + + padic_print_mode mode() const {return _ctx()->mode;} + padic_print_mode& mode() {return _ctx()->mode;} + + // TODO more constructors? Should we wrap padic_print_mode? + padicxx_ctx(fmpzxx_srcref p, slong min, slong max, padic_print_mode mode) + { + padic_ctx_init(ctx, p._fmpz(), min, max, mode); + } + + ~padicxx_ctx() {padic_ctx_clear(ctx);} +}; + +class padicxx_ctx_srcref +{ +private: + mutable padic_ctx_struct* ctx; + + padicxx_ctx_srcref(padic_ctx_struct* c) : ctx(c) {} + +public: + // NB: you must not modify user-visible state of ctx through a constant + // instance of padicxx_ctx + padic_ctx_struct* _ctx() const {return ctx;} + + // XXX these two are not actually exposed in the C api ... + fmpzxx_ref get_p() {return fmpzxx_ref::make(ctx[0].p);} + fmpzxx_srcref get_p() const {return fmpzxx_srcref::make(ctx[0].p);} + + padic_print_mode mode() const {return _ctx()->mode;} + + padicxx_ctx_srcref(padicxx_ctx& c) + : ctx(c._ctx()) {} + + static padicxx_ctx_srcref make(padic_ctx_struct* c) + {return padicxx_ctx_srcref(c);} +}; + +namespace traits { +template struct has_padicxx_ctx : mp::false_ { }; + +template struct is_padic_expr + : has_padicxx_ctx::type> { }; +} // traits +namespace detail { +struct has_padicxx_ctx_predicate +{ + template struct type : traits::has_padicxx_ctx { }; +}; + +template +struct padicxx_max_prec; + +template +struct padicxx_max_prec >::type> +{ + static slong get(const T& p) {return p.prec();} +}; + +template +struct padicxx_max_prec >::type> +{ + static slong get(const T&) {return 0;} +}; + +template +struct padicxx_max_prec_h; +template +struct padicxx_max_prec_h > +{ + static slong get(const tuple& t) + { + slong p1 = padicxx_max_prec_h::get(t.tail); + slong p2 = + padicxx_max_prec::type>::get(t.head); + return std::max(p1, p2); + } +}; +template<> +struct padicxx_max_prec_h +{ + static slong get(empty_tuple) {return 0;} +}; + +template +struct padicxx_max_prec, + mp::not_ > > >::type> +{ + static slong get(const T& e) + {return padicxx_max_prec_h::get(e._data());} +}; +} // detail +namespace tools { +template +padicxx_ctx_srcref find_padicxx_ctx(const Expr& e) +{ + return tools::find_subexpr(e).get_ctx(); +} + +template +slong padic_output_prec(const Expr& e) +{ + return detail::padicxx_max_prec::get(e); +} +} // tools + +FLINT_DEFINE_UNOP(padicxx_unit) + +namespace detail { +template +struct padic_traits +{ + typedef FLINT_UNOP_BUILD_RETTYPE(padicxx_unit, fmpzxx, Padic) + unit_srcref_t; + + typedef slong prec_ref_t; + typedef slong prec_srcref_t; + + typedef slong val_ref_t; + typedef slong val_srcref_t; + + static slong prec(const Padic& p) {return tools::padic_output_prec(p);} + static slong val(const Padic& p) {return padic_val(p.evaluate()._padic());} + + static unit_srcref_t unit(const Padic& p) {return padicxx_unit(p);} +}; +} //detail + +template +class padicxx_expression + : public expression, Operation, Data> +{ +public: + typedef expression, + Operation, Data> base_t; + + FLINTXX_DEFINE_BASICS(padicxx_expression) + FLINTXX_DEFINE_CTORS(padicxx_expression) + FLINTXX_DEFINE_C_REF(padicxx_expression, padic_struct, _padic) + +public: + typedef detail::padic_traits traits_t; + + // These only make sense with immediates + void reduce() {padic_reduce(_padic(), _ctx());} + void set_zero() {padic_zero(_padic());} + void set_one() {padic_one(_padic());} + +#define PADICXX_DEFINE_CTX \ + padicxx_ctx_srcref get_ctx() const {return this->_data().ctx;} \ + padic_ctx_struct* _ctx() const {return get_ctx()._ctx();} + PADICXX_DEFINE_CTX + + static padicxx_expression zero(padicxx_ctx_srcref ctx) + {return padicxx_expression(ctx);} + static padicxx_expression zero(padicxx_ctx_srcref ctx, slong N) + {return padicxx_expression(ctx, N);} + static padicxx_expression one(padicxx_ctx_srcref ctx) + { + padicxx_expression res(ctx); + res.set_one(); + return res; + } + static padicxx_expression one(padicxx_ctx_srcref ctx, slong N) + { + padicxx_expression res(ctx, N); + res.set_one(); + return res; + } + + template + static padicxx_expression from_QQ(const T& q, padicxx_ctx_srcref ctx, + typename mp::enable_if, + traits::is_fmpzxx, traits::is_integer > >::type* = 0) + { + padicxx_expression res(ctx); + res = q; + return res; + } + template + static padicxx_expression from_QQ(const T& q, padicxx_ctx_srcref ctx, + slong N, + typename mp::enable_if, + traits::is_fmpzxx, traits::is_integer > >::type* = 0) + { + padicxx_expression res(ctx, N); + res = q; + return res; + } + // TODO more? + + // The above method get_ctx() only works on immediates, i.e. instances of + // padicxx. This next one here works on any composite expression which + // contains at least one instance of padicxx. Returns the context of one of + // those immediate subexpressions. +#define PADICXX_DEFINE_ESTIMATE_CTX \ + padicxx_ctx_srcref estimate_ctx() const \ + { \ + return tools::find_padicxx_ctx(*this); \ + } + PADICXX_DEFINE_ESTIMATE_CTX + + // Create a temporary. The context will be estimated, and the precision + // will be the maximum of all subexpressions. + evaluated_t create_temporary() const + { + return evaluated_t(estimate_ctx(), prec()); + } + + // static methods which only make sense with padicxx + static padicxx_expression randtest(frandxx& state, + padicxx_ctx_srcref ctx, slong prec = PADIC_DEFAULT_PREC) + { + padicxx_expression res(ctx, prec); + padic_randtest(res._padic(), state._data(), ctx._ctx()); + return res; + } + static padicxx_expression randtest_not_zero(frandxx& state, + padicxx_ctx_srcref ctx, slong prec = PADIC_DEFAULT_PREC) + { + padicxx_expression res(ctx, prec); + padic_randtest_not_zero(res._padic(), state._data(), ctx._ctx()); + return res; + } + static padicxx_expression randtest_int(frandxx& state, + padicxx_ctx_srcref ctx, slong prec = PADIC_DEFAULT_PREC) + { + padicxx_expression res(ctx, prec); + padic_randtest_int(res._padic(), state._data(), ctx._ctx()); + return res; + } + +#define PADICXX_DEFINE_TON \ + typename flint_classes::to_srcref::type \ + toN(slong N) const \ + { \ + return flint_classes::to_srcref::type::make( \ + this->_data().inner, get_ctx(), N); \ + } + PADICXX_DEFINE_TON + + typename traits_t::unit_srcref_t unit() const + {return traits_t::unit(*this);} + + // Compute the maximal precision of all subexpressions +#define PADICXX_DEFINE_PREC \ + typename traits_t::prec_ref_t prec() {return traits_t::prec(*this);} \ + typename traits_t::prec_srcref_t prec() const \ + {return traits_t::prec(*this);} + PADICXX_DEFINE_PREC + +#define PADICXX_DEFINE_VAL \ + typename traits_t::val_ref_t val() {return traits_t::val(*this);} \ + typename traits_t::val_srcref_t val() const \ + {return traits_t::val(*this);} + PADICXX_DEFINE_VAL + + // these cause evaluation + bool is_zero() const {return padic_is_zero(this->evaluate()._padic());} + bool is_one() const {return padic_is_one(this->evaluate()._padic());} + + // forwarding of lazy functions + FLINTXX_DEFINE_MEMBER_UNOP(exp) + FLINTXX_DEFINE_MEMBER_UNOP(exp_balanced) + FLINTXX_DEFINE_MEMBER_UNOP(exp_rectangular) + FLINTXX_DEFINE_MEMBER_UNOP(inv) + FLINTXX_DEFINE_MEMBER_UNOP(log) + FLINTXX_DEFINE_MEMBER_UNOP(log_balanced) + FLINTXX_DEFINE_MEMBER_UNOP(log_satoh) + FLINTXX_DEFINE_MEMBER_UNOP(sqrt) + FLINTXX_DEFINE_MEMBER_UNOP(teichmuller) + FLINTXX_DEFINE_MEMBER_BINOP(pow) +}; + +#define PADICXX_DEFINE_STD \ + PADICXX_DEFINE_CTX \ + PADICXX_DEFINE_ESTIMATE_CTX \ + PADICXX_DEFINE_TON \ + PADICXX_DEFINE_PREC \ + PADICXX_DEFINE_VAL + +namespace detail { +struct padic_data; +} + +typedef padicxx_expression padicxx; +typedef padicxx_expression > padicxx_ref; +typedef padicxx_expression > padicxx_srcref; + +namespace traits { +template<> struct has_padicxx_ctx : mp::true_ { }; +template<> struct has_padicxx_ctx : mp::true_ { }; +template<> struct has_padicxx_ctx : mp::true_ { }; + +template struct is_padicxx : flint_classes::is_Base { }; +} // traits + +namespace detail { +template<> +struct padic_traits +{ + typedef fmpzxx_srcref unit_srcref_t; + template + static fmpzxx_srcref unit(const Poly& p) + {return fmpzxx_srcref::make(padic_unit(p._padic()));} + + typedef slong prec_ref_t; + typedef slong prec_srcref_t; + + typedef slong val_ref_t; + typedef slong val_srcref_t; + + template + static slong prec(P p) {return p._data().N;} + template + static slong val(P p) {return padic_val(p._padic());} +}; + +template<> +struct padic_traits + : padic_traits +{ + typedef slong& prec_ref_t; + typedef slong& val_ref_t; + + template + static slong& prec(P& p) {return padic_prec(p._padic());} + template + static slong prec(const P& p) {return padic_prec(p._padic());} + + template + static slong& val(P& p) {return padic_val(p._padic());} + template + static slong val(const P& p) {return padic_val(p._padic());} +}; +template<> +struct padic_traits + : padic_traits { }; + +template +struct faketemplate : mp::enable_if > { }; +} // detail + +// NB: usually, the "padicname" parameter would not be necessary. We would +// leave that as a template, identifying the type by structname alone, and +// conveniently delay all instantiations. Unfortunately qadic and padic_poly +// have the same structname, so we cannot do this. +// Instead we pass in the class name explicitly, and delay relevant functions +// by hand... +#define PADICXX_DEFINE_REF_STRUCTS_(padicname, structname, precname, ctxtype) \ +namespace flint_classes { \ +template<> \ +struct ref_data \ +{ \ + typedef void IS_REF_OR_CREF; \ + typedef padicname wrapped_t; \ + \ + typedef structname* data_ref_t; \ + typedef const structname* data_srcref_t; \ + \ + structname* inner; \ + ctxtype ctx; \ + \ + template \ + ref_data(T& o, typename detail::faketemplate::type* = 0) \ + : inner(o._data().inner), ctx(o._data().ctx) {} \ + \ + static ref_data make(structname* f, ctxtype ctx) \ + { \ + return ref_data(f, ctx); \ + } \ + \ +private: \ + ref_data(structname* fp, ctxtype c) : inner(fp), ctx(c) {} \ +}; \ + \ +template \ +struct srcref_data \ +{ \ + typedef void IS_REF_OR_CREF; \ + typedef padicname wrapped_t; \ + \ + typedef const structname* data_ref_t; \ + typedef const structname* data_srcref_t; \ + \ + const structname* inner; \ + ctxtype ctx; \ + slong N; \ + \ + template \ + srcref_data(const T& o, \ + typename detail::faketemplate::type* = 0) \ + : inner(o._data().inner), ctx(o._data().ctx), N(o.prec()) {} \ + template \ + srcref_data(T o, typename detail::faketemplate::type* = 0) \ + : inner(o._data().inner), ctx(o._data().ctx), N(o.prec()) {} \ + \ + static srcref_data make(const structname* f, ctxtype ctx) \ + { \ + return srcref_data(f, ctx); \ + } \ + static srcref_data make(const structname* f, ctxtype ctx, \ + slong N) \ + { \ + return srcref_data(f, ctx, N); \ + } \ + \ +private: \ + srcref_data(const structname* fp, ctxtype c) \ + : inner(fp), ctx(c), N(precname(fp)) {} \ + srcref_data(const structname* fp, ctxtype c, slong n) \ + : inner(fp), ctx(c), N(n) {} \ +}; \ +} /* flint_classes */ +#define PADICXX_DEFINE_REF_STRUCTS(padicname, structname, precname) \ + PADICXX_DEFINE_REF_STRUCTS_(padicname, structname, precname, padicxx_ctx_srcref) +PADICXX_DEFINE_REF_STRUCTS(padicxx, padic_struct, padic_prec) + +namespace detail { +struct padic_data +{ + typedef padic_t& data_ref_t; + typedef const padic_t& data_srcref_t; + + padicxx_ctx_srcref ctx; + padic_t inner; + + padic_data(padicxx_ctx_srcref c) + : ctx(c) + { + padic_init(inner); + } + + padic_data(padicxx_ctx_srcref c, slong N) + : ctx(c) + { + padic_init2(inner, N); + } + + padic_data(const padic_data& o) + : ctx(o.ctx) + { + padic_init2(inner, padic_prec(o.inner)); + padic_set(inner, o.inner, ctx._ctx()); + } + + ~padic_data() {padic_clear(inner);} + + padic_data(padicxx_srcref c) + : ctx(c.get_ctx()) + { + padic_init2(inner, c.prec()); + padic_set(inner, c._padic(), ctx._ctx()); + } +}; +} // detail + +#define PADICXX_COND_S FLINTXX_COND_S(padicxx) +#define PADICXX_COND_T FLINTXX_COND_T(padicxx) + +namespace rules { + +FLINT_DEFINE_DOIT_COND2(assignment, PADICXX_COND_T, PADICXX_COND_S, + padic_set(to._padic(), from._padic(), to._ctx())) +FLINT_DEFINE_DOIT_COND2(assignment, PADICXX_COND_T, traits::is_signed_integer, + padic_set_si(to._padic(), from, to._ctx())) +FLINT_DEFINE_DOIT_COND2(assignment, PADICXX_COND_T, traits::is_unsigned_integer, + padic_set_ui(to._padic(), from, to._ctx())) +FLINT_DEFINE_DOIT_COND2(assignment, PADICXX_COND_T, FMPZXX_COND_S, + padic_set_fmpz(to._padic(), from._fmpz(), to._ctx())) +FLINT_DEFINE_DOIT_COND2(assignment, PADICXX_COND_T, FMPQXX_COND_S, + padic_set_fmpq(to._padic(), from._fmpq(), to._ctx())) + +FLINTXX_DEFINE_CONVERSION_TMP(fmpzxx, padicxx, + padic_get_fmpz(to._fmpz(), from._padic(), from._ctx())) +FLINTXX_DEFINE_CONVERSION_TMP(fmpqxx, padicxx, + padic_get_fmpq(to._fmpq(), from._padic(), from._ctx())) + +FLINTXX_DEFINE_TO_STR(padicxx, padic_get_str(0, from._padic(), from._ctx())) + +FLINTXX_DEFINE_SWAP(padicxx, padic_swap(e1._padic(), e2._padic())) + +FLINTXX_DEFINE_EQUALS(padicxx, padic_equal(e1._padic(), e2._padic())) + +FLINT_DEFINE_UNARY_EXPR_COND(padicxx_unit_op, fmpzxx, PADICXX_COND_S, + fmpz_set(to._fmpz(), padic_unit(from._padic()))) + +FLINT_DEFINE_PRINT_COND(PADICXX_COND_S, + padic_fprint(to, from._padic(), from._ctx())) + + +FLINT_DEFINE_CBINARY_EXPR_COND2(plus, padicxx, PADICXX_COND_S, PADICXX_COND_S, + padic_add(to._padic(), e1._padic(), e2._padic(), to._ctx())) +FLINT_DEFINE_BINARY_EXPR_COND2(minus, padicxx, PADICXX_COND_S, PADICXX_COND_S, + padic_sub(to._padic(), e1._padic(), e2._padic(), to._ctx())) +FLINT_DEFINE_CBINARY_EXPR_COND2(times, padicxx, PADICXX_COND_S, PADICXX_COND_S, + padic_mul(to._padic(), e1._padic(), e2._padic(), to._ctx())) +FLINT_DEFINE_BINARY_EXPR_COND2(divided_by, padicxx, PADICXX_COND_S, PADICXX_COND_S, + padic_div(to._padic(), e1._padic(), e2._padic(), to._ctx())) +FLINT_DEFINE_BINARY_EXPR_COND2(shift, padicxx, PADICXX_COND_S, + traits::fits_into_slong, + padic_shift(to._padic(), e1._padic(), e2, to._ctx())) + +FLINT_DEFINE_UNARY_EXPR_COND(negate, padicxx, PADICXX_COND_S, + padic_neg(to._padic(), from._padic(), to._ctx())) + +// lazy functions +FLINT_DEFINE_UNARY_EXPR_COND(sqrt_op, padicxx, PADICXX_COND_S, + execution_check( + padic_sqrt(to._padic(), from._padic(), to._ctx()), "sqrt", "padic")) +FLINT_DEFINE_BINARY_EXPR_COND2(pow_op, padicxx, PADICXX_COND_S, + traits::fits_into_slong, + padic_pow_si(to._padic(), e1._padic(), e2, to._ctx())) +FLINT_DEFINE_UNARY_EXPR_COND(exp_op, padicxx, PADICXX_COND_S, + execution_check( + padic_exp(to._padic(), from._padic(), to._ctx()), "exp", "padic")) +FLINT_DEFINE_UNARY_EXPR_COND(exp_balanced_op, padicxx, PADICXX_COND_S, + execution_check(padic_exp_balanced( + to._padic(), from._padic(), to._ctx()), "exp_balanced", "padic")) +FLINT_DEFINE_UNARY_EXPR_COND(exp_rectangular_op, padicxx, PADICXX_COND_S, + execution_check(padic_exp_rectangular( + to._padic(), from._padic(), to._ctx()), + "exp_rectangular", "padic")) +FLINT_DEFINE_UNARY_EXPR_COND(log_op, padicxx, PADICXX_COND_S, + execution_check( + padic_log(to._padic(), from._padic(), to._ctx()), "log", "padic")) +FLINT_DEFINE_UNARY_EXPR_COND(log_rectangular_op, padicxx, PADICXX_COND_S, + execution_check(padic_log_rectangular( + to._padic(), from._padic(), to._ctx()), + "log_rectangular", "padic")) +FLINT_DEFINE_UNARY_EXPR_COND(log_balanced_op, padicxx, PADICXX_COND_S, + execution_check(padic_log_balanced( + to._padic(), from._padic(), to._ctx()), "log_balanced", "padic")) +FLINT_DEFINE_UNARY_EXPR_COND(log_satoh_op, padicxx, PADICXX_COND_S, + execution_check(padic_log_satoh(to._padic(), from._padic(), to._ctx()), + "log_satoh", "padic")) +FLINT_DEFINE_UNARY_EXPR_COND(inv_op, padicxx, PADICXX_COND_S, + padic_inv(to._padic(), from._padic(), to._ctx())) +FLINT_DEFINE_UNARY_EXPR_COND(teichmuller_op, padicxx, PADICXX_COND_S, + padic_teichmuller(to._padic(), from._padic(), to._ctx())) + +FLINT_DEFINE_BINARY_EXPR_COND2(padic_val_fac_op, fmpzxx, + FMPZXX_COND_S, FMPZXX_COND_S, + ::padic_val_fac(to._fmpz(), e1._fmpz(), e2._fmpz())) +} // rules + +// immediate version of padic_val_fac +template +inline typename mp::enable_if, traits::is_fmpzxx >, + ulong>::type +padic_val_fac(T n, const Fmpz& p) +{ + return padic_val_fac_ui(n, p._fmpz()); +} +} // flint + +#endif diff --git a/external/flint-2.4.3/perm.h b/external/flint-2.4.3/perm.h new file mode 100644 index 0000000..ed64add --- /dev/null +++ b/external/flint-2.4.3/perm.h @@ -0,0 +1,195 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#ifndef PERM_H +#define PERM_H + +#undef ulong +#define ulong ulongxx /* interferes with system includes */ +#include +#include +#undef ulong +#include +#define ulong mp_limb_t + +#include "flint.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/* Memory management *********************************************************/ + +static __inline__ slong * _perm_init(slong n) +{ + slong i, *vec; + + vec = (slong *) flint_malloc(n * sizeof(slong)); + + if (!vec) + { + flint_printf("ERROR (_perm_init).\n\n"); + abort(); + } + + for (i = 0; i < n; i++) + vec[i] = i; + + return vec; +} + +static __inline__ void _perm_clear(slong * vec) +{ + flint_free(vec); +} + +/* Assignment ****************************************************************/ + +static __inline__ slong _perm_equal(const slong *vec1, const slong *vec2, slong n) +{ + slong i; + + for (i = 0; i < n; i++) + if (vec1[i] != vec2[i]) + return 0; + + return 1; +} + +static __inline__ void _perm_set(slong *res, const slong *vec, slong n) +{ + slong i; + + for (i = 0; i < n; i++) + res[i] = vec[i]; +} + +static __inline__ void _perm_set_one(slong *vec, slong n) +{ + slong i; + + for (i = 0; i < n; i++) + vec[i] = i; +} + +static __inline__ void + _perm_inv(slong *res, const slong *vec, slong n) +{ + slong i; + + if (res == vec) + { + slong *t = (slong *) flint_malloc(n * sizeof(slong)); + + if (!t) + { + flint_printf("ERROR (_perm_inv).\n\n"); + abort(); + } + + for (i = 0; i < n; i++) + t[i] = vec[i]; + for (i = 0; i < n; i++) + res[t[i]] = i; + + flint_free(t); + } + else + { + for (i = 0; i < n; i++) + res[vec[i]] = i; + } +} + +/* Composition ***************************************************************/ + +static __inline__ void +_perm_compose(slong *res, const slong *vec1, const slong *vec2, slong n) +{ + slong i; + + if (res == vec1) + { + slong *t = (slong *) flint_malloc(n * sizeof(slong)); + + for (i = 0; i < n; i++) + t[i] = vec1[i]; + for (i = 0; i < n; i++) + res[i] = t[vec2[i]]; + + flint_free(t); + } + else + { + for (i = 0; i < n; i++) + res[i] = vec1[vec2[i]]; + } +} + +/* Randomisation *************************************************************/ + +int _perm_randtest(slong * vec, slong n, flint_rand_t state); + +/* Parity ********************************************************************/ + +int _perm_parity(const slong * vec, slong n); + +/* Input and output **********************************************************/ + +static __inline__ int _long_vec_print(const slong * vec, slong len) +{ + slong i; + + flint_printf("%wd", len); + if (len > 0) + { + flint_printf(" "); + for (i = 0; i < len; i++) + flint_printf(" %wd", vec[i]); + } + + return 1; +} + +static __inline__ int _perm_print(const slong * vec, slong n) +{ + slong i; + + flint_printf("%wd", n); + if (n > 0) + { + flint_printf(" "); + for (i = 0; i < n; i++) + flint_printf(" %wd", vec[i]); + } + + return 1; +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/flint-2.4.3/perm/doc/perm.txt b/external/flint-2.4.3/perm/doc/perm.txt new file mode 100644 index 0000000..a55376d --- /dev/null +++ b/external/flint-2.4.3/perm/doc/perm.txt @@ -0,0 +1,108 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +******************************************************************************* + + Memory management + +******************************************************************************* + +slong * _perm_init(slong n) + + Initialises the permutation for use. + +void _perm_clear(slong *vec) + + Clears the permutation. + +******************************************************************************* + + Assignment + +******************************************************************************* + +void _perm_set(slong *res, const slong *vec, slong n) + + Sets the permutation \code{res} to the same as the permutation \code{vec}. + +void _perm_set_one(slong *vec, slong n) + + Sets the permutation to the identity permutation. + +void _perm_inv(slong *res, const slong *vec, slong n) + + Sets \code{res} to the inverse permutation of \code{vec}. + Allows aliasing of \code{res} and \code{vec}. + +******************************************************************************* + + Composition + +******************************************************************************* + +void _perm_compose(slong *res, const slong *vec1, const slong *vec2, slong n) + + Forms the composition $\pi_1 \circ \pi_2$ of two permutations + $\pi_1$ and $\pi_2$. Here, $\pi_2$ is applied first, that is, + $(\pi_1 \circ \pi_2)(i) = \pi_1(\pi_2(i))$. + + Allows aliasing of \code{res}, \code{vec1} and \code{vec2}. + +******************************************************************************* + + Parity + +******************************************************************************* + +int _perm_parity(const slong *vec, slong n) + + Returns the parity of \code{vec}, 0 if the permutation is even and 1 if + the permutation is odd. + +******************************************************************************* + + Randomisation + +******************************************************************************* + +int _perm_randtest(slong *vec, slong n, flint_rand_t state) + + Generates a random permutation vector of length $n$ and returns + its parity, 0 or 1. + + This function uses the Knuth shuffle algorithm to generate a uniformly + random permutation without retries. + +******************************************************************************* + + Input and output + +******************************************************************************* + +int _perm_print(const slong * vec, slong n) + + Prints the permutation vector of length $n$ to \code{stdout}. + diff --git a/external/flint-2.4.3/perm/parity.c b/external/flint-2.4.3/perm/parity.c new file mode 100644 index 0000000..5fb8077 --- /dev/null +++ b/external/flint-2.4.3/perm/parity.c @@ -0,0 +1,61 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "perm.h" + +int +_perm_parity(const slong *vec, slong n) +{ + slong i, k; + int * encountered; + int parity; + + if (n <= 1) + return 0; + + parity = 0; + encountered = flint_calloc(n, sizeof(int)); + + for (i = 0; i < n; i++) + { + if (encountered[i] != 0) + { + parity ^= 1; + } + else + { + k = i; + do + { + k = vec[k]; + encountered[k] = 1; + } + while (k != i); + } + } + + flint_free(encountered); + return parity; +} diff --git a/external/flint-2.4.3/perm/randtest.c b/external/flint-2.4.3/perm/randtest.c new file mode 100644 index 0000000..ada8708 --- /dev/null +++ b/external/flint-2.4.3/perm/randtest.c @@ -0,0 +1,50 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include "perm.h" +#include "flint.h" +#include "ulong_extras.h" + +int _perm_randtest(slong *vec, slong n, flint_rand_t state) +{ + slong i, j, t; + + int parity = 0; + + for (i = 0; i < n; i++) + vec[i] = i; + + for (i = n - 1; i > 0; i--) + { + j = n_randint(state, i + 1); + parity ^= (i != j); + t = vec[i]; + vec[i] = vec[j]; + vec[j] = t; + } + + return parity; +} diff --git a/external/flint-2.4.3/perm/test/t-compose.c b/external/flint-2.4.3/perm/test/t-compose.c new file mode 100644 index 0000000..ca84174 --- /dev/null +++ b/external/flint-2.4.3/perm/test/t-compose.c @@ -0,0 +1,111 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "perm.h" +#include "ulong_extras.h" + +int main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("compose...."); + fflush(stdout); + + /* check (b^(-1))(b(a)) = a */ + for (i = 0; i < 10000; i++) + { + slong n, *a, *b, *binv, *c; + + n = n_randint(state, 100); + + a = _perm_init(n); + b = _perm_init(n); + binv = _perm_init(n); + c = _perm_init(n); + + _perm_randtest(a, n, state); + _perm_randtest(b, n, state); + _perm_inv(binv, b, n); + + _perm_compose(c, b, a, n); + _perm_compose(c, binv, c, n); + + if (!_perm_equal(a, c, n)) + { + flint_printf("FAIL:\n"); + flint_printf("a: "); _perm_print(a, n); flint_printf("\n\n"); + flint_printf("b: "); _perm_print(b, n); flint_printf("\n\n"); + flint_printf("binv: "); _perm_print(binv, n); flint_printf("\n\n"); + flint_printf("c: "); _perm_print(c, n); flint_printf("\n\n"); + abort(); + } + + _perm_clear(a); + _perm_clear(b); + _perm_clear(binv); + _perm_clear(c); + } + + /* check aliasing with first argument */ + for (i = 0; i < 10000; i++) + { + slong n, *a, *b, *c; + + n = n_randint(state, 100); + + a = _perm_init(n); + b = _perm_init(n); + c = _perm_init(n); + + _perm_randtest(a, n, state); + _perm_randtest(b, n, state); + + _perm_compose(c, b, a, n); + _perm_compose(b, b, a, n); + + if (!_perm_equal(b, c, n)) + { + flint_printf("FAIL:\n"); + flint_printf("a: "); _perm_print(a, n); flint_printf("\n\n"); + flint_printf("b: "); _perm_print(b, n); flint_printf("\n\n"); + flint_printf("c: "); _perm_print(c, n); flint_printf("\n\n"); + abort(); + } + + _perm_clear(a); + _perm_clear(b); + _perm_clear(c); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/perm/test/t-inv.c b/external/flint-2.4.3/perm/test/t-inv.c new file mode 100644 index 0000000..9eb72e3 --- /dev/null +++ b/external/flint-2.4.3/perm/test/t-inv.c @@ -0,0 +1,102 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "perm.h" +#include "ulong_extras.h" + +int main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("inv...."); + fflush(stdout); + + /* check inv(inv(a)) == a */ + for (i = 0; i < 10000; i++) + { + slong n, *a, *b, *c; + + n = n_randint(state, 100); + + a = _perm_init(n); + b = _perm_init(n); + c = _perm_init(n); + + _perm_randtest(a, n, state); + + _perm_inv(b, a, n); + _perm_inv(c, b, n); + + if (!_perm_equal(a, c, n)) + { + flint_printf("FAIL:\n"); + flint_printf("a: "); _perm_print(a, n); flint_printf("\n\n"); + flint_printf("b: "); _perm_print(b, n); flint_printf("\n\n"); + flint_printf("c: "); _perm_print(c, n); flint_printf("\n\n"); + abort(); + } + + _perm_clear(a); + _perm_clear(b); + _perm_clear(c); + } + + /* check aliasing */ + for (i = 0; i < 10000; i++) + { + slong n, *a, *b; + + n = n_randint(state, 100); + + a = _perm_init(n); + b = _perm_init(n); + + _perm_randtest(a, n, state); + + _perm_inv(b, a, n); + _perm_inv(a, a, n); + + if (!_perm_equal(a, b, n)) + { + flint_printf("FAIL:\n"); + flint_printf("a: "); _perm_print(a, n); flint_printf("\n\n"); + flint_printf("b: "); _perm_print(b, n); flint_printf("\n\n"); + abort(); + } + + _perm_clear(a); + _perm_clear(b); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/perm/test/t-parity.c b/external/flint-2.4.3/perm/test/t-parity.c new file mode 100644 index 0000000..3baebc3 --- /dev/null +++ b/external/flint-2.4.3/perm/test/t-parity.c @@ -0,0 +1,86 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "perm.h" +#include "ulong_extras.h" + +int main(void) +{ + int i; + FLINT_TEST_INIT(state); + + + flint_printf("parity...."); + fflush(stdout); + + /* check inv(inv(a)) == a */ + for (i = 0; i < 10000; i++) + { + slong n, *a, *b, *c; + int ap, bp, cp, ap2, bp2, cp2; + + n = n_randint(state, 100); + + a = _perm_init(n); + b = _perm_init(n); + c = _perm_init(n); + + ap = _perm_randtest(a, n, state); + bp = _perm_randtest(b, n, state); + + _perm_compose(c, a, b, n); + cp = ap ^ bp; + + ap2 = _perm_parity(a, n); + bp2 = _perm_parity(b, n); + cp2 = _perm_parity(c, n); + + if (ap != ap2 || bp != bp2 || cp != cp2) + { + flint_printf("FAIL:\n"); + flint_printf("a: "); _perm_print(a, n); flint_printf("\n\n"); + flint_printf("b: "); _perm_print(b, n); flint_printf("\n\n"); + flint_printf("c: "); _perm_print(c, n); flint_printf("\n\n"); + flint_printf("ap = %d\n", ap); + flint_printf("bp = %d\n", bp); + flint_printf("cp = %d\n", cp); + flint_printf("ap2 = %d\n", ap2); + flint_printf("bp2 = %d\n", bp2); + flint_printf("cp2 = %d\n", cp2); + abort(); + } + + _perm_clear(a); + _perm_clear(b); + _perm_clear(c); + } + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/permxx.h b/external/flint-2.4.3/permxx.h new file mode 100644 index 0000000..754e646 --- /dev/null +++ b/external/flint-2.4.3/permxx.h @@ -0,0 +1,114 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#ifndef PERMXX_H +#define PERMXX_H + +#include "perm.h" + +#include "flintxx/frandxx.h" +#include "flintxx/mp.h" + +namespace flint { +class permxx +{ +private: + slong* data; + slong sz; + +public: + permxx(slong n) {data = _perm_init(n);sz = n;} + ~permxx() {_perm_clear(data);} + + permxx(const permxx& o) + { + sz = o.size(); + data = _perm_init(sz); + _perm_set(data, o._data(), sz); + } + permxx& operator=(const permxx& o) + { + sz = o.size(); + _perm_set(_data(), o._data(), sz); + return *this; + } + + bool operator==(const permxx& o) + {return size() == o.size() && _perm_equal(_data(), o._data(), size());} + bool operator!=(const permxx& o) {return !(*this == o);} + + static permxx one(slong n) {return permxx(n);} + static permxx randtest(slong n, frandxx& state) + {permxx res(n);res.set_randtest(state);return res;} + + void set_one() {_perm_set_one(_data(), size());} + int set_randtest(frandxx& state) + {return _perm_randtest(_data(), size(), state._data());} + + slong* _data() {return data;} + const slong* _data() const {return data;} + slong size() const {return sz;} + + slong& operator[](slong idx) {return data[idx];} + slong operator[](slong idx) const {return data[idx];} + + int parity() const {return _perm_parity(_data(), size());} + + permxx operator*(const permxx& o) const + { + permxx res(o.size()); + _perm_compose(res._data(), _data(), o._data(), size()); + return res; + } + permxx& operator*=(const permxx& o) + { + _perm_compose(_data(), _data(), o._data(), size()); + return *this; + } + + void set_inv(const permxx& o) {_perm_inv(_data(), o._data(), o.size());} + permxx inv() const {permxx res(size());res.set_inv(*this);return res;} +}; + +inline permxx compose(const permxx& p1, const permxx& p2) {return p1*p2;} +inline int parity(const permxx& p) {return p.parity();} +inline permxx inv(const permxx& o) {return o.inv();} + +inline slong* maybe_perm_data(permxx* p) {return p ? p->_data() : 0;} +inline slong* maybe_perm_data(int zero) {return 0;} + +namespace traits { +template struct is_maybe_perm + : mp::or_, mp::equal_types > { }; +template struct is_permxx : mp::equal_types { }; +} // traits + +inline int print(const permxx& p) +{ + return _perm_print(p._data(), p.size()); +} +} // flint + +#endif diff --git a/external/flint-2.4.3/printf.c b/external/flint-2.4.3/printf.c new file mode 100644 index 0000000..ef05e7d --- /dev/null +++ b/external/flint-2.4.3/printf.c @@ -0,0 +1,169 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 William Hart + +******************************************************************************/ + +#include +#include +#include +#include +#include +#include "flint.h" + +/* return number of arguments called for by a specific format specifier */ +int parse_fmt(int * floating, const char * fmt) +{ + int args = 1; + + fmt++; /* skip % */ + + if (fmt[0] == '%') + return 0; /* special case, print % */ + + if (fmt[0] == ' ' || fmt[0] == '+' || fmt[0] == '-') + fmt++; /* skip flag */ + + if (fmt[0] == '*') + { + args++; + fmt++; /* skip * */ + } else + while (isdigit((unsigned char) fmt[0])) + fmt++; /* skip width */ + + if (fmt[0] == '.') + { + fmt++; /* skip . */ + if (fmt[0] == '*') + { + args++; + fmt++; /* skip * */ + } else + while (isdigit((unsigned char) fmt[0])) + fmt++; /* skip precision */ + } + + if (fmt[0] == 'h' || fmt[0] == 'l' || fmt[0] == 'L') + fmt++; /* skip length */ + + if (fmt[0] == 'e' || fmt[0] == 'E' || fmt[0] == 'f' || fmt[0] == 'g' || fmt[0] == 'G') + (*floating) = 1; + else + (*floating) = 0; + + return args; +} + +size_t flint_printf(const char * str, ...) +{ + va_list ap; + size_t len = strlen(str); + char * str2 = flint_malloc(len + 1); + int w1 = 0, w2 = 0; + void * w3; + double d; + ulong wu; + slong w; + int args, floating; + size_t ret; + + /* deal with first substring */ + size_t n = strcspn(str, "%"); + strncpy(str2, str, n); + str2[n] = '\0'; + ret = printf("%s", str2); + len -= n; + str += n; + + va_start(ap, str); + + while (len) /* deal with fmt spec prefixed strings */ + { + n = strcspn(str + 2, "%") + 2; /* be sure to skip a %% */ + strncpy(str2, str, n); + str2[n] = '\0'; + + switch (str[1]) + { + case 'w': + if (str[2] == 'x') + { + wu = (ulong) va_arg(ap, ulong); + ret += printf(WORD_FMT "x", wu); + ret += printf("%s", str2 + 3); + } else if (str[2] == 'u') + { + wu = (ulong) va_arg(ap, ulong); + ret += printf(WORD_FMT "u", wu); + ret += printf("%s", str2 + 3); + } else if (str[2] == 'd') + { + w = (slong) va_arg(ap, slong); + ret += printf(WORD_FMT "d", w); + ret += printf("%s", str2 + 3); + } else + { + w = (slong) va_arg(ap, slong); + ret += printf(WORD_FMT "d", w); + ret += printf("%s", str2 + 2); + } + break; + default: /* pass to printf */ + args = parse_fmt(&floating, str2); + if (args) + { + if (args == 3) + w1 = va_arg(ap, int); + if (args >= 2) + w2 = va_arg(ap, int); + if (floating) + { + d = va_arg(ap, double); + if (args == 2) + ret += printf(str2, w2, d); + else if (args == 3) + ret += printf(str2, w1, w2, d); + else + ret += printf(str2, d); + } else + { + w3 = va_arg(ap, void *); + if (args == 2) + ret += printf(str2, w2, w3); + else if (args == 3) + ret += printf(str2, w1, w2, w3); + else + ret += printf(str2, w3); + } + } else ret += printf("%s", str2); /* zero args */ + } + + len -= n; + str += n; + } + + va_end(ap); + flint_free(str2); + + return ret; +} diff --git a/external/flint-2.4.3/profile/p-udiv_qrnnd.c b/external/flint-2.4.3/profile/p-udiv_qrnnd.c new file mode 100644 index 0000000..e01835f --- /dev/null +++ b/external/flint-2.4.3/profile/p-udiv_qrnnd.c @@ -0,0 +1,81 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "profiler.h" +#include "flint.h" +#include "ulong_extras.h" + +void sample(void * arg, ulong count) +{ + mp_limb_t d; + mp_ptr array = (mp_ptr) flint_malloc(200 * sizeof(mp_limb_t)); + FLINT_TEST_INIT(state); + ulong i; + int j; + + + + d = n_randtest_not_zero(state); + + for (i = 0; i < count; i++) + { + for (j = 0; j < 200; j+=2) + { + do + { + array[j] = n_randtest(state); + } while (array[j] >= d); + array[j + 1] = n_randtest(state); + } + + prof_start(); + for (j = 0; j < 200; j+=2) + { + udiv_qrnnd(array[j], array[j+1], array[j], array[j+1], d); + } + prof_stop(); + + for (j = 0; j < 200; j++) + if (array[j] == 0) flint_printf("\r"); + } + + flint_randclear(state); + flint_free(array); +} + +int main(void) +{ + double min, max; + + prof_repeat(&min, &max, sample, NULL); + + flint_printf("udiv_qrnnd min time is %.3f cycles, max time is %.3f cycles\n", + (min/(double)FLINT_CLOCK_SCALE_FACTOR)/100, (max/(double)FLINT_CLOCK_SCALE_FACTOR)/100); + + return 0; +} diff --git a/external/flint-2.4.3/profile/p-udiv_qrnnd_preinv.c b/external/flint-2.4.3/profile/p-udiv_qrnnd_preinv.c new file mode 100644 index 0000000..e8b136a --- /dev/null +++ b/external/flint-2.4.3/profile/p-udiv_qrnnd_preinv.c @@ -0,0 +1,84 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "profiler.h" +#include "flint.h" +#include "ulong_extras.h" + +void sample(void * arg, ulong count) +{ + mp_limb_t d, q, r, dinv, norm; + mp_ptr array = (mp_ptr) flint_malloc(200 * sizeof(mp_limb_t)); + FLINT_TEST_INIT(state); + ulong i; + int j; + + + + d = n_randtest_not_zero(state); + count_leading_zeros(norm, d); + d <<= norm; + + for (i = 0; i < count; i++) + { + for (j = 0; j < 200; j+=2) + { + do + { + array[j] = n_randtest(state); + } while (array[j] >= d); + array[j + 1] = n_randtest(state); + } + + invert_limb(dinv, d); + + prof_start(); + for (j = 0; j < 200; j+=2) + { + udiv_qrnnd_preinv(q, r, array[j], array[j+1], d, dinv); + } + prof_stop(); + + if (q + r == 0) flint_printf("\r"); + } + + flint_randclear(state); + flint_free(array); +} + +int main(void) +{ + double min, max; + + prof_repeat(&min, &max, sample, NULL); + + flint_printf("udiv_qrnnd_preinv min time is %.3f cycles, max time is %.3f cycles\n", + (min/(double)FLINT_CLOCK_SCALE_FACTOR)/100, (max/(double)FLINT_CLOCK_SCALE_FACTOR)/100); + + return 0; +} diff --git a/external/flint-2.4.3/profile/timings.txt b/external/flint-2.4.3/profile/timings.txt new file mode 100644 index 0000000..96c7f4e --- /dev/null +++ b/external/flint-2.4.3/profile/timings.txt @@ -0,0 +1,11 @@ +udiv_qrnnd(q, r, nh, nl, d) + + Core2 53.4 cycles + K8 74.3 cycles + K10 80.6 cycles + +udiv_qrnnd_preinv(q, r, nh, nl, d, di) + + Core2 21.7 cycles + K8 14.9 cycles + K10 17.0 cycles diff --git a/external/flint-2.4.3/profiler.c b/external/flint-2.4.3/profiler.c new file mode 100644 index 0000000..3194a38 --- /dev/null +++ b/external/flint-2.4.3/profiler.c @@ -0,0 +1,149 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007 William Hart and David Harvey + Copyright (C) 2013 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include +#include +#include "profiler.h" + +/* + clock_last[i] is the last read clock value for clock #i. + clock_accum[i] is the total time attributed to clock #i so far. + These should not be read directly; use get_clock(i) instead. + */ +double clock_last[FLINT_NUM_CLOCKS]; +double clock_accum[FLINT_NUM_CLOCKS]; + +void +prof_repeat(double *min, double *max, profile_target_t target, void *arg) +{ + /* Number of timings that were at least DURATION_THRESHOLD microseconds */ + ulong good_count = 0; + double max_time = DBL_MIN, min_time = DBL_MAX; + + /* First try one loop */ + ulong num_trials = 4; + double last_time; + init_clock(0); + target(arg, num_trials); + last_time = get_clock(0); + + /* Loop until we have enough good times */ + while (1) + { + double per_trial = last_time / num_trials; + + /* If the last recorded time was long enough, record it */ + if (last_time > DURATION_THRESHOLD) + { + if (good_count) + { + if (per_trial > max_time) + max_time = per_trial; + if (per_trial < min_time) + min_time = per_trial; + } + else + max_time = min_time = per_trial; + + if (++good_count == 5) + { + /* We've got enough data */ + break; + } + } + + /* + Adjust num_trials so that the elapsed time gravitates towards + DURATION_TARGET; num_trials can be changed by a factor of + at most 25%, and must be at least 1 + */ + { + double adjust_ratio; + if (last_time < 0.0001) + last_time = 0.0001; + adjust_ratio = DURATION_TARGET / last_time; + if (adjust_ratio > 1.25) + adjust_ratio = 1.25; + if (adjust_ratio < 0.75) + adjust_ratio = 0.75; + num_trials = (ulong) ceil(adjust_ratio * num_trials); + /* Just to be safe */ + if (num_trials == 0) + num_trials = 1; + } + + /* Run another trial */ + init_clock(0); + target(arg, num_trials); + last_time = get_clock(0); + } + + /* Store results */ + if (min) + *min = min_time; + if (max) + *max = max_time; +} + +void get_memory_usage(meminfo_t meminfo) +{ + FILE * file = fopen("/proc/self/status", "r"); + + ulong result; + char line[128]; + + while (fgets(line, 128, file) != NULL) + { + result = 0; + + if (strncmp(line, "VmSize:", 7) == 0) + { + flint_sscanf(line, "VmSize: %wu kB\n", &result); + meminfo->size = result; + } + else if (strncmp(line, "VmPeak:", 7) == 0) + { + flint_sscanf(line, "VmPeak: %wu kB\n", &result); + meminfo->peak = result; + } + else if (strncmp(line, "VmHWM:", 6) == 0) + { + flint_sscanf(line, "VmHWM: %wu kB\n", &result); + meminfo->hwm = result; + } + else if (strncmp(line, "VmRSS:", 6) == 0) + { + flint_sscanf(line, "VmRSS: %wu kB\n", &result); + meminfo->rss = result; + } + } + + fclose(file); +} + diff --git a/external/flint-2.4.3/profiler.h b/external/flint-2.4.3/profiler.h new file mode 100644 index 0000000..d5ec8c7 --- /dev/null +++ b/external/flint-2.4.3/profiler.h @@ -0,0 +1,253 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright 2007 William Hart and David Harvey + +******************************************************************************/ +#ifndef FLINT_PROFILER_H +#define FLINT_PROFILER_H + +#include "flint.h" + +#undef ulong +#define ulong ulongxx /* interferes with system includes */ +#include +#include +#if defined (__WIN32) && !defined(__CYGWIN__) +#ifdef __cplusplus +void GetSystemTimeAsFileTime(FILETIME*); + +static __inline__ int gettimeofday(struct timeval * p, void * tz) +{ + union { + slong slong ns100; + FILETIME ft; + } now; + + GetSystemTimeAsFileTime(&(now.ft)); + p->tv_usec=(slong)((now.ns100 / WORD(10)L) % WORD(1000000)L ); + p->tv_sec= (slong)((now.ns100-(WORD(116444736000000000)L))/WORD(10000000)L); + + return 0; +} +#else +int gettimeofday(struct timeval * p, void * tz); +#endif +#else +#include +#endif +#undef ulong +#define ulong mp_limb_t + +#ifdef __cplusplus + extern "C" { +#endif + +typedef struct +{ + ulong size; + ulong peak; + ulong hwm; + ulong rss; +} meminfo_t[1]; + +void get_memory_usage(meminfo_t meminfo); + +typedef struct +{ + slong cpu; + slong wall; +} timeit_t[1]; + +static __inline__ +void timeit_start(timeit_t t) +{ + struct timeval tv; + gettimeofday(&tv, 0); + t->wall = - tv.tv_sec * 1000 - tv.tv_usec / 1000; + t->cpu = - clock() * 1000 / CLOCKS_PER_SEC; +} + +static __inline__ +void timeit_stop(timeit_t t) +{ + struct timeval tv; + gettimeofday(&tv, 0); + t->wall += tv.tv_sec * 1000 + tv.tv_usec / 1000; + t->cpu += clock() * 1000 / CLOCKS_PER_SEC; +} + +/****************************************************************************** + + Timer based on the cycle counter + +******************************************************************************/ + +#define FLINT_NUM_CLOCKS 20 + +#define FLINT_CLOCKSPEED 2400000000.0 + +extern double clock_last[FLINT_NUM_CLOCKS]; +extern double clock_accum[FLINT_NUM_CLOCKS]; + +static __inline__ +double get_cycle_counter() +{ + unsigned int hi; + unsigned int lo; + + __asm("rdtsc; movl %%edx,%0; movl %%eax,%1" + : "=r" (hi), "=r" (lo) + : + : "%edx", "%eax"); + + return (double) hi * (1 << 30) * 4 + lo; +} + +#define FLINT_CLOCK_SCALE_FACTOR (1000000.0 / FLINT_CLOCKSPEED) + +static __inline__ +void init_clock(int n) +{ + clock_accum[n] = 0.0; +} + +static __inline__ +void init_all_clocks() +{ + int i; + for (i = 0; i < FLINT_NUM_CLOCKS; i++) + clock_accum[i] = 0.0; +} + +static __inline__ +double get_clock(int n) +{ + return clock_accum[n] * FLINT_CLOCK_SCALE_FACTOR; +} + +static __inline__ +void start_clock(int n) +{ + clock_last[n] = get_cycle_counter(); +} + +static __inline__ +void stop_clock(int n) +{ + double now = get_cycle_counter(); + clock_accum[n] += (now - clock_last[n]); +} + +/****************************************************************************** + + Framework for repeatedly sampling a single target + +******************************************************************************/ + +static __inline__ +void prof_start() +{ + start_clock(0); +} + +static __inline__ +void prof_stop() +{ + stop_clock(0); +} + +typedef void (*profile_target_t)(void* arg, ulong count); + +void prof_repeat(double* min, double* max, profile_target_t target, void* arg); + +#define DURATION_THRESHOLD 5000.0 + +#define DURATION_TARGET 10000.0 + +/****************************************************************************** + + Simple timing macros + +******************************************************************************/ + +#define TIMEIT_PRINT(__timer, __reps) \ + flint_printf("cpu/wall(s): %g %g\n", \ + __timer->cpu*0.001/__reps, __timer->wall*0.001 / __reps); + +#define TIMEIT_REPEAT(__timer, __reps) \ + do \ + { \ + slong __timeit_k; \ + __reps = 1; \ + while (1) \ + { \ + timeit_start(__timer); \ + for (__timeit_k = 0; __timeit_k < __reps; __timeit_k++) \ + { + +#define TIMEIT_END_REPEAT(__timer, __reps) \ + } \ + timeit_stop(__timer); \ + if (__timer->cpu >= 100) \ + break; \ + __reps *= 10; \ + } \ + } while (0); + +#define TIMEIT_START \ + do { \ + timeit_t __timer; slong __reps; \ + TIMEIT_REPEAT(__timer, __reps) + +#define TIMEIT_STOP \ + TIMEIT_END_REPEAT(__timer, __reps) \ + TIMEIT_PRINT(__timer, __reps) \ + } while (0); + +#define TIMEIT_ONCE_START \ + do \ + { \ + timeit_t __timer; \ + timeit_start(__timer); \ + do { \ + +#define TIMEIT_ONCE_STOP \ + } while (0); \ + timeit_stop(__timer); \ + TIMEIT_PRINT(__timer, 1) \ + } while (0); \ + +#define SHOW_MEMORY_USAGE \ + do { \ + meminfo_t meminfo; \ + get_memory_usage(meminfo); \ + flint_printf("virt/peak/res/peak(MB): %.2f %.2f %.2f %.2f\n", \ + meminfo->size / 1024.0, meminfo->peak / 1024.0, \ + meminfo->rss / 1024.0, meminfo->hwm / 1024.0); \ + } while (0); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/external/flint-2.4.3/qadic.h b/external/flint-2.4.3/qadic.h new file mode 100644 index 0000000..e2b603c --- /dev/null +++ b/external/flint-2.4.3/qadic.h @@ -0,0 +1,467 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012, 2013 Sebastian Pancratz + +******************************************************************************/ + +#ifndef QADIC_H +#define QADIC_H + +#undef ulong +#define ulong ulongxx /* interferes with system includes */ +#include +#include +#undef ulong + +#include + +#include "flint.h" +#include "fmpz.h" +#include "fmpq.h" +#include "fmpz_vec.h" +#include "ulong_extras.h" +#include "padic.h" +#include "padic_poly.h" + +#define ulong mp_limb_t + +#ifdef __cplusplus + extern "C" { +#endif + +/* Data types and context ****************************************************/ + +typedef padic_poly_t qadic_t; + +typedef padic_poly_struct qadic_struct; + +static __inline__ slong qadic_val(const qadic_t op) +{ + return padic_poly_val(op); +} + +static __inline__ slong qadic_prec(const qadic_t op) +{ + return padic_poly_prec(op); +} + +typedef struct +{ + padic_ctx_struct pctx; + + fmpz *a; + slong *j; + slong len; + + char *var; +} +qadic_ctx_struct; + +typedef qadic_ctx_struct qadic_ctx_t[1]; + +void qadic_ctx_init_conway(qadic_ctx_t ctx, + const fmpz_t p, slong d, slong min, slong max, + const char *var, enum padic_print_mode mode); + +void qadic_ctx_clear(qadic_ctx_t ctx); + +static __inline__ slong qadic_ctx_degree(const qadic_ctx_t ctx) +{ + return ctx->j[ctx->len - 1]; +} + +static __inline__ void qadic_ctx_print(const qadic_ctx_t ctx) +{ + slong i, k; + + flint_printf("p = "), fmpz_print((&ctx->pctx)->p), flint_printf("\n"); + flint_printf("d = %wd\n", ctx->j[ctx->len - 1]); + flint_printf("f(X) = "); + fmpz_print(ctx->a + 0); + for (k = 1; k < ctx->len; k++) + { + i = ctx->j[k]; + flint_printf(" + "); + if (fmpz_is_one(ctx->a + k)) + { + if (i == 1) + flint_printf("X"); + else + flint_printf("X^%wd", i); + } + else + { + fmpz_print(ctx->a + k); + if (i == 1) + flint_printf("*X"); + else + flint_printf("*X^%wd", i); + } + } + flint_printf("\n"); +} + +/* Memory management *********************************************************/ + +static __inline__ void qadic_init(qadic_t x) +{ + padic_poly_init(x); +} + +static __inline__ void qadic_init2(qadic_t rop, slong prec) +{ + padic_poly_init2(rop, 0, prec); +} + +static __inline__ void qadic_clear(qadic_t x) +{ + padic_poly_clear(x); +} + +/* + TODO: Consider renaming this function, prefix for the "qadic" module. + */ + +static __inline__ void +_fmpz_poly_reduce(fmpz *R, slong lenR, const fmpz *a, const slong *j, slong len) +{ + const slong d = j[len - 1]; + slong i, k; + + FMPZ_VEC_NORM(R, lenR); + + for (i = lenR - 1; i >= d; i--) + { + for (k = len - 2; k >= 0; k--) + { + fmpz_submul(R + j[k] + i - d, R + i, a + k); + } + fmpz_zero(R + i); + } +} + +/* + TODO: Consider renaming this function, prefix for the "qadic" module. + */ + +static __inline__ void +_fmpz_mod_poly_reduce(fmpz *R, slong lenR, + const fmpz *a, const slong *j, slong len, const fmpz_t p) +{ + const slong d = j[len - 1]; + + if (lenR > d) + { + _fmpz_poly_reduce(R, lenR, a, j, len); + _fmpz_vec_scalar_mod_fmpz(R, R, d, p); + } + else + { + _fmpz_vec_scalar_mod_fmpz(R, R, lenR, p); + } +} + +static __inline__ void qadic_reduce(qadic_t x, const qadic_ctx_t ctx) +{ + const slong N = qadic_prec(x); + const slong d = ctx->j[ctx->len - 1]; + + if (x->length == 0 || x->val >= N) + { + padic_poly_zero(x); + } + else + { + fmpz_t pow; + int alloc; + + alloc = _padic_ctx_pow_ui(pow, N - x->val, &ctx->pctx); + + _fmpz_mod_poly_reduce(x->coeffs, x->length, ctx->a, ctx->j, ctx->len, pow); + _padic_poly_set_length(x, FLINT_MIN(x->length, d)); + _padic_poly_normalise(x); + padic_poly_canonicalise(x, (&ctx->pctx)->p); + + if (alloc) + fmpz_clear(pow); + } +} + +/* Randomisation *************************************************************/ + +static __inline__ void +qadic_randtest(qadic_t x, flint_rand_t state, const qadic_ctx_t ctx) +{ + padic_poly_randtest(x, state, qadic_ctx_degree(ctx), &ctx->pctx); +} + +static __inline__ void +qadic_randtest_not_zero(qadic_t x, flint_rand_t state, const qadic_ctx_t ctx) +{ + padic_poly_randtest_not_zero(x, state, qadic_ctx_degree(ctx), + &ctx->pctx); +} + +static __inline__ void +qadic_randtest_val(qadic_t x, flint_rand_t state, slong val, + const qadic_ctx_t ctx) +{ + padic_poly_randtest_val(x, state, val, qadic_ctx_degree(ctx), &ctx->pctx); +} + +static __inline__ void +qadic_randtest_int(qadic_t x, flint_rand_t state, const qadic_ctx_t ctx) +{ + const slong N = qadic_prec(x); + + if (N <= 0) + { + padic_poly_zero(x); + } + else + { + padic_poly_randtest_val(x, state, n_randint(state, N), + qadic_ctx_degree(ctx), &ctx->pctx); + } +} + +/* Assignments and conversions ***********************************************/ + +static __inline__ void qadic_zero(qadic_t op) +{ + padic_poly_zero(op); +} + +static __inline__ void qadic_one(qadic_t op) +{ + padic_poly_one(op); +} + +static __inline__ void qadic_gen(qadic_t x, const qadic_ctx_t ctx) +{ + const slong N = qadic_prec(x); + const slong d = qadic_ctx_degree(ctx); + + if (d > 1) + { + if (N > 0) + { + padic_poly_fit_length(x, 2); + fmpz_zero(x->coeffs + 0); + fmpz_one(x->coeffs + 1); + _padic_poly_set_length(x, 2); + x->val = 0; + } + else + { + padic_poly_zero(x); + } + } + else + { + flint_printf("Exception (qadic_gen). Extension degree d = 1.\n"); + abort(); + } +} + +static __inline__ +void qadic_set_ui(qadic_t rop, ulong op, const qadic_ctx_t ctx) +{ + padic_poly_set_ui(rop, op, &ctx->pctx); +} + +static __inline__ int +qadic_get_padic(padic_t rop, const qadic_t op, const qadic_ctx_t ctx) +{ + if (op->length > 0) + { + if (_fmpz_vec_is_zero(op->coeffs + 1, op->length - 1)) + { + fmpz_set(padic_unit(rop), op->coeffs + 0); + padic_val(rop) = op->val; + _padic_canonicalise(rop, &ctx->pctx); + return 1; + } + else + { + return 0; + } + } + else + { + padic_zero(rop); + return 1; + } +} + +static __inline__ void qadic_set(qadic_t rop, const qadic_t op, const qadic_ctx_t ctx) +{ + padic_poly_set(rop, op, &(ctx->pctx)); +} + +void qadic_set_fmpz_poly(qadic_t rop, const fmpz_poly_t op, + const qadic_ctx_t ctx); + +/* Comparison ****************************************************************/ + +static __inline__ int qadic_is_zero(const qadic_t op) +{ + return padic_poly_is_zero(op); +} + +static __inline__ int qadic_is_one(const qadic_t op) +{ + return padic_poly_is_one(op); +} + +static __inline__ int qadic_equal(const qadic_t op1, const qadic_t op2) +{ + return padic_poly_equal(op1, op2); +} + +/* Basic arithmetic **********************************************************/ + +static __inline__ void +qadic_add(qadic_t x, const qadic_t y, const qadic_t z, const qadic_ctx_t ctx) +{ + padic_poly_add(x, y, z, &ctx->pctx); +} + +static __inline__ void +qadic_sub(qadic_t x, const qadic_t y, const qadic_t z, const qadic_ctx_t ctx) +{ + padic_poly_sub(x, y, z, &ctx->pctx); +} + +static __inline__ void +qadic_neg(qadic_t x, const qadic_t y, const qadic_ctx_t ctx) +{ + padic_poly_neg(x, y, &ctx->pctx); +} + +void qadic_mul(qadic_t x, const qadic_t y, const qadic_t z, + const qadic_ctx_t ctx); + +void _qadic_inv(fmpz *rop, const fmpz *op, slong len, + const fmpz *a, const slong *j, slong lena, + const fmpz_t p, slong N); + +void qadic_inv(qadic_t x, const qadic_t y, const qadic_ctx_t ctx); + +void _qadic_pow(fmpz *rop, const fmpz *op, slong len, const fmpz_t e, + const fmpz *a, const slong *j, slong lena, + const fmpz_t p); + +void qadic_pow(qadic_t x, const qadic_t y, const fmpz_t e, const qadic_ctx_t ctx); + +/* Special functions *********************************************************/ + +void _qadic_exp_rectangular(fmpz *rop, const fmpz *op, slong v, slong len, + const fmpz *a, const slong *j, slong lena, + const fmpz_t p, slong N, const fmpz_t pN); + +int qadic_exp_rectangular(qadic_t rop, const qadic_t op, + const qadic_ctx_t ctx); + +void _qadic_exp_balanced(fmpz *rop, const fmpz *op, slong v, slong len, + const fmpz *a, const slong *j, slong lena, + const fmpz_t p, slong N, const fmpz_t pN); + +int qadic_exp_balanced(qadic_t rop, const qadic_t op, + const qadic_ctx_t ctx); + +void _qadic_exp(fmpz *rop, const fmpz *op, slong v, slong len, + const fmpz *a, const slong *j, slong lena, + const fmpz_t p, slong N, const fmpz_t pN); + +int qadic_exp(qadic_t rop, const qadic_t op, const qadic_ctx_t ctx); + +void _qadic_log_rectangular(fmpz *z, const fmpz *y, slong v, slong len, + const fmpz *a, const slong *j, slong lena, + const fmpz_t p, slong N, const fmpz_t pN); + +int qadic_log_rectangular(qadic_t rop, const qadic_t op, const qadic_ctx_t ctx); + +void _qadic_log_balanced(fmpz *z, const fmpz *y, slong len, + const fmpz *a, const slong *j, slong lena, + const fmpz_t p, slong N, const fmpz_t pN); + +int qadic_log_balanced(qadic_t rop, const qadic_t op, const qadic_ctx_t ctx); + +void _qadic_log(fmpz *z, const fmpz *y, slong v, slong len, + const fmpz *a, const slong *j, slong lena, + const fmpz_t p, slong N, const fmpz_t pN); + +int qadic_log(qadic_t rop, const qadic_t op, const qadic_ctx_t ctx); + +void qadic_frobenius(qadic_t rop, const qadic_t op, slong e, const qadic_ctx_t ctx); + +void _qadic_teichmuller(fmpz *rop, const fmpz *op, slong len, + const fmpz *a, const slong *j, slong lena, + const fmpz_t p, slong N); + +void qadic_teichmuller(qadic_t rop, const qadic_t op, const qadic_ctx_t ctx); + +void _qadic_trace(fmpz_t rop, const fmpz *op, slong len, + const fmpz *a, const slong *j, slong lena, const fmpz_t pN); + +void qadic_trace(padic_t rop, const qadic_t op, const qadic_ctx_t ctx); + + +void _qadic_norm_resultant(fmpz_t rop, const fmpz *op, slong len, + const fmpz *a, const slong *j, slong lena, + const fmpz_t p, slong N); +void _qadic_norm_analytic(fmpz_t rop, const fmpz *y, slong v, slong len, + const fmpz *a, const slong *j, slong lena, + const fmpz_t p, slong N); +void _qadic_norm(fmpz_t rop, const fmpz *op, slong len, + const fmpz *a, const slong *j, slong lena, + const fmpz_t p, slong N); + +void qadic_norm(padic_t rop, const qadic_t op, const qadic_ctx_t ctx); +void qadic_norm_analytic(padic_t rop, const qadic_t op, const qadic_ctx_t ctx); +void qadic_norm_resultant(padic_t rop, const qadic_t op, const qadic_ctx_t ctx); + +int qadic_sqrt(qadic_t rop, const qadic_t op, const qadic_ctx_t ctx); +int qadic_invsqrt(qadic_t rop, const qadic_t op, const qadic_ctx_t ctx); + +/* Output ********************************************************************/ + +int qadic_fprint_pretty(FILE *file, const qadic_t op, const qadic_ctx_t ctx); + +static __inline__ int +qadic_print_pretty(const qadic_t op, const qadic_ctx_t ctx) +{ + return qadic_fprint_pretty(stdout, op, ctx); +} + +static __inline__ int qadic_debug(const qadic_t op) +{ + return padic_poly_debug(op); +} + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/external/flint-2.4.3/qadic/CPimport.txt b/external/flint-2.4.3/qadic/CPimport.txt new file mode 100644 index 0000000..e4df203 --- /dev/null +++ b/external/flint-2.4.3/qadic/CPimport.txt @@ -0,0 +1,35357 @@ +2 1 1 1 +2 2 1 1 1 +2 3 1 1 0 1 +2 4 1 1 0 0 1 +2 5 1 0 1 0 0 1 +2 6 1 1 0 1 1 0 1 +2 7 1 1 0 0 0 0 0 1 +2 8 1 0 1 1 1 0 0 0 1 +2 9 1 0 0 0 1 0 0 0 0 1 +2 10 1 1 1 1 0 1 1 0 0 0 1 +2 11 1 0 1 0 0 0 0 0 0 0 0 1 +2 12 1 1 0 1 0 1 1 1 0 0 0 0 1 +2 13 1 1 0 1 1 0 0 0 0 0 0 0 0 1 +2 14 1 0 0 1 0 1 0 1 0 0 0 0 0 0 1 +2 15 1 0 1 0 1 1 0 0 0 0 0 0 0 0 0 1 +2 16 1 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 1 +2 17 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 18 1 1 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 1 +2 19 1 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 20 1 1 0 0 1 1 1 1 0 1 1 0 0 0 0 0 0 0 0 0 1 +2 21 1 0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 22 1 0 0 0 0 1 1 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 1 +2 23 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 24 1 0 0 1 0 1 0 1 0 1 1 0 0 1 1 1 1 0 0 0 0 0 0 0 1 +2 25 1 0 1 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 26 1 1 0 0 1 0 1 1 1 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 +2 27 1 0 1 1 0 1 0 1 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 28 1 0 1 0 0 1 1 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 29 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 30 1 1 1 1 0 1 0 1 0 0 0 1 0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 31 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 32 1 0 0 1 1 0 0 1 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 33 1 0 0 1 0 0 1 0 1 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 34 1 1 1 0 1 1 1 1 1 0 0 1 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 35 1 0 1 0 0 1 0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 36 1 1 0 0 0 1 1 0 1 0 0 0 0 1 1 0 0 1 0 1 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 37 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 38 1 1 1 0 0 1 0 0 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 39 1 0 1 0 0 1 1 1 0 1 1 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 40 1 1 0 1 0 1 0 0 1 0 0 0 1 1 0 1 1 0 1 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 41 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 42 1 1 1 0 0 1 1 0 0 1 0 1 1 0 0 0 0 0 1 0 1 0 0 0 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 +2 43 1 0 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 44 1 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 45 1 0 0 0 0 0 1 0 0 0 0 1 1 0 1 1 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 46 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 47 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 48 1 0 0 1 0 0 0 1 1 0 1 1 1 0 0 0 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 49 1 1 1 1 1 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 50 1 0 1 0 1 0 1 0 1 1 1 0 1 1 1 0 1 1 0 1 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 51 1 0 0 0 0 0 1 0 0 1 0 0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 52 1 1 0 0 1 0 0 1 0 0 1 0 0 0 1 1 0 1 0 0 0 1 0 1 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 53 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 54 1 1 1 0 1 0 0 1 0 0 0 0 0 1 0 1 1 1 1 0 0 1 0 0 0 1 0 1 0 1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 55 1 0 0 0 1 0 0 1 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 56 1 0 1 1 1 0 0 0 1 1 0 1 0 1 1 0 0 0 0 1 0 0 1 0 0 0 1 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 57 1 1 1 1 1 1 1 0 1 0 1 1 0 1 0 0 1 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 58 1 1 0 1 0 1 1 1 1 0 1 1 1 0 0 0 1 0 1 0 0 0 1 0 1 1 1 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 59 1 1 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 60 1 0 1 1 1 1 0 0 1 0 0 0 1 0 0 0 0 1 0 1 0 0 1 0 0 1 1 0 0 0 1 0 1 1 1 0 1 0 0 1 0 1 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 61 1 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 62 1 1 0 0 0 0 1 0 0 0 0 0 1 1 1 0 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 63 1 1 1 1 1 0 0 0 1 1 0 1 0 0 0 1 1 1 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 64 1 1 1 0 1 1 0 1 0 0 1 1 1 1 0 0 0 0 1 0 1 1 1 1 1 1 1 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 65 1 1 0 0 0 1 0 1 0 1 1 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 66 1 0 1 0 1 1 1 1 0 0 0 1 0 1 0 0 1 0 0 1 0 1 1 1 1 0 0 1 0 1 1 1 1 1 1 0 0 0 1 0 1 0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 67 1 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 68 1 1 0 0 1 1 0 0 1 1 0 0 0 1 1 1 0 0 0 0 1 0 1 0 0 0 1 0 1 1 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 69 1 0 0 0 1 1 0 0 1 1 1 0 0 0 1 0 0 1 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 70 1 0 1 1 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 1 1 1 0 0 1 0 1 0 0 1 1 0 1 1 1 1 1 1 0 1 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 71 1 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 72 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 1 0 0 1 0 0 1 1 1 0 1 0 1 0 1 1 1 1 0 0 1 0 0 1 0 0 0 0 0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 73 1 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 74 1 0 0 1 0 0 0 0 1 0 0 1 1 1 0 0 1 1 0 0 0 1 0 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 75 1 1 0 0 1 1 0 0 0 1 0 0 1 0 1 0 0 0 0 0 0 0 1 1 0 1 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 76 1 1 1 0 0 1 0 0 0 0 0 0 0 0 1 1 0 0 0 1 1 0 0 1 1 1 0 1 0 1 0 1 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 77 1 0 1 0 1 0 0 0 0 0 0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 78 1 1 0 0 1 0 1 1 1 1 0 1 0 1 1 1 0 1 1 1 0 1 1 0 1 1 0 1 1 0 0 0 1 1 1 1 0 1 0 1 0 0 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 79 1 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 80 1 0 1 0 1 1 1 0 1 1 0 1 0 1 0 1 0 1 0 0 1 1 1 0 1 1 1 0 0 1 0 1 1 1 0 0 0 0 1 0 0 1 1 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 81 1 0 0 1 1 0 1 1 0 1 1 1 0 0 0 1 1 1 0 0 0 1 0 1 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 82 1 1 1 1 1 0 1 1 0 1 0 1 1 1 0 1 1 1 0 0 0 1 1 0 1 0 0 0 1 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 83 1 0 1 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 84 1 0 1 0 1 1 0 1 1 1 0 1 1 1 0 0 1 1 0 0 1 1 0 0 1 1 1 0 1 0 0 1 1 0 0 0 0 1 0 1 0 1 0 0 0 0 1 1 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 85 1 0 1 0 0 0 1 1 0 0 0 0 0 0 1 1 1 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 86 1 1 1 0 0 1 1 1 1 1 1 0 1 0 1 0 1 0 0 0 0 1 1 0 0 1 0 1 0 0 0 1 0 0 0 0 0 0 1 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 87 1 1 0 1 0 1 0 1 1 0 1 1 1 1 1 0 1 0 0 0 1 0 0 0 0 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 88 1 1 0 1 1 1 0 1 1 1 0 1 1 1 1 1 0 0 1 1 0 1 0 0 1 0 0 1 1 0 1 1 0 1 0 0 1 0 1 0 0 1 0 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 89 1 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 90 1 0 1 0 1 0 0 1 0 0 1 1 1 0 1 0 1 0 1 0 0 0 0 0 1 1 1 0 1 0 1 0 1 0 1 0 1 1 1 1 1 0 1 0 1 1 1 1 1 0 1 1 0 1 0 1 1 1 1 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 91 1 1 0 0 1 0 0 0 0 1 1 0 1 1 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 92 1 0 1 0 1 1 0 0 0 1 0 0 1 0 1 1 1 1 1 0 0 1 1 1 1 0 0 0 0 0 1 0 1 1 0 0 0 1 1 0 1 1 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 95 1 1 0 1 0 0 1 0 1 1 0 0 1 1 1 0 1 1 1 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 96 1 0 1 1 1 0 1 1 1 1 0 1 0 1 1 1 1 0 1 1 1 1 0 1 1 0 0 0 1 0 0 0 1 1 0 0 0 1 0 0 1 0 0 0 1 0 1 0 0 0 1 0 0 0 1 0 0 0 0 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 97 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 98 1 1 0 1 0 0 1 0 1 0 1 1 0 0 1 1 0 0 1 0 0 0 1 0 0 0 1 1 1 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 1 0 1 0 1 0 1 1 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 100 1 0 0 1 0 1 1 0 1 1 0 1 0 0 0 1 1 0 0 1 1 0 1 0 1 1 0 1 0 0 1 1 0 0 1 1 1 1 0 0 0 1 0 1 1 1 1 1 1 0 0 0 1 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 101 1 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 102 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 1 1 1 0 1 1 0 1 0 0 0 0 0 0 1 0 1 0 1 0 0 1 1 0 1 0 1 0 1 1 0 1 1 1 1 1 1 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 103 1 0 1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 107 1 1 1 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 108 1 0 1 1 0 0 0 1 1 1 1 1 0 0 0 1 0 0 1 0 1 0 0 1 1 0 1 0 0 1 1 1 1 1 1 1 0 1 1 0 0 0 1 1 1 1 1 1 0 0 1 0 0 0 1 0 0 1 0 1 0 1 1 1 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 109 1 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 110 1 1 1 0 0 0 1 0 0 0 1 1 0 1 1 0 0 1 0 0 1 0 0 0 0 1 1 0 1 1 0 0 0 1 0 1 1 1 0 1 0 0 1 1 0 0 0 0 1 0 0 0 0 0 1 1 1 1 1 1 0 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 113 1 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 114 1 0 0 1 0 0 0 1 0 1 0 1 0 1 0 1 1 0 1 0 1 1 0 0 0 1 1 1 1 0 1 1 0 0 1 1 1 1 0 0 1 0 1 0 0 0 0 1 0 0 1 0 1 0 1 1 1 1 0 0 1 0 1 1 1 1 0 0 1 1 1 1 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 115 1 1 0 0 1 0 1 1 0 1 1 1 1 1 1 1 0 1 1 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 119 1 1 1 0 0 0 0 1 0 0 0 0 0 1 1 1 1 1 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 120 1 0 1 1 1 1 0 1 0 0 0 0 1 1 1 0 1 1 0 0 0 0 0 0 0 1 0 0 1 1 1 1 0 0 1 0 1 0 1 0 1 1 1 0 1 1 1 1 1 0 1 1 1 0 0 0 1 0 1 0 1 0 0 0 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0 1 0 1 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 121 1 0 1 0 0 0 1 1 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 125 1 0 0 1 0 1 1 0 0 1 1 1 1 1 0 1 1 1 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 126 1 1 0 0 0 1 1 0 1 0 1 1 0 1 0 1 1 1 0 1 1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0 1 1 0 1 1 1 1 1 1 1 0 1 0 0 0 1 1 0 0 0 1 1 0 1 1 0 1 0 1 0 0 0 1 0 1 1 0 0 1 0 0 1 0 1 0 1 0 0 0 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 127 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 131 1 1 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 132 1 0 0 0 1 1 0 1 0 1 1 0 0 0 0 0 1 0 1 0 1 0 0 1 1 0 1 1 0 0 1 0 0 0 0 1 0 1 1 1 0 1 0 1 1 0 0 0 0 0 1 1 1 0 0 0 0 1 0 0 1 0 0 1 0 1 0 0 0 1 1 1 0 0 0 0 0 1 0 0 1 0 0 0 1 1 0 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 133 1 0 0 0 0 1 1 0 1 0 0 1 0 1 0 1 1 1 0 1 1 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 137 1 0 1 1 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 139 1 1 1 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 143 1 1 1 0 1 0 0 1 0 0 0 1 1 0 1 0 1 1 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 149 1 1 0 1 1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 150 1 1 0 1 0 1 1 0 1 0 0 0 1 0 1 0 1 0 1 0 1 0 1 0 0 1 1 1 1 0 0 1 0 0 1 1 1 0 0 0 0 1 0 0 0 1 0 1 0 0 1 1 1 1 1 1 0 1 1 1 1 0 1 0 1 1 1 1 0 0 0 0 0 1 0 1 1 0 0 1 1 1 1 0 0 1 0 1 1 0 1 1 1 1 0 0 0 0 1 1 1 1 0 1 0 1 1 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 151 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 157 1 0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 163 1 0 0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 167 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 169 1 0 0 1 0 1 1 0 1 1 0 0 1 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 173 1 0 1 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 179 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 181 1 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 191 1 1 0 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 193 1 1 1 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 197 1 1 1 1 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 199 1 0 1 1 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 211 1 1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 223 1 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 227 1 1 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 229 1 1 1 0 0 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 233 1 0 1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 239 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 241 1 0 0 1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 251 1 0 1 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 257 1 0 1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 263 1 1 1 1 1 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 269 1 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 271 1 1 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 277 1 1 1 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 281 1 1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 283 1 1 1 0 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 289 1 1 1 1 0 0 1 1 1 0 1 0 1 1 1 0 1 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 293 1 1 0 1 1 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 307 1 0 1 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 311 1 0 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 313 1 1 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 317 1 0 1 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 331 1 0 1 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 337 1 1 1 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 347 1 0 1 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 349 1 0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 353 1 0 0 0 1 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 359 1 1 1 0 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 361 1 1 0 0 1 0 1 0 1 0 1 1 1 1 0 1 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 367 1 1 0 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 373 1 0 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 379 1 1 0 1 0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 383 1 1 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 389 1 1 1 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 397 1 1 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 401 1 1 0 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +2 409 1 0 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 1 1 1 +3 2 2 2 1 +3 3 1 2 0 1 +3 4 2 0 0 2 1 +3 5 1 2 0 0 0 1 +3 6 2 2 1 0 2 0 1 +3 7 1 0 2 0 0 0 0 1 +3 8 2 2 2 0 1 2 0 0 1 +3 9 1 1 2 2 0 0 0 0 0 1 +3 10 2 1 0 0 2 2 2 0 0 0 1 +3 11 1 0 2 0 0 0 0 0 0 0 0 1 +3 12 2 0 1 0 1 1 1 0 0 0 0 0 1 +3 13 1 2 0 0 0 0 0 0 0 0 0 0 0 1 +3 14 2 0 1 2 0 1 2 1 1 2 0 0 0 0 1 +3 15 1 1 2 0 0 1 0 0 2 0 0 0 0 0 0 1 +3 16 2 1 2 2 2 0 2 2 0 0 0 0 0 0 0 0 1 +3 17 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 18 2 0 2 0 2 1 2 0 2 0 1 0 0 0 0 0 0 0 1 +3 19 1 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 20 2 1 0 2 2 2 0 0 1 1 1 1 0 2 0 0 0 0 0 0 1 +3 21 1 2 0 2 0 1 2 0 2 0 2 0 0 0 0 0 0 0 0 0 0 1 +3 22 2 2 0 1 0 1 1 1 2 2 1 2 0 0 0 0 0 0 0 0 0 0 1 +3 23 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 24 2 2 0 2 2 0 2 0 2 0 0 2 0 0 1 0 0 0 0 0 0 0 0 0 1 +3 25 1 2 1 1 0 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 26 2 1 2 1 0 0 2 2 2 2 2 2 2 1 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 27 1 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 28 2 0 0 1 2 0 2 0 1 1 1 2 1 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 29 1 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 30 2 2 2 1 2 2 1 2 0 2 2 2 0 2 1 0 2 2 2 0 2 0 0 0 0 0 0 0 0 0 1 +3 31 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 32 2 1 0 1 2 1 2 0 0 0 0 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 33 1 0 2 1 2 2 1 0 0 1 0 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 34 2 0 0 0 2 0 2 1 0 2 0 1 2 0 2 0 2 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 35 1 1 2 0 2 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 36 2 1 1 1 0 2 2 0 2 1 2 2 0 2 2 0 1 1 0 0 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 37 1 2 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 38 2 2 0 1 2 2 2 0 2 2 1 0 2 2 2 2 1 0 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 39 1 0 2 0 1 0 1 2 0 1 2 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 40 2 0 1 2 1 1 2 2 1 0 1 2 0 2 0 1 1 2 0 1 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 41 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 42 2 2 0 2 0 1 0 0 2 1 0 2 1 1 2 1 2 1 1 1 0 0 2 1 0 2 2 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 43 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 44 2 0 1 1 2 2 1 1 0 0 1 0 1 0 2 2 0 1 1 0 2 1 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 45 1 0 0 1 1 2 0 1 2 2 0 1 2 0 1 1 2 2 2 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 46 2 0 1 2 2 1 0 1 0 2 1 0 0 1 2 2 0 2 0 1 1 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 47 1 2 2 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 48 2 0 1 2 1 0 2 0 2 0 2 2 0 2 1 0 0 1 1 1 1 2 1 0 2 0 2 2 0 1 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 49 1 1 0 0 1 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 50 2 2 1 0 0 1 0 1 0 1 1 2 2 1 0 2 0 1 1 0 0 1 1 2 0 1 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 51 1 2 2 2 1 0 2 2 2 0 2 0 1 0 0 0 2 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 52 2 0 1 1 1 2 0 1 2 0 0 0 1 0 2 0 2 2 2 1 2 0 2 1 0 0 2 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 53 1 0 2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 54 2 1 1 1 2 0 1 2 0 1 0 1 1 0 0 0 0 1 1 2 1 0 2 2 2 2 0 2 1 1 1 0 2 2 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 55 1 0 0 1 1 2 1 0 1 0 1 2 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 56 2 2 0 0 0 1 0 2 0 0 0 0 2 1 1 0 0 1 2 2 2 2 0 2 2 1 2 2 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 57 1 1 2 2 2 2 1 0 1 1 0 2 1 0 2 2 2 1 0 2 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 59 1 2 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 60 2 0 2 2 2 1 2 0 2 0 1 2 0 0 1 2 2 0 0 0 1 1 2 0 2 0 2 2 2 0 1 0 1 2 1 1 2 0 2 2 1 2 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 61 1 2 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 65 1 1 0 2 2 0 0 2 2 1 1 2 2 0 2 2 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 66 2 2 2 1 0 2 0 2 1 2 0 2 0 0 2 0 2 2 1 0 0 0 1 0 1 0 1 2 0 1 1 2 1 0 0 1 2 0 1 2 1 2 0 2 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 67 1 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 71 1 2 2 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 72 2 2 0 2 1 1 1 2 1 0 2 1 2 1 0 1 0 2 1 1 0 2 1 2 1 2 0 2 0 1 1 1 2 2 1 0 2 2 1 1 0 0 1 2 0 1 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 73 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 77 1 2 1 1 0 1 2 2 2 0 0 2 2 0 0 1 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 79 1 2 1 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 83 1 2 2 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 85 1 0 1 1 0 1 2 1 1 0 0 0 0 1 2 2 2 2 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 89 1 0 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 91 1 1 2 1 2 1 1 0 1 2 2 0 0 2 2 2 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 97 1 2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 101 1 0 2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 103 1 1 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 107 1 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 109 1 0 1 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 113 1 2 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 121 1 2 1 2 2 1 1 0 2 2 0 1 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 127 1 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 131 1 0 1 2 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 137 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 139 1 1 2 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 149 1 2 2 1 1 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 151 1 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 157 1 2 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 163 1 0 1 2 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 167 1 1 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 169 1 2 0 0 2 1 0 0 0 2 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 173 1 1 1 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 179 1 2 0 1 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 181 1 1 2 0 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 191 1 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 193 1 2 0 2 1 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 197 1 1 1 2 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 199 1 0 0 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 211 1 2 1 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 223 1 2 2 1 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 227 1 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 229 1 0 2 1 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 233 1 2 2 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 239 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 241 1 1 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 251 1 2 0 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 257 1 0 2 1 0 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +3 263 1 1 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 1 3 1 +5 2 2 4 1 +5 3 3 3 0 1 +5 4 2 4 4 0 1 +5 5 3 4 0 0 0 1 +5 6 2 0 1 4 1 0 1 +5 7 3 3 0 0 0 0 0 1 +5 8 2 4 3 0 1 0 0 0 1 +5 9 3 1 0 2 0 0 0 0 0 1 +5 10 2 1 4 2 3 3 0 0 0 0 1 +5 11 3 3 0 0 0 0 0 0 0 0 0 1 +5 12 2 2 3 4 4 0 1 1 0 0 0 0 1 +5 13 3 3 4 0 0 0 0 0 0 0 0 0 0 1 +5 14 2 1 0 3 2 4 4 0 1 0 0 0 0 0 1 +5 15 3 4 3 3 0 2 0 0 0 0 0 0 0 0 0 1 +5 16 2 1 4 4 2 4 4 4 1 0 0 0 0 0 0 0 1 +5 17 3 2 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 18 2 0 2 2 0 1 2 0 2 1 1 1 1 0 0 0 0 0 1 +5 19 3 2 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 20 2 1 0 4 0 0 3 0 2 3 4 0 3 0 0 0 0 0 0 0 1 +5 21 3 2 2 1 2 2 2 4 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 22 2 3 3 4 0 2 2 0 3 4 0 3 1 0 0 0 0 0 0 0 0 0 1 +5 23 3 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 24 2 1 3 3 2 0 4 2 4 0 3 1 2 4 0 4 2 0 0 0 0 0 0 0 1 +5 25 3 4 2 4 0 1 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 26 2 3 4 3 1 1 3 3 2 1 4 0 2 2 0 4 0 0 0 0 0 0 0 0 0 0 1 +5 27 3 3 0 4 3 2 0 3 0 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 28 2 4 2 3 0 2 0 2 3 2 4 2 2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 29 3 1 3 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 30 2 1 1 0 1 4 3 4 2 2 0 2 3 4 4 0 4 4 0 3 0 4 0 0 0 0 0 0 0 0 1 +5 31 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 33 3 0 1 3 3 0 3 2 4 1 3 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 35 3 2 0 2 1 3 2 0 0 4 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 36 2 1 3 1 0 4 0 2 2 0 3 0 4 1 2 3 3 1 0 2 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 1 +5 37 3 3 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 39 3 2 1 0 2 3 0 4 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 41 3 0 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 42 2 1 2 0 2 3 3 0 1 4 2 4 2 4 2 3 3 0 0 3 0 1 0 3 3 4 0 4 0 2 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 43 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 47 3 0 4 1 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 49 3 2 2 4 0 1 0 1 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 53 3 1 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 55 3 0 4 0 0 2 1 2 2 3 1 3 4 1 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 59 3 1 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 61 3 4 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 67 3 1 0 3 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 71 3 3 3 3 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 73 3 2 4 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 79 3 2 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 83 3 1 3 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 89 3 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 97 3 2 4 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 101 3 4 4 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 103 3 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 107 3 1 3 4 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 109 3 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 113 3 0 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 121 3 2 2 2 3 1 4 3 2 3 1 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 127 3 1 3 1 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 131 3 4 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 137 3 2 2 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 139 3 1 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 149 3 4 1 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 151 3 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 157 3 3 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 163 3 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 167 3 3 2 4 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 173 3 3 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 179 3 2 4 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 181 3 3 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 191 3 4 3 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 193 3 4 2 4 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 197 3 4 1 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 199 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 211 3 0 3 2 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 223 3 4 2 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 227 3 1 3 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 229 3 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 233 3 4 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 239 3 1 4 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 241 3 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +5 251 3 1 4 3 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 1 4 1 +7 2 3 6 1 +7 3 4 0 6 1 +7 4 3 4 5 0 1 +7 5 4 1 0 0 0 1 +7 6 3 6 4 5 1 0 1 +7 7 4 6 0 0 0 0 0 1 +7 8 3 2 6 4 0 0 0 0 1 +7 9 4 6 0 1 6 0 0 0 0 1 +7 10 3 3 2 1 4 1 1 0 0 0 1 +7 11 4 1 0 0 0 0 0 0 0 0 0 1 +7 12 3 0 5 0 4 2 3 5 2 0 0 0 1 +7 13 4 0 6 0 0 0 0 0 0 0 0 0 0 1 +7 14 3 6 3 0 2 6 0 5 0 0 0 0 0 0 1 +7 15 4 2 1 4 6 6 5 0 0 0 0 0 0 0 0 1 +7 16 3 4 2 6 1 4 3 5 4 0 0 0 0 0 0 0 1 +7 17 4 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 18 3 2 6 0 0 3 1 5 6 1 6 2 1 0 0 0 0 0 1 +7 19 4 0 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 20 3 1 0 3 0 3 1 3 2 5 2 6 1 0 0 0 0 0 0 0 1 +7 21 4 4 0 6 0 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 22 3 4 5 5 6 4 3 2 5 3 5 6 1 0 0 0 0 0 0 0 0 0 1 +7 23 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 24 3 3 4 6 2 2 5 4 3 0 1 2 1 5 5 6 0 0 0 0 0 0 0 0 1 +7 25 4 2 1 0 5 0 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 26 3 5 5 0 2 0 1 4 6 1 6 3 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 27 4 0 5 5 4 2 6 4 5 1 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 28 3 1 0 5 1 3 6 4 2 2 6 2 6 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 29 4 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 30 3 2 5 1 0 3 2 4 2 3 3 2 5 6 3 2 1 0 4 1 4 4 1 0 0 0 0 0 0 0 1 +7 31 4 0 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 35 4 4 0 3 1 3 5 5 6 5 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 36 3 1 1 3 3 6 0 6 3 3 6 2 3 3 0 4 1 6 6 2 2 5 4 3 1 0 0 0 0 0 0 0 0 0 0 0 1 +7 37 4 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 41 4 1 4 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 42 3 5 2 3 0 1 0 3 1 6 0 5 1 0 2 5 2 4 3 2 6 6 2 4 1 5 0 6 1 3 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 43 4 2 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 47 4 3 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 49 4 1 2 1 5 4 3 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 53 4 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 59 4 3 6 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 61 4 5 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 67 4 4 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 71 4 1 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 73 4 2 6 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 79 4 2 5 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 83 4 6 6 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 89 4 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 97 4 5 6 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 101 4 4 1 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 103 4 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 107 4 4 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 109 4 1 0 0 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 113 4 5 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 127 4 0 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 131 4 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 137 4 2 3 0 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 139 4 4 6 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 149 4 1 6 2 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 151 4 5 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 157 4 0 1 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 163 4 2 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 167 4 1 5 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 173 4 2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 179 4 3 1 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 181 4 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 191 4 2 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 193 4 4 6 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 197 4 4 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 199 4 4 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 223 4 4 5 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 227 4 6 5 3 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 229 4 3 1 4 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 241 4 3 2 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +7 251 4 3 4 0 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +11 1 9 1 +11 2 2 7 1 +11 3 9 2 0 1 +11 4 2 10 8 0 1 +11 5 9 0 10 0 0 1 +11 6 2 7 6 4 3 0 1 +11 7 9 4 0 0 0 0 0 1 +11 8 2 7 1 7 7 0 0 0 1 +11 9 9 8 9 0 0 0 0 0 0 1 +11 10 2 6 6 10 8 7 0 0 0 0 1 +11 11 9 10 0 0 0 0 0 0 0 0 0 1 +11 12 2 5 6 5 5 2 4 1 1 0 0 0 1 +11 13 9 7 0 0 0 0 0 0 0 0 0 0 0 1 +11 14 2 10 6 8 4 6 9 2 0 0 0 0 0 0 1 +11 15 9 0 0 5 0 7 10 0 0 0 0 0 0 0 0 1 +11 16 2 9 10 3 5 3 1 10 1 0 0 0 0 0 0 0 1 +11 17 9 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +11 18 2 2 8 9 3 0 1 9 3 8 10 8 3 0 0 0 0 0 1 +11 19 9 2 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +11 20 2 5 6 5 5 4 2 7 5 1 9 10 1 0 0 0 0 0 0 0 1 +11 21 9 2 10 7 10 1 7 6 9 0 0 0 0 0 0 0 0 0 0 0 0 1 +11 22 2 4 3 6 10 10 8 4 10 4 1 10 1 0 0 0 0 0 0 0 0 0 1 +11 23 9 1 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +11 24 2 9 6 5 5 1 4 7 2 5 1 9 9 3 0 9 0 0 0 0 0 0 0 0 1 +11 25 9 4 10 0 4 9 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +11 27 9 5 8 3 5 7 8 5 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +11 29 9 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +11 30 2 3 3 0 8 10 2 1 6 0 6 9 1 10 5 0 7 8 8 2 0 10 0 0 0 0 0 0 0 0 1 +11 31 9 6 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +11 35 9 3 9 8 6 9 3 2 4 4 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +11 37 9 4 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +11 41 9 6 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +11 43 9 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +11 47 9 7 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +11 49 9 0 8 5 7 6 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +11 53 9 1 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +11 59 9 3 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +11 61 9 7 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +11 67 9 10 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +11 71 9 10 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +11 73 9 7 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +11 79 9 9 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +11 83 9 1 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +11 89 9 1 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +11 97 9 3 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +11 101 9 5 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +11 103 9 1 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +11 107 9 10 6 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +11 109 9 4 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +11 113 9 5 10 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +11 127 9 7 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +11 131 9 8 10 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +11 137 9 2 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +11 139 9 4 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +11 149 9 6 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +11 151 9 10 10 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +11 157 9 0 8 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +11 163 9 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +11 167 9 10 4 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +11 173 9 8 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +11 179 9 2 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +11 181 9 3 9 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +11 191 9 0 8 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +11 193 9 4 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +11 197 9 0 10 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +11 211 9 5 4 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +11 223 9 3 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +13 1 11 1 +13 2 2 12 1 +13 3 11 2 0 1 +13 4 2 12 3 0 1 +13 5 11 4 0 0 0 1 +13 6 2 11 11 10 0 0 1 +13 7 11 3 0 0 0 0 0 1 +13 8 2 3 2 12 8 0 0 0 1 +13 9 11 12 12 8 12 0 0 0 0 1 +13 10 2 1 1 8 5 7 0 0 0 0 1 +13 11 11 3 0 0 0 0 0 0 0 0 0 1 +13 12 2 4 1 1 3 11 8 5 1 0 0 0 1 +13 13 11 12 0 0 0 0 0 0 0 0 0 0 0 1 +13 14 2 10 10 7 11 6 0 4 0 0 0 0 0 0 1 +13 15 11 8 11 10 11 2 12 2 0 0 0 0 0 0 0 1 +13 16 2 6 12 9 12 2 8 12 3 0 0 0 0 0 0 0 1 +13 17 11 6 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +13 18 2 9 0 6 5 3 5 9 11 11 4 10 0 0 0 0 0 0 1 +13 19 11 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +13 20 2 11 8 4 0 4 7 8 7 0 9 12 1 0 0 0 0 0 0 0 1 +13 21 11 7 12 11 0 4 0 2 9 1 0 0 0 0 0 0 0 0 0 0 0 1 +13 23 11 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +13 24 2 1 10 0 3 0 9 1 1 0 9 0 5 0 0 4 0 0 0 0 0 0 0 0 1 +13 25 11 1 0 5 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +13 27 11 8 7 9 6 7 5 3 5 0 12 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +13 29 11 4 11 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +13 30 2 0 2 4 4 4 5 4 12 4 9 5 4 6 7 11 3 11 10 1 0 0 2 0 0 0 0 0 0 0 1 +13 31 11 2 11 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +13 37 11 12 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +13 41 11 5 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +13 43 11 8 12 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +13 47 11 6 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +13 49 11 7 3 5 3 4 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +13 53 11 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +13 59 11 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +13 61 11 8 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +13 67 11 6 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +13 71 11 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +13 73 11 7 8 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +13 79 11 9 10 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +13 83 11 0 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +13 89 11 7 11 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +13 97 11 4 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +13 101 11 5 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +13 103 11 3 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +13 107 11 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +13 109 11 3 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +13 113 11 12 10 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +13 127 11 7 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +13 131 11 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +13 137 11 11 12 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +13 139 11 10 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +13 149 11 11 12 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +13 151 11 12 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +13 157 11 6 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +13 163 11 12 8 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +13 173 11 2 6 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +13 179 11 6 4 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +13 191 11 7 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +17 1 14 1 +17 2 3 16 1 +17 3 14 1 0 1 +17 4 3 10 7 0 1 +17 5 14 1 0 0 0 1 +17 6 3 3 10 0 2 0 1 +17 7 14 12 0 0 0 0 0 1 +17 8 3 6 0 12 11 0 0 0 1 +17 9 14 8 7 0 0 0 0 0 0 1 +17 10 3 12 9 5 6 13 0 0 0 0 1 +17 11 14 5 0 0 0 0 0 0 0 0 0 1 +17 12 3 9 14 6 13 14 14 4 1 0 0 0 1 +17 13 14 15 0 0 0 0 0 0 0 0 0 0 0 1 +17 14 3 3 9 13 16 8 1 11 1 0 0 0 0 0 1 +17 15 14 14 14 6 16 4 4 0 0 0 0 0 0 0 0 1 +17 16 3 1 12 13 12 2 5 13 1 0 0 0 0 0 0 0 1 +17 17 14 16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +17 18 3 9 13 13 11 9 0 1 7 16 9 0 1 0 0 0 0 0 1 +17 19 14 11 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +17 20 3 5 2 13 1 9 14 3 13 14 16 5 1 0 0 0 0 0 0 0 1 +17 21 14 3 6 6 0 16 12 9 10 1 0 0 0 0 0 0 0 0 0 0 0 1 +17 23 14 16 15 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +17 24 3 14 14 6 6 14 7 15 8 2 3 2 2 6 6 3 1 0 0 0 0 0 0 0 1 +17 25 14 9 6 13 15 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +17 27 14 4 6 7 6 10 7 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +17 29 14 11 16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +17 30 3 14 8 0 6 12 5 12 15 1 8 16 15 14 8 13 13 3 12 0 9 14 0 0 0 0 0 0 0 0 1 +17 31 14 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +17 37 14 16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +17 41 14 1 15 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +17 43 14 11 13 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +17 47 14 8 16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +17 49 14 13 14 15 1 7 9 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +17 53 14 2 12 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +17 59 14 1 15 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +17 61 14 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +17 67 14 11 16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +17 71 14 15 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +17 73 14 14 14 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +17 79 14 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +17 83 14 16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +17 89 14 3 11 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +17 97 14 10 15 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +17 101 14 14 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +17 103 14 16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +17 107 14 8 15 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +17 113 14 15 16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +17 127 14 9 15 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +17 131 14 9 13 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +17 157 14 16 13 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +17 163 14 3 11 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +17 179 14 5 16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +17 191 14 7 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +19 1 17 1 +19 2 2 18 1 +19 3 17 4 0 1 +19 4 2 11 2 0 1 +19 5 17 5 0 0 0 1 +19 6 2 6 17 17 0 0 1 +19 7 17 6 0 0 0 0 0 1 +19 8 2 3 10 12 1 0 0 0 1 +19 9 17 16 14 11 0 0 0 0 0 1 +19 10 2 4 3 17 13 18 0 0 0 0 1 +19 11 17 8 0 0 0 0 0 0 0 0 0 1 +19 12 2 7 16 9 2 18 2 3 0 0 0 0 1 +19 13 17 11 0 0 0 0 0 0 0 0 0 0 0 1 +19 14 2 7 16 5 1 11 11 11 0 0 0 0 0 0 1 +19 15 17 0 14 15 13 11 10 1 0 0 0 0 0 0 0 1 +19 16 2 14 6 9 15 0 13 12 0 0 0 0 0 0 0 0 1 +19 17 17 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +19 18 2 14 3 7 5 16 0 5 17 7 9 10 0 0 0 0 0 0 1 +19 19 17 18 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +19 20 2 11 6 3 0 6 8 7 4 0 13 16 0 0 0 0 0 0 0 0 1 +19 21 17 16 12 7 10 1 12 15 12 1 0 0 0 0 0 0 0 0 0 0 0 1 +19 23 17 13 18 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +19 24 2 8 17 8 5 12 6 0 9 15 15 6 14 0 4 6 0 0 0 0 0 0 0 0 1 +19 25 17 12 1 14 8 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +19 29 17 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +19 30 2 14 14 16 6 16 14 14 13 2 9 5 4 13 0 18 0 16 11 10 15 13 1 0 0 0 0 0 0 0 1 +19 31 17 5 17 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +19 37 17 1 18 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +19 41 17 1 18 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +19 43 17 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +19 47 17 6 18 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +19 49 17 11 0 15 7 11 10 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +19 53 17 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +19 59 17 0 12 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +19 61 17 16 18 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +19 67 17 0 17 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +19 71 17 14 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +19 73 17 2 17 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +19 79 17 7 18 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +19 83 17 11 14 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +19 89 17 4 18 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +19 97 17 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +19 101 17 2 14 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +19 103 17 3 18 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +19 107 17 8 15 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +19 109 17 6 18 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +19 113 17 18 13 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +19 127 17 7 18 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +19 131 17 1 16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +19 137 17 3 16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +19 139 17 11 18 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +19 149 17 4 17 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +19 151 17 4 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +19 157 17 14 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +19 167 17 14 16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +19 181 17 1 15 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +19 199 17 9 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +23 1 18 1 +23 2 5 21 1 +23 3 18 2 0 1 +23 4 5 19 3 0 1 +23 5 18 3 0 0 0 1 +23 6 5 1 9 9 1 0 1 +23 7 18 21 0 0 0 0 0 1 +23 8 5 3 5 20 3 0 0 0 1 +23 9 18 9 8 3 0 0 0 0 0 1 +23 10 5 1 6 15 5 17 0 0 0 0 1 +23 11 18 7 22 0 0 0 0 0 0 0 0 1 +23 12 5 12 18 12 14 15 21 21 0 0 0 0 1 +23 13 18 9 0 0 0 0 0 0 0 0 0 0 0 1 +23 14 5 22 1 19 18 1 16 5 1 0 0 0 0 0 1 +23 15 18 18 7 9 15 8 2 0 0 0 0 0 0 0 0 1 +23 16 5 17 14 1 13 16 19 19 0 0 0 0 0 0 0 0 1 +23 17 18 20 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +23 18 5 19 3 11 0 21 16 3 18 1 2 18 1 0 0 0 0 0 1 +23 19 18 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +23 23 18 22 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +23 25 18 4 13 5 11 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +23 29 18 5 21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +23 31 18 13 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +23 37 18 3 22 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +23 41 18 7 22 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +23 43 18 6 22 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +23 47 18 2 15 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +23 53 18 6 22 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +23 59 18 1 19 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +23 61 18 17 22 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +23 67 18 7 22 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +23 71 18 14 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +23 73 18 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +23 79 18 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +23 83 18 17 22 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +23 89 18 3 22 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +23 97 18 22 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +23 103 18 18 21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +23 107 18 7 22 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +23 127 18 12 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +23 137 18 10 19 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +23 151 18 3 19 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +23 163 18 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +23 179 18 5 13 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +29 1 27 1 +29 2 2 24 1 +29 3 27 2 0 1 +29 4 2 15 2 0 1 +29 5 27 3 0 0 0 1 +29 6 2 13 17 25 1 0 1 +29 7 27 2 0 0 0 0 0 1 +29 8 2 23 26 24 3 0 0 0 1 +29 9 27 22 22 4 0 0 0 0 0 1 +29 10 2 22 2 17 8 25 1 0 0 0 1 +29 11 27 8 28 0 0 0 0 0 0 0 0 1 +29 12 2 1 1 25 16 9 28 19 3 0 0 0 1 +29 13 27 7 0 0 0 0 0 0 0 0 0 0 0 1 +29 14 2 5 27 18 21 10 14 3 1 0 0 0 0 0 1 +29 15 27 26 12 1 8 14 13 0 0 0 0 0 0 0 0 1 +29 16 2 10 27 1 23 18 2 27 6 0 0 0 0 0 0 0 1 +29 17 27 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +29 18 2 14 19 16 8 10 2 26 6 1 1 24 0 0 0 0 0 0 1 +29 19 27 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +29 23 27 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +29 25 27 0 21 9 28 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +29 29 27 28 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +29 31 27 13 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +29 37 27 21 27 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +29 41 27 5 23 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +29 43 27 15 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +29 47 27 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +29 53 27 27 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +29 59 27 6 27 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +29 61 27 23 27 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +29 67 27 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +29 71 27 19 27 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +29 73 27 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +29 79 27 23 25 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +29 83 27 20 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +29 89 27 28 21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +29 97 27 20 25 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +29 103 27 21 28 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +29 107 27 14 27 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +29 109 27 24 26 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +29 131 27 5 13 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +29 137 27 24 23 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +29 139 27 22 26 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +29 151 27 13 24 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +29 157 27 4 27 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +31 1 28 1 +31 2 3 29 1 +31 3 28 1 0 1 +31 4 3 16 3 0 1 +31 5 28 7 0 0 0 1 +31 6 3 8 16 19 0 0 1 +31 7 28 1 0 0 0 0 0 1 +31 8 3 24 12 25 0 0 0 0 1 +31 9 28 29 20 4 0 0 0 0 0 1 +31 10 3 13 13 13 26 30 0 0 0 0 1 +31 11 28 20 0 0 0 0 0 0 0 0 0 1 +31 12 3 12 25 9 2 28 14 4 0 0 0 0 1 +31 13 28 6 0 0 0 0 0 0 0 0 0 0 0 1 +31 14 3 6 18 18 1 1 5 10 0 0 0 0 0 0 1 +31 15 28 25 23 13 12 29 30 0 0 0 0 0 0 0 0 1 +31 16 3 27 19 11 28 26 24 28 0 0 0 0 0 0 0 0 1 +31 17 28 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +31 18 3 6 10 25 25 11 12 7 2 24 5 27 1 0 0 0 0 0 1 +31 19 28 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +31 23 28 26 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +31 25 28 15 0 17 18 3 30 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +31 29 28 11 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +31 31 28 30 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +31 37 28 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +31 41 28 1 30 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +31 43 28 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +31 47 28 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +31 53 28 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +31 59 28 26 29 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +31 61 28 6 30 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +31 67 28 13 29 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +31 71 28 28 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +31 73 28 26 28 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +31 79 28 15 29 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +31 83 28 11 30 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +31 89 28 26 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +31 101 28 30 30 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +31 103 28 21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +31 107 28 15 26 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +31 109 28 16 28 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +31 113 28 25 28 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +31 137 28 17 29 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +31 139 28 1 24 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +37 1 35 1 +37 2 2 33 1 +37 3 35 6 0 1 +37 4 2 24 6 0 1 +37 5 35 10 0 0 0 1 +37 6 2 30 4 35 0 0 1 +37 7 35 7 0 0 0 0 0 1 +37 8 2 1 27 20 7 0 0 0 1 +37 9 35 32 20 6 0 0 0 0 0 1 +37 10 2 4 11 18 29 8 0 0 0 0 1 +37 11 35 2 0 0 0 0 0 0 0 0 0 1 +37 12 2 33 18 23 23 10 31 4 0 0 0 0 1 +37 13 35 6 0 0 0 0 0 0 0 0 0 0 0 1 +37 14 2 9 1 16 32 1 35 35 4 0 0 0 0 0 1 +37 15 35 33 34 13 27 28 31 1 0 0 0 0 0 0 0 1 +37 17 35 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +37 18 2 20 27 14 32 12 20 22 1 15 19 8 1 0 0 0 0 0 1 +37 19 35 23 36 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +37 23 35 22 36 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +37 25 35 10 24 33 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +37 29 35 13 36 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +37 31 35 33 35 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +37 37 35 36 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +37 41 35 22 36 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +37 43 35 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +37 47 35 15 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +37 49 35 25 0 35 23 11 34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +37 53 35 27 35 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +37 59 35 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +37 61 35 29 34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +37 67 35 16 36 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +37 71 35 2 32 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +37 73 35 7 33 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +37 79 35 23 32 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +37 83 35 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +37 97 35 29 34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +37 107 35 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +37 151 35 17 32 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +37 157 35 1 34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +41 1 35 1 +41 2 6 38 1 +41 3 35 1 0 1 +41 4 6 23 0 0 1 +41 5 35 14 40 0 0 1 +41 6 6 6 39 33 4 0 1 +41 7 35 6 0 0 0 0 0 1 +41 8 6 6 20 32 5 0 0 0 1 +41 9 35 5 31 4 0 0 0 0 0 1 +41 10 6 30 20 8 31 3 0 0 0 0 1 +41 11 35 20 0 0 0 0 0 0 0 0 0 1 +41 12 6 27 21 24 34 13 26 0 0 0 0 0 1 +41 13 35 13 0 0 0 0 0 0 0 0 0 0 0 1 +41 14 6 10 39 11 27 4 15 12 0 0 0 0 0 0 1 +41 15 35 21 10 35 2 16 29 0 0 0 0 0 0 0 0 1 +41 17 35 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +41 18 6 6 10 29 12 24 38 35 23 20 7 1 0 0 0 0 0 0 1 +41 19 35 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +41 23 35 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +41 25 35 38 21 27 40 0 40 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +41 29 35 13 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +41 31 35 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +41 37 35 30 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +41 41 35 40 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +41 43 35 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +41 47 35 38 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +41 53 35 21 40 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +41 59 35 12 40 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +41 61 35 11 40 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +41 67 35 35 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +41 71 35 2 39 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +41 73 35 12 40 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +41 79 35 35 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +41 83 35 11 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +41 89 35 4 37 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +41 97 35 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +41 113 35 0 39 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +41 149 35 15 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +41 151 35 25 35 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +41 157 35 8 40 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +43 1 40 1 +43 2 3 42 1 +43 3 40 1 0 1 +43 4 3 42 5 0 1 +43 5 40 8 0 0 0 1 +43 6 3 21 28 19 0 0 1 +43 7 40 7 42 0 0 0 0 1 +43 8 3 24 20 39 1 0 0 0 1 +43 9 40 1 39 12 0 0 0 0 0 1 +43 10 3 24 27 5 36 26 3 0 0 0 1 +43 11 40 7 0 0 0 0 0 0 0 0 0 1 +43 12 3 38 23 6 17 16 27 34 0 0 0 0 1 +43 13 40 4 0 0 0 0 0 0 0 0 0 0 0 1 +43 14 3 19 4 18 37 24 22 38 0 0 0 0 0 0 1 +43 15 40 37 15 4 42 22 37 2 0 0 0 0 0 0 0 1 +43 17 40 36 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +43 18 3 18 37 34 16 29 24 7 24 41 28 3 1 0 0 0 0 0 1 +43 19 40 30 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +43 23 40 27 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +43 25 40 2 25 19 13 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +43 29 40 8 42 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +43 31 40 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +43 37 40 13 42 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +43 41 40 17 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +43 43 40 42 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +43 47 40 29 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +43 53 40 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +43 59 40 24 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +43 61 40 40 40 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +43 67 40 27 36 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +43 71 40 34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +43 73 40 13 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +43 79 40 14 40 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +43 83 40 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +43 89 40 41 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +43 97 40 24 40 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +43 107 40 21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +43 109 40 25 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +43 131 40 18 37 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +47 1 42 1 +47 2 5 45 1 +47 3 42 3 0 1 +47 4 5 40 8 0 1 +47 5 42 1 0 0 0 1 +47 6 5 41 9 35 2 0 1 +47 7 42 12 0 0 0 0 0 1 +47 8 5 3 19 29 1 0 0 0 1 +47 9 42 1 19 1 0 0 0 0 0 1 +47 10 5 45 45 18 14 42 1 0 0 0 1 +47 11 42 6 0 0 0 0 0 0 0 0 0 1 +47 12 5 9 14 46 12 35 40 46 0 0 0 0 1 +47 13 42 5 0 0 0 0 0 0 0 0 0 0 0 1 +47 14 5 32 9 24 17 30 20 36 0 0 0 0 0 0 1 +47 15 42 17 13 42 14 31 43 0 0 0 0 0 0 0 0 1 +47 17 42 16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +47 18 5 33 45 5 11 22 24 44 26 42 41 6 0 0 0 0 0 0 1 +47 19 42 35 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +47 23 42 14 46 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +47 25 42 27 43 12 46 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +47 29 42 15 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +47 31 42 10 46 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +47 37 42 34 45 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +47 41 42 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +47 43 42 30 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +47 47 42 46 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +47 53 42 17 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +47 59 42 18 46 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +47 61 42 37 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +47 67 42 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +47 71 42 40 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +47 73 42 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +47 79 42 20 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +47 83 42 30 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +47 97 42 26 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +47 101 42 22 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +47 107 42 16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +47 127 42 41 46 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +53 1 51 1 +53 2 2 49 1 +53 3 51 3 0 1 +53 4 2 38 9 0 1 +53 5 51 3 0 0 0 1 +53 6 2 45 4 7 1 0 1 +53 7 51 9 0 0 0 0 0 1 +53 8 2 1 18 29 8 0 0 0 1 +53 9 51 5 13 0 0 0 0 0 0 1 +53 10 2 29 15 27 1 0 1 0 0 0 1 +53 11 51 15 0 0 0 0 0 0 0 0 0 1 +53 12 2 41 34 42 10 13 4 34 2 0 0 0 1 +53 13 51 28 52 0 0 0 0 0 0 0 0 0 0 1 +53 14 2 23 12 37 0 52 23 45 1 0 0 0 0 0 1 +53 15 51 4 20 11 15 31 22 0 0 0 0 0 0 0 0 1 +53 17 51 12 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +53 18 2 11 16 8 6 44 39 0 27 51 31 52 0 0 0 0 0 0 1 +53 19 51 11 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +53 23 51 27 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +53 25 51 11 27 21 12 12 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +53 29 51 20 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +53 31 51 33 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +53 37 51 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +53 41 51 50 52 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +53 43 51 46 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +53 47 51 15 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +53 53 51 52 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +53 59 51 23 51 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +53 61 51 36 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +53 67 51 28 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +53 71 51 24 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +53 73 51 11 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +53 79 51 26 50 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +53 83 51 38 40 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +53 97 51 15 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +53 101 51 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +53 107 51 49 48 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +53 113 51 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +53 127 51 25 52 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +59 1 57 1 +59 2 2 58 1 +59 3 57 5 0 1 +59 4 2 40 2 0 1 +59 5 57 8 0 0 0 1 +59 6 2 0 38 18 2 0 1 +59 7 57 10 0 0 0 0 0 1 +59 8 2 50 2 32 16 0 0 0 1 +59 9 57 47 32 1 0 0 0 0 0 1 +59 10 2 15 39 4 25 28 1 0 0 0 1 +59 11 57 6 0 0 0 0 0 0 0 0 0 1 +59 12 2 1 8 38 21 51 25 39 0 0 0 0 1 +59 13 57 3 0 0 0 0 0 0 0 0 0 0 0 1 +59 14 2 26 32 25 13 11 51 33 1 0 0 0 0 0 1 +59 15 57 58 39 13 23 24 57 0 0 0 0 0 0 0 0 1 +59 17 57 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +59 18 2 32 34 47 16 44 7 14 11 27 38 37 1 0 0 0 0 0 1 +59 19 57 11 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +59 23 57 35 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +59 25 57 6 45 56 33 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +59 29 57 9 58 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +59 31 57 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +59 37 57 22 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +59 41 57 23 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +59 43 57 36 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +59 47 57 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +59 53 57 14 58 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +59 59 57 58 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +59 61 57 36 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +59 67 57 49 57 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +59 71 57 22 58 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +59 73 57 20 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +59 79 57 22 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +59 83 57 47 57 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +59 89 57 15 58 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +59 107 57 34 57 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +61 1 59 1 +61 2 2 60 1 +61 3 59 7 0 1 +61 4 2 40 3 0 1 +61 5 59 12 0 0 0 1 +61 6 2 29 3 49 0 0 1 +61 7 59 2 0 0 0 0 0 1 +61 8 2 56 1 57 0 0 0 0 1 +61 9 59 18 50 9 0 0 0 0 0 1 +61 10 2 6 16 44 15 28 0 0 0 0 1 +61 11 59 18 0 0 0 0 0 0 0 0 0 1 +61 12 2 15 1 14 38 8 33 42 2 0 0 0 1 +61 13 59 3 0 0 0 0 0 0 0 0 0 0 0 1 +61 14 2 48 54 30 8 11 26 48 1 0 0 0 0 0 1 +61 15 59 51 23 25 44 35 39 0 0 0 0 0 0 0 0 1 +61 17 59 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +61 18 2 52 25 25 42 57 32 4 36 13 36 35 3 0 0 0 0 0 1 +61 19 59 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +61 23 59 13 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +61 25 59 28 25 43 58 37 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +61 29 59 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +61 31 59 11 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +61 37 59 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +61 41 59 35 60 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +61 43 59 15 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +61 47 59 20 60 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +61 53 59 39 60 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +61 59 59 24 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +61 61 59 60 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +61 67 59 44 60 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +61 71 59 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +61 73 59 51 60 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +61 89 59 31 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +61 101 59 31 58 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +61 107 59 17 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +61 109 59 52 60 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +61 139 59 55 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +67 1 65 1 +67 2 2 63 1 +67 3 65 6 0 1 +67 4 2 54 8 0 1 +67 5 65 2 0 0 0 1 +67 6 2 55 49 63 0 0 1 +67 7 65 7 0 0 0 0 0 1 +67 8 2 64 17 46 3 0 0 0 1 +67 9 65 55 49 25 0 0 0 0 0 1 +67 10 2 23 7 16 0 21 2 0 0 0 1 +67 11 65 9 66 0 0 0 0 0 0 0 0 1 +67 12 2 27 21 64 55 4 27 57 3 0 0 0 1 +67 13 65 22 0 0 0 0 0 0 0 0 0 0 0 1 +67 14 2 37 1 0 56 5 22 17 0 0 0 0 0 0 1 +67 15 65 46 21 20 41 52 1 1 0 0 0 0 0 0 0 1 +67 17 65 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +67 18 2 13 59 6 51 29 28 55 33 18 52 63 1 0 0 0 0 0 1 +67 19 65 18 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +67 23 65 11 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +67 25 65 3 11 51 21 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +67 29 65 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +67 31 65 24 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +67 37 65 54 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +67 41 65 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +67 43 65 17 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +67 47 65 26 66 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +67 53 65 15 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +67 59 65 42 65 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +67 61 65 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +67 67 65 66 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +67 71 65 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +67 73 65 23 66 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +67 79 65 14 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +67 89 65 47 66 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +67 103 65 23 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +71 1 64 1 +71 2 7 69 1 +71 3 64 4 0 1 +71 4 7 41 4 0 1 +71 5 64 18 0 0 0 1 +71 6 7 29 13 10 1 0 1 +71 7 64 2 0 0 0 0 0 1 +71 8 7 19 22 53 0 0 0 0 1 +71 9 64 62 43 4 0 0 0 0 0 1 +71 10 7 40 1 26 17 53 0 0 0 0 1 +71 11 64 48 0 0 0 0 0 0 0 0 0 1 +71 12 7 23 58 21 55 29 28 12 0 0 0 0 1 +71 13 64 27 0 0 0 0 0 0 0 0 0 0 0 1 +71 15 64 49 67 52 18 32 28 0 0 0 0 0 0 0 0 1 +71 17 64 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +71 19 64 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +71 23 64 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +71 25 64 7 30 65 69 24 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +71 29 64 19 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +71 31 64 21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +71 37 64 35 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +71 41 64 33 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +71 43 64 26 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +71 47 64 12 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +71 53 64 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +71 59 64 50 70 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +71 61 64 24 70 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +71 67 64 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +71 71 64 70 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +71 73 64 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +71 79 64 33 70 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +71 83 64 26 70 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +71 97 64 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +71 107 64 48 65 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +71 109 64 6 68 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +71 131 64 8 67 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +73 1 68 1 +73 2 5 70 1 +73 3 68 2 0 1 +73 4 5 56 16 0 1 +73 5 68 9 0 0 0 1 +73 6 5 48 23 45 0 0 1 +73 7 68 10 0 0 0 0 0 1 +73 8 5 18 39 53 3 0 0 0 1 +73 9 68 15 72 0 0 0 0 0 0 1 +73 10 5 69 32 33 23 15 2 0 0 0 1 +73 11 68 5 0 0 0 0 0 0 0 0 0 1 +73 12 5 25 29 46 20 26 52 69 1 0 0 0 1 +73 13 68 7 0 0 0 0 0 0 0 0 0 0 0 1 +73 15 68 62 57 57 33 10 0 0 0 0 0 0 0 0 0 1 +73 17 68 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +73 19 68 25 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +73 23 68 13 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +73 25 68 46 20 21 27 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +73 29 68 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +73 31 68 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +73 37 68 11 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +73 41 68 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +73 43 68 22 71 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +73 47 68 1 71 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +73 53 68 53 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +73 59 68 59 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +73 61 68 19 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +73 67 68 17 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +73 71 68 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +73 73 68 72 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +73 89 68 63 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +73 101 68 40 67 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +73 107 68 64 72 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +79 1 76 1 +79 2 3 78 1 +79 3 76 9 0 1 +79 4 3 66 2 0 1 +79 5 76 5 0 0 0 1 +79 6 3 68 28 19 0 0 1 +79 7 76 4 0 0 0 0 0 1 +79 8 3 48 59 60 0 0 0 0 1 +79 9 76 19 57 0 0 0 0 0 0 1 +79 10 3 42 30 1 51 44 4 0 0 0 1 +79 11 76 3 0 0 0 0 0 0 0 0 0 1 +79 12 3 62 59 40 7 52 45 29 1 0 0 0 1 +79 13 76 4 78 0 0 0 0 0 0 0 0 0 0 1 +79 17 76 25 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +79 19 76 25 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +79 23 76 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +79 25 76 68 67 7 42 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +79 29 76 11 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +79 31 76 52 78 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +79 37 76 44 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +79 41 76 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +79 43 76 13 78 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +79 47 76 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +79 53 76 66 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +79 59 76 13 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +79 61 76 48 77 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +79 67 76 16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +79 71 76 18 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +79 73 76 49 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +79 79 76 78 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +79 83 76 60 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +79 89 76 10 76 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +79 109 76 59 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +83 1 81 1 +83 2 2 82 1 +83 3 81 3 0 1 +83 4 2 42 4 0 1 +83 5 81 9 0 0 0 1 +83 6 2 17 32 76 1 0 1 +83 7 81 3 0 0 0 0 0 1 +83 8 2 42 23 65 1 0 0 0 1 +83 9 81 18 24 1 0 0 0 0 0 1 +83 10 2 53 0 73 0 7 0 0 0 0 1 +83 11 81 17 0 0 0 0 0 0 0 0 0 1 +83 12 2 75 55 65 19 31 12 35 0 0 0 0 1 +83 13 81 15 0 0 0 0 0 0 0 0 0 0 0 1 +83 17 81 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +83 19 81 47 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +83 23 81 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +83 25 81 74 17 3 11 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +83 29 81 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +83 31 81 38 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +83 37 81 32 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +83 41 81 18 82 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +83 43 81 44 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +83 47 81 40 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +83 53 81 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +83 59 81 17 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +83 61 81 63 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +83 67 81 39 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +83 71 81 66 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +83 73 81 16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +83 83 81 82 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +83 89 81 64 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +83 97 81 80 82 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +83 103 81 58 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +83 113 81 21 82 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +89 1 86 1 +89 2 3 82 1 +89 3 86 3 0 1 +89 4 3 72 4 0 1 +89 5 86 1 0 0 0 1 +89 6 3 15 80 82 1 0 1 +89 7 86 7 0 0 0 0 0 1 +89 8 3 79 40 65 0 0 0 0 1 +89 9 86 6 12 5 0 0 0 0 0 1 +89 10 3 4 52 82 33 16 1 0 0 0 1 +89 11 86 26 88 0 0 0 0 0 0 0 0 1 +89 12 3 52 70 8 51 44 15 85 2 0 0 0 1 +89 13 86 17 0 0 0 0 0 0 0 0 0 0 0 1 +89 17 86 20 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +89 19 86 34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +89 23 86 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +89 25 86 18 44 40 84 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +89 29 86 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +89 31 86 24 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +89 37 86 7 88 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +89 41 86 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +89 43 86 71 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +89 47 86 15 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +89 53 86 14 88 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +89 59 86 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +89 61 86 32 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +89 67 86 17 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +89 71 86 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +89 73 86 22 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +89 79 86 11 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +89 89 86 88 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +89 101 86 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +89 107 86 79 87 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +89 109 86 34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +89 113 86 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +97 1 92 1 +97 2 5 96 1 +97 3 92 9 0 1 +97 4 5 80 6 0 1 +97 5 92 3 0 0 0 1 +97 6 5 88 58 92 0 0 1 +97 7 92 5 0 0 0 0 0 1 +97 8 5 32 1 65 0 0 0 0 1 +97 9 92 7 59 12 0 0 0 0 0 1 +97 10 5 20 34 34 66 22 0 0 0 0 1 +97 11 92 5 0 0 0 0 0 0 0 0 0 1 +97 12 5 94 78 86 0 81 59 30 0 0 0 0 1 +97 13 92 3 0 0 0 0 0 0 0 0 0 0 0 1 +97 17 92 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +97 19 92 15 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +97 23 92 35 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +97 25 92 10 73 85 11 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +97 29 92 22 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +97 31 92 59 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +97 37 92 28 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +97 41 92 94 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +97 43 92 0 96 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +97 47 92 66 96 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +97 53 92 24 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +97 59 92 14 95 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +97 61 92 11 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +97 67 92 7 96 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +97 71 92 7 96 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +97 73 92 79 96 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +97 79 92 21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +97 97 92 96 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +97 113 92 93 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +97 127 92 21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +101 1 99 1 +101 2 2 97 1 +101 3 99 3 0 1 +101 4 2 78 1 0 1 +101 5 99 2 0 0 0 1 +101 6 2 67 20 90 2 0 1 +101 7 99 6 0 0 0 0 0 1 +101 8 2 24 29 76 4 0 0 0 1 +101 9 99 47 64 0 0 0 0 0 0 1 +101 10 2 52 100 100 49 67 1 0 0 0 1 +101 11 99 31 0 0 0 0 0 0 0 0 0 1 +101 12 2 21 84 48 78 39 64 79 1 0 0 0 1 +101 13 99 7 0 0 0 0 0 0 0 0 0 0 0 1 +101 17 99 31 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +101 19 99 24 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +101 23 99 38 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +101 25 99 55 72 95 79 87 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +101 29 99 12 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +101 31 99 63 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +101 37 99 66 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +101 41 99 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +101 43 99 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +101 47 99 27 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +103 1 98 1 +103 2 5 102 1 +103 3 98 2 0 1 +103 4 5 88 2 0 1 +103 5 98 11 0 0 0 1 +103 6 5 30 9 96 0 0 1 +103 7 98 5 0 0 0 0 0 1 +103 8 5 49 71 70 1 0 0 0 1 +103 9 98 51 97 0 0 0 0 0 0 1 +103 10 5 11 94 101 86 101 1 0 0 0 1 +103 11 98 5 0 0 0 0 0 0 0 0 0 1 +103 12 5 88 29 81 20 94 23 74 1 0 0 0 1 +103 13 98 5 0 0 0 0 0 0 0 0 0 0 0 1 +103 17 98 8 102 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +103 19 98 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +103 23 98 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +103 25 98 58 7 39 21 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +103 29 98 101 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +103 31 98 16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +103 37 98 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +103 41 98 74 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +103 43 98 16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +103 47 98 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +107 1 105 1 +107 2 2 103 1 +107 3 105 5 0 1 +107 4 2 79 13 0 1 +107 5 105 8 0 0 0 1 +107 6 2 79 22 52 1 0 1 +107 7 105 16 0 0 0 0 0 1 +107 8 2 95 24 105 2 0 0 0 1 +107 9 105 66 3 3 0 0 0 0 0 1 +107 10 2 95 83 83 61 94 2 0 0 0 1 +107 11 105 8 0 0 0 0 0 0 0 0 0 1 +107 12 2 57 42 61 0 6 48 37 0 0 0 0 1 +107 13 105 4 0 0 0 0 0 0 0 0 0 0 0 1 +107 17 105 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +107 19 105 24 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +107 23 105 18 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +107 25 105 15 101 8 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +107 29 105 45 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +107 31 105 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +107 37 105 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +107 41 105 12 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +107 43 105 29 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +107 47 105 34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +109 1 103 1 +109 2 6 108 1 +109 3 103 1 0 1 +109 4 6 98 11 0 1 +109 5 103 4 0 0 0 1 +109 6 6 66 102 107 0 0 1 +109 7 103 14 0 0 0 0 0 1 +109 8 6 86 34 102 1 0 0 0 1 +109 9 103 87 93 0 0 0 0 0 0 1 +109 10 6 69 75 16 55 71 1 0 0 0 1 +109 11 103 11 0 0 0 0 0 0 0 0 0 1 +109 12 6 28 103 65 8 37 53 50 1 0 0 0 1 +109 13 103 1 0 0 0 0 0 0 0 0 0 0 0 1 +109 17 103 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +109 19 103 15 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +109 23 103 23 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +109 25 103 9 94 61 83 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +109 29 103 43 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +109 31 103 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +109 37 103 66 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +109 41 103 24 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +109 43 103 32 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +109 47 103 52 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +113 1 110 1 +113 2 3 101 1 +113 3 110 8 0 1 +113 4 3 62 0 0 1 +113 5 110 7 0 0 0 1 +113 6 3 71 30 59 1 0 1 +113 7 110 5 0 0 0 0 0 1 +113 8 3 28 38 98 3 0 0 0 1 +113 9 110 71 87 0 0 0 0 0 0 1 +113 10 3 56 83 45 57 108 0 0 0 0 1 +113 11 110 3 0 0 0 0 0 0 0 0 0 1 +113 12 3 27 10 56 98 4 62 23 1 0 0 0 1 +113 13 110 4 0 0 0 0 0 0 0 0 0 0 0 1 +113 17 110 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +113 19 110 22 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +113 23 110 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +113 25 110 73 76 59 53 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +113 29 110 52 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +113 31 110 11 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +113 37 110 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +113 41 110 11 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +113 43 110 15 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +113 47 110 16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +127 1 124 1 +127 2 3 126 1 +127 3 124 3 0 1 +127 4 3 97 2 0 1 +127 5 124 7 0 0 0 1 +127 6 3 82 115 84 0 0 1 +127 7 124 15 0 0 0 0 0 1 +127 8 3 8 55 104 3 0 0 0 1 +127 9 124 126 119 14 0 0 0 0 0 1 +127 10 3 4 60 95 64 107 0 0 0 0 1 +127 11 124 11 0 0 0 0 0 0 0 0 0 1 +127 12 3 8 99 15 97 33 25 119 0 0 0 0 1 +127 13 124 8 0 0 0 0 0 0 0 0 0 0 0 1 +127 17 124 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +127 19 124 30 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +127 23 124 25 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +127 25 124 82 71 50 33 16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +127 29 124 15 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +127 31 124 13 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +127 37 124 73 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +127 41 124 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +127 43 124 54 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +127 47 124 60 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +131 1 129 1 +131 2 2 127 1 +131 3 129 3 0 1 +131 4 2 109 9 0 1 +131 5 129 19 0 0 0 1 +131 6 2 22 4 66 2 0 1 +131 7 129 10 0 0 0 0 0 1 +131 8 2 104 116 72 3 0 0 0 1 +131 9 129 19 6 6 0 0 0 0 0 1 +131 10 2 44 126 9 97 124 0 0 0 0 1 +131 11 129 6 0 0 0 0 0 0 0 0 0 1 +131 12 2 103 28 125 83 40 122 50 0 0 0 0 1 +131 13 129 9 0 0 0 0 0 0 0 0 0 0 0 1 +131 17 129 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +131 19 129 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +131 23 129 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +131 25 129 109 130 96 129 25 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +131 29 129 15 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +131 31 129 19 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +131 37 129 11 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +131 41 129 90 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +131 43 129 24 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +131 47 129 12 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +137 1 134 1 +137 2 3 131 1 +137 3 134 6 0 1 +137 4 3 95 1 0 1 +137 5 134 7 0 0 0 1 +137 6 3 3 102 116 1 0 1 +137 7 134 1 0 0 0 0 0 1 +137 8 3 34 21 105 4 0 0 0 1 +137 9 134 122 80 1 0 0 0 0 0 1 +137 10 3 119 93 67 20 0 2 0 0 0 1 +137 11 134 1 0 0 0 0 0 0 0 0 0 1 +137 12 3 61 135 36 12 40 40 61 1 0 0 0 1 +137 13 134 14 0 0 0 0 0 0 0 0 0 0 0 1 +137 17 134 4 136 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +137 19 134 18 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +137 23 134 12 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +137 25 134 130 29 88 129 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +137 29 134 57 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +137 31 134 38 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +137 37 134 21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +137 41 134 39 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +137 43 134 53 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +137 47 134 11 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +139 1 137 1 +139 2 2 138 1 +139 3 137 6 0 1 +139 4 2 96 7 0 1 +139 5 137 10 0 0 0 1 +139 6 2 118 10 46 4 0 1 +139 7 137 9 0 0 0 0 0 1 +139 8 2 21 36 103 4 0 0 0 1 +139 9 137 87 70 3 0 0 0 0 0 1 +139 10 2 106 66 130 48 110 0 0 0 0 1 +139 11 137 7 0 0 0 0 0 0 0 0 0 1 +139 12 2 10 8 106 77 41 75 120 0 0 0 0 1 +139 13 137 22 0 0 0 0 0 0 0 0 0 0 0 1 +139 17 137 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +139 19 137 23 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +139 23 137 12 138 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +139 25 137 70 100 35 105 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +139 29 137 32 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +139 31 137 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +139 37 137 12 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +139 41 137 58 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +139 43 137 75 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +139 47 137 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +149 1 147 1 +149 2 2 145 1 +149 3 147 3 0 1 +149 4 2 107 7 0 1 +149 5 147 2 0 0 0 1 +149 6 2 55 33 105 1 0 1 +149 7 147 19 0 0 0 0 0 1 +149 8 2 123 25 140 2 0 0 0 1 +149 9 147 20 146 0 0 0 0 0 0 1 +149 10 2 51 143 148 42 74 0 0 0 0 1 +149 11 147 33 0 0 0 0 0 0 0 0 0 1 +149 12 2 110 104 9 52 91 121 0 0 0 0 0 1 +149 13 147 4 0 0 0 0 0 0 0 0 0 0 0 1 +149 17 147 29 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +149 19 147 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +149 23 147 65 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +149 25 147 85 5 80 27 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +149 29 147 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +149 31 147 43 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +149 37 147 13 148 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +149 41 147 49 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +149 43 147 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +149 47 147 54 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +151 1 145 1 +151 2 6 149 1 +151 3 145 1 0 1 +151 4 6 89 13 0 1 +151 5 145 11 0 0 0 1 +151 6 6 15 18 125 0 0 1 +151 7 145 9 0 0 0 0 0 1 +151 8 6 43 122 140 9 0 0 0 1 +151 9 145 96 126 6 0 0 0 0 0 1 +151 10 6 142 20 49 104 21 1 0 0 0 1 +151 11 145 1 0 0 0 0 0 0 0 0 0 1 +151 12 6 147 107 77 6 101 121 109 1 0 0 0 1 +151 13 145 12 0 0 0 0 0 0 0 0 0 0 0 1 +151 17 145 24 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +151 19 145 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +151 23 145 11 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +151 29 145 12 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +151 31 145 20 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +151 37 145 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +151 41 145 39 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +151 43 145 22 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +151 47 145 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +157 1 152 1 +157 2 5 152 1 +157 3 152 1 0 1 +157 4 5 136 11 0 1 +157 5 152 7 0 0 0 1 +157 6 5 144 43 130 3 0 1 +157 7 152 14 0 0 0 0 0 1 +157 8 5 153 40 97 3 0 0 0 1 +157 9 152 52 114 2 0 0 0 0 0 1 +157 10 5 93 61 124 22 61 0 0 0 0 1 +157 11 152 29 0 0 0 0 0 0 0 0 0 1 +157 12 5 57 152 43 137 72 110 77 0 0 0 0 1 +157 13 152 9 156 0 0 0 0 0 0 0 0 0 0 1 +157 17 152 12 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +157 19 152 14 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +157 23 152 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +157 25 152 42 56 112 15 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +157 29 152 33 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +157 31 152 116 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +157 37 152 25 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +157 41 152 56 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +157 43 152 15 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +157 47 152 145 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +163 1 161 1 +163 2 2 159 1 +163 3 161 7 0 1 +163 4 2 91 8 0 1 +163 5 161 3 0 0 0 1 +163 6 2 156 25 83 0 0 1 +163 7 161 9 0 0 0 0 0 1 +163 8 2 6 83 132 1 0 0 0 1 +163 9 161 127 162 15 0 0 0 0 0 1 +163 10 2 0 15 125 120 111 3 0 0 0 1 +163 11 161 11 0 0 0 0 0 0 0 0 0 1 +163 12 2 69 10 103 38 31 112 39 0 0 0 0 1 +163 13 161 24 0 0 0 0 0 0 0 0 0 0 0 1 +163 17 161 71 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +163 19 161 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +163 23 161 59 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +163 25 161 95 71 120 45 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +163 29 161 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +163 31 161 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +163 37 161 34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +163 41 161 15 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +163 43 161 28 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +163 47 161 37 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +167 1 162 1 +167 2 5 166 1 +167 3 162 7 0 1 +167 4 5 120 3 0 1 +167 5 162 3 0 0 0 1 +167 6 5 2 38 75 2 0 1 +167 7 162 10 0 0 0 0 0 1 +167 8 5 113 56 149 2 0 0 0 1 +167 9 162 122 165 0 0 0 0 0 0 1 +167 10 5 148 143 109 68 85 0 0 0 0 1 +167 11 162 24 0 0 0 0 0 0 0 0 0 1 +167 12 5 57 41 140 131 142 10 142 0 0 0 0 1 +167 13 162 10 0 0 0 0 0 0 0 0 0 0 0 1 +167 17 162 32 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +167 19 162 14 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +167 23 162 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +167 29 162 48 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +167 31 162 85 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +167 37 162 17 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +167 41 162 14 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +167 43 162 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +167 47 162 54 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +173 1 171 1 +173 2 2 169 1 +173 3 171 2 0 1 +173 4 2 102 1 0 1 +173 5 171 6 0 0 0 1 +173 6 2 107 134 27 1 0 1 +173 7 171 5 0 0 0 0 0 1 +173 8 2 27 158 125 2 0 0 0 1 +173 9 171 104 56 0 0 0 0 0 0 1 +173 10 2 58 106 48 164 156 1 0 0 0 1 +173 11 171 12 0 0 0 0 0 0 0 0 0 1 +173 12 2 22 159 0 166 46 64 29 1 0 0 0 1 +173 13 171 6 0 0 0 0 0 0 0 0 0 0 0 1 +173 17 171 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +173 19 171 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +173 23 171 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +173 29 171 19 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +173 31 171 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +173 37 171 42 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +173 41 171 20 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +173 43 171 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +173 47 171 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +179 1 177 1 +179 2 2 172 1 +179 3 177 4 0 1 +179 4 2 109 1 0 1 +179 5 177 2 0 0 0 1 +179 6 2 109 55 91 7 0 1 +179 7 177 6 0 0 0 0 0 1 +179 8 2 73 144 163 0 0 0 0 1 +179 9 177 64 40 0 0 0 0 0 0 1 +179 10 2 87 49 150 71 115 0 0 0 0 1 +179 11 177 28 0 0 0 0 0 0 0 0 0 1 +179 12 2 1 177 8 76 43 83 103 2 0 0 0 1 +179 13 177 18 0 0 0 0 0 0 0 0 0 0 0 1 +179 17 177 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +179 19 177 11 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +179 23 177 42 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +179 25 177 143 85 31 8 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +179 29 177 35 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +179 31 177 69 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +179 37 177 12 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +179 41 177 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +179 43 177 107 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +179 47 177 45 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +181 1 179 1 +181 2 2 177 1 +181 3 179 6 0 1 +181 4 2 105 6 0 1 +181 5 179 21 0 0 0 1 +181 6 2 169 163 177 0 0 1 +181 7 179 4 0 0 0 0 0 1 +181 8 2 149 22 108 2 0 0 0 1 +181 9 179 168 107 11 0 0 0 0 0 1 +181 10 2 88 57 94 104 154 0 0 0 0 1 +181 11 179 24 0 0 0 0 0 0 0 0 0 1 +181 12 2 10 12 175 122 45 141 171 0 0 0 0 1 +181 13 179 8 0 0 0 0 0 0 0 0 0 0 0 1 +181 17 179 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +181 19 179 36 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +181 23 179 43 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +181 29 179 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +181 31 179 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +181 37 179 19 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +181 41 179 15 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +181 43 179 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +181 47 179 122 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +191 1 172 1 +191 2 19 190 1 +191 3 172 4 0 1 +191 4 19 100 7 0 1 +191 5 172 1 0 0 0 1 +191 6 19 10 10 110 1 0 1 +191 7 172 14 0 0 0 0 0 1 +191 8 19 171 139 164 2 0 0 0 1 +191 9 172 124 62 0 0 0 0 0 0 1 +191 10 19 156 74 173 47 113 0 0 0 0 1 +191 11 172 6 0 0 0 0 0 0 0 0 0 1 +191 12 19 151 7 90 49 25 168 79 0 0 0 0 1 +191 13 172 12 0 0 0 0 0 0 0 0 0 0 0 1 +191 17 172 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +191 19 172 2 190 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +191 23 172 48 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +191 29 172 50 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +191 31 172 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +191 37 172 20 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +191 41 172 70 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +191 43 172 35 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +191 47 172 96 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +193 1 188 1 +193 2 5 192 1 +193 3 188 1 0 1 +193 4 5 148 6 0 1 +193 5 188 7 0 0 0 1 +193 6 5 172 8 149 0 0 1 +193 7 188 8 0 0 0 0 0 1 +193 8 5 154 34 145 10 0 0 0 1 +193 9 188 27 168 8 0 0 0 0 0 1 +193 10 5 89 0 77 51 20 0 0 0 0 1 +193 11 188 1 0 0 0 0 0 0 0 0 0 1 +193 12 5 28 46 90 152 135 52 155 0 0 0 0 1 +193 13 188 39 0 0 0 0 0 0 0 0 0 0 0 1 +193 17 188 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +193 19 188 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +193 23 188 18 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +193 29 188 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +193 31 188 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +193 37 188 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +193 41 188 80 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +193 43 188 11 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +193 47 188 100 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +197 1 195 1 +197 2 2 192 1 +197 3 195 3 0 1 +197 4 2 124 16 0 1 +197 5 195 4 0 0 0 1 +197 6 2 173 79 124 1 0 1 +197 7 195 6 0 0 0 0 0 1 +197 8 2 29 96 176 0 0 0 0 1 +197 9 195 8 127 13 0 0 0 0 0 1 +197 10 2 42 73 8 137 121 0 0 0 0 1 +197 11 195 14 0 0 0 0 0 0 0 0 0 1 +197 12 2 163 90 9 141 130 15 168 0 0 0 0 1 +197 13 195 39 0 0 0 0 0 0 0 0 0 0 0 1 +197 17 195 35 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +197 19 195 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +197 23 195 19 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +197 29 195 52 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +197 31 195 13 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +197 37 195 25 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +197 41 195 75 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +197 43 195 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +197 47 195 23 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +199 1 196 1 +199 2 3 193 1 +199 3 196 1 0 1 +199 4 3 162 7 0 1 +199 5 196 3 0 0 0 1 +199 6 3 79 58 90 0 0 1 +199 7 196 3 0 0 0 0 0 1 +199 8 3 159 23 160 1 0 0 0 1 +199 9 196 141 177 8 0 0 0 0 0 1 +199 10 3 9 54 31 158 171 0 0 0 0 1 +199 11 196 1 0 0 0 0 0 0 0 0 0 1 +199 12 3 151 57 69 138 197 192 33 0 0 0 0 1 +199 13 196 10 0 0 0 0 0 0 0 0 0 0 0 1 +199 17 196 13 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +199 19 196 19 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +199 23 196 19 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +199 29 196 37 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +199 31 196 15 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +199 37 196 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +199 41 196 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +199 43 196 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +199 47 196 23 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +211 1 209 1 +211 2 2 207 1 +211 3 209 2 0 1 +211 4 2 161 8 0 1 +211 5 209 13 0 0 0 1 +211 6 2 133 194 81 0 0 1 +211 7 209 3 0 0 0 0 0 1 +211 8 2 29 87 200 2 0 0 0 1 +211 9 209 26 139 19 0 0 0 0 0 1 +211 10 2 125 87 148 61 30 1 0 0 0 1 +211 11 209 7 0 0 0 0 0 0 0 0 0 1 +211 12 2 27 84 184 126 145 50 8 0 0 0 0 1 +211 13 209 12 0 0 0 0 0 0 0 0 0 0 0 1 +211 17 209 12 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +211 19 209 17 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +211 23 209 12 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +211 29 209 33 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +211 31 209 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +211 37 209 69 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +211 41 209 14 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +211 43 209 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +211 47 209 54 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +223 1 220 1 +223 2 3 221 1 +223 3 220 6 0 1 +223 4 3 163 6 0 1 +223 5 220 1 0 0 0 1 +223 6 3 196 24 68 2 0 1 +223 7 220 6 0 0 0 0 0 1 +223 8 3 138 98 139 2 0 0 0 1 +223 9 220 64 164 1 0 0 0 0 0 1 +223 10 3 62 99 87 177 118 1 0 0 0 1 +223 11 220 8 0 0 0 0 0 0 0 0 0 1 +223 12 3 213 151 64 105 11 94 64 1 0 0 0 1 +223 13 220 23 0 0 0 0 0 0 0 0 0 0 0 1 +223 17 220 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +223 19 220 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +223 23 220 25 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +223 29 220 47 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +223 31 220 12 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +223 37 220 22 222 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +223 41 220 27 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +223 43 220 69 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +223 47 220 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +227 1 225 1 +227 2 2 220 1 +227 3 225 2 0 1 +227 4 2 143 1 0 1 +227 5 225 5 0 0 0 1 +227 6 2 135 24 174 1 0 1 +227 7 225 18 0 0 0 0 0 1 +227 8 2 106 176 151 2 0 0 0 1 +227 9 225 183 24 3 0 0 0 0 0 1 +227 10 2 77 93 12 199 22 0 0 0 0 1 +227 11 225 2 0 0 0 0 0 0 0 0 0 1 +227 12 2 94 142 127 96 160 99 123 0 0 0 0 1 +227 13 225 2 0 0 0 0 0 0 0 0 0 0 0 1 +227 17 225 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +227 19 225 34 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +227 23 225 12 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +227 29 225 22 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +227 31 225 17 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +227 37 225 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +227 41 225 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +227 43 225 49 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +227 47 225 142 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +229 1 223 1 +229 2 6 228 1 +229 3 223 1 0 1 +229 4 6 162 7 0 1 +229 5 223 8 0 0 0 1 +229 6 6 186 160 24 0 0 1 +229 7 223 7 0 0 0 0 0 1 +229 8 6 205 62 193 8 0 0 0 1 +229 9 223 50 117 15 0 0 0 0 0 1 +229 10 6 98 167 158 135 185 1 0 0 0 1 +229 11 223 2 0 0 0 0 0 0 0 0 0 1 +229 12 6 145 9 172 6 25 140 131 0 0 0 0 1 +229 13 223 47 0 0 0 0 0 0 0 0 0 0 0 1 +229 17 223 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +229 19 223 15 228 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +229 23 223 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +229 29 223 40 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +229 31 223 48 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +229 37 223 37 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +229 41 223 154 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +229 43 223 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +229 47 223 103 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +233 1 230 1 +233 2 3 232 1 +233 3 230 1 0 1 +233 4 3 158 4 0 1 +233 5 230 17 0 0 0 1 +233 6 3 32 215 122 3 0 1 +233 7 230 4 0 0 0 0 0 1 +233 8 3 181 135 202 12 0 0 0 1 +233 9 230 146 56 7 0 0 0 0 0 1 +233 10 3 48 3 102 71 28 3 0 0 0 1 +233 11 230 5 0 0 0 0 0 0 0 0 0 1 +233 12 3 20 216 19 31 114 21 96 0 0 0 0 1 +233 13 230 14 0 0 0 0 0 0 0 0 0 0 0 1 +233 17 230 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +233 19 230 25 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +233 23 230 13 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +233 29 230 5 232 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +233 31 230 153 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +233 37 230 24 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +233 41 230 18 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +233 43 230 63 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +233 47 230 41 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +239 1 232 1 +239 2 7 237 1 +239 3 232 11 0 1 +239 4 7 132 11 0 1 +239 5 232 2 0 0 0 1 +239 6 7 200 60 237 1 0 1 +239 7 232 17 0 0 0 0 0 1 +239 8 7 54 202 201 1 0 0 0 1 +239 9 232 88 2 3 0 0 0 0 0 1 +239 10 7 108 127 226 68 57 0 0 0 0 1 +239 11 232 8 0 0 0 0 0 0 0 0 0 1 +239 12 7 216 81 101 182 113 14 235 1 0 0 0 1 +239 13 232 2 0 0 0 0 0 0 0 0 0 0 0 1 +239 17 232 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +239 19 232 24 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +239 23 232 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +239 29 232 63 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +239 31 232 16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +239 37 232 92 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +239 41 232 15 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +239 43 232 93 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +239 47 232 74 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +241 1 234 1 +241 2 7 238 1 +241 3 234 1 0 1 +241 4 7 152 14 0 1 +241 5 234 7 0 0 0 1 +241 6 7 5 6 83 0 0 1 +241 7 234 2 0 0 0 0 0 1 +241 8 7 153 212 173 1 0 0 0 1 +241 9 234 125 236 0 0 0 0 0 0 1 +241 10 7 55 208 145 27 29 1 0 0 0 1 +241 11 234 3 0 0 0 0 0 0 0 0 0 1 +241 12 7 17 197 22 168 109 10 42 0 0 0 0 1 +241 13 234 11 0 0 0 0 0 0 0 0 0 0 0 1 +241 17 234 14 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +241 19 234 11 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +241 23 234 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +241 29 234 17 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +241 31 234 106 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +241 37 234 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +241 41 234 104 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +241 43 234 20 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +241 47 234 41 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +251 1 245 1 +251 2 6 242 1 +251 3 245 3 0 1 +251 4 6 200 3 0 1 +251 5 245 3 0 0 0 1 +251 6 6 179 151 247 1 0 1 +251 7 245 8 0 0 0 0 0 1 +251 8 6 173 215 142 7 0 0 0 1 +251 9 245 106 187 4 0 0 0 0 0 1 +251 10 6 149 34 45 110 138 1 0 0 0 1 +251 11 245 26 0 0 0 0 0 0 0 0 0 1 +251 12 6 232 201 15 20 20 53 192 1 0 0 0 1 +251 13 245 15 0 0 0 0 0 0 0 0 0 0 0 1 +251 17 245 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +251 19 245 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +251 23 245 13 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +251 29 245 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +251 31 245 11 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +251 37 245 79 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +251 41 245 38 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +251 43 245 92 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +251 47 245 67 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +257 1 254 1 +257 2 3 251 1 +257 3 254 6 0 1 +257 4 3 187 16 0 1 +257 5 254 4 0 0 0 1 +257 6 3 138 18 62 3 0 1 +257 7 254 31 0 0 0 0 0 1 +257 8 3 162 140 179 0 0 0 0 1 +257 9 254 50 201 1 0 0 0 0 0 1 +257 10 3 20 180 225 12 97 0 0 0 0 1 +257 11 254 40 0 0 0 0 0 0 0 0 0 1 +257 12 3 20 148 249 173 215 225 13 2 0 0 0 1 +257 13 254 5 0 0 0 0 0 0 0 0 0 0 0 1 +257 17 254 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +257 19 254 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +257 23 254 35 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +257 29 254 48 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +257 31 254 22 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +257 37 254 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +257 41 254 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +257 43 254 104 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +257 47 254 16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +263 1 258 1 +263 2 5 261 1 +263 3 258 14 0 1 +263 4 5 171 5 0 1 +263 5 258 13 0 0 0 1 +263 6 5 225 250 222 1 0 1 +263 7 258 1 0 0 0 0 0 1 +263 8 5 7 170 227 3 0 0 0 1 +263 9 258 29 261 6 0 0 0 0 0 1 +263 10 5 119 145 198 231 245 0 0 0 0 1 +263 11 258 2 0 0 0 0 0 0 0 0 0 1 +263 12 5 180 45 47 252 162 174 172 0 0 0 0 1 +269 1 267 1 +269 2 2 268 1 +269 3 267 9 0 1 +269 4 2 262 8 0 1 +269 5 267 12 0 0 0 1 +269 6 2 206 101 120 1 0 1 +269 7 267 6 0 0 0 0 0 1 +269 8 2 232 131 220 4 0 0 0 1 +269 9 267 267 214 2 0 0 0 0 0 1 +269 10 2 10 61 186 243 264 2 0 0 0 1 +269 11 267 20 0 0 0 0 0 0 0 0 0 1 +269 12 2 150 180 132 215 63 165 126 0 0 0 0 1 +271 1 265 1 +271 2 6 269 1 +271 3 265 2 0 1 +271 4 6 205 3 0 1 +271 5 265 2 0 0 0 1 +271 6 6 81 207 207 0 0 1 +271 7 265 22 0 0 0 0 0 1 +271 8 6 69 114 199 1 0 0 0 1 +271 9 265 186 266 10 0 0 0 0 0 1 +271 10 6 126 74 256 10 133 1 0 0 0 1 +271 11 265 10 0 0 0 0 0 0 0 0 0 1 +271 12 6 130 256 237 205 116 210 162 0 0 0 0 1 +277 1 272 1 +277 2 5 274 1 +277 3 272 3 0 1 +277 4 5 222 1 0 1 +277 5 272 1 0 0 0 1 +277 6 5 118 9 33 1 0 1 +277 7 272 9 0 0 0 0 0 1 +277 8 5 176 159 187 4 0 0 0 1 +277 9 272 110 177 4 0 0 0 0 0 1 +277 10 5 260 241 237 253 206 0 0 0 0 1 +277 11 272 5 0 0 0 0 0 0 0 0 0 1 +277 12 5 202 115 180 40 240 218 183 4 0 0 0 1 +281 1 278 1 +281 2 3 280 1 +281 3 278 1 0 1 +281 4 3 176 7 0 1 +281 5 278 5 0 0 0 1 +281 6 3 27 13 151 1 0 1 +281 7 278 19 0 0 0 0 0 1 +281 8 3 140 279 195 4 0 0 0 1 +281 9 278 70 148 6 0 0 0 0 0 1 +281 10 3 191 138 13 145 258 2 0 0 0 1 +281 11 278 36 0 0 0 0 0 0 0 0 0 1 +281 12 3 191 28 58 116 103 68 202 0 0 0 0 1 +283 1 280 1 +283 2 3 282 1 +283 3 280 3 0 1 +283 4 3 238 5 0 1 +283 5 280 3 0 0 0 1 +283 6 3 73 68 199 0 0 1 +283 7 280 8 0 0 0 0 0 1 +283 8 3 232 32 179 11 0 0 0 1 +283 9 280 65 136 0 0 0 0 0 0 1 +283 10 3 219 100 68 185 271 3 0 0 0 1 +283 11 280 4 0 0 0 0 0 0 0 0 0 1 +283 12 3 56 14 49 229 96 8 20 0 0 0 0 1 +293 1 291 1 +293 2 2 292 1 +293 3 291 2 0 1 +293 4 2 166 3 0 1 +293 5 291 2 0 0 0 1 +293 6 2 260 210 128 1 0 1 +293 7 291 8 0 0 0 0 0 1 +293 8 2 239 195 175 29 0 0 0 1 +293 9 291 190 208 0 0 0 0 0 0 1 +293 10 2 24 184 46 28 186 0 0 0 0 1 +293 11 291 3 0 0 0 0 0 0 0 0 0 1 +293 12 2 157 144 167 212 125 210 159 0 0 0 0 1 +307 1 302 1 +307 2 5 306 1 +307 3 302 7 0 1 +307 4 5 239 2 0 1 +307 5 302 5 0 0 0 1 +307 6 5 61 172 213 0 0 1 +307 7 302 6 0 0 0 0 0 1 +307 8 5 131 232 283 0 0 0 0 1 +307 9 302 70 165 1 0 0 0 0 0 1 +311 1 294 1 +311 2 17 310 1 +311 3 294 3 0 1 +311 4 17 163 3 0 1 +311 5 294 1 0 0 0 1 +311 6 17 152 167 27 1 0 1 +311 7 294 10 0 0 0 0 0 1 +311 8 17 2 118 162 19 0 0 0 1 +311 9 294 74 287 1 0 0 0 0 0 1 +313 1 303 1 +313 2 10 310 1 +313 3 303 2 0 1 +313 4 10 239 8 0 1 +313 5 303 7 0 0 0 1 +313 6 10 253 213 196 0 0 1 +313 7 303 4 0 0 0 0 0 1 +313 8 10 106 99 306 8 0 0 0 1 +313 9 303 300 267 8 0 0 0 0 0 1 +317 1 315 1 +317 2 2 313 1 +317 3 315 7 0 1 +317 4 2 178 6 0 1 +317 5 315 2 0 0 0 1 +317 6 2 4 156 195 2 0 1 +317 7 315 7 0 0 0 0 0 1 +317 8 2 31 85 207 1 0 0 0 1 +317 9 315 296 284 0 0 0 0 0 0 1 +331 1 328 1 +331 2 3 326 1 +331 3 328 1 0 1 +331 4 3 290 3 0 1 +331 5 328 4 0 0 0 1 +331 6 3 159 205 283 1 0 1 +331 7 328 5 0 0 0 0 0 1 +331 8 3 78 308 249 1 0 0 0 1 +331 9 328 210 194 0 0 0 0 0 0 1 +337 1 327 1 +337 2 10 332 1 +337 3 327 2 0 1 +337 4 10 224 25 0 1 +337 5 327 2 0 0 0 1 +337 6 10 109 127 216 0 0 1 +337 7 327 5 0 0 0 0 0 1 +337 8 10 251 246 331 0 0 0 0 1 +337 9 327 98 148 12 0 0 0 0 0 1 +347 1 345 1 +347 2 2 343 1 +347 3 345 9 0 1 +347 4 2 295 13 0 1 +347 5 345 3 0 0 0 1 +347 6 2 56 26 343 3 0 1 +347 7 345 4 0 0 0 0 0 1 +347 8 2 117 213 187 1 0 0 0 1 +347 9 345 252 235 2 0 0 0 0 0 1 +349 1 347 1 +349 2 2 348 1 +349 3 347 4 0 1 +349 4 2 279 3 0 1 +349 5 347 2 0 0 0 1 +349 6 2 316 177 135 0 0 1 +349 7 347 10 0 0 0 0 0 1 +349 8 2 268 328 308 0 0 0 0 1 +349 9 347 130 290 36 0 0 0 0 0 1 +353 1 350 1 +353 2 3 348 1 +353 3 350 3 0 1 +353 4 3 199 0 0 1 +353 5 350 1 0 0 0 1 +353 6 3 295 226 215 1 0 1 +353 7 350 16 0 0 0 0 0 1 +353 8 3 37 26 182 1 0 0 0 1 +353 9 350 49 319 2 0 0 0 0 0 1 +359 1 352 1 +359 2 7 358 1 +359 3 352 3 0 1 +359 4 7 229 2 0 1 +359 5 352 1 0 0 0 1 +359 6 7 327 327 309 4 0 1 +359 7 352 1 0 0 0 0 0 1 +359 8 7 271 143 301 0 0 0 0 1 +359 9 352 165 356 0 0 0 0 0 0 1 +367 1 361 1 +367 2 6 366 1 +367 3 361 10 0 1 +367 4 6 295 3 0 1 +367 5 361 3 0 0 0 1 +367 6 6 324 321 222 0 0 1 +367 7 361 13 0 0 0 0 0 1 +367 8 6 50 282 335 2 0 0 0 1 +367 9 361 268 213 15 0 0 0 0 0 1 +373 1 371 1 +373 2 2 369 1 +373 3 371 5 0 1 +373 4 2 304 15 0 1 +373 5 371 2 0 0 0 1 +373 6 2 108 83 126 0 0 1 +373 7 371 7 0 0 0 0 0 1 +373 8 2 66 219 203 0 0 0 0 1 +373 9 371 370 238 14 0 0 0 0 0 1 +379 1 377 1 +379 2 2 374 1 +379 3 377 5 0 1 +379 4 2 327 2 0 1 +379 5 377 4 0 0 0 1 +379 6 2 246 364 374 0 0 1 +379 7 377 14 0 0 0 0 0 1 +379 8 2 173 194 210 13 0 0 0 1 +379 9 377 369 362 11 0 0 0 0 0 1 +383 1 378 1 +383 2 5 382 1 +383 3 378 1 0 1 +383 4 5 309 7 0 1 +383 5 378 1 0 0 0 1 +383 6 5 158 8 69 1 0 1 +383 7 378 6 0 0 0 0 0 1 +383 8 5 296 332 281 10 0 0 0 1 +383 9 378 76 137 2 0 0 0 0 0 1 +389 1 387 1 +389 2 2 379 1 +389 3 387 2 0 1 +389 4 2 266 2 0 1 +389 5 387 4 0 0 0 1 +389 6 2 255 339 218 1 0 1 +389 7 387 24 0 0 0 0 0 1 +389 8 2 290 19 351 0 0 0 0 1 +389 9 387 308 258 2 0 0 0 0 0 1 +397 1 392 1 +397 2 5 392 1 +397 3 392 2 0 1 +397 4 5 363 12 0 1 +397 5 392 7 0 0 0 1 +397 6 5 287 274 382 0 0 1 +397 7 392 12 0 0 0 0 0 1 +397 8 5 203 255 375 1 0 0 0 1 +397 9 392 252 166 6 0 0 0 0 0 1 +401 1 398 1 +401 2 3 396 1 +401 3 398 3 0 1 +401 4 3 372 2 0 1 +401 5 398 4 0 0 0 1 +401 6 3 51 81 115 4 0 1 +401 7 398 5 0 0 0 0 0 1 +401 8 3 164 113 380 0 0 0 0 1 +401 9 398 158 199 1 0 0 0 0 0 1 +409 1 388 1 +409 2 21 404 1 +409 3 388 3 0 1 +409 4 21 407 12 0 1 +409 5 388 5 0 0 0 1 +409 6 21 364 53 372 0 0 1 +409 7 388 7 0 0 0 0 0 1 +409 8 21 396 69 256 3 0 0 0 1 +409 9 388 211 318 8 0 0 0 0 0 1 +419 1 417 1 +419 2 2 418 1 +419 3 417 11 0 1 +419 4 2 373 4 0 1 +419 5 417 4 0 0 0 1 +419 6 2 257 33 411 2 0 1 +419 7 417 4 0 0 0 0 0 1 +419 8 2 151 388 234 8 0 0 0 1 +419 9 417 386 93 0 0 0 0 0 0 1 +421 1 419 1 +421 2 2 417 1 +421 3 419 2 0 1 +421 4 2 257 10 0 1 +421 5 419 15 0 0 0 1 +421 6 2 41 342 111 0 0 1 +421 7 419 21 0 0 0 0 0 1 +421 8 2 77 32 389 5 0 0 0 1 +421 9 419 145 394 18 0 0 0 0 0 1 +431 1 424 1 +431 2 7 430 1 +431 3 424 2 0 1 +431 4 7 323 2 0 1 +431 5 424 7 0 0 0 1 +431 6 7 182 202 161 4 0 1 +431 7 424 1 0 0 0 0 0 1 +431 8 7 115 286 243 5 0 0 0 1 +431 9 424 329 71 2 0 0 0 0 0 1 +433 1 428 1 +433 2 5 432 1 +433 3 428 1 0 1 +433 4 5 402 6 0 1 +433 5 428 5 0 0 0 1 +433 6 5 360 353 244 0 0 1 +433 7 428 6 0 0 0 0 0 1 +433 8 5 39 32 347 10 0 0 0 1 +433 9 428 45 232 27 0 0 0 0 0 1 +439 1 424 1 +439 2 15 436 1 +439 3 424 3 0 1 +439 4 15 323 0 0 1 +439 5 424 1 0 0 0 1 +439 6 15 190 324 1 0 0 1 +439 7 424 1 0 0 0 0 0 1 +439 8 15 266 296 359 0 0 0 0 1 +439 9 424 254 342 16 0 0 0 0 0 1 +443 1 441 1 +443 2 2 437 1 +443 3 441 4 0 1 +443 4 2 383 4 0 1 +443 5 441 4 0 0 0 1 +443 6 2 41 218 298 1 0 1 +443 7 441 6 0 0 0 0 0 1 +443 8 2 290 217 437 2 0 0 0 1 +443 9 441 109 125 3 0 0 0 0 0 1 +449 1 446 1 +449 2 3 444 1 +449 3 446 1 0 1 +449 4 3 249 2 0 1 +449 5 446 9 0 0 0 1 +449 6 3 69 293 437 2 0 1 +449 7 446 28 0 0 0 0 0 1 +449 8 3 124 348 361 0 0 0 0 1 +449 9 446 9 226 6 0 0 0 0 0 1 +457 1 444 1 +457 2 13 454 1 +457 3 444 1 0 1 +457 4 13 407 8 0 1 +457 5 444 4 0 0 0 1 +457 6 13 266 389 205 0 0 1 +457 7 444 14 0 0 0 0 0 1 +457 8 13 412 296 365 9 0 0 0 1 +457 9 444 84 354 9 0 0 0 0 0 1 +461 1 459 1 +461 2 2 460 1 +461 3 459 3 0 1 +461 4 2 393 3 0 1 +461 5 459 14 0 0 0 1 +461 6 2 329 432 439 1 0 1 +461 7 459 5 0 0 0 0 0 1 +461 8 2 321 449 388 15 0 0 0 1 +461 9 459 276 210 5 0 0 0 0 0 1 +463 1 460 1 +463 2 3 461 1 +463 3 460 10 0 1 +463 4 3 262 17 0 1 +463 5 460 3 0 0 0 1 +463 6 3 110 51 462 0 0 1 +463 7 460 13 0 0 0 0 0 1 +463 8 3 396 414 234 0 0 0 0 1 +463 9 460 227 433 3 0 0 0 0 0 1 +467 1 465 1 +467 2 2 463 1 +467 3 465 2 0 1 +467 4 2 353 14 0 1 +467 5 465 2 0 0 0 1 +467 6 2 237 62 123 1 0 1 +467 7 465 7 0 0 0 0 0 1 +467 8 2 289 413 318 5 0 0 0 1 +467 9 465 447 397 0 0 0 0 0 0 1 +479 1 466 1 +479 2 13 474 1 +479 3 466 4 0 1 +479 4 13 386 6 0 1 +479 5 466 2 0 0 0 1 +479 6 13 334 287 243 1 0 1 +479 7 466 4 0 0 0 0 0 1 +479 8 13 17 440 247 7 0 0 0 1 +479 9 466 185 3 2 0 0 0 0 0 1 +487 1 484 1 +487 2 3 485 1 +487 3 484 4 0 1 +487 4 3 483 4 0 1 +487 5 484 1 0 0 0 1 +487 6 3 185 427 450 0 0 1 +487 7 484 7 0 0 0 0 0 1 +487 8 3 137 249 283 1 0 0 0 1 +487 9 484 447 271 10 0 0 0 0 0 1 +491 1 489 1 +491 2 2 487 1 +491 3 489 2 0 1 +491 4 2 360 7 0 1 +491 5 489 5 0 0 0 1 +491 6 2 125 402 369 1 0 1 +491 7 489 5 0 0 0 0 0 1 +491 8 2 216 372 378 1 0 0 0 1 +491 9 489 453 149 0 0 0 0 0 0 1 +499 1 492 1 +499 2 7 493 1 +499 3 492 2 0 1 +499 4 7 495 4 0 1 +499 5 492 17 0 0 0 1 +499 6 7 78 191 407 0 0 1 +499 7 492 8 0 0 0 0 0 1 +499 8 7 200 309 288 1 0 0 0 1 +499 9 492 222 491 5 0 0 0 0 0 1 +503 1 498 1 +503 2 5 498 1 +503 3 498 2 0 1 +503 4 5 325 6 0 1 +503 5 498 15 0 0 0 1 +503 6 5 255 292 380 1 0 1 +503 7 498 11 0 0 0 0 0 1 +503 8 5 316 203 441 8 0 0 0 1 +503 9 498 337 158 3 0 0 0 0 0 1 +509 1 507 1 +509 2 2 508 1 +509 3 507 3 0 1 +509 4 2 408 4 0 1 +509 5 507 3 0 0 0 1 +509 6 2 41 232 350 1 0 1 +509 7 507 6 0 0 0 0 0 1 +509 8 2 382 473 420 2 0 0 0 1 +509 9 507 28 314 0 0 0 0 0 0 1 +521 1 518 1 +521 2 3 515 1 +521 3 518 4 0 1 +521 4 3 509 0 0 1 +521 5 518 3 0 0 0 1 +521 6 3 280 153 315 1 0 1 +521 7 518 1 0 0 0 0 0 1 +521 8 3 312 407 462 6 0 0 0 1 +521 9 518 483 181 5 0 0 0 0 0 1 +523 1 521 1 +523 2 2 522 1 +523 3 521 5 0 1 +523 4 2 382 2 0 1 +523 5 521 4 0 0 0 1 +523 6 2 371 475 475 0 0 1 +523 7 521 13 0 0 0 0 0 1 +523 8 2 380 184 518 4 0 0 0 1 +523 9 521 145 342 19 0 0 0 0 0 1 +541 1 539 1 +541 2 2 537 1 +541 3 539 2 0 1 +541 4 2 333 6 0 1 +541 5 539 3 0 0 0 1 +541 6 2 69 320 239 0 0 1 +541 7 539 2 0 0 0 0 0 1 +541 8 2 113 108 376 3 0 0 0 1 +541 9 539 318 340 16 0 0 0 0 0 1 +547 1 545 1 +547 2 2 543 1 +547 3 545 4 0 1 +547 4 2 334 8 0 1 +547 5 545 2 0 0 0 1 +547 6 2 423 153 334 0 0 1 +547 7 545 11 0 0 0 0 0 1 +547 8 2 180 20 368 10 0 0 0 1 +547 9 545 263 238 11 0 0 0 0 0 1 +557 1 555 1 +557 2 2 553 1 +557 3 555 3 0 1 +557 4 2 430 7 0 1 +557 5 555 9 0 0 0 1 +557 6 2 253 192 202 1 0 1 +557 7 555 6 0 0 0 0 0 1 +557 8 2 113 384 480 0 0 0 0 1 +557 9 555 434 456 1 0 0 0 0 0 1 +563 1 561 1 +563 2 2 559 1 +563 3 561 3 0 1 +563 4 2 399 20 0 1 +563 5 561 6 0 0 0 1 +563 6 2 246 303 122 1 0 1 +563 7 561 5 0 0 0 0 0 1 +563 8 2 509 176 503 2 0 0 0 1 +563 9 561 19 15 3 0 0 0 0 0 1 +569 1 566 1 +569 2 3 568 1 +569 3 566 4 0 1 +569 4 3 381 7 0 1 +569 5 566 4 0 0 0 1 +569 6 3 480 263 50 2 0 1 +569 7 566 5 0 0 0 0 0 1 +569 8 3 241 173 527 1 0 0 0 1 +569 9 566 566 478 1 0 0 0 0 0 1 +571 1 568 1 +571 2 3 570 1 +571 3 568 8 0 1 +571 4 3 402 2 0 1 +571 5 568 4 0 0 0 1 +571 6 3 33 295 221 0 0 1 +571 7 568 7 0 0 0 0 0 1 +571 8 3 371 119 363 4 0 0 0 1 +571 9 568 179 545 34 0 0 0 0 0 1 +577 1 572 1 +577 2 5 572 1 +577 3 572 2 0 1 +577 4 5 494 12 0 1 +577 5 572 3 0 0 0 1 +577 6 5 283 25 450 1 0 1 +577 7 572 8 0 0 0 0 0 1 +577 8 5 321 545 450 12 0 0 0 1 +577 9 572 449 576 17 0 0 0 0 0 1 +587 1 585 1 +587 2 2 583 1 +587 3 585 3 0 1 +587 4 2 444 16 0 1 +587 5 585 2 0 0 0 1 +587 6 2 226 121 204 1 0 1 +587 7 585 3 0 0 0 0 0 1 +587 8 2 91 44 492 5 0 0 0 1 +587 9 585 55 333 0 0 0 0 0 0 1 +593 1 590 1 +593 2 3 592 1 +593 3 590 6 0 1 +593 4 3 419 4 0 1 +593 5 590 3 0 0 0 1 +593 6 3 478 65 345 2 0 1 +593 7 590 15 0 0 0 0 0 1 +593 8 3 495 291 350 9 0 0 0 1 +593 9 590 523 223 8 0 0 0 0 0 1 +599 1 592 1 +599 2 7 598 1 +599 3 592 2 0 1 +599 4 7 419 3 0 1 +599 5 592 8 0 0 0 1 +599 6 7 586 274 515 1 0 1 +599 7 592 2 0 0 0 0 0 1 +599 8 7 124 37 440 3 0 0 0 1 +599 9 592 98 114 3 0 0 0 0 0 1 +601 1 594 1 +601 2 7 598 1 +601 3 594 1 0 1 +601 4 7 347 14 0 1 +601 5 594 13 0 0 0 1 +601 6 7 49 440 128 1 0 1 +601 7 594 5 0 0 0 0 0 1 +601 8 7 490 241 550 0 0 0 0 1 +601 9 594 590 487 7 0 0 0 0 0 1 +607 1 604 1 +607 2 3 606 1 +607 3 604 5 0 1 +607 4 3 449 8 0 1 +607 5 604 4 0 0 0 1 +607 6 3 478 45 10 0 0 1 +607 7 604 9 0 0 0 0 0 1 +607 8 3 449 35 468 4 0 0 0 1 +607 9 604 129 444 1 0 0 0 0 0 1 +613 1 611 1 +613 2 2 609 1 +613 3 611 6 0 1 +613 4 2 333 12 0 1 +613 5 611 32 0 0 0 1 +613 6 2 601 595 609 0 0 1 +613 7 611 6 0 0 0 0 0 1 +613 8 2 539 57 489 6 0 0 0 1 +613 9 611 536 513 8 0 0 0 0 0 1 +617 1 614 1 +617 2 3 612 1 +617 3 614 3 0 1 +617 4 3 503 2 0 1 +617 5 614 4 0 0 0 1 +617 6 3 310 595 318 1 0 1 +617 7 614 7 0 0 0 0 0 1 +617 8 3 155 501 519 0 0 0 0 1 +617 9 614 543 388 15 0 0 0 0 0 1 +619 1 617 1 +619 2 2 618 1 +619 3 617 6 0 1 +619 4 2 492 6 0 1 +619 5 617 8 0 0 0 1 +619 6 2 347 468 238 0 0 1 +619 7 617 7 0 0 0 0 0 1 +619 8 2 225 383 416 10 0 0 0 1 +619 9 617 310 579 0 0 0 0 0 0 1 +631 1 628 1 +631 2 3 629 1 +631 3 628 5 0 1 +631 4 3 376 6 0 1 +631 5 628 5 0 0 0 1 +631 6 3 106 541 516 0 0 1 +631 7 628 5 0 0 0 0 0 1 +631 8 3 187 516 379 2 0 0 0 1 +631 9 628 413 296 3 0 0 0 0 0 1 +641 1 638 1 +641 2 3 635 1 +641 3 638 4 0 1 +641 4 3 629 0 0 1 +641 5 638 1 0 0 0 1 +641 6 3 294 557 105 2 0 1 +641 7 638 3 0 0 0 0 0 1 +641 8 3 332 392 356 3 0 0 0 1 +641 9 638 141 66 0 0 0 0 0 0 1 +643 1 632 1 +643 2 11 641 1 +643 3 632 1 0 1 +643 4 11 600 0 0 1 +643 5 632 2 0 0 0 1 +643 6 11 293 412 345 0 0 1 +643 7 632 5 0 0 0 0 0 1 +643 8 11 569 573 631 1 0 0 0 1 +643 9 632 475 591 3 0 0 0 0 0 1 +647 1 642 1 +647 2 5 645 1 +647 3 642 6 0 1 +647 4 5 643 3 0 1 +647 5 642 11 0 0 0 1 +647 6 5 642 385 308 5 0 1 +647 7 642 1 0 0 0 0 0 1 +647 8 5 271 259 603 9 0 0 0 1 +647 9 642 123 561 13 0 0 0 0 0 1 +653 1 651 1 +653 2 2 649 1 +653 3 651 3 0 1 +653 4 2 596 6 0 1 +653 5 651 5 0 0 0 1 +653 6 2 242 220 45 2 0 1 +653 7 651 15 0 0 0 0 0 1 +653 8 2 296 18 385 0 0 0 0 1 +653 9 651 60 365 0 0 0 0 0 0 1 +659 1 657 1 +659 2 2 655 1 +659 3 657 2 0 1 +659 4 2 351 8 0 1 +659 5 657 4 0 0 0 1 +659 6 2 223 105 371 6 0 1 +659 7 657 5 0 0 0 0 0 1 +659 8 2 90 246 358 6 0 0 0 1 +659 9 657 46 592 2 0 0 0 0 0 1 +661 1 659 1 +661 2 2 660 1 +661 3 659 4 0 1 +661 4 2 616 7 0 1 +661 5 659 19 0 0 0 1 +661 6 2 382 456 551 0 0 1 +661 7 659 2 0 0 0 0 0 1 +661 8 2 72 285 612 0 0 0 0 1 +661 9 659 220 389 18 0 0 0 0 0 1 +673 1 668 1 +673 2 5 672 1 +673 3 668 1 0 1 +673 4 5 416 6 0 1 +673 5 668 15 0 0 0 1 +673 6 5 35 248 524 0 0 1 +673 7 668 6 0 0 0 0 0 1 +673 8 5 302 587 669 6 0 0 0 1 +673 9 668 553 347 11 0 0 0 0 0 1 +677 1 675 1 +677 2 2 672 1 +677 3 675 2 0 1 +677 4 2 631 0 0 1 +677 5 675 5 0 0 0 1 +677 6 2 50 632 446 1 0 1 +677 7 675 10 0 0 0 0 0 1 +677 8 2 152 619 363 0 0 0 0 1 +677 9 675 404 504 0 0 0 0 0 0 1 +683 1 678 1 +683 2 5 682 1 +683 3 678 5 0 1 +683 4 5 455 5 0 1 +683 5 678 7 0 0 0 1 +683 6 5 434 109 644 2 0 1 +683 7 678 30 0 0 0 0 0 1 +683 8 5 65 184 383 0 0 0 0 1 +683 9 678 444 85 0 0 0 0 0 0 1 +691 1 688 1 +691 2 3 686 1 +691 3 688 14 0 1 +691 4 3 632 3 0 1 +691 5 688 4 0 0 0 1 +691 6 3 262 408 579 0 0 1 +691 7 688 4 0 0 0 0 0 1 +691 8 3 321 425 356 7 0 0 0 1 +691 9 688 443 556 5 0 0 0 0 0 1 +701 1 699 1 +701 2 2 697 1 +701 3 699 2 0 1 +701 4 2 379 12 0 1 +701 5 699 5 0 0 0 1 +701 6 2 285 327 571 1 0 1 +701 7 699 10 0 0 0 0 0 1 +701 8 2 593 206 619 1 0 0 0 1 +701 9 699 373 459 1 0 0 0 0 0 1 +709 1 707 1 +709 2 2 705 1 +709 3 707 2 0 1 +709 4 2 384 6 0 1 +709 5 707 10 0 0 0 1 +709 6 2 295 514 669 0 0 1 +709 7 707 4 0 0 0 0 0 1 +709 8 2 79 233 689 2 0 0 0 1 +709 9 707 171 257 3 0 0 0 0 0 1 +719 1 708 1 +719 2 11 715 1 +719 3 708 1 0 1 +719 4 11 602 5 0 1 +719 5 708 1 0 0 0 1 +719 6 11 182 591 533 1 0 1 +719 7 708 11 0 0 0 0 0 1 +719 8 11 244 362 714 5 0 0 0 1 +719 9 708 560 288 3 0 0 0 0 0 1 +727 1 722 1 +727 2 5 725 1 +727 3 722 7 0 1 +727 4 5 723 3 0 1 +727 5 722 5 0 0 0 1 +727 6 5 672 397 86 0 0 1 +727 7 722 17 0 0 0 0 0 1 +727 8 5 368 671 639 0 0 0 0 1 +727 9 722 502 573 6 0 0 0 0 0 1 +733 1 727 1 +733 2 6 732 1 +733 3 727 4 0 1 +733 4 6 539 12 0 1 +733 5 727 8 0 0 0 1 +733 6 6 151 549 174 1 0 1 +733 7 727 3 0 0 0 0 0 1 +733 8 6 142 610 532 1 0 0 0 1 +733 9 727 6 337 2 0 0 0 0 0 1 +739 1 736 1 +739 2 3 734 1 +739 3 736 11 0 1 +739 4 3 678 3 0 1 +739 5 736 9 0 0 0 1 +739 6 3 625 447 422 0 0 1 +739 7 736 44 0 0 0 0 0 1 +739 8 3 25 169 401 2 0 0 0 1 +739 9 736 81 616 1 0 0 0 0 0 1 +743 1 738 1 +743 2 5 742 1 +743 3 738 3 0 1 +743 4 5 425 5 0 1 +743 5 738 6 0 0 0 1 +743 6 5 88 471 236 1 0 1 +743 7 738 6 0 0 0 0 0 1 +743 8 5 588 279 551 0 0 0 0 1 +743 9 738 676 327 3 0 0 0 0 0 1 +751 1 748 1 +751 2 3 749 1 +751 3 748 5 0 1 +751 4 3 525 3 0 1 +751 5 748 7 0 0 0 1 +751 6 3 539 633 298 2 0 1 +751 7 748 7 0 0 0 0 0 1 +751 8 3 672 243 741 3 0 0 0 1 +751 9 748 489 703 10 0 0 0 0 0 1 +757 1 755 1 +757 2 2 753 1 +757 3 755 6 0 1 +757 4 2 537 10 0 1 +757 5 755 13 0 0 0 1 +757 6 2 745 739 753 0 0 1 +757 7 755 4 0 0 0 0 0 1 +757 8 2 509 110 494 12 0 0 0 1 +757 9 755 702 688 8 0 0 0 0 0 1 +761 1 755 1 +761 2 6 758 1 +761 3 755 12 0 1 +761 4 6 658 0 0 1 +761 5 755 6 0 0 0 1 +761 6 6 155 597 634 2 0 1 +761 7 755 6 0 0 0 0 0 1 +761 8 6 540 144 603 11 0 0 0 1 +761 9 755 571 317 4 0 0 0 0 0 1 +769 1 758 1 +769 2 11 765 1 +769 3 758 2 0 1 +769 4 11 741 32 0 1 +769 5 758 1 0 0 0 1 +769 6 11 650 326 43 0 0 1 +769 7 758 8 0 0 0 0 0 1 +769 8 11 632 574 560 1 0 0 0 1 +769 9 758 751 623 0 0 0 0 0 0 1 +773 1 771 1 +773 2 2 772 1 +773 3 771 2 0 1 +773 4 2 444 4 0 1 +773 5 771 8 0 0 0 1 +773 6 2 581 3 91 1 0 1 +773 7 771 9 0 0 0 0 0 1 +773 8 2 693 94 484 0 0 0 0 1 +773 9 771 574 216 4 0 0 0 0 0 1 +787 1 785 1 +787 2 2 786 1 +787 3 785 2 0 1 +787 4 2 605 11 0 1 +787 5 785 9 0 0 0 1 +787 6 2 606 512 98 0 0 1 +787 7 785 3 0 0 0 0 0 1 +787 8 2 715 26 612 5 0 0 0 1 +787 9 785 573 480 5 0 0 0 0 0 1 +797 1 795 1 +797 2 2 793 1 +797 3 795 2 0 1 +797 4 2 717 1 0 1 +797 5 795 3 0 0 0 1 +797 6 2 71 396 657 1 0 1 +797 7 795 11 0 0 0 0 0 1 +797 8 2 389 747 596 1 0 0 0 1 +797 9 795 599 240 2 0 0 0 0 0 1 +809 1 806 1 +809 2 3 799 1 +809 3 806 1 0 1 +809 4 3 644 4 0 1 +809 5 806 3 0 0 0 1 +809 6 3 43 75 562 1 0 1 +809 7 806 3 0 0 0 0 0 1 +809 8 3 673 745 593 1 0 0 0 1 +809 9 806 727 341 1 0 0 0 0 0 1 +811 1 808 1 +811 2 3 806 1 +811 3 808 1 0 1 +811 4 3 453 3 0 1 +811 5 808 3 0 0 0 1 +811 6 3 307 755 780 0 0 1 +811 7 808 1 0 0 0 0 0 1 +811 8 3 525 806 663 3 0 0 0 1 +811 9 808 200 382 10 0 0 0 0 0 1 +821 1 819 1 +821 2 2 816 1 +821 3 819 2 0 1 +821 4 2 662 15 0 1 +821 5 819 9 0 0 0 1 +821 6 2 803 130 160 2 0 1 +821 7 819 10 0 0 0 0 0 1 +821 8 2 589 556 626 5 0 0 0 1 +821 9 819 557 650 1 0 0 0 0 0 1 +823 1 820 1 +823 2 3 821 1 +823 3 820 3 0 1 +823 4 3 819 4 0 1 +823 5 820 3 0 0 0 1 +823 6 3 744 616 822 0 0 1 +823 7 820 10 0 0 0 0 0 1 +823 8 3 31 437 451 0 0 0 0 1 +823 9 820 609 740 6 0 0 0 0 0 1 +827 1 825 1 +827 2 2 821 1 +827 3 825 5 0 1 +827 4 2 605 18 0 1 +827 5 825 3 0 0 0 1 +827 6 2 691 601 685 9 0 1 +827 7 825 5 0 0 0 0 0 1 +827 8 2 32 79 812 2 0 0 0 1 +827 9 825 372 177 0 0 0 0 0 0 1 +829 1 827 1 +829 2 2 828 1 +829 3 827 5 0 1 +829 4 2 604 9 0 1 +829 5 827 7 0 0 0 1 +829 6 2 817 476 341 1 0 1 +829 7 827 5 0 0 0 0 0 1 +829 8 2 138 241 468 1 0 0 0 1 +829 9 827 552 621 3 0 0 0 0 0 1 +839 1 828 1 +839 2 11 838 1 +839 3 828 4 0 1 +839 4 11 609 2 0 1 +839 5 828 2 0 0 0 1 +839 6 11 23 537 370 1 0 1 +839 7 828 7 0 0 0 0 0 1 +839 8 11 329 779 553 16 0 0 0 1 +839 9 828 206 349 0 0 0 0 0 0 1 +853 1 851 1 +853 2 2 852 1 +853 3 851 4 0 1 +853 4 2 623 3 0 1 +853 5 851 2 0 0 0 1 +853 6 2 512 194 276 0 0 1 +853 7 851 4 0 0 0 0 0 1 +853 8 2 118 846 544 8 0 0 0 1 +853 9 851 821 677 11 0 0 0 0 0 1 +857 1 854 1 +857 2 3 850 1 +857 3 854 4 0 1 +857 4 3 528 0 0 1 +857 5 854 3 0 0 0 1 +857 6 3 65 824 32 1 0 1 +857 7 854 7 0 0 0 0 0 1 +857 8 3 494 552 611 3 0 0 0 1 +857 9 854 719 308 0 0 0 0 0 0 1 +859 1 857 1 +859 2 2 858 1 +859 3 857 6 0 1 +859 4 2 530 2 0 1 +859 5 857 12 0 0 0 1 +859 6 2 566 646 419 0 0 1 +859 7 857 2 0 0 0 0 0 1 +859 8 2 672 446 522 0 0 0 0 1 +859 9 857 845 648 7 0 0 0 0 0 1 +863 1 858 1 +863 2 5 862 1 +863 3 858 5 0 1 +863 4 5 770 2 0 1 +863 5 858 10 0 0 0 1 +863 6 5 300 62 330 1 0 1 +863 7 858 1 0 0 0 0 0 1 +863 8 5 849 576 765 9 0 0 0 1 +863 9 858 1 381 1 0 0 0 0 0 1 +877 1 875 1 +877 2 2 873 1 +877 3 875 5 0 1 +877 4 2 604 6 0 1 +877 5 875 6 0 0 0 1 +877 6 2 855 400 629 0 0 1 +877 7 875 3 0 0 0 0 0 1 +877 8 2 347 319 767 4 0 0 0 1 +877 9 875 278 770 9 0 0 0 0 0 1 +881 1 878 1 +881 2 3 869 1 +881 3 878 1 0 1 +881 4 3 447 0 0 1 +881 5 878 8 0 0 0 1 +881 6 3 231 419 218 1 0 1 +881 7 878 6 0 0 0 0 0 1 +881 8 3 561 490 635 21 0 0 0 1 +881 9 878 510 587 2 0 0 0 0 0 1 +883 1 881 1 +883 2 2 879 1 +883 3 881 6 0 1 +883 4 2 715 8 0 1 +883 5 881 14 0 0 0 1 +883 6 2 871 865 879 0 0 1 +883 7 881 6 0 0 0 0 0 1 +883 8 2 768 762 740 7 0 0 0 1 +883 9 881 557 360 5 0 0 0 0 0 1 +887 1 882 1 +887 2 5 885 1 +887 3 882 1 0 1 +887 4 5 883 3 0 1 +887 5 882 5 0 0 0 1 +887 6 5 28 341 775 1 0 1 +887 7 882 8 0 0 0 0 0 1 +887 8 5 706 381 781 0 0 0 0 1 +887 9 882 345 727 4 0 0 0 0 0 1 +907 1 905 1 +907 2 2 903 1 +907 3 905 4 0 1 +907 4 2 478 14 0 1 +907 5 905 2 0 0 0 1 +907 6 2 266 752 626 0 0 1 +907 7 905 2 0 0 0 0 0 1 +907 8 2 811 518 584 4 0 0 0 1 +907 9 905 57 783 1 0 0 0 0 0 1 +911 1 894 1 +911 2 17 909 1 +911 3 894 1 0 1 +911 4 17 887 11 0 1 +911 5 894 2 0 0 0 1 +911 6 17 19 683 172 1 0 1 +911 7 894 4 0 0 0 0 0 1 +911 8 17 168 590 708 6 0 0 0 1 +911 9 894 116 679 0 0 0 0 0 0 1 +919 1 912 1 +919 2 7 910 1 +919 3 912 2 0 1 +919 4 7 602 3 0 1 +919 5 912 11 0 0 0 1 +919 6 7 113 817 312 0 0 1 +919 7 912 9 0 0 0 0 0 1 +919 8 7 504 202 708 6 0 0 0 1 +919 9 912 623 410 7 0 0 0 0 0 1 +929 1 926 1 +929 2 3 917 1 +929 3 926 5 0 1 +929 4 3 787 0 0 1 +929 5 926 3 0 0 0 1 +929 6 3 86 92 805 2 0 1 +929 7 926 7 0 0 0 0 0 1 +929 8 3 586 292 699 5 0 0 0 1 +929 9 926 199 481 0 0 0 0 0 0 1 +937 1 932 1 +937 2 5 934 1 +937 3 932 3 0 1 +937 4 5 585 23 0 1 +937 5 932 5 0 0 0 1 +937 6 5 934 727 794 0 0 1 +937 7 932 24 0 0 0 0 0 1 +937 8 5 53 26 658 0 0 0 0 1 +937 9 932 483 533 28 0 0 0 0 0 1 +941 1 939 1 +941 2 2 940 1 +941 3 939 3 0 1 +941 4 2 505 3 0 1 +941 5 939 2 0 0 0 1 +941 6 2 538 694 459 2 0 1 +941 7 939 4 0 0 0 0 0 1 +941 8 2 590 675 805 0 0 0 0 1 +941 9 939 197 708 1 0 0 0 0 0 1 +947 1 945 1 +947 2 2 943 1 +947 3 945 3 0 1 +947 4 2 894 8 0 1 +947 5 945 15 0 0 0 1 +947 6 2 95 787 880 2 0 1 +947 7 945 6 0 0 0 0 0 1 +947 8 2 581 597 845 1 0 0 0 1 +947 9 945 808 269 1 0 0 0 0 0 1 +953 1 950 1 +953 2 3 947 1 +953 3 950 7 0 1 +953 4 3 865 1 0 1 +953 5 950 1 0 0 0 1 +953 6 3 730 829 507 1 0 1 +953 7 950 5 0 0 0 0 0 1 +953 8 3 108 658 579 6 0 0 0 1 +953 9 950 316 819 1 0 0 0 0 0 1 +967 1 962 1 +967 2 5 965 1 +967 3 962 1 0 1 +967 4 5 963 3 0 1 +967 5 962 2 0 0 0 1 +967 6 5 831 948 805 0 0 1 +967 7 962 9 0 0 0 0 0 1 +967 8 5 136 502 840 15 0 0 0 1 +967 9 962 783 512 3 0 0 0 0 0 1 +971 1 965 1 +971 2 6 970 1 +971 3 965 3 0 1 +971 4 6 527 2 0 1 +971 5 965 14 0 0 0 1 +971 6 6 718 729 970 1 0 1 +971 7 965 13 0 0 0 0 0 1 +971 8 6 206 281 725 0 0 0 0 1 +971 9 965 473 805 0 0 0 0 0 0 1 +977 1 974 1 +977 2 3 972 1 +977 3 974 1 0 1 +977 4 3 800 0 0 1 +977 5 974 11 0 0 0 1 +977 6 3 753 830 729 2 0 1 +977 7 974 7 0 0 0 0 0 1 +977 8 3 77 807 855 0 0 0 0 1 +977 9 974 740 450 0 0 0 0 0 0 1 +983 1 978 1 +983 2 5 981 1 +983 3 978 1 0 1 +983 4 5 567 5 0 1 +983 5 978 8 0 0 0 1 +983 6 5 228 296 849 2 0 1 +983 7 978 3 0 0 0 0 0 1 +983 8 5 530 276 738 7 0 0 0 1 +983 9 978 87 858 0 0 0 0 0 0 1 +991 1 985 1 +991 2 6 989 1 +991 3 985 4 0 1 +991 4 6 794 10 0 1 +991 5 985 3 0 0 0 1 +991 6 6 278 855 637 0 0 1 +991 7 985 7 0 0 0 0 0 1 +991 8 6 234 786 941 15 0 0 0 1 +991 9 985 222 466 9 0 0 0 0 0 1 +997 1 990 1 +997 2 7 995 1 +997 3 990 2 0 1 +997 4 7 622 4 0 1 +997 5 990 10 0 0 0 1 +997 6 7 260 58 981 0 0 1 +997 7 990 1 0 0 0 0 0 1 +997 8 7 241 473 934 0 0 0 0 1 +997 9 990 616 732 39 0 0 0 0 0 1 +1009 1 998 1 +1009 2 11 1008 1 +1009 3 998 3 0 1 +1009 4 11 825 14 0 1 +1009 5 998 6 0 0 0 1 +1009 6 11 509 515 850 0 0 1 +1009 7 998 1 0 0 0 0 0 1 +1009 9 998 627 634 2 0 0 0 0 0 1 +1013 1 1010 1 +1013 2 3 1006 1 +1013 3 1010 7 0 1 +1013 4 3 728 2 0 1 +1013 5 1010 12 0 0 0 1 +1013 6 3 319 230 17 2 0 1 +1013 7 1010 7 0 0 0 0 0 1 +1013 9 1010 451 396 9 0 0 0 0 0 1 +1019 1 1017 1 +1019 2 2 1015 1 +1019 3 1017 3 0 1 +1019 4 2 964 8 0 1 +1019 5 1017 3 0 0 0 1 +1019 6 2 384 359 996 1 0 1 +1019 7 1017 9 0 0 0 0 0 1 +1019 9 1017 549 971 0 0 0 0 0 0 1 +1021 1 1011 1 +1021 2 10 1020 1 +1021 3 1011 3 0 1 +1021 4 10 936 3 0 1 +1021 5 1011 2 0 0 0 1 +1021 6 10 862 66 684 0 0 1 +1021 7 1011 1 0 0 0 0 0 1 +1021 9 1011 628 395 2 0 0 0 0 0 1 +1031 1 1017 1 +1031 2 14 1029 1 +1031 3 1017 4 0 1 +1031 4 14 864 3 0 1 +1031 5 1017 7 0 0 0 1 +1031 6 14 327 378 721 4 0 1 +1031 7 1017 1 0 0 0 0 0 1 +1031 9 1017 158 823 5 0 0 0 0 0 1 +1033 1 1028 1 +1033 2 5 1030 1 +1033 3 1028 2 0 1 +1033 4 5 986 16 0 1 +1033 5 1028 9 0 0 0 1 +1033 6 5 204 680 697 0 0 1 +1033 7 1028 13 0 0 0 0 0 1 +1033 9 1028 331 447 11 0 0 0 0 0 1 +1039 1 1036 1 +1039 2 3 1033 1 +1039 3 1036 3 0 1 +1039 4 3 800 7 0 1 +1039 5 1036 1 0 0 0 1 +1039 6 3 703 447 1025 0 0 1 +1039 7 1036 1 0 0 0 0 0 1 +1039 9 1036 17 930 5 0 0 0 0 0 1 +1049 1 1046 1 +1049 2 3 1038 1 +1049 3 1046 1 0 1 +1049 4 3 929 4 0 1 +1049 5 1046 1 0 0 0 1 +1049 6 3 616 685 338 3 0 1 +1049 7 1046 13 0 0 0 0 0 1 +1049 9 1046 330 422 5 0 0 0 0 0 1 +1051 1 1044 1 +1051 2 7 1049 1 +1051 3 1044 2 0 1 +1051 4 7 994 6 0 1 +1051 5 1044 8 0 0 0 1 +1051 6 7 335 627 680 0 0 1 +1051 7 1044 3 0 0 0 0 0 1 +1051 9 1044 736 789 13 0 0 0 0 0 1 +1061 1 1059 1 +1061 2 2 1057 1 +1061 3 1059 2 0 1 +1061 4 2 649 6 0 1 +1061 5 1059 11 0 0 0 1 +1061 6 2 95 552 875 1 0 1 +1061 7 1059 5 0 0 0 0 0 1 +1061 9 1059 180 187 10 0 0 0 0 0 1 +1063 1 1060 1 +1063 2 3 1062 1 +1063 3 1060 3 0 1 +1063 4 3 628 2 0 1 +1063 5 1060 3 0 0 0 1 +1063 6 3 379 917 483 0 0 1 +1063 7 1060 8 0 0 0 0 0 1 +1063 9 1060 429 979 3 0 0 0 0 0 1 +1069 1 1063 1 +1069 2 6 1065 1 +1069 3 1063 2 0 1 +1069 4 6 1065 6 0 1 +1069 5 1063 2 0 0 0 1 +1069 6 6 497 137 686 0 0 1 +1069 7 1063 4 0 0 0 0 0 1 +1069 9 1063 452 896 4 0 0 0 0 0 1 +1087 1 1084 1 +1087 2 3 1085 1 +1087 3 1084 6 0 1 +1087 4 3 1079 10 0 1 +1087 5 1084 23 0 0 0 1 +1087 6 3 795 168 171 4 0 1 +1087 7 1084 1 0 0 0 0 0 1 +1087 9 1084 58 941 5 0 0 0 0 0 1 +1091 1 1089 1 +1091 2 2 1090 1 +1091 3 1089 3 0 1 +1091 4 2 947 2 0 1 +1091 5 1089 2 0 0 0 1 +1091 6 2 93 72 774 2 0 1 +1091 7 1089 2 0 0 0 0 0 1 +1091 9 1089 1053 784 0 0 0 0 0 0 1 +1093 1 1088 1 +1093 2 5 1092 1 +1093 3 1088 3 0 1 +1093 4 5 988 6 0 1 +1093 5 1088 7 0 0 0 1 +1093 6 5 199 119 720 0 0 1 +1093 7 1088 5 0 0 0 0 0 1 +1093 9 1088 635 840 39 0 0 0 0 0 1 +1097 1 1094 1 +1097 2 3 1096 1 +1097 3 1094 1 0 1 +1097 4 3 987 4 0 1 +1097 5 1094 13 0 0 0 1 +1097 6 3 74 641 91 1 0 1 +1097 7 1094 1 0 0 0 0 0 1 +1097 9 1094 625 17 0 0 0 0 0 0 1 +1103 1 1098 1 +1103 2 5 1091 1 +1103 3 1098 6 0 1 +1103 4 5 819 2 0 1 +1103 5 1098 6 0 0 0 1 +1103 6 5 698 931 796 1 0 1 +1103 7 1098 23 0 0 0 0 0 1 +1103 9 1098 789 448 2 0 0 0 0 0 1 +1109 1 1107 1 +1109 2 2 1108 1 +1109 3 1107 3 0 1 +1109 4 2 1102 8 0 1 +1109 5 1107 2 0 0 0 1 +1109 6 2 86 1031 1004 1 0 1 +1109 7 1107 3 0 0 0 0 0 1 +1109 9 1107 684 1050 3 0 0 0 0 0 1 +1117 1 1115 1 +1117 2 2 1113 1 +1117 3 1115 4 0 1 +1117 4 2 856 6 0 1 +1117 5 1115 2 0 0 0 1 +1117 6 2 12 1014 996 0 0 1 +1117 7 1115 9 0 0 0 0 0 1 +1117 9 1115 14 815 2 0 0 0 0 0 1 +1123 1 1121 1 +1123 2 2 1122 1 +1123 3 1121 2 0 1 +1123 4 2 1116 8 0 1 +1123 5 1121 2 0 0 0 1 +1123 6 2 536 187 918 0 0 1 +1123 7 1121 3 0 0 0 0 0 1 +1123 9 1121 964 522 1 0 0 0 0 0 1 +1129 1 1118 1 +1129 2 11 1124 1 +1129 3 1118 3 0 1 +1129 4 11 916 16 0 1 +1129 5 1118 8 0 0 0 1 +1129 6 11 366 139 1122 2 0 1 +1129 7 1118 3 0 0 0 0 0 1 +1129 9 1118 885 669 14 0 0 0 0 0 1 +1151 1 1134 1 +1151 2 17 1148 1 +1151 3 1134 1 0 1 +1151 4 17 687 4 0 1 +1151 5 1134 1 0 0 0 1 +1151 6 17 490 331 594 1 0 1 +1151 7 1134 4 0 0 0 0 0 1 +1151 9 1134 789 953 1 0 0 0 0 0 1 +1153 1 1148 1 +1153 2 5 1152 1 +1153 3 1148 3 0 1 +1153 4 5 870 29 0 1 +1153 5 1148 1 0 0 0 1 +1153 6 5 656 903 254 0 0 1 +1153 7 1148 24 0 0 0 0 0 1 +1153 9 1148 473 991 3 0 0 0 0 0 1 +1163 1 1158 1 +1163 2 5 1161 1 +1163 3 1158 2 0 1 +1163 4 5 1159 3 0 1 +1163 5 1158 9 0 0 0 1 +1163 6 5 919 503 226 2 0 1 +1163 7 1158 1 0 0 0 0 0 1 +1163 9 1158 238 281 2 0 0 0 0 0 1 +1171 1 1169 1 +1171 2 2 1167 1 +1171 3 1169 2 0 1 +1171 4 2 1112 8 0 1 +1171 5 1169 2 0 0 0 1 +1171 6 2 1049 594 1042 0 0 1 +1171 7 1169 4 0 0 0 0 0 1 +1171 9 1169 1092 580 0 0 0 0 0 0 1 +1181 1 1174 1 +1181 2 7 1180 1 +1181 3 1174 1 0 1 +1181 4 7 706 3 0 1 +1181 5 1174 2 0 0 0 1 +1181 6 7 903 1129 989 2 0 1 +1181 7 1174 2 0 0 0 0 0 1 +1181 9 1174 628 75 6 0 0 0 0 0 1 +1187 1 1185 1 +1187 2 2 1181 1 +1187 3 1185 4 0 1 +1187 4 2 758 4 0 1 +1187 5 1185 5 0 0 0 1 +1187 6 2 324 472 882 2 0 1 +1187 7 1185 7 0 0 0 0 0 1 +1187 9 1185 699 213 4 0 0 0 0 0 1 +1193 1 1190 1 +1193 2 3 1187 1 +1193 3 1190 4 0 1 +1193 4 3 826 11 0 1 +1193 5 1190 11 0 0 0 1 +1193 6 3 148 475 1120 2 0 1 +1193 7 1190 15 0 0 0 0 0 1 +1193 9 1190 12 1185 3 0 0 0 0 0 1 +1201 1 1190 1 +1201 2 11 1192 1 +1201 3 1190 2 0 1 +1201 4 11 1006 20 0 1 +1201 5 1190 17 0 0 0 1 +1201 6 11 985 428 917 0 0 1 +1201 7 1190 6 0 0 0 0 0 1 +1201 9 1190 575 1090 0 0 0 0 0 0 1 +1213 1 1211 1 +1213 2 2 1209 1 +1213 3 1211 4 0 1 +1213 4 2 879 9 0 1 +1213 5 1211 6 0 0 0 1 +1213 6 2 72 125 608 0 0 1 +1213 7 1211 9 0 0 0 0 0 1 +1213 9 1211 1169 1122 5 0 0 0 0 0 1 +1217 1 1214 1 +1217 2 3 1211 1 +1217 3 1214 3 0 1 +1217 4 3 888 9 0 1 +1217 5 1214 3 0 0 0 1 +1217 6 3 1080 782 304 2 0 1 +1217 7 1214 1 0 0 0 0 0 1 +1217 9 1214 143 1200 0 0 0 0 0 0 1 +1223 1 1218 1 +1223 2 5 1220 1 +1223 3 1218 2 0 1 +1223 4 5 715 4 0 1 +1223 5 1218 2 0 0 0 1 +1223 6 5 761 50 1041 2 0 1 +1223 7 1218 8 0 0 0 0 0 1 +1223 9 1218 675 154 4 0 0 0 0 0 1 +1229 1 1227 1 +1229 2 2 1225 1 +1229 3 1227 3 0 1 +1229 4 2 1159 6 0 1 +1229 5 1227 7 0 0 0 1 +1229 6 2 400 1219 1216 1 0 1 +1229 7 1227 19 0 0 0 0 0 1 +1229 9 1227 953 983 0 0 0 0 0 0 1 +1231 1 1228 1 +1231 2 3 1229 1 +1231 3 1228 3 0 1 +1231 4 3 662 3 0 1 +1231 5 1228 5 0 0 0 1 +1231 6 3 1162 399 1152 0 0 1 +1231 7 1228 1 0 0 0 0 0 1 +1231 9 1228 85 1121 24 0 0 0 0 0 1 +1237 1 1235 1 +1237 2 2 1236 1 +1237 3 1235 4 0 1 +1237 4 2 960 6 0 1 +1237 5 1235 4 0 0 0 1 +1237 6 2 346 117 849 0 0 1 +1237 7 1235 22 0 0 0 0 0 1 +1237 9 1235 46 1163 10 0 0 0 0 0 1 +1249 1 1242 1 +1249 2 7 1246 1 +1249 3 1242 5 0 1 +1249 4 7 792 17 0 1 +1249 5 1242 1 0 0 0 1 +1249 6 7 439 679 474 0 0 1 +1249 7 1242 2 0 0 0 0 0 1 +1249 9 1242 240 1149 0 0 0 0 0 0 1 +1259 1 1257 1 +1259 2 2 1258 1 +1259 3 1257 3 0 1 +1259 4 2 1049 6 0 1 +1259 5 1257 5 0 0 0 1 +1259 6 2 1187 1008 1191 1 0 1 +1259 7 1257 5 0 0 0 0 0 1 +1259 9 1257 864 794 2 0 0 0 0 0 1 +1277 1 1275 1 +1277 2 2 1276 1 +1277 3 1275 2 0 1 +1277 4 2 753 4 0 1 +1277 5 1275 9 0 0 0 1 +1277 6 2 500 456 996 2 0 1 +1277 7 1275 20 0 0 0 0 0 1 +1277 9 1275 1270 428 0 0 0 0 0 0 1 +1279 1 1276 1 +1279 2 3 1277 1 +1279 3 1276 6 0 1 +1279 4 3 916 6 0 1 +1279 5 1276 4 0 0 0 1 +1279 6 3 871 896 159 0 0 1 +1279 7 1276 7 0 0 0 0 0 1 +1279 9 1276 336 1118 0 0 0 0 0 0 1 +1283 1 1281 1 +1283 2 2 1279 1 +1283 3 1281 3 0 1 +1283 4 2 672 8 0 1 +1283 5 1281 3 0 0 0 1 +1283 6 2 386 536 842 1 0 1 +1283 7 1281 2 0 0 0 0 0 1 +1283 9 1281 1259 1145 1 0 0 0 0 0 1 +1289 1 1283 1 +1289 2 6 1280 1 +1289 3 1283 6 0 1 +1289 4 6 1105 3 0 1 +1289 5 1283 16 0 0 0 1 +1289 6 6 314 308 1117 1 0 1 +1289 7 1283 4 0 0 0 0 0 1 +1289 9 1283 179 659 3 0 0 0 0 0 1 +1291 1 1289 1 +1291 2 2 1290 1 +1291 3 1289 5 0 1 +1291 4 2 899 6 0 1 +1291 5 1289 5 0 0 0 1 +1291 6 2 183 1164 1044 0 0 1 +1291 7 1289 4 0 0 0 0 0 1 +1291 9 1289 607 646 4 0 0 0 0 0 1 +1297 1 1287 1 +1297 2 10 1294 1 +1297 3 1287 2 0 1 +1297 4 10 807 8 0 1 +1297 5 1287 1 0 0 0 1 +1297 6 10 531 428 797 0 0 1 +1297 7 1287 2 0 0 0 0 0 1 +1297 9 1287 709 1093 6 0 0 0 0 0 1 +1301 1 1299 1 +1301 2 2 1295 1 +1301 3 1299 7 0 1 +1301 4 2 1152 3 0 1 +1301 5 1299 3 0 0 0 1 +1301 6 2 160 635 1068 1 0 1 +1301 7 1299 8 0 0 0 0 0 1 +1301 9 1299 1293 1108 10 0 0 0 0 0 1 +1303 1 1297 1 +1303 2 6 1302 1 +1303 3 1297 2 0 1 +1303 4 6 816 2 0 1 +1303 5 1297 2 0 0 0 1 +1303 6 6 1092 1278 1228 0 0 1 +1303 7 1297 4 0 0 0 0 0 1 +1303 9 1297 300 865 0 0 0 0 0 0 1 +1307 1 1305 1 +1307 2 2 1306 1 +1307 3 1305 2 0 1 +1307 4 2 844 4 0 1 +1307 5 1305 4 0 0 0 1 +1307 6 2 65 788 130 3 0 1 +1307 7 1305 6 0 0 0 0 0 1 +1307 9 1305 958 743 0 0 0 0 0 0 1 +1319 1 1306 1 +1319 2 13 1316 1 +1319 3 1306 1 0 1 +1319 4 13 1015 5 0 1 +1319 5 1306 2 0 0 0 1 +1319 6 13 576 1005 957 1 0 1 +1319 7 1306 6 0 0 0 0 0 1 +1319 9 1306 408 1211 0 0 0 0 0 0 1 +1321 1 1308 1 +1321 2 13 1320 1 +1321 3 1308 5 0 1 +1321 4 13 1223 8 0 1 +1321 5 1308 1 0 0 0 1 +1321 6 13 683 1020 1055 0 0 1 +1321 7 1308 6 0 0 0 0 0 1 +1321 9 1308 1130 1162 7 0 0 0 0 0 1 +1327 1 1324 1 +1327 2 3 1326 1 +1327 3 1324 1 0 1 +1327 4 3 724 2 0 1 +1327 5 1324 9 0 0 0 1 +1327 6 3 665 911 1208 0 0 1 +1327 7 1324 4 0 0 0 0 0 1 +1327 9 1324 1153 605 12 0 0 0 0 0 1 +1361 1 1358 1 +1361 2 3 1355 1 +1361 3 1358 13 0 1 +1361 4 3 1349 0 0 1 +1361 5 1358 29 0 0 0 1 +1361 6 3 124 977 824 1 0 1 +1361 7 1358 22 0 0 0 0 0 1 +1361 9 1358 164 34 3 0 0 0 0 0 1 +1367 1 1362 1 +1367 2 5 1365 1 +1367 3 1362 1 0 1 +1367 4 5 1022 8 0 1 +1367 5 1362 2 0 0 0 1 +1367 6 5 1108 514 507 2 0 1 +1367 7 1362 8 0 0 0 0 0 1 +1367 9 1362 407 1250 3 0 0 0 0 0 1 +1373 1 1371 1 +1373 2 2 1365 1 +1373 3 1371 7 0 1 +1373 4 2 1269 11 0 1 +1373 5 1371 2 0 0 0 1 +1373 6 2 1177 567 874 2 0 1 +1373 7 1371 9 0 0 0 0 0 1 +1373 9 1371 104 1202 3 0 0 0 0 0 1 +1381 1 1379 1 +1381 2 2 1377 1 +1381 3 1379 4 0 1 +1381 4 2 1307 10 0 1 +1381 5 1379 2 0 0 0 1 +1381 6 2 746 1373 168 1 0 1 +1381 7 1379 12 0 0 0 0 0 1 +1381 9 1379 723 970 15 0 0 0 0 0 1 +1399 1 1386 1 +1399 2 13 1395 1 +1399 3 1386 3 0 1 +1399 4 13 964 14 0 1 +1399 5 1386 28 0 0 0 1 +1399 6 13 1222 533 1164 0 0 1 +1399 7 1386 5 0 0 0 0 0 1 +1399 9 1386 111 696 8 0 0 0 0 0 1 +1409 1 1406 1 +1409 2 3 1404 1 +1409 3 1406 1 0 1 +1409 4 3 968 2 0 1 +1409 5 1406 10 0 0 0 1 +1409 6 3 156 1165 624 1 0 1 +1409 7 1406 40 0 0 0 0 0 1 +1409 9 1406 55 778 1 0 0 0 0 0 1 +1423 1 1420 1 +1423 2 3 1421 1 +1423 3 1420 7 0 1 +1423 4 3 1419 4 0 1 +1423 5 1420 10 0 0 0 1 +1423 6 3 169 1041 1357 2 0 1 +1423 7 1420 4 0 0 0 0 0 1 +1423 9 1420 730 830 21 0 0 0 0 0 1 +1427 1 1425 1 +1427 2 2 1426 1 +1427 3 1425 2 0 1 +1427 4 2 1089 13 0 1 +1427 5 1425 21 0 0 0 1 +1427 6 2 770 1252 250 5 0 1 +1427 7 1425 10 0 0 0 0 0 1 +1427 9 1425 1056 747 1 0 0 0 0 0 1 +1429 1 1423 1 +1429 2 6 1425 1 +1429 3 1423 2 0 1 +1429 4 6 1425 6 0 1 +1429 5 1423 12 0 0 0 1 +1429 6 6 1301 716 1226 1 0 1 +1429 7 1423 2 0 0 0 0 0 1 +1429 9 1423 469 1214 1 0 0 0 0 0 1 +1433 1 1430 1 +1433 2 3 1420 1 +1433 3 1430 19 0 1 +1433 4 3 883 3 0 1 +1433 5 1430 12 0 0 0 1 +1433 6 3 74 937 1421 1 0 1 +1433 7 1430 28 0 0 0 0 0 1 +1433 9 1430 283 456 0 0 0 0 0 0 1 +1439 1 1432 1 +1439 2 7 1438 1 +1439 3 1432 7 0 1 +1439 4 7 1430 4 0 1 +1439 5 1432 2 0 0 0 1 +1439 6 7 1336 31 1267 1 0 1 +1439 7 1432 9 0 0 0 0 0 1 +1439 9 1432 451 1118 0 0 0 0 0 0 1 +1447 1 1444 1 +1447 2 3 1446 1 +1447 3 1444 3 0 1 +1447 4 3 909 5 0 1 +1447 5 1444 6 0 0 0 1 +1447 6 3 1246 33 430 0 0 1 +1447 7 1444 1 0 0 0 0 0 1 +1447 9 1444 750 1300 10 0 0 0 0 0 1 +1451 1 1449 1 +1451 2 2 1446 1 +1451 3 1449 9 0 1 +1451 4 2 759 3 0 1 +1451 5 1449 20 0 0 0 1 +1451 6 2 1094 208 615 6 0 1 +1451 7 1449 5 0 0 0 0 0 1 +1451 9 1449 15 193 2 0 0 0 0 0 1 +1453 1 1451 1 +1453 2 2 1449 1 +1453 3 1451 6 0 1 +1453 4 2 1368 9 0 1 +1453 5 1451 4 0 0 0 1 +1453 6 2 1441 1435 1449 0 0 1 +1453 7 1451 15 0 0 0 0 0 1 +1453 9 1451 23 1381 6 0 0 0 0 0 1 +1459 1 1456 1 +1459 2 3 1458 1 +1459 3 1456 3 0 1 +1459 4 3 855 7 0 1 +1459 5 1456 21 0 0 0 1 +1459 6 3 406 1309 629 0 0 1 +1459 7 1456 10 0 0 0 0 0 1 +1459 9 1456 73 1115 2 0 0 0 0 0 1 +1471 1 1465 1 +1471 2 6 1470 1 +1471 3 1465 1 0 1 +1471 4 6 1287 2 0 1 +1471 5 1465 3 0 0 0 1 +1471 6 6 1228 728 969 0 0 1 +1471 7 1465 2 0 0 0 0 0 1 +1471 9 1465 1362 599 34 0 0 0 0 0 1 +1481 1 1478 1 +1481 2 3 1480 1 +1481 3 1478 5 0 1 +1481 4 3 1372 4 0 1 +1481 5 1478 17 0 0 0 1 +1481 6 3 1021 855 1436 1 0 1 +1481 7 1478 12 0 0 0 0 0 1 +1481 9 1478 968 651 4 0 0 0 0 0 1 +1483 1 1481 1 +1483 2 2 1482 1 +1483 3 1481 2 0 1 +1483 4 2 1170 14 0 1 +1483 5 1481 3 0 0 0 1 +1483 6 2 541 996 1168 0 0 1 +1483 7 1481 11 0 0 0 0 0 1 +1483 9 1481 1452 1464 7 0 0 0 0 0 1 +1487 1 1482 1 +1487 2 5 1485 1 +1487 3 1482 2 0 1 +1487 4 5 1483 3 0 1 +1487 5 1482 11 0 0 0 1 +1487 6 5 1289 808 1194 1 0 1 +1487 7 1482 11 0 0 0 0 0 1 +1487 9 1482 866 1283 9 0 0 0 0 0 1 +1489 1 1475 1 +1489 2 14 1487 1 +1489 3 1475 2 0 1 +1489 4 14 1299 9 0 1 +1489 5 1475 2 0 0 0 1 +1489 6 14 1485 269 254 0 0 1 +1489 7 1475 1 0 0 0 0 0 1 +1489 9 1475 61 1192 7 0 0 0 0 0 1 +1493 1 1491 1 +1493 2 2 1485 1 +1493 3 1491 11 0 1 +1493 4 2 1120 3 0 1 +1493 5 1491 5 0 0 0 1 +1493 6 2 102 499 465 1 0 1 +1493 7 1491 3 0 0 0 0 0 1 +1493 9 1491 701 1377 0 0 0 0 0 0 1 +1499 1 1497 1 +1499 2 2 1495 1 +1499 3 1497 2 0 1 +1499 4 2 1270 7 0 1 +1499 5 1497 6 0 0 0 1 +1499 6 2 844 588 698 1 0 1 +1499 7 1497 2 0 0 0 0 0 1 +1499 9 1497 1196 1357 7 0 0 0 0 0 1 +1511 1 1500 1 +1511 2 11 1509 1 +1511 3 1500 2 0 1 +1511 4 11 1433 3 0 1 +1511 5 1500 5 0 0 0 1 +1511 6 11 1032 1278 106 1 0 1 +1511 7 1500 16 0 0 0 0 0 1 +1511 9 1500 403 142 7 0 0 0 0 0 1 +1523 1 1521 1 +1523 2 2 1518 1 +1523 3 1521 7 0 1 +1523 4 2 1123 0 0 1 +1523 5 1521 4 0 0 0 1 +1523 6 2 1226 1518 67 1 0 1 +1523 7 1521 28 0 0 0 0 0 1 +1523 9 1521 1286 573 1 0 0 0 0 0 1 +1531 1 1529 1 +1531 2 2 1530 1 +1531 3 1529 6 0 1 +1531 4 2 948 2 0 1 +1531 5 1529 3 0 0 0 1 +1531 6 2 827 122 1129 3 0 1 +1531 7 1529 2 0 0 0 0 0 1 +1531 9 1529 314 1400 7 0 0 0 0 0 1 +1543 1 1538 1 +1543 2 5 1541 1 +1543 3 1538 2 0 1 +1543 4 5 1539 3 0 1 +1543 5 1538 15 0 0 0 1 +1543 6 5 796 1363 1391 0 0 1 +1543 7 1538 5 0 0 0 0 0 1 +1543 9 1538 132 1157 7 0 0 0 0 0 1 +1549 1 1547 1 +1549 2 2 1541 1 +1549 3 1547 5 0 1 +1549 4 2 1336 0 0 1 +1549 5 1547 5 0 0 0 1 +1549 6 2 1191 987 1422 0 0 1 +1549 7 1547 3 0 0 0 0 0 1 +1549 9 1547 311 1322 9 0 0 0 0 0 1 +1553 1 1550 1 +1553 2 3 1552 1 +1553 3 1550 1 0 1 +1553 4 3 1330 4 0 1 +1553 5 1550 9 0 0 0 1 +1553 6 3 804 1242 904 2 0 1 +1553 7 1550 8 0 0 0 0 0 1 +1553 9 1550 1399 643 0 0 0 0 0 0 1 +1559 1 1540 1 +1559 2 19 1558 1 +1559 3 1540 3 0 1 +1559 4 19 1107 2 0 1 +1559 5 1540 1 0 0 0 1 +1559 6 19 1236 514 1237 1 0 1 +1559 7 1540 2 0 0 0 0 0 1 +1559 9 1540 1473 514 3 0 0 0 0 0 1 +1567 1 1564 1 +1567 2 3 1565 1 +1567 3 1564 4 0 1 +1567 4 3 1563 4 0 1 +1567 5 1564 6 0 0 0 1 +1567 6 3 988 1370 855 0 0 1 +1567 7 1564 18 0 0 0 0 0 1 +1567 9 1564 278 1384 5 0 0 0 0 0 1 +1571 1 1569 1 +1571 2 2 1570 1 +1571 3 1569 3 0 1 +1571 4 2 838 2 0 1 +1571 5 1569 17 0 0 0 1 +1571 6 2 1460 986 1541 1 0 1 +1571 7 1569 7 0 0 0 0 0 1 +1571 9 1569 113 601 6 0 0 0 0 0 1 +1579 1 1576 1 +1579 2 3 1578 1 +1579 3 1576 11 0 1 +1579 4 3 1447 6 0 1 +1579 5 1576 8 0 0 0 1 +1579 6 3 234 358 1245 0 0 1 +1579 7 1576 1 0 0 0 0 0 1 +1579 9 1576 666 1226 0 0 0 0 0 0 1 +1583 1 1578 1 +1583 2 5 1581 1 +1583 3 1578 1 0 1 +1583 4 5 1579 3 0 1 +1583 5 1578 2 0 0 0 1 +1583 6 5 466 898 271 1 0 1 +1583 7 1578 7 0 0 0 0 0 1 +1583 9 1578 719 1438 1 0 0 0 0 0 1 +1597 1 1586 1 +1597 2 11 1594 1 +1597 3 1586 5 0 1 +1597 4 11 1270 1 0 1 +1597 5 1586 2 0 0 0 1 +1597 6 11 567 200 793 0 0 1 +1597 7 1586 11 0 0 0 0 0 1 +1597 9 1586 611 1205 9 0 0 0 0 0 1 +1601 1 1598 1 +1601 2 3 1600 1 +1601 3 1598 15 0 1 +1601 4 3 962 7 0 1 +1601 5 1598 5 0 0 0 1 +1601 6 3 830 956 296 2 0 1 +1601 7 1598 1 0 0 0 0 0 1 +1601 9 1598 1120 603 5 0 0 0 0 0 1 +1607 1 1602 1 +1607 2 5 1605 1 +1607 3 1602 3 0 1 +1607 4 5 1595 11 0 1 +1607 5 1602 26 0 0 0 1 +1607 6 5 1182 923 203 1 0 1 +1607 7 1602 2 0 0 0 0 0 1 +1607 9 1602 508 1279 1 0 0 0 0 0 1 +1609 1 1602 1 +1609 2 7 1597 1 +1609 3 1602 4 0 1 +1609 4 7 1277 5 0 1 +1609 5 1602 8 0 0 0 1 +1609 6 7 490 1348 872 0 0 1 +1609 7 1602 2 0 0 0 0 0 1 +1609 9 1602 518 1578 7 0 0 0 0 0 1 +1613 1 1610 1 +1613 2 3 1606 1 +1613 3 1610 4 0 1 +1613 4 3 1279 0 0 1 +1613 5 1610 14 0 0 0 1 +1613 6 3 812 1085 1532 2 0 1 +1613 7 1610 10 0 0 0 0 0 1 +1613 9 1610 734 563 5 0 0 0 0 0 1 +1619 1 1617 1 +1619 2 2 1615 1 +1619 3 1617 2 0 1 +1619 4 2 1410 8 0 1 +1619 5 1617 3 0 0 0 1 +1619 6 2 20 1190 330 1 0 1 +1619 7 1617 6 0 0 0 0 0 1 +1619 9 1617 277 281 9 0 0 0 0 0 1 +1621 1 1619 1 +1621 2 2 1617 1 +1621 3 1619 4 0 1 +1621 4 2 957 6 0 1 +1621 5 1619 3 0 0 0 1 +1621 6 2 1208 679 1337 0 0 1 +1621 7 1619 13 0 0 0 0 0 1 +1621 9 1619 3 1605 5 0 0 0 0 0 1 +1627 1 1624 1 +1627 2 3 1622 1 +1627 3 1624 1 0 1 +1627 4 3 1176 3 0 1 +1627 5 1624 5 0 0 0 1 +1627 6 3 1257 265 1071 0 0 1 +1627 7 1624 11 0 0 0 0 0 1 +1627 9 1624 398 1354 0 0 0 0 0 0 1 +1637 1 1635 1 +1637 2 2 1633 1 +1637 3 1635 2 0 1 +1637 4 2 864 1 0 1 +1637 5 1635 4 0 0 0 1 +1637 6 2 1387 1455 1448 1 0 1 +1637 7 1635 7 0 0 0 0 0 1 +1637 9 1635 1263 1123 5 0 0 0 0 0 1 +1657 1 1646 1 +1657 2 11 1655 1 +1657 3 1646 1 0 1 +1657 4 11 915 13 0 1 +1657 5 1646 8 0 0 0 1 +1657 6 11 692 904 988 2 0 1 +1657 7 1646 7 0 0 0 0 0 1 +1657 9 1646 1018 956 7 0 0 0 0 0 1 +1663 1 1660 1 +1663 2 3 1662 1 +1663 3 1660 3 0 1 +1663 4 3 1534 2 0 1 +1663 5 1660 4 0 0 0 1 +1663 6 3 1371 1128 1471 0 0 1 +1663 7 1660 10 0 0 0 0 0 1 +1663 9 1660 559 1500 19 0 0 0 0 0 1 +1667 1 1665 1 +1667 2 2 1663 1 +1667 3 1665 3 0 1 +1667 4 2 1267 8 0 1 +1667 5 1665 9 0 0 0 1 +1667 6 2 255 1656 1508 1 0 1 +1667 7 1665 3 0 0 0 0 0 1 +1667 9 1665 1126 602 1 0 0 0 0 0 1 +1669 1 1667 1 +1669 2 2 1665 1 +1669 3 1667 4 0 1 +1669 4 2 880 6 0 1 +1669 5 1667 8 0 0 0 1 +1669 6 2 163 99 1328 0 0 1 +1669 7 1667 4 0 0 0 0 0 1 +1669 9 1667 852 689 6 0 0 0 0 0 1 +1693 1 1691 1 +1693 2 2 1692 1 +1693 3 1691 2 0 1 +1693 4 2 1539 3 0 1 +1693 5 1691 3 0 0 0 1 +1693 6 2 422 793 1299 0 0 1 +1693 7 1691 11 0 0 0 0 0 1 +1693 9 1691 242 1558 10 0 0 0 0 0 1 +1697 1 1694 1 +1697 2 3 1692 1 +1697 3 1694 3 0 1 +1697 4 3 1208 17 0 1 +1697 5 1694 15 0 0 0 1 +1697 6 3 22 42 1228 1 0 1 +1697 7 1694 3 0 0 0 0 0 1 +1697 9 1694 806 255 3 0 0 0 0 0 1 +1699 1 1696 1 +1699 2 3 1686 1 +1699 3 1696 3 0 1 +1699 4 3 1506 3 0 1 +1699 5 1696 13 0 0 0 1 +1699 6 3 99 299 590 0 0 1 +1699 7 1696 1 0 0 0 0 0 1 +1699 9 1696 855 1498 22 0 0 0 0 0 1 +1709 1 1706 1 +1709 2 3 1696 1 +1709 3 1706 1 0 1 +1709 4 3 1199 0 0 1 +1709 5 1706 5 0 0 0 1 +1709 6 3 176 1012 1460 1 0 1 +1709 7 1706 6 0 0 0 0 0 1 +1709 9 1706 188 658 3 0 0 0 0 0 1 +1721 1 1718 1 +1721 2 3 1716 1 +1721 3 1718 3 0 1 +1721 4 3 1662 2 0 1 +1721 5 1718 5 0 0 0 1 +1721 6 3 1363 1406 424 1 0 1 +1721 7 1718 11 0 0 0 0 0 1 +1721 9 1718 182 1597 6 0 0 0 0 0 1 +1723 1 1720 1 +1723 2 3 1722 1 +1723 3 1720 1 0 1 +1723 4 3 1046 2 0 1 +1723 5 1720 1 0 0 0 1 +1723 6 3 79 102 1250 2 0 1 +1723 7 1720 13 0 0 0 0 0 1 +1723 9 1720 331 1513 1 0 0 0 0 0 1 +1733 1 1731 1 +1733 2 2 1726 1 +1733 3 1731 16 0 1 +1733 4 2 1072 2 0 1 +1733 5 1731 9 0 0 0 1 +1733 6 2 1679 69 1638 1 0 1 +1733 7 1731 7 0 0 0 0 0 1 +1733 9 1731 1640 728 1 0 0 0 0 0 1 +1741 1 1739 1 +1741 2 2 1740 1 +1741 3 1739 5 0 1 +1741 4 2 1477 9 0 1 +1741 5 1739 17 0 0 0 1 +1741 6 2 1515 1720 1643 0 0 1 +1741 7 1739 25 0 0 0 0 0 1 +1741 9 1739 169 868 4 0 0 0 0 0 1 +1747 1 1745 1 +1747 2 2 1743 1 +1747 3 1745 5 0 1 +1747 4 2 1426 8 0 1 +1747 5 1745 6 0 0 0 1 +1747 6 2 1284 142 545 1 0 1 +1747 7 1745 4 0 0 0 0 0 1 +1747 9 1745 1407 1329 2 0 0 0 0 0 1 +1753 1 1746 1 +1753 2 7 1746 1 +1753 3 1746 1 0 1 +1753 4 7 951 14 0 1 +1753 5 1746 1 0 0 0 1 +1753 6 7 1199 1699 1534 0 0 1 +1753 7 1746 2 0 0 0 0 0 1 +1753 9 1746 639 1196 25 0 0 0 0 0 1 +1759 1 1753 1 +1759 2 6 1757 1 +1759 3 1753 3 0 1 +1759 4 6 1144 4 0 1 +1759 5 1753 6 0 0 0 1 +1759 6 6 1665 1526 1332 0 0 1 +1759 7 1753 16 0 0 0 0 0 1 +1759 9 1753 212 1720 0 0 0 0 0 0 1 +1777 1 1772 1 +1777 2 5 1774 1 +1777 3 1772 2 0 1 +1777 4 5 1224 18 0 1 +1777 5 1772 1 0 0 0 1 +1777 6 5 74 792 1744 0 0 1 +1777 7 1772 19 0 0 0 0 0 1 +1777 9 1772 731 1365 11 0 0 0 0 0 1 +1783 1 1773 1 +1783 2 10 1782 1 +1783 3 1773 6 0 1 +1783 4 10 1380 5 0 1 +1783 5 1773 8 0 0 0 1 +1783 6 10 1263 639 1202 1 0 1 +1783 7 1773 4 0 0 0 0 0 1 +1783 9 1773 920 1652 17 0 0 0 0 0 1 +1787 1 1785 1 +1787 2 2 1783 1 +1787 3 1785 8 0 1 +1787 4 2 1086 7 0 1 +1787 5 1785 13 0 0 0 1 +1787 6 2 911 1515 794 1 0 1 +1787 7 1785 7 0 0 0 0 0 1 +1787 9 1785 1703 1616 1 0 0 0 0 0 1 +1789 1 1783 1 +1789 2 6 1781 1 +1789 3 1783 1 0 1 +1789 4 6 1599 0 0 1 +1789 5 1783 3 0 0 0 1 +1789 6 6 1091 771 688 0 0 1 +1789 7 1783 33 0 0 0 0 0 1 +1789 9 1783 212 734 11 0 0 0 0 0 1 +1801 1 1790 1 +1801 2 11 1796 1 +1801 3 1790 1 0 1 +1801 4 11 1782 24 0 1 +1801 5 1790 1 0 0 0 1 +1801 6 11 1504 636 1791 0 0 1 +1801 7 1790 6 0 0 0 0 0 1 +1801 9 1790 787 1424 9 0 0 0 0 0 1 +1811 1 1805 1 +1811 2 6 1809 1 +1811 3 1805 3 0 1 +1811 4 6 1396 11 0 1 +1811 5 1805 3 0 0 0 1 +1811 6 6 1516 1210 364 1 0 1 +1811 7 1805 12 0 0 0 0 0 1 +1811 9 1805 1098 1569 4 0 0 0 0 0 1 +1823 1 1818 1 +1823 2 5 1822 1 +1823 3 1818 1 0 1 +1823 4 5 1574 2 0 1 +1823 5 1818 9 0 0 0 1 +1823 6 5 555 751 1442 1 0 1 +1823 7 1818 31 0 0 0 0 0 1 +1823 9 1818 1245 1010 1 0 0 0 0 0 1 +1831 1 1828 1 +1831 2 3 1829 1 +1831 3 1828 10 0 1 +1831 4 3 1827 4 0 1 +1831 5 1828 1 0 0 0 1 +1831 6 3 534 187 1679 0 0 1 +1831 7 1828 9 0 0 0 0 0 1 +1831 9 1828 1123 818 1 0 0 0 0 0 1 +1847 1 1842 1 +1847 2 5 1845 1 +1847 3 1842 2 0 1 +1847 4 5 1150 5 0 1 +1847 5 1842 2 0 0 0 1 +1847 6 5 844 477 1225 1 0 1 +1847 7 1842 2 0 0 0 0 0 1 +1847 9 1842 846 815 0 0 0 0 0 0 1 +1861 1 1859 1 +1861 2 2 1860 1 +1861 3 1859 4 0 1 +1861 4 2 1641 3 0 1 +1861 5 1859 15 0 0 0 1 +1861 6 2 515 862 1352 1 0 1 +1861 7 1859 12 0 0 0 0 0 1 +1861 9 1859 64 776 4 0 0 0 0 0 1 +1867 1 1865 1 +1867 2 2 1866 1 +1867 3 1865 2 0 1 +1867 4 2 1297 7 0 1 +1867 5 1865 5 0 0 0 1 +1867 6 2 323 1719 924 0 0 1 +1867 7 1865 6 0 0 0 0 0 1 +1867 9 1865 1336 1826 3 0 0 0 0 0 1 +1871 1 1857 1 +1871 2 14 1869 1 +1871 3 1857 1 0 1 +1871 4 14 1486 10 0 1 +1871 5 1857 7 0 0 0 1 +1871 6 14 1351 593 903 1 0 1 +1871 7 1857 12 0 0 0 0 0 1 +1871 9 1857 1116 1627 4 0 0 0 0 0 1 +1873 1 1863 1 +1873 2 10 1870 1 +1873 3 1863 4 0 1 +1873 4 10 1796 13 0 1 +1873 5 1863 7 0 0 0 1 +1873 6 10 708 47 487 0 0 1 +1873 7 1863 2 0 0 0 0 0 1 +1873 9 1863 1667 1056 10 0 0 0 0 0 1 +1877 1 1875 1 +1877 2 2 1873 1 +1877 3 1875 3 0 1 +1877 4 2 1329 6 0 1 +1877 5 1875 6 0 0 0 1 +1877 6 2 877 362 1792 1 0 1 +1877 7 1875 6 0 0 0 0 0 1 +1877 9 1875 1677 1840 3 0 0 0 0 0 1 +1879 1 1873 1 +1879 2 6 1877 1 +1879 3 1873 3 0 1 +1879 4 6 1690 3 0 1 +1879 5 1873 9 0 0 0 1 +1879 6 6 1098 870 1781 0 0 1 +1879 7 1873 9 0 0 0 0 0 1 +1879 9 1873 850 1570 25 0 0 0 0 0 1 +1889 1 1886 1 +1889 2 3 1883 1 +1889 3 1886 6 0 1 +1889 4 3 1877 0 0 1 +1889 5 1886 18 0 0 0 1 +1889 6 3 822 364 26 1 0 1 +1889 7 1886 15 0 0 0 0 0 1 +1889 9 1886 1877 991 6 0 0 0 0 0 1 +1901 1 1899 1 +1901 2 2 1896 1 +1901 3 1899 2 0 1 +1901 4 2 1198 8 0 1 +1901 5 1899 4 0 0 0 1 +1901 6 2 467 1830 952 1 0 1 +1901 7 1899 13 0 0 0 0 0 1 +1901 9 1899 157 1755 1 0 0 0 0 0 1 +1907 1 1905 1 +1907 2 2 1906 1 +1907 3 1905 2 0 1 +1907 4 2 1800 2 0 1 +1907 5 1905 3 0 0 0 1 +1907 6 2 1237 383 1019 4 0 1 +1907 7 1905 2 0 0 0 0 0 1 +1907 9 1905 1122 572 0 0 0 0 0 0 1 +1913 1 1910 1 +1913 2 3 1908 1 +1913 3 1910 4 0 1 +1913 4 3 1815 2 0 1 +1913 5 1910 3 0 0 0 1 +1913 6 3 1407 956 1266 1 0 1 +1913 7 1910 14 0 0 0 0 0 1 +1913 9 1910 1499 1049 4 0 0 0 0 0 1 +1931 1 1929 1 +1931 2 2 1927 1 +1931 3 1929 3 0 1 +1931 4 2 1239 7 0 1 +1931 5 1929 9 0 0 0 1 +1931 6 2 786 504 729 1 0 1 +1931 7 1929 9 0 0 0 0 0 1 +1931 9 1929 939 1464 4 0 0 0 0 0 1 +1933 1 1928 1 +1933 2 5 1932 1 +1933 3 1928 5 0 1 +1933 4 5 1144 6 0 1 +1933 5 1928 6 0 0 0 1 +1933 6 5 86 834 950 3 0 1 +1933 7 1928 14 0 0 0 0 0 1 +1933 9 1928 816 1400 0 0 0 0 0 0 1 +1949 1 1947 1 +1949 2 2 1948 1 +1949 3 1947 9 0 1 +1949 4 2 1024 3 0 1 +1949 5 1947 4 0 0 0 1 +1949 6 2 454 100 1846 1 0 1 +1949 7 1947 2 0 0 0 0 0 1 +1949 9 1947 0 1216 2 0 0 0 0 0 1 +1951 1 1948 1 +1951 2 3 1949 1 +1951 3 1948 9 0 1 +1951 4 3 1034 3 0 1 +1951 5 1948 10 0 0 0 1 +1951 6 3 598 1950 1542 0 0 1 +1951 7 1948 11 0 0 0 0 0 1 +1951 9 1948 1119 702 4 0 0 0 0 0 1 +1973 1 1971 1 +1973 2 2 1972 1 +1973 3 1971 2 0 1 +1973 4 2 1505 4 0 1 +1973 5 1971 6 0 0 0 1 +1973 6 2 1421 1641 85 4 0 1 +1973 7 1971 3 0 0 0 0 0 1 +1973 9 1971 818 1438 0 0 0 0 0 0 1 +1979 1 1977 1 +1979 2 2 1975 1 +1979 3 1977 3 0 1 +1979 4 2 1748 13 0 1 +1979 5 1977 2 0 0 0 1 +1979 6 2 315 1590 1945 1 0 1 +1979 7 1977 11 0 0 0 0 0 1 +1979 9 1977 416 823 3 0 0 0 0 0 1 +1987 1 1985 1 +1987 2 2 1986 1 +1987 3 1985 2 0 1 +1987 4 2 1727 7 0 1 +1987 5 1985 2 0 0 0 1 +1987 6 2 478 208 981 0 0 1 +1987 7 1985 6 0 0 0 0 0 1 +1987 9 1985 1084 1883 2 0 0 0 0 0 1 +1993 1 1988 1 +1993 2 5 1990 1 +1993 3 1988 2 0 1 +1993 4 5 1078 18 0 1 +1993 5 1988 12 0 0 0 1 +1993 6 5 1873 75 1750 0 0 1 +1993 7 1988 5 0 0 0 0 0 1 +1993 9 1988 1102 1671 40 0 0 0 0 0 1 +1997 1 1995 1 +1997 2 2 1993 1 +1997 3 1995 3 0 1 +1997 4 2 1836 9 0 1 +1997 5 1995 3 0 0 0 1 +1997 6 2 1168 326 1724 1 0 1 +1997 7 1995 4 0 0 0 0 0 1 +1997 9 1995 1081 1712 3 0 0 0 0 0 1 +1999 1 1996 1 +1999 2 3 1998 1 +1999 3 1996 1 0 1 +1999 4 3 1177 3 0 1 +1999 5 1996 1 0 0 0 1 +1999 6 3 1171 423 1114 0 0 1 +1999 7 1996 1 0 0 0 0 0 1 +1999 9 1996 651 1798 7 0 0 0 0 0 1 +2003 1 1998 1 +2003 2 5 2002 1 +2003 3 1998 7 0 1 +2003 4 5 1333 13 0 1 +2003 5 1998 3 0 0 0 1 +2003 6 5 350 1856 1981 2 0 1 +2003 7 1998 6 0 0 0 0 0 1 +2003 9 1998 1532 353 3 0 0 0 0 0 1 +2011 1 2008 1 +2011 2 3 2004 1 +2011 3 2008 3 0 1 +2011 4 3 1947 5 0 1 +2011 5 2008 6 0 0 0 1 +2011 6 3 1530 1650 1233 0 0 1 +2011 7 2008 3 0 0 0 0 0 1 +2011 9 2008 1256 1168 28 0 0 0 0 0 1 +2017 1 2012 1 +2017 2 5 2016 1 +2017 3 2012 14 0 1 +2017 4 5 1393 6 0 1 +2017 5 2012 35 0 0 0 1 +2017 6 5 943 129 1843 0 0 1 +2017 7 2012 2 0 0 0 0 0 1 +2017 9 2012 10 1133 9 0 0 0 0 0 1 +2027 1 2025 1 +2027 2 2 2021 1 +2027 3 2025 5 0 1 +2027 4 2 1899 0 0 1 +2027 5 2025 2 0 0 0 1 +2027 6 2 1083 1623 2006 1 0 1 +2027 7 2025 3 0 0 0 0 0 1 +2027 9 2025 1995 87 6 0 0 0 0 0 1 +2029 1 2027 1 +2029 2 2 2028 1 +2029 3 2027 5 0 1 +2029 4 2 1663 7 0 1 +2029 5 2027 12 0 0 0 1 +2029 6 2 317 1791 1492 0 0 1 +2029 7 2027 6 0 0 0 0 0 1 +2029 9 2027 1332 1730 20 0 0 0 0 0 1 +2039 1 2032 1 +2039 2 7 2026 1 +2039 3 2032 7 0 1 +2039 4 7 1377 14 0 1 +2039 5 2032 4 0 0 0 1 +2039 6 7 755 1630 1937 2 0 1 +2039 7 2032 4 0 0 0 0 0 1 +2039 9 2032 1023 1657 0 0 0 0 0 0 1 +2053 1 2051 1 +2053 2 2 2049 1 +2053 3 2051 6 0 1 +2053 4 2 1580 10 0 1 +2053 5 2051 31 0 0 0 1 +2053 6 2 2041 2035 2049 0 0 1 +2053 7 2051 6 0 0 0 0 0 1 +2053 9 2051 1432 837 1 0 0 0 0 0 1 +2063 1 2058 1 +2063 2 5 2058 1 +2063 3 2058 1 0 1 +2063 4 5 1625 8 0 1 +2063 5 2058 1 0 0 0 1 +2063 6 5 1137 949 608 1 0 1 +2063 7 2058 1 0 0 0 0 0 1 +2063 9 2058 1964 829 7 0 0 0 0 0 1 +2069 1 2067 1 +2069 2 2 2065 1 +2069 3 2067 2 0 1 +2069 4 2 1413 6 0 1 +2069 5 2067 8 0 0 0 1 +2069 6 2 1268 1157 1365 4 0 1 +2069 7 2067 4 0 0 0 0 0 1 +2069 9 2067 1924 1763 0 0 0 0 0 0 1 +2081 1 2078 1 +2081 2 3 2080 1 +2081 3 2078 10 0 1 +2081 4 3 1796 7 0 1 +2081 5 2078 4 0 0 0 1 +2081 6 3 873 2034 1765 1 0 1 +2081 7 2078 10 0 0 0 0 0 1 +2081 9 2078 646 1414 5 0 0 0 0 0 1 +2083 1 2081 1 +2083 2 2 2079 1 +2083 3 2081 4 0 1 +2083 4 2 1925 8 0 1 +2083 5 2081 3 0 0 0 1 +2083 6 2 830 2053 790 0 0 1 +2083 7 2081 6 0 0 0 0 0 1 +2083 9 2081 1011 1762 8 0 0 0 0 0 1 +2087 1 2082 1 +2087 2 5 2084 1 +2087 3 2082 1 0 1 +2087 4 5 1305 6 0 1 +2087 5 2082 3 0 0 0 1 +2087 6 5 1567 114 517 1 0 1 +2087 7 2082 2 0 0 0 0 0 1 +2087 9 2082 1970 1931 1 0 0 0 0 0 1 +2089 1 2082 1 +2089 2 7 2080 1 +2089 3 2082 4 0 1 +2089 4 7 1985 2 0 1 +2089 5 2082 5 0 0 0 1 +2089 6 7 1492 977 1737 0 0 1 +2089 7 2082 1 0 0 0 0 0 1 +2089 9 2082 570 2054 2 0 0 0 0 0 1 +2099 1 2097 1 +2099 2 2 2095 1 +2099 3 2097 3 0 1 +2099 4 2 1828 7 0 1 +2099 5 2097 6 0 0 0 1 +2099 6 2 1169 1728 1204 2 0 1 +2099 7 2097 9 0 0 0 0 0 1 +2099 9 2097 747 1559 5 0 0 0 0 0 1 +2111 1 2104 1 +2111 2 7 2110 1 +2111 3 2104 9 0 1 +2111 4 7 1916 2 0 1 +2111 5 2104 1 0 0 0 1 +2111 6 7 117 1071 1472 6 0 1 +2111 7 2104 8 0 0 0 0 0 1 +2111 9 2104 2097 615 0 0 0 0 0 0 1 +2113 1 2108 1 +2113 2 5 2108 1 +2113 3 2108 1 0 1 +2113 4 5 1278 18 0 1 +2113 5 2108 5 0 0 0 1 +2113 6 5 456 1649 1853 0 0 1 +2113 7 2108 10 0 0 0 0 0 1 +2113 9 2108 1636 1520 1 0 0 0 0 0 1 +2129 1 2126 1 +2129 2 3 2120 1 +2129 3 2126 1 0 1 +2129 4 3 1672 6 0 1 +2129 5 2126 3 0 0 0 1 +2129 6 3 700 1338 1245 3 0 1 +2129 7 2126 3 0 0 0 0 0 1 +2129 9 2126 844 115 6 0 0 0 0 0 1 +2131 1 2129 1 +2131 2 2 2130 1 +2131 3 2129 5 0 1 +2131 4 2 2051 2 0 1 +2131 5 2129 17 0 0 0 1 +2131 6 2 1622 1717 1000 0 0 1 +2131 7 2129 3 0 0 0 0 0 1 +2131 9 2129 431 2105 5 0 0 0 0 0 1 +2137 1 2127 1 +2137 2 10 2136 1 +2137 3 2127 6 0 1 +2137 4 10 1153 6 0 1 +2137 5 2127 5 0 0 0 1 +2137 6 10 970 84 734 0 0 1 +2137 7 2127 15 0 0 0 0 0 1 +2137 9 2127 965 2084 27 0 0 0 0 0 1 +2141 1 2139 1 +2141 2 2 2140 1 +2141 3 2139 3 0 1 +2141 4 2 1154 3 0 1 +2141 5 2139 2 0 0 0 1 +2141 6 2 1939 860 1732 1 0 1 +2141 7 2139 7 0 0 0 0 0 1 +2141 9 2139 829 278 0 0 0 0 0 0 1 +2143 1 2140 1 +2143 2 3 2141 1 +2143 3 2140 1 0 1 +2143 4 3 1638 3 0 1 +2143 5 2140 3 0 0 0 1 +2143 6 3 802 1443 1616 0 0 1 +2143 7 2140 7 0 0 0 0 0 1 +2143 9 2140 1518 2089 6 0 0 0 0 0 1 +2153 1 2150 1 +2153 2 3 2145 1 +2153 3 2150 3 0 1 +2153 4 3 1925 2 0 1 +2153 5 2150 3 0 0 0 1 +2153 6 3 1732 2007 1833 1 0 1 +2153 7 2150 8 0 0 0 0 0 1 +2153 9 2150 1865 2027 1 0 0 0 0 0 1 +2161 1 2138 1 +2161 2 23 2160 1 +2161 3 2138 2 0 1 +2161 4 23 1561 15 0 1 +2161 5 2138 2 0 0 0 1 +2161 6 23 699 821 1898 1 0 1 +2161 7 2138 6 0 0 0 0 0 1 +2161 9 2138 439 967 6 0 0 0 0 0 1 +2179 1 2172 1 +2179 2 7 2177 1 +2179 3 2172 1 0 1 +2179 4 7 2017 6 0 1 +2179 5 2172 3 0 0 0 1 +2179 6 7 1709 2022 2038 0 0 1 +2179 7 2172 15 0 0 0 0 0 1 +2179 9 2172 2079 981 3 0 0 0 0 0 1 +2203 1 2198 1 +2203 2 5 2202 1 +2203 3 2198 1 0 1 +2203 4 5 1600 7 0 1 +2203 5 2198 1 0 0 0 1 +2203 6 5 731 1727 742 0 0 1 +2203 7 2198 5 0 0 0 0 0 1 +2203 9 2198 581 2028 8 0 0 0 0 0 1 +2207 1 2202 1 +2207 2 5 2205 1 +2207 3 2202 3 0 1 +2207 4 5 1195 8 0 1 +2207 5 2202 2 0 0 0 1 +2207 6 5 2074 865 508 1 0 1 +2207 7 2202 10 0 0 0 0 0 1 +2207 9 2202 1132 1570 0 0 0 0 0 0 1 +2213 1 2211 1 +2213 2 2 2209 1 +2213 3 2211 3 0 1 +2213 4 2 2119 6 0 1 +2213 5 2211 5 0 0 0 1 +2213 6 2 1438 1211 1450 1 0 1 +2213 7 2211 6 0 0 0 0 0 1 +2213 9 2211 0 2017 2 0 0 0 0 0 1 +2221 1 2219 1 +2221 2 2 2217 1 +2221 3 2219 6 0 1 +2221 4 2 1282 6 0 1 +2221 5 2219 8 0 0 0 1 +2221 6 2 2209 2203 2217 0 0 1 +2221 7 2219 2 0 0 0 0 0 1 +2221 9 2219 1126 2012 5 0 0 0 0 0 1 +2237 1 2235 1 +2237 2 2 2232 1 +2237 3 2235 4 0 1 +2237 4 2 1387 8 0 1 +2237 5 2235 7 0 0 0 1 +2237 6 2 1978 160 839 1 0 1 +2237 7 2235 11 0 0 0 0 0 1 +2237 9 2235 1056 797 5 0 0 0 0 0 1 +2239 1 2236 1 +2239 2 3 2233 1 +2239 3 2236 6 0 1 +2239 4 3 2145 11 0 1 +2239 5 2236 8 0 0 0 1 +2239 6 3 1910 490 1124 0 0 1 +2239 7 2236 1 0 0 0 0 0 1 +2239 9 2236 947 1594 31 0 0 0 0 0 1 +2243 1 2241 1 +2243 2 2 2234 1 +2243 3 2241 2 0 1 +2243 4 2 1553 1 0 1 +2243 5 2241 2 0 0 0 1 +2243 6 2 2141 92 1983 2 0 1 +2243 7 2241 5 0 0 0 0 0 1 +2243 9 2241 957 1339 0 0 0 0 0 0 1 +2251 1 2244 1 +2251 2 7 2249 1 +2251 3 2244 1 0 1 +2251 4 7 1840 6 0 1 +2251 5 2244 3 0 0 0 1 +2251 6 7 1081 1578 2067 0 0 1 +2251 7 2244 7 0 0 0 0 0 1 +2251 9 2244 1455 1129 2 0 0 0 0 0 1 +2267 1 2265 1 +2267 2 2 2266 1 +2267 3 2265 2 0 1 +2267 4 2 1889 10 0 1 +2267 5 2265 9 0 0 0 1 +2267 6 2 1447 170 1050 4 0 1 +2267 7 2265 12 0 0 0 0 0 1 +2267 9 2265 2206 1865 1 0 0 0 0 0 1 +2269 1 2267 1 +2269 2 2 2265 1 +2269 3 2267 2 0 1 +2269 4 2 1609 10 0 1 +2269 5 2267 3 0 0 0 1 +2269 6 2 2181 867 2260 0 0 1 +2269 7 2267 4 0 0 0 0 0 1 +2269 9 2267 172 2153 9 0 0 0 0 0 1 +2273 1 2270 1 +2273 2 3 2268 1 +2273 3 2270 3 0 1 +2273 4 3 1913 2 0 1 +2273 5 2270 7 0 0 0 1 +2273 6 3 1673 1140 2220 1 0 1 +2273 7 2270 20 0 0 0 0 0 1 +2273 9 2270 1769 1846 1 0 0 0 0 0 1 +2281 1 2274 1 +2281 2 7 2274 1 +2281 3 2274 5 0 1 +2281 4 7 1462 0 0 1 +2281 5 2274 3 0 0 0 1 +2281 6 7 1814 946 1240 0 0 1 +2281 7 2274 1 0 0 0 0 0 1 +2281 9 2274 1458 1648 10 0 0 0 0 0 1 +2287 1 2268 1 +2287 2 19 2283 1 +2287 3 2268 1 0 1 +2287 4 19 2160 6 0 1 +2287 5 2268 4 0 0 0 1 +2287 6 19 233 630 1812 0 0 1 +2287 7 2268 4 0 0 0 0 0 1 +2287 9 2268 386 1670 1 0 0 0 0 0 1 +2293 1 2291 1 +2293 2 2 2289 1 +2293 3 2291 5 0 1 +2293 4 2 1256 10 0 1 +2293 5 2291 2 0 0 0 1 +2293 6 2 435 1415 1935 0 0 1 +2293 7 2291 10 0 0 0 0 0 1 +2293 9 2291 2124 1905 7 0 0 0 0 0 1 +2297 1 2292 1 +2297 2 5 2292 1 +2297 3 2292 1 0 1 +2297 4 5 1772 8 0 1 +2297 5 2292 2 0 0 0 1 +2297 6 5 607 1036 2147 1 0 1 +2297 7 2292 1 0 0 0 0 0 1 +2297 9 2292 1213 2134 0 0 0 0 0 0 1 +2309 1 2307 1 +2309 2 2 2305 1 +2309 3 2307 3 0 1 +2309 4 2 2173 1 0 1 +2309 5 2307 6 0 0 0 1 +2309 6 2 94 164 1911 1 0 1 +2309 7 2307 14 0 0 0 0 0 1 +2309 9 2307 1532 1441 6 0 0 0 0 0 1 +2311 1 2308 1 +2311 2 3 2309 1 +2311 3 2308 3 0 1 +2311 4 3 2175 3 0 1 +2311 5 2308 11 0 0 0 1 +2311 6 3 1099 1270 424 3 0 1 +2311 7 2308 7 0 0 0 0 0 1 +2311 9 2308 309 1796 1 0 0 0 0 0 1 +2333 1 2331 1 +2333 2 2 2329 1 +2333 3 2331 3 0 1 +2333 4 2 1591 7 0 1 +2333 5 2331 9 0 0 0 1 +2333 6 2 966 990 1899 1 0 1 +2333 7 2331 8 0 0 0 0 0 1 +2333 9 2331 1892 204 0 0 0 0 0 0 1 +2339 1 2337 1 +2339 2 2 2329 1 +2339 3 2337 20 0 1 +2339 4 2 1768 0 0 1 +2339 5 2337 6 0 0 0 1 +2339 6 2 1112 764 2243 2 0 1 +2339 7 2337 17 0 0 0 0 0 1 +2339 9 2337 900 1724 0 0 0 0 0 0 1 +2341 1 2334 1 +2341 2 7 2339 1 +2341 3 2334 3 0 1 +2341 4 7 1919 9 0 1 +2341 5 2334 3 0 0 0 1 +2341 6 7 1291 342 1220 0 0 1 +2341 7 2334 9 0 0 0 0 0 1 +2341 9 2334 328 2061 33 0 0 0 0 0 1 +2347 1 2344 1 +2347 2 3 2342 1 +2347 3 2344 4 0 1 +2347 4 3 1254 3 0 1 +2347 5 2344 3 0 0 0 1 +2347 6 3 889 177 2337 0 0 1 +2347 7 2344 6 0 0 0 0 0 1 +2347 9 2344 743 2277 5 0 0 0 0 0 1 +2351 1 2338 1 +2351 2 13 2347 1 +2351 3 2338 1 0 1 +2351 4 13 1822 6 0 1 +2351 5 2338 2 0 0 0 1 +2351 6 13 773 1036 1247 1 0 1 +2351 7 2338 1 0 0 0 0 0 1 +2351 9 2338 1452 1725 3 0 0 0 0 0 1 +2357 1 2355 1 +2357 2 2 2352 1 +2357 3 2355 2 0 1 +2357 4 2 2140 8 0 1 +2357 5 2355 5 0 0 0 1 +2357 6 2 280 2291 1782 1 0 1 +2357 7 2355 7 0 0 0 0 0 1 +2357 9 2355 2317 1931 0 0 0 0 0 0 1 +2371 1 2369 1 +2371 2 2 2370 1 +2371 3 2369 4 0 1 +2371 4 2 2087 7 0 1 +2371 5 2369 2 0 0 0 1 +2371 6 2 860 370 1269 2 0 1 +2371 7 2369 4 0 0 0 0 0 1 +2371 9 2369 1314 1457 23 0 0 0 0 0 1 +2377 1 2372 1 +2377 2 5 2376 1 +2377 3 2372 1 0 1 +2377 4 5 1684 6 0 1 +2377 5 2372 10 0 0 0 1 +2377 6 5 299 83 975 0 0 1 +2377 7 2372 2 0 0 0 0 0 1 +2377 9 2372 1827 2178 28 0 0 0 0 0 1 +2381 1 2378 1 +2381 2 3 2379 1 +2381 3 2378 7 0 1 +2381 4 3 2283 12 0 1 +2381 5 2378 20 0 0 0 1 +2381 6 3 1568 1764 432 1 0 1 +2381 7 2378 12 0 0 0 0 0 1 +2381 9 2378 2290 74 4 0 0 0 0 0 1 +2383 1 2378 1 +2383 2 5 2382 1 +2383 3 2378 2 0 1 +2383 4 5 2159 8 0 1 +2383 5 2378 1 0 0 0 1 +2383 6 5 767 2110 372 3 0 1 +2383 7 2378 34 0 0 0 0 0 1 +2383 9 2378 1599 2180 11 0 0 0 0 0 1 +2389 1 2387 1 +2389 2 2 2385 1 +2389 3 2387 2 0 1 +2389 4 2 1651 10 0 1 +2389 5 2387 5 0 0 0 1 +2389 6 2 953 405 1962 0 0 1 +2389 7 2387 3 0 0 0 0 0 1 +2389 9 2387 1273 1724 4 0 0 0 0 0 1 +2393 1 2390 1 +2393 2 3 2392 1 +2393 3 2390 4 0 1 +2393 4 3 2047 7 0 1 +2393 5 2390 7 0 0 0 1 +2393 6 3 606 861 1633 2 0 1 +2393 7 2390 9 0 0 0 0 0 1 +2393 9 2390 678 757 1 0 0 0 0 0 1 +2399 1 2388 1 +2399 2 11 2398 1 +2399 3 2388 4 0 1 +2399 4 11 1637 3 0 1 +2399 5 2388 3 0 0 0 1 +2399 6 11 1344 89 1838 2 0 1 +2399 7 2388 3 0 0 0 0 0 1 +2399 9 2388 1220 30 5 0 0 0 0 0 1 +2411 1 2405 1 +2411 2 6 2410 1 +2411 3 2405 3 0 1 +2411 4 6 1681 4 0 1 +2411 5 2405 12 0 0 0 1 +2411 6 6 1092 1304 2016 1 0 1 +2411 7 2405 1 0 0 0 0 0 1 +2411 9 2405 813 1670 1 0 0 0 0 0 1 +2417 1 2414 1 +2417 2 3 2408 1 +2417 3 2414 1 0 1 +2417 4 3 2350 14 0 1 +2417 5 2414 3 0 0 0 1 +2417 6 3 167 2026 893 1 0 1 +2417 7 2414 4 0 0 0 0 0 1 +2417 9 2414 742 1272 0 0 0 0 0 0 1 +2423 1 2418 1 +2423 2 5 2421 1 +2423 3 2418 1 0 1 +2423 4 5 1349 10 0 1 +2423 5 2418 6 0 0 0 1 +2423 6 5 2166 1751 2050 1 0 1 +2423 7 2418 7 0 0 0 0 0 1 +2423 9 2418 2267 915 5 0 0 0 0 0 1 +2437 1 2435 1 +2437 2 2 2433 1 +2437 3 2435 6 0 1 +2437 4 2 1592 6 0 1 +2437 5 2435 2 0 0 0 1 +2437 6 2 2425 2419 2433 0 0 1 +2437 7 2435 14 0 0 0 0 0 1 +2437 9 2435 444 2275 5 0 0 0 0 0 1 +2441 1 2435 1 +2441 2 6 2438 1 +2441 3 2435 1 0 1 +2441 4 6 2078 0 0 1 +2441 5 2435 7 0 0 0 1 +2441 6 6 1678 1880 1270 1 0 1 +2441 7 2435 4 0 0 0 0 0 1 +2441 9 2435 1272 787 0 0 0 0 0 0 1 +2447 1 2442 1 +2447 2 5 2446 1 +2447 3 2442 1 0 1 +2447 4 5 1426 2 0 1 +2447 5 2442 3 0 0 0 1 +2447 6 5 1496 2409 2123 1 0 1 +2447 7 2442 9 0 0 0 0 0 1 +2447 9 2442 1269 1060 4 0 0 0 0 0 1 +2459 1 2457 1 +2459 2 2 2455 1 +2459 3 2457 3 0 1 +2459 4 2 1737 7 0 1 +2459 5 2457 2 0 0 0 1 +2459 6 2 885 1850 2138 1 0 1 +2459 7 2457 4 0 0 0 0 0 1 +2459 9 2457 114 849 7 0 0 0 0 0 1 +2467 1 2465 1 +2467 2 2 2466 1 +2467 3 2465 6 0 1 +2467 4 2 1277 7 0 1 +2467 5 2465 6 0 0 0 1 +2467 6 2 1060 1538 1507 0 0 1 +2467 7 2465 6 0 0 0 0 0 1 +2467 9 2465 1683 1543 9 0 0 0 0 0 1 +2473 1 2468 1 +2473 2 5 2472 1 +2473 3 2468 1 0 1 +2473 4 5 1380 11 0 1 +2473 5 2468 10 0 0 0 1 +2473 6 5 1517 348 2137 1 0 1 +2473 7 2468 26 0 0 0 0 0 1 +2473 9 2468 1146 1002 4 0 0 0 0 0 1 +2477 1 2475 1 +2477 2 2 2476 1 +2477 3 2475 2 0 1 +2477 4 2 1955 3 0 1 +2477 5 2475 5 0 0 0 1 +2477 6 2 80 1343 959 2 0 1 +2477 7 2475 9 0 0 0 0 0 1 +2477 9 2475 223 1104 9 0 0 0 0 0 1 +2503 1 2500 1 +2503 2 3 2502 1 +2503 3 2500 14 0 1 +2503 4 3 2207 2 0 1 +2503 5 2500 9 0 0 0 1 +2503 6 3 2195 972 1282 0 0 1 +2503 7 2500 5 0 0 0 0 0 1 +2503 9 2500 1979 1152 7 0 0 0 0 0 1 +2521 1 2504 1 +2521 2 17 2520 1 +2521 3 2504 1 0 1 +2521 4 17 1993 23 0 1 +2521 5 2504 6 0 0 0 1 +2521 6 17 277 659 1946 1 0 1 +2521 7 2504 4 0 0 0 0 0 1 +2521 9 2504 822 2454 12 0 0 0 0 0 1 +2531 1 2529 1 +2531 2 2 2527 1 +2531 3 2529 2 0 1 +2531 4 2 1375 8 0 1 +2531 5 2529 5 0 0 0 1 +2531 6 2 1051 184 2346 2 0 1 +2531 7 2529 3 0 0 0 0 0 1 +2531 9 2529 2207 1381 0 0 0 0 0 0 1 +2539 1 2537 1 +2539 2 2 2538 1 +2539 3 2537 5 0 1 +2539 4 2 2069 2 0 1 +2539 5 2537 3 0 0 0 1 +2539 6 2 1802 1911 1332 0 0 1 +2539 7 2537 5 0 0 0 0 0 1 +2539 9 2537 822 2293 7 0 0 0 0 0 1 +2543 1 2538 1 +2543 2 5 2541 1 +2543 3 2538 6 0 1 +2543 4 5 2539 3 0 1 +2543 5 2538 3 0 0 0 1 +2543 6 5 860 1428 1634 2 0 1 +2543 7 2538 21 0 0 0 0 0 1 +2543 9 2538 1813 1024 0 0 0 0 0 0 1 +2549 1 2547 1 +2549 2 2 2545 1 +2549 3 2547 2 0 1 +2549 4 2 2242 12 0 1 +2549 5 2547 3 0 0 0 1 +2549 6 2 2264 1711 1391 1 0 1 +2549 7 2547 2 0 0 0 0 0 1 +2549 9 2547 1819 2 0 0 0 0 0 0 1 +2551 1 2545 1 +2551 2 6 2549 1 +2551 3 2545 2 0 1 +2551 4 6 2007 3 0 1 +2551 5 2545 7 0 0 0 1 +2551 6 6 1355 1591 1888 0 0 1 +2551 7 2545 23 0 0 0 0 0 1 +2551 9 2545 1151 2487 4 0 0 0 0 0 1 +2557 1 2555 1 +2557 2 2 2553 1 +2557 3 2555 6 0 1 +2557 4 2 2444 6 0 1 +2557 5 2555 4 0 0 0 1 +2557 6 2 2545 2539 2553 0 0 1 +2557 7 2555 2 0 0 0 0 0 1 +2557 9 2555 2359 1177 6 0 0 0 0 0 1 +2579 1 2577 1 +2579 2 2 2560 1 +2579 3 2577 5 0 1 +2579 4 2 1954 1 0 1 +2579 5 2577 12 0 0 0 1 +2579 6 2 73 471 1709 1 0 1 +2579 7 2577 4 0 0 0 0 0 1 +2579 9 2577 1770 866 7 0 0 0 0 0 1 +2591 1 2584 1 +2591 2 7 2589 1 +2591 3 2584 1 0 1 +2591 4 7 2159 5 0 1 +2591 5 2584 5 0 0 0 1 +2591 6 7 1936 607 1663 1 0 1 +2591 7 2584 14 0 0 0 0 0 1 +2591 9 2584 2384 310 1 0 0 0 0 0 1 +2593 1 2586 1 +2593 2 7 2586 1 +2593 3 2586 3 0 1 +2593 4 7 2226 14 0 1 +2593 5 2586 12 0 0 0 1 +2593 6 7 946 1268 1392 0 0 1 +2593 7 2586 3 0 0 0 0 0 1 +2593 9 2586 371 1458 11 0 0 0 0 0 1 +2609 1 2606 1 +2609 2 3 2603 1 +2609 3 2606 1 0 1 +2609 4 3 2597 0 0 1 +2609 5 2606 1 0 0 0 1 +2609 6 3 1184 2345 1105 1 0 1 +2609 7 2606 6 0 0 0 0 0 1 +2609 9 2606 1030 2447 3 0 0 0 0 0 1 +2617 1 2612 1 +2617 2 5 2614 1 +2617 3 2612 5 0 1 +2617 4 5 2248 10 0 1 +2617 5 2612 2 0 0 0 1 +2617 6 5 644 2355 1514 0 0 1 +2617 7 2612 3 0 0 0 0 0 1 +2617 9 2612 1014 2367 16 0 0 0 0 0 1 +2621 1 2619 1 +2621 2 2 2620 1 +2621 3 2619 3 0 1 +2621 4 2 1919 9 0 1 +2621 5 2619 10 0 0 0 1 +2621 6 2 1136 283 2390 1 0 1 +2621 7 2619 6 0 0 0 0 0 1 +2621 9 2619 1379 1858 1 0 0 0 0 0 1 +2633 1 2630 1 +2633 2 3 2627 1 +2633 3 2630 3 0 1 +2633 4 3 1393 9 0 1 +2633 5 2630 4 0 0 0 1 +2633 6 3 773 318 1332 1 0 1 +2633 7 2630 3 0 0 0 0 0 1 +2633 9 2630 1843 111 0 0 0 0 0 0 1 +2647 1 2644 1 +2647 2 3 2646 1 +2647 3 2644 4 0 1 +2647 4 3 1656 5 0 1 +2647 5 2644 3 0 0 0 1 +2647 6 3 234 1628 1100 0 0 1 +2647 7 2644 10 0 0 0 0 0 1 +2647 9 2644 561 1736 2 0 0 0 0 0 1 +2657 1 2654 1 +2657 2 3 2652 1 +2657 3 2654 3 0 1 +2657 4 3 1910 2 0 1 +2657 5 2654 8 0 0 0 1 +2657 6 3 1392 1071 1723 1 0 1 +2657 7 2654 13 0 0 0 0 0 1 +2657 9 2654 370 538 1 0 0 0 0 0 1 +2659 1 2657 1 +2659 2 2 2658 1 +2659 3 2657 4 0 1 +2659 4 2 1570 2 0 1 +2659 5 2657 13 0 0 0 1 +2659 6 2 35 998 1901 0 0 1 +2659 7 2657 28 0 0 0 0 0 1 +2659 9 2657 629 1806 10 0 0 0 0 0 1 +2663 1 2658 1 +2663 2 5 2655 1 +2663 3 2658 12 0 1 +2663 4 5 2263 3 0 1 +2663 5 2658 3 0 0 0 1 +2663 6 5 2428 772 1799 1 0 1 +2663 7 2658 1 0 0 0 0 0 1 +2663 9 2658 556 349 4 0 0 0 0 0 1 +2671 1 2664 1 +2671 2 7 2662 1 +2671 3 2664 7 0 1 +2671 4 7 2226 2 0 1 +2671 5 2664 1 0 0 0 1 +2671 6 7 2007 1802 2472 0 0 1 +2671 7 2664 2 0 0 0 0 0 1 +2671 9 2664 338 2358 16 0 0 0 0 0 1 +2677 1 2675 1 +2677 2 2 2676 1 +2677 3 2675 2 0 1 +2677 4 2 2358 6 0 1 +2677 5 2675 8 0 0 0 1 +2677 6 2 271 1113 723 0 0 1 +2677 7 2675 14 0 0 0 0 0 1 +2677 9 2675 1934 1971 11 0 0 0 0 0 1 +2683 1 2681 1 +2683 2 2 2679 1 +2683 3 2681 13 0 1 +2683 4 2 1386 8 0 1 +2683 5 2681 7 0 0 0 1 +2683 6 2 170 125 1906 0 0 1 +2683 7 2681 2 0 0 0 0 0 1 +2683 9 2681 259 997 8 0 0 0 0 0 1 +2687 1 2682 1 +2687 2 5 2686 1 +2687 3 2682 1 0 1 +2687 4 5 1568 2 0 1 +2687 5 2682 7 0 0 0 1 +2687 6 5 772 1402 1390 1 0 1 +2687 7 2682 7 0 0 0 0 0 1 +2687 9 2682 726 2286 3 0 0 0 0 0 1 +2689 1 2670 1 +2689 2 19 2684 1 +2689 3 2670 2 0 1 +2689 4 19 1679 24 0 1 +2689 5 2670 4 0 0 0 1 +2689 6 19 1942 2441 2393 0 0 1 +2693 1 2691 1 +2693 2 2 2688 1 +2693 3 2691 2 0 1 +2693 4 2 2281 0 0 1 +2693 5 2691 7 0 0 0 1 +2693 6 2 1940 68 2650 1 0 1 +2693 7 2691 21 0 0 0 0 0 1 +2693 9 2691 205 1843 3 0 0 0 0 0 1 +2699 1 2697 1 +2699 2 2 2693 1 +2699 3 2697 2 0 1 +2699 4 2 1520 4 0 1 +2699 5 2697 8 0 0 0 1 +2699 6 2 2046 773 2361 1 0 1 +2699 7 2697 2 0 0 0 0 0 1 +2699 9 2697 440 1133 5 0 0 0 0 0 1 +2707 1 2705 1 +2707 2 2 2706 1 +2707 3 2705 7 0 1 +2707 4 2 1560 2 0 1 +2707 5 2705 2 0 0 0 1 +2707 6 2 1133 2011 2594 0 0 1 +2707 7 2705 13 0 0 0 0 0 1 +2707 9 2705 466 2339 19 0 0 0 0 0 1 +2711 1 2704 1 +2711 2 7 2710 1 +2711 3 2704 1 0 1 +2711 4 7 1442 2 0 1 +2711 5 2704 1 0 0 0 1 +2711 6 7 2519 102 1774 1 0 1 +2711 7 2704 5 0 0 0 0 0 1 +2711 9 2704 2424 2482 0 0 0 0 0 0 1 +2713 1 2708 1 +2713 2 5 2712 1 +2713 3 2708 1 0 1 +2713 4 5 2548 6 0 1 +2713 5 2708 1 0 0 0 1 +2713 6 5 2518 1036 1920 0 0 1 +2713 7 2708 11 0 0 0 0 0 1 +2713 9 2708 1291 2050 3 0 0 0 0 0 1 +2719 1 2716 1 +2719 2 3 2718 1 +2719 3 2716 4 0 1 +2719 4 3 2480 3 0 1 +2719 5 2716 19 0 0 0 1 +2719 6 3 1769 441 689 1 0 1 +2719 7 2716 8 0 0 0 0 0 1 +2719 9 2716 1481 2154 2 0 0 0 0 0 1 +2729 1 2726 1 +2729 2 3 2723 1 +2729 3 2726 4 0 1 +2729 4 3 2717 0 0 1 +2729 5 2726 1 0 0 0 1 +2729 6 3 1424 213 2547 1 0 1 +2729 7 2726 1 0 0 0 0 0 1 +2729 9 2726 1869 1348 0 0 0 0 0 0 1 +2731 1 2728 1 +2731 2 3 2722 1 +2731 3 2728 3 0 1 +2731 4 3 2591 2 0 1 +2731 5 2728 10 0 0 0 1 +2731 6 3 1404 1520 512 0 0 1 +2731 7 2728 7 0 0 0 0 0 1 +2731 9 2728 2672 1637 1 0 0 0 0 0 1 +2741 1 2739 1 +2741 2 2 2737 1 +2741 3 2739 3 0 1 +2741 4 2 2507 12 0 1 +2741 5 2739 8 0 0 0 1 +2741 6 2 1311 1967 1856 1 0 1 +2741 7 2739 5 0 0 0 0 0 1 +2741 9 2739 2251 1666 5 0 0 0 0 0 1 +2749 1 2743 1 +2749 2 6 2741 1 +2749 3 2743 1 0 1 +2749 4 6 1695 0 0 1 +2749 5 2743 20 0 0 0 1 +2749 6 6 465 1636 767 0 0 1 +2749 7 2743 6 0 0 0 0 0 1 +2749 9 2743 2573 2665 10 0 0 0 0 0 1 +2753 1 2750 1 +2753 2 3 2747 1 +2753 3 2750 5 0 1 +2753 4 3 1947 9 0 1 +2753 5 2750 4 0 0 0 1 +2753 6 3 1153 1520 1673 3 0 1 +2753 7 2750 4 0 0 0 0 0 1 +2753 9 2750 1096 788 4 0 0 0 0 0 1 +2767 1 2764 1 +2767 2 3 2766 1 +2767 3 2764 15 0 1 +2767 4 3 2422 5 0 1 +2767 5 2764 3 0 0 0 1 +2767 6 3 1940 1828 1310 0 0 1 +2767 7 2764 1 0 0 0 0 0 1 +2767 9 2764 2582 2742 5 0 0 0 0 0 1 +2777 1 2774 1 +2777 2 3 2772 1 +2777 3 2774 1 0 1 +2777 4 3 1801 0 0 1 +2777 5 2774 1 0 0 0 1 +2777 6 3 1761 1143 1344 4 0 1 +2777 7 2774 17 0 0 0 0 0 1 +2777 9 2774 2399 2419 2 0 0 0 0 0 1 +2789 1 2787 1 +2789 2 2 2783 1 +2789 3 2787 3 0 1 +2789 4 2 2423 3 0 1 +2789 5 2787 4 0 0 0 1 +2789 6 2 2433 781 1923 1 0 1 +2789 7 2787 5 0 0 0 0 0 1 +2789 9 2787 1610 1475 3 0 0 0 0 0 1 +2791 1 2785 1 +2791 2 6 2789 1 +2791 3 2785 7 0 1 +2791 4 6 1653 3 0 1 +2791 5 2785 19 0 0 0 1 +2791 6 6 1742 1391 1876 0 0 1 +2791 7 2785 9 0 0 0 0 0 1 +2791 9 2785 1355 2415 3 0 0 0 0 0 1 +2797 1 2795 1 +2797 2 2 2793 1 +2797 3 2795 6 0 1 +2797 4 2 2145 9 0 1 +2797 5 2795 2 0 0 0 1 +2797 6 2 2785 2779 2793 0 0 1 +2801 1 2798 1 +2801 2 3 2800 1 +2801 3 2798 1 0 1 +2801 4 3 1614 7 0 1 +2801 5 2798 3 0 0 0 1 +2801 6 3 964 2436 600 1 0 1 +2801 7 2798 6 0 0 0 0 0 1 +2801 9 2798 410 1893 2 0 0 0 0 0 1 +2803 1 2801 1 +2803 2 2 2802 1 +2803 3 2801 4 0 1 +2803 4 2 2468 16 0 1 +2803 5 2801 9 0 0 0 1 +2803 6 2 917 2197 1394 0 0 1 +2803 7 2801 4 0 0 0 0 0 1 +2803 9 2801 179 1929 0 0 0 0 0 0 1 +2819 1 2817 1 +2819 2 2 2814 1 +2819 3 2817 3 0 1 +2819 4 2 2651 3 0 1 +2819 5 2817 9 0 0 0 1 +2819 6 2 1428 1252 2713 2 0 1 +2819 7 2817 8 0 0 0 0 0 1 +2819 9 2817 2516 1075 1 0 0 0 0 0 1 +2833 1 2828 1 +2833 2 5 2830 1 +2833 3 2828 3 0 1 +2833 4 5 2233 22 0 1 +2833 5 2828 1 0 0 0 1 +2833 6 5 2264 954 685 0 0 1 +2837 1 2835 1 +2837 2 2 2833 1 +2837 3 2835 3 0 1 +2837 4 2 2731 18 0 1 +2837 5 2835 3 0 0 0 1 +2837 6 2 1415 2694 2430 3 0 1 +2837 7 2835 5 0 0 0 0 0 1 +2837 9 2835 2419 2410 6 0 0 0 0 0 1 +2843 1 2841 1 +2843 2 2 2839 1 +2843 3 2841 3 0 1 +2843 4 2 2566 8 0 1 +2843 5 2841 12 0 0 0 1 +2843 6 2 2629 920 1618 1 0 1 +2843 7 2841 5 0 0 0 0 0 1 +2843 9 2841 2363 1669 0 0 0 0 0 0 1 +2851 1 2849 1 +2851 2 2 2847 1 +2851 3 2849 12 0 1 +2851 4 2 2674 8 0 1 +2851 5 2849 3 0 0 0 1 +2851 6 2 1398 200 509 0 0 1 +2851 7 2849 5 0 0 0 0 0 1 +2851 9 2849 656 2167 9 0 0 0 0 0 1 +2857 1 2846 1 +2857 2 11 2856 1 +2857 3 2846 2 0 1 +2857 4 11 2703 21 0 1 +2857 5 2846 1 0 0 0 1 +2857 6 11 1166 2012 2854 0 0 1 +2857 7 2846 2 0 0 0 0 0 1 +2857 9 2846 1833 2188 1 0 0 0 0 0 1 +2861 1 2859 1 +2861 2 2 2857 1 +2861 3 2859 3 0 1 +2861 4 2 1958 1 0 1 +2861 5 2859 17 0 0 0 1 +2861 6 2 424 459 2461 1 0 1 +2861 7 2859 15 0 0 0 0 0 1 +2861 9 2859 396 22 0 0 0 0 0 0 1 +2879 1 2872 1 +2879 2 7 2878 1 +2879 3 2872 2 0 1 +2879 4 7 1579 2 0 1 +2879 5 2872 1 0 0 0 1 +2879 6 7 1566 1144 2755 1 0 1 +2879 7 2872 18 0 0 0 0 0 1 +2879 9 2872 324 2154 0 0 0 0 0 0 1 +2887 1 2882 1 +2887 2 5 2885 1 +2887 3 2882 1 0 1 +2887 4 5 1657 9 0 1 +2887 5 2882 16 0 0 0 1 +2887 6 5 2797 2682 1171 0 0 1 +2887 7 2882 9 0 0 0 0 0 1 +2887 9 2882 1265 1114 9 0 0 0 0 0 1 +2897 1 2894 1 +2897 2 3 2891 1 +2897 3 2894 3 0 1 +2897 4 3 1560 1 0 1 +2897 5 2894 9 0 0 0 1 +2897 6 3 964 2504 1785 3 0 1 +2897 7 2894 18 0 0 0 0 0 1 +2897 9 2894 1011 2818 1 0 0 0 0 0 1 +2903 1 2898 1 +2903 2 5 2902 1 +2903 3 2898 1 0 1 +2903 4 5 2291 4 0 1 +2903 5 2898 11 0 0 0 1 +2903 6 5 2600 757 324 3 0 1 +2903 7 2898 9 0 0 0 0 0 1 +2903 9 2898 2226 558 1 0 0 0 0 0 1 +2909 1 2907 1 +2909 2 2 2900 1 +2909 3 2907 2 0 1 +2909 4 2 2786 1 0 1 +2909 5 2907 6 0 0 0 1 +2909 6 2 1025 2659 683 1 0 1 +2909 7 2907 5 0 0 0 0 0 1 +2909 9 2907 2338 681 0 0 0 0 0 0 1 +2917 1 2912 1 +2917 2 5 2916 1 +2917 3 2912 2 0 1 +2917 4 5 1860 3 0 1 +2917 5 2912 2 0 0 0 1 +2917 6 5 2643 1589 2181 1 0 1 +2917 7 2912 1 0 0 0 0 0 1 +2917 9 2912 914 2767 0 0 0 0 0 0 1 +2927 1 2922 1 +2927 2 5 2925 1 +2927 3 2922 7 0 1 +2927 4 5 2446 10 0 1 +2927 5 2922 3 0 0 0 1 +2927 6 5 1521 1142 2191 1 0 1 +2927 7 2922 10 0 0 0 0 0 1 +2927 9 2922 1741 428 5 0 0 0 0 0 1 +2939 1 2937 1 +2939 2 2 2938 1 +2939 3 2937 3 0 1 +2939 4 2 1878 13 0 1 +2939 5 2937 5 0 0 0 1 +2939 6 2 875 2840 2808 1 0 1 +2939 7 2937 20 0 0 0 0 0 1 +2939 9 2937 514 1940 1 0 0 0 0 0 1 +2953 1 2940 1 +2953 2 13 2952 1 +2953 3 2940 5 0 1 +2953 4 13 2109 14 0 1 +2953 5 2940 1 0 0 0 1 +2953 6 13 1904 94 702 1 0 1 +2953 7 2940 31 0 0 0 0 0 1 +2953 9 2940 1830 2020 10 0 0 0 0 0 1 +2957 1 2955 1 +2957 2 2 2956 1 +2957 3 2955 2 0 1 +2957 4 2 2502 6 0 1 +2957 5 2955 6 0 0 0 1 +2957 6 2 2223 2582 2361 1 0 1 +2957 7 2955 5 0 0 0 0 0 1 +2957 9 2955 1274 2653 4 0 0 0 0 0 1 +2963 1 2961 1 +2963 2 2 2959 1 +2963 3 2961 3 0 1 +2963 4 2 1600 8 0 1 +2963 5 2961 5 0 0 0 1 +2963 6 2 2724 1929 1507 1 0 1 +2963 7 2961 17 0 0 0 0 0 1 +2963 9 2961 2845 2121 9 0 0 0 0 0 1 +2969 1 2966 1 +2969 2 3 2968 1 +2969 3 2966 3 0 1 +2969 4 3 2702 4 0 1 +2969 5 2966 3 0 0 0 1 +2969 6 3 212 181 1690 1 0 1 +2969 7 2966 4 0 0 0 0 0 1 +2969 9 2966 2846 1727 0 0 0 0 0 0 1 +2971 1 2961 1 +2971 2 10 2970 1 +2971 3 2961 2 0 1 +2971 4 10 1931 5 0 1 +2971 5 2961 5 0 0 0 1 +2971 6 10 905 1121 2893 0 0 1 +2971 7 2961 8 0 0 0 0 0 1 +2971 9 2961 1724 2610 15 0 0 0 0 0 1 +2999 1 2982 1 +2999 2 17 2995 1 +2999 3 2982 4 0 1 +2999 4 17 2779 12 0 1 +2999 5 2982 8 0 0 0 1 +2999 6 17 2843 164 1108 7 0 1 +2999 7 2982 3 0 0 0 0 0 1 +2999 9 2982 506 1970 7 0 0 0 0 0 1 +3001 1 2987 1 +3001 2 14 2999 1 +3001 3 2987 2 0 1 +3001 4 14 2975 15 0 1 +3001 5 2987 1 0 0 0 1 +3001 6 14 1887 1943 1408 2 0 1 +3001 7 2987 1 0 0 0 0 0 1 +3001 9 2987 639 1829 0 0 0 0 0 0 1 +3011 1 3009 1 +3011 2 2 3007 1 +3011 3 3009 3 0 1 +3011 4 2 2235 7 0 1 +3011 5 3009 4 0 0 0 1 +3011 6 2 452 208 2613 1 0 1 +3011 7 3009 2 0 0 0 0 0 1 +3011 9 3009 1678 2158 1 0 0 0 0 0 1 +3019 1 3017 1 +3019 2 2 3015 1 +3019 3 3017 4 0 1 +3019 4 2 2924 8 0 1 +3019 5 3017 4 0 0 0 1 +3019 6 2 2983 1076 2099 0 0 1 +3023 1 3018 1 +3023 2 5 3021 1 +3023 3 3018 2 0 1 +3023 4 5 3019 3 0 1 +3023 5 3018 9 0 0 0 1 +3023 6 5 731 1273 1407 1 0 1 +3023 7 3018 8 0 0 0 0 0 1 +3023 9 3018 104 971 0 0 0 0 0 0 1 +3037 1 3035 1 +3037 2 2 3036 1 +3037 3 3035 2 0 1 +3037 4 2 1881 9 0 1 +3037 5 3035 5 0 0 0 1 +3037 6 2 2415 1532 928 0 0 1 +3037 7 3035 22 0 0 0 0 0 1 +3037 9 3035 272 2593 4 0 0 0 0 0 1 +3041 1 3038 1 +3041 2 3 3030 1 +3041 3 3038 1 0 1 +3041 4 3 2059 8 0 1 +3041 5 3038 1 0 0 0 1 +3041 6 3 1279 1713 2942 4 0 1 +3041 7 3038 6 0 0 0 0 0 1 +3041 9 3038 2606 1279 0 0 0 0 0 0 1 +3049 1 3038 1 +3049 2 11 3048 1 +3049 3 3038 3 0 1 +3049 4 11 2806 27 0 1 +3049 5 3038 5 0 0 0 1 +3049 6 11 453 1501 2406 0 0 1 +3049 7 3038 2 0 0 0 0 0 1 +3049 9 3038 1727 1617 3 0 0 0 0 0 1 +3061 1 3055 1 +3061 2 6 3057 1 +3061 3 3055 2 0 1 +3061 4 6 2404 10 0 1 +3061 5 3055 12 0 0 0 1 +3061 6 6 2164 914 1417 1 0 1 +3061 7 3055 1 0 0 0 0 0 1 +3061 9 3055 704 1540 0 0 0 0 0 0 1 +3067 1 3065 1 +3067 2 2 3063 1 +3067 3 3065 4 0 1 +3067 4 2 2516 8 0 1 +3067 5 3065 5 0 0 0 1 +3067 6 2 2295 2309 2709 0 0 1 +3067 7 3065 2 0 0 0 0 0 1 +3067 9 3065 304 1495 12 0 0 0 0 0 1 +3079 1 3073 1 +3079 2 6 3078 1 +3079 3 3073 1 0 1 +3079 4 6 2775 3 0 1 +3079 5 3073 2 0 0 0 1 +3079 6 6 2589 1176 1907 0 0 1 +3079 7 3073 4 0 0 0 0 0 1 +3079 9 3073 513 1559 2 0 0 0 0 0 1 +3083 1 3081 1 +3083 2 2 3079 1 +3083 3 3081 2 0 1 +3083 4 2 1589 11 0 1 +3083 5 3081 5 0 0 0 1 +3083 6 2 1552 662 2261 5 0 1 +3083 7 3081 20 0 0 0 0 0 1 +3083 9 3081 124 2 6 0 0 0 0 0 1 +3089 1 3086 1 +3089 2 3 3082 1 +3089 3 3086 3 0 1 +3089 4 3 3009 1 0 1 +3089 5 3086 5 0 0 0 1 +3089 6 3 822 2198 2929 5 0 1 +3089 7 3086 22 0 0 0 0 0 1 +3089 9 3086 1304 2593 1 0 0 0 0 0 1 +3109 1 3103 1 +3109 2 6 3105 1 +3109 3 3103 4 0 1 +3109 4 6 3105 6 0 1 +3109 5 3103 3 0 0 0 1 +3109 6 6 174 2325 2041 0 0 1 +3109 7 3103 8 0 0 0 0 0 1 +3109 9 3103 2388 1654 18 0 0 0 0 0 1 +3119 1 3112 1 +3119 2 7 3118 1 +3119 3 3112 8 0 1 +3119 4 7 2052 3 0 1 +3119 5 3112 1 0 0 0 1 +3119 6 7 2363 2315 1459 1 0 1 +3119 7 3112 1 0 0 0 0 0 1 +3119 9 3112 1849 450 1 0 0 0 0 0 1 +3121 1 3114 1 +3121 2 7 3114 1 +3121 3 3114 1 0 1 +3121 4 7 1779 0 0 1 +3121 5 3114 1 0 0 0 1 +3121 6 7 1798 478 2851 0 0 1 +3121 7 3114 5 0 0 0 0 0 1 +3121 9 3114 2996 1972 11 0 0 0 0 0 1 +3137 1 3134 1 +3137 2 3 3131 1 +3137 3 3134 4 0 1 +3137 4 3 2714 1 0 1 +3137 5 3134 15 0 0 0 1 +3137 6 3 3061 2685 3099 1 0 1 +3137 7 3134 23 0 0 0 0 0 1 +3137 9 3134 610 703 8 0 0 0 0 0 1 +3163 1 3160 1 +3163 2 3 3162 1 +3163 3 3160 4 0 1 +3163 4 3 1675 5 0 1 +3163 5 3160 6 0 0 0 1 +3163 6 3 1181 2392 3096 0 0 1 +3167 1 3162 1 +3167 2 5 3164 1 +3167 3 3162 1 0 1 +3167 4 5 1750 4 0 1 +3167 5 3162 5 0 0 0 1 +3167 6 5 1333 321 2821 1 0 1 +3167 7 3162 13 0 0 0 0 0 1 +3167 9 3162 2779 2174 1 0 0 0 0 0 1 +3169 1 3162 1 +3169 2 7 3162 1 +3169 3 3162 1 0 1 +3169 4 7 2295 0 0 1 +3169 5 3162 8 0 0 0 1 +3169 6 7 2744 731 3147 0 0 1 +3169 7 3162 10 0 0 0 0 0 1 +3169 9 3162 2562 1570 9 0 0 0 0 0 1 +3181 1 3174 1 +3181 2 7 3179 1 +3181 3 3174 4 0 1 +3181 4 7 1885 4 0 1 +3181 5 3174 1 0 0 0 1 +3181 6 7 937 2559 801 0 0 1 +3181 7 3174 1 0 0 0 0 0 1 +3181 9 3174 2312 2637 4 0 0 0 0 0 1 +3187 1 3185 1 +3187 2 2 3183 1 +3187 3 3185 5 0 1 +3187 4 2 1795 8 0 1 +3187 5 3185 3 0 0 0 1 +3187 6 2 134 564 1147 0 0 1 +3187 7 3185 7 0 0 0 0 0 1 +3187 9 3185 2880 1947 5 0 0 0 0 0 1 +3191 1 3180 1 +3191 2 11 3189 1 +3191 3 3180 6 0 1 +3191 4 11 1986 5 0 1 +3191 5 3180 4 0 0 0 1 +3191 6 11 1308 2065 2741 2 0 1 +3191 7 3180 1 0 0 0 0 0 1 +3191 9 3180 1632 2601 7 0 0 0 0 0 1 +3203 1 3201 1 +3203 2 2 3199 1 +3203 3 3201 3 0 1 +3203 4 2 2883 16 0 1 +3203 5 3201 18 0 0 0 1 +3203 6 2 610 1778 248 1 0 1 +3203 7 3201 4 0 0 0 0 0 1 +3203 9 3201 2402 1490 1 0 0 0 0 0 1 +3209 1 3206 1 +3209 2 3 3204 1 +3209 3 3206 3 0 1 +3209 4 3 2273 2 0 1 +3209 5 3206 12 0 0 0 1 +3209 6 3 911 304 2745 1 0 1 +3217 1 3212 1 +3217 2 5 3212 1 +3217 3 3212 1 0 1 +3217 4 5 2588 15 0 1 +3217 5 3212 1 0 0 0 1 +3217 6 5 1673 2408 2630 0 0 1 +3217 7 3212 5 0 0 0 0 0 1 +3217 9 3212 1567 3004 6 0 0 0 0 0 1 +3221 1 3211 1 +3221 2 10 3211 1 +3221 3 3211 2 0 1 +3221 4 10 1741 8 0 1 +3221 5 3211 4 0 0 0 1 +3221 6 10 2289 3027 2712 1 0 1 +3221 7 3211 5 0 0 0 0 0 1 +3221 9 3211 1296 1226 5 0 0 0 0 0 1 +3229 1 3223 1 +3229 2 6 3221 1 +3229 3 3223 1 0 1 +3229 4 6 3001 0 0 1 +3229 5 3223 6 0 0 0 1 +3229 6 6 2758 3091 1986 2 0 1 +3229 7 3223 2 0 0 0 0 0 1 +3229 9 3223 586 2272 18 0 0 0 0 0 1 +3251 1 3245 1 +3251 2 6 3249 1 +3251 3 3245 1 0 1 +3251 4 6 3241 7 0 1 +3251 5 3245 7 0 0 0 1 +3251 6 6 1634 696 2665 2 0 1 +3251 7 3245 2 0 0 0 0 0 1 +3251 9 3245 1022 2372 11 0 0 0 0 0 1 +3253 1 3251 1 +3253 2 2 3252 1 +3253 3 3251 2 0 1 +3253 4 2 2830 3 0 1 +3253 5 3251 3 0 0 0 1 +3253 6 2 1160 736 2923 0 0 1 +3253 7 3251 8 0 0 0 0 0 1 +3253 9 3251 1654 2858 3 0 0 0 0 0 1 +3257 1 3254 1 +3257 2 3 3252 1 +3257 3 3254 1 0 1 +3257 4 3 2302 0 0 1 +3257 5 3254 20 0 0 0 1 +3257 6 3 1992 1026 2176 2 0 1 +3257 7 3254 22 0 0 0 0 0 1 +3257 9 3254 2081 1711 1 0 0 0 0 0 1 +3259 1 3256 1 +3259 2 3 3248 1 +3259 3 3256 6 0 1 +3259 4 3 2888 4 0 1 +3259 5 3256 17 0 0 0 1 +3259 6 3 2050 892 1791 0 0 1 +3259 7 3256 1 0 0 0 0 0 1 +3259 9 3256 2286 3016 3 0 0 0 0 0 1 +3271 1 3268 1 +3271 2 3 3269 1 +3271 3 3268 1 0 1 +3271 4 3 2843 3 0 1 +3271 5 3268 1 0 0 0 1 +3271 6 3 959 2172 3031 0 0 1 +3271 7 3268 4 0 0 0 0 0 1 +3271 9 3268 1765 3006 11 0 0 0 0 0 1 +3299 1 3297 1 +3299 2 2 3293 1 +3299 3 3297 2 0 1 +3299 4 2 1855 0 0 1 +3299 5 3297 8 0 0 0 1 +3299 6 2 1901 1806 965 1 0 1 +3299 7 3297 7 0 0 0 0 0 1 +3299 9 3297 2403 100 1 0 0 0 0 0 1 +3301 1 3295 1 +3301 2 6 3297 1 +3301 3 3295 2 0 1 +3301 4 6 1754 2 0 1 +3301 5 3295 2 0 0 0 1 +3301 6 6 893 732 2883 0 0 1 +3301 7 3295 6 0 0 0 0 0 1 +3301 9 3295 2830 3284 9 0 0 0 0 0 1 +3307 1 3305 1 +3307 2 2 3306 1 +3307 3 3305 2 0 1 +3307 4 2 2555 2 0 1 +3307 5 3305 9 0 0 0 1 +3307 6 2 1264 2264 1625 0 0 1 +3307 7 3305 7 0 0 0 0 0 1 +3307 9 3305 2128 2558 2 0 0 0 0 0 1 +3313 1 3303 1 +3313 2 10 3312 1 +3313 3 3303 15 0 1 +3313 4 10 3105 6 0 1 +3313 5 3303 5 0 0 0 1 +3313 6 10 2527 1900 3133 0 0 1 +3313 7 3303 5 0 0 0 0 0 1 +3313 9 3303 193 1954 8 0 0 0 0 0 1 +3319 1 3313 1 +3319 2 6 3317 1 +3319 3 3313 3 0 1 +3319 4 6 3309 7 0 1 +3319 5 3313 12 0 0 0 1 +3319 6 6 3276 833 1883 0 0 1 +3319 7 3313 1 0 0 0 0 0 1 +3319 9 3313 2553 2265 6 0 0 0 0 0 1 +3323 1 3321 1 +3323 2 2 3319 1 +3323 3 3321 2 0 1 +3323 4 2 2982 7 0 1 +3323 5 3321 3 0 0 0 1 +3323 6 2 1089 591 1836 1 0 1 +3323 7 3321 4 0 0 0 0 0 1 +3323 9 3321 987 1801 0 0 0 0 0 0 1 +3329 1 3326 1 +3329 2 3 3328 1 +3329 3 3326 5 0 1 +3329 4 3 3247 7 0 1 +3329 5 3326 9 0 0 0 1 +3329 6 3 631 1163 1915 1 0 1 +3329 7 3326 7 0 0 0 0 0 1 +3329 9 3326 982 204 3 0 0 0 0 0 1 +3331 1 3328 1 +3331 2 3 3322 1 +3331 3 3328 1 0 1 +3331 4 3 1902 7 0 1 +3331 5 3328 5 0 0 0 1 +3331 6 3 419 756 2615 0 0 1 +3343 1 3338 1 +3343 2 5 3342 1 +3343 3 3338 10 0 1 +3343 4 5 3261 3 0 1 +3343 5 3338 15 0 0 0 1 +3343 6 5 1284 436 3081 0 0 1 +3343 7 3338 10 0 0 0 0 0 1 +3343 9 3338 1109 2343 16 0 0 0 0 0 1 +3347 1 3345 1 +3347 2 2 3343 1 +3347 3 3345 3 0 1 +3347 4 2 2846 7 0 1 +3347 5 3345 6 0 0 0 1 +3347 6 2 1196 1277 1699 1 0 1 +3347 7 3345 3 0 0 0 0 0 1 +3347 9 3345 1310 551 4 0 0 0 0 0 1 +3359 1 3348 1 +3359 2 11 3357 1 +3359 3 3348 2 0 1 +3359 4 11 3075 3 0 1 +3359 5 3348 2 0 0 0 1 +3359 6 11 1811 2201 3024 1 0 1 +3359 7 3348 5 0 0 0 0 0 1 +3359 9 3348 3082 3330 6 0 0 0 0 0 1 +3361 1 3339 1 +3361 2 22 3360 1 +3361 3 3339 4 0 1 +3361 4 22 1909 12 0 1 +3361 5 3339 5 0 0 0 1 +3361 6 22 429 102 468 0 0 1 +3361 7 3339 5 0 0 0 0 0 1 +3361 9 3339 3147 1704 5 0 0 0 0 0 1 +3371 1 3369 1 +3371 2 2 3366 1 +3371 3 3369 2 0 1 +3371 4 2 2291 3 0 1 +3371 5 3369 4 0 0 0 1 +3371 6 2 2408 1283 2758 3 0 1 +3373 1 3368 1 +3373 2 5 3372 1 +3373 3 3368 2 0 1 +3373 4 5 3354 20 0 1 +3373 5 3368 1 0 0 0 1 +3373 6 5 1701 2205 2230 0 0 1 +3389 1 3386 1 +3389 2 3 3387 1 +3389 3 3386 6 0 1 +3389 4 3 3385 4 0 1 +3389 5 3386 4 0 0 0 1 +3389 6 3 2246 619 3370 3 0 1 +3391 1 3388 1 +3391 2 3 3389 1 +3391 3 3388 7 0 1 +3391 4 3 2209 6 0 1 +3391 5 3388 5 0 0 0 1 +3391 6 3 38 1728 3156 0 0 1 +3407 1 3402 1 +3407 2 5 3405 1 +3407 3 3402 2 0 1 +3407 4 5 2792 5 0 1 +3407 5 3402 22 0 0 0 1 +3407 6 5 1933 3127 1959 1 0 1 +3413 1 3411 1 +3413 2 2 3405 1 +3413 3 3411 5 0 1 +3413 4 2 2381 5 0 1 +3413 5 3411 9 0 0 0 1 +3413 6 2 1557 3367 2318 2 0 1 +3433 1 3428 1 +3433 2 5 3432 1 +3433 3 3428 5 0 1 +3433 4 5 1930 6 0 1 +3433 5 3428 1 0 0 0 1 +3433 6 5 2465 1603 1777 0 0 1 +3449 1 3446 1 +3449 2 3 3448 1 +3449 3 3446 4 0 1 +3449 4 3 2833 7 0 1 +3449 5 3446 7 0 0 0 1 +3449 6 3 1525 1591 526 1 0 1 +3457 1 3450 1 +3457 2 7 3454 1 +3457 3 3450 8 0 1 +3457 4 7 2376 8 0 1 +3457 5 3450 8 0 0 0 1 +3457 6 7 3136 2416 3421 0 0 1 +3461 1 3459 1 +3461 2 2 3460 1 +3461 3 3459 3 0 1 +3461 4 2 3161 3 0 1 +3461 5 3459 9 0 0 0 1 +3461 6 2 1077 1453 3380 1 0 1 +3463 1 3460 1 +3463 2 3 3461 1 +3463 3 3460 5 0 1 +3463 4 3 3459 4 0 1 +3463 5 3460 1 0 0 0 1 +3463 6 3 2512 2050 491 0 0 1 +3467 1 3465 1 +3467 2 2 3455 1 +3467 3 3465 4 0 1 +3467 4 2 2489 15 0 1 +3467 5 3465 2 0 0 0 1 +3467 6 2 1625 364 3455 1 0 1 +3469 1 3467 1 +3469 2 2 3465 1 +3469 3 3467 6 0 1 +3469 4 2 2383 12 0 1 +3469 5 3467 3 0 0 0 1 +3469 6 2 3457 3451 3465 0 0 1 +3491 1 3489 1 +3491 2 2 3490 1 +3491 3 3489 3 0 1 +3491 4 2 1980 2 0 1 +3491 5 3489 6 0 0 0 1 +3491 6 2 681 1056 2910 2 0 1 +3499 1 3497 1 +3499 2 2 3498 1 +3499 3 3497 4 0 1 +3499 4 2 3149 6 0 1 +3499 5 3497 6 0 0 0 1 +3499 6 2 1570 3394 2404 0 0 1 +3511 1 3504 1 +3511 2 7 3508 1 +3511 3 3504 1 0 1 +3511 4 7 2456 5 0 1 +3511 5 3504 1 0 0 0 1 +3511 6 7 1811 3091 2649 0 0 1 +3517 1 3515 1 +3517 2 2 3516 1 +3517 3 3515 2 0 1 +3517 4 2 2895 3 0 1 +3517 5 3515 2 0 0 0 1 +3517 6 2 646 1777 3426 0 0 1 +3527 1 3522 1 +3527 2 5 3526 1 +3527 3 3522 2 0 1 +3527 4 5 2323 2 0 1 +3527 5 3522 2 0 0 0 1 +3527 6 5 766 3357 2445 2 0 1 +3529 1 3512 1 +3529 2 17 3525 1 +3529 3 3512 1 0 1 +3529 4 17 1957 21 0 1 +3529 5 3512 9 0 0 0 1 +3529 6 17 559 3222 338 0 0 1 +3533 1 3531 1 +3533 2 2 3532 1 +3533 3 3531 2 0 1 +3533 4 2 3345 3 0 1 +3533 5 3531 5 0 0 0 1 +3533 6 2 746 1540 1167 2 0 1 +3539 1 3537 1 +3539 2 2 3525 1 +3539 3 3537 2 0 1 +3539 4 2 3080 4 0 1 +3539 5 3537 8 0 0 0 1 +3539 6 2 294 3273 2694 1 0 1 +3541 1 3534 1 +3541 2 7 3535 1 +3541 3 3534 1 0 1 +3541 4 7 3537 4 0 1 +3541 5 3534 4 0 0 0 1 +3541 6 7 1620 3281 2886 0 0 1 +3547 1 3545 1 +3547 2 2 3546 1 +3547 3 3545 2 0 1 +3547 4 2 3540 8 0 1 +3547 5 3545 6 0 0 0 1 +3547 6 2 3029 624 2127 0 0 1 +3557 1 3555 1 +3557 2 2 3553 1 +3557 3 3555 3 0 1 +3557 4 2 3127 12 0 1 +3557 5 3555 4 0 0 0 1 +3557 6 2 2418 1690 2780 1 0 1 +3559 1 3556 1 +3559 2 3 3558 1 +3559 3 3556 1 0 1 +3559 4 3 1956 2 0 1 +3559 5 3556 3 0 0 0 1 +3559 6 3 3488 412 1908 0 0 1 +3571 1 3569 1 +3571 2 2 3567 1 +3571 3 3569 2 0 1 +3571 4 2 2653 8 0 1 +3571 5 3569 2 0 0 0 1 +3571 6 2 1424 2222 3504 0 0 1 +3581 1 3579 1 +3581 2 2 3577 1 +3581 3 3579 3 0 1 +3581 4 2 2125 6 0 1 +3581 5 3579 14 0 0 0 1 +3581 6 2 1283 1744 316 2 0 1 +3583 1 3580 1 +3583 2 3 3582 1 +3583 3 3580 11 0 1 +3583 4 3 3572 12 0 1 +3583 5 3580 1 0 0 0 1 +3583 6 3 549 607 2464 0 0 1 +3593 1 3590 1 +3593 2 3 3585 1 +3593 3 3590 1 0 1 +3593 4 3 3195 2 0 1 +3593 5 3590 6 0 0 0 1 +3593 6 3 3077 1496 2356 1 0 1 +3607 1 3602 1 +3607 2 5 3605 1 +3607 3 3602 1 0 1 +3607 4 5 2930 17 0 1 +3607 5 3602 10 0 0 0 1 +3607 6 5 3486 3024 913 2 0 1 +3613 1 3611 1 +3613 2 2 3609 1 +3613 3 3611 5 0 1 +3613 4 2 3295 9 0 1 +3613 5 3611 14 0 0 0 1 +3613 6 2 1181 2771 2217 0 0 1 +3617 1 3614 1 +3617 2 3 3605 1 +3617 3 3614 1 0 1 +3617 4 3 2714 0 0 1 +3617 5 3614 4 0 0 0 1 +3617 6 3 825 2384 42 1 0 1 +3623 1 3618 1 +3623 2 5 3616 1 +3623 3 3618 3 0 1 +3623 4 5 1865 2 0 1 +3623 5 3618 12 0 0 0 1 +3623 6 5 3350 1960 2559 3 0 1 +3631 1 3616 1 +3631 2 15 3630 1 +3631 3 3616 1 0 1 +3631 4 15 3231 5 0 1 +3631 5 3616 3 0 0 0 1 +3631 6 15 2672 2089 3556 0 0 1 +3637 1 3635 1 +3637 2 2 3630 1 +3637 3 3635 5 0 1 +3637 4 2 1942 12 0 1 +3637 5 3635 7 0 0 0 1 +3637 6 2 3284 865 1745 0 0 1 +3643 1 3641 1 +3643 2 2 3642 1 +3643 3 3641 5 0 1 +3643 4 2 2103 2 0 1 +3643 5 3641 3 0 0 0 1 +3643 6 2 2646 2013 2118 0 0 1 +3659 1 3657 1 +3659 2 2 3658 1 +3659 3 3657 4 0 1 +3659 4 2 2273 4 0 1 +3659 5 3657 2 0 0 0 1 +3659 6 2 1806 2084 2998 2 0 1 +3671 1 3658 1 +3671 2 13 3667 1 +3671 3 3658 4 0 1 +3671 4 13 3010 6 0 1 +3671 5 3658 9 0 0 0 1 +3671 6 13 1907 728 579 4 0 1 +3673 1 3668 1 +3673 2 5 3670 1 +3673 3 3668 5 0 1 +3673 4 5 2625 10 0 1 +3673 5 3668 2 0 0 0 1 +3673 6 5 54 1117 3020 0 0 1 +3677 1 3675 1 +3677 2 2 3673 1 +3677 3 3675 3 0 1 +3677 4 2 2118 6 0 1 +3677 5 3675 2 0 0 0 1 +3677 6 2 3242 690 3160 2 0 1 +3691 1 3689 1 +3691 2 2 3685 1 +3691 3 3689 2 0 1 +3691 4 2 3456 11 0 1 +3691 5 3689 9 0 0 0 1 +3691 6 2 2293 2814 3611 0 0 1 +3697 1 3692 1 +3697 2 5 3692 1 +3697 3 3692 1 0 1 +3697 4 5 2023 15 0 1 +3697 5 3692 1 0 0 0 1 +3697 6 5 2968 780 3552 0 0 1 +3701 1 3699 1 +3701 2 2 3697 1 +3701 3 3699 3 0 1 +3701 4 2 2072 1 0 1 +3701 5 3699 7 0 0 0 1 +3701 6 2 2528 2741 2061 2 0 1 +3709 1 3707 1 +3709 2 2 3708 1 +3709 3 3707 6 0 1 +3709 4 2 2816 3 0 1 +3709 5 3707 3 0 0 0 1 +3709 6 2 2504 2011 181 0 0 1 +3719 1 3712 1 +3719 2 7 3716 1 +3719 3 3712 5 0 1 +3719 4 7 3402 7 0 1 +3719 5 3712 9 0 0 0 1 +3719 6 7 1864 1919 3182 3 0 1 +3727 1 3724 1 +3727 2 3 3725 1 +3727 3 3724 3 0 1 +3727 4 3 2722 3 0 1 +3727 5 3724 11 0 0 0 1 +3727 6 3 2653 1052 1194 0 0 1 +3733 1 3731 1 +3733 2 2 3729 1 +3733 3 3731 6 0 1 +3733 4 2 3404 6 0 1 +3733 5 3731 11 0 0 0 1 +3733 6 2 3721 3715 3729 0 0 1 +3739 1 3732 1 +3739 2 7 3736 1 +3739 3 3732 11 0 1 +3739 4 7 2830 1 0 1 +3739 5 3732 1 0 0 0 1 +3739 6 7 3724 475 2935 0 0 1 +3761 1 3758 1 +3761 2 3 3760 1 +3761 3 3758 4 0 1 +3761 4 3 3323 4 0 1 +3761 5 3758 8 0 0 0 1 +3761 6 3 2793 2314 272 3 0 1 +3767 1 3762 1 +3767 2 5 3765 1 +3767 3 3762 1 0 1 +3767 4 5 2094 5 0 1 +3767 5 3762 2 0 0 0 1 +3767 6 5 2774 504 2920 1 0 1 +3769 1 3762 1 +3769 2 7 3751 1 +3769 3 3762 1 0 1 +3769 4 7 3487 4 0 1 +3769 5 3762 2 0 0 0 1 +3769 6 7 371 1049 2185 0 0 1 +3779 1 3777 1 +3779 2 2 3774 1 +3779 3 3777 14 0 1 +3779 4 2 2807 3 0 1 +3779 5 3777 11 0 0 0 1 +3779 6 2 158 3225 191 1 0 1 +3793 1 3788 1 +3793 2 5 3788 1 +3793 3 3788 1 0 1 +3793 4 5 3571 10 0 1 +3793 5 3788 7 0 0 0 1 +3793 6 5 2860 3155 3660 0 0 1 +3797 1 3795 1 +3797 2 2 3796 1 +3797 3 3795 2 0 1 +3797 4 2 3340 3 0 1 +3797 5 3795 5 0 0 0 1 +3797 6 2 3487 2754 1721 1 0 1 +3803 1 3801 1 +3803 2 2 3799 1 +3803 3 3801 3 0 1 +3803 4 2 2826 7 0 1 +3803 5 3801 3 0 0 0 1 +3803 6 2 2899 2520 2493 1 0 1 +3821 1 3818 1 +3821 2 3 3819 1 +3821 3 3818 5 0 1 +3821 4 3 2640 14 0 1 +3821 5 3818 4 0 0 0 1 +3821 6 3 242 2236 2523 2 0 1 +3823 1 3820 1 +3823 2 3 3822 1 +3823 3 3820 3 0 1 +3823 4 3 2316 18 0 1 +3823 5 3820 3 0 0 0 1 +3823 6 3 3256 688 2440 0 0 1 +3833 1 3830 1 +3833 2 3 3827 1 +3833 3 3830 7 0 1 +3833 4 3 2810 1 0 1 +3833 5 3830 3 0 0 0 1 +3833 6 3 2090 3555 3536 1 0 1 +3847 1 3842 1 +3847 2 5 3845 1 +3847 3 3842 1 0 1 +3847 4 5 2007 17 0 1 +3847 5 3842 2 0 0 0 1 +3847 6 5 2960 2951 3576 0 0 1 +3851 1 3849 1 +3851 2 2 3847 1 +3851 3 3849 2 0 1 +3851 4 2 2109 7 0 1 +3851 5 3849 2 0 0 0 1 +3851 6 2 538 2883 1595 1 0 1 +3853 1 3851 1 +3853 2 2 3852 1 +3853 3 3851 2 0 1 +3853 4 2 3714 9 0 1 +3853 5 3851 7 0 0 0 1 +3853 6 2 1061 683 3379 0 0 1 +3863 1 3858 1 +3863 2 5 3858 1 +3863 3 3858 1 0 1 +3863 4 5 3343 7 0 1 +3863 5 3858 6 0 0 0 1 +3863 6 5 2842 3189 2955 1 0 1 +3877 1 3875 1 +3877 2 2 3876 1 +3877 3 3875 2 0 1 +3877 4 2 2067 6 0 1 +3877 5 3875 4 0 0 0 1 +3877 6 2 2388 1029 2690 0 0 1 +3881 1 3868 1 +3881 2 13 3879 1 +3881 3 3868 18 0 1 +3881 4 13 3449 9 0 1 +3881 5 3868 6 0 0 0 1 +3881 6 13 1214 1806 2289 2 0 1 +3889 1 3878 1 +3889 2 11 3888 1 +3889 3 3878 4 0 1 +3889 4 11 2189 12 0 1 +3889 5 3878 3 0 0 0 1 +3889 6 11 418 1211 2603 0 0 1 +3907 1 3905 1 +3907 2 2 3903 1 +3907 3 3905 5 0 1 +3907 4 2 2057 8 0 1 +3907 5 3905 2 0 0 0 1 +3907 6 2 2140 3244 3396 4 0 1 +3911 1 3898 1 +3911 2 13 3909 1 +3911 3 3898 2 0 1 +3911 4 13 3384 3 0 1 +3911 5 3898 7 0 0 0 1 +3911 6 13 509 2434 770 3 0 1 +3917 1 3915 1 +3917 2 2 3913 1 +3917 3 3915 3 0 1 +3917 4 2 3340 6 0 1 +3917 5 3915 6 0 0 0 1 +3917 6 2 2753 2025 635 2 0 1 +3919 1 3916 1 +3919 2 3 3914 1 +3919 3 3916 20 0 1 +3919 4 3 3459 7 0 1 +3919 5 3916 1 0 0 0 1 +3919 6 3 3364 1782 1393 0 0 1 +3923 1 3921 1 +3923 2 2 3922 1 +3923 3 3921 2 0 1 +3923 4 2 3517 11 0 1 +3923 5 3921 2 0 0 0 1 +3923 6 2 2908 1332 444 2 0 1 +3929 1 3926 1 +3929 2 3 3928 1 +3929 3 3926 4 0 1 +3929 4 3 3318 7 0 1 +3929 5 3926 4 0 0 0 1 +3929 6 3 3588 3864 2235 1 0 1 +3931 1 3929 1 +3931 2 2 3927 1 +3931 3 3929 6 0 1 +3931 4 2 2867 8 0 1 +3931 5 3929 5 0 0 0 1 +3931 6 2 3919 3913 3927 0 0 1 +3943 1 3940 1 +3943 2 3 3941 1 +3943 3 3940 5 0 1 +3943 4 3 3258 3 0 1 +3943 5 3940 18 0 0 0 1 +3943 6 3 344 3559 2762 0 0 1 +3947 1 3945 1 +3947 2 2 3946 1 +3947 3 3945 3 0 1 +3947 4 2 3940 8 0 1 +3947 5 3945 29 0 0 0 1 +3947 6 2 2244 2906 2996 1 0 1 +3967 1 3961 1 +3967 2 6 3966 1 +3967 3 3961 1 0 1 +3967 4 6 2458 2 0 1 +3967 5 3961 4 0 0 0 1 +3967 6 6 768 313 254 1 0 1 +3989 1 3987 1 +3989 2 2 3988 1 +3989 3 3987 10 0 1 +3989 4 2 3348 3 0 1 +3989 5 3987 21 0 0 0 1 +3989 6 2 1169 1437 2331 2 0 1 +4001 1 3998 1 +4001 2 3 4000 1 +4001 3 3998 4 0 1 +4001 4 3 2873 7 0 1 +4001 5 3998 5 0 0 0 1 +4001 6 3 1714 3347 624 3 0 1 +4003 1 4001 1 +4003 2 2 4002 1 +4003 3 4001 2 0 1 +4003 4 2 3996 8 0 1 +4003 5 4001 28 0 0 0 1 +4003 6 2 139 3070 2275 0 0 1 +4007 1 4002 1 +4007 2 5 4005 1 +4007 3 4002 9 0 1 +4007 4 5 2773 8 0 1 +4007 5 4002 9 0 0 0 1 +4007 6 5 738 297 3896 1 0 1 +4013 1 4011 1 +4013 2 2 4009 1 +4013 3 4011 3 0 1 +4013 4 2 2953 9 0 1 +4013 5 4011 8 0 0 0 1 +4013 6 2 312 1603 3671 1 0 1 +4019 1 4017 1 +4019 2 2 4015 1 +4019 3 4017 3 0 1 +4019 4 2 3470 7 0 1 +4019 5 4017 7 0 0 0 1 +4019 6 2 3869 2830 3408 1 0 1 +4021 1 4019 1 +4021 2 2 4020 1 +4021 3 4019 5 0 1 +4021 4 2 2365 3 0 1 +4021 5 4019 5 0 0 0 1 +4021 6 2 3492 2818 1504 0 0 1 +4027 1 4024 1 +4027 2 3 4020 1 +4027 3 4024 3 0 1 +4027 4 3 3765 2 0 1 +4027 5 4024 1 0 0 0 1 +4027 6 3 423 4007 3986 0 0 1 +4049 1 4046 1 +4049 2 3 4043 1 +4049 3 4046 3 0 1 +4049 4 3 4037 0 0 1 +4049 5 4046 12 0 0 0 1 +4049 6 3 1007 3235 653 2 0 1 +4051 1 4041 1 +4051 2 10 4050 1 +4051 3 4041 2 0 1 +4051 4 10 2367 5 0 1 +4051 5 4041 1 0 0 0 1 +4051 6 10 1767 3082 701 0 0 1 +4057 1 4052 1 +4057 2 5 4056 1 +4057 3 4052 2 0 1 +4057 4 5 2914 6 0 1 +4057 5 4052 2 0 0 0 1 +4057 6 5 1797 3212 2395 2 0 1 +4073 1 4070 1 +4073 2 3 4061 1 +4073 3 4070 4 0 1 +4073 4 3 3117 0 0 1 +4073 5 4070 8 0 0 0 1 +4073 6 3 2900 4001 3356 3 0 1 +4079 1 4068 1 +4079 2 11 4076 1 +4079 3 4068 2 0 1 +4079 4 11 3922 8 0 1 +4079 5 4068 3 0 0 0 1 +4079 6 11 265 679 1978 1 0 1 +4091 1 4089 1 +4091 2 2 4090 1 +4091 3 4089 3 0 1 +4091 4 2 4084 8 0 1 +4091 5 4089 12 0 0 0 1 +4091 6 2 155 771 4021 2 0 1 +4093 1 4091 1 +4093 2 2 4092 1 +4093 3 4091 4 0 1 +4093 4 2 3106 6 0 1 +4093 5 4091 2 0 0 0 1 +4093 6 2 1942 1514 2807 0 0 1 +4099 1 4097 1 +4099 2 2 4095 1 +4099 3 4097 2 0 1 +4099 4 2 3462 8 0 1 +4099 5 4097 2 0 0 0 1 +4099 6 2 2299 633 3078 0 0 1 +4111 1 4099 1 +4111 2 12 4110 1 +4111 3 4099 4 0 1 +4111 4 12 3586 5 0 1 +4111 5 4099 4 0 0 0 1 +4111 6 12 1053 973 3920 0 0 1 +4127 1 4122 1 +4127 2 5 4125 1 +4127 3 4122 1 0 1 +4127 4 5 2630 5 0 1 +4127 5 4122 3 0 0 0 1 +4127 6 5 1872 1197 3436 1 0 1 +4129 1 4116 1 +4129 2 13 4120 1 +4129 3 4116 1 0 1 +4129 4 13 3348 48 0 1 +4129 5 4116 7 0 0 0 1 +4129 6 13 64 3902 3622 0 0 1 +4133 1 4131 1 +4133 2 2 4132 1 +4133 3 4131 3 0 1 +4133 4 2 2646 3 0 1 +4133 5 4131 12 0 0 0 1 +4133 6 2 849 3596 3591 1 0 1 +4139 1 4137 1 +4139 2 2 4135 1 +4139 3 4137 2 0 1 +4139 4 2 3367 8 0 1 +4139 5 4137 5 0 0 0 1 +4139 6 2 3148 2490 3012 2 0 1 +4153 1 4148 1 +4153 2 5 4150 1 +4153 3 4148 1 0 1 +4153 4 5 2470 16 0 1 +4153 5 4148 7 0 0 0 1 +4153 6 5 1334 1363 1137 0 0 1 +4157 1 4155 1 +4157 2 2 4156 1 +4157 3 4155 3 0 1 +4157 4 2 3798 3 0 1 +4157 5 4155 6 0 0 0 1 +4157 6 2 1241 1691 2413 1 0 1 +4159 1 4156 1 +4159 2 3 4157 1 +4159 3 4156 3 0 1 +4159 4 3 4155 4 0 1 +4159 5 4156 1 0 0 0 1 +4159 6 3 524 318 2954 0 0 1 +4177 1 4172 1 +4177 2 5 4174 1 +4177 3 4172 3 0 1 +4177 4 5 2899 10 0 1 +4177 5 4172 2 0 0 0 1 +4177 6 5 2637 2547 2641 0 0 1 +4201 1 4190 1 +4201 2 11 4200 1 +4201 3 4190 1 0 1 +4201 4 11 2944 12 0 1 +4201 5 4190 1 0 0 0 1 +4201 6 11 4121 1043 4040 0 0 1 +4211 1 4205 1 +4211 2 6 4208 1 +4211 3 4205 3 0 1 +4211 4 6 4052 4 0 1 +4211 5 4205 11 0 0 0 1 +4211 6 6 2570 1635 4208 3 0 1 +4217 1 4214 1 +4217 2 3 4212 1 +4217 3 4214 1 0 1 +4217 4 3 4045 0 0 1 +4217 5 4214 9 0 0 0 1 +4217 6 3 2712 633 2499 1 0 1 +4219 1 4217 1 +4219 2 2 4218 1 +4219 3 4217 6 0 1 +4219 4 2 4212 8 0 1 +4219 5 4217 6 0 0 0 1 +4219 6 2 2522 1265 3909 0 0 1 +4229 1 4227 1 +4229 2 2 4225 1 +4229 3 4227 3 0 1 +4229 4 2 2478 7 0 1 +4229 5 4227 3 0 0 0 1 +4229 6 2 1927 83 427 1 0 1 +4231 1 4228 1 +4231 2 3 4230 1 +4231 3 4228 4 0 1 +4231 4 3 3325 3 0 1 +4231 5 4228 10 0 0 0 1 +4231 6 3 956 953 3565 0 0 1 +4241 1 4238 1 +4241 2 3 4235 1 +4241 3 4238 5 0 1 +4241 4 3 4229 0 0 1 +4241 5 4238 19 0 0 0 1 +4241 6 3 1001 170 2946 1 0 1 +4243 1 4241 1 +4243 2 2 4239 1 +4243 3 4241 6 0 1 +4243 4 2 2742 8 0 1 +4243 5 4241 5 0 0 0 1 +4243 6 2 4231 4225 4239 0 0 1 +4253 1 4251 1 +4253 2 2 4249 1 +4253 3 4251 3 0 1 +4253 4 2 2244 6 0 1 +4253 5 4251 2 0 0 0 1 +4253 6 2 3397 1152 2531 5 0 1 +4259 1 4257 1 +4259 2 2 4246 1 +4259 3 4257 4 0 1 +4259 4 2 3422 0 0 1 +4259 5 4257 6 0 0 0 1 +4259 6 2 3885 1573 4168 3 0 1 +4261 1 4259 1 +4261 2 2 4260 1 +4261 3 4259 6 0 1 +4261 4 2 4254 8 0 1 +4261 5 4259 4 0 0 0 1 +4261 6 2 3462 1719 2416 0 0 1 +4271 1 4264 1 +4271 2 7 4269 1 +4271 3 4264 3 0 1 +4271 4 7 2992 4 0 1 +4271 5 4264 8 0 0 0 1 +4271 6 7 2631 1442 2342 2 0 1 +4273 1 4268 1 +4273 2 5 4268 1 +4273 3 4268 1 0 1 +4273 4 5 2546 10 0 1 +4273 5 4268 1 0 0 0 1 +4273 6 5 1236 2690 1754 0 0 1 +4283 1 4281 1 +4283 2 2 4279 1 +4283 3 4281 2 0 1 +4283 4 2 3405 11 0 1 +4283 5 4281 2 0 0 0 1 +4283 6 2 187 3765 1768 3 0 1 +4289 1 4286 1 +4289 2 3 4283 1 +4289 3 4286 4 0 1 +4289 4 3 4277 0 0 1 +4289 5 4286 1 0 0 0 1 +4289 6 3 295 148 3642 1 0 1 +4297 1 4292 1 +4297 2 5 4296 1 +4297 3 4292 3 0 1 +4297 4 5 3648 6 0 1 +4297 5 4292 1 0 0 0 1 +4297 6 5 3561 3069 3822 0 0 1 +4327 1 4324 1 +4327 2 3 4325 1 +4327 3 4324 4 0 1 +4327 4 3 2389 3 0 1 +4327 5 4324 1 0 0 0 1 +4327 6 3 1155 3649 3566 0 0 1 +4337 1 4334 1 +4337 2 3 4330 1 +4337 3 4334 3 0 1 +4337 4 3 4175 1 0 1 +4337 5 4334 1 0 0 0 1 +4337 6 3 55 176 3754 1 0 1 +4339 1 4329 1 +4339 2 10 4337 1 +4339 3 4329 11 0 1 +4339 4 10 2523 8 0 1 +4339 5 4329 1 0 0 0 1 +4339 6 10 2434 2335 3625 0 0 1 +4349 1 4347 1 +4349 2 2 4345 1 +4349 3 4347 2 0 1 +4349 4 2 2432 6 0 1 +4349 5 4347 8 0 0 0 1 +4349 6 2 4221 3320 4068 2 0 1 +4357 1 4355 1 +4357 2 2 4356 1 +4357 3 4355 2 0 1 +4357 4 2 3793 6 0 1 +4357 5 4355 6 0 0 0 1 +4357 6 2 2229 1623 3187 0 0 1 +4363 1 4361 1 +4363 2 2 4359 1 +4363 3 4361 6 0 1 +4363 4 2 4144 8 0 1 +4363 5 4361 14 0 0 0 1 +4363 6 2 4351 4345 4359 0 0 1 +4373 1 4371 1 +4373 2 2 4367 1 +4373 3 4371 2 0 1 +4373 4 2 2568 1 0 1 +4373 5 4371 7 0 0 0 1 +4373 6 2 3528 4263 3992 4 0 1 +4391 1 4377 1 +4391 2 14 4388 1 +4391 3 4377 1 0 1 +4391 4 14 2791 4 0 1 +4391 5 4377 2 0 0 0 1 +4391 6 14 3177 2954 3175 1 0 1 +4397 1 4395 1 +4397 2 2 4393 1 +4397 3 4395 3 0 1 +4397 4 2 2377 6 0 1 +4397 5 4395 5 0 0 0 1 +4397 6 2 1409 3598 4101 1 0 1 +4409 1 4406 1 +4409 2 3 4403 1 +4409 3 4406 3 0 1 +4409 4 3 4397 0 0 1 +4409 5 4406 11 0 0 0 1 +4409 6 3 2342 2421 2996 2 0 1 +4421 1 4418 1 +4421 2 3 4420 1 +4421 3 4418 6 0 1 +4421 4 3 3830 3 0 1 +4421 5 4418 18 0 0 0 1 +4421 6 3 1494 1122 4112 2 0 1 +4423 1 4420 1 +4423 2 3 4417 1 +4423 3 4420 3 0 1 +4423 4 3 4411 0 0 1 +4423 5 4420 3 0 0 0 1 +4423 6 3 3440 4067 3428 0 0 1 +4441 1 4420 1 +4441 2 21 4440 1 +4441 3 4420 2 0 1 +4441 4 21 4142 8 0 1 +4441 5 4420 5 0 0 0 1 +4441 6 21 3103 3247 629 1 0 1 +4447 1 4444 1 +4447 2 3 4445 1 +4447 3 4444 1 0 1 +4447 4 3 2739 6 0 1 +4447 5 4444 3 0 0 0 1 +4447 6 3 775 3099 2489 0 0 1 +4451 1 4449 1 +4451 2 2 4447 1 +4451 3 4449 3 0 1 +4451 4 2 3166 16 0 1 +4451 5 4449 3 0 0 0 1 +4451 6 2 256 3346 1419 1 0 1 +4457 1 4454 1 +4457 2 3 4452 1 +4457 3 4454 3 0 1 +4457 4 3 4268 0 0 1 +4457 5 4454 1 0 0 0 1 +4457 6 3 2943 3671 2423 1 0 1 +4463 1 4458 1 +4463 2 5 4460 1 +4463 3 4458 1 0 1 +4463 4 5 2602 6 0 1 +4463 5 4458 2 0 0 0 1 +4463 6 5 280 3180 1205 2 0 1 +4481 1 4478 1 +4481 2 3 4468 1 +4481 3 4478 4 0 1 +4481 4 3 3892 1 0 1 +4481 5 4478 1 0 0 0 1 +4481 6 3 4213 3703 3999 1 0 1 +4483 1 4481 1 +4483 2 2 4482 1 +4483 3 4481 2 0 1 +4483 4 2 4367 2 0 1 +4483 5 4481 6 0 0 0 1 +4483 6 2 2616 1198 695 0 0 1 +4493 1 4491 1 +4493 2 2 4489 1 +4493 3 4491 2 0 1 +4493 4 2 4132 1 0 1 +4493 5 4491 2 0 0 0 1 +4493 6 2 3144 2017 1085 1 0 1 +4507 1 4505 1 +4507 2 2 4503 1 +4507 3 4505 6 0 1 +4507 4 2 2907 1 0 1 +4507 5 4505 11 0 0 0 1 +4507 6 2 4495 4489 4503 0 0 1 +4513 1 4506 1 +4513 2 7 4510 1 +4513 3 4506 1 0 1 +4513 4 7 2378 8 0 1 +4513 5 4506 2 0 0 0 1 +4513 6 7 3674 235 3867 0 0 1 +4517 1 4515 1 +4517 2 2 4512 1 +4517 3 4515 11 0 1 +4517 4 2 4284 0 0 1 +4517 5 4515 3 0 0 0 1 +4517 6 2 1108 3536 3489 2 0 1 +4519 1 4516 1 +4519 2 3 4517 1 +4519 3 4516 6 0 1 +4519 4 3 4515 4 0 1 +4519 5 4516 1 0 0 0 1 +4519 6 3 2478 149 3566 2 0 1 +4523 1 4518 1 +4523 2 5 4520 1 +4523 3 4518 2 0 1 +4523 4 5 3148 4 0 1 +4523 5 4518 11 0 0 0 1 +4523 6 5 1902 3411 3259 2 0 1 +4547 1 4545 1 +4547 2 2 4541 1 +4547 3 4545 4 0 1 +4547 4 2 4148 4 0 1 +4547 5 4545 2 0 0 0 1 +4547 6 2 1387 3790 2417 2 0 1 +4549 1 4543 1 +4549 2 6 4545 1 +4549 3 4543 2 0 1 +4549 4 6 4058 2 0 1 +4549 5 4543 3 0 0 0 1 +4549 6 6 46 4336 886 0 0 1 +4561 1 4550 1 +4561 2 11 4560 1 +4561 3 4550 2 0 1 +4561 4 11 4381 12 0 1 +4561 5 4550 9 0 0 0 1 +4561 6 11 1145 3578 2777 0 0 1 +4567 1 4564 1 +4567 2 3 4566 1 +4567 3 4564 1 0 1 +4567 4 3 2779 5 0 1 +4567 5 4564 13 0 0 0 1 +4567 6 3 3246 976 4123 3 0 1 +4583 1 4578 1 +4583 2 5 4581 1 +4583 3 4578 2 0 1 +4583 4 5 4571 11 0 1 +4583 5 4578 1 0 0 0 1 +4583 6 5 53 4496 4242 1 0 1 +4591 1 4580 1 +4591 2 11 4590 1 +4591 3 4580 2 0 1 +4591 4 11 2962 2 0 1 +4591 5 4580 6 0 0 0 1 +4591 6 11 957 2109 2806 0 0 1 +4597 1 4592 1 +4597 2 5 4596 1 +4597 3 4592 1 0 1 +4597 4 5 4179 3 0 1 +4597 5 4592 6 0 0 0 1 +4597 6 5 2664 3847 2401 0 0 1 +4603 1 4601 1 +4603 2 2 4599 1 +4603 3 4601 6 0 1 +4603 4 2 4153 8 0 1 +4603 5 4601 3 0 0 0 1 +4603 6 2 4591 4585 4599 0 0 1 +4621 1 4619 1 +4621 2 2 4617 1 +4621 3 4619 2 0 1 +4621 4 2 4013 6 0 1 +4621 5 4619 7 0 0 0 1 +4621 6 2 1100 2174 879 0 0 1 +4637 1 4635 1 +4637 2 2 4631 1 +4637 3 4635 9 0 1 +4637 4 2 2395 4 0 1 +4637 5 4635 2 0 0 0 1 +4637 6 2 305 4319 808 1 0 1 +4639 1 4636 1 +4639 2 3 4637 1 +4639 3 4636 1 0 1 +4639 4 3 3896 3 0 1 +4639 5 4636 19 0 0 0 1 +4639 6 3 1317 1809 1606 0 0 1 +4643 1 4638 1 +4643 2 5 4634 1 +4643 3 4638 3 0 1 +4643 4 5 2546 1 0 1 +4643 5 4638 11 0 0 0 1 +4643 6 5 3845 2560 4022 1 0 1 +4649 1 4646 1 +4649 2 3 4648 1 +4649 3 4646 1 0 1 +4649 4 3 4013 4 0 1 +4649 5 4646 8 0 0 0 1 +4649 6 3 2396 3040 479 2 0 1 +4651 1 4648 1 +4651 2 3 4642 1 +4651 3 4648 6 0 1 +4651 4 3 3318 6 0 1 +4651 5 4648 8 0 0 0 1 +4651 6 3 843 1576 4195 0 0 1 +4657 1 4642 1 +4657 2 15 4652 1 +4657 3 4642 6 0 1 +4657 4 15 3692 0 0 1 +4657 5 4642 24 0 0 0 1 +4657 6 15 2713 2474 4346 0 0 1 +4663 1 4660 1 +4663 2 3 4662 1 +4663 3 4660 3 0 1 +4663 4 3 3855 5 0 1 +4663 5 4660 13 0 0 0 1 +4663 6 3 4017 2517 4263 0 0 1 +4673 1 4670 1 +4673 2 3 4668 1 +4673 3 4670 1 0 1 +4673 4 3 2460 0 0 1 +4673 5 4670 15 0 0 0 1 +4673 6 3 865 3238 160 4 0 1 +4679 1 4668 1 +4679 2 11 4677 1 +4679 3 4668 2 0 1 +4679 4 11 4414 3 0 1 +4679 5 4668 2 0 0 0 1 +4679 6 11 184 2733 3552 1 0 1 +4691 1 4689 1 +4691 2 2 4684 1 +4691 3 4689 2 0 1 +4691 4 2 4509 0 0 1 +4691 5 4689 9 0 0 0 1 +4691 6 2 4288 4489 3051 1 0 1 +4703 1 4698 1 +4703 2 5 4702 1 +4703 3 4698 5 0 1 +4703 4 5 3012 4 0 1 +4703 5 4698 1 0 0 0 1 +4703 6 5 3972 487 3929 3 0 1 +4721 1 4715 1 +4721 2 6 4718 1 +4721 3 4715 7 0 1 +4721 4 6 4464 0 0 1 +4721 5 4715 2 0 0 0 1 +4721 6 6 693 182 858 1 0 1 +4723 1 4721 1 +4723 2 2 4722 1 +4723 3 4721 2 0 1 +4723 4 2 4408 7 0 1 +4723 5 4721 5 0 0 0 1 +4723 6 2 4018 2920 2673 2 0 1 +4729 1 4712 1 +4729 2 17 4718 1 +4729 3 4712 1 0 1 +4729 4 17 4536 22 0 1 +4729 5 4712 4 0 0 0 1 +4729 6 17 2614 4300 4551 0 0 1 +4733 1 4728 1 +4733 2 5 4721 1 +4733 3 4728 7 0 1 +4733 4 5 3462 0 0 1 +4733 5 4728 10 0 0 0 1 +4733 6 5 1 969 4094 5 0 1 +4751 1 4732 1 +4751 2 19 4747 1 +4751 3 4732 4 0 1 +4751 4 19 3565 9 0 1 +4751 5 4732 1 0 0 0 1 +4751 6 19 4544 1906 704 1 0 1 +4759 1 4756 1 +4759 2 3 4753 1 +4759 3 4756 1 0 1 +4759 4 3 2513 7 0 1 +4759 5 4756 5 0 0 0 1 +4759 6 3 3147 1700 1939 0 0 1 +4783 1 4777 1 +4783 2 6 4782 1 +4783 3 4777 8 0 1 +4783 4 6 4466 3 0 1 +4783 5 4777 11 0 0 0 1 +4783 6 6 4214 3223 2342 0 0 1 +4787 1 4785 1 +4787 2 2 4783 1 +4787 3 4785 2 0 1 +4787 4 2 3115 7 0 1 +4787 5 4785 8 0 0 0 1 +4787 6 2 4307 4559 3742 2 0 1 +4789 1 4787 1 +4789 2 2 4784 1 +4789 3 4787 2 0 1 +4789 4 2 3684 15 0 1 +4789 5 4787 3 0 0 0 1 +4789 6 2 1158 1476 1036 0 0 1 +4793 1 4790 1 +4793 2 3 4792 1 +4793 3 4790 16 0 1 +4793 4 3 2583 4 0 1 +4793 5 4790 1 0 0 0 1 +4793 6 3 4483 930 3 2 0 1 +4799 1 4792 1 +4799 2 7 4798 1 +4799 3 4792 8 0 1 +4799 4 7 4439 2 0 1 +4799 5 4792 1 0 0 0 1 +4799 6 7 4125 600 2053 1 0 1 +4801 1 4794 1 +4801 2 7 4798 1 +4801 3 4794 1 0 1 +4801 4 7 2998 31 0 1 +4801 5 4794 1 0 0 0 1 +4801 6 7 3631 2238 4495 0 0 1 +4813 1 4811 1 +4813 2 2 4809 1 +4813 3 4811 4 0 1 +4813 4 2 4308 12 0 1 +4813 5 4811 4 0 0 0 1 +4813 6 2 1051 1931 2681 0 0 1 +4817 1 4814 1 +4817 2 3 4816 1 +4817 3 4814 1 0 1 +4817 4 3 3744 7 0 1 +4817 5 4814 3 0 0 0 1 +4817 6 3 4496 2100 3364 1 0 1 +4831 1 4828 1 +4831 2 3 4830 1 +4831 3 4828 5 0 1 +4831 4 3 2775 2 0 1 +4831 5 4828 3 0 0 0 1 +4831 6 3 1713 4453 2779 0 0 1 +4861 1 4850 1 +4861 2 11 4859 1 +4861 3 4850 5 0 1 +4861 4 11 3500 9 0 1 +4861 5 4850 4 0 0 0 1 +4861 6 11 2959 2621 2014 0 0 1 +4871 1 4860 1 +4871 2 11 4870 1 +4871 3 4860 7 0 1 +4871 4 11 3209 10 0 1 +4871 5 4860 1 0 0 0 1 +4871 6 11 812 73 4465 2 0 1 +4877 1 4875 1 +4877 2 2 4876 1 +4877 3 4875 3 0 1 +4877 4 2 4589 6 0 1 +4877 5 4875 2 0 0 0 1 +4877 6 2 3454 4507 1653 2 0 1 +4889 1 4886 1 +4889 2 3 4883 1 +4889 3 4886 1 0 1 +4889 4 3 4877 0 0 1 +4889 5 4886 7 0 0 0 1 +4889 6 3 1718 2917 4840 2 0 1 +4903 1 4900 1 +4903 2 3 4902 1 +4903 3 4900 4 0 1 +4903 4 3 2979 2 0 1 +4903 5 4900 8 0 0 0 1 +4903 6 3 1702 1305 1797 0 0 1 +4909 1 4903 1 +4909 2 6 4908 1 +4909 3 4903 6 0 1 +4909 4 6 3865 7 0 1 +4909 5 4903 6 0 0 0 1 +4909 6 6 2599 3481 4769 0 0 1 +4919 1 4906 1 +4919 2 13 4915 1 +4919 3 4906 1 0 1 +4919 4 13 4686 9 0 1 +4919 5 4906 6 0 0 0 1 +4919 6 13 2943 4045 3643 2 0 1 +4931 1 4925 1 +4931 2 6 4928 1 +4931 3 4925 3 0 1 +4931 4 6 3112 7 0 1 +4931 5 4925 7 0 0 0 1 +4931 6 6 1657 4017 1703 1 0 1 +4933 1 4931 1 +4933 2 2 4932 1 +4933 3 4931 2 0 1 +4933 4 2 4500 6 0 1 +4933 5 4931 2 0 0 0 1 +4933 6 2 129 4255 3313 0 0 1 +4937 1 4934 1 +4937 2 3 4926 1 +4937 3 4934 1 0 1 +4937 4 3 4763 5 0 1 +4937 5 4934 7 0 0 0 1 +4937 6 3 3800 3340 3079 6 0 1 +4943 1 4936 1 +4943 2 7 4940 1 +4943 3 4936 2 0 1 +4943 4 7 4276 4 0 1 +4943 5 4936 1 0 0 0 1 +4943 6 7 4160 1268 4619 1 0 1 +4951 1 4945 1 +4951 2 6 4949 1 +4951 3 4945 1 0 1 +4951 4 6 3348 4 0 1 +4951 5 4945 4 0 0 0 1 +4951 6 6 3464 4044 4102 0 0 1 +4957 1 4955 1 +4957 2 2 4953 1 +4957 3 4955 6 0 1 +4957 4 2 3521 6 0 1 +4957 5 4955 3 0 0 0 1 +4957 6 2 4945 4939 4953 0 0 1 +4967 1 4962 1 +4967 2 5 4966 1 +4967 3 4962 3 0 1 +4967 4 5 3184 12 0 1 +4967 5 4962 1 0 0 0 1 +4967 6 5 950 3727 466 3 0 1 +4969 1 4958 1 +4969 2 11 4966 1 +4969 3 4958 1 0 1 +4969 4 11 4047 14 0 1 +4969 5 4958 3 0 0 0 1 +4969 6 11 639 155 4528 0 0 1 +4973 1 4971 1 +4973 2 2 4972 1 +4973 3 4971 2 0 1 +4973 4 2 2632 6 0 1 +4973 5 4971 11 0 0 0 1 +4973 6 2 4155 4621 2573 3 0 1 +4987 1 4985 1 +4987 2 2 4986 1 +4987 3 4985 2 0 1 +4987 4 2 4814 2 0 1 +4987 5 4985 5 0 0 0 1 +4987 6 2 3525 4440 4786 0 0 1 +4993 1 4988 1 +4993 2 5 4992 1 +4993 3 4988 3 0 1 +4993 4 5 4297 6 0 1 +4993 5 4988 2 0 0 0 1 +4993 6 5 1106 3867 2646 2 0 1 +4999 1 4996 1 +4999 2 3 4997 1 +4999 3 4996 1 0 1 +4999 4 3 4799 3 0 1 +4999 5 4996 26 0 0 0 1 +4999 6 3 2779 360 4996 0 0 1 +5003 1 5001 1 +5003 2 2 4999 1 +5003 3 5001 2 0 1 +5003 4 2 4493 11 0 1 +5003 5 5001 6 0 0 0 1 +5003 6 2 4980 1719 2697 1 0 1 +5009 1 5006 1 +5009 2 3 5003 1 +5009 3 5006 6 0 1 +5009 4 3 4997 0 0 1 +5009 5 5006 7 0 0 0 1 +5009 6 3 2797 3783 4178 2 0 1 +5011 1 5009 1 +5011 2 2 5010 1 +5011 3 5009 4 0 1 +5011 4 2 4242 10 0 1 +5011 5 5009 3 0 0 0 1 +5011 6 2 4952 3074 3137 0 0 1 +5021 1 5018 1 +5021 2 3 5000 1 +5021 3 5018 1 0 1 +5021 4 3 3369 3 0 1 +5021 5 5018 4 0 0 0 1 +5021 6 3 536 4470 3582 1 0 1 +5023 1 5020 1 +5023 2 3 5022 1 +5023 3 5020 4 0 1 +5023 4 3 2666 2 0 1 +5023 5 5020 1 0 0 0 1 +5023 6 3 4661 406 4842 0 0 1 +5039 1 5028 1 +5039 2 11 5035 1 +5039 3 5028 1 0 1 +5039 4 11 2763 7 0 1 +5039 5 5028 2 0 0 0 1 +5039 6 11 1402 3485 389 1 0 1 +5051 1 5049 1 +5051 2 2 5047 1 +5051 3 5049 2 0 1 +5051 4 2 3758 8 0 1 +5051 5 5049 7 0 0 0 1 +5051 6 2 2908 2629 3492 2 0 1 +5059 1 5057 1 +5059 2 2 5055 1 +5059 3 5057 6 0 1 +5059 4 2 3985 1 0 1 +5059 5 5057 2 0 0 0 1 +5059 6 2 5047 5041 5055 0 0 1 +5077 1 5075 1 +5077 2 2 5073 1 +5077 3 5075 6 0 1 +5077 4 2 3432 6 0 1 +5077 5 5075 3 0 0 0 1 +5077 6 2 5065 5059 5073 0 0 1 +5081 1 5078 1 +5081 2 3 5070 1 +5081 3 5078 1 0 1 +5081 4 3 3582 0 0 1 +5081 5 5078 5 0 0 0 1 +5081 6 3 1571 2217 3364 3 0 1 +5087 1 5082 1 +5087 2 5 5086 1 +5087 3 5082 19 0 1 +5087 4 5 3574 2 0 1 +5087 5 5082 5 0 0 0 1 +5087 6 5 1424 3477 3422 1 0 1 +5099 1 5097 1 +5099 2 2 5098 1 +5099 3 5097 3 0 1 +5099 4 2 5092 8 0 1 +5099 5 5097 4 0 0 0 1 +5099 6 2 4903 38 759 1 0 1 +5101 1 5095 1 +5101 2 6 5097 1 +5101 3 5095 2 0 1 +5101 4 6 5097 6 0 1 +5101 5 5095 4 0 0 0 1 +5101 6 6 3421 4320 4789 0 0 1 +5107 1 5105 1 +5107 2 2 5103 1 +5107 3 5105 5 0 1 +5107 4 2 4396 13 0 1 +5107 5 5105 5 0 0 0 1 +5107 6 2 2785 1583 3796 0 0 1 +5113 1 5094 1 +5113 2 19 5109 1 +5113 3 5094 11 0 1 +5113 4 19 3501 23 0 1 +5113 5 5094 5 0 0 0 1 +5113 6 19 1417 4051 4963 2 0 1 +5119 1 5116 1 +5119 2 3 5117 1 +5119 3 5116 3 0 1 +5119 4 3 4529 3 0 1 +5119 5 5116 4 0 0 0 1 +5119 6 3 4512 2247 5016 0 0 1 +5147 1 5145 1 +5147 2 2 5143 1 +5147 3 5145 3 0 1 +5147 4 2 3705 7 0 1 +5147 5 5145 12 0 0 0 1 +5147 6 2 890 4432 3125 2 0 1 +5153 1 5148 1 +5153 2 5 5148 1 +5153 3 5148 1 0 1 +5153 4 5 3288 15 0 1 +5153 5 5148 9 0 0 0 1 +5153 6 5 4040 3661 3222 2 0 1 +5167 1 5161 1 +5167 2 6 5166 1 +5167 3 5161 2 0 1 +5167 4 6 2756 3 0 1 +5167 5 5161 28 0 0 0 1 +5167 6 6 2012 4295 4940 0 0 1 +5171 1 5169 1 +5171 2 2 5170 1 +5171 3 5169 3 0 1 +5171 4 2 4578 4 0 1 +5171 5 5169 2 0 0 0 1 +5171 6 2 2532 605 2542 1 0 1 +5179 1 5177 1 +5179 2 2 5175 1 +5179 3 5177 4 0 1 +5179 4 2 4114 1 0 1 +5179 5 5177 7 0 0 0 1 +5179 6 2 3903 3978 4616 1 0 1 +5189 1 5187 1 +5189 2 2 5179 1 +5189 3 5187 2 0 1 +5189 4 2 3521 0 0 1 +5189 5 5187 2 0 0 0 1 +5189 6 2 4015 1142 1147 2 0 1 +5197 1 5190 1 +5197 2 7 5195 1 +5197 3 5190 2 0 1 +5197 4 7 3172 10 0 1 +5197 5 5190 1 0 0 0 1 +5197 6 7 3064 949 3188 0 0 1 +5209 1 5192 1 +5209 2 17 5208 1 +5209 3 5192 2 0 1 +5209 4 17 3547 23 0 1 +5209 5 5192 1 0 0 0 1 +5209 6 17 1317 1227 4296 0 0 1 +5227 1 5225 1 +5227 2 2 5226 1 +5227 3 5225 2 0 1 +5227 4 2 3673 7 0 1 +5227 5 5225 18 0 0 0 1 +5227 6 2 1338 3492 1839 0 0 1 +5231 1 5224 1 +5231 2 7 5230 1 +5231 3 5224 1 0 1 +5231 4 7 2945 2 0 1 +5231 5 5224 4 0 0 0 1 +5231 6 7 2064 124 829 3 0 1 +5233 1 5223 1 +5233 2 10 5232 1 +5233 3 5223 12 0 1 +5233 4 10 4917 12 0 1 +5233 5 5223 13 0 0 0 1 +5233 6 10 5172 4218 4161 0 0 1 +5237 1 5234 1 +5237 2 3 5235 1 +5237 3 5234 1 0 1 +5237 4 3 4976 7 0 1 +5237 5 5234 15 0 0 0 1 +5237 6 3 1244 3085 651 5 0 1 +5261 1 5259 1 +5261 2 2 5257 1 +5261 3 5259 2 0 1 +5261 4 2 3906 12 0 1 +5261 5 5259 5 0 0 0 1 +5261 6 2 237 2891 1780 1 0 1 +5273 1 5270 1 +5273 2 3 5268 1 +5273 3 5270 1 0 1 +5273 4 3 3736 0 0 1 +5273 5 5270 3 0 0 0 1 +5273 6 3 2525 568 4238 1 0 1 +5279 1 5272 1 +5279 2 7 5275 1 +5279 3 5272 3 0 1 +5279 4 7 3255 10 0 1 +5279 5 5272 2 0 0 0 1 +5279 6 7 812 3859 3442 1 0 1 +5281 1 5274 1 +5281 2 7 5278 1 +5281 3 5274 1 0 1 +5281 4 7 4529 26 0 1 +5281 5 5274 3 0 0 0 1 +5281 6 7 1574 4991 4876 0 0 1 +5297 1 5294 1 +5297 2 3 5296 1 +5297 3 5294 3 0 1 +5297 4 3 2780 8 0 1 +5297 5 5294 1 0 0 0 1 +5297 6 3 4813 693 1723 2 0 1 +5303 1 5298 1 +5303 2 5 5298 1 +5303 3 5298 8 0 1 +5303 4 5 4664 7 0 1 +5303 5 5298 14 0 0 0 1 +5303 6 5 2210 3779 1797 3 0 1 +5309 1 5307 1 +5309 2 2 5305 1 +5309 3 5307 3 0 1 +5309 4 2 3402 6 0 1 +5309 5 5307 9 0 0 0 1 +5309 6 2 1374 1244 3426 3 0 1 +5323 1 5318 1 +5323 2 5 5322 1 +5323 3 5318 3 0 1 +5323 4 5 4544 2 0 1 +5323 5 5318 2 0 0 0 1 +5323 6 5 4678 449 4833 0 0 1 +5333 1 5331 1 +5333 2 2 5332 1 +5333 3 5331 2 0 1 +5333 4 2 3011 4 0 1 +5333 5 5331 7 0 0 0 1 +5333 6 2 4173 4880 4665 1 0 1 +5347 1 5344 1 +5347 2 3 5340 1 +5347 3 5344 3 0 1 +5347 4 3 4300 5 0 1 +5347 5 5344 1 0 0 0 1 +5347 6 3 3872 3767 4767 0 0 1 +5351 1 5340 1 +5351 2 11 5349 1 +5351 3 5340 2 0 1 +5351 4 11 2904 3 0 1 +5351 5 5340 3 0 0 0 1 +5351 6 11 2813 3018 1365 1 0 1 +5381 1 5378 1 +5381 2 3 5379 1 +5381 3 5378 1 0 1 +5381 4 3 5373 10 0 1 +5381 5 5378 4 0 0 0 1 +5381 6 3 591 3442 2419 2 0 1 +5387 1 5385 1 +5387 2 2 5381 1 +5387 3 5385 5 0 1 +5387 4 2 5179 0 0 1 +5387 5 5385 2 0 0 0 1 +5387 6 2 294 2140 4831 1 0 1 +5393 1 5390 1 +5393 2 3 5388 1 +5393 3 5390 5 0 1 +5393 4 3 2779 0 0 1 +5393 5 5390 9 0 0 0 1 +5393 6 3 3959 3645 1417 2 0 1 +5399 1 5392 1 +5399 2 7 5398 1 +5399 3 5392 2 0 1 +5399 4 7 4859 3 0 1 +5399 5 5392 5 0 0 0 1 +5399 6 7 2407 4443 3793 1 0 1 +5407 1 5404 1 +5407 2 3 5406 1 +5407 3 5404 1 0 1 +5407 4 3 2801 5 0 1 +5407 5 5404 5 0 0 0 1 +5407 6 3 5256 3948 4841 0 0 1 +5413 1 5408 1 +5413 2 5 5408 1 +5413 3 5408 5 0 1 +5413 4 5 3179 11 0 1 +5413 5 5408 5 0 0 0 1 +5413 6 5 648 4784 5019 0 0 1 +5417 1 5414 1 +5417 2 3 5411 1 +5417 3 5414 4 0 1 +5417 4 3 3351 16 0 1 +5417 5 5414 4 0 0 0 1 +5417 6 3 5229 2844 2225 2 0 1 +5419 1 5416 1 +5419 2 3 5414 1 +5419 3 5416 5 0 1 +5419 4 3 4003 3 0 1 +5419 5 5416 4 0 0 0 1 +5419 6 3 3470 5375 4215 2 0 1 +5431 1 5428 1 +5431 2 3 5430 1 +5431 3 5428 3 0 1 +5431 4 3 4493 3 0 1 +5431 5 5428 1 0 0 0 1 +5431 6 3 5406 3798 5206 0 0 1 +5437 1 5432 1 +5437 2 5 5436 1 +5437 3 5432 1 0 1 +5437 4 5 3703 6 0 1 +5437 5 5432 10 0 0 0 1 +5437 6 5 16 180 4983 0 0 1 +5441 1 5438 1 +5441 2 3 5435 1 +5441 3 5438 4 0 1 +5441 4 3 5429 0 0 1 +5441 5 5438 5 0 0 0 1 +5441 6 3 2825 1966 2329 1 0 1 +5443 1 5441 1 +5443 2 2 5439 1 +5443 3 5441 6 0 1 +5443 4 2 3215 8 0 1 +5443 5 5441 13 0 0 0 1 +5443 6 2 5431 5425 5439 0 0 1 +5449 1 5442 1 +5449 2 7 5446 1 +5449 3 5442 3 0 1 +5449 4 7 5215 17 0 1 +5449 5 5442 1 0 0 0 1 +5449 6 7 3651 1577 918 0 0 1 +5471 1 5464 1 +5471 2 7 5470 1 +5471 3 5464 1 0 1 +5471 4 7 4654 2 0 1 +5471 5 5464 3 0 0 0 1 +5471 6 7 1611 5284 4877 1 0 1 +5477 1 5475 1 +5477 2 2 5476 1 +5477 3 5475 9 0 1 +5477 4 2 4592 3 0 1 +5477 5 5475 5 0 0 0 1 +5477 6 2 1630 2737 726 3 0 1 +5479 1 5476 1 +5479 2 3 5477 1 +5479 3 5476 4 0 1 +5479 4 3 5475 4 0 1 +5479 5 5476 1 0 0 0 1 +5479 6 3 4310 4043 3121 0 0 1 +5483 1 5481 1 +5483 2 2 5479 1 +5483 3 5481 3 0 1 +5483 4 2 4428 7 0 1 +5483 5 5481 3 0 0 0 1 +5483 6 2 15 761 4423 1 0 1 +5501 1 5499 1 +5501 2 2 5500 1 +5501 3 5499 3 0 1 +5501 4 2 5494 8 0 1 +5501 5 5499 9 0 0 0 1 +5501 6 2 3141 1376 2152 2 0 1 +5503 1 5500 1 +5503 2 3 5501 1 +5503 3 5500 3 0 1 +5503 4 3 4553 3 0 1 +5503 5 5500 9 0 0 0 1 +5503 6 3 807 3098 4862 1 0 1 +5507 1 5505 1 +5507 2 2 5506 1 +5507 3 5505 3 0 1 +5507 4 2 4674 2 0 1 +5507 5 5505 7 0 0 0 1 +5507 6 2 4320 3265 1486 1 0 1 +5519 1 5506 1 +5519 2 13 5517 1 +5519 3 5506 3 0 1 +5519 4 13 4514 3 0 1 +5519 5 5506 8 0 0 0 1 +5519 6 13 1728 77 3957 2 0 1 +5521 1 5510 1 +5521 2 11 5518 1 +5521 3 5510 1 0 1 +5521 4 11 5107 10 0 1 +5521 5 5510 2 0 0 0 1 +5521 6 11 1127 3611 4199 0 0 1 +5527 1 5522 1 +5527 2 5 5525 1 +5527 3 5522 5 0 1 +5527 4 5 3244 10 0 1 +5527 5 5522 2 0 0 0 1 +5527 6 5 1602 4694 291 3 0 1 +5531 1 5521 1 +5531 2 10 5523 1 +5531 3 5521 5 0 1 +5531 4 10 5284 1 0 1 +5531 5 5521 13 0 0 0 1 +5531 6 10 3780 522 2818 1 0 1 +5557 1 5555 1 +5557 2 2 5556 1 +5557 3 5555 4 0 1 +5557 4 2 5232 7 0 1 +5557 5 5555 2 0 0 0 1 +5557 6 2 4509 1414 5195 0 0 1 +5563 1 5561 1 +5563 2 2 5562 1 +5563 3 5561 2 0 1 +5563 4 2 4029 2 0 1 +5563 5 5561 7 0 0 0 1 +5563 6 2 824 2629 3660 0 0 1 +5569 1 5556 1 +5569 2 13 5568 1 +5569 3 5556 1 0 1 +5569 4 13 5005 14 0 1 +5569 5 5556 3 0 0 0 1 +5569 6 13 2058 4630 3619 0 0 1 +5573 1 5571 1 +5573 2 2 5569 1 +5573 3 5571 3 0 1 +5573 4 2 4990 12 0 1 +5573 5 5571 9 0 0 0 1 +5573 6 2 458 5276 1540 1 0 1 +5581 1 5575 1 +5581 2 6 5580 1 +5581 3 5575 8 0 1 +5581 4 6 2877 23 0 1 +5581 5 5575 7 0 0 0 1 +5581 6 6 5084 5293 4711 0 0 1 +5591 1 5580 1 +5591 2 11 5589 1 +5591 3 5580 7 0 1 +5591 4 11 4672 10 0 1 +5591 5 5580 2 0 0 0 1 +5591 6 11 1604 4049 1141 1 0 1 +5623 1 5618 1 +5623 2 5 5622 1 +5623 3 5618 1 0 1 +5623 4 5 4471 5 0 1 +5623 5 5618 3 0 0 0 1 +5623 6 5 2026 3434 2370 0 0 1 +5639 1 5632 1 +5639 2 7 5632 1 +5639 3 5632 3 0 1 +5639 4 7 5533 9 0 1 +5639 5 5632 4 0 0 0 1 +5639 6 7 3109 2719 1858 1 0 1 +5641 1 5627 1 +5641 2 14 5627 1 +5641 3 5627 1 0 1 +5641 4 14 3065 0 0 1 +5641 5 5627 14 0 0 0 1 +5641 6 14 2049 1341 2687 0 0 1 +5647 1 5644 1 +5647 2 3 5645 1 +5647 3 5644 7 0 1 +5647 4 3 5643 4 0 1 +5647 5 5644 4 0 0 0 1 +5647 6 3 469 92 4939 0 0 1 +5651 1 5649 1 +5651 2 2 5645 1 +5651 3 5649 2 0 1 +5651 4 2 5114 0 0 1 +5651 5 5649 10 0 0 0 1 +5651 6 2 4954 2981 3352 1 0 1 +5653 1 5648 1 +5653 2 5 5652 1 +5653 3 5648 1 0 1 +5653 4 5 5415 7 0 1 +5653 5 5648 1 0 0 0 1 +5653 6 5 2467 4995 4874 1 0 1 +5657 1 5654 1 +5657 2 3 5652 1 +5657 3 5654 3 0 1 +5657 4 3 4685 0 0 1 +5657 5 5654 7 0 0 0 1 +5657 6 3 2612 4118 5555 1 0 1 +5659 1 5657 1 +5659 2 2 5658 1 +5659 3 5657 6 0 1 +5659 4 2 3882 2 0 1 +5659 5 5657 3 0 0 0 1 +5659 6 2 2138 5546 3119 0 0 1 +5669 1 5666 1 +5669 2 3 5657 1 +5669 3 5666 1 0 1 +5669 4 3 2924 5 0 1 +5669 5 5666 6 0 0 0 1 +5669 6 3 2120 1592 657 1 0 1 +5683 1 5681 1 +5683 2 2 5682 1 +5683 3 5681 4 0 1 +5683 4 2 4164 10 0 1 +5683 5 5681 2 0 0 0 1 +5683 6 2 2285 1361 5120 0 0 1 +5689 1 5678 1 +5689 2 11 5686 1 +5689 3 5678 2 0 1 +5689 4 11 4145 10 0 1 +5689 5 5678 8 0 0 0 1 +5689 6 11 2179 909 5572 0 0 1 +5693 1 5691 1 +5693 2 2 5689 1 +5693 3 5691 3 0 1 +5693 4 2 4512 7 0 1 +5693 5 5691 2 0 0 0 1 +5693 6 2 4455 2355 3472 2 0 1 +5701 1 5699 1 +5701 2 2 5700 1 +5701 3 5699 6 0 1 +5701 4 2 4705 7 0 1 +5701 5 5699 10 0 0 0 1 +5701 6 2 1099 3264 3092 0 0 1 +5711 1 5692 1 +5711 2 19 5710 1 +5711 3 5692 1 0 1 +5711 4 19 3629 2 0 1 +5711 5 5692 3 0 0 0 1 +5711 6 19 5210 5696 2375 1 0 1 +5717 1 5715 1 +5717 2 2 5716 1 +5717 3 5715 2 0 1 +5717 4 2 4875 9 0 1 +5717 5 5715 3 0 0 0 1 +5717 6 2 5001 2337 4666 7 0 1 +5737 1 5732 1 +5737 2 5 5736 1 +5737 3 5732 2 0 1 +5737 4 5 3985 12 0 1 +5737 5 5732 2 0 0 0 1 +5737 6 5 5307 2532 5344 0 0 1 +5741 1 5739 1 +5741 2 2 5736 1 +5741 3 5739 2 0 1 +5741 4 2 4555 2 0 1 +5741 5 5739 6 0 0 0 1 +5741 6 2 1063 5658 2348 2 0 1 +5743 1 5733 1 +5743 2 10 5741 1 +5743 3 5733 6 0 1 +5743 4 10 4715 4 0 1 +5743 5 5733 14 0 0 0 1 +5743 6 10 169 4833 5621 0 0 1 +5749 1 5747 1 +5749 2 2 5745 1 +5749 3 5747 4 0 1 +5749 4 2 3224 6 0 1 +5749 5 5747 9 0 0 0 1 +5749 6 2 3786 1618 3265 0 0 1 +5779 1 5777 1 +5779 2 2 5775 1 +5779 3 5777 2 0 1 +5779 4 2 4989 8 0 1 +5779 5 5777 5 0 0 0 1 +5779 6 2 520 936 4860 0 0 1 +5783 1 5776 1 +5783 2 7 5779 1 +5783 3 5776 2 0 1 +5783 4 7 3417 5 0 1 +5783 5 5776 7 0 0 0 1 +5783 6 7 3792 2474 3363 1 0 1 +5791 1 5785 1 +5791 2 6 5789 1 +5791 3 5785 10 0 1 +5791 4 6 5496 10 0 1 +5791 5 5785 12 0 0 0 1 +5791 6 6 5626 3300 3847 0 0 1 +5801 1 5798 1 +5801 2 3 5795 1 +5801 3 5798 5 0 1 +5801 4 3 5789 0 0 1 +5801 5 5798 9 0 0 0 1 +5801 6 3 3402 1709 4616 2 0 1 +5807 1 5802 1 +5807 2 5 5806 1 +5807 3 5802 12 0 1 +5807 4 5 5319 4 0 1 +5807 5 5802 2 0 0 0 1 +5807 6 5 3822 3004 2936 1 0 1 +5813 1 5811 1 +5813 2 2 5812 1 +5813 3 5811 5 0 1 +5813 4 2 5538 9 0 1 +5813 5 5811 8 0 0 0 1 +5813 6 2 3366 3540 2594 1 0 1 +5821 1 5815 1 +5821 2 6 5817 1 +5821 3 5815 2 0 1 +5821 4 6 4968 2 0 1 +5821 5 5815 6 0 0 0 1 +5821 6 6 5593 3825 5161 4 0 1 +5827 1 5825 1 +5827 2 2 5826 1 +5827 3 5825 2 0 1 +5827 4 2 4800 7 0 1 +5827 5 5825 3 0 0 0 1 +5827 6 2 2659 4815 4660 0 0 1 +5839 1 5833 1 +5839 2 6 5837 1 +5839 3 5833 2 0 1 +5839 4 6 3944 4 0 1 +5839 5 5833 4 0 0 0 1 +5839 6 6 1721 5345 2750 0 0 1 +5843 1 5841 1 +5843 2 2 5839 1 +5843 3 5841 3 0 1 +5843 4 2 5271 7 0 1 +5843 5 5841 8 0 0 0 1 +5843 6 2 1733 1896 3818 1 0 1 +5849 1 5846 1 +5849 2 3 5848 1 +5849 3 5846 1 0 1 +5849 4 3 4466 7 0 1 +5849 5 5846 9 0 0 0 1 +5849 6 3 1028 1241 4207 3 0 1 +5851 1 5849 1 +5851 2 2 5847 1 +5851 3 5849 6 0 1 +5851 4 2 4062 1 0 1 +5851 5 5849 2 0 0 0 1 +5851 6 2 5839 5833 5847 0 0 1 +5857 1 5850 1 +5857 2 7 5850 1 +5857 3 5850 9 0 1 +5857 4 7 5725 14 0 1 +5857 5 5850 4 0 0 0 1 +5857 6 7 1880 4090 2563 1 0 1 +5861 1 5858 1 +5861 2 3 5859 1 +5861 3 5858 7 0 1 +5861 4 3 4246 12 0 1 +5861 5 5858 8 0 0 0 1 +5861 6 3 4521 1056 2999 2 0 1 +5867 1 5862 1 +5867 2 5 5865 1 +5867 3 5862 2 0 1 +5867 4 5 5859 6 0 1 +5867 5 5862 1 0 0 0 1 +5867 6 5 4508 3300 3178 1 0 1 +5869 1 5867 1 +5869 2 2 5868 1 +5869 3 5867 4 0 1 +5869 4 2 3845 3 0 1 +5869 5 5867 10 0 0 0 1 +5869 6 2 767 5450 4506 0 0 1 +5879 1 5868 1 +5879 2 11 5877 1 +5879 3 5868 11 0 1 +5879 4 11 5039 5 0 1 +5879 5 5868 5 0 0 0 1 +5879 6 11 5094 4222 4253 2 0 1 +5881 1 5850 1 +5881 2 31 5876 1 +5881 3 5850 5 0 1 +5881 4 31 5848 16 0 1 +5881 5 5850 2 0 0 0 1 +5881 6 31 4546 2592 4096 0 0 1 +5897 1 5894 1 +5897 2 3 5892 1 +5897 3 5894 9 0 1 +5897 4 3 4016 8 0 1 +5897 5 5894 3 0 0 0 1 +5897 6 3 1149 1348 716 1 0 1 +5903 1 5898 1 +5903 2 5 5901 1 +5903 3 5898 2 0 1 +5903 4 5 5899 3 0 1 +5903 5 5898 2 0 0 0 1 +5903 6 5 3098 1573 314 3 0 1 +5923 1 5921 1 +5923 2 2 5919 1 +5923 3 5921 5 0 1 +5923 4 2 3089 8 0 1 +5923 5 5921 4 0 0 0 1 +5923 6 2 4010 5787 3895 0 0 1 +5927 1 5922 1 +5927 2 5 5926 1 +5927 3 5922 2 0 1 +5927 4 5 3813 3 0 1 +5927 5 5922 6 0 0 0 1 +5927 6 5 4057 5756 5257 1 0 1 +5939 1 5937 1 +5939 2 2 5935 1 +5939 3 5937 3 0 1 +5939 4 2 5109 7 0 1 +5939 5 5937 2 0 0 0 1 +5939 6 2 1341 2001 5778 1 0 1 +5953 1 5946 1 +5953 2 7 5946 1 +5953 3 5946 2 0 1 +5953 4 7 5381 18 0 1 +5953 5 5946 1 0 0 0 1 +5953 6 7 834 2240 4791 0 0 1 +5981 1 5978 1 +5981 2 3 5980 1 +5981 3 5978 5 0 1 +5981 4 3 3130 3 0 1 +5981 5 5978 5 0 0 0 1 +5981 6 3 5402 5980 3703 2 0 1 +5987 1 5985 1 +5987 2 2 5983 1 +5987 3 5985 3 0 1 +5987 4 2 5641 7 0 1 +5987 5 5985 16 0 0 0 1 +5987 6 2 3661 3911 205 3 0 1 +6007 1 6004 1 +6007 2 3 6005 1 +6007 3 6004 3 0 1 +6007 4 3 5427 3 0 1 +6007 5 6004 9 0 0 0 1 +6007 6 3 1729 5799 285 0 0 1 +6011 1 6009 1 +6011 2 2 6007 1 +6011 3 6009 3 0 1 +6011 4 2 3814 7 0 1 +6011 5 6009 18 0 0 0 1 +6011 6 2 2903 5566 956 2 0 1 +6029 1 6027 1 +6029 2 2 6025 1 +6029 3 6027 3 0 1 +6029 4 2 4854 6 0 1 +6029 5 6027 11 0 0 0 1 +6029 6 2 3826 933 1263 1 0 1 +6037 1 6032 1 +6037 2 5 6036 1 +6037 3 6032 3 0 1 +6037 4 5 4169 3 0 1 +6037 5 6032 2 0 0 0 1 +6037 6 5 2142 5518 2213 1 0 1 +6043 1 6038 1 +6043 2 5 6041 1 +6043 3 6038 2 0 1 +6043 4 5 6035 6 0 1 +6043 5 6038 5 0 0 0 1 +6043 6 5 2565 3936 3603 1 0 1 +6047 1 6042 1 +6047 2 5 6044 1 +6047 3 6042 8 0 1 +6047 4 5 4284 4 0 1 +6047 5 6042 3 0 0 0 1 +6047 6 5 5019 3051 3663 2 0 1 +6053 1 6051 1 +6053 2 2 6052 1 +6053 3 6051 2 0 1 +6053 4 2 6046 8 0 1 +6053 5 6051 3 0 0 0 1 +6053 6 2 376 426 4554 1 0 1 +6067 1 6065 1 +6067 2 2 6066 1 +6067 3 6065 6 0 1 +6067 4 2 5710 7 0 1 +6067 5 6065 2 0 0 0 1 +6067 6 2 876 3284 3354 0 0 1 +6073 1 6063 1 +6073 2 10 6072 1 +6073 3 6063 4 0 1 +6073 4 10 3299 16 0 1 +6073 5 6063 2 0 0 0 1 +6073 6 10 5420 1253 6051 1 0 1 +6079 1 6062 1 +6079 2 17 6077 1 +6079 3 6062 6 0 1 +6079 4 17 6071 3 0 1 +6079 5 6062 1 0 0 0 1 +6079 6 17 1413 5393 513 0 0 1 +6089 1 6086 1 +6089 2 3 6088 1 +6089 3 6086 3 0 1 +6089 4 3 4969 7 0 1 +6089 5 6086 7 0 0 0 1 +6089 6 3 485 1448 2643 1 0 1 +6091 1 6084 1 +6091 2 7 6089 1 +6091 3 6084 2 0 1 +6091 4 7 4936 6 0 1 +6091 5 6084 1 0 0 0 1 +6091 6 7 2839 484 5594 2 0 1 +6101 1 6099 1 +6101 2 2 6097 1 +6101 3 6099 3 0 1 +6101 4 2 4125 12 0 1 +6101 5 6099 3 0 0 0 1 +6101 6 2 1347 940 4989 1 0 1 +6113 1 6110 1 +6113 2 3 6112 1 +6113 3 6110 5 0 1 +6113 4 3 4935 4 0 1 +6113 5 6110 4 0 0 0 1 +6113 6 3 3957 4751 4691 2 0 1 +6121 1 6114 1 +6121 2 7 6118 1 +6121 3 6114 5 0 1 +6121 4 7 4176 16 0 1 +6121 5 6114 1 0 0 0 1 +6121 6 7 4024 2225 4299 0 0 1 +6131 1 6129 1 +6131 2 2 6126 1 +6131 3 6129 5 0 1 +6131 4 2 4866 3 0 1 +6131 5 6129 10 0 0 0 1 +6131 6 2 840 3151 3592 1 0 1 +6133 1 6128 1 +6133 2 5 6132 1 +6133 3 6128 12 0 1 +6133 4 5 4719 3 0 1 +6133 5 6128 3 0 0 0 1 +6133 6 5 187 5292 2412 0 0 1 +6143 1 6138 1 +6143 2 5 6141 1 +6143 3 6138 6 0 1 +6143 4 5 5375 8 0 1 +6143 5 6138 5 0 0 0 1 +6143 6 5 2112 319 5720 3 0 1 +6151 1 6148 1 +6151 2 3 6150 1 +6151 3 6148 1 0 1 +6151 4 3 5687 2 0 1 +6151 5 6148 3 0 0 0 1 +6151 6 3 1739 781 4259 0 0 1 +6163 1 6160 1 +6163 2 3 6154 1 +6163 3 6160 1 0 1 +6163 4 3 4191 10 0 1 +6163 5 6160 11 0 0 0 1 +6163 6 3 3969 1252 6155 0 0 1 +6173 1 6171 1 +6173 2 2 6172 1 +6173 3 6171 2 0 1 +6173 4 2 5879 3 0 1 +6173 5 6171 16 0 0 0 1 +6173 6 2 1787 5731 2807 2 0 1 +6197 1 6195 1 +6197 2 2 6193 1 +6197 3 6195 3 0 1 +6197 4 2 4395 7 0 1 +6197 5 6195 2 0 0 0 1 +6197 6 2 4487 2745 5836 1 0 1 +6199 1 6196 1 +6199 2 3 6197 1 +6199 3 6196 11 0 1 +6199 4 3 6195 4 0 1 +6199 5 6196 12 0 0 0 1 +6199 6 3 5339 3145 1684 0 0 1 +6203 1 6201 1 +6203 2 2 6197 1 +6203 3 6201 7 0 1 +6203 4 2 4407 4 0 1 +6203 5 6201 16 0 0 0 1 +6203 6 2 3723 3336 317 2 0 1 +6211 1 6209 1 +6211 2 2 6207 1 +6211 3 6209 2 0 1 +6211 4 2 3831 8 0 1 +6211 5 6209 6 0 0 0 1 +6211 6 2 4401 3423 1452 0 0 1 +6217 1 6212 1 +6217 2 5 6214 1 +6217 3 6212 1 0 1 +6217 4 5 4005 18 0 1 +6217 5 6212 6 0 0 0 1 +6217 6 5 4686 324 3426 0 0 1 +6221 1 6218 1 +6221 2 3 6220 1 +6221 3 6218 1 0 1 +6221 4 3 4737 3 0 1 +6221 5 6218 5 0 0 0 1 +6221 6 3 767 4690 2283 4 0 1 +6229 1 6227 1 +6229 2 2 6225 1 +6229 3 6227 6 0 1 +6229 4 2 5804 6 0 1 +6229 5 6227 3 0 0 0 1 +6229 6 2 6217 6211 6225 0 0 1 +6247 1 6242 1 +6247 2 5 6246 1 +6247 3 6242 1 0 1 +6247 4 5 4249 10 0 1 +6247 5 6242 2 0 0 0 1 +6247 6 5 5013 3016 863 0 0 1 +6257 1 6254 1 +6257 2 3 6248 1 +6257 3 6254 1 0 1 +6257 4 3 5301 3 0 1 +6257 5 6254 5 0 0 0 1 +6257 6 3 3820 902 764 1 0 1 +6263 1 6258 1 +6263 2 5 6262 1 +6263 3 6258 1 0 1 +6263 4 5 3733 7 0 1 +6263 5 6258 2 0 0 0 1 +6263 6 5 2635 2176 743 4 0 1 +6269 1 6267 1 +6269 2 2 6265 1 +6269 3 6267 2 0 1 +6269 4 2 5915 12 0 1 +6269 5 6267 19 0 0 0 1 +6269 6 2 4080 614 5113 1 0 1 +6271 1 6260 1 +6271 2 11 6267 1 +6271 3 6260 3 0 1 +6271 4 11 3429 1 0 1 +6271 5 6260 3 0 0 0 1 +6271 6 11 4877 5120 2956 0 0 1 +6277 1 6275 1 +6277 2 2 6276 1 +6277 3 6275 2 0 1 +6277 4 2 5873 3 0 1 +6277 5 6275 3 0 0 0 1 +6277 6 2 2132 1671 4081 0 0 1 +6287 1 6280 1 +6287 2 7 6285 1 +6287 3 6280 2 0 1 +6287 4 7 5422 5 0 1 +6287 5 6280 7 0 0 0 1 +6287 6 7 4689 149 2056 1 0 1 +6299 1 6297 1 +6299 2 2 6288 1 +6299 3 6297 5 0 1 +6299 4 2 5835 1 0 1 +6299 5 6297 5 0 0 0 1 +6299 6 2 5417 5643 2902 1 0 1 +6301 1 6291 1 +6301 2 10 6297 1 +6301 3 6291 6 0 1 +6301 4 10 3648 12 0 1 +6301 5 6291 1 0 0 0 1 +6301 6 10 1594 3503 229 0 0 1 +6311 1 6304 1 +6311 2 7 6310 1 +6311 3 6304 2 0 1 +6311 4 7 5361 2 0 1 +6311 5 6304 7 0 0 0 1 +6311 6 7 3661 4292 3292 1 0 1 +6317 1 6315 1 +6317 2 2 6316 1 +6317 3 6315 2 0 1 +6317 4 2 5652 6 0 1 +6317 5 6315 2 0 0 0 1 +6317 6 2 4441 2796 4421 1 0 1 +6323 1 6321 1 +6323 2 2 6311 1 +6323 3 6321 8 0 1 +6323 4 2 5598 6 0 1 +6323 5 6321 2 0 0 0 1 +6323 6 2 5335 6243 547 1 0 1 +6329 1 6326 1 +6329 2 3 6324 1 +6329 3 6326 1 0 1 +6329 4 3 6151 2 0 1 +6329 5 6326 4 0 0 0 1 +6329 6 3 1099 3130 695 1 0 1 +6337 1 6327 1 +6337 2 10 6336 1 +6337 3 6327 2 0 1 +6337 4 10 5231 6 0 1 +6337 5 6327 6 0 0 0 1 +6337 6 10 6074 4620 4918 0 0 1 +6343 1 6340 1 +6343 2 3 6342 1 +6343 3 6340 1 0 1 +6343 4 3 3971 14 0 1 +6343 5 6340 5 0 0 0 1 +6343 6 3 5827 5075 5042 1 0 1 +6353 1 6350 1 +6353 2 3 6352 1 +6353 3 6350 7 0 1 +6353 4 3 5517 7 0 1 +6353 5 6350 1 0 0 0 1 +6353 6 3 1406 6344 1479 1 0 1 +6359 1 6346 1 +6359 2 13 6358 1 +6359 3 6346 1 0 1 +6359 4 13 6246 2 0 1 +6359 5 6346 17 0 0 0 1 +6359 6 13 852 4721 6094 1 0 1 +6361 1 6342 1 +6361 2 19 6358 1 +6361 3 6342 5 0 1 +6361 4 19 4383 10 0 1 +6361 5 6342 13 0 0 0 1 +6361 6 19 1181 629 5908 0 0 1 +6367 1 6364 1 +6367 2 3 6365 1 +6367 3 6364 3 0 1 +6367 4 3 5709 3 0 1 +6367 5 6364 3 0 0 0 1 +6367 6 3 1894 5862 4612 0 0 1 +6373 1 6371 1 +6373 2 2 6372 1 +6373 3 6371 2 0 1 +6373 4 2 6366 8 0 1 +6373 5 6371 3 0 0 0 1 +6373 6 2 5239 3274 6004 0 0 1 +6379 1 6377 1 +6379 2 2 6370 1 +6379 3 6377 4 0 1 +6379 4 2 3885 2 0 1 +6379 5 6377 5 0 0 0 1 +6379 6 2 5798 2466 757 3 0 1 +6389 1 6387 1 +6389 2 2 6388 1 +6389 3 6387 3 0 1 +6389 4 2 6382 8 0 1 +6389 5 6387 2 0 0 0 1 +6389 6 2 1872 576 4136 4 0 1 +6397 1 6395 1 +6397 2 2 6396 1 +6397 3 6395 2 0 1 +6397 4 2 6218 9 0 1 +6397 5 6395 2 0 0 0 1 +6397 6 2 2137 983 1992 0 0 1 +6421 1 6415 1 +6421 2 6 6417 1 +6421 3 6415 9 0 1 +6421 4 6 3300 2 0 1 +6421 5 6415 6 0 0 0 1 +6421 6 6 1652 805 3697 1 0 1 +6427 1 6424 1 +6427 2 3 6422 1 +6427 3 6424 6 0 1 +6427 4 3 5590 3 0 1 +6427 5 6424 9 0 0 0 1 +6427 6 3 1225 4193 4170 0 0 1 +6449 1 6446 1 +6449 2 3 6443 1 +6449 3 6446 6 0 1 +6449 4 3 6437 0 0 1 +6449 5 6446 7 0 0 0 1 +6449 6 3 3985 2704 1378 4 0 1 +6451 1 6448 1 +6451 2 3 6444 1 +6451 3 6448 3 0 1 +6451 4 3 5883 5 0 1 +6451 5 6448 8 0 0 0 1 +6451 6 3 4522 5757 4142 0 0 1 +6469 1 6467 1 +6469 2 2 6465 1 +6469 3 6467 2 0 1 +6469 4 2 4409 12 0 1 +6469 5 6467 7 0 0 0 1 +6469 6 2 5646 1235 1560 2 0 1 +6473 1 6470 1 +6473 2 3 6467 1 +6473 3 6470 7 0 1 +6473 4 3 3818 9 0 1 +6473 5 6470 1 0 0 0 1 +6473 6 3 524 1141 2150 3 0 1 +6481 1 6474 1 +6481 2 7 6478 1 +6481 3 6474 1 0 1 +6481 4 7 5873 16 0 1 +6481 5 6474 8 0 0 0 1 +6481 6 7 1488 3948 2363 0 0 1 +6491 1 6489 1 +6491 2 2 6487 1 +6491 3 6489 3 0 1 +6491 4 2 3747 7 0 1 +6491 5 6489 4 0 0 0 1 +6491 6 2 5503 6117 837 1 0 1 +6521 1 6515 1 +6521 2 6 6515 1 +6521 3 6515 6 0 1 +6521 4 6 3760 0 0 1 +6521 5 6515 6 0 0 0 1 +6521 6 6 2751 1750 6329 2 0 1 +6529 1 6522 1 +6529 2 7 6526 1 +6529 3 6522 1 0 1 +6529 4 7 5221 17 0 1 +6529 5 6522 1 0 0 0 1 +6529 6 7 2223 2089 1712 0 0 1 +6547 1 6545 1 +6547 2 2 6543 1 +6547 3 6545 6 0 1 +6547 4 2 3676 8 0 1 +6547 5 6545 9 0 0 0 1 +6547 6 2 6535 6529 6543 0 0 1 +6551 1 6534 1 +6551 2 17 6550 1 +6551 3 6534 1 0 1 +6551 4 17 3541 2 0 1 +6551 5 6534 11 0 0 0 1 +6551 6 17 757 3626 3950 1 0 1 +6553 1 6543 1 +6553 2 10 6550 1 +6553 3 6543 3 0 1 +6553 4 10 6219 8 0 1 +6553 5 6543 24 0 0 0 1 +6553 6 10 1417 2186 6188 0 0 1 +6563 1 6558 1 +6563 2 5 6561 1 +6563 3 6558 1 0 1 +6563 4 5 6555 6 0 1 +6563 5 6558 9 0 0 0 1 +6563 6 5 2323 4178 4246 1 0 1 +6569 1 6566 1 +6569 2 3 6568 1 +6569 3 6566 4 0 1 +6569 4 3 6125 7 0 1 +6569 5 6566 16 0 0 0 1 +6569 6 3 1853 3838 6126 1 0 1 +6571 1 6568 1 +6571 2 3 6566 1 +6571 3 6568 4 0 1 +6571 4 3 4564 3 0 1 +6571 5 6568 1 0 0 0 1 +6571 6 3 410 3112 3877 0 0 1 +6577 1 6572 1 +6577 2 5 6576 1 +6577 3 6572 3 0 1 +6577 4 5 4769 6 0 1 +6577 5 6572 1 0 0 0 1 +6577 6 5 1408 995 6264 0 0 1 +6581 1 6567 1 +6581 2 14 6577 1 +6581 3 6567 2 0 1 +6581 4 14 6043 1 0 1 +6581 5 6567 3 0 0 0 1 +6581 6 14 3255 2186 5790 1 0 1 +6599 1 6586 1 +6599 2 13 6586 1 +6599 3 6586 2 0 1 +6599 4 13 6418 15 0 1 +6599 5 6586 5 0 0 0 1 +6599 6 13 2581 5600 2426 2 0 1 +6607 1 6604 1 +6607 2 3 6606 1 +6607 3 6604 3 0 1 +6607 4 3 6492 2 0 1 +6607 5 6604 3 0 0 0 1 +6607 6 3 1568 6135 2932 0 0 1 +6619 1 6617 1 +6619 2 2 6614 1 +6619 3 6617 6 0 1 +6619 4 2 4540 3 0 1 +6619 5 6617 3 0 0 0 1 +6619 6 2 5406 784 1425 0 0 1 +6637 1 6635 1 +6637 2 2 6633 1 +6637 3 6635 6 0 1 +6637 4 2 4675 6 0 1 +6637 5 6635 2 0 0 0 1 +6637 6 2 6625 6619 6633 0 0 1 +6653 1 6651 1 +6653 2 2 6652 1 +6653 3 6651 2 0 1 +6653 4 2 3675 6 0 1 +6653 5 6651 3 0 0 0 1 +6653 6 2 6102 1495 3732 1 0 1 +6659 1 6657 1 +6659 2 2 6655 1 +6659 3 6657 3 0 1 +6659 4 2 5754 8 0 1 +6659 5 6657 7 0 0 0 1 +6659 6 2 4969 5657 6486 1 0 1 +6661 1 6655 1 +6661 2 6 6660 1 +6661 3 6655 1 0 1 +6661 4 6 3579 7 0 1 +6661 5 6655 4 0 0 0 1 +6661 6 6 198 5037 4210 1 0 1 +6673 1 6668 1 +6673 2 5 6670 1 +6673 3 6668 7 0 1 +6673 4 5 6662 14 0 1 +6673 5 6668 2 0 0 0 1 +6673 6 5 3662 844 4835 3 0 1 +6679 1 6672 1 +6679 2 7 6676 1 +6679 3 6672 1 0 1 +6679 4 7 6084 5 0 1 +6679 5 6672 10 0 0 0 1 +6679 6 7 3803 3644 2537 0 0 1 +6689 1 6686 1 +6689 2 3 6684 1 +6689 3 6686 3 0 1 +6689 4 3 3532 2 0 1 +6689 5 6686 3 0 0 0 1 +6689 6 3 5708 4934 6026 4 0 1 +6691 1 6689 1 +6691 2 2 6690 1 +6691 3 6689 5 0 1 +6691 4 2 5612 2 0 1 +6691 5 6689 13 0 0 0 1 +6691 6 2 4749 150 6099 0 0 1 +6701 1 6699 1 +6701 2 2 6697 1 +6701 3 6699 3 0 1 +6701 4 2 6518 6 0 1 +6701 5 6699 2 0 0 0 1 +6701 6 2 278 2145 3624 1 0 1 +6703 1 6698 1 +6703 2 5 6702 1 +6703 3 6698 3 0 1 +6703 4 5 5107 5 0 1 +6703 5 6698 6 0 0 0 1 +6703 6 5 4801 5837 6622 1 0 1 +6709 1 6707 1 +6709 2 2 6708 1 +6709 3 6707 5 0 1 +6709 4 2 4545 3 0 1 +6709 5 6707 12 0 0 0 1 +6709 6 2 2390 5583 1108 0 0 1 +6719 1 6708 1 +6719 2 11 6716 1 +6719 3 6708 1 0 1 +6719 4 11 5879 6 0 1 +6719 5 6708 5 0 0 0 1 +6719 6 11 5545 2901 2787 1 0 1 +6733 1 6731 1 +6733 2 2 6732 1 +6733 3 6731 2 0 1 +6733 4 2 5096 6 0 1 +6733 5 6731 6 0 0 0 1 +6733 6 2 5670 4209 5611 0 0 1 +6737 1 6734 1 +6737 2 3 6731 1 +6737 3 6734 5 0 1 +6737 4 3 4969 12 0 1 +6737 5 6734 3 0 0 0 1 +6737 6 3 4305 3010 3041 1 0 1 +6761 1 6758 1 +6761 2 3 6760 1 +6761 3 6758 5 0 1 +6761 4 3 3691 7 0 1 +6761 5 6758 9 0 0 0 1 +6761 6 3 5874 5625 5122 2 0 1 +6763 1 6761 1 +6763 2 2 6758 1 +6763 3 6761 6 0 1 +6763 4 2 3708 0 0 1 +6763 5 6761 3 0 0 0 1 +6763 6 2 2068 1859 6719 0 0 1 +6779 1 6777 1 +6779 2 2 6775 1 +6779 3 6777 3 0 1 +6779 4 2 3633 7 0 1 +6779 5 6777 2 0 0 0 1 +6779 6 2 762 1713 5811 1 0 1 +6781 1 6779 1 +6781 2 2 6780 1 +6781 3 6779 4 0 1 +6781 4 2 6422 7 0 1 +6781 5 6779 4 0 0 0 1 +6781 6 2 4279 2576 5639 0 0 1 +6791 1 6784 1 +6791 2 7 6789 1 +6791 3 6784 2 0 1 +6791 4 7 6226 4 0 1 +6791 5 6784 14 0 0 0 1 +6791 6 7 4446 4602 2743 2 0 1 +6793 1 6783 1 +6793 2 10 6792 1 +6793 3 6783 2 0 1 +6793 4 10 3546 8 0 1 +6793 5 6783 6 0 0 0 1 +6793 6 10 2987 917 4415 0 0 1 +6803 1 6801 1 +6803 2 2 6799 1 +6803 3 6801 2 0 1 +6803 4 2 5750 14 0 1 +6803 5 6801 5 0 0 0 1 +6803 6 2 612 2018 6190 1 0 1 +6823 1 6820 1 +6823 2 3 6821 1 +6823 3 6820 8 0 1 +6823 4 3 6819 4 0 1 +6823 5 6820 1 0 0 0 1 +6823 6 3 1630 3578 6433 0 0 1 +6827 1 6825 1 +6827 2 2 6823 1 +6827 3 6825 3 0 1 +6827 4 2 4068 7 0 1 +6827 5 6825 5 0 0 0 1 +6827 6 2 5263 3597 6226 1 0 1 +6829 1 6827 1 +6829 2 2 6825 1 +6829 3 6827 2 0 1 +6829 4 2 6384 6 0 1 +6829 5 6827 2 0 0 0 1 +6829 6 2 4259 4000 6425 0 0 1 +6833 1 6830 1 +6833 2 3 6832 1 +6833 3 6830 1 0 1 +6833 4 3 6428 4 0 1 +6833 5 6830 3 0 0 0 1 +6833 6 3 3213 4297 4331 2 0 1 +6841 1 6819 1 +6841 2 22 6840 1 +6841 3 6819 1 0 1 +6841 4 22 5338 18 0 1 +6841 5 6819 2 0 0 0 1 +6841 6 22 53 1004 6303 0 0 1 +6857 1 6854 1 +6857 2 3 6852 1 +6857 3 6854 4 0 1 +6857 4 3 3578 0 0 1 +6857 5 6854 1 0 0 0 1 +6857 6 3 4241 4549 6371 1 0 1 +6863 1 6858 1 +6863 2 5 6860 1 +6863 3 6858 3 0 1 +6863 4 5 3569 6 0 1 +6863 5 6858 3 0 0 0 1 +6863 6 5 1806 5646 3396 1 0 1 +6869 1 6867 1 +6869 2 2 6865 1 +6869 3 6867 3 0 1 +6869 4 2 5754 12 0 1 +6869 5 6867 3 0 0 0 1 +6869 6 2 1589 4498 1535 2 0 1 +6871 1 6868 1 +6871 2 3 6870 1 +6871 3 6868 1 0 1 +6871 4 3 3573 2 0 1 +6871 5 6868 1 0 0 0 1 +6871 6 3 2819 4821 4520 0 0 1 +6883 1 6881 1 +6883 2 2 6879 1 +6883 3 6881 6 0 1 +6883 4 2 4187 8 0 1 +6883 5 6881 11 0 0 0 1 +6883 6 2 6871 6865 6879 0 0 1 +6899 1 6897 1 +6899 2 2 6895 1 +6899 3 6897 3 0 1 +6899 4 2 5297 7 0 1 +6899 5 6897 19 0 0 0 1 +6899 6 2 3996 6687 5926 2 0 1 +6907 1 6905 1 +6907 2 2 6906 1 +6907 3 6905 9 0 1 +6907 4 2 6900 8 0 1 +6907 5 6905 6 0 0 0 1 +6907 6 2 226 1334 5841 0 0 1 +6911 1 6904 1 +6911 2 7 6910 1 +6911 3 6904 3 0 1 +6911 4 7 6479 2 0 1 +6911 5 6904 25 0 0 0 1 +6911 6 7 3787 3523 646 1 0 1 +6917 1 6915 1 +6917 2 2 6913 1 +6917 3 6915 3 0 1 +6917 4 2 4673 9 0 1 +6917 5 6915 28 0 0 0 1 +6917 6 2 2784 5776 3952 1 0 1 +6947 1 6945 1 +6947 2 2 6942 1 +6947 3 6945 2 0 1 +6947 4 2 6296 3 0 1 +6947 5 6945 15 0 0 0 1 +6947 6 2 5933 5914 5586 3 0 1 +6949 1 6947 1 +6949 2 2 6948 1 +6949 3 6947 4 0 1 +6949 4 2 5165 3 0 1 +6949 5 6947 3 0 0 0 1 +6949 6 2 6814 4446 4030 0 0 1 +6959 1 6952 1 +6959 2 7 6957 1 +6959 3 6952 10 0 1 +6959 4 7 5088 13 0 1 +6959 5 6952 3 0 0 0 1 +6959 6 7 395 5933 3213 1 0 1 +6961 1 6948 1 +6961 2 13 6950 1 +6961 3 6948 3 0 1 +6961 4 13 5425 18 0 1 +6961 5 6948 1 0 0 0 1 +6961 6 13 787 5199 2288 2 0 1 +6967 1 6962 1 +6967 2 5 6965 1 +6967 3 6962 12 0 1 +6967 4 5 3595 17 0 1 +6967 5 6962 2 0 0 0 1 +6967 6 5 6552 1246 6016 0 0 1 +6971 1 6969 1 +6971 2 2 6970 1 +6971 3 6969 10 0 1 +6971 4 2 5192 2 0 1 +6971 5 6969 13 0 0 0 1 +6971 6 2 6619 3007 3606 2 0 1 +6977 1 6974 1 +6977 2 3 6971 1 +6977 3 6974 5 0 1 +6977 4 3 6423 9 0 1 +6977 5 6974 17 0 0 0 1 +6977 6 3 3216 6689 1076 1 0 1 +6983 1 6978 1 +6983 2 5 6974 1 +6983 3 6978 9 0 1 +6983 4 5 6746 4 0 1 +6983 5 6978 2 0 0 0 1 +6983 6 5 704 6370 5285 4 0 1 +6991 1 6985 1 +6991 2 6 6990 1 +6991 3 6985 1 0 1 +6991 4 6 4491 3 0 1 +6991 5 6985 2 0 0 0 1 +6991 6 6 1313 1793 3115 0 0 1 +6997 1 6992 1 +6997 2 5 6992 1 +6997 3 6992 9 0 1 +6997 4 5 5900 20 0 1 +6997 5 6992 10 0 0 0 1 +6997 6 5 5945 458 2575 0 0 1 +7001 1 6998 1 +7001 2 3 6994 1 +7001 3 6998 3 0 1 +7001 4 3 4330 1 0 1 +7001 5 6998 4 0 0 0 1 +7001 6 3 4025 3151 2368 1 0 1 +7013 1 7011 1 +7013 2 2 7012 1 +7013 3 7011 2 0 1 +7013 4 2 5076 3 0 1 +7013 5 7011 21 0 0 0 1 +7013 6 2 6926 5439 4350 1 0 1 +7019 1 7017 1 +7019 2 2 7015 1 +7019 3 7017 3 0 1 +7019 4 2 4031 7 0 1 +7019 5 7017 3 0 0 0 1 +7019 6 2 461 5640 2328 2 0 1 +7027 1 7025 1 +7027 2 2 7026 1 +7027 3 7025 4 0 1 +7027 4 2 4903 7 0 1 +7027 5 7025 8 0 0 0 1 +7027 6 2 421 4131 6876 0 0 1 +7039 1 7036 1 +7039 2 3 7038 1 +7039 3 7036 5 0 1 +7039 4 3 4087 3 0 1 +7039 5 7036 9 0 0 0 1 +7039 6 3 6693 3074 3617 0 0 1 +7043 1 7041 1 +7043 2 2 7037 1 +7043 3 7041 4 0 1 +7043 4 2 6012 25 0 1 +7043 5 7041 4 0 0 0 1 +7043 6 2 1762 2987 3991 2 0 1 +7057 1 7052 1 +7057 2 5 7056 1 +7057 3 7052 2 0 1 +7057 4 5 4013 6 0 1 +7057 5 7052 7 0 0 0 1 +7057 6 5 326 1378 6981 0 0 1 +7069 1 7067 1 +7069 2 2 7065 1 +7069 3 7067 6 0 1 +7069 4 2 6317 6 0 1 +7069 5 7067 2 0 0 0 1 +7069 6 2 7057 7051 7065 0 0 1 +7079 1 7072 1 +7079 2 7 7077 1 +7079 3 7072 1 0 1 +7079 4 7 6370 5 0 1 +7079 5 7072 8 0 0 0 1 +7079 6 7 6760 944 5256 1 0 1 +7103 1 7098 1 +7103 2 5 7101 1 +7103 3 7098 3 0 1 +7103 4 5 6519 9 0 1 +7103 5 7098 16 0 0 0 1 +7103 6 5 6748 5159 5353 3 0 1 +7109 1 7107 1 +7109 2 2 7100 1 +7109 3 7107 2 0 1 +7109 4 2 5252 1 0 1 +7109 5 7107 6 0 0 0 1 +7109 6 2 4001 1752 258 1 0 1 +7121 1 7118 1 +7121 2 3 7115 1 +7121 3 7118 6 0 1 +7121 4 3 7109 0 0 1 +7121 5 7118 1 0 0 0 1 +7121 6 3 1471 4940 2839 1 0 1 +7127 1 7122 1 +7127 2 5 7126 1 +7127 3 7122 8 0 1 +7127 4 5 3637 4 0 1 +7127 5 7122 1 0 0 0 1 +7127 6 5 5469 402 644 3 0 1 +7129 1 7122 1 +7129 2 7 7120 1 +7129 3 7122 2 0 1 +7129 4 7 3757 16 0 1 +7129 5 7122 1 0 0 0 1 +7129 6 7 1515 6041 2103 0 0 1 +7151 1 7144 1 +7151 2 7 7150 1 +7151 3 7144 5 0 1 +7151 4 7 3932 7 0 1 +7151 5 7144 3 0 0 0 1 +7151 6 7 1854 1423 1105 1 0 1 +7159 1 7156 1 +7159 2 3 7157 1 +7159 3 7156 3 0 1 +7159 4 3 6236 3 0 1 +7159 5 7156 3 0 0 0 1 +7159 6 3 1474 193 3635 0 0 1 +7177 1 7167 1 +7177 2 10 7172 1 +7177 3 7167 3 0 1 +7177 4 10 4338 15 0 1 +7177 5 7167 1 0 0 0 1 +7177 6 10 3113 6174 3830 0 0 1 +7187 1 7185 1 +7187 2 2 7186 1 +7187 3 7185 2 0 1 +7187 4 2 6410 4 0 1 +7187 5 7185 6 0 0 0 1 +7187 6 2 4440 6639 5701 1 0 1 +7193 1 7190 1 +7193 2 3 7187 1 +7193 3 7190 1 0 1 +7193 4 3 3771 11 0 1 +7193 5 7190 4 0 0 0 1 +7193 6 3 2785 6600 3366 1 0 1 +7207 1 7204 1 +7207 2 3 7206 1 +7207 3 7204 4 0 1 +7207 4 3 3716 5 0 1 +7207 5 7204 3 0 0 0 1 +7207 6 3 5204 2384 180 0 0 1 +7211 1 7209 1 +7211 2 2 7207 1 +7211 3 7209 3 0 1 +7211 4 2 6379 8 0 1 +7211 5 7209 8 0 0 0 1 +7211 6 2 402 5798 1605 1 0 1 +7213 1 7208 1 +7213 2 5 7212 1 +7213 3 7208 2 0 1 +7213 4 5 4303 3 0 1 +7213 5 7208 1 0 0 0 1 +7213 6 5 5006 6932 3215 0 0 1 +7219 1 7217 1 +7219 2 2 7215 1 +7219 3 7217 2 0 1 +7219 4 2 4165 8 0 1 +7219 5 7217 7 0 0 0 1 +7219 6 2 1767 795 5732 4 0 1 +7229 1 7227 1 +7229 2 2 7228 1 +7229 3 7227 3 0 1 +7229 4 2 4625 3 0 1 +7229 5 7227 11 0 0 0 1 +7229 6 2 1002 52 6435 2 0 1 +7237 1 7235 1 +7237 2 2 7236 1 +7237 3 7235 6 0 1 +7237 4 2 3772 7 0 1 +7237 5 7235 3 0 0 0 1 +7237 6 2 6719 3532 4691 0 0 1 +7243 1 7241 1 +7243 2 2 7242 1 +7243 3 7241 2 0 1 +7243 4 2 4257 10 0 1 +7243 5 7241 2 0 0 0 1 +7243 6 2 1410 5830 2864 2 0 1 +7247 1 7242 1 +7247 2 5 7246 1 +7247 3 7242 2 0 1 +7247 4 5 6940 3 0 1 +7247 5 7242 2 0 0 0 1 +7247 6 5 5700 7009 4641 1 0 1 +7253 1 7251 1 +7253 2 2 7249 1 +7253 3 7251 3 0 1 +7253 4 2 5662 6 0 1 +7253 5 7251 2 0 0 0 1 +7253 6 2 21 6469 7159 1 0 1 +7283 1 7281 1 +7283 2 2 7282 1 +7283 3 7281 3 0 1 +7283 4 2 6911 2 0 1 +7283 5 7281 2 0 0 0 1 +7283 6 2 2502 1631 6658 1 0 1 +7297 1 7292 1 +7297 2 5 7292 1 +7297 3 7292 5 0 1 +7297 4 5 4126 10 0 1 +7297 5 7292 5 0 0 0 1 +7297 6 5 5735 2750 4830 0 0 1 +7307 1 7305 1 +7307 2 2 7306 1 +7307 3 7305 2 0 1 +7307 4 2 5047 2 0 1 +7307 5 7305 9 0 0 0 1 +7307 6 2 585 5601 130 1 0 1 +7309 1 7303 1 +7309 2 6 7305 1 +7309 3 7303 4 0 1 +7309 4 6 5705 10 0 1 +7309 5 7303 7 0 0 0 1 +7309 6 6 6166 5665 5038 1 0 1 +7321 1 7314 1 +7321 2 7 7314 1 +7321 3 7314 2 0 1 +7321 4 7 4513 0 0 1 +7321 5 7314 1 0 0 0 1 +7321 6 7 6092 2104 6562 0 0 1 +7331 1 7329 1 +7331 2 2 7327 1 +7331 3 7329 2 0 1 +7331 4 2 5535 7 0 1 +7331 5 7329 5 0 0 0 1 +7331 6 2 5844 3873 6972 1 0 1 +7333 1 7327 1 +7333 2 6 7332 1 +7333 3 7327 1 0 1 +7333 4 6 6200 19 0 1 +7333 5 7327 13 0 0 0 1 +7333 6 6 5415 5266 2398 0 0 1 +7349 1 7347 1 +7349 2 2 7348 1 +7349 3 7347 3 0 1 +7349 4 2 7052 4 0 1 +7349 5 7347 2 0 0 0 1 +7349 6 2 5790 252 6222 1 0 1 +7351 1 7345 1 +7351 2 6 7350 1 +7351 3 7345 3 0 1 +7351 4 6 4268 3 0 1 +7351 5 7345 6 0 0 0 1 +7351 6 6 5578 1302 7044 0 0 1 +7369 1 7362 1 +7369 2 7 7362 1 +7369 3 7362 5 0 1 +7369 4 7 4712 0 0 1 +7369 5 7362 13 0 0 0 1 +7369 6 7 2196 3185 6895 2 0 1 +7393 1 7388 1 +7393 2 5 7392 1 +7393 3 7388 2 0 1 +7393 4 5 4462 6 0 1 +7393 5 7388 13 0 0 0 1 +7393 6 5 259 1460 1063 0 0 1 +7411 1 7409 1 +7411 2 2 7410 1 +7411 3 7409 6 0 1 +7411 4 2 5186 12 0 1 +7411 5 7409 14 0 0 0 1 +7411 6 2 3431 5822 5540 0 0 1 +7417 1 7412 1 +7417 2 5 7412 1 +7417 3 7412 7 0 1 +7417 4 5 6268 10 0 1 +7417 5 7412 2 0 0 0 1 +7417 6 5 5540 4355 4108 0 0 1 +7433 1 7430 1 +7433 2 3 7432 1 +7433 3 7430 4 0 1 +7433 4 3 7147 4 0 1 +7433 5 7430 4 0 0 0 1 +7433 6 3 3233 2366 6076 1 0 1 +7451 1 7449 1 +7451 2 2 7444 1 +7451 3 7449 4 0 1 +7451 4 2 5087 1 0 1 +7451 5 7449 10 0 0 0 1 +7451 6 2 2909 3645 3008 1 0 1 +7457 1 7454 1 +7457 2 3 7456 1 +7457 3 7454 3 0 1 +7457 4 3 7446 12 0 1 +7457 5 7454 24 0 0 0 1 +7457 6 3 1190 2527 3235 1 0 1 +7459 1 7457 1 +7459 2 2 7455 1 +7459 3 7457 6 0 1 +7459 4 2 5760 8 0 1 +7459 5 7457 10 0 0 0 1 +7459 6 2 7447 7441 7455 0 0 1 +7477 1 7475 1 +7477 2 2 7473 1 +7477 3 7475 5 0 1 +7477 4 2 6608 6 0 1 +7477 5 7475 7 0 0 0 1 +7477 6 2 4847 3501 6488 0 0 1 +7481 1 7475 1 +7481 2 6 7478 1 +7481 3 7475 4 0 1 +7481 4 6 5095 0 0 1 +7481 5 7475 4 0 0 0 1 +7481 6 6 5246 6853 3117 1 0 1 +7487 1 7482 1 +7487 2 5 7485 1 +7487 3 7482 1 0 1 +7487 4 5 6913 5 0 1 +7487 5 7482 7 0 0 0 1 +7487 6 5 1146 949 6607 1 0 1 +7489 1 7482 1 +7489 2 7 7486 1 +7489 3 7482 9 0 1 +7489 4 7 4900 17 0 1 +7489 5 7482 1 0 0 0 1 +7489 6 7 3602 5586 3832 0 0 1 +7499 1 7497 1 +7499 2 2 7493 1 +7499 3 7497 2 0 1 +7499 4 2 5082 0 0 1 +7499 5 7497 4 0 0 0 1 +7499 6 2 796 3707 5190 1 0 1 +7507 1 7505 1 +7507 2 2 7506 1 +7507 3 7505 4 0 1 +7507 4 2 7500 8 0 1 +7507 5 7505 2 0 0 0 1 +7507 6 2 7435 2078 5967 0 0 1 +7517 1 7515 1 +7517 2 2 7516 1 +7517 3 7515 2 0 1 +7517 4 2 4573 6 0 1 +7517 5 7515 11 0 0 0 1 +7517 6 2 5797 5676 6158 1 0 1 +7523 1 7521 1 +7523 2 2 7522 1 +7523 3 7521 3 0 1 +7523 4 2 7329 4 0 1 +7523 5 7521 4 0 0 0 1 +7523 6 2 6910 7216 6368 1 0 1 +7529 1 7526 1 +7529 2 3 7524 1 +7529 3 7526 5 0 1 +7529 4 3 6670 2 0 1 +7529 5 7526 1 0 0 0 1 +7529 6 3 2780 3909 6608 2 0 1 +7537 1 7530 1 +7537 2 7 7534 1 +7537 3 7530 7 0 1 +7537 4 7 4898 10 0 1 +7537 5 7530 2 0 0 0 1 +7537 6 7 895 6822 2291 0 0 1 +7541 1 7539 1 +7541 2 2 7537 1 +7541 3 7539 2 0 1 +7541 4 2 3927 6 0 1 +7541 5 7539 13 0 0 0 1 +7541 6 2 4749 4047 3247 2 0 1 +7547 1 7545 1 +7547 2 2 7543 1 +7547 3 7545 3 0 1 +7547 4 2 4129 8 0 1 +7547 5 7545 2 0 0 0 1 +7547 6 2 5032 3183 3233 1 0 1 +7549 1 7547 1 +7549 2 2 7548 1 +7549 3 7547 6 0 1 +7549 4 2 5562 7 0 1 +7549 5 7547 5 0 0 0 1 +7549 6 2 5305 4439 6900 0 0 1 +7559 1 7546 1 +7559 2 13 7557 1 +7559 3 7546 2 0 1 +7559 4 13 5754 4 0 1 +7559 5 7546 9 0 0 0 1 +7559 6 13 1411 1583 5606 1 0 1 +7561 1 7548 1 +7561 2 13 7552 1 +7561 3 7548 3 0 1 +7561 4 13 5370 35 0 1 +7561 5 7548 7 0 0 0 1 +7561 6 13 3226 6576 6950 0 0 1 +7573 1 7571 1 +7573 2 2 7572 1 +7573 3 7571 4 0 1 +7573 4 2 3966 6 0 1 +7573 5 7571 4 0 0 0 1 +7573 6 2 3595 7410 1807 0 0 1 +7577 1 7574 1 +7577 2 3 7572 1 +7577 3 7574 1 0 1 +7577 4 3 4887 0 0 1 +7577 5 7574 8 0 0 0 1 +7577 6 3 1333 6254 189 1 0 1 +7583 1 7578 1 +7583 2 5 7578 1 +7583 3 7578 3 0 1 +7583 4 5 6405 6 0 1 +7583 5 7578 15 0 0 0 1 +7583 6 5 6021 6421 2469 1 0 1 +7589 1 7587 1 +7589 2 2 7585 1 +7589 3 7587 3 0 1 +7589 4 2 5491 6 0 1 +7589 5 7587 3 0 0 0 1 +7589 6 2 1436 3574 7495 2 0 1 +7591 1 7585 1 +7591 2 6 7589 1 +7591 3 7585 4 0 1 +7591 4 6 7302 3 0 1 +7591 5 7585 6 0 0 0 1 +7591 6 6 6269 6080 4565 0 0 1 +7603 1 7601 1 +7603 2 2 7599 1 +7603 3 7601 5 0 1 +7603 4 2 7301 8 0 1 +7603 5 7601 8 0 0 0 1 +7603 6 2 7353 3297 5880 1 0 1 +7607 1 7602 1 +7607 2 5 7605 1 +7607 3 7602 1 0 1 +7607 4 5 5918 8 0 1 +7607 5 7602 6 0 0 0 1 +7607 6 5 2945 5588 5572 1 0 1 +7621 1 7619 1 +7621 2 2 7620 1 +7621 3 7619 5 0 1 +7621 4 2 7159 9 0 1 +7621 5 7619 2 0 0 0 1 +7621 6 2 2265 1419 1558 0 0 1 +7639 1 7632 1 +7639 2 7 7628 1 +7639 3 7632 1 0 1 +7639 4 7 4871 12 0 1 +7639 5 7632 1 0 0 0 1 +7639 6 7 2491 5805 3494 0 0 1 +7643 1 7641 1 +7643 2 2 7642 1 +7643 3 7641 8 0 1 +7643 4 2 7636 8 0 1 +7643 5 7641 5 0 0 0 1 +7643 6 2 5555 2982 7211 1 0 1 +7649 1 7646 1 +7649 2 3 7644 1 +7649 3 7646 3 0 1 +7649 4 3 7359 8 0 1 +7649 5 7646 12 0 0 0 1 +7649 6 3 5418 6712 1749 3 0 1 +7669 1 7667 1 +7669 2 2 7665 1 +7669 3 7667 2 0 1 +7669 4 2 4671 12 0 1 +7669 5 7667 2 0 0 0 1 +7669 6 2 4020 5683 5971 0 0 1 +7673 1 7670 1 +7673 2 3 7667 1 +7673 3 7670 5 0 1 +7673 4 3 7312 11 0 1 +7673 5 7670 4 0 0 0 1 +7673 6 3 1329 930 6164 1 0 1 +7681 1 7664 1 +7681 2 17 7680 1 +7681 3 7664 1 0 1 +7681 4 17 7308 14 0 1 +7681 5 7664 12 0 0 0 1 +7681 6 17 7076 4925 6113 0 0 1 +7687 1 7681 1 +7687 2 6 7686 1 +7687 3 7681 13 0 1 +7687 4 6 5032 3 0 1 +7687 5 7681 10 0 0 0 1 +7687 6 6 4875 2718 4602 0 0 1 +7691 1 7689 1 +7691 2 2 7687 1 +7691 3 7689 3 0 1 +7691 4 2 7443 7 0 1 +7691 5 7689 12 0 0 0 1 +7691 6 2 6510 1487 1304 2 0 1 +7699 1 7696 1 +7699 2 3 7698 1 +7699 3 7696 3 0 1 +7699 4 3 6377 2 0 1 +7699 5 7696 1 0 0 0 1 +7699 6 3 1172 5156 5599 0 0 1 +7703 1 7698 1 +7703 2 5 7702 1 +7703 3 7698 1 0 1 +7703 4 5 6237 2 0 1 +7703 5 7698 6 0 0 0 1 +7703 6 5 826 6494 6471 1 0 1 +7717 1 7715 1 +7717 2 2 7716 1 +7717 3 7715 4 0 1 +7717 4 2 3957 9 0 1 +7717 5 7715 7 0 0 0 1 +7717 6 2 1202 2249 2931 0 0 1 +7723 1 7720 1 +7723 2 3 7708 1 +7723 3 7720 1 0 1 +7723 4 3 4643 3 0 1 +7723 5 7720 3 0 0 0 1 +7723 6 3 886 7164 3978 1 0 1 +7727 1 7722 1 +7727 2 5 7726 1 +7727 3 7722 2 0 1 +7727 4 5 3940 4 0 1 +7727 5 7722 3 0 0 0 1 +7727 6 5 3518 2100 7081 2 0 1 +7741 1 7734 1 +7741 2 7 7739 1 +7741 3 7734 9 0 1 +7741 4 7 7389 4 0 1 +7741 5 7734 12 0 0 0 1 +7741 6 7 6003 5031 2290 0 0 1 +7753 1 7743 1 +7753 2 10 7752 1 +7753 3 7743 7 0 1 +7753 4 10 5369 14 0 1 +7753 5 7743 2 0 0 0 1 +7753 6 10 6896 4162 6595 0 0 1 +7757 1 7755 1 +7757 2 2 7749 1 +7757 3 7755 4 0 1 +7757 4 2 6682 11 0 1 +7757 5 7755 4 0 0 0 1 +7757 6 2 6662 7212 1941 1 0 1 +7759 1 7756 1 +7759 2 3 7754 1 +7759 3 7756 11 0 1 +7759 4 3 4050 7 0 1 +7759 5 7756 8 0 0 0 1 +7759 6 3 3196 2762 2236 0 0 1 +7789 1 7787 1 +7789 2 2 7785 1 +7789 3 7787 5 0 1 +7789 4 2 5723 6 0 1 +7789 5 7787 3 0 0 0 1 +7789 6 2 1115 3539 3519 0 0 1 +7793 1 7790 1 +7793 2 3 7788 1 +7793 3 7790 3 0 1 +7793 4 3 7668 2 0 1 +7793 5 7790 3 0 0 0 1 +7793 6 3 3922 2501 7568 1 0 1 +7817 1 7814 1 +7817 2 3 7811 1 +7817 3 7814 6 0 1 +7817 4 3 6121 16 0 1 +7817 5 7814 3 0 0 0 1 +7817 6 3 6437 7096 7295 2 0 1 +7823 1 7818 1 +7823 2 5 7822 1 +7823 3 7818 5 0 1 +7823 4 5 4777 3 0 1 +7823 5 7818 2 0 0 0 1 +7823 6 5 2438 356 4599 3 0 1 +7829 1 7827 1 +7829 2 2 7828 1 +7829 3 7827 3 0 1 +7829 4 2 4796 3 0 1 +7829 5 7827 8 0 0 0 1 +7829 6 2 7155 5906 401 1 0 1 +7841 1 7829 1 +7841 2 12 7840 1 +7841 3 7829 1 0 1 +7841 4 12 6793 13 0 1 +7841 5 7829 10 0 0 0 1 +7841 6 12 6877 710 7133 1 0 1 +7853 1 7851 1 +7853 2 2 7852 1 +7853 3 7851 7 0 1 +7853 4 2 5386 3 0 1 +7853 5 7851 10 0 0 0 1 +7853 6 2 2079 5068 7765 1 0 1 +7867 1 7864 1 +7867 2 3 7862 1 +7867 3 7864 4 0 1 +7867 4 3 5804 11 0 1 +7867 5 7864 1 0 0 0 1 +7867 6 3 5298 6607 6744 0 0 1 +7873 1 7868 1 +7873 2 5 7870 1 +7873 3 7868 6 0 1 +7873 4 5 6445 10 0 1 +7873 5 7868 3 0 0 0 1 +7873 6 5 4367 1891 7380 0 0 1 +7877 1 7875 1 +7877 2 2 7873 1 +7877 3 7875 3 0 1 +7877 4 2 6597 6 0 1 +7877 5 7875 5 0 0 0 1 +7877 6 2 4653 1395 7625 5 0 1 +7879 1 7876 1 +7879 2 3 7873 1 +7879 3 7876 3 0 1 +7879 4 3 6527 7 0 1 +7879 5 7876 1 0 0 0 1 +7879 6 3 6111 1548 4084 0 0 1 +7883 1 7881 1 +7883 2 2 7879 1 +7883 3 7881 3 0 1 +7883 4 2 6618 7 0 1 +7883 5 7881 6 0 0 0 1 +7883 6 2 3598 6912 4848 1 0 1 +7901 1 7899 1 +7901 2 2 7895 1 +7901 3 7899 8 0 1 +7901 4 2 6435 3 0 1 +7901 5 7899 2 0 0 0 1 +7901 6 2 6704 7881 7263 1 0 1 +7907 1 7905 1 +7907 2 2 7903 1 +7907 3 7905 3 0 1 +7907 4 2 7224 7 0 1 +7907 5 7905 15 0 0 0 1 +7907 6 2 5736 6031 6389 4 0 1 +7919 1 7912 1 +7919 2 7 7918 1 +7919 3 7912 3 0 1 +7919 4 7 7322 3 0 1 +7919 5 7912 8 0 0 0 1 +7919 6 7 4922 5917 3472 4 0 1 +7927 1 7924 1 +7927 2 3 7926 1 +7927 3 7924 1 0 1 +7927 4 3 6367 2 0 1 +7927 5 7924 4 0 0 0 1 +7927 6 3 1272 6856 6150 0 0 1 +7933 1 7931 1 +7933 2 2 7929 1 +7933 3 7931 5 0 1 +7933 4 2 7734 12 0 1 +7933 5 7931 5 0 0 0 1 +7933 6 2 7866 3854 2022 0 0 1 +7937 1 7934 1 +7937 2 3 7936 1 +7937 3 7934 1 0 1 +7937 4 3 5414 6 0 1 +7937 5 7934 14 0 0 0 1 +7937 6 3 3961 509 6755 2 0 1 +7949 1 7947 1 +7949 2 2 7944 1 +7949 3 7947 3 0 1 +7949 4 2 7294 18 0 1 +7949 5 7947 6 0 0 0 1 +7949 6 2 6177 7753 243 5 0 1 +7951 1 7945 1 +7951 2 6 7949 1 +7951 3 7945 1 0 1 +7951 4 6 6758 3 0 1 +7951 5 7945 10 0 0 0 1 +7951 6 6 2016 735 7698 3 0 1 +7963 1 7958 1 +7963 2 5 7962 1 +7963 3 7958 1 0 1 +7963 4 5 4368 5 0 1 +7963 5 7958 5 0 0 0 1 +7963 6 5 5444 659 6806 1 0 1 +7993 1 7988 1 +7993 2 5 7992 1 +7993 3 7988 7 0 1 +7993 4 5 4905 6 0 1 +7993 5 7988 11 0 0 0 1 +7993 6 5 2935 2235 7864 0 0 1 +8009 1 8006 1 +8009 2 3 8003 1 +8009 3 8006 6 0 1 +8009 4 3 7997 0 0 1 +8009 5 8006 5 0 0 0 1 +8009 6 3 3251 5503 6841 1 0 1 +8011 1 7997 1 +8011 2 14 8009 1 +8011 3 7997 1 0 1 +8011 4 14 7273 0 0 1 +8011 5 7997 31 0 0 0 1 +8011 6 14 6704 4929 7473 0 0 1 +8017 1 8012 1 +8017 2 5 8016 1 +8017 3 8012 3 0 1 +8017 4 5 5204 11 0 1 +8017 5 8012 7 0 0 0 1 +8017 6 5 3710 7946 7470 0 0 1 +8039 1 8028 1 +8039 2 11 8035 1 +8039 3 8028 1 0 1 +8039 4 11 7648 9 0 1 +8039 5 8028 1 0 0 0 1 +8039 6 11 7158 7277 2220 3 0 1 +8053 1 8051 1 +8053 2 2 8052 1 +8053 3 8051 4 0 1 +8053 4 2 8046 8 0 1 +8053 5 8051 2 0 0 0 1 +8053 6 2 898 1783 6375 0 0 1 +8059 1 8056 1 +8059 2 3 8058 1 +8059 3 8056 6 0 1 +8059 4 3 7932 2 0 1 +8059 5 8056 1 0 0 0 1 +8059 6 3 6629 5055 6373 0 0 1 +8069 1 8067 1 +8069 2 2 8068 1 +8069 3 8067 5 0 1 +8069 4 2 4135 3 0 1 +8069 5 8067 2 0 0 0 1 +8069 6 2 6072 7997 7974 1 0 1 +8081 1 8078 1 +8081 2 3 8080 1 +8081 3 8078 3 0 1 +8081 4 3 7439 4 0 1 +8081 5 8078 6 0 0 0 1 +8081 6 3 5498 5491 6981 2 0 1 +8087 1 8082 1 +8087 2 5 8086 1 +8087 3 8082 1 0 1 +8087 4 5 7414 4 0 1 +8087 5 8082 1 0 0 0 1 +8087 6 5 472 5447 1925 1 0 1 +8089 1 8072 1 +8089 2 17 8078 1 +8089 3 8072 2 0 1 +8089 4 17 5877 28 0 1 +8089 5 8072 14 0 0 0 1 +8089 6 17 7517 7863 819 0 0 1 +8093 1 8091 1 +8093 2 2 8089 1 +8093 3 8091 3 0 1 +8093 4 2 6711 7 0 1 +8093 5 8091 20 0 0 0 1 +8093 6 2 7359 2707 7561 2 0 1 +8101 1 8095 1 +8101 2 6 8100 1 +8101 3 8095 1 0 1 +8101 4 6 5576 7 0 1 +8101 5 8095 3 0 0 0 1 +8101 6 6 4610 3231 3842 0 0 1 +8111 1 8100 1 +8111 2 11 8110 1 +8111 3 8100 4 0 1 +8111 4 11 4175 3 0 1 +8111 5 8100 1 0 0 0 1 +8111 6 11 3313 5943 1374 1 0 1 +8117 1 8115 1 +8117 2 2 8109 1 +8117 3 8115 10 0 1 +8117 4 2 4332 13 0 1 +8117 5 8115 12 0 0 0 1 +8117 6 2 1507 1015 7142 1 0 1 +8123 1 8121 1 +8123 2 2 8122 1 +8123 3 8121 4 0 1 +8123 4 2 5348 4 0 1 +8123 5 8121 4 0 0 0 1 +8123 6 2 3854 5556 3044 2 0 1 +8147 1 8145 1 +8147 2 2 8146 1 +8147 3 8145 2 0 1 +8147 4 2 7196 13 0 1 +8147 5 8145 8 0 0 0 1 +8147 6 2 5596 5401 7685 1 0 1 +8161 1 8154 1 +8161 2 7 8154 1 +8161 3 8154 1 0 1 +8161 4 7 7029 0 0 1 +8161 5 8154 15 0 0 0 1 +8161 6 7 2036 1414 7254 0 0 1 +8167 1 8164 1 +8167 2 3 8165 1 +8167 3 8164 1 0 1 +8167 4 3 6636 6 0 1 +8167 5 8164 10 0 0 0 1 +8167 6 3 2265 7153 7585 0 0 1 +8171 1 8169 1 +8171 2 2 8167 1 +8171 3 8169 2 0 1 +8171 4 2 4824 8 0 1 +8171 5 8169 17 0 0 0 1 +8171 6 2 3525 6436 5270 1 0 1 +8179 1 8177 1 +8179 2 2 8178 1 +8179 3 8177 4 0 1 +8179 4 2 6095 2 0 1 +8179 5 8177 15 0 0 0 1 +8179 6 2 6127 4044 2735 0 0 1 +8191 1 8174 1 +8191 2 17 8189 1 +8191 3 8174 5 0 1 +8191 4 17 8183 3 0 1 +8191 5 8174 4 0 0 0 1 +8191 6 17 5644 5964 7746 0 0 1 +8209 1 8202 1 +8209 2 7 8202 1 +8209 3 8202 3 0 1 +8209 4 7 4481 0 0 1 +8209 5 8202 12 0 0 0 1 +8209 6 7 62 2959 4046 0 0 1 +8219 1 8217 1 +8219 2 2 8213 1 +8219 3 8217 9 0 1 +8219 4 2 4992 4 0 1 +8219 5 8217 8 0 0 0 1 +8219 6 2 5939 3375 1851 1 0 1 +8221 1 8219 1 +8221 2 2 8220 1 +8221 3 8219 5 0 1 +8221 4 2 7152 7 0 1 +8221 5 8219 3 0 0 0 1 +8221 6 2 6791 7026 7234 1 0 1 +8231 1 8220 1 +8231 2 11 8230 1 +8231 3 8220 2 0 1 +8231 4 11 7131 2 0 1 +8231 5 8220 2 0 0 0 1 +8231 6 11 3070 2212 4203 1 0 1 +8233 1 8223 1 +8233 2 10 8228 1 +8233 3 8223 3 0 1 +8233 4 10 6061 10 0 1 +8233 5 8223 6 0 0 0 1 +8233 6 10 4744 7612 6108 0 0 1 +8237 1 8235 1 +8237 2 2 8225 1 +8237 3 8235 5 0 1 +8237 4 2 4806 4 0 1 +8237 5 8235 11 0 0 0 1 +8237 6 2 6543 4317 5886 1 0 1 +8243 1 8241 1 +8243 2 2 8239 1 +8243 3 8241 3 0 1 +8243 4 2 5696 8 0 1 +8243 5 8241 4 0 0 0 1 +8243 6 2 4507 2514 2990 1 0 1 +8263 1 8260 1 +8263 2 3 8262 1 +8263 3 8260 11 0 1 +8263 4 3 7377 2 0 1 +8263 5 8260 4 0 0 0 1 +8263 6 3 454 2810 8004 0 0 1 +8269 1 8267 1 +8269 2 2 8265 1 +8269 3 8267 4 0 1 +8269 4 2 5697 6 0 1 +8269 5 8267 2 0 0 0 1 +8269 6 2 4559 6757 4287 0 0 1 +8273 1 8270 1 +8273 2 3 8266 1 +8273 3 8270 1 0 1 +8273 4 3 4860 2 0 1 +8273 5 8270 3 0 0 0 1 +8273 6 3 2399 6059 806 1 0 1 +8287 1 8284 1 +8287 2 3 8282 1 +8287 3 8284 1 0 1 +8287 4 3 4792 6 0 1 +8287 5 8284 5 0 0 0 1 +8287 6 3 1330 3839 5431 0 0 1 +8291 1 8289 1 +8291 2 2 8287 1 +8291 3 8289 3 0 1 +8291 4 2 6693 7 0 1 +8291 5 8289 6 0 0 0 1 +8291 6 2 1582 4825 2325 1 0 1 +8293 1 8291 1 +8293 2 2 8292 1 +8293 3 8291 6 0 1 +8293 4 2 8005 3 0 1 +8293 5 8291 2 0 0 0 1 +8293 6 2 6472 7110 7311 0 0 1 +8297 1 8294 1 +8297 2 3 8286 1 +8297 3 8294 6 0 1 +8297 4 3 7646 5 0 1 +8297 5 8294 4 0 0 0 1 +8297 6 3 6022 1160 4149 1 0 1 +8311 1 8308 1 +8311 2 3 8310 1 +8311 3 8308 3 0 1 +8311 4 3 5431 3 0 1 +8311 5 8308 8 0 0 0 1 +8311 6 3 7511 2038 1522 0 0 1 +8317 1 8311 1 +8317 2 6 8316 1 +8317 3 8311 3 0 1 +8317 4 6 7793 6 0 1 +8317 5 8311 3 0 0 0 1 +8317 6 6 2429 2524 6808 0 0 1 +8329 1 8322 1 +8329 2 7 8322 1 +8329 3 8322 8 0 1 +8329 4 7 6997 0 0 1 +8329 5 8322 2 0 0 0 1 +8329 6 7 7712 2699 2870 0 0 1 +8353 1 8348 1 +8353 2 5 8352 1 +8353 3 8348 1 0 1 +8353 4 5 7054 6 0 1 +8353 5 8348 8 0 0 0 1 +8353 6 5 6800 8204 4239 0 0 1 +8363 1 8361 1 +8363 2 2 8362 1 +8363 3 8361 2 0 1 +8363 4 2 8356 8 0 1 +8363 5 8361 4 0 0 0 1 +8363 6 2 3927 7299 6690 1 0 1 +8369 1 8366 1 +8369 2 3 8363 1 +8369 3 8366 1 0 1 +8369 4 3 8357 0 0 1 +8369 5 8366 9 0 0 0 1 +8369 6 3 5099 1511 5994 1 0 1 +8377 1 8372 1 +8377 2 5 8374 1 +8377 3 8372 6 0 1 +8377 4 5 6188 10 0 1 +8377 5 8372 5 0 0 0 1 +8377 6 5 2821 1440 6678 0 0 1 +8387 1 8385 1 +8387 2 2 8382 1 +8387 3 8385 9 0 1 +8387 4 2 4315 0 0 1 +8387 5 8385 8 0 0 0 1 +8387 6 2 1580 511 3244 2 0 1 +8389 1 8383 1 +8389 2 6 8388 1 +8389 3 8383 2 0 1 +8389 4 6 5414 11 0 1 +8389 5 8383 4 0 0 0 1 +8389 6 6 6479 3184 5219 0 0 1 +8419 1 8416 1 +8419 2 3 8414 1 +8419 3 8416 5 0 1 +8419 4 3 6238 3 0 1 +8419 5 8416 8 0 0 0 1 +8419 6 3 6064 6754 5573 0 0 1 +8423 1 8418 1 +8423 2 5 8421 1 +8423 3 8418 6 0 1 +8423 4 5 8411 11 0 1 +8423 5 8418 8 0 0 0 1 +8423 6 5 5929 1937 64 1 0 1 +8429 1 8427 1 +8429 2 2 8425 1 +8429 3 8427 2 0 1 +8429 4 2 8111 7 0 1 +8429 5 8427 2 0 0 0 1 +8429 6 2 2003 5123 5355 2 0 1 +8431 1 8428 1 +8431 2 3 8429 1 +8431 3 8428 4 0 1 +8431 4 3 4337 3 0 1 +8431 5 8428 1 0 0 0 1 +8431 6 3 7241 2827 8415 1 0 1 +8443 1 8441 1 +8443 2 2 8439 1 +8443 3 8441 6 0 1 +8443 4 2 4731 8 0 1 +8443 5 8441 7 0 0 0 1 +8443 6 2 8431 8425 8439 0 0 1 +8447 1 8442 1 +8447 2 5 8445 1 +8447 3 8442 6 0 1 +8447 4 5 4690 9 0 1 +8447 5 8442 3 0 0 0 1 +8447 6 5 8257 6076 6828 1 0 1 +8461 1 8455 1 +8461 2 6 8460 1 +8461 3 8455 8 0 1 +8461 4 6 7804 7 0 1 +8461 5 8455 2 0 0 0 1 +8461 6 6 2963 2257 4200 1 0 1 +8467 1 8465 1 +8467 2 2 8463 1 +8467 3 8465 4 0 1 +8467 4 2 5912 8 0 1 +8467 5 8465 2 0 0 0 1 +8467 6 2 2283 7061 7008 0 0 1 +8501 1 8494 1 +8501 2 7 8500 1 +8501 3 8494 1 0 1 +8501 4 7 6003 11 0 1 +8501 5 8494 10 0 0 0 1 +8501 6 7 7679 7644 1322 3 0 1 +8513 1 8508 1 +8513 2 5 8502 1 +8513 3 8508 6 0 1 +8513 4 5 5492 6 0 1 +8513 5 8508 1 0 0 0 1 +8513 6 5 1458 7531 85 1 0 1 +8521 1 8508 1 +8521 2 13 8518 1 +8521 3 8508 1 0 1 +8521 4 13 5088 25 0 1 +8521 5 8508 1 0 0 0 1 +8521 6 13 3817 5411 7988 0 0 1 +8527 1 8522 1 +8527 2 5 8526 1 +8527 3 8522 1 0 1 +8527 4 5 8207 5 0 1 +8527 5 8522 1 0 0 0 1 +8527 6 5 1927 2709 2231 2 0 1 +8537 1 8534 1 +8537 2 3 8531 1 +8537 3 8534 1 0 1 +8537 4 3 7792 1 0 1 +8537 5 8534 22 0 0 0 1 +8537 6 3 5831 2444 2380 1 0 1 +8539 1 8537 1 +8539 2 2 8538 1 +8539 3 8537 4 0 1 +8539 4 2 7075 2 0 1 +8539 5 8537 2 0 0 0 1 +8539 6 2 6655 6418 7175 0 0 1 +8543 1 8538 1 +8543 2 5 8541 1 +8543 3 8538 1 0 1 +8543 4 5 5021 5 0 1 +8543 5 8538 5 0 0 0 1 +8543 6 5 2782 5208 1478 2 0 1 +8563 1 8561 1 +8563 2 2 8559 1 +8563 3 8561 5 0 1 +8563 4 2 5843 8 0 1 +8563 5 8561 4 0 0 0 1 +8563 6 2 8102 7430 8481 0 0 1 +8573 1 8571 1 +8573 2 2 8569 1 +8573 3 8571 2 0 1 +8573 4 2 6305 1 0 1 +8573 5 8571 3 0 0 0 1 +8573 6 2 7706 6841 3192 1 0 1 +8581 1 8575 1 +8581 2 6 8577 1 +8581 3 8575 6 0 1 +8581 4 6 7245 10 0 1 +8581 5 8575 2 0 0 0 1 +8581 6 6 5084 7059 1532 1 0 1 +8597 1 8595 1 +8597 2 2 8593 1 +8597 3 8595 3 0 1 +8597 4 2 7922 6 0 1 +8597 5 8595 4 0 0 0 1 +8597 6 2 6709 5455 4088 2 0 1 +8599 1 8596 1 +8599 2 3 8598 1 +8599 3 8596 5 0 1 +8599 4 3 7681 3 0 1 +8599 5 8596 8 0 0 0 1 +8599 6 3 4637 4756 4240 0 0 1 +8609 1 8606 1 +8609 2 3 8608 1 +8609 3 8606 7 0 1 +8609 4 3 6308 7 0 1 +8609 5 8606 11 0 0 0 1 +8609 6 3 4751 1907 1867 2 0 1 +8623 1 8620 1 +8623 2 3 8622 1 +8623 3 8620 10 0 1 +8623 4 3 8007 5 0 1 +8623 5 8620 1 0 0 0 1 +8623 6 3 2263 4793 8507 0 0 1 +8627 1 8625 1 +8627 2 2 8626 1 +8627 3 8625 2 0 1 +8627 4 2 6369 2 0 1 +8627 5 8625 7 0 0 0 1 +8627 6 2 6559 3726 6628 1 0 1 +8629 1 8623 1 +8629 2 6 8621 1 +8629 3 8623 8 0 1 +8629 4 6 8257 0 0 1 +8629 5 8623 6 0 0 0 1 +8629 6 6 8607 8139 6917 2 0 1 +8641 1 8624 1 +8641 2 17 8634 1 +8641 3 8624 3 0 1 +8641 4 17 8622 26 0 1 +8641 5 8624 8 0 0 0 1 +8641 6 17 811 5137 8132 0 0 1 +8647 1 8644 1 +8647 2 3 8645 1 +8647 3 8644 1 0 1 +8647 4 3 8461 3 0 1 +8647 5 8644 6 0 0 0 1 +8647 6 3 5759 720 3543 0 0 1 +8663 1 8658 1 +8663 2 5 8662 1 +8663 3 8658 3 0 1 +8663 4 5 6897 5 0 1 +8663 5 8658 5 0 0 0 1 +8663 6 5 5105 6101 4990 2 0 1 +8669 1 8667 1 +8669 2 2 8665 1 +8669 3 8667 3 0 1 +8669 4 2 6162 1 0 1 +8669 5 8667 3 0 0 0 1 +8669 6 2 5286 1956 5119 1 0 1 +8677 1 8675 1 +8677 2 2 8673 1 +8677 3 8675 6 0 1 +8677 4 2 7175 6 0 1 +8677 5 8675 5 0 0 0 1 +8677 6 2 8665 8659 8673 0 0 1 +8681 1 8666 1 +8681 2 15 8680 1 +8681 3 8666 3 0 1 +8681 4 15 5574 4 0 1 +8681 5 8666 4 0 0 0 1 +8681 6 15 4442 6034 7487 2 0 1 +8689 1 8676 1 +8689 2 13 8686 1 +8689 3 8676 9 0 1 +8689 4 13 8553 29 0 1 +8689 5 8676 1 0 0 0 1 +8689 6 13 5398 120 8133 0 0 1 +8693 1 8691 1 +8693 2 2 8688 1 +8693 3 8691 2 0 1 +8693 4 2 5646 0 0 1 +8693 5 8691 5 0 0 0 1 +8693 6 2 8213 3798 8606 3 0 1 +8699 1 8697 1 +8699 2 2 8694 1 +8699 3 8697 3 0 1 +8699 4 2 6822 3 0 1 +8699 5 8697 11 0 0 0 1 +8699 6 2 3504 7003 4612 1 0 1 +8707 1 8702 1 +8707 2 5 8705 1 +8707 3 8702 1 0 1 +8707 4 5 8703 3 0 1 +8707 5 8702 2 0 0 0 1 +8707 6 5 3691 3786 6104 0 0 1 +8713 1 8708 1 +8713 2 5 8708 1 +8713 3 8708 1 0 1 +8713 4 5 8053 15 0 1 +8713 5 8708 1 0 0 0 1 +8713 6 5 5244 6551 7568 3 0 1 +8719 1 8716 1 +8719 2 3 8717 1 +8719 3 8716 1 0 1 +8719 4 3 7179 6 0 1 +8719 5 8716 3 0 0 0 1 +8719 6 3 8369 6247 8216 0 0 1 +8731 1 8729 1 +8731 2 2 8727 1 +8731 3 8729 2 0 1 +8731 4 2 6427 8 0 1 +8731 5 8729 3 0 0 0 1 +8731 6 2 6142 4660 815 3 0 1 +8737 1 8732 1 +8737 2 5 8732 1 +8737 3 8732 5 0 1 +8737 4 5 6826 34 0 1 +8737 5 8732 5 0 0 0 1 +8737 6 5 2847 8068 6560 0 0 1 +8741 1 8739 1 +8741 2 2 8737 1 +8741 3 8739 3 0 1 +8741 4 2 5400 1 0 1 +8741 5 8739 7 0 0 0 1 +8741 6 2 7582 7150 7172 1 0 1 +8747 1 8745 1 +8747 2 2 8743 1 +8747 3 8745 3 0 1 +8747 4 2 6301 8 0 1 +8747 5 8745 8 0 0 0 1 +8747 6 2 3019 1296 1216 1 0 1 +8753 1 8750 1 +8753 2 3 8744 1 +8753 3 8750 4 0 1 +8753 4 3 5995 6 0 1 +8753 5 8750 4 0 0 0 1 +8753 6 3 3660 1441 4276 2 0 1 +8761 1 8738 1 +8761 2 23 8758 1 +8761 3 8738 10 0 1 +8761 4 23 5114 20 0 1 +8761 5 8738 8 0 0 0 1 +8761 6 23 7319 3611 1537 1 0 1 +8779 1 8768 1 +8779 2 11 8778 1 +8779 3 8768 3 0 1 +8779 4 11 7274 2 0 1 +8779 5 8768 1 0 0 0 1 +8779 6 11 7050 2306 4786 1 0 1 +8783 1 8778 1 +8783 2 5 8781 1 +8783 3 8778 6 0 1 +8783 4 5 7117 10 0 1 +8783 5 8778 23 0 0 0 1 +8783 6 5 3955 5862 8316 1 0 1 +8803 1 8801 1 +8803 2 2 8799 1 +8803 3 8801 6 0 1 +8803 4 2 6724 8 0 1 +8803 5 8801 2 0 0 0 1 +8803 6 2 8791 8785 8799 0 0 1 +8807 1 8802 1 +8807 2 5 8805 1 +8807 3 8802 5 0 1 +8807 4 5 4665 10 0 1 +8807 5 8802 2 0 0 0 1 +8807 6 5 1200 2306 7401 2 0 1 +8819 1 8817 1 +8819 2 2 8818 1 +8819 3 8817 3 0 1 +8819 4 2 6655 2 0 1 +8819 5 8817 5 0 0 0 1 +8819 6 2 2915 3630 3811 2 0 1 +8821 1 8819 1 +8821 2 2 8817 1 +8821 3 8819 2 0 1 +8821 4 2 6971 10 0 1 +8821 5 8819 3 0 0 0 1 +8821 6 2 6300 1857 297 0 0 1 +8831 1 8824 1 +8831 2 7 8830 1 +8831 3 8824 1 0 1 +8831 4 7 8822 4 0 1 +8831 5 8824 5 0 0 0 1 +8831 6 7 3580 2624 6291 1 0 1 +8837 1 8835 1 +8837 2 2 8833 1 +8837 3 8835 3 0 1 +8837 4 2 7250 1 0 1 +8837 5 8835 7 0 0 0 1 +8837 6 2 6956 8689 2566 2 0 1 +8839 1 8836 1 +8839 2 3 8837 1 +8839 3 8836 1 0 1 +8839 4 3 4544 6 0 1 +8839 5 8836 11 0 0 0 1 +8839 6 3 2176 397 8457 0 0 1 +8849 1 8846 1 +8849 2 3 8843 1 +8849 3 8846 5 0 1 +8849 4 3 8837 0 0 1 +8849 5 8846 8 0 0 0 1 +8849 6 3 365 3317 2590 1 0 1 +8861 1 8859 1 +8861 2 2 8852 1 +8861 3 8859 4 0 1 +8861 4 2 4774 1 0 1 +8861 5 8859 2 0 0 0 1 +8861 6 2 6360 3414 6144 2 0 1 +8863 1 8860 1 +8863 2 3 8862 1 +8863 3 8860 1 0 1 +8863 4 3 8306 5 0 1 +8863 5 8860 15 0 0 0 1 +8863 6 3 6194 2869 6513 0 0 1 +8867 1 8865 1 +8867 2 2 8866 1 +8867 3 8865 5 0 1 +8867 4 2 5451 13 0 1 +8867 5 8865 4 0 0 0 1 +8867 6 2 6602 2630 2828 2 0 1 +8887 1 8884 1 +8887 2 3 8886 1 +8887 3 8884 1 0 1 +8887 4 3 7808 5 0 1 +8887 5 8884 3 0 0 0 1 +8887 6 3 3843 8137 8361 1 0 1 +8893 1 8888 1 +8893 2 5 8888 1 +8893 3 8888 6 0 1 +8893 4 5 6168 11 0 1 +8893 5 8888 13 0 0 0 1 +8893 6 5 2650 334 8386 0 0 1 +8923 1 8921 1 +8923 2 2 8922 1 +8923 3 8921 2 0 1 +8923 4 2 8144 12 0 1 +8923 5 8921 2 0 0 0 1 +8923 6 2 3743 1143 5020 2 0 1 +8929 1 8918 1 +8929 2 11 8924 1 +8929 3 8918 2 0 1 +8929 4 11 7151 27 0 1 +8929 5 8918 1 0 0 0 1 +8929 6 11 595 4416 6678 0 0 1 +8933 1 8931 1 +8933 2 2 8929 1 +8933 3 8931 3 0 1 +8933 4 2 5194 7 0 1 +8933 5 8931 4 0 0 0 1 +8933 6 2 4122 4036 7280 1 0 1 +8941 1 8935 1 +8941 2 6 8940 1 +8941 3 8935 6 0 1 +8941 4 6 6891 11 0 1 +8941 5 8935 6 0 0 0 1 +8941 6 6 1810 8744 7820 0 0 1 +8951 1 8938 1 +8951 2 13 8946 1 +8951 3 8938 5 0 1 +8951 4 13 5765 11 0 1 +8951 5 8938 1 0 0 0 1 +8951 6 13 8329 7274 6547 3 0 1 +8963 1 8961 1 +8963 2 2 8962 1 +8963 3 8961 2 0 1 +8963 4 2 4564 13 0 1 +8963 5 8961 7 0 0 0 1 +8963 6 2 4734 1878 3128 1 0 1 +8969 1 8966 1 +8969 2 3 8957 1 +8969 3 8966 5 0 1 +8969 4 3 8121 0 0 1 +8969 5 8966 4 0 0 0 1 +8969 6 3 7099 1084 5646 2 0 1 +8971 1 8969 1 +8971 2 2 8967 1 +8971 3 8969 2 0 1 +8971 4 2 8043 8 0 1 +8971 5 8969 6 0 0 0 1 +8971 6 2 4491 1899 493 0 0 1 +8999 1 8992 1 +8999 2 7 8997 1 +8999 3 8992 9 0 1 +8999 4 7 8544 4 0 1 +8999 5 8992 3 0 0 0 1 +8999 6 7 8803 8232 6050 5 0 1 +9001 1 8994 1 +9001 2 7 8998 1 +9001 3 8994 3 0 1 +9001 4 7 5064 16 0 1 +9001 5 8994 4 0 0 0 1 +9001 6 7 8167 7414 7543 0 0 1 +9007 1 9004 1 +9007 2 3 9005 1 +9007 3 9004 5 0 1 +9007 4 3 9003 4 0 1 +9007 5 9004 6 0 0 0 1 +9007 6 3 4954 800 6000 1 0 1 +9011 1 9009 1 +9011 2 2 9005 1 +9011 3 9009 2 0 1 +9011 4 2 8821 4 0 1 +9011 5 9009 4 0 0 0 1 +9011 6 2 649 2187 8646 1 0 1 +9013 1 9008 1 +9013 2 5 9008 1 +9013 3 9008 2 0 1 +9013 4 5 5925 7 0 1 +9013 5 9008 19 0 0 0 1 +9013 6 5 8822 5809 6555 0 0 1 +9029 1 9027 1 +9029 2 2 9028 1 +9029 3 9027 3 0 1 +9029 4 2 5776 4 0 1 +9029 5 9027 4 0 0 0 1 +9029 6 2 7194 1991 4979 2 0 1 +9041 1 9038 1 +9041 2 3 9040 1 +9041 3 9038 3 0 1 +9041 4 3 8772 4 0 1 +9041 5 9038 9 0 0 0 1 +9041 6 3 6171 2124 889 1 0 1 +9043 1 9040 1 +9043 2 3 9038 1 +9043 3 9040 1 0 1 +9043 4 3 7495 12 0 1 +9043 5 9040 13 0 0 0 1 +9043 6 3 1849 8353 8638 0 0 1 +9049 1 9042 1 +9049 2 7 9042 1 +9049 3 9042 2 0 1 +9049 4 7 5725 0 0 1 +9049 5 9042 4 0 0 0 1 +9049 6 7 4624 3105 2186 0 0 1 +9059 1 9057 1 +9059 2 2 9055 1 +9059 3 9057 2 0 1 +9059 4 2 4811 7 0 1 +9059 5 9057 5 0 0 0 1 +9059 6 2 1482 2453 1579 2 0 1 +9067 1 9064 1 +9067 2 3 9062 1 +9067 3 9064 10 0 1 +9067 4 3 6260 3 0 1 +9067 5 9064 3 0 0 0 1 +9067 6 3 6562 6836 6692 0 0 1 +9091 1 9088 1 +9091 2 3 9080 1 +9091 3 9088 3 0 1 +9091 4 3 7453 0 0 1 +9091 5 9088 1 0 0 0 1 +9091 6 3 5472 6337 1877 0 0 1 +9103 1 9097 1 +9103 2 6 9100 1 +9103 3 9097 6 0 1 +9103 4 6 5578 5 0 1 +9103 5 9097 2 0 0 0 1 +9103 6 6 1096 3322 4647 0 0 1 +9109 1 9099 1 +9109 2 10 9106 1 +9109 3 9099 6 0 1 +9109 4 10 4902 5 0 1 +9109 5 9099 11 0 0 0 1 +9109 6 10 3208 1962 6330 0 0 1 +9127 1 9124 1 +9127 2 3 9126 1 +9127 3 9124 1 0 1 +9127 4 3 5302 5 0 1 +9127 5 9124 4 0 0 0 1 +9127 6 3 702 4646 7426 0 0 1 +9133 1 9127 1 +9133 2 6 9131 1 +9133 3 9127 3 0 1 +9133 4 6 6574 8 0 1 +9133 5 9127 12 0 0 0 1 +9133 6 6 1196 3312 2556 0 0 1 +9137 1 9134 1 +9137 2 3 9136 1 +9137 3 9134 4 0 1 +9137 4 3 5911 4 0 1 +9137 5 9134 1 0 0 0 1 +9137 6 3 5560 3193 7286 1 0 1 +9151 1 9148 1 +9151 2 3 9150 1 +9151 3 9148 3 0 1 +9151 4 3 8204 2 0 1 +9151 5 9148 6 0 0 0 1 +9151 6 3 3429 6655 5977 0 0 1 +9157 1 9151 1 +9157 2 6 9155 1 +9157 3 9151 3 0 1 +9157 4 6 6299 8 0 1 +9157 5 9151 6 0 0 0 1 +9157 6 6 110 1682 5647 0 0 1 +9161 1 9158 1 +9161 2 3 9155 1 +9161 3 9158 12 0 1 +9161 4 3 9149 0 0 1 +9161 5 9158 3 0 0 0 1 +9161 6 3 6453 200 1330 2 0 1 +9173 1 9171 1 +9173 2 2 9172 1 +9173 3 9171 2 0 1 +9173 4 2 7906 3 0 1 +9173 5 9171 5 0 0 0 1 +9173 6 2 2784 3937 4880 2 0 1 +9181 1 9179 1 +9181 2 2 9177 1 +9181 3 9179 6 0 1 +9181 4 2 8076 10 0 1 +9181 5 9179 2 0 0 0 1 +9181 6 2 9169 9163 9177 0 0 1 +9187 1 9184 1 +9187 2 3 9186 1 +9187 3 9184 9 0 1 +9187 4 3 5702 2 0 1 +9187 5 9184 1 0 0 0 1 +9187 6 3 190 1967 7141 0 0 1 +9199 1 9196 1 +9199 2 3 9197 1 +9199 3 9196 1 0 1 +9199 4 3 7846 3 0 1 +9199 5 9196 4 0 0 0 1 +9199 6 3 5822 6629 9182 0 0 1 +9203 1 9201 1 +9203 2 2 9202 1 +9203 3 9201 2 0 1 +9203 4 2 7110 4 0 1 +9203 5 9201 7 0 0 0 1 +9203 6 2 5524 643 8945 1 0 1 +9209 1 9206 1 +9209 2 3 9208 1 +9209 3 9206 7 0 1 +9209 4 3 7273 4 0 1 +9209 5 9206 7 0 0 0 1 +9209 6 3 6289 1969 4074 1 0 1 +9221 1 9219 1 +9221 2 2 9216 1 +9221 3 9219 7 0 1 +9221 4 2 7422 15 0 1 +9221 5 9219 9 0 0 0 1 +9221 6 2 910 722 2441 2 0 1 +9227 1 9225 1 +9227 2 2 9223 1 +9227 3 9225 3 0 1 +9227 4 2 6443 7 0 1 +9227 5 9225 2 0 0 0 1 +9227 6 2 9082 3243 6820 1 0 1 +9239 1 9220 1 +9239 2 19 9234 1 +9239 3 9220 7 0 1 +9239 4 19 8312 7 0 1 +9239 5 9220 12 0 0 0 1 +9239 6 19 1407 6785 7285 2 0 1 +9241 1 9228 1 +9241 2 13 9240 1 +9241 3 9228 4 0 1 +9241 4 13 4914 14 0 1 +9241 5 9228 4 0 0 0 1 +9241 6 13 7794 4004 1012 0 0 1 +9257 1 9254 1 +9257 2 3 9256 1 +9257 3 9254 1 0 1 +9257 4 3 7434 7 0 1 +9257 5 9254 3 0 0 0 1 +9257 6 3 5278 4027 1045 2 0 1 +9277 1 9272 1 +9277 2 5 9272 1 +9277 3 9272 5 0 1 +9277 4 5 5440 11 0 1 +9277 5 9272 8 0 0 0 1 +9277 6 5 4880 1596 7970 0 0 1 +9281 1 9278 1 +9281 2 3 9275 1 +9281 3 9278 5 0 1 +9281 4 3 9269 0 0 1 +9281 5 9278 1 0 0 0 1 +9281 6 3 8133 1833 5545 1 0 1 +9283 1 9281 1 +9283 2 2 9279 1 +9283 3 9281 6 0 1 +9283 4 2 8339 8 0 1 +9283 5 9281 3 0 0 0 1 +9283 6 2 9271 9265 9279 0 0 1 +9293 1 9291 1 +9293 2 2 9289 1 +9293 3 9291 3 0 1 +9293 4 2 7365 6 0 1 +9293 5 9291 12 0 0 0 1 +9293 6 2 749 6168 4056 1 0 1 +9311 1 9304 1 +9311 2 7 9309 1 +9311 3 9304 1 0 1 +9311 4 7 6729 4 0 1 +9311 5 9304 4 0 0 0 1 +9311 6 7 4113 1876 1736 1 0 1 +9319 1 9316 1 +9319 2 3 9317 1 +9319 3 9316 4 0 1 +9319 4 3 9315 4 0 1 +9319 5 9316 1 0 0 0 1 +9319 6 3 6313 8883 8118 0 0 1 +9323 1 9321 1 +9323 2 2 9322 1 +9323 3 9321 2 0 1 +9323 4 2 9316 8 0 1 +9323 5 9321 11 0 0 0 1 +9323 6 2 6343 5860 726 2 0 1 +9337 1 9332 1 +9337 2 5 9336 1 +9337 3 9332 3 0 1 +9337 4 5 7142 8 0 1 +9337 5 9332 17 0 0 0 1 +9337 6 5 5575 6468 244 2 0 1 +9341 1 9339 1 +9341 2 2 9340 1 +9341 3 9339 3 0 1 +9341 4 2 6817 3 0 1 +9341 5 9339 4 0 0 0 1 +9341 6 2 2514 6633 7176 2 0 1 +9343 1 9338 1 +9343 2 5 9342 1 +9343 3 9338 2 0 1 +9343 4 5 6592 10 0 1 +9343 5 9338 7 0 0 0 1 +9343 6 5 2315 2343 6295 3 0 1 +9349 1 9347 1 +9349 2 2 9341 1 +9349 3 9347 2 0 1 +9349 4 2 5840 0 0 1 +9349 5 9347 3 0 0 0 1 +9349 6 2 8492 2492 7008 0 0 1 +9371 1 9369 1 +9371 2 2 9370 1 +9371 3 9369 4 0 1 +9371 4 2 5834 13 0 1 +9371 5 9369 2 0 0 0 1 +9371 6 2 6635 7764 3855 1 0 1 +9377 1 9374 1 +9377 2 3 9368 1 +9377 3 9374 10 0 1 +9377 4 3 5819 3 0 1 +9377 5 9374 12 0 0 0 1 +9377 6 3 3121 5127 2868 1 0 1 +9391 1 9388 1 +9391 2 3 9390 1 +9391 3 9388 6 0 1 +9391 4 3 6807 6 0 1 +9391 5 9388 7 0 0 0 1 +9391 6 3 1863 2392 5521 0 0 1 +9397 1 9395 1 +9397 2 2 9396 1 +9397 3 9395 6 0 1 +9397 4 2 7969 6 0 1 +9397 5 9395 9 0 0 0 1 +9397 6 2 5616 6531 5832 0 0 1 +9403 1 9400 1 +9403 2 3 9396 1 +9403 3 9400 1 0 1 +9403 4 3 9129 11 0 1 +9403 5 9400 5 0 0 0 1 +9403 6 3 5255 7055 4230 1 0 1 +9413 1 9410 1 +9413 2 3 9412 1 +9413 3 9410 4 0 1 +9413 4 3 5447 4 0 1 +9413 5 9410 5 0 0 0 1 +9413 6 3 8993 8167 4942 4 0 1 +9419 1 9417 1 +9419 2 2 9413 1 +9419 3 9417 9 0 1 +9419 4 2 6628 0 0 1 +9419 5 9417 3 0 0 0 1 +9419 6 2 7744 1647 8231 1 0 1 +9421 1 9419 1 +9421 2 2 9420 1 +9421 3 9419 6 0 1 +9421 4 2 8855 7 0 1 +9421 5 9419 2 0 0 0 1 +9421 6 2 4585 2484 1701 0 0 1 +9431 1 9424 1 +9431 2 7 9430 1 +9431 3 9424 3 0 1 +9431 4 7 6132 2 0 1 +9431 5 9424 5 0 0 0 1 +9431 6 7 2701 1680 8388 1 0 1 +9433 1 9428 1 +9433 2 5 9430 1 +9433 3 9428 9 0 1 +9433 4 5 9422 14 0 1 +9433 5 9428 5 0 0 0 1 +9433 6 5 8892 1778 9190 0 0 1 +9437 1 9435 1 +9437 2 2 9428 1 +9437 3 9435 4 0 1 +9437 4 2 6215 1 0 1 +9437 5 9435 4 0 0 0 1 +9437 6 2 2779 7855 3741 1 0 1 +9439 1 9417 1 +9439 2 22 9438 1 +9439 3 9417 2 0 1 +9439 4 22 8780 2 0 1 +9439 5 9417 3 0 0 0 1 +9439 6 22 8565 5999 6390 0 0 1 +9461 1 9458 1 +9461 2 3 9459 1 +9461 3 9458 12 0 1 +9461 4 3 7151 14 0 1 +9461 5 9458 6 0 0 0 1 +9461 6 3 1197 6380 4176 1 0 1 +9463 1 9460 1 +9463 2 3 9461 1 +9463 3 9460 4 0 1 +9463 4 3 9459 4 0 1 +9463 5 9460 1 0 0 0 1 +9463 6 3 5543 5930 5856 0 0 1 +9467 1 9465 1 +9467 2 2 9466 1 +9467 3 9465 2 0 1 +9467 4 2 6384 4 0 1 +9467 5 9465 2 0 0 0 1 +9467 6 2 1881 6205 5578 1 0 1 +9473 1 9470 1 +9473 2 3 9467 1 +9473 3 9470 1 0 1 +9473 4 3 5129 1 0 1 +9473 5 9470 19 0 0 0 1 +9473 6 3 1935 6654 995 2 0 1 +9479 1 9472 1 +9479 2 7 9472 1 +9479 3 9472 2 0 1 +9479 4 7 6365 8 0 1 +9479 5 9472 2 0 0 0 1 +9479 6 7 7469 8721 3242 3 0 1 +9491 1 9489 1 +9491 2 2 9476 1 +9491 3 9489 5 0 1 +9491 4 2 5083 4 0 1 +9491 5 9489 6 0 0 0 1 +9491 6 2 270 5031 8755 3 0 1 +9497 1 9494 1 +9497 2 3 9491 1 +9497 3 9494 3 0 1 +9497 4 3 6593 11 0 1 +9497 5 9494 6 0 0 0 1 +9497 6 3 6345 5362 863 1 0 1 +9511 1 9508 1 +9511 2 3 9510 1 +9511 3 9508 4 0 1 +9511 4 3 9373 3 0 1 +9511 5 9508 6 0 0 0 1 +9511 6 3 6658 4480 7514 0 0 1 +9521 1 9518 1 +9521 2 3 9520 1 +9521 3 9518 3 0 1 +9521 4 3 5073 7 0 1 +9521 5 9518 3 0 0 0 1 +9521 6 3 4999 8694 307 2 0 1 +9533 1 9531 1 +9533 2 2 9529 1 +9533 3 9531 2 0 1 +9533 4 2 5479 1 0 1 +9533 5 9531 2 0 0 0 1 +9533 6 2 2635 4771 6184 5 0 1 +9539 1 9537 1 +9539 2 2 9538 1 +9539 3 9537 11 0 1 +9539 4 2 9532 8 0 1 +9539 5 9537 2 0 0 0 1 +9539 6 2 4451 8475 9120 1 0 1 +9547 1 9545 1 +9547 2 2 9546 1 +9547 3 9545 2 0 1 +9547 4 2 4903 10 0 1 +9547 5 9545 6 0 0 0 1 +9547 6 2 9537 5553 3164 0 0 1 +9551 1 9540 1 +9551 2 11 9550 1 +9551 3 9540 7 0 1 +9551 4 11 8763 4 0 1 +9551 5 9540 8 0 0 0 1 +9551 6 11 4846 6942 2120 1 0 1 +9587 1 9585 1 +9587 2 2 9583 1 +9587 3 9585 3 0 1 +9587 4 2 7602 8 0 1 +9587 5 9585 15 0 0 0 1 +9587 6 2 3461 1202 8007 4 0 1 +9601 1 9588 1 +9601 2 13 9598 1 +9601 3 9588 5 0 1 +9601 4 13 6113 42 0 1 +9601 5 9588 15 0 0 0 1 +9601 6 13 8072 4399 5411 0 0 1 +9613 1 9611 1 +9613 2 2 9606 1 +9613 3 9611 5 0 1 +9613 4 2 6141 5 0 1 +9613 5 9611 6 0 0 0 1 +9613 6 2 3952 1517 6558 0 0 1 +9619 1 9617 1 +9619 2 2 9615 1 +9619 3 9617 2 0 1 +9619 4 2 7026 8 0 1 +9619 5 9617 3 0 0 0 1 +9619 6 2 373 4736 8835 0 0 1 +9623 1 9618 1 +9623 2 5 9621 1 +9623 3 9618 1 0 1 +9623 4 5 7793 8 0 1 +9623 5 9618 18 0 0 0 1 +9623 6 5 3984 8996 5702 2 0 1 +9629 1 9627 1 +9629 2 2 9621 1 +9629 3 9627 2 0 1 +9629 4 2 6790 0 0 1 +9629 5 9627 13 0 0 0 1 +9629 6 2 4940 5754 6591 1 0 1 +9631 1 9628 1 +9631 2 3 9629 1 +9631 3 9628 7 0 1 +9631 4 3 5229 6 0 1 +9631 5 9628 7 0 0 0 1 +9631 6 3 5073 5882 7033 0 0 1 +9643 1 9641 1 +9643 2 2 9639 1 +9643 3 9641 6 0 1 +9643 4 2 5310 8 0 1 +9643 5 9641 4 0 0 0 1 +9643 6 2 9631 9625 9639 0 0 1 +9649 1 9642 1 +9649 2 7 9642 1 +9649 3 9642 2 0 1 +9649 4 7 5002 0 0 1 +9649 5 9642 11 0 0 0 1 +9649 6 7 7129 3802 1048 0 0 1 +9661 1 9659 1 +9661 2 2 9657 1 +9661 3 9659 2 0 1 +9661 4 2 9105 6 0 1 +9661 5 9659 6 0 0 0 1 +9661 6 2 8970 4756 665 0 0 1 +9677 1 9675 1 +9677 2 2 9673 1 +9677 3 9675 3 0 1 +9677 4 2 8915 1 0 1 +9677 5 9675 21 0 0 0 1 +9677 6 2 747 3816 3455 2 0 1 +9679 1 9676 1 +9679 2 3 9678 1 +9679 3 9676 7 0 1 +9679 4 3 7499 2 0 1 +9679 5 9676 8 0 0 0 1 +9679 6 3 90 9445 7366 0 0 1 +9689 1 9686 1 +9689 2 3 9683 1 +9689 3 9686 6 0 1 +9689 4 3 9677 0 0 1 +9689 5 9686 4 0 0 0 1 +9689 6 3 223 5702 6648 1 0 1 +9697 1 9687 1 +9697 2 10 9692 1 +9697 3 9687 5 0 1 +9697 4 10 6346 10 0 1 +9697 5 9687 24 0 0 0 1 +9697 6 10 3349 7898 2350 0 0 1 +9719 1 9702 1 +9719 2 17 9712 1 +9719 3 9702 1 0 1 +9719 4 17 5263 8 0 1 +9719 5 9702 3 0 0 0 1 +9719 6 17 7452 2386 9440 3 0 1 +9721 1 9714 1 +9721 2 7 9718 1 +9721 3 9714 5 0 1 +9721 4 7 9702 22 0 1 +9721 5 9714 1 0 0 0 1 +9721 6 7 113 1306 5624 0 0 1 +9733 1 9731 1 +9733 2 2 9732 1 +9733 3 9731 2 0 1 +9733 4 2 9726 8 0 1 +9733 5 9731 2 0 0 0 1 +9733 6 2 8889 7453 2254 0 0 1 +9739 1 9736 1 +9739 2 3 9732 1 +9739 3 9736 8 0 1 +9739 4 3 8326 5 0 1 +9739 5 9736 1 0 0 0 1 +9739 6 3 9508 7496 2435 0 0 1 +9743 1 9738 1 +9743 2 5 9740 1 +9743 3 9738 8 0 1 +9743 4 5 5224 6 0 1 +9743 5 9738 2 0 0 0 1 +9743 6 5 6883 8750 5105 1 0 1 +9749 1 9747 1 +9749 2 2 9748 1 +9749 3 9747 5 0 1 +9749 4 2 5546 4 0 1 +9749 5 9747 6 0 0 0 1 +9749 6 2 7694 5721 3734 2 0 1 +9767 1 9762 1 +9767 2 5 9765 1 +9767 3 9762 2 0 1 +9767 4 5 9763 3 0 1 +9767 5 9762 3 0 0 0 1 +9767 6 5 2381 5959 3257 3 0 1 +9769 1 9756 1 +9769 2 13 9768 1 +9769 3 9756 9 0 1 +9769 4 13 6230 14 0 1 +9769 5 9756 1 0 0 0 1 +9769 6 13 6921 632 8704 0 0 1 +9781 1 9775 1 +9781 2 6 9777 1 +9781 3 9775 4 0 1 +9781 4 6 5001 2 0 1 +9781 5 9775 6 0 0 0 1 +9781 6 6 9149 9684 2229 0 0 1 +9787 1 9784 1 +9787 2 3 9786 1 +9787 3 9784 4 0 1 +9787 4 3 6629 2 0 1 +9787 5 9784 4 0 0 0 1 +9787 6 3 5127 4555 9505 0 0 1 +9791 1 9780 1 +9791 2 11 9790 1 +9791 3 9780 1 0 1 +9791 4 11 6086 2 0 1 +9791 5 9780 2 0 0 0 1 +9791 6 11 2437 3419 6324 2 0 1 +9803 1 9801 1 +9803 2 2 9802 1 +9803 3 9801 2 0 1 +9803 4 2 7808 2 0 1 +9803 5 9801 3 0 0 0 1 +9803 6 2 1791 6435 2148 1 0 1 +9811 1 9808 1 +9811 2 3 9810 1 +9811 3 9808 1 0 1 +9811 4 3 6930 6 0 1 +9811 5 9808 13 0 0 0 1 +9811 6 3 7526 2384 5050 0 0 1 +9817 1 9812 1 +9817 2 5 9816 1 +9817 3 9812 1 0 1 +9817 4 5 5210 6 0 1 +9817 5 9812 1 0 0 0 1 +9817 6 5 1895 215 6969 0 0 1 +9829 1 9819 1 +9829 2 10 9825 1 +9829 3 9819 11 0 1 +9829 4 10 5988 2 0 1 +9829 5 9819 3 0 0 0 1 +9829 6 10 2581 8245 8531 0 0 1 +9833 1 9830 1 +9833 2 3 9824 1 +9833 3 9830 6 0 1 +9833 4 3 6035 12 0 1 +9833 5 9830 5 0 0 0 1 +9833 6 3 3223 2059 6117 1 0 1 +9839 1 9832 1 +9839 2 7 9838 1 +9839 3 9832 1 0 1 +9839 4 7 5413 2 0 1 +9839 5 9832 1 0 0 0 1 +9839 6 7 8207 1934 3887 1 0 1 +9851 1 9849 1 +9851 2 2 9845 1 +9851 3 9849 2 0 1 +9851 4 2 5951 4 0 1 +9851 5 9849 7 0 0 0 1 +9851 6 2 6021 1251 5705 2 0 1 +9857 1 9852 1 +9857 2 5 9856 1 +9857 3 9852 5 0 1 +9857 4 5 9114 4 0 1 +9857 5 9852 10 0 0 0 1 +9857 6 5 4495 7184 7053 2 0 1 +9859 1 9857 1 +9859 2 2 9855 1 +9859 3 9857 4 0 1 +9859 4 2 9231 1 0 1 +9859 5 9857 3 0 0 0 1 +9859 6 2 2796 4250 5028 0 0 1 +9871 1 9868 1 +9871 2 3 9869 1 +9871 3 9868 3 0 1 +9871 4 3 6493 3 0 1 +9871 5 9868 3 0 0 0 1 +9871 6 3 7230 2345 4177 1 0 1 +9883 1 9881 1 +9883 2 2 9882 1 +9883 3 9881 2 0 1 +9883 4 2 5028 11 0 1 +9883 5 9881 12 0 0 0 1 +9883 6 2 8787 9638 9399 0 0 1 +9887 1 9882 1 +9887 2 5 9882 1 +9887 3 9882 1 0 1 +9887 4 5 7319 6 0 1 +9887 5 9882 3 0 0 0 1 +9887 6 5 8678 2032 6861 1 0 1 +9901 1 9899 1 +9901 2 2 9900 1 +9901 3 9899 4 0 1 +9901 4 2 9894 8 0 1 +9901 5 9899 2 0 0 0 1 +9901 6 2 1748 4483 8692 1 0 1 +9907 1 9905 1 +9907 2 2 9903 1 +9907 3 9905 4 0 1 +9907 4 2 6151 8 0 1 +9907 5 9905 9 0 0 0 1 +9907 6 2 5230 3284 7577 0 0 1 +9923 1 9921 1 +9923 2 2 9918 1 +9923 3 9921 4 0 1 +9923 4 2 9317 0 0 1 +9923 5 9921 6 0 0 0 1 +9923 6 2 2269 2624 6629 1 0 1 +9929 1 9926 1 +9929 2 3 9928 1 +9929 3 9926 1 0 1 +9929 4 3 8041 4 0 1 +9929 5 9926 3 0 0 0 1 +9929 6 3 2171 5942 8347 1 0 1 +9931 1 9921 1 +9931 2 10 9928 1 +9931 3 9921 4 0 1 +9931 4 10 9545 4 0 1 +9931 5 9921 2 0 0 0 1 +9931 6 10 2316 8350 5581 2 0 1 +9941 1 9939 1 +9941 2 2 9937 1 +9941 3 9939 3 0 1 +9941 4 2 8321 7 0 1 +9941 5 9939 2 0 0 0 1 +9941 6 2 1291 7931 1408 2 0 1 +9949 1 9947 1 +9949 2 2 9945 1 +9949 3 9947 4 0 1 +9949 4 2 9170 10 0 1 +9949 5 9947 5 0 0 0 1 +9949 6 2 1443 1156 6970 0 0 1 +9967 1 9964 1 +9967 2 3 9965 1 +9967 3 9964 3 0 1 +9967 4 3 9963 4 0 1 +9967 5 9964 4 0 0 0 1 +9967 6 3 6881 7254 9681 0 0 1 +9973 1 9962 1 +9973 2 11 9969 1 +9973 3 9962 1 0 1 +9973 4 11 7687 2 0 1 +9973 5 9962 8 0 0 0 1 +9973 6 11 3928 2985 9944 0 0 1 +10007 1 10002 1 +10007 2 5 10005 1 +10007 3 10002 3 0 1 +10007 4 5 9995 11 0 1 +10007 5 10002 3 0 0 0 1 +10007 6 5 7978 7220 7070 1 0 1 +10009 1 9998 1 +10009 2 11 10005 1 +10009 3 9998 1 0 1 +10009 4 11 9995 11 0 1 +10009 5 9998 1 0 0 0 1 +10009 6 11 8706 3520 9952 1 0 1 +10037 1 10035 1 +10037 2 2 10033 1 +10037 3 10035 2 0 1 +10037 4 2 7099 1 0 1 +10037 5 10035 3 0 0 0 1 +10037 6 2 102 8872 6761 1 0 1 +10039 1 10036 1 +10039 2 3 10038 1 +10039 3 10036 1 0 1 +10039 4 3 6587 2 0 1 +10039 5 10036 3 0 0 0 1 +10039 6 3 4408 9268 8821 3 0 1 +10061 1 10058 1 +10061 2 3 10059 1 +10061 3 10058 4 0 1 +10061 4 3 10057 4 0 1 +10061 5 10058 9 0 0 0 1 +10061 6 3 8516 7568 6258 2 0 1 +10067 1 10065 1 +10067 2 2 10063 1 +10067 3 10065 3 0 1 +10067 4 2 7032 14 0 1 +10067 5 10065 3 0 0 0 1 +10067 6 2 9132 2222 7159 1 0 1 +10069 1 10067 1 +10069 2 2 10065 1 +10069 3 10067 4 0 1 +10069 4 2 8451 6 0 1 +10069 5 10067 4 0 0 0 1 +10069 6 2 2432 8214 5305 0 0 1 +10079 1 10068 1 +10079 2 11 10076 1 +10079 3 10068 2 0 1 +10079 4 11 5337 12 0 1 +10079 5 10068 3 0 0 0 1 +10079 6 11 9540 4152 9065 5 0 1 +10091 1 10089 1 +10091 2 2 10087 1 +10091 3 10089 3 0 1 +10091 4 2 6538 8 0 1 +10091 5 10089 8 0 0 0 1 +10091 6 2 7118 9253 3773 1 0 1 +10093 1 10091 1 +10093 2 2 10092 1 +10093 3 10091 2 0 1 +10093 4 2 5918 3 0 1 +10093 5 10091 2 0 0 0 1 +10093 6 2 6200 562 4293 0 0 1 +10099 1 10097 1 +10099 2 2 10095 1 +10099 3 10097 6 0 1 +10099 4 2 9440 1 0 1 +10099 5 10097 5 0 0 0 1 +10099 6 2 355 883 6474 0 0 1 +10103 1 10098 1 +10103 2 5 10102 1 +10103 3 10098 8 0 1 +10103 4 5 6950 4 0 1 +10103 5 10098 1 0 0 0 1 +10103 6 5 8645 8394 7728 1 0 1 +10111 1 10099 1 +10111 2 12 10109 1 +10111 3 10099 5 0 1 +10111 4 12 8381 3 0 1 +10111 5 10099 4 0 0 0 1 +10111 6 12 91 4329 5293 1 0 1 +10133 1 10131 1 +10133 2 2 10129 1 +10133 3 10131 3 0 1 +10133 4 2 5713 7 0 1 +10133 5 10131 2 0 0 0 1 +10133 6 2 9574 3849 8838 1 0 1 +10139 1 10137 1 +10139 2 2 10138 1 +10139 3 10137 5 0 1 +10139 4 2 10132 8 0 1 +10139 5 10137 4 0 0 0 1 +10139 6 2 1353 1688 2822 1 0 1 +10141 1 10139 1 +10141 2 2 10140 1 +10141 3 10139 5 0 1 +10141 4 2 8225 3 0 1 +10141 5 10139 5 0 0 0 1 +10141 6 2 4279 4575 8246 0 0 1 +10151 1 10144 1 +10151 2 7 10149 1 +10151 3 10144 1 0 1 +10151 4 7 7169 4 0 1 +10151 5 10144 17 0 0 0 1 +10151 6 7 502 5985 7872 1 0 1 +10159 1 10156 1 +10159 2 3 10157 1 +10159 3 10156 1 0 1 +10159 4 3 9468 3 0 1 +10159 5 10156 4 0 0 0 1 +10159 6 3 9446 9225 438 0 0 1 +10163 1 10161 1 +10163 2 2 10159 1 +10163 3 10161 2 0 1 +10163 4 2 8097 17 0 1 +10163 5 10161 5 0 0 0 1 +10163 6 2 2747 2058 9888 1 0 1 +10169 1 10166 1 +10169 2 3 10163 1 +10169 3 10166 1 0 1 +10169 4 3 10157 0 0 1 +10169 5 10166 9 0 0 0 1 +10169 6 3 9807 1773 6295 5 0 1 +10177 1 10170 1 +10177 2 7 10174 1 +10177 3 10170 1 0 1 +10177 4 7 10034 8 0 1 +10177 5 10170 9 0 0 0 1 +10177 6 7 8952 8195 10064 0 0 1 +10181 1 10179 1 +10181 2 2 10180 1 +10181 3 10179 9 0 1 +10181 4 2 6033 3 0 1 +10181 5 10179 7 0 0 0 1 +10181 6 2 3594 8153 7912 1 0 1 +10193 1 10190 1 +10193 2 3 10192 1 +10193 3 10190 7 0 1 +10193 4 3 8097 4 0 1 +10193 5 10190 1 0 0 0 1 +10193 6 3 3862 8561 9167 1 0 1 +10211 1 10205 1 +10211 2 6 10210 1 +10211 3 10205 1 0 1 +10211 4 6 8236 2 0 1 +10211 5 10205 7 0 0 0 1 +10211 6 6 7499 8739 8209 1 0 1 +10223 1 10218 1 +10223 2 5 10221 1 +10223 3 10218 1 0 1 +10223 4 5 9079 14 0 1 +10223 5 10218 12 0 0 0 1 +10223 6 5 7202 5227 9800 1 0 1 +10243 1 10236 1 +10243 2 7 10241 1 +10243 3 10236 2 0 1 +10243 4 7 9513 13 0 1 +10243 5 10236 7 0 0 0 1 +10243 6 7 5937 6838 8205 0 0 1 +10247 1 10242 1 +10247 2 5 10244 1 +10247 3 10242 5 0 1 +10247 4 5 5485 6 0 1 +10247 5 10242 2 0 0 0 1 +10247 6 5 5326 8735 6340 1 0 1 +10253 1 10251 1 +10253 2 2 10252 1 +10253 3 10251 8 0 1 +10253 4 2 8614 6 0 1 +10253 5 10251 11 0 0 0 1 +10253 6 2 2012 2852 5703 1 0 1 +10259 1 10257 1 +10259 2 2 10249 1 +10259 3 10257 5 0 1 +10259 4 2 8416 0 0 1 +10259 5 10257 5 0 0 0 1 +10259 6 2 1727 5263 7235 1 0 1 +10267 1 10265 1 +10267 2 2 10263 1 +10267 3 10265 2 0 1 +10267 4 2 8737 1 0 1 +10267 5 10265 17 0 0 0 1 +10267 6 2 3657 3099 4244 0 0 1 +10271 1 10264 1 +10271 2 7 10270 1 +10271 3 10264 1 0 1 +10271 4 7 6272 3 0 1 +10271 5 10264 1 0 0 0 1 +10271 6 7 9500 1943 3784 1 0 1 +10273 1 10263 1 +10273 2 10 10268 1 +10273 3 10263 5 0 1 +10273 4 10 9542 16 0 1 +10273 5 10263 4 0 0 0 1 +10273 6 10 2243 6345 3002 1 0 1 +10289 1 10286 1 +10289 2 3 10283 1 +10289 3 10286 1 0 1 +10289 4 3 10277 0 0 1 +10289 5 10286 4 0 0 0 1 +10289 6 3 8887 8083 9311 1 0 1 +10301 1 10299 1 +10301 2 2 10293 1 +10301 3 10299 2 0 1 +10301 4 2 9322 0 0 1 +10301 5 10299 7 0 0 0 1 +10301 6 2 1126 316 2802 2 0 1 +10303 1 10300 1 +10303 2 3 10302 1 +10303 3 10300 4 0 1 +10303 4 3 9982 2 0 1 +10303 5 10300 6 0 0 0 1 +10303 6 3 119 6862 2036 9 0 1 +10313 1 10310 1 +10313 2 3 10312 1 +10313 3 10310 5 0 1 +10313 4 3 5430 4 0 1 +10313 5 10310 12 0 0 0 1 +10313 6 3 3920 3425 5885 1 0 1 +10321 1 10314 1 +10321 2 7 10314 1 +10321 3 10314 8 0 1 +10321 4 7 5844 0 0 1 +10321 5 10314 9 0 0 0 1 +10321 6 7 8505 8845 7362 0 0 1 +10331 1 10329 1 +10331 2 2 10330 1 +10331 3 10329 3 0 1 +10331 4 2 8493 2 0 1 +10331 5 10329 2 0 0 0 1 +10331 6 2 3409 9355 5321 1 0 1 +10333 1 10328 1 +10333 2 5 10328 1 +10333 3 10328 3 0 1 +10333 4 5 6295 11 0 1 +10333 5 10328 7 0 0 0 1 +10333 6 5 5943 6139 5383 0 0 1 +10337 1 10334 1 +10337 2 3 10336 1 +10337 3 10334 3 0 1 +10337 4 3 9346 7 0 1 +10337 5 10334 10 0 0 0 1 +10337 6 3 9593 5351 1518 1 0 1 +10343 1 10338 1 +10343 2 5 10341 1 +10343 3 10338 5 0 1 +10343 4 5 10339 3 0 1 +10343 5 10338 5 0 0 0 1 +10343 6 5 4855 709 8804 2 0 1 +10357 1 10355 1 +10357 2 2 10353 1 +10357 3 10355 4 0 1 +10357 4 2 9464 9 0 1 +10357 5 10355 29 0 0 0 1 +10357 6 2 7218 4223 6369 1 0 1 +10369 1 10356 1 +10369 2 13 10358 1 +10369 3 10356 4 0 1 +10369 4 13 5914 0 0 1 +10369 5 10356 14 0 0 0 1 +10369 6 13 9237 7072 9774 5 0 1 +10391 1 10372 1 +10391 2 19 10389 1 +10391 3 10372 1 0 1 +10391 4 19 8160 3 0 1 +10391 5 10372 6 0 0 0 1 +10391 6 19 8612 5888 4117 2 0 1 +10399 1 10393 1 +10399 2 6 10397 1 +10399 3 10393 1 0 1 +10399 4 6 10004 4 0 1 +10399 5 10393 4 0 0 0 1 +10399 6 6 3057 5189 6359 1 0 1 +10427 1 10425 1 +10427 2 2 10423 1 +10427 3 10425 3 0 1 +10427 4 2 6390 8 0 1 +10427 5 10425 4 0 0 0 1 +10427 6 2 2327 2364 2585 3 0 1 +10429 1 10422 1 +10429 2 7 10423 1 +10429 3 10422 8 0 1 +10429 4 7 6339 8 0 1 +10429 5 10422 5 0 0 0 1 +10429 6 7 702 1521 2882 0 0 1 +10433 1 10430 1 +10433 2 3 10428 1 +10433 3 10430 1 0 1 +10433 4 3 9291 2 0 1 +10433 5 10430 11 0 0 0 1 +10433 6 3 5541 9400 2175 1 0 1 +10453 1 10448 1 +10453 2 5 10452 1 +10453 3 10448 3 0 1 +10453 4 5 8607 3 0 1 +10453 5 10448 11 0 0 0 1 +10453 6 5 9188 8836 20 2 0 1 +10457 1 10454 1 +10457 2 3 10456 1 +10457 3 10454 3 0 1 +10457 4 3 5413 6 0 1 +10457 5 10454 4 0 0 0 1 +10457 6 3 3710 9475 2194 2 0 1 +10459 1 10457 1 +10459 2 2 10455 1 +10459 3 10457 2 0 1 +10459 4 2 5399 8 0 1 +10459 5 10457 5 0 0 0 1 +10459 6 2 5965 1050 1150 0 0 1 +10463 1 10458 1 +10463 2 5 10461 1 +10463 3 10458 2 0 1 +10463 4 5 7139 5 0 1 +10463 5 10458 9 0 0 0 1 +10463 6 5 2150 9054 10455 1 0 1 +10477 1 10475 1 +10477 2 2 10476 1 +10477 3 10475 2 0 1 +10477 4 2 9846 6 0 1 +10477 5 10475 5 0 0 0 1 +10477 6 2 5188 9854 6644 0 0 1 +10487 1 10482 1 +10487 2 5 10486 1 +10487 3 10482 1 0 1 +10487 4 5 5442 5 0 1 +10487 5 10482 5 0 0 0 1 +10487 6 5 10225 1681 7999 1 0 1 +10499 1 10497 1 +10499 2 2 10495 1 +10499 3 10497 3 0 1 +10499 4 2 7152 7 0 1 +10499 5 10497 12 0 0 0 1 +10499 6 2 6824 8169 10136 1 0 1 +10501 1 10499 1 +10501 2 2 10497 1 +10501 3 10499 2 0 1 +10501 4 2 5365 6 0 1 +10501 5 10499 11 0 0 0 1 +10501 6 2 806 246 10118 0 0 1 +10513 1 10506 1 +10513 2 7 10506 1 +10513 3 10506 1 0 1 +10513 4 7 8031 21 0 1 +10513 5 10506 3 0 0 0 1 +10513 6 7 4862 7613 5528 0 0 1 +10529 1 10526 1 +10529 2 3 10520 1 +10529 3 10526 5 0 1 +10529 4 3 9453 15 0 1 +10529 5 10526 5 0 0 0 1 +10529 6 3 9960 3590 9477 3 0 1 +10531 1 10528 1 +10531 2 3 10524 1 +10531 3 10528 3 0 1 +10531 4 3 9291 5 0 1 +10531 5 10528 13 0 0 0 1 +10531 6 3 4037 4785 8414 1 0 1 +10559 1 10536 1 +10559 2 23 10558 1 +10559 3 10536 10 0 1 +10559 4 23 10135 4 0 1 +10559 5 10536 2 0 0 0 1 +10559 6 23 4513 1327 8562 1 0 1 +10567 1 10561 1 +10567 2 6 10566 1 +10567 3 10561 2 0 1 +10567 4 6 8731 2 0 1 +10567 5 10561 6 0 0 0 1 +10567 6 6 2127 2150 5867 0 0 1 +10589 1 10587 1 +10589 2 2 10588 1 +10589 3 10587 3 0 1 +10589 4 2 5746 3 0 1 +10589 5 10587 18 0 0 0 1 +10589 6 2 6284 3375 5122 1 0 1 +10597 1 10592 1 +10597 2 5 10596 1 +10597 3 10592 11 0 1 +10597 4 5 8893 3 0 1 +10597 5 10592 2 0 0 0 1 +10597 6 5 8342 5064 9389 0 0 1 +10601 1 10598 1 +10601 2 3 10596 1 +10601 3 10598 7 0 1 +10601 4 3 5797 2 0 1 +10601 5 10598 3 0 0 0 1 +10601 6 3 1548 5573 8384 8 0 1 +10607 1 10602 1 +10607 2 5 10599 1 +10607 3 10602 5 0 1 +10607 4 5 10428 3 0 1 +10607 5 10602 3 0 0 0 1 +10607 6 5 3761 10137 9577 1 0 1 +10613 1 10611 1 +10613 2 2 10608 1 +10613 3 10611 8 0 1 +10613 4 2 7629 8 0 1 +10613 5 10611 6 0 0 0 1 +10613 6 2 5300 6621 6918 2 0 1 +10627 1 10622 1 +10627 2 5 10625 1 +10627 3 10622 1 0 1 +10627 4 5 10619 6 0 1 +10627 5 10622 2 0 0 0 1 +10627 6 5 2103 2607 6675 0 0 1 +10631 1 10620 1 +10631 2 11 10629 1 +10631 3 10620 1 0 1 +10631 4 11 7438 5 0 1 +10631 5 10620 1 0 0 0 1 +10631 6 11 2265 3246 2360 2 0 1 +10639 1 10633 1 +10639 2 6 10635 1 +10639 3 10633 3 0 1 +10639 4 6 6229 5 0 1 +10639 5 10633 3 0 0 0 1 +10639 6 6 7741 10588 5732 2 0 1 +10651 1 10644 1 +10651 2 7 10649 1 +10651 3 10644 2 0 1 +10651 4 7 8034 6 0 1 +10651 5 10644 8 0 0 0 1 +10651 6 7 8343 5328 6888 0 0 1 +10657 1 10650 1 +10657 2 7 10650 1 +10657 3 10650 3 0 1 +10657 4 7 8173 14 0 1 +10657 5 10650 3 0 0 0 1 +10657 6 7 6442 4670 9286 0 0 1 +10663 1 10660 1 +10663 2 3 10657 1 +10663 3 10660 1 0 1 +10663 4 3 10651 0 0 1 +10663 5 10660 3 0 0 0 1 +10663 6 3 2853 8493 7534 0 0 1 +10667 1 10665 1 +10667 2 2 10666 1 +10667 3 10665 3 0 1 +10667 4 2 9077 4 0 1 +10667 5 10665 16 0 0 0 1 +10667 6 2 9831 1922 2875 1 0 1 +10687 1 10682 1 +10687 2 5 10685 1 +10687 3 10682 7 0 1 +10687 4 5 10683 3 0 1 +10687 5 10682 5 0 0 0 1 +10687 6 5 8608 2242 1554 4 0 1 +10691 1 10689 1 +10691 2 2 10685 1 +10691 3 10689 12 0 1 +10691 4 2 8483 0 0 1 +10691 5 10689 21 0 0 0 1 +10691 6 2 4913 8402 879 2 0 1 +10709 1 10707 1 +10709 2 2 10708 1 +10709 3 10707 5 0 1 +10709 4 2 6531 3 0 1 +10709 5 10707 4 0 0 0 1 +10709 6 2 2824 7462 9497 2 0 1 +10711 1 10708 1 +10711 2 3 10710 1 +10711 3 10708 9 0 1 +10711 4 3 7232 2 0 1 +10711 5 10708 1 0 0 0 1 +10711 6 3 9464 216 6034 0 0 1 +10723 1 10721 1 +10723 2 2 10722 1 +10723 3 10721 2 0 1 +10723 4 2 10716 8 0 1 +10723 5 10721 6 0 0 0 1 +10723 6 2 8107 9992 10099 0 0 1 +10729 1 10722 1 +10729 2 7 10722 1 +10729 3 10722 7 0 1 +10729 4 7 8196 0 0 1 +10729 5 10722 5 0 0 0 1 +10729 6 7 9079 3233 3512 1 0 1 +10733 1 10731 1 +10733 2 2 10729 1 +10733 3 10731 3 0 1 +10733 4 2 5821 9 0 1 +10733 5 10731 2 0 0 0 1 +10733 6 2 9859 3470 7843 2 0 1 +10739 1 10733 1 +10739 2 6 10738 1 +10739 3 10733 2 0 1 +10739 4 6 6930 5 0 1 +10739 5 10733 4 0 0 0 1 +10739 6 6 10428 8594 10506 1 0 1 +10753 1 10742 1 +10753 2 11 10752 1 +10753 3 10742 2 0 1 +10753 4 11 9268 21 0 1 +10753 5 10742 1 0 0 0 1 +10753 6 11 8853 456 6717 0 0 1 +10771 1 10768 1 +10771 2 3 10770 1 +10771 3 10768 4 0 1 +10771 4 3 10157 2 0 1 +10771 5 10768 4 0 0 0 1 +10771 6 3 4964 4159 3365 0 0 1 +10781 1 10771 1 +10781 2 10 10780 1 +10781 3 10771 4 0 1 +10781 4 10 7606 11 0 1 +10781 5 10771 11 0 0 0 1 +10781 6 10 8080 7494 10445 2 0 1 +10789 1 10787 1 +10789 2 2 10782 1 +10789 3 10787 2 0 1 +10789 4 2 7877 17 0 1 +10789 5 10787 12 0 0 0 1 +10789 6 2 8124 4627 10087 0 0 1 +10799 1 10780 1 +10799 2 19 10797 1 +10799 3 10780 2 0 1 +10799 4 19 9456 5 0 1 +10799 5 10780 2 0 0 0 1 +10799 6 19 8481 4614 8994 10 0 1 +10831 1 10824 1 +10831 2 7 10822 1 +10831 3 10824 5 0 1 +10831 4 7 10215 2 0 1 +10831 5 10824 10 0 0 0 1 +10831 6 7 6435 9453 10520 0 0 1 +10837 1 10835 1 +10837 2 2 10833 1 +10837 3 10835 6 0 1 +10837 4 2 10360 10 0 1 +10837 5 10835 7 0 0 0 1 +10837 6 2 10825 10819 10833 0 0 1 +10847 1 10842 1 +10847 2 5 10845 1 +10847 3 10842 5 0 1 +10847 4 5 6619 10 0 1 +10847 5 10842 7 0 0 0 1 +10847 6 5 5616 1870 8460 2 0 1 +10853 1 10851 1 +10853 2 2 10852 1 +10853 3 10851 2 0 1 +10853 4 2 10846 8 0 1 +10853 5 10851 3 0 0 0 1 +10853 6 2 4861 2671 8870 1 0 1 +10859 1 10857 1 +10859 2 2 10853 1 +10859 3 10857 2 0 1 +10859 4 2 6366 0 0 1 +10859 5 10857 5 0 0 0 1 +10859 6 2 1506 6878 10660 1 0 1 +10861 1 10859 1 +10861 2 2 10857 1 +10861 3 10859 2 0 1 +10861 4 2 10395 12 0 1 +10861 5 10859 9 0 0 0 1 +10861 6 2 7967 1894 9957 0 0 1 +10867 1 10865 1 +10867 2 2 10866 1 +10867 3 10865 2 0 1 +10867 4 2 10860 8 0 1 +10867 5 10865 6 0 0 0 1 +10867 6 2 7094 7525 5213 0 0 1 +10883 1 10881 1 +10883 2 2 10882 1 +10883 3 10881 3 0 1 +10883 4 2 8117 2 0 1 +10883 5 10881 2 0 0 0 1 +10883 6 2 6775 5586 8864 2 0 1 +10889 1 10886 1 +10889 2 3 10884 1 +10889 3 10886 1 0 1 +10889 4 3 6640 2 0 1 +10889 5 10886 7 0 0 0 1 +10889 6 3 7550 68 2058 2 0 1 +10891 1 10889 1 +10891 2 2 10890 1 +10891 3 10889 6 0 1 +10891 4 2 6688 2 0 1 +10891 5 10889 16 0 0 0 1 +10891 6 2 6672 8404 2556 0 0 1 +10903 1 10900 1 +10903 2 3 10902 1 +10903 3 10900 1 0 1 +10903 4 3 7497 5 0 1 +10903 5 10900 5 0 0 0 1 +10903 6 3 3939 7090 1946 0 0 1 +10909 1 10907 1 +10909 2 2 10908 1 +10909 3 10907 6 0 1 +10909 4 2 9660 3 0 1 +10909 5 10907 27 0 0 0 1 +10909 6 2 4559 6806 6471 0 0 1 +10937 1 10934 1 +10937 2 3 10931 1 +10937 3 10934 4 0 1 +10937 4 3 10641 1 0 1 +10937 5 10934 11 0 0 0 1 +10937 6 3 9042 5447 8395 1 0 1 +10939 1 10936 1 +10939 2 3 10934 1 +10939 3 10936 1 0 1 +10939 4 3 10791 3 0 1 +10939 5 10936 8 0 0 0 1 +10939 6 3 6782 6456 6392 0 0 1 +10949 1 10947 1 +10949 2 2 10945 1 +10949 3 10947 3 0 1 +10949 4 2 9086 12 0 1 +10949 5 10947 2 0 0 0 1 +10949 6 2 4707 4207 10455 1 0 1 +10957 1 10952 1 +10957 2 5 10956 1 +10957 3 10952 1 0 1 +10957 4 5 6612 7 0 1 +10957 5 10952 1 0 0 0 1 +10957 6 5 2344 954 10070 3 0 1 +10973 1 10971 1 +10973 2 2 10969 1 +10973 3 10971 3 0 1 +10973 4 2 7937 7 0 1 +10973 5 10971 4 0 0 0 1 +10973 6 2 1660 7027 5553 1 0 1 +10979 1 10977 1 +10979 2 2 10974 1 +10979 3 10977 4 0 1 +10979 4 2 10209 3 0 1 +10979 5 10977 8 0 0 0 1 +10979 6 2 1555 2504 2716 1 0 1 +10987 1 10985 1 +10987 2 2 10983 1 +10987 3 10985 6 0 1 +10987 4 2 8862 8 0 1 +10987 5 10985 5 0 0 0 1 +10987 6 2 10975 10969 10983 0 0 1 +10993 1 10986 1 +10993 2 7 10986 1 +10993 3 10986 10 0 1 +10993 4 7 9709 21 0 1 +10993 5 10986 1 0 0 0 1 +10993 6 7 4015 6869 8311 0 0 1 +11003 1 11001 1 +11003 2 2 11002 1 +11003 3 11001 4 0 1 +11003 4 2 10996 8 0 1 +11027 1 11025 1 +11027 2 2 11023 1 +11027 3 11025 3 0 1 +11027 4 2 10607 8 0 1 +11047 1 11044 1 +11047 2 3 11045 1 +11047 3 11044 4 0 1 +11047 4 3 9701 3 0 1 +11057 1 11054 1 +11057 2 3 11056 1 +11057 3 11054 1 0 1 +11057 4 3 10481 7 0 1 +11059 1 11049 1 +11059 2 10 11049 1 +11059 3 11049 8 0 1 +11059 4 10 5760 0 0 1 +11069 1 11067 1 +11069 2 2 11061 1 +11069 3 11067 12 0 1 +11069 4 2 6982 0 0 1 +11071 1 11068 1 +11071 2 3 11069 1 +11071 3 11068 6 0 1 +11071 4 3 7980 3 0 1 +11083 1 11081 1 +11083 2 2 11079 1 +11083 3 11081 6 0 1 +11083 4 2 10536 8 0 1 +11087 1 11082 1 +11087 2 5 11086 1 +11087 3 11082 5 0 1 +11087 4 5 10473 3 0 1 +11093 1 11091 1 +11093 2 2 11092 1 +11093 3 11091 2 0 1 +11093 4 2 7869 6 0 1 +11113 1 11100 1 +11113 2 13 11112 1 +11113 3 11100 4 0 1 +11113 4 13 7710 14 0 1 +11117 1 11114 1 +11117 2 3 11116 1 +11117 3 11114 1 0 1 +11117 4 3 7991 4 0 1 +11119 1 11116 1 +11119 2 3 11117 1 +11119 3 11116 1 0 1 +11119 4 3 10561 6 0 1 +11131 1 11129 1 +11131 2 2 11127 1 +11131 3 11129 4 0 1 +11131 4 2 9391 8 0 1 +11149 1 11139 1 +11149 2 10 11148 1 +11149 3 11139 2 0 1 +11149 4 10 5896 7 0 1 +11159 1 11152 1 +11159 2 7 11157 1 +11159 3 11152 11 0 1 +11159 4 7 10793 4 0 1 +11161 1 11154 1 +11161 2 7 11158 1 +11161 3 11154 1 0 1 +11161 4 7 9994 16 0 1 +11171 1 11169 1 +11171 2 2 11170 1 +11171 3 11169 3 0 1 +11171 4 2 7302 4 0 1 +11173 1 11168 1 +11173 2 5 11170 1 +11173 3 11168 1 0 1 +11173 4 5 9051 18 0 1 +11177 1 11174 1 +11177 2 3 11171 1 +11177 3 11174 4 0 1 +11177 4 3 6647 9 0 1 +11197 1 11195 1 +11197 2 2 11193 1 +11197 3 11195 6 0 1 +11197 4 2 6642 6 0 1 +11213 1 11211 1 +11213 2 2 11209 1 +11213 3 11211 2 0 1 +11213 4 2 9249 1 0 1 +11239 1 11236 1 +11239 2 3 11238 1 +11239 3 11236 1 0 1 +11239 4 3 6673 2 0 1 +11243 1 11238 1 +11243 2 5 11238 1 +11243 3 11238 7 0 1 +11243 4 5 5897 3 0 1 +11251 1 11238 1 +11251 2 13 11250 1 +11251 3 11238 2 0 1 +11251 4 13 5766 2 0 1 +11257 1 11247 1 +11257 2 10 11252 1 +11257 3 11247 4 0 1 +11257 4 10 9783 10 0 1 +11261 1 11259 1 +11261 2 2 11260 1 +11261 3 11259 3 0 1 +11261 4 2 10474 3 0 1 +11273 1 11270 1 +11273 2 3 11268 1 +11273 3 11270 3 0 1 +11273 4 3 9079 0 0 1 +11279 1 11272 1 +11279 2 7 11278 1 +11279 3 11272 7 0 1 +11279 4 7 7469 2 0 1 +11287 1 11284 1 +11287 2 3 11285 1 +11287 3 11284 1 0 1 +11287 4 3 6223 6 0 1 +11299 1 11296 1 +11299 2 3 11298 1 +11299 3 11296 1 0 1 +11299 4 3 6832 6 0 1 +11311 1 11308 1 +11311 2 3 11309 1 +11311 3 11308 1 0 1 +11311 4 3 11307 4 0 1 +11317 1 11315 1 +11317 2 2 11316 1 +11317 3 11315 2 0 1 +11317 4 2 11310 8 0 1 +11321 1 11318 1 +11321 2 3 11320 1 +11321 3 11318 5 0 1 +11321 4 3 5880 7 0 1 +11329 1 11322 1 +11329 2 7 11317 1 +11329 3 11322 3 0 1 +11329 4 7 8324 5 0 1 +11351 1 11344 1 +11351 2 7 11350 1 +11351 3 11344 11 0 1 +11351 4 7 8130 2 0 1 +11353 1 11346 1 +11353 2 7 11350 1 +11353 3 11346 3 0 1 +11353 4 7 11202 8 0 1 +11369 1 11366 1 +11369 2 3 11354 1 +11369 3 11366 3 0 1 +11369 4 3 10844 2 0 1 +11383 1 11378 1 +11383 2 5 11382 1 +11383 3 11378 2 0 1 +11383 4 5 9168 9 0 1 +11393 1 11390 1 +11393 2 3 11392 1 +11393 3 11390 3 0 1 +11393 4 3 7035 4 0 1 +11399 1 11388 1 +11399 2 11 11397 1 +11399 3 11388 1 0 1 +11399 4 11 9253 5 0 1 +11411 1 11404 1 +11411 2 7 11405 1 +11411 3 11404 4 0 1 +11411 4 7 11226 7 0 1 +11423 1 11418 1 +11423 2 5 11421 1 +11423 3 11418 2 0 1 +11423 4 5 11419 3 0 1 +11437 1 11435 1 +11437 2 2 11436 1 +11437 3 11435 2 0 1 +11437 4 2 7118 3 0 1 +11443 1 11441 1 +11443 2 2 11442 1 +11443 3 11441 2 0 1 +11443 4 2 8699 7 0 1 +11447 1 11442 1 +11447 2 5 11445 1 +11447 3 11442 1 0 1 +11447 4 5 7158 14 0 1 +11467 1 11462 1 +11467 2 5 11466 1 +11467 3 11462 2 0 1 +11467 4 5 9143 2 0 1 +11471 1 11460 1 +11471 2 11 11470 1 +11471 3 11460 1 0 1 +11471 4 11 6789 2 0 1 +11483 1 11481 1 +11483 2 2 11476 1 +11483 3 11481 2 0 1 +11483 4 2 7121 14 0 1 +11489 1 11486 1 +11489 2 3 11483 1 +11489 3 11486 5 0 1 +11489 4 3 11477 0 0 1 +11491 1 11488 1 +11491 2 3 11481 1 +11491 3 11488 3 0 1 +11491 4 3 8779 2 0 1 +11497 1 11490 1 +11497 2 7 11494 1 +11497 3 11490 7 0 1 +11497 4 7 9646 8 0 1 +11503 1 11500 1 +11503 2 3 11502 1 +11503 3 11500 4 0 1 +11503 4 3 7225 2 0 1 +11519 1 11512 1 +11519 2 7 11518 1 +11519 3 11512 3 0 1 +11519 4 7 7599 3 0 1 +11527 1 11522 1 +11527 2 5 11526 1 +11527 3 11522 5 0 1 +11527 4 5 8088 2 0 1 +11549 1 11547 1 +11549 2 2 11544 1 +11549 3 11547 3 0 1 +11549 4 2 11363 8 0 1 +11551 1 11544 1 +11551 2 7 11542 1 +11551 3 11544 4 0 1 +11551 4 7 6094 2 0 1 +11579 1 11577 1 +11579 2 2 11566 1 +11579 3 11577 2 0 1 +11579 4 2 8159 3 0 1 +11587 1 11585 1 +11587 2 2 11583 1 +11587 3 11585 6 0 1 +11587 4 2 10873 8 0 1 +11593 1 11588 1 +11593 2 5 11592 1 +11593 3 11588 2 0 1 +11593 4 5 9337 12 0 1 +11597 1 11594 1 +11597 2 3 11587 1 +11597 3 11594 4 0 1 +11597 4 3 9996 7 0 1 +11617 1 11607 1 +11617 2 10 11616 1 +11617 3 11607 4 0 1 +11617 4 10 6340 21 0 1 +11621 1 11619 1 +11621 2 2 11617 1 +11621 3 11619 3 0 1 +11621 4 2 10543 6 0 1 +11633 1 11630 1 +11633 2 3 11632 1 +11633 3 11630 4 0 1 +11633 4 3 8552 4 0 1 +11657 1 11654 1 +11657 2 3 11656 1 +11657 3 11654 6 0 1 +11657 4 3 6727 6 0 1 +11677 1 11675 1 +11677 2 2 11673 1 +11677 3 11675 4 0 1 +11677 4 2 10358 18 0 1 +11681 1 11678 1 +11681 2 3 11673 1 +11681 3 11678 1 0 1 +11681 4 3 8444 2 0 1 +11689 1 11682 1 +11689 2 7 11682 1 +11689 3 11682 2 0 1 +11689 4 7 7401 0 0 1 +11699 1 11697 1 +11699 2 2 11695 1 +11699 3 11697 4 0 1 +11699 4 2 5943 8 0 1 +11701 1 11695 1 +11701 2 6 11700 1 +11701 3 11695 2 0 1 +11701 4 6 6465 12 0 1 +11717 1 11715 1 +11717 2 2 11716 1 +11717 3 11715 7 0 1 +11717 4 2 9431 3 0 1 +11719 1 11713 1 +11719 2 6 11717 1 +11719 3 11713 2 0 1 +11719 4 6 10615 4 0 1 +11731 1 11728 1 +11731 2 3 11726 1 +11731 3 11728 6 0 1 +11731 4 3 7601 3 0 1 +11743 1 11740 1 +11743 2 3 11742 1 +11743 3 11740 3 0 1 +11743 4 3 11732 12 0 1 +11777 1 11774 1 +11777 2 3 11768 1 +11777 3 11774 1 0 1 +11777 4 3 8084 2 0 1 +11779 1 11777 1 +11779 2 2 11778 1 +11779 3 11777 5 0 1 +11779 4 2 11591 2 0 1 +11783 1 11778 1 +11783 2 5 11782 1 +11783 3 11778 7 0 1 +11783 4 5 10624 2 0 1 +11789 1 11787 1 +11789 2 2 11785 1 +11789 3 11787 2 0 1 +11789 4 2 9784 7 0 1 +11801 1 11798 1 +11801 2 3 11795 1 +11801 3 11798 4 0 1 +11801 4 3 11789 0 0 1 +11807 1 11802 1 +11807 2 5 11802 1 +11807 3 11802 2 0 1 +11807 4 5 11346 6 0 1 +11813 1 11811 1 +11813 2 2 11809 1 +11813 3 11811 5 0 1 +11813 4 2 6237 9 0 1 +11821 1 11819 1 +11821 2 2 11820 1 +11821 3 11819 6 0 1 +11821 4 2 7766 3 0 1 +11827 1 11825 1 +11827 2 2 11823 1 +11827 3 11825 4 0 1 +11827 4 2 8917 8 0 1 +11831 1 11824 1 +11831 2 7 11829 1 +11831 3 11824 1 0 1 +11831 4 7 11523 11 0 1 +11833 1 11828 1 +11833 2 5 11832 1 +11833 3 11828 3 0 1 +11833 4 5 9164 6 0 1 +11839 1 11836 1 +11839 2 3 11837 1 +11839 3 11836 3 0 1 +11839 4 3 9176 3 0 1 +11863 1 11860 1 +11863 2 3 11861 1 +11863 3 11860 4 0 1 +11863 4 3 11859 4 0 1 +11867 1 11865 1 +11867 2 2 11863 1 +11867 3 11865 3 0 1 +11867 4 2 7791 7 0 1 +11887 1 11884 1 +11887 2 3 11886 1 +11887 3 11884 1 0 1 +11887 4 3 10400 18 0 1 +11897 1 11894 1 +11897 2 3 11896 1 +11897 3 11894 1 0 1 +11897 4 3 8766 4 0 1 +11903 1 11898 1 +11903 2 5 11901 1 +11903 3 11898 2 0 1 +11903 4 5 11899 3 0 1 +11909 1 11907 1 +11909 2 2 11893 1 +11909 3 11907 5 0 1 +11909 4 2 7289 2 0 1 +11923 1 11918 1 +11923 2 5 11922 1 +11923 3 11918 1 0 1 +11923 4 5 6692 5 0 1 +11927 1 11922 1 +11927 2 5 11919 1 +11927 3 11922 3 0 1 +11927 4 5 7777 10 0 1 +11933 1 11931 1 +11933 2 2 11932 1 +11933 3 11931 2 0 1 +11933 4 2 7489 4 0 1 +11939 1 11937 1 +11939 2 2 11934 1 +11939 3 11937 9 0 1 +11939 4 2 11206 3 0 1 +11941 1 11931 1 +11941 2 10 11940 1 +11941 3 11931 3 0 1 +11941 4 10 6541 3 0 1 +11953 1 11948 1 +11953 2 5 11952 1 +11953 3 11948 3 0 1 +11953 4 5 8562 6 0 1 +11959 1 11956 1 +11959 2 3 11958 1 +11959 3 11956 4 0 1 +11959 4 3 6303 2 0 1 +11969 1 11966 1 +11969 2 3 11962 1 +11969 3 11966 10 0 1 +11969 4 3 8176 4 0 1 +11971 1 11961 1 +11971 2 10 11970 1 +11971 3 11961 2 0 1 +11971 4 10 8429 5 0 1 +11981 1 11979 1 +11981 2 2 11973 1 +11981 3 11979 2 0 1 +11981 4 2 7574 0 0 1 +11987 1 11985 1 +11987 2 2 11980 1 +11987 3 11985 2 0 1 +11987 4 2 10954 1 0 1 +12007 1 11994 1 +12007 2 13 12006 1 +12007 3 11994 5 0 1 +12007 4 13 10837 3 0 1 +12011 1 12009 1 +12011 2 2 12007 1 +12011 3 12009 3 0 1 +12011 4 2 9302 9 0 1 +12037 1 12032 1 +12037 2 5 12036 1 +12037 3 12032 1 0 1 +12037 4 5 7802 6 0 1 +12041 1 12038 1 +12041 2 3 12040 1 +12041 3 12038 6 0 1 +12041 4 3 8855 4 0 1 +12043 1 12041 1 +12043 2 2 12042 1 +12043 3 12041 2 0 1 +12043 4 2 9243 2 0 1 +12049 1 12036 1 +12049 2 13 12040 1 +12049 3 12036 4 0 1 +12049 4 13 8499 35 0 1 +12071 1 12060 1 +12071 2 11 12068 1 +12071 3 12060 4 0 1 +12071 4 11 10269 6 0 1 +12073 1 12066 1 +12073 2 7 12070 1 +12073 3 12066 2 0 1 +12073 4 7 8681 8 0 1 +12097 1 12092 1 +12097 2 5 12096 1 +12097 3 12092 3 0 1 +12097 4 5 6345 12 0 1 +12101 1 12098 1 +12101 2 3 12090 1 +12101 3 12098 4 0 1 +12101 4 3 9744 1 0 1 +12107 1 12105 1 +12107 2 2 12102 1 +12107 3 12105 4 0 1 +12107 4 2 11759 3 0 1 +12109 1 12103 1 +12109 2 6 12108 1 +12109 3 12103 8 0 1 +12109 4 6 8914 7 0 1 +12113 1 12110 1 +12113 2 3 12106 1 +12113 3 12110 4 0 1 +12113 4 3 6426 0 0 1 +12119 1 12112 1 +12119 2 7 12118 1 +12119 3 12112 1 0 1 +12119 4 7 8857 7 0 1 +12143 1 12133 1 +12143 2 10 12142 1 +12143 3 12133 10 0 1 +12143 4 10 10228 2 0 1 +12149 1 12147 1 +12149 2 2 12144 1 +12149 3 12147 5 0 1 +12149 4 2 10662 2 0 1 +12157 1 12155 1 +12157 2 2 12156 1 +12157 3 12155 2 0 1 +12157 4 2 9056 3 0 1 +12161 1 12158 1 +12161 2 3 12153 1 +12161 3 12158 3 0 1 +12161 4 3 6434 2 0 1 +12163 1 12158 1 +12163 2 5 12162 1 +12163 3 12158 2 0 1 +12163 4 5 8225 2 0 1 +12197 1 12195 1 +12197 2 2 12196 1 +12197 3 12195 11 0 1 +12197 4 2 7573 6 0 1 +12203 1 12201 1 +12203 2 2 12199 1 +12203 3 12201 3 0 1 +12203 4 2 6197 8 0 1 +12211 1 12209 1 +12211 2 2 12210 1 +12211 3 12209 5 0 1 +12211 4 2 7980 6 0 1 +12227 1 12225 1 +12227 2 2 12226 1 +12227 3 12225 2 0 1 +12227 4 2 6696 2 0 1 +12239 1 12226 1 +12239 2 13 12238 1 +12239 3 12226 3 0 1 +12239 4 13 11522 2 0 1 +12241 1 12234 1 +12241 2 7 12234 1 +12241 3 12234 5 0 1 +12241 4 7 7895 14 0 1 +12251 1 12249 1 +12251 2 2 12246 1 +12251 3 12249 2 0 1 +12251 4 2 6778 3 0 1 +12253 1 12251 1 +12253 2 2 12252 1 +12253 3 12251 2 0 1 +12253 4 2 7895 3 0 1 +12263 1 12258 1 +12263 2 5 12262 1 +12263 3 12258 1 0 1 +12263 4 5 8857 3 0 1 +12269 1 12267 1 +12269 2 2 12268 1 +12269 3 12267 5 0 1 +12269 4 2 6657 4 0 1 +12277 1 12275 1 +12277 2 2 12276 1 +12277 3 12275 2 0 1 +12277 4 2 6367 6 0 1 +12281 1 12278 1 +12281 2 3 12264 1 +12281 3 12278 1 0 1 +12281 4 3 9966 0 0 1 +12289 1 12278 1 +12289 2 11 12288 1 +12289 3 12278 1 0 1 +12289 4 11 10637 23 0 1 +12301 1 12299 1 +12301 2 2 12297 1 +12301 3 12299 5 0 1 +12301 4 2 11309 6 0 1 +12323 1 12321 1 +12323 2 2 12322 1 +12323 3 12321 3 0 1 +12323 4 2 7335 2 0 1 +12329 1 12326 1 +12329 2 3 12324 1 +12329 3 12326 6 0 1 +12329 4 3 8762 8 0 1 +12343 1 12336 1 +12343 2 7 12340 1 +12343 3 12336 3 0 1 +12343 4 7 11091 0 0 1 +12347 1 12345 1 +12347 2 2 12346 1 +12347 3 12345 2 0 1 +12347 4 2 10924 4 0 1 +12373 1 12371 1 +12373 2 2 12369 1 +12373 3 12371 4 0 1 +12373 4 2 11774 6 0 1 +12377 1 12371 1 +12377 2 6 12366 1 +12377 3 12371 3 0 1 +12377 4 6 9835 1 0 1 +12379 1 12377 1 +12379 2 2 12378 1 +12379 3 12377 5 0 1 +12379 4 2 12372 8 0 1 +12391 1 12365 1 +12391 2 26 12390 1 +12391 3 12365 1 0 1 +12391 4 26 10137 3 0 1 +12401 1 12398 1 +12401 2 3 12395 1 +12401 3 12398 6 0 1 +12401 4 3 12389 0 0 1 +12409 1 12402 1 +12409 2 7 12406 1 +12409 3 12402 4 0 1 +12409 4 7 9146 16 0 1 +12413 1 12411 1 +12413 2 2 12409 1 +12413 3 12411 8 0 1 +12413 4 2 6331 6 0 1 +12421 1 12414 1 +12421 2 7 12419 1 +12421 3 12414 5 0 1 +12421 4 7 11329 4 0 1 +12433 1 12420 1 +12433 2 13 12432 1 +12433 3 12420 3 0 1 +12433 4 13 7663 11 0 1 +12437 1 12435 1 +12437 2 2 12436 1 +12437 3 12435 3 0 1 +12437 4 2 10551 3 0 1 +12451 1 12448 1 +12451 2 3 12450 1 +12451 3 12448 1 0 1 +12451 4 3 11286 7 0 1 +12457 1 12447 1 +12457 2 10 12454 1 +12457 3 12447 2 0 1 +12457 4 10 10267 8 0 1 +12473 1 12470 1 +12473 2 3 12467 1 +12473 3 12470 3 0 1 +12473 4 3 10319 16 0 1 +12479 1 12456 1 +12479 2 23 12466 1 +12479 3 12456 3 0 1 +12479 4 23 8509 14 0 1 +12487 1 12484 1 +12487 2 3 12486 1 +12487 3 12484 10 0 1 +12487 4 3 6883 2 0 1 +12491 1 12489 1 +12491 2 2 12487 1 +12491 3 12489 3 0 1 +12491 4 2 10160 7 0 1 +12497 1 12494 1 +12497 2 3 12491 1 +12497 3 12494 4 0 1 +12497 4 3 8631 25 0 1 +12503 1 12498 1 +12503 2 5 12498 1 +12503 3 12498 2 0 1 +12503 4 5 10642 7 0 1 +12511 1 12508 1 +12511 2 3 12509 1 +12511 3 12508 5 0 1 +12511 4 3 8133 6 0 1 +12517 1 12511 1 +12517 2 6 12516 1 +12517 3 12511 1 0 1 +12517 4 6 10850 6 0 1 +12527 1 12522 1 +12527 2 5 12519 1 +12527 3 12522 5 0 1 +12527 4 5 10348 1 0 1 +12539 1 12537 1 +12539 2 2 12535 1 +12539 3 12537 3 0 1 +12539 4 2 8483 8 0 1 +12541 1 12527 1 +12541 2 14 12538 1 +12541 3 12527 2 0 1 +12541 4 14 12187 1 0 1 +12547 1 12545 1 +12547 2 2 12546 1 +12547 3 12545 2 0 1 +12547 4 2 11040 7 0 1 +12553 1 12548 1 +12553 2 5 12552 1 +12553 3 12548 5 0 1 +12553 4 5 9804 6 0 1 +12569 1 12566 1 +12569 2 3 12563 1 +12569 3 12566 3 0 1 +12569 4 3 12557 0 0 1 +12577 1 12567 1 +12577 2 10 12576 1 +12577 3 12567 4 0 1 +12577 4 10 10786 15 0 1 +12583 1 12578 1 +12583 2 5 12581 1 +12583 3 12578 1 0 1 +12583 4 5 7861 15 0 1 +12589 1 12587 1 +12589 2 2 12588 1 +12589 3 12587 4 0 1 +12589 4 2 12582 8 0 1 +12601 1 12590 1 +12601 2 11 12600 1 +12601 3 12590 3 0 1 +12601 4 11 8297 23 0 1 +12611 1 12609 1 +12611 2 2 12607 1 +12611 3 12609 2 0 1 +12611 4 2 8240 7 0 1 +12613 1 12611 1 +12613 2 2 12612 1 +12613 3 12611 6 0 1 +12613 4 2 6509 3 0 1 +12619 1 12617 1 +12619 2 2 12618 1 +12619 3 12617 5 0 1 +12619 4 2 9097 2 0 1 +12637 1 12635 1 +12637 2 2 12633 1 +12637 3 12635 4 0 1 +12637 4 2 9579 6 0 1 +12641 1 12638 1 +12641 2 3 12636 1 +12641 3 12638 3 0 1 +12641 4 3 11325 2 0 1 +12647 1 12642 1 +12647 2 5 12645 1 +12647 3 12642 1 0 1 +12647 4 5 10998 8 0 1 +12653 1 12651 1 +12653 2 2 12649 1 +12653 3 12651 3 0 1 +12653 4 2 7719 6 0 1 +12659 1 12657 1 +12659 2 2 12655 1 +12659 3 12657 3 0 1 +12659 4 2 9226 9 0 1 +12671 1 12657 1 +12671 2 14 12666 1 +12671 3 12657 6 0 1 +12671 4 14 8174 8 0 1 +12689 1 12686 1 +12689 2 3 12663 1 +12689 3 12686 1 0 1 +12689 4 3 10300 11 0 1 +12697 1 12690 1 +12697 2 7 12690 1 +12697 3 12690 11 0 1 +12697 4 7 7201 14 0 1 +12703 1 12700 1 +12703 2 3 12701 1 +12703 3 12700 4 0 1 +12703 4 3 12695 10 0 1 +12713 1 12710 1 +12713 2 3 12712 1 +12713 3 12710 5 0 1 +12713 4 3 11614 7 0 1 +12721 1 12708 1 +12721 2 13 12720 1 +12721 3 12708 5 0 1 +12721 4 13 11757 14 0 1 +12739 1 12737 1 +12739 2 2 12738 1 +12739 3 12737 6 0 1 +12739 4 2 7197 6 0 1 +12743 1 12738 1 +12743 2 5 12742 1 +12743 3 12738 3 0 1 +12743 4 5 9400 3 0 1 +12757 1 12755 1 +12757 2 2 12756 1 +12757 3 12755 2 0 1 +12757 4 2 10778 7 0 1 +12763 1 12761 1 +12763 2 2 12759 1 +12763 3 12761 4 0 1 +12763 4 2 12176 8 0 1 +12781 1 12779 1 +12781 2 2 12780 1 +12781 3 12779 4 0 1 +12781 4 2 7134 3 0 1 +12791 1 12784 1 +12791 2 7 12790 1 +12791 3 12784 13 0 1 +12791 4 7 12538 3 0 1 +12799 1 12786 1 +12799 2 13 12796 1 +12799 3 12786 7 0 1 +12799 4 13 9776 4 0 1 +12809 1 12806 1 +12809 2 3 12803 1 +12809 3 12806 8 0 1 +12809 4 3 12797 0 0 1 +12821 1 12819 1 +12821 2 2 12817 1 +12821 3 12819 7 0 1 +12821 4 2 8064 6 0 1 +12823 1 12820 1 +12823 2 3 12821 1 +12823 3 12820 5 0 1 +12823 4 3 12819 4 0 1 +12829 1 12827 1 +12829 2 2 12828 1 +12829 3 12827 6 0 1 +12829 4 2 12822 8 0 1 +12841 1 12820 1 +12841 2 21 12837 1 +12841 3 12820 1 0 1 +12841 4 21 12285 18 0 1 +12853 1 12848 1 +12853 2 5 12848 1 +12853 3 12848 1 0 1 +12853 4 5 10364 10 0 1 +12889 1 12876 1 +12889 2 13 12876 1 +12889 3 12876 1 0 1 +12889 4 13 12850 0 0 1 +12893 1 12890 1 +12893 2 3 12891 1 +12893 3 12890 1 0 1 +12893 4 3 12889 4 0 1 +12899 1 12897 1 +12899 2 2 12895 1 +12899 3 12897 3 0 1 +12899 4 2 11522 7 0 1 +12907 1 12905 1 +12907 2 2 12906 1 +12907 3 12905 2 0 1 +12907 4 2 10806 2 0 1 +12911 1 12888 1 +12911 2 23 12909 1 +12911 3 12888 3 0 1 +12911 4 23 11184 3 0 1 +12917 1 12915 1 +12917 2 2 12913 1 +12917 3 12915 3 0 1 +12917 4 2 10722 6 0 1 +12919 1 12913 1 +12919 2 6 12917 1 +12919 3 12913 3 0 1 +12919 4 6 12237 4 0 1 +12923 1 12921 1 +12923 2 2 12919 1 +12923 3 12921 5 0 1 +12923 4 2 9816 8 0 1 +12941 1 12939 1 +12941 2 2 12937 1 +12941 3 12939 3 0 1 +12941 4 2 6943 1 0 1 +12953 1 12950 1 +12953 2 3 12952 1 +12953 3 12950 3 0 1 +12953 4 3 6783 4 0 1 +12959 1 12952 1 +12959 2 7 12958 1 +12959 3 12952 1 0 1 +12959 4 7 12476 2 0 1 +12967 1 12964 1 +12967 2 3 12965 1 +12967 3 12964 8 0 1 +12967 4 3 12959 10 0 1 +12973 1 12959 1 +12973 2 14 12972 1 +12973 3 12959 1 0 1 +12973 4 14 8938 3 0 1 +12979 1 12977 1 +12979 2 2 12975 1 +12979 3 12977 2 0 1 +12979 4 2 12782 20 0 1 +12983 1 12978 1 +12983 2 5 12978 1 +12983 3 12978 8 0 1 +12983 4 5 8709 6 0 1 +13001 1 12998 1 +13001 2 3 12992 1 +13001 3 12998 1 0 1 +13001 4 3 8473 6 0 1 +13003 1 12998 1 +13003 2 5 13001 1 +13003 3 12998 9 0 1 +13003 4 5 12995 6 0 1 +13007 1 13002 1 +13007 2 5 13005 1 +13007 3 13002 2 0 1 +13007 4 5 13003 3 0 1 +13009 1 13002 1 +13009 2 7 13006 1 +13009 3 13002 2 0 1 +13009 4 7 11645 14 0 1 +13033 1 13028 1 +13033 2 5 13028 1 +13033 3 13028 5 0 1 +13033 4 5 8087 10 0 1 +13037 1 13035 1 +13037 2 2 13036 1 +13037 3 13035 2 0 1 +13037 4 2 10273 3 0 1 +13043 1 13041 1 +13043 2 2 13037 1 +13043 3 13041 4 0 1 +13043 4 2 10220 4 0 1 +13049 1 13046 1 +13049 2 3 13043 1 +13049 3 13046 6 0 1 +13049 4 3 13037 0 0 1 +13063 1 13058 1 +13063 2 5 13062 1 +13063 3 13058 1 0 1 +13063 4 5 6753 5 0 1 +13093 1 13087 1 +13093 2 6 13091 1 +13093 3 13087 2 0 1 +13093 4 6 12260 0 0 1 +13099 1 13096 1 +13099 2 3 13094 1 +13099 3 13096 1 0 1 +13099 4 3 9131 3 0 1 +13103 1 13098 1 +13103 2 5 13100 1 +13103 3 13098 2 0 1 +13103 4 5 12631 6 0 1 +13109 1 13107 1 +13109 2 2 13108 1 +13109 3 13107 4 0 1 +13109 4 2 10967 3 0 1 +13121 1 13114 1 +13121 2 7 13120 1 +13121 3 13114 1 0 1 +13121 4 7 13112 4 0 1 +13127 1 13122 1 +13127 2 5 13125 1 +13127 3 13122 6 0 1 +13127 4 5 11607 5 0 1 +13147 1 13145 1 +13147 2 2 13143 1 +13147 3 13145 5 0 1 +13147 4 2 10388 8 0 1 +13151 1 13138 1 +13151 2 13 13149 1 +13151 3 13138 2 0 1 +13151 4 13 8034 3 0 1 +13159 1 13156 1 +13159 2 3 13157 1 +13159 3 13156 1 0 1 +13159 4 3 7702 6 0 1 +13163 1 13161 1 +13163 2 2 13162 1 +13163 3 13161 2 0 1 +13163 4 2 10042 4 0 1 +13171 1 13160 1 +13171 2 11 13155 1 +13171 3 13160 3 0 1 +13171 4 11 9001 1 0 1 +13177 1 13172 1 +13177 2 5 13176 1 +13177 3 13172 1 0 1 +13177 4 5 12852 12 0 1 +13183 1 13180 1 +13183 2 3 13181 1 +13183 3 13180 3 0 1 +13183 4 3 9259 6 0 1 +13187 1 13185 1 +13187 2 2 13186 1 +13187 3 13185 2 0 1 +13187 4 2 11476 2 0 1 +13217 1 13214 1 +13217 2 3 13216 1 +13217 3 13214 6 0 1 +13217 4 3 8353 7 0 1 +13219 1 13216 1 +13219 2 3 13218 1 +13219 3 13216 1 0 1 +13219 4 3 9064 2 0 1 +13229 1 13227 1 +13229 2 2 13228 1 +13229 3 13227 3 0 1 +13229 4 2 12376 3 0 1 +13241 1 13238 1 +13241 2 3 13235 1 +13241 3 13238 3 0 1 +13241 4 3 13229 0 0 1 +13249 1 13242 1 +13249 2 7 13242 1 +13249 3 13242 2 0 1 +13249 4 7 9771 0 0 1 +13259 1 13253 1 +13259 2 6 13258 1 +13259 3 13253 2 0 1 +13259 4 6 7318 2 0 1 +13267 1 13264 1 +13267 2 3 13262 1 +13267 3 13264 4 0 1 +13267 4 3 12885 6 0 1 +13291 1 13289 1 +13291 2 2 13290 1 +13291 3 13289 4 0 1 +13291 4 2 9534 2 0 1 +13297 1 13292 1 +13297 2 5 13292 1 +13297 3 13292 1 0 1 +13297 4 5 10985 15 0 1 +13309 1 13303 1 +13309 2 6 13308 1 +13309 3 13303 9 0 1 +13309 4 6 10048 11 0 1 +13313 1 13310 1 +13313 2 3 13307 1 +13313 3 13310 5 0 1 +13313 4 3 10149 26 0 1 +13327 1 13324 1 +13327 2 3 13326 1 +13327 3 13324 1 0 1 +13327 4 3 12644 5 0 1 +13331 1 13329 1 +13331 2 2 13330 1 +13331 3 13329 3 0 1 +13331 4 2 13324 8 0 1 +13337 1 13334 1 +13337 2 3 13331 1 +13337 3 13334 6 0 1 +13337 4 3 11563 25 0 1 +13339 1 13337 1 +13339 2 2 13335 1 +13339 3 13337 4 0 1 +13339 4 2 11379 8 0 1 +13367 1 13362 1 +13367 2 5 13365 1 +13367 3 13362 7 0 1 +13367 4 5 10774 5 0 1 +13381 1 13371 1 +13381 2 10 13377 1 +13381 3 13371 4 0 1 +13381 4 10 13369 10 0 1 +13397 1 13395 1 +13397 2 2 13387 1 +13397 3 13395 2 0 1 +13397 4 2 8569 23 0 1 +13399 1 13396 1 +13399 2 3 13397 1 +13399 3 13396 9 0 1 +13399 4 3 13395 4 0 1 +13411 1 13409 1 +13411 2 2 13410 1 +13411 3 13409 6 0 1 +13411 4 2 12560 2 0 1 +13417 1 13412 1 +13417 2 5 13416 1 +13417 3 13412 7 0 1 +13417 4 5 9896 8 0 1 +13421 1 13411 1 +13421 2 10 13412 1 +13421 3 13411 6 0 1 +13421 4 10 11263 12 0 1 +13441 1 13430 1 +13441 2 11 13436 1 +13441 3 13430 2 0 1 +13441 4 11 13422 24 0 1 +13451 1 13449 1 +13451 2 2 13447 1 +13451 3 13449 3 0 1 +13451 4 2 13123 7 0 1 +13457 1 13454 1 +13457 2 3 13451 1 +13457 3 13454 5 0 1 +13457 4 3 13055 1 0 1 +13463 1 13458 1 +13463 2 5 13461 1 +13463 3 13458 2 0 1 +13463 4 5 7855 8 0 1 +13469 1 13467 1 +13469 2 2 13465 1 +13469 3 13467 2 0 1 +13469 4 2 12001 6 0 1 +13477 1 13475 1 +13477 2 2 13473 1 +13477 3 13475 6 0 1 +13477 4 2 8310 10 0 1 +13487 1 13482 1 +13487 2 5 13485 1 +13487 3 13482 9 0 1 +13487 4 5 13483 3 0 1 +13499 1 13493 1 +13499 2 6 13498 1 +13499 3 13493 1 0 1 +13499 4 6 11673 2 0 1 +13513 1 13508 1 +13513 2 5 13508 1 +13513 3 13508 1 0 1 +13513 4 5 12909 12 0 1 +13523 1 13521 1 +13523 2 2 13522 1 +13523 3 13521 3 0 1 +13523 4 2 10269 2 0 1 +13537 1 13530 1 +13537 2 7 13530 1 +13537 3 13530 7 0 1 +13537 4 7 13336 17 0 1 +13553 1 13550 1 +13553 2 3 13548 1 +13553 3 13550 4 0 1 +13553 4 3 9255 0 0 1 +13567 1 13564 1 +13567 2 3 13565 1 +13567 3 13564 17 0 1 +13567 4 3 10098 6 0 1 +13577 1 13574 1 +13577 2 3 13572 1 +13577 3 13574 9 0 1 +13577 4 3 11270 0 0 1 +13591 1 13588 1 +13591 2 3 13590 1 +13591 3 13588 4 0 1 +13591 4 3 7954 2 0 1 +13597 1 13592 1 +13597 2 5 13592 1 +13597 3 13592 2 0 1 +13597 4 5 8962 12 0 1 +13613 1 13611 1 +13613 2 2 13612 1 +13613 3 13611 2 0 1 +13613 4 2 9342 4 0 1 +13619 1 13617 1 +13619 2 2 13612 1 +13619 3 13617 7 0 1 +13619 4 2 12678 1 0 1 +13627 1 13625 1 +13627 2 2 13626 1 +13627 3 13625 6 0 1 +13627 4 2 13620 8 0 1 +13633 1 13628 1 +13633 2 5 13632 1 +13633 3 13628 10 0 1 +13633 4 5 8948 6 0 1 +13649 1 13646 1 +13649 2 3 13643 1 +13649 3 13646 5 0 1 +13649 4 3 13637 0 0 1 +13669 1 13663 1 +13669 2 6 13668 1 +13669 3 13663 2 0 1 +13669 4 6 8034 7 0 1 +13679 1 13672 1 +13679 2 7 13677 1 +13679 3 13672 1 0 1 +13679 4 7 12320 11 0 1 +13681 1 13659 1 +13681 2 22 13679 1 +13681 3 13659 5 0 1 +13681 4 22 12837 13 0 1 +13687 1 13684 1 +13687 2 3 13685 1 +13687 3 13684 5 0 1 +13687 4 3 13219 6 0 1 +13691 1 13689 1 +13691 2 2 13684 1 +13691 3 13689 4 0 1 +13691 4 2 7555 1 0 1 +13693 1 13687 1 +13693 2 6 13691 1 +13693 3 13687 3 0 1 +13693 4 6 12123 10 0 1 +13697 1 13694 1 +13697 2 3 13692 1 +13697 3 13694 3 0 1 +13697 4 3 12739 0 0 1 +13709 1 13707 1 +13709 2 2 13705 1 +13709 3 13707 3 0 1 +13709 4 2 10841 1 0 1 +13711 1 13705 1 +13711 2 6 13709 1 +13711 3 13705 3 0 1 +13711 4 6 10891 3 0 1 +13721 1 13718 1 +13721 2 3 13716 1 +13721 3 13718 1 0 1 +13721 4 3 13459 2 0 1 +13723 1 13721 1 +13723 2 2 13722 1 +13723 3 13721 2 0 1 +13723 4 2 13716 8 0 1 +13729 1 13706 1 +13729 2 23 13724 1 +13729 3 13706 7 0 1 +13729 4 23 9923 28 0 1 +13751 1 13740 1 +13751 2 11 13750 1 +13751 3 13740 1 0 1 +13751 4 11 12072 3 0 1 +13757 1 13755 1 +13757 2 2 13753 1 +13757 3 13755 3 0 1 +13757 4 2 12979 7 0 1 +13759 1 13753 1 +13759 2 6 13758 1 +13759 3 13753 2 0 1 +13759 4 6 11518 3 0 1 +13763 1 13761 1 +13763 2 2 13758 1 +13763 3 13761 4 0 1 +13763 4 2 8176 0 0 1 +13781 1 13774 1 +13781 2 7 13780 1 +13781 3 13774 1 0 1 +13781 4 7 12092 3 0 1 +13789 1 13782 1 +13789 2 7 13787 1 +13789 3 13782 3 0 1 +13789 4 7 12012 4 0 1 +13799 1 13792 1 +13799 2 7 13798 1 +13799 3 13792 1 0 1 +13799 4 7 13200 2 0 1 +13807 1 13802 1 +13807 2 5 13806 1 +13807 3 13802 7 0 1 +13807 4 5 7160 12 0 1 +13829 1 13827 1 +13829 2 2 13822 1 +13829 3 13827 4 0 1 +13829 4 2 13104 4 0 1 +13831 1 13825 1 +13831 2 6 13829 1 +13831 3 13825 3 0 1 +13831 4 6 7411 3 0 1 +13841 1 13835 1 +13841 2 6 13835 1 +13841 3 13835 4 0 1 +13841 4 6 9725 0 0 1 +13859 1 13857 1 +13859 2 2 13849 1 +13859 3 13857 3 0 1 +13859 4 2 8838 0 0 1 +13873 1 13868 1 +13873 2 5 13872 1 +13873 3 13868 5 0 1 +13873 4 5 12572 6 0 1 +13877 1 13875 1 +13877 2 2 13873 1 +13877 3 13875 3 0 1 +13877 4 2 12699 6 0 1 +13879 1 13873 1 +13879 2 6 13878 1 +13879 3 13873 1 0 1 +13879 4 6 7827 2 0 1 +13883 1 13881 1 +13883 2 2 13878 1 +13883 3 13881 3 0 1 +13883 4 2 8704 0 0 1 +13901 1 13899 1 +13901 2 2 13900 1 +13901 3 13899 3 0 1 +13901 4 2 10722 3 0 1 +13903 1 13900 1 +13903 2 3 13902 1 +13903 3 13900 5 0 1 +13903 4 3 9020 5 0 1 +13907 1 13905 1 +13907 2 2 13906 1 +13907 3 13905 2 0 1 +13907 4 2 12303 4 0 1 +13913 1 13910 1 +13913 2 3 13907 1 +13913 3 13910 1 0 1 +13913 4 3 9536 9 0 1 +13921 1 13914 1 +13921 2 7 13918 1 +13921 3 13914 2 0 1 +13921 4 7 10679 14 0 1 +13931 1 13929 1 +13931 2 2 13927 1 +13931 3 13929 3 0 1 +13931 4 2 12622 8 0 1 +13933 1 13931 1 +13933 2 2 13932 1 +13933 3 13931 2 0 1 +13933 4 2 12695 3 0 1 +13963 1 13960 1 +13963 2 3 13956 1 +13963 3 13960 1 0 1 +13963 4 3 9166 2 0 1 +13967 1 13962 1 +13967 2 5 13964 1 +13967 3 13962 1 0 1 +13967 4 5 13388 6 0 1 +13997 1 13995 1 +13997 2 2 13993 1 +13997 3 13995 3 0 1 +13997 4 2 9119 6 0 1 +13999 1 13996 1 +13999 2 3 13998 1 +13999 3 13996 5 0 1 +13999 4 3 13497 3 0 1 +14009 1 14006 1 +14009 2 3 14002 1 +14009 3 14006 6 0 1 +14009 4 3 7563 1 0 1 +14011 1 14009 1 +14011 2 2 14007 1 +14011 3 14009 4 0 1 +14011 4 2 13601 8 0 1 +14029 1 14023 1 +14029 2 6 14028 1 +14029 3 14023 1 0 1 +14029 4 6 10970 7 0 1 +14033 1 14030 1 +14033 2 3 14032 1 +14033 3 14030 3 0 1 +14033 4 3 13187 4 0 1 +14051 1 14049 1 +14051 2 2 14047 1 +14051 3 14049 2 0 1 +14051 4 2 7128 8 0 1 +14057 1 14054 1 +14057 2 3 14051 1 +14057 3 14054 1 0 1 +14057 4 3 11112 12 0 1 +14071 1 14064 1 +14071 2 7 14062 1 +14071 3 14064 2 0 1 +14071 4 7 13232 2 0 1 +14081 1 14078 1 +14081 2 3 14076 1 +14081 3 14078 1 0 1 +14081 4 3 9476 2 0 1 +14083 1 14080 1 +14083 2 3 14076 1 +14083 3 14080 1 0 1 +14083 4 3 8351 2 0 1 +14087 1 14082 1 +14087 2 5 14085 1 +14087 3 14082 5 0 1 +14087 4 5 10003 5 0 1 +14107 1 14105 1 +14107 2 2 14103 1 +14107 3 14105 6 0 1 +14107 4 2 8711 8 0 1 +14143 1 14140 1 +14143 2 3 14142 1 +14143 3 14140 1 0 1 +14143 4 3 8452 2 0 1 +14149 1 14143 1 +14149 2 6 14145 1 +14149 3 14143 1 0 1 +14149 4 6 12231 2 0 1 +14153 1 14150 1 +14153 2 3 14152 1 +14153 3 14150 4 0 1 +14153 4 3 9492 7 0 1 +14159 1 14146 1 +14159 2 13 14142 1 +14159 3 14146 2 0 1 +14159 4 13 7929 4 0 1 +14173 1 14171 1 +14173 2 2 14172 1 +14173 3 14171 2 0 1 +14173 4 2 7332 6 0 1 +14177 1 14174 1 +14177 2 3 14172 1 +14177 3 14174 1 0 1 +14177 4 3 13112 0 0 1 +14197 1 14186 1 +14197 2 11 14196 1 +14197 3 14186 1 0 1 +14197 4 11 13990 7 0 1 +14207 1 14202 1 +14207 2 5 14206 1 +14207 3 14202 3 0 1 +14207 4 5 10123 3 0 1 +14221 1 14219 1 +14221 2 2 14217 1 +14221 3 14219 2 0 1 +14221 4 2 10322 10 0 1 +14243 1 14241 1 +14243 2 2 14239 1 +14243 3 14241 2 0 1 +14243 4 2 11177 7 0 1 +14249 1 14246 1 +14249 2 3 14240 1 +14249 3 14246 5 0 1 +14249 4 3 8020 3 0 1 +14251 1 14248 1 +14251 2 3 14244 1 +14251 3 14248 1 0 1 +14251 4 3 7517 5 0 1 +14281 1 14262 1 +14281 2 19 14268 1 +14281 3 14262 4 0 1 +14281 4 19 12888 32 0 1 +14293 1 14287 1 +14293 2 6 14292 1 +14293 3 14287 1 0 1 +14293 4 6 9296 7 0 1 +14303 1 14298 1 +14303 2 5 14302 1 +14303 3 14298 1 0 1 +14303 4 5 13408 4 0 1 +14321 1 14318 1 +14321 2 3 14320 1 +14321 3 14318 1 0 1 +14321 4 3 12410 7 0 1 +14323 1 14318 1 +14323 2 5 14321 1 +14323 3 14318 1 0 1 +14323 4 5 14315 6 0 1 +14327 1 14322 1 +14327 2 5 14319 1 +14327 3 14322 1 0 1 +14327 4 5 13083 3 0 1 +14341 1 14339 1 +14341 2 2 14340 1 +14341 3 14339 4 0 1 +14341 4 2 13520 3 0 1 +14347 1 14344 1 +14347 2 3 14342 1 +14347 3 14344 7 0 1 +14347 4 3 12043 3 0 1 +14369 1 14366 1 +14369 2 3 14363 1 +14369 3 14366 1 0 1 +14369 4 3 14357 0 0 1 +14387 1 14385 1 +14387 2 2 14383 1 +14387 3 14385 3 0 1 +14387 4 2 11871 7 0 1 +14389 1 14387 1 +14389 2 2 14384 1 +14389 3 14387 2 0 1 +14389 4 2 12161 18 0 1 +14401 1 14390 1 +14401 2 11 14400 1 +14401 3 14390 2 0 1 +14401 4 11 9977 20 0 1 +14407 1 14388 1 +14407 2 19 14405 1 +14407 3 14388 1 0 1 +14407 4 19 13007 11 0 1 +14411 1 14409 1 +14411 2 2 14406 1 +14411 3 14409 4 0 1 +14411 4 2 9697 3 0 1 +14419 1 14417 1 +14419 2 2 14418 1 +14419 3 14417 4 0 1 +14419 4 2 8774 6 0 1 +14423 1 14418 1 +14423 2 5 14422 1 +14423 3 14418 1 0 1 +14423 4 5 9831 3 0 1 +14431 1 14428 1 +14431 2 3 14430 1 +14431 3 14428 3 0 1 +14431 4 3 11655 3 0 1 +14437 1 14432 1 +14437 2 5 14432 1 +14437 3 14432 3 0 1 +14437 4 5 9262 7 0 1 +14447 1 14442 1 +14447 2 5 14442 1 +14447 3 14442 6 0 1 +14447 4 5 9069 7 0 1 +14449 1 14427 1 +14449 2 22 14443 1 +14449 3 14427 1 0 1 +14449 4 22 13340 39 0 1 +14461 1 14459 1 +14461 2 2 14460 1 +14461 3 14459 4 0 1 +14461 4 2 7365 3 0 1 +14479 1 14476 1 +14479 2 3 14477 1 +14479 3 14476 1 0 1 +14479 4 3 14475 4 0 1 +14489 1 14486 1 +14489 2 3 14484 1 +14489 3 14486 3 0 1 +14489 4 3 11364 2 0 1 +14503 1 14500 1 +14503 2 3 14501 1 +14503 3 14500 15 0 1 +14503 4 3 14495 10 0 1 +14519 1 14506 1 +14519 2 13 14516 1 +14519 3 14506 1 0 1 +14519 4 13 10077 4 0 1 +14533 1 14531 1 +14533 2 2 14526 1 +14533 3 14531 4 0 1 +14533 4 2 12880 2 0 1 +14537 1 14534 1 +14537 2 3 14536 1 +14537 3 14534 5 0 1 +14537 4 3 11076 4 0 1 +14543 1 14538 1 +14543 2 5 14542 1 +14543 3 14538 2 0 1 +14543 4 5 8060 2 0 1 +14549 1 14547 1 +14549 2 2 14536 1 +14549 3 14547 4 0 1 +14549 4 2 13678 0 0 1 +14551 1 14548 1 +14551 2 3 14549 1 +14551 3 14548 1 0 1 +14551 4 3 13724 6 0 1 +14557 1 14555 1 +14557 2 2 14553 1 +14557 3 14555 4 0 1 +14557 4 2 14122 6 0 1 +14561 1 14555 1 +14561 2 6 14558 1 +14561 3 14555 2 0 1 +14561 4 6 13475 0 0 1 +14563 1 14560 1 +14563 2 3 14562 1 +14563 3 14560 1 0 1 +14563 4 3 10162 2 0 1 +14591 1 14580 1 +14591 2 11 14588 1 +14591 3 14580 2 0 1 +14591 4 11 14295 5 0 1 +14593 1 14588 1 +14593 2 5 14590 1 +14593 3 14588 7 0 1 +14593 4 5 14582 14 0 1 +14621 1 14619 1 +14621 2 2 14615 1 +14621 3 14619 7 0 1 +14621 4 2 11075 4 0 1 +14627 1 14625 1 +14627 2 2 14623 1 +14627 3 14625 3 0 1 +14627 4 2 7514 7 0 1 +14629 1 14627 1 +14629 2 2 14623 1 +14629 3 14627 5 0 1 +14629 4 2 8495 0 0 1 +14633 1 14630 1 +14633 2 3 14627 1 +14633 3 14630 1 0 1 +14633 4 3 9488 9 0 1 +14639 1 14628 1 +14639 2 11 14633 1 +14639 3 14628 1 0 1 +14639 4 11 14397 7 0 1 +14653 1 14651 1 +14653 2 2 14649 1 +14653 3 14651 7 0 1 +14653 4 2 9191 12 0 1 +14657 1 14654 1 +14657 2 3 14652 1 +14657 3 14654 3 0 1 +14657 4 3 12260 0 0 1 +14669 1 14667 1 +14669 2 2 14657 1 +14669 3 14667 2 0 1 +14669 4 2 11437 1 0 1 +14683 1 14680 1 +14683 2 3 14678 1 +14683 3 14680 5 0 1 +14683 4 3 14412 3 0 1 +14699 1 14697 1 +14699 2 2 14698 1 +14699 3 14697 3 0 1 +14699 4 2 11988 4 0 1 +14713 1 14708 1 +14713 2 5 14710 1 +14713 3 14708 5 0 1 +14713 4 5 14702 14 0 1 +14717 1 14715 1 +14717 2 2 14713 1 +14717 3 14715 2 0 1 +14717 4 2 9721 6 0 1 +14723 1 14721 1 +14723 2 2 14719 1 +14723 3 14721 3 0 1 +14723 4 2 13815 7 0 1 +14731 1 14721 1 +14731 2 10 14730 1 +14731 3 14721 3 0 1 +14731 4 10 13058 2 0 1 +14737 1 14727 1 +14737 2 10 14736 1 +14737 3 14727 7 0 1 +14737 4 10 10198 6 0 1 +14741 1 14739 1 +14741 2 2 14740 1 +14741 3 14739 3 0 1 +14741 4 2 11603 9 0 1 +14747 1 14745 1 +14747 2 2 14740 1 +14747 3 14745 2 0 1 +14747 4 2 10091 1 0 1 +14753 1 14750 1 +14753 2 3 14752 1 +14753 3 14750 3 0 1 +14753 4 3 14315 6 0 1 +14759 1 14742 1 +14759 2 17 14757 1 +14759 3 14742 5 0 1 +14759 4 17 14751 3 0 1 +14767 1 14764 1 +14767 2 3 14765 1 +14767 3 14764 8 0 1 +14767 4 3 11676 6 0 1 +14771 1 14769 1 +14771 2 2 14765 1 +14771 3 14769 2 0 1 +14771 4 2 14427 0 0 1 +14779 1 14776 1 +14779 2 3 14778 1 +14779 3 14776 8 0 1 +14779 4 3 9676 2 0 1 +14783 1 14778 1 +14783 2 5 14774 1 +14783 3 14778 5 0 1 +14783 4 5 12067 10 0 1 +14797 1 14795 1 +14797 2 2 14796 1 +14797 3 14795 6 0 1 +14797 4 2 11646 3 0 1 +14813 1 14811 1 +14813 2 2 14809 1 +14813 3 14811 3 0 1 +14813 4 2 13288 6 0 1 +14821 1 14819 1 +14821 2 2 14817 1 +14821 3 14819 4 0 1 +14821 4 2 10680 6 0 1 +14827 1 14825 1 +14827 2 2 14823 1 +14827 3 14825 6 0 1 +14827 4 2 8938 8 0 1 +14831 1 14820 1 +14831 2 11 14830 1 +14831 3 14820 1 0 1 +14831 4 11 14142 4 0 1 +14843 1 14841 1 +14843 2 2 14839 1 +14843 3 14841 3 0 1 +14843 4 2 14210 13 0 1 +14851 1 14849 1 +14851 2 2 14847 1 +14851 3 14849 5 0 1 +14851 4 2 14640 8 0 1 +14867 1 14865 1 +14867 2 2 14866 1 +14867 3 14865 2 0 1 +14867 4 2 11809 4 0 1 +14869 1 14867 1 +14869 2 2 14865 1 +14869 3 14867 2 0 1 +14869 4 2 12464 6 0 1 +14879 1 14872 1 +14879 2 7 14878 1 +14879 3 14872 2 0 1 +14879 4 7 7908 2 0 1 +14887 1 14884 1 +14887 2 3 14885 1 +14887 3 14884 1 0 1 +14887 4 3 13556 3 0 1 +14891 1 14889 1 +14891 2 2 14887 1 +14891 3 14889 2 0 1 +14891 4 2 9122 7 0 1 +14897 1 14894 1 +14897 2 3 14891 1 +14897 3 14894 1 0 1 +14897 4 3 11419 1 0 1 +14923 1 14921 1 +14923 2 2 14922 1 +14923 3 14921 5 0 1 +14923 4 2 9081 10 0 1 +14929 1 14922 1 +14929 2 7 14926 1 +14929 3 14922 1 0 1 +14929 4 7 9447 16 0 1 +14939 1 14937 1 +14939 2 2 14935 1 +14939 3 14937 3 0 1 +14939 4 2 12854 7 0 1 +14947 1 14945 1 +14947 2 2 14943 1 +14947 3 14945 6 0 1 +14947 4 2 12696 8 0 1 +14951 1 14932 1 +14951 2 19 14950 1 +14951 3 14932 1 0 1 +14951 4 19 9679 2 0 1 +14957 1 14955 1 +14957 2 2 14956 1 +14957 3 14955 2 0 1 +14957 4 2 14950 8 0 1 +14969 1 14966 1 +14969 2 3 14964 1 +14969 3 14966 3 0 1 +14969 4 3 13196 2 0 1 +14983 1 14980 1 +14983 2 3 14981 1 +14983 3 14980 6 0 1 +14983 4 3 14979 4 0 1 +15013 1 15011 1 +15013 2 2 15012 1 +15013 3 15011 2 0 1 +15013 4 2 11191 6 0 1 +15017 1 15014 1 +15017 2 3 15016 1 +15017 3 15014 4 0 1 +15017 4 3 11978 7 0 1 +15031 1 15028 1 +15031 2 3 15029 1 +15031 3 15028 3 0 1 +15031 4 3 8554 3 0 1 +15053 1 15051 1 +15053 2 2 15047 1 +15053 3 15051 8 0 1 +15053 4 2 14277 4 0 1 +15061 1 15059 1 +15061 2 2 15057 1 +15061 3 15059 5 0 1 +15061 4 2 9468 10 0 1 +15073 1 15068 1 +15073 2 5 15068 1 +15073 3 15068 3 0 1 +15073 4 5 13101 15 0 1 +15077 1 15075 1 +15077 2 2 15076 1 +15077 3 15075 3 0 1 +15077 4 2 10509 9 0 1 +15083 1 15081 1 +15083 2 2 15075 1 +15083 3 15081 2 0 1 +15083 4 2 7810 0 0 1 +15091 1 15089 1 +15091 2 2 15087 1 +15091 3 15089 6 0 1 +15091 4 2 7652 1 0 1 +15101 1 15099 1 +15101 2 2 15093 1 +15101 3 15099 7 0 1 +15101 4 2 14609 0 0 1 +15107 1 15105 1 +15107 2 2 15101 1 +15107 3 15105 8 0 1 +15107 4 2 12520 0 0 1 +15121 1 15110 1 +15121 2 11 15120 1 +15121 3 15110 3 0 1 +15121 4 11 11091 23 0 1 +15131 1 15129 1 +15131 2 2 15127 1 +15131 3 15129 3 0 1 +15131 4 2 14639 8 0 1 +15137 1 15134 1 +15137 2 3 15132 1 +15137 3 15134 1 0 1 +15137 4 3 12044 0 0 1 +15139 1 15137 1 +15139 2 2 15138 1 +15139 3 15137 4 0 1 +15139 4 2 10952 2 0 1 +15149 1 15147 1 +15149 2 2 15145 1 +15149 3 15147 2 0 1 +15149 4 2 13568 7 0 1 +15161 1 15158 1 +15161 2 3 15155 1 +15161 3 15158 7 0 1 +15161 4 3 15149 0 0 1 +15173 1 15171 1 +15173 2 2 15169 1 +15173 3 15171 3 0 1 +15173 4 2 9189 7 0 1 +15187 1 15185 1 +15187 2 2 15183 1 +15187 3 15185 4 0 1 +15187 4 2 12918 8 0 1 +15193 1 15188 1 +15193 2 5 15192 1 +15193 3 15188 8 0 1 +15193 4 5 9152 6 0 1 +15199 1 15193 1 +15199 2 6 15197 1 +15199 3 15193 6 0 1 +15199 4 6 14595 4 0 1 +15217 1 15207 1 +15217 2 10 15216 1 +15217 3 15207 2 0 1 +15217 4 10 8075 21 0 1 +15227 1 15225 1 +15227 2 2 15223 1 +15227 3 15225 3 0 1 +15227 4 2 13122 8 0 1 +15233 1 15230 1 +15233 2 3 15227 1 +15233 3 15230 5 0 1 +15233 4 3 14724 1 0 1 +15241 1 15230 1 +15241 2 11 15240 1 +15241 3 15230 2 0 1 +15241 4 11 12892 14 0 1 +15259 1 15257 1 +15259 2 2 15258 1 +15259 3 15257 5 0 1 +15259 4 2 9510 2 0 1 +15263 1 15258 1 +15263 2 5 15261 1 +15263 3 15258 6 0 1 +15263 4 5 9395 8 0 1 +15269 1 15267 1 +15269 2 2 15262 1 +15269 3 15267 5 0 1 +15269 4 2 14071 9 0 1 +15271 1 15260 1 +15271 2 11 15269 1 +15271 3 15260 5 0 1 +15271 4 11 10687 6 0 1 +15277 1 15271 1 +15277 2 6 15276 1 +15277 3 15271 1 0 1 +15277 4 6 10990 7 0 1 +15287 1 15282 1 +15287 2 5 15285 1 +15287 3 15282 1 0 1 +15287 4 5 10761 8 0 1 +15289 1 15278 1 +15289 2 11 15284 1 +15289 3 15278 1 0 1 +15289 4 11 13890 16 0 1 +15299 1 15297 1 +15299 2 2 15295 1 +15299 3 15297 3 0 1 +15299 4 2 12536 8 0 1 +15307 1 15304 1 +15307 2 3 15306 1 +15307 3 15304 1 0 1 +15307 4 3 14957 5 0 1 +15313 1 15308 1 +15313 2 5 15312 1 +15313 3 15308 3 0 1 +15313 4 5 15294 20 0 1 +15319 1 15316 1 +15319 2 3 15313 1 +15319 3 15316 11 0 1 +15319 4 3 13897 7 0 1 +15329 1 15326 1 +15329 2 3 15328 1 +15329 3 15326 1 0 1 +15329 4 3 9817 7 0 1 +15331 1 15329 1 +15331 2 2 15327 1 +15331 3 15329 2 0 1 +15331 4 2 8141 8 0 1 +15349 1 15347 1 +15349 2 2 15348 1 +15349 3 15347 6 0 1 +15349 4 2 10522 22 0 1 +15359 1 15348 1 +15359 2 11 15357 1 +15359 3 15348 1 0 1 +15359 4 11 11082 6 0 1 +15361 1 15354 1 +15361 2 7 15354 1 +15361 3 15354 2 0 1 +15361 4 7 8585 0 0 1 +15373 1 15371 1 +15373 2 2 15369 1 +15373 3 15371 5 0 1 +15373 4 2 11244 6 0 1 +15377 1 15374 1 +15377 2 3 15372 1 +15377 3 15374 8 0 1 +15377 4 3 13302 0 0 1 +15383 1 15378 1 +15383 2 5 15382 1 +15383 3 15378 2 0 1 +15383 4 5 7799 2 0 1 +15391 1 15379 1 +15391 2 12 15390 1 +15391 3 15379 6 0 1 +15391 4 12 8544 10 0 1 +15401 1 15395 1 +15401 2 6 15398 1 +15401 3 15395 11 0 1 +15401 4 6 13736 6 0 1 +15413 1 15411 1 +15413 2 2 15412 1 +15413 3 15411 2 0 1 +15413 4 2 9182 3 0 1 +15427 1 15425 1 +15427 2 2 15426 1 +15427 3 15425 5 0 1 +15427 4 2 12801 2 0 1 +15439 1 15436 1 +15439 2 3 15438 1 +15439 3 15436 8 0 1 +15439 4 3 8299 3 0 1 +15443 1 15441 1 +15443 2 2 15438 1 +15443 3 15441 3 0 1 +15443 4 2 13921 3 0 1 +15451 1 15448 1 +15451 2 3 15450 1 +15451 3 15448 4 0 1 +15451 4 3 8718 6 0 1 +15461 1 15459 1 +15461 2 2 15460 1 +15461 3 15459 3 0 1 +15461 4 2 15132 3 0 1 +15467 1 15462 1 +15467 2 5 15462 1 +15467 3 15462 5 0 1 +15467 4 5 13985 3 0 1 +15473 1 15470 1 +15473 2 3 15472 1 +15473 3 15470 1 0 1 +15473 4 3 9553 6 0 1 +15493 1 15488 1 +15493 2 5 15492 1 +15493 3 15488 1 0 1 +15493 4 5 13989 3 0 1 +15497 1 15494 1 +15497 2 3 15491 1 +15497 3 15494 11 0 1 +15497 4 3 15145 9 0 1 +15511 1 15508 1 +15511 2 3 15509 1 +15511 3 15508 10 0 1 +15511 4 3 15507 4 0 1 +15527 1 15522 1 +15527 2 5 15524 1 +15527 3 15522 3 0 1 +15527 4 5 12618 9 0 1 +15541 1 15535 1 +15541 2 6 15537 1 +15541 3 15535 1 0 1 +15541 4 6 13485 2 0 1 +15551 1 15544 1 +15551 2 7 15550 1 +15551 3 15544 5 0 1 +15551 4 7 8500 3 0 1 +15559 1 15556 1 +15559 2 3 15557 1 +15559 3 15556 6 0 1 +15559 4 3 12175 6 0 1 +15569 1 15566 1 +15569 2 3 15564 1 +15569 3 15566 1 0 1 +15569 4 3 9214 2 0 1 +15581 1 15579 1 +15581 2 2 15580 1 +15581 3 15579 3 0 1 +15581 4 2 15574 8 0 1 +15583 1 15578 1 +15583 2 5 15582 1 +15583 3 15578 7 0 1 +15583 4 5 12039 3 0 1 +15601 1 15578 1 +15601 2 23 15600 1 +15601 3 15578 2 0 1 +15601 4 23 9357 8 0 1 +15607 1 15604 1 +15607 2 3 15605 1 +15607 3 15604 1 0 1 +15607 4 3 10488 3 0 1 +15619 1 15612 1 +15619 2 7 15617 1 +15619 3 15612 3 0 1 +15619 4 7 15119 6 0 1 +15629 1 15627 1 +15629 2 2 15624 1 +15629 3 15627 3 0 1 +15629 4 2 13192 8 0 1 +15641 1 15638 1 +15641 2 3 15636 1 +15641 3 15638 3 0 1 +15641 4 3 10034 2 0 1 +15643 1 15638 1 +15643 2 5 15641 1 +15643 3 15638 2 0 1 +15643 4 5 10262 0 0 1 +15647 1 15642 1 +15647 2 5 15646 1 +15647 3 15642 12 0 1 +15647 4 5 10656 4 0 1 +15649 1 15638 1 +15649 2 11 15644 1 +15649 3 15638 3 0 1 +15649 4 11 13785 27 0 1 +15661 1 15659 1 +15661 2 2 15657 1 +15661 3 15659 2 0 1 +15661 4 2 10274 12 0 1 +15667 1 15665 1 +15667 2 2 15663 1 +15667 3 15665 6 0 1 +15667 4 2 8825 8 0 1 +15671 1 15658 1 +15671 2 13 15669 1 +15671 3 15658 3 0 1 +15671 4 13 11603 3 0 1 +15679 1 15668 1 +15679 2 11 15678 1 +15679 3 15668 3 0 1 +15679 4 11 14897 2 0 1 +15683 1 15681 1 +15683 2 2 15682 1 +15683 3 15681 3 0 1 +15683 4 2 14689 2 0 1 +15727 1 15724 1 +15727 2 3 15726 1 +15727 3 15724 5 0 1 +15727 4 3 13197 2 0 1 +15731 1 15729 1 +15731 2 2 15726 1 +15731 3 15729 2 0 1 +15731 4 2 10581 3 0 1 +15733 1 15727 1 +15733 2 6 15731 1 +15733 3 15727 3 0 1 +15733 4 6 13802 4 0 1 +15737 1 15734 1 +15737 2 3 15736 1 +15737 3 15734 3 0 1 +15737 4 3 12626 7 0 1 +15739 1 15737 1 +15739 2 2 15738 1 +15739 3 15737 6 0 1 +15739 4 2 12090 2 0 1 +15749 1 15747 1 +15749 2 2 15744 1 +15749 3 15747 7 0 1 +15749 4 2 13579 8 0 1 +15761 1 15758 1 +15761 2 3 15756 1 +15761 3 15758 1 0 1 +15761 4 3 8021 2 0 1 +15767 1 15762 1 +15767 2 5 15765 1 +15767 3 15762 6 0 1 +15767 4 5 15763 3 0 1 +15773 1 15771 1 +15773 2 2 15765 1 +15773 3 15771 4 0 1 +15773 4 2 11997 19 0 1 +15787 1 15785 1 +15787 2 2 15783 1 +15787 3 15785 6 0 1 +15787 4 2 8715 8 0 1 +15791 1 15762 1 +15791 2 29 15789 1 +15791 3 15762 1 0 1 +15791 4 29 13692 3 0 1 +15797 1 15795 1 +15797 2 2 15796 1 +15797 3 15795 2 0 1 +15797 4 2 11364 4 0 1 +15803 1 15801 1 +15803 2 2 15799 1 +15803 3 15801 3 0 1 +15803 4 2 13330 8 0 1 +15809 1 15806 1 +15809 2 3 15793 1 +15809 3 15806 5 0 1 +15809 4 3 11417 5 0 1 +15817 1 15812 1 +15817 2 5 15814 1 +15817 3 15812 1 0 1 +15817 4 5 15806 14 0 1 +15823 1 15820 1 +15823 2 3 15821 1 +15823 3 15820 1 0 1 +15823 4 3 11784 3 0 1 +15859 1 15857 1 +15859 2 2 15855 1 +15859 3 15857 2 0 1 +15859 4 2 14606 8 0 1 +15877 1 15872 1 +15877 2 5 15876 1 +15877 3 15872 1 0 1 +15877 4 5 12548 6 0 1 +15881 1 15878 1 +15881 2 3 15880 1 +15881 3 15878 3 0 1 +15881 4 3 14374 7 0 1 +15887 1 15882 1 +15887 2 5 15885 1 +15887 3 15882 2 0 1 +15887 4 5 12622 5 0 1 +15889 1 15868 1 +15889 2 21 15885 1 +15889 3 15868 3 0 1 +15889 4 21 8661 18 0 1 +15901 1 15891 1 +15901 2 10 15900 1 +15901 3 15891 2 0 1 +15901 4 10 8178 3 0 1 +15907 1 15905 1 +15907 2 2 15906 1 +15907 3 15905 2 0 1 +15907 4 2 14352 24 0 1 +15913 1 15908 1 +15913 2 5 15912 1 +15913 3 15908 2 0 1 +15913 4 5 10875 12 0 1 +15919 1 15913 1 +15919 2 6 15915 1 +15919 3 15913 1 0 1 +15919 4 6 15915 6 0 1 +15923 1 15921 1 +15923 2 2 15922 1 +15923 3 15921 2 0 1 +15923 4 2 11080 11 0 1 +15937 1 15930 1 +15937 2 7 15934 1 +15937 3 15930 1 0 1 +15937 4 7 9049 8 0 1 +15959 1 15948 1 +15959 2 11 15957 1 +15959 3 15948 1 0 1 +15959 4 11 12406 8 0 1 +15971 1 15969 1 +15971 2 2 15967 1 +15971 3 15969 2 0 1 +15971 4 2 13906 8 0 1 +15973 1 15966 1 +15973 2 7 15971 1 +15973 3 15966 4 0 1 +15973 4 7 15535 9 0 1 +15991 1 15979 1 +15991 2 12 15990 1 +15991 3 15979 6 0 1 +15991 4 12 15501 6 0 1 +16001 1 15998 1 +16001 2 3 16000 1 +16001 3 15998 3 0 1 +16001 4 3 11518 4 0 1 +16007 1 16002 1 +16007 2 5 16005 1 +16007 3 16002 5 0 1 +16007 4 5 10910 5 0 1 +16033 1 16028 1 +16033 2 5 16030 1 +16033 3 16028 1 0 1 +16033 4 5 10823 24 0 1 +16057 1 16050 1 +16057 2 7 16054 1 +16057 3 16050 4 0 1 +16057 4 7 8370 14 0 1 +16061 1 16049 1 +16061 2 12 16057 1 +16061 3 16049 5 0 1 +16061 4 12 12651 2 0 1 +16063 1 16058 1 +16063 2 5 16062 1 +16063 3 16058 1 0 1 +16063 4 5 10575 2 0 1 +16067 1 16065 1 +16067 2 2 16061 1 +16067 3 16065 4 0 1 +16067 4 2 10096 0 0 1 +16069 1 16067 1 +16069 2 2 16062 1 +16069 3 16067 2 0 1 +16069 4 2 15200 9 0 1 +16073 1 16070 1 +16073 2 3 16072 1 +16073 3 16070 3 0 1 +16073 4 3 11304 7 0 1 +16087 1 16082 1 +16087 2 5 16086 1 +16087 3 16082 11 0 1 +16087 4 5 14210 5 0 1 +16091 1 16085 1 +16091 2 6 16090 1 +16091 3 16085 3 0 1 +16091 4 6 15496 2 0 1 +16097 1 16094 1 +16097 2 3 16091 1 +16097 3 16094 8 0 1 +16097 4 3 13585 1 0 1 +16103 1 16098 1 +16103 2 5 16102 1 +16103 3 16098 2 0 1 +16103 4 5 8601 2 0 1 +16111 1 16104 1 +16111 2 7 16100 1 +16111 3 16104 1 0 1 +16111 4 7 11905 5 0 1 +16127 1 16122 1 +16127 2 5 16126 1 +16127 3 16122 5 0 1 +16127 4 5 9406 7 0 1 +16139 1 16137 1 +16139 2 2 16134 1 +16139 3 16137 2 0 1 +16139 4 2 13098 3 0 1 +16141 1 16135 1 +16141 2 6 16137 1 +16141 3 16135 4 0 1 +16141 4 6 12611 10 0 1 +16183 1 16180 1 +16183 2 3 16181 1 +16183 3 16180 1 0 1 +16183 4 3 13542 3 0 1 +16187 1 16185 1 +16187 2 2 16186 1 +16187 3 16185 2 0 1 +16187 4 2 14687 2 0 1 +16189 1 16187 1 +16189 2 2 16188 1 +16189 3 16187 6 0 1 +16189 4 2 12027 3 0 1 +16193 1 16188 1 +16193 2 5 16186 1 +16193 3 16188 2 0 1 +16193 4 5 11495 2 0 1 +16217 1 16214 1 +16217 2 3 16209 1 +16217 3 16214 3 0 1 +16217 4 3 9176 2 0 1 +16223 1 16218 1 +16223 2 5 16221 1 +16223 3 16218 1 0 1 +16223 4 5 16211 11 0 1 +16229 1 16227 1 +16229 2 2 16225 1 +16229 3 16227 3 0 1 +16229 4 2 10412 1 0 1 +16231 1 16228 1 +16231 2 3 16230 1 +16231 3 16228 4 0 1 +16231 4 3 11282 3 0 1 +16249 1 16232 1 +16249 2 17 16246 1 +16249 3 16232 6 0 1 +16249 4 17 9288 20 0 1 +16253 1 16251 1 +16253 2 2 16252 1 +16253 3 16251 5 0 1 +16253 4 2 11667 3 0 1 +16267 1 16264 1 +16267 2 3 16254 1 +16267 3 16264 6 0 1 +16267 4 3 9631 2 0 1 +16273 1 16266 1 +16273 2 7 16266 1 +16273 3 16266 1 0 1 +16273 4 7 9328 14 0 1 +16301 1 16299 1 +16301 2 2 16300 1 +16301 3 16299 3 0 1 +16301 4 2 9533 3 0 1 +16319 1 16312 1 +16319 2 7 16318 1 +16319 3 16312 3 0 1 +16319 4 7 14283 11 0 1 +16333 1 16331 1 +16333 2 2 16329 1 +16333 3 16331 6 0 1 +16333 4 2 13777 12 0 1 +16339 1 16337 1 +16339 2 2 16335 1 +16339 3 16337 5 0 1 +16339 4 2 9888 8 0 1 +16349 1 16347 1 +16349 2 2 16345 1 +16349 3 16347 3 0 1 +16349 4 2 15888 6 0 1 +16361 1 16358 1 +16361 2 3 16353 1 +16361 3 16358 7 0 1 +16361 4 3 15626 2 0 1 +16363 1 16361 1 +16363 2 2 16359 1 +16363 3 16361 4 0 1 +16363 4 2 13047 14 0 1 +16369 1 16362 1 +16369 2 7 16366 1 +16369 3 16362 4 0 1 +16369 4 7 11519 16 0 1 +16381 1 16379 1 +16381 2 2 16377 1 +16381 3 16379 4 0 1 +16381 4 2 15657 6 0 1 +16411 1 16408 1 +16411 2 3 16410 1 +16411 3 16408 1 0 1 +16411 4 3 8375 2 0 1 +16417 1 16407 1 +16417 2 10 16416 1 +16417 3 16407 4 0 1 +16417 4 10 13893 21 0 1 +16421 1 16419 1 +16421 2 2 16411 1 +16421 3 16419 8 0 1 +16421 4 2 11652 7 0 1 +16427 1 16425 1 +16427 2 2 16423 1 +16427 3 16425 3 0 1 +16427 4 2 15023 7 0 1 +16433 1 16430 1 +16433 2 3 16423 1 +16433 3 16430 11 0 1 +16433 4 3 14284 4 0 1 +16447 1 16444 1 +16447 2 3 16446 1 +16447 3 16444 5 0 1 +16447 4 3 13423 5 0 1 +16451 1 16444 1 +16451 2 7 16445 1 +16451 3 16444 3 0 1 +16451 4 7 16447 4 0 1 +16453 1 16451 1 +16453 2 2 16452 1 +16453 3 16451 2 0 1 +16453 4 2 15443 3 0 1 +16477 1 16475 1 +16477 2 2 16476 1 +16477 3 16475 2 0 1 +16477 4 2 16470 8 0 1 +16481 1 16475 1 +16481 2 6 16471 1 +16481 3 16475 7 0 1 +16481 4 6 13531 3 0 1 +16487 1 16482 1 +16487 2 5 16486 1 +16487 3 16482 1 0 1 +16487 4 5 14263 5 0 1 +16493 1 16491 1 +16493 2 2 16489 1 +16493 3 16491 3 0 1 +16493 4 2 8748 6 0 1 +16519 1 16516 1 +16519 2 3 16517 1 +16519 3 16516 6 0 1 +16519 4 3 12886 3 0 1 +16529 1 16526 1 +16529 2 3 16528 1 +16529 3 16526 10 0 1 +16529 4 3 16347 7 0 1 +16547 1 16545 1 +16547 2 2 16546 1 +16547 3 16545 2 0 1 +16547 4 2 10767 2 0 1 +16553 1 16550 1 +16553 2 3 16547 1 +16553 3 16550 1 0 1 +16553 4 3 12969 9 0 1 +16561 1 16554 1 +16561 2 7 16558 1 +16561 3 16554 1 0 1 +16561 4 7 9382 14 0 1 +16567 1 16564 1 +16567 2 3 16565 1 +16567 3 16564 4 0 1 +16567 4 3 10444 3 0 1 +16573 1 16571 1 +16573 2 2 16569 1 +16573 3 16571 7 0 1 +16573 4 2 9569 12 0 1 +16603 1 16601 1 +16603 2 2 16602 1 +16603 3 16601 6 0 1 +16603 4 2 15788 16 0 1 +16607 1 16602 1 +16607 2 5 16605 1 +16607 3 16602 1 0 1 +16607 4 5 15925 10 0 1 +16619 1 16617 1 +16619 2 2 16615 1 +16619 3 16617 2 0 1 +16619 4 2 15056 7 0 1 +16631 1 16612 1 +16631 2 19 16630 1 +16631 3 16612 1 0 1 +16631 4 19 10223 8 0 1 +16633 1 16618 1 +16633 2 15 16632 1 +16633 3 16618 4 0 1 +16633 4 15 9934 14 0 1 +16649 1 16646 1 +16649 2 3 16643 1 +16649 3 16646 6 0 1 +16649 4 3 16637 0 0 1 +16651 1 16649 1 +16651 2 2 16650 1 +16651 3 16649 4 0 1 +16651 4 2 11256 12 0 1 +16657 1 16652 1 +16657 2 5 16656 1 +16657 3 16652 13 0 1 +16657 4 5 13959 6 0 1 +16661 1 16651 1 +16661 2 10 16656 1 +16661 3 16651 7 0 1 +16661 4 10 12016 7 0 1 +16673 1 16670 1 +16673 2 3 16672 1 +16673 3 16670 1 0 1 +16673 4 3 8824 7 0 1 +16691 1 16685 1 +16691 2 6 16689 1 +16691 3 16685 1 0 1 +16691 4 6 16681 7 0 1 +16693 1 16691 1 +16693 2 2 16692 1 +16693 3 16691 6 0 1 +16693 4 2 8491 3 0 1 +16699 1 16696 1 +16699 2 3 16694 1 +16699 3 16696 10 0 1 +16699 4 3 16410 3 0 1 +16703 1 16698 1 +16703 2 5 16702 1 +16703 3 16698 8 0 1 +16703 4 5 8813 2 0 1 +16729 1 16716 1 +16729 2 13 16726 1 +16729 3 16716 2 0 1 +16729 4 13 12734 16 0 1 +16741 1 16735 1 +16741 2 6 16740 1 +16741 3 16735 1 0 1 +16741 4 6 8876 11 0 1 +16747 1 16745 1 +16747 2 2 16746 1 +16747 3 16745 2 0 1 +16747 4 2 16430 2 0 1 +16759 1 16756 1 +16759 2 3 16754 1 +16759 3 16756 4 0 1 +16759 4 3 13520 6 0 1 +16763 1 16761 1 +16763 2 2 16759 1 +16763 3 16761 2 0 1 +16763 4 2 13241 21 0 1 +16787 1 16785 1 +16787 2 2 16783 1 +16787 3 16785 3 0 1 +16787 4 2 10145 13 0 1 +16811 1 16804 1 +16811 2 7 16810 1 +16811 3 16804 2 0 1 +16811 4 7 14794 2 0 1 +16823 1 16818 1 +16823 2 5 16821 1 +16823 3 16818 3 0 1 +16823 4 5 11944 8 0 1 +16829 1 16827 1 +16829 2 2 16825 1 +16829 3 16827 2 0 1 +16829 4 2 13058 12 0 1 +16831 1 16825 1 +16831 2 6 16829 1 +16831 3 16825 3 0 1 +16831 4 6 14569 3 0 1 +16843 1 16841 1 +16843 2 2 16839 1 +16843 3 16841 6 0 1 +16843 4 2 11857 13 0 1 +16871 1 16854 1 +16871 2 17 16869 1 +16871 3 16854 2 0 1 +16871 4 17 16863 3 0 1 +16879 1 16876 1 +16879 2 3 16877 1 +16879 3 16876 4 0 1 +16879 4 3 9540 6 0 1 +16883 1 16881 1 +16883 2 2 16875 1 +16883 3 16881 15 0 1 +16883 4 2 8556 0 0 1 +16889 1 16886 1 +16889 2 3 16882 1 +16889 3 16886 7 0 1 +16889 4 3 15970 4 0 1 +16901 1 16899 1 +16901 2 2 16900 1 +16901 3 16899 3 0 1 +16901 4 2 16894 8 0 1 +16903 1 16900 1 +16903 2 3 16902 1 +16903 3 16900 3 0 1 +16903 4 3 12591 5 0 1 +16921 1 16904 1 +16921 2 17 16918 1 +16921 3 16904 3 0 1 +16921 4 17 16162 16 0 1 +16927 1 16921 1 +16927 2 6 16926 1 +16927 3 16921 1 0 1 +16927 4 6 9845 2 0 1 +16931 1 16929 1 +16931 2 2 16930 1 +16931 3 16929 3 0 1 +16931 4 2 13481 2 0 1 +16937 1 16934 1 +16937 2 3 16936 1 +16937 3 16934 1 0 1 +16937 4 3 9810 7 0 1 +16943 1 16938 1 +16943 2 5 16942 1 +16943 3 16938 7 0 1 +16943 4 5 9020 7 0 1 +16963 1 16961 1 +16963 2 2 16959 1 +16963 3 16961 5 0 1 +16963 4 2 14815 8 0 1 +16979 1 16977 1 +16979 2 2 16973 1 +16979 3 16977 2 0 1 +16979 4 2 10100 0 0 1 +16981 1 16979 1 +16981 2 2 16980 1 +16981 3 16979 6 0 1 +16981 4 2 13100 3 0 1 +16987 1 16984 1 +16987 2 3 16976 1 +16987 3 16984 1 0 1 +16987 4 3 13805 3 0 1 +16993 1 16983 1 +16993 2 10 16992 1 +16993 3 16983 5 0 1 +16993 4 10 15879 14 0 1 +17011 1 17009 1 +17011 2 2 17007 1 +17011 3 17009 2 0 1 +17011 4 2 13795 8 0 1 +17021 1 17019 1 +17021 2 2 17013 1 +17021 3 17019 8 0 1 +17021 4 2 13081 0 0 1 +17027 1 17025 1 +17027 2 2 17026 1 +17027 3 17025 2 0 1 +17027 4 2 14040 4 0 1 +17029 1 17019 1 +17029 2 10 17025 1 +17029 3 17019 6 0 1 +17029 4 10 17017 10 0 1 +17033 1 17030 1 +17033 2 3 17027 1 +17033 3 17030 5 0 1 +17033 4 3 14449 1 0 1 +17041 1 17034 1 +17041 2 7 17034 1 +17041 3 17034 1 0 1 +17041 4 7 16291 0 0 1 +17047 1 17044 1 +17047 2 3 17046 1 +17047 3 17044 1 0 1 +17047 4 3 11227 2 0 1 +17053 1 17051 1 +17053 2 2 17049 1 +17053 3 17051 4 0 1 +17053 4 2 14289 10 0 1 +17077 1 17075 1 +17077 2 2 17073 1 +17077 3 17075 6 0 1 +17077 4 2 8890 36 0 1 +17093 1 17091 1 +17093 2 2 17089 1 +17093 3 17091 2 0 1 +17093 4 2 12893 1 0 1 +17099 1 17097 1 +17099 2 2 17098 1 +17099 3 17097 3 0 1 +17099 4 2 13487 2 0 1 +17107 1 17104 1 +17107 2 3 17106 1 +17107 3 17104 5 0 1 +17107 4 3 16922 2 0 1 +17117 1 17114 1 +17117 2 3 17115 1 +17117 3 17114 4 0 1 +17117 4 3 14382 14 0 1 +17123 1 17121 1 +17123 2 2 17119 1 +17123 3 17121 3 0 1 +17123 4 2 14197 7 0 1 +17137 1 17132 1 +17137 2 5 17136 1 +17137 3 17132 1 0 1 +17137 4 5 11563 6 0 1 +17159 1 17152 1 +17159 2 7 17158 1 +17159 3 17152 1 0 1 +17159 4 7 16866 3 0 1 +17167 1 17164 1 +17167 2 3 17166 1 +17167 3 17164 11 0 1 +17167 4 3 10995 2 0 1 +17183 1 17178 1 +17183 2 5 17178 1 +17183 3 17178 1 0 1 +17183 4 5 11186 7 0 1 +17189 1 17187 1 +17189 2 2 17177 1 +17189 3 17187 4 0 1 +17189 4 2 8834 1 0 1 +17191 1 17188 1 +17191 2 3 17189 1 +17191 3 17188 4 0 1 +17191 4 3 11345 3 0 1 +17203 1 17201 1 +17203 2 2 17199 1 +17203 3 17201 5 0 1 +17203 4 2 16333 8 0 1 +17207 1 17202 1 +17207 2 5 17205 1 +17207 3 17202 3 0 1 +17207 4 5 17203 3 0 1 +17209 1 17195 1 +17209 2 14 17202 1 +17209 3 17195 5 0 1 +17209 4 14 8751 0 0 1 +17231 1 17218 1 +17231 2 13 17227 1 +17231 3 17218 3 0 1 +17231 4 13 9900 6 0 1 +17239 1 17233 1 +17239 2 6 17237 1 +17239 3 17233 3 0 1 +17239 4 6 9995 3 0 1 +17257 1 17252 1 +17257 2 5 17252 1 +17257 3 17252 1 0 1 +17257 4 5 12127 10 0 1 +17291 1 17285 1 +17291 2 6 17288 1 +17291 3 17285 1 0 1 +17291 4 6 9115 1 0 1 +17293 1 17286 1 +17293 2 7 17291 1 +17293 3 17286 3 0 1 +17293 4 7 13974 7 0 1 +17299 1 17297 1 +17299 2 2 17295 1 +17299 3 17297 6 0 1 +17299 4 2 16555 8 0 1 +17317 1 17315 1 +17317 2 2 17316 1 +17317 3 17315 2 0 1 +17317 4 2 14695 6 0 1 +17321 1 17318 1 +17321 2 3 17316 1 +17321 3 17318 6 0 1 +17321 4 3 11113 2 0 1 +17327 1 17322 1 +17327 2 5 17324 1 +17327 3 17322 2 0 1 +17327 4 5 12024 11 0 1 +17333 1 17331 1 +17333 2 2 17329 1 +17333 3 17331 3 0 1 +17333 4 2 15647 6 0 1 +17341 1 17335 1 +17341 2 6 17340 1 +17341 3 17335 4 0 1 +17341 4 6 16573 11 0 1 +17351 1 17340 1 +17351 2 11 17350 1 +17351 3 17340 2 0 1 +17351 4 11 8850 3 0 1 +17359 1 17356 1 +17359 2 3 17357 1 +17359 3 17356 3 0 1 +17359 4 3 14524 3 0 1 +17377 1 17370 1 +17377 2 7 17370 1 +17377 3 17370 2 0 1 +17377 4 7 13357 17 0 1 +17383 1 17378 1 +17383 2 5 17381 1 +17383 3 17378 6 0 1 +17383 4 5 17379 3 0 1 +17387 1 17385 1 +17387 2 2 17380 1 +17387 3 17385 4 0 1 +17387 4 2 11427 8 0 1 +17389 1 17387 1 +17389 2 2 17385 1 +17389 3 17387 6 0 1 +17389 4 2 14053 12 0 1 +17393 1 17390 1 +17393 2 3 17387 1 +17393 3 17390 5 0 1 +17393 4 3 15367 9 0 1 +17401 1 17390 1 +17401 2 11 17400 1 +17401 3 17390 2 0 1 +17401 4 11 8849 8 0 1 +17417 1 17414 1 +17417 2 3 17408 1 +17417 3 17414 5 0 1 +17417 4 3 12851 6 0 1 +17419 1 17416 1 +17419 2 3 17418 1 +17419 3 17416 3 0 1 +17419 4 3 14679 2 0 1 +17431 1 17428 1 +17431 2 3 17430 1 +17431 3 17428 1 0 1 +17431 4 3 16720 3 0 1 +17443 1 17441 1 +17443 2 2 17439 1 +17443 3 17441 6 0 1 +17443 4 2 9848 1 0 1 +17449 1 17435 1 +17449 2 14 17444 1 +17449 3 17435 4 0 1 +17449 4 14 15512 19 0 1 +17467 1 17464 1 +17467 2 3 17466 1 +17467 3 17464 12 0 1 +17467 4 3 13632 2 0 1 +17471 1 17460 1 +17471 2 11 17468 1 +17471 3 17460 2 0 1 +17471 4 11 9740 5 0 1 +17477 1 17475 1 +17477 2 2 17476 1 +17477 3 17475 3 0 1 +17477 4 2 10983 6 0 1 +17483 1 17481 1 +17483 2 2 17478 1 +17483 3 17481 5 0 1 +17483 4 2 16596 3 0 1 +17489 1 17486 1 +17489 2 3 17480 1 +17489 3 17486 4 0 1 +17489 4 3 12697 6 0 1 +17491 1 17488 1 +17491 2 3 17486 1 +17491 3 17488 4 0 1 +17491 4 3 11158 3 0 1 +17497 1 17492 1 +17497 2 5 17494 1 +17497 3 17492 2 0 1 +17497 4 5 11505 23 0 1 +17509 1 17507 1 +17509 2 2 17505 1 +17509 3 17507 2 0 1 +17509 4 2 14794 12 0 1 +17519 1 17506 1 +17519 2 13 17517 1 +17519 3 17506 2 0 1 +17519 4 13 16641 3 0 1 +17539 1 17536 1 +17539 2 3 17531 1 +17539 3 17536 5 0 1 +17539 4 3 12655 0 0 1 +17551 1 17548 1 +17551 2 3 17550 1 +17551 3 17548 3 0 1 +17551 4 3 10092 2 0 1 +17569 1 17558 1 +17569 2 11 17564 1 +17569 3 17558 3 0 1 +17569 4 11 11572 19 0 1 +17573 1 17571 1 +17573 2 2 17569 1 +17573 3 17571 3 0 1 +17573 4 2 15339 1 0 1 +17579 1 17577 1 +17579 2 2 17575 1 +17579 3 17577 4 0 1 +17579 4 2 12349 7 0 1 +17581 1 17571 1 +17581 2 10 17580 1 +17581 3 17571 13 0 1 +17581 4 10 14731 3 0 1 +17597 1 17595 1 +17597 2 2 17596 1 +17597 3 17595 2 0 1 +17597 4 2 13272 3 0 1 +17599 1 17593 1 +17599 2 6 17597 1 +17599 3 17593 1 0 1 +17599 4 6 11910 10 0 1 +17609 1 17606 1 +17609 2 3 17603 1 +17609 3 17606 1 0 1 +17609 4 3 17597 0 0 1 +17623 1 17620 1 +17623 2 3 17621 1 +17623 3 17620 1 0 1 +17623 4 3 10124 3 0 1 +17627 1 17625 1 +17627 2 2 17621 1 +17627 3 17625 4 0 1 +17627 4 2 9640 4 0 1 +17657 1 17654 1 +17657 2 3 17648 1 +17657 3 17654 5 0 1 +17657 4 3 16553 2 0 1 +17659 1 17656 1 +17659 2 3 17643 1 +17659 3 17656 1 0 1 +17659 4 3 9493 3 0 1 +17669 1 17667 1 +17669 2 2 17665 1 +17669 3 17667 3 0 1 +17669 4 2 13132 6 0 1 +17681 1 17678 1 +17681 2 3 17675 1 +17681 3 17678 1 0 1 +17681 4 3 17669 0 0 1 +17683 1 17678 1 +17683 2 5 17682 1 +17683 3 17678 7 0 1 +17683 4 5 10266 5 0 1 +17707 1 17704 1 +17707 2 3 17706 1 +17707 3 17704 9 0 1 +17707 4 3 9502 2 0 1 +17713 1 17706 1 +17713 2 7 17706 1 +17713 3 17706 1 0 1 +17713 4 7 10800 12 0 1 +17729 1 17726 1 +17729 2 3 17723 1 +17729 3 17726 14 0 1 +17729 4 3 17717 0 0 1 +17737 1 17730 1 +17737 2 7 17730 1 +17737 3 17730 4 0 1 +17737 4 7 12831 20 0 1 +17747 1 17745 1 +17747 2 2 17743 1 +17747 3 17745 3 0 1 +17747 4 2 10694 8 0 1 +17749 1 17747 1 +17749 2 2 17740 1 +17749 3 17747 2 0 1 +17749 4 2 13430 15 0 1 +17761 1 17742 1 +17761 2 19 17748 1 +17761 3 17742 1 0 1 +17761 4 19 14869 32 0 1 +17783 1 17778 1 +17783 2 5 17778 1 +17783 3 17778 5 0 1 +17783 4 5 9981 6 0 1 +17789 1 17787 1 +17789 2 2 17784 1 +17789 3 17787 3 0 1 +17789 4 2 10357 18 0 1 +17791 1 17788 1 +17791 2 3 17789 1 +17791 3 17788 4 0 1 +17791 4 3 12096 6 0 1 +17807 1 17802 1 +17807 2 5 17802 1 +17807 3 17802 1 0 1 +17807 4 5 17454 13 0 1 +17827 1 17825 1 +17827 2 2 17826 1 +17827 3 17825 2 0 1 +17827 4 2 11229 11 0 1 +17837 1 17835 1 +17837 2 2 17833 1 +17837 3 17835 3 0 1 +17837 4 2 14362 7 0 1 +17839 1 17833 1 +17839 2 6 17837 1 +17839 3 17833 3 0 1 +17839 4 6 17396 3 0 1 +17851 1 17849 1 +17851 2 2 17847 1 +17851 3 17849 2 0 1 +17851 4 2 13825 8 0 1 +17863 1 17857 1 +17863 2 6 17862 1 +17863 3 17857 1 0 1 +17863 4 6 16183 3 0 1 +17881 1 17874 1 +17881 2 7 17878 1 +17881 3 17874 1 0 1 +17881 4 7 9480 29 0 1 +17891 1 17889 1 +17891 2 2 17887 1 +17891 3 17889 3 0 1 +17891 4 2 12191 11 0 1 +17903 1 17898 1 +17903 2 5 17898 1 +17903 3 17898 13 0 1 +17903 4 5 17549 6 0 1 +17909 1 17907 1 +17909 2 2 17903 1 +17909 3 17907 3 0 1 +17909 4 2 12859 3 0 1 +17911 1 17908 1 +17911 2 3 17909 1 +17911 3 17908 3 0 1 +17911 4 3 9990 3 0 1 +17921 1 17918 1 +17921 2 3 17914 1 +17921 3 17918 8 0 1 +17921 4 3 15904 1 0 1 +17923 1 17921 1 +17923 2 2 17922 1 +17923 3 17921 2 0 1 +17923 4 2 12671 2 0 1 +17929 1 17918 1 +17929 2 11 17915 1 +17929 3 17918 3 0 1 +17929 4 11 15684 1 0 1 +17939 1 17937 1 +17939 2 2 17932 1 +17939 3 17937 5 0 1 +17939 4 2 9366 1 0 1 +17957 1 17955 1 +17957 2 2 17952 1 +17957 3 17955 5 0 1 +17957 4 2 16029 0 0 1 +17959 1 17953 1 +17959 2 6 17957 1 +17959 3 17953 14 0 1 +17959 4 6 15994 4 0 1 +17971 1 17968 1 +17971 2 3 17970 1 +17971 3 17968 7 0 1 +17971 4 3 10615 6 0 1 +17977 1 17972 1 +17977 2 5 17976 1 +17977 3 17972 16 0 1 +17977 4 5 11843 6 0 1 +17981 1 17979 1 +17981 2 2 17980 1 +17981 3 17979 12 0 1 +17981 4 2 14248 3 0 1 +17987 1 17982 1 +17987 2 5 17984 1 +17987 3 17982 2 0 1 +17987 4 5 14070 1 0 1 +17989 1 17987 1 +17989 2 2 17988 1 +17989 3 17987 6 0 1 +17989 4 2 14690 9 0 1 +18013 1 18011 1 +18013 2 2 18009 1 +18013 3 18011 6 0 1 +18013 4 2 15982 6 0 1 +18041 1 18038 1 +18041 2 3 18035 1 +18041 3 18038 4 0 1 +18041 4 3 18029 0 0 1 +18043 1 18041 1 +18043 2 2 18039 1 +18043 3 18041 4 0 1 +18043 4 2 13772 8 0 1 +18047 1 18042 1 +18047 2 5 18044 1 +18047 3 18042 6 0 1 +18047 4 5 11073 4 0 1 +18049 1 18036 1 +18049 2 13 18048 1 +18049 3 18036 3 0 1 +18049 4 13 15234 15 0 1 +18059 1 18057 1 +18059 2 2 18054 1 +18059 3 18057 10 0 1 +18059 4 2 11939 3 0 1 +18061 1 18055 1 +18061 2 6 18057 1 +18061 3 18055 1 0 1 +18061 4 6 9650 2 0 1 +18077 1 18075 1 +18077 2 2 18071 1 +18077 3 18075 5 0 1 +18077 4 2 12604 1 0 1 +18089 1 18086 1 +18089 2 3 18084 1 +18089 3 18086 3 0 1 +18089 4 3 9195 2 0 1 +18097 1 18092 1 +18097 2 5 18094 1 +18097 3 18092 3 0 1 +18097 4 5 14769 23 0 1 +18119 1 18102 1 +18119 2 17 18117 1 +18119 3 18102 2 0 1 +18119 4 17 18111 3 0 1 +18121 1 18098 1 +18121 2 23 18120 1 +18121 3 18098 3 0 1 +18121 4 23 17654 8 0 1 +18127 1 18124 1 +18127 2 3 18126 1 +18127 3 18124 6 0 1 +18127 4 3 18116 12 0 1 +18131 1 18124 1 +18131 2 7 18127 1 +18131 3 18124 2 0 1 +18131 4 7 12288 2 0 1 +18133 1 18128 1 +18133 2 5 18128 1 +18133 3 18128 6 0 1 +18133 4 5 13395 7 0 1 +18143 1 18138 1 +18143 2 5 18135 1 +18143 3 18138 5 0 1 +18143 4 5 15942 3 0 1 +18149 1 18147 1 +18149 2 2 18148 1 +18149 3 18147 3 0 1 +18149 4 2 16538 3 0 1 +18169 1 18158 1 +18169 2 11 18154 1 +18169 3 18158 3 0 1 +18169 4 11 17818 37 0 1 +18181 1 18179 1 +18181 2 2 18177 1 +18181 3 18179 6 0 1 +18181 4 2 9768 12 0 1 +18191 1 18162 1 +18191 2 29 18190 1 +18191 3 18162 6 0 1 +18191 4 29 15236 4 0 1 +18199 1 18188 1 +18199 2 11 18197 1 +18199 3 18188 3 0 1 +18199 4 11 13365 3 0 1 +18211 1 18204 1 +18211 2 7 18205 1 +18211 3 18204 1 0 1 +18211 4 7 11326 7 0 1 +18217 1 18210 1 +18217 2 7 18214 1 +18217 3 18210 3 0 1 +18217 4 7 11839 20 0 1 +18223 1 18220 1 +18223 2 3 18222 1 +18223 3 18220 4 0 1 +18223 4 3 16672 16 0 1 +18229 1 18227 1 +18229 2 2 18225 1 +18229 3 18227 4 0 1 +18229 4 2 17959 6 0 1 +18233 1 18230 1 +18233 2 3 18232 1 +18233 3 18230 1 0 1 +18233 4 3 9739 6 0 1 +18251 1 18249 1 +18251 2 2 18246 1 +18251 3 18249 2 0 1 +18251 4 2 11575 3 0 1 +18253 1 18248 1 +18253 2 5 18252 1 +18253 3 18248 17 0 1 +18253 4 5 11906 3 0 1 +18257 1 18252 1 +18257 2 5 18249 1 +18257 3 18252 2 0 1 +18257 4 5 16485 13 0 1 +18269 1 18267 1 +18269 2 2 18265 1 +18269 3 18267 3 0 1 +18269 4 2 9937 1 0 1 +18287 1 18282 1 +18287 2 5 18282 1 +18287 3 18282 1 0 1 +18287 4 5 13947 7 0 1 +18289 1 18276 1 +18289 2 13 18280 1 +18289 3 18276 3 0 1 +18289 4 13 9706 16 0 1 +18301 1 18295 1 +18301 2 6 18297 1 +18301 3 18295 1 0 1 +18301 4 6 18297 6 0 1 +18307 1 18296 1 +18307 2 11 18306 1 +18307 3 18296 7 0 1 +18307 4 11 16831 2 0 1 +18311 1 18298 1 +18311 2 13 18307 1 +18311 3 18298 2 0 1 +18311 4 13 14877 6 0 1 +18313 1 18303 1 +18313 2 10 18310 1 +18313 3 18303 3 0 1 +18313 4 10 17080 13 0 1 +18329 1 18326 1 +18329 2 3 18323 1 +18329 3 18326 4 0 1 +18329 4 3 18317 0 0 1 +18341 1 18338 1 +18341 2 3 18336 1 +18341 3 18338 3 0 1 +18341 4 3 14231 2 0 1 +18353 1 18350 1 +18353 2 3 18341 1 +18353 3 18350 6 0 1 +18353 4 3 16535 0 0 1 +18367 1 18364 1 +18367 2 3 18366 1 +18367 3 18364 1 0 1 +18367 4 3 9844 5 0 1 +18371 1 18360 1 +18371 2 11 18368 1 +18371 3 18360 4 0 1 +18371 4 11 16148 1 0 1 +18379 1 18376 1 +18379 2 3 18368 1 +18379 3 18376 1 0 1 +18379 4 3 16019 4 0 1 +18397 1 18391 1 +18397 2 6 18396 1 +18397 3 18391 2 0 1 +18397 4 6 12477 6 0 1 +18401 1 18398 1 +18401 2 3 18396 1 +18401 3 18398 3 0 1 +18401 4 3 12715 2 0 1 +18413 1 18411 1 +18413 2 2 18409 1 +18413 3 18411 3 0 1 +18413 4 2 13627 1 0 1 +18427 1 18425 1 +18427 2 2 18426 1 +18427 3 18425 6 0 1 +18427 4 2 9861 7 0 1 +18433 1 18428 1 +18433 2 5 18432 1 +18433 3 18428 5 0 1 +18433 4 5 15443 6 0 1 +18439 1 18436 1 +18439 2 3 18437 1 +18439 3 18436 5 0 1 +18439 4 3 18435 4 0 1 +18443 1 18441 1 +18443 2 2 18442 1 +18443 3 18441 2 0 1 +18443 4 2 14970 2 0 1 +18451 1 18448 1 +18451 2 3 18440 1 +18451 3 18448 3 0 1 +18451 4 3 17314 0 0 1 +18457 1 18452 1 +18457 2 5 18456 1 +18457 3 18452 2 0 1 +18457 4 5 10609 6 0 1 +18461 1 18459 1 +18461 2 2 18453 1 +18461 3 18459 7 0 1 +18461 4 2 17838 0 0 1 +18481 1 18468 1 +18481 2 13 18478 1 +18481 3 18468 4 0 1 +18481 4 13 15261 16 0 1 +18493 1 18491 1 +18493 2 2 18492 1 +18493 3 18491 4 0 1 +18493 4 2 11729 3 0 1 +18503 1 18498 1 +18503 2 5 18501 1 +18503 3 18498 5 0 1 +18503 4 5 14477 5 0 1 +18517 1 18511 1 +18517 2 6 18515 1 +18517 3 18511 4 0 1 +18517 4 6 12181 4 0 1 +18521 1 18518 1 +18521 2 3 18515 1 +18521 3 18518 6 0 1 +18521 4 3 18509 0 0 1 +18523 1 18520 1 +18523 2 3 18522 1 +18523 3 18520 6 0 1 +18523 4 3 13398 2 0 1 +18539 1 18533 1 +18539 2 6 18537 1 +18539 3 18533 4 0 1 +18539 4 6 15012 5 0 1 +18541 1 18535 1 +18541 2 6 18537 1 +18541 3 18535 2 0 1 +18541 4 6 10978 2 0 1 +18553 1 18548 1 +18553 2 5 18550 1 +18553 3 18548 7 0 1 +18553 4 5 9961 10 0 1 +18583 1 18580 1 +18583 2 3 18581 1 +18583 3 18580 4 0 1 +18583 4 3 18575 10 0 1 +18587 1 18585 1 +18587 2 2 18583 1 +18587 3 18585 3 0 1 +18587 4 2 13034 7 0 1 +18593 1 18590 1 +18593 2 3 18587 1 +18593 3 18590 12 0 1 +18593 4 3 16589 9 0 1 +18617 1 18614 1 +18617 2 3 18610 1 +18617 3 18614 6 0 1 +18617 4 3 12761 1 0 1 +18637 1 18635 1 +18637 2 2 18636 1 +18637 3 18635 2 0 1 +18637 4 2 18630 8 0 1 +18661 1 18651 1 +18661 2 10 18660 1 +18661 3 18651 2 0 1 +18661 4 10 13839 3 0 1 +18671 1 18664 1 +18671 2 7 18670 1 +18671 3 18664 1 0 1 +18671 4 7 10586 3 0 1 +18679 1 18673 1 +18679 2 6 18677 1 +18679 3 18673 3 0 1 +18679 4 6 17207 3 0 1 +18691 1 18688 1 +18691 2 3 18690 1 +18691 3 18688 3 0 1 +18691 4 3 16159 2 0 1 +18701 1 18699 1 +18701 2 2 18693 1 +18701 3 18699 2 0 1 +18701 4 2 10844 0 0 1 +18713 1 18710 1 +18713 2 3 18712 1 +18713 3 18710 10 0 1 +18713 4 3 17106 6 0 1 +18719 1 18712 1 +18719 2 7 18717 1 +18719 3 18712 2 0 1 +18719 4 7 11067 5 0 1 +18731 1 18729 1 +18731 2 2 18727 1 +18731 3 18729 3 0 1 +18731 4 2 18494 7 0 1 +18743 1 18738 1 +18743 2 5 18738 1 +18743 3 18738 1 0 1 +18743 4 5 16527 7 0 1 +18749 1 18747 1 +18749 2 2 18742 1 +18749 3 18747 5 0 1 +18749 4 2 17743 17 0 1 +18757 1 18755 1 +18757 2 2 18753 1 +18757 3 18755 6 0 1 +18757 4 2 10613 6 0 1 +18773 1 18771 1 +18773 2 2 18768 1 +18773 3 18771 3 0 1 +18773 4 2 10974 12 0 1 +18787 1 18785 1 +18787 2 2 18786 1 +18787 3 18785 2 0 1 +18787 4 2 16032 12 0 1 +18793 1 18788 1 +18793 2 5 18792 1 +18793 3 18788 13 0 1 +18793 4 5 14561 6 0 1 +18797 1 18794 1 +18797 2 3 18795 1 +18797 3 18794 1 0 1 +18797 4 3 18793 4 0 1 +18803 1 18798 1 +18803 2 5 18802 1 +18803 3 18798 2 0 1 +18803 4 5 16948 5 0 1 +18839 1 18832 1 +18839 2 7 18838 1 +18839 3 18832 1 0 1 +18839 4 7 14835 2 0 1 +18859 1 18857 1 +18859 2 2 18855 1 +18859 3 18857 2 0 1 +18859 4 2 10191 8 0 1 +18869 1 18867 1 +18869 2 2 18861 1 +18869 3 18867 2 0 1 +18869 4 2 15316 0 0 1 +18899 1 18897 1 +18899 2 2 18895 1 +18899 3 18897 3 0 1 +18899 4 2 15825 7 0 1 +18911 1 18897 1 +18911 2 14 18905 1 +18911 3 18897 7 0 1 +18911 4 14 17681 7 0 1 +18913 1 18906 1 +18913 2 7 18910 1 +18913 3 18906 1 0 1 +18913 4 7 10361 10 0 1 +18917 1 18915 1 +18917 2 2 18916 1 +18917 3 18915 2 0 1 +18917 4 2 16591 3 0 1 +18919 1 18916 1 +18919 2 3 18918 1 +18919 3 18916 3 0 1 +18919 4 3 16302 2 0 1 +18947 1 18945 1 +18947 2 2 18946 1 +18947 3 18945 2 0 1 +18947 4 2 15044 4 0 1 +18959 1 18946 1 +18959 2 13 18958 1 +18959 3 18946 3 0 1 +18959 4 13 11516 2 0 1 +18973 1 18971 1 +18973 2 2 18972 1 +18973 3 18971 4 0 1 +18973 4 2 15546 7 0 1 +18979 1 18977 1 +18979 2 2 18975 1 +18979 3 18977 2 0 1 +18979 4 2 10202 8 0 1 +19001 1 18998 1 +19001 2 3 18995 1 +19001 3 18998 3 0 1 +19001 4 3 18989 0 0 1 +19009 1 18986 1 +19009 2 23 19006 1 +19009 3 18986 1 0 1 +19009 4 23 15317 20 0 1 +19013 1 19011 1 +19013 2 2 19008 1 +19013 3 19011 5 0 1 +19013 4 2 10213 2 0 1 +19031 1 19020 1 +19031 2 11 19029 1 +19031 3 19020 2 0 1 +19031 4 11 16760 3 0 1 +19037 1 19035 1 +19037 2 2 19033 1 +19037 3 19035 3 0 1 +19037 4 2 16206 6 0 1 +19051 1 19049 1 +19051 2 2 19047 1 +19051 3 19049 2 0 1 +19051 4 2 18812 8 0 1 +19069 1 19067 1 +19069 2 2 19064 1 +19069 3 19067 2 0 1 +19069 4 2 10991 7 0 1 +19073 1 19070 1 +19073 2 3 19068 1 +19073 3 19070 3 0 1 +19073 4 3 15571 0 0 1 +19079 1 19072 1 +19079 2 7 19077 1 +19079 3 19072 5 0 1 +19079 4 7 10494 4 0 1 +19081 1 19064 1 +19081 2 17 19080 1 +19081 3 19064 3 0 1 +19081 4 17 18602 8 0 1 +19087 1 19068 1 +19087 2 19 19085 1 +19087 3 19068 1 0 1 +19087 4 19 15189 18 0 1 +19121 1 19115 1 +19121 2 6 19118 1 +19121 3 19115 4 0 1 +19121 4 6 12575 0 0 1 +19139 1 19137 1 +19139 2 2 19135 1 +19139 3 19137 3 0 1 +19139 4 2 18536 8 0 1 +19141 1 19139 1 +19141 2 2 19140 1 +19141 3 19139 4 0 1 +19141 4 2 9820 7 0 1 +19157 1 19155 1 +19157 2 2 19156 1 +19157 3 19155 3 0 1 +19157 4 2 12944 3 0 1 +19163 1 19161 1 +19163 2 2 19159 1 +19163 3 19161 3 0 1 +19163 4 2 16983 7 0 1 +19181 1 19179 1 +19181 2 2 19177 1 +19181 3 19179 3 0 1 +19181 4 2 13168 6 0 1 +19183 1 19180 1 +19183 2 3 19182 1 +19183 3 19180 1 0 1 +19183 4 3 10706 2 0 1 +19207 1 19202 1 +19207 2 5 19205 1 +19207 3 19202 3 0 1 +19207 4 5 17416 9 0 1 +19211 1 19205 1 +19211 2 6 19208 1 +19211 3 19205 3 0 1 +19211 4 6 17571 7 0 1 +19213 1 19208 1 +19213 2 5 19210 1 +19213 3 19208 1 0 1 +19213 4 5 13122 1 0 1 +19219 1 19217 1 +19219 2 2 19210 1 +19219 3 19217 5 0 1 +19219 4 2 15652 2 0 1 +19231 1 19225 1 +19231 2 6 19229 1 +19231 3 19225 2 0 1 +19231 4 6 13006 10 0 1 +19237 1 19235 1 +19237 2 2 19233 1 +19237 3 19235 4 0 1 +19237 4 2 10465 6 0 1 +19249 1 19242 1 +19249 2 7 19242 1 +19249 3 19242 1 0 1 +19249 4 7 10637 0 0 1 +19259 1 19257 1 +19259 2 2 19255 1 +19259 3 19257 3 0 1 +19259 4 2 18438 7 0 1 +19267 1 19264 1 +19267 2 3 19266 1 +19267 3 19264 1 0 1 +19267 4 3 11639 5 0 1 +19273 1 19268 1 +19273 2 5 19268 1 +19273 3 19268 5 0 1 +19273 4 5 13201 18 0 1 +19289 1 19286 1 +19289 2 3 19276 1 +19289 3 19286 5 0 1 +19289 4 3 14941 1 0 1 +19301 1 19299 1 +19301 2 2 19297 1 +19301 3 19299 2 0 1 +19301 4 2 16927 6 0 1 +19309 1 19303 1 +19309 2 6 19305 1 +19309 3 19303 4 0 1 +19309 4 6 18808 2 0 1 +19319 1 19308 1 +19319 2 11 19318 1 +19319 3 19308 4 0 1 +19319 4 11 18667 3 0 1 +19333 1 19331 1 +19333 2 2 19332 1 +19333 3 19331 4 0 1 +19333 4 2 9822 3 0 1 +19373 1 19371 1 +19373 2 2 19358 1 +19373 3 19371 4 0 1 +19373 4 2 13948 1 0 1 +19379 1 19377 1 +19379 2 2 19378 1 +19379 3 19377 3 0 1 +19379 4 2 10801 4 0 1 +19381 1 19374 1 +19381 2 7 19379 1 +19381 3 19374 2 0 1 +19381 4 7 12050 4 0 1 +19387 1 19385 1 +19387 2 2 19383 1 +19387 3 19385 4 0 1 +19387 4 2 13594 10 0 1 +19391 1 19380 1 +19391 2 11 19389 1 +19391 3 19380 4 0 1 +19391 4 11 11000 6 0 1 +19403 1 19401 1 +19403 2 2 19402 1 +19403 3 19401 2 0 1 +19403 4 2 10684 2 0 1 +19417 1 19412 1 +19417 2 5 19416 1 +19417 3 19412 1 0 1 +19417 4 5 15493 6 0 1 +19421 1 19418 1 +19421 2 3 19412 1 +19421 3 19418 4 0 1 +19421 4 3 13945 1 0 1 +19423 1 19420 1 +19423 2 3 19422 1 +19423 3 19420 1 0 1 +19423 4 3 14877 5 0 1 +19427 1 19425 1 +19427 2 2 19423 1 +19427 3 19425 3 0 1 +19427 4 2 11849 20 0 1 +19429 1 19423 1 +19429 2 6 19421 1 +19429 3 19423 9 0 1 +19429 4 6 11211 0 0 1 +19433 1 19430 1 +19433 2 3 19428 1 +19433 3 19430 1 0 1 +19433 4 3 13274 0 0 1 +19441 1 19428 1 +19441 2 13 19440 1 +19441 3 19428 2 0 1 +19441 4 13 14039 14 0 1 +19447 1 19444 1 +19447 2 3 19446 1 +19447 3 19444 9 0 1 +19447 4 3 18565 5 0 1 +19457 1 19454 1 +19457 2 3 19450 1 +19457 3 19454 1 0 1 +19457 4 3 19115 1 0 1 +19463 1 19458 1 +19463 2 5 19455 1 +19463 3 19458 9 0 1 +19463 4 5 16645 3 0 1 +19469 1 19467 1 +19469 2 2 19465 1 +19469 3 19467 2 0 1 +19469 4 2 16973 12 0 1 +19471 1 19460 1 +19471 2 11 19469 1 +19471 3 19460 8 0 1 +19471 4 11 14971 6 0 1 +19477 1 19471 1 +19477 2 6 19476 1 +19477 3 19471 3 0 1 +19477 4 6 14529 6 0 1 +19483 1 19481 1 +19483 2 2 19479 1 +19483 3 19481 4 0 1 +19483 4 2 15277 20 0 1 +19489 1 19470 1 +19489 2 19 19484 1 +19489 3 19470 2 0 1 +19489 4 19 14131 22 0 1 +19501 1 19499 1 +19501 2 2 19500 1 +19501 3 19499 6 0 1 +19501 4 2 16335 7 0 1 +19507 1 19505 1 +19507 2 2 19506 1 +19507 3 19505 2 0 1 +19507 4 2 17426 2 0 1 +19531 1 19518 1 +19531 2 13 19527 1 +19531 3 19518 2 0 1 +19531 4 13 19519 8 0 1 +19541 1 19539 1 +19541 2 2 19537 1 +19541 3 19539 3 0 1 +19541 4 2 14530 12 0 1 +19543 1 19540 1 +19543 2 3 19542 1 +19543 3 19540 1 0 1 +19543 4 3 13152 2 0 1 +19553 1 19550 1 +19553 2 3 19552 1 +19553 3 19550 8 0 1 +19553 4 3 14809 4 0 1 +19559 1 19546 1 +19559 2 13 19557 1 +19559 3 19546 2 0 1 +19559 4 13 17030 3 0 1 +19571 1 19569 1 +19571 2 2 19567 1 +19571 3 19569 3 0 1 +19571 4 2 11687 9 0 1 +19577 1 19574 1 +19577 2 3 19576 1 +19577 3 19574 4 0 1 +19577 4 3 17994 4 0 1 +19583 1 19578 1 +19583 2 5 19582 1 +19583 3 19578 1 0 1 +19583 4 5 19041 2 0 1 +19597 1 19595 1 +19597 2 2 19593 1 +19597 3 19595 6 0 1 +19597 4 2 18971 12 0 1 +19603 1 19601 1 +19603 2 2 19602 1 +19603 3 19601 2 0 1 +19603 4 2 19596 8 0 1 +19609 1 19596 1 +19609 2 13 19596 1 +19609 3 19596 4 0 1 +19609 4 13 19570 0 0 1 +19661 1 19659 1 +19661 2 2 19660 1 +19661 3 19659 5 0 1 +19661 4 2 17605 4 0 1 +19681 1 19670 1 +19681 2 11 19680 1 +19681 3 19670 4 0 1 +19681 4 11 14428 30 0 1 +19687 1 19682 1 +19687 2 5 19686 1 +19687 3 19682 2 0 1 +19687 4 5 11861 2 0 1 +19697 1 19694 1 +19697 2 3 19696 1 +19697 3 19694 3 0 1 +19697 4 3 19300 4 0 1 +19699 1 19692 1 +19699 2 7 19697 1 +19699 3 19692 2 0 1 +19699 4 7 12581 6 0 1 +19709 1 19707 1 +19709 2 2 19702 1 +19709 3 19707 2 0 1 +19709 4 2 11056 9 0 1 +19717 1 19715 1 +19717 2 2 19716 1 +19717 3 19715 2 0 1 +19717 4 2 10550 6 0 1 +19727 1 19722 1 +19727 2 5 19725 1 +19727 3 19722 1 0 1 +19727 4 5 19723 3 0 1 +19739 1 19737 1 +19739 2 2 19738 1 +19739 3 19737 3 0 1 +19739 4 2 13586 2 0 1 +19751 1 19744 1 +19751 2 7 19750 1 +19751 3 19744 5 0 1 +19751 4 7 12836 3 0 1 +19753 1 19748 1 +19753 2 5 19750 1 +19753 3 19748 9 0 1 +19753 4 5 19742 14 0 1 +19759 1 19756 1 +19759 2 3 19757 1 +19759 3 19756 3 0 1 +19759 4 3 11645 3 0 1 +19763 1 19761 1 +19763 2 2 19757 1 +19763 3 19761 4 0 1 +19763 4 2 11361 0 0 1 +19777 1 19766 1 +19777 2 11 19775 1 +19777 3 19766 4 0 1 +19777 4 11 19757 12 0 1 +19793 1 19790 1 +19793 2 3 19788 1 +19793 3 19790 1 0 1 +19793 4 3 16165 2 0 1 +19801 1 19788 1 +19801 2 13 19790 1 +19801 3 19788 5 0 1 +19801 4 13 16129 24 0 1 +19813 1 19811 1 +19813 2 2 19812 1 +19813 3 19811 2 0 1 +19813 4 2 18848 3 0 1 +19819 1 19816 1 +19819 2 3 19818 1 +19819 3 19816 1 0 1 +19819 4 3 16578 2 0 1 +19841 1 19838 1 +19841 2 3 19840 1 +19841 3 19838 1 0 1 +19841 4 3 10211 7 0 1 +19843 1 19824 1 +19843 2 19 19840 1 +19843 3 19824 2 0 1 +19843 4 19 15188 10 0 1 +19853 1 19851 1 +19853 2 2 19848 1 +19853 3 19851 7 0 1 +19853 4 2 15733 0 0 1 +19861 1 19850 1 +19861 2 11 19859 1 +19861 3 19850 4 0 1 +19861 4 11 19546 0 0 1 +19867 1 19865 1 +19867 2 2 19863 1 +19867 3 19865 4 0 1 +19867 4 2 17475 8 0 1 +19889 1 19886 1 +19889 2 3 19883 1 +19889 3 19886 13 0 1 +19889 4 3 19877 0 0 1 +19891 1 19889 1 +19891 2 2 19887 1 +19891 3 19889 2 0 1 +19891 4 2 11654 8 0 1 +19913 1 19910 1 +19913 2 3 19907 1 +19913 3 19910 1 0 1 +19913 4 3 10168 9 0 1 +19919 1 19912 1 +19919 2 7 19918 1 +19919 3 19912 4 0 1 +19919 4 7 11212 6 0 1 +19927 1 19921 1 +19927 2 6 19924 1 +19927 3 19921 7 0 1 +19927 4 6 17010 7 0 1 +19937 1 19934 1 +19937 2 3 19932 1 +19937 3 19934 4 0 1 +19937 4 3 11705 8 0 1 +19949 1 19947 1 +19949 2 2 19948 1 +19949 3 19947 3 0 1 +19949 4 2 18260 3 0 1 +19961 1 19955 1 +19961 2 6 19960 1 +19961 3 19955 1 0 1 +19961 4 6 12333 4 0 1 +19963 1 19961 1 +19963 2 2 19962 1 +19963 3 19961 4 0 1 +19963 4 2 15034 11 0 1 +19973 1 19971 1 +19973 2 2 19969 1 +19973 3 19971 3 0 1 +19973 4 2 10367 7 0 1 +19979 1 19977 1 +19979 2 2 19975 1 +19979 3 19977 2 0 1 +19979 4 2 17346 7 0 1 +19991 1 19980 1 +19991 2 11 19990 1 +19991 3 19980 5 0 1 +19991 4 11 13741 3 0 1 +19993 1 19983 1 +19993 2 10 19990 1 +19993 3 19983 2 0 1 +19993 4 10 10617 8 0 1 +19997 1 19995 1 +19997 2 2 19996 1 +19997 3 19995 2 0 1 +19997 4 2 16717 3 0 1 +20011 1 19999 1 +20011 2 12 20009 1 +20011 3 19999 4 0 1 +20011 4 12 15522 3 0 1 +20021 1 20018 1 +20021 2 3 20019 1 +20021 3 20018 5 0 1 +20021 4 3 20017 4 0 1 +20023 1 20020 1 +20023 2 3 20021 1 +20023 3 20020 3 0 1 +20023 4 3 20019 4 0 1 +20029 1 20027 1 +20029 2 2 20025 1 +20029 3 20027 4 0 1 +20029 4 2 17747 6 0 1 +20047 1 20044 1 +20047 2 3 20045 1 +20047 3 20044 3 0 1 +20047 4 3 10742 6 0 1 +20051 1 20049 1 +20051 2 2 20050 1 +20051 3 20049 4 0 1 +20051 4 2 15376 6 0 1 +20063 1 20058 1 +20063 2 5 20062 1 +20063 3 20058 1 0 1 +20063 4 5 17486 5 0 1 +20071 1 20068 1 +20071 2 3 20070 1 +20071 3 20068 3 0 1 +20071 4 3 13551 3 0 1 +20089 1 20082 1 +20089 2 7 20080 1 +20089 3 20082 2 0 1 +20089 4 7 16179 2 0 1 +20101 1 20095 1 +20101 2 6 20100 1 +20101 3 20095 2 0 1 +20101 4 6 16896 19 0 1 +20107 1 20105 1 +20107 2 2 20106 1 +20107 3 20105 2 0 1 +20107 4 2 20100 8 0 1 +20113 1 20103 1 +20113 2 10 20112 1 +20113 3 20103 5 0 1 +20113 4 10 19737 16 0 1 +20117 1 20115 1 +20117 2 2 20112 1 +20117 3 20115 3 0 1 +20117 4 2 17193 2 0 1 +20123 1 20121 1 +20123 2 2 20122 1 +20123 3 20121 3 0 1 +20123 4 2 20116 8 0 1 +20129 1 20126 1 +20129 2 3 20128 1 +20129 3 20126 3 0 1 +20129 4 3 14233 4 0 1 +20143 1 20138 1 +20143 2 5 20142 1 +20143 3 20138 1 0 1 +20143 4 5 15741 3 0 1 +20147 1 20141 1 +20147 2 6 20138 1 +20147 3 20141 2 0 1 +20147 4 6 16405 2 0 1 +20149 1 20147 1 +20149 2 2 20148 1 +20149 3 20147 6 0 1 +20149 4 2 11354 3 0 1 +20161 1 20148 1 +20161 2 13 20158 1 +20161 3 20148 7 0 1 +20161 4 13 10924 22 0 1 +20173 1 20171 1 +20173 2 2 20172 1 +20173 3 20171 5 0 1 +20173 4 2 12648 3 0 1 +20177 1 20174 1 +20177 2 3 20171 1 +20177 3 20174 14 0 1 +20177 4 3 12724 9 0 1 +20183 1 20178 1 +20183 2 5 20175 1 +20183 3 20178 2 0 1 +20183 4 5 19020 1 0 1 +20201 1 20195 1 +20201 2 6 20195 1 +20201 3 20195 2 0 1 +20201 4 6 15004 0 0 1 +20219 1 20217 1 +20219 2 2 20218 1 +20219 3 20217 3 0 1 +20219 4 2 11006 2 0 1 +20231 1 20202 1 +20231 2 29 20230 1 +20231 3 20202 6 0 1 +20231 4 29 19120 3 0 1 +20233 1 20228 1 +20233 2 5 20228 1 +20233 3 20228 1 0 1 +20233 4 5 16403 10 0 1 +20249 1 20246 1 +20249 2 3 20243 1 +20249 3 20246 1 0 1 +20249 4 3 20237 0 0 1 +20261 1 20259 1 +20261 2 2 20260 1 +20261 3 20259 4 0 1 +20261 4 2 18378 3 0 1 +20269 1 20267 1 +20269 2 2 20265 1 +20269 3 20267 2 0 1 +20269 4 2 19095 6 0 1 +20287 1 20282 1 +20287 2 5 20286 1 +20287 3 20282 3 0 1 +20287 4 5 11622 3 0 1 +20297 1 20294 1 +20297 2 3 20296 1 +20297 3 20294 4 0 1 +20297 4 3 12438 11 0 1 +20323 1 20321 1 +20323 2 2 20319 1 +20323 3 20321 4 0 1 +20323 4 2 19228 8 0 1 +20327 1 20322 1 +20327 2 5 20325 1 +20327 3 20322 2 0 1 +20327 4 5 20323 3 0 1 +20333 1 20330 1 +20333 2 3 20326 1 +20333 3 20330 11 0 1 +20333 4 3 15379 2 0 1 +20341 1 20339 1 +20341 2 2 20340 1 +20341 3 20339 6 0 1 +20341 4 2 10330 3 0 1 +20347 1 20344 1 +20347 2 3 20346 1 +20347 3 20344 4 0 1 +20347 4 3 11117 2 0 1 +20353 1 20348 1 +20353 2 5 20348 1 +20353 3 20348 2 0 1 +20353 4 5 20106 15 0 1 +20357 1 20355 1 +20357 2 2 20349 1 +20357 3 20355 4 0 1 +20357 4 2 12291 19 0 1 +20359 1 20348 1 +20359 2 11 20356 1 +20359 3 20348 2 0 1 +20359 4 11 19263 4 0 1 +20369 1 20366 1 +20369 2 3 20364 1 +20369 3 20366 4 0 1 +20369 4 3 14324 2 0 1 +20389 1 20383 1 +20389 2 6 20385 1 +20389 3 20383 2 0 1 +20389 4 6 10912 2 0 1 +20393 1 20390 1 +20393 2 3 20392 1 +20393 3 20390 1 0 1 +20393 4 3 12277 7 0 1 +20399 1 20392 1 +20399 2 7 20395 1 +20399 3 20392 7 0 1 +20399 4 7 10542 5 0 1 +20407 1 20402 1 +20407 2 5 20405 1 +20407 3 20402 3 0 1 +20407 4 5 20403 3 0 1 +20411 1 20405 1 +20411 2 6 20410 1 +20411 3 20405 1 0 1 +20411 4 6 10887 5 0 1 +20431 1 20428 1 +20431 2 3 20429 1 +20431 3 20428 13 0 1 +20431 4 3 20427 4 0 1 +20441 1 20438 1 +20441 2 3 20435 1 +20441 3 20438 4 0 1 +20441 4 3 20429 0 0 1 +20443 1 20441 1 +20443 2 2 20442 1 +20443 3 20441 2 0 1 +20443 4 2 16404 2 0 1 +20477 1 20475 1 +20477 2 2 20473 1 +20477 3 20475 3 0 1 +20477 4 2 12367 7 0 1 +20479 1 20476 1 +20479 2 3 20478 1 +20479 3 20476 3 0 1 +20479 4 3 16508 2 0 1 +20483 1 20478 1 +20483 2 5 20481 1 +20483 3 20478 6 0 1 +20483 4 5 20479 3 0 1 +20507 1 20505 1 +20507 2 2 20503 1 +20507 3 20505 3 0 1 +20507 4 2 11073 7 0 1 +20509 1 20507 1 +20509 2 2 20505 1 +20509 3 20507 4 0 1 +20509 4 2 11765 6 0 1 +20521 1 20510 1 +20521 2 11 20512 1 +20521 3 20510 6 0 1 +20521 4 11 13028 20 0 1 +20533 1 20531 1 +20533 2 2 20529 1 +20533 3 20531 9 0 1 +20533 4 2 12737 12 0 1 +20543 1 20538 1 +20543 2 5 20532 1 +20543 3 20538 1 0 1 +20543 4 5 12630 6 0 1 +20549 1 20547 1 +20549 2 2 20545 1 +20549 3 20547 3 0 1 +20549 4 2 12215 12 0 1 +20551 1 20548 1 +20551 2 3 20549 1 +20551 3 20548 1 0 1 +20551 4 3 11603 3 0 1 +20563 1 20560 1 +20563 2 3 20548 1 +20563 3 20560 1 0 1 +20563 4 3 13174 3 0 1 +20593 1 20588 1 +20593 2 5 20586 1 +20593 3 20588 1 0 1 +20593 4 5 10926 12 0 1 +20599 1 20596 1 +20599 2 3 20598 1 +20599 3 20596 1 0 1 +20599 4 3 20396 2 0 1 +20611 1 20609 1 +20611 2 2 20610 1 +20611 3 20609 4 0 1 +20611 4 2 19726 2 0 1 +20627 1 20625 1 +20627 2 2 20626 1 +20627 3 20625 3 0 1 +20627 4 2 11219 2 0 1 +20639 1 20628 1 +20639 2 11 20636 1 +20639 3 20628 8 0 1 +20639 4 11 19354 6 0 1 +20641 1 20634 1 +20641 2 7 20634 1 +20641 3 20634 2 0 1 +20641 4 7 17957 0 0 1 +20663 1 20658 1 +20663 2 5 20655 1 +20663 3 20658 2 0 1 +20663 4 5 14980 3 0 1 +20681 1 20678 1 +20681 2 3 20676 1 +20681 3 20678 3 0 1 +20681 4 3 11466 2 0 1 +20693 1 20691 1 +20693 2 2 20689 1 +20693 3 20691 3 0 1 +20693 4 2 11356 9 0 1 +20707 1 20702 1 +20707 2 5 20705 1 +20707 3 20702 3 0 1 +20707 4 5 20703 3 0 1 +20717 1 20715 1 +20717 2 2 20713 1 +20717 3 20715 3 0 1 +20717 4 2 19390 6 0 1 +20719 1 20716 1 +20719 2 3 20718 1 +20719 3 20716 3 0 1 +20719 4 3 16971 3 0 1 +20731 1 20729 1 +20731 2 2 20727 1 +20731 3 20729 2 0 1 +20731 4 2 15429 8 0 1 +20743 1 20738 1 +20743 2 5 20742 1 +20743 3 20738 5 0 1 +20743 4 5 13294 5 0 1 +20747 1 20742 1 +20747 2 5 20746 1 +20747 3 20742 3 0 1 +20747 4 5 19111 8 0 1 +20749 1 20747 1 +20749 2 2 20745 1 +20749 3 20747 4 0 1 +20749 4 2 16542 10 0 1 +20753 1 20750 1 +20753 2 3 20748 1 +20753 3 20750 3 0 1 +20753 4 3 15131 0 0 1 +20759 1 20752 1 +20759 2 7 20758 1 +20759 3 20752 8 0 1 +20759 4 7 17518 2 0 1 +20771 1 20769 1 +20771 2 2 20767 1 +20771 3 20769 3 0 1 +20771 4 2 10858 8 0 1 +20773 1 20771 1 +20773 2 2 20769 1 +20773 3 20771 4 0 1 +20773 4 2 11356 10 0 1 +20789 1 20787 1 +20789 2 2 20785 1 +20789 3 20787 3 0 1 +20789 4 2 15511 1 0 1 +20807 1 20802 1 +20807 2 5 20805 1 +20807 3 20802 7 0 1 +20807 4 5 20803 3 0 1 +20809 1 20802 1 +20809 2 7 20802 1 +20809 3 20802 2 0 1 +20809 4 7 17529 0 0 1 +20849 1 20846 1 +20849 2 3 20843 1 +20849 3 20846 11 0 1 +20849 4 3 20837 0 0 1 +20857 1 20847 1 +20857 2 10 20856 1 +20857 3 20847 5 0 1 +20857 4 10 18094 14 0 1 +20873 1 20870 1 +20873 2 3 20868 1 +20873 3 20870 4 0 1 +20873 4 3 19344 0 0 1 +20879 1 20868 1 +20879 2 11 20877 1 +20879 3 20868 1 0 1 +20879 4 11 12172 7 0 1 +20887 1 20884 1 +20887 2 3 20885 1 +20887 3 20884 1 0 1 +20887 4 3 17620 6 0 1 +20897 1 20894 1 +20897 2 3 20892 1 +20897 3 20894 4 0 1 +20897 4 3 18719 0 0 1 +20899 1 20897 1 +20899 2 2 20895 1 +20899 3 20897 2 0 1 +20899 4 2 11108 8 0 1 +20903 1 20898 1 +20903 2 5 20901 1 +20903 3 20898 1 0 1 +20903 4 5 20899 3 0 1 +20921 1 20918 1 +20921 2 3 20915 1 +20921 3 20918 4 0 1 +20921 4 3 20909 0 0 1 +20929 1 20922 1 +20929 2 7 20926 1 +20929 3 20922 3 0 1 +20929 4 7 15261 14 0 1 +20939 1 20937 1 +20939 2 2 20928 1 +20939 3 20937 10 0 1 +20939 4 2 12137 3 0 1 +20947 1 20944 1 +20947 2 3 20940 1 +20947 3 20944 1 0 1 +20947 4 3 17590 8 0 1 +20959 1 20952 1 +20959 2 7 20948 1 +20959 3 20952 3 0 1 +20959 4 7 18067 0 0 1 +20963 1 20961 1 +20963 2 2 20962 1 +20963 3 20961 2 0 1 +20963 4 2 20712 17 0 1 +20981 1 20979 1 +20981 2 2 20977 1 +20981 3 20979 2 0 1 +20981 4 2 17538 6 0 1 +20983 1 20980 1 +20983 2 3 20982 1 +20983 3 20980 4 0 1 +20983 4 3 10920 2 0 1 +21001 1 20990 1 +21001 2 11 20992 1 +21001 3 20990 2 0 1 +21001 4 11 11284 20 0 1 +21011 1 21009 1 +21011 2 2 21004 1 +21011 3 21009 2 0 1 +21011 4 2 12497 1 0 1 +21013 1 21011 1 +21013 2 2 21012 1 +21013 3 21011 2 0 1 +21013 4 2 15841 6 0 1 +21017 1 21014 1 +21017 2 3 21011 1 +21017 3 21014 5 0 1 +21017 4 3 12444 11 0 1 +21019 1 21017 1 +21019 2 2 21018 1 +21019 3 21017 6 0 1 +21019 4 2 17038 6 0 1 +21023 1 21018 1 +21023 2 5 21020 1 +21023 3 21018 3 0 1 +21023 4 5 18234 4 0 1 +21031 1 21019 1 +21031 2 12 21030 1 +21031 3 21019 1 0 1 +21031 4 12 11608 2 0 1 +21059 1 21057 1 +21059 2 2 21058 1 +21059 3 21057 3 0 1 +21059 4 2 17715 2 0 1 +21061 1 21054 1 +21061 2 7 21059 1 +21061 3 21054 1 0 1 +21061 4 7 14335 4 0 1 +21067 1 21065 1 +21067 2 2 21063 1 +21067 3 21065 5 0 1 +21067 4 2 16954 8 0 1 +21089 1 21086 1 +21089 2 3 21079 1 +21089 3 21086 6 0 1 +21089 4 3 11010 4 0 1 +21101 1 21099 1 +21101 2 2 21100 1 +21101 3 21099 3 0 1 +21101 4 2 12337 9 0 1 +21107 1 21105 1 +21107 2 2 21102 1 +21107 3 21105 10 0 1 +21107 4 2 18689 0 0 1 +21121 1 21102 1 +21121 2 19 21109 1 +21121 3 21102 7 0 1 +21121 4 19 11023 50 0 1 +21139 1 21137 1 +21139 2 2 21138 1 +21139 3 21137 7 0 1 +21139 4 2 13810 7 0 1 +21143 1 21133 1 +21143 2 10 21139 1 +21143 3 21133 3 0 1 +21143 4 10 16832 5 0 1 +21149 1 21146 1 +21149 2 3 21147 1 +21149 3 21146 6 0 1 +21149 4 3 21141 10 0 1 +21157 1 21155 1 +21157 2 2 21156 1 +21157 3 21155 4 0 1 +21157 4 2 13289 7 0 1 +21163 1 21161 1 +21163 2 2 21159 1 +21163 3 21161 4 0 1 +21163 4 2 11414 8 0 1 +21169 1 21156 1 +21169 2 13 21156 1 +21169 3 21156 1 0 1 +21169 4 13 21130 0 0 1 +21179 1 21177 1 +21179 2 2 21175 1 +21179 3 21177 2 0 1 +21179 4 2 13268 7 0 1 +21187 1 21185 1 +21187 2 2 21186 1 +21187 3 21185 2 0 1 +21187 4 2 18507 2 0 1 +21191 1 21184 1 +21191 2 7 21190 1 +21191 3 21184 2 0 1 +21191 4 7 20985 3 0 1 +21193 1 21182 1 +21193 2 11 21192 1 +21193 3 21182 4 0 1 +21193 4 11 13689 6 0 1 +21211 1 21209 1 +21211 2 2 21207 1 +21211 3 21209 6 0 1 +21211 4 2 20728 8 0 1 +21221 1 21219 1 +21221 2 2 21217 1 +21221 3 21219 3 0 1 +21221 4 2 18148 6 0 1 +21227 1 21225 1 +21227 2 2 21226 1 +21227 3 21225 3 0 1 +21227 4 2 15984 13 0 1 +21247 1 21244 1 +21247 2 3 21246 1 +21247 3 21244 7 0 1 +21247 4 3 14636 23 0 1 +21269 1 21267 1 +21269 2 2 21265 1 +21269 3 21267 3 0 1 +21269 4 2 13497 1 0 1 +21277 1 21271 1 +21277 2 6 21275 1 +21277 3 21271 1 0 1 +21277 4 6 11311 8 0 1 +21283 1 21272 1 +21283 2 11 21281 1 +21283 3 21272 1 0 1 +21283 4 11 21030 6 0 1 +21313 1 21308 1 +21313 2 5 21312 1 +21313 3 21308 2 0 1 +21313 4 5 11188 6 0 1 +21317 1 21315 1 +21317 2 2 21310 1 +21317 3 21315 5 0 1 +21317 4 2 17994 4 0 1 +21319 1 21305 1 +21319 2 14 21317 1 +21319 3 21305 2 0 1 +21319 4 14 11947 4 0 1 +21323 1 21318 1 +21323 2 5 21321 1 +21323 3 21318 3 0 1 +21323 4 5 15462 0 0 1 +21341 1 21339 1 +21341 2 2 21340 1 +21341 3 21339 3 0 1 +21341 4 2 11664 4 0 1 +21347 1 21345 1 +21347 2 2 21343 1 +21347 3 21345 3 0 1 +21347 4 2 19528 7 0 1 +21377 1 21374 1 +21377 2 3 21369 1 +21377 3 21374 1 0 1 +21377 4 3 20407 2 0 1 +21379 1 21377 1 +21379 2 2 21375 1 +21379 3 21377 2 0 1 +21379 4 2 10816 8 0 1 +21383 1 21378 1 +21383 2 5 21382 1 +21383 3 21378 2 0 1 +21383 4 5 11578 4 0 1 +21391 1 21385 1 +21391 2 6 21389 1 +21391 3 21385 7 0 1 +21391 4 6 17645 3 0 1 +21397 1 21395 1 +21397 2 2 21396 1 +21397 3 21395 2 0 1 +21397 4 2 16917 3 0 1 +21401 1 21398 1 +21401 2 3 21394 1 +21401 3 21398 1 0 1 +21401 4 3 17194 1 0 1 +21407 1 21402 1 +21407 2 5 21406 1 +21407 3 21402 9 0 1 +21407 4 5 15684 2 0 1 +21419 1 21417 1 +21419 2 2 21415 1 +21419 3 21417 3 0 1 +21419 4 2 15943 7 0 1 +21433 1 21428 1 +21433 2 5 21428 1 +21433 3 21428 6 0 1 +21433 4 5 18101 19 0 1 +21467 1 21465 1 +21467 2 2 21466 1 +21467 3 21465 2 0 1 +21467 4 2 15783 4 0 1 +21481 1 21468 1 +21481 2 13 21480 1 +21481 3 21468 1 0 1 +21481 4 13 11187 14 0 1 +21487 1 21484 1 +21487 2 3 21485 1 +21487 3 21484 4 0 1 +21487 4 3 20081 6 0 1 +21491 1 21489 1 +21491 2 2 21486 1 +21491 3 21489 2 0 1 +21491 4 2 17541 3 0 1 +21493 1 21491 1 +21493 2 2 21492 1 +21493 3 21491 2 0 1 +21493 4 2 15459 3 0 1 +21499 1 21496 1 +21499 2 3 21492 1 +21499 3 21496 3 0 1 +21499 4 3 13890 5 0 1 +21503 1 21498 1 +21503 2 5 21502 1 +21503 3 21498 2 0 1 +21503 4 5 14072 4 0 1 +21517 1 21512 1 +21517 2 5 21512 1 +21517 3 21512 3 0 1 +21517 4 5 16883 7 0 1 +21521 1 21518 1 +21521 2 3 21516 1 +21521 3 21518 3 0 1 +21521 4 3 15845 2 0 1 +21523 1 21521 1 +21523 2 2 21522 1 +21523 3 21521 2 0 1 +21523 4 2 20994 7 0 1 +21529 1 21518 1 +21529 2 11 21528 1 +21529 3 21518 3 0 1 +21529 4 11 15558 20 0 1 +21557 1 21555 1 +21557 2 2 21553 1 +21557 3 21555 11 0 1 +21557 4 2 12548 7 0 1 +21559 1 21544 1 +21559 2 15 21554 1 +21559 3 21544 4 0 1 +21559 4 15 16632 2 0 1 +21563 1 21561 1 +21563 2 2 21562 1 +21563 3 21561 2 0 1 +21563 4 2 21556 8 0 1 +21569 1 21566 1 +21569 2 3 21564 1 +21569 3 21566 5 0 1 +21569 4 3 19927 2 0 1 +21577 1 21572 1 +21577 2 5 21576 1 +21577 3 21572 3 0 1 +21577 4 5 12406 6 0 1 +21587 1 21585 1 +21587 2 2 21586 1 +21587 3 21585 3 0 1 +21587 4 2 15908 10 0 1 +21589 1 21587 1 +21589 2 2 21585 1 +21589 3 21587 2 0 1 +21589 4 2 12637 12 0 1 +21599 1 21592 1 +21599 2 7 21598 1 +21599 3 21592 8 0 1 +21599 4 7 15458 2 0 1 +21601 1 21594 1 +21601 2 7 21594 1 +21601 3 21594 11 0 1 +21601 4 7 18308 0 0 1 +21611 1 21609 1 +21611 2 2 21607 1 +21611 3 21609 3 0 1 +21611 4 2 21023 8 0 1 +21613 1 21611 1 +21613 2 2 21609 1 +21613 3 21611 5 0 1 +21613 4 2 21319 6 0 1 +21617 1 21614 1 +21617 2 3 21612 1 +21617 3 21614 1 0 1 +21617 4 3 20609 0 0 1 +21647 1 21642 1 +21647 2 5 21644 1 +21647 3 21642 6 0 1 +21647 4 5 13870 4 0 1 +21649 1 21635 1 +21649 2 14 21646 1 +21649 3 21635 2 0 1 +21649 4 14 10990 10 0 1 +21661 1 21659 1 +21661 2 2 21660 1 +21661 3 21659 6 0 1 +21661 4 2 20652 3 0 1 +21673 1 21663 1 +21673 2 10 21672 1 +21673 3 21663 6 0 1 +21673 4 10 11562 21 0 1 +21683 1 21681 1 +21683 2 2 21679 1 +21683 3 21681 3 0 1 +21683 4 2 21428 7 0 1 +21701 1 21699 1 +21701 2 2 21697 1 +21701 3 21699 3 0 1 +21701 4 2 11188 7 0 1 +21713 1 21710 1 +21713 2 3 21706 1 +21713 3 21710 4 0 1 +21713 4 3 11351 0 0 1 +21727 1 21724 1 +21727 2 3 21726 1 +21727 3 21724 3 0 1 +21727 4 3 20947 5 0 1 +21737 1 21731 1 +21737 2 6 21735 1 +21737 3 21731 3 0 1 +21737 4 6 15587 8 0 1 +21739 1 21737 1 +21739 2 2 21735 1 +21739 3 21737 2 0 1 +21739 4 2 20761 8 0 1 +21751 1 21748 1 +21751 2 3 21749 1 +21751 3 21748 8 0 1 +21751 4 3 18831 3 0 1 +21757 1 21752 1 +21757 2 5 21756 1 +21757 3 21752 3 0 1 +21757 4 5 20260 3 0 1 +21767 1 21762 1 +21767 2 5 21766 1 +21767 3 21762 3 0 1 +21767 4 5 11790 3 0 1 +21773 1 21771 1 +21773 2 2 21769 1 +21773 3 21771 2 0 1 +21773 4 2 14021 1 0 1 +21787 1 21764 1 +21787 2 23 21786 1 +21787 3 21764 4 0 1 +21787 4 23 17555 11 0 1 +21799 1 21792 1 +21799 2 7 21788 1 +21799 3 21792 4 0 1 +21799 4 7 12115 5 0 1 +21803 1 21801 1 +21803 2 2 21802 1 +21803 3 21801 2 0 1 +21803 4 2 13905 4 0 1 +21817 1 21810 1 +21817 2 7 21810 1 +21817 3 21810 11 0 1 +21817 4 7 16726 22 0 1 +21821 1 21819 1 +21821 2 2 21817 1 +21821 3 21819 2 0 1 +21821 4 2 15700 6 0 1 +21839 1 21828 1 +21839 2 11 21835 1 +21839 3 21828 5 0 1 +21839 4 11 14928 5 0 1 +21841 1 21830 1 +21841 2 11 21836 1 +21841 3 21830 6 0 1 +21841 4 11 21822 24 0 1 +21851 1 21845 1 +21851 2 6 21849 1 +21851 3 21845 3 0 1 +21851 4 6 15992 0 0 1 +21859 1 21857 1 +21859 2 2 21858 1 +21859 3 21857 6 0 1 +21859 4 2 16731 2 0 1 +21863 1 21858 1 +21863 2 5 21861 1 +21863 3 21858 2 0 1 +21863 4 5 18880 5 0 1 +21871 1 21865 1 +21871 2 6 21870 1 +21871 3 21865 6 0 1 +21871 4 6 17088 2 0 1 +21881 1 21878 1 +21881 2 3 21876 1 +21881 3 21878 1 0 1 +21881 4 3 11106 2 0 1 +21893 1 21891 1 +21893 2 2 21885 1 +21893 3 21891 4 0 1 +21893 4 2 20466 3 0 1 +21911 1 21898 1 +21911 2 13 21910 1 +21911 3 21898 10 0 1 +21911 4 13 16837 2 0 1 +21929 1 21926 1 +21929 2 3 21924 1 +21929 3 21926 3 0 1 +21929 4 3 18844 2 0 1 +21937 1 21930 1 +21937 2 7 21930 1 +21937 3 21930 8 0 1 +21937 4 7 19558 12 0 1 +21943 1 21938 1 +21943 2 5 21941 1 +21943 3 21938 2 0 1 +21943 4 5 21931 11 0 1 +21961 1 21944 1 +21961 2 17 21960 1 +21961 3 21944 15 0 1 +21961 4 17 18877 30 0 1 +21977 1 21974 1 +21977 2 3 21972 1 +21977 3 21974 3 0 1 +21977 4 3 18370 0 0 1 +21991 1 21988 1 +21991 2 3 21990 1 +21991 3 21988 7 0 1 +21991 4 3 17520 3 0 1 +21997 1 21990 1 +21997 2 7 21995 1 +21997 3 21990 2 0 1 +21997 4 7 18589 4 0 1 +22003 1 22001 1 +22003 2 2 21999 1 +22003 3 22001 6 0 1 +22003 4 2 20223 8 0 1 +22013 1 22011 1 +22013 2 2 22012 1 +22013 3 22011 2 0 1 +22013 4 2 11274 3 0 1 +22027 1 22024 1 +22027 2 3 22022 1 +22027 3 22024 6 0 1 +22027 4 3 16824 3 0 1 +22031 1 22024 1 +22031 2 7 22030 1 +22031 3 22024 4 0 1 +22031 4 7 22022 4 0 1 +22037 1 22035 1 +22037 2 2 22033 1 +22037 3 22035 3 0 1 +22037 4 2 19625 7 0 1 +22039 1 22033 1 +22039 2 6 22038 1 +22039 3 22033 1 0 1 +22039 4 6 19033 3 0 1 +22051 1 22048 1 +22051 2 3 22050 1 +22051 3 22048 3 0 1 +22051 4 3 11985 2 0 1 +22063 1 22058 1 +22063 2 5 22061 1 +22063 3 22058 3 0 1 +22063 4 5 20190 9 0 1 +22067 1 22065 1 +22067 2 2 22066 1 +22067 3 22065 2 0 1 +22067 4 2 17808 2 0 1 +22073 1 22070 1 +22073 2 3 22067 1 +22073 3 22070 5 0 1 +22073 4 3 15707 9 0 1 +22079 1 22072 1 +22079 2 7 22075 1 +22079 3 22072 2 0 1 +22079 4 7 13498 12 0 1 +22091 1 22089 1 +22091 2 2 22090 1 +22091 3 22089 3 0 1 +22091 4 2 13125 2 0 1 +22093 1 22087 1 +22093 2 6 22091 1 +22093 3 22087 2 0 1 +22093 4 6 19829 8 0 1 +22109 1 22107 1 +22109 2 2 22103 1 +22109 3 22107 3 0 1 +22109 4 2 18368 3 0 1 +22111 1 22105 1 +22111 2 6 22109 1 +22111 3 22105 2 0 1 +22111 4 6 20781 3 0 1 +22123 1 22121 1 +22123 2 2 22122 1 +22123 3 22121 6 0 1 +22123 4 2 17751 17 0 1 +22129 1 22110 1 +22129 2 19 22124 1 +22129 3 22110 1 0 1 +22129 4 19 14125 16 0 1 +22133 1 22131 1 +22133 2 2 22127 1 +22133 3 22131 8 0 1 +22133 4 2 15963 1 0 1 +22147 1 22142 1 +22147 2 5 22146 1 +22147 3 22142 3 0 1 +22147 4 5 16305 24 0 1 +22153 1 22148 1 +22153 2 5 22152 1 +22153 3 22148 1 0 1 +22153 4 5 11345 6 0 1 +22157 1 22155 1 +22157 2 2 22153 1 +22157 3 22155 8 0 1 +22157 4 2 19121 6 0 1 +22159 1 22153 1 +22159 2 6 22158 1 +22159 3 22153 6 0 1 +22159 4 6 21602 2 0 1 +22171 1 22169 1 +22171 2 2 22167 1 +22171 3 22169 2 0 1 +22171 4 2 16048 8 0 1 +22189 1 22187 1 +22189 2 2 22185 1 +22189 3 22187 4 0 1 +22189 4 2 14003 27 0 1 +22193 1 22190 1 +22193 2 3 22192 1 +22193 3 22190 3 0 1 +22193 4 3 12354 6 0 1 +22229 1 22227 1 +22229 2 2 22221 1 +22229 3 22227 5 0 1 +22229 4 2 15382 0 0 1 +22247 1 22242 1 +22247 2 5 22245 1 +22247 3 22242 5 0 1 +22247 4 5 17628 20 0 1 +22259 1 22257 1 +22259 2 2 22255 1 +22259 3 22257 3 0 1 +22259 4 2 12627 15 0 1 +22271 1 22264 1 +22271 2 7 22270 1 +22271 3 22264 9 0 1 +22271 4 7 12906 2 0 1 +22273 1 22268 1 +22273 2 5 22268 1 +22273 3 22268 5 0 1 +22273 4 5 22062 10 0 1 +22277 1 22275 1 +22277 2 2 22273 1 +22277 3 22275 2 0 1 +22277 4 2 18990 1 0 1 +22279 1 22276 1 +22279 2 3 22277 1 +22279 3 22276 1 0 1 +22279 4 3 15116 6 0 1 +22283 1 22281 1 +22283 2 2 22277 1 +22283 3 22281 4 0 1 +22283 4 2 18879 4 0 1 +22291 1 22288 1 +22291 2 3 22284 1 +22291 3 22288 1 0 1 +22291 4 3 20233 5 0 1 +22303 1 22297 1 +22303 2 6 22300 1 +22303 3 22297 1 0 1 +22303 4 6 19217 4 0 1 +22307 1 22305 1 +22307 2 2 22302 1 +22307 3 22305 12 0 1 +22307 4 2 19485 0 0 1 +22343 1 22338 1 +22343 2 5 22342 1 +22343 3 22338 8 0 1 +22343 4 5 20747 7 0 1 +22349 1 22347 1 +22349 2 2 22340 1 +22349 3 22347 3 0 1 +22349 4 2 12245 1 0 1 +22367 1 22362 1 +22367 2 5 22365 1 +22367 3 22362 3 0 1 +22367 4 5 22363 3 0 1 +22369 1 22358 1 +22369 2 11 22358 1 +22369 3 22358 3 0 1 +22369 4 11 20057 22 0 1 +22381 1 22371 1 +22381 2 10 22378 1 +22381 3 22371 3 0 1 +22381 4 10 20073 9 0 1 +22391 1 22378 1 +22391 2 13 22390 1 +22391 3 22378 1 0 1 +22391 4 13 19015 8 0 1 +22397 1 22395 1 +22397 2 2 22393 1 +22397 3 22395 3 0 1 +22397 4 2 17655 7 0 1 +22409 1 22406 1 +22409 2 3 22408 1 +22409 3 22406 5 0 1 +22409 4 3 11808 7 0 1 +22433 1 22430 1 +22433 2 3 22428 1 +22433 3 22430 1 0 1 +22433 4 3 21207 0 0 1 +22441 1 22427 1 +22441 2 14 22438 1 +22441 3 22427 2 0 1 +22441 4 14 15277 10 0 1 +22447 1 22444 1 +22447 2 3 22446 1 +22447 3 22444 3 0 1 +22447 4 3 16286 5 0 1 +22453 1 22448 1 +22453 2 5 22452 1 +22453 3 22448 2 0 1 +22453 4 5 11570 7 0 1 +22469 1 22467 1 +22469 2 2 22465 1 +22469 3 22467 3 0 1 +22469 4 2 18906 6 0 1 +22481 1 22478 1 +22481 2 3 22480 1 +22481 3 22478 1 0 1 +22481 4 3 20688 7 0 1 +22483 1 22481 1 +22483 2 2 22479 1 +22483 3 22481 2 0 1 +22483 4 2 13033 1 0 1 +22501 1 22499 1 +22501 2 2 22500 1 +22501 3 22499 4 0 1 +22501 4 2 12237 3 0 1 +22511 1 22500 1 +22511 2 11 22510 1 +22511 3 22500 1 0 1 +22511 4 11 19183 5 0 1 +22531 1 22529 1 +22531 2 2 22530 1 +22531 3 22529 4 0 1 +22531 4 2 22271 2 0 1 +22541 1 22538 1 +22541 2 3 22539 1 +22541 3 22538 1 0 1 +22541 4 3 22533 10 0 1 +22543 1 22540 1 +22543 2 3 22541 1 +22543 3 22540 1 0 1 +22543 4 3 20698 6 0 1 +22549 1 22547 1 +22549 2 2 22545 1 +22549 3 22547 2 0 1 +22549 4 2 19242 6 0 1 +22567 1 22564 1 +22567 2 3 22565 1 +22567 3 22564 3 0 1 +22567 4 3 14944 15 0 1 +22571 1 22565 1 +22571 2 6 22569 1 +22571 3 22565 2 0 1 +22571 4 6 22561 7 0 1 +22573 1 22567 1 +22573 2 6 22572 1 +22573 3 22567 7 0 1 +22573 4 6 12988 6 0 1 +22613 1 22611 1 +22613 2 2 22608 1 +22613 3 22611 2 0 1 +22613 4 2 13162 2 0 1 +22619 1 22617 1 +22619 2 2 22612 1 +22619 3 22617 2 0 1 +22619 4 2 19196 0 0 1 +22621 1 22619 1 +22621 2 2 22617 1 +22621 3 22619 2 0 1 +22621 4 2 20510 6 0 1 +22637 1 22635 1 +22637 2 2 22631 1 +22637 3 22635 5 0 1 +22637 4 2 17813 1 0 1 +22639 1 22633 1 +22639 2 6 22638 1 +22639 3 22633 2 0 1 +22639 4 6 22076 2 0 1 +22643 1 22641 1 +22643 2 2 22639 1 +22643 3 22641 2 0 1 +22643 4 2 14386 7 0 1 +22651 1 22648 1 +22651 2 3 22650 1 +22651 3 22648 1 0 1 +22651 4 3 17235 2 0 1 +22669 1 22667 1 +22669 2 2 22668 1 +22669 3 22667 5 0 1 +22669 4 2 15799 7 0 1 +22679 1 22666 1 +22679 2 13 22677 1 +22679 3 22666 1 0 1 +22679 4 13 13290 3 0 1 +22691 1 22689 1 +22691 2 2 22687 1 +22691 3 22689 2 0 1 +22691 4 2 20225 8 0 1 +22697 1 22694 1 +22697 2 3 22691 1 +22697 3 22694 6 0 1 +22697 4 3 22175 1 0 1 +22699 1 22687 1 +22699 2 12 22698 1 +22699 3 22687 1 0 1 +22699 4 12 19604 2 0 1 +22709 1 22707 1 +22709 2 2 22704 1 +22709 3 22707 2 0 1 +22709 4 2 21768 15 0 1 +22717 1 22715 1 +22717 2 2 22713 1 +22717 3 22715 6 0 1 +22717 4 2 22380 6 0 1 +22721 1 22718 1 +22721 2 3 22720 1 +22721 3 22718 5 0 1 +22721 4 3 20033 7 0 1 +22727 1 22722 1 +22727 2 5 22719 1 +22727 3 22722 7 0 1 +22727 4 5 13027 3 0 1 +22739 1 22737 1 +22739 2 2 22738 1 +22739 3 22737 4 0 1 +22739 4 2 12192 4 0 1 +22741 1 22734 1 +22741 2 7 22739 1 +22741 3 22734 2 0 1 +22741 4 7 17229 9 0 1 +22751 1 22730 1 +22751 2 21 22749 1 +22751 3 22730 2 0 1 +22751 4 21 18369 3 0 1 +22769 1 22766 1 +22769 2 3 22768 1 +22769 3 22766 3 0 1 +22769 4 3 16921 7 0 1 +22777 1 22770 1 +22777 2 7 22774 1 +22777 3 22770 2 0 1 +22777 4 7 13091 10 0 1 +22783 1 22780 1 +22783 2 3 22782 1 +22783 3 22780 1 0 1 +22783 4 3 21890 5 0 1 +22787 1 22785 1 +22787 2 2 22783 1 +22787 3 22785 3 0 1 +22787 4 2 11840 7 0 1 +22807 1 22804 1 +22807 2 3 22805 1 +22807 3 22804 4 0 1 +22807 4 3 22803 4 0 1 +22811 1 22805 1 +22811 2 6 22809 1 +22811 3 22805 2 0 1 +22811 4 6 22226 5 0 1 +22817 1 22814 1 +22817 2 3 22811 1 +22817 3 22814 8 0 1 +22817 4 3 12875 1 0 1 +22853 1 22851 1 +22853 2 2 22849 1 +22853 3 22851 2 0 1 +22853 4 2 11699 6 0 1 +22859 1 22857 1 +22859 2 2 22852 1 +22859 3 22857 7 0 1 +22859 4 2 13165 0 0 1 +22861 1 22859 1 +22861 2 2 22860 1 +22861 3 22859 7 0 1 +22861 4 2 11777 7 0 1 +22871 1 22864 1 +22871 2 7 22870 1 +22871 3 22864 4 0 1 +22871 4 7 22862 4 0 1 +22877 1 22875 1 +22877 2 2 22873 1 +22877 3 22875 3 0 1 +22877 4 2 15815 6 0 1 +22901 1 22899 1 +22901 2 2 22897 1 +22901 3 22899 2 0 1 +22901 4 2 22473 7 0 1 +22907 1 22902 1 +22907 2 5 22902 1 +22907 3 22902 3 0 1 +22907 4 5 19319 3 0 1 +22921 1 22914 1 +22921 2 7 22914 1 +22921 3 22914 4 0 1 +22921 4 7 18100 0 0 1 +22937 1 22934 1 +22937 2 3 22936 1 +22937 3 22934 3 0 1 +22937 4 3 12673 6 0 1 +22943 1 22938 1 +22943 2 5 22940 1 +22943 3 22938 2 0 1 +22943 4 5 15087 9 0 1 +22961 1 22955 1 +22961 2 6 22960 1 +22961 3 22955 1 0 1 +22961 4 6 19430 7 0 1 +22963 1 22960 1 +22963 2 3 22962 1 +22963 3 22960 4 0 1 +22963 4 3 12220 2 0 1 +22973 1 22971 1 +22973 2 2 22972 1 +22973 3 22971 3 0 1 +22973 4 2 22634 9 0 1 +22993 1 22988 1 +22993 2 5 22992 1 +22993 3 22988 3 0 1 +22993 4 5 20272 6 0 1 +23003 1 23001 1 +23003 2 2 22993 1 +23003 3 23001 11 0 1 +23003 4 2 18086 2 0 1 +23011 1 23004 1 +23011 2 7 23009 1 +23011 3 23004 5 0 1 +23011 4 7 15883 6 0 1 +23017 1 23012 1 +23017 2 5 23016 1 +23017 3 23012 3 0 1 +23017 4 5 20398 6 0 1 +23021 1 23019 1 +23021 2 2 23020 1 +23021 3 23019 3 0 1 +23021 4 2 21707 4 0 1 +23027 1 23025 1 +23027 2 2 23023 1 +23027 3 23025 3 0 1 +23027 4 2 19504 7 0 1 +23029 1 23027 1 +23029 2 2 23025 1 +23029 3 23027 6 0 1 +23029 4 2 15045 6 0 1 +23039 1 23032 1 +23039 2 7 23038 1 +23039 3 23032 5 0 1 +23039 4 7 16180 10 0 1 +23041 1 23030 1 +23041 2 11 23036 1 +23041 3 23030 1 0 1 +23041 4 11 23022 24 0 1 +23053 1 23051 1 +23053 2 2 23049 1 +23053 3 23051 4 0 1 +23053 4 2 19444 12 0 1 +23057 1 23052 1 +23057 2 5 23050 1 +23057 3 23052 1 0 1 +23057 4 5 16889 1 0 1 +23059 1 23056 1 +23059 2 3 23042 1 +23059 3 23056 4 0 1 +23059 4 3 16809 15 0 1 +23063 1 23058 1 +23063 2 5 23060 1 +23063 3 23058 1 0 1 +23063 4 5 16943 11 0 1 +23071 1 23068 1 +23071 2 3 23069 1 +23071 3 23068 1 0 1 +23071 4 3 17794 6 0 1 +23081 1 23078 1 +23081 2 3 23075 1 +23081 3 23078 1 0 1 +23081 4 3 23069 0 0 1 +23087 1 23082 1 +23087 2 5 23086 1 +23087 3 23082 1 0 1 +23087 4 5 22201 3 0 1 +23099 1 23097 1 +23099 2 2 23098 1 +23099 3 23097 7 0 1 +23099 4 2 16685 12 0 1 +23117 1 23115 1 +23117 2 2 23113 1 +23117 3 23115 3 0 1 +23117 4 2 12190 1 0 1 +23131 1 23128 1 +23131 2 3 23124 1 +23131 3 23128 3 0 1 +23131 4 3 12649 5 0 1 +23143 1 23138 1 +23143 2 5 23141 1 +23143 3 23138 2 0 1 +23143 4 5 23139 3 0 1 +23159 1 23148 1 +23159 2 11 23153 1 +23159 3 23148 1 0 1 +23159 4 11 23155 8 0 1 +23167 1 23164 1 +23167 2 3 23165 1 +23167 3 23164 1 0 1 +23167 4 3 14687 6 0 1 +23173 1 23168 1 +23173 2 5 23172 1 +23173 3 23168 1 0 1 +23173 4 5 21666 6 0 1 +23189 1 23187 1 +23189 2 2 23188 1 +23189 3 23187 3 0 1 +23189 4 2 19547 9 0 1 +23197 1 23195 1 +23197 2 2 23196 1 +23197 3 23195 2 0 1 +23197 4 2 21941 21 0 1 +23201 1 23198 1 +23201 2 3 23200 1 +23201 3 23198 4 0 1 +23201 4 3 19539 7 0 1 +23203 1 23200 1 +23203 2 3 23198 1 +23203 3 23200 4 0 1 +23203 4 3 19660 3 0 1 +23209 1 23178 1 +23209 2 31 23208 1 +23209 3 23178 1 0 1 +23209 4 31 11886 32 0 1 +23227 1 23224 1 +23227 2 3 23226 1 +23227 3 23224 1 0 1 +23227 4 3 13128 5 0 1 +23251 1 23249 1 +23251 2 2 23247 1 +23251 3 23249 5 0 1 +23251 4 2 17091 8 0 1 +23269 1 23263 1 +23269 2 6 23265 1 +23269 3 23263 6 0 1 +23269 4 6 21069 10 0 1 +23279 1 23272 1 +23279 2 7 23278 1 +23279 3 23272 2 0 1 +23279 4 7 22708 6 0 1 +23291 1 23285 1 +23291 2 6 23290 1 +23291 3 23285 1 0 1 +23291 4 6 12883 2 0 1 +23293 1 23288 1 +23293 2 5 23292 1 +23293 3 23288 10 0 1 +23293 4 5 18037 3 0 1 +23297 1 23294 1 +23297 2 3 23296 1 +23297 3 23294 5 0 1 +23297 4 3 14862 18 0 1 +23311 1 23308 1 +23311 2 3 23310 1 +23311 3 23308 5 0 1 +23311 4 3 21212 3 0 1 +23321 1 23318 1 +23321 2 3 23315 1 +23321 3 23318 7 0 1 +23321 4 3 23309 0 0 1 +23327 1 23322 1 +23327 2 5 23325 1 +23327 3 23322 3 0 1 +23327 4 5 21599 10 0 1 +23333 1 23331 1 +23333 2 2 23329 1 +23333 3 23331 3 0 1 +23333 4 2 17585 7 0 1 +23339 1 23337 1 +23339 2 2 23335 1 +23339 3 23337 3 0 1 +23339 4 2 21157 8 0 1 +23357 1 23355 1 +23357 2 2 23356 1 +23357 3 23355 2 0 1 +23357 4 2 14555 6 0 1 +23369 1 23366 1 +23369 2 3 23364 1 +23369 3 23366 1 0 1 +23369 4 3 15507 2 0 1 +23371 1 23369 1 +23371 2 2 23370 1 +23371 3 23369 6 0 1 +23371 4 2 17462 2 0 1 +23399 1 23382 1 +23399 2 17 23397 1 +23399 3 23382 2 0 1 +23399 4 17 23391 3 0 1 +23417 1 23414 1 +23417 2 3 23408 1 +23417 3 23414 1 0 1 +23417 4 3 15219 3 0 1 +23431 1 23428 1 +23431 2 3 23429 1 +23431 3 23428 5 0 1 +23431 4 3 23427 4 0 1 +23447 1 23442 1 +23447 2 5 23444 1 +23447 3 23442 3 0 1 +23447 4 5 18884 6 0 1 +23459 1 23457 1 +23459 2 2 23450 1 +23459 3 23457 2 0 1 +23459 4 2 17342 1 0 1 +23473 1 23468 1 +23473 2 5 23472 1 +23473 3 23468 1 0 1 +23473 4 5 12620 6 0 1 +23497 1 23492 1 +23497 2 5 23496 1 +23497 3 23492 1 0 1 +23497 4 5 23280 6 0 1 +23509 1 23507 1 +23509 2 2 23508 1 +23509 3 23507 4 0 1 +23509 4 2 18922 3 0 1 +23531 1 23529 1 +23531 2 2 23526 1 +23531 3 23529 2 0 1 +23531 4 2 20955 3 0 1 +23537 1 23534 1 +23537 2 3 23536 1 +23537 3 23534 3 0 1 +23537 4 3 20947 6 0 1 +23539 1 23537 1 +23539 2 2 23534 1 +23539 3 23537 6 0 1 +23539 4 2 13023 3 0 1 +23549 1 23547 1 +23549 2 2 23545 1 +23549 3 23547 3 0 1 +23549 4 2 16278 12 0 1 +23557 1 23552 1 +23557 2 5 23554 1 +23557 3 23552 2 0 1 +23557 4 5 13162 9 0 1 +23561 1 23558 1 +23561 2 3 23556 1 +23561 3 23558 3 0 1 +23561 4 3 13414 2 0 1 +23563 1 23561 1 +23563 2 2 23559 1 +23563 3 23561 6 0 1 +23563 4 2 22059 8 0 1 +23567 1 23562 1 +23567 2 5 23562 1 +23567 3 23562 2 0 1 +23567 4 5 15639 6 0 1 +23581 1 23575 1 +23581 2 6 23577 1 +23581 3 23575 9 0 1 +23581 4 6 23577 6 0 1 +23593 1 23588 1 +23593 2 5 23592 1 +23593 3 23588 2 0 1 +23593 4 5 13402 6 0 1 +23599 1 23596 1 +23599 2 3 23597 1 +23599 3 23596 5 0 1 +23599 4 3 23595 4 0 1 +23603 1 23601 1 +23603 2 2 23602 1 +23603 3 23601 2 0 1 +23603 4 2 20737 17 0 1 +23609 1 23603 1 +23609 2 6 23606 1 +23609 3 23603 4 0 1 +23609 4 6 12496 9 0 1 +23623 1 23617 1 +23623 2 6 23620 1 +23623 3 23617 7 0 1 +23623 4 6 20619 5 0 1 +23627 1 23625 1 +23627 2 2 23623 1 +23627 3 23625 3 0 1 +23627 4 2 20095 8 0 1 +23629 1 23627 1 +23629 2 2 23625 1 +23629 3 23627 2 0 1 +23629 4 2 22694 10 0 1 +23633 1 23628 1 +23633 2 5 23628 1 +23633 3 23628 3 0 1 +23633 4 5 22258 8 0 1 +23663 1 23658 1 +23663 2 5 23661 1 +23663 3 23658 1 0 1 +23663 4 5 14091 5 0 1 +23669 1 23667 1 +23669 2 2 23662 1 +23669 3 23667 5 0 1 +23669 4 2 22391 4 0 1 +23671 1 23668 1 +23671 2 3 23670 1 +23671 3 23668 8 0 1 +23671 4 3 13774 2 0 1 +23677 1 23672 1 +23677 2 5 23676 1 +23677 3 23672 3 0 1 +23677 4 5 17965 3 0 1 +23687 1 23682 1 +23687 2 5 23685 1 +23687 3 23682 1 0 1 +23687 4 5 23683 3 0 1 +23689 1 23678 1 +23689 2 11 23684 1 +23689 3 23678 3 0 1 +23689 4 11 17232 16 0 1 +23719 1 23713 1 +23719 2 6 23717 1 +23719 3 23713 1 0 1 +23719 4 6 17194 3 0 1 +23741 1 23739 1 +23741 2 2 23737 1 +23741 3 23739 3 0 1 +23741 4 2 14491 12 0 1 +23743 1 23740 1 +23743 2 3 23738 1 +23743 3 23740 6 0 1 +23743 4 3 12127 6 0 1 +23747 1 23745 1 +23747 2 2 23746 1 +23747 3 23745 2 0 1 +23747 4 2 21173 10 0 1 +23753 1 23750 1 +23753 2 3 23747 1 +23753 3 23750 3 0 1 +23753 4 3 21853 25 0 1 +23761 1 23754 1 +23761 2 7 23754 1 +23761 3 23754 1 0 1 +23761 4 7 13633 0 0 1 +23767 1 23764 1 +23767 2 3 23766 1 +23767 3 23764 3 0 1 +23767 4 3 22423 5 0 1 +23773 1 23768 1 +23773 2 5 23770 1 +23773 3 23768 1 0 1 +23773 4 5 22420 11 0 1 +23789 1 23787 1 +23789 2 2 23788 1 +23789 3 23787 10 0 1 +23789 4 2 20966 3 0 1 +23801 1 23798 1 +23801 2 3 23791 1 +23801 3 23798 1 0 1 +23801 4 3 18160 22 0 1 +23813 1 23811 1 +23813 2 2 23809 1 +23813 3 23811 2 0 1 +23813 4 2 23057 1 0 1 +23819 1 23817 1 +23819 2 2 23811 1 +23819 3 23817 5 0 1 +23819 4 2 19293 2 0 1 +23827 1 23825 1 +23827 2 2 23826 1 +23827 3 23825 2 0 1 +23827 4 2 23820 8 0 1 +23831 1 23820 1 +23831 2 11 23827 1 +23831 3 23820 1 0 1 +23831 4 11 18265 6 0 1 +23833 1 23828 1 +23833 2 5 23830 1 +23833 3 23828 1 0 1 +23833 4 5 23822 14 0 1 +23857 1 23852 1 +23857 2 5 23856 1 +23857 3 23852 2 0 1 +23857 4 5 13498 6 0 1 +23869 1 23867 1 +23869 2 2 23863 1 +23869 3 23867 6 0 1 +23869 4 2 14180 8 0 1 +23873 1 23870 1 +23873 2 3 23868 1 +23873 3 23870 4 0 1 +23873 4 3 13312 0 0 1 +23879 1 23872 1 +23879 2 7 23878 1 +23879 3 23872 1 0 1 +23879 4 7 12533 2 0 1 +23887 1 23884 1 +23887 2 3 23886 1 +23887 3 23884 4 0 1 +23887 4 3 21324 5 0 1 +23893 1 23888 1 +23893 2 5 23892 1 +23893 3 23888 1 0 1 +23893 4 5 21391 3 0 1 +23899 1 23897 1 +23899 2 2 23895 1 +23899 3 23897 6 0 1 +23899 4 2 20028 8 0 1 +23909 1 23907 1 +23909 2 2 23905 1 +23909 3 23907 2 0 1 +23909 4 2 16857 6 0 1 +23911 1 23905 1 +23911 2 6 23910 1 +23911 3 23905 2 0 1 +23911 4 6 22897 2 0 1 +23917 1 23915 1 +23917 2 2 23916 1 +23917 3 23915 6 0 1 +23917 4 2 18746 6 0 1 +23929 1 23922 1 +23929 2 7 23926 1 +23929 3 23922 5 0 1 +23929 4 7 13359 24 0 1 +23957 1 23955 1 +23957 2 2 23950 1 +23957 3 23955 2 0 1 +23957 4 2 18108 2 0 1 +23971 1 23961 1 +23971 2 10 23969 1 +23971 3 23961 2 0 1 +23971 4 10 21167 0 0 1 +23977 1 23972 1 +23977 2 5 23976 1 +23977 3 23972 1 0 1 +23977 4 5 16580 6 0 1 +23981 1 23978 1 +23981 2 3 23979 1 +23981 3 23978 4 0 1 +23981 4 3 23977 4 0 1 +23993 1 23990 1 +23993 2 3 23985 1 +23993 3 23990 3 0 1 +23993 4 3 17629 2 0 1 +24001 1 23987 1 +24001 2 14 23998 1 +24001 3 23987 4 0 1 +24001 4 14 19905 14 0 1 +24007 1 23990 1 +24007 2 17 24005 1 +24007 3 23990 4 0 1 +24007 4 17 23999 3 0 1 +24019 1 24017 1 +24019 2 2 24015 1 +24019 3 24017 2 0 1 +24019 4 2 21463 8 0 1 +24023 1 24018 1 +24023 2 5 24021 1 +24023 3 24018 2 0 1 +24023 4 5 24019 3 0 1 +24029 1 24027 1 +24029 2 2 24025 1 +24029 3 24027 3 0 1 +24029 4 2 17813 1 0 1 +24043 1 24041 1 +24043 2 2 24042 1 +24043 3 24041 2 0 1 +24043 4 2 19923 7 0 1 +24049 1 24030 1 +24049 2 19 24046 1 +24049 3 24030 3 0 1 +24049 4 19 17444 20 0 1 +24061 1 24051 1 +24061 2 10 24060 1 +24061 3 24051 3 0 1 +24061 4 10 15322 14 0 1 +24071 1 24060 1 +24071 2 11 24070 1 +24071 3 24060 2 0 1 +24071 4 11 22963 2 0 1 +24077 1 24075 1 +24077 2 2 24073 1 +24077 3 24075 7 0 1 +24077 4 2 21575 6 0 1 +24083 1 24081 1 +24083 2 2 24082 1 +24083 3 24081 2 0 1 +24083 4 2 15842 4 0 1 +24091 1 24084 1 +24091 2 7 24089 1 +24091 3 24084 3 0 1 +24091 4 7 19002 6 0 1 +24097 1 24092 1 +24097 2 5 24094 1 +24097 3 24092 1 0 1 +24097 4 5 18233 10 0 1 +24103 1 24098 1 +24103 2 5 24101 1 +24103 3 24098 3 0 1 +24103 4 5 16916 17 0 1 +24107 1 24105 1 +24107 2 2 24106 1 +24107 3 24105 2 0 1 +24107 4 2 16265 2 0 1 +24109 1 24107 1 +24109 2 2 24105 1 +24109 3 24107 6 0 1 +24109 4 2 15418 6 0 1 +24113 1 24110 1 +24113 2 3 24107 1 +24113 3 24110 3 0 1 +24113 4 3 13869 16 0 1 +24121 1 24108 1 +24121 2 13 24109 1 +24121 3 24108 6 0 1 +24121 4 13 21986 19 0 1 +24133 1 24127 1 +24133 2 6 24131 1 +24133 3 24127 3 0 1 +24133 4 6 18645 10 0 1 +24137 1 24134 1 +24137 2 3 24131 1 +24137 3 24134 1 0 1 +24137 4 3 22964 1 0 1 +24151 1 24145 1 +24151 2 6 24149 1 +24151 3 24145 3 0 1 +24151 4 6 19583 10 0 1 +24169 1 24158 1 +24169 2 11 24168 1 +24169 3 24158 3 0 1 +24169 4 11 23491 12 0 1 +24179 1 24177 1 +24179 2 2 24175 1 +24179 3 24177 3 0 1 +24179 4 2 18883 7 0 1 +24181 1 24164 1 +24181 2 17 24180 1 +24181 3 24164 1 0 1 +24181 4 17 20864 3 0 1 +24197 1 24195 1 +24197 2 2 24191 1 +24197 3 24195 5 0 1 +24197 4 2 20105 1 0 1 +24203 1 24201 1 +24203 2 2 24199 1 +24203 3 24201 3 0 1 +24203 4 2 23092 8 0 1 +24223 1 24220 1 +24223 2 3 24221 1 +24223 3 24220 1 0 1 +24223 4 3 16011 16 0 1 +24229 1 24227 1 +24229 2 2 24225 1 +24229 3 24227 6 0 1 +24229 4 2 12395 12 0 1 +24239 1 24226 1 +24239 2 13 24237 1 +24239 3 24226 5 0 1 +24239 4 13 17548 3 0 1 +24247 1 24244 1 +24247 2 3 24242 1 +24247 3 24244 1 0 1 +24247 4 3 15502 6 0 1 +24251 1 24245 1 +24251 2 6 24249 1 +24251 3 24245 7 0 1 +24251 4 6 24241 7 0 1 +24281 1 24278 1 +24281 2 3 24269 1 +24281 3 24278 7 0 1 +24281 4 3 23583 0 0 1 +24317 1 24315 1 +24317 2 2 24316 1 +24317 3 24315 2 0 1 +24317 4 2 19371 3 0 1 +24329 1 24326 1 +24329 2 3 24328 1 +24329 3 24326 3 0 1 +24329 4 3 13839 4 0 1 +24337 1 24332 1 +24337 2 5 24332 1 +24337 3 24332 1 0 1 +24337 4 5 13634 15 0 1 +24359 1 24348 1 +24359 2 11 24357 1 +24359 3 24348 2 0 1 +24359 4 11 18118 3 0 1 +24371 1 24369 1 +24371 2 2 24367 1 +24371 3 24369 4 0 1 +24371 4 2 16480 7 0 1 +24373 1 24366 1 +24373 2 7 24371 1 +24373 3 24366 2 0 1 +24373 4 7 14265 4 0 1 +24379 1 24377 1 +24379 2 2 24375 1 +24379 3 24377 5 0 1 +24379 4 2 19135 1 0 1 +24391 1 24388 1 +24391 2 3 24389 1 +24391 3 24388 4 0 1 +24391 4 3 23642 3 0 1 +24407 1 24402 1 +24407 2 5 24405 1 +24407 3 24402 1 0 1 +24407 4 5 16779 8 0 1 +24413 1 24411 1 +24413 2 2 24405 1 +24413 3 24411 3 0 1 +24413 4 2 20485 5 0 1 +24419 1 24417 1 +24419 2 2 24418 1 +24419 3 24417 3 0 1 +24419 4 2 17258 4 0 1 +24421 1 24414 1 +24421 2 7 24419 1 +24421 3 24414 2 0 1 +24421 4 7 14717 12 0 1 +24439 1 24433 1 +24439 2 6 24435 1 +24439 3 24433 2 0 1 +24439 4 6 24435 6 0 1 +24443 1 24441 1 +24443 2 2 24442 1 +24443 3 24441 7 0 1 +24443 4 2 18400 2 0 1 +24469 1 24455 1 +24469 2 14 24466 1 +24469 3 24455 2 0 1 +24469 4 14 20631 1 0 1 +24473 1 24470 1 +24473 2 3 24467 1 +24473 3 24470 12 0 1 +24473 4 3 22810 1 0 1 +24481 1 24470 1 +24481 2 11 24472 1 +24481 3 24470 4 0 1 +24481 4 11 20309 20 0 1 +24499 1 24497 1 +24499 2 2 24495 1 +24499 3 24497 5 0 1 +24499 4 2 19662 1 0 1 +24509 1 24507 1 +24509 2 2 24501 1 +24509 3 24507 3 0 1 +24509 4 2 20791 0 0 1 +24517 1 24512 1 +24517 2 5 24512 1 +24517 3 24512 6 0 1 +24517 4 5 14823 10 0 1 +24527 1 24522 1 +24527 2 5 24510 1 +24527 3 24522 1 0 1 +24527 4 5 21810 19 0 1 +24533 1 24531 1 +24533 2 2 24532 1 +24533 3 24531 3 0 1 +24533 4 2 13522 6 0 1 +24547 1 24545 1 +24547 2 2 24546 1 +24547 3 24545 5 0 1 +24547 4 2 17155 7 0 1 +24551 1 24544 1 +24551 2 7 24550 1 +24551 3 24544 3 0 1 +24551 4 7 24542 4 0 1 +24571 1 24564 1 +24571 2 7 24569 1 +24571 3 24564 1 0 1 +24571 4 7 22890 6 0 1 +24593 1 24590 1 +24593 2 3 24592 1 +24593 3 24590 1 0 1 +24593 4 3 23409 6 0 1 +24611 1 24598 1 +24611 2 13 24607 1 +24611 3 24598 2 0 1 +24611 4 13 13355 7 0 1 +24623 1 24618 1 +24623 2 5 24622 1 +24623 3 24618 2 0 1 +24623 4 5 24401 3 0 1 +24631 1 24628 1 +24631 2 3 24630 1 +24631 3 24628 3 0 1 +24631 4 3 18822 2 0 1 +24659 1 24657 1 +24659 2 2 24658 1 +24659 3 24657 12 0 1 +24659 4 2 24387 2 0 1 +24671 1 24660 1 +24671 2 11 24670 1 +24671 3 24660 2 0 1 +24671 4 11 12472 4 0 1 +24677 1 24675 1 +24677 2 2 24673 1 +24677 3 24675 3 0 1 +24677 4 2 21473 6 0 1 +24683 1 24681 1 +24683 2 2 24677 1 +24683 3 24681 4 0 1 +24683 4 2 20298 0 0 1 +24691 1 24689 1 +24691 2 2 24687 1 +24691 3 24689 4 0 1 +24691 4 2 12606 9 0 1 +24697 1 24692 1 +24697 2 5 24694 1 +24697 3 24692 7 0 1 +24697 4 5 24686 14 0 1 +24709 1 24707 1 +24709 2 2 24705 1 +24709 3 24707 6 0 1 +24709 4 2 17368 10 0 1 +24733 1 24731 1 +24733 2 2 24729 1 +24733 3 24731 6 0 1 +24733 4 2 20705 12 0 1 +24749 1 24747 1 +24749 2 2 24745 1 +24749 3 24747 3 0 1 +24749 4 2 19862 6 0 1 +24763 1 24761 1 +24763 2 2 24759 1 +24763 3 24761 6 0 1 +24763 4 2 15839 8 0 1 +24767 1 24762 1 +24767 2 5 24766 1 +24767 3 24762 1 0 1 +24767 4 5 23274 2 0 1 +24781 1 24779 1 +24781 2 2 24777 1 +24781 3 24779 2 0 1 +24781 4 2 19579 10 0 1 +24793 1 24788 1 +24793 2 5 24790 1 +24793 3 24788 1 0 1 +24793 4 5 15414 10 0 1 +24799 1 24793 1 +24799 2 6 24798 1 +24799 3 24793 1 0 1 +24799 4 6 15233 3 0 1 +24809 1 24803 1 +24809 2 6 24806 1 +24809 3 24803 2 0 1 +24809 4 6 23226 15 0 1 +24821 1 24819 1 +24821 2 2 24820 1 +24821 3 24819 3 0 1 +24821 4 2 16665 9 0 1 +24841 1 24827 1 +24841 2 14 24839 1 +24841 3 24827 1 0 1 +24841 4 14 14749 9 0 1 +24847 1 24844 1 +24847 2 3 24845 1 +24847 3 24844 5 0 1 +24847 4 3 17856 6 0 1 +24851 1 24849 1 +24851 2 2 24846 1 +24851 3 24849 2 0 1 +24851 4 2 24434 9 0 1 +24859 1 24857 1 +24859 2 2 24855 1 +24859 3 24857 2 0 1 +24859 4 2 22967 8 0 1 +24877 1 24872 1 +24877 2 5 24874 1 +24877 3 24872 1 0 1 +24877 4 5 19054 1 0 1 +24889 1 24878 1 +24889 2 11 24884 1 +24889 3 24878 3 0 1 +24889 4 11 24870 24 0 1 +24907 1 24905 1 +24907 2 2 24903 1 +24907 3 24905 4 0 1 +24907 4 2 18748 14 0 1 +24917 1 24915 1 +24917 2 2 24913 1 +24917 3 24915 3 0 1 +24917 4 2 15180 6 0 1 +24919 1 24916 1 +24919 2 3 24917 1 +24919 3 24916 1 0 1 +24919 4 3 19134 3 0 1 +24923 1 24921 1 +24923 2 2 24922 1 +24923 3 24921 2 0 1 +24923 4 2 12901 2 0 1 +24943 1 24938 1 +24943 2 5 24942 1 +24943 3 24938 2 0 1 +24943 4 5 22421 2 0 1 +24953 1 24950 1 +24953 2 3 24948 1 +24953 3 24950 7 0 1 +24953 4 3 12957 0 0 1 +24967 1 24964 1 +24967 2 3 24966 1 +24967 3 24964 7 0 1 +24967 4 3 15797 5 0 1 +24971 1 24969 1 +24971 2 2 24967 1 +24971 3 24969 3 0 1 +24971 4 2 18660 7 0 1 +24977 1 24974 1 +24977 2 3 24976 1 +24977 3 24974 10 0 1 +24977 4 3 23990 7 0 1 +24979 1 24977 1 +24979 2 2 24978 1 +24979 3 24977 4 0 1 +24979 4 2 23765 6 0 1 +24989 1 24987 1 +24989 2 2 24988 1 +24989 3 24987 3 0 1 +24989 4 2 21711 3 0 1 +25013 1 25011 1 +25013 2 2 25009 1 +25013 3 25011 3 0 1 +25013 4 2 21530 6 0 1 +25031 1 25018 1 +25031 2 13 25029 1 +25031 3 25018 6 0 1 +25031 4 13 18502 3 0 1 +25033 1 25028 1 +25033 2 5 25032 1 +25033 3 25028 3 0 1 +25033 4 5 20483 12 0 1 +25037 1 25035 1 +25037 2 2 25033 1 +25037 3 25035 2 0 1 +25037 4 2 22014 1 0 1 +25057 1 25052 1 +25057 2 5 25056 1 +25057 3 25052 1 0 1 +25057 4 5 17482 6 0 1 +25073 1 25070 1 +25073 2 3 25067 1 +25073 3 25070 6 0 1 +25073 4 3 24625 1 0 1 +25087 1 25084 1 +25087 2 3 25086 1 +25087 3 25084 1 0 1 +25087 4 3 18369 2 0 1 +25097 1 25094 1 +25097 2 3 25092 1 +25097 3 25094 3 0 1 +25097 4 3 22684 0 0 1 +25111 1 25108 1 +25111 2 3 25109 1 +25111 3 25108 1 0 1 +25111 4 3 23263 3 0 1 +25117 1 25112 1 +25117 2 5 25116 1 +25117 3 25112 10 0 1 +25117 4 5 19643 6 0 1 +25121 1 25118 1 +25121 2 3 25120 1 +25121 3 25118 3 0 1 +25121 4 3 13068 7 0 1 +25127 1 25122 1 +25127 2 5 25125 1 +25127 3 25122 1 0 1 +25127 4 5 15511 8 0 1 +25147 1 25145 1 +25147 2 2 25146 1 +25147 3 25145 2 0 1 +25147 4 2 24323 2 0 1 +25153 1 25143 1 +25153 2 10 25152 1 +25153 3 25143 5 0 1 +25153 4 10 24581 6 0 1 +25163 1 25161 1 +25163 2 2 25159 1 +25163 3 25161 3 0 1 +25163 4 2 17257 11 0 1 +25169 1 25166 1 +25169 2 3 25158 1 +25169 3 25166 8 0 1 +25169 4 3 24153 8 0 1 +25171 1 25168 1 +25171 2 3 25160 1 +25171 3 25168 3 0 1 +25171 4 3 19305 0 0 1 +25183 1 25178 1 +25183 2 5 25182 1 +25183 3 25178 21 0 1 +25183 4 5 25164 20 0 1 +25189 1 25187 1 +25189 2 2 25188 1 +25189 3 25187 4 0 1 +25189 4 2 15569 3 0 1 +25219 1 25217 1 +25219 2 2 25210 1 +25219 3 25217 6 0 1 +25219 4 2 13660 6 0 1 +25229 1 25227 1 +25229 2 2 25225 1 +25229 3 25227 2 0 1 +25229 4 2 15951 12 0 1 +25237 1 25235 1 +25237 2 2 25233 1 +25237 3 25235 4 0 1 +25237 4 2 12796 9 0 1 +25243 1 25241 1 +25243 2 2 25239 1 +25243 3 25241 4 0 1 +25243 4 2 20249 10 0 1 +25247 1 25242 1 +25247 2 5 25246 1 +25247 3 25242 2 0 1 +25247 4 5 18166 2 0 1 +25253 1 25251 1 +25253 2 2 25249 1 +25253 3 25251 3 0 1 +25253 4 2 16484 7 0 1 +25261 1 25254 1 +25261 2 7 25259 1 +25261 3 25254 4 0 1 +25261 4 7 23105 15 0 1 +25301 1 25298 1 +25301 2 3 25299 1 +25301 3 25298 4 0 1 +25301 4 3 25297 4 0 1 +25303 1 25300 1 +25303 2 3 25301 1 +25303 3 25300 1 0 1 +25303 4 3 20395 3 0 1 +25307 1 25305 1 +25307 2 2 25303 1 +25307 3 25305 4 0 1 +25307 4 2 23849 7 0 1 +25309 1 25296 1 +25309 2 13 25300 1 +25309 3 25296 1 0 1 +25309 4 13 17876 11 0 1 +25321 1 25302 1 +25321 2 19 25302 1 +25321 3 25302 2 0 1 +25321 4 19 17706 8 0 1 +25339 1 25336 1 +25339 2 3 25338 1 +25339 3 25336 17 0 1 +25339 4 3 14839 2 0 1 +25343 1 25338 1 +25343 2 5 25341 1 +25343 3 25338 1 0 1 +25343 4 5 23928 10 0 1 +25349 1 25347 1 +25349 2 2 25345 1 +25349 3 25347 4 0 1 +25349 4 2 15950 12 0 1 +25357 1 25355 1 +25357 2 2 25356 1 +25357 3 25355 2 0 1 +25357 4 2 16390 7 0 1 +25367 1 25362 1 +25367 2 5 25366 1 +25367 3 25362 5 0 1 +25367 4 5 24452 7 0 1 +25373 1 25371 1 +25373 2 2 25372 1 +25373 3 25371 3 0 1 +25373 4 2 18348 21 0 1 +25391 1 25384 1 +25391 2 7 25390 1 +25391 3 25384 1 0 1 +25391 4 7 24563 2 0 1 +25409 1 25406 1 +25409 2 3 25408 1 +25409 3 25406 3 0 1 +25409 4 3 16382 7 0 1 +25411 1 25404 1 +25411 2 7 25409 1 +25411 3 25404 1 0 1 +25411 4 7 17404 6 0 1 +25423 1 25420 1 +25423 2 3 25422 1 +25423 3 25420 11 0 1 +25423 4 3 20629 5 0 1 +25439 1 25432 1 +25439 2 7 25435 1 +25439 3 25432 9 0 1 +25439 4 7 15607 6 0 1 +25447 1 25444 1 +25447 2 3 25445 1 +25447 3 25444 13 0 1 +25447 4 3 20273 6 0 1 +25453 1 25451 1 +25453 2 2 25443 1 +25453 3 25451 4 0 1 +25453 4 2 24739 2 0 1 +25457 1 25454 1 +25457 2 3 25445 1 +25457 3 25454 1 0 1 +25457 4 3 18293 0 0 1 +25463 1 25458 1 +25463 2 5 25462 1 +25463 3 25458 5 0 1 +25463 4 5 18607 3 0 1 +25469 1 25467 1 +25469 2 2 25468 1 +25469 3 25467 3 0 1 +25469 4 2 25462 8 0 1 +25471 1 25465 1 +25471 2 6 25470 1 +25471 3 25465 3 0 1 +25471 4 6 16657 3 0 1 +25523 1 25521 1 +25523 2 2 25518 1 +25523 3 25521 4 0 1 +25523 4 2 24349 3 0 1 +25537 1 25527 1 +25537 2 10 25536 1 +25537 3 25527 2 0 1 +25537 4 10 13603 14 0 1 +25541 1 25539 1 +25541 2 2 25537 1 +25541 3 25539 3 0 1 +25541 4 2 21841 1 0 1 +25561 1 25550 1 +25561 2 11 25560 1 +25561 3 25550 3 0 1 +25561 4 11 18210 30 0 1 +25577 1 25574 1 +25577 2 3 25576 1 +25577 3 25574 3 0 1 +25577 4 3 20220 6 0 1 +25579 1 25577 1 +25579 2 2 25575 1 +25579 3 25577 6 0 1 +25579 4 2 25025 8 0 1 +25583 1 25578 1 +25583 2 5 25581 1 +25583 3 25578 6 0 1 +25583 4 5 20849 5 0 1 +25589 1 25587 1 +25589 2 2 25581 1 +25589 3 25587 5 0 1 +25589 4 2 17836 0 0 1 +25601 1 25598 1 +25601 2 3 25583 1 +25601 3 25598 8 0 1 +25601 4 3 19529 6 0 1 +25603 1 25601 1 +25603 2 2 25599 1 +25603 3 25601 5 0 1 +25603 4 2 14069 8 0 1 +25609 1 25602 1 +25609 2 7 25598 1 +25609 3 25602 1 0 1 +25609 4 7 25333 18 0 1 +25621 1 25611 1 +25621 2 10 25618 1 +25621 3 25611 7 0 1 +25621 4 10 17653 9 0 1 +25633 1 25628 1 +25633 2 5 25632 1 +25633 3 25628 5 0 1 +25633 4 5 16896 6 0 1 +25639 1 25636 1 +25639 2 3 25637 1 +25639 3 25636 3 0 1 +25639 4 3 23467 3 0 1 +25643 1 25641 1 +25643 2 2 25639 1 +25643 3 25641 3 0 1 +25643 4 2 15275 8 0 1 +25657 1 25652 1 +25657 2 5 25652 1 +25657 3 25652 1 0 1 +25657 4 5 13832 10 0 1 +25667 1 25665 1 +25667 2 2 25666 1 +25667 3 25665 2 0 1 +25667 4 2 25660 8 0 1 +25673 1 25670 1 +25673 2 3 25672 1 +25673 3 25670 3 0 1 +25673 4 3 14189 6 0 1 +25679 1 25668 1 +25679 2 11 25678 1 +25679 3 25668 7 0 1 +25679 4 11 22310 2 0 1 +25693 1 25691 1 +25693 2 2 25692 1 +25693 3 25691 2 0 1 +25693 4 2 19927 3 0 1 +25703 1 25698 1 +25703 2 5 25701 1 +25703 3 25698 7 0 1 +25703 4 5 20340 9 0 1 +25717 1 25715 1 +25717 2 2 25716 1 +25717 3 25715 2 0 1 +25717 4 2 19736 3 0 1 +25733 1 25731 1 +25733 2 2 25728 1 +25733 3 25731 8 0 1 +25733 4 2 25455 0 0 1 +25741 1 25735 1 +25741 2 6 25737 1 +25741 3 25735 1 0 1 +25741 4 6 17719 2 0 1 +25747 1 25745 1 +25747 2 2 25743 1 +25747 3 25745 5 0 1 +25747 4 2 19241 8 0 1 +25759 1 25756 1 +25759 2 3 25758 1 +25759 3 25756 1 0 1 +25759 4 3 15974 3 0 1 +25763 1 25758 1 +25763 2 5 25762 1 +25763 3 25758 2 0 1 +25763 4 5 15195 2 0 1 +25771 1 25769 1 +25771 2 2 25767 1 +25771 3 25769 8 0 1 +25771 4 2 21110 8 0 1 +25793 1 25790 1 +25793 2 3 25787 1 +25793 3 25790 7 0 1 +25793 4 3 16061 9 0 1 +25799 1 25792 1 +25799 2 7 25798 1 +25799 3 25792 3 0 1 +25799 4 7 23379 2 0 1 +25801 1 25794 1 +25801 2 7 25788 1 +25801 3 25794 2 0 1 +25801 4 7 13642 2 0 1 +25819 1 25816 1 +25819 2 3 25809 1 +25819 3 25816 1 0 1 +25819 4 3 18669 0 0 1 +25841 1 25838 1 +25841 2 3 25840 1 +25841 3 25838 1 0 1 +25841 4 3 17379 4 0 1 +25847 1 25842 1 +25847 2 5 25844 1 +25847 3 25842 3 0 1 +25847 4 5 15693 6 0 1 +25849 1 25842 1 +25849 2 7 25842 1 +25849 3 25842 1 0 1 +25849 4 7 23130 0 0 1 +25867 1 25865 1 +25867 2 2 25863 1 +25867 3 25865 6 0 1 +25867 4 2 17712 8 0 1 +25873 1 25863 1 +25873 2 10 25863 1 +25873 3 25863 6 0 1 +25873 4 10 21826 0 0 1 +25889 1 25886 1 +25889 2 3 25888 1 +25889 3 25886 4 0 1 +25889 4 3 16880 7 0 1 +25903 1 25898 1 +25903 2 5 25901 1 +25903 3 25898 5 0 1 +25903 4 5 17698 10 0 1 +25913 1 25910 1 +25913 2 3 25912 1 +25913 3 25910 1 0 1 +25913 4 3 23988 7 0 1 +25919 1 25908 1 +25919 2 11 25918 1 +25919 3 25908 1 0 1 +25919 4 11 23765 6 0 1 +25931 1 25929 1 +25931 2 2 25930 1 +25931 3 25929 3 0 1 +25931 4 2 24429 2 0 1 +25933 1 25931 1 +25933 2 2 25932 1 +25933 3 25931 2 0 1 +25933 4 2 25231 12 0 1 +25939 1 25936 1 +25939 2 3 25926 1 +25939 3 25936 3 0 1 +25939 4 3 16606 2 0 1 +25943 1 25938 1 +25943 2 5 25942 1 +25943 3 25938 1 0 1 +25943 4 5 16536 5 0 1 +25951 1 25948 1 +25951 2 3 25950 1 +25951 3 25948 1 0 1 +25951 4 3 22211 2 0 1 +25969 1 25962 1 +25969 2 7 25966 1 +25969 3 25962 2 0 1 +25969 4 7 23150 16 0 1 +25981 1 25970 1 +25981 2 11 25979 1 +25981 3 25970 3 0 1 +25981 4 11 16071 0 0 1 +25997 1 25995 1 +25997 2 2 25990 1 +25997 3 25995 2 0 1 +25997 4 2 18736 2 0 1 +25999 1 25992 1 +25999 2 7 25987 1 +25999 3 25992 3 0 1 +25999 4 7 15883 0 0 1 +26003 1 26001 1 +26003 2 2 25999 1 +26003 3 26001 2 0 1 +26003 4 2 23173 7 0 1 +26017 1 26012 1 +26017 2 5 26014 1 +26017 3 26012 1 0 1 +26017 4 5 26006 14 0 1 +26021 1 26019 1 +26021 2 2 26017 1 +26021 3 26019 2 0 1 +26021 4 2 15677 6 0 1 +26029 1 26023 1 +26029 2 6 26025 1 +26029 3 26023 9 0 1 +26029 4 6 18412 10 0 1 +26041 1 26028 1 +26041 2 13 26038 1 +26041 3 26028 10 0 1 +26041 4 13 19185 20 0 1 +26053 1 26051 1 +26053 2 2 26052 1 +26053 3 26051 2 0 1 +26053 4 2 25471 6 0 1 +26083 1 26076 1 +26083 2 7 26081 1 +26083 3 26076 1 0 1 +26083 4 7 17280 11 0 1 +26099 1 26097 1 +26099 2 2 26098 1 +26099 3 26097 3 0 1 +26099 4 2 14663 2 0 1 +26107 1 26105 1 +26107 2 2 26103 1 +26107 3 26105 4 0 1 +26107 4 2 16461 8 0 1 +26111 1 26104 1 +26111 2 7 26109 1 +26111 3 26104 3 0 1 +26111 4 7 25336 5 0 1 +26113 1 26106 1 +26113 2 7 26102 1 +26113 3 26106 4 0 1 +26113 4 7 20499 26 0 1 +26119 1 26116 1 +26119 2 3 26117 1 +26119 3 26116 1 0 1 +26119 4 3 24356 3 0 1 +26141 1 26139 1 +26141 2 2 26136 1 +26141 3 26139 4 0 1 +26141 4 2 21261 8 0 1 +26153 1 26150 1 +26153 2 3 26152 1 +26153 3 26150 5 0 1 +26153 4 3 18937 4 0 1 +26161 1 26148 1 +26161 2 13 26152 1 +26161 3 26148 1 0 1 +26161 4 13 24227 32 0 1 +26171 1 26169 1 +26171 2 2 26170 1 +26171 3 26169 3 0 1 +26171 4 2 26164 8 0 1 +26177 1 26174 1 +26177 2 3 26176 1 +26177 3 26174 1 0 1 +26177 4 3 18571 7 0 1 +26183 1 26178 1 +26183 2 5 26181 1 +26183 3 26178 1 0 1 +26183 4 5 15893 5 0 1 +26189 1 26187 1 +26189 2 2 26179 1 +26189 3 26187 2 0 1 +26189 4 2 19369 2 0 1 +26203 1 26200 1 +26203 2 3 26198 1 +26203 3 26200 1 0 1 +26203 4 3 17154 3 0 1 +26209 1 26198 1 +26209 2 11 26208 1 +26209 3 26198 3 0 1 +26209 4 11 21110 12 0 1 +26227 1 26224 1 +26227 2 3 26222 1 +26227 3 26224 4 0 1 +26227 4 3 18650 3 0 1 +26237 1 26235 1 +26237 2 2 26233 1 +26237 3 26235 3 0 1 +26237 4 2 15275 6 0 1 +26249 1 26246 1 +26249 2 3 26244 1 +26249 3 26246 1 0 1 +26249 4 3 23205 2 0 1 +26251 1 26249 1 +26251 2 2 26247 1 +26251 3 26249 6 0 1 +26251 4 2 15154 8 0 1 +26261 1 26259 1 +26261 2 2 26257 1 +26261 3 26259 5 0 1 +26261 4 2 23709 7 0 1 +26263 1 26260 1 +26263 2 3 26262 1 +26263 3 26260 1 0 1 +26263 4 3 15154 5 0 1 +26267 1 26265 1 +26267 2 2 26263 1 +26267 3 26265 2 0 1 +26267 4 2 24302 7 0 1 +26293 1 26287 1 +26293 2 6 26291 1 +26293 3 26287 2 0 1 +26293 4 6 21461 4 0 1 +26297 1 26294 1 +26297 2 3 26296 1 +26297 3 26294 3 0 1 +26297 4 3 19083 4 0 1 +26309 1 26307 1 +26309 2 2 26308 1 +26309 3 26307 7 0 1 +26309 4 2 19641 3 0 1 +26317 1 26311 1 +26317 2 6 26316 1 +26317 3 26311 6 0 1 +26317 4 6 20554 6 0 1 +26321 1 26318 1 +26321 2 3 26315 1 +26321 3 26318 1 0 1 +26321 4 3 26309 0 0 1 +26339 1 26337 1 +26339 2 2 26338 1 +26339 3 26337 8 0 1 +26339 4 2 24248 2 0 1 +26347 1 26344 1 +26347 2 3 26346 1 +26347 3 26344 3 0 1 +26347 4 3 19895 5 0 1 +26357 1 26355 1 +26357 2 2 26350 1 +26357 3 26355 8 0 1 +26357 4 2 20207 2 0 1 +26371 1 26368 1 +26371 2 3 26366 1 +26371 3 26368 1 0 1 +26371 4 3 23788 3 0 1 +26387 1 26385 1 +26387 2 2 26382 1 +26387 3 26385 5 0 1 +26387 4 2 21859 0 0 1 +26393 1 26390 1 +26393 2 3 26387 1 +26393 3 26390 5 0 1 +26393 4 3 25460 26 0 1 +26399 1 26392 1 +26399 2 7 26390 1 +26399 3 26392 1 0 1 +26399 4 7 20930 11 0 1 +26407 1 26402 1 +26407 2 5 26405 1 +26407 3 26402 2 0 1 +26407 4 5 26403 3 0 1 +26417 1 26414 1 +26417 2 3 26408 1 +26417 3 26414 5 0 1 +26417 4 3 16448 6 0 1 +26423 1 26418 1 +26423 2 5 26422 1 +26423 3 26418 1 0 1 +26423 4 5 15901 7 0 1 +26431 1 26428 1 +26431 2 3 26429 1 +26431 3 26428 1 0 1 +26431 4 3 21524 3 0 1 +26437 1 26432 1 +26437 2 5 26436 1 +26437 3 26432 8 0 1 +26437 4 5 21196 3 0 1 +26449 1 26442 1 +26449 2 7 26442 1 +26449 3 26442 1 0 1 +26449 4 7 18096 0 0 1 +26459 1 26457 1 +26459 2 2 26452 1 +26459 3 26457 7 0 1 +26459 4 2 14846 1 0 1 +26479 1 26476 1 +26479 2 3 26478 1 +26479 3 26476 7 0 1 +26479 4 3 24093 2 0 1 +26489 1 26486 1 +26489 2 3 26478 1 +26489 3 26486 1 0 1 +26489 4 3 14238 8 0 1 +26497 1 26492 1 +26497 2 5 26492 1 +26497 3 26492 5 0 1 +26497 4 5 21704 15 0 1 +26501 1 26499 1 +26501 2 2 26500 1 +26501 3 26499 3 0 1 +26501 4 2 13544 3 0 1 +26513 1 26510 1 +26513 2 3 26507 1 +26513 3 26510 1 0 1 +26513 4 3 18750 1 0 1 +26539 1 26537 1 +26539 2 2 26535 1 +26539 3 26537 6 0 1 +26539 4 2 20981 8 0 1 +26557 1 26555 1 +26557 2 2 26556 1 +26557 3 26555 4 0 1 +26557 4 2 17024 6 0 1 +26561 1 26558 1 +26561 2 3 26560 1 +26561 3 26558 1 0 1 +26561 4 3 24291 7 0 1 +26573 1 26571 1 +26573 2 2 26569 1 +26573 3 26571 3 0 1 +26573 4 2 25826 7 0 1 +26591 1 26569 1 +26591 2 22 26589 1 +26591 3 26569 1 0 1 +26591 4 22 17105 5 0 1 +26597 1 26595 1 +26597 2 2 26593 1 +26597 3 26595 3 0 1 +26597 4 2 15264 7 0 1 +26627 1 26625 1 +26627 2 2 26626 1 +26627 3 26625 2 0 1 +26627 4 2 21132 2 0 1 +26633 1 26630 1 +26633 2 3 26627 1 +26633 3 26630 5 0 1 +26633 4 3 20767 1 0 1 +26641 1 26634 1 +26641 2 7 26638 1 +26641 3 26634 1 0 1 +26641 4 7 20536 17 0 1 +26647 1 26644 1 +26647 2 3 26645 1 +26647 3 26644 1 0 1 +26647 4 3 17281 6 0 1 +26669 1 26667 1 +26669 2 2 26668 1 +26669 3 26667 4 0 1 +26669 4 2 13629 9 0 1 +26681 1 26675 1 +26681 2 6 26678 1 +26681 3 26675 2 0 1 +26681 4 6 13523 0 0 1 +26683 1 26681 1 +26683 2 2 26682 1 +26683 3 26681 2 0 1 +26683 4 2 14202 2 0 1 +26687 1 26682 1 +26687 2 5 26685 1 +26687 3 26682 8 0 1 +26687 4 5 26683 3 0 1 +26693 1 26691 1 +26693 2 2 26688 1 +26693 3 26691 4 0 1 +26693 4 2 25003 8 0 1 +26699 1 26697 1 +26699 2 2 26693 1 +26699 3 26697 2 0 1 +26699 4 2 25065 4 0 1 +26701 1 26679 1 +26701 2 22 26700 1 +26701 3 26679 1 0 1 +26701 4 22 26068 3 0 1 +26711 1 26700 1 +26711 2 11 26709 1 +26711 3 26700 11 0 1 +26711 4 11 14485 10 0 1 +26713 1 26703 1 +26713 2 10 26712 1 +26713 3 26703 2 0 1 +26713 4 10 21848 14 0 1 +26717 1 26715 1 +26717 2 2 26716 1 +26717 3 26715 2 0 1 +26717 4 2 20892 6 0 1 +26723 1 26721 1 +26723 2 2 26719 1 +26723 3 26721 3 0 1 +26723 4 2 17493 7 0 1 +26729 1 26726 1 +26729 2 3 26719 1 +26729 3 26726 4 0 1 +26729 4 3 16586 4 0 1 +26731 1 26728 1 +26731 2 3 26724 1 +26731 3 26728 5 0 1 +26731 4 3 21780 5 0 1 +26737 1 26727 1 +26737 2 10 26734 1 +26737 3 26727 4 0 1 +26737 4 10 25022 8 0 1 +26759 1 26746 1 +26759 2 13 26757 1 +26759 3 26746 6 0 1 +26759 4 13 22112 4 0 1 +26777 1 26774 1 +26777 2 3 26771 1 +26777 3 26774 1 0 1 +26777 4 3 14760 9 0 1 +26783 1 26778 1 +26783 2 5 26782 1 +26783 3 26778 7 0 1 +26783 4 5 19230 2 0 1 +26801 1 26798 1 +26801 2 3 26795 1 +26801 3 26798 8 0 1 +26801 4 3 26789 0 0 1 +26813 1 26811 1 +26813 2 2 26812 1 +26813 3 26811 2 0 1 +26813 4 2 14508 3 0 1 +26821 1 26819 1 +26821 2 2 26817 1 +26821 3 26819 2 0 1 +26821 4 2 14326 6 0 1 +26833 1 26828 1 +26833 2 5 26828 1 +26833 3 26828 2 0 1 +26833 4 5 24987 20 0 1 +26839 1 26836 1 +26839 2 3 26837 1 +26839 3 26836 5 0 1 +26839 4 3 22643 6 0 1 +26849 1 26846 1 +26849 2 3 26840 1 +26849 3 26846 4 0 1 +26849 4 3 19139 3 0 1 +26861 1 26859 1 +26861 2 2 26854 1 +26861 3 26859 2 0 1 +26861 4 2 19313 4 0 1 +26863 1 26858 1 +26863 2 5 26861 1 +26863 3 26858 1 0 1 +26863 4 5 26859 3 0 1 +26879 1 26866 1 +26879 2 13 26878 1 +26879 3 26866 2 0 1 +26879 4 13 26387 4 0 1 +26881 1 26870 1 +26881 2 11 26876 1 +26881 3 26870 3 0 1 +26881 4 11 26862 24 0 1 +26891 1 26885 1 +26891 2 6 26889 1 +26891 3 26885 3 0 1 +26891 4 6 16896 0 0 1 +26893 1 26888 1 +26893 2 5 26892 1 +26893 3 26888 2 0 1 +26893 4 5 24300 22 0 1 +26903 1 26898 1 +26903 2 5 26902 1 +26903 3 26898 2 0 1 +26903 4 5 23332 2 0 1 +26921 1 26908 1 +26921 2 13 26916 1 +26921 3 26908 6 0 1 +26921 4 13 21832 2 0 1 +26927 1 26922 1 +26927 2 5 26924 1 +26927 3 26922 3 0 1 +26927 4 5 22601 4 0 1 +26947 1 26945 1 +26947 2 2 26943 1 +26947 3 26945 6 0 1 +26947 4 2 23175 8 0 1 +26951 1 26944 1 +26951 2 7 26949 1 +26951 3 26944 2 0 1 +26951 4 7 24429 4 0 1 +26953 1 26946 1 +26953 2 7 26946 1 +26953 3 26946 1 0 1 +26953 4 7 16703 21 0 1 +26959 1 26953 1 +26959 2 6 26955 1 +26959 3 26953 3 0 1 +26959 4 6 16795 5 0 1 +26981 1 26978 1 +26981 2 3 26976 1 +26981 3 26978 7 0 1 +26981 4 3 15016 2 0 1 +26987 1 26985 1 +26987 2 2 26983 1 +26987 3 26985 3 0 1 +26987 4 2 17425 18 0 1 +26993 1 26990 1 +26993 2 3 26992 1 +26993 3 26990 6 0 1 +26993 4 3 24801 11 0 1 +27011 1 27009 1 +27011 2 2 27003 1 +27011 3 27009 5 0 1 +27011 4 2 22922 6 0 1 +27017 1 27012 1 +27017 2 5 27016 1 +27017 3 27012 3 0 1 +27017 4 5 18792 4 0 1 +27031 1 27025 1 +27031 2 6 27029 1 +27031 3 27025 6 0 1 +27031 4 6 17674 4 0 1 +27043 1 27041 1 +27043 2 2 27039 1 +27043 3 27041 6 0 1 +27043 4 2 23086 10 0 1 +27059 1 27057 1 +27059 2 2 27055 1 +27059 3 27057 3 0 1 +27059 4 2 15396 7 0 1 +27061 1 27059 1 +27061 2 2 27057 1 +27061 3 27059 6 0 1 +27061 4 2 17843 6 0 1 +27067 1 27065 1 +27067 2 2 27066 1 +27067 3 27065 2 0 1 +27067 4 2 26664 2 0 1 +27073 1 27068 1 +27073 2 5 27070 1 +27073 3 27068 3 0 1 +27073 4 5 26840 16 0 1 +27077 1 27075 1 +27077 2 2 27073 1 +27077 3 27075 3 0 1 +27077 4 2 14297 12 0 1 +27091 1 27089 1 +27091 2 2 27087 1 +27091 3 27089 2 0 1 +27091 4 2 19090 8 0 1 +27103 1 27100 1 +27103 2 3 27102 1 +27103 3 27100 6 0 1 +27103 4 3 14162 5 0 1 +27107 1 27105 1 +27107 2 2 27106 1 +27107 3 27105 2 0 1 +27107 4 2 21945 10 0 1 +27109 1 27102 1 +27109 2 7 27103 1 +27109 3 27102 4 0 1 +27109 4 7 27105 4 0 1 +27127 1 27124 1 +27127 2 3 27125 1 +27127 3 27124 4 0 1 +27127 4 3 15454 3 0 1 +27143 1 27138 1 +27143 2 5 27141 1 +27143 3 27138 5 0 1 +27143 4 5 26211 5 0 1 +27179 1 27177 1 +27179 2 2 27175 1 +27179 3 27177 3 0 1 +27179 4 2 20628 9 0 1 +27191 1 27165 1 +27191 2 26 27189 1 +27191 3 27165 2 0 1 +27191 4 26 22000 4 0 1 +27197 1 27195 1 +27197 2 2 27192 1 +27197 3 27195 4 0 1 +27197 4 2 19228 7 0 1 +27211 1 27201 1 +27211 2 10 27210 1 +27211 3 27201 4 0 1 +27211 4 10 13925 2 0 1 +27239 1 27232 1 +27239 2 7 27238 1 +27239 3 27232 2 0 1 +27239 4 7 27230 4 0 1 +27241 1 27224 1 +27241 2 17 27238 1 +27241 3 27224 4 0 1 +27241 4 17 22918 20 0 1 +27253 1 27251 1 +27253 2 2 27249 1 +27253 3 27251 6 0 1 +27253 4 2 23503 10 0 1 +27259 1 27257 1 +27259 2 2 27255 1 +27259 3 27257 2 0 1 +27259 4 2 22941 8 0 1 +27271 1 27265 1 +27271 2 6 27267 1 +27271 3 27265 3 0 1 +27271 4 6 18035 5 0 1 +27277 1 27271 1 +27277 2 6 27276 1 +27277 3 27271 2 0 1 +27277 4 6 21297 12 0 1 +27281 1 27275 1 +27281 2 6 27278 1 +27281 3 27275 1 0 1 +27281 4 6 23165 0 0 1 +27283 1 27278 1 +27283 2 5 27282 1 +27283 3 27278 2 0 1 +27283 4 5 24149 5 0 1 +27299 1 27297 1 +27299 2 2 27292 1 +27299 3 27297 7 0 1 +27299 4 2 18406 1 0 1 +27329 1 27326 1 +27329 2 3 27323 1 +27329 3 27326 1 0 1 +27329 4 3 27317 0 0 1 +27337 1 27332 1 +27337 2 5 27336 1 +27337 3 27332 13 0 1 +27337 4 5 22681 6 0 1 +27361 1 27354 1 +27361 2 7 27354 1 +27361 3 27354 5 0 1 +27361 4 7 23316 0 0 1 +27367 1 27364 1 +27367 2 3 27366 1 +27367 3 27364 12 0 1 +27367 4 3 16245 5 0 1 +27397 1 27395 1 +27397 2 2 27396 1 +27397 3 27395 6 0 1 +27397 4 2 26553 3 0 1 +27407 1 27402 1 +27407 2 5 27405 1 +27407 3 27402 1 0 1 +27407 4 5 26272 8 0 1 +27409 1 27396 1 +27409 2 13 27408 1 +27409 3 27396 1 0 1 +27409 4 13 17344 12 0 1 +27427 1 27422 1 +27427 2 5 27426 1 +27427 3 27422 12 0 1 +27427 4 5 26705 10 0 1 +27431 1 27414 1 +27431 2 17 27430 1 +27431 3 27414 3 0 1 +27431 4 17 20902 2 0 1 +27437 1 27435 1 +27437 2 2 27433 1 +27437 3 27435 10 0 1 +27437 4 2 20670 12 0 1 +27449 1 27446 1 +27449 2 3 27443 1 +27449 3 27446 3 0 1 +27449 4 3 27437 0 0 1 +27457 1 27450 1 +27457 2 7 27454 1 +27457 3 27450 2 0 1 +27457 4 7 25825 8 0 1 +27479 1 27472 1 +27479 2 7 27478 1 +27479 3 27472 7 0 1 +27479 4 7 23201 11 0 1 +27481 1 27474 1 +27481 2 7 27474 1 +27481 3 27474 7 0 1 +27481 4 7 16721 0 0 1 +27487 1 27484 1 +27487 2 3 27485 1 +27487 3 27484 14 0 1 +27487 4 3 14442 3 0 1 +27509 1 27507 1 +27509 2 2 27504 1 +27509 3 27507 16 0 1 +27509 4 2 16018 12 0 1 +27527 1 27522 1 +27527 2 5 27526 1 +27527 3 27522 1 0 1 +27527 4 5 18273 2 0 1 +27529 1 27522 1 +27529 2 7 27522 1 +27529 3 27522 4 0 1 +27529 4 7 18740 0 0 1 +27539 1 27537 1 +27539 2 2 27535 1 +27539 3 27537 3 0 1 +27539 4 2 18112 7 0 1 +27541 1 27522 1 +27541 2 19 27539 1 +27541 3 27522 1 0 1 +27541 4 19 14327 0 0 1 +27551 1 27534 1 +27551 2 17 27549 1 +27551 3 27534 10 0 1 +27551 4 17 27543 3 0 1 +27581 1 27579 1 +27581 2 2 27577 1 +27581 3 27579 2 0 1 +27581 4 2 21932 6 0 1 +27583 1 27580 1 +27583 2 3 27582 1 +27583 3 27580 3 0 1 +27583 4 3 18630 2 0 1 +27611 1 27609 1 +27611 2 2 27607 1 +27611 3 27609 3 0 1 +27611 4 2 18864 13 0 1 +27617 1 27614 1 +27617 2 3 27616 1 +27617 3 27614 4 0 1 +27617 4 3 19393 14 0 1 +27631 1 27625 1 +27631 2 6 27627 1 +27631 3 27625 1 0 1 +27631 4 6 21856 5 0 1 +27647 1 27642 1 +27647 2 5 27645 1 +27647 3 27642 1 0 1 +27647 4 5 26495 5 0 1 +27653 1 27651 1 +27653 2 2 27649 1 +27653 3 27651 3 0 1 +27653 4 2 22982 1 0 1 +27673 1 27662 1 +27673 2 11 27671 1 +27673 3 27662 4 0 1 +27673 4 11 21682 7 0 1 +27689 1 27686 1 +27689 2 3 27688 1 +27689 3 27686 12 0 1 +27689 4 3 15654 7 0 1 +27691 1 27688 1 +27691 2 3 27684 1 +27691 3 27688 3 0 1 +27691 4 3 23649 5 0 1 +27697 1 27692 1 +27697 2 5 27696 1 +27697 3 27692 1 0 1 +27697 4 5 14230 8 0 1 +27701 1 27699 1 +27701 2 2 27697 1 +27701 3 27699 2 0 1 +27701 4 2 22935 12 0 1 +27733 1 27731 1 +27733 2 2 27732 1 +27733 3 27731 2 0 1 +27733 4 2 16728 3 0 1 +27737 1 27734 1 +27737 2 3 27736 1 +27737 3 27734 4 0 1 +27737 4 3 22452 7 0 1 +27739 1 27736 1 +27739 2 3 27738 1 +27739 3 27736 3 0 1 +27739 4 3 15220 2 0 1 +27743 1 27738 1 +27743 2 5 27738 1 +27743 3 27738 1 0 1 +27743 4 5 16117 9 0 1 +27749 1 27746 1 +27749 2 3 27744 1 +27749 3 27746 3 0 1 +27749 4 3 24376 2 0 1 +27751 1 27748 1 +27751 2 3 27749 1 +27751 3 27748 10 0 1 +27751 4 3 27747 4 0 1 +27763 1 27760 1 +27763 2 3 27762 1 +27763 3 27760 8 0 1 +27763 4 3 18860 5 0 1 +27767 1 27762 1 +27767 2 5 27766 1 +27767 3 27762 2 0 1 +27767 4 5 22807 3 0 1 +27773 1 27771 1 +27773 2 2 27768 1 +27773 3 27771 5 0 1 +27773 4 2 17311 2 0 1 +27779 1 27777 1 +27779 2 2 27778 1 +27779 3 27777 3 0 1 +27779 4 2 14110 2 0 1 +27791 1 27784 1 +27791 2 7 27789 1 +27791 3 27784 1 0 1 +27791 4 7 18896 4 0 1 +27793 1 27788 1 +27793 2 5 27790 1 +27793 3 27788 1 0 1 +27793 4 5 27782 14 0 1 +27799 1 27792 1 +27799 2 7 27796 1 +27799 3 27792 17 0 1 +27799 4 7 27175 13 0 1 +27803 1 27801 1 +27803 2 2 27802 1 +27803 3 27801 11 0 1 +27803 4 2 21069 10 0 1 +27809 1 27806 1 +27809 2 3 27804 1 +27809 3 27806 1 0 1 +27809 4 3 25850 2 0 1 +27817 1 27812 1 +27817 2 5 27812 1 +27817 3 27812 3 0 1 +27817 4 5 18284 15 0 1 +27823 1 27817 1 +27823 2 6 27820 1 +27823 3 27817 1 0 1 +27823 4 6 20444 5 0 1 +27827 1 27825 1 +27827 2 2 27821 1 +27827 3 27825 9 0 1 +27827 4 2 14407 4 0 1 +27847 1 27841 1 +27847 2 6 27846 1 +27847 3 27841 1 0 1 +27847 4 6 19020 2 0 1 +27851 1 27849 1 +27851 2 2 27850 1 +27851 3 27849 3 0 1 +27851 4 2 23955 4 0 1 +27883 1 27880 1 +27883 2 3 27878 1 +27883 3 27880 5 0 1 +27883 4 3 17518 3 0 1 +27893 1 27891 1 +27893 2 2 27892 1 +27893 3 27891 2 0 1 +27893 4 2 20167 9 0 1 +27901 1 27899 1 +27901 2 2 27895 1 +27901 3 27899 6 0 1 +27901 4 2 17018 8 0 1 +27917 1 27915 1 +27917 2 2 27913 1 +27917 3 27915 3 0 1 +27917 4 2 21672 7 0 1 +27919 1 27916 1 +27919 2 3 27917 1 +27919 3 27916 1 0 1 +27919 4 3 20139 3 0 1 +27941 1 27939 1 +27941 2 2 27937 1 +27941 3 27939 2 0 1 +27941 4 2 23222 6 0 1 +27943 1 27938 1 +27943 2 5 27942 1 +27943 3 27938 2 0 1 +27943 4 5 25944 9 0 1 +27947 1 27945 1 +27947 2 2 27946 1 +27947 3 27945 3 0 1 +27947 4 2 24727 10 0 1 +27953 1 27950 1 +27953 2 3 27952 1 +27953 3 27950 1 0 1 +27953 4 3 26759 4 0 1 +27961 1 27948 1 +27961 2 13 27948 1 +27961 3 27948 4 0 1 +27961 4 13 27922 0 0 1 +27967 1 27964 1 +27967 2 3 27965 1 +27967 3 27964 3 0 1 +27967 4 3 23857 6 0 1 +27983 1 27978 1 +27983 2 5 27982 1 +27983 3 27978 2 0 1 +27983 4 5 25214 2 0 1 +27997 1 27992 1 +27997 2 5 27996 1 +27997 3 27992 5 0 1 +27997 4 5 18866 6 0 1 +28001 1 27998 1 +28001 2 3 28000 1 +28001 3 27998 4 0 1 +28001 4 3 26370 7 0 1 +28019 1 28017 1 +28019 2 2 28015 1 +28019 3 28017 3 0 1 +28019 4 2 14907 9 0 1 +28027 1 28025 1 +28027 2 2 28022 1 +28027 3 28025 2 0 1 +28027 4 2 23430 2 0 1 +28031 1 28012 1 +28031 2 19 28030 1 +28031 3 28012 2 0 1 +28031 4 19 17916 2 0 1 +28051 1 28049 1 +28051 2 2 28047 1 +28051 3 28049 2 0 1 +28051 4 2 24860 8 0 1 +28057 1 28052 1 +28057 2 5 28056 1 +28057 3 28052 2 0 1 +28057 4 5 19702 12 0 1 +28069 1 28062 1 +28069 2 7 28063 1 +28069 3 28062 1 0 1 +28069 4 7 18824 16 0 1 +28081 1 28062 1 +28081 2 19 28078 1 +28081 3 28062 3 0 1 +28081 4 19 22235 20 0 1 +28087 1 28084 1 +28087 2 3 28085 1 +28087 3 28084 4 0 1 +28087 4 3 25323 6 0 1 +28097 1 28094 1 +28097 2 3 28091 1 +28097 3 28094 5 0 1 +28097 4 3 15760 1 0 1 +28099 1 28097 1 +28099 2 2 28095 1 +28099 3 28097 2 0 1 +28099 4 2 27228 8 0 1 +28109 1 28107 1 +28109 2 2 28105 1 +28109 3 28107 2 0 1 +28109 4 2 23032 7 0 1 +28111 1 28108 1 +28111 2 3 28110 1 +28111 3 28108 1 0 1 +28111 4 3 19480 2 0 1 +28123 1 28121 1 +28123 2 2 28119 1 +28123 3 28121 4 0 1 +28123 4 2 23818 8 0 1 +28151 1 28144 1 +28151 2 7 28150 1 +28151 3 28144 2 0 1 +28151 4 7 22238 2 0 1 +28163 1 28161 1 +28163 2 2 28159 1 +28163 3 28161 3 0 1 +28163 4 2 23095 8 0 1 +28181 1 28179 1 +28181 2 2 28180 1 +28181 3 28179 3 0 1 +28181 4 2 23797 3 0 1 +28183 1 28180 1 +28183 2 3 28181 1 +28183 3 28180 1 0 1 +28183 4 3 28179 4 0 1 +28201 1 28190 1 +28201 2 11 28198 1 +28201 3 28190 3 0 1 +28201 4 11 19509 14 0 1 +28211 1 28209 1 +28211 2 2 28207 1 +28211 3 28209 2 0 1 +28211 4 2 18436 8 0 1 +28219 1 28216 1 +28219 2 3 28206 1 +28219 3 28216 1 0 1 +28219 4 3 21787 3 0 1 +28229 1 28227 1 +28229 2 2 28220 1 +28229 3 28227 3 0 1 +28229 4 2 24350 1 0 1 +28277 1 28275 1 +28277 2 2 28273 1 +28277 3 28275 7 0 1 +28277 4 2 18350 6 0 1 +28279 1 28276 1 +28279 2 3 28277 1 +28279 3 28276 3 0 1 +28279 4 3 18556 6 0 1 +28283 1 28281 1 +28283 2 2 28282 1 +28283 3 28281 3 0 1 +28283 4 2 25284 2 0 1 +28289 1 28283 1 +28289 2 6 28288 1 +28289 3 28283 1 0 1 +28289 4 6 17328 7 0 1 +28297 1 28292 1 +28297 2 5 28292 1 +28297 3 28292 3 0 1 +28297 4 5 21396 15 0 1 +28307 1 28305 1 +28307 2 2 28306 1 +28307 3 28305 2 0 1 +28307 4 2 20261 2 0 1 +28309 1 28307 1 +28309 2 2 28305 1 +28309 3 28307 2 0 1 +28309 4 2 27538 10 0 1 +28319 1 28312 1 +28319 2 7 28318 1 +28319 3 28312 4 0 1 +28319 4 7 23506 2 0 1 +28349 1 28347 1 +28349 2 2 28344 1 +28349 3 28347 11 0 1 +28349 4 2 25323 8 0 1 +28351 1 28345 1 +28351 2 6 28350 1 +28351 3 28345 7 0 1 +28351 4 6 26373 3 0 1 +28387 1 28385 1 +28387 2 2 28383 1 +28387 3 28385 6 0 1 +28387 4 2 18465 8 0 1 +28393 1 28378 1 +28393 2 15 28392 1 +28393 3 28378 2 0 1 +28393 4 15 14936 6 0 1 +28403 1 28398 1 +28403 2 5 28401 1 +28403 3 28398 1 0 1 +28403 4 5 28399 3 0 1 +28409 1 28406 1 +28409 2 3 28400 1 +28409 3 28406 1 0 1 +28409 4 3 25949 2 0 1 +28411 1 28409 1 +28411 2 2 28410 1 +28411 3 28409 4 0 1 +28411 4 2 19551 2 0 1 +28429 1 28427 1 +28429 2 2 28424 1 +28429 3 28427 2 0 1 +28429 4 2 19769 11 0 1 +28433 1 28430 1 +28433 2 3 28427 1 +28433 3 28430 3 0 1 +28433 4 3 24023 9 0 1 +28439 1 28428 1 +28439 2 11 28437 1 +28439 3 28428 5 0 1 +28439 4 11 16708 3 0 1 +28447 1 28444 1 +28447 2 3 28445 1 +28447 3 28444 1 0 1 +28447 4 3 28443 4 0 1 +28463 1 28458 1 +28463 2 5 28458 1 +28463 3 28458 2 0 1 +28463 4 5 19734 7 0 1 +28477 1 28475 1 +28477 2 2 28473 1 +28477 3 28475 6 0 1 +28477 4 2 14427 12 0 1 +28493 1 28491 1 +28493 2 2 28492 1 +28493 3 28491 2 0 1 +28493 4 2 23102 4 0 1 +28499 1 28497 1 +28499 2 2 28493 1 +28499 3 28497 2 0 1 +28499 4 2 24255 0 0 1 +28513 1 28508 1 +28513 2 5 28512 1 +28513 3 28508 2 0 1 +28513 4 5 28274 6 0 1 +28517 1 28515 1 +28517 2 2 28516 1 +28517 3 28515 2 0 1 +28517 4 2 27932 4 0 1 +28537 1 28532 1 +28537 2 5 28536 1 +28537 3 28532 1 0 1 +28537 4 5 19203 6 0 1 +28541 1 28539 1 +28541 2 2 28537 1 +28541 3 28539 2 0 1 +28541 4 2 22580 7 0 1 +28547 1 28545 1 +28547 2 2 28540 1 +28547 3 28545 4 0 1 +28547 4 2 18577 1 0 1 +28549 1 28547 1 +28549 2 2 28548 1 +28549 3 28547 6 0 1 +28549 4 2 21317 9 0 1 +28559 1 28548 1 +28559 2 11 28557 1 +28559 3 28548 4 0 1 +28559 4 11 21583 3 0 1 +28571 1 28569 1 +28571 2 2 28567 1 +28571 3 28569 5 0 1 +28571 4 2 24687 8 0 1 +28573 1 28571 1 +28573 2 2 28572 1 +28573 3 28571 6 0 1 +28573 4 2 20213 7 0 1 +28579 1 28577 1 +28579 2 2 28578 1 +28579 3 28577 5 0 1 +28579 4 2 21361 2 0 1 +28591 1 28588 1 +28591 2 3 28590 1 +28591 3 28588 3 0 1 +28591 4 3 19908 3 0 1 +28597 1 28595 1 +28597 2 2 28593 1 +28597 3 28595 4 0 1 +28597 4 2 18952 6 0 1 +28603 1 28601 1 +28603 2 2 28599 1 +28603 3 28601 6 0 1 +28603 4 2 18823 8 0 1 +28607 1 28602 1 +28607 2 5 28605 1 +28607 3 28602 13 0 1 +28607 4 5 28603 3 0 1 +28619 1 28617 1 +28619 2 2 28615 1 +28619 3 28617 3 0 1 +28619 4 2 26797 19 0 1 +28621 1 28608 1 +28621 2 13 28620 1 +28621 3 28608 5 0 1 +28621 4 13 27089 3 0 1 +28627 1 28622 1 +28627 2 5 28626 1 +28627 3 28622 1 0 1 +28627 4 5 24350 5 0 1 +28631 1 28620 1 +28631 2 11 28625 1 +28631 3 28620 1 0 1 +28631 4 11 17656 7 0 1 +28643 1 28641 1 +28643 2 2 28642 1 +28643 3 28641 2 0 1 +28643 4 2 28636 8 0 1 +28649 1 28646 1 +28649 2 3 28638 1 +28649 3 28646 1 0 1 +28649 4 3 17102 4 0 1 +28657 1 28652 1 +28657 2 5 28649 1 +28657 3 28652 2 0 1 +28657 4 5 17774 1 0 1 +28661 1 28659 1 +28661 2 2 28660 1 +28661 3 28659 7 0 1 +28661 4 2 24490 3 0 1 +28663 1 28660 1 +28663 2 3 28662 1 +28663 3 28660 10 0 1 +28663 4 3 17708 5 0 1 +28669 1 28663 1 +28669 2 6 28668 1 +28669 3 28663 1 0 1 +28669 4 6 19840 11 0 1 +28687 1 28681 1 +28687 2 6 28684 1 +28687 3 28681 1 0 1 +28687 4 6 22832 7 0 1 +28697 1 28694 1 +28697 2 3 28692 1 +28697 3 28694 6 0 1 +28697 4 3 14538 2 0 1 +28703 1 28698 1 +28703 2 5 28689 1 +28703 3 28698 12 0 1 +28703 4 5 28659 3 0 1 +28711 1 28708 1 +28711 2 3 28709 1 +28711 3 28708 1 0 1 +28711 4 3 27443 3 0 1 +28723 1 28721 1 +28723 2 2 28719 1 +28723 3 28721 5 0 1 +28723 4 2 22265 8 0 1 +28729 1 28707 1 +28729 2 22 28728 1 +28729 3 28707 4 0 1 +28729 4 22 16634 12 0 1 +28751 1 28737 1 +28751 2 14 28750 1 +28751 3 28737 6 0 1 +28751 4 14 15346 6 0 1 +28753 1 28743 1 +28753 2 10 28748 1 +28753 3 28743 2 0 1 +28753 4 10 24524 10 0 1 +28759 1 28756 1 +28759 2 3 28757 1 +28759 3 28756 7 0 1 +28759 4 3 23891 3 0 1 +28771 1 28769 1 +28771 2 2 28767 1 +28771 3 28769 2 0 1 +28771 4 2 23259 8 0 1 +28789 1 28782 1 +28789 2 7 28787 1 +28789 3 28782 1 0 1 +28789 4 7 20285 4 0 1 +28793 1 28790 1 +28793 2 3 28792 1 +28793 3 28790 4 0 1 +28793 4 3 19115 6 0 1 +28807 1 28796 1 +28807 2 11 28804 1 +28807 3 28796 6 0 1 +28807 4 11 19354 0 0 1 +28813 1 28811 1 +28813 2 2 28809 1 +28813 3 28811 6 0 1 +28813 4 2 19508 9 0 1 +28817 1 28814 1 +28817 2 3 28816 1 +28817 3 28814 5 0 1 +28817 4 3 18171 6 0 1 +28837 1 28835 1 +28837 2 2 28833 1 +28837 3 28835 4 0 1 +28837 4 2 20125 9 0 1 +28843 1 28841 1 +28843 2 2 28842 1 +28843 3 28841 2 0 1 +28843 4 2 22865 2 0 1 +28859 1 28857 1 +28859 2 2 28858 1 +28859 3 28857 3 0 1 +28859 4 2 17533 4 0 1 +28867 1 28864 1 +28867 2 3 28862 1 +28867 3 28864 4 0 1 +28867 4 3 18464 3 0 1 +28871 1 28858 1 +28871 2 13 28869 1 +28871 3 28858 3 0 1 +28871 4 13 14843 3 0 1 +28879 1 28876 1 +28879 2 3 28877 1 +28879 3 28876 11 0 1 +28879 4 3 28064 3 0 1 +28901 1 28898 1 +28901 2 3 28899 1 +28901 3 28898 8 0 1 +28901 4 3 17058 14 0 1 +28909 1 28907 1 +28909 2 2 28908 1 +28909 3 28907 6 0 1 +28909 4 2 15741 7 0 1 +28921 1 28910 1 +28921 2 11 28916 1 +28921 3 28910 3 0 1 +28921 4 11 15579 16 0 1 +28927 1 28924 1 +28927 2 3 28926 1 +28927 3 28924 4 0 1 +28927 4 3 28027 5 0 1 +28933 1 28931 1 +28933 2 2 28929 1 +28933 3 28931 5 0 1 +28933 4 2 19493 9 0 1 +28949 1 28947 1 +28949 2 2 28945 1 +28949 3 28947 2 0 1 +28949 4 2 27456 7 0 1 +28961 1 28958 1 +28961 2 3 28955 1 +28961 3 28958 1 0 1 +28961 4 3 28949 0 0 1 +28979 1 28977 1 +28979 2 2 28971 1 +28979 3 28977 4 0 1 +28979 4 2 18470 6 0 1 +29009 1 29006 1 +29009 2 3 29008 1 +29009 3 29006 3 0 1 +29009 4 3 26200 4 0 1 +29017 1 29012 1 +29017 2 5 29014 1 +29017 3 29012 2 0 1 +29017 4 5 14998 23 0 1 +29021 1 29019 1 +29021 2 2 29015 1 +29021 3 29019 5 0 1 +29021 4 2 28640 4 0 1 +29023 1 29020 1 +29023 2 3 29021 1 +29023 3 29020 1 0 1 +29023 4 3 18196 6 0 1 +29027 1 29025 1 +29027 2 2 29026 1 +29027 3 29025 2 0 1 +29027 4 2 15411 2 0 1 +29033 1 29030 1 +29033 2 3 29022 1 +29033 3 29030 8 0 1 +29033 4 3 18828 5 0 1 +29059 1 29057 1 +29059 2 2 29054 1 +29059 3 29057 2 0 1 +29059 4 2 22311 2 0 1 +29063 1 29053 1 +29063 2 10 29061 1 +29063 3 29053 3 0 1 +29063 4 10 18950 4 0 1 +29077 1 29075 1 +29077 2 2 29076 1 +29077 3 29075 6 0 1 +29077 4 2 14846 9 0 1 +29101 1 29099 1 +29101 2 2 29097 1 +29101 3 29099 2 0 1 +29101 4 2 21252 6 0 1 +29123 1 29121 1 +29123 2 2 29119 1 +29123 3 29121 2 0 1 +29123 4 2 28287 11 0 1 +29129 1 29126 1 +29129 2 3 29123 1 +29129 3 29126 4 0 1 +29129 4 3 29117 0 0 1 +29131 1 29129 1 +29131 2 2 29127 1 +29131 3 29129 2 0 1 +29131 4 2 26509 8 0 1 +29137 1 29132 1 +29137 2 5 29136 1 +29137 3 29132 1 0 1 +29137 4 5 16303 6 0 1 +29147 1 29145 1 +29147 2 2 29146 1 +29147 3 29145 2 0 1 +29147 4 2 19304 4 0 1 +29153 1 29150 1 +29153 2 3 29147 1 +29153 3 29150 3 0 1 +29153 4 3 17373 1 0 1 +29167 1 29164 1 +29167 2 3 29166 1 +29167 3 29164 1 0 1 +29167 4 3 17782 8 0 1 +29173 1 29171 1 +29173 2 2 29169 1 +29173 3 29171 4 0 1 +29173 4 2 21434 10 0 1 +29179 1 29166 1 +29179 2 13 29178 1 +29179 3 29166 4 0 1 +29179 4 13 28727 2 0 1 +29191 1 29184 1 +29191 2 7 29182 1 +29191 3 29184 1 0 1 +29191 4 7 22099 2 0 1 +29201 1 29198 1 +29201 2 3 29200 1 +29201 3 29198 10 0 1 +29201 4 3 28265 7 0 1 +29207 1 29202 1 +29207 2 5 29205 1 +29207 3 29202 7 0 1 +29207 4 5 29203 3 0 1 +29209 1 29202 1 +29209 2 7 29196 1 +29209 3 29202 1 0 1 +29209 4 7 25391 0 0 1 +29221 1 29219 1 +29221 2 2 29220 1 +29221 3 29219 5 0 1 +29221 4 2 23703 7 0 1 +29231 1 29218 1 +29231 2 13 29229 1 +29231 3 29218 2 0 1 +29231 4 13 15869 4 0 1 +29243 1 29241 1 +29243 2 2 29239 1 +29243 3 29241 3 0 1 +29243 4 2 27114 7 0 1 +29251 1 29249 1 +29251 2 2 29250 1 +29251 3 29249 5 0 1 +29251 4 2 27108 7 0 1 +29269 1 29263 1 +29269 2 6 29265 1 +29269 3 29263 2 0 1 +29269 4 6 20234 2 0 1 +29287 1 29282 1 +29287 2 5 29286 1 +29287 3 29282 2 0 1 +29287 4 5 23381 2 0 1 +29297 1 29294 1 +29297 2 3 29291 1 +29297 3 29294 1 0 1 +29297 4 3 16396 25 0 1 +29303 1 29296 1 +29303 2 7 29301 1 +29303 3 29296 7 0 1 +29303 4 7 23680 10 0 1 +29311 1 29308 1 +29311 2 3 29310 1 +29311 3 29308 15 0 1 +29311 4 3 20443 2 0 1 +29327 1 29322 1 +29327 2 5 29326 1 +29327 3 29322 2 0 1 +29327 4 5 19955 2 0 1 +29333 1 29331 1 +29333 2 2 29332 1 +29333 3 29331 2 0 1 +29333 4 2 26625 3 0 1 +29339 1 29337 1 +29339 2 2 29333 1 +29339 3 29337 2 0 1 +29339 4 2 26845 0 0 1 +29347 1 29344 1 +29347 2 3 29342 1 +29347 3 29344 4 0 1 +29347 4 3 22197 3 0 1 +29363 1 29361 1 +29363 2 2 29362 1 +29363 3 29361 2 0 1 +29363 4 2 22209 2 0 1 +29383 1 29377 1 +29383 2 6 29380 1 +29383 3 29377 12 0 1 +29383 4 6 14840 4 0 1 +29387 1 29385 1 +29387 2 2 29383 1 +29387 3 29385 3 0 1 +29387 4 2 17320 16 0 1 +29389 1 29387 1 +29389 2 2 29388 1 +29389 3 29387 5 0 1 +29389 4 2 29382 8 0 1 +29399 1 29386 1 +29399 2 13 29396 1 +29399 3 29386 4 0 1 +29399 4 13 28356 5 0 1 +29401 1 29388 1 +29401 2 13 29398 1 +29401 3 29388 1 0 1 +29401 4 13 24677 22 0 1 +29411 1 29409 1 +29411 2 2 29404 1 +29411 3 29409 2 0 1 +29411 4 2 14933 0 0 1 +29423 1 29418 1 +29423 2 5 29421 1 +29423 3 29418 1 0 1 +29423 4 5 19236 5 0 1 +29429 1 29427 1 +29429 2 2 29425 1 +29429 3 29427 2 0 1 +29429 4 2 25294 7 0 1 +29437 1 29435 1 +29437 2 2 29433 1 +29437 3 29435 6 0 1 +29437 4 2 25134 12 0 1 +29443 1 29441 1 +29443 2 2 29439 1 +29443 3 29441 5 0 1 +29443 4 2 18291 20 0 1 +29453 1 29451 1 +29453 2 2 29446 1 +29453 3 29451 7 0 1 +29453 4 2 15788 2 0 1 +29473 1 29468 1 +29473 2 5 29468 1 +29473 3 29468 1 0 1 +29473 4 5 21461 15 0 1 +29483 1 29481 1 +29483 2 2 29482 1 +29483 3 29481 2 0 1 +29483 4 2 25211 2 0 1 +29501 1 29499 1 +29501 2 2 29496 1 +29501 3 29499 5 0 1 +29501 4 2 20034 2 0 1 +29527 1 29524 1 +29527 2 3 29525 1 +29527 3 29524 3 0 1 +29527 4 3 21906 6 0 1 +29531 1 29529 1 +29531 2 2 29530 1 +29531 3 29529 11 0 1 +29531 4 2 21925 2 0 1 +29537 1 29534 1 +29537 2 3 29536 1 +29537 3 29534 6 0 1 +29537 4 3 25213 6 0 1 +29567 1 29562 1 +29567 2 5 29566 1 +29567 3 29562 5 0 1 +29567 4 5 20491 7 0 1 +29569 1 29552 1 +29569 2 17 29566 1 +29569 3 29552 3 0 1 +29569 4 17 18151 20 0 1 +29573 1 29571 1 +29573 2 2 29572 1 +29573 3 29571 2 0 1 +29573 4 2 26920 6 0 1 +29581 1 29571 1 +29581 2 10 29580 1 +29581 3 29571 2 0 1 +29581 4 10 17406 7 0 1 +29587 1 29585 1 +29587 2 2 29586 1 +29587 3 29585 2 0 1 +29587 4 2 26406 2 0 1 +29599 1 29586 1 +29599 2 13 29595 1 +29599 3 29586 1 0 1 +29599 4 13 19983 9 0 1 +29611 1 29608 1 +29611 2 3 29610 1 +29611 3 29608 4 0 1 +29611 4 3 26191 6 0 1 +29629 1 29622 1 +29629 2 7 29627 1 +29629 3 29622 1 0 1 +29629 4 7 23634 4 0 1 +29633 1 29630 1 +29633 2 3 29632 1 +29633 3 29630 7 0 1 +29633 4 3 25224 4 0 1 +29641 1 29634 1 +29641 2 7 29634 1 +29641 3 29634 1 0 1 +29641 4 7 24805 0 0 1 +29663 1 29658 1 +29663 2 5 29661 1 +29663 3 29658 2 0 1 +29663 4 5 29659 3 0 1 +29669 1 29667 1 +29669 2 2 29668 1 +29669 3 29667 7 0 1 +29669 4 2 27999 3 0 1 +29671 1 29665 1 +29671 2 6 29669 1 +29671 3 29665 3 0 1 +29671 4 6 26942 3 0 1 +29683 1 29672 1 +29683 2 11 29681 1 +29683 3 29672 2 0 1 +29683 4 11 15914 3 0 1 +29717 1 29715 1 +29717 2 2 29709 1 +29717 3 29715 10 0 1 +29717 4 2 24974 3 0 1 +29723 1 29721 1 +29723 2 2 29719 1 +29723 3 29721 3 0 1 +29723 4 2 16626 7 0 1 +29741 1 29739 1 +29741 2 2 29740 1 +29741 3 29739 9 0 1 +29741 4 2 16425 3 0 1 +29753 1 29750 1 +29753 2 3 29746 1 +29753 3 29750 5 0 1 +29753 4 3 26197 4 0 1 +29759 1 29752 1 +29759 2 7 29758 1 +29759 3 29752 1 0 1 +29759 4 7 22835 2 0 1 +29761 1 29744 1 +29761 2 17 29760 1 +29761 3 29744 1 0 1 +29761 4 17 21538 12 0 1 +29789 1 29787 1 +29789 2 2 29785 1 +29789 3 29787 2 0 1 +29789 4 2 16795 6 0 1 +29803 1 29796 1 +29803 2 7 29801 1 +29803 3 29796 2 0 1 +29803 4 7 20953 11 0 1 +29819 1 29813 1 +29819 2 6 29818 1 +29819 3 29813 1 0 1 +29819 4 6 22081 5 0 1 +29833 1 29828 1 +29833 2 5 29832 1 +29833 3 29828 2 0 1 +29833 4 5 21582 6 0 1 +29837 1 29835 1 +29837 2 2 29836 1 +29837 3 29835 2 0 1 +29837 4 2 20232 4 0 1 +29851 1 29849 1 +29851 2 2 29850 1 +29851 3 29849 5 0 1 +29851 4 2 19580 2 0 1 +29863 1 29853 1 +29863 2 10 29862 1 +29863 3 29853 4 0 1 +29863 4 10 24650 2 0 1 +29867 1 29865 1 +29867 2 2 29863 1 +29867 3 29865 3 0 1 +29867 4 2 27059 7 0 1 +29873 1 29870 1 +29873 2 3 29872 1 +29873 3 29870 10 0 1 +29873 4 3 20724 6 0 1 +29879 1 29868 1 +29879 2 11 29877 1 +29879 3 29868 6 0 1 +29879 4 11 25142 3 0 1 +29881 1 29874 1 +29881 2 7 29878 1 +29881 3 29874 3 0 1 +29881 4 7 22162 16 0 1 +29917 1 29915 1 +29917 2 2 29916 1 +29917 3 29915 6 0 1 +29917 4 2 26532 3 0 1 +29921 1 29918 1 +29921 2 3 29915 1 +29921 3 29918 1 0 1 +29921 4 3 29909 0 0 1 +29927 1 29922 1 +29927 2 5 29924 1 +29927 3 29922 10 0 1 +29927 4 5 28232 6 0 1 +29947 1 29944 1 +29947 2 3 29942 1 +29947 3 29944 1 0 1 +29947 4 3 27189 3 0 1 +29959 1 29953 1 +29959 2 6 29957 1 +29959 3 29953 1 0 1 +29959 4 6 23001 3 0 1 +29983 1 29978 1 +29983 2 5 29981 1 +29983 3 29978 9 0 1 +29983 4 5 20417 17 0 1 +29989 1 29987 1 +29989 2 2 29980 1 +29989 3 29987 2 0 1 +29989 4 2 27546 3 0 1 +30011 1 30009 1 +30011 2 2 30005 1 +30011 3 30009 9 0 1 +30011 4 2 26951 0 0 1 +30013 1 30011 1 +30013 2 2 30009 1 +30013 3 30011 5 0 1 +30013 4 2 28053 12 0 1 +30029 1 30027 1 +30029 2 2 30025 1 +30029 3 30027 3 0 1 +30029 4 2 17215 1 0 1 +30047 1 30042 1 +30047 2 5 30046 1 +30047 3 30042 2 0 1 +30047 4 5 22017 3 0 1 +30059 1 30057 1 +30059 2 2 30055 1 +30059 3 30057 3 0 1 +30059 4 2 29484 7 0 1 +30071 1 30058 1 +30071 2 13 30070 1 +30071 3 30058 7 0 1 +30071 4 13 27810 2 0 1 +30089 1 30086 1 +30089 2 3 30084 1 +30089 3 30086 9 0 1 +30089 4 3 15442 2 0 1 +30091 1 30070 1 +30091 2 21 30090 1 +30091 3 30070 2 0 1 +30091 4 21 18186 6 0 1 +30097 1 30087 1 +30097 2 10 30096 1 +30097 3 30087 5 0 1 +30097 4 10 18998 21 0 1 +30103 1 30100 1 +30103 2 3 30101 1 +30103 3 30100 6 0 1 +30103 4 3 22137 6 0 1 +30109 1 30107 1 +30109 2 2 30102 1 +30109 3 30107 5 0 1 +30109 4 2 19414 33 0 1 +30113 1 30110 1 +30113 2 3 30108 1 +30113 3 30110 3 0 1 +30113 4 3 22214 0 0 1 +30119 1 30108 1 +30119 2 11 30117 1 +30119 3 30108 4 0 1 +30119 4 11 22758 8 0 1 +30133 1 30128 1 +30133 2 5 30132 1 +30133 3 30128 1 0 1 +30133 4 5 23507 6 0 1 +30137 1 30134 1 +30137 2 3 30136 1 +30137 3 30134 4 0 1 +30137 4 3 17463 7 0 1 +30139 1 30137 1 +30139 2 2 30133 1 +30139 3 30137 6 0 1 +30139 4 2 20974 12 0 1 +30161 1 30158 1 +30161 2 3 30160 1 +30161 3 30158 4 0 1 +30161 4 3 21019 4 0 1 +30169 1 30162 1 +30169 2 7 30160 1 +30169 3 30162 2 0 1 +30169 4 7 19551 2 0 1 +30181 1 30179 1 +30181 2 2 30177 1 +30181 3 30179 2 0 1 +30181 4 2 18980 6 0 1 +30187 1 30182 1 +30187 2 5 30186 1 +30187 3 30182 1 0 1 +30187 4 5 19640 7 0 1 +30197 1 30195 1 +30197 2 2 30193 1 +30197 3 30195 3 0 1 +30197 4 2 21691 1 0 1 +30203 1 30201 1 +30203 2 2 30202 1 +30203 3 30201 5 0 1 +30203 4 2 30196 8 0 1 +30211 1 30209 1 +30211 2 2 30203 1 +30211 3 30209 6 0 1 +30211 4 2 16242 6 0 1 +30223 1 30220 1 +30223 2 3 30222 1 +30223 3 30220 5 0 1 +30223 4 3 27943 5 0 1 +30241 1 30230 1 +30241 2 11 30240 1 +30241 3 30230 3 0 1 +30241 4 11 16745 12 0 1 +30253 1 30251 1 +30253 2 2 30252 1 +30253 3 30251 2 0 1 +30253 4 2 21456 6 0 1 +30259 1 30256 1 +30259 2 3 30254 1 +30259 3 30256 5 0 1 +30259 4 3 29870 3 0 1 +30269 1 30266 1 +30269 2 3 30268 1 +30269 3 30266 1 0 1 +30269 4 3 21776 3 0 1 +30271 1 30268 1 +30271 2 3 30270 1 +30271 3 30268 4 0 1 +30271 4 3 16756 2 0 1 +30293 1 30291 1 +30293 2 2 30289 1 +30293 3 30291 3 0 1 +30293 4 2 21473 7 0 1 +30307 1 30305 1 +30307 2 2 30303 1 +30307 3 30305 4 0 1 +30307 4 2 26118 8 0 1 +30313 1 30308 1 +30313 2 5 30312 1 +30313 3 30308 8 0 1 +30313 4 5 18238 6 0 1 +30319 1 30316 1 +30319 2 3 30313 1 +30319 3 30316 3 0 1 +30319 4 3 15805 15 0 1 +30323 1 30321 1 +30323 2 2 30322 1 +30323 3 30321 2 0 1 +30323 4 2 28026 2 0 1 +30341 1 30339 1 +30341 2 2 30335 1 +30341 3 30339 9 0 1 +30341 4 2 28783 3 0 1 +30347 1 30345 1 +30347 2 2 30343 1 +30347 3 30345 3 0 1 +30347 4 2 17617 14 0 1 +30367 1 30362 1 +30367 2 5 30365 1 +30367 3 30362 6 0 1 +30367 4 5 30355 11 0 1 +30389 1 30387 1 +30389 2 2 30385 1 +30389 3 30387 2 0 1 +30389 4 2 23109 6 0 1 +30391 1 30388 1 +30391 2 3 30389 1 +30391 3 30388 3 0 1 +30391 4 3 24019 3 0 1 +30403 1 30398 1 +30403 2 5 30402 1 +30403 3 30398 7 0 1 +30403 4 5 19714 14 0 1 +30427 1 30422 1 +30427 2 5 30426 1 +30427 3 30422 2 0 1 +30427 4 5 16271 7 0 1 +30431 1 30420 1 +30431 2 11 30416 1 +30431 3 30420 11 0 1 +30431 4 11 16803 4 0 1 +30449 1 30446 1 +30449 2 3 30443 1 +30449 3 30446 6 0 1 +30449 4 3 30437 0 0 1 +30467 1 30465 1 +30467 2 2 30463 1 +30467 3 30465 3 0 1 +30467 4 2 23496 7 0 1 +30469 1 30467 1 +30469 2 2 30468 1 +30469 3 30467 5 0 1 +30469 4 2 29917 3 0 1 +30491 1 30489 1 +30491 2 2 30487 1 +30491 3 30489 3 0 1 +30491 4 2 29458 16 0 1 +30493 1 30487 1 +30493 2 6 30491 1 +30493 3 30487 2 0 1 +30493 4 6 23342 4 0 1 +30497 1 30494 1 +30497 2 3 30485 1 +30497 3 30494 6 0 1 +30497 4 3 25756 6 0 1 +30509 1 30507 1 +30509 2 2 30504 1 +30509 3 30507 5 0 1 +30509 4 2 27775 2 0 1 +30517 1 30515 1 +30517 2 2 30513 1 +30517 3 30515 5 0 1 +30517 4 2 26108 10 0 1 +30529 1 30516 1 +30529 2 13 30528 1 +30529 3 30516 1 0 1 +30529 4 13 19269 14 0 1 +30539 1 30537 1 +30539 2 2 30535 1 +30539 3 30537 3 0 1 +30539 4 2 17947 7 0 1 +30553 1 30548 1 +30553 2 5 30550 1 +30553 3 30548 2 0 1 +30553 4 5 19373 10 0 1 +30557 1 30555 1 +30557 2 2 30553 1 +30557 3 30555 3 0 1 +30557 4 2 15679 7 0 1 +30559 1 30552 1 +30559 2 7 30548 1 +30559 3 30552 7 0 1 +30559 4 7 27067 0 0 1 +30577 1 30572 1 +30577 2 5 30574 1 +30577 3 30572 6 0 1 +30577 4 5 30566 14 0 1 +30593 1 30590 1 +30593 2 3 30592 1 +30593 3 30590 6 0 1 +30593 4 3 17254 4 0 1 +30631 1 30628 1 +30631 2 3 30630 1 +30631 3 30628 3 0 1 +30631 4 3 19988 2 0 1 +30637 1 30635 1 +30637 2 2 30636 1 +30637 3 30635 2 0 1 +30637 4 2 23467 3 0 1 +30643 1 30641 1 +30643 2 2 30639 1 +30643 3 30641 10 0 1 +30643 4 2 20662 8 0 1 +30649 1 30642 1 +30649 2 7 30638 1 +30649 3 30642 1 0 1 +30649 4 7 22659 30 0 1 +30661 1 30659 1 +30661 2 2 30657 1 +30661 3 30659 5 0 1 +30661 4 2 20324 6 0 1 +30671 1 30660 1 +30671 2 11 30670 1 +30671 3 30660 1 0 1 +30671 4 11 17644 3 0 1 +30677 1 30675 1 +30677 2 2 30676 1 +30677 3 30675 3 0 1 +30677 4 2 23980 6 0 1 +30689 1 30686 1 +30689 2 3 30683 1 +30689 3 30686 1 0 1 +30689 4 3 30677 0 0 1 +30697 1 30687 1 +30697 2 10 30692 1 +30697 3 30687 2 0 1 +30697 4 10 28684 16 0 1 +30703 1 30700 1 +30703 2 3 30702 1 +30703 3 30700 7 0 1 +30703 4 3 22014 5 0 1 +30707 1 30705 1 +30707 2 2 30706 1 +30707 3 30705 3 0 1 +30707 4 2 23927 4 0 1 +30713 1 30710 1 +30713 2 3 30708 1 +30713 3 30710 3 0 1 +30713 4 3 27578 0 0 1 +30727 1 30724 1 +30727 2 3 30725 1 +30727 3 30724 5 0 1 +30727 4 3 24780 6 0 1 +30757 1 30752 1 +30757 2 5 30756 1 +30757 3 30752 2 0 1 +30757 4 5 26454 6 0 1 +30763 1 30761 1 +30763 2 2 30762 1 +30763 3 30761 4 0 1 +30763 4 2 25015 7 0 1 +30773 1 30770 1 +30773 2 3 30772 1 +30773 3 30770 1 0 1 +30773 4 3 30762 12 0 1 +30781 1 30779 1 +30781 2 2 30777 1 +30781 3 30779 4 0 1 +30781 4 2 19287 6 0 1 +30803 1 30801 1 +30803 2 2 30799 1 +30803 3 30801 2 0 1 +30803 4 2 16549 13 0 1 +30809 1 30806 1 +30809 2 3 30787 1 +30809 3 30806 4 0 1 +30809 4 3 27459 5 0 1 +30817 1 30812 1 +30817 2 5 30816 1 +30817 3 30812 1 0 1 +30817 4 5 24603 6 0 1 +30829 1 30827 1 +30829 2 2 30825 1 +30829 3 30827 2 0 1 +30829 4 2 16743 10 0 1 +30839 1 30832 1 +30839 2 7 30837 1 +30839 3 30832 13 0 1 +30839 4 7 25900 5 0 1 +30841 1 30834 1 +30841 2 7 30834 1 +30841 3 30834 12 0 1 +30841 4 7 25905 21 0 1 +30851 1 30849 1 +30851 2 2 30847 1 +30851 3 30849 3 0 1 +30851 4 2 26815 8 0 1 +30853 1 30851 1 +30853 2 2 30849 1 +30853 3 30851 6 0 1 +30853 4 2 18765 12 0 1 +30859 1 30857 1 +30859 2 2 30858 1 +30859 3 30857 6 0 1 +30859 4 2 17937 6 0 1 +30869 1 30867 1 +30869 2 2 30865 1 +30869 3 30867 3 0 1 +30869 4 2 22574 1 0 1 +30871 1 30868 1 +30871 2 3 30869 1 +30871 3 30868 3 0 1 +30871 4 3 23037 3 0 1 +30881 1 30878 1 +30881 2 3 30876 1 +30881 3 30878 5 0 1 +30881 4 3 23515 2 0 1 +30893 1 30891 1 +30893 2 2 30889 1 +30893 3 30891 3 0 1 +30893 4 2 30107 12 0 1 +30911 1 30894 1 +30911 2 17 30909 1 +30911 3 30894 2 0 1 +30911 4 17 21641 7 0 1 +30931 1 30929 1 +30931 2 2 30930 1 +30931 3 30929 5 0 1 +30931 4 2 20931 12 0 1 +30937 1 30922 1 +30937 2 15 30934 1 +30937 3 30922 1 0 1 +30937 4 15 16156 20 0 1 +30941 1 30939 1 +30941 2 2 30937 1 +30941 3 30939 2 0 1 +30941 4 2 18994 7 0 1 +30949 1 30939 1 +30949 2 10 30946 1 +30949 3 30939 2 0 1 +30949 4 10 20186 5 0 1 +30971 1 30969 1 +30971 2 2 30963 1 +30971 3 30969 4 0 1 +30971 4 2 30666 6 0 1 +30977 1 30974 1 +30977 2 3 30972 1 +30977 3 30974 3 0 1 +30977 4 3 20520 2 0 1 +30983 1 30978 1 +30983 2 5 30982 1 +30983 3 30978 3 0 1 +30983 4 5 15644 2 0 1 +31013 1 31011 1 +31013 2 2 31012 1 +31013 3 31011 2 0 1 +31013 4 2 23752 4 0 1 +31019 1 31017 1 +31019 2 2 31015 1 +31019 3 31017 2 0 1 +31019 4 2 30714 8 0 1 +31033 1 31023 1 +31033 2 10 31032 1 +31033 3 31023 2 0 1 +31033 4 10 26446 6 0 1 +31039 1 31032 1 +31039 2 7 31036 1 +31039 3 31032 1 0 1 +31039 4 7 19176 0 0 1 +31051 1 31040 1 +31051 2 11 31050 1 +31051 3 31040 2 0 1 +31051 4 11 23777 5 0 1 +31063 1 31060 1 +31063 2 3 31062 1 +31063 3 31060 4 0 1 +31063 4 3 26380 2 0 1 +31069 1 31067 1 +31069 2 2 31068 1 +31069 3 31067 6 0 1 +31069 4 2 25009 7 0 1 +31079 1 31068 1 +31079 2 11 31077 1 +31079 3 31068 6 0 1 +31079 4 11 29978 5 0 1 +31081 1 31068 1 +31081 2 13 31080 1 +31081 3 31068 2 0 1 +31081 4 13 19769 18 0 1 +31091 1 31089 1 +31091 2 2 31085 1 +31091 3 31089 7 0 1 +31091 4 2 18968 7 0 1 +31121 1 31118 1 +31121 2 3 31111 1 +31121 3 31118 4 0 1 +31121 4 3 29125 4 0 1 +31123 1 31120 1 +31123 2 3 31116 1 +31123 3 31120 6 0 1 +31123 4 3 18218 11 0 1 +31139 1 31137 1 +31139 2 2 31138 1 +31139 3 31137 3 0 1 +31139 4 2 17165 2 0 1 +31147 1 31145 1 +31147 2 2 31143 1 +31147 3 31145 6 0 1 +31147 4 2 22415 8 0 1 +31151 1 31144 1 +31151 2 7 31149 1 +31151 3 31144 9 0 1 +31151 4 7 26366 12 0 1 +31153 1 31143 1 +31153 2 10 31152 1 +31153 3 31143 2 0 1 +31153 4 10 30170 15 0 1 +31159 1 31156 1 +31159 2 3 31158 1 +31159 3 31156 1 0 1 +31159 4 3 27759 2 0 1 +31177 1 31170 1 +31177 2 7 31170 1 +31177 3 31170 2 0 1 +31177 4 7 19612 12 0 1 +31181 1 31179 1 +31181 2 2 31180 1 +31181 3 31179 3 0 1 +31181 4 2 28389 3 0 1 +31183 1 31180 1 +31183 2 3 31181 1 +31183 3 31180 6 0 1 +31183 4 3 31179 4 0 1 +31189 1 31176 1 +31189 2 13 31188 1 +31189 3 31176 3 0 1 +31189 4 13 20344 7 0 1 +31193 1 31188 1 +31193 2 5 31192 1 +31193 3 31188 5 0 1 +31193 4 5 20145 6 0 1 +31219 1 31209 1 +31219 2 10 31217 1 +31219 3 31209 2 0 1 +31219 4 10 31207 6 0 1 +31223 1 31218 1 +31223 2 5 31221 1 +31223 3 31218 3 0 1 +31223 4 5 27619 5 0 1 +31231 1 31225 1 +31231 2 6 31230 1 +31231 3 31225 3 0 1 +31231 4 6 24588 3 0 1 +31237 1 31231 1 +31237 2 6 31235 1 +31237 3 31231 7 0 1 +31237 4 6 31227 7 0 1 +31247 1 31242 1 +31247 2 5 31244 1 +31247 3 31242 1 0 1 +31247 4 5 28170 11 0 1 +31249 1 31226 1 +31249 2 23 31245 1 +31249 3 31226 9 0 1 +31249 4 23 26334 27 0 1 +31253 1 31251 1 +31253 2 2 31252 1 +31253 3 31251 3 0 1 +31253 4 2 29539 3 0 1 +31259 1 31257 1 +31259 2 2 31255 1 +31259 3 31257 2 0 1 +31259 4 2 20506 8 0 1 +31267 1 31265 1 +31267 2 2 31266 1 +31267 3 31265 4 0 1 +31267 4 2 27397 2 0 1 +31271 1 31264 1 +31271 2 7 31270 1 +31271 3 31264 1 0 1 +31271 4 7 19977 2 0 1 +31277 1 31275 1 +31277 2 2 31270 1 +31277 3 31275 4 0 1 +31277 4 2 30358 5 0 1 +31307 1 31305 1 +31307 2 2 31303 1 +31307 3 31305 2 0 1 +31307 4 2 27165 13 0 1 +31319 1 31312 1 +31319 2 7 31308 1 +31319 3 31312 10 0 1 +31319 4 7 25793 4 0 1 +31321 1 31314 1 +31321 2 7 31314 1 +31321 3 31314 2 0 1 +31321 4 7 25513 0 0 1 +31327 1 31321 1 +31327 2 6 31324 1 +31327 3 31321 8 0 1 +31327 4 6 21898 4 0 1 +31333 1 31328 1 +31333 2 5 31332 1 +31333 3 31328 2 0 1 +31333 4 5 25417 6 0 1 +31337 1 31334 1 +31337 2 3 31332 1 +31337 3 31334 5 0 1 +31337 4 3 27679 0 0 1 +31357 1 31355 1 +31357 2 2 31353 1 +31357 3 31355 9 0 1 +31357 4 2 24570 12 0 1 +31379 1 31377 1 +31379 2 2 31378 1 +31379 3 31377 5 0 1 +31379 4 2 27418 4 0 1 +31387 1 31385 1 +31387 2 2 31386 1 +31387 3 31385 4 0 1 +31387 4 2 15928 10 0 1 +31391 1 31360 1 +31391 2 31 31389 1 +31391 3 31360 1 0 1 +31391 4 31 16662 4 0 1 +31393 1 31388 1 +31393 2 5 31390 1 +31393 3 31388 2 0 1 +31393 4 5 26054 10 0 1 +31397 1 31395 1 +31397 2 2 31393 1 +31397 3 31395 3 0 1 +31397 4 2 28910 9 0 1 +31469 1 31467 1 +31469 2 2 31459 1 +31469 3 31467 7 0 1 +31469 4 2 19610 0 0 1 +31477 1 31471 1 +31477 2 6 31475 1 +31477 3 31471 1 0 1 +31477 4 6 16850 0 0 1 +31481 1 31475 1 +31481 2 6 31478 1 +31481 3 31475 1 0 1 +31481 4 6 30304 14 0 1 +31489 1 31482 1 +31489 2 7 31482 1 +31489 3 31482 1 0 1 +31489 4 7 28488 0 0 1 +31511 1 31504 1 +31511 2 7 31510 1 +31511 3 31504 4 0 1 +31511 4 7 17581 7 0 1 +31513 1 31506 1 +31513 2 7 31506 1 +31513 3 31506 9 0 1 +31513 4 7 25338 12 0 1 +31517 1 31515 1 +31517 2 2 31511 1 +31517 3 31515 3 0 1 +31517 4 2 30053 1 0 1 +31531 1 31529 1 +31531 2 2 31530 1 +31531 3 31529 5 0 1 +31531 4 2 20456 6 0 1 +31541 1 31538 1 +31541 2 3 31539 1 +31541 3 31538 1 0 1 +31541 4 3 31537 4 0 1 +31543 1 31540 1 +31543 2 3 31542 1 +31543 3 31540 1 0 1 +31543 4 3 20872 2 0 1 +31547 1 31545 1 +31547 2 2 31546 1 +31547 3 31545 2 0 1 +31547 4 2 17600 2 0 1 +31567 1 31561 1 +31567 2 6 31566 1 +31567 3 31561 1 0 1 +31567 4 6 24886 2 0 1 +31573 1 31568 1 +31573 2 5 31572 1 +31573 3 31568 2 0 1 +31573 4 5 18777 3 0 1 +31583 1 31578 1 +31583 2 5 31578 1 +31583 3 31578 1 0 1 +31583 4 5 30502 7 0 1 +31601 1 31598 1 +31601 2 3 31596 1 +31601 3 31598 8 0 1 +31601 4 3 20344 2 0 1 +31607 1 31602 1 +31607 2 5 31602 1 +31607 3 31602 2 0 1 +31607 4 5 30966 7 0 1 +31627 1 31624 1 +31627 2 3 31626 1 +31627 3 31624 4 0 1 +31627 4 3 21695 2 0 1 +31643 1 31641 1 +31643 2 2 31642 1 +31643 3 31641 2 0 1 +31643 4 2 21228 4 0 1 +31649 1 31646 1 +31649 2 3 31648 1 +31649 3 31646 1 0 1 +31649 4 3 27565 4 0 1 +31657 1 31652 1 +31657 2 5 31656 1 +31657 3 31652 2 0 1 +31657 4 5 23384 6 0 1 +31663 1 31660 1 +31663 2 3 31661 1 +31663 3 31660 4 0 1 +31663 4 3 25142 6 0 1 +31667 1 31665 1 +31667 2 2 31666 1 +31667 3 31665 2 0 1 +31667 4 2 21477 2 0 1 +31687 1 31684 1 +31687 2 3 31686 1 +31687 3 31684 1 0 1 +31687 4 3 21500 5 0 1 +31699 1 31697 1 +31699 2 2 31698 1 +31699 3 31697 4 0 1 +31699 4 2 16753 10 0 1 +31721 1 31710 1 +31721 2 11 31716 1 +31721 3 31710 2 0 1 +31721 4 11 29853 11 0 1 +31723 1 31720 1 +31723 2 3 31716 1 +31723 3 31720 3 0 1 +31723 4 3 27099 5 0 1 +31727 1 31722 1 +31727 2 5 31725 1 +31727 3 31722 7 0 1 +31727 4 5 31723 3 0 1 +31729 1 31722 1 +31729 2 7 31726 1 +31729 3 31722 1 0 1 +31729 4 7 23340 24 0 1 +31741 1 31735 1 +31741 2 6 31737 1 +31741 3 31735 2 0 1 +31741 4 6 31737 6 0 1 +31751 1 31740 1 +31751 2 11 31749 1 +31751 3 31740 1 0 1 +31751 4 11 21928 3 0 1 +31769 1 31763 1 +31769 2 6 31757 1 +31769 3 31763 1 0 1 +31769 4 6 17097 5 0 1 +31771 1 31761 1 +31771 2 10 31769 1 +31771 3 31761 5 0 1 +31771 4 10 27394 8 0 1 +31793 1 31790 1 +31793 2 3 31780 1 +31793 3 31790 3 0 1 +31793 4 3 25278 3 0 1 +31799 1 31788 1 +31799 2 11 31798 1 +31799 3 31788 2 0 1 +31799 4 11 28237 2 0 1 +31817 1 31814 1 +31817 2 3 31812 1 +31817 3 31814 9 0 1 +31817 4 3 31345 0 0 1 +31847 1 31842 1 +31847 2 5 31845 1 +31847 3 31842 1 0 1 +31847 4 5 31843 3 0 1 +31849 1 31835 1 +31849 2 14 31846 1 +31849 3 31835 2 0 1 +31849 4 14 25058 10 0 1 +31859 1 31857 1 +31859 2 2 31855 1 +31859 3 31857 9 0 1 +31859 4 2 16084 7 0 1 +31873 1 31862 1 +31873 2 11 31871 1 +31873 3 31862 4 0 1 +31873 4 11 16816 17 0 1 +31883 1 31881 1 +31883 2 2 31882 1 +31883 3 31881 2 0 1 +31883 4 2 20059 4 0 1 +31891 1 31889 1 +31891 2 2 31890 1 +31891 3 31889 6 0 1 +31891 4 2 25349 7 0 1 +31907 1 31905 1 +31907 2 2 31901 1 +31907 3 31905 9 0 1 +31907 4 2 20919 4 0 1 +31957 1 31955 1 +31957 2 2 31953 1 +31957 3 31955 4 0 1 +31957 4 2 24976 12 0 1 +31963 1 31961 1 +31963 2 2 31959 1 +31963 3 31961 4 0 1 +31963 4 2 31017 10 0 1 +31973 1 31971 1 +31973 2 2 31969 1 +31973 3 31971 3 0 1 +31973 4 2 16771 9 0 1 +31981 1 31975 1 +31981 2 6 31980 1 +31981 3 31975 4 0 1 +31981 4 6 22591 22 0 1 +31991 1 31984 1 +31991 2 7 31988 1 +31991 3 31984 1 0 1 +31991 4 7 24528 5 0 1 +32003 1 32001 1 +32003 2 2 31995 1 +32003 3 32001 2 0 1 +32003 4 2 17396 0 0 1 +32009 1 32006 1 +32009 2 3 32008 1 +32009 3 32006 6 0 1 +32009 4 3 19461 4 0 1 +32027 1 32025 1 +32027 2 2 32023 1 +32027 3 32025 3 0 1 +32027 4 2 21014 14 0 1 +32029 1 32027 1 +32029 2 2 32025 1 +32029 3 32027 4 0 1 +32029 4 2 23167 12 0 1 +32051 1 32041 1 +32051 2 10 32046 1 +32051 3 32041 2 0 1 +32051 4 10 25281 3 0 1 +32057 1 32054 1 +32057 2 3 32050 1 +32057 3 32054 1 0 1 +32057 4 3 20274 1 0 1 +32059 1 32057 1 +32059 2 2 32055 1 +32059 3 32057 6 0 1 +32059 4 2 18541 1 0 1 +32063 1 32058 1 +32063 2 5 32062 1 +32063 3 32058 2 0 1 +32063 4 5 18079 2 0 1 +32069 1 32067 1 +32069 2 2 32065 1 +32069 3 32067 3 0 1 +32069 4 2 16860 6 0 1 +32077 1 32075 1 +32077 2 2 32076 1 +32077 3 32075 6 0 1 +32077 4 2 21600 6 0 1 +32083 1 32081 1 +32083 2 2 32079 1 +32083 3 32081 4 0 1 +32083 4 2 22551 8 0 1 +32089 1 32076 1 +32089 2 13 32088 1 +32089 3 32076 5 0 1 +32089 4 13 20637 12 0 1 +32099 1 32097 1 +32099 2 2 32095 1 +32099 3 32097 3 0 1 +32099 4 2 24817 7 0 1 +32117 1 32115 1 +32117 2 2 32113 1 +32117 3 32115 3 0 1 +32117 4 2 20811 7 0 1 +32119 1 32116 1 +32119 2 3 32118 1 +32119 3 32116 1 0 1 +32119 4 3 26845 3 0 1 +32141 1 32139 1 +32141 2 2 32136 1 +32141 3 32139 11 0 1 +32141 4 2 17811 2 0 1 +32143 1 32137 1 +32143 2 6 32139 1 +32143 3 32137 2 0 1 +32143 4 6 24658 1 0 1 +32159 1 32152 1 +32159 2 7 32157 1 +32159 3 32152 4 0 1 +32159 4 7 27961 5 0 1 +32173 1 32168 1 +32173 2 5 32168 1 +32173 3 32168 1 0 1 +32173 4 5 24843 7 0 1 +32183 1 32178 1 +32183 2 5 32181 1 +32183 3 32178 6 0 1 +32183 4 5 32179 3 0 1 +32189 1 32187 1 +32189 2 2 32188 1 +32189 3 32187 3 0 1 +32189 4 2 18279 4 0 1 +32191 1 32185 1 +32191 2 6 32190 1 +32191 3 32185 1 0 1 +32191 4 6 23688 2 0 1 +32203 1 32201 1 +32203 2 2 32202 1 +32203 3 32201 2 0 1 +32203 4 2 24230 2 0 1 +32213 1 32211 1 +32213 2 2 32209 1 +32213 3 32211 3 0 1 +32213 4 2 23787 1 0 1 +32233 1 32228 1 +32233 2 5 32228 1 +32233 3 32228 1 0 1 +32233 4 5 28092 20 0 1 +32237 1 32235 1 +32237 2 2 32233 1 +32237 3 32235 4 0 1 +32237 4 2 18370 6 0 1 +32251 1 32248 1 +32251 2 3 32250 1 +32251 3 32248 14 0 1 +32251 4 3 25215 2 0 1 +32257 1 32242 1 +32257 2 15 32256 1 +32257 3 32242 1 0 1 +32257 4 15 22507 20 0 1 +32261 1 32259 1 +32261 2 2 32257 1 +32261 3 32259 3 0 1 +32261 4 2 29740 1 0 1 +32297 1 32294 1 +32297 2 3 32291 1 +32297 3 32294 6 0 1 +32297 4 3 23537 9 0 1 +32299 1 32287 1 +32299 2 12 32298 1 +32299 3 32287 5 0 1 +32299 4 12 20907 7 0 1 +32303 1 32298 1 +32303 2 5 32302 1 +32303 3 32298 5 0 1 +32303 4 5 20531 7 0 1 +32309 1 32307 1 +32309 2 2 32300 1 +32309 3 32307 4 0 1 +32309 4 2 25180 1 0 1 +32321 1 32315 1 +32321 2 6 32309 1 +32321 3 32315 7 0 1 +32321 4 6 20416 0 0 1 +32323 1 32321 1 +32323 2 2 32319 1 +32323 3 32321 6 0 1 +32323 4 2 30321 10 0 1 +32327 1 32322 1 +32327 2 5 32326 1 +32327 3 32322 3 0 1 +32327 4 5 19526 3 0 1 +32341 1 32339 1 +32341 2 2 32337 1 +32341 3 32339 4 0 1 +32341 4 2 18167 6 0 1 +32353 1 32338 1 +32353 2 15 32351 1 +32353 3 32338 3 0 1 +32353 4 15 32325 16 0 1 +32359 1 32356 1 +32359 2 3 32358 1 +32359 3 32356 1 0 1 +32359 4 3 26081 3 0 1 +32363 1 32361 1 +32363 2 2 32356 1 +32363 3 32361 8 0 1 +32363 4 2 27433 0 0 1 +32369 1 32363 1 +32369 2 6 32359 1 +32369 3 32363 2 0 1 +32369 4 6 25327 4 0 1 +32371 1 32369 1 +32371 2 2 32370 1 +32371 3 32369 6 0 1 +32371 4 2 30989 6 0 1 +32377 1 32372 1 +32377 2 5 32372 1 +32377 3 32372 3 0 1 +32377 4 5 25952 15 0 1 +32381 1 32379 1 +32381 2 2 32377 1 +32381 3 32379 3 0 1 +32381 4 2 30655 1 0 1 +32401 1 32394 1 +32401 2 7 32394 1 +32401 3 32394 5 0 1 +32401 4 7 20058 0 0 1 +32411 1 32409 1 +32411 2 2 32399 1 +32411 3 32409 2 0 1 +32411 4 2 30480 1 0 1 +32413 1 32408 1 +32413 2 5 32412 1 +32413 3 32408 1 0 1 +32413 4 5 20094 6 0 1 +32423 1 32418 1 +32423 2 5 32421 1 +32423 3 32418 2 0 1 +32423 4 5 19579 9 0 1 +32429 1 32426 1 +32429 2 3 32424 1 +32429 3 32426 3 0 1 +32429 4 3 17357 2 0 1 +32441 1 32438 1 +32441 2 3 32440 1 +32441 3 32438 3 0 1 +32441 4 3 29800 7 0 1 +32443 1 32441 1 +32443 2 2 32442 1 +32443 3 32441 4 0 1 +32443 4 2 23922 2 0 1 +32467 1 32465 1 +32467 2 2 32463 1 +32467 3 32465 5 0 1 +32467 4 2 29034 8 0 1 +32479 1 32473 1 +32479 2 6 32477 1 +32479 3 32473 2 0 1 +32479 4 6 28790 3 0 1 +32491 1 32489 1 +32491 2 2 32487 1 +32491 3 32489 2 0 1 +32491 4 2 18735 10 0 1 +32497 1 32490 1 +32497 2 7 32490 1 +32497 3 32490 4 0 1 +32497 4 7 16766 21 0 1 +32503 1 32500 1 +32503 2 3 32501 1 +32503 3 32500 5 0 1 +32503 4 3 32026 3 0 1 +32507 1 32505 1 +32507 2 2 32506 1 +32507 3 32505 2 0 1 +32507 4 2 22167 12 0 1 +32531 1 32529 1 +32531 2 2 32527 1 +32531 3 32529 3 0 1 +32531 4 2 16799 7 0 1 +32533 1 32531 1 +32533 2 2 32529 1 +32533 3 32531 6 0 1 +32533 4 2 25409 17 0 1 +32537 1 32534 1 +32537 2 3 32536 1 +32537 3 32534 5 0 1 +32537 4 3 28952 11 0 1 +32561 1 32555 1 +32561 2 6 32555 1 +32561 3 32555 1 0 1 +32561 4 6 19428 0 0 1 +32563 1 32561 1 +32563 2 2 32562 1 +32563 3 32561 2 0 1 +32563 4 2 24619 7 0 1 +32569 1 32562 1 +32569 2 7 32562 1 +32569 3 32562 1 0 1 +32569 4 7 20514 0 0 1 +32573 1 32571 1 +32573 2 2 32566 1 +32573 3 32571 14 0 1 +32573 4 2 29250 5 0 1 +32579 1 32573 1 +32579 2 6 32577 1 +32579 3 32573 3 0 1 +32579 4 6 23356 0 0 1 +32587 1 32585 1 +32587 2 2 32583 1 +32587 3 32585 4 0 1 +32587 4 2 28439 8 0 1 +32603 1 32601 1 +32603 2 2 32598 1 +32603 3 32601 4 0 1 +32603 4 2 24530 9 0 1 +32609 1 32606 1 +32609 2 3 32603 1 +32609 3 32606 3 0 1 +32609 4 3 19295 3 0 1 +32611 1 32608 1 +32611 2 3 32610 1 +32611 3 32608 6 0 1 +32611 4 3 28696 6 0 1 +32621 1 32618 1 +32621 2 3 32620 1 +32621 3 32618 7 0 1 +32621 4 3 29276 3 0 1 +32633 1 32630 1 +32633 2 3 32627 1 +32633 3 32630 5 0 1 +32633 4 3 28234 13 0 1 +32647 1 32644 1 +32647 2 3 32646 1 +32647 3 32644 3 0 1 +32647 4 3 17491 5 0 1 +32653 1 32651 1 +32653 2 2 32652 1 +32653 3 32651 2 0 1 +32653 4 2 22423 6 0 1 +32687 1 32682 1 +32687 2 5 32684 1 +32687 3 32682 2 0 1 +32687 4 5 30309 6 0 1 +32693 1 32691 1 +32693 2 2 32692 1 +32693 3 32691 2 0 1 +32693 4 2 23175 4 0 1 +32707 1 32704 1 +32707 2 3 32692 1 +32707 3 32704 8 0 1 +32707 4 3 23204 1 0 1 +32713 1 32708 1 +32713 2 5 32712 1 +32713 3 32708 1 0 1 +32713 4 5 18247 6 0 1 +32717 1 32715 1 +32717 2 2 32703 1 +32717 3 32715 2 0 1 +32717 4 2 29481 2 0 1 +32719 1 32716 1 +32719 2 3 32717 1 +32719 3 32716 11 0 1 +32719 4 3 32715 4 0 1 +32749 1 32747 1 +32749 2 2 32748 1 +32749 3 32747 5 0 1 +32749 4 2 30851 3 0 1 +32771 1 32769 1 +32771 2 2 32767 1 +32771 3 32769 2 0 1 +32771 4 2 32259 7 0 1 +32779 1 32776 1 +32779 2 3 32774 1 +32779 3 32776 6 0 1 +32779 4 3 26012 3 0 1 +32783 1 32776 1 +32783 2 7 32782 1 +32783 3 32776 2 0 1 +32783 4 7 28998 3 0 1 +32789 1 32787 1 +32789 2 2 32781 1 +32789 3 32787 2 0 1 +32789 4 2 32277 11 0 1 +32797 1 32795 1 +32797 2 2 32793 1 +32797 3 32795 6 0 1 +32797 4 2 28616 9 0 1 +32801 1 32798 1 +32801 2 3 32800 1 +32801 3 32798 3 0 1 +32801 4 3 22863 4 0 1 +32803 1 32798 1 +32803 2 5 32801 1 +32803 3 32798 2 0 1 +32803 4 5 25866 0 0 1 +32831 1 32818 1 +32831 2 13 32830 1 +32831 3 32818 4 0 1 +32831 4 13 18423 2 0 1 +32833 1 32828 1 +32833 2 5 32828 1 +32833 3 32828 3 0 1 +32833 4 5 29968 10 0 1 +32839 1 32833 1 +32839 2 6 32835 1 +32839 3 32833 2 0 1 +32839 4 6 21220 8 0 1 +32843 1 32841 1 +32843 2 2 32839 1 +32843 3 32841 2 0 1 +32843 4 2 17834 11 0 1 +32869 1 32863 1 +32869 2 6 32865 1 +32869 3 32863 9 0 1 +32869 4 6 27500 10 0 1 +32887 1 32884 1 +32887 2 3 32886 1 +32887 3 32884 1 0 1 +32887 4 3 26361 2 0 1 +32909 1 32907 1 +32909 2 2 32904 1 +32909 3 32907 2 0 1 +32909 4 2 18890 16 0 1 +32911 1 32908 1 +32911 2 3 32910 1 +32911 3 32908 1 0 1 +32911 4 3 18623 2 0 1 +32917 1 32915 1 +32917 2 2 32916 1 +32917 3 32915 6 0 1 +32917 4 2 21131 9 0 1 +32933 1 32931 1 +32933 2 2 32932 1 +32933 3 32931 2 0 1 +32933 4 2 20665 3 0 1 +32939 1 32937 1 +32939 2 2 32929 1 +32939 3 32937 2 0 1 +32939 4 2 21184 0 0 1 +32941 1 32939 1 +32941 2 2 32940 1 +32941 3 32939 5 0 1 +32941 4 2 22761 3 0 1 +32957 1 32945 1 +32957 2 12 32956 1 +32957 3 32945 4 0 1 +32957 4 12 18115 9 0 1 +32969 1 32966 1 +32969 2 3 32963 1 +32969 3 32966 8 0 1 +32969 4 3 32957 0 0 1 +32971 1 32960 1 +32971 2 11 32970 1 +32971 3 32960 1 0 1 +32971 4 11 24648 7 0 1 +32983 1 32980 1 +32983 2 3 32981 1 +32983 3 32980 4 0 1 +32983 4 3 16927 3 0 1 +32987 1 32985 1 +32987 2 2 32986 1 +32987 3 32985 2 0 1 +32987 4 2 28023 2 0 1 +32993 1 32990 1 +32993 2 3 32987 1 +32993 3 32990 1 0 1 +32993 4 3 32244 1 0 1 +32999 1 32992 1 +32999 2 7 32997 1 +32999 3 32992 4 0 1 +32999 4 7 31501 5 0 1 +33013 1 33008 1 +33013 2 5 33012 1 +33013 3 33008 2 0 1 +33013 4 5 17239 6 0 1 +33023 1 33018 1 +33023 2 5 33018 1 +33023 3 33018 2 0 1 +33023 4 5 27157 7 0 1 +33029 1 33027 1 +33029 2 2 33028 1 +33029 3 33027 3 0 1 +33029 4 2 27592 3 0 1 +33037 1 33035 1 +33037 2 2 33033 1 +33037 3 33035 4 0 1 +33037 4 2 26224 6 0 1 +33049 1 33020 1 +33049 2 29 33048 1 +33049 3 33020 3 0 1 +33049 4 29 17775 20 0 1 +33053 1 33051 1 +33053 2 2 33052 1 +33053 3 33051 2 0 1 +33053 4 2 23062 4 0 1 +33071 1 33060 1 +33071 2 11 33060 1 +33071 3 33060 4 0 1 +33071 4 11 30672 0 0 1 +33073 1 33068 1 +33073 2 5 33072 1 +33073 3 33068 3 0 1 +33073 4 5 18093 6 0 1 +33083 1 33081 1 +33083 2 2 33073 1 +33083 3 33081 7 0 1 +33083 4 2 29809 8 0 1 +33091 1 33088 1 +33091 2 3 33086 1 +33091 3 33088 1 0 1 +33091 4 3 27901 3 0 1 +33107 1 33105 1 +33107 2 2 33101 1 +33107 3 33105 9 0 1 +33107 4 2 19761 4 0 1 +33113 1 33110 1 +33113 2 3 33108 1 +33113 3 33110 3 0 1 +33113 4 3 22628 0 0 1 +33119 1 33112 1 +33119 2 7 33118 1 +33119 3 33112 1 0 1 +33119 4 7 33110 4 0 1 +33149 1 33147 1 +33149 2 2 33145 1 +33149 3 33147 3 0 1 +33149 4 2 16778 7 0 1 +33151 1 33148 1 +33151 2 3 33150 1 +33151 3 33148 3 0 1 +33151 4 3 26104 2 0 1 +33161 1 33158 1 +33161 2 3 33156 1 +33161 3 33158 9 0 1 +33161 4 3 20542 2 0 1 +33179 1 33177 1 +33179 2 2 33178 1 +33179 3 33177 3 0 1 +33179 4 2 32385 6 0 1 +33181 1 33175 1 +33181 2 6 33180 1 +33181 3 33175 1 0 1 +33181 4 6 22519 7 0 1 +33191 1 33184 1 +33191 2 7 33190 1 +33191 3 33184 2 0 1 +33191 4 7 20472 2 0 1 +33199 1 33196 1 +33199 2 3 33197 1 +33199 3 33196 3 0 1 +33199 4 3 20640 6 0 1 +33203 1 33201 1 +33203 2 2 33197 1 +33203 3 33201 4 0 1 +33203 4 2 21507 4 0 1 +33211 1 33209 1 +33211 2 2 33210 1 +33211 3 33209 6 0 1 +33211 4 2 25145 2 0 1 +33223 1 33213 1 +33223 2 10 33222 1 +33223 3 33213 4 0 1 +33223 4 10 23554 2 0 1 +33247 1 33242 1 +33247 2 5 33245 1 +33247 3 33242 3 0 1 +33247 4 5 27069 10 0 1 +33287 1 33282 1 +33287 2 5 33286 1 +33287 3 33282 2 0 1 +33287 4 5 23269 2 0 1 +33289 1 33260 1 +33289 2 29 33282 1 +33289 3 33260 1 0 1 +33289 4 29 17665 24 0 1 +33301 1 33299 1 +33301 2 2 33297 1 +33301 3 33299 6 0 1 +33301 4 2 29088 12 0 1 +33311 1 33300 1 +33311 2 11 33310 1 +33311 3 33300 11 0 1 +33311 4 11 20962 2 0 1 +33317 1 33315 1 +33317 2 2 33309 1 +33317 3 33315 10 0 1 +33317 4 2 32351 3 0 1 +33329 1 33326 1 +33329 2 3 33323 1 +33329 3 33326 18 0 1 +33329 4 3 33317 0 0 1 +33331 1 33328 1 +33331 2 3 33324 1 +33331 3 33328 1 0 1 +33331 4 3 19187 5 0 1 +33343 1 33340 1 +33343 2 3 33342 1 +33343 3 33340 6 0 1 +33343 4 3 33332 12 0 1 +33347 1 33345 1 +33347 2 2 33343 1 +33347 3 33345 3 0 1 +33347 4 2 27382 7 0 1 +33349 1 33347 1 +33349 2 2 33345 1 +33349 3 33347 4 0 1 +33349 4 2 28951 6 0 1 +33353 1 33350 1 +33353 2 3 33348 1 +33353 3 33350 1 0 1 +33353 4 3 17232 0 0 1 +33359 1 33352 1 +33359 2 7 33356 1 +33359 3 33352 3 0 1 +33359 4 7 32248 5 0 1 +33377 1 33372 1 +33377 2 5 33376 1 +33377 3 33372 3 0 1 +33377 4 5 17018 6 0 1 +33391 1 33385 1 +33391 2 6 33389 1 +33391 3 33385 1 0 1 +33391 4 6 26084 4 0 1 +33403 1 33400 1 +33403 2 3 33402 1 +33403 3 33400 8 0 1 +33403 4 3 26826 5 0 1 +33409 1 33402 1 +33409 2 7 33402 1 +33409 3 33402 11 0 1 +33409 4 7 26059 0 0 1 +33413 1 33411 1 +33413 2 2 33405 1 +33413 3 33411 4 0 1 +33413 4 2 24533 13 0 1 +33427 1 33425 1 +33427 2 2 33423 1 +33427 3 33425 6 0 1 +33427 4 2 23368 10 0 1 +33457 1 33447 1 +33457 2 10 33456 1 +33457 3 33447 5 0 1 +33457 4 10 25484 12 0 1 +33461 1 33458 1 +33461 2 3 33460 1 +33461 3 33458 7 0 1 +33461 4 3 32603 3 0 1 +33469 1 33467 1 +33469 2 2 33465 1 +33469 3 33467 2 0 1 +33469 4 2 22958 10 0 1 +33479 1 33462 1 +33479 2 17 33478 1 +33479 3 33462 1 0 1 +33479 4 17 26329 2 0 1 +33487 1 33481 1 +33487 2 6 33484 1 +33487 3 33481 1 0 1 +33487 4 6 26490 4 0 1 +33493 1 33491 1 +33493 2 2 33492 1 +33493 3 33491 5 0 1 +33493 4 2 33486 8 0 1 +33503 1 33498 1 +33503 2 5 33501 1 +33503 3 33498 8 0 1 +33503 4 5 20309 5 0 1 +33521 1 33515 1 +33521 2 6 33518 1 +33521 3 33515 4 0 1 +33521 4 6 32624 10 0 1 +33529 1 33522 1 +33529 2 7 33522 1 +33529 3 33522 1 0 1 +33529 4 7 25410 0 0 1 +33533 1 33531 1 +33533 2 2 33532 1 +33533 3 33531 3 0 1 +33533 4 2 18904 6 0 1 +33547 1 33545 1 +33547 2 2 33546 1 +33547 3 33545 4 0 1 +33547 4 2 32059 7 0 1 +33563 1 33561 1 +33563 2 2 33559 1 +33563 3 33561 3 0 1 +33563 4 2 22030 14 0 1 +33569 1 33566 1 +33569 2 3 33563 1 +33569 3 33566 8 0 1 +33569 4 3 33557 0 0 1 +33577 1 33572 1 +33577 2 5 33572 1 +33577 3 33572 1 0 1 +33577 4 5 32243 10 0 1 +33581 1 33579 1 +33581 2 2 33576 1 +33581 3 33579 7 0 1 +33581 4 2 31633 2 0 1 +33587 1 33581 1 +33587 2 6 33573 1 +33587 3 33581 1 0 1 +33587 4 6 26388 9 0 1 +33589 1 33587 1 +33589 2 2 33588 1 +33589 3 33587 6 0 1 +33589 4 2 26734 3 0 1 +33599 1 33588 1 +33599 2 11 33583 1 +33599 3 33588 4 0 1 +33599 4 11 26711 3 0 1 +33601 1 33572 1 +33601 2 29 33600 1 +33601 3 33572 1 0 1 +33601 4 29 29589 12 0 1 +33613 1 33608 1 +33613 2 5 33612 1 +33613 3 33608 5 0 1 +33613 4 5 18310 3 0 1 +33617 1 33614 1 +33617 2 3 33611 1 +33617 3 33614 1 0 1 +33617 4 3 31668 11 0 1 +33619 1 33617 1 +33619 2 2 33618 1 +33619 3 33617 5 0 1 +33619 4 2 28186 2 0 1 +33623 1 33618 1 +33623 2 5 33622 1 +33623 3 33618 3 0 1 +33623 4 5 20626 4 0 1 +33629 1 33627 1 +33629 2 2 33621 1 +33629 3 33627 3 0 1 +33629 4 2 20008 0 0 1 +33637 1 33635 1 +33637 2 2 33633 1 +33637 3 33635 6 0 1 +33637 4 2 23036 6 0 1 +33641 1 33638 1 +33641 2 3 33630 1 +33641 3 33638 1 0 1 +33641 4 3 32587 4 0 1 +33647 1 33642 1 +33647 2 5 33645 1 +33647 3 33642 5 0 1 +33647 4 5 21492 5 0 1 +33679 1 33676 1 +33679 2 3 33678 1 +33679 3 33676 1 0 1 +33679 4 3 32838 3 0 1 +33703 1 33698 1 +33703 2 5 33701 1 +33703 3 33698 3 0 1 +33703 4 5 33699 3 0 1 +33713 1 33710 1 +33713 2 3 33706 1 +33713 3 33710 1 0 1 +33713 4 3 25095 2 0 1 +33721 1 33710 1 +33721 2 11 33716 1 +33721 3 33710 3 0 1 +33721 4 11 33702 24 0 1 +33739 1 33737 1 +33739 2 2 33738 1 +33739 3 33737 6 0 1 +33739 4 2 28573 2 0 1 +33749 1 33747 1 +33749 2 2 33745 1 +33749 3 33747 2 0 1 +33749 4 2 25591 12 0 1 +33751 1 33745 1 +33751 2 6 33750 1 +33751 3 33745 1 0 1 +33751 4 6 22979 3 0 1 +33757 1 33755 1 +33757 2 2 33756 1 +33757 3 33755 2 0 1 +33757 4 2 27295 6 0 1 +33767 1 33762 1 +33767 2 5 33764 1 +33767 3 33762 5 0 1 +33767 4 5 17486 4 0 1 +33769 1 33758 1 +33769 2 11 33753 1 +33769 3 33758 3 0 1 +33769 4 11 33247 5 0 1 +33773 1 33771 1 +33773 2 2 33772 1 +33773 3 33771 2 0 1 +33773 4 2 24868 4 0 1 +33791 1 33784 1 +33791 2 7 33789 1 +33791 3 33784 2 0 1 +33791 4 7 22107 11 0 1 +33797 1 33794 1 +33797 2 3 33795 1 +33797 3 33794 6 0 1 +33797 4 3 32757 14 0 1 +33809 1 33806 1 +33809 2 3 33808 1 +33809 3 33806 12 0 1 +33809 4 3 27277 7 0 1 +33811 1 33796 1 +33811 2 15 33809 1 +33811 3 33796 3 0 1 +33811 4 15 24502 0 0 1 +33827 1 33825 1 +33827 2 2 33826 1 +33827 3 33825 12 0 1 +33827 4 2 33820 8 0 1 +33829 1 33827 1 +33829 2 2 33828 1 +33829 3 33827 8 0 1 +33829 4 2 29111 7 0 1 +33851 1 33849 1 +33851 2 2 33850 1 +33851 3 33849 3 0 1 +33851 4 2 33049 6 0 1 +33857 1 33854 1 +33857 2 3 33856 1 +33857 3 33854 1 0 1 +33857 4 3 30037 4 0 1 +33863 1 33858 1 +33863 2 5 33861 1 +33863 3 33858 7 0 1 +33863 4 5 24686 5 0 1 +33871 1 33856 1 +33871 2 15 33869 1 +33871 3 33856 1 0 1 +33871 4 15 26736 4 0 1 +33889 1 33876 1 +33889 2 13 33880 1 +33889 3 33876 5 0 1 +33889 4 13 24533 28 0 1 +33893 1 33891 1 +33893 2 2 33892 1 +33893 3 33891 2 0 1 +33893 4 2 17992 4 0 1 +33911 1 33900 1 +33911 2 11 33910 1 +33911 3 33900 13 0 1 +33911 4 11 26841 3 0 1 +33923 1 33921 1 +33923 2 2 33911 1 +33923 3 33921 5 0 1 +33923 4 2 20091 23 0 1 +33931 1 33929 1 +33931 2 2 33925 1 +33931 3 33929 6 0 1 +33931 4 2 17987 3 0 1 +33937 1 33932 1 +33937 2 5 33936 1 +33937 3 33932 2 0 1 +33937 4 5 20229 6 0 1 +33941 1 33939 1 +33941 2 2 33940 1 +33941 3 33939 3 0 1 +33941 4 2 26503 3 0 1 +33961 1 33948 1 +33961 2 13 33960 1 +33961 3 33948 15 0 1 +33961 4 13 24460 14 0 1 +33967 1 33964 1 +33967 2 3 33966 1 +33967 3 33964 1 0 1 +33967 4 3 20622 5 0 1 +33997 1 33995 1 +33997 2 2 33996 1 +33997 3 33995 2 0 1 +33997 4 2 28864 3 0 1 +34019 1 34017 1 +34019 2 2 34009 1 +34019 3 34017 4 0 1 +34019 4 2 21975 0 0 1 +34031 1 34024 1 +34031 2 7 34030 1 +34031 3 34024 1 0 1 +34031 4 7 34022 4 0 1 +34033 1 34026 1 +34033 2 7 34026 1 +34033 3 34026 3 0 1 +34033 4 7 19209 12 0 1 +34039 1 34036 1 +34039 2 3 34037 1 +34039 3 34036 4 0 1 +34039 4 3 29357 3 0 1 +34057 1 34052 1 +34057 2 5 34052 1 +34057 3 34052 7 0 1 +34057 4 5 24647 25 0 1 +34061 1 34059 1 +34061 2 2 34057 1 +34061 3 34059 3 0 1 +34061 4 2 28075 1 0 1 +34123 1 34121 1 +34123 2 2 34122 1 +34123 3 34121 4 0 1 +34123 4 2 34116 8 0 1 +34127 1 34122 1 +34127 2 5 34126 1 +34127 3 34122 7 0 1 +34127 4 5 33807 2 0 1 +34129 1 34118 1 +34129 2 11 34128 1 +34129 3 34118 3 0 1 +34129 4 11 27504 18 0 1 +34141 1 34139 1 +34141 2 2 34137 1 +34141 3 34139 4 0 1 +34141 4 2 17568 6 0 1 +34147 1 34144 1 +34147 2 3 34138 1 +34147 3 34144 1 0 1 +34147 4 3 22260 2 0 1 +34157 1 34155 1 +34157 2 2 34153 1 +34157 3 34155 3 0 1 +34157 4 2 19275 12 0 1 +34159 1 34156 1 +34159 2 3 34154 1 +34159 3 34156 4 0 1 +34159 4 3 20405 7 0 1 +34171 1 34169 1 +34171 2 2 34167 1 +34171 3 34169 6 0 1 +34171 4 2 23285 8 0 1 +34183 1 34180 1 +34183 2 3 34182 1 +34183 3 34180 1 0 1 +34183 4 3 26315 2 0 1 +34211 1 34209 1 +34211 2 2 34207 1 +34211 3 34209 16 0 1 +34211 4 2 30318 7 0 1 +34213 1 34211 1 +34213 2 2 34209 1 +34213 3 34211 6 0 1 +34213 4 2 21739 10 0 1 +34217 1 34214 1 +34217 2 3 34211 1 +34217 3 34214 1 0 1 +34217 4 3 30499 12 0 1 +34231 1 34225 1 +34231 2 6 34229 1 +34231 3 34225 3 0 1 +34231 4 6 18282 4 0 1 +34253 1 34251 1 +34253 2 2 34241 1 +34253 3 34251 20 0 1 +34253 4 2 22385 4 0 1 +34259 1 34257 1 +34259 2 2 34242 1 +34259 3 34257 2 0 1 +34259 4 2 27770 7 0 1 +34261 1 34259 1 +34261 2 2 34260 1 +34261 3 34259 6 0 1 +34261 4 2 27220 3 0 1 +34267 1 34265 1 +34267 2 2 34262 1 +34267 3 34265 5 0 1 +34267 4 2 22256 2 0 1 +34273 1 34268 1 +34273 2 5 34270 1 +34273 3 34268 3 0 1 +34273 4 5 20465 18 0 1 +34283 1 34281 1 +34283 2 2 34277 1 +34283 3 34281 9 0 1 +34283 4 2 30976 7 0 1 +34297 1 34292 1 +34297 2 5 34296 1 +34297 3 34292 2 0 1 +34297 4 5 24969 6 0 1 +34301 1 34298 1 +34301 2 3 34289 1 +34301 3 34298 17 0 1 +34301 4 3 30648 2 0 1 +34303 1 34286 1 +34303 2 17 34302 1 +34303 3 34286 1 0 1 +34303 4 17 20822 2 0 1 +34313 1 34310 1 +34313 2 3 34308 1 +34313 3 34310 3 0 1 +34313 4 3 25339 0 0 1 +34319 1 34300 1 +34319 2 19 34301 1 +34319 3 34300 1 0 1 +34319 4 19 29846 19 0 1 +34327 1 34322 1 +34327 2 5 34326 1 +34327 3 34322 3 0 1 +34327 4 5 31086 2 0 1 +34337 1 34334 1 +34337 2 3 34336 1 +34337 3 34334 1 0 1 +34337 4 3 22979 6 0 1 +34351 1 34348 1 +34351 2 3 34349 1 +34351 3 34348 1 0 1 +34351 4 3 32470 3 0 1 +34361 1 34358 1 +34361 2 3 34360 1 +34361 3 34358 3 0 1 +34361 4 3 30241 7 0 1 +34367 1 34362 1 +34367 2 5 34366 1 +34367 3 34362 3 0 1 +34367 4 5 19563 4 0 1 +34369 1 34362 1 +34369 2 7 34358 1 +34369 3 34362 2 0 1 +34369 4 7 21857 18 0 1 +34381 1 34375 1 +34381 2 6 34380 1 +34381 3 34375 2 0 1 +34381 4 6 18518 11 0 1 +34403 1 34401 1 +34403 2 2 34402 1 +34403 3 34401 2 0 1 +34403 4 2 18263 13 0 1 +34421 1 34419 1 +34421 2 2 34417 1 +34421 3 34419 2 0 1 +34421 4 2 32218 23 0 1 +34429 1 34427 1 +34429 2 2 34428 1 +34429 3 34427 4 0 1 +34429 4 2 21285 3 0 1 +34439 1 34428 1 +34439 2 11 34437 1 +34439 3 34428 11 0 1 +34439 4 11 17799 3 0 1 +34457 1 34454 1 +34457 2 3 34452 1 +34457 3 34454 3 0 1 +34457 4 3 25198 0 0 1 +34469 1 34459 1 +34469 2 10 34460 1 +34469 3 34459 7 0 1 +34469 4 10 24838 7 0 1 +34471 1 34465 1 +34471 2 6 34470 1 +34471 3 34465 1 0 1 +34471 4 6 19446 3 0 1 +34483 1 34481 1 +34483 2 2 34479 1 +34483 3 34481 6 0 1 +34483 4 2 24949 8 0 1 +34487 1 34482 1 +34487 2 5 34486 1 +34487 3 34482 1 0 1 +34487 4 5 28325 4 0 1 +34499 1 34497 1 +34499 2 2 34495 1 +34499 3 34497 3 0 1 +34499 4 2 18492 7 0 1 +34501 1 34494 1 +34501 2 7 34499 1 +34501 3 34494 4 0 1 +34501 4 7 28465 12 0 1 +34511 1 34504 1 +34511 2 7 34509 1 +34511 3 34504 1 0 1 +34511 4 7 24801 4 0 1 +34513 1 34502 1 +34513 2 11 34512 1 +34513 3 34502 2 0 1 +34513 4 11 33682 8 0 1 +34519 1 34516 1 +34519 2 3 34517 1 +34519 3 34516 4 0 1 +34519 4 3 25289 3 0 1 +34537 1 34532 1 +34537 2 5 34536 1 +34537 3 34532 11 0 1 +34537 4 5 34274 6 0 1 +34543 1 34537 1 +34543 2 6 34542 1 +34543 3 34537 1 0 1 +34543 4 6 28376 3 0 1 +34549 1 34547 1 +34549 2 2 34545 1 +34549 3 34547 2 0 1 +34549 4 2 19235 6 0 1 +34583 1 34578 1 +34583 2 5 34582 1 +34583 3 34578 1 0 1 +34583 4 5 32137 4 0 1 +34589 1 34587 1 +34589 2 2 34585 1 +34589 3 34587 7 0 1 +34589 4 2 23410 6 0 1 +34591 1 34588 1 +34591 2 3 34590 1 +34591 3 34588 5 0 1 +34591 4 3 24433 2 0 1 +34603 1 34601 1 +34603 2 2 34599 1 +34603 3 34601 4 0 1 +34603 4 2 21587 8 0 1 +34607 1 34597 1 +34607 2 10 34605 1 +34607 3 34597 6 0 1 +34607 4 10 24077 4 0 1 +34613 1 34611 1 +34613 2 2 34609 1 +34613 3 34611 2 0 1 +34613 4 2 30117 1 0 1 +34631 1 34624 1 +34631 2 7 34630 1 +34631 3 34624 3 0 1 +34631 4 7 20505 3 0 1 +34649 1 34646 1 +34649 2 3 34648 1 +34649 3 34646 7 0 1 +34649 4 3 25174 7 0 1 +34651 1 34649 1 +34651 2 2 34647 1 +34651 3 34649 2 0 1 +34651 4 2 27131 8 0 1 +34667 1 34665 1 +34667 2 2 34663 1 +34667 3 34665 2 0 1 +34667 4 2 22401 7 0 1 +34673 1 34670 1 +34673 2 3 34668 1 +34673 3 34670 3 0 1 +34673 4 3 29380 0 0 1 +34679 1 34672 1 +34679 2 7 34675 1 +34679 3 34672 4 0 1 +34679 4 7 28528 5 0 1 +34687 1 34682 1 +34687 2 5 34686 1 +34687 3 34682 11 0 1 +34687 4 5 20425 5 0 1 +34693 1 34687 1 +34693 2 6 34691 1 +34693 3 34687 1 0 1 +34693 4 6 26188 8 0 1 +34703 1 34698 1 +34703 2 5 34701 1 +34703 3 34698 6 0 1 +34703 4 5 24420 5 0 1 +34721 1 34718 1 +34721 2 3 34716 1 +34721 3 34718 1 0 1 +34721 4 3 34194 8 0 1 +34729 1 34716 1 +34729 2 13 34726 1 +34729 3 34716 6 0 1 +34729 4 13 22002 14 0 1 +34739 1 34733 1 +34739 2 6 34736 1 +34739 3 34733 1 0 1 +34739 4 6 29717 1 0 1 +34747 1 34745 1 +34747 2 2 34746 1 +34747 3 34745 2 0 1 +34747 4 2 34740 8 0 1 +34757 1 34755 1 +34757 2 2 34749 1 +34757 3 34755 13 0 1 +34757 4 2 18057 11 0 1 +34759 1 34753 1 +34759 2 6 34757 1 +34759 3 34753 2 0 1 +34759 4 6 25196 4 0 1 +34763 1 34761 1 +34763 2 2 34759 1 +34763 3 34761 3 0 1 +34763 4 2 26536 8 0 1 +34781 1 34779 1 +34781 2 2 34775 1 +34781 3 34779 3 0 1 +34781 4 2 34012 3 0 1 +34807 1 34804 1 +34807 2 3 34805 1 +34807 3 34804 10 0 1 +34807 4 3 30898 3 0 1 +34819 1 34817 1 +34819 2 2 34814 1 +34819 3 34817 2 0 1 +34819 4 2 20983 3 0 1 +34841 1 34838 1 +34841 2 3 34835 1 +34841 3 34838 4 0 1 +34841 4 3 34829 0 0 1 +34843 1 34841 1 +34843 2 2 34839 1 +34843 3 34841 4 0 1 +34843 4 2 21035 8 0 1 +34847 1 34840 1 +34847 2 7 34845 1 +34847 3 34840 2 0 1 +34847 4 7 33401 6 0 1 +34849 1 34842 1 +34849 2 7 34842 1 +34849 3 34842 7 0 1 +34849 4 7 28928 0 0 1 +34871 1 34864 1 +34871 2 7 34870 1 +34871 3 34864 3 0 1 +34871 4 7 22279 2 0 1 +34877 1 34875 1 +34877 2 2 34876 1 +34877 3 34875 2 0 1 +34877 4 2 18970 3 0 1 +34883 1 34881 1 +34883 2 2 34877 1 +34883 3 34881 4 0 1 +34883 4 2 24993 0 0 1 +34897 1 34892 1 +34897 2 5 34896 1 +34897 3 34892 7 0 1 +34897 4 5 25694 11 0 1 +34913 1 34910 1 +34913 2 3 34908 1 +34913 3 34910 1 0 1 +34913 4 3 21047 0 0 1 +34919 1 34900 1 +34919 2 19 34918 1 +34919 3 34900 1 0 1 +34919 4 19 27648 2 0 1 +34939 1 34937 1 +34939 2 2 34935 1 +34939 3 34937 2 0 1 +34939 4 2 22028 10 0 1 +34949 1 34947 1 +34949 2 2 34945 1 +34949 3 34947 3 0 1 +34949 4 2 33588 1 0 1 +34961 1 34958 1 +34961 2 3 34949 1 +34961 3 34958 1 0 1 +34961 4 3 21770 0 0 1 +34963 1 34961 1 +34963 2 2 34962 1 +34963 3 34961 2 0 1 +34963 4 2 32993 2 0 1 +34981 1 34979 1 +34981 2 2 34977 1 +34981 3 34979 6 0 1 +34981 4 2 21190 6 0 1 +35023 1 35018 1 +35023 2 5 35021 1 +35023 3 35018 2 0 1 +35023 4 5 35019 3 0 1 +35027 1 35025 1 +35027 2 2 35023 1 +35027 3 35025 3 0 1 +35027 4 2 33020 11 0 1 +35051 1 35049 1 +35051 2 2 35047 1 +35051 3 35049 3 0 1 +35051 4 2 31484 7 0 1 +35053 1 35051 1 +35053 2 2 35049 1 +35053 3 35051 6 0 1 +35053 4 2 34378 12 0 1 +35059 1 35049 1 +35059 2 10 35058 1 +35059 3 35049 2 0 1 +35059 4 10 24233 2 0 1 +35069 1 35067 1 +35069 2 2 35065 1 +35069 3 35067 3 0 1 +35069 4 2 23519 1 0 1 +35081 1 35078 1 +35081 2 3 35080 1 +35081 3 35078 4 0 1 +35081 4 3 24328 4 0 1 +35083 1 35081 1 +35083 2 2 35082 1 +35083 3 35081 2 0 1 +35083 4 2 30282 11 0 1 +35089 1 35078 1 +35089 2 11 35086 1 +35089 3 35078 11 0 1 +35089 4 11 23856 10 0 1 +35099 1 35097 1 +35099 2 2 35095 1 +35099 3 35097 2 0 1 +35099 4 2 30378 7 0 1 +35107 1 35105 1 +35107 2 2 35103 1 +35107 3 35105 5 0 1 +35107 4 2 33400 8 0 1 +35111 1 35098 1 +35111 2 13 35106 1 +35111 3 35098 2 0 1 +35111 4 13 34316 6 0 1 +35117 1 35115 1 +35117 2 2 35116 1 +35117 3 35115 2 0 1 +35117 4 2 29689 4 0 1 +35129 1 35126 1 +35129 2 3 35128 1 +35129 3 35126 4 0 1 +35129 4 3 30888 4 0 1 +35141 1 35139 1 +35141 2 2 35137 1 +35141 3 35139 2 0 1 +35141 4 2 22688 7 0 1 +35149 1 35147 1 +35149 2 2 35145 1 +35149 3 35147 2 0 1 +35149 4 2 33603 6 0 1 +35153 1 35150 1 +35153 2 3 35152 1 +35153 3 35150 10 0 1 +35153 4 3 30948 7 0 1 +35159 1 35148 1 +35159 2 11 35158 1 +35159 3 35148 2 0 1 +35159 4 11 27315 3 0 1 +35171 1 35169 1 +35171 2 2 35164 1 +35171 3 35169 4 0 1 +35171 4 2 30035 1 0 1 +35201 1 35198 1 +35201 2 3 35195 1 +35201 3 35198 5 0 1 +35201 4 3 35189 0 0 1 +35221 1 35215 1 +35221 2 6 35217 1 +35221 3 35215 4 0 1 +35221 4 6 19694 2 0 1 +35227 1 35225 1 +35227 2 2 35226 1 +35227 3 35225 2 0 1 +35227 4 2 21352 11 0 1 +35251 1 35248 1 +35251 2 3 35250 1 +35251 3 35248 6 0 1 +35251 4 3 34574 7 0 1 +35257 1 35250 1 +35257 2 7 35250 1 +35257 3 35250 5 0 1 +35257 4 7 22970 12 0 1 +35267 1 35265 1 +35267 2 2 35263 1 +35267 3 35265 3 0 1 +35267 4 2 34156 7 0 1 +35279 1 35250 1 +35279 2 29 35278 1 +35279 3 35250 7 0 1 +35279 4 29 18049 2 0 1 +35281 1 35258 1 +35281 2 23 35278 1 +35281 3 35258 1 0 1 +35281 4 23 25185 32 0 1 +35291 1 35289 1 +35291 2 2 35287 1 +35291 3 35289 2 0 1 +35291 4 2 23112 8 0 1 +35311 1 35300 1 +35311 2 11 35310 1 +35311 3 35300 3 0 1 +35311 4 11 20984 3 0 1 +35317 1 35312 1 +35317 2 5 35316 1 +35317 3 35312 1 0 1 +35317 4 5 23743 6 0 1 +35323 1 35320 1 +35323 2 3 35322 1 +35323 3 35320 8 0 1 +35323 4 3 20708 5 0 1 +35327 1 35322 1 +35327 2 5 35324 1 +35327 3 35322 1 0 1 +35327 4 5 23922 4 0 1 +35339 1 35337 1 +35339 2 2 35338 1 +35339 3 35337 3 0 1 +35339 4 2 20494 4 0 1 +35353 1 35348 1 +35353 2 5 35352 1 +35353 3 35348 5 0 1 +35353 4 5 21644 8 0 1 +35363 1 35361 1 +35363 2 2 35359 1 +35363 3 35361 2 0 1 +35363 4 2 29573 7 0 1 +35381 1 35378 1 +35381 2 3 35379 1 +35381 3 35378 3 0 1 +35381 4 3 28683 14 0 1 +35393 1 35390 1 +35393 2 3 35392 1 +35393 3 35390 1 0 1 +35393 4 3 20372 7 0 1 +35401 1 35388 1 +35401 2 13 35400 1 +35401 3 35388 7 0 1 +35401 4 13 24079 14 0 1 +35407 1 35401 1 +35407 2 6 35406 1 +35407 3 35401 2 0 1 +35407 4 6 22403 9 0 1 +35419 1 35417 1 +35419 2 2 35418 1 +35419 3 35417 4 0 1 +35419 4 2 35412 8 0 1 +35423 1 35418 1 +35423 2 5 35421 1 +35423 3 35418 3 0 1 +35423 4 5 31626 5 0 1 +35437 1 35431 1 +35437 2 6 35436 1 +35437 3 35431 1 0 1 +35437 4 6 25467 6 0 1 +35447 1 35442 1 +35447 2 5 35445 1 +35447 3 35442 1 0 1 +35447 4 5 20162 5 0 1 +35449 1 35436 1 +35449 2 13 35432 1 +35449 3 35436 5 0 1 +35449 4 13 30833 6 0 1 +35461 1 35455 1 +35461 2 6 35457 1 +35461 3 35455 1 0 1 +35461 4 6 35457 6 0 1 +35491 1 35484 1 +35491 2 7 35489 1 +35491 3 35484 4 0 1 +35491 4 7 24761 6 0 1 +35507 1 35505 1 +35507 2 2 35506 1 +35507 3 35505 2 0 1 +35507 4 2 32405 2 0 1 +35509 1 35507 1 +35509 2 2 35508 1 +35509 3 35507 4 0 1 +35509 4 2 19205 7 0 1 +35521 1 35514 1 +35521 2 7 35518 1 +35521 3 35514 1 0 1 +35521 4 7 33397 14 0 1 +35527 1 35524 1 +35527 2 3 35526 1 +35527 3 35524 5 0 1 +35527 4 3 20682 5 0 1 +35531 1 35525 1 +35531 2 6 35530 1 +35531 3 35525 1 0 1 +35531 4 6 27235 4 0 1 +35533 1 35531 1 +35533 2 2 35529 1 +35533 3 35531 4 0 1 +35533 4 2 33119 6 0 1 +35537 1 35534 1 +35537 2 3 35536 1 +35537 3 35534 7 0 1 +35537 4 3 30152 4 0 1 +35543 1 35538 1 +35543 2 5 35542 1 +35543 3 35538 3 0 1 +35543 4 5 29884 3 0 1 +35569 1 35558 1 +35569 2 11 35568 1 +35569 3 35558 4 0 1 +35569 4 11 31907 18 0 1 +35573 1 35571 1 +35573 2 2 35566 1 +35573 3 35571 2 0 1 +35573 4 2 22925 4 0 1 +35591 1 35574 1 +35591 2 17 35589 1 +35591 3 35574 1 0 1 +35591 4 17 35583 3 0 1 +35593 1 35588 1 +35593 2 5 35590 1 +35593 3 35588 2 0 1 +35593 4 5 32282 10 0 1 +35597 1 35595 1 +35597 2 2 35593 1 +35597 3 35595 3 0 1 +35597 4 2 32596 9 0 1 +35603 1 35601 1 +35603 2 2 35599 1 +35603 3 35601 3 0 1 +35603 4 2 34191 7 0 1 +35617 1 35606 1 +35617 2 11 35615 1 +35617 3 35606 12 0 1 +35617 4 11 31025 32 0 1 +35671 1 35668 1 +35671 2 3 35665 1 +35671 3 35668 6 0 1 +35671 4 3 33223 7 0 1 +35677 1 35675 1 +35677 2 2 35676 1 +35677 3 35675 2 0 1 +35677 4 2 33207 20 0 1 +35729 1 35726 1 +35729 2 3 35724 1 +35729 3 35726 3 0 1 +35729 4 3 22054 2 0 1 +35731 1 35729 1 +35731 2 2 35730 1 +35731 3 35729 4 0 1 +35731 4 2 20912 6 0 1 +35747 1 35745 1 +35747 2 2 35739 1 +35747 3 35745 5 0 1 +35747 4 2 20052 0 0 1 +35753 1 35750 1 +35753 2 3 35741 1 +35753 3 35750 8 0 1 +35753 4 3 24804 6 0 1 +35759 1 35748 1 +35759 2 11 35758 1 +35759 3 35748 2 0 1 +35759 4 11 31616 4 0 1 +35771 1 35765 1 +35771 2 6 35769 1 +35771 3 35765 6 0 1 +35771 4 6 23040 0 0 1 +35797 1 35795 1 +35797 2 2 35793 1 +35797 3 35795 2 0 1 +35797 4 2 21997 9 0 1 +35801 1 35798 1 +35801 2 3 35800 1 +35801 3 35798 1 0 1 +35801 4 3 18410 4 0 1 +35803 1 35789 1 +35803 2 14 35802 1 +35803 3 35789 12 0 1 +35803 4 14 28409 2 0 1 +35809 1 35796 1 +35809 2 13 35808 1 +35809 3 35796 1 0 1 +35809 4 13 20668 14 0 1 +35831 1 35820 1 +35831 2 11 35829 1 +35831 3 35820 1 0 1 +35831 4 11 27470 3 0 1 +35837 1 35835 1 +35837 2 2 35833 1 +35837 3 35835 3 0 1 +35837 4 2 27920 7 0 1 +35839 1 35833 1 +35839 2 6 35837 1 +35839 3 35833 1 0 1 +35839 4 6 20789 3 0 1 +35851 1 35849 1 +35851 2 2 35847 1 +35851 3 35849 2 0 1 +35851 4 2 32401 8 0 1 +35863 1 35860 1 +35863 2 3 35861 1 +35863 3 35860 3 0 1 +35863 4 3 25693 3 0 1 +35869 1 35859 1 +35869 2 10 35868 1 +35869 3 35859 2 0 1 +35869 4 10 25437 3 0 1 +35879 1 35872 1 +35879 2 7 35865 1 +35879 3 35872 8 0 1 +35879 4 7 26393 16 0 1 +35897 1 35894 1 +35897 2 3 35881 1 +35897 3 35894 1 0 1 +35897 4 3 24352 10 0 1 +35899 1 35897 1 +35899 2 2 35898 1 +35899 3 35897 4 0 1 +35899 4 2 34062 10 0 1 +35911 1 35899 1 +35911 2 12 35909 1 +35911 3 35899 4 0 1 +35911 4 12 30858 4 0 1 +35923 1 35921 1 +35923 2 2 35922 1 +35923 3 35921 5 0 1 +35923 4 2 35916 8 0 1 +35933 1 35931 1 +35933 2 2 35929 1 +35933 3 35931 3 0 1 +35933 4 2 26455 6 0 1 +35951 1 35940 1 +35951 2 11 35949 1 +35951 3 35940 2 0 1 +35951 4 11 20372 3 0 1 +35963 1 35961 1 +35963 2 2 35956 1 +35963 3 35961 5 0 1 +35963 4 2 21073 2 0 1 +35969 1 35966 1 +35969 2 3 35962 1 +35969 3 35966 1 0 1 +35969 4 3 35285 0 0 1 +35977 1 35967 1 +35977 2 10 35976 1 +35977 3 35967 10 0 1 +35977 4 10 29866 6 0 1 +35983 1 35980 1 +35983 2 3 35982 1 +35983 3 35980 1 0 1 +35983 4 3 32077 5 0 1 +35993 1 35990 1 +35993 2 3 35986 1 +35993 3 35990 11 0 1 +35993 4 3 21439 4 0 1 +35999 1 35986 1 +35999 2 13 35997 1 +35999 3 35986 1 0 1 +35999 4 13 19538 3 0 1 +36007 1 36004 1 +36007 2 3 36005 1 +36007 3 36004 3 0 1 +36007 4 3 33167 6 0 1 +36011 1 36009 1 +36011 2 2 36010 1 +36011 3 36009 3 0 1 +36011 4 2 36004 8 0 1 +36013 1 36011 1 +36013 2 2 36012 1 +36013 3 36011 6 0 1 +36013 4 2 30730 3 0 1 +36017 1 36014 1 +36017 2 3 36012 1 +36017 3 36014 1 0 1 +36017 4 3 25143 0 0 1 +36037 1 36035 1 +36037 2 2 36033 1 +36037 3 36035 5 0 1 +36037 4 2 31822 6 0 1 +36061 1 36059 1 +36061 2 2 36057 1 +36061 3 36059 2 0 1 +36061 4 2 24535 10 0 1 +36067 1 36062 1 +36067 2 5 36065 1 +36067 3 36062 1 0 1 +36067 4 5 29480 0 0 1 +36073 1 36068 1 +36073 2 5 36068 1 +36073 3 36068 1 0 1 +36073 4 5 30882 15 0 1 +36083 1 36081 1 +36083 2 2 36074 1 +36083 3 36081 2 0 1 +36083 4 2 34713 1 0 1 +36097 1 36092 1 +36097 2 5 36094 1 +36097 3 36092 1 0 1 +36097 4 5 36086 14 0 1 +36107 1 36105 1 +36107 2 2 36101 1 +36107 3 36105 7 0 1 +36107 4 2 31026 4 0 1 +36109 1 36107 1 +36109 2 2 36108 1 +36109 3 36107 6 0 1 +36109 4 2 25606 3 0 1 +36131 1 36129 1 +36131 2 2 36126 1 +36131 3 36129 2 0 1 +36131 4 2 29519 3 0 1 +36137 1 36134 1 +36137 2 3 36131 1 +36137 3 36134 4 0 1 +36137 4 3 19639 1 0 1 +36151 1 36148 1 +36151 2 3 36149 1 +36151 3 36148 8 0 1 +36151 4 3 32430 3 0 1 +36161 1 36158 1 +36161 2 3 36153 1 +36161 3 36158 3 0 1 +36161 4 3 31503 1 0 1 +36187 1 36184 1 +36187 2 3 36186 1 +36187 3 36184 7 0 1 +36187 4 3 33102 5 0 1 +36191 1 36184 1 +36191 2 7 36189 1 +36191 3 36184 3 0 1 +36191 4 7 34588 4 0 1 +36209 1 36206 1 +36209 2 3 36195 1 +36209 3 36206 8 0 1 +36209 4 3 33794 0 0 1 +36217 1 36198 1 +36217 2 19 36213 1 +36217 3 36198 4 0 1 +36217 4 19 30943 11 0 1 +36229 1 36227 1 +36229 2 2 36225 1 +36229 3 36227 5 0 1 +36229 4 2 23421 10 0 1 +36241 1 36222 1 +36241 2 19 36238 1 +36241 3 36222 1 0 1 +36241 4 19 30081 22 0 1 +36251 1 36249 1 +36251 2 2 36247 1 +36251 3 36249 3 0 1 +36251 4 2 29127 7 0 1 +36263 1 36258 1 +36263 2 5 36258 1 +36263 3 36258 11 0 1 +36263 4 5 29741 8 0 1 +36269 1 36267 1 +36269 2 2 36265 1 +36269 3 36267 2 0 1 +36269 4 2 25760 7 0 1 +36277 1 36275 1 +36277 2 2 36276 1 +36277 3 36275 4 0 1 +36277 4 2 20036 3 0 1 +36293 1 36291 1 +36293 2 2 36292 1 +36293 3 36291 3 0 1 +36293 4 2 19996 6 0 1 +36299 1 36297 1 +36299 2 2 36295 1 +36299 3 36297 2 0 1 +36299 4 2 28690 7 0 1 +36307 1 36305 1 +36307 2 2 36306 1 +36307 3 36305 4 0 1 +36307 4 2 34759 7 0 1 +36313 1 36308 1 +36313 2 5 36310 1 +36313 3 36308 1 0 1 +36313 4 5 32125 18 0 1 +36319 1 36313 1 +36319 2 6 36315 1 +36319 3 36313 1 0 1 +36319 4 6 26609 1 0 1 +36341 1 36339 1 +36341 2 2 36337 1 +36341 3 36339 2 0 1 +36341 4 2 33197 6 0 1 +36343 1 36330 1 +36343 2 13 36342 1 +36343 3 36330 3 0 1 +36343 4 13 23388 2 0 1 +36353 1 36350 1 +36353 2 3 36348 1 +36353 3 36350 3 0 1 +36353 4 3 33590 2 0 1 +36373 1 36371 1 +36373 2 2 36369 1 +36373 3 36371 6 0 1 +36373 4 2 29979 6 0 1 +36383 1 36378 1 +36383 2 5 36380 1 +36383 3 36378 1 0 1 +36383 4 5 30951 4 0 1 +36389 1 36386 1 +36389 2 3 36387 1 +36389 3 36386 6 0 1 +36389 4 3 29737 12 0 1 +36433 1 36428 1 +36433 2 5 36432 1 +36433 3 36428 1 0 1 +36433 4 5 32929 6 0 1 +36451 1 36444 1 +36451 2 7 36445 1 +36451 3 36444 19 0 1 +36451 4 7 36447 4 0 1 +36457 1 36452 1 +36457 2 5 36456 1 +36457 3 36452 2 0 1 +36457 4 5 20331 6 0 1 +36467 1 36465 1 +36467 2 2 36463 1 +36467 3 36465 3 0 1 +36467 4 2 35613 7 0 1 +36469 1 36467 1 +36469 2 2 36468 1 +36469 3 36467 6 0 1 +36469 4 2 23910 9 0 1 +36473 1 36470 1 +36473 2 3 36472 1 +36473 3 36470 1 0 1 +36473 4 3 19617 7 0 1 +36479 1 36472 1 +36479 2 7 36476 1 +36479 3 36472 8 0 1 +36479 4 7 29389 5 0 1 +36493 1 36491 1 +36493 2 2 36489 1 +36493 3 36491 6 0 1 +36493 4 2 26318 6 0 1 +36497 1 36494 1 +36497 2 3 36496 1 +36497 3 36494 4 0 1 +36497 4 3 24594 6 0 1 +36523 1 36521 1 +36523 2 2 36519 1 +36523 3 36521 6 0 1 +36523 4 2 21049 18 0 1 +36527 1 36522 1 +36527 2 5 36525 1 +36527 3 36522 5 0 1 +36527 4 5 36523 3 0 1 +36529 1 36522 1 +36529 2 7 36522 1 +36529 3 36522 4 0 1 +36529 4 7 35431 0 0 1 +36541 1 36531 1 +36541 2 10 36540 1 +36541 3 36531 3 0 1 +36541 4 10 29944 3 0 1 +36551 1 36544 1 +36551 2 7 36550 1 +36551 3 36544 1 0 1 +36551 4 7 21398 2 0 1 +36559 1 36553 1 +36559 2 6 36557 1 +36559 3 36553 2 0 1 +36559 4 6 20681 3 0 1 +36563 1 36561 1 +36563 2 2 36559 1 +36563 3 36561 3 0 1 +36563 4 2 22728 14 0 1 +36571 1 36569 1 +36571 2 2 36570 1 +36571 3 36569 5 0 1 +36571 4 2 31515 2 0 1 +36583 1 36576 1 +36583 2 7 36580 1 +36583 3 36576 1 0 1 +36583 4 7 34883 0 0 1 +36587 1 36585 1 +36587 2 2 36582 1 +36587 3 36585 2 0 1 +36587 4 2 30336 0 0 1 +36599 1 36580 1 +36599 2 19 36595 1 +36599 3 36580 3 0 1 +36599 4 19 28767 9 0 1 +36607 1 36604 1 +36607 2 3 36606 1 +36607 3 36604 3 0 1 +36607 4 3 19013 5 0 1 +36629 1 36627 1 +36629 2 2 36628 1 +36629 3 36627 3 0 1 +36629 4 2 32104 3 0 1 +36637 1 36632 1 +36637 2 5 36634 1 +36637 3 36632 6 0 1 +36637 4 5 33971 1 0 1 +36643 1 36640 1 +36643 2 3 36642 1 +36643 3 36640 1 0 1 +36643 4 3 34748 2 0 1 +36653 1 36651 1 +36653 2 2 36649 1 +36653 3 36651 3 0 1 +36653 4 2 32200 12 0 1 +36671 1 36658 1 +36671 2 13 36670 1 +36671 3 36658 1 0 1 +36671 4 13 28165 4 0 1 +36677 1 36675 1 +36677 2 2 36673 1 +36677 3 36675 4 0 1 +36677 4 2 26307 12 0 1 +36683 1 36681 1 +36683 2 2 36679 1 +36683 3 36681 2 0 1 +36683 4 2 19255 11 0 1 +36691 1 36689 1 +36691 2 2 36687 1 +36691 3 36689 6 0 1 +36691 4 2 27601 8 0 1 +36697 1 36692 1 +36697 2 5 36696 1 +36697 3 36692 2 0 1 +36697 4 5 31757 6 0 1 +36709 1 36707 1 +36709 2 2 36705 1 +36709 3 36707 2 0 1 +36709 4 2 32935 6 0 1 +36713 1 36710 1 +36713 2 3 36712 1 +36713 3 36710 12 0 1 +36713 4 3 21973 7 0 1 +36721 1 36684 1 +36721 2 37 36716 1 +36721 3 36684 8 0 1 +36721 4 37 30482 12 0 1 +36739 1 36737 1 +36739 2 2 36738 1 +36739 3 36737 5 0 1 +36739 4 2 36407 2 0 1 +36749 1 36747 1 +36749 2 2 36745 1 +36749 3 36747 3 0 1 +36749 4 2 28643 1 0 1 +36761 1 36755 1 +36761 2 6 36751 1 +36761 3 36755 1 0 1 +36761 4 6 26036 4 0 1 +36767 1 36762 1 +36767 2 5 36766 1 +36767 3 36762 2 0 1 +36767 4 5 22326 4 0 1 +36779 1 36777 1 +36779 2 2 36775 1 +36779 3 36777 2 0 1 +36779 4 2 20821 8 0 1 +36781 1 36779 1 +36781 2 2 36780 1 +36781 3 36779 6 0 1 +36781 4 2 25314 3 0 1 +36787 1 36785 1 +36787 2 2 36783 1 +36787 3 36785 4 0 1 +36787 4 2 22006 8 0 1 +36791 1 36774 1 +36791 2 17 36787 1 +36791 3 36774 1 0 1 +36791 4 17 22588 7 0 1 +36793 1 36778 1 +36793 2 15 36790 1 +36793 3 36778 2 0 1 +36793 4 15 36460 13 0 1 +36809 1 36806 1 +36809 2 3 36804 1 +36809 3 36806 3 0 1 +36809 4 3 27220 2 0 1 +36821 1 36819 1 +36821 2 2 36814 1 +36821 3 36819 5 0 1 +36821 4 2 20832 9 0 1 +36833 1 36830 1 +36833 2 3 36827 1 +36833 3 36830 5 0 1 +36833 4 3 31974 9 0 1 +36847 1 36844 1 +36847 2 3 36846 1 +36847 3 36844 4 0 1 +36847 4 3 19359 5 0 1 +36857 1 36854 1 +36857 2 3 36856 1 +36857 3 36854 5 0 1 +36857 4 3 32096 7 0 1 +36871 1 36856 1 +36871 2 15 36870 1 +36871 3 36856 5 0 1 +36871 4 15 31644 3 0 1 +36877 1 36875 1 +36877 2 2 36873 1 +36877 3 36875 4 0 1 +36877 4 2 23194 9 0 1 +36887 1 36882 1 +36887 2 5 36886 1 +36887 3 36882 1 0 1 +36887 4 5 31122 3 0 1 +36899 1 36897 1 +36899 2 2 36893 1 +36899 3 36897 9 0 1 +36899 4 2 29442 4 0 1 +36901 1 36899 1 +36901 2 2 36897 1 +36901 3 36899 2 0 1 +36901 4 2 25191 6 0 1 +36913 1 36908 1 +36913 2 5 36912 1 +36913 3 36908 21 0 1 +36913 4 5 18803 6 0 1 +36919 1 36916 1 +36919 2 3 36917 1 +36919 3 36916 3 0 1 +36919 4 3 20454 3 0 1 +36923 1 36921 1 +36923 2 2 36919 1 +36923 3 36921 2 0 1 +36923 4 2 34345 11 0 1 +36929 1 36926 1 +36929 2 3 36919 1 +36929 3 36926 11 0 1 +36929 4 3 21647 4 0 1 +36931 1 36929 1 +36931 2 2 36930 1 +36931 3 36929 4 0 1 +36931 4 2 30324 2 0 1 +36943 1 36940 1 +36943 2 3 36941 1 +36943 3 36940 3 0 1 +36943 4 3 36935 10 0 1 +36947 1 36945 1 +36947 2 2 36940 1 +36947 3 36945 8 0 1 +36947 4 2 24391 0 0 1 +36973 1 36971 1 +36973 2 2 36972 1 +36973 3 36971 2 0 1 +36973 4 2 23162 3 0 1 +36979 1 36976 1 +36979 2 3 36978 1 +36979 3 36976 7 0 1 +36979 4 3 19090 6 0 1 +36997 1 36995 1 +36997 2 2 36993 1 +36997 3 36995 4 0 1 +36997 4 2 21881 6 0 1 +37003 1 37001 1 +37003 2 2 36999 1 +37003 3 37001 5 0 1 +37003 4 2 26101 8 0 1 +37013 1 37011 1 +37013 2 2 37005 1 +37013 3 37011 10 0 1 +37013 4 2 29720 5 0 1 +37019 1 37017 1 +37019 2 2 37014 1 +37019 3 37017 4 0 1 +37019 4 2 22512 3 0 1 +37021 1 37015 1 +37021 2 6 37020 1 +37021 3 37015 4 0 1 +37021 4 6 32663 18 0 1 +37039 1 37036 1 +37039 2 3 37038 1 +37039 3 37036 1 0 1 +37039 4 3 25707 2 0 1 +37049 1 37043 1 +37049 2 6 37046 1 +37049 3 37043 1 0 1 +37049 4 6 23618 15 0 1 +37057 1 37052 1 +37057 2 5 37048 1 +37057 3 37052 3 0 1 +37057 4 5 34294 2 0 1 +37061 1 37059 1 +37061 2 2 37060 1 +37061 3 37059 7 0 1 +37061 4 2 26907 3 0 1 +37087 1 37084 1 +37087 2 3 37086 1 +37087 3 37084 1 0 1 +37087 4 3 35869 5 0 1 +37097 1 37094 1 +37097 2 3 37091 1 +37097 3 37094 7 0 1 +37097 4 3 26078 11 0 1 +37117 1 37115 1 +37117 2 2 37116 1 +37117 3 37115 2 0 1 +37117 4 2 35600 6 0 1 +37123 1 37120 1 +37123 2 3 37118 1 +37123 3 37120 4 0 1 +37123 4 3 29214 3 0 1 +37139 1 37137 1 +37139 2 2 37135 1 +37139 3 37137 2 0 1 +37139 4 2 21300 7 0 1 +37159 1 37156 1 +37159 2 3 37157 1 +37159 3 37156 1 0 1 +37159 4 3 33865 3 0 1 +37171 1 37168 1 +37171 2 3 37170 1 +37171 3 37168 1 0 1 +37171 4 3 24119 2 0 1 +37181 1 37179 1 +37181 2 2 37166 1 +37181 3 37179 4 0 1 +37181 4 2 25911 3 0 1 +37189 1 37187 1 +37189 2 2 37188 1 +37189 3 37187 6 0 1 +37189 4 2 30260 7 0 1 +37199 1 37192 1 +37199 2 7 37187 1 +37199 3 37192 1 0 1 +37199 4 7 19932 18 0 1 +37201 1 37194 1 +37201 2 7 37194 1 +37201 3 37194 12 0 1 +37201 4 7 27563 0 0 1 +37217 1 37214 1 +37217 2 3 37211 1 +37217 3 37214 1 0 1 +37217 4 3 25495 1 0 1 +37223 1 37218 1 +37223 2 5 37222 1 +37223 3 37218 7 0 1 +37223 4 5 29669 4 0 1 +37243 1 37241 1 +37243 2 2 37242 1 +37243 3 37241 4 0 1 +37243 4 2 19542 7 0 1 +37253 1 37251 1 +37253 2 2 37249 1 +37253 3 37251 3 0 1 +37253 4 2 28291 7 0 1 +37273 1 37268 1 +37273 2 5 37272 1 +37273 3 37268 5 0 1 +37273 4 5 34429 6 0 1 +37277 1 37275 1 +37277 2 2 37269 1 +37277 3 37275 5 0 1 +37277 4 2 33278 5 0 1 +37307 1 37305 1 +37307 2 2 37301 1 +37307 3 37305 4 0 1 +37307 4 2 25085 4 0 1 +37309 1 37302 1 +37309 2 7 37307 1 +37309 3 37302 1 0 1 +37309 4 7 19242 4 0 1 +37313 1 37310 1 +37313 2 3 37301 1 +37313 3 37310 1 0 1 +37313 4 3 30263 0 0 1 +37321 1 37298 1 +37321 2 23 37320 1 +37321 3 37298 5 0 1 +37321 4 23 20097 18 0 1 +37337 1 37334 1 +37337 2 3 37331 1 +37337 3 37334 6 0 1 +37337 4 3 19067 1 0 1 +37339 1 37336 1 +37339 2 3 37332 1 +37339 3 37336 1 0 1 +37339 4 3 20666 5 0 1 +37357 1 37351 1 +37357 2 6 37356 1 +37357 3 37351 1 0 1 +37357 4 6 25712 6 0 1 +37361 1 37358 1 +37361 2 3 37355 1 +37361 3 37358 5 0 1 +37361 4 3 37349 0 0 1 +37363 1 37360 1 +37363 2 3 37362 1 +37363 3 37360 1 0 1 +37363 4 3 21155 2 0 1 +37369 1 37362 1 +37369 2 7 37366 1 +37369 3 37362 1 0 1 +37369 4 7 33527 14 0 1 +37379 1 37377 1 +37379 2 2 37378 1 +37379 3 37377 3 0 1 +37379 4 2 29464 4 0 1 +37397 1 37395 1 +37397 2 2 37396 1 +37397 3 37395 2 0 1 +37397 4 2 26940 4 0 1 +37409 1 37406 1 +37409 2 3 37404 1 +37409 3 37406 3 0 1 +37409 4 3 21337 2 0 1 +37423 1 37417 1 +37423 2 6 37420 1 +37423 3 37417 4 0 1 +37423 4 6 37408 18 0 1 +37441 1 37424 1 +37441 2 17 37430 1 +37441 3 37424 2 0 1 +37441 4 17 33605 0 0 1 +37447 1 37444 1 +37447 2 3 37445 1 +37447 3 37444 5 0 1 +37447 4 3 19779 6 0 1 +37463 1 37458 1 +37463 2 5 37461 1 +37463 3 37458 1 0 1 +37463 4 5 37459 3 0 1 +37483 1 37481 1 +37483 2 2 37482 1 +37483 3 37481 5 0 1 +37483 4 2 27131 2 0 1 +37489 1 37470 1 +37489 2 19 37474 1 +37489 3 37470 4 0 1 +37489 4 19 33346 52 0 1 +37493 1 37491 1 +37493 2 2 37486 1 +37493 3 37491 4 0 1 +37493 4 2 27205 2 0 1 +37501 1 37499 1 +37501 2 2 37497 1 +37501 3 37499 2 0 1 +37501 4 2 34278 10 0 1 +37507 1 37490 1 +37507 2 17 37505 1 +37507 3 37490 2 0 1 +37507 4 17 37499 3 0 1 +37511 1 37500 1 +37511 2 11 37508 1 +37511 3 37500 4 0 1 +37511 4 11 31881 6 0 1 +37517 1 37515 1 +37517 2 2 37513 1 +37517 3 37515 3 0 1 +37517 4 2 18975 7 0 1 +37529 1 37526 1 +37529 2 3 37519 1 +37529 3 37526 3 0 1 +37529 4 3 26883 13 0 1 +37537 1 37524 1 +37537 2 13 37528 1 +37537 3 37524 1 0 1 +37537 4 13 30190 2 0 1 +37547 1 37545 1 +37547 2 2 37546 1 +37547 3 37545 3 0 1 +37547 4 2 32251 2 0 1 +37549 1 37547 1 +37549 2 2 37545 1 +37549 3 37547 2 0 1 +37549 4 2 18991 12 0 1 +37561 1 37550 1 +37561 2 11 37560 1 +37561 3 37550 3 0 1 +37561 4 11 19631 8 0 1 +37567 1 37564 1 +37567 2 3 37566 1 +37567 3 37564 3 0 1 +37567 4 3 24636 5 0 1 +37571 1 37569 1 +37571 2 2 37560 1 +37571 3 37569 2 0 1 +37571 4 2 32823 3 0 1 +37573 1 37568 1 +37573 2 5 37572 1 +37573 3 37568 10 0 1 +37573 4 5 19136 3 0 1 +37579 1 37577 1 +37579 2 2 37578 1 +37579 3 37577 6 0 1 +37579 4 2 19454 2 0 1 +37589 1 37587 1 +37589 2 2 37588 1 +37589 3 37587 9 0 1 +37589 4 2 34854 3 0 1 +37591 1 37585 1 +37591 2 6 37589 1 +37591 3 37585 2 0 1 +37591 4 6 33174 10 0 1 +37607 1 37602 1 +37607 2 5 37605 1 +37607 3 37602 1 0 1 +37607 4 5 29548 14 0 1 +37619 1 37617 1 +37619 2 2 37615 1 +37619 3 37617 2 0 1 +37619 4 2 34006 7 0 1 +37633 1 37628 1 +37633 2 5 37632 1 +37633 3 37628 1 0 1 +37633 4 5 36406 12 0 1 +37643 1 37641 1 +37643 2 2 37639 1 +37643 3 37641 3 0 1 +37643 4 2 26690 8 0 1 +37649 1 37646 1 +37649 2 3 37648 1 +37649 3 37646 4 0 1 +37649 4 3 31939 7 0 1 +37657 1 37652 1 +37657 2 5 37656 1 +37657 3 37652 2 0 1 +37657 4 5 28634 6 0 1 +37663 1 37660 1 +37663 2 3 37662 1 +37663 3 37660 6 0 1 +37663 4 3 22013 2 0 1 +37691 1 37685 1 +37691 2 6 37689 1 +37691 3 37685 2 0 1 +37691 4 6 24698 5 0 1 +37693 1 37691 1 +37693 2 2 37692 1 +37693 3 37691 2 0 1 +37693 4 2 22114 3 0 1 +37699 1 37696 1 +37699 2 3 37687 1 +37699 3 37696 3 0 1 +37699 4 3 34574 0 0 1 +37717 1 37712 1 +37717 2 5 37716 1 +37717 3 37712 1 0 1 +37717 4 5 32095 3 0 1 +37747 1 37744 1 +37747 2 3 37746 1 +37747 3 37744 1 0 1 +37747 4 3 25645 5 0 1 +37781 1 37779 1 +37781 2 2 37776 1 +37781 3 37779 2 0 1 +37781 4 2 25477 8 0 1 +37783 1 37780 1 +37783 2 3 37781 1 +37783 3 37780 4 0 1 +37783 4 3 37775 10 0 1 +37799 1 37788 1 +37799 2 11 37798 1 +37799 3 37788 5 0 1 +37799 4 11 19068 2 0 1 +37811 1 37805 1 +37811 2 6 37810 1 +37811 3 37805 2 0 1 +37811 4 6 35535 4 0 1 +37813 1 37811 1 +37813 2 2 37809 1 +37813 3 37811 5 0 1 +37813 4 2 19352 10 0 1 +37831 1 37828 1 +37831 2 3 37830 1 +37831 3 37828 3 0 1 +37831 4 3 31814 3 0 1 +37847 1 37842 1 +37847 2 5 37846 1 +37847 3 37842 1 0 1 +37847 4 5 23220 3 0 1 +37853 1 37851 1 +37853 2 2 37848 1 +37853 3 37851 4 0 1 +37853 4 2 22552 17 0 1 +37861 1 37859 1 +37861 2 2 37860 1 +37861 3 37859 6 0 1 +37861 4 2 22027 3 0 1 +37871 1 37864 1 +37871 2 7 37864 1 +37871 3 37864 5 0 1 +37871 4 7 33945 8 0 1 +37879 1 37872 1 +37879 2 7 37876 1 +37879 3 37872 3 0 1 +37879 4 7 28903 0 0 1 +37889 1 37886 1 +37889 2 3 37881 1 +37889 3 37886 3 0 1 +37889 4 3 25113 1 0 1 +37897 1 37892 1 +37897 2 5 37894 1 +37897 3 37892 1 0 1 +37897 4 5 37195 16 0 1 +37907 1 37905 1 +37907 2 2 37903 1 +37907 3 37905 8 0 1 +37907 4 2 33823 7 0 1 +37951 1 37948 1 +37951 2 3 37949 1 +37951 3 37948 3 0 1 +37951 4 3 29265 3 0 1 +37957 1 37955 1 +37957 2 2 37956 1 +37957 3 37955 5 0 1 +37957 4 2 30796 3 0 1 +37963 1 37961 1 +37963 2 2 37959 1 +37963 3 37961 6 0 1 +37963 4 2 21601 8 0 1 +37967 1 37962 1 +37967 2 5 37964 1 +37967 3 37962 1 0 1 +37967 4 5 35382 6 0 1 +37987 1 37982 1 +37987 2 5 37985 1 +37987 3 37982 1 0 1 +37987 4 5 34893 9 0 1 +37991 1 37984 1 +37991 2 7 37990 1 +37991 3 37984 4 0 1 +37991 4 7 28727 2 0 1 +37993 1 37983 1 +37993 2 10 37992 1 +37993 3 37983 5 0 1 +37993 4 10 35024 16 0 1 +37997 1 37995 1 +37997 2 2 37993 1 +37997 3 37995 3 0 1 +37997 4 2 29297 7 0 1 +38011 1 38009 1 +38011 2 2 38007 1 +38011 3 38009 2 0 1 +38011 4 2 19512 8 0 1 +38039 1 38032 1 +38039 2 7 38037 1 +38039 3 38032 2 0 1 +38039 4 7 33167 4 0 1 +38047 1 38044 1 +38047 2 3 38045 1 +38047 3 38044 1 0 1 +38047 4 3 38039 10 0 1 +38053 1 38048 1 +38053 2 5 38052 1 +38053 3 38048 2 0 1 +38053 4 5 33474 3 0 1 +38069 1 38067 1 +38069 2 2 38064 1 +38069 3 38067 4 0 1 +38069 4 2 21442 2 0 1 +38083 1 38080 1 +38083 2 3 38078 1 +38083 3 38080 4 0 1 +38083 4 3 19791 3 0 1 +38113 1 38106 1 +38113 2 7 38110 1 +38113 3 38106 2 0 1 +38113 4 7 30887 17 0 1 +38119 1 38116 1 +38119 2 3 38117 1 +38119 3 38116 1 0 1 +38119 4 3 38115 4 0 1 +38149 1 38143 1 +38149 2 6 38148 1 +38149 3 38143 4 0 1 +38149 4 6 28909 7 0 1 +38153 1 38150 1 +38153 2 3 38148 1 +38153 3 38150 3 0 1 +38153 4 3 25251 0 0 1 +38167 1 38164 1 +38167 2 3 38166 1 +38167 3 38164 3 0 1 +38167 4 3 32206 5 0 1 +38177 1 38174 1 +38177 2 3 38176 1 +38177 3 38174 5 0 1 +38177 4 3 35652 7 0 1 +38183 1 38178 1 +38183 2 5 38180 1 +38183 3 38178 3 0 1 +38183 4 5 31711 6 0 1 +38189 1 38187 1 +38189 2 2 38185 1 +38189 3 38187 3 0 1 +38189 4 2 27557 6 0 1 +38197 1 38195 1 +38197 2 2 38196 1 +38197 3 38195 8 0 1 +38197 4 2 26216 6 0 1 +38201 1 38198 1 +38201 2 3 38196 1 +38201 3 38198 3 0 1 +38201 4 3 35721 2 0 1 +38219 1 38217 1 +38219 2 2 38215 1 +38219 3 38217 3 0 1 +38219 4 2 26073 7 0 1 +38231 1 38218 1 +38231 2 13 38230 1 +38231 3 38218 3 0 1 +38231 4 13 32649 10 0 1 +38237 1 38235 1 +38237 2 2 38233 1 +38237 3 38235 2 0 1 +38237 4 2 25637 7 0 1 +38239 1 38226 1 +38239 2 13 38238 1 +38239 3 38226 3 0 1 +38239 4 13 19289 2 0 1 +38261 1 38259 1 +38261 2 2 38260 1 +38261 3 38259 3 0 1 +38261 4 2 36648 4 0 1 +38273 1 38270 1 +38273 2 3 38267 1 +38273 3 38270 12 0 1 +38273 4 3 21659 1 0 1 +38281 1 38267 1 +38281 2 14 38278 1 +38281 3 38267 1 0 1 +38281 4 14 24768 20 0 1 +38287 1 38280 1 +38287 2 7 38284 1 +38287 3 38280 2 0 1 +38287 4 7 19895 4 0 1 +38299 1 38297 1 +38299 2 2 38293 1 +38299 3 38297 2 0 1 +38299 4 2 36650 7 0 1 +38303 1 38298 1 +38303 2 5 38301 1 +38303 3 38298 10 0 1 +38303 4 5 26437 10 0 1 +38317 1 38315 1 +38317 2 2 38316 1 +38317 3 38315 2 0 1 +38317 4 2 31189 7 0 1 +38321 1 38318 1 +38321 2 3 38320 1 +38321 3 38318 1 0 1 +38321 4 3 36923 4 0 1 +38327 1 38322 1 +38327 2 5 38325 1 +38327 3 38322 1 0 1 +38327 4 5 30440 5 0 1 +38329 1 38316 1 +38329 2 13 38328 1 +38329 3 38316 1 0 1 +38329 4 13 25055 14 0 1 +38333 1 38331 1 +38333 2 2 38325 1 +38333 3 38331 4 0 1 +38333 4 2 30289 11 0 1 +38351 1 38340 1 +38351 2 11 38349 1 +38351 3 38340 1 0 1 +38351 4 11 37128 3 0 1 +38371 1 38361 1 +38371 2 10 38370 1 +38371 3 38361 3 0 1 +38371 4 10 24488 5 0 1 +38377 1 38372 1 +38377 2 5 38372 1 +38377 3 38372 2 0 1 +38377 4 5 38100 10 0 1 +38393 1 38390 1 +38393 2 3 38387 1 +38393 3 38390 6 0 1 +38393 4 3 20238 1 0 1 +38431 1 38425 1 +38431 2 6 38430 1 +38431 3 38425 2 0 1 +38431 4 6 36645 2 0 1 +38447 1 38442 1 +38447 2 5 38446 1 +38447 3 38442 5 0 1 +38447 4 5 23340 4 0 1 +38449 1 38436 1 +38449 2 13 38448 1 +38449 3 38436 3 0 1 +38449 4 13 29532 8 0 1 +38453 1 38451 1 +38453 2 2 38449 1 +38453 3 38451 4 0 1 +38453 4 2 30005 12 0 1 +38459 1 38457 1 +38459 2 2 38455 1 +38459 3 38457 2 0 1 +38459 4 2 37440 8 0 1 +38461 1 38448 1 +38461 2 13 38460 1 +38461 3 38448 1 0 1 +38461 4 13 33488 7 0 1 +38501 1 38499 1 +38501 2 2 38493 1 +38501 3 38499 2 0 1 +38501 4 2 20275 0 0 1 +38543 1 38538 1 +38543 2 5 38541 1 +38543 3 38538 6 0 1 +38543 4 5 38539 3 0 1 +38557 1 38555 1 +38557 2 2 38553 1 +38557 3 38555 4 0 1 +38557 4 2 22303 10 0 1 +38561 1 38558 1 +38561 2 3 38555 1 +38561 3 38558 7 0 1 +38561 4 3 38549 0 0 1 +38567 1 38562 1 +38567 2 5 38562 1 +38567 3 38562 6 0 1 +38567 4 5 34251 6 0 1 +38569 1 38555 1 +38569 2 14 38567 1 +38569 3 38555 1 0 1 +38569 4 14 38543 15 0 1 +38593 1 38588 1 +38593 2 5 38588 1 +38593 3 38588 3 0 1 +38593 4 5 22172 15 0 1 +38603 1 38601 1 +38603 2 2 38602 1 +38603 3 38601 2 0 1 +38603 4 2 23298 4 0 1 +38609 1 38606 1 +38609 2 3 38608 1 +38609 3 38606 6 0 1 +38609 4 3 38331 7 0 1 +38611 1 38608 1 +38611 2 3 38604 1 +38611 3 38608 3 0 1 +38611 4 3 29249 5 0 1 +38629 1 38627 1 +38629 2 2 38628 1 +38629 3 38627 4 0 1 +38629 4 2 32309 3 0 1 +38639 1 38610 1 +38639 2 29 38638 1 +38639 3 38610 5 0 1 +38639 4 29 29599 2 0 1 +38651 1 38649 1 +38651 2 2 38645 1 +38651 3 38649 9 0 1 +38651 4 2 36685 4 0 1 +38653 1 38651 1 +38653 2 2 38652 1 +38653 3 38651 2 0 1 +38653 4 2 36591 3 0 1 +38669 1 38667 1 +38669 2 2 38664 1 +38669 3 38667 2 0 1 +38669 4 2 33671 15 0 1 +38671 1 38665 1 +38671 2 6 38669 1 +38671 3 38665 2 0 1 +38671 4 6 21972 3 0 1 +38677 1 38672 1 +38677 2 5 38676 1 +38677 3 38672 3 0 1 +38677 4 5 37582 3 0 1 +38693 1 38691 1 +38693 2 2 38683 1 +38693 3 38691 7 0 1 +38693 4 2 32166 2 0 1 +38699 1 38697 1 +38699 2 2 38698 1 +38699 3 38697 3 0 1 +38699 4 2 33472 6 0 1 +38707 1 38705 1 +38707 2 2 38703 1 +38707 3 38705 6 0 1 +38707 4 2 37302 8 0 1 +38711 1 38704 1 +38711 2 7 38708 1 +38711 3 38704 1 0 1 +38711 4 7 34674 5 0 1 +38713 1 38708 1 +38713 2 5 38712 1 +38713 3 38708 5 0 1 +38713 4 5 23934 6 0 1 +38723 1 38721 1 +38723 2 2 38719 1 +38723 3 38721 3 0 1 +38723 4 2 37759 11 0 1 +38729 1 38726 1 +38729 2 3 38724 1 +38729 3 38726 3 0 1 +38729 4 3 29906 2 0 1 +38737 1 38732 1 +38737 2 5 38736 1 +38737 3 38732 3 0 1 +38737 4 5 23632 6 0 1 +38747 1 38745 1 +38747 2 2 38736 1 +38747 3 38745 10 0 1 +38747 4 2 20734 4 0 1 +38749 1 38747 1 +38749 2 2 38745 1 +38749 3 38747 2 0 1 +38749 4 2 24273 6 0 1 +38767 1 38762 1 +38767 2 5 38765 1 +38767 3 38762 1 0 1 +38767 4 5 24075 15 0 1 +38783 1 38778 1 +38783 2 5 38780 1 +38783 3 38778 1 0 1 +38783 4 5 23214 4 0 1 +38791 1 38785 1 +38791 2 6 38789 1 +38791 3 38785 10 0 1 +38791 4 6 30215 4 0 1 +38803 1 38798 1 +38803 2 5 38801 1 +38803 3 38798 1 0 1 +38803 4 5 38795 6 0 1 +38821 1 38819 1 +38821 2 2 38817 1 +38821 3 38819 7 0 1 +38821 4 2 30471 6 0 1 +38833 1 38828 1 +38833 2 5 38828 1 +38833 3 38828 2 0 1 +38833 4 5 37701 18 0 1 +38839 1 38833 1 +38839 2 6 38838 1 +38839 3 38833 1 0 1 +38839 4 6 24569 2 0 1 +38851 1 38848 1 +38851 2 3 38850 1 +38851 3 38848 1 0 1 +38851 4 3 23661 2 0 1 +38861 1 38847 1 +38861 2 14 38838 1 +38861 3 38847 2 0 1 +38861 4 14 23356 0 0 1 +38867 1 38865 1 +38867 2 2 38866 1 +38867 3 38865 2 0 1 +38867 4 2 27407 2 0 1 +38873 1 38870 1 +38873 2 3 38872 1 +38873 3 38870 10 0 1 +38873 4 3 33001 4 0 1 +38891 1 38889 1 +38891 2 2 38890 1 +38891 3 38889 4 0 1 +38891 4 2 26445 10 0 1 +38903 1 38898 1 +38903 2 5 38902 1 +38903 3 38898 1 0 1 +38903 4 5 26815 5 0 1 +38917 1 38912 1 +38917 2 5 38914 1 +38917 3 38912 8 0 1 +38917 4 5 24190 11 0 1 +38921 1 38915 1 +38921 2 6 38920 1 +38921 3 38915 2 0 1 +38921 4 6 25186 7 0 1 +38923 1 38921 1 +38923 2 2 38922 1 +38923 3 38921 6 0 1 +38923 4 2 38916 8 0 1 +38933 1 38931 1 +38933 2 2 38932 1 +38933 3 38931 3 0 1 +38933 4 2 33245 4 0 1 +38953 1 38948 1 +38953 2 5 38952 1 +38953 3 38948 1 0 1 +38953 4 5 35439 6 0 1 +38959 1 38956 1 +38959 2 3 38954 1 +38959 3 38956 6 0 1 +38959 4 3 30864 6 0 1 +38971 1 38969 1 +38971 2 2 38967 1 +38971 3 38969 6 0 1 +38971 4 2 21563 8 0 1 +38977 1 38972 1 +38977 2 5 38976 1 +38977 3 38972 2 0 1 +38977 4 5 26193 6 0 1 +38993 1 38990 1 +38993 2 3 38987 1 +38993 3 38990 3 0 1 +38993 4 3 35395 9 0 1 +39019 1 39017 1 +39019 2 2 39013 1 +39019 3 39017 2 0 1 +39019 4 2 33763 3 0 1 +39023 1 39018 1 +39023 2 5 39021 1 +39023 3 39018 1 0 1 +39023 4 5 24508 5 0 1 +39041 1 39038 1 +39041 2 3 39040 1 +39041 3 39038 1 0 1 +39041 4 3 26546 7 0 1 +39043 1 39041 1 +39043 2 2 39039 1 +39043 3 39041 4 0 1 +39043 4 2 22536 10 0 1 +39047 1 39042 1 +39047 2 5 39046 1 +39047 3 39042 5 0 1 +39047 4 5 33621 3 0 1 +39079 1 39076 1 +39079 2 3 39077 1 +39079 3 39076 3 0 1 +39079 4 3 28472 3 0 1 +39089 1 39086 1 +39089 2 3 39083 1 +39089 3 39086 4 0 1 +39089 4 3 39077 0 0 1 +39097 1 39092 1 +39097 2 5 39096 1 +39097 3 39092 1 0 1 +39097 4 5 30051 6 0 1 +39103 1 39098 1 +39103 2 5 39101 1 +39103 3 39098 2 0 1 +39103 4 5 36150 17 0 1 +39107 1 39105 1 +39107 2 2 39106 1 +39107 3 39105 3 0 1 +39107 4 2 20557 2 0 1 +39113 1 39110 1 +39113 2 3 39112 1 +39113 3 39110 1 0 1 +39113 4 3 30930 4 0 1 +39119 1 39108 1 +39119 2 11 39118 1 +39119 3 39108 1 0 1 +39119 4 11 25086 2 0 1 +39133 1 39128 1 +39133 2 5 39132 1 +39133 3 39128 1 0 1 +39133 4 5 24278 3 0 1 +39139 1 39132 1 +39139 2 7 39137 1 +39139 3 39132 10 0 1 +39139 4 7 34512 6 0 1 +39157 1 39151 1 +39157 2 6 39156 1 +39157 3 39151 1 0 1 +39157 4 6 25232 8 0 1 +39161 1 39158 1 +39161 2 3 39156 1 +39161 3 39158 1 0 1 +39161 4 3 35010 8 0 1 +39163 1 39161 1 +39163 2 2 39162 1 +39163 3 39161 2 0 1 +39163 4 2 39156 8 0 1 +39181 1 39175 1 +39181 2 6 39177 1 +39181 3 39175 2 0 1 +39181 4 6 39177 6 0 1 +39191 1 39180 1 +39191 2 11 39190 1 +39191 3 39180 1 0 1 +39191 4 11 35745 2 0 1 +39199 1 39182 1 +39199 2 17 39195 1 +39199 3 39182 7 0 1 +39199 4 17 36081 15 0 1 +39209 1 39206 1 +39209 2 3 39203 1 +39209 3 39206 4 0 1 +39209 4 3 39197 0 0 1 +39217 1 39210 1 +39217 2 7 39210 1 +39217 3 39210 4 0 1 +39217 4 7 26512 14 0 1 +39227 1 39225 1 +39227 2 2 39226 1 +39227 3 39225 2 0 1 +39227 4 2 39220 8 0 1 +39229 1 39227 1 +39229 2 2 39225 1 +39229 3 39227 5 0 1 +39229 4 2 23379 6 0 1 +39233 1 39230 1 +39233 2 3 39232 1 +39233 3 39230 1 0 1 +39233 4 3 29629 4 0 1 +39239 1 39232 1 +39239 2 7 39238 1 +39239 3 39232 1 0 1 +39239 4 7 36389 2 0 1 +39241 1 39234 1 +39241 2 7 39234 1 +39241 3 39234 2 0 1 +39241 4 7 31295 0 0 1 +39251 1 39249 1 +39251 2 2 39247 1 +39251 3 39249 3 0 1 +39251 4 2 22058 8 0 1 +39293 1 39291 1 +39293 2 2 39289 1 +39293 3 39291 3 0 1 +39293 4 2 33034 9 0 1 +39301 1 39294 1 +39301 2 7 39299 1 +39301 3 39294 1 0 1 +39301 4 7 38586 15 0 1 +39313 1 39303 1 +39313 2 10 39308 1 +39313 3 39303 3 0 1 +39313 4 10 32642 0 0 1 +39317 1 39315 1 +39317 2 2 39316 1 +39317 3 39315 2 0 1 +39317 4 2 36258 6 0 1 +39323 1 39321 1 +39323 2 2 39319 1 +39323 3 39321 5 0 1 +39323 4 2 22160 7 0 1 +39341 1 39339 1 +39341 2 2 39337 1 +39341 3 39339 2 0 1 +39341 4 2 31163 6 0 1 +39343 1 39340 1 +39343 2 3 39342 1 +39343 3 39340 13 0 1 +39343 4 3 23892 8 0 1 +39359 1 39348 1 +39359 2 11 39356 1 +39359 3 39348 2 0 1 +39359 4 11 27324 6 0 1 +39367 1 39364 1 +39367 2 3 39365 1 +39367 3 39364 9 0 1 +39367 4 3 30496 3 0 1 +39371 1 39369 1 +39371 2 2 39370 1 +39371 3 39369 4 0 1 +39371 4 2 35643 4 0 1 +39373 1 39351 1 +39373 2 22 39371 1 +39373 3 39351 3 0 1 +39373 4 22 38401 0 0 1 +39383 1 39378 1 +39383 2 5 39382 1 +39383 3 39378 1 0 1 +39383 4 5 38278 9 0 1 +39397 1 39395 1 +39397 2 2 39393 1 +39397 3 39395 5 0 1 +39397 4 2 36507 12 0 1 +39409 1 39402 1 +39409 2 7 39406 1 +39409 3 39402 1 0 1 +39409 4 7 32961 14 0 1 +39419 1 39417 1 +39419 2 2 39415 1 +39419 3 39417 3 0 1 +39419 4 2 21067 8 0 1 +39439 1 39436 1 +39439 2 3 39429 1 +39439 3 39436 3 0 1 +39439 4 3 23903 3 0 1 +39443 1 39441 1 +39443 2 2 39442 1 +39443 3 39441 2 0 1 +39443 4 2 30777 13 0 1 +39451 1 39449 1 +39451 2 2 39450 1 +39451 3 39449 6 0 1 +39451 4 2 37321 6 0 1 +39461 1 39459 1 +39461 2 2 39457 1 +39461 3 39459 2 0 1 +39461 4 2 20975 12 0 1 +39499 1 39497 1 +39499 2 2 39498 1 +39499 3 39497 6 0 1 +39499 4 2 23602 2 0 1 +39503 1 39498 1 +39503 2 5 39502 1 +39503 3 39498 1 0 1 +39503 4 5 30046 4 0 1 +39509 1 39506 1 +39509 2 3 39507 1 +39509 3 39506 1 0 1 +39509 4 3 39501 10 0 1 +39511 1 39508 1 +39511 2 3 39510 1 +39511 3 39508 5 0 1 +39511 4 3 26516 2 0 1 +39521 1 39518 1 +39521 2 3 39515 1 +39521 3 39518 1 0 1 +39521 4 3 39509 0 0 1 +39541 1 39539 1 +39541 2 2 39540 1 +39541 3 39539 4 0 1 +39541 4 2 20129 3 0 1 +39551 1 39544 1 +39551 2 7 39548 1 +39551 3 39544 5 0 1 +39551 4 7 26926 8 0 1 +39563 1 39561 1 +39563 2 2 39562 1 +39563 3 39561 3 0 1 +39563 4 2 25866 10 0 1 +39569 1 39566 1 +39569 2 3 39559 1 +39569 3 39566 1 0 1 +39569 4 3 21015 3 0 1 +39581 1 39579 1 +39581 2 2 39580 1 +39581 3 39579 3 0 1 +39581 4 2 39574 8 0 1 +39607 1 39604 1 +39607 2 3 39606 1 +39607 3 39604 3 0 1 +39607 4 3 21811 5 0 1 +39619 1 39617 1 +39619 2 2 39618 1 +39619 3 39617 6 0 1 +39619 4 2 19982 7 0 1 +39623 1 39618 1 +39623 2 5 39622 1 +39623 3 39618 5 0 1 +39623 4 5 21113 2 0 1 +39631 1 39628 1 +39631 2 3 39629 1 +39631 3 39628 6 0 1 +39631 4 3 29962 6 0 1 +39659 1 39657 1 +39659 2 2 39655 1 +39659 3 39657 3 0 1 +39659 4 2 30533 7 0 1 +39667 1 39664 1 +39667 2 3 39658 1 +39667 3 39664 5 0 1 +39667 4 3 34504 4 0 1 +39671 1 39664 1 +39671 2 7 39670 1 +39671 3 39664 5 0 1 +39671 4 7 20353 2 0 1 +39679 1 39673 1 +39679 2 6 39677 1 +39679 3 39673 2 0 1 +39679 4 6 29071 3 0 1 +39703 1 39698 1 +39703 2 5 39702 1 +39703 3 39698 1 0 1 +39703 4 5 20563 2 0 1 +39709 1 39703 1 +39709 2 6 39708 1 +39709 3 39703 2 0 1 +39709 4 6 38547 7 0 1 +39719 1 39712 1 +39719 2 7 39717 1 +39719 3 39712 1 0 1 +39719 4 7 38397 4 0 1 +39727 1 39724 1 +39727 2 3 39726 1 +39727 3 39724 3 0 1 +39727 4 3 35383 2 0 1 +39733 1 39731 1 +39733 2 2 39729 1 +39733 3 39731 6 0 1 +39733 4 2 29299 12 0 1 +39749 1 39747 1 +39749 2 2 39748 1 +39749 3 39747 3 0 1 +39749 4 2 29632 3 0 1 +39761 1 39758 1 +39761 2 3 39756 1 +39761 3 39758 8 0 1 +39761 4 3 20842 2 0 1 +39769 1 39756 1 +39769 2 13 39768 1 +39769 3 39756 3 0 1 +39769 4 13 31398 14 0 1 +39779 1 39777 1 +39779 2 2 39775 1 +39779 3 39777 3 0 1 +39779 4 2 26299 13 0 1 +39791 1 39780 1 +39791 2 11 39789 1 +39791 3 39780 6 0 1 +39791 4 11 20451 7 0 1 +39799 1 39796 1 +39799 2 3 39797 1 +39799 3 39796 1 0 1 +39799 4 3 20740 3 0 1 +39821 1 39819 1 +39821 2 2 39815 1 +39821 3 39819 4 0 1 +39821 4 2 23010 3 0 1 +39827 1 39825 1 +39827 2 2 39823 1 +39827 3 39825 3 0 1 +39827 4 2 27913 8 0 1 +39829 1 39823 1 +39829 2 6 39825 1 +39829 3 39823 1 0 1 +39829 4 6 35544 11 0 1 +39839 1 39832 1 +39839 2 7 39838 1 +39839 3 39832 1 0 1 +39839 4 7 34688 2 0 1 +39841 1 39810 1 +39841 2 31 39840 1 +39841 3 39810 8 0 1 +39841 4 31 37627 12 0 1 +39847 1 39842 1 +39847 2 5 39845 1 +39847 3 39842 1 0 1 +39847 4 5 36920 16 0 1 +39857 1 39854 1 +39857 2 3 39850 1 +39857 3 39854 5 0 1 +39857 4 3 32268 19 0 1 +39863 1 39858 1 +39863 2 5 39861 1 +39863 3 39858 2 0 1 +39863 4 5 32102 10 0 1 +39869 1 39867 1 +39869 2 2 39861 1 +39869 3 39867 2 0 1 +39869 4 2 35127 0 0 1 +39877 1 39875 1 +39877 2 2 39876 1 +39877 3 39875 2 0 1 +39877 4 2 27572 9 0 1 +39883 1 39880 1 +39883 2 3 39882 1 +39883 3 39880 3 0 1 +39883 4 3 27660 2 0 1 +39887 1 39880 1 +39887 2 7 39885 1 +39887 3 39880 3 0 1 +39887 4 7 28653 14 0 1 +39901 1 39899 1 +39901 2 2 39897 1 +39901 3 39899 4 0 1 +39901 4 2 32944 12 0 1 +39929 1 39926 1 +39929 2 3 39921 1 +39929 3 39926 3 0 1 +39929 4 3 23450 2 0 1 +39937 1 39932 1 +39937 2 5 39934 1 +39937 3 39932 1 0 1 +39937 4 5 20329 18 0 1 +39953 1 39950 1 +39953 2 3 39944 1 +39953 3 39950 4 0 1 +39953 4 3 21336 3 0 1 +39971 1 39969 1 +39971 2 2 39967 1 +39971 3 39969 2 0 1 +39971 4 2 38660 8 0 1 +39979 1 39976 1 +39979 2 3 39970 1 +39979 3 39976 3 0 1 +39979 4 3 28841 6 0 1 +39983 1 39978 1 +39983 2 5 39981 1 +39983 3 39978 6 0 1 +39983 4 5 39971 11 0 1 +39989 1 39987 1 +39989 2 2 39985 1 +39989 3 39987 3 0 1 +39989 4 2 36619 1 0 1 +40009 1 39998 1 +40009 2 11 40008 1 +40009 3 39998 3 0 1 +40009 4 11 30730 12 0 1 +40013 1 40011 1 +40013 2 2 40009 1 +40013 3 40011 3 0 1 +40013 4 2 29898 6 0 1 +40031 1 40012 1 +40031 2 19 40030 1 +40031 3 40012 5 0 1 +40031 4 19 40001 13 0 1 +40037 1 40035 1 +40037 2 2 40029 1 +40037 3 40035 12 0 1 +40037 4 2 35214 11 0 1 +40039 1 40033 1 +40039 2 6 40038 1 +40039 3 40033 1 0 1 +40039 4 6 38943 3 0 1 +40063 1 40060 1 +40063 2 3 40061 1 +40063 3 40060 1 0 1 +40063 4 3 40059 4 0 1 +40087 1 40084 1 +40087 2 3 40085 1 +40087 3 40084 4 0 1 +40087 4 3 21667 6 0 1 +40093 1 40091 1 +40093 2 2 40089 1 +40093 3 40091 5 0 1 +40093 4 2 30961 6 0 1 +40099 1 40096 1 +40099 2 3 40094 1 +40099 3 40096 6 0 1 +40099 4 3 23464 3 0 1 +40111 1 40108 1 +40111 2 3 40109 1 +40111 3 40108 1 0 1 +40111 4 3 29259 3 0 1 +40123 1 40121 1 +40123 2 2 40122 1 +40123 3 40121 2 0 1 +40123 4 2 34321 2 0 1 +40127 1 40122 1 +40127 2 5 40124 1 +40127 3 40122 7 0 1 +40127 4 5 25313 6 0 1 +40129 1 40122 1 +40129 2 7 40122 1 +40129 3 40122 1 0 1 +40129 4 7 37548 0 0 1 +40151 1 40140 1 +40151 2 11 40149 1 +40151 3 40140 4 0 1 +40151 4 11 24171 3 0 1 +40153 1 40148 1 +40153 2 5 40148 1 +40153 3 40148 2 0 1 +40153 4 5 34765 20 0 1 +40163 1 40161 1 +40163 2 2 40157 1 +40163 3 40161 7 0 1 +40163 4 2 38283 4 0 1 +40169 1 40166 1 +40169 2 3 40159 1 +40169 3 40166 4 0 1 +40169 4 3 29838 4 0 1 +40177 1 40167 1 +40177 2 10 40176 1 +40177 3 40167 5 0 1 +40177 4 10 23176 18 0 1 +40189 1 40187 1 +40189 2 2 40185 1 +40189 3 40187 6 0 1 +40189 4 2 33230 12 0 1 +40193 1 40190 1 +40193 2 3 40192 1 +40193 3 40190 5 0 1 +40193 4 3 25310 7 0 1 +40213 1 40207 1 +40213 2 6 40211 1 +40213 3 40207 3 0 1 +40213 4 6 39490 0 0 1 +40231 1 40228 1 +40231 2 3 40229 1 +40231 3 40228 3 0 1 +40231 4 3 38577 3 0 1 +40237 1 40231 1 +40237 2 6 40236 1 +40237 3 40231 3 0 1 +40237 4 6 21847 6 0 1 +40241 1 40238 1 +40241 2 3 40236 1 +40241 3 40238 3 0 1 +40241 4 3 37334 2 0 1 +40253 1 40251 1 +40253 2 2 40249 1 +40253 3 40251 2 0 1 +40253 4 2 33918 6 0 1 +40277 1 40275 1 +40277 2 2 40276 1 +40277 3 40275 3 0 1 +40277 4 2 36883 3 0 1 +40283 1 40281 1 +40283 2 2 40282 1 +40283 3 40281 3 0 1 +40283 4 2 40276 8 0 1 +40289 1 40286 1 +40289 2 3 40283 1 +40289 3 40286 3 0 1 +40289 4 3 40277 0 0 1 +40343 1 40338 1 +40343 2 5 40341 1 +40343 3 40338 1 0 1 +40343 4 5 40331 11 0 1 +40351 1 40348 1 +40351 2 3 40349 1 +40351 3 40348 4 0 1 +40351 4 3 24291 3 0 1 +40357 1 40352 1 +40357 2 5 40352 1 +40357 3 40352 2 0 1 +40357 4 5 28961 7 0 1 +40361 1 40358 1 +40361 2 3 40345 1 +40361 3 40358 1 0 1 +40361 4 3 27273 1 0 1 +40387 1 40385 1 +40387 2 2 40383 1 +40387 3 40385 6 0 1 +40387 4 2 25780 13 0 1 +40423 1 40420 1 +40423 2 3 40421 1 +40423 3 40420 1 0 1 +40423 4 3 32670 3 0 1 +40427 1 40425 1 +40427 2 2 40423 1 +40427 3 40425 4 0 1 +40427 4 2 25846 8 0 1 +40429 1 40415 1 +40429 2 14 40425 1 +40429 3 40415 5 0 1 +40429 4 14 24419 10 0 1 +40433 1 40428 1 +40433 2 5 40430 1 +40433 3 40428 1 0 1 +40433 4 5 27145 6 0 1 +40459 1 40457 1 +40459 2 2 40458 1 +40459 3 40457 5 0 1 +40459 4 2 27701 2 0 1 +40471 1 40468 1 +40471 2 3 40470 1 +40471 3 40468 6 0 1 +40471 4 3 21751 2 0 1 +40483 1 40481 1 +40483 2 2 40479 1 +40483 3 40481 4 0 1 +40483 4 2 25023 8 0 1 +40487 1 40482 1 +40487 2 5 40482 1 +40487 3 40482 1 0 1 +40487 4 5 32754 7 0 1 +40493 1 40491 1 +40493 2 2 40492 1 +40493 3 40491 3 0 1 +40493 4 2 37633 3 0 1 +40499 1 40497 1 +40499 2 2 40494 1 +40499 3 40497 2 0 1 +40499 4 2 22620 3 0 1 +40507 1 40505 1 +40507 2 2 40506 1 +40507 3 40505 5 0 1 +40507 4 2 36181 7 0 1 +40519 1 40513 1 +40519 2 6 40509 1 +40519 3 40513 3 0 1 +40519 4 6 33044 11 0 1 +40529 1 40526 1 +40529 2 3 40523 1 +40529 3 40526 3 0 1 +40529 4 3 40517 0 0 1 +40531 1 40529 1 +40531 2 2 40527 1 +40531 3 40529 2 0 1 +40531 4 2 26103 8 0 1 +40543 1 40540 1 +40543 2 3 40537 1 +40543 3 40540 1 0 1 +40543 4 3 20538 3 0 1 +40559 1 40552 1 +40559 2 7 40556 1 +40559 3 40552 3 0 1 +40559 4 7 28279 5 0 1 +40577 1 40574 1 +40577 2 3 40571 1 +40577 3 40574 4 0 1 +40577 4 3 23305 11 0 1 +40583 1 40578 1 +40583 2 5 40581 1 +40583 3 40578 3 0 1 +40583 4 5 36766 14 0 1 +40591 1 40578 1 +40591 2 13 40590 1 +40591 3 40578 6 0 1 +40591 4 13 23143 5 0 1 +40597 1 40595 1 +40597 2 2 40593 1 +40597 3 40595 5 0 1 +40597 4 2 27420 9 0 1 +40609 1 40587 1 +40609 2 22 40606 1 +40609 3 40587 5 0 1 +40609 4 22 32138 25 0 1 +40627 1 40625 1 +40627 2 2 40623 1 +40627 3 40625 4 0 1 +40627 4 2 30140 19 0 1 +40637 1 40635 1 +40637 2 2 40626 1 +40637 3 40635 7 0 1 +40637 4 2 20898 6 0 1 +40639 1 40632 1 +40639 2 7 40630 1 +40639 3 40632 1 0 1 +40639 4 7 24068 3 0 1 +40693 1 40691 1 +40693 2 2 40689 1 +40693 3 40691 7 0 1 +40693 4 2 40242 12 0 1 +40697 1 40694 1 +40697 2 3 40692 1 +40697 3 40694 1 0 1 +40697 4 3 32615 2 0 1 +40699 1 40697 1 +40699 2 2 40693 1 +40699 3 40697 2 0 1 +40699 4 2 22810 3 0 1 +40709 1 40707 1 +40709 2 2 40705 1 +40709 3 40707 2 0 1 +40709 4 2 26989 6 0 1 +40739 1 40737 1 +40739 2 2 40734 1 +40739 3 40737 11 0 1 +40739 4 2 26215 3 0 1 +40751 1 40737 1 +40751 2 14 40750 1 +40751 3 40737 5 0 1 +40751 4 14 26491 3 0 1 +40759 1 40756 1 +40759 2 3 40757 1 +40759 3 40756 1 0 1 +40759 4 3 40755 4 0 1 +40763 1 40761 1 +40763 2 2 40758 1 +40763 3 40761 9 0 1 +40763 4 2 25783 0 0 1 +40771 1 40761 1 +40771 2 10 40769 1 +40771 3 40761 2 0 1 +40771 4 10 34197 8 0 1 +40787 1 40785 1 +40787 2 2 40783 1 +40787 3 40785 2 0 1 +40787 4 2 21438 13 0 1 +40801 1 40788 1 +40801 2 13 40798 1 +40801 3 40788 1 0 1 +40801 4 13 20627 10 0 1 +40813 1 40811 1 +40813 2 2 40812 1 +40813 3 40811 2 0 1 +40813 4 2 24806 6 0 1 +40819 1 40816 1 +40819 2 3 40810 1 +40819 3 40816 3 0 1 +40819 4 3 24908 2 0 1 +40823 1 40818 1 +40823 2 5 40821 1 +40823 3 40818 5 0 1 +40823 4 5 40819 3 0 1 +40829 1 40827 1 +40829 2 2 40828 1 +40829 3 40827 7 0 1 +40829 4 2 23012 3 0 1 +40841 1 40838 1 +40841 2 3 40836 1 +40841 3 40838 7 0 1 +40841 4 3 29237 2 0 1 +40847 1 40842 1 +40847 2 5 40842 1 +40847 3 40842 3 0 1 +40847 4 5 29258 8 0 1 +40849 1 40838 1 +40849 2 11 40848 1 +40849 3 40838 2 0 1 +40849 4 11 31508 20 0 1 +40853 1 40851 1 +40853 2 2 40849 1 +40853 3 40851 3 0 1 +40853 4 2 25624 9 0 1 +40867 1 40865 1 +40867 2 2 40863 1 +40867 3 40865 6 0 1 +40867 4 2 24590 8 0 1 +40879 1 40873 1 +40879 2 6 40877 1 +40879 3 40873 3 0 1 +40879 4 6 23940 3 0 1 +40883 1 40881 1 +40883 2 2 40882 1 +40883 3 40881 2 0 1 +40883 4 2 24907 2 0 1 +40897 1 40892 1 +40897 2 5 40894 1 +40897 3 40892 1 0 1 +40897 4 5 37119 24 0 1 +40903 1 40900 1 +40903 2 3 40901 1 +40903 3 40900 1 0 1 +40903 4 3 38313 3 0 1 +40927 1 40924 1 +40927 2 3 40926 1 +40927 3 40924 1 0 1 +40927 4 3 40256 5 0 1 +40933 1 40931 1 +40933 2 2 40929 1 +40933 3 40931 10 0 1 +40933 4 2 39591 15 0 1 +40939 1 40937 1 +40939 2 2 40938 1 +40939 3 40937 4 0 1 +40939 4 2 33285 2 0 1 +40949 1 40947 1 +40949 2 2 40937 1 +40949 3 40947 3 0 1 +40949 4 2 27494 1 0 1 +40961 1 40958 1 +40961 2 3 40960 1 +40961 3 40958 3 0 1 +40961 4 3 36045 7 0 1 +40973 1 40971 1 +40973 2 2 40969 1 +40973 3 40971 3 0 1 +40973 4 2 25152 6 0 1 +40993 1 40988 1 +40993 2 5 40992 1 +40993 3 40988 10 0 1 +40993 4 5 36660 6 0 1 +41011 1 41009 1 +41011 2 2 41010 1 +41011 3 41009 6 0 1 +41011 4 2 30297 2 0 1 +41017 1 41012 1 +41017 2 5 41016 1 +41017 3 41012 11 0 1 +41017 4 5 38780 6 0 1 +41023 1 41018 1 +41023 2 5 41022 1 +41023 3 41018 7 0 1 +41023 4 5 25426 2 0 1 +41039 1 41028 1 +41039 2 11 41034 1 +41039 3 41028 1 0 1 +41039 4 11 35768 7 0 1 +41047 1 41042 1 +41047 2 5 41045 1 +41047 3 41042 2 0 1 +41047 4 5 31745 10 0 1 +41051 1 41049 1 +41051 2 2 41050 1 +41051 3 41049 3 0 1 +41051 4 2 26951 2 0 1 +41057 1 41054 1 +41057 2 3 41050 1 +41057 3 41054 4 0 1 +41057 4 3 25119 2 0 1 +41077 1 41075 1 +41077 2 2 41073 1 +41077 3 41075 4 0 1 +41077 4 2 28407 6 0 1 +41081 1 41078 1 +41081 2 3 41072 1 +41081 3 41078 14 0 1 +41081 4 3 40794 6 0 1 +41113 1 41108 1 +41113 2 5 41110 1 +41113 3 41108 2 0 1 +41113 4 5 40826 16 0 1 +41117 1 41115 1 +41117 2 2 41112 1 +41117 3 41115 2 0 1 +41117 4 2 36922 8 0 1 +41131 1 41121 1 +41131 2 10 41127 1 +41131 3 41121 5 0 1 +41131 4 10 20741 2 0 1 +41141 1 41139 1 +41141 2 2 41133 1 +41141 3 41139 2 0 1 +41141 4 2 25057 0 0 1 +41143 1 41140 1 +41143 2 3 41141 1 +41143 3 41140 1 0 1 +41143 4 3 25489 3 0 1 +41149 1 41147 1 +41149 2 2 41148 1 +41149 3 41147 6 0 1 +41149 4 2 41142 8 0 1 +41161 1 41139 1 +41161 2 22 41150 1 +41161 3 41139 6 0 1 +41161 4 22 31429 0 0 1 +41177 1 41174 1 +41177 2 3 41171 1 +41177 3 41174 3 0 1 +41177 4 3 32635 1 0 1 +41179 1 41176 1 +41179 2 3 41174 1 +41179 3 41176 5 0 1 +41179 4 3 37566 3 0 1 +41183 1 41178 1 +41183 2 5 41182 1 +41183 3 41178 17 0 1 +41183 4 5 34579 2 0 1 +41189 1 41187 1 +41189 2 2 41179 1 +41189 3 41187 7 0 1 +41189 4 2 26633 0 0 1 +41201 1 41198 1 +41201 2 3 41200 1 +41201 3 41198 12 0 1 +41201 4 3 32563 4 0 1 +41203 1 41200 1 +41203 2 3 41202 1 +41203 3 41200 6 0 1 +41203 4 3 29148 5 0 1 +41213 1 41211 1 +41213 2 2 41209 1 +41213 3 41211 12 0 1 +41213 4 2 40807 6 0 1 +41221 1 41219 1 +41221 2 2 41220 1 +41221 3 41219 4 0 1 +41221 4 2 22592 7 0 1 +41227 1 41225 1 +41227 2 2 41221 1 +41227 3 41225 6 0 1 +41227 4 2 24158 22 0 1 +41231 1 41224 1 +41231 2 7 41229 1 +41231 3 41224 1 0 1 +41231 4 7 39520 7 0 1 +41233 1 41228 1 +41233 2 5 41228 1 +41233 3 41228 3 0 1 +41233 4 5 39339 12 0 1 +41243 1 41241 1 +41243 2 2 41239 1 +41243 3 41241 3 0 1 +41243 4 2 29410 16 0 1 +41257 1 41252 1 +41257 2 5 41256 1 +41257 3 41252 7 0 1 +41257 4 5 40905 8 0 1 +41263 1 41258 1 +41263 2 5 41262 1 +41263 3 41258 1 0 1 +41263 4 5 21896 2 0 1 +41269 1 41267 1 +41269 2 2 41264 1 +41269 3 41267 6 0 1 +41269 4 2 25657 15 0 1 +41281 1 41264 1 +41281 2 17 41278 1 +41281 3 41264 4 0 1 +41281 4 17 34193 16 0 1 +41299 1 41297 1 +41299 2 2 41298 1 +41299 3 41297 4 0 1 +41299 4 2 27828 6 0 1 +41333 1 41331 1 +41333 2 2 41329 1 +41333 3 41331 3 0 1 +41333 4 2 40337 1 0 1 +41341 1 41339 1 +41341 2 2 41340 1 +41341 3 41339 6 0 1 +41341 4 2 31592 7 0 1 +41351 1 41344 1 +41351 2 7 41350 1 +41351 3 41344 1 0 1 +41351 4 7 27913 2 0 1 +41357 1 41355 1 +41357 2 2 41353 1 +41357 3 41355 3 0 1 +41357 4 2 38481 7 0 1 +41381 1 41378 1 +41381 2 3 41380 1 +41381 3 41378 5 0 1 +41381 4 3 28687 3 0 1 +41387 1 41385 1 +41387 2 2 41386 1 +41387 3 41385 2 0 1 +41387 4 2 39457 11 0 1 +41389 1 41383 1 +41389 2 6 41385 1 +41389 3 41383 4 0 1 +41389 4 6 31412 2 0 1 +41399 1 41392 1 +41399 2 7 41397 1 +41399 3 41392 1 0 1 +41399 4 7 21094 18 0 1 +41411 1 41409 1 +41411 2 2 41410 1 +41411 3 41409 3 0 1 +41411 4 2 38845 2 0 1 +41413 1 41407 1 +41413 2 6 41411 1 +41413 3 41407 2 0 1 +41413 4 6 21880 8 0 1 +41443 1 41441 1 +41443 2 2 41442 1 +41443 3 41441 6 0 1 +41443 4 2 41436 8 0 1 +41453 1 41451 1 +41453 2 2 41448 1 +41453 3 41451 2 0 1 +41453 4 2 23622 2 0 1 +41467 1 41453 1 +41467 2 14 41465 1 +41467 3 41453 4 0 1 +41467 4 14 24950 0 0 1 +41479 1 41476 1 +41479 2 3 41477 1 +41479 3 41476 9 0 1 +41479 4 3 36172 3 0 1 +41491 1 41478 1 +41491 2 13 41490 1 +41491 3 41478 1 0 1 +41491 4 13 34900 5 0 1 +41507 1 41505 1 +41507 2 2 41503 1 +41507 3 41505 3 0 1 +41507 4 2 22418 8 0 1 +41513 1 41510 1 +41513 2 3 41512 1 +41513 3 41510 1 0 1 +41513 4 3 27579 6 0 1 +41519 1 41512 1 +41519 2 7 41517 1 +41519 3 41512 2 0 1 +41519 4 7 26294 4 0 1 +41521 1 41499 1 +41521 2 22 41510 1 +41521 3 41499 3 0 1 +41521 4 22 26353 0 0 1 +41539 1 41536 1 +41539 2 3 41528 1 +41539 3 41536 1 0 1 +41539 4 3 21498 1 0 1 +41543 1 41538 1 +41543 2 5 41541 1 +41543 3 41538 2 0 1 +41543 4 5 29025 10 0 1 +41549 1 41546 1 +41549 2 3 41548 1 +41549 3 41546 4 0 1 +41549 4 3 21142 3 0 1 +41579 1 41577 1 +41579 2 2 41578 1 +41579 3 41577 12 0 1 +41579 4 2 33637 4 0 1 +41593 1 41588 1 +41593 2 5 41590 1 +41593 3 41588 9 0 1 +41593 4 5 41582 14 0 1 +41597 1 41595 1 +41597 2 2 41596 1 +41597 3 41595 2 0 1 +41597 4 2 25029 4 0 1 +41603 1 41601 1 +41603 2 2 41597 1 +41603 3 41601 4 0 1 +41603 4 2 28645 4 0 1 +41609 1 41606 1 +41609 2 3 41608 1 +41609 3 41606 6 0 1 +41609 4 3 22146 4 0 1 +41611 1 41609 1 +41611 2 2 41610 1 +41611 3 41609 6 0 1 +41611 4 2 40112 2 0 1 +41617 1 41612 1 +41617 2 5 41612 1 +41617 3 41612 1 0 1 +41617 4 5 40597 10 0 1 +41621 1 41618 1 +41621 2 3 41613 1 +41621 3 41618 3 0 1 +41621 4 3 39277 1 0 1 +41627 1 41625 1 +41627 2 2 41626 1 +41627 3 41625 3 0 1 +41627 4 2 38959 2 0 1 +41641 1 41628 1 +41641 2 13 41632 1 +41641 3 41628 1 0 1 +41641 4 13 34077 31 0 1 +41647 1 41644 1 +41647 2 3 41645 1 +41647 3 41644 1 0 1 +41647 4 3 24249 3 0 1 +41651 1 41649 1 +41651 2 2 41645 1 +41651 3 41649 4 0 1 +41651 4 2 40974 0 0 1 +41659 1 41656 1 +41659 2 3 41658 1 +41659 3 41656 11 0 1 +41659 4 3 27113 6 0 1 +41669 1 41667 1 +41669 2 2 41665 1 +41669 3 41667 3 0 1 +41669 4 2 28432 1 0 1 +41681 1 41678 1 +41681 2 3 41680 1 +41681 3 41678 7 0 1 +41681 4 3 40406 7 0 1 +41687 1 41682 1 +41687 2 5 41685 1 +41687 3 41682 3 0 1 +41687 4 5 41683 3 0 1 +41719 1 41713 1 +41719 2 6 41718 1 +41719 3 41713 4 0 1 +41719 4 6 28988 3 0 1 +41729 1 41726 1 +41729 2 3 41728 1 +41729 3 41726 5 0 1 +41729 4 3 32489 7 0 1 +41737 1 41732 1 +41737 2 5 41736 1 +41737 3 41732 3 0 1 +41737 4 5 33331 6 0 1 +41759 1 41752 1 +41759 2 7 41758 1 +41759 3 41752 2 0 1 +41759 4 7 41302 3 0 1 +41761 1 41742 1 +41761 2 19 41758 1 +41761 3 41742 2 0 1 +41761 4 19 21110 10 0 1 +41771 1 41769 1 +41771 2 2 41767 1 +41771 3 41769 3 0 1 +41771 4 2 40857 7 0 1 +41777 1 41774 1 +41777 2 3 41776 1 +41777 3 41774 3 0 1 +41777 4 3 28975 4 0 1 +41801 1 41798 1 +41801 2 3 41796 1 +41801 3 41798 4 0 1 +41801 4 3 37527 2 0 1 +41809 1 41788 1 +41809 2 21 41805 1 +41809 3 41788 3 0 1 +41809 4 21 25666 18 0 1 +41813 1 41811 1 +41813 2 2 41809 1 +41813 3 41811 3 0 1 +41813 4 2 33303 6 0 1 +41843 1 41841 1 +41843 2 2 41839 1 +41843 3 41841 3 0 1 +41843 4 2 37269 7 0 1 +41849 1 41846 1 +41849 2 3 41843 1 +41849 3 41846 3 0 1 +41849 4 3 41837 0 0 1 +41851 1 41836 1 +41851 2 15 41848 1 +41851 3 41836 5 0 1 +41851 4 15 29500 9 0 1 +41863 1 41860 1 +41863 2 3 41862 1 +41863 3 41860 5 0 1 +41863 4 3 35189 5 0 1 +41879 1 41866 1 +41879 2 13 41878 1 +41879 3 41866 6 0 1 +41879 4 13 32276 2 0 1 +41887 1 41884 1 +41887 2 3 41886 1 +41887 3 41884 5 0 1 +41887 4 3 30353 5 0 1 +41893 1 41891 1 +41893 2 2 41892 1 +41893 3 41891 2 0 1 +41893 4 2 41155 6 0 1 +41897 1 41894 1 +41897 2 3 41892 1 +41897 3 41894 1 0 1 +41897 4 3 38726 8 0 1 +41903 1 41898 1 +41903 2 5 41901 1 +41903 3 41898 1 0 1 +41903 4 5 27030 14 0 1 +41911 1 41908 1 +41911 2 3 41909 1 +41911 3 41908 3 0 1 +41911 4 3 41907 4 0 1 +41927 1 41922 1 +41927 2 5 41926 1 +41927 3 41922 5 0 1 +41927 4 5 33194 5 0 1 +41941 1 41939 1 +41941 2 2 41937 1 +41941 3 41939 2 0 1 +41941 4 2 33233 12 0 1 +41947 1 41942 1 +41947 2 5 41946 1 +41947 3 41942 3 0 1 +41947 4 5 40004 2 0 1 +41953 1 41948 1 +41953 2 5 41950 1 +41953 3 41948 6 0 1 +41953 4 5 41942 14 0 1 +41957 1 41955 1 +41957 2 2 41956 1 +41957 3 41955 2 0 1 +41957 4 2 35105 4 0 1 +41959 1 41953 1 +41959 2 6 41958 1 +41959 3 41953 3 0 1 +41959 4 6 38417 2 0 1 +41969 1 41966 1 +41969 2 3 41963 1 +41969 3 41966 5 0 1 +41969 4 3 41957 0 0 1 +41981 1 41979 1 +41981 2 2 41977 1 +41981 3 41979 3 0 1 +41981 4 2 33173 7 0 1 +41983 1 41977 1 +41983 2 6 41980 1 +41983 3 41977 2 0 1 +41983 4 6 39620 5 0 1 +41999 1 41988 1 +41999 2 11 41997 1 +41999 3 41988 4 0 1 +41999 4 11 30341 7 0 1 +42013 1 42007 1 +42013 2 6 42012 1 +42013 3 42007 1 0 1 +42013 4 6 25317 8 0 1 +42017 1 42014 1 +42017 2 3 42016 1 +42017 3 42014 4 0 1 +42017 4 3 41727 7 0 1 +42019 1 42017 1 +42019 2 2 42018 1 +42019 3 42017 5 0 1 +42019 4 2 22334 2 0 1 +42023 1 42018 1 +42023 2 5 42021 1 +42023 3 42018 8 0 1 +42023 4 5 42019 3 0 1 +42043 1 42038 1 +42043 2 5 42042 1 +42043 3 42038 5 0 1 +42043 4 5 35790 2 0 1 +42061 1 42055 1 +42061 2 6 42060 1 +42061 3 42055 2 0 1 +42061 4 6 32864 7 0 1 +42071 1 42064 1 +42071 2 7 42067 1 +42071 3 42064 9 0 1 +42071 4 7 31233 5 0 1 +42073 1 42068 1 +42073 2 5 42068 1 +42073 3 42068 2 0 1 +42073 4 5 38165 12 0 1 +42083 1 42081 1 +42083 2 2 42079 1 +42083 3 42081 3 0 1 +42083 4 2 36671 7 0 1 +42089 1 42086 1 +42089 2 3 42083 1 +42089 3 42086 3 0 1 +42089 4 3 42077 0 0 1 +42101 1 42099 1 +42101 2 2 42100 1 +42101 3 42099 4 0 1 +42101 4 2 26708 4 0 1 +42131 1 42129 1 +42131 2 2 42130 1 +42131 3 42129 4 0 1 +42131 4 2 22755 6 0 1 +42139 1 42137 1 +42139 2 2 42135 1 +42139 3 42137 4 0 1 +42139 4 2 31828 1 0 1 +42157 1 42155 1 +42157 2 2 42156 1 +42157 3 42155 2 0 1 +42157 4 2 41262 7 0 1 +42169 1 42158 1 +42169 2 11 42168 1 +42169 3 42158 3 0 1 +42169 4 11 39075 12 0 1 +42179 1 42177 1 +42179 2 2 42161 1 +42179 3 42177 2 0 1 +42179 4 2 35470 0 0 1 +42181 1 42171 1 +42181 2 10 42178 1 +42181 3 42171 4 0 1 +42181 4 10 35274 1 0 1 +42187 1 42174 1 +42187 2 13 42186 1 +42187 3 42174 1 0 1 +42187 4 13 35833 8 0 1 +42193 1 42178 1 +42193 2 15 42192 1 +42193 3 42178 3 0 1 +42193 4 15 39181 12 0 1 +42197 1 42195 1 +42197 2 2 42192 1 +42197 3 42195 3 0 1 +42197 4 2 33616 17 0 1 +42209 1 42206 1 +42209 2 3 42208 1 +42209 3 42206 1 0 1 +42209 4 3 25189 4 0 1 +42221 1 42219 1 +42221 2 2 42216 1 +42221 3 42219 4 0 1 +42221 4 2 26446 2 0 1 +42223 1 42218 1 +42223 2 5 42218 1 +42223 3 42218 5 0 1 +42223 4 5 24675 12 0 1 +42227 1 42225 1 +42227 2 2 42226 1 +42227 3 42225 2 0 1 +42227 4 2 41308 4 0 1 +42239 1 42232 1 +42239 2 7 42235 1 +42239 3 42232 3 0 1 +42239 4 7 21824 5 0 1 +42257 1 42254 1 +42257 2 3 42256 1 +42257 3 42254 3 0 1 +42257 4 3 27944 4 0 1 +42281 1 42270 1 +42281 2 11 42270 1 +42281 3 42270 13 0 1 +42281 4 11 35421 0 0 1 +42283 1 42281 1 +42283 2 2 42282 1 +42283 3 42281 2 0 1 +42283 4 2 38525 7 0 1 +42293 1 42291 1 +42293 2 2 42292 1 +42293 3 42291 2 0 1 +42293 4 2 26526 6 0 1 +42299 1 42297 1 +42299 2 2 42298 1 +42299 3 42297 3 0 1 +42299 4 2 29826 2 0 1 +42307 1 42304 1 +42307 2 3 42302 1 +42307 3 42304 4 0 1 +42307 4 3 29452 14 0 1 +42323 1 42321 1 +42323 2 2 42318 1 +42323 3 42321 7 0 1 +42323 4 2 37569 3 0 1 +42331 1 42328 1 +42331 2 3 42322 1 +42331 3 42328 3 0 1 +42331 4 3 35501 7 0 1 +42337 1 42332 1 +42337 2 5 42332 1 +42337 3 42332 6 0 1 +42337 4 5 33700 10 0 1 +42349 1 42347 1 +42349 2 2 42348 1 +42349 3 42347 6 0 1 +42349 4 2 41579 3 0 1 +42359 1 42352 1 +42359 2 7 42358 1 +42359 3 42352 1 0 1 +42359 4 7 30711 2 0 1 +42373 1 42368 1 +42373 2 5 42372 1 +42373 3 42368 1 0 1 +42373 4 5 25617 3 0 1 +42379 1 42377 1 +42379 2 2 42375 1 +42379 3 42377 2 0 1 +42379 4 2 33587 8 0 1 +42391 1 42385 1 +42391 2 6 42387 1 +42391 3 42385 3 0 1 +42391 4 6 29306 1 0 1 +42397 1 42395 1 +42397 2 2 42396 1 +42397 3 42395 2 0 1 +42397 4 2 33251 6 0 1 +42403 1 42401 1 +42403 2 2 42399 1 +42403 3 42401 4 0 1 +42403 4 2 26121 8 0 1 +42407 1 42402 1 +42407 2 5 42406 1 +42407 3 42402 1 0 1 +42407 4 5 30921 2 0 1 +42409 1 42395 1 +42409 2 14 42406 1 +42409 3 42395 4 0 1 +42409 4 14 34944 20 0 1 +42433 1 42423 1 +42433 2 10 42428 1 +42433 3 42423 2 0 1 +42433 4 10 24349 0 0 1 +42437 1 42435 1 +42437 2 2 42436 1 +42437 3 42435 2 0 1 +42437 4 2 32230 3 0 1 +42443 1 42441 1 +42443 2 2 42439 1 +42443 3 42441 3 0 1 +42443 4 2 29817 8 0 1 +42451 1 42448 1 +42451 2 3 42450 1 +42451 3 42448 4 0 1 +42451 4 3 32143 2 0 1 +42457 1 42446 1 +42457 2 11 42455 1 +42457 3 42446 5 0 1 +42457 4 11 36096 22 0 1 +42461 1 42459 1 +42461 2 2 42457 1 +42461 3 42459 3 0 1 +42461 4 2 28461 1 0 1 +42463 1 42460 1 +42463 2 3 42461 1 +42463 3 42460 8 0 1 +42463 4 3 42459 4 0 1 +42467 1 42462 1 +42467 2 5 42466 1 +42467 3 42462 1 0 1 +42467 4 5 33449 2 0 1 +42473 1 42470 1 +42473 2 3 42472 1 +42473 3 42470 1 0 1 +42473 4 3 39182 7 0 1 +42487 1 42482 1 +42487 2 5 42486 1 +42487 3 42482 7 0 1 +42487 4 5 33118 2 0 1 +42491 1 42489 1 +42491 2 2 42487 1 +42491 3 42489 3 0 1 +42491 4 2 42134 7 0 1 +42499 1 42497 1 +42499 2 2 42495 1 +42499 3 42497 2 0 1 +42499 4 2 33589 8 0 1 +42509 1 42507 1 +42509 2 2 42503 1 +42509 3 42507 9 0 1 +42509 4 2 41205 4 0 1 +42533 1 42531 1 +42533 2 2 42529 1 +42533 3 42531 3 0 1 +42533 4 2 28048 12 0 1 +42557 1 42555 1 +42557 2 2 42553 1 +42557 3 42555 3 0 1 +42557 4 2 23138 6 0 1 +42569 1 42566 1 +42569 2 3 42568 1 +42569 3 42566 3 0 1 +42569 4 3 40558 7 0 1 +42571 1 42569 1 +42571 2 2 42567 1 +42571 3 42569 6 0 1 +42571 4 2 32911 8 0 1 +42577 1 42570 1 +42577 2 7 42570 1 +42577 3 42570 2 0 1 +42577 4 7 32664 14 0 1 +42589 1 42587 1 +42589 2 2 42585 1 +42589 3 42587 2 0 1 +42589 4 2 26561 12 0 1 +42611 1 42609 1 +42611 2 2 42607 1 +42611 3 42609 3 0 1 +42611 4 2 35865 8 0 1 +42641 1 42638 1 +42641 2 3 42635 1 +42641 3 42638 4 0 1 +42641 4 3 42629 0 0 1 +42643 1 42641 1 +42643 2 2 42642 1 +42643 3 42641 2 0 1 +42643 4 2 27387 7 0 1 +42649 1 42638 1 +42649 2 11 42646 1 +42649 3 42638 3 0 1 +42649 4 11 24225 14 0 1 +42667 1 42660 1 +42667 2 7 42665 1 +42667 3 42660 2 0 1 +42667 4 7 29827 15 0 1 +42677 1 42675 1 +42677 2 2 42676 1 +42677 3 42675 2 0 1 +42677 4 2 38324 4 0 1 +42683 1 42681 1 +42683 2 2 42679 1 +42683 3 42681 3 0 1 +42683 4 2 34075 7 0 1 +42689 1 42686 1 +42689 2 3 42678 1 +42689 3 42686 20 0 1 +42689 4 3 21718 4 0 1 +42697 1 42692 1 +42697 2 5 42694 1 +42697 3 42692 3 0 1 +42697 4 5 29768 29 0 1 +42701 1 42698 1 +42701 2 3 42700 1 +42701 3 42698 7 0 1 +42701 4 3 21824 3 0 1 +42703 1 42698 1 +42703 2 5 42702 1 +42703 3 42698 1 0 1 +42703 4 5 33987 2 0 1 +42709 1 42703 1 +42709 2 6 42708 1 +42709 3 42703 2 0 1 +42709 4 6 26009 11 0 1 +42719 1 42700 1 +42719 2 19 42718 1 +42719 3 42700 9 0 1 +42719 4 19 24773 6 0 1 +42727 1 42724 1 +42727 2 3 42725 1 +42727 3 42724 5 0 1 +42727 4 3 37668 3 0 1 +42737 1 42734 1 +42737 2 3 42736 1 +42737 3 42734 9 0 1 +42737 4 3 39247 6 0 1 +42743 1 42736 1 +42743 2 7 42741 1 +42743 3 42736 7 0 1 +42743 4 7 26987 10 0 1 +42751 1 42745 1 +42751 2 6 42750 1 +42751 3 42745 1 0 1 +42751 4 6 37845 2 0 1 +42767 1 42762 1 +42767 2 5 42765 1 +42767 3 42762 3 0 1 +42767 4 5 37821 14 0 1 +42773 1 42770 1 +42773 2 3 42771 1 +42773 3 42770 4 0 1 +42773 4 3 24335 7 0 1 +42787 1 42782 1 +42787 2 5 42786 1 +42787 3 42782 1 0 1 +42787 4 5 34696 10 0 1 +42793 1 42788 1 +42793 2 5 42788 1 +42793 3 42788 1 0 1 +42793 4 5 26894 15 0 1 +42797 1 42795 1 +42797 2 2 42796 1 +42797 3 42795 2 0 1 +42797 4 2 42790 8 0 1 +42821 1 42819 1 +42821 2 2 42817 1 +42821 3 42819 2 0 1 +42821 4 2 39582 7 0 1 +42829 1 42827 1 +42829 2 2 42828 1 +42829 3 42827 5 0 1 +42829 4 2 32006 3 0 1 +42839 1 42828 1 +42839 2 11 42837 1 +42839 3 42828 7 0 1 +42839 4 11 23627 5 0 1 +42841 1 42818 1 +42841 2 23 42840 1 +42841 3 42818 1 0 1 +42841 4 23 39641 12 0 1 +42853 1 42851 1 +42853 2 2 42852 1 +42853 3 42851 2 0 1 +42853 4 2 38687 14 0 1 +42859 1 42849 1 +42859 2 10 42858 1 +42859 3 42849 2 0 1 +42859 4 10 38482 5 0 1 +42863 1 42858 1 +42863 2 5 42862 1 +42863 3 42858 1 0 1 +42863 4 5 39068 4 0 1 +42899 1 42897 1 +42899 2 2 42898 1 +42899 3 42897 3 0 1 +42899 4 2 22968 4 0 1 +42901 1 42895 1 +42901 2 6 42897 1 +42901 3 42895 8 0 1 +42901 4 6 39485 2 0 1 +42923 1 42921 1 +42923 2 2 42911 1 +42923 3 42921 2 0 1 +42923 4 2 27243 16 0 1 +42929 1 42926 1 +42929 2 3 42919 1 +42929 3 42926 5 0 1 +42929 4 3 38061 3 0 1 +42937 1 42932 1 +42937 2 5 42932 1 +42937 3 42932 1 0 1 +42937 4 5 42644 10 0 1 +42943 1 42940 1 +42943 2 3 42942 1 +42943 3 42940 3 0 1 +42943 4 3 26521 5 0 1 +42953 1 42950 1 +42953 2 3 42947 1 +42953 3 42950 6 0 1 +42953 4 3 35469 25 0 1 +42961 1 42950 1 +42961 2 11 42956 1 +42961 3 42950 2 0 1 +42961 4 11 24271 16 0 1 +42967 1 42964 1 +42967 2 3 42965 1 +42967 3 42964 1 0 1 +42967 4 3 29612 3 0 1 +42979 1 42976 1 +42979 2 3 42978 1 +42979 3 42976 1 0 1 +42979 4 3 31641 6 0 1 +42989 1 42987 1 +42989 2 2 42981 1 +42989 3 42987 8 0 1 +42989 4 2 29404 0 0 1 +43003 1 42998 1 +43003 2 5 43001 1 +43003 3 42998 1 0 1 +43003 4 5 42995 6 0 1 +43013 1 43011 1 +43013 2 2 43012 1 +43013 3 43011 2 0 1 +43013 4 2 25052 4 0 1 +43019 1 43017 1 +43019 2 2 43015 1 +43019 3 43017 3 0 1 +43019 4 2 25405 8 0 1 +43037 1 43035 1 +43037 2 2 43033 1 +43037 3 43035 3 0 1 +43037 4 2 40246 6 0 1 +43049 1 43046 1 +43049 2 3 43048 1 +43049 3 43046 18 0 1 +43049 4 3 25533 4 0 1 +43051 1 43049 1 +43051 2 2 43047 1 +43051 3 43049 2 0 1 +43051 4 2 39322 8 0 1 +43063 1 43060 1 +43063 2 3 43058 1 +43063 3 43060 12 0 1 +43063 4 3 40513 6 0 1 +43067 1 43065 1 +43067 2 2 43066 1 +43067 3 43065 2 0 1 +43067 4 2 38385 4 0 1 +43093 1 43088 1 +43093 2 5 43090 1 +43093 3 43088 1 0 1 +43093 4 5 38709 1 0 1 +43103 1 43098 1 +43103 2 5 43101 1 +43103 3 43098 1 0 1 +43103 4 5 43099 3 0 1 +43117 1 43115 1 +43117 2 2 43113 1 +43117 3 43115 6 0 1 +43117 4 2 33081 6 0 1 +43133 1 43131 1 +43133 2 2 43127 1 +43133 3 43131 3 0 1 +43133 4 2 35076 3 0 1 +43151 1 43140 1 +43151 2 11 43150 1 +43151 3 43140 4 0 1 +43151 4 11 28114 4 0 1 +43159 1 43156 1 +43159 2 3 43158 1 +43159 3 43156 4 0 1 +43159 4 3 34751 3 0 1 +43177 1 43172 1 +43177 2 5 43174 1 +43177 3 43172 1 0 1 +43177 4 5 43166 14 0 1 +43189 1 43187 1 +43189 2 2 43183 1 +43189 3 43187 6 0 1 +43189 4 2 36760 0 0 1 +43201 1 43178 1 +43201 2 23 43200 1 +43201 3 43178 1 0 1 +43201 4 23 29702 14 0 1 +43207 1 43204 1 +43207 2 3 43206 1 +43207 3 43204 4 0 1 +43207 4 3 39155 5 0 1 +43223 1 43218 1 +43223 2 5 43221 1 +43223 3 43218 9 0 1 +43223 4 5 39112 10 0 1 +43237 1 43235 1 +43237 2 2 43236 1 +43237 3 43235 2 0 1 +43237 4 2 24655 7 0 1 +43261 1 43259 1 +43261 2 2 43257 1 +43261 3 43259 2 0 1 +43261 4 2 28419 10 0 1 +43271 1 43258 1 +43271 2 13 43269 1 +43271 3 43258 1 0 1 +43271 4 13 43259 5 0 1 +43283 1 43281 1 +43283 2 2 43279 1 +43283 3 43281 3 0 1 +43283 4 2 38919 7 0 1 +43291 1 43288 1 +43291 2 3 43290 1 +43291 3 43288 1 0 1 +43291 4 3 34735 6 0 1 +43313 1 43310 1 +43313 2 3 43312 1 +43313 3 43310 8 0 1 +43313 4 3 40552 4 0 1 +43319 1 43308 1 +43319 2 11 43317 1 +43319 3 43308 1 0 1 +43319 4 11 38802 3 0 1 +43321 1 43308 1 +43321 2 13 43320 1 +43321 3 43308 1 0 1 +43321 4 13 29474 14 0 1 +43331 1 43329 1 +43331 2 2 43327 1 +43331 3 43329 3 0 1 +43331 4 2 40546 7 0 1 +43391 1 43374 1 +43391 2 17 43390 1 +43391 3 43374 1 0 1 +43391 4 17 27050 2 0 1 +43397 1 43395 1 +43397 2 2 43393 1 +43397 3 43395 3 0 1 +43397 4 2 33130 7 0 1 +43399 1 43386 1 +43399 2 13 43396 1 +43399 3 43386 1 0 1 +43399 4 13 41165 0 0 1 +43403 1 43401 1 +43403 2 2 43402 1 +43403 3 43401 2 0 1 +43403 4 2 32462 2 0 1 +43411 1 43408 1 +43411 2 3 43402 1 +43411 3 43408 3 0 1 +43411 4 3 21982 2 0 1 +43427 1 43425 1 +43427 2 2 43426 1 +43427 3 43425 2 0 1 +43427 4 2 42961 4 0 1 +43441 1 43430 1 +43441 2 11 43438 1 +43441 3 43430 1 0 1 +43441 4 11 34169 10 0 1 +43451 1 43449 1 +43451 2 2 43447 1 +43451 3 43449 3 0 1 +43451 4 2 23733 7 0 1 +43457 1 43454 1 +43457 2 3 43452 1 +43457 3 43454 3 0 1 +43457 4 3 25956 0 0 1 +43481 1 43475 1 +43481 2 6 43480 1 +43481 3 43475 8 0 1 +43481 4 6 32217 7 0 1 +43487 1 43482 1 +43487 2 5 43485 1 +43487 3 43482 5 0 1 +43487 4 5 38995 8 0 1 +43499 1 43497 1 +43499 2 2 43495 1 +43499 3 43497 2 0 1 +43499 4 2 24344 9 0 1 +43517 1 43515 1 +43517 2 2 43516 1 +43517 3 43515 8 0 1 +43517 4 2 29167 9 0 1 +43541 1 43539 1 +43541 2 2 43537 1 +43541 3 43539 3 0 1 +43541 4 2 33814 12 0 1 +43543 1 43540 1 +43543 2 3 43541 1 +43543 3 43540 1 0 1 +43543 4 3 37975 3 0 1 +43573 1 43571 1 +43573 2 2 43572 1 +43573 3 43571 2 0 1 +43573 4 2 32563 3 0 1 +43577 1 43574 1 +43577 2 3 43576 1 +43577 3 43574 8 0 1 +43577 4 3 39567 18 0 1 +43579 1 43577 1 +43579 2 2 43575 1 +43579 3 43577 6 0 1 +43579 4 2 36760 8 0 1 +43591 1 43580 1 +43591 2 11 43590 1 +43591 3 43580 2 0 1 +43591 4 11 39505 2 0 1 +43597 1 43595 1 +43597 2 2 43593 1 +43597 3 43595 6 0 1 +43597 4 2 25494 9 0 1 +43607 1 43602 1 +43607 2 5 43606 1 +43607 3 43602 7 0 1 +43607 4 5 33614 2 0 1 +43609 1 43595 1 +43609 2 14 43607 1 +43609 3 43595 5 0 1 +43609 4 14 43583 15 0 1 +43613 1 43611 1 +43613 2 2 43612 1 +43613 3 43611 2 0 1 +43613 4 2 33869 6 0 1 +43627 1 43625 1 +43627 2 2 43626 1 +43627 3 43625 2 0 1 +43627 4 2 23387 11 0 1 +43633 1 43628 1 +43633 2 5 43630 1 +43633 3 43628 2 0 1 +43633 4 5 42940 29 0 1 +43649 1 43646 1 +43649 2 3 43644 1 +43649 3 43646 3 0 1 +43649 4 3 39029 2 0 1 +43651 1 43649 1 +43651 2 2 43650 1 +43651 3 43649 5 0 1 +43651 4 2 31013 6 0 1 +43661 1 43659 1 +43661 2 2 43657 1 +43661 3 43659 3 0 1 +43661 4 2 42390 6 0 1 +43669 1 43667 1 +43669 2 2 43665 1 +43669 3 43667 4 0 1 +43669 4 2 31089 11 0 1 +43691 1 43685 1 +43691 2 6 43688 1 +43691 3 43685 2 0 1 +43691 4 6 25082 4 0 1 +43711 1 43698 1 +43711 2 13 43707 1 +43711 3 43698 1 0 1 +43711 4 13 40875 6 0 1 +43717 1 43712 1 +43717 2 5 43712 1 +43717 3 43712 2 0 1 +43717 4 5 25396 22 0 1 +43721 1 43718 1 +43721 2 3 43716 1 +43721 3 43718 1 0 1 +43721 4 3 24256 2 0 1 +43753 1 43746 1 +43753 2 7 43750 1 +43753 3 43746 3 0 1 +43753 4 7 34502 10 0 1 +43759 1 43756 1 +43759 2 3 43757 1 +43759 3 43756 4 0 1 +43759 4 3 31341 3 0 1 +43777 1 43772 1 +43777 2 5 43774 1 +43777 3 43772 2 0 1 +43777 4 5 33589 10 0 1 +43781 1 43779 1 +43781 2 2 43780 1 +43781 3 43779 3 0 1 +43781 4 2 28286 4 0 1 +43783 1 43780 1 +43783 2 3 43781 1 +43783 3 43780 1 0 1 +43783 4 3 26033 6 0 1 +43787 1 43785 1 +43787 2 2 43782 1 +43787 3 43785 4 0 1 +43787 4 2 29567 3 0 1 +43789 1 43783 1 +43789 2 6 43788 1 +43789 3 43783 2 0 1 +43789 4 6 26852 11 0 1 +43793 1 43790 1 +43793 2 3 43792 1 +43793 3 43790 1 0 1 +43793 4 3 22460 4 0 1 +43801 1 43770 1 +43801 2 31 43800 1 +43801 3 43770 10 0 1 +43801 4 31 38713 12 0 1 +43853 1 43851 1 +43853 2 2 43852 1 +43853 3 43851 2 0 1 +43853 4 2 33682 3 0 1 +43867 1 43864 1 +43867 2 3 43866 1 +43867 3 43864 1 0 1 +43867 4 3 40905 5 0 1 +43889 1 43886 1 +43889 2 3 43888 1 +43889 3 43886 4 0 1 +43889 4 3 35759 7 0 1 +43891 1 43888 1 +43891 2 3 43882 1 +43891 3 43888 1 0 1 +43891 4 3 27605 2 0 1 +43913 1 43910 1 +43913 2 3 43906 1 +43913 3 43910 1 0 1 +43913 4 3 40419 1 0 1 +43933 1 43931 1 +43933 2 2 43929 1 +43933 3 43931 6 0 1 +43933 4 2 28743 6 0 1 +43943 1 43938 1 +43943 2 5 43942 1 +43943 3 43938 9 0 1 +43943 4 5 26709 2 0 1 +43951 1 43945 1 +43951 2 6 43950 1 +43951 3 43945 1 0 1 +43951 4 6 37226 3 0 1 +43961 1 43955 1 +43961 2 6 43958 1 +43961 3 43955 2 0 1 +43961 4 6 41983 0 0 1 +43963 1 43951 1 +43963 2 12 43961 1 +43963 3 43951 5 0 1 +43963 4 12 31920 0 0 1 +43969 1 43958 1 +43969 2 11 43964 1 +43969 3 43958 1 0 1 +43969 4 11 36514 16 0 1 +43973 1 43971 1 +43973 2 2 43972 1 +43973 3 43971 2 0 1 +43973 4 2 39500 3 0 1 +43987 1 43985 1 +43987 2 2 43986 1 +43987 3 43985 2 0 1 +43987 4 2 25031 20 0 1 +43991 1 43974 1 +43991 2 17 43989 1 +43991 3 43974 2 0 1 +43991 4 17 25746 4 0 1 +43997 1 43995 1 +43997 2 2 43985 1 +43997 3 43995 5 0 1 +43997 4 2 43240 4 0 1 +44017 1 44006 1 +44017 2 11 44016 1 +44017 3 44006 8 0 1 +44017 4 11 27001 11 0 1 +44021 1 44019 1 +44021 2 2 44020 1 +44021 3 44019 3 0 1 +44021 4 2 25060 3 0 1 +44027 1 44025 1 +44027 2 2 44022 1 +44027 3 44025 8 0 1 +44027 4 2 43513 3 0 1 +44029 1 44023 1 +44029 2 6 44025 1 +44029 3 44023 1 0 1 +44029 4 6 44025 6 0 1 +44041 1 44030 1 +44041 2 11 44030 1 +44041 3 44030 1 0 1 +44041 4 11 40183 33 0 1 +44053 1 44051 1 +44053 2 2 44049 1 +44053 3 44051 6 0 1 +44053 4 2 34020 6 0 1 +44059 1 44057 1 +44059 2 2 44055 1 +44059 3 44057 2 0 1 +44059 4 2 41061 8 0 1 +44071 1 44068 1 +44071 2 3 44069 1 +44071 3 44068 6 0 1 +44071 4 3 38223 3 0 1 +44087 1 44082 1 +44087 2 5 44084 1 +44087 3 44082 6 0 1 +44087 4 5 35704 4 0 1 +44089 1 44076 1 +44089 2 13 44077 1 +44089 3 44076 5 0 1 +44089 4 13 37163 5 0 1 +44101 1 44095 1 +44101 2 6 44100 1 +44101 3 44095 9 0 1 +44101 4 6 27234 7 0 1 +44111 1 44104 1 +44111 2 7 44110 1 +44111 3 44104 5 0 1 +44111 4 7 34808 2 0 1 +44119 1 44113 1 +44119 2 6 44118 1 +44119 3 44113 2 0 1 +44119 4 6 24852 2 0 1 +44123 1 44121 1 +44123 2 2 44119 1 +44123 3 44121 4 0 1 +44123 4 2 27622 8 0 1 +44129 1 44126 1 +44129 2 3 44128 1 +44129 3 44126 6 0 1 +44129 4 3 25052 7 0 1 +44131 1 44129 1 +44131 2 2 44130 1 +44131 3 44129 5 0 1 +44131 4 2 44124 8 0 1 +44159 1 44148 1 +44159 2 11 44157 1 +44159 3 44148 1 0 1 +44159 4 11 24048 3 0 1 +44171 1 44169 1 +44171 2 2 44167 1 +44171 3 44169 3 0 1 +44171 4 2 28055 7 0 1 +44179 1 44177 1 +44179 2 2 44175 1 +44179 3 44177 2 0 1 +44179 4 2 22840 8 0 1 +44189 1 44187 1 +44189 2 2 44184 1 +44189 3 44187 3 0 1 +44189 4 2 24361 2 0 1 +44201 1 44195 1 +44201 2 6 44198 1 +44201 3 44195 2 0 1 +44201 4 6 29090 0 0 1 +44203 1 44198 1 +44203 2 5 44201 1 +44203 3 44198 1 0 1 +44203 4 5 30833 0 0 1 +44207 1 44202 1 +44207 2 5 44206 1 +44207 3 44202 1 0 1 +44207 4 5 42981 3 0 1 +44221 1 44219 1 +44221 2 2 44217 1 +44221 3 44219 2 0 1 +44221 4 2 32008 12 0 1 +44249 1 44246 1 +44249 2 3 44248 1 +44249 3 44246 1 0 1 +44249 4 3 30476 7 0 1 +44257 1 44252 1 +44257 2 5 44252 1 +44257 3 44252 7 0 1 +44257 4 5 23929 10 0 1 +44263 1 44260 1 +44263 2 3 44262 1 +44263 3 44260 1 0 1 +44263 4 3 41855 2 0 1 +44267 1 44265 1 +44267 2 2 44266 1 +44267 3 44265 8 0 1 +44267 4 2 29079 2 0 1 +44269 1 44267 1 +44269 2 2 44265 1 +44269 3 44267 5 0 1 +44269 4 2 31561 10 0 1 +44273 1 44270 1 +44273 2 3 44267 1 +44273 3 44270 1 0 1 +44273 4 3 34723 1 0 1 +44279 1 44272 1 +44279 2 7 44278 1 +44279 3 44272 1 0 1 +44279 4 7 43581 6 0 1 +44281 1 44274 1 +44281 2 7 44274 1 +44281 3 44274 5 0 1 +44281 4 7 35321 0 0 1 +44293 1 44291 1 +44293 2 2 44289 1 +44293 3 44291 6 0 1 +44293 4 2 32613 9 0 1 +44351 1 44332 1 +44351 2 19 44350 1 +44351 3 44332 3 0 1 +44351 4 19 27884 2 0 1 +44357 1 44355 1 +44357 2 2 44356 1 +44357 3 44355 2 0 1 +44357 4 2 33875 6 0 1 +44371 1 44369 1 +44371 2 2 44370 1 +44371 3 44369 4 0 1 +44371 4 2 33187 2 0 1 +44381 1 44379 1 +44381 2 2 44377 1 +44381 3 44379 2 0 1 +44381 4 2 22426 6 0 1 +44383 1 44380 1 +44383 2 3 44381 1 +44383 3 44380 4 0 1 +44383 4 3 38428 3 0 1 +44389 1 44387 1 +44389 2 2 44385 1 +44389 3 44387 2 0 1 +44389 4 2 30976 10 0 1 +44417 1 44414 1 +44417 2 3 44416 1 +44417 3 44414 4 0 1 +44417 4 3 22776 4 0 1 +44449 1 44436 1 +44449 2 13 44448 1 +44449 3 44436 1 0 1 +44449 4 13 43275 8 0 1 +44453 1 44451 1 +44453 2 2 44452 1 +44453 3 44451 2 0 1 +44453 4 2 32208 9 0 1 +44483 1 44481 1 +44483 2 2 44482 1 +44483 3 44481 2 0 1 +44483 4 2 44476 8 0 1 +44491 1 44478 1 +44491 2 13 44487 1 +44491 3 44478 5 0 1 +44491 4 13 44479 8 0 1 +44497 1 44492 1 +44497 2 5 44496 1 +44497 3 44492 8 0 1 +44497 4 5 40423 6 0 1 +44501 1 44499 1 +44501 2 2 44497 1 +44501 3 44499 2 0 1 +44501 4 2 40698 6 0 1 +44507 1 44505 1 +44507 2 2 44503 1 +44507 3 44505 3 0 1 +44507 4 2 23167 7 0 1 +44519 1 44506 1 +44519 2 13 44518 1 +44519 3 44506 9 0 1 +44519 4 13 36891 2 0 1 +44531 1 44529 1 +44531 2 2 44527 1 +44531 3 44529 2 0 1 +44531 4 2 25071 7 0 1 +44533 1 44531 1 +44533 2 2 44532 1 +44533 3 44531 2 0 1 +44533 4 2 40441 9 0 1 +44537 1 44534 1 +44537 2 3 44526 1 +44537 3 44534 1 0 1 +44537 4 3 34804 1 0 1 +44543 1 44538 1 +44543 2 5 44541 1 +44543 3 44538 13 0 1 +44543 4 5 30983 8 0 1 +44549 1 44547 1 +44549 2 2 44541 1 +44549 3 44547 2 0 1 +44549 4 2 26924 0 0 1 +44563 1 44560 1 +44563 2 3 44562 1 +44563 3 44560 3 0 1 +44563 4 3 29486 7 0 1 +44579 1 44577 1 +44579 2 2 44578 1 +44579 3 44577 3 0 1 +44579 4 2 32744 2 0 1 +44587 1 44584 1 +44587 2 3 44580 1 +44587 3 44584 7 0 1 +44587 4 3 42198 2 0 1 +44617 1 44612 1 +44617 2 5 44610 1 +44617 3 44612 6 0 1 +44617 4 5 36621 12 0 1 +44621 1 44619 1 +44621 2 2 44617 1 +44621 3 44619 3 0 1 +44621 4 2 25247 1 0 1 +44623 1 44618 1 +44623 2 5 44621 1 +44623 3 44618 6 0 1 +44623 4 5 38712 9 0 1 +44633 1 44630 1 +44633 2 3 44627 1 +44633 3 44630 5 0 1 +44633 4 3 25261 1 0 1 +44641 1 44622 1 +44641 2 19 44626 1 +44641 3 44622 1 0 1 +44641 4 19 29082 53 0 1 +44647 1 44642 1 +44647 2 5 44645 1 +44647 3 44642 3 0 1 +44647 4 5 44643 3 0 1 +44651 1 44649 1 +44651 2 2 44639 1 +44651 3 44649 10 0 1 +44651 4 2 29349 2 0 1 +44657 1 44654 1 +44657 2 3 44650 1 +44657 3 44654 3 0 1 +44657 4 3 35664 1 0 1 +44683 1 44681 1 +44683 2 2 44679 1 +44683 3 44681 6 0 1 +44683 4 2 39812 8 0 1 +44687 1 44682 1 +44687 2 5 44686 1 +44687 3 44682 5 0 1 +44687 4 5 22753 7 0 1 +44699 1 44697 1 +44699 2 2 44695 1 +44699 3 44697 3 0 1 +44699 4 2 22700 13 0 1 +44701 1 44699 1 +44701 2 2 44700 1 +44701 3 44699 4 0 1 +44701 4 2 33644 3 0 1 +44711 1 44704 1 +44711 2 7 44710 1 +44711 3 44704 3 0 1 +44711 4 7 32919 3 0 1 +44729 1 44726 1 +44729 2 3 44718 1 +44729 3 44726 12 0 1 +44729 4 3 33328 8 0 1 +44741 1 44739 1 +44741 2 2 44737 1 +44741 3 44739 2 0 1 +44741 4 2 24989 6 0 1 +44753 1 44750 1 +44753 2 3 44748 1 +44753 3 44750 1 0 1 +44753 4 3 40201 0 0 1 +44771 1 44765 1 +44771 2 6 44768 1 +44771 3 44765 3 0 1 +44771 4 6 37426 1 0 1 +44773 1 44768 1 +44773 2 5 44768 1 +44773 3 44768 7 0 1 +44773 4 5 31254 10 0 1 +44777 1 44774 1 +44777 2 3 44776 1 +44777 3 44774 1 0 1 +44777 4 3 35882 7 0 1 +44789 1 44787 1 +44789 2 2 44788 1 +44789 3 44787 3 0 1 +44789 4 2 25164 3 0 1 +44797 1 44795 1 +44797 2 2 44793 1 +44797 3 44795 4 0 1 +44797 4 2 38114 19 0 1 +44809 1 44798 1 +44809 2 11 44808 1 +44809 3 44798 3 0 1 +44809 4 11 42414 12 0 1 +44819 1 44817 1 +44819 2 2 44818 1 +44819 3 44817 8 0 1 +44819 4 2 39060 4 0 1 +44839 1 44833 1 +44839 2 6 44837 1 +44839 3 44833 2 0 1 +44839 4 6 23972 10 0 1 +44843 1 44838 1 +44843 2 5 44842 1 +44843 3 44838 2 0 1 +44843 4 5 40321 5 0 1 +44851 1 44841 1 +44851 2 10 44849 1 +44851 3 44841 6 0 1 +44851 4 10 44833 11 0 1 +44867 1 44865 1 +44867 2 2 44863 1 +44867 3 44865 3 0 1 +44867 4 2 29181 8 0 1 +44879 1 44872 1 +44879 2 7 44872 1 +44879 3 44872 1 0 1 +44879 4 7 35745 12 0 1 +44887 1 44882 1 +44887 2 5 44885 1 +44887 3 44882 3 0 1 +44887 4 5 22724 10 0 1 +44893 1 44888 1 +44893 2 5 44892 1 +44893 3 44888 2 0 1 +44893 4 5 35048 3 0 1 +44909 1 44907 1 +44909 2 2 44905 1 +44909 3 44907 2 0 1 +44909 4 2 41382 12 0 1 +44917 1 44912 1 +44917 2 5 44912 1 +44917 3 44912 12 0 1 +44917 4 5 36869 7 0 1 +44927 1 44920 1 +44927 2 7 44920 1 +44927 3 44920 11 0 1 +44927 4 7 24924 0 0 1 +44939 1 44937 1 +44939 2 2 44932 1 +44939 3 44937 4 0 1 +44939 4 2 36433 1 0 1 +44953 1 44948 1 +44953 2 5 44950 1 +44953 3 44948 1 0 1 +44953 4 5 23277 23 0 1 +44959 1 44956 1 +44959 2 3 44958 1 +44959 3 44956 4 0 1 +44959 4 3 31149 3 0 1 +44963 1 44961 1 +44963 2 2 44959 1 +44963 3 44961 3 0 1 +44963 4 2 26831 8 0 1 +44971 1 44968 1 +44971 2 3 44958 1 +44971 3 44968 9 0 1 +44971 4 3 24561 2 0 1 +44983 1 44980 1 +44983 2 3 44981 1 +44983 3 44980 3 0 1 +44983 4 3 37289 3 0 1 +44987 1 44985 1 +44987 2 2 44986 1 +44987 3 44985 2 0 1 +44987 4 2 37946 2 0 1 +45007 1 45004 1 +45007 2 3 45006 1 +45007 3 45004 3 0 1 +45007 4 3 39082 16 0 1 +45013 1 45011 1 +45013 2 2 45012 1 +45013 3 45011 6 0 1 +45013 4 2 44248 9 0 1 +45053 1 45051 1 +45053 2 2 45049 1 +45053 3 45051 3 0 1 +45053 4 2 28099 7 0 1 +45061 1 45059 1 +45061 2 2 45057 1 +45061 3 45059 2 0 1 +45061 4 2 37766 6 0 1 +45077 1 45075 1 +45077 2 2 45072 1 +45077 3 45075 7 0 1 +45077 4 2 42647 16 0 1 +45083 1 45081 1 +45083 2 2 45082 1 +45083 3 45081 2 0 1 +45083 4 2 36140 2 0 1 +45119 1 45112 1 +45119 2 7 45118 1 +45119 3 45112 1 0 1 +45119 4 7 43617 3 0 1 +45121 1 45114 1 +45121 2 7 45118 1 +45121 3 45114 4 0 1 +45121 4 7 31700 14 0 1 +45127 1 45115 1 +45127 2 12 45123 1 +45127 3 45115 1 0 1 +45127 4 12 41102 5 0 1 +45131 1 45129 1 +45131 2 2 45125 1 +45131 3 45129 2 0 1 +45131 4 2 28913 4 0 1 +45137 1 45134 1 +45137 2 3 45124 1 +45137 3 45134 4 0 1 +45137 4 3 40344 25 0 1 +45139 1 45137 1 +45139 2 2 45138 1 +45139 3 45137 5 0 1 +45139 4 2 30734 7 0 1 +45161 1 45158 1 +45161 2 3 45160 1 +45161 3 45158 11 0 1 +45161 4 3 34176 4 0 1 +45179 1 45173 1 +45179 2 6 45171 1 +45179 3 45173 10 0 1 +45179 4 6 41353 1 0 1 +45181 1 45179 1 +45181 2 2 45180 1 +45181 3 45179 4 0 1 +45181 4 2 45174 8 0 1 +45191 1 45180 1 +45191 2 11 45187 1 +45191 3 45180 1 0 1 +45191 4 11 27300 5 0 1 +45197 1 45195 1 +45197 2 2 45196 1 +45197 3 45195 5 0 1 +45197 4 2 31103 4 0 1 +45233 1 45230 1 +45233 2 3 45227 1 +45233 3 45230 7 0 1 +45233 4 3 30727 1 0 1 +45247 1 45242 1 +45247 2 5 45246 1 +45247 3 45242 1 0 1 +45247 4 5 38021 3 0 1 +45259 1 45256 1 +45259 2 3 45254 1 +45259 3 45256 11 0 1 +45259 4 3 41101 3 0 1 +45263 1 45258 1 +45263 2 5 45261 1 +45263 3 45258 6 0 1 +45263 4 5 45259 3 0 1 +45281 1 45278 1 +45281 2 3 45276 1 +45281 3 45278 3 0 1 +45281 4 3 44980 2 0 1 +45289 1 45275 1 +45289 2 14 45284 1 +45289 3 45275 4 0 1 +45289 4 14 34625 12 0 1 +45293 1 45291 1 +45293 2 2 45292 1 +45293 3 45291 2 0 1 +45293 4 2 29347 3 0 1 +45307 1 45305 1 +45307 2 2 45306 1 +45307 3 45305 6 0 1 +45307 4 2 45300 8 0 1 +45317 1 45315 1 +45317 2 2 45316 1 +45317 3 45315 2 0 1 +45317 4 2 27826 3 0 1 +45319 1 45316 1 +45319 2 3 45317 1 +45319 3 45316 1 0 1 +45319 4 3 45315 4 0 1 +45329 1 45326 1 +45329 2 3 45315 1 +45329 3 45326 5 0 1 +45329 4 3 26229 2 0 1 +45337 1 45332 1 +45337 2 5 45336 1 +45337 3 45332 1 0 1 +45337 4 5 32816 6 0 1 +45341 1 45339 1 +45341 2 2 45329 1 +45341 3 45339 2 0 1 +45341 4 2 42292 1 0 1 +45343 1 45337 1 +45343 2 6 45342 1 +45343 3 45337 6 0 1 +45343 4 6 34743 3 0 1 +45361 1 45350 1 +45361 2 11 45360 1 +45361 3 45350 1 0 1 +45361 4 11 44156 12 0 1 +45377 1 45374 1 +45377 2 3 45372 1 +45377 3 45374 3 0 1 +45377 4 3 37182 0 0 1 +45389 1 45387 1 +45389 2 2 45379 1 +45389 3 45387 2 0 1 +45389 4 2 30421 0 0 1 +45403 1 45400 1 +45403 2 3 45402 1 +45403 3 45400 1 0 1 +45403 4 3 27129 2 0 1 +45413 1 45411 1 +45413 2 2 45406 1 +45413 3 45411 5 0 1 +45413 4 2 42709 4 0 1 +45427 1 45424 1 +45427 2 3 45426 1 +45427 3 45424 6 0 1 +45427 4 3 23344 5 0 1 +45433 1 45426 1 +45433 2 7 45426 1 +45433 3 45426 1 0 1 +45433 4 7 26654 12 0 1 +45439 1 45436 1 +45439 2 3 45433 1 +45439 3 45436 4 0 1 +45439 4 3 36560 7 0 1 +45481 1 45468 1 +45481 2 13 45480 1 +45481 3 45468 1 0 1 +45481 4 13 35722 18 0 1 +45491 1 45489 1 +45491 2 2 45487 1 +45491 3 45489 3 0 1 +45491 4 2 35717 7 0 1 +45497 1 45494 1 +45497 2 3 45491 1 +45497 3 45494 1 0 1 +45497 4 3 33499 27 0 1 +45503 1 45498 1 +45503 2 5 45501 1 +45503 3 45498 1 0 1 +45503 4 5 45499 3 0 1 +45523 1 45521 1 +45523 2 2 45519 1 +45523 3 45521 4 0 1 +45523 4 2 30815 8 0 1 +45533 1 45531 1 +45533 2 2 45532 1 +45533 3 45531 4 0 1 +45533 4 2 41057 9 0 1 +45541 1 45531 1 +45541 2 10 45540 1 +45541 3 45531 3 0 1 +45541 4 10 26200 14 0 1 +45553 1 45548 1 +45553 2 5 45552 1 +45553 3 45548 3 0 1 +45553 4 5 44878 6 0 1 +45557 1 45554 1 +45557 2 3 45556 1 +45557 3 45554 3 0 1 +45557 4 3 44882 6 0 1 +45569 1 45566 1 +45569 2 3 45568 1 +45569 3 45566 1 0 1 +45569 4 3 40897 4 0 1 +45587 1 45585 1 +45587 2 2 45586 1 +45587 3 45585 10 0 1 +45587 4 2 31949 13 0 1 +45589 1 45587 1 +45589 2 2 45588 1 +45589 3 45587 5 0 1 +45589 4 2 28142 9 0 1 +45599 1 45592 1 +45599 2 7 45595 1 +45599 3 45592 4 0 1 +45599 4 7 44995 6 0 1 +45613 1 45611 1 +45613 2 2 45609 1 +45613 3 45611 6 0 1 +45613 4 2 29096 12 0 1 +45631 1 45619 1 +45631 2 12 45630 1 +45631 3 45619 3 0 1 +45631 4 12 26884 2 0 1 +45641 1 45630 1 +45641 2 11 45632 1 +45641 3 45630 1 0 1 +45641 4 11 36166 15 0 1 +45659 1 45657 1 +45659 2 2 45650 1 +45659 3 45657 5 0 1 +45659 4 2 41259 1 0 1 +45667 1 45665 1 +45667 2 2 45663 1 +45667 3 45665 2 0 1 +45667 4 2 29332 11 0 1 +45673 1 45668 1 +45673 2 5 45668 1 +45673 3 45668 5 0 1 +45673 4 5 32101 10 0 1 +45677 1 45675 1 +45677 2 2 45673 1 +45677 3 45675 3 0 1 +45677 4 2 37666 12 0 1 +45691 1 45684 1 +45691 2 7 45689 1 +45691 3 45684 5 0 1 +45691 4 7 25859 6 0 1 +45697 1 45687 1 +45697 2 10 45696 1 +45697 3 45687 6 0 1 +45697 4 10 38298 6 0 1 +45707 1 45705 1 +45707 2 2 45702 1 +45707 3 45705 5 0 1 +45707 4 2 25083 3 0 1 +45737 1 45734 1 +45737 2 3 45730 1 +45737 3 45734 5 0 1 +45737 4 3 38513 0 0 1 +45751 1 45748 1 +45751 2 3 45750 1 +45751 3 45748 4 0 1 +45751 4 3 30312 2 0 1 +45757 1 45755 1 +45757 2 2 45756 1 +45757 3 45755 6 0 1 +45757 4 2 40134 7 0 1 +45763 1 45758 1 +45763 2 5 45761 1 +45763 3 45758 6 0 1 +45763 4 5 45755 6 0 1 +45767 1 45762 1 +45767 2 5 45766 1 +45767 3 45762 2 0 1 +45767 4 5 26371 5 0 1 +45779 1 45777 1 +45779 2 2 45767 1 +45779 3 45777 4 0 1 +45779 4 2 24414 6 0 1 +45817 1 45812 1 +45817 2 5 45816 1 +45817 3 45812 7 0 1 +45817 4 5 43698 6 0 1 +45821 1 45819 1 +45821 2 2 45817 1 +45821 3 45819 3 0 1 +45821 4 2 27262 1 0 1 +45823 1 45820 1 +45823 2 3 45822 1 +45823 3 45820 1 0 1 +45823 4 3 30323 2 0 1 +45827 1 45825 1 +45827 2 2 45826 1 +45827 3 45825 3 0 1 +45827 4 2 40257 4 0 1 +45833 1 45828 1 +45833 2 5 45825 1 +45833 3 45828 5 0 1 +45833 4 5 44852 11 0 1 +45841 1 45834 1 +45841 2 7 45838 1 +45841 3 45834 3 0 1 +45841 4 7 31158 17 0 1 +45853 1 45848 1 +45853 2 5 45848 1 +45853 3 45848 1 0 1 +45853 4 5 27311 11 0 1 +45863 1 45853 1 +45863 2 10 45862 1 +45863 3 45853 2 0 1 +45863 4 10 24212 3 0 1 +45869 1 45867 1 +45869 2 2 45868 1 +45869 3 45867 4 0 1 +45869 4 2 26797 3 0 1 +45887 1 45882 1 +45887 2 5 45886 1 +45887 3 45882 9 0 1 +45887 4 5 39288 3 0 1 +45893 1 45891 1 +45893 2 2 45889 1 +45893 3 45891 3 0 1 +45893 4 2 39520 26 0 1 +45943 1 45937 1 +45943 2 6 45940 1 +45943 3 45937 6 0 1 +45943 4 6 30371 5 0 1 +45949 1 45947 1 +45949 2 2 45945 1 +45949 3 45947 2 0 1 +45949 4 2 33945 10 0 1 +45953 1 45950 1 +45953 2 3 45952 1 +45953 3 45950 9 0 1 +45953 4 3 37935 8 0 1 +45959 1 45952 1 +45959 2 7 45958 1 +45959 3 45952 3 0 1 +45959 4 7 32873 7 0 1 +45971 1 45969 1 +45971 2 2 45967 1 +45971 3 45969 2 0 1 +45971 4 2 44216 8 0 1 +45979 1 45977 1 +45979 2 2 45978 1 +45979 3 45977 5 0 1 +45979 4 2 28690 7 0 1 +45989 1 45987 1 +45989 2 2 45988 1 +45989 3 45987 3 0 1 +45989 4 2 35560 9 0 1 +46021 1 46019 1 +46021 2 2 46020 1 +46021 3 46019 6 0 1 +46021 4 2 31211 3 0 1 +46027 1 46025 1 +46027 2 2 46023 1 +46027 3 46025 6 0 1 +46027 4 2 30373 8 0 1 +46049 1 46046 1 +46049 2 3 46038 1 +46049 3 46046 5 0 1 +46049 4 3 26786 8 0 1 +46051 1 46048 1 +46051 2 3 46046 1 +46051 3 46048 1 0 1 +46051 4 3 25364 3 0 1 +46061 1 46059 1 +46061 2 2 46057 1 +46061 3 46059 2 0 1 +46061 4 2 38464 7 0 1 +46073 1 46068 1 +46073 2 5 46068 1 +46073 3 46068 6 0 1 +46073 4 5 33248 2 0 1 +46091 1 46089 1 +46091 2 2 46087 1 +46091 3 46089 3 0 1 +46091 4 2 38291 19 0 1 +46093 1 46091 1 +46093 2 2 46092 1 +46093 3 46091 2 0 1 +46093 4 2 32682 6 0 1 +46099 1 46097 1 +46099 2 2 46095 1 +46099 3 46097 4 0 1 +46099 4 2 39615 8 0 1 +46103 1 46093 1 +46103 2 10 46101 1 +46103 3 46093 4 0 1 +46103 4 10 46085 11 0 1 +46133 1 46131 1 +46133 2 2 46132 1 +46133 3 46131 9 0 1 +46133 4 2 28930 3 0 1 +46141 1 46131 1 +46141 2 10 46138 1 +46141 3 46131 11 0 1 +46141 4 10 39758 9 0 1 +46147 1 46145 1 +46147 2 2 46146 1 +46147 3 46145 5 0 1 +46147 4 2 25219 2 0 1 +46153 1 46148 1 +46153 2 5 46152 1 +46153 3 46148 7 0 1 +46153 4 5 35048 12 0 1 +46171 1 46168 1 +46171 2 3 46166 1 +46171 3 46168 4 0 1 +46171 4 3 27178 3 0 1 +46181 1 46179 1 +46181 2 2 46177 1 +46181 3 46179 3 0 1 +46181 4 2 35131 12 0 1 +46183 1 46180 1 +46183 2 3 46181 1 +46183 3 46180 8 0 1 +46183 4 3 46179 4 0 1 +46187 1 46185 1 +46187 2 2 46177 1 +46187 3 46185 8 0 1 +46187 4 2 36061 2 0 1 +46199 1 46182 1 +46199 2 17 46197 1 +46199 3 46182 7 0 1 +46199 4 17 46191 3 0 1 +46219 1 46216 1 +46219 2 3 46218 1 +46219 3 46216 1 0 1 +46219 4 3 43375 2 0 1 +46229 1 46227 1 +46229 2 2 46224 1 +46229 3 46227 2 0 1 +46229 4 2 44536 2 0 1 +46237 1 46235 1 +46237 2 2 46233 1 +46237 3 46235 4 0 1 +46237 4 2 41915 12 0 1 +46261 1 46259 1 +46261 2 2 46260 1 +46261 3 46259 5 0 1 +46261 4 2 23371 3 0 1 +46271 1 46264 1 +46271 2 7 46269 1 +46271 3 46264 3 0 1 +46271 4 7 38257 4 0 1 +46273 1 46268 1 +46273 2 5 46272 1 +46273 3 46268 5 0 1 +46273 4 5 34133 6 0 1 +46279 1 46276 1 +46279 2 3 46278 1 +46279 3 46276 3 0 1 +46279 4 3 39624 3 0 1 +46301 1 46299 1 +46301 2 2 46297 1 +46301 3 46299 3 0 1 +46301 4 2 29134 1 0 1 +46307 1 46305 1 +46307 2 2 46303 1 +46307 3 46305 9 0 1 +46307 4 2 28139 13 0 1 +46309 1 46307 1 +46309 2 2 46305 1 +46309 3 46307 4 0 1 +46309 4 2 25582 12 0 1 +46327 1 46324 1 +46327 2 3 46326 1 +46327 3 46324 8 0 1 +46327 4 3 32791 2 0 1 +46337 1 46334 1 +46337 2 3 46332 1 +46337 3 46334 1 0 1 +46337 4 3 44575 0 0 1 +46349 1 46347 1 +46349 2 2 46342 1 +46349 3 46347 5 0 1 +46349 4 2 42092 17 0 1 +46351 1 46348 1 +46351 2 3 46350 1 +46351 3 46348 6 0 1 +46351 4 3 39860 3 0 1 +46381 1 46374 1 +46381 2 7 46378 1 +46381 3 46374 2 0 1 +46381 4 7 35780 5 0 1 +46399 1 46396 1 +46399 2 3 46397 1 +46399 3 46396 4 0 1 +46399 4 3 46395 4 0 1 +46411 1 46408 1 +46411 2 3 46410 1 +46411 3 46408 4 0 1 +46411 4 3 39497 7 0 1 +46439 1 46432 1 +46439 2 7 46437 1 +46439 3 46432 1 0 1 +46439 4 7 42373 5 0 1 +46441 1 46434 1 +46441 2 7 46434 1 +46441 3 46434 2 0 1 +46441 4 7 27654 18 0 1 +46447 1 46444 1 +46447 2 3 46445 1 +46447 3 46444 5 0 1 +46447 4 3 46443 4 0 1 +46451 1 46445 1 +46451 2 6 46449 1 +46451 3 46445 2 0 1 +46451 4 6 41734 5 0 1 +46457 1 46454 1 +46457 2 3 46452 1 +46457 3 46454 1 0 1 +46457 4 3 43174 0 0 1 +46471 1 46468 1 +46471 2 3 46470 1 +46471 3 46468 1 0 1 +46471 4 3 41420 3 0 1 +46477 1 46475 1 +46477 2 2 46473 1 +46477 3 46475 5 0 1 +46477 4 2 26312 10 0 1 +46489 1 46460 1 +46489 2 29 46486 1 +46489 3 46460 3 0 1 +46489 4 29 44904 20 0 1 +46499 1 46497 1 +46499 2 2 46495 1 +46499 3 46497 3 0 1 +46499 4 2 24692 7 0 1 +46507 1 46505 1 +46507 2 2 46503 1 +46507 3 46505 2 0 1 +46507 4 2 30550 1 0 1 +46511 1 46500 1 +46511 2 11 46507 1 +46511 3 46500 2 0 1 +46511 4 11 45147 6 0 1 +46523 1 46518 1 +46523 2 5 46521 1 +46523 3 46518 6 0 1 +46523 4 5 43829 5 0 1 +46549 1 46547 1 +46549 2 2 46545 1 +46549 3 46547 5 0 1 +46549 4 2 36157 6 0 1 +46559 1 46552 1 +46559 2 7 46558 1 +46559 3 46552 9 0 1 +46559 4 7 24905 2 0 1 +46567 1 46564 1 +46567 2 3 46565 1 +46567 3 46564 1 0 1 +46567 4 3 30664 6 0 1 +46573 1 46571 1 +46573 2 2 46569 1 +46573 3 46571 9 0 1 +46573 4 2 42450 6 0 1 +46589 1 46587 1 +46589 2 2 46582 1 +46589 3 46587 2 0 1 +46589 4 2 42838 4 0 1 +46591 1 46585 1 +46591 2 6 46587 1 +46591 3 46585 2 0 1 +46591 4 6 23581 1 0 1 +46601 1 46598 1 +46601 2 3 46594 1 +46601 3 46598 5 0 1 +46601 4 3 37174 1 0 1 +46619 1 46613 1 +46619 2 6 46617 1 +46619 3 46613 3 0 1 +46619 4 6 44101 9 0 1 +46633 1 46628 1 +46633 2 5 46628 1 +46633 3 46628 3 0 1 +46633 4 5 41892 10 0 1 +46639 1 46633 1 +46639 2 6 46637 1 +46639 3 46633 3 0 1 +46639 4 6 34453 3 0 1 +46643 1 46641 1 +46643 2 2 46637 1 +46643 3 46641 4 0 1 +46643 4 2 37192 4 0 1 +46649 1 46634 1 +46649 2 15 46648 1 +46649 3 46634 1 0 1 +46649 4 15 26508 4 0 1 +46663 1 46658 1 +46663 2 5 46662 1 +46663 3 46658 1 0 1 +46663 4 5 38255 2 0 1 +46679 1 46662 1 +46679 2 17 46677 1 +46679 3 46662 3 0 1 +46679 4 17 45842 8 0 1 +46681 1 46670 1 +46681 2 11 46680 1 +46681 3 46670 2 0 1 +46681 4 11 38568 14 0 1 +46687 1 46684 1 +46687 2 3 46685 1 +46687 3 46684 1 0 1 +46687 4 3 46683 4 0 1 +46691 1 46689 1 +46691 2 2 46687 1 +46691 3 46689 3 0 1 +46691 4 2 39580 8 0 1 +46703 1 46698 1 +46703 2 5 46700 1 +46703 3 46698 1 0 1 +46703 4 5 25022 9 0 1 +46723 1 46721 1 +46723 2 2 46722 1 +46723 3 46721 2 0 1 +46723 4 2 40260 2 0 1 +46727 1 46722 1 +46727 2 5 46725 1 +46727 3 46722 2 0 1 +46727 4 5 46715 11 0 1 +46747 1 46745 1 +46747 2 2 46743 1 +46747 3 46745 6 0 1 +46747 4 2 23732 8 0 1 +46751 1 46740 1 +46751 2 11 46749 1 +46751 3 46740 1 0 1 +46751 4 11 38211 3 0 1 +46757 1 46755 1 +46757 2 2 46753 1 +46757 3 46755 3 0 1 +46757 4 2 33210 6 0 1 +46769 1 46766 1 +46769 2 3 46763 1 +46769 3 46766 1 0 1 +46769 4 3 46757 0 0 1 +46771 1 46769 1 +46771 2 2 46767 1 +46771 3 46769 2 0 1 +46771 4 2 33203 8 0 1 +46807 1 46804 1 +46807 2 3 46806 1 +46807 3 46804 1 0 1 +46807 4 3 24365 5 0 1 +46811 1 46809 1 +46811 2 2 46805 1 +46811 3 46809 2 0 1 +46811 4 2 41529 0 0 1 +46817 1 46814 1 +46817 2 3 46811 1 +46817 3 46814 1 0 1 +46817 4 3 41548 11 0 1 +46819 1 46817 1 +46819 2 2 46812 1 +46819 3 46817 6 0 1 +46819 4 2 24486 5 0 1 +46829 1 46827 1 +46829 2 2 46828 1 +46829 3 46827 3 0 1 +46829 4 2 29540 3 0 1 +46831 1 46828 1 +46831 2 3 46829 1 +46831 3 46828 4 0 1 +46831 4 3 29341 3 0 1 +46853 1 46851 1 +46853 2 2 46845 1 +46853 3 46851 7 0 1 +46853 4 2 25849 5 0 1 +46861 1 46855 1 +46861 2 6 46860 1 +46861 3 46855 7 0 1 +46861 4 6 35569 22 0 1 +46867 1 46865 1 +46867 2 2 46863 1 +46867 3 46865 5 0 1 +46867 4 2 26956 8 0 1 +46877 1 46875 1 +46877 2 2 46873 1 +46877 3 46875 2 0 1 +46877 4 2 34515 1 0 1 +46889 1 46886 1 +46889 2 3 46884 1 +46889 3 46886 3 0 1 +46889 4 3 33650 2 0 1 +46901 1 46890 1 +46901 2 11 46899 1 +46901 3 46890 4 0 1 +46901 4 11 26924 0 0 1 +46919 1 46908 1 +46919 2 11 46917 1 +46919 3 46908 1 0 1 +46919 4 11 37138 5 0 1 +46933 1 46931 1 +46933 2 2 46932 1 +46933 3 46931 2 0 1 +46933 4 2 36682 3 0 1 +46957 1 46952 1 +46957 2 5 46956 1 +46957 3 46952 1 0 1 +46957 4 5 37504 3 0 1 +46993 1 46988 1 +46993 2 5 46988 1 +46993 3 46988 6 0 1 +46993 4 5 32806 15 0 1 +46997 1 46995 1 +46997 2 2 46996 1 +46997 3 46995 2 0 1 +46997 4 2 40850 4 0 1 +47017 1 47010 1 +47017 2 7 47010 1 +47017 3 47010 3 0 1 +47017 4 7 31573 12 0 1 +47041 1 47012 1 +47041 2 29 47038 1 +47041 3 47012 2 0 1 +47041 4 29 26628 16 0 1 +47051 1 47049 1 +47051 2 2 47046 1 +47051 3 47049 2 0 1 +47051 4 2 40653 3 0 1 +47057 1 47054 1 +47057 2 3 47056 1 +47057 3 47054 4 0 1 +47057 4 3 35069 7 0 1 +47059 1 47057 1 +47059 2 2 47058 1 +47059 3 47057 6 0 1 +47059 4 2 31564 2 0 1 +47087 1 47082 1 +47087 2 5 47085 1 +47087 3 47082 6 0 1 +47087 4 5 47083 3 0 1 +47093 1 47091 1 +47093 2 2 47089 1 +47093 3 47091 3 0 1 +47093 4 2 46659 6 0 1 +47111 1 47104 1 +47111 2 7 47107 1 +47111 3 47104 2 0 1 +47111 4 7 46497 13 0 1 +47119 1 47116 1 +47119 2 3 47117 1 +47119 3 47116 1 0 1 +47119 4 3 45329 3 0 1 +47123 1 47121 1 +47123 2 2 47119 1 +47123 3 47121 2 0 1 +47123 4 2 30269 20 0 1 +47129 1 47126 1 +47129 2 3 47117 1 +47129 3 47126 1 0 1 +47129 4 3 37567 0 0 1 +47137 1 47132 1 +47137 2 5 47134 1 +47137 3 47132 1 0 1 +47137 4 5 41132 23 0 1 +47143 1 47137 1 +47143 2 6 47140 1 +47143 3 47137 1 0 1 +47143 4 6 36780 4 0 1 +47147 1 47145 1 +47147 2 2 47143 1 +47147 3 47145 3 0 1 +47147 4 2 30463 8 0 1 +47149 1 47147 1 +47149 2 2 47141 1 +47149 3 47147 2 0 1 +47149 4 2 43332 0 0 1 +47161 1 47144 1 +47161 2 17 47156 1 +47161 3 47144 2 0 1 +47161 4 17 26737 22 0 1 +47189 1 47187 1 +47189 2 2 47181 1 +47189 3 47187 2 0 1 +47189 4 2 45094 0 0 1 +47207 1 47202 1 +47207 2 5 47204 1 +47207 3 47202 2 0 1 +47207 4 5 35549 4 0 1 +47221 1 47215 1 +47221 2 6 47217 1 +47221 3 47215 7 0 1 +47221 4 6 40587 2 0 1 +47237 1 47235 1 +47237 2 2 47233 1 +47237 3 47235 3 0 1 +47237 4 2 44006 6 0 1 +47251 1 47241 1 +47251 2 10 47249 1 +47251 3 47241 5 0 1 +47251 4 10 31356 0 0 1 +47269 1 47263 1 +47269 2 6 47261 1 +47269 3 47263 2 0 1 +47269 4 6 34884 0 0 1 +47279 1 47272 1 +47279 2 7 47277 1 +47279 3 47272 2 0 1 +47279 4 7 31867 4 0 1 +47287 1 47282 1 +47287 2 5 47286 1 +47287 3 47282 1 0 1 +47287 4 5 30338 5 0 1 +47293 1 47287 1 +47293 2 6 47292 1 +47293 3 47287 2 0 1 +47293 4 6 29331 27 0 1 +47297 1 47294 1 +47297 2 3 47291 1 +47297 3 47294 1 0 1 +47297 4 3 31326 1 0 1 +47303 1 47298 1 +47303 2 5 47302 1 +47303 3 47298 1 0 1 +47303 4 5 24970 4 0 1 +47309 1 47307 1 +47309 2 2 47300 1 +47309 3 47307 5 0 1 +47309 4 2 36347 1 0 1 +47317 1 47311 1 +47317 2 6 47315 1 +47317 3 47311 4 0 1 +47317 4 6 36456 4 0 1 +47339 1 47337 1 +47339 2 2 47338 1 +47339 3 47337 4 0 1 +47339 4 2 47332 8 0 1 +47351 1 47338 1 +47351 2 13 47349 1 +47351 3 47338 1 0 1 +47351 4 13 24355 3 0 1 +47353 1 47348 1 +47353 2 5 47348 1 +47353 3 47348 1 0 1 +47353 4 5 42696 10 0 1 +47363 1 47361 1 +47363 2 2 47359 1 +47363 3 47361 3 0 1 +47363 4 2 36657 7 0 1 +47381 1 47379 1 +47381 2 2 47380 1 +47381 3 47379 5 0 1 +47381 4 2 29852 9 0 1 +47387 1 47385 1 +47387 2 2 47383 1 +47387 3 47385 3 0 1 +47387 4 2 47010 8 0 1 +47389 1 47387 1 +47389 2 2 47388 1 +47389 3 47387 5 0 1 +47389 4 2 23938 9 0 1 +47407 1 47404 1 +47407 2 3 47406 1 +47407 3 47404 3 0 1 +47407 4 3 41033 8 0 1 +47417 1 47414 1 +47417 2 3 47416 1 +47417 3 47414 1 0 1 +47417 4 3 30547 7 0 1 +47419 1 47417 1 +47419 2 2 47415 1 +47419 3 47417 6 0 1 +47419 4 2 23898 8 0 1 +47431 1 47419 1 +47431 2 12 47428 1 +47431 3 47419 6 0 1 +47431 4 12 36693 0 0 1 +47441 1 47438 1 +47441 2 3 47435 1 +47441 3 47438 1 0 1 +47441 4 3 47429 0 0 1 +47459 1 47457 1 +47459 2 2 47458 1 +47459 3 47457 15 0 1 +47459 4 2 24336 6 0 1 +47491 1 47489 1 +47491 2 2 47490 1 +47491 3 47489 5 0 1 +47491 4 2 44244 2 0 1 +47497 1 47492 1 +47497 2 5 47494 1 +47497 3 47492 1 0 1 +47497 4 5 26516 18 0 1 +47501 1 47498 1 +47501 2 3 47499 1 +47501 3 47498 4 0 1 +47501 4 3 47497 4 0 1 +47507 1 47505 1 +47507 2 2 47503 1 +47507 3 47505 2 0 1 +47507 4 2 38252 16 0 1 +47513 1 47510 1 +47513 2 3 47508 1 +47513 3 47510 3 0 1 +47513 4 3 31881 0 0 1 +47521 1 47504 1 +47521 2 17 47520 1 +47521 3 47504 3 0 1 +47521 4 17 29097 20 0 1 +47527 1 47524 1 +47527 2 3 47526 1 +47527 3 47524 3 0 1 +47527 4 3 35241 5 0 1 +47533 1 47531 1 +47533 2 2 47532 1 +47533 3 47531 2 0 1 +47533 4 2 34111 3 0 1 +47543 1 47538 1 +47543 2 5 47535 1 +47543 3 47538 1 0 1 +47543 4 5 24194 3 0 1 +47563 1 47561 1 +47563 2 2 47562 1 +47563 3 47561 2 0 1 +47563 4 2 30316 2 0 1 +47569 1 47552 1 +47569 2 17 47568 1 +47569 3 47552 6 0 1 +47569 4 17 44979 14 0 1 +47581 1 47579 1 +47581 2 2 47577 1 +47581 3 47579 2 0 1 +47581 4 2 29004 12 0 1 +47591 1 47580 1 +47591 2 11 47590 1 +47591 3 47580 8 0 1 +47591 4 11 25303 3 0 1 +47599 1 47596 1 +47599 2 3 47598 1 +47599 3 47596 4 0 1 +47599 4 3 42246 2 0 1 +47609 1 47603 1 +47609 2 6 47608 1 +47609 3 47603 4 0 1 +47609 4 6 42600 7 0 1 +47623 1 47620 1 +47623 2 3 47621 1 +47623 3 47620 1 0 1 +47623 4 3 47619 4 0 1 +47629 1 47619 1 +47629 2 10 47626 1 +47629 3 47619 2 0 1 +47629 4 10 36643 13 0 1 +47639 1 47632 1 +47639 2 7 47638 1 +47639 3 47632 8 0 1 +47639 4 7 26912 2 0 1 +47653 1 47640 1 +47653 2 13 47642 1 +47653 3 47640 3 0 1 +47653 4 13 40519 3 0 1 +47657 1 47654 1 +47657 2 3 47651 1 +47657 3 47654 1 0 1 +47657 4 3 28471 9 0 1 +47659 1 47657 1 +47659 2 2 47658 1 +47659 3 47657 6 0 1 +47659 4 2 29906 7 0 1 +47681 1 47678 1 +47681 2 3 47680 1 +47681 3 47678 11 0 1 +47681 4 3 26764 4 0 1 +47699 1 47697 1 +47699 2 2 47694 1 +47699 3 47697 2 0 1 +47699 4 2 35869 3 0 1 +47701 1 47699 1 +47701 2 2 47700 1 +47701 3 47699 6 0 1 +47701 4 2 40941 7 0 1 +47711 1 47700 1 +47711 2 11 47709 1 +47711 3 47700 2 0 1 +47711 4 11 28539 3 0 1 +47713 1 47703 1 +47713 2 10 47708 1 +47713 3 47703 4 0 1 +47713 4 10 31546 10 0 1 +47717 1 47715 1 +47717 2 2 47716 1 +47717 3 47715 2 0 1 +47717 4 2 43442 3 0 1 +47737 1 47732 1 +47737 2 5 47734 1 +47737 3 47732 2 0 1 +47737 4 5 37040 23 0 1 +47741 1 47738 1 +47741 2 3 47733 1 +47741 3 47738 1 0 1 +47741 4 3 28355 11 0 1 +47743 1 47740 1 +47743 2 3 47741 1 +47743 3 47740 1 0 1 +47743 4 3 47739 4 0 1 +47777 1 47774 1 +47777 2 3 47769 1 +47777 3 47774 3 0 1 +47777 4 3 46327 2 0 1 +47779 1 47776 1 +47779 2 3 47778 1 +47779 3 47776 3 0 1 +47779 4 3 44214 2 0 1 +47791 1 47784 1 +47791 2 7 47778 1 +47791 3 47784 3 0 1 +47791 4 7 25128 1 0 1 +47797 1 47792 1 +47797 2 5 47796 1 +47797 3 47792 2 0 1 +47797 4 5 38175 6 0 1 +47807 1 47802 1 +47807 2 5 47806 1 +47807 3 47802 5 0 1 +47807 4 5 32752 3 0 1 +47809 1 47802 1 +47809 2 7 47800 1 +47809 3 47802 4 0 1 +47809 4 7 36600 16 0 1 +47819 1 47817 1 +47819 2 2 47813 1 +47819 3 47817 2 0 1 +47819 4 2 29004 0 0 1 +47837 1 47835 1 +47837 2 2 47831 1 +47837 3 47835 2 0 1 +47837 4 2 26959 1 0 1 +47843 1 47841 1 +47843 2 2 47842 1 +47843 3 47841 2 0 1 +47843 4 2 35977 2 0 1 +47857 1 47850 1 +47857 2 7 47854 1 +47857 3 47850 2 0 1 +47857 4 7 24323 8 0 1 +47869 1 47867 1 +47869 2 2 47868 1 +47869 3 47867 6 0 1 +47869 4 2 36099 3 0 1 +47881 1 47852 1 +47881 2 29 47876 1 +47881 3 47852 2 0 1 +47881 4 29 46952 18 0 1 +47903 1 47896 1 +47903 2 7 47902 1 +47903 3 47896 2 0 1 +47903 4 7 36964 2 0 1 +47911 1 47908 1 +47911 2 3 47910 1 +47911 3 47908 1 0 1 +47911 4 3 44831 3 0 1 +47917 1 47912 1 +47917 2 5 47916 1 +47917 3 47912 2 0 1 +47917 4 5 41117 6 0 1 +47933 1 47931 1 +47933 2 2 47929 1 +47933 3 47931 3 0 1 +47933 4 2 46754 6 0 1 +47939 1 47937 1 +47939 2 2 47938 1 +47939 3 47937 3 0 1 +47939 4 2 38673 2 0 1 +47947 1 47945 1 +47947 2 2 47943 1 +47947 3 47945 5 0 1 +47947 4 2 38585 13 0 1 +47951 1 47944 1 +47951 2 7 47949 1 +47951 3 47944 5 0 1 +47951 4 7 35366 5 0 1 +47963 1 47961 1 +47963 2 2 47962 1 +47963 3 47961 2 0 1 +47963 4 2 28626 4 0 1 +47969 1 47966 1 +47969 2 3 47963 1 +47969 3 47966 5 0 1 +47969 4 3 47957 0 0 1 +47977 1 47970 1 +47977 2 7 47970 1 +47977 3 47970 1 0 1 +47977 4 7 35515 12 0 1 +47981 1 47979 1 +47981 2 2 47974 1 +47981 3 47979 3 0 1 +47981 4 2 27256 14 0 1 +48017 1 48014 1 +48017 2 3 48016 1 +48017 3 48014 3 0 1 +48017 4 3 39230 4 0 1 +48023 1 48018 1 +48023 2 5 48006 1 +48023 3 48018 5 0 1 +48023 4 5 39800 12 0 1 +48029 1 48027 1 +48029 2 2 48021 1 +48029 3 48027 11 0 1 +48029 4 2 40222 0 0 1 +48049 1 48032 1 +48049 2 17 48046 1 +48049 3 48032 1 0 1 +48049 4 17 30905 20 0 1 +48073 1 48068 1 +48073 2 5 48072 1 +48073 3 48068 3 0 1 +48073 4 5 31604 6 0 1 +48079 1 48073 1 +48079 2 6 48077 1 +48079 3 48073 3 0 1 +48079 4 6 31403 4 0 1 +48091 1 48084 1 +48091 2 7 48089 1 +48091 3 48084 1 0 1 +48091 4 7 30351 6 0 1 +48109 1 48107 1 +48109 2 2 48105 1 +48109 3 48107 6 0 1 +48109 4 2 41128 11 0 1 +48119 1 48112 1 +48119 2 7 48117 1 +48119 3 48112 3 0 1 +48119 4 7 41509 4 0 1 +48121 1 48108 1 +48121 2 13 48120 1 +48121 3 48108 8 0 1 +48121 4 13 28355 8 0 1 +48131 1 48125 1 +48131 2 6 48129 1 +48131 3 48125 3 0 1 +48131 4 6 38135 5 0 1 +48157 1 48152 1 +48157 2 5 48154 1 +48157 3 48152 2 0 1 +48157 4 5 41490 1 0 1 +48163 1 48160 1 +48163 2 3 48158 1 +48163 3 48160 8 0 1 +48163 4 3 34731 3 0 1 +48179 1 48173 1 +48179 2 6 48177 1 +48179 3 48173 3 0 1 +48179 4 6 44807 9 0 1 +48187 1 48185 1 +48187 2 2 48186 1 +48187 3 48185 6 0 1 +48187 4 2 40059 2 0 1 +48193 1 48186 1 +48193 2 7 48186 1 +48193 3 48186 1 0 1 +48193 4 7 30606 12 0 1 +48197 1 48195 1 +48197 2 2 48193 1 +48197 3 48195 3 0 1 +48197 4 2 34515 7 0 1 +48221 1 48219 1 +48221 2 2 48215 1 +48221 3 48219 9 0 1 +48221 4 2 47059 4 0 1 +48239 1 48232 1 +48239 2 7 48232 1 +48239 3 48232 2 0 1 +48239 4 7 33840 8 0 1 +48247 1 48244 1 +48247 2 3 48245 1 +48247 3 48244 1 0 1 +48247 4 3 32980 6 0 1 +48259 1 48257 1 +48259 2 2 48255 1 +48259 3 48257 2 0 1 +48259 4 2 38080 8 0 1 +48271 1 48265 1 +48271 2 6 48270 1 +48271 3 48265 2 0 1 +48271 4 6 40466 2 0 1 +48281 1 48278 1 +48281 2 3 48280 1 +48281 3 48278 12 0 1 +48281 4 3 43232 4 0 1 +48299 1 48297 1 +48299 2 2 48295 1 +48299 3 48297 3 0 1 +48299 4 2 42653 7 0 1 +48311 1 48304 1 +48311 2 7 48310 1 +48311 3 48304 1 0 1 +48311 4 7 48302 4 0 1 +48313 1 48308 1 +48313 2 5 48312 1 +48313 3 48308 1 0 1 +48313 4 5 48002 6 0 1 +48337 1 48327 1 +48337 2 10 48332 1 +48337 3 48327 3 0 1 +48337 4 10 34674 10 0 1 +48341 1 48338 1 +48341 2 3 48340 1 +48341 3 48338 3 0 1 +48341 4 3 29790 3 0 1 +48353 1 48350 1 +48353 2 3 48352 1 +48353 3 48350 3 0 1 +48353 4 3 25766 7 0 1 +48371 1 48369 1 +48371 2 2 48366 1 +48371 3 48369 7 0 1 +48371 4 2 33067 3 0 1 +48383 1 48378 1 +48383 2 5 48381 1 +48383 3 48378 7 0 1 +48383 4 5 48379 3 0 1 +48397 1 48392 1 +48397 2 5 48394 1 +48397 3 48392 2 0 1 +48397 4 5 39035 10 0 1 +48407 1 48402 1 +48407 2 5 48406 1 +48407 3 48402 1 0 1 +48407 4 5 26131 2 0 1 +48409 1 48392 1 +48409 2 17 48398 1 +48409 3 48392 1 0 1 +48409 4 17 39919 28 0 1 +48413 1 48411 1 +48413 2 2 48409 1 +48413 3 48411 3 0 1 +48413 4 2 46445 6 0 1 +48437 1 48435 1 +48437 2 2 48433 1 +48437 3 48435 7 0 1 +48437 4 2 29367 16 0 1 +48449 1 48446 1 +48449 2 3 48444 1 +48449 3 48446 3 0 1 +48449 4 3 46270 2 0 1 +48463 1 48458 1 +48463 2 5 48462 1 +48463 3 48458 5 0 1 +48463 4 5 44000 5 0 1 +48473 1 48470 1 +48473 2 3 48472 1 +48473 3 48470 7 0 1 +48473 4 3 42834 4 0 1 +48479 1 48472 1 +48479 2 7 48478 1 +48479 3 48472 9 0 1 +48479 4 7 29312 2 0 1 +48481 1 48464 1 +48481 2 17 48478 1 +48481 3 48464 2 0 1 +48481 4 17 33727 17 0 1 +48487 1 48482 1 +48487 2 5 48486 1 +48487 3 48482 1 0 1 +48487 4 5 47077 8 0 1 +48491 1 48489 1 +48491 2 2 48487 1 +48491 3 48489 3 0 1 +48491 4 2 34981 7 0 1 +48497 1 48494 1 +48497 2 3 48492 1 +48497 3 48494 3 0 1 +48497 4 3 44812 0 0 1 +48523 1 48520 1 +48523 2 3 48522 1 +48523 3 48520 4 0 1 +48523 4 3 40596 5 0 1 +48527 1 48522 1 +48527 2 5 48525 1 +48527 3 48522 3 0 1 +48527 4 5 34075 8 0 1 +48533 1 48531 1 +48533 2 2 48529 1 +48533 3 48531 7 0 1 +48533 4 2 31450 9 0 1 +48539 1 48537 1 +48539 2 2 48535 1 +48539 3 48537 2 0 1 +48539 4 2 42777 8 0 1 +48541 1 48539 1 +48541 2 2 48540 1 +48541 3 48539 5 0 1 +48541 4 2 37897 7 0 1 +48563 1 48561 1 +48563 2 2 48557 1 +48563 3 48561 5 0 1 +48563 4 2 47832 0 0 1 +48571 1 48569 1 +48571 2 2 48570 1 +48571 3 48569 6 0 1 +48571 4 2 36188 7 0 1 +48589 1 48579 1 +48589 2 10 48588 1 +48589 3 48579 10 0 1 +48589 4 10 44652 3 0 1 +48593 1 48590 1 +48593 2 3 48587 1 +48593 3 48590 4 0 1 +48593 4 3 45796 17 0 1 +48611 1 48609 1 +48611 2 2 48610 1 +48611 3 48609 7 0 1 +48611 4 2 32878 12 0 1 +48619 1 48617 1 +48619 2 2 48613 1 +48619 3 48617 4 0 1 +48619 4 2 26111 3 0 1 +48623 1 48618 1 +48623 2 5 48615 1 +48623 3 48618 3 0 1 +48623 4 5 47859 3 0 1 +48647 1 48642 1 +48647 2 5 48642 1 +48647 3 48642 6 0 1 +48647 4 5 46056 6 0 1 +48649 1 48642 1 +48649 2 7 48640 1 +48649 3 48642 2 0 1 +48649 4 7 37237 2 0 1 +48661 1 48659 1 +48661 2 2 48657 1 +48661 3 48659 7 0 1 +48661 4 2 36619 6 0 1 +48673 1 48658 1 +48673 2 15 48668 1 +48673 3 48658 2 0 1 +48673 4 15 31069 0 0 1 +48677 1 48675 1 +48677 2 2 48676 1 +48677 3 48675 3 0 1 +48677 4 2 40064 4 0 1 +48679 1 48676 1 +48679 2 3 48677 1 +48679 3 48676 4 0 1 +48679 4 3 43172 6 0 1 +48731 1 48725 1 +48731 2 6 48730 1 +48731 3 48725 1 0 1 +48731 4 6 30965 4 0 1 +48733 1 48731 1 +48733 2 2 48729 1 +48733 3 48731 6 0 1 +48733 4 2 38665 6 0 1 +48751 1 48748 1 +48751 2 3 48749 1 +48751 3 48748 1 0 1 +48751 4 3 48747 4 0 1 +48757 1 48755 1 +48757 2 2 48753 1 +48757 3 48755 5 0 1 +48757 4 2 45082 12 0 1 +48761 1 48758 1 +48761 2 3 48756 1 +48761 3 48758 4 0 1 +48761 4 3 30253 2 0 1 +48767 1 48762 1 +48767 2 5 48766 1 +48767 3 48762 3 0 1 +48767 4 5 38128 7 0 1 +48779 1 48777 1 +48779 2 2 48775 1 +48779 3 48777 11 0 1 +48779 4 2 41865 7 0 1 +48781 1 48775 1 +48781 2 6 48780 1 +48781 3 48775 1 0 1 +48781 4 6 43730 7 0 1 +48787 1 48785 1 +48787 2 2 48783 1 +48787 3 48785 5 0 1 +48787 4 2 33906 8 0 1 +48799 1 48796 1 +48799 2 3 48797 1 +48799 3 48796 6 0 1 +48799 4 3 37818 6 0 1 +48809 1 48806 1 +48809 2 3 48803 1 +48809 3 48806 3 0 1 +48809 4 3 48797 0 0 1 +48817 1 48812 1 +48817 2 5 48814 1 +48817 3 48812 1 0 1 +48817 4 5 45035 16 0 1 +48821 1 48819 1 +48821 2 2 48820 1 +48821 3 48819 5 0 1 +48821 4 2 37862 4 0 1 +48823 1 48818 1 +48823 2 5 48822 1 +48823 3 48818 2 0 1 +48823 4 5 43255 2 0 1 +48847 1 48844 1 +48847 2 3 48846 1 +48847 3 48844 4 0 1 +48847 4 3 29183 5 0 1 +48857 1 48854 1 +48857 2 3 48851 1 +48857 3 48854 5 0 1 +48857 4 3 32875 9 0 1 +48859 1 48857 1 +48859 2 2 48855 1 +48859 3 48857 4 0 1 +48859 4 2 44505 1 0 1 +48869 1 48867 1 +48869 2 2 48864 1 +48869 3 48867 7 0 1 +48869 4 2 42699 8 0 1 +48871 1 48868 1 +48871 2 3 48869 1 +48871 3 48868 6 0 1 +48871 4 3 24728 6 0 1 +48883 1 48881 1 +48883 2 2 48879 1 +48883 3 48881 4 0 1 +48883 4 2 38356 8 0 1 +48889 1 48855 1 +48889 2 34 48872 1 +48889 3 48855 2 0 1 +48889 4 34 46792 34 0 1 +48907 1 48905 1 +48907 2 2 48906 1 +48907 3 48905 2 0 1 +48907 4 2 46136 7 0 1 +48947 1 48945 1 +48947 2 2 48946 1 +48947 3 48945 2 0 1 +48947 4 2 48940 8 0 1 +48953 1 48950 1 +48953 2 3 48948 1 +48953 3 48950 4 0 1 +48953 4 3 40344 2 0 1 +48973 1 48968 1 +48973 2 5 48972 1 +48973 3 48968 8 0 1 +48973 4 5 45963 6 0 1 +48989 1 48987 1 +48989 2 2 48988 1 +48989 3 48987 3 0 1 +48989 4 2 38762 3 0 1 +48991 1 48985 1 +48991 2 6 48989 1 +48991 3 48985 3 0 1 +48991 4 6 38716 3 0 1 +49003 1 48990 1 +49003 2 13 49000 1 +49003 3 48990 2 0 1 +49003 4 13 40738 4 0 1 +49009 1 48990 1 +49009 2 19 48996 1 +49009 3 48990 6 0 1 +49009 4 19 25010 32 0 1 +49019 1 49017 1 +49019 2 2 49015 1 +49019 3 49017 3 0 1 +49019 4 2 45449 9 0 1 +49031 1 49018 1 +49031 2 13 49022 1 +49031 3 49018 2 0 1 +49031 4 13 46127 13 0 1 +49033 1 49023 1 +49033 2 10 49030 1 +49033 3 49023 5 0 1 +49033 4 10 40636 8 0 1 +49037 1 49035 1 +49037 2 2 49033 1 +49037 3 49035 3 0 1 +49037 4 2 44789 18 0 1 +49043 1 49041 1 +49043 2 2 49039 1 +49043 3 49041 3 0 1 +49043 4 2 43188 8 0 1 +49057 1 49052 1 +49057 2 5 49056 1 +49057 3 49052 1 0 1 +49057 4 5 39309 6 0 1 +49069 1 49067 1 +49069 2 2 49068 1 +49069 3 49067 4 0 1 +49069 4 2 32044 7 0 1 +49081 1 49070 1 +49081 2 11 49080 1 +49081 3 49070 2 0 1 +49081 4 11 34628 12 0 1 +49103 1 49098 1 +49103 2 5 49098 1 +49103 3 49098 9 0 1 +49103 4 5 37207 11 0 1 +49109 1 49107 1 +49109 2 2 49105 1 +49109 3 49107 5 0 1 +49109 4 2 33641 7 0 1 +49117 1 49115 1 +49117 2 2 49116 1 +49117 3 49115 6 0 1 +49117 4 2 25424 9 0 1 +49121 1 49118 1 +49121 2 3 49120 1 +49121 3 49118 3 0 1 +49121 4 3 43733 4 0 1 +49123 1 49121 1 +49123 2 2 49119 1 +49123 3 49121 4 0 1 +49123 4 2 37322 17 0 1 +49139 1 49137 1 +49139 2 2 49138 1 +49139 3 49137 3 0 1 +49139 4 2 38377 4 0 1 +49157 1 49155 1 +49157 2 2 49152 1 +49157 3 49155 7 0 1 +49157 4 2 34802 12 0 1 +49169 1 49166 1 +49169 2 3 49168 1 +49169 3 49166 1 0 1 +49169 4 3 35300 4 0 1 +49171 1 49169 1 +49171 2 2 49170 1 +49171 3 49169 4 0 1 +49171 4 2 33733 2 0 1 +49177 1 49172 1 +49177 2 5 49174 1 +49177 3 49172 1 0 1 +49177 4 5 47757 16 0 1 +49193 1 49190 1 +49193 2 3 49186 1 +49193 3 49190 12 0 1 +49193 4 3 46513 1 0 1 +49199 1 49186 1 +49199 2 13 49196 1 +49199 3 49186 2 0 1 +49199 4 13 45713 4 0 1 +49201 1 49194 1 +49201 2 7 49198 1 +49201 3 49194 3 0 1 +49201 4 7 33068 24 0 1 +49207 1 49204 1 +49207 2 3 49205 1 +49207 3 49204 5 0 1 +49207 4 3 45887 6 0 1 +49211 1 49209 1 +49211 2 2 49207 1 +49211 3 49209 3 0 1 +49211 4 2 32254 7 0 1 +49223 1 49218 1 +49223 2 5 49222 1 +49223 3 49218 3 0 1 +49223 4 5 38606 2 0 1 +49253 1 49251 1 +49253 2 2 49249 1 +49253 3 49251 3 0 1 +49253 4 2 43835 12 0 1 +49261 1 49259 1 +49261 2 2 49257 1 +49261 3 49259 2 0 1 +49261 4 2 46480 6 0 1 +49277 1 49275 1 +49277 2 2 49273 1 +49277 3 49275 3 0 1 +49277 4 2 26712 6 0 1 +49279 1 49276 1 +49279 2 3 49272 1 +49279 3 49276 3 0 1 +49279 4 3 43012 9 0 1 +49297 1 49292 1 +49297 2 5 49294 1 +49297 3 49292 1 0 1 +49297 4 5 36111 10 0 1 +49307 1 49305 1 +49307 2 2 49293 1 +49307 3 49305 3 0 1 +49307 4 2 45416 0 0 1 +49331 1 49329 1 +49331 2 2 49327 1 +49331 3 49329 2 0 1 +49331 4 2 39900 8 0 1 +49333 1 49331 1 +49333 2 2 49329 1 +49333 3 49331 6 0 1 +49333 4 2 28444 12 0 1 +49339 1 49328 1 +49339 2 11 49330 1 +49339 3 49328 1 0 1 +49339 4 11 43354 6 0 1 +49363 1 49361 1 +49363 2 2 49362 1 +49363 3 49361 2 0 1 +49363 4 2 44925 2 0 1 +49367 1 49362 1 +49367 2 5 49365 1 +49367 3 49362 6 0 1 +49367 4 5 39079 8 0 1 +49369 1 49356 1 +49369 2 13 49366 1 +49369 3 49356 1 0 1 +49369 4 13 44953 10 0 1 +49391 1 49380 1 +49391 2 11 49390 1 +49391 3 49380 1 0 1 +49391 4 11 28511 2 0 1 +49393 1 49388 1 +49393 2 5 49392 1 +49393 3 49388 2 0 1 +49393 4 5 25335 11 0 1 +49409 1 49406 1 +49409 2 3 49403 1 +49409 3 49406 1 0 1 +49409 4 3 49397 0 0 1 +49411 1 49409 1 +49411 2 2 49410 1 +49411 3 49409 4 0 1 +49411 4 2 43356 10 0 1 +49417 1 49412 1 +49417 2 5 49412 1 +49417 3 49412 1 0 1 +49417 4 5 38659 15 0 1 +49429 1 49427 1 +49429 2 2 49425 1 +49429 3 49427 4 0 1 +49429 4 2 27773 6 0 1 +49433 1 49430 1 +49433 2 3 49427 1 +49433 3 49430 1 0 1 +49433 4 3 26127 13 0 1 +49451 1 49441 1 +49451 2 10 49450 1 +49451 3 49441 5 0 1 +49451 4 10 28037 8 0 1 +49459 1 49456 1 +49459 2 3 49451 1 +49459 3 49456 5 0 1 +49459 4 3 30359 0 0 1 +49463 1 49458 1 +49463 2 5 49461 1 +49463 3 49458 3 0 1 +49463 4 5 32467 8 0 1 +49477 1 49466 1 +49477 2 11 49476 1 +49477 3 49466 1 0 1 +49477 4 11 33940 3 0 1 +49481 1 49478 1 +49481 2 3 49475 1 +49481 3 49478 1 0 1 +49481 4 3 49469 0 0 1 +49499 1 49497 1 +49499 2 2 49495 1 +49499 3 49497 3 0 1 +49499 4 2 27389 7 0 1 +49523 1 49521 1 +49523 2 2 49522 1 +49523 3 49521 2 0 1 +49523 4 2 44113 2 0 1 +49529 1 49526 1 +49529 2 3 49528 1 +49529 3 49526 5 0 1 +49529 4 3 44829 7 0 1 +49531 1 49521 1 +49531 2 10 49529 1 +49531 3 49521 5 0 1 +49531 4 10 49513 11 0 1 +49537 1 49527 1 +49537 2 10 49536 1 +49537 3 49527 2 0 1 +49537 4 10 31783 16 0 1 +49547 1 49545 1 +49547 2 2 49543 1 +49547 3 49545 3 0 1 +49547 4 2 27116 7 0 1 +49549 1 49543 1 +49549 2 6 49548 1 +49549 3 49543 4 0 1 +49549 4 6 48251 7 0 1 +49559 1 49548 1 +49559 2 11 49557 1 +49559 3 49548 7 0 1 +49559 4 11 33849 9 0 1 +49597 1 49592 1 +49597 2 5 49592 1 +49597 3 49592 2 0 1 +49597 4 5 40614 11 0 1 +49603 1 49600 1 +49603 2 3 49598 1 +49603 3 49600 1 0 1 +49603 4 3 29825 3 0 1 +49613 1 49611 1 +49613 2 2 49609 1 +49613 3 49611 3 0 1 +49613 4 2 48353 6 0 1 +49627 1 49624 1 +49627 2 3 49626 1 +49627 3 49624 4 0 1 +49627 4 3 30852 5 0 1 +49633 1 49628 1 +49633 2 5 49628 1 +49633 3 49628 5 0 1 +49633 4 5 27663 10 0 1 +49639 1 49636 1 +49639 2 3 49637 1 +49639 3 49636 13 0 1 +49639 4 3 32045 6 0 1 +49663 1 49660 1 +49663 2 3 49661 1 +49663 3 49660 1 0 1 +49663 4 3 49659 4 0 1 +49667 1 49665 1 +49667 2 2 49663 1 +49667 3 49665 3 0 1 +49667 4 2 35014 8 0 1 +49669 1 49667 1 +49669 2 2 49665 1 +49669 3 49667 2 0 1 +49669 4 2 40306 6 0 1 +49681 1 49664 1 +49681 2 17 49680 1 +49681 3 49664 2 0 1 +49681 4 17 26405 14 0 1 +49697 1 49694 1 +49697 2 3 49692 1 +49697 3 49694 4 0 1 +49697 4 3 32921 0 0 1 +49711 1 49704 1 +49711 2 7 49702 1 +49711 3 49704 1 0 1 +49711 4 7 28138 10 0 1 +49727 1 49722 1 +49727 2 5 49725 1 +49727 3 49722 1 0 1 +49727 4 5 49723 3 0 1 +49739 1 49737 1 +49739 2 2 49732 1 +49739 3 49737 3 0 1 +49739 4 2 44053 1 0 1 +49741 1 49739 1 +49741 2 2 49740 1 +49741 3 49739 5 0 1 +49741 4 2 48212 3 0 1 +49747 1 49744 1 +49747 2 3 49740 1 +49747 3 49744 4 0 1 +49747 4 3 34505 5 0 1 +49757 1 49755 1 +49757 2 2 49753 1 +49757 3 49755 3 0 1 +49757 4 2 29424 7 0 1 +49783 1 49780 1 +49783 2 3 49782 1 +49783 3 49780 13 0 1 +49783 4 3 40233 5 0 1 +49787 1 49785 1 +49787 2 2 49783 1 +49787 3 49785 2 0 1 +49787 4 2 45577 13 0 1 +49789 1 49783 1 +49789 2 6 49788 1 +49789 3 49783 8 0 1 +49789 4 6 25766 11 0 1 +49801 1 49788 1 +49801 2 13 49798 1 +49801 3 49788 1 0 1 +49801 4 13 31480 10 0 1 +49807 1 49804 1 +49807 2 3 49806 1 +49807 3 49804 4 0 1 +49807 4 3 32124 14 0 1 +49811 1 49805 1 +49811 2 6 49809 1 +49811 3 49805 1 0 1 +49811 4 6 34569 5 0 1 +49823 1 49818 1 +49823 2 5 49818 1 +49823 3 49818 1 0 1 +49823 4 5 28121 8 0 1 +49831 1 49819 1 +49831 2 12 49830 1 +49831 3 49819 1 0 1 +49831 4 12 28689 3 0 1 +49843 1 49841 1 +49843 2 2 49842 1 +49843 3 49841 6 0 1 +49843 4 2 26448 7 0 1 +49853 1 49851 1 +49853 2 2 49852 1 +49853 3 49851 2 0 1 +49853 4 2 27228 4 0 1 +49871 1 49854 1 +49871 2 17 49869 1 +49871 3 49854 1 0 1 +49871 4 17 49863 3 0 1 +49877 1 49875 1 +49877 2 2 49873 1 +49877 3 49875 7 0 1 +49877 4 2 37283 7 0 1 +49891 1 49889 1 +49891 2 2 49887 1 +49891 3 49889 2 0 1 +49891 4 2 38705 8 0 1 +49919 1 49912 1 +49919 2 7 49918 1 +49919 3 49912 1 0 1 +49919 4 7 38692 3 0 1 +49921 1 49898 1 +49921 2 23 49917 1 +49921 3 49898 2 0 1 +49921 4 23 49883 23 0 1 +49927 1 49924 1 +49927 2 3 49925 1 +49927 3 49924 1 0 1 +49927 4 3 49919 10 0 1 +49937 1 49934 1 +49937 2 3 49931 1 +49937 3 49934 1 0 1 +49937 4 3 39765 1 0 1 +49939 1 49932 1 +49939 2 7 49937 1 +49939 3 49932 3 0 1 +49939 4 7 45043 6 0 1 +49943 1 49938 1 +49943 2 5 49941 1 +49943 3 49938 7 0 1 +49943 4 5 49939 3 0 1 +49957 1 49952 1 +49957 2 5 49954 1 +49957 3 49952 2 0 1 +49957 4 5 38964 9 0 1 +49991 1 49984 1 +49991 2 7 49990 1 +49991 3 49984 11 0 1 +49991 4 7 34536 2 0 1 +49993 1 49988 1 +49993 2 5 49988 1 +49993 3 49988 1 0 1 +49993 4 5 36062 18 0 1 +49999 1 49996 1 +49999 2 3 49993 1 +49999 3 49996 5 0 1 +49999 4 3 36978 13 0 1 +50021 1 50019 1 +50021 2 2 50020 1 +50021 3 50019 5 0 1 +50021 4 2 50014 8 0 1 +50023 1 50020 1 +50023 2 3 50022 1 +50023 3 50020 3 0 1 +50023 4 3 39725 5 0 1 +50033 1 50028 1 +50033 2 5 50026 1 +50033 3 50028 3 0 1 +50033 4 5 35784 4 0 1 +50047 1 50041 1 +50047 2 6 50046 1 +50047 3 50041 4 0 1 +50047 4 6 39163 10 0 1 +50051 1 50049 1 +50051 2 2 50046 1 +50051 3 50049 2 0 1 +50051 4 2 27862 3 0 1 +50053 1 50051 1 +50053 2 2 50052 1 +50053 3 50051 2 0 1 +50053 4 2 37338 6 0 1 +50069 1 50067 1 +50069 2 2 50068 1 +50069 3 50067 3 0 1 +50069 4 2 34473 3 0 1 +50077 1 50075 1 +50077 2 2 50076 1 +50077 3 50075 6 0 1 +50077 4 2 45399 6 0 1 +50087 1 50082 1 +50087 2 5 50086 1 +50087 3 50082 5 0 1 +50087 4 5 40006 3 0 1 +50093 1 50091 1 +50093 2 2 50088 1 +50093 3 50091 3 0 1 +50093 4 2 33148 8 0 1 +50101 1 50099 1 +50101 2 2 50097 1 +50101 3 50099 4 0 1 +50101 4 2 49294 12 0 1 +50111 1 50094 1 +50111 2 17 50109 1 +50111 3 50094 4 0 1 +50111 4 17 50103 3 0 1 +50119 1 50116 1 +50119 2 3 50117 1 +50119 3 50116 1 0 1 +50119 4 3 50115 4 0 1 +50123 1 50121 1 +50123 2 2 50122 1 +50123 3 50121 4 0 1 +50123 4 2 29841 10 0 1 +50129 1 50126 1 +50129 2 3 50128 1 +50129 3 50126 1 0 1 +50129 4 3 43702 4 0 1 +50131 1 50129 1 +50131 2 2 50127 1 +50131 3 50129 2 0 1 +50131 4 2 32113 8 0 1 +50147 1 50145 1 +50147 2 2 50146 1 +50147 3 50145 10 0 1 +50147 4 2 29812 10 0 1 +50153 1 50150 1 +50153 2 3 50147 1 +50153 3 50150 11 0 1 +50153 4 3 39996 9 0 1 +50159 1 50152 1 +50159 2 7 50158 1 +50159 3 50152 1 0 1 +50159 4 7 45366 2 0 1 +50177 1 50174 1 +50177 2 3 50176 1 +50177 3 50174 4 0 1 +50177 4 3 26300 6 0 1 +50207 1 50202 1 +50207 2 5 50205 1 +50207 3 50202 1 0 1 +50207 4 5 37343 16 0 1 +50221 1 50208 1 +50221 2 13 50220 1 +50221 3 50208 3 0 1 +50221 4 13 45023 7 0 1 +50227 1 50225 1 +50227 2 2 50223 1 +50227 3 50225 6 0 1 +50227 4 2 37029 8 0 1 +50231 1 50220 1 +50231 2 11 50228 1 +50231 3 50220 2 0 1 +50231 4 11 27812 8 0 1 +50261 1 50258 1 +50261 2 3 50259 1 +50261 3 50258 7 0 1 +50261 4 3 50253 10 0 1 +50263 1 50260 1 +50263 2 3 50261 1 +50263 3 50260 1 0 1 +50263 4 3 48726 3 0 1 +50273 1 50270 1 +50273 2 3 50267 1 +50273 3 50270 3 0 1 +50273 4 3 41061 1 0 1 +50287 1 50284 1 +50287 2 3 50286 1 +50287 3 50284 3 0 1 +50287 4 3 45318 5 0 1 +50291 1 50289 1 +50291 2 2 50290 1 +50291 3 50289 3 0 1 +50291 4 2 43956 2 0 1 +50311 1 50308 1 +50311 2 3 50310 1 +50311 3 50308 3 0 1 +50311 4 3 25819 2 0 1 +50321 1 50315 1 +50321 2 6 50312 1 +50321 3 50315 2 0 1 +50321 4 6 49819 2 0 1 +50329 1 50322 1 +50329 2 7 50322 1 +50329 3 50322 7 0 1 +50329 4 7 47892 0 0 1 +50333 1 50331 1 +50333 2 2 50332 1 +50333 3 50331 3 0 1 +50333 4 2 31976 3 0 1 +50341 1 50339 1 +50341 2 2 50337 1 +50341 3 50339 2 0 1 +50341 4 2 42673 12 0 1 +50359 1 50356 1 +50359 2 3 50357 1 +50359 3 50356 1 0 1 +50359 4 3 50355 4 0 1 +50363 1 50361 1 +50363 2 2 50362 1 +50363 3 50361 2 0 1 +50363 4 2 34649 2 0 1 +50377 1 50372 1 +50377 2 5 50376 1 +50377 3 50372 1 0 1 +50377 4 5 44870 6 0 1 +50383 1 50380 1 +50383 2 3 50381 1 +50383 3 50380 1 0 1 +50383 4 3 32021 3 0 1 +50387 1 50385 1 +50387 2 2 50381 1 +50387 3 50385 4 0 1 +50387 4 2 30105 4 0 1 +50411 1 50409 1 +50411 2 2 50406 1 +50411 3 50409 4 0 1 +50411 4 2 49861 3 0 1 +50417 1 50414 1 +50417 2 3 50411 1 +50417 3 50414 5 0 1 +50417 4 3 47117 9 0 1 +50423 1 50418 1 +50423 2 5 50421 1 +50423 3 50418 2 0 1 +50423 4 5 37270 8 0 1 +50441 1 50435 1 +50441 2 6 50431 1 +50441 3 50435 2 0 1 +50441 4 6 25866 3 0 1 +50459 1 50457 1 +50459 2 2 50458 1 +50459 3 50457 3 0 1 +50459 4 2 42533 4 0 1 +50461 1 50454 1 +50461 2 7 50459 1 +50461 3 50454 1 0 1 +50461 4 7 41484 15 0 1 +50497 1 50492 1 +50497 2 5 50496 1 +50497 3 50492 2 0 1 +50497 4 5 36424 6 0 1 +50503 1 50498 1 +50503 2 5 50501 1 +50503 3 50498 2 0 1 +50503 4 5 34429 10 0 1 +50513 1 50510 1 +50513 2 3 50508 1 +50513 3 50510 3 0 1 +50513 4 3 30427 0 0 1 +50527 1 50524 1 +50527 2 3 50525 1 +50527 3 50524 1 0 1 +50527 4 3 50519 10 0 1 +50539 1 50537 1 +50539 2 2 50535 1 +50539 3 50537 5 0 1 +50539 4 2 38391 1 0 1 +50543 1 50538 1 +50543 2 5 50542 1 +50543 3 50538 5 0 1 +50543 4 5 35497 2 0 1 +50549 1 50547 1 +50549 2 2 50541 1 +50549 3 50547 8 0 1 +50549 4 2 27326 0 0 1 +50551 1 50548 1 +50551 2 3 50550 1 +50551 3 50548 4 0 1 +50551 4 3 50233 3 0 1 +50581 1 50579 1 +50581 2 2 50580 1 +50581 3 50579 4 0 1 +50581 4 2 39499 9 0 1 +50587 1 50573 1 +50587 2 14 50586 1 +50587 3 50573 6 0 1 +50587 4 14 41596 2 0 1 +50591 1 50584 1 +50591 2 7 50589 1 +50591 3 50584 1 0 1 +50591 4 7 34087 5 0 1 +50593 1 50588 1 +50593 2 5 50592 1 +50593 3 50588 5 0 1 +50593 4 5 26449 11 0 1 +50599 1 50596 1 +50599 2 3 50598 1 +50599 3 50596 3 0 1 +50599 4 3 41000 3 0 1 +50627 1 50625 1 +50627 2 2 50623 1 +50627 3 50625 2 0 1 +50627 4 2 25979 16 0 1 +50647 1 50644 1 +50647 2 3 50645 1 +50647 3 50644 5 0 1 +50647 4 3 26551 3 0 1 +50651 1 50649 1 +50651 2 2 50650 1 +50651 3 50649 3 0 1 +50651 4 2 41952 2 0 1 +50671 1 50660 1 +50671 2 11 50669 1 +50671 3 50660 1 0 1 +50671 4 11 26891 3 0 1 +50683 1 50681 1 +50683 2 2 50682 1 +50683 3 50681 2 0 1 +50683 4 2 50676 8 0 1 +50707 1 50704 1 +50707 2 3 50706 1 +50707 3 50704 1 0 1 +50707 4 3 45182 2 0 1 +50723 1 50721 1 +50723 2 2 50718 1 +50723 3 50721 5 0 1 +50723 4 2 49068 6 0 1 +50741 1 50739 1 +50741 2 2 50740 1 +50741 3 50739 7 0 1 +50741 4 2 28510 4 0 1 +50753 1 50750 1 +50753 2 3 50752 1 +50753 3 50750 1 0 1 +50753 4 3 39774 7 0 1 +50767 1 50762 1 +50767 2 5 50766 1 +50767 3 50762 10 0 1 +50767 4 5 38749 12 0 1 +50773 1 50762 1 +50773 2 11 50772 1 +50773 3 50762 1 0 1 +50773 4 11 27150 3 0 1 +50777 1 50774 1 +50777 2 3 50771 1 +50777 3 50774 5 0 1 +50777 4 3 36989 12 0 1 +50789 1 50787 1 +50789 2 2 50785 1 +50789 3 50787 2 0 1 +50789 4 2 40054 6 0 1 +50821 1 50819 1 +50821 2 2 50817 1 +50821 3 50819 4 0 1 +50821 4 2 41439 10 0 1 +50833 1 50826 1 +50833 2 7 50826 1 +50833 3 50826 7 0 1 +50833 4 7 30908 12 0 1 +50839 1 50836 1 +50839 2 3 50838 1 +50839 3 50836 3 0 1 +50839 4 3 30653 2 0 1 +50849 1 50846 1 +50849 2 3 50844 1 +50849 3 50846 7 0 1 +50849 4 3 48200 2 0 1 +50857 1 50838 1 +50857 2 19 50853 1 +50857 3 50838 7 0 1 +50857 4 19 32990 9 0 1 +50867 1 50865 1 +50867 2 2 50866 1 +50867 3 50865 2 0 1 +50867 4 2 40928 2 0 1 +50873 1 50870 1 +50873 2 3 50866 1 +50873 3 50870 5 0 1 +50873 4 3 29597 1 0 1 +50891 1 50889 1 +50891 2 2 50885 1 +50891 3 50889 9 0 1 +50891 4 2 47150 4 0 1 +50893 1 50891 1 +50893 2 2 50892 1 +50893 3 50891 2 0 1 +50893 4 2 43160 3 0 1 +50909 1 50907 1 +50909 2 2 50908 1 +50909 3 50907 3 0 1 +50909 4 2 50902 8 0 1 +50923 1 50921 1 +50923 2 2 50922 1 +50923 3 50921 2 0 1 +50923 4 2 31950 7 0 1 +50929 1 50918 1 +50929 2 11 50920 1 +50929 3 50918 2 0 1 +50929 4 11 42833 20 0 1 +50951 1 50928 1 +50951 2 23 50947 1 +50951 3 50928 1 0 1 +50951 4 23 44911 13 0 1 +50957 1 50955 1 +50957 2 2 50953 1 +50957 3 50955 3 0 1 +50957 4 2 44272 12 0 1 +50969 1 50966 1 +50969 2 3 50963 1 +50969 3 50966 1 0 1 +50969 4 3 50957 0 0 1 +50971 1 50969 1 +50971 2 2 50967 1 +50971 3 50969 2 0 1 +50971 4 2 50580 8 0 1 +50989 1 50987 1 +50989 2 2 50985 1 +50989 3 50987 5 0 1 +50989 4 2 41764 6 0 1 +50993 1 50990 1 +50993 2 3 50992 1 +50993 3 50990 3 0 1 +50993 4 3 29297 4 0 1 +51001 1 50994 1 +51001 2 7 50994 1 +51001 3 50994 3 0 1 +51001 4 7 30917 0 0 1 +51031 1 51028 1 +51031 2 3 51030 1 +51031 3 51028 4 0 1 +51031 4 3 29818 2 0 1 +51043 1 51041 1 +51043 2 2 51042 1 +51043 3 51041 2 0 1 +51043 4 2 30270 2 0 1 +51047 1 51042 1 +51047 2 5 51046 1 +51047 3 51042 18 0 1 +51047 4 5 43008 2 0 1 +51059 1 51057 1 +51059 2 2 51055 1 +51059 3 51057 3 0 1 +51059 4 2 43363 7 0 1 +51061 1 51059 1 +51061 2 2 51060 1 +51061 3 51059 5 0 1 +51061 4 2 42845 3 0 1 +51071 1 51060 1 +51071 2 11 51070 1 +51071 3 51060 4 0 1 +51071 4 11 33195 4 0 1 +51109 1 51099 1 +51109 2 10 51108 1 +51109 3 51099 3 0 1 +51109 4 10 39597 14 0 1 +51131 1 51125 1 +51131 2 6 51129 1 +51131 3 51125 3 0 1 +51131 4 6 31172 5 0 1 +51133 1 51131 1 +51133 2 2 51132 1 +51133 3 51131 2 0 1 +51133 4 2 36778 6 0 1 +51137 1 51134 1 +51137 2 3 51129 1 +51137 3 51134 3 0 1 +51137 4 3 35927 2 0 1 +51151 1 51148 1 +51151 2 3 51149 1 +51151 3 51148 3 0 1 +51151 4 3 36445 3 0 1 +51157 1 51152 1 +51157 2 5 51154 1 +51157 3 51152 3 0 1 +51157 4 5 47246 1 0 1 +51169 1 51155 1 +51169 2 14 51166 1 +51169 3 51155 1 0 1 +51169 4 14 43076 10 0 1 +51193 1 51188 1 +51193 2 5 51190 1 +51193 3 51188 2 0 1 +51193 4 5 47089 32 0 1 +51197 1 51195 1 +51197 2 2 51187 1 +51197 3 51195 8 0 1 +51197 4 2 30959 3 0 1 +51199 1 51187 1 +51199 2 12 51189 1 +51199 3 51187 3 0 1 +51199 4 12 33515 3 0 1 +51203 1 51201 1 +51203 2 2 51199 1 +51203 3 51201 2 0 1 +51203 4 2 50563 7 0 1 +51217 1 51212 1 +51217 2 5 51216 1 +51217 3 51212 11 0 1 +51217 4 5 38869 6 0 1 +51229 1 51227 1 +51229 2 2 51228 1 +51229 3 51227 6 0 1 +51229 4 2 36253 3 0 1 +51239 1 51216 1 +51239 2 23 51233 1 +51239 3 51216 1 0 1 +51239 4 23 37381 13 0 1 +51241 1 51224 1 +51241 2 17 51240 1 +51241 3 51224 1 0 1 +51241 4 17 41348 18 0 1 +51257 1 51254 1 +51257 2 3 51256 1 +51257 3 51254 3 0 1 +51257 4 3 30626 4 0 1 +51263 1 51258 1 +51263 2 5 51261 1 +51263 3 51258 1 0 1 +51263 4 5 34676 5 0 1 +51283 1 51281 1 +51283 2 2 51279 1 +51283 3 51281 5 0 1 +51283 4 2 46692 8 0 1 +51287 1 51282 1 +51287 2 5 51285 1 +51287 3 51282 1 0 1 +51287 4 5 51283 3 0 1 +51307 1 51302 1 +51307 2 5 51305 1 +51307 3 51302 6 0 1 +51307 4 5 51303 3 0 1 +51329 1 51326 1 +51329 2 3 51324 1 +51329 3 51326 1 0 1 +51329 4 3 28338 2 0 1 +51341 1 51339 1 +51341 2 2 51340 1 +51341 3 51339 3 0 1 +51341 4 2 51334 8 0 1 +51343 1 51338 1 +51343 2 5 51341 1 +51343 3 51338 3 0 1 +51343 4 5 51331 11 0 1 +51347 1 51345 1 +51347 2 2 51343 1 +51347 3 51345 3 0 1 +51347 4 2 37882 8 0 1 +51349 1 51339 1 +51349 2 10 51346 1 +51349 3 51339 6 0 1 +51349 4 10 29555 9 0 1 +51361 1 51324 1 +51361 2 37 51358 1 +51361 3 51324 1 0 1 +51361 4 37 36924 32 0 1 +51383 1 51378 1 +51383 2 5 51381 1 +51383 3 51378 2 0 1 +51383 4 5 51379 3 0 1 +51407 1 51402 1 +51407 2 5 51406 1 +51407 3 51402 2 0 1 +51407 4 5 50690 2 0 1 +51413 1 51411 1 +51413 2 2 51412 1 +51413 3 51411 4 0 1 +51413 4 2 47171 3 0 1 +51419 1 51417 1 +51419 2 2 51415 1 +51419 3 51417 2 0 1 +51419 4 2 48935 7 0 1 +51421 1 51419 1 +51421 2 2 51420 1 +51421 3 51419 4 0 1 +51421 4 2 46584 3 0 1 +51427 1 51425 1 +51427 2 2 51426 1 +51427 3 51425 2 0 1 +51427 4 2 33403 32 0 1 +51431 1 51424 1 +51431 2 7 51430 1 +51431 3 51424 2 0 1 +51431 4 7 47569 3 0 1 +51437 1 51435 1 +51437 2 2 51432 1 +51437 3 51435 4 0 1 +51437 4 2 50502 17 0 1 +51439 1 51436 1 +51439 2 3 51433 1 +51439 3 51436 6 0 1 +51439 4 3 30174 7 0 1 +51449 1 51446 1 +51449 2 3 51444 1 +51449 3 51446 3 0 1 +51449 4 3 30638 2 0 1 +51461 1 51459 1 +51461 2 2 51457 1 +51461 3 51459 3 0 1 +51461 4 2 37625 7 0 1 +51473 1 51470 1 +51473 2 3 51467 1 +51473 3 51470 3 0 1 +51473 4 3 35766 16 0 1 +51479 1 51472 1 +51479 2 7 51477 1 +51479 3 51472 1 0 1 +51479 4 7 28324 12 0 1 +51481 1 51464 1 +51481 2 17 51478 1 +51481 3 51464 6 0 1 +51481 4 17 36296 17 0 1 +51487 1 51484 1 +51487 2 3 51486 1 +51487 3 51484 8 0 1 +51487 4 3 39036 5 0 1 +51503 1 51498 1 +51503 2 5 51502 1 +51503 3 51498 1 0 1 +51503 4 5 27446 3 0 1 +51511 1 51505 1 +51511 2 6 51510 1 +51511 3 51505 3 0 1 +51511 4 6 34580 3 0 1 +51517 1 51511 1 +51517 2 6 51516 1 +51517 3 51511 3 0 1 +51517 4 6 45268 6 0 1 +51521 1 51518 1 +51521 2 3 51520 1 +51521 3 51518 1 0 1 +51521 4 3 45198 4 0 1 +51539 1 51537 1 +51539 2 2 51538 1 +51539 3 51537 3 0 1 +51539 4 2 42061 2 0 1 +51551 1 51540 1 +51551 2 11 51549 1 +51551 3 51540 1 0 1 +51551 4 11 36288 7 0 1 +51563 1 51561 1 +51563 2 2 51559 1 +51563 3 51561 3 0 1 +51563 4 2 33015 8 0 1 +51577 1 51567 1 +51577 2 10 51576 1 +51577 3 51567 5 0 1 +51577 4 10 47092 6 0 1 +51581 1 51579 1 +51581 2 2 51577 1 +51581 3 51579 3 0 1 +51581 4 2 44285 1 0 1 +51593 1 51590 1 +51593 2 3 51586 1 +51593 3 51590 4 0 1 +51593 4 3 27603 2 0 1 +51599 1 51592 1 +51599 2 7 51598 1 +51599 3 51592 7 0 1 +51599 4 7 44072 2 0 1 +51607 1 51604 1 +51607 2 3 51606 1 +51607 3 51604 3 0 1 +51607 4 3 32990 8 0 1 +51613 1 51611 1 +51613 2 2 51609 1 +51613 3 51611 6 0 1 +51613 4 2 26327 10 0 1 +51631 1 51616 1 +51631 2 15 51629 1 +51631 3 51616 7 0 1 +51631 4 15 39763 3 0 1 +51637 1 51632 1 +51637 2 5 51636 1 +51637 3 51632 7 0 1 +51637 4 5 50571 19 0 1 +51647 1 51640 1 +51647 2 7 51645 1 +51647 3 51640 1 0 1 +51647 4 7 30770 6 0 1 +51659 1 51657 1 +51659 2 2 51649 1 +51659 3 51657 10 0 1 +51659 4 2 35307 0 0 1 +51673 1 51666 1 +51673 2 7 51670 1 +51673 3 51666 1 0 1 +51673 4 7 39291 10 0 1 +51679 1 51673 1 +51679 2 6 51678 1 +51679 3 51673 3 0 1 +51679 4 6 30497 3 0 1 +51683 1 51681 1 +51683 2 2 51679 1 +51683 3 51681 3 0 1 +51683 4 2 41425 7 0 1 +51691 1 51681 1 +51691 2 10 51689 1 +51691 3 51681 5 0 1 +51691 4 10 34612 0 0 1 +51713 1 51710 1 +51713 2 3 51706 1 +51713 3 51710 12 0 1 +51713 4 3 42691 1 0 1 +51719 1 51706 1 +51719 2 13 51717 1 +51719 3 51706 3 0 1 +51719 4 13 35614 7 0 1 +51721 1 51714 1 +51721 2 7 51718 1 +51721 3 51714 3 0 1 +51721 4 7 47016 26 0 1 +51749 1 51747 1 +51749 2 2 51745 1 +51749 3 51747 3 0 1 +51749 4 2 33772 1 0 1 +51767 1 51762 1 +51767 2 5 51762 1 +51767 3 51762 3 0 1 +51767 4 5 39984 6 0 1 +51769 1 51750 1 +51769 2 19 51766 1 +51769 3 51750 1 0 1 +51769 4 19 28683 26 0 1 +51787 1 51784 1 +51787 2 3 51786 1 +51787 3 51784 5 0 1 +51787 4 3 41309 5 0 1 +51797 1 51794 1 +51797 2 3 51795 1 +51797 3 51794 1 0 1 +51797 4 3 34746 7 0 1 +51803 1 51801 1 +51803 2 2 51802 1 +51803 3 51801 3 0 1 +51803 4 2 41067 4 0 1 +51817 1 51807 1 +51817 2 10 51812 1 +51817 3 51807 4 0 1 +51817 4 10 29040 0 0 1 +51827 1 51825 1 +51827 2 2 51823 1 +51827 3 51825 3 0 1 +51827 4 2 34212 7 0 1 +51829 1 51827 1 +51829 2 2 51825 1 +51829 3 51827 2 0 1 +51829 4 2 51320 12 0 1 +51839 1 51832 1 +51839 2 7 51838 1 +51839 3 51832 1 0 1 +51839 4 7 27888 2 0 1 +51853 1 51842 1 +51853 2 11 51850 1 +51853 3 51842 8 0 1 +51853 4 11 45646 5 0 1 +51859 1 51856 1 +51859 2 3 51851 1 +51859 3 51856 1 0 1 +51859 4 3 41790 0 0 1 +51869 1 51867 1 +51869 2 2 51857 1 +51869 3 51867 8 0 1 +51869 4 2 44581 4 0 1 +51871 1 51864 1 +51871 2 7 51859 1 +51871 3 51864 2 0 1 +51871 4 7 35005 0 0 1 +51893 1 51891 1 +51893 2 2 51886 1 +51893 3 51891 18 0 1 +51893 4 2 31509 2 0 1 +51899 1 51897 1 +51899 2 2 51895 1 +51899 3 51897 3 0 1 +51899 4 2 43375 7 0 1 +51907 1 51896 1 +51907 2 11 51905 1 +51907 3 51896 1 0 1 +51907 4 11 42771 3 0 1 +51913 1 51903 1 +51913 2 10 51908 1 +51913 3 51903 3 0 1 +51913 4 10 34965 10 0 1 +51929 1 51926 1 +51929 2 3 51921 1 +51929 3 51926 1 0 1 +51929 4 3 45104 2 0 1 +51941 1 51938 1 +51941 2 3 51936 1 +51941 3 51938 1 0 1 +51941 4 3 33200 2 0 1 +51949 1 51947 1 +51949 2 2 51945 1 +51949 3 51947 5 0 1 +51949 4 2 40496 6 0 1 +51971 1 51969 1 +51971 2 2 51970 1 +51971 3 51969 13 0 1 +51971 4 2 39077 2 0 1 +51973 1 51971 1 +51973 2 2 51972 1 +51973 3 51971 2 0 1 +51973 4 2 51151 6 0 1 +51977 1 51974 1 +51977 2 3 51976 1 +51977 3 51974 4 0 1 +51977 4 3 33537 7 0 1 +51991 1 51984 1 +51991 2 7 51982 1 +51991 3 51984 8 0 1 +51991 4 7 35432 10 0 1 +52009 1 51992 1 +52009 2 17 52006 1 +52009 3 51992 12 0 1 +52009 4 17 44665 20 0 1 +52021 1 52019 1 +52021 2 2 52017 1 +52021 3 52019 5 0 1 +52021 4 2 39143 12 0 1 +52027 1 52025 1 +52027 2 2 52026 1 +52027 3 52025 6 0 1 +52027 4 2 35108 2 0 1 +52051 1 52049 1 +52051 2 2 52047 1 +52051 3 52049 5 0 1 +52051 4 2 40756 1 0 1 +52057 1 52050 1 +52057 2 7 52050 1 +52057 3 52050 3 0 1 +52057 4 7 49013 17 0 1 +52067 1 52065 1 +52067 2 2 52063 1 +52067 3 52065 3 0 1 +52067 4 2 42954 16 0 1 +52069 1 52067 1 +52069 2 2 52068 1 +52069 3 52067 6 0 1 +52069 4 2 41826 3 0 1 +52081 1 52064 1 +52081 2 17 52078 1 +52081 3 52064 3 0 1 +52081 4 17 41781 20 0 1 +52103 1 52098 1 +52103 2 5 52101 1 +52103 3 52098 2 0 1 +52103 4 5 52099 3 0 1 +52121 1 52118 1 +52121 2 3 52115 1 +52121 3 52118 1 0 1 +52121 4 3 52109 0 0 1 +52127 1 52122 1 +52127 2 5 52126 1 +52127 3 52122 2 0 1 +52127 4 5 49124 3 0 1 +52147 1 52145 1 +52147 2 2 52143 1 +52147 3 52145 4 0 1 +52147 4 2 44306 8 0 1 +52153 1 52148 1 +52153 2 5 52150 1 +52153 3 52148 6 0 1 +52153 4 5 40698 10 0 1 +52163 1 52161 1 +52163 2 2 52162 1 +52163 3 52161 2 0 1 +52163 4 2 39023 11 0 1 +52177 1 52172 1 +52177 2 5 52176 1 +52177 3 52172 3 0 1 +52177 4 5 28122 6 0 1 +52181 1 52178 1 +52181 2 3 52180 1 +52181 3 52178 6 0 1 +52181 4 3 28647 3 0 1 +52183 1 52180 1 +52183 2 3 52182 1 +52183 3 52180 1 0 1 +52183 4 3 44586 2 0 1 +52189 1 52176 1 +52189 2 13 52180 1 +52189 3 52176 5 0 1 +52189 4 13 40268 23 0 1 +52201 1 52184 1 +52201 2 17 52200 1 +52201 3 52184 7 0 1 +52201 4 17 46708 14 0 1 +52223 1 52218 1 +52223 2 5 52221 1 +52223 3 52218 5 0 1 +52223 4 5 34293 9 0 1 +52237 1 52231 1 +52237 2 6 52235 1 +52237 3 52231 3 0 1 +52237 4 6 48847 0 0 1 +52249 1 52236 1 +52249 2 13 52236 1 +52249 3 52236 5 0 1 +52249 4 13 52210 0 0 1 +52253 1 52251 1 +52253 2 2 52252 1 +52253 3 52251 4 0 1 +52253 4 2 46552 6 0 1 +52259 1 52257 1 +52259 2 2 52245 1 +52259 3 52257 2 0 1 +52259 4 2 43253 3 0 1 +52267 1 52265 1 +52267 2 2 52266 1 +52267 3 52265 4 0 1 +52267 4 2 52260 8 0 1 +52289 1 52286 1 +52289 2 3 52288 1 +52289 3 52286 8 0 1 +52289 4 3 43330 7 0 1 +52291 1 52284 1 +52291 2 7 52289 1 +52291 3 52284 9 0 1 +52291 4 7 42016 6 0 1 +52301 1 52299 1 +52301 2 2 52294 1 +52301 3 52299 2 0 1 +52301 4 2 51696 9 0 1 +52313 1 52310 1 +52313 2 3 52307 1 +52313 3 52310 1 0 1 +52313 4 3 30146 11 0 1 +52321 1 52304 1 +52321 2 17 52320 1 +52321 3 52304 1 0 1 +52321 4 17 47622 18 0 1 +52361 1 52355 1 +52361 2 6 52358 1 +52361 3 52355 2 0 1 +52361 4 6 28483 0 0 1 +52363 1 52358 1 +52363 2 5 52362 1 +52363 3 52358 1 0 1 +52363 4 5 52344 20 0 1 +52369 1 52356 1 +52369 2 13 52358 1 +52369 3 52356 5 0 1 +52369 4 13 50272 34 0 1 +52379 1 52377 1 +52379 2 2 52378 1 +52379 3 52377 4 0 1 +52379 4 2 49810 2 0 1 +52387 1 52385 1 +52387 2 2 52386 1 +52387 3 52385 2 0 1 +52387 4 2 45789 2 0 1 +52391 1 52380 1 +52391 2 11 52388 1 +52391 3 52380 4 0 1 +52391 4 11 40163 5 0 1 +52433 1 52430 1 +52433 2 3 52432 1 +52433 3 52430 4 0 1 +52433 4 3 31887 4 0 1 +52453 1 52451 1 +52453 2 2 52449 1 +52453 3 52451 5 0 1 +52453 4 2 51995 10 0 1 +52457 1 52454 1 +52457 2 3 52451 1 +52457 3 52454 3 0 1 +52457 4 3 49747 1 0 1 +52489 1 52482 1 +52489 2 7 52482 1 +52489 3 52482 8 0 1 +52489 4 7 39696 0 0 1 +52501 1 52491 1 +52501 2 10 52500 1 +52501 3 52491 3 0 1 +52501 4 10 27307 15 0 1 +52511 1 52504 1 +52511 2 7 52510 1 +52511 3 52504 1 0 1 +52511 4 7 28612 3 0 1 +52517 1 52515 1 +52517 2 2 52511 1 +52517 3 52515 9 0 1 +52517 4 2 32464 1 0 1 +52529 1 52526 1 +52529 2 3 52523 1 +52529 3 52526 17 0 1 +52529 4 3 52517 0 0 1 +52541 1 52539 1 +52541 2 2 52540 1 +52541 3 52539 3 0 1 +52541 4 2 45653 4 0 1 +52543 1 52540 1 +52543 2 3 52542 1 +52543 3 52540 9 0 1 +52543 4 3 30071 2 0 1 +52553 1 52550 1 +52553 2 3 52548 1 +52553 3 52550 1 0 1 +52553 4 3 49860 10 0 1 +52561 1 52554 1 +52561 2 7 52554 1 +52561 3 52554 3 0 1 +52561 4 7 50303 0 0 1 +52567 1 52564 1 +52567 2 3 52565 1 +52567 3 52564 1 0 1 +52567 4 3 52563 4 0 1 +52571 1 52569 1 +52571 2 2 52566 1 +52571 3 52569 3 0 1 +52571 4 2 42415 3 0 1 +52579 1 52577 1 +52579 2 2 52572 1 +52579 3 52577 6 0 1 +52579 4 2 49320 4 0 1 +52583 1 52578 1 +52583 2 5 52582 1 +52583 3 52578 2 0 1 +52583 4 5 44395 2 0 1 +52609 1 52598 1 +52609 2 11 52608 1 +52609 3 52598 2 0 1 +52609 4 11 28702 12 0 1 +52627 1 52624 1 +52627 2 3 52620 1 +52627 3 52624 1 0 1 +52627 4 3 51978 2 0 1 +52631 1 52618 1 +52631 2 13 52630 1 +52631 3 52618 5 0 1 +52631 4 13 41479 2 0 1 +52639 1 52636 1 +52639 2 3 52637 1 +52639 3 52636 8 0 1 +52639 4 3 52635 4 0 1 +52667 1 52665 1 +52667 2 2 52663 1 +52667 3 52665 2 0 1 +52667 4 2 32868 14 0 1 +52673 1 52670 1 +52673 2 3 52666 1 +52673 3 52670 1 0 1 +52673 4 3 50520 2 0 1 +52691 1 52689 1 +52691 2 2 52687 1 +52691 3 52689 2 0 1 +52691 4 2 31262 7 0 1 +52697 1 52694 1 +52697 2 3 52696 1 +52697 3 52694 5 0 1 +52697 4 3 30819 4 0 1 +52709 1 52707 1 +52709 2 2 52708 1 +52709 3 52707 3 0 1 +52709 4 2 45603 3 0 1 +52711 1 52688 1 +52711 2 23 52709 1 +52711 3 52688 6 0 1 +52711 4 23 27839 3 0 1 +52721 1 52718 1 +52721 2 3 52716 1 +52721 3 52718 3 0 1 +52721 4 3 28804 2 0 1 +52727 1 52722 1 +52727 2 5 52722 1 +52727 3 52722 14 0 1 +52727 4 5 28078 9 0 1 +52733 1 52731 1 +52733 2 2 52729 1 +52733 3 52731 3 0 1 +52733 4 2 37759 9 0 1 +52747 1 52744 1 +52747 2 3 52746 1 +52747 3 52744 6 0 1 +52747 4 3 30461 5 0 1 +52757 1 52755 1 +52757 2 2 52753 1 +52757 3 52755 2 0 1 +52757 4 2 34759 1 0 1 +52769 1 52766 1 +52769 2 3 52761 1 +52769 3 52766 3 0 1 +52769 4 3 51298 2 0 1 +52783 1 52778 1 +52783 2 5 52781 1 +52783 3 52778 1 0 1 +52783 4 5 52779 3 0 1 +52807 1 52802 1 +52807 2 5 52804 1 +52807 3 52802 1 0 1 +52807 4 5 49469 0 0 1 +52813 1 52811 1 +52813 2 2 52812 1 +52813 3 52811 2 0 1 +52813 4 2 39817 7 0 1 +52817 1 52814 1 +52817 2 3 52816 1 +52817 3 52814 11 0 1 +52817 4 3 44518 4 0 1 +52837 1 52835 1 +52837 2 2 52833 1 +52837 3 52835 6 0 1 +52837 4 2 39891 10 0 1 +52859 1 52853 1 +52859 2 6 52858 1 +52859 3 52853 1 0 1 +52859 4 6 30636 5 0 1 +52861 1 52850 1 +52861 2 11 52859 1 +52861 3 52850 1 0 1 +52861 4 11 38349 0 0 1 +52879 1 52876 1 +52879 2 3 52878 1 +52879 3 52876 1 0 1 +52879 4 3 30897 3 0 1 +52883 1 52881 1 +52883 2 2 52879 1 +52883 3 52881 2 0 1 +52883 4 2 38001 14 0 1 +52889 1 52886 1 +52889 2 3 52880 1 +52889 3 52886 1 0 1 +52889 4 3 29129 3 0 1 +52901 1 52898 1 +52901 2 3 52899 1 +52901 3 52898 5 0 1 +52901 4 3 52897 4 0 1 +52903 1 52900 1 +52903 2 3 52901 1 +52903 3 52900 4 0 1 +52903 4 3 38242 6 0 1 +52919 1 52908 1 +52919 2 11 52918 1 +52919 3 52908 2 0 1 +52919 4 11 34050 4 0 1 +52937 1 52932 1 +52937 2 5 52936 1 +52937 3 52932 3 0 1 +52937 4 5 29372 6 0 1 +52951 1 52948 1 +52951 2 3 52950 1 +52951 3 52948 4 0 1 +52951 4 3 29695 3 0 1 +52957 1 52952 1 +52957 2 5 52952 1 +52957 3 52952 2 0 1 +52957 4 5 41398 11 0 1 +52963 1 52960 1 +52963 2 3 52954 1 +52963 3 52960 3 0 1 +52963 4 3 45941 10 0 1 +52967 1 52962 1 +52967 2 5 52965 1 +52967 3 52962 1 0 1 +52967 4 5 52963 3 0 1 +52973 1 52971 1 +52973 2 2 52969 1 +52973 3 52971 3 0 1 +52973 4 2 46099 9 0 1 +52981 1 52979 1 +52981 2 2 52980 1 +52981 3 52979 4 0 1 +52981 4 2 51763 9 0 1 +52999 1 52996 1 +52999 2 3 52994 1 +52999 3 52996 1 0 1 +52999 4 3 40493 6 0 1 +53003 1 53001 1 +53003 2 2 52999 1 +53003 3 53001 3 0 1 +53003 4 2 44042 7 0 1 +53017 1 53012 1 +53017 2 5 53014 1 +53017 3 53012 1 0 1 +53017 4 5 35010 10 0 1 +53047 1 53044 1 +53047 2 3 53045 1 +53047 3 53044 1 0 1 +53047 4 3 27313 3 0 1 +53051 1 53045 1 +53051 2 6 53048 1 +53051 3 53045 3 0 1 +53051 4 6 35622 4 0 1 +53069 1 53067 1 +53069 2 2 53065 1 +53069 3 53067 3 0 1 +53069 4 2 48916 6 0 1 +53077 1 53075 1 +53077 2 2 53076 1 +53077 3 53075 2 0 1 +53077 4 2 50322 3 0 1 +53087 1 53082 1 +53087 2 5 53085 1 +53087 3 53082 1 0 1 +53087 4 5 53083 3 0 1 +53089 1 53058 1 +53089 2 31 53088 1 +53089 3 53058 3 0 1 +53089 4 31 34721 24 0 1 +53093 1 53091 1 +53093 2 2 53092 1 +53093 3 53091 2 0 1 +53093 4 2 50859 3 0 1 +53101 1 53099 1 +53101 2 2 53100 1 +53101 3 53099 5 0 1 +53101 4 2 32404 7 0 1 +53113 1 53108 1 +53113 2 5 53112 1 +53113 3 53108 1 0 1 +53113 4 5 47333 18 0 1 +53117 1 53115 1 +53117 2 2 53113 1 +53117 3 53115 3 0 1 +53117 4 2 28531 12 0 1 +53129 1 53126 1 +53129 2 3 53128 1 +53129 3 53126 3 0 1 +53129 4 3 38670 7 0 1 +53147 1 53145 1 +53147 2 2 53146 1 +53147 3 53145 3 0 1 +53147 4 2 30289 2 0 1 +53149 1 53143 1 +53149 2 6 53148 1 +53149 3 53143 7 0 1 +53149 4 6 35954 7 0 1 +53161 1 53147 1 +53161 2 14 53156 1 +53161 3 53147 2 0 1 +53161 4 14 46763 19 0 1 +53171 1 53169 1 +53171 2 2 53170 1 +53171 3 53169 3 0 1 +53171 4 2 48565 2 0 1 +53173 1 53155 1 +53173 2 18 53171 1 +53173 3 53155 1 0 1 +53173 4 18 49287 0 0 1 +53189 1 53187 1 +53189 2 2 53188 1 +53189 3 53187 3 0 1 +53189 4 2 46605 4 0 1 +53197 1 53195 1 +53197 2 2 53193 1 +53197 3 53195 4 0 1 +53197 4 2 31752 9 0 1 +53201 1 53198 1 +53201 2 3 53195 1 +53201 3 53198 4 0 1 +53201 4 3 53189 0 0 1 +53231 1 53208 1 +53231 2 23 53230 1 +53231 3 53208 1 0 1 +53231 4 23 37258 7 0 1 +53233 1 53228 1 +53233 2 5 53232 1 +53233 3 53228 8 0 1 +53233 4 5 34161 6 0 1 +53239 1 53236 1 +53239 2 3 53238 1 +53239 3 53236 1 0 1 +53239 4 3 45917 2 0 1 +53267 1 53265 1 +53267 2 2 53263 1 +53267 3 53265 3 0 1 +53267 4 2 46483 8 0 1 +53269 1 53262 1 +53269 2 7 53266 1 +53269 3 53262 4 0 1 +53269 4 7 50668 5 0 1 +53279 1 53272 1 +53279 2 7 53278 1 +53279 3 53272 1 0 1 +53279 4 7 41917 2 0 1 +53281 1 53270 1 +53281 2 11 53270 1 +53281 3 53270 1 0 1 +53281 4 11 34812 24 0 1 +53299 1 53297 1 +53299 2 2 53295 1 +53299 3 53297 4 0 1 +53299 4 2 38727 8 0 1 +53309 1 53307 1 +53309 2 2 53301 1 +53309 3 53307 2 0 1 +53309 4 2 27768 0 0 1 +53323 1 53321 1 +53323 2 2 53319 1 +53323 3 53321 6 0 1 +53323 4 2 30154 14 0 1 +53327 1 53322 1 +53327 2 5 53324 1 +53327 3 53322 2 0 1 +53327 4 5 42727 4 0 1 +53353 1 53346 1 +53353 2 7 53346 1 +53353 3 53346 1 0 1 +53353 4 7 38054 17 0 1 +53359 1 53356 1 +53359 2 3 53357 1 +53359 3 53356 5 0 1 +53359 4 3 52435 6 0 1 +53377 1 53372 1 +53377 2 5 53372 1 +53377 3 53372 2 0 1 +53377 4 5 39744 10 0 1 +53381 1 53379 1 +53381 2 2 53380 1 +53381 3 53379 8 0 1 +53381 4 2 29714 9 0 1 +53401 1 53394 1 +53401 2 7 53394 1 +53401 3 53394 2 0 1 +53401 4 7 39557 0 0 1 +53407 1 53402 1 +53407 2 5 53405 1 +53407 3 53402 2 0 1 +53407 4 5 53403 3 0 1 +53411 1 53409 1 +53411 2 2 53407 1 +53411 3 53409 2 0 1 +53411 4 2 42544 8 0 1 +53419 1 53417 1 +53419 2 2 53415 1 +53419 3 53417 6 0 1 +53419 4 2 30159 8 0 1 +53437 1 53435 1 +53437 2 2 53436 1 +53437 3 53435 6 0 1 +53437 4 2 30309 3 0 1 +53441 1 53438 1 +53441 2 3 53436 1 +53441 3 53438 1 0 1 +53441 4 3 32629 2 0 1 +53453 1 53451 1 +53453 2 2 53449 1 +53453 3 53451 3 0 1 +53453 4 2 36781 6 0 1 +53479 1 53476 1 +53479 2 3 53478 1 +53479 3 53476 5 0 1 +53479 4 3 51225 2 0 1 +53503 1 53500 1 +53503 2 3 53501 1 +53503 3 53500 4 0 1 +53503 4 3 34581 3 0 1 +53507 1 53505 1 +53507 2 2 53506 1 +53507 3 53505 2 0 1 +53507 4 2 47738 2 0 1 +53527 1 53524 1 +53527 2 3 53525 1 +53527 3 53524 7 0 1 +53527 4 3 53523 4 0 1 +53549 1 53547 1 +53549 2 2 53548 1 +53549 3 53547 4 0 1 +53549 4 2 42415 4 0 1 +53551 1 53548 1 +53551 2 3 53549 1 +53551 3 53548 1 0 1 +53551 4 3 33763 6 0 1 +53569 1 53550 1 +53569 2 19 53550 1 +53569 3 53550 5 0 1 +53569 4 19 30483 0 0 1 +53591 1 53578 1 +53591 2 13 53589 1 +53591 3 53578 4 0 1 +53591 4 13 33693 4 0 1 +53593 1 53588 1 +53593 2 5 53592 1 +53593 3 53588 10 0 1 +53593 4 5 32222 6 0 1 +53597 1 53595 1 +53597 2 2 53593 1 +53597 3 53595 3 0 1 +53597 4 2 52044 11 0 1 +53609 1 53606 1 +53609 2 3 53608 1 +53609 3 53606 6 0 1 +53609 4 3 47985 7 0 1 +53611 1 53601 1 +53611 2 10 53609 1 +53611 3 53601 8 0 1 +53611 4 10 27407 0 0 1 +53617 1 53612 1 +53617 2 5 53616 1 +53617 3 53612 2 0 1 +53617 4 5 31561 6 0 1 +53623 1 53620 1 +53623 2 3 53621 1 +53623 3 53620 4 0 1 +53623 4 3 53619 4 0 1 +53629 1 53623 1 +53629 2 6 53621 1 +53629 3 53623 9 0 1 +53629 4 6 30991 0 0 1 +53633 1 53630 1 +53633 2 3 53632 1 +53633 3 53630 1 0 1 +53633 4 3 27294 7 0 1 +53639 1 53628 1 +53639 2 11 53638 1 +53639 3 53628 4 0 1 +53639 4 11 47011 2 0 1 +53653 1 53651 1 +53653 2 2 53652 1 +53653 3 53651 2 0 1 +53653 4 2 47442 3 0 1 +53657 1 53654 1 +53657 2 3 53652 1 +53657 3 53654 6 0 1 +53657 4 3 31526 0 0 1 +53681 1 53678 1 +53681 2 3 53675 1 +53681 3 53678 6 0 1 +53681 4 3 53669 0 0 1 +53693 1 53691 1 +53693 2 2 53692 1 +53693 3 53691 3 0 1 +53693 4 2 33623 3 0 1 +53699 1 53697 1 +53699 2 2 53695 1 +53699 3 53697 9 0 1 +53699 4 2 28092 9 0 1 +53717 1 53715 1 +53717 2 2 53716 1 +53717 3 53715 2 0 1 +53717 4 2 36983 6 0 1 +53719 1 53713 1 +53719 2 6 53718 1 +53719 3 53713 2 0 1 +53719 4 6 28206 3 0 1 +53731 1 53719 1 +53731 2 12 53729 1 +53731 3 53719 1 0 1 +53731 4 12 29169 6 0 1 +53759 1 53742 1 +53759 2 17 53757 1 +53759 3 53742 2 0 1 +53759 4 17 53751 3 0 1 +53773 1 53771 1 +53773 2 2 53772 1 +53773 3 53771 2 0 1 +53773 4 2 34710 6 0 1 +53777 1 53774 1 +53777 2 3 53771 1 +53777 3 53774 1 0 1 +53777 4 3 42831 16 0 1 +53783 1 53778 1 +53783 2 5 53782 1 +53783 3 53778 9 0 1 +53783 4 5 32552 3 0 1 +53791 1 53785 1 +53791 2 6 53790 1 +53791 3 53785 3 0 1 +53791 4 6 27401 2 0 1 +53813 1 53811 1 +53813 2 2 53805 1 +53813 3 53811 8 0 1 +53813 4 2 28837 3 0 1 +53819 1 53817 1 +53819 2 2 53814 1 +53819 3 53817 7 0 1 +53819 4 2 48668 3 0 1 +53831 1 53824 1 +53831 2 7 53827 1 +53831 3 53824 4 0 1 +53831 4 7 40011 5 0 1 +53849 1 53846 1 +53849 2 3 53843 1 +53849 3 53846 8 0 1 +53849 4 3 53837 0 0 1 +53857 1 53852 1 +53857 2 5 53852 1 +53857 3 53852 3 0 1 +53857 4 5 49534 15 0 1 +53861 1 53859 1 +53861 2 2 53860 1 +53861 3 53859 5 0 1 +53861 4 2 53342 9 0 1 +53881 1 53850 1 +53881 2 31 53880 1 +53881 3 53850 1 0 1 +53881 4 31 43513 24 0 1 +53887 1 53884 1 +53887 2 3 53885 1 +53887 3 53884 8 0 1 +53887 4 3 41551 3 0 1 +53891 1 53889 1 +53891 2 2 53883 1 +53891 3 53889 4 0 1 +53891 4 2 42377 2 0 1 +53897 1 53894 1 +53897 2 3 53896 1 +53897 3 53894 4 0 1 +53897 4 3 53127 4 0 1 +53899 1 53897 1 +53899 2 2 53895 1 +53899 3 53897 5 0 1 +53899 4 2 37119 1 0 1 +53917 1 53915 1 +53917 2 2 53916 1 +53917 3 53915 2 0 1 +53917 4 2 34912 7 0 1 +53923 1 53918 1 +53923 2 5 53921 1 +53923 3 53918 5 0 1 +53923 4 5 53915 6 0 1 +53927 1 53922 1 +53927 2 5 53925 1 +53927 3 53922 1 0 1 +53927 4 5 53923 3 0 1 +53939 1 53937 1 +53939 2 2 53933 1 +53939 3 53937 2 0 1 +53939 4 2 43058 4 0 1 +53951 1 53944 1 +53951 2 7 53950 1 +53951 3 53944 3 0 1 +53951 4 7 53942 4 0 1 +53959 1 53956 1 +53959 2 3 53957 1 +53959 3 53956 4 0 1 +53959 4 3 47291 3 0 1 +53987 1 53985 1 +53987 2 2 53986 1 +53987 3 53985 2 0 1 +53987 4 2 51795 4 0 1 +53993 1 53990 1 +53993 2 3 53984 1 +53993 3 53990 4 0 1 +53993 4 3 32327 3 0 1 +54001 1 53990 1 +54001 2 11 53998 1 +54001 3 53990 4 0 1 +54001 4 11 38898 14 0 1 +54011 1 54009 1 +54011 2 2 54004 1 +54011 3 54009 5 0 1 +54011 4 2 47801 1 0 1 +54013 1 54008 1 +54013 2 5 54012 1 +54013 3 54008 1 0 1 +54013 4 5 53278 6 0 1 +54037 1 54035 1 +54037 2 2 54033 1 +54037 3 54035 4 0 1 +54037 4 2 33218 6 0 1 +54049 1 54038 1 +54049 2 11 54044 1 +54049 3 54038 2 0 1 +54049 4 11 34837 22 0 1 +54059 1 54057 1 +54059 2 2 54058 1 +54059 3 54057 3 0 1 +54059 4 2 35508 2 0 1 +54083 1 54081 1 +54083 2 2 54079 1 +54083 3 54081 3 0 1 +54083 4 2 33127 7 0 1 +54091 1 54088 1 +54091 2 3 54086 1 +54091 3 54088 8 0 1 +54091 4 3 31288 3 0 1 +54101 1 54098 1 +54101 2 3 54099 1 +54101 3 54098 1 0 1 +54101 4 3 54097 4 0 1 +54121 1 54108 1 +54121 2 13 54120 1 +54121 3 54108 9 0 1 +54121 4 13 41494 14 0 1 +54133 1 54128 1 +54133 2 5 54132 1 +54133 3 54128 5 0 1 +54133 4 5 31507 6 0 1 +54139 1 54137 1 +54139 2 2 54135 1 +54139 3 54137 6 0 1 +54139 4 2 53333 8 0 1 +54151 1 54145 1 +54151 2 6 54149 1 +54151 3 54145 3 0 1 +54151 4 6 39340 3 0 1 +54163 1 54161 1 +54163 2 2 54159 1 +54163 3 54161 6 0 1 +54163 4 2 49878 8 0 1 +54167 1 54162 1 +54167 2 5 54165 1 +54167 3 54162 2 0 1 +54167 4 5 39230 8 0 1 +54181 1 54179 1 +54181 2 2 54177 1 +54181 3 54179 2 0 1 +54181 4 2 29314 12 0 1 +54193 1 54183 1 +54193 2 10 54188 1 +54193 3 54183 2 0 1 +54193 4 10 53577 12 0 1 +54217 1 54212 1 +54217 2 5 54216 1 +54217 3 54212 1 0 1 +54217 4 5 41596 6 0 1 +54251 1 54249 1 +54251 2 2 54247 1 +54251 3 54249 3 0 1 +54251 4 2 35571 8 0 1 +54269 1 54267 1 +54269 2 2 54264 1 +54269 3 54267 4 0 1 +54269 4 2 52348 8 0 1 +54277 1 54272 1 +54277 2 5 54276 1 +54277 3 54272 2 0 1 +54277 4 5 46093 3 0 1 +54287 1 54282 1 +54287 2 5 54285 1 +54287 3 54282 5 0 1 +54287 4 5 54283 3 0 1 +54293 1 54291 1 +54293 2 2 54288 1 +54293 3 54291 5 0 1 +54293 4 2 52801 2 0 1 +54311 1 54300 1 +54311 2 11 54310 1 +54311 3 54300 2 0 1 +54311 4 11 35318 10 0 1 +54319 1 54316 1 +54319 2 3 54317 1 +54319 3 54316 4 0 1 +54319 4 3 46010 6 0 1 +54323 1 54321 1 +54323 2 2 54319 1 +54323 3 54321 2 0 1 +54323 4 2 53550 7 0 1 +54331 1 54329 1 +54331 2 2 54327 1 +54331 3 54329 2 0 1 +54331 4 2 48975 8 0 1 +54347 1 54345 1 +54347 2 2 54343 1 +54347 3 54345 2 0 1 +54347 4 2 36691 11 0 1 +54361 1 54354 1 +54361 2 7 54358 1 +54361 3 54354 1 0 1 +54361 4 7 51839 16 0 1 +54367 1 54362 1 +54367 2 5 54366 1 +54367 3 54362 10 0 1 +54367 4 5 43976 2 0 1 +54371 1 54365 1 +54371 2 6 54370 1 +54371 3 54365 10 0 1 +54371 4 6 51692 4 0 1 +54377 1 54372 1 +54377 2 5 54370 1 +54377 3 54372 9 0 1 +54377 4 5 51708 1 0 1 +54401 1 54398 1 +54401 2 3 54400 1 +54401 3 54398 1 0 1 +54401 4 3 32412 4 0 1 +54403 1 54401 1 +54403 2 2 54399 1 +54403 3 54401 2 0 1 +54403 4 2 42818 1 0 1 +54409 1 54402 1 +54409 2 7 54406 1 +54409 3 54402 7 0 1 +54409 4 7 40433 17 0 1 +54413 1 54411 1 +54413 2 2 54406 1 +54413 3 54411 10 0 1 +54413 4 2 37262 4 0 1 +54419 1 54417 1 +54419 2 2 54415 1 +54419 3 54417 2 0 1 +54419 4 2 44995 8 0 1 +54421 1 54419 1 +54421 2 2 54420 1 +54421 3 54419 6 0 1 +54421 4 2 54414 8 0 1 +54437 1 54435 1 +54437 2 2 54432 1 +54437 3 54435 2 0 1 +54437 4 2 40155 0 0 1 +54443 1 54441 1 +54443 2 2 54439 1 +54443 3 54441 3 0 1 +54443 4 2 27730 8 0 1 +54449 1 54446 1 +54449 2 3 54442 1 +54449 3 54446 3 0 1 +54449 4 3 36474 0 0 1 +54469 1 54467 1 +54469 2 2 54465 1 +54469 3 54467 2 0 1 +54469 4 2 28084 12 0 1 +54493 1 54491 1 +54493 2 2 54492 1 +54493 3 54491 6 0 1 +54493 4 2 28709 9 0 1 +54497 1 54494 1 +54497 2 3 54483 1 +54497 3 54494 1 0 1 +54497 4 3 52734 4 0 1 +54499 1 54496 1 +54499 2 3 54492 1 +54499 3 54496 1 0 1 +54499 4 3 37260 5 0 1 +54503 1 54496 1 +54503 2 7 54501 1 +54503 3 54496 10 0 1 +54503 4 7 47550 4 0 1 +54517 1 54512 1 +54517 2 5 54512 1 +54517 3 54512 6 0 1 +54517 4 5 41098 23 0 1 +54521 1 54518 1 +54521 2 3 54514 1 +54521 3 54518 4 0 1 +54521 4 3 31723 4 0 1 +54539 1 54537 1 +54539 2 2 54533 1 +54539 3 54537 7 0 1 +54539 4 2 31098 4 0 1 +54541 1 54539 1 +54541 2 2 54537 1 +54541 3 54539 2 0 1 +54541 4 2 45092 6 0 1 +54547 1 54544 1 +54547 2 3 54538 1 +54547 3 54544 1 0 1 +54547 4 3 52356 4 0 1 +54559 1 54556 1 +54559 2 3 54558 1 +54559 3 54556 1 0 1 +54559 4 3 53941 2 0 1 +54563 1 54561 1 +54563 2 2 54559 1 +54563 3 54561 2 0 1 +54563 4 2 52815 7 0 1 +54577 1 54572 1 +54577 2 5 54574 1 +54577 3 54572 1 0 1 +54577 4 5 54566 14 0 1 +54581 1 54571 1 +54581 2 10 54578 1 +54581 3 54571 8 0 1 +54581 4 10 52377 0 0 1 +54583 1 54578 1 +54583 2 5 54582 1 +54583 3 54578 2 0 1 +54583 4 5 41655 3 0 1 +54601 1 54579 1 +54601 2 22 54598 1 +54601 3 54579 2 0 1 +54601 4 22 52577 22 0 1 +54617 1 54614 1 +54617 2 3 54616 1 +54617 3 54614 4 0 1 +54617 4 3 49252 7 0 1 +54623 1 54618 1 +54623 2 5 54620 1 +54623 3 54618 1 0 1 +54623 4 5 35656 4 0 1 +54629 1 54626 1 +54629 2 3 54627 1 +54629 3 54626 7 0 1 +54629 4 3 38672 12 0 1 +54631 1 54625 1 +54631 2 6 54629 1 +54631 3 54625 2 0 1 +54631 4 6 32685 3 0 1 +54647 1 54642 1 +54647 2 5 54642 1 +54647 3 54642 3 0 1 +54647 4 5 48318 7 0 1 +54667 1 54665 1 +54667 2 2 54663 1 +54667 3 54665 6 0 1 +54667 4 2 30127 13 0 1 +54673 1 54668 1 +54673 2 5 54672 1 +54673 3 54668 2 0 1 +54673 4 5 48898 6 0 1 +54679 1 54672 1 +54679 2 7 54667 1 +54679 3 54672 1 0 1 +54679 4 7 48374 0 0 1 +54709 1 54707 1 +54709 2 2 54705 1 +54709 3 54707 2 0 1 +54709 4 2 54186 6 0 1 +54713 1 54708 1 +54713 2 5 54712 1 +54713 3 54708 3 0 1 +54713 4 5 44310 6 0 1 +54721 1 54710 1 +54721 2 11 54712 1 +54721 3 54710 1 0 1 +54721 4 11 45297 20 0 1 +54727 1 54724 1 +54727 2 3 54726 1 +54727 3 54724 1 0 1 +54727 4 3 51959 5 0 1 +54751 1 54745 1 +54751 2 6 54749 1 +54751 3 54745 3 0 1 +54751 4 6 54741 7 0 1 +54767 1 54762 1 +54767 2 5 54765 1 +54767 3 54762 1 0 1 +54767 4 5 36070 5 0 1 +54773 1 54771 1 +54773 2 2 54766 1 +54773 3 54771 2 0 1 +54773 4 2 49710 2 0 1 +54779 1 54777 1 +54779 2 2 54775 1 +54779 3 54777 2 0 1 +54779 4 2 37806 8 0 1 +54787 1 54785 1 +54787 2 2 54786 1 +54787 3 54785 6 0 1 +54787 4 2 40532 7 0 1 +54799 1 54796 1 +54799 2 3 54798 1 +54799 3 54796 3 0 1 +54799 4 3 31708 2 0 1 +54829 1 54827 1 +54829 2 2 54828 1 +54829 3 54827 4 0 1 +54829 4 2 54822 8 0 1 +54833 1 54830 1 +54833 2 3 54827 1 +54833 3 54830 11 0 1 +54833 4 3 51648 1 0 1 +54851 1 54845 1 +54851 2 6 54849 1 +54851 3 54845 3 0 1 +54851 4 6 44707 15 0 1 +54869 1 54867 1 +54869 2 2 54868 1 +54869 3 54867 3 0 1 +54869 4 2 49807 4 0 1 +54877 1 54875 1 +54877 2 2 54873 1 +54877 3 54875 4 0 1 +54877 4 2 49718 12 0 1 +54881 1 54878 1 +54881 2 3 54880 1 +54881 3 54878 9 0 1 +54881 4 3 47900 4 0 1 +54907 1 54905 1 +54907 2 2 54906 1 +54907 3 54905 2 0 1 +54907 4 2 38476 7 0 1 +54917 1 54915 1 +54917 2 2 54909 1 +54917 3 54915 8 0 1 +54917 4 2 41903 5 0 1 +54919 1 54916 1 +54919 2 3 54918 1 +54919 3 54916 4 0 1 +54919 4 3 42837 3 0 1 +54941 1 54939 1 +54941 2 2 54940 1 +54941 3 54939 5 0 1 +54941 4 2 50581 3 0 1 +54949 1 54947 1 +54949 2 2 54948 1 +54949 3 54947 4 0 1 +54949 4 2 54942 8 0 1 +54959 1 54952 1 +54959 2 7 54958 1 +54959 3 54952 1 0 1 +54959 4 7 31117 2 0 1 +54973 1 54959 1 +54973 2 14 54970 1 +54973 3 54959 5 0 1 +54973 4 14 30370 1 0 1 +54979 1 54976 1 +54979 2 3 54974 1 +54979 3 54976 1 0 1 +54979 4 3 42920 3 0 1 +54983 1 54978 1 +54983 2 5 54978 1 +54983 3 54978 2 0 1 +54983 4 5 48837 6 0 1 +55001 1 54998 1 +55001 2 3 54996 1 +55001 3 54998 4 0 1 +55001 4 3 40914 8 0 1 +55009 1 55002 1 +55009 2 7 54998 1 +55009 3 55002 11 0 1 +55009 4 7 38608 24 0 1 +55021 1 55015 1 +55021 2 6 55020 1 +55021 3 55015 2 0 1 +55021 4 6 28224 7 0 1 +55049 1 55043 1 +55049 2 6 55048 1 +55049 3 55043 2 0 1 +55049 4 6 45962 4 0 1 +55051 1 55049 1 +55051 2 2 55050 1 +55051 3 55049 6 0 1 +55051 4 2 35693 2 0 1 +55057 1 55047 1 +55057 2 10 55056 1 +55057 3 55047 5 0 1 +55057 4 10 38627 12 0 1 +55061 1 55059 1 +55061 2 2 55060 1 +55061 3 55059 4 0 1 +55061 4 2 33619 3 0 1 +55073 1 55070 1 +55073 2 3 55072 1 +55073 3 55070 3 0 1 +55073 4 3 38454 7 0 1 +55079 1 55066 1 +55079 2 13 55078 1 +55079 3 55066 1 0 1 +55079 4 13 37766 2 0 1 +55103 1 55098 1 +55103 2 5 55102 1 +55103 3 55098 1 0 1 +55103 4 5 48476 3 0 1 +55109 1 55107 1 +55109 2 2 55098 1 +55109 3 55107 4 0 1 +55109 4 2 35765 9 0 1 +55117 1 55112 1 +55117 2 5 55114 1 +55117 3 55112 10 0 1 +55117 4 5 40725 1 0 1 +55127 1 55122 1 +55127 2 5 55125 1 +55127 3 55122 1 0 1 +55127 4 5 40534 5 0 1 +55147 1 55142 1 +55147 2 5 55145 1 +55147 3 55142 2 0 1 +55147 4 5 55143 3 0 1 +55163 1 55161 1 +55163 2 2 55162 1 +55163 3 55161 3 0 1 +55163 4 2 49605 13 0 1 +55171 1 55161 1 +55171 2 10 55169 1 +55171 3 55161 2 0 1 +55171 4 10 38724 13 0 1 +55201 1 55194 1 +55201 2 7 55194 1 +55201 3 55194 1 0 1 +55201 4 7 51398 0 0 1 +55207 1 55202 1 +55207 2 5 55206 1 +55207 3 55202 1 0 1 +55207 4 5 44099 2 0 1 +55213 1 55211 1 +55213 2 2 55209 1 +55213 3 55211 5 0 1 +55213 4 2 48748 6 0 1 +55217 1 55214 1 +55217 2 3 55216 1 +55217 3 55214 1 0 1 +55217 4 3 50697 11 0 1 +55219 1 55217 1 +55219 2 2 55218 1 +55219 3 55217 4 0 1 +55219 4 2 28415 2 0 1 +55229 1 55227 1 +55229 2 2 55223 1 +55229 3 55227 4 0 1 +55229 4 2 38844 4 0 1 +55243 1 55241 1 +55243 2 2 55242 1 +55243 3 55241 2 0 1 +55243 4 2 50554 2 0 1 +55249 1 55238 1 +55249 2 11 55248 1 +55249 3 55238 2 0 1 +55249 4 11 51344 8 0 1 +55259 1 55253 1 +55259 2 6 55249 1 +55259 3 55253 2 0 1 +55259 4 6 46182 0 0 1 +55291 1 55280 1 +55291 2 11 55288 1 +55291 3 55280 1 0 1 +55291 4 11 29304 0 0 1 +55313 1 55310 1 +55313 2 3 55308 1 +55313 3 55310 4 0 1 +55313 4 3 52824 0 0 1 +55331 1 55329 1 +55331 2 2 55330 1 +55331 3 55329 7 0 1 +55331 4 2 47533 6 0 1 +55333 1 55327 1 +55333 2 6 55331 1 +55333 3 55327 2 0 1 +55333 4 6 37793 8 0 1 +55337 1 55334 1 +55337 2 3 55336 1 +55337 3 55334 1 0 1 +55337 4 3 38163 7 0 1 +55339 1 55337 1 +55339 2 2 55335 1 +55339 3 55337 2 0 1 +55339 4 2 31052 8 0 1 +55343 1 55336 1 +55343 2 7 55339 1 +55343 3 55336 1 0 1 +55343 4 7 55331 16 0 1 +55351 1 55344 1 +55351 2 7 55342 1 +55351 3 55344 13 0 1 +55351 4 7 46608 3 0 1 +55373 1 55371 1 +55373 2 2 55372 1 +55373 3 55371 2 0 1 +55373 4 2 45800 3 0 1 +55381 1 55375 1 +55381 2 6 55380 1 +55381 3 55375 2 0 1 +55381 4 6 41076 11 0 1 +55399 1 55393 1 +55399 2 6 55398 1 +55399 3 55393 2 0 1 +55399 4 6 44143 2 0 1 +55411 1 55409 1 +55411 2 2 55410 1 +55411 3 55409 4 0 1 +55411 4 2 46072 2 0 1 +55439 1 55426 1 +55439 2 13 55437 1 +55439 3 55426 2 0 1 +55439 4 13 42340 4 0 1 +55441 1 55403 1 +55441 2 38 55440 1 +55441 3 55403 1 0 1 +55441 4 38 47380 20 0 1 +55457 1 55454 1 +55457 2 3 55451 1 +55457 3 55454 10 0 1 +55457 4 3 51566 1 0 1 +55469 1 55467 1 +55469 2 2 55460 1 +55469 3 55467 2 0 1 +55469 4 2 34598 1 0 1 +55487 1 55482 1 +55487 2 5 55482 1 +55487 3 55482 2 0 1 +55487 4 5 47865 6 0 1 +55501 1 55495 1 +55501 2 6 55497 1 +55501 3 55495 1 0 1 +55501 4 6 55497 6 0 1 +55511 1 55500 1 +55511 2 11 55509 1 +55511 3 55500 6 0 1 +55511 4 11 45652 5 0 1 +55529 1 55526 1 +55529 2 3 55524 1 +55529 3 55526 3 0 1 +55529 4 3 42741 2 0 1 +55541 1 55539 1 +55541 2 2 55535 1 +55541 3 55539 9 0 1 +55541 4 2 44080 4 0 1 +55547 1 55545 1 +55547 2 2 55541 1 +55547 3 55545 9 0 1 +55547 4 2 29580 4 0 1 +55579 1 55577 1 +55579 2 2 55578 1 +55579 3 55577 6 0 1 +55579 4 2 45669 2 0 1 +55589 1 55587 1 +55589 2 2 55585 1 +55589 3 55587 3 0 1 +55589 4 2 39396 12 0 1 +55603 1 55601 1 +55603 2 2 55599 1 +55603 3 55601 6 0 1 +55603 4 2 32874 8 0 1 +55609 1 55596 1 +55609 2 13 55596 1 +55609 3 55596 1 0 1 +55609 4 13 55570 0 0 1 +55619 1 55617 1 +55619 2 2 55615 1 +55619 3 55617 2 0 1 +55619 4 2 34176 7 0 1 +55621 1 55619 1 +55621 2 2 55620 1 +55621 3 55619 4 0 1 +55621 4 2 39788 7 0 1 +55631 1 55624 1 +55631 2 7 55629 1 +55631 3 55624 1 0 1 +55631 4 7 38577 4 0 1 +55633 1 55628 1 +55633 2 5 55630 1 +55633 3 55628 5 0 1 +55633 4 5 35265 16 0 1 +55639 1 55636 1 +55639 2 3 55637 1 +55639 3 55636 6 0 1 +55639 4 3 46470 6 0 1 +55661 1 55659 1 +55661 2 2 55657 1 +55661 3 55659 5 0 1 +55661 4 2 37283 12 0 1 +55663 1 55660 1 +55663 2 3 55661 1 +55663 3 55660 3 0 1 +55663 4 3 28880 3 0 1 +55667 1 55665 1 +55667 2 2 55663 1 +55667 3 55665 2 0 1 +55667 4 2 51291 13 0 1 +55673 1 55670 1 +55673 2 3 55672 1 +55673 3 55670 1 0 1 +55673 4 3 41377 4 0 1 +55681 1 55670 1 +55681 2 11 55680 1 +55681 3 55670 5 0 1 +55681 4 11 30307 12 0 1 +55691 1 55689 1 +55691 2 2 55690 1 +55691 3 55689 3 0 1 +55691 4 2 44290 2 0 1 +55697 1 55694 1 +55697 2 3 55692 1 +55697 3 55694 1 0 1 +55697 4 3 35089 2 0 1 +55711 1 55708 1 +55711 2 3 55710 1 +55711 3 55708 5 0 1 +55711 4 3 54042 2 0 1 +55717 1 55715 1 +55717 2 2 55713 1 +55717 3 55715 6 0 1 +55717 4 2 45647 9 0 1 +55721 1 55718 1 +55721 2 3 55720 1 +55721 3 55718 13 0 1 +55721 4 3 35341 7 0 1 +55733 1 55731 1 +55733 2 2 55727 1 +55733 3 55731 7 0 1 +55733 4 2 41119 1 0 1 +55763 1 55761 1 +55763 2 2 55757 1 +55763 3 55761 8 0 1 +55763 4 2 32202 4 0 1 +55787 1 55785 1 +55787 2 2 55782 1 +55787 3 55785 5 0 1 +55787 4 2 44917 3 0 1 +55793 1 55790 1 +55793 2 3 55787 1 +55793 3 55790 1 0 1 +55793 4 3 29668 12 0 1 +55799 1 55792 1 +55799 2 7 55797 1 +55799 3 55792 19 0 1 +55799 4 7 28837 5 0 1 +55807 1 55804 1 +55807 2 3 55805 1 +55807 3 55804 5 0 1 +55807 4 3 28470 6 0 1 +55813 1 55811 1 +55813 2 2 55809 1 +55813 3 55811 4 0 1 +55813 4 2 31826 10 0 1 +55817 1 55814 1 +55817 2 3 55805 1 +55817 3 55814 1 0 1 +55817 4 3 48937 0 0 1 +55819 1 55817 1 +55819 2 2 55815 1 +55819 3 55817 2 0 1 +55819 4 2 33154 8 0 1 +55823 1 55818 1 +55823 2 5 55821 1 +55823 3 55818 3 0 1 +55823 4 5 45481 8 0 1 +55829 1 55827 1 +55829 2 2 55825 1 +55829 3 55827 2 0 1 +55829 4 2 33851 7 0 1 +55837 1 55832 1 +55837 2 5 55836 1 +55837 3 55832 14 0 1 +55837 4 5 49246 6 0 1 +55843 1 55841 1 +55843 2 2 55839 1 +55843 3 55841 6 0 1 +55843 4 2 42336 8 0 1 +55849 1 55835 1 +55849 2 14 55846 1 +55849 3 55835 1 0 1 +55849 4 14 46684 10 0 1 +55871 1 55864 1 +55871 2 7 55870 1 +55871 3 55864 4 0 1 +55871 4 7 37071 3 0 1 +55889 1 55886 1 +55889 2 3 55883 1 +55889 3 55886 1 0 1 +55889 4 3 55877 0 0 1 +55897 1 55892 1 +55897 2 5 55896 1 +55897 3 55892 1 0 1 +55897 4 5 41446 12 0 1 +55901 1 55899 1 +55901 2 2 55900 1 +55901 3 55899 3 0 1 +55901 4 2 49020 3 0 1 +55903 1 55892 1 +55903 2 11 55902 1 +55903 3 55892 4 0 1 +55903 4 11 43803 2 0 1 +55921 1 55900 1 +55921 2 21 55920 1 +55921 3 55900 4 0 1 +55921 4 21 43101 8 0 1 +55927 1 55924 1 +55927 2 3 55925 1 +55927 3 55924 4 0 1 +55927 4 3 35633 3 0 1 +55931 1 55925 1 +55931 2 6 55929 1 +55931 3 55925 1 0 1 +55931 4 6 52723 0 0 1 +55933 1 55931 1 +55933 2 2 55932 1 +55933 3 55931 2 0 1 +55933 4 2 48082 6 0 1 +55949 1 55947 1 +55949 2 2 55945 1 +55949 3 55947 3 0 1 +55949 4 2 28239 1 0 1 +55967 1 55962 1 +55967 2 5 55966 1 +55967 3 55962 1 0 1 +55967 4 5 42501 5 0 1 +55987 1 55985 1 +55987 2 2 55983 1 +55987 3 55985 6 0 1 +55987 4 2 36179 8 0 1 +55997 1 55995 1 +55997 2 2 55993 1 +55997 3 55995 3 0 1 +55997 4 2 37684 12 0 1 +56003 1 56001 1 +56003 2 2 56002 1 +56003 3 56001 2 0 1 +56003 4 2 43720 2 0 1 +56009 1 56006 1 +56009 2 3 56001 1 +56009 3 56006 3 0 1 +56009 4 3 43639 2 0 1 +56039 1 56032 1 +56039 2 7 56038 1 +56039 3 56032 3 0 1 +56039 4 7 56030 4 0 1 +56041 1 56034 1 +56041 2 7 56034 1 +56041 3 56034 5 0 1 +56041 4 7 40523 0 0 1 +56053 1 56051 1 +56053 2 2 56049 1 +56053 3 56051 6 0 1 +56053 4 2 49665 9 0 1 +56081 1 56078 1 +56081 2 3 56069 1 +56081 3 56078 6 0 1 +56081 4 3 49974 0 0 1 +56087 1 56082 1 +56087 2 5 56085 1 +56087 3 56082 1 0 1 +56087 4 5 54608 5 0 1 +56093 1 56091 1 +56093 2 2 56089 1 +56093 3 56091 3 0 1 +56093 4 2 50569 6 0 1 +56099 1 56097 1 +56099 2 2 56093 1 +56099 3 56097 2 0 1 +56099 4 2 42982 4 0 1 +56101 1 56094 1 +56101 2 7 56099 1 +56101 3 56094 4 0 1 +56101 4 7 44663 15 0 1 +56113 1 56108 1 +56113 2 5 56110 1 +56113 3 56108 8 0 1 +56113 4 5 51606 16 0 1 +56123 1 56121 1 +56123 2 2 56119 1 +56123 3 56121 3 0 1 +56123 4 2 43350 8 0 1 +56131 1 56129 1 +56131 2 2 56130 1 +56131 3 56129 6 0 1 +56131 4 2 54390 2 0 1 +56149 1 56143 1 +56149 2 6 56141 1 +56149 3 56143 4 0 1 +56149 4 6 55201 0 0 1 +56167 1 56164 1 +56167 2 3 56165 1 +56167 3 56164 4 0 1 +56167 4 3 55693 3 0 1 +56171 1 56169 1 +56171 2 2 56170 1 +56171 3 56169 4 0 1 +56171 4 2 29334 2 0 1 +56179 1 56176 1 +56179 2 3 56174 1 +56179 3 56176 1 0 1 +56179 4 3 54503 3 0 1 +56197 1 56184 1 +56197 2 13 56196 1 +56197 3 56184 2 0 1 +56197 4 13 52594 3 0 1 +56207 1 56202 1 +56207 2 5 56205 1 +56207 3 56202 1 0 1 +56207 4 5 56203 3 0 1 +56209 1 56202 1 +56209 2 7 56202 1 +56209 3 56202 3 0 1 +56209 4 7 54847 0 0 1 +56237 1 56235 1 +56237 2 2 56236 1 +56237 3 56235 3 0 1 +56237 4 2 51506 6 0 1 +56239 1 56236 1 +56239 2 3 56237 1 +56239 3 56236 3 0 1 +56239 4 3 42826 3 0 1 +56249 1 56246 1 +56249 2 3 56244 1 +56249 3 56246 3 0 1 +56249 4 3 51793 2 0 1 +56263 1 56260 1 +56263 2 3 56261 1 +56263 3 56260 1 0 1 +56263 4 3 56259 4 0 1 +56267 1 56265 1 +56267 2 2 56263 1 +56267 3 56265 3 0 1 +56267 4 2 47807 7 0 1 +56269 1 56267 1 +56269 2 2 56268 1 +56269 3 56267 6 0 1 +56269 4 2 40885 7 0 1 +56299 1 56289 1 +56299 2 10 56297 1 +56299 3 56289 6 0 1 +56299 4 10 47088 0 0 1 +56311 1 56305 1 +56311 2 6 56310 1 +56311 3 56305 3 0 1 +56311 4 6 48710 6 0 1 +56333 1 56331 1 +56333 2 2 56328 1 +56333 3 56331 13 0 1 +56333 4 2 44573 0 0 1 +56359 1 56356 1 +56359 2 3 56358 1 +56359 3 56356 3 0 1 +56359 4 3 41399 2 0 1 +56369 1 56366 1 +56369 2 3 56363 1 +56369 3 56366 4 0 1 +56369 4 3 56357 0 0 1 +56377 1 56372 1 +56377 2 5 56374 1 +56377 3 56372 1 0 1 +56377 4 5 53649 23 0 1 +56383 1 56380 1 +56383 2 3 56382 1 +56383 3 56380 1 0 1 +56383 4 3 43205 5 0 1 +56393 1 56390 1 +56393 2 3 56392 1 +56393 3 56390 4 0 1 +56393 4 3 48024 6 0 1 +56401 1 56388 1 +56401 2 13 56400 1 +56401 3 56388 6 0 1 +56401 4 13 31874 14 0 1 +56417 1 56414 1 +56417 2 3 56411 1 +56417 3 56414 1 0 1 +56417 4 3 37285 9 0 1 +56431 1 56428 1 +56431 2 3 56429 1 +56431 3 56428 13 0 1 +56431 4 3 30540 6 0 1 +56437 1 56435 1 +56437 2 2 56436 1 +56437 3 56435 2 0 1 +56437 4 2 43979 3 0 1 +56443 1 56438 1 +56443 2 5 56442 1 +56443 3 56438 3 0 1 +56443 4 5 41908 5 0 1 +56453 1 56451 1 +56453 2 2 56447 1 +56453 3 56451 2 0 1 +56453 4 2 28655 1 0 1 +56467 1 56465 1 +56467 2 2 56466 1 +56467 3 56465 4 0 1 +56467 4 2 32208 2 0 1 +56473 1 56468 1 +56473 2 5 56470 1 +56473 3 56468 2 0 1 +56473 4 5 41277 32 0 1 +56477 1 56475 1 +56477 2 2 56473 1 +56477 3 56475 3 0 1 +56477 4 2 28783 7 0 1 +56479 1 56473 1 +56479 2 6 56478 1 +56479 3 56473 8 0 1 +56479 4 6 31461 3 0 1 +56489 1 56486 1 +56489 2 3 56480 1 +56489 3 56486 10 0 1 +56489 4 3 30320 3 0 1 +56501 1 56498 1 +56501 2 3 56499 1 +56501 3 56498 6 0 1 +56501 4 3 56497 4 0 1 +56503 1 56500 1 +56503 2 3 56502 1 +56503 3 56500 4 0 1 +56503 4 3 35604 2 0 1 +56509 1 56507 1 +56509 2 2 56508 1 +56509 3 56507 4 0 1 +56509 4 2 39742 3 0 1 +56519 1 56506 1 +56519 2 13 56510 1 +56519 3 56506 2 0 1 +56519 4 13 29316 11 0 1 +56527 1 56524 1 +56527 2 3 56525 1 +56527 3 56524 3 0 1 +56527 4 3 47508 3 0 1 +56531 1 56529 1 +56531 2 2 56527 1 +56531 3 56529 3 0 1 +56531 4 2 29045 15 0 1 +56533 1 56528 1 +56533 2 5 56532 1 +56533 3 56528 1 0 1 +56533 4 5 35775 3 0 1 +56543 1 56538 1 +56543 2 5 56541 1 +56543 3 56538 1 0 1 +56543 4 5 56539 3 0 1 +56569 1 56558 1 +56569 2 11 56558 1 +56569 3 56558 1 0 1 +56569 4 11 44961 33 0 1 +56591 1 56572 1 +56591 2 19 56590 1 +56591 3 56572 15 0 1 +56591 4 19 56576 4 0 1 +56597 1 56595 1 +56597 2 2 56590 1 +56597 3 56595 5 0 1 +56597 4 2 45525 5 0 1 +56599 1 56596 1 +56599 2 3 56597 1 +56599 3 56596 3 0 1 +56599 4 3 56595 4 0 1 +56611 1 56585 1 +56611 2 26 56609 1 +56611 3 56585 1 0 1 +56611 4 26 55822 0 0 1 +56629 1 56627 1 +56629 2 2 56628 1 +56629 3 56627 6 0 1 +56629 4 2 56622 8 0 1 +56633 1 56630 1 +56633 2 3 56628 1 +56633 3 56630 1 0 1 +56633 4 3 31538 0 0 1 +56659 1 56657 1 +56659 2 2 56655 1 +56659 3 56657 6 0 1 +56659 4 2 47043 8 0 1 +56663 1 56658 1 +56663 2 5 56661 1 +56663 3 56658 1 0 1 +56663 4 5 56659 3 0 1 +56671 1 56668 1 +56671 2 3 56670 1 +56671 3 56668 3 0 1 +56671 4 3 45827 2 0 1 +56681 1 56678 1 +56681 2 3 56675 1 +56681 3 56678 4 0 1 +56681 4 3 56669 0 0 1 +56687 1 56682 1 +56687 2 5 56686 1 +56687 3 56682 3 0 1 +56687 4 5 44288 4 0 1 +56701 1 56699 1 +56701 2 2 56697 1 +56701 3 56699 2 0 1 +56701 4 2 53689 6 0 1 +56711 1 56704 1 +56711 2 7 56710 1 +56711 3 56704 1 0 1 +56711 4 7 48465 2 0 1 +56713 1 56708 1 +56713 2 5 56710 1 +56713 3 56708 6 0 1 +56713 4 5 41674 10 0 1 +56731 1 56729 1 +56731 2 2 56730 1 +56731 3 56729 6 0 1 +56731 4 2 30326 6 0 1 +56737 1 56727 1 +56737 2 10 56736 1 +56737 3 56727 10 0 1 +56737 4 10 51769 12 0 1 +56747 1 56745 1 +56747 2 2 56743 1 +56747 3 56745 3 0 1 +56747 4 2 47524 7 0 1 +56767 1 56764 1 +56767 2 3 56766 1 +56767 3 56764 3 0 1 +56767 4 3 31734 17 0 1 +56773 1 56771 1 +56773 2 2 56772 1 +56773 3 56771 4 0 1 +56773 4 2 42713 3 0 1 +56779 1 56777 1 +56779 2 2 56775 1 +56779 3 56777 2 0 1 +56779 4 2 49583 8 0 1 +56783 1 56778 1 +56783 2 5 56781 1 +56783 3 56778 5 0 1 +56783 4 5 36408 9 0 1 +56807 1 56802 1 +56807 2 5 56802 1 +56807 3 56802 2 0 1 +56807 4 5 39806 8 0 1 +56809 1 56792 1 +56809 2 17 56802 1 +56809 3 56792 1 0 1 +56809 4 17 56790 26 0 1 +56813 1 56810 1 +56813 2 3 56811 1 +56813 3 56810 6 0 1 +56813 4 3 55747 14 0 1 +56821 1 56815 1 +56821 2 6 56820 1 +56821 3 56815 4 0 1 +56821 4 6 49900 7 0 1 +56827 1 56825 1 +56827 2 2 56823 1 +56827 3 56825 4 0 1 +56827 4 2 39738 8 0 1 +56843 1 56841 1 +56843 2 2 56839 1 +56843 3 56841 2 0 1 +56843 4 2 48461 7 0 1 +56857 1 56850 1 +56857 2 7 56850 1 +56857 3 56850 1 0 1 +56857 4 7 35829 12 0 1 +56873 1 56870 1 +56873 2 3 56868 1 +56873 3 56870 3 0 1 +56873 4 3 31446 0 0 1 +56891 1 56889 1 +56891 2 2 56887 1 +56891 3 56889 2 0 1 +56891 4 2 32887 8 0 1 +56893 1 56891 1 +56893 2 2 56889 1 +56893 3 56891 8 0 1 +56893 4 2 36782 6 0 1 +56897 1 56892 1 +56897 2 5 56892 1 +56897 3 56892 6 0 1 +56897 4 5 49662 8 0 1 +56909 1 56907 1 +56909 2 2 56908 1 +56909 3 56907 4 0 1 +56909 4 2 56902 8 0 1 +56911 1 56908 1 +56911 2 3 56910 1 +56911 3 56908 1 0 1 +56911 4 3 31894 3 0 1 +56921 1 56918 1 +56921 2 3 56920 1 +56921 3 56918 13 0 1 +56921 4 3 40471 7 0 1 +56923 1 56920 1 +56923 2 3 56914 1 +56923 3 56920 3 0 1 +56923 4 3 47329 4 0 1 +56929 1 56915 1 +56929 2 14 56924 1 +56929 3 56915 1 0 1 +56929 4 14 29755 12 0 1 +56941 1 56939 1 +56941 2 2 56940 1 +56941 3 56939 6 0 1 +56941 4 2 31538 9 0 1 +56951 1 56938 1 +56951 2 13 56950 1 +56951 3 56938 1 0 1 +56951 4 13 38438 2 0 1 +56957 1 56955 1 +56957 2 2 56953 1 +56957 3 56955 2 0 1 +56957 4 2 30493 1 0 1 +56963 1 56961 1 +56963 2 2 56951 1 +56963 3 56961 4 0 1 +56963 4 2 52095 6 0 1 +56983 1 56980 1 +56983 2 3 56981 1 +56983 3 56980 8 0 1 +56983 4 3 36515 3 0 1 +56989 1 56983 1 +56989 2 6 56985 1 +56989 3 56983 2 0 1 +56989 4 6 29829 2 0 1 +56993 1 56990 1 +56993 2 3 56987 1 +56993 3 56990 6 0 1 +56993 4 3 38637 1 0 1 +56999 1 56986 1 +56999 2 13 56995 1 +56999 3 56986 1 0 1 +56999 4 13 56981 13 0 1 +57037 1 57032 1 +57037 2 5 57034 1 +57037 3 57032 1 0 1 +57037 4 5 55996 1 0 1 +57041 1 57030 1 +57041 2 11 57038 1 +57041 3 57030 12 0 1 +57041 4 11 34827 6 0 1 +57047 1 57040 1 +57047 2 7 57046 1 +57047 3 57040 1 0 1 +57047 4 7 34431 3 0 1 +57059 1 57057 1 +57059 2 2 57054 1 +57059 3 57057 2 0 1 +57059 4 2 39457 3 0 1 +57073 1 57068 1 +57073 2 5 57068 1 +57073 3 57068 3 0 1 +57073 4 5 44036 10 0 1 +57077 1 57075 1 +57077 2 2 57076 1 +57077 3 57075 3 0 1 +57077 4 2 29715 6 0 1 +57089 1 57086 1 +57089 2 3 57088 1 +57089 3 57086 1 0 1 +57089 4 3 56751 7 0 1 +57097 1 57090 1 +57097 2 7 57094 1 +57097 3 57090 1 0 1 +57097 4 7 39494 13 0 1 +57107 1 57105 1 +57107 2 2 57103 1 +57107 3 57105 3 0 1 +57107 4 2 40016 7 0 1 +57119 1 57100 1 +57119 2 19 57117 1 +57119 3 57100 5 0 1 +57119 4 19 55685 3 0 1 +57131 1 57129 1 +57131 2 2 57127 1 +57131 3 57129 7 0 1 +57131 4 2 36157 7 0 1 +57139 1 57137 1 +57139 2 2 57138 1 +57139 3 57137 6 0 1 +57139 4 2 30322 6 0 1 +57143 1 57138 1 +57143 2 5 57135 1 +57143 3 57138 9 0 1 +57143 4 5 36287 3 0 1 +57149 1 57147 1 +57149 2 2 57141 1 +57149 3 57147 4 0 1 +57149 4 2 47915 0 0 1 +57163 1 57161 1 +57163 2 2 57159 1 +57163 3 57161 6 0 1 +57163 4 2 36804 8 0 1 +57173 1 57171 1 +57173 2 2 57169 1 +57173 3 57171 4 0 1 +57173 4 2 38644 7 0 1 +57179 1 57177 1 +57179 2 2 57178 1 +57179 3 57177 4 0 1 +57179 4 2 52261 2 0 1 +57191 1 57184 1 +57191 2 7 57189 1 +57191 3 57184 4 0 1 +57191 4 7 42241 5 0 1 +57193 1 57188 1 +57193 2 5 57192 1 +57193 3 57188 2 0 1 +57193 4 5 39799 15 0 1 +57203 1 57201 1 +57203 2 2 57202 1 +57203 3 57201 2 0 1 +57203 4 2 52152 10 0 1 +57221 1 57219 1 +57221 2 2 57215 1 +57221 3 57219 4 0 1 +57221 4 2 31351 3 0 1 +57223 1 57220 1 +57223 2 3 57221 1 +57223 3 57220 7 0 1 +57223 4 3 42759 3 0 1 +57241 1 57230 1 +57241 2 11 57240 1 +57241 3 57230 3 0 1 +57241 4 11 46815 20 0 1 +57251 1 57249 1 +57251 2 2 57246 1 +57251 3 57249 7 0 1 +57251 4 2 45427 3 0 1 +57259 1 57257 1 +57259 2 2 57258 1 +57259 3 57257 4 0 1 +57259 4 2 35735 2 0 1 +57269 1 57267 1 +57269 2 2 57265 1 +57269 3 57267 2 0 1 +57269 4 2 36576 12 0 1 +57271 1 57268 1 +57271 2 3 57269 1 +57271 3 57268 7 0 1 +57271 4 3 49860 6 0 1 +57283 1 57281 1 +57283 2 2 57279 1 +57283 3 57281 6 0 1 +57283 4 2 50812 8 0 1 +57287 1 57282 1 +57287 2 5 57286 1 +57287 3 57282 1 0 1 +57287 4 5 38078 7 0 1 +57301 1 57295 1 +57301 2 6 57297 1 +57301 3 57295 2 0 1 +57301 4 6 37913 2 0 1 +57329 1 57326 1 +57329 2 3 57323 1 +57329 3 57326 1 0 1 +57329 4 3 57317 0 0 1 +57331 1 57329 1 +57331 2 2 57327 1 +57331 3 57329 4 0 1 +57331 4 2 51427 8 0 1 +57347 1 57345 1 +57347 2 2 57346 1 +57347 3 57345 2 0 1 +57347 4 2 57340 8 0 1 +57349 1 57347 1 +57349 2 2 57343 1 +57349 3 57347 6 0 1 +57349 4 2 49578 8 0 1 +57367 1 57364 1 +57367 2 3 57366 1 +57367 3 57364 6 0 1 +57367 4 3 55950 5 0 1 +57373 1 57371 1 +57373 2 2 57369 1 +57373 3 57371 5 0 1 +57373 4 2 31513 15 0 1 +57383 1 57378 1 +57383 2 5 57382 1 +57383 3 57378 15 0 1 +57383 4 5 37502 4 0 1 +57389 1 57387 1 +57389 2 2 57388 1 +57389 3 57387 3 0 1 +57389 4 2 47299 3 0 1 +57397 1 57395 1 +57397 2 2 57393 1 +57397 3 57395 6 0 1 +57397 4 2 47519 6 0 1 +57413 1 57411 1 +57413 2 2 57407 1 +57413 3 57411 4 0 1 +57413 4 2 55753 14 0 1 +57427 1 57425 1 +57427 2 2 57426 1 +57427 3 57425 4 0 1 +57427 4 2 55666 10 0 1 +57457 1 57452 1 +57457 2 5 57452 1 +57457 3 57452 13 0 1 +57457 4 5 45768 10 0 1 +57467 1 57465 1 +57467 2 2 57463 1 +57467 3 57465 3 0 1 +57467 4 2 52560 7 0 1 +57487 1 57481 1 +57487 2 6 57486 1 +57487 3 57481 8 0 1 +57487 4 6 42883 3 0 1 +57493 1 57488 1 +57493 2 5 57492 1 +57493 3 57488 5 0 1 +57493 4 5 44338 6 0 1 +57503 1 57498 1 +57503 2 5 57501 1 +57503 3 57498 2 0 1 +57503 4 5 57491 11 0 1 +57527 1 57522 1 +57527 2 5 57526 1 +57527 3 57522 1 0 1 +57527 4 5 34433 2 0 1 +57529 1 57522 1 +57529 2 7 57518 1 +57529 3 57522 1 0 1 +57529 4 7 29315 0 0 1 +57557 1 57555 1 +57557 2 2 57553 1 +57557 3 57555 2 0 1 +57557 4 2 44691 1 0 1 +57559 1 57553 1 +57559 2 6 57550 1 +57559 3 57553 3 0 1 +57559 4 6 38120 11 0 1 +57571 1 57558 1 +57571 2 13 57568 1 +57571 3 57558 2 0 1 +57571 4 13 56016 4 0 1 +57587 1 57585 1 +57587 2 2 57586 1 +57587 3 57585 2 0 1 +57587 4 2 48928 2 0 1 +57593 1 57590 1 +57593 2 3 57587 1 +57593 3 57590 1 0 1 +57593 4 3 50111 9 0 1 +57601 1 57594 1 +57601 2 7 57598 1 +57601 3 57594 5 0 1 +57601 4 7 51952 16 0 1 +57637 1 57635 1 +57637 2 2 57633 1 +57637 3 57635 2 0 1 +57637 4 2 54068 6 0 1 +57641 1 57638 1 +57641 2 3 57629 1 +57641 3 57638 10 0 1 +57641 4 3 50846 0 0 1 +57649 1 57636 1 +57649 2 13 57640 1 +57649 3 57636 2 0 1 +57649 4 13 47197 28 0 1 +57653 1 57651 1 +57653 2 2 57649 1 +57653 3 57651 3 0 1 +57653 4 2 43843 7 0 1 +57667 1 57664 1 +57667 2 3 57650 1 +57667 3 57664 3 0 1 +57667 4 3 41653 6 0 1 +57679 1 57676 1 +57679 2 3 57678 1 +57679 3 57676 1 0 1 +57679 4 3 54439 3 0 1 +57689 1 57686 1 +57689 2 3 57683 1 +57689 3 57686 5 0 1 +57689 4 3 57677 0 0 1 +57697 1 57692 1 +57697 2 5 57696 1 +57697 3 57692 2 0 1 +57697 4 5 50189 6 0 1 +57709 1 57707 1 +57709 2 2 57705 1 +57709 3 57707 2 0 1 +57709 4 2 51030 6 0 1 +57713 1 57710 1 +57713 2 3 57712 1 +57713 3 57710 1 0 1 +57713 4 3 39774 4 0 1 +57719 1 57712 1 +57719 2 7 57717 1 +57719 3 57712 10 0 1 +57719 4 7 39353 7 0 1 +57727 1 57724 1 +57727 2 3 57726 1 +57727 3 57724 4 0 1 +57727 4 3 33496 5 0 1 +57731 1 57729 1 +57731 2 2 57724 1 +57731 3 57729 2 0 1 +57731 4 2 50693 1 0 1 +57737 1 57734 1 +57737 2 3 57731 1 +57737 3 57734 5 0 1 +57737 4 3 53953 11 0 1 +57751 1 57745 1 +57751 2 6 57750 1 +57751 3 57745 2 0 1 +57751 4 6 52885 3 0 1 +57773 1 57770 1 +57773 2 3 57771 1 +57773 3 57770 11 0 1 +57773 4 3 57769 4 0 1 +57781 1 57775 1 +57781 2 6 57780 1 +57781 3 57775 1 0 1 +57781 4 6 54988 19 0 1 +57787 1 57785 1 +57787 2 2 57783 1 +57787 3 57785 6 0 1 +57787 4 2 31258 8 0 1 +57791 1 57765 1 +57791 2 26 57784 1 +57791 3 57765 2 0 1 +57791 4 26 45332 8 0 1 +57793 1 57788 1 +57793 2 5 57792 1 +57793 3 57788 2 0 1 +57793 4 5 29330 6 0 1 +57803 1 57801 1 +57803 2 2 57799 1 +57803 3 57801 3 0 1 +57803 4 2 35996 8 0 1 +57809 1 57806 1 +57809 2 3 57804 1 +57809 3 57806 3 0 1 +57809 4 3 47249 2 0 1 +57829 1 57819 1 +57829 2 10 57828 1 +57829 3 57819 7 0 1 +57829 4 10 39378 3 0 1 +57839 1 57828 1 +57839 2 11 57837 1 +57839 3 57828 4 0 1 +57839 4 11 47367 3 0 1 +57847 1 57844 1 +57847 2 3 57845 1 +57847 3 57844 6 0 1 +57847 4 3 49112 6 0 1 +57853 1 57848 1 +57853 2 5 57848 1 +57853 3 57848 1 0 1 +57853 4 5 43173 10 0 1 +57859 1 57857 1 +57859 2 2 57855 1 +57859 3 57857 6 0 1 +57859 4 2 31091 8 0 1 +57881 1 57878 1 +57881 2 3 57876 1 +57881 3 57878 4 0 1 +57881 4 3 57343 2 0 1 +57899 1 57897 1 +57899 2 2 57895 1 +57899 3 57897 11 0 1 +57899 4 2 36940 8 0 1 +57901 1 57899 1 +57901 2 2 57897 1 +57901 3 57899 2 0 1 +57901 4 2 43209 12 0 1 +57917 1 57915 1 +57917 2 2 57911 1 +57917 3 57915 2 0 1 +57917 4 2 43655 1 0 1 +57923 1 57921 1 +57923 2 2 57922 1 +57923 3 57921 3 0 1 +57923 4 2 57916 8 0 1 +57943 1 57938 1 +57943 2 5 57942 1 +57943 3 57938 3 0 1 +57943 4 5 48885 5 0 1 +57947 1 57942 1 +57947 2 5 57935 1 +57947 3 57942 6 0 1 +57947 4 5 56021 5 0 1 +57973 1 57968 1 +57973 2 5 57968 1 +57973 3 57968 6 0 1 +57973 4 5 53894 7 0 1 +57977 1 57974 1 +57977 2 3 57976 1 +57977 3 57974 5 0 1 +57977 4 3 32248 6 0 1 +57991 1 57985 1 +57991 2 6 57989 1 +57991 3 57985 3 0 1 +57991 4 6 46233 3 0 1 +58013 1 58011 1 +58013 2 2 58009 1 +58013 3 58011 3 0 1 +58013 4 2 34641 7 0 1 +58027 1 58025 1 +58027 2 2 58023 1 +58027 3 58025 6 0 1 +58027 4 2 53939 8 0 1 +58031 1 58024 1 +58031 2 7 58029 1 +58031 3 58024 2 0 1 +58031 4 7 46714 5 0 1 +58043 1 58041 1 +58043 2 2 58042 1 +58043 3 58041 2 0 1 +58043 4 2 49155 4 0 1 +58049 1 58046 1 +58049 2 3 58043 1 +58049 3 58046 1 0 1 +58049 4 3 58037 0 0 1 +58057 1 58050 1 +58057 2 7 58050 1 +58057 3 58050 7 0 1 +58057 4 7 30538 14 0 1 +58061 1 58058 1 +58061 2 3 58054 1 +58061 3 58058 1 0 1 +58061 4 3 38376 4 0 1 +58067 1 58065 1 +58067 2 2 58063 1 +58067 3 58065 3 0 1 +58067 4 2 55226 8 0 1 +58073 1 58068 1 +58073 2 5 58068 1 +58073 3 58068 3 0 1 +58073 4 5 38829 2 0 1 +58099 1 58089 1 +58099 2 10 58098 1 +58099 3 58089 3 0 1 +58099 4 10 38520 2 0 1 +58109 1 58107 1 +58109 2 2 58104 1 +58109 3 58107 3 0 1 +58109 4 2 48748 8 0 1 +58111 1 58099 1 +58111 2 12 58110 1 +58111 3 58099 3 0 1 +58111 4 12 34656 5 0 1 +58129 1 58116 1 +58129 2 13 58116 1 +58129 3 58116 2 0 1 +58129 4 13 58090 0 0 1 +58147 1 58144 1 +58147 2 3 58142 1 +58147 3 58144 4 0 1 +58147 4 3 46811 3 0 1 +58151 1 58144 1 +58151 2 7 58150 1 +58151 3 58144 1 0 1 +58151 4 7 40891 2 0 1 +58153 1 58143 1 +58153 2 10 58148 1 +58153 3 58143 5 0 1 +58153 4 10 39832 0 0 1 +58169 1 58163 1 +58169 2 6 58163 1 +58169 3 58163 4 0 1 +58169 4 6 43378 0 0 1 +58171 1 58169 1 +58171 2 2 58167 1 +58171 3 58169 2 0 1 +58171 4 2 51474 8 0 1 +58189 1 58183 1 +58189 2 6 58188 1 +58189 3 58183 1 0 1 +58189 4 6 48887 8 0 1 +58193 1 58190 1 +58193 2 3 58186 1 +58193 3 58190 1 0 1 +58193 4 3 56340 1 0 1 +58199 1 58192 1 +58199 2 7 58197 1 +58199 3 58192 2 0 1 +58199 4 7 42928 4 0 1 +58207 1 58202 1 +58207 2 5 58206 1 +58207 3 58202 3 0 1 +58207 4 5 32800 2 0 1 +58211 1 58209 1 +58211 2 2 58207 1 +58211 3 58209 3 0 1 +58211 4 2 43921 15 0 1 +58217 1 58214 1 +58217 2 3 58211 1 +58217 3 58214 1 0 1 +58217 4 3 48348 1 0 1 +58229 1 58227 1 +58229 2 2 58225 1 +58229 3 58227 3 0 1 +58229 4 2 51018 1 0 1 +58231 1 58225 1 +58231 2 6 58229 1 +58231 3 58225 1 0 1 +58231 4 6 53033 3 0 1 +58237 1 58222 1 +58237 2 15 58235 1 +58237 3 58222 3 0 1 +58237 4 15 31925 0 0 1 +58243 1 58241 1 +58243 2 2 58242 1 +58243 3 58241 2 0 1 +58243 4 2 57340 2 0 1 +58271 1 58260 1 +58271 2 11 58267 1 +58271 3 58260 2 0 1 +58271 4 11 37635 5 0 1 +58309 1 58303 1 +58309 2 6 58305 1 +58309 3 58303 4 0 1 +58309 4 6 58301 12 0 1 +58313 1 58310 1 +58313 2 3 58308 1 +58313 3 58310 1 0 1 +58313 4 3 35319 0 0 1 +58321 1 58310 1 +58321 2 11 58316 1 +58321 3 58310 2 0 1 +58321 4 11 58302 24 0 1 +58337 1 58334 1 +58337 2 3 58332 1 +58337 3 58334 3 0 1 +58337 4 3 29604 0 0 1 +58363 1 58361 1 +58363 2 2 58359 1 +58363 3 58361 5 0 1 +58363 4 2 41459 8 0 1 +58367 1 58360 1 +58367 2 7 58365 1 +58367 3 58360 2 0 1 +58367 4 7 43398 4 0 1 +58369 1 58362 1 +58369 2 7 58362 1 +58369 3 58362 1 0 1 +58369 4 7 30188 0 0 1 +58379 1 58377 1 +58379 2 2 58378 1 +58379 3 58377 7 0 1 +58379 4 2 57542 4 0 1 +58391 1 58380 1 +58391 2 11 58389 1 +58391 3 58380 11 0 1 +58391 4 11 55344 3 0 1 +58393 1 58388 1 +58393 2 5 58388 1 +58393 3 58388 2 0 1 +58393 4 5 44634 10 0 1 +58403 1 58401 1 +58403 2 2 58399 1 +58403 3 58401 3 0 1 +58403 4 2 35770 7 0 1 +58411 1 58409 1 +58411 2 2 58410 1 +58411 3 58409 4 0 1 +58411 4 2 31595 6 0 1 +58417 1 58412 1 +58417 2 5 58414 1 +58417 3 58412 6 0 1 +58417 4 5 58406 14 0 1 +58427 1 58425 1 +58427 2 2 58423 1 +58427 3 58425 3 0 1 +58427 4 2 47674 7 0 1 +58439 1 58422 1 +58439 2 17 58435 1 +58439 3 58422 2 0 1 +58439 4 17 33992 7 0 1 +58441 1 58428 1 +58441 2 13 58440 1 +58441 3 58428 1 0 1 +58441 4 13 40655 14 0 1 +58451 1 58441 1 +58451 2 10 58449 1 +58451 3 58441 3 0 1 +58451 4 10 58433 11 0 1 +58453 1 58451 1 +58453 2 2 58452 1 +58453 3 58451 2 0 1 +58453 4 2 53853 3 0 1 +58477 1 58472 1 +58477 2 5 58476 1 +58477 3 58472 1 0 1 +58477 4 5 42959 3 0 1 +58481 1 58475 1 +58481 2 6 58480 1 +58481 3 58475 2 0 1 +58481 4 6 29511 4 0 1 +58511 1 58498 1 +58511 2 13 58506 1 +58511 3 58498 13 0 1 +58511 4 13 41376 6 0 1 +58537 1 58530 1 +58537 2 7 58530 1 +58537 3 58530 3 0 1 +58537 4 7 48187 17 0 1 +58543 1 58537 1 +58543 2 6 58540 1 +58543 3 58537 2 0 1 +58543 4 6 53814 4 0 1 +58549 1 58547 1 +58549 2 2 58545 1 +58549 3 58547 2 0 1 +58549 4 2 58008 12 0 1 +58567 1 58561 1 +58567 2 6 58564 1 +58567 3 58561 1 0 1 +58567 4 6 34218 7 0 1 +58573 1 58571 1 +58573 2 2 58569 1 +58573 3 58571 6 0 1 +58573 4 2 54611 19 0 1 +58579 1 58577 1 +58579 2 2 58578 1 +58579 3 58577 5 0 1 +58579 4 2 35266 2 0 1 +58601 1 58598 1 +58601 2 3 58595 1 +58601 3 58598 6 0 1 +58601 4 3 58589 0 0 1 +58603 1 58601 1 +58603 2 2 58602 1 +58603 3 58601 2 0 1 +58603 4 2 38029 2 0 1 +58613 1 58611 1 +58613 2 2 58606 1 +58613 3 58611 4 0 1 +58613 4 2 37260 5 0 1 +58631 1 58612 1 +58631 2 19 58627 1 +58631 3 58612 1 0 1 +58631 4 19 53136 5 0 1 +58657 1 58652 1 +58657 2 5 58652 1 +58657 3 58652 2 0 1 +58657 4 5 43645 15 0 1 +58661 1 58659 1 +58661 2 2 58657 1 +58661 3 58659 2 0 1 +58661 4 2 56239 6 0 1 +58679 1 58668 1 +58679 2 11 58678 1 +58679 3 58668 14 0 1 +58679 4 11 43631 2 0 1 +58687 1 58681 1 +58687 2 6 58686 1 +58687 3 58681 2 0 1 +58687 4 6 46188 10 0 1 +58693 1 58691 1 +58693 2 2 58692 1 +58693 3 58691 2 0 1 +58693 4 2 35548 3 0 1 +58699 1 58697 1 +58699 2 2 58693 1 +58699 3 58697 5 0 1 +58699 4 2 46234 7 0 1 +58711 1 58705 1 +58711 2 6 58710 1 +58711 3 58705 1 0 1 +58711 4 6 50134 3 0 1 +58727 1 58722 1 +58727 2 5 58725 1 +58727 3 58722 3 0 1 +58727 4 5 58723 3 0 1 +58733 1 58731 1 +58733 2 2 58732 1 +58733 3 58731 3 0 1 +58733 4 2 51995 6 0 1 +58741 1 58739 1 +58741 2 2 58737 1 +58741 3 58739 6 0 1 +58741 4 2 51466 6 0 1 +58757 1 58755 1 +58757 2 2 58756 1 +58757 3 58755 2 0 1 +58757 4 2 57521 3 0 1 +58763 1 58761 1 +58763 2 2 58762 1 +58763 3 58761 3 0 1 +58763 4 2 33436 4 0 1 +58771 1 58760 1 +58771 2 11 58770 1 +58771 3 58760 1 0 1 +58771 4 11 31439 2 0 1 +58787 1 58785 1 +58787 2 2 58783 1 +58787 3 58785 3 0 1 +58787 4 2 53034 13 0 1 +58789 1 58787 1 +58789 2 2 58788 1 +58789 3 58787 5 0 1 +58789 4 2 43414 9 0 1 +58831 1 58820 1 +58831 2 11 58830 1 +58831 3 58820 1 0 1 +58831 4 11 49291 2 0 1 +58889 1 58886 1 +58889 2 3 58888 1 +58889 3 58886 5 0 1 +58889 4 3 55753 4 0 1 +58897 1 58892 1 +58897 2 5 58892 1 +58897 3 58892 6 0 1 +58897 4 5 42970 15 0 1 +58901 1 58899 1 +58901 2 2 58900 1 +58901 3 58899 9 0 1 +58901 4 2 44936 3 0 1 +58907 1 58905 1 +58907 2 2 58901 1 +58907 3 58905 4 0 1 +58907 4 2 33592 7 0 1 +58909 1 58907 1 +58909 2 2 58905 1 +58909 3 58907 2 0 1 +58909 4 2 49635 12 0 1 +58913 1 58910 1 +58913 2 3 58912 1 +58913 3 58910 5 0 1 +58913 4 3 31211 7 0 1 +58921 1 58908 1 +58921 2 13 58908 1 +58921 3 58908 15 0 1 +58921 4 13 58882 0 0 1 +58937 1 58934 1 +58937 2 3 58936 1 +58937 3 58934 1 0 1 +58937 4 3 33022 11 0 1 +58943 1 58938 1 +58943 2 5 58938 1 +58943 3 58938 2 0 1 +58943 4 5 44689 6 0 1 +58963 1 58960 1 +58963 2 3 58958 1 +58963 3 58960 6 0 1 +58963 4 3 52617 6 0 1 +58967 1 58962 1 +58967 2 5 58966 1 +58967 3 58962 3 0 1 +58967 4 5 57572 7 0 1 +58979 1 58977 1 +58979 2 2 58975 1 +58979 3 58977 3 0 1 +58979 4 2 37095 7 0 1 +58991 1 58984 1 +58991 2 7 58990 1 +58991 3 58984 8 0 1 +58991 4 7 58982 4 0 1 +58997 1 58994 1 +58997 2 3 58995 1 +58997 3 58994 5 0 1 +58997 4 3 41475 14 0 1 +59009 1 59006 1 +59009 2 3 59002 1 +59009 3 59006 1 0 1 +59009 4 3 41755 4 0 1 +59011 1 59009 1 +59011 2 2 59007 1 +59011 3 59009 4 0 1 +59011 4 2 46242 8 0 1 +59021 1 59019 1 +59021 2 2 59017 1 +59021 3 59019 2 0 1 +59021 4 2 44130 6 0 1 +59023 1 59018 1 +59023 2 5 59021 1 +59023 3 59018 6 0 1 +59023 4 5 59007 18 0 1 +59029 1 59027 1 +59029 2 2 59028 1 +59029 3 59027 5 0 1 +59029 4 2 52110 7 0 1 +59051 1 59041 1 +59051 2 10 59049 1 +59051 3 59041 5 0 1 +59051 4 10 59039 6 0 1 +59053 1 59038 1 +59053 2 15 59051 1 +59053 3 59038 4 0 1 +59053 4 15 42434 7 0 1 +59063 1 59058 1 +59063 2 5 59061 1 +59063 3 59058 2 0 1 +59063 4 5 59059 3 0 1 +59069 1 59067 1 +59069 2 2 59065 1 +59069 3 59067 3 0 1 +59069 4 2 47659 1 0 1 +59077 1 59072 1 +59077 2 5 59074 1 +59077 3 59072 1 0 1 +59077 4 5 32079 1 0 1 +59083 1 59081 1 +59083 2 2 59082 1 +59083 3 59081 5 0 1 +59083 4 2 31074 2 0 1 +59093 1 59090 1 +59093 2 3 59091 1 +59093 3 59090 1 0 1 +59093 4 3 35731 14 0 1 +59107 1 59105 1 +59107 2 2 59103 1 +59107 3 59105 2 0 1 +59107 4 2 45262 1 0 1 +59113 1 59106 1 +59113 2 7 59106 1 +59113 3 59106 1 0 1 +59113 4 7 49406 20 0 1 +59119 1 59116 1 +59119 2 3 59114 1 +59119 3 59116 1 0 1 +59119 4 3 42179 7 0 1 +59123 1 59121 1 +59123 2 2 59118 1 +59123 3 59121 4 0 1 +59123 4 2 56145 3 0 1 +59141 1 59138 1 +59141 2 3 59139 1 +59141 3 59138 4 0 1 +59141 4 3 39886 14 0 1 +59149 1 59147 1 +59149 2 2 59148 1 +59149 3 59147 5 0 1 +59149 4 2 58239 3 0 1 +59159 1 59152 1 +59159 2 7 59158 1 +59159 3 59152 2 0 1 +59159 4 7 59150 4 0 1 +59167 1 59164 1 +59167 2 3 59165 1 +59167 3 59164 3 0 1 +59167 4 3 59163 4 0 1 +59183 1 59178 1 +59183 2 5 59178 1 +59183 3 59178 1 0 1 +59183 4 5 47171 7 0 1 +59197 1 59195 1 +59197 2 2 59196 1 +59197 3 59195 2 0 1 +59197 4 2 30666 3 0 1 +59207 1 59202 1 +59207 2 5 59206 1 +59207 3 59202 2 0 1 +59207 4 5 44946 5 0 1 +59209 1 59198 1 +59209 2 11 59206 1 +59209 3 59198 1 0 1 +59209 4 11 29877 10 0 1 +59219 1 59217 1 +59219 2 2 59207 1 +59219 3 59217 3 0 1 +59219 4 2 51679 2 0 1 +59221 1 59219 1 +59221 2 2 59217 1 +59221 3 59219 2 0 1 +59221 4 2 45722 6 0 1 +59233 1 59228 1 +59233 2 5 59232 1 +59233 3 59228 1 0 1 +59233 4 5 39196 6 0 1 +59239 1 59236 1 +59239 2 3 59234 1 +59239 3 59236 5 0 1 +59239 4 3 36481 6 0 1 +59243 1 59241 1 +59243 2 2 59239 1 +59243 3 59241 3 0 1 +59243 4 2 54074 8 0 1 +59263 1 59260 1 +59263 2 3 59262 1 +59263 3 59260 3 0 1 +59263 4 3 55226 5 0 1 +59273 1 59270 1 +59273 2 3 59267 1 +59273 3 59270 1 0 1 +59273 4 3 40628 11 0 1 +59281 1 59274 1 +59281 2 7 59274 1 +59281 3 59274 10 0 1 +59281 4 7 56883 0 0 1 +59333 1 59331 1 +59333 2 2 59329 1 +59333 3 59331 4 0 1 +59333 4 2 48426 6 0 1 +59341 1 59327 1 +59341 2 14 59340 1 +59341 3 59327 7 0 1 +59341 4 14 53520 7 0 1 +59351 1 59338 1 +59351 2 13 59347 1 +59351 3 59338 1 0 1 +59351 4 13 38445 6 0 1 +59357 1 59355 1 +59357 2 2 59353 1 +59357 3 59355 3 0 1 +59357 4 2 41315 7 0 1 +59359 1 59353 1 +59359 2 6 59358 1 +59359 3 59353 3 0 1 +59359 4 6 58297 2 0 1 +59369 1 59366 1 +59369 2 3 59368 1 +59369 3 59366 1 0 1 +59369 4 3 48940 4 0 1 +59377 1 59372 1 +59377 2 5 59376 1 +59377 3 59372 1 0 1 +59377 4 5 57603 6 0 1 +59387 1 59385 1 +59387 2 2 59383 1 +59387 3 59385 2 0 1 +59387 4 2 33537 7 0 1 +59393 1 59388 1 +59393 2 5 59388 1 +59393 3 59388 1 0 1 +59393 4 5 32290 8 0 1 +59399 1 59392 1 +59399 2 7 59398 1 +59399 3 59392 2 0 1 +59399 4 7 35888 2 0 1 +59407 1 59404 1 +59407 2 3 59406 1 +59407 3 59404 4 0 1 +59407 4 3 30026 5 0 1 +59417 1 59414 1 +59417 2 3 59416 1 +59417 3 59414 9 0 1 +59417 4 3 40071 4 0 1 +59419 1 59417 1 +59419 2 2 59418 1 +59419 3 59417 6 0 1 +59419 4 2 59412 8 0 1 +59441 1 59438 1 +59441 2 3 59440 1 +59441 3 59438 3 0 1 +59441 4 3 40468 4 0 1 +59443 1 59441 1 +59443 2 2 59442 1 +59443 3 59441 2 0 1 +59443 4 2 34764 10 0 1 +59447 1 59442 1 +59447 2 5 59445 1 +59447 3 59442 1 0 1 +59447 4 5 54195 8 0 1 +59453 1 59451 1 +59453 2 2 59449 1 +59453 3 59451 3 0 1 +59453 4 2 51754 9 0 1 +59467 1 59465 1 +59467 2 2 59463 1 +59467 3 59465 6 0 1 +59467 4 2 40603 8 0 1 +59471 1 59460 1 +59471 2 11 59469 1 +59471 3 59460 1 0 1 +59471 4 11 56163 7 0 1 +59473 1 59463 1 +59473 2 10 59472 1 +59473 3 59463 7 0 1 +59473 4 10 39154 6 0 1 +59497 1 59482 1 +59497 2 15 59494 1 +59497 3 59482 3 0 1 +59497 4 15 49261 32 0 1 +59509 1 59499 1 +59509 2 10 59505 1 +59509 3 59499 2 0 1 +59509 4 10 49122 2 0 1 +59513 1 59510 1 +59513 2 3 59507 1 +59513 3 59510 1 0 1 +59513 4 3 40979 1 0 1 +59539 1 59537 1 +59539 2 2 59534 1 +59539 3 59537 4 0 1 +59539 4 2 49508 2 0 1 +59557 1 59555 1 +59557 2 2 59553 1 +59557 3 59555 4 0 1 +59557 4 2 41602 6 0 1 +59561 1 59558 1 +59561 2 3 59560 1 +59561 3 59558 1 0 1 +59561 4 3 39592 7 0 1 +59567 1 59562 1 +59567 2 5 59566 1 +59567 3 59562 1 0 1 +59567 4 5 45015 2 0 1 +59581 1 59575 1 +59581 2 6 59580 1 +59581 3 59575 6 0 1 +59581 4 6 44209 7 0 1 +59611 1 59609 1 +59611 2 2 59610 1 +59611 3 59609 4 0 1 +59611 4 2 39105 7 0 1 +59617 1 59610 1 +59617 2 7 59614 1 +59617 3 59610 7 0 1 +59617 4 7 54965 10 0 1 +59621 1 59618 1 +59621 2 3 59614 1 +59621 3 59618 16 0 1 +59621 4 3 56091 4 0 1 +59627 1 59625 1 +59627 2 2 59623 1 +59627 3 59625 3 0 1 +59627 4 2 57389 7 0 1 +59629 1 59627 1 +59629 2 2 59625 1 +59629 3 59627 4 0 1 +59629 4 2 58314 6 0 1 +59651 1 59649 1 +59651 2 2 59642 1 +59651 3 59649 2 0 1 +59651 4 2 47557 1 0 1 +59659 1 59656 1 +59659 2 3 59652 1 +59659 3 59656 1 0 1 +59659 4 3 54020 5 0 1 +59663 1 59658 1 +59663 2 5 59661 1 +59663 3 59658 13 0 1 +59663 4 5 43156 10 0 1 +59669 1 59667 1 +59669 2 2 59665 1 +59669 3 59667 3 0 1 +59669 4 2 33597 12 0 1 +59671 1 59659 1 +59671 2 12 59669 1 +59671 3 59659 5 0 1 +59671 4 12 38104 3 0 1 +59693 1 59691 1 +59693 2 2 59688 1 +59693 3 59691 12 0 1 +59693 4 2 34867 2 0 1 +59699 1 59697 1 +59699 2 2 59698 1 +59699 3 59697 16 0 1 +59699 4 2 30989 2 0 1 +59707 1 59704 1 +59707 2 3 59706 1 +59707 3 59704 13 0 1 +59707 4 3 46798 5 0 1 +59723 1 59721 1 +59723 2 2 59716 1 +59723 3 59721 7 0 1 +59723 4 2 54408 1 0 1 +59729 1 59726 1 +59729 2 3 59724 1 +59729 3 59726 1 0 1 +59729 4 3 56858 2 0 1 +59743 1 59740 1 +59743 2 3 59742 1 +59743 3 59740 5 0 1 +59743 4 3 40344 5 0 1 +59747 1 59745 1 +59747 2 2 59737 1 +59747 3 59745 7 0 1 +59747 4 2 51354 2 0 1 +59753 1 59748 1 +59753 2 5 59742 1 +59753 3 59748 1 0 1 +59753 4 5 57333 5 0 1 +59771 1 59769 1 +59771 2 2 59770 1 +59771 3 59769 7 0 1 +59771 4 2 59764 8 0 1 +59779 1 59769 1 +59779 2 10 59778 1 +59779 3 59769 2 0 1 +59779 4 10 59132 5 0 1 +59791 1 59788 1 +59791 2 3 59790 1 +59791 3 59788 1 0 1 +59791 4 3 36138 3 0 1 +59797 1 59795 1 +59797 2 2 59796 1 +59797 3 59795 6 0 1 +59797 4 2 40340 7 0 1 +59809 1 59792 1 +59809 2 17 59808 1 +59809 3 59792 2 0 1 +59809 4 17 42116 30 0 1 +59833 1 59828 1 +59833 2 5 59832 1 +59833 3 59828 1 0 1 +59833 4 5 46665 11 0 1 +59863 1 59858 1 +59863 2 5 59862 1 +59863 3 59858 3 0 1 +59863 4 5 33091 16 0 1 +59879 1 59865 1 +59879 2 14 59878 1 +59879 3 59865 1 0 1 +59879 4 14 45363 2 0 1 +59887 1 59884 1 +59887 2 3 59885 1 +59887 3 59884 7 0 1 +59887 4 3 57869 3 0 1 +59921 1 59918 1 +59921 2 3 59914 1 +59921 3 59918 10 0 1 +59921 4 3 55013 1 0 1 +59929 1 59910 1 +59929 2 19 59926 1 +59929 3 59910 7 0 1 +59929 4 19 51620 22 0 1 +59951 1 59940 1 +59951 2 11 59948 1 +59951 3 59940 4 0 1 +59951 4 11 57454 6 0 1 +59957 1 59955 1 +59957 2 2 59950 1 +59957 3 59955 4 0 1 +59957 4 2 49111 5 0 1 +59971 1 59968 1 +59971 2 3 59970 1 +59971 3 59968 4 0 1 +59971 4 3 59088 7 0 1 +59981 1 59979 1 +59981 2 2 59976 1 +59981 3 59979 8 0 1 +59981 4 2 47505 12 0 1 +59999 1 59992 1 +59999 2 7 59998 1 +59999 3 59992 3 0 1 +59999 4 7 58199 3 0 1 +60013 1 60007 1 +60013 2 6 60011 1 +60013 3 60007 7 0 1 +60013 4 6 52216 4 0 1 +60017 1 60014 1 +60017 2 3 60006 1 +60017 3 60014 4 0 1 +60017 4 3 31524 1 0 1 +60029 1 60027 1 +60029 2 2 60025 1 +60029 3 60027 2 0 1 +60029 4 2 51903 7 0 1 +60037 1 60035 1 +60037 2 2 60036 1 +60037 3 60035 2 0 1 +60037 4 2 38532 3 0 1 +60041 1 60038 1 +60041 2 3 60036 1 +60041 3 60038 6 0 1 +60041 4 3 51746 2 0 1 +60077 1 60075 1 +60077 2 2 60076 1 +60077 3 60075 3 0 1 +60077 4 2 39408 3 0 1 +60083 1 60081 1 +60083 2 2 60078 1 +60083 3 60081 4 0 1 +60083 4 2 46956 0 0 1 +60089 1 60086 1 +60089 2 3 60088 1 +60089 3 60086 1 0 1 +60089 4 3 43037 4 0 1 +60091 1 60089 1 +60091 2 2 60090 1 +60091 3 60089 4 0 1 +60091 4 2 43323 6 0 1 +60101 1 60098 1 +60101 2 3 60099 1 +60101 3 60098 3 0 1 +60101 4 3 60097 4 0 1 +60103 1 60098 1 +60103 2 5 60101 1 +60103 3 60098 9 0 1 +60103 4 5 60091 11 0 1 +60107 1 60105 1 +60107 2 2 60106 1 +60107 3 60105 2 0 1 +60107 4 2 57860 4 0 1 +60127 1 60124 1 +60127 2 3 60125 1 +60127 3 60124 5 0 1 +60127 4 3 45764 6 0 1 +60133 1 60127 1 +60133 2 6 60132 1 +60133 3 60127 1 0 1 +60133 4 6 55618 7 0 1 +60139 1 60136 1 +60139 2 3 60138 1 +60139 3 60136 4 0 1 +60139 4 3 38015 6 0 1 +60149 1 60147 1 +60149 2 2 60148 1 +60149 3 60147 3 0 1 +60149 4 2 60142 8 0 1 +60161 1 60158 1 +60161 2 3 60155 1 +60161 3 60158 1 0 1 +60161 4 3 60149 0 0 1 +60167 1 60162 1 +60167 2 5 60166 1 +60167 3 60162 5 0 1 +60167 4 5 44146 2 0 1 +60169 1 60158 1 +60169 2 11 60168 1 +60169 3 60158 5 0 1 +60169 4 11 41275 14 0 1 +60209 1 60206 1 +60209 2 3 60208 1 +60209 3 60206 13 0 1 +60209 4 3 39868 4 0 1 +60217 1 60212 1 +60217 2 5 60212 1 +60217 3 60212 3 0 1 +60217 4 5 36215 12 0 1 +60223 1 60220 1 +60223 2 3 60221 1 +60223 3 60220 1 0 1 +60223 4 3 60215 10 0 1 +60251 1 60245 1 +60251 2 6 60250 1 +60251 3 60245 1 0 1 +60251 4 6 55705 2 0 1 +60257 1 60254 1 +60257 2 3 60256 1 +60257 3 60254 3 0 1 +60257 4 3 58724 7 0 1 +60259 1 60256 1 +60259 2 3 60250 1 +60259 3 60256 3 0 1 +60259 4 3 31861 6 0 1 +60271 1 60268 1 +60271 2 3 60270 1 +60271 3 60268 3 0 1 +60271 4 3 36772 10 0 1 +60289 1 60282 1 +60289 2 7 60286 1 +60289 3 60282 1 0 1 +60289 4 7 56173 16 0 1 +60293 1 60291 1 +60293 2 2 60288 1 +60293 3 60291 4 0 1 +60293 4 2 55589 0 0 1 +60317 1 60315 1 +60317 2 2 60316 1 +60317 3 60315 2 0 1 +60317 4 2 36105 4 0 1 +60331 1 60319 1 +60331 2 12 60330 1 +60331 3 60319 1 0 1 +60331 4 12 30701 5 0 1 +60337 1 60332 1 +60337 2 5 60336 1 +60337 3 60332 5 0 1 +60337 4 5 53239 12 0 1 +60343 1 60340 1 +60343 2 3 60342 1 +60343 3 60340 9 0 1 +60343 4 3 40662 5 0 1 +60353 1 60350 1 +60353 2 3 60352 1 +60353 3 60350 5 0 1 +60353 4 3 43662 4 0 1 +60373 1 60371 1 +60373 2 2 60372 1 +60373 3 60371 5 0 1 +60373 4 2 51163 6 0 1 +60383 1 60378 1 +60383 2 5 60378 1 +60383 3 60378 1 0 1 +60383 4 5 56436 6 0 1 +60397 1 60392 1 +60397 2 5 60396 1 +60397 3 60392 5 0 1 +60397 4 5 36324 7 0 1 +60413 1 60411 1 +60413 2 2 60412 1 +60413 3 60411 3 0 1 +60413 4 2 42023 19 0 1 +60427 1 60424 1 +60427 2 3 60420 1 +60427 3 60424 9 0 1 +60427 4 3 34137 5 0 1 +60443 1 60441 1 +60443 2 2 60442 1 +60443 3 60441 2 0 1 +60443 4 2 32304 4 0 1 +60449 1 60446 1 +60449 2 3 60435 1 +60449 3 60446 4 0 1 +60449 4 3 45079 2 0 1 +60457 1 60444 1 +60457 2 13 60456 1 +60457 3 60444 6 0 1 +60457 4 13 44255 11 0 1 +60493 1 60491 1 +60493 2 2 60492 1 +60493 3 60491 6 0 1 +60493 4 2 59943 6 0 1 +60497 1 60494 1 +60497 2 3 60496 1 +60497 3 60494 5 0 1 +60497 4 3 55621 6 0 1 +60509 1 60507 1 +60509 2 2 60505 1 +60509 3 60507 2 0 1 +60509 4 2 43962 6 0 1 +60521 1 60518 1 +60521 2 3 60520 1 +60521 3 60518 4 0 1 +60521 4 3 49677 4 0 1 +60527 1 60522 1 +60527 2 5 60526 1 +60527 3 60522 2 0 1 +60527 4 5 55656 4 0 1 +60539 1 60537 1 +60539 2 2 60535 1 +60539 3 60537 3 0 1 +60539 4 2 57889 7 0 1 +60589 1 60587 1 +60589 2 2 60579 1 +60589 3 60587 2 0 1 +60589 4 2 45582 2 0 1 +60601 1 60590 1 +60601 2 11 60596 1 +60601 3 60590 4 0 1 +60601 4 11 59044 16 0 1 +60607 1 60604 1 +60607 2 3 60606 1 +60607 3 60604 1 0 1 +60607 4 3 46733 5 0 1 +60611 1 60601 1 +60611 2 10 60608 1 +60611 3 60601 2 0 1 +60611 4 10 45565 4 0 1 +60617 1 60614 1 +60617 2 3 60612 1 +60617 3 60614 7 0 1 +60617 4 3 37458 0 0 1 +60623 1 60618 1 +60623 2 5 60622 1 +60623 3 60618 8 0 1 +60623 4 5 38247 2 0 1 +60631 1 60625 1 +60631 2 6 60629 1 +60631 3 60625 6 0 1 +60631 4 6 37775 4 0 1 +60637 1 60635 1 +60637 2 2 60636 1 +60637 3 60635 2 0 1 +60637 4 2 42535 9 0 1 +60647 1 60642 1 +60647 2 5 60642 1 +60647 3 60642 3 0 1 +60647 4 5 31472 9 0 1 +60649 1 60638 1 +60649 2 11 60648 1 +60649 3 60638 1 0 1 +60649 4 11 57391 24 0 1 +60659 1 60657 1 +60659 2 2 60655 1 +60659 3 60657 2 0 1 +60659 4 2 37394 8 0 1 +60661 1 60659 1 +60661 2 2 60660 1 +60661 3 60659 5 0 1 +60661 4 2 48780 3 0 1 +60679 1 60676 1 +60679 2 3 60677 1 +60679 3 60676 1 0 1 +60679 4 3 35802 3 0 1 +60689 1 60686 1 +60689 2 3 60688 1 +60689 3 60686 1 0 1 +60689 4 3 48859 7 0 1 +60703 1 60700 1 +60703 2 3 60701 1 +60703 3 60700 6 0 1 +60703 4 3 42426 17 0 1 +60719 1 60712 1 +60719 2 7 60715 1 +60719 3 60712 1 0 1 +60719 4 7 59617 6 0 1 +60727 1 60722 1 +60727 2 5 60726 1 +60727 3 60722 3 0 1 +60727 4 5 41599 12 0 1 +60733 1 60731 1 +60733 2 2 60729 1 +60733 3 60731 4 0 1 +60733 4 2 41358 10 0 1 +60737 1 60734 1 +60737 2 3 60736 1 +60737 3 60734 4 0 1 +60737 4 3 49217 6 0 1 +60757 1 60755 1 +60757 2 2 60753 1 +60757 3 60755 6 0 1 +60757 4 2 37347 9 0 1 +60761 1 60755 1 +60761 2 6 60758 1 +60761 3 60755 1 0 1 +60761 4 6 34826 0 0 1 +60763 1 60760 1 +60763 2 3 60762 1 +60763 3 60760 4 0 1 +60763 4 3 48750 5 0 1 +60773 1 60771 1 +60773 2 2 60769 1 +60773 3 60771 2 0 1 +60773 4 2 53959 1 0 1 +60779 1 60777 1 +60779 2 2 60778 1 +60779 3 60777 3 0 1 +60779 4 2 43256 4 0 1 +60793 1 60788 1 +60793 2 5 60792 1 +60793 3 60788 1 0 1 +60793 4 5 42116 6 0 1 +60811 1 60809 1 +60811 2 2 60807 1 +60811 3 60809 4 0 1 +60811 4 2 49132 8 0 1 +60821 1 60819 1 +60821 2 2 60820 1 +60821 3 60819 3 0 1 +60821 4 2 58097 3 0 1 +60859 1 60856 1 +60859 2 3 60854 1 +60859 3 60856 8 0 1 +60859 4 3 32881 3 0 1 +60869 1 60867 1 +60869 2 2 60865 1 +60869 3 60867 2 0 1 +60869 4 2 43138 7 0 1 +60887 1 60880 1 +60887 2 7 60885 1 +60887 3 60880 2 0 1 +60887 4 7 41522 10 0 1 +60889 1 60868 1 +60889 2 21 60888 1 +60889 3 60868 6 0 1 +60889 4 21 30890 8 0 1 +60899 1 60897 1 +60899 2 2 60890 1 +60899 3 60897 3 0 1 +60899 4 2 40968 1 0 1 +60901 1 60899 1 +60901 2 2 60897 1 +60901 3 60899 2 0 1 +60901 4 2 59505 6 0 1 +60913 1 60908 1 +60913 2 5 60912 1 +60913 3 60908 2 0 1 +60913 4 5 37275 6 0 1 +60917 1 60915 1 +60917 2 2 60916 1 +60917 3 60915 2 0 1 +60917 4 2 56743 3 0 1 +60919 1 60916 1 +60919 2 3 60917 1 +60919 3 60916 1 0 1 +60919 4 3 54223 6 0 1 +60923 1 60921 1 +60923 2 2 60918 1 +60923 3 60921 10 0 1 +60923 4 2 44157 3 0 1 +60937 1 60927 1 +60937 2 10 60936 1 +60937 3 60927 5 0 1 +60937 4 10 51187 21 0 1 +60943 1 60938 1 +60943 2 5 60942 1 +60943 3 60938 1 0 1 +60943 4 5 31353 2 0 1 +60953 1 60950 1 +60953 2 3 60952 1 +60953 3 60950 5 0 1 +60953 4 3 38273 4 0 1 +60961 1 60954 1 +60961 2 7 60954 1 +60961 3 60954 3 0 1 +60961 4 7 46153 0 0 1 +61001 1 60998 1 +61001 2 3 61000 1 +61001 3 60998 3 0 1 +61001 4 3 55315 7 0 1 +61007 1 61002 1 +61007 2 5 61005 1 +61007 3 61002 1 0 1 +61007 4 5 49699 14 0 1 +61027 1 61025 1 +61027 2 2 61023 1 +61027 3 61025 6 0 1 +61027 4 2 41014 8 0 1 +61031 1 61009 1 +61031 2 22 61028 1 +61031 3 61009 4 0 1 +61031 4 22 49802 8 0 1 +61043 1 61041 1 +61043 2 2 61042 1 +61043 3 61041 3 0 1 +61043 4 2 41886 20 0 1 +61051 1 61048 1 +61051 2 3 61040 1 +61051 3 61048 9 0 1 +61051 4 3 53312 1 0 1 +61057 1 61052 1 +61057 2 5 61056 1 +61057 3 61052 5 0 1 +61057 4 5 31428 6 0 1 +61091 1 61089 1 +61091 2 2 61087 1 +61091 3 61089 2 0 1 +61091 4 2 44076 7 0 1 +61099 1 61097 1 +61099 2 2 61098 1 +61099 3 61097 5 0 1 +61099 4 2 34487 6 0 1 +61121 1 61118 1 +61121 2 3 61116 1 +61121 3 61118 9 0 1 +61121 4 3 49149 2 0 1 +61129 1 61122 1 +61129 2 7 61120 1 +61129 3 61122 2 0 1 +61129 4 7 46243 2 0 1 +61141 1 61135 1 +61141 2 6 61140 1 +61141 3 61135 8 0 1 +61141 4 6 53310 7 0 1 +61151 1 61120 1 +61151 2 31 61150 1 +61151 3 61120 1 0 1 +61151 4 31 59965 2 0 1 +61153 1 61143 1 +61153 2 10 61150 1 +61153 3 61143 3 0 1 +61153 4 10 37800 8 0 1 +61169 1 61166 1 +61169 2 3 61163 1 +61169 3 61166 4 0 1 +61169 4 3 61157 0 0 1 +61211 1 61209 1 +61211 2 2 61203 1 +61211 3 61209 4 0 1 +61211 4 2 49876 2 0 1 +61223 1 61218 1 +61223 2 5 61221 1 +61223 3 61218 1 0 1 +61223 4 5 34750 5 0 1 +61231 1 61224 1 +61231 2 7 61228 1 +61231 3 61224 1 0 1 +61231 4 7 40021 0 0 1 +61253 1 61251 1 +61253 2 2 61249 1 +61253 3 61251 3 0 1 +61253 4 2 43674 22 0 1 +61261 1 61259 1 +61261 2 2 61257 1 +61261 3 61259 2 0 1 +61261 4 2 41485 10 0 1 +61283 1 61281 1 +61283 2 2 61282 1 +61283 3 61281 3 0 1 +61283 4 2 43068 10 0 1 +61291 1 61288 1 +61291 2 3 61290 1 +61291 3 61288 1 0 1 +61291 4 3 57988 2 0 1 +61297 1 61290 1 +61297 2 7 61294 1 +61297 3 61290 2 0 1 +61297 4 7 36957 8 0 1 +61331 1 61329 1 +61331 2 2 61327 1 +61331 3 61329 2 0 1 +61331 4 2 54672 8 0 1 +61333 1 61331 1 +61333 2 2 61332 1 +61333 3 61331 2 0 1 +61333 4 2 34465 3 0 1 +61339 1 61337 1 +61339 2 2 61338 1 +61339 3 61337 4 0 1 +61339 4 2 33990 6 0 1 +61343 1 61338 1 +61343 2 5 61341 1 +61343 3 61338 3 0 1 +61343 4 5 39504 8 0 1 +61357 1 61351 1 +61357 2 6 61355 1 +61357 3 61351 2 0 1 +61357 4 6 33171 10 0 1 +61363 1 61360 1 +61363 2 3 61356 1 +61363 3 61360 3 0 1 +61363 4 3 33832 2 0 1 +61379 1 61377 1 +61379 2 2 61378 1 +61379 3 61377 3 0 1 +61379 4 2 60825 4 0 1 +61381 1 61375 1 +61381 2 6 61380 1 +61381 3 61375 1 0 1 +61381 4 6 40379 7 0 1 +61403 1 61401 1 +61403 2 2 61402 1 +61403 3 61401 5 0 1 +61403 4 2 42392 10 0 1 +61409 1 61406 1 +61409 2 3 61408 1 +61409 3 61406 1 0 1 +61409 4 3 54546 7 0 1 +61417 1 61412 1 +61417 2 5 61408 1 +61417 3 61412 6 0 1 +61417 4 5 42540 14 0 1 +61441 1 61424 1 +61441 2 17 61440 1 +61441 3 61424 2 0 1 +61441 4 17 34907 12 0 1 +61463 1 61458 1 +61463 2 5 61461 1 +61463 3 61458 9 0 1 +61463 4 5 57285 14 0 1 +61469 1 61467 1 +61469 2 2 61464 1 +61469 3 61467 10 0 1 +61469 4 2 55713 20 0 1 +61471 1 61468 1 +61471 2 3 61469 1 +61471 3 61468 7 0 1 +61471 4 3 52115 6 0 1 +61483 1 61481 1 +61483 2 2 61478 1 +61483 3 61481 6 0 1 +61483 4 2 40254 2 0 1 +61487 1 61482 1 +61487 2 5 61485 1 +61487 3 61482 11 0 1 +61487 4 5 61483 3 0 1 +61493 1 61491 1 +61493 2 2 61492 1 +61493 3 61491 7 0 1 +61493 4 2 31024 21 0 1 +61507 1 61505 1 +61507 2 2 61506 1 +61507 3 61505 2 0 1 +61507 4 2 45654 2 0 1 +61511 1 61504 1 +61511 2 7 61510 1 +61511 3 61504 1 0 1 +61511 4 7 59211 3 0 1 +61519 1 61516 1 +61519 2 3 61518 1 +61519 3 61516 1 0 1 +61519 4 3 42703 2 0 1 +61543 1 61540 1 +61543 2 3 61541 1 +61543 3 61540 3 0 1 +61543 4 3 45606 3 0 1 +61547 1 61545 1 +61547 2 2 61543 1 +61547 3 61545 2 0 1 +61547 4 2 37014 7 0 1 +61553 1 61550 1 +61553 2 3 61548 1 +61553 3 61550 1 0 1 +61553 4 3 31054 0 0 1 +61559 1 61552 1 +61559 2 7 61557 1 +61559 3 61552 3 0 1 +61559 4 7 55248 4 0 1 +61561 1 61554 1 +61561 2 7 61554 1 +61561 3 61554 2 0 1 +61561 4 7 37994 0 0 1 +61583 1 61578 1 +61583 2 5 61578 1 +61583 3 61578 1 0 1 +61583 4 5 41969 6 0 1 +61603 1 61601 1 +61603 2 2 61602 1 +61603 3 61601 6 0 1 +61603 4 2 50916 2 0 1 +61609 1 61596 1 +61609 2 13 61606 1 +61609 3 61596 3 0 1 +61609 4 13 46793 26 0 1 +61613 1 61611 1 +61613 2 2 61597 1 +61613 3 61611 2 0 1 +61613 4 2 50836 3 0 1 +61627 1 61624 1 +61627 2 3 61622 1 +61627 3 61624 6 0 1 +61627 4 3 49372 3 0 1 +61631 1 61620 1 +61631 2 11 61630 1 +61631 3 61620 6 0 1 +61631 4 11 50465 2 0 1 +61637 1 61635 1 +61637 2 2 61632 1 +61637 3 61635 8 0 1 +61637 4 2 44458 0 0 1 +61643 1 61641 1 +61643 2 2 61639 1 +61643 3 61641 3 0 1 +61643 4 2 41731 8 0 1 +61651 1 61649 1 +61651 2 2 61647 1 +61651 3 61649 5 0 1 +61651 4 2 44616 8 0 1 +61657 1 61652 1 +61657 2 5 61656 1 +61657 3 61652 1 0 1 +61657 4 5 58391 6 0 1 +61667 1 61665 1 +61667 2 2 61663 1 +61667 3 61665 3 0 1 +61667 4 2 38136 8 0 1 +61673 1 61668 1 +61673 2 5 61670 1 +61673 3 61668 2 0 1 +61673 4 5 47605 0 0 1 +61681 1 61652 1 +61681 2 29 61674 1 +61681 3 61652 3 0 1 +61681 4 29 59222 36 0 1 +61687 1 61681 1 +61687 2 6 61684 1 +61687 3 61681 2 0 1 +61687 4 6 45338 5 0 1 +61703 1 61698 1 +61703 2 5 61702 1 +61703 3 61698 2 0 1 +61703 4 5 41755 4 0 1 +61717 1 61715 1 +61717 2 2 61716 1 +61717 3 61715 6 0 1 +61717 4 2 57170 3 0 1 +61723 1 61718 1 +61723 2 5 61721 1 +61723 3 61718 5 0 1 +61723 4 5 61719 3 0 1 +61729 1 61722 1 +61729 2 7 61722 1 +61729 3 61722 2 0 1 +61729 4 7 38315 0 0 1 +61751 1 61744 1 +61751 2 7 61750 1 +61751 3 61744 8 0 1 +61751 4 7 37416 6 0 1 +61757 1 61755 1 +61757 2 2 61756 1 +61757 3 61755 2 0 1 +61757 4 2 51635 4 0 1 +61781 1 61779 1 +61781 2 2 61774 1 +61781 3 61779 4 0 1 +61781 4 2 51262 17 0 1 +61813 1 61811 1 +61813 2 2 61812 1 +61813 3 61811 4 0 1 +61813 4 2 47977 6 0 1 +61819 1 61816 1 +61819 2 3 61812 1 +61819 3 61816 5 0 1 +61819 4 3 39500 0 0 1 +61837 1 61831 1 +61837 2 6 61835 1 +61837 3 61831 2 0 1 +61837 4 6 56096 0 0 1 +61843 1 61841 1 +61843 2 2 61842 1 +61843 3 61841 6 0 1 +61843 4 2 61836 8 0 1 +61861 1 61859 1 +61861 2 2 61857 1 +61861 3 61859 6 0 1 +61861 4 2 43169 12 0 1 +61871 1 61852 1 +61871 2 19 61870 1 +61871 3 61852 3 0 1 +61871 4 19 59775 6 0 1 +61879 1 61876 1 +61879 2 3 61877 1 +61879 3 61876 5 0 1 +61879 4 3 31536 3 0 1 +61909 1 61903 1 +61909 2 6 61905 1 +61909 3 61903 7 0 1 +61909 4 6 45367 2 0 1 +61927 1 61924 1 +61927 2 3 61926 1 +61927 3 61924 4 0 1 +61927 4 3 40760 5 0 1 +61933 1 61928 1 +61933 2 5 61932 1 +61933 3 61928 1 0 1 +61933 4 5 61581 3 0 1 +61949 1 61947 1 +61949 2 2 61943 1 +61949 3 61947 9 0 1 +61949 4 2 53327 3 0 1 +61961 1 61958 1 +61961 2 3 61955 1 +61961 3 61958 14 0 1 +61961 4 3 61949 0 0 1 +61967 1 61962 1 +61967 2 5 61966 1 +61967 3 61962 5 0 1 +61967 4 5 60581 2 0 1 +61979 1 61977 1 +61979 2 2 61973 1 +61979 3 61977 2 0 1 +61979 4 2 43937 4 0 1 +61981 1 61974 1 +61981 2 7 61979 1 +61981 3 61974 3 0 1 +61981 4 7 42871 4 0 1 +61987 1 61985 1 +61987 2 2 61983 1 +61987 3 61985 4 0 1 +61987 4 2 45800 14 0 1 +61991 1 61978 1 +61991 2 13 61989 1 +61991 3 61978 1 0 1 +61991 4 13 48932 7 0 1 +62003 1 62001 1 +62003 2 2 61999 1 +62003 3 62001 3 0 1 +62003 4 2 61007 8 0 1 +62011 1 62009 1 +62011 2 2 62010 1 +62011 3 62009 5 0 1 +62011 4 2 34612 6 0 1 +62017 1 62007 1 +62017 2 10 62016 1 +62017 3 62007 5 0 1 +62017 4 10 53517 6 0 1 +62039 1 62022 1 +62039 2 17 62037 1 +62039 3 62022 1 0 1 +62039 4 17 59403 4 0 1 +62047 1 62044 1 +62047 2 3 62046 1 +62047 3 62044 1 0 1 +62047 4 3 59196 5 0 1 +62053 1 62051 1 +62053 2 2 62052 1 +62053 3 62051 5 0 1 +62053 4 2 51561 7 0 1 +62057 1 62054 1 +62057 2 3 62050 1 +62057 3 62054 4 0 1 +62057 4 3 51886 1 0 1 +62071 1 62064 1 +62071 2 7 62062 1 +62071 3 62064 1 0 1 +62071 4 7 38517 3 0 1 +62081 1 62075 1 +62081 2 6 62078 1 +62081 3 62075 6 0 1 +62081 4 6 46374 0 0 1 +62099 1 62097 1 +62099 2 2 62095 1 +62099 3 62097 3 0 1 +62099 4 2 44457 7 0 1 +62119 1 62112 1 +62119 2 7 62116 1 +62119 3 62112 10 0 1 +62119 4 7 52234 5 0 1 +62129 1 62126 1 +62129 2 3 62124 1 +62129 3 62126 1 0 1 +62129 4 3 41537 2 0 1 +62131 1 62129 1 +62131 2 2 62127 1 +62131 3 62129 6 0 1 +62131 4 2 51020 1 0 1 +62137 1 62130 1 +62137 2 7 62130 1 +62137 3 62130 4 0 1 +62137 4 7 47863 14 0 1 +62141 1 62139 1 +62141 2 2 62137 1 +62141 3 62139 3 0 1 +62141 4 2 45909 6 0 1 +62143 1 62140 1 +62143 2 3 62141 1 +62143 3 62140 9 0 1 +62143 4 3 42592 3 0 1 +62171 1 62169 1 +62171 2 2 62165 1 +62171 3 62169 2 0 1 +62171 4 2 45467 0 0 1 +62189 1 62187 1 +62189 2 2 62185 1 +62189 3 62187 2 0 1 +62189 4 2 46417 6 0 1 +62191 1 62188 1 +62191 2 3 62190 1 +62191 3 62188 1 0 1 +62191 4 3 36223 2 0 1 +62201 1 62198 1 +62201 2 3 62195 1 +62201 3 62198 11 0 1 +62201 4 3 62189 0 0 1 +62207 1 62202 1 +62207 2 5 62205 1 +62207 3 62202 3 0 1 +62207 4 5 59062 9 0 1 +62213 1 62211 1 +62213 2 2 62209 1 +62213 3 62211 15 0 1 +62213 4 2 33853 12 0 1 +62219 1 62217 1 +62219 2 2 62218 1 +62219 3 62217 3 0 1 +62219 4 2 61608 2 0 1 +62233 1 62226 1 +62233 2 7 62230 1 +62233 3 62226 3 0 1 +62233 4 7 42282 10 0 1 +62273 1 62270 1 +62273 2 3 62272 1 +62273 3 62270 10 0 1 +62273 4 3 34964 4 0 1 +62297 1 62294 1 +62297 2 3 62291 1 +62297 3 62294 4 0 1 +62297 4 3 42663 1 0 1 +62299 1 62297 1 +62299 2 2 62298 1 +62299 3 62297 6 0 1 +62299 4 2 40082 17 0 1 +62303 1 62298 1 +62303 2 5 62302 1 +62303 3 62298 1 0 1 +62303 4 5 53972 2 0 1 +62311 1 62305 1 +62311 2 6 62309 1 +62311 3 62305 1 0 1 +62311 4 6 55233 4 0 1 +62323 1 62321 1 +62323 2 2 62319 1 +62323 3 62321 6 0 1 +62323 4 2 46418 8 0 1 +62327 1 62322 1 +62327 2 5 62322 1 +62327 3 62322 2 0 1 +62327 4 5 41669 6 0 1 +62347 1 62344 1 +62347 2 3 62346 1 +62347 3 62344 3 0 1 +62347 4 3 45311 2 0 1 +62351 1 62344 1 +62351 2 7 62350 1 +62351 3 62344 3 0 1 +62351 4 7 50862 3 0 1 +62383 1 62378 1 +62383 2 5 62381 1 +62383 3 62378 6 0 1 +62383 4 5 62379 3 0 1 +62401 1 62384 1 +62401 2 17 62398 1 +62401 3 62384 1 0 1 +62401 4 17 33894 17 0 1 +62417 1 62414 1 +62417 2 3 62411 1 +62417 3 62414 6 0 1 +62417 4 3 55883 9 0 1 +62423 1 62418 1 +62423 2 5 62422 1 +62423 3 62418 5 0 1 +62423 4 5 47543 2 0 1 +62459 1 62453 1 +62459 2 6 62458 1 +62459 3 62453 2 0 1 +62459 4 6 33256 2 0 1 +62467 1 62464 1 +62467 2 3 62462 1 +62467 3 62464 7 0 1 +62467 4 3 55812 11 0 1 +62473 1 62468 1 +62473 2 5 62468 1 +62473 3 62468 1 0 1 +62473 4 5 38917 15 0 1 +62477 1 62475 1 +62477 2 2 62469 1 +62477 3 62475 10 0 1 +62477 4 2 37627 11 0 1 +62483 1 62481 1 +62483 2 2 62479 1 +62483 3 62481 3 0 1 +62483 4 2 42208 8 0 1 +62497 1 62487 1 +62497 2 10 62496 1 +62497 3 62487 2 0 1 +62497 4 10 57867 12 0 1 +62501 1 62499 1 +62501 2 2 62500 1 +62501 3 62499 5 0 1 +62501 4 2 45749 3 0 1 +62507 1 62505 1 +62507 2 2 62503 1 +62507 3 62505 3 0 1 +62507 4 2 42044 7 0 1 +62533 1 62531 1 +62533 2 2 62529 1 +62533 3 62531 4 0 1 +62533 4 2 49614 6 0 1 +62539 1 62537 1 +62539 2 2 62535 1 +62539 3 62537 2 0 1 +62539 4 2 31486 8 0 1 +62549 1 62547 1 +62549 2 2 62545 1 +62549 3 62547 3 0 1 +62549 4 2 44535 6 0 1 +62563 1 62560 1 +62563 2 3 62562 1 +62563 3 62560 4 0 1 +62563 4 3 36586 2 0 1 +62581 1 62579 1 +62581 2 2 62577 1 +62581 3 62579 4 0 1 +62581 4 2 59696 10 0 1 +62591 1 62584 1 +62591 2 7 62590 1 +62591 3 62584 7 0 1 +62591 4 7 47670 3 0 1 +62597 1 62595 1 +62597 2 2 62596 1 +62597 3 62595 2 0 1 +62597 4 2 44147 3 0 1 +62603 1 62601 1 +62603 2 2 62599 1 +62603 3 62601 9 0 1 +62603 4 2 39073 8 0 1 +62617 1 62612 1 +62617 2 5 62616 1 +62617 3 62612 3 0 1 +62617 4 5 54329 6 0 1 +62627 1 62625 1 +62627 2 2 62626 1 +62627 3 62625 2 0 1 +62627 4 2 62014 2 0 1 +62633 1 62630 1 +62633 2 3 62632 1 +62633 3 62630 1 0 1 +62633 4 3 35689 4 0 1 +62639 1 62628 1 +62639 2 11 62636 1 +62639 3 62628 4 0 1 +62639 4 11 39672 5 0 1 +62653 1 62651 1 +62653 2 2 62652 1 +62653 3 62651 2 0 1 +62653 4 2 59122 3 0 1 +62659 1 62656 1 +62659 2 3 62652 1 +62659 3 62656 1 0 1 +62659 4 3 32070 5 0 1 +62683 1 62680 1 +62683 2 3 62676 1 +62683 3 62680 7 0 1 +62683 4 3 62123 2 0 1 +62687 1 62682 1 +62687 2 5 62685 1 +62687 3 62682 1 0 1 +62687 4 5 55913 14 0 1 +62701 1 62699 1 +62701 2 2 62697 1 +62701 3 62699 6 0 1 +62701 4 2 39258 6 0 1 +62723 1 62721 1 +62723 2 2 62722 1 +62723 3 62721 2 0 1 +62723 4 2 59565 2 0 1 +62731 1 62721 1 +62731 2 10 62730 1 +62731 3 62721 6 0 1 +62731 4 10 36959 5 0 1 +62743 1 62736 1 +62743 2 7 62732 1 +62743 3 62736 1 0 1 +62743 4 7 33771 1 0 1 +62753 1 62750 1 +62753 2 3 62747 1 +62753 3 62750 1 0 1 +62753 4 3 48144 9 0 1 +62761 1 62754 1 +62761 2 7 62754 1 +62761 3 62754 2 0 1 +62761 4 7 42142 0 0 1 +62773 1 62768 1 +62773 2 5 62770 1 +62773 3 62768 8 0 1 +62773 4 5 60647 23 0 1 +62791 1 62788 1 +62791 2 3 62789 1 +62791 3 62788 3 0 1 +62791 4 3 31727 3 0 1 +62801 1 62798 1 +62801 2 3 62796 1 +62801 3 62798 3 0 1 +62801 4 3 57059 2 0 1 +62819 1 62817 1 +62819 2 2 62815 1 +62819 3 62817 2 0 1 +62819 4 2 40689 7 0 1 +62827 1 62824 1 +62827 2 3 62826 1 +62827 3 62824 8 0 1 +62827 4 3 52046 2 0 1 +62851 1 62849 1 +62851 2 2 62850 1 +62851 3 62849 6 0 1 +62851 4 2 62844 8 0 1 +62861 1 62858 1 +62861 2 3 62860 1 +62861 3 62858 3 0 1 +62861 4 3 50905 3 0 1 +62869 1 62867 1 +62869 2 2 62865 1 +62869 3 62867 4 0 1 +62869 4 2 35329 6 0 1 +62873 1 62870 1 +62873 2 3 62867 1 +62873 3 62870 1 0 1 +62873 4 3 44762 11 0 1 +62897 1 62894 1 +62897 2 3 62896 1 +62897 3 62894 6 0 1 +62897 4 3 54782 7 0 1 +62903 1 62898 1 +62903 2 5 62902 1 +62903 3 62898 1 0 1 +62903 4 5 34079 9 0 1 +62921 1 62907 1 +62921 2 14 62916 1 +62921 3 62907 2 0 1 +62921 4 14 62089 8 0 1 +62927 1 62922 1 +62927 2 5 62920 1 +62927 3 62922 10 0 1 +62927 4 5 38104 2 0 1 +62929 1 62915 1 +62929 2 14 62926 1 +62929 3 62915 2 0 1 +62929 4 14 46660 24 0 1 +62939 1 62937 1 +62939 2 2 62933 1 +62939 3 62937 2 0 1 +62939 4 2 43142 4 0 1 +62969 1 62966 1 +62969 2 3 62963 1 +62969 3 62966 14 0 1 +62969 4 3 62957 0 0 1 +62971 1 62961 1 +62971 2 10 62967 1 +62971 3 62961 4 0 1 +62971 4 10 52750 2 0 1 +62981 1 62979 1 +62981 2 2 62977 1 +62981 3 62979 2 0 1 +62981 4 2 56568 7 0 1 +62983 1 62978 1 +62983 2 5 62981 1 +62983 3 62978 3 0 1 +62983 4 5 62979 3 0 1 +62987 1 62985 1 +62987 2 2 62983 1 +62987 3 62985 3 0 1 +62987 4 2 44134 8 0 1 +62989 1 62987 1 +62989 2 2 62985 1 +62989 3 62987 6 0 1 +62989 4 2 42878 10 0 1 +63029 1 63027 1 +63029 2 2 63025 1 +63029 3 63027 3 0 1 +63029 4 2 38322 6 0 1 +63031 1 63028 1 +63031 2 3 63029 1 +63031 3 63028 7 0 1 +63031 4 3 51837 3 0 1 +63059 1 63057 1 +63059 2 2 63049 1 +63059 3 63057 11 0 1 +63059 4 2 42683 0 0 1 +63067 1 63065 1 +63067 2 2 63063 1 +63067 3 63065 6 0 1 +63067 4 2 45304 8 0 1 +63073 1 63068 1 +63073 2 5 63072 1 +63073 3 63068 1 0 1 +63073 4 5 45905 6 0 1 +63079 1 63076 1 +63079 2 3 63073 1 +63079 3 63076 3 0 1 +63079 4 3 42838 7 0 1 +63097 1 63092 1 +63097 2 5 63092 1 +63097 3 63092 2 0 1 +63097 4 5 43546 10 0 1 +63103 1 63100 1 +63103 2 3 63102 1 +63103 3 63100 1 0 1 +63103 4 3 59006 2 0 1 +63113 1 63110 1 +63113 2 3 63107 1 +63113 3 63110 1 0 1 +63113 4 3 38456 1 0 1 +63127 1 63124 1 +63127 2 3 63125 1 +63127 3 63124 1 0 1 +63127 4 3 51151 6 0 1 +63131 1 63129 1 +63131 2 2 63130 1 +63131 3 63129 3 0 1 +63131 4 2 41900 4 0 1 +63149 1 63147 1 +63149 2 2 63141 1 +63149 3 63147 3 0 1 +63149 4 2 36683 0 0 1 +63179 1 63177 1 +63179 2 2 63175 1 +63179 3 63177 2 0 1 +63179 4 2 39541 8 0 1 +63197 1 63195 1 +63197 2 2 63188 1 +63197 3 63195 10 0 1 +63197 4 2 34917 4 0 1 +63199 1 63196 1 +63199 2 3 63194 1 +63199 3 63196 5 0 1 +63199 4 3 45062 7 0 1 +63211 1 63204 1 +63211 2 7 63209 1 +63211 3 63204 1 0 1 +63211 4 7 38146 6 0 1 +63241 1 63234 1 +63241 2 7 63234 1 +63241 3 63234 4 0 1 +63241 4 7 51494 0 0 1 +63247 1 63242 1 +63247 2 5 63246 1 +63247 3 63242 1 0 1 +63247 4 5 59655 5 0 1 +63277 1 63275 1 +63277 2 2 63273 1 +63277 3 63275 6 0 1 +63277 4 2 35827 6 0 1 +63281 1 63275 1 +63281 2 6 63278 1 +63281 3 63275 4 0 1 +63281 4 6 43459 0 0 1 +63299 1 63297 1 +63299 2 2 63298 1 +63299 3 63297 3 0 1 +63299 4 2 60566 2 0 1 +63311 1 63294 1 +63311 2 17 63310 1 +63311 3 63294 1 0 1 +63311 4 17 51397 3 0 1 +63313 1 63308 1 +63313 2 5 63310 1 +63313 3 63308 1 0 1 +63313 4 5 34930 10 0 1 +63317 1 63315 1 +63317 2 2 63313 1 +63317 3 63315 7 0 1 +63317 4 2 57640 7 0 1 +63331 1 63329 1 +63331 2 2 63327 1 +63331 3 63329 2 0 1 +63331 4 2 60540 8 0 1 +63337 1 63332 1 +63337 2 5 63336 1 +63337 3 63332 5 0 1 +63337 4 5 38091 16 0 1 +63347 1 63345 1 +63347 2 2 63343 1 +63347 3 63345 3 0 1 +63347 4 2 53866 8 0 1 +63353 1 63350 1 +63353 2 3 63347 1 +63353 3 63350 11 0 1 +63353 4 3 62641 1 0 1 +63361 1 63324 1 +63361 2 37 63344 1 +63361 3 63324 7 0 1 +63361 4 37 46878 36 0 1 +63367 1 63364 1 +63367 2 3 63366 1 +63367 3 63364 1 0 1 +63367 4 3 34185 2 0 1 +63377 1 63374 1 +63377 2 3 63372 1 +63377 3 63374 1 0 1 +63377 4 3 52720 0 0 1 +63389 1 63387 1 +63389 2 2 63385 1 +63389 3 63387 2 0 1 +63389 4 2 48122 12 0 1 +63391 1 63388 1 +63391 2 3 63389 1 +63391 3 63388 1 0 1 +63391 4 3 52937 6 0 1 +63397 1 63395 1 +63397 2 2 63396 1 +63397 3 63395 5 0 1 +63397 4 2 55543 6 0 1 +63409 1 63402 1 +63409 2 7 63402 1 +63409 3 63402 7 0 1 +63409 4 7 62501 0 0 1 +63419 1 63417 1 +63419 2 2 63418 1 +63419 3 63417 3 0 1 +63419 4 2 47019 4 0 1 +63421 1 63419 1 +63421 2 2 63417 1 +63421 3 63419 5 0 1 +63421 4 2 41070 6 0 1 +63439 1 63436 1 +63439 2 3 63438 1 +63439 3 63436 1 0 1 +63439 4 3 61658 2 0 1 +63443 1 63441 1 +63443 2 2 63439 1 +63443 3 63441 3 0 1 +63443 4 2 50612 7 0 1 +63463 1 63458 1 +63463 2 5 63462 1 +63463 3 63458 10 0 1 +63463 4 5 59293 3 0 1 +63467 1 63465 1 +63467 2 2 63466 1 +63467 3 63465 2 0 1 +63467 4 2 50599 4 0 1 +63473 1 63470 1 +63473 2 3 63468 1 +63473 3 63470 1 0 1 +63473 4 3 42553 0 0 1 +63487 1 63484 1 +63487 2 3 63486 1 +63487 3 63484 7 0 1 +63487 4 3 45109 5 0 1 +63493 1 63491 1 +63493 2 2 63492 1 +63493 3 63491 2 0 1 +63493 4 2 32266 6 0 1 +63499 1 63496 1 +63499 2 3 63498 1 +63499 3 63496 4 0 1 +63499 4 3 53027 2 0 1 +63521 1 63518 1 +63521 2 3 63520 1 +63521 3 63518 7 0 1 +63521 4 3 44157 4 0 1 +63527 1 63522 1 +63527 2 5 63526 1 +63527 3 63522 1 0 1 +63527 4 5 59118 2 0 1 +63533 1 63530 1 +63533 2 3 63531 1 +63533 3 63530 3 0 1 +63533 4 3 45853 7 0 1 +63541 1 63539 1 +63541 2 2 63537 1 +63541 3 63539 6 0 1 +63541 4 2 39262 6 0 1 +63559 1 63556 1 +63559 2 3 63557 1 +63559 3 63556 4 0 1 +63559 4 3 55017 6 0 1 +63577 1 63572 1 +63577 2 5 63576 1 +63577 3 63572 1 0 1 +63577 4 5 52829 6 0 1 +63587 1 63585 1 +63587 2 2 63583 1 +63587 3 63585 3 0 1 +63587 4 2 50506 11 0 1 +63589 1 63587 1 +63589 2 2 63585 1 +63589 3 63587 6 0 1 +63589 4 2 44259 12 0 1 +63599 1 63592 1 +63599 2 7 63598 1 +63599 3 63592 2 0 1 +63599 4 7 49293 3 0 1 +63601 1 63594 1 +63601 2 7 63598 1 +63601 3 63594 2 0 1 +63601 4 7 63244 16 0 1 +63607 1 63604 1 +63607 2 3 63605 1 +63607 3 63604 1 0 1 +63607 4 3 63603 4 0 1 +63611 1 63609 1 +63611 2 2 63606 1 +63611 3 63609 5 0 1 +63611 4 2 32024 3 0 1 +63617 1 63614 1 +63617 2 3 63612 1 +63617 3 63614 3 0 1 +63617 4 3 42887 0 0 1 +63629 1 63627 1 +63629 2 2 63628 1 +63629 3 63627 3 0 1 +63629 4 2 54409 9 0 1 +63647 1 63642 1 +63647 2 5 63642 1 +63647 3 63642 1 0 1 +63647 4 5 39696 7 0 1 +63649 1 63642 1 +63649 2 7 63646 1 +63649 3 63642 3 0 1 +63649 4 7 48666 17 0 1 +63659 1 63657 1 +63659 2 2 63655 1 +63659 3 63657 2 0 1 +63659 4 2 44961 7 0 1 +63667 1 63665 1 +63667 2 2 63663 1 +63667 3 63665 6 0 1 +63667 4 2 61260 10 0 1 +63671 1 63660 1 +63671 2 11 63669 1 +63671 3 63660 5 0 1 +63671 4 11 62157 3 0 1 +63689 1 63686 1 +63689 2 3 63683 1 +63689 3 63686 3 0 1 +63689 4 3 63677 0 0 1 +63691 1 63676 1 +63691 2 15 63690 1 +63691 3 63676 1 0 1 +63691 4 15 34653 6 0 1 +63697 1 63692 1 +63697 2 5 63694 1 +63697 3 63692 1 0 1 +63697 4 5 63686 14 0 1 +63703 1 63700 1 +63703 2 3 63702 1 +63703 3 63700 3 0 1 +63703 4 3 44331 2 0 1 +63709 1 63703 1 +63709 2 6 63708 1 +63709 3 63703 1 0 1 +63709 4 6 52134 27 0 1 +63719 1 63706 1 +63719 2 13 63715 1 +63719 3 63706 1 0 1 +63719 4 13 49694 6 0 1 +63727 1 63721 1 +63727 2 6 63726 1 +63727 3 63721 1 0 1 +63727 4 6 60312 9 0 1 +63737 1 63734 1 +63737 2 3 63729 1 +63737 3 63734 3 0 1 +63737 4 3 44762 2 0 1 +63743 1 63738 1 +63743 2 5 63738 1 +63743 3 63738 7 0 1 +63743 4 5 44314 6 0 1 +63761 1 63758 1 +63761 2 3 63755 1 +63761 3 63758 5 0 1 +63761 4 3 63749 0 0 1 +63773 1 63771 1 +63773 2 2 63772 1 +63773 3 63771 2 0 1 +63773 4 2 51531 3 0 1 +63781 1 63779 1 +63781 2 2 63777 1 +63781 3 63779 4 0 1 +63781 4 2 46335 6 0 1 +63793 1 63788 1 +63793 2 5 63792 1 +63793 3 63788 1 0 1 +63793 4 5 46437 11 0 1 +63799 1 63793 1 +63799 2 6 63798 1 +63799 3 63793 3 0 1 +63799 4 6 33492 3 0 1 +63803 1 63801 1 +63803 2 2 63802 1 +63803 3 63801 3 0 1 +63803 4 2 45662 2 0 1 +63809 1 63806 1 +63809 2 3 63804 1 +63809 3 63806 4 0 1 +63809 4 3 38517 2 0 1 +63823 1 63820 1 +63823 2 3 63821 1 +63823 3 63820 10 0 1 +63823 4 3 44743 3 0 1 +63839 1 63810 1 +63839 2 29 63836 1 +63839 3 63810 6 0 1 +63839 4 29 52266 4 0 1 +63841 1 63824 1 +63841 2 17 63840 1 +63841 3 63824 1 0 1 +63841 4 17 32205 18 0 1 +63853 1 63851 1 +63853 2 2 63852 1 +63853 3 63851 2 0 1 +63853 4 2 60444 6 0 1 +63857 1 63854 1 +63857 2 3 63856 1 +63857 3 63854 4 0 1 +63857 4 3 41700 4 0 1 +63863 1 63858 1 +63863 2 5 63860 1 +63863 3 63858 5 0 1 +63863 4 5 50800 6 0 1 +63901 1 63894 1 +63901 2 7 63899 1 +63901 3 63894 3 0 1 +63901 4 7 42432 4 0 1 +63907 1 63905 1 +63907 2 2 63903 1 +63907 3 63905 4 0 1 +63907 4 2 36755 10 0 1 +63913 1 63900 1 +63913 2 13 63912 1 +63913 3 63900 4 0 1 +63913 4 13 50745 6 0 1 +63929 1 63926 1 +63929 2 3 63928 1 +63929 3 63926 3 0 1 +63929 4 3 51391 4 0 1 +63949 1 63947 1 +63949 2 2 63945 1 +63949 3 63947 5 0 1 +63949 4 2 62108 6 0 1 +63977 1 63974 1 +63977 2 3 63966 1 +63977 3 63974 15 0 1 +63977 4 3 47618 1 0 1 +63997 1 63995 1 +63997 2 2 63996 1 +63997 3 63995 2 0 1 +63997 4 2 49095 3 0 1 +64007 1 64002 1 +64007 2 5 64005 1 +64007 3 64002 1 0 1 +64007 4 5 51492 8 0 1 +64013 1 64011 1 +64013 2 2 64012 1 +64013 3 64011 2 0 1 +64013 4 2 36728 6 0 1 +64019 1 64017 1 +64019 2 2 64015 1 +64019 3 64017 3 0 1 +64019 4 2 55357 7 0 1 +64033 1 64028 1 +64033 2 5 64032 1 +64033 3 64028 2 0 1 +64033 4 5 42155 12 0 1 +64037 1 64035 1 +64037 2 2 64033 1 +64037 3 64035 3 0 1 +64037 4 2 40137 9 0 1 +64063 1 64060 1 +64063 2 3 64062 1 +64063 3 64060 3 0 1 +64063 4 3 56576 5 0 1 +64067 1 64062 1 +64067 2 5 64066 1 +64067 3 64062 5 0 1 +64067 4 5 33568 13 0 1 +64081 1 64070 1 +64081 2 11 64078 1 +64081 3 64070 2 0 1 +64081 4 11 55613 14 0 1 +64091 1 64089 1 +64091 2 2 64090 1 +64091 3 64089 3 0 1 +64091 4 2 39373 4 0 1 +64109 1 64107 1 +64109 2 2 64108 1 +64109 3 64107 4 0 1 +64109 4 2 42240 4 0 1 +64123 1 64121 1 +64123 2 2 64122 1 +64123 3 64121 2 0 1 +64123 4 2 55300 2 0 1 +64151 1 64134 1 +64151 2 17 64150 1 +64151 3 64134 10 0 1 +64151 4 17 38195 3 0 1 +64153 1 64148 1 +64153 2 5 64148 1 +64153 3 64148 2 0 1 +64153 4 5 45494 15 0 1 +64157 1 64155 1 +64157 2 2 64153 1 +64157 3 64155 3 0 1 +64157 4 2 38351 7 0 1 +64171 1 64164 1 +64171 2 7 64169 1 +64171 3 64164 4 0 1 +64171 4 7 39100 6 0 1 +64187 1 64185 1 +64187 2 2 64183 1 +64187 3 64185 3 0 1 +64187 4 2 57561 8 0 1 +64189 1 64187 1 +64189 2 2 64188 1 +64189 3 64187 6 0 1 +64189 4 2 54808 7 0 1 +64217 1 64214 1 +64217 2 3 64216 1 +64217 3 64214 1 0 1 +64217 4 3 46207 4 0 1 +64223 1 64218 1 +64223 2 5 64221 1 +64223 3 64218 3 0 1 +64223 4 5 64219 3 0 1 +64231 1 64219 1 +64231 2 12 64230 1 +64231 3 64219 1 0 1 +64231 4 12 48608 8 0 1 +64237 1 64235 1 +64237 2 2 64236 1 +64237 3 64235 6 0 1 +64237 4 2 56727 3 0 1 +64271 1 64264 1 +64271 2 7 64270 1 +64271 3 64264 4 0 1 +64271 4 7 46350 3 0 1 +64279 1 64250 1 +64279 2 29 64278 1 +64279 3 64250 1 0 1 +64279 4 29 62098 2 0 1 +64283 1 64281 1 +64283 2 2 64279 1 +64283 3 64281 3 0 1 +64283 4 2 32361 8 0 1 +64301 1 64299 1 +64301 2 2 64297 1 +64301 3 64299 3 0 1 +64301 4 2 37355 1 0 1 +64303 1 64297 1 +64303 2 6 64300 1 +64303 3 64297 10 0 1 +64303 4 6 32487 5 0 1 +64319 1 64306 1 +64319 2 13 64315 1 +64319 3 64306 1 0 1 +64319 4 13 42640 7 0 1 +64327 1 64324 1 +64327 2 3 64326 1 +64327 3 64324 3 0 1 +64327 4 3 33104 5 0 1 +64333 1 64331 1 +64333 2 2 64329 1 +64333 3 64331 5 0 1 +64333 4 2 50093 6 0 1 +64373 1 64371 1 +64373 2 2 64368 1 +64373 3 64371 7 0 1 +64373 4 2 42537 0 0 1 +64381 1 64379 1 +64381 2 2 64377 1 +64381 3 64379 2 0 1 +64381 4 2 54656 12 0 1 +64399 1 64396 1 +64399 2 3 64397 1 +64399 3 64396 3 0 1 +64399 4 3 38922 3 0 1 +64403 1 64398 1 +64403 2 5 64401 1 +64403 3 64398 1 0 1 +64403 4 5 53529 0 0 1 +64433 1 64430 1 +64433 2 3 64428 1 +64433 3 64430 3 0 1 +64433 4 3 55938 0 0 1 +64439 1 64432 1 +64439 2 7 64437 1 +64439 3 64432 2 0 1 +64439 4 7 63003 4 0 1 +64451 1 64449 1 +64451 2 2 64447 1 +64451 3 64449 2 0 1 +64451 4 2 54312 7 0 1 +64453 1 64451 1 +64453 2 2 64449 1 +64453 3 64451 6 0 1 +64453 4 2 38959 6 0 1 +64483 1 64481 1 +64483 2 2 64479 1 +64483 3 64481 2 0 1 +64483 4 2 50586 1 0 1 +64489 1 64482 1 +64489 2 7 64486 1 +64489 3 64482 1 0 1 +64489 4 7 54347 14 0 1 +64499 1 64497 1 +64499 2 2 64495 1 +64499 3 64497 2 0 1 +64499 4 2 50377 7 0 1 +64513 1 64508 1 +64513 2 5 64512 1 +64513 3 64508 1 0 1 +64513 4 5 50578 6 0 1 +64553 1 64550 1 +64553 2 3 64548 1 +64553 3 64550 3 0 1 +64553 4 3 60008 0 0 1 +64567 1 64564 1 +64567 2 3 64566 1 +64567 3 64564 1 0 1 +64567 4 3 50465 5 0 1 +64577 1 64574 1 +64577 2 3 64571 1 +64577 3 64574 1 0 1 +64577 4 3 36260 11 0 1 +64579 1 64577 1 +64579 2 2 64573 1 +64579 3 64577 2 0 1 +64579 4 2 59371 3 0 1 +64591 1 64588 1 +64591 2 3 64590 1 +64591 3 64588 1 0 1 +64591 4 3 53938 3 0 1 +64601 1 64598 1 +64601 2 3 64595 1 +64601 3 64598 6 0 1 +64601 4 3 64589 0 0 1 +64609 1 64574 1 +64609 2 35 64596 1 +64609 3 64574 1 0 1 +64609 4 35 37869 20 0 1 +64613 1 64611 1 +64613 2 2 64612 1 +64613 3 64611 3 0 1 +64613 4 2 43964 3 0 1 +64621 1 64615 1 +64621 2 6 64620 1 +64621 3 64615 1 0 1 +64621 4 6 41431 7 0 1 +64627 1 64622 1 +64627 2 5 64626 1 +64627 3 64622 5 0 1 +64627 4 5 57281 10 0 1 +64633 1 64628 1 +64633 2 5 64632 1 +64633 3 64628 5 0 1 +64633 4 5 57835 12 0 1 +64661 1 64659 1 +64661 2 2 64657 1 +64661 3 64659 2 0 1 +64661 4 2 52413 6 0 1 +64663 1 64657 1 +64663 2 6 64662 1 +64663 3 64657 2 0 1 +64663 4 6 57699 3 0 1 +64667 1 64665 1 +64667 2 2 64663 1 +64667 3 64665 3 0 1 +64667 4 2 58548 8 0 1 +64679 1 64662 1 +64679 2 17 64674 1 +64679 3 64662 5 0 1 +64679 4 17 60594 6 0 1 +64693 1 64691 1 +64693 2 2 64692 1 +64693 3 64691 6 0 1 +64693 4 2 62227 3 0 1 +64709 1 64706 1 +64709 2 3 64704 1 +64709 3 64706 6 0 1 +64709 4 3 56549 2 0 1 +64717 1 64715 1 +64717 2 2 64713 1 +64717 3 64715 4 0 1 +64717 4 2 42839 10 0 1 +64747 1 64742 1 +64747 2 5 64746 1 +64747 3 64742 1 0 1 +64747 4 5 36222 5 0 1 +64763 1 64761 1 +64763 2 2 64759 1 +64763 3 64761 3 0 1 +64763 4 2 43934 16 0 1 +64781 1 64779 1 +64781 2 2 64776 1 +64781 3 64779 4 0 1 +64781 4 2 38678 2 0 1 +64783 1 64778 1 +64783 2 5 64782 1 +64783 3 64778 1 0 1 +64783 4 5 58349 2 0 1 +64793 1 64790 1 +64793 2 3 64787 1 +64793 3 64790 6 0 1 +64793 4 3 41440 9 0 1 +64811 1 64809 1 +64811 2 2 64810 1 +64811 3 64809 12 0 1 +64811 4 2 58749 2 0 1 +64817 1 64814 1 +64817 2 3 64811 1 +64817 3 64814 4 0 1 +64817 4 3 59280 9 0 1 +64849 1 64836 1 +64849 2 13 64848 1 +64849 3 64836 4 0 1 +64849 4 13 41497 14 0 1 +64853 1 64851 1 +64853 2 2 64849 1 +64853 3 64851 3 0 1 +64853 4 2 57996 1 0 1 +64871 1 64864 1 +64871 2 7 64870 1 +64871 3 64864 7 0 1 +64871 4 7 39297 3 0 1 +64877 1 64874 1 +64877 2 3 64876 1 +64877 3 64874 7 0 1 +64877 4 3 60577 6 0 1 +64879 1 64873 1 +64879 2 6 64878 1 +64879 3 64873 3 0 1 +64879 4 6 42037 3 0 1 +64891 1 64881 1 +64891 2 10 64890 1 +64891 3 64881 5 0 1 +64891 4 10 64217 2 0 1 +64901 1 64899 1 +64901 2 2 64897 1 +64901 3 64899 3 0 1 +64901 4 2 52960 6 0 1 +64919 1 64912 1 +64919 2 7 64917 1 +64919 3 64912 9 0 1 +64919 4 7 54303 5 0 1 +64921 1 64914 1 +64921 2 7 64914 1 +64921 3 64914 1 0 1 +64921 4 7 32920 0 0 1 +64927 1 64924 1 +64927 2 3 64925 1 +64927 3 64924 4 0 1 +64927 4 3 55506 6 0 1 +64937 1 64934 1 +64937 2 3 64932 1 +64937 3 64934 1 0 1 +64937 4 3 53518 0 0 1 +64951 1 64948 1 +64951 2 3 64950 1 +64951 3 64948 4 0 1 +64951 4 3 56365 2 0 1 +64969 1 64956 1 +64969 2 13 64968 1 +64969 3 64956 1 0 1 +64969 4 13 53294 14 0 1 +64997 1 64995 1 +64997 2 2 64993 1 +64997 3 64995 3 0 1 +64997 4 2 52445 7 0 1 +65003 1 64998 1 +65003 2 5 65001 1 +65003 3 64998 3 0 1 +65003 4 5 34388 0 0 1 +65011 1 65009 1 +65011 2 2 65007 1 +65011 3 65009 5 0 1 +65011 4 2 57311 8 0 1 +65027 1 65025 1 +65027 2 2 65021 1 +65027 3 65025 4 0 1 +65027 4 2 54894 4 0 1 +65029 1 65027 1 +65029 2 2 65028 1 +65029 3 65027 6 0 1 +65029 4 2 56829 3 0 1 +65033 1 65030 1 +65033 2 3 65028 1 +65033 3 65030 1 0 1 +65033 4 3 58622 0 0 1 +65053 1 65048 1 +65053 2 5 65050 1 +65053 3 65048 9 0 1 +65053 4 5 57093 1 0 1 +65063 1 65058 1 +65063 2 5 65061 1 +65063 3 65058 6 0 1 +65063 4 5 51223 10 0 1 +65071 1 65068 1 +65071 2 3 65070 1 +65071 3 65068 6 0 1 +65071 4 3 40238 3 0 1 +65089 1 65082 1 +65089 2 7 65086 1 +65089 3 65082 2 0 1 +65089 4 7 65070 22 0 1 +65099 1 65097 1 +65099 2 2 65090 1 +65099 3 65097 3 0 1 +65099 4 2 53861 1 0 1 +65101 1 65099 1 +65101 2 2 65097 1 +65101 3 65099 2 0 1 +65101 4 2 61904 10 0 1 +65111 1 65104 1 +65111 2 7 65110 1 +65111 3 65104 1 0 1 +65111 4 7 58892 2 0 1 +65119 1 65116 1 +65119 2 3 65114 1 +65119 3 65116 4 0 1 +65119 4 3 47853 7 0 1 +65123 1 65121 1 +65123 2 2 65119 1 +65123 3 65121 3 0 1 +65123 4 2 55674 8 0 1 +65129 1 65126 1 +65129 2 3 65120 1 +65129 3 65126 1 0 1 +65129 4 3 37272 3 0 1 +65141 1 65139 1 +65141 2 2 65136 1 +65141 3 65139 3 0 1 +65141 4 2 64516 18 0 1 +65147 1 65145 1 +65147 2 2 65146 1 +65147 3 65145 5 0 1 +65147 4 2 41370 10 0 1 +65167 1 65162 1 +65167 2 5 65165 1 +65167 3 65162 3 0 1 +65167 4 5 65163 3 0 1 +65171 1 65169 1 +65171 2 2 65167 1 +65171 3 65169 3 0 1 +65171 4 2 35802 7 0 1 +65173 1 65171 1 +65173 2 2 65172 1 +65173 3 65171 5 0 1 +65173 4 2 58034 6 0 1 +65179 1 65177 1 +65179 2 2 65175 1 +65179 3 65177 2 0 1 +65179 4 2 39472 8 0 1 +65183 1 65178 1 +65183 2 5 65181 1 +65183 3 65178 2 0 1 +65183 4 5 65179 3 0 1 +65203 1 65201 1 +65203 2 2 65202 1 +65203 3 65201 2 0 1 +65203 4 2 56555 10 0 1 +65213 1 65211 1 +65213 2 2 65209 1 +65213 3 65211 3 0 1 +65213 4 2 64642 7 0 1 +65239 1 65236 1 +65239 2 3 65234 1 +65239 3 65236 7 0 1 +65239 4 3 38859 6 0 1 +65257 1 65252 1 +65257 2 5 65252 1 +65257 3 65252 2 0 1 +65257 4 5 49206 12 0 1 +65267 1 65265 1 +65267 2 2 65266 1 +65267 3 65265 2 0 1 +65267 4 2 65260 8 0 1 +65269 1 65267 1 +65269 2 2 65265 1 +65269 3 65267 6 0 1 +65269 4 2 49182 6 0 1 +65287 1 65284 1 +65287 2 3 65286 1 +65287 3 65284 3 0 1 +65287 4 3 40493 5 0 1 +65293 1 65291 1 +65293 2 2 65289 1 +65293 3 65291 6 0 1 +65293 4 2 61269 15 0 1 +65309 1 65307 1 +65309 2 2 65308 1 +65309 3 65307 3 0 1 +65309 4 2 39470 3 0 1 +65323 1 65321 1 +65323 2 2 65322 1 +65323 3 65321 4 0 1 +65323 4 2 51095 2 0 1 +65327 1 65322 1 +65327 2 5 65320 1 +65327 3 65322 1 0 1 +65327 4 5 41871 9 0 1 +65353 1 65348 1 +65353 2 5 65352 1 +65353 3 65348 1 0 1 +65353 4 5 41358 6 0 1 +65357 1 65355 1 +65357 2 2 65356 1 +65357 3 65355 3 0 1 +65357 4 2 58240 3 0 1 +65371 1 65369 1 +65371 2 2 65370 1 +65371 3 65369 4 0 1 +65371 4 2 58383 2 0 1 +65381 1 65378 1 +65381 2 3 65379 1 +65381 3 65378 6 0 1 +65381 4 3 65373 10 0 1 +65393 1 65390 1 +65393 2 3 65386 1 +65393 3 65390 13 0 1 +65393 4 3 40335 13 0 1 +65407 1 65404 1 +65407 2 3 65405 1 +65407 3 65404 1 0 1 +65407 4 3 33781 6 0 1 +65413 1 65408 1 +65413 2 5 65412 1 +65413 3 65408 5 0 1 +65413 4 5 43090 6 0 1 +65419 1 65416 1 +65419 2 3 65418 1 +65419 3 65416 5 0 1 +65419 4 3 33267 7 0 1 +65423 1 65418 1 +65423 2 5 65420 1 +65423 3 65418 2 0 1 +65423 4 5 55880 6 0 1 +65437 1 65431 1 +65437 2 6 65435 1 +65437 3 65431 1 0 1 +65437 4 6 35512 16 0 1 +65447 1 65442 1 +65447 2 5 65445 1 +65447 3 65442 7 0 1 +65447 4 5 34701 5 0 1 +65449 1 65438 1 +65449 2 11 65445 1 +65449 3 65438 1 0 1 +65449 4 11 65435 11 0 1 +65479 1 65472 1 +65479 2 7 65467 1 +65479 3 65472 3 0 1 +65479 4 7 58767 0 0 1 +65497 1 65490 1 +65497 2 7 65490 1 +65497 3 65490 11 0 1 +65497 4 7 42170 14 0 1 +65519 1 65508 1 +65519 2 11 65518 1 +65519 3 65508 2 0 1 +65519 4 11 41499 3 0 1 +65521 1 65504 1 +65521 2 17 65518 1 +65521 3 65504 1 0 1 +65521 4 17 42121 20 0 1 +65537 4 3 48035 7 0 1 +65539 4 2 53504 6 0 1 +65543 4 5 44768 11 0 1 +65551 4 6 65547 6 0 1 +65557 4 5 60449 1 0 1 +65563 4 3 59509 0 0 1 +65579 4 2 39899 7 0 1 +65581 4 2 56596 3 0 1 +65587 4 2 39688 10 0 1 +65599 4 3 48691 3 0 1 +65609 4 3 65597 0 0 1 +65617 4 13 46802 11 0 1 +65629 4 2 64483 2 0 1 +65633 4 3 53051 9 0 1 +65647 4 3 54892 2 0 1 +65651 4 2 58463 2 0 1 +65657 4 3 54810 0 0 1 +65677 4 2 52138 3 0 1 +65687 4 5 39057 5 0 1 +65699 4 2 58874 3 0 1 +65701 4 6 35742 0 0 1 +65707 4 2 62355 2 0 1 +65713 4 10 63124 6 0 1 +65717 4 2 56730 7 0 1 +65719 4 3 65715 4 0 1 +65729 4 3 37642 4 0 1 +65731 4 10 61963 0 0 1 +65761 4 7 65398 16 0 1 +65777 4 3 51201 7 0 1 +65789 4 2 52108 4 0 1 +65809 4 11 36642 23 0 1 +65827 4 2 41666 0 0 1 +65831 4 31 64129 4 0 1 +65837 4 2 56209 18 0 1 +65839 4 3 38189 6 0 1 +65843 4 2 36484 0 0 1 +65851 4 3 44421 3 0 1 +65867 4 2 60917 7 0 1 +65881 4 11 46761 18 0 1 +65899 4 3 56823 3 0 1 +65921 4 3 54248 1 0 1 +65927 4 5 65915 11 0 1 +65929 4 7 45196 14 0 1 +65951 4 13 64135 7 0 1 +65957 4 2 62325 1 0 1 +65963 4 2 38212 7 0 1 +65981 4 2 62459 9 0 1 +65983 4 3 52265 3 0 1 +65993 4 3 37433 1 0 1 +66029 4 2 42133 1 0 1 +66037 4 2 47483 6 0 1 +66041 4 3 51490 2 0 1 +66047 4 5 49893 2 0 1 +66067 4 3 41503 2 0 1 +66071 4 22 33376 7 0 1 +66083 4 2 43702 4 0 1 +66089 4 3 66077 0 0 1 +66103 4 3 64179 3 0 1 +66107 4 2 59363 14 0 1 +66109 4 2 47832 10 0 1 +66137 4 3 36824 0 0 1 +66161 4 3 36306 4 0 1 +66169 4 14 34612 20 0 1 +66173 4 2 48656 4 0 1 +66179 4 2 46239 0 0 1 +66191 4 11 40036 3 0 1 +66221 4 2 43440 6 0 1 +66239 4 17 38430 7 0 1 +66271 4 3 33897 2 0 1 +66293 4 2 36555 1 0 1 +66301 4 22 66277 12 0 1 +66337 4 5 63257 12 0 1 +66343 4 5 53293 2 0 1 +66347 4 2 52402 8 0 1 +66359 4 13 40724 3 0 1 +66361 4 17 54358 35 0 1 +66373 4 2 64893 14 0 1 +66377 4 3 37215 1 0 1 +66383 4 5 46399 10 0 1 +66403 4 2 46989 8 0 1 +66413 4 2 39202 6 0 1 +66431 4 7 43779 9 0 1 +66449 4 3 49019 3 0 1 +66457 4 5 35848 6 0 1 +66463 4 10 47564 2 0 1 +66467 4 2 38103 13 0 1 +66491 4 2 47685 2 0 1 +66499 4 2 46693 6 0 1 +66509 4 2 42163 19 0 1 +66523 4 2 46700 8 0 1 +66529 4 19 34453 26 0 1 +66533 4 2 49134 2 0 1 +66541 4 6 50298 2 0 1 +66553 4 10 57958 6 0 1 +66569 4 3 61968 0 0 1 +66571 4 7 66124 6 0 1 +66587 4 2 46349 2 0 1 +66593 4 3 47462 4 0 1 +66601 4 7 42297 0 0 1 +66617 4 3 37334 0 0 1 +66629 4 2 45627 1 0 1 +66643 4 2 37302 2 0 1 +66653 4 2 37184 1 0 1 +66683 4 5 66675 6 0 1 +66697 4 5 51165 10 0 1 +66701 4 3 39641 3 0 1 +66713 4 3 51248 1 0 1 +66721 4 13 51624 14 0 1 +66733 4 2 49817 10 0 1 +66739 4 2 51010 8 0 1 +66749 4 3 41570 2 0 1 +66751 4 3 61431 7 0 1 +66763 4 3 34439 3 0 1 +66791 4 7 63890 6 0 1 +66797 4 2 46537 6 0 1 +66809 4 6 59124 4 0 1 +66821 4 2 49306 3 0 1 +66841 4 7 35751 24 0 1 +66851 4 2 53354 3 0 1 +66853 4 2 60261 3 0 1 +66863 4 5 61991 2 0 1 +66877 4 5 57414 9 0 1 +66883 4 2 34328 2 0 1 +66889 4 17 40264 20 0 1 +66919 4 6 63458 3 0 1 +66923 4 2 41480 11 0 1 +66931 4 3 49609 2 0 1 +66943 4 3 42749 5 0 1 +66947 4 2 52267 2 0 1 +66949 4 10 59718 12 0 1 +66959 4 7 66950 4 0 1 +66973 4 2 60937 6 0 1 +66977 4 5 47327 6 0 1 +67003 4 2 60348 7 0 1 +67021 4 7 66503 12 0 1 +67033 4 5 40294 16 0 1 +67043 4 2 45952 7 0 1 +67049 4 3 36231 2 0 1 +67057 4 5 66160 20 0 1 +67061 4 2 66482 12 0 1 +67073 4 3 46520 6 0 1 +67079 4 11 59667 2 0 1 +67103 4 5 40335 7 0 1 +67121 4 6 44101 10 0 1 +67129 4 7 47157 17 0 1 +67139 4 2 35718 1 0 1 +67141 4 2 42216 10 0 1 +67153 4 5 60531 10 0 1 +67157 4 2 64015 0 0 1 +67169 4 3 44657 2 0 1 +67181 4 2 40205 6 0 1 +67187 4 2 39121 8 0 1 +67189 4 6 34897 2 0 1 +67211 4 2 66762 8 0 1 +67213 4 2 34141 6 0 1 +67217 4 3 63758 6 0 1 +67219 4 11 52068 1 0 1 +67231 4 3 47479 2 0 1 +67247 4 5 63238 5 0 1 +67261 4 2 54686 3 0 1 +67271 4 14 36213 10 0 1 +67273 4 7 62964 10 0 1 +67289 4 3 60185 7 0 1 +67307 4 2 38062 7 0 1 +67339 4 3 39869 7 0 1 +67343 4 5 67339 3 0 1 +67349 4 2 50278 9 0 1 +67369 4 19 38219 42 0 1 +67391 4 7 40053 3 0 1 +67399 4 3 37548 3 0 1 +67409 4 3 67397 0 0 1 +67411 4 2 40791 8 0 1 +67421 4 2 39383 1 0 1 +67427 4 2 54909 7 0 1 +67429 4 2 62571 3 0 1 +67433 4 3 62067 0 0 1 +67447 4 3 60311 2 0 1 +67453 4 2 45967 21 0 1 +67477 4 2 54738 12 0 1 +67481 4 3 34031 2 0 1 +67489 4 23 65362 27 0 1 +67493 4 2 34037 1 0 1 +67499 4 2 34518 7 0 1 +67511 4 11 52043 3 0 1 +67523 4 2 44628 7 0 1 +67531 4 10 40415 0 0 1 +67537 4 5 46327 16 0 1 +67547 4 2 37219 0 0 1 +67559 4 7 65191 2 0 1 +67567 4 3 36628 6 0 1 +67577 4 3 66797 6 0 1 +67579 4 7 65404 8 0 1 +67589 4 2 58765 0 0 1 +67601 4 3 67233 1 0 1 +67607 4 5 66360 5 0 1 +67619 4 2 44755 2 0 1 +67631 4 7 51169 2 0 1 +67651 4 11 40363 10 0 1 +67679 4 19 66816 9 0 1 +67699 4 2 59915 2 0 1 +67709 4 2 50938 0 0 1 +67723 4 5 38763 0 0 1 +67733 4 2 36882 0 0 1 +67741 4 6 67733 12 0 1 +67751 4 13 39889 5 0 1 +67757 4 3 67753 4 0 1 +67759 4 6 60346 3 0 1 +67763 4 2 50484 10 0 1 +67777 4 5 54147 16 0 1 +67783 4 3 57395 3 0 1 +67789 4 6 62008 2 0 1 +67801 4 11 44970 12 0 1 +67807 4 3 44975 3 0 1 +67819 4 10 46696 0 0 1 +67829 4 2 64028 1 0 1 +67843 4 14 60029 0 0 1 +67853 4 2 41571 6 0 1 +67867 4 2 54474 8 0 1 +67883 4 2 42483 8 0 1 +67891 4 3 47030 2 0 1 +67901 4 3 67897 4 0 1 +67927 4 3 53290 2 0 1 +67931 4 6 67921 7 0 1 +67933 4 2 50804 3 0 1 +67939 4 3 56500 6 0 1 +67943 4 5 41694 3 0 1 +67957 4 2 58354 9 0 1 +67961 4 3 67949 0 0 1 +67967 4 5 67963 3 0 1 +67979 4 2 65282 4 0 1 +67987 4 2 58210 2 0 1 +67993 4 5 67982 14 0 1 +68023 4 3 66480 5 0 1 +68041 4 22 53027 0 0 1 +68053 4 5 50643 3 0 1 +68059 4 2 61367 7 0 1 +68071 4 6 63651 2 0 1 +68087 4 5 61008 12 0 1 +68099 4 2 56605 7 0 1 +68111 4 7 56197 5 0 1 +68113 4 5 58986 19 0 1 +68141 4 3 56253 11 0 1 +68147 4 2 50319 7 0 1 +68161 4 13 61180 35 0 1 +68171 4 2 53531 7 0 1 +68207 4 5 57650 4 0 1 +68209 4 13 66709 24 0 1 +68213 4 2 34705 3 0 1 +68219 4 2 48877 8 0 1 +68227 4 2 67030 7 0 1 +68239 4 3 42806 3 0 1 +68261 4 2 64746 6 0 1 +68279 4 7 54053 7 0 1 +68281 4 7 62806 17 0 1 +68311 4 6 35999 3 0 1 +68329 4 11 44735 12 0 1 +68351 4 17 39570 5 0 1 +68371 4 7 67918 6 0 1 +68389 4 2 43445 3 0 1 +68399 4 7 67493 4 0 1 +68437 4 2 65782 3 0 1 +68443 4 5 68435 6 0 1 +68447 4 5 68443 3 0 1 +68449 4 7 61208 0 0 1 +68473 4 10 59060 14 0 1 +68477 4 2 64640 3 0 1 +68483 4 2 35912 18 0 1 +68489 4 3 44684 2 0 1 +68491 4 10 64941 5 0 1 +68501 4 3 59518 4 0 1 +68507 4 2 46230 4 0 1 +68521 4 7 44205 0 0 1 +68531 4 6 36372 0 0 1 +68539 4 2 48277 3 0 1 +68543 4 5 67315 3 0 1 +68567 4 5 63503 3 0 1 +68581 4 6 39927 2 0 1 +68597 4 2 43600 12 0 1 +68611 4 2 35758 8 0 1 +68633 4 3 61618 1 0 1 +68639 4 7 39801 7 0 1 +68659 4 2 57459 2 0 1 +68669 4 2 48273 3 0 1 +68683 4 2 68676 8 0 1 +68687 4 5 50345 3 0 1 +68699 4 2 44701 0 0 1 +68711 4 11 43127 5 0 1 +68713 4 5 48329 16 0 1 +68729 4 3 68717 0 0 1 +68737 4 5 56637 11 0 1 +68743 4 3 68739 4 0 1 +68749 4 6 52637 0 0 1 +68767 4 3 36909 2 0 1 +68771 4 10 54749 6 0 1 +68777 4 3 48049 0 0 1 +68791 4 3 46092 2 0 1 +68813 4 2 57442 3 0 1 +68819 4 2 65671 8 0 1 +68821 4 14 58139 1 0 1 +68863 4 3 68855 10 0 1 +68879 4 13 60045 16 0 1 +68881 4 22 68855 19 0 1 +68891 4 2 43114 3 0 1 +68897 4 3 47010 9 0 1 +68899 4 2 59615 2 0 1 +68903 4 5 36021 5 0 1 +68909 4 2 65803 7 0 1 +68917 4 5 38485 1 0 1 +68927 4 5 52010 8 0 1 +68947 4 2 60274 35 0 1 +68963 4 2 53458 2 0 1 +68993 4 3 64207 1 0 1 +69001 4 19 67000 32 0 1 +69011 4 6 63999 9 0 1 +69019 4 2 47422 2 0 1 +69029 4 2 52075 2 0 1 +69031 4 3 55096 3 0 1 +69061 4 2 59670 6 0 1 +69067 4 2 69060 8 0 1 +69073 4 10 41305 0 0 1 +69109 4 2 53659 3 0 1 +69119 4 13 35190 4 0 1 +69127 4 5 69123 3 0 1 +69143 4 5 43087 2 0 1 +69149 4 2 56221 2 0 1 +69151 4 11 57951 3 0 1 +69163 4 2 69156 8 0 1 +69191 4 11 53053 5 0 1 +69193 4 10 35071 8 0 1 +69197 4 2 68453 9 0 1 +69203 4 2 68459 15 0 1 +69221 4 2 45363 12 0 1 +69233 4 3 35325 4 0 1 +69239 4 7 50195 3 0 1 +69247 4 3 59921 5 0 1 +69257 4 3 68051 2 0 1 +69259 4 2 39845 8 0 1 +69263 4 5 59152 8 0 1 +69313 4 10 67033 0 0 1 +69317 4 3 51122 4 0 1 +69337 4 5 48687 15 0 1 +69341 4 3 69333 10 0 1 +69371 4 2 38806 8 0 1 +69379 4 2 53834 8 0 1 +69383 4 5 69379 3 0 1 +69389 4 2 45620 4 0 1 +69401 4 6 58645 4 0 1 +69403 4 14 66102 7 0 1 +69427 4 2 49466 8 0 1 +69431 4 13 60664 7 0 1 +69439 4 3 68321 3 0 1 +69457 4 5 66848 6 0 1 +69463 4 6 47263 4 0 1 +69467 4 2 43474 2 0 1 +69473 4 3 44504 0 0 1 +69481 4 7 56254 2 0 1 +69491 4 2 35320 8 0 1 +69493 4 2 61830 6 0 1 +69497 4 3 56279 7 0 1 +69499 4 3 49301 5 0 1 +69539 4 2 36956 7 0 1 +69557 4 2 37857 4 0 1 +69593 4 3 61280 1 0 1 +69623 4 5 35040 6 0 1 +69653 4 2 40852 1 0 1 +69661 4 6 46057 7 0 1 +69677 4 2 67391 4 0 1 +69691 4 2 54995 2 0 1 +69697 4 5 38932 12 0 1 +69709 4 11 59497 11 0 1 +69737 4 3 40589 4 0 1 +69739 4 2 41714 2 0 1 +69761 4 3 54923 4 0 1 +69763 4 2 43287 10 0 1 +69767 4 5 60380 5 0 1 +69779 4 2 62123 7 0 1 +69809 4 3 50037 0 0 1 +69821 4 7 45311 9 0 1 +69827 4 2 66053 24 0 1 +69829 4 10 41766 14 0 1 +69833 4 5 62115 10 0 1 +69847 4 10 57258 3 0 1 +69857 4 3 43449 4 0 1 +69859 4 10 54267 1 0 1 +69877 4 2 40066 6 0 1 +69899 4 2 65475 4 0 1 +69911 4 7 69902 4 0 1 +69929 4 3 51163 2 0 1 +69931 4 3 69231 2 0 1 +69941 4 2 43594 6 0 1 +69959 4 7 54329 5 0 1 +69991 4 3 68518 3 0 1 +69997 4 2 67197 2 0 1 +70001 4 3 63569 4 0 1 +70003 4 2 42929 10 0 1 +70009 4 19 60077 32 0 1 +70019 4 6 38012 5 0 1 +70039 4 3 51654 2 0 1 +70051 4 7 37283 6 0 1 +70061 4 2 68098 3 0 1 +70067 4 2 69150 0 0 1 +70079 4 7 40728 3 0 1 +70099 4 3 45248 2 0 1 +70111 4 6 57088 3 0 1 +70117 4 2 47614 6 0 1 +70121 4 6 36468 7 0 1 +70123 4 2 50832 14 0 1 +70139 4 2 42365 1 0 1 +70141 4 10 69186 12 0 1 +70157 4 2 42002 5 0 1 +70163 4 2 43249 1 0 1 +70177 4 5 51571 6 0 1 +70181 4 7 65289 0 0 1 +70183 4 3 70179 4 0 1 +70199 4 17 53238 8 0 1 +70201 4 14 54788 8 0 1 +70207 4 5 42032 5 0 1 +70223 4 5 37478 3 0 1 +70229 4 2 47017 4 0 1 +70237 4 2 56553 3 0 1 +70241 4 6 53215 4 0 1 +70249 4 23 41688 34 0 1 +70271 4 11 68323 5 0 1 +70289 4 3 64290 4 0 1 +70297 4 5 47250 10 0 1 +70309 4 6 53424 11 0 1 +70313 4 3 56400 11 0 1 +70321 4 7 36964 17 0 1 +70327 4 11 68433 14 0 1 +70351 4 6 63404 2 0 1 +70373 4 2 51044 6 0 1 +70379 4 6 57535 0 0 1 +70381 4 10 56129 1 0 1 +70393 4 5 48327 10 0 1 +70423 4 5 70419 3 0 1 +70429 4 10 59245 2 0 1 +70439 4 13 36995 6 0 1 +70451 4 6 57297 5 0 1 +70457 4 3 60784 4 0 1 +70459 4 3 51996 2 0 1 +70481 4 3 48650 2 0 1 +70487 4 5 44704 14 0 1 +70489 4 17 45627 20 0 1 +70501 4 2 64881 10 0 1 +70507 4 2 44678 2 0 1 +70529 4 3 56755 7 0 1 +70537 4 5 62941 15 0 1 +70549 4 2 56638 3 0 1 +70571 4 2 54714 7 0 1 +70573 4 2 70566 8 0 1 +70583 4 5 70579 3 0 1 +70589 4 2 49075 4 0 1 +70607 4 5 58381 4 0 1 +70619 4 2 61619 2 0 1 +70621 4 6 41805 7 0 1 +70627 4 7 53445 13 0 1 +70639 4 3 61082 3 0 1 +70657 4 7 36137 8 0 1 +70663 4 3 54656 2 0 1 +70667 4 2 59153 3 0 1 +70687 4 5 70671 18 0 1 +70709 4 2 57901 6 0 1 +70717 4 2 39997 6 0 1 +70729 4 22 48128 0 0 1 +70753 4 5 63030 15 0 1 +70769 4 3 53835 4 0 1 +70783 4 3 36793 7 0 1 +70793 4 3 53597 6 0 1 +70823 4 5 63787 2 0 1 +70841 4 3 48633 1 0 1 +70843 4 2 69291 7 0 1 +70849 4 17 38090 35 0 1 +70853 4 2 66950 3 0 1 +70867 4 3 68822 3 0 1 +70877 4 2 54683 2 0 1 +70879 4 3 43553 2 0 1 +70891 4 3 65467 2 0 1 +70901 4 2 67460 3 0 1 +70913 4 3 42051 4 0 1 +70919 4 7 39710 6 0 1 +70921 4 13 54135 14 0 1 +70937 4 3 56041 11 0 1 +70949 4 2 62905 0 0 1 +70951 4 6 57780 3 0 1 +70957 4 2 51988 3 0 1 +70969 4 11 61783 16 0 1 +70979 4 2 57757 2 0 1 +70981 4 6 66178 2 0 1 +70991 4 7 61011 2 0 1 +70997 4 2 38359 9 0 1 +70999 4 11 66744 9 0 1 +71011 4 15 49875 6 0 1 +71023 4 6 58735 3 0 1 +71039 4 11 68825 6 0 1 +71059 4 7 41189 6 0 1 +71069 4 2 43626 9 0 1 +71081 4 3 69416 7 0 1 +71089 4 11 39634 22 0 1 +71119 4 3 67357 8 0 1 +71129 4 3 43019 2 0 1 +71143 4 6 70219 7 0 1 +71147 4 2 46222 4 0 1 +71153 4 3 42472 9 0 1 +71161 4 11 66960 12 0 1 +71167 4 3 59112 2 0 1 +71171 4 2 51451 4 0 1 +71191 4 3 47696 2 0 1 +71209 4 7 45847 0 0 1 +71233 4 11 55561 7 0 1 +71237 4 2 65919 6 0 1 +71249 4 3 70494 4 0 1 +71257 4 5 71246 14 0 1 +71261 4 3 66274 12 0 1 +71263 4 5 54562 2 0 1 +71287 4 3 41172 2 0 1 +71293 4 5 67279 1 0 1 +71317 4 2 52171 12 0 1 +71327 4 5 71323 3 0 1 +71329 4 7 42666 0 0 1 +71333 4 2 49522 11 0 1 +71339 4 2 42483 13 0 1 +71341 4 6 71337 6 0 1 +71347 4 2 55724 7 0 1 +71353 4 5 41313 12 0 1 +71359 4 6 44808 4 0 1 +71363 4 2 52079 10 0 1 +71387 4 2 44921 15 0 1 +71389 4 11 46466 8 0 1 +71399 4 11 35931 2 0 1 +71411 4 2 40070 7 0 1 +71413 4 2 71406 8 0 1 +71419 4 2 68999 7 0 1 +71429 4 2 50209 6 0 1 +71437 4 2 54737 10 0 1 +71443 4 11 36676 5 0 1 +71453 4 2 37951 3 0 1 +71471 4 7 41094 4 0 1 +71473 4 5 45163 6 0 1 +71479 4 6 56282 10 0 1 +71483 4 2 47456 4 0 1 +71503 4 3 68586 6 0 1 +71527 4 3 39248 6 0 1 +71537 4 3 36582 0 0 1 +71549 4 2 70584 4 0 1 +71551 4 6 64114 3 0 1 +71563 4 2 58689 8 0 1 +71569 4 19 60317 32 0 1 +71593 4 5 36565 15 0 1 +71597 4 2 70889 0 0 1 +71633 4 3 38013 4 0 1 +71647 4 3 59824 6 0 1 +71663 4 5 51461 2 0 1 +71671 4 15 43839 3 0 1 +71693 4 2 55090 1 0 1 +71699 4 2 67291 6 0 1 +71707 4 2 63239 1 0 1 +71711 4 17 38247 7 0 1 +71713 4 5 47165 12 0 1 +71719 4 3 63829 3 0 1 +71741 4 2 65142 3 0 1 +71761 4 44 51693 13 0 1 +71777 4 3 58795 9 0 1 +71789 4 2 48870 0 0 1 +71807 4 5 71795 11 0 1 +71809 4 7 68346 17 0 1 +71821 4 2 47183 10 0 1 +71837 4 2 41955 3 0 1 +71843 4 2 37674 8 0 1 +71849 4 3 43545 7 0 1 +71861 4 7 57037 5 0 1 +71867 4 2 55662 2 0 1 +71879 4 11 58652 2 0 1 +71881 4 7 51859 0 0 1 +71887 4 3 55991 2 0 1 +71899 4 2 65761 8 0 1 +71909 4 2 71061 3 0 1 +71917 4 2 41181 6 0 1 +71933 4 2 62443 6 0 1 +71941 4 2 48283 6 0 1 +71947 4 2 67395 8 0 1 +71963 4 2 71956 8 0 1 +71971 4 2 40745 8 0 1 +71983 4 3 64115 5 0 1 +71987 4 2 47287 26 0 1 +71993 4 3 53608 1 0 1 +71999 4 7 57398 7 0 1 +72019 4 2 62742 1 0 1 +72031 4 3 55350 3 0 1 +72043 4 5 41388 8 0 1 +72047 4 5 62811 5 0 1 +72053 4 2 59135 7 0 1 +72073 4 5 48859 10 0 1 +72077 4 2 42757 4 0 1 +72089 4 3 72077 0 0 1 +72091 4 2 60530 2 0 1 +72101 4 2 63163 12 0 1 +72103 4 6 57940 2 0 1 +72109 4 2 46459 6 0 1 +72139 4 2 45029 8 0 1 +72161 4 6 44064 4 0 1 +72167 4 5 72163 3 0 1 +72169 4 7 37026 0 0 1 +72173 4 2 47862 1 0 1 +72211 4 2 62661 2 0 1 +72221 4 2 42079 6 0 1 +72223 4 3 63494 17 0 1 +72227 4 2 60882 2 0 1 +72229 4 2 71628 9 0 1 +72251 4 7 72242 4 0 1 +72253 4 2 36427 6 0 1 +72269 4 3 58151 3 0 1 +72271 4 3 65518 3 0 1 +72277 4 5 66880 1 0 1 +72287 4 5 72283 3 0 1 +72307 4 3 64560 0 0 1 +72313 4 5 62407 6 0 1 +72337 4 7 39917 17 0 1 +72341 4 2 58293 9 0 1 +72353 4 3 55199 0 0 1 +72367 4 3 62623 6 0 1 +72379 4 2 51422 12 0 1 +72383 4 5 71622 4 0 1 +72421 4 6 66249 7 0 1 +72431 4 13 58708 6 0 1 +72461 4 2 43369 6 0 1 +72467 4 2 61622 13 0 1 +72469 4 6 60664 7 0 1 +72481 4 11 36542 8 0 1 +72493 4 2 69682 6 0 1 +72497 4 5 36734 6 0 1 +72503 4 5 54638 2 0 1 +72533 4 2 64635 1 0 1 +72547 4 2 72540 8 0 1 +72551 4 13 41107 9 0 1 +72559 4 3 46343 14 0 1 +72577 4 5 72566 14 0 1 +72613 4 2 57646 6 0 1 +72617 4 3 69042 4 0 1 +72623 4 5 59960 8 0 1 +72643 4 2 49227 17 0 1 +72647 4 5 72643 3 0 1 +72649 4 7 47012 17 0 1 +72661 4 11 62100 3 0 1 +72671 4 7 61218 3 0 1 +72673 4 5 72662 14 0 1 +72679 4 6 41235 3 0 1 +72689 4 3 69268 2 0 1 +72701 4 2 72694 8 0 1 +72707 4 2 55870 7 0 1 +72719 4 11 63204 5 0 1 +72727 4 7 64380 0 0 1 +72733 4 2 62105 6 0 1 +72739 4 2 52065 15 0 1 +72763 4 2 50862 16 0 1 +72767 4 5 44380 4 0 1 +72797 4 2 68786 6 0 1 +72817 4 5 40745 25 0 1 +72823 4 5 39509 5 0 1 +72859 4 2 42403 2 0 1 +72869 4 2 72862 8 0 1 +72871 4 6 49897 2 0 1 +72883 4 3 40725 8 0 1 +72889 4 7 59320 0 0 1 +72893 4 2 52422 6 0 1 +72901 4 2 65487 7 0 1 +72907 4 2 42627 8 0 1 +72911 4 11 39056 6 0 1 +72923 4 2 55043 8 0 1 +72931 4 10 60579 9 0 1 +72937 4 5 39982 6 0 1 +72949 4 2 52415 12 0 1 +72953 4 3 65046 9 0 1 +72959 4 17 72933 17 0 1 +72973 4 2 45763 7 0 1 +72977 4 3 45322 0 0 1 +72997 4 2 60557 9 0 1 +73009 4 7 61290 1 0 1 +73013 4 2 38041 4 0 1 +73019 4 2 47919 3 0 1 +73037 4 2 44880 3 0 1 +73039 4 3 59389 2 0 1 +73043 4 2 66445 7 0 1 +73061 4 2 58871 6 0 1 +73063 4 3 48207 3 0 1 +73079 4 13 40351 4 0 1 +73091 4 2 43963 4 0 1 +73121 4 3 42292 2 0 1 +73127 4 5 73123 3 0 1 +73133 4 2 72158 17 0 1 +73141 4 7 43993 4 0 1 +73181 4 2 47002 7 0 1 +73189 4 2 55841 12 0 1 +73237 4 6 65241 6 0 1 +73243 4 3 71712 2 0 1 +73259 4 2 61316 7 0 1 +73277 4 3 73273 4 0 1 +73291 4 3 69472 11 0 1 +73303 4 5 62926 5 0 1 +73309 4 2 66589 9 0 1 +73327 4 3 73323 4 0 1 +73331 4 2 42910 4 0 1 +73351 4 3 65865 6 0 1 +73361 4 11 51499 4 0 1 +73363 4 5 73359 3 0 1 +73369 4 11 70828 16 0 1 +73379 4 2 72262 1 0 1 +73387 4 2 73380 8 0 1 +73417 4 10 53155 21 0 1 +73421 4 2 37199 3 0 1 +73433 4 3 48227 1 0 1 +73453 4 2 72911 10 0 1 +73459 4 2 49334 8 0 1 +73471 4 3 73467 4 0 1 +73477 4 6 68628 8 0 1 +73483 4 2 70827 8 0 1 +73517 4 2 53158 6 0 1 +73523 4 2 46328 0 0 1 +73529 4 3 42582 0 0 1 +73547 4 2 66601 13 0 1 +73553 4 3 64744 7 0 1 +73561 4 13 42718 16 0 1 +73571 4 2 68944 8 0 1 +73583 4 5 63211 3 0 1 +73589 4 2 41254 14 0 1 +73597 4 2 51616 9 0 1 +73607 4 5 66527 6 0 1 +73609 4 19 72074 14 0 1 +73613 4 2 37537 12 0 1 +73637 4 2 56357 4 0 1 +73643 4 2 51879 14 0 1 +73651 4 2 67415 8 0 1 +73673 4 3 57691 4 0 1 +73679 4 14 64280 6 0 1 +73681 4 14 57935 0 0 1 +73693 4 2 58210 9 0 1 +73699 4 2 67161 1 0 1 +73709 4 2 39653 4 0 1 +73721 4 6 53276 0 0 1 +73727 4 5 73715 11 0 1 +73751 4 13 42278 3 0 1 +73757 4 2 53235 3 0 1 +73771 4 2 43300 6 0 1 +73783 4 3 72176 5 0 1 +73819 4 3 46285 3 0 1 +73823 4 5 38688 2 0 1 +73847 4 5 73843 3 0 1 +73849 4 7 54332 0 0 1 +73859 4 2 68126 3 0 1 +73867 4 2 51175 2 0 1 +73877 4 2 51052 4 0 1 +73883 4 2 72698 0 0 1 +73897 4 5 62054 16 0 1 +73907 4 2 38461 9 0 1 +73939 4 2 73468 1 0 1 +73943 4 5 67134 3 0 1 +73951 4 3 65283 3 0 1 +73961 4 3 73949 0 0 1 +73973 4 2 69985 8 0 1 +73999 4 6 37849 10 0 1 +74017 4 7 60515 10 0 1 +74021 4 2 66942 1 0 1 +74027 4 2 60175 14 0 1 +74047 4 3 66570 5 0 1 +74051 4 6 59760 2 0 1 +74071 4 14 65525 3 0 1 +74077 4 5 69539 3 0 1 +74093 4 2 48470 9 0 1 +74099 4 2 56842 0 0 1 +74101 4 2 74094 8 0 1 +74131 4 2 73228 8 0 1 +74143 4 5 74139 3 0 1 +74149 4 2 60624 7 0 1 +74159 4 13 74147 5 0 1 +74161 4 7 61232 0 0 1 +74167 4 5 46898 2 0 1 +74177 4 3 73054 1 0 1 +74189 4 2 74182 8 0 1 +74197 4 5 61162 6 0 1 +74201 4 6 46682 0 0 1 +74203 4 2 59268 2 0 1 +74209 4 19 72874 0 0 1 +74219 4 2 45079 4 0 1 +74231 4 11 64699 9 0 1 +74257 4 5 62236 32 0 1 +74279 4 7 74270 4 0 1 +74287 4 3 74283 4 0 1 +74293 4 5 45178 6 0 1 +74297 4 3 43437 5 0 1 +74311 4 12 69621 3 0 1 +74317 4 2 42707 6 0 1 +74323 4 5 65969 2 0 1 +74353 4 5 44387 10 0 1 +74357 4 2 64986 1 0 1 +74363 4 2 53504 8 0 1 +74377 4 5 58041 23 0 1 +74381 4 2 60053 1 0 1 +74383 4 5 74367 18 0 1 +74411 4 2 63354 7 0 1 +74413 4 5 52255 7 0 1 +74419 4 2 52003 8 0 1 +74441 4 3 74429 0 0 1 +74449 4 13 43654 14 0 1 +74453 4 2 67106 6 0 1 +74471 4 11 38724 5 0 1 +74489 4 3 70962 7 0 1 +74507 4 2 45482 7 0 1 +74509 4 2 66467 10 0 1 +74521 4 13 71684 10 0 1 +74527 4 3 56896 5 0 1 +74531 4 2 45219 7 0 1 +74551 4 11 67291 2 0 1 +74561 4 3 74549 0 0 1 +74567 4 5 74563 3 0 1 +74573 4 2 55217 6 0 1 +74587 4 2 74114 8 0 1 +74597 4 2 50072 3 0 1 +74609 4 3 48007 2 0 1 +74611 4 2 41939 2 0 1 +74623 4 3 39560 5 0 1 +74653 4 2 37632 3 0 1 +74687 4 5 48383 5 0 1 +74699 4 2 61778 7 0 1 +74707 4 2 72057 7 0 1 +74713 4 10 47033 16 0 1 +74717 4 2 67732 1 0 1 +74719 4 7 52460 0 0 1 +74729 4 3 65169 4 0 1 +74731 4 2 46647 5 0 1 +74747 4 2 52370 7 0 1 +74759 4 11 68112 3 0 1 +74761 4 19 57690 18 0 1 +74771 4 2 53812 4 0 1 +74779 4 2 65169 6 0 1 +74797 4 5 67484 7 0 1 +74821 4 6 74817 6 0 1 +74827 4 3 53210 5 0 1 +74831 4 7 46151 4 0 1 +74843 4 2 65225 7 0 1 +74857 4 5 42453 10 0 1 +74861 4 2 59239 1 0 1 +74869 4 2 43349 37 0 1 +74873 4 3 52027 4 0 1 +74887 4 3 62207 2 0 1 +74891 4 2 45677 9 0 1 +74897 4 3 44783 1 0 1 +74903 4 5 74899 3 0 1 +74923 4 5 74919 3 0 1 +74929 4 17 74910 26 0 1 +74933 4 2 56989 6 0 1 +74941 4 6 38035 8 0 1 +74959 4 3 74955 4 0 1 +75011 4 6 75001 7 0 1 +75013 4 2 68366 10 0 1 +75017 4 3 45462 8 0 1 +75029 4 2 43015 4 0 1 +75037 4 2 55138 10 0 1 +75041 4 3 60728 2 0 1 +75079 4 3 49811 3 0 1 +75083 4 2 38728 7 0 1 +75109 4 2 70881 7 0 1 +75133 4 2 63032 6 0 1 +75149 4 2 57023 0 0 1 +75161 4 3 57173 2 0 1 +75167 4 5 73433 5 0 1 +75169 4 7 59133 0 0 1 +75181 4 2 61827 6 0 1 +75193 4 7 45746 10 0 1 +75209 4 3 75197 0 0 1 +75211 4 2 53922 6 0 1 +75217 4 5 65957 23 0 1 +75223 4 3 64366 3 0 1 +75227 4 2 38702 2 0 1 +75239 4 13 74289 16 0 1 +75253 4 2 43719 3 0 1 +75269 4 2 61218 3 0 1 +75277 4 2 53931 6 0 1 +75289 4 13 63503 40 0 1 +75307 4 3 66690 6 0 1 +75323 4 2 39729 7 0 1 +75329 4 3 75317 0 0 1 +75337 4 5 59122 6 0 1 +75347 4 2 55916 11 0 1 +75353 4 3 49497 9 0 1 +75367 4 3 54296 5 0 1 +75377 4 3 47702 9 0 1 +75389 4 2 50980 3 0 1 +75391 4 3 62947 3 0 1 +75401 4 3 64247 7 0 1 +75403 4 3 47857 2 0 1 +75407 4 5 75403 3 0 1 +75431 4 19 64329 3 0 1 +75437 4 2 52905 3 0 1 +75479 4 19 54717 2 0 1 +75503 4 5 75499 3 0 1 +75511 4 3 63924 2 0 1 +75521 4 3 58652 4 0 1 +75527 4 5 39797 2 0 1 +75533 4 2 55610 3 0 1 +75539 4 2 71048 0 0 1 +75541 4 2 61862 6 0 1 +75553 4 5 49539 10 0 1 +75557 4 2 41269 1 0 1 +75571 4 2 41127 2 0 1 +75577 4 17 75551 17 0 1 +75583 4 5 57532 20 0 1 +75611 4 2 56351 3 0 1 +75617 4 3 49824 2 0 1 +75619 4 2 38524 5 0 1 +75629 4 2 74529 12 0 1 +75641 4 3 75252 2 0 1 +75653 4 2 63291 6 0 1 +75659 4 2 66607 2 0 1 +75679 4 6 61237 4 0 1 +75683 4 2 44590 2 0 1 +75689 4 3 75677 0 0 1 +75703 4 5 49498 9 0 1 +75707 4 2 44851 6 0 1 +75709 4 2 62812 12 0 1 +75721 4 11 68593 20 0 1 +75731 4 2 47760 19 0 1 +75743 4 5 62967 4 0 1 +75767 4 5 48472 7 0 1 +75773 4 2 42560 6 0 1 +75781 4 6 74581 8 0 1 +75787 4 5 73821 2 0 1 +75793 4 10 53297 8 0 1 +75797 4 2 39226 7 0 1 +75821 4 2 46250 0 0 1 +75833 4 3 38658 4 0 1 +75853 4 5 48073 1 0 1 +75869 4 2 57594 0 0 1 +75883 4 2 39825 7 0 1 +75913 4 5 49747 12 0 1 +75931 4 3 46134 3 0 1 +75937 4 10 42999 0 0 1 +75941 4 2 58727 3 0 1 +75967 4 3 75963 4 0 1 +75979 4 2 49107 8 0 1 +75983 4 5 66619 7 0 1 +75989 4 2 72681 0 0 1 +75991 4 11 61459 4 0 1 +75997 4 2 67184 6 0 1 +76001 4 3 53826 2 0 1 +76003 4 5 45793 5 0 1 +76031 4 7 61858 2 0 1 +76039 4 12 48240 3 0 1 +76079 4 11 67672 7 0 1 +76081 4 7 46107 0 0 1 +76091 4 2 48161 8 0 1 +76099 4 7 66436 6 0 1 +76103 4 5 71301 6 0 1 +76123 4 3 67204 3 0 1 +76129 4 17 76086 48 0 1 +76147 4 2 43774 8 0 1 +76157 4 2 75162 6 0 1 +76159 4 3 68242 6 0 1 +76163 4 2 64513 3 0 1 +76207 4 3 73692 5 0 1 +76213 4 5 65965 7 0 1 +76231 4 6 56446 4 0 1 +76243 4 3 42989 5 0 1 +76249 4 7 56790 0 0 1 +76253 4 2 59618 4 0 1 +76259 4 2 58288 7 0 1 +76261 4 2 76254 8 0 1 +76283 4 2 57665 7 0 1 +76289 4 3 54581 4 0 1 +76303 4 3 75307 8 0 1 +76333 4 5 62666 3 0 1 +76343 4 5 58212 0 0 1 +76367 4 5 68296 7 0 1 +76369 4 11 76355 11 0 1 +76379 4 2 40673 0 0 1 +76387 4 3 67788 2 0 1 +76403 4 2 67684 7 0 1 +76421 4 3 74011 6 0 1 +76423 4 5 76407 18 0 1 +76441 4 11 48662 23 0 1 +76463 4 5 54082 5 0 1 +76471 4 6 47297 3 0 1 +76481 4 3 39574 2 0 1 +76487 4 5 53589 2 0 1 +76493 4 2 42860 2 0 1 +76507 4 2 69273 8 0 1 +76511 4 7 54082 11 0 1 +76519 4 3 59686 6 0 1 +76537 4 5 42941 10 0 1 +76541 4 2 76534 8 0 1 +76543 4 3 40615 6 0 1 +76561 4 17 46886 20 0 1 +76579 4 14 50427 2 0 1 +76597 4 7 43441 10 0 1 +76603 4 2 58855 8 0 1 +76607 4 5 73867 7 0 1 +76631 4 7 70497 6 0 1 +76649 4 6 56278 0 0 1 +76651 4 3 52165 5 0 1 +76667 4 2 62005 7 0 1 +76673 4 3 66368 9 0 1 +76679 4 7 55592 4 0 1 +76697 4 3 50870 1 0 1 +76717 4 2 45082 9 0 1 +76733 4 2 56050 3 0 1 +76753 4 5 39385 6 0 1 +76757 4 2 49527 3 0 1 +76771 4 2 71492 8 0 1 +76777 4 5 76766 14 0 1 +76781 4 2 67454 9 0 1 +76801 4 17 48804 20 0 1 +76819 4 7 66753 8 0 1 +76829 4 2 61574 6 0 1 +76831 4 29 58581 2 0 1 +76837 4 5 60173 1 0 1 +76847 4 5 50138 9 0 1 +76871 4 7 58549 2 0 1 +76873 4 10 60065 22 0 1 +76883 4 2 41684 4 0 1 +76907 4 2 55765 7 0 1 +76913 4 3 52470 0 0 1 +76919 4 13 48489 3 0 1 +76943 4 10 69382 4 0 1 +76949 4 2 72266 1 0 1 +76961 4 3 76949 0 0 1 +76963 4 3 67494 7 0 1 +76991 4 13 55398 4 0 1 +77003 4 2 55719 2 0 1 +77017 4 7 64348 10 0 1 +77023 4 3 75692 6 0 1 +77029 4 2 58146 0 0 1 +77041 4 7 60137 0 0 1 +77047 4 3 61257 3 0 1 +77069 4 2 75574 1 0 1 +77081 4 3 77069 0 0 1 +77093 4 2 72956 4 0 1 +77101 4 7 40000 4 0 1 +77137 4 13 71265 4 0 1 +77141 4 3 77137 4 0 1 +77153 4 3 46439 0 0 1 +77167 4 21 39536 12 0 1 +77171 4 2 55211 4 0 1 +77191 4 6 70075 10 0 1 +77201 4 3 60243 2 0 1 +77213 4 2 41850 4 0 1 +77237 4 2 56993 3 0 1 +77239 4 3 61017 2 0 1 +77243 4 2 52825 2 0 1 +77249 4 3 52093 4 0 1 +77261 4 2 59385 19 0 1 +77263 4 5 77251 11 0 1 +77267 4 2 60416 7 0 1 +77269 4 2 73786 9 0 1 +77279 4 11 56247 5 0 1 +77291 4 2 65473 0 0 1 +77317 4 2 67074 19 0 1 +77323 4 2 59021 8 0 1 +77339 4 2 51352 4 0 1 +77347 4 3 63248 2 0 1 +77351 4 14 39544 7 0 1 +77359 4 3 55517 2 0 1 +77369 4 3 42002 7 0 1 +77377 4 5 74267 10 0 1 +77383 4 3 66656 3 0 1 +77417 4 3 57001 9 0 1 +77419 4 2 48070 2 0 1 +77431 4 3 43837 2 0 1 +77447 4 5 65461 4 0 1 +77471 4 7 44438 3 0 1 +77477 4 2 69614 4 0 1 +77479 4 6 64095 5 0 1 +77489 4 3 68695 3 0 1 +77491 4 3 47151 2 0 1 +77509 4 2 46053 7 0 1 +77513 4 3 70285 1 0 1 +77521 4 7 61075 0 0 1 +77527 4 5 39718 10 0 1 +77543 4 5 77539 3 0 1 +77549 4 2 58006 1 0 1 +77551 4 6 52072 3 0 1 +77557 4 5 42053 6 0 1 +77563 4 2 56342 10 0 1 +77569 4 13 77530 0 0 1 +77573 4 2 52860 1 0 1 +77587 4 2 50630 2 0 1 +77591 4 13 39037 6 0 1 +77611 4 2 73968 8 0 1 +77617 4 10 58808 6 0 1 +77621 4 2 77614 8 0 1 +77641 4 13 76166 42 0 1 +77647 4 3 60310 6 0 1 +77659 4 2 73063 8 0 1 +77681 4 3 77669 0 0 1 +77687 4 5 53507 3 0 1 +77689 4 14 62425 8 0 1 +77699 4 2 52513 9 0 1 +77711 4 14 66066 7 0 1 +77713 4 7 43614 12 0 1 +77719 4 6 76382 8 0 1 +77723 4 2 58596 8 0 1 +77731 4 2 53946 2 0 1 +77743 4 3 44481 2 0 1 +77747 4 2 77740 8 0 1 +77761 4 11 39193 16 0 1 +77773 4 2 65208 6 0 1 +77783 4 5 75933 5 0 1 +77797 4 5 43634 10 0 1 +77801 4 7 77783 13 0 1 +77813 4 2 46881 7 0 1 +77839 4 3 39991 6 0 1 +77849 4 3 53594 13 0 1 +77863 4 5 77859 3 0 1 +77867 4 2 41264 2 0 1 +77893 4 2 40695 10 0 1 +77899 4 14 75848 2 0 1 +77929 4 14 47811 9 0 1 +77933 4 2 67619 2 0 1 +77951 4 11 55967 6 0 1 +77969 4 3 70513 2 0 1 +77977 4 5 42830 10 0 1 +77983 4 3 54514 6 0 1 +77999 4 11 59423 7 0 1 +78007 4 3 77217 5 0 1 +78017 4 3 54087 1 0 1 +78031 4 7 61180 0 0 1 +78041 4 3 69721 4 0 1 +78049 4 7 46692 0 0 1 +78059 4 2 44202 3 0 1 +78079 4 12 40845 5 0 1 +78101 4 2 72401 6 0 1 +78121 4 11 66847 16 0 1 +78137 4 3 73578 2 0 1 +78139 4 3 77255 7 0 1 +78157 4 6 47619 8 0 1 +78163 4 3 76509 2 0 1 +78167 4 5 44736 6 0 1 +78173 4 2 57237 0 0 1 +78179 4 2 54881 2 0 1 +78191 4 11 59080 6 0 1 +78193 4 5 46298 6 0 1 +78203 4 2 77518 2 0 1 +78229 4 2 46801 15 0 1 +78233 4 3 72963 2 0 1 +78241 4 19 75215 40 0 1 +78259 4 2 57170 1 0 1 +78277 4 6 78267 7 0 1 +78283 4 3 47118 5 0 1 +78301 4 6 49151 10 0 1 +78307 4 2 64618 11 0 1 +78311 4 14 46637 2 0 1 +78317 4 2 45633 7 0 1 +78341 4 2 57293 8 0 1 +78347 4 2 65609 2 0 1 +78367 4 5 78355 11 0 1 +78401 4 13 77775 0 0 1 +78427 4 3 49267 7 0 1 +78437 4 2 46740 7 0 1 +78439 4 6 39762 10 0 1 +78467 4 2 65667 3 0 1 +78479 4 7 68429 2 0 1 +78487 4 3 74525 5 0 1 +78497 4 3 53802 13 0 1 +78509 4 3 78505 4 0 1 +78511 4 3 41910 3 0 1 +78517 4 2 78510 8 0 1 +78539 4 2 78532 8 0 1 +78541 4 2 64106 10 0 1 +78553 4 5 78542 14 0 1 +78569 4 3 52115 4 0 1 +78571 4 2 74274 1 0 1 +78577 4 5 67410 11 0 1 +78583 4 3 40331 5 0 1 +78593 4 3 64531 12 0 1 +78607 4 3 68027 6 0 1 +78623 4 5 72708 7 0 1 +78643 4 11 65412 2 0 1 +78649 4 11 61309 12 0 1 +78653 4 3 45000 11 0 1 +78691 4 7 63442 6 0 1 +78697 4 5 71814 6 0 1 +78707 4 2 40959 7 0 1 +78713 4 3 50674 8 0 1 +78721 4 7 45214 0 0 1 +78737 4 3 60761 9 0 1 +78779 4 2 60950 7 0 1 +78781 4 10 44740 2 0 1 +78787 4 2 75674 8 0 1 +78791 4 11 40272 3 0 1 +78797 4 2 67871 4 0 1 +78803 4 2 70667 7 0 1 +78809 4 3 64605 0 0 1 +78823 4 3 56477 2 0 1 +78839 4 13 43368 7 0 1 +78853 4 5 50889 6 0 1 +78857 4 3 76077 3 0 1 +78877 4 2 76365 6 0 1 +78887 4 5 57880 10 0 1 +78889 4 11 60182 10 0 1 +78893 4 2 59423 6 0 1 +78901 4 10 60797 5 0 1 +78919 4 3 74576 3 0 1 +78929 4 3 74478 1 0 1 +78941 4 2 72076 0 0 1 +78977 4 3 74142 4 0 1 +78979 4 3 60274 6 0 1 +78989 4 2 65252 0 0 1 +79031 4 7 52820 5 0 1 +79039 4 6 46887 2 0 1 +79043 4 2 75219 4 0 1 +79063 4 5 79059 3 0 1 +79087 4 3 47249 16 0 1 +79103 4 5 53185 5 0 1 +79111 4 6 58142 2 0 1 +79133 4 2 41941 1 0 1 +79139 4 2 75121 8 0 1 +79147 4 2 79140 8 0 1 +79151 4 13 67901 2 0 1 +79153 4 10 67468 25 0 1 +79159 4 3 79155 4 0 1 +79181 4 2 69094 6 0 1 +79187 4 5 57992 1 0 1 +79193 4 3 72932 15 0 1 +79201 4 13 57322 16 0 1 +79229 4 2 57924 3 0 1 +79231 4 3 79227 4 0 1 +79241 4 3 77951 2 0 1 +79259 4 2 44765 13 0 1 +79273 4 5 79262 14 0 1 +79279 4 3 52356 6 0 1 +79283 4 2 60361 4 0 1 +79301 4 2 54740 3 0 1 +79309 4 2 46121 10 0 1 +79319 4 7 44979 2 0 1 +79333 4 5 61604 6 0 1 +79337 4 3 60327 0 0 1 +79349 4 2 60161 6 0 1 +79357 4 7 65224 7 0 1 +79367 4 5 79355 11 0 1 +79379 4 2 78891 2 0 1 +79393 4 5 76492 16 0 1 +79397 4 2 72098 3 0 1 +79399 4 3 67608 6 0 1 +79411 4 2 79404 8 0 1 +79423 4 3 49546 6 0 1 +79427 4 2 76844 4 0 1 +79433 4 3 58499 46 0 1 +79451 4 6 44750 6 0 1 +79481 4 6 46790 0 0 1 +79493 4 5 56334 3 0 1 +79531 4 2 44457 8 0 1 +79537 4 7 76539 20 0 1 +79549 4 2 74949 7 0 1 +79559 4 7 68022 7 0 1 +79561 4 7 77151 0 0 1 +79579 4 10 60920 5 0 1 +79589 4 2 52849 1 0 1 +79601 4 3 40116 2 0 1 +79609 4 14 72499 8 0 1 +79613 4 2 63052 12 0 1 +79621 4 2 78990 9 0 1 +79627 4 3 78996 3 0 1 +79631 4 13 79619 5 0 1 +79633 4 13 44968 6 0 1 +79657 4 5 44055 23 0 1 +79669 4 10 44344 3 0 1 +79687 4 3 48111 6 0 1 +79691 4 10 49652 1 0 1 +79693 4 5 42715 7 0 1 +79697 4 3 47978 4 0 1 +79699 4 2 58007 8 0 1 +79757 4 2 51791 3 0 1 +79769 4 3 79757 0 0 1 +79777 4 5 75249 6 0 1 +79801 4 23 45329 24 0 1 +79811 4 2 77043 8 0 1 +79813 4 2 41146 9 0 1 +79817 4 3 77684 1 0 1 +79823 4 5 58590 8 0 1 +79829 4 2 48036 2 0 1 +79841 4 3 59475 8 0 1 +79843 4 2 41769 8 0 1 +79847 4 5 73592 6 0 1 +79861 4 2 40440 7 0 1 +79867 4 2 48936 8 0 1 +79873 4 7 59499 12 0 1 +79889 4 3 59347 7 0 1 +79901 4 2 50778 3 0 1 +79903 4 3 46371 3 0 1 +79907 4 2 70669 8 0 1 +79939 4 3 42155 6 0 1 +79943 4 5 46832 2 0 1 +79967 4 5 41208 2 0 1 +79973 4 2 65729 6 0 1 +79979 4 2 67881 3 0 1 +79987 4 2 54593 7 0 1 +79997 4 2 55896 6 0 1 +79999 4 3 64502 2 0 1 +80021 4 2 63575 12 0 1 +80039 4 11 51580 3 0 1 +80051 4 2 72344 2 0 1 +80071 4 3 50443 2 0 1 +80077 4 2 49161 6 0 1 +80107 4 2 40428 10 0 1 +80111 4 11 45203 2 0 1 +80141 4 2 79392 3 0 1 +80147 4 2 40809 8 0 1 +80149 4 6 70486 2 0 1 +80153 4 3 53569 6 0 1 +80167 4 3 65523 2 0 1 +80173 4 6 43355 4 0 1 +80177 4 3 71491 2 0 1 +80191 4 11 51587 2 0 1 +80207 4 5 59881 2 0 1 +80209 4 14 48958 12 0 1 +80221 4 2 56865 12 0 1 +80231 4 7 61268 2 0 1 +80233 4 7 72373 13 0 1 +80239 4 3 56406 3 0 1 +80251 4 2 78779 2 0 1 +80263 4 3 48238 2 0 1 +80273 4 3 66155 0 0 1 +80279 4 11 50740 5 0 1 +80287 4 3 60988 3 0 1 +80309 4 2 43863 4 0 1 +80317 4 2 63865 3 0 1 +80329 4 11 51392 12 0 1 +80341 4 2 59368 13 0 1 +80347 4 2 52202 10 0 1 +80363 4 2 80356 8 0 1 +80369 4 3 80357 0 0 1 +80387 4 2 57221 11 0 1 +80407 4 3 68664 5 0 1 +80429 4 2 41322 3 0 1 +80447 4 5 52770 6 0 1 +80449 4 7 67212 16 0 1 +80471 4 17 71746 4 0 1 +80473 4 5 74835 12 0 1 +80489 4 3 71800 2 0 1 +80491 4 2 76331 6 0 1 +80513 4 3 65304 13 0 1 +80527 4 3 63782 2 0 1 +80537 4 3 67798 7 0 1 +80557 4 2 52088 6 0 1 +80567 4 5 79065 10 0 1 +80599 4 3 45384 2 0 1 +80603 4 2 42304 2 0 1 +80611 4 2 75776 6 0 1 +80621 4 2 65341 6 0 1 +80627 4 2 44131 7 0 1 +80629 4 2 48667 3 0 1 +80651 4 2 58369 8 0 1 +80657 4 3 77638 1 0 1 +80669 4 2 79013 17 0 1 +80671 4 3 72929 2 0 1 +80677 4 2 69647 6 0 1 +80681 4 3 62240 7 0 1 +80683 4 3 59236 3 0 1 +80687 4 5 66673 3 0 1 +80701 4 2 67080 7 0 1 +80713 4 5 68049 18 0 1 +80737 4 7 63594 18 0 1 +80747 4 2 60140 7 0 1 +80749 4 2 71585 12 0 1 +80761 4 11 56384 28 0 1 +80777 4 3 57078 1 0 1 +80779 4 2 41715 2 0 1 +80783 4 5 75803 2 0 1 +80789 4 2 59014 6 0 1 +80803 4 2 78391 13 0 1 +80809 4 19 71007 42 0 1 +80819 4 2 73319 7 0 1 +80831 4 7 63312 3 0 1 +80833 4 5 76540 20 0 1 +80849 4 3 80837 0 0 1 +80863 4 3 59199 5 0 1 +80897 4 3 44553 1 0 1 +80909 4 2 72495 4 0 1 +80911 4 3 65970 6 0 1 +80917 4 6 47894 8 0 1 +80923 4 2 75107 7 0 1 +80929 4 19 56800 0 0 1 +80933 4 2 52283 3 0 1 +80953 4 7 73436 8 0 1 +80963 4 5 74575 5 0 1 +80989 4 2 56470 3 0 1 +81001 4 11 70314 14 0 1 +81013 4 6 62924 19 0 1 +81017 4 3 69703 17 0 1 +81019 4 2 73095 2 0 1 +81023 4 5 75713 8 0 1 +81031 4 6 66505 10 0 1 +81041 4 6 75738 5 0 1 +81043 4 5 79030 2 0 1 +81047 4 5 63890 16 0 1 +81049 4 7 81030 22 0 1 +81071 4 7 44123 6 0 1 +81077 4 2 77672 3 0 1 +81083 4 2 59721 14 0 1 +81097 4 5 42547 10 0 1 +81101 4 2 56209 1 0 1 +81119 4 11 69730 3 0 1 +81131 4 2 44016 7 0 1 +81157 4 6 76125 9 0 1 +81163 4 2 46963 2 0 1 +81173 4 2 75089 5 0 1 +81181 4 6 64088 11 0 1 +81197 4 2 62182 6 0 1 +81199 4 6 58312 3 0 1 +81203 4 2 81196 8 0 1 +81223 4 5 81211 11 0 1 +81233 4 3 72077 11 0 1 +81239 4 7 51287 2 0 1 +81281 4 3 62754 7 0 1 +81283 4 2 61273 7 0 1 +81293 4 2 72331 9 0 1 +81299 4 2 69876 3 0 1 +81307 4 2 75198 8 0 1 +81331 4 12 64308 6 0 1 +81343 4 6 80036 3 0 1 +81349 4 2 48042 12 0 1 +81353 4 3 66025 1 0 1 +81359 4 11 42040 2 0 1 +81371 4 2 47683 2 0 1 +81373 4 2 49604 7 0 1 +81401 4 3 80763 2 0 1 +81409 4 7 78971 6 0 1 +81421 4 11 68224 31 0 1 +81439 4 3 57820 2 0 1 +81457 4 5 81446 14 0 1 +81463 4 5 44020 2 0 1 +81509 4 2 41409 0 0 1 +81517 4 2 71606 12 0 1 +81527 4 5 81523 3 0 1 +81533 4 3 66135 5 0 1 +81547 4 3 66662 3 0 1 +81551 4 7 79472 5 0 1 +81553 4 5 81542 14 0 1 +81559 4 6 63371 4 0 1 +81563 4 2 56504 11 0 1 +81569 4 3 59997 2 0 1 +81611 4 2 81604 8 0 1 +81619 4 3 51777 6 0 1 +81629 4 2 55990 6 0 1 +81637 4 2 55131 3 0 1 +81647 4 5 50077 8 0 1 +81649 4 11 75177 0 0 1 +81667 4 3 56420 5 0 1 +81671 4 7 41578 2 0 1 +81677 4 3 75110 4 0 1 +81689 4 3 67242 3 0 1 +81701 4 2 73754 12 0 1 +81703 4 3 76131 5 0 1 +81707 4 2 74069 1 0 1 +81727 4 3 70729 5 0 1 +81737 4 3 43365 7 0 1 +81749 4 2 52507 1 0 1 +81761 4 12 63911 0 0 1 +81769 4 11 48137 0 0 1 +81773 4 2 44810 0 0 1 +81799 4 3 59239 1 0 1 +81817 4 5 54243 6 0 1 +81839 4 7 78131 15 0 1 +81847 4 3 55689 5 0 1 +81853 4 11 74376 1 0 1 +81869 4 2 74007 8 0 1 +81883 4 3 72549 5 0 1 +81899 4 2 72373 1 0 1 +81901 4 2 69257 6 0 1 +81919 4 3 76496 3 0 1 +81929 4 3 51057 8 0 1 +81931 4 3 79907 3 0 1 +81937 4 5 62686 15 0 1 +81943 4 5 59549 5 0 1 +81953 4 3 58809 9 0 1 +81967 4 5 77324 10 0 1 +81971 4 2 51046 8 0 1 +81973 4 2 56121 6 0 1 +82003 4 2 65809 7 0 1 +82007 4 5 62385 2 0 1 +82009 4 13 72624 16 0 1 +82013 4 11 62069 3 0 1 +82021 4 22 82009 6 0 1 +82031 4 11 54552 3 0 1 +82037 4 2 70086 6 0 1 +82039 4 15 63270 2 0 1 +82051 4 2 62947 8 0 1 +82067 4 2 65454 0 0 1 +82073 4 3 63700 0 0 1 +82129 4 13 63046 24 0 1 +82139 4 6 44113 4 0 1 +82141 4 6 55716 2 0 1 +82153 4 5 46076 15 0 1 +82163 4 2 75805 8 0 1 +82171 4 2 44300 2 0 1 +82183 4 21 74480 2 0 1 +82189 4 10 76121 2 0 1 +82193 4 5 50705 8 0 1 +82207 4 3 82203 4 0 1 +82217 4 3 80903 2 0 1 +82219 4 2 69126 3 0 1 +82223 4 5 71062 5 0 1 +82231 4 7 44407 5 0 1 +82237 4 5 74473 10 0 1 +82241 4 3 82229 0 0 1 +82261 4 6 55032 10 0 1 +82267 4 2 67823 1 0 1 +82279 4 6 82275 6 0 1 +82301 4 2 49980 0 0 1 +82307 4 2 52422 8 0 1 +82339 4 2 49544 2 0 1 +82349 4 3 51170 14 0 1 +82351 4 3 82347 4 0 1 +82361 4 3 56310 8 0 1 +82373 4 2 67086 5 0 1 +82387 4 2 54542 8 0 1 +82393 4 5 55968 15 0 1 +82421 4 2 46757 1 0 1 +82457 4 3 77652 0 0 1 +82463 4 5 78808 2 0 1 +82469 4 2 49032 2 0 1 +82471 4 3 48843 6 0 1 +82483 4 2 80432 8 0 1 +82487 4 5 78103 8 0 1 +82493 4 2 77844 6 0 1 +82499 4 6 53676 2 0 1 +82507 4 2 76333 7 0 1 +82529 4 3 71002 2 0 1 +82531 4 3 75326 3 0 1 +82549 4 2 46110 9 0 1 +82559 4 7 63452 2 0 1 +82561 4 7 75309 0 0 1 +82567 4 3 68679 6 0 1 +82571 4 6 80871 4 0 1 +82591 4 6 75332 2 0 1 +82601 4 3 82589 0 0 1 +82609 4 11 58894 22 0 1 +82613 4 2 47546 6 0 1 +82619 4 2 69694 2 0 1 +82633 4 5 58355 6 0 1 +82651 4 2 59623 8 0 1 +82657 4 10 48337 15 0 1 +82699 4 3 75912 3 0 1 +82721 4 6 72837 0 0 1 +82723 4 2 61102 8 0 1 +82727 4 5 62324 2 0 1 +82729 4 7 82710 22 0 1 +82757 4 2 72493 6 0 1 +82759 4 3 45072 2 0 1 +82763 4 2 52949 7 0 1 +82781 4 2 64996 1 0 1 +82787 4 2 42141 11 0 1 +82793 4 3 72993 1 0 1 +82799 4 13 46750 4 0 1 +82811 4 2 43150 7 0 1 +82813 4 2 66458 6 0 1 +82837 4 2 77577 7 0 1 +82847 4 5 61464 8 0 1 +82883 4 2 55847 18 0 1 +82889 4 3 82877 0 0 1 +82891 4 2 72806 8 0 1 +82903 4 3 73894 5 0 1 +82913 4 3 68256 7 0 1 +82939 4 2 44621 2 0 1 +82963 4 3 52130 3 0 1 +82981 4 2 49573 3 0 1 +82997 4 2 54972 3 0 1 +83003 4 2 46629 4 0 1 +83009 4 3 82997 0 0 1 +83023 4 3 47178 8 0 1 +83047 4 3 47635 5 0 1 +83059 4 2 53800 8 0 1 +83063 4 5 78249 2 0 1 +83071 4 14 43185 6 0 1 +83077 4 14 57821 7 0 1 +83089 4 7 48300 0 0 1 +83093 4 2 58833 12 0 1 +83101 4 2 78175 6 0 1 +83117 4 2 60873 6 0 1 +83137 4 5 73266 10 0 1 +83177 4 3 61245 4 0 1 +83203 4 2 67888 8 0 1 +83207 4 5 80501 3 0 1 +83219 4 2 71402 2 0 1 +83221 4 7 73515 13 0 1 +83227 4 5 42363 0 0 1 +83231 4 7 49723 13 0 1 +83233 4 7 79225 8 0 1 +83243 4 2 42837 10 0 1 +83257 4 5 59600 6 0 1 +83267 4 2 77915 4 0 1 +83269 4 2 74469 15 0 1 +83273 4 3 70147 2 0 1 +83299 4 2 44145 0 0 1 +83311 4 12 67642 3 0 1 +83339 4 2 77318 7 0 1 +83341 4 10 81383 3 0 1 +83357 4 2 55141 8 0 1 +83383 4 3 83375 10 0 1 +83389 4 2 81043 7 0 1 +83399 4 7 45528 5 0 1 +83401 4 7 60294 16 0 1 +83407 4 5 83403 3 0 1 +83417 4 3 60180 9 0 1 +83423 4 5 63381 2 0 1 +83431 4 12 76750 6 0 1 +83437 4 2 80169 18 0 1 +83443 4 2 44134 2 0 1 +83449 4 13 42049 26 0 1 +83459 4 2 71233 2 0 1 +83471 4 11 69008 2 0 1 +83477 4 2 75305 6 0 1 +83497 4 10 46830 6 0 1 +83537 4 3 55121 3 0 1 +83557 4 2 66055 7 0 1 +83561 4 3 83549 0 0 1 +83563 4 2 58344 8 0 1 +83579 4 2 44355 11 0 1 +83591 4 7 83582 4 0 1 +83597 4 2 71004 1 0 1 +83609 4 3 75159 3 0 1 +83617 4 5 45680 18 0 1 +83621 4 2 69792 3 0 1 +83639 4 19 43072 8 0 1 +83641 4 7 61860 14 0 1 +83653 4 5 80330 8 0 1 +83663 4 5 49846 9 0 1 +83689 4 13 73739 34 0 1 +83701 4 6 53413 2 0 1 +83717 4 2 73333 9 0 1 +83719 4 6 65689 2 0 1 +83737 4 5 43562 15 0 1 +83761 4 11 65650 10 0 1 +83773 4 5 51690 3 0 1 +83777 4 3 61569 0 0 1 +83791 4 3 73069 6 0 1 +83813 4 2 63896 9 0 1 +83833 4 5 46024 18 0 1 +83843 4 2 48028 0 0 1 +83857 4 5 62309 6 0 1 +83869 4 6 63809 7 0 1 +83873 4 3 70093 9 0 1 +83891 4 2 47157 4 0 1 +83903 4 5 83899 3 0 1 +83911 4 3 67617 6 0 1 +83921 4 3 42888 7 0 1 +83933 4 2 65209 6 0 1 +83939 4 2 43773 7 0 1 +83969 4 3 53813 7 0 1 +83983 4 5 65906 5 0 1 +83987 4 2 75739 3 0 1 +84011 4 6 68532 4 0 1 +84017 4 3 68671 0 0 1 +84047 4 5 51858 4 0 1 +84053 4 2 44102 6 0 1 +84059 4 2 66685 2 0 1 +84061 4 7 52237 4 0 1 +84067 4 2 58797 8 0 1 +84089 4 3 57127 2 0 1 +84121 4 13 81912 14 0 1 +84127 4 3 62032 5 0 1 +84131 4 2 78301 7 0 1 +84137 4 3 48372 3 0 1 +84143 4 5 84139 3 0 1 +84163 4 2 70983 8 0 1 +84179 4 2 73594 7 0 1 +84181 4 2 84174 8 0 1 +84191 4 7 84182 4 0 1 +84199 4 11 46401 5 0 1 +84211 4 3 54952 6 0 1 +84221 4 2 82432 4 0 1 +84223 4 6 53831 2 0 1 +84229 4 2 42439 3 0 1 +84239 4 11 68558 5 0 1 +84247 4 5 60526 10 0 1 +84263 4 5 71886 6 0 1 +84299 4 2 63350 2 0 1 +84307 4 3 58693 11 0 1 +84313 4 5 53362 6 0 1 +84317 4 2 42483 16 0 1 +84319 4 6 54492 10 0 1 +84347 4 2 83844 8 0 1 +84349 4 2 66228 6 0 1 +84377 4 3 67026 0 0 1 +84389 4 2 44813 12 0 1 +84391 4 3 65740 10 0 1 +84401 4 3 72744 2 0 1 +84407 4 5 79795 9 0 1 +84421 4 2 78870 12 0 1 +84431 4 7 53302 3 0 1 +84437 4 2 59837 4 0 1 +84443 4 2 75808 4 0 1 +84449 4 3 78305 4 0 1 +84457 4 5 78551 6 0 1 +84463 4 5 60009 5 0 1 +84467 4 2 74475 11 0 1 +84481 4 7 60446 0 0 1 +84499 4 2 51269 8 0 1 +84503 4 15 43248 5 0 1 +84509 4 2 55675 3 0 1 +84521 4 3 61147 13 0 1 +84523 4 2 57944 2 0 1 +84533 4 2 61937 17 0 1 +84551 4 19 68949 2 0 1 +84559 4 3 55918 3 0 1 +84589 4 2 60868 16 0 1 +84629 4 2 74132 2 0 1 +84631 4 6 61193 2 0 1 +84649 4 13 62937 14 0 1 +84653 4 2 78406 7 0 1 +84659 4 2 57484 0 0 1 +84673 4 10 61794 8 0 1 +84691 4 2 56204 2 0 1 +84697 4 11 75971 12 0 1 +84701 4 2 49463 6 0 1 +84713 4 3 74698 4 0 1 +84719 4 13 45992 6 0 1 +84731 4 2 46079 6 0 1 +84737 4 3 56766 1 0 1 +84751 4 6 43010 2 0 1 +84761 4 7 64891 7 0 1 +84787 4 2 47901 2 0 1 +84793 4 5 75166 21 0 1 +84809 4 3 71505 4 0 1 +84811 4 3 47337 7 0 1 +84827 4 2 63494 3 0 1 +84857 4 3 84033 1 0 1 +84859 4 2 59239 6 0 1 +84869 4 3 59778 2 0 1 +84871 4 3 66439 2 0 1 +84913 4 5 73940 6 0 1 +84919 4 3 70169 3 0 1 +84947 4 2 77330 18 0 1 +84961 4 11 81274 16 0 1 +84967 4 3 68727 6 0 1 +84977 4 3 65886 9 0 1 +84979 4 2 48347 6 0 1 +84991 4 3 66190 6 0 1 +85009 4 13 46408 28 0 1 +85021 4 7 75704 4 0 1 +85027 4 2 57937 10 0 1 +85037 4 2 47435 2 0 1 +85049 4 3 51697 4 0 1 +85061 4 2 68635 6 0 1 +85081 4 7 73852 24 0 1 +85087 4 3 69501 2 0 1 +85091 4 6 52263 4 0 1 +85093 4 2 57947 12 0 1 +85103 4 5 69098 6 0 1 +85109 4 2 71033 1 0 1 +85121 4 6 71135 7 0 1 +85133 4 2 71810 1 0 1 +85147 4 2 69923 7 0 1 +85159 4 3 51289 2 0 1 +85193 4 3 60997 1 0 1 +85199 4 7 85190 4 0 1 +85201 4 22 63597 25 0 1 +85213 4 6 71391 7 0 1 +85223 4 5 65949 2 0 1 +85229 4 3 84816 4 0 1 +85237 4 2 47471 6 0 1 +85243 4 3 68405 3 0 1 +85247 4 5 85243 3 0 1 +85259 4 2 63812 6 0 1 +85297 4 15 57173 6 0 1 +85303 4 5 71357 5 0 1 +85313 4 3 77832 4 0 1 +85331 4 2 46636 8 0 1 +85333 4 5 72738 1 0 1 +85361 4 3 44557 4 0 1 +85363 4 3 61217 3 0 1 +85369 4 17 64954 16 0 1 +85381 4 6 67497 11 0 1 +85411 4 2 48210 8 0 1 +85427 4 2 79618 6 0 1 +85429 4 6 50139 7 0 1 +85439 4 7 85430 4 0 1 +85447 4 3 46532 5 0 1 +85451 4 2 67788 8 0 1 +85453 4 2 72121 6 0 1 +85469 4 3 85465 4 0 1 +85487 4 5 61207 5 0 1 +85513 4 5 75894 6 0 1 +85517 4 2 55533 6 0 1 +85523 4 2 50514 8 0 1 +85531 4 14 77821 2 0 1 +85549 4 2 55721 6 0 1 +85571 4 2 85564 8 0 1 +85577 4 3 70921 7 0 1 +85597 4 2 43941 10 0 1 +85601 4 3 57286 0 0 1 +85607 4 5 43057 4 0 1 +85619 4 6 84127 1 0 1 +85621 4 10 64858 17 0 1 +85627 4 2 85620 8 0 1 +85639 4 3 85635 4 0 1 +85643 4 2 66957 0 0 1 +85661 4 2 68797 7 0 1 +85667 4 5 70694 11 0 1 +85669 4 2 54576 6 0 1 +85691 4 2 53620 8 0 1 +85703 4 5 72072 4 0 1 +85711 4 6 84740 3 0 1 +85717 4 2 73875 10 0 1 +85733 4 2 51237 7 0 1 +85751 4 14 57604 7 0 1 +85781 4 2 61366 4 0 1 +85793 4 3 78800 2 0 1 +85817 4 3 63942 4 0 1 +85819 4 2 43548 7 0 1 +85829 4 2 62106 7 0 1 +85831 4 3 57416 3 0 1 +85837 4 2 85830 8 0 1 +85843 4 3 61435 5 0 1 +85847 4 5 85843 3 0 1 +85853 4 2 76113 6 0 1 +85889 4 3 49293 2 0 1 +85903 4 3 44603 6 0 1 +85909 4 2 73309 0 0 1 +85931 4 2 64320 2 0 1 +85933 4 5 54460 3 0 1 +85991 4 11 69614 7 0 1 +85999 4 3 71115 6 0 1 +86011 4 7 79304 6 0 1 +86017 4 5 86006 14 0 1 +86027 4 2 77272 8 0 1 +86029 4 2 56318 10 0 1 +86069 4 2 83006 0 0 1 +86077 4 5 82618 1 0 1 +86083 4 2 45544 8 0 1 +86111 4 11 60598 5 0 1 +86113 4 5 75500 12 0 1 +86117 4 2 65408 4 0 1 +86131 4 2 68761 2 0 1 +86137 4 5 67832 6 0 1 +86143 4 3 78747 2 0 1 +86161 4 14 48931 22 0 1 +86171 4 7 48630 2 0 1 +86179 4 2 58736 8 0 1 +86183 4 5 62841 3 0 1 +86197 4 2 66956 7 0 1 +86201 4 3 47936 2 0 1 +86209 4 11 61514 14 0 1 +86239 4 3 81264 6 0 1 +86243 4 2 66854 13 0 1 +86249 4 3 86237 0 0 1 +86257 4 5 45060 10 0 1 +86263 4 3 68526 3 0 1 +86269 4 6 85210 2 0 1 +86287 4 11 67760 2 0 1 +86291 4 2 45154 8 0 1 +86293 4 2 76062 10 0 1 +86297 4 3 71712 1 0 1 +86311 4 3 64381 3 0 1 +86323 4 2 77742 7 0 1 +86341 4 2 64182 3 0 1 +86351 4 13 72249 2 0 1 +86353 4 10 52875 24 0 1 +86357 4 2 45402 3 0 1 +86369 4 3 86357 0 0 1 +86371 4 3 46150 2 0 1 +86381 4 3 66569 12 0 1 +86389 4 2 74249 7 0 1 +86399 4 11 83534 10 0 1 +86413 4 2 55786 3 0 1 +86423 4 5 86006 6 0 1 +86441 4 3 86429 0 0 1 +86453 4 2 68996 1 0 1 +86461 4 2 52347 12 0 1 +86467 4 2 68868 2 0 1 +86477 4 2 81636 3 0 1 +86491 4 2 65433 2 0 1 +86501 4 2 81054 7 0 1 +86509 4 6 81483 10 0 1 +86531 4 2 85699 7 0 1 +86533 4 2 66465 7 0 1 +86539 4 3 49584 7 0 1 +86561 4 3 72627 4 0 1 +86573 4 2 54557 12 0 1 +86579 4 2 73124 2 0 1 +86587 4 3 67004 7 0 1 +86599 4 3 44640 2 0 1 +86627 4 2 57171 16 0 1 +86629 4 2 85044 6 0 1 +86677 4 2 64843 9 0 1 +86689 4 13 84972 14 0 1 +86693 4 2 55253 3 0 1 +86711 4 7 55000 3 0 1 +86719 4 6 57420 3 0 1 +86729 4 3 71675 2 0 1 +86743 4 3 49384 2 0 1 +86753 4 3 75157 7 0 1 +86767 4 3 48986 5 0 1 +86771 4 6 71195 5 0 1 +86783 4 5 56575 2 0 1 +86813 4 2 68698 0 0 1 +86837 4 2 82049 7 0 1 +86843 4 2 52412 8 0 1 +86851 4 2 54827 8 0 1 +86857 4 10 74284 22 0 1 +86861 4 2 84997 9 0 1 +86869 4 2 53726 11 0 1 +86923 4 2 54590 8 0 1 +86927 4 5 59244 4 0 1 +86929 4 14 70834 12 0 1 +86939 4 2 53450 4 0 1 +86951 4 7 83694 2 0 1 +86959 4 3 55630 3 0 1 +86969 4 3 73143 3 0 1 +86981 4 2 69207 3 0 1 +86993 4 3 51121 9 0 1 +87011 4 2 48638 7 0 1 +87013 4 5 82915 6 0 1 +87037 4 2 84714 6 0 1 +87041 4 3 77323 2 0 1 +87049 4 19 82393 8 0 1 +87071 4 17 84135 2 0 1 +87083 4 2 59950 2 0 1 +87103 4 3 74077 6 0 1 +87107 4 2 82394 13 0 1 +87119 4 7 58638 0 0 1 +87121 4 7 82060 0 0 1 +87133 4 6 79783 4 0 1 +87149 4 2 49705 1 0 1 +87151 4 3 79521 6 0 1 +87179 4 2 56367 3 0 1 +87181 4 2 73538 3 0 1 +87187 4 3 46572 2 0 1 +87211 4 13 43996 0 0 1 +87221 4 10 70413 8 0 1 +87223 4 3 84598 3 0 1 +87251 4 2 81055 7 0 1 +87253 4 2 78421 7 0 1 +87257 4 3 69139 1 0 1 +87277 4 5 70778 3 0 1 +87281 4 3 85436 7 0 1 +87293 4 2 71729 4 0 1 +87299 4 2 65226 3 0 1 +87313 4 5 64889 12 0 1 +87317 4 2 77751 1 0 1 +87323 4 2 60246 4 0 1 +87337 4 5 57913 6 0 1 +87359 4 19 71352 7 0 1 +87383 4 5 75760 4 0 1 +87403 4 2 79194 8 0 1 +87407 4 5 55107 5 0 1 +87421 4 6 81011 11 0 1 +87427 4 2 61148 8 0 1 +87433 4 5 52544 6 0 1 +87443 4 2 62593 3 0 1 +87473 4 5 44636 10 0 1 +87481 4 29 48219 36 0 1 +87491 4 2 65234 2 0 1 +87509 4 2 80161 2 0 1 +87511 4 3 62448 2 0 1 +87517 4 2 80313 6 0 1 +87523 4 2 75300 8 0 1 +87539 4 2 47703 16 0 1 +87541 4 18 63377 7 0 1 +87547 4 2 61089 10 0 1 +87553 4 5 81453 10 0 1 +87557 4 3 64239 15 0 1 +87559 4 3 62832 6 0 1 +87583 4 3 73976 6 0 1 +87587 4 2 84795 4 0 1 +87589 4 2 45093 3 0 1 +87613 4 2 81843 9 0 1 +87623 4 5 69085 3 0 1 +87629 4 2 69345 4 0 1 +87631 4 6 81868 3 0 1 +87641 4 3 86979 2 0 1 +87643 4 3 52502 2 0 1 +87649 4 17 73497 18 0 1 +87671 4 11 84308 9 0 1 +87679 4 3 80235 3 0 1 +87683 4 2 76787 3 0 1 +87691 4 7 87178 6 0 1 +87697 4 17 52724 11 0 1 +87701 4 2 85003 4 0 1 +87719 4 7 86693 4 0 1 +87721 4 11 72924 20 0 1 +87739 4 7 58923 11 0 1 +87743 4 5 47423 8 0 1 +87751 4 3 87747 4 0 1 +87767 4 5 87763 3 0 1 +87793 4 5 81599 6 0 1 +87797 4 2 61351 3 0 1 +87803 4 5 83146 1 0 1 +87811 4 2 86300 6 0 1 +87833 4 3 55388 26 0 1 +87853 4 2 72141 3 0 1 +87869 4 2 47212 4 0 1 +87877 4 2 67457 6 0 1 +87881 4 3 63538 7 0 1 +87887 4 5 47133 7 0 1 +87911 4 29 80044 4 0 1 +87917 4 2 87254 6 0 1 +87931 4 10 83876 0 0 1 +87943 4 3 81473 6 0 1 +87959 4 7 87950 4 0 1 +87961 4 14 64659 0 0 1 +87973 4 2 68687 10 0 1 +87977 4 3 74554 4 0 1 +87991 4 6 50810 10 0 1 +88001 4 6 73068 0 0 1 +88003 4 2 45385 2 0 1 +88007 4 5 55334 2 0 1 +88019 4 2 53516 3 0 1 +88037 4 2 69629 2 0 1 +88069 4 2 55880 12 0 1 +88079 4 31 49692 6 0 1 +88093 4 2 65214 6 0 1 +88117 4 5 65820 6 0 1 +88129 4 11 76899 8 0 1 +88169 4 3 82590 0 0 1 +88177 4 5 47824 15 0 1 +88211 4 2 44598 7 0 1 +88223 4 5 66757 2 0 1 +88237 4 2 72822 6 0 1 +88241 4 3 61281 2 0 1 +88259 4 2 77291 2 0 1 +88261 4 2 82703 3 0 1 +88289 4 3 55821 1 0 1 +88301 4 2 76602 2 0 1 +88321 4 34 74290 13 0 1 +88327 4 5 60040 5 0 1 +88337 4 3 87076 6 0 1 +88339 4 3 55904 5 0 1 +88379 4 2 78778 16 0 1 +88397 4 2 75084 6 0 1 +88411 4 2 69314 3 0 1 +88423 4 6 79157 2 0 1 +88427 4 2 82450 4 0 1 +88463 4 5 88459 3 0 1 +88469 4 2 55759 3 0 1 +88471 4 11 46755 3 0 1 +88493 4 2 57070 6 0 1 +88499 4 2 77171 3 0 1 +88513 4 10 73337 15 0 1 +88523 4 2 69774 0 0 1 +88547 4 2 77053 15 0 1 +88589 4 2 61714 19 0 1 +88591 4 15 65659 10 0 1 +88607 4 5 88595 11 0 1 +88609 4 17 64549 20 0 1 +88643 4 2 60879 0 0 1 +88651 4 3 54690 2 0 1 +88657 4 5 61668 12 0 1 +88661 4 2 77749 4 0 1 +88663 4 3 88655 10 0 1 +88667 4 2 69703 11 0 1 +88681 4 7 79580 0 0 1 +88721 4 3 85597 7 0 1 +88729 4 17 76589 22 0 1 +88741 4 2 69371 10 0 1 +88747 4 7 60687 11 0 1 +88771 4 11 68103 5 0 1 +88789 4 2 52808 10 0 1 +88793 4 3 45894 2 0 1 +88799 4 7 88790 4 0 1 +88801 4 7 60014 26 0 1 +88807 4 5 88803 3 0 1 +88811 4 2 86213 8 0 1 +88813 4 5 45904 1 0 1 +88817 4 3 70968 1 0 1 +88819 4 2 56474 1 0 1 +88843 4 2 88836 8 0 1 +88853 4 2 58554 2 0 1 +88861 4 2 85821 9 0 1 +88867 4 2 85769 8 0 1 +88873 4 15 58644 8 0 1 +88883 4 2 48911 7 0 1 +88897 4 11 88877 12 0 1 +88903 4 3 53184 3 0 1 +88919 4 23 66274 6 0 1 +88937 4 3 79818 7 0 1 +88951 4 3 88947 4 0 1 +88969 4 7 52073 0 0 1 +88993 4 5 72906 20 0 1 +88997 4 2 83220 11 0 1 +89003 4 2 63678 2 0 1 +89009 4 3 88587 7 0 1 +89017 4 5 48720 6 0 1 +89021 4 2 85906 12 0 1 +89041 4 29 49844 25 0 1 +89051 4 2 52231 7 0 1 +89057 4 3 62232 0 0 1 +89069 4 2 65186 16 0 1 +89071 4 6 80263 2 0 1 +89083 4 2 84206 8 0 1 +89087 4 5 60314 3 0 1 +89101 4 2 50989 7 0 1 +89107 4 2 88590 8 0 1 +89113 4 7 57056 10 0 1 +89119 4 6 79322 3 0 1 +89123 4 5 60119 2 0 1 +89137 4 5 73978 6 0 1 +89153 4 3 76538 1 0 1 +89189 4 2 82558 6 0 1 +89203 4 2 83761 8 0 1 +89209 4 22 78469 0 0 1 +89213 4 2 83322 1 0 1 +89227 4 3 82947 7 0 1 +89231 4 14 54243 2 0 1 +89237 4 2 78562 7 0 1 +89261 4 2 47531 2 0 1 +89269 4 2 89262 8 0 1 +89273 4 3 82440 11 0 1 +89293 4 5 73019 3 0 1 +89303 4 5 70612 2 0 1 +89317 4 2 47251 10 0 1 +89329 4 13 80083 14 0 1 +89363 4 5 71387 0 0 1 +89371 4 2 75314 8 0 1 +89381 4 2 48063 1 0 1 +89387 4 2 76759 7 0 1 +89393 4 3 70160 6 0 1 +89399 4 7 53441 2 0 1 +89413 4 2 78153 7 0 1 +89417 4 3 66268 1 0 1 +89431 4 11 63805 2 0 1 +89443 4 2 65879 10 0 1 +89449 4 11 72948 10 0 1 +89459 4 2 48498 7 0 1 +89477 4 2 67764 9 0 1 +89491 4 2 89484 8 0 1 +89501 4 2 88832 9 0 1 +89513 4 3 49461 22 0 1 +89519 4 11 66672 5 0 1 +89521 4 14 77349 10 0 1 +89527 4 3 56588 3 0 1 +89533 4 2 50430 6 0 1 +89561 4 3 58735 7 0 1 +89563 4 2 67302 7 0 1 +89567 4 5 56806 4 0 1 +89591 4 13 79892 2 0 1 +89597 4 2 76712 6 0 1 +89599 4 3 68467 3 0 1 +89603 4 2 78467 11 0 1 +89611 4 2 51932 8 0 1 +89627 4 2 74306 13 0 1 +89633 4 3 87516 2 0 1 +89653 4 17 47869 3 0 1 +89657 4 3 46656 4 0 1 +89659 4 10 66021 5 0 1 +89669 4 2 77196 3 0 1 +89671 4 6 83849 3 0 1 +89681 4 3 88834 8 0 1 +89689 4 7 73283 0 0 1 +89753 4 3 72351 1 0 1 +89759 4 13 50779 3 0 1 +89767 4 3 61326 5 0 1 +89779 4 2 78492 8 0 1 +89783 4 5 68963 5 0 1 +89797 4 5 87272 3 0 1 +89809 4 7 50080 17 0 1 +89819 4 2 62438 8 0 1 +89821 4 2 53125 6 0 1 +89833 4 5 61199 18 0 1 +89839 4 7 48463 0 0 1 +89849 4 3 74019 2 0 1 +89867 4 2 86502 6 0 1 +89891 4 7 89882 4 0 1 +89897 4 3 54108 0 0 1 +89899 4 2 83993 1 0 1 +89909 4 2 52838 7 0 1 +89917 4 2 71569 22 0 1 +89923 4 3 77197 24 0 1 +89939 4 2 79281 2 0 1 +89959 4 3 58162 3 0 1 +89963 4 2 66614 4 0 1 +89977 4 5 72067 6 0 1 +89983 4 3 50744 3 0 1 +89989 4 2 77048 10 0 1 +90001 4 13 58023 23 0 1 +90007 4 6 70111 5 0 1 +90011 4 2 51361 11 0 1 +90017 4 3 65711 0 0 1 +90019 4 14 59043 2 0 1 +90023 4 5 45731 5 0 1 +90031 4 3 80184 3 0 1 +90053 4 2 86329 3 0 1 +90059 4 2 72422 6 0 1 +90067 4 2 46751 17 0 1 +90071 4 7 49992 2 0 1 +90073 4 10 48964 22 0 1 +90089 4 3 88445 7 0 1 +90107 4 2 46823 15 0 1 +90121 4 23 87998 16 0 1 +90127 4 3 55920 3 0 1 +90149 4 2 86484 1 0 1 +90163 4 2 88312 2 0 1 +90173 4 2 60563 4 0 1 +90187 4 2 53565 2 0 1 +90191 4 17 72994 14 0 1 +90197 4 2 67144 0 0 1 +90199 4 3 90195 4 0 1 +90203 4 2 87602 7 0 1 +90217 4 22 86753 6 0 1 +90227 4 2 82857 1 0 1 +90239 4 7 51383 2 0 1 +90247 4 5 72406 9 0 1 +90263 4 5 52953 7 0 1 +90271 4 3 67902 3 0 1 +90281 4 3 70020 3 0 1 +90289 4 23 69885 8 0 1 +90313 4 5 88188 10 0 1 +90353 4 3 79362 1 0 1 +90359 4 11 76295 10 0 1 +90371 4 2 65545 4 0 1 +90373 4 5 49256 1 0 1 +90379 4 2 79573 8 0 1 +90397 4 2 84894 3 0 1 +90401 4 6 54060 0 0 1 +90403 4 3 51970 3 0 1 +90407 4 5 90395 11 0 1 +90437 4 2 79758 6 0 1 +90439 4 13 60092 2 0 1 +90469 4 2 71719 7 0 1 +90473 4 3 74211 0 0 1 +90481 4 14 45930 8 0 1 +90499 4 2 71957 10 0 1 +90511 4 3 80865 3 0 1 +90523 4 2 85970 7 0 1 +90527 4 5 61759 7 0 1 +90529 4 7 52506 24 0 1 +90533 4 2 87647 9 0 1 +90547 4 2 52710 10 0 1 +90583 4 5 90579 3 0 1 +90599 4 11 57709 3 0 1 +90617 4 3 54153 6 0 1 +90619 4 3 46200 5 0 1 +90631 4 3 75393 3 0 1 +90641 4 3 77187 2 0 1 +90647 4 5 52402 6 0 1 +90659 4 2 76125 11 0 1 +90677 4 2 90670 8 0 1 +90679 4 3 78993 3 0 1 +90697 4 5 85335 6 0 1 +90703 4 3 75915 2 0 1 +90709 4 6 64890 0 0 1 +90731 4 2 67657 8 0 1 +90749 4 2 49247 6 0 1 +90787 4 3 55921 3 0 1 +90793 4 5 61253 10 0 1 +90803 4 2 51188 7 0 1 +90821 4 3 90817 4 0 1 +90823 4 6 90149 8 0 1 +90833 4 3 51966 7 0 1 +90841 4 17 51367 20 0 1 +90847 4 5 84626 2 0 1 +90863 4 5 90859 3 0 1 +90887 4 5 80344 5 0 1 +90901 4 2 65844 7 0 1 +90907 4 5 90903 3 0 1 +90911 4 7 69833 2 0 1 +90917 4 2 65494 7 0 1 +90931 4 11 70813 2 0 1 +90947 4 2 69616 1 0 1 +90971 4 2 65157 4 0 1 +90977 4 3 77733 11 0 1 +90989 4 2 58819 3 0 1 +90997 4 5 84198 20 0 1 +91009 4 11 81745 16 0 1 +91019 4 2 79315 4 0 1 +91033 4 5 91022 14 0 1 +91079 4 7 73240 12 0 1 +91081 4 17 49467 30 0 1 +91097 4 3 57390 0 0 1 +91099 4 2 86394 8 0 1 +91121 4 6 74214 0 0 1 +91127 4 5 50315 3 0 1 +91129 4 7 73326 0 0 1 +91139 4 2 73038 1 0 1 +91141 4 6 74979 7 0 1 +91151 4 7 90724 2 0 1 +91153 4 7 88955 8 0 1 +91159 4 6 81521 2 0 1 +91163 4 2 53788 7 0 1 +91183 4 3 76981 3 0 1 +91193 4 3 69107 2 0 1 +91199 4 11 57553 4 0 1 +91229 4 2 74540 1 0 1 +91237 4 6 54395 6 0 1 +91243 4 5 91235 6 0 1 +91249 4 17 88547 21 0 1 +91253 4 2 78562 12 0 1 +91283 4 2 52796 13 0 1 +91291 4 2 46882 28 0 1 +91297 4 5 75899 6 0 1 +91303 4 3 53758 3 0 1 +91309 4 10 91297 10 0 1 +91331 4 2 81982 3 0 1 +91367 4 11 78831 6 0 1 +91369 4 7 58816 0 0 1 +91373 4 3 63406 20 0 1 +91381 4 17 85807 4 0 1 +91387 4 2 67182 8 0 1 +91393 4 23 79072 47 0 1 +91397 4 2 49266 1 0 1 +91411 4 2 61380 6 0 1 +91423 4 3 82479 2 0 1 +91433 4 3 60385 2 0 1 +91453 4 6 62412 6 0 1 +91457 4 3 85056 0 0 1 +91459 4 2 84182 8 0 1 +91463 4 5 86817 5 0 1 +91493 4 2 53089 9 0 1 +91499 4 2 50634 7 0 1 +91513 4 10 65693 6 0 1 +91529 4 3 91517 0 0 1 +91541 4 2 57756 1 0 1 +91571 4 2 55807 8 0 1 +91573 4 5 91145 3 0 1 +91577 4 3 55670 7 0 1 +91583 4 5 90626 2 0 1 +91591 4 3 91587 4 0 1 +91621 4 2 68885 3 0 1 +91631 4 7 74108 4 0 1 +91639 4 3 68529 3 0 1 +91673 4 3 83024 4 0 1 +91691 4 2 73690 2 0 1 +91703 4 5 91699 3 0 1 +91711 4 11 69581 6 0 1 +91733 4 2 69673 6 0 1 +91753 4 10 85710 8 0 1 +91757 4 2 50197 11 0 1 +91771 4 2 75038 8 0 1 +91781 4 2 61413 12 0 1 +91801 4 13 89177 10 0 1 +91807 4 3 91803 4 0 1 +91811 4 2 74995 7 0 1 +91813 4 2 61823 10 0 1 +91823 4 5 78435 5 0 1 +91837 4 2 48907 6 0 1 +91841 4 3 64452 4 0 1 +91867 4 2 67015 10 0 1 +91873 4 5 79986 6 0 1 +91909 4 2 54536 9 0 1 +91921 4 13 62926 16 0 1 +91939 4 2 53264 3 0 1 +91943 4 5 60751 3 0 1 +91951 4 3 82295 3 0 1 +91957 4 7 70115 4 0 1 +91961 4 15 78886 3 0 1 +91967 4 5 91963 3 0 1 +91969 4 13 69462 16 0 1 +91997 4 2 55417 6 0 1 +92003 4 2 86036 13 0 1 +92009 4 3 54896 2 0 1 +92033 4 3 50748 0 0 1 +92041 4 7 64681 0 0 1 +92051 4 6 74667 2 0 1 +92077 4 2 60404 3 0 1 +92083 4 2 67601 12 0 1 +92107 4 2 52323 8 0 1 +92111 4 13 83816 7 0 1 +92119 4 3 67374 6 0 1 +92143 4 5 65197 5 0 1 +92153 4 3 61292 7 0 1 +92173 4 2 80029 12 0 1 +92177 4 6 73491 8 0 1 +92179 4 3 85229 2 0 1 +92189 4 2 56701 2 0 1 +92203 4 2 69284 11 0 1 +92219 4 2 61932 7 0 1 +92221 4 6 47606 8 0 1 +92227 4 3 88520 3 0 1 +92233 4 5 74044 15 0 1 +92237 4 2 66244 1 0 1 +92243 4 2 83218 4 0 1 +92251 4 2 73491 6 0 1 +92269 4 10 77657 3 0 1 +92297 4 3 57158 6 0 1 +92311 4 7 89997 5 0 1 +92317 4 6 76088 4 0 1 +92333 4 2 75472 3 0 1 +92347 4 5 46963 0 0 1 +92353 4 5 59252 12 0 1 +92357 4 3 52873 14 0 1 +92363 4 2 68580 12 0 1 +92369 4 3 84567 4 0 1 +92377 4 7 46885 10 0 1 +92381 4 2 64984 6 0 1 +92383 4 3 92379 4 0 1 +92387 4 2 54274 8 0 1 +92399 4 13 91487 4 0 1 +92401 4 34 72727 32 0 1 +92413 4 2 51430 3 0 1 +92419 4 2 92412 8 0 1 +92431 4 6 75729 3 0 1 +92459 4 2 54438 7 0 1 +92461 4 2 76655 3 0 1 +92467 4 2 50389 8 0 1 +92479 4 6 62711 3 0 1 +92489 4 3 92477 0 0 1 +92503 4 5 83399 10 0 1 +92507 4 2 88006 8 0 1 +92551 4 7 62292 5 0 1 +92557 4 2 86841 6 0 1 +92567 4 5 72826 4 0 1 +92569 4 31 85427 26 0 1 +92581 4 6 72794 0 0 1 +92593 4 5 92582 14 0 1 +92623 4 11 68484 5 0 1 +92627 4 2 56687 0 0 1 +92639 4 7 70281 7 0 1 +92641 4 11 47585 22 0 1 +92647 4 3 75648 3 0 1 +92657 4 3 91796 0 0 1 +92669 4 2 60388 9 0 1 +92671 4 3 71451 2 0 1 +92681 4 3 53959 7 0 1 +92683 4 3 79305 2 0 1 +92693 4 2 57116 3 0 1 +92699 4 2 51708 2 0 1 +92707 4 2 51068 2 0 1 +92717 4 2 84707 12 0 1 +92723 4 2 63648 3 0 1 +92737 4 5 72599 16 0 1 +92753 4 3 57683 1 0 1 +92761 4 26 56897 29 0 1 +92767 4 3 67277 6 0 1 +92779 4 2 90004 8 0 1 +92789 4 2 66713 6 0 1 +92791 4 6 64287 3 0 1 +92801 4 3 49917 2 0 1 +92809 4 14 70472 8 0 1 +92821 4 6 92813 12 0 1 +92831 4 7 51923 2 0 1 +92849 4 3 79914 8 0 1 +92857 4 5 92846 14 0 1 +92861 4 2 89454 1 0 1 +92863 4 6 63894 5 0 1 +92867 4 2 63074 10 0 1 +92893 4 5 68537 3 0 1 +92899 4 7 86070 0 0 1 +92921 4 3 92909 0 0 1 +92927 4 5 92915 11 0 1 +92941 4 2 62327 10 0 1 +92951 4 11 47140 2 0 1 +92957 4 2 64421 7 0 1 +92959 4 6 60236 5 0 1 +92987 4 2 61611 2 0 1 +92993 4 3 74567 4 0 1 +93001 4 14 81131 8 0 1 +93047 4 5 52220 8 0 1 +93053 4 2 84425 6 0 1 +93059 4 2 60438 7 0 1 +93077 4 2 82908 3 0 1 +93083 4 2 48340 8 0 1 +93089 4 3 67299 0 0 1 +93097 4 10 54524 10 0 1 +93103 4 5 46816 8 0 1 +93113 4 3 82056 11 0 1 +93131 4 6 50691 5 0 1 +93133 4 6 86194 0 0 1 +93139 4 2 81769 8 0 1 +93151 4 3 74064 3 0 1 +93169 4 11 89770 10 0 1 +93179 4 2 79311 8 0 1 +93187 4 3 54248 5 0 1 +93199 4 7 61765 5 0 1 +93229 4 6 83093 7 0 1 +93239 4 11 66356 7 0 1 +93241 4 13 55403 30 0 1 +93251 4 2 90259 8 0 1 +93253 4 2 69769 3 0 1 +93257 4 3 92449 0 0 1 +93263 4 5 78965 1 0 1 +93281 4 3 84093 2 0 1 +93283 4 2 92225 8 0 1 +93287 4 5 93283 3 0 1 +93307 4 2 92778 14 0 1 +93319 4 3 58537 3 0 1 +93323 4 2 69739 7 0 1 +93329 4 3 58619 2 0 1 +93337 4 5 93326 14 0 1 +93371 4 2 89104 11 0 1 +93377 4 3 77700 0 0 1 +93383 4 5 61397 5 0 1 +93407 4 5 62820 4 0 1 +93419 4 2 52904 7 0 1 +93427 4 2 52093 2 0 1 +93463 4 3 71770 5 0 1 +93479 4 7 64398 4 0 1 +93481 4 35 62766 8 0 1 +93487 4 6 85764 2 0 1 +93491 4 2 51730 2 0 1 +93493 4 2 64208 12 0 1 +93497 4 3 73856 0 0 1 +93503 4 5 56264 10 0 1 +93523 4 2 52065 11 0 1 +93529 4 11 50187 24 0 1 +93553 4 5 58144 10 0 1 +93557 4 2 52052 6 0 1 +93559 4 3 87503 3 0 1 +93563 4 5 49564 0 0 1 +93581 4 3 87932 12 0 1 +93601 4 22 81215 12 0 1 +93607 4 3 55991 5 0 1 +93629 4 2 66153 8 0 1 +93637 4 5 85296 7 0 1 +93683 4 2 60736 18 0 1 +93701 4 2 65243 4 0 1 +93703 4 5 48177 2 0 1 +93719 4 13 67929 8 0 1 +93739 4 3 60347 0 0 1 +93761 4 6 56073 0 0 1 +93763 4 2 51543 2 0 1 +93787 4 7 58891 19 0 1 +93809 4 3 93797 0 0 1 +93811 4 2 61705 8 0 1 +93827 4 2 53937 2 0 1 +93851 4 2 53104 8 0 1 +93871 4 3 59140 2 0 1 +93887 4 5 73264 2 0 1 +93889 4 14 69762 10 0 1 +93893 4 2 75439 2 0 1 +93901 4 2 88746 7 0 1 +93911 4 11 87317 2 0 1 +93913 4 5 68389 6 0 1 +93923 4 2 88020 7 0 1 +93937 4 15 48278 14 0 1 +93941 4 2 88961 7 0 1 +93949 4 2 60276 0 0 1 +93967 4 11 85776 2 0 1 +93971 4 2 62226 4 0 1 +93979 4 3 54012 3 0 1 +93983 4 5 92921 5 0 1 +93997 4 11 68986 3 0 1 +94007 4 5 49707 11 0 1 +94009 4 13 93970 0 0 1 +94033 4 15 75335 13 0 1 +94049 4 3 58138 4 0 1 +94057 4 7 80469 14 0 1 +94063 4 3 61800 2 0 1 +94079 4 13 57861 6 0 1 +94099 4 2 52964 2 0 1 +94109 4 2 81390 17 0 1 +94111 4 3 90076 3 0 1 +94117 4 2 86182 10 0 1 +94121 4 3 94109 0 0 1 +94151 4 7 69112 5 0 1 +94153 4 5 66094 6 0 1 +94169 4 3 94157 0 0 1 +94201 4 11 53642 27 0 1 +94207 4 6 92735 2 0 1 +94219 4 3 56115 3 0 1 +94229 4 2 53294 9 0 1 +94253 4 2 70338 4 0 1 +94261 4 6 66238 7 0 1 +94273 4 5 91249 6 0 1 +94291 4 2 51158 8 0 1 +94307 4 2 51537 4 0 1 +94309 4 6 60382 2 0 1 +94321 4 7 64258 0 0 1 +94327 4 3 92510 5 0 1 +94331 4 2 57050 2 0 1 +94343 4 5 90761 5 0 1 +94349 4 2 70590 3 0 1 +94351 4 3 70560 6 0 1 +94379 4 2 62113 2 0 1 +94397 4 2 75264 4 0 1 +94399 4 3 76959 3 0 1 +94421 4 2 67118 3 0 1 +94427 4 2 47481 2 0 1 +94433 4 5 57405 4 0 1 +94439 4 7 74611 2 0 1 +94441 4 11 61560 20 0 1 +94447 4 5 94435 11 0 1 +94463 4 5 73343 7 0 1 +94477 4 2 92533 9 0 1 +94483 4 2 48946 8 0 1 +94513 4 5 74549 10 0 1 +94529 4 3 70277 7 0 1 +94531 4 10 73810 2 0 1 +94541 4 2 86720 3 0 1 +94543 4 3 54415 3 0 1 +94547 4 2 75384 4 0 1 +94559 4 11 66411 2 0 1 +94561 4 14 57069 20 0 1 +94573 4 2 83257 3 0 1 +94583 4 5 94579 3 0 1 +94597 4 5 67430 6 0 1 +94603 4 5 89653 18 0 1 +94613 4 3 81968 6 0 1 +94621 4 2 47865 10 0 1 +94649 4 3 79805 10 0 1 +94651 4 2 54714 8 0 1 +94687 4 5 77788 12 0 1 +94693 4 5 54942 23 0 1 +94709 4 2 82155 7 0 1 +94723 4 2 94716 8 0 1 +94727 4 5 61647 8 0 1 +94747 4 2 80561 8 0 1 +94771 4 10 68212 0 0 1 +94777 4 10 61064 16 0 1 +94781 4 2 86227 6 0 1 +94789 4 2 76763 6 0 1 +94793 4 3 61930 1 0 1 +94811 4 2 65216 2 0 1 +94819 4 2 71968 8 0 1 +94823 4 5 94819 3 0 1 +94837 4 2 55689 6 0 1 +94841 4 3 79982 4 0 1 +94847 4 5 79653 3 0 1 +94849 4 7 64470 6 0 1 +94873 4 5 63762 10 0 1 +94889 4 3 63113 8 0 1 +94903 4 3 72731 5 0 1 +94907 4 2 83172 0 0 1 +94933 4 2 94926 8 0 1 +94949 4 2 93796 4 0 1 +94951 4 6 93929 2 0 1 +94961 4 3 73412 4 0 1 +94993 4 10 72892 6 0 1 +94999 4 3 67981 3 0 1 +95003 4 2 88963 0 0 1 +95009 4 3 94997 0 0 1 +95021 4 2 93750 3 0 1 +95027 4 2 69054 4 0 1 +95063 4 5 86191 3 0 1 +95071 4 3 85185 3 0 1 +95083 4 2 65786 8 0 1 +95087 4 5 67780 6 0 1 +95089 4 13 62743 28 0 1 +95093 4 2 79129 9 0 1 +95101 4 2 65026 3 0 1 +95107 4 5 59108 2 0 1 +95111 4 11 57452 6 0 1 +95131 4 7 71012 6 0 1 +95143 4 3 95139 4 0 1 +95153 4 3 74243 0 0 1 +95177 4 3 60159 12 0 1 +95189 4 2 83204 1 0 1 +95191 4 13 93882 4 0 1 +95203 4 2 48274 7 0 1 +95213 4 3 87737 6 0 1 +95219 4 2 49786 2 0 1 +95231 4 11 61498 5 0 1 +95233 4 5 68408 10 0 1 +95239 4 7 49752 11 0 1 +95257 4 5 75830 6 0 1 +95261 4 2 62802 4 0 1 +95267 4 2 48970 7 0 1 +95273 4 3 83479 12 0 1 +95279 4 7 80857 2 0 1 +95287 4 3 85970 6 0 1 +95311 4 3 69780 6 0 1 +95317 4 5 48647 8 0 1 +95327 4 5 81502 7 0 1 +95339 4 2 79802 4 0 1 +95369 4 3 76681 7 0 1 +95383 4 3 73155 5 0 1 +95393 4 3 74291 11 0 1 +95401 4 7 48825 26 0 1 +95413 4 2 68600 3 0 1 +95419 4 3 93540 7 0 1 +95429 4 2 75302 1 0 1 +95441 4 3 91825 2 0 1 +95443 4 3 64280 5 0 1 +95461 4 2 84420 6 0 1 +95467 4 5 89914 0 0 1 +95471 4 43 78567 4 0 1 +95479 4 17 72918 9 0 1 +95483 4 2 86754 2 0 1 +95507 4 2 93236 10 0 1 +95527 4 3 82183 3 0 1 +95531 4 2 76672 8 0 1 +95539 4 3 67779 3 0 1 +95549 4 2 95542 8 0 1 +95561 4 3 78911 2 0 1 +95569 4 14 92540 12 0 1 +95581 4 2 69439 3 0 1 +95597 4 2 77240 1 0 1 +95603 4 5 53811 4 0 1 +95617 4 5 74245 10 0 1 +95621 4 3 89689 14 0 1 +95629 4 2 51163 10 0 1 +95633 4 3 75190 2 0 1 +95651 4 2 81910 2 0 1 +95701 4 2 78245 10 0 1 +95707 4 2 64406 7 0 1 +95713 4 5 79947 6 0 1 +95717 4 2 81045 2 0 1 +95723 4 2 66923 2 0 1 +95731 4 2 69479 6 0 1 +95737 4 5 79467 6 0 1 +95747 4 5 74356 0 0 1 +95773 4 7 89150 8 0 1 +95783 4 5 95779 3 0 1 +95789 4 2 74195 6 0 1 +95791 4 3 84161 3 0 1 +95801 4 3 59716 4 0 1 +95803 4 3 55773 11 0 1 +95813 4 2 58590 12 0 1 +95819 4 2 52328 4 0 1 +95857 4 10 66217 6 0 1 +95869 4 6 70183 7 0 1 +95873 4 3 61085 0 0 1 +95881 4 13 80960 16 0 1 +95891 4 2 80263 2 0 1 +95911 4 3 77739 2 0 1 +95917 4 2 75116 3 0 1 +95923 4 3 52044 2 0 1 +95929 4 26 48312 0 0 1 +95947 4 2 93508 2 0 1 +95957 4 2 84588 5 0 1 +95959 4 3 55515 3 0 1 +95971 4 3 53167 6 0 1 +95987 4 2 85476 13 0 1 +95989 4 6 68967 8 0 1 +96001 4 7 75790 17 0 1 +96013 4 2 93294 9 0 1 +96017 4 3 67724 1 0 1 +96043 4 2 74901 7 0 1 +96053 4 2 93405 6 0 1 +96059 4 2 77432 4 0 1 +96079 4 3 81412 3 0 1 +96097 4 5 81898 6 0 1 +96137 4 3 78031 7 0 1 +96149 4 2 68855 6 0 1 +96157 4 5 85623 1 0 1 +96167 4 5 87206 5 0 1 +96179 4 2 79292 3 0 1 +96181 4 6 96177 6 0 1 +96199 4 3 62765 7 0 1 +96211 4 2 59834 6 0 1 +96221 4 2 75652 1 0 1 +96223 4 5 96219 3 0 1 +96233 4 3 94954 11 0 1 +96259 4 2 94201 8 0 1 +96263 4 5 71103 9 0 1 +96269 4 2 55930 3 0 1 +96281 4 3 96269 0 0 1 +96289 4 11 55587 14 0 1 +96293 4 2 71802 6 0 1 +96323 4 2 58808 20 0 1 +96329 4 3 51241 4 0 1 +96331 4 10 67123 0 0 1 +96337 4 5 74628 10 0 1 +96353 4 3 71768 12 0 1 +96377 4 3 93121 7 0 1 +96401 4 3 67648 4 0 1 +96419 4 6 51814 0 0 1 +96431 4 11 68311 7 0 1 +96443 4 2 94119 0 0 1 +96451 4 2 75576 2 0 1 +96457 4 5 84928 6 0 1 +96461 4 2 60988 6 0 1 +96469 4 10 90351 2 0 1 +96479 4 11 56985 2 0 1 +96487 4 3 96483 4 0 1 +96493 4 5 62411 7 0 1 +96497 4 3 62856 0 0 1 +96517 4 2 88676 10 0 1 +96527 4 5 67420 11 0 1 +96553 4 5 80776 6 0 1 +96557 4 2 67702 3 0 1 +96581 4 2 59621 12 0 1 +96587 4 2 76978 3 0 1 +96589 4 6 67855 2 0 1 +96601 4 11 63429 20 0 1 +96643 4 2 79925 8 0 1 +96661 4 7 59902 1 0 1 +96667 4 2 54005 8 0 1 +96671 4 7 92488 5 0 1 +96697 4 7 48909 12 0 1 +96703 4 3 49867 5 0 1 +96731 4 2 61297 7 0 1 +96737 4 3 52379 0 0 1 +96739 4 2 75132 6 0 1 +96749 4 2 49212 7 0 1 +96757 4 5 79768 7 0 1 +96763 4 5 65086 2 0 1 +96769 4 22 78211 26 0 1 +96779 4 2 92856 3 0 1 +96787 4 2 86895 2 0 1 +96797 4 2 92267 12 0 1 +96799 4 6 67656 2 0 1 +96821 4 2 53675 8 0 1 +96823 4 5 68098 2 0 1 +96827 4 2 87707 2 0 1 +96847 4 3 83225 6 0 1 +96851 4 2 62054 2 0 1 +96857 4 3 73630 2 0 1 +96893 4 2 94442 6 0 1 +96907 4 2 65057 1 0 1 +96911 4 11 52910 2 0 1 +96931 4 2 60283 8 0 1 +96953 4 3 94602 0 0 1 +96959 4 7 81272 2 0 1 +96973 4 2 49922 6 0 1 +96979 4 3 77350 5 0 1 +96989 4 2 71391 14 0 1 +96997 4 2 50855 3 0 1 +97001 4 3 75690 2 0 1 +97003 4 7 56471 11 0 1 +97007 4 5 73660 5 0 1 +97021 4 2 58337 10 0 1 +97039 4 3 89245 3 0 1 +97073 4 3 64947 13 0 1 +97081 4 7 90865 25 0 1 +97103 4 5 68961 8 0 1 +97117 4 2 59869 7 0 1 +97127 4 5 97123 3 0 1 +97151 4 13 89716 7 0 1 +97157 4 2 86477 5 0 1 +97159 4 3 59421 3 0 1 +97169 4 3 97157 0 0 1 +97171 4 10 65438 8 0 1 +97177 4 5 65272 15 0 1 +97187 4 2 87090 1 0 1 +97213 4 5 91750 1 0 1 +97231 4 6 56787 2 0 1 +97241 4 3 97229 0 0 1 +97259 4 6 83125 1 0 1 +97283 4 2 56145 7 0 1 +97301 4 2 56394 2 0 1 +97303 4 3 70350 2 0 1 +97327 4 5 82939 2 0 1 +97367 4 5 81613 6 0 1 +97369 4 7 87306 14 0 1 +97373 4 2 86367 1 0 1 +97379 4 2 66311 7 0 1 +97381 4 2 73755 6 0 1 +97387 4 2 65200 10 0 1 +97397 4 2 74074 3 0 1 +97423 4 3 57360 5 0 1 +97429 4 6 97425 6 0 1 +97441 4 37 66484 29 0 1 +97453 4 2 68677 6 0 1 +97459 4 2 89451 7 0 1 +97463 4 5 63961 8 0 1 +97499 4 2 61863 4 0 1 +97501 4 7 80183 4 0 1 +97511 4 7 90201 10 0 1 +97523 4 2 97516 8 0 1 +97547 4 2 79551 7 0 1 +97549 4 2 93801 0 0 1 +97553 4 3 54418 12 0 1 +97561 4 11 81708 12 0 1 +97571 4 2 54336 2 0 1 +97577 4 3 89843 6 0 1 +97579 4 2 63825 6 0 1 +97583 4 5 53026 7 0 1 +97607 4 5 97603 3 0 1 +97609 4 17 53535 16 0 1 +97613 4 2 96625 3 0 1 +97649 4 3 97207 7 0 1 +97651 4 2 84145 8 0 1 +97673 4 3 73017 0 0 1 +97687 4 5 62987 3 0 1 +97711 4 11 88700 9 0 1 +97729 4 13 51717 22 0 1 +97771 4 3 90080 3 0 1 +97777 4 17 92452 8 0 1 +97787 4 2 65537 8 0 1 +97789 4 2 88523 3 0 1 +97813 4 2 63890 6 0 1 +97829 4 2 90608 6 0 1 +97841 4 6 52449 6 0 1 +97843 4 2 54813 8 0 1 +97847 4 5 85087 14 0 1 +97849 4 13 64418 4 0 1 +97859 4 2 69466 2 0 1 +97861 4 2 92362 10 0 1 +97871 4 7 52802 2 0 1 +97879 4 6 81139 2 0 1 +97883 4 2 71286 8 0 1 +97919 4 23 83099 4 0 1 +97927 4 3 69330 6 0 1 +97931 4 2 91641 7 0 1 +97943 4 5 72877 4 0 1 +97961 4 3 51177 4 0 1 +97967 4 5 71612 6 0 1 +97973 4 2 89220 4 0 1 +97987 4 2 65742 8 0 1 +98009 4 3 80745 8 0 1 +98011 4 10 52900 0 0 1 +98017 4 7 66882 8 0 1 +98041 4 13 86782 33 0 1 +98047 4 5 98043 3 0 1 +98057 4 3 66944 0 0 1 +98081 4 6 65154 0 0 1 +98101 4 2 73751 9 0 1 +98123 4 2 75528 4 0 1 +98129 4 3 90198 3 0 1 +98143 4 5 79362 2 0 1 +98179 4 2 69135 8 0 1 +98207 4 5 75019 2 0 1 +98213 4 2 68474 9 0 1 +98221 4 2 64436 6 0 1 +98227 4 3 60233 5 0 1 +98251 4 2 58585 7 0 1 +98257 4 10 94292 12 0 1 +98269 4 2 49485 3 0 1 +98297 4 3 60788 1 0 1 +98299 4 2 57555 1 0 1 +98317 4 6 49805 6 0 1 +98321 4 3 98309 0 0 1 +98323 4 3 97436 2 0 1 +98327 4 5 64582 3 0 1 +98347 4 2 49445 10 0 1 +98369 4 3 55675 7 0 1 +98377 4 5 81792 8 0 1 +98387 4 2 94623 8 0 1 +98389 4 2 59966 6 0 1 +98407 4 6 85397 7 0 1 +98411 4 2 52914 6 0 1 +98419 4 2 88714 7 0 1 +98429 4 2 56713 12 0 1 +98443 4 2 85043 8 0 1 +98453 4 2 75524 4 0 1 +98459 4 2 88983 8 0 1 +98467 4 3 60098 5 0 1 +98473 4 10 50191 6 0 1 +98479 4 3 96260 2 0 1 +98491 4 7 66517 6 0 1 +98507 4 2 87406 11 0 1 +98519 4 7 54357 7 0 1 +98533 4 2 87373 18 0 1 +98543 4 5 84185 15 0 1 +98561 4 3 82017 2 0 1 +98563 4 2 88061 2 0 1 +98573 4 2 97685 9 0 1 +98597 4 2 97828 18 0 1 +98621 4 7 98612 4 0 1 +98627 4 2 51821 0 0 1 +98639 4 7 88232 2 0 1 +98641 4 17 78207 20 0 1 +98663 4 5 77646 3 0 1 +98669 4 2 59692 12 0 1 +98689 4 7 91235 14 0 1 +98711 4 13 83300 6 0 1 +98713 4 5 88728 6 0 1 +98717 4 2 64223 6 0 1 +98729 4 3 85831 2 0 1 +98731 4 2 96422 2 0 1 +98737 4 5 59469 6 0 1 +98773 4 2 77188 6 0 1 +98779 4 2 59519 3 0 1 +98801 4 3 77245 4 0 1 +98807 4 5 96652 8 0 1 +98809 4 17 64705 32 0 1 +98837 4 2 64513 12 0 1 +98849 4 3 98837 0 0 1 +98867 4 2 89513 4 0 1 +98869 4 2 92236 6 0 1 +98873 4 3 86974 0 0 1 +98887 4 3 98876 12 0 1 +98893 4 2 91158 9 0 1 +98897 4 3 84197 6 0 1 +98899 4 2 78657 2 0 1 +98909 4 2 88337 3 0 1 +98911 4 12 57552 2 0 1 +98927 4 5 98923 3 0 1 +98929 4 11 95329 8 0 1 +98939 4 2 89466 4 0 1 +98947 4 3 57547 7 0 1 +98953 4 10 82272 0 0 1 +98963 4 2 54403 8 0 1 +98981 4 3 98977 4 0 1 +98993 4 3 83315 0 0 1 +98999 4 19 66741 2 0 1 +99013 4 6 53070 6 0 1 +99017 4 3 86521 6 0 1 +99023 4 5 83330 5 0 1 +99041 4 6 95398 0 0 1 +99053 4 2 69467 6 0 1 +99079 4 3 63619 2 0 1 +99083 4 2 89229 7 0 1 +99089 4 3 69977 8 0 1 +99103 4 3 99099 4 0 1 +99109 4 6 99105 6 0 1 +99119 4 11 55145 6 0 1 +99131 4 6 78401 4 0 1 +99133 4 2 94358 6 0 1 +99137 4 3 83228 26 0 1 +99139 4 2 51038 6 0 1 +99149 4 2 90254 4 0 1 +99173 4 2 62125 6 0 1 +99181 4 7 83135 12 0 1 +99191 4 11 65978 7 0 1 +99223 4 3 99219 4 0 1 +99233 4 3 94614 7 0 1 +99241 4 11 58571 22 0 1 +99251 4 10 60280 2 0 1 +99257 4 3 87776 0 0 1 +99259 4 2 99252 8 0 1 +99277 4 2 75149 9 0 1 +99289 4 26 50603 22 0 1 +99317 4 2 71690 6 0 1 +99347 4 2 66879 2 0 1 +99349 4 11 56004 3 0 1 +99367 4 3 87376 6 0 1 +99371 4 2 90073 3 0 1 +99377 4 3 59447 2 0 1 +99391 4 6 95466 3 0 1 +99397 4 2 60075 10 0 1 +99401 4 3 99389 0 0 1 +99409 4 11 55067 2 0 1 +99431 4 13 96774 3 0 1 +99439 4 3 91222 3 0 1 +99469 4 2 56284 8 0 1 +99487 4 3 81536 3 0 1 +99497 4 3 60273 0 0 1 +99523 4 5 59386 0 0 1 +99527 4 5 50890 6 0 1 +99529 4 7 72102 0 0 1 +99551 4 7 92660 3 0 1 +99559 4 3 97156 6 0 1 +99563 4 2 54616 7 0 1 +99571 4 2 87056 7 0 1 +99577 4 5 63318 15 0 1 +99581 4 2 76108 4 0 1 +99607 4 3 52843 2 0 1 +99611 4 2 66058 0 0 1 +99623 4 5 88069 8 0 1 +99643 4 3 72041 3 0 1 +99661 4 2 68473 6 0 1 +99667 4 2 50357 8 0 1 +99679 4 6 58807 2 0 1 +99689 4 3 99678 12 0 1 +99707 4 2 81678 4 0 1 +99709 4 10 59397 5 0 1 +99713 4 3 82670 11 0 1 +99719 4 7 52361 6 0 1 +99721 4 11 67218 24 0 1 +99733 4 2 94954 6 0 1 +99761 4 3 75746 1 0 1 +99767 4 5 76539 5 0 1 +99787 4 2 55326 2 0 1 +99793 4 5 86930 10 0 1 +99809 4 3 74403 4 0 1 +99817 4 5 91887 11 0 1 +99823 4 21 63356 2 0 1 +99829 4 2 58958 6 0 1 +99833 4 3 76290 4 0 1 +99839 4 11 83927 3 0 1 +99859 4 2 57571 7 0 1 +99871 4 3 69176 2 0 1 +99877 4 2 80944 12 0 1 +99881 4 6 94555 0 0 1 +99901 4 2 76750 12 0 1 +99907 4 2 81363 7 0 1 +99923 4 2 88689 2 0 1 +99929 4 3 68784 1 0 1 +99961 4 31 95999 30 0 1 +99971 4 2 80658 0 0 1 +99989 4 2 65733 0 0 1 +99991 4 6 63566 3 0 1 +100003 4 2 98003 19 0 1 +100019 4 2 94727 11 0 1 +100043 4 2 80144 2 0 1 +100049 4 6 60696 7 0 1 +100057 4 10 50599 24 0 1 +100069 4 10 65117 2 0 1 +100103 4 5 84148 8 0 1 +100109 4 2 87453 12 0 1 +100129 4 11 85213 27 0 1 +100151 4 7 100142 4 0 1 +100153 4 5 85065 10 0 1 +100169 4 3 100157 0 0 1 +100183 4 3 61963 8 0 1 +100189 4 2 100182 8 0 1 +100193 4 3 54015 0 0 1 +100207 4 3 79012 5 0 1 +100213 4 2 52584 9 0 1 +100237 4 5 61791 7 0 1 +100267 4 5 100259 6 0 1 +100271 4 13 57533 7 0 1 +100279 4 3 51225 6 0 1 +100291 4 3 76569 2 0 1 +100297 4 13 80672 4 0 1 +100313 4 3 54952 0 0 1 +100333 4 2 82356 12 0 1 +100343 4 5 86579 9 0 1 +100357 4 2 54408 6 0 1 +100361 4 3 62889 4 0 1 +100363 4 2 97259 8 0 1 +100379 4 2 60895 2 0 1 +100391 4 7 70589 2 0 1 +100393 4 5 63844 16 0 1 +100403 4 2 80213 14 0 1 +100411 4 2 53510 1 0 1 +100417 4 5 78734 6 0 1 +100447 4 3 74631 2 0 1 +100459 4 2 76639 8 0 1 +100469 4 2 57663 3 0 1 +100483 4 3 88247 3 0 1 +100493 4 2 92806 0 0 1 +100501 4 2 50822 6 0 1 +100511 4 11 50675 3 0 1 +100517 4 2 55941 13 0 1 +100519 4 6 82185 3 0 1 +100523 4 2 62593 13 0 1 +100537 4 7 86031 8 0 1 +100547 4 2 56101 2 0 1 +100549 4 2 50629 6 0 1 +100559 4 7 79981 6 0 1 +100591 4 6 94786 4 0 1 +100609 4 7 87081 20 0 1 +100613 4 2 81955 6 0 1 +100621 4 18 96659 9 0 1 +100649 4 3 78430 3 0 1 +100669 4 6 55740 12 0 1 +100673 4 3 65991 1 0 1 +100693 4 2 55534 10 0 1 +100699 4 2 58357 8 0 1 +100703 4 5 81421 5 0 1 +100733 4 2 60875 4 0 1 +100741 4 6 52359 10 0 1 +100747 4 2 63140 10 0 1 +100769 4 3 58892 1 0 1 +100787 4 2 72686 4 0 1 +100799 4 17 67707 4 0 1 +100801 4 11 56231 20 0 1 +100811 4 2 68525 4 0 1 +100823 4 5 71888 6 0 1 +100829 4 2 86843 12 0 1 +100847 4 5 77189 7 0 1 +100853 4 3 66999 12 0 1 +100907 4 2 98156 7 0 1 +100913 4 3 95347 0 0 1 +100927 4 3 53940 5 0 1 +100931 4 2 77774 1 0 1 +100937 4 3 95053 0 0 1 +100943 4 5 74933 7 0 1 +100957 4 2 54986 9 0 1 +100981 4 7 91700 9 0 1 +100987 4 2 60984 2 0 1 +100999 4 3 84306 3 0 1 +101009 4 3 74909 1 0 1 +101021 4 2 96296 6 0 1 +101027 4 2 53688 2 0 1 +101051 4 2 96739 9 0 1 +101063 4 7 101054 4 0 1 +101081 4 6 79352 9 0 1 +101089 4 31 63437 17 0 1 +101107 4 3 83486 5 0 1 +101111 4 17 61375 7 0 1 +101113 4 5 90770 6 0 1 +101117 4 2 91989 7 0 1 +101119 4 3 69572 2 0 1 +101141 4 3 92023 3 0 1 +101149 4 2 50930 11 0 1 +101159 4 7 76253 3 0 1 +101161 4 13 92503 14 0 1 +101173 4 2 86538 6 0 1 +101183 4 5 99691 3 0 1 +101197 4 2 54187 3 0 1 +101203 4 7 59682 16 0 1 +101207 4 5 88094 5 0 1 +101209 4 7 65889 17 0 1 +101221 4 6 61316 12 0 1 +101267 4 2 74117 2 0 1 +101273 4 3 72475 6 0 1 +101279 4 17 53259 4 0 1 +101281 4 14 82421 16 0 1 +101287 4 3 101276 12 0 1 +101293 4 2 92263 6 0 1 +101323 4 2 65516 2 0 1 +101333 4 2 97244 7 0 1 +101341 4 2 61994 10 0 1 +101347 4 2 71845 8 0 1 +101359 4 3 97886 3 0 1 +101363 4 2 74202 2 0 1 +101377 4 5 70545 6 0 1 +101383 4 3 61665 5 0 1 +101399 4 7 101390 4 0 1 +101411 4 2 69358 8 0 1 +101419 4 2 96674 2 0 1 +101429 4 2 101422 8 0 1 +101449 4 11 85031 18 0 1 +101467 4 2 60770 8 0 1 +101477 4 2 86313 3 0 1 +101483 4 2 96436 7 0 1 +101489 4 3 101477 0 0 1 +101501 4 2 58912 2 0 1 +101503 4 5 84290 9 0 1 +101513 4 3 68932 1 0 1 +101527 4 5 92918 10 0 1 +101531 4 2 88370 6 0 1 +101533 4 5 83362 20 0 1 +101537 4 3 74293 7 0 1 +101561 4 3 99936 2 0 1 +101573 4 2 84763 3 0 1 +101581 4 2 65628 6 0 1 +101599 4 11 77791 2 0 1 +101603 4 2 92932 4 0 1 +101611 4 2 64823 6 0 1 +101627 4 2 90570 8 0 1 +101641 4 13 97121 16 0 1 +101653 4 5 101202 6 0 1 +101663 4 5 98655 4 0 1 +101681 4 6 89200 4 0 1 +101693 4 2 93804 2 0 1 +101701 4 2 77077 3 0 1 +101719 4 3 90529 2 0 1 +101723 4 2 70235 10 0 1 +101737 4 7 59738 12 0 1 +101741 4 2 78441 1 0 1 +101747 4 2 92827 1 0 1 +101749 4 2 57004 10 0 1 +101771 4 2 76676 12 0 1 +101789 4 2 84943 6 0 1 +101797 4 2 88983 6 0 1 +101807 4 5 97809 4 0 1 +101833 4 5 93760 12 0 1 +101837 4 5 64541 6 0 1 +101839 4 15 91279 2 0 1 +101863 4 3 65805 6 0 1 +101869 4 6 95574 2 0 1 +101873 4 3 86526 4 0 1 +101879 4 7 78537 5 0 1 +101891 4 2 54719 6 0 1 +101917 4 5 101906 14 0 1 +101921 4 11 58319 4 0 1 +101929 4 17 54509 22 0 1 +101939 4 2 88833 4 0 1 +101957 4 2 80402 7 0 1 +101963 4 2 76000 7 0 1 +101977 4 5 88974 16 0 1 +101987 4 2 99534 7 0 1 +101999 4 7 75721 3 0 1 +102001 4 31 83535 32 0 1 +102013 4 5 87162 6 0 1 +102019 4 2 97457 8 0 1 +102023 4 5 52974 3 0 1 +102031 4 3 66420 3 0 1 +102043 4 5 86820 5 0 1 +102059 4 2 100399 2 0 1 +102061 4 2 74291 6 0 1 +102071 4 7 59223 2 0 1 +102077 4 2 102070 8 0 1 +102079 4 3 59246 3 0 1 +102101 4 2 93738 1 0 1 +102103 4 5 88550 34 0 1 +102107 4 2 52675 2 0 1 +102121 4 7 96083 16 0 1 +102139 4 3 101687 3 0 1 +102149 4 2 54873 4 0 1 +102161 4 6 67310 0 0 1 +102181 4 6 89499 11 0 1 +102191 4 11 79839 6 0 1 +102197 4 2 85632 3 0 1 +102199 4 11 101416 0 0 1 +102203 4 2 97058 0 0 1 +102217 4 5 72290 10 0 1 +102229 4 2 62288 12 0 1 +102233 4 3 61249 7 0 1 +102241 4 11 98918 8 0 1 +102251 4 2 59922 8 0 1 +102253 4 2 101538 9 0 1 +102259 4 3 100725 0 0 1 +102293 4 2 57489 1 0 1 +102299 4 2 63103 3 0 1 +102301 4 7 77648 9 0 1 +102317 4 2 81415 3 0 1 +102329 4 3 83518 2 0 1 +102337 4 5 52333 6 0 1 +102359 4 11 92323 3 0 1 +102367 4 3 66798 3 0 1 +102397 4 5 69176 10 0 1 +102407 4 5 85977 5 0 1 +102409 4 7 55943 14 0 1 +102433 4 5 61943 18 0 1 +102437 4 2 57934 2 0 1 +102451 4 3 85850 2 0 1 +102461 4 2 57706 12 0 1 +102481 4 13 57206 14 0 1 +102497 4 3 64317 7 0 1 +102499 4 3 56652 0 0 1 +102503 4 5 54038 9 0 1 +102523 4 2 65832 8 0 1 +102533 4 2 69310 6 0 1 +102539 4 2 102532 8 0 1 +102547 4 2 92126 8 0 1 +102551 4 13 58879 5 0 1 +102559 4 3 81057 6 0 1 +102563 4 2 93025 10 0 1 +102587 4 2 87605 8 0 1 +102593 4 3 55795 4 0 1 +102607 4 5 70761 10 0 1 +102611 4 2 54237 4 0 1 +102643 4 7 59656 12 0 1 +102647 4 5 102643 3 0 1 +102653 4 2 53146 4 0 1 +102667 4 3 100718 11 0 1 +102673 4 5 102662 14 0 1 +102677 4 3 87685 4 0 1 +102679 4 3 65776 13 0 1 +102701 4 2 63466 12 0 1 +102761 4 6 79754 7 0 1 +102763 4 2 102756 8 0 1 +102769 4 11 57972 23 0 1 +102793 4 5 73589 6 0 1 +102797 4 2 66448 9 0 1 +102811 4 2 75581 8 0 1 +102829 4 2 72698 14 0 1 +102841 4 13 66555 14 0 1 +102859 4 3 86290 1 0 1 +102871 4 12 91554 3 0 1 +102877 4 2 89490 6 0 1 +102881 4 3 86668 3 0 1 +102911 4 7 84244 10 0 1 +102913 4 5 55630 10 0 1 +102929 4 6 65058 0 0 1 +102931 4 3 87941 2 0 1 +102953 4 3 52055 0 0 1 +102967 4 3 102956 12 0 1 +102983 4 5 100007 3 0 1 +103001 4 7 92108 12 0 1 +103007 4 5 63251 10 0 1 +103043 4 2 102487 2 0 1 +103049 4 3 97745 2 0 1 +103067 4 2 86256 2 0 1 +103069 4 2 79836 12 0 1 +103079 4 7 60715 2 0 1 +103087 4 3 85764 11 0 1 +103091 4 6 72821 5 0 1 +103093 4 2 77752 6 0 1 +103099 4 10 83855 0 0 1 +103123 4 3 100945 3 0 1 +103141 4 6 103133 12 0 1 +103171 4 14 95700 7 0 1 +103177 4 10 55642 0 0 1 +103183 4 3 84641 3 0 1 +103217 4 3 69497 9 0 1 +103231 4 3 93689 3 0 1 +103237 4 5 55872 1 0 1 +103289 4 3 103277 0 0 1 +103291 4 2 96681 2 0 1 +103307 4 2 55036 4 0 1 +103319 4 13 66378 6 0 1 +103333 4 2 72051 3 0 1 +103349 4 3 89966 3 0 1 +103357 4 6 74250 8 0 1 +103387 4 5 75077 5 0 1 +103391 4 7 99077 11 0 1 +103393 4 5 65275 6 0 1 +103399 4 3 103395 4 0 1 +103409 4 3 79050 2 0 1 +103421 4 10 65431 8 0 1 +103423 4 5 84181 16 0 1 +103451 4 2 65555 3 0 1 +103457 4 3 95339 12 0 1 +103471 4 3 99962 6 0 1 +103483 4 2 61867 8 0 1 +103511 4 7 102146 2 0 1 +103529 4 3 103517 0 0 1 +103549 4 2 61041 3 0 1 +103553 4 3 58725 7 0 1 +103561 4 21 101657 8 0 1 +103567 4 7 72790 10 0 1 +103573 4 5 60321 1 0 1 +103577 4 3 92578 0 0 1 +103583 4 5 86987 2 0 1 +103591 4 3 83774 3 0 1 +103613 4 2 88297 1 0 1 +103619 4 2 53087 2 0 1 +103643 4 2 88180 8 0 1 +103651 4 2 82461 8 0 1 +103657 4 5 101984 11 0 1 +103669 4 6 76248 2 0 1 +103681 4 11 79708 23 0 1 +103687 4 3 55186 6 0 1 +103699 4 2 95277 8 0 1 +103703 4 5 78562 8 0 1 +103723 4 3 83164 5 0 1 +103769 4 3 103757 0 0 1 +103787 4 2 97037 2 0 1 +103801 4 14 86695 12 0 1 +103811 4 2 73655 7 0 1 +103813 4 6 79788 16 0 1 +103837 4 5 92499 3 0 1 +103841 4 3 103829 0 0 1 +103843 4 2 93165 11 0 1 +103867 4 2 79812 8 0 1 +103889 4 3 79879 2 0 1 +103903 4 3 52905 2 0 1 +103913 4 3 87325 1 0 1 +103919 4 7 103910 4 0 1 +103951 4 6 77651 3 0 1 +103963 4 2 83403 7 0 1 +103967 4 5 90166 4 0 1 +103969 4 7 75541 0 0 1 +103979 4 2 69800 7 0 1 +103981 4 6 61321 7 0 1 +103991 4 19 73271 2 0 1 +103993 4 5 103982 14 0 1 +103997 4 2 75815 6 0 1 +104003 4 2 57229 8 0 1 +104009 4 3 103997 0 0 1 +104021 4 2 64314 16 0 1 +104033 4 3 70317 0 0 1 +104047 4 5 82234 3 0 1 +104053 4 6 100959 0 0 1 +104059 4 2 72611 8 0 1 +104087 4 5 87326 1 0 1 +104089 4 7 65453 0 0 1 +104107 4 5 100195 2 0 1 +104113 4 5 68904 11 0 1 +104119 4 6 101251 2 0 1 +104123 4 2 78232 2 0 1 +104147 4 2 67667 3 0 1 +104149 4 6 98807 7 0 1 +104161 4 19 86605 14 0 1 +104173 4 2 86281 6 0 1 +104179 4 2 69168 2 0 1 +104183 4 5 53198 14 0 1 +104207 4 5 104203 3 0 1 +104231 4 7 64988 6 0 1 +104233 4 7 68462 10 0 1 +104239 4 6 69062 10 0 1 +104243 4 2 70322 2 0 1 +104281 4 26 99646 14 0 1 +104287 4 5 63999 5 0 1 +104297 4 3 56603 7 0 1 +104309 4 2 75154 6 0 1 +104311 4 6 69756 5 0 1 +104323 4 5 53402 5 0 1 +104327 4 5 104323 3 0 1 +104347 4 11 100898 2 0 1 +104369 4 3 96656 2 0 1 +104381 4 2 69007 0 0 1 +104383 4 5 104379 3 0 1 +104393 4 3 59113 11 0 1 +104399 4 7 98018 2 0 1 +104417 4 6 98691 7 0 1 +104459 4 2 101660 7 0 1 +104471 4 11 71148 5 0 1 +104473 4 5 80426 17 0 1 +104479 4 7 68011 0 0 1 +104491 4 3 85947 6 0 1 +104513 4 3 62342 4 0 1 +104527 4 3 60643 3 0 1 +104537 4 3 76572 9 0 1 +104543 4 5 77726 14 0 1 +104549 4 2 60922 1 0 1 +104551 4 3 70500 2 0 1 +104561 4 6 61988 0 0 1 +104579 4 2 85884 2 0 1 +104593 4 5 92312 12 0 1 +104597 4 2 78156 20 0 1 +104623 4 7 75045 5 0 1 +104639 4 13 83282 3 0 1 +104651 4 6 55441 0 0 1 +104659 4 2 102978 8 0 1 +104677 4 2 91683 6 0 1 +104681 4 6 91337 0 0 1 +104683 4 2 74335 11 0 1 +104693 4 3 90701 15 0 1 +104701 4 2 93197 10 0 1 +104707 4 2 85720 8 0 1 +104711 4 43 92145 3 0 1 +104717 4 2 98245 6 0 1 +104723 4 2 99515 2 0 1 +104729 4 12 86801 0 0 1 +104743 4 3 84761 3 0 1 +104759 4 7 101184 2 0 1 +104761 4 7 96846 0 0 1 +104773 4 2 101520 12 0 1 +104779 4 3 54828 5 0 1 +104789 4 2 85032 1 0 1 +104801 4 13 104789 5 0 1 +104803 4 3 57748 5 0 1 +104827 4 3 81090 5 0 1 +104831 4 22 96444 4 0 1 +104849 4 3 104391 7 0 1 +104851 4 13 61997 2 0 1 +104869 4 2 81114 12 0 1 +104879 4 11 73074 5 0 1 +104891 4 2 104884 8 0 1 +104911 4 6 62542 4 0 1 +104917 4 2 65257 12 0 1 +104933 4 2 90338 6 0 1 +104947 4 5 87971 7 0 1 +104953 4 5 81890 18 0 1 +104959 4 3 72421 2 0 1 +104971 4 2 101949 2 0 1 +104987 4 2 55614 7 0 1 +104999 4 11 79633 7 0 1 +105019 4 2 94135 1 0 1 +105023 4 5 84131 5 0 1 +105031 4 3 74231 3 0 1 +105037 4 5 90097 10 0 1 +105071 4 7 69564 7 0 1 +105097 4 7 55342 13 0 1 +105107 4 2 98222 8 0 1 +105137 4 3 103361 7 0 1 +105143 4 5 95356 8 0 1 +105167 4 5 105155 11 0 1 +105173 4 2 77550 3 0 1 +105199 4 6 103097 3 0 1 +105211 4 2 55049 8 0 1 +105227 4 5 57345 5 0 1 +105229 4 2 105222 8 0 1 +105239 4 14 93426 2 0 1 +105251 4 2 82405 2 0 1 +105253 4 6 54633 6 0 1 +105263 4 5 105259 3 0 1 +105269 4 2 60321 9 0 1 +105277 4 6 86590 10 0 1 +105319 4 3 58606 3 0 1 +105323 4 2 95205 8 0 1 +105331 4 2 96671 13 0 1 +105337 4 10 79802 6 0 1 +105341 4 2 56459 4 0 1 +105359 4 7 78705 8 0 1 +105361 4 17 91628 28 0 1 +105367 4 3 101826 3 0 1 +105373 4 2 84771 9 0 1 +105379 4 2 70643 7 0 1 +105389 4 2 102396 6 0 1 +105397 4 2 80564 7 0 1 +105401 4 3 58077 4 0 1 +105407 4 5 84794 9 0 1 +105437 4 2 64232 3 0 1 +105449 4 6 54933 4 0 1 +105467 4 2 104342 4 0 1 +105491 4 2 82262 7 0 1 +105499 4 2 78421 3 0 1 +105503 4 10 57033 8 0 1 +105509 4 2 86419 3 0 1 +105517 4 2 60399 9 0 1 +105527 4 5 74025 8 0 1 +105529 4 11 75095 22 0 1 +105533 4 2 74680 8 0 1 +105541 4 2 54907 6 0 1 +105557 4 3 81753 5 0 1 +105563 4 2 73255 14 0 1 +105601 4 17 61332 20 0 1 +105607 4 3 80280 2 0 1 +105613 4 2 88206 10 0 1 +105619 4 3 70070 7 0 1 +105649 4 7 104477 0 0 1 +105653 4 2 101280 12 0 1 +105667 4 3 84802 2 0 1 +105673 4 5 94445 6 0 1 +105683 4 2 54090 13 0 1 +105691 4 2 103302 2 0 1 +105701 4 3 70314 3 0 1 +105727 4 6 56762 3 0 1 +105733 4 6 77423 0 0 1 +105751 4 7 78035 0 0 1 +105761 4 3 89313 7 0 1 +105767 4 5 68554 3 0 1 +105769 4 7 105750 22 0 1 +105817 4 5 80975 23 0 1 +105829 4 2 105822 8 0 1 +105863 4 5 83676 2 0 1 +105871 4 17 68994 3 0 1 +105883 4 2 58528 8 0 1 +105899 4 2 53380 2 0 1 +105907 4 5 102525 0 0 1 +105913 4 10 64189 6 0 1 +105929 4 3 105917 0 0 1 +105943 4 3 96487 5 0 1 +105953 4 3 67076 0 0 1 +105967 4 3 74907 6 0 1 +105971 4 2 105964 8 0 1 +105977 4 5 64467 4 0 1 +105983 4 5 98453 6 0 1 +105997 4 5 84705 6 0 1 +106013 4 2 54278 3 0 1 +106019 4 2 85099 8 0 1 +106031 4 19 94445 3 0 1 +106033 4 5 101451 11 0 1 +106087 4 3 106083 4 0 1 +106103 4 5 106099 3 0 1 +106109 4 2 84568 1 0 1 +106121 4 3 55610 2 0 1 +106123 4 2 94890 7 0 1 +106129 4 23 64933 22 0 1 +106163 4 2 86777 7 0 1 +106181 4 2 92499 4 0 1 +106187 4 2 91731 14 0 1 +106189 4 6 62156 7 0 1 +106207 4 6 104422 4 0 1 +106213 4 2 70417 6 0 1 +106217 4 3 65895 0 0 1 +106219 4 7 106215 4 0 1 +106243 4 3 96651 3 0 1 +106261 4 2 97618 7 0 1 +106273 4 5 62225 16 0 1 +106277 4 2 53503 3 0 1 +106279 4 3 62704 2 0 1 +106291 4 2 82469 6 0 1 +106297 4 5 96101 15 0 1 +106303 4 3 59249 6 0 1 +106307 4 2 73928 2 0 1 +106319 4 11 91359 6 0 1 +106321 4 13 95182 15 0 1 +106331 4 7 78048 2 0 1 +106349 4 2 85621 1 0 1 +106357 4 2 69834 6 0 1 +106363 4 2 66299 10 0 1 +106367 4 5 57873 6 0 1 +106373 4 5 89495 7 0 1 +106391 4 23 90435 4 0 1 +106397 4 2 104671 9 0 1 +106411 4 2 105281 8 0 1 +106417 4 7 82086 17 0 1 +106427 4 2 95480 2 0 1 +106433 4 3 102699 4 0 1 +106441 4 7 75881 17 0 1 +106451 4 2 95914 7 0 1 +106453 4 6 78899 8 0 1 +106487 4 5 106483 3 0 1 +106501 4 2 106494 8 0 1 +106531 4 3 73172 6 0 1 +106537 4 5 80739 18 0 1 +106541 4 3 86225 3 0 1 +106543 4 5 72749 2 0 1 +106591 4 3 90293 6 0 1 +106619 4 2 68024 7 0 1 +106621 4 10 100239 19 0 1 +106627 4 2 71429 14 0 1 +106637 4 2 99105 1 0 1 +106649 4 3 106637 0 0 1 +106657 4 5 60799 6 0 1 +106661 4 2 54836 6 0 1 +106663 4 5 106659 3 0 1 +106669 4 19 104118 13 0 1 +106681 4 23 79142 21 0 1 +106693 4 2 100556 1 0 1 +106699 4 3 82384 7 0 1 +106703 4 7 68234 3 0 1 +106721 4 3 65440 4 0 1 +106727 4 10 81877 3 0 1 +106739 4 2 91828 1 0 1 +106747 4 2 69594 10 0 1 +106751 4 13 86007 6 0 1 +106753 4 5 90199 12 0 1 +106759 4 6 105192 8 0 1 +106781 4 2 104271 4 0 1 +106783 4 5 99744 12 0 1 +106787 4 2 76629 0 0 1 +106801 4 11 75438 14 0 1 +106823 4 5 106819 3 0 1 +106853 4 2 53792 1 0 1 +106859 4 2 58647 7 0 1 +106861 4 7 92657 4 0 1 +106867 4 3 104933 2 0 1 +106871 4 7 71803 2 0 1 +106877 4 2 84310 1 0 1 +106903 4 5 106899 3 0 1 +106907 4 2 81631 11 0 1 +106921 4 14 79667 10 0 1 +106937 4 3 71137 6 0 1 +106949 4 2 89521 1 0 1 +106957 4 5 100199 20 0 1 +106961 4 3 61054 7 0 1 +106963 4 3 57105 5 0 1 +106979 4 2 85298 6 0 1 +106993 4 5 68696 18 0 1 +107021 4 7 62999 9 0 1 +107033 4 3 87292 9 0 1 +107053 4 5 88582 19 0 1 +107057 4 3 57579 0 0 1 +107069 4 2 100051 1 0 1 +107071 4 3 87186 3 0 1 +107077 4 2 107070 8 0 1 +107089 4 7 96108 0 0 1 +107099 4 2 87849 9 0 1 +107101 4 6 107093 12 0 1 +107119 4 3 97885 6 0 1 +107123 4 2 77610 4 0 1 +107137 4 10 59087 15 0 1 +107171 4 10 101625 2 0 1 +107183 4 5 65923 4 0 1 +107197 4 2 87303 15 0 1 +107201 4 7 78916 7 0 1 +107209 4 13 73503 14 0 1 +107227 4 20 62810 5 0 1 +107243 4 2 66189 13 0 1 +107251 4 3 79808 2 0 1 +107269 4 6 84140 7 0 1 +107273 4 3 86004 1 0 1 +107279 4 7 69237 3 0 1 +107309 4 2 80777 6 0 1 +107323 4 13 77205 2 0 1 +107339 4 6 54304 4 0 1 +107347 4 2 68776 8 0 1 +107351 4 19 87143 5 0 1 +107357 4 2 89342 3 0 1 +107377 4 10 97492 8 0 1 +107441 4 3 107429 0 0 1 +107449 4 7 87184 0 0 1 +107453 4 2 100577 9 0 1 +107467 4 2 106664 2 0 1 +107473 4 5 93041 15 0 1 +107507 4 2 101260 8 0 1 +107509 4 6 107505 6 0 1 +107563 4 11 91516 10 0 1 +107581 4 2 57281 7 0 1 +107599 4 3 76989 3 0 1 +107603 4 2 94082 11 0 1 +107609 4 3 73896 4 0 1 +107621 4 2 65807 15 0 1 +107641 4 11 91733 12 0 1 +107647 4 5 92136 5 0 1 +107671 4 6 90840 10 0 1 +107687 4 5 62234 7 0 1 +107693 4 2 60379 2 0 1 +107699 4 2 88066 8 0 1 +107713 4 10 100860 20 0 1 +107717 4 2 95667 6 0 1 +107719 4 3 96804 2 0 1 +107741 4 3 107737 4 0 1 +107747 4 2 107740 8 0 1 +107761 4 14 107027 0 0 1 +107773 4 2 101928 6 0 1 +107777 4 3 95854 7 0 1 +107791 4 3 72374 3 0 1 +107827 4 5 60617 3 0 1 +107837 4 2 63755 6 0 1 +107839 4 15 77835 5 0 1 +107843 4 2 99620 0 0 1 +107857 4 5 89097 12 0 1 +107867 4 2 60541 18 0 1 +107873 4 3 67841 17 0 1 +107881 4 23 105401 14 0 1 +107897 4 3 54316 2 0 1 +107903 4 5 70956 9 0 1 +107923 4 2 106785 8 0 1 +107927 4 5 107923 3 0 1 +107941 4 6 64633 10 0 1 +107951 4 7 103981 3 0 1 +107971 4 3 98229 6 0 1 +107981 4 2 96717 4 0 1 +107999 4 13 59088 6 0 1 +108007 4 11 86064 2 0 1 +108011 4 7 55179 1 0 1 +108013 4 6 75473 8 0 1 +108023 4 5 77798 7 0 1 +108037 4 2 80139 22 0 1 +108041 4 6 103451 10 0 1 +108061 4 2 70777 10 0 1 +108079 4 3 108075 4 0 1 +108089 4 6 75930 2 0 1 +108107 4 2 105736 12 0 1 +108109 4 2 62811 6 0 1 +108127 4 6 87299 7 0 1 +108131 4 6 64592 0 0 1 +108139 4 2 77447 6 0 1 +108161 4 3 108149 0 0 1 +108179 4 2 99577 8 0 1 +108187 4 5 71686 8 0 1 +108191 4 13 105936 3 0 1 +108193 4 13 69944 6 0 1 +108203 4 2 64580 8 0 1 +108211 4 3 58404 5 0 1 +108217 4 5 71451 12 0 1 +108223 4 3 72368 3 0 1 +108233 4 3 58932 1 0 1 +108247 4 3 102791 2 0 1 +108263 4 5 92442 8 0 1 +108271 4 3 65980 6 0 1 +108287 4 5 87705 9 0 1 +108289 4 7 75051 17 0 1 +108293 4 2 107723 4 0 1 +108301 4 6 103015 7 0 1 +108343 4 3 99766 6 0 1 +108347 4 2 100204 0 0 1 +108359 4 11 106815 7 0 1 +108377 4 3 104358 7 0 1 +108379 4 2 65781 2 0 1 +108401 4 3 73509 4 0 1 +108413 4 2 61123 2 0 1 +108421 4 17 78239 1 0 1 +108439 4 3 83691 6 0 1 +108457 4 5 66705 16 0 1 +108461 4 2 59975 4 0 1 +108463 4 5 108459 3 0 1 +108497 4 3 81126 12 0 1 +108499 4 14 92342 2 0 1 +108503 4 5 63561 2 0 1 +108517 4 5 89622 6 0 1 +108529 4 23 80774 14 0 1 +108533 4 2 90567 3 0 1 +108541 4 2 64993 10 0 1 +108553 4 5 88115 25 0 1 +108557 4 2 102067 6 0 1 +108571 4 3 92412 3 0 1 +108587 4 2 81296 0 0 1 +108631 4 6 92907 3 0 1 +108637 4 15 59747 15 0 1 +108643 4 5 108635 6 0 1 +108649 4 11 87737 22 0 1 +108677 4 2 82009 12 0 1 +108707 4 2 80616 0 0 1 +108709 4 6 81347 8 0 1 +108727 4 3 108723 4 0 1 +108739 4 2 63931 8 0 1 +108751 4 3 79316 3 0 1 +108761 4 3 108749 0 0 1 +108769 4 7 73877 16 0 1 +108791 4 7 58472 2 0 1 +108793 4 5 70431 8 0 1 +108799 4 6 94170 5 0 1 +108803 4 2 57904 8 0 1 +108821 4 2 68836 0 0 1 +108827 4 2 97718 10 0 1 +108863 4 5 57378 3 0 1 +108869 4 2 106422 3 0 1 +108877 4 2 103058 3 0 1 +108881 4 3 70048 2 0 1 +108883 4 2 92194 2 0 1 +108887 4 5 68489 5 0 1 +108893 4 3 95872 7 0 1 +108907 4 12 62872 0 0 1 +108917 4 2 81187 28 0 1 +108923 4 2 57198 7 0 1 +108929 4 3 70698 2 0 1 +108943 4 3 59113 5 0 1 +108947 4 2 77901 2 0 1 +108949 4 2 80916 10 0 1 +108959 4 11 71732 7 0 1 +108961 4 7 90013 14 0 1 +108967 4 3 80825 3 0 1 +108971 4 2 55462 4 0 1 +108991 4 6 70144 2 0 1 +109001 4 3 108989 0 0 1 +109013 4 2 102916 7 0 1 +109037 4 2 105116 1 0 1 +109049 4 3 109037 0 0 1 +109063 4 6 67465 3 0 1 +109073 4 3 83169 1 0 1 +109097 4 3 93654 6 0 1 +109103 4 5 85353 7 0 1 +109111 4 3 55735 6 0 1 +109121 4 3 109109 0 0 1 +109133 4 2 59368 9 0 1 +109139 4 2 61426 8 0 1 +109141 4 2 79949 12 0 1 +109147 4 3 100589 2 0 1 +109159 4 6 98795 4 0 1 +109169 4 3 100843 8 0 1 +109171 4 2 83228 3 0 1 +109199 4 19 95952 5 0 1 +109201 4 17 55710 38 0 1 +109211 4 6 61645 4 0 1 +109229 4 2 83105 1 0 1 +109253 4 3 68506 23 0 1 +109267 4 2 97367 8 0 1 +109279 4 11 58405 3 0 1 +109297 4 5 99462 17 0 1 +109303 4 3 95106 8 0 1 +109313 4 3 102362 6 0 1 +109321 4 19 67002 20 0 1 +109331 4 2 81855 4 0 1 +109357 4 11 61625 3 0 1 +109363 4 3 108266 0 0 1 +109367 4 5 83980 3 0 1 +109379 4 2 83806 5 0 1 +109387 4 2 62657 6 0 1 +109391 4 7 109382 4 0 1 +109397 4 2 74657 17 0 1 +109423 4 3 105318 14 0 1 +109433 4 3 90967 9 0 1 +109441 4 14 57513 8 0 1 +109451 4 2 72099 2 0 1 +109453 4 2 75295 6 0 1 +109469 4 2 58496 3 0 1 +109471 4 3 95240 2 0 1 +109481 4 3 97234 2 0 1 +109507 4 2 64343 2 0 1 +109517 4 2 76379 0 0 1 +109519 4 3 99769 3 0 1 +109537 4 5 109526 14 0 1 +109541 4 2 56063 9 0 1 +109547 4 2 67604 7 0 1 +109567 4 5 108285 2 0 1 +109579 4 2 73494 8 0 1 +109583 4 5 90581 2 0 1 +109589 4 2 105548 0 0 1 +109597 4 5 61160 7 0 1 +109609 4 14 76940 16 0 1 +109619 4 2 76843 7 0 1 +109621 4 10 74602 7 0 1 +109639 4 3 109635 4 0 1 +109661 4 3 109657 4 0 1 +109663 4 11 103620 5 0 1 +109673 4 3 72803 0 0 1 +109717 4 5 56797 10 0 1 +109721 4 3 90989 7 0 1 +109741 4 2 98434 6 0 1 +109751 4 11 108128 6 0 1 +109789 4 10 55492 12 0 1 +109793 4 3 79253 0 0 1 +109807 4 5 109803 3 0 1 +109819 4 3 89809 3 0 1 +109829 4 2 105285 3 0 1 +109831 4 3 103096 3 0 1 +109841 4 3 81116 4 0 1 +109843 4 2 77866 7 0 1 +109847 4 5 65590 14 0 1 +109849 4 7 91741 24 0 1 +109859 4 2 97735 3 0 1 +109873 4 15 56143 0 0 1 +109883 4 2 105350 8 0 1 +109891 4 2 83307 6 0 1 +109897 4 10 79199 12 0 1 +109903 4 3 81212 2 0 1 +109913 4 3 103200 2 0 1 +109919 4 17 109911 3 0 1 +109937 4 3 96530 5 0 1 +109943 4 5 109939 3 0 1 +109961 4 3 109949 0 0 1 +109987 4 3 100525 3 0 1 diff --git a/external/flint-2.4.3/qadic/Makefile b/external/flint-2.4.3/qadic/Makefile new file mode 100644 index 0000000..6969798 --- /dev/null +++ b/external/flint-2.4.3/qadic/Makefile @@ -0,0 +1,54 @@ +SOURCES = $(wildcard *.c) + +OBJS = $(patsubst %.c, $(BUILD_DIR)/$(MOD_DIR)_%.o, $(SOURCES)) + +LOBJS = $(patsubst %.c, $(BUILD_DIR)/%.lo, $(SOURCES)) +MOD_LOBJ = $(BUILD_DIR)/../$(MOD_DIR).lo + +TEST_SOURCES = $(wildcard test/*.c) + +PROF_SOURCES = $(wildcard profile/*.c) + +TUNE_SOURCES = $(wildcard tune/*.c) + +TESTS = $(patsubst %.c, $(BUILD_DIR)/%, $(TEST_SOURCES)) + +TESTS_RUN = $(patsubst %, %_RUN, $(TESTS)) + +PROFS = $(patsubst %.c, %, $(PROF_SOURCES)) + +TUNE = $(patsubst %.c, %, $(TUNE_SOURCES)) + +all: shared static + +shared: $(MOD_LOBJ) + +static: $(OBJS) + +profile: $(PROF_SOURCES) + $(foreach prog, $(PROFS), $(CC) $(ABI_FLAG) -O2 -std=c99 $(INCS) $(prog).c ../profiler.o -o $(BUILD_DIR)/$(prog) $(LIBS) || exit $$?;) + +tune: $(TUNE_SOURCES) + $(foreach prog, $(TUNE), $(CC) $(ABI_FLAG) -O2 -std=c99 $(INCS) $(prog).c -o $(BUILD_DIR)/$(prog) $(LIBS) || exit $$?;) + +$(BUILD_DIR)/$(MOD_DIR)_%.o: %.c + $(CC) $(CFLAGS) -c $(INCS) $< -o $@ + +$(MOD_LOBJ): $(LOBJS) + $(CC) $(ABI_FLAG) -Wl,-r $^ -o $@ -nostdlib + +$(BUILD_DIR)/%.lo: %.c + $(CC) $(PICFLAG) $(CFLAGS) $(INCS) -c $< -o $@ + +clean: + rm -rf $(BUILD_DIR) $(MOD_LOBJ) + +check: $(TESTS) $(TESTS_RUN) + +$(BUILD_DIR)/test/%: test/%.c + $(CC) $(CFLAGS) $(INCS) $< ../test_helpers.o -o $@ $(LIBS) + +%_RUN: % + @$< + +.PHONY: profile tune clean check all shared static %_RUN diff --git a/external/flint-2.4.3/qadic/ctx_clear.c b/external/flint-2.4.3/qadic/ctx_clear.c new file mode 100644 index 0000000..97fca38 --- /dev/null +++ b/external/flint-2.4.3/qadic/ctx_clear.c @@ -0,0 +1,37 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_vec.h" +#include "padic.h" +#include "qadic.h" + +void qadic_ctx_clear(qadic_ctx_t ctx) +{ + padic_ctx_clear(&ctx->pctx); + _fmpz_vec_clear(ctx->a, ctx->len); + flint_free(ctx->j); + flint_free(ctx->var); +} + diff --git a/external/flint-2.4.3/qadic/ctx_init_conway.c b/external/flint-2.4.3/qadic/ctx_init_conway.c new file mode 100644 index 0000000..a43a7b1 --- /dev/null +++ b/external/flint-2.4.3/qadic/ctx_init_conway.c @@ -0,0 +1,144 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include +#include + +#include "fmpz_vec.h" +#include "padic.h" +#include "qadic.h" + +#define FLINT_SRC_CPIMPORT "../qadic/CPimport.txt" + +#ifndef FLINT_CPIMPORT +#define FLINT_CPIMPORT FLINT_SRC_CPIMPORT +#endif + +void qadic_ctx_init_conway(qadic_ctx_t ctx, + const fmpz_t p, slong d, slong min, slong max, + const char *var, enum padic_print_mode mode) +{ + char *buf; + FILE *file; + + if (fmpz_cmp_ui(p, 109987) > 0) + { + flint_printf("Exception (qadic_ctx_init_conway). Conway polynomials \n"); + flint_printf("are only available for primes up to 109987.\n"); + abort(); + } + + buf = flint_malloc(832); + file = fopen(FLINT_CPIMPORT, "r"); + + if (!file) + file = fopen(FLINT_SRC_CPIMPORT, "r"); + + if (!file) + { + file = fopen("CPimport.txt", "r"); + + if (!file) + { + flint_printf("Exception (qadic_ctx_init_conway). File loading.\n"); + abort(); + } + } + + while (fgets(buf, 832, file)) + { + char *tmp = buf; + + /* Different prime? */ + if (fmpz_cmp_ui(p, atoi(tmp))) + continue; + + while (*tmp++ != ' ') ; + + /* Same degree? */ + if (d == atoi(tmp)) + { + slong i, j; + char *ptr; + + /* Find number of non-zero coefficients */ + ctx->len = 1; + ptr = tmp; + + for (i = 0; i < d; i++) + { + while (*ptr++ != ' ') ; + + if (atoi(ptr)) + ctx->len ++; + } + + ctx->a = _fmpz_vec_init(ctx->len); + ctx->j = flint_malloc(ctx->len * sizeof(slong)); + + /* Copy the polynomial */ + j = 0; + ptr = tmp; + + for (i = 0; i < d; i++) + { + int coeff; + + while (*ptr++ != ' ') ; + + coeff = atoi(ptr); + + if (coeff) + { + fmpz_set_ui(ctx->a + j, coeff); + ctx->j[j] = i; + j++; + } + } + + fmpz_set_ui(ctx->a + j, 1); + ctx->j[j] = d; + + /* Complete the initialisation of the context */ + padic_ctx_init(&ctx->pctx, p, min, max, mode); + + ctx->var = flint_malloc(strlen(var) + 1); + strcpy(ctx->var, var); + + fclose(file); + flint_free(buf); + return; + } + } + + fclose(file); + flint_free(buf); + + flint_printf("Exception (qadic_ctx_init_conway). The polynomial for \n"); + flint_printf("(p,d) = (%wd,%wd) is not present in the database.\n", *p, d); + abort(); +} + diff --git a/external/flint-2.4.3/qadic/doc/qadic.txt b/external/flint-2.4.3/qadic/doc/qadic.txt new file mode 100644 index 0000000..d053643 --- /dev/null +++ b/external/flint-2.4.3/qadic/doc/qadic.txt @@ -0,0 +1,620 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012, 2013 Sebastian Pancratz + +******************************************************************************/ + +******************************************************************************* + + Data structures + + We represent an element of the extension + $\mathbf{Q}_q \cong \mathbf{Q}_p[X] / (f(X))$ as + a polynomial in $\mathbf{Q}_p[X]$ of degree less + than $\deg(f)$. + + As such, \code{qadic_struct} and \code{qadic_t} are + typedef'ed as \code{padic_poly_struct} and \code{padic_poly_t}. + +******************************************************************************* + +******************************************************************************* + + Context + + We represent an unramified extension of $\mathbf{Q}_p$ + via $\mathbf{Q}_q \cong \mathbf{Q}_p[X] / (f(X))$, + where $f \in \mathbf{Q}_p[X]$ is a monic, irreducible + polynomial which we assume to actually be in $\mathbf{Z}[X]$. + + The first field in the context structure is a $p$-adic + context struct \code{pctx}, which contains data about + the prime~$p$, precomputed powers, the printing mode etc. + + The polynomial $f$ is represented as a sparse polynomial + using two arrays $j$ and $a$ of length \code{len}, where + $f(X) = \sum_{i} a_{i} X^{j_{i}}$. We also assume that + the array~$j$ is sorted in ascending order. + + We choose this data structure to improve reduction + modulo $f(X)$ in $\mathbf{Q}_p[X]$, assuming a sparse + polynomial $f(X)$ is chosen. + + The field \code{var} contains the name of a generator + of the extension, which is used when printing the + elements. + +******************************************************************************* + +void qadic_ctx_init_conway(qadic_ctx_t ctx, + const fmpz_t p, slong d, slong min, slong max, + const char *var, enum padic_print_mode mode) + + Initialises the context \code{ctx} with prime $p$, extension degree $d$, + variable name \code{var} and printing mode \code{mode}. + + Stores powers of $p$ with exponents between \code{min} (inclusive) and + \code{max} exclusive. Assumes that \code{min} is at most \code{max}. + + Assumes that $p$ is a prime. + + Assumes that the string \code{var} is a null-terminated string + of length at least one. + + Assumes that the printing mode is one of \code{PADIC_TERSE}, + \code{PADIC_SERIES}, or \code{PADIC_VAL_UNIT}. + + This function also carries out some relevant precomputation for + arithmetic in $\mathbf{Q}_p / (p^N)$ such as powers of $p$ close + to $p^N$. + +void qadic_ctx_clear(qadic_ctx_t ctx); + + Clears all memory that has been allocated as part of the context. + +slong qadic_ctx_degree(const qadic_ctx_t ctx) + + Returns the extension degree. + +static __inline__ void qadic_ctx_print(const qadic_ctx_t ctx) + + Prints the data from the given context. + +******************************************************************************* + + Memory management + +******************************************************************************* + +void qadic_init(qadic_t rop) + + Initialises the element \code{rop}, setting its value to~$0$. + +void qadic_init2(qadic_t rop, slong prec) + + Initialises the element \code{rop} with the given output precision, + setting the value to~$0$. + +void qadic_clear(qadic_t rop) + + Clears the element \code{rop}. + +void _fmpz_poly_reduce(fmpz *R, slong lenR, + const fmpz *a, const slong *j, slong len) + + Reduces a polynomial \code{(R, lenR)} modulo a sparse monic + polynomial $f(X) = \sum_{i} a_{i} X^{j_{i}}$ of degree at + least~$2$. + + Assumes that the array $j$ of positive length \code{len} is + sorted in ascending order. + + Allows zero-padding in \code{(R, lenR)}. + +void _fmpz_mod_poly_reduce(fmpz *R, slong lenR, + const fmpz *a, const slong *j, slong len, const fmpz_t p) + + Reduces a polynomial \code{(R, lenR)} modulo a sparse monic + polynomial $f(X) = \sum_{i} a_{i} X^{j_{i}}$ of degree at + least~$2$ in $\mathbf{Z}/(p)$, where $p$ is typically a prime + power. + + Assumes that the array $j$ of positive length \code{len} is + sorted in ascending order. + + Allows zero-padding in \code{(R, lenR)}. + +void qadic_reduce(qadic_t rop, const qadic_ctx_t ctx) + + Reduces \code{rop} modulo $f(X)$ and $p^N$. + +******************************************************************************* + + Properties + +******************************************************************************* + +slong qadic_val(const qadic_t op) + + Returns the valuation of \code{op}. + +slong qadic_prec(const qadic_t op) + + Returns the precision of \code{op}. + +******************************************************************************* + + Randomisation + +******************************************************************************* + +void qadic_randtest(qadic_t rop, flint_rand_t state, const qadic_ctx_t ctx) + + Generates a random element of $\mathbf{Q}_q$. + +void qadic_randtest_not_zero(qadic_t rop, flint_rand_t state, + const qadic_ctx_t ctx) + + Generates a random non-zero element of $\mathbf{Q}_q$. + +void qadic_randtest_val(qadic_t rop, flint_rand_t state, slong v, + const qadic_ctx_t ctx) + + Generates a random element of $\mathbf{Q}_q$ with prescribed + valuation \code{val}. + + Note that if $v \geq N$ then the element is necessarily zero. + +void qadic_randtest_int(qadic_t rop, flint_rand_t state, const qadic_ctx_t ctx) + + Generates a random element of $\mathbf{Q}_q$ with non-negative valuation. + +******************************************************************************* + + Assignments and conversions + +******************************************************************************* + +void qadic_set(qadic_t rop, const qadic_t op) + + Sets \code{rop} to \code{op}. + +void qadic_zero(qadic_t rop) + + Sets \code{rop} to zero. + +void qadic_one(qadic_t rop, const qadic_ctx_t ctx) + + Sets \code{rop} to one, reduced in the given context. + + Note that if the precision $N$ is non-positive then \code{rop} + is actually set to zero. + +void qadic_gen(qadic_t rop, const qadic_ctx_t ctx) + + Sets \code{rop} to the generator $X$ for the extension + when $N > 0$, and zero otherwise. If the extension degree + is one, raises an abort signal. + +void qadic_set_ui(qadic_t rop, ulong op, const qadic_ctx_t ctx) + + Sets \code{rop} to the integer \code{op}, reduced in the + context. + +int qadic_get_padic(padic_t rop, const qadic_t op, const qadic_ctx_t ctx) + + If the element \code{op} lies in $\mathbf{Q}_p$, sets \code{rop} + to its value and returns~$1$; otherwise, returns~$0$. + +******************************************************************************* + + Comparison + +******************************************************************************* + +int qadic_is_zero(const qadic_t op) + + Returns whether \code{op} is equal to zero. + +int qadic_is_one(const qadic_t op, const qadic_ctx_t ctx) + + Returns whether \code{op} is equal to one in the given + context. + +int qadic_equal(const qadic_t op1, const qadic_t op2) + + Returns whether \code{op1} and \code{op2} are equal. + +******************************************************************************* + + Basic arithmetic + +******************************************************************************* + +void qadic_add(qadic_t rop, const qadic_t op1, const qadic_t op2, + const qadic_ctx_t ctx) + + Sets \code{rop} to the sum of \code{op1} and \code{op2}. + + Assumes that both \code{op1} and \code{op2} are reduced in the + given context and ensures that \code{rop} is, too. + +void qadic_sub(qadic_t rop, const qadic_t op1, const qadic_t op2, + const qadic_ctx_t ctx) + + Sets \code{rop} to the difference of \code{op1} and \code{op2}. + + Assumes that both \code{op1} and \code{op2} are reduced in the + given context and ensures that \code{rop} is, too. + +void qadic_neg(qadic_t rop, const qadic_t op, const qadic_ctx_t ctx) + + Sets \code{rop} to the negative of \code{op}. + + Assumes that \code{op} is reduced in the given context and + ensures that \code{rop} is, too. + +void qadic_mul(qadic_t rop, const qadic_t op1, const qadic_t op2, + const qadic_ctx_t ctx) + + Sets \code{rop} to the product of \code{op1} and \code{op2}, + reducing the output in the given context. + +void _qadic_inv(fmpz *rop, const fmpz *op, slong len, + const fmpz *a, const slong *j, slong lena, + const fmpz_t p, slong N) + + Sets \code{(rop, d)} to the inverse of \code{(op, len)} + modulo $f(X)$ given by \code{(a,j,lena)} and $p^N$. + + Assumes that \code{(op,len)} has valuation~$0$, that is, + that it represents a $p$-adic unit. + + Assumes that \code{len} is at most $d$. + + Does not support aliasing. + +void qadic_inv(qadic_t rop, const qadic_t op, const qadic_ctx_t ctx) + + Sets \code{rop} to the inverse of \code{op}, reduced in the given context. + +void _qadic_pow(fmpz *rop, const fmpz *op, slong len, const fmpz_t e, + const fmpz *a, const slong *j, slong lena, + const fmpz_t p) + + Sets \code{(rop, 2*d-1)} to \code{(op,len)} raised to the power~$e$, + reduced modulo $f(X)$ given by \code{(a, j, lena)} and $p$, which + is expected to be a prime power. + + Assumes that $e \geq 0$ and that \code{len} is positive and at most~$d$. + + Although we require that \code{rop} provides space for + $2d - 1$ coefficients, the output will be reduces modulo + $f(X)$, which is a polynomial of degree~$d$. + + Does not support aliasing. + +void qadic_pow(qadic_t rop, const qadic_t op, const fmpz_t e, + const qadic_ctx_t ctx) + + Sets \code{rop} the \code{op} raised to the power~$e$. + + Currently assumes that $e \geq 0$. + + Note that for any input \code{op}, \code{rop} is set to one in the + given context whenever $e = 0$. + +******************************************************************************* + + Special functions + +******************************************************************************* + +void _qadic_exp_rectangular(fmpz *rop, const fmpz *op, slong v, slong len, + const fmpz *a, const slong *j, slong lena, + const fmpz_t p, slong N, const fmpz_t pN) + + Sets \code{(rop, 2*d - 1)} to the exponential of \code{(op, v, len)} + reduced modulo $p^N$, assuming that the series converges. + + Assumes that \code{(op, v, len)} is non-zero. + + Does not support aliasing. + +int qadic_exp_rectangular(qadic_t rop, const qadic_t op, const qadic_ctx_t ctx) + + Returns whether the exponential series converges at \code{op} + and sets \code{rop} to its value reduced modulo in the given + context. + +void _qadic_exp_balanced(fmpz *rop, const fmpz *x, slong v, slong len, + const fmpz *a, const slong *j, slong lena, + const fmpz_t p, slong N, const fmpz_t pN) + + Sets \code{(rop, d)} to the exponential of \code{(op, v, len)} + reduced modulo $p^N$, assuming that the series converges. + + Assumes that \code{len} is in $[1,d)$ but supports zero padding, + including the special case when \code{(op, len)} is zero. + + Supports aliasing between \code{rop} and \code{op}. + +int qadic_exp_balanced(qadic_t rop, const qadic_t op, const qadic_ctx_t ctx) + + Returns whether the exponential series converges at \code{op} + and sets \code{rop} to its value reduced modulo in the given + context. + +void _qadic_exp(fmpz *rop, const fmpz *op, slong v, slong len, + const fmpz *a, const slong *j, slong lena, + const fmpz_t p, slong N) + + Sets \code{(rop, 2*d - 1)} to the exponential of \code{(op, v, len)} + reduced modulo $p^N$, assuming that the series converges. + + Assumes that \code{(op, v, len)} is non-zero. + + Does not support aliasing. + +int qadic_exp(qadic_t rop, const qadic_t op, const qadic_ctx_t ctx) + + Returns whether the exponential series converges at \code{op} + and sets \code{rop} to its value reduced modulo in the given + context. + + The exponential series converges if the valuation of \code{op} + is at least~$2$ or $1$ when $p$ is even or odd, respectively. + +void _qadic_log_rectangular(fmpz *z, const fmpz *y, slong v, slong len, + const fmpz *a, const slong *j, slong lena, + const fmpz_t p, slong N, const fmpz_t pN) + + Computes + \begin{equation*} + z = - \sum_{i = 1}^{\infty} \frac{y^i}{i} \pmod{p^N}. + \end{equation*} + + Note that this can be used to compute the $p$-adic logarithm + via the equation + \begin{align*} + \log(x) & = \sum_{i=1}^{\infty} (-1)^{i-1} \frac{(x-1)^i}{i} \\ + & = - \sum_{i=1}^{\infty} \frac{(1-x)^i}{i}. + \end{align*} + + Assumes that $y = 1 - x$ is non-zero and that $v = \ord_p(y)$ + is at least $1$ when $p$ is odd and at least $2$ when $p = 2$ + so that the series converges. + + Assumes that $y$ is reduced modulo $p^N$. + + Assumes that $v < N$, and in particular $N \geq 2$. + + Supports aliasing between $y$ and $z$. + +int qadic_log_rectangular(qadic_t rop, const qadic_t op, const padic_ctx_t ctx) + + Returns whether the $p$-adic logarithm function converges at + \code{op}, and if so sets \code{rop} to its value. + +void _qadic_log_balanced(fmpz *z, const fmpz *y, slong len, + const fmpz *a, const slong *j, slong lena, + const fmpz_t p, slong N, const fmpz_t pN) + + Computes $(z, d)$ as + \begin{equation*} + z = - \sum_{i = 1}^{\infty} \frac{y^i}{i} \pmod{p^N}. + \end{equation*} + + Assumes that $v = \ord_p(y)$ is at least $1$ when $p$ is odd and + at least $2$ when $p = 2$ so that the series converges. + + Supports aliasing between $z$ and $y$. + +int qadic_log_balanced(qadic_t rop, const qadic_t op, const qadic_ctx_t ctx) + + Returns whether the $p$-adic logarithm function converges at + \code{op}, and if so sets \code{rop} to its value. + +void _qadic_log(fmpz *z, const fmpz *y, slong v, slong len, + const fmpz *a, const slong *j, slong lena, + const fmpz_t p, slong N, const fmpz_t pN) + + Computes $(z, d)$ as + \begin{equation*} + z = - \sum_{i = 1}^{\infty} \frac{y^i}{i} \pmod{p^N}. + \end{equation*} + + Note that this can be used to compute the $p$-adic logarithm + via the equation + \begin{align*} + \log(x) & = \sum_{i=1}^{\infty} (-1)^{i-1} \frac{(x-1)^i}{i} \\ + & = - \sum_{i=1}^{\infty} \frac{(1-x)^i}{i}. + \end{align*} + + Assumes that $y = 1 - x$ is non-zero and that $v = \ord_p(y)$ + is at least $1$ when $p$ is odd and at least $2$ when $p = 2$ + so that the series converges. + + Assumes that $(y, d)$ is reduced modulo $p^N$. + + Assumes that $v < N$, and hence in particular $N \geq 2$. + + Supports aliasing between $z$ and $y$. + +int qadic_log(qadic_t rop, const qadic_t op, const qadic_ctx_t ctx) + + Returns whether the $p$-adic logarithm function converges at + \code{op}, and if so sets \code{rop} to its value. + + The $p$-adic logarithm function is defined by the usual series + \begin{equation*} + \log_p(x) = \sum_{i=1}^{\infty} (-1)^{i-1} \frac{(x-1)^i}{i} + \end{equation*} + but this only converges when $\ord_p(x)$ is at least $2$ or $1$ + when $p = 2$ or $p > 2$, respectively. + +void _qadic_frobenius_a(fmpz *rop, slong e, + const fmpz *a, const slong *j, slong lena, + const fmpz_t p, slong N) + + Computes $\sigma^e(X) \bmod{p^N}$ where $X$ is such that + $\mathbf{Q}_q \cong \mathbf{Q}_p[X]/(f(X))$. + + Assumes that the precision $N$ is at least~$2$ and that the + extension is non-trivial, i.e.\ $d \geq 2$. + + Assumes that $0 < e < d$. + + Sets \code{(rop, 2*d-1)}, although the actual length of the + output will be at most~$d$. + +void _qadic_frobenius(fmpz *rop, const fmpz *op, slong len, slong e, + const fmpz *a, const slong *j, slong lena, + const fmpz_t p, slong N) + + Sets \code{(rop, 2*d-1)} to $\Sigma$ evaluated at \code{(op, len)}. + + Assumes that \code{len} is positive but at most~$d$. + + Assumes that $0 < e < d$. + + Does not support aliasing. + +void qadic_frobenius(qadic_t rop, const qadic_t op, slong e, const qadic_ctx_t ctx) + + Evaluates the homomorphism $\Sigma^e$ at \code{op}. + + Recall that $\mathbf{Q}_q / \mathbf{Q}_p$ is Galois with Galois group + $\langle \Sigma \rangle \cong \langle \sigma \rangle$, which is also + isomorphic to $\mathbf{Z}/d\mathbf{Z}$, where + $\sigma \in \Gal(\mathbf{F}_q/\mathbf{F}_p)$ is the Frobenius element + $\sigma \colon x \mapsto x^p$ and $\Sigma$ is its lift to + $\Gal(\mathbf{Q}_q/\mathbf{Q}_p)$. + + This functionality is implemented as \code{GaloisImage()} in Magma. + +void _qadic_teichmuller(fmpz *rop, const fmpz *op, slong len, + const fmpz *a, const slong *j, slong lena, + const fmpz_t p, slong N) + + Sets \code{(rop, d)} to the Teichm\"uller lift of \code{(op, len)} + modulo~$p^N$. + + Does not support aliasing. + +void qadic_teichmuller(qadic_t rop, const qadic_t op, const qadic_ctx_t ctx) + + Sets \code{rop} to the Teichm\"uller lift of \code{op} to the + precision given in the context. + + For a unit \code{op}, this is the unique $(q-1)$th root of unity + which is congruent to \code{op} modulo~$p$. + + Sets \code{rop} to zero if \code{op} is zero in the given context. + + Raises an exception if the valuation of \code{op} is negative. + +void _qadic_trace(fmpz_t rop, const fmpz *op, slong len, + const fmpz *a, const slong *j, slong lena, const fmpz_t pN) + +void qadic_trace(padic_t rop, const qadic_t op, const qadic_ctx_t ctx) + + Sets \code{rop} to the trace of \code{op}. + + For an element $a \in \mathbf{Q}_q$, multiplication by $a$ defines + a $\mathbf{Q}_p$-linear map on $\mathbf{Q}_q$. We define the trace + of $a$ as the trace of this map. Equivalently, if $\Sigma$ generates + $\Gal(\mathbf{Q}_q / \mathbf{Q}_p)$ then the trace of $a$ is equal to + $\sum_{i=0}^{d-1} \Sigma^i (a)$. + +void _qadic_norm(fmpz_t rop, const fmpz *op, slong len, + const fmpz *a, const slong *j, slong lena, + const fmpz_t p, slong N) + + Sets \code{rop} to the norm of the element \code{(op,len)} + in $\mathbf{Z}_q$ to precision $N$, where \code{len} is at + least one. + + The result will be reduced modulo $p^N$. + + Note that whenever \code{(op,len)} is a unit, so is its norm. + Thus, the output \code{rop} of this function will typically + not have to be canonicalised or reduced by the caller. + +void qadic_norm(padic_t rop, const qadic_t op, const qadic_ctx_t ctx) + + Computes the norm of \code{op} to the given precision. + + Algorithm selection is automatic depending on the input. + +void qadic_norm_analytic(padic_t rop, const qadic_t op, const qadic_ctx_t ctx) + + Whenever \code{op} has valuation greater than $(p-1)^{-1}$, this + routine computes its norm \code{rop} via + \begin{equation*} + \Norm (x) = \exp \Bigl( \bigl( \Trace \log (x) \bigr) \Bigr). + \end{equation*} + + In the special case that \code{op} lies in $\mathbf{Q}_p$, returns + its norm as $\Norm(x) = x^d$, where $d$ is the extension degree. + + Otherwise, raises an \code{abort} signal. + + The complexity of this implementation is quasi-linear in $d$ and $N$, + and polynomial in $\log p$. + +void qadic_norm_resultant(padic_t rop, const qadic_t op, const qadic_ctx_t ctx) + + Sets \code{rop} to the norm of \code{op}, using the formula + \begin{equation*} + \Norm(x) = \ell(f)^{-\deg(a)} \Res(f(X), a(X)), + \end{equation*} + where $\mathbf{Q}_q \cong \mathbf{Q}_p[X] / (f(X))$, $\ell(f)$ is the + leading coefficient of $f(X)$, and $a(X) \in mathbf{Q}_p[X]$ denotes + the same polynomial as $x$. + + The complexity of the current implementation is given by + $\mathcal{O}(d^4 M(N \log p))$, where $M(n)$ denotes the + complexity of multiplying to $n$-bit integers. + +******************************************************************************* + + Output + +******************************************************************************* + +int qadic_fprint_pretty(FILE *file, const qadic_t op, const qadic_ctx_t ctx) + + Prints a pretty representation of \code{op} to \code{file}. + + In the current implementation, always returns~$1$. The return code is + part of the function's signature to allow for a later implementation to + return the number of characters printed or a non-positive error code. + +int qadic_print_pretty(const qadic_t op, const qadic_ctx_t ctx) + + Prints a pretty representation of \code{op} to \code{stdout}. + + In the current implementation, always returns~$1$. The return code is + part of the function's signature to allow for a later implementation to + return the number of characters printed or a non-positive error code. + diff --git a/external/flint-2.4.3/qadic/exp.c b/external/flint-2.4.3/qadic/exp.c new file mode 100644 index 0000000..fffc885 --- /dev/null +++ b/external/flint-2.4.3/qadic/exp.c @@ -0,0 +1,108 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_mod_poly.h" +#include "qadic.h" + +void _qadic_exp(fmpz *rop, const fmpz *op, slong v, slong len, + const fmpz *a, const slong *j, slong lena, + const fmpz_t p, slong N, const fmpz_t pN) +{ + if (N < (WORD(1) << 13) / (slong) fmpz_bits(p)) + { + _qadic_exp_rectangular(rop, op, v, len, a, j, lena, p, N, pN); + } + else + { + const slong d = j[lena - 1]; + + _qadic_exp_balanced(rop, op, v, len, a, j, lena, p, N, pN); + _fmpz_vec_zero(rop + d, d - 1); + } +} + +int qadic_exp(qadic_t rop, const qadic_t op, const qadic_ctx_t ctx) +{ + const slong N = qadic_prec(rop); + const slong v = op->val; + const fmpz *p = (&ctx->pctx)->p; + + if (padic_poly_is_zero(op)) + { + padic_poly_one(rop); + return 1; + } + + if ((*p == WORD(2) && v <= 1) || (v <= 0)) + { + return 0; + } + else + { + if (v < N) + { + const slong d = qadic_ctx_degree(ctx); + + fmpz *t; + fmpz_t pN; + int alloc; + + alloc = _padic_ctx_pow_ui(pN, N, &ctx->pctx); + + if (rop == op) + { + t = _fmpz_vec_init(2 * d - 1); + } + else + { + padic_poly_fit_length(rop, 2 * d - 1); + t = rop->coeffs; + } + + _qadic_exp(t, op->coeffs, v, op->length, + ctx->a, ctx->j, ctx->len, p, N, pN); + rop->val = 0; + + if (rop == op) + { + _fmpz_vec_clear(rop->coeffs, rop->alloc); + rop->coeffs = t; + rop->alloc = 2 * d - 1; + rop->length = d; + } + _padic_poly_set_length(rop, d); + _padic_poly_normalise(rop); + + if (alloc) + fmpz_clear(pN); + } + else + { + padic_poly_one(rop); + } + return 1; + } +} + diff --git a/external/flint-2.4.3/qadic/exp_balanced.c b/external/flint-2.4.3/qadic/exp_balanced.c new file mode 100644 index 0000000..142515b --- /dev/null +++ b/external/flint-2.4.3/qadic/exp_balanced.c @@ -0,0 +1,235 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "qadic.h" + +extern slong _padic_exp_bound(slong v, slong N, const fmpz_t p); + +static void +_qadic_exp_bsplit_series(fmpz *P, fmpz_t Q, fmpz *T, + const fmpz *x, slong len, slong lo, slong hi, + const fmpz *a, const slong *j, slong lena) +{ + const slong d = j[lena - 1]; + + if (hi - lo == 1) + { + _fmpz_vec_set(P, x, len); + _fmpz_vec_zero(P + len, 2*d - 1 - len); + + fmpz_set_si(Q, lo); + + _fmpz_vec_set(T, P, 2*d - 1); + } + else if (hi - lo == 2) + { + _fmpz_poly_sqr(P, x, len); + _fmpz_vec_zero(P + (2*len - 1), d - (2*len - 1)); + _fmpz_poly_reduce(P, 2*len - 1, a, j, lena); + + fmpz_set_si(Q, lo); + fmpz_mul_si(Q, Q, lo + 1); + + _fmpz_vec_scalar_mul_si(T, x, len, lo + 1); + _fmpz_vec_zero(T + len, d - len); + _fmpz_vec_add(T, T, P, d); + } + else + { + const slong m = (lo + hi) / 2; + + fmpz *PR, *TR, *W; + fmpz_t QR; + + PR = _fmpz_vec_init(2*d - 1); + TR = _fmpz_vec_init(2*d - 1); + W = _fmpz_vec_init(2*d - 1); + fmpz_init(QR); + + _qadic_exp_bsplit_series(P, Q, T, x, len, lo, m, a, j, lena); + + _qadic_exp_bsplit_series(PR, QR, TR, x, len, m, hi, a, j, lena); + + _fmpz_poly_mul(W, TR, d, P, d); + _fmpz_poly_reduce(W, 2*d - 1, a, j, lena); + + _fmpz_vec_scalar_mul_fmpz(T, T, d, QR); + _fmpz_vec_add(T, T, W, d); + + _fmpz_poly_mul(W, P, d, PR, d); + _fmpz_poly_reduce(W, 2*d - 1, a, j, lena); + _fmpz_vec_swap(P, W, d); + + fmpz_mul(Q, Q, QR); + + _fmpz_vec_clear(PR, 2*d - 1); + _fmpz_vec_clear(TR, 2*d - 1); + _fmpz_vec_clear(W, 2*d - 1); + fmpz_clear(QR); + } +} + +static void +_qadic_exp_bsplit(fmpz *y, const fmpz *x, slong v, slong len, + const fmpz *a, const slong *j, slong lena, + const fmpz_t p, slong N) +{ + const slong d = j[lena - 1]; + const slong n = _padic_exp_bound(v, N, p); + + if (n == 1) + { + fmpz_one(y + 0); + _fmpz_vec_zero(y + 1, d - 1); + } + else + { + fmpz *P, *T; + fmpz_t Q, R; + slong f; + + P = _fmpz_vec_init(2*d - 1); + T = _fmpz_vec_init(2*d - 1); + fmpz_init(Q); + fmpz_init(R); + + _qadic_exp_bsplit_series(P, Q, T, x, len, 1, n, a, j, lena); + + fmpz_add(T + 0, T + 0, Q); /* (T,Q) := (T,Q) + 1 */ + + /* Note exp(x) is a unit so val(T) == val(Q). */ + f = fmpz_remove(Q, Q, p); + fmpz_pow_ui(R, p, f); + _fmpz_vec_scalar_divexact_fmpz(T, T, d, R); + + _padic_inv(Q, Q, p, N); + _fmpz_vec_scalar_mul_fmpz(y, T, d, Q); + + _fmpz_vec_clear(P, 2*d - 1); + _fmpz_vec_clear(T, 2*d - 1); + fmpz_clear(Q); + fmpz_clear(R); + } +} + +void _qadic_exp_balanced(fmpz *rop, const fmpz *x, slong v, slong len, + const fmpz *a, const slong *j, slong lena, + const fmpz_t p, slong N, const fmpz_t pN) +{ + const slong d = j[lena - 1]; + + fmpz_t pw; + fmpz *r, *s, *t; + slong i, w; + + r = _fmpz_vec_init(d); + s = _fmpz_vec_init(2*d - 1); + t = _fmpz_vec_init(d); + fmpz_init(pw); + + fmpz_pow_ui(pw, p, v); + _fmpz_vec_scalar_mul_fmpz(t, x, len, pw); + _fmpz_vec_scalar_mod_fmpz(t, t, len, pN); + _fmpz_vec_zero(t + len, d - len); + + fmpz_set(pw, p); + fmpz_one(rop + 0); + _fmpz_vec_zero(rop + 1, d - 1); + w = 1; + + while (!_fmpz_vec_is_zero(t, d)) + { + fmpz_mul(pw, pw, pw); + + for (i = 0; i < d; i++) + { + fmpz_fdiv_r(r + i, t + i, pw); + fmpz_sub(t + i, t + i, r + i); + } + + if (!_fmpz_vec_is_zero(r, d)) + { + _qadic_exp_bsplit(r, r, w, d, a, j, lena, p, N); + _fmpz_poly_mul(s, rop, d, r, d); + _fmpz_poly_reduce(s, 2*d - 1, a, j, lena); + _fmpz_vec_scalar_mod_fmpz(rop, s, d, pN); + } + + w *= 2; + } + + _fmpz_vec_clear(r, d); + _fmpz_vec_clear(s, 2*d - 1); + _fmpz_vec_clear(t, d); + fmpz_clear(pw); +} + +int qadic_exp_balanced(qadic_t rop, const qadic_t op, const qadic_ctx_t ctx) +{ + const slong N = qadic_prec(rop); + const slong v = op->val; + const fmpz *p = (&ctx->pctx)->p; + + if (padic_poly_is_zero(op)) + { + padic_poly_one(rop); + return 1; + } + + if ((*p == WORD(2) && v <= 1) || (v <= 0)) + { + return 0; + } + else + { + if (v < N) + { + const slong d = qadic_ctx_degree(ctx); + + fmpz_t pN; + int alloc; + + alloc = _padic_ctx_pow_ui(pN, N, &ctx->pctx); + + padic_poly_fit_length(rop, d); + + _qadic_exp_balanced(rop->coeffs, op->coeffs, v, op->length, + ctx->a, ctx->j, ctx->len, p, N, pN); + rop->val = 0; + + _padic_poly_set_length(rop, d); + _padic_poly_normalise(rop); + + if (alloc) + fmpz_clear(pN); + } + else + { + padic_poly_one(rop); + } + return 1; + } +} + diff --git a/external/flint-2.4.3/qadic/exp_rectangular.c b/external/flint-2.4.3/qadic/exp_rectangular.c new file mode 100644 index 0000000..5f1b201 --- /dev/null +++ b/external/flint-2.4.3/qadic/exp_rectangular.c @@ -0,0 +1,226 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_mod_poly.h" +#include "qadic.h" + +extern slong _padic_exp_bound(slong v, slong N, const fmpz_t p); + +void _qadic_exp_rectangular(fmpz *rop, const fmpz *op, slong v, slong len, + const fmpz *a, const slong *j, slong lena, + const fmpz_t p, slong N, const fmpz_t pN) +{ + const slong d = j[lena - 1]; + const slong n = _padic_exp_bound(v, N, p); + + if (n < 4) + { + if (n == 1) /* y := 1 */ + { + fmpz_one(rop); + _fmpz_vec_zero(rop + 1, d - 1); + } + else if (n == 2) /* y := 1 + x */ + { + fmpz_t f; + + fmpz_init(f); + fmpz_pow_ui(f, p, v); + + _fmpz_vec_scalar_mul_fmpz(rop, op, len, f); + _fmpz_vec_zero(rop + len, d - len); + fmpz_add_ui(rop, rop, 1); + _fmpz_vec_scalar_mod_fmpz(rop, rop, len, pN); + + fmpz_clear(f); + } + else /* y := 1 + x + x^2/2 */ + { + slong i; + fmpz *x = _fmpz_vec_init(len + 1); + + fmpz_pow_ui(x + len, p, v); + _fmpz_vec_scalar_mul_fmpz(x, op, len, x + len); + + _fmpz_poly_sqr(rop, x, len); + if (*p != WORD(2)) + { + for (i = 0; i < 2 * len - 1; i++) + if (fmpz_is_odd(rop + i)) + fmpz_add(rop + i, rop + i, pN); + } + _fmpz_vec_scalar_fdiv_q_2exp(rop, rop, 2 * len - 1, 1); + _fmpz_mod_poly_reduce(rop, 2 * len - 1, a, j, lena, pN); + _fmpz_vec_zero(rop + (2 * len - 1), d - (2 * len - 1)); + _fmpz_mod_poly_add(rop, rop, d, x, len, pN); + fmpz_add_ui(rop, rop, 1); + if (fmpz_equal(rop, pN)) + fmpz_zero(rop); + + _fmpz_vec_clear(x, len + 1); + } + } + else /* n >= 4 */ + { + const slong k = fmpz_fits_si(p) ? + (n - 1 - 1) / (fmpz_get_si(p) - 1) : 0; + const slong b = n_sqrt(n); + + slong i; + fmpz_t c, f, pNk; + fmpz *s, *t, *x; + + fmpz_init(c); + fmpz_init(f); + fmpz_init(pNk); + + s = _fmpz_vec_init(2 * d - 1); + t = _fmpz_vec_init(2 * d - 1); + x = _fmpz_vec_init(d * (b + 1) + d - 1); + + fmpz_pow_ui(f, p, v); + fmpz_pow_ui(pNk, p, N + k); + + /* Compute powers x^i of the argument */ + fmpz_one(x); + _fmpz_vec_scalar_mul_fmpz(x + d, op, len, f); + _fmpz_vec_zero(x + d + len, d - len); + for (i = 2; i <= b; i++) + { + _fmpz_mod_poly_mul(x + i * d, x + (i - 1) * d, d, x + d, d, pNk); + _fmpz_mod_poly_reduce(x + i * d, 2 * d - 1, a, j, lena, pNk); + } + + _fmpz_vec_zero(rop, d); + fmpz_one(f); + + for (i = (n + b - 1) / b - 1; i >= 0; i--) + { + slong lo = i * b; + slong hi = FLINT_MIN(n - 1, lo + b - 1); + + _fmpz_vec_zero(s, d); + fmpz_one(c); + + for ( ; hi >= lo; hi--) + { + _fmpz_vec_scalar_addmul_fmpz(s, x + (hi - lo) * d, d, c); + if (hi != 0) + fmpz_mul_ui(c, c, hi); + } + + _fmpz_poly_mul(t, x + b * d, d, rop, d); + _fmpz_mod_poly_reduce(t, 2 * d - 1, a, j, lena, pNk); + _fmpz_vec_scalar_mul_fmpz(rop, s, d, f); + _fmpz_vec_add(rop, rop, t, d); + _fmpz_vec_scalar_mod_fmpz(rop, rop, d, pNk); + + fmpz_mul(f, f, c); + } + + /* Note exp(x) is a unit so val(sum) == val(f). */ + i = fmpz_remove(f, f, p); + if (i) + { + fmpz_pow_ui(c, p, i); + _fmpz_vec_scalar_divexact_fmpz(rop, rop, d, c); + } + + _padic_inv(f, f, p, N); + _fmpz_vec_scalar_mul_fmpz(rop, rop, d, f); + _fmpz_vec_scalar_mod_fmpz(rop, rop, d, pN); + + _fmpz_vec_clear(s, 2 * d - 1); + _fmpz_vec_clear(t, 2 * d - 1); + _fmpz_vec_clear(x, d * (b + 1) + d - 1); + fmpz_clear(c); + fmpz_clear(f); + fmpz_clear(pNk); + } +} + +int qadic_exp_rectangular(qadic_t rop, const qadic_t op, const qadic_ctx_t ctx) +{ + const slong N = qadic_prec(rop); + const slong v = op->val; + const fmpz *p = (&ctx->pctx)->p; + + if (padic_poly_is_zero(op)) + { + padic_poly_one(rop); + return 1; + } + + if ((*p == WORD(2) && v <= 1) || (v <= 0)) + { + return 0; + } + else + { + if (v < N) + { + const slong d = qadic_ctx_degree(ctx); + + fmpz *t; + fmpz_t pN; + int alloc; + + alloc = _padic_ctx_pow_ui(pN, N, &ctx->pctx); + + if (rop == op) + { + t = _fmpz_vec_init(2 * d - 1); + } + else + { + padic_poly_fit_length(rop, 2 * d - 1); + t = rop->coeffs; + } + + _qadic_exp_rectangular(t, op->coeffs, v, op->length, + ctx->a, ctx->j, ctx->len, p, N, pN); + rop->val = 0; + + if (rop == op) + { + _fmpz_vec_clear(rop->coeffs, rop->alloc); + rop->coeffs = t; + rop->alloc = 2 * d - 1; + rop->length = d; + } + _padic_poly_set_length(rop, d); + _padic_poly_normalise(rop); + + if (alloc) + fmpz_clear(pN); + } + else + { + padic_poly_one(rop); + } + return 1; + } +} + diff --git a/external/flint-2.4.3/qadic/fprint_pretty.c b/external/flint-2.4.3/qadic/fprint_pretty.c new file mode 100644 index 0000000..7a19914 --- /dev/null +++ b/external/flint-2.4.3/qadic/fprint_pretty.c @@ -0,0 +1,172 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include + +#include "qadic.h" +#include "padic.h" + +int _qadic_fprint_pretty(FILE * file, const fmpz *u, slong len, slong v, + const qadic_ctx_t ctx) +{ + const fmpz *p = (&ctx->pctx)->p; + + if (_fmpz_vec_is_zero(u, len)) + { + fputc('0', file); + return 1; + } + + if ((&ctx->pctx)->mode == PADIC_TERSE) + { + if (v == 0) + { + _fmpz_poly_fprint_pretty(file, u, len, ctx->var); + } + else if (v > 0) + { + fmpz *t = _fmpz_vec_init(len + 1); + + fmpz_pow_ui(t + len, p, v); + _fmpz_vec_scalar_mul_fmpz(t, u, len, t + len); + _fmpz_poly_fprint_pretty(file, t, len, ctx->var); + _fmpz_vec_clear(t, len + 1); + } + else /* v < 0 */ + { + fmpz_t t; + + fmpz_init(t); + fmpz_pow_ui(t, p, -v); + _fmpq_poly_fprint_pretty(file, u, t, len, ctx->var); + fmpz_clear(t); + } + } + else if ((&ctx->pctx)->mode == PADIC_SERIES) + { + fmpz *x, *d; + slong i, j; + + for (i = 0; i < len; i++) + if (fmpz_sgn(u + i) < 0) + break; + + if (i < len) + { + flint_printf("ERROR (qadic_fprint_pretty). u < 0 in SERIES mode.\n"); + abort(); + } + + x = _fmpz_vec_init(len); + d = _fmpz_vec_init(len); + + _fmpz_vec_set(x, u, len); + + /* Unroll first step */ + j = 0; + { + _fmpz_vec_scalar_mod_fmpz(d, x, len, p); /* d = u mod p^{j+1} */ + _fmpz_vec_sub(x, x, d, len); /* x = x - d */ + _fmpz_vec_scalar_divexact_fmpz(x, x, len, p); /* x = x / p */ + + if (!_fmpz_vec_is_zero(d, len)) + { + fputc('(', file); + _fmpz_poly_fprint_pretty(file, d, len, ctx->var); + fputc(')', file); + if (j + v != 0) + { + fputc('*', file); + fmpz_fprint(file, p); + if (j + v != 1) + flint_fprintf(file, "^%wd", j + v); + } + } + + j++; + } + + for ( ; !_fmpz_vec_is_zero(x, len); j++) + { + _fmpz_vec_scalar_mod_fmpz(d, x, len, p); /* d = u mod p^{j+1} */ + _fmpz_vec_sub(x, x, d, len); /* x = x - d */ + _fmpz_vec_scalar_divexact_fmpz(x, x, len, p); /* x = x / p */ + + if (!_fmpz_vec_is_zero(d, len)) + { + flint_fprintf(file, " + "); + fputc('(', file); + _fmpz_poly_fprint_pretty(file, d, len, ctx->var); + fputc(')', file); + if (j + v != 0) + { + fputc('*', file); + fmpz_fprint(file, p); + if (j + v != 1) + flint_fprintf(file, "^%wd", j + v); + } + } + } + _fmpz_vec_clear(x, len); + _fmpz_vec_clear(d, len); + } + else if ((&ctx->pctx)->mode == PADIC_VAL_UNIT) + { + if (v == 0) + { + _fmpz_poly_fprint_pretty(file, u, len, ctx->var); + } + else if (v == 1) + { + fputc('(', file); + _fmpz_poly_fprint_pretty(file, u, len, ctx->var); + fputc(')', file); + fputc('*', file); + fmpz_fprint(file, p); + } + else + { + fputc('(', file); + _fmpz_poly_fprint_pretty(file, u, len, ctx->var); + fputc(')', file); + fputc('*', file); + fmpz_fprint(file, p); + flint_fprintf(file, "^%wd", v); + } + } + else + { + flint_printf("Exception (qadic_fprint_pretty). Unknown print mode.\n"); + abort(); + } + + return 1; +} + +int qadic_fprint_pretty(FILE *file, const qadic_t op, const qadic_ctx_t ctx) +{ + return _qadic_fprint_pretty(file, op->coeffs, op->length, op->val, ctx); +} + diff --git a/external/flint-2.4.3/qadic/frobenius.c b/external/flint-2.4.3/qadic/frobenius.c new file mode 100644 index 0000000..a5fd7cb --- /dev/null +++ b/external/flint-2.4.3/qadic/frobenius.c @@ -0,0 +1,361 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_mod_poly.h" +#include "ulong_extras.h" +#include "qadic.h" + +/* + Assumes that \code{len1} and \code{len2} are positive but at + most~$d$, and also that \code{len1} is at least $6$. + + The latter assumption guarantees that $\ceil{n/B} \geq 2$, + i.e.\ $n \geq 2B$ so $n \geq 2 \ceil{\sqrt{n}}$. + */ + +static void +_fmpz_mod_poly_compose_smod_rectangular(fmpz *rop, + const fmpz *op1, slong len1, + const fmpz *op2, slong len2, + const fmpz *a, const slong *j, slong lena, + const fmpz_t p) +{ + const slong d = j[lena - 1]; + + if (len2 == 1) + { + _fmpz_mod_poly_evaluate_fmpz(rop, op1, len1, op2, p); + _fmpz_vec_zero(rop + 1, d - 1); + } + else + { + const slong B = n_sqrt(len1); + slong i, k; + fmpz *pows, *t; + + pows = _fmpz_vec_init((B + 2) * d); + t = _fmpz_vec_init(2 * d - 1); + + fmpz_one(pows + 0 * d + 0); + _fmpz_vec_set(pows + 1 * d, op2, len2); + for (i = 2; i <= B; i++) + { + _fmpz_poly_mul(pows + i * d, pows + (i - 1) * d, d, op2, len2); + _fmpz_poly_reduce(pows + i * d, d + len2 - 1, a, j, lena); + _fmpz_vec_scalar_mod_fmpz(pows + i * d, pows + i * d, d, p); + } + + _fmpz_vec_zero(rop, d); + + for (i = (len1 + B - 1) / B - 1; i >= 0; i--) + { + _fmpz_poly_mul(t, rop, d, pows + B * d, d); + _fmpz_poly_reduce(t, 2 * d - 1, a, j, lena); + + _fmpz_vec_set(rop, t, d); + fmpz_add(rop + 0, rop + 0, op1 + i*B); + for (k = FLINT_MIN(B, len1 - i*B) - 1; k > 0; k--) + { + _fmpz_vec_scalar_addmul_fmpz(rop, pows + k * d, d, op1 + (i*B + k)); + } + + _fmpz_vec_scalar_mod_fmpz(rop, rop, d, p); + } + + _fmpz_vec_clear(pows, (B + 2) * d); + _fmpz_vec_clear(t, 2 * d - 1); + } +} + +static void +_fmpz_mod_poly_compose_smod_horner(fmpz *rop, + const fmpz *op1, slong len1, + const fmpz *op2, slong len2, + const fmpz *a, const slong *j, slong lena, + const fmpz_t p) +{ + const slong d = j[lena - 1]; + + if (len1 == 1) + { + fmpz_set(rop, op1); + _fmpz_vec_zero(rop + 1, d - 1); + } + else if (len2 == 1) + { + _fmpz_mod_poly_evaluate_fmpz(rop, op1, len1, op2, p); + _fmpz_vec_zero(rop + 1, d - 1); + } + else + { + slong i; + fmpz *t; + + t = _fmpz_vec_init(2*d - 1); + + _fmpz_vec_zero(rop, d); + + for (i = len1 - 1; i >= 0; i--) + { + _fmpz_poly_mul(t, rop, d, op2, len2); + _fmpz_poly_reduce(t, d + len2 - 1, a, j, lena); + _fmpz_poly_add(rop, t, d, op1 + i, 1); + _fmpz_vec_scalar_mod_fmpz(rop, rop, d, p); + } + + _fmpz_vec_clear(t, 2*d - 1); + } +} + +/* + Computes the composition $f(g(X))$ modulo the sparse polynomial + given by the data \code{(a, j, lena)}, which is assumed to be + of degree~$d \geq 2$. + + Sets the vector \code{(rop, d)}. + + Assumes that \code{len1} and \code{len2} are positive but at + most~$d$. + + Does not support aliasing. + */ + +void +_fmpz_mod_poly_compose_smod(fmpz *rop, + const fmpz *op1, slong len1, + const fmpz *op2, slong len2, + const fmpz *a, const slong *j, slong lena, + const fmpz_t p) +{ + if (len1 < 6) + { + _fmpz_mod_poly_compose_smod_horner(rop, op1, len1, op2, len2, a, j, lena, p); + } + else + { + _fmpz_mod_poly_compose_smod_rectangular(rop, op1, len1, op2, len2, a, j, lena, p); + } +} + +void _qadic_frobenius_a(fmpz *rop, slong exp, + const fmpz *a, const slong *j, slong lena, + const fmpz_t p, slong N) +{ + const slong d = j[lena - 1]; + + slong *e, i, n; + fmpz *pow, *f1, *f2, *inv, *s, *t; + + n = FLINT_CLOG2(N) + 1; + + e = flint_malloc(n * sizeof(slong)); + for (e[i = 0] = N; e[i] > 1; i++) + e[i + 1] = (e[i] + 1) / 2; + + pow = _fmpz_vec_init(n); + f1 = _fmpz_vec_init(d + 1); + f2 = _fmpz_vec_init(d); + inv = _fmpz_vec_init(2*d - 1); + s = _fmpz_vec_init(2*d - 1); + t = _fmpz_vec_init(2*d - 1); + + /* Compute powers of p */ + { + fmpz_one(t); + fmpz_set(pow + i, p); + } + for (i--; i >= 1; i--) + { + if (e[i] & WORD(1)) + { + fmpz_mul(pow + i, t, pow + (i + 1)); + fmpz_mul(t, t, t); + } + else + { + fmpz_mul(t, t, pow + (i + 1)); + fmpz_mul(pow + i, pow + (i + 1), pow + (i + 1)); + } + } + { + if (e[i] & WORD(1)) + fmpz_mul(pow + i, t, pow + (i + 1)); + else + fmpz_mul(pow + i, pow + (i + 1), pow + (i + 1)); + } + + /* Dense representation of f and f' */ + { + slong k; + + for (k = 0; k < lena; k++) + fmpz_set(f1 + j[k], a + k); + for (k = 1; k < lena; k++) + fmpz_mul_ui(f2 + (j[k] - 1), a + k, j[k]); + } + + /* Run Newton iteration */ + i = n - 1; + { + fmpz op[2] = {WORD(0), WORD(1)}; + + fmpz_pow_ui(t, p, exp); + _qadic_pow(rop, op, 2, t, a, j, lena, pow + i); + _fmpz_mod_poly_compose_smod(t, f2, d, rop, d, a, j, lena, pow + i); + _qadic_inv(inv, t, d, a, j, lena, p, 1); + } + for (i--; i >= 0; i--) + { + _fmpz_mod_poly_compose_smod(s, f1, d + 1, rop, d, a, j, lena, pow + i); + _fmpz_mod_poly_mul(t, s, d, inv, d, pow + i); + _fmpz_mod_poly_reduce(t, 2*d - 1, a, j, lena, pow + i); + _fmpz_mod_poly_sub(rop, rop, d, t, d, pow + i); + + if (i > 0) + { + _fmpz_mod_poly_compose_smod(s, f2, d, rop, d, a, j, lena, pow + i); + _fmpz_mod_poly_mul(t, inv, d, s, d, pow + i); + _fmpz_mod_poly_reduce(t, 2*d - 1, a, j, lena, pow + i); + fmpz_sub_ui(t, t, 2); + if (fmpz_sgn(t) < 0) + fmpz_add(t, t, pow + i); + _fmpz_mod_poly_neg(t, t, d, pow + i); + _fmpz_mod_poly_mul(s, inv, d, t, d, pow + i); + _fmpz_mod_poly_reduce(s, 2*d - 1, a, j, lena, pow + i); + + /* SWAP(inv, s). Requires the arrays to be of the same size. */ + { + fmpz *__t; + + __t = inv; + inv = s; + s = __t; + } + } + } + + _fmpz_vec_clear(pow, n); + _fmpz_vec_clear(f1, d + 1); + _fmpz_vec_clear(f2, d); + _fmpz_vec_clear(inv, 2*d - 1); + _fmpz_vec_clear(s, 2*d - 1); + _fmpz_vec_clear(t, 2*d - 1); + flint_free(e); +} + +/* + Sets (rop, 2d-1) to the image of (op, len) under the Frobenius operator + raised to the e-th power. + */ + +void _qadic_frobenius(fmpz *rop, const fmpz *op, slong len, slong e, + const fmpz *a, const slong *j, slong lena, + const fmpz_t p, slong N) +{ + const slong d = j[lena - 1]; + + if (len == 1) /* op is in Zp, not just Zq */ + { + _fmpz_vec_set(rop, op, len); + _fmpz_vec_zero(rop + len, (2*d - 1) - len); + } + else if (N == 1) + { + fmpz_t t; + + fmpz_init(t); + fmpz_pow_ui(t, p, e); + _qadic_pow(rop, op, len, t, a, j, lena, p); + fmpz_clear(t); + } + else + { + fmpz *t; + fmpz_t pow; + + t = _fmpz_vec_init(2*d - 1); + fmpz_init(pow); + fmpz_pow_ui(pow, p, N); + + _qadic_frobenius_a(t, e, a, j, lena, p, N); + + _fmpz_mod_poly_compose_smod(rop, op, len, t, d, a, j, lena, pow); + _fmpz_vec_zero(rop + d, d - 1); + + _fmpz_vec_clear(t, 2*d - 1); + fmpz_clear(pow); + } +} + +void qadic_frobenius(qadic_t rop, const qadic_t op, slong e, const qadic_ctx_t ctx) +{ + const slong N = qadic_prec(rop); + const slong d = qadic_ctx_degree(ctx); + + e = e % d; + if (e < 0) + e += d; + + if (qadic_is_zero(op) || op->val >= N) + { + qadic_zero(rop); + } + else if (e == 0) + { + padic_poly_set(rop, op, &ctx->pctx); + } + else + { + fmpz *t; + + if (rop == op) + { + t = _fmpz_vec_init(2 * d - 1); + } + else + { + padic_poly_fit_length(rop, 2 * d - 1); + t = rop->coeffs; + } + + _qadic_frobenius(t, op->coeffs, op->length, e, + ctx->a, ctx->j, ctx->len, (&ctx->pctx)->p, N - op->val); + + if (rop == op) + { + _fmpz_vec_clear(rop->coeffs, rop->alloc); + rop->coeffs = t; + rop->alloc = 2 * d - 1; + rop->length = d; + } + else + { + rop->val = op->val; + _padic_poly_set_length(rop, d); + } + _padic_poly_normalise(rop); + } +} + diff --git a/external/flint-2.4.3/qadic/inv.c b/external/flint-2.4.3/qadic/inv.c new file mode 100644 index 0000000..e0ec5df --- /dev/null +++ b/external/flint-2.4.3/qadic/inv.c @@ -0,0 +1,189 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_mod_poly.h" +#include "qadic.h" + +void _qadic_inv(fmpz *rop, const fmpz *op, slong len, + const fmpz *a, const slong *j, slong lena, + const fmpz_t p, slong N) +{ + const slong d = j[lena - 1]; + + if (len == 1) + { + _padic_inv(rop, op, p, N); + _fmpz_vec_zero(rop + 1, d - 1); + } + else if (N == 1) + { + fmpz *P = _fmpz_vec_init(d + 1); + slong k; + + for (k = 0; k < lena; k++) + fmpz_set(P + j[k], a + k); + + _fmpz_mod_poly_invmod(rop, op, len, P, d + 1, p); + + _fmpz_vec_clear(P, d + 1); + } + else /* d, N >= 2 */ + { + slong *e, i, n; + fmpz *pow, *u; + fmpz *s, *t; + + n = FLINT_CLOG2(N) + 1; + + /* Compute sequence of exponents */ + e = flint_malloc(n * sizeof(slong)); + for (e[i = 0] = N; e[i] > 1; i++) + e[i + 1] = (e[i] + 1) / 2; + + pow = _fmpz_vec_init(n); + u = _fmpz_vec_init(len * n); + s = _fmpz_vec_init(2 * d - 1); + t = _fmpz_vec_init(2 * d - 1); + + /* Compute powers of p */ + { + fmpz_one(t); + fmpz_set(pow + i, p); + } + for (i--; i >= 1; i--) + { + if (e[i] & WORD(1)) + { + fmpz_mul(pow + i, t, pow + (i + 1)); + fmpz_mul(t, t, t); + } + else + { + fmpz_mul(t, t, pow + (i + 1)); + fmpz_mul(pow + i, pow + (i + 1), pow + (i + 1)); + } + } + { + if (e[i] & WORD(1)) + fmpz_mul(pow + i, t, pow + (i + 1)); + else + fmpz_mul(pow + i, pow + (i + 1), pow + (i + 1)); + } + + /* Compute reduced units */ + { + _fmpz_vec_scalar_mod_fmpz(u + 0 * len, op, len, pow + 0); + } + for (i = 1; i < n; i++) + { + _fmpz_vec_scalar_mod_fmpz(u + i * len, u + (i - 1) * len, len, pow + i); + } + + /* Run Newton iteration */ + i = n - 1; + { + fmpz *P = _fmpz_vec_init(d + 1); + slong k; + + for (k = 0; k < lena; k++) + fmpz_set(P + j[k], a + k); + + _fmpz_mod_poly_invmod(rop, u + i * len, len, P, d + 1, pow + i); + + _fmpz_vec_clear(P, d + 1); + } + for (i--; i >= 0; i--) /* z' := 2 z - a z^2 */ + { + _fmpz_poly_sqr(s, rop, d); + _fmpz_poly_reduce(s, 2 * d - 1, a, j, lena); + + _fmpz_poly_mul(t, s, d, u + i * len, len); + _fmpz_poly_reduce(t, d + len - 1, a, j, lena); + + _fmpz_vec_scalar_mul_2exp(rop, rop, d, 1); + _fmpz_poly_sub(rop, rop, d, t, d); + _fmpz_vec_scalar_mod_fmpz(rop, rop, d, pow + i); + } + + _fmpz_vec_clear(pow, n); + _fmpz_vec_clear(u, len * n); + _fmpz_vec_clear(s, 2 * d - 1); + _fmpz_vec_clear(t, 2 * d - 1); + flint_free(e); + } +} + +void qadic_inv(qadic_t x, const qadic_t y, const qadic_ctx_t ctx) +{ + const slong N = qadic_prec(x); + + if (qadic_is_zero(y)) + { + flint_printf("Exception (qadic_inv). Zero is not invertible.\n"); + abort(); + } + + /* + If y = u p^v has negative valuation with N <= -v then the + exact inverse of y is zero when reduced modulo $p^N$ + */ + if (N + y->val <= 0) + { + qadic_zero(x); + } + else + { + const slong d = qadic_ctx_degree(ctx); + fmpz *t; + + if (x == y) + { + t = _fmpz_vec_init(d); + } + else + { + padic_poly_fit_length(x, d); + t = x->coeffs; + } + + _qadic_inv(t, y->coeffs, y->length, + ctx->a, ctx->j, ctx->len, (&ctx->pctx)->p, N + y->val); + x->val = - y->val; + + if (x == y) + { + _fmpz_vec_clear(x->coeffs, x->alloc); + x->coeffs = t; + x->alloc = d; + x->length = d; + } + else + { + _padic_poly_set_length(x, d); + } + _padic_poly_normalise(x); + } +} + diff --git a/external/flint-2.4.3/qadic/log.c b/external/flint-2.4.3/qadic/log.c new file mode 100644 index 0000000..5455340 --- /dev/null +++ b/external/flint-2.4.3/qadic/log.c @@ -0,0 +1,110 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "qadic.h" + +void _qadic_log(fmpz *z, const fmpz *y, slong v, slong len, + const fmpz *a, const slong *j, slong lena, + const fmpz_t p, slong N, const fmpz_t pN) +{ + if (N < (WORD(1) < 10) / (slong) fmpz_bits(p)) + { + _qadic_log_rectangular(z, y, v, len, a, j, lena, p, N, pN); + } + else + { + _qadic_log_balanced(z, y, len, a, j, lena, p, N, pN); + } +} + +int qadic_log(qadic_t rop, const qadic_t op, const qadic_ctx_t ctx) +{ + const fmpz *p = (&ctx->pctx)->p; + const slong d = qadic_ctx_degree(ctx); + const slong N = qadic_prec(rop); + const slong len = op->length; + + if (op->val < 0) + { + return 0; + } + else + { + fmpz *x; + fmpz_t pN; + int alloc, ans; + + x = _fmpz_vec_init(len + 1); + alloc = _padic_ctx_pow_ui(pN, N, &ctx->pctx); + + /* Set x := (1 - op) mod p^N */ + fmpz_pow_ui(x + len, p, op->val); + _fmpz_vec_scalar_mul_fmpz(x, op->coeffs, len, x + len); + fmpz_sub_ui(x, x, 1); + _fmpz_vec_neg(x, x, len); + _fmpz_vec_scalar_mod_fmpz(x, x, len, pN); + + if (_fmpz_vec_is_zero(x, len)) + { + padic_poly_zero(rop); + ans = 1; + } + else + { + const slong v = _fmpz_vec_ord_p(x, len, p); + + if (v >= 2 || (*p != WORD(2) && v >= 1)) + { + if (v >= N) + { + padic_poly_zero(rop); + } + else + { + padic_poly_fit_length(rop, d); + + _qadic_log(rop->coeffs, x, v, len, + ctx->a, ctx->j, ctx->len, p, N, pN); + rop->val = 0; + + _padic_poly_set_length(rop, d); + _padic_poly_normalise(rop); + padic_poly_canonicalise(rop, p); + } + ans = 1; + } + else + { + ans = 0; + } + } + + _fmpz_vec_clear(x, len + 1); + if (alloc) + fmpz_clear(pN); + return ans; + } +} + diff --git a/external/flint-2.4.3/qadic/log_balanced.c b/external/flint-2.4.3/qadic/log_balanced.c new file mode 100644 index 0000000..3750ab6 --- /dev/null +++ b/external/flint-2.4.3/qadic/log_balanced.c @@ -0,0 +1,308 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_mod_poly.h" +#include "qadic.h" + +extern slong _padic_log_bound(slong v, slong N, const fmpz_t p); + +/* + Assumes that P, T are vectors of length 2 d - 1. + + Assumes that 0 < len <= d. + + Assumes that 1 <= lo < hi. + + Does not support aliasing. + */ + +static void +_qadic_log_bsplit_series(fmpz *P, fmpz_t B, fmpz *T, + const fmpz *y, slong len, slong lo, slong hi, + const fmpz *a, const slong *j, slong lena) +{ + const slong d = j[lena - 1]; + + if (hi - lo == 1) + { + _fmpz_vec_set(P, y, len); + _fmpz_vec_zero(P + len, 2*d - 1 - len); + + fmpz_set_si(B, lo); + + _fmpz_vec_set(T, P, 2*d - 1); + } + else if (hi - lo == 2) + { + _fmpz_poly_sqr(P, y, len); + _fmpz_vec_zero(P + (2*len - 1), d - (2*len - 1)); + _fmpz_poly_reduce(P, 2*len - 1, a, j, lena); + + fmpz_set_si(B, lo); + fmpz_mul_si(B, B, lo + 1); + + _fmpz_vec_scalar_mul_si(T, y, len, lo + 1); + _fmpz_vec_zero(T + len, d - len); + _fmpz_vec_scalar_addmul_si(T, P, d, lo); + } + else + { + const slong m = (lo + hi) / 2; + + fmpz *RP, *RT, *W; + fmpz_t RB; + + RP = _fmpz_vec_init(2*d - 1); + RT = _fmpz_vec_init(2*d - 1); + W = _fmpz_vec_init(2*d - 1); + fmpz_init(RB); + + _qadic_log_bsplit_series(P, B, T, y, len, lo, m, a, j, lena); + + _qadic_log_bsplit_series(RP, RB, RT, y, len, m, hi, a, j, lena); + + _fmpz_poly_mul(W, RT, d, P, d); + _fmpz_poly_reduce(W, 2*d - 1, a, j, lena); + _fmpz_vec_swap(RT, W, d); + + _fmpz_vec_scalar_mul_fmpz(T, T, d, RB); + _fmpz_vec_scalar_addmul_fmpz(T, RT, d, B); + + _fmpz_poly_mul(W, P, d, RP, d); + _fmpz_poly_reduce(W, 2*d - 1, a, j, lena); + _fmpz_vec_swap(P, W, d); + + fmpz_mul(B, B, RB); + + _fmpz_vec_clear(RP, 2*d - 1); + _fmpz_vec_clear(RT, 2*d - 1); + _fmpz_vec_clear(W, 2*d - 1); + fmpz_clear(RB); + } +} + +/* + Sets (z, d) to the sum + + sum_{i=1}^{\infty} y^i / i mod p^N. + + The result may not be reduced modulo p^N, but it is + reduced modulo f(X) given by the data (a, j, lena). + + Supports aliasing between y and z. + */ + +static void +_qadic_log_bsplit(fmpz *z, const fmpz *y, slong v, slong len, + const fmpz *a, const slong *j, slong lena, + const fmpz_t p, slong N) +{ + const slong d = j[lena - 1]; + + fmpz *P, *T; + fmpz_t B, C; + slong n; + + n = _padic_log_bound(v, N, p); + n = FLINT_MAX(n, 2); + + P = _fmpz_vec_init(2*d - 1); + T = _fmpz_vec_init(2*d - 1); + fmpz_init(B); + fmpz_init(C); + + _qadic_log_bsplit_series(P, B, T, y, len, 1, n, a, j, lena); + + n = fmpz_remove(B, B, p); + fmpz_pow_ui(C, p, n); + _fmpz_vec_scalar_divexact_fmpz(T, T, d, C); + + _padic_inv(B, B, p, N); + _fmpz_vec_scalar_mul_fmpz(z, T, d, B); + + _fmpz_vec_clear(P, 2*d - 1); + _fmpz_vec_clear(T, 2*d - 1); + fmpz_clear(B); + fmpz_clear(C); +} + +/* + Computes + \begin{equation*} + z = - \sum_{i = 1}^{\infty} \frac{y^i}{i} \pmod{p^N}. + \end{equation*} + + Note that this can be used to compute the $p$-adic logarithm + via the equation + \begin{align*} + \log(x) & = \sum_{i=1}^{\infty} (-1)^{i-1} \frac{(x-1)^i}{i} \\ + & = - \sum_{i=1}^{\infty} \frac{(1-x)^i}{i}. + \end{align*} + + Assumes that $y = 1 - x$ is non-zero and that $v = \ord_p(y)$ + is at least $1$ when $p$ is odd and at least $2$ when $p = 2$ + so that the series converges. + + Assumes that $v < N$. + + Sets $(z, d)$. + + Ensures that the result is reduced modulo $p^N$. + + Does not support aliasing between $y$ and $z$. + */ + +void _qadic_log_balanced(fmpz *z, const fmpz *y, slong len, + const fmpz *a, const slong *j, slong lena, + const fmpz_t p, slong N, const fmpz_t pN) +{ + const slong d = j[lena - 1]; + + fmpz_t pv; + fmpz *r, *s, *t, *u; + slong i, w; + + r = _fmpz_vec_init(d); + s = _fmpz_vec_init(2*d - 1); + t = _fmpz_vec_init(d); + u = _fmpz_vec_init(d); + fmpz_init(pv); + + fmpz_set(pv, p); + _fmpz_vec_scalar_mod_fmpz(t, y, len, pN); + _fmpz_vec_zero(z, d); + w = 1; + + while (!_fmpz_vec_is_zero(t, d)) + { + fmpz_mul(pv, pv, pv); + + for (i = 0; i < d; i++) + { + fmpz_fdiv_qr(t + i, r + i, t + i, pv); + } + + if (!_fmpz_vec_is_zero(t, d)) + { + _fmpz_vec_scalar_mul_fmpz(t, t, d, pv); + + /* Temporarily set r = 1 - r to compute u = (1-r)^{-1} */ + fmpz_sub_ui(r + 0, r + 0, 1); + _fmpz_vec_neg(r, r, d); + _qadic_inv(u, r, d, a, j, lena, p, N); + _fmpz_vec_neg(r, r, d); + fmpz_add_ui(r + 0, r + 0, 1); + + _fmpz_poly_mul(s, t, d, u, d); + _fmpz_poly_reduce(s, 2 * d - 1, a, j, lena); + _fmpz_vec_scalar_mod_fmpz(t, s, d, pN); + } + + if (!_fmpz_vec_is_zero(r, d)) + { + _qadic_log_bsplit(r, r, w, d, a, j, lena, p, N); + _fmpz_vec_sub(z, z, r, d); + _fmpz_vec_scalar_mod_fmpz(z, z, d, pN); + } + + w *= 2; + } + + _fmpz_vec_clear(r, d); + _fmpz_vec_clear(s, 2*d - 1); + _fmpz_vec_clear(t, d); + _fmpz_vec_clear(u, d); + fmpz_clear(pv); +} + +int qadic_log_balanced(qadic_t rop, const qadic_t op, const qadic_ctx_t ctx) +{ + const fmpz *p = (&ctx->pctx)->p; + const slong d = qadic_ctx_degree(ctx); + const slong N = qadic_prec(rop); + const slong len = op->length; + + if (op->val < 0) + { + return 0; + } + else + { + fmpz *x; + fmpz_t pN; + int alloc, ans; + + x = _fmpz_vec_init(len + 1); + alloc = _padic_ctx_pow_ui(pN, N, &ctx->pctx); + + /* Set x := (1 - op) mod p^N */ + fmpz_pow_ui(x + len, p, op->val); + _fmpz_vec_scalar_mul_fmpz(x, op->coeffs, len, x + len); + fmpz_sub_ui(x + 0, x + 0, 1); + _fmpz_vec_neg(x, x, len); + _fmpz_vec_scalar_mod_fmpz(x, x, len, pN); + + if (_fmpz_vec_is_zero(x, len)) + { + padic_poly_zero(rop); + ans = 1; + } + else + { + const slong v = _fmpz_vec_ord_p(x, len, p); + + if (v >= 2 || (*p != WORD(2) && v >= 1)) + { + if (v >= N) + { + padic_poly_zero(rop); + } + else + { + padic_poly_fit_length(rop, d); + + _qadic_log_balanced(rop->coeffs, x, len, + ctx->a, ctx->j, ctx->len, p, N, pN); + rop->val = 0; + + _padic_poly_set_length(rop, d); + _padic_poly_normalise(rop); + padic_poly_canonicalise(rop, p); + } + ans = 1; + } + else + { + ans = 0; + } + } + + _fmpz_vec_clear(x, len + 1); + if (alloc) + fmpz_clear(pN); + return ans; + } +} + diff --git a/external/flint-2.4.3/qadic/log_rectangular.c b/external/flint-2.4.3/qadic/log_rectangular.c new file mode 100644 index 0000000..ed0e919 --- /dev/null +++ b/external/flint-2.4.3/qadic/log_rectangular.c @@ -0,0 +1,240 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_mod_poly.h" +#include "qadic.h" + +extern slong _padic_log_bound(slong v, slong N, const fmpz_t p); + +/* + Carries out the finite series evaluation for the logarithm + \begin{equation*} + \sum_{i=1}^{n} a_i y^i + = \sum_{j=0}^{\ceil{n/b}-1} \Bigl(\sum_{i=1}^b a_{i+jb} y^i\Bigr) y^{jb} + \end{equation*} + where $a_i = 1/i$ with the choice $b = \floor{\sqrt{n}}$, + all modulo $p^N$, where also $P = p^N$. + + Assumes that $y$ is reduced modulo $p^N$. + + Assumes that $z$ has space for $2d - 1$ coefficients, but + sets only the first $d$ to meaningful values on exit. + + Supports aliasing between $y$ and $z$. + */ +static void +_qadic_log_rectangular_series(fmpz *z, const fmpz *y, slong len, slong n, + const fmpz *a, const slong *j, slong lena, + const fmpz_t p, slong N, const fmpz_t pN) +{ + const slong d = j[lena - 1]; + + if (n <= 2) + { + if (n == 1) /* n == 1; z = y */ + { + _fmpz_vec_set(z, y, len); + _fmpz_vec_zero(z + len, d - len); + } + else /* n == 2; z = y + y^2/2 */ + { + slong i; + fmpz *t; + + t = _fmpz_vec_init(2 * len - 1); + + _fmpz_poly_sqr(t, y, len); + for (i = 0; i < 2 * len - 1; i++) + if (fmpz_is_even(t + i)) + { + fmpz_fdiv_q_2exp(t + i, t + i, 1); + } + else /* => p and t(i) are odd */ + { + fmpz_add(t + i, t + i, pN); + fmpz_fdiv_q_2exp(t + i, t + i, 1); + } + _fmpz_mod_poly_reduce(t, 2 * len - 1, a, j, lena, pN); + _fmpz_mod_poly_add(z, y, len, t, FLINT_MIN(d, 2 * len - 1), pN); + + _fmpz_vec_clear(t, 2 * len - 1); + } + } + else /* n >= 3 */ + { + const slong b = n_sqrt(n); + const slong k = fmpz_fits_si(p) ? n_flog(n, fmpz_get_si(p)) : 0; + + slong i, h; + fmpz_t f, pNk; + fmpz *c, *t, *ypow; + + c = _fmpz_vec_init(d); + t = _fmpz_vec_init(2 * d - 1); + ypow = _fmpz_vec_init((b + 1) * d + d - 1); + fmpz_init(f); + fmpz_init(pNk); + + fmpz_pow_ui(pNk, p, N + k); + + fmpz_one(ypow); + _fmpz_vec_set(ypow + d, y, len); + for (i = 2; i <= b; i++) + { + _fmpz_mod_poly_mul(ypow + i * d, ypow + (i - 1) * d, d, y, len, pNk); + _fmpz_mod_poly_reduce(ypow + i * d, d + len - 1, a, j, lena, pNk); + } + + _fmpz_vec_zero(z, d); + + for (h = (n + (b - 1)) / b - 1; h >= 0; h--) + { + const slong hi = FLINT_MIN(b, n - h*b); + slong w; + + /* Compute inner sum in c */ + fmpz_rfac_uiui(f, 1 + h*b, hi); + + _fmpz_vec_zero(c, d); + for (i = 1; i <= hi; i++) + { + fmpz_divexact_ui(t, f, i + h*b); + _fmpz_vec_scalar_addmul_fmpz(c, ypow + i * d, d, t); + } + + /* Multiply c by p^k f */ + w = fmpz_remove(f, f, p); + _padic_inv(f, f, p, N + k); + if (w > k) + { + fmpz_pow_ui(t, p, w - k); + _fmpz_vec_scalar_divexact_fmpz(c, c, d, t); + } + else if (w < k) + { + fmpz_pow_ui(t, p, k - w); + _fmpz_vec_scalar_mul_fmpz(c, c, d, t); + } + _fmpz_vec_scalar_mul_fmpz(c, c, d, f); + + /* Set z = z y^b + c */ + _fmpz_mod_poly_mul(t, z, d, ypow + b * d, d, pNk); + _fmpz_mod_poly_reduce(t, 2 * d - 1, a, j, lena, pNk); + _fmpz_vec_add(z, c, t, d); + _fmpz_vec_scalar_mod_fmpz(z, z, d, pNk); + } + + fmpz_pow_ui(f, p, k); + _fmpz_vec_scalar_divexact_fmpz(z, z, d, f); + + fmpz_clear(f); + fmpz_clear(pNk); + _fmpz_vec_clear(c, d); + _fmpz_vec_clear(t, 2 * d - 1); + _fmpz_vec_clear(ypow, (b + 1) * d + d - 1); + + } +} + +void _qadic_log_rectangular(fmpz *z, const fmpz *y, slong v, slong len, + const fmpz *a, const slong *j, slong lena, + const fmpz_t p, slong N, const fmpz_t pN) +{ + const slong d = j[lena - 1]; + const slong n = _padic_log_bound(v, N, p) - 1; + + _qadic_log_rectangular_series(z, y, len, n, a, j, lena, p, N, pN); + _fmpz_mod_poly_neg(z, z, d, pN); +} + +int qadic_log_rectangular(qadic_t rop, const qadic_t op, const qadic_ctx_t ctx) +{ + const fmpz *p = (&ctx->pctx)->p; + const slong d = qadic_ctx_degree(ctx); + const slong N = qadic_prec(rop); + const slong len = op->length; + + if (op->val < 0) + { + return 0; + } + else + { + fmpz *x; + fmpz_t pN; + int alloc, ans; + + x = _fmpz_vec_init(len + 1); + alloc = _padic_ctx_pow_ui(pN, N, &ctx->pctx); + + /* Set x := (1 - op) mod p^N */ + fmpz_pow_ui(x + len, p, op->val); + _fmpz_vec_scalar_mul_fmpz(x, op->coeffs, len, x + len); + fmpz_sub_ui(x, x, 1); + _fmpz_vec_neg(x, x, len); + _fmpz_vec_scalar_mod_fmpz(x, x, len, pN); + + if (_fmpz_vec_is_zero(x, len)) + { + padic_poly_zero(rop); + ans = 1; + } + else + { + const slong v = _fmpz_vec_ord_p(x, len, p); + + if (v >= 2 || (*p != WORD(2) && v >= 1)) + { + if (v >= N) + { + padic_poly_zero(rop); + } + else + { + padic_poly_fit_length(rop, d); + + _qadic_log_rectangular(rop->coeffs, x, v, len, + ctx->a, ctx->j, ctx->len, p, N, pN); + rop->val = 0; + + _padic_poly_set_length(rop, d); + _padic_poly_normalise(rop); + padic_poly_canonicalise(rop, p); + } + ans = 1; + } + else + { + ans = 0; + } + } + + _fmpz_vec_clear(x, len + 1); + if (alloc) + fmpz_clear(pN); + return ans; + } +} + diff --git a/external/flint-2.4.3/qadic/mul.c b/external/flint-2.4.3/qadic/mul.c new file mode 100644 index 0000000..88d2823 --- /dev/null +++ b/external/flint-2.4.3/qadic/mul.c @@ -0,0 +1,97 @@ +/*============================================================================ + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "qadic.h" + +/* + Forms the product of (op1,len1) and (op2,len2) modulo (a,j,lena) and pN. + Assumes that len1 >= len2 > 0. Requires rop to be of size at least + len1 + len2 - 1. + */ + +static +void _qadic_mul(fmpz *rop, + const fmpz *op1, slong len1, const fmpz *op2, slong len2, + const fmpz *a, const slong *j, slong lena, const fmpz_t pN) +{ + _fmpz_poly_mul(rop, op1, len1, op2, len2); + _fmpz_mod_poly_reduce(rop, len1 + len2 - 1, a, j, lena, pN); +} + +void qadic_mul(qadic_t x, const qadic_t y, const qadic_t z, + const qadic_ctx_t ctx) +{ + const slong leny = y->length; + const slong lenz = z->length; + const slong lenx = leny + lenz - 1; + const slong N = qadic_prec(x); + const slong d = qadic_ctx_degree(ctx); + + if (leny == 0 || lenz == 0 || y->val + z->val >= N) + { + qadic_zero(x); + } + else + { + fmpz *t; + fmpz_t pN; + int alloc; + + x->val = y->val + z->val; + + alloc = _padic_ctx_pow_ui(pN, N - x->val, &ctx->pctx); + + if (x == y || x == z) + { + t = _fmpz_vec_init(lenx); + } + else + { + padic_poly_fit_length(x, lenx); + t = x->coeffs; + } + + if (leny >= lenz) + _qadic_mul(t, y->coeffs, leny, + z->coeffs, lenz, ctx->a, ctx->j, ctx->len, pN); + else + _qadic_mul(t, z->coeffs, lenz, + y->coeffs, leny, ctx->a, ctx->j, ctx->len, pN); + + if (x == y || x == z) + { + _fmpz_vec_clear(x->coeffs, x->alloc); + x->coeffs = t; + x->alloc = lenx; + } + + _padic_poly_set_length(x, FLINT_MIN(lenx, d)); + _padic_poly_normalise(x); + + if (alloc) + fmpz_clear(pN); + } +} + diff --git a/external/flint-2.4.3/qadic/norm.c b/external/flint-2.4.3/qadic/norm.c new file mode 100644 index 0000000..300d5f6 --- /dev/null +++ b/external/flint-2.4.3/qadic/norm.c @@ -0,0 +1,113 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "qadic.h" + +/* + Discussion on the choice of the norm algorithm. + + When the logarithm function does not converge for x, + the only choice is the resultant method. + + However, when the logarithm function converges, we + can choose between the analytic method and the resultant + method. Roughly speaking, we postulate that the analytic + method has runtime A (log N)^2 mu(p,d,N), where mu(p,d,N) + is (d log d) M(N log p). The resultant method has runtime + B d^4 M(N log p). Experimentally, we find that A/B is + somewhere around 4. + + TODO: Repeat the experiments with p=2, which is an + important special case. + */ + +void _qadic_norm(fmpz_t rop, const fmpz *op, slong len, + const fmpz *a, const slong *j, slong lena, + const fmpz_t p, slong N) +{ + const slong d = j[lena - 1]; + + if (len == 1) + { + fmpz_t pN; + + fmpz_init(pN); + fmpz_pow_ui(pN, p, N); + fmpz_powm_ui(rop, op + 0, d, pN); + fmpz_clear(pN); + } + else + { + fmpz *y; + slong w; + + y = _fmpz_vec_init(len); + + /* (y,len) := 1 - (op,len) */ + _fmpz_vec_neg(y, op, len); + fmpz_add_ui(y + 0, y + 0, 1); + + w = _fmpz_vec_ord_p(y, len, p); + + if (w >= 2 || (*p != WORD(2) && w >= 1)) + { + if (4 * FLINT_FLOG2(N) * FLINT_FLOG2(N) * FLINT_FLOG2(d) < d*d*d) + { + _qadic_norm_analytic(rop, y, w, len, a, j, lena, p, N); + } + else + { + _qadic_norm_resultant(rop, op, len, a, j, lena, p, N); + } + } + else + { + _qadic_norm_resultant(rop, op, len, a, j, lena, p, N); + } + + _fmpz_vec_clear(y, len); + } +} + +void qadic_norm(padic_t rop, const qadic_t op, const qadic_ctx_t ctx) +{ + const slong N = padic_prec(rop); + const slong d = qadic_ctx_degree(ctx); + const fmpz *p = (&ctx->pctx)->p; + + /* N(p^v u) = p^{dv} N(u) */ + + if (qadic_is_zero(op) || d * op->val >= N) + { + padic_zero(rop); + } + else + { + _qadic_norm(padic_unit(rop), op->coeffs, op->length, + ctx->a, ctx->j, ctx->len, p, N - d * op->val); + padic_val(rop) = d * op->val; + } +} + diff --git a/external/flint-2.4.3/qadic/norm_analytic.c b/external/flint-2.4.3/qadic/norm_analytic.c new file mode 100644 index 0000000..ecd4804 --- /dev/null +++ b/external/flint-2.4.3/qadic/norm_analytic.c @@ -0,0 +1,122 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "qadic.h" + +/* + Computes the norm of an element $x$ of $\mathbf{Z}_q$ via the identity + + $\Norm(x) = \exp \Trace \log (x)$ + + whenever $y = 1-x$ has valuation $v$ greater than $(p-1)^{-1}$. + + Assumes that $y$ is non-zero. + */ + +void _qadic_norm_analytic(fmpz_t rop, const fmpz *y, slong v, slong len, + const fmpz *a, const slong *j, slong lena, + const fmpz_t p, slong N) +{ + const slong d = j[lena - 1]; + fmpz_t pN, tru; + slong trv; + fmpz *lg; + + fmpz_init(pN); + fmpz_init(tru); + lg = _fmpz_vec_init(d); + + fmpz_pow_ui(pN, p, N); + + _qadic_log(lg, y, v, len, a, j, lena, p, N, pN); + + _qadic_trace(tru, lg, d, a, j, lena, pN); + + if (!fmpz_is_zero(tru)) + { + trv = fmpz_remove(tru, tru, p); + _padic_exp(rop, tru, trv, p, N); + fmpz_mod(rop, rop, pN); + } + else + { + fmpz_one(rop); + } + + fmpz_clear(pN); + fmpz_clear(tru); + _fmpz_vec_clear(lg, d); +} + +void qadic_norm_analytic(padic_t rop, const qadic_t op, const qadic_ctx_t ctx) +{ + const slong N = padic_prec(rop); + const slong d = qadic_ctx_degree(ctx); + const fmpz *p = (&ctx->pctx)->p; + + /* N(p^v u) = p^{dv} N(u) */ + + if (qadic_is_zero(op) || d * op->val >= N) + { + padic_zero(rop); + } + else if (op->length == 1) + { + fmpz_t pN; + int alloc; + + alloc = _padic_ctx_pow_ui(pN, N - d * op->val, (&ctx->pctx)); + + fmpz_powm_ui(padic_unit(rop), op->coeffs + 0, d, pN); + padic_val(rop) = d * op->val; + + if (alloc) + fmpz_clear(pN); + } + else /* len >= 2 */ + { + fmpz *y; + slong w; + + y = _fmpz_vec_init(op->length); + + _fmpz_vec_neg(y, op->coeffs, op->length); + fmpz_add_ui(y + 0, y + 0, 1); + w = _fmpz_vec_ord_p(y, op->length, p); + + if ((w < 2 && *p == WORD(2)) || w < 1) + { + flint_printf("ERROR (qadic_norm_analytic). w = %wd.\n", w); + abort(); + } + + _qadic_norm_analytic(padic_unit(rop), y, w, op->length, + ctx->a, ctx->j, ctx->len, p, N - d * op->val); + padic_val(rop) = d * op->val; + + _fmpz_vec_clear(y, op->length); + } +} + diff --git a/external/flint-2.4.3/qadic/norm_resultant.c b/external/flint-2.4.3/qadic/norm_resultant.c new file mode 100644 index 0000000..ab4b6b1 --- /dev/null +++ b/external/flint-2.4.3/qadic/norm_resultant.c @@ -0,0 +1,192 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "qadic.h" + +/* + Computes the characteristic polynomial of the $n \times n$ matrix $M$ + modulo \code{pN} using a division-free algorithm in $O(n^4)$ ring + operations. + + Only returns the determinant. + + Assumes that $n$ is at least $2$. + */ + +static +void _fmpz_mod_mat_det(fmpz_t rop, const fmpz *M, slong n, const fmpz_t pN) +{ + fmpz *F; + fmpz *a; + fmpz *A; + fmpz_t s; + slong t, i, j, p, k; + + F = _fmpz_vec_init(n); + a = _fmpz_vec_init((n-1) * n); + A = _fmpz_vec_init(n); + + fmpz_init(s); + + fmpz_neg(F + 0, M + 0*n + 0); + + for (t = 1; t < n; t++) + { + for (i = 0; i <= t; i++) + fmpz_set(a + 0*n + i, M + i*n + t); + + fmpz_set(A + 0, M + t*n + t); + + for (p = 1; p < t; p++) + { + for (i = 0; i <= t; i++) + { + fmpz_zero(s); + for (j = 0; j <= t; j++) + fmpz_addmul(s, M + i*n + j, a + (p-1)*n + j); + fmpz_mod(a + p*n + i, s, pN); + } + + fmpz_set(A + p, a + p*n + t); + } + + fmpz_zero(s); + for (j = 0; j <= t; j++) + fmpz_addmul(s, M + t*n + j, a + (t-1)*n + j); + fmpz_mod(A + t, s, pN); + + for (p = 0; p <= t; p++) + { + fmpz_sub(F + p, F + p, A + p); + for (k = 0; k < p; k++) + fmpz_submul(F + p, A + k, F + (p-k-1)); + fmpz_mod(F + p, F + p, pN); + } + } + + /* + Now [F{n-1}, F{n-2}, ..., F{0}, 1] is the + characteristic polynomial of the matrix M. + */ + + if (n % WORD(2) == 0) + { + fmpz_set(rop, F + (n-1)); + } + else + { + fmpz_neg(rop, F + (n-1)); + fmpz_mod(rop, rop, pN); + } + + _fmpz_vec_clear(F, n); + _fmpz_vec_clear(a, (n-1)*n); + _fmpz_vec_clear(A, n); + fmpz_clear(s); +} + +void _qadic_norm_resultant(fmpz_t rop, const fmpz *op, slong len, + const fmpz *a, const slong *j, slong lena, + const fmpz_t p, slong N) +{ + const slong d = j[lena - 1]; + + fmpz_t pN; + + fmpz_init(pN); + fmpz_pow_ui(pN, p, N); + + if (len == 1) + { + fmpz_powm_ui(rop, op + 0, d, pN); + } + else /* len >= 2 */ + { + { + const slong n = d + len - 1; + slong i, k; + fmpz *M; + + M = flint_calloc(n * n, sizeof(fmpz)); + + for (k = 0; k < len-1; k++) + { + for (i = 0; i < lena; i++) + { + M[k * n + k + (d - j[i])] = a[i]; + } + } + for (k = 0; k < d; k++) + { + for (i = 0; i < len; i++) + { + M[(len-1 + k) * n + k + (len-1 - i)] = op[i]; + } + } + + _fmpz_mod_mat_det(rop, M, n, pN); + + flint_free(M); + } + + /* + XXX: This part of the code is currently untested as the Conway + polynomials used for the extension Qq/Qp are monic. + */ + if (!fmpz_is_one(a + (lena - 1))) + { + fmpz_t f; + + fmpz_init(f); + fmpz_powm_ui(f, a + (lena - 1), len - 1, pN); + _padic_inv(f, f, p, N); + fmpz_mul(rop, f, rop); + fmpz_mod(rop, rop, pN); + fmpz_clear(f); + } + } + fmpz_clear(pN); +} + +void qadic_norm_resultant(padic_t rop, const qadic_t op, const qadic_ctx_t ctx) +{ + const slong N = padic_prec(rop); + const slong d = qadic_ctx_degree(ctx); + + /* N(p^v u) = p^{dv} N(u) */ + + if (qadic_is_zero(op) || d * op->val >= N) + { + padic_zero(rop); + } + else + { + _qadic_norm_resultant(padic_unit(rop), op->coeffs, op->length, + ctx->a, ctx->j, ctx->len, (&ctx->pctx)->p, + N - d * op->val); + padic_val(rop) = d * op->val; + } +} + diff --git a/external/flint-2.4.3/qadic/pow.c b/external/flint-2.4.3/qadic/pow.c new file mode 100644 index 0000000..b094d0d --- /dev/null +++ b/external/flint-2.4.3/qadic/pow.c @@ -0,0 +1,198 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "fmpz_mod_poly.h" +#include "qadic.h" + +void _qadic_pow(fmpz *rop, const fmpz *op, slong len, const fmpz_t e, + const fmpz *a, const slong *j, slong lena, + const fmpz_t p) +{ + const slong d = j[lena - 1]; + + if (fmpz_is_zero(e)) + { + fmpz_one(rop); + _fmpz_vec_zero(rop + 1, 2 * d - 1 - 1); + } + else if (fmpz_is_one(e)) + { + _fmpz_vec_set(rop, op, len); + _fmpz_vec_zero(rop + len, 2 * d - 1 - len); + } + else + { + ulong bit; + fmpz *v = _fmpz_vec_init(2 * d - 1); + fmpz *R, *S, *T; + + _fmpz_vec_zero(rop, 2 * d - 1); + + /* + Set bits to the bitmask with a 1 one place lower than the msb of e + */ + + bit = fmpz_bits(e) - 2; + + /* + Trial run without any polynomial arithmetic to determine the parity + of the number of swaps; then set R and S accordingly + */ + + { + unsigned int swaps = 0U; + ulong bit2 = bit; + if (fmpz_tstbit(e, bit2)) + swaps = ~swaps; + while (bit2--) + if (!fmpz_tstbit(e, bit2)) + swaps = ~swaps; + + if (swaps == 0U) + { + R = rop; + S = v; + } + else + { + R = v; + S = rop; + } + } + + /* + We unroll the first step of the loop, referring to {op, len} + */ + + _fmpz_poly_sqr(R, op, len); + _fmpz_mod_poly_reduce(R, 2 * len - 1, a, j, lena, p); + + if (fmpz_tstbit(e, bit)) + { + _fmpz_poly_mul(S, R, d, op, len); + _fmpz_mod_poly_reduce(S, d + len - 1, a, j, lena, p); + T = R; + R = S; + S = T; + } + + while (bit--) + { + if (fmpz_tstbit(e, bit)) + { + _fmpz_poly_sqr(S, R, d); + _fmpz_mod_poly_reduce(S, 2 * d - 1, a, j, lena, p); + _fmpz_poly_mul(R, S, d, op, len); + _fmpz_mod_poly_reduce(R, d + len - 1, a, j, lena, p); + } + else + { + _fmpz_poly_sqr(S, R, d); + _fmpz_mod_poly_reduce(S, 2 * d - 1, a, j, lena, p); + T = R; + R = S; + S = T; + } + } + + _fmpz_vec_clear(v, 2 * d - 1); + } +} + +void qadic_pow(qadic_t x, const qadic_t y, const fmpz_t e, const qadic_ctx_t ctx) +{ + const slong N = qadic_prec(x); + + if (fmpz_sgn(e) < 0) + { + flint_printf("Exception (qadic_pow). e < 0.\n"); + abort(); + } + + if (fmpz_is_zero(e)) + { + qadic_one(x); + } + else if (qadic_is_zero(y)) + { + qadic_zero(x); + } + else + { + fmpz_t val; /* N - e * val(y) */ + + fmpz_init_set(val, e); + fmpz_mul_si(val, val, y->val); + + if (fmpz_cmp_si(val, N) >= 0) + { + qadic_zero(x); + } + else if (fmpz_is_one(e)) + { + qadic_set(x, y, ctx); + } + else + { + const slong d = qadic_ctx_degree(ctx); + fmpz *t; + fmpz_t pow; + int alloc; + + alloc = _padic_ctx_pow_ui(pow, N - fmpz_get_si(val), &ctx->pctx); + + if (x == y) + { + t = _fmpz_vec_init(2 * d - 1); + } + else + { + padic_poly_fit_length(x, 2 * d - 1); + t = x->coeffs; + } + + _qadic_pow(t, y->coeffs, y->length, e, ctx->a, ctx->j, ctx->len, pow); + x->val = fmpz_get_si(val); + + if (x == y) + { + _fmpz_vec_clear(x->coeffs, x->alloc); + x->coeffs = t; + x->alloc = 2 * d - 1; + x->length = d; + } + else + { + _padic_poly_set_length(x, d); + } + _padic_poly_normalise(x); + + if (alloc) + fmpz_clear(pow); + } + fmpz_clear(val); + } +} + diff --git a/external/flint-2.4.3/qadic/profile/p-exp_balanced.c b/external/flint-2.4.3/qadic/profile/p-exp_balanced.c new file mode 100644 index 0000000..a8c2c75 --- /dev/null +++ b/external/flint-2.4.3/qadic/profile/p-exp_balanced.c @@ -0,0 +1,134 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +/* + Benchmarks for the q-adic exponential (balanced) routine. + + We consider the set-up with p = 17, N = 2^i, i = 0, ..., 19, + and compute the norm of p A mod p^N, where + + A = [a{0},...,a{d-1}], where a{i} = (3+i)^{3N}. + */ + +#include +#include +#include +#include +#include +#include + +#include "flint.h" +#include "fmpz.h" +#include "qadic.h" + +int +main(void) +{ + slong l, len = 20; + slong runs[] = { + 10000000, 1000000, 100000, 100000, 10000, + 10000, 1000, 1000, 1000, 100, + 10, 10, 10, 1, 1, + 1, 1, 1, 1, 1 + }; + slong N[] = { + 1, 2, 4, 8, 16, + 32, 64, 128, 256, 512, + 1024, WORD(1) << 11, WORD(1) << 12, WORD(1) << 13, WORD(1) << 14, + WORD(1) << 15, WORD(1) << 16, WORD(1) << 17, WORD(1) << 18, WORD(1) << 19 + }; + slong T[20] = {0}; + + flint_printf("Benchmark for q-adic exponential (balanced).\n"); + fflush(stdout); + +for (l = 0; l < len; l++) +{ + FLINT_TEST_INIT(state); + slong d = 5, i, n = N[l], r; + clock_t c0, c1; + long double cputime; + + fmpz_t p; + qadic_ctx_t ctx; + qadic_t b; + qadic_t z; + + + + fmpz_init_set_ui(p, 17); + + qadic_ctx_init_conway(ctx, p, d, n, n, "X", PADIC_VAL_UNIT); + + qadic_init(b); + qadic_init(z); + + padic_poly_fit_length(b, d); + _padic_poly_set_length(b, d); + b->val = 1; + + for (i = 0; i < d; i++) + { + fmpz_t f, pN; + + fmpz_init(f); + fmpz_init(pN); + fmpz_set_ui(f, 3 + i); + fmpz_pow_ui(pN, p, n - 1); + fmpz_powm_ui(b->coeffs + i, f, 3 * n, pN); + fmpz_clear(f); + fmpz_clear(pN); + } + _padic_poly_normalise(b); + + c0 = clock(); + for (r = runs[l]; (r); r--) + { + qadic_exp_balanced(z, b, ctx); + qadic_zero(z); + } + c1 = clock(); + + cputime = (long double) (c1 - c0) / (long double) CLOCKS_PER_SEC; + + T[l] = (slong) (cputime * (1000000000 / runs[l])); + + flint_printf("%2ld, %4XYXYXYXY, %8ld, %wd\n", + l, cputime, runs[l], T[l]); + + qadic_clear(b); + qadic_clear(z); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + flint_randclear(state); +} + + flint_printf("Output as a list:\n"); + for (l = 0; l < len; l++) + flint_printf("%wd, ", T[l]); + flint_printf("\n"); +} + diff --git a/external/flint-2.4.3/qadic/profile/p-exp_rectangular.c b/external/flint-2.4.3/qadic/profile/p-exp_rectangular.c new file mode 100644 index 0000000..cc075d8 --- /dev/null +++ b/external/flint-2.4.3/qadic/profile/p-exp_rectangular.c @@ -0,0 +1,134 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +/* + Benchmarks for the q-adic exponential (rectangular) routine. + + We consider the set-up with p = 17, N = 2^i, i = 0, ..., 19, + and compute the norm of p A mod p^N, where + + A = [a{0},...,a{d-1}], where a{i} = (3+i)^{3N}. + */ + +#include +#include +#include +#include +#include +#include + +#include "flint.h" +#include "fmpz.h" +#include "qadic.h" + +int +main(void) +{ + slong l, len = 20; + slong runs[] = { + 10000000, 1000000, 100000, 100000, 10000, + 10000, 1000, 1000, 1000, 100, + 10, 10, 1, 1, 1, + 1, 1, 1, 1, 1 + }; + slong N[] = { + 1, 2, 4, 8, 16, + 32, 64, 128, 256, 512, + 1024, WORD(1) << 11, WORD(1) << 12, WORD(1) << 13, WORD(1) << 14, + WORD(1) << 15, WORD(1) << 16, WORD(1) << 17, WORD(1) << 18, WORD(1) << 19 + }; + slong T[20] = {0}; + + flint_printf("Benchmark for q-adic exponential (rectangular).\n"); + fflush(stdout); + +for (l = 0; l < FLINT_MIN(16, len); l++) +{ + FLINT_TEST_INIT(state); + slong d = 5, i, n = N[l], r; + clock_t c0, c1; + long double cputime; + + fmpz_t p; + qadic_ctx_t ctx; + qadic_t b; + qadic_t z; + + + + fmpz_init_set_ui(p, 17); + + qadic_ctx_init_conway(ctx, p, d, n, n, "X", PADIC_VAL_UNIT); + + qadic_init(b); + qadic_init(z); + + padic_poly_fit_length(b, d); + _padic_poly_set_length(b, d); + b->val = 1; + + for (i = 0; i < d; i++) + { + fmpz_t f, pN; + + fmpz_init(f); + fmpz_init(pN); + fmpz_set_ui(f, 3 + i); + fmpz_pow_ui(pN, p, n - 1); + fmpz_powm_ui(b->coeffs + i, f, 3 * n, pN); + fmpz_clear(f); + fmpz_clear(pN); + } + _padic_poly_normalise(b); + + c0 = clock(); + for (r = runs[l]; (r); r--) + { + qadic_exp_rectangular(z, b, ctx); + qadic_zero(z); + } + c1 = clock(); + + cputime = (long double) (c1 - c0) / (long double) CLOCKS_PER_SEC; + + T[l] = (slong) (cputime * (1000000000 / runs[l])); + + flint_printf("%2ld, %4XYXYXYXY, %8ld, %wd\n", + l, cputime, runs[l], T[l]); + + qadic_clear(b); + qadic_clear(z); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + flint_randclear(state); +} + + flint_printf("Output as a list:\n"); + for (l = 0; l < len; l++) + flint_printf("%wd, ", T[l]); + flint_printf("\n"); +} + diff --git a/external/flint-2.4.3/qadic/profile/p-frobenius.c b/external/flint-2.4.3/qadic/profile/p-frobenius.c new file mode 100644 index 0000000..0cb2653 --- /dev/null +++ b/external/flint-2.4.3/qadic/profile/p-frobenius.c @@ -0,0 +1,134 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +/* + Benchmarks for the q-adic Frobenius routine. + + We consider the set-up with p = 17, N = 2^i, i = 0, ..., 19, + and compute Sigma(A) mod p^N, where + + A = [a{0},...,a{d-1}], where a{i} = (3+i)^{3N}. + */ + +#include +#include +#include +#include +#include +#include + +#include "flint.h" +#include "fmpz.h" +#include "qadic.h" + +int +main(void) +{ + slong l, len = 20; + slong runs[] = { + 10000, 1000, 100, 100, 100, + 100, 10, 10, 10, 10, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + }; + slong N[] = { + 1, 2, 4, 8, 16, + 32, 64, 128, 256, 512, + 1024, WORD(1) << 11, WORD(1) << 12, WORD(1) << 13, WORD(1) << 14, + WORD(1) << 15, WORD(1) << 16, WORD(1) << 17, WORD(1) << 18, WORD(1) << 19 + }; + slong T[20] = {0}; + + flint_printf("Benchmark for q-adic Frobenius.\n"); + fflush(stdout); + +for (l = 0; l < FLINT_MIN(16, len); l++) +{ + FLINT_TEST_INIT(state); + slong d = 97, i, n = N[l], r; + clock_t c0, c1; + long double cputime; + + fmpz_t p; + qadic_ctx_t ctx; + qadic_t a, z; + + + + fmpz_init_set_ui(p, 17); + + qadic_ctx_init_conway(ctx, p, d, n, n, "X", PADIC_VAL_UNIT); + + qadic_init(a); + qadic_init(z); + + padic_poly_fit_length(a, d); + _padic_poly_set_length(a, d); + a->val = 0; + + for (i = 0; i < d; i++) + { + fmpz_t f, pow; + + fmpz_init(f); + fmpz_init(pow); + fmpz_set_ui(f, 3 + i); + fmpz_pow_ui(pow, p, n); + fmpz_pow_ui(a->coeffs + i, f, 3 * n); + fmpz_mod(a->coeffs + i, a->coeffs + i, pow); + fmpz_clear(f); + fmpz_clear(pow); + } + _padic_poly_normalise(a); + + c0 = clock(); + for (r = runs[l]; (r); r--) + { + qadic_frobenius(z, a, 1, ctx); + qadic_zero(z); + } + c1 = clock(); + + cputime = (long double) (c1 - c0) / (long double) CLOCKS_PER_SEC; + + T[l] = (slong) (cputime * (1000000000 / runs[l])); + + flint_printf("%2ld, %6XYXYXYXY, %5ld, %wd\n", + l, cputime, runs[l], T[l]); + + qadic_clear(a); + qadic_clear(z); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + flint_randclear(state); +} + + flint_printf("Output as a list:\n"); + for (l = 0; l < len; l++) + flint_printf("%wd, ", T[l]); + flint_printf("\n"); +} + diff --git a/external/flint-2.4.3/qadic/profile/p-inv.c b/external/flint-2.4.3/qadic/profile/p-inv.c new file mode 100644 index 0000000..2cee726 --- /dev/null +++ b/external/flint-2.4.3/qadic/profile/p-inv.c @@ -0,0 +1,134 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +/* + Benchmarks for the q-adic inversion routine. + + We consider the set-up with p = 17, N = 2^i, i = 0, ..., 19, + and invert A mod p^N, where + + A = [a{0},...,a{d-1}], where a{i} = (3+i)^{3N}. + */ + +#include +#include +#include +#include +#include +#include + +#include "flint.h" +#include "fmpz.h" +#include "qadic.h" + +int +main(void) +{ + slong l, len = 20; + slong runs[] = { + 1000, 1000, 1000, 1000, 1000, + 1000, 100, 100, 100, 100, + 100, 10, 10, 1, 1, + 1, 1, 1, 1, 1 + }; + slong N[] = { + 1, 2, 4, 8, 16, + 32, 64, 128, 256, 512, + 1024, WORD(1) << 11, WORD(1) << 12, WORD(1) << 13, WORD(1) << 14, + WORD(1) << 15, WORD(1) << 16, WORD(1) << 17, WORD(1) << 18, WORD(1) << 19 + }; + slong T[20] = {0}; + + flint_printf("Benchmark for q-adic inversion.\n"); + fflush(stdout); + +for (l = 0; l < len; l++) +{ + FLINT_TEST_INIT(state); + slong d = 97, i, n = N[l], r; + clock_t c0, c1; + long double cputime; + + fmpz_t p; + qadic_ctx_t ctx; + qadic_t a, z; + + + + fmpz_init_set_ui(p, 17); + + qadic_ctx_init_conway(ctx, p, d, n, n, "X", PADIC_VAL_UNIT); + + qadic_init(a); + qadic_init(z); + + padic_poly_fit_length(a, d); + _padic_poly_set_length(a, d); + a->val = 0; + + for (i = 0; i < d; i++) + { + fmpz_t f, pow; + + fmpz_init(f); + fmpz_init(pow); + fmpz_set_ui(f, 3 + i); + fmpz_pow_ui(pow, p, n); + fmpz_pow_ui(a->coeffs + i, f, 3 * n); + fmpz_mod(a->coeffs + i, a->coeffs + i, pow); + fmpz_clear(f); + fmpz_clear(pow); + } + _padic_poly_normalise(a); + + c0 = clock(); + for (r = runs[l]; (r); r--) + { + qadic_inv(z, a, ctx); + qadic_zero(z); + } + c1 = clock(); + + cputime = (long double) (c1 - c0) / (long double) CLOCKS_PER_SEC; + + T[l] = (slong) (cputime * (1000000000 / runs[l])); + + flint_printf("%2ld, %4XYXYXYXY, %8ld, %wd\n", + l, cputime, runs[l], T[l]); + + qadic_clear(a); + qadic_clear(z); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + flint_randclear(state); +} + + flint_printf("Output as a list:\n"); + for (l = 0; l < len; l++) + flint_printf("%wd, ", T[l]); + flint_printf("\n"); +} + diff --git a/external/flint-2.4.3/qadic/profile/p-log_balanced.c b/external/flint-2.4.3/qadic/profile/p-log_balanced.c new file mode 100644 index 0000000..85c182d --- /dev/null +++ b/external/flint-2.4.3/qadic/profile/p-log_balanced.c @@ -0,0 +1,137 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +/* + Benchmarks for the q-adic logarithm (balanced). + + We consider the set-up with p = 17, N = 2^i, i = 0, ..., 19, + and compute the logarithm of E = 1 + p A mod p^N, where + + A = [a{0},...,a{d-1}], where a{i} = (3+i)^{3N}. + */ + +#include +#include +#include +#include +#include +#include + +#include "flint.h" +#include "fmpz.h" +#include "qadic.h" + +int +main(void) +{ + slong l, len = 20; + slong runs[] = { + 10000000, 100000, 100000, 10000, 10000, + 1000, 1000, 1000, 100, 100, + 10, 10, 1, 1, 1, + 1, 1, 1, 1, 1 + }; + slong N[] = { + 1, 2, 4, 8, 16, + 32, 64, 128, 256, 512, + 1024, WORD(1) << 11, WORD(1) << 12, WORD(1) << 13, WORD(1) << 14, + WORD(1) << 15, WORD(1) << 16, WORD(1) << 17, WORD(1) << 18, WORD(1) << 19 + }; + slong T[20] = {0}; + + flint_printf("Benchmark for q-adic logarithm (balanced).\n"); + fflush(stdout); + +for (l = 0; l < len; l++) +{ + FLINT_TEST_INIT(state); + slong d = 5, i, n = N[l], r; + clock_t c0, c1; + long double cputime; + + fmpz_t p; + qadic_ctx_t ctx; + qadic_t e, z; + + + + fmpz_init_set_ui(p, 17); + + qadic_ctx_init_conway(ctx, p, d, n, n, "X", PADIC_VAL_UNIT); + + qadic_init(e); + qadic_init(z); + + padic_poly_fit_length(e, d); + _padic_poly_set_length(e, d); + e->val = 0; + + for (i = 0; i < d; i++) + { + fmpz_t f, pow; + + fmpz_init(f); + fmpz_init(pow); + fmpz_set_ui(f, 3 + i); + fmpz_pow_ui(pow, p, n); + fmpz_pow_ui(e->coeffs + i, f, 3 * n); + fmpz_mul(e->coeffs + i, e->coeffs + i, p); + if (i == 0) + fmpz_add_ui(e->coeffs + 0, e->coeffs + 0, 1); + fmpz_mod(e->coeffs + i, e->coeffs + i, pow); + fmpz_clear(f); + fmpz_clear(pow); + } + _padic_poly_normalise(e); + + c0 = clock(); + for (r = runs[l]; (r); r--) + { + qadic_log_balanced(z, e, ctx); + qadic_zero(z); + } + c1 = clock(); + + cputime = (long double) (c1 - c0) / (long double) CLOCKS_PER_SEC; + + T[l] = (slong) (cputime * (1000000000 / runs[l])); + + flint_printf("%2ld, %4XYXYXYXY, %8ld, %wd\n", + l, cputime, runs[l], T[l]); + + qadic_clear(e); + qadic_clear(z); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + flint_randclear(state); +} + + flint_printf("Output as a list:\n"); + for (l = 0; l < len; l++) + flint_printf("%wd, ", T[l]); + flint_printf("\n"); +} + diff --git a/external/flint-2.4.3/qadic/profile/p-log_rectangular.c b/external/flint-2.4.3/qadic/profile/p-log_rectangular.c new file mode 100644 index 0000000..323ed0a --- /dev/null +++ b/external/flint-2.4.3/qadic/profile/p-log_rectangular.c @@ -0,0 +1,137 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +/* + Benchmarks for the q-adic logarithm (rectangular). + + We consider the set-up with p = 17, N = 2^i, i = 0, ..., 19, + and compute the logarithm of E = 1 + p A mod p^N, where + + A = [a{0},...,a{d-1}], where a{i} = (3+i)^{3N}. + */ + +#include +#include +#include +#include +#include +#include + +#include "flint.h" +#include "fmpz.h" +#include "qadic.h" + +int +main(void) +{ + slong l, len = 20; + slong runs[] = { + 10000000, 100000, 100000, 10000, 10000, + 1000, 1000, 1000, 100, 100, + 10, 10, 1, 1, 1, + 1, 1, 1, 1, 1 + }; + slong N[] = { + 1, 2, 4, 8, 16, + 32, 64, 128, 256, 512, + 1024, WORD(1) << 11, WORD(1) << 12, WORD(1) << 13, WORD(1) << 14, + WORD(1) << 15, WORD(1) << 16, WORD(1) << 17, WORD(1) << 18, WORD(1) << 19 + }; + slong T[20] = {0}; + + flint_printf("Benchmark for q-adic logarithm (rectangular).\n"); + fflush(stdout); + +for (l = 0; l < FLINT_MIN(16, len); l++) +{ + FLINT_TEST_INIT(state); + slong d = 5, i, n = N[l], r; + clock_t c0, c1; + long double cputime; + + fmpz_t p; + qadic_ctx_t ctx; + qadic_t e, z; + + + + fmpz_init_set_ui(p, 17); + + qadic_ctx_init_conway(ctx, p, d, n, n, "X", PADIC_VAL_UNIT); + + qadic_init(e); + qadic_init(z); + + padic_poly_fit_length(e, d); + _padic_poly_set_length(e, d); + e->val = 0; + + for (i = 0; i < d; i++) + { + fmpz_t f, pow; + + fmpz_init(f); + fmpz_init(pow); + fmpz_set_ui(f, 3 + i); + fmpz_pow_ui(pow, p, n); + fmpz_pow_ui(e->coeffs + i, f, 3 * n); + fmpz_mul(e->coeffs + i, e->coeffs + i, p); + if (i == 0) + fmpz_add_ui(e->coeffs + 0, e->coeffs + 0, 1); + fmpz_mod(e->coeffs + i, e->coeffs + i, pow); + fmpz_clear(f); + fmpz_clear(pow); + } + _padic_poly_normalise(e); + + c0 = clock(); + for (r = runs[l]; (r); r--) + { + qadic_log_rectangular(z, e, ctx); + qadic_zero(z); + } + c1 = clock(); + + cputime = (long double) (c1 - c0) / (long double) CLOCKS_PER_SEC; + + T[l] = (slong) (cputime * (1000000000 / runs[l])); + + flint_printf("%2ld, %4XYXYXYXY, %8ld, %wd\n", + l, cputime, runs[l], T[l]); + + qadic_clear(e); + qadic_clear(z); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + flint_randclear(state); +} + + flint_printf("Output as a list:\n"); + for (l = 0; l < len; l++) + flint_printf("%wd, ", T[l]); + flint_printf("\n"); +} + diff --git a/external/flint-2.4.3/qadic/profile/p-mul.c b/external/flint-2.4.3/qadic/profile/p-mul.c new file mode 100644 index 0000000..5499e27 --- /dev/null +++ b/external/flint-2.4.3/qadic/profile/p-mul.c @@ -0,0 +1,148 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +/* + Benchmarks for the q-adic multiplication routine. + + We consider the set-up with p = 17, N = 2^i, i = 0, ..., 19, + and compute A*B mod p^N, where + + A = [a{0},...,a{d-1}], where a{i} = (3+i)^{3N}, + B = [b{0},...,b{d-1}], where b{i} = (5+2*i)^{3N}, + */ + +#include +#include +#include +#include +#include +#include + +#include "flint.h" +#include "fmpz.h" +#include "qadic.h" + +int +main(void) +{ + slong l, len = 20; + slong runs[] = { + 100000, 10000, 10000, 10000, 10000, + 1000, 1000, 1000, 1000, 100, + 100, 10, 10, 10, 1, + 1, 1, 1, 1, 1 + }; + slong N[] = { + 1, 2, 4, 8, 16, + 32, 64, 128, 256, 512, + 1024, WORD(1) << 11, WORD(1) << 12, WORD(1) << 13, WORD(1) << 14, + WORD(1) << 15, WORD(1) << 16, WORD(1) << 17, WORD(1) << 18, WORD(1) << 19 + }; + slong T[20] = {0}; + + flint_printf("Benchmark for q-adic multiplication.\n"); + fflush(stdout); + +for (l = 0; l < len; l++) +{ + FLINT_TEST_INIT(state); + slong d = 97, i, n = N[l], r; + clock_t c0, c1; + long double cputime; + + fmpz_t p; + qadic_ctx_t ctx; + qadic_t a, b, z; + + + + fmpz_init_set_ui(p, 17); + + qadic_ctx_init_conway(ctx, p, d, n, n, "X", PADIC_VAL_UNIT); + + qadic_init(a); + qadic_init(b); + qadic_init(z); + + padic_poly_fit_length(a, d); + _padic_poly_set_length(a, d); + a->val = 0; + + padic_poly_fit_length(b, d); + _padic_poly_set_length(b, d); + b->val = 0; + + for (i = 0; i < d; i++) + { + fmpz_t f, pow; + + fmpz_init(f); + fmpz_init(pow); + fmpz_pow_ui(pow, p, n); + + fmpz_set_ui(f, 3 + i); + fmpz_pow_ui(a->coeffs + i, f, 3 * n); + fmpz_mod(a->coeffs + i, a->coeffs + i, pow); + + fmpz_set_ui(f, 5 + 2*i); + fmpz_pow_ui(b->coeffs + i, f, 3 * n); + fmpz_mod(b->coeffs + i, b->coeffs + i, pow); + + fmpz_clear(f); + fmpz_clear(pow); + } + _padic_poly_normalise(a); + _padic_poly_normalise(b); + + c0 = clock(); + for (r = runs[l]; (r); r--) + { + qadic_mul(z, a, b, ctx); + qadic_zero(z); + } + c1 = clock(); + + cputime = (long double) (c1 - c0) / (long double) CLOCKS_PER_SEC; + + T[l] = (slong) (cputime * (1000000000 / runs[l])); + + flint_printf("%2ld, %4XYXYXYXY, %8ld, %wd\n", + l, cputime, runs[l], T[l]); + + qadic_clear(a); + qadic_clear(b); + qadic_clear(z); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + flint_randclear(state); +} + + flint_printf("Output as a list:\n"); + for (l = 0; l < len; l++) + flint_printf("%wd, ", T[l]); + flint_printf("\n"); +} + diff --git a/external/flint-2.4.3/qadic/profile/p-norm_analytic.c b/external/flint-2.4.3/qadic/profile/p-norm_analytic.c new file mode 100644 index 0000000..bdc2536 --- /dev/null +++ b/external/flint-2.4.3/qadic/profile/p-norm_analytic.c @@ -0,0 +1,138 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +/* + Benchmarks for the q-adic norm routine. + + We consider the set-up with p = 17, N = 2^i, i = 0, ..., 19, + and compute the norm of E = 1 + p A mod p^N, where + + A = [a{0},...,a{d-1}], where a{i} = (3+i)^{3N}. + */ + +#include +#include +#include +#include +#include +#include + +#include "flint.h" +#include "fmpz.h" +#include "qadic.h" + +int +main(void) +{ + slong l, len = 20; + slong runs[] = { + 10000000, 100000, 10000, 10000, 10000, + 1000, 1000, 1000, 100, 100, + 10, 10, 1, 1, 1, + 1, 1, 1, 1, 1 + }; + slong N[] = { + 1, 2, 4, 8, 16, + 32, 64, 128, 256, 512, + 1024, WORD(1) << 11, WORD(1) << 12, WORD(1) << 13, WORD(1) << 14, + WORD(1) << 15, WORD(1) << 16, WORD(1) << 17, WORD(1) << 18, WORD(1) << 19 + }; + slong T[20] = {0}; + + flint_printf("Benchmark for q-adic norm (analytic).\n"); + fflush(stdout); + +for (l = 0; l < len; l++) +{ + FLINT_TEST_INIT(state); + slong d = 5, i, n = N[l], r; + clock_t c0, c1; + long double cputime; + + fmpz_t p; + qadic_ctx_t ctx; + qadic_t e; + padic_t z; + + + + fmpz_init_set_ui(p, 17); + + qadic_ctx_init_conway(ctx, p, d, n, n, "X", PADIC_VAL_UNIT); + + qadic_init(e); + padic_init(z); + + padic_poly_fit_length(e, d); + _padic_poly_set_length(e, d); + e->val = 0; + + for (i = 0; i < d; i++) + { + fmpz_t f, pow; + + fmpz_init(f); + fmpz_init(pow); + fmpz_set_ui(f, 3 + i); + fmpz_pow_ui(pow, p, n); + fmpz_pow_ui(e->coeffs + i, f, 3 * n); + fmpz_mul(e->coeffs + i, e->coeffs + i, p); + if (i == 0) + fmpz_add_ui(e->coeffs + 0, e->coeffs + 0, 1); + fmpz_mod(e->coeffs + i, e->coeffs + i, pow); + fmpz_clear(f); + fmpz_clear(pow); + } + _padic_poly_normalise(e); + + c0 = clock(); + for (r = runs[l]; (r); r--) + { + qadic_norm_analytic(z, e, ctx); + padic_zero(z); + } + c1 = clock(); + + cputime = (long double) (c1 - c0) / (long double) CLOCKS_PER_SEC; + + T[l] = (slong) (cputime * (1000000000 / runs[l])); + + flint_printf("%2ld, %4XYXYXYXY, %8ld, %wd\n", + l, cputime, runs[l], T[l]); + + qadic_clear(e); + padic_clear(z); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + flint_randclear(state); +} + + flint_printf("Output as a list:\n"); + for (l = 0; l < len; l++) + flint_printf("%wd, ", T[l]); + flint_printf("\n"); +} + diff --git a/external/flint-2.4.3/qadic/profile/p-norm_resultant.c b/external/flint-2.4.3/qadic/profile/p-norm_resultant.c new file mode 100644 index 0000000..c8ce1fe --- /dev/null +++ b/external/flint-2.4.3/qadic/profile/p-norm_resultant.c @@ -0,0 +1,138 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +/* + Benchmarks for the q-adic norm routine. + + We consider the set-up with p = 17, N = 2^i, i = 0, ..., 19, + and compute the norm of E = 1 + p A mod p^N, where + + A = [a{0},...,a{d-1}], where a{i} = (3+i)^{3N}. + */ + +#include +#include +#include +#include +#include +#include + +#include "flint.h" +#include "fmpz.h" +#include "qadic.h" + +int +main(void) +{ + slong l, len = 20; + slong runs[] = { + 1000000, 10000, 10000, 10000, 10000, + 10000, 10000, 1000, 1000, 1000, + 100, 100, 10, 10, 1, + 1, 1, 1, 1, 1 + }; + slong N[] = { + 1, 2, 4, 8, 16, + 32, 64, 128, 256, 512, + 1024, WORD(1) << 11, WORD(1) << 12, WORD(1) << 13, WORD(1) << 14, + WORD(1) << 15, WORD(1) << 16, WORD(1) << 17, WORD(1) << 18, WORD(1) << 19 + }; + slong T[20] = {0}; + + flint_printf("Benchmark for q-adic norm (resultant).\n"); + fflush(stdout); + +for (l = 0; l < len; l++) +{ + FLINT_TEST_INIT(state); + slong d = 5, i, n = N[l], r; + clock_t c0, c1; + long double cputime; + + fmpz_t p; + qadic_ctx_t ctx; + qadic_t e; + padic_t z; + + + + fmpz_init_set_ui(p, 17); + + qadic_ctx_init_conway(ctx, p, d, n, n, "X", PADIC_VAL_UNIT); + + qadic_init(e); + padic_init(z); + + padic_poly_fit_length(e, d); + _padic_poly_set_length(e, d); + e->val = 0; + + for (i = 0; i < d; i++) + { + fmpz_t f, pow; + + fmpz_init(f); + fmpz_init(pow); + fmpz_set_ui(f, 3 + i); + fmpz_pow_ui(pow, p, n); + fmpz_pow_ui(e->coeffs + i, f, 3 * n); + fmpz_mul(e->coeffs + i, e->coeffs + i, p); + if (i == 0) + fmpz_add_ui(e->coeffs + 0, e->coeffs + 0, 1); + fmpz_mod(e->coeffs + i, e->coeffs + i, pow); + fmpz_clear(f); + fmpz_clear(pow); + } + _padic_poly_normalise(e); + + c0 = clock(); + for (r = runs[l]; (r); r--) + { + qadic_norm_resultant(z, e, ctx); + padic_zero(z); + } + c1 = clock(); + + cputime = (long double) (c1 - c0) / (long double) CLOCKS_PER_SEC; + + T[l] = (slong) (cputime * (1000000000 / runs[l])); + + flint_printf("%2ld, %4XYXYXYXY, %8ld, %wd\n", + l, cputime, runs[l], T[l]); + + qadic_clear(e); + padic_clear(z); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + flint_randclear(state); +} + + flint_printf("Output as a list:\n"); + for (l = 0; l < len; l++) + flint_printf("%wd, ", T[l]); + flint_printf("\n"); +} + diff --git a/external/flint-2.4.3/qadic/profile/p-sqrt.c b/external/flint-2.4.3/qadic/profile/p-sqrt.c new file mode 100644 index 0000000..0c40057 --- /dev/null +++ b/external/flint-2.4.3/qadic/profile/p-sqrt.c @@ -0,0 +1,145 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +/* + Benchmarks for the q-adic square root routine. + + We consider the set-up with p = 17, N = 2^i, i = 0, ..., 19, + and compute the square root of B = A^2, A mod p^N, where + + A = [a{0},...,a{d-1}], where a{i} = (3+i)^{3N}. + */ + +#include +#include +#include +#include +#include +#include + +#include "flint.h" +#include "fmpz.h" +#include "qadic.h" + +int +main(void) +{ + slong l, len = 20; + slong runs[] = { + 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, + 10, 10, 10, 1, 1, + 1, 1, 1, 1, 1 + }; + slong N[] = { + 1, 2, 4, 8, 16, + 32, 64, 128, 256, 512, + 1024, WORD(1) << 11, WORD(1) << 12, WORD(1) << 13, WORD(1) << 14, + WORD(1) << 15, WORD(1) << 16, WORD(1) << 17, WORD(1) << 18, WORD(1) << 19 + }; + slong T[20] = {0}; + + flint_printf("Benchmark for q-adic square root.\n"); + fflush(stdout); + +for (l = 0; l < len; l++) +{ + FLINT_TEST_INIT(state); + slong d = 97, i, n = N[l], r; + clock_t c0, c1; + long double cputime; + + fmpz_t p; + qadic_ctx_t ctx; + qadic_t a, b, z; + + + + fmpz_init_set_ui(p, 17); + + qadic_ctx_init_conway(ctx, p, d, n, n, "X", PADIC_VAL_UNIT); + + qadic_init(a); + qadic_init(b); + qadic_init(z); + + padic_poly_fit_length(a, d); + _padic_poly_set_length(a, d); + a->val = 0; + + for (i = 0; i < d; i++) + { + fmpz_t f, pow; + + fmpz_init(f); + fmpz_init(pow); + fmpz_set_ui(f, 3 + i); + fmpz_pow_ui(pow, p, n); + fmpz_pow_ui(a->coeffs + i, f, 3 * n); + fmpz_mod(a->coeffs + i, a->coeffs + i, pow); + fmpz_clear(f); + fmpz_clear(pow); + } + _padic_poly_normalise(a); + qadic_mul(b, a, a, ctx); + + c0 = clock(); + for (r = runs[l]; (r); r--) + { + qadic_sqrt(z, b, ctx); + qadic_zero(z); + } + c1 = clock(); + + qadic_sqrt(z, b, ctx); + qadic_mul(z, z, z, ctx); + if (!qadic_equal(b, z)) + { + flint_printf("FAIL:\n"); + abort(); + } + + cputime = (long double) (c1 - c0) / (long double) CLOCKS_PER_SEC; + + T[l] = (slong) (cputime * (1000000000 / runs[l])); + + flint_printf("%2ld, %4XYXYXYXY, %8ld, %wd\n", + l, cputime, runs[l], T[l]); + + qadic_clear(a); + qadic_clear(b); + qadic_clear(z); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + flint_randclear(state); +} + + flint_printf("Output as a list:\n"); + for (l = 0; l < len; l++) + flint_printf("%wd, ", T[l]); + flint_printf("\n"); +} + diff --git a/external/flint-2.4.3/qadic/profile/p-teichmuller.c b/external/flint-2.4.3/qadic/profile/p-teichmuller.c new file mode 100644 index 0000000..337fdf3 --- /dev/null +++ b/external/flint-2.4.3/qadic/profile/p-teichmuller.c @@ -0,0 +1,126 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +/* + Benchmarks for the q-adic square root routine. + + We consider the set-up with p = 17, N = 2^i, i = 0, ..., 19, + and compute the Teichmuller lift of C where + + C = [c{0},...,c{d-1}], where c{i} = (3+i) mod p. + */ + +#include +#include +#include +#include +#include +#include + +#include "flint.h" +#include "fmpz.h" +#include "qadic.h" + +int +main(void) +{ + slong l, len = 20; + slong runs[] = { + 100, 10, 10, 10, 10, + 10, 10, 10, 10, 10, + 10, 10, 10, 1, 1, + 1, 1, 1, 1, 1 + }; + slong N[] = { + 1, 2, 4, 8, 16, + 32, 64, 128, 256, 512, + 1024, WORD(1) << 11, WORD(1) << 12, WORD(1) << 13, WORD(1) << 14, + WORD(1) << 15, WORD(1) << 16, WORD(1) << 17, WORD(1) << 18, WORD(1) << 19 + }; + slong T[20] = {0}; + + flint_printf("Benchmark for q-adic Teichmuller.\n"); + fflush(stdout); + +for (l = 0; l < len; l++) +{ + FLINT_TEST_INIT(state); + slong d = 97, i, n = N[l], r; + clock_t c0, c1; + long double cputime; + + fmpz_t p; + qadic_ctx_t ctx; + qadic_t c, z; + + + + fmpz_init_set_ui(p, 17); + + qadic_ctx_init_conway(ctx, p, d, n, n, "X", PADIC_VAL_UNIT); + + qadic_init(c); + qadic_init(z); + + padic_poly_fit_length(c, d); + _padic_poly_set_length(c, d); + c->val = 0; + + for (i = 0; i < d; i++) + { + fmpz_set_ui(c->coeffs + i, 3 + i); + fmpz_mod(c->coeffs + i, c->coeffs + i, p); + } + _padic_poly_normalise(c); + + c0 = clock(); + for (r = runs[l]; (r); r--) + { + qadic_teichmuller(z, c, ctx); + qadic_zero(z); + } + c1 = clock(); + + cputime = (long double) (c1 - c0) / (long double) CLOCKS_PER_SEC; + + T[l] = (slong) (cputime * (1000000000 / runs[l])); + + flint_printf("%2ld, %4XYXYXYXY, %8ld, %wd\n", + l, cputime, runs[l], T[l]); + + qadic_clear(c); + qadic_clear(z); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + flint_randclear(state); +} + + flint_printf("Output as a list:\n"); + for (l = 0; l < len; l++) + flint_printf("%wd, ", T[l]); + flint_printf("\n"); +} + diff --git a/external/flint-2.4.3/qadic/profile/p-trace.c b/external/flint-2.4.3/qadic/profile/p-trace.c new file mode 100644 index 0000000..c473486 --- /dev/null +++ b/external/flint-2.4.3/qadic/profile/p-trace.c @@ -0,0 +1,135 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +/* + Benchmarks for the q-adic trace routine. + + We consider the set-up with p = 17, N = 2^i, i = 0, ..., 19, + and compute the trace of A mod p^N, where + + A = [a{0},...,a{d-1}], where a{i} = (3+i)^{3N}. + */ + +#include +#include +#include +#include +#include +#include + +#include "flint.h" +#include "fmpz.h" +#include "qadic.h" + +int +main(void) +{ + slong l, len = 20; + slong runs[] = { + 100000, 100000, 100000, 100000, 100000, + 100000, 100000, 100000, 100000, 100000, + 10000, 10000, 1000, 1000, 1000, + 100, 100, 10, 10, 10 + }; + slong N[] = { + 1, 2, 4, 8, 16, + 32, 64, 128, 256, 512, + 1024, WORD(1) << 11, WORD(1) << 12, WORD(1) << 13, WORD(1) << 14, + WORD(1) << 15, WORD(1) << 16, WORD(1) << 17, WORD(1) << 18, WORD(1) << 19 + }; + slong T[20] = {0}; + + flint_printf("Benchmark for q-adic trace.\n"); + fflush(stdout); + +for (l = 0; l < len; l++) +{ + FLINT_TEST_INIT(state); + slong d = 97, i, n = N[l], r; + clock_t c0, c1; + long double cputime; + + fmpz_t p; + qadic_ctx_t ctx; + qadic_t a; + padic_t z; + + + + fmpz_init_set_ui(p, 17); + + qadic_ctx_init_conway(ctx, p, d, n, n, "X", PADIC_VAL_UNIT); + + qadic_init(a); + padic_init(z); + + padic_poly_fit_length(a, d); + _padic_poly_set_length(a, d); + a->val = 0; + + for (i = 0; i < d; i++) + { + fmpz_t f, pow; + + fmpz_init(f); + fmpz_init(pow); + fmpz_set_ui(f, 3 + i); + fmpz_pow_ui(pow, p, n); + fmpz_pow_ui(a->coeffs + i, f, 3 * n); + fmpz_mod(a->coeffs + i, a->coeffs + i, pow); + fmpz_clear(f); + fmpz_clear(pow); + } + _padic_poly_normalise(a); + + c0 = clock(); + for (r = runs[l]; (r); r--) + { + qadic_trace(z, a, ctx); + padic_zero(z); + } + c1 = clock(); + + cputime = (long double) (c1 - c0) / (long double) CLOCKS_PER_SEC; + + T[l] = (slong) (cputime * (1000000000 / runs[l])); + + flint_printf("%2ld, %4XYXYXYXY, %8ld, %wd\n", + l, cputime, runs[l], T[l]); + + qadic_clear(a); + padic_clear(z); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + flint_randclear(state); +} + + flint_printf("Output as a list:\n"); + for (l = 0; l < len; l++) + flint_printf("%wd, ", T[l]); + flint_printf("\n"); +} + diff --git a/external/flint-2.4.3/qadic/set_fmpz_poly.c b/external/flint-2.4.3/qadic/set_fmpz_poly.c new file mode 100644 index 0000000..bdbf82c --- /dev/null +++ b/external/flint-2.4.3/qadic/set_fmpz_poly.c @@ -0,0 +1,47 @@ +/*============================================================================ + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "qadic.h" + +void qadic_set_fmpz_poly(qadic_t rop, const fmpz_poly_t op, + const qadic_ctx_t ctx) +{ + const slong len = op->length; + + if (len == 0) + { + qadic_zero(rop); + } + else + { + padic_poly_fit_length(rop, len); + _padic_poly_set_length(rop, len); + _fmpz_vec_set(rop->coeffs, op->coeffs, len); + rop->val = 0; + + qadic_reduce(rop, ctx); + } +} + diff --git a/external/flint-2.4.3/qadic/sqrt.c b/external/flint-2.4.3/qadic/sqrt.c new file mode 100644 index 0000000..9591408 --- /dev/null +++ b/external/flint-2.4.3/qadic/sqrt.c @@ -0,0 +1,850 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include + +#include "nmod_mat.h" + +#include "fmpz_mod_poly.h" +#include "qadic.h" + +/* + FILE DOCUMENTATION. + + This file contains routines for computing square roots in + finite fields and Hensel lifting. + + - _find_nonresidue() + - _artin_schreier_preimage() + - _fmpz_mod_poly_sqrtmod_p() + - _fmpz_mod_poly_sqrtmod_2() + - _qadic_sqrt_p() + - _qadic_sqrt() + - qadic_sqrt() + */ + +/* + Sets \code{(rop,d)} to a non-residue in $\mathbf{F_q}$ for odd $p$ + and $d \geq 2$. + */ +static void _find_nonresidue(fmpz *rop, + const fmpz *a, const slong *j, slong lena, + const fmpz_t p) +{ + const slong d = j[lena - 1]; + + fmpz *w; + fmpz_t pm1, z; + slong i; + + w = _fmpz_vec_init(2 * d - 1); + fmpz_init(pm1); + fmpz_init(z); + + fmpz_sub_ui(pm1, p, 1); + fmpz_pow_ui(z, p, d); + fmpz_sub_ui(z, z, 1); + fmpz_fdiv_q_2exp(z, z, 1); + + /* + Find a non-residue g; + uses stack-based depth first traversal starting from [0,...,0,1] + */ + _fmpz_vec_zero(rop, d); + fmpz_one(rop + (d - 1)); + + for (i = d; i > 0; ) + { + if (i == d) + { + /* Consider this element, rop^{(q-1)/2} == -1 ? */ + _qadic_pow(w, rop, d, z, a, j, lena, p); + if (fmpz_equal(w + 0, pm1) && _fmpz_vec_is_zero(w + 1, d - 1)) + break; + + /* Backtrace, find the next element */ + for (i--; i >= 0 && fmpz_equal(rop + i, pm1); i--) ; + if (i >= 0) + { + fmpz_add_ui(rop + i, rop + i, 1); + i++; + } + } + else + { + _fmpz_vec_zero(rop + i, d - i); + i = d; + } + } + + _fmpz_vec_clear(w, 2 * d - 1); + fmpz_clear(pm1); + fmpz_clear(z); +} + +/* + Given an element $d$ as \code{(op,len)}, returns whether it has a + preimage $u$ under the Artin Schreier map $Y \mapsto Y^2 + Y$, and + if so sets \code{(rop,d)} to $u$. + + In this case, the other preimage is given by $u + 1$. This + completes the set of preimages as the kernel of the Artin Schreier + map is $\mathbf{F}_2$. + + The value of \code{(rop,d)}$ is undefined when the return value + is zero. + */ +int +_artin_schreier_preimage(fmpz *rop, const fmpz *op, slong len, + const fmpz *a, const slong *j, slong lena) +{ + const slong d = j[lena - 1]; + const fmpz_t p = {WORD(2)}; + + int ans; + + fmpz *e, *f; + nmod_mat_t A; + slong i, k, rk, *P; + + e = _fmpz_vec_init(d); + f = _fmpz_vec_init(2 * d - 1); + + nmod_mat_init(A, d, d, 2); + P = flint_malloc(d * sizeof(slong)); + + /* Construct Artin Schreier matrix ------------------------------------- */ + + for (i = 0; i < d; i++) + { + fmpz_one(e + i); + + _fmpz_poly_sqr(f, e, i+1); + _fmpz_poly_reduce(f, 2*(i+1)-1, a, j, lena); + fmpz_add_ui(f + i, f + i, 1); + _fmpz_vec_scalar_mod_fmpz(f, f, d, p); + + for (k = 0; k < d; k++) + { + nmod_mat_entry(A, k, i) = (mp_limb_t) f[k]; + } + fmpz_zero(e + i); + } + + /* Perform LUP decomposition ------------------------------------------- */ + + /* + Write LU = PA and r = rank(A) so that U is in row echelon form + with only the top r rows non-zero, and L is lower unit triangular + truncated to r columns. + + We know that Y^2 + Y = 0 if and only if Y is in the base field, + i.e., dim ker(A) = 1 and rank(A) = d-1. + + Consider the linear system A x = b, which we can then write as + LU x = Pb, hence L y = Pb and U x = y. + */ + + rk = nmod_mat_lu(P, A, 0); + + assert(rk == d-1); + + /* Solve for a preimage of (op,len) ------------------------------------ */ + + _fmpz_vec_zero(rop, d); + + for (i = 0; i < d; i++) + { + rop[i] = P[i] < len ? op[P[i]] : 0; + for (k = 0; k < i; k++) + rop[i] ^= nmod_mat_entry(A, i, k) & rop[k]; + } + + ans = (rop[d-1] == 0); + + if (ans) + { + slong c; + + for (c = 0; c < d; c++) + if (nmod_mat_entry(A, c, c) == 0) + break; + + for (k = d - 1; k > c; k--) + { + rop[k] = rop[k-1]; + + if ((rop[k])) + for (i = k - 2; i >= 0; i--) + rop[i] ^= nmod_mat_entry(A, i, k); + } + rop[k] = 0; + for (k--; k >= 0; k--) + { + if ((rop[k])) + for (i = k - 1; i >= 0; i--) + rop[i] ^= nmod_mat_entry(A, i, k); + } + } + + /* Clean-up ------------------------------------------------------------ */ + + _fmpz_vec_clear(e, d); + _fmpz_vec_clear(f, 2 * d - 1); + nmod_mat_clear(A); + flint_free(P); + + return ans; +} + +/* + Returns whether the non-zero element \code{(op, len)} is a square, + and if so sets \code{(rop, 2 * d - 1)} to its square root. + + Assumes that $p$ is an odd prime. + + Assumes that $d \geq 1$. + + Does not support aliasing. + */ +static int +_fmpz_mod_poly_sqrtmod_p(fmpz *rop, const fmpz *op, slong len, + const fmpz *a, const slong *j, slong lena, + const fmpz_t p) +{ + const slong d = j[lena - 1]; + int ans; + + /* + When $q \equiv 3 \pmod{4}$... + + A non-zero element $x$ is a square if and only if $x^{(q-1)/2} = 1$, + and in this case one of its square roots is given by $x^{(q+1)/4}$. + + To avoid recomputation of powers of $x$, we compute $x^{(q-3)/4}$, + multiply this by $x$ to obtain the potential square root $x^{(q+1)/4}$, + and then combine these two powers to find $x^{(q-1)/2}$. + */ + if (fmpz_fdiv_ui(p, 4) == 3 && (d & WORD(1))) + { + fmpz_t z; + fmpz *v, *w; + + fmpz_init(z); + v = _fmpz_vec_init(4 * d - 2); + w = v + (2 * d - 1); + + fmpz_pow_ui(z, p, d); + fmpz_sub_ui(z, z, 3); + fmpz_fdiv_q_2exp(z, z, 2); + + _qadic_pow(v, op, len, z, a, j, lena, p); + + _fmpz_poly_mul(rop, v, d, op, len); + _fmpz_vec_zero(rop + d + len - 1, d - len); + _fmpz_mod_poly_reduce(rop, d + len - 1, a, j, lena, p); + + _fmpz_poly_mul(w, rop, d, v, d); + _fmpz_mod_poly_reduce(w, 2 * d - 1, a, j, lena, p); + ans = fmpz_is_one(w + 0); + + fmpz_clear(z); + _fmpz_vec_clear(v, 4 * d - 2); + } + + /* + When $q \equiv 5 \pmod{8}$... + + A non-zero element $x$ is a square if and only if $y = x^{(q-1)/4}$ + is $\pm 1$. If $y = +1$, a square root is given by $x^{(q+3)/8}$, + otherwise it is $(2x) (4x)^{(q-5)/8}$. + + We begin by computing $v = x^{(q-5)/8}$, $w = x v = x^{(q+3)/8}$ + and $y = v w = x^{(q-1)/4}$. If $y = +1$ we return $w$, and if + $y = -1$ we return $2^{(q-1)/4} x^{(q+3)/8} = 2^{(q-1)/4} w$. + */ + else if (fmpz_fdiv_ui(p, 8) == 5 && (d & WORD(1))) + { + fmpz_t f, g, pm1; + + fmpz *v; /* v = x^{(q-5)/8} */ + fmpz *w; /* w = x^{(q+3)/8} */ + fmpz *y; /* y = x^{(q-1)/4} */ + + fmpz_init(f); + fmpz_init(g); + fmpz_init(pm1); + fmpz_sub_ui(pm1, p, 1); + + v = _fmpz_vec_init(2 * d - 1); + w = _fmpz_vec_init(2 * d - 1); + y = _fmpz_vec_init(2 * d - 1); + + fmpz_pow_ui(g, p, d); + fmpz_sub_ui(g, g, 5); + fmpz_fdiv_q_2exp(g, g, 3); + _qadic_pow(v, op, len, g, a, j, lena, p); + + _fmpz_poly_mul(w, v, d, op, len); + _fmpz_mod_poly_reduce(w, d + len - 1, a, j, lena, p); + + _fmpz_poly_mul(y, v, d, w, d); + _fmpz_mod_poly_reduce(y, 2 * d - 1, a, j, lena, p); + + if ((fmpz_is_one(y + 0) || fmpz_equal(y + 0, pm1)) /* q.r. */ + && _fmpz_vec_is_zero(y + 1, d - 1)) + { + if (fmpz_is_one(y + 0)) + { + _fmpz_vec_set(rop, w, d); + } + else + { + fmpz_t two = {WORD(2)}; + + fmpz_zero(g); + fmpz_pow_ui(g, p, d); + fmpz_sub_ui(g, g, 1); + fmpz_fdiv_q_2exp(g, g, 2); + _fmpz_vec_set(rop, v, d); + + fmpz_powm(f, two, g, p); + + _fmpz_mod_poly_scalar_mul_fmpz(rop, w, d, f, p); + } + _fmpz_vec_zero(rop + d, d - 1); + ans = 1; + } + else /* q.n.r. */ + { + ans = 0; + } + + fmpz_clear(f); + fmpz_clear(g); + fmpz_clear(pm1); + + _fmpz_vec_clear(v, 2 * d - 1); + _fmpz_vec_clear(w, 2 * d - 1); + _fmpz_vec_clear(y, 2 * d - 1); + } + + /* + General case for odd $q$... + + TODO: Find a better way to integrate the check for square-ness + into the computation of a potential square root. + */ + else + { + slong i, s; + + fmpz_t t, pm1, qm1, z; + + fmpz *b, *g, *bpow, *gpow, *w; + + fmpz_init(t); + fmpz_init(pm1); + fmpz_init(qm1); + fmpz_init(z); + + fmpz_sub_ui(pm1, p, 1); + fmpz_pow_ui(qm1, p, d); + fmpz_sub_ui(qm1, qm1, 1); + + b = _fmpz_vec_init(2 * d - 1); + g = _fmpz_vec_init(2 * d - 1); + bpow = _fmpz_vec_init(2 * d - 1); + gpow = _fmpz_vec_init(2 * d - 1); + w = _fmpz_vec_init(2 * d - 1); + + /* Check whether op is a square, i.e. op^{(q-1}/2} == 1 */ + fmpz_fdiv_q_2exp(z, qm1, 1); + _qadic_pow(w, op, len, z, a, j, lena, p); + ans = fmpz_is_one(w); + + if (ans) + { + /* Find a non-residue g */ + _find_nonresidue(g, a, j, lena, p); + + /* Write q - 1 = 2^s t */ + for (s = 0, fmpz_set(t, qm1); fmpz_is_even(t); s++) + fmpz_fdiv_q_2exp(t, t, 1); + + /* Set g = g^t */ + _qadic_pow(w, g, d, t, a, j, lena, p); + _fmpz_vec_set(g, w, d); + + /* Set rop = op^{(t+1)/2} */ + fmpz_add_ui(z, t, 1); + fmpz_fdiv_q_2exp(z, z, 1); + _qadic_pow(rop, op, len, z, a, j, lena, p); + + /* Set b = op^t */ + _qadic_pow(b, op, len, t, a, j, lena, p); + + while (!_fmpz_poly_is_one(b, d)) + { + slong k; + + _fmpz_vec_set(bpow, b, d); + for (k = 1; (k < s) && !_fmpz_poly_is_one(bpow, d); k++) + { + _fmpz_poly_sqr(w, bpow, d); + _fmpz_mod_poly_reduce(w, 2 * d - 1, a, j, lena, p); + _fmpz_vec_scalar_mod_fmpz(bpow, w, d, p); + } + + _fmpz_vec_set(gpow, g, d); + for (i = 1; i < s - k; i++) + { + _fmpz_poly_sqr(w, gpow, d); + _fmpz_mod_poly_reduce(w, 2 * d - 1, a, j, lena, p); + _fmpz_vec_scalar_mod_fmpz(gpow, w, d, p); + } + + _fmpz_poly_mul(w, rop, d, gpow, d); + _fmpz_mod_poly_reduce(w, 2 * d - 1, a, j, lena, p); + _fmpz_vec_scalar_mod_fmpz(rop, w, d, p); + + _fmpz_poly_sqr(w, gpow, d); + _fmpz_mod_poly_reduce(w, 2 * d - 1, a, j, lena, p); + _fmpz_vec_scalar_mod_fmpz(gpow, w, d, p); + + _fmpz_poly_mul(w, b, d, gpow, d); + _fmpz_mod_poly_reduce(w, 2 * d - 1, a, j, lena, p); + _fmpz_vec_scalar_mod_fmpz(b, w, d, p); + + s = k; + } + } + + fmpz_clear(t); + fmpz_clear(pm1); + fmpz_clear(qm1); + fmpz_clear(z); + _fmpz_vec_clear(b, 2 * d - 1); + _fmpz_vec_clear(g, 2 * d - 1); + _fmpz_vec_clear(bpow, 2 * d - 1); + _fmpz_vec_clear(gpow, 2 * d - 1); + _fmpz_vec_clear(w, 2 * d - 1); + } + return ans; +} + +/* + Sets \code{(rop, 2 * d - 1)} to the square root of + \code{(op, len)}. + + Note that the group of units of $\mathbf{F}_q$ is cyclic of order $q - 1$, + which is odd if $p = 2$. We have $x^{q-1} = 1$ for every non-zero $x$, so + $x^q = x$ for every $x$ and $u = x^{q/2}$ satisfies $u^2 = x$. + + Assumes that $d \geq 1$. + */ +static void +_fmpz_mod_poly_sqrtmod_2(fmpz *rop, const fmpz *op, slong len, + const fmpz *a, const slong *j, slong lena) +{ + const fmpz_t p = {WORD(2)}; + const slong d = j[lena - 1]; + + fmpz_t z; + + fmpz_init(z); + fmpz_setbit(z, d - 1); + _qadic_pow(rop, op, len, z, a, j, lena, p); + fmpz_clear(z); +} + +/* + Returns whether \code{(op, len)} is a square, and if so + sets \code{(rop, 2 * d - 1)} to a square root mod $p^N$. + + Assumes that \code{(op, len)} has valuation $0$. + */ +static int +_qadic_sqrt_p(fmpz *rop, const fmpz *op, slong len, + const fmpz *a, const slong *j, slong lena, + const fmpz_t p, slong N) +{ + const slong d = j[lena - 1]; + int ans; + + if (N == 1) + { + ans = _fmpz_mod_poly_sqrtmod_p(rop, op, len, a, j, lena, p); + return ans; + } + else + { + slong *e, i, k, n; + fmpz *pow, *u; + fmpz *r, *s, *t, *f; + + n = FLINT_CLOG2(N) + 1; + + /* Compute sequence of exponents */ + e = flint_malloc(n * sizeof(slong)); + for (e[i = 0] = N; e[i] > 1; i++) + e[i + 1] = (e[i] + 1) / 2; + + pow = _fmpz_vec_init(n); + u = _fmpz_vec_init(len * n); + r = _fmpz_vec_init(2 * d - 1); + s = _fmpz_vec_init(2 * d - 1); + t = _fmpz_vec_init(2 * d - 1); + f = _fmpz_vec_init(d + 1); + + /* Compute powers of p */ + { + fmpz_one(t); + fmpz_set(pow + i, p); + } + for (i--; i >= 1; i--) + { + if (e[i] & WORD(1)) + { + fmpz_mul(pow + i, t, pow + (i + 1)); + fmpz_mul(t, t, t); + } + else + { + fmpz_mul(t, t, pow + (i + 1)); + fmpz_mul(pow + i, pow + (i + 1), pow + (i + 1)); + } + } + { + if (e[i] & WORD(1)) + fmpz_mul(pow + i, t, pow + (i + 1)); + else + fmpz_mul(pow + i, pow + (i + 1), pow + (i + 1)); + } + + /* Compute reduced units */ + { + _fmpz_vec_scalar_mod_fmpz(u + 0 * len, op, len, pow + 0); + } + for (i = 1; i < n; i++) + { + _fmpz_vec_scalar_mod_fmpz(u + i * len, u + (i - 1) * len, len, pow + i); + } + + /* Run Newton iteration */ + i = n - 1; + { + ans = _fmpz_mod_poly_sqrtmod_p(t, u + i * len, len, a, j, lena, p); + if (!ans) + goto exit; + + /* Dense copy of f, used for inversion */ + for (k = 0; k < lena; k++) + fmpz_set(f + j[k], a + k); + _fmpz_mod_poly_invmod(rop, t, d, f, d + 1, p); + } + for (i--; i >= 1; i--) /* z := z - z (a z^2 - 1) / 2 */ + { + _fmpz_poly_sqr(s, rop, d); + _fmpz_poly_reduce(s, 2 * d - 1, a, j, lena); + _fmpz_poly_mul(t, s, d, u + i * len, len); + _fmpz_poly_reduce(t, d + len - 1, a, j, lena); + fmpz_sub_ui(t, t, 1); + + for (k = 0; k < d; k++) + { + if (fmpz_is_odd(t + k)) + fmpz_add(t + k, t + k, pow + i); + fmpz_fdiv_q_2exp(t + k, t + k, 1); + } + + _fmpz_poly_mul(s, t, d, rop, d); + _fmpz_poly_reduce(s, 2 * d - 1, a, j, lena); + _fmpz_poly_sub(rop, rop, d, s, d); + _fmpz_vec_scalar_mod_fmpz(rop, rop, d, pow + i); + } + { + _fmpz_poly_mul(s, rop, d, u + 1 * len, len); + _fmpz_poly_reduce(s, d + len - 1, a, j, lena); + _fmpz_poly_sqr(t, s, d); + _fmpz_poly_reduce(t, 2 * d - 1, a, j, lena); + _fmpz_poly_sub(t, u + 0 * len, len, t, d); + + for (k = 0; k < d; k++) + { + if (fmpz_is_odd(t + k)) + fmpz_add(t + k, t + k, pow + 0); + fmpz_fdiv_q_2exp(t + k, t + k, 1); + } + + _fmpz_poly_mul(r, rop, d, t, d); + _fmpz_poly_reduce(r, 2 * d - 1, a, j, lena); + _fmpz_poly_add(rop, r, d, s, d); + _fmpz_vec_scalar_mod_fmpz(rop, rop, d, pow + 0); + } + + exit: + + _fmpz_vec_clear(pow, n); + _fmpz_vec_clear(u, len * n); + _fmpz_vec_clear(r, 2 * d - 1); + _fmpz_vec_clear(s, 2 * d - 1); + _fmpz_vec_clear(t, 2 * d - 1); + _fmpz_vec_clear(f, d + 1); + flint_free(e); + + return ans; + } +} + +/* + Returns whether \code{(op, len)} is a square, and if so + sets \code{(rop, 2 * d - 1)} to a square root mod $2^N$. + + Assumes that \code{(op, len)} has valuation $0$. + */ +static int +_qadic_sqrt_2(fmpz *rop, const fmpz *op, slong len, + const fmpz *a, const slong *j, slong lena, slong N) +{ + int ans; + + const slong d = j[lena - 1]; + const fmpz_t p = {WORD(2)}; + + fmpz *g, *r, *s, *t; + slong i; + + g = _fmpz_vec_init(2 * d - 1); + r = _fmpz_vec_init(2 * d - 1); + s = _fmpz_vec_init(2 * d - 1); + t = _fmpz_vec_init(2 * d - 1); + + /* Compute r = 1/op (mod 8) */ + _qadic_inv(r, op, len, a, j, lena, p, 3); + + /* Compute s = invsqrt(op) (mod 2) */ + _fmpz_vec_scalar_fdiv_r_2exp(t, r, d, 1); + _fmpz_mod_poly_sqrtmod_2(s, r, d, a, j, lena); + + /* Compute t = (1/op - s^2) / 4 (mod 2) if that makes sense */ + _fmpz_poly_sqr(t, s, d); + _fmpz_poly_reduce(t, 2*d - 1, a, j, lena); + _fmpz_vec_sub(t, r, t, d); + + _fmpz_vec_zero(rop, 2 * d - 1); + ans = 1; + for (i = 0; i < d; i++) + { + if (fmpz_val2(t + i) == 1) + ans = 0; + } + + if (ans) { + _fmpz_vec_scalar_fdiv_q_2exp(t, t, d, 2); + _fmpz_vec_scalar_fdiv_r_2exp(t, t, d, 1); + + /* Check whether X^2 + s X = t (mod 2) has a solution */ + /* + u = (op,len) is a square in Zq iff it is a square modulo 8, + which is the case iff X^2 + s X + t == 0 (mod 2) is soluble. + Let g be t/s^2. Then the above quadratic is soluble iff + Y^2 + Y + d = 0 is soluble. + + We can observe that 1/s^2 = op (mod 2). + */ + _fmpz_vec_scalar_fdiv_r_2exp(r, op, len, 1); + _fmpz_poly_mul(g, t, d, r, len); + _fmpz_mod_poly_reduce(g, 2 * d - 1, a, j, lena, p); + + ans = _artin_schreier_preimage(r, g, d, a, j, lena); + + if (ans) + { + if (N == 1) + { + _fmpz_mod_poly_sqrtmod_2(rop, op, len, a, j, lena); + } + else + { + + /* Set t = r s, a root of X^2 + s X = t (mod 2) */ + _fmpz_poly_mul(t, r, d, s, d); + _fmpz_mod_poly_reduce(t, 2 * d - 1, a, j, lena, p); + + /* Now s + 2t is an invsqrt of (op, len) to precision 4. */ + _fmpz_vec_scalar_addmul_si(s, t, d, 2); + + if (N == 2) + { + _qadic_inv(rop, s, d, a, j, lena, p, 2); + } + else /* N >= 3 */ + { + slong *e, n; + fmpz *u; + + n = FLINT_CLOG2(N - 1) + 1; + + /* Compute sequence of exponents */ + e = flint_malloc(n * sizeof(slong)); + for (e[i = 0] = N; e[i] > 2; i++) + e[i + 1] = e[i] / 2 + 1; + + u = _fmpz_vec_init(len * n); + + /* Compute reduced units */ + { + _fmpz_vec_scalar_fdiv_r_2exp(u + 0 * len, op, len, e[0]); + } + for (i = 1; i < n; i++) + { + _fmpz_vec_scalar_fdiv_r_2exp(u + i * len, u + (i - 1) * len, len, e[i] + 1); + } + + /* Run Newton iteration */ + { + _fmpz_vec_set(rop, s, d); + } + for (i = n - 2; i >= 1; i--) /* z := z - z (a z^2 - 1) / 2 */ + { + _fmpz_poly_sqr(s, rop, d); + _fmpz_poly_reduce(s, 2 * d - 1, a, j, lena); + _fmpz_poly_mul(t, s, d, u + i * len, len); + _fmpz_poly_reduce(t, d + len - 1, a, j, lena); + fmpz_sub_ui(t, t, 1); + _fmpz_vec_scalar_fdiv_q_2exp(t, t, d, 1); + _fmpz_poly_mul(s, t, d, rop, d); + _fmpz_poly_reduce(s, 2 * d - 1, a, j, lena); + _fmpz_poly_sub(rop, rop, d, s, d); + _fmpz_vec_scalar_fdiv_r_2exp(rop, rop, d, e[i]); + } + /* z := a z + z (a - (a z)^2) / 2 */ + { + _fmpz_poly_mul(s, rop, d, u + len, len); + _fmpz_poly_reduce(s, d + len - 1, a, j, lena); + _fmpz_poly_sqr(t, s, d); + _fmpz_poly_reduce(t, 2 * d - 1, a, j, lena); + _fmpz_poly_sub(t, u + 0 * len, len, t, d); + _fmpz_vec_scalar_fdiv_q_2exp(t, t, d, 1); + _fmpz_poly_mul(r, rop, d, t, d); + _fmpz_poly_reduce(r, 2 * d - 1, a, j, lena); + _fmpz_poly_add(rop, r, d, s, d); + _fmpz_vec_scalar_fdiv_r_2exp(rop, rop, d, e[0]); + } + + _fmpz_vec_clear(u, len * n); + flint_free(e); + } + } + } + } + + _fmpz_vec_clear(g, 2 * d - 1); + _fmpz_vec_clear(r, 2 * d - 1); + _fmpz_vec_clear(s, 2 * d - 1); + _fmpz_vec_clear(t, 2 * d - 1); + + return ans; +} + +/* + Returns whether \code{(op, len)} is a square, and if so + sets \code{(rop, 2 * d - 1)} to a square root, reduced + modulo $2^N$. + + Assumes that \code{(op, len)} has valuation $0$. + */ +int _qadic_sqrt(fmpz *rop, const fmpz *op, slong len, + const fmpz *a, const slong *j, slong lena, + const fmpz_t p, slong N) +{ + if (*p == WORD(2)) + { + return _qadic_sqrt_2(rop, op, len, a, j, lena, N); + } + else + { + return _qadic_sqrt_p(rop, op, len, a, j, lena, p, N); + } +} + +int qadic_sqrt(qadic_t rop, const qadic_t op, const qadic_ctx_t ctx) +{ + const fmpz *p = (&ctx->pctx)->p; + const slong d = qadic_ctx_degree(ctx); + const slong N = qadic_prec(rop); + + fmpz *t; + int ans; + + if (qadic_is_zero(op)) + { + qadic_zero(rop); + return 1; + } + if (op->val & WORD(1)) + { + return 0; + } + + rop->val = op->val / 2; + + /* + FIXME: In this case, we don't actually + check whether the element is a square! + */ + if (rop->val >= N) + { + qadic_zero(rop); + return 1; + } + + if (rop == op) + { + t = _fmpz_vec_init(2 * d - 1); + } + else + { + padic_poly_fit_length(rop, 2 * d - 1); + t = rop->coeffs; + } + + ans = _qadic_sqrt(t, op->coeffs, op->length, ctx->a, ctx->j, ctx->len, p, N - rop->val); + + if (rop == op) + { + _fmpz_vec_clear(rop->coeffs, rop->alloc); + rop->coeffs = t; + rop->alloc = 2 * d - 1; + rop->length = d; + } + _padic_poly_set_length(rop, d); + _padic_poly_normalise(rop); + if (padic_poly_length(rop) == 0) + padic_poly_val(rop) = 0; + + return ans; +} diff --git a/external/flint-2.4.3/qadic/teichmuller.c b/external/flint-2.4.3/qadic/teichmuller.c new file mode 100644 index 0000000..525c414 --- /dev/null +++ b/external/flint-2.4.3/qadic/teichmuller.c @@ -0,0 +1,177 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "fmpz_mod_poly.h" +#include "qadic.h" + +/* + Uses Hensel lifting along the polynomial $X^q - X$, which yields + the formula $z' = z - (z^q - z) / (q z^{q-1} - 1)$. + + We observe that the denominator is an approximation to $q - 1$, + which allows us to use the formula $z' = z - (q-1)^{-1} (z^q - z)$ + during the iteration. + + Supports aliasing between \code{rop} and \code{op}. + */ + +void _qadic_teichmuller(fmpz *rop, const fmpz *op, slong len, + const fmpz *a, const slong *j, slong lena, + const fmpz_t p, slong N) +{ + const slong d = j[lena - 1]; + + if (len == 1) + { + _padic_teichmuller(rop, op, p, N); + _fmpz_vec_zero(rop + 1, d - 1); + } + else if (N == 1) + { + _fmpz_vec_scalar_mod_fmpz(rop, op, len, p); + _fmpz_vec_zero(rop + len, d - len); + } + else /* d, N >= 2 */ + { + slong *e, i, n; + fmpz *pow, *u, *t, *w; + fmpz_t inv, q, qm1; + + n = FLINT_CLOG2(N) + 1; + + e = flint_malloc(n * sizeof(slong)); + for (e[i = 0] = N; e[i] > 1; i++) + e[i + 1] = (e[i] + 1) / 2; + + w = _fmpz_vec_init(n + n + (2 * d - 1)); + pow = w; + u = w + n; + t = w + 2 * n; + + fmpz_init(inv); + fmpz_init(q); + fmpz_init(qm1); + + fmpz_pow_ui(q, p, d); + fmpz_sub_ui(qm1, q, 1); + + /* Compute powers of p */ + { + fmpz_one(t); + fmpz_set(pow + i, p); + } + for (i--; i >= 1; i--) + { + if (e[i] & WORD(1)) + { + fmpz_mul(pow + i, t, pow + (i + 1)); + fmpz_mul(t, t, t); + } + else + { + fmpz_mul(t, t, pow + (i + 1)); + fmpz_mul(pow + i, pow + (i + 1), pow + (i + 1)); + } + } + { + if (e[i] & WORD(1)) + fmpz_mul(pow + i, t, pow + (i + 1)); + else + fmpz_mul(pow + i, pow + (i + 1), pow + (i + 1)); + } + + /* Compute reduced units for (q-1) */ + { + fmpz_mod(u + 0, qm1, pow + 0); + } + for (i = 1; i < n; i++) + { + fmpz_mod(u + i, u + (i - 1), pow + i); + } + + /* Run Newton iteration */ + i = n - 1; + { + _fmpz_vec_scalar_mod_fmpz(rop, op, len, pow + i); + _fmpz_vec_zero(rop + len, d - len); + + fmpz_sub_ui(inv, p, 1); + } + for (i--; i >= 0; i--) + { + /* Lift rop */ + _qadic_pow(t, rop, d, q, a, j, lena, pow + i); + _fmpz_poly_sub(t, t, d, rop, d); + _fmpz_vec_scalar_submul_fmpz(rop, t, d, inv); + _fmpz_vec_scalar_mod_fmpz(rop, rop, d, pow + i); + + /* Lift inv */ + if (i > 0) + { + fmpz_mul(t, inv, inv); + fmpz_mul(t + 1, u + i, t); + fmpz_mul_2exp(inv, inv, 1); + fmpz_sub(inv, inv, t + 1); + fmpz_mod(inv, inv, pow + i); + } + } + + _fmpz_vec_clear(w, n + n + (2 * d - 1)); + fmpz_clear(inv); + fmpz_clear(q); + fmpz_clear(qm1); + flint_free(e); + } +} + +void qadic_teichmuller(qadic_t rop, const qadic_t op, const qadic_ctx_t ctx) +{ + const slong N = qadic_prec(rop); + + if (op->val < 0) + { + flint_printf("Exception (qadic_teichmuller). val(op) is negative.\n"); + abort(); + } + + if (qadic_is_zero(op) || op->val > 0 || N <= 0) + { + qadic_zero(rop); + } + else + { + const slong d = qadic_ctx_degree(ctx); + + padic_poly_fit_length(rop, d); + + _qadic_teichmuller(rop->coeffs, op->coeffs, op->length, + ctx->a, ctx->j, ctx->len, (&ctx->pctx)->p, N); + rop->val = 0; + _padic_poly_set_length(rop, d); + _padic_poly_normalise(rop); + } +} + diff --git a/external/flint-2.4.3/qadic/test/t-add.c b/external/flint-2.4.3/qadic/test/t-add.c new file mode 100644 index 0000000..2e1dd37 --- /dev/null +++ b/external/flint-2.4.3/qadic/test/t-add.c @@ -0,0 +1,269 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include +#include + +#include "qadic.h" +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("add... "); + fflush(stdout); + + + + /* Check aliasing: a = a + b */ + for (i = 0; i < 2000; i++) + { + fmpz_t p; + slong d, N; + qadic_ctx_t ctx; + + qadic_t a, b, c; + + fmpz_init_set_ui(p, n_randprime(state, 2 + n_randint(state, 3), 1)); + d = n_randint(state, 10) + 1; + N = z_randint(state, 50) + 1; + qadic_ctx_init_conway(ctx, p, d, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), "a", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + qadic_init2(c, N); + + qadic_randtest(a, state, ctx); + qadic_randtest(b, state, ctx); + + qadic_add(c, a, b, ctx); + qadic_add(a, a, b, ctx); + + result = (qadic_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), qadic_print_pretty(c, ctx), flint_printf("\n"); + abort(); + } + + qadic_clear(a); + qadic_clear(b); + qadic_clear(c); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + } + + /* Check aliasing: b = a + b */ + for (i = 0; i < 2000; i++) + { + fmpz_t p; + slong d, N; + qadic_ctx_t ctx; + + qadic_t a, b, c; + + fmpz_init_set_ui(p, n_randprime(state, 2 + n_randint(state, 3), 1)); + d = n_randint(state, 10) + 1; + N = z_randint(state, 50) + 1; + qadic_ctx_init_conway(ctx, p, d, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), "a", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + qadic_init2(c, N); + + qadic_randtest(a, state, ctx); + qadic_randtest(b, state, ctx); + + qadic_add(c, a, b, ctx); + qadic_add(b, a, b, ctx); + + result = (qadic_equal(b, c)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), qadic_print_pretty(c, ctx), flint_printf("\n"); + abort(); + } + + qadic_clear(a); + qadic_clear(b); + qadic_clear(c); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + } + + /* Check aliasing: a = a + a */ + for (i = 0; i < 2000; i++) + { + fmpz_t p; + slong d, N; + qadic_ctx_t ctx; + + qadic_t a, c; + + fmpz_init_set_ui(p, n_randprime(state, 2 + n_randint(state, 3), 1)); + d = n_randint(state, 10) + 1; + N = z_randint(state, 50) + 1; + qadic_ctx_init_conway(ctx, p, d, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), "a", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(c, N); + + qadic_randtest(a, state, ctx); + + qadic_add(c, a, a, ctx); + qadic_add(a, a, a, ctx); + + result = (qadic_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("c = "), qadic_print_pretty(c, ctx), flint_printf("\n"); + abort(); + } + + qadic_clear(a); + qadic_clear(c); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + } + + /* Check that a + b == b + a */ + for (i = 0; i < 2000; i++) + { + fmpz_t p; + slong d, N; + qadic_ctx_t ctx; + + qadic_t a, b, c1, c2; + + fmpz_init_set_ui(p, n_randprime(state, 2 + n_randint(state, 3), 1)); + d = n_randint(state, 10) + 1; + N = z_randint(state, 50) + 1; + qadic_ctx_init_conway(ctx, p, d, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), "a", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + qadic_init2(c1, N); + qadic_init2(c2, N); + + qadic_randtest(a, state, ctx); + qadic_randtest(b, state, ctx); + + qadic_add(c1, a, b, ctx); + qadic_add(c2, b, a, ctx); + + result = (qadic_equal(c1, c2)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c1 = "), qadic_print_pretty(c1, ctx), flint_printf("\n"); + flint_printf("c2 = "), qadic_print_pretty(c2, ctx), flint_printf("\n"); + abort(); + } + + qadic_clear(a); + qadic_clear(b); + qadic_clear(c1); + qadic_clear(c2); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + } + + /* Check that (a + b) + c == a + (b + c) */ + for (i = 0; i < 2000; i++) + { + fmpz_t p; + slong d, N; + qadic_ctx_t ctx; + + qadic_t a, b, c, lhs, rhs; + + fmpz_init_set_ui(p, n_randprime(state, 2 + n_randint(state, 3), 1)); + d = n_randint(state, 10) + 1; + N = z_randint(state, 50) + 1; + qadic_ctx_init_conway(ctx, p, d, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), "a", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + qadic_init2(c, N); + qadic_init2(lhs, N); + qadic_init2(rhs, N); + + qadic_randtest(a, state, ctx); + qadic_randtest(b, state, ctx); + qadic_randtest(c, state, ctx); + + qadic_add(lhs, a, b, ctx); + qadic_add(lhs, lhs, c, ctx); + qadic_add(rhs, b, c, ctx); + qadic_add(rhs, a, rhs, ctx); + + result = (qadic_equal(lhs, rhs)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), qadic_print_pretty(c, ctx), flint_printf("\n"); + flint_printf("lhs = "), qadic_print_pretty(lhs, ctx), flint_printf("\n"); + flint_printf("rhs = "), qadic_print_pretty(rhs, ctx), flint_printf("\n"); + flint_printf("p = "), fmpz_print(p), flint_printf("\n"); + flint_printf("N = %wd\n", N); + abort(); + } + + qadic_clear(a); + qadic_clear(b); + qadic_clear(c); + qadic_clear(lhs); + qadic_clear(rhs); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/qadic/test/t-exp.c b/external/flint-2.4.3/qadic/test/t-exp.c new file mode 100644 index 0000000..eb65fc5 --- /dev/null +++ b/external/flint-2.4.3/qadic/test/t-exp.c @@ -0,0 +1,151 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include + +#include "qadic.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("exp... "); + fflush(stdout); + + + + /* Check aliasing */ + for (i = 0; i < 1000; i++) + { + fmpz_t p; + slong d, N; + qadic_ctx_t ctx; + + qadic_t a, b, c; + int ans1, ans2; + + fmpz_init_set_ui(p, n_randprime(state, 2 + n_randint(state, 3), 1)); + d = n_randint(state, 10) + 1; + N = n_randint(state, 50) + 1; + qadic_ctx_init_conway(ctx, p, d, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), "a", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + qadic_init2(c, N); + + qadic_randtest(a, state, ctx); + qadic_set(b, a, ctx); + + ans1 = qadic_exp(c, b, ctx); + ans2 = qadic_exp(b, b, ctx); + + result = ((ans1 == ans2) && (!ans1 || qadic_equal(b, c))); + if (!result) + { + flint_printf("FAIL (alias):\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), qadic_print_pretty(c, ctx), flint_printf("\n"); + flint_printf("ans1 = %d\n", ans1); + flint_printf("ans2 = %d\n", ans2); + abort(); + } + + qadic_clear(a); + qadic_clear(b); + qadic_clear(c); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + } + + /* Functional equation: exp(a + b) == exp(a) exp(b) */ + for (i = 0; i < 1000; i++) + { + fmpz_t p; + slong deg, N; + qadic_ctx_t ctx; + + qadic_t a, b, c, d, e, f, g; + int ans1, ans2, ans3; + + fmpz_init_set_ui(p, n_randprime(state, 2 + n_randint(state, 3), 1)); + deg = n_randint(state, 10) + 1; + N = n_randint(state, 50) + 1; + qadic_ctx_init_conway(ctx, p, deg, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), "a", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + qadic_init2(c, N); + qadic_init2(d, N); + qadic_init2(e, N); + qadic_init2(f, N); + qadic_init2(g, N); + + qadic_randtest(a, state, ctx); + qadic_randtest(b, state, ctx); + qadic_add(c, a, b, ctx); + + ans1 = qadic_exp(d, a, ctx); + ans2 = qadic_exp(e, b, ctx); + qadic_mul(f, d, e, ctx); + + ans3 = qadic_exp(g, c, ctx); + + result = (!ans1 || !ans2 || (ans3 && qadic_equal(f, g))); + if (!result) + { + flint_printf("FAIL (functional equation):\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = a + b = "), qadic_print_pretty(c, ctx), flint_printf("\n"); + flint_printf("d = exp(a) = "), qadic_print_pretty(d, ctx), flint_printf("\n"); + flint_printf("e = exp(b) = "), qadic_print_pretty(e, ctx), flint_printf("\n"); + flint_printf("f = exp(a) exp(b) = "), qadic_print_pretty(f, ctx), flint_printf("\n"); + flint_printf("g = exp(a + b) = "), qadic_print_pretty(g, ctx), flint_printf("\n"); + abort(); + } + + qadic_clear(a); + qadic_clear(b); + qadic_clear(c); + qadic_clear(d); + qadic_clear(e); + qadic_clear(f); + qadic_clear(g); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/qadic/test/t-exp_balanced.c b/external/flint-2.4.3/qadic/test/t-exp_balanced.c new file mode 100644 index 0000000..6639bdd --- /dev/null +++ b/external/flint-2.4.3/qadic/test/t-exp_balanced.c @@ -0,0 +1,151 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include + +#include "qadic.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("exp_balanced... "); + fflush(stdout); + + + + /* Check aliasing */ + for (i = 0; i < 1000; i++) + { + fmpz_t p; + slong d, N; + qadic_ctx_t ctx; + + qadic_t a, b, c; + int ans1, ans2; + + fmpz_init_set_ui(p, n_randprime(state, 2 + n_randint(state, 3), 1)); + d = n_randint(state, 10) + 1; + N = n_randint(state, 50) + 1; + qadic_ctx_init_conway(ctx, p, d, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), "a", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + qadic_init2(c, N); + + qadic_randtest(a, state, ctx); + qadic_set(b, a, ctx); + + ans1 = qadic_exp_balanced(c, b, ctx); + ans2 = qadic_exp_balanced(b, b, ctx); + + result = ((ans1 == ans2) && (!ans1 || qadic_equal(b, c))); + if (!result) + { + flint_printf("FAIL (alias):\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), qadic_print_pretty(c, ctx), flint_printf("\n"); + flint_printf("ans1 = %d\n", ans1); + flint_printf("ans2 = %d\n", ans2); + abort(); + } + + qadic_clear(a); + qadic_clear(b); + qadic_clear(c); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + } + + /* Functional equation: exp(a + b) == exp(a) exp(b) */ + for (i = 0; i < 1000; i++) + { + fmpz_t p; + slong deg, N; + qadic_ctx_t ctx; + + qadic_t a, b, c, d, e, f, g; + int ans1, ans2, ans3; + + fmpz_init_set_ui(p, n_randprime(state, 2 + n_randint(state, 3), 1)); + deg = n_randint(state, 10) + 1; + N = n_randint(state, 50) + 1; + qadic_ctx_init_conway(ctx, p, deg, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), "a", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + qadic_init2(c, N); + qadic_init2(d, N); + qadic_init2(e, N); + qadic_init2(f, N); + qadic_init2(g, N); + + qadic_randtest(a, state, ctx); + qadic_randtest(b, state, ctx); + qadic_add(c, a, b, ctx); + + ans1 = qadic_exp_balanced(d, a, ctx); + ans2 = qadic_exp_balanced(e, b, ctx); + qadic_mul(f, d, e, ctx); + + ans3 = qadic_exp_balanced(g, c, ctx); + + result = (!ans1 || !ans2 || (ans3 && qadic_equal(f, g))); + if (!result) + { + flint_printf("FAIL (functional equation):\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = a + b = "), qadic_print_pretty(c, ctx), flint_printf("\n"); + flint_printf("d = exp(a) = "), qadic_print_pretty(d, ctx), flint_printf("\n"); + flint_printf("e = exp(b) = "), qadic_print_pretty(e, ctx), flint_printf("\n"); + flint_printf("f = exp(a) exp(b) = "), qadic_print_pretty(f, ctx), flint_printf("\n"); + flint_printf("g = exp(a + b) = "), qadic_print_pretty(g, ctx), flint_printf("\n"); + abort(); + } + + qadic_clear(a); + qadic_clear(b); + qadic_clear(c); + qadic_clear(d); + qadic_clear(e); + qadic_clear(f); + qadic_clear(g); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/qadic/test/t-exp_rectangular.c b/external/flint-2.4.3/qadic/test/t-exp_rectangular.c new file mode 100644 index 0000000..605ab48 --- /dev/null +++ b/external/flint-2.4.3/qadic/test/t-exp_rectangular.c @@ -0,0 +1,151 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include + +#include "qadic.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("exp_rectangular... "); + fflush(stdout); + + + + /* Check aliasing */ + for (i = 0; i < 1000; i++) + { + fmpz_t p; + slong d, N; + qadic_ctx_t ctx; + + qadic_t a, b, c; + int ans1, ans2; + + fmpz_init_set_ui(p, n_randprime(state, 2 + n_randint(state, 3), 1)); + d = n_randint(state, 10) + 1; + N = n_randint(state, 50) + 1; + qadic_ctx_init_conway(ctx, p, d, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), "a", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + qadic_init2(c, N); + + qadic_randtest(a, state, ctx); + qadic_set(b, a, ctx); + + ans1 = qadic_exp_rectangular(c, b, ctx); + ans2 = qadic_exp_rectangular(b, b, ctx); + + result = ((ans1 == ans2) && (!ans1 || qadic_equal(b, c))); + if (!result) + { + flint_printf("FAIL (alias):\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), qadic_print_pretty(c, ctx), flint_printf("\n"); + flint_printf("ans1 = %d\n", ans1); + flint_printf("ans2 = %d\n", ans2); + abort(); + } + + qadic_clear(a); + qadic_clear(b); + qadic_clear(c); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + } + + /* Functional equation: exp(a + b) == exp(a) exp(b) */ + for (i = 0; i < 1000; i++) + { + fmpz_t p; + slong deg, N; + qadic_ctx_t ctx; + + qadic_t a, b, c, d, e, f, g; + int ans1, ans2, ans3; + + fmpz_init_set_ui(p, n_randprime(state, 2 + n_randint(state, 3), 1)); + deg = n_randint(state, 10) + 1; + N = n_randint(state, 50) + 1; + qadic_ctx_init_conway(ctx, p, deg, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), "a", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + qadic_init2(c, N); + qadic_init2(d, N); + qadic_init2(e, N); + qadic_init2(f, N); + qadic_init2(g, N); + + qadic_randtest(a, state, ctx); + qadic_randtest(b, state, ctx); + qadic_add(c, a, b, ctx); + + ans1 = qadic_exp_rectangular(d, a, ctx); + ans2 = qadic_exp_rectangular(e, b, ctx); + qadic_mul(f, d, e, ctx); + + ans3 = qadic_exp_rectangular(g, c, ctx); + + result = (!ans1 || !ans2 || (ans3 && qadic_equal(f, g))); + if (!result) + { + flint_printf("FAIL (functional equation):\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = a + b = "), qadic_print_pretty(c, ctx), flint_printf("\n"); + flint_printf("d = exp(a) = "), qadic_print_pretty(d, ctx), flint_printf("\n"); + flint_printf("e = exp(b) = "), qadic_print_pretty(e, ctx), flint_printf("\n"); + flint_printf("f = exp(a) exp(b) = "), qadic_print_pretty(f, ctx), flint_printf("\n"); + flint_printf("g = exp(a + b) = "), qadic_print_pretty(g, ctx), flint_printf("\n"); + abort(); + } + + qadic_clear(a); + qadic_clear(b); + qadic_clear(c); + qadic_clear(d); + qadic_clear(e); + qadic_clear(f); + qadic_clear(g); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/qadic/test/t-frobenius.c b/external/flint-2.4.3/qadic/test/t-frobenius.c new file mode 100644 index 0000000..a0d65ae --- /dev/null +++ b/external/flint-2.4.3/qadic/test/t-frobenius.c @@ -0,0 +1,274 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012, 2013 Sebastian Pancratz + +******************************************************************************/ + +#include +#include + +#include "qadic.h" +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("frobenius... "); + fflush(stdout); + + + + /* Check aliasing */ + for (i = 0; i < 1000; i++) + { + fmpz_t p; + slong d, N; + qadic_ctx_t ctx; + + qadic_t a, b, c; + slong e; + + fmpz_init_set_ui(p, n_randprime(state, 2 + n_randint(state, 3), 1)); + d = n_randint(state, 10) + 1; + N = z_randint(state, 50) + 1; + qadic_ctx_init_conway(ctx, p, d, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), "a", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + qadic_init2(c, N); + + qadic_randtest(a, state, ctx); + qadic_set(b, a, ctx); + e = n_randint(state, 10) % d; + + qadic_frobenius(c, b, e, ctx); + qadic_frobenius(b, b, e, ctx); + + result = (qadic_equal(b, c)); + if (!result) + { + flint_printf("FAIL (alias):\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), qadic_print_pretty(c, ctx), flint_printf("\n"); + flint_printf("e = %wd\n", e); + abort(); + } + + qadic_clear(a); + qadic_clear(b); + qadic_clear(c); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + } + + /* Check sigma^e(x) == x^{p^e} mod p for integral values */ + for (i = 0; i < 1000; i++) + { + fmpz_t p; + slong d, N; + qadic_ctx_t ctx; + + qadic_t a, b, c, lhs, rhs; + slong e; + + fmpz_init_set_ui(p, n_randprime(state, 2 + n_randint(state, 3), 1)); + d = n_randint(state, 10) + 1; + N = n_randint(state, 50) + 1; + qadic_ctx_init_conway(ctx, p, d, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), "a", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + qadic_init2(c, N); + qadic_init2(lhs, 1); + qadic_init2(rhs, 1); + + qadic_randtest_int(a, state, ctx); + e = n_randint(state, 10) % d; + + qadic_frobenius(b, a, e, ctx); + { + fmpz_t t; + + fmpz_init(t); + fmpz_pow_ui(t, p, e); + qadic_pow(c, a, t, ctx); + fmpz_clear(t); + } + + qadic_set(lhs, b, ctx); + qadic_set(rhs, c, ctx); + + result = (qadic_equal(lhs, rhs)); + if (!result) + { + flint_printf("FAIL (sigma^e(x) = x^{p^e} mod p):\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), qadic_print_pretty(c, ctx), flint_printf("\n"); + flint_printf("lhs = "), qadic_print_pretty(lhs, ctx), flint_printf("\n"); + flint_printf("rhs = "), qadic_print_pretty(rhs, ctx), flint_printf("\n"); + flint_printf("e = %wd\n", e); + abort(); + } + + qadic_clear(a); + qadic_clear(b); + qadic_clear(c); + qadic_clear(lhs); + qadic_clear(rhs); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + } + + /* Check sigma^e(x + y) = sigma^e(x) + sigma^e(y) on Zq */ + for (i = 0; i < 1000; i++) + { + fmpz_t p; + slong d, N; + qadic_ctx_t ctx; + + qadic_t a, b, s, s1, s2, lhs, rhs; + slong e; + + fmpz_init_set_ui(p, n_randprime(state, 2 + n_randint(state, 3), 1)); + d = n_randint(state, 10) + 1; + N = n_randint(state, 10) + 1; + qadic_ctx_init_conway(ctx, p, d, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), "a", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + qadic_init2(s, N); + qadic_init2(s1, N); + qadic_init2(s2, N); + qadic_init2(lhs, N); + qadic_init2(rhs, N); + + qadic_randtest_int(a, state, ctx); + qadic_randtest_int(b, state, ctx); + e = n_randint(state, 10) % d; + + qadic_add(s, a, b, ctx); + qadic_frobenius(lhs, s, e, ctx); + qadic_frobenius(s1, a, e, ctx); + qadic_frobenius(s2, b, e, ctx); + qadic_add(rhs, s1, s2, ctx); + + result = (qadic_equal(lhs, rhs)); + if (!result) + { + flint_printf("FAIL (sigma(a+b) = sigma(a) + sigma(b)):\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("s = "), qadic_print_pretty(s, ctx), flint_printf("\n"); + flint_printf("s1 = "), qadic_print_pretty(s1, ctx), flint_printf("\n"); + flint_printf("s2 = "), qadic_print_pretty(s2, ctx), flint_printf("\n"); + flint_printf("lhs = "), qadic_print_pretty(lhs, ctx), flint_printf("\n"); + flint_printf("rhs = "), qadic_print_pretty(rhs, ctx), flint_printf("\n"); + flint_printf("e = %wd\n", e); + abort(); + } + + qadic_clear(a); + qadic_clear(b); + qadic_clear(s); + qadic_clear(s1); + qadic_clear(s2); + qadic_clear(lhs); + qadic_clear(rhs); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + } + + /* Check sigma^e(x * y) = sigma^e(x) * sigma^e(y) on Zq */ + for (i = 0; i < 1000; i++) + { + fmpz_t p; + slong d, N; + qadic_ctx_t ctx; + + qadic_t a, b, s, s1, s2, lhs, rhs; + slong e; + + fmpz_init_set_ui(p, n_randprime(state, 2 + n_randint(state, 3), 1)); + d = n_randint(state, 10) + 1; + N = n_randint(state, 10) + 1; + qadic_ctx_init_conway(ctx, p, d, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), "a", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + qadic_init2(s, N); + qadic_init2(s1, N); + qadic_init2(s2, N); + qadic_init2(lhs, N); + qadic_init2(rhs, N); + + qadic_randtest_int(a, state, ctx); + qadic_randtest_int(b, state, ctx); + e = n_randint(state, 10) % d; + + qadic_mul(s, a, b, ctx); + qadic_frobenius(lhs, s, e, ctx); + qadic_frobenius(s1, a, e, ctx); + qadic_frobenius(s2, b, e, ctx); + qadic_mul(rhs, s1, s2, ctx); + + result = (qadic_equal(lhs, rhs)); + if (!result) + { + flint_printf("FAIL (sigma(a*b) = sigma(a) * sigma(b)):\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("s = "), qadic_print_pretty(s, ctx), flint_printf("\n"); + flint_printf("s1 = "), qadic_print_pretty(s1, ctx), flint_printf("\n"); + flint_printf("s2 = "), qadic_print_pretty(s2, ctx), flint_printf("\n"); + flint_printf("lhs = "), qadic_print_pretty(lhs, ctx), flint_printf("\n"); + flint_printf("rhs = "), qadic_print_pretty(rhs, ctx), flint_printf("\n"); + flint_printf("e = %wd\n", e); + abort(); + } + + qadic_clear(a); + qadic_clear(b); + qadic_clear(s); + qadic_clear(s1); + qadic_clear(s2); + qadic_clear(lhs); + qadic_clear(rhs); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/qadic/test/t-inv.c b/external/flint-2.4.3/qadic/test/t-inv.c new file mode 100644 index 0000000..a009180 --- /dev/null +++ b/external/flint-2.4.3/qadic/test/t-inv.c @@ -0,0 +1,130 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include +#include + +#include "qadic.h" +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("inv... "); + fflush(stdout); + + + + /* Check aliasing: a = ~a */ + for (i = 0; i < 2000; i++) + { + fmpz_t p; + slong d, N; + qadic_ctx_t ctx; + + qadic_t a, b, c; + + fmpz_init_set_ui(p, n_randprime(state, 2 + n_randint(state, 3), 1)); + d = n_randint(state, 10) + 1; + N = z_randint(state, 50) + 1; + qadic_ctx_init_conway(ctx, p, d, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), "a", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + qadic_init2(c, N); + + qadic_randtest_not_zero(a, state, ctx); + qadic_set(b, a, ctx); + + qadic_inv(c, b, ctx); + qadic_inv(b, b, ctx); + + result = (qadic_equal(b, c)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), qadic_print_pretty(c, ctx), flint_printf("\n"); + abort(); + } + + qadic_clear(a); + qadic_clear(b); + qadic_clear(c); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + } + + /* Check a * ~a == 1 for units */ + for (i = 0; i < 2000; i++) + { + fmpz_t p; + slong d, N; + qadic_ctx_t ctx; + + qadic_t a, b; + + fmpz_init_set_ui(p, n_randprime(state, 2 + n_randint(state, 3), 1)); + d = n_randint(state, 10) + 1; + N = n_randint(state, 50) + 1; + qadic_ctx_init_conway(ctx, p, d, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), "a", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + + do qadic_randtest_val(a, state, 0, ctx); + while (qadic_is_zero(a)); + + qadic_inv(b, a, ctx); + qadic_mul(b, a, b, ctx); + + result = qadic_is_one(b); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + abort(); + } + + qadic_clear(a); + qadic_clear(b); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/qadic/test/t-log.c b/external/flint-2.4.3/qadic/test/t-log.c new file mode 100644 index 0000000..b6e73e6 --- /dev/null +++ b/external/flint-2.4.3/qadic/test/t-log.c @@ -0,0 +1,207 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include + +#include "qadic.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("log... "); + fflush(stdout); + + + +/** p == 2 *******************************************************************/ + +/** p > 2 ********************************************************************/ + + /* Check aliasing: a = log(a) */ + for (i = 0; i < 1000; i++) + { + fmpz_t p; + slong d, N; + slong ans1, ans2; + qadic_ctx_t ctx; + + qadic_t a, b; + + fmpz_init_set_ui(p, n_randprime(state, 3 + n_randint(state, 3), 1)); + d = n_randint(state, 10) + 1; + N = n_randint(state, 50) + 1; + qadic_ctx_init_conway(ctx, p, d, FLINT_MAX(0,N-10), FLINT_MAX(0,N+10), "a", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + + qadic_randtest_not_zero(a, state, ctx); + if (a->val < 1) + a->val = 1; + padic_poly_reduce(a, &ctx->pctx); + qadic_one(b); + qadic_add(a, a, b, ctx); + + ans1 = qadic_log(b, a, ctx); + ans2 = qadic_log(a, a, ctx); + + result = (ans1 == ans2) && (!ans1 || qadic_equal(a, b)); + if (!result) + { + flint_printf("FAIL (aliasing):\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + abort(); + } + + qadic_clear(a); + qadic_clear(b); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + } + + /* Check: log(a) + log(b) == log(a * b) */ + for (i = 0; i < 1000; i++) + { + fmpz_t p; + slong deg, N; + qadic_ctx_t ctx; + + qadic_t a, b, c, d, e, f, g; + + fmpz_init_set_ui(p, n_randprime(state, 3 + n_randint(state, 3), 1)); + deg = n_randint(state, 10) + 1; + N = n_randint(state, 50) + 1; + qadic_ctx_init_conway(ctx, p, deg, FLINT_MAX(0,N-10), FLINT_MAX(0,N+10), "a", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + qadic_init2(c, N); + qadic_init2(d, N); + qadic_init2(e, N); + qadic_init2(f, N); + qadic_init2(g, N); + + qadic_randtest_not_zero(a, state, ctx); + if (a->val < 1) + a->val = 1; + padic_poly_reduce(a, &ctx->pctx); + qadic_one(c); + qadic_add(a, a, c, ctx); + + qadic_randtest_not_zero(b, state, ctx); + if (b->val < 1) + b->val = 1; + padic_poly_reduce(b, &ctx->pctx); + qadic_one(c); + qadic_add(b, b, c, ctx); + + qadic_mul(c, a, b, ctx); + + qadic_log(d, a, ctx); + qadic_log(e, b, ctx); + qadic_add(f, d, e, ctx); + + qadic_log(g, c, ctx); + + result = (qadic_equal(f, g)); + if (!result) + { + flint_printf("FAIL (functional equation):\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = a * b = "), qadic_print_pretty(c, ctx), flint_printf("\n"); + flint_printf("d = log(a) = "), qadic_print_pretty(d, ctx), flint_printf("\n"); + flint_printf("e = log(b) = "), qadic_print_pretty(e, ctx), flint_printf("\n"); + flint_printf("f = log(a) + log(b) = "), qadic_print_pretty(f, ctx), flint_printf("\n"); + flint_printf("g = log(a * b) = "), qadic_print_pretty(g, ctx), flint_printf("\n"); + qadic_ctx_print(ctx); + abort(); + } + + qadic_clear(a); + qadic_clear(b); + qadic_clear(c); + qadic_clear(d); + qadic_clear(e); + qadic_clear(f); + qadic_clear(g); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + } + + /* Check: log(exp(x)) == x */ + for (i = 0; i < 1000; i++) + { + fmpz_t p; + slong deg, N; + qadic_ctx_t ctx; + + qadic_t a, b, c; + + fmpz_init_set_ui(p, n_randprime(state, 3 + n_randint(state, 3), 1)); + deg = n_randint(state, 10) + 1; + N = n_randint(state, 50) + 1; + qadic_ctx_init_conway(ctx, p, deg, FLINT_MAX(0,N-10), FLINT_MAX(0,N+10), "a", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + qadic_init2(c, N); + + qadic_randtest_val(a, state, (*p == WORD(2)) + 1, ctx); + + qadic_exp(b, a, ctx); + qadic_log(c, b, ctx); + + result = (qadic_equal(a, c)); + if (!result) + { + flint_printf("FAIL (log(exp(x)) == x):\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = exp(a) = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = log(b) = "), qadic_print_pretty(c, ctx), flint_printf("\n"); + abort(); + } + + qadic_clear(a); + qadic_clear(b); + qadic_clear(c); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/qadic/test/t-log_balanced.c b/external/flint-2.4.3/qadic/test/t-log_balanced.c new file mode 100644 index 0000000..eb045a0 --- /dev/null +++ b/external/flint-2.4.3/qadic/test/t-log_balanced.c @@ -0,0 +1,207 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012, 2013 Sebastian Pancratz + +******************************************************************************/ + +#include + +#include "qadic.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("log_balanced... "); + fflush(stdout); + + + +/** p == 2 *******************************************************************/ + +/** p > 2 ********************************************************************/ + + /* Check aliasing: a = log(a) */ + for (i = 0; i < 1000; i++) + { + fmpz_t p; + slong d, N; + slong ans1, ans2; + qadic_ctx_t ctx; + + qadic_t a, b; + + fmpz_init_set_ui(p, n_randprime(state, 3 + n_randint(state, 3), 1)); + d = n_randint(state, 10) + 1; + N = n_randint(state, 50) + 1; + qadic_ctx_init_conway(ctx, p, d, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), "a", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + + qadic_randtest_not_zero(a, state, ctx); + if (a->val < 1) + a->val = 1; + padic_poly_reduce(a, &ctx->pctx); + qadic_one(b); + qadic_add(a, a, b, ctx); + + ans1 = qadic_log_balanced(b, a, ctx); + ans2 = qadic_log_balanced(a, a, ctx); + + result = (ans1 == ans2) && (!ans1 || qadic_equal(a, b)); + if (!result) + { + flint_printf("FAIL (aliasing):\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + abort(); + } + + qadic_clear(a); + qadic_clear(b); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + } + + /* Check: log(a) + log(b) == log(a * b) */ + for (i = 0; i < 1000; i++) + { + fmpz_t p; + slong deg, N; + qadic_ctx_t ctx; + + qadic_t a, b, c, d, e, f, g; + + fmpz_init_set_ui(p, n_randprime(state, 3 + n_randint(state, 3), 1)); + deg = n_randint(state, 10) + 1; + N = n_randint(state, 50) + 1; + qadic_ctx_init_conway(ctx, p, deg, FLINT_MAX(0,N-10), FLINT_MAX(0,N+10), "a", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + qadic_init2(c, N); + qadic_init2(d, N); + qadic_init2(e, N); + qadic_init2(f, N); + qadic_init2(g, N); + + qadic_randtest_not_zero(a, state, ctx); + if (a->val < 1) + a->val = 1; + padic_poly_reduce(a, &ctx->pctx); + qadic_one(c); + qadic_add(a, a, c, ctx); + + qadic_randtest_not_zero(b, state, ctx); + if (b->val < 1) + b->val = 1; + padic_poly_reduce(b, &ctx->pctx); + qadic_one(c); + qadic_add(b, b, c, ctx); + + qadic_mul(c, a, b, ctx); + + qadic_log_balanced(d, a, ctx); + qadic_log_balanced(e, b, ctx); + qadic_add(f, d, e, ctx); + + qadic_log_balanced(g, c, ctx); + + result = (qadic_equal(f, g)); + if (!result) + { + flint_printf("FAIL (functional equation):\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = a * b = "), qadic_print_pretty(c, ctx), flint_printf("\n"); + flint_printf("d = log(a) = "), qadic_print_pretty(d, ctx), flint_printf("\n"); + flint_printf("e = log(b) = "), qadic_print_pretty(e, ctx), flint_printf("\n"); + flint_printf("f = log(a) + log(b) = "), qadic_print_pretty(f, ctx), flint_printf("\n"); + flint_printf("g = log(a * b) = "), qadic_print_pretty(g, ctx), flint_printf("\n"); + qadic_ctx_print(ctx); + abort(); + } + + qadic_clear(a); + qadic_clear(b); + qadic_clear(c); + qadic_clear(d); + qadic_clear(e); + qadic_clear(f); + qadic_clear(g); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + } + + /* Check: log(exp(x)) == x */ + for (i = 0; i < 1000; i++) + { + fmpz_t p; + slong deg, N; + qadic_ctx_t ctx; + + qadic_t a, b, c; + + fmpz_init_set_ui(p, n_randprime(state, 3 + n_randint(state, 3), 1)); + deg = n_randint(state, 10) + 1; + N = n_randint(state, 50) + 1; + qadic_ctx_init_conway(ctx, p, deg, FLINT_MAX(0,N-10), FLINT_MAX(0,N+10), "a", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + qadic_init2(c, N); + + qadic_randtest_val(a, state, (*p == WORD(2)) + 1, ctx); + + qadic_exp(b, a, ctx); + qadic_log_balanced(c, b, ctx); + + result = (qadic_equal(a, c)); + if (!result) + { + flint_printf("FAIL (log(exp(x)) == x):\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = exp(a) = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = log(b) = "), qadic_print_pretty(c, ctx), flint_printf("\n"); + abort(); + } + + qadic_clear(a); + qadic_clear(b); + qadic_clear(c); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/qadic/test/t-log_rectangular.c b/external/flint-2.4.3/qadic/test/t-log_rectangular.c new file mode 100644 index 0000000..3000bf1 --- /dev/null +++ b/external/flint-2.4.3/qadic/test/t-log_rectangular.c @@ -0,0 +1,206 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011, 2012 Sebastian Pancratz + +******************************************************************************/ + +#include + +#include "qadic.h" +#include "ulong_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("log_rectangular... "); + fflush(stdout); + + + +/** p == 2 *******************************************************************/ + +/** p > 2 ********************************************************************/ + + /* Check aliasing: a = log(a) */ + for (i = 0; i < 1000; i++) + { + fmpz_t p; + slong d, N; + slong ans1, ans2; + qadic_ctx_t ctx; + + qadic_t a, b; + + fmpz_init_set_ui(p, n_randprime(state, 2 + n_randint(state, 3), 1)); + d = n_randint(state, 10) + 1; + N = n_randint(state, 50) + 1; + qadic_ctx_init_conway(ctx, p, d, FLINT_MAX(0,N-10), FLINT_MAX(0,N+10), "a", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + + qadic_randtest_not_zero(a, state, ctx); + if (a->val < 1) + a->val = 1; + padic_poly_reduce(a, &ctx->pctx); + qadic_one(b); + qadic_add(a, a, b, ctx); + + ans1 = qadic_log_rectangular(b, a, ctx); + ans2 = qadic_log_rectangular(a, a, ctx); + + result = (ans1 == ans2) && (!ans1 || qadic_equal(a, b)); + if (!result) + { + flint_printf("FAIL (aliasing):\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + abort(); + } + + qadic_clear(a); + qadic_clear(b); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + } + + /* Check: log(a) + log(b) == log(a * b) */ + for (i = 0; i < 1000; i++) + { + fmpz_t p; + slong deg, N; + qadic_ctx_t ctx; + + qadic_t a, b, c, d, e, f, g; + + fmpz_init_set_ui(p, n_randprime(state, 3 + n_randint(state, 3), 1)); + deg = n_randint(state, 10) + 1; + N = n_randint(state, 50) + 1; + qadic_ctx_init_conway(ctx, p, deg, FLINT_MAX(0,N-10), FLINT_MAX(0,N+10), "a", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + qadic_init2(c, N); + qadic_init2(d, N); + qadic_init2(e, N); + qadic_init2(f, N); + qadic_init2(g, N); + + qadic_randtest_not_zero(a, state, ctx); + if (a->val < 1) + a->val = 1; + padic_poly_reduce(a, &ctx->pctx); + qadic_one(c); + qadic_add(a, a, c, ctx); + + qadic_randtest_not_zero(b, state, ctx); + if (b->val < 1) + b->val = 1; + padic_poly_reduce(b, &ctx->pctx); + qadic_one(c); + qadic_add(b, b, c, ctx); + + qadic_mul(c, a, b, ctx); + + qadic_log_rectangular(d, a, ctx); + qadic_log_rectangular(e, b, ctx); + qadic_add(f, d, e, ctx); + + qadic_log_rectangular(g, c, ctx); + + result = (qadic_equal(f, g)); + if (!result) + { + flint_printf("FAIL (functional equation):\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = a * b = "), qadic_print_pretty(c, ctx), flint_printf("\n"); + flint_printf("d = log(a) = "), qadic_print_pretty(d, ctx), flint_printf("\n"); + flint_printf("e = log(b) = "), qadic_print_pretty(e, ctx), flint_printf("\n"); + flint_printf("f = log(a) + log(b) = "), qadic_print_pretty(f, ctx), flint_printf("\n"); + flint_printf("g = log(a * b) = "), qadic_print_pretty(g, ctx), flint_printf("\n"); + abort(); + } + + qadic_clear(a); + qadic_clear(b); + qadic_clear(c); + qadic_clear(d); + qadic_clear(e); + qadic_clear(f); + qadic_clear(g); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + } + + /* Check: log(exp(x)) == x */ + for (i = 0; i < 1000; i++) + { + fmpz_t p; + slong deg, N; + qadic_ctx_t ctx; + + qadic_t a, b, c; + + fmpz_init_set_ui(p, n_randprime(state, 2 + n_randint(state, 3), 1)); + deg = n_randint(state, 10) + 1; + N = n_randint(state, 50) + 1; + qadic_ctx_init_conway(ctx, p, deg, FLINT_MAX(0,N-10), FLINT_MAX(0,N+10), "a", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + qadic_init2(c, N); + + qadic_randtest_val(a, state, (*p == WORD(2)) + 1, ctx); + + qadic_exp(b, a, ctx); + qadic_log_rectangular(c, b, ctx); + + result = (qadic_equal(a, c)); + if (!result) + { + flint_printf("FAIL (log(exp(x)) == x):\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), qadic_print_pretty(c, ctx), flint_printf("\n"); + abort(); + } + + qadic_clear(a); + qadic_clear(b); + qadic_clear(c); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/qadic/test/t-mul.c b/external/flint-2.4.3/qadic/test/t-mul.c new file mode 100644 index 0000000..6a9a903 --- /dev/null +++ b/external/flint-2.4.3/qadic/test/t-mul.c @@ -0,0 +1,267 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include +#include + +#include "qadic.h" +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("mul... "); + fflush(stdout); + + + + /* Check aliasing: a = a * b */ + for (i = 0; i < 2000; i++) + { + fmpz_t p; + slong d, N; + qadic_ctx_t ctx; + + qadic_t a, b, c; + + fmpz_init_set_ui(p, n_randprime(state, 2 + n_randint(state, 3), 1)); + d = n_randint(state, 10) + 1; + N = z_randint(state, 50) + 1; + qadic_ctx_init_conway(ctx, p, d, FLINT_MAX(0,N-10), FLINT_MAX(0,N+10), "a", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + qadic_init2(c, N); + + qadic_randtest(a, state, ctx); + qadic_randtest(b, state, ctx); + + qadic_mul(c, a, b, ctx); + qadic_mul(a, a, b, ctx); + + result = (qadic_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), qadic_print_pretty(c, ctx), flint_printf("\n"); + abort(); + } + + qadic_clear(a); + qadic_clear(b); + qadic_clear(c); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + } + + /* Check aliasing: b = a * b */ + for (i = 0; i < 2000; i++) + { + fmpz_t p; + slong d, N; + qadic_ctx_t ctx; + + qadic_t a, b, c; + + fmpz_init_set_ui(p, n_randprime(state, 2 + n_randint(state, 3), 1)); + d = n_randint(state, 10) + 1; + N = z_randint(state, 50) + 1; + qadic_ctx_init_conway(ctx, p, d, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), "a", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + qadic_init2(c, N); + + qadic_randtest(a, state, ctx); + qadic_randtest(b, state, ctx); + + qadic_mul(c, a, b, ctx); + qadic_mul(b, a, b, ctx); + + result = (qadic_equal(b, c)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), qadic_print_pretty(c, ctx), flint_printf("\n"); + abort(); + } + + qadic_clear(a); + qadic_clear(b); + qadic_clear(c); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + } + + /* Check aliasing: a = a + a */ + for (i = 0; i < 2000; i++) + { + fmpz_t p; + slong d, N; + qadic_ctx_t ctx; + + qadic_t a, c; + + fmpz_init_set_ui(p, n_randprime(state, 2 + n_randint(state, 3), 1)); + d = n_randint(state, 10) + 1; + N = z_randint(state, 50) + 1; + qadic_ctx_init_conway(ctx, p, d, FLINT_MAX(0,N-10), FLINT_MAX(0,N+10), "a", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(c, N); + + qadic_randtest(a, state, ctx); + + qadic_add(c, a, a, ctx); + qadic_add(a, a, a, ctx); + + result = (qadic_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("c = "), qadic_print_pretty(c, ctx), flint_printf("\n"); + abort(); + } + + qadic_clear(a); + qadic_clear(c); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + } + + /* Check that a * b == b * a */ + for (i = 0; i < 2000; i++) + { + fmpz_t p; + slong d, N; + qadic_ctx_t ctx; + + qadic_t a, b, c1, c2; + + fmpz_init_set_ui(p, n_randprime(state, 2 + n_randint(state, 3), 1)); + d = n_randint(state, 10) + 1; + N = z_randint(state, 50) + 1; + qadic_ctx_init_conway(ctx, p, d, FLINT_MAX(0,N-10), FLINT_MAX(0,N+10), "a", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + qadic_init2(c1, N); + qadic_init2(c2, N); + + qadic_randtest(a, state, ctx); + qadic_randtest(b, state, ctx); + + qadic_mul(c1, a, b, ctx); + qadic_mul(c2, b, a, ctx); + + result = (qadic_equal(c1, c2)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c1 = "), qadic_print_pretty(c1, ctx), flint_printf("\n"); + flint_printf("c2 = "), qadic_print_pretty(c2, ctx), flint_printf("\n"); + abort(); + } + + qadic_clear(a); + qadic_clear(b); + qadic_clear(c1); + qadic_clear(c2); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + } + + /* Check that (a * b) * c == a * (b * c) for integral values */ + for (i = 0; i < 2000; i++) + { + fmpz_t p; + slong d, N; + qadic_ctx_t ctx; + + qadic_t a, b, c, lhs, rhs; + + fmpz_init_set_ui(p, n_randprime(state, 2 + n_randint(state, 3), 1)); + d = n_randint(state, 10) + 1; + N = n_randint(state, 50) + 1; + qadic_ctx_init_conway(ctx, p, d, FLINT_MAX(0,N-10), FLINT_MAX(0,N+10), "a", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + qadic_init2(c, N); + qadic_init2(lhs, N); + qadic_init2(rhs, N); + + qadic_randtest_int(a, state, ctx); + qadic_randtest_int(b, state, ctx); + qadic_randtest_int(c, state, ctx); + + qadic_mul(lhs, a, b, ctx); + qadic_mul(lhs, lhs, c, ctx); + qadic_mul(rhs, b, c, ctx); + qadic_mul(rhs, a, rhs, ctx); + + result = (qadic_equal(lhs, rhs)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), qadic_print_pretty(c, ctx), flint_printf("\n"); + flint_printf("lhs = "), qadic_print_pretty(lhs, ctx), flint_printf("\n"); + flint_printf("rhs = "), qadic_print_pretty(rhs, ctx), flint_printf("\n"); + abort(); + } + + qadic_clear(a); + qadic_clear(b); + qadic_clear(c); + qadic_clear(lhs); + qadic_clear(rhs); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/qadic/test/t-neg.c b/external/flint-2.4.3/qadic/test/t-neg.c new file mode 100644 index 0000000..b428f9e --- /dev/null +++ b/external/flint-2.4.3/qadic/test/t-neg.c @@ -0,0 +1,137 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include +#include + +#include "qadic.h" +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("neg... "); + fflush(stdout); + + + + /* Check aliasing: a = -a */ + for (i = 0; i < 2000; i++) + { + fmpz_t p; + slong d, N; + qadic_ctx_t ctx; + + qadic_t a, b, c; + + fmpz_init_set_ui(p, n_randprime(state, 2 + n_randint(state, 3), 1)); + d = n_randint(state, 10) + 1; + N = z_randint(state, 50) + 1; + qadic_ctx_init_conway(ctx, p, d, FLINT_MAX(0,N-10), FLINT_MAX(0,N+10), "a", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + qadic_init2(c, N); + + qadic_randtest(a, state, ctx); + qadic_set(b, a, ctx); + + qadic_neg(c, b, ctx); + qadic_neg(b, b, ctx); + + result = (qadic_equal(b, c)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), qadic_print_pretty(c, ctx), flint_printf("\n"); + abort(); + } + + qadic_clear(a); + qadic_clear(b); + qadic_clear(c); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + } + + /* Check a - b == a + (-b) */ + for (i = 0; i < 2000; i++) + { + fmpz_t p; + slong d, N; + qadic_ctx_t ctx; + + qadic_t a, b, c1, c2; + + fmpz_init_set_ui(p, n_randprime(state, 2 + n_randint(state, 3), 1)); + d = n_randint(state, 10) + 1; + N = z_randint(state, 50) + 1; + qadic_ctx_init_conway(ctx, p, d, FLINT_MAX(0,N-10), FLINT_MAX(0,N+10), "a", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + qadic_init2(c1, N); + qadic_init2(c2, N); + + qadic_randtest(a, state, ctx); + qadic_randtest(b, state, ctx); + + qadic_sub(c1, a, b, ctx); + qadic_neg(c2, b, ctx); + qadic_add(c2, a, c2, ctx); + + result = (qadic_equal(c1, c2)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c1 = "), qadic_print_pretty(c1, ctx), flint_printf("\n"); + flint_printf("c2 = "), qadic_print_pretty(c2, ctx), flint_printf("\n"); + abort(); + } + + qadic_clear(a); + qadic_clear(b); + qadic_clear(c1); + qadic_clear(c2); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/qadic/test/t-norm.c b/external/flint-2.4.3/qadic/test/t-norm.c new file mode 100644 index 0000000..93fde4d --- /dev/null +++ b/external/flint-2.4.3/qadic/test/t-norm.c @@ -0,0 +1,111 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include + +#include "qadic.h" +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("norm... "); + fflush(stdout); + + + + /* Compare with product of Galois conjugates */ + for (i = 0; i < 2000; i++) + { + fmpz_t p; + slong d, N; + qadic_ctx_t ctx; + + qadic_t a, b, c; + padic_t x, y; + slong j; + int ans; + + fmpz_init_set_ui(p, n_randprime(state, 2 + n_randint(state, 3), 1)); + d = n_randint(state, 10) + 1; + N = z_randint(state, 50) + 1; + qadic_ctx_init_conway(ctx, p, d, FLINT_MAX(0,N-10), FLINT_MAX(0,N+10), "a", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + qadic_init2(c, N); + padic_init2(x, N); + padic_init2(y, N); + + qadic_randtest_val(a, state, 0, ctx); + qadic_reduce(a, ctx); + + qadic_norm(x, a, ctx); + + qadic_one(b); + for (j = 0; j < d; j++) + { + qadic_frobenius(c, a, j, ctx); + qadic_mul(b, b, c, ctx); + } + ans = qadic_get_padic(y, b, ctx); + + result = (ans && padic_equal(x, y)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("x = "), padic_print(x, &ctx->pctx), flint_printf("\n"); + flint_printf("y = "), padic_print(y, &ctx->pctx), flint_printf("\n"); + for (j = 0; j < d; j++) + { + qadic_frobenius(c, a, j, ctx); + flint_printf("sigma^%wd = ", j), qadic_print_pretty(c, ctx), flint_printf("\n"); + } + flint_printf("ans = %d\n", ans); + abort(); + } + + qadic_clear(a); + qadic_clear(b); + qadic_clear(c); + padic_clear(x); + padic_clear(y); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/qadic/test/t-norm_analytic.c b/external/flint-2.4.3/qadic/test/t-norm_analytic.c new file mode 100644 index 0000000..8eef502 --- /dev/null +++ b/external/flint-2.4.3/qadic/test/t-norm_analytic.c @@ -0,0 +1,113 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include + +#include "qadic.h" +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("norm_analytic... "); + fflush(stdout); + + + + /* Compare with product of Galois conjugates */ + for (i = 0; i < 2000; i++) + { + fmpz_t p; + slong d, N; + qadic_ctx_t ctx; + + qadic_t a, b, c; + padic_t x, y; + slong j; + int ans; + + fmpz_init_set_ui(p, n_randprime(state, 2 + n_randint(state, 3), 1)); + d = n_randint(state, 10) + 1; + N = z_randint(state, 50) + 1; + qadic_ctx_init_conway(ctx, p, d, FLINT_MAX(0,N-10), FLINT_MAX(0,N+10), "a", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + qadic_init2(c, N); + padic_init2(x, N); + padic_init2(y, N); + + qadic_randtest_val(a, state, fmpz_cmp_ui(p, 2) == 0 ? 2 : 1, ctx); + qadic_reduce(a, ctx); + qadic_one(b); + qadic_add(a, a, b, ctx); + + qadic_norm_analytic(x, a, ctx); + + qadic_one(b); + for (j = 0; j < d; j++) + { + qadic_frobenius(c, a, j, ctx); + qadic_mul(b, b, c, ctx); + } + ans = qadic_get_padic(y, b, ctx); + + result = (ans && padic_equal(x, y)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("x = "), padic_print(x, &ctx->pctx), flint_printf("\n"); + flint_printf("y = "), padic_print(y, &ctx->pctx), flint_printf("\n"); + for (j = 0; j < d; j++) + { + qadic_frobenius(c, a, j, ctx); + flint_printf("sigma^%wd = ", j), qadic_print_pretty(c, ctx), flint_printf("\n"); + } + flint_printf("ans = %d\n", ans); + abort(); + } + + qadic_clear(a); + qadic_clear(b); + qadic_clear(c); + padic_clear(x); + padic_clear(y); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/qadic/test/t-norm_resultant.c b/external/flint-2.4.3/qadic/test/t-norm_resultant.c new file mode 100644 index 0000000..94dd67b --- /dev/null +++ b/external/flint-2.4.3/qadic/test/t-norm_resultant.c @@ -0,0 +1,111 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include + +#include "qadic.h" +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("norm_resultant... "); + fflush(stdout); + + + + /* Compare with product of Galois conjugates */ + for (i = 0; i < 2000; i++) + { + fmpz_t p; + slong d, N; + qadic_ctx_t ctx; + + qadic_t a, b, c; + padic_t x, y; + slong j; + int ans; + + fmpz_init_set_ui(p, n_randprime(state, 2 + n_randint(state, 3), 1)); + d = n_randint(state, 10) + 1; + N = z_randint(state, 50) + 1; + qadic_ctx_init_conway(ctx, p, d, FLINT_MAX(0,N-10), FLINT_MAX(0,N+10), "a", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + qadic_init2(c, N); + padic_init2(x, N); + padic_init2(y, N); + + qadic_randtest_val(a, state, 0, ctx); + qadic_reduce(a, ctx); + + qadic_norm_resultant(x, a, ctx); + + qadic_one(b); + for (j = 0; j < d; j++) + { + qadic_frobenius(c, a, j, ctx); + qadic_mul(b, b, c, ctx); + } + ans = qadic_get_padic(y, b, ctx); + + result = (ans && padic_equal(x, y)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("x = "), padic_print(x, &ctx->pctx), flint_printf("\n"); + flint_printf("y = "), padic_print(y, &ctx->pctx), flint_printf("\n"); + for (j = 0; j < d; j++) + { + qadic_frobenius(c, a, j, ctx); + flint_printf("sigma^%wd = ", j), qadic_print_pretty(c, ctx), flint_printf("\n"); + } + flint_printf("ans = %d\n", ans); + abort(); + } + + qadic_clear(a); + qadic_clear(b); + qadic_clear(c); + padic_clear(x); + padic_clear(y); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/qadic/test/t-pow.c b/external/flint-2.4.3/qadic/test/t-pow.c new file mode 100644 index 0000000..d960bbf --- /dev/null +++ b/external/flint-2.4.3/qadic/test/t-pow.c @@ -0,0 +1,143 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include +#include + +#include "qadic.h" +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("pow... "); + fflush(stdout); + + + + /* Check aliasing: a = a^e */ + for (i = 0; i < 1000; i++) + { + fmpz_t p; + slong d, N; + qadic_ctx_t ctx; + + qadic_t a, b; + fmpz_t e; + + fmpz_init_set_ui(p, n_randprime(state, 2 + n_randint(state, 3), 1)); + d = n_randint(state, 10) + 1; + N = z_randint(state, 50) + 1; + qadic_ctx_init_conway(ctx, p, d, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), "a", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + fmpz_init(e); + + qadic_randtest(a, state, ctx); + fmpz_randtest_unsigned(e, state, 6); + + qadic_pow(b, a, e, ctx); + qadic_pow(a, a, e, ctx); + + result = (qadic_equal(a, b)); + if (!result) + { + flint_printf("FAIL (alias):\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + abort(); + } + + qadic_clear(a); + qadic_clear(b); + fmpz_clear(e); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + } + + /* Compare with multiplication, for integral values */ + for (i = 0; i < 1000; i++) + { + fmpz_t p; + slong d, N; + qadic_ctx_t ctx; + + qadic_t a, b, c; + fmpz_t e, f; + + fmpz_init_set_ui(p, n_randprime(state, 2 + n_randint(state, 3), 1)); + d = n_randint(state, 10) + 1; + N = n_randint(state, 50) + 1; + qadic_ctx_init_conway(ctx, p, d, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), "a", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + qadic_init2(c, N); + fmpz_init(f); + fmpz_init(e); + + qadic_randtest_int(a, state, ctx); + fmpz_randtest_unsigned(e, state, 6); + + qadic_pow(b, a, e, ctx); + qadic_one(c); + for (fmpz_one(f); fmpz_cmp(f, e) <= 0; fmpz_add_ui(f, f, 1)) + { + qadic_mul(c, c, a, ctx); + } + + result = (qadic_equal(b, c)); + if (!result) + { + flint_printf("FAIL (cmp with mul):\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("e = "), fmpz_print(e), flint_printf("\n"); + abort(); + } + + qadic_clear(a); + qadic_clear(b); + qadic_clear(c); + fmpz_clear(e); + fmpz_clear(f); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/qadic/test/t-sqrt.c b/external/flint-2.4.3/qadic/test/t-sqrt.c new file mode 100644 index 0000000..259e68e --- /dev/null +++ b/external/flint-2.4.3/qadic/test/t-sqrt.c @@ -0,0 +1,723 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include +#include + +#include "qadic.h" +#include "ulong_extras.h" +#include "long_extras.h" + +extern int +_artin_schreier_preimage(fmpz *rop, const fmpz *op, slong len, + const fmpz *a, const slong *j, slong lena); + +int main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("sqrt... "); + fflush(stdout); + + + +/* PRIME p = 2 ***************************************************************/ + + /* Check Artin Schreier preimages */ + for (i = 0; i < 2000; i++) + { + fmpz_t p = {WORD(2)}; + slong d; + qadic_ctx_t ctx; + + int ans; + qadic_t a, b, c; + + d = n_randint(state, 10) + 1; + qadic_ctx_init_conway(ctx, p, d, 1, 1, "X", PADIC_SERIES); + + qadic_init2(a, 1); + qadic_init2(b, 1); + qadic_init2(c, 1); + + qadic_randtest_val(a, state, 0, ctx); + padic_poly_fit_length(b, d); + + ans = _artin_schreier_preimage(b->coeffs, a->coeffs, a->length, + ctx->a, ctx->j, ctx->len); + + b->val = 0; + _padic_poly_set_length(b, d); + _padic_poly_normalise(b); + + if (ans) + { + qadic_mul(c, b, b, ctx); + qadic_add(c, c, b, ctx); + + result = qadic_equal(a, c); + + if (!result) + { + flint_printf("FAIL (Artin Schreier preimages):\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), qadic_print_pretty(c, ctx), flint_printf("\n"); + qadic_ctx_print(ctx); + abort(); + } + } + + qadic_clear(a); + qadic_clear(b); + qadic_clear(c); + + qadic_ctx_clear(ctx); + } + + /* Check aliasing: a = sqrt(a) */ + for (i = 0; i < 2000; i++) + { + fmpz_t p = {WORD(2)}; + slong d, N; + qadic_ctx_t ctx; + + int ans1, ans2; + qadic_t a, b, c; + + d = n_randint(state, 10) + 1; + N = z_randint(state, 50) + 1; + qadic_ctx_init_conway(ctx, p, d, FLINT_MAX(0,N-10), FLINT_MAX(0,N+10), "X", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + qadic_init2(c, N); + + qadic_randtest(a, state, ctx); + qadic_set(c, a, ctx); + + ans1 = qadic_sqrt(b, a, ctx); + ans2 = qadic_sqrt(a, a, ctx); + + result = ((ans1 == ans2) && (!ans1 || qadic_equal(a, b))); + if (!result) + { + flint_printf("FAIL (aliasing):\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), qadic_print_pretty(c, ctx), flint_printf("\n"); + flint_printf("ans1,ans2 = %d,%d\n", ans1, ans2); + qadic_ctx_print(ctx); + abort(); + } + + qadic_clear(a); + qadic_clear(b); + + qadic_ctx_clear(ctx); + } + + /* Test random squares over finite fields */ + for (i = 0; i < 2000; i++) + { + fmpz_t p = {WORD(2)}; + slong deg, N; + qadic_ctx_t ctx; + + int ans; + qadic_t a, b, c; + + deg = n_randint(state, 10) + 1; + N = 1; + qadic_ctx_init_conway(ctx, p, deg, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), "X", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + qadic_init2(c, N); + + qadic_randtest_val(b, state, 0, ctx); + qadic_mul(a, b, b, ctx); + + ans = qadic_sqrt(c, a, ctx); + if (ans) + { + qadic_t d, e; + qadic_init2(d, N + qadic_val(a)/2); + qadic_init2(e, N + qadic_val(a)/2); + + qadic_mul(d, c, c, ctx); + qadic_set(e, a, ctx); + + result = (qadic_equal(d, e)); + if (!result) + { + flint_printf("FAIL (a = b^2, c = sqrt(a), d = c^2 == a):\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), qadic_print_pretty(c, ctx), flint_printf("\n"); + flint_printf("d = "), qadic_print_pretty(d, ctx), flint_printf("\n"); + flint_printf("e = "), qadic_print_pretty(e, ctx), flint_printf("\n"); + flint_printf("ans = %d\n", ans); + flint_printf("N = %wd\n", N); + flint_printf("N + val(a)/2 = %wd\n", N + qadic_val(a)/2); + qadic_ctx_print(ctx); + abort(); + } + + qadic_clear(d); + qadic_clear(e); + } + /* there is no reason for that to work */ + /*else + { + flint_printf("FAIL (a = b^2, c = sqrt(a), d = c^2 == a):\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), qadic_print_pretty(c, ctx), flint_printf("\n"); + flint_printf("ans = %d\n", ans); + qadic_ctx_print(ctx); + abort(); + }*/ + + qadic_clear(a); + qadic_clear(b); + qadic_clear(c); + + qadic_ctx_clear(ctx); + } + + /* Test random elements over finite fields */ + for (i = 0; i < 2000; i++) + { + fmpz_t p = {WORD(2)}; + slong d, N; + qadic_ctx_t ctx; + + int ans; + qadic_t a, b; + + d = n_randint(state, 10) + 1; + N = 1; + + qadic_ctx_init_conway(ctx, p, d, FLINT_MAX(0,N-10), FLINT_MAX(0,N+10), "X", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + + qadic_randtest_val(a, state, 0, ctx); + + ans = qadic_sqrt(b, a, ctx); + if (ans) + { + qadic_t c, d; + qadic_init2(c, N + qadic_val(a)/2); + qadic_init2(d, N + qadic_val(a)/2); + + qadic_mul(c, b, b, ctx); + qadic_set(d, a, ctx); + + result = (qadic_equal(c, d)); + if (!result) + { + flint_printf("FAIL (random elements):\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), qadic_print_pretty(c, ctx), flint_printf("\n"); + flint_printf("d = "), qadic_print_pretty(d, ctx), flint_printf("\n"); + flint_printf("ans = %d\n", ans); + flint_printf("N = %wd\n", N); + flint_printf("N + val(a)/2 = %wd\n", N + qadic_val(a)/2); + qadic_ctx_print(ctx); + abort(); + } + + qadic_clear(c); + qadic_clear(d); + } + + qadic_clear(a); + qadic_clear(b); + + qadic_ctx_clear(ctx); + } + + /* Test random squares */ + for (i = 0; i < 2000; i++) + { + fmpz_t p = {WORD(2)}; + slong deg, N; + qadic_ctx_t ctx; + + int ans; + qadic_t a, b, c; + + deg = n_randint(state, 10) + 1; + /* N >= 3 */ + N = n_randint(state, 50) + 3; + + qadic_ctx_init_conway(ctx, p, deg, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), "X", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + qadic_init2(c, N); + + + qadic_randtest_val(b, state, 0, ctx); + qadic_randtest_int(b, state, ctx); + qadic_mul(a, b, b, ctx); + + ans = qadic_sqrt(c, a, ctx); + if (ans) + { + qadic_t d, e, u, v, w; + qadic_init2(d, N + qadic_val(a)/2); + qadic_init2(e, N + qadic_val(a)/2); + qadic_init2(u, N); + qadic_init2(v, N + qadic_val(a)/2); + qadic_init2(w, N + qadic_val(a)/2); + + qadic_mul(d, c, c, ctx); + qadic_set(e, a, ctx); + + result = (qadic_equal(d, e)); + if (!result) + { + flint_printf("FAIL (a = b^2, c = sqrt(a), d = c^2 == a):\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), qadic_print_pretty(c, ctx), flint_printf("\n"); + flint_printf("d = "), qadic_print_pretty(d, ctx), flint_printf("\n"); + flint_printf("e = "), qadic_print_pretty(e, ctx), flint_printf("\n"); + flint_printf("ans = %d\n", ans); + flint_printf("N = %wd\n", N); + flint_printf("N + val(a)/2 = %wd\n", N + qadic_val(a)/2); + qadic_ctx_print(ctx); + abort(); + } + + qadic_clear(d); + qadic_clear(e); + } + else + { + if (N - qadic_val(a) >= 3) + { + flint_printf("FAIL (a = b^2, c = sqrt(a), d = c^2 == a):\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), qadic_print_pretty(c, ctx), flint_printf("\n"); + flint_printf("ans = %d\n", ans); + flint_printf("N = %wd\n", N); + flint_printf("N + val(a)/2 = %wd\n", N + qadic_val(a)/2); + qadic_ctx_print(ctx); + abort(); + } + } + + qadic_clear(a); + qadic_clear(b); + qadic_clear(c); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + } + + /* Test random elements */ + for (i = 0; i < 2000; i++) + { + fmpz_t p = {WORD(2)}; + slong d, N; + qadic_ctx_t ctx; + + int ans; + qadic_t a, b; + + d = n_randint(state, 10) + 1; + N = z_randint(state, 50) + 1; + + qadic_ctx_init_conway(ctx, p, d, FLINT_MAX(0,N-10), FLINT_MAX(0,N+10), "X", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + + qadic_randtest(a, state, ctx); + + ans = qadic_sqrt(b, a, ctx); + if (ans) + { + qadic_t c, d; + qadic_init2(c, N + qadic_val(a)/2); + qadic_init2(d, N + qadic_val(a)/2); + + qadic_mul(c, b, b, ctx); + qadic_set(d, a, ctx); + + result = (qadic_equal(c, d)); + if (!result) + { + flint_printf("FAIL (random elements):\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), qadic_print_pretty(c, ctx), flint_printf("\n"); + flint_printf("d = "), qadic_print_pretty(d, ctx), flint_printf("\n"); + flint_printf("ans = %d\n", ans); + flint_printf("N = %wd\n", N); + flint_printf("N + val(a)/2 = %wd\n", N + qadic_val(a)/2); + qadic_ctx_print(ctx); + abort(); + } + + qadic_clear(c); + qadic_clear(d); + } + + qadic_clear(a); + qadic_clear(b); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + } + +/* PRIME p != 2 **************************************************************/ + + /* Check aliasing: a = sqrt(a) */ + for (i = 0; i < 2000; i++) + { + fmpz_t p; + slong d, N, q; + qadic_ctx_t ctx; + + int ans1, ans2; + qadic_t a, b, c; + + q = 2; + while (q == 2) + q = n_randprime(state, 2 + n_randint(state, 3), 1); + fmpz_init_set_ui(p, q); + d = n_randint(state, 10) + 1; + N = z_randint(state, 50) + 1; + qadic_ctx_init_conway(ctx, p, d, FLINT_MAX(0,N-10), FLINT_MAX(0,N+10), "X", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + qadic_init2(c, N); + + qadic_randtest(a, state, ctx); + qadic_set(c, a, ctx); + + ans1 = qadic_sqrt(b, a, ctx); + ans2 = qadic_sqrt(a, a, ctx); + + result = ((ans1 == ans2) && (!ans1 || qadic_equal(a, b))); + if (!result) + { + flint_printf("FAIL (aliasing):\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), qadic_print_pretty(c, ctx), flint_printf("\n"); + flint_printf("ans1,ans2 = %d,%d\n", ans1, ans2); + qadic_ctx_print(ctx); + abort(); + } + + qadic_clear(a); + qadic_clear(b); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + } + + /* Test random squares over finite fields */ + for (i = 0; i < 2000; i++) + { + fmpz_t p; + slong deg, N, q; + qadic_ctx_t ctx; + + int ans; + qadic_t a, b, c; + + q = 2; + while (q == 2) + q = n_randprime(state, 2 + n_randint(state, 3), 1); + fmpz_init_set_ui(p, q); + deg = n_randint(state, 10) + 1; + N = 1; + qadic_ctx_init_conway(ctx, p, deg, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), "X", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + qadic_init2(c, N); + + qadic_randtest_val(b, state, 0, ctx); + qadic_mul(a, b, b, ctx); + + ans = qadic_sqrt(c, a, ctx); + if (ans) + { + qadic_t d, e; + qadic_init2(d, N + qadic_val(a)/2); + qadic_init2(e, N + qadic_val(a)/2); + + qadic_mul(d, c, c, ctx); + qadic_set(e, a, ctx); + + result = (qadic_equal(d, e)); + if (!result) + { + flint_printf("FAIL (a = b^2, c = sqrt(a), d = c^2 == a):\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), qadic_print_pretty(c, ctx), flint_printf("\n"); + flint_printf("d = "), qadic_print_pretty(d, ctx), flint_printf("\n"); + flint_printf("e = "), qadic_print_pretty(e, ctx), flint_printf("\n"); + flint_printf("ans = %d\n", ans); + flint_printf("N = %wd\n", N); + flint_printf("N + val(a)/2 = %wd\n", N + qadic_val(a)/2); + qadic_ctx_print(ctx); + abort(); + } + + qadic_clear(d); + qadic_clear(e); + } + else + { + flint_printf("FAIL (a = b^2, c = sqrt(a), d = c^2 == a):\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), qadic_print_pretty(c, ctx), flint_printf("\n"); + flint_printf("ans = %d\n", ans); + qadic_ctx_print(ctx); + abort(); + } + + qadic_clear(a); + qadic_clear(b); + qadic_clear(c); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + } + + /* Test random elements over finite fields */ + for (i = 0; i < 2000; i++) + { + fmpz_t p; + slong d, N, q; + qadic_ctx_t ctx; + + int ans; + qadic_t a, b; + + q = 2; + while (q == 2) + q = n_randprime(state, 2 + n_randint(state, 3), 1); + fmpz_init_set_ui(p, q); + d = n_randint(state, 10) + 1; + N = 1; + + qadic_ctx_init_conway(ctx, p, d, FLINT_MAX(0,N-10), FLINT_MAX(0,N+10), "X", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + + qadic_randtest_val(a, state, 0, ctx); + + ans = qadic_sqrt(b, a, ctx); + if (ans) + { + qadic_t c, d; + qadic_init2(c, N + qadic_val(a)/2); + qadic_init2(d, N + qadic_val(a)/2); + + qadic_mul(c, b, b, ctx); + qadic_set(d, a, ctx); + + result = (qadic_equal(c, d)); + if (!result) + { + flint_printf("FAIL (random elements):\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), qadic_print_pretty(c, ctx), flint_printf("\n"); + flint_printf("d = "), qadic_print_pretty(d, ctx), flint_printf("\n"); + flint_printf("ans = %d\n", ans); + flint_printf("N = %wd\n", N); + flint_printf("N + val(a)/2 = %wd\n", N + qadic_val(a)/2); + qadic_ctx_print(ctx); + abort(); + } + + qadic_clear(c); + qadic_clear(d); + } + + qadic_clear(a); + qadic_clear(b); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + } + + /* Test random squares */ + for (i = 0; i < 2000; i++) + { + fmpz_t p; + slong deg, N, q; + qadic_ctx_t ctx; + + int ans; + qadic_t a, b, c; + + q = 2; + while (q == 2) + q = n_randprime(state, 2 + n_randint(state, 3), 1); + fmpz_init_set_ui(p, q); + deg = n_randint(state, 10) + 1; + N = z_randint(state, 50) + 1; + qadic_ctx_init_conway(ctx, p, deg, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), "X", PADIC_SERIES); + qadic_init2(a, N); + qadic_init2(b, N); + qadic_init2(c, N); + + qadic_randtest_val(b, state, 0, ctx); /* XXX */ + qadic_mul(a, b, b, ctx); + + ans = qadic_sqrt(c, a, ctx); + if (ans) + { + qadic_t d, e; + qadic_init2(d, N + qadic_val(a)/2); + qadic_init2(e, N + qadic_val(a)/2); + + qadic_mul(d, c, c, ctx); + qadic_set(e, a, ctx); + + result = (qadic_equal(d, e)); + if (!result) + { + flint_printf("FAIL (a = b^2, c = sqrt(a), d = c^2 == a):\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), qadic_print_pretty(c, ctx), flint_printf("\n"); + flint_printf("d = "), qadic_print_pretty(d, ctx), flint_printf("\n"); + flint_printf("e = "), qadic_print_pretty(e, ctx), flint_printf("\n"); + flint_printf("ans = %d\n", ans); + flint_printf("N = %wd\n", N); + flint_printf("N + val(a)/2 = %wd\n", N + qadic_val(a)/2); + qadic_ctx_print(ctx); + abort(); + } + + qadic_clear(d); + qadic_clear(e); + } + else + { + flint_printf("FAIL (a = b^2, c = sqrt(a), d = c^2 == a):\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), qadic_print_pretty(c, ctx), flint_printf("\n"); + flint_printf("ans = %d\n", ans); + qadic_ctx_print(ctx); + abort(); + } + + qadic_clear(a); + qadic_clear(b); + qadic_clear(c); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + } + + /* Test random elements */ + for (i = 0; i < 2000; i++) + { + fmpz_t p; + slong d, N, q; + qadic_ctx_t ctx; + + int ans; + qadic_t a, b; + + q = 2; + while (q == 2) + q = n_randprime(state, 2 + n_randint(state, 3), 1); + fmpz_init_set_ui(p, q); + d = n_randint(state, 10) + 1; + N = z_randint(state, 50) + 1; + + qadic_ctx_init_conway(ctx, p, d, FLINT_MAX(0,N-10), FLINT_MAX(0,N+10), "X", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + + qadic_randtest(a, state, ctx); + + ans = qadic_sqrt(b, a, ctx); + if (ans) + { + qadic_t c, d; + qadic_init2(c, N + qadic_val(a)/2); + qadic_init2(d, N + qadic_val(a)/2); + + qadic_mul(c, b, b, ctx); + qadic_set(d, a, ctx); + + result = (qadic_equal(c, d)); + if (!result) + { + flint_printf("FAIL (random elements):\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), qadic_print_pretty(c, ctx), flint_printf("\n"); + flint_printf("d = "), qadic_print_pretty(d, ctx), flint_printf("\n"); + flint_printf("ans = %d\n", ans); + flint_printf("N = %wd\n", N); + flint_printf("N + val(a)/2 = %wd\n", N + qadic_val(a)/2); + qadic_ctx_print(ctx); + abort(); + } + + qadic_clear(c); + qadic_clear(d); + } + + qadic_clear(a); + qadic_clear(b); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/qadic/test/t-sub.c b/external/flint-2.4.3/qadic/test/t-sub.c new file mode 100644 index 0000000..3153258 --- /dev/null +++ b/external/flint-2.4.3/qadic/test/t-sub.c @@ -0,0 +1,268 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include +#include + +#include "qadic.h" +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("sub... "); + fflush(stdout); + + + + /* Check aliasing: a = a - b */ + for (i = 0; i < 2000; i++) + { + fmpz_t p; + slong d, N; + qadic_ctx_t ctx; + + qadic_t a, b, c; + + fmpz_init_set_ui(p, n_randprime(state, 2 + n_randint(state, 3), 1)); + d = n_randint(state, 10) + 1; + N = z_randint(state, 50) + 1; + qadic_ctx_init_conway(ctx, p, d, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), "a", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + qadic_init2(c, N); + + qadic_randtest(a, state, ctx); + qadic_randtest(b, state, ctx); + + qadic_sub(c, a, b, ctx); + qadic_sub(a, a, b, ctx); + + result = (qadic_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), qadic_print_pretty(c, ctx), flint_printf("\n"); + abort(); + } + + qadic_clear(a); + qadic_clear(b); + qadic_clear(c); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + } + + /* Check aliasing: b = a - b */ + for (i = 0; i < 2000; i++) + { + fmpz_t p; + slong d, N; + qadic_ctx_t ctx; + + qadic_t a, b, c; + + fmpz_init_set_ui(p, n_randprime(state, 2 + n_randint(state, 3), 1)); + d = n_randint(state, 10) + 1; + N = z_randint(state, 50) + 1; + qadic_ctx_init_conway(ctx, p, d, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), "a", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + qadic_init2(c, N); + + qadic_randtest(a, state, ctx); + qadic_randtest(b, state, ctx); + + qadic_sub(c, a, b, ctx); + qadic_sub(b, a, b, ctx); + + result = (qadic_equal(b, c)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), qadic_print_pretty(c, ctx), flint_printf("\n"); + abort(); + } + + qadic_clear(a); + qadic_clear(b); + qadic_clear(c); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + } + + /* Check aliasing: a = a - a */ + for (i = 0; i < 2000; i++) + { + fmpz_t p; + slong d, N; + qadic_ctx_t ctx; + + qadic_t a, c; + + fmpz_init_set_ui(p, n_randprime(state, 2 + n_randint(state, 3), 1)); + d = n_randint(state, 10) + 1; + N = z_randint(state, 50) + 1; + qadic_ctx_init_conway(ctx, p, d, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), "a", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(c, N); + + qadic_randtest(a, state, ctx); + + qadic_sub(c, a, a, ctx); + qadic_sub(a, a, a, ctx); + + result = (qadic_equal(a, c)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("c = "), qadic_print_pretty(c, ctx), flint_printf("\n"); + abort(); + } + + qadic_clear(a); + qadic_clear(c); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + } + + /* Check that a - b == -(b - a) */ + for (i = 0; i < 2000; i++) + { + fmpz_t p; + slong d, N; + qadic_ctx_t ctx; + + qadic_t a, b, c1, c2; + + fmpz_init_set_ui(p, n_randprime(state, 2 + n_randint(state, 3), 1)); + d = n_randint(state, 10) + 1; + N = z_randint(state, 50) + 1; + qadic_ctx_init_conway(ctx, p, d, FLINT_MAX(0,N-10), FLINT_MAX(0,N+10), "a", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + qadic_init2(c1, N); + qadic_init2(c2, N); + + qadic_randtest(a, state, ctx); + qadic_randtest(b, state, ctx); + + qadic_sub(c1, a, b, ctx); + qadic_sub(c2, b, a, ctx); + qadic_neg(c2, c2, ctx); + + result = (qadic_equal(c1, c2)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c1 = "), qadic_print_pretty(c1, ctx), flint_printf("\n"); + flint_printf("c2 = "), qadic_print_pretty(c2, ctx), flint_printf("\n"); + abort(); + } + + qadic_clear(a); + qadic_clear(b); + qadic_clear(c1); + qadic_clear(c2); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + } + + /* Check that (a - b) - c == a - (b + c) */ + for (i = 0; i < 2000; i++) + { + fmpz_t p; + slong d, N; + qadic_ctx_t ctx; + + qadic_t a, b, c, lhs, rhs; + + fmpz_init_set_ui(p, n_randprime(state, 2 + n_randint(state, 3), 1)); + d = n_randint(state, 10) + 1; + N = z_randint(state, 50) + 1; + qadic_ctx_init_conway(ctx, p, d, FLINT_MAX(0,N-10), FLINT_MAX(0,N+10), "a", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + qadic_init2(c, N); + qadic_init2(lhs, N); + qadic_init2(rhs, N); + + qadic_randtest(a, state, ctx); + qadic_randtest(b, state, ctx); + qadic_randtest(c, state, ctx); + + qadic_sub(lhs, a, b, ctx); + qadic_sub(lhs, lhs, c, ctx); + qadic_add(rhs, b, c, ctx); + qadic_sub(rhs, a, rhs, ctx); + + result = (qadic_equal(lhs, rhs)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), qadic_print_pretty(c, ctx), flint_printf("\n"); + flint_printf("lhs = "), qadic_print_pretty(lhs, ctx), flint_printf("\n"); + flint_printf("rhs = "), qadic_print_pretty(rhs, ctx), flint_printf("\n"); + abort(); + } + + qadic_clear(a); + qadic_clear(b); + qadic_clear(c); + qadic_clear(lhs); + qadic_clear(rhs); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/qadic/test/t-teichmuller.c b/external/flint-2.4.3/qadic/test/t-teichmuller.c new file mode 100644 index 0000000..619dbcc --- /dev/null +++ b/external/flint-2.4.3/qadic/test/t-teichmuller.c @@ -0,0 +1,139 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include +#include + +#include "qadic.h" +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("teichmuller... "); + fflush(stdout); + + + + /* Check aliasing */ + for (i = 0; i < 100; i++) + { + fmpz_t p; + slong d, N; + qadic_ctx_t ctx; + + qadic_t a, b, c; + + fmpz_init_set_ui(p, n_randprime(state, 2 + n_randint(state, 3), 1)); + d = n_randint(state, 10) + 1; + N = n_randint(state, 50) + 1; + qadic_ctx_init_conway(ctx, p, d, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), "a", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + qadic_init2(c, N); + + qadic_randtest_int(a, state, ctx); + qadic_set(b, a, ctx); + + qadic_teichmuller(c, b, ctx); + qadic_teichmuller(b, b, ctx); + + result = (qadic_equal(b, c)); + if (!result) + { + flint_printf("FAIL (alias):\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), qadic_print_pretty(c, ctx), flint_printf("\n"); + abort(); + } + + qadic_clear(a); + qadic_clear(b); + qadic_clear(c); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + } + + /* Check x^q == x for units */ + for (i = 0; i < 100; i++) + { + fmpz_t p, q; + slong d, N; + qadic_ctx_t ctx; + + qadic_t a, b, c; + + fmpz_init_set_ui(p, n_randprime(state, 2 + n_randint(state, 3), 1)); + d = n_randint(state, 10) + 1; + N = n_randint(state, 50) + 1; + qadic_ctx_init_conway(ctx, p, d, FLINT_MAX(0, N-10), FLINT_MAX(0, N+10), "a", PADIC_SERIES); + + fmpz_init(q); + fmpz_pow_ui(q, p, d); + + qadic_init2(a, N); + qadic_init2(b, N); + qadic_init2(c, N); + + qadic_randtest_val(a, state, 0, ctx); + + qadic_teichmuller(b, a, ctx); + qadic_pow(c, b, q, ctx); + + result = (qadic_equal(c, b)); + if (!result) + { + flint_printf("FAIL (x^q == x):\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("c = "), qadic_print_pretty(c, ctx), flint_printf("\n"); + flint_printf("p = "), fmpz_print(p), flint_printf("\n"); + flint_printf("d = %wd\n", d); + flint_printf("N = %wd\n", N); + abort(); + } + + qadic_clear(a); + qadic_clear(b); + qadic_clear(c); + + fmpz_clear(p); + fmpz_clear(q); + qadic_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/qadic/test/t-trace.c b/external/flint-2.4.3/qadic/test/t-trace.c new file mode 100644 index 0000000..c64f75b --- /dev/null +++ b/external/flint-2.4.3/qadic/test/t-trace.c @@ -0,0 +1,111 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include + +#include "qadic.h" +#include "ulong_extras.h" +#include "long_extras.h" + +int +main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("trace... "); + fflush(stdout); + + + + /* Compare with sum of Galois conjugates */ + for (i = 0; i < 2000; i++) + { + fmpz_t p; + slong d, N; + qadic_ctx_t ctx; + + qadic_t a, b, c; + padic_t x, y; + slong j; + int ans; + + fmpz_init_set_ui(p, n_randprime(state, 2 + n_randint(state, 3), 1)); + d = n_randint(state, 10) + 1; + N = z_randint(state, 50) + 1; + qadic_ctx_init_conway(ctx, p, d, FLINT_MAX(0,N-10), FLINT_MAX(0,N+10), "a", PADIC_SERIES); + + qadic_init2(a, N); + qadic_init2(b, N); + qadic_init2(c, N); + padic_init2(x, N); + padic_init2(y, N); + + qadic_randtest(a, state, ctx); + + qadic_trace(x, a, ctx); + + qadic_zero(b); + for (j = 0; j < d; j++) + { + qadic_frobenius(c, a, j, ctx); + qadic_add(b, b, c, ctx); + } + ans = qadic_get_padic(y, b, ctx); + + result = (ans && padic_equal(x, y)); + if (!result) + { + flint_printf("FAIL:\n\n"); + flint_printf("a = "), qadic_print_pretty(a, ctx), flint_printf("\n"); + flint_printf("b = "), qadic_print_pretty(b, ctx), flint_printf("\n"); + flint_printf("x = "), padic_print(x, &ctx->pctx), flint_printf("\n"); + flint_printf("y = "), padic_print(y, &ctx->pctx), flint_printf("\n"); + for (j = 0; j < d; j++) + { + qadic_frobenius(c, a, j, ctx); + flint_printf("sigma^%wd = ", j), qadic_print_pretty(c, ctx), flint_printf("\n"); + } + flint_printf("ans = %d\n", ans); + qadic_ctx_print(ctx); + abort(); + } + + qadic_clear(a); + qadic_clear(b); + qadic_clear(c); + padic_clear(x); + padic_clear(y); + + fmpz_clear(p); + qadic_ctx_clear(ctx); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} + diff --git a/external/flint-2.4.3/qadic/trace.c b/external/flint-2.4.3/qadic/trace.c new file mode 100644 index 0000000..46737c6 --- /dev/null +++ b/external/flint-2.4.3/qadic/trace.c @@ -0,0 +1,90 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Sebastian Pancratz + +******************************************************************************/ + +#include "qadic.h" + +void _qadic_trace(fmpz_t rop, const fmpz *op, slong len, + const fmpz *a, const slong *j, slong lena, const fmpz_t pN) +{ + const slong d = j[lena - 1]; + + slong i, l; + fmpz *t; + + t = _fmpz_vec_init(d); + + fmpz_set_ui(t + 0, d); + for (i = 1; i < d; i++) + { + for (l = lena - 2; l >= 0 && j[l] >= d - (i - 1); l--) + { + fmpz_addmul(t + i, t + (j[l] + i - d), a + l); + } + + if (l >= 0 && j[l] == d - i) + { + fmpz_addmul_ui(t + i, a + l, i); + } + + fmpz_neg(t + i, t + i); + fmpz_mod(t + i, t + i, pN); + } + + fmpz_zero(rop); + for (i = 0; i < d; i++) + { + fmpz_addmul(rop, op + i, t + i); + } + fmpz_mod(rop, rop, pN); + + _fmpz_vec_clear(t, d); +} + +void qadic_trace(padic_t rop, const qadic_t op, const qadic_ctx_t ctx) +{ + const slong N = padic_prec(rop); + + if (qadic_is_zero(op) || op->val >= N) + { + padic_zero(rop); + } + else + { + fmpz_t pN; + int alloc; + + alloc = _padic_ctx_pow_ui(pN, N - op->val, &ctx->pctx); + + _qadic_trace(padic_unit(rop), op->coeffs, op->length, + ctx->a, ctx->j, ctx->len, pN); + padic_val(rop) = op->val; + + _padic_canonicalise(rop, &ctx->pctx); + + if (alloc) + fmpz_clear(pN); + } +} + diff --git a/external/flint-2.4.3/qadicxx.h b/external/flint-2.4.3/qadicxx.h new file mode 100644 index 0000000..081c11f --- /dev/null +++ b/external/flint-2.4.3/qadicxx.h @@ -0,0 +1,414 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Tom Bachmann + +******************************************************************************/ + +#ifndef QADICXX_H +#define QADICXX_H + +#include // std::max + +#include "qadic.h" + +#include "flintxx/expression.h" +#include "flintxx/flint_classes.h" +#include "flintxx/matrix.h" // trace ... + +#include "padicxx.h" + +namespace flint { +FLINT_DEFINE_BINOP(frobenius) +FLINT_DEFINE_UNOP(norm) +FLINT_DEFINE_UNOP(norm_analytic) +FLINT_DEFINE_UNOP(norm_resultant) + +class qadicxx_ctx +{ +private: + mutable qadic_ctx_t ctx; + +public: + // NB: you must not modify user-visible state of ctx through a constant + // instance of qadicxx_ctx + qadic_ctx_t& _ctx() const {return ctx;} + padicxx_ctx_srcref pctx() const + {return padicxx_ctx_srcref::make(&ctx->pctx);} + + // TODO more constructors? Should we wrap padic_print_mode? + qadicxx_ctx(fmpzxx_srcref p, slong d, slong min, slong max, + padic_print_mode mode, const char* var = "x") + { + qadic_ctx_init_conway(ctx, p._fmpz(), d, min, max, var, mode); + } + + ~qadicxx_ctx() {qadic_ctx_clear(ctx);} +}; + +inline void print(const qadicxx_ctx& c) +{ + qadic_ctx_print(c._ctx()); +} + +namespace traits { +template struct has_qadicxx_ctx : mp::false_ { }; + +template struct is_qadic_expr + : has_qadicxx_ctx::type> { }; +} // traits + +namespace detail { +struct has_qadicxx_ctx_predicate +{ + template struct type : traits::has_qadicxx_ctx { }; +}; +} // detail + +namespace tools { +template +const qadicxx_ctx& find_qadicxx_ctx(const Expr& e) +{ + return tools::find_subexpr(e).get_qctx(); +} +} // tools + +namespace detail { +template +struct qadic_traits +{ + static slong prec(const Qadic& q) {return tools::padic_output_prec(q);} +}; +} // detail + +template +class qadicxx_expression + : public expression, Operation, Data> +{ +public: + typedef expression, + Operation, Data> base_t; + + FLINTXX_DEFINE_BASICS(qadicxx_expression) + FLINTXX_DEFINE_CTORS(qadicxx_expression) + FLINTXX_DEFINE_C_REF(qadicxx_expression, qadic_struct, _qadic) + + typedef detail::qadic_traits traits_t; + + // These only make sense with immediates + void reduce() {qadic_reduce(_qadic(), _ctx());} + void set_zero() {qadic_zero(_qadic());} + void set_one() {qadic_one(_qadic());} + void set_gen() {qadic_gen(_qadic(), _ctx());} + + const qadicxx_ctx& get_qctx() const {return this->_data().ctx;} + padicxx_ctx_srcref get_ctx() const {return get_qctx().pctx();} + qadic_ctx_t& _ctx() const {return get_qctx()._ctx();} + + // these only make sense with qadicxx + static qadicxx_expression zero(const qadicxx_ctx& ctx) + {return qadicxx_expression(ctx);} + static qadicxx_expression zero(const qadicxx_ctx& ctx, slong N) + {return qadicxx_expression(ctx, N);} + static qadicxx_expression one(const qadicxx_ctx& ctx) + { + qadicxx_expression res(ctx); + res.set_one(); + return res; + } + static qadicxx_expression one(const qadicxx_ctx& ctx, slong N) + { + qadicxx_expression res(ctx, N); + res.set_one(); + return res; + } + static qadicxx_expression gen(const qadicxx_ctx& ctx) + { + qadicxx_expression res(ctx); + res.set_gen(); + return res; + } + static qadicxx_expression gen(const qadicxx_ctx& ctx, slong N) + { + qadicxx_expression res(ctx, N); + res.set_gen(); + return res; + } + + template + static qadicxx_expression from_ground(const qadicxx_ctx& ctx, + const Padic& p, + typename mp::enable_if >::type* = 0) + { + qadicxx_expression res(ctx); + res = p; + return res; + } + + template + static qadicxx_expression from_ground(const qadicxx_ctx& ctx, slong N, + const Padic& p, + typename mp::enable_if >::type* = 0) + { + qadicxx_expression res(ctx, N); + res = p; + return res; + } + + static qadicxx_expression randtest(frandxx& state, + const qadicxx_ctx& ctx, slong prec = PADIC_DEFAULT_PREC) + { + qadicxx_expression res(ctx, prec); + qadic_randtest(res._qadic(), state._data(), ctx._ctx()); + return res; + } + static qadicxx_expression randtest_not_zero(frandxx& state, + const qadicxx_ctx& ctx, slong prec = PADIC_DEFAULT_PREC) + { + qadicxx_expression res(ctx, prec); + qadic_randtest_not_zero(res._qadic(), state._data(), ctx._ctx()); + return res; + } + static qadicxx_expression randtest_val(frandxx& state, + slong val, const qadicxx_ctx& ctx, slong prec = PADIC_DEFAULT_PREC) + { + qadicxx_expression res(ctx, prec); + qadic_randtest_val(res._qadic(), state._data(), val, ctx._ctx()); + return res; + } + static qadicxx_expression randtest_int(frandxx& state, + const qadicxx_ctx& ctx, slong prec = PADIC_DEFAULT_PREC) + { + qadicxx_expression res(ctx, prec); + qadic_randtest_int(res._qadic(), state._data(), ctx._ctx()); + return res; + } + + const qadicxx_ctx& estimate_ctx() const + { + return tools::find_qadicxx_ctx(*this); + } + + // Create a temporary. The context will be estimated, and the precision + // will be the maximum of all subexpressions. + evaluated_t create_temporary() const + { + return evaluated_t(estimate_ctx(), prec()); + } + + // TODO randomisation + + typename flint_classes::to_srcref::type + toN(slong N) const + { + return flint_classes::to_srcref::type::make( + this->_data().inner, get_qctx(), N); + } + + slong prec () const {return traits_t::prec(*this);} + + // these cause evaluation + slong val() const {return qadic_val(this->evaluate()._qadic());} + bool is_zero() const {return qadic_is_zero(this->evaluate()._qadic());} + bool is_one() const {return qadic_is_one(this->evaluate()._qadic());} + + // forwarding of lazy functions + FLINTXX_DEFINE_MEMBER_BINOP(frobenius) + FLINTXX_DEFINE_MEMBER_BINOP(pow) + FLINTXX_DEFINE_MEMBER_UNOP(exp) + FLINTXX_DEFINE_MEMBER_UNOP(exp_balanced) + FLINTXX_DEFINE_MEMBER_UNOP(exp_rectangular) + FLINTXX_DEFINE_MEMBER_UNOP(inv) + FLINTXX_DEFINE_MEMBER_UNOP(log) + FLINTXX_DEFINE_MEMBER_UNOP(log_balanced) + FLINTXX_DEFINE_MEMBER_UNOP(teichmuller) + + FLINTXX_DEFINE_MEMBER_UNOP_RTYPE(padicxx, trace) + FLINTXX_DEFINE_MEMBER_UNOP_RTYPE(padicxx, norm) + FLINTXX_DEFINE_MEMBER_UNOP_RTYPE(padicxx, norm_analytic) + FLINTXX_DEFINE_MEMBER_UNOP_RTYPE(padicxx, norm_resultant) +}; + +namespace detail { +struct qadic_data; +} + +typedef qadicxx_expression qadicxx; +typedef qadicxx_expression > qadicxx_ref; +typedef qadicxx_expression > qadicxx_srcref; + +namespace traits { +template<> struct has_padicxx_ctx : mp::true_ { }; +template<> struct has_padicxx_ctx : mp::true_ { }; +template<> struct has_padicxx_ctx : mp::true_ { }; +template<> struct has_qadicxx_ctx : mp::true_ { }; +template<> struct has_qadicxx_ctx : mp::true_ { }; +template<> struct has_qadicxx_ctx : mp::true_ { }; + +template struct is_qadicxx : flint_classes::is_Base { }; +} // traits + +namespace detail { +template<> +struct qadic_traits +{ + template + static slong prec(const Q& q) {return q._data().N;} +}; +template<> +struct qadic_traits +{ + template + static slong prec(const Q& q) {return qadic_prec(q._qadic());} +}; +template<> struct qadic_traits : qadic_traits { }; +} + +PADICXX_DEFINE_REF_STRUCTS_(qadicxx, qadic_struct, qadic_prec, const qadicxx_ctx&) + +namespace detail { +struct qadic_data +{ + typedef qadic_t& data_ref_t; + typedef const qadic_t& data_srcref_t; + + const qadicxx_ctx& ctx; + qadic_t inner; + + qadic_data(const qadicxx_ctx& c) + : ctx(c) + { + qadic_init(inner); + } + + qadic_data(const qadicxx_ctx& c, slong N) + : ctx(c) + { + qadic_init2(inner, N); + } + + qadic_data(const qadic_data& o) + : ctx(o.ctx) + { + qadic_init2(inner, qadic_prec(o.inner)); + qadic_set(inner, o.inner, ctx._ctx()); + } + + ~qadic_data() {qadic_clear(inner);} + + qadic_data(qadicxx_srcref c) + : ctx(c.get_qctx()) + { + qadic_init2(inner, c.prec()); + qadic_set(inner, c._qadic(), ctx._ctx()); + } +}; +} // detail + +#define QADICXX_COND_S FLINTXX_COND_S(qadicxx) +#define QADICXX_COND_T FLINTXX_COND_T(qadicxx) + +namespace rules { +FLINT_DEFINE_DOIT_COND2(assignment, QADICXX_COND_T, QADICXX_COND_S, + qadic_set(to._qadic(), from._qadic(), to._ctx())) + +FLINT_DEFINE_DOIT_COND2(assignment, QADICXX_COND_T, traits::is_unsigned_integer, + qadic_set_ui(to._qadic(), from, to._ctx())) +FLINT_DEFINE_DOIT_COND2(assignment, QADICXX_COND_T, PADICXX_COND_S, + padic_poly_set_padic(to._qadic(), from._padic(), from._ctx())) + +FLINT_DEFINE_PRINT_PRETTY_COND(QADICXX_COND_S, + qadic_fprint_pretty(to, from._qadic(), from._ctx())) + +template +struct conversion >::type> +{ + static padicxx get(const T& from) + { + padicxx res(from.estimate_ctx().pctx(), from.prec()); + execution_check(qadic_get_padic(res._padic(), from._qadic(), from._ctx()), + "get_padic", "qadic"); + return res; + } +}; + +FLINTXX_DEFINE_SWAP(qadicxx, qadic_swap(e1._qadic(), e2._qadic())) + +FLINTXX_DEFINE_EQUALS(qadicxx, qadic_equal(e1._qadic(), e2._qadic())) + +FLINT_DEFINE_CBINARY_EXPR_COND2(plus, qadicxx, QADICXX_COND_S, QADICXX_COND_S, + qadic_add(to._qadic(), e1._qadic(), e2._qadic(), to._ctx())) +FLINT_DEFINE_BINARY_EXPR_COND2(minus, qadicxx, QADICXX_COND_S, QADICXX_COND_S, + qadic_sub(to._qadic(), e1._qadic(), e2._qadic(), to._ctx())) +FLINT_DEFINE_CBINARY_EXPR_COND2(times, qadicxx, QADICXX_COND_S, QADICXX_COND_S, + qadic_mul(to._qadic(), e1._qadic(), e2._qadic(), to._ctx())) + +FLINT_DEFINE_UNARY_EXPR_COND(negate, qadicxx, QADICXX_COND_S, + qadic_neg(to._qadic(), from._qadic(), to._ctx())) + +FLINT_DEFINE_UNARY_EXPR_COND(inv_op, qadicxx, QADICXX_COND_S, + qadic_inv(to._qadic(), from._qadic(), to._ctx())) +FLINT_DEFINE_BINARY_EXPR_COND2(pow_op, qadicxx, QADICXX_COND_S, + traits::is_fmpzxx, + qadic_pow(to._qadic(), e1._qadic(), e2._fmpz(), to._ctx())) + +FLINT_DEFINE_UNARY_EXPR_COND(exp_op, qadicxx, QADICXX_COND_S, + execution_check( + qadic_exp(to._qadic(), from._qadic(), to._ctx()), "exp", "qadic")) +FLINT_DEFINE_UNARY_EXPR_COND(exp_balanced_op, qadicxx, QADICXX_COND_S, + execution_check(qadic_exp_balanced( + to._qadic(), from._qadic(), to._ctx()), "exp_balanced", "qadic")) +FLINT_DEFINE_UNARY_EXPR_COND(exp_rectangular_op, qadicxx, QADICXX_COND_S, + execution_check(qadic_exp_rectangular( + to._qadic(), from._qadic(), to._ctx()), + "exp_rectangular", "qadic")) +FLINT_DEFINE_UNARY_EXPR_COND(log_op, qadicxx, QADICXX_COND_S, + execution_check( + qadic_log(to._qadic(), from._qadic(), to._ctx()), "log", "qadic")) +FLINT_DEFINE_UNARY_EXPR_COND(log_rectangular_op, qadicxx, QADICXX_COND_S, + execution_check(qadic_log_rectangular( + to._qadic(), from._qadic(), to._ctx()), + "log_rectangular", "qadic")) +FLINT_DEFINE_UNARY_EXPR_COND(log_balanced_op, qadicxx, QADICXX_COND_S, + execution_check(qadic_log_balanced( + to._qadic(), from._qadic(), to._ctx()), "log_balanced", "qadic")) +FLINT_DEFINE_UNARY_EXPR_COND(teichmuller_op, qadicxx, QADICXX_COND_S, + qadic_teichmuller(to._qadic(), from._qadic(), to._ctx())) + +FLINT_DEFINE_BINARY_EXPR_COND2(frobenius_op, qadicxx, QADICXX_COND_S, + traits::fits_into_slong, + qadic_frobenius(to._qadic(), e1._qadic(), e2, to._ctx())) + +FLINT_DEFINE_UNARY_EXPR_COND(trace_op, padicxx, QADICXX_COND_S, + qadic_trace(to._padic(), from._qadic(), from._ctx())) +FLINT_DEFINE_UNARY_EXPR_COND(norm_op, padicxx, QADICXX_COND_S, + qadic_norm(to._padic(), from._qadic(), from._ctx())) +FLINT_DEFINE_UNARY_EXPR_COND(norm_analytic_op, padicxx, QADICXX_COND_S, + qadic_norm_analytic(to._padic(), from._qadic(), from._ctx())) +FLINT_DEFINE_UNARY_EXPR_COND(norm_resultant_op, padicxx, QADICXX_COND_S, + qadic_norm_resultant(to._padic(), from._qadic(), from._ctx())) +} // rules +} // flint + +#endif diff --git a/external/flint-2.4.3/qsieve.h b/external/flint-2.4.3/qsieve.h new file mode 100644 index 0000000..cb28f33 --- /dev/null +++ b/external/flint-2.4.3/qsieve.h @@ -0,0 +1,309 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2006, 2011 William Hart + +******************************************************************************/ + +#ifndef QSIEVE_H +#define QSIEVE_H + +#include +#include "flint.h" +#include "fmpz.h" + +#ifdef __cplusplus + extern "C" { +#endif + +#if FLINT_BITS==64 + #ifndef uint64_t + #define uint64_t ulong + #endif +#else + #include +#endif + +/* + Debug verbosity (bits are as follows): + >0 - print headings for each phase of the sieve and some + simple data about the number of FB primes used, etc. + 2 - print poly A coeffs + 4 - print polynomials used + 8 - print relations + 16 - print statistics for sieve contents + 32 - print X values for each sieve entry that passes initial sieve test + 64 - print information about the number of duplicate relations + 128 - print lanczos information and errors +*/ +#define QS_DEBUG 0 + +#define CACHE_SIZE 65536 /* size of L1 cache */ + +typedef struct prime_t +{ + mp_limb_t pinv; /* precomputed inverse */ + int p; /* prime */ + char size; +} prime_t; + +typedef struct fac_t /* struct for factors of relations */ +{ + slong ind; + slong exp; +} fac_t; + +typedef struct la_col_t /* matrix column */ +{ + slong * data; /* The list of occupied rows in this column */ + slong weight; /* Number of nonzero entries in this column */ + slong orig; /* Original relation number */ +} la_col_t; + +typedef struct qs_s +{ + mp_limb_t hi; /* Number to factor */ + mp_limb_t lo; + + mp_bitcnt_t bits; /* Number of bits of n */ + + ulong ks_primes; /* number of Knuth-Schroeppel primes */ + + mp_limb_t k; /* Multiplier */ + fmpz_t kn; /* kn as a multiprecision integer */ + + slong num_primes; /* number of factor base primes including k and 2 */ + slong small_primes; /* number of primes to not sieve with */ + slong sieve_size; /* size of sieve to use */ + + prime_t * factor_base; /* data about factor base primes */ + + int * sqrts; /* square roots of kn mod factor base primes */ + + char sieve_bits; /* number of bits to exceed in sieve */ + + /****************** + Polynomial data + ******************/ + + mp_limb_t A; /* coefficient A */ + mp_limb_t B; /* coefficient B */ + fmpz_t C; /* coefficient C */ + + mp_limb_t * A_ind; /* indices of factor base primes dividing A */ + mp_limb_t * A_modp; /* (A/p) mod p for each prime p dividing A */ + mp_limb_t * inv_p2; /* newton inverse of p^2 for each factor p of A */ + + mp_limb_t * B_terms; /* + Let A_i = (A/p) mod p where p is the i-th prime + which is a factor of A, then B_terms[i] is + {p^(1/2) / A_i} mod p * (A/p) where we take + the smaller square root of p + */ + + mp_limb_t * A_inv; /* A^(-1) mod p */ + + mp_limb_t ** A_inv2B; /* A_inv[j][i] = 2*B_terms[j]*A^(-1) mod p */ + + mp_limb_t * soln1; /* first root of poly */ + mp_limb_t * soln2; /* second root of poly */ + + mp_limb_t target_A; /* approximate target value for A coeff of poly */ + + slong s; /* number of prime factors of A coeff */ + slong min; /* minimum FB prime that can appear as factor of A */ + slong span; /* size of set of possible prime factors of A */ + slong fact; /* middle of set of possible prime factors of A */ + slong mid; /* start of range for middle factor */ + slong high; /* end of range for middle factor */ + + + /********************* + Relations data + **********************/ + + slong qsort_rels; /* number of relations to accumulate before sorting */ + slong extra_rels; /* number of extra relations beyond num_primes */ + slong max_factors; /* maximum number of factors a relation can have */ + + slong * small; /* exponents of small prime factors in relations */ + fac_t * factor; /* factors for a relation */ + fmpz * Y_arr; /* array of Y's corresponding to relations */ + slong * curr_rel; /* current relation in array of relations */ + slong * relation; /* relation array */ + + slong buffer_size; /* size of buffer of relations */ + slong num_relations; /* number of relations so far */ + + slong num_factors; /* number of factors found in a relation */ + + /********************* + Linear algebra data + **********************/ + + la_col_t * matrix; /* the main matrix over GF(2) in sparse format */ + la_col_t * unmerged; /* unmerged matrix columns */ + la_col_t ** qsort_arr; /* array of columns ready to be sorted */ + + slong num_unmerged; /* number of columns unmerged */ + slong columns; /* number of columns in matrix so far */ + + /********************* + Square root data + **********************/ + + slong * prime_count; /* counts of the exponents of primes appearing in the square */ + + /********************* + Statistics + **********************/ + +#if (QS_DEBUG & 16) + slong * sieve_tally; +#endif + +} qs_s; + +typedef qs_s qs_t[1]; + +/* + Tuning parameters { bits, ks_primes, fb_primes, small_primes } + for qsieve_ll_factor where: + * bits is the number of bits of n + * ks_primes is the max number of primes to try in Knuth-Schroeppel algo + * fb_primes is the number of factor base primes to use (including k and 2) + * small_primes is the number of small primes to not factor with (including k and 2) + * sieve_size is the size of the sieve to use +*/ +static const mp_limb_t qsieve_ll_tune[][5] = +{ + {0, 50, 80, 2, 14000 }, + {30, 50, 80, 2, 16000 }, + {40, 50, 100, 3, 18000 }, + {50, 50, 120, 3, 20000 }, + {60, 50, 140, 4, 22000 }, + {70, 50, 160, 4, 24000 }, + {80, 100, 180, 5, 26000 }, + {90, 100, 200, 5, 28000 }, + {100, 100, 250, 6, 30000 }, + {110, 100, 300, 6, 34000 }, + {120, 100, 500, 7, 40000 }, + {130, 100, 550, 7, 60000 } +}; + +/* number of entries in the tuning table */ +#define QS_LL_TUNE_SIZE (sizeof(qsieve_ll_tune)/(5*sizeof(mp_limb_t))) + +#define P_GOODNESS 100 /* within what factor of target_A must A be */ +#define P_GOODNESS2 200 /* within what factor of target_A must A be when s = 2 */ + +#define BITS_ADJUST 10 /* no. bits less than f(X) to qualify for trial division */ + +void qsieve_ll_init(qs_t qs_inf, mp_limb_t hi, mp_limb_t lo); + +void qsieve_ll_clear(qs_t qs_inf); + +mp_limb_t qsieve_ll_knuth_schroeppel(qs_t qs_inf); + +mp_limb_t qsieve_ll_primes_init(qs_t qs_inf); + +mp_limb_t qsieve_ll_poly_init(qs_t qs_inf); + +void qsieve_ll_linalg_init(qs_t qs_inf); + +void qsieve_ll_compute_poly_data(qs_t qs_inf); + +void qsieve_ll_compute_A_factor_offsets(qs_t qs_inf); + +void qsieve_ll_compute_C(qs_t qs_inf); + +slong qsieve_ll_collect_relations(qs_t qs_inf, char * sieve); + +slong qsieve_ll_merge_sort(qs_t qs_inf); + +slong qsieve_ll_merge_relations(qs_t qs_inf); + +slong qsieve_ll_insert_relation(qs_t qs_inf, fmpz_t Y); + +mp_limb_t qsieve_ll_factor(mp_limb_t hi, mp_limb_t lo); + +static __inline__ void insert_col_entry(la_col_t * col, slong entry) +{ + if (((col->weight >> 4) << 4) == col->weight) /* need more space */ + { + if (col->weight != 0) col->data = + (slong *) flint_realloc(col->data, (col->weight + 16)*sizeof(slong)); + else col->data = (slong *) flint_malloc(16*sizeof(slong)); + } + + col->data[col->weight] = entry; + col->weight++; +} + +static __inline__ void copy_col(la_col_t * col2, la_col_t * col1) +{ + col2->weight = col1->weight; + col2->data = col1->data; + col2->orig = col1->orig; +} + +static __inline__ void swap_cols(la_col_t * col2, la_col_t * col1) +{ + la_col_t temp; + + temp.weight = col1->weight; + temp.data = col1->data; + temp.orig = col1->orig; + + col1->weight = col2->weight; + col1->data = col2->data; + col1->orig = col2->orig; + + col2->weight = temp.weight; + col2->data = temp.data; + col2->orig = temp.orig; +} + +static __inline__ void clear_col(la_col_t * col) +{ + col->weight = 0; +} + +static __inline__ void free_col(la_col_t * col) +{ + if (col->weight) flint_free(col->data); +} + +uint64_t get_null_entry(uint64_t * nullrows, slong i, slong l); + +void reduce_matrix(qs_t qs_inf, slong * nrows, slong * ncols, la_col_t * cols); + +uint64_t * block_lanczos(flint_rand_t state, slong nrows, slong dense_rows, + slong ncols, la_col_t *B); + +void qsieve_ll_square_root(fmpz_t X, fmpz_t Y, qs_t qs_inf, + uint64_t * nullrows, slong ncols, slong l, fmpz_t N); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/flint-2.4.3/qsieve/block_lanczos.c b/external/flint-2.4.3/qsieve/block_lanczos.c new file mode 100644 index 0000000..29fd9ac --- /dev/null +++ b/external/flint-2.4.3/qsieve/block_lanczos.c @@ -0,0 +1,970 @@ +/*============================================================================ + Copyright 2006 Jason Papadopoulos. + Copyright 2006, 2011 William Hart. + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================== + +Optionally, please be nice and tell me if you find this source to be +useful. Again optionally, if you add to the functionality present here +please consider making those additions public too, so that others may +benefit from your work. + --jasonp@boo.net 9/8/06 + +The following modifications were made by William Hart: + -added the utility function get_null_entry + -reformatted original code so it would operate as a standalone + filter and block Lanczos module +--------------------------------------------------------------------*/ + + +#define ulong ulongxx /* interferes with system includes */ +#include +#include +#include +#undef ulong +#define ulong mp_limb_t + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "qsieve.h" + +#define BIT(x) (((uint64_t)(1)) << (x)) + +static const uint64_t bitmask[64] = { + BIT( 0), BIT( 1), BIT( 2), BIT( 3), BIT( 4), BIT( 5), BIT( 6), BIT( 7), + BIT( 8), BIT( 9), BIT(10), BIT(11), BIT(12), BIT(13), BIT(14), BIT(15), + BIT(16), BIT(17), BIT(18), BIT(19), BIT(20), BIT(21), BIT(22), BIT(23), + BIT(24), BIT(25), BIT(26), BIT(27), BIT(28), BIT(29), BIT(30), BIT(31), + BIT(32), BIT(33), BIT(34), BIT(35), BIT(36), BIT(37), BIT(38), BIT(39), + BIT(40), BIT(41), BIT(42), BIT(43), BIT(44), BIT(45), BIT(46), BIT(47), + BIT(48), BIT(49), BIT(50), BIT(51), BIT(52), BIT(53), BIT(54), BIT(55), + BIT(56), BIT(57), BIT(58), BIT(59), BIT(60), BIT(61), BIT(62), BIT(63), +}; + +/*--------------------------------------------------------------------*/ +uint64_t get_null_entry(uint64_t * nullrows, slong i, slong l) { + + /* Returns true if the entry with indices i,l is 1 in the + supplied 64xN matrix. This is used to read the nullspace + vectors which are output by the Lanczos routine */ + + return nullrows[i]&bitmask[l]; +} + +/*--------------------------------------------------------------------*/ +void reduce_matrix(qs_t qs_inf, slong *nrows, slong *ncols, la_col_t *cols) { + + /* Perform light filtering on the nrows x ncols + matrix specified by cols[]. The processing here is + limited to deleting columns that contain a singleton + row, then resizing the matrix to have a few more + columns than rows. Because deleting a column reduces + the counts in several different rows, the process + must iterate to convergence. + + Note that this step is not intended to make the Lanczos + iteration run any faster (though it will); it's just + that if we don't go to this trouble then there are + factorizations for which the matrix step will fail + outright */ + + slong r, c, i, j, k; + slong passes; + slong *counts; + slong reduced_rows; + slong reduced_cols; + + /* count the number of nonzero entries in each row */ + + counts = (slong *)flint_calloc((size_t)*nrows, sizeof(slong)); + for (i = 0; i < *ncols; i++) { + for (j = 0; j < cols[i].weight; j++) + counts[cols[i].data[j]]++; + } + + reduced_rows = *nrows; + reduced_cols = *ncols; + passes = 0; + + do { + r = reduced_rows; + + /* remove any columns that contain the only entry + in one or more rows, then update the row counts + to reflect the missing column. Iterate until + no more columns can be deleted */ + + do { + c = reduced_cols; + for (i = j = 0; i < reduced_cols; i++) { + la_col_t *col = cols + i; + for (k = 0; k < col->weight; k++) { + if (counts[col->data[k]] < 2) + break; + } + + if (k < col->weight) { + for (k = 0; k < col->weight; k++) { + counts[col->data[k]]--; + } + free_col(col); + clear_col(col); + } + else { + cols[j++] = cols[i]; + if (j-1 != i) clear_col(col); + } + } + reduced_cols = j; + } while (c != reduced_cols); + + /* count the number of rows that contain a + nonzero entry */ + + for (i = reduced_rows = 0; i < *nrows; i++) { + if (counts[i]) + reduced_rows++; + } + + /* Because deleting a column reduces the weight + of many rows, the number of nonzero rows may + be much less than the number of columns. Delete + more columns until the matrix has the correct + aspect ratio. Columns at the end of cols[] are + the heaviest, so delete those (and update the + row counts again) */ + + if (reduced_cols > reduced_rows + qs_inf->extra_rels) { + for (i = reduced_rows + qs_inf->extra_rels; + i < reduced_cols; i++) { + + la_col_t *col = cols + i; + for (j = 0; j < col->weight; j++) { + counts[col->data[j]]--; + } + free_col(col); + clear_col(col); + } + reduced_cols = reduced_rows + qs_inf->extra_rels; + } + + /* if any columns were deleted in the previous step, + then the matrix is less dense and more columns + can be deleted; iterate until no further deletions + are possible */ + + passes++; + + } while (r != reduced_rows); + +#if (QS_DEBUG & 128) + flint_printf("reduce to %wd x %wd in %wd passes\n", + reduced_rows, reduced_cols, passes); +#endif + + flint_free(counts); + + /* record the final matrix size. Note that we can't touch + nrows because all the column data (and the sieving relations + that produced it) would have to be updated */ + + *ncols = reduced_cols; +} + +/*-------------------------------------------------------------------*/ +static void mul_64x64_64x64(uint64_t *a, uint64_t *b, uint64_t *c ) { + + /* c[][] = x[][] * y[][], where all operands are 64 x 64 + (i.e. contain 64 words of 64 bits each). The result + may overwrite a or b. */ + + uint64_t ai, bj, accum; + uint64_t tmp[64]; + ulong i, j; + + for (i = 0; i < 64; i++) { + j = 0; + accum = 0; + ai = a[i]; + + while (ai) { + bj = b[j]; + if( ai & 1 ) + accum ^= bj; + ai >>= 1; + j++; + } + + tmp[i] = accum; + } + memcpy(c, tmp, sizeof(tmp)); +} + +/*-----------------------------------------------------------------------*/ +static void precompute_Nx64_64x64(uint64_t *x, uint64_t *c) { + + /* Let x[][] be a 64 x 64 matrix in GF(2), represented + as 64 words of 64 bits each. Let c[][] be an 8 x 256 + matrix of 64-bit words. This code fills c[][] with + a bunch of "partial matrix multiplies". For 0<=i<256, + the j_th row of c[][] contains the matrix product + + ( i << (8*j) ) * x[][] + + where the quantity in parentheses is considered a + 1 x 64 vector of elements in GF(2). The resulting + table can dramatically speed up matrix multiplies + by x[][]. */ + + uint64_t accum, xk; + ulong i, j, k, index; + + for (j = 0; j < 8; j++) { + for (i = 0; i < 256; i++) { + k = 0; + index = i; + accum = 0; + while (index) { + xk = x[k]; + if (index & 1) + accum ^= xk; + index >>= 1; + k++; + } + c[i] = accum; + } + + x += 8; + c += 256; + } +} + +/*-------------------------------------------------------------------*/ +static void mul_Nx64_64x64_acc(uint64_t *v, uint64_t *x, uint64_t *c, + uint64_t *y, slong n) { + + /* let v[][] be a n x 64 matrix with elements in GF(2), + represented as an array of n 64-bit words. Let c[][] + be an 8 x 256 scratch matrix of 64-bit words. + This code multiplies v[][] by the 64x64 matrix + x[][], then XORs the n x 64 result into y[][] */ + + slong i; + uint64_t word; + + precompute_Nx64_64x64(x, c); + + for (i = 0; i < n; i++) { + word = v[i]; + y[i] ^= c[ 0*256 + ((word>> 0) & 0xff) ] + ^ c[ 1*256 + ((word>> 8) & 0xff) ] + ^ c[ 2*256 + ((word>>16) & 0xff) ] + ^ c[ 3*256 + ((word>>24) & 0xff) ] + ^ c[ 4*256 + ((word>>32) & 0xff) ] + ^ c[ 5*256 + ((word>>40) & 0xff) ] + ^ c[ 6*256 + ((word>>48) & 0xff) ] + ^ c[ 7*256 + ((word>>56) ) ]; + } +} + +/*-------------------------------------------------------------------*/ +static void mul_64xN_Nx64(uint64_t *x, uint64_t *y, + uint64_t *c, uint64_t *xy, slong n) { + + /* Let x and y be n x 64 matrices. This routine computes + the 64 x 64 matrix xy[][] given by transpose(x) * y. + c[][] is a 256 x 8 scratch matrix of 64-bit words. */ + + slong i; + + memset(c, 0, 256 * 8 * sizeof(uint64_t)); + memset(xy, 0, 64 * sizeof(uint64_t)); + + for (i = 0; i < n; i++) { + uint64_t xi = x[i]; + uint64_t yi = y[i]; + c[ 0*256 + ( xi & 0xff) ] ^= yi; + c[ 1*256 + ((xi >> 8) & 0xff) ] ^= yi; + c[ 2*256 + ((xi >> 16) & 0xff) ] ^= yi; + c[ 3*256 + ((xi >> 24) & 0xff) ] ^= yi; + c[ 4*256 + ((xi >> 32) & 0xff) ] ^= yi; + c[ 5*256 + ((xi >> 40) & 0xff) ] ^= yi; + c[ 6*256 + ((xi >> 48) & 0xff) ] ^= yi; + c[ 7*256 + ((xi >> 56) ) ] ^= yi; + } + + + for(i = 0; i < 8; i++) { + + ulong j; + uint64_t a0, a1, a2, a3, a4, a5, a6, a7; + + a0 = a1 = a2 = a3 = 0; + a4 = a5 = a6 = a7 = 0; + + for (j = 0; j < 256; j++) { + if ((j >> i) & 1) { + a0 ^= c[0*256 + j]; + a1 ^= c[1*256 + j]; + a2 ^= c[2*256 + j]; + a3 ^= c[3*256 + j]; + a4 ^= c[4*256 + j]; + a5 ^= c[5*256 + j]; + a6 ^= c[6*256 + j]; + a7 ^= c[7*256 + j]; + } + } + + xy[ 0] = a0; xy[ 8] = a1; xy[16] = a2; xy[24] = a3; + xy[32] = a4; xy[40] = a5; xy[48] = a6; xy[56] = a7; + xy++; + } +} + +/*-------------------------------------------------------------------*/ +static slong find_nonsingular_sub(uint64_t *t, slong *s, + slong *last_s, slong last_dim, + uint64_t *w) { + + /* given a 64x64 matrix t[][] (i.e. sixty-four + 64-bit words) and a list of 'last_dim' column + indices enumerated in last_s[]: + + - find a submatrix of t that is invertible + - invert it and copy to w[][] + - enumerate in s[] the columns represented in w[][] */ + + slong i, j; + slong dim; + slong cols[64]; + uint64_t M[64][2]; + uint64_t mask, *row_i, *row_j; + uint64_t m0, m1; + + /* M = [t | I] for I the 64x64 identity matrix */ + + for (i = 0; i < 64; i++) { + M[i][0] = t[i]; + M[i][1] = bitmask[i]; + } + + /* put the column indices from last_s[] into the + back of cols[], and copy to the beginning of cols[] + any column indices not in last_s[] */ + + mask = 0; + for (i = 0; i < last_dim; i++) { + cols[63 - i] = last_s[i]; + mask |= bitmask[last_s[i]]; + } + for (i = j = 0; i < 64; i++) { + if (!(mask & bitmask[i])) + cols[j++] = i; + } + + /* compute the inverse of t[][] */ + + for (i = dim = 0; i < 64; i++) { + + /* find the next pivot row and put in row i */ + + mask = bitmask[cols[i]]; + row_i = M[cols[i]]; + + for (j = i; j < 64; j++) { + row_j = M[cols[j]]; + if (row_j[0] & mask) { + m0 = row_j[0]; + m1 = row_j[1]; + row_j[0] = row_i[0]; + row_j[1] = row_i[1]; + row_i[0] = m0; + row_i[1] = m1; + break; + } + } + + /* if a pivot row was found, eliminate the pivot + column from all other rows */ + + if (j < 64) { + for (j = 0; j < 64; j++) { + row_j = M[cols[j]]; + if ((row_i != row_j) && (row_j[0] & mask)) { + row_j[0] ^= row_i[0]; + row_j[1] ^= row_i[1]; + } + } + + /* add the pivot column to the list of + accepted columns */ + + s[dim++] = cols[i]; + continue; + } + + /* otherwise, use the right-hand half of M[] + to compensate for the absence of a pivot column */ + + for (j = i; j < 64; j++) { + row_j = M[cols[j]]; + if (row_j[1] & mask) { + m0 = row_j[0]; + m1 = row_j[1]; + row_j[0] = row_i[0]; + row_j[1] = row_i[1]; + row_i[0] = m0; + row_i[1] = m1; + break; + } + } + + if (j == 64) { +#if (QS_DEBUG & 128) + flint_printf("lanczos error: submatrix " + "is not invertible\n"); +#endif + return 0; + } + + /* eliminate the pivot column from the other rows + of the inverse */ + + for (j = 0; j < 64; j++) { + row_j = M[cols[j]]; + if ((row_i != row_j) && (row_j[1] & mask)) { + row_j[0] ^= row_i[0]; + row_j[1] ^= row_i[1]; + } + } + + /* wipe out the pivot row */ + + row_i[0] = row_i[1] = 0; + } + + /* the right-hand half of M[] is the desired inverse */ + + for (i = 0; i < 64; i++) + w[i] = M[i][1]; + + /* The block Lanczos recurrence depends on all columns + of t[][] appearing in s[] and/or last_s[]. + Verify that condition here */ + + mask = 0; + for (i = 0; i < dim; i++) + mask |= bitmask[s[i]]; + for (i = 0; i < last_dim; i++) + mask |= bitmask[last_s[i]]; + + if (mask != (uint64_t)(-1)) { +#if (QS_DEBUG & 128) + flint_printf("lanczos error: not all columns used\n"); +#endif + return 0; + } + + return dim; +} + +/*-------------------------------------------------------------------*/ +void mul_MxN_Nx64(slong vsize, slong dense_rows, + slong ncols, la_col_t *A, + uint64_t *x, uint64_t *b) { + + /* Multiply the vector x[] by the matrix A (stored + columnwise) and put the result in b[]. vsize + refers to the number of uint64_t's allocated for + x[] and b[]; vsize is probably different from ncols */ + + slong i, j; + + memset(b, 0, vsize * sizeof(uint64_t)); + + for (i = 0; i < ncols; i++) { + la_col_t *col = A + i; + slong *row_entries = col->data; + uint64_t tmp = x[i]; + + for (j = 0; j < col->weight; j++) { + b[row_entries[j]] ^= tmp; + } + } + + if (dense_rows) { + for (i = 0; i < ncols; i++) { + la_col_t *col = A + i; + slong *row_entries = col->data + col->weight; + uint64_t tmp = x[i]; + + for (j = 0; j < dense_rows; j++) { + if (row_entries[j / 32] & + ((slong)1 << (j % 32))) { + b[j] ^= tmp; + } + } + } + } +} + +/*-------------------------------------------------------------------*/ +void mul_trans_MxN_Nx64(slong dense_rows, slong ncols, + la_col_t *A, uint64_t *x, uint64_t *b) { + + /* Multiply the vector x[] by the transpose of the + matrix A and put the result in b[]. Since A is stored + by columns, this is just a matrix-vector product */ + + slong i, j; + + for (i = 0; i < ncols; i++) { + la_col_t *col = A + i; + slong *row_entries = col->data; + uint64_t accum = 0; + + for (j = 0; j < col->weight; j++) { + accum ^= x[row_entries[j]]; + } + b[i] = accum; + } + + if (dense_rows) { + for (i = 0; i < ncols; i++) { + la_col_t *col = A + i; + slong *row_entries = col->data + col->weight; + uint64_t accum = b[i]; + + for (j = 0; j < dense_rows; j++) { + if (row_entries[j / 32] & + ((slong)1 << (j % 32))) { + accum ^= x[j]; + } + } + b[i] = accum; + } + } +} + +/*-----------------------------------------------------------------------*/ +static void transpose_vector(slong ncols, uint64_t *v, uint64_t **trans) { + + /* Hideously inefficent routine to transpose a + vector v[] of 64-bit words into a 2-D array + trans[][] of 64-bit words */ + + slong i, j; + slong col; + uint64_t mask, word; + + for (i = 0; i < ncols; i++) { + col = i / 64; + mask = bitmask[i % 64]; + word = v[i]; + j = 0; + while (word) { + if (word & 1) + trans[j][col] |= mask; + word = word >> 1; + j++; + } + } +} + +/*-----------------------------------------------------------------------*/ +void combine_cols(slong ncols, + uint64_t *x, uint64_t *v, + uint64_t *ax, uint64_t *av) { + + /* Once the block Lanczos iteration has finished, + x[] and v[] will contain mostly nullspace vectors + between them, as well as possibly some columns + that are linear combinations of nullspace vectors. + Given vectors ax[] and av[] that are the result of + multiplying x[] and v[] by the matrix, this routine + will use Gauss elimination on the columns of [ax | av] + to find all of the linearly dependent columns. The + column operations needed to accomplish this are mir- + rored in [x | v] and the columns that are independent + are skipped. Finally, the dependent columns are copied + back into x[] and represent the nullspace vector output + of the block Lanczos code. + + v[] and av[] can be NULL, in which case the elimination + process assumes 64 dependencies instead of 128 */ + + slong i, j, k, bitpos, col, col_words, num_deps; + uint64_t mask; + uint64_t *matrix[128], *amatrix[128], *tmp; + + num_deps = 128; + if (v == NULL || av == NULL) + num_deps = 64; + + col_words = (ncols + 63) / 64; + + for (i = 0; i < num_deps; i++) { + matrix[i] = (uint64_t *)flint_calloc((size_t)col_words, + sizeof(uint64_t)); + amatrix[i] = (uint64_t *)flint_calloc((size_t)col_words, + sizeof(uint64_t)); + } + + /* operations on columns can more conveniently become + operations on rows if all the vectors are first + transposed */ + + transpose_vector(ncols, x, matrix); + transpose_vector(ncols, ax, amatrix); + if (num_deps == 128) { + transpose_vector(ncols, v, matrix + 64); + transpose_vector(ncols, av, amatrix + 64); + } + + /* Keep eliminating rows until the unprocessed part + of amatrix[][] is all zero. The rows where this + happens correspond to linearly dependent vectors + in the nullspace */ + + for (i = bitpos = 0; i < num_deps && bitpos < ncols; bitpos++) { + + /* find the next pivot row */ + + mask = bitmask[bitpos % 64]; + col = bitpos / 64; + for (j = i; j < num_deps; j++) { + if (amatrix[j][col] & mask) { + tmp = matrix[i]; + matrix[i] = matrix[j]; + matrix[j] = tmp; + tmp = amatrix[i]; + amatrix[i] = amatrix[j]; + amatrix[j] = tmp; + break; + } + } + if (j == num_deps) + continue; + + /* a pivot was found; eliminate it from the + remaining rows */ + + for (j++; j < num_deps; j++) { + if (amatrix[j][col] & mask) { + + /* Note that the entire row, *not* + just the nonzero part of it, must + be eliminated; this is because the + corresponding (dense) row of matrix[][] + must have the same operation applied */ + + for (k = 0; k < col_words; k++) { + amatrix[j][k] ^= amatrix[i][k]; + matrix[j][k] ^= matrix[i][k]; + } + } + } + i++; + } + + /* transpose rows i to 64 back into x[] */ + + for (j = 0; j < ncols; j++) { + uint64_t word = 0; + + col = j / 64; + mask = bitmask[j % 64]; + + for (k = i; k < 64; k++) { + if (matrix[k][col] & mask) + word |= bitmask[k]; + } + x[j] = word; + } + + for (i = 0; i < num_deps; i++) { + flint_free(matrix[i]); + flint_free(amatrix[i]); + } +} + +/*-----------------------------------------------------------------------*/ +uint64_t * block_lanczos(flint_rand_t state, slong nrows, + slong dense_rows, slong ncols, la_col_t *B) { + + /* Solve Bx = 0 for some nonzero x; the computed + solution, containing up to 64 of these nullspace + vectors, is returned */ + + uint64_t *vnext, *v[3], *x, *v0; + uint64_t *winv[3]; + uint64_t *vt_a_v[2], *vt_a2_v[2]; + uint64_t *scratch; + uint64_t *d, *e, *f, *f2; + uint64_t *tmp; + slong s[2][64]; + slong i, iter; + slong n = ncols; + slong dim0, dim1; + uint64_t mask0, mask1; + slong vsize; + + /* allocate all of the size-n variables. Note that because + B has been preprocessed to ignore singleton rows, the + number of rows may really be less than nrows and may + be greater than ncols. vsize is the maximum of these + two numbers */ + + vsize = FLINT_MAX(nrows, ncols); + v[0] = (uint64_t *)flint_malloc(vsize * sizeof(uint64_t)); + v[1] = (uint64_t *)flint_malloc(vsize * sizeof(uint64_t)); + v[2] = (uint64_t *)flint_malloc(vsize * sizeof(uint64_t)); + vnext = (uint64_t *)flint_malloc(vsize * sizeof(uint64_t)); + x = (uint64_t *)flint_malloc(vsize * sizeof(uint64_t)); + v0 = (uint64_t *)flint_malloc(vsize * sizeof(uint64_t)); + scratch = (uint64_t *)flint_malloc(FLINT_MAX(vsize, 256 * 8) * sizeof(uint64_t)); + + /* allocate all the 64x64 variables */ + + winv[0] = (uint64_t *)flint_malloc(64 * sizeof(uint64_t)); + winv[1] = (uint64_t *)flint_malloc(64 * sizeof(uint64_t)); + winv[2] = (uint64_t *)flint_malloc(64 * sizeof(uint64_t)); + vt_a_v[0] = (uint64_t *)flint_malloc(64 * sizeof(uint64_t)); + vt_a_v[1] = (uint64_t *)flint_malloc(64 * sizeof(uint64_t)); + vt_a2_v[0] = (uint64_t *)flint_malloc(64 * sizeof(uint64_t)); + vt_a2_v[1] = (uint64_t *)flint_malloc(64 * sizeof(uint64_t)); + d = (uint64_t *)flint_malloc(64 * sizeof(uint64_t)); + e = (uint64_t *)flint_malloc(64 * sizeof(uint64_t)); + f = (uint64_t *)flint_malloc(64 * sizeof(uint64_t)); + f2 = (uint64_t *)flint_malloc(64 * sizeof(uint64_t)); + + /* The iterations computes v[0], vt_a_v[0], + vt_a2_v[0], s[0] and winv[0]. Subscripts larger + than zero represent past versions of these + quantities, which start off empty (except for + the past version of s[], which contains all + the column indices */ + + memset(v[1], 0, vsize * sizeof(uint64_t)); + memset(v[2], 0, vsize * sizeof(uint64_t)); + for (i = 0; i < 64; i++) { + s[1][i] = i; + vt_a_v[1][i] = 0; + vt_a2_v[1][i] = 0; + winv[1][i] = 0; + winv[2][i] = 0; + } + dim0 = 0; + dim1 = 64; + mask1 = (uint64_t)(-1); + iter = 0; + + /* The computed solution 'x' starts off random, + and v[0] starts off as B*x. This initial copy + of v[0] must be saved off separately */ + + for (i = 0; i < n; i++) +#if FLINT_BITS==64 + v[0][i] = (uint64_t) n_randlimb(state); +#else + v[0][i] = (uint64_t) n_randlimb(state) + ((uint64_t) n_randlimb(state) << 32); +#endif + + memcpy(x, v[0], vsize * sizeof(uint64_t)); + mul_MxN_Nx64(vsize, dense_rows, ncols, B, v[0], scratch); + mul_trans_MxN_Nx64(dense_rows, ncols, B, scratch, v[0]); + memcpy(v0, v[0], vsize * sizeof(uint64_t)); + + /* perform the iteration */ + + while (1) { + iter++; + + /* multiply the current v[0] by a symmetrized + version of B, or B'B (apostrophe means + transpose). Use "A" to refer to B'B */ + + mul_MxN_Nx64(vsize, dense_rows, ncols, B, v[0], scratch); + mul_trans_MxN_Nx64(dense_rows, ncols, B, scratch, vnext); + + /* compute v0'*A*v0 and (A*v0)'(A*v0) */ + + mul_64xN_Nx64(v[0], vnext, scratch, vt_a_v[0], n); + mul_64xN_Nx64(vnext, vnext, scratch, vt_a2_v[0], n); + + /* if the former is orthogonal to itself, then + the iteration has finished */ + + for (i = 0; i < 64; i++) { + if (vt_a_v[0][i] != 0) + break; + } + if (i == 64) { + break; + } + + /* Find the size-'dim0' nonsingular submatrix + of v0'*A*v0, invert it, and list the column + indices present in the submatrix */ + + dim0 = find_nonsingular_sub(vt_a_v[0], s[0], + s[1], dim1, winv[0]); + if (dim0 == 0) + break; + + /* mask0 contains one set bit for every column + that participates in the inverted submatrix + computed above */ + + mask0 = 0; + for (i = 0; i < dim0; i++) + mask0 |= bitmask[s[0][i]]; + + /* compute d */ + + for (i = 0; i < 64; i++) + d[i] = (vt_a2_v[0][i] & mask0) ^ vt_a_v[0][i]; + + mul_64x64_64x64(winv[0], d, d); + + for (i = 0; i < 64; i++) + d[i] = d[i] ^ bitmask[i]; + + /* compute e */ + + mul_64x64_64x64(winv[1], vt_a_v[0], e); + + for (i = 0; i < 64; i++) + e[i] = e[i] & mask0; + + /* compute f */ + + mul_64x64_64x64(vt_a_v[1], winv[1], f); + + for (i = 0; i < 64; i++) + f[i] = f[i] ^ bitmask[i]; + + mul_64x64_64x64(winv[2], f, f); + + for (i = 0; i < 64; i++) + f2[i] = ((vt_a2_v[1][i] & mask1) ^ + vt_a_v[1][i]) & mask0; + + mul_64x64_64x64(f, f2, f); + + /* compute the next v */ + + for (i = 0; i < n; i++) + vnext[i] = vnext[i] & mask0; + + mul_Nx64_64x64_acc(v[0], d, scratch, vnext, n); + mul_Nx64_64x64_acc(v[1], e, scratch, vnext, n); + mul_Nx64_64x64_acc(v[2], f, scratch, vnext, n); + + /* update the computed solution 'x' */ + + mul_64xN_Nx64(v[0], v0, scratch, d, n); + mul_64x64_64x64(winv[0], d, d); + mul_Nx64_64x64_acc(v[0], d, scratch, x, n); + + /* rotate all the variables */ + + tmp = v[2]; + v[2] = v[1]; + v[1] = v[0]; + v[0] = vnext; + vnext = tmp; + + tmp = winv[2]; + winv[2] = winv[1]; + winv[1] = winv[0]; + winv[0] = tmp; + + tmp = vt_a_v[1]; vt_a_v[1] = vt_a_v[0]; vt_a_v[0] = tmp; + + tmp = vt_a2_v[1]; vt_a2_v[1] = vt_a2_v[0]; vt_a2_v[0] = tmp; + + memcpy(s[1], s[0], 64 * sizeof(slong)); + mask1 = mask0; + dim1 = dim0; + } + +#if (QS_DEBUG & 128) + flint_printf("lanczos halted after %wd iterations\n", iter); +#endif + + /* free unneeded storage */ + + + flint_free(vnext); + flint_free(scratch); + flint_free(v0); + flint_free(vt_a_v[0]); + flint_free(vt_a_v[1]); + flint_free(vt_a2_v[0]); + flint_free(vt_a2_v[1]); + flint_free(winv[0]); + flint_free(winv[1]); + flint_free(winv[2]); + flint_free(d); + flint_free(e); + flint_free(f); + flint_free(f2); + + /* if a recoverable failure occurred, start everything + over again */ + + if (dim0 == 0) { +#if (QS_DEBUG & 128) + flint_printf("linear algebra failed; retrying...\n"); +#endif + flint_free(x); + flint_free(v[0]); + flint_free(v[1]); + flint_free(v[2]); + return NULL; + } + + /* convert the output of the iteration to an actual + collection of nullspace vectors */ + + mul_MxN_Nx64(vsize, dense_rows, ncols, B, x, v[1]); + mul_MxN_Nx64(vsize, dense_rows, ncols, B, v[0], v[2]); + + combine_cols(ncols, x, v[0], v[1], v[2]); + + /* verify that these really are linear dependencies of B */ + + mul_MxN_Nx64(vsize, dense_rows, ncols, B, x, v[0]); + + for (i = 0; i < ncols; i++) { + if (v[0][i] != 0) + break; + } + if (i < ncols) { + flint_printf("lanczos error: dependencies don't work %wd\n",i); + abort(); + } + + flint_free(v[0]); + flint_free(v[1]); + flint_free(v[2]); + return x; +} diff --git a/external/flint-2.4.3/qsieve/doc/qsieve.txt b/external/flint-2.4.3/qsieve/doc/qsieve.txt new file mode 100644 index 0000000..f5f4a04 --- /dev/null +++ b/external/flint-2.4.3/qsieve/doc/qsieve.txt @@ -0,0 +1,42 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 William Hart + +******************************************************************************/ + +******************************************************************************* + + Quadratic sieve + +******************************************************************************* + +mp_limb_t qsieve_ll_factor(mp_limb_t hi, mp_limb_t lo) + + Given an integer \code{n = (hi, lo)} find a factor and return it. + If a tiny factor is encountered, this is returned very quickly. + Otherwise the quadratic sieve algorithm is employed. The algorithm + requires that $n$ not be prime and not be a perfect power. There is + also a limit to the size of $n$. During the algorithm $n$ will be + multiplied by a small multiplier $k$ (from 1 to 47). The product + $kn$ must fit in two limbs. If not the algorithm will silently + fail, returning 0. Otherwise a factor of $n$ which fits in a single + limb will be returned. diff --git a/external/flint-2.4.3/qsieve/ll_clear.c b/external/flint-2.4.3/qsieve/ll_clear.c new file mode 100644 index 0000000..7e30c9a --- /dev/null +++ b/external/flint-2.4.3/qsieve/ll_clear.c @@ -0,0 +1,96 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2006, 2011 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "qsieve.h" +#include "fmpz.h" + +void qsieve_ll_clear(qs_t qs_inf) +{ + slong i; + + fmpz_clear(qs_inf->kn); + fmpz_clear(qs_inf->C); + + flint_free(qs_inf->factor_base); + flint_free(qs_inf->sqrts); + flint_free(qs_inf->B_terms); + flint_free(qs_inf->A_inv); + + if (qs_inf->A_inv2B != NULL) + flint_free(qs_inf->A_inv2B[0]); + + flint_free(qs_inf->A_inv2B); + + qs_inf->factor_base = NULL; + qs_inf->sqrts = NULL; + qs_inf->B_terms = NULL; + qs_inf->A_inv = NULL; + qs_inf->A_inv2B = NULL; + + flint_free(qs_inf->small); + flint_free(qs_inf->factor); + flint_free(qs_inf->relation); + flint_free(qs_inf->qsort_arr); + + if (qs_inf->matrix != NULL) + { + for (i = 0; i < qs_inf->buffer_size + qs_inf->num_unmerged; i++) + { + la_col_t * col = qs_inf->matrix + i; + if (col->weight) + flint_free(col->data); + } + + flint_free(qs_inf->matrix); + } + + if (qs_inf->Y_arr != NULL) + { + for (i = 0; i < qs_inf->buffer_size; i++) + fmpz_clear(qs_inf->Y_arr + i); + flint_free(qs_inf->Y_arr); + } + + flint_free(qs_inf->prime_count); + + qs_inf->small = NULL; + qs_inf->factor = NULL; + qs_inf->matrix = NULL; + qs_inf->Y_arr = NULL; + qs_inf->relation = NULL; + qs_inf->qsort_arr = NULL; + + qs_inf->prime_count = NULL; + + qs_inf->A = 0; + +#if (QS_DEBUG & 16) + flint_free(qs_inf->sieve_tally); + qs_inf->sieve_tally = NULL; +#endif +} diff --git a/external/flint-2.4.3/qsieve/ll_collect_relations.c b/external/flint-2.4.3/qsieve/ll_collect_relations.c new file mode 100644 index 0000000..217aa75 --- /dev/null +++ b/external/flint-2.4.3/qsieve/ll_collect_relations.c @@ -0,0 +1,407 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2006, 2011 William Hart + +******************************************************************************/ + +#define ulong ulongxx /* interferes with system includes */ +#include +#include +#include +#undef ulong +#define ulong mp_limb_t + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "qsieve.h" +#include "fmpz.h" + +void qsieve_ll_do_sieving(qs_t qs_inf, char * sieve) +{ + slong num_primes = qs_inf->num_primes; + mp_limb_t * soln1 = qs_inf->soln1; + mp_limb_t * soln2 = qs_inf->soln2; + prime_t * factor_base = qs_inf->factor_base; + mp_limb_t p; + char * end = sieve + qs_inf->sieve_size; + register char * pos1; + register char * pos2; + register char * bound; + slong size; + slong diff; + slong pind; + + memset(sieve, 0, qs_inf->sieve_size + sizeof(ulong)); + *end = (char) 255; + + for (pind = qs_inf->small_primes; pind < num_primes; pind++) + { + if (soln2[pind] == -1) continue; /* don't sieve with A factors */ + + p = factor_base[pind].p; + size = factor_base[pind].size; + pos1 = sieve + soln1[pind]; + pos2 = sieve + soln2[pind]; + diff = pos2 - pos1; + bound = end - 2*p; + + while (bound - pos1 > 0) + { + (*pos1) += size, (*(pos1 + diff)) += size, pos1 += p; + (*pos1) += size, (*(pos1 + diff)) += size, pos1 += p; + } + + while ((end - pos1 > 0) && (end - pos1 - diff > 0)) + { + (*pos1) += size, (*(pos1 + diff)) += size, pos1 += p; + } + + pos2 = pos1 + diff; + + if (end - pos2 > 0) + { + (*pos2) += size; + } + + if (end - pos1 > 0) + { + (*pos1) += size; + } + } +} + +slong qsieve_ll_evaluate_candidate(qs_t qs_inf, slong i, char * sieve) +{ + slong bits, exp, extra_bits; + mp_limb_t modp, prime; + slong num_primes = qs_inf->num_primes; + prime_t * factor_base = qs_inf->factor_base; + fac_t * factor = qs_inf->factor; + mp_limb_t * soln1 = qs_inf->soln1; + mp_limb_t * soln2 = qs_inf->soln2; + slong * small = qs_inf->small; + mp_limb_t A = qs_inf->A; + mp_limb_t B = qs_inf->B; + mp_limb_t pinv; + slong num_factors = 0; + slong relations = 0; + slong j; + + fmpz_t X, Y, res, p; + fmpz_init(X); + fmpz_init(Y); + fmpz_init(res); + fmpz_init(p); + + fmpz_set_ui(X, i); + fmpz_sub_ui(X, X, qs_inf->sieve_size/2); /* X */ + +#if (QS_DEBUG & 32) + flint_printf("i = "); fmpz_print(X); flint_printf("\n"); +#endif + + fmpz_mul_ui(Y, X, A); + if ((mp_limb_signed_t) B < 0) + { + fmpz_sub_ui(Y, Y, -B); /* Y = AX + B */ + fmpz_sub_ui(res, Y, -B); + } else + { + fmpz_add_ui(Y, Y, B); + fmpz_add_ui(res, Y, B); + } + fmpz_mul(res, res, X); + fmpz_add(res, res, qs_inf->C); /* res = AX^2 + 2BX + C */ + + bits = FLINT_ABS(fmpz_bits(res)); + bits -= BITS_ADJUST; + extra_bits = 0; + + fmpz_set_ui(p, 2); /* divide out by powers of 2 */ + exp = fmpz_remove(res, res, p); + +#if (QS_DEBUG & 8) + if (exp) flint_printf("2^%wd ", exp); +#endif + + extra_bits += exp; + small[1] = exp; + + if (factor_base[0].p != 1) /* divide out powers of the multiplier */ + { + fmpz_set_ui(p, factor_base[0].p); + exp = fmpz_remove(res, res, p); + if (exp) extra_bits += exp*qs_inf->factor_base[0].size; + small[0] = exp; + +#if (QS_DEBUG & 8) + if (exp) flint_printf("%d^%wd ", factor_base[0].p, exp); +#endif + } else small[0] = 0; + + for (j = 2; j < qs_inf->small_primes; j++) /* pull out small primes */ + { + prime = factor_base[j].p; + pinv = factor_base[j].pinv; + modp = n_mod2_preinv(i, prime, pinv); + if ((modp == soln1[j]) || (modp == soln2[j])) + { + fmpz_set_ui(p, prime); + exp = fmpz_remove(res, res, p); + if (exp) extra_bits += qs_inf->factor_base[j].size; + small[j] = exp; + +#if (QS_DEBUG & 8) + if (exp) + { + fmpz_print(p); + flint_printf("^%wd ", exp); + } +#endif + } else small[j] = 0; + } + + if (extra_bits + sieve[i] > bits) + { + sieve[i] += extra_bits; + + /* pull out remaining primes */ + for (j = qs_inf->small_primes; j < num_primes && extra_bits < sieve[i]; j++) + { + prime = factor_base[j].p; + pinv = factor_base[j].pinv; + modp = n_mod2_preinv(i, prime, pinv); + if (soln2[j] != -1) + { + if ((modp == soln1[j]) || (modp == soln2[j])) + { + fmpz_set_ui(p, prime); + exp = fmpz_remove(res, res, p); +#if (QS_DEBUG & 8) + if (exp) + { + fmpz_print(p); + flint_printf("^%wd ", exp); + } +#endif + if (exp) + { + extra_bits += qs_inf->factor_base[j].size; + factor[num_factors].ind = j; + factor[num_factors++].exp = exp; + } + } + } else + { + fmpz_set_ui(p, prime); + exp = fmpz_remove(res, res, p); + factor[num_factors].ind = j; + factor[num_factors++].exp = exp + 1; + +#if (QS_DEBUG & 8) + if (exp) + { + fmpz_print(p); + flint_printf("^%wd ", exp); + } +#endif + } + } + + if (fmpz_cmp_ui(res, 1) == 0 || fmpz_cmp_si(res, -1) == 0) /* We've found a relation */ + { + mp_limb_t * A_ind = qs_inf->A_ind; + slong i; + + for (i = 0; i < qs_inf->s; i++) /* Commit any outstanding A factors */ + { + if (A_ind[i] >= j) + { + factor[num_factors].ind = A_ind[i]; + factor[num_factors++].exp = 1; + } + } + + qs_inf->num_factors = num_factors; + relations += qsieve_ll_insert_relation(qs_inf, Y); /* Insert the relation in the matrix */ + + if (qs_inf->num_relations >= qs_inf->buffer_size) + { + flint_printf("Error: too many duplicate relations!\n"); + flint_printf("s = %wd, bits = %wd\n", qs_inf->s, qs_inf->bits); + abort(); + } + + goto cleanup; + } + } + +#if (QS_DEBUG & 8) + flint_printf("\n"); +#endif + +cleanup: + fmpz_clear(X); + fmpz_clear(Y); + fmpz_clear(res); + fmpz_clear(p); + + return relations; +} + +slong qsieve_ll_evaluate_sieve(qs_t qs_inf, char * sieve) +{ + slong i = 0, j = 0; + ulong * sieve2 = (ulong *) sieve; + char bits = qs_inf->sieve_bits; + slong rels = 0; + +#if (QS_DEBUG & 16) + slong stats_limit; + for (i = 0; i < 256; i++) + qs_inf->sieve_tally[i] = 0; +#endif + +#if (QS_DEBUG & 4) + flint_printf("%wdX^2+2*%wdX+", qs_inf->A, qs_inf->B); + fmpz_print(qs_inf->C); flint_printf("\n"); +#endif + + while (j < qs_inf->sieve_size/sizeof(ulong)) + { +#if FLINT64 + while ((sieve2[j] & UWORD(0xE0E0E0E0E0E0E0E0)) == 0) +#else + while ((sieve2[j] & UWORD(0xE0E0E0E0)) == 0) +#endif + { +#if (QS_DEBUG & 16) + for (i = j*sizeof(ulong); i < (j+1)*sizeof(ulong) && i < qs_inf->sieve_size; i++) + qs_inf->sieve_tally[(int)sieve[i]]++; +#endif + j++; + } + + i = j*sizeof(ulong); + + while (i < (j+1)*sizeof(ulong) && i < qs_inf->sieve_size) + { +#if (QS_DEBUG & 16) + qs_inf->sieve_tally[(int)sieve[i]]++; +#endif + if (sieve[i] > bits) + rels += qsieve_ll_evaluate_candidate(qs_inf, i, sieve); + + i++; + } + j++; + } + +#if (QS_DEBUG & 16) + for (stats_limit = 255; stats_limit >= 0; stats_limit--) + if (qs_inf->sieve_tally[stats_limit] != 0) + break; + + for (i = 0; i <= stats_limit; i++) + { + if ((i % 16) == 0) + flint_printf("|%wd:", i); + flint_printf(" %wd", qs_inf->sieve_tally[i]); + } + flint_printf("|\n"); + flint_printf("Total of %wd relations for this sieve interval\n", rels); +#endif + + return rels; +} + +void qsieve_ll_update_offsets(int poly_add, mp_limb_t * poly_corr, qs_t qs_inf) +{ + slong num_primes = qs_inf->num_primes; + mp_limb_t * soln1 = qs_inf->soln1; + mp_limb_t * soln2 = qs_inf->soln2; + prime_t * factor_base = qs_inf->factor_base; + mp_limb_t p, correction; + slong pind; + + for (pind = 2; pind < num_primes; pind++) + { + p = factor_base[pind].p; + correction = (poly_add ? p - poly_corr[pind] : poly_corr[pind]); + soln1[pind] += correction; + if (soln1[pind] >= p) soln1[pind] -= p; + if (soln2[pind] == -1) continue; + soln2[pind] += correction; + if (soln2[pind] >= p) soln2[pind] -= p; + } +} + +slong qsieve_ll_collect_relations(qs_t qs_inf, char * sieve) +{ + slong s = qs_inf->s; + mp_limb_t ** A_inv2B = qs_inf->A_inv2B; + + mp_limb_t * poly_corr; + slong relations = 0; + slong poly_index, j; + int poly_add; + + qsieve_ll_compute_poly_data(qs_inf); + + for (poly_index = 1; poly_index < (1<<(s - 1)); poly_index++) + { + for (j = 0; j < s; j++) + if (((poly_index >> j) & UWORD(1)) != UWORD(0)) break; + + poly_add = ((poly_index >> j) & 2); + + poly_corr = A_inv2B[j]; + + qsieve_ll_do_sieving(qs_inf, sieve); + + relations += qsieve_ll_evaluate_sieve(qs_inf, sieve); + + qsieve_ll_update_offsets(poly_add, poly_corr, qs_inf); + + if (poly_add) qs_inf->B += (2*qs_inf->B_terms[j]); + else qs_inf->B -= (2*qs_inf->B_terms[j]); + + qsieve_ll_compute_C(qs_inf); + + qsieve_ll_compute_A_factor_offsets(qs_inf); + + if (qs_inf->columns >= qs_inf->num_primes + qs_inf->extra_rels) + break; + } + + if (qs_inf->columns < qs_inf->num_primes + qs_inf->extra_rels) + { + qsieve_ll_do_sieving(qs_inf, sieve); + + relations += qsieve_ll_evaluate_sieve(qs_inf, sieve); + + relations += qsieve_ll_merge_relations(qs_inf); + } + + return relations; +} diff --git a/external/flint-2.4.3/qsieve/ll_compute_poly_data.c b/external/flint-2.4.3/qsieve/ll_compute_poly_data.c new file mode 100644 index 0000000..9cb062d --- /dev/null +++ b/external/flint-2.4.3/qsieve/ll_compute_poly_data.c @@ -0,0 +1,452 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2006, 2011 William Hart + +******************************************************************************/ + +#define ulong ulongxx /* interferes with system includes */ +#include +#include +#undef ulong +#define ulong mp_limb_t + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "qsieve.h" +#include "fmpz.h" + +void balance4(qs_t qs_inf, mp_limb_t * A_ind, + prime_t * factor_base, slong min, slong fact, slong span, mp_limb_t target) +{ + slong i, j; + + mp_limb_t prod = factor_base[A_ind[0]].p * factor_base[A_ind[1]].p; + i = fact; + j = i + 1; + while (j < min + span) + { + while (j < min + span) + { + if (prod*factor_base[i].p*factor_base[j].p >= target/P_GOODNESS) + break; + j++; + } + i++; + j = i + 1; + } + A_ind[2] = i; + A_ind[3] = j; +} + +void balance5(qs_t qs_inf, mp_limb_t * A_ind, + prime_t * factor_base, slong min, slong high, slong span, mp_limb_t target) +{ + slong i, j; + + mp_limb_t prod = factor_base[A_ind[0]].p * factor_base[A_ind[1]].p + * factor_base[A_ind[2]].p; + i = A_ind[2] + 1; + j = i + 1; + while (j < min + span) + { + while (j < min + span) + { + if (prod*factor_base[i].p*factor_base[j].p >= target/P_GOODNESS) + break; + j++; + } + i++; + j = i + 1; + } + A_ind[3] = i; + A_ind[4] = j; +} + +void try_compute_A(qs_t qs_inf) +{ + slong min = qs_inf->min; + slong span = qs_inf->span; + slong fact = qs_inf->fact; + slong mid = qs_inf->mid; + slong high = qs_inf->high; + slong s = qs_inf->s; + mp_limb_t * A_ind = qs_inf->A_ind; + mp_limb_t target = qs_inf->target_A; + prime_t * factor_base = qs_inf->factor_base; + slong i, j; + mp_limb_t prod; + + if (qs_inf->A == 0) /* this is our first poly */ + { + A_ind[0] = min; + + /* try to pick prime factors of A whose product is not much smaller than target_A */ + switch (s) /* we can only have up to 5 factors in A for small factorisations */ + { + case 1: + break; + case 2: + prod = factor_base[A_ind[0]].p; + i = A_ind[0] + 1; + while (prod*factor_base[i].p < target/P_GOODNESS2 && i + 1 < min + span) i++; + A_ind[1] = i; + break; + case 3: + A_ind[1] = mid; + prod = factor_base[A_ind[0]].p * factor_base[A_ind[1]].p; + i = A_ind[1] + 1; + while (prod*factor_base[i].p < target/P_GOODNESS && i + 1 < min + span) i++; + A_ind[2] = i; + break; + case 4: + A_ind[1] = A_ind[0] + 1; + balance4(qs_inf, A_ind, factor_base, min, fact, span, target); + break; + case 5: + A_ind[1] = A_ind[0] + 1; + A_ind[2] = mid; + balance5(qs_inf, A_ind, factor_base, min, high, span, target); + break; + } + } else /* update to the next poly */ + { + switch (s) + { + case 1: + if (A_ind[0] + 1 < min + span) + A_ind[0]++; + else + goto out_of_polys; + break; + case 2: + i = A_ind[0]; + j = A_ind[1] + 1; + if (j < min + span && factor_base[i].p * factor_base[j].p < P_GOODNESS2*target) + A_ind[1] = j; /* we can just increment second index */ + else /* must increment first index */ + { + i++; + if (i < fact) /* find first appropriate second index */ + { + A_ind[0] = i; + prod = factor_base[A_ind[0]].p; + i = A_ind[0] + 1; + while (prod*factor_base[i].p < target/P_GOODNESS && i + 1 < min + span) i++; + A_ind[1] = i; + } else + goto out_of_polys; + } + break; + case 3: + prod = factor_base[A_ind[0]].p * factor_base[A_ind[1]].p; + j = A_ind[2] + 1; + if (j < min + span && prod * factor_base[j].p < P_GOODNESS*target) + A_ind[2] = j; /* increment third index */ + else + { + A_ind[1]++; /* increment second index */ + i = A_ind[1] + 1; + prod = factor_base[A_ind[0]].p * factor_base[A_ind[1]].p; + if (i < min + span && prod * factor_base[i].p < P_GOODNESS*target) + { + while (prod*factor_base[i].p < target/P_GOODNESS && i + 1 < min + span) i++; + A_ind[2] = i; + } else /* must increment first index */ + { + A_ind[0]++; + if (A_ind[0] < mid) + { + A_ind[1] = mid; + prod = factor_base[A_ind[0]].p * factor_base[A_ind[1]].p; + i = A_ind[1] + 1; + while (prod*factor_base[i].p < target/P_GOODNESS && i + 1 < min + span) i++; + A_ind[2] = i; + } else + goto out_of_polys; + } + } + break; + case 4: + prod = factor_base[A_ind[0]].p * factor_base[A_ind[1]].p * factor_base[A_ind[2]].p; + j = A_ind[3] + 1; + if (j < min + span && prod * factor_base[j].p < P_GOODNESS*target) + A_ind[3] = j; /* increment fourth index */ + else + { + A_ind[2]++; /* increment third index */ + i = A_ind[2] + 1; + prod = factor_base[A_ind[0]].p * factor_base[A_ind[1]].p * factor_base[A_ind[2]].p; + if (i < min + span && prod * factor_base[i].p < P_GOODNESS*target) + { + while (prod*factor_base[i].p < target/P_GOODNESS && i + 1 < min + span) i++; + A_ind[3] = i; + } else + { + A_ind[1]++; /* increment second index */ + if (A_ind[1] < fact) + { + balance4(qs_inf, A_ind, factor_base, min, fact, span, target); + } else + { + A_ind[0]++; /* increment first factor */ + A_ind[1] = A_ind[0] + 1; + if (A_ind[1] < fact) + { + balance4(qs_inf, A_ind, factor_base, min, fact, span, target); + } else + goto out_of_polys; + } + } + } + break; + case 5: + prod = factor_base[A_ind[0]].p * factor_base[A_ind[1]].p * factor_base[A_ind[2]].p * factor_base[A_ind[3]].p; + j = A_ind[4] + 1; + if (j < min + span && prod * factor_base[j].p < P_GOODNESS*target) + A_ind[4] = j; /* increment fifth index */ + else + { + A_ind[3]++; /* increment fourth index */ + i = A_ind[3] + 1; + prod = factor_base[A_ind[0]].p * factor_base[A_ind[1]].p * factor_base[A_ind[2]].p * factor_base[A_ind[3]].p; + if (i < min + span && prod * factor_base[i].p < P_GOODNESS*target) + { + while (prod*factor_base[i].p < target/P_GOODNESS && i + 1 < min + span) i++; + A_ind[4] = i; + } else + { + A_ind[2]++; /* increment third index */ + if (A_ind[2] < high) + { + balance5(qs_inf, A_ind, factor_base, min, high, span, target); + } else + { + A_ind[1]++; /* increment second index */ + if (A_ind[1] < high) + { + A_ind[2] = mid; + balance5(qs_inf, A_ind, factor_base, min, high, span, target); + } else + { + A_ind[0]++; /* increment first factor */ + A_ind[1] = A_ind[0] + 1; + if (A_ind[1] < mid) + { + A_ind[2] = mid; + balance5(qs_inf, A_ind, factor_base, min, high, span, target); + } else + goto out_of_polys; + } + } + } + } + break; + } + } + + qs_inf->A = 1; + for (i = 0; i < s; i++) + qs_inf->A *= factor_base[A_ind[i]].p; + + return; + +out_of_polys: + flint_printf("Out of polynomials, s = %wd\n", qs_inf->s); + abort(); +} + +void qsieve_ll_compute_A(qs_t qs_inf) +{ + slong i; + + do + { + try_compute_A(qs_inf); + } while (((qs_inf->A > P_GOODNESS * qs_inf->target_A + || qs_inf->A < qs_inf->target_A / P_GOODNESS) && qs_inf->s > 2) + || (((qs_inf->A > P_GOODNESS2 * qs_inf->target_A + || qs_inf->A < qs_inf->target_A / P_GOODNESS2) && qs_inf->s == 2))); + +#if QS_DEBUG > 1 + flint_printf("A = %wd, target A = %wd\n", qs_inf->A, qs_inf->target_A); +#endif + + for (i = 0; i < qs_inf->s; i++) + { + mp_limb_t p = qs_inf->factor_base[qs_inf->A_ind[i]].p; + qs_inf->inv_p2[i] = n_preinvert_limb(p*p); + } +} + +void qsieve_ll_compute_B_terms(qs_t qs_inf) +{ + slong s = qs_inf->s; + mp_limb_t * A_ind = qs_inf->A_ind; + mp_limb_t * A_modp = qs_inf->A_modp; + mp_limb_t * B_terms = qs_inf->B_terms; + prime_t * factor_base = qs_inf->factor_base; + mp_limb_t A = qs_inf->A; + mp_limb_t B; + mp_limb_t p, temp, temp2, pinv; + slong i; + + for (i = 0; i < s; i++) + { + p = factor_base[A_ind[i]].p; + pinv = factor_base[A_ind[i]].pinv; + temp = A/p; /* TODO: possibly use precomputed inverse here */ + A_modp[i] = (temp2 = n_mod2_preinv(temp, p, pinv)); + temp2 = n_invmod(temp2, p); + temp2 = n_mulmod2_preinv(temp2, qs_inf->sqrts[A_ind[i]], p, pinv); + if (temp2 > p/2) temp2 = p - temp2; + B_terms[i] = temp*temp2; + } + + B = B_terms[0]; + for (i = 1; i < s; i++) + { + B += B_terms[i]; + } + qs_inf->B = B; +} + +void qsieve_ll_compute_off_adj(qs_t qs_inf) +{ + slong num_primes = qs_inf->num_primes; + mp_limb_t A = qs_inf->A; + mp_limb_t B = qs_inf->B; + mp_limb_t * A_inv = qs_inf->A_inv; + mp_limb_t ** A_inv2B = qs_inf->A_inv2B; + mp_limb_t * B_terms = qs_inf->B_terms; + mp_limb_t * soln1 = qs_inf->soln1; + mp_limb_t * soln2 = qs_inf->soln2; + int * sqrts = qs_inf->sqrts; + prime_t * factor_base = qs_inf->factor_base; + slong s = qs_inf->s; + mp_limb_t p, temp, pinv; + slong i, j; + + for (i = 2; i < num_primes; i++) /* skip k and 2 */ + { + p = factor_base[i].p; + pinv = factor_base[i].pinv; + + A_inv[i] = n_invmod(n_mod2_preinv(A, p, pinv), p); + + for (j = 0; j < s; j++) + { + temp = n_mod2_preinv(B_terms[j], p, pinv); + temp = n_mulmod2_preinv(temp, A_inv[i], p, pinv); + temp *= 2; + if (temp >= p) temp -= p; + A_inv2B[j][i] = temp; + } + + temp = n_mod2_preinv(B, p, pinv); + temp = sqrts[i] + p - temp; + temp *= A_inv[i]; + temp += qs_inf->sieve_size/2; + soln1[i] = n_mod2_preinv(temp, p, pinv); + temp = p - sqrts[i]; + if (temp == p) temp -= p; + temp = n_mulmod2_preinv(temp, A_inv[i], p, pinv); + temp *= 2; + if (temp >= p) temp -= p; + soln2[i] = temp + soln1[i]; + if (soln2[i] >= p) soln2[i] -= p; + } +} + +void qsieve_ll_compute_A_factor_offsets(qs_t qs_inf) +{ + slong s = qs_inf->s; + mp_limb_t * A_ind = qs_inf->A_ind; + mp_limb_t * A_modp = qs_inf->A_modp; + mp_limb_t * soln1 = qs_inf->soln1; + mp_limb_t * soln2 = qs_inf->soln2; + mp_limb_t p, D; + mp_limb_t hi = qs_inf->hi; + mp_limb_t lo = qs_inf->lo; + mp_limb_t B = qs_inf->B; + mp_limb_t temp, temp2, B_modp2, index, p2; + prime_t * factor_base = qs_inf->factor_base; + mp_limb_t * inv_p2 = qs_inf->inv_p2; + mp_limb_t pinv; + slong j; + + for (j = 0; j < s; j++) + { + index = A_ind[j]; + p = factor_base[index].p; + p2 = p*p; + pinv = factor_base[index].pinv; + D = n_ll_mod_preinv(hi, lo, p*p, inv_p2[j]); + if ((mp_limb_signed_t) B < 0) + { + B_modp2 = n_mod2_preinv(-B, p2, inv_p2[j]); + B_modp2 = p2 - B_modp2; + if (B_modp2 == p2) B_modp2 = 0; + } else + B_modp2 = n_mod2_preinv(B, p2, inv_p2[j]); + temp = B_modp2*A_modp[j]; + temp = n_mod2_preinv(temp, p, pinv); + temp2 = n_invmod(temp, p); + D -= (B_modp2*B_modp2); + if ((mp_limb_signed_t) D < 0) + temp = -(-D/p); /* TODO consider using precomputed inverse */ + else + temp = (D/p); /* TODO consider using precomputed inverse */ + temp *= temp2; + temp += qs_inf->sieve_size/2; + if ((mp_limb_signed_t) temp < 0) + { + temp = p - n_mod2_preinv(-temp, p, pinv); + if (temp == p) temp = 0; + } + else temp = n_mod2_preinv(temp, p, pinv); + soln1[index] = temp; + soln2[index] = -1; + } +} + +void qsieve_ll_compute_C(qs_t qs_inf) +{ + mp_limb_t A = qs_inf->A; + mp_limb_t B = qs_inf->B; + + if ((mp_limb_signed_t) B < WORD(0)) B = -B; + fmpz_set_ui(qs_inf->C, B); + fmpz_mul_ui(qs_inf->C, qs_inf->C, B); + fmpz_sub(qs_inf->C, qs_inf->C, qs_inf->kn); + fmpz_divexact_ui(qs_inf->C, qs_inf->C, A); +} + +void qsieve_ll_compute_poly_data(qs_t qs_inf) +{ + qsieve_ll_compute_A(qs_inf); + qsieve_ll_compute_B_terms(qs_inf); + qsieve_ll_compute_off_adj(qs_inf); + qsieve_ll_compute_A_factor_offsets(qs_inf); + qsieve_ll_compute_C(qs_inf); +} + diff --git a/external/flint-2.4.3/qsieve/ll_factor.c b/external/flint-2.4.3/qsieve/ll_factor.c new file mode 100644 index 0000000..248f70a --- /dev/null +++ b/external/flint-2.4.3/qsieve/ll_factor.c @@ -0,0 +1,285 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2006, 2011 William Hart + +******************************************************************************/ + +#define ulong ulongxx /* interferes with system includes */ +#include +#undef ulong +#define ulong mp_limb_t + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "qsieve.h" +#include "fmpz.h" + +/* + Factor n = (hi, lo). Returns a factor of n. + Assumes n is not prime and not a perfect power. + Returns 0 if n is too large to be factored by this function. +*/ +mp_limb_t qsieve_ll_factor(mp_limb_t hi, mp_limb_t lo) +{ + qs_t qs_inf; + mp_limb_t factor = 0, t; + slong rels_found = 0; + char * sieve; + slong ncols, nrows, i, count; + uint64_t * nullrows; + uint64_t mask; + flint_rand_t state; + fmpz_t X, Y; + + /************************************************************************ + INITIALISATION: + + Initialise the qs_t structure. + ************************************************************************/ +#if QS_DEBUG + flint_printf("\nStart:\n"); +#endif + + qsieve_ll_init(qs_inf, hi, lo); + +#if QS_DEBUG /* print some diagnostic information */ + { + mpz_t _n; + mpz_init(_n); + flint_mpz_set_ui(_n, hi); + mpz_mul_2exp(_n, _n, FLINT_BITS); + flint_mpz_add_ui(_n, _n, lo); + gmp_printf("Factoring %Zd of %wd bits\n", _n, qs_inf->bits); + mpz_clear(_n); + } +#endif + + /************************************************************************ + KNUTH SCHROEPPEL: + + Try to compute a multiplier k such that there are a lot of small primes + which are quadratic residues modulo kn. If a small factor of n is found + during this process it is returned. + ************************************************************************/ +#if QS_DEBUG + flint_printf("\nKnuth-Schroeppel:\n"); +#endif + + factor = qsieve_ll_knuth_schroeppel(qs_inf); + if (factor) + { +#if QS_DEBUG + flint_printf("Found small factor %wd in Knuth-Schroeppel\n", factor); +#endif + qsieve_ll_clear(qs_inf); + return factor; + } + + /* compute kn */ + fmpz_set_ui(qs_inf->kn, hi); + fmpz_mul_2exp(qs_inf->kn, qs_inf->kn, FLINT_BITS); + fmpz_add_ui(qs_inf->kn, qs_inf->kn, lo); + fmpz_mul_ui(qs_inf->kn, qs_inf->kn, qs_inf->k); + + /* refine qs_inf->bits */ + qs_inf->bits = fmpz_bits(qs_inf->kn); + if (qs_inf->bits > 2*FLINT_BITS) + { + qsieve_ll_clear(qs_inf); + return 0; /* kn is too large to factor */ + } + + /************************************************************************ + COMPUTE FACTOR BASE: + + Try to compute a multiplier k such that there are a lot of small primes + which are quadratic residues modulo kn. If a small factor of n is found + during this process it is returned. + ************************************************************************/ +#if QS_DEBUG + flint_printf("\nCompute factor base:\n"); +#endif + + /* compute factor base primes and associated data*/ + factor = qsieve_ll_primes_init(qs_inf); + if (factor) + { +#if QS_DEBUG + flint_printf("Found small factor %wd whilst generating factor base\n", factor); +#endif + qsieve_ll_clear(qs_inf); + return factor; + } + + /************************************************************************ + INITIALISE POLYNOMIAL DATA: + + Create space for all the polynomial information + ************************************************************************/ +#if QS_DEBUG + flint_printf("\nInitialise poly:\n"); +#endif + + /* set (hi, lo) to kn */ + umul_ppmm(t, lo, lo, qs_inf->k); + hi = hi*qs_inf->k + t; + qs_inf->hi = hi; + qs_inf->lo = lo; + + qsieve_ll_poly_init(qs_inf); + + /************************************************************************ + INITIALISE RELATION/LINAXYXYXYXY DATA: + + Create space for all the relations and matrix information + ************************************************************************/ +#if QS_DEBUG + flint_printf("\nInitialise relations and linear algebra:\n"); +#endif + + qsieve_ll_linalg_init(qs_inf); + + /************************************************************************ + SIEVE: + + Sieve for relations + ************************************************************************/ +#if QS_DEBUG + flint_printf("\nSieve:\n"); +#endif + + sieve = flint_malloc(qs_inf->sieve_size + sizeof(ulong)); + + while (rels_found < qs_inf->num_primes + qs_inf->extra_rels) + { + rels_found += qsieve_ll_collect_relations(qs_inf, sieve); + +#if (QS_DEBUG & 128) + flint_printf("%wd/%wd relations.\n", rels_found, qs_inf->num_primes + qs_inf->extra_rels); +#endif + } + + flint_free(sieve); + + /************************************************************************ + REDUCE MATRIX: + + Perform some light filtering on the matrix + ************************************************************************/ + + ncols = qs_inf->num_primes + qs_inf->extra_rels; + nrows = qs_inf->num_primes; + +#if QS_DEBUG + flint_printf("Reduce matrix:\n"); +#endif + + reduce_matrix(qs_inf, &nrows, &ncols, qs_inf->matrix); + + /************************************************************************ + BLOCK LANCZOS: + + Find extra_rels nullspace vectors (if they exist) + ************************************************************************/ + +#if QS_DEBUG + flint_printf("Block lanczos:\n"); +#endif + + flint_randinit(state); /* initialise the random generator */ + + do /* repeat block lanczos until it succeeds */ + { + nullrows = block_lanczos(state, nrows, 0, ncols, qs_inf->matrix); + } while (nullrows == NULL); + + for (i = 0, mask = 0; i < ncols; i++) /* create mask of nullspace vectors */ + mask |= nullrows[i]; + + for (i = count = 0; i < 64; i++) /* count nullspace vectors found */ + { + if (mask & ((uint64_t)(1) << i)) + count++; + } + + flint_randclear(state); /* clean up random state */ + +#if QS_DEBUG + flint_printf("%wd nullspace vectors found\n", count); +#endif + + /************************************************************************ + SQUARE ROOT: + + Compute the square root and take the GCD of X-Y with N + ************************************************************************/ + +#if QS_DEBUG + flint_printf("Square root:\n"); +#endif + + fmpz_fdiv_q_ui(qs_inf->kn, qs_inf->kn, qs_inf->k); /* divide kn by multiplier */ + + fmpz_init(X); + fmpz_init(Y); + + for (count = 0; count < 64; count++) + { + if (mask & ((uint64_t)(1) << count)) + { + qsieve_ll_square_root(X, Y, qs_inf, nullrows, ncols, count, qs_inf->kn); + fmpz_sub(X, X, Y); + fmpz_gcd(X, X, qs_inf->kn); + + if (fmpz_cmp(X, qs_inf->kn) != 0 && fmpz_cmp_ui(X, 1) != 0) /* have a factor */ + { + if (fmpz_size(X)!= 1) + fmpz_fdiv_q(X, qs_inf->kn, X); /* take smaller of two factors */ + factor = fmpz_get_ui(X); + break; + } + } + } + + fmpz_clear(X); + fmpz_clear(Y); + flint_free(nullrows); + + /************************************************************************ + CLEAN UP: + + Free all used memory + ************************************************************************/ + +#if QS_DEBUG + flint_printf("\nClean up:\n"); +#endif + + qsieve_ll_clear(qs_inf); + +#if QS_DEBUG + flint_printf("\nDone.\n"); +#endif + + return factor; +} diff --git a/external/flint-2.4.3/qsieve/ll_init.c b/external/flint-2.4.3/qsieve/ll_init.c new file mode 100644 index 0000000..720901f --- /dev/null +++ b/external/flint-2.4.3/qsieve/ll_init.c @@ -0,0 +1,77 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2006, 2011 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "qsieve.h" +#include "fmpz.h" + +void qsieve_ll_init(qs_t qs_inf, mp_limb_t hi, mp_limb_t lo) +{ + ulong i; + + /* store n in struct */ + qs_inf->hi = hi; + qs_inf->lo = lo; + + /* determine the number of bits of n */ + qs_inf->bits = (hi ? FLINT_BITS + FLINT_BIT_COUNT(hi) : FLINT_BIT_COUNT(lo)); + + /* determine which index in the tuning table n corresponds to */ + for (i = 1; i < QS_LL_TUNE_SIZE; i++) + { + if (qsieve_ll_tune[i][0] > qs_inf->bits) + break; + } + i--; + + qs_inf->ks_primes = qsieve_ll_tune[i][1]; /* number of Knuth-Schroeppel primes */ + qs_inf->num_primes = qsieve_ll_tune[i][2]; /* number of factor base primes */ + + fmpz_init(qs_inf->kn); /* initialise kn */ + fmpz_init(qs_inf->C); /* initialise C */ + + qs_inf->factor_base = NULL; + qs_inf->sqrts = NULL; + qs_inf->B_terms = NULL; + qs_inf->A_inv = NULL; + qs_inf->A_inv2B = NULL; + + qs_inf->small = NULL; + qs_inf->factor = NULL; + qs_inf->matrix = NULL; + qs_inf->Y_arr = NULL; + qs_inf->relation = NULL; + qs_inf->qsort_arr = NULL; + + qs_inf->prime_count = NULL; + + qs_inf->A = 0; + +#if (QS_DEBUG & 16) + qs_inf->sieve_tally = flint_malloc(256*sizeof(slong)); +#endif +} diff --git a/external/flint-2.4.3/qsieve/ll_insert_relations.c b/external/flint-2.4.3/qsieve/ll_insert_relations.c new file mode 100644 index 0000000..6bfbe5f --- /dev/null +++ b/external/flint-2.4.3/qsieve/ll_insert_relations.c @@ -0,0 +1,255 @@ +/*============================================================================ + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +===============================================================================*/ +/****************************************************************************** + + linear_algebra.c + + Routines for dealing with building the final F_2 matrix + + (C) 2006, 2011 William Hart + +******************************************************************************/ + +#define ulong ulongxx /* interferes with system includes */ +#include +#include +#undef ulong +#define ulong mp_limb_t + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "qsieve.h" +#include "fmpz.h" + +/*========================================================================= + + Compare relations: + + Function: Compare two relations; used by qsort + +==========================================================================*/ + +int qsieve_ll_relations_cmp(const void * a, const void * b) +{ + la_col_t * ra = *((la_col_t **) a); + la_col_t * rb = *((la_col_t **) b); + slong point; + + if (ra->weight > rb->weight) return 1; + else if (ra->weight < rb->weight) return -1; + + for (point = ra->weight - 1; point >= 0 + && (ra->data[point] == rb->data[point]); point--) + { + ; + } + + if (point == -1) return 0; + + if (ra->data[point] > rb->data[point]) return 1; + else if (ra->data[point] < rb->data[point]) return -1; + + return 0; +} + +int qsieve_ll_relations_cmp2(const void * a, const void * b) +{ + la_col_t * ra = (la_col_t *) a; + la_col_t * rb = (la_col_t *) b; + slong point; + + if (ra->weight > rb->weight) return 1; + else if (ra->weight < rb->weight) return -1; + + for (point = ra->weight - 1; point >= 0 + && (ra->data[point] == rb->data[point]); point--) + { + ; + } + + if (point == -1) return 0; + + if (ra->data[point] > rb->data[point]) return 1; + else if (ra->data[point] < rb->data[point]) return -1; + + return 0; +} + +/*========================================================================== + Merge sort: + + Function: Merge a list of sorted new relations into a list of existing + sorted relations. Sort is done using a merge sort algorithm + with a short stack. + +===========================================================================*/ + +slong qsieve_ll_merge_sort(qs_t qs_inf) +{ + la_col_t * matrix = qs_inf->matrix; + slong columns = qs_inf->columns; + la_col_t ** qsort_arr = qs_inf->qsort_arr; + slong num_unmerged = qs_inf->num_unmerged; + slong dups = 0; + int comp; + slong i; + + for (i = columns + num_unmerged - WORD(1); i >= dups; i--) + { + if (!columns) comp = -1; + else if (!num_unmerged) comp = 1; + else + comp = qsieve_ll_relations_cmp2(matrix + columns - WORD(1), qsort_arr[num_unmerged - WORD(1)]); + + switch (comp) + { + case -1: + { + copy_col(matrix + i, qsort_arr[num_unmerged - WORD(1)]); + clear_col(qsort_arr[num_unmerged - WORD(1)]); + num_unmerged--; + break; + } + case 1: + { + copy_col(matrix + i, matrix + columns - WORD(1)); + columns--; + break; + } + case 0: + { + free_col(qsort_arr[num_unmerged - WORD(1)]); + clear_col(qsort_arr[num_unmerged - WORD(1)]); + num_unmerged--; + copy_col(matrix + i, matrix + columns - WORD(1)); + columns--; + dups++; + break; + } + } + } + + columns = qs_inf->columns + qs_inf->num_unmerged - dups; + + if (dups) + { + slong i; + for (i = 0; i < columns; i++) + copy_col(matrix + i, matrix + i + dups); + + for ( ; i < columns + dups; i++) + clear_col(matrix + i); + } + + qs_inf->columns = columns; + columns = qs_inf->num_unmerged - dups; + qs_inf->num_unmerged = 0; + +#if (QS_DEBUG & 64) + flint_printf("%wd new, %wd dups\n", columns, dups); +#endif + + return columns; +} + +/*========================================================================== + Merge relations: + + Function: Merge unmerged relations into the matrix + +===========================================================================*/ + +slong qsieve_ll_merge_relations(qs_t qs_inf) +{ + const slong num_unmerged = qs_inf->num_unmerged; + la_col_t * unmerged = qs_inf->unmerged; + la_col_t ** qsort_arr = qs_inf->qsort_arr; + + if (num_unmerged) + { + slong i; + + for (i = 0; i < num_unmerged; i++) + qsort_arr[i] = unmerged + i; + + qsort(qsort_arr, num_unmerged, sizeof(la_col_t *), qsieve_ll_relations_cmp); + + return qsieve_ll_merge_sort(qs_inf); + } + + return 0; +} + +/*========================================================================== + Insert relation: + + Function: Insert the relation into the matrix and store the Y value + +===========================================================================*/ + +slong qsieve_ll_insert_relation(qs_t qs_inf, fmpz_t Y) +{ + la_col_t * unmerged = qs_inf->unmerged; + slong num_unmerged = qs_inf->num_unmerged; + slong * small = qs_inf->small; + slong num_factors = qs_inf->num_factors; + fac_t * factor = qs_inf->factor; + slong * curr_rel = qs_inf->curr_rel; + slong fac_num = 0; + slong i; + + clear_col(unmerged + num_unmerged); + + for (i = 0; i < qs_inf->small_primes; i++) + { + if (small[i] & 1) insert_col_entry(unmerged + num_unmerged, i); + if (small[i]) + { + curr_rel[2*fac_num + 1] = i; + curr_rel[2*fac_num + 2] = small[i]; + fac_num++; + } + } + + for (i = 0; i < num_factors; i++) + { + if (factor[i].exp & 1) insert_col_entry(unmerged + num_unmerged, factor[i].ind); + curr_rel[2*fac_num + 1] = factor[i].ind; + curr_rel[2*fac_num + 2] = factor[i].exp; + fac_num++; + } + + curr_rel[0] = fac_num; + + unmerged[num_unmerged].orig = qs_inf->num_relations; + + fmpz_set(qs_inf->Y_arr + qs_inf->num_relations, Y); + + qs_inf->curr_rel += qs_inf->max_factors*2; + qs_inf->num_unmerged++; + qs_inf->num_relations++; + + if (qs_inf->num_unmerged == qs_inf->qsort_rels) + return qsieve_ll_merge_relations(qs_inf); + + return 0; +} + diff --git a/external/flint-2.4.3/qsieve/ll_knuth_schroeppel.c b/external/flint-2.4.3/qsieve/ll_knuth_schroeppel.c new file mode 100644 index 0000000..bcecf97 --- /dev/null +++ b/external/flint-2.4.3/qsieve/ll_knuth_schroeppel.c @@ -0,0 +1,141 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2006, 2011 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "longlong.h" +#include "qsieve.h" + +/* Array of possible Knuth-Schroeppel multipliers */ +static const mp_limb_t multipliers[] = {1, 2, 3, 5, 6, 7, 10, 11, 13, 14, 15, + 17, 19, 21, 22, 23, 26, 29, 30, 31, + 33, 34, 35, 37, 38, 41, 42, 43, 47}; + +/* Number of possible Knuth-Schroeppel multipliers */ +#define KS_MULTIPLIERS (sizeof(multipliers)/sizeof(mp_limb_t)) + +/* + Try to compute a multiplier k such that there are a lot of small primes + which are quadratic residues modulo kn. If a small weight of n is found + during this process it is returned. +*/ +mp_limb_t qsieve_ll_knuth_schroeppel(qs_t qs_inf) +{ + float weights[KS_MULTIPLIERS]; /* array of Knuth-Schroeppel weights */ + float best_weight = -10.0f; /* best weight so far */ + + ulong i; + ulong num_primes, max; + float logpdivp; + mp_limb_t nmod8, mod8, p, nmod, pinv, mult; + int kron, jac; + + if ((qs_inf->lo & 1) == 0) /* check 2 is not a factor */ + return 2; + + /* initialise weights for each multiplier k depending on kn mod 8 */ + nmod8 = qs_inf->lo % 8; /* n modulo 8 */ + + for (i = 0; i < KS_MULTIPLIERS; i++) + { + mod8 = ((nmod8*multipliers[i]) % 8); /* kn modulo 8 */ + weights[i] = 0.34657359; /* ln2/2 */ + if (mod8 == 1) weights[i] *= 4.0; + if (mod8 == 5) weights[i] *= 2.0; + weights[i] -= (log((float) multipliers[i]) / 2.0); + } + + /* + maximum number of primes to try + may not exceed number of factor base primes (recall k and 2 are factor base primes) + */ + max = FLINT_MIN(qs_inf->ks_primes, qs_inf->num_primes - 2); + +#if QS_DEBUG + flint_printf("Checking %wd Knuth-Schroeppel primes\n", max); +#endif + + p = 3; + for (num_primes = 0; num_primes < max; num_primes++) + { + pinv = n_preinvert_limb(p); /* compute precomputed inverse */ + + logpdivp = log((float) p) / (float) p; /* log p / p */ + + nmod = n_ll_mod_preinv(qs_inf->hi, qs_inf->lo, p, pinv); + if (nmod == 0) return p; /* we found a small factor */ + + kron = 1; /* n mod p is even, not handled by n_jacobi */ + while ((nmod % 2) == 0) + { + if ((p % 8) == 3 || (p % 8) == 5) kron *= -1; + nmod /= 2; + } + + kron *= n_jacobi(nmod, p); + for (i = 0; i < KS_MULTIPLIERS; i++) + { + mult = multipliers[i]; + if (mult >= p) + mult = n_mod2_preinv(mult, p, pinv); /* k mod p */ + + if (mult == 0) weights[i] += logpdivp; /* kn == 0 mod p */ + else + { + jac = 1; + while ((mult % 2) == 0) /* k mod p is even, not handled by n_jacobi */ + { + if ((p % 8) == 3 || (p % 8) == 5) jac *= -1; + mult /= 2; + } + + if (kron*jac*n_jacobi(mult, p) == 1) /* kn is a square mod p */ + weights[i] += 2.0*logpdivp; + } + } + + p = n_nextprime(p, 0); + } + + /* search for the multiplier with the best weight and set qs_inf->k */ + for (i = 0; i < KS_MULTIPLIERS; i++) + { + if (weights[i] > best_weight) + { + best_weight = weights[i]; + qs_inf->k = multipliers[i]; + } + } + +#if QS_DEBUG + flint_printf("Using multiplier %wd\n", qs_inf->k); +#endif + + return 0; /* we didn't find any small factors */ +} + diff --git a/external/flint-2.4.3/qsieve/ll_linalg_init.c b/external/flint-2.4.3/qsieve/ll_linalg_init.c new file mode 100644 index 0000000..06d16a1 --- /dev/null +++ b/external/flint-2.4.3/qsieve/ll_linalg_init.c @@ -0,0 +1,69 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2006, 2011 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "qsieve.h" +#include "fmpz.h" + +void qsieve_ll_linalg_init(qs_t qs_inf) +{ + slong i; + + qs_inf->extra_rels = 64; /* number of opportunities to factor n */ + qs_inf->max_factors = 30; /* maximum number of factors a relation can have */ + + /* allow as many dups as relations */ + qs_inf->buffer_size = 2*(qs_inf->num_primes + qs_inf->extra_rels + qs_inf->qsort_rels); + + qs_inf->small = flint_malloc(qs_inf->small_primes*sizeof(mp_limb_t)); + qs_inf->factor = flint_malloc(qs_inf->max_factors*sizeof(fac_t)); + qs_inf->matrix = flint_malloc((qs_inf->buffer_size + qs_inf->qsort_rels)*sizeof(la_col_t)); + qs_inf->unmerged = qs_inf->matrix + qs_inf->buffer_size; + qs_inf->Y_arr = flint_malloc(qs_inf->buffer_size*sizeof(fmpz)); + qs_inf->curr_rel = qs_inf->relation + = flint_malloc(2*qs_inf->buffer_size*qs_inf->max_factors*sizeof(slong)); + qs_inf->qsort_arr = flint_malloc(qs_inf->qsort_rels*sizeof(la_col_t *)); + + for (i = 0; i < qs_inf->buffer_size; i++) + { + fmpz_init(qs_inf->Y_arr + i); + qs_inf->matrix[i].weight = 0; + qs_inf->matrix[i].data = NULL; + } + + for (i = 0; i < qs_inf->qsort_rels; i++) + { + qs_inf->unmerged[i].weight = 0; + qs_inf->unmerged[i].data = NULL; + } + + qs_inf->prime_count = flint_malloc(qs_inf->num_primes*sizeof(slong)); + + qs_inf->num_unmerged = 0; + qs_inf->columns = 0; + qs_inf->num_relations = 0; +} diff --git a/external/flint-2.4.3/qsieve/ll_poly_init.c b/external/flint-2.4.3/qsieve/ll_poly_init.c new file mode 100644 index 0000000..00eca6a --- /dev/null +++ b/external/flint-2.4.3/qsieve/ll_poly_init.c @@ -0,0 +1,58 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2006, 2011 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "qsieve.h" + +mp_limb_t qsieve_ll_poly_init(qs_t qs_inf) +{ + ulong num_primes = qs_inf->num_primes; + ulong s = qs_inf->s; /* number of prime factors in A coeff */ + + mp_limb_t ** A_inv2B; + + slong i; + + qs_inf->B_terms = flint_malloc(4*s*sizeof(mp_limb_t)); + qs_inf->A_ind = qs_inf->B_terms + s; + qs_inf->A_modp = qs_inf->A_ind + s; + qs_inf->inv_p2 = qs_inf->A_modp + s; + + qs_inf->A_inv2B = flint_malloc(s*sizeof(mp_limb_t *)); + + qs_inf->A_inv = flint_malloc(3*num_primes*sizeof(mp_limb_t)); + qs_inf->soln1 = qs_inf->A_inv + num_primes; + qs_inf->soln2 = qs_inf->soln1 + num_primes; + + A_inv2B = qs_inf->A_inv2B; + + A_inv2B[0] = flint_malloc(num_primes*s*sizeof(mp_limb_t)); + for (i = 1; i < s; i++) + A_inv2B[i] = A_inv2B[i - 1] + num_primes; + + return 0; +} diff --git a/external/flint-2.4.3/qsieve/ll_primes_init.c b/external/flint-2.4.3/qsieve/ll_primes_init.c new file mode 100644 index 0000000..b089346 --- /dev/null +++ b/external/flint-2.4.3/qsieve/ll_primes_init.c @@ -0,0 +1,197 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2006, 2011 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "qsieve.h" + +prime_t * compute_factor_base(mp_limb_t * small_factor, qs_t qs_inf, slong num_primes) +{ + mp_limb_t p, nmod, nmod2; + mp_limb_t pinv; + mp_limb_t k = qs_inf->k; + slong num = qs_inf->num_primes; + slong fb_prime = 2; + prime_t * factor_base; + int * sqrts; + int kron; + + /* (re)allocate space for factor base */ + if (num == 0) + factor_base = (prime_t *) flint_malloc(num_primes*sizeof(prime_t)); + else + factor_base = (prime_t *) flint_realloc(qs_inf->factor_base, + num_primes*sizeof(prime_t)); + qs_inf->factor_base = factor_base; + + /* allocate space for square roots kn mod factor base primes */ + if (num == 0) + sqrts = flint_malloc(sizeof(int)*num_primes); + else + sqrts = flint_realloc(qs_inf->sqrts, sizeof(int)*num_primes); + qs_inf->sqrts = sqrts; + + qs_inf->num_primes = num_primes; + + /* compute the two limbs of kn */ + if (num == 0) + { + p = 2; + num = 2; + } else + p = factor_base[num - 1].p; + + for (fb_prime = num; fb_prime < num_primes; ) /* leave space for k and 2 */ + { + p = n_nextprime(p, 0); + pinv = n_preinvert_limb(p); + nmod = n_ll_mod_preinv(qs_inf->hi, qs_inf->lo, p, pinv); /* n mod p */ + if (nmod == 0) + { + *small_factor = p; + return factor_base; + } + + nmod2 = n_mulmod2_preinv(nmod, k, p, pinv); /* kn mod p */ + if (nmod2 == 0) /* don't sieve with factors of multiplier */ + continue; + + nmod = nmod2; /* save nmod2 */ + + kron = 1; /* n mod p is even, not handled by n_jacobi */ + while ((nmod2 % 2) == 0) + { + if ((p % 8) == 3 || (p % 8) == 5) kron *= -1; + nmod2 /= 2; + } + + kron *= n_jacobi(nmod2, p); + if (kron == 1) /* kn is a quadratic residue mod p (and hence a FB prime) */ + { + factor_base[fb_prime].p = p; + factor_base[fb_prime].pinv = pinv; + factor_base[fb_prime].size = FLINT_BIT_COUNT(p); + sqrts[fb_prime] = n_sqrtmod(nmod, p); + fb_prime++; + } + } + + *small_factor = 0; + return factor_base; +} + +mp_limb_t qsieve_ll_primes_init(qs_t qs_inf) +{ + slong num_primes; + slong i, s, min, fact, span; + mp_limb_t fact_approx; + fmpz_t temp; + mp_limb_t k = qs_inf->k; + mp_limb_t small_factor = 0; + + prime_t * factor_base; + + /* determine which index in the tuning table n corresponds to */ + for (i = 1; i < QS_LL_TUNE_SIZE; i++) + { + if (qsieve_ll_tune[i][0] > qs_inf->bits) + break; + } + i--; + + qs_inf->sieve_bits = 32; /* number of bits to exceed in evaluate_sieve */ + qs_inf->sieve_size = qsieve_ll_tune[i][4]; /* size of sieve to use */ + qs_inf->small_primes = qsieve_ll_tune[i][3]; /* number of primes to not sieve with */ + num_primes = qsieve_ll_tune[i][2]; /* number of factor base primes */ + qs_inf->qsort_rels = qsieve_ll_tune[i][1]; /* number of relations to accumulate before sorting */ + + qs_inf->num_primes = 0; /* start with 0 primes */ + factor_base = compute_factor_base(&small_factor, qs_inf, num_primes); /* build up FB */ + if (small_factor) + return small_factor; + + /* figure out the number of factors of A and min, fact and span */ + s = qs_inf->bits/28 + 1; /* number of prime factors in A coeff */ + + fmpz_init(temp); + + fmpz_mul_2exp(temp, qs_inf->kn, 1); + fmpz_sqrt(temp, temp); + fmpz_tdiv_q_ui(temp, temp, qs_inf->sieve_size); + qs_inf->target_A = 2*fmpz_get_ui(temp); + + fmpz_root(temp, temp, s); + fact_approx = fmpz_get_ui(temp); + + fmpz_clear(temp); + + fact = 2; + while (fact_approx >= factor_base[fact].p) + fact++; + + while (1) + { + span = num_primes/s/s/2; + if (span < 6*s) span = 6*s; /* make sure we have plenty of primes to choose from */ + + min = fact - span/2; + if (min < qs_inf->small_primes) + min = qs_inf->small_primes; + + fact = min + span/2; + if (min + span <= num_primes - 2) /* we have enough primes */ + break; + + num_primes = (slong) (1.1 * (double) num_primes); + factor_base = compute_factor_base(&small_factor, qs_inf, num_primes); /* increase size of FB */ + if (small_factor) + return small_factor; + } + + qs_inf->s = s; + qs_inf->min = min; + qs_inf->fact = fact; + qs_inf->span = span; + + /* these are used for the range of the middle factor of A when s is odd */ + qs_inf->mid = qs_inf->min + ((s - 1) * qs_inf->span)/(2 * s); + qs_inf->high = qs_inf->mid + qs_inf->span / s; + +#if (QS_DEBUG & 2) + flint_printf("Using %wd factor base primes\n", qs_inf->num_primes); + flint_printf("min = FB[%wd], span = %wd, number of A factors = %wd, target A = %wd\n", + min, span, s, qs_inf->target_A); +#endif + + /* consider k and 2 as factor base primes */ + factor_base[0].p = k; + factor_base[0].pinv = n_preinvert_limb(k); + factor_base[0].size = FLINT_BIT_COUNT(k); + factor_base[1].p = 2; + factor_base[0].size = 2; + + return 0; +} diff --git a/external/flint-2.4.3/qsieve/ll_square_root.c b/external/flint-2.4.3/qsieve/ll_square_root.c new file mode 100644 index 0000000..ceb366b --- /dev/null +++ b/external/flint-2.4.3/qsieve/ll_square_root.c @@ -0,0 +1,93 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2006, 2011 William Hart + +******************************************************************************/ + +#define ulong ulongxx /* interferes with system includes */ +#include +#include +#include +#undef ulong +#define ulong mp_limb_t + +#include +#include "flint.h" +#include "ulong_extras.h" +#include "qsieve.h" +#include "fmpz.h" + +void qsieve_ll_square_root(fmpz_t X, fmpz_t Y, qs_t qs_inf, + uint64_t * nullrows, slong ncols, slong l, fmpz_t N) +{ + slong position, i, j; + slong * relation = qs_inf->relation; + prime_t * factor_base = qs_inf->factor_base; + slong * prime_count = qs_inf->prime_count; + slong num_primes = qs_inf->num_primes; + fmpz * Y_arr = qs_inf->Y_arr; + fmpz_t pow; + + fmpz_init(pow); + + memset(prime_count, 0, num_primes*sizeof(slong)); + + fmpz_one(X); + fmpz_one(Y); + + for (i = 0; i < ncols; i++) + { + if (get_null_entry(nullrows, i, l)) + { + position = qs_inf->matrix[i].orig*2*qs_inf->max_factors; + + for (j = 0; j < relation[position]; j++) + { + prime_count[relation[position+2*j+1]] += + (relation[position+2*j+2]); + } + + fmpz_mul(Y, Y, Y_arr + qs_inf->matrix[i].orig); + if (i % 10 == 0) fmpz_mod(Y, Y, N); + } + } + + for (i = 0; i < num_primes; i++) + { + if (prime_count[i]) + { + fmpz_set_ui(pow, factor_base[i].p); + fmpz_powm_ui(pow, pow, prime_count[i]/2, N); + fmpz_mul(X, X, pow); + } + + if (i%10 == 0 || i == num_primes - 1) fmpz_mod(X, X, N); + } + +#if QS_DEBUG + for (i = 0; i < num_primes; i++) + if ((prime_count[i] %2) != 0) flint_printf("Error %wd, %wd, %wd\n", l, i, prime_count[i]); +#endif + + fmpz_clear(pow); +} + diff --git a/external/flint-2.4.3/qsieve/test/t-ll_factor.c b/external/flint-2.4.3/qsieve/test/t-ll_factor.c new file mode 100644 index 0000000..826a820 --- /dev/null +++ b/external/flint-2.4.3/qsieve/test/t-ll_factor.c @@ -0,0 +1,89 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009, 2011 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "fmpz.h" +#include "qsieve.h" + +int main(void) +{ + int i, result; + fmpz_t n, t; + mp_limb_t fac1, fac2, fac; + + FLINT_TEST_INIT(state); + + flint_printf("ll_factor...."); + fflush(stdout); + + fmpz_init(n); + fmpz_init(t); + + for (i = 0; i < 1000; i++) /* Test random n */ + { + mp_limb_t hi = 0, lo; + + fac1 = n_randprime(state, n_randint(state, FLINT_BITS - 2) + 2, 0); + do { + fac2 = n_randprime(state, n_randint(state, FLINT_BITS - 2) + 2, 0); + } while (fac1 == fac2); + + fmpz_set_ui(n, fac1); + fmpz_mul_ui(n, n, fac2); + + fmpz_set_ui(t, 1); + fmpz_mul_2exp(t, t, FLINT_BITS); + + fmpz_mod(t, n, t); + lo = fmpz_get_ui(t); + + fmpz_fdiv_q_2exp(t, n, FLINT_BITS); + hi = fmpz_get_ui(t); + + fac = qsieve_ll_factor(hi, lo); + + /* multiplier may be up to 6 bits, hence the limitation */ + result = ((fac == 0 && fmpz_bits(n) > 2*FLINT_BITS - 6) + || fac == fac1 || fac == fac2); + if (!result) + { + flint_printf("FAIL: "); fmpz_print(n); flint_printf(" = %wd * %wd\n", fac1, fac2); + flint_printf("fac = %wd, bits = %wd\n", fac, fmpz_bits(n)); + abort(); + } + } + + fmpz_clear(t); + fmpz_clear(n); + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/qsieve/test/t-ll_knuth_schroeppel.c b/external/flint-2.4.3/qsieve/test/t-ll_knuth_schroeppel.c new file mode 100644 index 0000000..21bcb94 --- /dev/null +++ b/external/flint-2.4.3/qsieve/test/t-ll_knuth_schroeppel.c @@ -0,0 +1,66 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009, 2011 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" +#include "qsieve.h" + +int main(void) +{ + int i; + FLINT_TEST_INIT(state); + + flint_printf("ll_knuth_schroeppel...."); + fflush(stdout); + + + + for (i = 0; i < 10000; i++) /* Test random n */ + { + mp_limb_t hi = 0, lo; + qs_t qs_inf; + mp_bitcnt_t bits; + + bits = n_randint(state, 2*FLINT_BITS) + 1; + if (bits > FLINT_BITS) + { + lo = n_randlimb(state); + hi = n_randbits(state, bits - FLINT_BITS); + } else + lo = n_randbits(state, bits); + + qsieve_ll_init(qs_inf, hi, lo); + qsieve_ll_knuth_schroeppel(qs_inf); + qsieve_ll_clear(qs_inf); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/scanf.c b/external/flint-2.4.3/scanf.c new file mode 100644 index 0000000..395aff9 --- /dev/null +++ b/external/flint-2.4.3/scanf.c @@ -0,0 +1,138 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 William Hart + +******************************************************************************/ + +#include +#include +#include +#include +#include +#include "flint.h" + +int flint_scanf(const char * str, ...) +{ + va_list ap; + size_t len = strlen(str); + char * str2 = flint_malloc(len + 1); + int * w1 = NULL, * w2 = NULL; + void * w3; + double * d; + ulong * wu; + slong * w; + int args, floating; + int ret; + + /* deal with first substring */ + size_t n = strcspn(str, "%"); + strncpy(str2, str, n); + str2[n] = '\0'; + ret = 0; + if (!fread(str2, 1, n, stdin) && n > 0) + goto cleanup; + len -= n; + str += n; + + va_start(ap, str); + + while (len) /* deal with fmt spec prefixed strings */ + { + n = strcspn(str + 2, "%") + 2; /* be sure to skip a %% */ + strncpy(str2, str, n); + str2[n] = '\0'; + + switch (str[1]) + { + case 'w': + if (str[2] == 'x') + { + wu = (ulong *) va_arg(ap, ulong *); + ret += scanf(WORD_FMT "x", wu); + if (!fread(str2 + 3, 1, n - 3, stdin) && n > 3) + goto cleanup; + } else if (str[2] == 'u') + { + wu = (ulong *) va_arg(ap, ulong *); + ret += scanf(WORD_FMT "u", wu); + if (!fread(str2 + 3, 1, n - 3, stdin) && n > 3) + goto cleanup; + } else if (str[2] == 'd') + { + w = (slong *) va_arg(ap, slong *); + ret += scanf(WORD_FMT "d", w); + if (!fread(str2 + 3, 1, n - 3, stdin) && n > 3) + goto cleanup; + } else + { + w = (slong *) va_arg(ap, slong *); + ret += scanf(WORD_FMT "d", w); + if (!fread(str2 + 2, 1, n - 2, stdin) && n > 2) + goto cleanup; + } + break; + default: /* pass to printf */ + args = parse_fmt(&floating, str2); + if (args) + { + if (args == 3) + w1 = va_arg(ap, int *); + if (args >= 2) + w2 = va_arg(ap, int *); + if (floating) + { + d = va_arg(ap, double *); + if (args == 2) + ret += scanf(str2, w2, d); + else if (args == 3) + ret += scanf(str2, w1, w2, d); + else + ret += scanf(str2, d); + } else + { + w3 = va_arg(ap, void *); + if (args == 2) + ret += scanf(str2, w2, w3); + else if (args == 3) + ret += scanf(str2, w1, w2, w3); + else + ret += scanf(str2, w3); + } + } else + { + if (!fread(str2, 1, n, stdin) && n > 0) /* zero args */ + goto cleanup; + } + + } + + len -= n; + str += n; + } + + va_end(ap); + +cleanup: + flint_free(str2); + + return ret; +} diff --git a/external/flint-2.4.3/sprintf.c b/external/flint-2.4.3/sprintf.c new file mode 100644 index 0000000..7a8d154 --- /dev/null +++ b/external/flint-2.4.3/sprintf.c @@ -0,0 +1,125 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 William Hart + +******************************************************************************/ + +#include +#include +#include +#include +#include +#include "flint.h" + +size_t flint_sprintf(char * s, const char * str, ...) +{ + va_list ap; + size_t len = strlen(str); + char * str2 = flint_malloc(len + 1); + int w1 = 0, w2 = 0; + void * w3; + double d; + ulong wu; + slong w; + int args, floating; + size_t ret; + + /* deal with first substring */ + size_t n = strcspn(str, "%"); + strncpy(str2, str, n); + str2[n] = '\0'; + ret = sprintf(s, "%s", str2); + len -= n; + str += n; + + va_start(ap, str); + + while (len) /* deal with fmt spec prefixed strings */ + { + n = strcspn(str + 2, "%") + 2; /* be sure to skip a %% */ + strncpy(str2, str, n); + str2[n] = '\0'; + + switch (str[1]) + { + case 'w': + if (str[2] == 'x') + { + wu = (ulong) va_arg(ap, ulong); + ret += sprintf(s + ret, WORD_FMT "x", wu); + ret += sprintf(s + ret, "%s", str2 + 3); + } else if (str[2] == 'u') + { + wu = (ulong) va_arg(ap, ulong); + ret += sprintf(s + ret, WORD_FMT "u", wu); + ret += sprintf(s + ret, "%s", str2 + 3); + } else if (str[2] == 'd') + { + w = (slong) va_arg(ap, slong); + ret += sprintf(s + ret, WORD_FMT "d", w); + ret += sprintf(s + ret, "%s", str2 + 3); + } else + { + w = (slong) va_arg(ap, slong); + ret += sprintf(s + ret, WORD_FMT "d", w); + ret += sprintf(s + ret, "%s", str2 + 2); + } + break; + default: /* pass to sprintf */ + args = parse_fmt(&floating, str2); + if (args) + { + if (args == 3) + w1 = va_arg(ap, int); + if (args >= 2) + w2 = va_arg(ap, int); + if (floating) + { + d = va_arg(ap, double); + if (args == 2) + ret += sprintf(s + ret, str2, w2, d); + else if (args == 3) + ret += sprintf(s + ret, str2, w1, w2, d); + else + ret += sprintf(s + ret, str2, d); + } else + { + w3 = va_arg(ap, void *); + if (args == 2) + ret += sprintf(s + ret, str2, w2, w3); + else if (args == 3) + ret += sprintf(s + ret, str2, w1, w2, w3); + else + ret += sprintf(s + ret, str2, w3); + } + } else ret += sprintf(s + ret, "%s", str2); /* zero args */ + } + + len -= n; + str += n; + } + + va_end(ap); + flint_free(str2); + + return ret; +} diff --git a/external/flint-2.4.3/sscanf.c b/external/flint-2.4.3/sscanf.c new file mode 100644 index 0000000..0baad81 --- /dev/null +++ b/external/flint-2.4.3/sscanf.c @@ -0,0 +1,152 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 William Hart + +******************************************************************************/ + +#include +#include +#include +#include +#include +#include "flint.h" + +int flint_sscanf(const char * s, const char * str, ...) +{ + va_list ap; + size_t len = strlen(str); + char * str2 = flint_malloc(len + 1); + char * s2 = flint_malloc(strlen(s) + 1); + int * w1 = NULL, * w2 = NULL; + void ** w3; + double * d; + ulong * wu; + slong * w; + int args, floating; + int ret; + + /* deal with first substring */ + size_t n = strcspn(str, "%"); + strncpy(str2, s, n); + str2[n] = '\0'; + ret = 0; + len -= n; + str += n; + s += n; + + va_start(ap, str); + + while (len) /* deal with fmt spec prefixed strings */ + { + n = strcspn(str + 2, "%") + 2; /* be sure to skip a %% */ + strncpy(str2, str, n); + str2[n] = '\0'; + + switch (str[1]) + { + case 'w': + if (str[2] == 'x') + { + wu = (ulong *) va_arg(ap, ulong *); + ret += sscanf(s, WORD_FMT "x", wu); + s += sprintf(s2, WORD_FMT "x", *wu); + s += n - 3; + } else if (str[2] == 'u') + { + wu = (ulong *) va_arg(ap, ulong *); + ret += sscanf(s, WORD_FMT "u", wu); + s += sprintf(s2, WORD_FMT "u", *wu); + s += n - 3; + } else if (str[2] == 'd') + { + w = (slong *) va_arg(ap, slong *); + ret += sscanf(s, WORD_FMT "d", w); + s += sprintf(s2, WORD_FMT "d", *w); + s += n - 3; + } else + { + w = (slong *) va_arg(ap, slong *); + ret += sscanf(s, WORD_FMT "d", w); + s += sprintf(s2, WORD_FMT "d", *w); + s += n - 2; + } + break; + default: /* pass to printf */ + args = parse_fmt(&floating, str2); + if (args) + { + if (args == 3) + w1 = va_arg(ap, int *); + if (args >= 2) + w2 = va_arg(ap, int *); + if (floating) + { + d = va_arg(ap, double *); + if (args == 2) + { + ret += sscanf(s, str2, w2, d); + s += sprintf(s2, str2, *w2, *d); + } + else if (args == 3) + { + ret += sscanf(s, str2, w1, w2, d); + s += sprintf(s2, str2, *w1, *w2, *d); + } + else + { + ret += sscanf(s, str2, d); + s += sprintf(s2, str2, *d); + } + } else + { + w3 = va_arg(ap, void **); + if (args == 2) + { + ret += sscanf(s, str2, w2, w3); + s += sprintf(s2, str2, *w2, *w3); + } + else if (args == 3) + { + ret += sscanf(s, str2, w1, w2, w3); + s += sprintf(s2, str2, *w1, *w2, *w3); + } + else + { + ret += sscanf(s, str2, w3); + s += sprintf(s2, str2, *w3); + } + } + } else /* zero args */ + s += n; + } + + len -= n; + str += n; + } + + va_end(ap); + + flint_free(str2); + flint_free(s2); + + return ret; +} diff --git a/external/flint-2.4.3/templates.h b/external/flint-2.4.3/templates.h new file mode 100644 index 0000000..b37ee5e --- /dev/null +++ b/external/flint-2.4.3/templates.h @@ -0,0 +1,47 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#ifndef TEMPLATES_H_ +#define TEMPLATES_H_ + +#define CAT(X,Y) X##_##Y +#define CAT3(X,Y,Z) X##_##Y##_##Z +#define _CAT(X,Y) _##X##_##Y +#define _CAT3(X,Y,Z) _##X##_##Y##_##Z +#define __CAT(X,Y) __##X##_##Y +#define __CAT3(X,Y,Z) __##X##_##Y##_##Z + +#define TEMPLATE(X,Y) CAT(X,Y) +#define TEMPLATE3(X,Y,Z) CAT3(X,Y,Z) +#define _TEMPLATE(X,Y) _CAT(X,Y) +#define _TEMPLATE3(X,Y,Z) _CAT3(X,Y,Z) +#define __TEMPLATE(X,Y) __CAT(X,Y) +#define __TEMPLATE3(X,Y,Z) __CAT3(X,Y,Z) + +#define TEMPLATE_STR(x) #x +#define TEMPLATE_PRINT(x) flint_printf("%s", TEMPLATE_STR(x)); +#define TEMPLATE_PRINTF(s, x) flint_printf(s, TEMPLATE_STR(x)); + +#endif diff --git a/external/flint-2.4.3/test/t-add_ssaaaa.c b/external/flint-2.4.3/test/t-add_ssaaaa.c new file mode 100644 index 0000000..bc66aec --- /dev/null +++ b/external/flint-2.4.3/test/t-add_ssaaaa.c @@ -0,0 +1,71 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("add_ssaaaa...."); + fflush(stdout); + + for (i = 0; i < 1000000; i++) + { + mp_limb_t sh1, sl1, sh2, sl2, ah1, al1, ah2, al2; + + ah1 = n_randtest(state); + al1 = n_randtest(state); + ah2 = n_randtest(state); + al2 = n_randtest(state); + + add_ssaaaa(sh1, sl1, ah1, al1, ah2, al2); + + sl2 = al1 + al2; + sh2 = (sl1 < al1); + sh2 += ah1; + sh2 += ah2; + + result = ((sh2 == sh1) && (sl2 == sl1)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("ah1 = %wu, al1 = %wu, ah2 = %wu, al1 = %wu\n", ah1, al1, ah2, al1); + flint_printf("sh2 = %wu, sh1 = %wu, sl2 = %wu, sl1 = %wu\n", sh2, sh1, sl2, sl1); + abort(); + } + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/test/t-add_sssaaaaaa.c b/external/flint-2.4.3/test/t-add_sssaaaaaa.c new file mode 100644 index 0000000..164a7e7 --- /dev/null +++ b/external/flint-2.4.3/test/t-add_sssaaaaaa.c @@ -0,0 +1,74 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, j, result; + FLINT_TEST_INIT(state); + + + flint_printf("add_sssaaaaaa...."); + fflush(stdout); + + for (i = 0; i < 1000000; i++) + { + mp_limb_t s[3], t[3], a[3], b[3]; + + for (j = 0; j < 3; j++) + { + s[j] = n_randtest(state); + t[j] = n_randtest(state); + a[j] = n_randtest(state); + b[j] = n_randtest(state); + } + + add_sssaaaaaa(s[2], s[1], s[0], a[2], a[1], a[0], b[2], b[1], b[0]); + + mpn_add_n(t, a, b, 3); + + result = ((s[2] == t[2]) && (s[1] == t[1]) && (s[0] == t[0])); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a[2] = %wu, a[1] = %wu, a[0] = %wu\n", a[2], a[1], a[0]); + flint_printf("b[2] = %wu, b[1] = %wu, b[0] = %wu\n", b[2], b[1], b[0]); + flint_printf("s[2] = %wu, s[1] = %wu, s[0] = %wu\n", s[2], s[1], s[0]); + flint_printf("t[2] = %wu, t[1] = %wu, t[0] = %wu\n", t[2], t[1], t[0]); + abort(); + } + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/test/t-count_leading_zeros.c b/external/flint-2.4.3/test/t-count_leading_zeros.c new file mode 100644 index 0000000..8ac524a --- /dev/null +++ b/external/flint-2.4.3/test/t-count_leading_zeros.c @@ -0,0 +1,64 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("count_leading_zeros...."); + fflush(stdout); + + for (i = 0; i < 1000000; i++) + { + mp_limb_t n; + unsigned int count = 0; + + n = n_randtest(state); + + if (n != 0) + count_leading_zeros(count, n); + + result = ((n == UWORD(0)) || (((slong)(n << count) < WORD(0)) && (r_shift(n, FLINT_BITS-count) == UWORD(0)))); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("n = %wu, count = %u\n", n, count); + abort(); + } + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/test/t-count_trailing_zeros.c b/external/flint-2.4.3/test/t-count_trailing_zeros.c new file mode 100644 index 0000000..9d071a4 --- /dev/null +++ b/external/flint-2.4.3/test/t-count_trailing_zeros.c @@ -0,0 +1,64 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("count_trailing_zeros...."); + fflush(stdout); + + for (i = 0; i < 1000000; i++) + { + mp_limb_t n; + unsigned int count = 0; + + n = n_randtest(state); + + if (n != 0) + count_trailing_zeros(count, n); + + result = ((n == UWORD(0)) || (((n >> count) & UWORD(1)) && (l_shift(n, FLINT_BITS-count) == UWORD(0)))); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("n = %wu, count = %u\n", n, count); + abort(); + } + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/test/t-sdiv_qrnnd.c b/external/flint-2.4.3/test/t-sdiv_qrnnd.c new file mode 100644 index 0000000..3b9d7de --- /dev/null +++ b/external/flint-2.4.3/test/t-sdiv_qrnnd.c @@ -0,0 +1,74 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("sdiv_qrnnd...."); + fflush(stdout); + + for (i = 0; i < 1000000; i++) + { + mp_limb_signed_t d, nh, nl, q, r, ph, pl; + + do + { + d = n_randtest_not_zero(state); + nh = n_randtest(state); + } while ((FLINT_ABS(nh) >= FLINT_ABS(d)/2) || (nh == WORD_MIN)); + + nl = n_randtest(state); + + sdiv_qrnnd(q, r, nh, nl, d); + smul_ppmm(ph, pl, d, q); + if (r < WORD(0)) sub_ddmmss(ph, pl, ph, pl, UWORD(0), -r); + else add_ssaaaa(ph, pl, ph, pl, UWORD(0), r); + + result = ((ph == nh) && (pl == nl)); + + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("nh = %wu, nl = %wu, d = %wu\n", nh, nl, d); + flint_printf("ph = %wu, pl = %wu\n", ph, pl); + abort(); + } + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/test/t-smul_ppmm.c b/external/flint-2.4.3/test/t-smul_ppmm.c new file mode 100644 index 0000000..4b43741 --- /dev/null +++ b/external/flint-2.4.3/test/t-smul_ppmm.c @@ -0,0 +1,101 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("smul_ppmm...."); + fflush(stdout); + + for (i = 0; i < 1000000; i++) + { + mp_limb_t ph1, pl1, ph2, pl2, pl2old, n1, n2, m1, m2, bit; + int j, sign; + + n1 = n_randtest(state); + n2 = n_randtest(state); + + smul_ppmm(ph1, pl1, n1, n2); + + m1 = n1; + m2 = n2; + + sign = 1; + if ((mp_limb_signed_t) m1 < WORD(0)) + { + sign = -1; + m1 = -m1; + } + + if ((mp_limb_signed_t) m2 < WORD(0)) + { + sign = -sign; + m2 = -m2; + } + + pl2old = UWORD(0); + pl2 = UWORD(0); + ph2 = UWORD(0); + bit = UWORD(1); + for (j = 0; j < FLINT_BITS; j++) + { + if (m2 & bit) + { + pl2 += (m1 << j); + ph2 += (pl2 < pl2old); + ph2 += r_shift(m1, FLINT_BITS - j); + pl2old = pl2; + } + bit <<= 1; + } + + if (sign == -1) + sub_ddmmss(ph2, pl2, 0, 0, ph2, pl2); + + result = ((ph2 == ph1) && (pl2 == pl1)); + + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("m1 = %wu, m2 = %wu\n", n1, n2); + flint_printf("ph2 = %wu, ph1 = %wu, pl2 = %wu, pl1 = %wu\n", ph2, ph1, pl2, pl1); + abort(); + } + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/test/t-sub_ddmmss.c b/external/flint-2.4.3/test/t-sub_ddmmss.c new file mode 100644 index 0000000..59c3639 --- /dev/null +++ b/external/flint-2.4.3/test/t-sub_ddmmss.c @@ -0,0 +1,72 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("sub_ddmmss...."); + fflush(stdout); + + for (i = 0; i < 1000000; i++) + { + mp_limb_t dh1, dl1, dh2, dl2, mh, ml, sh, sl; + + mh = n_randtest(state); + ml = n_randtest(state); + sh = n_randtest(state); + sl = n_randtest(state); + + sub_ddmmss(dh1, dl1, mh, ml, sh, sl); + + dl2 = ml - sl; + dh2 = -(sl > ml); + dh2 += mh; + dh2 -= sh; + + result = ((dh2 == dh1) && (dl2 == dl1)); + + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("mh = %wu, ml = %wu, sh = %wu, sl = %wu\n", mh, ml, sh, sl); + flint_printf("dh2 = %wu, dh1 = %wu, dl2 = %wu, dl1 = %wu\n", dh2, dh1, dl2, dl1); + abort(); + } + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/test/t-udiv_qrnnd.c b/external/flint-2.4.3/test/t-udiv_qrnnd.c new file mode 100644 index 0000000..40fb7e4 --- /dev/null +++ b/external/flint-2.4.3/test/t-udiv_qrnnd.c @@ -0,0 +1,71 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("udiv_qrnnd...."); + fflush(stdout); + + for (i = 0; i < 1000000; i++) + { + mp_limb_t d, nh, nl, q, r, ph, pl; + + do + { + d = n_randtest_not_zero(state); + nh = n_randtest(state); + } while (nh >= d); + nl = n_randtest(state); + + udiv_qrnnd(q, r, nh, nl, d); + umul_ppmm(ph, pl, d, q); + add_ssaaaa(ph, pl, ph, pl, UWORD(0), r); + + result = ((ph == nh) && (pl == nl)); + + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("nh = %wu, nl = %wu, d = %wu\n", nh, nl, d); + flint_printf("ph = %wu, pl = %wu\n", ph, pl); + abort(); + } + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/test/t-udiv_qrnnd_preinv.c b/external/flint-2.4.3/test/t-udiv_qrnnd_preinv.c new file mode 100644 index 0000000..3346ec9 --- /dev/null +++ b/external/flint-2.4.3/test/t-udiv_qrnnd_preinv.c @@ -0,0 +1,73 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("udiv_qrnnd_preinv...."); + fflush(stdout); + + for (i = 0; i < 1000000; i++) + { + mp_limb_t d, dinv, nh, nl, q1, r1, q2, r2, norm; + + do + { + d = n_randtest_not_zero(state); + nh = n_randtest(state); + count_leading_zeros(norm, d); + d <<= norm; + } while (nh >= d); + nl = n_randtest(state); + + invert_limb(dinv, d); + + udiv_qrnnd_preinv(q1, r1, nh, nl, d, dinv); + udiv_qrnnd(q2, r2, nh, nl, d); + + result = ((q1 == q2) && (r1 == r2)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("nh = %wu, nl = %wu, d = %wu, dinv = %wu\n", nh, nl, d, dinv); + flint_printf("q1 = %wu, q2 = %wu, r1 = %wu, r2 = %wu\n", q1, q2, r1, r2); + abort(); + } + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/test/t-umul_ppmm.c b/external/flint-2.4.3/test/t-umul_ppmm.c new file mode 100644 index 0000000..cb3d17d --- /dev/null +++ b/external/flint-2.4.3/test/t-umul_ppmm.c @@ -0,0 +1,81 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, j, result; + FLINT_TEST_INIT(state); + + + flint_printf("umul_ppmm...."); + fflush(stdout); + + for (i = 0; i < 1000000; i++) + { + mp_limb_t ph1, pl1, ph2, pl2, pl2old, m1, m2, bit; + + m1 = n_randtest(state); + m2 = n_randtest(state); + + umul_ppmm(ph1, pl1, m1, m2); + + pl2old = UWORD(0); + pl2 = UWORD(0); + ph2 = UWORD(0); + bit = UWORD(1); + for (j = 0; j < FLINT_BITS; j++) + { + if (m2 & bit) + { + pl2 += (m1 << j); + ph2 += (pl2 < pl2old); + ph2 += r_shift(m1, FLINT_BITS - j); + pl2old = pl2; + } + bit <<= 1; + } + + result = ((ph2 == ph1) && (pl2 == pl1)); + + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("m1 = %wu, m2 = %wu\n", m1, m2); + flint_printf("ph2 = %wu, ph1 = %wu, pl2 = %wu, pl1 = %wu\n", ph2, ph1, pl2, pl1); + abort(); + } + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/test_helpers.c b/external/flint-2.4.3/test_helpers.c new file mode 100644 index 0000000..d1790ac --- /dev/null +++ b/external/flint-2.4.3/test_helpers.c @@ -0,0 +1,29 @@ +/*============================================================================ + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +===============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 Fredrik Johansson + +******************************************************************************/ + +int flint_test_multiplier() +{ + return 10; +} diff --git a/external/flint-2.4.3/thread_support.c b/external/flint-2.4.3/thread_support.c new file mode 100644 index 0000000..431066b --- /dev/null +++ b/external/flint-2.4.3/thread_support.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 "flint.h" + +FLINT_TLS_PREFIX int _flint_num_threads = 1; + +int flint_get_num_threads() +{ + return _flint_num_threads; +} + +void flint_set_num_threads(int num_threads) +{ + _flint_num_threads = num_threads; +} + diff --git a/external/flint-2.4.3/todo.txt b/external/flint-2.4.3/todo.txt new file mode 100644 index 0000000..f6af3b7 --- /dev/null +++ b/external/flint-2.4.3/todo.txt @@ -0,0 +1,357 @@ +TODO +==== + +general +------- + +* Write a flint2 memory manager, both reentrant and non-reentrant stack based + versions + +* [maybe] a type mpfr which is an alias for __mpfr_struct and using throughout + + +fmpz +---- + +* [maybe] Improve the functions fmpz_get_str and fmpz_set_str + +* [maybe] figure out how to write robust test code for fmpz_read (which reads + from stdin), perhaps using a pipe + +* Inline or create inline versions of core fmpz functions. + +* [maybe] Avoid the double allocation of both an mpz struct and limb data, + having an fmpz point directly to a combined structure. This would require + writing replacements for most mpz functions. + + +ulong_extras +------------ + +* in is_prime_pocklington allow the cofactor to be a perfect power not just + prime + +* factor out some common code between n_is_perfect_power235 and + n_factor_power235 + +* n_mod2_preinv may be slower than the chip on Core2 due to the fact that it can + pipeline 2 divisions. Check all occurrences of this function and replace with + divisions where it will speed things up on Core2. Beware, this will slow things + down on AMD, so it is necessary to do this per architecture. The macros in + nmod_vec will also be faster than the functions in ulong_extras, thus they should + be tried first. + +* add profile code for factor_trial, factor_one_line, factor_SQUFOF + +* [maybe] make n_factor_t an array of length 1 so it can be passed by reference + automatically, as per mpz_t's, etc + +* [enhancement] Implement a primality test which only requires factoring of + n-1 up to n^1/3 or n^1/4 + +* [enhancement] Implement a combined p-1 and p+1 primality test as per + http://primes.utm.edu/prove/prove3_3.html + +* [enhancement] Implement a quadratic sieve and use it in n_factor once things + get too large for SQUFOF + + +long_extras +----------- + +* write and use z_gcd and z_invert in fmpz_gcd and fmpz_invert, respectively + + +fmpz_vec +-------- + +* add a cache of mpfr's which can be used as temporaries for functions like + _mpfr_vec_scalar_product + +* test code for ulong_extras/revbin.c + +* add test code for numerous mpfr_vec functions and mpfr_poly_mul_classical + +* make use of mpfr type througout LLL, mpfr_vec and mpfr_mat modules + + +fmpz_factor +----------- + +* Add primality testing, perfect power testing, fast factorisation + (Brent-Pollard, QS, ...) + + +fmpz_mpoly / nmod_mpoly +----------------------- + +* Write fmpz_mpoly_max_bits, use in t-mul_heap test code and mul_heap + +* Write ACCUM2 and ACCUM3 assembly functions and use in mul_heap + +* Make mul_heap take arrays of fmpz's as arguments and document function + + +nmod_poly +--------- + +* Make some assembly optimisations to nmod_poly module. + +* Add basecase versions of log, sqrt, invsqrt series + +* Add O(M(n)) powering mod x^n based on exp and log + +* Implement fast mulmid and use to improve Newton iteration + +* Determine cutoffs for compose_series_divconquer for default use in + compose_series (only when one polynomial is small). + +* Add asymptotically fast resultants? + +* Optimise, write an underscore version of, and test + nmod_poly_remove + +* Improve powmod and powpowmod using precomputed Newton inverse and + 2^k-ary/sliding window powering. + +* Maybe restructure the code in factor.c + +* Add a (fast) function to convert an nmod_poly_factor_t to + an expanded polynomial + + +fmpz_poly +--------- + +* add test code for fmpz_poly_max_limbs + +* Improve the implementations of fmpz_poly_divrem, _div, and _rem, check that + the documentations still apply, and write test code for this --- all of this + makes more sense once there is a choice of algorithms + +* Include test code for fmpz_poly_inv_series, once this method does anything + better than aliasing fmpz_poly_inv_newton + +* Sort out the fmpz_poly_pseudo_div and _rem code. Currently this is just + a hack to call fmpz_poly_pseudo_divrem + +* Fix the inefficient cases in CRT_ui, and move the relevant parts of this + function to the fmpz_vec module + +* Avoid redundant work and memory allocation in fmpz_poly_bit_unpack + and fmpz_poly_bit_unpack_unsigned. + +* Add functions for composition, multiplication and division + by a monic linear factor, i.e. P(x +/- c), P * (x +/- c), P / (x +/- c). + +* xgcd_modular is really slow. But it is not clear why. 1/3 of the time is + spent in resultant, but the CRT code or the nmod_poly_xgcd code may also + be to blame. + +* Make resultants use fast GCD? + +* In fmpz_poly_pseudo_divrem_divconquer, fix the repeated memory allocation + of size O(lenA) in the case when lenA >> lenB. + +fmpq_poly +--------- + +* add fmpq_poly_fprint_pretty + +* Rewrite _fmpq_poly_interpolate_fmpz_vec to use the Newton form as done + in the fmpz_poly interpolation function. In general this should + be much faster. + +* Add versions of fmpq_poly_interpolate_fmpz_vec for fmpq y values, + and fmpq values of both x and y. + +* Add mulhigh + +* Add asymptotically fast resultants? + +* Add pow_trunc + + +fmpz_mod_poly +------------- + +* Replace fmpz_mod_poly_rem by a proper implementation which + actually saves work over divrem. Then, also add test code. + +* Implement a faster GCD function then the euclidean one, then + make the wrapping GCD function choose the appropriate algorithm, + and add some test code + +fmpz_poly_mat +------------- + +* Tune multiplication cutoffs. + +* Take sparseness into account when selecting between algorithms. + +* Investigate more clever pivoting strategies in row reduction. + + +arith +----- + +* Think of a better name for this module and/or move parts of it + to other modules. + +* Write profiling code. + +* Write a faster arith_divisors using the merge sort algorithm + (see Sage's implementation). Alternatively (or as a complement) + write a supernaturally fast _fmpz_vec_sort. + +* Improve arith_divisors by using long and longlong arithmetic + for divisors that fit in 1 or 2 limbs. + +* Optimise memory management in mpq_harmonic. + +* Maybe move the helper functions in primorial.c to the mpn_extras + module. + +* Implement computation of generalised harmonic numbers. + +* Maybe: move Stirling number matrix functions to the fmpz_mat module. + +* Implement computation of Bernoulli numbers modulo a prime + (e.g. porting the code from flint 1) + +* Implement multimodular computation of large Bernoulli numbers + (e.g. porting bernmm) + +* Implement rising factorials and falling factorials (x)_n, (x)^n + as fmpz_poly functions, and add fmpz functions for their + direct evaluation. + +* Implement the binomial coefficient binomial(x,n) as an fmpq_poly + function. + +* Implement Fibonacci polynomials and fmpz Fibonacci numbers. + +* Implement orthogonal polynomials (Jacobi, Hermite, Laguerre, Gegenbauer). + +* Implement hypergeometric polynomials and series. + +* Change the partition function code to use an fmpz (or mpz) instead of + ulong for n, to allow n larger than 10^9 on 32 bits (or 10^19 on 64 bits!) + +* Write tests for the arith_hrr_expsum_factored functions. + +fmpz_mat +-------- + +* Add fmpz_mat/randajtai2.c based on Stehle's matrix.cpp in fpLLL + (requires mpfr_t's). + +* Add element getter and setter methods. + +* Implement Strassen multiplication. + +* Implement fast multiplication when when results are smaller than + 2^(FLINT_BITS-1) by using fmpz arithmetic directly. Also use 2^FLINT_BITS + as one of the "primes" for multimodular multiplication, along with + fast CRT code for this purpose. + +* Write multiplication functions optimised for sparse matrices by changing + the loop order and discarding zero multipliers. + +* Implement fast null space computation. + +* The Dixon p-adic solver should implement output-sensitive termination. + +* The Dixon p-adic solver currently spends most of the time computing + integer matrix-vector products. Instead of using a single prime, it + is likely to be faster to use a product of primes to increase the + proportion of time spent on modular linear algebra. The code should also + use fast radix conversion instead of building up the result incrementally + to improve performance when the output gets large. + +* Maybe optimise multimodular multiplication by pre-transposing + so that transposed nmod_mat multiplication can be used directly instead of + creating a transposed copy in nmod_mat_mul. However, this doesn't help + in the Strassen range unless there also is a transpose version of + nmod_mat_mul_strassen. + +* Use _fmpz_vec functions instead of for loops in some more places. + +* Add transpose versions of common functions, in-place addmul etc. + +* Take sparseness into account when selecting between algorithms. + +* Maybe simplify the interface for row reduction by guaranteeing + that the denominator is the determinant. + + +nmod_mat +-------- + +* Support BLAS and use this for multiplication when entries fit in a double + before reduction. Even for large moduli, it might be faster to use + repeated BLAS multiplications modulo a few small primes followed by CRT. + Linear algebra operations would benefit from BLAS versions of triangular + solving as well. + +* Improve multiplication with packed entries using SSE. Maybe also write + a Strassen for packed entries that does additions faster. + +* Investigate why the constant of solving/rref/inverse compared to + multiplication appears to be worse than in theory (recent paper by Jeannerod, + Pernet and Storjohann). + +* See if Strassen can be improved using combined addmul operations. + +* Consider getting rid of the row pointer array, using offsets instead of + window matrices. The row pointer is only useful for Gaussian elimination, + but there we end up working with a separate permutation array anyway. + +* Add element getter and setter methods, more convenience functions + for setting the zero matrix, identity matrix, etc. + +* Implement nmod_mat_pow. + +* Add functions for computing A*B^T and A^T*B, using transpose + multiplications directly to avoid creating a temporary copy. + +* Maybe: add asserts to check that the modulus is a prime + where this is assumed. + +* Add transpose versions of common functions, in-place addmul etc. + +* The current addmul/submul functions are misnamed since they + implement a more general operation. + +* Improve rref and inverse to perform everything in-place. + + +fmpq +---- + +* Add more functions for generating random numbers. + +* Write a subquadratic fmpq_get_cfrac + +* Implement subquadratic rational reconstruction. Also improve detection + of integers, etc. and perhaps add CRT functions to hide the intermediate + step going from residues -> integer -> rational. + + +fmpq_mat +-------- + +* Add more random functions. + +* Add a user-friendly function for LUP decomposition. + +* Add a nullspace function. + +padic +----- + +* Add test code for the various output formats; + perhaps in the form of examples? + +* Implement padic_val_fac for generic inputs + diff --git a/external/flint-2.4.3/ulong_extras.h b/external/flint-2.4.3/ulong_extras.h new file mode 100644 index 0000000..d3768b9 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras.h @@ -0,0 +1,381 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2006, 2007, 2008, 2009 William Hart + Copyright (C) 2008, Peter Shrimpton + Copyright (C) 2009, Tom Boothby + Copyright (C) 2010, Fredrik Johansson + +******************************************************************************/ + +#ifndef ULONG_EXTRAS_H +#define ULONG_EXTRAS_H + +#include +#include "flint.h" + +#ifdef __cplusplus + extern "C" { +#endif + +typedef struct pair_s +{ + mp_limb_t x, y; +} n_pair_t; + +#define FLINT_MAX_FACTORS_IN_LIMB 15 + +typedef struct { + int num; + int exp[FLINT_MAX_FACTORS_IN_LIMB]; + mp_limb_t p[FLINT_MAX_FACTORS_IN_LIMB]; +} n_factor_t; + +#define FLINT_ODDPRIME_SMALL_CUTOFF 4096 +#define FLINT_NUM_PRIMES_SMALL 172 +#define FLINT_PRIMES_SMALL_CUTOFF 1030 +#define FLINT_PSEUDOSQUARES_CUTOFF 1000 + +#define FLINT_FACTOR_TRIAL_PRIMES 3000 +/* nth_prime(FLINT_FACTOR_TRIAL_PRIMES) */ +#define FLINT_FACTOR_TRIAL_PRIMES_PRIME UWORD(27449) +#define FLINT_FACTOR_TRIAL_CUTOFF (UWORD(27449) * UWORD(27449)) + +#define FLINT_PRIMES_TAB_DEFAULT_CUTOFF 1000000 + +#define FLINT_FACTOR_SQUFOF_ITERS 50000 +#define FLINT_FACTOR_ONE_LINE_MAX (UWORD(1)<<39) +#define FLINT_FACTOR_ONE_LINE_ITERS 40000 + +#define FLINT_PRIME_PI_ODD_LOOKUP_CUTOFF 311 + +#define FLINT_SIEVE_SIZE 65536 + +#if FLINT64 +#define UWORD_MAX_PRIME UWORD(18446744073709551557) +#else +#define UWORD_MAX_PRIME UWORD(4294967291) +#endif + +typedef struct +{ + slong small_i; + slong small_num; + unsigned int * small_primes; + + mp_limb_t sieve_a; + mp_limb_t sieve_b; + slong sieve_i; + slong sieve_num; + char * sieve; +} +n_primes_struct; + +typedef n_primes_struct n_primes_t[1]; + +void n_primes_init(n_primes_t iter); + +void n_primes_clear(n_primes_t iter); + +void n_primes_extend_small(n_primes_t iter, mp_limb_t bound); + +void n_primes_sieve_range(n_primes_t iter, mp_limb_t a, mp_limb_t b); + +void n_primes_jump_after(n_primes_t iter, mp_limb_t n); + +static __inline__ mp_limb_t +n_primes_next(n_primes_t iter) +{ + if (iter->small_i < iter->small_num) + return iter->small_primes[(iter->small_i)++]; + + for (;;) + { + while (iter->sieve_i < iter->sieve_num) + if (iter->sieve[iter->sieve_i++] != 0) + return iter->sieve_a + 2 * (iter->sieve_i - 1); + + if (iter->sieve_b == 0) + n_primes_jump_after(iter, iter->small_primes[iter->small_num-1]); + else + n_primes_jump_after(iter, iter->sieve_b); + } +} + +extern const unsigned int flint_primes_small[]; + +extern FLINT_TLS_PREFIX mp_limb_t * _flint_primes[FLINT_BITS]; +extern FLINT_TLS_PREFIX double * _flint_prime_inverses[FLINT_BITS]; +extern FLINT_TLS_PREFIX int _flint_primes_used; + +void n_compute_primes(ulong num_primes); + +void n_cleanup_primes(void); + +const mp_limb_t * n_primes_arr_readonly(ulong n); +const double * n_prime_inverses_arr_readonly(ulong n); + +mp_limb_t n_randlimb(flint_rand_t state); + +mp_limb_t n_randint(flint_rand_t state, mp_limb_t limit); + +mp_limb_t n_randbits(flint_rand_t state, unsigned int bits); + +mp_limb_t n_randtest_bits(flint_rand_t state, int bits); + +mp_limb_t n_randtest(flint_rand_t state); + +mp_limb_t n_randtest_not_zero(flint_rand_t state); + +mp_limb_t n_randprime(flint_rand_t state, ulong bits, int proved); + +mp_limb_t n_randtest_prime(flint_rand_t state, int proved); + +mp_limb_t n_pow(mp_limb_t n, ulong exp); + +mp_limb_t n_flog(mp_limb_t n, mp_limb_t b); + +mp_limb_t n_clog(mp_limb_t n, mp_limb_t b); + +static __inline__ +double n_precompute_inverse(mp_limb_t n) +{ + return (double) 1 / (double) n; +} + +static __inline__ +mp_limb_t n_preinvert_limb(mp_limb_t n) +{ + mp_limb_t norm, ninv; + + count_leading_zeros(norm, n); + invert_limb(ninv, n< x ? x + y : x + y - n); +} + +static __inline__ +mp_limb_t n_submod(mp_limb_t x, mp_limb_t y, mp_limb_t n) +{ + return (y > x ? x - y + n : x - y); +} + +static __inline__ +mp_limb_t n_negmod(mp_limb_t x, mp_limb_t n) +{ + return n_submod(0, x, n); +} + +mp_limb_t n_sqrtmod(mp_limb_t a, mp_limb_t p); + +slong n_sqrtmod_2pow(mp_limb_t ** sqrt, mp_limb_t a, slong exp); + +slong n_sqrtmod_primepow(mp_limb_t ** sqrt, mp_limb_t a, + mp_limb_t p, slong exp); + +slong n_sqrtmodn(mp_limb_t ** sqrt, mp_limb_t a, n_factor_t * fac); + +mp_limb_t n_gcd(mp_limb_t x, mp_limb_t y); + +static __inline__ mp_limb_t +n_gcd_full(mp_limb_t x, mp_limb_t y) +{ + if (x >= y) + return n_gcd(x, y); + else + return n_gcd(y, x); +} + +mp_limb_t n_xgcd(mp_limb_t * a, mp_limb_t * b, mp_limb_t x, mp_limb_t y); + +mp_limb_t n_invmod(mp_limb_t x, mp_limb_t y); + +mp_limb_t n_gcdinv(mp_limb_t * a, mp_limb_t x, mp_limb_t y); + +ulong n_revbin(ulong in, ulong bits); + +int n_jacobi(mp_limb_signed_t x, mp_limb_t y); + +int n_jacobi_unsigned(mp_limb_t x, mp_limb_t y); + +mp_limb_t n_sqrt(mp_limb_t a); + +mp_limb_t n_sqrtrem(mp_limb_t * r, mp_limb_t a); + +int n_is_square(mp_limb_t x); + +int n_is_perfect_power235(mp_limb_t n); + +int n_is_oddprime_small(mp_limb_t n); + +int n_is_oddprime_binary(mp_limb_t n); + +int n_is_probabprime_fermat(mp_limb_t n, mp_limb_t i); + +int n_is_probabprime_fibonacci(mp_limb_t n); + +int n_is_probabprime_lucas(mp_limb_t n); + +int n_is_probabprime_BPSW(mp_limb_t n); + +int n_is_strong_probabprime_precomp(mp_limb_t n, + double npre, mp_limb_t a, mp_limb_t d); + +int n_is_strong_probabprime2_preinv(mp_limb_t n, + mp_limb_t ninv, mp_limb_t a, mp_limb_t d); + +int n_is_probabprime(mp_limb_t n); + +int n_is_prime_pseudosquare(mp_limb_t n); + +int n_is_prime_pocklington(mp_limb_t n, ulong iterations); + +int n_is_prime(mp_limb_t n); + +mp_limb_t n_nth_prime(ulong n); + +void n_nth_prime_bounds(mp_limb_t *lo, mp_limb_t *hi, ulong n); + +ulong n_prime_pi(mp_limb_t n); + +void n_prime_pi_bounds(ulong *lo, ulong *hi, mp_limb_t n); + +int n_remove(mp_limb_t * n, mp_limb_t p); + +int n_remove2_precomp(mp_limb_t * n, mp_limb_t p, double ppre); + +static __inline__ +void n_factor_init(n_factor_t * factors) +{ + factors->num = UWORD(0); +} + +void n_factor_insert(n_factor_t * factors, mp_limb_t p, ulong exp); + +mp_limb_t n_factor_trial_range(n_factor_t * factors, + mp_limb_t n, ulong start, ulong num_primes); + +mp_limb_t n_factor_trial_partial(n_factor_t * factors, mp_limb_t n, + mp_limb_t * prod, ulong num_primes, mp_limb_t limit); + +mp_limb_t n_factor_trial(n_factor_t * factors, + mp_limb_t n, ulong num_primes); + +mp_limb_t n_factor_partial(n_factor_t * factors, + mp_limb_t n, mp_limb_t limit, int proved); + +mp_limb_t n_factor_power235(ulong *exp, mp_limb_t n); + +mp_limb_t n_factor_one_line(mp_limb_t n, ulong iters); + +mp_limb_t n_factor_lehman(mp_limb_t n); + +mp_limb_t n_factor_SQUFOF(mp_limb_t n, ulong iters); + +void n_factor(n_factor_t * factors, mp_limb_t n, int proved); + +mp_limb_t n_factor_pp1(mp_limb_t n, ulong B1, ulong c); + +int n_is_squarefree(mp_limb_t n); + +int n_moebius_mu(mp_limb_t n); + +void n_moebius_mu_vec(int * mu, ulong len); + +mp_limb_t n_euler_phi(mp_limb_t n); + +int n_sizeinbase(mp_limb_t n, int base); + +mp_limb_t n_nextprime(mp_limb_t n, int proved); + +mp_limb_t n_factorial_mod2_preinv(ulong n, mp_limb_t p, mp_limb_t pinv); + +mp_limb_t n_factorial_fast_mod2_preinv(ulong n, mp_limb_t p, mp_limb_t pinv); + +mp_limb_t n_primitive_root_prime_prefactor(mp_limb_t p, n_factor_t * factors); + +mp_limb_t n_primitive_root_prime(mp_limb_t p); + +mp_limb_t n_discrete_log_bsgs(mp_limb_t b, mp_limb_t a, mp_limb_t n); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/flint-2.4.3/ulong_extras/cleanup_primes.c b/external/flint-2.4.3/ulong_extras/cleanup_primes.c new file mode 100644 index 0000000..e92ee1c --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/cleanup_primes.c @@ -0,0 +1,46 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 "flint.h" +#include "ulong_extras.h" + +void +n_cleanup_primes() +{ + int i; + + for (i = 0; i < _flint_primes_used; i++) + { + if (i < _flint_primes_used - 1 && _flint_primes[i] == _flint_primes[i+1]) + continue; + + flint_free(_flint_primes[i]); + flint_free(_flint_prime_inverses[i]); + } + + _flint_primes_used = 0; +} + diff --git a/external/flint-2.4.3/ulong_extras/clog.c b/external/flint-2.4.3/ulong_extras/clog.c new file mode 100644 index 0000000..96f69ea --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/clog.c @@ -0,0 +1,50 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" + +mp_limb_t n_clog(mp_limb_t n, mp_limb_t b) +{ + mp_limb_t r, p, t, phi; + + r = 0; + p = 1; + + while (1) + { + umul_ppmm(phi, t, p, b); + + if (t <= n && !phi) + { + r++; + p = t; + } + else + return r + (p != n); + } +} diff --git a/external/flint-2.4.3/ulong_extras/compute_primes.c b/external/flint-2.4.3/ulong_extras/compute_primes.c new file mode 100644 index 0000000..c33793e --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/compute_primes.c @@ -0,0 +1,118 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 Tom Boothby + Copyright (C) 2009 William Hart + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#define ulong ulongxx /* interferes with system includes */ +#include +#include +#include +#undef ulong +#include +#define ulong mp_limb_t + +#include "flint.h" +#include "ulong_extras.h" + +#if FLINT_REENTRANT && !HAVE_TLS +#include + +static pthread_once_t primes_initialised = PTHREAD_ONCE_INIT; +pthread_mutex_t primes_lock; +#endif + +const unsigned int flint_primes_small[] = +{ + 2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97, + 101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181, + 191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277, + 281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383, + 389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487, + 491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601, + 607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709, + 719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827, + 829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947, + 953,967,971,977,983,991,997,1009,1013,1019,1021 +}; + + +/* _flint_primes[i] holds an array of 2^i primes */ +FLINT_TLS_PREFIX mp_limb_t * _flint_primes[FLINT_BITS]; +FLINT_TLS_PREFIX double * _flint_prime_inverses[FLINT_BITS]; +FLINT_TLS_PREFIX int _flint_primes_used = 0; + +#if FLINT_REENTRANT && !HAVE_TLS +void n_compute_primes_init() +{ + pthread_mutex_init(&primes_lock, NULL); +} +#endif + +void +n_compute_primes(ulong num_primes) +{ + int i, m; + ulong num_computed; + +#if FLINT_REENTRANT && !HAVE_TLS + pthread_once(&primes_initialised, n_compute_primes_init); + pthread_mutex_lock(&primes_lock); +#endif + + m = FLINT_CLOG2(num_primes); + + if (_flint_primes_used == 0) + flint_register_cleanup_function(n_cleanup_primes); + + if (m >= _flint_primes_used) + { + n_primes_t iter; + + num_computed = UWORD(1) << m; + _flint_primes[m] = flint_malloc(sizeof(mp_limb_t) * num_computed); + _flint_prime_inverses[m] = flint_malloc(sizeof(double) * num_computed); + + n_primes_init(iter); + for (i = 0; i < num_computed; i++) + { + _flint_primes[m][i] = n_primes_next(iter); + _flint_prime_inverses[m][i] = n_precompute_inverse(_flint_primes[m][i]); + } + n_primes_clear(iter); + + /* copy to lower power-of-two slots */ + for (i = m - 1; i >= _flint_primes_used; i--) + { + _flint_primes[i] = _flint_primes[m]; + _flint_prime_inverses[i] = _flint_prime_inverses[m]; + } + _flint_primes_used = m + 1; + } + +#if FLINT_REENTRANT && !HAVE_TLS + pthread_mutex_unlock(&primes_lock); +#endif +} + diff --git a/external/flint-2.4.3/ulong_extras/discrete_log_bsgs.c b/external/flint-2.4.3/ulong_extras/discrete_log_bsgs.c new file mode 100644 index 0000000..d4240df --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/discrete_log_bsgs.c @@ -0,0 +1,73 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include +#include +#include + +#include "flint.h" +#include "ulong_extras.h" + +mp_limb_t n_discrete_log_bsgs(mp_limb_t b, mp_limb_t a, mp_limb_t n) +{ + int i, j; + double ninv; + mp_limb_t m, a_m, c; + mp_limb_t * table; + + ninv = n_precompute_inverse(n); + + m = ceil(sqrt((double) n)); + + table = (mp_limb_t*)flint_malloc(m * sizeof(mp_limb_t)); + + table[0] = 1; + for (j = 1; j < m; j++) + { + table[j] = n_mulmod_precomp(table[j-1], a, n, ninv); + } + + a_m = n_invmod(a, n); + a_m = n_powmod_precomp(a_m, m, n, ninv); + + c = b; + + for (i = 0; i < m; i++) + { + for (j = 0; j < m; j++) + { + if (c == table[j]) + { + flint_free(table); + return i * m + j; + } + } + c = n_mulmod_precomp(c, a_m, n, ninv); + } + + flint_free(table); + flint_printf("Exception (n_discrete_log_bsgs). discrete log not found.\n"); + abort(); +} diff --git a/external/flint-2.4.3/ulong_extras/divrem2_precomp.c b/external/flint-2.4.3/ulong_extras/divrem2_precomp.c new file mode 100644 index 0000000..4a2cf32 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/divrem2_precomp.c @@ -0,0 +1,89 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" + +mp_limb_t +n_divrem2_precomp(mp_limb_t * q, mp_limb_t a, mp_limb_t n, double npre) +{ + mp_limb_t quot; + slong rem; + + if (a < n) + { + (*q) = UWORD(0); + return a; + } + + if ((mp_limb_signed_t) n < WORD(0)) + { + (*q) = UWORD(1); + return a - n; + } + + if (n == 1) + { + quot = a; + rem = 0; + } else + { + quot = (ulong) ( a * npre); + rem = a - quot * n; + } + + if (rem < (mp_limb_signed_t) (-n)) + quot -= (mp_limb_t) ((double) (-rem) * npre); + else if (rem >= (slong) n) + quot += (mp_limb_t) ((double) rem * npre); + else if (rem < WORD(0)) + { + (*q) = quot - 1; + return rem + n; + } + else + { + (*q) = quot; + return rem; + } + + rem = a - quot * n; + if (rem >= (slong) n) + { + (*q) = quot + 1; + return rem - n; + } + else if (rem < WORD(0)) + { + (*q) = quot - 1; + return rem + n; + } + else + { + (*q) = quot; + return rem; + } +} diff --git a/external/flint-2.4.3/ulong_extras/doc/ulong_extras.txt b/external/flint-2.4.3/ulong_extras/doc/ulong_extras.txt new file mode 100644 index 0000000..28d3d98 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/doc/ulong_extras.txt @@ -0,0 +1,1209 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +******************************************************************************* + + Random functions + +******************************************************************************* + +void n_randinit(flint_rand_t state) + + Initialise a random state for use in random functions. + +void n_randclear(flint_rand_t state) + + Release any memory used by a random state. + +mp_limb_t n_randlimb(flint_rand_t state) + + Returns a uniformly pseudo random limb. + + The algorithm generates two random half limbs $s_j$, $j = 0, 1$, + by iterating respectively $v_{i+1} = (v_i a + b) \bmod{p_j}$ for + some initial seed $v_0$, randomly chosen values $a$ and $b$ and + \code{p_0 = 4294967311 = nextprime(2^32)} on a 64-bit machine + and \code{p_0 = nextprime(2^16)} on a 32-bit machine and + \code{p_1 = nextprime(p_0)}. + +mp_limb_t n_randbits(flint_rand_t state, unsigned int bits) + + Returns a uniformly pseudo random number with the given number of + bits. The most significant bit is always set, unless zero is passed, + in which case zero is returned. + +mp_limb_t n_randtest_bits(flint_rand_t state, int bits) + + Returns a uniformly pseudo random number with the given number of + bits. The most significant bit is always set, unless zero is passed, + in which case zero is returned. The probability of a value with a + sparse binary representation being returned is increased. This + function is intended for use in test code. + +mp_limb_t n_randint(flint_rand_t state, mp_limb_t limit) + + Returns a uniformly pseudo random number up to but not including + the given limit. If zero is passed as a parameter, an entire random + limb is returned. + +mp_limb_t n_randtest(flint_rand_t state) + + Returns a pseudo random number with a random number of bits, + from $0$ to \code{FLINT_BITS}. The probability of the special + values $0$, $1$, \code{COEFF_MAX} and \code{WORD_MAX} is increased + as is the probability of a value with sparse binary representation. + This random function is mainly used for testing purposes. + This function is intended for use in test code. + +mp_limb_t n_randtest_not_zero(flint_rand_t state) + + As for \code{n_randtest()}, but does not return $0$. + This function is intended for use in test code. + +mp_limb_t n_randprime(flint_rand_t state, unsigned slong bits, int proved) + + Returns a random prime number (proved = 1) or probable prime (proved = 0) + with \code{bits} bits, where \code{bits} must be at least 2 and + at most \code{FLINT_BITS}. + +mp_limb_t n_randtest_prime(flint_rand_t state, int proved) + + Returns a random prime number (proved = 1) or probable prime (proved = 0) + with size randomly chosen between 2 and \code{FLINT_BITS} bits. + This function is intended for use in test code. + +******************************************************************************* + + Basic arithmetic + +******************************************************************************* + +mp_limb_t n_pow(mp_limb_t n, ulong exp) + + Returns \code{n^exp}. No checking is done for overflow. The exponent + may be zero. We define $0^0 = 1$. + + The algorithm simply uses a for loop. Repeated squaring is + unlikely to speed up this algorithm. + +mp_limb_t n_flog(mp_limb_t n, mp_limb_t b) + + Returns $\floor{\log_b x}$. + + Assumes that $x \geq 1$ and $b \geq 2$. + +mp_limb_t n_clog(mp_limb_t n, mp_limb_t b) + + Returns $\ceil{\log_b x}$. + + Assumes that $x \geq 1$ and $b \geq 2$. + +******************************************************************************* + + Miscellaneous + +******************************************************************************* + +ulong n_revbin(ulong in, ulong bits) + + Returns the binary reverse of \code{in}, assuming it is the given + number of bits in length, e.g.\ \code{n_revbin(10110, 6)} will return + \code{110100}. + +int n_sizeinbase(mp_limb_t n, int base) + + Returns the exact number of digits needed to represent $n$ as a + string in base \code{base} assumed to be between 2 and 36. + Returns 1 when $n = 0$. + + +******************************************************************************* + + Basic arithmetic with precomputed inverses + +******************************************************************************* + +mp_limb_t n_mod_precomp(mp_limb_t a, mp_limb_t n, double ninv) + + Returns $a \bmod{n}$ given a precomputed inverse of $n$ computed + by\\ \code{n_precompute_inverse()}. We require \code{n < 2^FLINT_D_BITS} + and \code{a < 2^(FLINT_BITS-1)} and $0 \leq a < n^2$. + + We assume the processor is in the standard round to nearest + mode. Thus \code{ninv} is correct to $53$ binary bits, the least + significant bit of which we shall call a place, and can be at most + half a place out. When $a$ is multiplied by $ninv$, the binary + representation of $a$ is exact and the mantissa is less than $2$, thus we + see that \code{a * ninv} can be at most one out in the mantissa. We now + truncate \code{a * ninv} to the nearest integer, which is always a round + down. Either we already have an integer, or we need to make a change down + of at least $1$ in the last place. In the latter case we either get + precisely the exact quotient or below it as when we rounded the + product to the nearest place we changed by at most half a place. + In the case that truncating to an integer takes us below the + exact quotient, we have rounded down by less than $1$ plus half a + place. But as the product is less than $n$ and $n$ is less than $2^{53}$, + half a place is less than $1$, thus we are out by less than $2$ from + the exact quotient, i.e.\ the quotient we have computed is the + quotient we are after or one too small. That leaves only the case + where we had to round up to the nearest place which happened to + be an integer, so that truncating to an integer didn't change + anything. But this implies that the exact quotient $a/n$ is less + than $2^{-54}$ from an integer. We deal with this rare case by + subtracting 1 from the quotient. Then the quotient we have computed is + either exactly what we are after, or one too small. + +mp_limb_t n_mod2_precomp(mp_limb_t a, mp_limb_t n, double ninv) + + Returns $a \bmod{n}$ given a precomputed inverse of $n$ computed by\\ + \code{n_precompute_inverse()}. There are no restrictions on $a$ or + on $n$. + + As for \code{n_mod_precomp()} for $n < 2^{53}$ and $a < n^2$ the + computed quotient is either what we are after or one too large or small. + We deal with these cases. Otherwise we can be sure that the + top $52$ bits of the quotient are computed correctly. We take + the remainder and adjust the quotient by multiplying the + remainder by \code{ninv} to compute another approximate quotient as + per \code{mod_precomp}. Now the remainder may be either + negative or positive, so the quotient we compute may be one + out in either direction. + +mp_limb_t n_mod2_preinv(mp_limb_t a, mp_limb_t n, mp_limb_t ninv) + + Returns $a \bmod{n}$ given a precomputed inverse of $n$ computed by + \code{n_preinvert_limb()}. There are no restrictions on $a$ or on $n$. + + The old version of this function was implemented simply by + making use of\\ \code{udiv_qrnnd_preinv()}. + + The new version uses the new algorithm of Granlund and + M\"oller~\citep{GraMol2010}. First $n$ is normalised and a + shifted into two limbs to compensate. Then their algorithm is + applied verbatim and the result shifted back. + + % Torbjorn Granlund and Niels Moller + % Improved Division by Invariant Integers + % http://www.lysator.liu.se/~nisse/archive/draft-division-paper.pdf + +mp_limb_t n_divrem2_precomp(mp_limb_t * q, mp_limb_t a, mp_limb_t n, + double npre) + + Returns $a \bmod{n}$ given a precomputed inverse of $n$ computed by\\ + \code{n_precompute_inverse()} and sets $q$ to the quotient. There + are no restrictions on $a$ or on $n$. + + This is as for \code{n_mod2_precomp()} with some additional care taken + to retain the quotient information. There are also special + cases to deal with the case where $a$ is already reduced modulo + $n$ and where $n$ is $64$ bits and $a$ is not reduced modulo $n$. + +mp_limb_t n_ll_mod_preinv(mp_limb_t a_hi, mp_limb_t a_lo, + mp_limb_t n, mp_limb_t ninv) + + Returns $a \bmod{n}$ given a precomputed inverse of $n$ computed by + \code{n_preinvert_limb()}. There are no restrictions on $a$, which + will be two limbs \code{(a_hi, a_lo)}, or on $n$. + + The old version of this function merely reduced the top limb + \code{a_hi} modulo $n$ so that \code{udiv_qrnnd_preinv()} could + be used. + + The new version reduces the top limb modulo $n$ as per + \code{n_mod2_preinv()} and then the algorithm of Granlund and + M\"oller~\citep{GraMol2010} is used again to reduce modulo $n$. + + % Torbjorn Granlund and Niels Moller + % Improved Division by Invariant Integers + % http://www.lysator.liu.se/~nisse/archive/draft-division-paper.pdf + +mp_limb_t n_lll_mod_preinv(mp_limb_t a_hi, mp_limb_t a_mi, + mp_limb_t a_lo, mp_limb_t n, mp_limb_t ninv) + + Returns $a \bmod{n}$, where $a$ has three limbs \code{(a_hi, a_mi, a_lo)}, + given a precomputed inverse of $n$ computed by \code{n_preinvert_limb()}. + It is assumed that \code{a_hi} is reduced modulo $n$. There are no + restrictions on $n$. + + This function uses the algorithm of Granlund and + M\"oller~\citep{GraMol2010} to first reduce the top two limbs + modulo $n$, then does the same on the bottom two limbs. + + % Torbjorn Granlund and Niels Moller + % Improved Division by Invariant Integers + % http://www.lysator.liu.se/~nisse/archive/draft-division-paper.pdf + +mp_limb_t n_mulmod_precomp(mp_limb_t a, mp_limb_t b, mp_limb_t n, double ninv) + + Returns $a b \bmod{n}$ given a precomputed inverse of $n$ + computed by\\ \code{n_precompute_inverse()}. We require + \code{n < 2^FLINT_D_BITS} and $0 \leq a, b < n$. + + We assume the processor is in the standard round to nearest + mode. Thus \code{ninv} is correct to $53$ binary bits, the least + significant bit of which we shall call a place, and can be at most half + a place out. The product of $a$ and $b$ is computed with error at most + half a place. When \code{a * b} is multiplied by $ninv$ we find that the + exact quotient and computed quotient differ by less than two places. As + the quotient is less than $n$ this means that the exact quotient is at + most $1$ away from the computed quotient. We truncate this quotient to + an integer which reduces the value by less than $1$. We end up with a + value which can be no more than two above the quotient we are after and + no less than two below. However an argument similar to that for + \code{n_mod_precomp()} shows that the truncated computed quotient cannot + be two smaller than the truncated exact quotient. In other words the + computed integer quotient is at most two above and one below the quotient + we are after. + +mp_limb_t n_mulmod2_preinv(mp_limb_t a, mp_limb_t b, + mp_limb_t n, mp_limb_t ninv) + + Returns $a b \bmod{n}$ given a precomputed inverse of $n$ computed by\\ + \code{n_preinvert_limb()}. There are no restrictions on $a$, $b$ or + on $n$. This is implemented by multiplying using \code{umul_ppmm()} and + then reducing using \code{n_ll_mod_preinv()}. + +mp_limb_t n_mulmod_preinv(mp_limb_t a, mp_limb_t b, mp_limb_t n, + mp_limb_t ninv, ulong norm) + + Returns $a b \pmod{n}$ given a precomputed inverse of $n$ computed by\\ + \code{n_preinvert_limb()}, assuming $a$ and $b$ are reduced modulo $n$ + and $n$ is normalised, i.e. with most significant bit set. There are + no other restrictions on $a$, $b$ or $n$. + + The value \code{norm} is provided for convenience. As $n$ is required + to be normalised, it may be that $a$ and $b$ have been shifted to the + left by \code{norm} bits before calling the function. Their product + then has an extra factor of $2^\text{norm}$. Specifying a nonzero + \code{norm} will shift the product right by this many bits before + reducing it. + + The algorithm use is that of Granlund and M\"oller~\citep{GraMol2010}. + + % Torbjorn Granlund and Niels Moller + % Improved Division by Invariant Integers + % http://www.lysator.liu.se/~nisse/archive/draft-division-paper.pdf + + +******************************************************************************* + + Greatest common divisor + +******************************************************************************* + +mp_limb_t n_gcd(mp_limb_t x, mp_limb_t y) + + Returns the greatest common divisor $g$ of $x$ and $y$. + We require $x \geq y$. + + The algorithm is a slight embelishment of the Euclidean algorithm + which uses some branches to avoid most divisions. + + One wishes to compute the quotient and remainder of $u_3 / v_3$ without + division where possible. This is accomplished when $u_3 < 4 v_3$, i.e.\ + the quotient is either $1$, $2$ or $3$. + + We first compute $s = u_3 - v_3$. If $s < v_3$, i.e.\ $u_3 < 2 v_3$, we + know the quotient is $1$, else if $s < 2 v_3$, i.e.\ $u_3 < 3 v_3$ we + know the quotient is $2$. In the remaining cases, the quotient must + be $3$. When the quotient is $4$ or above, we use division. However this + happens rarely for generic inputs. + +mp_limb_t n_gcd_full(mp_limb_t x, mp_limb_t y) + + Returns the greatest common divisor $g$ of $x$ and $y$. + No assumptions are made about $x$ and $y$. + +mp_limb_t n_gcdinv(mp_limb_t * a, mp_limb_t x, mp_limb_t y) + + Returns the greatest common divisor $g$ of $x$ and $y$ and computes + $a$ such that $0 \leq a < y$ and $a x = \gcd(x, y) \bmod{y}$, when + this is defined. We require $0 \leq x < y$. + + This is merely an adaption of the extended Euclidean algorithm with + appropriate normalisation. + +mp_limb_t n_xgcd(mp_limb_t * a, mp_limb_t * b, mp_limb_t x, mp_limb_t y) + + Returns the greatest common divisor $g$ of $x$ and $y$ and unsigned + values $a$ and $b$ such that $a x - b y = g$. We require $x \geq y$. + + We claim that computing the extended greatest common divisor via the + Euclidean algorithm always results in cofactor $\abs{a} < x/2$, + $\abs{b} < x/2$, with perhaps some small degenerate exceptions. + + We proceed by induction. + + Suppose we are at some step of the algorithm, with $x_n = q y_n + r$ + with $r \geq 1$, and suppose $1 = s y_n - t r$ with + $s < y_n / 2$, $t < y_n / 2$ by hypothesis. + + Write $1 = s y_n - t (x_n - q y_n) = (s + t q) y_n - t x_n$. + + It suffices to show that $(s + t q) < x_n / 2$ as $t < y_n / 2 < x_n / 2$, + which will complete the induction step. + + But at the previous step in the backsubstitution we would have had + $1 = s r - c d$ with $s < r/2$ and $c < r/2$. + + Then $s + t q < r/2 + y_n / 2 q = (r + q y_n)/2 = x_n / 2$. + + See the documentation of \code{n_gcd()} for a description of the + branching in the algorithm, which is faster than using division. + +******************************************************************************* + + Jacobi and Kronecker symbols + +******************************************************************************* + +int n_jacobi(mp_limb_signed_t x, mp_limb_t y) + + Computes the Jacobi symbol of $x \bmod{y}$. Assumes that $y$ is positive + and odd, and for performance reasons that $\gcd(x, y) = 1$. + + This is just a straightforward application of the law of quadratic + reciprocity. For performance, divisions are replaced with some + comparisons and subtractions where possible. + +int n_jacobi_unsigned(mp_limb_t x, mp_limb_t y) + + Computes the Jacobi symbol, allowing $x$ to go up to a full limb. + +******************************************************************************* + + Modular Arithmetic + +******************************************************************************* + +mp_limb_t n_addmod(mp_limb_t a, mp_limb_t b, mp_limb_t n) + + Returns $(a + b) \bmod{n}$. + +mp_limb_t n_submod(mp_limb_t a, mp_limb_t b, mp_limb_t n) + + Returns $(a - b) \bmod{n}$. + +mp_limb_t n_invmod(mp_limb_t x, mp_limb_t y) + + Returns a value $a$ such that $0 \leq a < y$ and + $a x = \gcd(x, y) \bmod{y}$, when this is defined. + We require $0 \leq x < y$. + + Specifically, when $x$ is coprime to $y$, $a$ is the inverse + of $x$ in $\Z / y \Z$. + + This is merely an adaption of the extended Euclidean algorithm + with appropriate normalisation. + +mp_limb_t n_powmod_precomp(mp_limb_t a, mp_limb_signed_t exp, + mp_limb_t n, double npre) + + Returns \code{a^exp} modulo $n$ given a precomputed inverse of $n$ + computed by\\ \code{n_precompute_inverse()}. We require $n < 2^{53}$ + and $0 \leq a < n$. There are no restrictions on \code{exp}, i.e.\ + it can be negative. + + This is implemented as a standard binary powering algorithm using + repeated squaring and reducing modulo $n$ at each step. + +mp_limb_t n_powmod_ui_precomp(mp_limb_t a, mp_limb_t exp, + mp_limb_t n, double npre) + + Returns \code{a^exp} modulo $n$ given a precomputed inverse of $n$ + computed by\\ \code{n_precompute_inverse()}. We require $n < 2^{53}$ + and $0 \leq a < n$. The exponent \code{exp} is unsigned and so + can be larger than allowed by \code{n_powmod_precomp}. + + This is implemented as a standard binary powering algorithm using + repeated squaring and reducing modulo $n$ at each step. + +mp_limb_t n_powmod(mp_limb_t a, mp_limb_signed_t exp, mp_limb_t n) + + Returns \code{a^exp} modulo $n$. We require \code{n < 2^FLINT_D_BITS} + and $0 \leq a < n$. There are no restrictions on \code{exp}, i.e.\ + it can be negative. + + This is implemented by precomputing an inverse and calling the + \code{precomp} version of this function. + +mp_limb_t n_powmod2_preinv(mp_limb_t a, mp_limb_signed_t exp, mp_limb_t n, + mp_limb_t ninv) + + Returns \code{(a^exp) % n} given a precomputed inverse of $n$ computed + by \code{n_preinvert_limb()}. We require $0 \leq a < n$, but there are no + restrictions on $n$ or on \code{exp}, i.e.\ it can be negative. + + This is implemented as a standard binary powering algorithm using + repeated squaring and reducing modulo $n$ at each step. + +mp_limb_t n_powmod2(mp_limb_t a, mp_limb_signed_t exp, mp_limb_t n) + + Returns \code{(a^exp) % n}. We require $0 \leq a < n$, but there are + no restrictions on $n$ or on \code{exp}, i.e.\ it can be negative. + + This is implemented by precomputing an inverse limb and calling the + \code{preinv} version of this function. + +mp_limb_t n_powmod2_ui_preinv(mp_limb_t a, mp_limb_t exp, mp_limb_t n, + mp_limb_t ninv) + + Returns \code{(a^exp) % n} given a precomputed inverse of $n$ computed + by \code{n_preinvert_limb()}. We require $0 \leq a < n$, but there are no + restrictions on $n$. The exponent \code{exp} is unsigned and so can be + larger than allowed by \code{n_powmod2_preinv}. + + This is implemented as a standard binary powering algorithm using + repeated squaring and reducing modulo $n$ at each step. + +mp_limb_t n_sqrtmod(mp_limb_t a, mp_limb_t p) + + Computes a square root of $a$ modulo $p$. + + Assumes that $p$ is a prime and that $a$ is reduced modulo $p$. + Returns 0 if $a$ is a quadratic non-residue modulo $p$. + +slong n_sqrtmod_2pow(mp_limb_t ** sqrt, mp_limb_t a, slong exp) + + Computes all the square roots of \code{a} modulo \code{2^exp}. The roots + are stored in an array which is created and whose address is stored in + the location pointed to by \code{sqrt}. The array of roots is allocated + by the function but must be cleaned up by the user by calling + \code{flint_free}. The number of roots is returned by the function. If + \code{a} is not a quadratic residue modulo \code{2^exp} then 0 is + returned by the function and the location \code{sqrt} points to is set to + NULL. + +slong +n_sqrtmod_primepow(mp_limb_t ** sqrt, mp_limb_t a, mp_limb_t p, slong exp) + + Computes all the square roots of \code{a} modulo \code{p^exp}. The roots + are stored in an array which is created and whose address is stored in + the location pointed to by \code{sqrt}. The array of roots is allocated + by the function but must be cleaned up by the user by calling + \code{flint_free}. The number of roots is returned by the function. If + \code{a} is not a quadratic residue modulo \code{p^exp} then 0 is + returned by the function and the location \code{sqrt} points to is set to + NULL. + +slong n_sqrtmodn(mp_limb_t ** sqrt, mp_limb_t a, n_factor_t * fac) + + Computes all the square roots of \code{a} modulo \code{m} given the + factorisation of \code{m} in \code{fac}. The roots are stored in an array + which is created and whose address is stored in the location pointed to by + \code{sqrt}. The array of roots is allocated by the function but must be + cleaned up by the user by calling \code{flint_free}. The number of roots + is returned by the function. If \code{a} is not a quadratic residue modulo + \code{m} then 0 is returned by the function and the location \code{sqrt} + points to is set to NULL. + +******************************************************************************* + + Prime number generation and counting + +******************************************************************************* + +void n_primes_init(n_primes_t iter) + + Initialises the prime number iterator \code{iter} for use. + +void n_primes_clear(n_primes_t iter) + + Clears memory allocated by the prime number iterator \code{iter}. + +mp_limb_t n_primes_next(n_primes_t iter) + + Returns the next prime number and advances the state of \code{iter}. + The first call returns 2. + + Small primes are looked up from \code{flint_small_primes}. + When this table is exhausted, primes are generated in blocks + by calling \code{n_primes_sieve_range}. + +void n_primes_jump_after(n_primes_t iter, mp_limb_t n) + + Changes the state of \code{iter} to start generating primes + after $n$ (excluding $n$ itself). + +void n_primes_extend_small(n_primes_t iter, mp_limb_t bound) + + Extends the table of small primes in \code{iter} to contain + at least two primes larger than or equal to \code{bound}. + +void n_primes_sieve_range(n_primes_t iter, mp_limb_t a, mp_limb_t b) + + Sets the block endpoints of \code{iter} to the smallest and + largest odd numbers between $a$ and $b$ inclusive, and + sieves to mark all odd primes in this range. + The iterator state is changed to point to the first + number in the sieved range. + +void n_compute_primes(ulong num_primes) + + Precomputes at least \code{num_primes} primes and their \code{double} + precomputed inverses and stores them in an internal cache. + Assuming that FLINT has been built with support for thread-local storage, + each thread has its own cache. + +const mp_limb_t * n_primes_arr_readonly(ulong num_primes) + + Returns a pointer to a read-only array of the first \code{num_primes} + prime numbers. The computed primes are cached for repeated calls. + The pointer is valid until the user calls \code{n_cleanup_primes} + in the same thread. + +const double * n_prime_inverses_arr_readonly(ulong n) + + Returns a pointer to a read-only array of inverses of the first + \code{num_primes} prime numbers. The computed primes are cached for + repeated calls. The pointer is valid until the user calls + \code{n_cleanup_primes} in the same thread. + +void n_cleanup_primes() + + Frees the internal cache of prime numbers used by the current thread. + This will invalidate any pointers returned by + \code{n_primes_arr_readonly} or \code{n_prime_inverses_arr_readonly}. + +mp_limb_t n_nextprime(mp_limb_t n, int proved) + + Returns the next prime after $n$. Assumes the result will fit in an + \code{mp_limb_t}. If proved is $0$, i.e.\ false, the prime is not + proven prime, otherwise it is. + +ulong n_prime_pi(mp_limb_t n) + + Returns the value of the prime counting function $\pi(n)$, i.e.\ the + number of primes less than or equal to $n$. The invariant + \code{n_prime_pi(n_nth_prime(n)) == n}. + + Currently, this function simply extends the table of cached primes up to + an upper limit and then performs a binary search. + +void n_prime_pi_bounds(ulong *lo, ulong *hi, mp_limb_t n) + + Calculates lower and upper bounds for the value of the prime counting + function \code{lo <= pi(n) <= hi}. If \code{lo} and \code{hi} point to + the same location, the high value will be stored. + + The upper approximation is $1.25506 n / \ln n$, and the + lower is $n / \ln n$. These bounds are due to Rosser and + Schoenfeld~\citep{RosSch1962} and valid for $n \geq 17$. + + We use the number of bits in $n$ (or one less) to form an + approximation to $\ln n$, taking care to use a value too + small or too large to maintain the inequality. + +mp_limb_t n_nth_prime(ulong n) + + Returns the $n$th prime number $p_n$, using the mathematical indexing + convention $p_1 = 2, p_2 = 3, \dotsc$. + + This function simply ensures that the table of cached primes is large + enough and then looks up the entry. + +void n_nth_prime_bounds(mp_limb_t *lo, mp_limb_t *hi, ulong n) + + Calculates lower and upper bounds for the $n$th prime number $p_n$, + \code{lo <= p_n <= hi}. If \code{lo} and \code{hi} point to the same + location, the high value will be stored. Note that this function will + overflow for sufficiently large $n$. + + We use the following estimates, valid for $n > 5$: + \begin{align*} + p_n & > n (\ln n + \ln \ln n - 1) \\ + p_n & < n (\ln n + \ln \ln n) \\ + p_n & < n (\ln n + \ln \ln n - 0.9427) \quad (n \geq 15985) + \end{align*} + + The first inequality was proved by Dusart~\citep{Dus1999}, and the last + is due to Massias and Robin~\citep{MasRob1996}. For a further overview, + see \url{http://primes.utm.edu/howmany.shtml}. + + We bound $\ln n$ using the number of bits in $n$ as in + \code{n_prime_pi_bounds()}, and estimate $\ln \ln n$ to the nearest + integer; this function is nearly constant. + + % P. Dusart, "The kth prime is greater than k(ln k+ln ln k-1) for k> 2," + % Math. Comp., 68:225 (January 1999) 411--415. + + % J. Massias and G. Robin, "Bornes effectives pour certaines fonctions + % concernant les nombres premiers," J. Theorie Nombres Bordeaux, 8 + % (1996) 215-242. + +******************************************************************************* + + Primality testing + +******************************************************************************* + +int n_is_oddprime_small(mp_limb_t n) + + Returns $1$ if $n$ is an odd prime smaller than + \code{FLINT_ODDPRIME_SMALL_CUTOFF}. Expects $n$ + to be odd and smaller than the cutoff. + + This function merely uses a lookup table with one bit allocated for each + odd number up to the cutoff. + +int n_is_oddprime_binary(mp_limb_t n) + + This function performs a simple binary search through + the table of cached primes for $n$. If it exists in the array it returns + $1$, otherwise $0$. For the algorithm to operate correctly + $n$ should be odd and at least $17$. + + Lower and upper bounds are computed with \code{n_prime_pi_bounds()}. + Once we have bounds on where to look in the table, we + refine our search with a simple binary algorithm, taking + the top or bottom of the current interval as necessary. + +int n_is_prime_pocklington(mp_limb_t n, ulong iterations) + + Tests if $n$ is a prime using the Pocklington--Lehmer primality + test. If $1$ is returned $n$ has been proved prime. If $0$ is returned + $n$ is composite. However $-1$ may be returned if nothing was proved + either way due to the number of iterations being too small. + + The most time consuming part of the algorithm is factoring + $n - 1$. For this reason \code{n_factor_partial()} is used, + which uses a combination of trial factoring and Hart's one + line factor algorithm~\citep{Har2009} to try to quickly factor $n - 1$. + Additionally if the cofactor is less than the square root of + $n - 1$ the algorithm can still proceed. + + One can also specify a number of iterations if less time + should be taken. Simply set this to \code{~WORD(0)} if this is irrelevant. + In most cases a greater number of iterations will not + significantly affect timings as most of the time is spent + factoring. + + See + \url{http://mathworld.wolfram.com/PocklingtonsTheorem.html} + for a description of the algorithm. + +int n_is_prime_pseudosquare(mp_limb_t n) + + Tests if $n$ is a prime according to~\citep[Theorem~2.7]{LukPatWil1996}. + + % "Some results on pseudosquares" by Lukes, Patterson and Williams, + % Math. Comp. vol 65, No. 213. pp 361-372. See + % http://www.ams.org/mcom/1996-65-213/S0025-5718-96-00678-3/ + % S0025-5718-96-00678-3.pdf + + We first factor $N$ using trial division up to some limit $B$. + In fact, the number of primes used in the trial factoring is at + most \code{FLINT_PSEUDOSQUARES_CUTOFF}. + + Next we compute $N/B$ and find the next pseudosquare $L_p$ above + this value, using a static table as per + \url{http://research.att.com/~njas/sequences/b002189.txt}. + + As noted in the text, if $p$ is prime then Step~3 will pass. This + test rejects many composites, and so by this time we suspect + that $p$ is prime. If $N$ is $3$ or $7$ modulo $8$, we are done, + and $N$ is prime. + + We now run a probable prime test, for which no known + counterexamples are known, to reject any composites. We then + proceed to prove $N$ prime by executing Step~4. In the case that + $N$ is $1$ modulo $8$, if Step~4 fails, we extend the number of primes + $p_i$ at Step~3 and hope to find one which passes Step~4. We take + the test one past the largest $p$ for which we have pseudosquares + $L_p$ tabulated, as this already corresponds to the next $L_p$ which + is bigger than $2^{64}$ and hence larger than any prime we might be + testing. + + As explained in the text, Condition~4 cannot fail if $N$ is prime. + + The possibility exists that the probable prime test declares a + composite prime. However in that case an error is printed, as + that would be of independent interest. + +int n_is_prime(mp_limb_t n) + + Tests if $n$ is a prime. Up to $10^{16}$ this simply calls + \code{n_is_probabprime()} which is a primality test up to that limit. + Beyond that point it calls \code{n_is_probabprime()} and returns $0$ + if $n$ is composite, then it calls \code{n_is_prime_pocklington()} + which proves the primality of $n$ in most cases. As a fallback, + \code{n_is_prime_pseudosquare()} is called, which will unconditionally + prove the primality of $n$. + +int n_is_strong_probabprime_precomp(mp_limb_t n, double npre, + mp_limb_t a, mp_limb_t d) + + Tests if $n$ is a strong probable prime to the base $a$. We + require that $d$ is set to the largest odd factor of $n - 1$ and + \code{npre} is a precomputed inverse of $n$ computed with + \code{n_precompute_inverse()}. We also require that $n < 2^{53}$, + $a$ to be reduced modulo $n$ and not $0$ and $n$ to be odd. + + If we write $n - 1 = 2^s d$ where $d$ is odd then $n$ is a strong + probable prime to the base $a$, i.e.\ an $a$-SPRP, if either + $a^d = 1 \pmod n$ or $(a^d)^{2^r} = -1 \pmod n$ for some~$r$ less + than~$s$. + + A description of strong probable primes is given here: + \url{http://mathworld.wolfram.com/StrongPseudoprime.html} + +int n_is_strong_probabprime2_preinv(mp_limb_t n, mp_limb_t ninv, + mp_limb_t a, mp_limb_t d) + + Tests if $n$ is a strong probable prime to the base $a$. We require + that $d$ is set to the largest odd factor of $n - 1$ and \code{npre} + is a precomputed inverse of $n$ computed with \code{n_preinvert_limb()}. + We require a to be reduced modulo $n$ and not $0$ and $n$ to be odd. + + If we write $n - 1 = 2^s d$ where $d$ is odd then $n$ is a strong + probable prime to the base $a$ (an $a$-SPRP) if either $a^d = 1 \pmod n$ + or $(a^d)^{2^r} = -1 \pmod n$ for some $r$ less than $s$. + + A description of strong probable primes is given here: + \url{http://mathworld.wolfram.com/StrongPseudoprime.html} + +int n_is_probabprime_fermat(mp_limb_t n, mp_limb_t i) + + Returns $1$ if $n$ is a base $i$ Fermat probable prime. Requires + $1 < i < n$ and that $i$ does not divide $n$. + + By Fermat's Little Theorem if $i^{n-1}$ is not congruent to $1$ + then $n$ is not prime. + +int n_is_probabprime_fibonacci(mp_limb_t n) + + Let $F_j$ be the $j$th element of the Fibonacci sequence + $0, 1, 1, 2, 3, 5, \dotsc$, starting at $j = 0$. Then if $n$ is prime + we have $F_{n - (n/5)} = 0 \pmod n$, where $(n/5)$ is the Jacobi + symbol. + + For further details, see~\citep[pp.~142]{CraPom2005}. + + We require that $n$ is not divisible by $2$ or $5$. + +int n_is_probabprime_BPSW(mp_limb_t n) + + Implements the Baillie--Pomerance--Selfridge--Wagstaff probable primality + test. There are no known counterexamples to this being a primality test. + For further details, see~\citep{CraPom2005}. + +int n_is_probabprime_lucas(mp_limb_t n) + + For details on Lucas pseudoprimes, see~\citep[pp.~143]{CraPom2005}. + + We implement a variant of the Lucas pseudoprime test as + described by Baillie and Wagstaff~\citep{BaiWag1980}. + +int n_is_probabprime(mp_limb_t n) + + Tests if $n$ is a probable prime. Up to \code{FLINT_ODDPRIME_SMALL_CUTOFF} + this algorithm uses \code{n_is_oddprime_small()} which uses a lookup table. + Next it calls \code{n_compute_primes()} with the maximum table size and + uses this table to perform a binary search for $n$ up to the table limit. + Then up to $10^{16}$ it uses a number of strong probable prime tests, + \code{n_is_strong_probabprime_precomp()}, etc., for various bases. The + output of the algorithm is guaranteed to be correct up to this bound due + to exhaustive tables, described at + \url{http://uucode.com/obf/dalbec/alg.html}. + + Beyond that point the BPSW probabilistic primality test is used, by + calling the function \code{n_is_probabprime_BPSW()}. There are no known + counterexamples, but it may well declare some composites to be prime. + +******************************************************************************* + + Square root and perfect power testing + +******************************************************************************* + +mp_limb_t n_sqrt(mp_limb_t a) + + Computes the integer truncation of the square root of $a$. The integer + itself can be represented exactly as a double and its square root is + computed to the nearest place. If $a$ is one below a square, the + rounding may be up, whereas if it is one above a square, the rounding + will be down. Thus the square root may be one too large in some + instances. We also have to be careful when the square of this too large + value causes an overflow. The same assumptions hold for a single + precision float provided the square root itself can be represented + in a single float, i.e.\ for $a < 281474976710656 = 2^{46}$. + +mp_limb_t n_sqrtrem(mp_limb_t * r, mp_limb_t a) + + Computes the integer truncation of the square root of $a$. The integer + itself can be represented exactly as a double and its square root is + computed to the nearest place. If $a$ is one below a square, the + rounding may be up, whereas if it is one above a square, the rounding + will be down. Thus the square root may be one too large in some + instances. We also have to be careful when the square of this too + large value causes an overflow. The same assumptions hold for a + single precision float provided the square root itself can be + represented in a single float, i.e. for \ + $a < 281474976710656 = 2^{46}$. The remainder is computed by + subtracting the square of the computed square root from $a$. + +int n_is_square(mp_limb_t x) + + Returns $1$ if $x$ is a square, otherwise $0$. + + This code first checks if $x$ is a square modulo $64$, + $63 = 3 \times 3 \times 7$ and $65 = 5 \times 13$, using lookup tables, + and if so it then takes a square root and checks that the square of this + equals the original value. + +int n_is_perfect_power235(mp_limb_t n) + + Returns $1$ if $n$ is a perfect square, cube or fifth power. + + This function uses a series of modular tests to reject most + non $235$-powers. Each modular test returns a value from $0$ to $7$ + whose bits respectively indicate whether the value is a square, + cube or fifth power modulo the given modulus. When these are + logically \code{AND}ed together, this gives a powerful test which will + reject most non-$235$ powers. + + If a bit remains set indicating it may be a square, a standard + square root test is performed. Similarly a cube root or fifth + root can be taken, if indicated, to determine whether the power + of that root is exactly equal to $n$. + +******************************************************************************* + + Factorisation + +******************************************************************************* + +int n_remove(mp_limb_t * n, mp_limb_t p) + + Removes the highest possible power of $p$ from $n$, replacing + $n$ with the quotient. The return value is that highest + power of $p$ that divided $n$. Assumes $n$ is not $0$. + + For $p = 2$ trailing zeroes are counted. For other primes + $p$ is repeatedly squared and stored in a table of powers + with the current highest power of $p$ removed at each step + until no higher power can be removed. The algorithm then + proceeds down the power tree again removing powers of $p$ + until none remain. + +int n_remove2_precomp(mp_limb_t * n, mp_limb_t p, double ppre) + + Removes the highest possible power of $p$ from $n$, replacing + $n$ with the quotient. The return value is that highest + power of $p$ that divided $n$. Assumes $n$ is not $0$. We require + \code{ppre} to be set to a precomputed inverse of $p$ computed + with \code{n_precompute_inverse()}. + + For $p = 2$ trailing zeroes are counted. For other primes + $p$ we make repeated use of \code{n_divrem2_precomp()} until division + by $p$ is no longer possible. + +void n_factor_insert(n_factor_t * factors, mp_limb_t p, ulong exp) + + Inserts the given prime power factor \code{p^exp} into + the \code{n_factor_t} \code{factors}. See the documentation for + \code{n_factor_trial()} for a description of the \code{n_factor_t} type. + + The algorithm performs a simple search to see if $p$ already + exists as a prime factor in the structure. If so the exponent + there is increased by the supplied exponent. Otherwise a new + factor \code{p^exp} is added to the end of the structure. + + There is no test code for this function other than its use by + the various factoring functions, which have test code. + +mp_limb_t n_factor_trial_range(n_factor_t * factors, + mp_limb_t n, ulong start, ulong num_primes) + + Trial factor $n$ with the first \code{num_primes} primes, but + starting at the prime with index start (counting from zero). + + One requires an initialised \code{n_factor_t} structure, but factors + will be added by default to an already used \code{n_factor_t}. Use + the function \code{n_factor_init()} defined in \code{ulong_extras} if + initialisation has not already been completed on factors. + + Once completed, \code{num} will contain the number of distinct + prime factors found. The field $p$ is an array of \code{mp_limb_t}'s + containing the distinct prime factors, \code{exp} an array + containing the corresponding exponents. + + The return value is the unfactored cofactor after trial + factoring is done. + + The function calls \code{n_compute_primes()} automatically. See + the documentation for that function regarding limits. + + The algorithm stops when the current prime has a square + exceeding $n$, as no prime factor of $n$ can exceed this + unless $n$ is prime. + + The precomputed inverses of all the primes computed by + \code{n_compute_primes()} are utilised with the \code{n_remove2_precomp()} + function. + +mp_limb_t n_factor_trial(n_factor_t * factors, mp_limb_t n, ulong num_primes) + + This function calls \code{n_factor_trial_range()}, with the value of + $0$ for \code{start}. By default this adds factors to an already existing + \code{n_factor_t} or to a newly initialised one. + +mp_limb_t n_factor_power235(ulong *exp, mp_limb_t n) + + Returns $0$ if $n$ is not a perfect square, cube or fifth power. + Otherwise it returns the root and sets \code{exp} to either $2$, + $3$ or $5$ appropriately. + + This function uses a series of modular tests to reject most + non $235$-powers. Each modular test returns a value from $0$ to $7$ + whose bits respectively indicate whether the value is a square, + cube or fifth power modulo the given modulus. When these are + logically \code{AND}ed together, this gives a powerful test which will + reject most non-$235$ powers. + + If a bit remains set indicating it may be a square, a standard + square root test is performed. Similarly a cube root or fifth + root can be taken, if indicated, to determine whether the power + of that root is exactly equal to $n$. + +mp_limb_t n_factor_one_line(mp_limb_t n, ulong iters) + + This implements Bill Hart's one line factoring algorithm~\citep{Har2009}. + It is a variant of Fermat's algorithm which cycles through a large number + of multipliers instead of incrementing the square root. It is faster than + SQUFOF for $n$ less than about $2^{40}$. + +mp_limb_t n_factor_lehman(mp_limb_t n) + + Lehman's factoring algorithm. Currently works up to $10^{16}$, but is + not particularly efficient and so is not used in the general factor + function. Always returns a factor of $n$. + +mp_limb_t n_factor_SQUFOF(mp_limb_t n, ulong iters) + + Attempts to split $n$ using the given number of iterations + of SQUFOF. Simply set \code{iters} to \code{~WORD(0)} for maximum + persistence. + + The version of SQUFOF imlemented here is as described by Gower + and Wagstaff~\citep{GowWag2008}. + + % Jason Gower and Sam Wagstaff + % "Square form factoring" + % Math. Comp. 77, 2008, pp 551-588, see: + % http://www.ams.org/mcom/2008-77-261/S0025-5718-07-02010-8/home.html + + We start by trying SQUFOF directly on $n$. If that fails we + multiply it by each of the primes in \code{flint_primes_small} in + turn. As this multiplication may result in a two limb value + we allow this in our implementation of SQUFOF. As SQUFOF + works with values about half the size of $n$ it only needs + single limb arithmetic internally. + + If SQUFOF fails to factor $n$ we return $0$, however with + \code{iters} large enough this should never happen. + +void n_factor(n_factor_t * factors, mp_limb_t n, int proved) + + Factors $n$ with no restrictions on $n$. If the prime factors are + required to be certified prime, one may set \code{proved} to $1$, + otherwise set it to $0$, and they will only be probable primes + (with no known counterexamples to the conjecture that they are + in fact all prime). + + For details on the \code{n_factor_t} structure, see + \code{n_factor_trial()}. + + This function first tries trial factoring with a number of primes + specified by the constant \code{FLINT_FACTOR_TRIAL_PRIMES}. If the + cofactor is $1$ or prime the function returns with all the factors. + + Otherwise, the cofactor is placed in the array \code{factor_arr}. Whilst + there are factors remaining in there which have not been split, the + algorithm continues. At each step each factor is first checked to + determine if it is a perfect power. If so it is replaced by the power + that has been found. Next if the factor is small enough and composite, + in particular, less than \code{FLINT_FACTOR_ONE_LINE_MAX} then + \code{n_factor_one_line()} is called with + \code{FLINT_FACTOR_ONE_LINE_ITERS} to try and split the factor. If + that fails or the factor is too large for \code{n_factor_one_line()} + then \code{n_factor_SQUFOF()} is called, with + \code{FLINT_FACTOR_SQUFOF_ITERS}. If that fails an error results and + the program aborts. However this should not happen in practice. + +mp_limb_t n_factor_trial_partial(n_factor_t * factors, mp_limb_t n, + mp_limb_t * prod, ulong num_primes, mp_limb_t limit) + + Attempts trial factoring of $n$ with the first \code{num_primes primes}, + but stops when the product of prime factors so far exceeds \code{limit}. + + One requires an initialised \code{n_factor_t} structure, but factors + will be added by default to an already used \code{n_factor_t}. Use + the function \code{n_factor_init()} defined in \code{ulong_extras} if + initialisation has not already been completed on \code{factors}. + + Once completed, \code{num} will contain the number of distinct + prime factors found. The field $p$ is an array of \code{mp_limb_t}'s + containing the distinct prime factors, \code{exp} an array + containing the corresponding exponents. + + The return value is the unfactored cofactor after trial + factoring is done. The value \code{prod} will be set to the product + of the factors found. + + The function calls \code{n_compute_primes()} automatically. See + the documentation for that function regarding limits. + + The algorithm stops when the current prime has a square + exceeding $n$, as no prime factor of $n$ can exceed this + unless $n$ is prime. + + The precomputed inverses of all the primes computed by + \code{n_compute_primes()} are utilised with the \code{n_remove2_precomp()} + function. + +mp_limb_t n_factor_partial(n_factor_t * factors, + mp_limb_t n, mp_limb_t limit, int proved) + + Factors $n$, but stops when the product of prime factors so far + exceeds \code{limit}. + + One requires an initialised \code{n_factor_t} structure, but factors + will be added by default to an already used \code{n_factor_t}. Use + the function \code{n_factor_init()} defined in \code{ulong_extras} if + initialisation has not already been completed on \code{factors}. + + On exit, \code{num} will contain the number of distinct prime factors + found. The field $p$ is an array of \code{mp_limb_t}'s containing the + distinct prime factors, \code{exp} an array containing the corresponding + exponents. + + The return value is the unfactored cofactor after factoring is done. + + The factors are proved prime if \code{proved} is $1$, otherwise + they are merely probably prime. + +mp_limb_t n_factor_pp1(mp_limb_t n, ulong B1, ulong c) + + Factors $n$ using Williams' $p + 1$ factoring algorithm, with prime + limit set to $B1$. We require $c$ to be set to a random value. Each + trial of the algorithm with a different value of $c$ gives another + chance to factor $n$, with roughly exponentially decreasing chance + of finding a missing factor. If $p + 1$ (or $p - 1$) is not smooth + for any factor $p$ of $n$, the algorithm will never succeed. The + value $c$ should be less than $n$ and greater than $2$. + + If the algorithm succeeds, it returns the factor, otherwise it + returns $0$ or $1$ (the trivial factors modulo $n$). + +******************************************************************************* + + Arithmetic functions + +******************************************************************************* + +int n_moebius_mu(mp_limb_t n) + + Computes the Moebius function $\mu(n)$, which is defined as $\mu(n) = 0$ + if $n$ has a prime factor of multiplicity greater than $1$, $\mu(n) = -1$ + if $n$ has an odd number of distinct prime factors, and $\mu(n) = 1$ if + $n$ has an even number of distinct prime factors. By convention, + $\mu(0) = 0$. + + For even numbers, we use the identities $\mu(4n) = 0$ and + $\mu(2n) = - \mu(n)$. Odd numbers up to a cutoff are then looked up from + a precomputed table storing $\mu(n) + 1$ in groups of two bits. + + For larger $n$, we first check if $n$ is divisible by a small odd square + and otherwise call \code{n_factor()} and count the factors. + +void n_moebius_mu_vec(int * mu, ulong len) + + Computes $\mu(n)$ for \code{n = 0, 1, ..., len - 1}. This + is done by sieving over each prime in the range, flipping the sign + of $\mu(n)$ for every multiple of a prime $p$ and setting $\mu(n) = 0$ + for every multiple of $p^2$. + +int n_is_squarefree(mp_limb_t n) + + Returns $0$ if $n$ is divisible by some perfect square, and $1$ otherwise. + This simply amounts to testing whether $\mu(n) \neq 0$. As special + cases, $1$ is considered squarefree and $0$ is not considered squarefree. + +mp_limb_t n_euler_phi(mp_limb_t n) + + Computes the Euler totient function $\phi(n)$, counting the number of + positive integers less than or equal to $n$ that are coprime to $n$. + +******************************************************************************* + + Factorials + +******************************************************************************* + +mp_limb_t n_factorial_fast_mod2_preinv(ulong n, mp_limb_t p, mp_limb_t pinv) + + Returns $n! \bmod p$ given a precomputed inverse of $p$ as computed + by \code{n_preinvert_limb()}. $p$ is not required to be a prime, but + no special optimisations are made for composite $p$. + Uses fast multipoint evaluation, running in about $O(n^{1/2})$ time. + +mp_limb_t n_factorial_mod2_preinv(ulong n, mp_limb_t p, mp_limb_t pinv) + + Returns $n! \bmod p$ given a precomputed inverse of $p$ as computed + by \code{n_preinvert_limb()}. $p$ is not required to be a prime, but + no special optimisations are made for composite $p$. + + Uses a lookup table for small $n$, otherwise computes the product + if $n$ is not too large, and calls the fast algorithm for extremely + large $n$. + +******************************************************************************* + + Primitive Roots and Discrete Logarithms + +******************************************************************************* + +mp_limb_t n_primitive_root_prime_prefactor(mp_limb_t p, n_factor_t * factors) + + Returns a primitive root for the multiplicative subgroup of $Z/pZ$ + where $p$ is prime given the factorisation ($factors$) of $p - 1$. + + +mp_limb_t n_primitive_root_prime(mp_limb_t p) + + Returns a primitive root for the multiplicative subgroup of $Z/pZ$ + where $p$ is prime. + +mp_limb_t n_discrete_log_bsgs(mp_limb_t b, mp_limb_t a, mp_limb_t n) + + Returns the discrete logarithm of $b$ with respect to $a$ in the + multiplicative subgroup of $Z/nZ$ when $Z/nZ$ is cyclic That is, + it returns an number $x$ such that $a^x = b \bmod n$. The + multiplicative subgroup is only cyclic when $n$ is $2$, $4$, + $p^k$, or $2p^k$ where $p$ is an odd prime and $k$ is a positive + integer. diff --git a/external/flint-2.4.3/ulong_extras/euler_phi.c b/external/flint-2.4.3/ulong_extras/euler_phi.c new file mode 100644 index 0000000..ad3eaa3 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/euler_phi.c @@ -0,0 +1,46 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include "flint.h" +#include "ulong_extras.h" + +mp_limb_t n_euler_phi(mp_limb_t n) +{ + int i; + mp_limb_t phi; + n_factor_t fac; + + if (n < 2) + return n; + + n_factor_init(&fac); + n_factor(&fac, n, 1); + + phi = UWORD(1); + for (i = 0; i < fac.num; i++) + phi *= (fac.p[i]-1) * n_pow(fac.p[i], fac.exp[i]-1); + + return phi; +} diff --git a/external/flint-2.4.3/ulong_extras/factor.c b/external/flint-2.4.3/ulong_extras/factor.c new file mode 100644 index 0000000..a7d982d --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/factor.c @@ -0,0 +1,103 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#define ulong ulongxx /* interferes with system includes */ +#include +#include +#undef ulong +#define ulong mp_limb_t +#include +#include "flint.h" +#include "ulong_extras.h" + +static int is_prime(mp_limb_t n, int proved) +{ + return proved ? n_is_prime(n) : n_is_probabprime(n); +} + +void n_factor(n_factor_t * factors, mp_limb_t n, int proved) +{ + ulong factor_arr[FLINT_MAX_FACTORS_IN_LIMB]; + ulong exp_arr[FLINT_MAX_FACTORS_IN_LIMB]; + ulong factors_left; + ulong exp; + mp_limb_t cofactor, factor, cutoff; + + cofactor = n_factor_trial(factors, n, FLINT_FACTOR_TRIAL_PRIMES); + if (cofactor == UWORD(1)) return; + if (is_prime(cofactor, proved)) + { + n_factor_insert(factors, cofactor, UWORD(1)); + return; + } + + factor_arr[0] = cofactor; + factors_left = 1; + exp_arr[0] = 1; + + cutoff = FLINT_FACTOR_TRIAL_CUTOFF; + + while (factors_left > 0) + { + factor = factor_arr[factors_left - 1]; + + if (factor >= cutoff) + { + if ((cofactor = n_factor_power235(&exp, factor))) + { + exp_arr[factors_left - 1] *= exp; + factor_arr[factors_left - 1] = factor = cofactor; + } + + if ((factor >= cutoff) && !is_prime(factor, proved)) + { + if (( +#if FLINT64 + (factor < FLINT_FACTOR_ONE_LINE_MAX) && +#endif + (cofactor = n_factor_one_line(factor, FLINT_FACTOR_ONE_LINE_ITERS))) + || (cofactor = n_factor_SQUFOF(factor, FLINT_FACTOR_SQUFOF_ITERS))) + { + exp_arr[factors_left] = exp_arr[factors_left - 1]; + factor_arr[factors_left] = cofactor; + factor_arr[factors_left - 1] /= cofactor; + factors_left++; + } else + { + flint_printf("Exception (n_factor). Failed to factor %wd.\n", n); + abort(); + } + } else + { + n_factor_insert(factors, factor, exp_arr[factors_left - 1]); + factors_left--; + } + } else + { + n_factor_insert(factors, factor, exp_arr[factors_left - 1]); + factors_left--; + } + } +} diff --git a/external/flint-2.4.3/ulong_extras/factor_SQUFOF.c b/external/flint-2.4.3/ulong_extras/factor_SQUFOF.c new file mode 100644 index 0000000..616b479 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/factor_SQUFOF.c @@ -0,0 +1,159 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" + +mp_limb_t _ll_factor_SQUFOF(mp_limb_t n_hi, mp_limb_t n_lo, ulong max_iters) +{ + mp_limb_t n[2]; + mp_limb_t sqrt[2]; + mp_limb_t rem[2]; + slong num, sqroot, p, q; + + mp_limb_t l, l2, iq, pnext; + mp_limb_t qarr[50]; + mp_limb_t qupto, qlast, t, r = 0; + ulong i, j; + + n[0] = n_lo; + n[1] = n_hi; + + if (n_hi) num = mpn_sqrtrem(sqrt, rem, n, 2); + else num = ((sqrt[0] = n_sqrtrem(rem, n_lo)) != UWORD(0)); + + sqroot = sqrt[0]; + p = sqroot; + q = rem[0]; + + if ((q == 0) || (num == 0)) + { + return sqroot; + } + + l = 1 + 2*n_sqrt(2*p); + l2 = l/2; + qupto = 0; + qlast = 1; + + for (i = 0; i < max_iters; i++) + { + iq = (sqroot + p)/q; + pnext = iq*q - p; + if (q <= l) + { + if ((q & UWORD(1)) == UWORD(0)) + { + qarr[qupto] = q/2; + qupto++; + if (qupto >= UWORD(50)) return UWORD(0); + } else if (q <= l2) + { + qarr[qupto] = q; + qupto++; + if (qupto >= UWORD(50)) return UWORD(0); + } + } + + t = qlast + iq*(p - pnext); + qlast = q; + q = t; + p = pnext; + if ((i & 1) == 1) continue; + if (!n_is_square(q)) continue; + r = n_sqrt(q); + if (qupto == UWORD(0)) break; + for (j = 0; j < qupto; j++) + if (r == qarr[j]) goto cont; + break; + cont: ; + if (r == UWORD(1)) return UWORD(0); + } + + if (i == max_iters) return UWORD(0); /* taken too much time, give up */ + + qlast = r; + p = p + r*((sqroot - p)/r); + + umul_ppmm(rem[1], rem[0], p, p); + sub_ddmmss(sqrt[1], sqrt[0], n[1], n[0], rem[1], rem[0]); + if (sqrt[1]) + { + int norm; + count_leading_zeros(norm, qlast); + udiv_qrnnd(q, rem[0], (sqrt[1] << norm) + r_shift(sqrt[0], FLINT_BITS - norm), sqrt[0] << norm, qlast << norm); + rem[0] >>= norm; + } + else + { + q = sqrt[0]/qlast; + } + + for (j = 0; j < max_iters; j++) + { + iq = (sqroot + p)/q; + pnext = iq*q - p; + if (p == pnext) break; + t = qlast + iq*(p - pnext); + qlast = q; + q = t; + p = pnext; + } + + if (j == max_iters) return UWORD(0); /* taken too much time, give up */ + + if ((q & UWORD(1)) == UWORD(0)) q /= UWORD(2); + + return q; +} + +mp_limb_t n_factor_SQUFOF(mp_limb_t n, ulong iters) +{ + mp_limb_t factor = _ll_factor_SQUFOF(UWORD(0), n, iters); + mp_limb_t multiplier; + mp_limb_t quot, rem; + ulong i; + + for (i = 1; (i < FLINT_NUM_PRIMES_SMALL) && !factor; i++) + { + mp_limb_t multn[2]; + multiplier = flint_primes_small[i]; + umul_ppmm(multn[1], multn[0], multiplier, n); + factor = _ll_factor_SQUFOF(multn[1], multn[0], iters); + + if (factor) + { + quot = factor/multiplier; + rem = factor - quot*multiplier; + if (!rem) factor = quot; + if ((factor == UWORD(1)) || (factor == n)) factor = UWORD(0); + } + } + + if (i == FLINT_NUM_PRIMES_SMALL) return UWORD(0); + + return factor; +} diff --git a/external/flint-2.4.3/ulong_extras/factor_insert.c b/external/flint-2.4.3/ulong_extras/factor_insert.c new file mode 100644 index 0000000..9a83350 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/factor_insert.c @@ -0,0 +1,48 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" + +void n_factor_insert(n_factor_t * factors, mp_limb_t p, ulong exp) +{ + ulong i; + + for (i = 0; i < factors->num; i++) + { + if (factors->p[i] == p) break; + } + + if (i != factors->num) + { + factors->exp[i] += exp; + } else + { + factors->p[i] = p; + factors->exp[i] = exp; + factors->num++; + } +} diff --git a/external/flint-2.4.3/ulong_extras/factor_lehman.c b/external/flint-2.4.3/ulong_extras/factor_lehman.c new file mode 100644 index 0000000..dd52237 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/factor_lehman.c @@ -0,0 +1,79 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 William Hart + +******************************************************************************/ + +#define ulong ulongxx /* interferes with system includes */ +#include +#undef ulong +#include +#include "flint.h" +#include "ulong_extras.h" + +mp_limb_t n_factor_lehman(mp_limb_t n) +{ + double limit; + mp_limb_t cuberoot, k; + n_factor_t factors; + slong bound; + +#if FLINT64 /* cannot compute enough primes */ + if (n > UWORD(10000000000000000)) return n; +#endif + + if ((n & 1) == 0) return 2; + + limit = pow(n, 1.0/3.0); + cuberoot = (mp_limb_t) ceil(limit); + bound = n_prime_pi(cuberoot); + + n_factor_init(&factors); + if (n_factor_trial_range(&factors, n, 0, bound) != n) + return factors.p[0]; + + if ((factors.p[0] = n_factor_one_line(n, FLINT_FACTOR_ONE_LINE_ITERS))) + if (factors.p[0] != n) + return factors.p[0]; + + for (k = 1; k <= cuberoot + 1; k++) + { + double low = 2.0*sqrt((double) k)*sqrt((double) n); + mp_limb_t x = (mp_limb_t) ceil(low - 0.0001); + mp_limb_t end = (mp_limb_t) floor(0.0001 + low + pow(n, 1.0/6.0)/((double) 4.0*sqrt((double) k))); + mp_limb_t sub = k*n*4; + + for ( ; x <= end; x++) + { + mp_limb_t p, sq = x*x - sub; + if (n_is_square(sq)) + { + sq = sqrt((double) sq); + p = n_gcd(n, x - sq); + if (p != 1) + return p; + } + } + } + + return n; +} diff --git a/external/flint-2.4.3/ulong_extras/factor_one_line.c b/external/flint-2.4.3/ulong_extras/factor_one_line.c new file mode 100644 index 0000000..ffd2389 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/factor_one_line.c @@ -0,0 +1,62 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2009 Thomas Boothby + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" + +#define FLINT_ONE_LINE_MULTIPLIER 480 + +mp_limb_t n_factor_one_line(mp_limb_t n, ulong iters) +{ + mp_limb_t orig_n = n, in, square, sqrti, mod, factor, factoring = iters, iin; + n *= FLINT_ONE_LINE_MULTIPLIER; + + iin = 0; + in = n; + while (factoring && (iin < in)) + { + sqrti = n_sqrt(in); + sqrti++; + square = sqrti*sqrti; + mod = square - in; + if (n_is_square(mod)) + { + factor = n_sqrt(mod); + sqrti -= factor; + factor = n_gcd_full(orig_n, sqrti); + if (factor != UWORD(1)) + { + return factor; + } + } + factoring--; + iin = in; + in += n; + } + + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/factor_partial.c b/external/flint-2.4.3/ulong_extras/factor_partial.c new file mode 100644 index 0000000..f4c030e --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/factor_partial.c @@ -0,0 +1,107 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#define ulong ulongxx /* prevent clash with standard library */ +#include +#include +#undef ulong +#include +#include "flint.h" +#include "ulong_extras.h" + +int is_prime2(mp_limb_t n, int proved) +{ + if (proved) return n_is_prime(n); + else return n_is_probabprime(n); +} + +mp_limb_t n_factor_partial(n_factor_t * factors, mp_limb_t n, mp_limb_t limit, int proved) +{ + ulong factor_arr[FLINT_MAX_FACTORS_IN_LIMB]; + ulong exp_arr[FLINT_MAX_FACTORS_IN_LIMB]; + ulong factors_left; + ulong exp; + mp_limb_t cofactor, factor, cutoff, prod; + + cofactor = n_factor_trial_partial(factors, n, &prod, FLINT_FACTOR_TRIAL_PRIMES, limit); + if (prod > limit) return cofactor; + if (is_prime2(cofactor, proved)) + { + n_factor_insert(factors, cofactor, UWORD(1)); + return 1; + } + + factor_arr[0] = cofactor; + factors_left = 1; + exp_arr[0] = 1; + + cutoff = FLINT_FACTOR_TRIAL_CUTOFF; + + while (factors_left > 0 && prod <= limit) + { + factor = factor_arr[factors_left - 1]; + + if (factor >= cutoff) + { + if ((cofactor = n_factor_power235(&exp, factor))) + { + exp_arr[factors_left - 1] *= exp; + factor_arr[factors_left - 1] = factor = cofactor; + } + + if ((factor >= cutoff) && !is_prime2(factor, proved)) + { + if (( +#if FLINT64 + (factor < FLINT_FACTOR_ONE_LINE_MAX) && +#endif + (cofactor = n_factor_one_line(factor, FLINT_FACTOR_ONE_LINE_ITERS))) + || (cofactor = n_factor_SQUFOF(factor, FLINT_FACTOR_SQUFOF_ITERS))) + { + exp_arr[factors_left] = exp_arr[factors_left - 1]; + factor_arr[factors_left] = cofactor; + factor_arr[factors_left - 1] /= cofactor; + factors_left++; + } else + { + flint_printf("Error (n_factor_partial). Failed to factor %wd.\n", n); + abort(); + } + } else + { + n_factor_insert(factors, factor, exp_arr[factors_left - 1]); + prod *= n_pow(factor, exp_arr[factors_left - 1]); + factors_left--; + } + } else + { + n_factor_insert(factors, factor, exp_arr[factors_left - 1]); + prod *= n_pow(factor, exp_arr[factors_left - 1]); + factors_left--; + } + } + + return n/prod; +} diff --git a/external/flint-2.4.3/ulong_extras/factor_power235.c b/external/flint-2.4.3/ulong_extras/factor_power235.c new file mode 100644 index 0000000..c9e0897 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/factor_power235.c @@ -0,0 +1,93 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2009 Thomas Boothby + +******************************************************************************/ + +#define ulong ulongxx /* interferes with standard libraries */ +#include +#undef ulong +#include +#include "flint.h" +#include "ulong_extras.h" + +mp_limb_t n_factor_power235(ulong * exp, mp_limb_t n) +{ + static char mod63[63] = {7,7,4,0,5,4,0,5,6,5,4,4,0,4,4,0,5,4,5,4,4,0, + 5,4,0,5,4,6,7,4,0,4,4,0,4,6,7,5,4,0,4,4,0,5, + 4,4,5,4,0,5,4,0,4,4,4,6,4,0,5,4,0,4,6}; + static char mod61[61] = {7,7,0,3,1,1,0,0,2,3,0,6,1,5,5,1,1,0,0,1,3,4, + 1,2,2,1,0,3,2,4,0,0,4,2,3,0,1,2,2,1,4,3,1,0, + 0,1,1,5,5,1,6,0,3,2,0,0,1,1,3,0,7}; + static char mod44[44] = {7,7,0,2,3,3,0,2,2,3,0,6,7,2,0,2,3,2,0,2,3,6, + 0,6,2,3,0,2,2,2,0,2,6,7,0,2,3,3,0,2,2,2,0,6}; + static char mod31[31] = {7,7,3,0,3,5,4,1,3,1,1,0,0,0,1,2,3,0,1,1,1,0, + 0,2,0,5,4,2,1,2,6}; + char t; + + t = mod31[n%31]; + if (!t) return UWORD(0); + + t &= mod44[n%44]; + if (!t) return UWORD(0); + + t &= mod61[n%61]; + if (!t) return UWORD(0); + + t&= mod63[n%63]; + + if (t & 1) + { + double x = sqrt((double) n); + mp_limb_t y = (mp_limb_t) (x + 0.5); + if (n == n_pow(y, 2)) + { + *exp = 2; + return y; + } + } + + if (t & 2) + { + double x = pow((double) n, 1.0 / 3.0); + mp_limb_t y = (mp_limb_t) (x + 0.5); + if (n == n_pow(y, 3)) + { + *exp = 3; + return y; + } + } + + if (t & 4) + { + double x = pow((double) n, 1.0 / 5.0); + mp_limb_t y = (mp_limb_t) (x + 0.5); + if (n == n_pow(y, 5)) + { + *exp = 5; + return y; + } + } + + return UWORD(0); +} diff --git a/external/flint-2.4.3/ulong_extras/factor_pp1.c b/external/flint-2.4.3/ulong_extras/factor_pp1.c new file mode 100644 index 0000000..e372b3b --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/factor_pp1.c @@ -0,0 +1,209 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 William Hart + +******************************************************************************/ + +#define ulong ulongxx /* prevent clash with stdlib */ +#include +#undef ulong +#include +#include "flint.h" +#include "ulong_extras.h" + +#define n_pp1_set(x1, y1, x2, y2) \ + do { \ + x1 = x2; \ + y1 = y2; \ + } while (0) + +#define n_pp1_set_ui(x, norm, c) \ + do { \ + x = (c << norm); \ + } while (0) + +void n_pp1_print(mp_limb_t x, mp_limb_t y, ulong norm) +{ + if (norm) + { + x >>= norm; + y >>= norm; + } + + flint_printf("[%wu, %wu]", x, y); +} + +#define n_pp1_2k(x, y, n, ninv, x0, norm) \ + do { \ + const mp_limb_t two = (UWORD(2) << norm); \ + y = n_mulmod_preinv(y, x, n, ninv, norm); \ + y = n_submod(y, x0, n); \ + x = n_mulmod_preinv(x, x, n, ninv, norm); \ + x = n_submod(x, two, n); \ + } while (0) + +#define n_pp1_2kp1(x, y, n, ninv, x0, norm) \ + do { \ + const mp_limb_t two = (UWORD(2) << norm); \ + x = n_mulmod_preinv(x, y, n, ninv, norm); \ + x = n_submod(x, x0, n); \ + y = n_mulmod_preinv(y, y, n, ninv, norm); \ + y = n_submod(y, two, n); \ + } while (0) + +void n_pp1_pow_ui(mp_limb_t * x, mp_limb_t * y, ulong exp, + mp_limb_t n, mp_limb_t ninv, ulong norm) +{ + const mp_limb_t x0 = *x; + const mp_limb_t two = (UWORD(2) << norm); + ulong bit = ((UWORD(1) << FLINT_BIT_COUNT(exp)) >> 2); + + (*y) = n_mulmod_preinv(*x, *x, n, ninv, norm); + (*y) = n_submod(*y, two, n); + + while (bit) + { + if (exp & bit) + n_pp1_2kp1(*x, *y, n, ninv, x0, norm); + else + n_pp1_2k(*x, *y, n, ninv, x0, norm); + + bit >>= 1; + } +} + +mp_limb_t n_pp1_factor(mp_limb_t n, mp_limb_t x, ulong norm) +{ + if (norm) + { + n >>= norm; + x >>= norm; + } + + x = n_submod(x, 2, n); + if (x == 0) + return 0; + + return n_gcd(n, x); +} + +mp_limb_t n_pp1_find_power(mp_limb_t * x, mp_limb_t * y, + ulong p, mp_limb_t n, mp_limb_t ninv, ulong norm) +{ + mp_limb_t factor; + + do + { + n_pp1_pow_ui(x, y, p, n, ninv, norm); + factor = n_pp1_factor(n, *x, norm); + } while (factor == 1); + + return factor; +} + +mp_limb_t n_factor_pp1(mp_limb_t n, ulong B1, ulong c) +{ + slong i, j; + mp_limb_t factor = 0; + mp_limb_t x, y, oldx, oldy, ninv; + ulong pr, oldpr, sqrt, bits0, norm; + n_primes_t iter; + + if ((n % 2) == 0) + return 2; + + n_primes_init(iter); + + sqrt = n_sqrt(B1); + bits0 = FLINT_BIT_COUNT(B1); + + count_leading_zeros(norm, n); + n <<= norm; + + ninv = n_preinvert_limb(n); + + n_pp1_set_ui(x, norm, c); + + /* mul by various prime powers */ + pr = 0; + oldpr = 0; + + for (i = 0; pr < B1; ) + { + j = i + 1024; + oldpr = pr; + n_pp1_set(oldx, oldy, x, y); + + for ( ; i < j; i++) + { + pr = n_primes_next(iter); + if (pr < sqrt) + { + ulong bits = FLINT_BIT_COUNT(pr); + ulong exp = bits0 / bits; + n_pp1_pow_ui(&x, &y, n_pow(pr, exp), n, ninv, norm); + } else + n_pp1_pow_ui(&x, &y, pr, n, ninv, norm); + } + + factor = n_pp1_factor(n, x, norm); + if (factor == 0) + break; + if (factor != 1) + goto cleanup; + } + + if (pr < B1) /* factor = 0 */ + { + n_primes_jump_after(iter, oldpr); + n_pp1_set(x, y, oldx, oldy); + + do + { + pr = n_primes_next(iter); + n_pp1_set(oldx, oldy, x, y); + if (pr < sqrt) + { + ulong bits = FLINT_BIT_COUNT(pr); + ulong exp = bits0 / bits; + n_pp1_pow_ui(&x, &y, n_pow(pr, exp), n, ninv, norm); + } else + n_pp1_pow_ui(&x, &y, pr, n, ninv, norm); + + factor = n_pp1_factor(n, x, norm); + if (factor == 0) + break; + if (factor != 1) + goto cleanup; + } while (1); + } else + goto cleanup; + + /* factor still 0 */ + factor = n_pp1_find_power(&oldx, &oldy, pr, n, ninv, norm); + +cleanup: + + n_primes_clear(iter); + + return factor; +} diff --git a/external/flint-2.4.3/ulong_extras/factor_trial.c b/external/flint-2.4.3/ulong_extras/factor_trial.c new file mode 100644 index 0000000..907de27 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/factor_trial.c @@ -0,0 +1,33 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" + +mp_limb_t n_factor_trial(n_factor_t * factors, mp_limb_t n, ulong num_primes) +{ + return n_factor_trial_range(factors, n, UWORD(0), num_primes); +} diff --git a/external/flint-2.4.3/ulong_extras/factor_trial_partial.c b/external/flint-2.4.3/ulong_extras/factor_trial_partial.c new file mode 100644 index 0000000..970bedd --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/factor_trial_partial.c @@ -0,0 +1,58 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" + +mp_limb_t n_factor_trial_partial(n_factor_t * factors, mp_limb_t n, mp_limb_t * prod, ulong num_primes, mp_limb_t limit) +{ + unsigned int exp; + mp_limb_t p; + double ppre; + ulong i; + const mp_limb_t * primes; + const double * inverses; + + (*prod) = 1; + primes = n_primes_arr_readonly(num_primes); + inverses = n_prime_inverses_arr_readonly(num_primes); + + for (i = 0; i < num_primes; i++) + { + p = primes[i]; + if (p*p > n) break; + ppre = inverses[i]; + exp = n_remove2_precomp(&n, p, ppre); + if (exp) + { + n_factor_insert(factors, p, exp); + (*prod) *= n_pow(p, exp); + if (*prod > limit) break; + } + } + + return n; +} diff --git a/external/flint-2.4.3/ulong_extras/factor_trial_range.c b/external/flint-2.4.3/ulong_extras/factor_trial_range.c new file mode 100644 index 0000000..150bfa7 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/factor_trial_range.c @@ -0,0 +1,52 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" + +mp_limb_t n_factor_trial_range(n_factor_t * factors, mp_limb_t n, ulong start, ulong num_primes) +{ + unsigned int exp; + mp_limb_t p; + double ppre; + ulong i; + const mp_limb_t * primes; + const double * inverses; + + primes = n_primes_arr_readonly(num_primes); + inverses = n_prime_inverses_arr_readonly(num_primes); + + for (i = start; i < num_primes; i++) + { + p = primes[i]; + if (p*p > n) break; + ppre = inverses[i]; + exp = n_remove2_precomp(&n, p, ppre); + if (exp) n_factor_insert(factors, p, exp); + } + + return n; +} diff --git a/external/flint-2.4.3/ulong_extras/factorial_fast_mod2_preinv.c b/external/flint-2.4.3/ulong_extras/factorial_fast_mod2_preinv.c new file mode 100644 index 0000000..c1cb8cd --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/factorial_fast_mod2_preinv.c @@ -0,0 +1,78 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 +#include "flint.h" +#include "ulong_extras.h" +#include "nmod_vec.h" +#include "nmod_poly.h" + +mp_limb_t +n_factorial_fast_mod2_preinv(ulong n, mp_limb_t p, mp_limb_t pinv) +{ + slong i, m; + nmod_t mod; + mp_ptr t, u, v; + mp_limb_t r, s; + + if (p == UWORD(1) || n >= p) + return UWORD(0); + + if (n <= 1) + return UWORD(1); + + nmod_init(&mod, p); + + m = n_sqrt(n); + + t = _nmod_vec_init(m + 1); + u = _nmod_vec_init(m + 1); + v = _nmod_vec_init(m + 1); + + t[0] = UWORD(0); + for (i = 1; i < m; i++) + t[i] = n_submod(t[i-1], UWORD(1), p); + + _nmod_poly_product_roots_nmod_vec(u, t, m, mod); + + for (i = 0; i < m; i++) + t[i] = n_mod2_preinv(i * m + 1, p, pinv); + + _nmod_poly_evaluate_nmod_vec_fast(v, u, m + 1, t, m, mod); + + r = 1; + for (i = 0; i < m; i++) + r = n_mulmod2_preinv(r, v[i], mod.n, mod.ninv); + + for (s = m * m + 1; s <= n; s++) + r = n_mulmod2_preinv(r, s, mod.n, mod.ninv); + + _nmod_vec_clear(t); + _nmod_vec_clear(u); + _nmod_vec_clear(v); + + return r; +} + diff --git a/external/flint-2.4.3/ulong_extras/factorial_mod2_preinv.c b/external/flint-2.4.3/ulong_extras/factorial_mod2_preinv.c new file mode 100644 index 0000000..ca63be4 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/factorial_mod2_preinv.c @@ -0,0 +1,82 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" + + +static const mp_limb_t small_factorials[] = +{ + UWORD(1), UWORD(1), UWORD(2), UWORD(6), UWORD(24), UWORD(120), UWORD(720), UWORD(5040), UWORD(40320), UWORD(362880), + UWORD(3628800), UWORD(39916800), UWORD(479001600), +#if FLINT64 + UWORD(6227020800), UWORD(87178291200), + UWORD(1307674368000), UWORD(20922789888000), UWORD(355687428096000), UWORD(6402373705728000), + UWORD(121645100408832000), UWORD(2432902008176640000), +#endif +}; + +#if FLINT64 +#define MAX_SMALL_FACTORIAL 20 +#else +#define MAX_SMALL_FACTORIAL 12 +#endif + + +mp_limb_t n_factorial_mod2_preinv(ulong n, mp_limb_t p, mp_limb_t pinv) +{ + mp_limb_t prod, hi, lo; + + if (n <= MAX_SMALL_FACTORIAL) + return n_mod2_preinv(small_factorials[n], p, pinv); + + if (n >= p) + return UWORD(0); + + if (n >= UWORD(1000000)) + return n_factorial_fast_mod2_preinv(n, p, pinv); + + prod = small_factorials[MAX_SMALL_FACTORIAL]; + lo = n; + n--; + + /* TODO: speedup for n in the range of sqrt(UWORD_MAX) */ + while (n > MAX_SMALL_FACTORIAL) + { + umul_ppmm(hi, lo, lo, n); + + if (hi) + { + lo = n_ll_mod_preinv(hi, lo, p, pinv); + prod = n_mulmod2_preinv(prod, lo, p, pinv); + lo = UWORD(1); + } + + n--; + } + + return n_mulmod2_preinv(prod, lo, p, pinv); +} diff --git a/external/flint-2.4.3/ulong_extras/flog.c b/external/flint-2.4.3/ulong_extras/flog.c new file mode 100644 index 0000000..97795b7 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/flog.c @@ -0,0 +1,47 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" + +mp_limb_t n_flog(mp_limb_t n, mp_limb_t b) +{ + mp_limb_t r, p, phi; + + r = 0; + p = 1; + + while (1) + { + umul_ppmm(phi, p, p, b); + + if (p <= n && !phi) + r++; + else + return r; + } +} diff --git a/external/flint-2.4.3/ulong_extras/gcd.c b/external/flint-2.4.3/ulong_extras/gcd.c new file mode 100644 index 0000000..6592d19 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/gcd.c @@ -0,0 +1,75 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" + +mp_limb_t +n_gcd(mp_limb_t x, mp_limb_t y) +{ + mp_limb_t u3, v3; + mp_limb_t quot, rem; + + u3 = x; + v3 = y; + + if ((mp_limb_signed_t) (x & y) < WORD(0)) /* x and y both have top bit set */ + { + quot = u3 - v3; + u3 = v3; + v3 = quot; + } + + while ((mp_limb_signed_t) (v3 << 1) < WORD(0)) /* second value has second msb set */ + { + quot = u3 - v3; + u3 = v3; + if (quot < v3) v3 = quot; + else if (quot < (v3 << 1)) v3 = quot - u3; + else v3 = quot - (u3 << 1); + } + + while (v3) + { + if (u3 < (v3 << 2)) /* overflow not possible due to top 2 bits of v3 not being set */ + { + quot = u3 - v3; + u3 = v3; + if (quot < v3) v3 = quot; + else if (quot < (v3 << 1)) v3 = quot - u3; + else v3 = quot - (u3 << 1); + } + else + { + quot = u3 / v3; + rem = u3 - v3 * quot; + u3 = v3; + v3 = rem; + } + } + + return u3; +} diff --git a/external/flint-2.4.3/ulong_extras/gcdinv.c b/external/flint-2.4.3/ulong_extras/gcdinv.c new file mode 100644 index 0000000..0381be5 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/gcdinv.c @@ -0,0 +1,138 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" + +mp_limb_t +n_gcdinv(mp_limb_t * s, mp_limb_t x, mp_limb_t y) +{ + mp_limb_signed_t v1 = UWORD(0); + mp_limb_signed_t v2 = UWORD(1); + mp_limb_signed_t t2; + mp_limb_t u3, v3; + mp_limb_t quot, rem; + + u3 = y, v3 = x; + + if (v3 > u3) + { + rem = u3; + u3 = v3; + t2 = v2; + v2 = v1; + v1 = t2; + v3 = rem; + } + + if ((mp_limb_signed_t) (y & x) < WORD(0)) /* y and x both have top bit set */ + { + quot = u3 - v3; + t2 = v2; + u3 = v3; + v2 = v1 - v2; + v1 = t2; + v3 = quot; + } + + while ((mp_limb_signed_t) (v3 << 1) < WORD(0)) /* second value has second msb set */ + { + quot = u3 - v3; + if (quot < v3) + { + t2 = v2; + u3 = v3; + v2 = v1 - v2; + v1 = t2; + v3 = quot; + } + else if (quot < (v3 << 1)) + { + u3 = v3; + t2 = v2; + v2 = v1 - (v2 << 1); + v1 = t2; + v3 = quot - u3; + } + else + { + u3 = v3; + t2 = v2; + v2 = v1 - 3 * v2; + v1 = t2; + v3 = quot - (u3 << 1); + } + } + + while (v3) + { + if (u3 < (v3 << 2)) /* overflow not possible due to top 2 bits of v3 not being set */ + { + quot = u3 - v3; + if (quot < v3) + { + t2 = v2; + u3 = v3; + v2 = v1 - v2; + v1 = t2; + v3 = quot; + } + else if (quot < (v3 << 1)) + { + u3 = v3; + t2 = v2; + v2 = v1 - (v2 << 1); + v1 = t2; + v3 = quot - u3; + } + else + { + u3 = v3; + t2 = v2; + v2 = v1 - 3 * v2; + v1 = t2; + v3 = quot - (u3 << 1); + } + } + else + { + quot = u3 / v3; + rem = u3 - v3 * quot; + u3 = v3; + t2 = v2; + v2 = v1 - quot * v2; + v1 = t2; + v3 = rem; + } + } + + if (v1 < WORD(0)) + v1 += y; + + (*s) = v1; + + return u3; +} diff --git a/external/flint-2.4.3/ulong_extras/invmod.c b/external/flint-2.4.3/ulong_extras/invmod.c new file mode 100644 index 0000000..454bc42 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/invmod.c @@ -0,0 +1,136 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" + +mp_limb_t +n_invmod(mp_limb_t x, mp_limb_t y) +{ + mp_limb_signed_t v1 = UWORD(0); + mp_limb_signed_t v2 = UWORD(1); + mp_limb_signed_t t2; + mp_limb_t u3, v3; + mp_limb_t quot, rem; + + u3 = y, v3 = x; + + if (v3 > u3) + { + rem = u3; + u3 = v3; + t2 = v2; + v2 = v1; + v1 = t2; + v3 = rem; + } + + if ((mp_limb_signed_t) (y & x) < WORD(0)) /* y and x both have top bit set */ + { + quot = u3 - v3; + t2 = v2; + u3 = v3; + v2 = v1 - v2; + v1 = t2; + v3 = quot; + } + + while ((mp_limb_signed_t) (v3 << 1) < WORD(0)) /* second value has second msb set */ + { + quot = u3 - v3; + if (quot < v3) + { + t2 = v2; + u3 = v3; + v2 = v1 - v2; + v1 = t2; + v3 = quot; + } + else if (quot < (v3 << 1)) + { + u3 = v3; + t2 = v2; + v2 = v1 - (v2 << 1); + v1 = t2; + v3 = quot - u3; + } + else + { + u3 = v3; + t2 = v2; + v2 = v1 - 3 * v2; + v1 = t2; + v3 = quot - (u3 << 1); + } + } + + while (v3) + { + if (u3 < (v3 << 2)) /* overflow not possible due to top 2 bits of v3 not being set */ + { + quot = u3 - v3; + if (quot < v3) + { + t2 = v2; + u3 = v3; + v2 = v1 - v2; + v1 = t2; + v3 = quot; + } + else if (quot < (v3 << 1)) + { + u3 = v3; + t2 = v2; + v2 = v1 - (v2 << 1); + v1 = t2; + v3 = quot - u3; + } + else + { + u3 = v3; + t2 = v2; + v2 = v1 - 3 * v2; + v1 = t2; + v3 = quot - (u3 << 1); + } + } + else + { + quot = u3 / v3; + rem = u3 - v3 * quot; + u3 = v3; + t2 = v2; + v2 = v1 - quot * v2; + v1 = t2; + v3 = rem; + } + } + + if (v1 < WORD(0)) + v1 += y; + + return v1; +} diff --git a/external/flint-2.4.3/ulong_extras/is_oddprime_binary.c b/external/flint-2.4.3/ulong_extras/is_oddprime_binary.c new file mode 100644 index 0000000..90944c2 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/is_oddprime_binary.c @@ -0,0 +1,56 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 Thomas Boothby + Copyright (C) 2009 William Hart + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" + +int n_is_oddprime_binary(mp_limb_t n) +{ + ulong diff, prime_lo, prime_hi; + const mp_limb_t * primes; + + n_prime_pi_bounds(&prime_lo, &prime_hi, n); + primes = n_primes_arr_readonly(prime_hi + 1); + + if (n == primes[prime_hi]) return 1; + if (n > primes[prime_hi]) return 0; + + diff = (prime_hi - prime_lo + 1) / 2; + + while (1) + { + ulong diff2; + if (primes[prime_lo + diff] <= n) prime_lo += diff; + if (diff <= UWORD(1)) break; + diff = (diff + 1)/2; + diff2 = (prime_hi - prime_lo + 1)/2; + if (diff > diff2) diff = diff2; + } + + return (n == primes[prime_lo]); +} diff --git a/external/flint-2.4.3/ulong_extras/is_oddprime_small.c b/external/flint-2.4.3/ulong_extras/is_oddprime_small.c new file mode 100644 index 0000000..28c346c --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/is_oddprime_small.c @@ -0,0 +1,77 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 Tom Boothby + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" + +#if FLINT64 + +mp_limb_t FLINT_ODD_PRIME_LOOKUP[] = +{ + 0x816d129a64b4cb6eUL, UWORD(0x2196820d864a4c32), UWORD(0xa48961205a0434c9), + UWORD(0x4a2882d129861144), UWORD(0x834992132424030), 0x148a48844225064bUL, + UWORD(0xb40b4086c304205), UWORD(0x65048928125108a0), UWORD(0x80124496804c3098), + UWORD(0xc02104c941124221), UWORD(0x804490000982d32), UWORD(0x220825b082689681), + UWORD(0x9004265940a28948), UWORD(0x6900924430434006), UWORD(0x12410da408088210), + UWORD(0x86122d22400c060), UWORD(0x110d301821b0484), UWORD(0x14916022c044a002), + 0x92094d204a6400cUL, UWORD(0x4ca2100800522094), UWORD(0xa48b081051018200), + UWORD(0x34c108144309a25), UWORD(0x2084490880522502), UWORD(0x241140a218003250), + UWORD(0xa41a00101840128), UWORD(0x2926000836004512), UWORD(0x10100480c0618283), + 0xc20c26584822006dUL, UWORD(0x4520582024894810), UWORD(0x10c0250219002488), + UWORD(0x802832ca01140868), UWORD(0x60901300264b0400) +}; + +#else + +mp_limb_t FLINT_ODD_PRIME_LOOKUP[] = +{ + 0x64b4cb6eUL, 0x816d129aUL, UWORD(0x864a4c32), 0x2196820dUL, + UWORD(0x5a0434c9), UWORD(0xa4896120), UWORD(0x29861144), UWORD(0x4a2882d1), + UWORD(0x32424030), UWORD(0x8349921), 0x4225064bUL, UWORD(0x148a4884), + UWORD(0x6c304205), UWORD(0xb40b408), UWORD(0x125108a0), UWORD(0x65048928), + UWORD(0x804c3098), UWORD(0x80124496), UWORD(0x41124221), UWORD(0xc02104c9), + UWORD(0x982d32), UWORD(0x8044900), UWORD(0x82689681), UWORD(0x220825b0), + UWORD(0x40a28948), UWORD(0x90042659), UWORD(0x30434006), UWORD(0x69009244), + UWORD(0x8088210), UWORD(0x12410da4), UWORD(0x2400c060), UWORD(0x86122d2), + UWORD(0x821b0484), UWORD(0x110d301), UWORD(0xc044a002), UWORD(0x14916022), + 0x4a6400cUL, UWORD(0x92094d2), UWORD(0x522094), UWORD(0x4ca21008), + UWORD(0x51018200), UWORD(0xa48b0810), UWORD(0x44309a25), UWORD(0x34c1081), + UWORD(0x80522502), UWORD(0x20844908), UWORD(0x18003250), UWORD(0x241140a2), + UWORD(0x1840128), UWORD(0xa41a001), UWORD(0x36004512), UWORD(0x29260008), + UWORD(0xc0618283), UWORD(0x10100480), 0x4822006dUL, UWORD(0xc20c2658), + UWORD(0x24894810), UWORD(0x45205820), UWORD(0x19002488), UWORD(0x10c02502), + UWORD(0x1140868), 0x802832caUL, UWORD(0x264b0400), UWORD(0x60901300) +}; + +#endif + +int n_is_oddprime_small(mp_limb_t n) +{ + mp_limb_t q = n / 2; + mp_limb_t x = (q & (FLINT_BITS - UWORD(1))); + return (FLINT_ODD_PRIME_LOOKUP[q / FLINT_BITS] & (UWORD(1) << x)) >> x; +} diff --git a/external/flint-2.4.3/ulong_extras/is_perfect_power235.c b/external/flint-2.4.3/ulong_extras/is_perfect_power235.c new file mode 100644 index 0000000..6e28112 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/is_perfect_power235.c @@ -0,0 +1,83 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 Thomas Boothby + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#define ulong ulongxx /* interferes with system includes */ +#include +#undef ulong +#include "flint.h" +#include "ulong_extras.h" + +int n_is_perfect_power235(mp_limb_t n) +{ + static unsigned char mod63[63] = {7,7,4,0,5,4,0,5,6,5,4,4,0,4,4,0,5,4,5,4, + 4,0,5,4,0,5,4,6,7,4,0,4,4,0,4,6,7,5,4,0,4,4,0,5, + 4,4,5,4,0,5,4,0,4,4,4,6,4,0,5,4,0,4,6}; + static unsigned char mod61[61] = {7,7,0,3,1,1,0,0,2,3,0,6,1,5,5,1,1,0,0,1, + 3,4,1,2,2,1,0,3,2,4,0,0,4,2,3,0,1,2,2,1,4,3,1,0, + 0,1,1,5,5,1,6,0,3,2,0,0,1,1,3,0,7}; + static unsigned char mod44[44] = {7,7,0,2,3,3,0,2,2,3,0,6,7,2,0,2,3,2,0,2, + 3,6,0,6,2,3,0,2,2,2,0,2,6,7,0,2,3,3,0,2,2,2,0,6}; + static unsigned char mod31[31] = {7,7,3,0,3,5,4,1,3,1,1,0,0,0,1,2,3,0,1,1, + 1,0,0,2,0,5,4,2,1,2,6}; + + unsigned char t; + + t = mod31[n%31]; + if (!t) return 0; + + t &= mod44[n%44]; + if (!t) return 0; + + t &= mod61[n%61]; + if (!t) return 0; + + t &= mod63[n%63]; + + if (t & 1) + { + double x = sqrt((double) n); + mp_limb_t y = (mp_limb_t) (x + 0.5); + if (n == n_pow(y, 2)) return 1; + } + + if (t & 2) + { + double x = pow((double) n, 1.0 / 3.0); + mp_limb_t y = (mp_limb_t) (x + 0.5); + if (n == n_pow(y, 3)) return 1; + } + + if (t & 4) + { + double x = pow((double) n, 1.0 / 5.0); + mp_limb_t y = (mp_limb_t) (x + 0.5); + if (n == n_pow(y, 5)) return 1; + } + + return 0; +} + diff --git a/external/flint-2.4.3/ulong_extras/is_prime.c b/external/flint-2.4.3/ulong_extras/is_prime.c new file mode 100644 index 0000000..56030b2 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/is_prime.c @@ -0,0 +1,45 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" + +int n_is_prime(mp_limb_t n) +{ + /* flint's "BPSW" checked against Feitma and Galway's database [1] + up to 2^64 by Dana Jacobsen. + [1] http://www.janfeitsma.nl/math/psp2/database + */ + +#if !FLINT64 + return n_is_probabprime(n); +#else + if (n < UWORD(10000000000000000)) + return n_is_probabprime(n); + else + return n_is_probabprime_BPSW(n); +#endif +} diff --git a/external/flint-2.4.3/ulong_extras/is_prime_pocklington.c b/external/flint-2.4.3/ulong_extras/is_prime_pocklington.c new file mode 100644 index 0000000..4a89897 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/is_prime_pocklington.c @@ -0,0 +1,99 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2008 Peter Shrimpton + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#define ulong ulongxx /* interferes with system includes */ +#include +#undef ulong +#define ulong mp_limb_t +#include "flint.h" +#include "ulong_extras.h" + +int +n_is_prime_pocklington(mp_limb_t n, ulong iterations) +{ + int i, j, pass; + mp_limb_t n1, cofactor, b, c = 0, ninv, limit; + n_factor_t factors; + + if (n % 2 == 0) + { + return (n == UWORD(2)); + } + + n1 = n - 1; + + n_factor_init(&factors); + + limit = n_sqrt(n1); + cofactor = n_factor_partial(&factors, n1, limit, 1); + + if (cofactor != 1) /* check that cofactor is coprime to factors found */ + { + for (i = 0; i < factors.num; i++) + { + if (factors.p[i] > FLINT_FACTOR_TRIAL_PRIMES_PRIME) + { + while (cofactor >= factors.p[i] && (cofactor % factors.p[i]) == 0) + { + factors.exp[i]++; + cofactor /= factors.p[i]; + } + } + } + } + + ninv = n_preinvert_limb(n); + + c = 1; + for (i = factors.num - 1; i >= 0; i--) + { + mp_limb_t exp = n1 / factors.p[i]; + pass = 0; + + for (j = 2; j < iterations && pass == 0; j++) + { + b = n_powmod2_preinv(j, exp, n, ninv); + if (n_powmod2_ui_preinv(b, factors.p[i], n, ninv) != UWORD(1)) + return 0; + + b = n_submod(b, UWORD(1), n); + if (b != UWORD(0)) + { + c = n_mulmod2_preinv(c, b, n, ninv); + pass = 1; + } + + if (c == 0) + return 0; + } + + if (j == iterations) + return -1; + } + + return (n_gcd(n, c) == UWORD(1)); +} diff --git a/external/flint-2.4.3/ulong_extras/is_prime_pseudosquare.c b/external/flint-2.4.3/ulong_extras/is_prime_pseudosquare.c new file mode 100644 index 0000000..710e9d5 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/is_prime_pseudosquare.c @@ -0,0 +1,128 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#define ulong ulongxx /* interferes with system includes */ +#include +#include +#undef ulong +#include +#include "flint.h" +#include "ulong_extras.h" + +mp_limb_t flint_pseudosquares[] = {17, 73, 241, 1009, 2641, 8089, 18001, + 53881, 87481, 117049, 515761, 1083289, 3206641, 3818929, 9257329, + 22000801, 48473881, 48473881, 175244281, 427733329, 427733329, + 898716289u, 2805544681u, 2805544681u, 2805544681u +#ifndef FLINT64 + }; +#else + , 10310263441u, 23616331489u, 85157610409u, 85157610409u, + 196265095009u, 196265095009u, 2871842842801u, 2871842842801u, + 2871842842801u, 26250887023729u, 26250887023729u, 112434732901969u, + 112434732901969u, 112434732901969u, 178936222537081u, + 178936222537081u, 696161110209049u, 696161110209049u, + 2854909648103881u, 6450045516630769u, 6450045516630769u, + 11641399247947921u, 11641399247947921u, 190621428905186449u, + 196640248121928601u, 712624335095093521u, 1773855791877850321u }; +#endif + +#if FLINT64 +#define FLINT_NUM_PSEUDOSQUARES 52 +#else +#define FLINT_NUM_PSEUDOSQUARES 25 +#endif + +int n_is_prime_pseudosquare(mp_limb_t n) +{ + unsigned int i, j, m1; + mp_limb_t p, B, NB, exp, mod8; + const mp_limb_t * primes; + const double * inverses; + + if (n < UWORD(2)) return 0; + + if ((n & UWORD(1)) == UWORD(0)) + { + return (n == UWORD(2)); + } + + primes = n_primes_arr_readonly(FLINT_PSEUDOSQUARES_CUTOFF+1); + inverses = n_prime_inverses_arr_readonly(FLINT_PSEUDOSQUARES_CUTOFF+1); + + for (i = 0; i < FLINT_PSEUDOSQUARES_CUTOFF; i++) + { + double ppre; + p = primes[i]; + if (p*p > n) return 1; + ppre = inverses[i]; + if (!n_mod2_precomp(n, p, ppre)) return 0; + } + + B = primes[FLINT_PSEUDOSQUARES_CUTOFF]; + NB = (n - 1)/B + 1; + m1 = 0; + + for (i = 0; i < FLINT_NUM_PSEUDOSQUARES; i++) + { + if (flint_pseudosquares[i] > NB) break; + } + + exp = (n - 1)/2; + + for (j = 0; j <= i; j++) + { + mp_limb_t mod = n_powmod2(primes[j], exp, n); + if ((mod != UWORD(1)) && (mod != n - 1)) return 0; + if (mod == n - 1) m1 = 1; + } + + mod8 = n % 8; + + if ((mod8 == 3) || (mod8 == 7)) return 1; + + if (mod8 == 5) + { + mp_limb_t mod = n_powmod2(UWORD(2), exp, n); + if (mod == n - 1) return 1; + flint_printf("Whoah, %wu is a probable prime, but not prime, please report!!\n", n); + abort(); + } + else + { + if (m1) return 1; + for (j = i + 1; j < FLINT_NUM_PSEUDOSQUARES + 1; j++) + { + mp_limb_t mod = n_powmod2(primes[j], exp, n); + if (mod == n - 1) return 1; + if (mod != 1) + { + flint_printf("Whoah, %wu is a probable prime, but not prime, please report!!\n", n); + abort(); + } + } + flint_printf("Whoah, %wu is a probable prime, but not prime, please report!!\n", n); + abort(); + } +} diff --git a/external/flint-2.4.3/ulong_extras/is_probabprime.c b/external/flint-2.4.3/ulong_extras/is_probabprime.c new file mode 100644 index 0000000..4bca967 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/is_probabprime.c @@ -0,0 +1,111 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" + +/* + This function is used by n_is_prime up to 2^64 and *must* therefore + act as a primality proof up to that limit. + + Currently it acts as such all the way up to 2^64. +*/ +int n_is_probabprime(mp_limb_t n) +{ + mp_limb_t d; + unsigned int norm; + mp_limb_t ninv; + + if (n <= UWORD(1)) return 0; + if (n == UWORD(2)) return 1; + if ((n & UWORD(1)) == 0) return 0; + + if (n_is_perfect_power235(n)) return 0; + +#if FLINT64 + if (n >= UWORD(10000000000000000)) return n_is_probabprime_BPSW(n); +#endif + + d = n - 1; + count_trailing_zeros(norm, d); + d >>= norm; + +#if FLINT64 + if (n < UWORD(1122004669633)) +#else + if (n < UWORD(2147483648)) +#endif + { + double npre; + if (n < FLINT_ODDPRIME_SMALL_CUTOFF) + return n_is_oddprime_small(n); + + if (n < FLINT_PRIMES_TAB_DEFAULT_CUTOFF) + return n_is_oddprime_binary(n); + + npre = n_precompute_inverse(n); + + if (n < UWORD(9080191)) + { + if (n_is_strong_probabprime_precomp(n, npre, UWORD(31), d) + && n_is_strong_probabprime_precomp(n, npre, UWORD(73), d)) return 1; + else return 0; + } + +#if FLINT64 + if (n < UWORD(4759123141)) + { +#endif + if (n_is_strong_probabprime_precomp(n, npre, UWORD(2), d) + && n_is_strong_probabprime_precomp(n, npre, UWORD(7), d) + && n_is_strong_probabprime_precomp(n, npre, UWORD(61), d)) return 1; + else return 0; +#if FLINT64 + } + + if (n_is_strong_probabprime_precomp(n, npre, UWORD(2), d) + && n_is_strong_probabprime_precomp(n, npre, UWORD(13), d) + && n_is_strong_probabprime_precomp(n, npre, UWORD(23), d) + && n_is_strong_probabprime_precomp(n, npre, UWORD(1662803), d)) + if (n != UWORD(46856248255981)) return 1; + return 0; +#endif + } + + ninv = n_preinvert_limb(n); + + if (n_is_strong_probabprime2_preinv(n, ninv, UWORD(2), d) + && n_is_strong_probabprime2_preinv(n, ninv, UWORD(3), d) + && n_is_strong_probabprime2_preinv(n, ninv, UWORD(7), d) + && n_is_strong_probabprime2_preinv(n, ninv, UWORD(61), d) + && n_is_strong_probabprime2_preinv(n, ninv, UWORD(24251), d)) +#if FLINT64 + if (n != UWORD(46856248255981)) +#endif + return 1; + + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/is_probabprime_BPSW.c b/external/flint-2.4.3/ulong_extras/is_probabprime_BPSW.c new file mode 100644 index 0000000..dd565f7 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/is_probabprime_BPSW.c @@ -0,0 +1,74 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2008 Peter Shrimpton + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" + +int +n_is_probabprime_BPSW(mp_limb_t n) +{ + if (n <= UWORD(1)) + return 0; + + if ((n & UWORD(1)) == UWORD(0)) + { + if (n == UWORD(2)) + return 1; + return 0; + } + + if (((n % 10) == 3) || ((n % 10) == 7)) + { + if (n_is_probabprime_fermat(n, 2) == 0) + return 0; + + return n_is_probabprime_fibonacci(n); + } + else + { + mp_limb_t d; + + d = n - UWORD(1); + while ((d & UWORD(1)) == UWORD(0)) + d >>= 1; + + if (FLINT_BIT_COUNT(n) <= FLINT_D_BITS) + { + double npre = n_precompute_inverse(n); + if (n_is_strong_probabprime_precomp(n, npre, WORD(2), d) == 0) + return 0; + } + else + { + mp_limb_t ninv = n_preinvert_limb(n); + if (n_is_strong_probabprime2_preinv(n, ninv, WORD(2), d) == 0) + return 0; + } + + return (n_is_probabprime_lucas(n) == 1); + } +} diff --git a/external/flint-2.4.3/ulong_extras/is_probabprime_fermat.c b/external/flint-2.4.3/ulong_extras/is_probabprime_fermat.c new file mode 100644 index 0000000..790cd30 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/is_probabprime_fermat.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2008 Peter Shrimpton + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" + +int +n_is_probabprime_fermat(mp_limb_t n, mp_limb_t i) +{ + if (FLINT_BIT_COUNT(n) <= FLINT_D_BITS) + return (n_powmod(i, n - 1, n) == UWORD(1)); + else + return n_powmod2_ui_preinv(i, n - 1, n, n_preinvert_limb(n)) == UWORD(1); +} diff --git a/external/flint-2.4.3/ulong_extras/is_probabprime_fibonacci.c b/external/flint-2.4.3/ulong_extras/is_probabprime_fibonacci.c new file mode 100644 index 0000000..75d7b61 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/is_probabprime_fibonacci.c @@ -0,0 +1,141 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2008 Peter Shrimpton + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" + +n_pair_t +fchain_precomp(mp_limb_t m, mp_limb_t n, double npre) +{ + n_pair_t current = {0, 0}, old; + int length; + mp_limb_t power, xy; + + old.x = UWORD(2); + old.y = n - UWORD(3); + + length = FLINT_BIT_COUNT(m); + power = (UWORD(1) << (length - 1)); + + for (; length > 0; length--) + { + xy = n_mulmod_precomp(old.x, old.y, n, npre); + + xy = n_addmod(xy, UWORD(3), n); + + if (m & power) + { + current.y = + n_submod(n_mulmod_precomp(old.y, old.y, n, npre), UWORD(2), n); + current.x = xy; + } + else + { + current.x = + n_submod(n_mulmod_precomp(old.x, old.x, n, npre), UWORD(2), n); + current.y = xy; + } + + power >>= 1; + old = current; + } + + return current; +} + +n_pair_t +fchain2_preinv(mp_limb_t m, mp_limb_t n, mp_limb_t ninv) +{ + n_pair_t current = {0, 0}, old; + int length; + mp_limb_t power, xy; + + old.x = UWORD(2); + old.y = n - UWORD(3); + + length = FLINT_BIT_COUNT(m); + power = (UWORD(1) << (length - 1)); + + for (; length > 0; length--) + { + xy = n_mulmod2_preinv(old.x, old.y, n, ninv); + + xy = n_addmod(xy, UWORD(3), n); + + if (m & power) + { + current.y = + n_submod(n_mulmod2_preinv(old.y, old.y, n, ninv), UWORD(2), n); + current.x = xy; + } + else + { + current.x = + n_submod(n_mulmod2_preinv(old.x, old.x, n, ninv), UWORD(2), n); + current.y = xy; + } + + power >>= 1; + old = current; + } + + return current; +} + +int +n_is_probabprime_fibonacci(mp_limb_t n) +{ + mp_limb_t m; + n_pair_t V; + + if (FLINT_ABS((mp_limb_signed_t) n) <= UWORD(3)) + { + if (n >= UWORD(2)) + return 1; + return 0; + } + + m = (n - n_jacobi(WORD(5), n)) / 2; /* cannot overflow + as (5/n) = 0 for n = 2^64-1 */ + + if (FLINT_BIT_COUNT(n) <= FLINT_D_BITS) + { + double npre = n_precompute_inverse(n); + + V = fchain_precomp(m, n, npre); + return (n_mulmod_precomp(n - UWORD(3), V.x, n, npre) == + n_mulmod_precomp(UWORD(2), V.y, n, npre)); + } + else + { + mp_limb_t ninv = n_preinvert_limb(n); + + V = fchain2_preinv(m, n, ninv); + return (n_mulmod2_preinv(n - UWORD(3), V.x, n, ninv) == + n_mulmod2_preinv(UWORD(2), V.y, n, ninv)); + } +} diff --git a/external/flint-2.4.3/ulong_extras/is_probabprime_lucas.c b/external/flint-2.4.3/ulong_extras/is_probabprime_lucas.c new file mode 100644 index 0000000..330921c --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/is_probabprime_lucas.c @@ -0,0 +1,184 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2008 Peter Shrimpton + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" + +n_pair_t +lchain_precomp(mp_limb_t m, mp_limb_t a, mp_limb_t n, double npre) +{ + n_pair_t current = {0, 0}, old; + int length, i; + mp_limb_t power, xy, xx, yy; + + old.x = UWORD(2); + old.y = a; + + length = FLINT_BIT_COUNT(m); + power = (UWORD(1) << (length - 1)); + + for (i = 0; i < length; i++) + { + xy = n_submod(n_mulmod_precomp(old.x, old.y, n, npre), a, n); + + if (m & power) + { + yy = n_submod(n_mulmod_precomp(old.y, old.y, n, npre), UWORD(2), n); + current.x = xy; + current.y = yy; + } + else + { + xx = n_submod(n_mulmod_precomp(old.x, old.x, n, npre), UWORD(2), n); + current.x = xx; + current.y = xy; + } + + power >>= 1; + old = current; + } + + return current; +} + +n_pair_t +lchain2_preinv(mp_limb_t m, mp_limb_t a, mp_limb_t n, mp_limb_t ninv) +{ + n_pair_t current = {0, 0}, old; + int length, i; + mp_limb_t power, xy, xx, yy; + + old.x = UWORD(2); + old.y = a; + + length = FLINT_BIT_COUNT(m); + power = (UWORD(1) << (length - 1)); + + for (i = 0; i < length; i++) + { + xy = n_submod(n_mulmod2_preinv(old.x, old.y, n, ninv), a, n); + + if (m & power) + { + yy = n_submod(n_mulmod2_preinv(old.y, old.y, n, ninv), UWORD(2), n); + current.x = xy; + current.y = yy; + } + else + { + xx = n_submod(n_mulmod2_preinv(old.x, old.x, n, ninv), UWORD(2), n); + current.x = xx; + current.y = xy; + } + + power >>= 1; + old = current; + } + + return current; +} + +int +n_is_probabprime_lucas(mp_limb_t n) +{ + int i, D, Q; + mp_limb_t A; + mp_limb_t left, right; + n_pair_t V; + + D = 0; + Q = 0; + + if (((n % 2) == 0) || (FLINT_ABS((mp_limb_signed_t) n) <= 2)) + { + return (n == UWORD(2)); + } + + for (i = 0; i < 100; i++) + { + D = 5 + 2 * i; + if (n_gcd(D, n % D) != UWORD(1)) + { + if (n == D) + continue; + else + return 0; + } + if (i % 2 == 1) + D = -D; + if (n_jacobi(D, n) == -1) + break; + } + + if (i == 100) + { + return (n_is_square(n) ? -1 : 1); + } + + Q = (1 - D) / 4; + if (Q < 0) + { + if (n < UWORD(52)) + { + while (Q < 0) + Q += n; + A = n_submod(n_invmod(Q, n), UWORD(2), n); + } + else + A = n_submod(n_invmod(Q + n, n), UWORD(2), n); + } + else + { + if (n < UWORD(52)) + { + while (Q >= n) + Q -= n; + A = n_submod(n_invmod(Q, n), UWORD(2), n); + } + else + A = n_submod(n_invmod(Q, n), UWORD(2), n); + } + + if (FLINT_BIT_COUNT(n) <= FLINT_D_BITS) + { + double npre = n_precompute_inverse(n); + V = lchain_precomp(n + 1, A, n, npre); + + left = n_mulmod_precomp(A, V.x, n, npre); + right = n_mulmod_precomp(2, V.y, n, npre); + } + else + { + mp_limb_t ninv = n_preinvert_limb(n); + V = lchain2_preinv(n + 1, A, n, ninv); + + left = n_mulmod_precomp(A, V.x, n, ninv); + right = n_mulmod_precomp(2, V.y, n, ninv); + } + + return (left == right); +} diff --git a/external/flint-2.4.3/ulong_extras/is_square.c b/external/flint-2.4.3/ulong_extras/is_square.c new file mode 100644 index 0000000..b61892d --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/is_square.c @@ -0,0 +1,57 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#define ulong ulongxx /* interferes with system includes */ +#include +#undef ulong +#define ulong mp_limb_t +#include +#include "flint.h" +#include "ulong_extras.h" + +int mod64[64] = {1,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0, + 0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,1, + 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0}; + +int mod65[65] = {1,1,0,0,1,0,0,0,0,1,1,0,0,0,1,0,1,0,0,0,0,0, + 0,0,0,1,1,0,0,1,1,0,0,0,0,1,1,0,0,1,1,0,0,0, + 0,0,0,0,0,1,0,1,0,0,0,1,1,0,0,0,0,1,0,0,1}; + +int mod63[63] = {1,1,0,0,1,0,0,1,0,1,0,0,0,0,1,0,1,0,1,0,0, + 0,1,0,0,1,0,0,1,0,0,0,0,0,0,1,1,1,0,0,0,0, + 0,1,0,0,1,0,0,1,0,0,0,0,0,0,1,0,1,0,0,0,0}; + +int n_is_square(mp_limb_t x) +{ + mp_limb_t sq; + + if (!mod64[x % UWORD(64)]) return 0; + if (!mod63[x % UWORD(63)]) return 0; + if (!mod65[x % UWORD(65)]) return 0; + + sq = (mp_limb_t) (sqrt((double) x) + 0.5); + + return (x == sq*sq); +} diff --git a/external/flint-2.4.3/ulong_extras/is_squarefree.c b/external/flint-2.4.3/ulong_extras/is_squarefree.c new file mode 100644 index 0000000..6e45b94 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/is_squarefree.c @@ -0,0 +1,32 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include "flint.h" +#include "ulong_extras.h" + +int n_is_squarefree(mp_limb_t n) +{ + return n_moebius_mu(n) != 0; +} diff --git a/external/flint-2.4.3/ulong_extras/is_strong_probabprime2_preinv.c b/external/flint-2.4.3/ulong_extras/is_strong_probabprime2_preinv.c new file mode 100644 index 0000000..8fdd1e7 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/is_strong_probabprime2_preinv.c @@ -0,0 +1,51 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2008, Peter Shrimpton + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" + +int +n_is_strong_probabprime2_preinv(mp_limb_t n, mp_limb_t ninv, mp_limb_t a, + mp_limb_t d) +{ + mp_limb_t t = d; + mp_limb_t y; + + y = n_powmod2_ui_preinv(a, t, n, ninv); + + if (y == UWORD(1)) + return 1; + t <<= 1; + + while ((t != n - 1) && (y != n - 1)) + { + y = n_mulmod2_preinv(y, y, n, ninv); + t <<= 1; + } + + return (y == n - 1); +} diff --git a/external/flint-2.4.3/ulong_extras/is_strong_probabprime_precomp.c b/external/flint-2.4.3/ulong_extras/is_strong_probabprime_precomp.c new file mode 100644 index 0000000..be9e212 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/is_strong_probabprime_precomp.c @@ -0,0 +1,51 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2008, Peter Shrimpton + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" + +int +n_is_strong_probabprime_precomp(mp_limb_t n, double npre, mp_limb_t a, + mp_limb_t d) +{ + mp_limb_t t = d; + mp_limb_t y; + + y = n_powmod_ui_precomp(a, t, n, npre); + + if (y == UWORD(1)) + return 1; + t <<= 1; + + while ((t != n - 1) && (y != n - 1)) + { + y = n_mulmod_precomp(y, y, n, npre); + t <<= 1; + } + + return (y == n - 1); +} diff --git a/external/flint-2.4.3/ulong_extras/jacobi.c b/external/flint-2.4.3/ulong_extras/jacobi.c new file mode 100644 index 0000000..6c6f78f --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/jacobi.c @@ -0,0 +1,112 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2008 Peter Shrimpton + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" + +int +n_jacobi_unsigned(mp_limb_t x, mp_limb_t y) +{ + mp_limb_t a, b, temp; + int s, exp; + + a = x; + b = y; + s = 1; + + if ((a < b) && (b != UWORD(1))) + { + if (a == UWORD(0)) + return 0; + + temp = a; + a = b; + b = temp; + + count_trailing_zeros(exp, b); + b >>= exp; + + /* We are only interested in values mod 8, so overflows don't matter here */ + if (((exp * (a * a - 1)) / 8) % 2 == UWORD(1)) + s = -s; + + /* We are only interested in values mod 4, so overflows don't matter here */ + if ((((a - 1) * (b - 1)) / 4) % 2 == UWORD(1)) + s = -s; + } + + while (b != UWORD(1)) + { + if ((a >> 2) < b) + { + temp = a - b; + a = b; + if (temp < b) + b = temp; + else if (temp < (b << 1)) + b = temp - a; + else + b = temp - (a << 1); + } + else + { + temp = a % b; + a = b; + b = temp; + } + + if (b == UWORD(0)) + return 0; + + count_trailing_zeros(exp, b); + b >>= exp; + + /* We are only interested in values mod 8, so overflows don't matter here */ + if (((exp * (a * a - 1)) / 8) % 2 == UWORD(1)) + s = -s; + + /* We are only interested in values mod 4, so overflows don't matter here */ + if ((((a - 1) * (b - 1)) / 4) % 2 == UWORD(1)) + s = -s; + } + + return s; +} + +int +n_jacobi(mp_limb_signed_t x, mp_limb_t y) +{ + if (x < WORD(0)) + { + if (((y - 1) / 2) % 2 == UWORD(1)) + return -n_jacobi_unsigned(-x, y); + else + return n_jacobi_unsigned(-x, y); + } + else + return n_jacobi_unsigned(x, y); +} diff --git a/external/flint-2.4.3/ulong_extras/ll_mod_preinv.c b/external/flint-2.4.3/ulong_extras/ll_mod_preinv.c new file mode 100644 index 0000000..cf1984a --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/ll_mod_preinv.c @@ -0,0 +1,103 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009, 2010 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" + +/* + +mp_limb_t +n_ll_mod_preinv(mp_limb_t a_hi, mp_limb_t a_lo, mp_limb_t n, mp_limb_t ninv) +{ + mp_limb_t q, r, norm; + + if (a_hi > n) a_hi = n_mod2_preinv(a_hi, n, ninv); + + count_leading_zeros(norm, n); + + udiv_qrnnd_preinv(q, r, (a_hi<>norm); +} + +*/ + +/* + New method of Moller and Granlund + see paper Improved Division by Invariant Integers (Torbjorn Granlund + and Niels Moller) (preprint): (pp. 4) + http://www.lysator.liu.se/~nisse/archive/draft-division-paper.pdf +*/ +mp_limb_t +n_ll_mod_preinv(mp_limb_t a_hi, mp_limb_t a_lo, mp_limb_t n, mp_limb_t ninv) +{ + mp_limb_t q0, q1, r, norm; + + count_leading_zeros(norm, n); + + /* reduce u1 first i.e. u1 = n_mod2_preinv(u1, n, ninv) */ + if (a_hi >= n) + { + const mp_limb_t u1 = r_shift(a_hi, FLINT_BITS - norm); + const mp_limb_t u0 = (a_hi << norm); + + n <<= norm; + + umul_ppmm(q1, q0, ninv, u1); + add_ssaaaa(q1, q0, q1, q0, u1, u0); + + r = (u0 - (q1 + 1) * n); + + if (r >= q0) + r += n; + + if (r < n) + a_hi = (r >> norm); + else + a_hi = ((r - n) >> norm); + } + else + n <<= norm; + + /* now reduce the rest of the way */ + { + const mp_limb_t u1 = (a_hi << norm) + r_shift(a_lo, FLINT_BITS - norm); + const mp_limb_t u0 = (a_lo << norm); + + umul_ppmm(q1, q0, ninv, u1); + add_ssaaaa(q1, q0, q1, q0, u1, u0); + + r = (u0 - (q1 + 1) * n); + + if (r >= q0) + r += n; + + if (r < n) + return (r >> norm); + else + return ((r - n) >> norm); + } +} diff --git a/external/flint-2.4.3/ulong_extras/lll_mod_preinv.c b/external/flint-2.4.3/ulong_extras/lll_mod_preinv.c new file mode 100644 index 0000000..7d316ff --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/lll_mod_preinv.c @@ -0,0 +1,88 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009, 2010 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" + +/* + New method of Moller and Granlund + see paper Improved Division by Invariant Integers (Torbjorn Granlund + and Niels Moller) (preprint): (pp. 4) + http://www.lysator.liu.se/~nisse/archive/draft-division-paper.pdf +*/ +mp_limb_t +n_lll_mod_preinv(mp_limb_t a_hi, mp_limb_t a_mi, mp_limb_t a_lo, + mp_limb_t n, mp_limb_t ninv) +{ + mp_limb_t q0, q1, r, norm; + + count_leading_zeros(norm, n); + n <<= norm; + + /* + we assume a_hi is already reduced + first reduce a_hi, a_mi mod n + */ + { + const mp_limb_t u1 = (a_hi << norm) + r_shift(a_mi, FLINT_BITS - norm); + const mp_limb_t u0 = (a_mi << norm); + + umul_ppmm(q1, q0, ninv, u1); + add_ssaaaa(q1, q0, q1, q0, u1, u0); + + r = (u0 - (q1 + 1) * n); + + if (r >= q0) + r += n; + + if (r < n) + a_mi = (r >> norm); + else + a_mi = ((r - n) >> norm); + } + + /* + now a_mid is reduced mod n + so reduce a_mi, a_lo mod n + */ + { + const mp_limb_t u1 = (a_mi << norm) + r_shift(a_lo, FLINT_BITS - norm); + const mp_limb_t u0 = (a_lo << norm); + + umul_ppmm(q1, q0, ninv, u1); + add_ssaaaa(q1, q0, q1, q0, u1, u0); + + r = (u0 - (q1 + 1) * n); + + if (r >= q0) + r += n; + + if (r < n) + return (r >> norm); + else + return ((r - n) >> norm); + } +} diff --git a/external/flint-2.4.3/ulong_extras/mod2_precomp.c b/external/flint-2.4.3/ulong_extras/mod2_precomp.c new file mode 100644 index 0000000..96f9130 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/mod2_precomp.c @@ -0,0 +1,67 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" + +mp_limb_t +n_mod2_precomp(mp_limb_t a, mp_limb_t n, double npre) +{ + mp_limb_t quot; + slong rem; + + if (a < n) + return a; + if ((mp_limb_signed_t) n < WORD(0)) + return a - n; + + if (n == 1) + { + quot = a; + rem = 0; + } else + { + quot = (mp_limb_t) ((double) a * npre); + rem = a - quot * n; + } + + if (rem < (mp_limb_signed_t) (-n)) + quot -= (mp_limb_t) ((double) (-rem) * npre); + else if (rem >= (slong) n) + quot += (mp_limb_t) ((double) rem * npre); + else if (rem < WORD(0)) + return rem + n; + else + return rem; + + rem = a - quot * n; + if (rem >= (slong) n) + return rem - n; + else if (rem < WORD(0)) + return rem + n; + else + return rem; +} diff --git a/external/flint-2.4.3/ulong_extras/mod2_preinv.c b/external/flint-2.4.3/ulong_extras/mod2_preinv.c new file mode 100644 index 0000000..229852a --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/mod2_preinv.c @@ -0,0 +1,72 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009, 2010 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" + +/* + +mp_limb_t n_mod2_preinv(mp_limb_t a, mp_limb_t n, mp_limb_t ninv) +{ + unsigned int norm; + mp_limb_t q, r; + + count_leading_zeros(norm, n); + udiv_qrnnd_preinv(q, r, r_shift(a, FLINT_BITS-norm), a<>norm); +} + +*/ + +/* + New method of Moller and Granlund + see paper Improved Division by Invariant Integers (Torbjorn Granlund + and Niels Moller) (preprint): (pp. 4) + http://www.lysator.liu.se/~nisse/archive/draft-division-paper.pdf + */ +mp_limb_t n_mod2_preinv(mp_limb_t a, mp_limb_t n, mp_limb_t ninv) +{ + unsigned int norm; + mp_limb_t q1, q0, r; + + count_leading_zeros(norm, n); + n <<= norm; + + { + const mp_limb_t u1 = r_shift(a, FLINT_BITS-norm); + const mp_limb_t u0 = (a << norm); + + umul_ppmm(q1, q0, ninv, u1); + add_ssaaaa(q1, q0, q1, q0, u1, u0); + + r = (u0 - (q1 + 1)*n); + + if (r >= q0) r += n; + + return (r < n) ? (r >> norm) : ((r - n) >> norm); + } +} + diff --git a/external/flint-2.4.3/ulong_extras/mod_precomp.c b/external/flint-2.4.3/ulong_extras/mod_precomp.c new file mode 100644 index 0000000..580b1b7 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/mod_precomp.c @@ -0,0 +1,39 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" + +mp_limb_t n_mod_precomp(mp_limb_t a, mp_limb_t n, double npre) +{ + mp_limb_t quot, rem; + + quot = (mp_limb_t) ((double) a * npre); + rem = a - quot*n; + if ((slong) rem < 0) /* unlikely */ + rem += n; + return rem - (n & (((mp_limb_signed_t) (n - rem - 1)) >> (FLINT_BITS-1))); +} diff --git a/external/flint-2.4.3/ulong_extras/moebius_mu.c b/external/flint-2.4.3/ulong_extras/moebius_mu.c new file mode 100644 index 0000000..66dcb27 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/moebius_mu.c @@ -0,0 +1,117 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include "flint.h" +#include "ulong_extras.h" + +#define FLINT_MU_LOOKUP_CUTOFF 1024 + +#if FLINT64 +const mp_limb_t FLINT_MOEBIUS_ODD[] = +{ + UWORD(0x4289108a05208102), UWORD(0x19988004a8a12422), UWORD(0x1a8245028906a062), + UWORD(0x229428012aa26a00), UWORD(0x8422a98980440a18), 0x224925084068929aUL, + UWORD(0xa1200942a8980a84), UWORD(0x8622622216a00428), UWORD(0x6060829286a590a9), + UWORD(0x5a2190081420a1a8), UWORD(0x8a92a284a8018200), UWORD(0x980a2602491a2248), + UWORD(0x8106a08982a26848), UWORD(0xa60085a6004a5919), UWORD(0x88a188245a221228), + UWORD(0x0108884a22186025) +}; +#else +const mp_limb_t FLINT_MOEBIUS_ODD[] = +{ + UWORD(0x05208102), 0x4289108aUL, UWORD(0xa8a12422), UWORD(0x19988004), UWORD(0x8906a062), + UWORD(0x1a824502), UWORD(0x2aa26a00), UWORD(0x22942801), UWORD(0x80440a18), UWORD(0x8422a989), + 0x4068929aUL, UWORD(0x22492508), UWORD(0xa8980a84), UWORD(0xa1200942), UWORD(0x16a00428), + UWORD(0x86226222), UWORD(0x86a590a9), UWORD(0x60608292), UWORD(0x1420a1a8), UWORD(0x5a219008), + UWORD(0xa8018200), UWORD(0x8a92a284), UWORD(0x491a2248), UWORD(0x980a2602), UWORD(0x82a26848), + UWORD(0x8106a089), UWORD(0x004a5919), UWORD(0xa60085a6), UWORD(0x5a221228), UWORD(0x88a18824), + UWORD(0x22186025), 0x0108884aUL +}; +#endif + +void n_moebius_mu_vec(int * mu, ulong len) +{ + slong k; + ulong pi; + const mp_limb_t * primes; + mp_limb_t p, q; + + pi = n_prime_pi(len); + primes = n_primes_arr_readonly(pi); + + if (len) + mu[0] = 0; + for (k = 1; k < len; k++) + mu[k] = 1; + for (k = 0; k < pi; k++) + { + p = primes[k]; + for (q = p; q < len; q += p) + mu[q] = -mu[q]; + p = p * p; + for (q = p; q < len; q += p) + mu[q] = 0; + } +} + +int n_moebius_mu(mp_limb_t n) +{ + int i; + n_factor_t fac; + + if (n % 2 == 0) + { + if (n % 4 == 0) + return 0; + return -n_moebius_mu(n / 2); + } + + if (n < FLINT_MU_LOOKUP_CUTOFF) + { + mp_limb_t m; + n -= 1; + m = FLINT_MOEBIUS_ODD[n / FLINT_BITS]; + m &= (UWORD(3) << (n % FLINT_BITS)); + m >>= (n % FLINT_BITS); + return ((int) m) - 1; + } + + /* Weed out just a few more common squares first */ + if (n % 9 == 0 || n % 25 == 0) + return 0; + + n_factor_init(&fac); + n_factor(&fac, n, 1); + for (i = 0; i < fac.num; i++) + { + if (fac.exp[i] != 1) + return 0; + } + + if (fac.num % 2) + return -1; + else + return 1; +} diff --git a/external/flint-2.4.3/ulong_extras/mulmod2_preinv.c b/external/flint-2.4.3/ulong_extras/mulmod2_preinv.c new file mode 100644 index 0000000..1f5bb15 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/mulmod2_preinv.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" + +mp_limb_t +n_mulmod2_preinv(mp_limb_t a, mp_limb_t b, mp_limb_t n, mp_limb_t ninv) +{ + mp_limb_t p1, p2; + + umul_ppmm(p1, p2, a, b); + + return n_ll_mod_preinv(p1, p2, n, ninv); +} diff --git a/external/flint-2.4.3/ulong_extras/mulmod_precomp.c b/external/flint-2.4.3/ulong_extras/mulmod_precomp.c new file mode 100644 index 0000000..7d0696a --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/mulmod_precomp.c @@ -0,0 +1,44 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" + +mp_limb_t n_mulmod_precomp(mp_limb_t a, mp_limb_t b, mp_limb_t n, double npre) +{ + mp_limb_t quot; + mp_limb_signed_t rem; + + quot = (mp_limb_t) ((double) a * (double) b * npre); + rem = a * b - quot * n; + if (rem < 0) + { + rem += n; + if (rem < 0) return rem + n; + } + else if (rem >= n) return rem - n; + return rem; +} diff --git a/external/flint-2.4.3/ulong_extras/mulmod_preinv.c b/external/flint-2.4.3/ulong_extras/mulmod_preinv.c new file mode 100644 index 0000000..4b88654 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/mulmod_preinv.c @@ -0,0 +1,58 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009, 2010, 2012 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" + +mp_limb_t +n_mulmod_preinv(mp_limb_t a, mp_limb_t b, mp_limb_t n, + mp_limb_t ninv, ulong norm) +{ + mp_limb_t q0, q1, r, p_hi, p_lo; + + /* multiply */ + umul_ppmm(p_hi, p_lo, a, b); + + /* renormalise product */ + if (norm) + { + p_lo = (p_lo >> norm) + (p_hi << (FLINT_BITS - norm)); + p_hi = (p_hi >> norm); + } + + /* reduce mod n */ + { + umul_ppmm(q1, q0, ninv, p_hi); + add_ssaaaa(q1, q0, q1, q0, p_hi, p_lo); + + r = (p_lo - (q1 + 1) * n); + + if (r >= q0) + r += n; + + return (r < n ? r : r - n); + } +} diff --git a/external/flint-2.4.3/ulong_extras/nextprime.c b/external/flint-2.4.3/ulong_extras/nextprime.c new file mode 100644 index 0000000..5705507 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/nextprime.c @@ -0,0 +1,131 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007, 2008 William Hart + Copyright (C) 2008 Peter Shrimpton + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#define ulong ulongxx /* interferes with system includes */ +#include +#include +#undef ulong +#define ulong mp_limb_t +#include +#include "flint.h" +#include "ulong_extras.h" + +unsigned int nextmod30[] = +{ + 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 2, 1, + 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 2 +}; + +unsigned int nextindex[] = +{ + 1, 7, 7, 7, 7, 7, 7, 11, 11, 11, 11, 13, 13, 17, 17, 17, 17, 19, 19, + 23, 23, 23, 23, 29, 29, 29, 29, 29, 29, 1 +}; + +#define NEXTPRIME_PRIMES 54 + + +mp_limb_t n_nextprime(mp_limb_t n, int proved) +{ + mp_limb_t * moduli; + ulong i, index; + + if (n < 7) + { + if (n < 2) + return 2; + n++; + n |= 1; + return n; + } + + if (n >= UWORD_MAX_PRIME) + { + flint_printf("Exception (n_nextprime). No larger single-limb prime exists.\n"); + abort(); + } + + index = n % 30; + n += nextmod30[index]; + index = nextindex[index]; + + if (n <= flint_primes_small[NEXTPRIME_PRIMES-1]) + { + if (n == 7) return 7; + if (n == 11) return 11; + if (n == 13) return 13; + + while (((n % 7) == 0) || ((n % 11) == 0) || ((n % 13) == 0)) + { + n += nextmod30[index]; + index = nextindex[index]; + } + return n; + } + + moduli = (mp_limb_t *) flint_malloc(NEXTPRIME_PRIMES * sizeof(mp_limb_t)); + + for (i = 3; i < NEXTPRIME_PRIMES; i++) + moduli[i] = (n % flint_primes_small[i]); + + while (1) + { + ulong composite = 0; + ulong diff, acc, pr; + + diff = nextmod30[index]; + + /* First check residues */ + for (i = 3; i < NEXTPRIME_PRIMES; i++) + { + composite |= (moduli[i] == 0); + acc = moduli[i] + diff; + pr = flint_primes_small[i]; + moduli[i] = acc >= pr ? acc - pr : acc; + } + + if (composite) + { + n += diff; + index = nextindex[index]; + continue; + } + + if ((!proved && n_is_probabprime(n)) || (proved && n_is_prime(n))) + { + break; + } + else + { + n += diff; + index = nextindex[index]; + } + } + + flint_free(moduli); + return n; +} diff --git a/external/flint-2.4.3/ulong_extras/nth_prime.c b/external/flint-2.4.3/ulong_extras/nth_prime.c new file mode 100644 index 0000000..21b320f --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/nth_prime.c @@ -0,0 +1,44 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#define ulong ulongxx /* interferes with system includes */ +#include +#include +#undef ulong +#define ulong mp_limb_t +#include "flint.h" +#include "ulong_extras.h" + +mp_limb_t n_nth_prime(ulong n) +{ + if (n == 0) + { + flint_printf("Exception (n_nth_prime). n_nth_prime(0) is undefined.\n"); + abort(); + } + + return n_primes_arr_readonly(n)[n-1]; +} + diff --git a/external/flint-2.4.3/ulong_extras/nth_prime_bounds.c b/external/flint-2.4.3/ulong_extras/nth_prime_bounds.c new file mode 100644 index 0000000..3479251 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/nth_prime_bounds.c @@ -0,0 +1,49 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not,write to the Free Software + Foundation,Inc.,51 Franklin St,Fifth Floor,Boston,MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" + + +void n_nth_prime_bounds(mp_limb_t *lo, mp_limb_t *hi, ulong n) +{ + int bits, ll; + double llo, lhi; + + /* Lower and upper bounds for ln(n) */ + bits = FLINT_BIT_COUNT(n); + llo = (bits-1) * 0.6931471; + lhi = bits * 0.6931472; + + /* Lower bound for ln(ln(n)) */ + if (n < 16) ll = 0; + else if (n < 1619) ll = 1; + else if (n < 528491312) ll = 2; + else ll = 3; + + *lo = (mp_limb_t) (n * (llo + ll - 1)); + *hi = (mp_limb_t) (n * (lhi + (ll+1) - (n >= 15985 ? 0.9427 : 0.0))); +} diff --git a/external/flint-2.4.3/ulong_extras/pow.c b/external/flint-2.4.3/ulong_extras/pow.c new file mode 100644 index 0000000..058dfa3 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/pow.c @@ -0,0 +1,41 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" + +mp_limb_t n_pow(mp_limb_t n, ulong exp) +{ + ulong i; + mp_limb_t res; + + res = UWORD(1); + for (i = 0; i < exp; i++) + res *= n; + + return res; +} diff --git a/external/flint-2.4.3/ulong_extras/powmod2_preinv.c b/external/flint-2.4.3/ulong_extras/powmod2_preinv.c new file mode 100644 index 0000000..f01ddba --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/powmod2_preinv.c @@ -0,0 +1,60 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" + +mp_limb_t +n_powmod2_ui_preinv(mp_limb_t a, mp_limb_t exp, mp_limb_t n, mp_limb_t ninv) +{ + mp_limb_t x, y; + + if (n == UWORD(1)) return UWORD(0); + + x = UWORD(1); + y = a; + while (exp) + { + if (exp & 1) x = n_mulmod2_preinv(x, y, n, ninv); + exp >>= 1; + if (exp) y = n_mulmod2_preinv(y, y, n, ninv); + } + + return x; +} + +mp_limb_t +n_powmod2_preinv(mp_limb_t a, mp_limb_signed_t exp, mp_limb_t n, mp_limb_t ninv) +{ + if (exp < WORD(0)) + { + a = n_invmod(a, n); + exp = -exp; + } + + return n_powmod2_ui_preinv(a, exp, n, ninv); +} + diff --git a/external/flint-2.4.3/ulong_extras/powmod_precomp.c b/external/flint-2.4.3/ulong_extras/powmod_precomp.c new file mode 100644 index 0000000..394c795 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/powmod_precomp.c @@ -0,0 +1,63 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" + +mp_limb_t +n_powmod_ui_precomp(mp_limb_t a, mp_limb_t exp, mp_limb_t n, double npre) +{ + mp_limb_t x, y; + + if (n == UWORD(1)) + return WORD(0); + + x = UWORD(1); + y = a; + + while (exp) + { + if (exp & WORD(1)) + x = n_mulmod_precomp(x, y, n, npre); + exp >>= 1; + if (exp) + y = n_mulmod_precomp(y, y, n, npre); + } + + return x; +} + +mp_limb_t +n_powmod_precomp(mp_limb_t a, mp_limb_signed_t exp, mp_limb_t n, double npre) +{ + if (exp < 0) + { + a = n_invmod(a, n); + exp = -exp; + } + + return n_powmod_ui_precomp(a, exp, n, npre); +} diff --git a/external/flint-2.4.3/ulong_extras/prime_inverses_arr_readonly.c b/external/flint-2.4.3/ulong_extras/prime_inverses_arr_readonly.c new file mode 100644 index 0000000..636c4d4 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/prime_inverses_arr_readonly.c @@ -0,0 +1,44 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 +#include "flint.h" +#include "ulong_extras.h" + +const double * n_prime_inverses_arr_readonly(ulong num_primes) +{ + int m; + + if (num_primes < 1) + return NULL; + + m = FLINT_CLOG2(num_primes); + if (m >= _flint_primes_used) + n_compute_primes(num_primes); + + return _flint_prime_inverses[m]; +} + diff --git a/external/flint-2.4.3/ulong_extras/prime_pi.c b/external/flint-2.4.3/ulong_extras/prime_pi.c new file mode 100644 index 0000000..cdc0e32 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/prime_pi.c @@ -0,0 +1,66 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" + +const unsigned char FLINT_PRIME_PI_ODD_LOOKUP[] = +{ + 0,2,3,4,4,5,6,6,7,8,8,9,9,9,10,11,11,11,12,12,13,14,14,15,15,15,16,16,16,17, + 18,18,18,19,19,20,21,21,21,22,22,23,23,23,24,24,24,24,25,25,26,27,27,28,29, + 29,30,30,30,30,30,30,30,31,31,32,32,32,33,34,34,34,34,34,35,36,36,36,37,37, + 37,38,38,39,39,39,40,40,40,41,42,42,42,42,42,43,44,44,45,46,46,46,46,46,46, + 47,47,47,47,47,47,48,48,49,50,50,51,51,51,52,53,53,53,53,53,54,54,54,55,55, + 55,56,56,56,57,58,58,58,59,59,60,61,61,61,61,61,62,62,62,62,62,62,62,63,63 +}; + + +ulong n_prime_pi(mp_limb_t n) +{ + ulong low, mid, high; + const mp_limb_t * primes; + + if (n < FLINT_PRIME_PI_ODD_LOOKUP_CUTOFF) + { + if (n < 3) + return (n == 2); + return FLINT_PRIME_PI_ODD_LOOKUP[(n-1)/2]; + } + + n_prime_pi_bounds(&low, &high, n); + primes = n_primes_arr_readonly(high + 1); + + while (low < high) + { + mid = (low + high) / 2; + if (n < primes[mid-1]) + high = mid; + else + low = mid + 1; + } + + return low-1; +} diff --git a/external/flint-2.4.3/ulong_extras/prime_pi_bounds.c b/external/flint-2.4.3/ulong_extras/prime_pi_bounds.c new file mode 100644 index 0000000..0766624 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/prime_pi_bounds.c @@ -0,0 +1,38 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" + + +void n_prime_pi_bounds(ulong *lo, ulong *hi, mp_limb_t n) +{ + int lg2 = FLINT_BIT_COUNT(n); + + *lo = (ulong)(((double)n)/((double)lg2*0.6931472)); + *hi = (ulong)(((double)n)/((double)(lg2-1)*0.5522821)); +} diff --git a/external/flint-2.4.3/ulong_extras/primes_arr_readonly.c b/external/flint-2.4.3/ulong_extras/primes_arr_readonly.c new file mode 100644 index 0000000..467e3c6 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/primes_arr_readonly.c @@ -0,0 +1,44 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 +#include "flint.h" +#include "ulong_extras.h" + +const mp_limb_t * n_primes_arr_readonly(ulong num_primes) +{ + int m; + + if (num_primes < 1) + return NULL; + + m = FLINT_CLOG2(num_primes); + if (m >= _flint_primes_used) + n_compute_primes(num_primes); + + return _flint_primes[m]; +} + diff --git a/external/flint-2.4.3/ulong_extras/primes_clear.c b/external/flint-2.4.3/ulong_extras/primes_clear.c new file mode 100644 index 0000000..b729d3c --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/primes_clear.c @@ -0,0 +1,37 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 +#include "ulong_extras.h" + +void +n_primes_clear(n_primes_t iter) +{ + if (iter->small_primes != flint_primes_small) + flint_free(iter->small_primes); + + if (iter->sieve != NULL) + flint_free(iter->sieve); +} diff --git a/external/flint-2.4.3/ulong_extras/primes_extend_small.c b/external/flint-2.4.3/ulong_extras/primes_extend_small.c new file mode 100644 index 0000000..59b1509 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/primes_extend_small.c @@ -0,0 +1,55 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 +#include +#include "flint.h" +#include "ulong_extras.h" + +void +n_primes_extend_small(n_primes_t iter, mp_limb_t bound) +{ + while (iter->small_primes[iter->small_num - 2] < bound) + { + n_primes_t iter2; + slong i, num; + + num = iter->small_num * 2; + + if (iter->small_primes == flint_primes_small) + iter->small_primes = flint_malloc(num * sizeof(unsigned int)); + else + iter->small_primes = flint_realloc(iter->small_primes, + num * sizeof(unsigned int)); + + n_primes_init(iter2); + for (i = 0; i < num; i++) + iter->small_primes[i] = n_primes_next(iter2); + n_primes_clear(iter2); + + iter->small_num = num; + iter->small_i = num; + } +} diff --git a/external/flint-2.4.3/ulong_extras/primes_init.c b/external/flint-2.4.3/ulong_extras/primes_init.c new file mode 100644 index 0000000..37a57ab --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/primes_init.c @@ -0,0 +1,41 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 +#include "ulong_extras.h" + +void +n_primes_init(n_primes_t iter) +{ + iter->small_i = 0; + iter->small_primes = (unsigned int *) flint_primes_small; + iter->small_num = FLINT_NUM_PRIMES_SMALL; + + iter->sieve_i = 0; + iter->sieve_num = 0; + iter->sieve_a = 0; + iter->sieve_b = 0; + iter->sieve = NULL; +} diff --git a/external/flint-2.4.3/ulong_extras/primes_jump_after.c b/external/flint-2.4.3/ulong_extras/primes_jump_after.c new file mode 100644 index 0000000..e65b492 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/primes_jump_after.c @@ -0,0 +1,43 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 +#include "ulong_extras.h" + +void +n_primes_jump_after(n_primes_t iter, mp_limb_t n) +{ + if (n < iter->small_primes[iter->small_num - 1]) + { + iter->small_i = n_prime_pi(n); + iter->sieve_a = iter->sieve_b = iter->sieve_num = 0; + } + else + { + iter->small_i = iter->small_num; + n_primes_sieve_range(iter, n + 1, + n + 1 + FLINT_MIN(n, FLINT_SIEVE_SIZE) - 2); + } +} diff --git a/external/flint-2.4.3/ulong_extras/primes_sieve_range.c b/external/flint-2.4.3/ulong_extras/primes_sieve_range.c new file mode 100644 index 0000000..4c36efa --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/primes_sieve_range.c @@ -0,0 +1,107 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 +#include +#include "flint.h" +#include "ulong_extras.h" + +static void +mark(char * sieve, mp_limb_t a, slong len, mp_limb_t p) +{ + mp_limb_t t; + + t = p * p; + if (t >= a) + { + t = (t - a) / 2; + } + else + { + t = p - ((a - p) / 2) % p; + if (t == p) + t = 0; + } + + while (t < len) + { + sieve[t] = 0; + t += p; + } +} + +void +n_sieve_odd(char * sieve, ulong n, mp_limb_t a, + unsigned int * sieve_primes, mp_limb_t bound) +{ + slong i; + mp_limb_t p; + + for (i = 0; i < n / 2; i++) + sieve[i] = 1; + + i = 0; + while (1) + { + i++; + p = sieve_primes[i]; + if (p > bound) + break; + mark(sieve, a, n / 2, p); + } +} + +void +n_primes_sieve_range(n_primes_t iter, mp_limb_t a, mp_limb_t b) +{ + mp_limb_t bound; + ulong len, odd_len; + + /* a and b must be odd */ + a += (a % 2 == 0); + b -= (b % 2 == 0); + + len = b - a + 2; + odd_len = len / 2; + + if (a < 3 || b < a || len > FLINT_SIEVE_SIZE) + { + flint_printf("invalid sieve range %wu,%wu!\n", a, b); + abort(); + } + + bound = n_sqrt(b) + 1; + + if (iter->sieve == NULL) + iter->sieve = flint_malloc(FLINT_SIEVE_SIZE / 2 * sizeof(char)); + + n_primes_extend_small(iter, bound); + n_sieve_odd(iter->sieve, len, a, iter->small_primes, bound); + + iter->sieve_i = 0; + iter->sieve_num = odd_len; + iter->sieve_a = a; + iter->sieve_b = b; +} diff --git a/external/flint-2.4.3/ulong_extras/primitive_root_prime.c b/external/flint-2.4.3/ulong_extras/primitive_root_prime.c new file mode 100644 index 0000000..ee5ebff --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/primitive_root_prime.c @@ -0,0 +1,78 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +mp_limb_t n_primitive_root_prime_prefactor(mp_limb_t p, n_factor_t * factors) +{ + slong i; + int found; + mp_limb_t result, a, pm1; + double pinv; + + if (p == 2) + { + return 1; + } + + pm1 = p - 1; + pinv = n_precompute_inverse(p); + + for (a = 2; a < p; a++) + { + found = 1; + for (i = 0; i < factors->num; i++) + { + result = n_powmod_precomp(a, pm1 / factors->p[i], p, pinv); + if (result == 1) + { + found = 0; + break; + } + } + if (found) + { + return a; + } + } + flint_printf("Exception (n_primitive_root_prime_prefactor). root not found.\n"); + abort(); +} + +mp_limb_t n_primitive_root_prime(mp_limb_t p) +{ + mp_limb_t a; + n_factor_t factors; + + n_factor_init(&factors); + n_factor(&factors, p - 1, 1); + + a = n_primitive_root_prime_prefactor(p, &factors); + + return a; +} diff --git a/external/flint-2.4.3/ulong_extras/profile/p-factor.c b/external/flint-2.4.3/ulong_extras/profile/p-factor.c new file mode 100644 index 0000000..101ac9b --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/profile/p-factor.c @@ -0,0 +1,107 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright 2009 William Hart + +******************************************************************************/ + +#include +#include +#include "profiler.h" +#include "flint.h" +#include "ulong_extras.h" + +#define ITERS 1000 + +typedef struct +{ + ulong * composites; + mp_bitcnt_t bits; +} fac_one_line_t; + +void sample(void * arg, ulong count) +{ + fac_one_line_t * params = (fac_one_line_t *) arg; + mp_bitcnt_t bits = params->bits; + ulong i, j, res, primes = (WORD(1)<<(bits/3))/10 + 1; + n_factor_t factors; + mp_limb_t n2; + + for (i = 0; i < count; i++) + { + prof_start(); + for (j = 0; j < ITERS; j++) + { + /*n_factor_init(&factors); + n_factor(&factors, params->composites[j & 1023], 0); + if ((factors.num == 0) || (factors.num == 1 && factors.exp[0] < 2)) + flint_printf("Error %wd\n", params->composites[j & 1023]);*/ + n2 = n_factor_lehman(params->composites[j & 1023]); + if (n2 == params->composites[j & 1023]) + flint_printf("Error n = %wd\n", params->composites[j & 1023]); + } + prof_stop(); + } +} + +void fill_array(ulong * ret, mp_bitcnt_t bits, flint_rand_t state) +{ + ulong n; + n_factor_t factors; + ulong i, primes = (1<<(bits/3))/10 + 1; + + for (i = 0; i < 1024; i++) + { + do + { + n_factor_init(&factors); + n = n_randbits(state, bits); + } while (n_is_probabprime(n) || (n_factor_trial(&factors, n, primes) != n)); + ret[i] = n; + } + +} + +int main(void) +{ + double min, max; + fac_one_line_t params; + FLINT_TEST_INIT(state); + int i; + + + params.composites = flint_malloc(1024*sizeof(ulong)); + + flint_printf("factor_one_line:\n"); + + for (i = 4; i <= 64; i++) + { + fill_array(params.composites, i, state); + params.bits = i; + prof_repeat(&min, &max, sample, ¶ms); + flint_printf("bits = %d, time is %.3f us\n", + i, max/(double)ITERS); + } + + flint_randclear(state); + flint_free(params.composites); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/profile/p-factor_pp1.c b/external/flint-2.4.3/ulong_extras/profile/p-factor_pp1.c new file mode 100644 index 0000000..2706199 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/profile/p-factor_pp1.c @@ -0,0 +1,72 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright 2012 William Hart + +******************************************************************************/ + +#include +#include +#include "profiler.h" +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + ulong c; + ulong B1; + mp_limb_t n, p; + + FLINT_TEST_INIT(state); + + + while(1) + { + flint_printf("Enter number to be factored: "); fflush(stdout); + if (!flint_scanf("%wu", &n)) + { + flint_printf("Read failed\n"); + abort(); + } + + flint_printf("Enter B1: "); fflush(stdout); + if (!flint_scanf("%wu", &B1)) + { + flint_printf("Read failed\n"); + abort(); + } + + do + { + c = n_randint(state, n); + } while (c <= UWORD(2)); + + p = n_factor_pp1(n, B1, c); + if (p >= 2) + flint_printf("Factor: %wu\n", p); + else + flint_printf("Factor not found!\n"); + } while(1); + + flint_randclear(state); + + return 0; +} \ No newline at end of file diff --git a/external/flint-2.4.3/ulong_extras/profile/p-is_probabprime_BPSW.c b/external/flint-2.4.3/ulong_extras/profile/p-is_probabprime_BPSW.c new file mode 100644 index 0000000..b7a1d87 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/profile/p-is_probabprime_BPSW.c @@ -0,0 +1,81 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright 2009 William Hart + +******************************************************************************/ + +#include +#include +#include "profiler.h" +#include "flint.h" +#include "ulong_extras.h" + +typedef struct +{ + ulong bits; +} BPSW_t; + +void sample(void * arg, ulong count) +{ + BPSW_t * params = (BPSW_t *) arg; + ulong bits = params->bits; + ulong i; + mp_limb_t n, d, r, norm; + double dpre; + FLINT_TEST_INIT(state); + + + for (i = 0; i < count; i++) + { + int j, res = 1; + d = n_randbits(state, bits); + while (!n_is_prime(d)) d++; + + prof_start(); + for (j = 0; j < 1000000; j++) + res &= n_is_probabprime_BPSW(d); + prof_stop(); + + if (!res) flint_printf("Error\n"); + } + + flint_randclear(state); +} + +int main(void) +{ + double min, max; + BPSW_t params; + int i; + + flint_printf("is_probabprime_BPSW:\n"); + + for (i = 1; i <= 64; i++) + { + params.bits = i; + prof_repeat(&min, &max, sample, ¶ms); + flint_printf("bits = %d, min time is %.3f cycles, max time is %.3f cycles\n", + i, (min/(double)FLINT_CLOCK_SCALE_FACTOR)/1000000, (max/(double)FLINT_CLOCK_SCALE_FACTOR)/1000000); + } + + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/profile/p-lll_mod_preinv.c b/external/flint-2.4.3/ulong_extras/profile/p-lll_mod_preinv.c new file mode 100644 index 0000000..05e93cf --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/profile/p-lll_mod_preinv.c @@ -0,0 +1,108 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright 2010 William Hart + +******************************************************************************/ + +#include +#include +#include "profiler.h" +#include "flint.h" +#include "ulong_extras.h" + +typedef struct +{ + mp_bitcnt_t bits; + ulong type; +} info_t; + +void sample(void * arg, ulong count) +{ + mp_limb_t n, d, dinv, r = 0, norm; + double dpre; + info_t * info = (info_t *) arg; + mp_bitcnt_t bits = info->bits; + ulong type = info->type; + ulong i; + FLINT_TEST_INIT(state); + + + mp_ptr arr = (mp_ptr) flint_malloc(1024*sizeof(mp_limb_t)); + mp_ptr arr2 = (mp_ptr) flint_malloc(1024*sizeof(mp_limb_t)); + + for (i = 0; i < count; i++) + { + int j; + d = n_randbits(state, bits); + if (d == UWORD(0)) d++; + + dinv = n_preinvert_limb(d); + + for (j = 0; j < 1024; j++) + { + arr[j] = n_randbits(state, FLINT_BITS); + arr2[j] = n_randint(state, n); + } + + switch (type) + { + case 1: + + prof_start(); + for (mp_size_t j = 0; j < UWORD(10000); j++) + { + r += n_lll_mod_preinv(arr2[j&1023], arr[j&1023], arr[(j+1)&1023], d, dinv); + } + prof_stop(); + + break; + } + + } + + if (r == UWORD(9879875897)) abort(); + + flint_randclear(state); + flint_free(arr); + flint_free(arr2); +} + +int main(void) +{ + double min1, min2, min3, min4, min5, max; + info_t info; + int i; + + for (i = FLINT_BITS/2 + 1; i <= FLINT_BITS; i++) + { + info.bits = i; + info.type = 1; + prof_repeat(&min1, &max, sample, (void *) &info); + + flint_printf("bits %d, ll_inv %.1f c/l\n", + i, + (min1/(double)FLINT_CLOCK_SCALE_FACTOR)/10000 + ); + } + + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/profile/p-mod2_precomp.c b/external/flint-2.4.3/ulong_extras/profile/p-mod2_precomp.c new file mode 100644 index 0000000..4ca9abb --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/profile/p-mod2_precomp.c @@ -0,0 +1,78 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright 2009 William Hart + +******************************************************************************/ + +#include +#include +#include "profiler.h" +#include "flint.h" +#include "ulong_extras.h" + +void sample(void * arg, ulong count) +{ + mp_limb_t n, d, r = 0; + double dpre; + ulong i; + mp_ptr array = (mp_ptr) flint_malloc(1024*sizeof(mp_limb_t)); + FLINT_TEST_INIT(state); + + + for (i = 0; i < count; i++) + { + int j; + d = n_randtest(state); + if (d == UWORD(0)) d++; + + dpre = n_precompute_inverse(d); + + for (j = 0; j < 1024; j++) + { + array[j] = n_randtest(state); + } + + prof_start(); + for (j = 0; j < 10000; j++) + { + r += n_mod2_precomp(array[j&1023], d, dpre); + } + prof_stop(); + } + + if (r == 0) abort(); + + flint_randclear(state); + flint_free(array); +} + +int main(void) +{ + double min, max; + + prof_repeat(&min, &max, sample, NULL); + + flint_printf("mod2_precomp min time is %.3f cycles, max time is %.3f cycles\n", + (min/(double)FLINT_CLOCK_SCALE_FACTOR)/10000.0, (max/(double)FLINT_CLOCK_SCALE_FACTOR)/10000.0); + + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/profile/p-mod2_preinv.c b/external/flint-2.4.3/ulong_extras/profile/p-mod2_preinv.c new file mode 100644 index 0000000..2981678 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/profile/p-mod2_preinv.c @@ -0,0 +1,183 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright 2010 William Hart + +******************************************************************************/ + +#include +#include +#include "profiler.h" +#include "flint.h" +#include "ulong_extras.h" + +typedef struct +{ + mp_bitcnt_t bits; + ulong type; +} info_t; + +void sample(void * arg, ulong count) +{ + mp_limb_t n, d, dinv, r = 0, norm; + double dpre; + info_t * info = (info_t *) arg; + mp_bitcnt_t bits = info->bits; + ulong type = info->type; + ulong i; + mp_ptr arr = (mp_ptr) flint_malloc(1024*sizeof(mp_limb_t)); + FLINT_TEST_INIT(state); + + + for (i = 0; i < count; i++) + { + int j; + d = n_randbits(state, bits); + if (d == UWORD(0)) d++; + + dinv = n_preinvert_limb(d); + dpre = n_precompute_inverse(d); + + for (j = 0; j < 1024; j++) + { + arr[j] = n_randbits(state, FLINT_BITS); + } + + switch (type) + { + /*case 1: + + prof_start(); + for (mp_size_t j = 0; j < UWORD(10000); j++) + { + r += n_empty(arr[j&1023], d, dinv); + } + prof_stop(); + + break;*/ + + case 2: + + prof_start(); + for (j = 0; j < 10000; j++) + { + r += n_mod2_preinv(arr[j&1023], d, dinv); + } + prof_stop(); + + break; + + /*case 3: + + prof_start(); + for (mp_size_t j = 0; j < UWORD(10000); j++) + { + r += n_mod3_preinv(arr[j&1023], d, dinv); + } + prof_stop(); + + break;*/ + + case 4: + + prof_start(); + for (j = 0; j < 10000; j++) + { + r += n_mod2_precomp(arr[j&1023], d, dpre); + } + prof_stop(); + + break; + + case 5: + + prof_start(); + for (j = 0; j < 10000; j++) + { + r += n_mod_precomp(arr[j&1023], d, dpre); + } + prof_stop(); + + break; + } + + } + + if (r == UWORD(9879875897)) abort(); + + flint_randclear(state); + flint_free(arr); +} + +int main(void) +{ + double min1, min2, min3, min4, min5, max; + info_t info; + int i; + + for (i = 1; i <= FLINT_BITS; i++) + { + info.bits = i; + + /* + info.type = 1; + prof_repeat(&min1, &max, sample, (void *) &info); + */ + + info.type = 2; + prof_repeat(&min2, &max, sample, (void *) &info); + + /* + info.type = 3; + prof_repeat(&min3, &max, sample, (void *) &info); + */ + + info.type = 4; + prof_repeat(&min4, &max, sample, (void *) &info); + + if (i >= 32 && i <= 53) + { + info.type = 5; + prof_repeat(&min5, &max, sample, (void *) &info); + + flint_printf("bits %d, inv2 %.1f c/l, pre2 %.1f c/l, pre %.1f c/l\n", + i, + /* (min1/(double)FLINT_CLOCK_SCALE_FACTOR)/10000, */ + (min2/(double)FLINT_CLOCK_SCALE_FACTOR)/10000, + /* (min3/(double)FLINT_CLOCK_SCALE_FACTOR)/10000, */ + (min4/(double)FLINT_CLOCK_SCALE_FACTOR)/10000, + (min5/(double)FLINT_CLOCK_SCALE_FACTOR)/10000 + ); + + } else + { + flint_printf("bits %d, inv2 %.1f c/l, pre2 %.1f c/l\n", + i, + /* (min1/(double)FLINT_CLOCK_SCALE_FACTOR)/10000, */ + (min2/(double)FLINT_CLOCK_SCALE_FACTOR)/10000, + /* (min3/(double)FLINT_CLOCK_SCALE_FACTOR)/10000, */ + (min4/(double)FLINT_CLOCK_SCALE_FACTOR)/10000 + ); + } + } + + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/profile/p-mod_precomp.c b/external/flint-2.4.3/ulong_extras/profile/p-mod_precomp.c new file mode 100644 index 0000000..717667c --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/profile/p-mod_precomp.c @@ -0,0 +1,76 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright 2009 William Hart + +******************************************************************************/ + +#include +#include +#include "profiler.h" +#include "flint.h" +#include "ulong_extras.h" + +void sample(void * arg, ulong count) +{ + mp_limb_t n, d, r, norm, bits; + double dpre; + ulong i; + mp_ptr array = (mp_ptr) flint_malloc(1000*sizeof(mp_limb_t)); + FLINT_TEST_INIT(state); + + + for (i = 0; i < count; i++) + { + int j; + bits = n_randint(state, 53) + 1; + d = n_randbits(state, bits); + dpre = n_precompute_inverse(d); + + for (j = 0; j < 1000; j++) + { + if (bits <= 32) array[j] = n_randint(state, d*d); + else array[j] = n_randtest(state); + } + + prof_start(); + for (j = 0; j < 1000; j++) + { + r = n_mod_precomp(array[j], d, dpre); + } + prof_stop(); + } + + flint_randclear(state); + flint_free(array); +} + +int main(void) +{ + double min, max; + + prof_repeat(&min, &max, sample, NULL); + + flint_printf("mod_precomp min time is %.3f cycles, max time is %.3f cycles\n", + (min/(double)FLINT_CLOCK_SCALE_FACTOR)/1000, (max/(double)FLINT_CLOCK_SCALE_FACTOR)/1000); + + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/profile/p-mulmod2_preinv.c b/external/flint-2.4.3/ulong_extras/profile/p-mulmod2_preinv.c new file mode 100644 index 0000000..221c28c --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/profile/p-mulmod2_preinv.c @@ -0,0 +1,75 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright 2009 William Hart + +******************************************************************************/ + +#include +#include +#include "profiler.h" +#include "flint.h" +#include "ulong_extras.h" + +void sample(void * arg, ulong count) +{ + mp_limb_t a, b, d, r, norm, dinv; + mp_ptr array = (mp_ptr) flint_malloc(1000*sizeof(mp_limb_t)); + ulong i; + FLINT_TEST_INIT(state); + + + for (i = 0; i < count; i++) + { + int j; + mp_limb_t bits = n_randint(state, 53) + 1; + d = n_randbits(state, bits); + a = n_randint(state, d); + dinv = n_preinvert_limb(d); + + for (j = 0; j < 1000; j++) + { + array[j] = n_randint(state, d); + } + + prof_start(); + for (j = 0; j < 1000; j++) + { + r = n_mulmod2_preinv(a, array[j], d, dinv); + } + prof_stop(); + } + + flint_randclear(state); + flint_free(array); +} + +int main(void) +{ + double min, max; + + prof_repeat(&min, &max, sample, NULL); + + flint_printf("mulmod2_precomp min time is %.3f cycles, max time is %.3f cycles\n", + (min/(double)FLINT_CLOCK_SCALE_FACTOR)/1000, (max/(double)FLINT_CLOCK_SCALE_FACTOR)/1000); + + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/profile/p-mulmod_precomp.c b/external/flint-2.4.3/ulong_extras/profile/p-mulmod_precomp.c new file mode 100644 index 0000000..579d351 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/profile/p-mulmod_precomp.c @@ -0,0 +1,76 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright 2009 William Hart + +******************************************************************************/ + +#include +#include +#include "profiler.h" +#include "flint.h" +#include "ulong_extras.h" + +void sample(void * arg, ulong count) +{ + ulong i; + mp_limb_t a, b, d, r; + double dpre; + mp_ptr array = (mp_ptr) flint_malloc(1000*sizeof(mp_limb_t)); + FLINT_TEST_INIT(state); + + + for (i = 0; i < count; i++) + { + int j; + mp_limb_t bits = n_randint(state, 53) + 1; + d = n_randbits(state, bits); + a = n_randint(state, d); + dpre = n_precompute_inverse(d); + + for (j = 0; j < 1000; j++) + { + array[i] = n_randint(state, d); + } + + prof_start(); + for (j = 0; j < 1000; j++) + { + r = n_mulmod_precomp(a, array[j], d, dpre); + } + prof_stop(); + } + + flint_randclear(state); + flint_free(array); +} + +int main(void) +{ + double min, max; + + prof_repeat(&min, &max, sample, NULL); + + flint_printf("mulmod_precomp min time is %.3f cycles, max time is %.3f cycles\n", + (min/(double)FLINT_CLOCK_SCALE_FACTOR)/1000, (max/(double)FLINT_CLOCK_SCALE_FACTOR)/1000); + + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/profile/timings.txt b/external/flint-2.4.3/ulong_extras/profile/timings.txt new file mode 100644 index 0000000..ea723c6 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/profile/timings.txt @@ -0,0 +1,172 @@ +K10-2: + +Comparing an empty function with the old n_mod2_preinv, the new n_mod2_preinv, n_mod2_precomp and n_mod_precomp. + +The timings are all for a%n with a of FLINT_BITS bits and n of the given number of bits. + +bits 1, empty 12.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 73.6 c/l +bits 2, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 74.5 c/l +bits 3, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 71.4 c/l +bits 4, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 68.1 c/l +bits 5, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 67.4 c/l +bits 6, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 68.8 c/l +bits 7, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 67.7 c/l +bits 8, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 69.7 c/l +bits 9, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 71.4 c/l +bits 10, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 71.5 c/l +bits 11, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 61.4 c/l +bits 12, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 52.2 c/l +bits 13, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 46.1 c/l +bits 14, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 40.1 c/l +bits 15, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 37.5 c/l +bits 16, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 36.3 c/l +bits 17, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 35.7 c/l +bits 18, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 35.4 c/l +bits 19, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 35.2 c/l +bits 20, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 35.1 c/l +bits 21, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 35.1 c/l +bits 22, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 35.0 c/l +bits 23, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 35.0 c/l +bits 24, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 35.0 c/l +bits 25, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 35.0 c/l +bits 26, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 35.0 c/l +bits 27, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 35.0 c/l +bits 28, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 35.0 c/l +bits 29, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 35.0 c/l +bits 30, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 35.0 c/l +bits 31, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 35.0 c/l +bits 32, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 35.0 c/l, pre 29.0 c/l +bits 33, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 35.0 c/l, pre 29.0 c/l +bits 34, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 35.0 c/l, pre 29.0 c/l +bits 35, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 35.0 c/l, pre 29.0 c/l +bits 36, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 35.0 c/l, pre 29.0 c/l +bits 37, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 35.0 c/l, pre 29.0 c/l +bits 38, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 35.0 c/l, pre 29.0 c/l +bits 39, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 35.0 c/l, pre 29.0 c/l +bits 40, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 35.0 c/l, pre 29.0 c/l +bits 41, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 35.0 c/l, pre 29.0 c/l +bits 42, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 35.0 c/l, pre 29.0 c/l +bits 43, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 35.0 c/l, pre 29.0 c/l +bits 44, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 35.0 c/l, pre 29.0 c/l +bits 45, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 35.0 c/l, pre 29.0 c/l +bits 46, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 35.0 c/l, pre 29.0 c/l +bits 47, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 35.0 c/l, pre 29.0 c/l +bits 48, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 35.0 c/l, pre 29.0 c/l +bits 49, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 35.0 c/l, pre 29.0 c/l +bits 50, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 35.0 c/l, pre 29.0 c/l +bits 51, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 35.0 c/l, pre 29.0 c/l +bits 52, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 35.0 c/l, pre 29.0 c/l +bits 53, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 35.0 c/l, pre 29.0 c/l +bits 54, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 35.0 c/l +bits 55, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 35.0 c/l +bits 56, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 35.0 c/l +bits 57, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 35.0 c/l +bits 58, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 35.0 c/l +bits 59, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 35.0 c/l +bits 60, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 35.0 c/l +bits 61, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 35.0 c/l +bits 62, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 35.0 c/l +bits 63, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 35.0 c/l +bits 64, empty 9.0 c/l, old 27.0 c/l, new 21.0 c/l, pre2 16.2 c/l + +timings for n_ll_mod_preinv (old function was about 60 c/l (note empty function takes about 11 cycles) + +bits 1, ll_inv 43.0 c/l +bits 2, ll_inv 43.1 c/l +bits 3, ll_inv 41.4 c/l +bits 4, ll_inv 40.5 c/l +bits 5, ll_inv 39.1 c/l +bits 6, ll_inv 39.9 c/l +bits 7, ll_inv 39.3 c/l +bits 8, ll_inv 39.5 c/l +bits 9, ll_inv 39.4 c/l +bits 10, ll_inv 39.3 c/l +bits 11, ll_inv 38.9 c/l +bits 12, ll_inv 38.5 c/l +bits 13, ll_inv 40.4 c/l +bits 14, ll_inv 37.8 c/l +bits 15, ll_inv 39.0 c/l +bits 16, ll_inv 38.9 c/l +bits 17, ll_inv 39.0 c/l +bits 18, ll_inv 39.6 c/l +bits 19, ll_inv 38.1 c/l +bits 20, ll_inv 38.9 c/l +bits 21, ll_inv 39.3 c/l +bits 22, ll_inv 38.4 c/l +bits 23, ll_inv 39.1 c/l +bits 24, ll_inv 39.5 c/l +bits 25, ll_inv 39.2 c/l +bits 26, ll_inv 38.9 c/l +bits 27, ll_inv 39.8 c/l +bits 28, ll_inv 38.9 c/l +bits 29, ll_inv 40.0 c/l +bits 30, ll_inv 38.3 c/l +bits 31, ll_inv 39.3 c/l +bits 32, ll_inv 39.1 c/l +bits 33, ll_inv 39.2 c/l +bits 34, ll_inv 39.8 c/l +bits 35, ll_inv 39.8 c/l +bits 36, ll_inv 39.1 c/l +bits 37, ll_inv 39.4 c/l +bits 38, ll_inv 38.5 c/l +bits 39, ll_inv 39.1 c/l +bits 40, ll_inv 39.5 c/l +bits 41, ll_inv 39.5 c/l +bits 42, ll_inv 40.5 c/l +bits 43, ll_inv 38.5 c/l +bits 44, ll_inv 37.6 c/l +bits 45, ll_inv 38.8 c/l +bits 46, ll_inv 38.1 c/l +bits 47, ll_inv 39.5 c/l +bits 48, ll_inv 38.9 c/l +bits 49, ll_inv 39.5 c/l +bits 50, ll_inv 39.1 c/l +bits 51, ll_inv 38.5 c/l +bits 52, ll_inv 39.3 c/l +bits 53, ll_inv 38.5 c/l +bits 54, ll_inv 40.0 c/l +bits 55, ll_inv 38.9 c/l +bits 56, ll_inv 39.4 c/l +bits 57, ll_inv 38.4 c/l +bits 58, ll_inv 38.6 c/l +bits 59, ll_inv 39.0 c/l +bits 60, ll_inv 39.5 c/l +bits 61, ll_inv 38.8 c/l +bits 62, ll_inv 39.4 c/l +bits 63, ll_inv 38.4 c/l +bits 64, ll_inv 38.1 c/l + +n_lll_mod_preinv (there was no old function, but it would have been something like 113 cycles) - empty takes 13 cycles + +bits 33, ll_inv 135.1 c/l +bits 34, ll_inv 135.2 c/l +bits 35, ll_inv 45.1 c/l +bits 36, ll_inv 45.1 c/l +bits 37, ll_inv 45.0 c/l +bits 38, ll_inv 45.1 c/l +bits 39, ll_inv 45.1 c/l +bits 40, ll_inv 45.1 c/l +bits 41, ll_inv 45.1 c/l +bits 42, ll_inv 45.0 c/l +bits 43, ll_inv 45.0 c/l +bits 44, ll_inv 45.1 c/l +bits 45, ll_inv 45.1 c/l +bits 46, ll_inv 45.1 c/l +bits 47, ll_inv 45.1 c/l +bits 48, ll_inv 45.1 c/l +bits 49, ll_inv 45.1 c/l +bits 50, ll_inv 45.1 c/l +bits 51, ll_inv 45.0 c/l +bits 52, ll_inv 45.1 c/l +bits 53, ll_inv 45.0 c/l +bits 54, ll_inv 45.1 c/l +bits 55, ll_inv 45.1 c/l +bits 56, ll_inv 45.0 c/l +bits 57, ll_inv 45.0 c/l +bits 58, ll_inv 45.1 c/l +bits 59, ll_inv 45.1 c/l +bits 60, ll_inv 45.1 c/l +bits 61, ll_inv 45.1 c/l +bits 62, ll_inv 45.1 c/l +bits 63, ll_inv 45.1 c/l +bits 64, ll_inv 44.8 c/l diff --git a/external/flint-2.4.3/ulong_extras/randbits.c b/external/flint-2.4.3/ulong_extras/randbits.c new file mode 100644 index 0000000..121bd3a --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/randbits.c @@ -0,0 +1,34 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" + +mp_limb_t n_randbits(flint_rand_t state, unsigned int bits) +{ + if (bits == 0) return UWORD(0); + else return (UWORD(1) << (bits - 1)) | n_randint(state, l_shift(UWORD(1), bits)); +} diff --git a/external/flint-2.4.3/ulong_extras/randint.c b/external/flint-2.4.3/ulong_extras/randint.c new file mode 100644 index 0000000..33fc345 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/randint.c @@ -0,0 +1,34 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" + +mp_limb_t n_randint(flint_rand_t state, mp_limb_t limit) +{ + if (limit == UWORD(0)) return n_randlimb(state); + else return n_randlimb(state) % limit; +} diff --git a/external/flint-2.4.3/ulong_extras/randlimb.c b/external/flint-2.4.3/ulong_extras/randlimb.c new file mode 100644 index 0000000..4978e39 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/randlimb.c @@ -0,0 +1,50 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" + +#if FLINT64 + +mp_limb_t n_randlimb(flint_rand_t state) +{ + state->__randval = (state->__randval*UWORD(13282407956253574709) + UWORD(286824421)); + state->__randval2 = (state->__randval2*UWORD(7557322358563246341) + UWORD(286824421)); + + return (state->__randval>>32) + ((state->__randval2>>32) << 32); +} + +#else + +mp_limb_t n_randlimb(flint_rand_t state) +{ + state->__randval = (state->__randval*UWORD(1543932465) + UWORD(1626832771)); + state->__randval2 = (state->__randval2*UWORD(2495927737) + UWORD(1626832771)); + + return (state->__randval>>16) + ((state->__randval2>>16) << 16); +} + +#endif diff --git a/external/flint-2.4.3/ulong_extras/randprime.c b/external/flint-2.4.3/ulong_extras/randprime.c new file mode 100644 index 0000000..aef2027 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/randprime.c @@ -0,0 +1,73 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007, 2008 William Hart + Copyright (C) 2008 Peter Shrimpton + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#define ulong ulongxx /* interferes with system includes */ +#include +#include +#undef ulong +#define ulong mp_limb_t +#include "flint.h" +#include "ulong_extras.h" + + +mp_limb_t n_randprime(flint_rand_t state, ulong bits, int proved) +{ + mp_limb_t rand; + + if (bits < 2) + { + flint_printf("Exception in n_randprime: attempt to generate prime < 2!\n"); + abort(); + } + + if (bits == FLINT_BITS) + { + do { rand = n_randbits(state, bits); } + while (rand >= UWORD_MAX_PRIME); + + rand = n_nextprime(rand, proved); + } + else if (bits == 2) + { + rand = 2 + n_randint(state, 2); + } + else + { + do + { + rand = n_randbits(state, bits); + rand = n_nextprime(rand, proved); + } while ((rand >> bits) > WORD(0)); + } + + return rand; +} + +mp_limb_t n_randtest_prime(flint_rand_t state, int proved) +{ + return n_randprime(state, 2 + n_randint(state, FLINT_BITS - 1), proved); +} diff --git a/external/flint-2.4.3/ulong_extras/randtest.c b/external/flint-2.4.3/ulong_extras/randtest.c new file mode 100644 index 0000000..f1b76a7 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/randtest.c @@ -0,0 +1,89 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2010 Sebastian Pancratz + +******************************************************************************/ + +#include +#include + +#include "flint.h" +#include "fmpz.h" +#include "ulong_extras.h" + +mp_limb_t n_randtest_bits(flint_rand_t state, int bits) +{ + mp_limb_t m; + mp_limb_t n; + + m = n_randlimb(state); + + if (m & UWORD(7)) + { + n = n_randbits(state, bits); + } + else + { + m >>= 3; + + switch (m & UWORD(7)) + { + case 0: n = 0; break; + case 1: n = 1; break; + case 2: n = COEFF_MAX; break; + case 3: n = WORD_MAX; break; + case 4: n = UWORD_MAX; break; + case 5: n = (UWORD(1)< +#include "flint.h" +#include "ulong_extras.h" + +int +n_remove(mp_limb_t * n, mp_limb_t p) +{ + int exp, i; + mp_limb_t powp[6]; + mp_limb_t quot, rem; + + if (p == 2) + { + count_trailing_zeros(exp, *n); + if (exp) + (*n) >>= exp; + + return exp; + } + + powp[0] = p; + + for (i = 0; ; i++) + { + if ((*n) < powp[i]) + break; + quot = (*n) / powp[i]; + rem = (*n) - quot * powp[i]; + if (rem != UWORD(0)) + break; + powp[i + 1] = powp[i] * powp[i]; + (*n) = quot; + } + + exp = (1 << i) - 1; + + while (i > 0) + { + i--; + if ((*n) < powp[i]) + continue; + quot = (*n) / powp[i]; + rem = (*n) - quot * powp[i]; + if (rem == UWORD(0)) + { + exp += (UWORD(1) << i); + (*n) = quot; + } + } + + return exp; +} diff --git a/external/flint-2.4.3/ulong_extras/remove2_precomp.c b/external/flint-2.4.3/ulong_extras/remove2_precomp.c new file mode 100644 index 0000000..7c10ad8 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/remove2_precomp.c @@ -0,0 +1,57 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" + +int +n_remove2_precomp(mp_limb_t * n, mp_limb_t p, double ppre) +{ + int exp = 0; + mp_limb_t quot, rem = UWORD(0); + + if (p == 2) + { + count_trailing_zeros(exp, *n); + if (exp) + (*n) >>= exp; + + return exp; + } + + do + { + if ((*n) < p) + break; + rem = n_divrem2_precomp(", *n, p, ppre); + if (rem) + break; + exp++; + (*n) = quot; + } while (1); + + return exp; +} diff --git a/external/flint-2.4.3/ulong_extras/revbin.c b/external/flint-2.4.3/ulong_extras/revbin.c new file mode 100644 index 0000000..baf8733 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/revbin.c @@ -0,0 +1,56 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" + +const ulong flint_revtab0[1] = { 0 }; +const ulong flint_revtab1[2] = { 0, 1 }; +const ulong flint_revtab2[4] = { 0, 2, 1, 3 }; +const ulong flint_revtab3[8] = { 0, 4, 2, 6, 1, 5, 3, 7 }; +const ulong flint_revtab4[16] = { 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15 }; + +const ulong * flint_revtab[5] = { flint_revtab0, flint_revtab1, flint_revtab2, flint_revtab3, flint_revtab4 }; + +/* + computes the reverse binary of a binary number of the given number of bits + */ +ulong n_revbin(ulong in, ulong bits) +{ + ulong out = 0, i; + + if (bits <= 4) + return flint_revtab[bits][in]; + + for (i = 0; i < bits; i++) + { + out <<= 1; + out += (in & 1); + in >>= 1; + } + + return out; +} diff --git a/external/flint-2.4.3/ulong_extras/sizeinbase.c b/external/flint-2.4.3/ulong_extras/sizeinbase.c new file mode 100644 index 0000000..a0357c3 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/sizeinbase.c @@ -0,0 +1,40 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#define ulong ulongxx /* interferes with system includes */ +#include +#undef ulong +#define ulong mp_limb_t +#include "flint.h" +#include "ulong_extras.h" + +int n_sizeinbase(mp_limb_t n, int base) +{ + if (n == 0) + return 1; + + return n_flog(n, base) + 1; +} diff --git a/external/flint-2.4.3/ulong_extras/sqrt.c b/external/flint-2.4.3/ulong_extras/sqrt.c new file mode 100644 index 0000000..f955a8c --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/sqrt.c @@ -0,0 +1,44 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#define ulong ulongxx /* interferes with system includes */ +#include +#undef ulong +#include "flint.h" +#include "ulong_extras.h" + +mp_limb_t n_sqrt(mp_limb_t a) +{ + mp_limb_t is; + + is = (mp_limb_t) sqrt((double) a); + + is -= (is*is > a); +#if FLINT64 + if (is == UWORD(4294967296)) is--; +#endif + return is; +} diff --git a/external/flint-2.4.3/ulong_extras/sqrtmod.c b/external/flint-2.4.3/ulong_extras/sqrtmod.c new file mode 100644 index 0000000..8718fca --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/sqrtmod.c @@ -0,0 +1,92 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" + +mp_limb_t n_sqrtmod(mp_limb_t a, mp_limb_t p) +{ + slong i, r, m; + mp_limb_t p1, k, b, g, bpow, gpow, res; + mp_limb_t pinv; + + if (a <= 1) + { + return a; + } + + pinv = n_preinvert_limb(p); + + if (n_jacobi_unsigned(a, p) == -1) + return 0; + + if ((p & UWORD(3)) == 3) + { + return n_powmod2_ui_preinv(a, (p + 1) / 4, p, pinv); + } + + r = 0; + p1 = p - 1; + + do { + p1 >>= UWORD(1); + r++; + } while ((p1 & UWORD(1)) == 0); + + b = n_powmod2_ui_preinv(a, p1, p, pinv); + + for (k = 2; ; k++) + { + if (n_jacobi_unsigned(k, p) == -1) break; + } + + g = n_powmod2_ui_preinv(k, p1, p, pinv); + res = n_powmod2_ui_preinv(a, (p1 + 1) / 2, p, pinv); + + while (b != 1) + { + bpow = b; + m = 0; + do + { + bpow = n_mulmod2_preinv(bpow, bpow, p, pinv); + m++; + } while (m < r && bpow != 1); + gpow = g; + for (i = 1; i < r - m; i++) + { + gpow = n_mulmod2_preinv(gpow, gpow, p, pinv); + } + res = n_mulmod2_preinv(res, gpow, p, pinv); + g = n_mulmod2_preinv(gpow, gpow, p, pinv); + b = n_mulmod2_preinv(b, g, p, pinv); + r = m; + } + + return res; +} + diff --git a/external/flint-2.4.3/ulong_extras/sqrtmod_primepow.c b/external/flint-2.4.3/ulong_extras/sqrtmod_primepow.c new file mode 100644 index 0000000..e9c307b --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/sqrtmod_primepow.c @@ -0,0 +1,345 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2012 William Hart + +******************************************************************************/ + +#define ulong ulongxx /* interferes with system includes */ +#include +#include +#undef ulong +#define ulong mp_limb_t +#include +#include "flint.h" +#include "ulong_extras.h" + +slong n_sqrtmod_2pow(mp_limb_t ** sqrt, mp_limb_t a, slong exp) +{ + mp_limb_t r = (a & 1); + mp_limb_t * s; + + if (exp == 0) /* special case for sqrt of 0 mod 1 */ + { + *sqrt = flint_malloc(sizeof(mp_limb_t)); + (*sqrt)[0] = 0; + + return 1; + } + + if (exp == 1) /* special case mod 2 */ + { + *sqrt = flint_malloc(sizeof(mp_limb_t)); + + if (r) (*sqrt)[0] = 1; + else (*sqrt)[0] = 0; + + return 1; + } + + if (exp == 2) /* special case mod 4 */ + { + r = (a & 3); + + if (r < 2) /* 0, 1 mod 4 */ + { + *sqrt = flint_malloc(sizeof(mp_limb_t)*2); + + (*sqrt)[0] = r; + (*sqrt)[1] = r + 2; + + return 2; + } else /* 2, 3 mod 4 */ + { + *sqrt = NULL; + return 0; + } + } + + if (r) /* a is odd */ + { + mp_limb_t roots[2]; + slong i, ex, pow; + + if ((a & 7) != 1) /* check square root exists */ + { + *sqrt = NULL; + return 0; + } + + roots[0] = 1; /* one of each pair of square roots mod 8 */ + roots[1] = 3; + + pow = 8; + for (ex = 3; ex < exp; ex++, pow *= 2) /* lift roots */ + { + i = 0; + + r = roots[0]; + if (((r*r) & (2*pow - 1)) == (a & (2*pow - 1))) + roots[i++] = r; + + r = pow - r; + if (((r*r) & (2*pow - 1)) == (a & (2*pow - 1))) + { + roots[i++] = r; + if (i == 2) continue; + } + + r = roots[1]; + if (((r*r) & (2*pow - 1)) == (a & (2*pow - 1))) + { + roots[i++] = r; + if (i == 2) continue; + } + + r = pow - r; + roots[i] = r; + } + + *sqrt = flint_malloc(sizeof(mp_limb_t)*4); + + (*sqrt)[0] = roots[0]; /* write out both pairs of roots */ + (*sqrt)[1] = pow - roots[0]; + (*sqrt)[2] = roots[1]; + (*sqrt)[3] = pow - roots[1]; + + return 4; + } else /* a is even */ + { + slong i, k, num, pow; + + for (k = 2; k <= exp; k++) /* find highest power of 2 dividing a */ + { + if (a & ((UWORD(1)< +#include +#undef ulong +#include +#include "flint.h" +#include "ulong_extras.h" + +/* compute square roots of a modulo m given factorisation of m */ +slong n_sqrtmodn(mp_limb_t ** sqrt, mp_limb_t a, n_factor_t * fac) +{ + mp_limb_t m = 1, minv = 1; + slong i, j, num; + mp_limb_t * x, * sn, * ind, ** s; + + if (fac->num == 0) + { + *sqrt = flint_malloc(sizeof(mp_limb_t)); + (*sqrt)[0] = 0; + return 1; + } + + x = flint_malloc(sizeof(mp_limb_t)*fac->num); + sn = flint_malloc(sizeof(mp_limb_t)*fac->num); + ind = flint_malloc(sizeof(mp_limb_t)*fac->num); + s = flint_malloc(sizeof(mp_limb_t *)*fac->num); + + /* compute prime powers and square roots of a mod x_i = p_i^r_i*/ + num = 1; + for (i = 0; i < fac->num; i++) + { + ind[i] = 0; + x[i] = n_pow(fac->p[i], fac->exp[i]); + sn[i] = n_sqrtmod_primepow(s + i, a % x[i], fac->p[i], fac->exp[i]); + num *= sn[i]; + + if (num == 0) + { + for (j = 0; j < i; j++) + flint_free(s[j]); + flint_free(ind); + flint_free(x); + flint_free(s); + flint_free(sn); + *sqrt = NULL; + return 0; + } + } + + *sqrt = flint_malloc(num*sizeof(mp_limb_t)); + + /* + compute values s_i = 1 mod x_i and s_i = 0 mod x_j for j != i + then replace sqrts a_i with a_i * s_i mod m = x_1*x_2*...*x_n + */ + for (i = 0; i < fac->num; i++) + { + mp_limb_t xp = 1, si; + + /* compute product of x_j for j != i */ + for (j = 0; j < i; j++) + xp *= x[j]; + for (j = i + 1; j < fac->num; j++) + xp *= x[j]; + + /* compute m and precomputed inverse */ + if (i == 0) + { + m = xp*x[i]; + minv = n_preinvert_limb(m); + } + + /* compute s_i */ + si = xp*n_invmod(xp % x[i], x[i]); + + /* a_i*s_i mod m for each sqrt a_i of a mod x_i*/ + for (j = 0; j < sn[i]; j++) + s[i][j] = n_mulmod2_preinv(si, s[i][j], m, minv); + } + + /* + compute all the square roots by computing + sum_{i=0}^{fac->num} s[i][j] for each different permutation + of j's, all modulo m + */ + + for (i = 0; i < num; i++) /* loop through every possibility */ + { + /* compute next root */ + (*sqrt)[i] = 0; + for (j = 0; j < fac->num; j++) + (*sqrt)[i] = n_addmod((*sqrt)[i], s[j][ind[j]], m); + + /* increment to next set of indices */ + for (j = 0; j < fac->num; j++) + { + ind[j]++; + if (ind[j] != sn[j]) + break; + ind[j] = 0; + } + } + + /* clean up */ + for (i = 0; i < fac->num; i++) + flint_free(s[i]); + flint_free(ind); + flint_free(x); + flint_free(s); + flint_free(sn); + + return num; +} + diff --git a/external/flint-2.4.3/ulong_extras/sqrtrem.c b/external/flint-2.4.3/ulong_extras/sqrtrem.c new file mode 100644 index 0000000..65c0359 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/sqrtrem.c @@ -0,0 +1,44 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +mp_limb_t n_sqrtrem(mp_limb_t * r, mp_limb_t a) +{ + mp_limb_t is; + + is = (mp_limb_t) sqrt((double) a); + + is -= (is*is > a); +#if FLINT64 + if (is == UWORD(4294967296)) is--; +#endif + (*r) = a - is*is; + + return is; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-addmod.c b/external/flint-2.4.3/ulong_extras/test/t-addmod.c new file mode 100644 index 0000000..241ee0f --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-addmod.c @@ -0,0 +1,71 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("addmod...."); + fflush(stdout); + + + + for (i = 0; i < 100000 * flint_test_multiplier(); i++) + { + mp_limb_t a, b, d, r1, r2, s1; + + d = n_randtest_not_zero(state); + a = n_randtest(state) % d; + b = n_randtest(state) % d; + + r1 = n_addmod(a, b, d); + + add_ssaaaa(s1, r2, UWORD(0), a, UWORD(0), b); + if (s1) sub_ddmmss(s1, r2, s1, r2, UWORD(0), d); + else if (r2 >= d) r2 -= d; + + result = (r1 == r2); + + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = %wu, b = %wu, d = %wu\n", a, b, d); + flint_printf("r1 = %wu, r2 = %wu\n", r1, r2); + abort(); + } + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-clog.c b/external/flint-2.4.3/ulong_extras/test/t-clog.c new file mode 100644 index 0000000..d707a43 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-clog.c @@ -0,0 +1,69 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("clog...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + mp_limb_t a = 0, b = 0, k, x; + + while (a < 1) + a = n_randtest(state); + while (b < 2) + b = n_randtest(state); + + k = n_clog(a, b); + x = (k > 0) ? n_pow(b, k - 1) : 0; + + result = (x < a && ((k > 0) ? ((a + b - 1) / b <= x) : (a <= 1))); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = %wu\n", a); + flint_printf("b = %wu\n", b); + flint_printf("x = %wu\n", x); + flint_printf("k = %wu\n", k); + } + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-compute_primes.c b/external/flint-2.4.3/ulong_extras/test/t-compute_primes.c new file mode 100644 index 0000000..aae96db --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-compute_primes.c @@ -0,0 +1,88 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main() +{ + slong i, lim = 1000000; + n_primes_t pg; + mp_limb_t * ref_primes; + double * ref_inverses; + FLINT_TEST_INIT(state); + + flint_printf("compute_primes...."); + fflush(stdout); + + + ref_primes = flint_malloc(sizeof(mp_limb_t) * lim); + ref_inverses = flint_malloc(sizeof(double) * lim); + + n_primes_init(pg); + for (i = 0; i < lim; i++) + { + ref_primes[i] = n_primes_next(pg); + ref_inverses[i] = n_precompute_inverse(ref_primes[i]); + } + n_primes_clear(pg); + + for (i = 0; i < 250; i++) + { + slong n; + const mp_limb_t * primes; + const double * inverses; + + n = n_randtest(state) % lim; + + primes = n_primes_arr_readonly(n + 1); + inverses = n_prime_inverses_arr_readonly(n + 1); + + if (primes[n] != ref_primes[n] || inverses[n] != ref_inverses[n]) + { + flint_printf("FAIL!\n"); + flint_printf("n = %wd, p1 = %wu, p2 = %wu\n", n, primes[n], ref_primes[n]); + flint_printf("inv1 = %g, inv2 = %g\n", inverses[n], ref_inverses[n]); + abort(); + } + + if (n_randint(state, 20) == 0) + { + n_cleanup_primes(); + } + } + + flint_free(ref_primes); + flint_free(ref_inverses); + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} + diff --git a/external/flint-2.4.3/ulong_extras/test/t-discrete_log_bsgs.c b/external/flint-2.4.3/ulong_extras/test/t-discrete_log_bsgs.c new file mode 100644 index 0000000..c27589c --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-discrete_log_bsgs.c @@ -0,0 +1,65 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i; + FLINT_TEST_INIT(state); + + flint_printf("discrete_log_bsgs...."); + fflush(stdout); + + flint_randinit(state); + + for (i = 0; i < 1000; i++) + { + mp_limb_t p, root, b, d, result; + double pinv; + + p = n_randprime(state, 20, 1); + pinv = n_precompute_inverse(p); + root = n_primitive_root_prime(p); + b = n_randint(state, p - 1) + 1; + d = n_discrete_log_bsgs(b, root, p); + + result = n_powmod_precomp(root, d, p, pinv); + + if (result != b) + { + flint_printf("FAIL:\n"); + flint_printf("%wu ** (%wu) == %wu != %wu\n", root, d, result, b); + abort(); + } + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; + +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-divrem2_precomp.c b/external/flint-2.4.3/ulong_extras/test/t-divrem2_precomp.c new file mode 100644 index 0000000..0b5bbc1 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-divrem2_precomp.c @@ -0,0 +1,72 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int result; + ulong i; + FLINT_TEST_INIT(state); + + + flint_printf("divrem2_precomp...."); + fflush(stdout); + + for (i = 0; i < 100000 * flint_test_multiplier(); i++) + { + mp_limb_t d, n, r1, r2, q1, q2; + double dpre; + + d = n_randtest(state); + if (d == UWORD(0)) d++; + + n = n_randtest(state); + + dpre = n_precompute_inverse(d); + + r1 = n_divrem2_precomp(&q1, n, d, dpre); + r2 = n%d; + q2 = n/d; + + result = ((r1 == r2) && (q1 == q2)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("n = %wu, d = %wu, dpre = %f\n", n, d, dpre); + flint_printf("q1 = %wu, q2 = %wu, r1 = %wu, r2 = %wu\n", q1, q2, r1, r2); + abort(); + } + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-euler_phi.c b/external/flint-2.4.3/ulong_extras/test/t-euler_phi.c new file mode 100644 index 0000000..9ea4d9e --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-euler_phi.c @@ -0,0 +1,56 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int n, k, t; + + FLINT_TEST_INIT(state); + + flint_printf("euler_phi...."); + fflush(stdout); + + for (n = 0; n < 20 * flint_test_multiplier(); n++) + { + t = 0; + for (k = 1; k <= n; k++) + t += (n_gcd(n, k) == 1); + if (t != n_euler_phi(n)) + { + flint_printf("FAIL:\n"); + flint_printf("phi(%d) = %d, got %wu\n", n, t, n_euler_phi(n)); + abort(); + } + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-factor.c b/external/flint-2.4.3/ulong_extras/test/t-factor.c new file mode 100644 index 0000000..1e90c16 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-factor.c @@ -0,0 +1,95 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, j, result; + FLINT_TEST_INIT(state); + + + flint_printf("factor...."); + fflush(stdout); + + /* Test random numbers */ + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + mp_limb_t n1, n2; + n_factor_t factors; + + n_factor_init(&factors); + + n1 = n_randtest_not_zero(state); + n_factor(&factors, n1, 0); + + n2 = UWORD(1); + for (j = 0; j < factors.num; j++) + { + n2 *= n_pow(factors.p[j], factors.exp[j]); + } + + result = (n1 == n2); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("n1 = %wu, n2 = %wu\n", n1, n2); + abort(); + } + } + + { + mp_limb_t n1, n2; + n_factor_t factors; + + n_factor_init(&factors); + + n1 = UWORD(4253857039); + n_factor(&factors, n1, 0); + + n2 = UWORD(1); + for (j = 0; j < factors.num; j++) + { + n2 *= n_pow(factors.p[j], factors.exp[j]); + } + + result = (n1 == n2); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("n1 = %wu, n2 = %wu\n", n1, n2); + abort(); + } + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-factor_SQUFOF.c b/external/flint-2.4.3/ulong_extras/test/t-factor_SQUFOF.c new file mode 100644 index 0000000..d6e8b10 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-factor_SQUFOF.c @@ -0,0 +1,81 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + ulong count = UWORD(0); + FLINT_TEST_INIT(state); + + + flint_printf("factor_SQUFOF...."); + fflush(stdout); + + for (i = 0; i < 300 * flint_test_multiplier(); i++) /* Test random numbers */ + { + mp_limb_t n1, n2; + + do + { + n1 = n_randtest_bits(state, n_randint(state, FLINT_BITS) + 1); + } while (n_is_prime(n1) || (n1 < UWORD(2))); + +#if FLINT64 + n2 = n_factor_SQUFOF(n1, 10000); +#else + n2 = n_factor_SQUFOF(n1, 2000); +#endif + + if (n2) + { + count++; + result = ((n1%n2) == UWORD(0)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("n1 = %wu, n2 = %wu\n", n1, n2); + abort(); + } + } + } + + if (count < 280 * flint_test_multiplier()) + { + flint_printf("FAIL:\n"); + flint_printf("Only %wu numbers factored\n", count); + abort(); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-factor_lehman.c b/external/flint-2.4.3/ulong_extras/test/t-factor_lehman.c new file mode 100644 index 0000000..00c8bda --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-factor_lehman.c @@ -0,0 +1,107 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("factor_lehman...."); + fflush(stdout); + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) /* Test random numbers */ + { + mp_limb_t n1, n2; + + do + { + n1 = n_randtest_bits(state, n_randint(state, FLINT_BITS) + 1); + } while (n_is_prime(n1) || (n1 < UWORD(2)) +#if FLINT64 /* cannot compute enough primes */ + || (n1 >= UWORD(10000000000000000)) +#endif + ); + + n2 = n_factor_lehman(n1); + + result = ((n1%n2) == UWORD(0) && n1 != n2); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("n1 = %wu, n2 = %wu\n", n1, n2); + abort(); + } + } + + for (i = 0; i < 100 * flint_test_multiplier(); i++) /* Test random products of two primes */ + { + mp_limb_t n1, n2, n3, n, limit; + +#if FLINT64 + limit = UWORD(100000000) - UWORD(100); +#else + limit = UWORD(65535); +#endif + + n1 = n_randtest(state) % (limit + 1); + n2 = n_randtest(state) % (limit + 1); + + n1 = n_nextprime(n1, 1); + n2 = n_nextprime(n2, 1); + + /* test a specific bug */ +#if FLINT64 + if (i == 0) + { + n1 = 72528697; + n2 = 73339073; + } +#endif + + n = n1*n2; + + n3 = n_factor_lehman(n); + + result = ((n%n3) == UWORD(0) && n != n3); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("n = %wd, n3 = %wu\n", n, n3); + abort(); + } + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-factor_one_line.c b/external/flint-2.4.3/ulong_extras/test/t-factor_one_line.c new file mode 100644 index 0000000..d6fbe10 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-factor_one_line.c @@ -0,0 +1,84 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + ulong count = UWORD(0); + FLINT_TEST_INIT(state); + + flint_printf("factor_one_line...."); + fflush(stdout); + + + + for (i = 0; i < 500 * flint_test_multiplier(); i++) /* Test random numbers */ + { + mp_limb_t n1, n2, bits; + + do + { +#if FLINT64 + bits = n_randint(state, 44); +#else + bits = n_randint(state, 20); +#endif + n1 = n_randtest_bits(state, bits + 1); + } while (n_is_prime(n1) || (n1 == UWORD(1))); + + n2 = n_factor_one_line(n1, 50000); + + if (n2) + { + count++; + result = ((n1%n2) == UWORD(0)); + + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("n1 = %wu, n2 = %wu\n", n1, n2); + abort(); + } + } + } + + if (count < 450 * flint_test_multiplier()) + { + flint_printf("FAIL:\n"); + flint_printf("Only %wu numbers factored\n", count); + abort(); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-factor_partial.c b/external/flint-2.4.3/ulong_extras/test/t-factor_partial.c new file mode 100644 index 0000000..5f45d95 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-factor_partial.c @@ -0,0 +1,71 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, j, result; + FLINT_TEST_INIT(state); + + + flint_printf("factor_partial...."); + fflush(stdout); + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) /* Test random numbers */ + { + mp_limb_t n1, n2, prod, limit; + n_factor_t factors; + + n_factor_init(&factors); + + n1 = n_randtest_not_zero(state); + limit = n_sqrt(n1); + n2 = n_factor_partial(&factors, n1, limit, 0); + + prod = 1; + for (j = 0; j < factors.num; j++) + { + prod *= n_pow(factors.p[j], factors.exp[j]); + } + + result = ((n1 == n2*prod) && ((prod > limit) || (n1 == 1))); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("n1 = %wu, n2 = %wu\n", n1, n2); + abort(); + } + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-factor_power235.c b/external/flint-2.4.3/ulong_extras/test/t-factor_power235.c new file mode 100644 index 0000000..285d7c4 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-factor_power235.c @@ -0,0 +1,121 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("factor_power235...."); + fflush(stdout); + + + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) /* Test random squares */ + { + mp_limb_t factor, exp, n1, n2, bits; + + bits = n_randint(state, FLINT_BITS/2) + 1; + n1 = n_randtest_bits(state, bits); + factor = n_factor_power235(&exp, n1*n1); + + n2 = n_pow(factor, exp); + + result = (n1*n1 == n2); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("factor = %wu, exp = %wu\n", factor, exp); + abort(); + } + } + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) /* Test random cubes */ + { + mp_limb_t factor, exp, n1, n2, bits; + + bits = n_randint(state, FLINT_BITS/3) + 1; + n1 = n_randtest_bits(state, bits); + factor = n_factor_power235(&exp, n1*n1*n1); + + n2 = n_pow(factor, exp); + + result = (n1*n1*n1 == n2); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("factor = %wu, exp = %wu\n", factor, exp); + abort(); + } + } + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) /* Test random fifth powers */ + { + mp_limb_t factor, exp, n1, n2, bits; + + bits = n_randint(state, FLINT_BITS/5) + 1; + n1 = n_randtest_bits(state, bits); + factor = n_factor_power235(&exp, n1*n1*n1*n1*n1); + + n2 = n_pow(factor, exp); + + result = (n1*n1*n1*n1*n1 == n2); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("factor = %wu, exp = %wu\n", factor, exp); + abort(); + } + } + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) /* Test non 235-powers */ + { + mp_limb_t exp, n1; + + do + { + n1 = n_randtest(state); + } while (n_is_perfect_power235(n1)); + + result = (!n_factor_power235(&exp, n1)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("n1 = %wu, exp = %wu\n", n1, exp); + abort(); + } + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-factor_pp1.c b/external/flint-2.4.3/ulong_extras/test/t-factor_pp1.c new file mode 100644 index 0000000..b9b01c3 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-factor_pp1.c @@ -0,0 +1,81 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, j, result; + ulong count = UWORD(0); + FLINT_TEST_INIT(state); + + + flint_printf("factor_pp1...."); + fflush(stdout); + + for (i = 0; i < 300 * flint_test_multiplier(); i++) /* Test random numbers */ + { + mp_limb_t n1, n2; + + do + { + n1 = n_randtest_bits(state, n_randint(state, FLINT_BITS) + 1); + } while (n_is_prime(n1) || (n1 < UWORD(2))); + + for (j = 0; j < 20; j++) + { + n2 = n_factor_pp1(n1, 1000000, n_randint(state, n1 - 3) + 3); + if (n2 > 1) break; + } + + if (n2 > 1) + { + count++; + result = ((n1%n2) == UWORD(0)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("n1 = %wu, n2 = %wu\n", n1, n2); + abort(); + } + } + } + + if (count < 295 * flint_test_multiplier()) + { + flint_printf("FAIL:\n"); + flint_printf("Only %wu numbers factored\n", count); + abort(); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-factor_trial.c b/external/flint-2.4.3/ulong_extras/test/t-factor_trial.c new file mode 100644 index 0000000..a0ee2b5 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-factor_trial.c @@ -0,0 +1,69 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, j, result; + FLINT_TEST_INIT(state); + + + flint_printf("factor_trial...."); + fflush(stdout); + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) /* Test random numbers */ + { + mp_limb_t n1, n2; + n_factor_t factors; + + n_factor_init(&factors); + + n1 = n_randtest_not_zero(state); + n2 = n_factor_trial(&factors, n1, UWORD(10000)); + + for (j = 0; j < factors.num; j++) + { + n2 *= n_pow(factors.p[j], factors.exp[j]); + } + + result = (n1 == n2); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("n1 = %wu, n2 = %wu\n", n1, n2); + abort(); + } + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-factor_trial_partial.c b/external/flint-2.4.3/ulong_extras/test/t-factor_trial_partial.c new file mode 100644 index 0000000..cba2fe3 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-factor_trial_partial.c @@ -0,0 +1,77 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, j, result; + FLINT_TEST_INIT(state); + + + flint_printf("factor_trial_partial...."); + fflush(stdout); + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) /* Test random numbers */ + { + mp_limb_t n1, n2, prod, limit; + n_factor_t factors; + + n_factor_init(&factors); + + n1 = n_randtest_not_zero(state); + limit = n_sqrt(n1); + n2 = n_factor_trial_partial(&factors, n1, &prod, UWORD(10000), limit); + + if (n1 != n2*prod) + { + flint_printf("FAIL:\n"); + flint_printf("n1 = %wu, n2 = %wu, prod = %wu\n", n1, n2, prod); + abort(); + } + + for (j = 0; j < factors.num; j++) + { + n2 *= n_pow(factors.p[j], factors.exp[j]); + } + + result = (n1 == n2); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("n1 = %wu, n2 = %wu\n", n1, n2); + abort(); + } + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-factor_trial_range.c b/external/flint-2.4.3/ulong_extras/test/t-factor_trial_range.c new file mode 100644 index 0000000..5449368 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-factor_trial_range.c @@ -0,0 +1,70 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, j, result; + FLINT_TEST_INIT(state); + + + flint_printf("factor_trial_range...."); + fflush(stdout); + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) /* Test random numbers */ + { + mp_limb_t n1, n2; + n_factor_t factors; + + n_factor_init(&factors); + + n1 = n_randtest_not_zero(state); + n2 = n_factor_trial_range(&factors, n1, UWORD(100), UWORD(10000)); + + for (j = 0; j < factors.num; j++) + { + n2 *= n_pow(factors.p[j], factors.exp[j]); + } + + result = (n1 == n2); + + if (!result) + { + flint_printf("FAIL\n"); + flint_printf("n1 = %wu, n2 = %wu\n", n1, n2); + abort(); + } + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-factorial_fast_mod2_preinv.c b/external/flint-2.4.3/ulong_extras/test/t-factorial_fast_mod2_preinv.c new file mode 100644 index 0000000..bb19bc1 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-factorial_fast_mod2_preinv.c @@ -0,0 +1,80 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "ulong_extras.h" + + +static mp_limb_t +n_factorial_mod2_foolproof(ulong n, mp_limb_t p, mp_limb_t pinv) +{ + mp_limb_t prod = UWORD(1) % p; + + while (n) + { + prod = n_mulmod2_preinv(prod, n, p, pinv); + n--; + } + + return prod; +} + +int main(void) +{ + mp_limb_t n; + int j; + + FLINT_TEST_INIT(state); + + flint_printf("factorial_fast_mod2_preinv...."); + fflush(stdout); + + for (n = 0; n < 100 * flint_test_multiplier(); n++) + { + mp_limb_t p, pinv, x, y; + + for (j = 0; j < 10; j++) + { + p = n_randtest_not_zero(state); + pinv = n_preinvert_limb(p); + x = n_factorial_fast_mod2_preinv(n, p, pinv); + y = n_factorial_mod2_foolproof(n, p, pinv); + + if (x != y) + { + flint_printf("FAIL:\n"); + flint_printf("n = %wu\np = %wu\nx = %wu\ny = %wu\n", n, p, x, y); + abort(); + } + } + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-factorial_mod2_preinv.c b/external/flint-2.4.3/ulong_extras/test/t-factorial_mod2_preinv.c new file mode 100644 index 0000000..899b362 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-factorial_mod2_preinv.c @@ -0,0 +1,80 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "ulong_extras.h" + + +static mp_limb_t +n_factorial_mod2_foolproof(ulong n, mp_limb_t p, mp_limb_t pinv) +{ + mp_limb_t prod = UWORD(1) % p; + + while (n) + { + prod = n_mulmod2_preinv(prod, n, p, pinv); + n--; + } + + return prod; +} + +int main(void) +{ + mp_limb_t n; + int j; + + FLINT_TEST_INIT(state); + + flint_printf("factorial_mod2_preinv...."); + fflush(stdout); + + for (n = 0; n < 100 * flint_test_multiplier(); n++) + { + mp_limb_t p, pinv, x, y; + + for (j = 0; j < 10; j++) + { + p = n_randtest_not_zero(state); + pinv = n_preinvert_limb(p); + x = n_factorial_mod2_preinv(n, p, pinv); + y = n_factorial_mod2_foolproof(n, p, pinv); + + if (x != y) + { + flint_printf("FAIL:\n"); + flint_printf("n = %wu\np = %wu\nx = %wu\ny = %wu\n", n, p, x, y); + abort(); + } + } + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-flog.c b/external/flint-2.4.3/ulong_extras/test/t-flog.c new file mode 100644 index 0000000..0638e7b --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-flog.c @@ -0,0 +1,69 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("flog...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + mp_limb_t a = 0, b = 0, k, x; + + while (a < 1) + a = n_randtest(state); + while (b < 2) + b = n_randtest(state); + + k = n_flog(a, b); + x = n_pow(b, k); + + result = (x <= a && a / b < x); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = %wu\n", a); + flint_printf("b = %wu\n", b); + flint_printf("x = %wu\n", x); + flint_printf("k = %wu\n", k); + } + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return EXIT_SUCCESS; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-gcd.c b/external/flint-2.4.3/ulong_extras/test/t-gcd.c new file mode 100644 index 0000000..d7c3541 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-gcd.c @@ -0,0 +1,71 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("gcd...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + mp_limb_t a, b, c, bits1, bits2, bits3; + + bits1 = n_randint(state, FLINT_BITS-1) + 1; + bits2 = n_randint(state, bits1) + 1; + bits3 = n_randint(state, FLINT_BITS - bits1) + 1; + + do + { + a = n_randtest_bits(state, bits1); + b = n_randtest_bits(state, bits2); + } while ((n_gcd(a, b) != UWORD(1)) || (b > a)); + + c = n_randtest_bits(state, bits3); + + result = (n_gcd(a*c, b*c) == c); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = %wu, b = %wu, c = %wu\n", a, b, c); + abort(); + } + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-gcd_full.c b/external/flint-2.4.3/ulong_extras/test/t-gcd_full.c new file mode 100644 index 0000000..13e5909 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-gcd_full.c @@ -0,0 +1,71 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("gcd_full...."); + fflush(stdout); + + + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) + { + mp_limb_t a, b, c, bits1, bits2, bits3; + + bits1 = n_randint(state, FLINT_BITS-1) + 1; + bits2 = n_randint(state, bits1) + 1; + bits3 = n_randint(state, FLINT_BITS - bits1) + 1; + + do + { + a = n_randtest_bits(state, bits1); + b = n_randtest_bits(state, bits2); + } while ((n_gcd_full(a, b) != UWORD(1))); + + c = n_randtest_bits(state, bits3); + + result = (n_gcd_full(a*c, b*c) == c); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = %wu, b = %wu, c = %wu\n", a, b, c); + abort(); + } + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-gcdinv.c b/external/flint-2.4.3/ulong_extras/test/t-gcdinv.c new file mode 100644 index 0000000..88b0816 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-gcdinv.c @@ -0,0 +1,76 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("gcdinv...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + mp_limb_t a, b, c, g, g2, s, t2, t, bits1, bits2, bits3; + + bits1 = n_randint(state, FLINT_BITS-2) + 2; + bits2 = n_randint(state, bits1) + 1; + bits3 = n_randint(state, FLINT_BITS - bits1) + 1; + + do + { + a = n_randtest_bits(state, bits1); + b = n_randtest_bits(state, bits2); + } while ((n_gcd(a, b) != UWORD(1)) || (b >= a)); + + c = n_randtest_bits(state, bits3); + + g = n_xgcd(&s, &t, a*c, b*c); + g2 = n_gcdinv(&t2, b*c, a*c); + t %= (a*c); + t = a*c - t; + + result = ((g == g2) && (t == t2)); + if (!result) + { + flint_printf("FAIL\n"); + flint_printf("a = %wu, b = %wu, c = %wu, g = %wu, g2 = %wu, t = %wd, t2 = %wd\n", a, b, c, g, g2, t, t2); + abort(); + } + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-invmod.c b/external/flint-2.4.3/ulong_extras/test/t-invmod.c new file mode 100644 index 0000000..81615bd --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-invmod.c @@ -0,0 +1,70 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("invmod...."); + fflush(stdout); + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + mp_limb_t a, b, t, r, binv, ph, pl; + + do + { + a = n_randtest(state); + b = n_randtest(state); + } while ((a >= b) || (n_gcd(b, a) != UWORD(1))); + + t = n_invmod(a, b); + + binv = n_preinvert_limb(b); + umul_ppmm(ph, pl, t, a); + r = n_ll_mod_preinv(ph, pl, b, binv); + + result = (((r == UWORD(0)) && (b == UWORD(1))) || (r == UWORD(1))); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = %wu, b = %wu, r = %wd\n", a, b, r); + abort(); + } + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-is_oddprime_binary.c b/external/flint-2.4.3/ulong_extras/test/t-is_oddprime_binary.c new file mode 100644 index 0000000..7957339 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-is_oddprime_binary.c @@ -0,0 +1,99 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + slong cutoff = 100000; + + FLINT_TEST_INIT(state); + + flint_printf("is_oddprime_binary...."); + fflush(stdout); + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) /* Test that primes pass the test */ + { + mp_limb_t d; + mpz_t d_m; + + mpz_init(d_m); + + do + { + d = n_randint(state, cutoff) | 1; + if (d == UWORD(1)) d += 16; /* algorithm requires d >= 17 */ + flint_mpz_set_ui(d_m, d); + mpz_nextprime(d_m, d_m); + d = flint_mpz_get_ui(d_m); + } while (d > cutoff); + + result = n_is_oddprime_binary(d); + + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("d = %wu is declared composite\n", d); + abort(); + } + + mpz_clear(d_m); + } + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) /* Test that not too many composites pass */ + { + mp_limb_t d; + mpz_t d_m; + + mpz_init(d_m); + + do + { + d = (n_randint(state, cutoff) + 16) | 1; + flint_mpz_set_ui(d_m, d); + } while ((mpz_probab_prime_p(d_m, 12)) || (d > cutoff)); + + result = !n_is_oddprime_binary(d); + + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("d = %wu is declared prime\n", d); + abort(); + } + + mpz_clear(d_m); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-is_oddprime_small.c b/external/flint-2.4.3/ulong_extras/test/t-is_oddprime_small.c new file mode 100644 index 0000000..a7f0076 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-is_oddprime_small.c @@ -0,0 +1,96 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("is_oddprime_small...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) /* Test that primes pass the test */ + { + mp_limb_t d; + mpz_t d_m; + + mpz_init(d_m); + + do + { + d = n_randint(state, FLINT_ODDPRIME_SMALL_CUTOFF) | 1; + flint_mpz_set_ui(d_m, d); + mpz_nextprime(d_m, d_m); + d = flint_mpz_get_ui(d_m); + } while (d > FLINT_ODDPRIME_SMALL_CUTOFF); + + result = n_is_oddprime_small(d); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("d = %wu is declared composite\n", d); + abort(); + } + + mpz_clear(d_m); + } + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) /* Test that not too many composites pass */ + { + mp_limb_t d; + mpz_t d_m; + + mpz_init(d_m); + + do + { + d = n_randint(state, FLINT_ODDPRIME_SMALL_CUTOFF) | 1; + flint_mpz_set_ui(d_m, d); + } while ((mpz_probab_prime_p(d_m, 12)) || (d > FLINT_ODDPRIME_SMALL_CUTOFF)); + + result = !n_is_oddprime_small(d); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("d = %wu is declared prime\n", d); + abort(); + } + + mpz_clear(d_m); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-is_perfect_power235.c b/external/flint-2.4.3/ulong_extras/test/t-is_perfect_power235.c new file mode 100644 index 0000000..cdae1de --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-is_perfect_power235.c @@ -0,0 +1,117 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + ulong bits; + mp_limb_t d; + FLINT_TEST_INIT(state); + + flint_printf("is_perfect_power235...."); + fflush(stdout); + + + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) /* Test that square pass the test */ + { + bits = n_randint(state, FLINT_BITS/2) + 1; + d = n_randtest_bits(state, bits); + + result = n_is_perfect_power235(n_pow(d, 2)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("d^2 = %wu is declared not a perfect power\n", d*d); + abort(); + } + + } + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) /* Test that cubes pass the test */ + { + bits = n_randint(state, FLINT_BITS/3) + 1; + d = n_randtest_bits(state, bits); + + result = n_is_perfect_power235(n_pow(d, 3)); + + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("d^3 = %wu is declared not a perfect power\n", d*d*d); + abort(); + } + + } + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) /* Test that fifth powers pass the test */ + { + bits = n_randint(state, FLINT_BITS/5) + 1; + d = n_randtest_bits(state, bits); + + result = n_is_perfect_power235(n_pow(d, 5)); + + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("d^5 = %wu is declared not a perfect power\n", d*d*d*d*d); + abort(); + } + + } + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) /* Test that non prefect powers fail */ + { + mpz_t d_m; + mpz_init(d_m); + + do + { + d = n_randtest(state); + flint_mpz_set_ui(d_m, d); + } while (mpz_perfect_power_p(d_m)); + + result = !n_is_perfect_power235(d); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("d = %wu is declared a perfect power\n", d); + abort(); + } + + mpz_clear(d_m); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-is_prime.c b/external/flint-2.4.3/ulong_extras/test/t-is_prime.c new file mode 100644 index 0000000..d3a4611 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-is_prime.c @@ -0,0 +1,92 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + mp_limb_t d; + mpz_t d_m; + + FLINT_TEST_INIT(state); + + flint_printf("is_prime...."); + fflush(stdout); + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) /* Test that primes pass the test */ + { + mpz_init(d_m); + + do + { + d = n_randtest(state) | 1; + flint_mpz_set_ui(d_m, d); + mpz_nextprime(d_m, d_m); + d = flint_mpz_get_ui(d_m); + } while (mpz_size(d_m) > 1); + + result = n_is_prime(d); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("d = %wu is declared composite\n", d); + abort(); + } + + mpz_clear(d_m); + } + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) /* Test that composites do not pass */ + { + mpz_init(d_m); + + do + { + d = n_randtest(state) | 1; + if (d == UWORD(1)) d++; + flint_mpz_set_ui(d_m, d); + } while (mpz_probab_prime_p(d_m, 12)); + + result = !n_is_prime(d); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("d = %wu is declared prime\n", d); + abort(); + } + + mpz_clear(d_m); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-is_prime_pocklington.c b/external/flint-2.4.3/ulong_extras/test/t-is_prime_pocklington.c new file mode 100644 index 0000000..455741c --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-is_prime_pocklington.c @@ -0,0 +1,103 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + ulong count = 0; + mp_limb_t d; + mpz_t d_m; + FLINT_TEST_INIT(state); + + + flint_printf("is_prime_pocklington...."); + fflush(stdout); + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) /* Test that primes pass the test */ + { + mpz_init(d_m); + + do + { + d = n_randtest(state) | 1; + flint_mpz_set_ui(d_m, d); + mpz_nextprime(d_m, d_m); + d = flint_mpz_get_ui(d_m); + } while (mpz_size(d_m) > 1); + + result = n_is_prime_pocklington(d, 100); + if (result == -1) count++; + + if (result == 0) + { + flint_printf("FAIL:\n"); + flint_printf("d = %wu is declared composite\n", d); + abort(); + } + + mpz_clear(d_m); + } + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) /* Test that composites do not pass */ + { + mpz_init(d_m); + + do + { + d = n_randtest(state) | 1; + if (d == UWORD(1)) d++; + flint_mpz_set_ui(d_m, d); + } while (mpz_probab_prime_p(d_m, 12)); + + result = n_is_prime_pocklington(d, 100); + if (result == -1) count++; + + if (result == 1) + { + flint_printf("FAIL:\n"); + flint_printf("d = %wu is declared prime\n", d); + abort(); + } + + mpz_clear(d_m); + } + + if (count > 200 * flint_test_multiplier()) + { + flint_printf("FAIL: Pocklington-Lehmer failed too many times (%wu times)\n", count); + abort(); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-is_prime_pseudosquare.c b/external/flint-2.4.3/ulong_extras/test/t-is_prime_pseudosquare.c new file mode 100644 index 0000000..ec68a45 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-is_prime_pseudosquare.c @@ -0,0 +1,92 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + mp_limb_t d; + mpz_t d_m; + FLINT_TEST_INIT(state); + + + flint_printf("is_prime_pseudosquare...."); + fflush(stdout); + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) /* Test that primes pass the test */ + { + mpz_init(d_m); + + do + { + d = n_randtest(state) | 1; + flint_mpz_set_ui(d_m, d); + mpz_nextprime(d_m, d_m); + d = flint_mpz_get_ui(d_m); + } while (mpz_size(d_m) > 1); + + result = n_is_prime_pseudosquare(d); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("d = %wu is declared composite\n", d); + abort(); + } + + mpz_clear(d_m); + } + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) /* Test that composites don't pass */ + { + mpz_init(d_m); + + do + { + d = n_randtest(state) | 1; + if (d == UWORD(1)) d++; + flint_mpz_set_ui(d_m, d); + } while (mpz_probab_prime_p(d_m, 12)); + + result = !n_is_prime_pseudosquare(d); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("d = %wu is declared prime\n", d); + abort(); + } + + mpz_clear(d_m); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-is_probabprime.c b/external/flint-2.4.3/ulong_extras/test/t-is_probabprime.c new file mode 100644 index 0000000..27bb9a8 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-is_probabprime.c @@ -0,0 +1,92 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + mp_limb_t d; + mpz_t d_m; + FLINT_TEST_INIT(state); + + + flint_printf("is_probabprime...."); + fflush(stdout); + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) /* Test that primes pass the test */ + { + mpz_init(d_m); + + do + { + d = n_randtest(state) | 1; + flint_mpz_set_ui(d_m, d); + mpz_nextprime(d_m, d_m); + d = flint_mpz_get_ui(d_m); + } while (mpz_size(d_m) > 1); + + result = n_is_probabprime(d); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("d = %wu is declared composite\n", d); + abort(); + } + + mpz_clear(d_m); + } + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) /* Test that composites do not pass */ + { + mpz_init(d_m); + + do + { + d = n_randtest(state) | 1; + if (d == UWORD(1)) d++; + flint_mpz_set_ui(d_m, d); + } while (mpz_probab_prime_p(d_m, 12)); + + result = !n_is_probabprime(d); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("d = %wu is declared prime\n", d); + abort(); + } + + mpz_clear(d_m); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-is_probabprime_BPSW.c b/external/flint-2.4.3/ulong_extras/test/t-is_probabprime_BPSW.c new file mode 100644 index 0000000..eb0d222 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-is_probabprime_BPSW.c @@ -0,0 +1,91 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + mp_limb_t d; + mpz_t d_m; + FLINT_TEST_INIT(state); + + + flint_printf("is_probabprime_BPSW...."); + fflush(stdout); + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) /* Test that primes pass the test */ + { + mpz_init(d_m); + + do + { + d = n_randtest_not_zero(state); + flint_mpz_set_ui(d_m, d); + mpz_nextprime(d_m, d_m); + d = flint_mpz_get_ui(d_m); + } while (mpz_size(d_m) > 1); + + result = n_is_probabprime_BPSW(d); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("d = %wu is declared composite\n", d); + abort(); + } + + mpz_clear(d_m); + } + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) /* Test that not too many composites pass */ + { + mpz_init(d_m); + + do + { + d = n_randtest(state); + flint_mpz_set_ui(d_m, d); + } while (mpz_probab_prime_p(d_m, 12)); + + result = (n_is_probabprime_BPSW(d) == 0); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("d = %wu is declared prime\n", d); + abort(); + } + + mpz_clear(d_m); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-is_probabprime_fermat.c b/external/flint-2.4.3/ulong_extras/test/t-is_probabprime_fermat.c new file mode 100644 index 0000000..e71d2a4 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-is_probabprime_fermat.c @@ -0,0 +1,109 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + ulong count = UWORD(0); + mp_limb_t d, j; + mpz_t d_m; + FLINT_TEST_INIT(state); + + flint_printf("is_probabprime_fermat...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) /* Test that primes pass the test */ + { + mpz_init(d_m); + + do + { + d = n_randtest_not_zero(state); + if (d == UWORD(1)) d++; + flint_mpz_set_ui(d_m, d); + mpz_nextprime(d_m, d_m); + d = flint_mpz_get_ui(d_m); + } while (mpz_size(d_m) > 1); + + do + { + j = n_randtest(state) % d; + if ((j == WORD(1)) && (d != UWORD(2))) j++; + } while (n_gcd(d, j) != UWORD(1)); + + result = n_is_probabprime_fermat(d, j); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("d = %wu is declared composite\n", d); + abort(); + } + + mpz_clear(d_m); + } + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) /* Test that not too many composites pass */ + { + mpz_init(d_m); + + do + { + d = n_randtest_bits(state, n_randint(state, FLINT_BITS) + 1); + if (d < UWORD(2)) d = 2; + flint_mpz_set_ui(d_m, d); + } while (mpz_probab_prime_p(d_m, 12)); + + do + { + j = n_randtest(state) % d; + if ((j == WORD(1)) && (d != UWORD(2))) j++; + } while (n_gcd(d, j) != UWORD(1)); + + if (n_is_probabprime_fermat(d, j)) count++; + + mpz_clear(d_m); + } + + result = (count < 200 * flint_test_multiplier()); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("%wu composites declared prime\n", count); + abort(); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-is_probabprime_fibonacci.c b/external/flint-2.4.3/ulong_extras/test/t-is_probabprime_fibonacci.c new file mode 100644 index 0000000..9b7324d --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-is_probabprime_fibonacci.c @@ -0,0 +1,95 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + ulong count = UWORD(0); + mp_limb_t d; + mpz_t d_m; + FLINT_TEST_INIT(state); + + + flint_printf("is_probabprime_fibonacci...."); + fflush(stdout); + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) /* Test that primes pass the test */ + { + mpz_init(d_m); + + do + { + d = n_randtest_not_zero(state); + flint_mpz_set_ui(d_m, d); + mpz_nextprime(d_m, d_m); + d = flint_mpz_get_ui(d_m); + } while (mpz_size(d_m) > 1); + + result = n_is_probabprime_fibonacci(d); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("d = %wu is declared composite\n", d); + abort(); + } + + mpz_clear(d_m); + } + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) /* Test that not too many composites pass */ + { + mpz_init(d_m); + + do + { + d = n_randtest(state) | UWORD(1); + if ((d % 5) == 0) d+=2; + flint_mpz_set_ui(d_m, d); + } while (mpz_probab_prime_p(d_m, 12)); + + if (n_is_probabprime_fibonacci(d)) count++; + + mpz_clear(d_m); + } + + result = (count < 20 * flint_test_multiplier()); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("%wu composites declared prime\n", count); + abort(); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-is_probabprime_lucas.c b/external/flint-2.4.3/ulong_extras/test/t-is_probabprime_lucas.c new file mode 100644 index 0000000..2f5ce5c --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-is_probabprime_lucas.c @@ -0,0 +1,94 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + ulong count = UWORD(0); + mp_limb_t d; + mpz_t d_m; + FLINT_TEST_INIT(state); + + + flint_printf("is_probabprime_lucas...."); + fflush(stdout); + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) /* Test that primes pass the test */ + { + mpz_init(d_m); + + do + { + d = n_randtest_not_zero(state); + flint_mpz_set_ui(d_m, d); + mpz_nextprime(d_m, d_m); + d = flint_mpz_get_ui(d_m); + } while (mpz_size(d_m) > 1); + + result = n_is_probabprime_lucas(d); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("d = %wu is declared composite\n", d); + abort(); + } + + mpz_clear(d_m); + } + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) /* Test that not too many composites pass */ + { + mpz_init(d_m); + + do + { + d = n_randtest(state); + flint_mpz_set_ui(d_m, d); + } while (mpz_probab_prime_p(d_m, 12)); + + if (n_is_probabprime_lucas(d) == 1) count++; + + mpz_clear(d_m); + } + + result = (count < 20 * flint_test_multiplier()); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("%wu composites declared prime\n", count); + abort(); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-is_square.c b/external/flint-2.4.3/ulong_extras/test/t-is_square.c new file mode 100644 index 0000000..cfe5a61 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-is_square.c @@ -0,0 +1,80 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("is_square...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) /* Test that non-squares pass */ + { + mp_limb_t a, s, bits; + + bits = n_randint(state, FLINT_BITS/2) + 1; + a = n_randtest_bits(state, bits); + s = a*a + n_randtest(state) % (2*a) + 1; + + result = !n_is_square(s); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("s = %wu is declared square\n", s); + abort(); + } + } + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) /* Test that squares pass */ + { + mp_limb_t a, s, bits; + + bits = n_randint(state, FLINT_BITS/2); + a = n_randtest_bits(state, bits); + s = a*a; + + result = n_is_square(s); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("s = %wu is declared square\n", s); + abort(); + } + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-is_squarefree.c b/external/flint-2.4.3/ulong_extras/test/t-is_squarefree.c new file mode 100644 index 0000000..b977451 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-is_squarefree.c @@ -0,0 +1,86 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "ulong_extras.h" + + +void check(mp_limb_t n, int s1, int s2) +{ + if (s1 != s2) + { + flint_printf("FAIL:\n"); + flint_printf("%wu: got %d instead of %d\n", n, s1, s2); + abort(); + } +} + +int main(void) +{ + int s, k; + + FLINT_TEST_INIT(state); + + flint_printf("is_squarefree...."); + fflush(stdout); + + check(0, n_is_squarefree(0), 0); + check(1, n_is_squarefree(1), 1); + check(2, n_is_squarefree(2), 1); + check(3, n_is_squarefree(3), 1); + check(4, n_is_squarefree(4), 0); + check(5, n_is_squarefree(5), 1); + + check(16, n_is_squarefree(16), 0); + check(25, n_is_squarefree(25), 0); + check(49, n_is_squarefree(49), 0); + check(16*3, n_is_squarefree(16*3), 0); + check(25*3, n_is_squarefree(25*3), 0); + check(49*3, n_is_squarefree(49*3), 0); + + check(101*103, n_is_squarefree(101*103), 1); + check(101*101, n_is_squarefree(101*101), 0); + check(101*103*4, n_is_squarefree(101*103*4), 0); + check(101*103*5, n_is_squarefree(101*103*5), 1); + check(101*103*103*5, n_is_squarefree(101*103*103*5), 0); + check(101*103*25, n_is_squarefree(101*103*25), 0); + + s = 0; + for (k = 0; k <= 10000; k++) + s += n_is_squarefree(k); + + if (s != 6083) + { + flint_printf("FAIL:\n"); + flint_printf("expected %d squarefree numbers <= 10000 (got %d)\n", 6083, s); + abort(); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-is_strong_probabprime2_preinv.c b/external/flint-2.4.3/ulong_extras/test/t-is_strong_probabprime2_preinv.c new file mode 100644 index 0000000..57ae9fe --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-is_strong_probabprime2_preinv.c @@ -0,0 +1,125 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + ulong count = UWORD(0); + FLINT_TEST_INIT(state); + + flint_printf("is_strong_probabprime2_preinv...."); + fflush(stdout); + + + + for (i = 0; i < 100 * flint_test_multiplier(); i++) /* Test that primes pass the test */ + { + mp_limb_t a, d, dinv, norm; + mpz_t d_m; + ulong j; + + mpz_init(d_m); + + do + { + d = n_randtest(state) | 1; + flint_mpz_set_ui(d_m, d); + mpz_nextprime(d_m, d_m); + d = flint_mpz_get_ui(d_m); + } while (mpz_size(d_m) > 1); + if (d == UWORD(2)) d++; + + for (j = 0; j < 100; j++) + { + do a = n_randtest(state) % d; + while (a == UWORD(0)); + + dinv = n_preinvert_limb(d); + count_trailing_zeros(norm, d - 1); + result = n_is_strong_probabprime2_preinv(d, dinv, a, (d - 1)>>norm); + + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = %wu, d = %wu\n", a, d); + abort(); + } + } + + mpz_clear(d_m); + } + + for (i = 0; i < 100 * flint_test_multiplier(); i++) /* Test that not too many composites pass */ + { + mp_limb_t a, d, dinv, norm; + mpz_t d_m; + ulong j; + + mpz_init(d_m); + + do + { + d = n_randtest(state) | 1; + if (d == UWORD(1)) d++; + flint_mpz_set_ui(d_m, d); + } while (mpz_probab_prime_p(d_m, 12)); + + for (j = 0; j < 100; j++) + { + do a = n_randtest(state) % d; + while (a == UWORD(0)); + + dinv = n_preinvert_limb(d); + count_trailing_zeros(norm, d - 1); + result = !n_is_strong_probabprime2_preinv(d, dinv, a, (d - 1)>>norm); + + if (!result) count++; + } + + mpz_clear(d_m); + } + +#if FLINT64 + if (count > 220 * flint_test_multiplier()) +#else + if (count > 430 * flint_test_multiplier()) +#endif + { + flint_printf("FAIL:\n"); + flint_printf("count = %wu\n", count); + abort(); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-is_strong_probabprime_precomp.c b/external/flint-2.4.3/ulong_extras/test/t-is_strong_probabprime_precomp.c new file mode 100644 index 0000000..659ccd2 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-is_strong_probabprime_precomp.c @@ -0,0 +1,122 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, j, result; + ulong count = UWORD(0); + FLINT_TEST_INIT(state); + + flint_printf("is_strong_probabprime_precomp...."); + fflush(stdout); + + + + for (i = 0; i < 100 * flint_test_multiplier(); i++) /* Test that primes pass the test */ + { + mp_limb_t a, d, norm; + mpz_t d_m; + double dpre; + mp_limb_t bits = n_randint(state, FLINT_D_BITS-1) + 2; + + mpz_init(d_m); + + do + { + d = n_randbits(state, bits) | 1; + flint_mpz_set_ui(d_m, d); + mpz_nextprime(d_m, d_m); + d = flint_mpz_get_ui(d_m); + } while (FLINT_BIT_COUNT(d) > FLINT_D_BITS); + if (d == UWORD(2)) d++; + + for (j = 0; j < 100; j++) + { + do a = n_randint(state, d); + while (a == UWORD(0)); + + dpre = n_precompute_inverse(d); + count_trailing_zeros(norm, d - 1); + result = n_is_strong_probabprime_precomp(d, dpre, a, (d - 1)>>norm); + + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = %wu, d = %wu\n", a, d); + abort(); + } + } + + mpz_clear(d_m); + } + + for (i = 0; i < 100 * flint_test_multiplier(); i++) /* Test that not too many composites pass */ + { + mp_limb_t a, d, norm; + mpz_t d_m; + double dpre; + mp_limb_t bits = n_randint(state, FLINT_D_BITS-3) + 4; + + mpz_init(d_m); + + do + { + d = n_randbits(state, bits) | 1; + flint_mpz_set_ui(d_m, d); + } while (mpz_probab_prime_p(d_m, 12)); + + for (j = 0; j < 100; j++) + { + do a = n_randint(state, d); + while (a == UWORD(0)); + + dpre = n_precompute_inverse(d); + count_trailing_zeros(norm, d - 1); + result = !n_is_strong_probabprime_precomp(d, dpre, a, (d - 1)>>norm); + + if (!result) count++; + } + + mpz_clear(d_m); + } + + if (count > 220 * flint_test_multiplier()) + { + flint_printf("FAIL:\n"); + flint_printf("count = %wu\n", count); + abort(); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-jacobi.c b/external/flint-2.4.3/ulong_extras/test/t-jacobi.c new file mode 100644 index 0000000..2d6f90f --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-jacobi.c @@ -0,0 +1,76 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("jacobi...."); + fflush(stdout); + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + mp_limb_t d; + mpz_t a_m, d_m; + mp_limb_signed_t a; + int r1, r2; + + mpz_init(a_m); + mpz_init(d_m); + + a = n_randtest(state); + d = n_randtest_not_zero(state) | WORD(1); + + r1 = n_jacobi(a, d); + + flint_mpz_set_si(a_m, a); + flint_mpz_set_ui(d_m, d); + r2 = mpz_jacobi(a_m, d_m); + + result = (r1 == r2); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = %wu, d = %wu\n", a, d); + abort(); + } + + mpz_clear(a_m); + mpz_clear(d_m); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-ll_mod_preinv.c b/external/flint-2.4.3/ulong_extras/test/t-ll_mod_preinv.c new file mode 100644 index 0000000..c5b3191 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-ll_mod_preinv.c @@ -0,0 +1,70 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("ll_mod_preinv...."); + fflush(stdout); + + + + for (i = 0; i < 100000 * flint_test_multiplier(); i++) + { + mp_limb_t d, dinv, nh, nl, r1, r2, m; + + d = n_randtest_not_zero(state); + m = n_randtest(state); + r1 = n_randtest(state) % d; + umul_ppmm(nh, nl, m, d); + add_ssaaaa(nh, nl, nh, nl, UWORD(0), r1); + + dinv = n_preinvert_limb(d); + + r2 = n_ll_mod_preinv(nh, nl, d, dinv); + + result = (r1 == r2); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("nh = %wu, nl = %wu, d = %wu, dinv = %wu\n", nh, nl, d, dinv); + flint_printf("r1 = %wu, r2 = %wu\n", r1, r2); + abort(); + } + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-lll_mod_preinv.c b/external/flint-2.4.3/ulong_extras/test/t-lll_mod_preinv.c new file mode 100644 index 0000000..81646f4 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-lll_mod_preinv.c @@ -0,0 +1,71 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("lll_mod_preinv...."); + fflush(stdout); + + + + for (i = 0; i < 100000 * flint_test_multiplier(); i++) + { + mp_limb_t d, dinv, nh, nm, nl, r1, r2; + + d = n_randtest_not_zero(state); + nh = n_randtest(state) % d; + nm = n_randtest(state); + nl = n_randtest(state); + + dinv = n_preinvert_limb(d); + + r2 = n_lll_mod_preinv(nh, nm, nl, d, dinv); + nm = n_ll_mod_preinv(nh, nm, d, dinv); + r1 = n_ll_mod_preinv(nm, nl, d, dinv); + + result = (r1 == r2); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("nh = %wu, nm = %wd, nl = %wu, d = %wu, dinv = %wu\n", nh, nm, nl, d, dinv); + flint_printf("r1 = %wu, r2 = %wu\n", r1, r2); + abort(); + } + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-mod2_precomp.c b/external/flint-2.4.3/ulong_extras/test/t-mod2_precomp.c new file mode 100644 index 0000000..0baebcb --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-mod2_precomp.c @@ -0,0 +1,69 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("mod2_precomp...."); + fflush(stdout); + + for (i = 0; i < 100000 * flint_test_multiplier(); i++) + { + mp_limb_t d, n, r1, r2; + double dpre; + + d = n_randtest_not_zero(state); + + n = n_randtest(state); + + dpre = n_precompute_inverse(d); + + r1 = n_mod2_precomp(n, d, dpre); + r2 = n%d; + + result = (r1 == r2); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("n = %wu, d = %wu, dpre = %f\n", n, d, dpre); + flint_printf("r1 = %wu, r2 = %wu\n", r1, r2); + abort(); + } + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-mod2_preinv.c b/external/flint-2.4.3/ulong_extras/test/t-mod2_preinv.c new file mode 100644 index 0000000..ded480f --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-mod2_preinv.c @@ -0,0 +1,67 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + + flint_printf("mod2_preinv...."); + fflush(stdout); + + for (i = 0; i < 100000 * flint_test_multiplier(); i++) + { + mp_limb_t d, dinv, n, r1, r2; + + d = n_randtest_not_zero(state); + n = n_randtest(state); + + dinv = n_preinvert_limb(d); + + r1 = n_mod2_preinv(n, d, dinv); + r2 = n%d; + + result = (r1 == r2); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("n = %wu, d = %wu, dinv = %wu\n", n, d, dinv); + flint_printf("r1 = %wu, r2 = %wu\n", r1, r2); + abort(); + } + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-mod_precomp.c b/external/flint-2.4.3/ulong_extras/test/t-mod_precomp.c new file mode 100644 index 0000000..b607958 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-mod_precomp.c @@ -0,0 +1,75 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("mod_precomp...."); + fflush(stdout); + + + + for (i = 0; i < 100000 * flint_test_multiplier(); i++) + { + mp_limb_t bits, d, n, r1, r2; + double dpre; + + bits = n_randint(state, FLINT_D_BITS) + 1; + d = n_randtest_bits(state, bits); + if (bits <= (FLINT_BITS/2)) n = n_randtest(state) % (d*d); + else n = n_randtest(state); + + /* must have n < 2^(FLINT_BITS - 1) */ + if (FLINT_BIT_COUNT(n) == FLINT_BITS) + n >>= 1; + + dpre = n_precompute_inverse(d); + + r1 = n_mod_precomp(n, d, dpre); + r2 = n%d; + + result = (r1 == r2); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("n = %wu, d = %wu, dinv = %g\n", n, d, dpre); + flint_printf("r1 = %wu, r2 = %wu\n", r1, r2); + abort(); + } + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-moebius_mu.c b/external/flint-2.4.3/ulong_extras/test/t-moebius_mu.c new file mode 100644 index 0000000..d54d9fb --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-moebius_mu.c @@ -0,0 +1,96 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "ulong_extras.h" + + +void check(mp_limb_t n, int mu1, int mu2) +{ + if (mu1 != mu2) + { + flint_printf("FAIL:\n"); + flint_printf("mu(%wu): %d != %d\n", n, mu1, mu2); + abort(); + } +} + +int main(void) +{ + int n, k, s; + int * mu; + + FLINT_TEST_INIT(state); + + flint_printf("moebius_mu...."); + fflush(stdout); + + check(0, n_moebius_mu(0), 0); + check(1, n_moebius_mu(1), 1); + + for (n = 1; n < 100; n++) + { + mu = flint_malloc(sizeof(int) * n); + n_moebius_mu_vec(mu, n); + for (k = 0; k < n; k++) + check(k, mu[k], n_moebius_mu(k)); + flint_free(mu); + } + + mu = flint_malloc(sizeof(int) * 10000); + n_moebius_mu_vec(mu, 10000); + for (k = 0; k < n; k++) + check(k, mu[k], n_moebius_mu(k)); + flint_free(mu); + + check(10000, n_moebius_mu(10000), 0); + check(10001, n_moebius_mu(10001), 1); + check(10002, n_moebius_mu(10002), -1); + check(10003, n_moebius_mu(10003), 1); + check(10004, n_moebius_mu(10004), 0); + check(10005, n_moebius_mu(10005), 1); + check(10006, n_moebius_mu(10006), 1); + check(10007, n_moebius_mu(10007), -1); + check(10008, n_moebius_mu(10008), 0); + check(10009, n_moebius_mu(10009), -1); + check(10010, n_moebius_mu(10010), -1); + + s = 0; + for (k = 0; k <= 10000; k++) + s += n_moebius_mu(k); + + if (s != -23) + { + flint_printf("FAIL:\n"); + flint_printf("expected mu(k), k <= 10000 to sum to %d (got %d)\n", -23, s); + abort(); + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-mulmod2_preinv.c b/external/flint-2.4.3/ulong_extras/test/t-mulmod2_preinv.c new file mode 100644 index 0000000..bc27fc4 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-mulmod2_preinv.c @@ -0,0 +1,72 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("mulmod2_preinv...."); + fflush(stdout); + + + + for (i = 0; i < 100000 * flint_test_multiplier(); i++) + { + mp_limb_t a, b, d, r1, r2, q, p1, p2, dinv; + + d = n_randtest_not_zero(state); + a = n_randtest(state) % d; + b = n_randtest(state) % d; + + dinv = n_preinvert_limb(d); + + r1 = n_mulmod2_preinv(a, b, d, dinv); + + umul_ppmm(p1, p2, a, b); + p1 %= d; + udiv_qrnnd(q, r2, p1, p2, d); + + result = (r1 == r2); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = %wu, b = %wu, d = %wu, dinv = %wu\n", a, b, d, dinv); + flint_printf("q = %wu, r1 = %wu, r2 = %wu\n", q, r1, r2); + abort(); + } + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-mulmod_precomp.c b/external/flint-2.4.3/ulong_extras/test/t-mulmod_precomp.c new file mode 100644 index 0000000..9ddf4f4 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-mulmod_precomp.c @@ -0,0 +1,74 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("mulmod_precomp...."); + fflush(stdout); + + + + for (i = 0; i < 100000 * flint_test_multiplier(); i++) + { + mp_limb_t a, b, d, r1, r2, p1, p2, dinv; + double dpre; + + mp_limb_t bits = n_randint(state, FLINT_D_BITS) + 1; + d = n_randtest_bits(state, bits); + a = n_randtest(state) % d; + b = n_randtest(state) % d; + + dpre = n_precompute_inverse(d); + + r1 = n_mulmod_precomp(a, b, d, dpre); + + umul_ppmm(p1, p2, a, b); + dinv = n_preinvert_limb(d); + r2 = n_ll_mod_preinv(p1, p2, d, dinv); + + result = (r1 == r2); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = %wu, b = %wu, d = %wu, dinv = %f\n", a, b, d, dpre); + flint_printf("r1 = %wu, r2 = %wu\n", r1, r2); + abort(); + } + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-nextprime.c b/external/flint-2.4.3/ulong_extras/test/t-nextprime.c new file mode 100644 index 0000000..b8136ff --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-nextprime.c @@ -0,0 +1,90 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2007, 2008 William Hart + Copyright (C) 2008 Peter Shrimpton + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + mp_limb_t n; + mp_limb_t res1, res2; + slong i, rep; + mpz_t mpz_n; + FLINT_TEST_INIT(state); + + flint_printf("nextprime...."); + fflush(stdout); + + + + if (n_nextprime(0, 0) != 2) + { + flint_printf("FAIL: expected n_nextprime(0) = 2"); + abort(); + } + + if (n_nextprime(UWORD_MAX_PRIME - 1, 0) != UWORD_MAX_PRIME) + { + flint_printf("FAIL: expected n_nextprime(UWORD_MAX_PRIME-1) = UWORD_MAX_PRIME"); + abort(); + } + + mpz_init(mpz_n); + + for (rep = 0; rep < 10000 * flint_test_multiplier(); rep++) + { + ulong bits = n_randint(state, FLINT_D_BITS-1)+1; + n = n_randtest(state) % ((UWORD(1)< +#include +#include "flint.h" +#include "ulong_extras.h" + +void check(ulong n, mp_limb_t ans) +{ + int ok, reasonable; + mp_limb_t lo, hi; + n_nth_prime_bounds(&lo, &hi, n); + + ok = lo <= ans && ans <= hi; + reasonable = (n < 1000) || (ans/2 < lo && hi < ans*2); + + if (ok && reasonable) + return; + + flint_printf("FAIL:\n"); + flint_printf("n = %wu: %wu < %wu < %wu\n", n, lo, ans, hi); + abort(); +} + +int main(void) +{ + int n; + + FLINT_TEST_INIT(state); + + flint_printf("nth_prime_bounds...."); + fflush(stdout); + + for (n=6; n<7500 * FLINT_MIN(10, flint_test_multiplier()); n++) + { + check(n, n_nth_prime(n)); + } + + /* Some known large primes */ + check(UWORD(10), UWORD(29)); + check(UWORD(100), UWORD(541)); + check(UWORD(1000), UWORD(7919)); + check(UWORD(10000), UWORD(104729)); + check(UWORD(100000), UWORD(1299709)); + check(UWORD(1000000), UWORD(15485863)); + check(UWORD(10000000), UWORD(179424673)); + check(UWORD(100000000), UWORD(2038074743)); +#if FLINT64 + check(UWORD(1000000000), UWORD(22801763489)); + check(UWORD(10000000000), UWORD(252097800623)); + check(UWORD(100000000000), UWORD(2760727302517)); + check(UWORD(1000000000000), UWORD(29996224275833)); + check(UWORD(10000000000000), UWORD(323780508946331)); + check(UWORD(100000000000000), UWORD(3475385758524527)); + check(UWORD(1000000000000000), UWORD(37124508045065437)); + check(UWORD(10000000000000000), UWORD(394906913903735329)); + check(UWORD(100000000000000000), UWORD(4185296581467695669)); +#endif + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-pow.c b/external/flint-2.4.3/ulong_extras/test/t-pow.c new file mode 100644 index 0000000..c60d260 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-pow.c @@ -0,0 +1,71 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("pow...."); + fflush(stdout); + + + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) /* Test a^e1 * a^e2 = a^(e1 + e2) */ + { + mp_limb_t exp1, exp2, n, bits, r1, r2; + + bits = n_randint(state, 55) + 10; + exp1 = n_randint(state, 5); + exp2 = n_randint(state, 5); + + if ((exp1 == WORD(0)) && (exp2 == WORD(0))) bits = n_randint(state, 64) + 1; + else bits /= (exp1 + exp2); + + n = n_randtest_bits(state, bits); + + r1 = n_pow(n, exp1)*n_pow(n, exp2); + r2 = n_pow(n, exp1 + exp2); + + result = (r1 == r2); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("n = %wu, exp1 = %wu, exp2 = %wu, r1 = %wu, r2 = %wu\n", n, exp1, exp2, r1, r2); + abort(); + } + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-powmod.c b/external/flint-2.4.3/ulong_extras/test/t-powmod.c new file mode 100644 index 0000000..6c162d4 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-powmod.c @@ -0,0 +1,90 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("powmod...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + mp_limb_t bits, a, d, r1, r2; + mpz_t a_m, d_m, r2_m; + mp_limb_signed_t exp; + + mpz_init(a_m); + mpz_init(d_m); + mpz_init(r2_m); + + bits = n_randint(state, FLINT_D_BITS) + 1; + d = n_randtest_bits(state, bits); + do + { + a = n_randtest(state) % d; + } while (n_gcd(d, a) != UWORD(1)); + exp = n_randtest(state); + + r1 = n_powmod(a, exp, d); + + flint_mpz_set_ui(a_m, a); + flint_mpz_set_ui(d_m, d); + if (exp < WORD(0)) + { + flint_mpz_powm_ui(r2_m, a_m, -exp, d_m); + mpz_invert(r2_m, r2_m, d_m); + } else + flint_mpz_powm_ui(r2_m, a_m, exp, d_m); + r2 = flint_mpz_get_ui(r2_m); + + result = (r1 == r2); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = %wu, exp = %wd, d = %wu\n", a, exp, d); + flint_printf("r1 = %wu, r2 = %wu\n", r1, r2); + abort(); + } + + mpz_clear(a_m); + mpz_clear(d_m); + mpz_clear(r2_m); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-powmod2.c b/external/flint-2.4.3/ulong_extras/test/t-powmod2.c new file mode 100644 index 0000000..c10963d --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-powmod2.c @@ -0,0 +1,89 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("powmod2...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + mp_limb_t a, d, r1, r2; + mpz_t a_m, d_m, r2_m; + mp_limb_signed_t exp; + + mpz_init(a_m); + mpz_init(d_m); + mpz_init(r2_m); + + d = n_randtest_not_zero(state); + do + { + a = n_randtest(state) % d; + } while (n_gcd(d, a) != UWORD(1)); + exp = n_randtest(state); + + r1 = n_powmod2(a, exp, d); + + flint_mpz_set_ui(a_m, a); + flint_mpz_set_ui(d_m, d); + if (exp < WORD(0)) + { + flint_mpz_powm_ui(r2_m, a_m, -exp, d_m); + mpz_invert(r2_m, r2_m, d_m); + } else + flint_mpz_powm_ui(r2_m, a_m, exp, d_m); + r2 = flint_mpz_get_ui(r2_m); + + result = (r1 == r2); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = %wu, exp = %wd, d = %wu\n", a, exp, d); + flint_printf("r1 = %wu, r2 = %wu\n", r1, r2); + abort(); + } + + mpz_clear(a_m); + mpz_clear(d_m); + mpz_clear(r2_m); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-powmod2_preinv.c b/external/flint-2.4.3/ulong_extras/test/t-powmod2_preinv.c new file mode 100644 index 0000000..d55eb2c --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-powmod2_preinv.c @@ -0,0 +1,90 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("powmod2_preinv...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + mp_limb_t a, d, r1, r2, dinv; + mpz_t a_m, d_m, r2_m; + mp_limb_signed_t exp; + + mpz_init(a_m); + mpz_init(d_m); + mpz_init(r2_m); + + d = n_randtest_not_zero(state); + do + { + a = n_randtest(state) % d; + } while (n_gcd(d, a) != UWORD(1)); + exp = n_randtest(state); + + dinv = n_preinvert_limb(d); + r1 = n_powmod2_preinv(a, exp, d, dinv); + + flint_mpz_set_ui(a_m, a); + flint_mpz_set_ui(d_m, d); + if (exp < WORD(0)) + { + flint_mpz_powm_ui(r2_m, a_m, -exp, d_m); + mpz_invert(r2_m, r2_m, d_m); + } else + flint_mpz_powm_ui(r2_m, a_m, exp, d_m); + r2 = flint_mpz_get_ui(r2_m); + + result = (r1 == r2); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = %wu, exp = %wd, d = %wu\n", a, exp, d); + flint_printf("r1 = %wu, r2 = %wu\n", r1, r2); + abort(); + } + + mpz_clear(a_m); + mpz_clear(d_m); + mpz_clear(r2_m); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-powmod2_ui_preinv.c b/external/flint-2.4.3/ulong_extras/test/t-powmod2_ui_preinv.c new file mode 100644 index 0000000..f20b133 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-powmod2_ui_preinv.c @@ -0,0 +1,85 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("powmod2_ui_preinv...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + mp_limb_t a, d, r1, r2, dinv; + mpz_t a_m, d_m, r2_m; + mp_limb_t exp; + + mpz_init(a_m); + mpz_init(d_m); + mpz_init(r2_m); + + d = n_randtest_not_zero(state); + do + { + a = n_randtest(state) % d; + } while (n_gcd(d, a) != UWORD(1)); + exp = n_randtest(state); + + dinv = n_preinvert_limb(d); + r1 = n_powmod2_ui_preinv(a, exp, d, dinv); + + flint_mpz_set_ui(a_m, a); + flint_mpz_set_ui(d_m, d); + flint_mpz_powm_ui(r2_m, a_m, exp, d_m); + r2 = flint_mpz_get_ui(r2_m); + + result = (r1 == r2); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = %wu, exp = %wu, d = %wu\n", a, exp, d); + flint_printf("r1 = %wu, r2 = %wu\n", r1, r2); + abort(); + } + + mpz_clear(a_m); + mpz_clear(d_m); + mpz_clear(r2_m); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-powmod_precomp.c b/external/flint-2.4.3/ulong_extras/test/t-powmod_precomp.c new file mode 100644 index 0000000..7df4ea7 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-powmod_precomp.c @@ -0,0 +1,92 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("powmod_precomp...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + mp_limb_t a, d, r1, r2, bits; + mpz_t a_m, d_m, r2_m; + mp_limb_signed_t exp; + double dpre; + + mpz_init(a_m); + mpz_init(d_m); + mpz_init(r2_m); + + bits = n_randint(state, FLINT_D_BITS) + 1; + d = n_randtest_bits(state, bits); + do + { + a = n_randtest(state) % d; + } while (n_gcd(d, a) != UWORD(1)); + exp = n_randtest(state); + + dpre = n_precompute_inverse(d); + r1 = n_powmod_precomp(a, exp, d, dpre); + + flint_mpz_set_ui(a_m, a); + flint_mpz_set_ui(d_m, d); + if (exp < WORD(0)) + { + flint_mpz_powm_ui(r2_m, a_m, -exp, d_m); + mpz_invert(r2_m, r2_m, d_m); + } else + flint_mpz_powm_ui(r2_m, a_m, exp, d_m); + r2 = flint_mpz_get_ui(r2_m); + + result = (r1 == r2); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = %wu, exp = %wd, d = %wu\n", a, exp, d); + flint_printf("r1 = %wu, r2 = %wu\n", r1, r2); + abort(); + } + + mpz_clear(a_m); + mpz_clear(d_m); + mpz_clear(r2_m); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-powmod_ui_precomp.c b/external/flint-2.4.3/ulong_extras/test/t-powmod_ui_precomp.c new file mode 100644 index 0000000..f00144e --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-powmod_ui_precomp.c @@ -0,0 +1,87 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("powmod_ui_precomp...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + mp_limb_t a, d, r1, r2, bits; + mpz_t a_m, d_m, r2_m; + mp_limb_t exp; + double dpre; + + mpz_init(a_m); + mpz_init(d_m); + mpz_init(r2_m); + + bits = n_randint(state, FLINT_D_BITS) + 1; + d = n_randtest_bits(state, bits); + do + { + a = n_randtest(state) % d; + } while (n_gcd(d, a) != UWORD(1)); + exp = n_randtest(state); + + dpre = n_precompute_inverse(d); + r1 = n_powmod_ui_precomp(a, exp, d, dpre); + + flint_mpz_set_ui(a_m, a); + flint_mpz_set_ui(d_m, d); + flint_mpz_powm_ui(r2_m, a_m, exp, d_m); + r2 = flint_mpz_get_ui(r2_m); + + result = (r1 == r2); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = %wu, exp = %wd, d = %wu\n", a, exp, d); + flint_printf("r1 = %wu, r2 = %wu\n", r1, r2); + abort(); + } + + mpz_clear(a_m); + mpz_clear(d_m); + mpz_clear(r2_m); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-prime_pi.c b/external/flint-2.4.3/ulong_extras/test/t-prime_pi.c new file mode 100644 index 0000000..0a69947 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-prime_pi.c @@ -0,0 +1,63 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int n; + + FLINT_TEST_INIT(state); + + flint_printf("prime_pi...."); + fflush(stdout); + + for (n=1; n<10000 * FLINT_MIN(10, flint_test_multiplier()); n++) + { + if ((n_prime_pi(n-1)+1 == n_prime_pi(n)) != n_is_prime(n)) + { + flint_printf("FAIL:\n"); + flint_printf("expected pi(%d) + 1 = pi(%d)\n", n-1, n); + abort(); + } + } + + for (n=1; n<5000 * FLINT_MIN(10, flint_test_multiplier()); n++) + { + if (n_prime_pi(n_nth_prime(n)) != n) + { + flint_printf("FAIL:\n"); + flint_printf("expected pi(prime(%d)) = %d\n", n, n); + abort(); + } + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-prime_pi_bounds.c b/external/flint-2.4.3/ulong_extras/test/t-prime_pi_bounds.c new file mode 100644 index 0000000..0123285 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-prime_pi_bounds.c @@ -0,0 +1,84 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2010 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +void check(mp_limb_t n, ulong ans) +{ + int ok, reasonable; + ulong lo, hi; + n_prime_pi_bounds(&lo, &hi, n); + + ok = lo <= ans && ans <= hi; + reasonable = (n < 1000) || (ans/2 < lo && hi < ans*2); + + if (ok && reasonable) + return; + + flint_printf("FAIL:\n"); + flint_printf("n = %wu: %wu < %wu < %wu\n", n, lo, ans, hi); + abort(); +} + +int main(void) +{ + int n; + + FLINT_TEST_INIT(state); + flint_printf("prime_pi_bounds...."); + fflush(stdout); + + for (n=17; n<10000 * FLINT_MIN(10, flint_test_multiplier()); n++) + { + check(n, n_prime_pi(n)); + } + + check(UWORD(10), UWORD(4)); + check(UWORD(100), UWORD(25)); + check(UWORD(1000), UWORD(168)); + check(UWORD(10000), UWORD(1229)); + check(UWORD(100000), UWORD(9592)); + check(UWORD(1000000), UWORD(78498)); + check(UWORD(10000000), UWORD(664579)); + check(UWORD(100000000), UWORD(5761455)); + check(UWORD(1000000000), UWORD(50847534)); +#if FLINT64 + check(UWORD(10000000000), UWORD(455052511)); + check(UWORD(100000000000), UWORD(4118054813)); + check(UWORD(1000000000000), UWORD(37607912018)); + check(UWORD(10000000000000), UWORD(346065536839)); + check(UWORD(100000000000000), UWORD(3204941750802)); + check(UWORD(1000000000000000), UWORD(29844570422669)); + check(UWORD(10000000000000000), UWORD(279238341033925)); + check(UWORD(100000000000000000), UWORD(2623557157654233)); +#endif + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-primes.c b/external/flint-2.4.3/ulong_extras/test/t-primes.c new file mode 100644 index 0000000..c51c043 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-primes.c @@ -0,0 +1,98 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + slong n; + + FLINT_TEST_INIT(state); + + flint_printf("primes...."); + fflush(stdout); + + _flint_rand_init_gmp(state); + + /* compare with n_nextprime */ + { + n_primes_t iter; + slong i; + mp_limb_t p, q; + + n_primes_init(iter); + q = 0; + for (i = 0; i < 200000; i++) + { + p = n_primes_next(iter); + q = n_nextprime(q, 0); + + if (p != q) + { + flint_printf("FAIL\n"); + flint_printf("i = %wu, p = %wu, q = %wu\n", i, p, q); + abort(); + } + } + + n_primes_clear(iter); + } + + /* count primes */ + for (n = 0; n < 10; n++) + { + n_primes_t iter; + mp_limb_t s, p, r; + + const unsigned int primepi[10] = { + 0, 4, 25, 168, 1229, 9592, 78498, 664579, 5761455, 50847534 + }; + + r = n_pow(10, n); + + n_primes_init(iter); + s = 0; + while ((p = n_primes_next(iter)) <= r) + s++; + + if (s != primepi[n]) + { + flint_printf("FAIL\n"); + flint_printf("pi(10^%wd) = %u, computed = %wu\n", n, primepi[n], s); + abort(); + } + + n_primes_clear(iter); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-primes_jump_after.c b/external/flint-2.4.3/ulong_extras/test/t-primes_jump_after.c new file mode 100644 index 0000000..0536fd8 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-primes_jump_after.c @@ -0,0 +1,76 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; 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 +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + slong j, k, l; + + FLINT_TEST_INIT(state); + + flint_printf("primes_jump_after...."); + fflush(stdout); + + for (j = 0; j < 10; j++) + { + n_primes_t iter; + + n_primes_init(iter); + + for (k = 0; k < 100; k++) + { + mp_limb_t p, q; + + q = n_randtest(state) % UWORD(1000000000); + + n_primes_jump_after(iter, q); + + for (l = 0; l < 100; l++) + { + p = n_primes_next(iter); + q = n_nextprime(q, 0); + + if (p != q) + { + flint_printf("FAIL\n"); + flint_printf("p = %wu, q = %wu\n", p, q); + abort(); + } + } + } + + n_primes_clear(iter); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-primitive_root_prime.c b/external/flint-2.4.3/ulong_extras/test/t-primitive_root_prime.c new file mode 100644 index 0000000..b4d7bc0 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-primitive_root_prime.c @@ -0,0 +1,66 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2013 Mike Hansen + +******************************************************************************/ +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, j; + FLINT_TEST_INIT(state); + + flint_printf("primitive_root_prime...."); + fflush(stdout); + + for (i = 0; i < 100; i++) + { + n_factor_t factors; + mp_limb_t p, root; + double pinv; + + n_factor_init(&factors); + p = n_randtest_prime(state, 1); + pinv = n_precompute_inverse(p); + n_factor(&factors, p - 1, 1); + + root = n_primitive_root_prime(p); + + for (j = 0; j < factors.num; j++) + { + if (n_powmod_precomp(root, (p-1) / factors.p[j], p, pinv) == 1) + { + flint_printf("FAIL:\n"); + flint_printf("%wu ** (%wu / %wu) == 1 mod %wu\n", root, p-1, factors.p[j], p); + abort(); + } + } + } + + FLINT_TEST_CLEANUP(state); + flint_printf("PASS\n"); + return 0; + +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-remove.c b/external/flint-2.4.3/ulong_extras/test/t-remove.c new file mode 100644 index 0000000..4d94ad8 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-remove.c @@ -0,0 +1,122 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("remove...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) /* Test random numbers */ + { + mp_limb_t n1, n2, orig_n; + mpz_t d_n2, d_n1, d_p; + int exp1, exp2; + ulong j; + + mpz_init(d_n1); + mpz_init(d_n2); + mpz_init(d_p); + + n1 = n_randtest_not_zero(state); + orig_n = n1; + + for (j = 0; j < FLINT_NUM_PRIMES_SMALL/10; j++) + { + flint_mpz_set_ui(d_n1, n1); + flint_mpz_set_ui(d_p, flint_primes_small[j]); + exp1 = n_remove(&n1, flint_primes_small[j]); + exp2 = mpz_remove(d_n2, d_n1, d_p); + n2 = flint_mpz_get_ui(d_n2); + + result = ((exp1 == exp2) && (n1 == n2)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("n = %wu, exp1 = %d, exp2 = %d, n1 = %wu, n2 = %wu, p = %d\n", orig_n, exp1, exp2, n1, n2, flint_primes_small[j]); + abort(); + } + } + + mpz_clear(d_n1); + mpz_clear(d_n2); + mpz_clear(d_p); + } + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) /* Test perfect powers */ + { + mp_limb_t n1, n2, orig_n, base; + mpz_t d_n2, d_n1, d_p; + int exp1, exp2, exp; + ulong j; + + mpz_init(d_n1); + mpz_init(d_n2); + mpz_init(d_p); + + base = n_randtest_not_zero(state); + n1 = base; + exp = n_randint(state, FLINT_BITS/FLINT_BIT_COUNT(n1)) + 1; + n1 = n_pow(base, exp); + + orig_n = n1; + + for (j = 0; j < FLINT_NUM_PRIMES_SMALL/10; j++) + { + flint_mpz_set_ui(d_n1, n1); + flint_mpz_set_ui(d_p, flint_primes_small[j]); + exp1 = n_remove(&n1, flint_primes_small[j]); + exp2 = mpz_remove(d_n2, d_n1, d_p); + n2 = flint_mpz_get_ui(d_n2); + + result = ((exp1 == exp2) && (n1 == n2)); + if (!result) + { + flint_printf("FAIL\n"); + flint_printf("n = %wu, exp1 = %d, exp2 = %d, n1 = %wu, n2 = %wu, p = %d\n", orig_n, exp1, exp2, n1, n2, flint_primes_small[j]); + abort(); + } + } + + mpz_clear(d_n1); + mpz_clear(d_n2); + mpz_clear(d_p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-remove2_precomp.c b/external/flint-2.4.3/ulong_extras/test/t-remove2_precomp.c new file mode 100644 index 0000000..198380a --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-remove2_precomp.c @@ -0,0 +1,126 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + const mp_limb_t * primes; + const double * inverses; + + FLINT_TEST_INIT(state); + + flint_printf("remove2_precomp...."); + fflush(stdout); + + primes = n_primes_arr_readonly(10000); + inverses = n_prime_inverses_arr_readonly(10000); + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) /* Test random numbers */ + { + mp_limb_t n1, n2, orig_n; + mpz_t d_n2, d_n1, d_p; + int exp1, exp2; + ulong j; + + mpz_init(d_n1); + mpz_init(d_n2); + mpz_init(d_p); + + n1 = n_randtest_not_zero(state); + orig_n = n1; + + for (j = 0; j < FLINT_NUM_PRIMES_SMALL/10; j++) + { + flint_mpz_set_ui(d_n1, n1); + flint_mpz_set_ui(d_p, flint_primes_small[j]); + exp1 = n_remove2_precomp(&n1, primes[j], inverses[j]); + exp2 = mpz_remove(d_n2, d_n1, d_p); + n2 = flint_mpz_get_ui(d_n2); + + result = ((exp1 == exp2) && (n1 == n2)); + if (!result) + { + flint_printf("FAIL\n"); + flint_printf("n = %wu, exp1 = %d, exp2 = %d, n1 = %wu, n2 = %wu, p = %d\n", orig_n, exp1, exp2, n1, n2, flint_primes_small[j]); + abort(); + } + } + + mpz_clear(d_n1); + mpz_clear(d_n2); + mpz_clear(d_p); + } + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) /* Test perfect powers */ + { + mp_limb_t n1, n2, orig_n, base; + mpz_t d_n2, d_n1, d_p; + int exp1, exp2, exp; + ulong j; + + mpz_init(d_n1); + mpz_init(d_n2); + mpz_init(d_p); + + base = n_randtest_not_zero(state); + n1 = base; + exp = n_randint(state, FLINT_BITS/FLINT_BIT_COUNT(n1)) + 1; + n1 = n_pow(base, exp); + + orig_n = n1; + + for (j = 0; j < FLINT_NUM_PRIMES_SMALL/10; j++) + { + flint_mpz_set_ui(d_n1, n1); + flint_mpz_set_ui(d_p, flint_primes_small[j]); + exp1 = n_remove2_precomp(&n1, primes[j], inverses[j]); + exp2 = mpz_remove(d_n2, d_n1, d_p); + n2 = flint_mpz_get_ui(d_n2); + + result = ((exp1 == exp2) && (n1 == n2)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("n = %wu, exp1 = %d, exp2 = %d, n1 = %wu, n2 = %wu, p = %d\n", orig_n, exp1, exp2, n1, n2, flint_primes_small[j]); + abort(); + } + } + + mpz_clear(d_n1); + mpz_clear(d_n2); + mpz_clear(d_p); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-sizeinbase.c b/external/flint-2.4.3/ulong_extras/test/t-sizeinbase.c new file mode 100644 index 0000000..ddc07e3 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-sizeinbase.c @@ -0,0 +1,77 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Fredrik Johansson + +******************************************************************************/ + +#include +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + mp_limb_t n; + int base, size1, size2; + slong rep; + mpz_t t; + char * str; + + FLINT_TEST_INIT(state); + + flint_printf("sizeinbase...."); + fflush(stdout); + + + mpz_init(t); + str = flint_malloc((FLINT_BITS + 1) * sizeof(char)); + + for (rep = 0; rep < 1000 * flint_test_multiplier(); rep++) + { + n = n_randtest(state); + base = 2 + n_randint(state, 34); + + size1 = n_sizeinbase(n, base); + + flint_mpz_set_ui(t, n); + + mpz_get_str(str, base, t); + size2 = strlen(str); + + if (size1 != size2) + { + flint_printf("FAIL: n = %wu, base = %d\n", n, base); + flint_printf("n_sizeinbase: %d, strlen: %d\n", size1, size2); + abort(); + } + } + + flint_free(str); + mpz_clear(t); + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-sqrt.c b/external/flint-2.4.3/ulong_extras/test/t-sqrt.c new file mode 100644 index 0000000..6ecc126 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-sqrt.c @@ -0,0 +1,104 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("sqrt...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + mp_limb_t a, s1, s2; + mpz_t a_m, s2_m; + + mpz_init(a_m); + mpz_init(s2_m); + + a = n_randtest(state); + + s1 = n_sqrt(a); + + flint_mpz_set_ui(a_m, a); + mpz_sqrt(s2_m, a_m); + s2 = flint_mpz_get_ui(s2_m); + + result = (s1 == s2); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = %wu, s1 = %wd, s2 = %wu\n", a, s1, s2); + abort(); + } + + mpz_clear(a_m); + mpz_clear(s2_m); + } + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + mp_limb_t a, s1, s2, bits; + mpz_t a_m, s2_m; + + mpz_init(a_m); + mpz_init(s2_m); + + bits = n_randint(state, FLINT_BITS/2 + 1); + a = n_randtest_bits(state, bits); + a = a*a; + a += (n_randint(state, 100) - 50); + s1 = n_sqrt(a); + + flint_mpz_set_ui(a_m, a); + mpz_sqrt(s2_m, a_m); + s2 = flint_mpz_get_ui(s2_m); + + result = (s1 == s2); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = %wu, s1 = %wd, s2 = %wu\n", a, s1, s2); + abort(); + } + + mpz_clear(a_m); + mpz_clear(s2_m); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-sqrtmod.c b/external/flint-2.4.3/ulong_extras/test/t-sqrtmod.c new file mode 100644 index 0000000..87f8724 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-sqrtmod.c @@ -0,0 +1,93 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("sqrtmod...."); + fflush(stdout); + + + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) /* Test random integers */ + { + mp_limb_t a, b, p, pinv; + + p = n_randtest_prime(state, 0); + a = n_randtest(state) % p; + + b = n_sqrtmod(a, p); + pinv = n_preinvert_limb(p); + + result = (b == 0 || n_mulmod2_preinv(b, b, p, pinv) == a); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("p = %wu\n", p); + flint_printf("a = %wu\n", a); + flint_printf("b = %wu\n", b); + abort(); + } + } + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) /* Test random squares */ + { + mp_limb_t a, b, p, pinv; + + p = n_randtest_prime(state, 0); + + do + b = n_randtest(state) % p; + while (b == 0); + + pinv = n_preinvert_limb(p); + a = n_mulmod2_preinv(b, b, p, pinv); + + b = n_sqrtmod(a, p); + + result = (n_mulmod2_preinv(b, b, p, pinv) == a); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("p = %wu\n", p); + flint_printf("a = %wu\n", a); + flint_printf("b = %wu\n", b); + abort(); + } + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-sqrtmod_primepow.c b/external/flint-2.4.3/ulong_extras/test/t-sqrtmod_primepow.c new file mode 100644 index 0000000..6e450a1 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-sqrtmod_primepow.c @@ -0,0 +1,215 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("sqrtmod_primepow...."); + fflush(stdout); + + + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) /* Test random squares mod a power of 2 */ + { + mp_limb_t a, b, p, pow, pow2, pinv; + slong exp, num, i; + mp_limb_t * sqrt; + int btest; + + p = 2; + exp = n_randint(state, FLINT_BITS - 1) + 1; + pow = n_pow(p, exp); + b = n_randtest(state) % pow; + + pow2 = p; + while (FLINT_BIT_COUNT(p*pow2) <= 12) + pow2 *= p; + + if ((b % (p*pow2)) == 0) + { + b += pow2; + b %= pow; + } + + pinv = n_preinvert_limb(pow); + a = n_mulmod2_preinv(b, b, pow, pinv); + + num = n_sqrtmod_primepow(&sqrt, a, p, exp); + + btest = 0; + for (i = 0; i < num; i++) + { + if (a != n_mulmod2_preinv(sqrt[i], sqrt[i], pow, pinv)) + break; + if (sqrt[i] == b) + btest = 1; + } + + result = btest & (i == num); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("p = %wu\n", p); + flint_printf("exp = %wd\n", exp); + flint_printf("a = %wu\n", a); + flint_printf("b = %wu\n", b); + flint_printf("num = %wd\n", num); + + if (!btest) + flint_printf("Square root not found.\n"); + if (i != num) + flint_printf("%wu not a square root of %wu mod %wu\n", sqrt[i], a, pow); + + abort(); + } + + flint_free(sqrt); + } + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) /* Test random squares mod other prime powers */ + { + mp_limb_t a, b, p, pow, pow2, pinv; + slong exp, maxexp, num, i; + mp_bitcnt_t bits; + mp_limb_t * sqrt; + int btest; + + bits = n_randint(state, 18) + 2; + p = n_randprime(state, bits, 0); + maxexp = FLINT_BITS/bits; + exp = n_randint(state, maxexp) + 1; + pow = n_pow(p, exp); + b = n_randtest(state) % pow; + + if (bits <= FLINT_BITS/2) + { + pow2 = p; + while (FLINT_BIT_COUNT(p*pow2) <= 12) + pow2 *= p; + + if ((b % (p*pow2)) == 0) + b += pow2; + + b %= pow; + } + + pinv = n_preinvert_limb(pow); + a = n_mulmod2_preinv(b, b, pow, pinv); + + num = n_sqrtmod_primepow(&sqrt, a, p, exp); + + btest = 0; + for (i = 0; i < num; i++) + { + if (a != n_mulmod2_preinv(sqrt[i], sqrt[i], pow, pinv)) + break; + if (sqrt[i] == b) + btest = 1; + } + + result = btest & (i == num); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("p = %wu\n", p); + flint_printf("exp = %wd\n", exp); + flint_printf("a = %wu\n", a); + flint_printf("b = %wu\n", b); + flint_printf("num = %wd\n", num); + + if (!btest) + flint_printf("Square root not found.\n"); + if (i != num) + flint_printf("%wu not a square root of %wu mod %wu\n", sqrt[i], a, pow); + + abort(); + } + + flint_free(sqrt); + } + + for (i = 0; i < 500 * flint_test_multiplier(); i++) /* Test random nonsquares */ + { + mp_limb_t a, b, p, pow, pinv; + slong exp, maxexp; + mp_bitcnt_t bits; + mp_limb_t * sqrt; + + bits = n_randint(state, 18) + 2; + p = n_randprime(state, bits, 0); + maxexp = 20/bits; + exp = n_randint(state, maxexp) + 1 + (p == 2); + pow = n_pow(p, exp); + + pinv = n_preinvert_limb(pow); + + a = n_randtest(state) % pow; + while (n_sqrtmod_primepow(&sqrt, a, p, exp)) + { + if (n_mulmod2_preinv(sqrt[0], sqrt[0], pow, pinv) != a) + { + flint_printf("FAIL:\n"); + flint_printf("%wu^2 is not %wu mod %wu\n", sqrt[0], a, pow); + abort(); + } + + flint_free(sqrt); + a = n_randtest(state) % pow; + } + + for (b = 0; b < pow; b++) + { + if (n_mulmod2_preinv(b, b, pow, pinv) == a) + break; + } + + result = (b == pow); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("p = %wu\n", p); + flint_printf("exp = %wd\n", exp); + flint_printf("a = %wu\n", a); + flint_printf("b = %wu\n", b); + + abort(); + } + + flint_free(sqrt); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-sqrtmodn.c b/external/flint-2.4.3/ulong_extras/test/t-sqrtmodn.c new file mode 100644 index 0000000..39ea74e --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-sqrtmodn.c @@ -0,0 +1,146 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2011 Sebastian Pancratz + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("sqrtmodn...."); + fflush(stdout); + + + + for (i = 0; i < 1000 * flint_test_multiplier(); i++) /* Test random squares mod n */ + { + mp_limb_t a, b, n, ninv; + slong num, i; + mp_bitcnt_t bits; + mp_limb_t * sqrt; + int btest; + n_factor_t fac; + + bits = n_randint(state, 18) + 2; + n = n_randtest_bits(state, bits); + if (n == 0) n = 1; + b = n_randtest(state) % n; + + n_factor_init(&fac); + n_factor(&fac, n, 0); + + ninv = n_preinvert_limb(n); + a = n_mulmod2_preinv(b, b, n, ninv); + + num = n_sqrtmodn(&sqrt, a, &fac); + + btest = 0; + for (i = 0; i < num; i++) + { + if (a != n_mulmod2_preinv(sqrt[i], sqrt[i], n, ninv)) + break; + if (sqrt[i] == b) + btest = 1; + } + + result = btest & (i == num); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("n = %wu\n", n); + flint_printf("a = %wu\n", a); + flint_printf("b = %wu\n", b); + flint_printf("num = %wd\n", num); + + if (!btest) + flint_printf("Square root not found.\n"); + if (i != num) + flint_printf("%wu not a square root of %wu mod %wu\n", sqrt[i], a, n); + + abort(); + } + + flint_free(sqrt); + } + + for (i = 0; i < 500 * flint_test_multiplier(); i++) /* test random nonsquares */ + { + mp_limb_t a, b, n, ninv; + mp_bitcnt_t bits; + mp_limb_t * sqrt; + n_factor_t fac; + + bits = n_randint(state, 18) + 2; + n = n_randtest_bits(state, bits); + if (n == 2) n++; + n_factor_init(&fac); + n_factor(&fac, n, 0); + + ninv = n_preinvert_limb(n); + + a = n_randtest(state) % n; + while (n_sqrtmodn(&sqrt, a, &fac)) + { + if (n_mulmod2_preinv(sqrt[0], sqrt[0], n, ninv) != a) + { + flint_printf("FAIL:\n"); + flint_printf("%wu^2 is not %wu mod %wu\n", sqrt[0], a, n); + abort(); + } + + flint_free(sqrt); + a = n_randtest(state) % n; + } + + for (b = 0; b < n; b++) + { + if (n_mulmod2_preinv(b, b, n, ninv) == a) + break; + } + + result = (b == n); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("n = %wu\n", n); + flint_printf("a = %wu\n", a); + flint_printf("b = %wu\n", b); + + abort(); + } + + flint_free(sqrt); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-sqrtrem.c b/external/flint-2.4.3/ulong_extras/test/t-sqrtrem.c new file mode 100644 index 0000000..93a1fc9 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-sqrtrem.c @@ -0,0 +1,110 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("sqrtrem...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + mp_limb_t a, r1, r2, s1, s2; + mpz_t a_m, r2_m, s2_m; + + mpz_init(a_m); + mpz_init(r2_m); + mpz_init(s2_m); + + a = n_randtest(state); + + s1 = n_sqrtrem(&r1, a); + + flint_mpz_set_ui(a_m, a); + mpz_sqrtrem(s2_m, r2_m, a_m); + r2 = flint_mpz_get_ui(r2_m); + s2 = flint_mpz_get_ui(s2_m); + + result = ((r1 == r2) && (s1 == s2)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = %wu, r1 = %wd, r2 = %wu, s1 = %wd, s2 = %wu\n", a, r1, r2, s1, s2); + abort(); + } + + mpz_clear(a_m); + mpz_clear(r2_m); + mpz_clear(s2_m); + } + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + mp_limb_t a, r1, r2, s1, s2, bits; + mpz_t a_m, r2_m, s2_m; + + mpz_init(a_m); + mpz_init(r2_m); + mpz_init(s2_m); + + bits = n_randint(state, FLINT_BITS/2 + 1); + a = n_randtest_bits(state, bits); + a = a*a; + a += (n_randint(state, 100) - 50); + s1 = n_sqrtrem(&r1, a); + + flint_mpz_set_ui(a_m, a); + mpz_sqrtrem(s2_m, r2_m, a_m); + r2 = flint_mpz_get_ui(r2_m); + s2 = flint_mpz_get_ui(s2_m); + + result = ((r1 == r2) && (s1 == s2)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = %wu, r1 = %wd, r2 = %wu, s1 = %wd, s2 = %wu\n", a, r1, r2, s1, s2); + abort(); + } + + mpz_clear(a_m); + mpz_clear(r2_m); + mpz_clear(s2_m); + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-submod.c b/external/flint-2.4.3/ulong_extras/test/t-submod.c new file mode 100644 index 0000000..0132ab6 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-submod.c @@ -0,0 +1,70 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("submod...."); + fflush(stdout); + + + + for (i = 0; i < 100000 * flint_test_multiplier(); i++) + { + mp_limb_t a, b, d, r1, r2, s1; + + d = n_randtest_not_zero(state); + a = n_randtest(state)%d; + b = n_randtest(state)%d; + + r1 = n_submod(a, b, d); + + add_ssaaaa(s1, r2, UWORD(0), a, UWORD(0), d); + sub_ddmmss(s1, r2, s1, r2, UWORD(0), b); + if ((s1) || (r2 >= d)) r2 -= d; + + result = (r1 == r2); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = %wu, b = %wu, d = %wu\n", a, b, d); + flint_printf("r1 = %wu, r2 = %wu\n", r1, r2); + abort(); + } + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/test/t-xgcd.c b/external/flint-2.4.3/ulong_extras/test/t-xgcd.c new file mode 100644 index 0000000..3ab5ee7 --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/test/t-xgcd.c @@ -0,0 +1,78 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include +#include +#include "flint.h" +#include "ulong_extras.h" + +int main(void) +{ + int i, result; + FLINT_TEST_INIT(state); + + flint_printf("xgcd...."); + fflush(stdout); + + + + for (i = 0; i < 10000 * flint_test_multiplier(); i++) + { + mp_limb_t a, b, c, g, bits1, bits2, bits3, ph, pl, qh, ql; + mp_limb_t s, t; + + bits1 = n_randint(state, FLINT_BITS-1) + 1; + bits2 = n_randint(state, bits1) + 1; + bits3 = n_randint(state, FLINT_BITS - bits1) + 1; + + do + { + a = n_randtest_bits(state, bits1); + b = n_randtest_bits(state, bits2); + } while ((n_gcd(a, b) != UWORD(1)) || (b > a)); + + c = n_randtest_bits(state, bits3); + + g = n_xgcd(&s, &t, a*c, b*c); + + umul_ppmm(ph, pl, a*c, s); + umul_ppmm(qh, ql, b*c, t); + sub_ddmmss(ph, pl, ph, pl, qh, ql); + + result = ((g == c) && (ph == UWORD(0)) && (pl == c)); + if (!result) + { + flint_printf("FAIL:\n"); + flint_printf("a = %wu, b = %wu, c = %wu, g = %wu, s = %wu, t = %wu\n", a, b, c, g, s, t); + abort(); + } + } + + FLINT_TEST_CLEANUP(state); + + flint_printf("PASS\n"); + return 0; +} diff --git a/external/flint-2.4.3/ulong_extras/xgcd.c b/external/flint-2.4.3/ulong_extras/xgcd.c new file mode 100644 index 0000000..9febaaa --- /dev/null +++ b/external/flint-2.4.3/ulong_extras/xgcd.c @@ -0,0 +1,172 @@ +/*============================================================================= + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=============================================================================*/ +/****************************************************************************** + + Copyright (C) 2009 William Hart + +******************************************************************************/ + +#include +#include "flint.h" +#include "ulong_extras.h" + +mp_limb_t +n_xgcd(mp_limb_t * a, mp_limb_t * b, mp_limb_t x, mp_limb_t y) +{ + mp_limb_signed_t u1 = UWORD(1); + mp_limb_signed_t u2 = UWORD(0); + mp_limb_signed_t v1 = UWORD(0); + mp_limb_signed_t v2 = UWORD(1); + mp_limb_signed_t t1, t2; + mp_limb_t u3, v3; + mp_limb_t quot, rem; + + u3 = x, v3 = y; + + if (v3 > u3) + { + rem = u3; + t1 = u2; + u2 = u1; + u1 = t1; + u3 = v3; + t2 = v2; + v2 = v1; + v1 = t2; + v3 = rem; + } + + if ((mp_limb_signed_t) (x & y) < WORD(0)) /* x and y both have top bit set */ + { + quot = u3 - v3; + t2 = v2; + t1 = u2; + u2 = u1 - u2; + u1 = t1; + u3 = v3; + v2 = v1 - v2; + v1 = t2; + v3 = quot; + } + + while ((mp_limb_signed_t) (v3 << 1) < WORD(0)) /*second value has second msb set */ + { + quot = u3 - v3; + if (quot < v3) + { + t2 = v2; + t1 = u2; + u2 = u1 - u2; + u1 = t1; + u3 = v3; + v2 = v1 - v2; + v1 = t2; + v3 = quot; + } + else if (quot < (v3 << 1)) + { + t1 = u2; + u2 = u1 - (u2 << 1); + u1 = t1; + u3 = v3; + t2 = v2; + v2 = v1 - (v2 << 1); + v1 = t2; + v3 = quot - u3; + } + else + { + t1 = u2; + u2 = u1 - 3 * u2; + u1 = t1; + u3 = v3; + t2 = v2; + v2 = v1 - 3 * v2; + v1 = t2; + v3 = quot - (u3 << 1); + } + } + + while (v3) + { + quot = u3 - v3; + if (u3 < (v3 << 2)) /* overflow not possible due to top 2 bits of v3 not being set */ + { + if (quot < v3) + { + t2 = v2; + t1 = u2; + u2 = u1 - u2; + u1 = t1; + u3 = v3; + v2 = v1 - v2; + v1 = t2; + v3 = quot; + } + else if (quot < (v3 << 1)) + { + t1 = u2; + u2 = u1 - (u2 << 1); + u1 = t1; + u3 = v3; + t2 = v2; + v2 = v1 - (v2 << 1); + v1 = t2; + v3 = quot - u3; + } + else + { + t1 = u2; + u2 = u1 - 3 * u2; + u1 = t1; + u3 = v3; + t2 = v2; + v2 = v1 - 3 * v2; + v1 = t2; + v3 = quot - (u3 << 1); + } + } + else + { + quot = u3 / v3; + rem = u3 - v3 * quot; + t1 = u2; + u2 = u1 - quot * u2; + u1 = t1; + u3 = v3; + t2 = v2; + v2 = v1 - quot * v2; + v1 = t2; + v3 = rem; + } + } + + /* Quite remarkably, this always has |u1| < x/2 at this point, thus comparison with 0 is valid */ + if (u1 <= WORD(0)) + { + u1 += y; + v1 -= x; + } + + *a = u1; + *b = -v1; + + return u3; +} diff --git a/external/flint-2.4.3/version.c b/external/flint-2.4.3/version.c new file mode 100644 index 0000000..49acafa --- /dev/null +++ b/external/flint-2.4.3/version.c @@ -0,0 +1,28 @@ +/*============================================================================ + + This file is part of FLINT. + + FLINT 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. + + FLINT 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 FLINT; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +===============================================================================*/ +/****************************************************************************** + + (C) 2011 William Hart + +******************************************************************************/ + +#include "flint.h" + +char version[]=FLINT_VERSION; From 7b0a1f19204cb7ba62cb4d787f3715264d5ec0a3 Mon Sep 17 00:00:00 2001 From: hasufell Date: Mon, 19 May 2014 00:04:00 +0200 Subject: [PATCH 02/26] BUILD: Fix Makefiles for flint --- Makefile | 1 + src/Makefile | 20 ++++++++++++++------ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index d16c097..0f8d809 100644 --- a/Makefile +++ b/Makefile @@ -10,6 +10,7 @@ clean: clean-all: clean $(MAKE) -C external/libtommath-0.42.0 clean $(MAKE) -C external/libtompoly-0.04 clean + $(MAKE) -C external/flint-2.4.3 clean doc: doxygen diff --git a/src/Makefile b/src/Makefile index bd89c5d..9811bf7 100644 --- a/src/Makefile +++ b/src/Makefile @@ -34,7 +34,7 @@ else PQC_LIBS = libpqc.a endif # CUNIT_LIBS = -lcunit -LIBS += -L. +LIBS += -L. -lgmp -lmpfr -lm # objects PQC_OBJS = rand.o poly.o mem.o ntru_decrypt.o pqc_encrypt.o @@ -47,10 +47,14 @@ INCS = -I. ifndef UNBUNDLE LIBTOMMATH = ../external/libtommath-0.42.0/libtommath.a LIBTOMPOLY = ../external/libtompoly-0.04/libtompoly.a -INCS += -I../external/libtommath-0.42.0 -I../external/libtompoly-0.04 +LIBFLINT = ../external/flint-2.4.3/libflint.a +INCS += -I../external/libtommath-0.42.0 \ + -I../external/libtompoly-0.04 \ + -I../external/flint-2.4.3 else LIBTOMMATH = -ltommath LIBTOMPOLY = -ltompoly +LIBFLINT = -lflint endif @@ -69,18 +73,22 @@ $(LIBTOMMATH): $(LIBTOMPOLY): $(MAKE) -C ../external/libtompoly-0.04 + +$(LIBFLINT): + cd ../external/flint-2.4.3 && ./configure --prefix=/usr --with-gmp=/usr --with-mpfr=/usr --disable-shared + $(MAKE) -C ../external/flint-2.4.3 endif libpqc.a: $(PQC_OBJS) $(PQC_HEADERS) $(AR) cru libpqc.a $(PQC_OBJS) -libpqc.so: libpqc.a $(PQC_HEADERS) $(LIBTOMMATH) $(LIBTOMPOLY) +libpqc.so: libpqc.a $(PQC_HEADERS) $(LIBTOMMATH) $(LIBTOMPOLY) $(LIBFLINT) $(CC) -shared $(CFLAGS) -o $@ $(LDFLAGS) \ - libpqc.a $(LIBTOMMATH) $(LIBTOMPOLY) $(LIBS) + libpqc.a $(LIBTOMMATH) $(LIBTOMPOLY) $(LIBFLINT) $(LIBS) -main: main.o libpqc.a $(LIBTOMMATH) $(LIBTOMPOLY) +main: main.o libpqc.a $(LIBTOMMATH) $(LIBTOMPOLY) $(LIBFLINT) $(CC) $(CFLAGS) -o $@ $(LDFLAGS) \ - main.o $(LIBTOMPOLY) libpqc.a $(LIBTOMPOLY) $(LIBTOMMATH) $(LIBS) + main.o $(LIBTOMPOLY) libpqc.a $(LIBTOMPOLY) $(LIBTOMMATH) $(LIBFLINT) $(LIBS) install: $(INSTALL_DIR) "$(DESTDIR)$(INSTALL_BINDIR)" From d56c920b847d514ef6ff593e5555772ba98b9f73 Mon Sep 17 00:00:00 2001 From: hasufell Date: Mon, 19 May 2014 22:31:22 +0200 Subject: [PATCH 03/26] Update .gitignore --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 3837701..cff5c63 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ latex/ *.la *.a *.o +*.d # targets @@ -22,4 +23,4 @@ src/main ./.settings/org.eclipse* -.project \ No newline at end of file +.project From fb7a46c363983997be70562e21b2530af2223cc9 Mon Sep 17 00:00:00 2001 From: hasufell Date: Mon, 19 May 2014 22:31:36 +0200 Subject: [PATCH 04/26] ENC: fix indenting level --- src/pqc_encrypt.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/pqc_encrypt.c b/src/pqc_encrypt.c index 05c1a82..c8fd750 100644 --- a/src/pqc_encrypt.c +++ b/src/pqc_encrypt.c @@ -43,23 +43,23 @@ void pb_encrypt(ntru_context *ctx, pb_poly *pubKey, pb_poly *out) { - mp_int *tmpOut; - mp_int *tmpMsg; - mp_int mp_int_mod; + mp_int *tmpOut; + mp_int *tmpMsg; + mp_int mp_int_mod; - init_integer(&mp_int_mod); - MP_SET_INT(&mp_int_mod,(unsigned long)ctx->q); + init_integer(&mp_int_mod); + MP_SET_INT(&mp_int_mod,(unsigned long)ctx->q); - pb_starmultiply(pubKey, rnd, out, ctx, ctx->q); + pb_starmultiply(pubKey, rnd, out, ctx, ctx->q); - tmpOut = out->terms; - tmpMsg = msg->terms; + tmpOut = out->terms; + tmpMsg = msg->terms; - for(unsigned int i = 0; i <= ctx->N-1; i++) { - mp_add(tmpOut,tmpMsg,tmpOut); - mp_mod(tmpOut,&mp_int_mod,tmpOut); + for(unsigned int i = 0; i <= ctx->N-1; i++) { + mp_add(tmpOut,tmpMsg,tmpOut); + mp_mod(tmpOut,&mp_int_mod,tmpOut); - tmpOut++; - tmpMsg++; - } + tmpOut++; + tmpMsg++; + } } From c075f4a0a32d4172c93fa9583849b9cf4035ff94 Mon Sep 17 00:00:00 2001 From: hasufell Date: Sat, 24 May 2014 23:11:02 +0200 Subject: [PATCH 05/26] ALL: Convert codebase to flint POLY, ENC, DEC all converted. RAND will have to be revised. --- src/Makefile | 4 +- src/{ntru_decrypt.c => decrypt.c} | 65 +-- src/{ntru_decrypt.h => decrypt.h} | 16 +- src/{pqc_encrypt.c => encrypt.c} | 45 +- src/{pqc_encrypt.h => encrypt.h} | 18 +- src/poly.c | 756 ++++++++++++++---------------- src/poly.h | 202 +------- 7 files changed, 457 insertions(+), 649 deletions(-) rename src/{ntru_decrypt.c => decrypt.c} (52%) rename src/{ntru_decrypt.h => decrypt.h} (83%) rename src/{pqc_encrypt.c => encrypt.c} (63%) rename src/{pqc_encrypt.h => encrypt.h} (85%) diff --git a/src/Makefile b/src/Makefile index 9811bf7..77126fb 100644 --- a/src/Makefile +++ b/src/Makefile @@ -37,8 +37,8 @@ endif LIBS += -L. -lgmp -lmpfr -lm # objects -PQC_OBJS = rand.o poly.o mem.o ntru_decrypt.o pqc_encrypt.o -PQC_HEADERS = err.h rand.h poly.h context.h ntru_decrypt.h pqc_encrypt.h +PQC_OBJS = poly.o mem.o encrypt.o decrypt.o +PQC_HEADERS = err.h poly.h context.h encrypt.h decrypt.h # CUNIT_OBJS = cunit.o # includes diff --git a/src/ntru_decrypt.c b/src/decrypt.c similarity index 52% rename from src/ntru_decrypt.c rename to src/decrypt.c index 211a3c7..13845d1 100644 --- a/src/ntru_decrypt.c +++ b/src/decrypt.c @@ -19,10 +19,13 @@ * MA 02110-1301 USA */ -#include "ntru_decrypt.h" +#include "decrypt.h" + +#include +#include -/** +/** * Decryption of the given Polynom with the private key, its inverse * and the fitting ntru_context * @@ -31,49 +34,23 @@ * @param priv_key the polynom containing the private key to decrypt * the message * @param priv_key_inv the inverse polynome to the private key - * @param context the ntru_context - * @param decr_msg may contain the decrypted polynome at some point - * @returns the decrypted polynome at the moment - * - * + * @param context the ntru_context + * @param out the result polynom is written in here [out] + * */ -pb_poly* ntru_decrypt(pb_poly *encr_msg, pb_poly *priv_key, - pb_poly *priv_key_inv, ntru_context *context, char ** decr_msg){ +void ntru_decrypt_poly( + fmpz_poly_t encr_msg, + fmpz_poly_t priv_key, + fmpz_poly_t priv_key_inv, + fmpz_poly_t out, + ntru_context *ctx) +{ + fmpz_poly_t a; - unsigned int q = context->q; - unsigned int p = context->p; - unsigned int N = context->N; - unsigned int i; + fmpz_poly_init(a); + fmpz_poly_zero(a); - pb_poly *a = build_polynom(NULL, N); - pb_starmultiply(priv_key, encr_msg, a, context, q); - - mp_int mp_q; - mp_int mp_qdiv2; - mp_int zero; - - init_integer(&mp_q); - init_integer(&mp_qdiv2); - init_integer(&zero); - - MP_SET_INT(&mp_q, q); - mp_div_2(&mp_q, &mp_qdiv2); - mp_zero(&zero); - - for(i = 0; i < N; i++){ - if(mp_cmp(&(a->terms[i]),&zero) == MP_LT) { - mp_add((&a->terms[i]),&mp_q,(&a->terms[i])); - } - if(mp_cmp(&(a->terms[i]), &mp_qdiv2) == MP_GT) { - mp_sub((&a->terms[i]),&mp_q,(&a->terms[i])); - } - } - - pb_poly *d = build_polynom(NULL, N); - - pb_starmultiply(a, priv_key_inv, d, context, p); - - pb_normalize(d,-1,1,context); - - return d; + poly_starmultiply(priv_key, encr_msg, a, ctx, ctx->q); + fmpz_poly_mod(a, ctx->q); + poly_starmultiply(a, priv_key_inv, out, ctx, ctx->p); } diff --git a/src/ntru_decrypt.h b/src/decrypt.h similarity index 83% rename from src/ntru_decrypt.h rename to src/decrypt.h index 5f44005..d610ecd 100644 --- a/src/ntru_decrypt.h +++ b/src/decrypt.h @@ -25,10 +25,16 @@ #include "poly.h" #include "context.h" -pb_poly* ntru_decrypt(pb_poly*, - pb_poly*, - pb_poly*, - ntru_context*, - char**); +#include +#include + + +void ntru_decrypt_poly( + fmpz_poly_t encr_msg, + fmpz_poly_t priv_key, + fmpz_poly_t priv_key_inv, + fmpz_poly_t out, + ntru_context *ctx); + #endif /* NTRU_DECRYPT */ diff --git a/src/pqc_encrypt.c b/src/encrypt.c similarity index 63% rename from src/pqc_encrypt.c rename to src/encrypt.c index c8fd750..0368349 100644 --- a/src/pqc_encrypt.c +++ b/src/encrypt.c @@ -19,9 +19,13 @@ * MA 02110-1301 USA */ -#include "pqc_encrypt.h" +#include "encrypt.h" -/* +#include +#include + + +/** * encrypt the msg, using the math: * e = (h ∗ r) + m (mod q) * @@ -35,31 +39,30 @@ * @param rnd pb_poly* the random poly * @param msg pb_poly* the message to encrypt * @param pubKey pb_poly* the public key - * @param out pb_poly* the output poly + * @param out pb_poly* the output poly [out] */ -void pb_encrypt(ntru_context *ctx, - pb_poly *rnd, - pb_poly *msg, - pb_poly *pubKey, - pb_poly *out) +void ntru_encrypt_poly(fmpz_poly_t rnd, + fmpz_poly_t msg, + fmpz_poly_t pub_key, + fmpz_poly_t out, + ntru_context *ctx) { - mp_int *tmpOut; - mp_int *tmpMsg; - mp_int mp_int_mod; + poly_starmultiply(pub_key, rnd, out, ctx, ctx->q); - init_integer(&mp_int_mod); - MP_SET_INT(&mp_int_mod,(unsigned long)ctx->q); + fmpz_poly_zero(out); - pb_starmultiply(pubKey, rnd, out, ctx, ctx->q); + for(unsigned int i = 0; i <= ctx->N - 1; i++) { + fmpz_poly_t tmp_poly; + fmpz_t tmp_coeff; + fmpz *e_coeff_i = fmpz_poly_get_coeff_ptr(out, i), + *m_coeff_i = fmpz_poly_get_coeff_ptr(msg, i); - tmpOut = out->terms; - tmpMsg = msg->terms; + fmpz_poly_init(tmp_poly); + fmpz_init(tmp_coeff); - for(unsigned int i = 0; i <= ctx->N-1; i++) { - mp_add(tmpOut,tmpMsg,tmpOut); - mp_mod(tmpOut,&mp_int_mod,tmpOut); + fmpz_add_n(tmp_coeff, e_coeff_i, m_coeff_i); + fmpz_mod_ui(tmp_coeff, tmp_coeff, ctx->q); - tmpOut++; - tmpMsg++; + fmpz_poly_set_coeff_fmpz(out, i, tmp_coeff); } } diff --git a/src/pqc_encrypt.h b/src/encrypt.h similarity index 85% rename from src/pqc_encrypt.h rename to src/encrypt.h index 7be7636..181bf15 100644 --- a/src/pqc_encrypt.h +++ b/src/encrypt.h @@ -22,15 +22,19 @@ #ifndef PQC_ENCRYPT_H #define PQC_ENCRYPT_H -#include -#include + #include "context.h" #include "poly.h" -void pb_encrypt(ntru_context *ctx, - pb_poly *rnd, - pb_poly *msg, - pb_poly *pubKey, - pb_poly *out); +#include +#include + + +void ntru_encrypt_poly(fmpz_poly_t rnd, + fmpz_poly_t msg, + fmpz_poly_t pubKey, + fmpz_poly_t out, + ntru_context *ctx); + #endif /* PQC_ENCRYPT_H */ diff --git a/src/poly.c b/src/poly.c index b565725..b1e032c 100644 --- a/src/poly.c +++ b/src/poly.c @@ -27,143 +27,80 @@ #include #include #include -#include -#include #include +#include +#include + /* * static declarations */ -static void pb_mod2_to_modq(pb_poly * const a, - pb_poly *Fq, +static void poly_mod2_to_modq(fmpz_poly_t a, + fmpz_poly_t Fq, ntru_context *ctx); /** - * Initialize a mp_int and check if this was successful, the - * caller must free new_int. + * Find the inverse polynomial modulo a power of 2, + * which is q. * - * @param new_int a pointer to the mp_int you want to initialize + * @param a polynomial to invert + * @param Fq polynomial [out] + * @param ctx NTRU context */ -void init_integer(mp_int *new_int) +static void poly_mod2_to_modq(fmpz_poly_t a, + fmpz_poly_t Fq, + ntru_context *ctx) { - int result; - if ((result = mp_init(new_int)) != MP_OKAY) { - NTRU_ABORT("Error initializing the number. %s", - mp_error_to_string(result)); - } -} + int v = 2; + fmpz_poly_t poly_tmp, two; -/** - * Initialize one ore more mp_int and check if this was successful, the - * caller must free new_int with mp_clear(). - * - * @param new_int a pointer to the mp_int you want to initialize - */ -void init_integers(mp_int *new_int, ...) -{ - mp_int *next_mp; - va_list args; + fmpz_poly_init(poly_tmp); + fmpz_poly_zero(poly_tmp); + fmpz_poly_init(two); + fmpz_poly_set_coeff_ui(two, 0, 2); - next_mp = new_int; - va_start(args, new_int); - while (next_mp != NULL) { - init_integer(next_mp); - next_mp = va_arg(args, mp_int*); - } - va_end(args); -} + while (v < (int)(ctx->q)) { + v = v * 2; -/** - * Initialize a Polynom with a pb_poly and a mp_int as characteristic. - * Checks if everything went fine. The caller must free new_poly - * with pb_clear(). - * - * @param new_poly the pb_poly you want to initialize - * @param chara the characteristic - */ -void init_polynom(pb_poly *new_poly, mp_int *chara) -{ - int result; - if ((result = pb_init(new_poly, chara)) != MP_OKAY) { - NTRU_ABORT("Error initializing the number. %s", - mp_error_to_string(result)); - } -} + poly_starmultiply(a, Fq, poly_tmp, ctx, v); + fmpz_poly_sub(poly_tmp, two, poly_tmp); + fmpz_poly_mod_unsigned(poly_tmp, v); + poly_starmultiply(Fq, poly_tmp, Fq, ctx, v); -/** - * Initialize a Polynom with a pb_poly and an mp_int as characteristic - * with size. Checks if everything went fine. The caller must free - * new_poly with pb_clear(). - * - * @param new_poly the pb_poly you want to initialize - * @param chara the characteristic - * @param size the size of the polynomial - */ -void init_polynom_size(pb_poly *new_poly, mp_int *chara, size_t size) -{ - int result; - if ((result = pb_init_size(new_poly, chara, size)) != MP_OKAY) { - NTRU_ABORT("Error initializing the number. %s", - mp_error_to_string(result)); } + + fmpz_poly_clear(poly_tmp); + fmpz_poly_clear(two); + } /** * Initializes and builds a polynomial with the * coefficient values of c[] of size len within NTRU * context ctx and returns a newly allocated polynomial - * pointer which is not clamped. - * - * If you want to fill a polyonmial of length 11 with zeros, - * call build_polynom(NULL, 11). + * pointer which is not clamped. For an empty polynom, + * both parameters can be NULL/0. * * @param c array of polynomial coefficients, can be NULL * @param len size of the coefficient array, can be 0 - * @param ctx NTRU context * @return newly allocated polynomial pointer, must be freed - * with delete_polynom() + * with fmpz_poly_clear() */ -pb_poly *build_polynom(int const * const c, +fmpz_poly_t *poly_new(int const * const c, const size_t len) { - pb_poly *new_poly; - mp_int chara; + fmpz_poly_t *new_poly = ntru_malloc(sizeof(*new_poly)); - new_poly = ntru_malloc(sizeof(*new_poly)); - init_integer(&chara); - init_polynom_size(new_poly, &chara, len); - mp_clear(&chara); + fmpz_poly_init(*new_poly); - /* fill the polynom if c is not NULL */ - if (c) { - for (unsigned int i = 0; i < len; i++) - MP_SET_INT(&(new_poly->terms[i]), c[i]); - } else { /* fill with 0 */ - for (unsigned int i = 0; i < len; i++) - MP_SET(&(new_poly->terms[i]), 0); - } - - new_poly->used = len; + for (unsigned int i = 0; i < len; i++) + fmpz_poly_set_coeff_si(*new_poly, i, c[i]); return new_poly; } -/** - * Sets all the polynomial coefficients to +0. - * - * @param poly the polynomial - * @param len the length of the polynomial - */ -void erase_polynom(pb_poly *poly, size_t len) -{ - for (unsigned int i = 0; i < len ; i++) { - MP_SET(&(poly->terms[i]), 0); - mp_abs(&(poly->terms[i]), &(poly->terms[i])); - } -} - /** * This deletes the internal structure of a polynomial, * and frees the pointer. Don't call this on stack variables, @@ -172,9 +109,9 @@ void erase_polynom(pb_poly *poly, size_t len) * * @param poly the polynomial to delete */ -void delete_polynom(pb_poly *poly) +void poly_delete(fmpz_poly_t *poly) { - pb_clear(poly); + fmpz_poly_clear(*poly); free(poly); } @@ -188,20 +125,117 @@ void delete_polynom(pb_poly *poly) * @param poly the polynomial to delete * @param ... follow up polynomials */ -void delete_polynom_multi(pb_poly *poly, ...) +void poly_delete_all(fmpz_poly_t *poly, ...) { - pb_poly *next_poly; + fmpz_poly_t *next_poly; va_list args; next_poly = poly; va_start(args, poly); while (next_poly != NULL) { - delete_polynom(next_poly); - next_poly = va_arg(args, pb_poly*); + poly_delete(next_poly); + next_poly = va_arg(args, fmpz_poly_t*); } va_end(args); } +/** + * Calls fmpz_poly_get_nmod_poly() and + * fmpz_poly_set_nmod_poly_unsigned() in a row, + * so we don't have to deal with the intermediate + * nmod_poly_t type if we don't need it. + * + * @param a the polynom to apply the modulus to + * @param mod the modulus + */ +void fmpz_poly_mod_unsigned(fmpz_poly_t a, + unsigned int mod) +{ + nmod_poly_t nmod_tmp; + + nmod_poly_init(nmod_tmp, mod); + + fmpz_poly_get_nmod_poly(nmod_tmp, a); + fmpz_poly_set_nmod_poly_unsigned(a, nmod_tmp); + + nmod_poly_clear(nmod_tmp); +} + +/** + * Calls fmpz_poly_get_nmod_poly() and + * fmpz_poly_set_nmod_poly() in a row, + * so we don't have to deal with the intermediate + * nmod_poly_t type if we don't need it. + * + * @param a the polynom to apply the modulus to + * @param mod the modulus + */ +void fmpz_poly_mod(fmpz_poly_t a, + unsigned int mod) +{ + nmod_poly_t nmod_tmp; + + nmod_poly_init(nmod_tmp, mod); + + fmpz_poly_get_nmod_poly(nmod_tmp, a); + fmpz_poly_set_nmod_poly(a, nmod_tmp); + + nmod_poly_clear(nmod_tmp); +} + +/** + * The same as fmpz_poly_set_coeff_fmpz() except that it + * will take care of null-pointer coefficients and use + * fmpz_poly_set_coeff_si() in that case. + * + * @param poly the polynom we want to change a coefficient of + * @param n the coefficient we want to set + * @param x the value to assign to the coefficient + */ +void fmpz_poly_set_coeff_fmpz_n(fmpz_poly_t poly, slong n, + const fmpz_t x) +{ + if (x) + fmpz_poly_set_coeff_fmpz(poly, n, x); + else + fmpz_poly_set_coeff_si(poly, n, 0); +} + +/** + * Wrapper around fmpz_invmod() where we convert + * mod to an fmpz_t implicitly. + * + * @param f result [out] + * @param g the inverse + * @param mod the modulo + */ +int fmpz_invmod_ui(fmpz_t f, const fmpz_t g, unsigned int mod) +{ + fmpz_t modulus; + + fmpz_init_set_ui(modulus, mod); + + return fmpz_invmod(f, g, modulus); +} + +/** + * The same as fmpz_add() except that it handles NULL + * pointer for g and h. + */ +void fmpz_add_n(fmpz_t f, const fmpz_t g, const fmpz_t h) +{ + if (!g && !h) { + fmpz_zero(f); + } else { + if (!g && h) + fmpz_add_ui(f, h, 0); + else if (g && !h) + fmpz_add_ui(f, g, 0); + else + fmpz_add(f, g, h); + } +} + /** * Starmultiplication, as follows: * c = a * b mod (x^N − 1) @@ -212,425 +246,359 @@ void delete_polynom_multi(pb_poly *poly, ...) * @param ctx NTRU context * @param modulus whether we use p or q */ -void pb_starmultiply(pb_poly *a, - pb_poly *b, - pb_poly *c, +void poly_starmultiply(fmpz_poly_t a, + fmpz_poly_t b, + fmpz_poly_t c, ntru_context *ctx, unsigned int modulus) { - pb_poly *a_tmp; - mp_int mp_modulus; + fmpz_poly_t a_tmp; + fmpz_t c_coeff_k; - init_integer(&mp_modulus); - MP_SET_INT(&mp_modulus, (unsigned long)(modulus)); + fmpz_poly_init(a_tmp); + fmpz_init(c_coeff_k); /* avoid side effects */ - a_tmp = build_polynom(NULL, ctx->N); - PB_COPY(a, a_tmp); - erase_polynom(c, ctx->N); + fmpz_poly_set(a_tmp, a); + fmpz_poly_zero(c); for (int k = ctx->N - 1; k >= 0; k--) { int j; + j = k + 1; + fmpz_set_si(c_coeff_k, 0); + for (int i = ctx->N - 1; i >= 0; i--) { + fmpz *a_tmp_coeff_i, + *b_coeff_j; + if (j == (int)(ctx->N)) j = 0; - if (mp_cmp_d(&(a_tmp->terms[i]), 0) != MP_EQ && - mp_cmp_d(&(b->terms[j]), 0) != MP_EQ) { - mp_int mp_tmp; - init_integer(&mp_tmp); + a_tmp_coeff_i = fmpz_poly_get_coeff_ptr(a_tmp, i); + b_coeff_j = fmpz_poly_get_coeff_ptr(b, j); - MP_MUL(&(a_tmp->terms[i]), &(b->terms[j]), &mp_tmp); - MP_ADD(&(c->terms[k]), &mp_tmp, &(c->terms[k])); - MP_DIV(&(c->terms[k]), &mp_modulus, NULL, &(c->terms[k])); + if (a_tmp_coeff_i && fmpz_cmp_si(a_tmp_coeff_i, 0) && + b_coeff_j && fmpz_cmp_si(b_coeff_j, 0)) { + fmpz_t fmpz_tmp; - mp_clear(&mp_tmp); + fmpz_init(fmpz_tmp); + + fmpz_mul(fmpz_tmp, a_tmp_coeff_i, b_coeff_j); + fmpz_add(fmpz_tmp, fmpz_tmp, c_coeff_k); + fmpz_mod_ui(c_coeff_k, fmpz_tmp, modulus); + + fmpz_poly_set_coeff_fmpz(c, k, c_coeff_k); + + fmpz_clear(fmpz_tmp); } j++; } + fmpz_clear(c_coeff_k); } - mp_clear(&mp_modulus); - delete_polynom(a_tmp); + + fmpz_poly_clear(a_tmp); } /** - * Calculate c = a * b where c and a are polynomials - * and b is an mp_int. - * - * @param a polynom - * @param b mp_int - * @param c polynom [out] - * @return error code of pb_mul() - */ -int pb_mp_mul(pb_poly *a, mp_int *b, pb_poly *c) -{ - int result; - - pb_poly *b_poly = build_polynom(NULL, 1); - MP_COPY(b, &(b_poly->terms[0])); - printf("u converted to poly: "); draw_polynom(b_poly); - result = pb_mul(a, b_poly, c); - - delete_polynom(b_poly); - - return result; -} - -/** - * c = a XOR b - * - * @param a polynom (is allowed to be the same as param c) - * @param b polynom - * @param c polynom [out] - * @param len max size of the polynoms, make sure all are - * properly allocated - */ -void pb_xor(pb_poly *a, - pb_poly *b, - pb_poly *c, - const size_t len) -{ - for (unsigned int i = 0; i < len; i++) - MP_XOR(&(a->terms[i]), &(b->terms[i]), &(c->terms[i])); -} - -/** - * Get the degree of the polynomial. - * - * @param poly the polynomial - * @return the degree, -1 if polynom is empty - */ -int get_degree(pb_poly const * const poly) -{ - int count = -1; - - for (int i = 0; i < poly->alloc; i++) - if (mp_iszero(&(poly->terms[i])) == MP_NO) - count = i; - - return count; -} - -/** - * Find the inverse polynomial modulo a power of 2, - * which is q. - * - * @param a polynomial to invert - * @param Fq polynomial [out] - * @param ctx NTRU context - */ -static void pb_mod2_to_modq(pb_poly * const a, - pb_poly *Fq, - ntru_context *ctx) -{ - int v = 2; - - while (v < (int)(ctx->q)) { - pb_poly *pb_tmp, - *pb_tmp2; - mp_int tmp_v; - pb_tmp = build_polynom(NULL, ctx->N); - v = v * 2; - init_integer(&tmp_v); - MP_SET_INT(&tmp_v, v); - pb_tmp2 = build_polynom(NULL, ctx->N); - MP_SET_INT(&(pb_tmp2->terms[0]), 2); - - pb_starmultiply(a, Fq, pb_tmp, ctx, v); - PB_SUB(pb_tmp2, pb_tmp, pb_tmp); - PB_MOD(pb_tmp, &tmp_v, pb_tmp, ctx->N); - pb_starmultiply(Fq, pb_tmp, Fq, ctx, v); - - mp_clear(&tmp_v); - delete_polynom_multi(pb_tmp, pb_tmp2, NULL); - } -} - -/** - * Invert the polynomial a modulo q. + * Compute the inverse of a polynomial in modulo a power of 2, + * which is q. This is based off the pseudo-code for "Inversion + * in (Z/2Z)[X](X^N - 1)" and "Inversion in (Z/p^r Z)[X](X^N - 1)". + * See NTRU Cryptosystems Tech Report #014 "Almost Inverses + * and Fast NTRU Key Creation." * * @param a polynomial to invert (is allowed to be the same as param Fq) * @param Fq polynomial [out] * @param ctx NTRU context * @return true if invertible, false if not */ -bool pb_inverse_poly_q(pb_poly * const a, - pb_poly *Fq, +bool poly_inverse_poly_q(fmpz_poly_t a, + fmpz_poly_t Fq, ntru_context *ctx) { + bool retval = true; int k = 0, j = 0; - pb_poly *a_tmp, *b, *c, *f, *g; - mp_int mp_modulus; + fmpz *b_last; + fmpz_poly_t a_tmp, + b, + c, + f, + g; /* general initialization of temp variables */ - init_integer(&mp_modulus); - MP_SET_INT(&mp_modulus, (unsigned long)(ctx->q)); - b = build_polynom(NULL, ctx->N + 1); - MP_SET(&(b->terms[0]), 1); - c = build_polynom(NULL, ctx->N + 1); - f = build_polynom(NULL, ctx->N + 1); - PB_COPY(a, f); + fmpz_poly_init(b); + fmpz_poly_set_coeff_ui(b, 0, 1); + fmpz_poly_init(c); + fmpz_poly_init(f); + fmpz_poly_set(f, a); /* set g(x) = x^N − 1 */ - g = build_polynom(NULL, ctx->N + 1); - MP_SET(&(g->terms[0]), 1); - MP_SET(&(g->terms[ctx->N]), 1); + fmpz_poly_init(g); + fmpz_poly_set_coeff_si(g, 0, -1); + fmpz_poly_set_coeff_si(g, ctx->N, 1); /* avoid side effects */ - a_tmp = build_polynom(NULL, ctx->N); - PB_COPY(a, a_tmp); - erase_polynom(Fq, ctx->N); + fmpz_poly_init(a_tmp); + fmpz_poly_set(a_tmp, a); + fmpz_poly_zero(Fq); while (1) { - while (mp_cmp_d(&(f->terms[0]), 0) == MP_EQ) { + while (fmpz_is_zero(fmpz_poly_get_coeff_ptr(f, 0))) { for (unsigned int i = 1; i <= ctx->N; i++) { + fmpz *f_coeff = fmpz_poly_get_coeff_ptr(f, i); + fmpz *c_coeff = fmpz_poly_get_coeff_ptr(c, ctx->N - i); + /* f(x) = f(x) / x */ - MP_COPY(&(f->terms[i]), &(f->terms[i - 1])); + fmpz_poly_set_coeff_fmpz_n(f, i - 1, + f_coeff); + /* c(x) = c(x) * x */ - MP_COPY(&(c->terms[ctx->N - i]), &(c->terms[ctx->N + 1 - i])); + fmpz_poly_set_coeff_fmpz_n(c, ctx->N + 1 - i, + c_coeff); } - MP_SET(&(f->terms[ctx->N]), 0); - MP_SET(&(c->terms[0]), 0); + + fmpz_poly_set_coeff_si(f, ctx->N, 0); + fmpz_poly_set_coeff_si(c, 0, 0); + k++; - if (get_degree(f) == -1) - return false; + + if (fmpz_poly_degree(f) == -1) { + retval = false; + goto cleanup; + } } - if (get_degree(f) == 0) + if (fmpz_poly_degree(f) == 0) break; - if (get_degree(f) < get_degree(g)) { - pb_exch(f, g); - pb_exch(b, c); + if (fmpz_poly_degree(f) < fmpz_poly_degree(g)) { + fmpz_poly_swap(f, g); + fmpz_poly_swap(b, c); } - pb_xor(f, g, f, ctx->N); - pb_xor(b, c, b, ctx->N); + fmpz_poly_add(f, g, f); + fmpz_poly_mod_unsigned(f, 2); + + fmpz_poly_add(b, c, b); + fmpz_poly_mod_unsigned(b, 2); } k = k % ctx->N; - if (mp_cmp_d(&(b->terms[ctx->N]), 0) != MP_EQ) - return false; + b_last = fmpz_poly_get_coeff_ptr(b, ctx->N); + if (b_last && fmpz_cmp_si(b_last, 0)) { + retval = false; + goto cleanup; + } /* Fq(x) = x^(N-k) * b(x) */ for (int i = ctx->N - 1; i >= 0; i--) { + fmpz *b_i; + j = i - k; + if (j < 0) j = j + ctx->N; - MP_COPY(&(b->terms[i]), &(Fq->terms[j])); + + b_i = fmpz_poly_get_coeff_ptr(b, i); + fmpz_poly_set_coeff_fmpz_n(Fq, j, b_i); } - pb_mod2_to_modq(a_tmp, Fq, ctx); + poly_mod2_to_modq(a_tmp, Fq, ctx); - /* pull into positive space */ - for (int i = ctx->N - 1; i >= 0; i--) - if (mp_cmp_d(&(Fq->terms[i]), 0) == MP_LT) - MP_ADD(&(Fq->terms[i]), &mp_modulus, &(Fq->terms[i])); + /* check if the f * Fq = 1 (mod p) condition holds true */ + fmpz_poly_set(a_tmp, a); + poly_starmultiply(a_tmp, Fq, a_tmp, ctx, ctx->q); + if (!fmpz_poly_is_one(a_tmp)) + retval = false; - delete_polynom_multi(a_tmp, b, c, f, g, NULL); - mp_clear(&mp_modulus); +cleanup: + fmpz_poly_clear(a_tmp); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + fmpz_poly_clear(f); + fmpz_poly_clear(g); - /* TODO: check if the f * Fq = 1 (mod p) condition holds true */ + if (!retval) + fmpz_poly_zero(Fq); - return true; + return retval; } /** - * Invert the polynomial a modulo p. + * Compute the inverse of a polynomial in (Z/pZ)[X]/(X^N - 1). + * See NTRU Cryptosystems Tech Report #014 "Almost Inverses + * and Fast NTRU Key Creation." * * @param a polynomial to invert * @param Fq polynomial [out] * @param ctx NTRU context */ -bool pb_inverse_poly_p(pb_poly *a, - pb_poly *Fp, +bool poly_inverse_poly_p(fmpz_poly_t a, + fmpz_poly_t Fp, ntru_context *ctx) { + bool retval = true; int k = 0, j = 0; - pb_poly *a_tmp, *b, *c, *f, *g; - mp_int mp_modulus; + fmpz *b_last; + fmpz_poly_t a_tmp, + b, + c, + f, + g; /* general initialization of temp variables */ - init_integer(&mp_modulus); - MP_SET_INT(&mp_modulus, (unsigned long)(ctx->p)); - b = build_polynom(NULL, ctx->N + 1); - MP_SET(&(b->terms[0]), 1); - c = build_polynom(NULL, ctx->N + 1); - f = build_polynom(NULL, ctx->N + 1); - PB_COPY(a, f); + fmpz_poly_init(b); + fmpz_poly_set_coeff_ui(b, 0, 1); + fmpz_poly_init(c); + fmpz_poly_init(f); + fmpz_poly_set(f, a); /* set g(x) = x^N − 1 */ - g = build_polynom(NULL, ctx->N + 1); - MP_SET_INT(&(g->terms[0]), -1); - MP_SET(&(g->terms[ctx->N]), 1); + fmpz_poly_init(g); + fmpz_poly_set_coeff_si(g, 0, -1); + fmpz_poly_set_coeff_si(g, ctx->N, 1); /* avoid side effects */ - a_tmp = build_polynom(NULL, ctx->N); - PB_COPY(a, a_tmp); - erase_polynom(Fp, ctx->N); - - printf("f: "); draw_polynom(f); - printf("g: "); draw_polynom(g); + fmpz_poly_init(a_tmp); + fmpz_poly_set(a_tmp, a); + fmpz_poly_zero(Fp); while (1) { - while (mp_cmp_d(&(f->terms[0]), 0) == MP_EQ) { + while (fmpz_is_zero(fmpz_poly_get_coeff_ptr(f, 0))) { for (unsigned int i = 1; i <= ctx->N; i++) { + fmpz *f_coeff_tmp = fmpz_poly_get_coeff_ptr(f, i); + fmpz *c_coeff_tmp = fmpz_poly_get_coeff_ptr(c, ctx->N - i); + /* f(x) = f(x) / x */ - MP_COPY(&(f->terms[i]), &(f->terms[i - 1])); + fmpz_poly_set_coeff_fmpz_n(f, i - 1, + f_coeff_tmp); + /* c(x) = c(x) * x */ - MP_COPY(&(c->terms[ctx->N - i]), &(c->terms[ctx->N + 1 - i])); + fmpz_poly_set_coeff_fmpz_n(c, ctx->N + 1 - i, + c_coeff_tmp); } - MP_SET(&(f->terms[ctx->N]), 0); - MP_SET(&(c->terms[0]), 0); + + fmpz_poly_set_coeff_si(f, ctx->N, 0); + fmpz_poly_set_coeff_si(c, 0, 0); + k++; + + if (fmpz_poly_degree(f) == -1) { + retval = false; + goto cleanup; + } } - if (get_degree(f) == 0) + if (fmpz_poly_degree(f) == 0) break; - if (get_degree(f) < get_degree(g)) { + if (fmpz_poly_degree(f) < fmpz_poly_degree(g)) { /* exchange f and g and exchange b and c */ - pb_exch(f, g); - pb_exch(b, c); + fmpz_poly_swap(f, g); + fmpz_poly_swap(b, c); } { - pb_poly *c_tmp, *g_tmp; - mp_int u, mp_tmp; + fmpz_poly_t c_tmp, + g_tmp; + fmpz_t u, + mp_tmp; - init_integers(&u, &mp_tmp, NULL); - g_tmp = build_polynom(NULL, ctx->N + 1); - PB_COPY(g, g_tmp); - c_tmp = build_polynom(NULL, ctx->N + 1); - PB_COPY(c, c_tmp); + fmpz_init(u); + fmpz_zero(u); - /* u = f[0] * g[0]^(-1) mod p - * = (f[0] mod p) * (g[0] inverse mod p) mod p */ - MP_COPY(&(f->terms[0]), &mp_tmp); - MP_INVMOD(&(g->terms[0]), &mp_modulus, &u); - MP_MOD(&mp_tmp, &mp_modulus, &mp_tmp); - MP_MUL(&u, &mp_tmp, &u); - MP_MOD(&u, &mp_modulus, &u); + fmpz_init_set(mp_tmp, fmpz_poly_get_coeff_ptr(f, 0)); + + fmpz_poly_init(g_tmp); + fmpz_poly_set(g_tmp, g); + + fmpz_poly_init(c_tmp); + fmpz_poly_set(c_tmp, c); + + /* u = f[0] * g[0]^(-1) mod p */ + /* = (f[0] mod p) * (g[0] inverse mod p) mod p */ + fmpz_invmod_ui(u, + fmpz_poly_get_coeff_ptr(g, 0), + ctx->p); + fmpz_mod_ui(mp_tmp, mp_tmp, ctx->p); + fmpz_mul(u, mp_tmp, u); + fmpz_mod_ui(u, u, ctx->p); /* f = f - u * g mod p */ - PB_MP_MUL(g_tmp, &u, g_tmp); - PB_SUB(f, g_tmp, f); - PB_MOD(f, &mp_modulus, f, ctx->N + 1); + fmpz_poly_scalar_mul_fmpz(g_tmp, g_tmp, u); + fmpz_poly_sub(f, g_tmp, f); + fmpz_poly_mod_unsigned(f, ctx->p); /* b = b - u * c mod p */ - PB_MP_MUL(c_tmp, &u, c_tmp); - PB_SUB(b, c_tmp, b); - PB_MOD(b, &mp_modulus, b, ctx->N + 1); + fmpz_poly_scalar_mul_fmpz(c_tmp, c_tmp, u); + fmpz_poly_sub(b, c_tmp, b); + fmpz_poly_mod_unsigned(b, ctx->p); - mp_clear(&mp_tmp); - delete_polynom_multi(c_tmp, g_tmp, NULL); + fmpz_clear(u); + fmpz_poly_clear(g_tmp); + fmpz_poly_clear(c_tmp); } } k = k % ctx->N; + b_last = fmpz_poly_get_coeff_ptr(b, ctx->N); + if (b_last && fmpz_cmp_si(b_last, 0)) { + retval = false; + goto cleanup; + } + /* Fp(x) = x^(N-k) * b(x) */ for (int i = ctx->N - 1; i >= 0; i--) { + fmpz *b_i; /* b(X) = f[0]^(-1) * b(X) (mod p) */ { - pb_poly *poly_tmp; + fmpz_t mp_tmp; - poly_tmp = build_polynom(NULL, 1); + fmpz_init(mp_tmp); - MP_INVMOD(&(f->terms[0]), &mp_modulus, &(poly_tmp->terms[0])); - MP_MOD(&(b->terms[i]), &mp_modulus, &(b->terms[i])); - MP_MUL(&(b->terms[i]), &(poly_tmp->terms[0]), &(b->terms[i])); + fmpz_invmod_ui(mp_tmp, + fmpz_poly_get_coeff_ptr(f, 0), + ctx->p); - delete_polynom(poly_tmp); + if (fmpz_poly_get_coeff_ptr(b, i)) { + fmpz_mul(fmpz_poly_get_coeff_ptr(b, i), + fmpz_poly_get_coeff_ptr(b, i), + mp_tmp); + fmpz_mod_ui(fmpz_poly_get_coeff_ptr(b, i), + fmpz_poly_get_coeff_ptr(b, i), + ctx->p); + } } j = i - k; if (j < 0) j = j + ctx->N; - MP_COPY(&(b->terms[i]), &(Fp->terms[j])); - /* delete_polynom(f_tmp); */ + b_i = fmpz_poly_get_coeff_ptr(b, i); + fmpz_poly_set_coeff_fmpz_n(Fp, j, b_i); } - /* pull into positive space */ - for (int i = ctx->N - 1; i >= 0; i--) - if (mp_cmp_d(&(Fp->terms[i]), 0) == MP_LT) - MP_ADD(&(Fp->terms[i]), &mp_modulus, &(Fp->terms[i])); + /* check if the f * Fq = 1 (mod p) condition holds true */ + fmpz_poly_set(a_tmp, a); + poly_starmultiply(a_tmp, Fp, a_tmp, ctx, ctx->p); + if (!fmpz_poly_is_one(a_tmp)) + retval = false; - mp_clear(&mp_modulus); - delete_polynom_multi(a_tmp, b, c, f, g, NULL); +cleanup: + fmpz_poly_clear(a_tmp); + fmpz_poly_clear(b); + fmpz_poly_clear(c); + fmpz_poly_clear(f); + fmpz_poly_clear(g); - /* TODO: check if the f * Fq = 1 (mod p) condition holds true */ + if (!retval) + fmpz_poly_zero(Fp); - return true; -} - -/** - * Print the polynomial in a human readable format to stdout. - * - * @param poly to draw - */ -void draw_polynom(pb_poly * const poly) -{ - int x; - char buf[8192]; - - if (poly->used == 0) { - printf("0"); - } else { - for (x = poly->used - 1; x >= 0; x--) { - if (mp_iszero(&(poly->terms[x])) == MP_YES) - continue; - mp_toradix(&(poly->terms[x]), buf, 10); - if ((x != poly->used - 1) && poly->terms[x].sign == MP_ZPOS) { - printf("+"); - } - printf(" %sx^%d ", buf, x); - } - } - if (mp_iszero(&(poly->characteristic)) == MP_NO) { - mp_toradix(&(poly->characteristic), buf, 10); - printf(" (mod %s)", buf); - } - printf("\n"); -} - -void pb_normalize(pb_poly *poly, int low_border, int high_border, ntru_context *ctx){ - unsigned int p = ctx->p; - unsigned int N = ctx->N; - - mp_int mp_p; - mp_int mp_low_border; - mp_int mp_high_border; - - init_integer(&mp_low_border); - init_integer(&mp_high_border); - init_integer(&mp_p); - - MP_SET_INT(&mp_p, p); - MP_SET_INT(&mp_low_border,(unsigned long)abs(low_border)); - mp_neg(&mp_low_border,&mp_low_border); - MP_SET_INT(&mp_high_border,high_border); - - - unsigned int i; - for(i = 0; i < N; i++){ - if(mp_cmp(&(poly->terms[i]),&mp_low_border) == MP_LT) { - mp_add(&(poly->terms[i]),&mp_p,&(poly->terms[i])); - } else if(mp_cmp(&(poly->terms[i]),&mp_high_border) == MP_GT) { - mp_sub(&(poly->terms[i]),&mp_p,&(poly->terms[i])); - } - } -} - -void draw_mp_int(mp_int *digit) { - char buf[8192]; - mp_toradix(digit, buf, 10); - printf("%s\n",buf); + return retval; } diff --git a/src/poly.h b/src/poly.h index bda6a85..a92ad3a 100644 --- a/src/poly.h +++ b/src/poly.h @@ -26,199 +26,49 @@ #include "context.h" #include "err.h" -#include -#include #include #include #include - -#define MP_SET(...) mp_set(__VA_ARGS__) - -#define MP_SET_INT(a, b) \ -{ \ - int result; \ - if ((result = mp_set_int(a, (unsigned long)abs(b))) != MP_OKAY) \ - NTRU_ABORT("Error setting long constant. %s", \ - mp_error_to_string(result)); \ - if ((int)b < 0) \ - mp_neg(a, a); \ -} - -#define MP_MUL(...) \ -{ \ - int result; \ - if ((result = mp_mul(__VA_ARGS__)) != MP_OKAY) \ - NTRU_ABORT("Error multiplying terms. %s", \ - mp_error_to_string(result)); \ -} - -#define MP_DIV(...) \ -{ \ - int result; \ - if ((result = mp_div(__VA_ARGS__)) != MP_OKAY) \ - NTRU_ABORT("Error dividing terms. %s", \ - mp_error_to_string(result)); \ -} - -#define MP_ADD(...) \ -{ \ - int result; \ - if ((result = mp_add(__VA_ARGS__)) != MP_OKAY) \ - NTRU_ABORT("Error adding terms. %s", \ - mp_error_to_string(result)); \ -} - -#define MP_SUB(...) \ -{ \ - int result; \ - if ((result = mp_sub(__VA_ARGS__)) != MP_OKAY) \ - NTRU_ABORT("Error substracting terms. %s", \ - mp_error_to_string(result)); \ -} - -#define MP_MOD(...) \ -{ \ - int result; \ - if ((result = mp_mod(__VA_ARGS__)) != MP_OKAY) \ - NTRU_ABORT("Error reducing term by modulo. %s", \ - mp_error_to_string(result)); \ -} - -#define MP_COPY(...) \ -{ \ - int result; \ - if ((result = mp_copy(__VA_ARGS__)) != MP_OKAY) \ - NTRU_ABORT("Error copying terms. %s", \ - mp_error_to_string(result)); \ -} - -#define MP_XOR(...) \ -{ \ - int result; \ - if ((result = mp_xor(__VA_ARGS__)) != MP_OKAY) \ - NTRU_ABORT("Error XORing terms. %s", \ - mp_error_to_string(result)); \ -} - -#define MP_EXPTMOD(...) \ -{ \ - int result; \ - if ((result = mp_exptmod(__VA_ARGS__)) != MP_OKAY) \ - NTRU_ABORT("Error computing modular exponentiation. %s", \ - mp_error_to_string(result)); \ -} - -#define MP_INVMOD(...) \ -{ \ - int result; \ - if ((result = mp_invmod(__VA_ARGS__)) != MP_OKAY) \ - NTRU_ABORT("Error computing modular inverse. %s", \ - mp_error_to_string(result)); \ -} - -#define MP_EXPT_D(...) \ -{ \ - int result; \ - if ((result = mp_expt_d(__VA_ARGS__)) != MP_OKAY) \ - NTRU_ABORT("Error computing modular exponentiation. %s", \ - mp_error_to_string(result)); \ -} - -#define PB_MUL(...) \ -{ \ - int result; \ - if ((result = pb_mul(__VA_ARGS__)) != MP_OKAY) \ - NTRU_ABORT("Error multiplying polynomials. %s", \ - mp_error_to_string(result)); \ -} - -#define PB_MP_MUL(...) \ -{ \ - int result; \ - if ((result = pb_mp_mul(__VA_ARGS__)) != MP_OKAY) \ - NTRU_ABORT("Error multiplying polynomial with mp_int. %s", \ - mp_error_to_string(result)); \ -} - -#define PB_ADD(...) \ -{ \ - int result; \ - if ((result = pb_add(__VA_ARGS__)) != MP_OKAY) \ - NTRU_ABORT("Error adding polynomials. %s", \ - mp_error_to_string(result)); \ -} - -#define PB_SUB(...) \ -{ \ - int result; \ - if ((result = pb_sub(__VA_ARGS__)) != MP_OKAY) \ - NTRU_ABORT("Error substracting polynomials. %s", \ - mp_error_to_string(result)); \ -} - -#define PB_MOD(poly_a, mp_int, poly_out, len) \ -{ \ - for (unsigned int i = 0; i < len; i++) \ - MP_DIV(&(poly_a->terms[i]), mp_int, NULL, &(poly_out->terms[i])); \ -} - -#define PB_COPY(...) \ -{ \ - int result; \ - if ((result = pb_copy(__VA_ARGS__)) != MP_OKAY) \ - NTRU_ABORT("Error copying polynomial. %s", \ - mp_error_to_string(result)); \ -} +#include -void init_integer(mp_int *new_int); - -void init_integers(mp_int *new_int, ...); - -void init_polynom(pb_poly *new_poly, mp_int *chara); - -void init_polynom_size(pb_poly *new_poly, mp_int *chara, size_t size); - -pb_poly *build_polynom(int const * const c, +fmpz_poly_t *poly_new(int const * const c, const size_t len); -void erase_polynom(pb_poly *poly, size_t len); +void poly_delete(fmpz_poly_t *poly); -void delete_polynom(pb_poly *new_poly); +void poly_delete_all(fmpz_poly_t *poly, ...); -void delete_polynom_multi(pb_poly *poly, ...); +void fmpz_poly_mod_unsigned(fmpz_poly_t a, + unsigned int mod); -void pb_starmultiply(pb_poly *a, - pb_poly *b, - pb_poly *c, +void fmpz_poly_mod(fmpz_poly_t a, + unsigned int mod); + +void fmpz_poly_set_coeff_fmpz_n(fmpz_poly_t poly, + slong n, + const fmpz_t x); + +int fmpz_invmod_ui(fmpz_t f, + const fmpz_t g, + unsigned int mod); + +void fmpz_add_n(fmpz_t f, const fmpz_t g, const fmpz_t h); + +void poly_starmultiply(fmpz_poly_t a, + fmpz_poly_t b, + fmpz_poly_t c, ntru_context *ctx, unsigned int modulus); -int pb_mp_mul(pb_poly *a, mp_int *b, pb_poly *c); - -void pb_xor(pb_poly *a, - pb_poly *b, - pb_poly *c, - const size_t len); - -int get_degree(pb_poly const * const poly); - -bool pb_inverse_poly_q(pb_poly *a, - pb_poly *Fq, +bool poly_inverse_poly_q(fmpz_poly_t a, + fmpz_poly_t Fq, ntru_context *ctx); -bool pb_inverse_poly_p(pb_poly *a, - pb_poly *Fp, +bool poly_inverse_poly_p(fmpz_poly_t a, + fmpz_poly_t Fp, ntru_context *ctx); -void draw_polynom(pb_poly * const poly); - -void pb_normalize(pb_poly*, - int, - int, - ntru_context*); - -void draw_mp_int(mp_int*); #endif /* NTRU_POLY_H */ From d20a448b3bb3b49e246347d2e5b71685b8c484f2 Mon Sep 17 00:00:00 2001 From: hasufell Date: Sat, 24 May 2014 23:11:41 +0200 Subject: [PATCH 06/26] ALL: rm libtompoly/libtommath --- external/libtommath-0.42.0/LICENSE | 4 - external/libtommath-0.42.0/bn.tex | 1835 --- external/libtommath-0.42.0/bn_error.c | 47 - .../libtommath-0.42.0/bn_fast_mp_invmod.c | 148 - .../bn_fast_mp_montgomery_reduce.c | 172 - .../libtommath-0.42.0/bn_fast_s_mp_mul_digs.c | 107 - .../bn_fast_s_mp_mul_high_digs.c | 98 - external/libtommath-0.42.0/bn_fast_s_mp_sqr.c | 114 - external/libtommath-0.42.0/bn_mp_2expt.c | 48 - external/libtommath-0.42.0/bn_mp_abs.c | 43 - external/libtommath-0.42.0/bn_mp_add.c | 53 - external/libtommath-0.42.0/bn_mp_add_d.c | 112 - external/libtommath-0.42.0/bn_mp_addmod.c | 41 - external/libtommath-0.42.0/bn_mp_and.c | 57 - external/libtommath-0.42.0/bn_mp_clamp.c | 44 - external/libtommath-0.42.0/bn_mp_clear.c | 44 - .../libtommath-0.42.0/bn_mp_clear_multi.c | 34 - external/libtommath-0.42.0/bn_mp_cmp.c | 43 - external/libtommath-0.42.0/bn_mp_cmp_d.c | 44 - external/libtommath-0.42.0/bn_mp_cmp_mag.c | 55 - external/libtommath-0.42.0/bn_mp_cnt_lsb.c | 53 - external/libtommath-0.42.0/bn_mp_copy.c | 68 - external/libtommath-0.42.0/bn_mp_count_bits.c | 45 - external/libtommath-0.42.0/bn_mp_div.c | 292 - external/libtommath-0.42.0/bn_mp_div_2.c | 68 - external/libtommath-0.42.0/bn_mp_div_2d.c | 97 - external/libtommath-0.42.0/bn_mp_div_3.c | 79 - external/libtommath-0.42.0/bn_mp_div_d.c | 115 - .../libtommath-0.42.0/bn_mp_dr_is_modulus.c | 43 - external/libtommath-0.42.0/bn_mp_dr_reduce.c | 94 - external/libtommath-0.42.0/bn_mp_dr_setup.c | 32 - external/libtommath-0.42.0/bn_mp_exch.c | 34 - external/libtommath-0.42.0/bn_mp_expt_d.c | 57 - external/libtommath-0.42.0/bn_mp_exptmod.c | 112 - .../libtommath-0.42.0/bn_mp_exptmod_fast.c | 321 - external/libtommath-0.42.0/bn_mp_exteuclid.c | 82 - external/libtommath-0.42.0/bn_mp_fread.c | 67 - external/libtommath-0.42.0/bn_mp_fwrite.c | 52 - external/libtommath-0.42.0/bn_mp_gcd.c | 105 - external/libtommath-0.42.0/bn_mp_get_int.c | 45 - external/libtommath-0.42.0/bn_mp_grow.c | 57 - external/libtommath-0.42.0/bn_mp_init.c | 46 - external/libtommath-0.42.0/bn_mp_init_copy.c | 32 - external/libtommath-0.42.0/bn_mp_init_multi.c | 59 - external/libtommath-0.42.0/bn_mp_init_set.c | 32 - .../libtommath-0.42.0/bn_mp_init_set_int.c | 31 - external/libtommath-0.42.0/bn_mp_init_size.c | 48 - external/libtommath-0.42.0/bn_mp_invmod.c | 43 - .../libtommath-0.42.0/bn_mp_invmod_slow.c | 175 - external/libtommath-0.42.0/bn_mp_is_square.c | 109 - external/libtommath-0.42.0/bn_mp_jacobi.c | 105 - .../libtommath-0.42.0/bn_mp_karatsuba_mul.c | 167 - .../libtommath-0.42.0/bn_mp_karatsuba_sqr.c | 121 - external/libtommath-0.42.0/bn_mp_lcm.c | 60 - external/libtommath-0.42.0/bn_mp_lshd.c | 67 - external/libtommath-0.42.0/bn_mp_mod.c | 48 - external/libtommath-0.42.0/bn_mp_mod_2d.c | 55 - external/libtommath-0.42.0/bn_mp_mod_d.c | 27 - .../bn_mp_montgomery_calc_normalization.c | 59 - .../bn_mp_montgomery_reduce.c | 118 - .../bn_mp_montgomery_setup.c | 59 - external/libtommath-0.42.0/bn_mp_mul.c | 66 - external/libtommath-0.42.0/bn_mp_mul_2.c | 82 - external/libtommath-0.42.0/bn_mp_mul_2d.c | 85 - external/libtommath-0.42.0/bn_mp_mul_d.c | 79 - external/libtommath-0.42.0/bn_mp_mulmod.c | 40 - external/libtommath-0.42.0/bn_mp_n_root.c | 132 - external/libtommath-0.42.0/bn_mp_neg.c | 40 - external/libtommath-0.42.0/bn_mp_or.c | 50 - .../libtommath-0.42.0/bn_mp_prime_fermat.c | 62 - .../bn_mp_prime_is_divisible.c | 50 - .../libtommath-0.42.0/bn_mp_prime_is_prime.c | 83 - .../bn_mp_prime_miller_rabin.c | 103 - .../bn_mp_prime_next_prime.c | 170 - .../bn_mp_prime_rabin_miller_trials.c | 52 - .../libtommath-0.42.0/bn_mp_prime_random_ex.c | 125 - external/libtommath-0.42.0/bn_mp_radix_size.c | 78 - external/libtommath-0.42.0/bn_mp_radix_smap.c | 24 - external/libtommath-0.42.0/bn_mp_rand.c | 55 - external/libtommath-0.42.0/bn_mp_read_radix.c | 85 - .../libtommath-0.42.0/bn_mp_read_signed_bin.c | 41 - .../bn_mp_read_unsigned_bin.c | 55 - external/libtommath-0.42.0/bn_mp_reduce.c | 100 - external/libtommath-0.42.0/bn_mp_reduce_2k.c | 61 - .../libtommath-0.42.0/bn_mp_reduce_2k_l.c | 62 - .../libtommath-0.42.0/bn_mp_reduce_2k_setup.c | 47 - .../bn_mp_reduce_2k_setup_l.c | 44 - .../libtommath-0.42.0/bn_mp_reduce_is_2k.c | 52 - .../libtommath-0.42.0/bn_mp_reduce_is_2k_l.c | 44 - .../libtommath-0.42.0/bn_mp_reduce_setup.c | 34 - external/libtommath-0.42.0/bn_mp_rshd.c | 72 - external/libtommath-0.42.0/bn_mp_set.c | 29 - external/libtommath-0.42.0/bn_mp_set_int.c | 48 - external/libtommath-0.42.0/bn_mp_shrink.c | 40 - .../libtommath-0.42.0/bn_mp_signed_bin_size.c | 27 - external/libtommath-0.42.0/bn_mp_sqr.c | 58 - external/libtommath-0.42.0/bn_mp_sqrmod.c | 41 - external/libtommath-0.42.0/bn_mp_sqrt.c | 81 - external/libtommath-0.42.0/bn_mp_sub.c | 59 - external/libtommath-0.42.0/bn_mp_sub_d.c | 93 - external/libtommath-0.42.0/bn_mp_submod.c | 42 - .../libtommath-0.42.0/bn_mp_to_signed_bin.c | 33 - .../libtommath-0.42.0/bn_mp_to_signed_bin_n.c | 31 - .../libtommath-0.42.0/bn_mp_to_unsigned_bin.c | 48 - .../bn_mp_to_unsigned_bin_n.c | 31 - external/libtommath-0.42.0/bn_mp_toom_mul.c | 284 - external/libtommath-0.42.0/bn_mp_toom_sqr.c | 226 - external/libtommath-0.42.0/bn_mp_toradix.c | 75 - external/libtommath-0.42.0/bn_mp_toradix_n.c | 88 - .../bn_mp_unsigned_bin_size.c | 28 - external/libtommath-0.42.0/bn_mp_xor.c | 51 - external/libtommath-0.42.0/bn_mp_zero.c | 36 - external/libtommath-0.42.0/bn_prime_tab.c | 61 - external/libtommath-0.42.0/bn_reverse.c | 39 - external/libtommath-0.42.0/bn_s_mp_add.c | 109 - external/libtommath-0.42.0/bn_s_mp_exptmod.c | 252 - external/libtommath-0.42.0/bn_s_mp_mul_digs.c | 90 - .../libtommath-0.42.0/bn_s_mp_mul_high_digs.c | 81 - external/libtommath-0.42.0/bn_s_mp_sqr.c | 84 - external/libtommath-0.42.0/bn_s_mp_sub.c | 89 - external/libtommath-0.42.0/bncore.c | 36 - external/libtommath-0.42.0/booker.pl | 265 - external/libtommath-0.42.0/callgraph.txt | 11913 ---------------- external/libtommath-0.42.0/changes.txt | 403 - external/libtommath-0.42.0/demo/demo.c | 740 - external/libtommath-0.42.0/demo/timing.c | 319 - external/libtommath-0.42.0/dep.pl | 123 - external/libtommath-0.42.0/etc/2kprime.1 | 2 - external/libtommath-0.42.0/etc/2kprime.c | 84 - external/libtommath-0.42.0/etc/drprime.c | 64 - external/libtommath-0.42.0/etc/drprimes.28 | 25 - external/libtommath-0.42.0/etc/drprimes.txt | 9 - external/libtommath-0.42.0/etc/makefile | 50 - external/libtommath-0.42.0/etc/makefile.icc | 67 - external/libtommath-0.42.0/etc/makefile.msvc | 23 - external/libtommath-0.42.0/etc/mersenne.c | 144 - external/libtommath-0.42.0/etc/mont.c | 50 - external/libtommath-0.42.0/etc/pprime.c | 400 - external/libtommath-0.42.0/etc/prime.1024 | 414 - external/libtommath-0.42.0/etc/prime.512 | 205 - external/libtommath-0.42.0/etc/timer.asm | 37 - external/libtommath-0.42.0/etc/tune.c | 142 - external/libtommath-0.42.0/gen.pl | 17 - external/libtommath-0.42.0/libtommath.dsp | 572 - .../libtommath-0.42.0/libtommath_VS2005.sln | 20 - .../libtommath_VS2005.vcproj | 2803 ---- .../libtommath-0.42.0/libtommath_VS2008.sln | 20 - .../libtommath_VS2008.vcproj | 2805 ---- external/libtommath-0.42.0/logs/README | 13 - external/libtommath-0.42.0/logs/add.log | 16 - external/libtommath-0.42.0/logs/addsub.png | Bin 6254 -> 0 bytes external/libtommath-0.42.0/logs/expt.log | 7 - external/libtommath-0.42.0/logs/expt.png | Bin 6605 -> 0 bytes external/libtommath-0.42.0/logs/expt_2k.log | 5 - external/libtommath-0.42.0/logs/expt_2kl.log | 4 - external/libtommath-0.42.0/logs/expt_dr.log | 7 - external/libtommath-0.42.0/logs/graphs.dem | 17 - external/libtommath-0.42.0/logs/index.html | 27 - external/libtommath-0.42.0/logs/invmod.log | 0 external/libtommath-0.42.0/logs/invmod.png | Bin 4918 -> 0 bytes external/libtommath-0.42.0/logs/mult.log | 84 - external/libtommath-0.42.0/logs/mult.png | Bin 6770 -> 0 bytes external/libtommath-0.42.0/logs/mult_kara.log | 84 - external/libtommath-0.42.0/logs/sqr.log | 84 - external/libtommath-0.42.0/logs/sqr_kara.log | 84 - external/libtommath-0.42.0/logs/sub.log | 16 - external/libtommath-0.42.0/makefile | 186 - external/libtommath-0.42.0/makefile.bcc | 44 - .../libtommath-0.42.0/makefile.cygwin_dll | 55 - external/libtommath-0.42.0/makefile.icc | 116 - external/libtommath-0.42.0/makefile.msvc | 40 - external/libtommath-0.42.0/makefile.shared | 102 - external/libtommath-0.42.0/mess.sh | 4 - external/libtommath-0.42.0/mtest/logtab.h | 24 - external/libtommath-0.42.0/mtest/mpi-config.h | 90 - external/libtommath-0.42.0/mtest/mpi-types.h | 20 - external/libtommath-0.42.0/mtest/mpi.c | 3985 ------ external/libtommath-0.42.0/mtest/mpi.h | 231 - external/libtommath-0.42.0/mtest/mtest.c | 308 - .../libtommath-0.42.0/pics/design_process.sxd | Bin 6950 -> 0 bytes .../libtommath-0.42.0/pics/design_process.tif | Bin 79042 -> 0 bytes .../libtommath-0.42.0/pics/expt_state.sxd | Bin 6869 -> 0 bytes .../libtommath-0.42.0/pics/expt_state.tif | Bin 87542 -> 0 bytes external/libtommath-0.42.0/pics/makefile | 35 - external/libtommath-0.42.0/pics/primality.tif | Bin 85514 -> 0 bytes external/libtommath-0.42.0/pics/radix.sxd | Bin 6181 -> 0 bytes .../libtommath-0.42.0/pics/sliding_window.sxd | Bin 6787 -> 0 bytes .../libtommath-0.42.0/pics/sliding_window.tif | Bin 53880 -> 0 bytes external/libtommath-0.42.0/poster.out | 0 external/libtommath-0.42.0/poster.tex | 35 - external/libtommath-0.42.0/pre_gen/mpi.c | 9524 ------------ external/libtommath-0.42.0/pretty.build | 66 - external/libtommath-0.42.0/tombc/grammar.txt | 35 - external/libtommath-0.42.0/tommath.h | 584 - external/libtommath-0.42.0/tommath.out | 139 - external/libtommath-0.42.0/tommath.src | 6350 -------- external/libtommath-0.42.0/tommath_class.h | 999 -- .../libtommath-0.42.0/tommath_superclass.h | 76 - external/libtompoly-0.04/LICENSE | 4 - external/libtompoly-0.04/changes.txt | 24 - external/libtompoly-0.04/demo/demo.c | 216 - external/libtompoly-0.04/makefile | 56 - external/libtompoly-0.04/makefile.msvc | 17 - external/libtompoly-0.04/pb.pdf | Bin 193637 -> 0 bytes external/libtompoly-0.04/pb.tex | 433 - external/libtompoly-0.04/pb_add.c | 73 - external/libtompoly-0.04/pb_addmod.c | 35 - external/libtompoly-0.04/pb_clamp.c | 21 - external/libtompoly-0.04/pb_clear.c | 32 - external/libtompoly-0.04/pb_clear_multi.c | 25 - external/libtompoly-0.04/pb_cmp.c | 32 - external/libtompoly-0.04/pb_copy.c | 51 - external/libtompoly-0.04/pb_div.c | 135 - external/libtompoly-0.04/pb_exch.c | 20 - external/libtompoly-0.04/pb_exptmod.c | 186 - external/libtompoly-0.04/pb_exteuclid.c | 74 - external/libtompoly-0.04/pb_gcd.c | 69 - external/libtompoly-0.04/pb_grow.c | 46 - external/libtompoly-0.04/pb_init.c | 49 - external/libtompoly-0.04/pb_init_copy.c | 21 - external/libtompoly-0.04/pb_init_multi.c | 50 - external/libtompoly-0.04/pb_init_size.c | 58 - external/libtompoly-0.04/pb_invmod.c | 33 - external/libtompoly-0.04/pb_isirreduc.c | 59 - external/libtompoly-0.04/pb_lshd.c | 42 - external/libtompoly-0.04/pb_mod.c | 19 - external/libtompoly-0.04/pb_monic.c | 60 - external/libtompoly-0.04/pb_mul.c | 62 - external/libtompoly-0.04/pb_mulmod.c | 35 - external/libtompoly-0.04/pb_rawsize.c | 32 - external/libtompoly-0.04/pb_readraw.c | 55 - external/libtompoly-0.04/pb_rshd.c | 38 - external/libtompoly-0.04/pb_shrink.c | 44 - external/libtompoly-0.04/pb_sub.c | 86 - external/libtompoly-0.04/pb_submod.c | 35 - external/libtompoly-0.04/pb_toraw.c | 42 - external/libtompoly-0.04/pb_zero.c | 23 - external/libtompoly-0.04/tompoly.h | 115 - 238 files changed, 58604 deletions(-) delete mode 100755 external/libtommath-0.42.0/LICENSE delete mode 100755 external/libtommath-0.42.0/bn.tex delete mode 100755 external/libtommath-0.42.0/bn_error.c delete mode 100755 external/libtommath-0.42.0/bn_fast_mp_invmod.c delete mode 100755 external/libtommath-0.42.0/bn_fast_mp_montgomery_reduce.c delete mode 100755 external/libtommath-0.42.0/bn_fast_s_mp_mul_digs.c delete mode 100755 external/libtommath-0.42.0/bn_fast_s_mp_mul_high_digs.c delete mode 100755 external/libtommath-0.42.0/bn_fast_s_mp_sqr.c delete mode 100755 external/libtommath-0.42.0/bn_mp_2expt.c delete mode 100755 external/libtommath-0.42.0/bn_mp_abs.c delete mode 100755 external/libtommath-0.42.0/bn_mp_add.c delete mode 100755 external/libtommath-0.42.0/bn_mp_add_d.c delete mode 100755 external/libtommath-0.42.0/bn_mp_addmod.c delete mode 100755 external/libtommath-0.42.0/bn_mp_and.c delete mode 100755 external/libtommath-0.42.0/bn_mp_clamp.c delete mode 100755 external/libtommath-0.42.0/bn_mp_clear.c delete mode 100755 external/libtommath-0.42.0/bn_mp_clear_multi.c delete mode 100755 external/libtommath-0.42.0/bn_mp_cmp.c delete mode 100755 external/libtommath-0.42.0/bn_mp_cmp_d.c delete mode 100755 external/libtommath-0.42.0/bn_mp_cmp_mag.c delete mode 100755 external/libtommath-0.42.0/bn_mp_cnt_lsb.c delete mode 100755 external/libtommath-0.42.0/bn_mp_copy.c delete mode 100755 external/libtommath-0.42.0/bn_mp_count_bits.c delete mode 100755 external/libtommath-0.42.0/bn_mp_div.c delete mode 100755 external/libtommath-0.42.0/bn_mp_div_2.c delete mode 100755 external/libtommath-0.42.0/bn_mp_div_2d.c delete mode 100755 external/libtommath-0.42.0/bn_mp_div_3.c delete mode 100755 external/libtommath-0.42.0/bn_mp_div_d.c delete mode 100755 external/libtommath-0.42.0/bn_mp_dr_is_modulus.c delete mode 100755 external/libtommath-0.42.0/bn_mp_dr_reduce.c delete mode 100755 external/libtommath-0.42.0/bn_mp_dr_setup.c delete mode 100755 external/libtommath-0.42.0/bn_mp_exch.c delete mode 100755 external/libtommath-0.42.0/bn_mp_expt_d.c delete mode 100755 external/libtommath-0.42.0/bn_mp_exptmod.c delete mode 100755 external/libtommath-0.42.0/bn_mp_exptmod_fast.c delete mode 100755 external/libtommath-0.42.0/bn_mp_exteuclid.c delete mode 100755 external/libtommath-0.42.0/bn_mp_fread.c delete mode 100755 external/libtommath-0.42.0/bn_mp_fwrite.c delete mode 100755 external/libtommath-0.42.0/bn_mp_gcd.c delete mode 100755 external/libtommath-0.42.0/bn_mp_get_int.c delete mode 100755 external/libtommath-0.42.0/bn_mp_grow.c delete mode 100755 external/libtommath-0.42.0/bn_mp_init.c delete mode 100755 external/libtommath-0.42.0/bn_mp_init_copy.c delete mode 100755 external/libtommath-0.42.0/bn_mp_init_multi.c delete mode 100755 external/libtommath-0.42.0/bn_mp_init_set.c delete mode 100755 external/libtommath-0.42.0/bn_mp_init_set_int.c delete mode 100755 external/libtommath-0.42.0/bn_mp_init_size.c delete mode 100755 external/libtommath-0.42.0/bn_mp_invmod.c delete mode 100755 external/libtommath-0.42.0/bn_mp_invmod_slow.c delete mode 100755 external/libtommath-0.42.0/bn_mp_is_square.c delete mode 100755 external/libtommath-0.42.0/bn_mp_jacobi.c delete mode 100755 external/libtommath-0.42.0/bn_mp_karatsuba_mul.c delete mode 100755 external/libtommath-0.42.0/bn_mp_karatsuba_sqr.c delete mode 100755 external/libtommath-0.42.0/bn_mp_lcm.c delete mode 100755 external/libtommath-0.42.0/bn_mp_lshd.c delete mode 100755 external/libtommath-0.42.0/bn_mp_mod.c delete mode 100755 external/libtommath-0.42.0/bn_mp_mod_2d.c delete mode 100755 external/libtommath-0.42.0/bn_mp_mod_d.c delete mode 100755 external/libtommath-0.42.0/bn_mp_montgomery_calc_normalization.c delete mode 100755 external/libtommath-0.42.0/bn_mp_montgomery_reduce.c delete mode 100755 external/libtommath-0.42.0/bn_mp_montgomery_setup.c delete mode 100755 external/libtommath-0.42.0/bn_mp_mul.c delete mode 100755 external/libtommath-0.42.0/bn_mp_mul_2.c delete mode 100755 external/libtommath-0.42.0/bn_mp_mul_2d.c delete mode 100755 external/libtommath-0.42.0/bn_mp_mul_d.c delete mode 100755 external/libtommath-0.42.0/bn_mp_mulmod.c delete mode 100755 external/libtommath-0.42.0/bn_mp_n_root.c delete mode 100755 external/libtommath-0.42.0/bn_mp_neg.c delete mode 100755 external/libtommath-0.42.0/bn_mp_or.c delete mode 100755 external/libtommath-0.42.0/bn_mp_prime_fermat.c delete mode 100755 external/libtommath-0.42.0/bn_mp_prime_is_divisible.c delete mode 100755 external/libtommath-0.42.0/bn_mp_prime_is_prime.c delete mode 100755 external/libtommath-0.42.0/bn_mp_prime_miller_rabin.c delete mode 100755 external/libtommath-0.42.0/bn_mp_prime_next_prime.c delete mode 100755 external/libtommath-0.42.0/bn_mp_prime_rabin_miller_trials.c delete mode 100755 external/libtommath-0.42.0/bn_mp_prime_random_ex.c delete mode 100755 external/libtommath-0.42.0/bn_mp_radix_size.c delete mode 100755 external/libtommath-0.42.0/bn_mp_radix_smap.c delete mode 100755 external/libtommath-0.42.0/bn_mp_rand.c delete mode 100755 external/libtommath-0.42.0/bn_mp_read_radix.c delete mode 100755 external/libtommath-0.42.0/bn_mp_read_signed_bin.c delete mode 100755 external/libtommath-0.42.0/bn_mp_read_unsigned_bin.c delete mode 100755 external/libtommath-0.42.0/bn_mp_reduce.c delete mode 100755 external/libtommath-0.42.0/bn_mp_reduce_2k.c delete mode 100755 external/libtommath-0.42.0/bn_mp_reduce_2k_l.c delete mode 100755 external/libtommath-0.42.0/bn_mp_reduce_2k_setup.c delete mode 100755 external/libtommath-0.42.0/bn_mp_reduce_2k_setup_l.c delete mode 100755 external/libtommath-0.42.0/bn_mp_reduce_is_2k.c delete mode 100755 external/libtommath-0.42.0/bn_mp_reduce_is_2k_l.c delete mode 100755 external/libtommath-0.42.0/bn_mp_reduce_setup.c delete mode 100755 external/libtommath-0.42.0/bn_mp_rshd.c delete mode 100755 external/libtommath-0.42.0/bn_mp_set.c delete mode 100755 external/libtommath-0.42.0/bn_mp_set_int.c delete mode 100755 external/libtommath-0.42.0/bn_mp_shrink.c delete mode 100755 external/libtommath-0.42.0/bn_mp_signed_bin_size.c delete mode 100755 external/libtommath-0.42.0/bn_mp_sqr.c delete mode 100755 external/libtommath-0.42.0/bn_mp_sqrmod.c delete mode 100755 external/libtommath-0.42.0/bn_mp_sqrt.c delete mode 100755 external/libtommath-0.42.0/bn_mp_sub.c delete mode 100755 external/libtommath-0.42.0/bn_mp_sub_d.c delete mode 100755 external/libtommath-0.42.0/bn_mp_submod.c delete mode 100755 external/libtommath-0.42.0/bn_mp_to_signed_bin.c delete mode 100755 external/libtommath-0.42.0/bn_mp_to_signed_bin_n.c delete mode 100755 external/libtommath-0.42.0/bn_mp_to_unsigned_bin.c delete mode 100755 external/libtommath-0.42.0/bn_mp_to_unsigned_bin_n.c delete mode 100755 external/libtommath-0.42.0/bn_mp_toom_mul.c delete mode 100755 external/libtommath-0.42.0/bn_mp_toom_sqr.c delete mode 100755 external/libtommath-0.42.0/bn_mp_toradix.c delete mode 100755 external/libtommath-0.42.0/bn_mp_toradix_n.c delete mode 100755 external/libtommath-0.42.0/bn_mp_unsigned_bin_size.c delete mode 100755 external/libtommath-0.42.0/bn_mp_xor.c delete mode 100755 external/libtommath-0.42.0/bn_mp_zero.c delete mode 100755 external/libtommath-0.42.0/bn_prime_tab.c delete mode 100755 external/libtommath-0.42.0/bn_reverse.c delete mode 100755 external/libtommath-0.42.0/bn_s_mp_add.c delete mode 100755 external/libtommath-0.42.0/bn_s_mp_exptmod.c delete mode 100755 external/libtommath-0.42.0/bn_s_mp_mul_digs.c delete mode 100755 external/libtommath-0.42.0/bn_s_mp_mul_high_digs.c delete mode 100755 external/libtommath-0.42.0/bn_s_mp_sqr.c delete mode 100755 external/libtommath-0.42.0/bn_s_mp_sub.c delete mode 100755 external/libtommath-0.42.0/bncore.c delete mode 100755 external/libtommath-0.42.0/booker.pl delete mode 100755 external/libtommath-0.42.0/callgraph.txt delete mode 100755 external/libtommath-0.42.0/changes.txt delete mode 100755 external/libtommath-0.42.0/demo/demo.c delete mode 100755 external/libtommath-0.42.0/demo/timing.c delete mode 100755 external/libtommath-0.42.0/dep.pl delete mode 100755 external/libtommath-0.42.0/etc/2kprime.1 delete mode 100755 external/libtommath-0.42.0/etc/2kprime.c delete mode 100755 external/libtommath-0.42.0/etc/drprime.c delete mode 100755 external/libtommath-0.42.0/etc/drprimes.28 delete mode 100755 external/libtommath-0.42.0/etc/drprimes.txt delete mode 100755 external/libtommath-0.42.0/etc/makefile delete mode 100755 external/libtommath-0.42.0/etc/makefile.icc delete mode 100755 external/libtommath-0.42.0/etc/makefile.msvc delete mode 100755 external/libtommath-0.42.0/etc/mersenne.c delete mode 100755 external/libtommath-0.42.0/etc/mont.c delete mode 100755 external/libtommath-0.42.0/etc/pprime.c delete mode 100755 external/libtommath-0.42.0/etc/prime.1024 delete mode 100755 external/libtommath-0.42.0/etc/prime.512 delete mode 100755 external/libtommath-0.42.0/etc/timer.asm delete mode 100755 external/libtommath-0.42.0/etc/tune.c delete mode 100755 external/libtommath-0.42.0/gen.pl delete mode 100755 external/libtommath-0.42.0/libtommath.dsp delete mode 100755 external/libtommath-0.42.0/libtommath_VS2005.sln delete mode 100755 external/libtommath-0.42.0/libtommath_VS2005.vcproj delete mode 100755 external/libtommath-0.42.0/libtommath_VS2008.sln delete mode 100755 external/libtommath-0.42.0/libtommath_VS2008.vcproj delete mode 100755 external/libtommath-0.42.0/logs/README delete mode 100755 external/libtommath-0.42.0/logs/add.log delete mode 100755 external/libtommath-0.42.0/logs/addsub.png delete mode 100755 external/libtommath-0.42.0/logs/expt.log delete mode 100755 external/libtommath-0.42.0/logs/expt.png delete mode 100755 external/libtommath-0.42.0/logs/expt_2k.log delete mode 100755 external/libtommath-0.42.0/logs/expt_2kl.log delete mode 100755 external/libtommath-0.42.0/logs/expt_dr.log delete mode 100755 external/libtommath-0.42.0/logs/graphs.dem delete mode 100755 external/libtommath-0.42.0/logs/index.html delete mode 100755 external/libtommath-0.42.0/logs/invmod.log delete mode 100755 external/libtommath-0.42.0/logs/invmod.png delete mode 100755 external/libtommath-0.42.0/logs/mult.log delete mode 100755 external/libtommath-0.42.0/logs/mult.png delete mode 100755 external/libtommath-0.42.0/logs/mult_kara.log delete mode 100755 external/libtommath-0.42.0/logs/sqr.log delete mode 100755 external/libtommath-0.42.0/logs/sqr_kara.log delete mode 100755 external/libtommath-0.42.0/logs/sub.log delete mode 100755 external/libtommath-0.42.0/makefile delete mode 100755 external/libtommath-0.42.0/makefile.bcc delete mode 100755 external/libtommath-0.42.0/makefile.cygwin_dll delete mode 100755 external/libtommath-0.42.0/makefile.icc delete mode 100755 external/libtommath-0.42.0/makefile.msvc delete mode 100755 external/libtommath-0.42.0/makefile.shared delete mode 100755 external/libtommath-0.42.0/mess.sh delete mode 100755 external/libtommath-0.42.0/mtest/logtab.h delete mode 100755 external/libtommath-0.42.0/mtest/mpi-config.h delete mode 100755 external/libtommath-0.42.0/mtest/mpi-types.h delete mode 100755 external/libtommath-0.42.0/mtest/mpi.c delete mode 100755 external/libtommath-0.42.0/mtest/mpi.h delete mode 100755 external/libtommath-0.42.0/mtest/mtest.c delete mode 100755 external/libtommath-0.42.0/pics/design_process.sxd delete mode 100755 external/libtommath-0.42.0/pics/design_process.tif delete mode 100755 external/libtommath-0.42.0/pics/expt_state.sxd delete mode 100755 external/libtommath-0.42.0/pics/expt_state.tif delete mode 100755 external/libtommath-0.42.0/pics/makefile delete mode 100755 external/libtommath-0.42.0/pics/primality.tif delete mode 100755 external/libtommath-0.42.0/pics/radix.sxd delete mode 100755 external/libtommath-0.42.0/pics/sliding_window.sxd delete mode 100755 external/libtommath-0.42.0/pics/sliding_window.tif delete mode 100644 external/libtommath-0.42.0/poster.out delete mode 100755 external/libtommath-0.42.0/poster.tex delete mode 100644 external/libtommath-0.42.0/pre_gen/mpi.c delete mode 100755 external/libtommath-0.42.0/pretty.build delete mode 100755 external/libtommath-0.42.0/tombc/grammar.txt delete mode 100755 external/libtommath-0.42.0/tommath.h delete mode 100755 external/libtommath-0.42.0/tommath.out delete mode 100755 external/libtommath-0.42.0/tommath.src delete mode 100755 external/libtommath-0.42.0/tommath_class.h delete mode 100755 external/libtommath-0.42.0/tommath_superclass.h delete mode 100644 external/libtompoly-0.04/LICENSE delete mode 100644 external/libtompoly-0.04/changes.txt delete mode 100644 external/libtompoly-0.04/demo/demo.c delete mode 100644 external/libtompoly-0.04/makefile delete mode 100644 external/libtompoly-0.04/makefile.msvc delete mode 100644 external/libtompoly-0.04/pb.pdf delete mode 100644 external/libtompoly-0.04/pb.tex delete mode 100644 external/libtompoly-0.04/pb_add.c delete mode 100644 external/libtompoly-0.04/pb_addmod.c delete mode 100644 external/libtompoly-0.04/pb_clamp.c delete mode 100644 external/libtompoly-0.04/pb_clear.c delete mode 100644 external/libtompoly-0.04/pb_clear_multi.c delete mode 100644 external/libtompoly-0.04/pb_cmp.c delete mode 100644 external/libtompoly-0.04/pb_copy.c delete mode 100644 external/libtompoly-0.04/pb_div.c delete mode 100644 external/libtompoly-0.04/pb_exch.c delete mode 100644 external/libtompoly-0.04/pb_exptmod.c delete mode 100644 external/libtompoly-0.04/pb_exteuclid.c delete mode 100644 external/libtompoly-0.04/pb_gcd.c delete mode 100644 external/libtompoly-0.04/pb_grow.c delete mode 100644 external/libtompoly-0.04/pb_init.c delete mode 100644 external/libtompoly-0.04/pb_init_copy.c delete mode 100644 external/libtompoly-0.04/pb_init_multi.c delete mode 100644 external/libtompoly-0.04/pb_init_size.c delete mode 100644 external/libtompoly-0.04/pb_invmod.c delete mode 100644 external/libtompoly-0.04/pb_isirreduc.c delete mode 100644 external/libtompoly-0.04/pb_lshd.c delete mode 100644 external/libtompoly-0.04/pb_mod.c delete mode 100644 external/libtompoly-0.04/pb_monic.c delete mode 100644 external/libtompoly-0.04/pb_mul.c delete mode 100644 external/libtompoly-0.04/pb_mulmod.c delete mode 100644 external/libtompoly-0.04/pb_rawsize.c delete mode 100644 external/libtompoly-0.04/pb_readraw.c delete mode 100644 external/libtompoly-0.04/pb_rshd.c delete mode 100644 external/libtompoly-0.04/pb_shrink.c delete mode 100644 external/libtompoly-0.04/pb_sub.c delete mode 100644 external/libtompoly-0.04/pb_submod.c delete mode 100644 external/libtompoly-0.04/pb_toraw.c delete mode 100644 external/libtompoly-0.04/pb_zero.c delete mode 100644 external/libtompoly-0.04/tompoly.h diff --git a/external/libtommath-0.42.0/LICENSE b/external/libtommath-0.42.0/LICENSE deleted file mode 100755 index 5baa792..0000000 --- a/external/libtommath-0.42.0/LICENSE +++ /dev/null @@ -1,4 +0,0 @@ -LibTomMath is hereby released into the Public Domain. - --- Tom St Denis - diff --git a/external/libtommath-0.42.0/bn.tex b/external/libtommath-0.42.0/bn.tex deleted file mode 100755 index 71b6840..0000000 --- a/external/libtommath-0.42.0/bn.tex +++ /dev/null @@ -1,1835 +0,0 @@ -\documentclass[synpaper]{book} -\usepackage{hyperref} -\usepackage{makeidx} -\usepackage{amssymb} -\usepackage{color} -\usepackage{alltt} -\usepackage{graphicx} -\usepackage{layout} -\def\union{\cup} -\def\intersect{\cap} -\def\getsrandom{\stackrel{\rm R}{\gets}} -\def\cross{\times} -\def\cat{\hspace{0.5em} \| \hspace{0.5em}} -\def\catn{$\|$} -\def\divides{\hspace{0.3em} | \hspace{0.3em}} -\def\nequiv{\not\equiv} -\def\approx{\raisebox{0.2ex}{\mbox{\small $\sim$}}} -\def\lcm{{\rm lcm}} -\def\gcd{{\rm gcd}} -\def\log{{\rm log}} -\def\ord{{\rm ord}} -\def\abs{{\mathit abs}} -\def\rep{{\mathit rep}} -\def\mod{{\mathit\ mod\ }} -\renewcommand{\pmod}[1]{\ ({\rm mod\ }{#1})} -\newcommand{\floor}[1]{\left\lfloor{#1}\right\rfloor} -\newcommand{\ceil}[1]{\left\lceil{#1}\right\rceil} -\def\Or{{\rm\ or\ }} -\def\And{{\rm\ and\ }} -\def\iff{\hspace{1em}\Longleftrightarrow\hspace{1em}} -\def\implies{\Rightarrow} -\def\undefined{{\rm ``undefined"}} -\def\Proof{\vspace{1ex}\noindent {\bf Proof:}\hspace{1em}} -\let\oldphi\phi -\def\phi{\varphi} -\def\Pr{{\rm Pr}} -\newcommand{\str}[1]{{\mathbf{#1}}} -\def\F{{\mathbb F}} -\def\N{{\mathbb N}} -\def\Z{{\mathbb Z}} -\def\R{{\mathbb R}} -\def\C{{\mathbb C}} -\def\Q{{\mathbb Q}} -\definecolor{DGray}{gray}{0.5} -\newcommand{\emailaddr}[1]{\mbox{$<${#1}$>$}} -\def\twiddle{\raisebox{0.3ex}{\mbox{\tiny $\sim$}}} -\def\gap{\vspace{0.5ex}} -\makeindex -\begin{document} -\frontmatter -\pagestyle{empty} -\title{LibTomMath User Manual \\ v0.42.0} -\author{Tom St Denis \\ tomstdenis@gmail.com} -\maketitle -This text, the library and the accompanying textbook are all hereby placed in the public domain. This book has been -formatted for B5 [176x250] paper using the \LaTeX{} {\em book} macro package. - -\vspace{10cm} - -\begin{flushright}Open Source. Open Academia. Open Minds. - -\mbox{ } - -Tom St Denis, - -Ontario, Canada -\end{flushright} - -\tableofcontents -\listoffigures -\mainmatter -\pagestyle{headings} -\chapter{Introduction} -\section{What is LibTomMath?} -LibTomMath is a library of source code which provides a series of efficient and carefully written functions for manipulating -large integer numbers. It was written in portable ISO C source code so that it will build on any platform with a conforming -C compiler. - -In a nutshell the library was written from scratch with verbose comments to help instruct computer science students how -to implement ``bignum'' math. However, the resulting code has proven to be very useful. It has been used by numerous -universities, commercial and open source software developers. It has been used on a variety of platforms ranging from -Linux and Windows based x86 to ARM based Gameboys and PPC based MacOS machines. - -\section{License} -As of the v0.25 the library source code has been placed in the public domain with every new release. As of the v0.28 -release the textbook ``Implementing Multiple Precision Arithmetic'' has been placed in the public domain with every new -release as well. This textbook is meant to compliment the project by providing a more solid walkthrough of the development -algorithms used in the library. - -Since both\footnote{Note that the MPI files under mtest/ are copyrighted by Michael Fromberger. They are not required to use LibTomMath.} are in the -public domain everyone is entitled to do with them as they see fit. - -\section{Building LibTomMath} - -LibTomMath is meant to be very ``GCC friendly'' as it comes with a makefile well suited for GCC. However, the library will -also build in MSVC, Borland C out of the box. For any other ISO C compiler a makefile will have to be made by the end -developer. - -\subsection{Static Libraries} -To build as a static library for GCC issue the following -\begin{alltt} -make -\end{alltt} - -command. This will build the library and archive the object files in ``libtommath.a''. Now you link against -that and include ``tommath.h'' within your programs. Alternatively to build with MSVC issue the following -\begin{alltt} -nmake -f makefile.msvc -\end{alltt} - -This will build the library and archive the object files in ``tommath.lib''. This has been tested with MSVC -version 6.00 with service pack 5. - -\subsection{Shared Libraries} -To build as a shared library for GCC issue the following -\begin{alltt} -make -f makefile.shared -\end{alltt} -This requires the ``libtool'' package (common on most Linux/BSD systems). It will build LibTomMath as both shared -and static then install (by default) into /usr/lib as well as install the header files in /usr/include. The shared -library (resource) will be called ``libtommath.la'' while the static library called ``libtommath.a''. Generally -you use libtool to link your application against the shared object. - -There is limited support for making a ``DLL'' in windows via the ``makefile.cygwin\_dll'' makefile. It requires -Cygwin to work with since it requires the auto-export/import functionality. The resulting DLL and import library -``libtommath.dll.a'' can be used to link LibTomMath dynamically to any Windows program using Cygwin. - -\subsection{Testing} -To build the library and the test harness type - -\begin{alltt} -make test -\end{alltt} - -This will build the library, ``test'' and ``mtest/mtest''. The ``test'' program will accept test vectors and verify the -results. ``mtest/mtest'' will generate test vectors using the MPI library by Michael Fromberger\footnote{A copy of MPI -is included in the package}. Simply pipe mtest into test using - -\begin{alltt} -mtest/mtest | test -\end{alltt} - -If you do not have a ``/dev/urandom'' style RNG source you will have to write your own PRNG and simply pipe that into -mtest. For example, if your PRNG program is called ``myprng'' simply invoke - -\begin{alltt} -myprng | mtest/mtest | test -\end{alltt} - -This will output a row of numbers that are increasing. Each column is a different test (such as addition, multiplication, etc) -that is being performed. The numbers represent how many times the test was invoked. If an error is detected the program -will exit with a dump of the relevent numbers it was working with. - -\section{Build Configuration} -LibTomMath can configured at build time in three phases we shall call ``depends'', ``tweaks'' and ``trims''. -Each phase changes how the library is built and they are applied one after another respectively. - -To make the system more powerful you can tweak the build process. Classes are defined in the file -``tommath\_superclass.h''. By default, the symbol ``LTM\_ALL'' shall be defined which simply -instructs the system to build all of the functions. This is how LibTomMath used to be packaged. This will give you -access to every function LibTomMath offers. - -However, there are cases where such a build is not optional. For instance, you want to perform RSA operations. You -don't need the vast majority of the library to perform these operations. Aside from LTM\_ALL there is -another pre--defined class ``SC\_RSA\_1'' which works in conjunction with the RSA from LibTomCrypt. Additional -classes can be defined base on the need of the user. - -\subsection{Build Depends} -In the file tommath\_class.h you will see a large list of C ``defines'' followed by a series of ``ifdefs'' -which further define symbols. All of the symbols (technically they're macros $\ldots$) represent a given C source -file. For instance, BN\_MP\_ADD\_C represents the file ``bn\_mp\_add.c''. When a define has been enabled the -function in the respective file will be compiled and linked into the library. Accordingly when the define -is absent the file will not be compiled and not contribute any size to the library. - -You will also note that the header tommath\_class.h is actually recursively included (it includes itself twice). -This is to help resolve as many dependencies as possible. In the last pass the symbol LTM\_LAST will be defined. -This is useful for ``trims''. - -\subsection{Build Tweaks} -A tweak is an algorithm ``alternative''. For example, to provide tradeoffs (usually between size and space). -They can be enabled at any pass of the configuration phase. - -\begin{small} -\begin{center} -\begin{tabular}{|l|l|} -\hline \textbf{Define} & \textbf{Purpose} \\ -\hline BN\_MP\_DIV\_SMALL & Enables a slower, smaller and equally \\ - & functional mp\_div() function \\ -\hline -\end{tabular} -\end{center} -\end{small} - -\subsection{Build Trims} -A trim is a manner of removing functionality from a function that is not required. For instance, to perform -RSA cryptography you only require exponentiation with odd moduli so even moduli support can be safely removed. -Build trims are meant to be defined on the last pass of the configuration which means they are to be defined -only if LTM\_LAST has been defined. - -\subsubsection{Moduli Related} -\begin{small} -\begin{center} -\begin{tabular}{|l|l|} -\hline \textbf{Restriction} & \textbf{Undefine} \\ -\hline Exponentiation with odd moduli only & BN\_S\_MP\_EXPTMOD\_C \\ - & BN\_MP\_REDUCE\_C \\ - & BN\_MP\_REDUCE\_SETUP\_C \\ - & BN\_S\_MP\_MUL\_HIGH\_DIGS\_C \\ - & BN\_FAST\_S\_MP\_MUL\_HIGH\_DIGS\_C \\ -\hline Exponentiation with random odd moduli & (The above plus the following) \\ - & BN\_MP\_REDUCE\_2K\_C \\ - & BN\_MP\_REDUCE\_2K\_SETUP\_C \\ - & BN\_MP\_REDUCE\_IS\_2K\_C \\ - & BN\_MP\_DR\_IS\_MODULUS\_C \\ - & BN\_MP\_DR\_REDUCE\_C \\ - & BN\_MP\_DR\_SETUP\_C \\ -\hline Modular inverse odd moduli only & BN\_MP\_INVMOD\_SLOW\_C \\ -\hline Modular inverse (both, smaller/slower) & BN\_FAST\_MP\_INVMOD\_C \\ -\hline -\end{tabular} -\end{center} -\end{small} - -\subsubsection{Operand Size Related} -\begin{small} -\begin{center} -\begin{tabular}{|l|l|} -\hline \textbf{Restriction} & \textbf{Undefine} \\ -\hline Moduli $\le 2560$ bits & BN\_MP\_MONTGOMERY\_REDUCE\_C \\ - & BN\_S\_MP\_MUL\_DIGS\_C \\ - & BN\_S\_MP\_MUL\_HIGH\_DIGS\_C \\ - & BN\_S\_MP\_SQR\_C \\ -\hline Polynomial Schmolynomial & BN\_MP\_KARATSUBA\_MUL\_C \\ - & BN\_MP\_KARATSUBA\_SQR\_C \\ - & BN\_MP\_TOOM\_MUL\_C \\ - & BN\_MP\_TOOM\_SQR\_C \\ - -\hline -\end{tabular} -\end{center} -\end{small} - - -\section{Purpose of LibTomMath} -Unlike GNU MP (GMP) Library, LIP, OpenSSL or various other commercial kits (Miracl), LibTomMath was not written with -bleeding edge performance in mind. First and foremost LibTomMath was written to be entirely open. Not only is the -source code public domain (unlike various other GPL/etc licensed code), not only is the code freely downloadable but the -source code is also accessible for computer science students attempting to learn ``BigNum'' or multiple precision -arithmetic techniques. - -LibTomMath was written to be an instructive collection of source code. This is why there are many comments, only one -function per source file and often I use a ``middle-road'' approach where I don't cut corners for an extra 2\% speed -increase. - -Source code alone cannot really teach how the algorithms work which is why I also wrote a textbook that accompanies -the library (beat that!). - -So you may be thinking ``should I use LibTomMath?'' and the answer is a definite maybe. Let me tabulate what I think -are the pros and cons of LibTomMath by comparing it to the math routines from GnuPG\footnote{GnuPG v1.2.3 versus LibTomMath v0.28}. - -\newpage\begin{figure}[here] -\begin{small} -\begin{center} -\begin{tabular}{|l|c|c|l|} -\hline \textbf{Criteria} & \textbf{Pro} & \textbf{Con} & \textbf{Notes} \\ -\hline Few lines of code per file & X & & GnuPG $ = 300.9$, LibTomMath $ = 71.97$ \\ -\hline Commented function prototypes & X && GnuPG function names are cryptic. \\ -\hline Speed && X & LibTomMath is slower. \\ -\hline Totally free & X & & GPL has unfavourable restrictions.\\ -\hline Large function base & X & & GnuPG is barebones. \\ -\hline Five modular reduction algorithms & X & & Faster modular exponentiation for a variety of moduli. \\ -\hline Portable & X & & GnuPG requires configuration to build. \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{LibTomMath Valuation} -\end{figure} - -It may seem odd to compare LibTomMath to GnuPG since the math in GnuPG is only a small portion of the entire application. -However, LibTomMath was written with cryptography in mind. It provides essentially all of the functions a cryptosystem -would require when working with large integers. - -So it may feel tempting to just rip the math code out of GnuPG (or GnuMP where it was taken from originally) in your -own application but I think there are reasons not to. While LibTomMath is slower than libraries such as GnuMP it is -not normally significantly slower. On x86 machines the difference is normally a factor of two when performing modular -exponentiations. It depends largely on the processor, compiler and the moduli being used. - -Essentially the only time you wouldn't use LibTomMath is when blazing speed is the primary concern. However, -on the other side of the coin LibTomMath offers you a totally free (public domain) well structured math library -that is very flexible, complete and performs well in resource contrained environments. Fast RSA for example can -be performed with as little as 8KB of ram for data (again depending on build options). - -\chapter{Getting Started with LibTomMath} -\section{Building Programs} -In order to use LibTomMath you must include ``tommath.h'' and link against the appropriate library file (typically -libtommath.a). There is no library initialization required and the entire library is thread safe. - -\section{Return Codes} -There are three possible return codes a function may return. - -\index{MP\_OKAY}\index{MP\_YES}\index{MP\_NO}\index{MP\_VAL}\index{MP\_MEM} -\begin{figure}[here!] -\begin{center} -\begin{small} -\begin{tabular}{|l|l|} -\hline \textbf{Code} & \textbf{Meaning} \\ -\hline MP\_OKAY & The function succeeded. \\ -\hline MP\_VAL & The function input was invalid. \\ -\hline MP\_MEM & Heap memory exhausted. \\ -\hline &\\ -\hline MP\_YES & Response is yes. \\ -\hline MP\_NO & Response is no. \\ -\hline -\end{tabular} -\end{small} -\end{center} -\caption{Return Codes} -\end{figure} - -The last two codes listed are not actually ``return'ed'' by a function. They are placed in an integer (the caller must -provide the address of an integer it can store to) which the caller can access. To convert one of the three return codes -to a string use the following function. - -\index{mp\_error\_to\_string} -\begin{alltt} -char *mp_error_to_string(int code); -\end{alltt} - -This will return a pointer to a string which describes the given error code. It will not work for the return codes -MP\_YES and MP\_NO. - -\section{Data Types} -The basic ``multiple precision integer'' type is known as the ``mp\_int'' within LibTomMath. This data type is used to -organize all of the data required to manipulate the integer it represents. Within LibTomMath it has been prototyped -as the following. - -\index{mp\_int} -\begin{alltt} -typedef struct \{ - int used, alloc, sign; - mp_digit *dp; -\} mp_int; -\end{alltt} - -Where ``mp\_digit'' is a data type that represents individual digits of the integer. By default, an mp\_digit is the -ISO C ``unsigned long'' data type and each digit is $28-$bits long. The mp\_digit type can be configured to suit other -platforms by defining the appropriate macros. - -All LTM functions that use the mp\_int type will expect a pointer to mp\_int structure. You must allocate memory to -hold the structure itself by yourself (whether off stack or heap it doesn't matter). The very first thing that must be -done to use an mp\_int is that it must be initialized. - -\section{Function Organization} - -The arithmetic functions of the library are all organized to have the same style prototype. That is source operands -are passed on the left and the destination is on the right. For instance, - -\begin{alltt} -mp_add(&a, &b, &c); /* c = a + b */ -mp_mul(&a, &a, &c); /* c = a * a */ -mp_div(&a, &b, &c, &d); /* c = [a/b], d = a mod b */ -\end{alltt} - -Another feature of the way the functions have been implemented is that source operands can be destination operands as well. -For instance, - -\begin{alltt} -mp_add(&a, &b, &b); /* b = a + b */ -mp_div(&a, &b, &a, &c); /* a = [a/b], c = a mod b */ -\end{alltt} - -This allows operands to be re-used which can make programming simpler. - -\section{Initialization} -\subsection{Single Initialization} -A single mp\_int can be initialized with the ``mp\_init'' function. - -\index{mp\_init} -\begin{alltt} -int mp_init (mp_int * a); -\end{alltt} - -This function expects a pointer to an mp\_int structure and will initialize the members of the structure so the mp\_int -represents the default integer which is zero. If the functions returns MP\_OKAY then the mp\_int is ready to be used -by the other LibTomMath functions. - -\begin{small} \begin{alltt} -int main(void) -\{ - mp_int number; - int result; - - if ((result = mp_init(&number)) != MP_OKAY) \{ - printf("Error initializing the number. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* use the number */ - - return EXIT_SUCCESS; -\} -\end{alltt} \end{small} - -\subsection{Single Free} -When you are finished with an mp\_int it is ideal to return the heap it used back to the system. The following function -provides this functionality. - -\index{mp\_clear} -\begin{alltt} -void mp_clear (mp_int * a); -\end{alltt} - -The function expects a pointer to a previously initialized mp\_int structure and frees the heap it uses. It sets the -pointer\footnote{The ``dp'' member.} within the mp\_int to \textbf{NULL} which is used to prevent double free situations. -Is is legal to call mp\_clear() twice on the same mp\_int in a row. - -\begin{small} \begin{alltt} -int main(void) -\{ - mp_int number; - int result; - - if ((result = mp_init(&number)) != MP_OKAY) \{ - printf("Error initializing the number. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* use the number */ - - /* We're done with it. */ - mp_clear(&number); - - return EXIT_SUCCESS; -\} -\end{alltt} \end{small} - -\subsection{Multiple Initializations} -Certain algorithms require more than one large integer. In these instances it is ideal to initialize all of the mp\_int -variables in an ``all or nothing'' fashion. That is, they are either all initialized successfully or they are all -not initialized. - -The mp\_init\_multi() function provides this functionality. - -\index{mp\_init\_multi} \index{mp\_clear\_multi} -\begin{alltt} -int mp_init_multi(mp_int *mp, ...); -\end{alltt} - -It accepts a \textbf{NULL} terminated list of pointers to mp\_int structures. It will attempt to initialize them all -at once. If the function returns MP\_OKAY then all of the mp\_int variables are ready to use, otherwise none of them -are available for use. A complementary mp\_clear\_multi() function allows multiple mp\_int variables to be free'd -from the heap at the same time. - -\begin{small} \begin{alltt} -int main(void) -\{ - mp_int num1, num2, num3; - int result; - - if ((result = mp_init_multi(&num1, - &num2, - &num3, NULL)) != MP\_OKAY) \{ - printf("Error initializing the numbers. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* use the numbers */ - - /* We're done with them. */ - mp_clear_multi(&num1, &num2, &num3, NULL); - - return EXIT_SUCCESS; -\} -\end{alltt} \end{small} - -\subsection{Other Initializers} -To initialized and make a copy of an mp\_int the mp\_init\_copy() function has been provided. - -\index{mp\_init\_copy} -\begin{alltt} -int mp_init_copy (mp_int * a, mp_int * b); -\end{alltt} - -This function will initialize $a$ and make it a copy of $b$ if all goes well. - -\begin{small} \begin{alltt} -int main(void) -\{ - mp_int num1, num2; - int result; - - /* initialize and do work on num1 ... */ - - /* We want a copy of num1 in num2 now */ - if ((result = mp_init_copy(&num2, &num1)) != MP_OKAY) \{ - printf("Error initializing the copy. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* now num2 is ready and contains a copy of num1 */ - - /* We're done with them. */ - mp_clear_multi(&num1, &num2, NULL); - - return EXIT_SUCCESS; -\} -\end{alltt} \end{small} - -Another less common initializer is mp\_init\_size() which allows the user to initialize an mp\_int with a given -default number of digits. By default, all initializers allocate \textbf{MP\_PREC} digits. This function lets -you override this behaviour. - -\index{mp\_init\_size} -\begin{alltt} -int mp_init_size (mp_int * a, int size); -\end{alltt} - -The $size$ parameter must be greater than zero. If the function succeeds the mp\_int $a$ will be initialized -to have $size$ digits (which are all initially zero). - -\begin{small} \begin{alltt} -int main(void) -\{ - mp_int number; - int result; - - /* we need a 60-digit number */ - if ((result = mp_init_size(&number, 60)) != MP_OKAY) \{ - printf("Error initializing the number. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* use the number */ - - return EXIT_SUCCESS; -\} -\end{alltt} \end{small} - -\section{Maintenance Functions} - -\subsection{Reducing Memory Usage} -When an mp\_int is in a state where it won't be changed again\footnote{A Diffie-Hellman modulus for instance.} excess -digits can be removed to return memory to the heap with the mp\_shrink() function. - -\index{mp\_shrink} -\begin{alltt} -int mp_shrink (mp_int * a); -\end{alltt} - -This will remove excess digits of the mp\_int $a$. If the operation fails the mp\_int should be intact without the -excess digits being removed. Note that you can use a shrunk mp\_int in further computations, however, such operations -will require heap operations which can be slow. It is not ideal to shrink mp\_int variables that you will further -modify in the system (unless you are seriously low on memory). - -\begin{small} \begin{alltt} -int main(void) -\{ - mp_int number; - int result; - - if ((result = mp_init(&number)) != MP_OKAY) \{ - printf("Error initializing the number. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* use the number [e.g. pre-computation] */ - - /* We're done with it for now. */ - if ((result = mp_shrink(&number)) != MP_OKAY) \{ - printf("Error shrinking the number. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* use it .... */ - - - /* we're done with it. */ - mp_clear(&number); - - return EXIT_SUCCESS; -\} -\end{alltt} \end{small} - -\subsection{Adding additional digits} - -Within the mp\_int structure are two parameters which control the limitations of the array of digits that represent -the integer the mp\_int is meant to equal. The \textit{used} parameter dictates how many digits are significant, that is, -contribute to the value of the mp\_int. The \textit{alloc} parameter dictates how many digits are currently available in -the array. If you need to perform an operation that requires more digits you will have to mp\_grow() the mp\_int to -your desired size. - -\index{mp\_grow} -\begin{alltt} -int mp_grow (mp_int * a, int size); -\end{alltt} - -This will grow the array of digits of $a$ to $size$. If the \textit{alloc} parameter is already bigger than -$size$ the function will not do anything. - -\begin{small} \begin{alltt} -int main(void) -\{ - mp_int number; - int result; - - if ((result = mp_init(&number)) != MP_OKAY) \{ - printf("Error initializing the number. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* use the number */ - - /* We need to add 20 digits to the number */ - if ((result = mp_grow(&number, number.alloc + 20)) != MP_OKAY) \{ - printf("Error growing the number. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - - /* use the number */ - - /* we're done with it. */ - mp_clear(&number); - - return EXIT_SUCCESS; -\} -\end{alltt} \end{small} - -\chapter{Basic Operations} -\section{Small Constants} -Setting mp\_ints to small constants is a relatively common operation. To accomodate these instances there are two -small constant assignment functions. The first function is used to set a single digit constant while the second sets -an ISO C style ``unsigned long'' constant. The reason for both functions is efficiency. Setting a single digit is quick but the -domain of a digit can change (it's always at least $0 \ldots 127$). - -\subsection{Single Digit} - -Setting a single digit can be accomplished with the following function. - -\index{mp\_set} -\begin{alltt} -void mp_set (mp_int * a, mp_digit b); -\end{alltt} - -This will zero the contents of $a$ and make it represent an integer equal to the value of $b$. Note that this -function has a return type of \textbf{void}. It cannot cause an error so it is safe to assume the function -succeeded. - -\begin{small} \begin{alltt} -int main(void) -\{ - mp_int number; - int result; - - if ((result = mp_init(&number)) != MP_OKAY) \{ - printf("Error initializing the number. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* set the number to 5 */ - mp_set(&number, 5); - - /* we're done with it. */ - mp_clear(&number); - - return EXIT_SUCCESS; -\} -\end{alltt} \end{small} - -\subsection{Long Constants} - -To set a constant that is the size of an ISO C ``unsigned long'' and larger than a single digit the following function -can be used. - -\index{mp\_set\_int} -\begin{alltt} -int mp_set_int (mp_int * a, unsigned long b); -\end{alltt} - -This will assign the value of the 32-bit variable $b$ to the mp\_int $a$. Unlike mp\_set() this function will always -accept a 32-bit input regardless of the size of a single digit. However, since the value may span several digits -this function can fail if it runs out of heap memory. - -To get the ``unsigned long'' copy of an mp\_int the following function can be used. - -\index{mp\_get\_int} -\begin{alltt} -unsigned long mp_get_int (mp_int * a); -\end{alltt} - -This will return the 32 least significant bits of the mp\_int $a$. - -\begin{small} \begin{alltt} -int main(void) -\{ - mp_int number; - int result; - - if ((result = mp_init(&number)) != MP_OKAY) \{ - printf("Error initializing the number. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* set the number to 654321 (note this is bigger than 127) */ - if ((result = mp_set_int(&number, 654321)) != MP_OKAY) \{ - printf("Error setting the value of the number. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - printf("number == \%lu", mp_get_int(&number)); - - /* we're done with it. */ - mp_clear(&number); - - return EXIT_SUCCESS; -\} -\end{alltt} \end{small} - -This should output the following if the program succeeds. - -\begin{alltt} -number == 654321 -\end{alltt} - -\subsection{Initialize and Setting Constants} -To both initialize and set small constants the following two functions are available. -\index{mp\_init\_set} \index{mp\_init\_set\_int} -\begin{alltt} -int mp_init_set (mp_int * a, mp_digit b); -int mp_init_set_int (mp_int * a, unsigned long b); -\end{alltt} - -Both functions work like the previous counterparts except they first mp\_init $a$ before setting the values. - -\begin{alltt} -int main(void) -\{ - mp_int number1, number2; - int result; - - /* initialize and set a single digit */ - if ((result = mp_init_set(&number1, 100)) != MP_OKAY) \{ - printf("Error setting number1: \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* initialize and set a long */ - if ((result = mp_init_set_int(&number2, 1023)) != MP_OKAY) \{ - printf("Error setting number2: \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* display */ - printf("Number1, Number2 == \%lu, \%lu", - mp_get_int(&number1), mp_get_int(&number2)); - - /* clear */ - mp_clear_multi(&number1, &number2, NULL); - - return EXIT_SUCCESS; -\} -\end{alltt} - -If this program succeeds it shall output. -\begin{alltt} -Number1, Number2 == 100, 1023 -\end{alltt} - -\section{Comparisons} - -Comparisons in LibTomMath are always performed in a ``left to right'' fashion. There are three possible return codes -for any comparison. - -\index{MP\_GT} \index{MP\_EQ} \index{MP\_LT} -\begin{figure}[here] -\begin{center} -\begin{tabular}{|c|c|} -\hline \textbf{Result Code} & \textbf{Meaning} \\ -\hline MP\_GT & $a > b$ \\ -\hline MP\_EQ & $a = b$ \\ -\hline MP\_LT & $a < b$ \\ -\hline -\end{tabular} -\end{center} -\caption{Comparison Codes for $a, b$} -\label{fig:CMP} -\end{figure} - -In figure \ref{fig:CMP} two integers $a$ and $b$ are being compared. In this case $a$ is said to be ``to the left'' of -$b$. - -\subsection{Unsigned comparison} - -An unsigned comparison considers only the digits themselves and not the associated \textit{sign} flag of the -mp\_int structures. This is analogous to an absolute comparison. The function mp\_cmp\_mag() will compare two -mp\_int variables based on their digits only. - -\index{mp\_cmp\_mag} -\begin{alltt} -int mp_cmp_mag(mp_int * a, mp_int * b); -\end{alltt} -This will compare $a$ to $b$ placing $a$ to the left of $b$. This function cannot fail and will return one of the -three compare codes listed in figure \ref{fig:CMP}. - -\begin{small} \begin{alltt} -int main(void) -\{ - mp_int number1, number2; - int result; - - if ((result = mp_init_multi(&number1, &number2, NULL)) != MP_OKAY) \{ - printf("Error initializing the numbers. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* set the number1 to 5 */ - mp_set(&number1, 5); - - /* set the number2 to -6 */ - mp_set(&number2, 6); - if ((result = mp_neg(&number2, &number2)) != MP_OKAY) \{ - printf("Error negating number2. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - switch(mp_cmp_mag(&number1, &number2)) \{ - case MP_GT: printf("|number1| > |number2|"); break; - case MP_EQ: printf("|number1| = |number2|"); break; - case MP_LT: printf("|number1| < |number2|"); break; - \} - - /* we're done with it. */ - mp_clear_multi(&number1, &number2, NULL); - - return EXIT_SUCCESS; -\} -\end{alltt} \end{small} - -If this program\footnote{This function uses the mp\_neg() function which is discussed in section \ref{sec:NEG}.} completes -successfully it should print the following. - -\begin{alltt} -|number1| < |number2| -\end{alltt} - -This is because $\vert -6 \vert = 6$ and obviously $5 < 6$. - -\subsection{Signed comparison} - -To compare two mp\_int variables based on their signed value the mp\_cmp() function is provided. - -\index{mp\_cmp} -\begin{alltt} -int mp_cmp(mp_int * a, mp_int * b); -\end{alltt} - -This will compare $a$ to the left of $b$. It will first compare the signs of the two mp\_int variables. If they -differ it will return immediately based on their signs. If the signs are equal then it will compare the digits -individually. This function will return one of the compare conditions codes listed in figure \ref{fig:CMP}. - -\begin{small} \begin{alltt} -int main(void) -\{ - mp_int number1, number2; - int result; - - if ((result = mp_init_multi(&number1, &number2, NULL)) != MP_OKAY) \{ - printf("Error initializing the numbers. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* set the number1 to 5 */ - mp_set(&number1, 5); - - /* set the number2 to -6 */ - mp_set(&number2, 6); - if ((result = mp_neg(&number2, &number2)) != MP_OKAY) \{ - printf("Error negating number2. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - switch(mp_cmp(&number1, &number2)) \{ - case MP_GT: printf("number1 > number2"); break; - case MP_EQ: printf("number1 = number2"); break; - case MP_LT: printf("number1 < number2"); break; - \} - - /* we're done with it. */ - mp_clear_multi(&number1, &number2, NULL); - - return EXIT_SUCCESS; -\} -\end{alltt} \end{small} - -If this program\footnote{This function uses the mp\_neg() function which is discussed in section \ref{sec:NEG}.} completes -successfully it should print the following. - -\begin{alltt} -number1 > number2 -\end{alltt} - -\subsection{Single Digit} - -To compare a single digit against an mp\_int the following function has been provided. - -\index{mp\_cmp\_d} -\begin{alltt} -int mp_cmp_d(mp_int * a, mp_digit b); -\end{alltt} - -This will compare $a$ to the left of $b$ using a signed comparison. Note that it will always treat $b$ as -positive. This function is rather handy when you have to compare against small values such as $1$ (which often -comes up in cryptography). The function cannot fail and will return one of the tree compare condition codes -listed in figure \ref{fig:CMP}. - - -\begin{small} \begin{alltt} -int main(void) -\{ - mp_int number; - int result; - - if ((result = mp_init(&number)) != MP_OKAY) \{ - printf("Error initializing the number. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* set the number to 5 */ - mp_set(&number, 5); - - switch(mp_cmp_d(&number, 7)) \{ - case MP_GT: printf("number > 7"); break; - case MP_EQ: printf("number = 7"); break; - case MP_LT: printf("number < 7"); break; - \} - - /* we're done with it. */ - mp_clear(&number); - - return EXIT_SUCCESS; -\} -\end{alltt} \end{small} - -If this program functions properly it will print out the following. - -\begin{alltt} -number < 7 -\end{alltt} - -\section{Logical Operations} - -Logical operations are operations that can be performed either with simple shifts or boolean operators such as -AND, XOR and OR directly. These operations are very quick. - -\subsection{Multiplication by two} - -Multiplications and divisions by any power of two can be performed with quick logical shifts either left or -right depending on the operation. - -When multiplying or dividing by two a special case routine can be used which are as follows. -\index{mp\_mul\_2} \index{mp\_div\_2} -\begin{alltt} -int mp_mul_2(mp_int * a, mp_int * b); -int mp_div_2(mp_int * a, mp_int * b); -\end{alltt} - -The former will assign twice $a$ to $b$ while the latter will assign half $a$ to $b$. These functions are fast -since the shift counts and maskes are hardcoded into the routines. - -\begin{small} \begin{alltt} -int main(void) -\{ - mp_int number; - int result; - - if ((result = mp_init(&number)) != MP_OKAY) \{ - printf("Error initializing the number. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* set the number to 5 */ - mp_set(&number, 5); - - /* multiply by two */ - if ((result = mp\_mul\_2(&number, &number)) != MP_OKAY) \{ - printf("Error multiplying the number. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - switch(mp_cmp_d(&number, 7)) \{ - case MP_GT: printf("2*number > 7"); break; - case MP_EQ: printf("2*number = 7"); break; - case MP_LT: printf("2*number < 7"); break; - \} - - /* now divide by two */ - if ((result = mp\_div\_2(&number, &number)) != MP_OKAY) \{ - printf("Error dividing the number. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - switch(mp_cmp_d(&number, 7)) \{ - case MP_GT: printf("2*number/2 > 7"); break; - case MP_EQ: printf("2*number/2 = 7"); break; - case MP_LT: printf("2*number/2 < 7"); break; - \} - - /* we're done with it. */ - mp_clear(&number); - - return EXIT_SUCCESS; -\} -\end{alltt} \end{small} - -If this program is successful it will print out the following text. - -\begin{alltt} -2*number > 7 -2*number/2 < 7 -\end{alltt} - -Since $10 > 7$ and $5 < 7$. To multiply by a power of two the following function can be used. - -\index{mp\_mul\_2d} -\begin{alltt} -int mp_mul_2d(mp_int * a, int b, mp_int * c); -\end{alltt} - -This will multiply $a$ by $2^b$ and store the result in ``c''. If the value of $b$ is less than or equal to -zero the function will copy $a$ to ``c'' without performing any further actions. - -To divide by a power of two use the following. - -\index{mp\_div\_2d} -\begin{alltt} -int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d); -\end{alltt} -Which will divide $a$ by $2^b$, store the quotient in ``c'' and the remainder in ``d'. If $b \le 0$ then the -function simply copies $a$ over to ``c'' and zeroes $d$. The variable $d$ may be passed as a \textbf{NULL} -value to signal that the remainder is not desired. - -\subsection{Polynomial Basis Operations} - -Strictly speaking the organization of the integers within the mp\_int structures is what is known as a -``polynomial basis''. This simply means a field element is stored by divisions of a radix. For example, if -$f(x) = \sum_{i=0}^{k} y_ix^k$ for any vector $\vec y$ then the array of digits in $\vec y$ are said to be -the polynomial basis representation of $z$ if $f(\beta) = z$ for a given radix $\beta$. - -To multiply by the polynomial $g(x) = x$ all you have todo is shift the digits of the basis left one place. The -following function provides this operation. - -\index{mp\_lshd} -\begin{alltt} -int mp_lshd (mp_int * a, int b); -\end{alltt} - -This will multiply $a$ in place by $x^b$ which is equivalent to shifting the digits left $b$ places and inserting zeroes -in the least significant digits. Similarly to divide by a power of $x$ the following function is provided. - -\index{mp\_rshd} -\begin{alltt} -void mp_rshd (mp_int * a, int b) -\end{alltt} -This will divide $a$ in place by $x^b$ and discard the remainder. This function cannot fail as it performs the operations -in place and no new digits are required to complete it. - -\subsection{AND, OR and XOR Operations} - -While AND, OR and XOR operations are not typical ``bignum functions'' they can be useful in several instances. The -three functions are prototyped as follows. - -\index{mp\_or} \index{mp\_and} \index{mp\_xor} -\begin{alltt} -int mp_or (mp_int * a, mp_int * b, mp_int * c); -int mp_and (mp_int * a, mp_int * b, mp_int * c); -int mp_xor (mp_int * a, mp_int * b, mp_int * c); -\end{alltt} - -Which compute $c = a \odot b$ where $\odot$ is one of OR, AND or XOR. - -\section{Addition and Subtraction} - -To compute an addition or subtraction the following two functions can be used. - -\index{mp\_add} \index{mp\_sub} -\begin{alltt} -int mp_add (mp_int * a, mp_int * b, mp_int * c); -int mp_sub (mp_int * a, mp_int * b, mp_int * c) -\end{alltt} - -Which perform $c = a \odot b$ where $\odot$ is one of signed addition or subtraction. The operations are fully sign -aware. - -\section{Sign Manipulation} -\subsection{Negation} -\label{sec:NEG} -Simple integer negation can be performed with the following. - -\index{mp\_neg} -\begin{alltt} -int mp_neg (mp_int * a, mp_int * b); -\end{alltt} - -Which assigns $-a$ to $b$. - -\subsection{Absolute} -Simple integer absolutes can be performed with the following. - -\index{mp\_neg} -\begin{alltt} -int mp_abs (mp_int * a, mp_int * b); -\end{alltt} - -Which assigns $\vert a \vert$ to $b$. - -\section{Integer Division and Remainder} -To perform a complete and general integer division with remainder use the following function. - -\index{mp\_div} -\begin{alltt} -int mp_div (mp_int * a, mp_int * b, mp_int * c, mp_int * d); -\end{alltt} - -This divides $a$ by $b$ and stores the quotient in $c$ and $d$. The signed quotient is computed such that -$bc + d = a$. Note that either of $c$ or $d$ can be set to \textbf{NULL} if their value is not required. If -$b$ is zero the function returns \textbf{MP\_VAL}. - - -\chapter{Multiplication and Squaring} -\section{Multiplication} -A full signed integer multiplication can be performed with the following. -\index{mp\_mul} -\begin{alltt} -int mp_mul (mp_int * a, mp_int * b, mp_int * c); -\end{alltt} -Which assigns the full signed product $ab$ to $c$. This function actually breaks into one of four cases which are -specific multiplication routines optimized for given parameters. First there are the Toom-Cook multiplications which -should only be used with very large inputs. This is followed by the Karatsuba multiplications which are for moderate -sized inputs. Then followed by the Comba and baseline multipliers. - -Fortunately for the developer you don't really need to know this unless you really want to fine tune the system. mp\_mul() -will determine on its own\footnote{Some tweaking may be required.} what routine to use automatically when it is called. - -\begin{alltt} -int main(void) -\{ - mp_int number1, number2; - int result; - - /* Initialize the numbers */ - if ((result = mp_init_multi(&number1, - &number2, NULL)) != MP_OKAY) \{ - printf("Error initializing the numbers. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* set the terms */ - if ((result = mp_set_int(&number, 257)) != MP_OKAY) \{ - printf("Error setting number1. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - if ((result = mp_set_int(&number2, 1023)) != MP_OKAY) \{ - printf("Error setting number2. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* multiply them */ - if ((result = mp_mul(&number1, &number2, - &number1)) != MP_OKAY) \{ - printf("Error multiplying terms. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* display */ - printf("number1 * number2 == \%lu", mp_get_int(&number1)); - - /* free terms and return */ - mp_clear_multi(&number1, &number2, NULL); - - return EXIT_SUCCESS; -\} -\end{alltt} - -If this program succeeds it shall output the following. - -\begin{alltt} -number1 * number2 == 262911 -\end{alltt} - -\section{Squaring} -Since squaring can be performed faster than multiplication it is performed it's own function instead of just using -mp\_mul(). - -\index{mp\_sqr} -\begin{alltt} -int mp_sqr (mp_int * a, mp_int * b); -\end{alltt} - -Will square $a$ and store it in $b$. Like the case of multiplication there are four different squaring -algorithms all which can be called from mp\_sqr(). It is ideal to use mp\_sqr over mp\_mul when squaring terms because -of the speed difference. - -\section{Tuning Polynomial Basis Routines} - -Both of the Toom-Cook and Karatsuba multiplication algorithms are faster than the traditional $O(n^2)$ approach that -the Comba and baseline algorithms use. At $O(n^{1.464973})$ and $O(n^{1.584962})$ running times respectively they require -considerably less work. For example, a 10000-digit multiplication would take roughly 724,000 single precision -multiplications with Toom-Cook or 100,000,000 single precision multiplications with the standard Comba (a factor -of 138). - -So why not always use Karatsuba or Toom-Cook? The simple answer is that they have so much overhead that they're not -actually faster than Comba until you hit distinct ``cutoff'' points. For Karatsuba with the default configuration, -GCC 3.3.1 and an Athlon XP processor the cutoff point is roughly 110 digits (about 70 for the Intel P4). That is, at -110 digits Karatsuba and Comba multiplications just about break even and for 110+ digits Karatsuba is faster. - -Toom-Cook has incredible overhead and is probably only useful for very large inputs. So far no known cutoff points -exist and for the most part I just set the cutoff points very high to make sure they're not called. - -A demo program in the ``etc/'' directory of the project called ``tune.c'' can be used to find the cutoff points. This -can be built with GCC as follows - -\begin{alltt} -make XXX -\end{alltt} -Where ``XXX'' is one of the following entries from the table \ref{fig:tuning}. - -\begin{figure}[here] -\begin{center} -\begin{small} -\begin{tabular}{|l|l|} -\hline \textbf{Value of XXX} & \textbf{Meaning} \\ -\hline tune & Builds portable tuning application \\ -\hline tune86 & Builds x86 (pentium and up) program for COFF \\ -\hline tune86c & Builds x86 program for Cygwin \\ -\hline tune86l & Builds x86 program for Linux (ELF format) \\ -\hline -\end{tabular} -\end{small} -\end{center} -\caption{Build Names for Tuning Programs} -\label{fig:tuning} -\end{figure} - -When the program is running it will output a series of measurements for different cutoff points. It will first find -good Karatsuba squaring and multiplication points. Then it proceeds to find Toom-Cook points. Note that the Toom-Cook -tuning takes a very long time as the cutoff points are likely to be very high. - -\chapter{Modular Reduction} - -Modular reduction is process of taking the remainder of one quantity divided by another. Expressed -as (\ref{eqn:mod}) the modular reduction is equivalent to the remainder of $b$ divided by $c$. - -\begin{equation} -a \equiv b \mbox{ (mod }c\mbox{)} -\label{eqn:mod} -\end{equation} - -Of particular interest to cryptography are reductions where $b$ is limited to the range $0 \le b < c^2$ since particularly -fast reduction algorithms can be written for the limited range. - -Note that one of the four optimized reduction algorithms are automatically chosen in the modular exponentiation -algorithm mp\_exptmod when an appropriate modulus is detected. - -\section{Straight Division} -In order to effect an arbitrary modular reduction the following algorithm is provided. - -\index{mp\_mod} -\begin{alltt} -int mp_mod(mp_int *a, mp_int *b, mp_int *c); -\end{alltt} - -This reduces $a$ modulo $b$ and stores the result in $c$. The sign of $c$ shall agree with the sign -of $b$. This algorithm accepts an input $a$ of any range and is not limited by $0 \le a < b^2$. - -\section{Barrett Reduction} - -Barrett reduction is a generic optimized reduction algorithm that requires pre--computation to achieve -a decent speedup over straight division. First a $\mu$ value must be precomputed with the following function. - -\index{mp\_reduce\_setup} -\begin{alltt} -int mp_reduce_setup(mp_int *a, mp_int *b); -\end{alltt} - -Given a modulus in $b$ this produces the required $\mu$ value in $a$. For any given modulus this only has to -be computed once. Modular reduction can now be performed with the following. - -\index{mp\_reduce} -\begin{alltt} -int mp_reduce(mp_int *a, mp_int *b, mp_int *c); -\end{alltt} - -This will reduce $a$ in place modulo $b$ with the precomputed $\mu$ value in $c$. $a$ must be in the range -$0 \le a < b^2$. - -\begin{alltt} -int main(void) -\{ - mp_int a, b, c, mu; - int result; - - /* initialize a,b to desired values, mp_init mu, - * c and set c to 1...we want to compute a^3 mod b - */ - - /* get mu value */ - if ((result = mp_reduce_setup(&mu, b)) != MP_OKAY) \{ - printf("Error getting mu. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* square a to get c = a^2 */ - if ((result = mp_sqr(&a, &c)) != MP_OKAY) \{ - printf("Error squaring. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* now reduce `c' modulo b */ - if ((result = mp_reduce(&c, &b, &mu)) != MP_OKAY) \{ - printf("Error reducing. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* multiply a to get c = a^3 */ - if ((result = mp_mul(&a, &c, &c)) != MP_OKAY) \{ - printf("Error reducing. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* now reduce `c' modulo b */ - if ((result = mp_reduce(&c, &b, &mu)) != MP_OKAY) \{ - printf("Error reducing. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* c now equals a^3 mod b */ - - return EXIT_SUCCESS; -\} -\end{alltt} - -This program will calculate $a^3 \mbox{ mod }b$ if all the functions succeed. - -\section{Montgomery Reduction} - -Montgomery is a specialized reduction algorithm for any odd moduli. Like Barrett reduction a pre--computation -step is required. This is accomplished with the following. - -\index{mp\_montgomery\_setup} -\begin{alltt} -int mp_montgomery_setup(mp_int *a, mp_digit *mp); -\end{alltt} - -For the given odd moduli $a$ the precomputation value is placed in $mp$. The reduction is computed with the -following. - -\index{mp\_montgomery\_reduce} -\begin{alltt} -int mp_montgomery_reduce(mp_int *a, mp_int *m, mp_digit mp); -\end{alltt} -This reduces $a$ in place modulo $m$ with the pre--computed value $mp$. $a$ must be in the range -$0 \le a < b^2$. - -Montgomery reduction is faster than Barrett reduction for moduli smaller than the ``comba'' limit. With the default -setup for instance, the limit is $127$ digits ($3556$--bits). Note that this function is not limited to -$127$ digits just that it falls back to a baseline algorithm after that point. - -An important observation is that this reduction does not return $a \mbox{ mod }m$ but $aR^{-1} \mbox{ mod }m$ -where $R = \beta^n$, $n$ is the n number of digits in $m$ and $\beta$ is radix used (default is $2^{28}$). - -To quickly calculate $R$ the following function was provided. - -\index{mp\_montgomery\_calc\_normalization} -\begin{alltt} -int mp_montgomery_calc_normalization(mp_int *a, mp_int *b); -\end{alltt} -Which calculates $a = R$ for the odd moduli $b$ without using multiplication or division. - -The normal modus operandi for Montgomery reductions is to normalize the integers before entering the system. For -example, to calculate $a^3 \mbox { mod }b$ using Montgomery reduction the value of $a$ can be normalized by -multiplying it by $R$. Consider the following code snippet. - -\begin{alltt} -int main(void) -\{ - mp_int a, b, c, R; - mp_digit mp; - int result; - - /* initialize a,b to desired values, - * mp_init R, c and set c to 1.... - */ - - /* get normalization */ - if ((result = mp_montgomery_calc_normalization(&R, b)) != MP_OKAY) \{ - printf("Error getting norm. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* get mp value */ - if ((result = mp_montgomery_setup(&c, &mp)) != MP_OKAY) \{ - printf("Error setting up montgomery. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* normalize `a' so now a is equal to aR */ - if ((result = mp_mulmod(&a, &R, &b, &a)) != MP_OKAY) \{ - printf("Error computing aR. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* square a to get c = a^2R^2 */ - if ((result = mp_sqr(&a, &c)) != MP_OKAY) \{ - printf("Error squaring. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* now reduce `c' back down to c = a^2R^2 * R^-1 == a^2R */ - if ((result = mp_montgomery_reduce(&c, &b, mp)) != MP_OKAY) \{ - printf("Error reducing. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* multiply a to get c = a^3R^2 */ - if ((result = mp_mul(&a, &c, &c)) != MP_OKAY) \{ - printf("Error reducing. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* now reduce `c' back down to c = a^3R^2 * R^-1 == a^3R */ - if ((result = mp_montgomery_reduce(&c, &b, mp)) != MP_OKAY) \{ - printf("Error reducing. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* now reduce (again) `c' back down to c = a^3R * R^-1 == a^3 */ - if ((result = mp_montgomery_reduce(&c, &b, mp)) != MP_OKAY) \{ - printf("Error reducing. \%s", - mp_error_to_string(result)); - return EXIT_FAILURE; - \} - - /* c now equals a^3 mod b */ - - return EXIT_SUCCESS; -\} -\end{alltt} - -This particular example does not look too efficient but it demonstrates the point of the algorithm. By -normalizing the inputs the reduced results are always of the form $aR$ for some variable $a$. This allows -a single final reduction to correct for the normalization and the fast reduction used within the algorithm. - -For more details consider examining the file \textit{bn\_mp\_exptmod\_fast.c}. - -\section{Restricted Dimminished Radix} - -``Dimminished Radix'' reduction refers to reduction with respect to moduli that are ameniable to simple -digit shifting and small multiplications. In this case the ``restricted'' variant refers to moduli of the -form $\beta^k - p$ for some $k \ge 0$ and $0 < p < \beta$ where $\beta$ is the radix (default to $2^{28}$). - -As in the case of Montgomery reduction there is a pre--computation phase required for a given modulus. - -\index{mp\_dr\_setup} -\begin{alltt} -void mp_dr_setup(mp_int *a, mp_digit *d); -\end{alltt} - -This computes the value required for the modulus $a$ and stores it in $d$. This function cannot fail -and does not return any error codes. After the pre--computation a reduction can be performed with the -following. - -\index{mp\_dr\_reduce} -\begin{alltt} -int mp_dr_reduce(mp_int *a, mp_int *b, mp_digit mp); -\end{alltt} - -This reduces $a$ in place modulo $b$ with the pre--computed value $mp$. $b$ must be of a restricted -dimminished radix form and $a$ must be in the range $0 \le a < b^2$. Dimminished radix reductions are -much faster than both Barrett and Montgomery reductions as they have a much lower asymtotic running time. - -Since the moduli are restricted this algorithm is not particularly useful for something like Rabin, RSA or -BBS cryptographic purposes. This reduction algorithm is useful for Diffie-Hellman and ECC where fixed -primes are acceptable. - -Note that unlike Montgomery reduction there is no normalization process. The result of this function is -equal to the correct residue. - -\section{Unrestricted Dimminshed Radix} - -Unrestricted reductions work much like the restricted counterparts except in this case the moduli is of the -form $2^k - p$ for $0 < p < \beta$. In this sense the unrestricted reductions are more flexible as they -can be applied to a wider range of numbers. - -\index{mp\_reduce\_2k\_setup} -\begin{alltt} -int mp_reduce_2k_setup(mp_int *a, mp_digit *d); -\end{alltt} - -This will compute the required $d$ value for the given moduli $a$. - -\index{mp\_reduce\_2k} -\begin{alltt} -int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d); -\end{alltt} - -This will reduce $a$ in place modulo $n$ with the pre--computed value $d$. From my experience this routine is -slower than mp\_dr\_reduce but faster for most moduli sizes than the Montgomery reduction. - -\chapter{Exponentiation} -\section{Single Digit Exponentiation} -\index{mp\_expt\_d} -\begin{alltt} -int mp_expt_d (mp_int * a, mp_digit b, mp_int * c) -\end{alltt} -This computes $c = a^b$ using a simple binary left-to-right algorithm. It is faster than repeated multiplications by -$a$ for all values of $b$ greater than three. - -\section{Modular Exponentiation} -\index{mp\_exptmod} -\begin{alltt} -int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) -\end{alltt} -This computes $Y \equiv G^X \mbox{ (mod }P\mbox{)}$ using a variable width sliding window algorithm. This function -will automatically detect the fastest modular reduction technique to use during the operation. For negative values of -$X$ the operation is performed as $Y \equiv (G^{-1} \mbox{ mod }P)^{\vert X \vert} \mbox{ (mod }P\mbox{)}$ provided that -$gcd(G, P) = 1$. - -This function is actually a shell around the two internal exponentiation functions. This routine will automatically -detect when Barrett, Montgomery, Restricted and Unrestricted Dimminished Radix based exponentiation can be used. Generally -moduli of the a ``restricted dimminished radix'' form lead to the fastest modular exponentiations. Followed by Montgomery -and the other two algorithms. - -\section{Root Finding} -\index{mp\_n\_root} -\begin{alltt} -int mp_n_root (mp_int * a, mp_digit b, mp_int * c) -\end{alltt} -This computes $c = a^{1/b}$ such that $c^b \le a$ and $(c+1)^b > a$. The implementation of this function is not -ideal for values of $b$ greater than three. It will work but become very slow. So unless you are working with very small -numbers (less than 1000 bits) I'd avoid $b > 3$ situations. Will return a positive root only for even roots and return -a root with the sign of the input for odd roots. For example, performing $4^{1/2}$ will return $2$ whereas $(-8)^{1/3}$ -will return $-2$. - -This algorithm uses the ``Newton Approximation'' method and will converge on the correct root fairly quickly. Since -the algorithm requires raising $a$ to the power of $b$ it is not ideal to attempt to find roots for large -values of $b$. If particularly large roots are required then a factor method could be used instead. For example, -$a^{1/16}$ is equivalent to $\left (a^{1/4} \right)^{1/4}$ or simply -$\left ( \left ( \left ( a^{1/2} \right )^{1/2} \right )^{1/2} \right )^{1/2}$ - -\chapter{Prime Numbers} -\section{Trial Division} -\index{mp\_prime\_is\_divisible} -\begin{alltt} -int mp_prime_is_divisible (mp_int * a, int *result) -\end{alltt} -This will attempt to evenly divide $a$ by a list of primes\footnote{Default is the first 256 primes.} and store the -outcome in ``result''. That is if $result = 0$ then $a$ is not divisible by the primes, otherwise it is. Note that -if the function does not return \textbf{MP\_OKAY} the value in ``result'' should be considered undefined\footnote{Currently -the default is to set it to zero first.}. - -\section{Fermat Test} -\index{mp\_prime\_fermat} -\begin{alltt} -int mp_prime_fermat (mp_int * a, mp_int * b, int *result) -\end{alltt} -Performs a Fermat primality test to the base $b$. That is it computes $b^a \mbox{ mod }a$ and tests whether the value is -equal to $b$ or not. If the values are equal then $a$ is probably prime and $result$ is set to one. Otherwise $result$ -is set to zero. - -\section{Miller-Rabin Test} -\index{mp\_prime\_miller\_rabin} -\begin{alltt} -int mp_prime_miller_rabin (mp_int * a, mp_int * b, int *result) -\end{alltt} -Performs a Miller-Rabin test to the base $b$ of $a$. This test is much stronger than the Fermat test and is very hard to -fool (besides with Carmichael numbers). If $a$ passes the test (therefore is probably prime) $result$ is set to one. -Otherwise $result$ is set to zero. - -Note that is suggested that you use the Miller-Rabin test instead of the Fermat test since all of the failures of -Miller-Rabin are a subset of the failures of the Fermat test. - -\subsection{Required Number of Tests} -Generally to ensure a number is very likely to be prime you have to perform the Miller-Rabin with at least a half-dozen -or so unique bases. However, it has been proven that the probability of failure goes down as the size of the input goes up. -This is why a simple function has been provided to help out. - -\index{mp\_prime\_rabin\_miller\_trials} -\begin{alltt} -int mp_prime_rabin_miller_trials(int size) -\end{alltt} -This returns the number of trials required for a $2^{-96}$ (or lower) probability of failure for a given ``size'' expressed -in bits. This comes in handy specially since larger numbers are slower to test. For example, a 512-bit number would -require ten tests whereas a 1024-bit number would only require four tests. - -You should always still perform a trial division before a Miller-Rabin test though. - -\section{Primality Testing} -\index{mp\_prime\_is\_prime} -\begin{alltt} -int mp_prime_is_prime (mp_int * a, int t, int *result) -\end{alltt} -This will perform a trial division followed by $t$ rounds of Miller-Rabin tests on $a$ and store the result in $result$. -If $a$ passes all of the tests $result$ is set to one, otherwise it is set to zero. Note that $t$ is bounded by -$1 \le t < PRIME\_SIZE$ where $PRIME\_SIZE$ is the number of primes in the prime number table (by default this is $256$). - -\section{Next Prime} -\index{mp\_prime\_next\_prime} -\begin{alltt} -int mp_prime_next_prime(mp_int *a, int t, int bbs_style) -\end{alltt} -This finds the next prime after $a$ that passes mp\_prime\_is\_prime() with $t$ tests. Set $bbs\_style$ to one if you -want only the next prime congruent to $3 \mbox{ mod } 4$, otherwise set it to zero to find any next prime. - -\section{Random Primes} -\index{mp\_prime\_random} -\begin{alltt} -int mp_prime_random(mp_int *a, int t, int size, int bbs, - ltm_prime_callback cb, void *dat) -\end{alltt} -This will find a prime greater than $256^{size}$ which can be ``bbs\_style'' or not depending on $bbs$ and must pass -$t$ rounds of tests. The ``ltm\_prime\_callback'' is a typedef for - -\begin{alltt} -typedef int ltm_prime_callback(unsigned char *dst, int len, void *dat); -\end{alltt} - -Which is a function that must read $len$ bytes (and return the amount stored) into $dst$. The $dat$ variable is simply -copied from the original input. It can be used to pass RNG context data to the callback. The function -mp\_prime\_random() is more suitable for generating primes which must be secret (as in the case of RSA) since there -is no skew on the least significant bits. - -\textit{Note:} As of v0.30 of the LibTomMath library this function has been deprecated. It is still available -but users are encouraged to use the new mp\_prime\_random\_ex() function instead. - -\subsection{Extended Generation} -\index{mp\_prime\_random\_ex} -\begin{alltt} -int mp_prime_random_ex(mp_int *a, int t, - int size, int flags, - ltm_prime_callback cb, void *dat); -\end{alltt} -This will generate a prime in $a$ using $t$ tests of the primality testing algorithms. The variable $size$ -specifies the bit length of the prime desired. The variable $flags$ specifies one of several options available -(see fig. \ref{fig:primeopts}) which can be OR'ed together. The callback parameters are used as in -mp\_prime\_random(). - -\begin{figure}[here] -\begin{center} -\begin{small} -\begin{tabular}{|r|l|} -\hline \textbf{Flag} & \textbf{Meaning} \\ -\hline LTM\_PRIME\_BBS & Make the prime congruent to $3$ modulo $4$ \\ -\hline LTM\_PRIME\_SAFE & Make a prime $p$ such that $(p - 1)/2$ is also prime. \\ - & This option implies LTM\_PRIME\_BBS as well. \\ -\hline LTM\_PRIME\_2MSB\_OFF & Makes sure that the bit adjacent to the most significant bit \\ - & Is forced to zero. \\ -\hline LTM\_PRIME\_2MSB\_ON & Makes sure that the bit adjacent to the most significant bit \\ - & Is forced to one. \\ -\hline -\end{tabular} -\end{small} -\end{center} -\caption{Primality Generation Options} -\label{fig:primeopts} -\end{figure} - -\chapter{Input and Output} -\section{ASCII Conversions} -\subsection{To ASCII} -\index{mp\_toradix} -\begin{alltt} -int mp_toradix (mp_int * a, char *str, int radix); -\end{alltt} -This still store $a$ in ``str'' as a base-``radix'' string of ASCII chars. This function appends a NUL character -to terminate the string. Valid values of ``radix'' line in the range $[2, 64]$. To determine the size (exact) required -by the conversion before storing any data use the following function. - -\index{mp\_radix\_size} -\begin{alltt} -int mp_radix_size (mp_int * a, int radix, int *size) -\end{alltt} -This stores in ``size'' the number of characters (including space for the NUL terminator) required. Upon error this -function returns an error code and ``size'' will be zero. - -\subsection{From ASCII} -\index{mp\_read\_radix} -\begin{alltt} -int mp_read_radix (mp_int * a, char *str, int radix); -\end{alltt} -This will read the base-``radix'' NUL terminated string from ``str'' into $a$. It will stop reading when it reads a -character it does not recognize (which happens to include th NUL char... imagine that...). A single leading $-$ sign -can be used to denote a negative number. - -\section{Binary Conversions} - -Converting an mp\_int to and from binary is another keen idea. - -\index{mp\_unsigned\_bin\_size} -\begin{alltt} -int mp_unsigned_bin_size(mp_int *a); -\end{alltt} - -This will return the number of bytes (octets) required to store the unsigned copy of the integer $a$. - -\index{mp\_to\_unsigned\_bin} -\begin{alltt} -int mp_to_unsigned_bin(mp_int *a, unsigned char *b); -\end{alltt} -This will store $a$ into the buffer $b$ in big--endian format. Fortunately this is exactly what DER (or is it ASN?) -requires. It does not store the sign of the integer. - -\index{mp\_read\_unsigned\_bin} -\begin{alltt} -int mp_read_unsigned_bin(mp_int *a, unsigned char *b, int c); -\end{alltt} -This will read in an unsigned big--endian array of bytes (octets) from $b$ of length $c$ into $a$. The resulting -integer $a$ will always be positive. - -For those who acknowledge the existence of negative numbers (heretic!) there are ``signed'' versions of the -previous functions. - -\begin{alltt} -int mp_signed_bin_size(mp_int *a); -int mp_read_signed_bin(mp_int *a, unsigned char *b, int c); -int mp_to_signed_bin(mp_int *a, unsigned char *b); -\end{alltt} -They operate essentially the same as the unsigned copies except they prefix the data with zero or non--zero -byte depending on the sign. If the sign is zpos (e.g. not negative) the prefix is zero, otherwise the prefix -is non--zero. - -\chapter{Algebraic Functions} -\section{Extended Euclidean Algorithm} -\index{mp\_exteuclid} -\begin{alltt} -int mp_exteuclid(mp_int *a, mp_int *b, - mp_int *U1, mp_int *U2, mp_int *U3); -\end{alltt} - -This finds the triple U1/U2/U3 using the Extended Euclidean algorithm such that the following equation holds. - -\begin{equation} -a \cdot U1 + b \cdot U2 = U3 -\end{equation} - -Any of the U1/U2/U3 paramters can be set to \textbf{NULL} if they are not desired. - -\section{Greatest Common Divisor} -\index{mp\_gcd} -\begin{alltt} -int mp_gcd (mp_int * a, mp_int * b, mp_int * c) -\end{alltt} -This will compute the greatest common divisor of $a$ and $b$ and store it in $c$. - -\section{Least Common Multiple} -\index{mp\_lcm} -\begin{alltt} -int mp_lcm (mp_int * a, mp_int * b, mp_int * c) -\end{alltt} -This will compute the least common multiple of $a$ and $b$ and store it in $c$. - -\section{Jacobi Symbol} -\index{mp\_jacobi} -\begin{alltt} -int mp_jacobi (mp_int * a, mp_int * p, int *c) -\end{alltt} -This will compute the Jacobi symbol for $a$ with respect to $p$. If $p$ is prime this essentially computes the Legendre -symbol. The result is stored in $c$ and can take on one of three values $\lbrace -1, 0, 1 \rbrace$. If $p$ is prime -then the result will be $-1$ when $a$ is not a quadratic residue modulo $p$. The result will be $0$ if $a$ divides $p$ -and the result will be $1$ if $a$ is a quadratic residue modulo $p$. - -\section{Modular Inverse} -\index{mp\_invmod} -\begin{alltt} -int mp_invmod (mp_int * a, mp_int * b, mp_int * c) -\end{alltt} -Computes the multiplicative inverse of $a$ modulo $b$ and stores the result in $c$ such that $ac \equiv 1 \mbox{ (mod }b\mbox{)}$. - -\section{Single Digit Functions} - -For those using small numbers (\textit{snicker snicker}) there are several ``helper'' functions - -\index{mp\_add\_d} \index{mp\_sub\_d} \index{mp\_mul\_d} \index{mp\_div\_d} \index{mp\_mod\_d} -\begin{alltt} -int mp_add_d(mp_int *a, mp_digit b, mp_int *c); -int mp_sub_d(mp_int *a, mp_digit b, mp_int *c); -int mp_mul_d(mp_int *a, mp_digit b, mp_int *c); -int mp_div_d(mp_int *a, mp_digit b, mp_int *c, mp_digit *d); -int mp_mod_d(mp_int *a, mp_digit b, mp_digit *c); -\end{alltt} - -These work like the full mp\_int capable variants except the second parameter $b$ is a mp\_digit. These -functions fairly handy if you have to work with relatively small numbers since you will not have to allocate -an entire mp\_int to store a number like $1$ or $2$. - -\input{bn.ind} - -\end{document} diff --git a/external/libtommath-0.42.0/bn_error.c b/external/libtommath-0.42.0/bn_error.c deleted file mode 100755 index 250057b..0000000 --- a/external/libtommath-0.42.0/bn_error.c +++ /dev/null @@ -1,47 +0,0 @@ -#include -#ifdef BN_ERROR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -static const struct { - int code; - char *msg; -} msgs[] = { - { MP_OKAY, "Successful" }, - { MP_MEM, "Out of heap" }, - { MP_VAL, "Value out of range" } -}; - -/* return a char * string for a given code */ -char *mp_error_to_string(int code) -{ - int x; - - /* scan the lookup table for the given message */ - for (x = 0; x < (int)(sizeof(msgs) / sizeof(msgs[0])); x++) { - if (msgs[x].code == code) { - return msgs[x].msg; - } - } - - /* generic reply for invalid code */ - return "Invalid error code"; -} - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_fast_mp_invmod.c b/external/libtommath-0.42.0/bn_fast_mp_invmod.c deleted file mode 100755 index 948a134..0000000 --- a/external/libtommath-0.42.0/bn_fast_mp_invmod.c +++ /dev/null @@ -1,148 +0,0 @@ -#include -#ifdef BN_FAST_MP_INVMOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* computes the modular inverse via binary extended euclidean algorithm, - * that is c = 1/a mod b - * - * Based on slow invmod except this is optimized for the case where b is - * odd as per HAC Note 14.64 on pp. 610 - */ -int fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c) -{ - mp_int x, y, u, v, B, D; - int res, neg; - - /* 2. [modified] b must be odd */ - if (mp_iseven (b) == 1) { - return MP_VAL; - } - - /* init all our temps */ - if ((res = mp_init_multi(&x, &y, &u, &v, &B, &D, NULL)) != MP_OKAY) { - return res; - } - - /* x == modulus, y == value to invert */ - if ((res = mp_copy (b, &x)) != MP_OKAY) { - goto LBL_ERR; - } - - /* we need y = |a| */ - if ((res = mp_mod (a, b, &y)) != MP_OKAY) { - goto LBL_ERR; - } - - /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */ - if ((res = mp_copy (&x, &u)) != MP_OKAY) { - goto LBL_ERR; - } - if ((res = mp_copy (&y, &v)) != MP_OKAY) { - goto LBL_ERR; - } - mp_set (&D, 1); - -top: - /* 4. while u is even do */ - while (mp_iseven (&u) == 1) { - /* 4.1 u = u/2 */ - if ((res = mp_div_2 (&u, &u)) != MP_OKAY) { - goto LBL_ERR; - } - /* 4.2 if B is odd then */ - if (mp_isodd (&B) == 1) { - if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) { - goto LBL_ERR; - } - } - /* B = B/2 */ - if ((res = mp_div_2 (&B, &B)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* 5. while v is even do */ - while (mp_iseven (&v) == 1) { - /* 5.1 v = v/2 */ - if ((res = mp_div_2 (&v, &v)) != MP_OKAY) { - goto LBL_ERR; - } - /* 5.2 if D is odd then */ - if (mp_isodd (&D) == 1) { - /* D = (D-x)/2 */ - if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) { - goto LBL_ERR; - } - } - /* D = D/2 */ - if ((res = mp_div_2 (&D, &D)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* 6. if u >= v then */ - if (mp_cmp (&u, &v) != MP_LT) { - /* u = u - v, B = B - D */ - if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) { - goto LBL_ERR; - } - - if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) { - goto LBL_ERR; - } - } else { - /* v - v - u, D = D - B */ - if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) { - goto LBL_ERR; - } - - if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* if not zero goto step 4 */ - if (mp_iszero (&u) == 0) { - goto top; - } - - /* now a = C, b = D, gcd == g*v */ - - /* if v != 1 then there is no inverse */ - if (mp_cmp_d (&v, 1) != MP_EQ) { - res = MP_VAL; - goto LBL_ERR; - } - - /* b is now the inverse */ - neg = a->sign; - while (D.sign == MP_NEG) { - if ((res = mp_add (&D, b, &D)) != MP_OKAY) { - goto LBL_ERR; - } - } - mp_exch (&D, c); - c->sign = neg; - res = MP_OKAY; - -LBL_ERR:mp_clear_multi (&x, &y, &u, &v, &B, &D, NULL); - return res; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_fast_mp_montgomery_reduce.c b/external/libtommath-0.42.0/bn_fast_mp_montgomery_reduce.c deleted file mode 100755 index 1a81689..0000000 --- a/external/libtommath-0.42.0/bn_fast_mp_montgomery_reduce.c +++ /dev/null @@ -1,172 +0,0 @@ -#include -#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* computes xR**-1 == x (mod N) via Montgomery Reduction - * - * This is an optimized implementation of montgomery_reduce - * which uses the comba method to quickly calculate the columns of the - * reduction. - * - * Based on Algorithm 14.32 on pp.601 of HAC. -*/ -int fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) -{ - int ix, res, olduse; - mp_word W[MP_WARRAY]; - - /* get old used count */ - olduse = x->used; - - /* grow a as required */ - if (x->alloc < n->used + 1) { - if ((res = mp_grow (x, n->used + 1)) != MP_OKAY) { - return res; - } - } - - /* first we have to get the digits of the input into - * an array of double precision words W[...] - */ - { - register mp_word *_W; - register mp_digit *tmpx; - - /* alias for the W[] array */ - _W = W; - - /* alias for the digits of x*/ - tmpx = x->dp; - - /* copy the digits of a into W[0..a->used-1] */ - for (ix = 0; ix < x->used; ix++) { - *_W++ = *tmpx++; - } - - /* zero the high words of W[a->used..m->used*2] */ - for (; ix < n->used * 2 + 1; ix++) { - *_W++ = 0; - } - } - - /* now we proceed to zero successive digits - * from the least significant upwards - */ - for (ix = 0; ix < n->used; ix++) { - /* mu = ai * m' mod b - * - * We avoid a double precision multiplication (which isn't required) - * by casting the value down to a mp_digit. Note this requires - * that W[ix-1] have the carry cleared (see after the inner loop) - */ - register mp_digit mu; - mu = (mp_digit) (((W[ix] & MP_MASK) * rho) & MP_MASK); - - /* a = a + mu * m * b**i - * - * This is computed in place and on the fly. The multiplication - * by b**i is handled by offseting which columns the results - * are added to. - * - * Note the comba method normally doesn't handle carries in the - * inner loop In this case we fix the carry from the previous - * column since the Montgomery reduction requires digits of the - * result (so far) [see above] to work. This is - * handled by fixing up one carry after the inner loop. The - * carry fixups are done in order so after these loops the - * first m->used words of W[] have the carries fixed - */ - { - register int iy; - register mp_digit *tmpn; - register mp_word *_W; - - /* alias for the digits of the modulus */ - tmpn = n->dp; - - /* Alias for the columns set by an offset of ix */ - _W = W + ix; - - /* inner loop */ - for (iy = 0; iy < n->used; iy++) { - *_W++ += ((mp_word)mu) * ((mp_word)*tmpn++); - } - } - - /* now fix carry for next digit, W[ix+1] */ - W[ix + 1] += W[ix] >> ((mp_word) DIGIT_BIT); - } - - /* now we have to propagate the carries and - * shift the words downward [all those least - * significant digits we zeroed]. - */ - { - register mp_digit *tmpx; - register mp_word *_W, *_W1; - - /* nox fix rest of carries */ - - /* alias for current word */ - _W1 = W + ix; - - /* alias for next word, where the carry goes */ - _W = W + ++ix; - - for (; ix <= n->used * 2 + 1; ix++) { - *_W++ += *_W1++ >> ((mp_word) DIGIT_BIT); - } - - /* copy out, A = A/b**n - * - * The result is A/b**n but instead of converting from an - * array of mp_word to mp_digit than calling mp_rshd - * we just copy them in the right order - */ - - /* alias for destination word */ - tmpx = x->dp; - - /* alias for shifted double precision result */ - _W = W + n->used; - - for (ix = 0; ix < n->used + 1; ix++) { - *tmpx++ = (mp_digit)(*_W++ & ((mp_word) MP_MASK)); - } - - /* zero oldused digits, if the input a was larger than - * m->used+1 we'll have to clear the digits - */ - for (; ix < olduse; ix++) { - *tmpx++ = 0; - } - } - - /* set the max used and clamp */ - x->used = n->used + 1; - mp_clamp (x); - - /* if A >= m then A = A - m */ - if (mp_cmp_mag (x, n) != MP_LT) { - return s_mp_sub (x, n, x); - } - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_fast_s_mp_mul_digs.c b/external/libtommath-0.42.0/bn_fast_s_mp_mul_digs.c deleted file mode 100755 index 04becfd..0000000 --- a/external/libtommath-0.42.0/bn_fast_s_mp_mul_digs.c +++ /dev/null @@ -1,107 +0,0 @@ -#include -#ifdef BN_FAST_S_MP_MUL_DIGS_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* Fast (comba) multiplier - * - * This is the fast column-array [comba] multiplier. It is - * designed to compute the columns of the product first - * then handle the carries afterwards. This has the effect - * of making the nested loops that compute the columns very - * simple and schedulable on super-scalar processors. - * - * This has been modified to produce a variable number of - * digits of output so if say only a half-product is required - * you don't have to compute the upper half (a feature - * required for fast Barrett reduction). - * - * Based on Algorithm 14.12 on pp.595 of HAC. - * - */ -int fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) -{ - int olduse, res, pa, ix, iz; - mp_digit W[MP_WARRAY]; - register mp_word _W; - - /* grow the destination as required */ - if (c->alloc < digs) { - if ((res = mp_grow (c, digs)) != MP_OKAY) { - return res; - } - } - - /* number of output digits to produce */ - pa = MIN(digs, a->used + b->used); - - /* clear the carry */ - _W = 0; - for (ix = 0; ix < pa; ix++) { - int tx, ty; - int iy; - mp_digit *tmpx, *tmpy; - - /* get offsets into the two bignums */ - ty = MIN(b->used-1, ix); - tx = ix - ty; - - /* setup temp aliases */ - tmpx = a->dp + tx; - tmpy = b->dp + ty; - - /* this is the number of times the loop will iterrate, essentially - while (tx++ < a->used && ty-- >= 0) { ... } - */ - iy = MIN(a->used-tx, ty+1); - - /* execute loop */ - for (iz = 0; iz < iy; ++iz) { - _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--); - - } - - /* store term */ - W[ix] = ((mp_digit)_W) & MP_MASK; - - /* make next carry */ - _W = _W >> ((mp_word)DIGIT_BIT); - } - - /* setup dest */ - olduse = c->used; - c->used = pa; - - { - register mp_digit *tmpc; - tmpc = c->dp; - for (ix = 0; ix < pa+1; ix++) { - /* now extract the previous digit [below the carry] */ - *tmpc++ = W[ix]; - } - - /* clear unused digits [that existed in the old copy of c] */ - for (; ix < olduse; ix++) { - *tmpc++ = 0; - } - } - mp_clamp (c); - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_fast_s_mp_mul_high_digs.c b/external/libtommath-0.42.0/bn_fast_s_mp_mul_high_digs.c deleted file mode 100755 index 98bee37..0000000 --- a/external/libtommath-0.42.0/bn_fast_s_mp_mul_high_digs.c +++ /dev/null @@ -1,98 +0,0 @@ -#include -#ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* this is a modified version of fast_s_mul_digs that only produces - * output digits *above* digs. See the comments for fast_s_mul_digs - * to see how it works. - * - * This is used in the Barrett reduction since for one of the multiplications - * only the higher digits were needed. This essentially halves the work. - * - * Based on Algorithm 14.12 on pp.595 of HAC. - */ -int fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs) -{ - int olduse, res, pa, ix, iz; - mp_digit W[MP_WARRAY]; - mp_word _W; - - /* grow the destination as required */ - pa = a->used + b->used; - if (c->alloc < pa) { - if ((res = mp_grow (c, pa)) != MP_OKAY) { - return res; - } - } - - /* number of output digits to produce */ - pa = a->used + b->used; - _W = 0; - for (ix = digs; ix < pa; ix++) { - int tx, ty, iy; - mp_digit *tmpx, *tmpy; - - /* get offsets into the two bignums */ - ty = MIN(b->used-1, ix); - tx = ix - ty; - - /* setup temp aliases */ - tmpx = a->dp + tx; - tmpy = b->dp + ty; - - /* this is the number of times the loop will iterrate, essentially its - while (tx++ < a->used && ty-- >= 0) { ... } - */ - iy = MIN(a->used-tx, ty+1); - - /* execute loop */ - for (iz = 0; iz < iy; iz++) { - _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--); - } - - /* store term */ - W[ix] = ((mp_digit)_W) & MP_MASK; - - /* make next carry */ - _W = _W >> ((mp_word)DIGIT_BIT); - } - - /* setup dest */ - olduse = c->used; - c->used = pa; - - { - register mp_digit *tmpc; - - tmpc = c->dp + digs; - for (ix = digs; ix < pa; ix++) { - /* now extract the previous digit [below the carry] */ - *tmpc++ = W[ix]; - } - - /* clear unused digits [that existed in the old copy of c] */ - for (; ix < olduse; ix++) { - *tmpc++ = 0; - } - } - mp_clamp (c); - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_fast_s_mp_sqr.c b/external/libtommath-0.42.0/bn_fast_s_mp_sqr.c deleted file mode 100755 index 086b52c..0000000 --- a/external/libtommath-0.42.0/bn_fast_s_mp_sqr.c +++ /dev/null @@ -1,114 +0,0 @@ -#include -#ifdef BN_FAST_S_MP_SQR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* the jist of squaring... - * you do like mult except the offset of the tmpx [one that - * starts closer to zero] can't equal the offset of tmpy. - * So basically you set up iy like before then you min it with - * (ty-tx) so that it never happens. You double all those - * you add in the inner loop - -After that loop you do the squares and add them in. -*/ - -int fast_s_mp_sqr (mp_int * a, mp_int * b) -{ - int olduse, res, pa, ix, iz; - mp_digit W[MP_WARRAY], *tmpx; - mp_word W1; - - /* grow the destination as required */ - pa = a->used + a->used; - if (b->alloc < pa) { - if ((res = mp_grow (b, pa)) != MP_OKAY) { - return res; - } - } - - /* number of output digits to produce */ - W1 = 0; - for (ix = 0; ix < pa; ix++) { - int tx, ty, iy; - mp_word _W; - mp_digit *tmpy; - - /* clear counter */ - _W = 0; - - /* get offsets into the two bignums */ - ty = MIN(a->used-1, ix); - tx = ix - ty; - - /* setup temp aliases */ - tmpx = a->dp + tx; - tmpy = a->dp + ty; - - /* this is the number of times the loop will iterrate, essentially - while (tx++ < a->used && ty-- >= 0) { ... } - */ - iy = MIN(a->used-tx, ty+1); - - /* now for squaring tx can never equal ty - * we halve the distance since they approach at a rate of 2x - * and we have to round because odd cases need to be executed - */ - iy = MIN(iy, (ty-tx+1)>>1); - - /* execute loop */ - for (iz = 0; iz < iy; iz++) { - _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--); - } - - /* double the inner product and add carry */ - _W = _W + _W + W1; - - /* even columns have the square term in them */ - if ((ix&1) == 0) { - _W += ((mp_word)a->dp[ix>>1])*((mp_word)a->dp[ix>>1]); - } - - /* store it */ - W[ix] = (mp_digit)(_W & MP_MASK); - - /* make next carry */ - W1 = _W >> ((mp_word)DIGIT_BIT); - } - - /* setup dest */ - olduse = b->used; - b->used = a->used+a->used; - - { - mp_digit *tmpb; - tmpb = b->dp; - for (ix = 0; ix < pa; ix++) { - *tmpb++ = W[ix] & MP_MASK; - } - - /* clear unused digits [that existed in the old copy of c] */ - for (; ix < olduse; ix++) { - *tmpb++ = 0; - } - } - mp_clamp (b); - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_2expt.c b/external/libtommath-0.42.0/bn_mp_2expt.c deleted file mode 100755 index 4774aab..0000000 --- a/external/libtommath-0.42.0/bn_mp_2expt.c +++ /dev/null @@ -1,48 +0,0 @@ -#include -#ifdef BN_MP_2EXPT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* computes a = 2**b - * - * Simple algorithm which zeroes the int, grows it then just sets one bit - * as required. - */ -int -mp_2expt (mp_int * a, int b) -{ - int res; - - /* zero a as per default */ - mp_zero (a); - - /* grow a to accomodate the single bit */ - if ((res = mp_grow (a, b / DIGIT_BIT + 1)) != MP_OKAY) { - return res; - } - - /* set the used count of where the bit will go */ - a->used = b / DIGIT_BIT + 1; - - /* put the single bit in its place */ - a->dp[b / DIGIT_BIT] = ((mp_digit)1) << (b % DIGIT_BIT); - - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_abs.c b/external/libtommath-0.42.0/bn_mp_abs.c deleted file mode 100755 index 4d1fa44..0000000 --- a/external/libtommath-0.42.0/bn_mp_abs.c +++ /dev/null @@ -1,43 +0,0 @@ -#include -#ifdef BN_MP_ABS_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* b = |a| - * - * Simple function copies the input and fixes the sign to positive - */ -int -mp_abs (mp_int * a, mp_int * b) -{ - int res; - - /* copy a to b */ - if (a != b) { - if ((res = mp_copy (a, b)) != MP_OKAY) { - return res; - } - } - - /* force the sign of b to positive */ - b->sign = MP_ZPOS; - - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_add.c b/external/libtommath-0.42.0/bn_mp_add.c deleted file mode 100755 index 122c850..0000000 --- a/external/libtommath-0.42.0/bn_mp_add.c +++ /dev/null @@ -1,53 +0,0 @@ -#include -#ifdef BN_MP_ADD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* high level addition (handles signs) */ -int mp_add (mp_int * a, mp_int * b, mp_int * c) -{ - int sa, sb, res; - - /* get sign of both inputs */ - sa = a->sign; - sb = b->sign; - - /* handle two cases, not four */ - if (sa == sb) { - /* both positive or both negative */ - /* add their magnitudes, copy the sign */ - c->sign = sa; - res = s_mp_add (a, b, c); - } else { - /* one positive, the other negative */ - /* subtract the one with the greater magnitude from */ - /* the one of the lesser magnitude. The result gets */ - /* the sign of the one with the greater magnitude. */ - if (mp_cmp_mag (a, b) == MP_LT) { - c->sign = sb; - res = s_mp_sub (b, a, c); - } else { - c->sign = sa; - res = s_mp_sub (a, b, c); - } - } - return res; -} - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_add_d.c b/external/libtommath-0.42.0/bn_mp_add_d.c deleted file mode 100755 index aec8fc8..0000000 --- a/external/libtommath-0.42.0/bn_mp_add_d.c +++ /dev/null @@ -1,112 +0,0 @@ -#include -#ifdef BN_MP_ADD_D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* single digit addition */ -int -mp_add_d (mp_int * a, mp_digit b, mp_int * c) -{ - int res, ix, oldused; - mp_digit *tmpa, *tmpc, mu; - - /* grow c as required */ - if (c->alloc < a->used + 1) { - if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) { - return res; - } - } - - /* if a is negative and |a| >= b, call c = |a| - b */ - if (a->sign == MP_NEG && (a->used > 1 || a->dp[0] >= b)) { - /* temporarily fix sign of a */ - a->sign = MP_ZPOS; - - /* c = |a| - b */ - res = mp_sub_d(a, b, c); - - /* fix sign */ - a->sign = c->sign = MP_NEG; - - /* clamp */ - mp_clamp(c); - - return res; - } - - /* old number of used digits in c */ - oldused = c->used; - - /* sign always positive */ - c->sign = MP_ZPOS; - - /* source alias */ - tmpa = a->dp; - - /* destination alias */ - tmpc = c->dp; - - /* if a is positive */ - if (a->sign == MP_ZPOS) { - /* add digit, after this we're propagating - * the carry. - */ - *tmpc = *tmpa++ + b; - mu = *tmpc >> DIGIT_BIT; - *tmpc++ &= MP_MASK; - - /* now handle rest of the digits */ - for (ix = 1; ix < a->used; ix++) { - *tmpc = *tmpa++ + mu; - mu = *tmpc >> DIGIT_BIT; - *tmpc++ &= MP_MASK; - } - /* set final carry */ - ix++; - *tmpc++ = mu; - - /* setup size */ - c->used = a->used + 1; - } else { - /* a was negative and |a| < b */ - c->used = 1; - - /* the result is a single digit */ - if (a->used == 1) { - *tmpc++ = b - a->dp[0]; - } else { - *tmpc++ = b; - } - - /* setup count so the clearing of oldused - * can fall through correctly - */ - ix = 1; - } - - /* now zero to oldused */ - while (ix++ < oldused) { - *tmpc++ = 0; - } - mp_clamp(c); - - return MP_OKAY; -} - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_addmod.c b/external/libtommath-0.42.0/bn_mp_addmod.c deleted file mode 100755 index 0376659..0000000 --- a/external/libtommath-0.42.0/bn_mp_addmod.c +++ /dev/null @@ -1,41 +0,0 @@ -#include -#ifdef BN_MP_ADDMOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* d = a + b (mod c) */ -int -mp_addmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) -{ - int res; - mp_int t; - - if ((res = mp_init (&t)) != MP_OKAY) { - return res; - } - - if ((res = mp_add (a, b, &t)) != MP_OKAY) { - mp_clear (&t); - return res; - } - res = mp_mod (&t, c, d); - mp_clear (&t); - return res; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_and.c b/external/libtommath-0.42.0/bn_mp_and.c deleted file mode 100755 index 22dfbff..0000000 --- a/external/libtommath-0.42.0/bn_mp_and.c +++ /dev/null @@ -1,57 +0,0 @@ -#include -#ifdef BN_MP_AND_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* AND two ints together */ -int -mp_and (mp_int * a, mp_int * b, mp_int * c) -{ - int res, ix, px; - mp_int t, *x; - - if (a->used > b->used) { - if ((res = mp_init_copy (&t, a)) != MP_OKAY) { - return res; - } - px = b->used; - x = b; - } else { - if ((res = mp_init_copy (&t, b)) != MP_OKAY) { - return res; - } - px = a->used; - x = a; - } - - for (ix = 0; ix < px; ix++) { - t.dp[ix] &= x->dp[ix]; - } - - /* zero digits above the last from the smallest mp_int */ - for (; ix < t.used; ix++) { - t.dp[ix] = 0; - } - - mp_clamp (&t); - mp_exch (c, &t); - mp_clear (&t); - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_clamp.c b/external/libtommath-0.42.0/bn_mp_clamp.c deleted file mode 100755 index 1e0c817..0000000 --- a/external/libtommath-0.42.0/bn_mp_clamp.c +++ /dev/null @@ -1,44 +0,0 @@ -#include -#ifdef BN_MP_CLAMP_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* trim unused digits - * - * This is used to ensure that leading zero digits are - * trimed and the leading "used" digit will be non-zero - * Typically very fast. Also fixes the sign if there - * are no more leading digits - */ -void -mp_clamp (mp_int * a) -{ - /* decrease used while the most significant digit is - * zero. - */ - while (a->used > 0 && a->dp[a->used - 1] == 0) { - --(a->used); - } - - /* reset the sign flag if used == 0 */ - if (a->used == 0) { - a->sign = MP_ZPOS; - } -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_clear.c b/external/libtommath-0.42.0/bn_mp_clear.c deleted file mode 100755 index 72301df..0000000 --- a/external/libtommath-0.42.0/bn_mp_clear.c +++ /dev/null @@ -1,44 +0,0 @@ -#include -#ifdef BN_MP_CLEAR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* clear one (frees) */ -void -mp_clear (mp_int * a) -{ - int i; - - /* only do anything if a hasn't been freed previously */ - if (a->dp != NULL) { - /* first zero the digits */ - for (i = 0; i < a->used; i++) { - a->dp[i] = 0; - } - - /* free ram */ - XFREE(a->dp); - - /* reset members to make debugging easier */ - a->dp = NULL; - a->alloc = a->used = 0; - a->sign = MP_ZPOS; - } -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_clear_multi.c b/external/libtommath-0.42.0/bn_mp_clear_multi.c deleted file mode 100755 index 6bbc10c..0000000 --- a/external/libtommath-0.42.0/bn_mp_clear_multi.c +++ /dev/null @@ -1,34 +0,0 @@ -#include -#ifdef BN_MP_CLEAR_MULTI_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include - -void mp_clear_multi(mp_int *mp, ...) -{ - mp_int* next_mp = mp; - va_list args; - va_start(args, mp); - while (next_mp != NULL) { - mp_clear(next_mp); - next_mp = va_arg(args, mp_int*); - } - va_end(args); -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_cmp.c b/external/libtommath-0.42.0/bn_mp_cmp.c deleted file mode 100755 index 77d00cd..0000000 --- a/external/libtommath-0.42.0/bn_mp_cmp.c +++ /dev/null @@ -1,43 +0,0 @@ -#include -#ifdef BN_MP_CMP_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* compare two ints (signed)*/ -int -mp_cmp (mp_int * a, mp_int * b) -{ - /* compare based on sign */ - if (a->sign != b->sign) { - if (a->sign == MP_NEG) { - return MP_LT; - } else { - return MP_GT; - } - } - - /* compare digits */ - if (a->sign == MP_NEG) { - /* if negative compare opposite direction */ - return mp_cmp_mag(b, a); - } else { - return mp_cmp_mag(a, b); - } -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_cmp_d.c b/external/libtommath-0.42.0/bn_mp_cmp_d.c deleted file mode 100755 index 0d5bcb4..0000000 --- a/external/libtommath-0.42.0/bn_mp_cmp_d.c +++ /dev/null @@ -1,44 +0,0 @@ -#include -#ifdef BN_MP_CMP_D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* compare a digit */ -int mp_cmp_d(mp_int * a, mp_digit b) -{ - /* compare based on sign */ - if (a->sign == MP_NEG) { - return MP_LT; - } - - /* compare based on magnitude */ - if (a->used > 1) { - return MP_GT; - } - - /* compare the only digit of a to b */ - if (a->dp[0] > b) { - return MP_GT; - } else if (a->dp[0] < b) { - return MP_LT; - } else { - return MP_EQ; - } -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_cmp_mag.c b/external/libtommath-0.42.0/bn_mp_cmp_mag.c deleted file mode 100755 index 063fd18..0000000 --- a/external/libtommath-0.42.0/bn_mp_cmp_mag.c +++ /dev/null @@ -1,55 +0,0 @@ -#include -#ifdef BN_MP_CMP_MAG_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* compare maginitude of two ints (unsigned) */ -int mp_cmp_mag (mp_int * a, mp_int * b) -{ - int n; - mp_digit *tmpa, *tmpb; - - /* compare based on # of non-zero digits */ - if (a->used > b->used) { - return MP_GT; - } - - if (a->used < b->used) { - return MP_LT; - } - - /* alias for a */ - tmpa = a->dp + (a->used - 1); - - /* alias for b */ - tmpb = b->dp + (a->used - 1); - - /* compare based on digits */ - for (n = 0; n < a->used; ++n, --tmpa, --tmpb) { - if (*tmpa > *tmpb) { - return MP_GT; - } - - if (*tmpa < *tmpb) { - return MP_LT; - } - } - return MP_EQ; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_cnt_lsb.c b/external/libtommath-0.42.0/bn_mp_cnt_lsb.c deleted file mode 100755 index efebd2a..0000000 --- a/external/libtommath-0.42.0/bn_mp_cnt_lsb.c +++ /dev/null @@ -1,53 +0,0 @@ -#include -#ifdef BN_MP_CNT_LSB_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -static const int lnz[16] = { - 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 -}; - -/* Counts the number of lsbs which are zero before the first zero bit */ -int mp_cnt_lsb(mp_int *a) -{ - int x; - mp_digit q, qq; - - /* easy out */ - if (mp_iszero(a) == 1) { - return 0; - } - - /* scan lower digits until non-zero */ - for (x = 0; x < a->used && a->dp[x] == 0; x++); - q = a->dp[x]; - x *= DIGIT_BIT; - - /* now scan this digit until a 1 is found */ - if ((q & 1) == 0) { - do { - qq = q & 15; - x += lnz[qq]; - q >>= 4; - } while (qq == 0); - } - return x; -} - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_copy.c b/external/libtommath-0.42.0/bn_mp_copy.c deleted file mode 100755 index 45cac61..0000000 --- a/external/libtommath-0.42.0/bn_mp_copy.c +++ /dev/null @@ -1,68 +0,0 @@ -#include -#ifdef BN_MP_COPY_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* copy, b = a */ -int -mp_copy (mp_int * a, mp_int * b) -{ - int res, n; - - /* if dst == src do nothing */ - if (a == b) { - return MP_OKAY; - } - - /* grow dest */ - if (b->alloc < a->used) { - if ((res = mp_grow (b, a->used)) != MP_OKAY) { - return res; - } - } - - /* zero b and copy the parameters over */ - { - register mp_digit *tmpa, *tmpb; - - /* pointer aliases */ - - /* source */ - tmpa = a->dp; - - /* destination */ - tmpb = b->dp; - - /* copy all the digits */ - for (n = 0; n < a->used; n++) { - *tmpb++ = *tmpa++; - } - - /* clear high digits */ - for (; n < b->used; n++) { - *tmpb++ = 0; - } - } - - /* copy used count and sign */ - b->used = a->used; - b->sign = a->sign; - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_count_bits.c b/external/libtommath-0.42.0/bn_mp_count_bits.c deleted file mode 100755 index 6c02ec6..0000000 --- a/external/libtommath-0.42.0/bn_mp_count_bits.c +++ /dev/null @@ -1,45 +0,0 @@ -#include -#ifdef BN_MP_COUNT_BITS_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* returns the number of bits in an int */ -int -mp_count_bits (mp_int * a) -{ - int r; - mp_digit q; - - /* shortcut */ - if (a->used == 0) { - return 0; - } - - /* get number of digits and add that */ - r = (a->used - 1) * DIGIT_BIT; - - /* take the last digit and count the bits in it */ - q = a->dp[a->used - 1]; - while (q > ((mp_digit) 0)) { - ++r; - q >>= ((mp_digit) 1); - } - return r; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_div.c b/external/libtommath-0.42.0/bn_mp_div.c deleted file mode 100755 index af5c55d..0000000 --- a/external/libtommath-0.42.0/bn_mp_div.c +++ /dev/null @@ -1,292 +0,0 @@ -#include -#ifdef BN_MP_DIV_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -#ifdef BN_MP_DIV_SMALL - -/* slower bit-bang division... also smaller */ -int mp_div(mp_int * a, mp_int * b, mp_int * c, mp_int * d) -{ - mp_int ta, tb, tq, q; - int res, n, n2; - - /* is divisor zero ? */ - if (mp_iszero (b) == 1) { - return MP_VAL; - } - - /* if a < b then q=0, r = a */ - if (mp_cmp_mag (a, b) == MP_LT) { - if (d != NULL) { - res = mp_copy (a, d); - } else { - res = MP_OKAY; - } - if (c != NULL) { - mp_zero (c); - } - return res; - } - - /* init our temps */ - if ((res = mp_init_multi(&ta, &tb, &tq, &q, NULL) != MP_OKAY)) { - return res; - } - - - mp_set(&tq, 1); - n = mp_count_bits(a) - mp_count_bits(b); - if (((res = mp_abs(a, &ta)) != MP_OKAY) || - ((res = mp_abs(b, &tb)) != MP_OKAY) || - ((res = mp_mul_2d(&tb, n, &tb)) != MP_OKAY) || - ((res = mp_mul_2d(&tq, n, &tq)) != MP_OKAY)) { - goto LBL_ERR; - } - - while (n-- >= 0) { - if (mp_cmp(&tb, &ta) != MP_GT) { - if (((res = mp_sub(&ta, &tb, &ta)) != MP_OKAY) || - ((res = mp_add(&q, &tq, &q)) != MP_OKAY)) { - goto LBL_ERR; - } - } - if (((res = mp_div_2d(&tb, 1, &tb, NULL)) != MP_OKAY) || - ((res = mp_div_2d(&tq, 1, &tq, NULL)) != MP_OKAY)) { - goto LBL_ERR; - } - } - - /* now q == quotient and ta == remainder */ - n = a->sign; - n2 = (a->sign == b->sign ? MP_ZPOS : MP_NEG); - if (c != NULL) { - mp_exch(c, &q); - c->sign = (mp_iszero(c) == MP_YES) ? MP_ZPOS : n2; - } - if (d != NULL) { - mp_exch(d, &ta); - d->sign = (mp_iszero(d) == MP_YES) ? MP_ZPOS : n; - } -LBL_ERR: - mp_clear_multi(&ta, &tb, &tq, &q, NULL); - return res; -} - -#else - -/* integer signed division. - * c*b + d == a [e.g. a/b, c=quotient, d=remainder] - * HAC pp.598 Algorithm 14.20 - * - * Note that the description in HAC is horribly - * incomplete. For example, it doesn't consider - * the case where digits are removed from 'x' in - * the inner loop. It also doesn't consider the - * case that y has fewer than three digits, etc.. - * - * The overall algorithm is as described as - * 14.20 from HAC but fixed to treat these cases. -*/ -int mp_div (mp_int * a, mp_int * b, mp_int * c, mp_int * d) -{ - mp_int q, x, y, t1, t2; - int res, n, t, i, norm, neg; - - /* is divisor zero ? */ - if (mp_iszero (b) == 1) { - return MP_VAL; - } - - /* if a < b then q=0, r = a */ - if (mp_cmp_mag (a, b) == MP_LT) { - if (d != NULL) { - res = mp_copy (a, d); - } else { - res = MP_OKAY; - } - if (c != NULL) { - mp_zero (c); - } - return res; - } - - if ((res = mp_init_size (&q, a->used + 2)) != MP_OKAY) { - return res; - } - q.used = a->used + 2; - - if ((res = mp_init (&t1)) != MP_OKAY) { - goto LBL_Q; - } - - if ((res = mp_init (&t2)) != MP_OKAY) { - goto LBL_T1; - } - - if ((res = mp_init_copy (&x, a)) != MP_OKAY) { - goto LBL_T2; - } - - if ((res = mp_init_copy (&y, b)) != MP_OKAY) { - goto LBL_X; - } - - /* fix the sign */ - neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; - x.sign = y.sign = MP_ZPOS; - - /* normalize both x and y, ensure that y >= b/2, [b == 2**DIGIT_BIT] */ - norm = mp_count_bits(&y) % DIGIT_BIT; - if (norm < (int)(DIGIT_BIT-1)) { - norm = (DIGIT_BIT-1) - norm; - if ((res = mp_mul_2d (&x, norm, &x)) != MP_OKAY) { - goto LBL_Y; - } - if ((res = mp_mul_2d (&y, norm, &y)) != MP_OKAY) { - goto LBL_Y; - } - } else { - norm = 0; - } - - /* note hac does 0 based, so if used==5 then its 0,1,2,3,4, e.g. use 4 */ - n = x.used - 1; - t = y.used - 1; - - /* while (x >= y*b**n-t) do { q[n-t] += 1; x -= y*b**{n-t} } */ - if ((res = mp_lshd (&y, n - t)) != MP_OKAY) { /* y = y*b**{n-t} */ - goto LBL_Y; - } - - while (mp_cmp (&x, &y) != MP_LT) { - ++(q.dp[n - t]); - if ((res = mp_sub (&x, &y, &x)) != MP_OKAY) { - goto LBL_Y; - } - } - - /* reset y by shifting it back down */ - mp_rshd (&y, n - t); - - /* step 3. for i from n down to (t + 1) */ - for (i = n; i >= (t + 1); i--) { - if (i > x.used) { - continue; - } - - /* step 3.1 if xi == yt then set q{i-t-1} to b-1, - * otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */ - if (x.dp[i] == y.dp[t]) { - q.dp[i - t - 1] = ((((mp_digit)1) << DIGIT_BIT) - 1); - } else { - mp_word tmp; - tmp = ((mp_word) x.dp[i]) << ((mp_word) DIGIT_BIT); - tmp |= ((mp_word) x.dp[i - 1]); - tmp /= ((mp_word) y.dp[t]); - if (tmp > (mp_word) MP_MASK) - tmp = MP_MASK; - q.dp[i - t - 1] = (mp_digit) (tmp & (mp_word) (MP_MASK)); - } - - /* while (q{i-t-1} * (yt * b + y{t-1})) > - xi * b**2 + xi-1 * b + xi-2 - - do q{i-t-1} -= 1; - */ - q.dp[i - t - 1] = (q.dp[i - t - 1] + 1) & MP_MASK; - do { - q.dp[i - t - 1] = (q.dp[i - t - 1] - 1) & MP_MASK; - - /* find left hand */ - mp_zero (&t1); - t1.dp[0] = (t - 1 < 0) ? 0 : y.dp[t - 1]; - t1.dp[1] = y.dp[t]; - t1.used = 2; - if ((res = mp_mul_d (&t1, q.dp[i - t - 1], &t1)) != MP_OKAY) { - goto LBL_Y; - } - - /* find right hand */ - t2.dp[0] = (i - 2 < 0) ? 0 : x.dp[i - 2]; - t2.dp[1] = (i - 1 < 0) ? 0 : x.dp[i - 1]; - t2.dp[2] = x.dp[i]; - t2.used = 3; - } while (mp_cmp_mag(&t1, &t2) == MP_GT); - - /* step 3.3 x = x - q{i-t-1} * y * b**{i-t-1} */ - if ((res = mp_mul_d (&y, q.dp[i - t - 1], &t1)) != MP_OKAY) { - goto LBL_Y; - } - - if ((res = mp_lshd (&t1, i - t - 1)) != MP_OKAY) { - goto LBL_Y; - } - - if ((res = mp_sub (&x, &t1, &x)) != MP_OKAY) { - goto LBL_Y; - } - - /* if x < 0 then { x = x + y*b**{i-t-1}; q{i-t-1} -= 1; } */ - if (x.sign == MP_NEG) { - if ((res = mp_copy (&y, &t1)) != MP_OKAY) { - goto LBL_Y; - } - if ((res = mp_lshd (&t1, i - t - 1)) != MP_OKAY) { - goto LBL_Y; - } - if ((res = mp_add (&x, &t1, &x)) != MP_OKAY) { - goto LBL_Y; - } - - q.dp[i - t - 1] = (q.dp[i - t - 1] - 1UL) & MP_MASK; - } - } - - /* now q is the quotient and x is the remainder - * [which we have to normalize] - */ - - /* get sign before writing to c */ - x.sign = x.used == 0 ? MP_ZPOS : a->sign; - - if (c != NULL) { - mp_clamp (&q); - mp_exch (&q, c); - c->sign = neg; - } - - if (d != NULL) { - mp_div_2d (&x, norm, &x, NULL); - mp_exch (&x, d); - } - - res = MP_OKAY; - -LBL_Y:mp_clear (&y); -LBL_X:mp_clear (&x); -LBL_T2:mp_clear (&t2); -LBL_T1:mp_clear (&t1); -LBL_Q:mp_clear (&q); - return res; -} - -#endif - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_div_2.c b/external/libtommath-0.42.0/bn_mp_div_2.c deleted file mode 100755 index 64ef823..0000000 --- a/external/libtommath-0.42.0/bn_mp_div_2.c +++ /dev/null @@ -1,68 +0,0 @@ -#include -#ifdef BN_MP_DIV_2_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* b = a/2 */ -int mp_div_2(mp_int * a, mp_int * b) -{ - int x, res, oldused; - - /* copy */ - if (b->alloc < a->used) { - if ((res = mp_grow (b, a->used)) != MP_OKAY) { - return res; - } - } - - oldused = b->used; - b->used = a->used; - { - register mp_digit r, rr, *tmpa, *tmpb; - - /* source alias */ - tmpa = a->dp + b->used - 1; - - /* dest alias */ - tmpb = b->dp + b->used - 1; - - /* carry */ - r = 0; - for (x = b->used - 1; x >= 0; x--) { - /* get the carry for the next iteration */ - rr = *tmpa & 1; - - /* shift the current digit, add in carry and store */ - *tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1)); - - /* forward carry to next iteration */ - r = rr; - } - - /* zero excess digits */ - tmpb = b->dp + b->used; - for (x = b->used; x < oldused; x++) { - *tmpb++ = 0; - } - } - b->sign = a->sign; - mp_clamp (b); - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_div_2d.c b/external/libtommath-0.42.0/bn_mp_div_2d.c deleted file mode 100755 index 72936a4..0000000 --- a/external/libtommath-0.42.0/bn_mp_div_2d.c +++ /dev/null @@ -1,97 +0,0 @@ -#include -#ifdef BN_MP_DIV_2D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* shift right by a certain bit count (store quotient in c, optional remainder in d) */ -int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d) -{ - mp_digit D, r, rr; - int x, res; - mp_int t; - - - /* if the shift count is <= 0 then we do no work */ - if (b <= 0) { - res = mp_copy (a, c); - if (d != NULL) { - mp_zero (d); - } - return res; - } - - if ((res = mp_init (&t)) != MP_OKAY) { - return res; - } - - /* get the remainder */ - if (d != NULL) { - if ((res = mp_mod_2d (a, b, &t)) != MP_OKAY) { - mp_clear (&t); - return res; - } - } - - /* copy */ - if ((res = mp_copy (a, c)) != MP_OKAY) { - mp_clear (&t); - return res; - } - - /* shift by as many digits in the bit count */ - if (b >= (int)DIGIT_BIT) { - mp_rshd (c, b / DIGIT_BIT); - } - - /* shift any bit count < DIGIT_BIT */ - D = (mp_digit) (b % DIGIT_BIT); - if (D != 0) { - register mp_digit *tmpc, mask, shift; - - /* mask */ - mask = (((mp_digit)1) << D) - 1; - - /* shift for lsb */ - shift = DIGIT_BIT - D; - - /* alias */ - tmpc = c->dp + (c->used - 1); - - /* carry */ - r = 0; - for (x = c->used - 1; x >= 0; x--) { - /* get the lower bits of this word in a temp */ - rr = *tmpc & mask; - - /* shift the current word and mix in the carry bits from the previous word */ - *tmpc = (*tmpc >> D) | (r << shift); - --tmpc; - - /* set the carry to the carry bits of the current word found above */ - r = rr; - } - } - mp_clamp (c); - if (d != NULL) { - mp_exch (&t, d); - } - mp_clear (&t); - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_div_3.c b/external/libtommath-0.42.0/bn_mp_div_3.c deleted file mode 100755 index 7f6869b..0000000 --- a/external/libtommath-0.42.0/bn_mp_div_3.c +++ /dev/null @@ -1,79 +0,0 @@ -#include -#ifdef BN_MP_DIV_3_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* divide by three (based on routine from MPI and the GMP manual) */ -int -mp_div_3 (mp_int * a, mp_int *c, mp_digit * d) -{ - mp_int q; - mp_word w, t; - mp_digit b; - int res, ix; - - /* b = 2**DIGIT_BIT / 3 */ - b = (((mp_word)1) << ((mp_word)DIGIT_BIT)) / ((mp_word)3); - - if ((res = mp_init_size(&q, a->used)) != MP_OKAY) { - return res; - } - - q.used = a->used; - q.sign = a->sign; - w = 0; - for (ix = a->used - 1; ix >= 0; ix--) { - w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]); - - if (w >= 3) { - /* multiply w by [1/3] */ - t = (w * ((mp_word)b)) >> ((mp_word)DIGIT_BIT); - - /* now subtract 3 * [w/3] from w, to get the remainder */ - w -= t+t+t; - - /* fixup the remainder as required since - * the optimization is not exact. - */ - while (w >= 3) { - t += 1; - w -= 3; - } - } else { - t = 0; - } - q.dp[ix] = (mp_digit)t; - } - - /* [optional] store the remainder */ - if (d != NULL) { - *d = (mp_digit)w; - } - - /* [optional] store the quotient */ - if (c != NULL) { - mp_clamp(&q); - mp_exch(&q, c); - } - mp_clear(&q); - - return res; -} - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_div_d.c b/external/libtommath-0.42.0/bn_mp_div_d.c deleted file mode 100755 index ca34e87..0000000 --- a/external/libtommath-0.42.0/bn_mp_div_d.c +++ /dev/null @@ -1,115 +0,0 @@ -#include -#ifdef BN_MP_DIV_D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -static int s_is_power_of_two(mp_digit b, int *p) -{ - int x; - - /* fast return if no power of two */ - if ((b==0) || (b & (b-1))) { - return 0; - } - - for (x = 0; x < DIGIT_BIT; x++) { - if (b == (((mp_digit)1)<dp[0] & ((((mp_digit)1)<used)) != MP_OKAY) { - return res; - } - - q.used = a->used; - q.sign = a->sign; - w = 0; - for (ix = a->used - 1; ix >= 0; ix--) { - w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]); - - if (w >= b) { - t = (mp_digit)(w / b); - w -= ((mp_word)t) * ((mp_word)b); - } else { - t = 0; - } - q.dp[ix] = (mp_digit)t; - } - - if (d != NULL) { - *d = (mp_digit)w; - } - - if (c != NULL) { - mp_clamp(&q); - mp_exch(&q, c); - } - mp_clear(&q); - - return res; -} - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_dr_is_modulus.c b/external/libtommath-0.42.0/bn_mp_dr_is_modulus.c deleted file mode 100755 index 52b4fdf..0000000 --- a/external/libtommath-0.42.0/bn_mp_dr_is_modulus.c +++ /dev/null @@ -1,43 +0,0 @@ -#include -#ifdef BN_MP_DR_IS_MODULUS_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* determines if a number is a valid DR modulus */ -int mp_dr_is_modulus(mp_int *a) -{ - int ix; - - /* must be at least two digits */ - if (a->used < 2) { - return 0; - } - - /* must be of the form b**k - a [a <= b] so all - * but the first digit must be equal to -1 (mod b). - */ - for (ix = 1; ix < a->used; ix++) { - if (a->dp[ix] != MP_MASK) { - return 0; - } - } - return 1; -} - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_dr_reduce.c b/external/libtommath-0.42.0/bn_mp_dr_reduce.c deleted file mode 100755 index 47f0c60..0000000 --- a/external/libtommath-0.42.0/bn_mp_dr_reduce.c +++ /dev/null @@ -1,94 +0,0 @@ -#include -#ifdef BN_MP_DR_REDUCE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* reduce "x" in place modulo "n" using the Diminished Radix algorithm. - * - * Based on algorithm from the paper - * - * "Generating Efficient Primes for Discrete Log Cryptosystems" - * Chae Hoon Lim, Pil Joong Lee, - * POSTECH Information Research Laboratories - * - * The modulus must be of a special format [see manual] - * - * Has been modified to use algorithm 7.10 from the LTM book instead - * - * Input x must be in the range 0 <= x <= (n-1)**2 - */ -int -mp_dr_reduce (mp_int * x, mp_int * n, mp_digit k) -{ - int err, i, m; - mp_word r; - mp_digit mu, *tmpx1, *tmpx2; - - /* m = digits in modulus */ - m = n->used; - - /* ensure that "x" has at least 2m digits */ - if (x->alloc < m + m) { - if ((err = mp_grow (x, m + m)) != MP_OKAY) { - return err; - } - } - -/* top of loop, this is where the code resumes if - * another reduction pass is required. - */ -top: - /* aliases for digits */ - /* alias for lower half of x */ - tmpx1 = x->dp; - - /* alias for upper half of x, or x/B**m */ - tmpx2 = x->dp + m; - - /* set carry to zero */ - mu = 0; - - /* compute (x mod B**m) + k * [x/B**m] inline and inplace */ - for (i = 0; i < m; i++) { - r = ((mp_word)*tmpx2++) * ((mp_word)k) + *tmpx1 + mu; - *tmpx1++ = (mp_digit)(r & MP_MASK); - mu = (mp_digit)(r >> ((mp_word)DIGIT_BIT)); - } - - /* set final carry */ - *tmpx1++ = mu; - - /* zero words above m */ - for (i = m + 1; i < x->used; i++) { - *tmpx1++ = 0; - } - - /* clamp, sub and return */ - mp_clamp (x); - - /* if x >= n then subtract and reduce again - * Each successive "recursion" makes the input smaller and smaller. - */ - if (mp_cmp_mag (x, n) != MP_LT) { - s_mp_sub(x, n, x); - goto top; - } - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_dr_setup.c b/external/libtommath-0.42.0/bn_mp_dr_setup.c deleted file mode 100755 index 99ee67d..0000000 --- a/external/libtommath-0.42.0/bn_mp_dr_setup.c +++ /dev/null @@ -1,32 +0,0 @@ -#include -#ifdef BN_MP_DR_SETUP_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* determines the setup value */ -void mp_dr_setup(mp_int *a, mp_digit *d) -{ - /* the casts are required if DIGIT_BIT is one less than - * the number of bits in a mp_digit [e.g. DIGIT_BIT==31] - */ - *d = (mp_digit)((((mp_word)1) << ((mp_word)DIGIT_BIT)) - - ((mp_word)a->dp[0])); -} - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_exch.c b/external/libtommath-0.42.0/bn_mp_exch.c deleted file mode 100755 index dd3098e..0000000 --- a/external/libtommath-0.42.0/bn_mp_exch.c +++ /dev/null @@ -1,34 +0,0 @@ -#include -#ifdef BN_MP_EXCH_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* swap the elements of two integers, for cases where you can't simply swap the - * mp_int pointers around - */ -void -mp_exch (mp_int * a, mp_int * b) -{ - mp_int t; - - t = *a; - *a = *b; - *b = t; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_expt_d.c b/external/libtommath-0.42.0/bn_mp_expt_d.c deleted file mode 100755 index f9357cc..0000000 --- a/external/libtommath-0.42.0/bn_mp_expt_d.c +++ /dev/null @@ -1,57 +0,0 @@ -#include -#ifdef BN_MP_EXPT_D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* calculate c = a**b using a square-multiply algorithm */ -int mp_expt_d (mp_int * a, mp_digit b, mp_int * c) -{ - int res, x; - mp_int g; - - if ((res = mp_init_copy (&g, a)) != MP_OKAY) { - return res; - } - - /* set initial result */ - mp_set (c, 1); - - for (x = 0; x < (int) DIGIT_BIT; x++) { - /* square */ - if ((res = mp_sqr (c, c)) != MP_OKAY) { - mp_clear (&g); - return res; - } - - /* if the bit is set multiply */ - if ((b & (mp_digit) (((mp_digit)1) << (DIGIT_BIT - 1))) != 0) { - if ((res = mp_mul (c, &g, c)) != MP_OKAY) { - mp_clear (&g); - return res; - } - } - - /* shift to next bit */ - b <<= 1; - } - - mp_clear (&g); - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_exptmod.c b/external/libtommath-0.42.0/bn_mp_exptmod.c deleted file mode 100755 index 8fbce19..0000000 --- a/external/libtommath-0.42.0/bn_mp_exptmod.c +++ /dev/null @@ -1,112 +0,0 @@ -#include -#ifdef BN_MP_EXPTMOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - - -/* this is a shell function that calls either the normal or Montgomery - * exptmod functions. Originally the call to the montgomery code was - * embedded in the normal function but that wasted alot of stack space - * for nothing (since 99% of the time the Montgomery code would be called) - */ -int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) -{ - int dr; - - /* modulus P must be positive */ - if (P->sign == MP_NEG) { - return MP_VAL; - } - - /* if exponent X is negative we have to recurse */ - if (X->sign == MP_NEG) { -#ifdef BN_MP_INVMOD_C - mp_int tmpG, tmpX; - int err; - - /* first compute 1/G mod P */ - if ((err = mp_init(&tmpG)) != MP_OKAY) { - return err; - } - if ((err = mp_invmod(G, P, &tmpG)) != MP_OKAY) { - mp_clear(&tmpG); - return err; - } - - /* now get |X| */ - if ((err = mp_init(&tmpX)) != MP_OKAY) { - mp_clear(&tmpG); - return err; - } - if ((err = mp_abs(X, &tmpX)) != MP_OKAY) { - mp_clear_multi(&tmpG, &tmpX, NULL); - return err; - } - - /* and now compute (1/G)**|X| instead of G**X [X < 0] */ - err = mp_exptmod(&tmpG, &tmpX, P, Y); - mp_clear_multi(&tmpG, &tmpX, NULL); - return err; -#else - /* no invmod */ - return MP_VAL; -#endif - } - -/* modified diminished radix reduction */ -#if defined(BN_MP_REDUCE_IS_2K_L_C) && defined(BN_MP_REDUCE_2K_L_C) && defined(BN_S_MP_EXPTMOD_C) - if (mp_reduce_is_2k_l(P) == MP_YES) { - return s_mp_exptmod(G, X, P, Y, 1); - } -#endif - -#ifdef BN_MP_DR_IS_MODULUS_C - /* is it a DR modulus? */ - dr = mp_dr_is_modulus(P); -#else - /* default to no */ - dr = 0; -#endif - -#ifdef BN_MP_REDUCE_IS_2K_C - /* if not, is it a unrestricted DR modulus? */ - if (dr == 0) { - dr = mp_reduce_is_2k(P) << 1; - } -#endif - - /* if the modulus is odd or dr != 0 use the montgomery method */ -#ifdef BN_MP_EXPTMOD_FAST_C - if (mp_isodd (P) == 1 || dr != 0) { - return mp_exptmod_fast (G, X, P, Y, dr); - } else { -#endif -#ifdef BN_S_MP_EXPTMOD_C - /* otherwise use the generic Barrett reduction technique */ - return s_mp_exptmod (G, X, P, Y, 0); -#else - /* no exptmod for evens */ - return MP_VAL; -#endif -#ifdef BN_MP_EXPTMOD_FAST_C - } -#endif -} - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_exptmod_fast.c b/external/libtommath-0.42.0/bn_mp_exptmod_fast.c deleted file mode 100755 index 60c7e2b..0000000 --- a/external/libtommath-0.42.0/bn_mp_exptmod_fast.c +++ /dev/null @@ -1,321 +0,0 @@ -#include -#ifdef BN_MP_EXPTMOD_FAST_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* computes Y == G**X mod P, HAC pp.616, Algorithm 14.85 - * - * Uses a left-to-right k-ary sliding window to compute the modular exponentiation. - * The value of k changes based on the size of the exponent. - * - * Uses Montgomery or Diminished Radix reduction [whichever appropriate] - */ - -#ifdef MP_LOW_MEM - #define TAB_SIZE 32 -#else - #define TAB_SIZE 256 -#endif - -int mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) -{ - mp_int M[TAB_SIZE], res; - mp_digit buf, mp; - int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize; - - /* use a pointer to the reduction algorithm. This allows us to use - * one of many reduction algorithms without modding the guts of - * the code with if statements everywhere. - */ - int (*redux)(mp_int*,mp_int*,mp_digit); - - /* find window size */ - x = mp_count_bits (X); - if (x <= 7) { - winsize = 2; - } else if (x <= 36) { - winsize = 3; - } else if (x <= 140) { - winsize = 4; - } else if (x <= 450) { - winsize = 5; - } else if (x <= 1303) { - winsize = 6; - } else if (x <= 3529) { - winsize = 7; - } else { - winsize = 8; - } - -#ifdef MP_LOW_MEM - if (winsize > 5) { - winsize = 5; - } -#endif - - /* init M array */ - /* init first cell */ - if ((err = mp_init(&M[1])) != MP_OKAY) { - return err; - } - - /* now init the second half of the array */ - for (x = 1<<(winsize-1); x < (1 << winsize); x++) { - if ((err = mp_init(&M[x])) != MP_OKAY) { - for (y = 1<<(winsize-1); y < x; y++) { - mp_clear (&M[y]); - } - mp_clear(&M[1]); - return err; - } - } - - /* determine and setup reduction code */ - if (redmode == 0) { -#ifdef BN_MP_MONTGOMERY_SETUP_C - /* now setup montgomery */ - if ((err = mp_montgomery_setup (P, &mp)) != MP_OKAY) { - goto LBL_M; - } -#else - err = MP_VAL; - goto LBL_M; -#endif - - /* automatically pick the comba one if available (saves quite a few calls/ifs) */ -#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C - if (((P->used * 2 + 1) < MP_WARRAY) && - P->used < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { - redux = fast_mp_montgomery_reduce; - } else -#endif - { -#ifdef BN_MP_MONTGOMERY_REDUCE_C - /* use slower baseline Montgomery method */ - redux = mp_montgomery_reduce; -#else - err = MP_VAL; - goto LBL_M; -#endif - } - } else if (redmode == 1) { -#if defined(BN_MP_DR_SETUP_C) && defined(BN_MP_DR_REDUCE_C) - /* setup DR reduction for moduli of the form B**k - b */ - mp_dr_setup(P, &mp); - redux = mp_dr_reduce; -#else - err = MP_VAL; - goto LBL_M; -#endif - } else { -#if defined(BN_MP_REDUCE_2K_SETUP_C) && defined(BN_MP_REDUCE_2K_C) - /* setup DR reduction for moduli of the form 2**k - b */ - if ((err = mp_reduce_2k_setup(P, &mp)) != MP_OKAY) { - goto LBL_M; - } - redux = mp_reduce_2k; -#else - err = MP_VAL; - goto LBL_M; -#endif - } - - /* setup result */ - if ((err = mp_init (&res)) != MP_OKAY) { - goto LBL_M; - } - - /* create M table - * - - * - * The first half of the table is not computed though accept for M[0] and M[1] - */ - - if (redmode == 0) { -#ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C - /* now we need R mod m */ - if ((err = mp_montgomery_calc_normalization (&res, P)) != MP_OKAY) { - goto LBL_RES; - } -#else - err = MP_VAL; - goto LBL_RES; -#endif - - /* now set M[1] to G * R mod m */ - if ((err = mp_mulmod (G, &res, P, &M[1])) != MP_OKAY) { - goto LBL_RES; - } - } else { - mp_set(&res, 1); - if ((err = mp_mod(G, P, &M[1])) != MP_OKAY) { - goto LBL_RES; - } - } - - /* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times */ - if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) { - goto LBL_RES; - } - - for (x = 0; x < (winsize - 1); x++) { - if ((err = mp_sqr (&M[1 << (winsize - 1)], &M[1 << (winsize - 1)])) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&M[1 << (winsize - 1)], P, mp)) != MP_OKAY) { - goto LBL_RES; - } - } - - /* create upper table */ - for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) { - if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&M[x], P, mp)) != MP_OKAY) { - goto LBL_RES; - } - } - - /* set initial mode and bit cnt */ - mode = 0; - bitcnt = 1; - buf = 0; - digidx = X->used - 1; - bitcpy = 0; - bitbuf = 0; - - for (;;) { - /* grab next digit as required */ - if (--bitcnt == 0) { - /* if digidx == -1 we are out of digits so break */ - if (digidx == -1) { - break; - } - /* read next digit and reset bitcnt */ - buf = X->dp[digidx--]; - bitcnt = (int)DIGIT_BIT; - } - - /* grab the next msb from the exponent */ - y = (mp_digit)(buf >> (DIGIT_BIT - 1)) & 1; - buf <<= (mp_digit)1; - - /* if the bit is zero and mode == 0 then we ignore it - * These represent the leading zero bits before the first 1 bit - * in the exponent. Technically this opt is not required but it - * does lower the # of trivial squaring/reductions used - */ - if (mode == 0 && y == 0) { - continue; - } - - /* if the bit is zero and mode == 1 then we square */ - if (mode == 1 && y == 0) { - if ((err = mp_sqr (&res, &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, mp)) != MP_OKAY) { - goto LBL_RES; - } - continue; - } - - /* else we add it to the window */ - bitbuf |= (y << (winsize - ++bitcpy)); - mode = 2; - - if (bitcpy == winsize) { - /* ok window is filled so square as required and multiply */ - /* square first */ - for (x = 0; x < winsize; x++) { - if ((err = mp_sqr (&res, &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, mp)) != MP_OKAY) { - goto LBL_RES; - } - } - - /* then multiply */ - if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, mp)) != MP_OKAY) { - goto LBL_RES; - } - - /* empty window and reset */ - bitcpy = 0; - bitbuf = 0; - mode = 1; - } - } - - /* if bits remain then square/multiply */ - if (mode == 2 && bitcpy > 0) { - /* square then multiply if the bit is set */ - for (x = 0; x < bitcpy; x++) { - if ((err = mp_sqr (&res, &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, mp)) != MP_OKAY) { - goto LBL_RES; - } - - /* get next bit of the window */ - bitbuf <<= 1; - if ((bitbuf & (1 << winsize)) != 0) { - /* then multiply */ - if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, mp)) != MP_OKAY) { - goto LBL_RES; - } - } - } - } - - if (redmode == 0) { - /* fixup result if Montgomery reduction is used - * recall that any value in a Montgomery system is - * actually multiplied by R mod n. So we have - * to reduce one more time to cancel out the factor - * of R. - */ - if ((err = redux(&res, P, mp)) != MP_OKAY) { - goto LBL_RES; - } - } - - /* swap res with Y */ - mp_exch (&res, Y); - err = MP_OKAY; -LBL_RES:mp_clear (&res); -LBL_M: - mp_clear(&M[1]); - for (x = 1<<(winsize-1); x < (1 << winsize); x++) { - mp_clear (&M[x]); - } - return err; -} -#endif - - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_exteuclid.c b/external/libtommath-0.42.0/bn_mp_exteuclid.c deleted file mode 100755 index c65928d..0000000 --- a/external/libtommath-0.42.0/bn_mp_exteuclid.c +++ /dev/null @@ -1,82 +0,0 @@ -#include -#ifdef BN_MP_EXTEUCLID_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* Extended euclidean algorithm of (a, b) produces - a*u1 + b*u2 = u3 - */ -int mp_exteuclid(mp_int *a, mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3) -{ - mp_int u1,u2,u3,v1,v2,v3,t1,t2,t3,q,tmp; - int err; - - if ((err = mp_init_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL)) != MP_OKAY) { - return err; - } - - /* initialize, (u1,u2,u3) = (1,0,a) */ - mp_set(&u1, 1); - if ((err = mp_copy(a, &u3)) != MP_OKAY) { goto _ERR; } - - /* initialize, (v1,v2,v3) = (0,1,b) */ - mp_set(&v2, 1); - if ((err = mp_copy(b, &v3)) != MP_OKAY) { goto _ERR; } - - /* loop while v3 != 0 */ - while (mp_iszero(&v3) == MP_NO) { - /* q = u3/v3 */ - if ((err = mp_div(&u3, &v3, &q, NULL)) != MP_OKAY) { goto _ERR; } - - /* (t1,t2,t3) = (u1,u2,u3) - (v1,v2,v3)q */ - if ((err = mp_mul(&v1, &q, &tmp)) != MP_OKAY) { goto _ERR; } - if ((err = mp_sub(&u1, &tmp, &t1)) != MP_OKAY) { goto _ERR; } - if ((err = mp_mul(&v2, &q, &tmp)) != MP_OKAY) { goto _ERR; } - if ((err = mp_sub(&u2, &tmp, &t2)) != MP_OKAY) { goto _ERR; } - if ((err = mp_mul(&v3, &q, &tmp)) != MP_OKAY) { goto _ERR; } - if ((err = mp_sub(&u3, &tmp, &t3)) != MP_OKAY) { goto _ERR; } - - /* (u1,u2,u3) = (v1,v2,v3) */ - if ((err = mp_copy(&v1, &u1)) != MP_OKAY) { goto _ERR; } - if ((err = mp_copy(&v2, &u2)) != MP_OKAY) { goto _ERR; } - if ((err = mp_copy(&v3, &u3)) != MP_OKAY) { goto _ERR; } - - /* (v1,v2,v3) = (t1,t2,t3) */ - if ((err = mp_copy(&t1, &v1)) != MP_OKAY) { goto _ERR; } - if ((err = mp_copy(&t2, &v2)) != MP_OKAY) { goto _ERR; } - if ((err = mp_copy(&t3, &v3)) != MP_OKAY) { goto _ERR; } - } - - /* make sure U3 >= 0 */ - if (u3.sign == MP_NEG) { - mp_neg(&u1, &u1); - mp_neg(&u2, &u2); - mp_neg(&u3, &u3); - } - - /* copy result out */ - if (U1 != NULL) { mp_exch(U1, &u1); } - if (U2 != NULL) { mp_exch(U2, &u2); } - if (U3 != NULL) { mp_exch(U3, &u3); } - - err = MP_OKAY; -_ERR: mp_clear_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL); - return err; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_fread.c b/external/libtommath-0.42.0/bn_mp_fread.c deleted file mode 100755 index a2e51a1..0000000 --- a/external/libtommath-0.42.0/bn_mp_fread.c +++ /dev/null @@ -1,67 +0,0 @@ -#include -#ifdef BN_MP_FREAD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* read a bigint from a file stream in ASCII */ -int mp_fread(mp_int *a, int radix, FILE *stream) -{ - int err, ch, neg, y; - - /* clear a */ - mp_zero(a); - - /* if first digit is - then set negative */ - ch = fgetc(stream); - if (ch == '-') { - neg = MP_NEG; - ch = fgetc(stream); - } else { - neg = MP_ZPOS; - } - - for (;;) { - /* find y in the radix map */ - for (y = 0; y < radix; y++) { - if (mp_s_rmap[y] == ch) { - break; - } - } - if (y == radix) { - break; - } - - /* shift up and add */ - if ((err = mp_mul_d(a, radix, a)) != MP_OKAY) { - return err; - } - if ((err = mp_add_d(a, y, a)) != MP_OKAY) { - return err; - } - - ch = fgetc(stream); - } - if (mp_cmp_d(a, 0) != MP_EQ) { - a->sign = neg; - } - - return MP_OKAY; -} - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_fwrite.c b/external/libtommath-0.42.0/bn_mp_fwrite.c deleted file mode 100755 index b3fd834..0000000 --- a/external/libtommath-0.42.0/bn_mp_fwrite.c +++ /dev/null @@ -1,52 +0,0 @@ -#include -#ifdef BN_MP_FWRITE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -int mp_fwrite(mp_int *a, int radix, FILE *stream) -{ - char *buf; - int err, len, x; - - if ((err = mp_radix_size(a, radix, &len)) != MP_OKAY) { - return err; - } - - buf = OPT_CAST(char) XMALLOC (len); - if (buf == NULL) { - return MP_MEM; - } - - if ((err = mp_toradix(a, buf, radix)) != MP_OKAY) { - XFREE (buf); - return err; - } - - for (x = 0; x < len; x++) { - if (fputc(buf[x], stream) == EOF) { - XFREE (buf); - return MP_VAL; - } - } - - XFREE (buf); - return MP_OKAY; -} - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_gcd.c b/external/libtommath-0.42.0/bn_mp_gcd.c deleted file mode 100755 index b45cfed..0000000 --- a/external/libtommath-0.42.0/bn_mp_gcd.c +++ /dev/null @@ -1,105 +0,0 @@ -#include -#ifdef BN_MP_GCD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* Greatest Common Divisor using the binary method */ -int mp_gcd (mp_int * a, mp_int * b, mp_int * c) -{ - mp_int u, v; - int k, u_lsb, v_lsb, res; - - /* either zero than gcd is the largest */ - if (mp_iszero (a) == MP_YES) { - return mp_abs (b, c); - } - if (mp_iszero (b) == MP_YES) { - return mp_abs (a, c); - } - - /* get copies of a and b we can modify */ - if ((res = mp_init_copy (&u, a)) != MP_OKAY) { - return res; - } - - if ((res = mp_init_copy (&v, b)) != MP_OKAY) { - goto LBL_U; - } - - /* must be positive for the remainder of the algorithm */ - u.sign = v.sign = MP_ZPOS; - - /* B1. Find the common power of two for u and v */ - u_lsb = mp_cnt_lsb(&u); - v_lsb = mp_cnt_lsb(&v); - k = MIN(u_lsb, v_lsb); - - if (k > 0) { - /* divide the power of two out */ - if ((res = mp_div_2d(&u, k, &u, NULL)) != MP_OKAY) { - goto LBL_V; - } - - if ((res = mp_div_2d(&v, k, &v, NULL)) != MP_OKAY) { - goto LBL_V; - } - } - - /* divide any remaining factors of two out */ - if (u_lsb != k) { - if ((res = mp_div_2d(&u, u_lsb - k, &u, NULL)) != MP_OKAY) { - goto LBL_V; - } - } - - if (v_lsb != k) { - if ((res = mp_div_2d(&v, v_lsb - k, &v, NULL)) != MP_OKAY) { - goto LBL_V; - } - } - - while (mp_iszero(&v) == 0) { - /* make sure v is the largest */ - if (mp_cmp_mag(&u, &v) == MP_GT) { - /* swap u and v to make sure v is >= u */ - mp_exch(&u, &v); - } - - /* subtract smallest from largest */ - if ((res = s_mp_sub(&v, &u, &v)) != MP_OKAY) { - goto LBL_V; - } - - /* Divide out all factors of two */ - if ((res = mp_div_2d(&v, mp_cnt_lsb(&v), &v, NULL)) != MP_OKAY) { - goto LBL_V; - } - } - - /* multiply by 2**k which we divided out at the beginning */ - if ((res = mp_mul_2d (&u, k, c)) != MP_OKAY) { - goto LBL_V; - } - c->sign = MP_ZPOS; - res = MP_OKAY; -LBL_V:mp_clear (&u); -LBL_U:mp_clear (&v); - return res; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_get_int.c b/external/libtommath-0.42.0/bn_mp_get_int.c deleted file mode 100755 index 11baa0e..0000000 --- a/external/libtommath-0.42.0/bn_mp_get_int.c +++ /dev/null @@ -1,45 +0,0 @@ -#include -#ifdef BN_MP_GET_INT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* get the lower 32-bits of an mp_int */ -unsigned long mp_get_int(mp_int * a) -{ - int i; - unsigned long res; - - if (a->used == 0) { - return 0; - } - - /* get number of digits of the lsb we have to read */ - i = MIN(a->used,(int)((sizeof(unsigned long)*CHAR_BIT+DIGIT_BIT-1)/DIGIT_BIT))-1; - - /* get most significant digit of result */ - res = DIGIT(a,i); - - while (--i >= 0) { - res = (res << DIGIT_BIT) | DIGIT(a,i); - } - - /* force result to 32-bits always so it is consistent on non 32-bit platforms */ - return res & 0xFFFFFFFFUL; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_grow.c b/external/libtommath-0.42.0/bn_mp_grow.c deleted file mode 100755 index f1c1cab..0000000 --- a/external/libtommath-0.42.0/bn_mp_grow.c +++ /dev/null @@ -1,57 +0,0 @@ -#include -#ifdef BN_MP_GROW_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* grow as required */ -int mp_grow (mp_int * a, int size) -{ - int i; - mp_digit *tmp; - - /* if the alloc size is smaller alloc more ram */ - if (a->alloc < size) { - /* ensure there are always at least MP_PREC digits extra on top */ - size += (MP_PREC * 2) - (size % MP_PREC); - - /* reallocate the array a->dp - * - * We store the return in a temporary variable - * in case the operation failed we don't want - * to overwrite the dp member of a. - */ - tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * size); - if (tmp == NULL) { - /* reallocation failed but "a" is still valid [can be freed] */ - return MP_MEM; - } - - /* reallocation succeeded so set a->dp */ - a->dp = tmp; - - /* zero excess digits */ - i = a->alloc; - a->alloc = size; - for (; i < a->alloc; i++) { - a->dp[i] = 0; - } - } - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_init.c b/external/libtommath-0.42.0/bn_mp_init.c deleted file mode 100755 index 79cca3c..0000000 --- a/external/libtommath-0.42.0/bn_mp_init.c +++ /dev/null @@ -1,46 +0,0 @@ -#include -#ifdef BN_MP_INIT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* init a new mp_int */ -int mp_init (mp_int * a) -{ - int i; - - /* allocate memory required and clear it */ - a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * MP_PREC); - if (a->dp == NULL) { - return MP_MEM; - } - - /* set the digits to zero */ - for (i = 0; i < MP_PREC; i++) { - a->dp[i] = 0; - } - - /* set the used to zero, allocated digits to the default precision - * and sign to positive */ - a->used = 0; - a->alloc = MP_PREC; - a->sign = MP_ZPOS; - - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_init_copy.c b/external/libtommath-0.42.0/bn_mp_init_copy.c deleted file mode 100755 index 8ce0ef9..0000000 --- a/external/libtommath-0.42.0/bn_mp_init_copy.c +++ /dev/null @@ -1,32 +0,0 @@ -#include -#ifdef BN_MP_INIT_COPY_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* creates "a" then copies b into it */ -int mp_init_copy (mp_int * a, mp_int * b) -{ - int res; - - if ((res = mp_init (a)) != MP_OKAY) { - return res; - } - return mp_copy (b, a); -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_init_multi.c b/external/libtommath-0.42.0/bn_mp_init_multi.c deleted file mode 100755 index a40ea8e..0000000 --- a/external/libtommath-0.42.0/bn_mp_init_multi.c +++ /dev/null @@ -1,59 +0,0 @@ -#include -#ifdef BN_MP_INIT_MULTI_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include - -int mp_init_multi(mp_int *mp, ...) -{ - mp_err res = MP_OKAY; /* Assume ok until proven otherwise */ - int n = 0; /* Number of ok inits */ - mp_int* cur_arg = mp; - va_list args; - - va_start(args, mp); /* init args to next argument from caller */ - while (cur_arg != NULL) { - if (mp_init(cur_arg) != MP_OKAY) { - /* Oops - error! Back-track and mp_clear what we already - succeeded in init-ing, then return error. - */ - va_list clean_args; - - /* end the current list */ - va_end(args); - - /* now start cleaning up */ - cur_arg = mp; - va_start(clean_args, mp); - while (n--) { - mp_clear(cur_arg); - cur_arg = va_arg(clean_args, mp_int*); - } - va_end(clean_args); - res = MP_MEM; - break; - } - n++; - cur_arg = va_arg(args, mp_int*); - } - va_end(args); - return res; /* Assumed ok, if error flagged above. */ -} - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_init_set.c b/external/libtommath-0.42.0/bn_mp_init_set.c deleted file mode 100755 index f9b08e9..0000000 --- a/external/libtommath-0.42.0/bn_mp_init_set.c +++ /dev/null @@ -1,32 +0,0 @@ -#include -#ifdef BN_MP_INIT_SET_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* initialize and set a digit */ -int mp_init_set (mp_int * a, mp_digit b) -{ - int err; - if ((err = mp_init(a)) != MP_OKAY) { - return err; - } - mp_set(a, b); - return err; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_init_set_int.c b/external/libtommath-0.42.0/bn_mp_init_set_int.c deleted file mode 100755 index 9473c3f..0000000 --- a/external/libtommath-0.42.0/bn_mp_init_set_int.c +++ /dev/null @@ -1,31 +0,0 @@ -#include -#ifdef BN_MP_INIT_SET_INT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* initialize and set a digit */ -int mp_init_set_int (mp_int * a, unsigned long b) -{ - int err; - if ((err = mp_init(a)) != MP_OKAY) { - return err; - } - return mp_set_int(a, b); -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_init_size.c b/external/libtommath-0.42.0/bn_mp_init_size.c deleted file mode 100755 index 69dd49c..0000000 --- a/external/libtommath-0.42.0/bn_mp_init_size.c +++ /dev/null @@ -1,48 +0,0 @@ -#include -#ifdef BN_MP_INIT_SIZE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* init an mp_init for a given size */ -int mp_init_size (mp_int * a, int size) -{ - int x; - - /* pad size so there are always extra digits */ - size += (MP_PREC * 2) - (size % MP_PREC); - - /* alloc mem */ - a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * size); - if (a->dp == NULL) { - return MP_MEM; - } - - /* set the members */ - a->used = 0; - a->alloc = size; - a->sign = MP_ZPOS; - - /* zero the digits */ - for (x = 0; x < size; x++) { - a->dp[x] = 0; - } - - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_invmod.c b/external/libtommath-0.42.0/bn_mp_invmod.c deleted file mode 100755 index f4bdc17..0000000 --- a/external/libtommath-0.42.0/bn_mp_invmod.c +++ /dev/null @@ -1,43 +0,0 @@ -#include -#ifdef BN_MP_INVMOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* hac 14.61, pp608 */ -int mp_invmod (mp_int * a, mp_int * b, mp_int * c) -{ - /* b cannot be negative */ - if (b->sign == MP_NEG || mp_iszero(b) == 1) { - return MP_VAL; - } - -#ifdef BN_FAST_MP_INVMOD_C - /* if the modulus is odd we can use a faster routine instead */ - if (mp_isodd (b) == 1) { - return fast_mp_invmod (a, b, c); - } -#endif - -#ifdef BN_MP_INVMOD_SLOW_C - return mp_invmod_slow(a, b, c); -#endif - - return MP_VAL; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_invmod_slow.c b/external/libtommath-0.42.0/bn_mp_invmod_slow.c deleted file mode 100755 index 2430f02..0000000 --- a/external/libtommath-0.42.0/bn_mp_invmod_slow.c +++ /dev/null @@ -1,175 +0,0 @@ -#include -#ifdef BN_MP_INVMOD_SLOW_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* hac 14.61, pp608 */ -int mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c) -{ - mp_int x, y, u, v, A, B, C, D; - int res; - - /* b cannot be negative */ - if (b->sign == MP_NEG || mp_iszero(b) == 1) { - return MP_VAL; - } - - /* init temps */ - if ((res = mp_init_multi(&x, &y, &u, &v, - &A, &B, &C, &D, NULL)) != MP_OKAY) { - return res; - } - - /* x = a, y = b */ - if ((res = mp_mod(a, b, &x)) != MP_OKAY) { - goto LBL_ERR; - } - if ((res = mp_copy (b, &y)) != MP_OKAY) { - goto LBL_ERR; - } - - /* 2. [modified] if x,y are both even then return an error! */ - if (mp_iseven (&x) == 1 && mp_iseven (&y) == 1) { - res = MP_VAL; - goto LBL_ERR; - } - - /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */ - if ((res = mp_copy (&x, &u)) != MP_OKAY) { - goto LBL_ERR; - } - if ((res = mp_copy (&y, &v)) != MP_OKAY) { - goto LBL_ERR; - } - mp_set (&A, 1); - mp_set (&D, 1); - -top: - /* 4. while u is even do */ - while (mp_iseven (&u) == 1) { - /* 4.1 u = u/2 */ - if ((res = mp_div_2 (&u, &u)) != MP_OKAY) { - goto LBL_ERR; - } - /* 4.2 if A or B is odd then */ - if (mp_isodd (&A) == 1 || mp_isodd (&B) == 1) { - /* A = (A+y)/2, B = (B-x)/2 */ - if ((res = mp_add (&A, &y, &A)) != MP_OKAY) { - goto LBL_ERR; - } - if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) { - goto LBL_ERR; - } - } - /* A = A/2, B = B/2 */ - if ((res = mp_div_2 (&A, &A)) != MP_OKAY) { - goto LBL_ERR; - } - if ((res = mp_div_2 (&B, &B)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* 5. while v is even do */ - while (mp_iseven (&v) == 1) { - /* 5.1 v = v/2 */ - if ((res = mp_div_2 (&v, &v)) != MP_OKAY) { - goto LBL_ERR; - } - /* 5.2 if C or D is odd then */ - if (mp_isodd (&C) == 1 || mp_isodd (&D) == 1) { - /* C = (C+y)/2, D = (D-x)/2 */ - if ((res = mp_add (&C, &y, &C)) != MP_OKAY) { - goto LBL_ERR; - } - if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) { - goto LBL_ERR; - } - } - /* C = C/2, D = D/2 */ - if ((res = mp_div_2 (&C, &C)) != MP_OKAY) { - goto LBL_ERR; - } - if ((res = mp_div_2 (&D, &D)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* 6. if u >= v then */ - if (mp_cmp (&u, &v) != MP_LT) { - /* u = u - v, A = A - C, B = B - D */ - if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) { - goto LBL_ERR; - } - - if ((res = mp_sub (&A, &C, &A)) != MP_OKAY) { - goto LBL_ERR; - } - - if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) { - goto LBL_ERR; - } - } else { - /* v - v - u, C = C - A, D = D - B */ - if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) { - goto LBL_ERR; - } - - if ((res = mp_sub (&C, &A, &C)) != MP_OKAY) { - goto LBL_ERR; - } - - if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* if not zero goto step 4 */ - if (mp_iszero (&u) == 0) - goto top; - - /* now a = C, b = D, gcd == g*v */ - - /* if v != 1 then there is no inverse */ - if (mp_cmp_d (&v, 1) != MP_EQ) { - res = MP_VAL; - goto LBL_ERR; - } - - /* if its too low */ - while (mp_cmp_d(&C, 0) == MP_LT) { - if ((res = mp_add(&C, b, &C)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* too big */ - while (mp_cmp_mag(&C, b) != MP_LT) { - if ((res = mp_sub(&C, b, &C)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* C is now the inverse */ - mp_exch (&C, c); - res = MP_OKAY; -LBL_ERR:mp_clear_multi (&x, &y, &u, &v, &A, &B, &C, &D, NULL); - return res; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_is_square.c b/external/libtommath-0.42.0/bn_mp_is_square.c deleted file mode 100755 index 12b9ec7..0000000 --- a/external/libtommath-0.42.0/bn_mp_is_square.c +++ /dev/null @@ -1,109 +0,0 @@ -#include -#ifdef BN_MP_IS_SQUARE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* Check if remainders are possible squares - fast exclude non-squares */ -static const char rem_128[128] = { - 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, - 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, - 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, - 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, - 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, - 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, - 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, - 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1 -}; - -static const char rem_105[105] = { - 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, - 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, - 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, - 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, - 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1 -}; - -/* Store non-zero to ret if arg is square, and zero if not */ -int mp_is_square(mp_int *arg,int *ret) -{ - int res; - mp_digit c; - mp_int t; - unsigned long r; - - /* Default to Non-square :) */ - *ret = MP_NO; - - if (arg->sign == MP_NEG) { - return MP_VAL; - } - - /* digits used? (TSD) */ - if (arg->used == 0) { - return MP_OKAY; - } - - /* First check mod 128 (suppose that DIGIT_BIT is at least 7) */ - if (rem_128[127 & DIGIT(arg,0)] == 1) { - return MP_OKAY; - } - - /* Next check mod 105 (3*5*7) */ - if ((res = mp_mod_d(arg,105,&c)) != MP_OKAY) { - return res; - } - if (rem_105[c] == 1) { - return MP_OKAY; - } - - - if ((res = mp_init_set_int(&t,11L*13L*17L*19L*23L*29L*31L)) != MP_OKAY) { - return res; - } - if ((res = mp_mod(arg,&t,&t)) != MP_OKAY) { - goto ERR; - } - r = mp_get_int(&t); - /* Check for other prime modules, note it's not an ERROR but we must - * free "t" so the easiest way is to goto ERR. We know that res - * is already equal to MP_OKAY from the mp_mod call - */ - if ( (1L<<(r%11)) & 0x5C4L ) goto ERR; - if ( (1L<<(r%13)) & 0x9E4L ) goto ERR; - if ( (1L<<(r%17)) & 0x5CE8L ) goto ERR; - if ( (1L<<(r%19)) & 0x4F50CL ) goto ERR; - if ( (1L<<(r%23)) & 0x7ACCA0L ) goto ERR; - if ( (1L<<(r%29)) & 0xC2EDD0CL ) goto ERR; - if ( (1L<<(r%31)) & 0x6DE2B848L ) goto ERR; - - /* Final check - is sqr(sqrt(arg)) == arg ? */ - if ((res = mp_sqrt(arg,&t)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sqr(&t,&t)) != MP_OKAY) { - goto ERR; - } - - *ret = (mp_cmp_mag(&t,arg) == MP_EQ) ? MP_YES : MP_NO; -ERR:mp_clear(&t); - return res; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_jacobi.c b/external/libtommath-0.42.0/bn_mp_jacobi.c deleted file mode 100755 index 07a9d65..0000000 --- a/external/libtommath-0.42.0/bn_mp_jacobi.c +++ /dev/null @@ -1,105 +0,0 @@ -#include -#ifdef BN_MP_JACOBI_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* computes the jacobi c = (a | n) (or Legendre if n is prime) - * HAC pp. 73 Algorithm 2.149 - */ -int mp_jacobi (mp_int * a, mp_int * p, int *c) -{ - mp_int a1, p1; - int k, s, r, res; - mp_digit residue; - - /* if p <= 0 return MP_VAL */ - if (mp_cmp_d(p, 0) != MP_GT) { - return MP_VAL; - } - - /* step 1. if a == 0, return 0 */ - if (mp_iszero (a) == 1) { - *c = 0; - return MP_OKAY; - } - - /* step 2. if a == 1, return 1 */ - if (mp_cmp_d (a, 1) == MP_EQ) { - *c = 1; - return MP_OKAY; - } - - /* default */ - s = 0; - - /* step 3. write a = a1 * 2**k */ - if ((res = mp_init_copy (&a1, a)) != MP_OKAY) { - return res; - } - - if ((res = mp_init (&p1)) != MP_OKAY) { - goto LBL_A1; - } - - /* divide out larger power of two */ - k = mp_cnt_lsb(&a1); - if ((res = mp_div_2d(&a1, k, &a1, NULL)) != MP_OKAY) { - goto LBL_P1; - } - - /* step 4. if e is even set s=1 */ - if ((k & 1) == 0) { - s = 1; - } else { - /* else set s=1 if p = 1/7 (mod 8) or s=-1 if p = 3/5 (mod 8) */ - residue = p->dp[0] & 7; - - if (residue == 1 || residue == 7) { - s = 1; - } else if (residue == 3 || residue == 5) { - s = -1; - } - } - - /* step 5. if p == 3 (mod 4) *and* a1 == 3 (mod 4) then s = -s */ - if ( ((p->dp[0] & 3) == 3) && ((a1.dp[0] & 3) == 3)) { - s = -s; - } - - /* if a1 == 1 we're done */ - if (mp_cmp_d (&a1, 1) == MP_EQ) { - *c = s; - } else { - /* n1 = n mod a1 */ - if ((res = mp_mod (p, &a1, &p1)) != MP_OKAY) { - goto LBL_P1; - } - if ((res = mp_jacobi (&p1, &a1, &r)) != MP_OKAY) { - goto LBL_P1; - } - *c = s * r; - } - - /* done */ - res = MP_OKAY; -LBL_P1:mp_clear (&p1); -LBL_A1:mp_clear (&a1); - return res; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_karatsuba_mul.c b/external/libtommath-0.42.0/bn_mp_karatsuba_mul.c deleted file mode 100755 index 62e885c..0000000 --- a/external/libtommath-0.42.0/bn_mp_karatsuba_mul.c +++ /dev/null @@ -1,167 +0,0 @@ -#include -#ifdef BN_MP_KARATSUBA_MUL_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* c = |a| * |b| using Karatsuba Multiplication using - * three half size multiplications - * - * Let B represent the radix [e.g. 2**DIGIT_BIT] and - * let n represent half of the number of digits in - * the min(a,b) - * - * a = a1 * B**n + a0 - * b = b1 * B**n + b0 - * - * Then, a * b => - a1b1 * B**2n + ((a1 + a0)(b1 + b0) - (a0b0 + a1b1)) * B + a0b0 - * - * Note that a1b1 and a0b0 are used twice and only need to be - * computed once. So in total three half size (half # of - * digit) multiplications are performed, a0b0, a1b1 and - * (a1+b1)(a0+b0) - * - * Note that a multiplication of half the digits requires - * 1/4th the number of single precision multiplications so in - * total after one call 25% of the single precision multiplications - * are saved. Note also that the call to mp_mul can end up back - * in this function if the a0, a1, b0, or b1 are above the threshold. - * This is known as divide-and-conquer and leads to the famous - * O(N**lg(3)) or O(N**1.584) work which is asymptopically lower than - * the standard O(N**2) that the baseline/comba methods use. - * Generally though the overhead of this method doesn't pay off - * until a certain size (N ~ 80) is reached. - */ -int mp_karatsuba_mul (mp_int * a, mp_int * b, mp_int * c) -{ - mp_int x0, x1, y0, y1, t1, x0y0, x1y1; - int B, err; - - /* default the return code to an error */ - err = MP_MEM; - - /* min # of digits */ - B = MIN (a->used, b->used); - - /* now divide in two */ - B = B >> 1; - - /* init copy all the temps */ - if (mp_init_size (&x0, B) != MP_OKAY) - goto ERR; - if (mp_init_size (&x1, a->used - B) != MP_OKAY) - goto X0; - if (mp_init_size (&y0, B) != MP_OKAY) - goto X1; - if (mp_init_size (&y1, b->used - B) != MP_OKAY) - goto Y0; - - /* init temps */ - if (mp_init_size (&t1, B * 2) != MP_OKAY) - goto Y1; - if (mp_init_size (&x0y0, B * 2) != MP_OKAY) - goto T1; - if (mp_init_size (&x1y1, B * 2) != MP_OKAY) - goto X0Y0; - - /* now shift the digits */ - x0.used = y0.used = B; - x1.used = a->used - B; - y1.used = b->used - B; - - { - register int x; - register mp_digit *tmpa, *tmpb, *tmpx, *tmpy; - - /* we copy the digits directly instead of using higher level functions - * since we also need to shift the digits - */ - tmpa = a->dp; - tmpb = b->dp; - - tmpx = x0.dp; - tmpy = y0.dp; - for (x = 0; x < B; x++) { - *tmpx++ = *tmpa++; - *tmpy++ = *tmpb++; - } - - tmpx = x1.dp; - for (x = B; x < a->used; x++) { - *tmpx++ = *tmpa++; - } - - tmpy = y1.dp; - for (x = B; x < b->used; x++) { - *tmpy++ = *tmpb++; - } - } - - /* only need to clamp the lower words since by definition the - * upper words x1/y1 must have a known number of digits - */ - mp_clamp (&x0); - mp_clamp (&y0); - - /* now calc the products x0y0 and x1y1 */ - /* after this x0 is no longer required, free temp [x0==t2]! */ - if (mp_mul (&x0, &y0, &x0y0) != MP_OKAY) - goto X1Y1; /* x0y0 = x0*y0 */ - if (mp_mul (&x1, &y1, &x1y1) != MP_OKAY) - goto X1Y1; /* x1y1 = x1*y1 */ - - /* now calc x1+x0 and y1+y0 */ - if (s_mp_add (&x1, &x0, &t1) != MP_OKAY) - goto X1Y1; /* t1 = x1 - x0 */ - if (s_mp_add (&y1, &y0, &x0) != MP_OKAY) - goto X1Y1; /* t2 = y1 - y0 */ - if (mp_mul (&t1, &x0, &t1) != MP_OKAY) - goto X1Y1; /* t1 = (x1 + x0) * (y1 + y0) */ - - /* add x0y0 */ - if (mp_add (&x0y0, &x1y1, &x0) != MP_OKAY) - goto X1Y1; /* t2 = x0y0 + x1y1 */ - if (s_mp_sub (&t1, &x0, &t1) != MP_OKAY) - goto X1Y1; /* t1 = (x1+x0)*(y1+y0) - (x1y1 + x0y0) */ - - /* shift by B */ - if (mp_lshd (&t1, B) != MP_OKAY) - goto X1Y1; /* t1 = (x0y0 + x1y1 - (x1-x0)*(y1-y0))< -#ifdef BN_MP_KARATSUBA_SQR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* Karatsuba squaring, computes b = a*a using three - * half size squarings - * - * See comments of karatsuba_mul for details. It - * is essentially the same algorithm but merely - * tuned to perform recursive squarings. - */ -int mp_karatsuba_sqr (mp_int * a, mp_int * b) -{ - mp_int x0, x1, t1, t2, x0x0, x1x1; - int B, err; - - err = MP_MEM; - - /* min # of digits */ - B = a->used; - - /* now divide in two */ - B = B >> 1; - - /* init copy all the temps */ - if (mp_init_size (&x0, B) != MP_OKAY) - goto ERR; - if (mp_init_size (&x1, a->used - B) != MP_OKAY) - goto X0; - - /* init temps */ - if (mp_init_size (&t1, a->used * 2) != MP_OKAY) - goto X1; - if (mp_init_size (&t2, a->used * 2) != MP_OKAY) - goto T1; - if (mp_init_size (&x0x0, B * 2) != MP_OKAY) - goto T2; - if (mp_init_size (&x1x1, (a->used - B) * 2) != MP_OKAY) - goto X0X0; - - { - register int x; - register mp_digit *dst, *src; - - src = a->dp; - - /* now shift the digits */ - dst = x0.dp; - for (x = 0; x < B; x++) { - *dst++ = *src++; - } - - dst = x1.dp; - for (x = B; x < a->used; x++) { - *dst++ = *src++; - } - } - - x0.used = B; - x1.used = a->used - B; - - mp_clamp (&x0); - - /* now calc the products x0*x0 and x1*x1 */ - if (mp_sqr (&x0, &x0x0) != MP_OKAY) - goto X1X1; /* x0x0 = x0*x0 */ - if (mp_sqr (&x1, &x1x1) != MP_OKAY) - goto X1X1; /* x1x1 = x1*x1 */ - - /* now calc (x1+x0)**2 */ - if (s_mp_add (&x1, &x0, &t1) != MP_OKAY) - goto X1X1; /* t1 = x1 - x0 */ - if (mp_sqr (&t1, &t1) != MP_OKAY) - goto X1X1; /* t1 = (x1 - x0) * (x1 - x0) */ - - /* add x0y0 */ - if (s_mp_add (&x0x0, &x1x1, &t2) != MP_OKAY) - goto X1X1; /* t2 = x0x0 + x1x1 */ - if (s_mp_sub (&t1, &t2, &t1) != MP_OKAY) - goto X1X1; /* t1 = (x1+x0)**2 - (x0x0 + x1x1) */ - - /* shift by B */ - if (mp_lshd (&t1, B) != MP_OKAY) - goto X1X1; /* t1 = (x0x0 + x1x1 - (x1-x0)*(x1-x0))< -#ifdef BN_MP_LCM_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* computes least common multiple as |a*b|/(a, b) */ -int mp_lcm (mp_int * a, mp_int * b, mp_int * c) -{ - int res; - mp_int t1, t2; - - - if ((res = mp_init_multi (&t1, &t2, NULL)) != MP_OKAY) { - return res; - } - - /* t1 = get the GCD of the two inputs */ - if ((res = mp_gcd (a, b, &t1)) != MP_OKAY) { - goto LBL_T; - } - - /* divide the smallest by the GCD */ - if (mp_cmp_mag(a, b) == MP_LT) { - /* store quotient in t2 such that t2 * b is the LCM */ - if ((res = mp_div(a, &t1, &t2, NULL)) != MP_OKAY) { - goto LBL_T; - } - res = mp_mul(b, &t2, c); - } else { - /* store quotient in t2 such that t2 * a is the LCM */ - if ((res = mp_div(b, &t1, &t2, NULL)) != MP_OKAY) { - goto LBL_T; - } - res = mp_mul(a, &t2, c); - } - - /* fix the sign to positive */ - c->sign = MP_ZPOS; - -LBL_T: - mp_clear_multi (&t1, &t2, NULL); - return res; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_lshd.c b/external/libtommath-0.42.0/bn_mp_lshd.c deleted file mode 100755 index 87c216b..0000000 --- a/external/libtommath-0.42.0/bn_mp_lshd.c +++ /dev/null @@ -1,67 +0,0 @@ -#include -#ifdef BN_MP_LSHD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* shift left a certain amount of digits */ -int mp_lshd (mp_int * a, int b) -{ - int x, res; - - /* if its less than zero return */ - if (b <= 0) { - return MP_OKAY; - } - - /* grow to fit the new digits */ - if (a->alloc < a->used + b) { - if ((res = mp_grow (a, a->used + b)) != MP_OKAY) { - return res; - } - } - - { - register mp_digit *top, *bottom; - - /* increment the used by the shift amount then copy upwards */ - a->used += b; - - /* top */ - top = a->dp + a->used - 1; - - /* base */ - bottom = a->dp + a->used - 1 - b; - - /* much like mp_rshd this is implemented using a sliding window - * except the window goes the otherway around. Copying from - * the bottom to the top. see bn_mp_rshd.c for more info. - */ - for (x = a->used - 1; x >= b; x--) { - *top-- = *bottom--; - } - - /* zero the lower digits */ - top = a->dp; - for (x = 0; x < b; x++) { - *top++ = 0; - } - } - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_mod.c b/external/libtommath-0.42.0/bn_mp_mod.c deleted file mode 100755 index 6828328..0000000 --- a/external/libtommath-0.42.0/bn_mp_mod.c +++ /dev/null @@ -1,48 +0,0 @@ -#include -#ifdef BN_MP_MOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* c = a mod b, 0 <= c < b */ -int -mp_mod (mp_int * a, mp_int * b, mp_int * c) -{ - mp_int t; - int res; - - if ((res = mp_init (&t)) != MP_OKAY) { - return res; - } - - if ((res = mp_div (a, b, NULL, &t)) != MP_OKAY) { - mp_clear (&t); - return res; - } - - if (t.sign != b->sign) { - res = mp_add (b, &t, c); - } else { - res = MP_OKAY; - mp_exch (&t, c); - } - - mp_clear (&t); - return res; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_mod_2d.c b/external/libtommath-0.42.0/bn_mp_mod_2d.c deleted file mode 100755 index 77f13c3..0000000 --- a/external/libtommath-0.42.0/bn_mp_mod_2d.c +++ /dev/null @@ -1,55 +0,0 @@ -#include -#ifdef BN_MP_MOD_2D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* calc a value mod 2**b */ -int -mp_mod_2d (mp_int * a, int b, mp_int * c) -{ - int x, res; - - /* if b is <= 0 then zero the int */ - if (b <= 0) { - mp_zero (c); - return MP_OKAY; - } - - /* if the modulus is larger than the value than return */ - if (b >= (int) (a->used * DIGIT_BIT)) { - res = mp_copy (a, c); - return res; - } - - /* copy */ - if ((res = mp_copy (a, c)) != MP_OKAY) { - return res; - } - - /* zero digits above the last digit of the modulus */ - for (x = (b / DIGIT_BIT) + ((b % DIGIT_BIT) == 0 ? 0 : 1); x < c->used; x++) { - c->dp[x] = 0; - } - /* clear the digit that is not completely outside/inside the modulus */ - c->dp[b / DIGIT_BIT] &= - (mp_digit) ((((mp_digit) 1) << (((mp_digit) b) % DIGIT_BIT)) - ((mp_digit) 1)); - mp_clamp (c); - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_mod_d.c b/external/libtommath-0.42.0/bn_mp_mod_d.c deleted file mode 100755 index 4ad3d90..0000000 --- a/external/libtommath-0.42.0/bn_mp_mod_d.c +++ /dev/null @@ -1,27 +0,0 @@ -#include -#ifdef BN_MP_MOD_D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -int -mp_mod_d (mp_int * a, mp_digit b, mp_digit * c) -{ - return mp_div_d(a, b, NULL, c); -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_montgomery_calc_normalization.c b/external/libtommath-0.42.0/bn_mp_montgomery_calc_normalization.c deleted file mode 100755 index 4825ab5..0000000 --- a/external/libtommath-0.42.0/bn_mp_montgomery_calc_normalization.c +++ /dev/null @@ -1,59 +0,0 @@ -#include -#ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* - * shifts with subtractions when the result is greater than b. - * - * The method is slightly modified to shift B unconditionally upto just under - * the leading bit of b. This saves alot of multiple precision shifting. - */ -int mp_montgomery_calc_normalization (mp_int * a, mp_int * b) -{ - int x, bits, res; - - /* how many bits of last digit does b use */ - bits = mp_count_bits (b) % DIGIT_BIT; - - if (b->used > 1) { - if ((res = mp_2expt (a, (b->used - 1) * DIGIT_BIT + bits - 1)) != MP_OKAY) { - return res; - } - } else { - mp_set(a, 1); - bits = 1; - } - - - /* now compute C = A * B mod b */ - for (x = bits - 1; x < (int)DIGIT_BIT; x++) { - if ((res = mp_mul_2 (a, a)) != MP_OKAY) { - return res; - } - if (mp_cmp_mag (a, b) != MP_LT) { - if ((res = s_mp_sub (a, b, a)) != MP_OKAY) { - return res; - } - } - } - - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_montgomery_reduce.c b/external/libtommath-0.42.0/bn_mp_montgomery_reduce.c deleted file mode 100755 index 3c73268..0000000 --- a/external/libtommath-0.42.0/bn_mp_montgomery_reduce.c +++ /dev/null @@ -1,118 +0,0 @@ -#include -#ifdef BN_MP_MONTGOMERY_REDUCE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* computes xR**-1 == x (mod N) via Montgomery Reduction */ -int -mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) -{ - int ix, res, digs; - mp_digit mu; - - /* can the fast reduction [comba] method be used? - * - * Note that unlike in mul you're safely allowed *less* - * than the available columns [255 per default] since carries - * are fixed up in the inner loop. - */ - digs = n->used * 2 + 1; - if ((digs < MP_WARRAY) && - n->used < - (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { - return fast_mp_montgomery_reduce (x, n, rho); - } - - /* grow the input as required */ - if (x->alloc < digs) { - if ((res = mp_grow (x, digs)) != MP_OKAY) { - return res; - } - } - x->used = digs; - - for (ix = 0; ix < n->used; ix++) { - /* mu = ai * rho mod b - * - * The value of rho must be precalculated via - * montgomery_setup() such that - * it equals -1/n0 mod b this allows the - * following inner loop to reduce the - * input one digit at a time - */ - mu = (mp_digit) (((mp_word)x->dp[ix]) * ((mp_word)rho) & MP_MASK); - - /* a = a + mu * m * b**i */ - { - register int iy; - register mp_digit *tmpn, *tmpx, u; - register mp_word r; - - /* alias for digits of the modulus */ - tmpn = n->dp; - - /* alias for the digits of x [the input] */ - tmpx = x->dp + ix; - - /* set the carry to zero */ - u = 0; - - /* Multiply and add in place */ - for (iy = 0; iy < n->used; iy++) { - /* compute product and sum */ - r = ((mp_word)mu) * ((mp_word)*tmpn++) + - ((mp_word) u) + ((mp_word) * tmpx); - - /* get carry */ - u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); - - /* fix digit */ - *tmpx++ = (mp_digit)(r & ((mp_word) MP_MASK)); - } - /* At this point the ix'th digit of x should be zero */ - - - /* propagate carries upwards as required*/ - while (u) { - *tmpx += u; - u = *tmpx >> DIGIT_BIT; - *tmpx++ &= MP_MASK; - } - } - } - - /* at this point the n.used'th least - * significant digits of x are all zero - * which means we can shift x to the - * right by n.used digits and the - * residue is unchanged. - */ - - /* x = x/b**n.used */ - mp_clamp(x); - mp_rshd (x, n->used); - - /* if x >= n then x = x - n */ - if (mp_cmp_mag (x, n) != MP_LT) { - return s_mp_sub (x, n, x); - } - - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_montgomery_setup.c b/external/libtommath-0.42.0/bn_mp_montgomery_setup.c deleted file mode 100755 index 0de27bb..0000000 --- a/external/libtommath-0.42.0/bn_mp_montgomery_setup.c +++ /dev/null @@ -1,59 +0,0 @@ -#include -#ifdef BN_MP_MONTGOMERY_SETUP_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* setups the montgomery reduction stuff */ -int -mp_montgomery_setup (mp_int * n, mp_digit * rho) -{ - mp_digit x, b; - -/* fast inversion mod 2**k - * - * Based on the fact that - * - * XA = 1 (mod 2**n) => (X(2-XA)) A = 1 (mod 2**2n) - * => 2*X*A - X*X*A*A = 1 - * => 2*(1) - (1) = 1 - */ - b = n->dp[0]; - - if ((b & 1) == 0) { - return MP_VAL; - } - - x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */ - x *= 2 - b * x; /* here x*a==1 mod 2**8 */ -#if !defined(MP_8BIT) - x *= 2 - b * x; /* here x*a==1 mod 2**16 */ -#endif -#if defined(MP_64BIT) || !(defined(MP_8BIT) || defined(MP_16BIT)) - x *= 2 - b * x; /* here x*a==1 mod 2**32 */ -#endif -#ifdef MP_64BIT - x *= 2 - b * x; /* here x*a==1 mod 2**64 */ -#endif - - /* rho = -1/m mod b */ - *rho = (unsigned long)(((mp_word)1 << ((mp_word) DIGIT_BIT)) - x) & MP_MASK; - - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_mul.c b/external/libtommath-0.42.0/bn_mp_mul.c deleted file mode 100755 index bd75d04..0000000 --- a/external/libtommath-0.42.0/bn_mp_mul.c +++ /dev/null @@ -1,66 +0,0 @@ -#include -#ifdef BN_MP_MUL_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* high level multiplication (handles sign) */ -int mp_mul (mp_int * a, mp_int * b, mp_int * c) -{ - int res, neg; - neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; - - /* use Toom-Cook? */ -#ifdef BN_MP_TOOM_MUL_C - if (MIN (a->used, b->used) >= TOOM_MUL_CUTOFF) { - res = mp_toom_mul(a, b, c); - } else -#endif -#ifdef BN_MP_KARATSUBA_MUL_C - /* use Karatsuba? */ - if (MIN (a->used, b->used) >= KARATSUBA_MUL_CUTOFF) { - res = mp_karatsuba_mul (a, b, c); - } else -#endif - { - /* can we use the fast multiplier? - * - * The fast multiplier can be used if the output will - * have less than MP_WARRAY digits and the number of - * digits won't affect carry propagation - */ - int digs = a->used + b->used + 1; - -#ifdef BN_FAST_S_MP_MUL_DIGS_C - if ((digs < MP_WARRAY) && - MIN(a->used, b->used) <= - (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { - res = fast_s_mp_mul_digs (a, b, c, digs); - } else -#endif -#ifdef BN_S_MP_MUL_DIGS_C - res = s_mp_mul (a, b, c); /* uses s_mp_mul_digs */ -#else - res = MP_VAL; -#endif - - } - c->sign = (c->used > 0) ? neg : MP_ZPOS; - return res; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_mul_2.c b/external/libtommath-0.42.0/bn_mp_mul_2.c deleted file mode 100755 index 6ba76be..0000000 --- a/external/libtommath-0.42.0/bn_mp_mul_2.c +++ /dev/null @@ -1,82 +0,0 @@ -#include -#ifdef BN_MP_MUL_2_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* b = a*2 */ -int mp_mul_2(mp_int * a, mp_int * b) -{ - int x, res, oldused; - - /* grow to accomodate result */ - if (b->alloc < a->used + 1) { - if ((res = mp_grow (b, a->used + 1)) != MP_OKAY) { - return res; - } - } - - oldused = b->used; - b->used = a->used; - - { - register mp_digit r, rr, *tmpa, *tmpb; - - /* alias for source */ - tmpa = a->dp; - - /* alias for dest */ - tmpb = b->dp; - - /* carry */ - r = 0; - for (x = 0; x < a->used; x++) { - - /* get what will be the *next* carry bit from the - * MSB of the current digit - */ - rr = *tmpa >> ((mp_digit)(DIGIT_BIT - 1)); - - /* now shift up this digit, add in the carry [from the previous] */ - *tmpb++ = ((*tmpa++ << ((mp_digit)1)) | r) & MP_MASK; - - /* copy the carry that would be from the source - * digit into the next iteration - */ - r = rr; - } - - /* new leading digit? */ - if (r != 0) { - /* add a MSB which is always 1 at this point */ - *tmpb = 1; - ++(b->used); - } - - /* now zero any excess digits on the destination - * that we didn't write to - */ - tmpb = b->dp + b->used; - for (x = b->used; x < oldused; x++) { - *tmpb++ = 0; - } - } - b->sign = a->sign; - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_mul_2d.c b/external/libtommath-0.42.0/bn_mp_mul_2d.c deleted file mode 100755 index 385ac59..0000000 --- a/external/libtommath-0.42.0/bn_mp_mul_2d.c +++ /dev/null @@ -1,85 +0,0 @@ -#include -#ifdef BN_MP_MUL_2D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* shift left by a certain bit count */ -int mp_mul_2d (mp_int * a, int b, mp_int * c) -{ - mp_digit d; - int res; - - /* copy */ - if (a != c) { - if ((res = mp_copy (a, c)) != MP_OKAY) { - return res; - } - } - - if (c->alloc < (int)(c->used + b/DIGIT_BIT + 1)) { - if ((res = mp_grow (c, c->used + b / DIGIT_BIT + 1)) != MP_OKAY) { - return res; - } - } - - /* shift by as many digits in the bit count */ - if (b >= (int)DIGIT_BIT) { - if ((res = mp_lshd (c, b / DIGIT_BIT)) != MP_OKAY) { - return res; - } - } - - /* shift any bit count < DIGIT_BIT */ - d = (mp_digit) (b % DIGIT_BIT); - if (d != 0) { - register mp_digit *tmpc, shift, mask, r, rr; - register int x; - - /* bitmask for carries */ - mask = (((mp_digit)1) << d) - 1; - - /* shift for msbs */ - shift = DIGIT_BIT - d; - - /* alias */ - tmpc = c->dp; - - /* carry */ - r = 0; - for (x = 0; x < c->used; x++) { - /* get the higher bits of the current word */ - rr = (*tmpc >> shift) & mask; - - /* shift the current word and OR in the carry */ - *tmpc = ((*tmpc << d) | r) & MP_MASK; - ++tmpc; - - /* set the carry to the carry bits of the current word */ - r = rr; - } - - /* set final carry */ - if (r != 0) { - c->dp[(c->used)++] = r; - } - } - mp_clamp (c); - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_mul_d.c b/external/libtommath-0.42.0/bn_mp_mul_d.c deleted file mode 100755 index 13c6066..0000000 --- a/external/libtommath-0.42.0/bn_mp_mul_d.c +++ /dev/null @@ -1,79 +0,0 @@ -#include -#ifdef BN_MP_MUL_D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* multiply by a digit */ -int -mp_mul_d (mp_int * a, mp_digit b, mp_int * c) -{ - mp_digit u, *tmpa, *tmpc; - mp_word r; - int ix, res, olduse; - - /* make sure c is big enough to hold a*b */ - if (c->alloc < a->used + 1) { - if ((res = mp_grow (c, a->used + 1)) != MP_OKAY) { - return res; - } - } - - /* get the original destinations used count */ - olduse = c->used; - - /* set the sign */ - c->sign = a->sign; - - /* alias for a->dp [source] */ - tmpa = a->dp; - - /* alias for c->dp [dest] */ - tmpc = c->dp; - - /* zero carry */ - u = 0; - - /* compute columns */ - for (ix = 0; ix < a->used; ix++) { - /* compute product and carry sum for this term */ - r = ((mp_word) u) + ((mp_word)*tmpa++) * ((mp_word)b); - - /* mask off higher bits to get a single digit */ - *tmpc++ = (mp_digit) (r & ((mp_word) MP_MASK)); - - /* send carry into next iteration */ - u = (mp_digit) (r >> ((mp_word) DIGIT_BIT)); - } - - /* store final carry [if any] and increment ix offset */ - *tmpc++ = u; - ++ix; - - /* now zero digits above the top */ - while (ix++ < olduse) { - *tmpc++ = 0; - } - - /* set used count */ - c->used = a->used + 1; - mp_clamp(c); - - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_mulmod.c b/external/libtommath-0.42.0/bn_mp_mulmod.c deleted file mode 100755 index eebca37..0000000 --- a/external/libtommath-0.42.0/bn_mp_mulmod.c +++ /dev/null @@ -1,40 +0,0 @@ -#include -#ifdef BN_MP_MULMOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* d = a * b (mod c) */ -int mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) -{ - int res; - mp_int t; - - if ((res = mp_init (&t)) != MP_OKAY) { - return res; - } - - if ((res = mp_mul (a, b, &t)) != MP_OKAY) { - mp_clear (&t); - return res; - } - res = mp_mod (&t, c, d); - mp_clear (&t); - return res; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_n_root.c b/external/libtommath-0.42.0/bn_mp_n_root.c deleted file mode 100755 index e6bf725..0000000 --- a/external/libtommath-0.42.0/bn_mp_n_root.c +++ /dev/null @@ -1,132 +0,0 @@ -#include -#ifdef BN_MP_N_ROOT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* find the n'th root of an integer - * - * Result found such that (c)**b <= a and (c+1)**b > a - * - * This algorithm uses Newton's approximation - * x[i+1] = x[i] - f(x[i])/f'(x[i]) - * which will find the root in log(N) time where - * each step involves a fair bit. This is not meant to - * find huge roots [square and cube, etc]. - */ -int mp_n_root (mp_int * a, mp_digit b, mp_int * c) -{ - mp_int t1, t2, t3; - int res, neg; - - /* input must be positive if b is even */ - if ((b & 1) == 0 && a->sign == MP_NEG) { - return MP_VAL; - } - - if ((res = mp_init (&t1)) != MP_OKAY) { - return res; - } - - if ((res = mp_init (&t2)) != MP_OKAY) { - goto LBL_T1; - } - - if ((res = mp_init (&t3)) != MP_OKAY) { - goto LBL_T2; - } - - /* if a is negative fudge the sign but keep track */ - neg = a->sign; - a->sign = MP_ZPOS; - - /* t2 = 2 */ - mp_set (&t2, 2); - - do { - /* t1 = t2 */ - if ((res = mp_copy (&t2, &t1)) != MP_OKAY) { - goto LBL_T3; - } - - /* t2 = t1 - ((t1**b - a) / (b * t1**(b-1))) */ - - /* t3 = t1**(b-1) */ - if ((res = mp_expt_d (&t1, b - 1, &t3)) != MP_OKAY) { - goto LBL_T3; - } - - /* numerator */ - /* t2 = t1**b */ - if ((res = mp_mul (&t3, &t1, &t2)) != MP_OKAY) { - goto LBL_T3; - } - - /* t2 = t1**b - a */ - if ((res = mp_sub (&t2, a, &t2)) != MP_OKAY) { - goto LBL_T3; - } - - /* denominator */ - /* t3 = t1**(b-1) * b */ - if ((res = mp_mul_d (&t3, b, &t3)) != MP_OKAY) { - goto LBL_T3; - } - - /* t3 = (t1**b - a)/(b * t1**(b-1)) */ - if ((res = mp_div (&t2, &t3, &t3, NULL)) != MP_OKAY) { - goto LBL_T3; - } - - if ((res = mp_sub (&t1, &t3, &t2)) != MP_OKAY) { - goto LBL_T3; - } - } while (mp_cmp (&t1, &t2) != MP_EQ); - - /* result can be off by a few so check */ - for (;;) { - if ((res = mp_expt_d (&t1, b, &t2)) != MP_OKAY) { - goto LBL_T3; - } - - if (mp_cmp (&t2, a) == MP_GT) { - if ((res = mp_sub_d (&t1, 1, &t1)) != MP_OKAY) { - goto LBL_T3; - } - } else { - break; - } - } - - /* reset the sign of a first */ - a->sign = neg; - - /* set the result */ - mp_exch (&t1, c); - - /* set the sign of the result */ - c->sign = neg; - - res = MP_OKAY; - -LBL_T3:mp_clear (&t3); -LBL_T2:mp_clear (&t2); -LBL_T1:mp_clear (&t1); - return res; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_neg.c b/external/libtommath-0.42.0/bn_mp_neg.c deleted file mode 100755 index 0e868ce..0000000 --- a/external/libtommath-0.42.0/bn_mp_neg.c +++ /dev/null @@ -1,40 +0,0 @@ -#include -#ifdef BN_MP_NEG_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* b = -a */ -int mp_neg (mp_int * a, mp_int * b) -{ - int res; - if (a != b) { - if ((res = mp_copy (a, b)) != MP_OKAY) { - return res; - } - } - - if (mp_iszero(b) != MP_YES) { - b->sign = (a->sign == MP_ZPOS) ? MP_NEG : MP_ZPOS; - } else { - b->sign = MP_ZPOS; - } - - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_or.c b/external/libtommath-0.42.0/bn_mp_or.c deleted file mode 100755 index 5c2761a..0000000 --- a/external/libtommath-0.42.0/bn_mp_or.c +++ /dev/null @@ -1,50 +0,0 @@ -#include -#ifdef BN_MP_OR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* OR two ints together */ -int mp_or (mp_int * a, mp_int * b, mp_int * c) -{ - int res, ix, px; - mp_int t, *x; - - if (a->used > b->used) { - if ((res = mp_init_copy (&t, a)) != MP_OKAY) { - return res; - } - px = b->used; - x = b; - } else { - if ((res = mp_init_copy (&t, b)) != MP_OKAY) { - return res; - } - px = a->used; - x = a; - } - - for (ix = 0; ix < px; ix++) { - t.dp[ix] |= x->dp[ix]; - } - mp_clamp (&t); - mp_exch (c, &t); - mp_clear (&t); - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_prime_fermat.c b/external/libtommath-0.42.0/bn_mp_prime_fermat.c deleted file mode 100755 index fe10ab2..0000000 --- a/external/libtommath-0.42.0/bn_mp_prime_fermat.c +++ /dev/null @@ -1,62 +0,0 @@ -#include -#ifdef BN_MP_PRIME_FERMAT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* performs one Fermat test. - * - * If "a" were prime then b**a == b (mod a) since the order of - * the multiplicative sub-group would be phi(a) = a-1. That means - * it would be the same as b**(a mod (a-1)) == b**1 == b (mod a). - * - * Sets result to 1 if the congruence holds, or zero otherwise. - */ -int mp_prime_fermat (mp_int * a, mp_int * b, int *result) -{ - mp_int t; - int err; - - /* default to composite */ - *result = MP_NO; - - /* ensure b > 1 */ - if (mp_cmp_d(b, 1) != MP_GT) { - return MP_VAL; - } - - /* init t */ - if ((err = mp_init (&t)) != MP_OKAY) { - return err; - } - - /* compute t = b**a mod a */ - if ((err = mp_exptmod (b, a, a, &t)) != MP_OKAY) { - goto LBL_T; - } - - /* is it equal to b? */ - if (mp_cmp (&t, b) == MP_EQ) { - *result = MP_YES; - } - - err = MP_OKAY; -LBL_T:mp_clear (&t); - return err; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_prime_is_divisible.c b/external/libtommath-0.42.0/bn_mp_prime_is_divisible.c deleted file mode 100755 index 2b217ae..0000000 --- a/external/libtommath-0.42.0/bn_mp_prime_is_divisible.c +++ /dev/null @@ -1,50 +0,0 @@ -#include -#ifdef BN_MP_PRIME_IS_DIVISIBLE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* determines if an integers is divisible by one - * of the first PRIME_SIZE primes or not - * - * sets result to 0 if not, 1 if yes - */ -int mp_prime_is_divisible (mp_int * a, int *result) -{ - int err, ix; - mp_digit res; - - /* default to not */ - *result = MP_NO; - - for (ix = 0; ix < PRIME_SIZE; ix++) { - /* what is a mod LBL_prime_tab[ix] */ - if ((err = mp_mod_d (a, ltm_prime_tab[ix], &res)) != MP_OKAY) { - return err; - } - - /* is the residue zero? */ - if (res == 0) { - *result = MP_YES; - return MP_OKAY; - } - } - - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_prime_is_prime.c b/external/libtommath-0.42.0/bn_mp_prime_is_prime.c deleted file mode 100755 index 09908df..0000000 --- a/external/libtommath-0.42.0/bn_mp_prime_is_prime.c +++ /dev/null @@ -1,83 +0,0 @@ -#include -#ifdef BN_MP_PRIME_IS_PRIME_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* performs a variable number of rounds of Miller-Rabin - * - * Probability of error after t rounds is no more than - - * - * Sets result to 1 if probably prime, 0 otherwise - */ -int mp_prime_is_prime (mp_int * a, int t, int *result) -{ - mp_int b; - int ix, err, res; - - /* default to no */ - *result = MP_NO; - - /* valid value of t? */ - if (t <= 0 || t > PRIME_SIZE) { - return MP_VAL; - } - - /* is the input equal to one of the primes in the table? */ - for (ix = 0; ix < PRIME_SIZE; ix++) { - if (mp_cmp_d(a, ltm_prime_tab[ix]) == MP_EQ) { - *result = 1; - return MP_OKAY; - } - } - - /* first perform trial division */ - if ((err = mp_prime_is_divisible (a, &res)) != MP_OKAY) { - return err; - } - - /* return if it was trivially divisible */ - if (res == MP_YES) { - return MP_OKAY; - } - - /* now perform the miller-rabin rounds */ - if ((err = mp_init (&b)) != MP_OKAY) { - return err; - } - - for (ix = 0; ix < t; ix++) { - /* set the prime */ - mp_set (&b, ltm_prime_tab[ix]); - - if ((err = mp_prime_miller_rabin (a, &b, &res)) != MP_OKAY) { - goto LBL_B; - } - - if (res == MP_NO) { - goto LBL_B; - } - } - - /* passed the test */ - *result = MP_YES; -LBL_B:mp_clear (&b); - return err; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_prime_miller_rabin.c b/external/libtommath-0.42.0/bn_mp_prime_miller_rabin.c deleted file mode 100755 index fe88d94..0000000 --- a/external/libtommath-0.42.0/bn_mp_prime_miller_rabin.c +++ /dev/null @@ -1,103 +0,0 @@ -#include -#ifdef BN_MP_PRIME_MILLER_RABIN_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* Miller-Rabin test of "a" to the base of "b" as described in - * HAC pp. 139 Algorithm 4.24 - * - * Sets result to 0 if definitely composite or 1 if probably prime. - * Randomly the chance of error is no more than 1/4 and often - * very much lower. - */ -int mp_prime_miller_rabin (mp_int * a, mp_int * b, int *result) -{ - mp_int n1, y, r; - int s, j, err; - - /* default */ - *result = MP_NO; - - /* ensure b > 1 */ - if (mp_cmp_d(b, 1) != MP_GT) { - return MP_VAL; - } - - /* get n1 = a - 1 */ - if ((err = mp_init_copy (&n1, a)) != MP_OKAY) { - return err; - } - if ((err = mp_sub_d (&n1, 1, &n1)) != MP_OKAY) { - goto LBL_N1; - } - - /* set 2**s * r = n1 */ - if ((err = mp_init_copy (&r, &n1)) != MP_OKAY) { - goto LBL_N1; - } - - /* count the number of least significant bits - * which are zero - */ - s = mp_cnt_lsb(&r); - - /* now divide n - 1 by 2**s */ - if ((err = mp_div_2d (&r, s, &r, NULL)) != MP_OKAY) { - goto LBL_R; - } - - /* compute y = b**r mod a */ - if ((err = mp_init (&y)) != MP_OKAY) { - goto LBL_R; - } - if ((err = mp_exptmod (b, &r, a, &y)) != MP_OKAY) { - goto LBL_Y; - } - - /* if y != 1 and y != n1 do */ - if (mp_cmp_d (&y, 1) != MP_EQ && mp_cmp (&y, &n1) != MP_EQ) { - j = 1; - /* while j <= s-1 and y != n1 */ - while ((j <= (s - 1)) && mp_cmp (&y, &n1) != MP_EQ) { - if ((err = mp_sqrmod (&y, a, &y)) != MP_OKAY) { - goto LBL_Y; - } - - /* if y == 1 then composite */ - if (mp_cmp_d (&y, 1) == MP_EQ) { - goto LBL_Y; - } - - ++j; - } - - /* if y != n1 then composite */ - if (mp_cmp (&y, &n1) != MP_EQ) { - goto LBL_Y; - } - } - - /* probably prime now */ - *result = MP_YES; -LBL_Y:mp_clear (&y); -LBL_R:mp_clear (&r); -LBL_N1:mp_clear (&n1); - return err; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_prime_next_prime.c b/external/libtommath-0.42.0/bn_mp_prime_next_prime.c deleted file mode 100755 index 37a03c6..0000000 --- a/external/libtommath-0.42.0/bn_mp_prime_next_prime.c +++ /dev/null @@ -1,170 +0,0 @@ -#include -#ifdef BN_MP_PRIME_NEXT_PRIME_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* finds the next prime after the number "a" using "t" trials - * of Miller-Rabin. - * - * bbs_style = 1 means the prime must be congruent to 3 mod 4 - */ -int mp_prime_next_prime(mp_int *a, int t, int bbs_style) -{ - int err, res, x, y; - mp_digit res_tab[PRIME_SIZE], step, kstep; - mp_int b; - - /* ensure t is valid */ - if (t <= 0 || t > PRIME_SIZE) { - return MP_VAL; - } - - /* force positive */ - a->sign = MP_ZPOS; - - /* simple algo if a is less than the largest prime in the table */ - if (mp_cmp_d(a, ltm_prime_tab[PRIME_SIZE-1]) == MP_LT) { - /* find which prime it is bigger than */ - for (x = PRIME_SIZE - 2; x >= 0; x--) { - if (mp_cmp_d(a, ltm_prime_tab[x]) != MP_LT) { - if (bbs_style == 1) { - /* ok we found a prime smaller or - * equal [so the next is larger] - * - * however, the prime must be - * congruent to 3 mod 4 - */ - if ((ltm_prime_tab[x + 1] & 3) != 3) { - /* scan upwards for a prime congruent to 3 mod 4 */ - for (y = x + 1; y < PRIME_SIZE; y++) { - if ((ltm_prime_tab[y] & 3) == 3) { - mp_set(a, ltm_prime_tab[y]); - return MP_OKAY; - } - } - } - } else { - mp_set(a, ltm_prime_tab[x + 1]); - return MP_OKAY; - } - } - } - /* at this point a maybe 1 */ - if (mp_cmp_d(a, 1) == MP_EQ) { - mp_set(a, 2); - return MP_OKAY; - } - /* fall through to the sieve */ - } - - /* generate a prime congruent to 3 mod 4 or 1/3 mod 4? */ - if (bbs_style == 1) { - kstep = 4; - } else { - kstep = 2; - } - - /* at this point we will use a combination of a sieve and Miller-Rabin */ - - if (bbs_style == 1) { - /* if a mod 4 != 3 subtract the correct value to make it so */ - if ((a->dp[0] & 3) != 3) { - if ((err = mp_sub_d(a, (a->dp[0] & 3) + 1, a)) != MP_OKAY) { return err; }; - } - } else { - if (mp_iseven(a) == 1) { - /* force odd */ - if ((err = mp_sub_d(a, 1, a)) != MP_OKAY) { - return err; - } - } - } - - /* generate the restable */ - for (x = 1; x < PRIME_SIZE; x++) { - if ((err = mp_mod_d(a, ltm_prime_tab[x], res_tab + x)) != MP_OKAY) { - return err; - } - } - - /* init temp used for Miller-Rabin Testing */ - if ((err = mp_init(&b)) != MP_OKAY) { - return err; - } - - for (;;) { - /* skip to the next non-trivially divisible candidate */ - step = 0; - do { - /* y == 1 if any residue was zero [e.g. cannot be prime] */ - y = 0; - - /* increase step to next candidate */ - step += kstep; - - /* compute the new residue without using division */ - for (x = 1; x < PRIME_SIZE; x++) { - /* add the step to each residue */ - res_tab[x] += kstep; - - /* subtract the modulus [instead of using division] */ - if (res_tab[x] >= ltm_prime_tab[x]) { - res_tab[x] -= ltm_prime_tab[x]; - } - - /* set flag if zero */ - if (res_tab[x] == 0) { - y = 1; - } - } - } while (y == 1 && step < ((((mp_digit)1)<= ((((mp_digit)1)< -#ifdef BN_MP_PRIME_RABIN_MILLER_TRIALS_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - - -static const struct { - int k, t; -} sizes[] = { -{ 128, 28 }, -{ 256, 16 }, -{ 384, 10 }, -{ 512, 7 }, -{ 640, 6 }, -{ 768, 5 }, -{ 896, 4 }, -{ 1024, 4 } -}; - -/* returns # of RM trials required for a given bit size */ -int mp_prime_rabin_miller_trials(int size) -{ - int x; - - for (x = 0; x < (int)(sizeof(sizes)/(sizeof(sizes[0]))); x++) { - if (sizes[x].k == size) { - return sizes[x].t; - } else if (sizes[x].k > size) { - return (x == 0) ? sizes[0].t : sizes[x - 1].t; - } - } - return sizes[x-1].t + 1; -} - - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_prime_random_ex.c b/external/libtommath-0.42.0/bn_mp_prime_random_ex.c deleted file mode 100755 index 16d2aae..0000000 --- a/external/libtommath-0.42.0/bn_mp_prime_random_ex.c +++ /dev/null @@ -1,125 +0,0 @@ -#include -#ifdef BN_MP_PRIME_RANDOM_EX_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* makes a truly random prime of a given size (bits), - * - * Flags are as follows: - * - * LTM_PRIME_BBS - make prime congruent to 3 mod 4 - * LTM_PRIME_SAFE - make sure (p-1)/2 is prime as well (implies LTM_PRIME_BBS) - * LTM_PRIME_2MSB_OFF - make the 2nd highest bit zero - * LTM_PRIME_2MSB_ON - make the 2nd highest bit one - * - * You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can - * have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself - * so it can be NULL - * - */ - -/* This is possibly the mother of all prime generation functions, muahahahahaha! */ -int mp_prime_random_ex(mp_int *a, int t, int size, int flags, ltm_prime_callback cb, void *dat) -{ - unsigned char *tmp, maskAND, maskOR_msb, maskOR_lsb; - int res, err, bsize, maskOR_msb_offset; - - /* sanity check the input */ - if (size <= 1 || t <= 0) { - return MP_VAL; - } - - /* LTM_PRIME_SAFE implies LTM_PRIME_BBS */ - if (flags & LTM_PRIME_SAFE) { - flags |= LTM_PRIME_BBS; - } - - /* calc the byte size */ - bsize = (size>>3) + ((size&7)?1:0); - - /* we need a buffer of bsize bytes */ - tmp = OPT_CAST(unsigned char) XMALLOC(bsize); - if (tmp == NULL) { - return MP_MEM; - } - - /* calc the maskAND value for the MSbyte*/ - maskAND = ((size&7) == 0) ? 0xFF : (0xFF >> (8 - (size & 7))); - - /* calc the maskOR_msb */ - maskOR_msb = 0; - maskOR_msb_offset = ((size & 7) == 1) ? 1 : 0; - if (flags & LTM_PRIME_2MSB_ON) { - maskOR_msb |= 0x80 >> ((9 - size) & 7); - } - - /* get the maskOR_lsb */ - maskOR_lsb = 1; - if (flags & LTM_PRIME_BBS) { - maskOR_lsb |= 3; - } - - do { - /* read the bytes */ - if (cb(tmp, bsize, dat) != bsize) { - err = MP_VAL; - goto error; - } - - /* work over the MSbyte */ - tmp[0] &= maskAND; - tmp[0] |= 1 << ((size - 1) & 7); - - /* mix in the maskORs */ - tmp[maskOR_msb_offset] |= maskOR_msb; - tmp[bsize-1] |= maskOR_lsb; - - /* read it in */ - if ((err = mp_read_unsigned_bin(a, tmp, bsize)) != MP_OKAY) { goto error; } - - /* is it prime? */ - if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY) { goto error; } - if (res == MP_NO) { - continue; - } - - if (flags & LTM_PRIME_SAFE) { - /* see if (a-1)/2 is prime */ - if ((err = mp_sub_d(a, 1, a)) != MP_OKAY) { goto error; } - if ((err = mp_div_2(a, a)) != MP_OKAY) { goto error; } - - /* is it prime? */ - if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY) { goto error; } - } - } while (res == MP_NO); - - if (flags & LTM_PRIME_SAFE) { - /* restore a to the original value */ - if ((err = mp_mul_2(a, a)) != MP_OKAY) { goto error; } - if ((err = mp_add_d(a, 1, a)) != MP_OKAY) { goto error; } - } - - err = MP_OKAY; -error: - XFREE(tmp); - return err; -} - - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_radix_size.c b/external/libtommath-0.42.0/bn_mp_radix_size.c deleted file mode 100755 index 9d95c48..0000000 --- a/external/libtommath-0.42.0/bn_mp_radix_size.c +++ /dev/null @@ -1,78 +0,0 @@ -#include -#ifdef BN_MP_RADIX_SIZE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* returns size of ASCII reprensentation */ -int mp_radix_size (mp_int * a, int radix, int *size) -{ - int res, digs; - mp_int t; - mp_digit d; - - *size = 0; - - /* special case for binary */ - if (radix == 2) { - *size = mp_count_bits (a) + (a->sign == MP_NEG ? 1 : 0) + 1; - return MP_OKAY; - } - - /* make sure the radix is in range */ - if (radix < 2 || radix > 64) { - return MP_VAL; - } - - if (mp_iszero(a) == MP_YES) { - *size = 2; - return MP_OKAY; - } - - /* digs is the digit count */ - digs = 0; - - /* if it's negative add one for the sign */ - if (a->sign == MP_NEG) { - ++digs; - } - - /* init a copy of the input */ - if ((res = mp_init_copy (&t, a)) != MP_OKAY) { - return res; - } - - /* force temp to positive */ - t.sign = MP_ZPOS; - - /* fetch out all of the digits */ - while (mp_iszero (&t) == MP_NO) { - if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) { - mp_clear (&t); - return res; - } - ++digs; - } - mp_clear (&t); - - /* return digs + 1, the 1 is for the NULL byte that would be required. */ - *size = digs + 1; - return MP_OKAY; -} - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_radix_smap.c b/external/libtommath-0.42.0/bn_mp_radix_smap.c deleted file mode 100755 index b3abd3e..0000000 --- a/external/libtommath-0.42.0/bn_mp_radix_smap.c +++ /dev/null @@ -1,24 +0,0 @@ -#include -#ifdef BN_MP_RADIX_SMAP_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* chars used in radix conversions */ -const char *mp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/"; -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_rand.c b/external/libtommath-0.42.0/bn_mp_rand.c deleted file mode 100755 index 96e4e46..0000000 --- a/external/libtommath-0.42.0/bn_mp_rand.c +++ /dev/null @@ -1,55 +0,0 @@ -#include -#ifdef BN_MP_RAND_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* makes a pseudo-random int of a given size */ -int -mp_rand (mp_int * a, int digits) -{ - int res; - mp_digit d; - - mp_zero (a); - if (digits <= 0) { - return MP_OKAY; - } - - /* first place a random non-zero digit */ - do { - d = ((mp_digit) abs (rand ())) & MP_MASK; - } while (d == 0); - - if ((res = mp_add_d (a, d, a)) != MP_OKAY) { - return res; - } - - while (--digits > 0) { - if ((res = mp_lshd (a, 1)) != MP_OKAY) { - return res; - } - - if ((res = mp_add_d (a, ((mp_digit) abs (rand ())), a)) != MP_OKAY) { - return res; - } - } - - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_read_radix.c b/external/libtommath-0.42.0/bn_mp_read_radix.c deleted file mode 100755 index 8ce103f..0000000 --- a/external/libtommath-0.42.0/bn_mp_read_radix.c +++ /dev/null @@ -1,85 +0,0 @@ -#include -#ifdef BN_MP_READ_RADIX_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* read a string [ASCII] in a given radix */ -int mp_read_radix (mp_int * a, const char *str, int radix) -{ - int y, res, neg; - char ch; - - /* zero the digit bignum */ - mp_zero(a); - - /* make sure the radix is ok */ - if (radix < 2 || radix > 64) { - return MP_VAL; - } - - /* if the leading digit is a - * minus set the sign to negative. - */ - if (*str == '-') { - ++str; - neg = MP_NEG; - } else { - neg = MP_ZPOS; - } - - /* set the integer to the default of zero */ - mp_zero (a); - - /* process each digit of the string */ - while (*str) { - /* if the radix < 36 the conversion is case insensitive - * this allows numbers like 1AB and 1ab to represent the same value - * [e.g. in hex] - */ - ch = (char) ((radix < 36) ? toupper (*str) : *str); - for (y = 0; y < 64; y++) { - if (ch == mp_s_rmap[y]) { - break; - } - } - - /* if the char was found in the map - * and is less than the given radix add it - * to the number, otherwise exit the loop. - */ - if (y < radix) { - if ((res = mp_mul_d (a, (mp_digit) radix, a)) != MP_OKAY) { - return res; - } - if ((res = mp_add_d (a, (mp_digit) y, a)) != MP_OKAY) { - return res; - } - } else { - break; - } - ++str; - } - - /* set the sign only if a != 0 */ - if (mp_iszero(a) != 1) { - a->sign = neg; - } - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_read_signed_bin.c b/external/libtommath-0.42.0/bn_mp_read_signed_bin.c deleted file mode 100755 index 92924e8..0000000 --- a/external/libtommath-0.42.0/bn_mp_read_signed_bin.c +++ /dev/null @@ -1,41 +0,0 @@ -#include -#ifdef BN_MP_READ_SIGNED_BIN_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* read signed bin, big endian, first byte is 0==positive or 1==negative */ -int mp_read_signed_bin (mp_int * a, const unsigned char *b, int c) -{ - int res; - - /* read magnitude */ - if ((res = mp_read_unsigned_bin (a, b + 1, c - 1)) != MP_OKAY) { - return res; - } - - /* first byte is 0 for positive, non-zero for negative */ - if (b[0] == 0) { - a->sign = MP_ZPOS; - } else { - a->sign = MP_NEG; - } - - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_read_unsigned_bin.c b/external/libtommath-0.42.0/bn_mp_read_unsigned_bin.c deleted file mode 100755 index 5a7fa91..0000000 --- a/external/libtommath-0.42.0/bn_mp_read_unsigned_bin.c +++ /dev/null @@ -1,55 +0,0 @@ -#include -#ifdef BN_MP_READ_UNSIGNED_BIN_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* reads a unsigned char array, assumes the msb is stored first [big endian] */ -int mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c) -{ - int res; - - /* make sure there are at least two digits */ - if (a->alloc < 2) { - if ((res = mp_grow(a, 2)) != MP_OKAY) { - return res; - } - } - - /* zero the int */ - mp_zero (a); - - /* read the bytes in */ - while (c-- > 0) { - if ((res = mp_mul_2d (a, 8, a)) != MP_OKAY) { - return res; - } - -#ifndef MP_8BIT - a->dp[0] |= *b++; - a->used += 1; -#else - a->dp[0] = (*b & MP_MASK); - a->dp[1] |= ((*b++ >> 7U) & 1); - a->used += 2; -#endif - } - mp_clamp (a); - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_reduce.c b/external/libtommath-0.42.0/bn_mp_reduce.c deleted file mode 100755 index 50e1eaa..0000000 --- a/external/libtommath-0.42.0/bn_mp_reduce.c +++ /dev/null @@ -1,100 +0,0 @@ -#include -#ifdef BN_MP_REDUCE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* reduces x mod m, assumes 0 < x < m**2, mu is - * precomputed via mp_reduce_setup. - * From HAC pp.604 Algorithm 14.42 - */ -int mp_reduce (mp_int * x, mp_int * m, mp_int * mu) -{ - mp_int q; - int res, um = m->used; - - /* q = x */ - if ((res = mp_init_copy (&q, x)) != MP_OKAY) { - return res; - } - - /* q1 = x / b**(k-1) */ - mp_rshd (&q, um - 1); - - /* according to HAC this optimization is ok */ - if (((unsigned long) um) > (((mp_digit)1) << (DIGIT_BIT - 1))) { - if ((res = mp_mul (&q, mu, &q)) != MP_OKAY) { - goto CLEANUP; - } - } else { -#ifdef BN_S_MP_MUL_HIGH_DIGS_C - if ((res = s_mp_mul_high_digs (&q, mu, &q, um)) != MP_OKAY) { - goto CLEANUP; - } -#elif defined(BN_FAST_S_MP_MUL_HIGH_DIGS_C) - if ((res = fast_s_mp_mul_high_digs (&q, mu, &q, um)) != MP_OKAY) { - goto CLEANUP; - } -#else - { - res = MP_VAL; - goto CLEANUP; - } -#endif - } - - /* q3 = q2 / b**(k+1) */ - mp_rshd (&q, um + 1); - - /* x = x mod b**(k+1), quick (no division) */ - if ((res = mp_mod_2d (x, DIGIT_BIT * (um + 1), x)) != MP_OKAY) { - goto CLEANUP; - } - - /* q = q * m mod b**(k+1), quick (no division) */ - if ((res = s_mp_mul_digs (&q, m, &q, um + 1)) != MP_OKAY) { - goto CLEANUP; - } - - /* x = x - q */ - if ((res = mp_sub (x, &q, x)) != MP_OKAY) { - goto CLEANUP; - } - - /* If x < 0, add b**(k+1) to it */ - if (mp_cmp_d (x, 0) == MP_LT) { - mp_set (&q, 1); - if ((res = mp_lshd (&q, um + 1)) != MP_OKAY) - goto CLEANUP; - if ((res = mp_add (x, &q, x)) != MP_OKAY) - goto CLEANUP; - } - - /* Back off if it's too big */ - while (mp_cmp (x, m) != MP_LT) { - if ((res = s_mp_sub (x, m, x)) != MP_OKAY) { - goto CLEANUP; - } - } - -CLEANUP: - mp_clear (&q); - - return res; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_reduce_2k.c b/external/libtommath-0.42.0/bn_mp_reduce_2k.c deleted file mode 100755 index 6bbc5f1..0000000 --- a/external/libtommath-0.42.0/bn_mp_reduce_2k.c +++ /dev/null @@ -1,61 +0,0 @@ -#include -#ifdef BN_MP_REDUCE_2K_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* reduces a modulo n where n is of the form 2**p - d */ -int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d) -{ - mp_int q; - int p, res; - - if ((res = mp_init(&q)) != MP_OKAY) { - return res; - } - - p = mp_count_bits(n); -top: - /* q = a/2**p, a = a mod 2**p */ - if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) { - goto ERR; - } - - if (d != 1) { - /* q = q * d */ - if ((res = mp_mul_d(&q, d, &q)) != MP_OKAY) { - goto ERR; - } - } - - /* a = a + q */ - if ((res = s_mp_add(a, &q, a)) != MP_OKAY) { - goto ERR; - } - - if (mp_cmp_mag(a, n) != MP_LT) { - s_mp_sub(a, n, a); - goto top; - } - -ERR: - mp_clear(&q); - return res; -} - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_reduce_2k_l.c b/external/libtommath-0.42.0/bn_mp_reduce_2k_l.c deleted file mode 100755 index 067122a..0000000 --- a/external/libtommath-0.42.0/bn_mp_reduce_2k_l.c +++ /dev/null @@ -1,62 +0,0 @@ -#include -#ifdef BN_MP_REDUCE_2K_L_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* reduces a modulo n where n is of the form 2**p - d - This differs from reduce_2k since "d" can be larger - than a single digit. -*/ -int mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d) -{ - mp_int q; - int p, res; - - if ((res = mp_init(&q)) != MP_OKAY) { - return res; - } - - p = mp_count_bits(n); -top: - /* q = a/2**p, a = a mod 2**p */ - if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) { - goto ERR; - } - - /* q = q * d */ - if ((res = mp_mul(&q, d, &q)) != MP_OKAY) { - goto ERR; - } - - /* a = a + q */ - if ((res = s_mp_add(a, &q, a)) != MP_OKAY) { - goto ERR; - } - - if (mp_cmp_mag(a, n) != MP_LT) { - s_mp_sub(a, n, a); - goto top; - } - -ERR: - mp_clear(&q); - return res; -} - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_reduce_2k_setup.c b/external/libtommath-0.42.0/bn_mp_reduce_2k_setup.c deleted file mode 100755 index 3f9ffd9..0000000 --- a/external/libtommath-0.42.0/bn_mp_reduce_2k_setup.c +++ /dev/null @@ -1,47 +0,0 @@ -#include -#ifdef BN_MP_REDUCE_2K_SETUP_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* determines the setup value */ -int mp_reduce_2k_setup(mp_int *a, mp_digit *d) -{ - int res, p; - mp_int tmp; - - if ((res = mp_init(&tmp)) != MP_OKAY) { - return res; - } - - p = mp_count_bits(a); - if ((res = mp_2expt(&tmp, p)) != MP_OKAY) { - mp_clear(&tmp); - return res; - } - - if ((res = s_mp_sub(&tmp, a, &tmp)) != MP_OKAY) { - mp_clear(&tmp); - return res; - } - - *d = tmp.dp[0]; - mp_clear(&tmp); - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_reduce_2k_setup_l.c b/external/libtommath-0.42.0/bn_mp_reduce_2k_setup_l.c deleted file mode 100755 index 686368e..0000000 --- a/external/libtommath-0.42.0/bn_mp_reduce_2k_setup_l.c +++ /dev/null @@ -1,44 +0,0 @@ -#include -#ifdef BN_MP_REDUCE_2K_SETUP_L_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* determines the setup value */ -int mp_reduce_2k_setup_l(mp_int *a, mp_int *d) -{ - int res; - mp_int tmp; - - if ((res = mp_init(&tmp)) != MP_OKAY) { - return res; - } - - if ((res = mp_2expt(&tmp, mp_count_bits(a))) != MP_OKAY) { - goto ERR; - } - - if ((res = s_mp_sub(&tmp, a, d)) != MP_OKAY) { - goto ERR; - } - -ERR: - mp_clear(&tmp); - return res; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_reduce_is_2k.c b/external/libtommath-0.42.0/bn_mp_reduce_is_2k.c deleted file mode 100755 index 08b62ff..0000000 --- a/external/libtommath-0.42.0/bn_mp_reduce_is_2k.c +++ /dev/null @@ -1,52 +0,0 @@ -#include -#ifdef BN_MP_REDUCE_IS_2K_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* determines if mp_reduce_2k can be used */ -int mp_reduce_is_2k(mp_int *a) -{ - int ix, iy, iw; - mp_digit iz; - - if (a->used == 0) { - return MP_NO; - } else if (a->used == 1) { - return MP_YES; - } else if (a->used > 1) { - iy = mp_count_bits(a); - iz = 1; - iw = 1; - - /* Test every bit from the second digit up, must be 1 */ - for (ix = DIGIT_BIT; ix < iy; ix++) { - if ((a->dp[iw] & iz) == 0) { - return MP_NO; - } - iz <<= 1; - if (iz > (mp_digit)MP_MASK) { - ++iw; - iz = 1; - } - } - } - return MP_YES; -} - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_reduce_is_2k_l.c b/external/libtommath-0.42.0/bn_mp_reduce_is_2k_l.c deleted file mode 100755 index a72e39c..0000000 --- a/external/libtommath-0.42.0/bn_mp_reduce_is_2k_l.c +++ /dev/null @@ -1,44 +0,0 @@ -#include -#ifdef BN_MP_REDUCE_IS_2K_L_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* determines if reduce_2k_l can be used */ -int mp_reduce_is_2k_l(mp_int *a) -{ - int ix, iy; - - if (a->used == 0) { - return MP_NO; - } else if (a->used == 1) { - return MP_YES; - } else if (a->used > 1) { - /* if more than half of the digits are -1 we're sold */ - for (iy = ix = 0; ix < a->used; ix++) { - if (a->dp[ix] == MP_MASK) { - ++iy; - } - } - return (iy >= (a->used/2)) ? MP_YES : MP_NO; - - } - return MP_NO; -} - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_reduce_setup.c b/external/libtommath-0.42.0/bn_mp_reduce_setup.c deleted file mode 100755 index f017386..0000000 --- a/external/libtommath-0.42.0/bn_mp_reduce_setup.c +++ /dev/null @@ -1,34 +0,0 @@ -#include -#ifdef BN_MP_REDUCE_SETUP_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* pre-calculate the value required for Barrett reduction - * For a given modulus "b" it calulates the value required in "a" - */ -int mp_reduce_setup (mp_int * a, mp_int * b) -{ - int res; - - if ((res = mp_2expt (a, b->used * 2 * DIGIT_BIT)) != MP_OKAY) { - return res; - } - return mp_div (a, b, a, NULL); -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_rshd.c b/external/libtommath-0.42.0/bn_mp_rshd.c deleted file mode 100755 index bb506e9..0000000 --- a/external/libtommath-0.42.0/bn_mp_rshd.c +++ /dev/null @@ -1,72 +0,0 @@ -#include -#ifdef BN_MP_RSHD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* shift right a certain amount of digits */ -void mp_rshd (mp_int * a, int b) -{ - int x; - - /* if b <= 0 then ignore it */ - if (b <= 0) { - return; - } - - /* if b > used then simply zero it and return */ - if (a->used <= b) { - mp_zero (a); - return; - } - - { - register mp_digit *bottom, *top; - - /* shift the digits down */ - - /* bottom */ - bottom = a->dp; - - /* top [offset into digits] */ - top = a->dp + b; - - /* this is implemented as a sliding window where - * the window is b-digits long and digits from - * the top of the window are copied to the bottom - * - * e.g. - - b-2 | b-1 | b0 | b1 | b2 | ... | bb | ----> - /\ | ----> - \-------------------/ ----> - */ - for (x = 0; x < (a->used - b); x++) { - *bottom++ = *top++; - } - - /* zero the top digits */ - for (; x < a->used; x++) { - *bottom++ = 0; - } - } - - /* remove excess digits */ - a->used -= b; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_set.c b/external/libtommath-0.42.0/bn_mp_set.c deleted file mode 100755 index 412673a..0000000 --- a/external/libtommath-0.42.0/bn_mp_set.c +++ /dev/null @@ -1,29 +0,0 @@ -#include -#ifdef BN_MP_SET_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* set to a digit */ -void mp_set (mp_int * a, mp_digit b) -{ - mp_zero (a); - a->dp[0] = b & MP_MASK; - a->used = (a->dp[0] != 0) ? 1 : 0; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_set_int.c b/external/libtommath-0.42.0/bn_mp_set_int.c deleted file mode 100755 index 17cfe89..0000000 --- a/external/libtommath-0.42.0/bn_mp_set_int.c +++ /dev/null @@ -1,48 +0,0 @@ -#include -#ifdef BN_MP_SET_INT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* set a 32-bit const */ -int mp_set_int (mp_int * a, unsigned long b) -{ - int x, res; - - mp_zero (a); - - /* set four bits at a time */ - for (x = 0; x < 8; x++) { - /* shift the number up four bits */ - if ((res = mp_mul_2d (a, 4, a)) != MP_OKAY) { - return res; - } - - /* OR in the top four bits of the source */ - a->dp[0] |= (b >> 28) & 15; - - /* shift the source up to the next four bits */ - b <<= 4; - - /* ensure that digits are not clamped off */ - a->used += 1; - } - mp_clamp (a); - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_shrink.c b/external/libtommath-0.42.0/bn_mp_shrink.c deleted file mode 100755 index 2bee381..0000000 --- a/external/libtommath-0.42.0/bn_mp_shrink.c +++ /dev/null @@ -1,40 +0,0 @@ -#include -#ifdef BN_MP_SHRINK_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* shrink a bignum */ -int mp_shrink (mp_int * a) -{ - mp_digit *tmp; - int used = 1; - - if(a->used > 0) - used = a->used; - - if (a->alloc != used) { - if ((tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * used)) == NULL) { - return MP_MEM; - } - a->dp = tmp; - a->alloc = used; - } - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: v0.42.0 $ */ -/* $Date: 2010-06-02 15:09:36 +0200 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_signed_bin_size.c b/external/libtommath-0.42.0/bn_mp_signed_bin_size.c deleted file mode 100755 index b28d402..0000000 --- a/external/libtommath-0.42.0/bn_mp_signed_bin_size.c +++ /dev/null @@ -1,27 +0,0 @@ -#include -#ifdef BN_MP_SIGNED_BIN_SIZE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* get the size for an signed equivalent */ -int mp_signed_bin_size (mp_int * a) -{ - return 1 + mp_unsigned_bin_size (a); -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_sqr.c b/external/libtommath-0.42.0/bn_mp_sqr.c deleted file mode 100755 index b085668..0000000 --- a/external/libtommath-0.42.0/bn_mp_sqr.c +++ /dev/null @@ -1,58 +0,0 @@ -#include -#ifdef BN_MP_SQR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* computes b = a*a */ -int -mp_sqr (mp_int * a, mp_int * b) -{ - int res; - -#ifdef BN_MP_TOOM_SQR_C - /* use Toom-Cook? */ - if (a->used >= TOOM_SQR_CUTOFF) { - res = mp_toom_sqr(a, b); - /* Karatsuba? */ - } else -#endif -#ifdef BN_MP_KARATSUBA_SQR_C -if (a->used >= KARATSUBA_SQR_CUTOFF) { - res = mp_karatsuba_sqr (a, b); - } else -#endif - { -#ifdef BN_FAST_S_MP_SQR_C - /* can we use the fast comba multiplier? */ - if ((a->used * 2 + 1) < MP_WARRAY && - a->used < - (1 << (sizeof(mp_word) * CHAR_BIT - 2*DIGIT_BIT - 1))) { - res = fast_s_mp_sqr (a, b); - } else -#endif -#ifdef BN_S_MP_SQR_C - res = s_mp_sqr (a, b); -#else - res = MP_VAL; -#endif - } - b->sign = MP_ZPOS; - return res; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_sqrmod.c b/external/libtommath-0.42.0/bn_mp_sqrmod.c deleted file mode 100755 index 369028b..0000000 --- a/external/libtommath-0.42.0/bn_mp_sqrmod.c +++ /dev/null @@ -1,41 +0,0 @@ -#include -#ifdef BN_MP_SQRMOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* c = a * a (mod b) */ -int -mp_sqrmod (mp_int * a, mp_int * b, mp_int * c) -{ - int res; - mp_int t; - - if ((res = mp_init (&t)) != MP_OKAY) { - return res; - } - - if ((res = mp_sqr (a, &t)) != MP_OKAY) { - mp_clear (&t); - return res; - } - res = mp_mod (&t, b, c); - mp_clear (&t); - return res; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_sqrt.c b/external/libtommath-0.42.0/bn_mp_sqrt.c deleted file mode 100755 index 983e41c..0000000 --- a/external/libtommath-0.42.0/bn_mp_sqrt.c +++ /dev/null @@ -1,81 +0,0 @@ -#include -#ifdef BN_MP_SQRT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* this function is less generic than mp_n_root, simpler and faster */ -int mp_sqrt(mp_int *arg, mp_int *ret) -{ - int res; - mp_int t1,t2; - - /* must be positive */ - if (arg->sign == MP_NEG) { - return MP_VAL; - } - - /* easy out */ - if (mp_iszero(arg) == MP_YES) { - mp_zero(ret); - return MP_OKAY; - } - - if ((res = mp_init_copy(&t1, arg)) != MP_OKAY) { - return res; - } - - if ((res = mp_init(&t2)) != MP_OKAY) { - goto E2; - } - - /* First approx. (not very bad for large arg) */ - mp_rshd (&t1,t1.used/2); - - /* t1 > 0 */ - if ((res = mp_div(arg,&t1,&t2,NULL)) != MP_OKAY) { - goto E1; - } - if ((res = mp_add(&t1,&t2,&t1)) != MP_OKAY) { - goto E1; - } - if ((res = mp_div_2(&t1,&t1)) != MP_OKAY) { - goto E1; - } - /* And now t1 > sqrt(arg) */ - do { - if ((res = mp_div(arg,&t1,&t2,NULL)) != MP_OKAY) { - goto E1; - } - if ((res = mp_add(&t1,&t2,&t1)) != MP_OKAY) { - goto E1; - } - if ((res = mp_div_2(&t1,&t1)) != MP_OKAY) { - goto E1; - } - /* t1 >= sqrt(arg) >= t2 at this point */ - } while (mp_cmp_mag(&t1,&t2) == MP_GT); - - mp_exch(&t1,ret); - -E1: mp_clear(&t2); -E2: mp_clear(&t1); - return res; -} - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_sub.c b/external/libtommath-0.42.0/bn_mp_sub.c deleted file mode 100755 index 3c8e5d4..0000000 --- a/external/libtommath-0.42.0/bn_mp_sub.c +++ /dev/null @@ -1,59 +0,0 @@ -#include -#ifdef BN_MP_SUB_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* high level subtraction (handles signs) */ -int -mp_sub (mp_int * a, mp_int * b, mp_int * c) -{ - int sa, sb, res; - - sa = a->sign; - sb = b->sign; - - if (sa != sb) { - /* subtract a negative from a positive, OR */ - /* subtract a positive from a negative. */ - /* In either case, ADD their magnitudes, */ - /* and use the sign of the first number. */ - c->sign = sa; - res = s_mp_add (a, b, c); - } else { - /* subtract a positive from a positive, OR */ - /* subtract a negative from a negative. */ - /* First, take the difference between their */ - /* magnitudes, then... */ - if (mp_cmp_mag (a, b) != MP_LT) { - /* Copy the sign from the first */ - c->sign = sa; - /* The first has a larger or equal magnitude */ - res = s_mp_sub (a, b, c); - } else { - /* The result has the *opposite* sign from */ - /* the first number. */ - c->sign = (sa == MP_ZPOS) ? MP_NEG : MP_ZPOS; - /* The second has a larger magnitude */ - res = s_mp_sub (b, a, c); - } - } - return res; -} - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_sub_d.c b/external/libtommath-0.42.0/bn_mp_sub_d.c deleted file mode 100755 index 13b49bc..0000000 --- a/external/libtommath-0.42.0/bn_mp_sub_d.c +++ /dev/null @@ -1,93 +0,0 @@ -#include -#ifdef BN_MP_SUB_D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* single digit subtraction */ -int -mp_sub_d (mp_int * a, mp_digit b, mp_int * c) -{ - mp_digit *tmpa, *tmpc, mu; - int res, ix, oldused; - - /* grow c as required */ - if (c->alloc < a->used + 1) { - if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) { - return res; - } - } - - /* if a is negative just do an unsigned - * addition [with fudged signs] - */ - if (a->sign == MP_NEG) { - a->sign = MP_ZPOS; - res = mp_add_d(a, b, c); - a->sign = c->sign = MP_NEG; - - /* clamp */ - mp_clamp(c); - - return res; - } - - /* setup regs */ - oldused = c->used; - tmpa = a->dp; - tmpc = c->dp; - - /* if a <= b simply fix the single digit */ - if ((a->used == 1 && a->dp[0] <= b) || a->used == 0) { - if (a->used == 1) { - *tmpc++ = b - *tmpa; - } else { - *tmpc++ = b; - } - ix = 1; - - /* negative/1digit */ - c->sign = MP_NEG; - c->used = 1; - } else { - /* positive/size */ - c->sign = MP_ZPOS; - c->used = a->used; - - /* subtract first digit */ - *tmpc = *tmpa++ - b; - mu = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1); - *tmpc++ &= MP_MASK; - - /* handle rest of the digits */ - for (ix = 1; ix < a->used; ix++) { - *tmpc = *tmpa++ - mu; - mu = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1); - *tmpc++ &= MP_MASK; - } - } - - /* zero excess digits */ - while (ix++ < oldused) { - *tmpc++ = 0; - } - mp_clamp(c); - return MP_OKAY; -} - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_submod.c b/external/libtommath-0.42.0/bn_mp_submod.c deleted file mode 100755 index d919c17..0000000 --- a/external/libtommath-0.42.0/bn_mp_submod.c +++ /dev/null @@ -1,42 +0,0 @@ -#include -#ifdef BN_MP_SUBMOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* d = a - b (mod c) */ -int -mp_submod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) -{ - int res; - mp_int t; - - - if ((res = mp_init (&t)) != MP_OKAY) { - return res; - } - - if ((res = mp_sub (a, b, &t)) != MP_OKAY) { - mp_clear (&t); - return res; - } - res = mp_mod (&t, c, d); - mp_clear (&t); - return res; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_to_signed_bin.c b/external/libtommath-0.42.0/bn_mp_to_signed_bin.c deleted file mode 100755 index dda9285..0000000 --- a/external/libtommath-0.42.0/bn_mp_to_signed_bin.c +++ /dev/null @@ -1,33 +0,0 @@ -#include -#ifdef BN_MP_TO_SIGNED_BIN_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* store in signed [big endian] format */ -int mp_to_signed_bin (mp_int * a, unsigned char *b) -{ - int res; - - if ((res = mp_to_unsigned_bin (a, b + 1)) != MP_OKAY) { - return res; - } - b[0] = (unsigned char) ((a->sign == MP_ZPOS) ? 0 : 1); - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_to_signed_bin_n.c b/external/libtommath-0.42.0/bn_mp_to_signed_bin_n.c deleted file mode 100755 index 9e3b011..0000000 --- a/external/libtommath-0.42.0/bn_mp_to_signed_bin_n.c +++ /dev/null @@ -1,31 +0,0 @@ -#include -#ifdef BN_MP_TO_SIGNED_BIN_N_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* store in signed [big endian] format */ -int mp_to_signed_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen) -{ - if (*outlen < (unsigned long)mp_signed_bin_size(a)) { - return MP_VAL; - } - *outlen = mp_signed_bin_size(a); - return mp_to_signed_bin(a, b); -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_to_unsigned_bin.c b/external/libtommath-0.42.0/bn_mp_to_unsigned_bin.c deleted file mode 100755 index 76072a9..0000000 --- a/external/libtommath-0.42.0/bn_mp_to_unsigned_bin.c +++ /dev/null @@ -1,48 +0,0 @@ -#include -#ifdef BN_MP_TO_UNSIGNED_BIN_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* store in unsigned [big endian] format */ -int mp_to_unsigned_bin (mp_int * a, unsigned char *b) -{ - int x, res; - mp_int t; - - if ((res = mp_init_copy (&t, a)) != MP_OKAY) { - return res; - } - - x = 0; - while (mp_iszero (&t) == 0) { -#ifndef MP_8BIT - b[x++] = (unsigned char) (t.dp[0] & 255); -#else - b[x++] = (unsigned char) (t.dp[0] | ((t.dp[1] & 0x01) << 7)); -#endif - if ((res = mp_div_2d (&t, 8, &t, NULL)) != MP_OKAY) { - mp_clear (&t); - return res; - } - } - bn_reverse (b, x); - mp_clear (&t); - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_to_unsigned_bin_n.c b/external/libtommath-0.42.0/bn_mp_to_unsigned_bin_n.c deleted file mode 100755 index 51028d8..0000000 --- a/external/libtommath-0.42.0/bn_mp_to_unsigned_bin_n.c +++ /dev/null @@ -1,31 +0,0 @@ -#include -#ifdef BN_MP_TO_UNSIGNED_BIN_N_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* store in unsigned [big endian] format */ -int mp_to_unsigned_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen) -{ - if (*outlen < (unsigned long)mp_unsigned_bin_size(a)) { - return MP_VAL; - } - *outlen = mp_unsigned_bin_size(a); - return mp_to_unsigned_bin(a, b); -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_toom_mul.c b/external/libtommath-0.42.0/bn_mp_toom_mul.c deleted file mode 100755 index e0fd772..0000000 --- a/external/libtommath-0.42.0/bn_mp_toom_mul.c +++ /dev/null @@ -1,284 +0,0 @@ -#include -#ifdef BN_MP_TOOM_MUL_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* multiplication using the Toom-Cook 3-way algorithm - * - * Much more complicated than Karatsuba but has a lower - * asymptotic running time of O(N**1.464). This algorithm is - * only particularly useful on VERY large inputs - * (we're talking 1000s of digits here...). -*/ -int mp_toom_mul(mp_int *a, mp_int *b, mp_int *c) -{ - mp_int w0, w1, w2, w3, w4, tmp1, tmp2, a0, a1, a2, b0, b1, b2; - int res, B; - - /* init temps */ - if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, - &a0, &a1, &a2, &b0, &b1, - &b2, &tmp1, &tmp2, NULL)) != MP_OKAY) { - return res; - } - - /* B */ - B = MIN(a->used, b->used) / 3; - - /* a = a2 * B**2 + a1 * B + a0 */ - if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_copy(a, &a1)) != MP_OKAY) { - goto ERR; - } - mp_rshd(&a1, B); - mp_mod_2d(&a1, DIGIT_BIT * B, &a1); - - if ((res = mp_copy(a, &a2)) != MP_OKAY) { - goto ERR; - } - mp_rshd(&a2, B*2); - - /* b = b2 * B**2 + b1 * B + b0 */ - if ((res = mp_mod_2d(b, DIGIT_BIT * B, &b0)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_copy(b, &b1)) != MP_OKAY) { - goto ERR; - } - mp_rshd(&b1, B); - mp_mod_2d(&b1, DIGIT_BIT * B, &b1); - - if ((res = mp_copy(b, &b2)) != MP_OKAY) { - goto ERR; - } - mp_rshd(&b2, B*2); - - /* w0 = a0*b0 */ - if ((res = mp_mul(&a0, &b0, &w0)) != MP_OKAY) { - goto ERR; - } - - /* w4 = a2 * b2 */ - if ((res = mp_mul(&a2, &b2, &w4)) != MP_OKAY) { - goto ERR; - } - - /* w1 = (a2 + 2(a1 + 2a0))(b2 + 2(b1 + 2b0)) */ - if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_mul_2(&b0, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp2, &b2, &tmp2)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_mul(&tmp1, &tmp2, &w1)) != MP_OKAY) { - goto ERR; - } - - /* w3 = (a0 + 2(a1 + 2a2))(b0 + 2(b1 + 2b2)) */ - if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_mul_2(&b2, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_mul(&tmp1, &tmp2, &w3)) != MP_OKAY) { - goto ERR; - } - - - /* w2 = (a2 + a1 + a0)(b2 + b1 + b0) */ - if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&b2, &b1, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul(&tmp1, &tmp2, &w2)) != MP_OKAY) { - goto ERR; - } - - /* now solve the matrix - - 0 0 0 0 1 - 1 2 4 8 16 - 1 1 1 1 1 - 16 8 4 2 1 - 1 0 0 0 0 - - using 12 subtractions, 4 shifts, - 2 small divisions and 1 small multiplication - */ - - /* r1 - r4 */ - if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - r0 */ - if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) { - goto ERR; - } - /* r1/2 */ - if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3/2 */ - if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) { - goto ERR; - } - /* r2 - r0 - r4 */ - if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) { - goto ERR; - } - /* r1 - r2 */ - if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - r2 */ - if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { - goto ERR; - } - /* r1 - 8r0 */ - if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - 8r4 */ - if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) { - goto ERR; - } - /* 3r2 - r1 - r3 */ - if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) { - goto ERR; - } - /* r1 - r2 */ - if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - r2 */ - if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { - goto ERR; - } - /* r1/3 */ - if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) { - goto ERR; - } - /* r3/3 */ - if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) { - goto ERR; - } - - /* at this point shift W[n] by B*n */ - if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_add(&w0, &w1, c)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, c, c)) != MP_OKAY) { - goto ERR; - } - -ERR: - mp_clear_multi(&w0, &w1, &w2, &w3, &w4, - &a0, &a1, &a2, &b0, &b1, - &b2, &tmp1, &tmp2, NULL); - return res; -} - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_toom_sqr.c b/external/libtommath-0.42.0/bn_mp_toom_sqr.c deleted file mode 100755 index 9076e6f..0000000 --- a/external/libtommath-0.42.0/bn_mp_toom_sqr.c +++ /dev/null @@ -1,226 +0,0 @@ -#include -#ifdef BN_MP_TOOM_SQR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* squaring using Toom-Cook 3-way algorithm */ -int -mp_toom_sqr(mp_int *a, mp_int *b) -{ - mp_int w0, w1, w2, w3, w4, tmp1, a0, a1, a2; - int res, B; - - /* init temps */ - if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL)) != MP_OKAY) { - return res; - } - - /* B */ - B = a->used / 3; - - /* a = a2 * B**2 + a1 * B + a0 */ - if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_copy(a, &a1)) != MP_OKAY) { - goto ERR; - } - mp_rshd(&a1, B); - mp_mod_2d(&a1, DIGIT_BIT * B, &a1); - - if ((res = mp_copy(a, &a2)) != MP_OKAY) { - goto ERR; - } - mp_rshd(&a2, B*2); - - /* w0 = a0*a0 */ - if ((res = mp_sqr(&a0, &w0)) != MP_OKAY) { - goto ERR; - } - - /* w4 = a2 * a2 */ - if ((res = mp_sqr(&a2, &w4)) != MP_OKAY) { - goto ERR; - } - - /* w1 = (a2 + 2(a1 + 2a0))**2 */ - if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_sqr(&tmp1, &w1)) != MP_OKAY) { - goto ERR; - } - - /* w3 = (a0 + 2(a1 + 2a2))**2 */ - if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_sqr(&tmp1, &w3)) != MP_OKAY) { - goto ERR; - } - - - /* w2 = (a2 + a1 + a0)**2 */ - if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sqr(&tmp1, &w2)) != MP_OKAY) { - goto ERR; - } - - /* now solve the matrix - - 0 0 0 0 1 - 1 2 4 8 16 - 1 1 1 1 1 - 16 8 4 2 1 - 1 0 0 0 0 - - using 12 subtractions, 4 shifts, 2 small divisions and 1 small multiplication. - */ - - /* r1 - r4 */ - if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - r0 */ - if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) { - goto ERR; - } - /* r1/2 */ - if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3/2 */ - if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) { - goto ERR; - } - /* r2 - r0 - r4 */ - if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) { - goto ERR; - } - /* r1 - r2 */ - if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - r2 */ - if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { - goto ERR; - } - /* r1 - 8r0 */ - if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - 8r4 */ - if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) { - goto ERR; - } - /* 3r2 - r1 - r3 */ - if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) { - goto ERR; - } - /* r1 - r2 */ - if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - r2 */ - if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { - goto ERR; - } - /* r1/3 */ - if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) { - goto ERR; - } - /* r3/3 */ - if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) { - goto ERR; - } - - /* at this point shift W[n] by B*n */ - if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_add(&w0, &w1, b)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, b, b)) != MP_OKAY) { - goto ERR; - } - -ERR: - mp_clear_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL); - return res; -} - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_toradix.c b/external/libtommath-0.42.0/bn_mp_toradix.c deleted file mode 100755 index bb95783..0000000 --- a/external/libtommath-0.42.0/bn_mp_toradix.c +++ /dev/null @@ -1,75 +0,0 @@ -#include -#ifdef BN_MP_TORADIX_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* stores a bignum as a ASCII string in a given radix (2..64) */ -int mp_toradix (mp_int * a, char *str, int radix) -{ - int res, digs; - mp_int t; - mp_digit d; - char *_s = str; - - /* check range of the radix */ - if (radix < 2 || radix > 64) { - return MP_VAL; - } - - /* quick out if its zero */ - if (mp_iszero(a) == 1) { - *str++ = '0'; - *str = '\0'; - return MP_OKAY; - } - - if ((res = mp_init_copy (&t, a)) != MP_OKAY) { - return res; - } - - /* if it is negative output a - */ - if (t.sign == MP_NEG) { - ++_s; - *str++ = '-'; - t.sign = MP_ZPOS; - } - - digs = 0; - while (mp_iszero (&t) == 0) { - if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) { - mp_clear (&t); - return res; - } - *str++ = mp_s_rmap[d]; - ++digs; - } - - /* reverse the digits of the string. In this case _s points - * to the first digit [exluding the sign] of the number] - */ - bn_reverse ((unsigned char *)_s, digs); - - /* append a NULL so the string is properly terminated */ - *str = '\0'; - - mp_clear (&t); - return MP_OKAY; -} - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_toradix_n.c b/external/libtommath-0.42.0/bn_mp_toradix_n.c deleted file mode 100755 index 7e425d6..0000000 --- a/external/libtommath-0.42.0/bn_mp_toradix_n.c +++ /dev/null @@ -1,88 +0,0 @@ -#include -#ifdef BN_MP_TORADIX_N_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* stores a bignum as a ASCII string in a given radix (2..64) - * - * Stores upto maxlen-1 chars and always a NULL byte - */ -int mp_toradix_n(mp_int * a, char *str, int radix, int maxlen) -{ - int res, digs; - mp_int t; - mp_digit d; - char *_s = str; - - /* check range of the maxlen, radix */ - if (maxlen < 2 || radix < 2 || radix > 64) { - return MP_VAL; - } - - /* quick out if its zero */ - if (mp_iszero(a) == MP_YES) { - *str++ = '0'; - *str = '\0'; - return MP_OKAY; - } - - if ((res = mp_init_copy (&t, a)) != MP_OKAY) { - return res; - } - - /* if it is negative output a - */ - if (t.sign == MP_NEG) { - /* we have to reverse our digits later... but not the - sign!! */ - ++_s; - - /* store the flag and mark the number as positive */ - *str++ = '-'; - t.sign = MP_ZPOS; - - /* subtract a char */ - --maxlen; - } - - digs = 0; - while (mp_iszero (&t) == 0) { - if (--maxlen < 1) { - /* no more room */ - break; - } - if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) { - mp_clear (&t); - return res; - } - *str++ = mp_s_rmap[d]; - ++digs; - } - - /* reverse the digits of the string. In this case _s points - * to the first digit [exluding the sign] of the number - */ - bn_reverse ((unsigned char *)_s, digs); - - /* append a NULL so the string is properly terminated */ - *str = '\0'; - - mp_clear (&t); - return MP_OKAY; -} - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_unsigned_bin_size.c b/external/libtommath-0.42.0/bn_mp_unsigned_bin_size.c deleted file mode 100755 index b16fdcd..0000000 --- a/external/libtommath-0.42.0/bn_mp_unsigned_bin_size.c +++ /dev/null @@ -1,28 +0,0 @@ -#include -#ifdef BN_MP_UNSIGNED_BIN_SIZE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* get the size for an unsigned equivalent */ -int mp_unsigned_bin_size (mp_int * a) -{ - int size = mp_count_bits (a); - return (size / 8 + ((size & 7) != 0 ? 1 : 0)); -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_xor.c b/external/libtommath-0.42.0/bn_mp_xor.c deleted file mode 100755 index 5744556..0000000 --- a/external/libtommath-0.42.0/bn_mp_xor.c +++ /dev/null @@ -1,51 +0,0 @@ -#include -#ifdef BN_MP_XOR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* XOR two ints together */ -int -mp_xor (mp_int * a, mp_int * b, mp_int * c) -{ - int res, ix, px; - mp_int t, *x; - - if (a->used > b->used) { - if ((res = mp_init_copy (&t, a)) != MP_OKAY) { - return res; - } - px = b->used; - x = b; - } else { - if ((res = mp_init_copy (&t, b)) != MP_OKAY) { - return res; - } - px = a->used; - x = a; - } - - for (ix = 0; ix < px; ix++) { - t.dp[ix] ^= x->dp[ix]; - } - mp_clamp (&t); - mp_exch (c, &t); - mp_clear (&t); - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_mp_zero.c b/external/libtommath-0.42.0/bn_mp_zero.c deleted file mode 100755 index 99e6df2..0000000 --- a/external/libtommath-0.42.0/bn_mp_zero.c +++ /dev/null @@ -1,36 +0,0 @@ -#include -#ifdef BN_MP_ZERO_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* set to zero */ -void mp_zero (mp_int * a) -{ - int n; - mp_digit *tmp; - - a->sign = MP_ZPOS; - a->used = 0; - - tmp = a->dp; - for (n = 0; n < a->alloc; n++) { - *tmp++ = 0; - } -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_prime_tab.c b/external/libtommath-0.42.0/bn_prime_tab.c deleted file mode 100755 index fb5ad08..0000000 --- a/external/libtommath-0.42.0/bn_prime_tab.c +++ /dev/null @@ -1,61 +0,0 @@ -#include -#ifdef BN_PRIME_TAB_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -const mp_digit ltm_prime_tab[] = { - 0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013, - 0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035, - 0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059, - 0x0061, 0x0065, 0x0067, 0x006B, 0x006D, 0x0071, 0x007F, -#ifndef MP_8BIT - 0x0083, - 0x0089, 0x008B, 0x0095, 0x0097, 0x009D, 0x00A3, 0x00A7, 0x00AD, - 0x00B3, 0x00B5, 0x00BF, 0x00C1, 0x00C5, 0x00C7, 0x00D3, 0x00DF, - 0x00E3, 0x00E5, 0x00E9, 0x00EF, 0x00F1, 0x00FB, 0x0101, 0x0107, - 0x010D, 0x010F, 0x0115, 0x0119, 0x011B, 0x0125, 0x0133, 0x0137, - - 0x0139, 0x013D, 0x014B, 0x0151, 0x015B, 0x015D, 0x0161, 0x0167, - 0x016F, 0x0175, 0x017B, 0x017F, 0x0185, 0x018D, 0x0191, 0x0199, - 0x01A3, 0x01A5, 0x01AF, 0x01B1, 0x01B7, 0x01BB, 0x01C1, 0x01C9, - 0x01CD, 0x01CF, 0x01D3, 0x01DF, 0x01E7, 0x01EB, 0x01F3, 0x01F7, - 0x01FD, 0x0209, 0x020B, 0x021D, 0x0223, 0x022D, 0x0233, 0x0239, - 0x023B, 0x0241, 0x024B, 0x0251, 0x0257, 0x0259, 0x025F, 0x0265, - 0x0269, 0x026B, 0x0277, 0x0281, 0x0283, 0x0287, 0x028D, 0x0293, - 0x0295, 0x02A1, 0x02A5, 0x02AB, 0x02B3, 0x02BD, 0x02C5, 0x02CF, - - 0x02D7, 0x02DD, 0x02E3, 0x02E7, 0x02EF, 0x02F5, 0x02F9, 0x0301, - 0x0305, 0x0313, 0x031D, 0x0329, 0x032B, 0x0335, 0x0337, 0x033B, - 0x033D, 0x0347, 0x0355, 0x0359, 0x035B, 0x035F, 0x036D, 0x0371, - 0x0373, 0x0377, 0x038B, 0x038F, 0x0397, 0x03A1, 0x03A9, 0x03AD, - 0x03B3, 0x03B9, 0x03C7, 0x03CB, 0x03D1, 0x03D7, 0x03DF, 0x03E5, - 0x03F1, 0x03F5, 0x03FB, 0x03FD, 0x0407, 0x0409, 0x040F, 0x0419, - 0x041B, 0x0425, 0x0427, 0x042D, 0x043F, 0x0443, 0x0445, 0x0449, - 0x044F, 0x0455, 0x045D, 0x0463, 0x0469, 0x047F, 0x0481, 0x048B, - - 0x0493, 0x049D, 0x04A3, 0x04A9, 0x04B1, 0x04BD, 0x04C1, 0x04C7, - 0x04CD, 0x04CF, 0x04D5, 0x04E1, 0x04EB, 0x04FD, 0x04FF, 0x0503, - 0x0509, 0x050B, 0x0511, 0x0515, 0x0517, 0x051B, 0x0527, 0x0529, - 0x052F, 0x0551, 0x0557, 0x055D, 0x0565, 0x0577, 0x0581, 0x058F, - 0x0593, 0x0595, 0x0599, 0x059F, 0x05A7, 0x05AB, 0x05AD, 0x05B3, - 0x05BF, 0x05C9, 0x05CB, 0x05CF, 0x05D1, 0x05D5, 0x05DB, 0x05E7, - 0x05F3, 0x05FB, 0x0607, 0x060D, 0x0611, 0x0617, 0x061F, 0x0623, - 0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653 -#endif -}; -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_reverse.c b/external/libtommath-0.42.0/bn_reverse.c deleted file mode 100755 index 17cdcc1..0000000 --- a/external/libtommath-0.42.0/bn_reverse.c +++ /dev/null @@ -1,39 +0,0 @@ -#include -#ifdef BN_REVERSE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* reverse an array, used for radix code */ -void -bn_reverse (unsigned char *s, int len) -{ - int ix, iy; - unsigned char t; - - ix = 0; - iy = len - 1; - while (ix < iy) { - t = s[ix]; - s[ix] = s[iy]; - s[iy] = t; - ++ix; - --iy; - } -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_s_mp_add.c b/external/libtommath-0.42.0/bn_s_mp_add.c deleted file mode 100755 index 0ca20b8..0000000 --- a/external/libtommath-0.42.0/bn_s_mp_add.c +++ /dev/null @@ -1,109 +0,0 @@ -#include -#ifdef BN_S_MP_ADD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* low level addition, based on HAC pp.594, Algorithm 14.7 */ -int -s_mp_add (mp_int * a, mp_int * b, mp_int * c) -{ - mp_int *x; - int olduse, res, min, max; - - /* find sizes, we let |a| <= |b| which means we have to sort - * them. "x" will point to the input with the most digits - */ - if (a->used > b->used) { - min = b->used; - max = a->used; - x = a; - } else { - min = a->used; - max = b->used; - x = b; - } - - /* init result */ - if (c->alloc < max + 1) { - if ((res = mp_grow (c, max + 1)) != MP_OKAY) { - return res; - } - } - - /* get old used digit count and set new one */ - olduse = c->used; - c->used = max + 1; - - { - register mp_digit u, *tmpa, *tmpb, *tmpc; - register int i; - - /* alias for digit pointers */ - - /* first input */ - tmpa = a->dp; - - /* second input */ - tmpb = b->dp; - - /* destination */ - tmpc = c->dp; - - /* zero the carry */ - u = 0; - for (i = 0; i < min; i++) { - /* Compute the sum at one digit, T[i] = A[i] + B[i] + U */ - *tmpc = *tmpa++ + *tmpb++ + u; - - /* U = carry bit of T[i] */ - u = *tmpc >> ((mp_digit)DIGIT_BIT); - - /* take away carry bit from T[i] */ - *tmpc++ &= MP_MASK; - } - - /* now copy higher words if any, that is in A+B - * if A or B has more digits add those in - */ - if (min != max) { - for (; i < max; i++) { - /* T[i] = X[i] + U */ - *tmpc = x->dp[i] + u; - - /* U = carry bit of T[i] */ - u = *tmpc >> ((mp_digit)DIGIT_BIT); - - /* take away carry bit from T[i] */ - *tmpc++ &= MP_MASK; - } - } - - /* add carry */ - *tmpc++ = u; - - /* clear digits above oldused */ - for (i = c->used; i < olduse; i++) { - *tmpc++ = 0; - } - } - - mp_clamp (c); - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_s_mp_exptmod.c b/external/libtommath-0.42.0/bn_s_mp_exptmod.c deleted file mode 100755 index bc02a28..0000000 --- a/external/libtommath-0.42.0/bn_s_mp_exptmod.c +++ /dev/null @@ -1,252 +0,0 @@ -#include -#ifdef BN_S_MP_EXPTMOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#ifdef MP_LOW_MEM - #define TAB_SIZE 32 -#else - #define TAB_SIZE 256 -#endif - -int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) -{ - mp_int M[TAB_SIZE], res, mu; - mp_digit buf; - int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize; - int (*redux)(mp_int*,mp_int*,mp_int*); - - /* find window size */ - x = mp_count_bits (X); - if (x <= 7) { - winsize = 2; - } else if (x <= 36) { - winsize = 3; - } else if (x <= 140) { - winsize = 4; - } else if (x <= 450) { - winsize = 5; - } else if (x <= 1303) { - winsize = 6; - } else if (x <= 3529) { - winsize = 7; - } else { - winsize = 8; - } - -#ifdef MP_LOW_MEM - if (winsize > 5) { - winsize = 5; - } -#endif - - /* init M array */ - /* init first cell */ - if ((err = mp_init(&M[1])) != MP_OKAY) { - return err; - } - - /* now init the second half of the array */ - for (x = 1<<(winsize-1); x < (1 << winsize); x++) { - if ((err = mp_init(&M[x])) != MP_OKAY) { - for (y = 1<<(winsize-1); y < x; y++) { - mp_clear (&M[y]); - } - mp_clear(&M[1]); - return err; - } - } - - /* create mu, used for Barrett reduction */ - if ((err = mp_init (&mu)) != MP_OKAY) { - goto LBL_M; - } - - if (redmode == 0) { - if ((err = mp_reduce_setup (&mu, P)) != MP_OKAY) { - goto LBL_MU; - } - redux = mp_reduce; - } else { - if ((err = mp_reduce_2k_setup_l (P, &mu)) != MP_OKAY) { - goto LBL_MU; - } - redux = mp_reduce_2k_l; - } - - /* create M table - * - * The M table contains powers of the base, - * e.g. M[x] = G**x mod P - * - * The first half of the table is not - * computed though accept for M[0] and M[1] - */ - if ((err = mp_mod (G, P, &M[1])) != MP_OKAY) { - goto LBL_MU; - } - - /* compute the value at M[1<<(winsize-1)] by squaring - * M[1] (winsize-1) times - */ - if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) { - goto LBL_MU; - } - - for (x = 0; x < (winsize - 1); x++) { - /* square it */ - if ((err = mp_sqr (&M[1 << (winsize - 1)], - &M[1 << (winsize - 1)])) != MP_OKAY) { - goto LBL_MU; - } - - /* reduce modulo P */ - if ((err = redux (&M[1 << (winsize - 1)], P, &mu)) != MP_OKAY) { - goto LBL_MU; - } - } - - /* create upper table, that is M[x] = M[x-1] * M[1] (mod P) - * for x = (2**(winsize - 1) + 1) to (2**winsize - 1) - */ - for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) { - if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) { - goto LBL_MU; - } - if ((err = redux (&M[x], P, &mu)) != MP_OKAY) { - goto LBL_MU; - } - } - - /* setup result */ - if ((err = mp_init (&res)) != MP_OKAY) { - goto LBL_MU; - } - mp_set (&res, 1); - - /* set initial mode and bit cnt */ - mode = 0; - bitcnt = 1; - buf = 0; - digidx = X->used - 1; - bitcpy = 0; - bitbuf = 0; - - for (;;) { - /* grab next digit as required */ - if (--bitcnt == 0) { - /* if digidx == -1 we are out of digits */ - if (digidx == -1) { - break; - } - /* read next digit and reset the bitcnt */ - buf = X->dp[digidx--]; - bitcnt = (int) DIGIT_BIT; - } - - /* grab the next msb from the exponent */ - y = (buf >> (mp_digit)(DIGIT_BIT - 1)) & 1; - buf <<= (mp_digit)1; - - /* if the bit is zero and mode == 0 then we ignore it - * These represent the leading zero bits before the first 1 bit - * in the exponent. Technically this opt is not required but it - * does lower the # of trivial squaring/reductions used - */ - if (mode == 0 && y == 0) { - continue; - } - - /* if the bit is zero and mode == 1 then we square */ - if (mode == 1 && y == 0) { - if ((err = mp_sqr (&res, &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, &mu)) != MP_OKAY) { - goto LBL_RES; - } - continue; - } - - /* else we add it to the window */ - bitbuf |= (y << (winsize - ++bitcpy)); - mode = 2; - - if (bitcpy == winsize) { - /* ok window is filled so square as required and multiply */ - /* square first */ - for (x = 0; x < winsize; x++) { - if ((err = mp_sqr (&res, &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, &mu)) != MP_OKAY) { - goto LBL_RES; - } - } - - /* then multiply */ - if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, &mu)) != MP_OKAY) { - goto LBL_RES; - } - - /* empty window and reset */ - bitcpy = 0; - bitbuf = 0; - mode = 1; - } - } - - /* if bits remain then square/multiply */ - if (mode == 2 && bitcpy > 0) { - /* square then multiply if the bit is set */ - for (x = 0; x < bitcpy; x++) { - if ((err = mp_sqr (&res, &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, &mu)) != MP_OKAY) { - goto LBL_RES; - } - - bitbuf <<= 1; - if ((bitbuf & (1 << winsize)) != 0) { - /* then multiply */ - if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, &mu)) != MP_OKAY) { - goto LBL_RES; - } - } - } - } - - mp_exch (&res, Y); - err = MP_OKAY; -LBL_RES:mp_clear (&res); -LBL_MU:mp_clear (&mu); -LBL_M: - mp_clear(&M[1]); - for (x = 1<<(winsize-1); x < (1 << winsize); x++) { - mp_clear (&M[x]); - } - return err; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_s_mp_mul_digs.c b/external/libtommath-0.42.0/bn_s_mp_mul_digs.c deleted file mode 100755 index 86196bf..0000000 --- a/external/libtommath-0.42.0/bn_s_mp_mul_digs.c +++ /dev/null @@ -1,90 +0,0 @@ -#include -#ifdef BN_S_MP_MUL_DIGS_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* multiplies |a| * |b| and only computes upto digs digits of result - * HAC pp. 595, Algorithm 14.12 Modified so you can control how - * many digits of output are created. - */ -int s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) -{ - mp_int t; - int res, pa, pb, ix, iy; - mp_digit u; - mp_word r; - mp_digit tmpx, *tmpt, *tmpy; - - /* can we use the fast multiplier? */ - if (((digs) < MP_WARRAY) && - MIN (a->used, b->used) < - (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { - return fast_s_mp_mul_digs (a, b, c, digs); - } - - if ((res = mp_init_size (&t, digs)) != MP_OKAY) { - return res; - } - t.used = digs; - - /* compute the digits of the product directly */ - pa = a->used; - for (ix = 0; ix < pa; ix++) { - /* set the carry to zero */ - u = 0; - - /* limit ourselves to making digs digits of output */ - pb = MIN (b->used, digs - ix); - - /* setup some aliases */ - /* copy of the digit from a used within the nested loop */ - tmpx = a->dp[ix]; - - /* an alias for the destination shifted ix places */ - tmpt = t.dp + ix; - - /* an alias for the digits of b */ - tmpy = b->dp; - - /* compute the columns of the output and propagate the carry */ - for (iy = 0; iy < pb; iy++) { - /* compute the column as a mp_word */ - r = ((mp_word)*tmpt) + - ((mp_word)tmpx) * ((mp_word)*tmpy++) + - ((mp_word) u); - - /* the new column is the lower part of the result */ - *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); - - /* get the carry word from the result */ - u = (mp_digit) (r >> ((mp_word) DIGIT_BIT)); - } - /* set carry if it is placed below digs */ - if (ix + iy < digs) { - *tmpt = u; - } - } - - mp_clamp (&t); - mp_exch (&t, c); - - mp_clear (&t); - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_s_mp_mul_high_digs.c b/external/libtommath-0.42.0/bn_s_mp_mul_high_digs.c deleted file mode 100755 index 019014e..0000000 --- a/external/libtommath-0.42.0/bn_s_mp_mul_high_digs.c +++ /dev/null @@ -1,81 +0,0 @@ -#include -#ifdef BN_S_MP_MUL_HIGH_DIGS_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* multiplies |a| * |b| and does not compute the lower digs digits - * [meant to get the higher part of the product] - */ -int -s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs) -{ - mp_int t; - int res, pa, pb, ix, iy; - mp_digit u; - mp_word r; - mp_digit tmpx, *tmpt, *tmpy; - - /* can we use the fast multiplier? */ -#ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C - if (((a->used + b->used + 1) < MP_WARRAY) - && MIN (a->used, b->used) < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { - return fast_s_mp_mul_high_digs (a, b, c, digs); - } -#endif - - if ((res = mp_init_size (&t, a->used + b->used + 1)) != MP_OKAY) { - return res; - } - t.used = a->used + b->used + 1; - - pa = a->used; - pb = b->used; - for (ix = 0; ix < pa; ix++) { - /* clear the carry */ - u = 0; - - /* left hand side of A[ix] * B[iy] */ - tmpx = a->dp[ix]; - - /* alias to the address of where the digits will be stored */ - tmpt = &(t.dp[digs]); - - /* alias for where to read the right hand side from */ - tmpy = b->dp + (digs - ix); - - for (iy = digs - ix; iy < pb; iy++) { - /* calculate the double precision result */ - r = ((mp_word)*tmpt) + - ((mp_word)tmpx) * ((mp_word)*tmpy++) + - ((mp_word) u); - - /* get the lower part */ - *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); - - /* carry the carry */ - u = (mp_digit) (r >> ((mp_word) DIGIT_BIT)); - } - *tmpt = u; - } - mp_clamp (&t); - mp_exch (&t, c); - mp_clear (&t); - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_s_mp_sqr.c b/external/libtommath-0.42.0/bn_s_mp_sqr.c deleted file mode 100755 index 90c465d..0000000 --- a/external/libtommath-0.42.0/bn_s_mp_sqr.c +++ /dev/null @@ -1,84 +0,0 @@ -#include -#ifdef BN_S_MP_SQR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* low level squaring, b = a*a, HAC pp.596-597, Algorithm 14.16 */ -int s_mp_sqr (mp_int * a, mp_int * b) -{ - mp_int t; - int res, ix, iy, pa; - mp_word r; - mp_digit u, tmpx, *tmpt; - - pa = a->used; - if ((res = mp_init_size (&t, 2*pa + 1)) != MP_OKAY) { - return res; - } - - /* default used is maximum possible size */ - t.used = 2*pa + 1; - - for (ix = 0; ix < pa; ix++) { - /* first calculate the digit at 2*ix */ - /* calculate double precision result */ - r = ((mp_word) t.dp[2*ix]) + - ((mp_word)a->dp[ix])*((mp_word)a->dp[ix]); - - /* store lower part in result */ - t.dp[ix+ix] = (mp_digit) (r & ((mp_word) MP_MASK)); - - /* get the carry */ - u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); - - /* left hand side of A[ix] * A[iy] */ - tmpx = a->dp[ix]; - - /* alias for where to store the results */ - tmpt = t.dp + (2*ix + 1); - - for (iy = ix + 1; iy < pa; iy++) { - /* first calculate the product */ - r = ((mp_word)tmpx) * ((mp_word)a->dp[iy]); - - /* now calculate the double precision result, note we use - * addition instead of *2 since it's easier to optimize - */ - r = ((mp_word) *tmpt) + r + r + ((mp_word) u); - - /* store lower part */ - *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); - - /* get carry */ - u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); - } - /* propagate upwards */ - while (u != ((mp_digit) 0)) { - r = ((mp_word) *tmpt) + ((mp_word) u); - *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); - u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); - } - } - - mp_clamp (&t); - mp_exch (&t, b); - mp_clear (&t); - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bn_s_mp_sub.c b/external/libtommath-0.42.0/bn_s_mp_sub.c deleted file mode 100755 index ccea6bd..0000000 --- a/external/libtommath-0.42.0/bn_s_mp_sub.c +++ /dev/null @@ -1,89 +0,0 @@ -#include -#ifdef BN_S_MP_SUB_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* low level subtraction (assumes |a| > |b|), HAC pp.595 Algorithm 14.9 */ -int -s_mp_sub (mp_int * a, mp_int * b, mp_int * c) -{ - int olduse, res, min, max; - - /* find sizes */ - min = b->used; - max = a->used; - - /* init result */ - if (c->alloc < max) { - if ((res = mp_grow (c, max)) != MP_OKAY) { - return res; - } - } - olduse = c->used; - c->used = max; - - { - register mp_digit u, *tmpa, *tmpb, *tmpc; - register int i; - - /* alias for digit pointers */ - tmpa = a->dp; - tmpb = b->dp; - tmpc = c->dp; - - /* set carry to zero */ - u = 0; - for (i = 0; i < min; i++) { - /* T[i] = A[i] - B[i] - U */ - *tmpc = *tmpa++ - *tmpb++ - u; - - /* U = carry bit of T[i] - * Note this saves performing an AND operation since - * if a carry does occur it will propagate all the way to the - * MSB. As a result a single shift is enough to get the carry - */ - u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1)); - - /* Clear carry from T[i] */ - *tmpc++ &= MP_MASK; - } - - /* now copy higher words if any, e.g. if A has more digits than B */ - for (; i < max; i++) { - /* T[i] = A[i] - U */ - *tmpc = *tmpa++ - u; - - /* U = carry bit of T[i] */ - u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1)); - - /* Clear carry from T[i] */ - *tmpc++ &= MP_MASK; - } - - /* clear digits above used (since we may not have grown result above) */ - for (i = c->used; i < olduse; i++) { - *tmpc++ = 0; - } - } - - mp_clamp (c); - return MP_OKAY; -} - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/bncore.c b/external/libtommath-0.42.0/bncore.c deleted file mode 100755 index 1a0ac2c..0000000 --- a/external/libtommath-0.42.0/bncore.c +++ /dev/null @@ -1,36 +0,0 @@ -#include -#ifdef BNCORE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* Known optimal configurations - - CPU /Compiler /MUL CUTOFF/SQR CUTOFF -------------------------------------------------------------- - Intel P4 Northwood /GCC v3.4.1 / 88/ 128/LTM 0.32 ;-) - AMD Athlon64 /GCC v3.4.4 / 80/ 120/LTM 0.35 - -*/ - -int KARATSUBA_MUL_CUTOFF = 80, /* Min. number of digits before Karatsuba multiplication is used. */ - KARATSUBA_SQR_CUTOFF = 120, /* Min. number of digits before Karatsuba squaring is used. */ - - TOOM_MUL_CUTOFF = 350, /* no optimal values of these are known yet so set em high */ - TOOM_SQR_CUTOFF = 400; -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ diff --git a/external/libtommath-0.42.0/booker.pl b/external/libtommath-0.42.0/booker.pl deleted file mode 100755 index 49f1889..0000000 --- a/external/libtommath-0.42.0/booker.pl +++ /dev/null @@ -1,265 +0,0 @@ -#!/bin/perl -# -#Used to prepare the book "tommath.src" for LaTeX by pre-processing it into a .tex file -# -#Essentially you write the "tommath.src" as normal LaTex except where you want code snippets you put -# -#EXAM,file -# -#This preprocessor will then open "file" and insert it as a verbatim copy. -# -#Tom St Denis - -#get graphics type -if (shift =~ /PDF/) { - $graph = ""; -} else { - $graph = ".ps"; -} - -open(IN,"tommath.tex") or die "Can't open destination file"; - -print "Scanning for sections\n"; -$chapter = $section = $subsection = 0; -$x = 0; -while () { - print "."; - if (!(++$x % 80)) { print "\n"; } - #update the headings - if (~($_ =~ /\*/)) { - if ($_ =~ /\\chapter{.+}/) { - ++$chapter; - $section = $subsection = 0; - } elsif ($_ =~ /\\section{.+}/) { - ++$section; - $subsection = 0; - } elsif ($_ =~ /\\subsection{.+}/) { - ++$subsection; - } - } - - if ($_ =~ m/MARK/) { - @m = split(",",$_); - chomp(@m[1]); - $index1{@m[1]} = $chapter; - $index2{@m[1]} = $section; - $index3{@m[1]} = $subsection; - } -} -close(IN); - -open(IN,") { - ++$readline; - ++$srcline; - - if ($_ =~ m/MARK/) { - } elsif ($_ =~ m/EXAM/ || $_ =~ m/LIST/) { - if ($_ =~ m/EXAM/) { - $skipheader = 1; - } else { - $skipheader = 0; - } - - # EXAM,file - chomp($_); - @m = split(",",$_); - open(SRC,"<$m[1]") or die "Error:$srcline:Can't open source file $m[1]"; - - print "$srcline:Inserting $m[1]:"; - - $line = 0; - $tmp = $m[1]; - $tmp =~ s/_/"\\_"/ge; - print OUT "\\vspace{+3mm}\\begin{small}\n\\hspace{-5.1mm}{\\bf File}: $tmp\n\\vspace{-3mm}\n\\begin{alltt}\n"; - $wroteline += 5; - - if ($skipheader == 1) { - # scan till next end of comment, e.g. skip license - while () { - $text[$line++] = $_; - last if ($_ =~ /math\.libtomcrypt\.com/); - } - ; - } - - $inline = 0; - while () { - next if ($_ =~ /\$Source/); - next if ($_ =~ /\$Revision/); - next if ($_ =~ /\$Date/); - $text[$line++] = $_; - ++$inline; - chomp($_); - $_ =~ s/\t/" "/ge; - $_ =~ s/{/"^{"/ge; - $_ =~ s/}/"^}"/ge; - $_ =~ s/\\/'\symbol{92}'/ge; - $_ =~ s/\^/"\\"/ge; - - printf OUT ("%03d ", $line); - for ($x = 0; $x < length($_); $x++) { - print OUT chr(vec($_, $x, 8)); - if ($x == 75) { - print OUT "\n "; - ++$wroteline; - } - } - print OUT "\n"; - ++$wroteline; - } - $totlines = $line; - print OUT "\\end{alltt}\n\\end{small}\n"; - close(SRC); - print "$inline lines\n"; - $wroteline += 2; - } elsif ($_ =~ m/@\d+,.+@/) { - # line contains [number,text] - # e.g. @14,for (ix = 0)@ - $txt = $_; - while ($txt =~ m/@\d+,.+@/) { - @m = split("@",$txt); # splits into text, one, two - @parms = split(",",$m[1]); # splits one,two into two elements - - # now search from $parms[0] down for $parms[1] - $found1 = 0; - $found2 = 0; - for ($i = $parms[0]; $i < $totlines && $found1 == 0; $i++) { - if ($text[$i] =~ m/\Q$parms[1]\E/) { - $foundline1 = $i + 1; - $found1 = 1; - } - } - - # now search backwards - for ($i = $parms[0] - 1; $i >= 0 && $found2 == 0; $i--) { - if ($text[$i] =~ m/\Q$parms[1]\E/) { - $foundline2 = $i + 1; - $found2 = 1; - } - } - - # now use the closest match or the first if tied - if ($found1 == 1 && $found2 == 0) { - $found = 1; - $foundline = $foundline1; - } elsif ($found1 == 0 && $found2 == 1) { - $found = 1; - $foundline = $foundline2; - } elsif ($found1 == 1 && $found2 == 1) { - $found = 1; - if (($foundline1 - $parms[0]) <= ($parms[0] - $foundline2)) { - $foundline = $foundline1; - } else { - $foundline = $foundline2; - } - } else { - $found = 0; - } - - # if found replace - if ($found == 1) { - $delta = $parms[0] - $foundline; - print "Found replacement tag for \"$parms[1]\" on line $srcline which refers to line $foundline (delta $delta)\n"; - $_ =~ s/@\Q$m[1]\E@/$foundline/; - } else { - print "ERROR: The tag \"$parms[1]\" on line $srcline was not found in the most recently parsed source!\n"; - } - - # remake the rest of the line - $cnt = @m; - $txt = ""; - for ($i = 2; $i < $cnt; $i++) { - $txt = $txt . $m[$i] . "@"; - } - } - print OUT $_; - ++$wroteline; - } elsif ($_ =~ /~.+~/) { - # line contains a ~text~ pair used to refer to indexing :-) - $txt = $_; - while ($txt =~ /~.+~/) { - @m = split("~", $txt); - - # word is the second position - $word = @m[1]; - $a = $index1{$word}; - $b = $index2{$word}; - $c = $index3{$word}; - - # if chapter (a) is zero it wasn't found - if ($a == 0) { - print "ERROR: the tag \"$word\" on line $srcline was not found previously marked.\n"; - } else { - # format the tag as x, x.y or x.y.z depending on the values - $str = $a; - $str = $str . ".$b" if ($b != 0); - $str = $str . ".$c" if ($c != 0); - - if ($b == 0 && $c == 0) { - # its a chapter - if ($a <= 10) { - if ($a == 1) { - $str = "chapter one"; - } elsif ($a == 2) { - $str = "chapter two"; - } elsif ($a == 3) { - $str = "chapter three"; - } elsif ($a == 4) { - $str = "chapter four"; - } elsif ($a == 5) { - $str = "chapter five"; - } elsif ($a == 6) { - $str = "chapter six"; - } elsif ($a == 7) { - $str = "chapter seven"; - } elsif ($a == 8) { - $str = "chapter eight"; - } elsif ($a == 9) { - $str = "chapter nine"; - } elsif ($a == 10) { - $str = "chapter ten"; - } - } else { - $str = "chapter " . $str; - } - } else { - $str = "section " . $str if ($b != 0 && $c == 0); - $str = "sub-section " . $str if ($b != 0 && $c != 0); - } - - #substitute - $_ =~ s/~\Q$word\E~/$str/; - - print "Found replacement tag for marker \"$word\" on line $srcline which refers to $str\n"; - } - - # remake rest of the line - $cnt = @m; - $txt = ""; - for ($i = 2; $i < $cnt; $i++) { - $txt = $txt . $m[$i] . "~"; - } - } - print OUT $_; - ++$wroteline; - } elsif ($_ =~ m/FIGU/) { - # FIGU,file,caption - chomp($_); - @m = split(",", $_); - print OUT "\\begin{center}\n\\begin{figure}[here]\n\\includegraphics{pics/$m[1]$graph}\n"; - print OUT "\\caption{$m[2]}\n\\label{pic:$m[1]}\n\\end{figure}\n\\end{center}\n"; - $wroteline += 4; - } else { - print OUT $_; - ++$wroteline; - } -} -print "Read $readline lines, wrote $wroteline lines\n"; - -close (OUT); -close (IN); diff --git a/external/libtommath-0.42.0/callgraph.txt b/external/libtommath-0.42.0/callgraph.txt deleted file mode 100755 index 2efcf24..0000000 --- a/external/libtommath-0.42.0/callgraph.txt +++ /dev/null @@ -1,11913 +0,0 @@ -BN_PRIME_TAB_C - - -BN_MP_SQRT_C -+--->BN_MP_N_ROOT_C -| +--->BN_MP_INIT_C -| +--->BN_MP_SET_C -| | +--->BN_MP_ZERO_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_EXPT_D_C -| | +--->BN_MP_INIT_COPY_C -| | +--->BN_MP_SQR_C -| | | +--->BN_MP_TOOM_SQR_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_MUL_2_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_2_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_3_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_KARATSUBA_SQR_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_FAST_S_MP_SQR_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SQR_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_CLEAR_C -| | +--->BN_MP_MUL_C -| | | +--->BN_MP_TOOM_MUL_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_MUL_2_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_2_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_3_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLEAR_MULTI_C -| | | +--->BN_MP_KARATSUBA_MUL_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_MUL_DIGS_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| +--->BN_MP_MUL_C -| | +--->BN_MP_TOOM_MUL_C -| | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_MUL_2_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_2_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_2D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_3_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLEAR_MULTI_C -| | | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_KARATSUBA_MUL_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_MUL_DIGS_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_C -| +--->BN_MP_SUB_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_MUL_D_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_DIV_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_COUNT_BITS_C -| | +--->BN_MP_ABS_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2D_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_MULTI_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_INIT_COPY_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_CMP_C -| | +--->BN_MP_CMP_MAG_C -| +--->BN_MP_SUB_D_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_D_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_ZERO_C -+--->BN_MP_INIT_COPY_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -+--->BN_MP_RSHD_C -+--->BN_MP_DIV_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_INIT_MULTI_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_SET_C -| +--->BN_MP_COUNT_BITS_C -| +--->BN_MP_ABS_C -| +--->BN_MP_MUL_2D_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_C -| +--->BN_MP_SUB_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_ADD_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_DIV_2D_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLEAR_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| +--->BN_MP_EXCH_C -| +--->BN_MP_CLEAR_MULTI_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_INIT_SIZE_C -| +--->BN_MP_LSHD_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_MUL_D_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CLAMP_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_ADD_C -| +--->BN_S_MP_ADD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -+--->BN_MP_DIV_2_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_CMP_MAG_C -+--->BN_MP_EXCH_C -+--->BN_MP_CLEAR_C - - -BN_MP_CMP_D_C - - -BN_MP_EXCH_C - - -BN_MP_IS_SQUARE_C -+--->BN_MP_MOD_D_C -| +--->BN_MP_DIV_D_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_DIV_2D_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_INIT_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | +--->BN_MP_DIV_3_C -| | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_INIT_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_INIT_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C -+--->BN_MP_INIT_SET_INT_C -| +--->BN_MP_INIT_C -| +--->BN_MP_SET_INT_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLAMP_C -+--->BN_MP_MOD_C -| +--->BN_MP_INIT_C -| +--->BN_MP_DIV_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_SET_C -| | +--->BN_MP_COUNT_BITS_C -| | +--->BN_MP_ABS_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2D_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_MULTI_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_INIT_COPY_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_CLEAR_C -| +--->BN_MP_ADD_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C -+--->BN_MP_GET_INT_C -+--->BN_MP_SQRT_C -| +--->BN_MP_N_ROOT_C -| | +--->BN_MP_INIT_C -| | +--->BN_MP_SET_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_EXPT_D_C -| | | +--->BN_MP_INIT_COPY_C -| | | +--->BN_MP_SQR_C -| | | | +--->BN_MP_TOOM_SQR_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | | +--->BN_MP_CLEAR_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_MUL_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_3_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | | +--->BN_MP_CLEAR_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_KARATSUBA_SQR_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_FAST_S_MP_SQR_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_SQR_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_MUL_C -| | | | +--->BN_MP_TOOM_MUL_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_MUL_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_3_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLEAR_MULTI_C -| | | | +--->BN_MP_KARATSUBA_MUL_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | +--->BN_MP_MUL_C -| | | +--->BN_MP_TOOM_MUL_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_MUL_2_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_2_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_3_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_KARATSUBA_MUL_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_MUL_DIGS_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_COUNT_BITS_C -| | | +--->BN_MP_ABS_C -| | | +--->BN_MP_MUL_2D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_2D_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_MULTI_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_INIT_COPY_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_CMP_C -| | | +--->BN_MP_CMP_MAG_C -| | +--->BN_MP_SUB_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ADD_D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_ZERO_C -| +--->BN_MP_INIT_COPY_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| +--->BN_MP_RSHD_C -| +--->BN_MP_DIV_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_SET_C -| | +--->BN_MP_COUNT_BITS_C -| | +--->BN_MP_ABS_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2D_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_MULTI_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_ADD_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_DIV_2_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_MP_EXCH_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_SQR_C -| +--->BN_MP_TOOM_SQR_C -| | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_INIT_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_RSHD_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_MUL_2_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_3_C -| | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_INIT_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_MULTI_C -| | | +--->BN_MP_CLEAR_C -| +--->BN_MP_KARATSUBA_SQR_C -| | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_INIT_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | +--->BN_MP_ADD_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_C -| +--->BN_FAST_S_MP_SQR_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_S_MP_SQR_C -| | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_INIT_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C -+--->BN_MP_CMP_MAG_C -+--->BN_MP_CLEAR_C - - -BN_MP_NEG_C -+--->BN_MP_COPY_C -| +--->BN_MP_GROW_C - - -BN_MP_EXPTMOD_C -+--->BN_MP_INIT_C -+--->BN_MP_INVMOD_C -| +--->BN_FAST_MP_INVMOD_C -| | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_MOD_C -| | | +--->BN_MP_DIV_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_SET_C -| | | | +--->BN_MP_COUNT_BITS_C -| | | | +--->BN_MP_ABS_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_2D_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CLEAR_C -| | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_INIT_COPY_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | +--->BN_MP_SET_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_DIV_2_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_C -| | | +--->BN_MP_CMP_MAG_C -| | +--->BN_MP_CMP_D_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_MULTI_C -| | | +--->BN_MP_CLEAR_C -| +--->BN_MP_INVMOD_SLOW_C -| | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_MOD_C -| | | +--->BN_MP_DIV_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_SET_C -| | | | +--->BN_MP_COUNT_BITS_C -| | | | +--->BN_MP_ABS_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_2D_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CLEAR_C -| | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_INIT_COPY_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_SET_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_DIV_2_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_C -| | | +--->BN_MP_CMP_MAG_C -| | +--->BN_MP_CMP_D_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_MULTI_C -| | | +--->BN_MP_CLEAR_C -+--->BN_MP_CLEAR_C -+--->BN_MP_ABS_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -+--->BN_MP_CLEAR_MULTI_C -+--->BN_MP_REDUCE_IS_2K_L_C -+--->BN_S_MP_EXPTMOD_C -| +--->BN_MP_COUNT_BITS_C -| +--->BN_MP_REDUCE_SETUP_C -| | +--->BN_MP_2EXPT_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_DIV_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_SET_C -| | | +--->BN_MP_MUL_2D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_2D_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_INIT_COPY_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_REDUCE_C -| | +--->BN_MP_INIT_COPY_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_MP_RSHD_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_MUL_C -| | | +--->BN_MP_TOOM_MUL_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_MUL_2_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_2_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_3_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_KARATSUBA_MUL_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_MUL_DIGS_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | +--->BN_S_MP_MUL_HIGH_DIGS_C -| | | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_MUL_DIGS_C -| | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_D_C -| | +--->BN_MP_SET_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_C -| | | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_REDUCE_2K_SETUP_L_C -| | +--->BN_MP_2EXPT_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_GROW_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_REDUCE_2K_L_C -| | +--->BN_MP_DIV_2D_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | +--->BN_MP_MUL_C -| | | +--->BN_MP_TOOM_MUL_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_MUL_2_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_2_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_3_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_KARATSUBA_MUL_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_MUL_DIGS_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_MOD_C -| | +--->BN_MP_DIV_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_SET_C -| | | +--->BN_MP_MUL_2D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_2D_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_INIT_COPY_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_SQR_C -| | +--->BN_MP_TOOM_SQR_C -| | | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_MUL_2_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_2_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_2D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_3_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_MP_KARATSUBA_SQR_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | +--->BN_FAST_S_MP_SQR_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_SQR_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| +--->BN_MP_MUL_C -| | +--->BN_MP_TOOM_MUL_C -| | | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_MUL_2_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_2_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_2D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_3_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_MP_KARATSUBA_MUL_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_MUL_DIGS_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| +--->BN_MP_SET_C -| | +--->BN_MP_ZERO_C -| +--->BN_MP_EXCH_C -+--->BN_MP_DR_IS_MODULUS_C -+--->BN_MP_REDUCE_IS_2K_C -| +--->BN_MP_REDUCE_2K_C -| | +--->BN_MP_COUNT_BITS_C -| | +--->BN_MP_DIV_2D_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_COUNT_BITS_C -+--->BN_MP_EXPTMOD_FAST_C -| +--->BN_MP_COUNT_BITS_C -| +--->BN_MP_MONTGOMERY_SETUP_C -| +--->BN_FAST_MP_MONTGOMERY_REDUCE_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_RSHD_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| +--->BN_MP_MONTGOMERY_REDUCE_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_RSHD_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| +--->BN_MP_DR_SETUP_C -| +--->BN_MP_DR_REDUCE_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| +--->BN_MP_REDUCE_2K_SETUP_C -| | +--->BN_MP_2EXPT_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_GROW_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_REDUCE_2K_C -| | +--->BN_MP_DIV_2D_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_MONTGOMERY_CALC_NORMALIZATION_C -| | +--->BN_MP_2EXPT_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_SET_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_MUL_2_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_MULMOD_C -| | +--->BN_MP_MUL_C -| | | +--->BN_MP_TOOM_MUL_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_MUL_2_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_2_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_3_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_KARATSUBA_MUL_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_MUL_DIGS_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | +--->BN_MP_MOD_C -| | | +--->BN_MP_DIV_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_SET_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_2D_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_INIT_COPY_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| +--->BN_MP_SET_C -| | +--->BN_MP_ZERO_C -| +--->BN_MP_MOD_C -| | +--->BN_MP_DIV_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_MUL_2D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_2D_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_INIT_COPY_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_SQR_C -| | +--->BN_MP_TOOM_SQR_C -| | | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_MUL_2_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_2_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_2D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_3_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_MP_KARATSUBA_SQR_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | +--->BN_FAST_S_MP_SQR_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_SQR_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| +--->BN_MP_MUL_C -| | +--->BN_MP_TOOM_MUL_C -| | | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_MUL_2_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_2_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_2D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_3_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_MP_KARATSUBA_MUL_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_MUL_DIGS_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| +--->BN_MP_EXCH_C - - -BN_MP_OR_C -+--->BN_MP_INIT_COPY_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -+--->BN_MP_CLAMP_C -+--->BN_MP_EXCH_C -+--->BN_MP_CLEAR_C - - -BN_MP_ZERO_C - - -BN_MP_GROW_C - - -BN_MP_COUNT_BITS_C - - -BN_MP_PRIME_FERMAT_C -+--->BN_MP_CMP_D_C -+--->BN_MP_INIT_C -+--->BN_MP_EXPTMOD_C -| +--->BN_MP_INVMOD_C -| | +--->BN_FAST_MP_INVMOD_C -| | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_MOD_C -| | | | +--->BN_MP_DIV_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_SET_C -| | | | | +--->BN_MP_COUNT_BITS_C -| | | | | +--->BN_MP_ABS_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_2D_C -| | | | | | +--->BN_MP_MOD_2D_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CLEAR_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | | +--->BN_MP_CLEAR_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_INIT_COPY_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_SET_C -| | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_DIV_2_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_MULTI_C -| | | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_INVMOD_SLOW_C -| | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_MOD_C -| | | | +--->BN_MP_DIV_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_SET_C -| | | | | +--->BN_MP_COUNT_BITS_C -| | | | | +--->BN_MP_ABS_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_2D_C -| | | | | | +--->BN_MP_MOD_2D_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CLEAR_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | | +--->BN_MP_CLEAR_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_INIT_COPY_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_SET_C -| | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_DIV_2_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_MULTI_C -| | | | +--->BN_MP_CLEAR_C -| +--->BN_MP_CLEAR_C -| +--->BN_MP_ABS_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| +--->BN_MP_CLEAR_MULTI_C -| +--->BN_MP_REDUCE_IS_2K_L_C -| +--->BN_S_MP_EXPTMOD_C -| | +--->BN_MP_COUNT_BITS_C -| | +--->BN_MP_REDUCE_SETUP_C -| | | +--->BN_MP_2EXPT_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_DIV_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_SET_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_2D_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_INIT_COPY_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_REDUCE_C -| | | +--->BN_MP_INIT_COPY_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_MUL_C -| | | | +--->BN_MP_TOOM_MUL_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_COPY_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_MUL_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_3_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_KARATSUBA_MUL_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | +--->BN_S_MP_MUL_HIGH_DIGS_C -| | | | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_MUL_DIGS_C -| | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SET_C -| | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_REDUCE_2K_SETUP_L_C -| | | +--->BN_MP_2EXPT_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_REDUCE_2K_L_C -| | | +--->BN_MP_DIV_2D_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_MUL_C -| | | | +--->BN_MP_TOOM_MUL_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_COPY_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_MUL_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_3_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_KARATSUBA_MUL_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MOD_C -| | | +--->BN_MP_DIV_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_SET_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_2D_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_INIT_COPY_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_SQR_C -| | | +--->BN_MP_TOOM_SQR_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_MUL_2_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_2_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_3_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_KARATSUBA_SQR_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | +--->BN_FAST_S_MP_SQR_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SQR_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | +--->BN_MP_MUL_C -| | | +--->BN_MP_TOOM_MUL_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_MUL_2_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_2_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_3_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_KARATSUBA_MUL_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_MUL_DIGS_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | +--->BN_MP_SET_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_EXCH_C -| +--->BN_MP_DR_IS_MODULUS_C -| +--->BN_MP_REDUCE_IS_2K_C -| | +--->BN_MP_REDUCE_2K_C -| | | +--->BN_MP_COUNT_BITS_C -| | | +--->BN_MP_DIV_2D_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_COUNT_BITS_C -| +--->BN_MP_EXPTMOD_FAST_C -| | +--->BN_MP_COUNT_BITS_C -| | +--->BN_MP_MONTGOMERY_SETUP_C -| | +--->BN_FAST_MP_MONTGOMERY_REDUCE_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | +--->BN_MP_MONTGOMERY_REDUCE_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | +--->BN_MP_DR_SETUP_C -| | +--->BN_MP_DR_REDUCE_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | +--->BN_MP_REDUCE_2K_SETUP_C -| | | +--->BN_MP_2EXPT_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_REDUCE_2K_C -| | | +--->BN_MP_DIV_2D_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MONTGOMERY_CALC_NORMALIZATION_C -| | | +--->BN_MP_2EXPT_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_SET_C -| | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_MUL_2_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MULMOD_C -| | | +--->BN_MP_MUL_C -| | | | +--->BN_MP_TOOM_MUL_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_COPY_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_MUL_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_3_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_KARATSUBA_MUL_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_MOD_C -| | | | +--->BN_MP_DIV_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_SET_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_2D_C -| | | | | | +--->BN_MP_MOD_2D_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_INIT_COPY_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | +--->BN_MP_SET_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_MOD_C -| | | +--->BN_MP_DIV_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_2D_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_INIT_COPY_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_SQR_C -| | | +--->BN_MP_TOOM_SQR_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_MUL_2_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_2_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_3_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_KARATSUBA_SQR_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | +--->BN_FAST_S_MP_SQR_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SQR_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | +--->BN_MP_MUL_C -| | | +--->BN_MP_TOOM_MUL_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_MUL_2_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_2_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_3_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_KARATSUBA_MUL_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_MUL_DIGS_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | +--->BN_MP_EXCH_C -+--->BN_MP_CMP_C -| +--->BN_MP_CMP_MAG_C -+--->BN_MP_CLEAR_C - - -BN_MP_SUBMOD_C -+--->BN_MP_INIT_C -+--->BN_MP_SUB_C -| +--->BN_S_MP_ADD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -+--->BN_MP_CLEAR_C -+--->BN_MP_MOD_C -| +--->BN_MP_DIV_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_INIT_MULTI_C -| | +--->BN_MP_SET_C -| | +--->BN_MP_COUNT_BITS_C -| | +--->BN_MP_ABS_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2D_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_MULTI_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_INIT_COPY_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_ADD_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C - - -BN_MP_MOD_2D_C -+--->BN_MP_ZERO_C -+--->BN_MP_COPY_C -| +--->BN_MP_GROW_C -+--->BN_MP_CLAMP_C - - -BN_MP_TORADIX_N_C -+--->BN_MP_INIT_COPY_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -+--->BN_MP_DIV_D_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_DIV_2D_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLEAR_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| +--->BN_MP_DIV_3_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_INIT_SIZE_C -| +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_CLEAR_C - - -BN_MP_CMP_C -+--->BN_MP_CMP_MAG_C - - -BNCORE_C - - -BN_MP_TORADIX_C -+--->BN_MP_INIT_COPY_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -+--->BN_MP_DIV_D_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_DIV_2D_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLEAR_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| +--->BN_MP_DIV_3_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_INIT_SIZE_C -| +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_CLEAR_C - - -BN_MP_ADD_D_C -+--->BN_MP_GROW_C -+--->BN_MP_SUB_D_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_CLAMP_C - - -BN_MP_DIV_3_C -+--->BN_MP_INIT_SIZE_C -| +--->BN_MP_INIT_C -+--->BN_MP_CLAMP_C -+--->BN_MP_EXCH_C -+--->BN_MP_CLEAR_C - - -BN_FAST_S_MP_MUL_DIGS_C -+--->BN_MP_GROW_C -+--->BN_MP_CLAMP_C - - -BN_MP_SQRMOD_C -+--->BN_MP_INIT_C -+--->BN_MP_SQR_C -| +--->BN_MP_TOOM_SQR_C -| | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_RSHD_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_MUL_2_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_3_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_MULTI_C -| | | +--->BN_MP_CLEAR_C -| +--->BN_MP_KARATSUBA_SQR_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | +--->BN_MP_ADD_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_C -| +--->BN_FAST_S_MP_SQR_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_S_MP_SQR_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C -+--->BN_MP_CLEAR_C -+--->BN_MP_MOD_C -| +--->BN_MP_DIV_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_INIT_MULTI_C -| | +--->BN_MP_SET_C -| | +--->BN_MP_COUNT_BITS_C -| | +--->BN_MP_ABS_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2D_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_MULTI_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_INIT_COPY_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_ADD_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C - - -BN_MP_INVMOD_C -+--->BN_FAST_MP_INVMOD_C -| +--->BN_MP_INIT_MULTI_C -| | +--->BN_MP_INIT_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_MOD_C -| | +--->BN_MP_INIT_C -| | +--->BN_MP_DIV_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_SET_C -| | | +--->BN_MP_COUNT_BITS_C -| | | +--->BN_MP_ABS_C -| | | +--->BN_MP_MUL_2D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_2D_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_MULTI_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_INIT_COPY_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_CLEAR_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| +--->BN_MP_SET_C -| | +--->BN_MP_ZERO_C -| +--->BN_MP_DIV_2_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_SUB_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_C -| | +--->BN_MP_CMP_MAG_C -| +--->BN_MP_CMP_D_C -| +--->BN_MP_ADD_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C -| +--->BN_MP_CLEAR_MULTI_C -| | +--->BN_MP_CLEAR_C -+--->BN_MP_INVMOD_SLOW_C -| +--->BN_MP_INIT_MULTI_C -| | +--->BN_MP_INIT_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_MOD_C -| | +--->BN_MP_INIT_C -| | +--->BN_MP_DIV_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_SET_C -| | | +--->BN_MP_COUNT_BITS_C -| | | +--->BN_MP_ABS_C -| | | +--->BN_MP_MUL_2D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_2D_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_MULTI_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_INIT_COPY_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_CLEAR_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_SET_C -| | +--->BN_MP_ZERO_C -| +--->BN_MP_DIV_2_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_ADD_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_SUB_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_C -| | +--->BN_MP_CMP_MAG_C -| +--->BN_MP_CMP_D_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_MP_EXCH_C -| +--->BN_MP_CLEAR_MULTI_C -| | +--->BN_MP_CLEAR_C - - -BN_MP_AND_C -+--->BN_MP_INIT_COPY_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -+--->BN_MP_CLAMP_C -+--->BN_MP_EXCH_C -+--->BN_MP_CLEAR_C - - -BN_MP_MUL_D_C -+--->BN_MP_GROW_C -+--->BN_MP_CLAMP_C - - -BN_FAST_MP_INVMOD_C -+--->BN_MP_INIT_MULTI_C -| +--->BN_MP_INIT_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_COPY_C -| +--->BN_MP_GROW_C -+--->BN_MP_MOD_C -| +--->BN_MP_INIT_C -| +--->BN_MP_DIV_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_SET_C -| | +--->BN_MP_COUNT_BITS_C -| | +--->BN_MP_ABS_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2D_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_MULTI_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_INIT_COPY_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_CLEAR_C -| +--->BN_MP_ADD_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C -+--->BN_MP_SET_C -| +--->BN_MP_ZERO_C -+--->BN_MP_DIV_2_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_SUB_C -| +--->BN_S_MP_ADD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -+--->BN_MP_CMP_C -| +--->BN_MP_CMP_MAG_C -+--->BN_MP_CMP_D_C -+--->BN_MP_ADD_C -| +--->BN_S_MP_ADD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -+--->BN_MP_EXCH_C -+--->BN_MP_CLEAR_MULTI_C -| +--->BN_MP_CLEAR_C - - -BN_MP_FWRITE_C -+--->BN_MP_RADIX_SIZE_C -| +--->BN_MP_COUNT_BITS_C -| +--->BN_MP_INIT_COPY_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| +--->BN_MP_DIV_D_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_DIV_2D_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | +--->BN_MP_DIV_3_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_TORADIX_C -| +--->BN_MP_INIT_COPY_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| +--->BN_MP_DIV_D_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_DIV_2D_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | +--->BN_MP_DIV_3_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_CLEAR_C - - -BN_S_MP_SQR_C -+--->BN_MP_INIT_SIZE_C -| +--->BN_MP_INIT_C -+--->BN_MP_CLAMP_C -+--->BN_MP_EXCH_C -+--->BN_MP_CLEAR_C - - -BN_MP_N_ROOT_C -+--->BN_MP_INIT_C -+--->BN_MP_SET_C -| +--->BN_MP_ZERO_C -+--->BN_MP_COPY_C -| +--->BN_MP_GROW_C -+--->BN_MP_EXPT_D_C -| +--->BN_MP_INIT_COPY_C -| +--->BN_MP_SQR_C -| | +--->BN_MP_TOOM_SQR_C -| | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_MUL_2_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_2_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_2D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_3_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLEAR_MULTI_C -| | | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_KARATSUBA_SQR_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_FAST_S_MP_SQR_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_SQR_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_C -| +--->BN_MP_CLEAR_C -| +--->BN_MP_MUL_C -| | +--->BN_MP_TOOM_MUL_C -| | | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_MUL_2_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_2_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_2D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_3_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLEAR_MULTI_C -| | +--->BN_MP_KARATSUBA_MUL_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_MUL_DIGS_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -+--->BN_MP_MUL_C -| +--->BN_MP_TOOM_MUL_C -| | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_RSHD_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_MUL_2_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_3_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_MULTI_C -| | | +--->BN_MP_CLEAR_C -| +--->BN_MP_KARATSUBA_MUL_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | +--->BN_MP_CLEAR_C -| +--->BN_FAST_S_MP_MUL_DIGS_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_S_MP_MUL_DIGS_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C -+--->BN_MP_SUB_C -| +--->BN_S_MP_ADD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -+--->BN_MP_MUL_D_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_DIV_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_MP_ZERO_C -| +--->BN_MP_INIT_MULTI_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_COUNT_BITS_C -| +--->BN_MP_ABS_C -| +--->BN_MP_MUL_2D_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_C -| +--->BN_MP_ADD_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_DIV_2D_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLEAR_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| +--->BN_MP_EXCH_C -| +--->BN_MP_CLEAR_MULTI_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_INIT_SIZE_C -| +--->BN_MP_INIT_COPY_C -| +--->BN_MP_LSHD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_RSHD_C -| +--->BN_MP_RSHD_C -| +--->BN_MP_CLAMP_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_CMP_C -| +--->BN_MP_CMP_MAG_C -+--->BN_MP_SUB_D_C -| +--->BN_MP_GROW_C -| +--->BN_MP_ADD_D_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_EXCH_C -+--->BN_MP_CLEAR_C - - -BN_MP_PRIME_RABIN_MILLER_TRIALS_C - - -BN_MP_RADIX_SIZE_C -+--->BN_MP_COUNT_BITS_C -+--->BN_MP_INIT_COPY_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -+--->BN_MP_DIV_D_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_DIV_2D_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLEAR_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| +--->BN_MP_DIV_3_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_INIT_SIZE_C -| +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_CLEAR_C - - -BN_MP_READ_SIGNED_BIN_C -+--->BN_MP_READ_UNSIGNED_BIN_C -| +--->BN_MP_GROW_C -| +--->BN_MP_ZERO_C -| +--->BN_MP_MUL_2D_C -| | +--->BN_MP_COPY_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CLAMP_C - - -BN_MP_PRIME_RANDOM_EX_C -+--->BN_MP_READ_UNSIGNED_BIN_C -| +--->BN_MP_GROW_C -| +--->BN_MP_ZERO_C -| +--->BN_MP_MUL_2D_C -| | +--->BN_MP_COPY_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_PRIME_IS_PRIME_C -| +--->BN_MP_CMP_D_C -| +--->BN_MP_PRIME_IS_DIVISIBLE_C -| | +--->BN_MP_MOD_D_C -| | | +--->BN_MP_DIV_D_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_DIV_2D_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_INIT_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CLEAR_C -| | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_DIV_3_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_INIT_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_INIT_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_CLEAR_C -| +--->BN_MP_INIT_C -| +--->BN_MP_SET_C -| | +--->BN_MP_ZERO_C -| +--->BN_MP_PRIME_MILLER_RABIN_C -| | +--->BN_MP_INIT_COPY_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_MP_SUB_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ADD_D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CNT_LSB_C -| | +--->BN_MP_DIV_2D_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | +--->BN_MP_EXPTMOD_C -| | | +--->BN_MP_INVMOD_C -| | | | +--->BN_FAST_MP_INVMOD_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | | +--->BN_MP_CLEAR_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_MOD_C -| | | | | | +--->BN_MP_DIV_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | | | +--->BN_MP_COUNT_BITS_C -| | | | | | | +--->BN_MP_ABS_C -| | | | | | | +--->BN_MP_MUL_2D_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_LSHD_C -| | | | | | | | | +--->BN_MP_RSHD_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_C -| | | | | | | +--->BN_MP_SUB_C -| | | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_ADD_C -| | | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_EXCH_C -| | | | | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | | | | +--->BN_MP_CLEAR_C -| | | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_MUL_D_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CLEAR_C -| | | | | | +--->BN_MP_CLEAR_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_DIV_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_INVMOD_SLOW_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | | +--->BN_MP_CLEAR_C -| | | | | +--->BN_MP_MOD_C -| | | | | | +--->BN_MP_DIV_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_MP_COPY_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | | | +--->BN_MP_COUNT_BITS_C -| | | | | | | +--->BN_MP_ABS_C -| | | | | | | +--->BN_MP_MUL_2D_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_LSHD_C -| | | | | | | | | +--->BN_MP_RSHD_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_C -| | | | | | | +--->BN_MP_SUB_C -| | | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_ADD_C -| | | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_EXCH_C -| | | | | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | | | | +--->BN_MP_CLEAR_C -| | | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_MUL_D_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CLEAR_C -| | | | | | +--->BN_MP_CLEAR_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_DIV_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_ABS_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLEAR_MULTI_C -| | | +--->BN_MP_REDUCE_IS_2K_L_C -| | | +--->BN_S_MP_EXPTMOD_C -| | | | +--->BN_MP_COUNT_BITS_C -| | | | +--->BN_MP_REDUCE_SETUP_C -| | | | | +--->BN_MP_2EXPT_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_DIV_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_MP_COPY_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_INIT_MULTI_C -| | | | | | +--->BN_MP_MUL_2D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_C -| | | | | | +--->BN_MP_SUB_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_MUL_D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_REDUCE_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_MUL_C -| | | | | | +--->BN_MP_TOOM_MUL_C -| | | | | | | +--->BN_MP_INIT_MULTI_C -| | | | | | | +--->BN_MP_MOD_2D_C -| | | | | | | | +--->BN_MP_ZERO_C -| | | | | | | | +--->BN_MP_COPY_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_COPY_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_MUL_2_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_ADD_C -| | | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_SUB_C -| | | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_DIV_2_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_MUL_2D_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_LSHD_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_MUL_D_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_DIV_3_C -| | | | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | | +--->BN_MP_EXCH_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_KARATSUBA_MUL_C -| | | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_SUB_C -| | | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_ADD_C -| | | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_S_MP_MUL_HIGH_DIGS_C -| | | | | | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_COPY_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_REDUCE_2K_SETUP_L_C -| | | | | +--->BN_MP_2EXPT_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_REDUCE_2K_L_C -| | | | | +--->BN_MP_MUL_C -| | | | | | +--->BN_MP_TOOM_MUL_C -| | | | | | | +--->BN_MP_INIT_MULTI_C -| | | | | | | +--->BN_MP_MOD_2D_C -| | | | | | | | +--->BN_MP_ZERO_C -| | | | | | | | +--->BN_MP_COPY_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_COPY_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | | | +--->BN_MP_ZERO_C -| | | | | | | +--->BN_MP_MUL_2_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_ADD_C -| | | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_SUB_C -| | | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_DIV_2_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_MUL_2D_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_LSHD_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_MUL_D_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_DIV_3_C -| | | | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | | +--->BN_MP_EXCH_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_KARATSUBA_MUL_C -| | | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_SUB_C -| | | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_ADD_C -| | | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_RSHD_C -| | | | | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MOD_C -| | | | | +--->BN_MP_DIV_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_MP_COPY_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_INIT_MULTI_C -| | | | | | +--->BN_MP_MUL_2D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_C -| | | | | | +--->BN_MP_SUB_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_MUL_D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_SQR_C -| | | | | +--->BN_MP_TOOM_SQR_C -| | | | | | +--->BN_MP_INIT_MULTI_C -| | | | | | +--->BN_MP_MOD_2D_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_MUL_2_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_SUB_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_DIV_2_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_MUL_2D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_MUL_D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_DIV_3_C -| | | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_EXCH_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_KARATSUBA_SQR_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_SUB_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_FAST_S_MP_SQR_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SQR_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_MUL_C -| | | | | +--->BN_MP_TOOM_MUL_C -| | | | | | +--->BN_MP_INIT_MULTI_C -| | | | | | +--->BN_MP_MOD_2D_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_MUL_2_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_SUB_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_DIV_2_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_MUL_2D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_MUL_D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_DIV_3_C -| | | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_EXCH_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_KARATSUBA_MUL_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_SUB_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_DR_IS_MODULUS_C -| | | +--->BN_MP_REDUCE_IS_2K_C -| | | | +--->BN_MP_REDUCE_2K_C -| | | | | +--->BN_MP_COUNT_BITS_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_COUNT_BITS_C -| | | +--->BN_MP_EXPTMOD_FAST_C -| | | | +--->BN_MP_COUNT_BITS_C -| | | | +--->BN_MP_MONTGOMERY_SETUP_C -| | | | +--->BN_FAST_MP_MONTGOMERY_REDUCE_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_MONTGOMERY_REDUCE_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_DR_SETUP_C -| | | | +--->BN_MP_DR_REDUCE_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_REDUCE_2K_SETUP_C -| | | | | +--->BN_MP_2EXPT_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_REDUCE_2K_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MONTGOMERY_CALC_NORMALIZATION_C -| | | | | +--->BN_MP_2EXPT_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_MUL_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MULMOD_C -| | | | | +--->BN_MP_MUL_C -| | | | | | +--->BN_MP_TOOM_MUL_C -| | | | | | | +--->BN_MP_INIT_MULTI_C -| | | | | | | +--->BN_MP_MOD_2D_C -| | | | | | | | +--->BN_MP_ZERO_C -| | | | | | | | +--->BN_MP_COPY_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_COPY_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | | | +--->BN_MP_ZERO_C -| | | | | | | +--->BN_MP_MUL_2_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_ADD_C -| | | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_SUB_C -| | | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_DIV_2_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_MUL_2D_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_LSHD_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_MUL_D_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_DIV_3_C -| | | | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | | +--->BN_MP_EXCH_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_KARATSUBA_MUL_C -| | | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_SUB_C -| | | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_ADD_C -| | | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_RSHD_C -| | | | | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_MOD_C -| | | | | | +--->BN_MP_DIV_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_MP_COPY_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | | | +--->BN_MP_INIT_MULTI_C -| | | | | | | +--->BN_MP_MUL_2D_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_LSHD_C -| | | | | | | | | +--->BN_MP_RSHD_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_C -| | | | | | | +--->BN_MP_SUB_C -| | | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_ADD_C -| | | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_EXCH_C -| | | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_MUL_D_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_MOD_C -| | | | | +--->BN_MP_DIV_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_MP_COPY_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_INIT_MULTI_C -| | | | | | +--->BN_MP_MUL_2D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_C -| | | | | | +--->BN_MP_SUB_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_MUL_D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_SQR_C -| | | | | +--->BN_MP_TOOM_SQR_C -| | | | | | +--->BN_MP_INIT_MULTI_C -| | | | | | +--->BN_MP_MOD_2D_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_MUL_2_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_SUB_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_DIV_2_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_MUL_2D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_MUL_D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_DIV_3_C -| | | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_EXCH_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_KARATSUBA_SQR_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_SUB_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_FAST_S_MP_SQR_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SQR_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_MUL_C -| | | | | +--->BN_MP_TOOM_MUL_C -| | | | | | +--->BN_MP_INIT_MULTI_C -| | | | | | +--->BN_MP_MOD_2D_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_MUL_2_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_SUB_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_DIV_2_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_MUL_2D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_MUL_D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_DIV_3_C -| | | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_EXCH_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_KARATSUBA_MUL_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_SUB_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_EXCH_C -| | +--->BN_MP_CMP_C -| | | +--->BN_MP_CMP_MAG_C -| | +--->BN_MP_SQRMOD_C -| | | +--->BN_MP_SQR_C -| | | | +--->BN_MP_TOOM_SQR_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | | +--->BN_MP_CLEAR_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_COPY_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_MUL_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_3_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | | +--->BN_MP_CLEAR_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_KARATSUBA_SQR_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_FAST_S_MP_SQR_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_SQR_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_MOD_C -| | | | +--->BN_MP_DIV_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_COUNT_BITS_C -| | | | | +--->BN_MP_ABS_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_SUB_D_C -| +--->BN_MP_GROW_C -| +--->BN_MP_ADD_D_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_DIV_2_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_MUL_2_C -| +--->BN_MP_GROW_C -+--->BN_MP_ADD_D_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C - - -BN_MP_KARATSUBA_SQR_C -+--->BN_MP_INIT_SIZE_C -| +--->BN_MP_INIT_C -+--->BN_MP_CLAMP_C -+--->BN_MP_SQR_C -| +--->BN_MP_TOOM_SQR_C -| | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_INIT_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_RSHD_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_MUL_2_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_MP_DIV_2_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_DIV_3_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_MULTI_C -| | | +--->BN_MP_CLEAR_C -| +--->BN_FAST_S_MP_SQR_C -| | +--->BN_MP_GROW_C -| +--->BN_S_MP_SQR_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C -+--->BN_MP_SUB_C -| +--->BN_S_MP_ADD_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -+--->BN_S_MP_ADD_C -| +--->BN_MP_GROW_C -+--->BN_MP_LSHD_C -| +--->BN_MP_GROW_C -| +--->BN_MP_RSHD_C -| | +--->BN_MP_ZERO_C -+--->BN_MP_ADD_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -+--->BN_MP_CLEAR_C - - -BN_MP_INIT_COPY_C -+--->BN_MP_COPY_C -| +--->BN_MP_GROW_C - - -BN_MP_CLAMP_C - - -BN_MP_TOOM_SQR_C -+--->BN_MP_INIT_MULTI_C -| +--->BN_MP_INIT_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_MOD_2D_C -| +--->BN_MP_ZERO_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_COPY_C -| +--->BN_MP_GROW_C -+--->BN_MP_RSHD_C -| +--->BN_MP_ZERO_C -+--->BN_MP_SQR_C -| +--->BN_MP_KARATSUBA_SQR_C -| | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_INIT_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_C -| +--->BN_FAST_S_MP_SQR_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_S_MP_SQR_C -| | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_INIT_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C -+--->BN_MP_MUL_2_C -| +--->BN_MP_GROW_C -+--->BN_MP_ADD_C -| +--->BN_S_MP_ADD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -+--->BN_MP_SUB_C -| +--->BN_S_MP_ADD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -+--->BN_MP_DIV_2_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_MUL_2D_C -| +--->BN_MP_GROW_C -| +--->BN_MP_LSHD_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_MUL_D_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_DIV_3_C -| +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_INIT_C -| +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_LSHD_C -| +--->BN_MP_GROW_C -+--->BN_MP_CLEAR_MULTI_C -| +--->BN_MP_CLEAR_C - - -BN_MP_MOD_C -+--->BN_MP_INIT_C -+--->BN_MP_DIV_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_ZERO_C -| +--->BN_MP_INIT_MULTI_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_SET_C -| +--->BN_MP_COUNT_BITS_C -| +--->BN_MP_ABS_C -| +--->BN_MP_MUL_2D_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_C -| +--->BN_MP_SUB_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_ADD_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_DIV_2D_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLEAR_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| +--->BN_MP_EXCH_C -| +--->BN_MP_CLEAR_MULTI_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_INIT_SIZE_C -| +--->BN_MP_INIT_COPY_C -| +--->BN_MP_LSHD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_RSHD_C -| +--->BN_MP_RSHD_C -| +--->BN_MP_MUL_D_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CLAMP_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_CLEAR_C -+--->BN_MP_ADD_C -| +--->BN_S_MP_ADD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -+--->BN_MP_EXCH_C - - -BN_MP_INIT_C - - -BN_MP_TOOM_MUL_C -+--->BN_MP_INIT_MULTI_C -| +--->BN_MP_INIT_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_MOD_2D_C -| +--->BN_MP_ZERO_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_COPY_C -| +--->BN_MP_GROW_C -+--->BN_MP_RSHD_C -| +--->BN_MP_ZERO_C -+--->BN_MP_MUL_C -| +--->BN_MP_KARATSUBA_MUL_C -| | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_INIT_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_C -| +--->BN_FAST_S_MP_MUL_DIGS_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_S_MP_MUL_DIGS_C -| | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_INIT_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C -+--->BN_MP_MUL_2_C -| +--->BN_MP_GROW_C -+--->BN_MP_ADD_C -| +--->BN_S_MP_ADD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -+--->BN_MP_SUB_C -| +--->BN_S_MP_ADD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -+--->BN_MP_DIV_2_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_MUL_2D_C -| +--->BN_MP_GROW_C -| +--->BN_MP_LSHD_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_MUL_D_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_DIV_3_C -| +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_INIT_C -| +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_LSHD_C -| +--->BN_MP_GROW_C -+--->BN_MP_CLEAR_MULTI_C -| +--->BN_MP_CLEAR_C - - -BN_MP_PRIME_IS_PRIME_C -+--->BN_MP_CMP_D_C -+--->BN_MP_PRIME_IS_DIVISIBLE_C -| +--->BN_MP_MOD_D_C -| | +--->BN_MP_DIV_D_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_DIV_2D_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_INIT_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_DIV_3_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_INIT_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_INIT_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_C -+--->BN_MP_INIT_C -+--->BN_MP_SET_C -| +--->BN_MP_ZERO_C -+--->BN_MP_PRIME_MILLER_RABIN_C -| +--->BN_MP_INIT_COPY_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| +--->BN_MP_SUB_D_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_D_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CNT_LSB_C -| +--->BN_MP_DIV_2D_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLEAR_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| +--->BN_MP_EXPTMOD_C -| | +--->BN_MP_INVMOD_C -| | | +--->BN_FAST_MP_INVMOD_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_MOD_C -| | | | | +--->BN_MP_DIV_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_COUNT_BITS_C -| | | | | | +--->BN_MP_ABS_C -| | | | | | +--->BN_MP_MUL_2D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_C -| | | | | | +--->BN_MP_SUB_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | | | +--->BN_MP_CLEAR_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_MUL_D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CLEAR_C -| | | | | +--->BN_MP_CLEAR_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_DIV_2_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_INVMOD_SLOW_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_MOD_C -| | | | | +--->BN_MP_DIV_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_MP_COPY_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_COUNT_BITS_C -| | | | | | +--->BN_MP_ABS_C -| | | | | | +--->BN_MP_MUL_2D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_C -| | | | | | +--->BN_MP_SUB_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | | | +--->BN_MP_CLEAR_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_MUL_D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CLEAR_C -| | | | | +--->BN_MP_CLEAR_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_DIV_2_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_CLEAR_C -| | +--->BN_MP_ABS_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_MULTI_C -| | +--->BN_MP_REDUCE_IS_2K_L_C -| | +--->BN_S_MP_EXPTMOD_C -| | | +--->BN_MP_COUNT_BITS_C -| | | +--->BN_MP_REDUCE_SETUP_C -| | | | +--->BN_MP_2EXPT_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_DIV_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_REDUCE_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_MUL_C -| | | | | +--->BN_MP_TOOM_MUL_C -| | | | | | +--->BN_MP_INIT_MULTI_C -| | | | | | +--->BN_MP_MOD_2D_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | | | +--->BN_MP_COPY_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_COPY_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_MUL_2_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_SUB_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_DIV_2_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_MUL_2D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_MUL_D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_DIV_3_C -| | | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_EXCH_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_KARATSUBA_MUL_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_SUB_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_S_MP_MUL_HIGH_DIGS_C -| | | | | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_REDUCE_2K_SETUP_L_C -| | | | +--->BN_MP_2EXPT_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_REDUCE_2K_L_C -| | | | +--->BN_MP_MUL_C -| | | | | +--->BN_MP_TOOM_MUL_C -| | | | | | +--->BN_MP_INIT_MULTI_C -| | | | | | +--->BN_MP_MOD_2D_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | | | +--->BN_MP_COPY_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_COPY_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_MUL_2_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_SUB_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_DIV_2_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_MUL_2D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_MUL_D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_DIV_3_C -| | | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_EXCH_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_KARATSUBA_MUL_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_SUB_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MOD_C -| | | | +--->BN_MP_DIV_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_SQR_C -| | | | +--->BN_MP_TOOM_SQR_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_MUL_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_3_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_KARATSUBA_SQR_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_FAST_S_MP_SQR_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_SQR_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_MUL_C -| | | | +--->BN_MP_TOOM_MUL_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_MUL_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_3_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_KARATSUBA_MUL_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_EXCH_C -| | +--->BN_MP_DR_IS_MODULUS_C -| | +--->BN_MP_REDUCE_IS_2K_C -| | | +--->BN_MP_REDUCE_2K_C -| | | | +--->BN_MP_COUNT_BITS_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_COUNT_BITS_C -| | +--->BN_MP_EXPTMOD_FAST_C -| | | +--->BN_MP_COUNT_BITS_C -| | | +--->BN_MP_MONTGOMERY_SETUP_C -| | | +--->BN_FAST_MP_MONTGOMERY_REDUCE_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_MONTGOMERY_REDUCE_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_DR_SETUP_C -| | | +--->BN_MP_DR_REDUCE_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_REDUCE_2K_SETUP_C -| | | | +--->BN_MP_2EXPT_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_REDUCE_2K_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MONTGOMERY_CALC_NORMALIZATION_C -| | | | +--->BN_MP_2EXPT_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_MUL_2_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MULMOD_C -| | | | +--->BN_MP_MUL_C -| | | | | +--->BN_MP_TOOM_MUL_C -| | | | | | +--->BN_MP_INIT_MULTI_C -| | | | | | +--->BN_MP_MOD_2D_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | | | +--->BN_MP_COPY_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_COPY_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_MUL_2_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_SUB_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_DIV_2_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_MUL_2D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_MUL_D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_DIV_3_C -| | | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_EXCH_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_KARATSUBA_MUL_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_SUB_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_MOD_C -| | | | | +--->BN_MP_DIV_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_MP_COPY_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_INIT_MULTI_C -| | | | | | +--->BN_MP_MUL_2D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_C -| | | | | | +--->BN_MP_SUB_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_MUL_D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_MOD_C -| | | | +--->BN_MP_DIV_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_SQR_C -| | | | +--->BN_MP_TOOM_SQR_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_MUL_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_3_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_KARATSUBA_SQR_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_FAST_S_MP_SQR_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_SQR_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_MUL_C -| | | | +--->BN_MP_TOOM_MUL_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_MUL_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_3_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_KARATSUBA_MUL_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_EXCH_C -| +--->BN_MP_CMP_C -| | +--->BN_MP_CMP_MAG_C -| +--->BN_MP_SQRMOD_C -| | +--->BN_MP_SQR_C -| | | +--->BN_MP_TOOM_SQR_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_MUL_2_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_2_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_3_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_KARATSUBA_SQR_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_FAST_S_MP_SQR_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SQR_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_CLEAR_C -| | +--->BN_MP_MOD_C -| | | +--->BN_MP_DIV_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_COUNT_BITS_C -| | | | +--->BN_MP_ABS_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_CLEAR_MULTI_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_CLEAR_C - - -BN_MP_COPY_C -+--->BN_MP_GROW_C - - -BN_S_MP_SUB_C -+--->BN_MP_GROW_C -+--->BN_MP_CLAMP_C - - -BN_MP_READ_UNSIGNED_BIN_C -+--->BN_MP_GROW_C -+--->BN_MP_ZERO_C -+--->BN_MP_MUL_2D_C -| +--->BN_MP_COPY_C -| +--->BN_MP_LSHD_C -| | +--->BN_MP_RSHD_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_CLAMP_C - - -BN_MP_EXPTMOD_FAST_C -+--->BN_MP_COUNT_BITS_C -+--->BN_MP_INIT_C -+--->BN_MP_CLEAR_C -+--->BN_MP_MONTGOMERY_SETUP_C -+--->BN_FAST_MP_MONTGOMERY_REDUCE_C -| +--->BN_MP_GROW_C -| +--->BN_MP_RSHD_C -| | +--->BN_MP_ZERO_C -| +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -+--->BN_MP_MONTGOMERY_REDUCE_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -| +--->BN_MP_RSHD_C -| | +--->BN_MP_ZERO_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -+--->BN_MP_DR_SETUP_C -+--->BN_MP_DR_REDUCE_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -+--->BN_MP_REDUCE_2K_SETUP_C -| +--->BN_MP_2EXPT_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_GROW_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -+--->BN_MP_REDUCE_2K_C -| +--->BN_MP_DIV_2D_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| +--->BN_MP_MUL_D_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_S_MP_ADD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -+--->BN_MP_MONTGOMERY_CALC_NORMALIZATION_C -| +--->BN_MP_2EXPT_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_SET_C -| | +--->BN_MP_ZERO_C -| +--->BN_MP_MUL_2_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -+--->BN_MP_MULMOD_C -| +--->BN_MP_MUL_C -| | +--->BN_MP_TOOM_MUL_C -| | | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_MUL_2_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_2_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_2D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_3_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLEAR_MULTI_C -| | +--->BN_MP_KARATSUBA_MUL_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_MUL_DIGS_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| +--->BN_MP_MOD_C -| | +--->BN_MP_DIV_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_SET_C -| | | +--->BN_MP_ABS_C -| | | +--->BN_MP_MUL_2D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_2D_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_MULTI_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_INIT_COPY_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -+--->BN_MP_SET_C -| +--->BN_MP_ZERO_C -+--->BN_MP_MOD_C -| +--->BN_MP_DIV_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_INIT_MULTI_C -| | +--->BN_MP_ABS_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2D_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_MULTI_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_INIT_COPY_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_ADD_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C -+--->BN_MP_COPY_C -| +--->BN_MP_GROW_C -+--->BN_MP_SQR_C -| +--->BN_MP_TOOM_SQR_C -| | +--->BN_MP_INIT_MULTI_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_RSHD_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_MUL_2_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_3_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_MULTI_C -| +--->BN_MP_KARATSUBA_SQR_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | +--->BN_MP_ADD_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| +--->BN_FAST_S_MP_SQR_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_S_MP_SQR_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -+--->BN_MP_MUL_C -| +--->BN_MP_TOOM_MUL_C -| | +--->BN_MP_INIT_MULTI_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_RSHD_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_MUL_2_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_3_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_MULTI_C -| +--->BN_MP_KARATSUBA_MUL_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| +--->BN_FAST_S_MP_MUL_DIGS_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_S_MP_MUL_DIGS_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -+--->BN_MP_EXCH_C - - -BN_MP_TO_UNSIGNED_BIN_C -+--->BN_MP_INIT_COPY_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -+--->BN_MP_DIV_2D_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_ZERO_C -| +--->BN_MP_MOD_2D_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CLEAR_C -| +--->BN_MP_RSHD_C -| +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C -+--->BN_MP_CLEAR_C - - -BN_MP_SET_INT_C -+--->BN_MP_ZERO_C -+--->BN_MP_MUL_2D_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_GROW_C -| +--->BN_MP_LSHD_C -| | +--->BN_MP_RSHD_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_CLAMP_C - - -BN_MP_MOD_D_C -+--->BN_MP_DIV_D_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_DIV_2D_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_INIT_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLEAR_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| +--->BN_MP_DIV_3_C -| | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_INIT_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_INIT_C -| +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C -| +--->BN_MP_CLEAR_C - - -BN_MP_SQR_C -+--->BN_MP_TOOM_SQR_C -| +--->BN_MP_INIT_MULTI_C -| | +--->BN_MP_INIT_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_MOD_2D_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_RSHD_C -| | +--->BN_MP_ZERO_C -| +--->BN_MP_MUL_2_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_ADD_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_SUB_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_DIV_2_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_MUL_2D_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_MUL_D_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_DIV_3_C -| | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_INIT_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_LSHD_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_CLEAR_MULTI_C -| | +--->BN_MP_CLEAR_C -+--->BN_MP_KARATSUBA_SQR_C -| +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_INIT_C -| +--->BN_MP_CLAMP_C -| +--->BN_MP_SUB_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| +--->BN_S_MP_ADD_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_LSHD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_RSHD_C -| | | +--->BN_MP_ZERO_C -| +--->BN_MP_ADD_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| +--->BN_MP_CLEAR_C -+--->BN_FAST_S_MP_SQR_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_S_MP_SQR_C -| +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_INIT_C -| +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C -| +--->BN_MP_CLEAR_C - - -BN_MP_MULMOD_C -+--->BN_MP_INIT_C -+--->BN_MP_MUL_C -| +--->BN_MP_TOOM_MUL_C -| | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_RSHD_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_MUL_2_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_3_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_MULTI_C -| | | +--->BN_MP_CLEAR_C -| +--->BN_MP_KARATSUBA_MUL_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | +--->BN_MP_CLEAR_C -| +--->BN_FAST_S_MP_MUL_DIGS_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_S_MP_MUL_DIGS_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C -+--->BN_MP_CLEAR_C -+--->BN_MP_MOD_C -| +--->BN_MP_DIV_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_INIT_MULTI_C -| | +--->BN_MP_SET_C -| | +--->BN_MP_COUNT_BITS_C -| | +--->BN_MP_ABS_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2D_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_MULTI_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_INIT_COPY_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_ADD_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C - - -BN_MP_DIV_2D_C -+--->BN_MP_COPY_C -| +--->BN_MP_GROW_C -+--->BN_MP_ZERO_C -+--->BN_MP_INIT_C -+--->BN_MP_MOD_2D_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_CLEAR_C -+--->BN_MP_RSHD_C -+--->BN_MP_CLAMP_C -+--->BN_MP_EXCH_C - - -BN_S_MP_ADD_C -+--->BN_MP_GROW_C -+--->BN_MP_CLAMP_C - - -BN_FAST_S_MP_SQR_C -+--->BN_MP_GROW_C -+--->BN_MP_CLAMP_C - - -BN_S_MP_MUL_DIGS_C -+--->BN_FAST_S_MP_MUL_DIGS_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_INIT_SIZE_C -| +--->BN_MP_INIT_C -+--->BN_MP_CLAMP_C -+--->BN_MP_EXCH_C -+--->BN_MP_CLEAR_C - - -BN_MP_XOR_C -+--->BN_MP_INIT_COPY_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -+--->BN_MP_CLAMP_C -+--->BN_MP_EXCH_C -+--->BN_MP_CLEAR_C - - -BN_MP_RADIX_SMAP_C - - -BN_MP_DR_IS_MODULUS_C - - -BN_MP_MONTGOMERY_CALC_NORMALIZATION_C -+--->BN_MP_COUNT_BITS_C -+--->BN_MP_2EXPT_C -| +--->BN_MP_ZERO_C -| +--->BN_MP_GROW_C -+--->BN_MP_SET_C -| +--->BN_MP_ZERO_C -+--->BN_MP_MUL_2_C -| +--->BN_MP_GROW_C -+--->BN_MP_CMP_MAG_C -+--->BN_S_MP_SUB_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C - - -BN_MP_SUB_C -+--->BN_S_MP_ADD_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_CMP_MAG_C -+--->BN_S_MP_SUB_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C - - -BN_MP_INIT_MULTI_C -+--->BN_MP_INIT_C -+--->BN_MP_CLEAR_C - - -BN_S_MP_MUL_HIGH_DIGS_C -+--->BN_FAST_S_MP_MUL_HIGH_DIGS_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_INIT_SIZE_C -| +--->BN_MP_INIT_C -+--->BN_MP_CLAMP_C -+--->BN_MP_EXCH_C -+--->BN_MP_CLEAR_C - - -BN_MP_PRIME_NEXT_PRIME_C -+--->BN_MP_CMP_D_C -+--->BN_MP_SET_C -| +--->BN_MP_ZERO_C -+--->BN_MP_SUB_D_C -| +--->BN_MP_GROW_C -| +--->BN_MP_ADD_D_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_MOD_D_C -| +--->BN_MP_DIV_D_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_DIV_2D_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_INIT_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | +--->BN_MP_DIV_3_C -| | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_INIT_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_INIT_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C -+--->BN_MP_INIT_C -+--->BN_MP_ADD_D_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_PRIME_MILLER_RABIN_C -| +--->BN_MP_INIT_COPY_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| +--->BN_MP_CNT_LSB_C -| +--->BN_MP_DIV_2D_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLEAR_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| +--->BN_MP_EXPTMOD_C -| | +--->BN_MP_INVMOD_C -| | | +--->BN_FAST_MP_INVMOD_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_MOD_C -| | | | | +--->BN_MP_DIV_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_COUNT_BITS_C -| | | | | | +--->BN_MP_ABS_C -| | | | | | +--->BN_MP_MUL_2D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_C -| | | | | | +--->BN_MP_SUB_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | | | +--->BN_MP_CLEAR_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_MUL_D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CLEAR_C -| | | | | +--->BN_MP_CLEAR_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_DIV_2_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_INVMOD_SLOW_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_MOD_C -| | | | | +--->BN_MP_DIV_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_MP_COPY_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_COUNT_BITS_C -| | | | | | +--->BN_MP_ABS_C -| | | | | | +--->BN_MP_MUL_2D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_C -| | | | | | +--->BN_MP_SUB_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | | | +--->BN_MP_CLEAR_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_MUL_D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CLEAR_C -| | | | | +--->BN_MP_CLEAR_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_DIV_2_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_CLEAR_C -| | +--->BN_MP_ABS_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_MULTI_C -| | +--->BN_MP_REDUCE_IS_2K_L_C -| | +--->BN_S_MP_EXPTMOD_C -| | | +--->BN_MP_COUNT_BITS_C -| | | +--->BN_MP_REDUCE_SETUP_C -| | | | +--->BN_MP_2EXPT_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_DIV_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_REDUCE_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_MUL_C -| | | | | +--->BN_MP_TOOM_MUL_C -| | | | | | +--->BN_MP_INIT_MULTI_C -| | | | | | +--->BN_MP_MOD_2D_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | | | +--->BN_MP_COPY_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_COPY_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_MUL_2_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_SUB_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_DIV_2_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_MUL_2D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_MUL_D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_DIV_3_C -| | | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_EXCH_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_KARATSUBA_MUL_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_SUB_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_S_MP_MUL_HIGH_DIGS_C -| | | | | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_REDUCE_2K_SETUP_L_C -| | | | +--->BN_MP_2EXPT_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_REDUCE_2K_L_C -| | | | +--->BN_MP_MUL_C -| | | | | +--->BN_MP_TOOM_MUL_C -| | | | | | +--->BN_MP_INIT_MULTI_C -| | | | | | +--->BN_MP_MOD_2D_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | | | +--->BN_MP_COPY_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_COPY_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_MUL_2_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_SUB_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_DIV_2_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_MUL_2D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_MUL_D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_DIV_3_C -| | | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_EXCH_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_KARATSUBA_MUL_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_SUB_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MOD_C -| | | | +--->BN_MP_DIV_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_SQR_C -| | | | +--->BN_MP_TOOM_SQR_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_MUL_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_3_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_KARATSUBA_SQR_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_FAST_S_MP_SQR_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_SQR_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_MUL_C -| | | | +--->BN_MP_TOOM_MUL_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_MUL_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_3_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_KARATSUBA_MUL_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_EXCH_C -| | +--->BN_MP_DR_IS_MODULUS_C -| | +--->BN_MP_REDUCE_IS_2K_C -| | | +--->BN_MP_REDUCE_2K_C -| | | | +--->BN_MP_COUNT_BITS_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_COUNT_BITS_C -| | +--->BN_MP_EXPTMOD_FAST_C -| | | +--->BN_MP_COUNT_BITS_C -| | | +--->BN_MP_MONTGOMERY_SETUP_C -| | | +--->BN_FAST_MP_MONTGOMERY_REDUCE_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_MONTGOMERY_REDUCE_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_DR_SETUP_C -| | | +--->BN_MP_DR_REDUCE_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_REDUCE_2K_SETUP_C -| | | | +--->BN_MP_2EXPT_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_REDUCE_2K_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MONTGOMERY_CALC_NORMALIZATION_C -| | | | +--->BN_MP_2EXPT_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_MUL_2_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MULMOD_C -| | | | +--->BN_MP_MUL_C -| | | | | +--->BN_MP_TOOM_MUL_C -| | | | | | +--->BN_MP_INIT_MULTI_C -| | | | | | +--->BN_MP_MOD_2D_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | | | +--->BN_MP_COPY_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_COPY_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_MUL_2_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_SUB_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_DIV_2_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_MUL_2D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_MUL_D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_DIV_3_C -| | | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_MP_EXCH_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_KARATSUBA_MUL_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_SUB_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_MOD_C -| | | | | +--->BN_MP_DIV_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_MP_COPY_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_INIT_MULTI_C -| | | | | | +--->BN_MP_MUL_2D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_LSHD_C -| | | | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_C -| | | | | | +--->BN_MP_SUB_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_ADD_C -| | | | | | | +--->BN_S_MP_ADD_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | | +--->BN_S_MP_SUB_C -| | | | | | | | +--->BN_MP_GROW_C -| | | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_MUL_D_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_MOD_C -| | | | +--->BN_MP_DIV_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_SQR_C -| | | | +--->BN_MP_TOOM_SQR_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_MUL_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_3_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_KARATSUBA_SQR_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_FAST_S_MP_SQR_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_SQR_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_MUL_C -| | | | +--->BN_MP_TOOM_MUL_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_MUL_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_3_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_KARATSUBA_MUL_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_EXCH_C -| +--->BN_MP_CMP_C -| | +--->BN_MP_CMP_MAG_C -| +--->BN_MP_SQRMOD_C -| | +--->BN_MP_SQR_C -| | | +--->BN_MP_TOOM_SQR_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_MUL_2_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_2_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_3_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_KARATSUBA_SQR_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_FAST_S_MP_SQR_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SQR_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_CLEAR_C -| | +--->BN_MP_MOD_C -| | | +--->BN_MP_DIV_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_COUNT_BITS_C -| | | | +--->BN_MP_ABS_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_CLEAR_MULTI_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_CLEAR_C - - -BN_MP_SIGNED_BIN_SIZE_C -+--->BN_MP_UNSIGNED_BIN_SIZE_C -| +--->BN_MP_COUNT_BITS_C - - -BN_MP_INVMOD_SLOW_C -+--->BN_MP_INIT_MULTI_C -| +--->BN_MP_INIT_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_MOD_C -| +--->BN_MP_INIT_C -| +--->BN_MP_DIV_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_SET_C -| | +--->BN_MP_COUNT_BITS_C -| | +--->BN_MP_ABS_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2D_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_MULTI_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_INIT_COPY_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_CLEAR_C -| +--->BN_MP_ADD_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C -+--->BN_MP_COPY_C -| +--->BN_MP_GROW_C -+--->BN_MP_SET_C -| +--->BN_MP_ZERO_C -+--->BN_MP_DIV_2_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_ADD_C -| +--->BN_S_MP_ADD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -+--->BN_MP_SUB_C -| +--->BN_S_MP_ADD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -+--->BN_MP_CMP_C -| +--->BN_MP_CMP_MAG_C -+--->BN_MP_CMP_D_C -+--->BN_MP_CMP_MAG_C -+--->BN_MP_EXCH_C -+--->BN_MP_CLEAR_MULTI_C -| +--->BN_MP_CLEAR_C - - -BN_MP_LCM_C -+--->BN_MP_INIT_MULTI_C -| +--->BN_MP_INIT_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_GCD_C -| +--->BN_MP_ABS_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| +--->BN_MP_ZERO_C -| +--->BN_MP_INIT_COPY_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| +--->BN_MP_CNT_LSB_C -| +--->BN_MP_DIV_2D_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLEAR_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_MP_EXCH_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_MUL_2D_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_CMP_MAG_C -+--->BN_MP_DIV_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_ZERO_C -| +--->BN_MP_SET_C -| +--->BN_MP_COUNT_BITS_C -| +--->BN_MP_ABS_C -| +--->BN_MP_MUL_2D_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_C -| +--->BN_MP_SUB_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_ADD_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_DIV_2D_C -| | +--->BN_MP_INIT_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLEAR_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| +--->BN_MP_EXCH_C -| +--->BN_MP_CLEAR_MULTI_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_INIT_C -| +--->BN_MP_INIT_C -| +--->BN_MP_INIT_COPY_C -| +--->BN_MP_LSHD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_RSHD_C -| +--->BN_MP_RSHD_C -| +--->BN_MP_MUL_D_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CLAMP_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_MUL_C -| +--->BN_MP_TOOM_MUL_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_RSHD_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_MUL_2_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_3_C -| | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_INIT_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_MULTI_C -| | | +--->BN_MP_CLEAR_C -| +--->BN_MP_KARATSUBA_MUL_C -| | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_INIT_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | +--->BN_MP_CLEAR_C -| +--->BN_FAST_S_MP_MUL_DIGS_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_S_MP_MUL_DIGS_C -| | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_INIT_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C -+--->BN_MP_CLEAR_MULTI_C -| +--->BN_MP_CLEAR_C - - -BN_MP_REDUCE_2K_L_C -+--->BN_MP_INIT_C -+--->BN_MP_COUNT_BITS_C -+--->BN_MP_DIV_2D_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_ZERO_C -| +--->BN_MP_MOD_2D_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CLEAR_C -| +--->BN_MP_RSHD_C -| +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C -+--->BN_MP_MUL_C -| +--->BN_MP_TOOM_MUL_C -| | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_RSHD_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_MUL_2_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_3_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_MULTI_C -| | | +--->BN_MP_CLEAR_C -| +--->BN_MP_KARATSUBA_MUL_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | +--->BN_MP_CLEAR_C -| +--->BN_FAST_S_MP_MUL_DIGS_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_S_MP_MUL_DIGS_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C -+--->BN_S_MP_ADD_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_CMP_MAG_C -+--->BN_S_MP_SUB_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_CLEAR_C - - -BN_REVERSE_C - - -BN_MP_PRIME_IS_DIVISIBLE_C -+--->BN_MP_MOD_D_C -| +--->BN_MP_DIV_D_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_DIV_2D_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_INIT_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | +--->BN_MP_DIV_3_C -| | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_INIT_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_INIT_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C - - -BN_MP_SET_C -+--->BN_MP_ZERO_C - - -BN_MP_GCD_C -+--->BN_MP_ABS_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -+--->BN_MP_ZERO_C -+--->BN_MP_INIT_COPY_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -+--->BN_MP_CNT_LSB_C -+--->BN_MP_DIV_2D_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_MOD_2D_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CLEAR_C -| +--->BN_MP_RSHD_C -| +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C -+--->BN_MP_CMP_MAG_C -+--->BN_MP_EXCH_C -+--->BN_S_MP_SUB_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_MUL_2D_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_GROW_C -| +--->BN_MP_LSHD_C -| | +--->BN_MP_RSHD_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_CLEAR_C - - -BN_MP_REDUCE_2K_SETUP_L_C -+--->BN_MP_INIT_C -+--->BN_MP_2EXPT_C -| +--->BN_MP_ZERO_C -| +--->BN_MP_GROW_C -+--->BN_MP_COUNT_BITS_C -+--->BN_S_MP_SUB_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_CLEAR_C - - -BN_MP_READ_RADIX_C -+--->BN_MP_ZERO_C -+--->BN_MP_MUL_D_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_ADD_D_C -| +--->BN_MP_GROW_C -| +--->BN_MP_SUB_D_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CLAMP_C - - -BN_FAST_S_MP_MUL_HIGH_DIGS_C -+--->BN_MP_GROW_C -+--->BN_MP_CLAMP_C - - -BN_FAST_MP_MONTGOMERY_REDUCE_C -+--->BN_MP_GROW_C -+--->BN_MP_RSHD_C -| +--->BN_MP_ZERO_C -+--->BN_MP_CLAMP_C -+--->BN_MP_CMP_MAG_C -+--->BN_S_MP_SUB_C - - -BN_MP_DIV_D_C -+--->BN_MP_COPY_C -| +--->BN_MP_GROW_C -+--->BN_MP_DIV_2D_C -| +--->BN_MP_ZERO_C -| +--->BN_MP_INIT_C -| +--->BN_MP_MOD_2D_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CLEAR_C -| +--->BN_MP_RSHD_C -| +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C -+--->BN_MP_DIV_3_C -| +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_INIT_C -| +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_INIT_SIZE_C -| +--->BN_MP_INIT_C -+--->BN_MP_CLAMP_C -+--->BN_MP_EXCH_C -+--->BN_MP_CLEAR_C - - -BN_MP_REDUCE_2K_SETUP_C -+--->BN_MP_INIT_C -+--->BN_MP_COUNT_BITS_C -+--->BN_MP_2EXPT_C -| +--->BN_MP_ZERO_C -| +--->BN_MP_GROW_C -+--->BN_MP_CLEAR_C -+--->BN_S_MP_SUB_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C - - -BN_MP_INIT_SET_C -+--->BN_MP_INIT_C -+--->BN_MP_SET_C -| +--->BN_MP_ZERO_C - - -BN_MP_REDUCE_2K_C -+--->BN_MP_INIT_C -+--->BN_MP_COUNT_BITS_C -+--->BN_MP_DIV_2D_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_ZERO_C -| +--->BN_MP_MOD_2D_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CLEAR_C -| +--->BN_MP_RSHD_C -| +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C -+--->BN_MP_MUL_D_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_S_MP_ADD_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_CMP_MAG_C -+--->BN_S_MP_SUB_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_CLEAR_C - - -BN_ERROR_C - - -BN_MP_EXPT_D_C -+--->BN_MP_INIT_COPY_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -+--->BN_MP_SET_C -| +--->BN_MP_ZERO_C -+--->BN_MP_SQR_C -| +--->BN_MP_TOOM_SQR_C -| | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_RSHD_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_MUL_2_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_3_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_MULTI_C -| | | +--->BN_MP_CLEAR_C -| +--->BN_MP_KARATSUBA_SQR_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | +--->BN_MP_ADD_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_C -| +--->BN_FAST_S_MP_SQR_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_S_MP_SQR_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C -+--->BN_MP_CLEAR_C -+--->BN_MP_MUL_C -| +--->BN_MP_TOOM_MUL_C -| | +--->BN_MP_INIT_MULTI_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_RSHD_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_MUL_2_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_3_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_MULTI_C -| +--->BN_MP_KARATSUBA_MUL_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| +--->BN_FAST_S_MP_MUL_DIGS_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_S_MP_MUL_DIGS_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C - - -BN_S_MP_EXPTMOD_C -+--->BN_MP_COUNT_BITS_C -+--->BN_MP_INIT_C -+--->BN_MP_CLEAR_C -+--->BN_MP_REDUCE_SETUP_C -| +--->BN_MP_2EXPT_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_DIV_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_INIT_MULTI_C -| | +--->BN_MP_SET_C -| | +--->BN_MP_ABS_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2D_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_MULTI_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_INIT_COPY_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLAMP_C -+--->BN_MP_REDUCE_C -| +--->BN_MP_INIT_COPY_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| +--->BN_MP_RSHD_C -| | +--->BN_MP_ZERO_C -| +--->BN_MP_MUL_C -| | +--->BN_MP_TOOM_MUL_C -| | | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_MUL_2_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_2_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_2D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_3_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLEAR_MULTI_C -| | +--->BN_MP_KARATSUBA_MUL_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_MUL_DIGS_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| +--->BN_S_MP_MUL_HIGH_DIGS_C -| | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_MOD_2D_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_S_MP_MUL_DIGS_C -| | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| +--->BN_MP_SUB_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_D_C -| +--->BN_MP_SET_C -| | +--->BN_MP_ZERO_C -| +--->BN_MP_LSHD_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_ADD_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_C -| | +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -+--->BN_MP_REDUCE_2K_SETUP_L_C -| +--->BN_MP_2EXPT_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_GROW_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -+--->BN_MP_REDUCE_2K_L_C -| +--->BN_MP_DIV_2D_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| +--->BN_MP_MUL_C -| | +--->BN_MP_TOOM_MUL_C -| | | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_MUL_2_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_2_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_2D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_3_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLEAR_MULTI_C -| | +--->BN_MP_KARATSUBA_MUL_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_MUL_DIGS_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| +--->BN_S_MP_ADD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -+--->BN_MP_MOD_C -| +--->BN_MP_DIV_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_INIT_MULTI_C -| | +--->BN_MP_SET_C -| | +--->BN_MP_ABS_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2D_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_MULTI_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_INIT_COPY_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_ADD_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C -+--->BN_MP_COPY_C -| +--->BN_MP_GROW_C -+--->BN_MP_SQR_C -| +--->BN_MP_TOOM_SQR_C -| | +--->BN_MP_INIT_MULTI_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_RSHD_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_MUL_2_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_3_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_MULTI_C -| +--->BN_MP_KARATSUBA_SQR_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | +--->BN_MP_ADD_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| +--->BN_FAST_S_MP_SQR_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_S_MP_SQR_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -+--->BN_MP_MUL_C -| +--->BN_MP_TOOM_MUL_C -| | +--->BN_MP_INIT_MULTI_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_RSHD_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_MUL_2_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_3_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_MULTI_C -| +--->BN_MP_KARATSUBA_MUL_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| +--->BN_FAST_S_MP_MUL_DIGS_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_S_MP_MUL_DIGS_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -+--->BN_MP_SET_C -| +--->BN_MP_ZERO_C -+--->BN_MP_EXCH_C - - -BN_MP_ABS_C -+--->BN_MP_COPY_C -| +--->BN_MP_GROW_C - - -BN_MP_INIT_SET_INT_C -+--->BN_MP_INIT_C -+--->BN_MP_SET_INT_C -| +--->BN_MP_ZERO_C -| +--->BN_MP_MUL_2D_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CLAMP_C - - -BN_MP_SUB_D_C -+--->BN_MP_GROW_C -+--->BN_MP_ADD_D_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_CLAMP_C - - -BN_MP_TO_SIGNED_BIN_C -+--->BN_MP_TO_UNSIGNED_BIN_C -| +--->BN_MP_INIT_COPY_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| +--->BN_MP_DIV_2D_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLEAR_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| +--->BN_MP_CLEAR_C - - -BN_MP_DIV_2_C -+--->BN_MP_GROW_C -+--->BN_MP_CLAMP_C - - -BN_MP_REDUCE_IS_2K_C -+--->BN_MP_REDUCE_2K_C -| +--->BN_MP_INIT_C -| +--->BN_MP_COUNT_BITS_C -| +--->BN_MP_DIV_2D_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLEAR_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| +--->BN_MP_MUL_D_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_S_MP_ADD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_COUNT_BITS_C - - -BN_MP_INIT_SIZE_C -+--->BN_MP_INIT_C - - -BN_MP_DIV_C -+--->BN_MP_CMP_MAG_C -+--->BN_MP_COPY_C -| +--->BN_MP_GROW_C -+--->BN_MP_ZERO_C -+--->BN_MP_INIT_MULTI_C -| +--->BN_MP_INIT_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_SET_C -+--->BN_MP_COUNT_BITS_C -+--->BN_MP_ABS_C -+--->BN_MP_MUL_2D_C -| +--->BN_MP_GROW_C -| +--->BN_MP_LSHD_C -| | +--->BN_MP_RSHD_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_CMP_C -+--->BN_MP_SUB_C -| +--->BN_S_MP_ADD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -+--->BN_MP_ADD_C -| +--->BN_S_MP_ADD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -+--->BN_MP_DIV_2D_C -| +--->BN_MP_INIT_C -| +--->BN_MP_MOD_2D_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CLEAR_C -| +--->BN_MP_RSHD_C -| +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C -+--->BN_MP_EXCH_C -+--->BN_MP_CLEAR_MULTI_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_INIT_SIZE_C -| +--->BN_MP_INIT_C -+--->BN_MP_INIT_C -+--->BN_MP_INIT_COPY_C -+--->BN_MP_LSHD_C -| +--->BN_MP_GROW_C -| +--->BN_MP_RSHD_C -+--->BN_MP_RSHD_C -+--->BN_MP_MUL_D_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_CLAMP_C -+--->BN_MP_CLEAR_C - - -BN_MP_CLEAR_C - - -BN_MP_MONTGOMERY_REDUCE_C -+--->BN_FAST_MP_MONTGOMERY_REDUCE_C -| +--->BN_MP_GROW_C -| +--->BN_MP_RSHD_C -| | +--->BN_MP_ZERO_C -| +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -+--->BN_MP_GROW_C -+--->BN_MP_CLAMP_C -+--->BN_MP_RSHD_C -| +--->BN_MP_ZERO_C -+--->BN_MP_CMP_MAG_C -+--->BN_S_MP_SUB_C - - -BN_MP_MUL_2_C -+--->BN_MP_GROW_C - - -BN_MP_UNSIGNED_BIN_SIZE_C -+--->BN_MP_COUNT_BITS_C - - -BN_MP_ADDMOD_C -+--->BN_MP_INIT_C -+--->BN_MP_ADD_C -| +--->BN_S_MP_ADD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -+--->BN_MP_CLEAR_C -+--->BN_MP_MOD_C -| +--->BN_MP_DIV_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_INIT_MULTI_C -| | +--->BN_MP_SET_C -| | +--->BN_MP_COUNT_BITS_C -| | +--->BN_MP_ABS_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2D_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_MULTI_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_INIT_COPY_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C - - -BN_MP_ADD_C -+--->BN_S_MP_ADD_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_CMP_MAG_C -+--->BN_S_MP_SUB_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C - - -BN_MP_TO_SIGNED_BIN_N_C -+--->BN_MP_SIGNED_BIN_SIZE_C -| +--->BN_MP_UNSIGNED_BIN_SIZE_C -| | +--->BN_MP_COUNT_BITS_C -+--->BN_MP_TO_SIGNED_BIN_C -| +--->BN_MP_TO_UNSIGNED_BIN_C -| | +--->BN_MP_INIT_COPY_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_MP_DIV_2D_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C - - -BN_MP_REDUCE_IS_2K_L_C - - -BN_MP_RAND_C -+--->BN_MP_ZERO_C -+--->BN_MP_ADD_D_C -| +--->BN_MP_GROW_C -| +--->BN_MP_SUB_D_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_LSHD_C -| +--->BN_MP_GROW_C -| +--->BN_MP_RSHD_C - - -BN_MP_CNT_LSB_C - - -BN_MP_2EXPT_C -+--->BN_MP_ZERO_C -+--->BN_MP_GROW_C - - -BN_MP_RSHD_C -+--->BN_MP_ZERO_C - - -BN_MP_SHRINK_C - - -BN_MP_TO_UNSIGNED_BIN_N_C -+--->BN_MP_UNSIGNED_BIN_SIZE_C -| +--->BN_MP_COUNT_BITS_C -+--->BN_MP_TO_UNSIGNED_BIN_C -| +--->BN_MP_INIT_COPY_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| +--->BN_MP_DIV_2D_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLEAR_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| +--->BN_MP_CLEAR_C - - -BN_MP_REDUCE_C -+--->BN_MP_REDUCE_SETUP_C -| +--->BN_MP_2EXPT_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_DIV_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_INIT_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_SET_C -| | +--->BN_MP_COUNT_BITS_C -| | +--->BN_MP_ABS_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2D_C -| | | +--->BN_MP_INIT_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_MULTI_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_INIT_C -| | +--->BN_MP_INIT_C -| | +--->BN_MP_INIT_COPY_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLEAR_C -+--->BN_MP_INIT_COPY_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -+--->BN_MP_RSHD_C -| +--->BN_MP_ZERO_C -+--->BN_MP_MUL_C -| +--->BN_MP_TOOM_MUL_C -| | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_MUL_2_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_3_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_MULTI_C -| | | +--->BN_MP_CLEAR_C -| +--->BN_MP_KARATSUBA_MUL_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_C -| +--->BN_FAST_S_MP_MUL_DIGS_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_S_MP_MUL_DIGS_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C -+--->BN_S_MP_MUL_HIGH_DIGS_C -| +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_INIT_SIZE_C -| +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C -| +--->BN_MP_CLEAR_C -+--->BN_FAST_S_MP_MUL_HIGH_DIGS_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_MOD_2D_C -| +--->BN_MP_ZERO_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_S_MP_MUL_DIGS_C -| +--->BN_FAST_S_MP_MUL_DIGS_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_INIT_SIZE_C -| +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_SUB_C -| +--->BN_S_MP_ADD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -+--->BN_MP_CMP_D_C -+--->BN_MP_SET_C -| +--->BN_MP_ZERO_C -+--->BN_MP_LSHD_C -| +--->BN_MP_GROW_C -+--->BN_MP_ADD_C -| +--->BN_S_MP_ADD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -+--->BN_MP_CMP_C -| +--->BN_MP_CMP_MAG_C -+--->BN_S_MP_SUB_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_CLEAR_C - - -BN_MP_MUL_2D_C -+--->BN_MP_COPY_C -| +--->BN_MP_GROW_C -+--->BN_MP_GROW_C -+--->BN_MP_LSHD_C -| +--->BN_MP_RSHD_C -| | +--->BN_MP_ZERO_C -+--->BN_MP_CLAMP_C - - -BN_MP_GET_INT_C - - -BN_MP_JACOBI_C -+--->BN_MP_CMP_D_C -+--->BN_MP_INIT_COPY_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -+--->BN_MP_CNT_LSB_C -+--->BN_MP_DIV_2D_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_ZERO_C -| +--->BN_MP_MOD_2D_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CLEAR_C -| +--->BN_MP_RSHD_C -| +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C -+--->BN_MP_MOD_C -| +--->BN_MP_DIV_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_SET_C -| | +--->BN_MP_COUNT_BITS_C -| | +--->BN_MP_ABS_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_MULTI_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_CLEAR_C -| +--->BN_MP_ADD_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C -+--->BN_MP_CLEAR_C - - -BN_MP_CLEAR_MULTI_C -+--->BN_MP_CLEAR_C - - -BN_MP_MUL_C -+--->BN_MP_TOOM_MUL_C -| +--->BN_MP_INIT_MULTI_C -| | +--->BN_MP_INIT_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_MOD_2D_C -| | +--->BN_MP_ZERO_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_RSHD_C -| | +--->BN_MP_ZERO_C -| +--->BN_MP_MUL_2_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_ADD_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_SUB_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_DIV_2_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_MUL_2D_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_MUL_D_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_DIV_3_C -| | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_INIT_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_LSHD_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_CLEAR_MULTI_C -| | +--->BN_MP_CLEAR_C -+--->BN_MP_KARATSUBA_MUL_C -| +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_INIT_C -| +--->BN_MP_CLAMP_C -| +--->BN_MP_SUB_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| +--->BN_MP_ADD_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CMP_MAG_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| +--->BN_MP_LSHD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_RSHD_C -| | | +--->BN_MP_ZERO_C -| +--->BN_MP_CLEAR_C -+--->BN_FAST_S_MP_MUL_DIGS_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_S_MP_MUL_DIGS_C -| +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_INIT_C -| +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C -| +--->BN_MP_CLEAR_C - - -BN_MP_EXTEUCLID_C -+--->BN_MP_INIT_MULTI_C -| +--->BN_MP_INIT_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_SET_C -| +--->BN_MP_ZERO_C -+--->BN_MP_COPY_C -| +--->BN_MP_GROW_C -+--->BN_MP_DIV_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_MP_ZERO_C -| +--->BN_MP_COUNT_BITS_C -| +--->BN_MP_ABS_C -| +--->BN_MP_MUL_2D_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_C -| +--->BN_MP_SUB_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_ADD_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_DIV_2D_C -| | +--->BN_MP_INIT_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLEAR_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| +--->BN_MP_EXCH_C -| +--->BN_MP_CLEAR_MULTI_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_INIT_C -| +--->BN_MP_INIT_C -| +--->BN_MP_INIT_COPY_C -| +--->BN_MP_LSHD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_RSHD_C -| +--->BN_MP_RSHD_C -| +--->BN_MP_MUL_D_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CLAMP_C -| +--->BN_MP_CLEAR_C -+--->BN_MP_MUL_C -| +--->BN_MP_TOOM_MUL_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_RSHD_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_MUL_2_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_3_C -| | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_INIT_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_MULTI_C -| | | +--->BN_MP_CLEAR_C -| +--->BN_MP_KARATSUBA_MUL_C -| | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_INIT_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | +--->BN_MP_CLEAR_C -| +--->BN_FAST_S_MP_MUL_DIGS_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_S_MP_MUL_DIGS_C -| | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_INIT_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C -+--->BN_MP_SUB_C -| +--->BN_S_MP_ADD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -+--->BN_MP_NEG_C -+--->BN_MP_EXCH_C -+--->BN_MP_CLEAR_MULTI_C -| +--->BN_MP_CLEAR_C - - -BN_MP_DR_REDUCE_C -+--->BN_MP_GROW_C -+--->BN_MP_CLAMP_C -+--->BN_MP_CMP_MAG_C -+--->BN_S_MP_SUB_C - - -BN_MP_FREAD_C -+--->BN_MP_ZERO_C -+--->BN_MP_MUL_D_C -| +--->BN_MP_GROW_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_ADD_D_C -| +--->BN_MP_GROW_C -| +--->BN_MP_SUB_D_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_CMP_D_C - - -BN_MP_REDUCE_SETUP_C -+--->BN_MP_2EXPT_C -| +--->BN_MP_ZERO_C -| +--->BN_MP_GROW_C -+--->BN_MP_DIV_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_ZERO_C -| +--->BN_MP_INIT_MULTI_C -| | +--->BN_MP_INIT_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_SET_C -| +--->BN_MP_COUNT_BITS_C -| +--->BN_MP_ABS_C -| +--->BN_MP_MUL_2D_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CMP_C -| +--->BN_MP_SUB_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_ADD_C -| | +--->BN_S_MP_ADD_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_SUB_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| +--->BN_MP_DIV_2D_C -| | +--->BN_MP_INIT_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_CLEAR_C -| | +--->BN_MP_RSHD_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| +--->BN_MP_EXCH_C -| +--->BN_MP_CLEAR_MULTI_C -| | +--->BN_MP_CLEAR_C -| +--->BN_MP_INIT_SIZE_C -| | +--->BN_MP_INIT_C -| +--->BN_MP_INIT_C -| +--->BN_MP_INIT_COPY_C -| +--->BN_MP_LSHD_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_RSHD_C -| +--->BN_MP_RSHD_C -| +--->BN_MP_MUL_D_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CLAMP_C -| +--->BN_MP_CLEAR_C - - -BN_MP_MONTGOMERY_SETUP_C - - -BN_MP_KARATSUBA_MUL_C -+--->BN_MP_MUL_C -| +--->BN_MP_TOOM_MUL_C -| | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_INIT_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_MOD_2D_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_RSHD_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_MUL_2_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_SUB_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_2_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_2D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MUL_D_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_DIV_3_C -| | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_INIT_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_LSHD_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_CLEAR_MULTI_C -| | | +--->BN_MP_CLEAR_C -| +--->BN_FAST_S_MP_MUL_DIGS_C -| | +--->BN_MP_GROW_C -| | +--->BN_MP_CLAMP_C -| +--->BN_S_MP_MUL_DIGS_C -| | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_INIT_C -| | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -| | +--->BN_MP_CLEAR_C -+--->BN_MP_INIT_SIZE_C -| +--->BN_MP_INIT_C -+--->BN_MP_CLAMP_C -+--->BN_MP_SUB_C -| +--->BN_S_MP_ADD_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -+--->BN_MP_ADD_C -| +--->BN_S_MP_ADD_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_CMP_MAG_C -| +--->BN_S_MP_SUB_C -| | +--->BN_MP_GROW_C -+--->BN_MP_LSHD_C -| +--->BN_MP_GROW_C -| +--->BN_MP_RSHD_C -| | +--->BN_MP_ZERO_C -+--->BN_MP_CLEAR_C - - -BN_MP_LSHD_C -+--->BN_MP_GROW_C -+--->BN_MP_RSHD_C -| +--->BN_MP_ZERO_C - - -BN_MP_PRIME_MILLER_RABIN_C -+--->BN_MP_CMP_D_C -+--->BN_MP_INIT_COPY_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -+--->BN_MP_SUB_D_C -| +--->BN_MP_GROW_C -| +--->BN_MP_ADD_D_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CLAMP_C -+--->BN_MP_CNT_LSB_C -+--->BN_MP_DIV_2D_C -| +--->BN_MP_COPY_C -| | +--->BN_MP_GROW_C -| +--->BN_MP_ZERO_C -| +--->BN_MP_MOD_2D_C -| | +--->BN_MP_CLAMP_C -| +--->BN_MP_CLEAR_C -| +--->BN_MP_RSHD_C -| +--->BN_MP_CLAMP_C -| +--->BN_MP_EXCH_C -+--->BN_MP_EXPTMOD_C -| +--->BN_MP_INVMOD_C -| | +--->BN_FAST_MP_INVMOD_C -| | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_MOD_C -| | | | +--->BN_MP_DIV_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_SET_C -| | | | | +--->BN_MP_COUNT_BITS_C -| | | | | +--->BN_MP_ABS_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | | +--->BN_MP_CLEAR_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_SET_C -| | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_DIV_2_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_MULTI_C -| | | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_INVMOD_SLOW_C -| | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_MOD_C -| | | | +--->BN_MP_DIV_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_SET_C -| | | | | +--->BN_MP_COUNT_BITS_C -| | | | | +--->BN_MP_ABS_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_CLEAR_MULTI_C -| | | | | | +--->BN_MP_CLEAR_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_CLEAR_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_SET_C -| | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_DIV_2_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_MULTI_C -| | | | +--->BN_MP_CLEAR_C -| +--->BN_MP_CLEAR_C -| +--->BN_MP_ABS_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| +--->BN_MP_CLEAR_MULTI_C -| +--->BN_MP_REDUCE_IS_2K_L_C -| +--->BN_S_MP_EXPTMOD_C -| | +--->BN_MP_COUNT_BITS_C -| | +--->BN_MP_REDUCE_SETUP_C -| | | +--->BN_MP_2EXPT_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_DIV_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_SET_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_REDUCE_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_MUL_C -| | | | +--->BN_MP_TOOM_MUL_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_COPY_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_MUL_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_3_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_KARATSUBA_MUL_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | +--->BN_S_MP_MUL_HIGH_DIGS_C -| | | | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_MUL_DIGS_C -| | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SET_C -| | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_REDUCE_2K_SETUP_L_C -| | | +--->BN_MP_2EXPT_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_REDUCE_2K_L_C -| | | +--->BN_MP_MUL_C -| | | | +--->BN_MP_TOOM_MUL_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_COPY_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_MUL_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_3_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_KARATSUBA_MUL_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MOD_C -| | | +--->BN_MP_DIV_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_SET_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_SQR_C -| | | +--->BN_MP_TOOM_SQR_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_MUL_2_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_2_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_3_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_KARATSUBA_SQR_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | +--->BN_FAST_S_MP_SQR_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SQR_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | +--->BN_MP_MUL_C -| | | +--->BN_MP_TOOM_MUL_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_MUL_2_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_2_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_3_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_KARATSUBA_MUL_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_MUL_DIGS_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | +--->BN_MP_SET_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_EXCH_C -| +--->BN_MP_DR_IS_MODULUS_C -| +--->BN_MP_REDUCE_IS_2K_C -| | +--->BN_MP_REDUCE_2K_C -| | | +--->BN_MP_COUNT_BITS_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_COUNT_BITS_C -| +--->BN_MP_EXPTMOD_FAST_C -| | +--->BN_MP_COUNT_BITS_C -| | +--->BN_MP_MONTGOMERY_SETUP_C -| | +--->BN_FAST_MP_MONTGOMERY_REDUCE_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | +--->BN_MP_MONTGOMERY_REDUCE_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | +--->BN_MP_DR_SETUP_C -| | +--->BN_MP_DR_REDUCE_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | +--->BN_MP_REDUCE_2K_SETUP_C -| | | +--->BN_MP_2EXPT_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_REDUCE_2K_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MONTGOMERY_CALC_NORMALIZATION_C -| | | +--->BN_MP_2EXPT_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_SET_C -| | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_MUL_2_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_MULMOD_C -| | | +--->BN_MP_MUL_C -| | | | +--->BN_MP_TOOM_MUL_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_MOD_2D_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | | +--->BN_MP_COPY_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_MUL_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_2_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_DIV_3_C -| | | | | | +--->BN_MP_INIT_SIZE_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_KARATSUBA_MUL_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CMP_MAG_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_MUL_DIGS_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_MOD_C -| | | | +--->BN_MP_DIV_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_MP_COPY_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_INIT_MULTI_C -| | | | | +--->BN_MP_SET_C -| | | | | +--->BN_MP_MUL_2D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_LSHD_C -| | | | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_C -| | | | | +--->BN_MP_SUB_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_ADD_C -| | | | | | +--->BN_S_MP_ADD_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | | +--->BN_S_MP_SUB_C -| | | | | | | +--->BN_MP_GROW_C -| | | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_MUL_D_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | +--->BN_MP_SET_C -| | | +--->BN_MP_ZERO_C -| | +--->BN_MP_MOD_C -| | | +--->BN_MP_DIV_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | +--->BN_MP_COPY_C -| | | +--->BN_MP_GROW_C -| | +--->BN_MP_SQR_C -| | | +--->BN_MP_TOOM_SQR_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_MUL_2_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_2_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_3_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_KARATSUBA_SQR_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | +--->BN_FAST_S_MP_SQR_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_SQR_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | +--->BN_MP_MUL_C -| | | +--->BN_MP_TOOM_MUL_C -| | | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_MOD_2D_C -| | | | | +--->BN_MP_ZERO_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_MUL_2_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_2_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_2D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_MUL_D_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_DIV_3_C -| | | | | +--->BN_MP_INIT_SIZE_C -| | | | | +--->BN_MP_CLAMP_C -| | | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_KARATSUBA_MUL_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_SUB_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_ADD_C -| | | | | +--->BN_S_MP_ADD_C -| | | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CMP_MAG_C -| | | | | +--->BN_S_MP_SUB_C -| | | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_RSHD_C -| | | | | | +--->BN_MP_ZERO_C -| | | +--->BN_FAST_S_MP_MUL_DIGS_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_S_MP_MUL_DIGS_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | +--->BN_MP_EXCH_C -+--->BN_MP_CMP_C -| +--->BN_MP_CMP_MAG_C -+--->BN_MP_SQRMOD_C -| +--->BN_MP_SQR_C -| | +--->BN_MP_TOOM_SQR_C -| | | +--->BN_MP_INIT_MULTI_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_MOD_2D_C -| | | | +--->BN_MP_ZERO_C -| | | | +--->BN_MP_COPY_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_MUL_2_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_2_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_2D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_DIV_3_C -| | | | +--->BN_MP_INIT_SIZE_C -| | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_MP_EXCH_C -| | | | +--->BN_MP_CLEAR_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLEAR_MULTI_C -| | | | +--->BN_MP_CLEAR_C -| | +--->BN_MP_KARATSUBA_SQR_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_MP_CMP_MAG_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLEAR_C -| | +--->BN_FAST_S_MP_SQR_C -| | | +--->BN_MP_GROW_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_S_MP_SQR_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_C -| +--->BN_MP_CLEAR_C -| +--->BN_MP_MOD_C -| | +--->BN_MP_DIV_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_MP_COPY_C -| | | | +--->BN_MP_GROW_C -| | | +--->BN_MP_ZERO_C -| | | +--->BN_MP_INIT_MULTI_C -| | | +--->BN_MP_SET_C -| | | +--->BN_MP_COUNT_BITS_C -| | | +--->BN_MP_ABS_C -| | | +--->BN_MP_MUL_2D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_LSHD_C -| | | | | +--->BN_MP_RSHD_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_SUB_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_ADD_C -| | | | +--->BN_S_MP_ADD_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | | +--->BN_S_MP_SUB_C -| | | | | +--->BN_MP_GROW_C -| | | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_EXCH_C -| | | +--->BN_MP_CLEAR_MULTI_C -| | | +--->BN_MP_INIT_SIZE_C -| | | +--->BN_MP_LSHD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_RSHD_C -| | | +--->BN_MP_MUL_D_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_ADD_C -| | | +--->BN_S_MP_ADD_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | | +--->BN_MP_CMP_MAG_C -| | | +--->BN_S_MP_SUB_C -| | | | +--->BN_MP_GROW_C -| | | | +--->BN_MP_CLAMP_C -| | +--->BN_MP_EXCH_C -+--->BN_MP_CLEAR_C - - -BN_MP_DR_SETUP_C - - -BN_MP_CMP_MAG_C - - diff --git a/external/libtommath-0.42.0/changes.txt b/external/libtommath-0.42.0/changes.txt deleted file mode 100755 index 4fc0913..0000000 --- a/external/libtommath-0.42.0/changes.txt +++ /dev/null @@ -1,403 +0,0 @@ -July 23rd, 2010 -v0.42.0 - -- Fix for mp_prime_next_prime() bug when checking generated prime - -- allow mp_shrink to shrink initialized, but empty MPI's - -- Added project and solution files for Visual Studio 2005 and Visual Studio 2008. - -March 10th, 2007 -v0.41 -- Wolfgang Ehrhardt suggested a quick fix to mp_div_d() which makes the detection of powers of two quicker. - -- [CRI] Added libtommath.dsp for Visual C++ users. - -December 24th, 2006 -v0.40 -- Updated makefile to properly support LIBNAME - -- Fixed bug in fast_s_mp_mul_high_digs() which overflowed (line 83), thanks Valgrind! - -April 4th, 2006 -v0.39 -- Jim Wigginton pointed out my Montgomery examples in figures 6.4 and 6.6 were off by one, k should be 9 not 8 - -- Bruce Guenter suggested I use --tag=CC for libtool builds where the compiler may think it's C++. - -- "mm" from sci.crypt pointed out that my mp_gcd was sub-optimal (I also updated and corrected the book) - -- updated some of the @@ tags in tommath.src to reflect source changes. - -- updated email and url info in all source files - -Jan 26th, 2006 -v0.38 -- broken makefile.shared fixed - -- removed some carry stores that were not required [updated text] - -November 18th, 2005 -v0.37 -- [Don Porter] reported on a TCL list [HEY SEND ME BUGREPORTS ALREADY!!!] that mp_add_d() would compute -0 with some inputs. Fixed. - -- [rinick@gmail.com] reported the makefile.bcc was messed up. Fixed. - -- [Kevin Kenny] reported some issues with mp_toradix_n(). Now it doesn't require a min of 3 chars of output. - -- Made the make command renamable. Wee - -August 1st, 2005 -v0.36 -- LTM_PRIME_2MSB_ON was fixed and the "OFF" flag was removed. - -- [Peter LaDow] found a typo in the XREALLOC macro - -- [Peter LaDow] pointed out that mp_read_(un)signed_bin should have "const" on the input - -- Ported LTC patch to fix the prime_random_ex() function to get the bitsize correct [and the maskOR flags] - -- Kevin Kenny pointed out a stray // - -- David Hulton pointed out a typo in the textbook [mp_montgomery_setup() pseudo-code] - -- Neal Hamilton (Elliptic Semiconductor) pointed out that my Karatsuba notation was backwards and that I could use - unsigned operations in the routine. - -- Paul Schmidt pointed out a linking error in mp_exptmod() when BN_S_MP_EXPTMOD_C is undefined (and another for read_radix) - -- Updated makefiles to be way more flexible - -March 12th, 2005 -v0.35 -- Stupid XOR function missing line again... oops. - -- Fixed bug in invmod not handling negative inputs correctly [Wolfgang Ehrhardt] - -- Made exteuclid always give positive u3 output...[ Wolfgang Ehrhardt ] - -- [Wolfgang Ehrhardt] Suggested a fix for mp_reduce() which avoided underruns. ;-) - -- mp_rand() would emit one too many digits and it was possible to get a 0 out of it ... oops - -- Added montgomery to the testing to make sure it handles 1..10 digit moduli correctly - -- Fixed bug in comba that would lead to possible erroneous outputs when "pa < digs" - -- Fixed bug in mp_toradix_size for "0" [Kevin Kenny] - -- Updated chapters 1-5 of the textbook ;-) It now talks about the new comba code! - -February 12th, 2005 -v0.34 -- Fixed two more small errors in mp_prime_random_ex() - -- Fixed overflow in mp_mul_d() [Kevin Kenny] - -- Added mp_to_(un)signed_bin_n() functions which do bounds checking for ya [and report the size] - -- Added "large" diminished radix support. Speeds up things like DSA where the moduli is of the form 2^k - P for some P < 2^(k/2) or so - Actually is faster than Montgomery on my AMD64 (and probably much faster on a P4) - -- Updated the manual a bit - -- Ok so I haven't done the textbook work yet... My current freelance gig has landed me in France till the - end of Feb/05. Once I get back I'll have tons of free time and I plan to go to town on the book. - As of this release the API will freeze. At least until the book catches up with all the changes. I welcome - bug reports but new algorithms will have to wait. - -December 23rd, 2004 -v0.33 -- Fixed "small" variant for mp_div() which would munge with negative dividends... - -- Fixed bug in mp_prime_random_ex() which would set the most significant byte to zero when - no special flags were set - -- Fixed overflow [minor] bug in fast_s_mp_sqr() - -- Made the makefiles easier to configure the group/user that ltm will install as - -- Fixed "final carry" bug in comba multipliers. (Volkan Ceylan) - -- Matt Johnston pointed out a missing semi-colon in mp_exptmod - -October 29th, 2004 -v0.32 -- Added "makefile.shared" for shared object support - -- Added more to the build options/configs in the manual - -- Started the Depends framework, wrote dep.pl to scan deps and - produce "callgraph.txt" ;-) - -- Wrote SC_RSA_1 which will enable close to the minimum required to perform - RSA on 32-bit [or 64-bit] platforms with LibTomCrypt - -- Merged in the small/slower mp_div replacement. You can now toggle which - you want to use as your mp_div() at build time. Saves roughly 8KB or so. - -- Renamed a few files and changed some comments to make depends system work better. - (No changes to function names) - -- Merged in new Combas that perform 2 reads per inner loop instead of the older - 3reads/2writes per inner loop of the old code. Really though if you want speed - learn to use TomsFastMath ;-) - -August 9th, 2004 -v0.31 -- "profiled" builds now :-) new timings for Intel Northwoods - -- Added "pretty" build target - -- Update mp_init() to actually assign 0's instead of relying on calloc() - -- "Wolfgang Ehrhardt" found a bug in mp_mul() where if - you multiply a negative by zero you get negative zero as the result. Oops. - -- J Harper from PeerSec let me toy with his AMD64 and I got 60-bit digits working properly - [this also means that I fixed a bug where if sizeof(int) < sizeof(mp_digit) it would bug] - -April 11th, 2004 -v0.30 -- Added "mp_toradix_n" which stores upto "n-1" least significant digits of an mp_int - -- Johan Lindh sent a patch so MSVC wouldn't whine about redefining malloc [in weird dll modes] - -- Henrik Goldman spotted a missing OPT_CAST in mp_fwrite() - -- Tuned tommath.h so that when MP_LOW_MEM is defined MP_PREC shall be reduced. - [I also allow MP_PREC to be externally defined now] - -- Sped up mp_cnt_lsb() by using a 4x4 table [e.g. 4x speedup] - -- Added mp_prime_random_ex() which is a more versatile prime generator accurate to - exact bit lengths (unlike the deprecated but still available mp_prime_random() which - is only accurate to byte lengths). See the new LTM_PRIME_* flags ;-) - -- Alex Polushin contributed an optimized mp_sqrt() as well as mp_get_int() and mp_is_square(). - I've cleaned them all up to be a little more consistent [along with one bug fix] for this release. - -- Added mp_init_set and mp_init_set_int to initialize and set small constants with one function - call. - -- Removed /etclib directory [um LibTomPoly deprecates this]. - -- Fixed mp_mod() so the sign of the result agrees with the sign of the modulus. - ++ N.B. My semester is almost up so expect updates to the textbook to be posted to the libtomcrypt.org - website. - -Jan 25th, 2004 -v0.29 ++ Note: "Henrik" from the v0.28 changelog refers to Henrik Goldman ;-) - -- Added fix to mp_shrink to prevent a realloc when used == 0 [e.g. realloc zero bytes???] - -- Made the mp_prime_rabin_miller_trials() function internal table smaller and also - set the minimum number of tests to two (sounds a bit safer). - -- Added a mp_exteuclid() which computes the extended euclidean algorithm. - -- Fixed a memory leak in s_mp_exptmod() [called when Barrett reduction is to be used] which would arise - if a multiplication or subsequent reduction failed [would not free the temp result]. - -- Made an API change to mp_radix_size(). It now returns an error code and stores the required size - through an "int star" passed to it. - -Dec 24th, 2003 -v0.28 -- Henrik Goldman suggested I add casts to the montomgery code [stores into mu...] so compilers wouldn't - spew [erroneous] diagnostics... fixed. - -- Henrik Goldman also spotted two typos. One in mp_radix_size() and another in mp_toradix(). - -- Added fix to mp_shrink() to avoid a memory leak. - -- Added mp_prime_random() which requires a callback to make truly random primes of a given nature - (idea from chat with Niels Ferguson at Crypto'03) - -- Picked up a second wind. I'm filled with Gooo. Mission Gooo! - -- Removed divisions from mp_reduce_is_2k() - -- Sped up mp_div_d() [general case] to use only one division per digit instead of two. - -- Added the heap macros from LTC to LTM. Now you can easily [by editing four lines of tommath.h] - change the name of the heap functions used in LTM [also compatible with LTC via MPI mode] - -- Added bn_prime_rabin_miller_trials() which gives the number of Rabin-Miller trials to achieve - a failure rate of less than 2^-96 - -- fixed bug in fast_mp_invmod(). The initial testing logic was wrong. An invalid input is not when - "a" and "b" are even it's when "b" is even [the algo is for odd moduli only]. - -- Started a new manual [finally]. It is incomplete and will be finished as time goes on. I had to stop - adding full demos around half way in chapter three so I could at least get a good portion of the - manual done. If you really need help using the library you can always email me! - -- My Textbook is now included as part of the package [all Public Domain] - -Sept 19th, 2003 -v0.27 -- Removed changes.txt~ which was made by accident since "kate" decided it was - a good time to re-enable backups... [kde is fun!] - -- In mp_grow() "a->dp" is not overwritten by realloc call [re: memory leak] - Now if mp_grow() fails the mp_int is still valid and can be cleared via - mp_clear() to reclaim the memory. - -- Henrik Goldman found a buffer overflow bug in mp_add_d(). Fixed. - -- Cleaned up mp_mul_d() to be much easier to read and follow. - -Aug 29th, 2003 -v0.26 -- Fixed typo that caused warning with GCC 3.2 - -- Martin Marcel noticed a bug in mp_neg() that allowed negative zeroes. - Also, Martin is the fellow who noted the bugs in mp_gcd() of 0.24/0.25. - -- Martin Marcel noticed an optimization [and slight bug] in mp_lcm(). - -- Added fix to mp_read_unsigned_bin to prevent a buffer overflow. - -- Beefed up the comments in the baseline multipliers [and montgomery] - -- Added "mont" demo to the makefile.msvc in etc/ - -- Optimized sign compares in mp_cmp from 4 to 2 cases. - -Aug 4th, 2003 -v0.25 -- Fix to mp_gcd again... oops (0,-a) == (-a, 0) == a - -- Fix to mp_clear which didn't reset the sign [Greg Rose] - -- Added mp_error_to_string() to convert return codes to strings. [Greg Rose] - -- Optimized fast_mp_invmod() to do the test for invalid inputs [both even] - first so temps don't have to be initialized if it's going to fail. - -- Optimized mp_gcd() by removing mp_div_2d calls for when one of the inputs - is odd. - -- Tons of new comments, some indentation fixups, etc. - -- mp_jacobi() returns MP_VAL if the modulus is less than or equal to zero. - -- fixed two typos in the header of each file :-) - -- LibTomMath is officially Public Domain [see LICENSE] - -July 15th, 2003 -v0.24 -- Optimized mp_add_d and mp_sub_d to not allocate temporary variables - -- Fixed mp_gcd() so the gcd of 0,0 is 0. Allows the gcd operation to be chained - e.g. (0,0,a) == a [instead of 1] - -- Should be one of the last release for a while. Working on LibTomMath book now. - -- optimized the pprime demo [/etc/pprime.c] to first make a huge table of single - digit primes then it reads them randomly instead of randomly choosing/testing single - digit primes. - -July 12th, 2003 -v0.23 -- Optimized mp_prime_next_prime() to not use mp_mod [via is_divisible()] in each - iteration. Instead now a smaller table is kept of the residues which can be updated - without division. - -- Fixed a bug in next_prime() where an input of zero would be treated as odd and - have two added to it [to move to the next odd]. - -- fixed a bug in prime_fermat() and prime_miller_rabin() which allowed the base - to be negative, zero or one. Normally the test is only valid if the base is - greater than one. - -- changed the next_prime() prototype to accept a new parameter "bbs_style" which - will find the next prime congruent to 3 mod 4. The default [bbs_style==0] will - make primes which are either congruent to 1 or 3 mod 4. - -- fixed mp_read_unsigned_bin() so that it doesn't include both code for - the case DIGIT_BIT < 8 and >= 8 - -- optimized div_d() to easy out on division by 1 [or if a == 0] and use - logical shifts if the divisor is a power of two. - -- the default DIGIT_BIT type was not int for non-default builds. Fixed. - -July 2nd, 2003 -v0.22 -- Fixed up mp_invmod so the result is properly in range now [was always congruent to the inverse...] - -- Fixed up s_mp_exptmod and mp_exptmod_fast so the lower half of the pre-computed table isn't allocated - which makes the algorithm use half as much ram. - -- Fixed the install script not to make the book :-) [which isn't included anyways] - -- added mp_cnt_lsb() which counts how many of the lsbs are zero - -- optimized mp_gcd() to use the new mp_cnt_lsb() to replace multiple divisions by two by a single division. - -- applied similar optimization to mp_prime_miller_rabin(). - -- Fixed a bug in both mp_invmod() and fast_mp_invmod() which tested for odd - via "mp_iseven() == 0" which is not valid [since zero is not even either]. - -June 19th, 2003 -v0.21 -- Fixed bug in mp_mul_d which would not handle sign correctly [would not always forward it] - -- Removed the #line lines from gen.pl [was in violation of ISO C] - -June 8th, 2003 -v0.20 -- Removed the book from the package. Added the TDCAL license document. - -- This release is officially pure-bred TDCAL again [last officially TDCAL based release was v0.16] - -June 6th, 2003 -v0.19 -- Fixed a bug in mp_montgomery_reduce() which was introduced when I tweaked mp_rshd() in the previous release. - Essentially the digits were not trimmed before the compare which cause a subtraction to occur all the time. - -- Fixed up etc/tune.c a bit to stop testing new cutoffs after 16 failures [to find more optimal points]. - Brute force ho! - - -May 29th, 2003 -v0.18 -- Fixed a bug in s_mp_sqr which would handle carries properly just not very elegantly. - (e.g. correct result, just bad looking code) - -- Fixed bug in mp_sqr which still had a 512 constant instead of MP_WARRAY - -- Added Toom-Cook multipliers [needs tuning!] - -- Added efficient divide by 3 algorithm mp_div_3 - -- Re-wrote mp_div_d to be faster than calling mp_div - -- Added in a donated BCC makefile and a single page LTM poster (ahalhabsi@sbcglobal.net) - -- Added mp_reduce_2k which reduces an input modulo n = 2**p - k for any single digit k - -- Made the exptmod system be aware of the 2k reduction algorithms. - -- Rewrote mp_dr_reduce to be smaller, simpler and easier to understand. - -May 17th, 2003 -v0.17 -- Benjamin Goldberg submitted optimized mp_add and mp_sub routines. A new gen.pl as well - as several smaller suggestions. Thanks! - -- removed call to mp_cmp in inner loop of mp_div and put mp_cmp_mag in its place :-) - -- Fixed bug in mp_exptmod that would cause it to fail for odd moduli when DIGIT_BIT != 28 - -- mp_exptmod now also returns errors if the modulus is negative and will handle negative exponents - -- mp_prime_is_prime will now return true if the input is one of the primes in the prime table - -- Damian M Gryski (dgryski@uwaterloo.ca) found a index out of bounds error in the - mp_fast_s_mp_mul_high_digs function which didn't come up before. (fixed) - -- Refactored the DR reduction code so there is only one function per file. - -- Fixed bug in the mp_mul() which would erroneously avoid the faster multiplier [comba] when it was - allowed. The bug would not cause the incorrect value to be produced just less efficient (fixed) - -- Fixed similar bug in the Montgomery reduction code. - -- Added tons of (mp_digit) casts so the 7/15/28/31 bit digit code will work flawlessly out of the box. - Also added limited support for 64-bit machines with a 60-bit digit. Both thanks to Tom Wu (tom@arcot.com) - -- Added new comments here and there, cleaned up some code [style stuff] - -- Fixed a lingering typo in mp_exptmod* that would set bitcnt to zero then one. Very silly stuff :-) - -- Fixed up mp_exptmod_fast so it would set "redux" to the comba Montgomery reduction if allowed. This - saves quite a few calls and if statements. - -- Added etc/mont.c a test of the Montgomery reduction [assuming all else works :-| ] - -- Fixed up etc/tune.c to use a wider test range [more appropriate] also added a x86 based addition which - uses RDTSC for high precision timing. - -- Updated demo/demo.c to remove MPI stuff [won't work anyways], made the tests run for 2 seconds each so its - not so insanely slow. Also made the output space delimited [and fixed up various errors] - -- Added logs directory, logs/graph.dem which will use gnuplot to make a series of PNG files - that go with the pre-made index.html. You have to build [via make timing] and run ltmtest first in the - root of the package. - -- Fixed a bug in mp_sub and mp_add where "-a - -a" or "-a + a" would produce -0 as the result [obviously invalid]. - -- Fixed a bug in mp_rshd. If the count == a.used it should zero/return [instead of shifting] - -- Fixed a "off-by-one" bug in mp_mul2d. The initial size check on alloc would be off by one if the residue - shifting caused a carry. - -- Fixed a bug where s_mp_mul_digs() would not call the Comba based routine if allowed. This made Barrett reduction - slower than it had to be. - -Mar 29th, 2003 -v0.16 -- Sped up mp_div by making normalization one shift call - -- Sped up mp_mul_2d/mp_div_2d by aliasing pointers :-) - -- Cleaned up mp_gcd to use the macros for odd/even detection - -- Added comments here and there, mostly there but occasionally here too. - -Mar 22nd, 2003 -v0.15 -- Added series of prime testing routines to lib - -- Fixed up etc/tune.c - -- Added DR reduction algorithm - -- Beefed up the manual more. - -- Fixed up demo/demo.c so it doesn't have so many warnings and it does the full series of - tests - -- Added "pre-gen" directory which will hold a "gen.pl"'ed copy of the entire lib [done at - zipup time so its always the latest] - -- Added conditional casts for C++ users [boo!] - -Mar 15th, 2003 -v0.14 -- Tons of manual updates - -- cleaned up the directory - -- added MSVC makefiles - -- source changes [that I don't recall] - -- Fixed up the lshd/rshd code to use pointer aliasing - -- Fixed up the mul_2d and div_2d to not call rshd/lshd unless needed - -- Fixed up etc/tune.c a tad - -- fixed up demo/demo.c to output comma-delimited results of timing - also fixed up timing demo to use a finer granularity for various functions - -- fixed up demo/demo.c testing to pause during testing so my Duron won't catch on fire - [stays around 31-35C during testing :-)] - -Feb 13th, 2003 -v0.13 -- tons of minor speed-ups in low level add, sub, mul_2 and div_2 which propagate - to other functions like mp_invmod, mp_div, etc... - -- Sped up mp_exptmod_fast by using new code to find R mod m [e.g. B^n mod m] - -- minor fixes - -Jan 17th, 2003 -v0.12 -- re-wrote the majority of the makefile so its more portable and will - install via "make install" on most *nix platforms - -- Re-packaged all the source as seperate files. Means the library a single - file packagage any more. Instead of just adding "bn.c" you have to add - libtommath.a - -- Renamed "bn.h" to "tommath.h" - -- Changes to the manual to reflect all of this - -- Used GNU Indent to clean up the source - -Jan 15th, 2003 -v0.11 -- More subtle fixes - -- Moved to gentoo linux [hurrah!] so made *nix specific fixes to the make process - -- Sped up the montgomery reduction code quite a bit - -- fixed up demo so when building timing for the x86 it assumes ELF format now - -Jan 9th, 2003 -v0.10 -- Pekka Riikonen suggested fixes to the radix conversion code. - -- Added baseline montgomery and comba montgomery reductions, sped up exptmods - [to a point, see bn.h for MONTGOMERY_EXPT_CUTOFF] - -Jan 6th, 2003 -v0.09 -- Updated the manual to reflect recent changes. :-) - -- Added Jacobi function (mp_jacobi) to supplement the number theory side of the lib - -- Added a Mersenne prime finder demo in ./etc/mersenne.c - -Jan 2nd, 2003 -v0.08 -- Sped up the multipliers by moving the inner loop variables into a smaller scope - -- Corrected a bunch of small "warnings" - -- Added more comments - -- Made "mtest" be able to use /dev/random, /dev/urandom or stdin for RNG data - -- Corrected some bugs where error messages were potentially ignored - -- add etc/pprime.c program which makes numbers which are provably prime. - -Jan 1st, 2003 -v0.07 -- Removed alot of heap operations from core functions to speed them up - -- Added a root finding function [and mp_sqrt macro like from MPI] - -- Added more to manual - -Dec 31st, 2002 -v0.06 -- Sped up the s_mp_add, s_mp_sub which inturn sped up mp_invmod, mp_exptmod, etc... - -- Cleaned up the header a bit more - -Dec 30th, 2002 -v0.05 -- Builds with MSVC out of the box - -- Fixed a bug in mp_invmod w.r.t. even moduli - -- Made mp_toradix and mp_read_radix use char instead of unsigned char arrays - -- Fixed up exptmod to use fewer multiplications - -- Fixed up mp_init_size to use only one heap operation - -- Note there is a slight "off-by-one" bug in the library somewhere - without the padding (see the source for comment) the library - crashes in libtomcrypt. Anyways a reasonable workaround is to pad the - numbers which will always correct it since as the numbers grow the padding - will still be beyond the end of the number - -- Added more to the manual - -Dec 29th, 2002 -v0.04 -- Fixed a memory leak in mp_to_unsigned_bin - -- optimized invmod code - -- Fixed bug in mp_div - -- use exchange instead of copy for results - -- added a bit more to the manual - -Dec 27th, 2002 -v0.03 -- Sped up s_mp_mul_high_digs by not computing the carries of the lower digits - -- Fixed a bug where mp_set_int wouldn't zero the value first and set the used member. - -- fixed a bug in s_mp_mul_high_digs where the limit placed on the result digits was not calculated properly - -- fixed bugs in add/sub/mul/sqr_mod functions where if the modulus and dest were the same it wouldn't work - -- fixed a bug in mp_mod and mp_mod_d concerning negative inputs - -- mp_mul_d didn't preserve sign - -- Many many many many fixes - -- Works in LibTomCrypt now :-) - -- Added iterations to the timing demos... more accurate. - -- Tom needs a job. - -Dec 26th, 2002 -v0.02 -- Fixed a few "slips" in the manual. This is "LibTomMath" afterall :-) - -- Added mp_cmp_mag, mp_neg, mp_abs and mp_radix_size that were missing. - -- Sped up the fast [comba] multipliers more [yahoo!] - -Dec 25th,2002 -v0.01 -- Initial release. Gimme a break. - -- Todo list, - add details to manual [e.g. algorithms] - more comments in code - example programs diff --git a/external/libtommath-0.42.0/demo/demo.c b/external/libtommath-0.42.0/demo/demo.c deleted file mode 100755 index 3e5663b..0000000 --- a/external/libtommath-0.42.0/demo/demo.c +++ /dev/null @@ -1,740 +0,0 @@ -#include - -#ifdef IOWNANATHLON -#include -#define SLEEP sleep(4) -#else -#define SLEEP -#endif - -#include "tommath.h" - -void ndraw(mp_int * a, char *name) -{ - char buf[16000]; - - printf("%s: ", name); - mp_toradix(a, buf, 10); - printf("%s\n", buf); -} - -static void draw(mp_int * a) -{ - ndraw(a, ""); -} - - -unsigned long lfsr = 0xAAAAAAAAUL; - -int lbit(void) -{ - if (lfsr & 0x80000000UL) { - lfsr = ((lfsr << 1) ^ 0x8000001BUL) & 0xFFFFFFFFUL; - return 1; - } else { - lfsr <<= 1; - return 0; - } -} - -int myrng(unsigned char *dst, int len, void *dat) -{ - int x; - - for (x = 0; x < len; x++) - dst[x] = rand() & 0xFF; - return len; -} - - - -char cmd[4096], buf[4096]; -int main(void) -{ - mp_int a, b, c, d, e, f; - unsigned long expt_n, add_n, sub_n, mul_n, div_n, sqr_n, mul2d_n, div2d_n, - gcd_n, lcm_n, inv_n, div2_n, mul2_n, add_d_n, sub_d_n, t; - unsigned rr; - int i, n, err, cnt, ix, old_kara_m, old_kara_s; - mp_digit mp; - - - mp_init(&a); - mp_init(&b); - mp_init(&c); - mp_init(&d); - mp_init(&e); - mp_init(&f); - - srand(time(NULL)); - -#if 0 - // test montgomery - printf("Testing montgomery...\n"); - for (i = 1; i < 10; i++) { - printf("Testing digit size: %d\n", i); - for (n = 0; n < 1000; n++) { - mp_rand(&a, i); - a.dp[0] |= 1; - - // let's see if R is right - mp_montgomery_calc_normalization(&b, &a); - mp_montgomery_setup(&a, &mp); - - // now test a random reduction - for (ix = 0; ix < 100; ix++) { - mp_rand(&c, 1 + abs(rand()) % (2*i)); - mp_copy(&c, &d); - mp_copy(&c, &e); - - mp_mod(&d, &a, &d); - mp_montgomery_reduce(&c, &a, mp); - mp_mulmod(&c, &b, &a, &c); - - if (mp_cmp(&c, &d) != MP_EQ) { -printf("d = e mod a, c = e MOD a\n"); -mp_todecimal(&a, buf); printf("a = %s\n", buf); -mp_todecimal(&e, buf); printf("e = %s\n", buf); -mp_todecimal(&d, buf); printf("d = %s\n", buf); -mp_todecimal(&c, buf); printf("c = %s\n", buf); -printf("compare no compare!\n"); exit(EXIT_FAILURE); } - } - } - } - printf("done\n"); - - // test mp_get_int - printf("Testing: mp_get_int\n"); - for (i = 0; i < 1000; ++i) { - t = ((unsigned long) rand() * rand() + 1) & 0xFFFFFFFF; - mp_set_int(&a, t); - if (t != mp_get_int(&a)) { - printf("mp_get_int() bad result!\n"); - return 1; - } - } - mp_set_int(&a, 0); - if (mp_get_int(&a) != 0) { - printf("mp_get_int() bad result!\n"); - return 1; - } - mp_set_int(&a, 0xffffffff); - if (mp_get_int(&a) != 0xffffffff) { - printf("mp_get_int() bad result!\n"); - return 1; - } - // test mp_sqrt - printf("Testing: mp_sqrt\n"); - for (i = 0; i < 1000; ++i) { - printf("%6d\r", i); - fflush(stdout); - n = (rand() & 15) + 1; - mp_rand(&a, n); - if (mp_sqrt(&a, &b) != MP_OKAY) { - printf("mp_sqrt() error!\n"); - return 1; - } - mp_n_root(&a, 2, &a); - if (mp_cmp_mag(&b, &a) != MP_EQ) { - printf("mp_sqrt() bad result!\n"); - return 1; - } - } - - printf("\nTesting: mp_is_square\n"); - for (i = 0; i < 1000; ++i) { - printf("%6d\r", i); - fflush(stdout); - - /* test mp_is_square false negatives */ - n = (rand() & 7) + 1; - mp_rand(&a, n); - mp_sqr(&a, &a); - if (mp_is_square(&a, &n) != MP_OKAY) { - printf("fn:mp_is_square() error!\n"); - return 1; - } - if (n == 0) { - printf("fn:mp_is_square() bad result!\n"); - return 1; - } - - /* test for false positives */ - mp_add_d(&a, 1, &a); - if (mp_is_square(&a, &n) != MP_OKAY) { - printf("fp:mp_is_square() error!\n"); - return 1; - } - if (n == 1) { - printf("fp:mp_is_square() bad result!\n"); - return 1; - } - - } - printf("\n\n"); - - /* test for size */ - for (ix = 10; ix < 128; ix++) { - printf("Testing (not safe-prime): %9d bits \r", ix); - fflush(stdout); - err = - mp_prime_random_ex(&a, 8, ix, - (rand() & 1) ? LTM_PRIME_2MSB_OFF : - LTM_PRIME_2MSB_ON, myrng, NULL); - if (err != MP_OKAY) { - printf("failed with err code %d\n", err); - return EXIT_FAILURE; - } - if (mp_count_bits(&a) != ix) { - printf("Prime is %d not %d bits!!!\n", mp_count_bits(&a), ix); - return EXIT_FAILURE; - } - } - - for (ix = 16; ix < 128; ix++) { - printf("Testing ( safe-prime): %9d bits \r", ix); - fflush(stdout); - err = - mp_prime_random_ex(&a, 8, ix, - ((rand() & 1) ? LTM_PRIME_2MSB_OFF : - LTM_PRIME_2MSB_ON) | LTM_PRIME_SAFE, myrng, - NULL); - if (err != MP_OKAY) { - printf("failed with err code %d\n", err); - return EXIT_FAILURE; - } - if (mp_count_bits(&a) != ix) { - printf("Prime is %d not %d bits!!!\n", mp_count_bits(&a), ix); - return EXIT_FAILURE; - } - /* let's see if it's really a safe prime */ - mp_sub_d(&a, 1, &a); - mp_div_2(&a, &a); - mp_prime_is_prime(&a, 8, &cnt); - if (cnt != MP_YES) { - printf("sub is not prime!\n"); - return EXIT_FAILURE; - } - } - - printf("\n\n"); - - mp_read_radix(&a, "123456", 10); - mp_toradix_n(&a, buf, 10, 3); - printf("a == %s\n", buf); - mp_toradix_n(&a, buf, 10, 4); - printf("a == %s\n", buf); - mp_toradix_n(&a, buf, 10, 30); - printf("a == %s\n", buf); - - -#if 0 - for (;;) { - fgets(buf, sizeof(buf), stdin); - mp_read_radix(&a, buf, 10); - mp_prime_next_prime(&a, 5, 1); - mp_toradix(&a, buf, 10); - printf("%s, %lu\n", buf, a.dp[0] & 3); - } -#endif - - /* test mp_cnt_lsb */ - printf("testing mp_cnt_lsb...\n"); - mp_set(&a, 1); - for (ix = 0; ix < 1024; ix++) { - if (mp_cnt_lsb(&a) != ix) { - printf("Failed at %d, %d\n", ix, mp_cnt_lsb(&a)); - return 0; - } - mp_mul_2(&a, &a); - } - -/* test mp_reduce_2k */ - printf("Testing mp_reduce_2k...\n"); - for (cnt = 3; cnt <= 128; ++cnt) { - mp_digit tmp; - - mp_2expt(&a, cnt); - mp_sub_d(&a, 2, &a); /* a = 2**cnt - 2 */ - - - printf("\nTesting %4d bits", cnt); - printf("(%d)", mp_reduce_is_2k(&a)); - mp_reduce_2k_setup(&a, &tmp); - printf("(%d)", tmp); - for (ix = 0; ix < 1000; ix++) { - if (!(ix & 127)) { - printf("."); - fflush(stdout); - } - mp_rand(&b, (cnt / DIGIT_BIT + 1) * 2); - mp_copy(&c, &b); - mp_mod(&c, &a, &c); - mp_reduce_2k(&b, &a, 2); - if (mp_cmp(&c, &b)) { - printf("FAILED\n"); - exit(0); - } - } - } - -/* test mp_div_3 */ - printf("Testing mp_div_3...\n"); - mp_set(&d, 3); - for (cnt = 0; cnt < 10000;) { - mp_digit r1, r2; - - if (!(++cnt & 127)) - printf("%9d\r", cnt); - mp_rand(&a, abs(rand()) % 128 + 1); - mp_div(&a, &d, &b, &e); - mp_div_3(&a, &c, &r2); - - if (mp_cmp(&b, &c) || mp_cmp_d(&e, r2)) { - printf("\n\nmp_div_3 => Failure\n"); - } - } - printf("\n\nPassed div_3 testing\n"); - -/* test the DR reduction */ - printf("testing mp_dr_reduce...\n"); - for (cnt = 2; cnt < 32; cnt++) { - printf("%d digit modulus\n", cnt); - mp_grow(&a, cnt); - mp_zero(&a); - for (ix = 1; ix < cnt; ix++) { - a.dp[ix] = MP_MASK; - } - a.used = cnt; - a.dp[0] = 3; - - mp_rand(&b, cnt - 1); - mp_copy(&b, &c); - - rr = 0; - do { - if (!(rr & 127)) { - printf("%9lu\r", rr); - fflush(stdout); - } - mp_sqr(&b, &b); - mp_add_d(&b, 1, &b); - mp_copy(&b, &c); - - mp_mod(&b, &a, &b); - mp_dr_reduce(&c, &a, (((mp_digit) 1) << DIGIT_BIT) - a.dp[0]); - - if (mp_cmp(&b, &c) != MP_EQ) { - printf("Failed on trial %lu\n", rr); - exit(-1); - - } - } while (++rr < 500); - printf("Passed DR test for %d digits\n", cnt); - } - -#endif - -/* test the mp_reduce_2k_l code */ -#if 0 -#if 0 -/* first load P with 2^1024 - 0x2A434 B9FDEC95 D8F9D550 FFFFFFFF FFFFFFFF */ - mp_2expt(&a, 1024); - mp_read_radix(&b, "2A434B9FDEC95D8F9D550FFFFFFFFFFFFFFFF", 16); - mp_sub(&a, &b, &a); -#elif 1 -/* p = 2^2048 - 0x1 00000000 00000000 00000000 00000000 4945DDBF 8EA2A91D 5776399B B83E188F */ - mp_2expt(&a, 2048); - mp_read_radix(&b, - "1000000000000000000000000000000004945DDBF8EA2A91D5776399BB83E188F", - 16); - mp_sub(&a, &b, &a); -#endif - - mp_todecimal(&a, buf); - printf("p==%s\n", buf); -/* now mp_reduce_is_2k_l() should return */ - if (mp_reduce_is_2k_l(&a) != 1) { - printf("mp_reduce_is_2k_l() return 0, should be 1\n"); - return EXIT_FAILURE; - } - mp_reduce_2k_setup_l(&a, &d); - /* now do a million square+1 to see if it varies */ - mp_rand(&b, 64); - mp_mod(&b, &a, &b); - mp_copy(&b, &c); - printf("testing mp_reduce_2k_l..."); - fflush(stdout); - for (cnt = 0; cnt < (1UL << 20); cnt++) { - mp_sqr(&b, &b); - mp_add_d(&b, 1, &b); - mp_reduce_2k_l(&b, &a, &d); - mp_sqr(&c, &c); - mp_add_d(&c, 1, &c); - mp_mod(&c, &a, &c); - if (mp_cmp(&b, &c) != MP_EQ) { - printf("mp_reduce_2k_l() failed at step %lu\n", cnt); - mp_tohex(&b, buf); - printf("b == %s\n", buf); - mp_tohex(&c, buf); - printf("c == %s\n", buf); - return EXIT_FAILURE; - } - } - printf("...Passed\n"); -#endif - - div2_n = mul2_n = inv_n = expt_n = lcm_n = gcd_n = add_n = - sub_n = mul_n = div_n = sqr_n = mul2d_n = div2d_n = cnt = add_d_n = - sub_d_n = 0; - - /* force KARA and TOOM to enable despite cutoffs */ - KARATSUBA_SQR_CUTOFF = KARATSUBA_MUL_CUTOFF = 8; - TOOM_SQR_CUTOFF = TOOM_MUL_CUTOFF = 16; - - for (;;) { - /* randomly clear and re-init one variable, this has the affect of triming the alloc space */ - switch (abs(rand()) % 7) { - case 0: - mp_clear(&a); - mp_init(&a); - break; - case 1: - mp_clear(&b); - mp_init(&b); - break; - case 2: - mp_clear(&c); - mp_init(&c); - break; - case 3: - mp_clear(&d); - mp_init(&d); - break; - case 4: - mp_clear(&e); - mp_init(&e); - break; - case 5: - mp_clear(&f); - mp_init(&f); - break; - case 6: - break; /* don't clear any */ - } - - - printf - ("%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu ", - add_n, sub_n, mul_n, div_n, sqr_n, mul2d_n, div2d_n, gcd_n, lcm_n, - expt_n, inv_n, div2_n, mul2_n, add_d_n, sub_d_n); - fgets(cmd, 4095, stdin); - cmd[strlen(cmd) - 1] = 0; - printf("%s ]\r", cmd); - fflush(stdout); - if (!strcmp(cmd, "mul2d")) { - ++mul2d_n; - fgets(buf, 4095, stdin); - mp_read_radix(&a, buf, 64); - fgets(buf, 4095, stdin); - sscanf(buf, "%d", &rr); - fgets(buf, 4095, stdin); - mp_read_radix(&b, buf, 64); - - mp_mul_2d(&a, rr, &a); - a.sign = b.sign; - if (mp_cmp(&a, &b) != MP_EQ) { - printf("mul2d failed, rr == %d\n", rr); - draw(&a); - draw(&b); - return 0; - } - } else if (!strcmp(cmd, "div2d")) { - ++div2d_n; - fgets(buf, 4095, stdin); - mp_read_radix(&a, buf, 64); - fgets(buf, 4095, stdin); - sscanf(buf, "%d", &rr); - fgets(buf, 4095, stdin); - mp_read_radix(&b, buf, 64); - - mp_div_2d(&a, rr, &a, &e); - a.sign = b.sign; - if (a.used == b.used && a.used == 0) { - a.sign = b.sign = MP_ZPOS; - } - if (mp_cmp(&a, &b) != MP_EQ) { - printf("div2d failed, rr == %d\n", rr); - draw(&a); - draw(&b); - return 0; - } - } else if (!strcmp(cmd, "add")) { - ++add_n; - fgets(buf, 4095, stdin); - mp_read_radix(&a, buf, 64); - fgets(buf, 4095, stdin); - mp_read_radix(&b, buf, 64); - fgets(buf, 4095, stdin); - mp_read_radix(&c, buf, 64); - mp_copy(&a, &d); - mp_add(&d, &b, &d); - if (mp_cmp(&c, &d) != MP_EQ) { - printf("add %lu failure!\n", add_n); - draw(&a); - draw(&b); - draw(&c); - draw(&d); - return 0; - } - - /* test the sign/unsigned storage functions */ - - rr = mp_signed_bin_size(&c); - mp_to_signed_bin(&c, (unsigned char *) cmd); - memset(cmd + rr, rand() & 255, sizeof(cmd) - rr); - mp_read_signed_bin(&d, (unsigned char *) cmd, rr); - if (mp_cmp(&c, &d) != MP_EQ) { - printf("mp_signed_bin failure!\n"); - draw(&c); - draw(&d); - return 0; - } - - - rr = mp_unsigned_bin_size(&c); - mp_to_unsigned_bin(&c, (unsigned char *) cmd); - memset(cmd + rr, rand() & 255, sizeof(cmd) - rr); - mp_read_unsigned_bin(&d, (unsigned char *) cmd, rr); - if (mp_cmp_mag(&c, &d) != MP_EQ) { - printf("mp_unsigned_bin failure!\n"); - draw(&c); - draw(&d); - return 0; - } - - } else if (!strcmp(cmd, "sub")) { - ++sub_n; - fgets(buf, 4095, stdin); - mp_read_radix(&a, buf, 64); - fgets(buf, 4095, stdin); - mp_read_radix(&b, buf, 64); - fgets(buf, 4095, stdin); - mp_read_radix(&c, buf, 64); - mp_copy(&a, &d); - mp_sub(&d, &b, &d); - if (mp_cmp(&c, &d) != MP_EQ) { - printf("sub %lu failure!\n", sub_n); - draw(&a); - draw(&b); - draw(&c); - draw(&d); - return 0; - } - } else if (!strcmp(cmd, "mul")) { - ++mul_n; - fgets(buf, 4095, stdin); - mp_read_radix(&a, buf, 64); - fgets(buf, 4095, stdin); - mp_read_radix(&b, buf, 64); - fgets(buf, 4095, stdin); - mp_read_radix(&c, buf, 64); - mp_copy(&a, &d); - mp_mul(&d, &b, &d); - if (mp_cmp(&c, &d) != MP_EQ) { - printf("mul %lu failure!\n", mul_n); - draw(&a); - draw(&b); - draw(&c); - draw(&d); - return 0; - } - } else if (!strcmp(cmd, "div")) { - ++div_n; - fgets(buf, 4095, stdin); - mp_read_radix(&a, buf, 64); - fgets(buf, 4095, stdin); - mp_read_radix(&b, buf, 64); - fgets(buf, 4095, stdin); - mp_read_radix(&c, buf, 64); - fgets(buf, 4095, stdin); - mp_read_radix(&d, buf, 64); - - mp_div(&a, &b, &e, &f); - if (mp_cmp(&c, &e) != MP_EQ || mp_cmp(&d, &f) != MP_EQ) { - printf("div %lu %d, %d, failure!\n", div_n, mp_cmp(&c, &e), - mp_cmp(&d, &f)); - draw(&a); - draw(&b); - draw(&c); - draw(&d); - draw(&e); - draw(&f); - return 0; - } - - } else if (!strcmp(cmd, "sqr")) { - ++sqr_n; - fgets(buf, 4095, stdin); - mp_read_radix(&a, buf, 64); - fgets(buf, 4095, stdin); - mp_read_radix(&b, buf, 64); - mp_copy(&a, &c); - mp_sqr(&c, &c); - if (mp_cmp(&b, &c) != MP_EQ) { - printf("sqr %lu failure!\n", sqr_n); - draw(&a); - draw(&b); - draw(&c); - return 0; - } - } else if (!strcmp(cmd, "gcd")) { - ++gcd_n; - fgets(buf, 4095, stdin); - mp_read_radix(&a, buf, 64); - fgets(buf, 4095, stdin); - mp_read_radix(&b, buf, 64); - fgets(buf, 4095, stdin); - mp_read_radix(&c, buf, 64); - mp_copy(&a, &d); - mp_gcd(&d, &b, &d); - d.sign = c.sign; - if (mp_cmp(&c, &d) != MP_EQ) { - printf("gcd %lu failure!\n", gcd_n); - draw(&a); - draw(&b); - draw(&c); - draw(&d); - return 0; - } - } else if (!strcmp(cmd, "lcm")) { - ++lcm_n; - fgets(buf, 4095, stdin); - mp_read_radix(&a, buf, 64); - fgets(buf, 4095, stdin); - mp_read_radix(&b, buf, 64); - fgets(buf, 4095, stdin); - mp_read_radix(&c, buf, 64); - mp_copy(&a, &d); - mp_lcm(&d, &b, &d); - d.sign = c.sign; - if (mp_cmp(&c, &d) != MP_EQ) { - printf("lcm %lu failure!\n", lcm_n); - draw(&a); - draw(&b); - draw(&c); - draw(&d); - return 0; - } - } else if (!strcmp(cmd, "expt")) { - ++expt_n; - fgets(buf, 4095, stdin); - mp_read_radix(&a, buf, 64); - fgets(buf, 4095, stdin); - mp_read_radix(&b, buf, 64); - fgets(buf, 4095, stdin); - mp_read_radix(&c, buf, 64); - fgets(buf, 4095, stdin); - mp_read_radix(&d, buf, 64); - mp_copy(&a, &e); - mp_exptmod(&e, &b, &c, &e); - if (mp_cmp(&d, &e) != MP_EQ) { - printf("expt %lu failure!\n", expt_n); - draw(&a); - draw(&b); - draw(&c); - draw(&d); - draw(&e); - return 0; - } - } else if (!strcmp(cmd, "invmod")) { - ++inv_n; - fgets(buf, 4095, stdin); - mp_read_radix(&a, buf, 64); - fgets(buf, 4095, stdin); - mp_read_radix(&b, buf, 64); - fgets(buf, 4095, stdin); - mp_read_radix(&c, buf, 64); - mp_invmod(&a, &b, &d); - mp_mulmod(&d, &a, &b, &e); - if (mp_cmp_d(&e, 1) != MP_EQ) { - printf("inv [wrong value from MPI?!] failure\n"); - draw(&a); - draw(&b); - draw(&c); - draw(&d); - mp_gcd(&a, &b, &e); - draw(&e); - return 0; - } - - } else if (!strcmp(cmd, "div2")) { - ++div2_n; - fgets(buf, 4095, stdin); - mp_read_radix(&a, buf, 64); - fgets(buf, 4095, stdin); - mp_read_radix(&b, buf, 64); - mp_div_2(&a, &c); - if (mp_cmp(&c, &b) != MP_EQ) { - printf("div_2 %lu failure\n", div2_n); - draw(&a); - draw(&b); - draw(&c); - return 0; - } - } else if (!strcmp(cmd, "mul2")) { - ++mul2_n; - fgets(buf, 4095, stdin); - mp_read_radix(&a, buf, 64); - fgets(buf, 4095, stdin); - mp_read_radix(&b, buf, 64); - mp_mul_2(&a, &c); - if (mp_cmp(&c, &b) != MP_EQ) { - printf("mul_2 %lu failure\n", mul2_n); - draw(&a); - draw(&b); - draw(&c); - return 0; - } - } else if (!strcmp(cmd, "add_d")) { - ++add_d_n; - fgets(buf, 4095, stdin); - mp_read_radix(&a, buf, 64); - fgets(buf, 4095, stdin); - sscanf(buf, "%d", &ix); - fgets(buf, 4095, stdin); - mp_read_radix(&b, buf, 64); - mp_add_d(&a, ix, &c); - if (mp_cmp(&b, &c) != MP_EQ) { - printf("add_d %lu failure\n", add_d_n); - draw(&a); - draw(&b); - draw(&c); - printf("d == %d\n", ix); - return 0; - } - } else if (!strcmp(cmd, "sub_d")) { - ++sub_d_n; - fgets(buf, 4095, stdin); - mp_read_radix(&a, buf, 64); - fgets(buf, 4095, stdin); - sscanf(buf, "%d", &ix); - fgets(buf, 4095, stdin); - mp_read_radix(&b, buf, 64); - mp_sub_d(&a, ix, &c); - if (mp_cmp(&b, &c) != MP_EQ) { - printf("sub_d %lu failure\n", sub_d_n); - draw(&a); - draw(&b); - draw(&c); - printf("d == %d\n", ix); - return 0; - } - } - } - return 0; -} - -/* $Source$ */ -/* $Revision: 0.36 $ */ -/* $Date: 2005-08-01 16:37:28 +0000 $ */ diff --git a/external/libtommath-0.42.0/demo/timing.c b/external/libtommath-0.42.0/demo/timing.c deleted file mode 100755 index 57bb6d4..0000000 --- a/external/libtommath-0.42.0/demo/timing.c +++ /dev/null @@ -1,319 +0,0 @@ -#include -#include - -ulong64 _tt; - -#ifdef IOWNANATHLON -#include -#define SLEEP sleep(4) -#else -#define SLEEP -#endif - - -void ndraw(mp_int * a, char *name) -{ - char buf[4096]; - - printf("%s: ", name); - mp_toradix(a, buf, 64); - printf("%s\n", buf); -} - -static void draw(mp_int * a) -{ - ndraw(a, ""); -} - - -unsigned long lfsr = 0xAAAAAAAAUL; - -int lbit(void) -{ - if (lfsr & 0x80000000UL) { - lfsr = ((lfsr << 1) ^ 0x8000001BUL) & 0xFFFFFFFFUL; - return 1; - } else { - lfsr <<= 1; - return 0; - } -} - -/* RDTSC from Scott Duplichan */ -static ulong64 TIMFUNC(void) -{ -#if defined __GNUC__ -#if defined(__i386__) || defined(__x86_64__) - unsigned long long a; - __asm__ __volatile__("rdtsc\nmovl %%eax,%0\nmovl %%edx,4+%0\n":: - "m"(a):"%eax", "%edx"); - return a; -#else /* gcc-IA64 version */ - unsigned long result; - __asm__ __volatile__("mov %0=ar.itc":"=r"(result)::"memory"); - - while (__builtin_expect((int) result == -1, 0)) - __asm__ __volatile__("mov %0=ar.itc":"=r"(result)::"memory"); - - return result; -#endif - - // Microsoft and Intel Windows compilers -#elif defined _M_IX86 - __asm rdtsc -#elif defined _M_AMD64 - return __rdtsc(); -#elif defined _M_IA64 -#if defined __INTEL_COMPILER -#include -#endif - return __getReg(3116); -#else -#error need rdtsc function for this build -#endif -} - -#define DO(x) x; x; -//#define DO4(x) DO2(x); DO2(x); -//#define DO8(x) DO4(x); DO4(x); -//#define DO(x) DO8(x); DO8(x); - -int main(void) -{ - ulong64 tt, gg, CLK_PER_SEC; - FILE *log, *logb, *logc, *logd; - mp_int a, b, c, d, e, f; - int n, cnt, ix, old_kara_m, old_kara_s; - unsigned rr; - - mp_init(&a); - mp_init(&b); - mp_init(&c); - mp_init(&d); - mp_init(&e); - mp_init(&f); - - srand(time(NULL)); - - - /* temp. turn off TOOM */ - TOOM_MUL_CUTOFF = TOOM_SQR_CUTOFF = 100000; - - CLK_PER_SEC = TIMFUNC(); - sleep(1); - CLK_PER_SEC = TIMFUNC() - CLK_PER_SEC; - - printf("CLK_PER_SEC == %llu\n", CLK_PER_SEC); - goto exptmod; - log = fopen("logs/add.log", "w"); - for (cnt = 8; cnt <= 128; cnt += 8) { - SLEEP; - mp_rand(&a, cnt); - mp_rand(&b, cnt); - rr = 0; - tt = -1; - do { - gg = TIMFUNC(); - DO(mp_add(&a, &b, &c)); - gg = (TIMFUNC() - gg) >> 1; - if (tt > gg) - tt = gg; - } while (++rr < 100000); - printf("Adding\t\t%4d-bit => %9llu/sec, %9llu cycles\n", - mp_count_bits(&a), CLK_PER_SEC / tt, tt); - fprintf(log, "%d %9llu\n", cnt * DIGIT_BIT, tt); - fflush(log); - } - fclose(log); - - log = fopen("logs/sub.log", "w"); - for (cnt = 8; cnt <= 128; cnt += 8) { - SLEEP; - mp_rand(&a, cnt); - mp_rand(&b, cnt); - rr = 0; - tt = -1; - do { - gg = TIMFUNC(); - DO(mp_sub(&a, &b, &c)); - gg = (TIMFUNC() - gg) >> 1; - if (tt > gg) - tt = gg; - } while (++rr < 100000); - - printf("Subtracting\t\t%4d-bit => %9llu/sec, %9llu cycles\n", - mp_count_bits(&a), CLK_PER_SEC / tt, tt); - fprintf(log, "%d %9llu\n", cnt * DIGIT_BIT, tt); - fflush(log); - } - fclose(log); - - /* do mult/square twice, first without karatsuba and second with */ - multtest: - old_kara_m = KARATSUBA_MUL_CUTOFF; - old_kara_s = KARATSUBA_SQR_CUTOFF; - for (ix = 0; ix < 2; ix++) { - printf("With%s Karatsuba\n", (ix == 0) ? "out" : ""); - - KARATSUBA_MUL_CUTOFF = (ix == 0) ? 9999 : old_kara_m; - KARATSUBA_SQR_CUTOFF = (ix == 0) ? 9999 : old_kara_s; - - log = fopen((ix == 0) ? "logs/mult.log" : "logs/mult_kara.log", "w"); - for (cnt = 4; cnt <= 10240 / DIGIT_BIT; cnt += 2) { - SLEEP; - mp_rand(&a, cnt); - mp_rand(&b, cnt); - rr = 0; - tt = -1; - do { - gg = TIMFUNC(); - DO(mp_mul(&a, &b, &c)); - gg = (TIMFUNC() - gg) >> 1; - if (tt > gg) - tt = gg; - } while (++rr < 100); - printf("Multiplying\t%4d-bit => %9llu/sec, %9llu cycles\n", - mp_count_bits(&a), CLK_PER_SEC / tt, tt); - fprintf(log, "%d %9llu\n", mp_count_bits(&a), tt); - fflush(log); - } - fclose(log); - - log = fopen((ix == 0) ? "logs/sqr.log" : "logs/sqr_kara.log", "w"); - for (cnt = 4; cnt <= 10240 / DIGIT_BIT; cnt += 2) { - SLEEP; - mp_rand(&a, cnt); - rr = 0; - tt = -1; - do { - gg = TIMFUNC(); - DO(mp_sqr(&a, &b)); - gg = (TIMFUNC() - gg) >> 1; - if (tt > gg) - tt = gg; - } while (++rr < 100); - printf("Squaring\t%4d-bit => %9llu/sec, %9llu cycles\n", - mp_count_bits(&a), CLK_PER_SEC / tt, tt); - fprintf(log, "%d %9llu\n", mp_count_bits(&a), tt); - fflush(log); - } - fclose(log); - - } - exptmod: - - { - char *primes[] = { - /* 2K large moduli */ - "179769313486231590772930519078902473361797697894230657273430081157732675805500963132708477322407536021120113879871393357658789768814416622492847430639474124377767893424865485276302219601246094119453082952085005768838150682342462881473913110540827237163350510684586239334100047359817950870678242457666208137217", - "32317006071311007300714876688669951960444102669715484032130345427524655138867890893197201411522913463688717960921898019494119559150490921095088152386448283120630877367300996091750197750389652106796057638384067568276792218642619756161838094338476170470581645852036305042887575891541065808607552399123930385521914333389668342420684974786564569494856176035326322058077805659331026192708460314150258592864177116725943603718461857357598351152301645904403697613233287231227125684710820209725157101726931323469678542580656697935045997268352998638099733077152121140120031150424541696791951097529546801429027668869927491725169", - "1044388881413152506691752710716624382579964249047383780384233483283953907971557456848826811934997558340890106714439262837987573438185793607263236087851365277945956976543709998340361590134383718314428070011855946226376318839397712745672334684344586617496807908705803704071284048740118609114467977783598029006686938976881787785946905630190260940599579453432823469303026696443059025015972399867714215541693835559885291486318237914434496734087811872639496475100189041349008417061675093668333850551032972088269550769983616369411933015213796825837188091833656751221318492846368125550225998300412344784862595674492194617023806505913245610825731835380087608622102834270197698202313169017678006675195485079921636419370285375124784014907159135459982790513399611551794271106831134090584272884279791554849782954323534517065223269061394905987693002122963395687782878948440616007412945674919823050571642377154816321380631045902916136926708342856440730447899971901781465763473223850267253059899795996090799469201774624817718449867455659250178329070473119433165550807568221846571746373296884912819520317457002440926616910874148385078411929804522981857338977648103126085902995208257421855249796721729039744118165938433694823325696642096892124547425283", - /* 2K moduli mersenne primes */ - "6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151", - "531137992816767098689588206552468627329593117727031923199444138200403559860852242739162502265229285668889329486246501015346579337652707239409519978766587351943831270835393219031728127", - "10407932194664399081925240327364085538615262247266704805319112350403608059673360298012239441732324184842421613954281007791383566248323464908139906605677320762924129509389220345773183349661583550472959420547689811211693677147548478866962501384438260291732348885311160828538416585028255604666224831890918801847068222203140521026698435488732958028878050869736186900714720710555703168729087", - "1475979915214180235084898622737381736312066145333169775147771216478570297878078949377407337049389289382748507531496480477281264838760259191814463365330269540496961201113430156902396093989090226259326935025281409614983499388222831448598601834318536230923772641390209490231836446899608210795482963763094236630945410832793769905399982457186322944729636418890623372171723742105636440368218459649632948538696905872650486914434637457507280441823676813517852099348660847172579408422316678097670224011990280170474894487426924742108823536808485072502240519452587542875349976558572670229633962575212637477897785501552646522609988869914013540483809865681250419497686697771007", - "259117086013202627776246767922441530941818887553125427303974923161874019266586362086201209516800483406550695241733194177441689509238807017410377709597512042313066624082916353517952311186154862265604547691127595848775610568757931191017711408826252153849035830401185072116424747461823031471398340229288074545677907941037288235820705892351068433882986888616658650280927692080339605869308790500409503709875902119018371991620994002568935113136548829739112656797303241986517250116412703509705427773477972349821676443446668383119322540099648994051790241624056519054483690809616061625743042361721863339415852426431208737266591962061753535748892894599629195183082621860853400937932839420261866586142503251450773096274235376822938649407127700846077124211823080804139298087057504713825264571448379371125032081826126566649084251699453951887789613650248405739378594599444335231188280123660406262468609212150349937584782292237144339628858485938215738821232393687046160677362909315071", - "190797007524439073807468042969529173669356994749940177394741882673528979787005053706368049835514900244303495954950709725762186311224148828811920216904542206960744666169364221195289538436845390250168663932838805192055137154390912666527533007309292687539092257043362517857366624699975402375462954490293259233303137330643531556539739921926201438606439020075174723029056838272505051571967594608350063404495977660656269020823960825567012344189908927956646011998057988548630107637380993519826582389781888135705408653045219655801758081251164080554609057468028203308718724654081055323215860189611391296030471108443146745671967766308925858547271507311563765171008318248647110097614890313562856541784154881743146033909602737947385055355960331855614540900081456378659068370317267696980001187750995491090350108417050917991562167972281070161305972518044872048331306383715094854938415738549894606070722584737978176686422134354526989443028353644037187375385397838259511833166416134323695660367676897722287918773420968982326089026150031515424165462111337527431154890666327374921446276833564519776797633875503548665093914556482031482248883127023777039667707976559857333357013727342079099064400455741830654320379350833236245819348824064783585692924881021978332974949906122664421376034687815350484991", - - /* DR moduli */ - "14059105607947488696282932836518693308967803494693489478439861164411992439598399594747002144074658928593502845729752797260025831423419686528151609940203368612079", - "101745825697019260773923519755878567461315282017759829107608914364075275235254395622580447400994175578963163918967182013639660669771108475957692810857098847138903161308502419410142185759152435680068435915159402496058513611411688900243039", - "736335108039604595805923406147184530889923370574768772191969612422073040099331944991573923112581267542507986451953227192970402893063850485730703075899286013451337291468249027691733891486704001513279827771740183629161065194874727962517148100775228363421083691764065477590823919364012917984605619526140821797602431", - "38564998830736521417281865696453025806593491967131023221754800625044118265468851210705360385717536794615180260494208076605798671660719333199513807806252394423283413430106003596332513246682903994829528690198205120921557533726473585751382193953592127439965050261476810842071573684505878854588706623484573925925903505747545471088867712185004135201289273405614415899438276535626346098904241020877974002916168099951885406379295536200413493190419727789712076165162175783", - "542189391331696172661670440619180536749994166415993334151601745392193484590296600979602378676624808129613777993466242203025054573692562689251250471628358318743978285860720148446448885701001277560572526947619392551574490839286458454994488665744991822837769918095117129546414124448777033941223565831420390846864429504774477949153794689948747680362212954278693335653935890352619041936727463717926744868338358149568368643403037768649616778526013610493696186055899318268339432671541328195724261329606699831016666359440874843103020666106568222401047720269951530296879490444224546654729111504346660859907296364097126834834235287147", - "1487259134814709264092032648525971038895865645148901180585340454985524155135260217788758027400478312256339496385275012465661575576202252063145698732079880294664220579764848767704076761853197216563262660046602703973050798218246170835962005598561669706844469447435461092542265792444947706769615695252256130901271870341005768912974433684521436211263358097522726462083917939091760026658925757076733484173202927141441492573799914240222628795405623953109131594523623353044898339481494120112723445689647986475279242446083151413667587008191682564376412347964146113898565886683139407005941383669325997475076910488086663256335689181157957571445067490187939553165903773554290260531009121879044170766615232300936675369451260747671432073394867530820527479172464106442450727640226503746586340279816318821395210726268291535648506190714616083163403189943334431056876038286530365757187367147446004855912033137386225053275419626102417236133948503", - "1095121115716677802856811290392395128588168592409109494900178008967955253005183831872715423151551999734857184538199864469605657805519106717529655044054833197687459782636297255219742994736751541815269727940751860670268774903340296040006114013971309257028332849679096824800250742691718610670812374272414086863715763724622797509437062518082383056050144624962776302147890521249477060215148275163688301275847155316042279405557632639366066847442861422164832655874655824221577849928863023018366835675399949740429332468186340518172487073360822220449055340582568461568645259954873303616953776393853174845132081121976327462740354930744487429617202585015510744298530101547706821590188733515880733527449780963163909830077616357506845523215289297624086914545378511082534229620116563260168494523906566709418166011112754529766183554579321224940951177394088465596712620076240067370589036924024728375076210477267488679008016579588696191194060127319035195370137160936882402244399699172017835144537488486396906144217720028992863941288217185353914991583400421682751000603596655790990815525126154394344641336397793791497068253936771017031980867706707490224041075826337383538651825493679503771934836094655802776331664261631740148281763487765852746577808019633679", - - /* generic unrestricted moduli */ - "17933601194860113372237070562165128350027320072176844226673287945873370751245439587792371960615073855669274087805055507977323024886880985062002853331424203", - "2893527720709661239493896562339544088620375736490408468011883030469939904368086092336458298221245707898933583190713188177399401852627749210994595974791782790253946539043962213027074922559572312141181787434278708783207966459019479487", - "347743159439876626079252796797422223177535447388206607607181663903045907591201940478223621722118173270898487582987137708656414344685816179420855160986340457973820182883508387588163122354089264395604796675278966117567294812714812796820596564876450716066283126720010859041484786529056457896367683122960411136319", - "47266428956356393164697365098120418976400602706072312735924071745438532218237979333351774907308168340693326687317443721193266215155735814510792148768576498491199122744351399489453533553203833318691678263241941706256996197460424029012419012634671862283532342656309677173602509498417976091509154360039893165037637034737020327399910409885798185771003505320583967737293415979917317338985837385734747478364242020380416892056650841470869294527543597349250299539682430605173321029026555546832473048600327036845781970289288898317888427517364945316709081173840186150794397479045034008257793436817683392375274635794835245695887", - "436463808505957768574894870394349739623346440601945961161254440072143298152040105676491048248110146278752857839930515766167441407021501229924721335644557342265864606569000117714935185566842453630868849121480179691838399545644365571106757731317371758557990781880691336695584799313313687287468894148823761785582982549586183756806449017542622267874275103877481475534991201849912222670102069951687572917937634467778042874315463238062009202992087620963771759666448266532858079402669920025224220613419441069718482837399612644978839925207109870840278194042158748845445131729137117098529028886770063736487420613144045836803985635654192482395882603511950547826439092832800532152534003936926017612446606135655146445620623395788978726744728503058670046885876251527122350275750995227", - "11424167473351836398078306042624362277956429440521137061889702611766348760692206243140413411077394583180726863277012016602279290144126785129569474909173584789822341986742719230331946072730319555984484911716797058875905400999504305877245849119687509023232790273637466821052576859232452982061831009770786031785669030271542286603956118755585683996118896215213488875253101894663403069677745948305893849505434201763745232895780711972432011344857521691017896316861403206449421332243658855453435784006517202894181640562433575390821384210960117518650374602256601091379644034244332285065935413233557998331562749140202965844219336298970011513882564935538704289446968322281451907487362046511461221329799897350993370560697505809686438782036235372137015731304779072430260986460269894522159103008260495503005267165927542949439526272736586626709581721032189532726389643625590680105784844246152702670169304203783072275089194754889511973916207", - "1214855636816562637502584060163403830270705000634713483015101384881871978446801224798536155406895823305035467591632531067547890948695117172076954220727075688048751022421198712032848890056357845974246560748347918630050853933697792254955890439720297560693579400297062396904306270145886830719309296352765295712183040773146419022875165382778007040109957609739589875590885701126197906063620133954893216612678838507540777138437797705602453719559017633986486649523611975865005712371194067612263330335590526176087004421363598470302731349138773205901447704682181517904064735636518462452242791676541725292378925568296858010151852326316777511935037531017413910506921922450666933202278489024521263798482237150056835746454842662048692127173834433089016107854491097456725016327709663199738238442164843147132789153725513257167915555162094970853584447993125488607696008169807374736711297007473812256272245489405898470297178738029484459690836250560495461579533254473316340608217876781986188705928270735695752830825527963838355419762516246028680280988020401914551825487349990306976304093109384451438813251211051597392127491464898797406789175453067960072008590614886532333015881171367104445044718144312416815712216611576221546455968770801413440778423979", - NULL - }; - log = fopen("logs/expt.log", "w"); - logb = fopen("logs/expt_dr.log", "w"); - logc = fopen("logs/expt_2k.log", "w"); - logd = fopen("logs/expt_2kl.log", "w"); - for (n = 0; primes[n]; n++) { - SLEEP; - mp_read_radix(&a, primes[n], 10); - mp_zero(&b); - for (rr = 0; rr < (unsigned) mp_count_bits(&a); rr++) { - mp_mul_2(&b, &b); - b.dp[0] |= lbit(); - b.used += 1; - } - mp_sub_d(&a, 1, &c); - mp_mod(&b, &c, &b); - mp_set(&c, 3); - rr = 0; - tt = -1; - do { - gg = TIMFUNC(); - DO(mp_exptmod(&c, &b, &a, &d)); - gg = (TIMFUNC() - gg) >> 1; - if (tt > gg) - tt = gg; - } while (++rr < 10); - mp_sub_d(&a, 1, &e); - mp_sub(&e, &b, &b); - mp_exptmod(&c, &b, &a, &e); /* c^(p-1-b) mod a */ - mp_mulmod(&e, &d, &a, &d); /* c^b * c^(p-1-b) == c^p-1 == 1 */ - if (mp_cmp_d(&d, 1)) { - printf("Different (%d)!!!\n", mp_count_bits(&a)); - draw(&d); - exit(0); - } - printf("Exponentiating\t%4d-bit => %9llu/sec, %9llu cycles\n", - mp_count_bits(&a), CLK_PER_SEC / tt, tt); - fprintf(n < 4 ? logd : (n < 9) ? logc : (n < 16) ? logb : log, - "%d %9llu\n", mp_count_bits(&a), tt); - } - } - fclose(log); - fclose(logb); - fclose(logc); - fclose(logd); - - log = fopen("logs/invmod.log", "w"); - for (cnt = 4; cnt <= 128; cnt += 4) { - SLEEP; - mp_rand(&a, cnt); - mp_rand(&b, cnt); - - do { - mp_add_d(&b, 1, &b); - mp_gcd(&a, &b, &c); - } while (mp_cmp_d(&c, 1) != MP_EQ); - - rr = 0; - tt = -1; - do { - gg = TIMFUNC(); - DO(mp_invmod(&b, &a, &c)); - gg = (TIMFUNC() - gg) >> 1; - if (tt > gg) - tt = gg; - } while (++rr < 1000); - mp_mulmod(&b, &c, &a, &d); - if (mp_cmp_d(&d, 1) != MP_EQ) { - printf("Failed to invert\n"); - return 0; - } - printf("Inverting mod\t%4d-bit => %9llu/sec, %9llu cycles\n", - mp_count_bits(&a), CLK_PER_SEC / tt, tt); - fprintf(log, "%d %9llu\n", cnt * DIGIT_BIT, tt); - } - fclose(log); - - return 0; -} - -/* $Source$ */ -/* $Revision: 0.36 $ */ -/* $Date: 2005-08-01 16:37:28 +0000 $ */ diff --git a/external/libtommath-0.42.0/dep.pl b/external/libtommath-0.42.0/dep.pl deleted file mode 100755 index c39e27e..0000000 --- a/external/libtommath-0.42.0/dep.pl +++ /dev/null @@ -1,123 +0,0 @@ -#!/usr/bin/perl -# -# Walk through source, add labels and make classes -# -#use strict; - -my %deplist; - -#open class file and write preamble -open(CLASS, ">tommath_class.h") or die "Couldn't open tommath_class.h for writing\n"; -print CLASS "#if !(defined(LTM1) && defined(LTM2) && defined(LTM3))\n#if defined(LTM2)\n#define LTM3\n#endif\n#if defined(LTM1)\n#define LTM2\n#endif\n#define LTM1\n\n#if defined(LTM_ALL)\n"; - -foreach my $filename (glob "bn*.c") { - my $define = $filename; - -print "Processing $filename\n"; - - # convert filename to upper case so we can use it as a define - $define =~ tr/[a-z]/[A-Z]/; - $define =~ tr/\./_/; - print CLASS "#define $define\n"; - - # now copy text and apply #ifdef as required - my $apply = 0; - open(SRC, "<$filename"); - open(OUT, ">tmp"); - - # first line will be the #ifdef - my $line = ; - if ($line =~ /include/) { - print OUT $line; - } else { - print OUT "#include \n#ifdef $define\n$line"; - $apply = 1; - } - while () { - if (!($_ =~ /tommath\.h/)) { - print OUT $_; - } - } - if ($apply == 1) { - print OUT "#endif\n"; - } - close SRC; - close OUT; - - unlink($filename); - rename("tmp", $filename); -} -print CLASS "#endif\n\n"; - -# now do classes - -foreach my $filename (glob "bn*.c") { - open(SRC, "<$filename") or die "Can't open source file!\n"; - - # convert filename to upper case so we can use it as a define - $filename =~ tr/[a-z]/[A-Z]/; - $filename =~ tr/\./_/; - - print CLASS "#if defined($filename)\n"; - my $list = $filename; - - # scan for mp_* and make classes - while () { - my $line = $_; - while ($line =~ m/(fast_)*(s_)*mp\_[a-z_0-9]*/) { - $line = $'; - # now $& is the match, we want to skip over LTM keywords like - # mp_int, mp_word, mp_digit - if (!($& eq "mp_digit") && !($& eq "mp_word") && !($& eq "mp_int")) { - my $a = $&; - $a =~ tr/[a-z]/[A-Z]/; - $a = "BN_" . $a . "_C"; - if (!($list =~ /$a/)) { - print CLASS " #define $a\n"; - } - $list = $list . "," . $a; - } - } - } - @deplist{$filename} = $list; - - print CLASS "#endif\n\n"; - close SRC; -} - -print CLASS "#ifdef LTM3\n#define LTM_LAST\n#endif\n#include \n#include \n#else\n#define LTM_LAST\n#endif\n"; -close CLASS; - -#now let's make a cool call graph... - -open(OUT,">callgraph.txt"); -$indent = 0; -foreach (keys %deplist) { - $list = ""; - draw_func(@deplist{$_}); - print OUT "\n\n"; -} -close(OUT); - -sub draw_func() -{ - my @funcs = split(",", $_[0]); - if ($list =~ /@funcs[0]/) { - return; - } else { - $list = $list . @funcs[0]; - } - if ($indent == 0) { } - elsif ($indent >= 1) { print OUT "| " x ($indent - 1) . "+--->"; } - print OUT @funcs[0] . "\n"; - shift @funcs; - my $temp = $list; - foreach my $i (@funcs) { - ++$indent; - draw_func(@deplist{$i}); - --$indent; - } - $list = $temp; -} - - diff --git a/external/libtommath-0.42.0/etc/2kprime.1 b/external/libtommath-0.42.0/etc/2kprime.1 deleted file mode 100755 index c41ded1..0000000 --- a/external/libtommath-0.42.0/etc/2kprime.1 +++ /dev/null @@ -1,2 +0,0 @@ -256-bits (k = 36113) = 115792089237316195423570985008687907853269984665640564039457584007913129603823 -512-bits (k = 38117) = 13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006045979 diff --git a/external/libtommath-0.42.0/etc/2kprime.c b/external/libtommath-0.42.0/etc/2kprime.c deleted file mode 100755 index fff4825..0000000 --- a/external/libtommath-0.42.0/etc/2kprime.c +++ /dev/null @@ -1,84 +0,0 @@ -/* Makes safe primes of a 2k nature */ -#include -#include - -int sizes[] = {256, 512, 768, 1024, 1536, 2048, 3072, 4096}; - -int main(void) -{ - char buf[2000]; - int x, y; - mp_int q, p; - FILE *out; - clock_t t1; - mp_digit z; - - mp_init_multi(&q, &p, NULL); - - out = fopen("2kprime.1", "w"); - for (x = 0; x < (int)(sizeof(sizes) / sizeof(sizes[0])); x++) { - top: - mp_2expt(&q, sizes[x]); - mp_add_d(&q, 3, &q); - z = -3; - - t1 = clock(); - for(;;) { - mp_sub_d(&q, 4, &q); - z += 4; - - if (z > MP_MASK) { - printf("No primes of size %d found\n", sizes[x]); - break; - } - - if (clock() - t1 > CLOCKS_PER_SEC) { - printf("."); fflush(stdout); -// sleep((clock() - t1 + CLOCKS_PER_SEC/2)/CLOCKS_PER_SEC); - t1 = clock(); - } - - /* quick test on q */ - mp_prime_is_prime(&q, 1, &y); - if (y == 0) { - continue; - } - - /* find (q-1)/2 */ - mp_sub_d(&q, 1, &p); - mp_div_2(&p, &p); - mp_prime_is_prime(&p, 3, &y); - if (y == 0) { - continue; - } - - /* test on q */ - mp_prime_is_prime(&q, 3, &y); - if (y == 0) { - continue; - } - - break; - } - - if (y == 0) { - ++sizes[x]; - goto top; - } - - mp_toradix(&q, buf, 10); - printf("\n\n%d-bits (k = %lu) = %s\n", sizes[x], z, buf); - fprintf(out, "%d-bits (k = %lu) = %s\n", sizes[x], z, buf); fflush(out); - } - - return 0; -} - - - - - - -/* $Source$ */ -/* $Revision: 0.36 $ */ -/* $Date: 2005-08-01 16:37:28 +0000 $ */ diff --git a/external/libtommath-0.42.0/etc/drprime.c b/external/libtommath-0.42.0/etc/drprime.c deleted file mode 100755 index ea40bd3..0000000 --- a/external/libtommath-0.42.0/etc/drprime.c +++ /dev/null @@ -1,64 +0,0 @@ -/* Makes safe primes of a DR nature */ -#include - -int sizes[] = { 1+256/DIGIT_BIT, 1+512/DIGIT_BIT, 1+768/DIGIT_BIT, 1+1024/DIGIT_BIT, 1+2048/DIGIT_BIT, 1+4096/DIGIT_BIT }; -int main(void) -{ - int res, x, y; - char buf[4096]; - FILE *out; - mp_int a, b; - - mp_init(&a); - mp_init(&b); - - out = fopen("drprimes.txt", "w"); - for (x = 0; x < (int)(sizeof(sizes)/sizeof(sizes[0])); x++) { - top: - printf("Seeking a %d-bit safe prime\n", sizes[x] * DIGIT_BIT); - mp_grow(&a, sizes[x]); - mp_zero(&a); - for (y = 1; y < sizes[x]; y++) { - a.dp[y] = MP_MASK; - } - - /* make a DR modulus */ - a.dp[0] = -1; - a.used = sizes[x]; - - /* now loop */ - res = 0; - for (;;) { - a.dp[0] += 4; - if (a.dp[0] >= MP_MASK) break; - mp_prime_is_prime(&a, 1, &res); - if (res == 0) continue; - printf("."); fflush(stdout); - mp_sub_d(&a, 1, &b); - mp_div_2(&b, &b); - mp_prime_is_prime(&b, 3, &res); - if (res == 0) continue; - mp_prime_is_prime(&a, 3, &res); - if (res == 1) break; - } - - if (res != 1) { - printf("Error not DR modulus\n"); sizes[x] += 1; goto top; - } else { - mp_toradix(&a, buf, 10); - printf("\n\np == %s\n\n", buf); - fprintf(out, "%d-bit prime:\np == %s\n\n", mp_count_bits(&a), buf); fflush(out); - } - } - fclose(out); - - mp_clear(&a); - mp_clear(&b); - - return 0; -} - - -/* $Source$ */ -/* $Revision: 0.36 $ */ -/* $Date: 2005-08-01 16:37:28 +0000 $ */ diff --git a/external/libtommath-0.42.0/etc/drprimes.28 b/external/libtommath-0.42.0/etc/drprimes.28 deleted file mode 100755 index 9d438ad..0000000 --- a/external/libtommath-0.42.0/etc/drprimes.28 +++ /dev/null @@ -1,25 +0,0 @@ -DR safe primes for 28-bit digits. - -224-bit prime: -p == 26959946667150639794667015087019630673637144422540572481103341844143 - -532-bit prime: -p == 14059105607947488696282932836518693308967803494693489478439861164411992439598399594747002144074658928593502845729752797260025831423419686528151609940203368691747 - -784-bit prime: -p == 101745825697019260773923519755878567461315282017759829107608914364075275235254395622580447400994175578963163918967182013639660669771108475957692810857098847138903161308502419410142185759152435680068435915159402496058513611411688900243039 - -1036-bit prime: -p == 736335108039604595805923406147184530889923370574768772191969612422073040099331944991573923112581267542507986451953227192970402893063850485730703075899286013451337291468249027691733891486704001513279827771740183629161065194874727962517148100775228363421083691764065477590823919364012917984605619526140821798437127 - -1540-bit prime: -p == 38564998830736521417281865696453025806593491967131023221754800625044118265468851210705360385717536794615180260494208076605798671660719333199513807806252394423283413430106003596332513246682903994829528690198205120921557533726473585751382193953592127439965050261476810842071573684505878854588706623484573925925903505747545471088867712185004135201289273405614415899438276535626346098904241020877974002916168099951885406379295536200413493190419727789712076165162175783 - -2072-bit prime: -p == 542189391331696172661670440619180536749994166415993334151601745392193484590296600979602378676624808129613777993466242203025054573692562689251250471628358318743978285860720148446448885701001277560572526947619392551574490839286458454994488665744991822837769918095117129546414124448777033941223565831420390846864429504774477949153794689948747680362212954278693335653935890352619041936727463717926744868338358149568368643403037768649616778526013610493696186055899318268339432671541328195724261329606699831016666359440874843103020666106568222401047720269951530296879490444224546654729111504346660859907296364097126834834235287147 - -3080-bit prime: -p == 1487259134814709264092032648525971038895865645148901180585340454985524155135260217788758027400478312256339496385275012465661575576202252063145698732079880294664220579764848767704076761853197216563262660046602703973050798218246170835962005598561669706844469447435461092542265792444947706769615695252256130901271870341005768912974433684521436211263358097522726462083917939091760026658925757076733484173202927141441492573799914240222628795405623953109131594523623353044898339481494120112723445689647986475279242446083151413667587008191682564376412347964146113898565886683139407005941383669325997475076910488086663256335689181157957571445067490187939553165903773554290260531009121879044170766615232300936675369451260747671432073394867530820527479172464106442450727640226503746586340279816318821395210726268291535648506190714616083163403189943334431056876038286530365757187367147446004855912033137386225053275419626102417236133948503 - -4116-bit prime: -p == 1095121115716677802856811290392395128588168592409109494900178008967955253005183831872715423151551999734857184538199864469605657805519106717529655044054833197687459782636297255219742994736751541815269727940751860670268774903340296040006114013971309257028332849679096824800250742691718610670812374272414086863715763724622797509437062518082383056050144624962776302147890521249477060215148275163688301275847155316042279405557632639366066847442861422164832655874655824221577849928863023018366835675399949740429332468186340518172487073360822220449055340582568461568645259954873303616953776393853174845132081121976327462740354930744487429617202585015510744298530101547706821590188733515880733527449780963163909830077616357506845523215289297624086914545378511082534229620116563260168494523906566709418166011112754529766183554579321224940951177394088465596712620076240067370589036924024728375076210477267488679008016579588696191194060127319035195370137160936882402244399699172017835144537488486396906144217720028992863941288217185353914991583400421682751000603596655790990815525126154394344641336397793791497068253936771017031980867706707490224041075826337383538651825493679503771934836094655802776331664261631740148281763487765852746577808019633679 diff --git a/external/libtommath-0.42.0/etc/drprimes.txt b/external/libtommath-0.42.0/etc/drprimes.txt deleted file mode 100755 index 7c97f67..0000000 --- a/external/libtommath-0.42.0/etc/drprimes.txt +++ /dev/null @@ -1,9 +0,0 @@ -300-bit prime: -p == 2037035976334486086268445688409378161051468393665936250636140449354381298610415201576637819 - -540-bit prime: -p == 3599131035634557106248430806148785487095757694641533306480604458089470064537190296255232548883112685719936728506816716098566612844395439751206810991770626477344739 - -780-bit prime: -p == 6359114106063703798370219984742410466332205126109989319225557147754704702203399726411277962562135973685197744935448875852478791860694279747355800678568677946181447581781401213133886609947027230004277244697462656003655947791725966271167 - diff --git a/external/libtommath-0.42.0/etc/makefile b/external/libtommath-0.42.0/etc/makefile deleted file mode 100755 index 99154d8..0000000 --- a/external/libtommath-0.42.0/etc/makefile +++ /dev/null @@ -1,50 +0,0 @@ -CFLAGS += -Wall -W -Wshadow -O3 -fomit-frame-pointer -funroll-loops -I../ - -# default lib name (requires install with root) -# LIBNAME=-ltommath - -# libname when you can't install the lib with install -LIBNAME=../libtommath.a - -#provable primes -pprime: pprime.o - $(CC) pprime.o $(LIBNAME) -o pprime - -# portable [well requires clock()] tuning app -tune: tune.o - $(CC) tune.o $(LIBNAME) -o tune - -# same app but using RDTSC for higher precision [requires 80586+], coff based gcc installs [e.g. ming, cygwin, djgpp] -tune86: tune.c - nasm -f coff timer.asm - $(CC) -DX86_TIMER $(CFLAGS) tune.c timer.o $(LIBNAME) -o tune86 - -# for cygwin -tune86c: tune.c - nasm -f gnuwin32 timer.asm - $(CC) -DX86_TIMER $(CFLAGS) tune.c timer.o $(LIBNAME) -o tune86 - -#make tune86 for linux or any ELF format -tune86l: tune.c - nasm -f elf -DUSE_ELF timer.asm - $(CC) -DX86_TIMER $(CFLAGS) tune.c timer.o $(LIBNAME) -o tune86l - -# spits out mersenne primes -mersenne: mersenne.o - $(CC) mersenne.o $(LIBNAME) -o mersenne - -# fines DR safe primes for the given config -drprime: drprime.o - $(CC) drprime.o $(LIBNAME) -o drprime - -# fines 2k safe primes for the given config -2kprime: 2kprime.o - $(CC) 2kprime.o $(LIBNAME) -o 2kprime - -mont: mont.o - $(CC) mont.o $(LIBNAME) -o mont - - -clean: - rm -f *.log *.o *.obj *.exe pprime tune mersenne drprime tune86 tune86l mont 2kprime pprime.dat \ - *.da *.dyn *.dpi *~ diff --git a/external/libtommath-0.42.0/etc/makefile.icc b/external/libtommath-0.42.0/etc/makefile.icc deleted file mode 100755 index 8a1ffff..0000000 --- a/external/libtommath-0.42.0/etc/makefile.icc +++ /dev/null @@ -1,67 +0,0 @@ -CC = icc - -CFLAGS += -I../ - -# optimize for SPEED -# -# -mcpu= can be pentium, pentiumpro (covers PII through PIII) or pentium4 -# -ax? specifies make code specifically for ? but compatible with IA-32 -# -x? specifies compile solely for ? [not specifically IA-32 compatible] -# -# where ? is -# K - PIII -# W - first P4 [Williamette] -# N - P4 Northwood -# P - P4 Prescott -# B - Blend of P4 and PM [mobile] -# -# Default to just generic max opts -CFLAGS += -O3 -xP -ip - -# default lib name (requires install with root) -# LIBNAME=-ltommath - -# libname when you can't install the lib with install -LIBNAME=../libtommath.a - -#provable primes -pprime: pprime.o - $(CC) pprime.o $(LIBNAME) -o pprime - -# portable [well requires clock()] tuning app -tune: tune.o - $(CC) tune.o $(LIBNAME) -o tune - -# same app but using RDTSC for higher precision [requires 80586+], coff based gcc installs [e.g. ming, cygwin, djgpp] -tune86: tune.c - nasm -f coff timer.asm - $(CC) -DX86_TIMER $(CFLAGS) tune.c timer.o $(LIBNAME) -o tune86 - -# for cygwin -tune86c: tune.c - nasm -f gnuwin32 timer.asm - $(CC) -DX86_TIMER $(CFLAGS) tune.c timer.o $(LIBNAME) -o tune86 - -#make tune86 for linux or any ELF format -tune86l: tune.c - nasm -f elf -DUSE_ELF timer.asm - $(CC) -DX86_TIMER $(CFLAGS) tune.c timer.o $(LIBNAME) -o tune86l - -# spits out mersenne primes -mersenne: mersenne.o - $(CC) mersenne.o $(LIBNAME) -o mersenne - -# fines DR safe primes for the given config -drprime: drprime.o - $(CC) drprime.o $(LIBNAME) -o drprime - -# fines 2k safe primes for the given config -2kprime: 2kprime.o - $(CC) 2kprime.o $(LIBNAME) -o 2kprime - -mont: mont.o - $(CC) mont.o $(LIBNAME) -o mont - - -clean: - rm -f *.log *.o *.obj *.exe pprime tune mersenne drprime tune86 tune86l mont 2kprime pprime.dat *.il diff --git a/external/libtommath-0.42.0/etc/makefile.msvc b/external/libtommath-0.42.0/etc/makefile.msvc deleted file mode 100755 index 2833372..0000000 --- a/external/libtommath-0.42.0/etc/makefile.msvc +++ /dev/null @@ -1,23 +0,0 @@ -#MSVC Makefile -# -#Tom St Denis - -CFLAGS = /I../ /Ox /DWIN32 /W3 - -pprime: pprime.obj - cl pprime.obj ../tommath.lib - -mersenne: mersenne.obj - cl mersenne.obj ../tommath.lib - -tune: tune.obj - cl tune.obj ../tommath.lib - -mont: mont.obj - cl mont.obj ../tommath.lib - -drprime: drprime.obj - cl drprime.obj ../tommath.lib - -2kprime: 2kprime.obj - cl 2kprime.obj ../tommath.lib diff --git a/external/libtommath-0.42.0/etc/mersenne.c b/external/libtommath-0.42.0/etc/mersenne.c deleted file mode 100755 index 6f9eed2..0000000 --- a/external/libtommath-0.42.0/etc/mersenne.c +++ /dev/null @@ -1,144 +0,0 @@ -/* Finds Mersenne primes using the Lucas-Lehmer test - * - * Tom St Denis, tomstdenis@gmail.com - */ -#include -#include - -int -is_mersenne (long s, int *pp) -{ - mp_int n, u; - int res, k; - - *pp = 0; - - if ((res = mp_init (&n)) != MP_OKAY) { - return res; - } - - if ((res = mp_init (&u)) != MP_OKAY) { - goto LBL_N; - } - - /* n = 2^s - 1 */ - if ((res = mp_2expt(&n, s)) != MP_OKAY) { - goto LBL_MU; - } - if ((res = mp_sub_d (&n, 1, &n)) != MP_OKAY) { - goto LBL_MU; - } - - /* set u=4 */ - mp_set (&u, 4); - - /* for k=1 to s-2 do */ - for (k = 1; k <= s - 2; k++) { - /* u = u^2 - 2 mod n */ - if ((res = mp_sqr (&u, &u)) != MP_OKAY) { - goto LBL_MU; - } - if ((res = mp_sub_d (&u, 2, &u)) != MP_OKAY) { - goto LBL_MU; - } - - /* make sure u is positive */ - while (u.sign == MP_NEG) { - if ((res = mp_add (&u, &n, &u)) != MP_OKAY) { - goto LBL_MU; - } - } - - /* reduce */ - if ((res = mp_reduce_2k (&u, &n, 1)) != MP_OKAY) { - goto LBL_MU; - } - } - - /* if u == 0 then its prime */ - if (mp_iszero (&u) == 1) { - mp_prime_is_prime(&n, 8, pp); - if (*pp != 1) printf("FAILURE\n"); - } - - res = MP_OKAY; -LBL_MU:mp_clear (&u); -LBL_N:mp_clear (&n); - return res; -} - -/* square root of a long < 65536 */ -long -i_sqrt (long x) -{ - long x1, x2; - - x2 = 16; - do { - x1 = x2; - x2 = x1 - ((x1 * x1) - x) / (2 * x1); - } while (x1 != x2); - - if (x1 * x1 > x) { - --x1; - } - - return x1; -} - -/* is the long prime by brute force */ -int -isprime (long k) -{ - long y, z; - - y = i_sqrt (k); - for (z = 2; z <= y; z++) { - if ((k % z) == 0) - return 0; - } - return 1; -} - - -int -main (void) -{ - int pp; - long k; - clock_t tt; - - k = 3; - - for (;;) { - /* start time */ - tt = clock (); - - /* test if 2^k - 1 is prime */ - if (is_mersenne (k, &pp) != MP_OKAY) { - printf ("Whoa error\n"); - return -1; - } - - if (pp == 1) { - /* count time */ - tt = clock () - tt; - - /* display if prime */ - printf ("2^%-5ld - 1 is prime, test took %ld ticks\n", k, tt); - } - - /* goto next odd exponent */ - k += 2; - - /* but make sure its prime */ - while (isprime (k) == 0) { - k += 2; - } - } - return 0; -} - -/* $Source$ */ -/* $Revision: 0.39 $ */ -/* $Date: 2006-04-06 19:49:59 +0000 $ */ diff --git a/external/libtommath-0.42.0/etc/mont.c b/external/libtommath-0.42.0/etc/mont.c deleted file mode 100755 index 8356903..0000000 --- a/external/libtommath-0.42.0/etc/mont.c +++ /dev/null @@ -1,50 +0,0 @@ -/* tests the montgomery routines */ -#include - -int main(void) -{ - mp_int modulus, R, p, pp; - mp_digit mp; - long x, y; - - srand(time(NULL)); - mp_init_multi(&modulus, &R, &p, &pp, NULL); - - /* loop through various sizes */ - for (x = 4; x < 256; x++) { - printf("DIGITS == %3ld...", x); fflush(stdout); - - /* make up the odd modulus */ - mp_rand(&modulus, x); - modulus.dp[0] |= 1; - - /* now find the R value */ - mp_montgomery_calc_normalization(&R, &modulus); - mp_montgomery_setup(&modulus, &mp); - - /* now run through a bunch tests */ - for (y = 0; y < 1000; y++) { - mp_rand(&p, x/2); /* p = random */ - mp_mul(&p, &R, &pp); /* pp = R * p */ - mp_montgomery_reduce(&pp, &modulus, mp); - - /* should be equal to p */ - if (mp_cmp(&pp, &p) != MP_EQ) { - printf("FAILURE!\n"); - exit(-1); - } - } - printf("PASSED\n"); - } - - return 0; -} - - - - - - -/* $Source$ */ -/* $Revision: 0.36 $ */ -/* $Date: 2005-08-01 16:37:28 +0000 $ */ diff --git a/external/libtommath-0.42.0/etc/pprime.c b/external/libtommath-0.42.0/etc/pprime.c deleted file mode 100755 index d2d3a32..0000000 --- a/external/libtommath-0.42.0/etc/pprime.c +++ /dev/null @@ -1,400 +0,0 @@ -/* Generates provable primes - * - * See http://gmail.com:8080/papers/pp.pdf for more info. - * - * Tom St Denis, tomstdenis@gmail.com, http://tom.gmail.com - */ -#include -#include "tommath.h" - -int n_prime; -FILE *primes; - -/* fast square root */ -static mp_digit -i_sqrt (mp_word x) -{ - mp_word x1, x2; - - x2 = x; - do { - x1 = x2; - x2 = x1 - ((x1 * x1) - x) / (2 * x1); - } while (x1 != x2); - - if (x1 * x1 > x) { - --x1; - } - - return x1; -} - - -/* generates a prime digit */ -static void gen_prime (void) -{ - mp_digit r, x, y, next; - FILE *out; - - out = fopen("pprime.dat", "wb"); - - /* write first set of primes */ - r = 3; fwrite(&r, 1, sizeof(mp_digit), out); - r = 5; fwrite(&r, 1, sizeof(mp_digit), out); - r = 7; fwrite(&r, 1, sizeof(mp_digit), out); - r = 11; fwrite(&r, 1, sizeof(mp_digit), out); - r = 13; fwrite(&r, 1, sizeof(mp_digit), out); - r = 17; fwrite(&r, 1, sizeof(mp_digit), out); - r = 19; fwrite(&r, 1, sizeof(mp_digit), out); - r = 23; fwrite(&r, 1, sizeof(mp_digit), out); - r = 29; fwrite(&r, 1, sizeof(mp_digit), out); - r = 31; fwrite(&r, 1, sizeof(mp_digit), out); - - /* get square root, since if 'r' is composite its factors must be < than this */ - y = i_sqrt (r); - next = (y + 1) * (y + 1); - - for (;;) { - do { - r += 2; /* next candidate */ - r &= MP_MASK; - if (r < 31) break; - - /* update sqrt ? */ - if (next <= r) { - ++y; - next = (y + 1) * (y + 1); - } - - /* loop if divisible by 3,5,7,11,13,17,19,23,29 */ - if ((r % 3) == 0) { - x = 0; - continue; - } - if ((r % 5) == 0) { - x = 0; - continue; - } - if ((r % 7) == 0) { - x = 0; - continue; - } - if ((r % 11) == 0) { - x = 0; - continue; - } - if ((r % 13) == 0) { - x = 0; - continue; - } - if ((r % 17) == 0) { - x = 0; - continue; - } - if ((r % 19) == 0) { - x = 0; - continue; - } - if ((r % 23) == 0) { - x = 0; - continue; - } - if ((r % 29) == 0) { - x = 0; - continue; - } - - /* now check if r is divisible by x + k={1,7,11,13,17,19,23,29} */ - for (x = 30; x <= y; x += 30) { - if ((r % (x + 1)) == 0) { - x = 0; - break; - } - if ((r % (x + 7)) == 0) { - x = 0; - break; - } - if ((r % (x + 11)) == 0) { - x = 0; - break; - } - if ((r % (x + 13)) == 0) { - x = 0; - break; - } - if ((r % (x + 17)) == 0) { - x = 0; - break; - } - if ((r % (x + 19)) == 0) { - x = 0; - break; - } - if ((r % (x + 23)) == 0) { - x = 0; - break; - } - if ((r % (x + 29)) == 0) { - x = 0; - break; - } - } - } while (x == 0); - if (r > 31) { fwrite(&r, 1, sizeof(mp_digit), out); printf("%9d\r", r); fflush(stdout); } - if (r < 31) break; - } - - fclose(out); -} - -void load_tab(void) -{ - primes = fopen("pprime.dat", "rb"); - if (primes == NULL) { - gen_prime(); - primes = fopen("pprime.dat", "rb"); - } - fseek(primes, 0, SEEK_END); - n_prime = ftell(primes) / sizeof(mp_digit); -} - -mp_digit prime_digit(void) -{ - int n; - mp_digit d; - - n = abs(rand()) % n_prime; - fseek(primes, n * sizeof(mp_digit), SEEK_SET); - fread(&d, 1, sizeof(mp_digit), primes); - return d; -} - - -/* makes a prime of at least k bits */ -int -pprime (int k, int li, mp_int * p, mp_int * q) -{ - mp_int a, b, c, n, x, y, z, v; - int res, ii; - static const mp_digit bases[] = { 2, 3, 5, 7, 11, 13, 17, 19 }; - - /* single digit ? */ - if (k <= (int) DIGIT_BIT) { - mp_set (p, prime_digit ()); - return MP_OKAY; - } - - if ((res = mp_init (&c)) != MP_OKAY) { - return res; - } - - if ((res = mp_init (&v)) != MP_OKAY) { - goto LBL_C; - } - - /* product of first 50 primes */ - if ((res = - mp_read_radix (&v, - "19078266889580195013601891820992757757219839668357012055907516904309700014933909014729740190", - 10)) != MP_OKAY) { - goto LBL_V; - } - - if ((res = mp_init (&a)) != MP_OKAY) { - goto LBL_V; - } - - /* set the prime */ - mp_set (&a, prime_digit ()); - - if ((res = mp_init (&b)) != MP_OKAY) { - goto LBL_A; - } - - if ((res = mp_init (&n)) != MP_OKAY) { - goto LBL_B; - } - - if ((res = mp_init (&x)) != MP_OKAY) { - goto LBL_N; - } - - if ((res = mp_init (&y)) != MP_OKAY) { - goto LBL_X; - } - - if ((res = mp_init (&z)) != MP_OKAY) { - goto LBL_Y; - } - - /* now loop making the single digit */ - while (mp_count_bits (&a) < k) { - fprintf (stderr, "prime has %4d bits left\r", k - mp_count_bits (&a)); - fflush (stderr); - top: - mp_set (&b, prime_digit ()); - - /* now compute z = a * b * 2 */ - if ((res = mp_mul (&a, &b, &z)) != MP_OKAY) { /* z = a * b */ - goto LBL_Z; - } - - if ((res = mp_copy (&z, &c)) != MP_OKAY) { /* c = a * b */ - goto LBL_Z; - } - - if ((res = mp_mul_2 (&z, &z)) != MP_OKAY) { /* z = 2 * a * b */ - goto LBL_Z; - } - - /* n = z + 1 */ - if ((res = mp_add_d (&z, 1, &n)) != MP_OKAY) { /* n = z + 1 */ - goto LBL_Z; - } - - /* check (n, v) == 1 */ - if ((res = mp_gcd (&n, &v, &y)) != MP_OKAY) { /* y = (n, v) */ - goto LBL_Z; - } - - if (mp_cmp_d (&y, 1) != MP_EQ) - goto top; - - /* now try base x=bases[ii] */ - for (ii = 0; ii < li; ii++) { - mp_set (&x, bases[ii]); - - /* compute x^a mod n */ - if ((res = mp_exptmod (&x, &a, &n, &y)) != MP_OKAY) { /* y = x^a mod n */ - goto LBL_Z; - } - - /* if y == 1 loop */ - if (mp_cmp_d (&y, 1) == MP_EQ) - continue; - - /* now x^2a mod n */ - if ((res = mp_sqrmod (&y, &n, &y)) != MP_OKAY) { /* y = x^2a mod n */ - goto LBL_Z; - } - - if (mp_cmp_d (&y, 1) == MP_EQ) - continue; - - /* compute x^b mod n */ - if ((res = mp_exptmod (&x, &b, &n, &y)) != MP_OKAY) { /* y = x^b mod n */ - goto LBL_Z; - } - - /* if y == 1 loop */ - if (mp_cmp_d (&y, 1) == MP_EQ) - continue; - - /* now x^2b mod n */ - if ((res = mp_sqrmod (&y, &n, &y)) != MP_OKAY) { /* y = x^2b mod n */ - goto LBL_Z; - } - - if (mp_cmp_d (&y, 1) == MP_EQ) - continue; - - /* compute x^c mod n == x^ab mod n */ - if ((res = mp_exptmod (&x, &c, &n, &y)) != MP_OKAY) { /* y = x^ab mod n */ - goto LBL_Z; - } - - /* if y == 1 loop */ - if (mp_cmp_d (&y, 1) == MP_EQ) - continue; - - /* now compute (x^c mod n)^2 */ - if ((res = mp_sqrmod (&y, &n, &y)) != MP_OKAY) { /* y = x^2ab mod n */ - goto LBL_Z; - } - - /* y should be 1 */ - if (mp_cmp_d (&y, 1) != MP_EQ) - continue; - break; - } - - /* no bases worked? */ - if (ii == li) - goto top; - -{ - char buf[4096]; - - mp_toradix(&n, buf, 10); - printf("Certificate of primality for:\n%s\n\n", buf); - mp_toradix(&a, buf, 10); - printf("A == \n%s\n\n", buf); - mp_toradix(&b, buf, 10); - printf("B == \n%s\n\nG == %d\n", buf, bases[ii]); - printf("----------------------------------------------------------------\n"); -} - - /* a = n */ - mp_copy (&n, &a); - } - - /* get q to be the order of the large prime subgroup */ - mp_sub_d (&n, 1, q); - mp_div_2 (q, q); - mp_div (q, &b, q, NULL); - - mp_exch (&n, p); - - res = MP_OKAY; -LBL_Z:mp_clear (&z); -LBL_Y:mp_clear (&y); -LBL_X:mp_clear (&x); -LBL_N:mp_clear (&n); -LBL_B:mp_clear (&b); -LBL_A:mp_clear (&a); -LBL_V:mp_clear (&v); -LBL_C:mp_clear (&c); - return res; -} - - -int -main (void) -{ - mp_int p, q; - char buf[4096]; - int k, li; - clock_t t1; - - srand (time (NULL)); - load_tab(); - - printf ("Enter # of bits: \n"); - fgets (buf, sizeof (buf), stdin); - sscanf (buf, "%d", &k); - - printf ("Enter number of bases to try (1 to 8):\n"); - fgets (buf, sizeof (buf), stdin); - sscanf (buf, "%d", &li); - - - mp_init (&p); - mp_init (&q); - - t1 = clock (); - pprime (k, li, &p, &q); - t1 = clock () - t1; - - printf ("\n\nTook %ld ticks, %d bits\n", t1, mp_count_bits (&p)); - - mp_toradix (&p, buf, 10); - printf ("P == %s\n", buf); - mp_toradix (&q, buf, 10); - printf ("Q == %s\n", buf); - - return 0; -} - -/* $Source$ */ -/* $Revision: 0.39 $ */ -/* $Date: 2006-04-06 19:49:59 +0000 $ */ diff --git a/external/libtommath-0.42.0/etc/prime.1024 b/external/libtommath-0.42.0/etc/prime.1024 deleted file mode 100755 index 5636e2d..0000000 --- a/external/libtommath-0.42.0/etc/prime.1024 +++ /dev/null @@ -1,414 +0,0 @@ -Enter # of bits: -Enter number of bases to try (1 to 8): -Certificate of primality for: -36360080703173363 - -A == -89963569 - -B == -202082249 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -4851595597739856136987139 - -A == -36360080703173363 - -B == -66715963 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -19550639734462621430325731591027 - -A == -4851595597739856136987139 - -B == -2014867 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -10409036141344317165691858509923818734539 - -A == -19550639734462621430325731591027 - -B == -266207047 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -1049829549988285012736475602118094726647504414203 - -A == -10409036141344317165691858509923818734539 - -B == -50428759 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -77194737385528288387712399596835459931920358844586615003 - -A == -1049829549988285012736475602118094726647504414203 - -B == -36765367 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -35663756695365208574443215955488689578374232732893628896541201763 - -A == -77194737385528288387712399596835459931920358844586615003 - -B == -230998627 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -16711831463502165169495622246023119698415848120292671294127567620396469803 - -A == -35663756695365208574443215955488689578374232732893628896541201763 - -B == -234297127 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -6163534781560285962890718925972249753147470953579266394395432475622345597103528739 - -A == -16711831463502165169495622246023119698415848120292671294127567620396469803 - -B == -184406323 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -814258256205243497704094951432575867360065658372158511036259934640748088306764553488803787 - -A == -6163534781560285962890718925972249753147470953579266394395432475622345597103528739 - -B == -66054487 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -176469695533271657902814176811660357049007467856432383037590673407330246967781451723764079581998187 - -A == -814258256205243497704094951432575867360065658372158511036259934640748088306764553488803787 - -B == -108362239 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -44924492859445516541759485198544012102424796403707253610035148063863073596051272171194806669756971406400419 - -A == -176469695533271657902814176811660357049007467856432383037590673407330246967781451723764079581998187 - -B == -127286707 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -20600996927219343383225424320134474929609459588323857796871086845924186191561749519858600696159932468024710985371059 - -A == -44924492859445516541759485198544012102424796403707253610035148063863073596051272171194806669756971406400419 - -B == -229284691 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -6295696427695493110141186605837397185848992307978456138112526915330347715236378041486547994708748840844217371233735072572979 - -A == -20600996927219343383225424320134474929609459588323857796871086845924186191561749519858600696159932468024710985371059 - -B == -152800771 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -3104984078042317488749073016454213579257792635142218294052134804187631661145261015102617582090263808696699966840735333252107678792123 - -A == -6295696427695493110141186605837397185848992307978456138112526915330347715236378041486547994708748840844217371233735072572979 - -B == -246595759 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -26405175827665701256325699315126705508919255051121452292124404943796947287968603975320562847910946802396632302209435206627913466015741799499 - -A == -3104984078042317488749073016454213579257792635142218294052134804187631661145261015102617582090263808696699966840735333252107678792123 - -B == -4252063 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -11122146237908413610034600609460545703591095894418599759742741406628055069007082998134905595800236452010905900391505454890446585211975124558601770163 - -A == -26405175827665701256325699315126705508919255051121452292124404943796947287968603975320562847910946802396632302209435206627913466015741799499 - -B == -210605419 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -1649861642047798890580354082088712649911849362201343649289384923147797960364736011515757482030049342943790127685185806092659832129486307035500638595572396187 - -A == -11122146237908413610034600609460545703591095894418599759742741406628055069007082998134905595800236452010905900391505454890446585211975124558601770163 - -B == -74170111 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -857983367126266717607389719637086684134462613006415859877666235955788392464081914127715967940968197765042399904117392707518175220864852816390004264107201177394565363 - -A == -1649861642047798890580354082088712649911849362201343649289384923147797960364736011515757482030049342943790127685185806092659832129486307035500638595572396187 - -B == -260016763 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -175995909353623703257072120479340610010337144085688850745292031336724691277374210929188442230237711063783727092685448718515661641054886101716698390145283196296702450566161283 - -A == -857983367126266717607389719637086684134462613006415859877666235955788392464081914127715967940968197765042399904117392707518175220864852816390004264107201177394565363 - -B == -102563707 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -48486002551155667224487059713350447239190772068092630563272168418880661006593537218144160068395218642353495339720640699721703003648144463556291315694787862009052641640656933232794283 - -A == -175995909353623703257072120479340610010337144085688850745292031336724691277374210929188442230237711063783727092685448718515661641054886101716698390145283196296702450566161283 - -B == -137747527 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -13156468011529105025061495011938518171328604045212410096476697450506055664012861932372156505805788068791146986282263016790631108386790291275939575123375304599622623328517354163964228279867403 - -A == -48486002551155667224487059713350447239190772068092630563272168418880661006593537218144160068395218642353495339720640699721703003648144463556291315694787862009052641640656933232794283 - -B == -135672847 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -6355194692790533601105154341731997464407930009404822926832136060319955058388106456084549316415200519472481147942263916585428906582726749131479465958107142228236909665306781538860053107680830113869123 - -A == -13156468011529105025061495011938518171328604045212410096476697450506055664012861932372156505805788068791146986282263016790631108386790291275939575123375304599622623328517354163964228279867403 - -B == -241523587 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -3157116676535430302794438027544146642863331358530722860333745617571010460905857862561870488000265751138954271040017454405707755458702044884023184574412221802502351503929935224995314581932097706874819348858083 - -A == -6355194692790533601105154341731997464407930009404822926832136060319955058388106456084549316415200519472481147942263916585428906582726749131479465958107142228236909665306781538860053107680830113869123 - -B == -248388667 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -390533129219992506725320633489467713907837370444962163378727819939092929448752905310115311180032249230394348337568973177802874166228132778126338883671958897238722734394783244237133367055422297736215754829839364158067 - -A == -3157116676535430302794438027544146642863331358530722860333745617571010460905857862561870488000265751138954271040017454405707755458702044884023184574412221802502351503929935224995314581932097706874819348858083 - -B == -61849651 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -48583654555070224891047847050732516652910250240135992225139515777200432486685999462997073444468380434359929499498804723793106565291183220444221080449740542884172281158126259373095216435009661050109711341419005972852770440739 - -A == -390533129219992506725320633489467713907837370444962163378727819939092929448752905310115311180032249230394348337568973177802874166228132778126338883671958897238722734394783244237133367055422297736215754829839364158067 - -B == -62201707 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -25733035251905120039135866524384525138869748427727001128764704499071378939227862068500633813538831598776578372709963673670934388213622433800015759585470542686333039614931682098922935087822950084908715298627996115185849260703525317419 - -A == -48583654555070224891047847050732516652910250240135992225139515777200432486685999462997073444468380434359929499498804723793106565291183220444221080449740542884172281158126259373095216435009661050109711341419005972852770440739 - -B == -264832231 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -2804594464939948901906623499531073917980499195397462605359913717827014360538186518540781517129548650937632008683280555602633122170458773895504894807182664540529077836857897972175530148107545939211339044386106111633510166695386323426241809387 - -A == -25733035251905120039135866524384525138869748427727001128764704499071378939227862068500633813538831598776578372709963673670934388213622433800015759585470542686333039614931682098922935087822950084908715298627996115185849260703525317419 - -B == -54494047 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -738136612083433720096707308165797114449914259256979340471077690416567237592465306112484843530074782721390528773594351482384711900456440808251196845265132086486672447136822046628407467459921823150600138073268385534588238548865012638209515923513516547 - -A == -2804594464939948901906623499531073917980499195397462605359913717827014360538186518540781517129548650937632008683280555602633122170458773895504894807182664540529077836857897972175530148107545939211339044386106111633510166695386323426241809387 - -B == -131594179 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -392847529056126766528615419937165193421166694172790666626558750047057558168124866940509180171236517681470100877687445134633784815352076138790217228749332398026714192707447855731679485746120589851992221508292976900578299504461333767437280988393026452846013683 - -A == -738136612083433720096707308165797114449914259256979340471077690416567237592465306112484843530074782721390528773594351482384711900456440808251196845265132086486672447136822046628407467459921823150600138073268385534588238548865012638209515923513516547 - -B == -266107603 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -168459393231883505975876919268398655632763956627405508859662408056221544310200546265681845397346956580604208064328814319465940958080244889692368602591598503944015835190587740756859842792554282496742843600573336023639256008687581291233481455395123454655488735304365627 - -A == -392847529056126766528615419937165193421166694172790666626558750047057558168124866940509180171236517681470100877687445134633784815352076138790217228749332398026714192707447855731679485746120589851992221508292976900578299504461333767437280988393026452846013683 - -B == -214408111 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -14865774288636941404884923981945833072113667565310054952177860608355263252462409554658728941191929400198053290113492910272458441655458514080123870132092365833472436407455910185221474386718838138135065780840839893113912689594815485706154461164071775481134379794909690501684643 - -A == -168459393231883505975876919268398655632763956627405508859662408056221544310200546265681845397346956580604208064328814319465940958080244889692368602591598503944015835190587740756859842792554282496742843600573336023639256008687581291233481455395123454655488735304365627 - -B == -44122723 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -1213301773203241614897109856134894783021668292000023984098824423682568173639394290886185366993108292039068940333907505157813934962357206131450244004178619265868614859794316361031904412926604138893775068853175215502104744339658944443630407632290152772487455298652998368296998719996019 - -A == -14865774288636941404884923981945833072113667565310054952177860608355263252462409554658728941191929400198053290113492910272458441655458514080123870132092365833472436407455910185221474386718838138135065780840839893113912689594815485706154461164071775481134379794909690501684643 - -B == -40808563 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -186935245989515158127969129347464851990429060640910951266513740972248428651109062997368144722015290092846666943896556191257222521203647606911446635194198213436423080005867489516421559330500722264446765608763224572386410155413161172707802334865729654109050873820610813855041667633843601286843 - -A == -1213301773203241614897109856134894783021668292000023984098824423682568173639394290886185366993108292039068940333907505157813934962357206131450244004178619265868614859794316361031904412926604138893775068853175215502104744339658944443630407632290152772487455298652998368296998719996019 - -B == -77035759 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -83142661079751490510739960019112406284111408348732592580459037404394946037094409915127399165633756159385609671956087845517678367844901424617866988187132480585966721962585586730693443536100138246516868613250009028187662080828012497191775172228832247706080044971423654632146928165751885302331924491683 - -A == -186935245989515158127969129347464851990429060640910951266513740972248428651109062997368144722015290092846666943896556191257222521203647606911446635194198213436423080005867489516421559330500722264446765608763224572386410155413161172707802334865729654109050873820610813855041667633843601286843 - -B == -222383587 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -3892354773803809855317742245039794448230625839512638747643814927766738642436392673485997449586432241626440927010641564064764336402368634186618250134234189066179771240232458249806850838490410473462391401438160528157981942499581634732706904411807195259620779379274017704050790865030808501633772117217899534443 - -A == -83142661079751490510739960019112406284111408348732592580459037404394946037094409915127399165633756159385609671956087845517678367844901424617866988187132480585966721962585586730693443536100138246516868613250009028187662080828012497191775172228832247706080044971423654632146928165751885302331924491683 - -B == -23407687 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -1663606652988091811284014366560171522582683318514519379924950390627250155440313691226744227787921928894551755219495501365555370027257568506349958010457682898612082048959464465369892842603765280317696116552850664773291371490339084156052244256635115997453399761029567033971998617303988376172539172702246575225837054723 - -A == -3892354773803809855317742245039794448230625839512638747643814927766738642436392673485997449586432241626440927010641564064764336402368634186618250134234189066179771240232458249806850838490410473462391401438160528157981942499581634732706904411807195259620779379274017704050790865030808501633772117217899534443 - -B == -213701827 - -G == 2 ----------------------------------------------------------------- - - -Took 33057 ticks, 1048 bits -P == 1663606652988091811284014366560171522582683318514519379924950390627250155440313691226744227787921928894551755219495501365555370027257568506349958010457682898612082048959464465369892842603765280317696116552850664773291371490339084156052244256635115997453399761029567033971998617303988376172539172702246575225837054723 -Q == 3892354773803809855317742245039794448230625839512638747643814927766738642436392673485997449586432241626440927010641564064764336402368634186618250134234189066179771240232458249806850838490410473462391401438160528157981942499581634732706904411807195259620779379274017704050790865030808501633772117217899534443 diff --git a/external/libtommath-0.42.0/etc/prime.512 b/external/libtommath-0.42.0/etc/prime.512 deleted file mode 100755 index cb6ec30..0000000 --- a/external/libtommath-0.42.0/etc/prime.512 +++ /dev/null @@ -1,205 +0,0 @@ -Enter # of bits: -Enter number of bases to try (1 to 8): -Certificate of primality for: -85933926807634727 - -A == -253758023 - -B == -169322581 - -G == 5 ----------------------------------------------------------------- -Certificate of primality for: -23930198825086241462113799 - -A == -85933926807634727 - -B == -139236037 - -G == 11 ----------------------------------------------------------------- -Certificate of primality for: -6401844647261612602378676572510019 - -A == -23930198825086241462113799 - -B == -133760791 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -269731366027728777712034888684015329354259 - -A == -6401844647261612602378676572510019 - -B == -21066691 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -37942338209025571690075025099189467992329684223707 - -A == -269731366027728777712034888684015329354259 - -B == -70333567 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -15306904714258982484473490774101705363308327436988160248323 - -A == -37942338209025571690075025099189467992329684223707 - -B == -201712723 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -1616744757018513392810355191503853040357155275733333124624513530099 - -A == -15306904714258982484473490774101705363308327436988160248323 - -B == -52810963 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -464222094814208047161771036072622485188658077940154689939306386289983787983 - -A == -1616744757018513392810355191503853040357155275733333124624513530099 - -B == -143566909 - -G == 5 ----------------------------------------------------------------- -Certificate of primality for: -187429931674053784626487560729643601208757374994177258429930699354770049369025096447 - -A == -464222094814208047161771036072622485188658077940154689939306386289983787983 - -B == -201875281 - -G == 5 ----------------------------------------------------------------- -Certificate of primality for: -100579220846502621074093727119851331775052664444339632682598589456666938521976625305832917563 - -A == -187429931674053784626487560729643601208757374994177258429930699354770049369025096447 - -B == -268311523 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -1173616081309758475197022137833792133815753368965945885089720153370737965497134878651384030219765163 - -A == -100579220846502621074093727119851331775052664444339632682598589456666938521976625305832917563 - -B == -5834287 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -191456913489905913185935197655672585713573070349044195411728114905691721186574907738081340754373032735283623 - -A == -1173616081309758475197022137833792133815753368965945885089720153370737965497134878651384030219765163 - -B == -81567097 - -G == 5 ----------------------------------------------------------------- -Certificate of primality for: -57856530489201750164178576399448868489243874083056587683743345599898489554401618943240901541005080049321706789987519 - -A == -191456913489905913185935197655672585713573070349044195411728114905691721186574907738081340754373032735283623 - -B == -151095433 - -G == 7 ----------------------------------------------------------------- -Certificate of primality for: -13790529750452576698109671710773784949185621244122040804792403407272729038377767162233653248852099545134831722512085881814803 - -A == -57856530489201750164178576399448868489243874083056587683743345599898489554401618943240901541005080049321706789987519 - -B == -119178679 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -7075985989000817742677547821106534174334812111605018857703825637170140040509067704269696198231266351631132464035671858077052876058979 - -A == -13790529750452576698109671710773784949185621244122040804792403407272729038377767162233653248852099545134831722512085881814803 - -B == -256552363 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -1227273006232588072907488910282307435921226646895131225407452056677899411162892829564455154080310937471747140942360789623819327234258162420463 - -A == -7075985989000817742677547821106534174334812111605018857703825637170140040509067704269696198231266351631132464035671858077052876058979 - -B == -86720989 - -G == 5 ----------------------------------------------------------------- -Certificate of primality for: -446764896913554613686067036908702877942872355053329937790398156069936255759889884246832779737114032666318220500106499161852193765380831330106375235763 - -A == -1227273006232588072907488910282307435921226646895131225407452056677899411162892829564455154080310937471747140942360789623819327234258162420463 - -B == -182015287 - -G == 2 ----------------------------------------------------------------- -Certificate of primality for: -5290203010849586596974953717018896543907195901082056939587768479377028575911127944611236020459652034082251335583308070846379514569838984811187823420951275243 - -A == -446764896913554613686067036908702877942872355053329937790398156069936255759889884246832779737114032666318220500106499161852193765380831330106375235763 - -B == -5920567 - -G == 2 ----------------------------------------------------------------- - - -Took 3454 ticks, 521 bits -P == 5290203010849586596974953717018896543907195901082056939587768479377028575911127944611236020459652034082251335583308070846379514569838984811187823420951275243 -Q == 446764896913554613686067036908702877942872355053329937790398156069936255759889884246832779737114032666318220500106499161852193765380831330106375235763 diff --git a/external/libtommath-0.42.0/etc/timer.asm b/external/libtommath-0.42.0/etc/timer.asm deleted file mode 100755 index 35890d9..0000000 --- a/external/libtommath-0.42.0/etc/timer.asm +++ /dev/null @@ -1,37 +0,0 @@ -; x86 timer in NASM -; -; Tom St Denis, tomstdenis@iahu.ca -[bits 32] -[section .data] -time dd 0, 0 - -[section .text] - -%ifdef USE_ELF -[global t_start] -t_start: -%else -[global _t_start] -_t_start: -%endif - push edx - push eax - rdtsc - mov [time+0],edx - mov [time+4],eax - pop eax - pop edx - ret - -%ifdef USE_ELF -[global t_read] -t_read: -%else -[global _t_read] -_t_read: -%endif - rdtsc - sub eax,[time+4] - sbb edx,[time+0] - ret - \ No newline at end of file diff --git a/external/libtommath-0.42.0/etc/tune.c b/external/libtommath-0.42.0/etc/tune.c deleted file mode 100755 index 0094f19..0000000 --- a/external/libtommath-0.42.0/etc/tune.c +++ /dev/null @@ -1,142 +0,0 @@ -/* Tune the Karatsuba parameters - * - * Tom St Denis, tomstdenis@gmail.com - */ -#include -#include - -/* how many times todo each size mult. Depends on your computer. For slow computers - * this can be low like 5 or 10. For fast [re: Athlon] should be 25 - 50 or so - */ -#define TIMES (1UL<<14UL) - -/* RDTSC from Scott Duplichan */ -static ulong64 TIMFUNC (void) - { - #if defined __GNUC__ - #if defined(__i386__) || defined(__x86_64__) - unsigned long long a; - __asm__ __volatile__ ("rdtsc\nmovl %%eax,%0\nmovl %%edx,4+%0\n"::"m"(a):"%eax","%edx"); - return a; - #else /* gcc-IA64 version */ - unsigned long result; - __asm__ __volatile__("mov %0=ar.itc" : "=r"(result) :: "memory"); - while (__builtin_expect ((int) result == -1, 0)) - __asm__ __volatile__("mov %0=ar.itc" : "=r"(result) :: "memory"); - return result; - #endif - - // Microsoft and Intel Windows compilers - #elif defined _M_IX86 - __asm rdtsc - #elif defined _M_AMD64 - return __rdtsc (); - #elif defined _M_IA64 - #if defined __INTEL_COMPILER - #include - #endif - return __getReg (3116); - #else - #error need rdtsc function for this build - #endif - } - - -#ifndef X86_TIMER - -/* generic ISO C timer */ -ulong64 LBL_T; -void t_start(void) { LBL_T = TIMFUNC(); } -ulong64 t_read(void) { return TIMFUNC() - LBL_T; } - -#else -extern void t_start(void); -extern ulong64 t_read(void); -#endif - -ulong64 time_mult(int size, int s) -{ - unsigned long x; - mp_int a, b, c; - ulong64 t1; - - mp_init (&a); - mp_init (&b); - mp_init (&c); - - mp_rand (&a, size); - mp_rand (&b, size); - - if (s == 1) { - KARATSUBA_MUL_CUTOFF = size; - } else { - KARATSUBA_MUL_CUTOFF = 100000; - } - - t_start(); - for (x = 0; x < TIMES; x++) { - mp_mul(&a,&b,&c); - } - t1 = t_read(); - mp_clear (&a); - mp_clear (&b); - mp_clear (&c); - return t1; -} - -ulong64 time_sqr(int size, int s) -{ - unsigned long x; - mp_int a, b; - ulong64 t1; - - mp_init (&a); - mp_init (&b); - - mp_rand (&a, size); - - if (s == 1) { - KARATSUBA_SQR_CUTOFF = size; - } else { - KARATSUBA_SQR_CUTOFF = 100000; - } - - t_start(); - for (x = 0; x < TIMES; x++) { - mp_sqr(&a,&b); - } - t1 = t_read(); - mp_clear (&a); - mp_clear (&b); - return t1; -} - -int -main (void) -{ - ulong64 t1, t2; - int x, y; - - for (x = 8; ; x += 2) { - t1 = time_mult(x, 0); - t2 = time_mult(x, 1); - printf("%d: %9llu %9llu, %9llu\n", x, t1, t2, t2 - t1); - if (t2 < t1) break; - } - y = x; - - for (x = 8; ; x += 2) { - t1 = time_sqr(x, 0); - t2 = time_sqr(x, 1); - printf("%d: %9llu %9llu, %9llu\n", x, t1, t2, t2 - t1); - if (t2 < t1) break; - } - printf("KARATSUBA_MUL_CUTOFF = %d\n", y); - printf("KARATSUBA_SQR_CUTOFF = %d\n", x); - - return 0; -} - -/* $Source$ */ -/* $Revision: 0.39 $ */ -/* $Date: 2006-04-06 19:49:59 +0000 $ */ diff --git a/external/libtommath-0.42.0/gen.pl b/external/libtommath-0.42.0/gen.pl deleted file mode 100755 index 7236591..0000000 --- a/external/libtommath-0.42.0/gen.pl +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/perl -w -# -# Generates a "single file" you can use to quickly -# add the whole source without any makefile troubles -# -use strict; - -open( OUT, ">mpi.c" ) or die "Couldn't open mpi.c for writing: $!"; -foreach my $filename (glob "bn*.c") { - open( SRC, "<$filename" ) or die "Couldn't open $filename for reading: $!"; - print OUT "/* Start: $filename */\n"; - print OUT while ; - print OUT "\n/* End: $filename */\n\n"; - close SRC or die "Error closing $filename after reading: $!"; -} -print OUT "\n/* EOF */\n"; -close OUT or die "Error closing mpi.c after writing: $!"; \ No newline at end of file diff --git a/external/libtommath-0.42.0/libtommath.dsp b/external/libtommath-0.42.0/libtommath.dsp deleted file mode 100755 index 71ac243..0000000 --- a/external/libtommath-0.42.0/libtommath.dsp +++ /dev/null @@ -1,572 +0,0 @@ -# Microsoft Developer Studio Project File - Name="libtommath" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Static Library" 0x0104 - -CFG=libtommath - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "libtommath.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "libtommath.mak" CFG="libtommath - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "libtommath - Win32 Release" (based on "Win32 (x86) Static Library") -!MESSAGE "libtommath - Win32 Debug" (based on "Win32 (x86) Static Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "libtommath" -# PROP Scc_LocalPath "." -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "libtommath - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c -# ADD CPP /nologo /W3 /GX /O2 /I "." /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo -# ADD LIB32 /nologo /out:"Release\tommath.lib" - -!ELSEIF "$(CFG)" == "libtommath - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c -# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "." /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo -# ADD LIB32 /nologo /out:"Debug\tommath.lib" - -!ENDIF - -# Begin Target - -# Name "libtommath - Win32 Release" -# Name "libtommath - Win32 Debug" -# Begin Source File - -SOURCE=.\bn_error.c -# End Source File -# Begin Source File - -SOURCE=.\bn_fast_mp_invmod.c -# End Source File -# Begin Source File - -SOURCE=.\bn_fast_mp_montgomery_reduce.c -# End Source File -# Begin Source File - -SOURCE=.\bn_fast_s_mp_mul_digs.c -# End Source File -# Begin Source File - -SOURCE=.\bn_fast_s_mp_mul_high_digs.c -# End Source File -# Begin Source File - -SOURCE=.\bn_fast_s_mp_sqr.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_2expt.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_abs.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_add.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_add_d.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_addmod.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_and.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_clamp.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_clear.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_clear_multi.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_cmp.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_cmp_d.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_cmp_mag.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_cnt_lsb.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_copy.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_count_bits.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_div.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_div_2.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_div_2d.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_div_3.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_div_d.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_dr_is_modulus.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_dr_reduce.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_dr_setup.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_exch.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_expt_d.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_exptmod.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_exptmod_fast.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_exteuclid.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_fread.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_fwrite.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_gcd.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_get_int.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_grow.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_init.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_init_copy.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_init_multi.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_init_set.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_init_set_int.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_init_size.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_invmod.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_invmod_slow.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_is_square.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_jacobi.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_karatsuba_mul.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_karatsuba_sqr.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_lcm.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_lshd.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_mod.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_mod_2d.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_mod_d.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_montgomery_calc_normalization.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_montgomery_reduce.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_montgomery_setup.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_mul.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_mul_2.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_mul_2d.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_mul_d.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_mulmod.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_n_root.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_neg.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_or.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_prime_fermat.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_prime_is_divisible.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_prime_is_prime.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_prime_miller_rabin.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_prime_next_prime.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_prime_rabin_miller_trials.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_prime_random_ex.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_radix_size.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_radix_smap.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_rand.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_read_radix.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_read_signed_bin.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_read_unsigned_bin.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_reduce.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_reduce_2k.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_reduce_2k_l.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_reduce_2k_setup.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_reduce_2k_setup_l.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_reduce_is_2k.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_reduce_is_2k_l.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_reduce_setup.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_rshd.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_set.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_set_int.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_shrink.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_signed_bin_size.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_sqr.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_sqrmod.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_sqrt.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_sub.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_sub_d.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_submod.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_to_signed_bin.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_to_signed_bin_n.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_to_unsigned_bin.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_to_unsigned_bin_n.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_toom_mul.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_toom_sqr.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_toradix.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_toradix_n.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_unsigned_bin_size.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_xor.c -# End Source File -# Begin Source File - -SOURCE=.\bn_mp_zero.c -# End Source File -# Begin Source File - -SOURCE=.\bn_prime_tab.c -# End Source File -# Begin Source File - -SOURCE=.\bn_reverse.c -# End Source File -# Begin Source File - -SOURCE=.\bn_s_mp_add.c -# End Source File -# Begin Source File - -SOURCE=.\bn_s_mp_exptmod.c -# End Source File -# Begin Source File - -SOURCE=.\bn_s_mp_mul_digs.c -# End Source File -# Begin Source File - -SOURCE=.\bn_s_mp_mul_high_digs.c -# End Source File -# Begin Source File - -SOURCE=.\bn_s_mp_sqr.c -# End Source File -# Begin Source File - -SOURCE=.\bn_s_mp_sub.c -# End Source File -# Begin Source File - -SOURCE=.\bncore.c -# End Source File -# Begin Source File - -SOURCE=.\tommath.h -# End Source File -# Begin Source File - -SOURCE=.\tommath_class.h -# End Source File -# Begin Source File - -SOURCE=.\tommath_superclass.h -# End Source File -# End Target -# End Project diff --git a/external/libtommath-0.42.0/libtommath_VS2005.sln b/external/libtommath-0.42.0/libtommath_VS2005.sln deleted file mode 100755 index 21bc915..0000000 --- a/external/libtommath-0.42.0/libtommath_VS2005.sln +++ /dev/null @@ -1,20 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 9.00 -# Visual Studio 2005 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libtommath", "libtommath_VS2005.vcproj", "{0272C9B2-D68B-4F24-B32D-C1FD552F7E51}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Release|Win32 = Release|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {0272C9B2-D68B-4F24-B32D-C1FD552F7E51}.Debug|Win32.ActiveCfg = Debug|Win32 - {0272C9B2-D68B-4F24-B32D-C1FD552F7E51}.Debug|Win32.Build.0 = Debug|Win32 - {0272C9B2-D68B-4F24-B32D-C1FD552F7E51}.Release|Win32.ActiveCfg = Release|Win32 - {0272C9B2-D68B-4F24-B32D-C1FD552F7E51}.Release|Win32.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/external/libtommath-0.42.0/libtommath_VS2005.vcproj b/external/libtommath-0.42.0/libtommath_VS2005.vcproj deleted file mode 100755 index 7162185..0000000 --- a/external/libtommath-0.42.0/libtommath_VS2005.vcproj +++ /dev/null @@ -1,2803 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/external/libtommath-0.42.0/libtommath_VS2008.sln b/external/libtommath-0.42.0/libtommath_VS2008.sln deleted file mode 100755 index 1327ccf..0000000 --- a/external/libtommath-0.42.0/libtommath_VS2008.sln +++ /dev/null @@ -1,20 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 10.00 -# Visual Studio 2008 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libtommath", "libtommath_VS2008.vcproj", "{42109FEE-B0B9-4FCD-9E56-2863BF8C55D2}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Release|Win32 = Release|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {42109FEE-B0B9-4FCD-9E56-2863BF8C55D2}.Debug|Win32.ActiveCfg = Debug|Win32 - {42109FEE-B0B9-4FCD-9E56-2863BF8C55D2}.Debug|Win32.Build.0 = Debug|Win32 - {42109FEE-B0B9-4FCD-9E56-2863BF8C55D2}.Release|Win32.ActiveCfg = Release|Win32 - {42109FEE-B0B9-4FCD-9E56-2863BF8C55D2}.Release|Win32.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/external/libtommath-0.42.0/libtommath_VS2008.vcproj b/external/libtommath-0.42.0/libtommath_VS2008.vcproj deleted file mode 100755 index 205aec1..0000000 --- a/external/libtommath-0.42.0/libtommath_VS2008.vcproj +++ /dev/null @@ -1,2805 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/external/libtommath-0.42.0/logs/README b/external/libtommath-0.42.0/logs/README deleted file mode 100755 index ea20c81..0000000 --- a/external/libtommath-0.42.0/logs/README +++ /dev/null @@ -1,13 +0,0 @@ -To use the pretty graphs you have to first build/run the ltmtest from the root directory of the package. -Todo this type - -make timing ; ltmtest - -in the root. It will run for a while [about ten minutes on most PCs] and produce a series of .log files in logs/. - -After doing that run "gnuplot graphs.dem" to make the PNGs. If you managed todo that all so far just open index.html to view -them all :-) - -Have fun - -Tom \ No newline at end of file diff --git a/external/libtommath-0.42.0/logs/add.log b/external/libtommath-0.42.0/logs/add.log deleted file mode 100755 index 43503ac..0000000 --- a/external/libtommath-0.42.0/logs/add.log +++ /dev/null @@ -1,16 +0,0 @@ -480 87 -960 111 -1440 135 -1920 159 -2400 200 -2880 224 -3360 248 -3840 272 -4320 296 -4800 320 -5280 344 -5760 368 -6240 392 -6720 416 -7200 440 -7680 464 diff --git a/external/libtommath-0.42.0/logs/addsub.png b/external/libtommath-0.42.0/logs/addsub.png deleted file mode 100755 index a5679ac563e6cf347bccc70fb4694ef684375ffc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6254 zcmb7I3tUX;`yVr7R7N$`)``-nwhOA0qN^I0F2hu$m4wdJE+R!j>0(9~#fXZWwrFe@ zY|#>OTaL8j(n#*2fdC`D3cxu5CLEa<{xF$%qYS*tJ<4Q+pUIWY6p9XoJAaN}bbV*j zo5(hMb;06ocdyE9y4BFDSSBUAD7)sw;oBU1?c66p=a|M1>6EV@TXVy<$3=G!vUYXT zqni#jloc%e=vsD43u%2rNXze7qMxa88aa21Vtu=Ee`?6zYRANkgYuG|1#Lg@LqfS| z#=eHfUTwDT-Y@-l+jRMGXk0*0MU$bj$fsGS`E`E(4~O?}@Xgk==~|b6#p=rAmPYn( zk;}KmhQ{Y|vAFkF-z}95b$b+-+174urZXlw4*C1|IXRx3iV_V0IlVo4cvCE$5gi-$ z%;jc6FK=d`aqA#aI{C-6fwT=h(Q8ez177BuN|l*RUA!~*hQ)&slZUom53jW-F`4@K zz&U4wu@X8>D;J|PJ~^X4_ar(<>s=zu=e?w(uWKadGnICBnT>D^ouQ79M|Y>X0_lda z4EGIpuD=l_?B1p0M2(P6X~-Yxc}mn7j@i-hs&q&5%@McshaG##x$umw_in9RrS%Ja ztt{!%(|a$5yX~m7d0y65G#fj!Bjz_b*2l-hx0?$WBZw2)TY6@^ z^yk@B8nrjz`!4Rqh~42k>c@3#wD}gT<*&GEU!U*#=&V8@$NG4D?3VIsyAxp*o}|H+ zpsm~hZ)x7SJc7W50h2SES2-y&m3ZmxT8z=e-T7Z|(;4)R2Y;HtIGE)!@2}H;WATqe zVE*F@g}FS`;;(dlrQyFF0_wTtd6fb}iK!$aDAWR=3(_<~1%#Pmgr+2tPqV)c4Kv*N z;%mhGFw6ORjfQO>2H$&wn}LNv!IN@_+xriaG(8D&Qjt2Byrq_33eC{ZsU#?Yg@a{- z#jidbi^o*$mQZQ>lJ?w!VQgoNf@n8WBw2XG6!*ZMbjOBekj#}6rGaO>?yP%g44}HZ zPGvv5)L>WAz&k{T_~ptS*s-YVkyM(|*y6qIu)er4QiVj$MwJgKbRbuioKX(uYjy13 zQX_L_qoXE=r~l(L^$QENf!L@+QqywU&T1X}u~!Lj%+0)P{07MYfO4HqFRVGS}>q>Mm^X@E#Mn21z^oDO$H z9Z!PxS4WJXTPy#QI|Xx56Guyni~bk!CcpnhW_V8wE2w$9N;hR^V%p4^zN*%9)JzXfF*&P1-`lucZd&X1+=|j!Vx?V4AG6eno zLA-DoSAf=T#Udjz!ZOJkV|xx*D;gQaIIazwkT$Ki?}qM8K*+gInr@dX3*lp>7QSj~OD6Hf zw~4+U^c;&(&*XKG3FTwOE+$B>@mfoiW!=9?71Y@|w&T&7`o|N!f?}H8( zy-Mxw;ID&pbZ{vY$yOh~Fgx8g4m4fk+GbRIs^&V7QbaU{PazX3K=-fP^QhV`?+kZm z2X*uMg+8V+d(m2NEK=Sy@^*nfAw~ODaWG{GNChUwP_wo>0C;Cqe>iMivhc%s&n0Dn#<|AF_3={)QKisy?tBcl@ST4X zs5_3}H3_r&V@MV|QzKAl_v232`}D!lI$>IK1?)xN&}_W2w`!}^06bU`0+dL zZ>hRserY(=0AFIzw-i}xZ`q>P*>LTmOVgPv0q!{+rX=-ScRur)+F;?^4ZzI4!MDsk zFTYKn&Z{Ksg*gUs%`RH{mv3etVc^BIkSzLL9_ry#^u8JdRYp`%tiD-<9M{C#@2`e? zhP@N|F{0XOEX<$`U=cm7k;_N??)c zr4glv&+&ObmHEP{ZJaVVn&dIGU;c;#Z7>mUH}%@5tEjH$CAWzmV!*AAe$R8*4%qit zu6_VlcyZSF0g%I@cd7eAe++IVoocB{ZKGgLMZbp?;>z2QMQ^8VZXya%v{5_s9Yim* zZ_8pxLJ_m5DyMNFNy6YjW0FH{+}wQ!z8p4DEyfInM4QVO*RfoOdg0Pnujd3*bmM21 z!Bfkp>&d|8mt7YafCkEGA)~1)S9ne?UMg2un2`JHip|L^gudFfl6Pe7nk1obVBu}j zB@eq&w^$J)Ji~c+)H)zo_)NQ_vR#CtzSs=VdF=?DWY8@=+BMpXFJ6Ip-<|6L2ubZe zsqj43nR!XRn}CES!HsezNO2BUSpWq|PXDyo&U1LIJHIuT$ZJgQl6MMO6&2WwB-~ZW zLR*ixL&BaY#4NVTV1h%%{WVV1ejr(xDSX!XlVR7jrZU(P=3rMpu`80~FBB!8$(w_) zEwFI(odWKQ{Rd80a&ByL=y4NSdo2v;uv@rodp@vo3df3HT0B4i?1k_5oV|QjH`7rS zwv`;%B;6t^R(xD|gWl0l>B*#Kt-t7(Y+VJ#018j?#_ zp(3Hjq16FQTEj~9z(&RZpIM*AZCns2+=NeCt{%-VOa`7w>!Ah$&siYWI*i``u z^G;78Asdqg$s06Y6U#yXy9mN_Fs3ymmGUM9Nt;8GP-i*?l^2og_$NyhRclCXk*#$X zm(Cb81`?RoY*d3Jaz9Clqo>G8L-;#N`cllN=m$f%qpj*7IHp`2HSw7MNK20#pF_$d zgS0dzft})sE^7#nE(<0Zg~e|Frj4P&wh(7o zu;_10=e1WwKbj~!I&4iw*=^z;0>^J9h&+NEm8i?GY1{Yso{$XNm zdPKBon~I27RBB!G5x&K+%HOWz%E?R#09`cQ+WRJa18PO4c4<8qW>V*+NbFmtq0~eP zl%WalJ-=Y05elWKS}P)kdJ5)Ol}xki)yDsnKuL}`Llz8{5j{?+*n;#(`kHZ_xZxcgAEJQd5 zat12rgxI>n+xFf$*zrcvx(YJGM02oOs4Rqm?v*c6M;yaN2J;}ldAn~RAy7%Pi-Dg_ zXF$Vgg^6yFw4AjzgoJO*3Gp7nAoWGzA}|*wN}^Ll5S43aWKE@wH6ml%i=;7oS-L`D zu>AOw{8%8de?z)|b}P?M7YO0pUMyL~#W>$XtmEoASuXo;DKYhGtk=YwrLhpR3jfF_ z{+M{}_iqo<8S^29l*Ww3;IiNr@&j1>5~P6$`F)GsgXs*F^cfOBl9_SZUjvEO&sp+e z0U&)BobK@aMk)ll_-iJ(Ucu5m2!6G73q*tft{H_&PrKC?2kDxU}$s0 z!yRjl$Qd|mBO93zw;V1qXFtSqSjdIxGoE+m&>2(buRZ`Kaft4*9b*~wol*+m;5_zP z(vks$ZNdkF5BxF1hDzJ}HfMWWB|w~=1u&UA*#@{wFXZ3#babd1{8gp(hcg-2M zjI4E6I=Je?K{L-y<#6-#@(hrOc*eurhGC^J-(lNvnJQ;VoZAZV=KNcU;h}b+Y^c zSkQ3G8SV#{wR(&0o>xXB0WoQz=G8+TF?;CmZch$mSG6B1v|9CRz0QtTJ_)^TN8cnp`OHMdxfcvM|~xbxJY>GTr+3p7>NKPHwu{nVy5eA}njX25Esv1F`Cw$AsfhW4eN zSd9hGyw042?+zMTmp>HJzaT%(Z#>WMN9;-2wJRSCtjC%BJfyib=JJqg^z!qSua^|X zCU6`3tGlZs`(JOl`mU#Mg5D`-X+{3q$HFv6SyKPBs&%E4zjOU~eDF6{=gL#1>x+Cw zeh6@CGSv4jIpl+G8BuN^{Or{h_YN)Tv`Xl=@GbI57|6CL$V=39M!&hYQ*>#&lWENQ zBV#Vb^)IlBFYQNq`d$kwFKjdo?_chteq4rb`AyclzPbPFZ@&~u-ka8eR#z9dxZa5e z3j(+Abckve*{Qy_qm_?j$NIP?FXLmWIWM}$4dgo1F*@GOQ)2cR;B{A~e&{c%^KseK zclhQuqw0qiPZP7?_bFjaPv`7a@%Q%KEK2O&K67?w+R}=~mF6hA2n!x=QrmYm=2=2S zdBUW@DKCG(5?uPn_c>nY?HEqkG?@0nLHkX_#g9>wXiVl-)sABZ7keLShYso_jF)~+ zRA%9G-(Js$Qtk4=Zjg3;6uXdbjbVw3}-+e-6$940b Ke`+qa^M3$0ORS*) diff --git a/external/libtommath-0.42.0/logs/expt.log b/external/libtommath-0.42.0/logs/expt.log deleted file mode 100755 index 70932ab..0000000 --- a/external/libtommath-0.42.0/logs/expt.log +++ /dev/null @@ -1,7 +0,0 @@ -513 1435869 -769 3544970 -1025 7791638 -2049 46902238 -2561 85334899 -3073 141451412 -4097 308770310 diff --git a/external/libtommath-0.42.0/logs/expt.png b/external/libtommath-0.42.0/logs/expt.png deleted file mode 100755 index 9ee8bb769feaa56ee7cffbbd5c7d39ebdb4799d3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6605 zcmb_gc~lcgw+~4STVz!XxDXZtvPgrdfGj~}iAH3AQ5g^$!lodL;Es@%L1l=J7#)M6 z#8DX-cTf=#XaOT&+yEC41P6?wC`u4Sz!f_JH$5B3sPhuyGnphl z@I~U|9Y7!FlW;z&07!s0T%iDCuqp0$3$1DinAC>sk_t#8|~y=pL}C zUf0{KzcGK#`q<&zx#k-fq`yD>7`4!TH=~iy z?|aD|;j60TX>q$tSCMjG-zqnCNBIkbP6RDWRcsA*j+!D)`hzTItdwMLraRvF!)h)* zwSyM0g)+@+{iDm?Z-cP+`U#XfYqNJG22v&C6O^wg*~a0~TQ3bDmxh<2DYRDp2E}SV zPRg!$QPpB-eAW`V=VSNVv{x&KcNi*0--vJgwehbPiF+&!x3d@JSd_%j7Zu;;AvW!U)v-qd9ct%I-57Z@wtA%FUBm3CTPpPA zqR?M1Ki)HLX(|`PW>Sh@OpLo*sd5%4O^jrtY?Ml~c&uISmYw+Npv|x5Z=S}MyT)}f zZJM$LNiSwTZJ!s0hQ!~mqBKs+-_a7e&jfQED6g0*nmQXGHbZXSU76w>7_n({NNayv zl{|TS-Kq+!@{!m>i25P_apHZ}4LM1ZZcY|;cQ23|MUCcMD}HoGtMK!J&%%ZJ!!COEO;gtS$=eb7mB5 ztZwSB{DBBqi-9RoX$DUs%AMn7wQpm)tu^}Q&#H4+@7nb`CPd?unf=VqxA(}+$I%Xn zIIfz~5$$(3gPtC_ccobi!}7^VeJQm!%o>-p$A7kKpKQi)`jPZgi}6%9!@gcc{sQib zVQp{qrTIZA``&H3(7TaJn_21Mw8^!rbM^Jc+l~D_wa*Q)i?a|GBYHLxzjXPbJerHa z>W67fEl*%_#~Y>(^`z8>ZfZ6@)4N+16{JqTm`ay*4ec${=+h9&jl6+VGBhINtAO@b9Z|-CiDUku=l{{EWib9l_~gF{>n;252xRh&^pf^8 zn?ELzDY-E|8r!tZ=wQp=97;D4#^Z1I=p_N z_1h`9z{h)n|AkM8dMr2aDn5go(^Ui@D->|$<70~7Oo0V^y?-I~+bMuZ@=rwU+t?3Z zvjwXDONRe3CBE=a@4iXsgzpnu;E1Sw4G~rjnbI`nTj#Kf)@TT-zG7D)!kMi+7H6%2 zNGq;V5#nP*r8!I#ZT%rNZOPa$XbF|(UE=ZS%p%cB=cwF{*`eb0D?N+w4QN$Nxa*>W zIA1k#+jhqi4;>H5BsS=II5#i0Lv?bV$x`W8NS z$3N?}z~Ori9KYAsX8afbo+$qp%D44F7V`dCdluhw$lde*4dQE)s?dM>iPSlM!7>&*52VnXd1JAoU{naQdsrk}+GNp}+G?#djiCbGn2IflkkCsm- zD&(=T(t~lb-nETc=Aa5+GLiUK^5K{*MhO0t9;*pT=tP_GsAPJpjilEcxwkfWz!a5- z-+Xkn<}j!}ClR_~9P7Fs2Nlb$_u-@{a`Cn~>#KGaj-xrLa7zI#EqSQM<@sRSdD^>I zqP&bs+odl$enE?&B~k}vCmscdPjO-8I2u*9Bvj*^6@b(Y6DGQ?Dw7hOUtGGtNse3s z{T92@D0j;Q4$+h5MIKHces2d2UA$7HYpG6G;a-JFh#Yw`>E5md3WFjcb>Z%@dNr3yXa1Dxs+>gr|G5ed4owvf1de;dMD+<>Ew< zgXQEg-r}hm*)q&A1X$cbPD(bJon}ZBxA>}c!(vopk|!$8 z!E2mqV*rz!D@8C(%XWmcn>|#4n_E2S(tGRCI5$7$9rqA`kwYA4fmgQUq#0!S^-JKP z;67x1f@p=MC5V2%+8cH0bvUCf%CiJ^ErFGD%XdwLH0YN*)})BG*djO8OptqA^!GDU ztYK?tUv zqR#gBIZu{~%2#pQBY(zxI*VSsdvh3{l{^jCS(Nc92#5V%fh~Ik$;?BaSw0oCtHH2}(x_E4SM3vhFu`oo* z%A4Dv%qVUe4Ew3!%xU22Bv~E^IHbyicuD~5Wn17k*aU%PpG=fxwWXIeJb@uqGj$li zwDkUg<9hJv#udPZ$6Eq%TymT79vdh*c1o`YTMiplQ;yt7*zbhX(rlt*GKf9jYuTP4 z=yAw-EU9<~aaKR46c>YZkcFq=l?TePt_YT6ehNH+Wt|5)3Ez;Xz-2Jk!Az(xoQZ4& z)kKVwF5x}qUyw+jljRlA5J6E{#Oz0JfO~H8I4l6}yj(t|2(sKLfhUB^nRJ$=!`L696D-XAK}}&}9?RG&4X~ zD`AeHD3!1ozQlMc9ADs&u|fozCswYk>xWRKLj<3Mw&(zy;qI?Wfi3oDm6e7q2uyc6 zj30(Kn-*F4HPq#r&|~=DsoQrBru*P{!4jQsu+#-Y|KKQ^hZv2Fd>R@}O}v3$tJsoW zg@2&P8}|qC-cFhkd0ZtUM-#X@sL8F>Wn^F)l%!kry=lK@{jlY1zxTc>_R}l5J~%H~ z--}g875)w&96XB7uf62q$9Nf^WiPnp=MHlBr#iQ9XCY5d78EKzigyJ$`h>C;K-v}( z#SUqE2#*z6AEpnsBQ{Jo>jNxyVchdg8AI@-T8Qb7hcUxw3*p0#DB04CV0s}DFEnx% zud$Yv0J|qFq+%ck4ETpaW3V3ksH_d46~GJY$I#TBFnEp*q?;2ciibZxirj$|5YDfH zymRZna!rRg&O>&E7D%U|1F3(C$TUO$i&?1f5I40D)bMdrOQ{<$1rLZ%YVx~tRH>}c z&?&FszB5)-_DG$Yi7hxd)OfqbZ`ZDbt4nDUCHB=Wq9+KzxN| zKpJexUQqfG-ZcYA=V5hzK-z~QEI@2B-%lUsLSrong)akjE5Q6Tim(vEwu9U^vH?~n zI`@#SFa&}Fi?5%p$pA0jyu(y-W7Ql^n3m`>S=fC|DHC(02+tro>3A|j6ufiGbQ;!e zi$bwJ8aBLf`pv~!vB8qh?|&%?vp2^0Qkk*4hcM}_N!aRw6_&|U5*cs!}&00=7F zsv0`{mF^uJ@yc{Zoz$g!hr9(fOvGgzYdD($r_{KZkte{PN)`@zOo3P|kmfvH6I*C; zhFy&}ohyd`vWczlmMr_$TRKN49d8rP zkm0VJuxQhn+B#aq>)LHDQkhxj25hlJ_ouCnUY`{Zo7bNfW>3RPUz~W3Pgo?d1;e#P z^RqPl7t{B*8&3=@J@N&+uPpi;KzxLne^0A(lMT7i1J#)>d!xk@xT9B9V7YpOD!-J; zxljPaK&S0$KFHYZj{c;{yWL})ny zJosxMTqn@hr%EEbeR&H32{|XyiRq;5wtd8M@?Nm)3D=&@-%Sh~yd*=9R0Qra<6;w7}R~PV-?wJ#w zqpc4Tw!v7~o4#$YezrCPv#p(SSGwoUV;fZgzKh$ED7n50NJJV7%k1(ZJfncU09Ih6 zU>4A~NSZlo!xCbUy;68r2wLa)ff=Hlk|T);o+wp<@N(VJE71{eJEdh!45(`G*lyc_ zGNrA4CQ#oxS$3*x?OuR@@g(0_cQ*uBz%2wW^)dGdQdlv#H5ohh=ffubBdIYa2qR$;HELVXhtYG#mJ0EEU3~eE?<-%F z9pgEX7kE7=yvUwt=%dG&P%v;kYMzV7f~EwtmEWPU%k5*z{^MD#l;LT9OZ|Q?7-WCU zi?^98&YRcqI_W_xCDBP&?*GpJU{q*In!4aFdq3-l`3nC$GL}ebRk{(6Ut$&3V)}2g z$@j{y>_m5TTsL9X+1oc8E2+?ZIidaIh(C$>5rby$MqTpvj~+YuWar`3{?l{+dateC zrkOe}v6)ieI;Mg4 zYY$(e)VEWr<*PqrRH(AFA`=67R-ej}CfD)t3JivT3L`Cm!#*P9K1g9viI}1SY`UD>6O%J%E_JW{GzOZK2RGj5Avb#Yr>1nhnRg*Gj{Qve z=5N#VZ;de5KAJ23I5pwG&cZCWMXf{Q|NeKKMC!=RFvH?qZBo{S)i=y`IW@%~UZULI zWk`!0`7^CkUOAEWDTgzVCQK8huSWF_YB8eSkkEA&J)iQbQu}90j6a?X8-^I diff --git a/external/libtommath-0.42.0/logs/expt_2k.log b/external/libtommath-0.42.0/logs/expt_2k.log deleted file mode 100755 index 97d325f..0000000 --- a/external/libtommath-0.42.0/logs/expt_2k.log +++ /dev/null @@ -1,5 +0,0 @@ -607 2109225 -1279 10148314 -2203 34126877 -3217 82716424 -4253 161569606 diff --git a/external/libtommath-0.42.0/logs/expt_2kl.log b/external/libtommath-0.42.0/logs/expt_2kl.log deleted file mode 100755 index d9ad4be..0000000 --- a/external/libtommath-0.42.0/logs/expt_2kl.log +++ /dev/null @@ -1,4 +0,0 @@ -1024 7705271 -2048 34286851 -4096 165207491 -521 1618631 diff --git a/external/libtommath-0.42.0/logs/expt_dr.log b/external/libtommath-0.42.0/logs/expt_dr.log deleted file mode 100755 index c6bbe07..0000000 --- a/external/libtommath-0.42.0/logs/expt_dr.log +++ /dev/null @@ -1,7 +0,0 @@ -532 1928550 -784 3763908 -1036 7564221 -1540 16566059 -2072 32283784 -3080 79851565 -4116 157843530 diff --git a/external/libtommath-0.42.0/logs/graphs.dem b/external/libtommath-0.42.0/logs/graphs.dem deleted file mode 100755 index dfaf613..0000000 --- a/external/libtommath-0.42.0/logs/graphs.dem +++ /dev/null @@ -1,17 +0,0 @@ -set terminal png -set size 1.75 -set ylabel "Cycles per Operation" -set xlabel "Operand size (bits)" - -set output "addsub.png" -plot 'add.log' smooth bezier title "Addition", 'sub.log' smooth bezier title "Subtraction" - -set output "mult.png" -plot 'sqr.log' smooth bezier title "Squaring (without Karatsuba)", 'sqr_kara.log' smooth bezier title "Squaring (Karatsuba)", 'mult.log' smooth bezier title "Multiplication (without Karatsuba)", 'mult_kara.log' smooth bezier title "Multiplication (Karatsuba)" - -set output "expt.png" -plot 'expt.log' smooth bezier title "Exptmod (Montgomery)", 'expt_dr.log' smooth bezier title "Exptmod (Dimminished Radix)", 'expt_2k.log' smooth bezier title "Exptmod (2k Reduction)" - -set output "invmod.png" -plot 'invmod.log' smooth bezier title "Modular Inverse" - diff --git a/external/libtommath-0.42.0/logs/index.html b/external/libtommath-0.42.0/logs/index.html deleted file mode 100755 index 4b68c25..0000000 --- a/external/libtommath-0.42.0/logs/index.html +++ /dev/null @@ -1,27 +0,0 @@ - - -LibTomMath Log Plots - - - -

Addition and Subtraction

-
-
- -

Multipliers

-
-
- -

Exptmod

-
-
- -

Modular Inverse

-
-
- - - -/* $Source: /cvs/libtom/libtommath/logs/index.html,v $ */ -/* $Revision: 1.2 $ */ -/* $Date: 2005/05/05 14:38:47 $ */ diff --git a/external/libtommath-0.42.0/logs/invmod.log b/external/libtommath-0.42.0/logs/invmod.log deleted file mode 100755 index e69de29..0000000 diff --git a/external/libtommath-0.42.0/logs/invmod.png b/external/libtommath-0.42.0/logs/invmod.png deleted file mode 100755 index 0a8a4ad77170380b229a454283696e6cd4910fd0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4918 zcma)93p`YL-#>FP3{!5!5bcDf3vtN3FqI|>t(41R9AOf*=wc(6bEsUJvQ}kKnbuSC ztc|Fx5JyT#rBBqYHh2qkccfL^`AdEf?dI5>fG zAe1LT36uvBC;{OJgyRr`;s^?%5RX7%1Vs^u2QCzt0M9BYf}ns)nj;_t>MF%~IEqMc z1nA)szyO*E2S_0taPfE?9uVgsq#C$*9FzkH2uae?fpa(z3VcB*-U0M+6v9!20FeN1 zI6;7Cz?FcAa1ba+fq=lE1ji)=f{-sLL`WdCqeB9I1P26!L%4*)k#GnU80K(DZ#)!5 zNUJC?jsq1QApt*xkVF!|s>~um;A^>6TOmlb!P#-i+8qyGwm*!1gP`?i{ z;F;5$yLg8-c9WWQ@F-W}iWm<%hY0L%bRy~_*3Y2AwfPG&*PnN+a5e9$8)bSPxY0Ly zqo#etArI-{=K7nPMKk)?CW?A;>DoD&E0H7~pUJ==OT{tO& z4revAg9`@A=B9T#gbzN5!?3yov-#n9w*p7gKg7PT=*+(R;@*M;3tt2k(itjj9s+%f z*uSnJ7T@Q<0B{A?IB6~*{P}?A){$-f-=_$C|7DUUCmCD|YeW9&_z6BPrDokzZpxyH5ww7QLa%I3R>|J{Xvx8ERges?-vlc4lM9i-Dyj*l9VMw;n~F#p0FYn`-2P)EO=?l*ke- zU`t-AIftMcSYzrn-3(~eYB*2osv8}1>>&=BD~YlPsJ~OYehibe)Afycm9y8p?9ltg zU+}~XHuj*oW;=xxXojk>Q6ZL-BN%wASe0vI)Wl^CvBf#pT4R255xULHTokpISZNF%3)MRWj zbl#B~sv$m{yTwe;?B8bk^SR1UA9Z1TPQ_ipEQ-Gyyt8q)EBlEt>=Rf^GiSO8{_vf~ z@J>i7df2`kQj!<0*mQ{(fi*rPAfp-L_c2}!UznH7Jh3zYnGaW1xZ+&aHp^NzSga$+?JpJ;$5Hn2}+<^5YgTum%;I_E*#%oV5GU3_W<9KN-# z_SRoA2XpR|r#1d09dMvz@w`H9-e#OgRW5)TMLvMoHa@kQ7kly-2 zugv01Nd^uX%@hwMNJ0Bq`yun+jxJpUgol{*%MHf+$`iZ){Nnz*PLch1@b1bYELvR@ zeutNg4_`RV>tYJe~q2j?qVXOD&;1MO<_^qvn4X6;E?wW~O@LnM@@ z2F6V<8i+Rtdj|DKC*4w#xFZ68<%$=zE;FIO<+wz(`41MxqD0$O>c3?-Ux~SbBIE3i++F-XP7ZqS=d>t*G zSa&CSMJ6KY#o1&NkusARS(6#$qCKwh-!nwxN5K|nMCN?L2M-a!xF=Xh$RmOk)_Ag^ zxG}jlbKf)Xujks{o%>E zSX;MCtVt8@9JThC@R- zY<(7aY~hn9EpP+?IgYE6Q$C2?&`6DO2`~}Jhr3Roja6iN_|vatNX$*i-H~LFB_Pdz z@(mc|c}=9sfNMV)w+;YNjt3|6J|5hc;mcweH!~5X%sy#`&JToE8IXyBXbY!;k!WqP zC|#7Ao~mpq~Q{|a%4L)kh_2MY4dP@7bnW} z5?&T&Y?c_Hcc+!ou@_(4wwt0Y*YhB!IW^WAiqjQ83)vmK3j+)3c--y)-|;->eok+i z>;&;oHl)mW4ZbC#NTU|W+Jnr`T?Rgx)?9!uV97vIVeckcBms$%6C_zp_jt zjW6KzEQdD@O*?EC^BYuXbJlFl9J$7gm}0o5aC7=BhDLzi@k8wOl68pjBBO&^?xyza z_0t&DiZ08&XKAgM+@UAWV$kbVXw;xo3Re4xnqCH9kKmo8hr?1c0cvR!j3fpCn)N&c z5C#~zZ)~cajJFt>*0bph!`U*aPMc3-fFm*Gz}f)adJY`QQg8{_r>aHYBP8#PObTWb z9c<3Pj`_&$Q9+L2`RRJ+U={WQK7WG>J9jyG_k1R5;J|16&5KynW#xhObAi8v1Gh*! z1)>`qxcE=4%q2)^=u+^fVzs|AW&dMc%d>8CVDsl9aGyJcy3FgiOyzh~BNIEeaRY0i z0xO)ga3wHSM&3)qHZI+w!v5hPmu02EI^?dv@;51%CXXGvZ`QO4uxmHz+fZrOg)7)|#H9NZVH9NR3r;xe-^@sMktesKh#tlO?(-lU+_vfA-Qi>$(+A>Y{YRL zzvWB2r2Tz7`y<2AV~MNsg?YZ;g-4E^t=T8)%_;B_rZ8t4|7@bK(C&~|8$tT{Bm$BPW2 zTDz_1wG@1bca*J*d0#HiwKGvI9ro4B|rIEqOH}=Q7!iw_G9V!HTQk( z#_|Uv-VP7GZ(Z#$mbiKBK*S>ByHni+g)vi4C0+{a8jSe3p`(}>D=BXp>grps%xy0# zZQok@CM*A4yK6>bf#k96PB^dq{SKSg!==KSg<<7=fzJm6EGcd~#~Ri1pNvL~O&#;K z6&Cs)X|0zg4@Qh`khmp`oquJz`l!?}2K(m6v-NLjz5#;2rwk4r-C#lFyqcrVwvFId zdWmaRuiQK&NCho+-5}uO>=H(P8s5^bvo-Nv&q#ostG$+bpWPT-+&#Q->+staJ{#*~ z)%QIZ-Fm({{NYDpXKviH-28A`Zj$Ny=I6>mZ7+^IQf2?48^X9QetE0^qjq0cQ-rki z_0wyrY&X*eQC_AA_h{Ok@9jLh+p{Z02JqqFZAI>ef5*p8d7oMLU4eVe@PpUc`tUZ} z(|*#&rTm%-BJuSjuk9Z?eG9Bg<8%V~`93+xR$k_~0;|wR{Yu@^-m%|eKjv7Bm{MNJVL? z5`rKq9QHyV1fgIEBFCO22WCnSg?J$d$>K+@pNB*u0W&!{Iq*gx2reNI3DVO;xPd>2 zkr5#wj1b%{2bbV(hy<4)1cndtu{G1I0#0(3%^LV^Av&loLS2O_Bq?m?USL1Zb6Nlt>6av*Jhu(WP(}&iC8-^nLS@ z9jDk++?H;t>yyMqR6Ra2chb@yQ(_)R*>ySuWG&p&BOhRYl*vi`{wvf{j%zkN)uzZ9 z(h@u=FO554zzlgvk)w02mz=dg*C?|7Ba%MaA(!9H8r81u z70Nm0$ic9SJyq{`DOUxX5kZ`TErcuzCFHi40X%Q@R>;2qQ7vE`E5b6F( zZ1u$;fs6Wt5m5##g7#3UG~-+hLF;~}zj52?je*C)Rau^+dfd3+6{O%kyDqw*N$1f( zFC}YeU^MR9$fmsnTQ_U}F4rsN8$FbK&GCa}&m|2`vz)(DM|~?Ji|rpYR=3qov3E#$ zj<9Ni1x+q}>m*HNmgi)FPs!_<7?Z@(z!1iT!l?H@7e4QvzHDC=X)dRzX=%Oqnq>GC zv$=bE$g3vF`z5JiJJRj`Fo}stdlNs`Y3z?Fn6OwRDA<}Bb?v+`l;|$vTnz`KkMjhK zFzMXQNOY^(j%H?O@FGrEx%dm;JX7)~&aWYvT|dPnF{o%NB1d0VT#?X}9ejUr;O%P+ zOn9f|U0vkuJxv=vF;^G$S2;P6StsLOhs9RLjeYuDn~X0#;Ive5!(!t*gNm^uUpm6( zZed9x)+I&npzt;+h)O@w*3z6thGsS!Pfv;7QT!`F`<`})4!Xp4_u0#EQ4}3@r%k~> z0#)jmFN&q1t1MaR6Cz4y$DP=(y+Vb?j<2kc%nsiXDx zaxS{Y5p0~qV-g61ESTX?IpYoF~yq!PC%NVX0f5gYhy|ZlP@U zPX%!Z%m{GcQI3hrWat15lX`H4P-Bs0W0*ve0t#R{5uWMVkDg)6oLmEZB_bGJFB9iUi(rR?z(Z{zl z*8#TR_s7g*HaM@Sze{0cVmqETk}3}~J8x)*tUl3&8}s}q=#eM6R=2n+bc;AF)mc^Q zE;KssBDkggKb<>H8~5#BGB7LF$Zzlh5)THkHn+D>$|6f1>6RZA5VjxodA`*+ty&U@;6Rof?5MkuINicCcm@s+& z&X)|$?}-7|>c~Njicz*@Z2SrX`Yoj@j8ba?P;L!z!)umQvQMsZ#TpqkXcN@1kZYY; z@Qw7va=i4p=&Q8@ThF9C5WCxez-uUiTb2*pkJS#aqcPMy}0bTdq=Cc zJJ4!DT2->AzI5RHZ@5@nlZFX3mJ4;zkYCwzol?_n(Zxc9RUhp=azVKvW36b%3ICc{ z56?aaY1L8Do8(rTREpqQyzxKEPs|5MiJKt!Jbli86~Jk|k8;bv0^W zwT58d84o{ETKdwug7BG30cU~HKLEd|D`T9(P7x@x zWX(cm|6749qw&&YhD1z2OR4Se8cwG)Y0}WYG0j4g4pKNc2lSrr@+dw&5esOf+X;tp zmqf$;W7pr4fC-n+ZM|nyWNFa_$LqrHbzidMPaQDa>- zfxOd!Rb+SPO+@BY)aUdJpVX>Biqy0X!A>G;o?cIrK`m7B7jC0L&AvJy>U;&W0qts# z=GEBApfD2vyP!LzzbP5iT0GUPOS_sww^)IZF{X!{*)aSC0lUlwunMBR%Gi12w5D)` zv0k40#j5ZcgR>lzy*4?LHaU+B3Ea}gCD-(FJ7!TKA6-9W|NNld_b3C;K8nb=nSf1K~;$%6x z#WkwPV$VLff+lE@w~$1la~ZsJCR$Zo-xG*+vo*lwvwemSDI<@>Fr{*JGxBueK>{*J zX-}ZP6z+|+i)su2#nKJXxF^3Xc2ERb=VLvFOC81w)pI5P@Yj95n~A^p!WsC@XFg?| zHRb`rPk8lv2UyDAl{3d5(#0AiT2`k;Uy=;H9BZ$`#I7cBrz_Bba|Y;Lh#TNso=7{7 zXXS8RLDsG;sRD6w(4y3b0gjE#iu}NtKAH)zrqLl2n<@%vRz4vH`#y<%llv6)V4oIPg%PWi#prR%(FOu|=VM ztl+fkr>}VR!7Rwf4zg`k?da@#=*Ww=kak}HQIg+~08?rZfuhY;*axB;K>pNcw>WpM zb=}U%=r)6(l~Ee9mni+r2inQR7KdAKyIi})f5wws-(v22CNI7GaQeG&@N_wmkQ%0q z@Y1!=(Mu0-eiRc;vAVBJ=cwZr9YbGwO#P~4CLkeatG+V58f+AKQ?TS$ z#-_3&O$Ab^J6u2BcdAyVTj*kajrIJ>3YP3Eq8WJyk z;IQB8F32JiLa)L-4AiTmieN9~-dxOc&slv;xDX#4#b0~%?as?iS4G>h_X7e@5zPgB zDd#9+YMKTn{MldFhu>6Zc_J{$34D-baU>|A)SvhlU zU2CNW2zfZwV=W|~DXKUN65V#Vyp0?QbHtD~0pWY^k$UgGr+lGuJg6ZSJrBVQA|E6w zg4!8u%ou*Aa@mzRdAv*QUM_4;V*j-3?Pb4tEg#tQ&LHEGo%IKY6RsZS_G$6}pke!N zHY_azC|KBI1`%42w4SPh56}4#rQFa2e(FlT&kykA^%tK>_>qAG`S0z1-E{6^fF9f+ z21y_*$iyWF3mGlQi*}j>ByZgl93Z7*rb{N=6p+R{4DfhRlpcRkrt9kNJ(S&Ua z1L%=g;RyEZ^mab`$-iHN^{!yv zD<{lAVmi|(ZGZw|$UlXxA<~OL{Ry>}3w`22jX3HHWRZTB zG(jChf;g#C>%P6d23aq937E83K)e1U^ne@heP@ zEX_Z`;}A$8*Q6N=T$kB3na!#Fq$FD=T`Ki2>k3mHM8>U9uS{C=w=QUOh&1}ngq_jvL{kj1~X}J;X=(y zHMmGs3OfW^Y63yMM9?mPW-Wuj z%sW78Vjr3ap{h%`Vg{g^H=kYs;WXnJ!{uD*n&1Tj_t|FBi3Hlk~R^yI}Y%3g| z&49TEdi%5#p!##vAn28?M*DBRx242c0{)i`S_1w}6x=zPKqs*dDm54e0{g#MiQ_kG zfROcz&FrB}WHJhFQEyJ#sa49Gl30qW*1tl_;t=UFk5y^i95PRJRoYZ{9&)|`0&%|l zvG9sis!`3>7`mlzS5XMGXz>MkaU5t(&32Y_e!f@;7dD!MUWs{d zk0Kq+)P>Hqem^o9n5@f~Py%A&Jx;jkp#}#f(*mDr2g0S(0#C%z!Aws@g<2*3{F^gh zUlj}o+4duX-e+?w3O85KgVG(*0%=D<+C2l8yOOOvWA>4_MHQEo_tP)@aOe3fYUJdY z!%;TYvjU@ZXCHL#%!snS!*mlTri7RHbG%S1K(0=WhOnXO71P_mz7NO1U(YT3Rus9s zx7ltN=wdHw{u<6(8ZpD?=c>H(&vGjZS0)7jP+FcDx!Q`F$IkN9F}29yE&iKajX5Yygdt6_#Nij9_8-&1jmh= z#1%TnLY}pz$m^0sFXpvV0^w|kxZ=svEe!qlt_6egG;Gtt;B79VP=-No>4w-YlANIE z*e+|$<8(O{4DszKYAhDa+b=M;jqL}Ib|2fdsx0iGP326mFZv~kz4yG1&priSzr0%@ z8XO$?wcvp*nK#F{{}Ok&KT_LvObrxn-=fUYNNayIXak`2JNo*bX$__`($Z`}ZFFAW z8l1l((+w!oTEcx6RXet(inbBRL?m&r^0NxCQ3_KMAF%Lj4gBjF@g zre?$1OvifW2Ul%7d}(q8_xb#7(;Vccl30t5TDN9X?EuI1gUq5uQD?)iDxfv>f`M8) zjzt`W&X}ysuP?Er3vCk~Gu5v~w9Ct2=eCGJ{uM41w+*>#; z^y)FuyVXjlr(R}Wov3}tRn3;9c;tNl1Ht)E)llSIxe<5Le%3 zqaR+9HVLiIby}v7d$emvlgzuAYF_?i1hg^BB}V5}Fku%fr`6O_V=BSUWfx|O&Mlu# zutOT`97EE|?d=G5<{ZUZYdI}U54?=tM#>6ZFIhQttgZJjd>dW)v284+g`*hdrbywz ziC}r|hDA!LmNVNe1ZFpOGA+gqgFTF&o`mk@PrM4RkJzxQvx9mSUIgPG1@%ig+Fj1()mVEwU6zw9~_&=i-LvVUmhNkcT{ zmgY#C^N8eV?Z_;ZhiglItaE&*Nazh_IRq`*P43_66J=oH+VarxWmjkP3(~_;T1%Y1 zx6{j}(hJ$%SH-1vxf0#e(Os>PP1E8ctTV3KPIlJbpUh@KW+nKW)XZGRYta{z*z_GP?iHp@cR*76j$(X#q-l;SzU;l_D*FUbb z{O4PLCa30X(vy8wCC6GOci z9*K3aTTlE~X6OtbiTPzx!{}XvaeNjxnx2E0R%YUc4 g4xA5Cg`UHP^M*oSE`Q=%f`AXl!)syw0&L&^0or4D&j0`b diff --git a/external/libtommath-0.42.0/logs/mult_kara.log b/external/libtommath-0.42.0/logs/mult_kara.log deleted file mode 100755 index 7136c79..0000000 --- a/external/libtommath-0.42.0/logs/mult_kara.log +++ /dev/null @@ -1,84 +0,0 @@ -271 560 -391 870 -511 1159 -631 1605 -750 2111 -871 2737 -991 3361 -1111 4054 -1231 4778 -1351 5600 -1471 6404 -1591 7323 -1710 8255 -1831 9239 -1948 10257 -2070 11397 -2190 12531 -2308 13665 -2429 14870 -2550 16175 -2671 17539 -2787 18879 -2911 20350 -3031 21807 -3150 23415 -3270 24897 -3388 26567 -3511 28205 -3627 30076 -3751 31744 -3869 33657 -3991 35425 -4111 37522 -4229 39363 -4351 41503 -4470 43491 -4590 45827 -4711 47795 -4828 50166 -4951 52318 -5070 54911 -5191 57036 -5308 58237 -5431 60248 -5551 62678 -5671 64786 -5791 67294 -5908 69343 -6031 71607 -6151 74166 -6271 76590 -6391 78734 -6511 81175 -6631 83742 -6750 86403 -6868 88873 -6990 91150 -7110 94211 -7228 96922 -7351 99445 -7469 102216 -7589 104968 -7711 108113 -7827 110758 -7950 113714 -8071 116511 -8186 119643 -8310 122679 -8425 125581 -8551 128715 -8669 131778 -8788 135116 -8910 138138 -9031 141628 -9148 144754 -9268 148367 -9391 151551 -9511 155033 -9631 158652 -9751 162125 -9871 165248 -9988 168627 -10111 172427 -10231 176412 diff --git a/external/libtommath-0.42.0/logs/sqr.log b/external/libtommath-0.42.0/logs/sqr.log deleted file mode 100755 index cd29fc5..0000000 --- a/external/libtommath-0.42.0/logs/sqr.log +++ /dev/null @@ -1,84 +0,0 @@ -265 562 -389 882 -509 1207 -631 1572 -750 1990 -859 2433 -991 2894 -1109 3555 -1230 4228 -1350 5018 -1471 5805 -1591 6579 -1709 7415 -1829 8329 -1949 9225 -2071 10139 -2188 11239 -2309 12178 -2431 13212 -2551 14294 -2671 15551 -2791 16512 -2911 17718 -3030 18876 -3150 20259 -3270 21374 -3391 22650 -3511 23948 -3631 25493 -3750 26756 -3870 28225 -3989 29705 -4110 31409 -4230 32834 -4351 34327 -4471 35818 -4591 37636 -4711 39228 -4830 40868 -4949 42393 -5070 44541 -5191 46269 -5310 48162 -5429 49728 -5548 51985 -5671 53948 -5791 55885 -5910 57584 -6031 60082 -6150 62239 -6270 64309 -6390 66014 -6511 68766 -6631 71012 -6750 73172 -6871 74952 -6991 77909 -7111 80371 -7231 82666 -7351 84531 -7469 87698 -7589 90318 -7711 225384 -7830 232428 -7950 240009 -8070 246522 -8190 253662 -8310 260961 -8431 269253 -8549 275743 -8671 283769 -8789 290811 -8911 300034 -9030 306873 -9149 315085 -9270 323944 -9390 332390 -9508 337519 -9631 348986 -9749 356904 -9871 367013 -9989 373831 -10108 381033 -10230 393475 diff --git a/external/libtommath-0.42.0/logs/sqr_kara.log b/external/libtommath-0.42.0/logs/sqr_kara.log deleted file mode 100755 index 06355a7..0000000 --- a/external/libtommath-0.42.0/logs/sqr_kara.log +++ /dev/null @@ -1,84 +0,0 @@ -271 560 -388 878 -511 1179 -629 1625 -751 1988 -871 2423 -989 2896 -1111 3561 -1231 4209 -1350 5015 -1470 5804 -1591 6556 -1709 7420 -1831 8263 -1951 9173 -2070 10153 -2191 11229 -2310 12167 -2431 13211 -2550 14309 -2671 15524 -2788 16525 -2910 17712 -3028 18822 -3148 20220 -3271 21343 -3391 22652 -3511 23944 -3630 25485 -3750 26778 -3868 28201 -3990 29653 -4111 31393 -4225 32841 -4350 34328 -4471 35786 -4590 37652 -4711 39245 -4830 40876 -4951 42433 -5068 44547 -5191 46321 -5311 48140 -5430 49727 -5550 52034 -5671 53954 -5791 55921 -5908 57597 -6031 60084 -6148 62226 -6270 64295 -6390 66045 -6511 68779 -6629 71003 -6751 73169 -6871 74992 -6991 77895 -7110 80376 -7231 82628 -7351 84468 -7470 87664 -7591 90284 -7711 91352 -7828 93995 -7950 96276 -8071 98691 -8190 101256 -8308 103631 -8431 105222 -8550 108343 -8671 110281 -8787 112764 -8911 115397 -9031 117690 -9151 120266 -9271 122715 -9391 124624 -9510 127937 -9630 130313 -9750 132914 -9871 136129 -9991 138517 -10108 141525 -10231 144225 diff --git a/external/libtommath-0.42.0/logs/sub.log b/external/libtommath-0.42.0/logs/sub.log deleted file mode 100755 index 9f84fa2..0000000 --- a/external/libtommath-0.42.0/logs/sub.log +++ /dev/null @@ -1,16 +0,0 @@ -480 94 -960 116 -1440 140 -1920 164 -2400 205 -2880 229 -3360 253 -3840 277 -4320 299 -4800 321 -5280 345 -5760 371 -6240 395 -6720 419 -7200 441 -7680 465 diff --git a/external/libtommath-0.42.0/makefile b/external/libtommath-0.42.0/makefile deleted file mode 100755 index 805c8fc..0000000 --- a/external/libtommath-0.42.0/makefile +++ /dev/null @@ -1,186 +0,0 @@ -#Makefile for GCC -# -#Tom St Denis - -#version of library -VERSION=0.42.0 - -CFLAGS += -fPIC -I./ -Wall -W -Wshadow -Wsign-compare - -ifndef MAKE - MAKE=make -endif - -ifndef IGNORE_SPEED - -#for speed -CFLAGS += -O3 -funroll-loops - -#for size -#CFLAGS += -Os - -#x86 optimizations [should be valid for any GCC install though] -CFLAGS += -fomit-frame-pointer - -#debug -#CFLAGS += -g3 - -endif - -#install as this user -ifndef INSTALL_GROUP - GROUP=wheel -else - GROUP=$(INSTALL_GROUP) -endif - -ifndef INSTALL_USER - USER=root -else - USER=$(INSTALL_USER) -endif - -#default files to install -ifndef LIBNAME - LIBNAME=libtommath.a -endif - -default: ${LIBNAME} - -HEADERS=tommath.h tommath_class.h tommath_superclass.h - -#LIBPATH-The directory for libtommath to be installed to. -#INCPATH-The directory to install the header files for libtommath. -#DATAPATH-The directory to install the pdf docs. -DESTDIR= -LIBPATH=/usr/lib -INCPATH=/usr/include -DATAPATH=/usr/share/doc/libtommath/pdf - -OBJECTS=bncore.o bn_mp_init.o bn_mp_clear.o bn_mp_exch.o bn_mp_grow.o bn_mp_shrink.o \ -bn_mp_clamp.o bn_mp_zero.o bn_mp_set.o bn_mp_set_int.o bn_mp_init_size.o bn_mp_copy.o \ -bn_mp_init_copy.o bn_mp_abs.o bn_mp_neg.o bn_mp_cmp_mag.o bn_mp_cmp.o bn_mp_cmp_d.o \ -bn_mp_rshd.o bn_mp_lshd.o bn_mp_mod_2d.o bn_mp_div_2d.o bn_mp_mul_2d.o bn_mp_div_2.o \ -bn_mp_mul_2.o bn_s_mp_add.o bn_s_mp_sub.o bn_fast_s_mp_mul_digs.o bn_s_mp_mul_digs.o \ -bn_fast_s_mp_mul_high_digs.o bn_s_mp_mul_high_digs.o bn_fast_s_mp_sqr.o bn_s_mp_sqr.o \ -bn_mp_add.o bn_mp_sub.o bn_mp_karatsuba_mul.o bn_mp_mul.o bn_mp_karatsuba_sqr.o \ -bn_mp_sqr.o bn_mp_div.o bn_mp_mod.o bn_mp_add_d.o bn_mp_sub_d.o bn_mp_mul_d.o \ -bn_mp_div_d.o bn_mp_mod_d.o bn_mp_expt_d.o bn_mp_addmod.o bn_mp_submod.o \ -bn_mp_mulmod.o bn_mp_sqrmod.o bn_mp_gcd.o bn_mp_lcm.o bn_fast_mp_invmod.o bn_mp_invmod.o \ -bn_mp_reduce.o bn_mp_montgomery_setup.o bn_fast_mp_montgomery_reduce.o bn_mp_montgomery_reduce.o \ -bn_mp_exptmod_fast.o bn_mp_exptmod.o bn_mp_2expt.o bn_mp_n_root.o bn_mp_jacobi.o bn_reverse.o \ -bn_mp_count_bits.o bn_mp_read_unsigned_bin.o bn_mp_read_signed_bin.o bn_mp_to_unsigned_bin.o \ -bn_mp_to_signed_bin.o bn_mp_unsigned_bin_size.o bn_mp_signed_bin_size.o \ -bn_mp_xor.o bn_mp_and.o bn_mp_or.o bn_mp_rand.o bn_mp_montgomery_calc_normalization.o \ -bn_mp_prime_is_divisible.o bn_prime_tab.o bn_mp_prime_fermat.o bn_mp_prime_miller_rabin.o \ -bn_mp_prime_is_prime.o bn_mp_prime_next_prime.o bn_mp_dr_reduce.o \ -bn_mp_dr_is_modulus.o bn_mp_dr_setup.o bn_mp_reduce_setup.o \ -bn_mp_toom_mul.o bn_mp_toom_sqr.o bn_mp_div_3.o bn_s_mp_exptmod.o \ -bn_mp_reduce_2k.o bn_mp_reduce_is_2k.o bn_mp_reduce_2k_setup.o \ -bn_mp_reduce_2k_l.o bn_mp_reduce_is_2k_l.o bn_mp_reduce_2k_setup_l.o \ -bn_mp_radix_smap.o bn_mp_read_radix.o bn_mp_toradix.o bn_mp_radix_size.o \ -bn_mp_fread.o bn_mp_fwrite.o bn_mp_cnt_lsb.o bn_error.o \ -bn_mp_init_multi.o bn_mp_clear_multi.o bn_mp_exteuclid.o bn_mp_toradix_n.o \ -bn_mp_prime_random_ex.o bn_mp_get_int.o bn_mp_sqrt.o bn_mp_is_square.o bn_mp_init_set.o \ -bn_mp_init_set_int.o bn_mp_invmod_slow.o bn_mp_prime_rabin_miller_trials.o \ -bn_mp_to_signed_bin_n.o bn_mp_to_unsigned_bin_n.o - -$(LIBNAME): $(OBJECTS) - $(AR) $(ARFLAGS) $@ $(OBJECTS) - ranlib $@ - -#make a profiled library (takes a while!!!) -# -# This will build the library with profile generation -# then run the test demo and rebuild the library. -# -# So far I've seen improvements in the MP math -profiled: - make CFLAGS="$(CFLAGS) -fprofile-arcs -DTESTING" timing - ./ltmtest - rm -f *.a *.o ltmtest - make CFLAGS="$(CFLAGS) -fbranch-probabilities" - -#make a single object profiled library -profiled_single: - perl gen.pl - $(CC) $(CFLAGS) -fprofile-arcs -DTESTING -c mpi.c -o mpi.o - $(CC) $(CFLAGS) -DTESTING -DTIMER demo/timing.c mpi.o -o ltmtest - ./ltmtest - rm -f *.o ltmtest - $(CC) $(CFLAGS) -fbranch-probabilities -DTESTING -c mpi.c -o mpi.o - $(AR) $(ARFLAGS) $(LIBNAME) mpi.o - ranlib $(LIBNAME) - -install: $(LIBNAME) - install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(LIBPATH) - install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(INCPATH) - install -g $(GROUP) -o $(USER) $(LIBNAME) $(DESTDIR)$(LIBPATH) - install -g $(GROUP) -o $(USER) $(HEADERS) $(DESTDIR)$(INCPATH) - -test: $(LIBNAME) demo/demo.o - $(CC) $(CFLAGS) demo/demo.o $(LIBNAME) -o test - -mtest: test - cd mtest ; $(CC) $(CFLAGS) mtest.c -o mtest - -timing: $(LIBNAME) - $(CC) $(CFLAGS) -DTIMER demo/timing.c $(LIBNAME) -o ltmtest - -# makes the LTM book DVI file, requires tetex, perl and makeindex [part of tetex I think] -docdvi: tommath.src - cd pics ; MAKE=${MAKE} ${MAKE} - echo "hello" > tommath.ind - perl booker.pl - latex tommath > /dev/null - latex tommath > /dev/null - makeindex tommath - latex tommath > /dev/null - -# poster, makes the single page PDF poster -poster: poster.tex - pdflatex poster - rm -f poster.aux poster.log - -# makes the LTM book PDF file, requires tetex, cleans up the LaTeX temp files -docs: docdvi - dvipdf tommath - rm -f tommath.log tommath.aux tommath.dvi tommath.idx tommath.toc tommath.lof tommath.ind tommath.ilg - cd pics ; MAKE=${MAKE} ${MAKE} clean - -#LTM user manual -mandvi: bn.tex - echo "hello" > bn.ind - latex bn > /dev/null - latex bn > /dev/null - makeindex bn - latex bn > /dev/null - -#LTM user manual [pdf] -manual: mandvi - pdflatex bn >/dev/null - rm -f bn.aux bn.dvi bn.log bn.idx bn.lof bn.out bn.toc - -pretty: - perl pretty.build - -clean: - rm -f *.bat *.pdf *.o *.a *.obj *.lib *.exe *.dll etclib/*.o demo/demo.o test ltmtest mpitest mtest/mtest mtest/mtest.exe \ - *.idx *.toc *.log *.aux *.dvi *.lof *.ind *.ilg *.ps *.log *.s mpi.c *.da *.dyn *.dpi tommath.tex `find . -type f | grep [~] | xargs` *.lo *.la - rm -rf .libs - cd etc ; MAKE=${MAKE} ${MAKE} clean - cd pics ; MAKE=${MAKE} ${MAKE} clean - -#zipup the project (take that!) -no_oops: clean - cd .. ; cvs commit - echo Scanning for scratch/dirty files - find . -type f | grep -v CVS | xargs -n 1 bash mess.sh - -zipup: clean manual poster docs - perl gen.pl ; mv mpi.c pre_gen/ ; \ - cd .. ; rm -rf ltm* libtommath-$(VERSION) ; mkdir libtommath-$(VERSION) ; \ - cp -R ./libtommath/* ./libtommath-$(VERSION)/ ; \ - tar -c libtommath-$(VERSION)/* | bzip2 -9vvc > ltm-$(VERSION).tar.bz2 ; \ - zip -9 -r ltm-$(VERSION).zip libtommath-$(VERSION)/* ; \ - mv -f ltm* ~ ; rm -rf libtommath-$(VERSION) diff --git a/external/libtommath-0.42.0/makefile.bcc b/external/libtommath-0.42.0/makefile.bcc deleted file mode 100755 index 67743d9..0000000 --- a/external/libtommath-0.42.0/makefile.bcc +++ /dev/null @@ -1,44 +0,0 @@ -# -# Borland C++Builder Makefile (makefile.bcc) -# - - -LIB = tlib -CC = bcc32 -CFLAGS = -c -O2 -I. - -OBJECTS=bncore.obj bn_mp_init.obj bn_mp_clear.obj bn_mp_exch.obj bn_mp_grow.obj bn_mp_shrink.obj \ -bn_mp_clamp.obj bn_mp_zero.obj bn_mp_set.obj bn_mp_set_int.obj bn_mp_init_size.obj bn_mp_copy.obj \ -bn_mp_init_copy.obj bn_mp_abs.obj bn_mp_neg.obj bn_mp_cmp_mag.obj bn_mp_cmp.obj bn_mp_cmp_d.obj \ -bn_mp_rshd.obj bn_mp_lshd.obj bn_mp_mod_2d.obj bn_mp_div_2d.obj bn_mp_mul_2d.obj bn_mp_div_2.obj \ -bn_mp_mul_2.obj bn_s_mp_add.obj bn_s_mp_sub.obj bn_fast_s_mp_mul_digs.obj bn_s_mp_mul_digs.obj \ -bn_fast_s_mp_mul_high_digs.obj bn_s_mp_mul_high_digs.obj bn_fast_s_mp_sqr.obj bn_s_mp_sqr.obj \ -bn_mp_add.obj bn_mp_sub.obj bn_mp_karatsuba_mul.obj bn_mp_mul.obj bn_mp_karatsuba_sqr.obj \ -bn_mp_sqr.obj bn_mp_div.obj bn_mp_mod.obj bn_mp_add_d.obj bn_mp_sub_d.obj bn_mp_mul_d.obj \ -bn_mp_div_d.obj bn_mp_mod_d.obj bn_mp_expt_d.obj bn_mp_addmod.obj bn_mp_submod.obj \ -bn_mp_mulmod.obj bn_mp_sqrmod.obj bn_mp_gcd.obj bn_mp_lcm.obj bn_fast_mp_invmod.obj bn_mp_invmod.obj \ -bn_mp_reduce.obj bn_mp_montgomery_setup.obj bn_fast_mp_montgomery_reduce.obj bn_mp_montgomery_reduce.obj \ -bn_mp_exptmod_fast.obj bn_mp_exptmod.obj bn_mp_2expt.obj bn_mp_n_root.obj bn_mp_jacobi.obj bn_reverse.obj \ -bn_mp_count_bits.obj bn_mp_read_unsigned_bin.obj bn_mp_read_signed_bin.obj bn_mp_to_unsigned_bin.obj \ -bn_mp_to_signed_bin.obj bn_mp_unsigned_bin_size.obj bn_mp_signed_bin_size.obj \ -bn_mp_xor.obj bn_mp_and.obj bn_mp_or.obj bn_mp_rand.obj bn_mp_montgomery_calc_normalization.obj \ -bn_mp_prime_is_divisible.obj bn_prime_tab.obj bn_mp_prime_fermat.obj bn_mp_prime_miller_rabin.obj \ -bn_mp_prime_is_prime.obj bn_mp_prime_next_prime.obj bn_mp_dr_reduce.obj \ -bn_mp_dr_is_modulus.obj bn_mp_dr_setup.obj bn_mp_reduce_setup.obj \ -bn_mp_toom_mul.obj bn_mp_toom_sqr.obj bn_mp_div_3.obj bn_s_mp_exptmod.obj \ -bn_mp_reduce_2k.obj bn_mp_reduce_is_2k.obj bn_mp_reduce_2k_setup.obj \ -bn_mp_reduce_2k_l.obj bn_mp_reduce_is_2k_l.obj bn_mp_reduce_2k_setup_l.obj \ -bn_mp_radix_smap.obj bn_mp_read_radix.obj bn_mp_toradix.obj bn_mp_radix_size.obj \ -bn_mp_fread.obj bn_mp_fwrite.obj bn_mp_cnt_lsb.obj bn_error.obj \ -bn_mp_init_multi.obj bn_mp_clear_multi.obj bn_mp_exteuclid.obj bn_mp_toradix_n.obj \ -bn_mp_prime_random_ex.obj bn_mp_get_int.obj bn_mp_sqrt.obj bn_mp_is_square.obj \ -bn_mp_init_set.obj bn_mp_init_set_int.obj bn_mp_invmod_slow.obj bn_mp_prime_rabin_miller_trials.obj \ -bn_mp_to_signed_bin_n.obj bn_mp_to_unsigned_bin_n.obj - -TARGET = libtommath.lib - -$(TARGET): $(OBJECTS) - -.c.obj: - $(CC) $(CFLAGS) $< - $(LIB) $(TARGET) -+$@ diff --git a/external/libtommath-0.42.0/makefile.cygwin_dll b/external/libtommath-0.42.0/makefile.cygwin_dll deleted file mode 100755 index 85a9b20..0000000 --- a/external/libtommath-0.42.0/makefile.cygwin_dll +++ /dev/null @@ -1,55 +0,0 @@ -#Makefile for Cygwin-GCC -# -#This makefile will build a Windows DLL [doesn't require cygwin to run] in the file -#libtommath.dll. The import library is in libtommath.dll.a. Remember to add -#"-Wl,--enable-auto-import" to your client build to avoid the auto-import warnings -# -#Tom St Denis -CFLAGS += -I./ -Wall -W -Wshadow -O3 -funroll-loops -mno-cygwin - -#x86 optimizations [should be valid for any GCC install though] -CFLAGS += -fomit-frame-pointer - -default: windll - -OBJECTS=bncore.o bn_mp_init.o bn_mp_clear.o bn_mp_exch.o bn_mp_grow.o bn_mp_shrink.o \ -bn_mp_clamp.o bn_mp_zero.o bn_mp_set.o bn_mp_set_int.o bn_mp_init_size.o bn_mp_copy.o \ -bn_mp_init_copy.o bn_mp_abs.o bn_mp_neg.o bn_mp_cmp_mag.o bn_mp_cmp.o bn_mp_cmp_d.o \ -bn_mp_rshd.o bn_mp_lshd.o bn_mp_mod_2d.o bn_mp_div_2d.o bn_mp_mul_2d.o bn_mp_div_2.o \ -bn_mp_mul_2.o bn_s_mp_add.o bn_s_mp_sub.o bn_fast_s_mp_mul_digs.o bn_s_mp_mul_digs.o \ -bn_fast_s_mp_mul_high_digs.o bn_s_mp_mul_high_digs.o bn_fast_s_mp_sqr.o bn_s_mp_sqr.o \ -bn_mp_add.o bn_mp_sub.o bn_mp_karatsuba_mul.o bn_mp_mul.o bn_mp_karatsuba_sqr.o \ -bn_mp_sqr.o bn_mp_div.o bn_mp_mod.o bn_mp_add_d.o bn_mp_sub_d.o bn_mp_mul_d.o \ -bn_mp_div_d.o bn_mp_mod_d.o bn_mp_expt_d.o bn_mp_addmod.o bn_mp_submod.o \ -bn_mp_mulmod.o bn_mp_sqrmod.o bn_mp_gcd.o bn_mp_lcm.o bn_fast_mp_invmod.o bn_mp_invmod.o \ -bn_mp_reduce.o bn_mp_montgomery_setup.o bn_fast_mp_montgomery_reduce.o bn_mp_montgomery_reduce.o \ -bn_mp_exptmod_fast.o bn_mp_exptmod.o bn_mp_2expt.o bn_mp_n_root.o bn_mp_jacobi.o bn_reverse.o \ -bn_mp_count_bits.o bn_mp_read_unsigned_bin.o bn_mp_read_signed_bin.o bn_mp_to_unsigned_bin.o \ -bn_mp_to_signed_bin.o bn_mp_unsigned_bin_size.o bn_mp_signed_bin_size.o \ -bn_mp_xor.o bn_mp_and.o bn_mp_or.o bn_mp_rand.o bn_mp_montgomery_calc_normalization.o \ -bn_mp_prime_is_divisible.o bn_prime_tab.o bn_mp_prime_fermat.o bn_mp_prime_miller_rabin.o \ -bn_mp_prime_is_prime.o bn_mp_prime_next_prime.o bn_mp_dr_reduce.o \ -bn_mp_dr_is_modulus.o bn_mp_dr_setup.o bn_mp_reduce_setup.o \ -bn_mp_toom_mul.o bn_mp_toom_sqr.o bn_mp_div_3.o bn_s_mp_exptmod.o \ -bn_mp_reduce_2k.o bn_mp_reduce_is_2k.o bn_mp_reduce_2k_setup.o \ -bn_mp_reduce_2k_l.o bn_mp_reduce_is_2k_l.o bn_mp_reduce_2k_setup_l.o \ -bn_mp_radix_smap.o bn_mp_read_radix.o bn_mp_toradix.o bn_mp_radix_size.o \ -bn_mp_fread.o bn_mp_fwrite.o bn_mp_cnt_lsb.o bn_error.o \ -bn_mp_init_multi.o bn_mp_clear_multi.o bn_mp_exteuclid.o bn_mp_toradix_n.o \ -bn_mp_prime_random_ex.o bn_mp_get_int.o bn_mp_sqrt.o bn_mp_is_square.o bn_mp_init_set.o \ -bn_mp_init_set_int.o bn_mp_invmod_slow.o bn_mp_prime_rabin_miller_trials.o \ -bn_mp_to_signed_bin_n.o bn_mp_to_unsigned_bin_n.o - -# make a Windows DLL via Cygwin -windll: $(OBJECTS) - gcc -mno-cygwin -mdll -o libtommath.dll -Wl,--out-implib=libtommath.dll.a -Wl,--export-all-symbols *.o - ranlib libtommath.dll.a - -# build the test program using the windows DLL -test: $(OBJECTS) windll - gcc $(CFLAGS) demo/demo.c libtommath.dll.a -Wl,--enable-auto-import -o test -s - cd mtest ; $(CC) -O3 -fomit-frame-pointer -funroll-loops mtest.c -o mtest -s - -/* $Source: /cvs/libtom/libtommath/makefile.cygwin_dll,v $ */ -/* $Revision: 1.2 $ */ -/* $Date: 2005/05/05 14:38:45 $ */ diff --git a/external/libtommath-0.42.0/makefile.icc b/external/libtommath-0.42.0/makefile.icc deleted file mode 100755 index cf70ab0..0000000 --- a/external/libtommath-0.42.0/makefile.icc +++ /dev/null @@ -1,116 +0,0 @@ -#Makefile for ICC -# -#Tom St Denis -CC=icc - -CFLAGS += -I./ - -# optimize for SPEED -# -# -mcpu= can be pentium, pentiumpro (covers PII through PIII) or pentium4 -# -ax? specifies make code specifically for ? but compatible with IA-32 -# -x? specifies compile solely for ? [not specifically IA-32 compatible] -# -# where ? is -# K - PIII -# W - first P4 [Williamette] -# N - P4 Northwood -# P - P4 Prescott -# B - Blend of P4 and PM [mobile] -# -# Default to just generic max opts -CFLAGS += -O3 -xP -ip - -#install as this user -USER=root -GROUP=root - -default: libtommath.a - -#default files to install -LIBNAME=libtommath.a -HEADERS=tommath.h - -#LIBPATH-The directory for libtomcrypt to be installed to. -#INCPATH-The directory to install the header files for libtommath. -#DATAPATH-The directory to install the pdf docs. -DESTDIR= -LIBPATH=/usr/lib -INCPATH=/usr/include -DATAPATH=/usr/share/doc/libtommath/pdf - -OBJECTS=bncore.o bn_mp_init.o bn_mp_clear.o bn_mp_exch.o bn_mp_grow.o bn_mp_shrink.o \ -bn_mp_clamp.o bn_mp_zero.o bn_mp_set.o bn_mp_set_int.o bn_mp_init_size.o bn_mp_copy.o \ -bn_mp_init_copy.o bn_mp_abs.o bn_mp_neg.o bn_mp_cmp_mag.o bn_mp_cmp.o bn_mp_cmp_d.o \ -bn_mp_rshd.o bn_mp_lshd.o bn_mp_mod_2d.o bn_mp_div_2d.o bn_mp_mul_2d.o bn_mp_div_2.o \ -bn_mp_mul_2.o bn_s_mp_add.o bn_s_mp_sub.o bn_fast_s_mp_mul_digs.o bn_s_mp_mul_digs.o \ -bn_fast_s_mp_mul_high_digs.o bn_s_mp_mul_high_digs.o bn_fast_s_mp_sqr.o bn_s_mp_sqr.o \ -bn_mp_add.o bn_mp_sub.o bn_mp_karatsuba_mul.o bn_mp_mul.o bn_mp_karatsuba_sqr.o \ -bn_mp_sqr.o bn_mp_div.o bn_mp_mod.o bn_mp_add_d.o bn_mp_sub_d.o bn_mp_mul_d.o \ -bn_mp_div_d.o bn_mp_mod_d.o bn_mp_expt_d.o bn_mp_addmod.o bn_mp_submod.o \ -bn_mp_mulmod.o bn_mp_sqrmod.o bn_mp_gcd.o bn_mp_lcm.o bn_fast_mp_invmod.o bn_mp_invmod.o \ -bn_mp_reduce.o bn_mp_montgomery_setup.o bn_fast_mp_montgomery_reduce.o bn_mp_montgomery_reduce.o \ -bn_mp_exptmod_fast.o bn_mp_exptmod.o bn_mp_2expt.o bn_mp_n_root.o bn_mp_jacobi.o bn_reverse.o \ -bn_mp_count_bits.o bn_mp_read_unsigned_bin.o bn_mp_read_signed_bin.o bn_mp_to_unsigned_bin.o \ -bn_mp_to_signed_bin.o bn_mp_unsigned_bin_size.o bn_mp_signed_bin_size.o \ -bn_mp_xor.o bn_mp_and.o bn_mp_or.o bn_mp_rand.o bn_mp_montgomery_calc_normalization.o \ -bn_mp_prime_is_divisible.o bn_prime_tab.o bn_mp_prime_fermat.o bn_mp_prime_miller_rabin.o \ -bn_mp_prime_is_prime.o bn_mp_prime_next_prime.o bn_mp_dr_reduce.o \ -bn_mp_dr_is_modulus.o bn_mp_dr_setup.o bn_mp_reduce_setup.o \ -bn_mp_toom_mul.o bn_mp_toom_sqr.o bn_mp_div_3.o bn_s_mp_exptmod.o \ -bn_mp_reduce_2k.o bn_mp_reduce_is_2k.o bn_mp_reduce_2k_setup.o \ -bn_mp_reduce_2k_l.o bn_mp_reduce_is_2k_l.o bn_mp_reduce_2k_setup_l.o \ -bn_mp_radix_smap.o bn_mp_read_radix.o bn_mp_toradix.o bn_mp_radix_size.o \ -bn_mp_fread.o bn_mp_fwrite.o bn_mp_cnt_lsb.o bn_error.o \ -bn_mp_init_multi.o bn_mp_clear_multi.o bn_mp_exteuclid.o bn_mp_toradix_n.o \ -bn_mp_prime_random_ex.o bn_mp_get_int.o bn_mp_sqrt.o bn_mp_is_square.o bn_mp_init_set.o \ -bn_mp_init_set_int.o bn_mp_invmod_slow.o bn_mp_prime_rabin_miller_trials.o \ -bn_mp_to_signed_bin_n.o bn_mp_to_unsigned_bin_n.o - -libtommath.a: $(OBJECTS) - $(AR) $(ARFLAGS) libtommath.a $(OBJECTS) - ranlib libtommath.a - -#make a profiled library (takes a while!!!) -# -# This will build the library with profile generation -# then run the test demo and rebuild the library. -# -# So far I've seen improvements in the MP math -profiled: - make -f makefile.icc CFLAGS="$(CFLAGS) -prof_gen -DTESTING" timing - ./ltmtest - rm -f *.a *.o ltmtest - make -f makefile.icc CFLAGS="$(CFLAGS) -prof_use" - -#make a single object profiled library -profiled_single: - perl gen.pl - $(CC) $(CFLAGS) -prof_gen -DTESTING -c mpi.c -o mpi.o - $(CC) $(CFLAGS) -DTESTING -DTIMER demo/demo.c mpi.o -o ltmtest - ./ltmtest - rm -f *.o ltmtest - $(CC) $(CFLAGS) -prof_use -ip -DTESTING -c mpi.c -o mpi.o - $(AR) $(ARFLAGS) libtommath.a mpi.o - ranlib libtommath.a - -install: libtommath.a - install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(LIBPATH) - install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(INCPATH) - install -g $(GROUP) -o $(USER) $(LIBNAME) $(DESTDIR)$(LIBPATH) - install -g $(GROUP) -o $(USER) $(HEADERS) $(DESTDIR)$(INCPATH) - -test: libtommath.a demo/demo.o - $(CC) demo/demo.o libtommath.a -o test - -mtest: test - cd mtest ; $(CC) $(CFLAGS) mtest.c -o mtest - -timing: libtommath.a - $(CC) $(CFLAGS) -DTIMER demo/timing.c libtommath.a -o ltmtest - -clean: - rm -f *.bat *.pdf *.o *.a *.obj *.lib *.exe *.dll etclib/*.o demo/demo.o test ltmtest mpitest mtest/mtest mtest/mtest.exe \ - *.idx *.toc *.log *.aux *.dvi *.lof *.ind *.ilg *.ps *.log *.s mpi.c *.il etc/*.il *.dyn - cd etc ; make clean - cd pics ; make clean diff --git a/external/libtommath-0.42.0/makefile.msvc b/external/libtommath-0.42.0/makefile.msvc deleted file mode 100755 index 5edebec..0000000 --- a/external/libtommath-0.42.0/makefile.msvc +++ /dev/null @@ -1,40 +0,0 @@ -#MSVC Makefile -# -#Tom St Denis - -CFLAGS = /I. /Ox /DWIN32 /W3 /Fo$@ - -default: library - -OBJECTS=bncore.obj bn_mp_init.obj bn_mp_clear.obj bn_mp_exch.obj bn_mp_grow.obj bn_mp_shrink.obj \ -bn_mp_clamp.obj bn_mp_zero.obj bn_mp_set.obj bn_mp_set_int.obj bn_mp_init_size.obj bn_mp_copy.obj \ -bn_mp_init_copy.obj bn_mp_abs.obj bn_mp_neg.obj bn_mp_cmp_mag.obj bn_mp_cmp.obj bn_mp_cmp_d.obj \ -bn_mp_rshd.obj bn_mp_lshd.obj bn_mp_mod_2d.obj bn_mp_div_2d.obj bn_mp_mul_2d.obj bn_mp_div_2.obj \ -bn_mp_mul_2.obj bn_s_mp_add.obj bn_s_mp_sub.obj bn_fast_s_mp_mul_digs.obj bn_s_mp_mul_digs.obj \ -bn_fast_s_mp_mul_high_digs.obj bn_s_mp_mul_high_digs.obj bn_fast_s_mp_sqr.obj bn_s_mp_sqr.obj \ -bn_mp_add.obj bn_mp_sub.obj bn_mp_karatsuba_mul.obj bn_mp_mul.obj bn_mp_karatsuba_sqr.obj \ -bn_mp_sqr.obj bn_mp_div.obj bn_mp_mod.obj bn_mp_add_d.obj bn_mp_sub_d.obj bn_mp_mul_d.obj \ -bn_mp_div_d.obj bn_mp_mod_d.obj bn_mp_expt_d.obj bn_mp_addmod.obj bn_mp_submod.obj \ -bn_mp_mulmod.obj bn_mp_sqrmod.obj bn_mp_gcd.obj bn_mp_lcm.obj bn_fast_mp_invmod.obj bn_mp_invmod.obj \ -bn_mp_reduce.obj bn_mp_montgomery_setup.obj bn_fast_mp_montgomery_reduce.obj bn_mp_montgomery_reduce.obj \ -bn_mp_exptmod_fast.obj bn_mp_exptmod.obj bn_mp_2expt.obj bn_mp_n_root.obj bn_mp_jacobi.obj bn_reverse.obj \ -bn_mp_count_bits.obj bn_mp_read_unsigned_bin.obj bn_mp_read_signed_bin.obj bn_mp_to_unsigned_bin.obj \ -bn_mp_to_signed_bin.obj bn_mp_unsigned_bin_size.obj bn_mp_signed_bin_size.obj \ -bn_mp_xor.obj bn_mp_and.obj bn_mp_or.obj bn_mp_rand.obj bn_mp_montgomery_calc_normalization.obj \ -bn_mp_prime_is_divisible.obj bn_prime_tab.obj bn_mp_prime_fermat.obj bn_mp_prime_miller_rabin.obj \ -bn_mp_prime_is_prime.obj bn_mp_prime_next_prime.obj bn_mp_dr_reduce.obj \ -bn_mp_dr_is_modulus.obj bn_mp_dr_setup.obj bn_mp_reduce_setup.obj \ -bn_mp_toom_mul.obj bn_mp_toom_sqr.obj bn_mp_div_3.obj bn_s_mp_exptmod.obj \ -bn_mp_reduce_2k.obj bn_mp_reduce_is_2k.obj bn_mp_reduce_2k_setup.obj \ -bn_mp_reduce_2k_l.obj bn_mp_reduce_is_2k_l.obj bn_mp_reduce_2k_setup_l.obj \ -bn_mp_radix_smap.obj bn_mp_read_radix.obj bn_mp_toradix.obj bn_mp_radix_size.obj \ -bn_mp_fread.obj bn_mp_fwrite.obj bn_mp_cnt_lsb.obj bn_error.obj \ -bn_mp_init_multi.obj bn_mp_clear_multi.obj bn_mp_exteuclid.obj bn_mp_toradix_n.obj \ -bn_mp_prime_random_ex.obj bn_mp_get_int.obj bn_mp_sqrt.obj bn_mp_is_square.obj \ -bn_mp_init_set.obj bn_mp_init_set_int.obj bn_mp_invmod_slow.obj bn_mp_prime_rabin_miller_trials.obj \ -bn_mp_to_signed_bin_n.obj bn_mp_to_unsigned_bin_n.obj - -HEADERS=tommath.h tommath_class.h tommath_superclass.h - -library: $(OBJECTS) - lib /out:tommath.lib $(OBJECTS) diff --git a/external/libtommath-0.42.0/makefile.shared b/external/libtommath-0.42.0/makefile.shared deleted file mode 100755 index f17bbbd..0000000 --- a/external/libtommath-0.42.0/makefile.shared +++ /dev/null @@ -1,102 +0,0 @@ -#Makefile for GCC -# -#Tom St Denis -VERSION=0:41 - -CC = libtool --mode=compile --tag=CC gcc - -CFLAGS += -I./ -Wall -W -Wshadow -Wsign-compare - -ifndef IGNORE_SPEED - -#for speed -CFLAGS += -O3 -funroll-loops - -#for size -#CFLAGS += -Os - -#x86 optimizations [should be valid for any GCC install though] -CFLAGS += -fomit-frame-pointer - -endif - -#install as this user -ifndef INSTALL_GROUP - GROUP=wheel -else - GROUP=$(INSTALL_GROUP) -endif - -ifndef INSTALL_USER - USER=root -else - USER=$(INSTALL_USER) -endif - -default: libtommath.la - -#default files to install -ifndef LIBNAME - LIBNAME=libtommath.la -endif -ifndef LIBNAME_S - LIBNAME_S=libtommath.a -endif -HEADERS=tommath.h tommath_class.h tommath_superclass.h - -#LIBPATH-The directory for libtommath to be installed to. -#INCPATH-The directory to install the header files for libtommath. -#DATAPATH-The directory to install the pdf docs. -DESTDIR= -LIBPATH=/usr/lib -INCPATH=/usr/include -DATAPATH=/usr/share/doc/libtommath/pdf - -OBJECTS=bncore.o bn_mp_init.o bn_mp_clear.o bn_mp_exch.o bn_mp_grow.o bn_mp_shrink.o \ -bn_mp_clamp.o bn_mp_zero.o bn_mp_set.o bn_mp_set_int.o bn_mp_init_size.o bn_mp_copy.o \ -bn_mp_init_copy.o bn_mp_abs.o bn_mp_neg.o bn_mp_cmp_mag.o bn_mp_cmp.o bn_mp_cmp_d.o \ -bn_mp_rshd.o bn_mp_lshd.o bn_mp_mod_2d.o bn_mp_div_2d.o bn_mp_mul_2d.o bn_mp_div_2.o \ -bn_mp_mul_2.o bn_s_mp_add.o bn_s_mp_sub.o bn_fast_s_mp_mul_digs.o bn_s_mp_mul_digs.o \ -bn_fast_s_mp_mul_high_digs.o bn_s_mp_mul_high_digs.o bn_fast_s_mp_sqr.o bn_s_mp_sqr.o \ -bn_mp_add.o bn_mp_sub.o bn_mp_karatsuba_mul.o bn_mp_mul.o bn_mp_karatsuba_sqr.o \ -bn_mp_sqr.o bn_mp_div.o bn_mp_mod.o bn_mp_add_d.o bn_mp_sub_d.o bn_mp_mul_d.o \ -bn_mp_div_d.o bn_mp_mod_d.o bn_mp_expt_d.o bn_mp_addmod.o bn_mp_submod.o \ -bn_mp_mulmod.o bn_mp_sqrmod.o bn_mp_gcd.o bn_mp_lcm.o bn_fast_mp_invmod.o bn_mp_invmod.o \ -bn_mp_reduce.o bn_mp_montgomery_setup.o bn_fast_mp_montgomery_reduce.o bn_mp_montgomery_reduce.o \ -bn_mp_exptmod_fast.o bn_mp_exptmod.o bn_mp_2expt.o bn_mp_n_root.o bn_mp_jacobi.o bn_reverse.o \ -bn_mp_count_bits.o bn_mp_read_unsigned_bin.o bn_mp_read_signed_bin.o bn_mp_to_unsigned_bin.o \ -bn_mp_to_signed_bin.o bn_mp_unsigned_bin_size.o bn_mp_signed_bin_size.o \ -bn_mp_xor.o bn_mp_and.o bn_mp_or.o bn_mp_rand.o bn_mp_montgomery_calc_normalization.o \ -bn_mp_prime_is_divisible.o bn_prime_tab.o bn_mp_prime_fermat.o bn_mp_prime_miller_rabin.o \ -bn_mp_prime_is_prime.o bn_mp_prime_next_prime.o bn_mp_dr_reduce.o \ -bn_mp_dr_is_modulus.o bn_mp_dr_setup.o bn_mp_reduce_setup.o \ -bn_mp_toom_mul.o bn_mp_toom_sqr.o bn_mp_div_3.o bn_s_mp_exptmod.o \ -bn_mp_reduce_2k.o bn_mp_reduce_is_2k.o bn_mp_reduce_2k_setup.o \ -bn_mp_reduce_2k_l.o bn_mp_reduce_is_2k_l.o bn_mp_reduce_2k_setup_l.o \ -bn_mp_radix_smap.o bn_mp_read_radix.o bn_mp_toradix.o bn_mp_radix_size.o \ -bn_mp_fread.o bn_mp_fwrite.o bn_mp_cnt_lsb.o bn_error.o \ -bn_mp_init_multi.o bn_mp_clear_multi.o bn_mp_exteuclid.o bn_mp_toradix_n.o \ -bn_mp_prime_random_ex.o bn_mp_get_int.o bn_mp_sqrt.o bn_mp_is_square.o bn_mp_init_set.o \ -bn_mp_init_set_int.o bn_mp_invmod_slow.o bn_mp_prime_rabin_miller_trials.o \ -bn_mp_to_signed_bin_n.o bn_mp_to_unsigned_bin_n.o - -objs: $(OBJECTS) - -$(LIBNAME): $(OBJECTS) - libtool --mode=link gcc *.lo -o $(LIBNAME) -rpath $(LIBPATH) -version-info $(VERSION) - -install: $(LIBNAME) - install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(LIBPATH) - libtool --mode=install install -c $(LIBNAME) $(DESTDIR)$(LIBPATH)/$(LIBNAME) - install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(INCPATH) - install -g $(GROUP) -o $(USER) $(HEADERS) $(DESTDIR)$(INCPATH) - -test: $(LIBNAME) demo/demo.o - gcc $(CFLAGS) -c demo/demo.c -o demo/demo.o - libtool --mode=link gcc -o test demo/demo.o $(LIBNAME_S) - -mtest: test - cd mtest ; gcc $(CFLAGS) mtest.c -o mtest - -timing: $(LIBNAME) - gcc $(CFLAGS) -DTIMER demo/timing.c $(LIBNAME_S) -o ltmtest diff --git a/external/libtommath-0.42.0/mess.sh b/external/libtommath-0.42.0/mess.sh deleted file mode 100755 index bf639ce..0000000 --- a/external/libtommath-0.42.0/mess.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash -if cvs log $1 >/dev/null 2>/dev/null; then exit 0; else echo "$1 shouldn't be here" ; exit 1; fi - - diff --git a/external/libtommath-0.42.0/mtest/logtab.h b/external/libtommath-0.42.0/mtest/logtab.h deleted file mode 100755 index 04c1ad3..0000000 --- a/external/libtommath-0.42.0/mtest/logtab.h +++ /dev/null @@ -1,24 +0,0 @@ -const float s_logv_2[] = { - 0.000000000, 0.000000000, 1.000000000, 0.630929754, /* 0 1 2 3 */ - 0.500000000, 0.430676558, 0.386852807, 0.356207187, /* 4 5 6 7 */ - 0.333333333, 0.315464877, 0.301029996, 0.289064826, /* 8 9 10 11 */ - 0.278942946, 0.270238154, 0.262649535, 0.255958025, /* 12 13 14 15 */ - 0.250000000, 0.244650542, 0.239812467, 0.235408913, /* 16 17 18 19 */ - 0.231378213, 0.227670249, 0.224243824, 0.221064729, /* 20 21 22 23 */ - 0.218104292, 0.215338279, 0.212746054, 0.210309918, /* 24 25 26 27 */ - 0.208014598, 0.205846832, 0.203795047, 0.201849087, /* 28 29 30 31 */ - 0.200000000, 0.198239863, 0.196561632, 0.194959022, /* 32 33 34 35 */ - 0.193426404, 0.191958720, 0.190551412, 0.189200360, /* 36 37 38 39 */ - 0.187901825, 0.186652411, 0.185449023, 0.184288833, /* 40 41 42 43 */ - 0.183169251, 0.182087900, 0.181042597, 0.180031327, /* 44 45 46 47 */ - 0.179052232, 0.178103594, 0.177183820, 0.176291434, /* 48 49 50 51 */ - 0.175425064, 0.174583430, 0.173765343, 0.172969690, /* 52 53 54 55 */ - 0.172195434, 0.171441601, 0.170707280, 0.169991616, /* 56 57 58 59 */ - 0.169293808, 0.168613099, 0.167948779, 0.167300179, /* 60 61 62 63 */ - 0.166666667 -}; - - -/* $Source$ */ -/* $Revision: 0.36 $ */ -/* $Date: 2005-08-01 16:37:28 +0000 $ */ diff --git a/external/libtommath-0.42.0/mtest/mpi-config.h b/external/libtommath-0.42.0/mtest/mpi-config.h deleted file mode 100755 index 21e72b2..0000000 --- a/external/libtommath-0.42.0/mtest/mpi-config.h +++ /dev/null @@ -1,90 +0,0 @@ -/* Default configuration for MPI library */ -/* $ID$ */ - -#ifndef MPI_CONFIG_H_ -#define MPI_CONFIG_H_ - -/* - For boolean options, - 0 = no - 1 = yes - - Other options are documented individually. - - */ - -#ifndef MP_IOFUNC -#define MP_IOFUNC 0 /* include mp_print() ? */ -#endif - -#ifndef MP_MODARITH -#define MP_MODARITH 1 /* include modular arithmetic ? */ -#endif - -#ifndef MP_NUMTH -#define MP_NUMTH 1 /* include number theoretic functions? */ -#endif - -#ifndef MP_LOGTAB -#define MP_LOGTAB 1 /* use table of logs instead of log()? */ -#endif - -#ifndef MP_MEMSET -#define MP_MEMSET 1 /* use memset() to zero buffers? */ -#endif - -#ifndef MP_MEMCPY -#define MP_MEMCPY 1 /* use memcpy() to copy buffers? */ -#endif - -#ifndef MP_CRYPTO -#define MP_CRYPTO 1 /* erase memory on free? */ -#endif - -#ifndef MP_ARGCHK -/* - 0 = no parameter checks - 1 = runtime checks, continue execution and return an error to caller - 2 = assertions; dump core on parameter errors - */ -#define MP_ARGCHK 2 /* how to check input arguments */ -#endif - -#ifndef MP_DEBUG -#define MP_DEBUG 0 /* print diagnostic output? */ -#endif - -#ifndef MP_DEFPREC -#define MP_DEFPREC 64 /* default precision, in digits */ -#endif - -#ifndef MP_MACRO -#define MP_MACRO 1 /* use macros for frequent calls? */ -#endif - -#ifndef MP_SQUARE -#define MP_SQUARE 1 /* use separate squaring code? */ -#endif - -#ifndef MP_PTAB_SIZE -/* - When building mpprime.c, we build in a table of small prime - values to use for primality testing. The more you include, - the more space they take up. See primes.c for the possible - values (currently 16, 32, 64, 128, 256, and 6542) - */ -#define MP_PTAB_SIZE 128 /* how many built-in primes? */ -#endif - -#ifndef MP_COMPAT_MACROS -#define MP_COMPAT_MACROS 1 /* define compatibility macros? */ -#endif - -#endif /* ifndef MPI_CONFIG_H_ */ - - -/* crc==3287762869, version==2, Sat Feb 02 06:43:53 2002 */ - -/* $Source$ */ -/* $Revision: 0.36 $ */ -/* $Date: 2005-08-01 16:37:28 +0000 $ */ diff --git a/external/libtommath-0.42.0/mtest/mpi-types.h b/external/libtommath-0.42.0/mtest/mpi-types.h deleted file mode 100755 index a90f11e..0000000 --- a/external/libtommath-0.42.0/mtest/mpi-types.h +++ /dev/null @@ -1,20 +0,0 @@ -/* Type definitions generated by 'types.pl' */ -typedef char mp_sign; -typedef unsigned short mp_digit; /* 2 byte type */ -typedef unsigned int mp_word; /* 4 byte type */ -typedef unsigned int mp_size; -typedef int mp_err; - -#define MP_DIGIT_BIT (CHAR_BIT*sizeof(mp_digit)) -#define MP_DIGIT_MAX USHRT_MAX -#define MP_WORD_BIT (CHAR_BIT*sizeof(mp_word)) -#define MP_WORD_MAX UINT_MAX - -#define MP_DIGIT_SIZE 2 -#define DIGIT_FMT "%04X" -#define RADIX (MP_DIGIT_MAX+1) - - -/* $Source$ */ -/* $Revision: 0.36 $ */ -/* $Date: 2005-08-01 16:37:28 +0000 $ */ diff --git a/external/libtommath-0.42.0/mtest/mpi.c b/external/libtommath-0.42.0/mtest/mpi.c deleted file mode 100755 index f6ef8c7..0000000 --- a/external/libtommath-0.42.0/mtest/mpi.c +++ /dev/null @@ -1,3985 +0,0 @@ -/* - mpi.c - - by Michael J. Fromberger - Copyright (C) 1998 Michael J. Fromberger, All Rights Reserved - - Arbitrary precision integer arithmetic library - - $ID$ - */ - -#include "mpi.h" -#include -#include -#include - -#if MP_DEBUG -#include - -#define DIAG(T,V) {fprintf(stderr,T);mp_print(V,stderr);fputc('\n',stderr);} -#else -#define DIAG(T,V) -#endif - -/* - If MP_LOGTAB is not defined, use the math library to compute the - logarithms on the fly. Otherwise, use the static table below. - Pick which works best for your system. - */ -#if MP_LOGTAB - -/* {{{ s_logv_2[] - log table for 2 in various bases */ - -/* - A table of the logs of 2 for various bases (the 0 and 1 entries of - this table are meaningless and should not be referenced). - - This table is used to compute output lengths for the mp_toradix() - function. Since a number n in radix r takes up about log_r(n) - digits, we estimate the output size by taking the least integer - greater than log_r(n), where: - - log_r(n) = log_2(n) * log_r(2) - - This table, therefore, is a table of log_r(2) for 2 <= r <= 36, - which are the output bases supported. - */ - -#include "logtab.h" - -/* }}} */ -#define LOG_V_2(R) s_logv_2[(R)] - -#else - -#include -#define LOG_V_2(R) (log(2.0)/log(R)) - -#endif - -/* Default precision for newly created mp_int's */ -static unsigned int s_mp_defprec = MP_DEFPREC; - -/* {{{ Digit arithmetic macros */ - -/* - When adding and multiplying digits, the results can be larger than - can be contained in an mp_digit. Thus, an mp_word is used. These - macros mask off the upper and lower digits of the mp_word (the - mp_word may be more than 2 mp_digits wide, but we only concern - ourselves with the low-order 2 mp_digits) - - If your mp_word DOES have more than 2 mp_digits, you need to - uncomment the first line, and comment out the second. - */ - -/* #define CARRYOUT(W) (((W)>>DIGIT_BIT)&MP_DIGIT_MAX) */ -#define CARRYOUT(W) ((W)>>DIGIT_BIT) -#define ACCUM(W) ((W)&MP_DIGIT_MAX) - -/* }}} */ - -/* {{{ Comparison constants */ - -#define MP_LT -1 -#define MP_EQ 0 -#define MP_GT 1 - -/* }}} */ - -/* {{{ Constant strings */ - -/* Constant strings returned by mp_strerror() */ -static const char *mp_err_string[] = { - "unknown result code", /* say what? */ - "boolean true", /* MP_OKAY, MP_YES */ - "boolean false", /* MP_NO */ - "out of memory", /* MP_MEM */ - "argument out of range", /* MP_RANGE */ - "invalid input parameter", /* MP_BADARG */ - "result is undefined" /* MP_UNDEF */ -}; - -/* Value to digit maps for radix conversion */ - -/* s_dmap_1 - standard digits and letters */ -static const char *s_dmap_1 = - "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/"; - -#if 0 -/* s_dmap_2 - base64 ordering for digits */ -static const char *s_dmap_2 = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; -#endif - -/* }}} */ - -/* {{{ Static function declarations */ - -/* - If MP_MACRO is false, these will be defined as actual functions; - otherwise, suitable macro definitions will be used. This works - around the fact that ANSI C89 doesn't support an 'inline' keyword - (although I hear C9x will ... about bloody time). At present, the - macro definitions are identical to the function bodies, but they'll - expand in place, instead of generating a function call. - - I chose these particular functions to be made into macros because - some profiling showed they are called a lot on a typical workload, - and yet they are primarily housekeeping. - */ -#if MP_MACRO == 0 - void s_mp_setz(mp_digit *dp, mp_size count); /* zero digits */ - void s_mp_copy(mp_digit *sp, mp_digit *dp, mp_size count); /* copy */ - void *s_mp_alloc(size_t nb, size_t ni); /* general allocator */ - void s_mp_free(void *ptr); /* general free function */ -#else - - /* Even if these are defined as macros, we need to respect the settings - of the MP_MEMSET and MP_MEMCPY configuration options... - */ - #if MP_MEMSET == 0 - #define s_mp_setz(dp, count) \ - {int ix;for(ix=0;ix<(count);ix++)(dp)[ix]=0;} - #else - #define s_mp_setz(dp, count) memset(dp, 0, (count) * sizeof(mp_digit)) - #endif /* MP_MEMSET */ - - #if MP_MEMCPY == 0 - #define s_mp_copy(sp, dp, count) \ - {int ix;for(ix=0;ix<(count);ix++)(dp)[ix]=(sp)[ix];} - #else - #define s_mp_copy(sp, dp, count) memcpy(dp, sp, (count) * sizeof(mp_digit)) - #endif /* MP_MEMCPY */ - - #define s_mp_alloc(nb, ni) calloc(nb, ni) - #define s_mp_free(ptr) {if(ptr) free(ptr);} -#endif /* MP_MACRO */ - -mp_err s_mp_grow(mp_int *mp, mp_size min); /* increase allocated size */ -mp_err s_mp_pad(mp_int *mp, mp_size min); /* left pad with zeroes */ - -void s_mp_clamp(mp_int *mp); /* clip leading zeroes */ - -void s_mp_exch(mp_int *a, mp_int *b); /* swap a and b in place */ - -mp_err s_mp_lshd(mp_int *mp, mp_size p); /* left-shift by p digits */ -void s_mp_rshd(mp_int *mp, mp_size p); /* right-shift by p digits */ -void s_mp_div_2d(mp_int *mp, mp_digit d); /* divide by 2^d in place */ -void s_mp_mod_2d(mp_int *mp, mp_digit d); /* modulo 2^d in place */ -mp_err s_mp_mul_2d(mp_int *mp, mp_digit d); /* multiply by 2^d in place*/ -void s_mp_div_2(mp_int *mp); /* divide by 2 in place */ -mp_err s_mp_mul_2(mp_int *mp); /* multiply by 2 in place */ -mp_digit s_mp_norm(mp_int *a, mp_int *b); /* normalize for division */ -mp_err s_mp_add_d(mp_int *mp, mp_digit d); /* unsigned digit addition */ -mp_err s_mp_sub_d(mp_int *mp, mp_digit d); /* unsigned digit subtract */ -mp_err s_mp_mul_d(mp_int *mp, mp_digit d); /* unsigned digit multiply */ -mp_err s_mp_div_d(mp_int *mp, mp_digit d, mp_digit *r); - /* unsigned digit divide */ -mp_err s_mp_reduce(mp_int *x, mp_int *m, mp_int *mu); - /* Barrett reduction */ -mp_err s_mp_add(mp_int *a, mp_int *b); /* magnitude addition */ -mp_err s_mp_sub(mp_int *a, mp_int *b); /* magnitude subtract */ -mp_err s_mp_mul(mp_int *a, mp_int *b); /* magnitude multiply */ -#if 0 -void s_mp_kmul(mp_digit *a, mp_digit *b, mp_digit *out, mp_size len); - /* multiply buffers in place */ -#endif -#if MP_SQUARE -mp_err s_mp_sqr(mp_int *a); /* magnitude square */ -#else -#define s_mp_sqr(a) s_mp_mul(a, a) -#endif -mp_err s_mp_div(mp_int *a, mp_int *b); /* magnitude divide */ -mp_err s_mp_2expt(mp_int *a, mp_digit k); /* a = 2^k */ -int s_mp_cmp(mp_int *a, mp_int *b); /* magnitude comparison */ -int s_mp_cmp_d(mp_int *a, mp_digit d); /* magnitude digit compare */ -int s_mp_ispow2(mp_int *v); /* is v a power of 2? */ -int s_mp_ispow2d(mp_digit d); /* is d a power of 2? */ - -int s_mp_tovalue(char ch, int r); /* convert ch to value */ -char s_mp_todigit(int val, int r, int low); /* convert val to digit */ -int s_mp_outlen(int bits, int r); /* output length in bytes */ - -/* }}} */ - -/* {{{ Default precision manipulation */ - -unsigned int mp_get_prec(void) -{ - return s_mp_defprec; - -} /* end mp_get_prec() */ - -void mp_set_prec(unsigned int prec) -{ - if(prec == 0) - s_mp_defprec = MP_DEFPREC; - else - s_mp_defprec = prec; - -} /* end mp_set_prec() */ - -/* }}} */ - -/*------------------------------------------------------------------------*/ -/* {{{ mp_init(mp) */ - -/* - mp_init(mp) - - Initialize a new zero-valued mp_int. Returns MP_OKAY if successful, - MP_MEM if memory could not be allocated for the structure. - */ - -mp_err mp_init(mp_int *mp) -{ - return mp_init_size(mp, s_mp_defprec); - -} /* end mp_init() */ - -/* }}} */ - -/* {{{ mp_init_array(mp[], count) */ - -mp_err mp_init_array(mp_int mp[], int count) -{ - mp_err res; - int pos; - - ARGCHK(mp !=NULL && count > 0, MP_BADARG); - - for(pos = 0; pos < count; ++pos) { - if((res = mp_init(&mp[pos])) != MP_OKAY) - goto CLEANUP; - } - - return MP_OKAY; - - CLEANUP: - while(--pos >= 0) - mp_clear(&mp[pos]); - - return res; - -} /* end mp_init_array() */ - -/* }}} */ - -/* {{{ mp_init_size(mp, prec) */ - -/* - mp_init_size(mp, prec) - - Initialize a new zero-valued mp_int with at least the given - precision; returns MP_OKAY if successful, or MP_MEM if memory could - not be allocated for the structure. - */ - -mp_err mp_init_size(mp_int *mp, mp_size prec) -{ - ARGCHK(mp != NULL && prec > 0, MP_BADARG); - - if((DIGITS(mp) = s_mp_alloc(prec, sizeof(mp_digit))) == NULL) - return MP_MEM; - - SIGN(mp) = MP_ZPOS; - USED(mp) = 1; - ALLOC(mp) = prec; - - return MP_OKAY; - -} /* end mp_init_size() */ - -/* }}} */ - -/* {{{ mp_init_copy(mp, from) */ - -/* - mp_init_copy(mp, from) - - Initialize mp as an exact copy of from. Returns MP_OKAY if - successful, MP_MEM if memory could not be allocated for the new - structure. - */ - -mp_err mp_init_copy(mp_int *mp, mp_int *from) -{ - ARGCHK(mp != NULL && from != NULL, MP_BADARG); - - if(mp == from) - return MP_OKAY; - - if((DIGITS(mp) = s_mp_alloc(USED(from), sizeof(mp_digit))) == NULL) - return MP_MEM; - - s_mp_copy(DIGITS(from), DIGITS(mp), USED(from)); - USED(mp) = USED(from); - ALLOC(mp) = USED(from); - SIGN(mp) = SIGN(from); - - return MP_OKAY; - -} /* end mp_init_copy() */ - -/* }}} */ - -/* {{{ mp_copy(from, to) */ - -/* - mp_copy(from, to) - - Copies the mp_int 'from' to the mp_int 'to'. It is presumed that - 'to' has already been initialized (if not, use mp_init_copy() - instead). If 'from' and 'to' are identical, nothing happens. - */ - -mp_err mp_copy(mp_int *from, mp_int *to) -{ - ARGCHK(from != NULL && to != NULL, MP_BADARG); - - if(from == to) - return MP_OKAY; - - { /* copy */ - mp_digit *tmp; - - /* - If the allocated buffer in 'to' already has enough space to hold - all the used digits of 'from', we'll re-use it to avoid hitting - the memory allocater more than necessary; otherwise, we'd have - to grow anyway, so we just allocate a hunk and make the copy as - usual - */ - if(ALLOC(to) >= USED(from)) { - s_mp_setz(DIGITS(to) + USED(from), ALLOC(to) - USED(from)); - s_mp_copy(DIGITS(from), DIGITS(to), USED(from)); - - } else { - if((tmp = s_mp_alloc(USED(from), sizeof(mp_digit))) == NULL) - return MP_MEM; - - s_mp_copy(DIGITS(from), tmp, USED(from)); - - if(DIGITS(to) != NULL) { -#if MP_CRYPTO - s_mp_setz(DIGITS(to), ALLOC(to)); -#endif - s_mp_free(DIGITS(to)); - } - - DIGITS(to) = tmp; - ALLOC(to) = USED(from); - } - - /* Copy the precision and sign from the original */ - USED(to) = USED(from); - SIGN(to) = SIGN(from); - } /* end copy */ - - return MP_OKAY; - -} /* end mp_copy() */ - -/* }}} */ - -/* {{{ mp_exch(mp1, mp2) */ - -/* - mp_exch(mp1, mp2) - - Exchange mp1 and mp2 without allocating any intermediate memory - (well, unless you count the stack space needed for this call and the - locals it creates...). This cannot fail. - */ - -void mp_exch(mp_int *mp1, mp_int *mp2) -{ -#if MP_ARGCHK == 2 - assert(mp1 != NULL && mp2 != NULL); -#else - if(mp1 == NULL || mp2 == NULL) - return; -#endif - - s_mp_exch(mp1, mp2); - -} /* end mp_exch() */ - -/* }}} */ - -/* {{{ mp_clear(mp) */ - -/* - mp_clear(mp) - - Release the storage used by an mp_int, and void its fields so that - if someone calls mp_clear() again for the same int later, we won't - get tollchocked. - */ - -void mp_clear(mp_int *mp) -{ - if(mp == NULL) - return; - - if(DIGITS(mp) != NULL) { -#if MP_CRYPTO - s_mp_setz(DIGITS(mp), ALLOC(mp)); -#endif - s_mp_free(DIGITS(mp)); - DIGITS(mp) = NULL; - } - - USED(mp) = 0; - ALLOC(mp) = 0; - -} /* end mp_clear() */ - -/* }}} */ - -/* {{{ mp_clear_array(mp[], count) */ - -void mp_clear_array(mp_int mp[], int count) -{ - ARGCHK(mp != NULL && count > 0, MP_BADARG); - - while(--count >= 0) - mp_clear(&mp[count]); - -} /* end mp_clear_array() */ - -/* }}} */ - -/* {{{ mp_zero(mp) */ - -/* - mp_zero(mp) - - Set mp to zero. Does not change the allocated size of the structure, - and therefore cannot fail (except on a bad argument, which we ignore) - */ -void mp_zero(mp_int *mp) -{ - if(mp == NULL) - return; - - s_mp_setz(DIGITS(mp), ALLOC(mp)); - USED(mp) = 1; - SIGN(mp) = MP_ZPOS; - -} /* end mp_zero() */ - -/* }}} */ - -/* {{{ mp_set(mp, d) */ - -void mp_set(mp_int *mp, mp_digit d) -{ - if(mp == NULL) - return; - - mp_zero(mp); - DIGIT(mp, 0) = d; - -} /* end mp_set() */ - -/* }}} */ - -/* {{{ mp_set_int(mp, z) */ - -mp_err mp_set_int(mp_int *mp, long z) -{ - int ix; - unsigned long v = abs(z); - mp_err res; - - ARGCHK(mp != NULL, MP_BADARG); - - mp_zero(mp); - if(z == 0) - return MP_OKAY; /* shortcut for zero */ - - for(ix = sizeof(long) - 1; ix >= 0; ix--) { - - if((res = s_mp_mul_2d(mp, CHAR_BIT)) != MP_OKAY) - return res; - - res = s_mp_add_d(mp, - (mp_digit)((v >> (ix * CHAR_BIT)) & UCHAR_MAX)); - if(res != MP_OKAY) - return res; - - } - - if(z < 0) - SIGN(mp) = MP_NEG; - - return MP_OKAY; - -} /* end mp_set_int() */ - -/* }}} */ - -/*------------------------------------------------------------------------*/ -/* {{{ Digit arithmetic */ - -/* {{{ mp_add_d(a, d, b) */ - -/* - mp_add_d(a, d, b) - - Compute the sum b = a + d, for a single digit d. Respects the sign of - its primary addend (single digits are unsigned anyway). - */ - -mp_err mp_add_d(mp_int *a, mp_digit d, mp_int *b) -{ - mp_err res = MP_OKAY; - - ARGCHK(a != NULL && b != NULL, MP_BADARG); - - if((res = mp_copy(a, b)) != MP_OKAY) - return res; - - if(SIGN(b) == MP_ZPOS) { - res = s_mp_add_d(b, d); - } else if(s_mp_cmp_d(b, d) >= 0) { - res = s_mp_sub_d(b, d); - } else { - SIGN(b) = MP_ZPOS; - - DIGIT(b, 0) = d - DIGIT(b, 0); - } - - return res; - -} /* end mp_add_d() */ - -/* }}} */ - -/* {{{ mp_sub_d(a, d, b) */ - -/* - mp_sub_d(a, d, b) - - Compute the difference b = a - d, for a single digit d. Respects the - sign of its subtrahend (single digits are unsigned anyway). - */ - -mp_err mp_sub_d(mp_int *a, mp_digit d, mp_int *b) -{ - mp_err res; - - ARGCHK(a != NULL && b != NULL, MP_BADARG); - - if((res = mp_copy(a, b)) != MP_OKAY) - return res; - - if(SIGN(b) == MP_NEG) { - if((res = s_mp_add_d(b, d)) != MP_OKAY) - return res; - - } else if(s_mp_cmp_d(b, d) >= 0) { - if((res = s_mp_sub_d(b, d)) != MP_OKAY) - return res; - - } else { - mp_neg(b, b); - - DIGIT(b, 0) = d - DIGIT(b, 0); - SIGN(b) = MP_NEG; - } - - if(s_mp_cmp_d(b, 0) == 0) - SIGN(b) = MP_ZPOS; - - return MP_OKAY; - -} /* end mp_sub_d() */ - -/* }}} */ - -/* {{{ mp_mul_d(a, d, b) */ - -/* - mp_mul_d(a, d, b) - - Compute the product b = a * d, for a single digit d. Respects the sign - of its multiplicand (single digits are unsigned anyway) - */ - -mp_err mp_mul_d(mp_int *a, mp_digit d, mp_int *b) -{ - mp_err res; - - ARGCHK(a != NULL && b != NULL, MP_BADARG); - - if(d == 0) { - mp_zero(b); - return MP_OKAY; - } - - if((res = mp_copy(a, b)) != MP_OKAY) - return res; - - res = s_mp_mul_d(b, d); - - return res; - -} /* end mp_mul_d() */ - -/* }}} */ - -/* {{{ mp_mul_2(a, c) */ - -mp_err mp_mul_2(mp_int *a, mp_int *c) -{ - mp_err res; - - ARGCHK(a != NULL && c != NULL, MP_BADARG); - - if((res = mp_copy(a, c)) != MP_OKAY) - return res; - - return s_mp_mul_2(c); - -} /* end mp_mul_2() */ - -/* }}} */ - -/* {{{ mp_div_d(a, d, q, r) */ - -/* - mp_div_d(a, d, q, r) - - Compute the quotient q = a / d and remainder r = a mod d, for a - single digit d. Respects the sign of its divisor (single digits are - unsigned anyway). - */ - -mp_err mp_div_d(mp_int *a, mp_digit d, mp_int *q, mp_digit *r) -{ - mp_err res; - mp_digit rem; - int pow; - - ARGCHK(a != NULL, MP_BADARG); - - if(d == 0) - return MP_RANGE; - - /* Shortcut for powers of two ... */ - if((pow = s_mp_ispow2d(d)) >= 0) { - mp_digit mask; - - mask = (1 << pow) - 1; - rem = DIGIT(a, 0) & mask; - - if(q) { - mp_copy(a, q); - s_mp_div_2d(q, pow); - } - - if(r) - *r = rem; - - return MP_OKAY; - } - - /* - If the quotient is actually going to be returned, we'll try to - avoid hitting the memory allocator by copying the dividend into it - and doing the division there. This can't be any _worse_ than - always copying, and will sometimes be better (since it won't make - another copy) - - If it's not going to be returned, we need to allocate a temporary - to hold the quotient, which will just be discarded. - */ - if(q) { - if((res = mp_copy(a, q)) != MP_OKAY) - return res; - - res = s_mp_div_d(q, d, &rem); - if(s_mp_cmp_d(q, 0) == MP_EQ) - SIGN(q) = MP_ZPOS; - - } else { - mp_int qp; - - if((res = mp_init_copy(&qp, a)) != MP_OKAY) - return res; - - res = s_mp_div_d(&qp, d, &rem); - if(s_mp_cmp_d(&qp, 0) == 0) - SIGN(&qp) = MP_ZPOS; - - mp_clear(&qp); - } - - if(r) - *r = rem; - - return res; - -} /* end mp_div_d() */ - -/* }}} */ - -/* {{{ mp_div_2(a, c) */ - -/* - mp_div_2(a, c) - - Compute c = a / 2, disregarding the remainder. - */ - -mp_err mp_div_2(mp_int *a, mp_int *c) -{ - mp_err res; - - ARGCHK(a != NULL && c != NULL, MP_BADARG); - - if((res = mp_copy(a, c)) != MP_OKAY) - return res; - - s_mp_div_2(c); - - return MP_OKAY; - -} /* end mp_div_2() */ - -/* }}} */ - -/* {{{ mp_expt_d(a, d, b) */ - -mp_err mp_expt_d(mp_int *a, mp_digit d, mp_int *c) -{ - mp_int s, x; - mp_err res; - - ARGCHK(a != NULL && c != NULL, MP_BADARG); - - if((res = mp_init(&s)) != MP_OKAY) - return res; - if((res = mp_init_copy(&x, a)) != MP_OKAY) - goto X; - - DIGIT(&s, 0) = 1; - - while(d != 0) { - if(d & 1) { - if((res = s_mp_mul(&s, &x)) != MP_OKAY) - goto CLEANUP; - } - - d >>= 1; - - if((res = s_mp_sqr(&x)) != MP_OKAY) - goto CLEANUP; - } - - s_mp_exch(&s, c); - -CLEANUP: - mp_clear(&x); -X: - mp_clear(&s); - - return res; - -} /* end mp_expt_d() */ - -/* }}} */ - -/* }}} */ - -/*------------------------------------------------------------------------*/ -/* {{{ Full arithmetic */ - -/* {{{ mp_abs(a, b) */ - -/* - mp_abs(a, b) - - Compute b = |a|. 'a' and 'b' may be identical. - */ - -mp_err mp_abs(mp_int *a, mp_int *b) -{ - mp_err res; - - ARGCHK(a != NULL && b != NULL, MP_BADARG); - - if((res = mp_copy(a, b)) != MP_OKAY) - return res; - - SIGN(b) = MP_ZPOS; - - return MP_OKAY; - -} /* end mp_abs() */ - -/* }}} */ - -/* {{{ mp_neg(a, b) */ - -/* - mp_neg(a, b) - - Compute b = -a. 'a' and 'b' may be identical. - */ - -mp_err mp_neg(mp_int *a, mp_int *b) -{ - mp_err res; - - ARGCHK(a != NULL && b != NULL, MP_BADARG); - - if((res = mp_copy(a, b)) != MP_OKAY) - return res; - - if(s_mp_cmp_d(b, 0) == MP_EQ) - SIGN(b) = MP_ZPOS; - else - SIGN(b) = (SIGN(b) == MP_NEG) ? MP_ZPOS : MP_NEG; - - return MP_OKAY; - -} /* end mp_neg() */ - -/* }}} */ - -/* {{{ mp_add(a, b, c) */ - -/* - mp_add(a, b, c) - - Compute c = a + b. All parameters may be identical. - */ - -mp_err mp_add(mp_int *a, mp_int *b, mp_int *c) -{ - mp_err res; - int cmp; - - ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); - - if(SIGN(a) == SIGN(b)) { /* same sign: add values, keep sign */ - - /* Commutativity of addition lets us do this in either order, - so we avoid having to use a temporary even if the result - is supposed to replace the output - */ - if(c == b) { - if((res = s_mp_add(c, a)) != MP_OKAY) - return res; - } else { - if(c != a && (res = mp_copy(a, c)) != MP_OKAY) - return res; - - if((res = s_mp_add(c, b)) != MP_OKAY) - return res; - } - - } else if((cmp = s_mp_cmp(a, b)) > 0) { /* different sign: a > b */ - - /* If the output is going to be clobbered, we will use a temporary - variable; otherwise, we'll do it without touching the memory - allocator at all, if possible - */ - if(c == b) { - mp_int tmp; - - if((res = mp_init_copy(&tmp, a)) != MP_OKAY) - return res; - if((res = s_mp_sub(&tmp, b)) != MP_OKAY) { - mp_clear(&tmp); - return res; - } - - s_mp_exch(&tmp, c); - mp_clear(&tmp); - - } else { - - if(c != a && (res = mp_copy(a, c)) != MP_OKAY) - return res; - if((res = s_mp_sub(c, b)) != MP_OKAY) - return res; - - } - - } else if(cmp == 0) { /* different sign, a == b */ - - mp_zero(c); - return MP_OKAY; - - } else { /* different sign: a < b */ - - /* See above... */ - if(c == a) { - mp_int tmp; - - if((res = mp_init_copy(&tmp, b)) != MP_OKAY) - return res; - if((res = s_mp_sub(&tmp, a)) != MP_OKAY) { - mp_clear(&tmp); - return res; - } - - s_mp_exch(&tmp, c); - mp_clear(&tmp); - - } else { - - if(c != b && (res = mp_copy(b, c)) != MP_OKAY) - return res; - if((res = s_mp_sub(c, a)) != MP_OKAY) - return res; - - } - } - - if(USED(c) == 1 && DIGIT(c, 0) == 0) - SIGN(c) = MP_ZPOS; - - return MP_OKAY; - -} /* end mp_add() */ - -/* }}} */ - -/* {{{ mp_sub(a, b, c) */ - -/* - mp_sub(a, b, c) - - Compute c = a - b. All parameters may be identical. - */ - -mp_err mp_sub(mp_int *a, mp_int *b, mp_int *c) -{ - mp_err res; - int cmp; - - ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); - - if(SIGN(a) != SIGN(b)) { - if(c == a) { - if((res = s_mp_add(c, b)) != MP_OKAY) - return res; - } else { - if(c != b && ((res = mp_copy(b, c)) != MP_OKAY)) - return res; - if((res = s_mp_add(c, a)) != MP_OKAY) - return res; - SIGN(c) = SIGN(a); - } - - } else if((cmp = s_mp_cmp(a, b)) > 0) { /* Same sign, a > b */ - if(c == b) { - mp_int tmp; - - if((res = mp_init_copy(&tmp, a)) != MP_OKAY) - return res; - if((res = s_mp_sub(&tmp, b)) != MP_OKAY) { - mp_clear(&tmp); - return res; - } - s_mp_exch(&tmp, c); - mp_clear(&tmp); - - } else { - if(c != a && ((res = mp_copy(a, c)) != MP_OKAY)) - return res; - - if((res = s_mp_sub(c, b)) != MP_OKAY) - return res; - } - - } else if(cmp == 0) { /* Same sign, equal magnitude */ - mp_zero(c); - return MP_OKAY; - - } else { /* Same sign, b > a */ - if(c == a) { - mp_int tmp; - - if((res = mp_init_copy(&tmp, b)) != MP_OKAY) - return res; - - if((res = s_mp_sub(&tmp, a)) != MP_OKAY) { - mp_clear(&tmp); - return res; - } - s_mp_exch(&tmp, c); - mp_clear(&tmp); - - } else { - if(c != b && ((res = mp_copy(b, c)) != MP_OKAY)) - return res; - - if((res = s_mp_sub(c, a)) != MP_OKAY) - return res; - } - - SIGN(c) = !SIGN(b); - } - - if(USED(c) == 1 && DIGIT(c, 0) == 0) - SIGN(c) = MP_ZPOS; - - return MP_OKAY; - -} /* end mp_sub() */ - -/* }}} */ - -/* {{{ mp_mul(a, b, c) */ - -/* - mp_mul(a, b, c) - - Compute c = a * b. All parameters may be identical. - */ - -mp_err mp_mul(mp_int *a, mp_int *b, mp_int *c) -{ - mp_err res; - mp_sign sgn; - - ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); - - sgn = (SIGN(a) == SIGN(b)) ? MP_ZPOS : MP_NEG; - - if(c == b) { - if((res = s_mp_mul(c, a)) != MP_OKAY) - return res; - - } else { - if((res = mp_copy(a, c)) != MP_OKAY) - return res; - - if((res = s_mp_mul(c, b)) != MP_OKAY) - return res; - } - - if(sgn == MP_ZPOS || s_mp_cmp_d(c, 0) == MP_EQ) - SIGN(c) = MP_ZPOS; - else - SIGN(c) = sgn; - - return MP_OKAY; - -} /* end mp_mul() */ - -/* }}} */ - -/* {{{ mp_mul_2d(a, d, c) */ - -/* - mp_mul_2d(a, d, c) - - Compute c = a * 2^d. a may be the same as c. - */ - -mp_err mp_mul_2d(mp_int *a, mp_digit d, mp_int *c) -{ - mp_err res; - - ARGCHK(a != NULL && c != NULL, MP_BADARG); - - if((res = mp_copy(a, c)) != MP_OKAY) - return res; - - if(d == 0) - return MP_OKAY; - - return s_mp_mul_2d(c, d); - -} /* end mp_mul() */ - -/* }}} */ - -/* {{{ mp_sqr(a, b) */ - -#if MP_SQUARE -mp_err mp_sqr(mp_int *a, mp_int *b) -{ - mp_err res; - - ARGCHK(a != NULL && b != NULL, MP_BADARG); - - if((res = mp_copy(a, b)) != MP_OKAY) - return res; - - if((res = s_mp_sqr(b)) != MP_OKAY) - return res; - - SIGN(b) = MP_ZPOS; - - return MP_OKAY; - -} /* end mp_sqr() */ -#endif - -/* }}} */ - -/* {{{ mp_div(a, b, q, r) */ - -/* - mp_div(a, b, q, r) - - Compute q = a / b and r = a mod b. Input parameters may be re-used - as output parameters. If q or r is NULL, that portion of the - computation will be discarded (although it will still be computed) - - Pay no attention to the hacker behind the curtain. - */ - -mp_err mp_div(mp_int *a, mp_int *b, mp_int *q, mp_int *r) -{ - mp_err res; - mp_int qtmp, rtmp; - int cmp; - - ARGCHK(a != NULL && b != NULL, MP_BADARG); - - if(mp_cmp_z(b) == MP_EQ) - return MP_RANGE; - - /* If a <= b, we can compute the solution without division, and - avoid any memory allocation - */ - if((cmp = s_mp_cmp(a, b)) < 0) { - if(r) { - if((res = mp_copy(a, r)) != MP_OKAY) - return res; - } - - if(q) - mp_zero(q); - - return MP_OKAY; - - } else if(cmp == 0) { - - /* Set quotient to 1, with appropriate sign */ - if(q) { - int qneg = (SIGN(a) != SIGN(b)); - - mp_set(q, 1); - if(qneg) - SIGN(q) = MP_NEG; - } - - if(r) - mp_zero(r); - - return MP_OKAY; - } - - /* If we get here, it means we actually have to do some division */ - - /* Set up some temporaries... */ - if((res = mp_init_copy(&qtmp, a)) != MP_OKAY) - return res; - if((res = mp_init_copy(&rtmp, b)) != MP_OKAY) - goto CLEANUP; - - if((res = s_mp_div(&qtmp, &rtmp)) != MP_OKAY) - goto CLEANUP; - - /* Compute the signs for the output */ - SIGN(&rtmp) = SIGN(a); /* Sr = Sa */ - if(SIGN(a) == SIGN(b)) - SIGN(&qtmp) = MP_ZPOS; /* Sq = MP_ZPOS if Sa = Sb */ - else - SIGN(&qtmp) = MP_NEG; /* Sq = MP_NEG if Sa != Sb */ - - if(s_mp_cmp_d(&qtmp, 0) == MP_EQ) - SIGN(&qtmp) = MP_ZPOS; - if(s_mp_cmp_d(&rtmp, 0) == MP_EQ) - SIGN(&rtmp) = MP_ZPOS; - - /* Copy output, if it is needed */ - if(q) - s_mp_exch(&qtmp, q); - - if(r) - s_mp_exch(&rtmp, r); - -CLEANUP: - mp_clear(&rtmp); - mp_clear(&qtmp); - - return res; - -} /* end mp_div() */ - -/* }}} */ - -/* {{{ mp_div_2d(a, d, q, r) */ - -mp_err mp_div_2d(mp_int *a, mp_digit d, mp_int *q, mp_int *r) -{ - mp_err res; - - ARGCHK(a != NULL, MP_BADARG); - - if(q) { - if((res = mp_copy(a, q)) != MP_OKAY) - return res; - - s_mp_div_2d(q, d); - } - - if(r) { - if((res = mp_copy(a, r)) != MP_OKAY) - return res; - - s_mp_mod_2d(r, d); - } - - return MP_OKAY; - -} /* end mp_div_2d() */ - -/* }}} */ - -/* {{{ mp_expt(a, b, c) */ - -/* - mp_expt(a, b, c) - - Compute c = a ** b, that is, raise a to the b power. Uses a - standard iterative square-and-multiply technique. - */ - -mp_err mp_expt(mp_int *a, mp_int *b, mp_int *c) -{ - mp_int s, x; - mp_err res; - mp_digit d; - int dig, bit; - - ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); - - if(mp_cmp_z(b) < 0) - return MP_RANGE; - - if((res = mp_init(&s)) != MP_OKAY) - return res; - - mp_set(&s, 1); - - if((res = mp_init_copy(&x, a)) != MP_OKAY) - goto X; - - /* Loop over low-order digits in ascending order */ - for(dig = 0; dig < (USED(b) - 1); dig++) { - d = DIGIT(b, dig); - - /* Loop over bits of each non-maximal digit */ - for(bit = 0; bit < DIGIT_BIT; bit++) { - if(d & 1) { - if((res = s_mp_mul(&s, &x)) != MP_OKAY) - goto CLEANUP; - } - - d >>= 1; - - if((res = s_mp_sqr(&x)) != MP_OKAY) - goto CLEANUP; - } - } - - /* Consider now the last digit... */ - d = DIGIT(b, dig); - - while(d) { - if(d & 1) { - if((res = s_mp_mul(&s, &x)) != MP_OKAY) - goto CLEANUP; - } - - d >>= 1; - - if((res = s_mp_sqr(&x)) != MP_OKAY) - goto CLEANUP; - } - - if(mp_iseven(b)) - SIGN(&s) = SIGN(a); - - res = mp_copy(&s, c); - -CLEANUP: - mp_clear(&x); -X: - mp_clear(&s); - - return res; - -} /* end mp_expt() */ - -/* }}} */ - -/* {{{ mp_2expt(a, k) */ - -/* Compute a = 2^k */ - -mp_err mp_2expt(mp_int *a, mp_digit k) -{ - ARGCHK(a != NULL, MP_BADARG); - - return s_mp_2expt(a, k); - -} /* end mp_2expt() */ - -/* }}} */ - -/* {{{ mp_mod(a, m, c) */ - -/* - mp_mod(a, m, c) - - Compute c = a (mod m). Result will always be 0 <= c < m. - */ - -mp_err mp_mod(mp_int *a, mp_int *m, mp_int *c) -{ - mp_err res; - int mag; - - ARGCHK(a != NULL && m != NULL && c != NULL, MP_BADARG); - - if(SIGN(m) == MP_NEG) - return MP_RANGE; - - /* - If |a| > m, we need to divide to get the remainder and take the - absolute value. - - If |a| < m, we don't need to do any division, just copy and adjust - the sign (if a is negative). - - If |a| == m, we can simply set the result to zero. - - This order is intended to minimize the average path length of the - comparison chain on common workloads -- the most frequent cases are - that |a| != m, so we do those first. - */ - if((mag = s_mp_cmp(a, m)) > 0) { - if((res = mp_div(a, m, NULL, c)) != MP_OKAY) - return res; - - if(SIGN(c) == MP_NEG) { - if((res = mp_add(c, m, c)) != MP_OKAY) - return res; - } - - } else if(mag < 0) { - if((res = mp_copy(a, c)) != MP_OKAY) - return res; - - if(mp_cmp_z(a) < 0) { - if((res = mp_add(c, m, c)) != MP_OKAY) - return res; - - } - - } else { - mp_zero(c); - - } - - return MP_OKAY; - -} /* end mp_mod() */ - -/* }}} */ - -/* {{{ mp_mod_d(a, d, c) */ - -/* - mp_mod_d(a, d, c) - - Compute c = a (mod d). Result will always be 0 <= c < d - */ -mp_err mp_mod_d(mp_int *a, mp_digit d, mp_digit *c) -{ - mp_err res; - mp_digit rem; - - ARGCHK(a != NULL && c != NULL, MP_BADARG); - - if(s_mp_cmp_d(a, d) > 0) { - if((res = mp_div_d(a, d, NULL, &rem)) != MP_OKAY) - return res; - - } else { - if(SIGN(a) == MP_NEG) - rem = d - DIGIT(a, 0); - else - rem = DIGIT(a, 0); - } - - if(c) - *c = rem; - - return MP_OKAY; - -} /* end mp_mod_d() */ - -/* }}} */ - -/* {{{ mp_sqrt(a, b) */ - -/* - mp_sqrt(a, b) - - Compute the integer square root of a, and store the result in b. - Uses an integer-arithmetic version of Newton's iterative linear - approximation technique to determine this value; the result has the - following two properties: - - b^2 <= a - (b+1)^2 >= a - - It is a range error to pass a negative value. - */ -mp_err mp_sqrt(mp_int *a, mp_int *b) -{ - mp_int x, t; - mp_err res; - - ARGCHK(a != NULL && b != NULL, MP_BADARG); - - /* Cannot take square root of a negative value */ - if(SIGN(a) == MP_NEG) - return MP_RANGE; - - /* Special cases for zero and one, trivial */ - if(mp_cmp_d(a, 0) == MP_EQ || mp_cmp_d(a, 1) == MP_EQ) - return mp_copy(a, b); - - /* Initialize the temporaries we'll use below */ - if((res = mp_init_size(&t, USED(a))) != MP_OKAY) - return res; - - /* Compute an initial guess for the iteration as a itself */ - if((res = mp_init_copy(&x, a)) != MP_OKAY) - goto X; - -s_mp_rshd(&x, (USED(&x)/2)+1); -mp_add_d(&x, 1, &x); - - for(;;) { - /* t = (x * x) - a */ - mp_copy(&x, &t); /* can't fail, t is big enough for original x */ - if((res = mp_sqr(&t, &t)) != MP_OKAY || - (res = mp_sub(&t, a, &t)) != MP_OKAY) - goto CLEANUP; - - /* t = t / 2x */ - s_mp_mul_2(&x); - if((res = mp_div(&t, &x, &t, NULL)) != MP_OKAY) - goto CLEANUP; - s_mp_div_2(&x); - - /* Terminate the loop, if the quotient is zero */ - if(mp_cmp_z(&t) == MP_EQ) - break; - - /* x = x - t */ - if((res = mp_sub(&x, &t, &x)) != MP_OKAY) - goto CLEANUP; - - } - - /* Copy result to output parameter */ - mp_sub_d(&x, 1, &x); - s_mp_exch(&x, b); - - CLEANUP: - mp_clear(&x); - X: - mp_clear(&t); - - return res; - -} /* end mp_sqrt() */ - -/* }}} */ - -/* }}} */ - -/*------------------------------------------------------------------------*/ -/* {{{ Modular arithmetic */ - -#if MP_MODARITH -/* {{{ mp_addmod(a, b, m, c) */ - -/* - mp_addmod(a, b, m, c) - - Compute c = (a + b) mod m - */ - -mp_err mp_addmod(mp_int *a, mp_int *b, mp_int *m, mp_int *c) -{ - mp_err res; - - ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG); - - if((res = mp_add(a, b, c)) != MP_OKAY) - return res; - if((res = mp_mod(c, m, c)) != MP_OKAY) - return res; - - return MP_OKAY; - -} - -/* }}} */ - -/* {{{ mp_submod(a, b, m, c) */ - -/* - mp_submod(a, b, m, c) - - Compute c = (a - b) mod m - */ - -mp_err mp_submod(mp_int *a, mp_int *b, mp_int *m, mp_int *c) -{ - mp_err res; - - ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG); - - if((res = mp_sub(a, b, c)) != MP_OKAY) - return res; - if((res = mp_mod(c, m, c)) != MP_OKAY) - return res; - - return MP_OKAY; - -} - -/* }}} */ - -/* {{{ mp_mulmod(a, b, m, c) */ - -/* - mp_mulmod(a, b, m, c) - - Compute c = (a * b) mod m - */ - -mp_err mp_mulmod(mp_int *a, mp_int *b, mp_int *m, mp_int *c) -{ - mp_err res; - - ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG); - - if((res = mp_mul(a, b, c)) != MP_OKAY) - return res; - if((res = mp_mod(c, m, c)) != MP_OKAY) - return res; - - return MP_OKAY; - -} - -/* }}} */ - -/* {{{ mp_sqrmod(a, m, c) */ - -#if MP_SQUARE -mp_err mp_sqrmod(mp_int *a, mp_int *m, mp_int *c) -{ - mp_err res; - - ARGCHK(a != NULL && m != NULL && c != NULL, MP_BADARG); - - if((res = mp_sqr(a, c)) != MP_OKAY) - return res; - if((res = mp_mod(c, m, c)) != MP_OKAY) - return res; - - return MP_OKAY; - -} /* end mp_sqrmod() */ -#endif - -/* }}} */ - -/* {{{ mp_exptmod(a, b, m, c) */ - -/* - mp_exptmod(a, b, m, c) - - Compute c = (a ** b) mod m. Uses a standard square-and-multiply - method with modular reductions at each step. (This is basically the - same code as mp_expt(), except for the addition of the reductions) - - The modular reductions are done using Barrett's algorithm (see - s_mp_reduce() below for details) - */ - -mp_err mp_exptmod(mp_int *a, mp_int *b, mp_int *m, mp_int *c) -{ - mp_int s, x, mu; - mp_err res; - mp_digit d, *db = DIGITS(b); - mp_size ub = USED(b); - int dig, bit; - - ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); - - if(mp_cmp_z(b) < 0 || mp_cmp_z(m) <= 0) - return MP_RANGE; - - if((res = mp_init(&s)) != MP_OKAY) - return res; - if((res = mp_init_copy(&x, a)) != MP_OKAY) - goto X; - if((res = mp_mod(&x, m, &x)) != MP_OKAY || - (res = mp_init(&mu)) != MP_OKAY) - goto MU; - - mp_set(&s, 1); - - /* mu = b^2k / m */ - s_mp_add_d(&mu, 1); - s_mp_lshd(&mu, 2 * USED(m)); - if((res = mp_div(&mu, m, &mu, NULL)) != MP_OKAY) - goto CLEANUP; - - /* Loop over digits of b in ascending order, except highest order */ - for(dig = 0; dig < (ub - 1); dig++) { - d = *db++; - - /* Loop over the bits of the lower-order digits */ - for(bit = 0; bit < DIGIT_BIT; bit++) { - if(d & 1) { - if((res = s_mp_mul(&s, &x)) != MP_OKAY) - goto CLEANUP; - if((res = s_mp_reduce(&s, m, &mu)) != MP_OKAY) - goto CLEANUP; - } - - d >>= 1; - - if((res = s_mp_sqr(&x)) != MP_OKAY) - goto CLEANUP; - if((res = s_mp_reduce(&x, m, &mu)) != MP_OKAY) - goto CLEANUP; - } - } - - /* Now do the last digit... */ - d = *db; - - while(d) { - if(d & 1) { - if((res = s_mp_mul(&s, &x)) != MP_OKAY) - goto CLEANUP; - if((res = s_mp_reduce(&s, m, &mu)) != MP_OKAY) - goto CLEANUP; - } - - d >>= 1; - - if((res = s_mp_sqr(&x)) != MP_OKAY) - goto CLEANUP; - if((res = s_mp_reduce(&x, m, &mu)) != MP_OKAY) - goto CLEANUP; - } - - s_mp_exch(&s, c); - - CLEANUP: - mp_clear(&mu); - MU: - mp_clear(&x); - X: - mp_clear(&s); - - return res; - -} /* end mp_exptmod() */ - -/* }}} */ - -/* {{{ mp_exptmod_d(a, d, m, c) */ - -mp_err mp_exptmod_d(mp_int *a, mp_digit d, mp_int *m, mp_int *c) -{ - mp_int s, x; - mp_err res; - - ARGCHK(a != NULL && c != NULL, MP_BADARG); - - if((res = mp_init(&s)) != MP_OKAY) - return res; - if((res = mp_init_copy(&x, a)) != MP_OKAY) - goto X; - - mp_set(&s, 1); - - while(d != 0) { - if(d & 1) { - if((res = s_mp_mul(&s, &x)) != MP_OKAY || - (res = mp_mod(&s, m, &s)) != MP_OKAY) - goto CLEANUP; - } - - d /= 2; - - if((res = s_mp_sqr(&x)) != MP_OKAY || - (res = mp_mod(&x, m, &x)) != MP_OKAY) - goto CLEANUP; - } - - s_mp_exch(&s, c); - -CLEANUP: - mp_clear(&x); -X: - mp_clear(&s); - - return res; - -} /* end mp_exptmod_d() */ - -/* }}} */ -#endif /* if MP_MODARITH */ - -/* }}} */ - -/*------------------------------------------------------------------------*/ -/* {{{ Comparison functions */ - -/* {{{ mp_cmp_z(a) */ - -/* - mp_cmp_z(a) - - Compare a <=> 0. Returns <0 if a<0, 0 if a=0, >0 if a>0. - */ - -int mp_cmp_z(mp_int *a) -{ - if(SIGN(a) == MP_NEG) - return MP_LT; - else if(USED(a) == 1 && DIGIT(a, 0) == 0) - return MP_EQ; - else - return MP_GT; - -} /* end mp_cmp_z() */ - -/* }}} */ - -/* {{{ mp_cmp_d(a, d) */ - -/* - mp_cmp_d(a, d) - - Compare a <=> d. Returns <0 if a0 if a>d - */ - -int mp_cmp_d(mp_int *a, mp_digit d) -{ - ARGCHK(a != NULL, MP_EQ); - - if(SIGN(a) == MP_NEG) - return MP_LT; - - return s_mp_cmp_d(a, d); - -} /* end mp_cmp_d() */ - -/* }}} */ - -/* {{{ mp_cmp(a, b) */ - -int mp_cmp(mp_int *a, mp_int *b) -{ - ARGCHK(a != NULL && b != NULL, MP_EQ); - - if(SIGN(a) == SIGN(b)) { - int mag; - - if((mag = s_mp_cmp(a, b)) == MP_EQ) - return MP_EQ; - - if(SIGN(a) == MP_ZPOS) - return mag; - else - return -mag; - - } else if(SIGN(a) == MP_ZPOS) { - return MP_GT; - } else { - return MP_LT; - } - -} /* end mp_cmp() */ - -/* }}} */ - -/* {{{ mp_cmp_mag(a, b) */ - -/* - mp_cmp_mag(a, b) - - Compares |a| <=> |b|, and returns an appropriate comparison result - */ - -int mp_cmp_mag(mp_int *a, mp_int *b) -{ - ARGCHK(a != NULL && b != NULL, MP_EQ); - - return s_mp_cmp(a, b); - -} /* end mp_cmp_mag() */ - -/* }}} */ - -/* {{{ mp_cmp_int(a, z) */ - -/* - This just converts z to an mp_int, and uses the existing comparison - routines. This is sort of inefficient, but it's not clear to me how - frequently this wil get used anyway. For small positive constants, - you can always use mp_cmp_d(), and for zero, there is mp_cmp_z(). - */ -int mp_cmp_int(mp_int *a, long z) -{ - mp_int tmp; - int out; - - ARGCHK(a != NULL, MP_EQ); - - mp_init(&tmp); mp_set_int(&tmp, z); - out = mp_cmp(a, &tmp); - mp_clear(&tmp); - - return out; - -} /* end mp_cmp_int() */ - -/* }}} */ - -/* {{{ mp_isodd(a) */ - -/* - mp_isodd(a) - - Returns a true (non-zero) value if a is odd, false (zero) otherwise. - */ -int mp_isodd(mp_int *a) -{ - ARGCHK(a != NULL, 0); - - return (DIGIT(a, 0) & 1); - -} /* end mp_isodd() */ - -/* }}} */ - -/* {{{ mp_iseven(a) */ - -int mp_iseven(mp_int *a) -{ - return !mp_isodd(a); - -} /* end mp_iseven() */ - -/* }}} */ - -/* }}} */ - -/*------------------------------------------------------------------------*/ -/* {{{ Number theoretic functions */ - -#if MP_NUMTH -/* {{{ mp_gcd(a, b, c) */ - -/* - Like the old mp_gcd() function, except computes the GCD using the - binary algorithm due to Josef Stein in 1961 (via Knuth). - */ -mp_err mp_gcd(mp_int *a, mp_int *b, mp_int *c) -{ - mp_err res; - mp_int u, v, t; - mp_size k = 0; - - ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); - - if(mp_cmp_z(a) == MP_EQ && mp_cmp_z(b) == MP_EQ) - return MP_RANGE; - if(mp_cmp_z(a) == MP_EQ) { - return mp_copy(b, c); - } else if(mp_cmp_z(b) == MP_EQ) { - return mp_copy(a, c); - } - - if((res = mp_init(&t)) != MP_OKAY) - return res; - if((res = mp_init_copy(&u, a)) != MP_OKAY) - goto U; - if((res = mp_init_copy(&v, b)) != MP_OKAY) - goto V; - - SIGN(&u) = MP_ZPOS; - SIGN(&v) = MP_ZPOS; - - /* Divide out common factors of 2 until at least 1 of a, b is even */ - while(mp_iseven(&u) && mp_iseven(&v)) { - s_mp_div_2(&u); - s_mp_div_2(&v); - ++k; - } - - /* Initialize t */ - if(mp_isodd(&u)) { - if((res = mp_copy(&v, &t)) != MP_OKAY) - goto CLEANUP; - - /* t = -v */ - if(SIGN(&v) == MP_ZPOS) - SIGN(&t) = MP_NEG; - else - SIGN(&t) = MP_ZPOS; - - } else { - if((res = mp_copy(&u, &t)) != MP_OKAY) - goto CLEANUP; - - } - - for(;;) { - while(mp_iseven(&t)) { - s_mp_div_2(&t); - } - - if(mp_cmp_z(&t) == MP_GT) { - if((res = mp_copy(&t, &u)) != MP_OKAY) - goto CLEANUP; - - } else { - if((res = mp_copy(&t, &v)) != MP_OKAY) - goto CLEANUP; - - /* v = -t */ - if(SIGN(&t) == MP_ZPOS) - SIGN(&v) = MP_NEG; - else - SIGN(&v) = MP_ZPOS; - } - - if((res = mp_sub(&u, &v, &t)) != MP_OKAY) - goto CLEANUP; - - if(s_mp_cmp_d(&t, 0) == MP_EQ) - break; - } - - s_mp_2expt(&v, k); /* v = 2^k */ - res = mp_mul(&u, &v, c); /* c = u * v */ - - CLEANUP: - mp_clear(&v); - V: - mp_clear(&u); - U: - mp_clear(&t); - - return res; - -} /* end mp_bgcd() */ - -/* }}} */ - -/* {{{ mp_lcm(a, b, c) */ - -/* We compute the least common multiple using the rule: - - ab = [a, b](a, b) - - ... by computing the product, and dividing out the gcd. - */ - -mp_err mp_lcm(mp_int *a, mp_int *b, mp_int *c) -{ - mp_int gcd, prod; - mp_err res; - - ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); - - /* Set up temporaries */ - if((res = mp_init(&gcd)) != MP_OKAY) - return res; - if((res = mp_init(&prod)) != MP_OKAY) - goto GCD; - - if((res = mp_mul(a, b, &prod)) != MP_OKAY) - goto CLEANUP; - if((res = mp_gcd(a, b, &gcd)) != MP_OKAY) - goto CLEANUP; - - res = mp_div(&prod, &gcd, c, NULL); - - CLEANUP: - mp_clear(&prod); - GCD: - mp_clear(&gcd); - - return res; - -} /* end mp_lcm() */ - -/* }}} */ - -/* {{{ mp_xgcd(a, b, g, x, y) */ - -/* - mp_xgcd(a, b, g, x, y) - - Compute g = (a, b) and values x and y satisfying Bezout's identity - (that is, ax + by = g). This uses the extended binary GCD algorithm - based on the Stein algorithm used for mp_gcd() - */ - -mp_err mp_xgcd(mp_int *a, mp_int *b, mp_int *g, mp_int *x, mp_int *y) -{ - mp_int gx, xc, yc, u, v, A, B, C, D; - mp_int *clean[9]; - mp_err res; - int last = -1; - - if(mp_cmp_z(b) == 0) - return MP_RANGE; - - /* Initialize all these variables we need */ - if((res = mp_init(&u)) != MP_OKAY) goto CLEANUP; - clean[++last] = &u; - if((res = mp_init(&v)) != MP_OKAY) goto CLEANUP; - clean[++last] = &v; - if((res = mp_init(&gx)) != MP_OKAY) goto CLEANUP; - clean[++last] = &gx; - if((res = mp_init(&A)) != MP_OKAY) goto CLEANUP; - clean[++last] = &A; - if((res = mp_init(&B)) != MP_OKAY) goto CLEANUP; - clean[++last] = &B; - if((res = mp_init(&C)) != MP_OKAY) goto CLEANUP; - clean[++last] = &C; - if((res = mp_init(&D)) != MP_OKAY) goto CLEANUP; - clean[++last] = &D; - if((res = mp_init_copy(&xc, a)) != MP_OKAY) goto CLEANUP; - clean[++last] = &xc; - mp_abs(&xc, &xc); - if((res = mp_init_copy(&yc, b)) != MP_OKAY) goto CLEANUP; - clean[++last] = &yc; - mp_abs(&yc, &yc); - - mp_set(&gx, 1); - - /* Divide by two until at least one of them is even */ - while(mp_iseven(&xc) && mp_iseven(&yc)) { - s_mp_div_2(&xc); - s_mp_div_2(&yc); - if((res = s_mp_mul_2(&gx)) != MP_OKAY) - goto CLEANUP; - } - - mp_copy(&xc, &u); - mp_copy(&yc, &v); - mp_set(&A, 1); mp_set(&D, 1); - - /* Loop through binary GCD algorithm */ - for(;;) { - while(mp_iseven(&u)) { - s_mp_div_2(&u); - - if(mp_iseven(&A) && mp_iseven(&B)) { - s_mp_div_2(&A); s_mp_div_2(&B); - } else { - if((res = mp_add(&A, &yc, &A)) != MP_OKAY) goto CLEANUP; - s_mp_div_2(&A); - if((res = mp_sub(&B, &xc, &B)) != MP_OKAY) goto CLEANUP; - s_mp_div_2(&B); - } - } - - while(mp_iseven(&v)) { - s_mp_div_2(&v); - - if(mp_iseven(&C) && mp_iseven(&D)) { - s_mp_div_2(&C); s_mp_div_2(&D); - } else { - if((res = mp_add(&C, &yc, &C)) != MP_OKAY) goto CLEANUP; - s_mp_div_2(&C); - if((res = mp_sub(&D, &xc, &D)) != MP_OKAY) goto CLEANUP; - s_mp_div_2(&D); - } - } - - if(mp_cmp(&u, &v) >= 0) { - if((res = mp_sub(&u, &v, &u)) != MP_OKAY) goto CLEANUP; - if((res = mp_sub(&A, &C, &A)) != MP_OKAY) goto CLEANUP; - if((res = mp_sub(&B, &D, &B)) != MP_OKAY) goto CLEANUP; - - } else { - if((res = mp_sub(&v, &u, &v)) != MP_OKAY) goto CLEANUP; - if((res = mp_sub(&C, &A, &C)) != MP_OKAY) goto CLEANUP; - if((res = mp_sub(&D, &B, &D)) != MP_OKAY) goto CLEANUP; - - } - - /* If we're done, copy results to output */ - if(mp_cmp_z(&u) == 0) { - if(x) - if((res = mp_copy(&C, x)) != MP_OKAY) goto CLEANUP; - - if(y) - if((res = mp_copy(&D, y)) != MP_OKAY) goto CLEANUP; - - if(g) - if((res = mp_mul(&gx, &v, g)) != MP_OKAY) goto CLEANUP; - - break; - } - } - - CLEANUP: - while(last >= 0) - mp_clear(clean[last--]); - - return res; - -} /* end mp_xgcd() */ - -/* }}} */ - -/* {{{ mp_invmod(a, m, c) */ - -/* - mp_invmod(a, m, c) - - Compute c = a^-1 (mod m), if there is an inverse for a (mod m). - This is equivalent to the question of whether (a, m) = 1. If not, - MP_UNDEF is returned, and there is no inverse. - */ - -mp_err mp_invmod(mp_int *a, mp_int *m, mp_int *c) -{ - mp_int g, x; - mp_err res; - - ARGCHK(a && m && c, MP_BADARG); - - if(mp_cmp_z(a) == 0 || mp_cmp_z(m) == 0) - return MP_RANGE; - - if((res = mp_init(&g)) != MP_OKAY) - return res; - if((res = mp_init(&x)) != MP_OKAY) - goto X; - - if((res = mp_xgcd(a, m, &g, &x, NULL)) != MP_OKAY) - goto CLEANUP; - - if(mp_cmp_d(&g, 1) != MP_EQ) { - res = MP_UNDEF; - goto CLEANUP; - } - - res = mp_mod(&x, m, c); - SIGN(c) = SIGN(a); - -CLEANUP: - mp_clear(&x); -X: - mp_clear(&g); - - return res; - -} /* end mp_invmod() */ - -/* }}} */ -#endif /* if MP_NUMTH */ - -/* }}} */ - -/*------------------------------------------------------------------------*/ -/* {{{ mp_print(mp, ofp) */ - -#if MP_IOFUNC -/* - mp_print(mp, ofp) - - Print a textual representation of the given mp_int on the output - stream 'ofp'. Output is generated using the internal radix. - */ - -void mp_print(mp_int *mp, FILE *ofp) -{ - int ix; - - if(mp == NULL || ofp == NULL) - return; - - fputc((SIGN(mp) == MP_NEG) ? '-' : '+', ofp); - - for(ix = USED(mp) - 1; ix >= 0; ix--) { - fprintf(ofp, DIGIT_FMT, DIGIT(mp, ix)); - } - -} /* end mp_print() */ - -#endif /* if MP_IOFUNC */ - -/* }}} */ - -/*------------------------------------------------------------------------*/ -/* {{{ More I/O Functions */ - -/* {{{ mp_read_signed_bin(mp, str, len) */ - -/* - mp_read_signed_bin(mp, str, len) - - Read in a raw value (base 256) into the given mp_int - */ - -mp_err mp_read_signed_bin(mp_int *mp, unsigned char *str, int len) -{ - mp_err res; - - ARGCHK(mp != NULL && str != NULL && len > 0, MP_BADARG); - - if((res = mp_read_unsigned_bin(mp, str + 1, len - 1)) == MP_OKAY) { - /* Get sign from first byte */ - if(str[0]) - SIGN(mp) = MP_NEG; - else - SIGN(mp) = MP_ZPOS; - } - - return res; - -} /* end mp_read_signed_bin() */ - -/* }}} */ - -/* {{{ mp_signed_bin_size(mp) */ - -int mp_signed_bin_size(mp_int *mp) -{ - ARGCHK(mp != NULL, 0); - - return mp_unsigned_bin_size(mp) + 1; - -} /* end mp_signed_bin_size() */ - -/* }}} */ - -/* {{{ mp_to_signed_bin(mp, str) */ - -mp_err mp_to_signed_bin(mp_int *mp, unsigned char *str) -{ - ARGCHK(mp != NULL && str != NULL, MP_BADARG); - - /* Caller responsible for allocating enough memory (use mp_raw_size(mp)) */ - str[0] = (char)SIGN(mp); - - return mp_to_unsigned_bin(mp, str + 1); - -} /* end mp_to_signed_bin() */ - -/* }}} */ - -/* {{{ mp_read_unsigned_bin(mp, str, len) */ - -/* - mp_read_unsigned_bin(mp, str, len) - - Read in an unsigned value (base 256) into the given mp_int - */ - -mp_err mp_read_unsigned_bin(mp_int *mp, unsigned char *str, int len) -{ - int ix; - mp_err res; - - ARGCHK(mp != NULL && str != NULL && len > 0, MP_BADARG); - - mp_zero(mp); - - for(ix = 0; ix < len; ix++) { - if((res = s_mp_mul_2d(mp, CHAR_BIT)) != MP_OKAY) - return res; - - if((res = mp_add_d(mp, str[ix], mp)) != MP_OKAY) - return res; - } - - return MP_OKAY; - -} /* end mp_read_unsigned_bin() */ - -/* }}} */ - -/* {{{ mp_unsigned_bin_size(mp) */ - -int mp_unsigned_bin_size(mp_int *mp) -{ - mp_digit topdig; - int count; - - ARGCHK(mp != NULL, 0); - - /* Special case for the value zero */ - if(USED(mp) == 1 && DIGIT(mp, 0) == 0) - return 1; - - count = (USED(mp) - 1) * sizeof(mp_digit); - topdig = DIGIT(mp, USED(mp) - 1); - - while(topdig != 0) { - ++count; - topdig >>= CHAR_BIT; - } - - return count; - -} /* end mp_unsigned_bin_size() */ - -/* }}} */ - -/* {{{ mp_to_unsigned_bin(mp, str) */ - -mp_err mp_to_unsigned_bin(mp_int *mp, unsigned char *str) -{ - mp_digit *dp, *end, d; - unsigned char *spos; - - ARGCHK(mp != NULL && str != NULL, MP_BADARG); - - dp = DIGITS(mp); - end = dp + USED(mp) - 1; - spos = str; - - /* Special case for zero, quick test */ - if(dp == end && *dp == 0) { - *str = '\0'; - return MP_OKAY; - } - - /* Generate digits in reverse order */ - while(dp < end) { - int ix; - - d = *dp; - for(ix = 0; ix < sizeof(mp_digit); ++ix) { - *spos = d & UCHAR_MAX; - d >>= CHAR_BIT; - ++spos; - } - - ++dp; - } - - /* Now handle last digit specially, high order zeroes are not written */ - d = *end; - while(d != 0) { - *spos = d & UCHAR_MAX; - d >>= CHAR_BIT; - ++spos; - } - - /* Reverse everything to get digits in the correct order */ - while(--spos > str) { - unsigned char t = *str; - *str = *spos; - *spos = t; - - ++str; - } - - return MP_OKAY; - -} /* end mp_to_unsigned_bin() */ - -/* }}} */ - -/* {{{ mp_count_bits(mp) */ - -int mp_count_bits(mp_int *mp) -{ - int len; - mp_digit d; - - ARGCHK(mp != NULL, MP_BADARG); - - len = DIGIT_BIT * (USED(mp) - 1); - d = DIGIT(mp, USED(mp) - 1); - - while(d != 0) { - ++len; - d >>= 1; - } - - return len; - -} /* end mp_count_bits() */ - -/* }}} */ - -/* {{{ mp_read_radix(mp, str, radix) */ - -/* - mp_read_radix(mp, str, radix) - - Read an integer from the given string, and set mp to the resulting - value. The input is presumed to be in base 10. Leading non-digit - characters are ignored, and the function reads until a non-digit - character or the end of the string. - */ - -mp_err mp_read_radix(mp_int *mp, unsigned char *str, int radix) -{ - int ix = 0, val = 0; - mp_err res; - mp_sign sig = MP_ZPOS; - - ARGCHK(mp != NULL && str != NULL && radix >= 2 && radix <= MAX_RADIX, - MP_BADARG); - - mp_zero(mp); - - /* Skip leading non-digit characters until a digit or '-' or '+' */ - while(str[ix] && - (s_mp_tovalue(str[ix], radix) < 0) && - str[ix] != '-' && - str[ix] != '+') { - ++ix; - } - - if(str[ix] == '-') { - sig = MP_NEG; - ++ix; - } else if(str[ix] == '+') { - sig = MP_ZPOS; /* this is the default anyway... */ - ++ix; - } - - while((val = s_mp_tovalue(str[ix], radix)) >= 0) { - if((res = s_mp_mul_d(mp, radix)) != MP_OKAY) - return res; - if((res = s_mp_add_d(mp, val)) != MP_OKAY) - return res; - ++ix; - } - - if(s_mp_cmp_d(mp, 0) == MP_EQ) - SIGN(mp) = MP_ZPOS; - else - SIGN(mp) = sig; - - return MP_OKAY; - -} /* end mp_read_radix() */ - -/* }}} */ - -/* {{{ mp_radix_size(mp, radix) */ - -int mp_radix_size(mp_int *mp, int radix) -{ - int len; - ARGCHK(mp != NULL, 0); - - len = s_mp_outlen(mp_count_bits(mp), radix) + 1; /* for NUL terminator */ - - if(mp_cmp_z(mp) < 0) - ++len; /* for sign */ - - return len; - -} /* end mp_radix_size() */ - -/* }}} */ - -/* {{{ mp_value_radix_size(num, qty, radix) */ - -/* num = number of digits - qty = number of bits per digit - radix = target base - - Return the number of digits in the specified radix that would be - needed to express 'num' digits of 'qty' bits each. - */ -int mp_value_radix_size(int num, int qty, int radix) -{ - ARGCHK(num >= 0 && qty > 0 && radix >= 2 && radix <= MAX_RADIX, 0); - - return s_mp_outlen(num * qty, radix); - -} /* end mp_value_radix_size() */ - -/* }}} */ - -/* {{{ mp_toradix(mp, str, radix) */ - -mp_err mp_toradix(mp_int *mp, unsigned char *str, int radix) -{ - int ix, pos = 0; - - ARGCHK(mp != NULL && str != NULL, MP_BADARG); - ARGCHK(radix > 1 && radix <= MAX_RADIX, MP_RANGE); - - if(mp_cmp_z(mp) == MP_EQ) { - str[0] = '0'; - str[1] = '\0'; - } else { - mp_err res; - mp_int tmp; - mp_sign sgn; - mp_digit rem, rdx = (mp_digit)radix; - char ch; - - if((res = mp_init_copy(&tmp, mp)) != MP_OKAY) - return res; - - /* Save sign for later, and take absolute value */ - sgn = SIGN(&tmp); SIGN(&tmp) = MP_ZPOS; - - /* Generate output digits in reverse order */ - while(mp_cmp_z(&tmp) != 0) { - if((res = s_mp_div_d(&tmp, rdx, &rem)) != MP_OKAY) { - mp_clear(&tmp); - return res; - } - - /* Generate digits, use capital letters */ - ch = s_mp_todigit(rem, radix, 0); - - str[pos++] = ch; - } - - /* Add - sign if original value was negative */ - if(sgn == MP_NEG) - str[pos++] = '-'; - - /* Add trailing NUL to end the string */ - str[pos--] = '\0'; - - /* Reverse the digits and sign indicator */ - ix = 0; - while(ix < pos) { - char tmp = str[ix]; - - str[ix] = str[pos]; - str[pos] = tmp; - ++ix; - --pos; - } - - mp_clear(&tmp); - } - - return MP_OKAY; - -} /* end mp_toradix() */ - -/* }}} */ - -/* {{{ mp_char2value(ch, r) */ - -int mp_char2value(char ch, int r) -{ - return s_mp_tovalue(ch, r); - -} /* end mp_tovalue() */ - -/* }}} */ - -/* }}} */ - -/* {{{ mp_strerror(ec) */ - -/* - mp_strerror(ec) - - Return a string describing the meaning of error code 'ec'. The - string returned is allocated in static memory, so the caller should - not attempt to modify or free the memory associated with this - string. - */ -const char *mp_strerror(mp_err ec) -{ - int aec = (ec < 0) ? -ec : ec; - - /* Code values are negative, so the senses of these comparisons - are accurate */ - if(ec < MP_LAST_CODE || ec > MP_OKAY) { - return mp_err_string[0]; /* unknown error code */ - } else { - return mp_err_string[aec + 1]; - } - -} /* end mp_strerror() */ - -/* }}} */ - -/*========================================================================*/ -/*------------------------------------------------------------------------*/ -/* Static function definitions (internal use only) */ - -/* {{{ Memory management */ - -/* {{{ s_mp_grow(mp, min) */ - -/* Make sure there are at least 'min' digits allocated to mp */ -mp_err s_mp_grow(mp_int *mp, mp_size min) -{ - if(min > ALLOC(mp)) { - mp_digit *tmp; - - /* Set min to next nearest default precision block size */ - min = ((min + (s_mp_defprec - 1)) / s_mp_defprec) * s_mp_defprec; - - if((tmp = s_mp_alloc(min, sizeof(mp_digit))) == NULL) - return MP_MEM; - - s_mp_copy(DIGITS(mp), tmp, USED(mp)); - -#if MP_CRYPTO - s_mp_setz(DIGITS(mp), ALLOC(mp)); -#endif - s_mp_free(DIGITS(mp)); - DIGITS(mp) = tmp; - ALLOC(mp) = min; - } - - return MP_OKAY; - -} /* end s_mp_grow() */ - -/* }}} */ - -/* {{{ s_mp_pad(mp, min) */ - -/* Make sure the used size of mp is at least 'min', growing if needed */ -mp_err s_mp_pad(mp_int *mp, mp_size min) -{ - if(min > USED(mp)) { - mp_err res; - - /* Make sure there is room to increase precision */ - if(min > ALLOC(mp) && (res = s_mp_grow(mp, min)) != MP_OKAY) - return res; - - /* Increase precision; should already be 0-filled */ - USED(mp) = min; - } - - return MP_OKAY; - -} /* end s_mp_pad() */ - -/* }}} */ - -/* {{{ s_mp_setz(dp, count) */ - -#if MP_MACRO == 0 -/* Set 'count' digits pointed to by dp to be zeroes */ -void s_mp_setz(mp_digit *dp, mp_size count) -{ -#if MP_MEMSET == 0 - int ix; - - for(ix = 0; ix < count; ix++) - dp[ix] = 0; -#else - memset(dp, 0, count * sizeof(mp_digit)); -#endif - -} /* end s_mp_setz() */ -#endif - -/* }}} */ - -/* {{{ s_mp_copy(sp, dp, count) */ - -#if MP_MACRO == 0 -/* Copy 'count' digits from sp to dp */ -void s_mp_copy(mp_digit *sp, mp_digit *dp, mp_size count) -{ -#if MP_MEMCPY == 0 - int ix; - - for(ix = 0; ix < count; ix++) - dp[ix] = sp[ix]; -#else - memcpy(dp, sp, count * sizeof(mp_digit)); -#endif - -} /* end s_mp_copy() */ -#endif - -/* }}} */ - -/* {{{ s_mp_alloc(nb, ni) */ - -#if MP_MACRO == 0 -/* Allocate ni records of nb bytes each, and return a pointer to that */ -void *s_mp_alloc(size_t nb, size_t ni) -{ - return calloc(nb, ni); - -} /* end s_mp_alloc() */ -#endif - -/* }}} */ - -/* {{{ s_mp_free(ptr) */ - -#if MP_MACRO == 0 -/* Free the memory pointed to by ptr */ -void s_mp_free(void *ptr) -{ - if(ptr) - free(ptr); - -} /* end s_mp_free() */ -#endif - -/* }}} */ - -/* {{{ s_mp_clamp(mp) */ - -/* Remove leading zeroes from the given value */ -void s_mp_clamp(mp_int *mp) -{ - mp_size du = USED(mp); - mp_digit *zp = DIGITS(mp) + du - 1; - - while(du > 1 && !*zp--) - --du; - - USED(mp) = du; - -} /* end s_mp_clamp() */ - - -/* }}} */ - -/* {{{ s_mp_exch(a, b) */ - -/* Exchange the data for a and b; (b, a) = (a, b) */ -void s_mp_exch(mp_int *a, mp_int *b) -{ - mp_int tmp; - - tmp = *a; - *a = *b; - *b = tmp; - -} /* end s_mp_exch() */ - -/* }}} */ - -/* }}} */ - -/* {{{ Arithmetic helpers */ - -/* {{{ s_mp_lshd(mp, p) */ - -/* - Shift mp leftward by p digits, growing if needed, and zero-filling - the in-shifted digits at the right end. This is a convenient - alternative to multiplication by powers of the radix - */ - -mp_err s_mp_lshd(mp_int *mp, mp_size p) -{ - mp_err res; - mp_size pos; - mp_digit *dp; - int ix; - - if(p == 0) - return MP_OKAY; - - if((res = s_mp_pad(mp, USED(mp) + p)) != MP_OKAY) - return res; - - pos = USED(mp) - 1; - dp = DIGITS(mp); - - /* Shift all the significant figures over as needed */ - for(ix = pos - p; ix >= 0; ix--) - dp[ix + p] = dp[ix]; - - /* Fill the bottom digits with zeroes */ - for(ix = 0; ix < p; ix++) - dp[ix] = 0; - - return MP_OKAY; - -} /* end s_mp_lshd() */ - -/* }}} */ - -/* {{{ s_mp_rshd(mp, p) */ - -/* - Shift mp rightward by p digits. Maintains the invariant that - digits above the precision are all zero. Digits shifted off the - end are lost. Cannot fail. - */ - -void s_mp_rshd(mp_int *mp, mp_size p) -{ - mp_size ix; - mp_digit *dp; - - if(p == 0) - return; - - /* Shortcut when all digits are to be shifted off */ - if(p >= USED(mp)) { - s_mp_setz(DIGITS(mp), ALLOC(mp)); - USED(mp) = 1; - SIGN(mp) = MP_ZPOS; - return; - } - - /* Shift all the significant figures over as needed */ - dp = DIGITS(mp); - for(ix = p; ix < USED(mp); ix++) - dp[ix - p] = dp[ix]; - - /* Fill the top digits with zeroes */ - ix -= p; - while(ix < USED(mp)) - dp[ix++] = 0; - - /* Strip off any leading zeroes */ - s_mp_clamp(mp); - -} /* end s_mp_rshd() */ - -/* }}} */ - -/* {{{ s_mp_div_2(mp) */ - -/* Divide by two -- take advantage of radix properties to do it fast */ -void s_mp_div_2(mp_int *mp) -{ - s_mp_div_2d(mp, 1); - -} /* end s_mp_div_2() */ - -/* }}} */ - -/* {{{ s_mp_mul_2(mp) */ - -mp_err s_mp_mul_2(mp_int *mp) -{ - int ix; - mp_digit kin = 0, kout, *dp = DIGITS(mp); - mp_err res; - - /* Shift digits leftward by 1 bit */ - for(ix = 0; ix < USED(mp); ix++) { - kout = (dp[ix] >> (DIGIT_BIT - 1)) & 1; - dp[ix] = (dp[ix] << 1) | kin; - - kin = kout; - } - - /* Deal with rollover from last digit */ - if(kin) { - if(ix >= ALLOC(mp)) { - if((res = s_mp_grow(mp, ALLOC(mp) + 1)) != MP_OKAY) - return res; - dp = DIGITS(mp); - } - - dp[ix] = kin; - USED(mp) += 1; - } - - return MP_OKAY; - -} /* end s_mp_mul_2() */ - -/* }}} */ - -/* {{{ s_mp_mod_2d(mp, d) */ - -/* - Remainder the integer by 2^d, where d is a number of bits. This - amounts to a bitwise AND of the value, and does not require the full - division code - */ -void s_mp_mod_2d(mp_int *mp, mp_digit d) -{ - unsigned int ndig = (d / DIGIT_BIT), nbit = (d % DIGIT_BIT); - unsigned int ix; - mp_digit dmask, *dp = DIGITS(mp); - - if(ndig >= USED(mp)) - return; - - /* Flush all the bits above 2^d in its digit */ - dmask = (1 << nbit) - 1; - dp[ndig] &= dmask; - - /* Flush all digits above the one with 2^d in it */ - for(ix = ndig + 1; ix < USED(mp); ix++) - dp[ix] = 0; - - s_mp_clamp(mp); - -} /* end s_mp_mod_2d() */ - -/* }}} */ - -/* {{{ s_mp_mul_2d(mp, d) */ - -/* - Multiply by the integer 2^d, where d is a number of bits. This - amounts to a bitwise shift of the value, and does not require the - full multiplication code. - */ -mp_err s_mp_mul_2d(mp_int *mp, mp_digit d) -{ - mp_err res; - mp_digit save, next, mask, *dp; - mp_size used; - int ix; - - if((res = s_mp_lshd(mp, d / DIGIT_BIT)) != MP_OKAY) - return res; - - dp = DIGITS(mp); used = USED(mp); - d %= DIGIT_BIT; - - mask = (1 << d) - 1; - - /* If the shift requires another digit, make sure we've got one to - work with */ - if((dp[used - 1] >> (DIGIT_BIT - d)) & mask) { - if((res = s_mp_grow(mp, used + 1)) != MP_OKAY) - return res; - dp = DIGITS(mp); - } - - /* Do the shifting... */ - save = 0; - for(ix = 0; ix < used; ix++) { - next = (dp[ix] >> (DIGIT_BIT - d)) & mask; - dp[ix] = (dp[ix] << d) | save; - save = next; - } - - /* If, at this point, we have a nonzero carryout into the next - digit, we'll increase the size by one digit, and store it... - */ - if(save) { - dp[used] = save; - USED(mp) += 1; - } - - s_mp_clamp(mp); - return MP_OKAY; - -} /* end s_mp_mul_2d() */ - -/* }}} */ - -/* {{{ s_mp_div_2d(mp, d) */ - -/* - Divide the integer by 2^d, where d is a number of bits. This - amounts to a bitwise shift of the value, and does not require the - full division code (used in Barrett reduction, see below) - */ -void s_mp_div_2d(mp_int *mp, mp_digit d) -{ - int ix; - mp_digit save, next, mask, *dp = DIGITS(mp); - - s_mp_rshd(mp, d / DIGIT_BIT); - d %= DIGIT_BIT; - - mask = (1 << d) - 1; - - save = 0; - for(ix = USED(mp) - 1; ix >= 0; ix--) { - next = dp[ix] & mask; - dp[ix] = (dp[ix] >> d) | (save << (DIGIT_BIT - d)); - save = next; - } - - s_mp_clamp(mp); - -} /* end s_mp_div_2d() */ - -/* }}} */ - -/* {{{ s_mp_norm(a, b) */ - -/* - s_mp_norm(a, b) - - Normalize a and b for division, where b is the divisor. In order - that we might make good guesses for quotient digits, we want the - leading digit of b to be at least half the radix, which we - accomplish by multiplying a and b by a constant. This constant is - returned (so that it can be divided back out of the remainder at the - end of the division process). - - We multiply by the smallest power of 2 that gives us a leading digit - at least half the radix. By choosing a power of 2, we simplify the - multiplication and division steps to simple shifts. - */ -mp_digit s_mp_norm(mp_int *a, mp_int *b) -{ - mp_digit t, d = 0; - - t = DIGIT(b, USED(b) - 1); - while(t < (RADIX / 2)) { - t <<= 1; - ++d; - } - - if(d != 0) { - s_mp_mul_2d(a, d); - s_mp_mul_2d(b, d); - } - - return d; - -} /* end s_mp_norm() */ - -/* }}} */ - -/* }}} */ - -/* {{{ Primitive digit arithmetic */ - -/* {{{ s_mp_add_d(mp, d) */ - -/* Add d to |mp| in place */ -mp_err s_mp_add_d(mp_int *mp, mp_digit d) /* unsigned digit addition */ -{ - mp_word w, k = 0; - mp_size ix = 1, used = USED(mp); - mp_digit *dp = DIGITS(mp); - - w = dp[0] + d; - dp[0] = ACCUM(w); - k = CARRYOUT(w); - - while(ix < used && k) { - w = dp[ix] + k; - dp[ix] = ACCUM(w); - k = CARRYOUT(w); - ++ix; - } - - if(k != 0) { - mp_err res; - - if((res = s_mp_pad(mp, USED(mp) + 1)) != MP_OKAY) - return res; - - DIGIT(mp, ix) = k; - } - - return MP_OKAY; - -} /* end s_mp_add_d() */ - -/* }}} */ - -/* {{{ s_mp_sub_d(mp, d) */ - -/* Subtract d from |mp| in place, assumes |mp| > d */ -mp_err s_mp_sub_d(mp_int *mp, mp_digit d) /* unsigned digit subtract */ -{ - mp_word w, b = 0; - mp_size ix = 1, used = USED(mp); - mp_digit *dp = DIGITS(mp); - - /* Compute initial subtraction */ - w = (RADIX + dp[0]) - d; - b = CARRYOUT(w) ? 0 : 1; - dp[0] = ACCUM(w); - - /* Propagate borrows leftward */ - while(b && ix < used) { - w = (RADIX + dp[ix]) - b; - b = CARRYOUT(w) ? 0 : 1; - dp[ix] = ACCUM(w); - ++ix; - } - - /* Remove leading zeroes */ - s_mp_clamp(mp); - - /* If we have a borrow out, it's a violation of the input invariant */ - if(b) - return MP_RANGE; - else - return MP_OKAY; - -} /* end s_mp_sub_d() */ - -/* }}} */ - -/* {{{ s_mp_mul_d(a, d) */ - -/* Compute a = a * d, single digit multiplication */ -mp_err s_mp_mul_d(mp_int *a, mp_digit d) -{ - mp_word w, k = 0; - mp_size ix, max; - mp_err res; - mp_digit *dp = DIGITS(a); - - /* - Single-digit multiplication will increase the precision of the - output by at most one digit. However, we can detect when this - will happen -- if the high-order digit of a, times d, gives a - two-digit result, then the precision of the result will increase; - otherwise it won't. We use this fact to avoid calling s_mp_pad() - unless absolutely necessary. - */ - max = USED(a); - w = dp[max - 1] * d; - if(CARRYOUT(w) != 0) { - if((res = s_mp_pad(a, max + 1)) != MP_OKAY) - return res; - dp = DIGITS(a); - } - - for(ix = 0; ix < max; ix++) { - w = (dp[ix] * d) + k; - dp[ix] = ACCUM(w); - k = CARRYOUT(w); - } - - /* If there is a precision increase, take care of it here; the above - test guarantees we have enough storage to do this safely. - */ - if(k) { - dp[max] = k; - USED(a) = max + 1; - } - - s_mp_clamp(a); - - return MP_OKAY; - -} /* end s_mp_mul_d() */ - -/* }}} */ - -/* {{{ s_mp_div_d(mp, d, r) */ - -/* - s_mp_div_d(mp, d, r) - - Compute the quotient mp = mp / d and remainder r = mp mod d, for a - single digit d. If r is null, the remainder will be discarded. - */ - -mp_err s_mp_div_d(mp_int *mp, mp_digit d, mp_digit *r) -{ - mp_word w = 0, t; - mp_int quot; - mp_err res; - mp_digit *dp = DIGITS(mp), *qp; - int ix; - - if(d == 0) - return MP_RANGE; - - /* Make room for the quotient */ - if((res = mp_init_size(", USED(mp))) != MP_OKAY) - return res; - - USED(") = USED(mp); /* so clamping will work below */ - qp = DIGITS("); - - /* Divide without subtraction */ - for(ix = USED(mp) - 1; ix >= 0; ix--) { - w = (w << DIGIT_BIT) | dp[ix]; - - if(w >= d) { - t = w / d; - w = w % d; - } else { - t = 0; - } - - qp[ix] = t; - } - - /* Deliver the remainder, if desired */ - if(r) - *r = w; - - s_mp_clamp("); - mp_exch(", mp); - mp_clear("); - - return MP_OKAY; - -} /* end s_mp_div_d() */ - -/* }}} */ - -/* }}} */ - -/* {{{ Primitive full arithmetic */ - -/* {{{ s_mp_add(a, b) */ - -/* Compute a = |a| + |b| */ -mp_err s_mp_add(mp_int *a, mp_int *b) /* magnitude addition */ -{ - mp_word w = 0; - mp_digit *pa, *pb; - mp_size ix, used = USED(b); - mp_err res; - - /* Make sure a has enough precision for the output value */ - if((used > USED(a)) && (res = s_mp_pad(a, used)) != MP_OKAY) - return res; - - /* - Add up all digits up to the precision of b. If b had initially - the same precision as a, or greater, we took care of it by the - padding step above, so there is no problem. If b had initially - less precision, we'll have to make sure the carry out is duly - propagated upward among the higher-order digits of the sum. - */ - pa = DIGITS(a); - pb = DIGITS(b); - for(ix = 0; ix < used; ++ix) { - w += *pa + *pb++; - *pa++ = ACCUM(w); - w = CARRYOUT(w); - } - - /* If we run out of 'b' digits before we're actually done, make - sure the carries get propagated upward... - */ - used = USED(a); - while(w && ix < used) { - w += *pa; - *pa++ = ACCUM(w); - w = CARRYOUT(w); - ++ix; - } - - /* If there's an overall carry out, increase precision and include - it. We could have done this initially, but why touch the memory - allocator unless we're sure we have to? - */ - if(w) { - if((res = s_mp_pad(a, used + 1)) != MP_OKAY) - return res; - - DIGIT(a, ix) = w; /* pa may not be valid after s_mp_pad() call */ - } - - return MP_OKAY; - -} /* end s_mp_add() */ - -/* }}} */ - -/* {{{ s_mp_sub(a, b) */ - -/* Compute a = |a| - |b|, assumes |a| >= |b| */ -mp_err s_mp_sub(mp_int *a, mp_int *b) /* magnitude subtract */ -{ - mp_word w = 0; - mp_digit *pa, *pb; - mp_size ix, used = USED(b); - - /* - Subtract and propagate borrow. Up to the precision of b, this - accounts for the digits of b; after that, we just make sure the - carries get to the right place. This saves having to pad b out to - the precision of a just to make the loops work right... - */ - pa = DIGITS(a); - pb = DIGITS(b); - - for(ix = 0; ix < used; ++ix) { - w = (RADIX + *pa) - w - *pb++; - *pa++ = ACCUM(w); - w = CARRYOUT(w) ? 0 : 1; - } - - used = USED(a); - while(ix < used) { - w = RADIX + *pa - w; - *pa++ = ACCUM(w); - w = CARRYOUT(w) ? 0 : 1; - ++ix; - } - - /* Clobber any leading zeroes we created */ - s_mp_clamp(a); - - /* - If there was a borrow out, then |b| > |a| in violation - of our input invariant. We've already done the work, - but we'll at least complain about it... - */ - if(w) - return MP_RANGE; - else - return MP_OKAY; - -} /* end s_mp_sub() */ - -/* }}} */ - -mp_err s_mp_reduce(mp_int *x, mp_int *m, mp_int *mu) -{ - mp_int q; - mp_err res; - mp_size um = USED(m); - - if((res = mp_init_copy(&q, x)) != MP_OKAY) - return res; - - s_mp_rshd(&q, um - 1); /* q1 = x / b^(k-1) */ - s_mp_mul(&q, mu); /* q2 = q1 * mu */ - s_mp_rshd(&q, um + 1); /* q3 = q2 / b^(k+1) */ - - /* x = x mod b^(k+1), quick (no division) */ - s_mp_mod_2d(x, (mp_digit)(DIGIT_BIT * (um + 1))); - - /* q = q * m mod b^(k+1), quick (no division), uses the short multiplier */ -#ifndef SHRT_MUL - s_mp_mul(&q, m); - s_mp_mod_2d(&q, (mp_digit)(DIGIT_BIT * (um + 1))); -#else - s_mp_mul_dig(&q, m, um + 1); -#endif - - /* x = x - q */ - if((res = mp_sub(x, &q, x)) != MP_OKAY) - goto CLEANUP; - - /* If x < 0, add b^(k+1) to it */ - if(mp_cmp_z(x) < 0) { - mp_set(&q, 1); - if((res = s_mp_lshd(&q, um + 1)) != MP_OKAY) - goto CLEANUP; - if((res = mp_add(x, &q, x)) != MP_OKAY) - goto CLEANUP; - } - - /* Back off if it's too big */ - while(mp_cmp(x, m) >= 0) { - if((res = s_mp_sub(x, m)) != MP_OKAY) - break; - } - - CLEANUP: - mp_clear(&q); - - return res; - -} /* end s_mp_reduce() */ - - - -/* {{{ s_mp_mul(a, b) */ - -/* Compute a = |a| * |b| */ -mp_err s_mp_mul(mp_int *a, mp_int *b) -{ - mp_word w, k = 0; - mp_int tmp; - mp_err res; - mp_size ix, jx, ua = USED(a), ub = USED(b); - mp_digit *pa, *pb, *pt, *pbt; - - if((res = mp_init_size(&tmp, ua + ub)) != MP_OKAY) - return res; - - /* This has the effect of left-padding with zeroes... */ - USED(&tmp) = ua + ub; - - /* We're going to need the base value each iteration */ - pbt = DIGITS(&tmp); - - /* Outer loop: Digits of b */ - - pb = DIGITS(b); - for(ix = 0; ix < ub; ++ix, ++pb) { - if(*pb == 0) - continue; - - /* Inner product: Digits of a */ - pa = DIGITS(a); - for(jx = 0; jx < ua; ++jx, ++pa) { - pt = pbt + ix + jx; - w = *pb * *pa + k + *pt; - *pt = ACCUM(w); - k = CARRYOUT(w); - } - - pbt[ix + jx] = k; - k = 0; - } - - s_mp_clamp(&tmp); - s_mp_exch(&tmp, a); - - mp_clear(&tmp); - - return MP_OKAY; - -} /* end s_mp_mul() */ - -/* }}} */ - -/* {{{ s_mp_kmul(a, b, out, len) */ - -#if 0 -void s_mp_kmul(mp_digit *a, mp_digit *b, mp_digit *out, mp_size len) -{ - mp_word w, k = 0; - mp_size ix, jx; - mp_digit *pa, *pt; - - for(ix = 0; ix < len; ++ix, ++b) { - if(*b == 0) - continue; - - pa = a; - for(jx = 0; jx < len; ++jx, ++pa) { - pt = out + ix + jx; - w = *b * *pa + k + *pt; - *pt = ACCUM(w); - k = CARRYOUT(w); - } - - out[ix + jx] = k; - k = 0; - } - -} /* end s_mp_kmul() */ -#endif - -/* }}} */ - -/* {{{ s_mp_sqr(a) */ - -/* - Computes the square of a, in place. This can be done more - efficiently than a general multiplication, because many of the - computation steps are redundant when squaring. The inner product - step is a bit more complicated, but we save a fair number of - iterations of the multiplication loop. - */ -#if MP_SQUARE -mp_err s_mp_sqr(mp_int *a) -{ - mp_word w, k = 0; - mp_int tmp; - mp_err res; - mp_size ix, jx, kx, used = USED(a); - mp_digit *pa1, *pa2, *pt, *pbt; - - if((res = mp_init_size(&tmp, 2 * used)) != MP_OKAY) - return res; - - /* Left-pad with zeroes */ - USED(&tmp) = 2 * used; - - /* We need the base value each time through the loop */ - pbt = DIGITS(&tmp); - - pa1 = DIGITS(a); - for(ix = 0; ix < used; ++ix, ++pa1) { - if(*pa1 == 0) - continue; - - w = DIGIT(&tmp, ix + ix) + (*pa1 * *pa1); - - pbt[ix + ix] = ACCUM(w); - k = CARRYOUT(w); - - /* - The inner product is computed as: - - (C, S) = t[i,j] + 2 a[i] a[j] + C - - This can overflow what can be represented in an mp_word, and - since C arithmetic does not provide any way to check for - overflow, we have to check explicitly for overflow conditions - before they happen. - */ - for(jx = ix + 1, pa2 = DIGITS(a) + jx; jx < used; ++jx, ++pa2) { - mp_word u = 0, v; - - /* Store this in a temporary to avoid indirections later */ - pt = pbt + ix + jx; - - /* Compute the multiplicative step */ - w = *pa1 * *pa2; - - /* If w is more than half MP_WORD_MAX, the doubling will - overflow, and we need to record a carry out into the next - word */ - u = (w >> (MP_WORD_BIT - 1)) & 1; - - /* Double what we've got, overflow will be ignored as defined - for C arithmetic (we've already noted if it is to occur) - */ - w *= 2; - - /* Compute the additive step */ - v = *pt + k; - - /* If we do not already have an overflow carry, check to see - if the addition will cause one, and set the carry out if so - */ - u |= ((MP_WORD_MAX - v) < w); - - /* Add in the rest, again ignoring overflow */ - w += v; - - /* Set the i,j digit of the output */ - *pt = ACCUM(w); - - /* Save carry information for the next iteration of the loop. - This is why k must be an mp_word, instead of an mp_digit */ - k = CARRYOUT(w) | (u << DIGIT_BIT); - - } /* for(jx ...) */ - - /* Set the last digit in the cycle and reset the carry */ - k = DIGIT(&tmp, ix + jx) + k; - pbt[ix + jx] = ACCUM(k); - k = CARRYOUT(k); - - /* If we are carrying out, propagate the carry to the next digit - in the output. This may cascade, so we have to be somewhat - circumspect -- but we will have enough precision in the output - that we won't overflow - */ - kx = 1; - while(k) { - k = pbt[ix + jx + kx] + 1; - pbt[ix + jx + kx] = ACCUM(k); - k = CARRYOUT(k); - ++kx; - } - } /* for(ix ...) */ - - s_mp_clamp(&tmp); - s_mp_exch(&tmp, a); - - mp_clear(&tmp); - - return MP_OKAY; - -} /* end s_mp_sqr() */ -#endif - -/* }}} */ - -/* {{{ s_mp_div(a, b) */ - -/* - s_mp_div(a, b) - - Compute a = a / b and b = a mod b. Assumes b > a. - */ - -mp_err s_mp_div(mp_int *a, mp_int *b) -{ - mp_int quot, rem, t; - mp_word q; - mp_err res; - mp_digit d; - int ix; - - if(mp_cmp_z(b) == 0) - return MP_RANGE; - - /* Shortcut if b is power of two */ - if((ix = s_mp_ispow2(b)) >= 0) { - mp_copy(a, b); /* need this for remainder */ - s_mp_div_2d(a, (mp_digit)ix); - s_mp_mod_2d(b, (mp_digit)ix); - - return MP_OKAY; - } - - /* Allocate space to store the quotient */ - if((res = mp_init_size(", USED(a))) != MP_OKAY) - return res; - - /* A working temporary for division */ - if((res = mp_init_size(&t, USED(a))) != MP_OKAY) - goto T; - - /* Allocate space for the remainder */ - if((res = mp_init_size(&rem, USED(a))) != MP_OKAY) - goto REM; - - /* Normalize to optimize guessing */ - d = s_mp_norm(a, b); - - /* Perform the division itself...woo! */ - ix = USED(a) - 1; - - while(ix >= 0) { - /* Find a partial substring of a which is at least b */ - while(s_mp_cmp(&rem, b) < 0 && ix >= 0) { - if((res = s_mp_lshd(&rem, 1)) != MP_OKAY) - goto CLEANUP; - - if((res = s_mp_lshd(", 1)) != MP_OKAY) - goto CLEANUP; - - DIGIT(&rem, 0) = DIGIT(a, ix); - s_mp_clamp(&rem); - --ix; - } - - /* If we didn't find one, we're finished dividing */ - if(s_mp_cmp(&rem, b) < 0) - break; - - /* Compute a guess for the next quotient digit */ - q = DIGIT(&rem, USED(&rem) - 1); - if(q <= DIGIT(b, USED(b) - 1) && USED(&rem) > 1) - q = (q << DIGIT_BIT) | DIGIT(&rem, USED(&rem) - 2); - - q /= DIGIT(b, USED(b) - 1); - - /* The guess can be as much as RADIX + 1 */ - if(q >= RADIX) - q = RADIX - 1; - - /* See what that multiplies out to */ - mp_copy(b, &t); - if((res = s_mp_mul_d(&t, q)) != MP_OKAY) - goto CLEANUP; - - /* - If it's too big, back it off. We should not have to do this - more than once, or, in rare cases, twice. Knuth describes a - method by which this could be reduced to a maximum of once, but - I didn't implement that here. - */ - while(s_mp_cmp(&t, &rem) > 0) { - --q; - s_mp_sub(&t, b); - } - - /* At this point, q should be the right next digit */ - if((res = s_mp_sub(&rem, &t)) != MP_OKAY) - goto CLEANUP; - - /* - Include the digit in the quotient. We allocated enough memory - for any quotient we could ever possibly get, so we should not - have to check for failures here - */ - DIGIT(", 0) = q; - } - - /* Denormalize remainder */ - if(d != 0) - s_mp_div_2d(&rem, d); - - s_mp_clamp("); - s_mp_clamp(&rem); - - /* Copy quotient back to output */ - s_mp_exch(", a); - - /* Copy remainder back to output */ - s_mp_exch(&rem, b); - -CLEANUP: - mp_clear(&rem); -REM: - mp_clear(&t); -T: - mp_clear("); - - return res; - -} /* end s_mp_div() */ - -/* }}} */ - -/* {{{ s_mp_2expt(a, k) */ - -mp_err s_mp_2expt(mp_int *a, mp_digit k) -{ - mp_err res; - mp_size dig, bit; - - dig = k / DIGIT_BIT; - bit = k % DIGIT_BIT; - - mp_zero(a); - if((res = s_mp_pad(a, dig + 1)) != MP_OKAY) - return res; - - DIGIT(a, dig) |= (1 << bit); - - return MP_OKAY; - -} /* end s_mp_2expt() */ - -/* }}} */ - - -/* }}} */ - -/* }}} */ - -/* {{{ Primitive comparisons */ - -/* {{{ s_mp_cmp(a, b) */ - -/* Compare |a| <=> |b|, return 0 if equal, <0 if a0 if a>b */ -int s_mp_cmp(mp_int *a, mp_int *b) -{ - mp_size ua = USED(a), ub = USED(b); - - if(ua > ub) - return MP_GT; - else if(ua < ub) - return MP_LT; - else { - int ix = ua - 1; - mp_digit *ap = DIGITS(a) + ix, *bp = DIGITS(b) + ix; - - while(ix >= 0) { - if(*ap > *bp) - return MP_GT; - else if(*ap < *bp) - return MP_LT; - - --ap; --bp; --ix; - } - - return MP_EQ; - } - -} /* end s_mp_cmp() */ - -/* }}} */ - -/* {{{ s_mp_cmp_d(a, d) */ - -/* Compare |a| <=> d, return 0 if equal, <0 if a0 if a>d */ -int s_mp_cmp_d(mp_int *a, mp_digit d) -{ - mp_size ua = USED(a); - mp_digit *ap = DIGITS(a); - - if(ua > 1) - return MP_GT; - - if(*ap < d) - return MP_LT; - else if(*ap > d) - return MP_GT; - else - return MP_EQ; - -} /* end s_mp_cmp_d() */ - -/* }}} */ - -/* {{{ s_mp_ispow2(v) */ - -/* - Returns -1 if the value is not a power of two; otherwise, it returns - k such that v = 2^k, i.e. lg(v). - */ -int s_mp_ispow2(mp_int *v) -{ - mp_digit d, *dp; - mp_size uv = USED(v); - int extra = 0, ix; - - d = DIGIT(v, uv - 1); /* most significant digit of v */ - - while(d && ((d & 1) == 0)) { - d >>= 1; - ++extra; - } - - if(d == 1) { - ix = uv - 2; - dp = DIGITS(v) + ix; - - while(ix >= 0) { - if(*dp) - return -1; /* not a power of two */ - - --dp; --ix; - } - - return ((uv - 1) * DIGIT_BIT) + extra; - } - - return -1; - -} /* end s_mp_ispow2() */ - -/* }}} */ - -/* {{{ s_mp_ispow2d(d) */ - -int s_mp_ispow2d(mp_digit d) -{ - int pow = 0; - - while((d & 1) == 0) { - ++pow; d >>= 1; - } - - if(d == 1) - return pow; - - return -1; - -} /* end s_mp_ispow2d() */ - -/* }}} */ - -/* }}} */ - -/* {{{ Primitive I/O helpers */ - -/* {{{ s_mp_tovalue(ch, r) */ - -/* - Convert the given character to its digit value, in the given radix. - If the given character is not understood in the given radix, -1 is - returned. Otherwise the digit's numeric value is returned. - - The results will be odd if you use a radix < 2 or > 62, you are - expected to know what you're up to. - */ -int s_mp_tovalue(char ch, int r) -{ - int val, xch; - - if(r > 36) - xch = ch; - else - xch = toupper(ch); - - if(isdigit(xch)) - val = xch - '0'; - else if(isupper(xch)) - val = xch - 'A' + 10; - else if(islower(xch)) - val = xch - 'a' + 36; - else if(xch == '+') - val = 62; - else if(xch == '/') - val = 63; - else - return -1; - - if(val < 0 || val >= r) - return -1; - - return val; - -} /* end s_mp_tovalue() */ - -/* }}} */ - -/* {{{ s_mp_todigit(val, r, low) */ - -/* - Convert val to a radix-r digit, if possible. If val is out of range - for r, returns zero. Otherwise, returns an ASCII character denoting - the value in the given radix. - - The results may be odd if you use a radix < 2 or > 64, you are - expected to know what you're doing. - */ - -char s_mp_todigit(int val, int r, int low) -{ - char ch; - - if(val < 0 || val >= r) - return 0; - - ch = s_dmap_1[val]; - - if(r <= 36 && low) - ch = tolower(ch); - - return ch; - -} /* end s_mp_todigit() */ - -/* }}} */ - -/* {{{ s_mp_outlen(bits, radix) */ - -/* - Return an estimate for how long a string is needed to hold a radix - r representation of a number with 'bits' significant bits. - - Does not include space for a sign or a NUL terminator. - */ -int s_mp_outlen(int bits, int r) -{ - return (int)((double)bits * LOG_V_2(r)); - -} /* end s_mp_outlen() */ - -/* }}} */ - -/* }}} */ - -/*------------------------------------------------------------------------*/ -/* HERE THERE BE DRAGONS */ -/* crc==4242132123, version==2, Sat Feb 02 06:43:52 2002 */ - -/* $Source$ */ -/* $Revision: 0.36 $ */ -/* $Date: 2005-08-01 16:37:28 +0000 $ */ diff --git a/external/libtommath-0.42.0/mtest/mpi.h b/external/libtommath-0.42.0/mtest/mpi.h deleted file mode 100755 index 526c3fd..0000000 --- a/external/libtommath-0.42.0/mtest/mpi.h +++ /dev/null @@ -1,231 +0,0 @@ -/* - mpi.h - - by Michael J. Fromberger - Copyright (C) 1998 Michael J. Fromberger, All Rights Reserved - - Arbitrary precision integer arithmetic library - - $ID$ - */ - -#ifndef _H_MPI_ -#define _H_MPI_ - -#include "mpi-config.h" - -#define MP_LT -1 -#define MP_EQ 0 -#define MP_GT 1 - -#if MP_DEBUG -#undef MP_IOFUNC -#define MP_IOFUNC 1 -#endif - -#if MP_IOFUNC -#include -#include -#endif - -#include - -#define MP_NEG 1 -#define MP_ZPOS 0 - -/* Included for compatibility... */ -#define NEG MP_NEG -#define ZPOS MP_ZPOS - -#define MP_OKAY 0 /* no error, all is well */ -#define MP_YES 0 /* yes (boolean result) */ -#define MP_NO -1 /* no (boolean result) */ -#define MP_MEM -2 /* out of memory */ -#define MP_RANGE -3 /* argument out of range */ -#define MP_BADARG -4 /* invalid parameter */ -#define MP_UNDEF -5 /* answer is undefined */ -#define MP_LAST_CODE MP_UNDEF - -#include "mpi-types.h" - -/* Included for compatibility... */ -#define DIGIT_BIT MP_DIGIT_BIT -#define DIGIT_MAX MP_DIGIT_MAX - -/* Macros for accessing the mp_int internals */ -#define SIGN(MP) ((MP)->sign) -#define USED(MP) ((MP)->used) -#define ALLOC(MP) ((MP)->alloc) -#define DIGITS(MP) ((MP)->dp) -#define DIGIT(MP,N) (MP)->dp[(N)] - -#if MP_ARGCHK == 1 -#define ARGCHK(X,Y) {if(!(X)){return (Y);}} -#elif MP_ARGCHK == 2 -#include -#define ARGCHK(X,Y) assert(X) -#else -#define ARGCHK(X,Y) /* */ -#endif - -/* This defines the maximum I/O base (minimum is 2) */ -#define MAX_RADIX 64 - -typedef struct { - mp_sign sign; /* sign of this quantity */ - mp_size alloc; /* how many digits allocated */ - mp_size used; /* how many digits used */ - mp_digit *dp; /* the digits themselves */ -} mp_int; - -/*------------------------------------------------------------------------*/ -/* Default precision */ - -unsigned int mp_get_prec(void); -void mp_set_prec(unsigned int prec); - -/*------------------------------------------------------------------------*/ -/* Memory management */ - -mp_err mp_init(mp_int *mp); -mp_err mp_init_array(mp_int mp[], int count); -mp_err mp_init_size(mp_int *mp, mp_size prec); -mp_err mp_init_copy(mp_int *mp, mp_int *from); -mp_err mp_copy(mp_int *from, mp_int *to); -void mp_exch(mp_int *mp1, mp_int *mp2); -void mp_clear(mp_int *mp); -void mp_clear_array(mp_int mp[], int count); -void mp_zero(mp_int *mp); -void mp_set(mp_int *mp, mp_digit d); -mp_err mp_set_int(mp_int *mp, long z); -mp_err mp_shrink(mp_int *a); - - -/*------------------------------------------------------------------------*/ -/* Single digit arithmetic */ - -mp_err mp_add_d(mp_int *a, mp_digit d, mp_int *b); -mp_err mp_sub_d(mp_int *a, mp_digit d, mp_int *b); -mp_err mp_mul_d(mp_int *a, mp_digit d, mp_int *b); -mp_err mp_mul_2(mp_int *a, mp_int *c); -mp_err mp_div_d(mp_int *a, mp_digit d, mp_int *q, mp_digit *r); -mp_err mp_div_2(mp_int *a, mp_int *c); -mp_err mp_expt_d(mp_int *a, mp_digit d, mp_int *c); - -/*------------------------------------------------------------------------*/ -/* Sign manipulations */ - -mp_err mp_abs(mp_int *a, mp_int *b); -mp_err mp_neg(mp_int *a, mp_int *b); - -/*------------------------------------------------------------------------*/ -/* Full arithmetic */ - -mp_err mp_add(mp_int *a, mp_int *b, mp_int *c); -mp_err mp_sub(mp_int *a, mp_int *b, mp_int *c); -mp_err mp_mul(mp_int *a, mp_int *b, mp_int *c); -mp_err mp_mul_2d(mp_int *a, mp_digit d, mp_int *c); -#if MP_SQUARE -mp_err mp_sqr(mp_int *a, mp_int *b); -#else -#define mp_sqr(a, b) mp_mul(a, a, b) -#endif -mp_err mp_div(mp_int *a, mp_int *b, mp_int *q, mp_int *r); -mp_err mp_div_2d(mp_int *a, mp_digit d, mp_int *q, mp_int *r); -mp_err mp_expt(mp_int *a, mp_int *b, mp_int *c); -mp_err mp_2expt(mp_int *a, mp_digit k); -mp_err mp_sqrt(mp_int *a, mp_int *b); - -/*------------------------------------------------------------------------*/ -/* Modular arithmetic */ - -#if MP_MODARITH -mp_err mp_mod(mp_int *a, mp_int *m, mp_int *c); -mp_err mp_mod_d(mp_int *a, mp_digit d, mp_digit *c); -mp_err mp_addmod(mp_int *a, mp_int *b, mp_int *m, mp_int *c); -mp_err mp_submod(mp_int *a, mp_int *b, mp_int *m, mp_int *c); -mp_err mp_mulmod(mp_int *a, mp_int *b, mp_int *m, mp_int *c); -#if MP_SQUARE -mp_err mp_sqrmod(mp_int *a, mp_int *m, mp_int *c); -#else -#define mp_sqrmod(a, m, c) mp_mulmod(a, a, m, c) -#endif -mp_err mp_exptmod(mp_int *a, mp_int *b, mp_int *m, mp_int *c); -mp_err mp_exptmod_d(mp_int *a, mp_digit d, mp_int *m, mp_int *c); -#endif /* MP_MODARITH */ - -/*------------------------------------------------------------------------*/ -/* Comparisons */ - -int mp_cmp_z(mp_int *a); -int mp_cmp_d(mp_int *a, mp_digit d); -int mp_cmp(mp_int *a, mp_int *b); -int mp_cmp_mag(mp_int *a, mp_int *b); -int mp_cmp_int(mp_int *a, long z); -int mp_isodd(mp_int *a); -int mp_iseven(mp_int *a); - -/*------------------------------------------------------------------------*/ -/* Number theoretic */ - -#if MP_NUMTH -mp_err mp_gcd(mp_int *a, mp_int *b, mp_int *c); -mp_err mp_lcm(mp_int *a, mp_int *b, mp_int *c); -mp_err mp_xgcd(mp_int *a, mp_int *b, mp_int *g, mp_int *x, mp_int *y); -mp_err mp_invmod(mp_int *a, mp_int *m, mp_int *c); -#endif /* end MP_NUMTH */ - -/*------------------------------------------------------------------------*/ -/* Input and output */ - -#if MP_IOFUNC -void mp_print(mp_int *mp, FILE *ofp); -#endif /* end MP_IOFUNC */ - -/*------------------------------------------------------------------------*/ -/* Base conversion */ - -#define BITS 1 -#define BYTES CHAR_BIT - -mp_err mp_read_signed_bin(mp_int *mp, unsigned char *str, int len); -int mp_signed_bin_size(mp_int *mp); -mp_err mp_to_signed_bin(mp_int *mp, unsigned char *str); - -mp_err mp_read_unsigned_bin(mp_int *mp, unsigned char *str, int len); -int mp_unsigned_bin_size(mp_int *mp); -mp_err mp_to_unsigned_bin(mp_int *mp, unsigned char *str); - -int mp_count_bits(mp_int *mp); - -#if MP_COMPAT_MACROS -#define mp_read_raw(mp, str, len) mp_read_signed_bin((mp), (str), (len)) -#define mp_raw_size(mp) mp_signed_bin_size(mp) -#define mp_toraw(mp, str) mp_to_signed_bin((mp), (str)) -#define mp_read_mag(mp, str, len) mp_read_unsigned_bin((mp), (str), (len)) -#define mp_mag_size(mp) mp_unsigned_bin_size(mp) -#define mp_tomag(mp, str) mp_to_unsigned_bin((mp), (str)) -#endif - -mp_err mp_read_radix(mp_int *mp, unsigned char *str, int radix); -int mp_radix_size(mp_int *mp, int radix); -int mp_value_radix_size(int num, int qty, int radix); -mp_err mp_toradix(mp_int *mp, unsigned char *str, int radix); - -int mp_char2value(char ch, int r); - -#define mp_tobinary(M, S) mp_toradix((M), (S), 2) -#define mp_tooctal(M, S) mp_toradix((M), (S), 8) -#define mp_todecimal(M, S) mp_toradix((M), (S), 10) -#define mp_tohex(M, S) mp_toradix((M), (S), 16) - -/*------------------------------------------------------------------------*/ -/* Error strings */ - -const char *mp_strerror(mp_err ec); - -#endif /* end _H_MPI_ */ - -/* $Source$ */ -/* $Revision: 0.36 $ */ -/* $Date: 2005-08-01 16:37:28 +0000 $ */ diff --git a/external/libtommath-0.42.0/mtest/mtest.c b/external/libtommath-0.42.0/mtest/mtest.c deleted file mode 100755 index 92f03ad..0000000 --- a/external/libtommath-0.42.0/mtest/mtest.c +++ /dev/null @@ -1,308 +0,0 @@ -/* makes a bignum test harness with NUM tests per operation - * - * the output is made in the following format [one parameter per line] - -operation -operand1 -operand2 -[... operandN] -result1 -result2 -[... resultN] - -So for example "a * b mod n" would be - -mulmod -a -b -n -a*b mod n - -e.g. if a=3, b=4 n=11 then - -mulmod -3 -4 -11 -1 - - */ - -#ifdef MP_8BIT -#define THE_MASK 127 -#else -#define THE_MASK 32767 -#endif - -#include -#include -#include -#include "mpi.c" - -FILE *rng; - -void rand_num(mp_int *a) -{ - int n, size; - unsigned char buf[2048]; - - size = 1 + ((fgetc(rng)<<8) + fgetc(rng)) % 101; - buf[0] = (fgetc(rng)&1)?1:0; - fread(buf+1, 1, size, rng); - while (buf[1] == 0) buf[1] = fgetc(rng); - mp_read_raw(a, buf, 1+size); -} - -void rand_num2(mp_int *a) -{ - int n, size; - unsigned char buf[2048]; - - size = 10 + ((fgetc(rng)<<8) + fgetc(rng)) % 101; - buf[0] = (fgetc(rng)&1)?1:0; - fread(buf+1, 1, size, rng); - while (buf[1] == 0) buf[1] = fgetc(rng); - mp_read_raw(a, buf, 1+size); -} - -#define mp_to64(a, b) mp_toradix(a, b, 64) - -int main(void) -{ - int n, tmp; - mp_int a, b, c, d, e; - clock_t t1; - char buf[4096]; - - mp_init(&a); - mp_init(&b); - mp_init(&c); - mp_init(&d); - mp_init(&e); - - - /* initial (2^n - 1)^2 testing, makes sure the comba multiplier works [it has the new carry code] */ -/* - mp_set(&a, 1); - for (n = 1; n < 8192; n++) { - mp_mul(&a, &a, &c); - printf("mul\n"); - mp_to64(&a, buf); - printf("%s\n%s\n", buf, buf); - mp_to64(&c, buf); - printf("%s\n", buf); - - mp_add_d(&a, 1, &a); - mp_mul_2(&a, &a); - mp_sub_d(&a, 1, &a); - } -*/ - - rng = fopen("/dev/urandom", "rb"); - if (rng == NULL) { - rng = fopen("/dev/random", "rb"); - if (rng == NULL) { - fprintf(stderr, "\nWarning: stdin used as random source\n\n"); - rng = stdin; - } - } - - t1 = clock(); - for (;;) { -#if 0 - if (clock() - t1 > CLOCKS_PER_SEC) { - sleep(2); - t1 = clock(); - } -#endif - n = fgetc(rng) % 15; - - if (n == 0) { - /* add tests */ - rand_num(&a); - rand_num(&b); - mp_add(&a, &b, &c); - printf("add\n"); - mp_to64(&a, buf); - printf("%s\n", buf); - mp_to64(&b, buf); - printf("%s\n", buf); - mp_to64(&c, buf); - printf("%s\n", buf); - } else if (n == 1) { - /* sub tests */ - rand_num(&a); - rand_num(&b); - mp_sub(&a, &b, &c); - printf("sub\n"); - mp_to64(&a, buf); - printf("%s\n", buf); - mp_to64(&b, buf); - printf("%s\n", buf); - mp_to64(&c, buf); - printf("%s\n", buf); - } else if (n == 2) { - /* mul tests */ - rand_num(&a); - rand_num(&b); - mp_mul(&a, &b, &c); - printf("mul\n"); - mp_to64(&a, buf); - printf("%s\n", buf); - mp_to64(&b, buf); - printf("%s\n", buf); - mp_to64(&c, buf); - printf("%s\n", buf); - } else if (n == 3) { - /* div tests */ - rand_num(&a); - rand_num(&b); - mp_div(&a, &b, &c, &d); - printf("div\n"); - mp_to64(&a, buf); - printf("%s\n", buf); - mp_to64(&b, buf); - printf("%s\n", buf); - mp_to64(&c, buf); - printf("%s\n", buf); - mp_to64(&d, buf); - printf("%s\n", buf); - } else if (n == 4) { - /* sqr tests */ - rand_num(&a); - mp_sqr(&a, &b); - printf("sqr\n"); - mp_to64(&a, buf); - printf("%s\n", buf); - mp_to64(&b, buf); - printf("%s\n", buf); - } else if (n == 5) { - /* mul_2d test */ - rand_num(&a); - mp_copy(&a, &b); - n = fgetc(rng) & 63; - mp_mul_2d(&b, n, &b); - mp_to64(&a, buf); - printf("mul2d\n"); - printf("%s\n", buf); - printf("%d\n", n); - mp_to64(&b, buf); - printf("%s\n", buf); - } else if (n == 6) { - /* div_2d test */ - rand_num(&a); - mp_copy(&a, &b); - n = fgetc(rng) & 63; - mp_div_2d(&b, n, &b, NULL); - mp_to64(&a, buf); - printf("div2d\n"); - printf("%s\n", buf); - printf("%d\n", n); - mp_to64(&b, buf); - printf("%s\n", buf); - } else if (n == 7) { - /* gcd test */ - rand_num(&a); - rand_num(&b); - a.sign = MP_ZPOS; - b.sign = MP_ZPOS; - mp_gcd(&a, &b, &c); - printf("gcd\n"); - mp_to64(&a, buf); - printf("%s\n", buf); - mp_to64(&b, buf); - printf("%s\n", buf); - mp_to64(&c, buf); - printf("%s\n", buf); - } else if (n == 8) { - /* lcm test */ - rand_num(&a); - rand_num(&b); - a.sign = MP_ZPOS; - b.sign = MP_ZPOS; - mp_lcm(&a, &b, &c); - printf("lcm\n"); - mp_to64(&a, buf); - printf("%s\n", buf); - mp_to64(&b, buf); - printf("%s\n", buf); - mp_to64(&c, buf); - printf("%s\n", buf); - } else if (n == 9) { - /* exptmod test */ - rand_num2(&a); - rand_num2(&b); - rand_num2(&c); -// if (c.dp[0]&1) mp_add_d(&c, 1, &c); - a.sign = b.sign = c.sign = 0; - mp_exptmod(&a, &b, &c, &d); - printf("expt\n"); - mp_to64(&a, buf); - printf("%s\n", buf); - mp_to64(&b, buf); - printf("%s\n", buf); - mp_to64(&c, buf); - printf("%s\n", buf); - mp_to64(&d, buf); - printf("%s\n", buf); - } else if (n == 10) { - /* invmod test */ - rand_num2(&a); - rand_num2(&b); - b.sign = MP_ZPOS; - a.sign = MP_ZPOS; - mp_gcd(&a, &b, &c); - if (mp_cmp_d(&c, 1) != 0) continue; - if (mp_cmp_d(&b, 1) == 0) continue; - mp_invmod(&a, &b, &c); - printf("invmod\n"); - mp_to64(&a, buf); - printf("%s\n", buf); - mp_to64(&b, buf); - printf("%s\n", buf); - mp_to64(&c, buf); - printf("%s\n", buf); - } else if (n == 11) { - rand_num(&a); - mp_mul_2(&a, &a); - mp_div_2(&a, &b); - printf("div2\n"); - mp_to64(&a, buf); - printf("%s\n", buf); - mp_to64(&b, buf); - printf("%s\n", buf); - } else if (n == 12) { - rand_num2(&a); - mp_mul_2(&a, &b); - printf("mul2\n"); - mp_to64(&a, buf); - printf("%s\n", buf); - mp_to64(&b, buf); - printf("%s\n", buf); - } else if (n == 13) { - rand_num2(&a); - tmp = abs(rand()) & THE_MASK; - mp_add_d(&a, tmp, &b); - printf("add_d\n"); - mp_to64(&a, buf); - printf("%s\n%d\n", buf, tmp); - mp_to64(&b, buf); - printf("%s\n", buf); - } else if (n == 14) { - rand_num2(&a); - tmp = abs(rand()) & THE_MASK; - mp_sub_d(&a, tmp, &b); - printf("sub_d\n"); - mp_to64(&a, buf); - printf("%s\n%d\n", buf, tmp); - mp_to64(&b, buf); - printf("%s\n", buf); - } - } - fclose(rng); - return 0; -} - -/* $Source$ */ -/* $Revision: 0.36 $ */ -/* $Date: 2005-08-01 16:37:28 +0000 $ */ diff --git a/external/libtommath-0.42.0/pics/design_process.sxd b/external/libtommath-0.42.0/pics/design_process.sxd deleted file mode 100755 index 7414dbb27696fe716fe8c73a5c2b21d8c3e0c23c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6950 zcma)B2V7Ij(x>;L2+{%qf`9@c5ULdEMLGl_C~1MDu}mC6_HTF5qEm7rNkl@JC@y!ELLZS23IS@F0e(qYvrp$Zal!neBYg&oTx_AEji0C^fpqI zVe)z0BHXg(kBaMT3D$Tzf@HI!45X+J-vXyi(T~Ir7_9EKd<_G4?kuY7GVnDeBftg(cn5bPt*^|q*i^3WX46}_u->}?+1Q;%#eBV1 za<%wrRhJK)b6Qj*c{)=CL!h@na%^L?MwczYi9OpkPL0Jc*@}rF!2H&Zpe^2eFa5w72aY!NINl9Hy zW?Q9&ew$@+?ZRjKBr~%-(A2rR!5}9WU7tfEZ&T%X)V+YauN_F3p)QoT4pFu{YkJ&jjAQ#9 zF60z*;iD^=jPJvu(Q>H?2F?}1`vfwWI|+bnht!!TW|P5YKr1}6ue$j6t=pVJAp(MW zB2)8?@>MX`8V7>{@t{<&4pSooH6hsq&$PWnkVv*%-5NCVG|gj^b0uvxeWCl7I+ z&F!T!LVWza-Z6=y1`j?DnUwq~IdzIBdz4Q?xYILiY9JCuU3GOf%sJV}gZ+7Q1tIyhJSYraul44Gv~$gS!H4)8 zU4AeV1?u|VeY8qrz25nooGCTFQC zAa_+GA$csfbi%Fx+WEGFKDx17IJ!^yW6LZ!RbRp!_bj>oW$-5-#1yMdO1@QJ-W-J? z-Pj9lPW>|2PR!!?6B~faYp(zw!nEy${>K{jiyOsy-q+%oN?z$vGL8gVyw}r&z+v{< zNgFkXX%)HPh&SK!+WJBv&y&$|FTLnd^TxJAQvS-_SF)ThjTBNz(n)lasI<ykT|ZO3bg@+*E2iGKASb1+lGzctJl5;o+RN}nYP#NDIH+}QU@o^9dLnj{YNG_lGF z!5TKxp7CcLj%OdZD2{JuG*+MC>)a(Kp&>osyhenB)5nK{^Pl|+*|}eF#(3BvoG;wU zx`{n{QuNYkgIOl>vkWAjZxWf>!aI?}Ld0q7$Jw+W70;7W#7Ra=$9;0;N6lHaS^0I| zFD>!0H9aY~m3MTpEP0Q@-MD39F~|Ei$ii&9^yC+kBmm;C{9qABoTgn}1)UKinTPv} zK?~QkWlua0zpqdeQR2O|@S^9+)of(!mhfde#yG~V& zpOBfMfO>aMI5!4 zwc&3idbe~%o<-;qcE*#TO(jpS_#DUsy zlL_?li<%jb3(F?3VWfB!&K^w92z^Y_syExuw@d-3t+lS@R3{CdtW$EFm@UL8QS-6n z8yS3rZ-L3Zo6`MuXjE zZLIIN5Y$SF_5h(}bo5A-dx_xrTW>T;nB!jNLU|UznvvEU&8-HO*-snc&)*nFx3KoY zt;!5vq$lxSuApO$WH50ylK&h~8ryu!%LLSzSq8oQFe8b*;-Ib#W8JSq16Iq_`MS3V zRIHruS15?fRtGQf>|fsL=KpfnQ2gNT`(RRQRWC@VI)Tzk$jFkru4d{eRy+I{#uS&1 zt0kYpM?|G;@%hzEfG9r-AD2x3zSxH{Ea<*<3K20U1v$af?D^GWK@um;TE#x~7YG_G zeGBw5w2xB1t0?8DWvydUIj3PL^ZIGWRU8?hs@+rZS&vJ1*{_Ezy`pt8R}jrj9aJr8 zoTe;`9tAIOfI@U22CP}go7*&Y7^S*M!+f~SCT&QVGEd8ZeZ4C)S89ulC7B&d7g>So zS`yUc8#-1YNlK@c9~2wrvT)QWK=4BO+_7U#B3z@XmYI;P6uIKy|bI*br;pS0GNaaQj7|@xyQX~;b$$eFG z^UfQ#yyuE$3eGjq{sQXlsy&Oj2-g5vK+Pjc-@04JP4$7Y_HuH11okQLx(=aX>!<)sjJ82`v<`e&q5`aZEo}( z@!^!s+l@gNX0W|w#7*s0;CJHjYizUVTGEe+*sSk>@tp2d^f zZ1`bUxv3)jjMMB@mz~kALs|ZxD_2YKb`hEi6)8S9+D)tdy z8YIgp+Bwpb8n4hyp{Q}8pqhOtoDC0weS=tUlYCndTW=2eg}M4M+Fcdg6Wu$$w0+kI z|Jgj;Pu%K=DOs`LTKHyIsCXddrI&k~^-V!8b~4JPI;0TI!<_y`Oj@~kfYW8F452zr zOobfGj1cDS8=hw%NEb_!@c^uKX;6+YTCO?mjWj+S+n$lnd|f#3`Gt2}dffN7!1|!? zT}4(XY3H>hlin%M^4M1B&wXFe1=s>8n&Bi_6vnn8a>`;YQ`wPeW z>q`Mn2CX|L)p@R8Dc$ZC=1JS!J2cUtBcvGX;u;jt{^ppL&78nrj*<6$B)PegJ~h|y$~U@aZdt4|_##un z$}v@6WyKT0nP>)m0B@{%(_PEvzKgH~Pia?)q-RvP>~* zlbX`6)s&m4Lh4kWFY_0DbphPukubWvHc^|JU-F{E(6BHEvRs5RM)+RoL?(bt$#bTU zKW?_4UHDgTmRE#4#5g!{QosD`MY490w>4x^cW>b1;9OikGd~2z{KC6R$)5kPxgwmL z&vQR%4v>H#2O9zfL&K3MD`^ghfik~1hpY^l6uY9ff`PG)5*ymm5(z^{!qG4n`}4$) z|2%;-XVZbmYp5x(aqt6y+71Ym_D_re+Q|wCR5Vaz`=hV;Ckxy8BtW2&76%*0AHoFS z7&wQF)W4N{t{uu*@{b{D4r>g?K@tc=pU?3p>%|;Gf`Wp;Kl&VOe=xY)AyKx!@osKz z0&c=T^#MspNC1D1{({0`zi|#OPIf<0a2OC_hqzduGY}*I0{+5YEcQ40-)V6H_yu-w zLO7pG_?cDzSEj!MIer=VACKg>aW3S`NL~C&S|LyfCvyziN#>s>KQ}LkjYk8Ca&hOC z0{#nBik+Wd6f9yd$|LWBw1Z2EiwaBdnkd}Umqeq{AdnO60YCqr@?lPhpQ`i2%`pg> za~liu3ySdz2^xR|CBedyV2MA4{}U$#he`fF1|dn%#a9aWYw!YPXO6ORF}FgDuC?j+(;OBDw<^DgxaF=tVobP2B9RrZ6khrE0_+0is z*nT7aV03XtIPt>~mPix=&h`_CGPg%abEu&#(QF_N;GgFBuP~wi4JQ1*!N9*^zuz+F zi*4kLLBjsf5N%K^nbnqk{3&mk^0s9E#c?w{~U8uT*TZ6%!R#w zM%~j;?7ew$S|99t|MfLid$}}5sg6`U|Io+B%I@U$eEs0n8+m;vYht{!JhX7AuvPCq zu62wTwp(+fyT1Cqx7m^ScRWUw*!#?f`kifZ^E&jGHzydVY`C$Zn>n(@r-d{3h+=v) z!)0VRh)rvUNWE2?NrU9u8l*-U<5R-ad&EKAKX9Ud)L?lL=}1H3;i)eTwXE?mimyBd zMV&s8Z4J>C>()+$2;^`cI}Ll;cReK$(2P-MJ&MVFXdM5xR%`@6o*`;w^faVp9^-iR zdpCWEk}zr-L&>lhP4mp?GBLx9>lB46kB8!npSg$gaLX9aR$7M{cS90-)n?e6(#xM< zH%`cDt(D+Fj}k~CUfONd;6u$zBj9%VNKKh8zUHmM*sXEv}#;rgdvyP9j$$Sxf!hssf)h6Nc^}7f;N+ zjt)9ByinKCW^!Ade+$CYp;Y*AQHpw2Z>mPMlkwUWgXPEWr7B|P2f5n05mDqG#O16H zIDy+9Uz{Da=vjy$u_J7bf|<4-v7kyE`bh8Q1RunaPTj&g>Ze^L;HbRroX8*YDC-YZ zlu|N``p`L|TFsX5OfRBhAvvZSxeQ5z31>*t1eQ|=(*znbE+#rMhM-3|z4QY%r`!j) z&UtpVfQ z6>uJ^IwuXECaD{q%l)&CqB+*6XX->419IBhz-)WJzRjR9pR>f-}ccmPTXIE3xPN)Qc#bCHwS<{HJLZfUMcl_zsKUAyu<8X7E* ztAnQw2kYzt?D+lKM;+UFb1N_w?Ia1fNtUH#dysZxNC>gsEA4La`8qA^P#Q)Lf}62+ zr9+dK){B7ss$Ow}Dpk49lHiQlwPIaSg<|sdHKI0CepCmXSEJ2vwBrfq`UWZ88S9X_ zETWHy0q^$GoXD5Uagjp1mvnOmhe*VlrNw0mm`@HU2n3=Z9@%}kTMe$hBhJL{oW3vq zJ|J}L{zkHvD&X>$d{VIceHlLeqtLmTiBGwgWBqmtvmS59D@>*&CMvRyd6F@MJSm^Y zI`%~oRF_>d1VCpRn*n6?MQfBAU4oHBdH1yOvz2_70&;GRtf2KehW#H0QBbvOc{{U& zdTW{$#;Xle2r=Rxuz^T5jWJ)_bQ)o7iQg5lqf4v{^?j7M$`-e8wCRb3n6ulq4eARN zf>rwo`cb&+R)SZoFiABu6i)bNK?FjJizCv){kxeY)z{mReGia`5JvI3r zT$HfEm3aZ@Jtky9QN^3253)p~voj1qzO``HY*Cu!Q1?0@L zWb$=_ujFab>kZp+h&*ISrLvUb#_6t|VVcqUHzDij{Z6!=ddI!@-X3~#(o01QM-N>D zxV8ix5O=s0lznkdaB|5v_D3SS(#}34{WzsEI-HzDW?tHfi2z{??TEzX zw(`;*0lVDGKSykh-mTKB`t+-z+lX#@L_9~(SFOwH>()iZW1 zOuQ3r_p28$Z`Y+#y_`bJ%v9rXG&e@^Co7NAx}D&HN}Rq)3==Xteka6xm1|Vy|JW>r zJ$5g_mPp02TJfttw)^yMG@rvwvdF|7W#-^EC)v}x8tR?TR8$yMS3--qg3K1$^T((~ zsT5$to!1ggl0PQ4smWMAe(a`MQxsdfoXPE5@(E)}fr~D1v629voy=wyuk=UyicivX zwpwv5m%d4O!)sbJ{N<q;f3Dk{!~RCUsyM&6e%bx+r)?Lt zn!iZ?y!p4v&A&4KJ&m|HjQfj{&mZt#M{~dUF2?^|lJOVc5#@QY={zvGNI8CS{ZjMq x8|NYn`HQG%{uz|~E9c)$cCoSkB3Fk0u+4Pt5}q#s2Z!kV1I5L`sbak7{U16yBQgL0 diff --git a/external/libtommath-0.42.0/pics/design_process.tif b/external/libtommath-0.42.0/pics/design_process.tif deleted file mode 100755 index 4a0c012d565ecd12a43186f132b3bccdefb9a23e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 79042 zcmeFYcT`h(`!CA8z9YXG6;x&fq^Ss~2uL@Spo55l!YC@zl@>7+AyQ(Rj-!Y)=>j29 zktR)gPsX9QM0%Ad0YVQUkY3IXbKZ8=y7&BX*InnXyMFw!S4j5$?(cq{&+~cezI^$V z6xi@PsVMB)m*~Ws?G)*+xhHO&J`quI*S5lRb)WrD#_4TkEp(S%~`*- zJZ*VXI6kF^hZ`zYuIh5Kw!`RfobR7u6R?PdK8=Y!8X6)J@##b*Daqes-K{$8uAPsI z*TZCXKD=@32JL)!9IQdx`5@Jp_K%Zp{cld1gtAsA`uj2sv&mq7$&kl)BI{h+#Nbg+ z#F~H2$gP!!&cKQyW015|^;mWYVPZOb%%fjD(PD6^OiKKgLG3h^Rzp5844rLri2Pnk z>Z?}@OzIrMa(mdRpG(72rXRHK>o2^Po8_0`QLCu$eW9S~`@Jb3*n*LjV8gnqSGUQC zhC>9yhOgO%H`)WY5@!KBpDbQbb}DetS;3jpn_=DNk7ta6CaX8aXllG^It)0=(wg+0 z)Y?s0!m3Ajha$uXf`j{4Eq^GEXmtDIOv7qrZBj$LZ@_3^I8`;=3XHO@u8lGsu=NI~Xljy0~T zY3#O7yky@=lBawq{f|pudFhFPoeX}kIpp$QVq@GYHvr92QjJgldW7$u?#SgISM1uY zC3(O_nH{TmrbFWZSMQiVcfEz&6qmV9mJ>y;yjP)fE7gs3r!{MWl~19tkh-`9 z{*@>eArzsm1l7Km+GV#%iwc&Hwk*Wy6*Qh6Q4rRJze%$szXzB1xw$ShuczF^yWmEq z$=c+QGjP4(&^gQfYG}?~!|>(dg;BSVH9i5Giw5Lx)C8cyg55=Sh0mw;Dj1ro+a|1X z1Y0|T`AhTAySDC)&KzBn*qM|2c+YNGQ*UEK6%IL z+}ezpPj@TBqH=0QycN@x(mGGW`@@Bmy0~pdBn4Gh?Pw*e<^tlg???_`FG0|FbEk?+ zD($LRlTcHi&V-;*kH|0nIpL!x*=l`NWUyNY1AxB_&$3sKh^zuwGMzQz?3D&aZVlMZ zugo1^vJQLN&{?sN1x-%}zn@oiv8B(s^4JuNS4UR*>fJMPnpf_zC>XJSc2I35jbgxZ z7mxcS?&DTnw@*qJ92rAye3JGf4H{%*vb(SvLxp5*W?DlzeeDU(*&xL%A%c#L0{*5XR)nciD#zS<8g3X0)E&M7%$M{e{ zx5hDed+JFiJA2)Y9_@0Y5CYfVg^APmx#&_ZS}MTzKzLQEgg<}OHc|@wc;1CZ;=x=; zqf(CgdWhQPy#hTSE#)O=%<<;-a^Wt9{cU6xV6bvQ;Ptm`OqnhLO&-WUbR>_?Sr(7Lx_V=u5_JtzB% z3UIE=nx1IxygzSi$&YkBGO3}jnFfK746LXf@!C3MXwzCP)MWBrt^tJ079|G_hYmL; zKk2wexBP5K7HT=-rj?_L9sQ7^_#Uhd?eE@IIg=B23}02wR~cEU%FnqqHU>*{ z7c)B5GR9Jj=c)wes~@eas0rrj%^Dao?vgN1RfBpd;<}%5z(lt8V04U}mPylkBedIK z8ST=2b_@Z>LKhwv)j^}!8dEDHK24!H$ht9)B6 z;@+6q6Rr#&P3kKqh(8SP3L*+w{hHZ<2IRBJ9zg`|!aQYJ6_PpiEM~`p+x&y8F3r5E zS>`EoogHRyQ}&&cCB6MxiUb8tZR0?WCw6k4P)+LK!Y>y6?s+GC}BDm$K3Di3HMX9 zy>D`C!v2f%Nh_;xX>L`*N#Z*V_N7u=)>XTRGR{-on;}a&nTvqYzJW zXBYR2;!4e!=M)=dJ+GWe&jQ_KPs1D=I;V~Gvx6H00^kl4wx>%M4rTUEt1G%JSkl+} z;I1srB%GFGe=)5@o&H3`wZ=uxAYh5=ur#pm`Uk*cl@6yWKm2^28K+)ztozpBrsvWY z&U@F6FZj#j)qI>+7HZHgi3jh4UoqdO==-*q;jNMl3 zk}BqKz}1PvF~eR1$>r~7j#4qRFCF;@QAq?wuX!7m z@MJn-DrjC+7RRAA%+537>!kCR(yi1ifh~ z=Gl9ufZZQ_`W{t2k9-wJ-Ds5+OFR00JNhr*T&x7df9zD=Gv0)tdid@zd4QIMRJDRQ zLCCo!;S?Z(=tr@?I2*(bhaJ!Ea)rBw#a2(7PMi<>%^lBs3^)hXZuu~9_-G4M%FOsiL2Dqsy?Vk@1GA; z+aAm-7kPCz(_A#_E|HQz_Ql(J6f{35vu^kgUy>?d=>x<9DOeYLAdFOPu~^ zm7Un&%WK&CLq6p#tW$hrzfyC)!n~nSIPbnZ>^0Yys1#iPwt>;1#3xCS;rklE+X@X} zxUE5Q!@To*cRcH}wQSl7vpL-h&AqPnYWo{t+GQm?_wqEwSr@4J@_wVxTRUB9+?PXG7{UMD@ z`N=5XnXt0%AGEN)lF)Q3%3mn^D}Hb`T~O{eT83=GG#`Qs@O^KH*zH$_l~tIVB~Y#fcE(DIhOamm@bUGlm^4)Bpo7`c`-PG!(ka9V9m#e_ z7okDt`|m$@MUX`|Ct|gstZu2`hWYfcjtJIgJBMV;>cOyuO9lI!0b)#p+ppQ}$!2LEVzUSvaGhBSBvPr|s{p>uX;|2t@{Ze&-bt7m^=V!3DM|VT_-2y(rJ(k6 zH3~^yurQC&B3NP;%okHIP3=-oTrDOmoS+pFHS-d3!38{&3yk~-PI`HJzYvySK{HF3 zGw!~>Tgeu62!uGs5A{H-)%5@D?0&5y-O%hhHF;V?r@>aTyHFt6OQoe5UR!S7&H&l> z!g`tu<|PnjfqJodYX4J`=6^{NxO=IY4#L4t_~=dCyPoiERbyJ$1f>BCvaNjfwhY+a zG(fl#-`>UKnSyLpY*|@Zl(WlV_o9_97xnJ_l`>Xgb6wYE!zKd?j0^B+-ebru!Ps+c z+NF*pS{l{|P1Xk4q87SA$3V8cBQzjd2a*pPN%ApL3VZ{KB0U&3~m64$WN4@YPMc*#%e#Lur^OlR>6P_U!xJx0zVFc@Q z0wBOZeehCS4!74mQSt$}HIenCW!b8iGi6@-t`~( z)M6khsU?4~a=~KUW%1_nS-{iR4VDpj%L{|{dOB<%5yqpbV=;nCiDl#_2>!AaP1}7j|JPn}_aj?-xqcePcn12fyQfeJ7qhcp@ zE@=i}{VgEe%LmxT*pksEw*-U%ju33<#oU6CSs;n&W5(8^g*?IJ1O%T$Q)F5$y-!Iv zdvU9{;|1f-`cUeog2Yv4F96&dGAAl;-n8q5N<5b;wX#_tb`4s~ zTBfR^Io}@gmI?|~Eg!uP{?aJ)5d%q(`r1^TULBmdkO#q|OoFEC^|zOXwDuh~I?;~> z8P)+&bm>**(xu{Cr9ERjfT8P}BbfcBG=6xeN@R6FoV*uOKd~Z;F`GW73Q(m*2M`P+ z+eAQUZQpB|$p49C$)29JnvBuHMYZXVmbzu|$vDfVc}aphCjt}@FcfZ-U4VOZ%F7Aq zFv%1HxIAZQE=jVzyFrIDU|V#GmF31CyOw~$lH)FEnJWNoY!b^_Bsp8aSeZuvd;Lqm zr{BI05DB;eQ?)@$eTL*K*3b7|28uHMYr{^CK|@HhWNa>c2bgBbK$_YxrySo4^3DN` z_NZsSz#iLt*<~i`ezHq?5J;jnvrv6B0AIZ|DuAM{s$Yz|1Vr&ZS!YAN&E`{`CXMh3 zHwv)o1_@oefz+v-(*mL?SNZqf?*`4*(1~L3+H`}VRj#f_3_KJ@W!>*gfKiVLI}gFR{5uvi+4WKMq%lpnxA z-N2*{NUJQ!dCujYL0OKrAM8m7$fv@d)F+Iao(5Z)PCu|FfixX)Sd1n*ErC|?aA^>0 z-9F=EiD32ND^|*hgp-d`QbgM-D*#_Y>&D%kiIg>R^;u!C8@PdB8Gp*M$W*OewTB&2gvohM_59Arz8Ui zt_T?i65}i@^F%Q3UL#Nzal3DUL##I-OOwvG*Q5BXep=auSTfXbCkp)cjZg%(`#Lwi zwK54#*M>q#Ale*JoLJSajbN|$^N+Q=3ODC_VSFILVP^5amv?`~d|HpYU6;TLfn-Le zH_j;ofrVd|d1P=f0A`=bDu^TL{j7W1xcVxPUy_5q{rL>E@&ZpEEB6A2_;ti71^|f= z+^W+5m?Sz|megP7lVL`>v=`y5E@SUC%jGj44uvaT8@o2q7!IBMc-Pvs%Kz#kfIpb% zn-%HkQ5VR3%Lj=QeFzj}=8)>H!%vM|0Xd9EpISH&)SIrub-AEx4AcN0uGNg?Kb4kU zV7pZMUIy#=btb5AGcSrBP6gHFO@$CG$EJ>H&}-sfbLLfqL;!ouBIS2pTZxDGd!OCbN)$|B z#$ieAZ&Ko^?-B@0_d+aw8Wm?Uh|o;$8m~=n&mB~cB{0X*yigl z0`m*t{cPyKI~yIVNT9&7!2fy7J;p+7-C1CE*r%=Lrljy7ShW&v4W*CGHrN)2y&2Ed z=5?YH5}cQbp3UkgJj?by!mW>KO?H*IeqEldfuh&m#p?FZG%k2pZ(#sOGz1vwCi|UN3BFTdq}(zT{mWJe zYCRGgdcfzx=zgCzUX(^y#v&1bV*1!S+_8=qamOwM9}woYAKv^XLk7)4-s#?19xj51 zeCXPJjQoPxL0!3Rl^DKtR&2JJSwGrk<^9DXEbBhLxKRGZN*4e{#nDp^u{F8PQCCi)ZeegsRU+Bh}jnx|j>KEC}Cxx~# zCAlA%FN}rvLyDK(6T9|$w-AyLH`^OAl7|m{ZiBdzX`n$VFLa9$B{@~wx?{r0)ahge zb<*EL5(^DuL_pn>XGMvvGCj8PV!EgYbd33;S=)0@DBVZ(n)X3s6QBUqkI1yiKUlh* zx!Hg2e?fqC#iQ+I@lEN^hblUh5#QVF-d}TM;9dS3%h@Z>6x3OUFGV*!&biqT7u8BX znBH5Xhb5d1Ip$hYV5=(^u71ggPvtFs*PM zUgLb*&BjxXt$qL4JItKL+JP~zFU)bs>5dnDg_g6R3*xR5GV)ye8q=G@&o9KDE-=f; zZKUfb7Sdu?kK8wVm!QtlkEM<7rR7y?{)>SmxBx8x9NfPZD6>-z{HJ1bNg^HE3)t{m zLrHS+_#bXB$Ch;7a3}Wr2LYQUVxRgS`PW8(s7n;nE z(g1u;*=X0lxGMvj%j^Q(+x;Idu5-K@4wDe*WQC7yFEsX$j-8~YHd*OsFEXo)2dWDv zuVT;YZ!eE%6G!VpC`Jz#KO6aWz4CcP-(DFj$T5#pow89rFBS=z?$WZV({Jgm82f)I z8`zfuz_#{#4xPTFh7pAJLILk@4s|(OPJ3!+BK!dFJ~ zO5N&ei@k_w;UM7dU>=mO*hjM>C^zRDU)$<jx{<}KA^ZO5{{D1tWWv6Jj>mS^0 zWCK;D6~J-l7JUEkl|&1YC>4m)dL)>hlyn>#K47WO5UOH@i|Hk1nch2P& z*l3xF1^xk4>iqWf?+1?l{pY_Qef87Qg*{58gKj^h6Moq=tFX_Ozm#+; zzBI4q*&CBXKklyHuS|NP_~&Zy_V6ZW52SIAm)vh86cTMIRNE7#w`NEb9pG~ zUq5;Wob3DGC%fqC=@oQ@B9Ri|No^1dV82cc4Glerh%o6F3Wd`vKyN%OGSU=_#a^ju zX|Y5KIH6Ghj{`D4S2xoPHw+94x?1(|;~BOYP+`n@I;pCr79Bz%Ts0)f?~>wF#gUIs z&&)V5dD|;@{rvoHySio}bfgwXnNhn}?T|qv-?e{QP{w*xz1{M9Fu$xVvN5XL&r{wDxz+_1W3kORUneG6#B$ zK)|g6)US7r_NJC%-Z^f{VzZ-ja&mwR?=8&EdINR&&J8AwytF%^s-i-l?J8Aum_B=! zN{{Yns;{dvW!p*Vt#55TY(!CEX8`atD+7;(rYi%t7=kn~nogg4$q>hMC~*MSw$!v5 zC2fV|oRO@;<1@dFqdJ?SqN2|3EW&5ght|xktj0i6U%y{c9?pkJEj^TZoJ{)e_#i;u z`+#*H${fidefR4i= z642j$PC6e1{OUlHI(@NWzN z`g_*2HzvTZ1u&^p;I>JCjDi;bdsF`(l@#W?fb|eJ34_Kq1>JP%WcVHXulLX22mF|y z?sDy5jNg+N=>dMY<&LPR@5R8kUv)5{pRJ>?R^U zz*4XGoEibyot(N9o^ajnVq7n%b=tC7Ik%-Fy`t z*yuX{)BLr>N5iv9M23<)Ft;P>SbhLhXk;Uj5~G0rW^jq>{P6RTE)($LdD+8(k_fSW z=~S9is-AFAPi6I(7X!_10+MDjP@6Oyw`9>1%-6^3=qGKJsL^ZuHZ8C|=l4|#ijJUM zbuPxf`-oVjfN0pNr4In!-uk%EIDbfkKSptTy$Dh5+MX3fz|zXr%e7O%N<@ zQ#FgWV|m#BazsoH9dh;vADQiTL~lO9uvfgqyiYO&stWz=&I3wJM=9`Y0eHLU=#R6pj6x%Z6)~jN%s_9xC$}7l^AxvRTsUPf>&ngSH;Rk{jtl$ zBQNZwx8Bc9h1l>>7e31}@=N&G9kwT{GD9aAXpy1#xUg#OR)Lk}IG7rJ@zN(k1+cF?$)IV7A`qbIEt^ttPpW6 zY~i!D8t?Nb6CBV1X~nts;KbDdO4$S$Kn`)5e0A#XCl=H_+Cn*lE{$egaC3 zGzYBm6g%9D9lk>s%4QKmAnZw9@`-%(c&ln{(Q?}L+W(?QGyt zPq=QE`5WOAi?OFzLNDv9`7i;nc~*jOwaLl;r1TR=qntguw+`9c5uP9xkj2v#PxDg4 zUVTRS$hJ_I&nzkHJsOC8&O58r2vANkkylJSy!sh2!^G_x0})tIVg!dk7tYYX)X}x` zQcsGwcrm>5&`k+LeUWez==2U-`Rp8TN+_;2NkV7_iIQXMFA|~yU6dSM@&JnSQ<7YC zk_iyse_#6lXEFJu0mXC(Ba@8u@2WYiGvW1zglg)=LOSs*;2&i^M)(mWAUIhJAjdWh z=q*JmgdoA$0AC5GB!-wkq*0m}Bx90OM-GF3s!V#j_m$rMt(m-&$Bn}ZbXL%4bhm!0(_ea0N%tcskS zeZYZZbdqFdX?!TT<@8x*pP{@g^6M^n2rxjm8yexgaqUa=!Dg*-6c*scsjNJ6LM|-!2=VT$=Td~il9G-a+5ah z@K5QrzA(JJ=1c(URT1b&5tpW?+r06o(|wCUt!dzv>fBidHjm`A|w~@G){nqybifM{rK2Ur35+s=S63w5{67KERZy3D>EGOZu(5)Q|Nnks5 zAw1#WzxMuLIo4$p@b}+<+Oq1_6MMauhmv&{mDjDiZ!|5wi+#?IT6V<sEW!0T)$X z0R-asFM$AG{VDi;K$T$a!tzIogIrCk)5LIyulDsQKhPHTeeq0NV)@|L-3* zS53G$do|?I(5y}fyq838J47lmOWQo9Cgya?hoG6+(TMIFOivj$<998KyQ9V*U=odG zE-TyOCA?i}7oJdg75GYGcX@reX11U>Nk>0c65(_iMoU!9*od}5O7tE4(O>Ji#m#kf zr?pi2*82j$@Z?R`&1XD=&DEGplu zbKsvra-baW)jv(3=Ucv+geKC9{x7tXkVRsAlf^_a%Ei2LuMN*=Ka$x>Njnvwg-^~x zx>!VS2gZ;aIdfW84M0=T{Q2et869!LYg5CkvYsMbuiN3RsIR-!>Z3kCRW)i>`i0RX zp{!7#0;dNCuyk6qLKH!1%rH5i$4&kfDXJcFP!fdDGd6;sOIvY1wHmu)Ohr^Hkq-lq zjb3Y$N`$q_R{SjL(DFu+BkF#Aff(?t6Gczy*Q7CY)$7vpKwnt7EL@Va%qa!g+bd}@9#JezU>RS?G9XOPDJ!L z;VL;Kx`5OUbTWxy`{*LhhjQMBc8L|eC8s$(3mO777kFYYi`HtB+aYnLKI#3NAwHvL z^@BrzdBeNYe$$7m6zl8)_wieYt6Vx-{#*#4SCrP%QFQY-l!*ZqTssSN=P5M_fr;G6 z)_tZWEnc-f$`92tF$8>nnA-AJF(3>jO0>5q@2ZU4%ZPJJyb|>nkKvow$R&_vG;0DvUX~l{ zjr12R^Q%+z|B&g_>7LBvB*fYKe5(J9?%+4laZTx!-3yu9CxYIhUz+(Ly;n^Xhrms0 z^!UkJIn)cI*CUcb_9K$PLlKItiq;FaN4Gd(pYa`c19Q1|kO_PX@cC8mz}$w9N(74K z$M`a$k}SN-`gv$7|BmCxCrDq$IBobYQmrC>VexKd?BtDsgiOc4T*83vQIs5&h z93dUliEjetBgW8~5>032aEM!JeBM6tEe7C(o}1j#qmCP-(odt1}Q&DD#mkMoR_}ho5!`T>GdK4%C7-3nd8`yVtot~)=WsA*@mE?pE)aX&2 z<`F`raE=IIk58Qkatoi<|GIaxA`ul>_;ePLtTt=alsI>_=2=a63i>#{t>u&e`z2~H z1y{}arY8ED1A}iV$xdf9 zW@GbPs?*SkWoJe_1zFS5UJ%nc`j^fj9IHA_tQGt~tsLGDjX-zmjo{I{;Rno~o9V(B z?ecm!(N@8Z6U{;P75!Peq+G2{wdo@$A!*~wCC$h*pA58<(L$wn0HRIg~MEzcW zzv)UV1~(q@j2=8)^~C$f+TY0Z!yRKjs?67){M&Dp3~|O)*^J3CLd2S|^5&0I%Z3B* zf3Ce@iL{;lqmQ_lvS~c|^<#U>q;Z2mMUH5|GzRV+o2&RDJb7$r^d&es<$5ygvqMvb zyjk>gG*3}_Iq=Hyv24+PYt7o9Q)2c_ocH-f{L#9nQNgm_bMi7@0HmD!H&*X+Iu2V_ z?$+k2QUX*=bO)cWbhKh?hAoAkWrd$-L1Z{-zgB_HV&Zb4=gWFGMBEomYNn-gL5sgz zctQho33ye)XuLf{I2xj|`fl4D@3-zk?r$ogJv=~t9^@mRqI70v{D?`nai28${AOsE z@%V*jR}G~5#=dmm>5;Mvi;XR&z`H1)&Lj}lrU*fu_#4uAecLZjA04M3Hw{s(PaKE9 z9u5(v6_^(W`bzc+Dg5^GH4c^))uf5wysqSE3{tzK=1dm zDowOo#Uj7&;Jb`#hTpUm#aDb&9bXA26g3`J8v{bZqls_WVL-~&YrvOK6lp87hp8hdLA#fry^Q^xiGv!z5O3m7cN%x0 zHQ9FpJENoK)Yag>gkF`zUzwfPMnE&$Wsz$FhrV~d{c}yd(m)O5ruE*FwU-Hro_9Pd zJN#t}jBg9_&T3r>?05dw$uVE~kW7YnMbmq6XTW>CKJiXria#?;5l)Y6!wfNEHipPF zAB#|nk@avQ;qd3Qf0YL1uIeb#MoaL>6D!Tf%0&4gynGck=oeg@P}58rb1bw7@vwXy z6ovj2_0yQHT#nCb;-VW~ZDki3wGN9WM3Rl(wpELC`7eh;yl*c}$9czp9+eZ+q@76jND(p9P!14$UT_(Ti z_Gz=uvt|0?;Q@inYFaXXKbd2$0qR~wg;6>{2#rH`%GIZJ!+gopXY;RQ#}ZRdsu*HRNN-V9^fTcO4cvw7NL-x){qhYjMx$kPQStZ{ zREk=~^VM41_dc$1nleTrq!$lN)#E-XahvRlEXYBYhyJ0*5CU#q@Z|>Bm*jfiQp`{j zGuoMWvEVK^Q*E+Cuo)SMV9^?+HG(+5$v5A*2ZQ;RPekNUqo76ZHTrs{y|@z-P*Oqy zyQD)l_Tn4j_(h-odRP!1qEMc@E&@YS}1YC z1U;>h;cgITx!t9@I=5@&XvDSP4&}LQPRT6s3*~MUI_1j?58BWRZH`+v8zNf@H1d8o|k9VNsA%rdsc1dR%BNE2y%+JYSlq8 z)cu)?Sf!stR$1WNG`qj+^jCQ5LXH#1byfh5zq2eR)T1@h*4D+p1U3hfqPC*qYHULP z3!}$=+ooF|Jw7rQ)sKnj8}}O;9|a-6GC#7cR?x_N4gyX%xpI|tq0PUO5-U58tBz#F zEjEQ$OiE&agLrN5%s9;vcZ8q{gaKuNWoDaA1`d5SfL=Y~6Duy}&^ivv-piP~>#hx0 zIycNcS0^R9g5}yY(S1)59D;4KqEzXY4J^b!IlG$LjR!y-kc*Dz4T;c$>5$Jj zv>SJ~#!<7{mSM9ym3D)~+h%{ zR+Dnze)>|Rz8`Diz4&19eKoGKMnyL04!N+_LAi02GGDTfolN6y@~fl$!h%OQpm4aH4}Q1eaJzDtnqv0mF}MiZ za-CdJx;YfN;9|ylse)q){y?|ZR*vwngdulp1F65542R?&UpW_ZK&FYdWr5$kjN1_#)UR#tT3s1p=PolB!RLhcJ`X1^C z{``}8D@u@{GQPLrEXYiHHFbfFuUVX=#->V_~Lw9l) zAz<7z!sfD7Wg7hAxw|w@Q9#w=kKI?hof+T83*W@gIedY1RiUY{;ss91s877i@FV2!>9sN!)DuO?_0}T$oGnOLSof!Ra;ZVSaB4Ew zb27uKaGbKAh^~VbBMU6vxBO5x50=Akgr`XNd1f&hZjPR2h6=8DZsx&fbX`&8Ql15< z&W`xK=z!aqnQVyT&rKZ|w_2#8DN>qxoiZP&3@rqCJNSaUGh$ z!p9i}^RkA$=8Z^n7AD(=D*SuLdGGuRk6y#qjAtDp+-%4!-KH~Vawz=sJ#q=ZA_SdL zZ_XzVk{WDbS|S`5M{_B$erf#W_QAR}Nm$=uhtyrUjobAyD2CiVrpEvJ629i?VQtBc zU^I-UVk-b^0g&5iuVhS`Uwj*MaBO4#UFO`xx43I-Y4w_L1(S}mk+Kt*O5L)%x$f$S z<4E?|vH=;V(5s`uP|t5)=xFu>HKSMiz5YZUmo@x(>@@A}_#^7HYicOimR!73T0VQ< ztkWP^Z{_^v^U)*F>}2L_O76EIzaS*gA2GL3^QK%Uz4%6Xd9=i9RHtG;=GU0uqmWtV zs2ARuQwb(hlAsyUvyQGx^MZv9Ag5nxMI8?z%fImQiI%-YccAh23&PKk-cs+ zl~F5h6f zP55X!-kl~aT@9I3tP9*TH3ymfuJ$*twZmZYp|%CkRHrd#v+SE_;*23oF##s+)o7uWd?J=@Z(aZ=?L3Ah+9Vd*oh(&%0Kd-g0ZI zn^O_~B&)g5ZEo={uV>G_$hA_v_BV{(_B66xqn~yosq`uhdp;7{oMdO;)P-Su+=aNdbO;~msQiG}{h=yx=C0leh!fgL$ zp2P2QIl6qG(2&o%;Z4g0eE9LY6IwmGJ;J$FInjZs*KD<*KQny1hMf?b&RCy9(&~F| zO3m@w4htt|)GOLME_xvkk&+&3Z&;TwS=Lba*gJe-InW* zBqpN#3#JXT=fqqklbed{yznETPm@iOS6=GevSsViyU4yy6He4qkm9(Y`=b|YyJ!=a zCZ8Yc*ueG#!-v|w2Px@7q(8WY^$ws4Sa-ii&GFk!2S6n%1jKz=l4lqYvO8@gx~C9- z3NvvOw1i^4J*zJBPDfnr`}3lUT)ZK}OVGl(T1I6WjaZQHszmNX+mnJ!X8NwJRABh4 z%ADeL0EY6}J!K7Q%yVC6=|#|)*q@s6RXZLouMsAUH0agS?}?pSz;tk0C zR{YI)o9z)2@0dtc>08z2I^1!9ESx5*MCw?&kN}Nih5`mvPiZr@ zo9V3!#yU%yQSiWA(kJoPSYNUG>?D?w3UT0WOaji$Mzv!y_-Zdvu6GXpXywMtT3U<8 z>~*M)l>zM+bLe^HPg*&xVZoa8qcrt7P)b|7UE?j_T^)nt&Z$ffRC@WG@`!~gTmdIL zqnBfCwS*AW64dZdQ!FFASFp}l1!p&AC-T;ehsVO4(FYh-VFZ*Pp0Ju}8ayGxw4j=h zgNmSGpDUa<&jkL2w<6nVY0A+xReRAwto||8GwbvFz02GFJ|Q-XKAEEqysLP%|5J0M z2^^$<6fuwXF0YjBr^I|ee!8MPpA^vTd71GXoxJkaL)f zW#4VuncYZy=pCe@614>f$Enk`$=sPyD~eulwVEDc*@NcG-dkAAJJGFYyQ{Cs_9yCf z2Oyf&+e#FUC*Gu;mCAo8Lp35twrBKmuP!KMrz3ITs)AIHR6TvY_>6Iz22-J)S8`<9 zpT>P7e)z|%G+J*Q!tYBHqBWItS7cMJNZ;qDRFyb^>_S7fU$OPkRh?;8-6oCF+g=&? z8NIoIKKt6K=`*%{UJa^j_452VctZ6Ur{&PXS^N}vp8blRN4hJFReOz1HT$6CarE#- zlEKi-dZ%Rv*j7D-262p!wP4;MR9;0dC^nSr>ek|&M)c+LPG^5m2?NU$-HC?_R%gd) zeF*nB2&Gg8j{jMF!|iH|;fabE(1tB$%htLZQPxR6I0w-V8(AThXV48zXCZCGaXRf~ zLM7=y(>oQRIpnaSJe)9S;WJc?V%Z%BUa@7zJ-MgWa8Y2%pYGHzTe;0fLS~qz;R_Q# zIhjR6ZOr3jvpGg&&--KJ#*N=$9CfpcAR!9 z({^E*15ap{wZ;cPtojj5F$BYc$X=kGvDzwb>?luUomx-CWJNw1GVK6oh!e{ooz zT$%xiISsrzsL*NL@icUuzLi(8j!Tdq+i9st4D6_$PfjgCYfJj0hl%%A1jn@mjv9@9By67lnGnN-md3ztllnK-EWwf3t^J;oB(&K&L8ygFMr>N? z95wIV^jkOnX>GT{Wmvw-ZVGjq`$6O*EW4=+Q}2p#ZCb!wL-}~jDz}fot?18X%s1~J z`>1BhvLiifNiN6&9$3HD8Dwild+>dPq3b#Cp1J061D4&u?$r^^O?Zq;`<1}oTU<8x zykzP7x2wQq?lfCzL#!&^j{39-8+?CNyL9}tw#PZI?p=(Q>KONe+J2A*C>nyb zB2T!7xdz_t;WU$4hC$ViEa~}@e5^~&s%#eXp%M&dqRht{(zbVHx2d}Bdbi}O(sjGn z?A5jj#AnHgWs&tH{I+KwA>f%uFEjiojrK9R<9Ph<{eB2khwGVnwT08BJ`1wq4Ow|T z47WF0d@He8&qbKiS+F4&fdG>&Dn(st3k_fsm-R^E*nDmYY_V?Dm@L`|b%(6ZWy(Z! zXI=9~S8d9vO<40+>J;HN4Xv1l z((hoevqy{W^-r``tl}@4N0MWt$4$XrNZqlou$apWA4^~yLYr~Na|DEz4-}y+LgSB_ z=H|pdo3Hn8*3%eMphSz9q=Gi%hrZP5Mk9dut(D?B8!8&z+6dZMImrm`C&z=@bGA=73Zmyg5B)(ijUAP;rztxyiiD( zqH!;IE8y#D8Ry%zM{k9;aZ0|0pQib{Tcd5!C;8|SM$=KUhUz!3`M946QW!IYcbYKn z=Y>iyfSVRg372MyYWG_GE+%&#+I32BTkAb@DUeAX^eTlZ4aAZx5|J1JX?)OBc@=W}#v8utsDo$jklSS=AG#W&2j zR}S-UbKCdGF!K0qPkR)Gq<L2jiC3guZ4AA8&wzg0WHnV0(*FXBgCSyB!(Xu1cU zLn*DWvZDxpV427tn+g}DsiriQ{+vCCAC%;>a~=hdhqYl)mB2m3%etTWMt#hW8D`NY z&gHA^{=|X~hiVVDFQK<0lfL{$Z^U@zF}>SzLBMWUdCXVATWgdncyGSeOP9>s4yW<@edEKf42*v$zJ z&1KyYGnEIG#hlo0Csvfhx&Vtvfu&^(h$^7C?z>|Lsg>3Y_GaAdFkkv0_3)kw=qN^{ zis&kvh&=-+uk~<uHgq=pp3__lKJc-~0CG@oMSVLP8p0%; zp^nz1;(?CFjA_nO&n&~gbB#t{GZY`K>`zowy*}WfI!CSeHJ3{*#*(IM7 z)2WBq>7lr7pD)Y@f3^6h3Sr~BURiRHno!p8qYzAr@hyiH$pq)G2c=)cEdGQd=-I1u>RO|z2DDVkF-(R*pt6-n{~&{o*DPJA(b7rW;_A{lYy8m z{?5?&d(Pcn>Ir(=wK&CyAZ+f7iwmysvU`~pUilQ1XHvAk(zaz&VV~kICo^e8mu`<7 z4gNTsF75%nUr=i*>^cB6KWAdFrd1jLgT40-YclKJh4pomaYV2K(sV=-Q4m2eK!^@D zR6s>3(gcKnw1H5B5TfHKAWeErP!JKR0qGD#AV^C@TBwnh2m}HNqyT|$Kg|1k&+mNS z_y4)hb%J?sxOn%rl-2o2l{b3af61$|jN8lSzyF!v$Q^wN z))>AKy~bC8#ln|d3V0uZ(_};*!xT=Y%lbN+OjlZn@OuHN~U<1A8wu?8s;zMflky!>Ha%V8V5 z7a{TIF-+$U<)FtL`+7<}yiHp~=ktj!5$_$n=hm{Q=P6Q)0=CB^p)A&Tqly&2!xiq> zAFXUAF z7C-N@S@`QHa&z+YHH=W?k?P8qMlrgg(mPyj3de4VmHVAiF}BLu9l1yo;Am2$3p&~2 zk(?^mws`VU#ReNXCT|uGD@g>I4<^Igs?_M;F%s%kTw~xVMf*r{&CMj9S3_V^(gAE} z^Z{2r{?kG`Ogk|&m#6n2%epa@4`EjII}%G__>DD&YVepuupJe3K4fY*;)#_k^U7=S ziIze%vWXvY8#zb~IqoqbABu3<(pEh@aftv{70rGp7}D)je;UVve<~42ezRAS7er=XoHBmFdn9cV^fhXGx`UX4$_>sx+boh^yKLo!t>s<)2aeaLOGrxMq`SZ%v zQOkPCQhS|%3)&$t*J$Cn3H7~A`0@U9i!uMMy@|uIILfKfv6DrLHb(h{1-0#{`GGs_ zuDQd*_sy)&$ER=8yVf%5`4JU_2W$I!gtf!2SZoTr@f^Lw5~HdpGr34raA-OIegzXW z|7*<$=Uuep{a;kryNpa3XOTS(IyM8%>CdXAQ?TB>^o(&7Gt+f(fiVt*cu#bvN_Aw_S}Jk-c2CI`#ZYmVtjBE*jv&$8GN;WCez$k7xcO~w&Gkv_|PtDwHiHFu~@WOqln>-`cj z)l|8H6^y7HMNTi+Q8oI1gcrk^zowmVg0|dt9Unug4%L*4p?#?59R_RrTLKs__|evB zHL8EAzI9~t_;U2Bs@MPz;e?jqTuR!P3vGCPOkt&%ywiwYTwE_~&&Cb0Bdb@ujef{v z+_b?(j=8cc_}0vA8Lso%>e;AA5hZFZ;jZ~0st{pT93AG$ybrU1Oarz02%L59N1{@B zkgcK=kSH0|LN7#Xqw}tb;o#f|)bd$!KYaDxCj5#JsV$Px6dZJzm>f=0E90GXt*u-# z!!DbJq@#Vr7Rx9cV|EZJ-ZP`_Vc+EpiTzWjZ_Q>dCm>*uNmS|=UV;zDY3C2=C-A}- zC3GuXiptgh#YYC&sbySnoDtBUJJtJ$>BSHk(auFm87G4eV!!cR{q=J7!pV!__5AQ& z828zXOtYRc7pU@wR6i@+>C^^(UmR&Ln)L{XK! zBDHT#w@*|z*`zcw5AHq!Q$kl#^9}htdri%IQ7^=@BAc{tkWXZwJ+5(ow8@6qHvJjU z|GB#MGYFd7`>G|Z-$q`s=|!@QBC9CuF2$wYLbLj>*Ivy{TDY8WTe_$6{qQ5z;@`y| z2Ym$8E2|>={i8?X)+|@4#?v(@F-;*ed_euPc(G>f!V6Uy`_3uU15JSRqkwzz^=+vO zX>oDw?8G&dWa}k$Nu7W~P1bvh6MlEXRIfWMSd(;XoYy)76dU5n4H-T7Ma4OF>m+4O zl@6(OOM1rn2AOh^mh`?8BD*nGdZ$@0V^NHXMc=8>si#r?M zhYRK{_H%Fu|4czZdB64#;(%KD*TYAU0hzNG$r14rz7+PyfR@6t{?dIu;f_si>wQx9 zx{3rZxZ9<7F-d&PWZ!9Rd71_#d$P{T?W31r7F zN6%{f05gB7$gj7^=aycQz#S1^4juAOnCK;?*RpsvANW=)jj3Awhm5CXq_XBWo_Ix~ zze+}u)%0vHt;(wwj%iiD)VyVNjHp45&N=u3?CG>K<$~Vs2S%biF^rOxVgzjoNcLs9 z7iM8(Q=U=arG7jJ`8HyldUau~A4o)?#5Kd$FGz9!mL?0|-VBSHnS^j`hPWrik zIagbqP3UN=fg(-=#{POt@tTZRQ#G#=f)?*5zMd?=DX zwgLhET@h$d385FyGQqRs@37cVD~)gn!za2C%x{#}t9|anZdLT;%h3RC;^o=~v{X$( zP|C^WBCK!{KtgR#v;gjyKZ_vfC>y$R98`Ib#V)<2CulVmW38a;d1zO}YAZN8y{)z3 zf02l)4k_^yca(?lw&GLE{1!y8T|llDZKbc`Q0Sd>mDMXg1qbPTS?B}DJ;FWo!#WtXZ<+n9iYUH`!2a}XPxF}Y1_6}ObekEBVm7a9S+ zN}7HNZCCWpzi!rA-)0@4l|72h0Oii`B;-3q(w4IjD_LNOaJ7q(p6ONqXsr(u^1xy3 z;Vzryk7m0KHrSv_)Zuvy$u1ySfz$pa`X~*1;T*EB@vgh z;{afsAKX8UCaz7X8qWi)=Ub+NFwc*ht%`B^n&bnDal|OeUdHogMq_`jeur?9`XfP| zt~TmxBNam*jBU3Q?+lh`PRL^E$Y7@yHU|RUxC#v9KYir#AROo1K#-K~tOe!p+F4)s z2zkvSRm_yKEsUz*elg9`Cput#5&&>`1%3 zTp4EQX;rPU+eL;x)HydAV`fZ3JSS}O=r5%`k|D%$Tt)5F8U1wtyv4t*|KY!gUV=ka zHHStUD-s~A_*>jM1Th=j5Hcz2%*4T`eucFos=DCdB|EqZ;h>fXX=VKopWMsf&y@z2 zLOe@=FAM$=6CE`9er4;_afrgKQEN&>2D`SXfA{6gG!%_kwazgFB~fK@vxPMtUqhBQ zarL_g8Ub^T=ZF1c+vNG57cl(w8C(;06mSwYQlL)QRWblNOMJKHHQVu_MfjWDd|6uR z2sg5~2C2tM(O+M~9DHHP~Am4F=uM=1i$j6@@LWr$a5^UGaJCqta)qr z7ndcsViLsS1+!A?k-8Nzh_~{Tn#G2<^G~i}W+nM~g=U`Hq?`2e^c|QF*6N@Ny+)lX z30q@aV8bq(v(&Nx_lE-z6#qGEX`NS(T`=x>@rknu#2SPRl}o)BCacjd5K{OL_yChP zJtnP`w){@`~= zdW)~v#9d76Bdd?bgWxFP_G1Mqgp#(2cAS<85D%WaD!6@!)I#bbA=i%6hAO+4R~}E? znJC3MS!iEd+e=7^Y-_K0?^OxF)4jKG4n%T{A4C}BZtmIN4f7VCAVe~IOF)o+Z@?aX zDF>~AQ<}3lRuJQ1QN)>j$^e>{cV*(4<5BK=xA^@!i*H2W&Y>v=`s{Bckv?(0<@IJuzH|gRg063fb(0D1^f!SJ1j5nQ;Tluc0 z*HhvX)d}+Mc)w$#$DA59A5)l_nw=^o+wu@sxic)M3&zKi zez(){65b3nA=<>8*r zN_$68tn&xA_)kAqA#%5jddmOUK6i_WQxglg#ZxAeBr{N6eFfE8S#33D( zD6#9tnQ9R!CX)NYA03O#s%Iw@iPDBtW#}6an zbrTR?eG>98{iJqkA#B@x3~XBs*kOm58#AukYSYsS`jd=iWx~zhlL=DTyLz8&xj5_i zo`Z8Q$PHqK74`Rz>gBo%>o<5CeQsJUKNZ-L1kqb7 zCl?gce8qUtWWrvKPZU4Gp^u?@lX05|(vOj$o!@p)H8!VAt&Oy~=3uzyv}`F^W6mlf z_~7~|Fip-4zLncHYtfN?A(L2ekxN-*X=<9_9G34f%xxL3^BL68k$jY-M0LorjHJ3JOj~4C0@tYX zNVnKTJA`l-xSpoEH>j_rYWL}e4{CA{2jmZ{i@Wa~9jMs5?cBU(uxQ1wcl&Kq`y~2) zEU02lPY+(1j#DRJa7f;Uq#V(-K)gF$N^7rGt60qDX^x5xokt$QOnbc5ZaI2rS_Yi9 z>MzX5g$yOBSTc$!?a6-07g|9bh&KQFOlftd5Nzt3ao=Ffs(49^TZJUXCrWMhMCRL) zgMHm9HyJ<7Zq3SAJ|j20zsd-em&G;mBwbCi;7ApnGg_#E<{$h*j(u&{NvL2;jHu5Q zb3{MGRJajAW0{D-?cC>a02QJLVWp zzwQq=~QppOI8i*PWCWtm-nVB=dfweg`Ac+HG3NpR$zC5Zg(g(t9_`cNIm zywtQ`tfmY}H=Uk7O&WB|RnR#pzK)5BXBt__U*XGj> zT71+Gv=i+Va%;y>X^SuO@2Vk?*~MxoxH5b8uKyMIL;4XSc+i}?)}51c8g7}=4a?uz zDrJPv#pIg7l%HYWVYN&butaxml5OvUO5irA1t73VDkOM1P-Igp{4Kc!4?J1rj*b1_ z$aPtPuQ7QFYAc;gBzz3PTkpwRlxG zc}W*UhQ1BX!5`QXc2*{As|AH{NAxA;q9;C zjk;OUn<<$#+DP+Yh13v?t8)uDX&?|wBSBjahaeyA&J0ZQJ^U@B%M4W1A%!8B+#vnA zMmB=NK)8nV4{oeJz9Q|wAR9c{vC;} zfXl&l_uMdSat&U7X5EH-)RtSN0mh?e`>b7$a28a59rP%8x1H zfU<4(g)5OE5pe=-lK$wG%oL_ZFH8*7!D+Vy0~d43VAY|h=~Zo2x@>`>j1U$F&l0uXvh2lrp-PAQGW9A7#LvSr(e zq7gd<2i7}u?X(lBf7D(n_sK%G1eY+lrMYB6;78QyYm5tkWB6tHkrTMe(M*`~;GUtM zHev4JWw|vzVt!sWOxJ;*TKOX1G;sqCMGDA=rQ!B&ZOE*1cNxw53eN1Y{G_SC)WkX1 zAU+owtUP0)5j%wG=h8-XURlRBjsG+aXQsIpfx7m$%rX;9JtjN9?2Y4P#_J5GlrwQ_ zO>AYlCW&Z7*~&mw+8}N+-W*SsKi=o0R~bm(Fat1reWoc+e`wrx;hOjS^6${9Ahn>gHBc@ViS`$Q}l$EewS!5xL>y7|GXFH^}vev@FC4 z9U%H90sLQhoi-5W2?;7T)9FH3*xE;B5Z=KrMl>|NRVa@)t^GMt{v7m`{aF4XYTxt_ z7lpjJEbk*G45_4^`zko)rdBr+WY58)h&RZGtuJ%uw1^<(s=jG;Z;QIcn)9ev+`aCg z_Z+j6p1QQ!kF1Px@7eKb7WY%Dxt_)?uh{KJO8r;Z8GDJ0#Rz16^PI%dK9_Yu*-`qj z+3-eSd-UaPw6w!|Je2CE+a*+S>Q^x0{f$g>W!7%j_P~K@@0m6ts zn1^K}fO^R#{fGTM2;N>1(`&~AbIYsuJIHxC&kbAcolCa`S(Kr>Buj0Nza?O>XtoGkjd zCdDSKCbX#7Ok?!EgM6Ta&BT5+l||i&;|8Pgyi8xO0sY&|rn2#y%u?6@UH6o2@ z_+zU?)!$M3dKK5h(180T4|K`fM~r4F`YJkWZei+Bv-{Fb;&vPb#jj<90nJ*qgnPqHL?Wvkz7Y!WIYsGqEslc7VP({@GL`hYyxwp_}YL|KR@aj0v0 z8R3!RDECjq6XBg#k)24Mexo=9_$MaZ+h}?W~Hu!5t^;#XC9=rE8@x`gSPtJk^VCpN2M5Jb6I=P zfFhFqfuvcoDqVJGstq5g=+`_vUpxfn(^26TM0bs=_&#Z7T2$|r;pc{&QFb2dP||@A z6aq7qS;}crE9j1+T5u>r>x@hrC!-2IYULGcP)_%h^;3FAk$*8(Eqd1F*8!6=D>vz8 zk-gsKasTX$LbNl9i)z$&k>tCaGdb?5<=MLp=BMPCtslD%HNS6O6`+X&`Slgov0b){ z%OysU^^9PPiA?zk&Y8dpU^5!VdJ-FF^^*7kCo3VOU`#zI2V zX!BHu^1#pZulH|*{Xx*<*%x)!xaC@6-rN+gZS`S@8UIg~>!){jY~(s{#YU7jZ@q|R zb98iFn^e?Ydi+NUGlBOoFaEh?jz7UDtS**X9ZCOuW|x{jm;(SW*8E{fIhIhQ7Vhb& zk{|D{KI&-JQRj%Qi>s4zP9bUAUnM5+!#+97R9k@k{P!^GIkmH>?CF!__JjHo4$IcD z$mPoc?K(rpSu2Pzr{7;X)jAHJQl;}=^&g(iHr`49Kd@mhku&E@R-FRn#`X$sp-qatcq>Y@r3S;%B6KS3 zQm*3K!LT!3M3)a?7Ia-UGwmFlW|5{LVbNidui}27#*h)p{V4y?WZ;D6{gU-Rn0Muq zN~5XW%)QweSyL@J9QeR_&HJ#GjiqhOQ>)b? z`I3cz7v51_Gn%RL?OkDA(JcG#zQiO5VIZ$4C7!}L4{u3{K4Ie;)Y)?GTGWOkbK-$R zBGW9}bHtfK-kep$l(H837DpLZap%=%hmjxS?B9*!f(*VD@vVc62mhHF|b=tOZjX z{nhMYP9*HOgY$zhzdX_RErp{LPDiJvQ(}*S??srDB3;*bainMa#202oX1>Den56ti zd9d(22A)O+r!Ndw&5?DM7(7ywOf5&2hL7JL+&c6@=%VbFRq{}}J1S9%V=X?HfN?Nu zVk@}!^Vm^qPD*}itM5;SFfHbFN+sI*X%lF>ifNf?kx6yo7Gav9-c->Vb=rdZMEHv| z>$Hyn#v!B!;d|rzsDgw3N~cjr4%v&IZ8}%@>sHTgwuIVS!`P#Re&;`18jJXV}aUz+~)OfIzx?fvtshh*!irx8?fv z!jW8tlxLS#k87$4>3rM329lT?C^zyX#&9#gHbM0SwVrqnyjO9*dU?!J_m7YZ8~55O z?`5Q!-|O?wan2tj!!uC}u2w9Wk|T1HfxI^OU$B}&tq{!x#}WM?B?a+PPX1Zxv@UV> zF?Geu=OixDj9J&$1;wO@LUr0{RJ0K9l^i@uMdrMw46ygLvx(h$xGJwU*TI}L6_mrL zApeuDyxZJ{!@u&9Z4kI~#(Li3>o!E4f?cGKxjJ32L%p)TDnPu=`9`6?=@b+F$f#3; zL>_IvkjgqGaB6GNVr(oL2&_l%TU{27VY!{I->=fgpp|rZMHd5l1>yXOaYKk^vW!kIrcl3Ev17pMrw_O__lTNuQ<5VBB@;2!B#F@pNi3UZgO?bC|oFBYW_VvkYLTOH`#319*B*i{CdS_={j*Mcp4VIN@+89L8k4BD z)2C-{BImT5Uc}=Tb($o;>t&*DRS~@RjcYeul#%AV0Sm+D1DU z+0|8-;t?+52E4B_9ansjc=Fr2VrfG7KJ;hJk7*Xh34Y4KoqeG-Q=%%X!vt9!j9gOf zt7-GB6NJ6=UzGRz8MvvY8oB*46w7Je$K!ce_{)%f%5dDW{pQmQXSv~PtpUN*->Dy% z{Rz~}3ugAO2ErAzx1#eRoPY1~T=t(i0Do?ipKhh-?xbqLQayyE9M()VKK}kx)W@ir zqE*#bXG)5=xiNgAkGO;U@=)?L6aaqR(}lBFosr?pyss>(o=)4&IoQ)Vt?qYd8QJGu z6A~=7QoMu=!>O{RmWv3kD^@>mS{Hfl4j*jM#Wh|)^%XYLI0fHZS_%m+Gx;ks{yklM zbU1gx>fqodjpuyy;4icnv}5)A&b*|(+n}=u;sZAu>dP>*r6omY4J{G-M*MByDU3L2 zX~EU*<+C(%Q5@XSjBg2(HmvHl7FdylT~4|>uCN}F05Z&H#YXe!VacXR_)tbE1#fmO zQe+arsptX87p9=>Llm2L_gc4NF{0{P(9{)Sy=3St&T?NzhL3P*tswtdnpR;-4oZQ0 z&XSTHVG_}WY&pMf4DZ)^6#YdlaI-L6swKD^7SSj;n$p5t-Y2j2eoOt|Mn@ezejOQ+ zym;#r$8CA`$IztQwED73VFrHN&j-9c^8uYqU?YEX+0mK_ECE>5c_`garo^dD~g2p%!k<=%Aa3r zivw0)Qo3PO{GGy&G{#qK^uXHeLtkQ&eas`W~CaRie!9elNh7rA77`)aOY*HW)I#VL(? zQy5ml-5nIpY}Bhux;Hkf?GaF(oa=pP+iqZ*P5abE_P}zq+)3))dizY4j0$ag178Hl+ykLoy3^8@CSo9|>8#+kg?f4&jv7jpay;5BriAvolzM4Tcpv~T)D-V_3qe#3 za86Lwgj?kAVjME!pLu>Tnv4+jy?ZyhB*T!1q)!(=XUCt12YuSq?C^9laJB+MTkY!xvDR; z_ov01ulj5-bZSC0w_(gzO5=Cde6Dz?+^yFG|9~a9j_xO(snLY{KgG4_#g%pdRv(cX zr(3aA`xbfMcYNx%z#3boEb}zA)zJsPDSlE^TF3hx^}M^5)YMY?(iHs)Y{>?;P35^| zQ=21{tm8ZsJyb$7|4`P3Yl?~qt-%5*JgL_4GD8<;;&klsmwH#_;u-*KQxJr(t zJ>mKU;YQeQwELqu*o=%*8y5S=VYyirsCT39@oBpz;gGp7xT}ZmcQSmBc}oFqE)=V3mvPQ}2?imw4%CDoqv$ zCUnx)AKmXdo~seqsrVr$xtwzgQNTqEbtw8`f@CU#2QxIH&pDDe7Dw_ko_gYR-_1YD zn3%3^l=rR+I2s_XH|I3knB3)`UXk>ay$HuxqCR&vycc<*Du^`>Fu?hV2Pg64ctc@A zw~Dq)z(v7(lBRuaNC#(bYKTk@IeF|^eI2MQHzpV6&&e}kL}>k}?iq?`=(vQcyO0sc zl9NJws9@5U*3K-O>b-Y=QKvlYFe-@Ufbgc3cTq%IJfTT55GhEq^;6@%5--9z%DpL9 z_blxF*s3Q_Ou0}^)hEY%!=BVvA_N9F=~FX;x;q5R9x44=H9H!URm+cKUUON}rKn2- zmB{e|d|Y5`@;#C@45_a-g~P;bF!xWPB}=o#T5oc#WBi5DfzG#1N|j3auV|K{^js7M z8XHjWI^5gWNYrWPW&DHq=LV<_pPtNq@#$PrN&d5eq`___By zcMZBvGy!d*^8EQnl(Vtr+|ACI<&m|FSsFXBB40?8M0C))ot(WxCXC5L#;$ns(Y`5O zf!ad}fw#R2Gqe1w%H!~q#!MU`e5r%ETSdIhPLaEq_9D_CBI2cLVO|~5-E`c!YwIUk zhq9A+LWU#`lv1z>2n&iDJmg8@+=61lw9|FOYgCeg=1>Kf-0geyuCe{ZUH_8c7OjI> z-4gu7?@s+m$w&`deXJ8avdk~Gnki zdPMTNnW+b`sD~Z}kK`Zq6R@%6~ zBknJMZ*t4h=&z)$csN|Hxc&tajSa{c%|UlONjG{O=rR05&gZuX+5UH`*_d~t3COlT zZy_EQA$iGo#9sQe4EHs6b^dLX@_|Ifr6- z(Ts=_tiaVFC*r7iQ{u>T+n;jX=!?VE{fjHcIG;Eti)FQER~aFA(be6P3xt54YY zVoY~%)HCI3|Da6f58(cyy{~=8_i@-Oaoc9JK`V{hNP2Ut#4j0fT)dluXgMNB4_w^} ztS<4#?T64F?zpq4lPTQ-mztbmxxG;A-)=U4aJox96bM^= zk2uUTTap7JyIqeV?+{(&?QgcZuMD%*o+QpnG~Y|=ywnT(xhJGMX~knE6aDR(*7Lyh z>P9{JC!>p@O!?#%kPH0NS*pn zta^8^tAR}x(kYnWzjxcxIyYrs&MS|{Dlzac%teCSqGB&DA1QNlt(BQoVo^fBnmR9X zE?Ub~5)`_(9Ow){qJF|lSJ&MSO?B!GdR~>IcBDsUB9=R@pzT_7%2ldDRz4WMFLab& zQDbzS4zK%w3RTUKr-=?;cZ>C#3|#4Ux?TT0BOCK*ZpA#pYtmuV;wo@sUY>r2nAQND zu#Lw#K#%pU>~;I~nVi~>Nam2o67O|so409&r!-a-wbCHM5stG0w1oQP)I+MtWdkHm zuHrgTY6(U}aVw{cn;CcgsoTo$+W_28siwgz!*LOMP}!B@cKlpT8=5>W8O{!?pRt%% zgXY1Sf^R%GBm+DSJ6W?wo7pxdF|CP=}EJ~5@QrTVL2|grOKH)DcZ-G{N;wNb{=6ThjzOvLtu6Ku6LK8-SSQFj%i8sK5RBok>T_`P zwHMSf7p&)I4_)p0XdK2;rQ2Xq!g$LQMecD|7QO7Kp2bY-*ve#^R<$=*CepAiHO_+O z(|003UeB!0R3)%{WsEn4E!9qChtcR3^8~Ohwg}0LdXM)+BF-8!-gtdrXdD$-YZTrg zc6%jHmnk^R20&C;n-h|&4z^T5Syx=Y-5gMs(ZD$%)WKI;Pqk00>jCO!*awifbi$ME z&J>p%kkI`ZS{EiisN9-T!^K9ve@t9}h>_B(Y{WFtAbU>%^Mon*kWQaN-EXsb1iodv zdpT%yy{`Suf5L2lV|0K8BCZHfXFRn40#6&@k=y}$kGjzE1L(Bd3=Opg|GtU;WS&qCz^1m zQS!^cp4qu;h)7{i!d_gX6dQ{54_5UvaQ>sk$lj0R29CVDASVw}yE4CQCa6Y1Bn>?N z-#_odui7EO!w({~>II!~5LG$5mI3!<1NPB?xrnhV3!W}AKqawp5+WibDJ<=74Imi@ zevdl=v^GhvM&B__K_68>1J5r)_iR81^b|Z!uHpb<0)&FIWdPwVS6<{20|J@!jmDf< zgcz{A0b;ap4&e(Bw#HE~dh(e6?n@A1l(?^TrWeHe*=Rlq$nbGN(>HBXH{qgW`nMf` z^shyf=n12OMyx?2A^5w8uk_mCp^dA5p7l zBot)3fy4t^dj9;70*0YOlM420KT{zZoPJ<~{6J(X0FWydS+}d&yYdZ&mYI%wrO6vj z{X}kAD`0li1SbVs1V0v%{+tAqkjw=<#H_!g;7gUP+o_rYT0MZOi|oEWJeVqm$a1Zm z|7(|u&<)fHSvDh_8GA0j_TvYuZqD7)a#adVqIJ{tgHF0*Yw&fV)MRQ| z0lkdrPLDh@x)|jzis39UME0E&~D3HY?bS8+K=3UhzcsDU+%wB{g$({}khh}d=x zIZ(uh0%Z%HsBs`*nSRtUc<7kiVrUsWqN2@EYeYkL6;jKvt82UpA*%Fknmun^0)U`a z_lglsY6Ns^T@fg;GwAc~jrf(G95L>x#Zz88H7}l1q5cLa*cc*1d`LlH!Nz`D(-gqj z=ZFT(RaWHx1&yfoj+&EU!U>2FHfE8gi=W^Kgk%+*7FdX<25%(hm{D6EF}h9Jkd+XZEjlC>B}b9IV@%KnE%o zh13&aa=W0FtdiE}Q5@d=fVD|)nL1tdE$x}pYvgQ8VwlinvKN2vjiq_T?_E^|-3#ls zp!6U_GS_=?z3nfLqw7kV3b??T+~?)`6UE}8{7Cbd1MctQp}D6iJG8GLF(b#2v-&T9 zbaLz@st1hg!;nbjpU>G$NBd3-_G8xH-U|;cdrGJ4sH6y2XF;xxWiRItaC~4359;~+ zfA`}R`q#N`@}ZjaFUrn2Fgr*E_Jw~TjVYZrJLo@KU3ng7An(|;qOR%iAW8PQ+C{Dn zZ6>`60=&mTB=0x-9gSgA@nyA|qo$_N?2DwHtT~AR#T%nNWsuK(=vp3_7*idGqydzx zWp#@=gv~r!#7+K-nxn4$^Dw>X`vnicMLb4}HIG?K*`){2Is3=+y=O7gvg=Da*7|0E z4xWHo2p>2Y-0#F~+Ak6%o=|3+);u^yElXKwF3(gsUZfH2z3_&ThwMh*i)=_Q=)vtb z*7X|V-2cx{wRcy+l7}lgKWnMWlP`GXNk*f~7k{1`+x6A8FEA0T2cB$DH-agavbRWU z(5(mh#O}r0EUk~(AtWi};NbQzLF1EU=$v?vLUQmtHcHVn=;oxiJS>p5EbW!F#2Y%8 zb8Wa94+9KuwG@8|GNarNnbV)5tlb)YCyH>EWY#y4Q>CRxj;;8+d!ztR9@$P0%^Y<4 zv|}zE_qx0~!x)cS_GuAB1l3fV z>tH_Ml+Oz_yLnA6U~)3qAu2`2x95%yF1w`V$vP(kQML5_rXnPV)0QFRR@7tIP-z64 z$gA_5qNrrYTR`Oh4RSU>=s_njB+Zi;upmBg_3$kv%S$6;@^W5HdzZ!A?Jl`Kf$DRp zr2R%0>|7{s-HS1?f}U)*7oOPFq33h^17RyavqV%3kkq(U_FIP%?rtaP96260fWOmQSs ztdq!thkK=55Y})iWO(5C_u6FS+|UyWjDt>pe|(Fza6OE2vdMD!K|7>OQQ>50-d^?CrUuI z>c&98xIEswP3bwH+i#X&`6PmAIlWnVGgm62FvJ_G7Y;o)1=A)wehw(Y3;+oL@GbC{ z#s9F=?D$?_{cf913S6^ovmD_c1Han_QqyIPiz z+|B>tQsPShY$kqglN%g-Ed`RI`L{2+VX+$=AN)4MPoNtekc0ZS6U)vATR_Ku)_%~M z(|_}RcTEA$L&?ade*@hpg{Q--=MnD8rMS>lAp)+XYG*Q z8}ZkX%F2Yx->BxVBwjyFC_bdbykaNZmS4N%YG4X%$(eR+>za3k$H-$Yv8t-diKXK^a}Ux%r8#W<{HpW~YR@eo zn)wE32|k8I1hss`GJ&SxmQO%QFcL@z{shv48bELGDbNx800{_=e1nAoRl_acz|(n1 z(-6oGc0mH0K-lojRiJ3-qt7^!3O;xd$Qt%QdWIf9WiA7G!!6E0)bKE*W(ZUeoxumU zxND2tJ_fE`{T8(cwEw?jC;H}Pa*Q*KLd0Ze(5HdMC>X;349XyGVz>(B;_Y3+A^?F> zFnIqN4p;xE>FMcu5!Y%~6?iN9e|{@mLX|Ak`^K}{vSsPof4eVbIxUgXTI;gXKhY{% zwyb3Rx3>O2H-Kfj^?$xahy0^}g7N$Pibi}{?=AcccJ^S6KPz>6qnne{3G4b`cw}^R z4iM+g7OwJm@O`H(^GpkFq-l8?rD?j~aP2RgL(2qz;gJ{D1RN(;yQ`1SCl=x9(Gt7H zmvmk8`d|z#>vPF_)E;*)27hJQ6}q;(x`1?O%SrBZca9H--s!`eA0b|QmT^u;C(Wkz zNeqy7PV!??W6Ir!`gqri-KNUDetdrBv+$$glh*`^*fORV#FB}YgM)cnd-dwo6}erK zzk{oKkpBka(p>m&r(MCs1HTFghtlVD^$=%gvJZmRfb6IbkP7wz%G7in37`u+jaJwa z90LSOvsG=08n|QFiIb{^e^!oEp%kr&L9me;|033%r$=Mu`{|q`MaQm1X)qeb8bem) zb|sz%6E$4t+B$Yt%X2hhO?_eLBCT}m=d-Q-F2)&pvM}s=P&IZVI5j=pEzwM5i|KoT zK(I8~8Yf>r^#&zczgG7#L|p#8S&_{${I|20^|0&1=^_DhLlwr1r^kUAl~_#hLf$&{kGI$ZX6c6z^45#*Q5RwV7*#j~T0~jV;H*X9J*>Ff7Uan#KC!eo-;WJ-7aPbmYjX3rBvv`uwjww{Pzh zQ!u*q*Wr6h6t9bW6))d8(y%jf=U@9#xBp1ra!~5lzwAN}C!E|_zdTUC{AmcqgVn8i zS5u~kDE$8WXq(3H@pAuoBtjJ zw^&FsYY|k7Bl#9>29r<$^*D&^+73f%c94>$eiaaGtD74-HT4z5;!ua6;`I>kBJ_ys zP=$Icqy%HvQ7z;SRbZ5-k~fb>UO+GDG(@AU3iMxcc580ba>zsAo;kDu^+;W6hY0-V zr6FR%HV#Bdun4%<{fl$ib=m0}Kv=ENPWQG-)nu%l?vtJ@xiZkKqq3Dx*OkU6ehu3t z@`W}3b@$w2wd$q~!(EH&{6cv*VPSv`Kf`<&s_o~WGJeZ^990qDI0>jBtgIldjDhb(-L>Ltpbu4>Jd93LDmY4B{<3{>W=LUR|e8OUO-f};J#NUkyh2#t++ap}KZfT|dKvd=* z%|A^8pQs8Dq7Bc{ol??=tujlY9z&mph%mynYR7gr5|6iBVHERTFSc3D0IRx@|NIFQ zAC3nyf@=}qU>$Z?z+F)bDUwuyy8&$VGPTA~^r0>qNCw)1W6)-N#&92Q0w@5oxNOUe z)vAn|e}A%;TUI1Xdgc!ZF8ygCT^J4!&ongInU zelqoF^RPtUd~QntNr;kNkh#0XLT54WlFa}RXY+aL7D)39Y=^F?2}*FluOHZS41&#P z?-NkQWitVjwi)?JciU_|2ztH&+Yg%b+e|kYZbpraG&f^7deC!r`c80(8YltMc4D(B z#s7!B_X=xr>)w9f^}3YhQbDl*((Kp(0V$y*x=>MRDgq)ULPTWIgh)+DmZBnE1f>%Z z1(6!6v_u6$Pee-SQAz?N5RyPb63U+O{eR#4?Q0+G(|xedyc7vM&zxh9ImWo}->)m7 z_OD9O4YH*F;w)(~xhMVlsH9)F!n9w!y%QebBRe$y|6f;9Li_*7+f{lZ!BR?;%bF4p zDR0rsD^({uHeiaY9B&*v!>3MPU9)S01 zW%b)fBiY=5*rih9t!(3$*NxSjCt0&?Cp!2Fr z{B<WN>B$VHA_DZBRR@58GOWsHjOqtL?Fhvn3i6Imj)L;|%v5x+C|9H!4MWwp2PBCNL zq9s;DF~QX^x04t`0I=QJPTXz7;k}xCD}x5i$^CQZYUis*p3%};^QDuWmt$Zy|F``i zb>3n%o!W5kI9=rnI#=S&B8j%#!5O8cbYnC0kOX^ z#+0@;Mhm|$z>NOKWyypHu%{#9v83#!cR!tBK$<%=k@ZTl+iv^{8Rb_n0L+G(iA2DK z7Xf_uo7(hhP+IfNU&L)m-D|Oan`Xms_^{cF(z`h42O+>Yss+2S2Xc8Lq z|MN8*I7V;fdK6nft7@oxG?|ACkv9xp9fAA?X<$e|uk7H5(rlrmBe#!T^dAi6 zuXte@Fbe$2&gKn+NClqnh@|NJD{x31G;GzSI`Oa%;|ojb{yyGn$yijX84qJF8bL!P z4i|KZ>r`ZL_}Vg+y|%#Z)Kncuf^OTd=Jx+AFs0xuQ{(p+7@q(FbPJ3KwDTZv{x|AD z{y=|L^lR`xK7k&LSpIIVsode;17UrcQy5?8*RaDqrhs3~#^UyXeMtVxVzQPDZHZS> z%=|;*Lj`SMO1w8l>ha~jvanzAt>YMk3?_S#NAxT#mj975zN4vUtU+UdU<%HXUnOx# zI8}NgInY*o1+B1k&X>}s=;K&B2(zf78Xd{|ksZ2)^0l<(m(@7sTumAe)XnK%{5U1M z#Xlq{^2HK~G#eWeZ1=0s{@;%^b8DJTy=oko>DDCC%69Po_o)GqNH%qT9cBNC(Ut+3 zf$@^R_<#8_&_NO3l>GG7zY71yASbgX7wXw6dZBWpvUuo*9?BGe)AxQG{B(=CSPzCdCl+mWOa9B`@mYHOdMc z;v~DUHkO22ojS-C#R491GV+u4{9ji90)AFzvV1i@5!EGDAqs2-Y^P9b=H-plkNSb7 zC9B5U2b@tB!?ZrsZ9xesJS1Zoz4IfoYw|$Qg)8+A9vdn1Y5XL;Nk4>)eHF2{DpE94 z2Yt=>1`kk0wtk;x4C<2D{!TEaC>Rs(^K*rPp%@az`*c%E^_Q&#JnJ+0zKMEu?R8nG z`7``b(z+sD6su5?P*)6SyWw=v;S4S;UnDs1v%V)@f1xW}nxQ0^jUZXqf1MTG>Ev?{ zU#N8}LQs|$jDZq(zFT%YxJmeC-h8O^1~Y94DX6dV8=zfJ^=Pd^^Js(xEJ z2VzE~oWu!aLedW@^Z3vpk9$_Sht@9mP0|v~LHEdo_dLiBpRM`XEOgX57KG z#E!p5Eh?3i#steT#VZ*p}TnyiM?n^?Hi^1wxd7)I;Lk zX)BVIvbdf6MfFM0GF_h-%6VPW;Lc_fmduF{IXh^JJCd}b4EbyGn&NUz#o^R|J{p}T z4FgVW>QGTn!opgE1W#MXiH%YmO@V$`6TK#Zs7%Yrex4kT}vc z)f1*(np+96AgA3hR@#udYR$8YGIB{`2A^G*K7t>Rso=eWH_zET zC56_}h?mvGd4F#OHf+t2cCWKaZOw?SzczweieHYTh#M%5nE*N5RDYd$(As8OvSdaAm)%E>gGd!1V!7$~*|mT{(vYmwNM$XD1&hZ{BC*wrKKJ5Dtv zxxOaw;rnv~;itvN>BPDq`j>@BhBh4@^7AQbUaw(ejSXMz2lfyXjUZF#7|lb)uw63^ zuY#!&=x_!9Ls9P^DqyY2=s5yl>9K_$hl|T=M30FcrBx%Kv+|0gki5hml;xZFn|br= z_+p7C7>aUG`gTi`3coDJ+Q^R-*Q_k6MLkG}!jUM6>owc_&32xO3%6~lzs0w2KO9EXc9|x0;eQX`{WJ7%p1`X>Dxlf))!>IPF-6#9vM0*gM*Po`kdDp87 zKDF++xOO_1Ago|9PU2R}Qg_>U!ts<&e7vDWhLwfxf1tg7Txz4vnhxQ`WAcgrMwU2@t=RK1j)_S$b?%mbd1n0R z3D`5-$0M3eaxam#gME@AATMGXsfMQ{kxLCgBg10|z`YT>h#!maNK~|0=|p=T@%ssx zA`&M~5!^n>tTQtq=Oeod!7RhiP>DTb$*Q72w90^Ck9QJI!#MVsY5Ql$MRR+OWCV!= zob-a*!cp*&d~$yV`UT#)Yd3t{(2X7Imxk^(g!6R)H1&Z@0IKi-*|@bFcM>)m(z15W z$b5D8lJYX7Ke7)T8NUX1U`|#K{@&5$dg#~-{i``g!E}+Te75!45j#1Z=-#Qt=4)p! zEEknJqd6^2jWGvPdRn>J-%0r)qFx-df#J7G@-v>^Sd+jgAFKvaoojkLtVga%m4r(! zv#X9imL@TULzmWE9QW`<&aBJaf96JwT&)KWt=&S?8w;4uV6x4abt=aP++X8PZCo-Y zzdpg;d)6Nz*?$U6gB2Y4cW}H1-kr1qk?L_*W^XOR=ghn{Jg7nI$-MS6_tk3y-D?{X zc*IYLBuy`N5aRx_ioPA{lg4+m8wkRr(Q4lQQl)a zb3*i5Lh?c=J$f&VIOL%Vp`xk20oT(HO^_FyZ88>V(Ml1)3L}L_q~`XI=R0|G?=!g` zSgsmYyKg>(o#bw8KKFWzN*JtNIbPsMyooaG;#M)Y$N2v!*<&)_?9enAi~C@8p;bbXO!&5T!%c z_~}G49bYRdMhrQIpU=>#t{56F4bB_8w-A9?QWJXdZ~Hf_?{WNEI#FMjjac@Z4}O(( z*N>-!z#`MY4IDkwOV03*u%??Va$e?JuTDXhJh8Z6JM)fQE8*iI>b%1eaiwtF^Q-an;*{@#`lxfRxl+6MKSMN4CZWN_YRKvqyGTf z(Vo5+N>GO_N|MdD^aUA7;Tw>7=QY2 zalGDk<>xhfF|xSSjq+IW@~2LKa1z1m3t(_w|*8jgYb{;B3GeIGLyAN`WaOYIpj9Wx62SvV^Sj{7Uv3 z%R|QJo`MhP8CrAq{;4?S+~RVYqV6)TdC;qCa2MovL21c!NzG6S60OT5Py_Xhl)@^98rVqmpyNbGv6b=o~Dz>MRcJQx3-4)m^%i46j8taYM--?rK`T>p8CiuSMx*sxkT_UT$ zW?KmVUOFCVG%zvaRf5Bto4ogR9uYsV=9Et0VyS7(W2)k+IY%&eP@1oEK0AR5tk2dcf!x%uMg9E#*LIvrB!A4<^6I1O*kSV*9a7r1y7j z_RY!0%e?y7g7LztSKf@1gEd7qOVA-t&XoaCobJH1{{i;~x~0WbokPCPUi0tXeQM5z zAufUGwKvZ^E03|6|B8${F*s%G!;qYq3Wq1GHN*!+=Z7nyj|)IFQPHx|G;_s1w?N;esjy=D27V(cIC%_rHZHa926J zepvPBEycezS`1Ve?9NS{yY8(&F`!wmLloQOrUdDluWIpb_Yf7r!<=C44Q*zs@MM(! z)Vz?gTF|T(FhB4<`e%!#4R2Ex6+E7~bg2mliFbabb|SdeM`(LgyuL^g-XOoqB#3|5 zqpVt^YbJ7ibjBa}W!tZP5%Y?!qB#H(ZHR1m*-*3kaX zp4*OXqvT|X<9x=K4nH^6n_%i4X0DDKk%@#83mrETn(O9jLWYEw)sMS!L(W_GS@gj%#GA^ zA@KHt^$vadLDv$>-~i1Q}B^MmiZ)JOZ5S>R53F!+dvlF`?F&G9SPJIpxO9vuW_ z566#7REQW1U%Qm3Np*>}9meY^uj%n$bT8JBAg!l{GlSar;M`Q5kFx~Z&pW$1T{mdh zKl?Bu1DYZ%;BJ}J>O#7!qI|}*$P9-))wi&`)192*_Eejio`eQ#pEyhH z@!Awtp}g~*zl&2v4_G1bEY-Ch)g6Hu!arFr!fXe11xbP*nc%Fnt+|TcBPjBnzSv*v zG{UW_(7Tiqx)_&f?zn{MHu4b1ne*1u6?&Y=(7S}|&8FX7q z@2+LLHbU*B8!Ci!CK zkn+Za95I9)%vA#Y{UMEmub0Q0ua6TC9pe+45kt&lLKFW;{t1`F+#Ahw`kVF>p(Ke* za9W@bbtxM&sgFUhgOPxVG4~ESFb{bl44fEd)ql+^^KsBQ;*r5mbSkgjTTXT6r+COs z9o@@u=l|{RRB3?U=a>ZP^!^YuJ7!2m^$C)gwn{ZIG%+xd3@bCoA8rpXoMchEUY{7= zso1LLzWw{9rFM>dvdNw*d!HN1@BHS1hl@t*G9RxipxX99T!{T-op^kVjW|qm@^)za z)K_OC)IXmHp{?0RA$d7jH)M+z#y*BPllRuV_vR080CR2#^7}24lY=+Elpr|mD z43EB=ep`NE6#dKqtebKt~0!YLw& z;X8`hOP|DE%C#KLaaM~Y51eFOA}CJEuZIm>F6$lgAalq~@pmzMGv-wQ%iKKnjdH8m zkA&{?*hMA&=+?@AQSUY_SufAhvJ;3eQJKyCV0iqV|SF8QQdGAY5`~x%RD1cdpuX{ zp0CWv7nGFsmX!Lq%QOcL%GqSa3zX13F)n9Ei5}zbq@W`h!LJ2M=D-9c28RKKtKp&0R1<0rehu#M5k1a!7E! zyw|Kv^GLot?OACOyNo3DGUcHPcox!X`w~Zj&;gcz;<}cn?xIayeYcyuM;ge`x|S;h z59uLMipDXkR|xoQM%()Qsy_7D#5!-scOT>}!^qkjb0)~i!HQ@SJhZdIP)2<{HhxtR(LHfxdQ)S*3Q@+wgbJ z$GK5%#|ZV1xa{t#uES&(!^zNvp^AS@$`&rTXnXwx_EfvNRHid>hcX;8GyV406DC5d zEH_@Oy=bb$T<|Y42&E1L0?Qziyod2!x*n95M*1qV`jc91G-e9-q(VfjYjhAP-m|bh z?SAWUk=}F&HQvO6aFwXXKR%q{ADdmP3ao5VaV|;hk1>LZOR^*_y|423#vXgzQRABU zAvR?cZOAtnk6dST4@NHeu`h4D-jqanurY-ES|5}!B)%54o)&&HR^I{l!=#;2rVbd= zoQvX{swJ&??&0yq@0c7-uDaV~_<+Ejc$^N#F9+T~W)Bz6bE`fIWz6k4P=^5e@RBuGSR5MjdHltX*g2xe8 zU2kPLnv-3njZr@1q4d9J{a97Z3Mz{)VPWi#Vb){$w|i*i9@b}R&C2ATkXZ4Mjr|yt zx^M-TEq0EvbTghT9qv7`{t=~(8`r`AwxGWL_W<&)rsmTz+n1*@xb2gZ(I*i3o)sj` zKr?e&Crv1V&a6M?IB!zkPuev9mpFQ%(4?TZ%Rfy-XiA+^$_H3#_du0!^9?8dQxe`4 zeQ-H-@Y={ORWj%4|5@;7rIXJiUhGbc&>e_|o#F3jML~%YigI*d{`#|xq=t)hpA3Ng zbL2+09G}=hdt{?@N^Mp|-%pOymn@Eh?W?D?gk0nSWY2sLg4oM?@47>MBNgXLc(2r~ zfu^jK0c~@dz?U3nXv6h+{uyV>h^`WG)#fz4c(~;vj~!3_>LpA2TM1@11>@PK9~uWRq8!AtwPfH$8tK^j`Vh1Z? z&(ER%-mV>wj~p(l&LD!AhwzqJrf?ujrmbG}qS(o09&1-gBe>H%D?wake6ud!up8)d z--zRcznia5h((aj@UQ!}$={>wM1a!ee$|l|{!O>$#RVh{zKez?Z!0$|Dsasap7-cp z_-~D-3x7K>?x3d5PG5Ak?%Cqhi|R6Jud;KtNv!v$5njDw@9%6JQZpA{QxkXFI1fNp zLOKI8!msC{_k^nlD(-L~L?*a(nU9f5rcsAG{MPAy(zIjw2Nh9$#OeYA63QXJ_x_}) z;j7$t%@rGN$1t_}1KHmgl%Kn(34D1}j6eK`$NiY-@W4Uu^?c$_SPR`uvj_KDEV}`r z@ytiR#8*(`T}y?3B2&LZR*pMR)E2&#<`cdsp-3t-y&xB|jEOaQ2oo{-)*B;ts780o zD&Dhh1y=o`5yX>>tg1(yA9B%x=x&bh3bqg(fbrqKy_+kJc|Lv|kQHTEm zSqWb-VY&~V2#Qaz+=gHd6gwA^{XYV*?K8qr{TG2RYzWs#A%t(B38fROKU5Kyr=fRt zoDEtbAi+UNdV$_AoqHk8-2sW{hwHN;erYdE0;i%d^Hhw_@pjt;Vph6Ikq*p1R?C^C zA;;sU5Yfk1}V|;=r-DJE_+=D8Vqh7ZQr&8A1)zZy1E(K&xV8-%= zj-rGRIQre`))VU*;-(pFJauCV{c__4aj;ZIs+KT8aT>TDaxwA$&WlEK}k zTGT;QO3m#7NLT%}QtxBo=Mp27;5xN^Yj>ok4-UO#J#x1y#NV*8(eNR%ai^I|J;(br zjq-h|o=3-B=k$<6aoairjWCfto`d@!7lL{)43bOrH)B~U9cJNdgsklDe1&}|O$AV` zX-?f+A7E4%qWvEEZClkTFGu_E!-xhA3)J0;WxuxiV+)JY%CP>tij9-Bw8kLmwMUIX zN+@+4O!78I-&ykYpZ3~H)q0Qo6b$OKjk~EWDS@EmV~)yH6#GemCVFcUfJ)se zb?%Wy_@(?*YYx`lg0Fe_oBSyRZ&|9c7-^iHugT_%4-K~;|KgE`w zZ{0K|{~Z?*ZfguPYO+S|AkZ?|1$Zg%SGSTIwW0UrR-pnGx}y$_4UD$|(iwa?@iC@F z1}>)}`G~+5__^3jge_aa7*KQ!8>s;kN2Whu^U>u0^bIKT9>U!=!W@=X zr)naCzB>)R6>^NHmwA}R&%6yj@<|610>$jzXji&T0Lm^G2onOb8%$cQ!>Xg84Ci;m zZ^9@Nt)rD(Ysh)L5yF1W2_04>}mzacbXfG0SJe2vDzLKs^bk${m@rNc6bj zhoo!b&H@I495rKiMyR#h9pO=}V&l8~cds|uNQqP&U%U)OO0C5&0!1X`uI66+d#4B? z7IV)U%CVlW&wqM7fo!TX<|niIf^eFcugUCn^U%UE zUYQQl30#~1q_)yRuj(#?3-*XkySVewgX1er*_%VX7)9Oopf+MQ; zq5tkaKpP#BS$DT06hDQ^o_9TD&j>>ba=Kjf7fgV;PHUxF zEsXLes|X~p*Q6Xa+U&}OOi?}mOI~Qos$O6xV*>OCU>2d9K`}mMLYgP`rNDD^j z{uEdLTB(RRHS(34P;wX^*hi~?17RfR?o~#av?&~Lh{rXOlngV((e@2)Wi@oWbJ*B! z%DRuu+KE=Cd6dy=Mk74}Pery?03xeK4xATSP7YOGJ-24D(U)Ir(_S;YWEt+WP&a1z zwbUL)s#qx`*%DGiEga;S!WDOPfAUHp5^c+L81ziPz&e}Jk=@(CRTe_3kI_DQ6at$% zt;DPf=##A8(t#FgKg0@HS40rrCzSA>b}4FE^)v}@kj9%&i;@Kf9_0Ty=8xzjwu9kX z%g=)Gy;+Bm*L2{1Ct=AbI(1b-c)Io$`Fu^8Qi|W#%qgTlK1IiN+89M{(04}#{-U5Q zau{a-9Z}N(%KO-OxAm^I12U#rebtGXzZa^%=JEH~@^#6DYxN()3TS9({6Ol|mT6{x zM(EopkG?bz#cob%RN0`Y+_7%R?oIdM0r)hrN9pE^MHx5@&iGEi2dSTD02eXV<3_Xi z>}I{wDDSB57Bl+ysK{d6tw1(cdcktxudMVNE$ebII_r36uCG54#5^^H` zW_wL7btst8X235`Y4nzFWznW?h5lQTcG9ZeSG~h3Rut_`!V13t#?yIbTW|xTXotMl zJpC_4qty{1iT2cu=VTLJrdHyq#E|<2d8@WcV*PIet{*>sC53 zp8B*HWY%r^)JjuI8Qj-ljM+PoX(*$Z_Q@31o9`K87Pox#>|N;1Ra>D?Pz=;~y7XjE z5igF*Q7N*KM-6%EsRs?K*o68bQnbw&I}`4~rqGJb5Fv(MwJ2U`Wb%DLY3Cz3N2PKW z%&I6 z+{7H+3#nqI936ONnrz*tLSIOH8S1`ZZS^wTeBtw`7vzf%Ycn3?&yssj4y|mBm6l1u zAigClCn5r*eL`TU=LPsa6bD1U|F?}{>-pC29D)Y_t}89Bb9h$<=*Q3(f@@B&b|tO* z6sH&>-5hG*hV!V5lF5v_g{!2z^FZnd5iHtVot3e8>vbv62_PT5p)7uVbYesF?m%a<;u9 z=V)F4c02pP=9{$^4s=z6SMlb0S7`j;J}9LA5Ciuq!tSN+fLUCX#^3#4*qg1HHpM-%e+l^Fg#N?h)6Pw9IY08rw#3BX^hcq!Mh<_^v#-Y4S}cH zc$OyQ__|4Hr)Y{uqsI50Hqai!lqqRe&sS2#e_^p zH?`I8Y$}fw#l2(>(mFElLrj@JrfMq>>xGYvYnuH}wasp!b-#SKk^St|`gs?eGAIuScsLO**DVE zT34J6mQNv0zjoyFVfMtK$T4Dz#?Z*;FzGe(a4#y~qMgvj^d=p97(W_;($l=vzV3Ji zn;?DI+Et^$B%@mI9xNnMRZ>M?6OixzDqf&1sbBz zijbl2j0)rP5os)$m_%zkS`57mMc$N91v?I;kGQeANNB`hCYj=b) zV*}icT@><-^bE*VD{s9w(fqRDz<9*46;!hRtBja@0QmD4T4{{b3hRjs z#eccqUIxDeP74lE$t)|vF+Kcw%Tb~9`-ZfJICjW4lhvEVfG2JN7g1A_oiXi^cby~s zEK?En(UvnxQHbu@URv`bH)q=7o&;{>3Vo=wBm83%WIj=O7wr_coc=RZCGbPpVVtMR zS%?&;2~ z1XF3s{+Obw;df+Lm{xp&&~JVG zyqgWaQi$f?&&z$DGwrqv=Rc?CY>>0C;YuJ!2$QTuzeS~YGBaj9R@39GWpefYrr1u> z8K&BR=iA6fYb!1wciwSP#bN`~d{{+`rS55cnQt+4cY~a5j^0ECz)xeQ#^4D;`)Fgz z{UZT8S>^2CPX#0`Z8nsGH|aMF;ERw3c8wq5VFMr8OI!2|pdFIQyd2;8z$P>NYb)?C zjN6+nhljV;Hxm?%~dP=i*qsnX9XLlFL29F*Bab+4xs{oNX@9V`fEGoW3X|rhK^kBJ(L~tL%jf z=L1NWw_GfLd3Dc*a>eV!BU`Rr+xhB<+_m4@-^w02{-^BHTiHE?<%j(qX#gqAN*mMh z2qrJ^ZU#Cp1bF1-H;woaaSPd!A+_cB%MoA-abp&}fW)1e1$s&|2CxUQU`XT)?<$TS zGEW9$ziKVntAKZXivMIuGWmO&LI5sOofSasfeXTlf%}^Sw@kcHPeH8#V<{Th1125{ zNQhJk`>EpI<|R2kW&l?6l*h%AZk zQWdu%waBTq+|k7vD!eP42h%{Pnl5`spQ=!{M4*?#Bm$GMhgdNX+}tdI0e2Oz=}Dk` z&=jn+XkvQS)I$e>2O7PRVEB3+$Wu=efoWLK7^-2`(l1@0BA{Whwd(*s^_QRq$R5L| zMUx3I!T_rBw_%g;Suj(szAOfy>57bOpij5~J>va4yNj*pQ+eHk*R9Xa1jZsqeX9EH zkmDP#9eqzsU#OP`Bj09MA<996u1J^2ZI*<~z}L&HRtEc0N@Nr|2xcaYKyS;wmIA(^ z!@AXN_gA)m6E`-1sDdn+NdKO<&?p!u+gO{}&TRm7;)N>`);RvCS4r)?d6b53nRDMR z{)1HLnXTZ_u#+3sCsj9&3-5NN?g1lmN(;P;=dneI%H(S5DwYL+f<&Qk&QXsVrl z64|HcMl53K1PM&8{QxDR*?2^XQ^1v3HgKk)b;wr(O=pT03s~OGH7pnV6)#&^a)8vM zk+;Ui5|7M1H~y(6abI(fm8>xH+lV;b{U|y>kTczEFu*=1cwIy#zJAzu-E6O;5KP$D z43_NB8+W*?~5#tf%9;dH_pOHp5f&wD-hF+x% zHv|Z^Qt(nnR%0xn+sXpJNU5z}l>eFVXNK=fd;C)NOP+5%`%ywW>PLd*DWI6~3Z=$q z)O`?-M5$%p8V6S)nbJU+l4+IEZ3DNxic7llVck+bM($R)e}KnOvC{@nu70#r!2rZ} zG84GJ`2}H7U{k^F89nS=b+sq&fyWh%Ms_Wlhq~Sl#Kz#E2{cfM7?{1S!N-P-j0c^-4?A z{dxF)63*!lFkX4Fz=jmJ2v%@iHC>Er9A~PR+-I@hfWmU6_#0yf}UiEjV-Yob@-8uCV zi1J=qv_J@m>DMabB@#G0%)Z@$@%kSWad%xVja(JGkuN}sfxQnR1NJlin5wb<@>v=$ z3QT@43QFr2>b~1YMab^HD}5PzbVvF~!bju_`)up4R=ea5Z@Gld5RCv!Jafav&zsCu z74GVUU>D33Zg#4!#6fmN38Cy(KieIVq1yOZ!{%k{tfY`*Q6BLX^m z`a60)3!`i#>nPpG|6QW;<930qSl|VV%8@NRc#N<-;22yz=oT|9#7;!1U8Nm)X8PBu zL(iUIzYId)=tg_S8)-M%^NpXm+oPjo#aG5|#P`jE*y1wx+CM4mJw|`Ty8^;KuZR*( zru<;$nmz@m(t?HtP!unv3)QLjtBN9OF^xg`+g9RxKlS-EqaJen=7oV@CV zPu0yj9BAQuuAhi2%^rDf7+LvSp!6?YhY_e}uMP-L>ox z*4e{U^FA%up)KUb=M~jk1LJ#A?`1`pD8;%C(t)*D z!C>oo)XonwVA)J8Q{iw~Ubtw#SX#d6@}!GQduq%2zhs$GGn0eHZs~)#=5JC%Zma|T zO5=(6v?p;B&NH3KGHZrAVWu_*_OD!df0{)}UB);L~o-<^(`ZDWNc16ddR(5gB z7M>1pz_E<_VGEWhIChJ3wk94^Xk}i^LU?L-8%oW;fLg+TEu5Aayv>rQ_u+6! zx}p)D-mG$RA%bY&D{qbuojEh8#{GONnrL|ZS!~uFp9Pg?Cr_Ap6W1=V%AEm@7S&r=Zu>pn6flEl_=NY1Ee&vaQprnOAbj zoGnWVXQjsvGfrKHuQV0yCJ$?@`ns()>u{EPqztIB&4v^HpEEgN9RxY3JtKW?P=TWf zywsW9$$OFVd>b?XVw@6urFtZMAM(IC%dYuqT1izHS*CN4P3RsOxCm8jwl) zcI$ZWd9UtTIkvUiI)yS@Ljz}A)36SZQ`-k13|!p`ktW%z_y^T*lA=0bdDY{aCmec!IY zh%AQjPPEFf)%Xdv!F|e6enLgAJa6XI=%)JfPB_7Y#m70P(~SIUHA2Cl%(^=M@k2Wspx2kB_xpkJakvki~GSFtn#pNn(@$4TQTRGmR9u=a@eq@>J5?XT} z6{xKepg9m{qtUQU{MRSBx*hIKLywy4zr`DDi>cZatN%`KKEj4^E8U`kd>&RrHo6?) zwzM*_F(SX>@K2=;+gx_a+9}KZPB)}{HM$h zDJz9w{kg6}Nm8V1=s?nMXqf0BnrO(|pB+UrTU8_`Twux55^66FY~Rk^S{BoFqD*jK zzCmWv02$qNum`jF{)+MLjjWAU^kd}j$6C(LDgoEI6mydw+pbH+j`jT(MIakoqUA_` z&>4?wzID;$t}j0M8smlD8}h+JmT$>;14Ai{8v7sO=P)ytuJEAyc;Yhbh?_iQ^6~QJ zE(S+yF@{5l(sVCfK60HAvWb2tv+)c1^zvoa9FTmSV4I5XTJ95lt|2S~s8DKQjt}ra zRyf*kQhzt6EIT#$sAluj9}Y#}Hizb7Z9E`qo5f~-)qGy)fqiqSm7!KZQ$h~l<=vDXaocL* zLR7XIH8swP2h~Y`vbIGLo|zO3k7q)x#Xr&pj}0pdf8OqRW%va{5fmr507}B21tYBX zHzgCfzh|4RMyxo4GZ9zkKDHV9r_WxowXollJ$QK`A}`kEYx=G6-Que%H|(ckkX2BZe2Hl5X;)1+;GCvD&rYj|K+g8PoWKKBZ8 z$OnDSWtm<`zmSCh?o4!Mv(BRbm6Z=G!$sSoh>;r?PN$@9Lto80USZ-^RALXIT@!GnbmWd=uI#6(WX&iwKc96xg2qhjpHkyg zXR3Fm=gsU`+9m6?ZeSl*-kJ7yv(ymHS}`leHBfq>iDNv0g5+;j&0HssCWRcDHV;3l zCl`KCV+-)1GvSc$+jjv1eQIIix6=+ZvwF8~oxsaZ5qshyR(F*in2uE#mclYN5H@W( zm<)!U`u4#14P47Nh&(dD*X*I;cpM+cK69q~D4|LIlEr~ZdFppf{O-XZ?+avKMZr*i z)Wx3Go8T zpfAIBIz^h~Y%f!5&I_pCp1zg;r2NWgEH>d@$NCm-Hw_PKz8+PW`scds+`exSpW^GfG27;9$Sc;hJ1K{*%b^n@v<&LB-M?UMN}3I# z6sB1`y&N+BY#PW02y~>w#S^@Pt4bj1?Z?GKyJ@q%OT;dtGTkMnf45ZOU6-rl zVQaSIo5kla2)VMfN(6e5720Hf^tyhm>7WzoAbOx-x9AT(*sSGmEI7a6dt;-D{C^tG zCF6hVjudOjHIb6a68jDUJk_IQlg7bdG|XF`|2jeausi)jKr@z>LcCm^EN9u=7vf{cEejRC{%FE|ax!q?pY-H}=m_@`s?c21B@B81O zP+KEw6Y(E;2!8Feq0hkAitOWyYx)GUG^F$5iSpN5R1;8(YCj^&vmc|5*mWCcE$vYuIQI|mFNWIOi$Z>Tb{x5Gk(Q74^ctN6 zo&)pHNWqj!f9O5B^QRk5l!{Fp0Wqq=rxYlg=?O!3sC|A7WLjUD+D9}9JPubUIXRrr*D+WS2k|@Vb zGf+IiOikNnBk1}mo8;!wMfh{>sk|bxW+ntO0%g7^;C=esJaF7=z~m{0nSH}P`7krQ zz>zMywC#;m*|sHfI@CDnrbm`0zN6BSeyGvV><;FtMS{?BBB|)$J4^RQEnfFW@_7di zq1p0;>O*5${}8Ul=vh=nnRS$>B)tr~6Y(+V39PqdM)jYp1QQDdQv5actg1r9^BiOX zaGWR;D@|yPMj*d#@-bofEXBW{X&lX6xHYVpu#k_u!~0GgiXa(Wg8x`s(V?AxKc@4n zCrCT~B13IG#>cO-0T8L z#@xP)}G6?3osv>=)7hZs~qbZNTL1NoG5Q}rP6WY#;E?}X7;7GXnaqz z)9`acGjR@%v|%CsD)-f8x0>`4!rQ${y;b##71CsS&!^X@2b!NLaqQFz;cO>x70>1D z{ny&r$u0cN&mSSzX7h35;Z}r*0d~fvwTIFo-=+JavnRs$qpTEuB;6Z-WRlBvO_~9S zE2Cqz`!?18LyT6H$G)nLQvYn-8u`|#oUj?55q!t$tC6c8r{!`puE3sk&)bDPWM8>^ z725H;Q5>zcD%SPgOwUR{?9W(6-_fl&EyRJzKcT1iudq$o`-knw7h@Al`j71Jh z4+o}yRJa8f7?Iu;ZT!?H?IhXHZQtSHv_#%f5Ybg|+z6a)+m^`%BH>@Lp`*DU&vUIt zH{t%T_TD?HsqJkSjoU3)L3Aq}tXL2MkrGO7by5A|M2aKmZjLqy!a|8X_W1 zdhbD`DJ7wIh!7z35CTak31`ON-rw2Z*!%o*$GGF%amR;aEEi#Atu@;_=X~Gic^~z? z%P(Uh+;|7|lopD*n$^;M)A9R!=K@PEiN2W@?%rm5xCG;qPETqzD7gF7OGB+_!D3K3 z9dSeW7I{Bd%SYpD6AstxRX_jpR381L(2j|)FlIkH;%DV! zwKKSLxWkOEb`oA%VS7!C8&-!;T~$E*mIEKm;pAl(2wA2!ORVJ;LU)$pJ z+|#A^1&Yx8gEsr>rI#WLto+)&i$Zl#?E0mpIm4-{gEHJd#MYQ$6Dq_j6YKSB&-!=u zo$}w;+HwHFYg!n>n}Dd@?#91dt6cPkrdUw=wB(Xl8TUfG?*k0qLk#1F`Mq$HLA~*( zoKd=gmvlZQbZKzErw+zYBBLv7mmNBC^?s35XBqBCi!X_B5Uwo}zQ)CpBp1DLf8|4; zFecnh7F~ArR-Z~(NkbuzAq1LFthQBdM~F2CDetWE#n;do_Q<<6&uQTbwV_g=%2Rt z)Ii!s65fD!aKCdUS~SToExR7w?j^_7;D3NT?sNMH4}P`B)tqcTTEuvXPN}YNR>y2t zX%=|Zd!=%UHN7XFSFkBYyvvmt05wdY>mAz)+vZv0T-g6$L25Nf?OWRSGJVVY`b;@i z9QFL1pLamxBOC1#bR-||#~k-WOKA(NXL;7a#?*V}OiV$Dm6;k+dQ#i_-I4sGo4+N7 zVlVAQw3l{eu7Jq(><7l=$djhginiDX1NxfZ=(kJP6j&cAJ}ZIL1oB&xQ(qb1O|>y4 zbz-rofCPnBxnF~?mh$bcjjMz8B^@Di(^btp!~W(k>IclV)J`P|wx7@M8{RX0HGi!? z;8JCn{?!_i*cxLclNm-0r6w=$TXMveY2q$hreN`xu}Rjpr1<0 zh+RRTy5_Yq7b7u$L`k#HKGa*g7x0~z&LfQR6EO;S&uFcDyHt3i|J0y7J>-JK>g=Wk zq5tVt9Bo%@VWWgW4fBzawH$F5LEx?0$!;l06 zMBfO+d*{0OA@jku^YcC+^K>IJOq=}ml#R5bXPYBF39lURmH%5>n7UThOSLpIHo$+N zrA2MY>B`iopbPaVV(Qwa*3?G}f?{ZSA|>=8j&DoJP3Px84~_Axx^6g`SRN0o82%>6 zv5si5I7MXEQI3smm#~VWi7kaMy{0x%_pJHae2LtoOUyZ*E@Zx)fKK+9PxUaRogSwv zjvqRMKp}2eC^74!{&>C#Ryzx!p82t$Ncx1&m?gYPT^6Slq`7;!`Dw*IN=(8vbirrpDI+ zclMM6wsqfhQ0qaeihX>mTKo3oh~EblCv}=}nf|Mo)lTn#<`DN(T#Vu4SG*hQ7ozv7 zW-=<2AGmyD=_${AhI*n~;}KJPsalVY)AVe9WbvQSixW8EeO!N~r`v&^N4BtIPcXWX z@wgP>Zs@Ffd`X+Pz^y)Xo&tuhYY{t_4=<8RSK-Q64`kQ64hPDI-tW)9NMp4F`Ja7Q zkRs%vNL>z}u`TADpU8*`S<-0X+R9M9LU2Rr%+T)FuRFZ*{X2nh(@HBDNbt6?*@ybo8#~f z+^j4SGwlL5j{e}^ZaMzFvEBom4lQpTQq z%Vv;DY^tZa!Sj;jm>4rF;aObao4G5GUU}82#aO#Xpqf(7+v^Vpu2Wv39@e0G*>b!s zg60`2y^Q>tz>0^gLyQMGw~^9U4$5dAv#w{vs~?7OLRKHqma#uYhXaS-J@ z#l^x8+lakc$FKiTzIC_z;A`BE)mGV$4#sgYe-JVj`({rPXCI7eJ$eU~cDuQ(5j)xX z+wzBU5mt=6Z`8hZ2^JK-dBRG0hONp!E3$g&REjf?lcs>8J;EN-e{}IJOWgA)?5o;z zd@?#EKL|=Yy3z%;uk5%ULrSJ~@CUch7+L%D!pg$mIv~H_n|TchZLMuTrfr zfg86xghH4|HW@ zy$j7;v>+&3S>eQ@F7CM);>MYlQP)(0CVjgt*c8374~V+H=`bn>_nsUw zrOGy~?bGb_X_vN#*L~d#f<5z#kd6Y?dYSkGB=@m3u?{ZTZ=H_RKS4U+{M6?=vZ(-; z@52^#4p+Wp*aFjDj8{w2-sj2Vu>Ds6gwzRL5?m^dMeg0s{*AWdfNT?UuI^IU^EoP% zDqh}{hY%b80BpKXtiN&-$8FerKqY)@|5nT$%ewcgO9Qsyl=?wzN&Ph{{4^|GXe${BbeJS%vx4f+(GeUDf_PAN0{bHsVg- zZV8w7Pyt5REBPGdoW$$z)aX!^lTPCWiBkC+t;j+<#f3<9a$Kbwp&RL`)`MC)H@N4a zZX(cq{+Vj&F#C?YSDAKlPD%?Jal})*d9xyJD~mfEb`3hIl32ZAHTX(dQ!VfEp8Vsj zftmRe_rD8VGdG_$8C2oLYLh`$t35YAEnMKbmYgR2!1dao|D$VzY9%(E8+_#7e4|bL z>2?ibcb)G)y4R}&r|drCmG4r6_IhV>xA!h%Fme>$2|zO!KI}D5WqF{xrRXw%Gj;BV zzPxlbtoceG$`CgZq{I);<1@UnaXT-{s zF{>wGR}4*eZt$&YJbY5*OW2_^b^RJQOs9tH!uSNYUJca6v-VcGu0G12WxuGhrSFGt zeJ%5AH6XvDzKq%P5C+SVjw(MIHonKeD;Ah#eh2IB08h#-c`S96#?l{^gvaYvY=u4l zD=6~LZAPR^M;$}rcncp6e4ylp1h>9aZh9majelEmi=nc=QxB}YGt7Gt`n&0-1&5>6 zp~9~`hvp~m>2t%|ilA1X@kb*+WAU}#uHE9~;~~M_Kt*}*sd7;8#n;MB-weQ3ASDdk z4*)eriY&=r7av6IG22GGJ$3GbLNfU3HI6sw%K!N*M&zHuI;g+|O2DLQUNwC%^YbXB zt^{=USPEJp?1PRH89m#SrfP54#M6@PVSUtOCFqdOO+QVMP^1e zQJi;H1 zvE9(@qf}yloGlt?19IZtet|{JXEQG*=1Lg+TQQV4d4>xPQ(y91O|u)37o~B`aXgSW z>t-#~AJm^u@EUZ$Sb7blY+~fYTB*>8``w-)ti)=8to%lykt&WlO6Yo)=?j{2dJ|Z2 z;%FRz#cZL;Rc*@xjk^!dgLc|uQ`CRNCgCaG?Z?UJs1+c+@}9_vQQ|Yw63q_G&23Zp zR(2@?bthf%k#%CVNfv1Tlex}Y_^Vx2%<<3^lyQ#50BeB*o`5xP=T*JM){Fh@!pTmz zEX-0Pv9E9<_!WpAPJF$7YmMF5DC}x6c>5yHGP7ASH%e6mz&|j7ys#&=1TiqPT{ypV zaHgyO(WYh@1-B7Wt)aa)NYu+@ri)wT@g+v-%8Wr1B2hFzo?x}NUH-?Z*U;c@xCP?s zR8BXqa|kqB2Xv|biv7F_q&(y#oWcMYL&}D*+tDeJ*Sy=-8(k_FdIugv>NXQ&hvb6P zC*E9D1~7ur8wCGNYE$S3cks*k`IA%I#1*`qow5*TXrOS>KA%Npkrq1i5hU?;1c<}7 zeS&Fz06ny@0mQCN=LuJN)$XwMHbZ1NK{~0)-ScBd7Jn#xDC;VC*wWmeM}TdFZO#L@ zO|@#g3Dc$kXlT8!S_G@U(Dj6pXCE%F-NrssJJ`Jdq!bO=xT!cNuerl&I~9m1+G1JF ztuM;lJ_8{3Zj3rQ_=lO`AQ#mTUo;3lP-%&lrpyC4z~lx=dxs~FAb)-COcyh}zGw`% zKhFCl;6(EX-A8??-=1-cnXIp*Z< zZUi0=gG65#0A!(Ia{X5`uUZCq0U0CysO6K1GP@I?wS~|?8`%M$xooxE2Yeapk@`TJ z=MxO%-^8C?Ko?%UHgyFIzOwm(mS&UNBY`GC0HabFwH6Ccgf17F2DTO&XPL+@tIa+J zqcXZ`c_hemJkBZS%%pFRk?}sy5xfe;qB)dmlLXgDLcHN#KT`qAQ;d@T%8W+kZdbS6 zVlgNpKtAcZ>lh>D4;4f58@J0MDy)nO{Y)Ot)@r7!d*O5*E`+>{LiIH~XNzwHE}mHx z^t4hwXWvWZp%xptR<=zdmxC~QqPL9{`!@yGVpavhL`-?IY?^_BGB*28#bUo!>g%A-5I{u6=vHpSy@bJAI&;ZlYXBe=q$1Z^F^q(#* zFq!?&mpHz?|3?+^8t+D_W_anTvsUne@Pv**=7-?miv$2pAeJwE+oJ;Daue@5pou^w z?1B{rwfrLz|1P*y0L(fz`LUmY4R<~3fd*-qbNahEHoJ4+0N-2LTBWZhULDu@J?X;; zeXuCl`D+E-0lk}L(lOx27zst!0EtL_WpmJw5@LQU9e7|wM@&J={pc`!t=P3j$=)NO z!C{d=>#ZE*zGnPU`5Gs?Pnnx89$)cjpg;?*eeGIfeP%Astnor;Qjpje{LzD#IZKuk z%1r=mXE~*mnN@I83*23}3QXT8rL1wNAJZa=L=-}>@W!!Yq!;`3=clMm;_8QhAY6oc zj_x78SlJ7SRC0%=c=lg6n*eC2IRI1IH>uCZ7i*~iW{!dnq20ZHen4i;SFlhFOjKI% z>mN=hczXfsgB0^;j$Md8mJOgtk@yei4Enb}Ya0g83JJ{nByYf`3{gADan(fP(ZRtw z`|!Db3l45Q&q3?KlfxCxW@K-yTY+qz7wqzR zOdtFq_T=X?d`h&{U^$o-l+zO2Z)$=0Y!W~+wW9!@D7U}W6Kr=oO$CK|mu&R45-g7$ zJ65>I2_`_8G6$~7qq@Jw7WnXjDhE{*u%%WCVsy9)8T~d`J~P{cwpP5G7t% zFlK%0nna*(^Us`+^f`aTtoa95B7UZ7V|e9Bw{Ji=W0b6xHniY%uzQ+BI=(=m@R#Q0 zy`j_To$Kp9i>43=L~UVlF^4JU>EmODidZj?jg1{H1kzbn0JCPtkp;Wt4UU)OmAO4R zs$r03&hbkJG#%)PK_Ish!SPl&{_+S%^6Kd_I6igs;F;w}l0l-vE=j{K~C#~W4Z?Uqs#yGM{bNjPg?%+gr=n*m!1a>@q0LX`mtP zQlru|H|HcIEG+2*suHrbFgGVzU0t0*p}2Bt<9ARSER;e`S=o)~=;(|Q7joiu$R*w< zK0aq%?CsN;BVLYaP?YD4!D`Y4di=;kscAiZ99Rk_p z<5c)By*J1wpauoG#F3YS1b^Z*;4dM$BO#oI{v{dr^z{E+{C}l3sG~$;C}{BVv`dGZ znwn-NCQj(;>7_0#EOa{-gT_9`#m(LI{re5ai$djTpiu=uJ6)=po161MAR-4BycW;A zX;@frc1uo9c5ri(m5*;5jyw`NFfdS5R1`HuCL{E>L6~x!zWqc~Q*&l%Nk$C@n@ar6 z6y@)KxUUbSb&l}6ckc+}#CID{Px*!U`Oo3u;lqXy2sl85869GpkbmBiv$La0`$58b>Yg+qc8Sf$wdKdu`_)lQs0XMx-SLP zfmUQR_**LH!7knl z3$(#2IJ*E`n=L(9cYdjzLYW%ba zr#w4Ze1F}WbK$pd5`Vs8z%}x(SDnUkF3ijO^{t~X+Qt9p_WQ5=|EF^9OQ>#b(nheL zk8>Ob@#~M?8{M7h1$wkDz;VHl^krkFF=~7 z!bqpA0HVJVFgUz>H$<*j|J8LO{_10(|F*u+6!$9v>)E*qj%RJQ5P&lChJd%ELRVqn zftas?-1No9+7Pf=s0p_%Y*UDz7Ui&TN}o{27Xd6das5$lHGP)jA#tf*?TufB1-0}4 z)fJEb*=M)FgXP8mk7b4nwk_pJ+j0U_5&reA3Ho1rXZTQ)JPZ<-NpTO@y-?D3WN5XitOI6h(4+P zLB}sO^_3eZXFqmYv;+Fh>E*u`W{E?o@dbRS%9_ndX+v!Fq?GH-U2DHp7qHJr1RY>6 zNrubz%w02wltqpZcRlBwtR(-fjb9jRc%YZej{chosk#7aqHp&~wN|fm?ulA5n-R)41qOQ$U+BeC(dIarI?qO?{clCb&&& zS0^(8d1a8Z5gp+;qCn$Ar(zbFqzDSfHTIUmSTrN9S&`!U#t?TA7nO_yeT%339~1R1 zB-R#pqdmo}hz4`2Wxavea3{FL+`>pQ-J;s58+m=9a%RvUNGvtsuaAwa=B#@zsm#}m zltv!-)6%N{)h7rRGa^9CPP_t0dX)PD22LtV&{GTu*6%WH!I6Kj!S}YtBF;t3X~x;^x#;<^&uyofH(;L*tOA;?%oTR0)b@gN~V= zPFeXHg@8^{Xzr9<+~_C@CMai8*%o^vjU~t$vhKIH>O$_tV=JvP9TOJ zYsMF&Z_T6;)QOGF9Ilx|z#^cdxt4NhCc?nw+`?`Z@?n<@xd;#S0;<_S??_xsE)X*R zoGoamo$PTSzy;4mZmG!Ry)a_ojcdHmtJB2c+PP$Amk62av%v1ynXm=NA9^sbsrJUA*QhN#QJ_@)3uf>bsg|`vjy9T^G zba(m#kZ~_j?2$1A)V0AiIfi_q8_tW8#c8zU4ij&xO# zdR-F|_^TCsfu}xRe+`T~KP2!-cmU3zHEmTEx7f+W>|J9pB^~x`=4?iyFq6lt=5i_r zX+>NxSDZe9mXreo{6>I}dw7!|4m7_i0PQhr%_NN$YwiByq_YTT0H=ut`Eyv0BWXbV zauG;n8P09DW{Lw651qLFHKG~$g;yTUvAx9v=520@7lHdCm+eE;&o1g1Z$Oy}VCz+K z=#tVKh32l+#cBb7XoPm21O3o-4qv*!A$pdM0B7q^?*eePI?SQX6cG>ct?xb4igl0# zETz1$wiG4`jHs<}6YzO#6sUKJ6R^M!VThfH^s|%N<3|cAEvcIaf{Y{V4GK}ptjPXm zTCDV@;T-UxxO#!Q;Lz156&xN>8}Ghv{b8Zln(-ae`&vgoOHp6b^1Jpps*+Z?{e3BE z_ecCU7TOXJ*!PK(j~rWk?^=5Hq@HBD6yP}=MW-$}$+5vVAe*5C!f~E@ioh+OLD|i6 z)5H4AW}L}R?v2uWNL<4$SthC1QBM}VbM#G6Fk#{bfh~;_OlEY3-*e{pvh0e|LjnZt zz?->l(2oN)<%OYm^gm4L)J<|3@S#*Rgz_r}xYb6qHS_-n@BySbc|?=>xl3!8)&rda=76TgLI`GxI2DhDk%d?qH}$KNJ6*jwLLJs zy|H=NElBnQ`_?>Q!a7qp>Xc6gRG4@N3yw5GH+-s2Wm>NRc<%dqF~sP@6Y#8opMG0r z$QniIR@CdHrA%*lommjsQDn0rk6ygB+kbop50Uyxiv~fXZukm>!0UJlHP(w~3u?4B z>!~bsZ_c8ak8<)ES()A`;zH4K-_jNfn~4`=oU+rOJYSw0%H`1c;sk|-Q$}K(C?% zRhfmW%SvK*Cj^UM;2~P(M*Umk{UjrdD>hr%Uy#7rD31sb+VmZAF13{Nd8yL<5cLK1 z%40iK(340E*hnD0?Hx;0v{n*-xK{1gIINwE<(K@{+}9lN!+Kh;Mrj*NlfYA#<}4CO z-N$c@aue2^EO>`}MSMrWh-)OnjM2wfd3Kxay*l%k8|X{kuAoEc zlD-H;j8)m9zRB}!{N``Hkt>jfXy;P3tquW;tt7RY2S46r5bB@DaBsk4nhPKD-Z}rd zyiqAZ*zD@0*M%B-dbJ}vR?R{gtFGwkvD@h$)`xqm8f%-PKUh;2qqy+8tuwLEoLtL5 z)0wQ|rkmUzu(P-;<~WtC+~UKGTNPhr60=v&i@qJT%l4-iVs%*}&Rx(|baRant3Uyt zPT}(HtLPJ49hnRZnagvHh5sZMx3or6)YjVO5BZiZ`~9GSX{53k0b{C7629n#d&|({ z)P>&SOs@Kbi3GF?%6!<;I2isf<`sQ^cqFGJ6SqyOZp5xJ;`=Z%$3ot-DX!+$Xgbi0 z%Xbh%#cX0X(VH(&@u-*Yw}7oEG>*>@9utL0hQGvpMMA$cemjk0ujZDz zE!6}@bQgy89?gA+E1x5znFq8@%Jr6Ps@1IbzPr&NC#Lf3Gy$q4A>)U9$nm|;c9NIEiOHZIRYu%+xkdUb{{mvN;M(feL_(ZdRO`Y-m(2h>oExgk7MX ztSkPCab4dj8rJ9zq0%w4||4M%PFoyC5jaFv(Z9p5tjYlr#Q zOsJkKfeCbd8-V34TqYX(3$Y2!;&sF}{cQC1>Oe|7>?aJ-v+rl-MCF6`K_Pd4dNV#} z!XU&Xw_-)N>^JNm+XAJeoS55`uo1^HP3&vpTxHJ4hO&a?FHsqvZaoxdb%1TGG=Vd8({VApqidVQ7IxYNO zTpM2jL~*Jx2xl|>1zGYH-$NuDwYe}KtIa>Mzxv3rdK3p!5RPqU1A5A6vNy>ep~}hh z_0@|YVUs;0K!3ak_*~_@n(Qk=b?$ovg-BqW|T{C&_(az+)du8Hp zROa|=nAd4)G*RD(%BjsX$Gx<*!Y|uouqz<%W}nMQ+k1JEZ_`f{wWm^>l2}tQ1)LsM zwBzxTvPT?a3$>;kl4eBcG3Cko;uQVTWM#+=RtJR*XliE_KG7xB)v@ZyNam_GVB7+C z;PfBw$v6F8gEeN&r1d8))1gl8`t!QR>bSvV{yUi6a~hGK_n4gWv_v7-5+CE!Y@_h^ z2};S!DFetx=^UFf=^kF6mx$TQZ-T4U4=KVyt2qLnKRKd^Bfr?j)sg@4zch9-n>0Q{tyMQpL(X`gpc0BJ>%=^+XWaOY(z?;^ZL z+-N&ofY4z$z31W~+dTey<&ItT7lWMz7&#zom}T8)itrt0{`|vTNA;sOO%L@QMfNR$ zDl@t>;^iBTx5cLCUf$?{muF5NdY|lSVx56Y!AX@d)ZZEZ*u4204`zpT~< zJekc%D@l+s;wF7R9x;zwdMRC`st_rYg|Lsj`)z{oj$oIdQ5zwNd_VXDm81^z{NlLk zD9x@GaX(JL#&9#*WEtb$aM(RI7j5g0-u{Y?mstZG;^X1t_uA~un#2Q8g<6ZH(ibs- z*sT!B9DB28!`6<2cbs?mrAXxTAJ+?j+8uc-G@vJdSfB~YKGoMrCqVPwp-y^@n4L!p(*S2Mzm-DMrIV^3Z z`d($L5X*W*8{*kGmu721Zb$m9A?F7T}zE^xTN9iwNpYU8= zV%b3-%*u1;Nwsu8>2{cdWFo(&4UPxK{J98{iZJ_e_vn<&IWxB3DTdRhJ327!# zmOEtFhUJ@UuhuYYq7Bg;@Q1E?tm}Fw6b*LY3f3Tll>Aw)v|b&ZASisXIWWLdJj>hz z9i1FO1erX{tu9ix(FYAQMSE6G7MD#v5>JvE@xqgIZg;@RE>UP0 zZdbGS8ax>BQB7UN5fhX@HE4s+Q1#qo_)vc^<^rq5`Q-ZEYgb++SFBpT_|lLiuZf;~~NhzZsEJ36HPDOMC8lMJeVT z$L^fU=w$(ifddxsgFYdu5;#2i$#sx~wc(>t)ZtTl^CwfPeCNd0#>y*3fU?2&*VsfEQ(`gI|h>V&HA#Bb_tmUMmyq6!( z)Roq-7Q8eDz{3Xc>8khYVqDFFEX+N`%~H$uD`!=ROa*!qekQbgPRtw#-CofSP~Jn1 z{g28gKeQy2#_s=zHzpG-2Y9Esv7-gc1v+VnCz>-NEk2so%9;&_%MiFM7}F`2Eyt*z z?6_SME8dNvd{G&zrs-mpgOKe|85caWDjCtb7y4lu?!kleL4nLCk7#=2{n|3;r|eVP z73{YS-jPhyxaV91}3XCMrLTn@o$) z)kV`B9|Z5};FbRtBp7zQTNq>?=Hj7VgA8oqW~q~+7{5jcNkV)Rk5+DN6N~I;G?aLfiLp4Q^vp8%?{{#i@Cf2K^Bjl z%dIxz$B2JWAH=x9ET|%jUkm%(Rl#ff8&nR(y$*bQcfP5UP=7h9#=qnv!d`#=WyJv- zq59+Ygtafsw^}6V*$?BJG=eL+PU#C&Qu6y!M^nEu*$o5TL56zJhiA`U zR}GS@0KPN*jj9;*m!Ut0)+f0@JqNK0wlRez0~ z^Uxf-$balQKOt6<5lcsn{m^c!68FwCpAB$QTTBVl&#yU66pX3l#!b<5fstWacS7qg ze=ocyE)zf(sZsTNioYxu(^h3DA`4vo$Gp`6wX-IF)V$LMQQm=FRI2%`GQQ}e4uV%B z9QcpBv6N*+(V9wj3-I-gv{p`mkdrjE<}<hhxv-E|B{(ADC*g5&^CdJ z16_+#!b713o*hm1@d-eWAi;oE4swT;A}X51d@r&ZD^mkC#w|8*$%=r^k|LE_CkW?2 zKIJz02(o6}2MI|vD{o+b?OOg8;cA+n6IluFl;{?m;ua-eo!q*Eh`|7%-4WpX8c+lI ze{`h{T>DL8`roWcC^u1a4AMeYhB3)k8+NJ$xPbIFI3q@2FC3$Bf8Hb7 z&CR$-2)@#5?&=KhHudZs;J{45&Km1R+COB&mad#HP*4O4&)QDL8;R;G?N`kcS~x)7 z5s;|JaIL7`?Ypb|&}!4ag)>@l_}YLLtZ)DQAbDcumREqE^6Ht9NY&<|@WZTQ+p2N(Zl7?uV~zI#WZJd- z3utDn-NlAq3kQjW4iG4*#&mp1krVYeOpa0*3!4p+n+>CYt@lDgNTq;c06mB1LI~bv zpkF;j1B=Q>vPah+1CVF2cjn*(Z~?frxb_$?R{YD@1LYobsS=S3bA5+(w>bAo^$IF( z9-xNj&(~}&D~RFTJ%c!+&n{^gFGr~Rug;qff>9-O`hL;6#JiGLoShhyqlC9UJUTTq z!j3J%-2OL;!48say-iHAhelEo~)s zCOtV@&25)a}fzTXjF#^YS+u+maA%IRG8L2pr`ul#jb){gSrDo^rZ2)S)P} zTdD!Ma)P#c^Z(S#cS7w1#OLptJNGmyh`R6O=p9L=wYMn}hZjRzZ0mU2n#yNV;}zoT z1Bi+pP^&9h&%N`4zGxKt@H?8j<~JN(fHQL^m26P7<%=EL0b-d4`rwn7-FEp4%$Wu0 z^{}$w!Fb@~aURMnLeG38^`|WxWJryPE}wn<>>fbuThltC@7ja|-Flqe;DL=#c0nSh zboZX&)U|VaJfRcbHgv34TQa@KX`#U=tff*OXzTEkQVn9b74*m-jiAXFcha5!cU`f` z{wY(EP_)V(_Uo1eB;rb8lJE~hxadlQ)df9h!P)2@kV~z{=G#QkY~a6liCXa=gtoI1 zf#P??*tMHRiy4&+JhxQ9zDWKcbrU`D@+T9$`3mmKt#+7cW3Z5q{)sd`IHbfJ&rSgq z;Y{;3w%oP)C3f{N<(~C-gU_%=3+hUjzGC0bO!mpnCidb1A+(66~TpzkIsP+E;V{R zUS~eozhz7UuN6OK7%(y54x6%wSfO4NOz4KY zu@-xrHB1{hF+z+!7$n}U%D=L=+#!r8>aEf8lQu~qH_3}_wM`Wy)_GhbKiM^xa#(&# zrACn?ewTK6VJB-M8boDjm7Mk9TE>hqYL*+o59?|2!W^u>E}T#C$g8J!sqI&JP*ods_MEtuP^l4GqNzl5v4>l3cWHPsI=2pbN)9e z!oUIj+ukDytmbEvP@y27ks`hYBc5~0zqh?XeD2l@5e#h2&R*Mo67zg2%{yp-*DHmx+O$t_uE+`V}Z$D1kPE&h+d zr<}2J(8kYY`jYQ+@s*-3JtxL+i}3=wM7c^6Oi_1ugxK0_b$?Al=0k(HR|!gqjKp=F zMSjYguGFP0Wcw~v!fr-kHE?i^{|w}Hp*$vtCel=`NvEx6^YFFCEw0V2nS-_dlj>9E z*@NA)=xFiMMGqRZOOyF@#M`>az9TEUR;QyWj`k&4H&WJmS?18@@RSn>D@zVJseIzb4L8FIyz5mMTT-dyHNihZi-k*OtSkBP4JubD)aT4>SXCQ?1in9 znIgI<^d@1sC8{O{dkFPCks${2UNZDa+$wkztr32Y?F!n;qWz|-HS0I=WaRhPyo8zU znaVAJd*?*_HNpZ_Ve2OuJeahVeV!sQ1m+gYY*ln6p7NmvyX9%&JdGP8$XjQ5?1s70 zu1B9?X14K*dyL_5YtKCquGK#obRPe?PqR?tYA)Z}IB#yz8{*SDfAZ#38~Q#=H1O3F z`E7WEp}OT49@x8$%^pdH%iSZ(GdgBjH?3a%bZf{rhE3a|G0Y9~chNJ{Ty)z) ztLGVk3$2IfaZ0;1uHKsaH1#5pJe)t6DbL0BSBFb?`6cX|vsxR-;B#svR_>!&t8eDb-a{1}1!|CJkl@jC zme3q+&e$9qsI_3CrW4_dX1sDBOK~+P+azaw)8{@~ww*$-KReFLbXf~8u2q~*3|Onq z)O)%rkQiG2Dqs*L>+cxF`@|HH!+x<=ppmFf3X@A^XC+EI@0RavZn5QY!Z!?>Aj?05 zXwlKWTZu#@(JzgT77)^@Ku&yI=Aj5_gzelH$Ua7Svw3w{rQ`Wo`U@g<@iKouh(DUQ zIj&*8@HAQ&3O$#9j6UlsRIMSVG}pRFnb{@5X$b_Y46Sn!<%QiLEnGTrJdBc zTA9M@P~&K6AJJi2G*fl=+#dnzthb}}{L<=oXO2b600p3+@i1k?p-dYojA2C-;wCa( z>0kvKag(^Tm({(FdsiV?%ym&+_WEp9J8b&asB~Iv*~jMNy~Zr+v47w%%7H?gpfp(5 zWSEIWek)CPdG5QE2tTwXd&XVeo7*~typ|0AO+1$zTRB_@I{9YptgZ~>YeUEqd0CwH zjE3p8q&K%16|2<$Ap;wQ(Wv^*aeWEAQ|ocRBRksoRi!`JNVI=&#J6Q4m+A<=Q%@!$ z#c_>ec(%?*-6u`=vTho9p2*5j+A)R3m2uBGE!az-mRnW6a9wNAZRKZYTsObxetQ7x zFR$LS)%ld!zhLN#rB7 zO{L?@29FnB{$cX5e+*B^&0UP6spEeq_;6d_UpoMQPF5vojAV+XAQC|2 zrHy%Gq-%<|&lP8dEN2;&qCTT4{LzBa!eP!a(#!-WJU2;9;+gs&N-&KK|Dr1x&{nQy zh$F{-)nD|+Eemm5uj}l0B8eu?9`DAW=FB{;n~kmW&-S(_W~?t?l$v`qLaxj~P2N9H zX&|fd-Z0xn=9Zs4kA|(xVcb@1y@(OMq*>DlZu1z=MRul|*RZEmpT>zltHy0hP4c-Q$AV!qTNn}MCrT`Yo6 zR_wPB*i&C}>-Ee1zS2}Tp5d<>)SnC+cb8)f+OxVkr&yX@!X7-*4xejXLE#-Lah_W|!*b&hhb7R*Mk#O&v;|~*=N5*6JfOpiTWX3@eb}`DHj*g;6Mn>1;e?8;BKPVef zR9u`w1qFV*$)w)0wiZ`-)W07@Ed=aZWB6Y2ii^G4D|ox;KhOGa4;00asHCP0+s(~2 zxiCRF3BM-#T%UA!*s8b zO{EfIN{6{Tsclm3{?Mf0fz~=Kn6ySCkBwIQCS_z~uxhBLXx(^)ms*h$FJXS`FTm&U z*uI($fb(Adb?AaBPq8)_V?CM1Gye0>4b${qMxN4t6~rr^Djp#qdu)EVTyB1_SaPqJ zs*>MfN*kK;Nl@8i+SPRfbc3i{AYqZKc65pW&3t%U}oE#i> zmAVqyP2MVQ+B) zlS=CH=GT<%n>^kA_Xdy{*~ z1o!!nERgg4Z#`8~&MM?T5s46izVlQ$u8G!Z0&=5%GtlR^`LJ(;Hxv`osDkO}{z|0l zpfzHub!J5sEvoWiYCkd7=++Z)BUJ^^vmM%~#ZG;x1}2fm*>N@;ocH0BNiR=O!|Ayo5B^0B!IkkSzGmnSfeKISV83MUX)E0jWe_iu)sMMN(E& zn}$kVhp^;eCtHtes34JKNxb_`EOl}`;x=oYY1|a!)y7={A{~5$N|NpIEPIS zo~NB0Udu!>=K#1ZQ3`-6aYUSR0Lh;|7I7FYe_0_&%KzJsthquKxbWacf3+_%Ju?$n z@ol%Rt*)**=p-l^fEu2*`89-I;;CbGK{Ck2;airLBO`{teGCR{l&%={030Z1d&94i z?ZzZ$WSm)y8+dc{#-MRAu%mGDK2O$v4tKdyIKkPf;cATH3v`)|;!Ov6m z9wJWwfAK*G8}d5@FiigQvu*pYb7d|FWZR$TpMHZtego%#tpYiHaT{d&pPv^zg+RFe zJO`IR_HFwO0-gzx0oU+=bHK@gTm$EP+kS`a0q17m{J@{rbDnqT&vVXw5C3_737qr) zdHpMJz0kHDzuu<+oD2VXUIETU{&t_!f1U%{3`FhEbI$wR{@XR+SIEvk|2=q!aDcm5 zKX!MueTYDu_i(U-K(4w!yzlYw!4af`hy9T|_79I}YU$nr*Fzv;d=N;y7z8qM90GAQ zhCtHZLLm7u5Xj|D2*i{Pf&9LG8$|EiHppRco!>qPjs$4FGEPsgj5nxb?Qb{{LV3p`=Ox diff --git a/external/libtommath-0.42.0/pics/expt_state.sxd b/external/libtommath-0.42.0/pics/expt_state.sxd deleted file mode 100755 index 6518404d5fa6eca01b4457a813f85cda074c0915..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6869 zcma)B1yqzx7p4V4O3I}Xq-2*aVUaEgDWzj~ffd*#mM(Q^5D+P)m5^rX5~Ptv1f)wq zQUNKcAN12N&iDW4pZC0T-kEvsow?7bDU<_dco+)aJNwR& zVrr%k#>O2)!*IwdY7;yuA!O5M7QH6czoz2REPO>(>gv;iFq}wV%788B8-AW1Ac^^; zB<3Rj`jc;abHzvQIEFXnn9cE9X9}E>Rl%V`2Yi$MhbNmY#K}Ux^9M=jOw2r z`{dMfqBis~Qp%RcA6NR7)ki(bQX%8ap$VQ(>e;DswDCa;R4blkoA-xj;hr~3rH-_y z&HNV!Pd~Xt`AY6uu%vitOUh>(FpfFJM)7x^9ePytOPlWdB}?cX_yBI4JY5D_jY;}_ z%38ToaM>)8UiyB8+-Z@Hw0BYjR_Z{4N9g+`yVF}awb5sc-gXw&(JUDLoAs`A8+qJW zt;SY&SNvR6jf;V~2?cU8d>f(4hUo1}-2UM`XYGEKSIVfzpyB*stajt!YvGP+sOzWQ8)bK%66q#vXkZl$U8d%Ym+>NC(#YZM68F(gMTRp@X?myE-AbNc;~B+2yQZlfKx;VH=4E0eH`2{+gF+iaco~5A3?-^r z?yd0`MeyXSTJrMZXH$fVfH*M0oiOSeNcwbDIcc;f!-fEZy<`;7Qpo^glUQl8j(KXxMqvv6;J0OF6bURfy zoo+!eP2i#CZXoy8fYnTBS!_*@!(plv-U{&v#j~mdajWf-o9k2gTzA490YX!(m`(CI zP6lcou^9!5z5t)-vAH9w(?l{=`)86@&yM!f8ambR(k%H7>W%wVTZdd;Khj_cIuz;{ zq#X;XuAp#o=@8!XIiL)B1G46^!(`80zvFuyNm{1wjgvopcLvwQ7hu9}M~gq2czLvj zt9nVe`h~p-m5Cj|si0JQmSCPNW zcs-}7gV>Khtl5?YKH8{W{qtPsFcAhqZ8fgkwl zN<1ZHsXUDp9z**}cUr!vN+#mGHXS8mom`1s+iow$P=mFIN)ohbDC2ENc5S{9_5v#T z*)pU$Lbl6oi0WPEdouXtQj2te#uX3I2g1WpeKF1dp;}7lMUC|E& zkL=hbz5@(G3GxJ9eTu|=Gbbw2yq+EjR$_}F4HbU^TVf9#FtJO7W#8?u;aCegVWWJc zSfIKpX~O@*;LqdwImPIPj_- zBa}*I!K1h}yj}0XxO{mhXZrP=%x@G(2{Q;tI0Q1ZTT9hs4V}rkp4GW-*w!E$rfHT} z=vSi{Z=Zpder`7+z-Fw}S%40ZuE>s3JQTduiMG(@OXQhW8ZP&3WFQ&^lz|f&74LS? zwrwh}biG*kHryKL&;gInoJG*Ta>|ZjsEp!C+FgPNg*;$&6V<|mi$88+(&dD_6eL}% z1YRFP@V=@MTUx7lB^EHqFir!&ZGIgpw!^>k%vAo`(KJ>rwO?qddEm2|hZ2>RJwT?u zn~f<7a3XCN><@cPkdT+D(*xi4Wmz)2UQC%BxGswj3g2S(j$Pe``U?GbCaLFRDx8^>GM4-q-X%P~TQY+kr{;~B#1Cf`*;e?&kk>ebp4+-(r<$$*2SgG)7f@{sz|OozdCZ^<7(A&vglX0HnIXmmk)y6jfm0BbbOnM#zwX- zX&J6L75ooF?2aDNjI8Z?l`yGx&)JKXok_}6%;?f&;B;%K%;y_;=MHB((eUxFDLod? zYvZsK4{W<_azmw~GtUx3Fxq_s%JY3RuyOh_W^-0OTrm0iS)^m6j|0h5qY8!Pw_x0? zaRk^8P>vc2{$KDhUU%wnFnnO%0UG zkOCx9;ne(=xSfc~>^7M+Ku0Apjp49^>g7W@`05-jZhzmSBt<@+(thSB?TZHbag7X;{H$V18>HD|>FUW~K}0|}P6lJxY;nV!Uu&)C)% z&#h)SUAy|Z@uT=HWT0_`-6fMmVL4#AMml}m%OgXs1!0Y7+m_Z2y`{*&W@uo!VN4rS zKa{LwBt12Wo1%=GP$i-ezlBiJpo>+)+}>ReQ#Uqno!DW z`0(iZX;(9Tk2<9>E2#%lt4^naCqk8#wh~I*CGkXU%laGdJ2fF-X(6G8;-bKdY{y1w zQOREB+A{9vS}Iz8T2(w4vyK3ye4&X zaX;<>4BOvxPrLUDAX#^K%M*~2_p)zaeZ%J)DU%v)T1m%ffIRyLp=4{xycHpi_|8FFJ-R1$W(YA=$+AQJ|`Hh*EI8` z#b!72c1$#gAUhR3W6s2@R(`b}e;3KjG_O>AP4ki7UeF1*x@Cpa5jx*H(0nlohlmJq zRF_`8ydXZXz^$9Y*`3raFR<7UG4x>MyMjVbi*nM(FF8 z_(v|yyf!jXiUjQoX3*OfOkl3hkwaFl0TWTz>r5Fu)yEu7CQ(o$80RXte1CN9jCiI- zzfrR4oGD+V?5tI4RDhE?Bh~vT zxK_g6MV4A$=3QH!qwZb%ZR&j%wNirz?Z#c^ndOOo%tYlGie5Aw0Se1H@wp$rtHHp? zq-V}LjP#QOAD&E|jYNEAokV(};~gy+ri<=|@~a8C71x+Aj`@;JsyEzYdMy^2&sd)D zO0thT!jwWk??P^A**Pe;f7NR)Vd{#tzWu;(j zC&MejBB@17`56t3Op4|Ut8~+;ut%htb|jQt;_?CR!4`GV$I$%ZrL<~8D<8YKo6+tS zP+|13erQd44=ow_rVry=ghro91`Dl@gk=aKP-RlCduEud`1Wm~72mRk)*}wl)wsy= zsSoHdsPKA8=dD=VsrOye-{kQ*+znc5D}kJ=YtKucQrp4f4D;y?#->`G$6*m-a&R&K zD$iq?3#Sx@PHUS_%8w(5pK|wygd!oX4(D4$ zz6(Vx+WK;LROMON_&^{nM;Jou2L_0AwgG_@^b}ZrmKFXGVL9&v1X9#wV`2NL3 z(2wy5NJvP4ezg9ALLt9#j;_x3KTuEz2xbqvu+Ie~02BcI!d@8r8~tyixB&bDJ37N$ z&NWz~elYt#hW=L|+b@FuHYLBwxzG=my2vGMUb{yXIt^a6!gxbDFbLW0~< zpnrg+So!#Lb>u~b1+%TOw>+Ep1?67=lk<_eb0Bs-HH)pm5ar!sLT^Le4`zuz_*jlS{WgsT-PuwGeR49GxNqed zq0=~WCV5gfSV2%FZOppA--+e~Z_N{0HMFoSzXa)e$(JqO5379zpW<$vDliWmxIF|w z2MIPJKebTFX2RW+^*=~hv@JIn$(V)%Gh5f8(>~de5^1Tn01By3&vUZZYDF9G?O;c- zHb2WbRgKY$nJPf;9vs~7Hlj7np%RoO^2iPmqcd|eA=x8rP;R1c$s4Z^uhpLAjg!&v z5t#YDQtwS#j~0*6fpHx|NZ2xhF5x}nq|Q}@nC&;pkvx&J)g~l><^chR_B;TJr3bz? z?*5H#d4)J9lpe&>J96K~x0*&~M?04n*uEJ#RMl3A9OElARcn7=ot~R+pZ}s@QHw4i zW6o&o!GAX2*40kf{jyAhJt%Ym6#7n_IzD|wx9)ZPP^*MuLyNQT&88?qBG$JLPM88n z5a^jqJkZ(!QOZy?dv%KmNj7dwj7qdG_6#nzJuZNy=Tk51i9IU`hYm_vCcPs`Pb&6x zp@e!=h;+Fd(0K4$bD}BMdT{hLOB`#;La_>ytyi+LvtcPTUH2JpDNr;&Y+)j@c|LA5 zk1eKCD_2!syaux=>*9cfZtvPYdM>^bzlDvyD-W${3rPl^tTxHwr~@{5vpKios#C~AP`(k`tne;7EY;nYX|$gEyiR;aB0B~wJtqB z>58|{VsB^QF}1na65F*{h4{??sk+ z4Y_>|&WzwiT~Ihy*R0V>enm^n-Zsf;(7JJkSlgZn??DqnH479ys{V!=^#Z4Gw9-t} z+5C26##$jp2!oV#!sDI|=+f=gz_p6WVr{!=tS6W%j*zirs&ZbME4jI=4!2LX1`4Xt zbJqrt>_kSt4kw=fqyYtb9F)pc7D<3=sogE2kp@O7Gp)kJApflP2X}Jj>^oT;ut>q+ zSbhrHXAGHc{Pp&Qxo1*pwlf@NHa2X<>Hv&r-zLv$ z?tGmbz$Tb;J5%`s+g&3bt^7$`*6CntHAC=sZlkYiN{0`h$S8svGkv}?wX)K()z*t& zK8hRi@~x;-{Y-cWZq>5J_-@p3=rmTd?Dy?nb}~!~(>)b=EnfxIyTpaV+qTKzimr_$ z!VMUbbA;p3A0Z=WM*184RdASzO0>pEWoz_nu_lj_Pb7i#_&&i@^mjh$fZCa&V8hZ3 z@o_2|ayM8_j2jR6ajtq?y{7mwf#LnMD2#nRIYF1~-9S=E0!f-Edv#~MOBd^+hHm@Q zm+sIvur4|REBdbCAuQFWGP^y^vi@Of+}u|5I5fKAt-OnqQbD|iQJn>BkxJ2FEUY+z zaQk-vJFQlLoca)kUis-wt>@1bWe8a3yJcJ4+Drrh?;oF(mJnQDQh+yg5DtWv8V|X0 z5C_L0qqUaN)Q{tkm22@4hRzfwoePTtUw7#RDZe$?dX=rFG2^3m^4|=)x)4~m_wSKi zcUtdj`F!lL^l@mQk>6(4%e=A9>G53$kR#_kv}J{Z&t64F1bo!4rQ`{2iy?^vptmmL zAT{E9&|s07TQTKC3CYkmB#@cmNFZQ&7(A9iF^ZuTeao}Hi0Tq4A;))1vX4?H<|eg&TYcC|o#?o>1s^de@D5?<&iq6uKKKSvT z{-usUC=v8o>y&%r?EBpsk$HtTqba=>6r3!bBPs9qqMI7L!p$t-c&VlBSQ+~!+!|EN zr{AtmCVe@H1W#Atu(dWn<$IwtO67inEl}*dB{7Uo@3fDPlbv%P^Z2285^L;kf*paf zb(O;U?vOiPd z`BeRRZ1zj;qW$0Y3V+JYU-@(A@Js5~ME`XOTtp9lCIZU8#}faP{HyU7OXSaFO!r?F YjJ7)dxd~WU_~#EhHWpUWwTse!03-Pj!~g&Q diff --git a/external/libtommath-0.42.0/pics/expt_state.tif b/external/libtommath-0.42.0/pics/expt_state.tif deleted file mode 100755 index cb06e8edf17017dec815be222c845f1b0a938e07..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 87542 zcmdp;_g7O}^zE;eYeB9eAYG)1G^KY$q&MkOLPUBOLQ5c^q9D?wL+HJOf^-5ZT}lX5 zdI=;uvq(4T3@OsZwF7_gs)!6+UHyJkWj#lj3T+mwoOYYsX^Y0dl9;{&i zgUfWO8SnV49pFljl7bM54mqEP8#_*`tQtM%Z*@Mr{(rp!Z!|f;nr!cc|DUhj%oqRf zXKnwVeHJLvc!WPto{;uhNXn4*{29Y4y+0L(c-I7IEqH zWN%`?=U~%97Q9!;rtEJ$oToD=U8>H!`E2!0bxBGAZDuc)bg27q?DZ)j7R{sRWpaZA2#{c=t z@LkL|3Gd%`enX+xu}%RN)P`ShUjs5jVB=Gg(ls2h|nH9ZAoh z@-*_+Mh!)K#Ot-)YE)3_$x%&U=D(M*Tl(MSBk&y*5fBEEj8Hn!^>?4;66FgvWRY^e z4`}hdne#-cd`nSe%FB8xI)yhXwJ)5OmB*nx$*4|UPr#~SlYYA0R>3WnO)(#&BY56? z-P)l3wX4x|M=g&*HrWC{L%(*ki>mdVHc}kEc;%MnM7e4A;v&$fSogRxVCdiSS2#b` zMf-a>2;UnOJ;^c~Q#Co6@^iON0Id-T~lV%fCg_ z)A{n>icyNV!I{9N8s68TeB20WfI^`~Zd28xUtNr~U=kbj$JZrxmp;9ixIR^B!F>g& zd!Jq2FUb?os`!~t->h@FGh%Ig!x*bIlq{a=D0L^BhIeTwLz;-&OCIpqUpJJ!1%5hO zVjv18tR`O+glU!HPACarWw>8xod^O}~M7}!&y z`NImrfUW*|!aZRAHr_dLVNwM%(53#e|Vi^!aawNPVfqYOuODVt&yL1uUxr; zBy&-;&y2pj?Ba5xAT0 zzR+f&9>dIQ)##pVS?{KGxINDcfcX}8D%z#hJigZMbNn$=0c!N)FnplFW7ZxwS>EP=zdZ$P_wTvU17!Sn-9X>*;Qb>*@L>-AXJKTb1pbXe;sQKK zC;6vob{R)3W9;NdOki&;du<@{<&da;+WowPHTSV%y~=dK9?s4oE9tc!qWo0E@yD!hYX9xhYg17j z+B@Yhj#uhL?T>5M5|mUSF7w6pU%jSmJ~9fFEBORak_wWQqir|W4rysThU(OD11?+V^kL#Rw zdK%Df4aAVoY=>)F5u}1wv0K>s3Lo;3_jGGO4R$GbYp&TimR+$J#As3Hz)+KElOXM7 z)1RuGvpSe=Ox%5Xh2Dh`QLw)JC^;!kj;ucZmthqQrb3EIH zlhCb3H&}X%2J9@`qSn!{D)p2?oC4NUmNtw_*7nv0T22f56SPx=EO?+T`-ko)jf?oe z%IR(D@kLblq8A%KRlwC-%nrIu&Av?o^-t z0*%O~KgjSl%zb=Lz_9k+(b17+&ptD+cS6_R%ePF#=NzV~tH1VHtlJ7P$-u;kz1jLj z9`Dhv1OemXR`8^#=6;Sh5o=2P41xwKTEcO6(0Ah4Wb;wk-tn?Jj#}yWie{lsY~sqf zcBq2}X3kAcl#JetM8YG~7Rn&=`AXXkWh&mye|NOI6%~maW;)51bTd00EImfaRg0XJ z+oie}Tw@Yh&*3%5wvNjPx?7AJa!UuUqy;LU^yhd3GEdSF{ypvu?$f?G1swR84C#Gn zKpf$K$<8cJTrUYlUJRT7C(hO^b0~R}-*GH<{yqQiM@phX7OdEyU=~QHbK-&X(HVkI$Ca+rCegOg5r-IKyquCwkkqNUo&O= zpV)jLyd5vKP$dhVRNP>f*0-McJPeTGpKbI?&1F!j4Oq0fLPwXXXd7gbvx-Ne2uyvV z3(as-dV6J7Nmrg`pEaMLXng}jA9wsMMvmfkG^#fi_a)ajKRuo)th&!18g-7WpBMy7EW4VB6I3~CF;am?IDx@~9)&N_4%Y>|(o_WGw z={ztk=Lumrp32YPk<)1mp**<0+kHNDS|MvwVo)CJlc)b8Fv!acQ*r5xGZ zK{qBik^A&r20Opbtb0bOy#&w7vv+K=kQ0_nnIh6oKRv(Spd%t3aQ^)H!Zfc(6V(Os zo(*B@^3WdN={A?T?8V6{D_pz!`(0@}^mU6?$Eww#RCCv%vtS2h?L z-{86S*x?Xwn{|FH244b_c5aFGI*TRrrO5@aetxR1j(zmX;GueY*h`^0;4q0sDPqfO z_KTkQOaOjHn1=fXR#9El+9&qtrN}$PE1Fp+-P*~whkJ6{(@AAU+6|l2zQI16@9z$3$Pvsm2-dZD5o4E(~bFyiHA=JUcL?A1oDS~U2kyXL%K|QYyOcy5Q_P}Gd(G(tN+V|kf{OxkW_4WLt z(do-Dwv*>4MKds+un<`fl0>>JsMvMp$O?%MJS8sHRJ1SFI_Q)cm&Dp5vQL#3TQ2ne zXl8l%;&t?q%R9)I3X`gPS@M1<3A{Q=K6t~eRtTzvd^XDtlsR6?kn$L{lmE;6F_b(= zliSKf6n^mj8q?(9E8p?2Wnu@T4D?vP3QGU6a{lgL{pKkNmgk6$ouL9vKbgk>VW9IZ_dxlV9G(wt7*NhG4b| z-qq{!GX)xSWzWClhcM#)JPH!qS2cUT-n3$);J=yXx^^^IF;yu7Xz`CItsqAt>0T1@Yd z4Y9`S4J#uAwQljp`?JqzwKi<|iu593;MnCe$_|jToNu@u^6b}Tgrez%@}F)sZN(?J zk7HAkD=*%8=0J55BqGrhPQytS)c`nOMx*sX0s1=P9=;)+ch;MJxLV)r*Y}w zj3W&CV+RGQOdH*&^XnyXwBXCy$#Tg`0i@fz@z%0FE-`mRJ=>J^__F`osdG`nz%SNH z!4%ai*RC0#CR^X~Rcp(e3hCfu9(DL6Q8rdO+z2K(P7EVgN7(x%*Uwx7$^aD&kf&K~ zG_}`9qLD_s*-jOb##m~`LtiJyA#S3{yNf9M@OT0JtxP`P62Hv0_^<_^EZ z)Yb~lnSN`-(}^OHCw111o>@YcZJHeg!sxzqRqfOV!reNz%_*V_JMXUC!tUy(JydZV zOyiRES^Y$9aVu^_=trW}rT&!Lq@L!cc6L_YD?NX=rQj%Z`LzP(l~eVS)nM=If#vD+ zGM_20Cp}kl1Mo;dxmj6xh>x!$7QO>rE-yiyLqqNTawAZ-A~uyx*oy6?dgr7Z=t25* zHkoHNS3s9SPi7Yj)nizYt{ab*2X$WQk7zfegZa&A6jQ*7DP{}n8%Dn z7Qtn;kwN_d1G@1u7lBU zs(zep5N8h2M5)L4wTDA;Kz)xMN+EN@RNoR?K%Ds*iRR<&szCylUrQHMH$`XXK6{4^ zi`)05sfYmEgrb;4Q>a3|bOF$!>oS1^LN<7b=^F2YqvH>!I=R_H(= zE`Z}S=<7i|w}!T+<_GkhM+PHQ$EQ`vJKHdg#@1a7QSXKkv1kZR-<$BrwWk2$(ERLjc7bBeaqsC4c4H}WZQn~noBg*?r=we9L)ZLnr z7kO{xrn*miSm;ASf(bDfi%3vK4&Xxp(zN zK};2()r{Enjp2_EC9|r-8{6Z|WXp2YE|dK9qV zpen?=A=ydovt*Nqf7Q8vYRp?!hGl0Gt+AW7i13y(H}tNVfL@EObs=FA@5mvomEO#{8w|xI@NoiD~PNUEkR^X zR(kB4P13n9wg3*^;gN3XQUJ>=!Tuc4jw8myiR)J-p0{m`7lzt1zDET(a_(MEd8<|O<%(a2!j*Psn-A9~KYpDWaA#;JJLg?9B{JuFCR#$htrrXpoENOPG z$lCW8O=z1$t+JYFhYyQK^dP{k#a3YNOX?{`WD^TrRp9y%t3*4L zv-PhFgSd=Ub2XhbG%7#|+Exi6QtTJLm?h3IBW}7$m(_#$Ug&udUt=vPY8ci%p8xcx zz1q@MVuz945{_rAKsQ|sruP=ehIjbEL|@+Xl=iJ>yL11&3B-1 zS6GNgS5T(L>Tx`&c~*y>qm^3X{V?7ND@6tmA$z|M!Nbh?JCioJM+TQJe)4|up3N9-=L^_n9nl$-jkx~s_ zsJ7hCRS8?|{KtMys`Ucwb&6F zDgbP6JIjWm$wD?Q&rjQqhRP@-kAn_2%R+Y36snxD8B$&ek%@di^N*uU+%VA9rwXNf z+xDM@XssWpsHnj3%l2jkb@_%X$|X*Y4VBZrp?8?J$;Y7*(WvXn|Uss}ai;PXBMGtGty%^=RQ0v&5@Ux><6jr;h?{Y(i0f0H((|nqM){ znVVd$pH6=R z+nxRl*JJfn7*sEL&!YfXkjzsVLN|=9*j-K2qFH5NZ?17P*_!W}A7v<=((@wWQdAzVr2q!%S z& z^kpB4WhtZDb>+~6j34-o3T6iK73c9b8oCG2BZx0PPsu|A6|h&Ye2On2S?=3mCB(jN z6nx-k9ip2T!^$ZI*Sk$snR@Mw^6Hp&sEe*CM4 zbL~vqm*;O~54}Wsz@lg=6hfo{822eHB~$h)~I2gU_ZhVqOah^X6nyP5VJPw)tqPV4E9tzGmMX2raUqcXb%_~ zJ4EezqLKC22i5$b%@yd(rOrrB(RR zna~&(>6TggZ_P>|^dJ)a_A)K2=Ei7|U(7|&^J;h?(Q-kF&nA?#=|Vhx*zsM`7b;A! zmk-z)mz5QZP6MuB7%+dvC}Sl%4rV2xw1>p#4RML6TA$>fqwUb3vK3(W7UID_c@iqF z+k#WGXQ62q<-5g|&5C_7sbf^otmO8rW|R|qf^VO~FM!*MEC`OHpF>mu2F!kXc_p_0 z8r+QK#+w?6NnDTbJc%>g5u#r!9GtfQz?W$1HU!!= zACkQbx_Fwv5+Uhb11G^qf8-Oy61x@c*Z)eFa7keMDC5iT)$A|)+f|>4D!{_aQ{!XU zZr!8j*EOLNhFHeHBux&Va{5mkvF*%^hJLz!ZGsOsffVv|6_-$b43rOC&kZK7nTvUD z%2c6Br+%8>uVJQZ%bxR_8jOuf6)7)afO{iPJz7(cSvZ;oIac6vI5Ol);$;UexJ_Zp;P4nQ0ppS)B|D_S9fz&&PnJ)u z2HLm3gWi+Q#tnW^svsGI{QNgZS^`PY8|C1{-A>C(d!MtSReG(S3=L&|A9c`i=xtz! zwA+n#F=KF(HDf_xgMnz?;H#v$0HtXq*zu%?mBT86+hJzhCBP3m6$B5FCM*yY1G6l= zb~_uDojGovavn!picT0ovx1^4Z|-53BUZ;smCwf6LlxZk`JOqpf9Jd2#AtQ&6{F0bT)tk5PMc+T)J9aIa&_#eA;8HoAq znKb(lKSK6`h?_;nN`@eZCZ+Y=!S`$Z85+Gc@-+&FH{E2LypCnx`0FnyAGY9r-4l;s zV-3cFFvAlk8L~9h0pm(vA->iDmX7Vn z>pmPiorTdUy{d>Th{@X>%2GD>qoyZP zZhSIO0V@eFE^2DxS5Z-`M=}W6-_^j@s5|ipHaQHWjJAP66W{XD#kr|@d5MT8H?BgT zYo|OYn*qjPCASHm7C^d{V(X(PQ(V9w>#F>0PgaI=-*}Y;WFuqab?N9Xo`?kehX;l=Zm4AUgL%FzRpuB!B>yxq%j2q!}th? z!KO!Y6qQiTNxg@QVT`&R`t6CT!_U1*ePZf?A!#z;{C2$N>P@XwrL3>+6GoWGo!70~ zi&RfzKl_C>k~{I_ok!h5638?^@CxAC_xfH?=NIwAH;sx9$g*xX`wp3jg!@-4Z}Rjf z@Q=Au4z^}=;(w@Z%j;L)?8UC)njq~PtpnD~poipv`$XHzu$EtunBM>Qk&CLiE_qjy z-OUQwHC1I*ViUbxs2FeOk}?ftXzbg2v2mu;cW%boC?0!g)AQLTi`=@z}kd45H3oi=GT@b?{M^C z8O9L2*QF(3mY?Q}UjUphzf=kw%Q{Sne&;Zd+D~(;^vr_|@E2|K?7+N4?*(D0@}BS> zEjj~Vt=NccA$y^MoFL3Wtmy@A@k{XABPeU2f#b#LKKo}&h$8e}&59@-h_C9sIe*Zv zuTs;4Xmjrun;1gQ^{?K|nFZ%0>Zly_1S~>JSVS#Ef5)VgRhAWuTY-~+!ywApDXg>6 z11Gh6cxWEiRDnNMX$IqpUDKm!e3z+t<3JBBt3$vq&&UrSJ^>Mw2W4Z0X0)kuxL`1$ zj4_ML?lL<~_4J+4+nd}csuXpfacU%0VJX_ekBRcTXwAJBux{J&;`@1l=efDtCstnV zMVP59zS!cAoO1T2A0XS*1WEARxpUSioMZ& zK7YZ}C*h7A8_kL4!WFl_nv~NhwjJL9>TQXkU5bxAuk>nF4-Y8Xq^Q%fYE2GWaJmkC zt6>V6`0~C7y8S~I&P0AdQfoa(&f#8P3fy%3;~=N zwj4aUsIa;Ir9<~bE$DtY{)##0eWgDZ%zu@9cGQ}Ko)U58*C;Ye8e8zU(vyv)HEo1p z`SSOQo}QlzeL7G?!w=`_Hx3|qoy9MBAH-Fr%7QSZz3m<6LM*ZLr_2KJG;{`363IX1=LSpFmrtTH`P%7^5z%V46twv8n=sCoKGCV``7 z|5N_^DD6?6!)oNKVfv|&bjl3XsergQ@uy|D%oTpg7N_Qdk05R%sNGV^PA45ClT2P} zIoz1lz`R?3e|&d}Wj+h^G==n$LC_cY9H9aP?)4N5xM37m7hZXN_J2co&o?~7h<+&o zXe&e|L02()>*!~S{@afZ;=mF;yvnnK+<$W;;k)}t4h4<4zPD=E?E99uYI%L5CLP9I zs6yB{?x`-Z5XF^mKA1+8qoVu>dtuA^CLF_Im$mnQ;chMh)qdgRDhOGbMt@gbI z<%L9;q+8FCO)$c3vN|4FppKhUB1xvxQArNuLXx3)7_xBW9Y!=wRQZ5nNbJyM7B6dv z;Zy{+2YX6B+?ST9vh9rMr)J&t2V9Gpl{EXxU(Lts1!E1VSBv&Um zYP6|d0*Acx^Aq60LQZJto)-~g)XE@W^i=8ikl(1?`uGHWF5lww_hF#Ej^}7VrRiv_a2Gz$AAB3Sw~1YP&%f(sproobyczOkv|x zZWHx7wqN!IWh644{yQp4^pq-^Zb{o%45Ai{IUvz$yrlkJKk zj3Sn$(+6&om4@uupq;$|Q8&6tJO0=*jm%B+8vxZC{gv<;~{0TesN?r-hDwGGB9^i5^Sf)n1U6+Rv7Oo@A#f1C@@C=!eQwyfB36 z4mm&EdfH1*E>}Io(Ou3AQU~Sm)K7WLNwengCQB%lO38;_UV;af^bhizJ5xQ)ERB_! zBmr}E!uxfq2R*R95SOYb!}I*|jXQydGU>CBt@|V&fUlS1mD{5mai8b@c)%dB7a&jS^QO^aSYID8VJ`90wjq zo_Ezm>!#QDx=|&mjXlI6fty1#M1jauM_H|HRV7$?#wjZN+6Sz$eG2Go;ug#azBP4x z=d1I+3tCD2Iwuzu$1wJQ9dn^S_Dy$W=yCG0W+GOyd6|M|M8{0{`Np#BmP0;z0A8bK zynf}Lx?+a1N@VZ5Ux0V`XU(**_Y}5%>6GEaWq;{cR2OLmWeyr6>F+jx`Fo^UWDqLW z7a$~`n30KsgI?c=gJA%Be)E$kCgGH*4x8~gEly6(p(dx8Yj}*H9##To-pOVuQe&NP z&*Cbs$mQ=UT0Xbq-q*5BMdWY>j<7IZSoUcr^d){*OziY3sL3_9@hcagz-7} zGvjiTY9C;z9(iFs!MSY)xJSanhUUsZ{KOwdbxqiUSSeklgHQ?qII-RLq12|J1%ebj zHXY3jFa0D=M#U++Dl0_mx8`xj6{9Y~2k+ZM+drrlvRwMoyMdtMSh8OIf!&TyrnA5iqLwtTRKQ%!V zuSIpmaC_SX?&I>oER6{K4AITh%I2Zh8`r+%3X_y-K&xxvl zpWZ3kf%4|GJg=a>uKkak0PHyO@Uv4eDC>Dgzn@*`4qqZ3K;`TpiGaGUe#^XAC*jA> zo_(rDenSl%6`MOu`#4B?t!3N6PdVWh{emn??oIAQf>s<_n^e*-xxR z+txDaw}DD0UAy$Kn@4RSM$HdIe{|m zM?uPLa)Fvu{6{od(0tMbh_Q6HP*Wp@-s!C0*@gVX=iEI zZ~>`Cya_wmH3$1rLQc>q2+*t&I#FzV-mJ3v{+f?%~g?dL+ZBpZ`6BJ|VSedbF_w6qk#`iT|ZDB|gwU{dPTVjv(cf*ebOw8=8+&I)hv-?H3_ zY<{);g!s7tcyN-Nb98$rvH{3RQigJtoQaw88Ne#j*Z2Qa)1bPl#g1yNAxcUTDDEpdQ{tGyuu7fcV>n2+{uq)N9$ax?b!|kg2_%3 zr$X>E0#X#%QYq)~=Itd3(F~j9z~FQp&CL6|+z4}-cGO5!o|yak!*ofzlx>~vj|@e6 zvr^bM#c_O=O^Liv6e;FJ!W$yde%vTcRPf2_zs#S}yK#6YtM^V83;}F@Srkm^JS4GG z3Cgq7){aV?a8s&vFTEd`N^!1HA1$*unb|{um4bydDhKL{j>gGyAvoAc)F8&x;5xx* z)2fkUz7RTlkiZ=j8??~bygcA1pGmKj*v1S=Opxw8%MI(;AJvh=nAEPGf<^cLx?7WN zqZy3B_Xpa>Jh1Ty=w*4hBaYM0;9hiKkFOh1O5(A5zO8^;pl7?p7Zv{DiH`1^z|cEK4kr5U=q(Z5jQd zsxh=*Fcr=JpFMVY-HKJ(BdMl?Wcgdd$Z^Q6XmExW%8op8N$NFVqxQCF=MdHzegY}0 z#Ww*q;pVEOK7N>Qz@g;xyjVZ0ym@VvFVST*&yL1rsv!$a(^^q6V%{&Texh2}8>Mq_ zi5a=C|5V2h%6WQq5q!cvtz1kiCyxV{k3xa6m(-)}W=itWTrhPEkkjS{ zw&&V}L9lLlsU@u;pEJ!}LnU0cuM9sTT=VK6G)TD2t#Z(2c&yN1l%7ZjOf;rfmZrR{La-as0J}-$#IE04JDmBrCIk*Fn{8xO-<2tsGdpzydzLl z*~@=xrf4CMyljsgIZVkesb286i916CE|Yzf-k_GVkM_q5h`+?0`h`4Z>XFBPKoC9X zOE0rTFz+9In?h9@{9`{L=p<>}4%gwsB=yOz?#q%Fvl+31Q%dW(Zch=w5z;5jA5$Ji zOe-{Zl}`*6xyGN4dmC6WVFJqrN^f#%FqQB#-~>a{Nl|ETKHa2exE~8ph)%kZ!?xA6 z%^R+AKHO!rp)6;Kj@Aj%{gy++S@^)Xogaa>{sq#VUh`>~9p-)yv#0WoD{E^-;I8q% zkX7cW9B*tK6*qIueq`f_Uc^mS2vXI50Pa}*0-(bd?wFDYB;(!#CB4oeK=X2b6CGPO zTs7M!)-(6@xNvPx`)`d_xk*ETd#i_T9b8;odxsqqKu19wvMw%~@NrF08*74e0=`De zS+|rbj=T|CDb(5?4;ru4h-F6x-|{txtfrKo7|qis_kn+510z-6)hR1pQk)l*67E!0oKHANw!%xq&K zdI*MVQ}vyS*jk~nthJ9MwWd40h>gIg1c12gC&m&}GkJa8YI$Wj6~t+o#h#u~qeE;P z4ft$O@m2M-qpk&Z@Z4{jI>(@yZ#AYj1^&0Z>;bZ3o5q|BD)0{7dkipsjrkRQ))L1& zsUMxX^KZg+lycpM)K7J)Snu2^T`UtW+hP}H7tU-+40-UyVL`2z%6t1&i6Z_qNTi|! zu5j&xd6d182o*J-I+sZ4gS;g3uRg7Htb2}pNxII+8lcG6=%!jLUIw;k9B5zWzGs{X zn@N1AH~0J5P`Kcu#iyTHI{nLDxq!2Mw};iJ%Cg=WgU%Yf)Rw)!-kI~dF|(zbI;>#H z-{NQ|&-_i9yb}h|K{g;qb~_U$bhqB}&q`*TKXv=|?VKg%lX!zLP~yaW=CQBf!+r$!dITJ@2q{DBlzVHKw|>c@jyCjHe+HB<^6O=qNcONz`>Z#} zZVOvAI>(AbY3VrSgeF`~#vm0TStL(rSGi8MEcZZ)=vZ5X$83WO`jMO*Mn<*eIuh-@ z^k(h3`k8_e;~+5CPeSs(1!8~SzID|m_W~+Ho!<$lSQU5umFF&bFIZ(>`-Z%Qn0*I+ zw$-4V#$-zN?K)chWf&nk6w+JG-g3hhyIKYbF)G#;DAGxt^hiuk5U?w5MX*=HWDxw4 zu9G9yZrOHeocH7}Zb>vaF#r&Mu?Yb~j*F^|bJ_V$@684{i?01l8k_TVik919rsvc9 zl%r1Op$=e_h5$RhXMNH0Zxc6ynmYpeXrdRC<>I>=(&*K zI#IC!p{tDy^heGmQ0AkCl|b{m5u$(wlfxp-_8;Pgb55LR%scV82*!5EmMfgDnR1osL8Y6<-)&)Fh_}L{$}BY| zAbYK4j`@!H(~0h~wROR53?`r?PHWgYq2qA~@mAC1qGiBmGat-wtK#hLyCurE&S=DY z%=PSR91{a?r_fuCi)L}(#@-FKhLTa7Ms0z+y^!s@L4;Ya_K6THM$c@Tu!#5Mq zSeP1ldzFgPj9WlEwk4dmT)=0U*kF6dXH3SJ_>DKQ!$HrDwX$>(153FtsuElM@WmFa zmk3P0tpJjKczF2Ft}FBt_>bE&pAA(NfowXumV))mEkv9NrPB(5iI;rCr;k^QrDsox z-lS&Yu8uzoNV?gK`o;GUOwMQ4i}0WWEJw|4)8%e(xV$a{ge? zmqKy~Me?*$PAFeN2nR2qEWbC^l_Gc7o>`c?JwR#G<;u+%G)dQiu#%m>sO`z|bF zP1B|9U>r`rwjWLmSbcTp8nTj_!lVf@)i~>4@74IucgRxX zp8LPj#T-6jSDcqBtH$c1C_$8hCnC#(>EaVkyApZ&mDHgJ`+=0LFSW)y_E2gfZaHg| zn#lZ%%1?nQVTbj~v2Kb??9MAkCG98M@>Ltn9F-Ivx4HoQ0x5Vy>)(t6!PslAK@!&#%OZ{6x(ym1{@pLNgSQZ-*;kIFUfjB^H+ z1s(y|IW5Tr#h^pyP_=!h{rOhd@`NCk^$yh=9AdZS94T7_W7voOT)f?)HCbuHEs#+3 zEJv-Kd~DL8;Cu85T@`%>{_4Ki4rq*E)Tea)G!?8EE(70hq?~M#yex6~V<;LfulF{> zY;+;E!QHFhWMHy{KTbo}MQv?uTL5j$&gGT;QIPi1H^|_Ct%V{2?Ldmi7(oN5H=KHK zFItVF7TRV0wpdI5(#Z$^xk|A31U>SoZ@<*AARMi%9GguRdezn%O*dTBdiIg-n%^sG zMj~ncj-U~0+QWQ|t3Kx6me{4v=a^XWI$fmAIQ{66Gh(&tNvI^C=#;SyJAcLN*_8VV z!1W*J=zn$Xxo`IdoF9TGj@2`6UUPGz93w)tA3uKl6=CLt$eK_fg+h-+i7a0b(G%^V zxC+qy=u;|wh66F4wEJ!tWktQDq=mXJd~H6EjDhF|cF=JuRbt#nzNxf?R$4jShyrb z(?Y!YS{-q!w|x!wq|fJPDu2$lG(lI+TmtKqE+15VVDvIJCg)09gYJe{f~>J)7VFYX zrV_{!qy5AzqHkdb-eQ){kw0kng|UZz%Jd)KaNiq3W5{$Ww#Ae#2L1?nmg#;gJ9$Up zS?Z^)-MjUT)w?H)byskEKa+*|O$E&-X4brMHU~tPpsqJ8v80E^mfI@dW>4{<6f1-@ z<_hO!o2a-mqTyF~@!WEGn{n4&rLNmcD|Y8|UZ*{kxCYpT zQ(8=MW^(vA#^~yBMt^FMGx2StVX7J+c=Lq&tJ!z%$5NMIuY6~2WxI*dtDi|25k8*t zYA%Q|L>%8fh`*<#CL!Nh7P{m5dt{)l3z>w}E#sCC*r?J;J>4hqb-OVII$A?z$7G#KHKD(g!hE&xFRH0M6I*^Kg0~uWsR54&v z4rz;KR#aEq)k@?w6&25ZslXyxKJ_g0A$U8^%ACTm)be@zoR^|q!u9W$sf>tc&DI`0-EG9MX3CkMAad3DZR0vS|R2-{R10VvXTzMVa^ zd(_RfKS51re88x~2D-7UO*iBg8T)%;hq=9bE zBfxLQ3g^GOjBft*zPebz{G6Dcy-9vQ4wrCoSShV(b?4#~j%? z(0+5#6hGWqmhTmszK`}EKh5GH6`t3b@pUOG^)e*pp4{F?f_^Fy$Xb)~a`MVf&+&tc zpbm)9cKhEm(g+SG0Nd%Z#ejy*OMCmmNzTehI}g70b7H^palE$~+Gwa)91`;3u#QhU zp!x(iiiuYVyWCHu?J6x^eB^{mz_P{$9^!qIH9Mkj&i zN%A?S)xoj?W^HL9Hs!a=wvj(GultbKR)q-x>ofbcDwLJO{lm_Zo2EJedw`TnB8mNp zd^(!XK9Jltgg>Na1v9xCO``Ie&z<&1-4@A*Ns{DhQ1}8YVKph5MN%7Hv6{A|eBY{} za=hGF$4|!Be<3W@pBfxtZA-$3)3^#u_A5%KgO0ET=zy+^QxWd*SLpfHgMXYsPl)13 zPdB)Uj^8ui$=)4zvfP)%&L7M%=-JM; z_h?k2&81)^rL79{>Ytqo=Rb?G8RtloG^s1%Cmea+3(f zpTdV%4RWXBjo+p!lI=KLiI%DcIn0pP_O)VW(X{j<+pohJ1BG=D0x=&^ZZR&tUThnpWOJ5`-SC7m$A zvjHzcK0F$fU9yM~MZXzoM8?2DLAaT)(oYVzTX;?Iy$(^SWf31wZZ1mpYAN09-N=-O z?CiP!Xu0JywA=X_p`7dZ`m4v7nRfDhKLot9;9>}QOTG~YdO$F!9C)GkXK%OSAbcx% zRtF*6PBC)Oo=4(1S7!d^jdz3J2AmI-_Tz1lITg!d2|MGpHyz_2tGD@hm3Y;SeBS)B zD_k>Xt?KJzQQ^Ghe6& zrE;*IQHRm^VnZ}ifYo!&;~g=K+NZ148qQsLe=?97q@H3(aKoxX0Va`szSNt0sN*r^t6%EjTm2SqlsfSs z7nu;n3DB3FN_MC7fu=Qnv&&KfkRpc1USxV_t#db1$rAQ!(RvcDUmdVPQyyZyZ#CE{ z5~xR@ltH5cN80{u;S+$~Ec;wZ(2qmSrP{|;6lSNuvRx-PlI-smx1+&iQ|clZd8lG$~TZ&3zm z*mHV!C}?jW#GQ~Y)#?`o+=Q(Wc?T}=V6ET(hX8Wa4nG-Z4aK2_iD@9O#4lZn9}F_< z&$A^S*ZwUoKhSP9gIiNx3bR{yuu8d)EE>BRqT++}=mK210?uwb>50JKluDLqlrE;{ zG;TJ?=SGI^_4EHP#=bhN%6w}Z6AMtm00|WVY3T+F0qGE=MY_9VVUE>b6qpzv!CY|EADl#d(Ah!rb+WujrmKSgW%lWO%g(K zqj@f56e62Uoiy4z$73mFd{eHLetuI}-`T*@#V>96Yk}1C@fBUZ?oX}G6psV#=Vfg~ zkk;PFmWCU3O8Vs9dy^oPDWr|CC%hwe63m$m-N=u+`c1F&fEFu)u@R80EdExFf|#+I8J>@9x;ZSdojsJeyY_Vrl1d z^zfsOxi#-wo6a+W+Ldt=<66Fk64q*y%@b(78?7_BE6dYX&yBxs?>Jk%ZeNIYj;fw1 zaExWs7&4`q-+icAZMXH+H*n+Ca;ux*xkZt0kI&lr-Yk#hX}&R3>h@@6i<`-9sS-6e z&{##rf%}_)^&qbJ3%!((O>e`}NVVp|t;&4pfePnZd-ADEs zo_qIX7GCU~+n()sbnXhnriX(-`(8U+Lsgvg-NU_rBypqDw;X>MgeI>M|7qxYGf{Li zWho;E8SpGa(UAI%_44Gh?QHi0l5W$u1r2q9Qw}E{a(O(JvG|lI;V*|dm*=*sRVB>w zl|-(0{K?idKVEybGGRmi&w594t(YRgDKrstbnxQUih;DNklr=7bA%<}Q2k z6VYzX_sWy)ip`LZqvm=tLY+{t)X=OtKSlj$-Lki-)7WkF%d32gj)&NW-@R5Wy1lYL zK}P#2$9;OE?)0u>h22U3meKOol5n!SK|X-r(TY|*xzGk66r-N>Bmw)sPuQx>U8PlH z^ZrUPY zMqsOIt)_t1x05Y~juDeBkxJHg=5Fk93$95URE=OeXvI8R%I_E~<=9kHlMfArcP35t9CWKI*L zd~Om~8B}fplpQ2_gG&rLVUr9Ck~{NUMH&KW+O&IK1wGnFzpk`Eqc=bFl^Q0zJ?Sya zE0m9G?L5<~vMi=w_*>TC{Utu=ehQgt3N_aJ5f}VmzJ>aR8ru~yP<1JsP1o&Cbc6{}@2)?a!)~YUmUp65pvv#|&yXt* z=(`Cu^3;TB6*I$nJwifX{{FnS(=KEFBDZx{po~g5es1muNM&cBi2Im$j5nYT)5@J;z)J%Nsp5mdg{oBj&s{q zT3Ora2(OY;ziK+6Tfa?~jzFcWinqoJF%J}*b?x<42UPD6t*@2t^Zhm( z4&-GHbMej5Y)S$R{FI;Ad~y5eOG3A;YMG_TD2Pb!;1W=DOPDwvPZEt8S6(R>`L@xU z{w!m%piQuAP;_%~ktbig;A%^vb$#nNsC;}!Q!-AB!~!_w4c%T3x!%q14Rj`nivvH= zR`6RF|M(v%s+coH#1UI%=Vx>vsb@tjyM%L^_79P72)llKy1<#0WS7+sC^xk_pXd_i z-Y`M0e0~dP6g6f?S9IfQB%2VoAhjbmvzZlAKP5g5Z=7(!`+d3A_}4L8Bf2BQuB>{^ z*NHidf=C5jo*(gx1>Cs|-G@%w^Jy`}PR8GXkpu+X4@ykTVi!j?Y?P&O3>|>uN-U&R zDR_)z9`Z|}5SkJcvYb$_(qVl^A&?yE*rCyGTsndi!6j^?!s zxLhZmiXQCxUBb8^eL`R#oBx`%@b=|ddrT*1YF21$11*-9r`&$;!d#M$X8@=g5w~ET zP@>n?{1e3j1asXapX`3PL|JIZcimFPb^M*nIWggCuX!Q;p`@v#KUYfsE8Ev79%~(} zEpuuyDzn;cWqUZh@0bL<3%Q$!W3F~T!YNZKp==%iHd4Q;iM$00O*%ah&(@)DuwnjF zPlW6Q$mgseG1)=%N>WuK9S>Gg-ry26qDEX818F3C8P;5OH^k87LrD(~PS10!*EW;< zcC4%H*(0Udy9n)i?_i%BoJKJ_=G6zuTOso0GD>-;{g~ab!Qql|jG*ZrZf|absB)gw zyJpRMn)t$`ohoHdi|FKvO_Uq_89mGf{&rfc4DBZNi$6bC0b7QgQRKE?Y7VtwXJUX5 z!VRnRF}dB!sM{12{1RE${mASwL7TEp!BP7WZuoW+I}h}{A3Sj#S){i$LdlNU+q7%j zZ1lFQL)ZF`*N*4!XvM#U$`OZSQayb{>^CP3>Du3JmLIP%P&|~m0mv&;z}+R-jJZI} zDhdvdf-VDpiA;TebFM2w*7xX`deq@kj7r6y;9vv4?fj;#THecdF2IA!*Qz<+?djs?gd(Q<& z>8*m_XU~3g_YFrZR+QnG5dJ5uRc|dVDJdy58IrT@;~#cxraZi;1|m6Pel#4xiTP0D2J(c#qa zg6k0ijR9SeevV^bq?`GB)BqH%h^4~1dS2W4RQM0uD4g`rrch?%5u_`x#i+ZNmzM)+ zLO*Mc{Ios@ip3`+T)B8rrqAOf4vxDV(Y0#}vv~;-hr>2dG?%XTqfk;%2#RsrHXOQU z9eaHLgo*k6zOZTn%}NJZXY^vvH{tU|whM}7&ZYFz$m?~Rp0XR$EmLE2pI`4EClj(8 zJVb9DspMp4G892Nns?%54`Y7h@e?O9_8qIA5aO;9RyZxCub*EJcI1=?uP$q5mhC!Z zWohXTJF-OZb?eR4!h~v{$GK5zU44D}Teltnzcml9qp2w)pWy7>Ya8V@Pu{j5r zZR1^`PrbwQBpJMZo?8!-;f%-=zZ|}0RD-3H4 z)0NBVIIBE)^8VcU^F1u_2~OzcENY*~pKaqfse8@Z+=7A{DblgMz=>MYpL3u8QK{Dw z#UoFzm>K7J0tZKdGFgaJ$Wm>MZNjw1)ok9{2$dbpFCajVX;0^{)@aFWZnh5Rb)7EE zZ`E@x`QE{9Nuf#c?(JKsR6Hqu7paWXljL!O-4aLWR97_tDSsTKEq%Lk(>z_xoAVtB z9>DO{o1qWGcLM=3h|i@oGcga9!<9+e5$^9VkjLX+BBR4F;oLpZRokLZ)S~V9?d@5k zj(Fi;%bVSenxsg)mS!> zW=GF>hTU+SR%=%HH8Z`$u&Ww9`W~7DlBD;A*tLuh2hJc%B#*b{&tH z_p$x3V~RSZS&UFiGwp^`a6mx(sgGA@m$*iXtreaKv8oXGI<#vTv$tj8q%%cuN4=)T zhdmZhFSU38y`)7O@+u`pS%Ou2Kib-I@(IpABgOt0D+<4bfru^87CywTZ6;g2oX$)w zD!yE#uj)DyanR1b2{&}1?#NYEgw40Vjay)UwT6V-A`Ut*>SM0ozw(68L%zNC7!FQ) z?07~UuhV9#VB}HwApan{Mf-gYd}9VKrES_8zXZ<{siI|$Whz*1Olw#gxWxXVVM=n6 z&$0x5`PT1qO3=BEB#qn=pWhbg?kngy}aI(j4Lt@H6X27_^na}nG) zIQO?+qFI`%Qzs7^RI03sqPuus)}C=Jb-u@SDk&a*>F)I0bqG~gnQ6LdwARO$gC zE)GtrMzhHRC9z1M*#Ym=)D&&LapHlClWml#&ww8_e%$S_lz^x~QrEIM@v6Ogr6TKk zsj{+)KH~8oQk5 zYR8D+P~y0!*Ra11I3N@6)NMfe78#-Twz))k9C`X7DpJf+O9Comno^F&IlQyFKHQCO zfBpJGLE1>7k<>TRmT&=)dS7yR5XFdwa#EvCk%{u2ig^L^_w&q^anLh02kd?$Py-?- z+em#P$S%hiQ8H?am-_neHSO`&{FEb~BHdT~DKJ{w`Th%;xNqOS5s{Lb+^Bu^2Di|% z>q#`Pqh?bSHh>+?&BE*%s1g5@FYvT05A-WosO;!;U8*7esCTG+0CU@PG z<-j*rn>P(3U+Wz(p9_>0?1&k1CL$tAgbs6Q$i54gtI!%{rMW0-nV$B)*I^8#<(~3I zB?Clk&=;V~Ycu;vZN4-W_?BK}Lf?y5zI}U$y`RLy#Pg`?Sf{Poq|>+X!XjU@VvpGw zJ@b}R=daH09yw|B_4RG{n?U&@=7aM?a176?-45i;6XN3T$GYr!j!#S!K^e)>$tfLr zF`e}0*+{PQ$sh%hmB?eyF8qB0NSaA3*eLh6s*%~Is>QT4H1&thT_@*zGcw%WaU7i- z``eQ3{pQV3A3Qufnuc1c0{lpO&PtMg$zt88YDQkgHYC$CSHIM(c5!i8XOP|`h6rskjw4J94Go5%{LSM0YP%UU)`Dz&sESsOjWan5)%fvw@#pc}g-_o-iY z#ps@-*4BKF(^ijCk#;>khR0@OrFoy|n$oph2TZDZg`F4K^^C&2v*IB`FSJr1pelw@ByZ>gMp+; zw@B^kVCA9d(h}Dq$pXQsq`tL+rLy&n4S4`GIK~>z+KuQV5Jz(6DYH-gk^Q^D8qP}` zjDTm7M~0WJe_6$4-}CPt!jcQ%)*Was3vB|Q;O>D%`8v~d z!%)poE1~&Nd6D`XRE3f`#-5Xaz^_qIN8u5Cz0X{pp07ybSE6Ws$Ie6Z4VOLF?bav^rZ~f#_RfbrmE2ttxZjs zuMw67)PtG2Wpa~eM%MF-5cNLvu^q`Gs*07|dh&&{t{XHHu`0WI3h=$dC5Aa~m>Q^33Ia~s?L)Hm84z*VMLRfdyR$Pkuv2x_wOAi4z1;pv%5Lx} z265D9hm22AJ|-rfFJkbPQfR(9{k?@X#75-E z&jB_B{&Yl6I3B0v_+tU~^;-}-{pT6R=_Z98^FN4^G%NN^r0DpLcZ0)xnV;_?9UmX2 z!f^=i;f>i>S_B5o3EJHdIS#1Ph3DL1~IT}?~6g2K$B7dB-d&C=9d{(@H%_(p13oVgC(i<}^ zB^%Ps5#|XH8yuZIH#2unlU?S=3iyh&>3(V!C=xKVesuvi#s|yG~`7T z^-j+$xrs(#)U5>KDxo+-hJh5au$mKfrI{flg<3EPdYI`-H7vr-7cjt4TtLSw*vNh3j#prQE{8!hN>G zLf`onn5H$meWUpbw>OH;nP1L+m3Lx^WOjWqWA2XL!M-?il}==7nVC#yZA)b!tXAvt z0~JM-@wgs^Ojj+W7Se>c>DT`lpT9OPTKSFZdbb#coNH|2r0EE9D7$`pbF+}`%f$CO z!`b%F=h7(F6HEu1Z*x`IL6&T1_Vh9444-u^svgZb9GUJ(jsNS${xZopsXPYbsb`xt z>M-aP)FOet@$z7qT~_ICuQ}XW&?hyTNeTOIs`p{gAg0u?3RfO~zNtl%?u*cUe|5^9 zJC&Y8Df!9Zw>Y3k{#VF>V}u{UZFIaqaeuL|02{Ll?yo*t8m>}xbaY(bUQ@*2FKz8; z`x*Z{QDahHHLSLjfy$;^c^RXwjf5mg*w(KTZpA>+bP21+0Ik9J{TAVWKL)-LUtA(1 z%f>O=OI`J6DHgEU)S7m^X^M783oz~H@^ZLHS%u+swL)a0as0inIE?K4QqH~_l#A!hsD`s$y%osfKQWIlO_ zK@};nQiX}ROh~w-W=TLmVC%D(&Z1p!@FVWlIn#@KZ;D3rBzKcrA{Vh{q7v?coq3Db z%U(qaA-BQpQSev_KbJzj4@ws-mqWT`WpB@nUJBdT*;~jNc>iMALpFxmtapP#Oz0(M zFLOt^I4jbTb2>_hV~o~$>Gr*Qxr6m*cnnU%07zX9gaV5L|OO*Yp zmoiM94vJ7k7GEDa`+`_!cagD@!0u$A7o=~%d@A!JykD2#Sp$0sN!$IF2ZSP$FMDt4 z>**SSCb?bK4s8!7vmZ9BIlcICqIf2R-Mq^=aQlwo#I#TP!IIx40$&-2 ziPdugOkK5D{hNW{=0*R3q(skZP#dzV?pSAC7`(=;VWRpCc;cpnT*fsbKIBQD3Y#jt zan;J6-j%G}a6Gcuq*L=~Pl-{v^f3T_vTsh~btCR0__(N8S>*(W1*Zh1aIQdLoboGQ z!{Gq;z~N&$C?*ym;9RVj`CLoiHH?Xzgd`n#u-C6lp{H0HnGtz#pf|L=j$lHq1=cS) zO-WsfCK}buGY)RSSai(*;%V%+Vh6?f${9aj-w;3PUDbkc^vi7G+BPqxZz5;6`yWB5 z`d)}zEs$DTu7Y!EF>1S0jj1xTCpM>-&%7!D8&_@ZNk($?q>4N-gv7w8Cq6jZ_C(w~ z*q~pF`o&XXo2>#*k9y`y3Xd_az;SUYFY~(`jmsK>Rc+_iDN|HY1#(xjXa*vJhiDY>QHl;MR>NzrN@G zdg1g@br~lP9mOB(Af+H96L)|?FF<>pow}NE>#I|Ak-ITw{e@{m9<4TOk=Wy*6R`xk z<{Z}35{zo4?b%njvMSvU_DEPwK9D08ErsnqDy#*+H0?tQ4-}gfY{-$59>(!k@jnx< ze7{e#!TwU^+v`*3H=8sMJF~O67RpwTGiCyp&~NvKM%tFAlu4{_tVki0DB5nMa;+E9L*fV90~dLVI95`$)**>B$%JieOwF@N#1eLZE-d; zY=vq%_GzSu3PqXClt;R9v}i;_QBfW=4b5u=j{S<0f2EcdB!TrL$r});^e#iQ)A^b*+;s9kt}H4!(KE7oATc?4-o6?W?P`w4 z{mPMGZ${{-uXQ8I^8{CYB`1S&{$q-kT~RSlF>pzaqBe8=!g(jOdqC^k6tvN?fnsc3 zT*Gh}kNFI96lxEVg)+`T>Y-UU3Z&m(Ad7F1ryk(gUN&3i+IK1#5!vgok&L=0t6FU0 z?~&r+v^AgP8AwgHH*B!GyEpXR`9xgip8(i`1YXmd8b2u3@uPx{3{dW|*RTGW3~?45VggeR%BC4AZu)mGzh;r~4#^Zn);eM6D*ibgI95 z_wMX_)Dv9Xzq=KVgoZ5R~LGWMaHSFVx=q%UHwjzfqY2_R(hdI zh|OQ@+!}rQ?Nn4E^lIDMQ_jZr_f4{(>kU9|XTCG7Npd9+XLS4X9~)u_-_9DrZDA~d z;9%sxb?a;P6(NvnjrJkyzo+o#{e{l+M+dJXI1L+lr&w9pWIB;zUHfg*#%u9)jg8H6 z=+tErA+yT(`1r}CrGq!t;gOLU@Fqq;P2hzI97B;CpZy7F?e1s3UO3fMSC?dPlA9*{4S+w@u8YZKF> z_L>_vu6~~Jh87o#6$4oMu9qOVqM`zz;3d+vOlxI3J%1GA^QI|yZ(M6NMlGwW zK#ASy3A+2!*GH3cbIN@lr*NJD|Ld>VQtHolS>Bv-2es{#Z}jixEzJpROEXTe@#Dk+ z5cL<*z>Nog1i*7M$p#ZY$w)54p2lZh%fwl!%d+P#oY4v4#t8y^@h><3_aUHVV(JZV zX6rAtOb7@JTxt%&U*h}8gTisA_#eBspY4j7ko!utBr%v)oA`KlXXkFRy*F6ve2ma> z95=uw|MP`!u=#zAkH3xS+AoI`5WxF9>u<)WG*kU#EX^7K`wpmhc0-4??OeC;@bK_9 z`hR=M0^3Nx@=U(X-K|f)q=NC4gZyO`74&!5ACHZVojZ3Y}a zDVAWtD{K=`T`go>do0fTpF5`(8y?DPKde@@zusiW)@klFEnuJ8gq6O&@+@|_Arm#*)UjiPPs&_G3WohTLf zEc7rjVu-RLL%ZG=g7l{Zxb9Ye$4-Cjo+}D@;2#~G)m^ASwe&Q9L!Lu`Z z>z)TJ>kdK)QC42wS#vCo^q*@m_j9*c{Olwg5Uk)Q~>gy|4*X~Ws9r-@p2VC)Q5=9&Qa|2t04l5wk?V;YoUgj zy3{RCZmR}9DJG;~OH94f@a@b-tY9E&;?-IdEtv9slex#g@z>Y=2DM2+tv zkNkz$LWFMYg4$3DX0GI5`(S3{z->6juOj-}v}^PdX1D-7vxS5aD#C!!uRf5K^~X~6 z5BE2uiTNFJ?@&{pb{2D&hM70aj_4u#DWG75!mK1!v#PD$7tCjIaK11{?Bi1inrw6O z*)Ipd#0xRNFmppsoqX#?um|cdO(TdSMl7JDhB(;Ls5%nHqVua@>WY8G{{!u{T5Q;V zbp}?zrAzko+v#XjQ24R|WpC>)%xu+@y%M||Ogr$XF;gYz2pMipC`a5sggf^(GW zs%G6op&Tg-SUgbKNi`dGl}{TK-aK>A`m#^k|fREf*?9yk?6Niwm{`($z1j5$? zD88e4jY;jEd3nz2Th2A%k5{q0f|eP%hYuentq@+lN(~h`4)gn||9*O+9us;?N@TU?KxDStE zar58jY3vSc-$O!NCM6XWIv}Wiii#rLolA+8n8`MYjKlcJr$~iUB*e$_J4uQ@eHs8o zeK8}W^tT=!xJJ9~n*V;jXkeiTA=u*)pvlH~F<0-)VW~=h6Ur$nUR@QU;o(uvFDOU? zdx>qxbw{{-x%O`-_Ft<}9@}0pUaqN8I4w!~8GH>6&hJ}c@q0n12EeIe zXY;^eOQ-Lwm6wxic8j9+m4VN}!TEiwxZylUw%5K|U;3H%=qkhW7s%n2p$b&9!r8ZQ zE}xp1WZKMki-EobHKR)5D96cLfC~Q4U*dy_CfLbIAa1XP9LAl`ba?#uZJ{wr>box) zJ(jl!b<(H7bkB~j=N&^}FX`Vm?5{%+_Y#n>(3x0-MhKHS9mpe`{Za4j?HvRlY*-mX z$)MGF0n%G=J8^IxhEG>ODIlV%jPt(q$PAS1pfw$eJ6LT~c9WmEo#?I^zO8+)!!vK` zz=ZyF5boFElXAb>+*KU^bOD8h>;*JA5|9W|QBu}43!Hq2t^57?igNwK z`HY-9G&CZ;+3Lo~L(HR=prT|q0{F337pvP+mQMbO7+;&ixuI;PPyna-=UQkIJ`DX6g{GD8=+~bh{QL9CgK$}H!w4XD>+=H9 z$~)#xe$q}(Wc$i;LcE*n0(== zL#Qo{lq*3llG9hgW%BbLPR6Nh(!Vc-yFNZS|6MFVJRNBs!IZ5p&!1%9vrrWQXPa%N z&avfwDip?XaJc&Nv^|<5IK)GkHJJb$M`I?`otKK%0mEnlK&b^?&tcSk<_p~`dZ^a? zS%Prbt{(t0Hlthx*p^#{woUsB{X;dJ8eDu?{4Rd}jsh8L5!^NBCZ-nucbgr@8-3nbbU7elH1!4E^V#5-g zl8$g%fcjX>oy_V`wbv*p%%?v9Mx{yux9>eFK@zgBi2C@AO$jD6C9 zY9qGquc8{#8ULT0B`Ow7c2x5JSsi~=hBlb0TTt5>01nFu#2=vKssr~X- zgGL~}G`-sl#1!YDTGb*WDoPPwc6BxM8niPj83f;d@vrMvnUZq?P7Yg};(WB=l&6nR zFu-jMvmFVJ+n2L{1*B$MForGCdVItc9qm}$71vsv<0#=kuo8;(Hi5)9!8TgfWi!_WgKKqixbmB0#kaT$8pnTnsE zUzGk-KO^Ab>Tmb(@Gh1ht zDpv&epGR$IK<3}~ky*XGd$36Pk^q55iWC`kswodm%%@MIqj1L{G5r&@E<=%3FQ%09 zadd2a&M7BkBI4+9npomMUxQ*4qF3++b~Ms4?2;}p)Y1wr$vK23*o;IlFw@RsaKk;l zysRwXJpF5{TvF`&j`la&V1O!7LrV+C2JTk&9x(mI;gq*T3%En{1@X`T2m`e)w%BIx zK&V7lX}t0MhItUSJr*#uB=~3ZB@g<4ol%#R0jwZOc$J46lOb5aglifO55U1N!N53z z?aRk#puuR1+_4H zju|E%e!9x2vf7V>!a9B&)#hkEB?#nn4U^6T7(*ns}GQ$2Px z>-`PxSft}S-U^wOENOA^z}Z=YnCiC+zg~#(Din)I#*nTU3FgYjZF%fQ-9HuwFq?DQ z%Q)!}&|XwJx8wV-`&|v_jdH2Q=RUt#Wx^q)6K0Qp1+G8KZ8KbeIkyf=q-Lk6hG~ID z8YY+k;7=~#gf(&(mCo+`?TZ{nXN}t-W@@SWSXypCh_b#5*&0i%ILtu(s&V=C{n+#E z2kw#RlfPo^Knjr3!Vbs*={d~I%qD(ZP!Lgp(Wi{?)*w~75#cWSAS>q^qOw{`|fv#>dPhxX(^9$yB{a9sFQ_Tc+fmL4#pcWbkM*<=uNEWA#x&7_1$glU;ZsA`u6$4N@1avo**_AwnWA=9>$bXNCV-2=a z9JnPd2x-Wrwtm7?9*G!!Wr*d4v4`W#Envuoz9-?5vH_oQFs)W5xX#6JP*; z-E#8l?3SbRzfgcPlE4|j`c$?@!jYw|l7_>TJod)l&K+{D9pNy)Hyn3}T8usw^{i*R zKJ=~VSyB66e|->5J0pk@aBX|+O6PU+a_6m~A*vy=n)V?opZ%GNX~cBP1^f5JrGw#R z1#WKBlo!y0)~$lhD+Or#oC8%qIHh-}<*$PeK{SBd)rI2!x*uZy5hO@dAmr;c+r%0k z^Az0jCs42ZVVqM%4Iz@xY?Eic)6VMWMX2h($0wt6T%YV%cbQ8Hy}g$&K^^Gvi*VeA zIHUwm7g#dvL?6#QlU8?q1}--W{S7(^sA1~ZhgosfaQMF)beyP%D(s~J&ZS9s;u8R; zOcXpR6$B%fT$QNaSFy!hhWRxFyA`Bg6!x=SSc+jE4A4=H8G*RpSNeE zM2G74T1o5^z0{mmM_&zAIV&BRdkr7ojpng_g3TMD@t}uA6-Gu=!i!$YgcwFVirexI zq>7hZY1{5-k5fxGhLtu%>PQR`^p&4~%QurEn#H3!BR%kS5X%e^hX2`^is19uMQ z1YV(4%8t78H0W+Ta|6+<*JD#KFc#8PY-@x6b(WWpH>m`Q;N|#f;pyf9ES6|^?*^hO zU5P;*`2OS{Nf2oM$f-U|XZZ#-b>GhBrp?88^3lj|m5dsd4vG}V5{_sFrrzUta>`VEJ17-OWD7HQY+$a$MYfgPw zg>)En)(8>6BzX9BAS~P<C&==#dn{w1rnWZg# zlGKE+J&zzB&PN=%X^+2@7$g$J{(hjhXN3s7L-H)6_PDI{g(LNYQRc?OJ#Znn;+Z?J z@6vV?o*UQ@?Cpsg%wj3;09*5)UoAq$vRLiBl08^utz($c zJ*|h>IR$s5f_|=>!(Pf0{d&jAr{8Pez-H6(|BoY-@IH)wu-sMLg#gpIMp%z+9I=|8 zq%Ct8i$4rUG(|G!u!BU-`eZ9*o_1Za1NMWx;<3jiT&*F@K?XkT9rmOCV__Y-+p93> z$>u(`e1neLebBJ2R_-9S%PkS*jNln-!Zt_G!GJpG_d|_i&oJ$|Uz=e?r9J)tHkt^# z$^TfcM+D^jpXgE9cL{_X#}lEPB)4L_5>sWh(9781&*o7G)cXEnL;7$weY+-}@YvA? zki#PLzxG(eYa;;edi{8tq{gjzG!)~D+}M(m%{C@X7sL=k>lJOz!-&{n>i@p(n(jU| zYuigBG(!73Z!(`FADXFE-_mUi=_r%kGU}mH&et*H8Ntq;hrl5pIFp{l^vRR0!K&Kr zOJrK>r#tj>Q7_w;1=dH$PBcVtWDwCk7X`lawT{qf#k84#oE+b+=M(Yf&7oYe(-ilF zHDC$CC9-uS_*3D`eZ!u&|F}>5^PY}1FzC|`>LK?$1`rVN(3Vu}^g)P#ASVr94YIwd}1Z?(?exSRvJ& z4v%r?A4+nGqPG}TiximG7{UumTL`sgTBEV?vhI6=Be%PfBwYT|g1e79p@N<~;aCk- z+egro#gwOAAEFdc86Sg3EwA$l8Zn@u=`p-S{NW?u8wWvCwJ0=~RvH~lV>2{^_M5tQ zbB}=TZp;TY9{b0d5wt}AZ5@p~1u;K8wOMWF6?T(Wn19(gnOyfm^AU}3TbNrgXqOEG zcpJUL*>nyocP~@wUBHg5gmz$RiD3qZ>zWl#lEo`OnLJzw#2_k7dc1Zy;I`wr67|@I zO$J^-=UP2y+1RBj)p+LMewLyiJhuCKqg13H5;p)rLbhQX2v&aT|8G$pJk19SWltXo zKA&!lS>PhRn5LKzVYB#C7CZ3LlaR`8pv>&hR=#ZKR_vq8Y-5+%mekwnR<^e=1Hq=<1wsF`yZGRZ0 zG4u8;;T=b>Ni4wPLnwVw=+!`Wn~u{}+3M)1q7UVgWN7LUBBC9^T{iTr4|>k@znY;- zHHS?~Oii;a2~!!&$j;{`;{t2W23_Sol~BLC)L2%E1kzeVo%l7~jpPmOaa^e?g4x$bs#-4ApxECc=9Ut!hvVHmZ5`Yb?SH)^V-w_SFuTp4m3mc9>xFqU*Z7}et z3w%JO@_+roZ$~d$2YFasb}YjA^s^Hsg5?~oVHoW3>BkayQ525{OAl*TG5$35pZMxe z9U;D;Pkwxa`nifhv%5vxH+(yFUKdC^R+FojJTFnc_vIKUGEQ+kfUe4P z-#2H(=c1MNY!+TPME|!v5pnRuQgfbolYZ71@5|Q>Bo}ZNtvQW11@)02N|+w8tX@%v zLMeew{;XZ8kS1?9qEY$WQq2GMyC%!n8l_#gpW6TiO+pFBYH6M$Izz48M$BreA!*_} zds^pR)O47ty;%bU0XjWi&+=ig??FM^1Bxv9$*qZqAF5$|_GV(yyhSn908$2UnGeh4 zJhDC>!+T56!)5Zr%B3pu^;?2_82{Rj*Q8l>e%y52mpuy*P};Iy*2kBpQAFiE-GvBknIz|7Lf6Qoefe z3uGkN+mui}mPYF)>dg7>j zHXM<6A*@g@yxfK?N^>L;eM2k zU`TVz));cab|Y7L0JXmXX24BBlX0W`SY@L~j+*S%pD_Jf7Ymva*s9^7RYBGF0tvsU zA2TQtf8PzgtN3snqWxs2FMJq?n$|&Dy%8!bvDvKe9s$Y{j5yqgEyurfHSctu?!r|@ z)y9wc`mXOVQ%7QfG(Gt*$!Ls2GW~i^h)mk)M(Z|*vE&0KxTUQ>Ly4IzgV&p}0c&@fJe7U+;JQ)0Qj%QV({*%0wQd_yfK|Kyf=}BN`HKjP``Ij7-`;lS zYCW23&wKOzTn>cmLby4Jm7})$QW&<)owafLCIrwZIIdnd6MXRnM|Ya*s637TvPOe| z9H;F^H^nEu5azHYq`O7;yLTog_7h}xzL{#7ad%wbMI#GY)t}l{Cnk-$pDmmK&OGr$Xh>3SQ zXdZbn1~sWJ4$}TB&ct>rLyXpXEgc+;jZtf4TfyZKt5a|17mk*NhJ&GYfE%S+|H^G@ zqbF2z&bmv0SnKhHsL*oR3NzEW_Ut#y^k*1oIHOqaEW5%;+kU35BzeY71flD%6H=@dNwzy-0(PkO-@H-qYXs6$85LN6VPUac^f zwVAhQA=Ts2D!0rui-pkhyDOK+!!*4x0Sf7AVl&3i=$=^;FU-}hj<31n@~qg78%-KHr^1Y1ow%3@zsi2ZT8vS5B_*kJKQs`Ia)$q-;<7OL-)_>21@2!k+S4$FklU z5rU>l#|@pa{dbKDJjFKQosA;Ky{W`s4%I!^r~0dp#+-EvEM#9AYqf%zId82l;}?14 zr{p$#`*cM98BcZG&^^1+3hSi^tLM;YtzPpy&*WWx-%sZ6ie`Jm6)STax>etM>}5RM z=FlJarZ?09JG5)4)oR5O^#w;EgR6f7rJL@2+uDs3GZ~Fl#rfL8xh|cp^q##T$Mq?H z7()9@h0{E(?bTjOKkgyt;0aT|B9dOM4<}M2NZ3u{So$4YzQmW94BY;Bm7#N`DV#5b zh*3r1W!(p=8V`Kb-f_ZK$chUM`W{AbnKSX^&&b3qe&8&9IdzVh($}c%?fB+H$RxDGLXN6aY)}hyV+W_PeRtmCsK%J| zvc|b^6JXdrm>#9IN#`S0+**ci{8XYUC3R~fk%gH^w(9P-WWC(SSL`jU@S>_MG^$=a zFS&_d`Ed7KKUe!zs7a=p`XA~;Hz%*qR9``INBT4RIp{(UQMC!eVnF{VzVZSAz-|w> z!l5^__1A}|k`x-`=ILMAA6pB8l&#mXu0ftAI7>2`^BJf4VCIGMiXJ6jaaRx*$9MeN zE;XH1QmfF*LK2X08E3AgzdJ`{MU0DweyuxUE$B39pgX80{!#I8S7>9Z<=WdLp4Usu ze7VvS_6;p!{4B_`tNE-+O$MYK8Us>lJYD4DV;*=nlG}*!4#FI3O)G5L9zU5@4_Pw>2EhbP$8DK zP&P-8))O0ap`4Kavgce@Y&Wr6XR=s^GduEV12e?Xkq5^W^Mb2iT@6L8QhfT(it2 z>9EQvYrYd$kF@gn68D`ySFX|De&P&Zx|2DTcu>$C&%n|}$`@!0#E|?rN@HWXi5`lI zJw^1rO{D(%n}=1H`5Ue1{FJff=nA>Khr(N=ZDF+9pSCXcGQj+CN?^BjV?6o@yIT3q zu7u6r{ckvx8_Qt*o6w&sR7EgwE922Z<2L~H-;8mn$65s&5m z+wCO_YM1+JEJi0QC^blyD*?9JdiqNK(!kT0FQZ5rwHqu&wGEd;1+2eIwERE5-us>E zKk)y5m86BFG9wWg;gG#5l`>yZ+4C4lvXWz*bBc^pM%i1EBztBb<2bfcW=7UAa*X3R zILF}}--q}0{an|3eLnsGe(<~=&*$SlZg=8I9HOAZvfD>ldZS9H?=Eb;Fj~(AP&dQj z>>x?op9A^gI?%1>6&xV#Q+yc50*2)fUM;YC)xrfOcC~t#BPgnh2_~`-_8+{*Q(Upn zRmvYEbU*%L#|Yl^ZcSn;elPc@)+KMMZ7YA!*Zp;}{h~{+N(SZ1bB-(&sGWU_X&;k! z84eF#Y1X=Wqq;}{k|Zr5ct{auTtY?w>MP4EYDy#sZddF{Kyivb?RoO<{%OPk2iL*wQkI*Ql2oQ| z!A?na5;lrg@9UYA;NBLqj%;gh!Bwrx7aLtlG6}4hDfaOrB(jbX|FB{sbcHS76rH*0 zWV#khQ}W+U_}x4&@yNS3x%J>dA8=C%hxEN3&Eon}h7Y$6YR%fv}L=!|bK+c_oB= zNS0=X|C;Y^(0)a{MJSpqe=bjrB!KE#PsSW$ZMP(<23$kOs?VnlPlYCzOzI-r?KI9o6( zEN9X*Q@qUj#uXG0Abd!u)4XFohd;EnqYOMo8d9(?>)*Nijig1Wh3l9s5(df7Ixep; z$Df>9SVh}4UPCtRAMsj_Ng&ty5ZWtW?iz2u_--{e&7NMzx4%yvDy@E#b&jzVDO1a} zm`Tk&hI47oyqMVqOdnqv-EH1sUpkvs;?MnvLt&~>r$NlzJDJ+xx=W?g<9OsXd>qCwK)4&YF30hvOd?J$XF!ml0O3WXk^sMdAl4Tlu}sN1_Iak9gS1eo*UQ z#8H1uhwm3d3T1Httc3jV6Pf3P7V;g(Lq=8n|3L{#+h#Xl7mr8B`ED||J_6{C0v{dj z%eyB~wbxC)M$&SR#k>hc395PNhcPrC-HYM9&Lv|t)R0ukIv0@<=s7nbrk{S9iRH|B zTU*-)00WLVE}ALrUf0ny@r%wvscM}4b$hBaHdj}-D77lSC~R?>-`E`H!29=^`;~@P zw-Cs22o(rLL!)2J-#c$U3pY(@F-F!VNsjLOWR-IT!)WdAFS^0mqfq$JKEw(2Ko}cr z+p#;jYeD|J+9B?=ul?N;yUm7m{mTU4Rx;aH-7i`0zF=Pd97PK%+4YH93@dzC z5k~uiSBj>bno_}pllfCjm%U6&4rf*4A9#$HJ{UE9sy9z^WVCNHYjW+WM&vm+hS%M) zY`6VlpA*(yR^in5HC+(xSsbF7{Vd`8I3r|Qaz%0C)$_r}5Wi=y^Jp&v0vMacz@Jg5J-a`*i=^qE~_*ASs9F^?n&>D%=@Z-ApND*$r9P;;$|pBn8Mi()`~@{#N&deXT;N4abZ6f(=l0c zf^UUdr%O5ReZ2Y?MXZ(+brq{74BPeQZ{RXKAzWnoBXiN=OHivSZloa; zLFumuR?zZjQMdms!bGT;@j^ z=wcCz!(Of$X%;X`y6YK#F-*+1dHs@2MEz0lTi{{R^+FiIK<5pO;nBN;mEGuIN z7?C`qW#KFAcv&MYlI6507cmJvfbbQi=eiwj?_ z513Q5OI_Z&X!C2}#wZabiEHIod-fX_PhS|Sdk7Sn2U&{n%FH}o&Y0A>OW{eHt7%O! z+mHrImw(R`*SMm4gaZEO&V`gKhN%Y=B{83~uG&K2ob-#twwaaJ976wBOY)=T*00lC z*B>o5ApQiPE~q62oC?|*bLp1QekX%fV^≦RYV{r={iMn(Ta_rSwB@dOoKkT7uoB zm>DX9w4o@~>(T4B6{=OK>K|NB_%L#N5_JJ$;s!Q}qJxUPIv=G3bmrL^6**GGA-Da^ zCB;W@?#|o}7gXp1E%T~qJTaVw0a<51tcNsB*noTLp+>XomZ1Ci_CA7uD{ibGLLbrc zT5N_{Zw1xom9I4Oe+VzQ2k5ll zA-%4~x&F@$@1$Lx7H*QE4ps;-706f=e)ER!+<0`&_7;vu*;d5e1Hdmg$Ck3Xz9$sC zT>ES{8$3`HsFZJ6Uks3y*oEzf$AQ*8vU5r+r>OaZO5$V<)eAq!DSxli{Vj1eh?-@R zM7k^F;Y|5aSD@rah|h1E#LmpZ{%oA72Ak^saDSUZe9flmts$QgjZS-A>rwtj1TI?h zJ^0)V-fJB_dBC+fRKDKg8^@9qC

Gz?-?J@iV6)5~XACr^a8KN7>Cj@YUK!?WXXd z3Y5m9N->(}NFvMaqx+~7S%;D|< z)sU+U=ZQVU9kJ{la-lBFaoplpW1M?Kc0AX{%EwKexXGjRDm~zvrvdfB2fqz-jdOM% zVJLi$x;OPcQV@u~33prPHxy3hH$({8RC}kCH$3h!eXz;})x&>{QmDR&n{QqS?Kq>) z%kD-MY?_Hmy)jUJ)z4)gMiL~?*s-a(txJuS`@f&>Owrbm+897UUQuaKns*Jv?QEf+ zx<}Ph@Qy_uz@5sBBnjtMM8OAXj=5#_i?WNi)n%oEw}VwGmcHdFAtpSxKmtsh!rqU` z@Z;-{vMsZcwr&y`E}&IBGHp^be6E2IP`4Eu70W`_FHIQd++%&P<^8#XaNPZN6yJQa^qnX$U)}QE4iY?4FX&b_8F8PARTfmSQ zKTi7I;Ws~zila4<*o71ut@mDm?Qj3akq>j{#r2f?ftKv+9uZ*u>E@B;Z9|!STQmbY zg%?6GLZ}-c5A!r5G(1Vt)=d$m@z{JNk zovlA@Qzv(zAAYa=s%a znkfmzMn4?sY$*1Bzo?oQvcT;8tXJEvYvXQ1Tvrid|%c zuh{hS9n@>9tn9{#__YIwp+++MCG{_e5@O>)=1_^Lt$D!A=I7#BWbhA`-gsis!-BAv zu&R)FX>%H+sk_3gDX12^=Yx}#-k0AnI@#2}A(F2YI$h<>00LMT`a`Su{`kspL0%!v zwVhr95Rxg>hFWr^&EWJFfUmD`O92C0eNrz;qR976z+J=p;2Pw|mt|cQkf7-S`-jw1 zyd!tH<40JsBR3u(q2qCLrhlp|O%D;(dei64_V$^{+bV6LyJrN%uj(dz03wRyXr5JY zhdX{r&Syt|nXD}sB_o0rIEeE*AQd}yrQUUDIJ?;t$i4IRdRk>+1VpSjzV4XP*CG%| zxL5n~zS{(*oKr1EhVeP{eWiMh(IzIAZ|L#*n;BzV5L)#(dj~YE1~Jn9RIl{ihmqoI z^4?nm(HjOrwi1v7>Y@uS)7k;^E?e{1q4mQ;5&TQz5!l$0q2}V-Z)YC87u?%}g$ zH%C2F#?U@ECMaez+45>A5IXl!XSKjy@C^OJu6XBIgTwNvwGPsEJiNUEYRln9-)a%^ zAMyX+GDv|jH*AO3CRFpVC1(+@fVp)T7K-j5oxdE-K|B_SUFX0nIb23X2~YE8o>FH* zuy=e)N1bfNCHz*MV-lVSnofqzU+_Jhs2YUvj4Ek_uT;NWA2Hus{v7%aOueBhtSez3 zX<{?AN0UUJYyrhf54*(^!rzk~!~GH)5tpZ*2-S&km69(Tp5N?^7mw>9UFiUfA#2Uu zdCmoweGO#G{y?>X<@PzTuZo^5Rg1$t&L&;@oSNm0K` z5g`cVptC_Pyne^H=HJ<~<^rSenVBO_Stef%A0|d?VbEIiAMsM=n-H9H_p7l1r_G7x z>8&Ply-j#E@uv;leCCVc?&g^kw>D*>Mok|6!j3KH>Agz$5eTjqk1|D0eLiqN(4@%B z4oN^q{hWE#M9gSdPTbLHt4RLWA7&~0)S&Bn8r4JwrQx00bY+D;ZZ()I_Bg#LcLshBcHIv;WNn1BzN&k zmZs<5*E@7hM)IdMCLYchtIud?P`i9iOaS$7_IiRaR~v|XZ_95P6t0x{fsDc4VT$kp z@D=_~xU5lI_EOM^h+kL2*%|4W?`MfO1tgVK$o@OcZ9G@TPs@CNKbzFnin?l#t}lrx z!Ooj3$}0Rm!p~1U{`;iWG3gIdu5ze7{_Xrx$$Ac&B)ew4{Wv7@3b3$E z5AYw}vM>d4$DG)7%>+nBX!-`~bsk3+zuA1!B*;^r;Z?rBh|4PR@#pqfD$d9a8rzH& z@j5qZGY4!SFb=n%b-;)zZX~V0&YI<9otUp_Ud`}lhb&NQWk*F8ciNDMYf-$413>{e zi4J*(0n7v5K>hlaUlrj)`PLm;BWiD{R^t##3!O7fPxH=>4&JLj;HD?r3G!?6xnKX$ zg`KC^F3aT(lWQ%8pLMf|%g~%?EOW7x)jv7-7Y?uD!~zwkU*6dbbl~kI2R>mx-EEI! zXb>!eV{o=g2gVG8bmd(mRK7?w-+{lkbt`gqzBm~+^4z?A=|fCF%z-anCLb)*gRI-N z%YHeMzXXY3yKOZ5t3ldV&Exaljv8TfCQK4b%=TjHj~8PSwutTA#k-+;ZC(HuP=rv$ zDEefyOfW+wMiLl%e~<~L4ctq2HNs$94x#TuU2z&~G1QIx!LQG(zq+@cvg^XE4lL2Pd|HiSDA+;`*|yKy|6H%5dmkj5d>6KG^CzgaMBFBxqV;U=CU~(X zMR0vW=N`Q0lPP9o!3~&b>>sM!_I+M)b0V7#bCzHJlbSXqv{<}4Yg_$1CHmvcEJn0- zD7{RDynN_zgE;AB?9ZlfxNm zz%_#-@4QtS>>)Q13>GDLwD@Z6&B;6I7YD^%dU$cZgbx7XdNUO)cijrAi*7tQkDF?S zl%>WIu?pJ;%LjVM3?{j0x1XhNXxG6On-Sh4BrxbH|5}-Fs#|RO>-lU4)^88-_XxMx zCe8>1zDM?i3&OwIOk$Mt^s)>!>8mEL|CYS@qRSDmzZ!>u|0F(4>I(1Ve*$ehAba$o zF2sh*Us<|JTA^y3G(GxXqE@o7dV=pyC2~vUZ;pDp8A4gc zY3UuR?L$P&SAELf>S!bLe9hbKuuAOx#^#D}3jXyGCPz|hJ8e%lLDDr{HB)k{y(R0U zRVsrH+Sk9-6AE=^g%10ox?t^D0XvpZY*qhxm0s`BGzjNt@T-5ha)r1Rpfef~yhkPD zpZz%!jq|tv3|Qm8{7$cZ*y*$|s95Z)lsfvp>iQfBy+$uWANWUd#k*D{z7}JJ*8e03 z;GDo{vPGUN5mavn6wjw3m9-4VeEMLtAlh=?VK{V6=P$de@45&ubOx&ImiB)Yv8qRb ziv+wZFJk|oMp%L`CJPV z3)7ApFDLR9WHmUPgN)K)LKOAVhuda;9W3s$N!kTs!PPbQv!l;Bohm3JkYfYjBYPVrQ`ymyPH+sxs&=E zGGEXd6X$hpMHd4_(z1*IjK37(C8kJUZ>(obwY>?F?EDyN`;u4^*ppRo5bxL(=c>O0 z?66M=uHxjW=@`aHwVuADugk)_1cJw8oq^l(@9Z3GS^c@uCRehkQv*g4pZ3;ImBHPY zsyK+R!Cvi2{HuD^skcGFuYWSt=SCfBGLJfkcV*&qfrp#XfO_*yhuz5r{Q|x%?{z*M zg@1^f_IHK_iakiZ1Me8j(<7ptId5y}9=!MHPOtTG1mJtZ7?WNxknIoq*_%r}2fxQz zw{i))OXhIS3(TIwf7-2HEqFAz)SIo=Z@`w9lbkN+az1@8D7h5>cfNqU*5T8$7 zDzvT$zfVUw9CshA6SQylc83nRHn`Wmnj3P(t=>9SSh3XKy{b~75Pp5H-S~@sHjy`I z3^mABhHLhq6CRJ1dWDRPq6Hb(6C|F*$~pC1WB1$kZ}<&hK?VLd%~za)Ze`s(I33~w z*B$LlygDj#d|sXbXefz-MOPAMHYczLE?LCfy*y$Fj$Y1tmW zBL8z-p7>#LXe%w|+ys_8Xf)Hh4#{g|L}ir|Wjy!ZH#Q4=UDBJWVd;M_`0dH~h0=q} zWaFC7KWcsoespkWd1>_3+e?c?^wf4}C%w1hKg|_$U+@C>WHec=wE=-3?>i1Z!0O+3 z(kLv;u`B&5MwLlt0$`M}qB0hh_x+)ubF!_xINj0#_q?Y5TD$_}oCukm-Y4d6SykLK zK-!{`A%akoEy;};nI_t8wq5>#nt{2i?^mqQhDEB~>JMkQe;>jd>WNJS?%^x?aiUQT zdyIO5Mkd&r{wfLomTqVC#<_aIc3G!|e^TRIHD)^Goef){?;g{F&je9ruY9 zzj_H7nx5Hp8!pUX8?)PRajq5me)g4^-3S)VXgSg9^zBm(%5pB|W-aKSK_XZup2w0<4 z$$1amPf>JAokaWDp1LUg&FxO9zj}*xMjQ}tfg?wlaWQJ@1T)7Hfh88T&u&_Js@LcB zC4UVPM0(Ht;l!{LLXT<>253O*wpJ#LDDoRkpQ0K;lQ9+o{pl;lt+3>*u{zMM7m!sn zQJpBtN^hiRRG*tqJwSX@ks-MV9bBh$kDKQY@mZL?crcke0)#A;{!|RA}9!y%+bWx)zJZM;_mhz)< zcv=lssN_A;9-XBw4XSIVU~0m&#Eo&w`{Xl?_hgs`w4W_-cO5<5wP=u*z%-g~ssqjR zal~b7_LPc`AdZs7gD!%?UI96P#=U7i;`Xo6l8e9h!pFnA6meLsv&6c2*j39mh;;X# z3Oq%2o~`87&-C{~sARX1M35pcE-R#dnknd&kLK%`j(Jl%J2TBvV7l8*=E@Cf-`vEe zc|2`ckwn@0r!&*4mHkY!2+f$%4|C#;|gbvoE2F;fKc2i(t4`on;VPnQNLwTTxurhucLBwdWAnv_MQQoe8 zO8T6dcK+aFF!L#0urFs_9Wv8u^p;57&C5!dHD)h(RB)x_RnV~3E7f~a)&;MOWUjai%x2`3~4kDgr{c?@3&*q9az6Ik!7FLcF!rR`IdXtAJj zWI@jIW^FKi%7rPYc(wWreLPU>8vD4SrsGw;g!p$CBy=~w;MVH}6P)zb2|dZMArS1q z9rmN*4nO7o|JGGtUZ*WfAShy{W1;`?046K)KcA2ISnl8B+!d!3GX&PIHW&Kx)Gt45 zy>ldR17*+vG?spHl9ct8I8pt9WUox-UM9sOl7AWZ{G1ZANk5iA7wDr=@9E@~4{7hy zUt?axE=8*_AzF(Y1o&SxIRD{IQS!@7SMxD!j9pRsCgV?D^j%I_ou6}@*3J^#yB2dL zNx&+(;q_>V?I`!a+}-zjU=HzUe~-RSOtEy_B+=%Ghj3qMD8y{gDF0m-B}iWo}ba{lTA7Fu`D-6{5IccK{#_^ ziP=X7My(bU`)>&gY}{`eA*Ppf{qfE>#-Jcl1T^Lzv4_np=MwrMw9uOt*a8c}#Kjwt)w{^i~_Z@0$h3YKHr_<;qz zZi?MtFB0V?8dm$b=Lw-qAgEDPmUGG6u{ZwVv!QRdu#&I>vG-kCQ*+j($~f6x1lwJ0+q$BvB6ES z#n6o*aaL(vc}1(hX$`{M3EIK1lP}j;qz(4$3|zr&j3(eZ_Bq$FC-!=$pW2F*tk)(K z@0*3biEx^OZT)MMfusBG$yiVC(h5oxIu!NO=tA>dxqm($sF?O!8Gm*>xxKx}z3GkT zyYpPBY;VJJF)aS!{p}03DY0lP%i*o*1VU!bOf4wkcE5jOLbv%w zdVnZDPgp20uJN?j2t#BvgckokN9rFk!iK?6ZA11CWwn*3QhZ!qHhz7cQchrBkL2<9 zcs^eF0AQCTgu`PVJz)!U&Sd}bHi`2BhfqSf8rJm)0|3STVkOwrr{KeW zm;%|p;nn>fSN^KmpH!Iq!!DDiCuR`)=x`NBo&U++mokV`G>h8qk1%$@Vt+onI*bO_ zwMRE`Ob7TWf18$3+0Qw@P5+q=VdpS1=v8vNw$PnKj>%?U6vxYw0Q-cwP^jGbVS)2? zYvjqE{kx5uF_+>Vn22_L9#;2p2{uzb3lcJh{XtTy*Yq(Xu z>B%jx-}$)VM;oTg=^atojUPm1AHV8LePA{hZr`~va=7xCKIU_SB87`k$OQKK{muBU zD#Tpih2N5n%bU4!AnBX}aSxMoP`)v$2WNAgx`WW$v7AYYX5rY5P}Q^PuUsDZjyvre zNs)EBrLVLnrTAj<8$zPWZ8$O2_n9tOEgllf+6(C`F{`@$)hMHw@gSOAbvr?`SzKwn zx&Mz^g0@kL`dxpvJq^3n+@AO+w!+1sfd<@K+0~Mp_|~7M(zf|~{NDzPH;>mCH#dD4 zRn;xYYz*EwJ+gGoXPh#r;-kPOSe7JV)TACOuVdI~TbxoQwck1T#URJW7_spz4{cYX z^YSn#AOjk-CRmJyB*?@4=N9vN1~>?9R8+P*Q##CQfQNHy?vysCb`|i&-J*Xy;1qM6 zltlX^pCm$eYSbXe%tYX%i3P#zTQHq-X*Ub6^-4n*BfIN1w4y1->U}W}q!h|ZO{J|L zme_lBs-) zpR5o~!jD#dF0_XOAtfYqxSqSZG3&njr&S>G##|L>I*cc&nZ?KoFtk({6~NbcKB$ZZJK(aY&v3>+h%+}+A5pc<_Hqdl$%uFBi^g?kUqFSh7y7GG%a{y&{1EAKeodZ zTs5n8TP+jf8@9>3&N;megq&rIb3{qnSu=7IeQ!&kOU-j}i)UN*WX!b?uvhK6{;#^# z(Tnc8+@E!W8NTEm8FWkI*^_SOd{m(wRX-8xH6 z)>(~&5IQNciFkOjijVVkfLW%g%X2Pev~jas>{esL31N5oEiTfpQQGNc(Mz!0+KIr< zE-vDOW6P7_V(|D#RNxa(49q-?8~>lqr5ezK8iRS7Iess(ErqBYUwWH;@?PoFt}8q@ zJU{YOq8_Wnm$9293ywydZO#(8lx}FIC`89z)g{QY=CeB$IsPrpCYW1S zSv>B_5dI;TwIORFmYGE}XoBt+jh$|`VE4KFTh3R4S|P^%7a+rj!_&4ec@GVU-tJlU z$CvQYqAwc;c2r*)7l`;J`ZdirqlPp`m^vOEp8GLymx{v2Dg-`(Cs`@`-GY9{rE3U- zqmATZT?QqfXDPwx({8tiOvmrftbEcezZddj6jb&SQp!Z{XdWp}qYDINLH6ke-%1LF zAUkdHR~wYyY)V*W7cSObH{KxmvMz*<789Bhu3J`j0^LF3;w9wyb(Z6&@VGRslJ#5J zS+jH(b@gwVT%5>_jW;`E^MRiPMMpP2=IA&Q*Bc2H+Q`o2V>05ITn*`UT{g#d6h53j zs@Sg<7J%jD+UAt*5MasEoQcu4?&v|RR2P+lQ6)NpAf^j)Z8ZF#;k)w^p9AAtRZp1$n9d*EbgZi`~7QWxLGOPlbmcZ zC30uZO|$IpS@(saGN97!zb_uRjGVTcs>}mKmX-Q5(yegSK>3J-T)MH%{@!43*{<}6 zq+J6Xxn2Ni1(mL(dr^G(G0IL{0$71dcP_mNolR<~V|6>8J{ zZ#Ex1GwDa1d_2{$i!xzDg}31IO^0;M6bqwq;jbFO#Pnxi0lLD&PJ0U=g7+LAin;o% zl0OM-HvVAL<&ui_e_l+db(f*yL`E7e6fPg5So_^6l!26Eh6fch_P%HwN59|}3rvFL zX+**Ne(5xqGX?e^ySSFtbhmb8L63K|n^<#k9i`VVrLG4jZAi z`<&^BMZfW5p2m%feRhXPhd!)ee`|Ff$j)a>)cnR3RIEv$(8PRif1^d)X`vEA;~xo1 zr<~emGmP{&x2N=uOH!b8eeVk?eX(rE&9smiuY~30b30L(=5^h0|3;z~Te!=afx5?T zNFo?f$b5$~>0d2yuxhJgo;IjQ?cUa>Ycc@M-@9he@87Sh?;S3293YgX;Y$_8I8}c% zlC~^H0zcO{!^82`p@OM-I{?G*-*l*JS5lO1dQ=hggEC2|VE-jp=J&w!f|@_6S2XdF zYEbOE{48M`i5ol3e)2X8W=jcOODc)!CcW*MP6r~RIrw!J27djuR~a=XTR91oVP(&` z;GAcCHr3W!#xrOUPP->L>D&EB()*trBkKp}94H%!i`JPh~$N^LE*&rES4Hl(Kuqxz8>*HAY^YshAJ40sbv*rDA6}Qc&C_+RuT> zET`~MZmhS_rkzLx7cKKhbhv?!AZ!Hx7(?z!zgn?A3q_ybmFgVqWe8(!8pOD{+B!|X z>gHz^80Wr|3v%GR-LurHoa|Hn>NQfpEqgx9$>w&t`d(~j_^oO7n2w%E@+GYRt6eq5 zoz>G`*nWGbxx!0NrT^}dhscsT{rsv%&?rNSN8?%Tj@XSm4$|LbFvTX-t8L##KV{x{ z{_|fbHY?#Ox$v8$V9>^!)$uCHPW2i8cLB}h*#>Z#+y1>jlw9NTU(J?G$2r47fh9-& z@B=|S8?et6H!nBymG4y#dDuzN@`8DResKa#;9#wP_seg0webOZ*bKTqX_igaV;i=WuGZsr*(m zXh_7noV8)Y(T*VaECdivz95;Gk##nwb$3Wx$kn(j^?Jc#>6OIz#?;7^%tVwMf8Ml4 zY|MK&E}*H$^hR|rN%rO3iwzY~MP{SU83Y<9(cd0~F@bvOM6>6rDQk`PGsXdtq6Z)s zwlZgYS9uUQdwjftPAZC720(<(I;5MtzbF&SA*^!^FI3&&HHaO^hO>x2`t;Ms)uhrX zNT^e|2Ji@@45UDqC0^3f(D>_pSNyX$@pmT?^#Duflv3%@VBP83%Qz-Bby>>h(fSD4 zZfHGTiJv3i{)wpFGX zHJ*^oe)nJHp|q{Iy_EF1)wI`ws!(_AY$>exjRtFE=(P#`6#3<{>z0*g6iiPq&DAGK zSzZB>f6{fnA5XQ|2b(>z(tpBOz0`gFG2^q!g82rm*kL2xc#t1Gg3YMF8eVP?{sI?{ zEF;-{j@}1>%CR4QS3#m&- zGb1@&1lnoL5RuFPH1B^uVLDCpt?*L&*mse+s0llLUqY|=B|hSGy{*3xRNLVQH74*0CFd{}|NA&n}%jX&-J)zJq zNIx>u;IhZVzJ)0zoeeDKi8FbEc_y2cy?Ra9!58M-i$BG6U23@C$!Ix-(-&-`81-Ss z@O8vy%}YKlGb&tx6}uWxPZyaR{>hv3J;I@@oGlM+Qv} zFdh;Ma^Z>5Dv03B<44mME#d4YF=l$-EYZdNQM%_PvzOkV01DUL$1ObANP!$&27Ljh zMfp3XO=gsdG5jOFmW`Gvro}e-L}7AV|55JAnxZnkQns$Of$ zzcRtCZY?Xk8Xsgh<9dwJHP1-*s`>QQDagTo+HD{8!X(##1)lLNxv!5s;;)3>C}G;? zDS4r+s^UW$bapp}w$n9rG*6nzPvesLMtY|*3R5ZwHZ^HVF9;CKaX{0#HzusRse5i4 zYp4FGN_Y5diZI?|V<(3>r}sB zh*TyNbF~uijGm2r%ZK`y1_nhy%xjBDQjD>B0Tu=cq1yg& zP}*U*1l#Tw{l|qn$%id7AAbZd{*YLkR0^A{(fc3Q>&^3=F8q3hicr@BM_a;@ah<^UWtQtx!Tyd7c- z&#u)Co`WsF$P%@etDn5od%1)O@aF(#b%B}qX`PMg`+89}$4CO8g@R~AqXd&y6cxQ%bdJ%W(`lh9wbN%`>13AN*u#Me;ANF7h)n+xa-df_nUq6;&sDE@hWV3 zEFqv8Sf71$kCK|DcFZNO5~|%HZb#0yd+7DF{Em>4TYL8f1+lAmPAoDyPpgBYK-Tf^ z*%U?JR5@pwW?xpSXqDWyx!9YdOaEetNccgdy@HnIM(F57T*!Exoi)B zOY(WBGIeRbQNlDk{jf~%?!5HpvR=#wDf5Oq8t3e}5pDJwnPzTH@4XZ{#e~phe zkc=<+1i2y<#Z{{rtp)H&XymWpyQ&O*KrF(hbH2ZIhP9WQadOawC<6J@5p&6Ox<%wc z+*2NWT+6;F@CLdowdbxGu66)QpCh)H=a8fOr@k{eBl#+~DD(!lYt+Mr3rLye&9DDqi@$}V||uND+q3G7Pq&nC5VGY3V40K__g#aZ$PP4$_}!% zSLiW7Ow<4REq_LzUq!$#^1@h%PD90_JYv^r&1K`sn-uvNEc=9YApYozzq}VVFtQ-x zuGeot2SI0mL&|+HD5^R#6jTEV37GqJaM(dfAqM-O-tvpTfd9IAp~tOIH)X)-CE9Sq zOB%i$ZLRiF{YJph-`6B{H#Q*04L~HE1gs(rTyQDZg~MWgn)zhjjj~WUEGpHRidE8+ zQpMQ7<1##RWv?dmV@_WTH9s|9uI9?auWvsh{a5ds4PoM8jN2-ElN0}H!`pEkBR>Yh zpGc_&TONqcqE)0q6e=8iMEy5)5*(kS+^m9v+c#7K*9)KjuDRudpHcWry@PKg0U(4P z2+Q~E`;!%#)B^igc@O%`KHwQvP@(Ov51YTdurw8 zz)8i%NwI4*|I*NT~paGu_uARHz17q(dJzrWJpvUT9j}G zw@Kdp#M|gNl?zalWUbz0W!`=IZ)6v&?%&zl-H|IJ`2|btuKYOOe{2YVewIi=MkeLx zL=zYT7QW9OWQ_ZYcw{yZEN`zyMXL zz-2)hxB16V^YpyzF$cy)8S_G--cGmaq06vwrJLO8C|9ckvWa$(FfZB>tYKurGL)Oh zk#y^fihj2}TK2Ku1}VZ}u0d@&VDGx?uZFu3nnU1=PM$^t{)xKf@F!Tct^T7%%<6+1q5^=a@!zhqopCCPmpJ6>3Ao3b+ex-P)kPCW zv8efmw+0nDoLU-K!FIj#6v`K#RiC6wrWF)VK?yDEm`BL?_ z+KvY_?vfY$y6$es*(1eOTqE>^oYMoZz6ep~R6pYeyg8rf88~D#OmMc6XE1(OR?)es zy(Xjf9!P%;+sc$GorIqB7A<=r8e8T{#vPE*A3b&3p_>24 zi$AK%2X4siSfN+xv=BcbMtZzBg)gJsXY2SE+@jU#i_#y!XKNP-QoNjO_TwmMO)dmo7~b$Ux|bn#%@(;`wQl<5 z#fOfFI%BjAJn9YmS~{LAO(c~kwtE*4@b-##zt zvy;AVe>%WG>eatmdx>+|AP?A9AY*;XN8@&xNa92|HFK!Q+7w?Mk~N5O2X&T1@L!3) z-N74K|Ga;zF}VE6ZG<%f{f69<9%{dt-dX3Uia=h%|JQDlLed4a0;&P#a z><>Cf1gj=N*C`$$#qtq6TU4WN&IpI=R>py?lm>{s$J=`(Kkn@)MNlySLIf6kWsQEVEQ$``u3 z_XHbC%5Fr`v$oh?7f^P~ViLW~lBpx^mQI*XjyiO_TN^Y(<;Bw`+2|VQouoOLu7gYZ z_swUwHw&l4-%yPFEsW}mw<`bF$79MLGYMJ0N^Fp4@!D~VC2BgoiOlBMI~B$%T3fjO{+1nZ`P`2+2`<*MB`WTmpqvk__cgS_sYetLm8+wDB1k8twi}gw zb&s?1eDU`N3vpL?|U*tT3$qIQS&{^s^__0OK;HO zD&t!`g9=k=^!!5BpDxIqT^9mGTPo=O=g4$=9L!W+@tzRGtC(Xw#zSR67v9VsmYmX1 zyBU^xIv#pBf7ldzSZG)CTOHbiGE6~`)}PYomkW>)LIT9K&v4RySPZu`7^i=vrRV)Y zPS7EyxBz|GinH3r%j{Yg$(l!)G{Y30+0+j?E;;y%e_VesMAS>j?p*V0~- zfC%?fgQ_}6+s&6ch{dpy1npChe4Gbahwa9)e$VHd$IC=fKQ1+iT6vh^vv{%uRDaki#piTlF#dV?v~W{Jcw9l*1b_xR0{X?~aFVSngD0HQdj0R{hD(@R_&gE@ z26A?1_XKZDH~L7ar+TqLhd{Z-ZKBcT2euM${%k;8NjUWV`6sVzK`Iom!X78Drq(hIs~ zrl8NQ#Us57pL5bxj*%@gnRj=eLW?FU6H|xXzIQzme)ksp(*-dIH$&K`BAdVRWbYxU8s`7w>pR1m%(}H_MgAjT2e~HSL6A;489|t*GMVx@STel)fJ);uQ@*mN#bkJsjsL3v>LWG4Sh2f- z0c&i-2FHY%2@McLTbgBc9C_3LB0B1|;;? zV^zvkM9+Q-llNvy1m^>uCb2iHJ5-L<1q^!mEElSL_T%IXtny3phY_uv^aeu z4(V6mfTDY*7iT>6TDm=8{fXo;`#Jqi0@KCr{a5>(`*g`>`-^TwS~$c{nxC0DjQ7)yVqe<7BZC8?QEQ~iu{?rzfKaN+-n9#hvenNnSKACGN_-N{P! z{$R2bnwM;{jw6CQ{JE>ib$OK8q$N0vKdt4df$H3iZ`PWF>)edoMk}%$SPD9kHb6R? ztu9wM5J%k^z6!Ry2rq@CmsjTQ==gz$+2^Jc0+Z+y4nVG0W9K9UgeuU}>B*7gC;69EuV(kXHaASU8vwWUs1NVn|Kw{A(uQct}DdZVo)&$FAdpqwt=;QuD9JB-}FYW z8%!RaX`QO#5{Ye}NkkEb8UIGDb~_-m<4>;)?B9@ z$>+{SJj%EiIa4=r_-JFUoi4NR1M4_*mlUaGaHt$<@*8z47^Ee!lQLWf?`T`YTLmTYo;~FjnY#95L>&s9uUn?-xXcw(cB}Qoal7tn)*SCYgY<`vT)xQG9peR3zPrplo{X z42hE)53@IwlR_}EeCucgQ5#C~na=zlP8xLV_(`>rc&sWaei81coG4Y|iLB>uObVr@ z$*XYOCo0q529&>ZGGm=dLQvh!u0SNx$zm#qu&z1-HGvI%@AYpq8lQe1R+Bff%+Zq= zC~Go;Xz16@&%GU`9Ov-#6KetStu&LXO)e7WJ$oYWSEi*)ui%)xXw2P9Le zIP(16L)k};rzXS(x(P&Gy}`F$XwqsWm8Vxx)Y7L&#@mwh4T`fQ0j9XXhM4jNcM>W6 zzqp6jXy!0L5@BBk)E>gRp7-A5ks#uX|AA^pT}ps+f!smPni9l z%ocst%r{z;q>9{9?N}}u* z|M1X$A3aHB6D5RhkR|KfFzcKJE)J!57u%cIr+!YfEc(?PIH{JSUB9O~C?gI|THguE zwfs6qupwzHu%D2w0&z=pOI_u;gy1bl&*YfoWRQZWS$>igB#|aa&2CQUnEn9 z+$9+e*t*3y!U32tzt3iom(W-AP-*u^4dv&=@Wg{RL5jTk<>_Ksti$1wH#lH+L0gRc zndzKu7{>rxb*e3&ORFFwrPr_tN!8$Q6#ufY)?$~+#HEMMP+N3$R5MFfIuoKo8a=j_ zGo-&B7ygo@-Q6IXVEx%=FWS(%7yJ2uzuP@YIiaE*C>S=Ao^0I>zZN+tUc)AZ+6)Cc zXE&StR8Dn~C~n=%LBFgtcKOkp-U7>JXFgsUoYX-$?`g(LS(k>SLCS*TOT18Y5G@PZ z-|dMQa;i%)%^^W_Wn?#HG;L$Q{+A+yVKwg$L(uT~ihR#*^2A+{-@r_-KH0Z5fSURM zbQ2eAYvvi*Rqa$ZET`-n3!5&^KvayF0P*c#9@?}i?IZDV4nE}SH5H&d$iB-;s?4Ga zUp6%bUf_iRZ-ovESt<2BO6p>6>}-nW(qVzSrg)X|hcxvy)pTV25g)p2MwZEdV{D38 z62zln^q5A)J+rOB*BymTNt&8ZrkVo2B7SW7;>}G1%TA!_?OBF>rx`AEPX~i+0N4MQ z4FI#@x$|>UT;$2YvE)>=Ei$}j1mF~+@kGKdxdvU9}z8XRRn zame&e{NBfRab(?QDodM{j=JI_K{M4Ew(q{qaTw(?(-b2v+Xyqqd}bkMt?;3z6$v~L z5j?aScDnxE$ole^ug5qV2CmuIb!M#gZA}Qj#lx-yt}U+0;G)0up(6=4ogE!dREiaB#)>A{yZ3IQcCs~Z zMBXdWYP#f$q&ld2)TfppFg~~uD0F6bcX!I<%lEel!4u*3VJE_l6!ZAjOb=Eji+b6{ zWEJp4Rlmi>6iEO6>e#EPW0*K(v2y4Z2euA@Heq54k4eBAPnh}>^hG)*xLRAV!X4sQ zc$uj!^c0cG@ndYQh26~8#LR|bMVHLuYM-84liMS6Q1+ zbIMO!1m97nZYK(v5NR6;^m8YjxwIGWIEjsBveU*mGYVi@zTedJ|*{_nfA)5Wo_e0yDKb_()Yu8bmPVdvCGVD9i&2I*0W{|?{%|`$e($r%6y0y!2@pg~j&3k= zzrVQbVZk(NSGLR{#M#ZC%uD#$LmqBIoG6^W7r5lQv3-?n|41LX)lI$|-khLeb*C&# zsmA@PQf&D>n9zX_T5kdbT}<@zn~lRBA8FA)<1Z`Ou@jpRte3zqbG_xgvZt0SvC@~w zw5NV}SBi(|h7|Vpk(PJkT`CPvx*I3a<}<&qh;0L$tmk-ow`iTgA*mTB>t1OUX)UY%}q? zMOl>YqOpfPKh7ppsJ@>Lc!*R{8B6+H|KqpEy1G>5^r2GKq0BK(8qdS7Z|XRJ&uO$*G8Z6_^4;yl%l z&AMuit?=}_i(xau(0SY^YE>*Bnehm|Z{iU0J@B=`>rEMv#-_FLs#A3n=*mj*P5pU- zh&Q%att2zGyj;87ZTOUBQFr;c8-_k`5S(5qso?Q7RE9`z@RG>0g2i_`JGR<&%*J?5 zg*ejO6Uk^)d&5am<>YRf#|FrL$o_fsxKPA-8TOZFQPFG<`|lr3zhrhy&d2GI_M_Rt zQ#>mAN40(!R=&xu?~5LfKiHb@wfo-99IX(H z6~k9ylL!P5r{a-wc@q#224&k$fbEmSY2SjZvJybV9XtwOGq!<-2XGhcqEFL{-hT}B zmytl+_eu|Z9!UFYns+B~lvsW1+tSItpQ4CL1|draQhYx$L1ZI|m#3#+J#dHepDA#< zZ$Ng^!cE_EIZ+fTBTd{f@gh>6JGY4?5{VnVicIY|3?g}QW4aQ^OCo`Fv>kL8uJZG% z`xsO>n9&N`#OyDq`J4lBzWAm6>LrULJ!&*JNiCS(R9-gU{6>jiMBS6bk9@KL< zK^UWW3EA4z($<~q+M(Mx{ucBFK}146-4d5cLeINb;=WGlbUy$Ez8Rp=3OxbTz)zoM zgYfXu%3$6DU9!{kSG)+DksH#p#nt&F3U?4nHXE;YN5$W-bh0EVkI#bs*dRd|l<7K2 zNwvM8g(5TD#eiyt_xK@@pmje89&{dpDa}GlacXC^s?iT(VwGrk+fVUUhguv;uZxF- z1VjOzy%Wgx&DN4?Gz8yeN-OSoa_f~B=$H8pUL&4aw}%q{%41B(FEufc2ug>U*}x(W z#T3`#U%$RC@=GG@G%ZWKh`nmA;>s(GHOQ+Wot?i`wzsw_F3I+%??|@dpFe-D0o*$M zOW$<`Ni=M=2iv;2*04a!KW$z5qqF4|gD+o$cT_%b{}Lx8#6AxsXAw6Zc5GH=101%N zizHt*Yk0W#Xc6P(56H^0@WV5JI4mjA5X2y%6@8>2q=4du?U7N{y)7q+ zjnd`s6|zLv#lwye28pYCs-N=0t-gJ159F=M-pWLmq0c*TnpTDsb`=&Dk`z&61)M?M zuFUYBdqiIx#g_B88xNbmeBs_I%1%W4(SI`oF`=~4fXcM8K-(bb_qiKwr=JcngvQsp zOcDcibn~_3zyUuuhJ)=9`^uG{2l$Cjz$k5D?^nwq7bfcJNSs>0%-ekUc!0!&ha;}N zI*fXdr8+jDRpA;2(hy1+9g*okn$TCR<9H(b!WC%xe`_osXh}i4tD6qW%55pW{-&+l z43!M`fpBW~M;hhTcjkZQ(G+1o0?4WA8ED7uNfEmb_V-Qads5EP({o)@it73{TZNqV zv*R@OxHOUq92Lb*nRp37WCxk~R75l%wd-l~saT7tY?Uxq)dW6uQo*H!(`o|Z?2ewg zGm${w8EF0cAXgdk*@TGQSSYw`9a&6XH$e2M-!|AH*-MLP(RO$TBvCW&OtQqOrTHa6 z8`v^5T`sxSm&!xpd=p82^r)%3&ro|)AtMx@(zm_=6l1HB!}UQr2r&1(cVu_posG`0 z4A0c4c0;zWy+wQ_G`n;I29~6(H#NI*&6n)VTj2UIME8CfRQPwoFttq&3B;Ge`D_aoR?^lIij#@vwl)v>UrP9#ZeHvqb2N;N(M!t?X zA-p=)I4Z~Q7h{ryB(|{M$$t)8=eO72K2qXyWT{?RQ!~PIeU@fpw;b~Teo4iPu=Q=U z(9e)!3=^ugF=kqUTKV9KUvZ6lm?Y{gQ}+9ta+=Mx$Vb~RO26r!t$9?O z(jrcUlCjp;LoAkExBONaIX9Uo;Y`dQR$AJo6EW>BbDYUy^6ASNYAfl*-7nTs@yY{9 z+zjW6=&b00^=x0YWU*Z5NmxQt(3IS(p&BuwOI5@$3OIf5>CYKzqY|i@4HJr9hZ|> zbCv`xFl|3w{W>8u-^9Avfrju0FPXL`;BJVY-R?<$HTs54Dx33L*$oa^UJ7~7WLuj#(-=y^p!DXd{t(%?J-UI}@RHX^ag1NCp z(3g3++;gkQyy^j)S{P6?W!R-@W^3QBlp0h)ZO?N!FZGj3beVS848t<*?Vf`BHEJ_c zV;)Y?KfD`&VT<>xGp@YBk=B|0UI+ss^FV=oo1q7r58ZZspvqje*BHD(k=&W}S*;yH zDyOPEXfquSPY#a>pr#6YXcifeHqKvr-;l++iDprt|KZNEeP8-rD?h@O-LhCk_`k$E z%J=&Bp;pr@V81Fk1X+{CH6+*7#afydhM_3urMv3*)VM=h^r=Bb?rO7gX!m)}(7@1LoB3%-)O4&|Wuw96ya8 zwAYI!F&;o6&~$9i*#Qt#D=DiqqiX0^IrnQ{Sb8Ui##~`;mHmV!PMjj<;w@|>o(%O6 z)U)gu-s|S)Y36C`c$D^HyqBB!#md*-nG-B9iIKUwWtnrs+5=?4m+z1SPk}#Kqtr=< z1C&7qyvtSU_v8`Xt`lDDBc*m)}C!bBE@x*&y$pM~?Moj+0MbRc*^3*2fmDM?_1%s{7!!joIu10jNa|dr~PT zK%!+jCcs3vm7U3Fsz;gLi=(aSD_&z%rGnFfwYy`6BiyWg>Ke+cUwT%u^Dd}WI>)D& z1x9J4x&O7tX~BIYtdgwBN;J zvwjHFpzv?Ky$B22G$`4=L1VWdw|qr!g!jJNmx^HLm#y359%~E8TuVVD-`=a*%ZHHz zFGT04%VxFOR0zouPK#FXrr-uucXCQ4xH&!{=!?yJun`Y!6Cx6>BG-{9dY%xP@1Kz2dNtk; zL8qQIF?lgZ(8=MPAd-cp=)-2L+wf`nSQ?ZJf9H`{?nS;$mNZ70+<=K`i=D(Y$3n%h zfV4bWjKIdEAeF_ZyfMJG0`C;(mOva~@MpNHnsXm5LtAujv`xQA4C~I)xS`q5hFK9X z`iePkXf8Sz8vZ8a9M3*-Coqbe)TfQo?@!KtR6@S@(@3WRl>rat(9`R$Kx zt+f9PFCs*bk;pJ}r>%AdLoJfL6q0Ok>E=VRwj!eewXBM0hHt06w>rLwCtnq26LubF z$kWY!#*E~i|1fdry@se}?4f*dnaOJk#K7-;AtGs)CF%>0#gzFUaOUck4(J3as2$_+ zSl^Ie;nm^uc|Ne2-5I=ct=N;^uv~iMXNa0}1W1Le#tB)nH3ypMM?a?B7J2FKzqHr9 zB*-PHJdpF471~-Nz+1{R=#Gi?9TeI#d`5qC?%+qvSsNNNC*`KJ`oG)GpwYG_^{*=< zb!yO1%v0q(9yuJY2Xv^3Dmz_*7*lQCE56OuZ`2S6niHLU=2Ijbx}AjSC)>B`Y#}Hz zoht&!P0Mslj5?)B-p-7V>VWO}ezkertqB*jfmAvOyG|K48amE>I^eQQ@!kdS&}^rV z=X)WVyg=#8Qo`RlCAMm`3FlX(GFK!@tq&wjuJwsk3_ zs;QKWkuoIlH07y5=i;a9EQxpR`X}d~`w$Y#O4R7ZoQGQjI-f|KNT!NOcG%xRt~_Wk z`>EZ_^j!Lqjm0~^{CQn<5C70LW46HnHU3LOH&BRB zvo!XL&OF^J-*D&jh{AR--H5yYF?NW8r`8=wSU*Z_{^R7D`mFU^RZSU(|*(<~VOS(`QT#1j~t4ohH1vS)?yu$Xt2dh^4R$Y8edopXn=KB2~4b?pOd(BjF*b1^)SxyG0QtCv%h z>5^7%b6P~Jk5p+ZRZ{0fs`pn~c2EfJnYQQ8r$SRoNzYRkXHhDmb!zdIRn(4(cH`ym zvFi=Om(8C}U3%2j(6xXu`^$Tc5yE#%tj)XAsW-k;O9hE=R1p0l>we(gB^`5B)cIIZ zE80y<*6>mh1sU(aF3kLv!q|%g@@+k)662NOl9Fx(+n~o(t@l#LyG{;>Sm{YJDQMa7 zbw>w?pVnbxq^|9;{u9Me*JvUnuzfP}#(cF5m(tj<^VXqy*-$(U9o~PiBc;*b6v}~* zEs_zg1}v@(J-=T@e3aa$;<2_*}sA8v@{a1kr2nM791XiSJhqqLZ{4*-_YI?s^k|~1ybmhva9s&P53mm}4az4D7db19 zk$t9@>B_s67(QI(wN}^kQtnG&@F2tDlTH7pQkwZ8-NzgFGv^N#4uXR&qqq7Zl^j@R zUUu^~t%oBEk$tr$9*H=Af=s5BOVY(n4}U-Zj=pP3&UtS0>plHA+f+M+!!scVIgc|w z@bE@mh~+M&3>`Ef93jy4_}iEsx*5<3SzcujcM1LN@Hc(M`NP`^`DmQM-RILs2ko`< zrKsm?ZgYohg-p;oJ`TbuW%!S@R@S4M9OoZ)bE<(6rrnnTU?2?DWP;_xXud{r}gdnQ_BrEPp3tbIUX}H zHgOW(Njc)bNmQp4v2!@Qq_-LNG%9hT+OMIAnTAq=HWTgs%}0x*JE}ow-qLQDvBMLp zPn}oJ?JThW&GCJ_kZtCOo2W%4|B+*Licujb1}TK-gx3iBh!wi#_g%3lchDygSECdo zf=K8l*8G}(SeQvX>lMCRnB12p`h{vomag!6+Wjb|#(qtxds5q7*W_|`+g~*GsH{C@ zh;997Qhj}WzoXNCUAWo4y_{BEQ-TitqpRc|nz3#MCZ=)O&gvhhc5g0vq-{4lE-cQ) ziQ@=HRu4vn4LHjYqxQqlG16#MDr)7}rExQ)p^5&?C~s7QsPxwyCbr_%*SOSF1UWv~ z>#_pH2Li*%i#;YH$Pr77ujsLOX`~3$Y%Ku zud`bm+rOty{81rk?lm3r<>+(`TeCAnvdu?G!y zxyY6HCXJt(orT4Lr>iNT?et$$-5%2#7@H|dPKT;vy3lo>PRJ@^PPVJ*zb7^rhnl`b z74vtgB^Op4&vA4;BT75moVotn>$*bITEUEDjNGKXW_K#~ z`d)3A+H``*PG8Pmi%LKsS}D=!HKX&yn_6*1flKc2aI}7k@v)WJwr&E)-WQ}#%!OJY za}o1iF5j*&nfSxOO;T$Um4;!cU=y&+NdpDVcIb>)h2A7uKT*5$2McY5g`VFjL)G)e z&96>*zMT)IgmC$5mTD(R)83>JK{bXgOeMrqTow);evY?Lm;*|m0<~iVr%->B8u6k{ zfskN6bK5ycoIx_K`&FzcRjd&yv@CZvqGKpFZVjSk{iv1O@w0r}|M`mJ45*U@^%$s_ zPt7Pp)Ty8fWKTYy2~joJTYTmY&@_E^P-TQJDb_#M=jmp!#b%O4*LgYVHG^Hqqu{fI^va9o6C5AE=DZA!eRFfBhyPp2PsNa*k^I2f*1D3NW2Qt zKIL35{F>$Z%FjzTMKHci$_cMuw^i`L@(Xq~+457D@t9NTW0?`l?{dDyXWl1Y09EBOE{<0CxsVQjzfg+7=~~3$4`=AlkQJG56*I=cfIP(ImZP z3=I$zxT_ov>0y zO1;9N=ivX9LjDi4$9_jub%6L2cs4tLAdb<>`(B}OGbv*Z($;6CS~IJvs-`bSv^|Hz zK?W;k{mb8&(SsEXqy6Rig){T;sDcV{zF<8iqvZ9wckgao;e`?m<(I}@){sMX2d#e` ze|u<5%ynjF<_%I79>ls!9?>664?U;lNJ>hI3!r2W*97^at=Cae^OOHP{v!q_Nu>eT zHG|!aPF^#B77a@zF|;*+uwDJ&pFYV^qW^ILGh89sr4@5X&(SWF5p?iK zQLF}lZ>7|JpAs)L={?-^jF;dj8S?H-H3#NyMry%ioz#oH*g4pZ}!cg~of0YrFGl=yZrDU>O(waT>BV zL+ukK-8I-$;?l7rK_MaC8{+d+_^qu-2!Uz&p8VMlI?JR6 zzJ8r>3f5Ji@mESiz;Sg{EEe{0SDcU%FMdpylCZWXs6x)!8;{bpc4CpwxR#y>%ht&jv$p4_MB%s zBH`P0DNy0CW*Y|t5dGtOss1q7|7=4Nx_+2F7n_P<4@saa))YX!f5%RbYb2+*oQ@sX z+}`e<%(#Z)`^Wvr!3sMmE&xp{$o5s4-mwvMqf>baKkl$n#@l~z{4PgO?nLF!vJZ3WED(cz)@z|FA2mqsXLV{oxl-&=VX=f(o z120CB8a&{?Gai>%RTQMlQTqMk7Bn-19H@YC)A6AS$E>SYuYTXpgA&TQ^XIPuk#(3t z@MTMB)y?uJ|7e1ANGnCE?k*1%Uz3#7(}0f;c5;%L1k>F*wJX{?P4c?`qXiW;JH|`3 zUsJs`pi9ameyO`+SnH{grzb`$?vzbxAMI*dDE#LYTc(0+OY9Dq`fD5#MHapnO50aOSCViyY08EVPW8U;@pMh)arZA|`g?zZdQ zh3v;FuO<5sD@eyCH8u4rAK!iH{hzX+8VmVs6xToRb&nJgPpEs7gn$#nNxGs3bXLQk zIIx*LCjWS4i4Ji}OB>Yg&e6q6d6aq|0!sIu{~3mK&G#B_d7<2GAfCGXe+*Y<)p_|l zf2@do5a)%w8Hxwp@s@;o8#AY~TQ501D#XNTkUi$f2`Dv%f977_J?JLcx z^qNJccS(%LM~@zr+-^Po54XOV2=zpjYrf}tGtFDLLktWIq6}QMULIVD;Y!ph+xlB)=gVlzT`7=A-KG}aBV=d@4lawq--2q8n+d4=`M-RsIL^cd zgah5~e_!NnP1vqjR?yrIhsyV3aU4tPp(}1qMW^7&^8|6|b)jVJQceJGVJIM06nxnK zw%4SBwHY7*#j*XZt^U~Gibb2eMMda|&d$!W`?{wZxn@8a>rGi%*{|O1EL8^csiAu1 zgtkgRJHeg(-%h|gawn)XJAlP+H=mJpzi(rcLoe=h2U17QRb_7LQx!FLA_6zC7+yeM zkgBnrYl5WPA1XDf;JN&l2giba*|xU$?W2J6qUH%o%4h(Bk}4Y{Tu1^iT(cC>2qNKj zNoX4;Rotkk#Mog7wEyvkz?r>nLJDC>cO8T=|ME8EW)k45WfD%zGzrZ@Jp!ppb zdxp;;5&oWQ1}KdMtopAX*z9x~5@Bs*!4H%3fjcgOAD(8)Yd&R47P|wHw<#3&G(eik zaxgEkys~m`+n7rIOa+wQxj@DK#fumJ8Y9);#uysl|LRpci0*6}f?xArJM{(j5EkNX zLP8Ek3h%G2rlIk+siox}C|h0=6%{R`@qY~;B24_hy_2*8%x=k}eL#Fv)QCnj8XFs% zLP7T2g$vg}KZHh24Kr$Rwc}V!^!c-AuXuZVSJYf5y~!r|zmJC&e5|mhCb<<_HtPmr zXoVxTV{2*9tp3m6H2`Px>jwbZ68_@YsYM!?a4NCCeOqq9$gTr$Gc!=S7l0l=Da;Mh zA5qOp|NArKEaepyJHe1bVW9Ydf!pLU2-JcjfKZm;2X_U)O7L(QbX@w^0<(}bx4rg0 zc^+&H7Cr4{InaUT3^Ong8dWZ~9QWVd;^Ac`J>=Kk|J%2YLvTj|kRL|r>FaN;%@<>& z!_B|MA@gpM{$8C2HcCX{A=K{m-AGWU6P`i%+SYYm7UNEZqj#5;UT3^!VVQq%{POLH z)O(icxf$O+<~|tfuJ~q!Nr~4uTDbOd_?t#&p=nzBi=#SJ=guAN9htx+R^Jo?H1VYk zuZifvincCEoTMP@f#l(S(uB|9f$I!VDHFi57`}rGVDBSP3+z^iQAxF&VUi94+cyQ0 z?=67O`O{&xLuygwMkuIyJps(H+ic{co?0)0VvU#_Ix;7R3l{E28d_TB&Yk02+}yo+ z`Vz`+ZRn$JHS#|Lw)H z-Kqe-=B>t^d?eXxn-&00`}O%Bp?RQNHLPR`eA!p8UNy^(Yy27{OqxIlOolT2f@XC_ zRu=2kt4F~Gw?K*t3CSsP??g}gp7guauwZxcOBUwmcS6e|NVEC+-$!}DzKCZZTJ1iA z24h%U+)0xO8JNF6q9Fbms}hku*nH6c@zENy{jcey`u8QfF%JHkllhyQ>q~?A*xjuS zG3E)un@@XwFxxPYW`k-Bt&-3tDhz)9g?Lf*^~l)RfVQ?fo-k?JfYu{Q^TG{^;#O5t zQv(RcB(u%6U*DoF__u9wBWXtW6>LN0MDYudK=}+Z)0?PxcjU8Yf9B`&0uO#*OE4Yc zCHJ*oQ*s2JHBH)rny?|8!#zKqrK1ak1vdd}2aUo}?PZbpfe4NVJrFOkjLQ7_PDjAs z1{o0+xm8UkG}G+Ztpj+edtHGQkFY5#jOX1m?HbEh64NI!u+ zZ3>*}az|_kJZQ-}gkJ0%9F%8BM@0hEaSvx*_~4PZ~hlI~9O^Eg&dZ2z~1MSO#k9@U;;oYF7t`&j7WggnYsGp`jGh z_P6o{8NVLrg!tQJs>#V6g#<}3Lc7371@tJ2pOWO~ zFT8~}F){J2ufG+GT_d*W33 zv(6X;+FTi-fsN4TyS72KKh}&W|Gp1_^M$f6eQ^o;34T)`NZNOyAe9VGbO}Xm}0ej2&1~)f8A+ zSpHCFPj$*%0_BQzsQ*hYe#s!r7gjlvb3{J~jYxR;iPLh=W8ud}QgOa18a#o<;o-{{ zGq@OsU0}&BFoAy|uBbPT6R{h;9zlq}1VLZ_Ja~#jq=5bP>o;frnn1NYFun)N zf#S5U3RsOq-F{wyU6_lY^x;0Z3>n1VMMOkAH`>`@^LqEkD;=s0;~|H7Hu|jp&)3i7 zUMgOZ=3y+epHQ$2>?$4+9${*mcKi+30$$+yl^sj|I{$JyYh&aDIRz;JNlJYvFwoF)3SXgV2Ks)#B zPWTQWQ`_0>*wQ`NuU?(s4IHamR#=SG)I{dIAfuqG9~joMpwX*!pylW1-*YWl>Q`tz z!_W)1Q(w@aUmq4B+btBA1v{e=aBa`#x@Z$?9$uOmz5wyFB0!b4Q1Q@-=l`m?k)T6E zvMQ-lFMnB;b@oSlB~Ehk@|GqlwV|L`MEOLvjf@nHAZRj@ivr>)Emff#xe-vhg_d90 zuClSEg2K_y)z#oRH6j1t5{gyxv2P|7_7l=Jqvce9KYpcaB9bWoV|F&fnkVoa$*Nvi zbB?uV8T=lREOx`D@AE8S9X6Cfe$Cxq=jzp8CU~7ae)4CgzDi?AqQuXJCQ7G}@*EL! zY7r)2t>`1G^=fq?$(UNyc6vUKCaXQ_>WW9yU}nCzyPsK@D+kpC*ngrbO-oXa!auus7za{&)z2X}H()~I|TrS2G{c^jhE>Qh-R0GL%e7S;I zuUxrhkzEiFkIt#m*|YD52&BLhq^G4&=R-n5+z7d4B{W0B!^8|Eo%uociMX_~aJ&%= z@yFU4+K=M$V%Ke`i78gdFks8>O+SIxrlqAlPC+UE>>1yHe~u!UfL;iKkCKrs>Yd;9Qgztp z(XV`Ii?DC3e&>Gt)G1lnK|eS5`OcrKixgRls`5p-zc#2RPjhSQGz1|-*7d<*`C<58 zz}jv)HVh4kVF=NfGrQt+baVzL;lB>>>%R`LfhW8@lh~QQM9_GBpDQN7qLH6PyMwxd zB5W&M@V}v8LDeSd3m9M{fMID@7+>SMr#t@`Db`{;@`?LxNi;k-BK*@&NUzmsHN&m_ z2DP;a?%=PRj0GMs>!(t^18>N?F`$IGqxe+&`U`XN1<#+H(fRLGMucN_&;j$`3t2m~ zqxdWRH0*dO7D2SAaeo)LHBkYSu|~kZK)UunXbO*iJ>-G4BVCWA7ig3G%d-D^foKUG zSEt||;8H7i)*$oJ-*1UOY{^VDL6j=@aY=_`=AWOg$L`YI6gl1+!srVgRwaHuB#c!d z6~J+D?=ae-r1u1j^Ub}FMk2g=KOmR=cLe^jcM(!FR#&7PV7ZUAZAUH`gR zn#tqKcSFncTeeQGdaU1k~VNT4HsnqqRH^c^66r4kw8vc}49y zuEn8|k*}(BT(|HW_&y>iF|w7>b~#AYtT5s2Nr2jj8}4hR$6_0}@IH9_;RG?q=Ir_Z-sHt^~~Ft+|oSVg4c*GQX4#&XKx(C^@>TQz|RM>I*nRGb~;KyU!* zjsBg_P|e~yAS{UE<+jbjGgbIzW|`;LCYZWayWPjt=5m$g6cnt`k3T)5>g(%!Vr?A= zr`ZT1B|t+_!QFh)whD~=b#_>A(g)WB4o-rY&^iF|uLyBp0K?P#e*VGU#2`4mKQ}gH z;36-oTYbDIB$pi05@5pa#E1g}s9vh41Kdy4d3kx+4~s8CQ|C_o#rUM85JU9g8|qfI zE0Ai#KDs05CAhh{)!#c@ z6BUz4@l&GEC%3V+)qm&3hUdfyLJ0c|I8B>co2_XgZ2=-G`QcGMFiO~sRf-~~aeHApasogHbqR$% zWZdWd9P)Bhg)CPTeR@u{`KN!TFZdv08p5;vKL~kurNKr0q7I6bmMUg?#$?2xCiE&s$L=J<& zz%eD>DED3=tASe}OxRoP?pQA5{MFmW!X#_N>PAH!=le(CGk+9(&-$6wDLGNX=gj-} z?<-aM6!i7@F9=eIuQb;4eQ=(}@e6X0t9lC6na4ISYB< zB`|adR&m5v9c+@*#^O;r>v+jEMQ;NZ9%)sN{xU!0k#9uEcp9WhP~8-9`$ z4*vZxlBWJ(bLM^c>!8<74Tp?!+S)NL>p`2RZT^^Zx`?Th&l8tITCm3qVh&qa6CC3+6yQor5Ys!$j7+j%5H&ktg_f5?mCTb6+P!7$K(jj zH{~&&>e#wFXT?t(I)(p+rn&}{6VIzR;gkh_0UMZ2xL(+ty|1=Pl_wa4?tuJet5TCJEiZZ zIjCD20l(@V?)WigZXYa0g5PmYd3n587oWHsjjfVIBkj??in^3Q!TzAFHi`Ns`GeY+ zRBYIc7b}A1ii+Oc+s>sA1#k_itAbf1edb8fRk`9&)9gXH>H4|EUFM}kv$6b}QVU%& z1Kvum9u}V^hFt-g7s4H1I!_Q26nro-(pQo(czLh%=2L4r>m58^@yU}b2_Gd`B?a^> zG=ZCmfg@VOsk!G4+o?c!h!4hI( zv%{0KVkD0V5>|x{v-hN;uZ)ePyz$MWh-!7Vo&PYB7#j1Ztp6D!%&OGzwAt8tp&{DR zCz8Nl641FG>Mnfh1VkZfy$PT*FV!QB$9CGTdcW*&nhNxJg1bs@kv>99JJZ2(upxTNLv8G&hg{Ndv;}Cz50&_ z<&c5fI?60@YY1mi=!jLd8LF1ADheHE^Lji`bx#CQaQGV+7xyPct)l$R)|Ml62itTc z@kg9&y5Qx!G7g*!Nw;~)j0CXs8fa-Dg9h|ou`fj-kLUhu!<~>i_og$N*FwZOHf3X@ zCwg5bpXP_=*uwLrxLNBAe-eG7z|)w5I+J#f6l^4;8#ve2{1 z@0PNC0JF3IX_7rLm!;Um)V9jspL~CBX8~oWGiaSdmt~P|{UBM)gbg}cGSLge-yg=i zKoYRzL8s@%1wx;WS)QMhvKZ5qrFJv@l7u5?GjAfr9$hK6nGx#_^{C0w*C~VL# zq4+5fT0FPNYAX!Gk%3F`&DyksKa3EK?{5mAo}8PD^2%f86^k!l)^%TNBPa}f8q8Kt zyETF$1=fFetMJ+Rg&dT;OS$2^Y$m{~x3lkq7^G#8nbRn<8ag>XR%4{TH_mlV$B}Dn zsJnaBfEux@yB%j~nJ!{K+E0j}9b3&EQy+U@DXba$fFve<({|u|gd)X0OFHe zP3v;AgHNHWL%`Kiy*+F_Ji+8tqoPB7uoPhE%(yu$WbJ%Vu{jGV$ccFBspb9X-5)55 z?syTW_-L-jFMzRp!Q$;RCnveA?nJ&PKYm+T5HOU)PIs)BbhkVqd8%bD3{%~$3vo`C z3&ewc=ejoOaIE14#;JaK6~3Q5vyFJ+1j@ z7Y~!Ap$xoV4rMPmr4P63x(e2DxJHODdV%d&#(iuCm!W$-U4+JIJ22FX1ADp_m{t#V zk26z@PE0TXB)@N|CT>p@W;=9ix36ge>Pud{=P!ySK`U2}BYh2O3&j#wUR?`b4pI8w zy`0fByD74wTI~U5*xVzp0|I&x;h9`Z)u7P(B5$mcEC=zp(EUgPO8xoeTEm>X9@?0=tO4NYN}IUnWA{oH>dmmD+1wo-U0o4@8JcW;$1ZLy;12izwF9w=-_N=D^yM{Qr{e%Sr{ zc?n(Kl^BAkM>O_bGNRE3f$yuE4 zst8cBU;6%@)xZbm{K;~RtW>xZ#oa}?+Zdws`l}Go#Nl#lTg?p0Z{F6S<_WF@h)4E< z#)GvrV)u1hiCKp?-CDpJd>Q&XQWN!t(>DvDU*S9eF?=ki`X&L{@tVne|4-<3`7!*> z`kDQ72(z#MJ4HO>@F~Zo*o|_5B@g{Jajw$_*@AVmNKVb1cQrbdg*J}ew5$SIW{|Dfh=`tOxzw$goEdk92fNllB)}Q4i#(**@KD; zqmHq?Nsbiz2c~D*7QTNKZ}gg@6m&KZlBA5CT%QW$U3|PgMWo#q6+y=0Sq?K7F(+e0 zCz|!z33tZxHw2l%753?mm)+FZYkttO_-bMVu%s3Gic>5ZL1G`st6cgF?jWKjn_DY9F`3ESJ-719O}B`xooQI5M~8R!u%k{C7~ zG>w<|<3SW}Ox-Q~M0r`uLN%^P%Zy1>t>xC9x3LC`u>DZb5BCNXgYuC5z`($8KZ&gL z55u$#Bp#+ohn+|8=d9F5c|JAGMx{;9yM`KfWw{9ZfAZl;`WUHa zJ-1H#IE!8$us;rdXA2`weBK4MJM|#g%MX;PiIXhFJ!W4%bOq3EY@AK>v728i#2WLn zKRuJ_E%b1(v_puIu({%^{ygo+aJ>+wqT97-b$&mhUj6xTN=i&|Koin%?x{hpmVw4#U;ZQj1BMS~6JCYp@!*;DlT`L^07p#JSQ7=TX!?Z}ST8${izBK;UDV^jB6MV@MtCJPT~=vONh`mcN(Ej%0R)hB6WtUq4cB ztWe0a&ZaOe>l}?*LD;tfm2aUd#z5c40BYHZMm*NtUY?$x%9QHHD=e~vcP?~l&5PUY z;vOm1z9}?m`8?ijFc^&8bMx6Zlyf_(5OnEzPfw3ze0kSzhQ)RibKS9l1qFOk-3}}F zEvGW25ksm&b$-z?%dL=Nx2B2q+IDR}Xh*&^q$G&PL)ak_UqtD^I>;PZar1B&s3@p36_gGFQX@@zAYj>o zND~z>p(#}b66qy0l_Jt>=tz(fLg*xPz8UmJ35OB0-*S>nSb&(=oZj2ivPfliJ-lD0Ux4x{d5-Bz1Ew$G7MJYOOWe)0W zuYCA2k25VTZj6f>yS6vm!xYzY5{4@(c`o+5*Y|=TN)yk~W47Tds0kuUM8%X%OG~S# za>OfU1uMDzfALP6v}oiWtxa=zku>AZn&+bj4jg#9-U3_l*eQbI{H;_!!7G;0d88{r zS9;E;c-En7^Ny!nQfFttDsr_2l>LmIPMOVj8aa`9_v;YZ$I^mos;Y({yS1eT%DswD z5b@zB%(TuEMNG^Ms`nqe-DAo57`&fxA4PK1l0Pb(zE^g^y0Cm>g;K1%>jIR9IO|s( zf|2+DW#QKkGRg5nSYk!q!_~EJQ9gCYT+b6F_Dn_l&U%AFfR8$+rKhJ$&oXV>F^)|6 zcV%8ydUj39g`72a@XyemGXxc45cBW0PB_EN_qC<66vrrBjVVA0a9mNW!rxJt*3Xc@ zAK70Cgu|B9Huw}%Wp87aAb9MC3sgw0Uw(!;A>g~jgj!l?M(&F`xlAWM<$B4xtw?DE zg6oSpplErI-wVBNkdV+zY54;pRp6&7=JX$~4qZ|BF6%Kr6)-y;Qqwl29n&7;)L-^^ z_FTWC&PkMjm? zV22TQ381Sfe1=~#oM9pAP6?`$E`=2RZgkIwC}V74y_VSG?5@_zIFs0YOR9%fXyjl+ zDSHlE+LiPDg)Z9w4_a((ij#qHML8E12w=weg5x{A`{SO-KS-&IvLHWCc@i4bG2FA< z-FQI4V^4`f>1~r1`KHy{`udBu7mtrN#s#MYM@^vSpLTMz5VV~fNKkpCzDx^ge)~VT zww9ep0_cSZX_sw*Cs_|jdOgd(50tiJ>0IjS&jdF{qRs3Bqc9y>9dWt%I(KO+kz6-z z74~Sk_Es%EUf#V+sMj8|_pItLlEVZr;o_6b%#`==OCHEH%zYRc8Clzu^`Tb%R#?p1 z^Rd|vU;Ltp4>N#SQp5c)z9sql(Tu?l{B7kiVSsui&)b6`Y`WWvrJvxg23GWZiGZB) z2hUAY>h;4&SPie>*>>(}78GF_%+9rXkiY2nAKZWnn>jkEzGB-4(VKCNe?m{b2SD!#j^JORh-e~rBW;u(ik0&jy;;_Z~aiOuD)W99Re zEE4r2a?z*ESThqGL$5O>ed}-F;W+uKjHYjDk!>bwTJppQQ}9i{Bde=Gw_9j#C4$&j zzPav%X8EeXK~%+|96A6}ml&WP3LXekwwV08t=%WY6O2upL>fiB#{369s*9HX1;|~j zf>F&M|LH~iHI1!xE(^trS?;i~v|OaM@|DV?%z=Eti`H#pZi8G|8;#A;$#BS6%nB?M z|D(Uyt<9jB&7PE>pD!PgXMJCgXAv9(DPMnY)S>r3APanOtJktuib zyoE+w_n-64FGP=8ZkDYVwcpVT$0rn-PeWY0nI-$l!o5|b;01?#9PJ?F9$IrNVVeo&3 zcE6+?A59CY!%l&d+(N6FH;&>mU#+RwDY{hlI-J}+(DvPu5kR7?WiuPeICU71x9!+- z4uVgb#ncxXrfFl12`XP!_EPI3h9ZuGC#1jFqir~@m(qEzbEYX)j{UsrqrI+zqXQu^ zN`42Fd}Xo4QtNHVf;0c-jQBC*msgr+uGJ?f3&4`n;XW{@-}-TVb(NAQmcp$6@+;wz z^}yGQ8h7`AzJJ8lWAF19&%rX~D^Xama-c{d+uOUp&%M$~)%ZARkmEw@GoW^7^B3Nt z8Zx49woH9Jb+b zLb-C|%0AH61Hmn5%008+zWs}j$d?yd1E_;UiM`yMPY){BSEPoFC(is-+sc?%GQ;;2C)Q4chNGh?Yc|IN~@5sWVv6cJwjl(JhN zh;{S7NTfC0Y0`!q6L!;s8@uFlrx8A9SB-6gzc@xOwgrass{V+P5Dj{v99xHDKh*Hn zH!`9SzfMMUAa7X${byGeI&j0(Fl|!6Tcg`%Dzk4sc2-!^7c*k`@_!0DZ) z_vLa%$59^L)^@X@F_HoJ1X17ORa-8+{>Dd%^hG&SLclg=*6}rWOtdiZ&&8<;ht|a- z!NK4+Wk96-O}{}Y$+t#$5!D?b7t58_uXSWiY{QS8Sd~^hVq!L(?d0Dx^P-F&wJ`Z$ zA3m&^sA5ic{s@`|BmDh~u>x}3cds33xF&p4ojpO)?glO=QUJnWchmb+4Zq{!2yTr} za!K4$NZS{@vbPUm3#D2pR@{{5J)NS)6_A9L8?=d<)GLj*9`r*GK}<>&7n*HzzK*!T zxz1zVgb5`NY7vnVyX;b0`B%!j%xtdJDWRH+EmUHn#)Kr~AU+ad!_FnXYBZYmh1!Db=G+x2%6Bj|5#$Qtj`R zvC0VHe?b~uX`nn&;C?6ZQ4epJS(67fPyr4QVw!W)@75t9IX?h1>k}M>qfVPXgs6C; z!Myd(oqNs+;kDixzq4(W`}bMlYD>!gN2|BWg$pwb>Vdpdmx|^_nscB?%1k($n`uFo zJ5k1QpaQUGV&q3x0K8i7NV-?5PVNyl%s*GVpRFu2OK_mr9qBtq78-AV*JdW4)8~KV z-u?^Hf8CynE!qj$-@Ub`ZSCr_Ig63eIA@Q0oqlVtRfQY$<#XzHnq^r$mewNAh%+1V zw^dgQu6hLE&GLOQetuQeeT4k9wNlC2)CTOQf&#qKAS|`uHC0iI1gbWXoTf)(%$AhS z%);lWOVc{E>i|}Aa0p`)|FO%(auM|+n^Vq)t9*6UWPKW@i!^DzHenbF z$#-k^eg3>{THDubQxA6&caB6fkpv6*^;SIgX`+hA&>?`lH zq?)h^Zd;7eVLmhN?9x(2g&v=Ach+8?Tw*uZoWh>@DyPAsOk(=WF@hC^GY+$lgX1v- z0^bxkIVm#V&aewm`|F68`I%d%jUE8_udmGAC?Tz0-^JnkQ^-fOuY&~iG8}tUC)W3{ zK@&SKRLm0?17hCG>gsJ{A`S%8b<~07p34g}02AHy%5Vp8YJO2#p>@>f8rZI*l8ErK@~uL%7mOWx z4jzYS8mz3({$gv7bJ!GiSLHwH#s~96CcDdc?1Ys>pkjuGILb^LmqY>$5-uJE}W!BqHi#KfsRGeX?O8=hg0gJooSN>y7~AJfb^RKZeqpfvr;zx4t{J; zk57JJa89skdX7PxbOW zN<=wI6^2(7!;@>izJs9v+Ud0|tUX<;KW|x3T|9lK@oD{s=y};}nptDk7w>0|CIoWR z@h@xGM27A6cZs~gmhLV486cK@4dEPCWfijm>#QuTC85pz&fYC`>4%(|d+(@zo6yuS z1{(KBbuN*)&$ma@+}E3SbgU%nub^e>m4EDcavqKmVPS z%W;)b&zCIjtMvVQtXqQoqHdhL(2$Wf5#T7eOWOb{|JjS25>3jg;jb$IrUsepCAK|m zY&D?xS$u0h=L>Kuu&xJ|fJ~eOQT}B*B#{I|!c5iIo2M)(+l(wBT9XCwcVDEFQ#d4I zR1SR(v?NZM%z_P99r0O>1Yz~Taz7gz8=!+z@LR0FTTroiS*VVQLi&JDQc}_p{4jWm zvsMcT!yrn69x=03W2PG`7yBdP+j@I>$_G{`g+Ll&G2)L4DO+8cYr^vg2!szs3@zCX zs?7qGSj|Q_O>L8F-NkP52LE8c=O7=Cj8i?`)w(HYbaeE9k|HnEHw!-EFTWp zgGmoE*(y~w=dWd$-WHrtw55`{&?4xwzf+1d_JXK7=0pL=VoHdVsu7rmqKYPH{9^*$Zw3KLl zqtT$ps!ric_N%C<%)(QSP9H%azICee*@4ny3dzEK?tnpl3}D6XOn%PxPkBaNmCEZ2 zZC=BnG9++!gu$v?)h%J;Iv+EEDxgkGJO#s66%eivq*A0$L0V5AE5s>Z7_E$t+iGZO zZQSl|Pqp!EXsmN8@w8N!`*Nh{tXZ+!34nS%>H+|Y?_!6Z3uK?Xdi83_ue+U7M_a2d zWh{+#a|z;se4c%?k7iTy<5y-Fh(-W>yUc_$4+CKa;l`(ym03~Aw4EHzBlz9q1ZQU~ZmWqm_x0jeb6Co0mBk&>wb z=auUt1_A!v-h5#h`s}IUS;$Bk%kpTPtnc@MXh%z1+Y7=vXhQe6%z&CnV|uA(6-y(7 zh_RT7`Pjt>F2K-sSrAp5UyU;S(p8nU7Ar|>zucxoAyb1`c%&;ksYaG{q6L+t_$qI+ znKpp9@~V7RS?;R^)DpkSBbDWxh_G6>Jq_cr5ltz{^OC__qG3g@qoYk<8m5MV1X=&E zBOwsiw6U@;36Yu#?lbM-I=#3*-ACG8bUtf_>j)@8LcoUqQhPl5$h+{g)cDc9)Xup0 zgfgxh#8M^E^_t{H0>A@#Jo?)o>F8+lDM;0;1hQ4NC<`=%>zukADnT7>ZzK2+TtzR> zXA?7w+0~wSL`~;d6_b^oVwgfPCi>JR? znKqTMIltjGRWwGb6D<#ctPp(&^JN$nh@gB>mJr!%ks_S3?iV}dN#to5)9S_07H7-( z!#}IBj(IN&Da##9Q_~tlzlt(C&xuSi2JD4$~S$0R@w}^LC}a(bRUa| zi10`dSW+~fm{dBPW|n(#BJ~|6b$*v!9Jxo-E*_1=19#=5 zFEx6>B)St*OfDGo;{j$)KYkrzEN*;?92P$n-#4N20{^E&&3IMI0bcI~bUSpq18gS8b(<&nA0+C(DuPWKVJwzl?ZTZv29w zOiy(Qdec*Q-fdNG?2PNY9qC+zAS(i~m>i@cr^);F>fi5q?j~0DT5`}f#5qMf(lsr1 z=J&0Y5B}8TMIa`wum|3Qe@6Z~&e|#;y#KX7V+C1tQ-Zc#!pb5L?JopbN8q0)HF=M> zRx%-=_OHwFw4iM_|K}0@rx*UW#=^RU<{Bh@gn)Hj1qD>V+TfEx+Ma8GEV-kA4aX>N zp7oe)u4G~iPy4GdJVT{t*H`H^3{F~QJ+KXfU}cVxlC(cwIz2o*4EWW3nVFd_?d^Yn zwnFImOtKLd7k|D=WY<=B6SNKU&uLMl8si1)DI!#HK{>n zFa)&wDjjXbNJ3#bM`5X?jLg{b5S2=83`A_rnU^qUxE)A+1Fg%?00u6+nOOmNWp?0i z#mZJVX#7)d#R_U20ZEbi%e-pasmXi)-7n%p@&Y^aZJ2!jJ#|B&t6sr;{~`MRAH4)! z<~Pm1QW;vWB2w4jK*g+3(AyJ7Zx0!b?M_TMw|h}S-;f#kvAVhkf5^ikt&}tP^ofg{ zA3Gl}O4;wk{6oW3m3Y9?njTghKU%@Rv+og|9zzn>QLH*cA8Nv!J z?0#sU*!rv>!s7+C{_#Jz|G(Jz%Gf0kF~g7~-~v#0P2Sf@SPlz!cPYq?XRoWP6FYmB z2ga9^&uIkWP#Kld&>aaS`KllZNXq51E$O8#b_tNVH8#IB#hv8>Fivo7ZEb$dZ?BIv zpogIPjujGxwexZ4Jd9&`;)`A|>1O2qi2t*dCJ=@dd%I`sOPjEnJ_a>d=fDtKWhDiK-}kh4ex3qX>Zz_)Ya4TRMg1Kf>L+OcVLY- zSUq@_v>fcUL7dn3D&O1I*5)!xsw#9Iy3l(By63|-n8B}uv8-kJ`J5nGP^G4)7o#kO z`Y)8A>CyxBFe}a}+WsJ{Jzl7kx za>WqSa+#?i9UUE)l?6M75c$S6$JU6zX)sbbeeQNFuGh@!8J&DNV5fZ+m9;bXYs#q* zfj{;difH9FV;qcs4>9h~K9E}5T>0wmQeaT|B;APQR=eZ;Z|n!Oj>zm2evQi;xuu@Y z$;6y{NiKKcg6P7)#+vWW#=&W|SLb|iP0VuS$F5~#u8qorFKm>({UIUIXFEKE4HOEv zX=Ie%*r>&_>tOO|lr@L{jf`kh-z!#DR^kE?kOwRY*~E%a2Mo2)qSjx^=pDp4fpLah zMJV4<`pu+#`|rQMP0CS$xZFw=d-*j#zcLgG1-${=w?|uhBDc4uW+q623BwtCXBI|xArQU-TiwR}W56#dG4>Tw40(+} z%%BtVs4a<; zc=~jgl%!;rCALQG;ze7)sxc}B>|o{fGD3RD$Dts7)(v=Ae2n!92j;j$jNkV48Lt|y z@ch~lMDqHmnUPUUBUEO5`0zLM(#OD)A|khd#(90+lO^b2Vu;JZmD-Yow-qBS(hm~L9t<0cr+Z0DrTy#1Zu*c=(mcy*WUtvxIroSD$T^;@X z=-!&5o2ie?rk9}*!UTORX-m-EpJwd8p+*;aJ33NUR!|(A923)LH*jo9Yv(#TItHc3 zpr+_VboojOe=YiAmRQyxrO+C`{DzIS+ft6i`_=on+PfnVUwzYh=r4or{^~1{jSixj9e6Z)irv${Uaf2I>$^+HvC9gMKHUi+)|W3| zEjWc+apTCH(^LL>BO@c&cqtRi3vmv9&Z+0|le_;m6vO3M3i9*cXJlwNmCObJ2F%jN zGp73_D8^VI@i*0{KZN8t4qjg0Hp{%c0z~1phJ<|H$o-u)pXYh7NJM<)jL2Y#N=FR*_HAoVpJ<3^J(9uTr zwA;y`OE4d^>2am`X-z=yku=4V^6c5(?N5qM408QCHk)qa@EFfS+CV+k+;T*Xs=<+? z$H;r5nCjaYIb8IrWD!748EsrDV*Sqdf$l9kW`0aa=+yBuU#jq*2*1v-nLXA4OYd~j z7RJig3s!Lh8i*G7`&4SWuA`F#$_28{te~ru#F+Kx!w;TS z1@~$D3vDGke4aO2)oWU26IJZv2FeH3->IDX&D!zmg$oaNpo@ed#oC*!9VLfnMWci(Xe>n8&% z=vl6+$!;YWDI9zvH*7r91T|kJw%!k2*t)<}Sl5l^l2(|b= z?$pNW=1Qs7%h(UXJ@xwplq?GU*4yz?o>RuhjvcKvKvR3LX=So0kQYiwkUxD|gJ~iL ziCp3Nb^VBcmz$vr`4BA-LL4a>&n=hmsS;@P)=$^Ncm5@y*-Vy5b6@DX-tSH{!7A8g z-_X&a(hC*;_O3c6=r{&abZ}#;;H2Vpdz-+R0Y&S2fU1;U%@KH&>F>9!9k)hGt_~N# z|6^FF3yCbYsD6S^{8g-BG+vZC4?Q&XoxMcu&QSxucy4L$kn{Kh0p-^QIX3SK()7T7 z#>%;-f)`(D`*s?Y*To;4R*WwHA&gz6q@^dmy?KO!$`m)Bncc>_+u<@XFJqHK1gvc* zyRxosnir>PU=rUbA9#NsG5TciAAjqHI>{Lr?6&>8DY=V_neWrnbNYQi6~3yWq1)KU zt4QmzyebfbgSqZ0N~HX4g8CY56klS@^P24fy$PD^+M4Ql>z#c!rnJn%m-xg5f;8C8 zvhUPx+LNpWL+wbT=pBrQ_EKitKEBCV%@sTXD{bliH`LSuKYjijDJ7xKSTj0vPqQ2p zuk2S}upb?M=52OLRCgk%L;Luq!1AE8?vmX;`?`pT5wj9uN)odH0@6n^x z-)(@Y<0&+l3Dg5}ysVclUCMIWQgTZ6Fy!cTb9;MoV&b3cvysXtVf_x~6mBgHahcp# zt_fLh9iXb}-nx|v%9@mv^t;qlRXrozdqUc3?<%I0G^!}=GY@eb>e?SZ=(bp1D{JeM zl9KJAc(5=)nM!BKd@p8+>Ehg6U9gVyJUsGYj@rFMdE!HljYyY--#3O?1l z%J@fLzIyeBv$L~u=3d4HngzBlpyXOyrt5k|EsVbJTiz{iR@^!B)b`c+VzcYilBdZ?J!TdV(R+*9vE!hCFej zXKx)eBhQ#=3WLjE=TSC;XIC;7BotvO@(A|=GQz*#tEk?tI4w;XPO7<>DFOh>yapjff55S&9KV;WjCJd z{IP#OX*6=nzWNr&c-=xZ8=EwHiv7*&*WZBe|9w)aiusT^P%K=#cQ2bd0MrJzHfok( z_P+->gdLfbvWt~9zjW(^BKqVRcgERhm9wz0oRq(j46z99gedg;s8LS%^r8G`4asEk zQy|`IBkP{`dr%$1mlVj4x_pp)aLQDE>)}lqs>yu{#^3}j$|y92(vxKw2+>|AdQeR1 zP>V_;hs04;AYi50E{^f=>@J`3%ebN+B)9n*J!J zd&pYw>mr5(96Dd)BQk-{#h&D^p?ml4X$hUJ6AM)s{cqe9>xZ#>yP&kS<_G0wAfLK=Z!6c-nlA09Iu3i-s_2RSmneY?GV`wlVD zA45y&;t#P0r!4LMA;X|qVFtb&#${mJc=$t+gXRnuj-wl2I6W?r+fk9ZtJ;lL@iy=ijsMBM>`&w&4&23)621A=vA~F|5$$g!X-C z?_>HMu?yN!(BA*^c*gxWezqCc<^0(`2W_sO$CttJ+)UfIo@W%=JU`o0(B}Q+I>&#u z8NI9cv(0#(8^0U_zan=2{85oNc5`xYHNI design_process.ps - -sliding_window.ps: sliding_window.tif - tiff2ps -s -e sliding_window.tif > sliding_window.ps - -expt_state.ps: expt_state.tif - tiff2ps -s -e expt_state.tif > expt_state.ps - -primality.ps: primality.tif - tiff2ps -s -e primality.tif > primality.ps - -design_process.pdf: design_process.ps - epstopdf design_process.ps - -sliding_window.pdf: sliding_window.ps - epstopdf sliding_window.ps - -expt_state.pdf: expt_state.ps - epstopdf expt_state.ps - -primality.pdf: primality.ps - epstopdf primality.ps - - -pses: sliding_window.ps expt_state.ps primality.ps design_process.ps -pdfes: sliding_window.pdf expt_state.pdf primality.pdf design_process.pdf - -clean: - rm -rf *.ps *.pdf .xvpics - \ No newline at end of file diff --git a/external/libtommath-0.42.0/pics/primality.tif b/external/libtommath-0.42.0/pics/primality.tif deleted file mode 100755 index 76d6be3fac2cc8b07a401e008fbe45f02758cef7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 85514 zcmeFZRah0;+CK^^U801v0@5WZEg=Zf-7x8x(%m5-QX<{m-3)Yg(G-|bNcFfXxtH3FJq^Y}jV#6*b(^zI+roeq3Tz;vagq(XCO?@>S931?x zFyM1H5$uO{{|{2*$@~93_xtlz_y7O;{~0$((cpa`q?%a#gKC9UO-=LfKDKXeni`zZ zneh;>*+^!Oc=x}5|NcS)qGT@(HsR?zQqqnny~i`Wb@HPf%1%4!u{MyHY{SmZPE&8H zs;sQM#_7|NqGMC2WX2wUVH`R46pYeYWQD$J9l1K*7|{-}mAx*Sn5%an;dgJSu8tls zELWXU?7ci(d5=T0es%>H4<dAQIWb81 z3bykM?6?wLi;j+ty!%g_Z=#D8|K4KE;F`sJgVW8W9hc96qeh8`kS}6vbckS*H|?y@%s#_% ztzw6;ceqm${cA_wOIur8{ofm1&dT1_q1)Kll$SkU*aGy{`n5q?rXnLFy)^_TWmF%7 z;hvvOCdFeVD0ULc%ga~3_wVtq$rg~jA zJ~lSC5MW+SVCZdNg3WZ`NBuZtg=GcY}VjDJU z75_~jD!k89g2UcC5qT1?OVq%xyZ41NJGV)Q2yG2bP3}qM&CS}XU-lY3?)XSP*x0b3 zV6TpkE454w8%OwxuN@T^78WYvJOW!x(FH6oDlXP;bUra7r3(oS4Gjs=YI1doKn%3d z8jq984o|SJzfmV8L}j@)yI4X%KnU!?Zg9I|@5MGOpXyt4K3#p(@v8Gq0NN0;hbtyT;90HBuY`_)xr?g&=3I0(PPP9Z^1)K6!x>}V9EDq|)$GU~s& z?%5>ip@>ab=jGM&)#cxwHQ$|l(Ow0gz2>`HX*@#L>vJn7Cno~~gIZK{czF2bH6U<) zx65Pj^+|xR)Z@VR<%zrVrO=WdI3;CeyV{>i2Q_pPH&k)Wn;VR3P>3>8-IPaQKeGdsJJqqV_&gOHGr(ZR^%goFxFh`PG^ zl?=SEcWAqAaZiK$4ZgdfVOEDj`BVWzI+r7@gnOQfqwW_l6q_FSul8c9H zV0(KTY~83gC^&fR+&ooA25!{X?ci7Y5%cD^6Jzc7V%Z~QUu|kNbi|(iMa+xD?_FJ8 zH7U)_{M&?6DA?@Mql%LZ3=DvbCjlQ1&s_yP7iiGLZ`kpJr_)Pb@LyeBxl}J(bJ`}X z(>FFYRyHRMt{I4t@HpL7tVBWoTryH&>s1y}xfc z$ytU=15L`wFCii#a>ErS4O5|Gw?b(ua&M}wMbf5;+?Jh`%N?Df&(6-K4u`Uql?dB8+O` z!JIK`-nhDaZ*fa#aBy&xEP?=f5QFc|^0M$Md6%YSA!&SnURU1Z^rbB>uf1tgq%hsm zoO*&c2oY%5N!7D0OZf1w%DPh?)#{2v}?z(BU9OU^vHR)RKW*z0E0cYRxQhJKtX%P8U5g7=_)v8>^4%k(QL~#?a8x zQp+z%OiH4#;N;^I;s258*;%8!RA0li;UE~9{0ixCwI#D8Q;s?|T!jutMXEq>2b%AV z66!~jZ=kD7x{Yd2bm6My|1cpTp~e~QP6wCA$jC?xR)hr)b3j6fGP<{W3+va)CY!>f zH-cU?VUM4`zkzVg6YKq-Qi>sZHNN4P0i8<_qmnJENO7^JeG&#T-m~aIR7~7oFk5)u zihM+ofWr`>!NZhLw|$+Jo&B4%wBqg0MuSPRe@Oc!>WfxrW@@@wt=`eunYkRojduYn zfl#10d3tsR5U#qaDx&k|n@X(q1q-X%up%D4Ex-Gi1=%@0(r( zIvu5wm9ul64~jM&jzQ&q4>nJ&hLniDg@v@pqa=?}^dujjhj?Wg9tx;z$mlF-f-;@rw&wxW}jpPK3g@U?x>?;%2V-F-Z6m#ifTDsa0m^(%k6 zODmz6pWbub%FT_Q?C|2qNVzz*6^92vRG2^u6O~V^5x*dU!_P~ahfVG`c~^m4KLK4w z8zYocW&n;2gm>ra?}ZcsBs?WKFgR$y;dF6maBo+@5`z%YLF`9Xk2Dd3oMf@k)cpw+ z9lht%en9R|PHyh-xku%k6DPd)G6SJq^xQHqGlfZaOaSaPM|kYM&f=0cs-`9;Vono* z*L>Jj5)?Kz@3|5gZ~_mjV?y(Js2cceqNk~iQKdfl%d@$j&z=zF_%12pENJ6somHyrnrj>g= zEY7!;gKR-_N~Ykk*-^mMoPVbN0H#Kxf#L}MYw9Y$)YjDi?z1OjeS?EbhH^WOX$@Nf z%*n_EyK(m56u0_SFk!2K$2gAjjX&{MV)hb4u7y zf&Z+*stP6Hztu7X#1lzKNCY8kI9ve^^!H0jPytFMcTzkZEm zOXFGq%VcYEcXqC${>FA@5UX6Q)iNo36a(+G}_WFD_jy$|u z1Ca^W@o>4jwY4>z*)H3H9v~ZV$iqWS`n9I-_1kq1T7@Iu;nKe=^hBOX{9C-%e{0TP zYW0_d(C$Nm3)kB&atpb7KC7bz#%BZs^^`Gjae0Z(@3E`G!=I`$NZc9Jes0$d-V-6k z)Xeenf<1Sks3h4jV^Emf1seL-R8e3mAnbb``%6RbHNjT~V)hJZKNU_O$i1SYqkDYX zm}`<{5h^2d4h{~ks&&fPd3kx++5Jdp_?emIxKE;JpfP*BX+$I>TY|9HB^?gw!#Olz z42cX8hyU9}-`HWp`3l0GMI~FbSn(wnAK1-0H8C8mC400E4i28(2b24D2038Gx8Wct zQY2NZ&}RlR10GM1`ci^4>{E8%x!3=klNgzDNJqcM#uVwx#*`*4^Dor)_ZNkvyFoz5k}`bI{c=2<%zJ6 zeesi%F85tV#ysR!SPv_VYwg#0C04bpME6%o5{kI(;_Cg10g;$ub9s6R_ppdg-5GIVsDl(z<2LxUZeu;s*QXYJ-*OzB`{ zV?!1g)o*C#T2o!EOo4VyzVnm@>hNz6WB-4}q2%RW5K7s}T(yBP{l*||n5to-)>Hg# z_R8nP!SH&Zre(&Na=9J;WMQAg6|#3JO_F6G^hG2U-OSMDNMfe7XUg6oB+S;xo7I3P^>H8-RaH@NYWeW%WG<$-TO>XhrsY= z)NWe0q{=CQ8=RhwL+x2!&Isz--i87XY7dOSz?13iS6D%e&7B=I5X2*NFgRJo#>NgW zdL}0&p>z9ag7j`^5hhnbTua0K?&hq7Wzufhx)y_?SgY}?-o$+f?6l1VibDFrAam6h zUR_%QLGFZ=yE_9}8Ib8X`Mvl3?H~Ul&%E{(fu^>$a+3^I1Jw}-P|guBi0=~tvheP8 zOPC6EBJ`E?VdML0tE#H>Iq*nGqA_FR;*hz0<_7xvgEtvz-hlcH7uTjIvid&M+`LEY zX=tZGacn{YD%fvlcXvQg*U3p`5F*I{67iqd&dN#_T|-Dn2(nhXH90dg!lCneeQz&% z?jyzm{NTz;CSeWJhcL{=diK;ezJIGuLSo_$(&zSHZR&t3&Uf(A4AJ43oIE_P#;s>_ z-Utr1%v5A#WXz;XOZS2DOt(HW^BWK)7HK^V5N;jNoA3hBnE@0kA@b-B?S5zN?Y=>X z&cQ*5nLa;Th$fP{K^klz1K9Ta$G!eR?^y98F&C5Jy(tr=dOsy3CDj$}ftd+XTmP0g zsGbZC3|O|vHG$%fq-6V&)e1GyBk5F`FPLJPa$JNxMFBnbF}~~;dIT5Nf4ka2h1(Z;{*#NdfL%yv%(k<`8R~vb zk!X*B`_&6J9i4kM7h9rIAJ+$>6Y-*4NndC{Q&M)7aD3KZVK`J@t>{$8ri~)w>EBWh zek|zy&?aqZDM|mwD?%N3UY4cF7Alr&C%{SYrNL4*fxEAW`QPQ zu?lM$TH6q1 zy-gC)j~@xI9q*43oROVPAYC^GHOFrQHhiGItf55KGlsW(Bx2^p>tX(}Z#ugi8O~wA z3YXqyeinhE*)5;qk&w%mHaLfHa&nbFG4~G$@CF~h{Cr35e0!9f)O=^pvwdD;FE%o14^)2ZvRGS zgJoA}L2S3%wQnLn1p5;*Fy@v_NwJ#=@2__` zvg9iqo}dy)6%C>`H(T&Tcq6&Q(?HwPj~)i#SeJD_z-&*;!aR zQ1VRM^TNVDpB=Hzg+BLYZtAL)$lslR6d&JVY2^yVB0Q=bkeQUBFN-QFnuYzaU^Kb9 z8pOdtNs%|~e^#54u!UE3V3iJ$mc%n*tA;!kbO)&amtO^%X!0V4J}E&#lCdCTHMEux zxX#)dCej#jycsy%`As7t_KEIco{BtApLZFW*j3PRDrIJq2s4L?=+;%Pi;djUJ^i^x z;jpObuW}!1U%y&>r#Kx~@2tqR)1}LmzrM#@Sf{RBGY)xA9^~DrOO#fUs9W%nenBp{|AeRvU!AI&@+Ar1 zpAdilNVkRKEPs&tA%uO!>@!SsdbN7KUvgljJ>&Lk`Lge|C0nSMm%ZYoxp|(i_ri?L z-pfr<_l1n3lx6)~E>miH|fjo~cS^)0$9gpTQ|sM&}gO z-MFP!qGC9FYW1V)8u!+Eo*wYChhBchm{B$cYQhvD$j+Y37+iPyq_K(p$LIE-iW)kC z7xaGr&0qJM&B^JwB@FaD48w0sP8lF$jXBxcZ?Pmf--nDbEhrBLQypF2#&OkF3AY*( z$9Pufw%S|C(qrZAUOA*|aBwtXRrU6ozSgjO_uWw~BOlyQX+7CV+C`q!BmkvEV_FQF4pB@2s5&Re8s zgc{Ndsa8E5?A+?Xe0}-P_a5B5%kmu-%JQxIYH~5V8uM5Vl{_6r-2$7iDZIf z4DpQ5@JHz-x#3&RLb&0WPDfb-6V+ADe6Bh8X{Qs~ynFMU#N)GQ>cDu;N!LKEJWJv+ zdQn%vdcL<1T)ya^m|6nl1bcJZk4Qy_&*mK4zpj((GngFQ!Oo%l!Q}ORZD^s?dnZ&1 z=EBq$=@7jP(vKBS{)3LvIKdXjy@w9NhbOUhX1GS>k&JmhO?*pm)sGh{TiQoYE`vxE zYHf!L)H01cnvLwnrk=_;T`S|_3CQj_$wJDJ=gcB@b~sT6ET9TJf~T8`gT2w%dq-i} zJ0H@W$e)bO=gl9P%KOqs=0&{2MzitYeB5#+J85aHsmJu_oya34g731s@^}HyxW;~^ zC0o~P3-I#UPY0RvY*d7e84WfhUSBzot${*<#z2>;Me&uSIv%sDinn+;$!T3uOkL52 zy}P@)ZE0JZDK_<1CSf3bEjI^V0sk4PURoGP*62UI+otHbLj zr}HQtg(mb?7#cOs@jMpf5&UFWLPjJ{st_*F{qhCf9KL+p*AK zPR28nBd5WHchCBl_DkYeQF$vQv8(cFvtP#?=3DP>Rb_uvO;ErI}eGUPMsfaeebA{z5Fpm*80Lp^4${8Z+6Q%RjQ4Xr-(1iq^(B zAg-5TVun9z8~P&4kdKof@Ceg4ovhQ+Q|t>J+ol&N84wb_P8~*}dLeRiGf+<3qgVGC z-meIu&1+D~*4>;HBeH_MuX9EL()R9U?+X4W83}%5-~*)c2SORL+EUR?N926_E4yY+ z>@rt!I#{?&^~bh8=GP(<SbYI1a>C6XP}}DuKA?I zSZ%Gs&Ma_ny)B(ALMAXg&TGlHhU^xjz|BnVXO=7ixMs2i_1U^OqxabC$_Rso!5u8T zAC_%wM`ya@^GiNh5Co&e4hvDaS`^DZu8hh#zh*;j*JZG${+?aUso3o zmKu*9@J(on9u0jE;+>=pm&%?|gtX0-K~JC6=-2YO9cGr)N`-JKU=9o9N&=2dup@WH zn{yh!4JA=#$?bdEuQ)kA5nK=wjHisi3cXM#r?=WUOXa)UA`kEAKG0TuZ@gCb+5Kfo zrL?;%bh&(&*=?Z-Pn!hqRg;!Owi<4o*?oa^Fgbsft9GK=PqPO8Y2~9FDcWe3ABT1D z&tGH^|DA4P>ax{{DTPzB<=53PWo6n`r?sI~U0;qy9Gukc^;U#H$776jI(Gb33b+KW zj-=Nxj>o^gdxqJvU95@4-Z#x8>hr>WKc?jZwtTfkz$mGR?z<$1`|^?~nFz>QMEH_f za{G7975TlIo6MDc``i12WsA=C+^C@pmPSSKnPt<2gbKu&@_tp>{^*XygQp+}+jMd1 z7;!dUb2j$obsn{(CW^~1xj70Q9uO4?DmXnOfU5!OG@qXB@C@(SG><6Z+s^*Qxs{GU-ulu#L)5TyUw&Nr@c2)9UNgQHnoRs3E zr8YfBsL$EMRljEi$4w^e&38YVkO@`=*484~x)(KRlU?9m#3$Gi^L_M(WSL+nOvXup z;-v1dacs$SPCufQG%XzQ_>Mk!mcht*tFhy|$1};?dO7(onU!K0JK=-^3vM_WWX+zD`l<`C)j3Kd_Tu zqN&YYc<}SvE5aHjzBA;kY8#sYTIHUJIc$!1AW~1fuXrYH8Rnv!J`H$1KBLb0jD$l3 zqd32xGJGs!v3$xfY4+`Ja=U2iGV;?jBE+TObv9wNhv)E`nwyn=0B-JP6b zkY@(}m3XR1W`oUaWXMTbRh&IEw23*_p~<+OR0+49dN2+AOVI62wW*z5&~#tlYwvI6 zM%d-zSedQkwrY7LE7l^tAUim63VLE}!SwM7ae5jtuMQd6yxhXnE4jU$!UUxY#|AD2 zHcM+sqEp_7{>s3a?-cYC%v1NiL6dzppU(yG5&RH z>`G%`N(8}Z=ys*o)WNU#X5Ik^PA=Ek%4;!=`lza z$m$jr22U~?D=X?-{gA?#C+5AihLPjr)|}^3i!(ub$^}qwG%3LO_zgXz75(ZkGc9d& z^%$~kLIXQ271SB=ZTW=aBXt#~rucq*Sl>oBvqu%D zBhElv8XB64qVz#J3r(C8l9RpBkq@th+oh&vHP~FK_!#0O!8yQ#lY+M$rqEDwoNS)eCi)F zQoD)D!RH@)lV>ItyG1?1E;l)Jx{MOQ%`Jr+WpAx3yg%Q#S@Xzj_emJgpiO#NHvxg5 zX{=?9`3_5gT5SRPtdq-Y*QGic4#FM6YQiS z=p49m5U|;Q*8skoaw&rJJi)gi;sf+tbJWasRMm*U?*+!276l*dD>nG>gem-uQkFC~-@I^HXp$?DZY=_H?;>WM!p2GV(1j0;_)*0T2bm z`}Cq*uPc>nUx;q}Xfu+9QU3JW=`W>I_^viZ2x#gq-66Q9`~PFE;E2#AZ&Q%h<&)BV$a zkblSk7gr*^-aE0jTPzT&YZnvpILUqB*98*abe3DMq0G2tRKmIis(2vK`q&td))VfsA$OKT#hi4 zk=2=1ceG!BW6HV0MSbY_G(L^iyQ?-Nk?T$M53wa3Xx}^hn^ugXj`CWQj1V=sev!&# ze+;+GmCc_nE+VgFEvIC*kcX4bOXF>kKnnd*9&&{}y$&e9KMuFq6b&Wr<~*?gN8$r_ zuwf&00e`NyO^f4piavID+gLNE^g*+3p5g4u!_P%s{X;Rq?t{EyUxlpLgnn?ds5XM%%;cZdKB!*uvaYJ2_#riI02hJ)XO0?)R$dT99=i zXg$M&(9%Nf#!A}TL8J;t9X-+gbG?4eG=e!UY|2*N@ll$*2ADU((b05!cI}BF#6z3*wWQdnH+LiC>g0Vr zPH?aZ{o!`(oI@^SE}Ho10l3qY`l7yA9wiU=&Q^`P-O#W=voyO?byy)!ao)7-qDy}! zz&;^~JuMJbI9=`d-FG)*Z|}UswQG$no~ST0(;oQ(K>=EdvAk*JTy*M>sAt!;*(x|a z20N^&M>hd)cvW}a+qT1_ZKM&f`@3G9N+!xTJ01uo%HJJylI#rVtR0eIu|K9uDS;gt zexwLVCpZj$+7=R8d)E5%dGgxV;Q}un$ssNrDrh2xWW;Ea7>jM30m|0alHemdrnpFy zbWX>oCb_L5EDH)ftaULt$ET(%hp(rqhZ>R9Gt(6D@ignZ#9uCXZi+Xa4^`&aJrV(M zRXBFil?9LFj~A&N=Yp|G6CW< znMs&+WAD6@;o$X^m(3WIjOY!h#jGr8X z5IP;CnnH=ZWG6qr-N7PD?v2e>N!76xoFZtXf=0v{a}T>xQmP$=1q?Ail$SR&J|up5 zoK9AF_pwcF{lKbx?aP$1n$Q!Z^60PGMfs`=+&EsWbU0DubdY!{&{9gL* z+t6DMD7shcDn1qTxy~EN!<2NSyjBq(YDrh)q?i3DsgIk7iJmbP)MD(i;R10D&Lxg> znursJ#*38ythSJhk2f=12NBxnnfonka1lL?Equ3Nqf4h&^C?!Z;2HP>p0M3;r2=7t zYwpx~j?>Bu6#sapt81=$@qNYeY zrDx$p`hN;+U|@2hI7?IeD4;J}dUic!F(`i5Zmf9ZeEtRU%!rpcL6<4p((~9+wdG&l zZnsc;$#r8j;j`o)KHx@f8}^GSeO4C5!Irhb%2VrU{it0l*8;oH8TCS!f}%KC4cpN0 zr;<-nFKT**zGOMeZZtgqOcrQwlRmb1S*OIn9A}ivyO0EqQsW{<5&|!;J?K^FOz8zr znbr!03WW|8W`Awyaz4vllDnNzo%~G5i1J}~1e30ww0_>evkrZ3OPqLdtHKopX zKA54Ho0|@=t@hO{>%FSqJ$UTI5a32Jb^R=BW zfE-4IQ$Fbbnv>imjz07-^c$Saq{c&Ev`45^P#9ZQT-@yikBhyZtw!Y?@wCJjx1Swn z&(q#Pobi$47lss$S34^7<;;d8{1|c6)LE_%nF)x;Q7aOc^a{Jz`DAzzva>2qt@Em} z0@co5^Rhh*%Wm#z5^y&W3tTylW#-2Qa;C*Sv8mKxg~j##ni(iknKo7YsGJIF8(E&Q z`stl8$_G^$fwkfW_s3TJj^BrP<=beNK&V(7G={=5EIPJTWwKhDUdsZBHw z5s?X8YC&G98qMve0cu*#NK;5bh&NY&T6cK(&cI`1%6~9~l{;m|(BxS9BBE1IX@c^} z^u*d~O38&JL+6_9+L~W=1)`*c@sqP(z7Sgp`I21f5j{NhnN%hD`0ZUOmq}A-5Jxza zFN3M*yfq|5Z2XXpCKyb5xaE(uBaPLD<8pH%)FOfrFsjWPb> zxJCtzKgN02NpsO{Y*UhSmt96Acv>@Uqr^S$HYU;UzQa>X&!3Kg1f>-@W=g{Q_~$Hf%VU z%PFptp3WHFw{S;8+idOmjeLUJFV^j?k?GzI!7v5!E#iQW#csY$i|Z36wJ zCBx@sV~R$l*9w!yWzy|oE1x?nxyTvC$=_F(r75Q0OcMu!d+wQIUq}3n+I?J@E8eQ6 zQGDrtAt8b(pziFqyJt4$Xq9S*(NW<&axB?s%i7?vMd(|oHr5k47_XP`I%PK%r(dhH zreSn|I**l$HdBOy-{M1yuIyHVZGe)r<>u#Kwoiw%vv&kXPBhRYDZX==gnh!9bAOd2 z|NZh6-unh=tq#+TrM|YdEJQKI8(S^W@rB}(%%~z`I3f%z_6gu#U>_nAz-W3BIvejk z&tlPTwwC7D50Oh@0a!CgNcc>WVte`fxyOmUAcI2sj9o2B8WRFd|7Jozmfv-br0xzA0FuYA*2%5dTemljB zD)-aWfPV<16#tM4O6=JR{{S9~9i|ScmU($idiU&%z*XxuM=}Z3Z1P&P0P=L_t-ZVX z+2XtJDvU4CkkzxpB=9AvgQQ+nHm+mYd>;lUf-9MG{s;(_DpJ{{xe+*l&RIR*Jj1qU zs?DENf9W?Z#n;MRHx%+Sukn-Ag7R(O8{m+Z9LY z8!4^0WnFrRyuAGaeRO5mry#DNOS`MJN3_^B3Z(V*S8l(4e8*=uL7OO19iTp`kBHz! zK$xCbaeC3`Zif@u`}L@aFG(FDB;?hY6u44Z#OMR_=m8b9$m`!k9@vw`JwUXGCF3U# zf2CzcruD$*tmFbiu^!5JXpP-tv9Ysa6YdK)vJ`zF<)bF^VMtEQj1hMa?5I3i=JKj? z_u!ZBQbN8m#%65P_c8C+lCuvqb4RV&8sz#1&4zbgVr54QxO8+@4n>`nRN~UasRb)o z68QO5c(X-1@_FP3Rcx40LEVMIb%*s^qs8q>b~hFSVU3?q@~*Sy2&^EzOIjV( zeabtmFLm~n7N>GomSM*2HP(+h|B-&!+`ZgVI_u!h@AR)5e!IIy)$?Ot(m3jS8>H~zWMIPR&RDr;1Abh?&C(ZT<>_za z3sTf6xlwVim@8daB@(1a+4PR3r)q5XV@zd*!Ep6ZQ+-FKm@QRC-~*`0CC(#SBTqono5Em6AEt9o_*bZ^^m zTvhx-HU)Ox>xVFC3&&KOUhI2W;2&O;FY+Q! z5WS~N7KS;8`wt|X6Rzx0PQnVDUH^8Q`a;Pg^m0DQBs|>Jr?%RnmU1hH108g$8so4+ zFxx&7GIALqhxeO4lqVhDMXd~~WYep_ZYv6;SAvDneDIG+bH67S*ETFC_1!kE7u?nn z#Pxm|rtAheY39q3{W2^V7)0{1yjK$Mwi2lO<`Q2qA=Nj2aPU*>X!T}awI5~ag7M6H z;M>n8Gx_El0J1k60xV%8^0(vokSJVXesaQ9#&-e2HI(r&KZ|waV_&(-B&)!}cv4Db zwss=gHLMc~zR-L3L}W=pCN_>4L4z4T5Ecd&?myLzG+K|F8|o78QkI?$pPUWrW+Nc z9I~~Q#g@QYSWt4d7ku{Z%doHr-LuEUj6V=yJl|M5basB)Tj)PXv&mvAjd?{LuxJ8F zox?N5v#!7Lktnr`e9R)L9RcXskC&sRW1A(i%U8FRG&-G^#6xtW9@c`zHgIxZ> zgr+!c^i1N5YMIsQYP6Z@UroPfW@n;jsNxoaf%%F3pZFNyIzQ=3PrP<}UemIs-JoNO zgW_`Wgi#Ch1#Bm9|3j&< zkm1+j<7~fmTEKQYlA=XaXYES;;ItB>xLWx;#7do12a=PsyMdblsd|=WoVuUQ?jNS(Id%rV z2)-^rlW1%NQ8x^X<9{f{eG_Dp97DOdZ~W`^g!-*5v(qiytBaBS14l4JR1@FnT5_D- zs81RY7N{%yI~NDTe$q}%#EqHm3=Hu)IM7A@D%O5_dssGyXZ@bMRY_^`keR~@#uqeu zs{x1n?-&G(yY|`53>RzC3_Kn)tv|BGSP5p9&$oJtpeb&_=yKXuQOgPPBbXts|5}a2 zmXRpbYa?jVO6xZ z{}$sLT$sP@9E{@O{QR~_Gpiz>Ry#dfT;mrRBN(&mZ21LL-dESq_*q7FQGtNhAN+$n zPfAg~L3H$W3Qw1^au)6M(BRTxS@U1du@2el(A?ah);}tYEB+sL35~kBHc{i*)m~2` zK0SP?uEy*}{!81|Mes#a&fYI2agB_;jXEt2|O&oF~@? zw|jASeFeIJwG8$DlNmdyD$DAqv$K}zKGsvsLs$prlNAa*%|n3ip;Bd)Y)dIN<0XJD zn1TNY>A}}&A@*Jd22^hTHSc%}1)2gGrl4P!cy-zSjgBoiI5oKAGh5oW;CCrg|FzzW zNL^9U?fsz=je+K&#zv^|rQx< z#oDvlnisgvj*}|<6ysm}`_6IWWZHSll8Cj_@4Ja5|7kkL7~I_8?%U}gzh7eV6|S?j z+>E)-hyLcFAiS?}n}9OUqCW$iGAsvocIch1E`x+geUL%NXwyphi+0`86q!P$#*8c+ z8)M^~&dz$td)0^W6e~4uN(t(lIiL4b`0NLzRPRMyG}W9uJzYur+cra^oBv*DiAz*e z^w&4{4P{n*w<0D^&JA@Xg0Jt$L$Hx;!?(TGxG+ho3;kPxD}jjt<=!Q|k=E$u&@}zL@=01Hq$GeR7(Vn z9EatJ#}Bt|Z=2}g!Uosw`4zr@5x*z!6k6_TTJ$K+zkfKPxxNx~NrZu8#I6 zAYM&^S`IZ2ffe4A{847DoH5gdP1l=CMZ!sb4NeY@Gtl=x2wn-uD=#Ve2`D+-nqaJ? zn}UwN2W~IG%gf6Ui0UtH1*6r;uAZLIp3S=pn0@Pw-X7$a3~X0>)+;EDf#S=0Pl+e( zZ`Fz?Gp(G~Ow=uX2kyIX@9gaC?uuJ9`vuqi0=*}o|J*k@F_GxmGjJOnx2chU1oTE< zgDdezNoJH5lv!HjTf&Yfk1{|?17=KOsKobRFIQo0sOCuIGW1Ah)SH=O11~GQVb!q; zYjiPEqijUGUm7O#Pvp#*CYP(BscFC*oA0vzI=&xSdUDT}iHYfPun4%O?n_BQLGh8Y zqoc!>wo6D#O6u3aIbiL6wNw&mu2Q}-*B@Ga#CIZsL=jxU}ttrX9cD^#Mj z0~g-GD+28N{EXM5qY)NxPVcx9rD$e3ot|3PYAEIV@_@t*fR3l%=!iTxDLfZ$omgLF z@({&~eO=Nhd(iX!(So^-VMj@7DozJL8<;m{ecot;;SxzK0K<0A*x zKr<*!DsodNt78%Ka}w1-*8*V{k&R@Og1qUKVed zjQ>!ULq!8v+GHEdqpGg$aSu^24u7ylbasB;{q7c6u;zJxf4{>Sc%&ez;ii7{Yd5*u z+os(hxvTSorDTs=>g&zTJV4|p4OL2XLc1Vvd3{Tm5ai-uF4RM((;IGe?KKgE`1mFf zZS|4)V0NC_R+ZE*rCL&Sv2FJEzj}lF$J-NHxwzz?R`|<(eGAD~pvmM~u~y}QTrPEj zerL2rYPORt@DPTHa&3ZK{@AGX-0UoLuDr2P@)kUQaev$cE+;HhHwfG>{1dy5nd}t|OPAiN>Z$Q4h>MG4&&pCtec;*Nls|@_Mec9I_1ygv=yA4!JDs4_$NtS@^%wVj z5!4DakqnBHJu79ivjT(}Ti}@XvyU>DyLmYBy|edJHf7V(hN%_sjK0dWj?Em|KK$xZ zmY=_BaEwXEz>I&DfrfsGPjt`Fxj%7%%}06Poz2Zn3Cgf{h|(VgQ^D+?+tbu?0s~PF z?sU@;4uL-1Kc-=~o>E;s@h?guLChvS;}qqT_kB_8FIPt-2k{+A6CcJAKQRn$<2 z^n0m&17{r|UtUGbMph>co1B}&rX64Ryp2_SMo73V=S!bF82BV04Lr4RBTI=Bh(t1m zba74r#(<#>a=H6PoZa>gXnSuVfx_qZ4{f<=u9x+Xm@g4UL{(W$<3gLA?$<~m_~X4o zEb~f;2nnxc-cf}AYBy*VO&e#vg9=7=V!1 z{hFyz%`SO*=<$O2&l59q+meRah9ExgcOMDnk`ecgknddhqCc=>CBi!P<~lbvdYz0cNTef_q?Xd%ru?tbNztBAaW z!l%S`N#I2n*JdN2{16B%@(dXu{1dn~oU2gR)HJYSJz@7_!&ZFp@KEkH0KIOVdbqxx zyHX=oLWEwKFIihvRaHwXswr5t64Xw0tujNpCbzc>qQB>M11J&^746(SuN9@a4~E2F z+Pn4BM=#x;jyDfg;=j*iJ+f|QecffOub~A1-6YrK;{H()n4G=R9I46Pm9pqj(0}K`NO+&R?@tA zMojdS=#dFlH2Nnqs;d`-(}!bSKo_#8h)7)I2e6Woxw#6nN!*~irBZ&JQ)+Yaa2Hko zj0NxgE?{teY*dWm84qaD;WTF4@4|VoySp2}d`b!L6DnwkaZZV>$Na)V=)zNE-;OQN zb^9f|IPeZP8KCW4T8XBnX6{OlK69CjDQu?2zxEL?DhV|;1wG0eE4(}O)WFjxK%?51 zY*p8i=wgo*OT8ZqySkPPJxFxTPi;FXWD)~YP;K7vso_oZm-C&)WUFJsrLdpGlpV8K$ z_&|oz39?vnHF_USO2#!&Ke^wQrzjATLarCZww4@iq_~6K=XTPI%1SmW=)Kz_Bc_2S zZ-N(5WC_17S(P?Y+yuDN;mGsLkEtNaN78FC(?l0-z3fMgNL3^@)-K|n-Agds=CISx78n!&|=zxV!k@40u*+1<1HJWqF5 zS65f~Rh5x%Tzr006U*50$<;ORF&7utSKj(C-in{hq#`*5Mac}(+&rYZs%kB?2R1C@ z*wEG1hNG~F;E{K8+jWlH+;qmPe3I*Z{rxfkp=10!W&@jOP|yuUlN4E*1>+K#eI%IP zMVLWxm;Oy|n3!Vl6#t_~k4BT=BICSqV`+zhwY;GnYH=CAmaP94GcnPZ+7=I2NmoC; z+#}WGAMZ7VpIN@Dv9r&FD_m8?hw7!n7 z8RoCjqe|Pb6!7=o`Dv%`&O94wH`PdW*xRqxt?y9I)KctYRX8oL_UG1snS#V*#bfGE z^$Qb%6MRz-N=aUw+mQ*~9%-O>Do|ckwFha!dzH*I1C=hkdW)ltVQ;z@7jv!Wrl!)D z#(czvn`3xA0C5nb0phLF-9zT`<;&$Ia0c}`!Xbhpm2pE;GMT2P}K z`D&SbYwOeJ=h|}dY4a=ng99M=vp!F(q#hfy>25TRk~ZwTy?51|6cPV9=-!5idvLB= zYiMpI)Gu;1gIr&YH}UbZv`myFBgeXtYmN`_g)pGxMX9wELNQZmWE&Ku`t{SteNb){ zGVCP1u+uv=i2l$MuuZbZD2{mr?swQ+_~-9Z`!1rPzak^`p4@TWNyB7u=+FgH2L;$+ z)J8@S^keiJuB_i_&pg!9IFG;VDU`}Ip`rn#(K=-+XY!qe0!?jij(z?5H8{8bBuNZ& zH49R>01A?1Wo3O{;72!%=@1|D^YfFXEM^qpjtDdh^h?}r`=McW*44#DqpBRM(bJ2p zxZ2&e%n|38!K@p$P`7b+ZzMpDW_~G;5PQA^~pJEkm*OXOoRe8h4g?Tsf^50E2 z(_$wk=mWtT@Dy;`UPCWgPESplP!= z6@$7&F$6U)X4uQ@uAh0?_k+BC+TMWO%c!6mpEA7bhHm;uYbm+b*!V!oYw$894^i%I zchXW!XljX}<2yx47Z*JborU}NU)`fUd-BAIpPROov0C1wFpKi@x&?vW&7nF8wLGRg z+}zC7yM}N$EPa|O0Vnk{^<$9@5XEL4%%8Pctd9vj zL9uD{!kdhUEe$J1_TmC2fpR0r;*eamWwV-; zG1u)4JTCF2~F{4JeQs9CPqQxL72^Gay0m8%6 z;@2W0yv@zc=gQOs8F&XWrXoGe&fJpjf`S_u6DwzD6U`WDmcaWrZ`{zGLW9{wOHAP- z)`N38w|S@C=@E~GXr&wzlIZcr=D_GTk8KOoWQEUo*G_B8&ed?LQMZVrkNhE&6UKe( z3d3SLFrUKnNQtx1w`7BbzHK@f^t~c0cS=_HE>wz`vO_sI@VH4KR-xLAGu&63-{c@~I9$@e z#KZ&=f@k1vm|L%^s~iBXmnPtvoNXJem=>&6#0bmu+TWrcJ_2eO+{(zD83=djd0 zI)h4xNDdB;6D6b11{V^zC!KUIlk{o@=l-!+)%HkfuzKbMHe)w&+TPmv>hZsndY(}Y z=e~(E?`TVXbq@~khf1I(o>NVWqMHrnWMvBx;Z0*-*v%7nJKGl4{lpR zg0FWo4<(P(G;S+dH1Xjretv#ILFB4Bx?_9{a{p~?Y#@=jt3ld;|9t!-@JyTEBXyl?fxojXuBg(OC)NFA-6V^*n- z&PJo5QchLtHS_(ikgN=z3c!Q?*!ucadXT+(Fo(Txko#Y{I4+FdPcS?ku;zFCSlx1d zhDy%rUw%}_H+IG1zZDKlRp8}_-@(i;!^|-s{U{hMdImB$g@yNOhSKYZ+gaA|&^Zja|h|Q`we#_7yWLO*Be6)zc@I znT!AOGOd?GYgZ}8T@`?RWw=4f(<{*x8>~|~rvcS})GZTo17E&;-!@gIVe`=xSp=q4 zSEQYro4KX{Q2&gY1FaYDfX{5Ju_EpL8OS@2xHoeFSh+eu;X!O%I=_g@?sP`&nhocZ zBDdS3#7{ln#86Gy6@=lPV1jxC9^$)DjcPEQOQ@v=W1S3&8723R+3<~2eHjm+?xS~w z%Y-~sGP$tz7%?$>V8Nr#Y3e?W&>_svj_xZWx#75nQxwc{eKS8 zuA7@Y2-mb)77=w7KK=dd3HWHx8Il-tCgkE7pyhg^w#v#$Mb_r|PgCh#eWx@uQ1lEA zU3+6v+_=;Z12WQEJp%B`BGrFh86Lkky3%}8ZXT(Ycg2QpX}4UP{(e~Xmvh`AIpat1 zHcsDdJj>Dw`g)UnaJv!?kzmy0=-GT5K1bimkq6FtV(%3)%uYP@6mY>yx}^L6dAby% zU`yq?o6$KCpVWHs`N9T#(hQ0TcsxLuHSVz(zwiV7KP)2y+O#{nSY$HEp&vphTu{I<|Dk-C!gtWs*wT&0d;=C#Z z56|k}SU{3nU{JuAff7`A+nUWvBIu3f1cB()08+;4eqNd(U1{lemolXKwf(5(7b8z9 z6XN-MIu~;{R$2^`6$o;MXcn&GKyNaJJ0LjdH!EIzJ7@1~qJFIlbBS+sa zs4YcY$jSQztJ)zXxBFhrv7ieeA73Gr_ry;2_M${Yc+q5ke)=AqAufh{WlL4ad;Klq ziCO#5+y6bUhP^6OeRLKDqhiaLv>7pR-A;w}GELKJVUineJ>a3l7&5=<_@8umrGcpH z?jfz6#HVqFSksz*PIZ<`9Ubk8iTO=m3}xWb{4~?qjN0pK)&lWEBqa8qHzb*HPF(2h zZ1Lou<3mP9KNlZjTSKOOo|%}lvBV2eoj8FqTEmw;bvkm$FGD9AC+ZsgGmy%-88cqu z>N5Edt+FghP}Nc(i2o+qv}2<*rW`*vlsAFbok&S&7oW$*KJV{099yvG7l8MH!tkX109xXL|?YwP|Q9=D}ax{7(iXbPg5Z*_7drLx%HA z9koHZ?PsIVhUyxK%r3NQ`$|a+Ew7^xKdYhPr`5s%=O5?(k5?Q&b1IH(6-wX3MUV)2 ziSFJo4tYMkyK6Bo#GrCPBWV-?&lBYk1QCJNocsjum|MI+vtx@g6s2ijzIu^-rUu*e2 zH$mgh&Y!D=YLSuj#T=)ku{R@)Z(cPtQc7;i;5>_ec8K&pLo`j)eSF$AsKQJmD<^>1@oI# zzCWR%`8g{cn=n&pu-2lNS0>qkRVq((6~4in${N=}bL43@13|ie{w)Gfvm2^(3_O{d zJZS9vOuNPOtdmZvrhqU);VQPsCt`vS;jub>NUygI4vsPFPrnSux7ruuqH@Trm~;=Q^6q z@9xD!NedPirXQ6@@!bCSH?ck#OicXTby*tr8mM-i%H8dYby|~VV@nG?(VAw09^`l? zs`S(oPFcTz6@EbF-vhE`VilD#Ge*TKE!17y5gnZ|MV0-!g>`rHD%ke6q{20yH2=A>T^pAwC-9Q`c>1|B-(7Tc4$he8 ze{Mg?%Ip@kw@NMo0(#~$IgSfpsi_MHvT0XSU%Qskq^>$SAdly?N%q4t)UzLKx6CyeR7xgy zl#w1Iu4{j--PWdu%yJw1?2z;3q zFJZUv0ngK`)Q1P=_NjoMBljzLcs_L~`^`1ff11tGo+`w!w|`zxIT@QJA&z^P_MdUK z8CynJ%oe0k5yI12Y ze5b~@Ax-sE6POGqeliMImvEWS?*+shI#DXEs-eG4=n-)1CUzzW5`lEzJh6|JDNK$~%iN zJ;@L7tmyRkaOQVBBvY|ZO)=kEls+3Ov8G?v)b4OezDP||S0h&0(&A|H1D+>h0EM_g zqU*a6{F4y+z}hKIcK@}OGJpSKS`%}Hw*4+w|It5g@HuNyQE5eU;U`55rqki1YVRz~ zX;c=MV0DqoV2ea6;8xS8!@~5ORI#5W-0%ZH)T?Iv3<>QPXgFJK-(Gcf1$)d*3q>KF zxag>Jw9`?W3OJ*dPeX56BQu5Z&wC1-Kco$XQeIkyVg^O@Kbs;5yK!$7 zOq>86V?n|yHArh`oHi^Ubl+R7^E9c0%{+djtz*AABsfE9X(|kVlWL9G)KZO)!%Yh8 z8cxSWpFD0uQlbHh>kR%P_Us5bWLj-`bjItiSt$j=mZ0xff-OA$q>GvcD%aLm}|a(|b)4A}agS8LMxn&fo(MM5P`~ z$X6k`i7mmoiDqz!mh!%|*|q4me?;bg8QYRK=g~ym;7l?_VT6YSAL3u2zkf(13=2c# z_Mm-u)5TK?ye!{O|J`LSaQ%F|pgcE^G9y?26#j9ddB*=NVAl=QC(Ly8{L!Og^OlBz zL4)~agE|}ua`t6>_=oL4RKse`GtQ0%$y3ZG2tKybI_q>R;cfF@(;u7r>or3d>D+h*$hu?~lyDlHyI4aK?zIp^FdBW!zPCl~9Kr3>#KRWfiZtZT!LPU2K1`|Dt z`o6m7jAA9Hz_N=QL~?U6DJy4Rqn!FtK~P<@2~x()Z)Yk_^8rg(zKS`AAp_~L%WU`V z-Q(xM@)#7T*#`bF7|}Y}Z&9N8ZDXUftk9zQQE=|?Uc2eVs8g3OcVb_sMM}O?J>?@- z*+jF^7yBkoiJ4d~-p*tIzW^&0!uAy1*;@riw+9IJa>aB-WIQ9e-^9cO4K=l$$8DE! zsHmm=R@($TGQ!hKPFXXdl^QFjn2@C+MbVfaJwc4H-B;z;x9b*j|2{S&L`S{MZK13Z zG>5lT@IG9Sz-am+b@Qf+=K>=nnPVovL6)s1EhA%(%rKW^3F`=FU|>*Z#BI8o1!B16 zL~DGvAE95M(Y~gV?Uzp85aFPvR&0E_(?<1on(bYK$T6J5|Cl^ql7~f+`rMsM+ur6V z)K*;Gvz;>*lVchTli>{X^lFi1B_&2~uLc)*bu82!$4!C!3#o&bGnJNx@7xJ*B9n93 z)BGH#19iLJWu{8ug}dj`1ERcF&K$ETa}`b~UruV(`bNnOVH@(ZN1l4lx>r|24RWPC zRj$aZ#EtqtFke#&#Bn!}nVFeeL_BZaq*%khfUEsxlwjq%h1{s7vDFWI6H`l0&!{2j2ek`5&Wt{` zvn#}p$sbpo%>^FPoX>UC0e5G@aQ0nU7;bYQ+F+WdatSduT>3>p!IqY|{g_SjI%Qm} z;$^>RoRx(EUf2GAJI8AwKd)wJ61G%Q{b)3-4djlnFY`Qg*X2C(&ak*SG`*D(mj0SKx@0W?YT&z{@ zz|Q66dWQF~v&hPFO|q8tZ7kWH=4B@g7eQoMJwF&8Dq?!D3484AKm|@-%YirjPqw4@ z8G@SJ?4LZjvo6iD5?KeWJsPNOGAk>EW+cb9!N%`<5B9cEtCW0VgJpWxTlwq8SUxOmqGx03MGO2PAlF85R zvQcmAb@lbV*4hiQUnwdovOr6nDdEYL#Z68cL#=2i|K2&YAu4L>r{Y{l z?#D7yrBlc8e8jFwI2+E8457QbbIBlwJFSF((=i#nS@*v`+J>|0#?i$F3ZMv)A6J0|U_Q=mp6q^iV- ziIvLwarkc&tT9M0>1L%kkeX%`^rg?Ls;^6l`3Btrert7#*jZa;f z=%B#u0^#ZPZ5JNhl}%SE-?1@+?%LtpW<0E5_#S=Cnv4vIhHwI}%7wcZLmaA{uAeDH z6hyW})WwaiKrwI7X=joxZ66{6!2iwO zS}yFA={nx#Hu=46c-OF}A;gqB(k>*ll&oN(EsG#Sr-OX~J z-nsbP;O(*uUEDte<{oHm`>g~-ix~Zr46EnKNdrESF@~AMd$W5?$&xoVuK~)cqhD&j#KrA+Ic3{f!mv)s{(ebTVW7roY7*5o}~ZPTjWMpFiKl| z<7A=H4U}uA^6Fd93gR&zXd;Pmjz|+O`?1F+U(zciES%lqjfLTbaw#U=bM^(L+GC|- zjQpX#`V5C15;^NAL%Yr#r%aNMfocE4#H2kvkzBrriArg3fwwiu17) z%(_$&0`wAVj{L!^Xu7X^g(2l$sh!<}Q@8i-0b>kXb#2j3$P!b0Sjq#Xer88_gLMUej+U&1cS)sv$B zv9JRz<{>2yaB*QFla8d+vF*nh>gad~cPAvoXjvLt%;Qi3#lb1wGF2t2mqD1p93X<# zp_4Yau&>ot@76s?16QKaeS0+-4>OoU*PGz-lG*&4VP6cpD&D;C%$7=RqXEujc9|Nt z{tF!pXBdzej*j*^nwm@pjLOA~1Ps|Kps&0b0H`Gd{2}K>=UuBiljJY{Gm!~!@|QT+ z0icR34$m3Ls3>XB&#G_U}w<=UOs1Oa&yt-Y0XRo7*C)E~!? zz81O4aq4)7edB;#09KY^28$Opq4qbMG|Q_N8mn2r_`wtxpQ9|+%pPuRYXe8UlI38= zH=j=Y<_TH=ISSoV;$vbi{W{8mQg%*GPM_WqgOjD>N!PQFZ|zrjsEVNz8!rT7P3`~z zgr`?FznVy(ebvErLA*@H9;Y1M*bXj#%ue(?Z%(bDkgp6NBM{Amn;Zq94X{tx%c62+ z&OtSOhObKxN)x0w^NH{8em&7wwq3O9LuNl-@08T z&3alM(V00#&q1f$fR19`$G1@cmtCEWjqPPn(2NV+;yvFxS zi*G1*qIPQwGY=R__kfgu#G)vut7qwP1783f!CNBC&&Ox-O+4CU>4gHG7}$)y@VZD2 z99*gYL_~P+R5l^5{bTG@)yqEm&4jvyU_LIE60Gx%P))>okm$S(R3zC^8*Ck#>n%YI z;ZWv0cs-}|Vzn4gOgQbHJ@n_Q+bg%UuuxwINR@#boTMJsl>vSnSbqiAuIbucsRMiQgGjpj!~2Vdkp0D_M{bq#noU%cZt; zfT?Z}W3Giz$qgyHB6J3csn~(os*C3Fzm`TC?CBXYVrW#Qs`fPk4m7h5`vhBGL&~&B z9T5qA$uIyJVx)$SH_$K7aK-ADpyf$_anM$SMaeBHRl8v`(XS<#vSy%GdSN%{ zgkO1Y(j>dI(KF7UCg~jsZSqI6E48LggDcrx8(Smh_77>H;H!^C_e7&Q+H=5khekxHa`z^ShQ31og(YmWg`*0CVclL`EevDUf}R1Y7FJ15Gs_yY z!Np5rTPXSmRdy#O`UTt7=>_kc#gE0n4|}vn9IQi?PVgQ-I;GNkY^WA-2b#o63twVt;^ZJH|mxc1hlcN7vb;f~F#o6vOQ zd=B(+tU%$WahDrW(4g@|i-_ZVU$`828r-+0QY|rk(2)QYzG{Ot#SJAv3n`gu*0RgxQ7aAU(nk`i9gV6h7I@KW|x7rGePFFsGODbh)d!d?fM+67WB0ugw z@-Pdse&_lMR{ymLjVcBMygiYa5G*h#=RtaB>e(CAgh2olhe5|J1 z6Pc>rO<2QkX=nrtz>&D!_C0qjMOWY*d^=Ds6c_1%zlwzzacgTV1(}&MG1*FJWeROG zN5}OuFboebFNHS1_}qpYp{XJ%u%#9kAt~W*|^!@npV@n=myjj1$%~FX+`$z`jSPB#q9Vkjduc5H`qW z>e7$g@V*)`r;Y2*twEfPeVQ9{C8+xPpD`VwOx62SVDx+Dr06!u)ZS|}?us5*bEt?@ zk4B>xyDQ05RB8igbZu_3sAXk+QZ~2ais7|5RcHcl+$1bGNuLWTV`wl3fX z4dN5ututF&dMK9yxV~;{pDXU;LcV_Ki=GnlU|dtp&s zVTlo5Mlb)s?-hRP%|&c1Ht1Z(&keQRK_ z%Z?89C3$gtVa@UJ&v?KS^ib?@jhljQ=NLrD<>Egv1xPaYRh+e*QI0igVL;iS(nRmy zkI;w5Kip{jcbPJ8l>@rF8^;TbboDMawWTg~n3h=j2{`6&(7_e*A?V$|n}1GgIl3U9 zQdwmtDnaD+%0w+kwSJkqko&1qu;Ywkhg*WFth~-k11%+syZQq?$`VFTyBJ@o3S*C( z$9tw1lMeU#UP(EvcE#UeVb&>AGbbj#8Js=yoL5`mO?LJ>M?h~{Dg5Wj0;;`@OXDpf z1$Cb#cDN?pzs35a)s2jJdV2`W|KUO6?`fi`83dn~d5CDd4D?xAdgHSGb9Rm$6#$!i z`L!=QFBvU!lCGKEInWP0?q)OPoi(bB4AU~`M94Gn8n?W8dhd-4{2 zfAd-z7L=Dy(!(&Z4-bbKZa39+7iMGAx3#`e;laqmJ7a5ng_NSR4Xd>J3QQr{D~Eh! z#lu@W(~0}~%{M;YYRk@z1!~E#h9g^B<^R`{8QAMLPVQ}8i{a4z#G9d2Mj3|qkzp=^ zM&DfkfZ&k#A-jfipmRWC{^=%9q4k-M;F6`ilI zUT9si)RM8+z`&N>Ho$H?|MMiTNJ7Px20_;|6EVEQC4)6_0yi4BiT>c*sk+ol?-^2xSHuk6+Tjr#e3uu=9^DQBW z6X21n4zQyemcOTAIq2)L=fAnVa4Qp=B`w8?7h}^?z`o@$-yPn6w_e#3L#s0Y6m<3Xy%690a2?tU7!X3as!))wxLjbp`j^K*52?2U81YPE0} zZ*v~fUIeaChgebm!ODOMKLophi6up23twZAnYA`X@nD*)zdx#~NxHvB%PBxRvAv#{ z%*+z<6*zE7kF6s#O8@cO0}?3xOM>2@>zq_9mupuhfcTai@&8~FY$wD#JibP8TCc61 zs?>s|RlWH4SZ$w#N5d}P2x4pi|E|SA*2K@c4PNlW_w)t~AmCA*yZ?$BHyQzf8%63o zI#r}pRKrtkZ}eN+sOJ098v^kLS9I9nClMVTHPfa-0Rh8vy>B)*Z*6bY;AVy+b@J8H z4~Abpq{CocZwX`?T<48!Mx#OQ_V**#*8LI_-$+INl-`59{M%HAXJxQ1Q)Rd=0L9P$ z)B4zhZ}CE0ZFe0VTYKTCoTvDAtJbunrM*S={`T05YJU23mNU^LRK&r)&d#BJ${0?* z=lJ`7`MN6Leo)Qs_V7n95b~QgXBa8g=j){8Y@EW=b%I4$&<&qDN+AGoJ{M@{gaL(K6fQjQ@MMb|@`B`VRVpwW@ z=^NATEFKKcE^#{q3s)xTF(tW(mJYq!^Nq~yNC!zh#sK@%csIGi=TSAYNFmi^au z#o}A`tg*scEgx?0=o=?fhOvd-$Fs2eA-A2Go%QzjU+mOT3&nl^p2&;FtuwOr;n@Li zZ~XU@>g)nMT+Ow9y2vc|Y|+rwCyCG%2Co6EwEcVCInT~BV48dC?>XUEH|6W25ZO8u zNlC*UXkeaxErRH}bvQJ8kUBdX!Z$e?$)cu1VPcABCvwFX9Yh4HJv5(l>yzjd8KK#acC17qMPZ|ht z0`hzn&9F{{e(C z&+Fa+6slR%Zsir~yNM6e^%Z7k6#?y$g*L(Mxg`^T)kGgo9DsXKq$C;|%g)v=nb>BT zlfqxr6)HA=?@YCil#-V5Z)`N> zb;k$mi6%`5m^1v8i^kTJXBPq(MG8Z`#Kk^WhmDM=^Rk}GxOy;gr#}ebAHqbX1QAv4 zr((m6bom@P=1aun97tD+VO-$S&nZ_!ouAe$V2>L4@b+AB629?;jk5FmeH} zhmDR-Letpv!U8X5RWJR>nVzfbPIpSrkIl_8OfZsX zM&HuLK1AY^W_rVj^RMswd*9;EXdh1etS^3DHU0K&Z!tZj^tH`Sg|(0nSvk-VAh7WV zVN?0!5s}dSxO(cPDCAcx?^xZcz+kqNFXJ;QTX?V$?hq(PFojFMOS+4HsA2)8Lh11!!trGx{L@fsy5t;5+zl<###R(n_ zgwE$NNC6?CU2u|A+uP*k=6+A5+LHO_rD!Uo6h>8x<_``Gfa=bFW7D{Z{swsmZ#WY06@oGBywEuVszh>OH-X zD;E3hj1_(Hw@ZYu6;UAp@g2hq`G6Z68>6G2CZTosJ-zYHM$r`xMTlr$dd^A7SJG?# z=fist6L2l|;mVNe8twb)-)Mm=P8})IM08Tgl%E7zLuv?qa_ScjQg6URsFeq4%tnQ}%k%rJ++1{Eyk=z01)K z5F#4pna%w?~y0pcb+`~TtvOlNzy61o{CGJvyjj4d@x7Iiw;yf z+g7l(i6I~O_!Q3Iuj7m+hylX~JTXcwg-{0oCmrU6@kT$q(l-VDk!Rt1gH>+50|Pvm zokYy$^t5Se2Q&DfZ=XLuv9dO&kpzxk-tJ=PDOg(C2Z6L3PQ@m?7j-i~Pt^6teI6@B z%={Fq;`%u$F_Ztk#Ih*VC~nr)mOh@HuyH32#`cHEaJZz_3?!*Q#>=V%uy;9x1f2v= zynq0uz6OL?)^6`%8uyTG7UDI^A<{3z#h?x)Gx2glx?=JVlM8a~65?!Z&}4gl)s8^* zI6_`U46`y-F@%C4cCdAxIsjTcXlrSm?VodSG_PTidkOJnt6Rv`@pVd^lVAZRD(dW$ z#e)$bjY?Loh+m)$C7hFNDx3h>AQS=qByoZ%+08mcm#$SRk0?5<{?*gRjjL>fx%eOw=;shc(zpnd_SOe$}_|1R&oAQCO5d1 zrbb3C{`1eBJL-|xR*p4-_{023kf{->GF{~40d+`}XuC6-?3PZfoJ?(SBG zRpLKwVG+IgVP{8>L?Z@HtVvXEKm7XocG~;7uDcuK!x5Ovx*%TiUh9P&zxhtz_s-5vArcJ`7!OBR zHrGnRjauE%CUubHYU|#SiO`i|3CppA5Nkef^;J`;q@*MpzVRQ>@t)DFCnyM?8AU{- z?U|W*jr%!>AK5hrXXkX^qf$~*faU^>^Lqn)D1Y4!e8>4Ng7LW*Bb(-gg5{vxNPk!^ zptIg1!X+EES;Kn-IKf+yhz_yWM+itK3GB3Y!=l^m z?Qw&@u5G73p!UkkziS>(y^{-6;OArv-d|zXH3R4zGdmSNmJW_iD(t!e3bBWq6P~l|ICCDs3^X-M zPm@>Y@bmH-Wqnrd9~~WiBD1}8Amu)s$So;JJ$4eB6w9tDXB6eMeS+eaMvV-E4o(B75@>?Kg;dqF^|_|$r%(;y}7-ep}gfZQ>| zjR6rkAYr6kJ+J~Z1JnX=o=*?zFqf@aJ9Vy_`5aVcA>-?IzD1`z_&qN#uOWKvk_1cL zoO$x7PWy~mh=lR!ATu{7RW^2$qKYj0Jy!gwye$W-*j;+;;UN+yE709*&R)gbBMdwR z>r78ihhh!s#P#>ze^s#uc6F5yhC>>fD^!GmQ0V7zS|;LUdh7g^kdTu&ddS5N;-0&2 zWqskDJX-GtnkJx!qFHD0p@g)IlBtb?-HH$)6ij3u&@j?!%mp`(JzQ$CYt(H~0;96T zbC6;3{)X-&5k~HtH*fOrtoe!UecC8n@)o}+TC>(Z4TzT#W}n&x`z^@gBXj#^U*uqQ z-hC%6q9xVsVKaa-+4VV1^~LS5UkT#UA-Qb|5CJhUv?Gs<2uEggKRvLe<}Blj0P%~z zco?Az`uzIzOEcF8kRpHW1*~J`0$*uq>3LljQ+pC9-l32a&MP9apg)0#lyYmJ*T&9; zn49}I%K#W!+2*=1LRmS3n}?-B8x4A@csR=JvPkQ% zVQ=W#cB*S>aa(d-b?Gnp8ybDbF(Jq2gvsm|v^+c@$5A?SSg!xu*uW^mSNbm=Jl(}H zR6Luk>0xT>>ZsxX}UrxJptgo6?|NJ%yg=Q*&d zv~(lY!r57E4Kp(>Al-#8L=q{@VgOYDrjvvd#4ZTfHHn@5ANy$ABfaBRrWh*Sb zp}F>d9VpSBfB*-@TkXf2+{z5@-N%N8_tr4_jk-0|K@A+IAYSdp_0QjFoFqPCU`0tV zwZ}CZ=9t)`_R%+1D*wwQQ&`?glJrec`+gD%XG1Lf#fCJ$S>R2TGE9>5;|^N4Ui9`Irx z$zl5@7qD*TS4YRElc3B}T;tcTFO!q8bAqRir@NTNcZU40MTIsScAf^)aQ9*6{2eoU zz`ynBkARfkOjA`;GjU%+_7dzU!v}~+Pyzc} z8$ZHnCjfF@J8u?^J1zng3si<3(K1c<-7RRo@uC$pmKes}2UNwiwRfJF5ccTZ=#d$V z7wV~stWg0ssf`g|CLwM0hkmTnRg##UW|`E?@W$uHim?eQkUy1`^}I8u2w~<_+Qvz^ zH0=a_sh6jYr@mNOvCZi;b7gNovx>uUcULH~HVTb0ewHz`Uw#>0xjFIa6V+v8o~pD~ zbZiEOtE9JIU&ERD?6sRJyc(IC_qQ23r5<$6FVtbfl_Mj=MG=?f9)`4lA~Q15)6n(R z6qQ4$yFvtaKbWWyuO*YA&Xo8?-8DP@ILYL%+K9*)pW)hq@)d%7kg)x7 zV0k`4E;<+P(KIQzsK(#D$81M*SeI%35m&}#D_{Ti-;pJmt?k}pm#htj)&m|t{PT!< z8|cvw6EmwX35TN}U~gbmOMwNTg@$N(QW8|nl}u)d33~Mk!Nw+j@nljp z3TOIo*ev|1ph-pI=$&17I3*EXK<)y`?Fpj)tg0n)=RY|Yn0hu%$Y-aKvB!L zHcpxo7CIIyik}@f+;9|LD-B8N0f^xiYcO09Z_x7T!C#kS?OJ231(3{CazO z6ev31)qBTZU`Y0o=~Za2!#_-Enk1iIJhXjhr%gi^Fx}A^eA}ikd*q zT)zHwD6XemO$d?$&yEVNZIM@i^s>V@bl%O4DTh$uiVZb z?C(zx0(-``C0{^rZe*zxQ>cHld$f@us6jBh73K^1+`lA-&;bQ5=u|qPK}BF`0c7Dh zl|Q{irTn%xS5mECgJRJ=Bg`>jHDM2!S4=jNr+2i`qQs>lBJ7TUcnze`;-{7ip=0=@ z-%SjX$BdxXqACG+16k9P?3U&aC+6p6g_Qdz#^~lNpr5x&5O$|GXLomZI?<0mdM-Hk zm%%c7V6Y_W6sZeW=X8uPG&O!hGt5l=ZyJ1mg5uG=772R3a#?H#=h-qvYpb{RNst$1 zIS4@64BW?$vMu2M2Zy!Cfkaz<6E6epFs$9Q(#6GgcCIR11q|<(#}=||Y|uzxCO_6q z=HU4wzq}`H1tc1X%d&EH-D=4VdNniXh=xlnEaJB`ukuCUUD2=~#|isEmw`plfbfS@V_ydR7jIszat-mA1usjbP+qa}BZi>Kh0bT( zYBt|nw`K58L!vcIU`^y&d|Nc$m!>6m+K9$;IQ4v9PoQF!q(Vs{PjrUNDM*3(a9qZ8 z&!?Z~l~IUn5)UE#Z@JL|WGXyyCGh3r6w& zt^lsctaD3vah6}c>+@Z_w(EJuhh19t(ph{VFe1HE#n*iT^$8X5p38UDoZ<wmpDG?VTG`#U7^t`^C1p=dGvkiS5JV|L^Y87|gQ{}1SCG2LX&Xnc zB0cuh2CCQ>28vvaQnS$EIGls~HoC98^ILzp{WW}5HP?ehM+y3vdsHKlb_JDM zbnR}gn!dF*Gs*(ZEB6_3Zg?kdk_=((EOOAFfjvhjGCUj;)7``BCCVEXW`M$QFYX2ze1+Y#wENDs zleKotBczK%wX!>X8!igzNRR!Y89k+$?5hvsUr`#*eom+^Ei_5RnS{I>c z7LFSkSssf_F01ZtCiQbm09*Ip$IOA%-LR>yLm$%p=s>M2_Ie*NhZ(_zdGE^d~;$m9lgCJ zx%rxk4$h4c9%ww+mj91wE$M^aoO0Q(iW_$}NM=KHsHtacZECclTVJ*Rvr_$B~nk*1#P7Z41>uGBP$$X(7B{v0w{~At6iPR>RlFd)FMg`?7TB z?AF%44D0gUGG0%X8tXvcq$}PoXxSoc;^^-W@7V6n7lnuOH`lhxpC$crIicNzAtgm} zr5o2GExSh8nP2pIsi3Q&jcAFt=e!|rF^DKAn5%NH+&kMl)@09XyQDWb0k%$XEP*}0 zUO8RN=sr0>*CQw`>j1Q_r^$giF76-f#Q!5s{u+fq5)#VBYYU*Z=wDxv?gQ$i~rdOf!&v`6|t; zlGEW46^mT23vi1E1>(cz!Kt-PInnz=K}~ZOYCO5F$T)B0#!XG#6dq{qQcXw&idpR) z@O|u5&DvZ^f6Sd2Av!$87*bNVD?l`R+RFV;5j@MmA#fLmzhB56^?Vtuw|;;A-Nm0L zf(#bRm zu^EQ9eo*?=b!&A>C%_m|ZfBrqCm=$19!Ej3Qo{*hkF}j`OY_aubY&wWAx04tgk0F) z-QekHt^(S@g*SoD%1Y~O2RPj{H%?@Kr)`dWK&KkgK{bB)3BTW|NrBoP5J(|-JBUDO z>4Cq7SONZhqW?Gk8ZDy|VOqpW`;B%T2kBPO0!KS%-GYC!)4%N=eW^*b-mU5Hm@eJ} zt%+zgIM?Kou9@GPO0mS?lFz;-(d50vN1g^7I60}dL$zIjndw1*K4ImdS~1^67h|p2 zUn(3CN}{U}0N!`L4&*U|Bg8 ze(6SU{k&ypNi+mL&Caz0O#X#BTA98WD!xJgSZ8%!K#&<}?Un;(Pe^|le8&v0=^oQ; z|5DC8L2rc0GjrEvRx%ABnSzJ3)~d@LvizYiWB6UJl+@IPtV|CTMC7CUZca`c8M5TL z0dBt>zPBkzVnDGgk#0K`#$r~au2uA$^C3?x!RJt752!V85A17G}Gt7RI zqE>k7_+Q<(;HP*?g!vq~A7f|p*RN2^@&fn>D+->L8l1T&A0nH|%fnOENl#B7lG`ul zT6X*|xx5XR2TX#*#PPMYGX|z#R+bIS)l}24#M|YrcpmW_xQ*wb=5W&@l-`5Xw)_YS zn|Qf|7T&i2k8U-#b9L41kYKVgI%+)w1>oqNz#&#bM@RP@I0`e4H+Qlx0NTjx<+9xacd(Tm0GmI>Aif8Aw zd5;mB-H5IfzsRuEY2sR;Tu1qLpVlCLHAEXn3EQF~nf!yd30&}LP#1V91`_gW8^BAk zehT2Wt@*jR=S>}TK2AYOO6F0>cdE|SghIEhJm+=G?qPP!4QcZ@UgE<8-ZgOzXs;8 z2b*J|LJ*5l?j$EAh0=WQG^^Zg({`7?mssWu(y{6=@ZWNBj3b=(w~$H>%$S`<5@Y{)zE zIQq7A<~0s*Rm0u4@jZ^?YiZ6zhNE^S_2x`q8Ub?IV5ak~rt*AU=or>4zx7})6J5zO zk>}x!c!}}OJEhX8De{XxYjrKQHJ(FC`KshU`q2-KR=KUT{@U2c$i0`KXdFEKAb~kM zjV?aOjmz8bX; z^@ux(*Cwby;pO8K2>J;9&#Oykcmw@~l=q4J^3xB~`$$a3ROW46U3oKkoFK)GIOr_d zdg3(Yom)`jIL^Jcwvupk7Zzs55PQrV9d~+p@!r8zz0!e)?~lUBt89b;?&c1$;D27~ zU5WFH7b*vFj5OTj1JpKta9|))YPH6}fQQ*~dl;Xx-r6O4_`VH`A~Cjz3Rb$dH+PbjhDx!=NE0$PVQi1TU)!Hfx-KCi9d)DBl!HP zW&I@qUE!WyROztaW$d5J1E(zf+}HrEVOm1>$+F(@!7n`K2R5&Hy^GiN^tX!+_M#g6 z-O9?!dX%x>d+t!c-3;?fZ8HC|!; zfT>~csJ*63XF*rj^Xj^PUazT1g|8R+O>w8p*YM_Su%8{8a+e;So=vtL_}J$$g_A&UT?YlI&iYp@HHSG zqNT}(75Y5P-i9_Xj5INk*P@P$&W9%c{KG#QOdG~w@@l5Je{+|(On0davU{~YC$Yw_ z_bPbCTxmb?xiW11^Iaq++FDyBkG!eh;_lp8ZS%Z?R)5X-D~Z5s2Rr)*W2;M4XF0); zvhawA(t{&^Tpd_`@Q|#M-f^hVb25^W4%@^XJ;@=L&$V=N%E1U~YNUH@I?u;gKi{a6 zamxW#r{S-QWkT%kr&m2lymOi?&M8>(E_k(9K|lYAClCJWYNU$->U&D`&#PGEwUoC! zyeqvsFJyx{*!v$MR^#2t!jx{nUQ3X5%Y~M_D+ybo7cnE&6`b{A{^h3{A8^FM?l(w& zefQdGjW50u2~0XN=YYasQC+_}WQMA1cjD?;>9sPzF*c8X{P9Ocjb$>(3b9v6ZK-|k zxS1VBq_${hC0yqI_&RI$m>fEEXelII$}I;8^EYqy8zaw9554!XKRgsB6b2m%^unXA zscu$NQ(Hftn3c8AQxNni);nq+BwoO9VY<{gYA-Inb-azA$LH(PvxAG*srHaH z{VAcrt*@(FO1^#T&227{F??7LrNM_aq9PvC>c~ew*6`i(dl(1zm|XB)_;6dMAWbHR zSD8y{EITOv*3{y>-RxfVWQc&he6HkkiF3B{KUKULme`Q-IPs2vW>{Bxdb;?)>aXi1 z35MI}5@I0#U7jx=;*{>ZgaN;S)J{=kK1VX=Op#J6SJEg5i$Dh%DM4uz`vk~xiN>#K zWU@3y+6FdkA*N#o&P{%vT30NyHG*;Pa>D&jtY-)#HPa^*RwZ5h7(aGuGMeXU<%qZz z+Qe$Q`dzpHEzLz1)c!$!wF&p;2@wcEP zFW+*DbkszXn|aU-3dnI3Aqe})VxlsnN%D2$H~P?W+-ViLi-dJb14#z0eT@ho(IVh? z)r9(3*Q_!Rc;s5avhYmU%$p2hX77fuO+LsktDO+whUdO&Z-mT8gJdHmWOl!Fez>(g z=NJRxw|KGYzg+{{zOIeUg;4X@M}%0xbL}#e;AKgT9=POP*g;J*Z_Rev zH{iXMFVq)yr19azj;n=f!J}mF&?DtCm$EpzVTf<>rue@2{nxgnD@caaV8Q71^-oN_`7Z|v zO?a4Ngayg>yyC@9*e^|;?Jb44MpkS8X4V}$e57~l*>rG(`6}ku0r8{X_}3RvC|GvB zIr3zVk`;W`g%K(g6xG(dtbsId+qw-kSk!u-{gXLyI27cV}rv9zqJZ6~Lt)#`0o z^Rvw$d@-^O&qYT?S>LJ&c9u+-+7l%IvXe2@%FFB};d@dZ?N{P5DlMB*&87!n%6i1j+`!aX0KbTQ2%K`OpB$VSIw0q-vt zcWi{(?8PzBW5>d>W0o%vLb6v>l<2cI-Q<%j;5#G5cqYbLi$iMac1cp8LBe}_`)z++ z030K0F&Cpv>w86Zz#ZXkvIP;gBQ>q&RjPlaznwK)_JSR+$8WpBcBMvX@={MQ3q@4K zcJ>d6#N%PQBMr@mr!B2joHkfr{cN{IKtOUSbI$p1&rw~dP(I!_J-=$pBCk0X0J;98 z`1tsxj&iL{UaC&I+io4zg%;emCH;g*Z5g;KBPJ&HIWC#;PEO(WS+)tmT7@59c-K?& z%9n2*)=a{TC}zxyG}_8DL2>h>EgDZ;V`|eyD<8jWHa^0% z>4%(PaXWiqz%_VnNCY!n7OXC-=yn% zuv_3eY&GaRfV=p6Jk{Vk6#R(tHPRthXZ1MC#zD(tVsggD*$qwd=B-hYk(Prd^bfN0 z(~(Gl0A{ib=ME0L-h|vL4!7rngO-3jCr9|RoiCNgsx_At7rW$$;gvTX`se5U{ZrEF z!^~ShJg>WI-Mf&r;B7kT=s5Z`?I5wnN?fMHy9Nh&VA9<;-fJl=QaahTQ$hZ@Va12k zrAL2_%U)5F(XvSC?y%{3=9!u4Q%diq4y>6f*RhyJy>%*<@14LriF zxjOS*pG3@u##8a{my790*vIc+Q2p<5|NnX4eGl_}pJw&6k{*MXJ%eA zjSJOr8;0-xCE*QjOMw%b5m>7ip{Xl$SprK(*<>zwB#h3Nf-dnrX5yk(# zZBsWXm!+nVT$&;iQ?|ntw}L`s2ScbXkAdY__z)o$y>OPu?;H_m%AcAvR@YI=U98ip zDF5KL#!)CaIY#x2QurUrCU-HZZqOK(hiUa0iXJ=PCGa_80_s~0MV}^X2yyjS6`6_2WwLLG!2_LWw@ z$x51-q6a`RkDo=#w!>e+2Fy3*eN-eOT(%6`h zp+Z7z_jX#+b>R(7yU^g3l0|}_pWg>w%L>o9TDdX=QyXcSq(K;E8i(;Pt*`b$C&Ewb&&hX2C6Hol@#XX97nOn9 z-8t`IeY4?}9}JhkMBrmR{01c=P=*UKT}dNVRn;#F`&bj|kEN<7+#US#QF*_;qSElo z)?tUyjv`_4c_&ALB(~!6MlfxVAQFO8lmHK{)2Da)ZM(?Hz~UD?gt|v&gFQX(J1Brn()mQMSKo(q_;@0f(8d_VorZ$`9`cXExxyHc5Dn0f3QSLNwqIm9SXJi}+ zu3BY2wDzYTel+gdy3b^OK0HCk&E%=i#k6{8!vWvm^x9%yS;nId$qSv-+A{rLN@yZtr}@5lz(#9QwxqIVq@+*d#=p(vnm z*cUh2Vp`lLcdTboz<1Xv<<}XdPF(2wF`{DY!;7t8gDuSfiKY@N?C#vd30NuyaOxV_>cIZ0rIx&|lOWHz4x6{5uMbd1UoTOn4TCmFZO z)T65pKjP`Htqr)A(9%{}=_k1{JL?ORUUj5PZomN&(;1;hyZQlOnUpbq)X(p;Hm9~Q z+X(u7J&UgMRgK+yYJIa=eTfN@AJ@tVR2GQH9ur^bd;{XiMs+2{#R2*l20Lc+t}?4N zy3iu7(pq4kz}-?4n5C9=mv>m>;zj%T%2jibF76~b$~$vu?Gn@(jBC){w@R|zPN zs2HRB+v@1AU|;*W7?pcU1G=A#QbRvJDl?e$HoPy0?)d(q!ttGq8O>%#w+rW#eL;33 z=Xu%07E(bd0ru!MJUw0+l~q45d21-7-)U|l=7nU0`QW*i84Dk-QO!yOtn zN!A^mZMbA_`)K)%@k?NJ>)!da^6Jqb1qQINp0YQ)8h<9%y7ADO5a-HXI z;}2~!!-klAH_;Zb6pfOP1T&7!W@Xh6Pgk@eb;Z8Ht4K%}rX{P$D$4m>s=Rz$8-Jk$ zn36a_{ot>g@<}Gw-8q&cVdZzrk$Si2zfnoS2Ve{3It3|3Hb>o(AX8;7Abi zJ=uy13MEd|L9+9V&L4?eybEc9ptnBlu@rSkXdTwUX+&MUDt048K6!thTgCD^h*3Dn z(&4b}aC%~sS*}^Cwn#`qidcH$S3c%8c0l)ItEP-n`}N5vkY^(7^FheO7a9X^ctqi# zqOPuv5jr{+YmDj?FHl&__19;WGiR8{n5_2pk4yA72o>s{gL|PP0)?lnE)U)eGq^H@ zTujeGwNqVVa=N-{l4f06H)tp!u|n9&mQ6eJ5F z#S?4Zx^Cs7EA66=1bZL{%9|}!dBjy--7JVp)p+^M1faTzgwvFXt82>(w-N299W-XW zy~uJU3TZq&`?$P2D!C!L;nlXEqNBgA83mmS3t2lY?D;COADIY;z~}KpwloJM1I)_# zD6g~0M~2fy7iI7a=TYYf+|Pv@NEhb{k}@+gGTyw|xHjk0e+c%ub}|i%Zi~^ z12Ie?>_&1&3mkzzm8IK`-GAt&vN;*1r z|MLaI;S0IVdSHoDzWP9=Tz{2}pq;@~7V9$t>2TuUuxT2VX4i_0Hx7>ptuw!_yP4Pa z_K^`L@A>Wk*h4i0mt`h*Qky1BP3#MY9j&bNEgyax$rBZQ?^oG+iB^D|+SAi>OJ*H2 zGqWs(9cHzUyjE+p<)|E-Ty|yrj3w%W7Y7H2_-P98h(=bI%XbL_&a8(J#cRX`aZNjB zkD1izJje3dl_M?GtUJlTWzw;Qm(KvsKP}c&YB-;cM1<7zO9~g)S4`I|H7RMATh!M@ zk=>O+L!QaEXmSqdbz3k&BiPMc6LCXozX7jm~ zCE_Pr?2Y}DtS-P+-wTM#Qm4*g$KSRv44%}~$sv@l?V6rHC8W!L(T|#YS1PYE;AAGu z>LZ{Kqr!M$K_4o@D_2e?01&M+q{XeqnZ32UPMT9j`DWjv^<0<-GRhejd@36$l*e&} zN59HZzqJoWZx%EZ(hJw04<8oztTYqHwRugM95|`3d>7+ZYb0I#Lj!?^jIyt}!oK&( z(?L1DLuo|SF8ut8!~_xKVLw4pHq}@ep1@N4<<%y4F!;R-3fiwDAmA&OZbjgSqCCd% zlaib_SD^GyW;8WIf!GqL9a0umn1pP>RXL7gmpeu-*IE<))&aMp2jr^E(w2?aCJ$PR z?eH$Z5rsapgSBzkDcV!l+TJr;wi@eL6C9ERf*IW{(@iX1UCgRfkrS|O%krn&NF3_10JRZ20ht5P^3I<%x*TsMx{7`b*e;v%q8M64e|Fuo=GB? z6bF>ldlkH3XKS8{iKd?Tid(rfBK#u+B?f|*$Pka1NYeb`x zQccCvh?L5!5}}&=6iIfL{?3wo)05T4l&+kg_C?#?{yJxb=))^?V+9D-;*yf(*WR_w z%{6w6;=E8HhzR-V`%ViqhcuHCiV(9a##g-JPd}Zm`KaPTLOl=rm+5(*@%|tGy9Qfk zUFz(_z;3W80m>U!-6yh>|8aaEf^2LO4wn9?!85BFC0OxpVDdw>?Y1FN>3PdaxC-l-^8I0g% zwb$}czK&!+F=|%SJRo9b_tLMb=Ra=|^PEld8=+^p7ut^eOZTn}{03((kGVJSZ>Ki~ zlpNu3-j#oOzw3EX`G@%DucQ2bdTB)_Y_DlTA$IO2byn9$^g==>ko3?C31^ojO6#EB zF&yYH^55L6_844fQs$*mj8Ze>w1;a;PFGYtgz--N`_3Q#}do+tN-$m>S!$ zzGK?y{d>m?VCWBL2iCzTCCbxt6<=N%8bqbtIWEz1 zruH3|E3eT`{s-ao+t~IKeUZ4%61|#Q_h^QpFge{pt+z*lw$SM?KNZi#$R06lHty)O z+*M}BiLp;_e15u>!*0VC_rgNr4~^Z2A8^qdocZy8MR)#x^d=iU9;v z_lfK?JTlGIYZ`odp*7|aEK3By7=N(e(v{R>EXX%7q&a!0nM`C1I@bM0nLoxgQfqu1m*w#9c7T1|Hy@A zXPcoGYxBloDeHBLwf&X(^z;wir2&W3GStXH!D3N_b4i<*G6A?U3S1-&SRV`t@q#OR zvyE}Algonro1mbWg()gWJzwtj>WldBNCBOUe23)~L{=ACvP82~RWpp^R9RSJY6iTF zr*wS#`pgVV>qkfRSP4O~>rpyHd)R#o**0^m>vVTtb%9Xk*h67)r#FfU7g&9UVvQSu zwKzG81ex*ih3oX3g6_&gCUL5u4;L6)BxUk)tHf&$F6q>d*;u}w=K?gD{aPW_QC<%a z##@GH0<>??y9A38N$C0h?X6mlC5es`55?gB|Tuz}}bW3>> zHvZ!GwHl*=Cz2=M`$)Np3Q|KQ9OSKV{kMt4<58!JC9|=cGaQ>WK*G0c323GAF;tsv z5IcPMaLTg{{o}nAg_RIs%bCU38qG>CR^GBLfA-gOArJexIGQ^FS{qZC&C~{}(v)rm zGLBTeRo32@P0%4*#N*x`hT!ZZd5(TZ`~RA@gHHMpEy)QG(!B<_6xbBuvV~78Lr_Y} zEymE%(edi39W@ZFOP(`B)%UI*AYo^8x~ta@hMxKk|83O+#vujw9`9KLbWPV1l-zF9 znwhpd8hn~>_=#tL`F3GCkd8BE>>M0?qQ2+<5>>2x=%NX-;h?R!4)7q3V~!Ie z?FFZfHAF4!Aoun4d4`t;@)-^ww+<>wwsu8*=VH5icKFg&7<%_J1jNBJd~d~lAD?cf z$>;%wfP~szOFu=^w^6z(Ko~`#$451Ah^8$bqz2Ne@(?z*I^hhMEHrPh6t{Ce?F3ub z3v^P4Ca9ojAxe|A(ox#8o!4~yN?&!tr2rBre@j897Z^&U)j z0%Uf`8yg$zGY`mpg#)t4+SehpbNmnlryRfUi1ONQ@sW{{aMBDlc6QF{YEX>!SDI)q z@N!lTHFkA%)z{a*>i*pl{3Akrgwt*#ZF!5~P-xM{HM$R6)6?s`c09H=1F#+@X8hEG z=+Zhh+whL75M~#qmxqcfkC_O|TEt_)pY-}50!#iAY|?+B_H4zF1mA5{ zP%$5HlMRy7ff>X6dN4d7AYk9mgSPX%2Tb4rygwYL^M%+y z7j_8KzrsjQBK^pck_h}VZflmy{M6(?y}2W1toowE8c5#MM@({uXH z_XCj{G~J2&1YmNE`=XXs^X$t86P#)yq7xBqE~w0o8l^VcSCshgOHS2J2$YEZ_Ps>f zKT6e&b`#sYw=!chN09~Z?lkGc`~ClvKR$o#S{;ohqGFW$LyAuOUVD{wtGl^I#D_`- z6D58eYG<(~PaE6jSXtUJ^uFr)=xV@+dEf~*>@4T$p=KxdtDvr9i|>JNuKBvB?c=kK z+1hE;K^CIEaO6=*Nmb(EZKgqg%?xif&t|hsDG-UT9{{G)BY4s&S!d_Q#~%|t5ii8# zavpXSU1{NQQcGREpPEs5-EC&)R^M|@Y;4(O3Q0;87d4+eh;;KU>Qt3C(Z(`{kn+4z z%c<~O-#v=`Qv1Q!WYv^_`dx=5nbXH@gtniPiL4lH^#nH|nFXGy3U6R{#Yw5Bw+h;w zLK1~S6s(waQ($sm{2spe9~Hx{ars{oDt-@z>N^=T@GgtHx9LMVuOc#)LT%UN{iD=# zd^YhMUsYeJe2=cpWc~}ST%G0?)ZjJu`0dH*a=Np`jpLJ!TDR6!fvR^j8+6B>@mWpY zeFMNeWhrI^D&ecx@1#FX%G~IvD_WDMtqqkYSuZD6lMwfJ*KH^}+t+vS02r}X4 zUC=1510t*pCHaUiVI+zNwNz4Aq+*s!VtkumF_d66T}7td)@Rk9RG?X&B6?&=x2< zk?v{O$w~)X(+GsO*kf>Hgg>MVSl=c0ygylrZ#S9<*QRzvObZj>#gU=|w`r;;gr{bm z`vp&~Z{B$7R~6qPfh0d*qK7SQ_?MP4C8M3PYfDR0OV1?toOlwNr0;(G9NQu%cr$<4 z<=)kK^kUTB`CHFCIJ))`(KAa63(lb}UB{xMti=@aZDIRBz9&z?xwQ2VI^6kf&Z{uR zQ(E)b3^8h47UwSPFp5!OeQmLGBY*S(Hr~#B;bg^!dr45V_H0|Zs?#pL<#uGfz`&!@ z$(BJ^H|2pvYN_}qg-6jD^jri#3A%)1Zc^gnY{@5rHkSZ?lUu&%IxZ9AMM7=3X0%zk zUN}U-X4(nFe}?n^a*+?k{Ny5!=P1t2MGBoU7D!ZX97lP52D* z`IsguQBq+CE9iI9NIs1nikfrhTANg7xt&Y+%W?N%Mi)oUAbIsAR{Mnb4ll1!clQBD z`7x2@y?6tF0H4_*PrYx@?|>tta4j)8uZcvEF0|uKchNI zgYIbxnM`Ki2J`Y)$U9dWADJeB+HpzXnBYB*zzPg85 znnp%(r@O*ORD+D7Tm=Z?w#Ym>mND&&!IYY>uhpV zbsud%x0)4rS1zEp*BS|}D>G15DRm2ti8)}ypR+_|I|WgbzbOB?XO%DJ?$0;}#Wo9V+$WPo@aYf1wm@-CmdL896 z)HY)?_mkD{xz)WT6kqrJjZ~4CnR)1C_xh|3C$kMF?iqFYS98l!zM?8_N9j5Z@{)t^SI$Q7VmmBB_ShbJ)aDUfn`xH_bDSgi<-)P}JlNsGXtU)`)9NKKt5>Uk4C z%bK#XM@UB_)mf<9cT3`i(GErJvTkAYf~Th^a_ijNbdx9}F8ibPc zX>NUP%5dv9NOM_xMF!?N&W7!=M)?H5J0G(&asBDD`!@^R9)A7;0{}PZCo8S}S?EY% zus)F@?RwEQ0?vJ0i*}ZMQdX8p9X1<{Okek}u;H=-&SaBUEXtdy$B~~jnDi_c9w||=0&l=S3L`<*{zj0RQ^&6g z&hgor)$2;NSkvFz+r?7^^V)QK$L9+N1E4}wS@-ntg2Jl2%h%1!c#%V4UE^uuqKP3Z zRce_H|E4ce+c!`Ln?g%3_u7^me(XN#nB6&H@YP-Lt6a|~ront>G&DGP?9dnO2Bbu4 zDqcT#py~ELJ+`2m<+rfdWHx;?yWwj}>8srC`oEGh-3z{9pL8J~+xBnR=klv;uJo*j$T-Fcfk^W_vuHWzt`&=Gv|G6}TYyWFITwpgzL*3FQGhVSb<8Gw3 zoy)@K#)foleLa++(icGOD`GUh1H5>HJ4>=|-uor4w9{9m5%~J3i=Z z_Dx`~aHVM}(fy=utfuqfS9-DdCGKU6_h$k^lc3Iwg{~eu z`ti0054+u!a0@ zLW-$#G&gs)skWPIpNDwty}?a7eM7WG{2i6TRD5Us$GF}D{jtVZVyu4q?Ly1lbmYEw zJm5sa*%AA2vNRzJwZ~S1azO0+Tv@k$wx9Y^T2URX(=$K41C<*QHgxYh_W6s%0KKYc zgFSZWsbiDCKJZ@z?w9yR7R1g{inr1a!5#ZeDmM#TE+ei-*JucO`h+gS6!-I)6-b~!?SlYi86q}Q(>vVR#I6iRnhQc?m`Hz|E|Kb)AzHNp^GiA-(VfY2wy)0z(g z8pG_j3Ez#E#!c+m=~Bkpl)1S%vnv2_7Hb|gMxji`7h$-kCbOYVpX9*Lu90+rW4k9$ zaDLtWk%<2L=?{c%GV)l@;2I6RCkMXZsery0r^( zbbyIIbmMkFH|FmKhDfj`tq3Km)jDvZC56ZG*TU?@**3)3*qHVKG&S+RUH0L~^;$-V zmHV8>4a?S2;qK*r0vrtJdUF1F<2-BmxVQh^s!7M}N2u6}Du6T0X;o-z)m z_BPF9=YS-#QRNxrSlZXn(jd`y1+ZM-zWvqy=KAd!$jSJJsKwTH zcX!K0z7G8iHLP!ue0R&EnkB>qT0}Xl?V_kT9z=Wrvv2kuN zt(CZW4PB^|oSmIbOt{1HBF_W{H#tL1kK7NDISQn-v@99YUjPdIg*VFF#}Sc@x^7js zrGrSP7l-TF@1OEztrokIHaL1anK3+@t`^MCHOrQ)KxC6Y3|4d{Rz@SXK;V32$jGLIr)-f@O zZIU#!lClhpl1pSOwqBQ9OMU-d#x{o3-N#%tE?zTW^S8^Wax>Fh zt{NG=)Z`ro$h$B9xMR+Z@k_|1s%I2ir$UkYDmTe*f~|`_nTna{Q{$oDS`7fkuDc}? zNzj)bKBoMu7%K2i3CzvUSD2#y3ZbNCBJiFAR$-Mabkbi^!z+umVM>y zg2Usj`S_w{7VYynJz+i*IB;$~BG!Er+hVy2=W#(xY4K^if>}^sKsK_d%zzKs-Q9f2 z=hKsNBn6Hh72xM*>uJ0E7*~bU7pO1UcEj3Ykg>VSWg>jIk;~YUXn2Acy5iI1tSrqK zl`0nC-Um(gJx@&SqQIPuS;r9Lv#FHQ&~QytP)KOYQcR+Y-KjNH0Boo`Dk?~+oh+@Z zlTH=e)Kga%Ho|sbbN+B&t`rD`^#x@iA_WHfHb8H%2DnGYg1#uc_OH1pCY!+<-l37Eq{LD6>?6yO3es`+eS23{f zUw$%bK65yMo%;~tBW`9xruLl@)34RAB&brB%{#jlTVL}TyOEr4@|KT;bXa~{Z>Mp3x}2Ho;kxwQavbAS7)$lm7&)y1Aji! zT4JoUv%k(g+e%c+c-w%Ig2^m{ZVbfDMV>z$J-j>tTA9gDo;(5S`h>posl{s|sdU;9 zB>bs00R7icTL-CDckb&q9o&5DVe)O)phDf&j*hD0;*MfjJ$5JF%J;)!^1Y0Nn~sU6 z-DmIi?7^z@VpOTXtA`8HrIm)HCdBlVh)~f*jY;i?x9uK*(#KbSdUpF_%0F~2*EWwV zO1Z~f)o|A1iDvb%^^4r}%YmUQQKyUSg?a2W2k%!{^)v~HogT{GwbVYm0*=sBMz_Wg zNRgT|r)_qJHs!jxEok9njoXG3P3FTFwMGrGIG;8|4`Wkj^}*Yd=|FBj!qJU(A-O@m zK9qL}X^_6)>Owvq9+&=~mxeF}8${BZ&061BbmCQrFpjq$8v9&1(^=Ga(Pgxw%!e&5 zL_~umuPE0&c4KRTYHVMiCANfn*t4Du5{PbB=Eoghi|T^E~6GJ$db1Qe22ZI^V*T@8;TS+wG7FFyH)0 z&cfIk&q1a06vghveA}rn4FW6}SURAOf|4p1DsIO+KY<)o&jAyNombs~q?rGfn`A>Q zYFTDq@wnh~|Gw*69~zCBJhHkXr)09Puc}@rV*B(^*u9GI0992vpZ6tx;kOO&$j7z32yjRk$zS))X3ZebthJqPD9ky*matOyeiypKm}i0;Cu0^u>skv zlD&Pb%v-k>*!NXM{;dT$9g@>X+i^!7_sl!jEqgu&wcpEW^@vDLMEV(ozgtT4M!I%( zB2G5&vrfCm58}{1EjWvTJk4^p3d?^NoyGNJ%-2 zbzQ5+9777TH3K~5wuXYNh6)EAQYOMLvZEH#!4-<)VdbQ!&1POn4JHO6IcaHuS`HL@ zB+XO~W*@Go5nWCypIUxiv?axarH!=E?!^(+A_NA1TOY#1K7}>sQFs7wT&)nYqxMt2 zmniCSbp!Vdk{hTt8{-YsB&DP{rX+*>4EsaB3uYC&QH0gXY8)_K$Q?X!r`>v2snYJT zv+pSsN+i;?^4n-5?sJFNQn8SgN@FG!wZs>c!1l(xAqFY!(mNA-{(g@Mxl41y_wecm z?L1elv!8=B#`9gF_tpZq93S(;OeL*TTUD`yHWBb9$3p~jOKOU|{k>wefZrxzSlhta z;LWFizuoBGEG-mY3{%{r7XkPr?v%0RBzuotDp2b@MHu2k1E(AMaZYe2EBq^fU2(7#IJje4BH^p^J$ z%Dpu@6tS@PVd95SkSxh!e(E&IY2rl+d5SvIaq_^csq(PaQ^W|qQ4v4{v!$F_P8BV+ zeby@_B%L?oa4>x80Ft`)FZ&?&sk($jYysk@*J{-qwep_u!!sbRo1Pw2{;&~+hDO?8 z5)?AcH?911)hZuP&j3$PnQV6CX<+fz7agH^|N2-dUu0tA#EW_*nZI2%o9!RZ_qk(R zKvv#lcQ)tSYs2a3$nb{jzlWoFLoC=5N;<+Wi=iSDsBTzd7B@WKJ%>%c+&0pFrC@&(Z{I*w)7`WY=TCy=9>b2Sz zAa8lwSrIBKAS!w(ww8+t>GbGe-t5X>%`epZArW_k~ua5v0BcPiN&VQtw*$f916Ji`=wSyu9 zGilG#NZm>o#OtrECTp`o`C9g6`<^h*$ZHLOGgkF!r{vxsvFIfvxNBdizz#+xm6hnj z$$@=E9UUbzwQBS(R6P@6-Hq#vTsuI33u~fsk*M`Ke=SnQXiw2;QfZ5*wZp7(0#Q+8 z=^$~)Vf%TRvqe7x%H%Ec5a{#x9RD)?i+=RjyiEDB_|I4V(_{brfSKYrWpkNn8Fpi8 zXn9ML{bltJKa_90By)RhOC?MCvsRkG+c(-GJ74_ycH5(!#&4%T9Xq=zZnITK>E(Wh zmjgPds+wy}D^xS=Ibn6q4F!qkq*UO{Ys0Z&x@30mg6!mr~dsU`9JG2ttr?+!k~d&ldKvmL?LKC zRgq`3Y|014a-;qNk=~0SHj;}RJG_Y*aqfCsL@(I*{2}g?c_YnzZ z`Mq%%H^>0i245fcK5HCy9N^4>7YkM4lHf z%J$+ES(JqKO7vMdv1S%jgOwQ_T|ho8R7*~-7C&q;TNl@&KagP?7ne4D6>;NLTe}FVCvgt=Ihw$)WwU{W zql%I*BMBKgr?m36w#)8%pbSR1T(h(sYsq%_)s7G9W*k!b9K%@ zeze3l3PgyXfJYJ{zFfChLv7DHKG>4I=rnCqV#_bt@-aQR!Q>Q*htEY|4~!SrR9%;VEUd2LQ!mjCUeETC_AbkT9p_?yU^k zj_u1dGt;K5bia>-?d=BT%{aW_h0R`s>`YsY$m?%HB|H_{BWG}4gObb2%Ry9ggqXz! zAlLyD!{>>9Mw%25P(e&ZDV4-OE^26qAB9!no3u2$vGW;kj(QGO_w;!A`9rUPMsPT4)nE5m6uojA_`5uij%o!h_pTR%1S_iMV*n%@2@8g!<)xh&M_`t=dVu-|(eiOh^3 zRuqf)azH}@h8jdaM-deJHB^=ZCeK;7lA(a-9tCX6U*K*Fpm*fY$mEOMQ94o$?H!xR z0o~n(v(A)ou5nY|`j6=d_kldkQ_XWD1)652GmOyuZGLfar!fPGkHFgv%E|MQp!OZ2 zca7Ku3LryRZ_=E&znrDDKLG)DAD?G44x9s0MteTu4WQTT|0t9EsLy^YsO%Ay8X`Ik zKJuaugUGZ-GaCQ%G^~`I;YC*_VJSB3+sa>hS7Xd#5t`UhQ)KD)*6mNT4=SIVlQ%ZCjO%4e&&J> zJsll^-Wgx^TXdEDI@0|Yy zXU4%n;7XR}yB9{~!ki`DNNcH6b*fjKv(6vfQ8qf--*#D`cL>Cd+|e_Eye?mF8ea<# zLkgiRbPy29xDEJT%cDfu6J=Fm&+fP0o3DHQdZLOUTqRtD!rC)G=QEQVmzJi&#Km)$ z90iA)8s@tL4a&nxyA_ATK5AM;grKKaC=gZ@n9qtHg*Z!ME{%2+((WH~TLS7XPZH;( z_Y1g0E!t>!##h?@&wTCxxyhnir)JRp2v3VG&6VoD>Xd*9@+YkUXz?vWHxa3rk04S3 zGT@gl)2~8;n+7bla;*E#i{UUpv-$!c2@t_#5#2!N6KJal(_@r9LGByr6~oe255}}l zm}3-uVY&Jbdgc&ssIIc|u(0r>sT6)RQ(eOx9>tGb$bc_BrSa#_%j-|{8V$TZw|-Or zilk`?22}L^mk&^pu9$nWvhM`!GOhkpx241 zsVLxM$$3e*<60vdobmPVyB!ED4Ws&e7k>G@R5?hjQ>CSSL^cJTg>6p^3PE>0m`q~x zhL40H|6`Pt>U;X^S!a{kGVysirCI}Nt3d}g0TO&ek==4dY=Xg^mz1t)W^Zr5$B);M z5wE##w|`0Kzg|^L9`c*#-q;X}?tpFMk)D;+)JFO3$q1@~wu&>?fl3roX23|YFtf8* zzT$rRt1x$jMl@Lrcf8(~ck>#%Tx$e0>*?JmO%EEKs{yq@It@}wFV-&iFst+?;C@J# zOiEu2tvKl#Lf==;;l!VTR>K5_d z=R;4iFNcfLB<}+zD$CLL|E<4o9zRl%*nDw)qDq)xaxWvEV(j@TXjjc9uFxL^fC zwt12LHoZ(f6T`SLrRofg`Q;Fhb2Aww3J%lC$F+vhK=u5Xrw-XxRAImjU=Xpz-9Jmw zUBgzmAW)H(-FpA9uLYWLOP%T!huB$5=Wn&6$V7Yx-w)odyo_CYi56-)-ci}x-^}{tr|B|3pN~6Wef#t6=^zP*e z2iU$E?)6Rn=}sJ{DM#PutyDyf)owS~UnAfrY9L3PVn)SCl*HX{pDi31OT?;|H1D}x0&MWp~oaw$E7k@j2WXFH^W%%7w%%DA3pVLjcNZD~uj77+?nBR!| z>e2g$jegq~?WDC?ahe%lSUdM(Z`{4$MDcB+OMNY==YP=Jyg@V1*uvFrEzyoFMT{t# zgCfQ?Wn~I7ek?PO_xZ`niX*dSyNdG^7emJG1{2#?=pLU~UOM+U8ev@7}!`J?V|oUh!x5&(!(}hbfBOW3}vSgBYaW-&-@N-+%4amwAxS zOjL01j;I(od;~cI;)NJ!I^L5-X`QV$=T@#q!GmSJAGKlhzxvG>uqZJffY`SmW6ZT z_5|nokXLLe1nu#%M}pR&oxm~!o8P;xCiv>z^x(0#{4(aNSM}i!4K;luqk}}xl$6|w zmqnqrq9h`RKs-82pyc(Ed`Ma*lDy6Pe?jfbsx9>Y3H985;wyN)GGQwE2&PD?cq7kl zd&KE2SM62+YI1IvIcT`A`E^DHEAh4hOZ)CZKc%WB4dafR`~1bU{wOIqt+hF->4`tf zn?pXamGjfXi=!RPGh)x$h#b6Q4Mxo8yCaq1ZEzUqCt1QF)oV5S6fktg?$<<0Xn>Tj zw(%!(D=TF+{mYksRrAOdUo{Nl9tNiLVB@2?Ud?&?casLTt!5*tfx}C;?m;381Ss2A zha9K>a_L0A0nE6ds$YpZdeDEPaz-2~c^k`8*6k(UO?zb=A|W@oJ9_Z$5oWwmjTZD^(9h24j2Z0=zg8+ zQ>7YvA$u3j*d)6Vjy)y{sCT&hxEA!sC4O1H(dE0wC?lH{w}_92hKFZ(;;7RxjbIlM z6o+4L5VQR4K~KV?lF!kSKKWTQl$d=$(r;m%C;8Y8pkdl#E?Y z=F{Z5)l?*}ZXN-D;i6imHEN=30ITa2PCmOId_+p?1Ds$I#b+4)y+;?p9XeHjv!e-u zkH&)Qks#-#h1tf&U}J@!mE+(t)X!6U|&pLKSfhn}XYqaA```6n+BAx`*#Lu9IVSu-e1vc^V-=(V_@;Xsu7PP zP`(KX?cHjj%sw0OR=6wnb;B#_uW6A-NYGG-vtN3!c-aUQqCfk`2?3gKrbA@hj)p4l$AS_A+}1g+Yz+?+k`UODikR zqAms-(65r&)5k2=#zjx#h%)Fm>ze}l)urbC{+BVG=@Xw!pHa1E4TVDjmNIRxUM>Ct zy~e*YIqM#wMs6b~pXjyjr!&zJu5$@RJSjQ*CB?)X2mDxKQY`Oe!%ETn6f^A6nJKrN z0oGblKMP|4R||k+PcjpHi2t3*rvdXP*T`&#@u>EvN7;P`TJ0iM!bUwF-Uvwd+H0uo z-#k&E(ClYrXIF1iWpk0s#PI~QpC1*W90^9jVfySB?xZg@#4pRM%krEj)=|@IA|!wB z&u4tMi#!jw=9}65xvuU}3Itgu`L@>9U9CGWIEE-j^KEI6|MzdXQGo)$k72_GeX>>C zX`(L7=|lBD7%&M3J?x8TcU&;_)8Q8U!HNcxa6naG64#5JRcO$%(;*Slv{zI5a zxS`6puyv#8-qVMYfBqlc8hmR)#DY8_H=--hv<8N@UKSw5s>ZrXdCF6s)0W8k$(R1U z7B4dFF+r~K71WJp;dm>}YOGNMItrAo_6z|aFi_Fd6KjW)rR7sMBToH_%O za$214ZB&=9;C{W6$@Q2#irW?-9)KC*0ErO}Q~W^@5r_f&I0GNy5?fNjZ=7bsKKmIO zT*t@Uyu1$+U7oSaQo24yN;w9V8Du(;f&ZkxM8%Kz9jvTXQj10ed(6fVAQ(*OP^d%G z$-<(YrlMXN!DxEjj){!ZbF>Wr0AL%4$+nM;RdZYf%j31k!m)x7tDE~0HbAh=Kl7~i5EeSAAdUO z7o&nWb9<0c|6P7)+);n3Qplc)+M(ni# zL-#bLOWEOM5Fr77r@81y!`7eLhPX^nN5jl)$nO;MZYQ5FW>*GU^*0my5#kfn zo$b53or7Z@5mXl2K6_xF@!R8h!Pv{#ZE1^T|C}0n^7k(5gtdFt63kp8z7&(?_#h)A zV|{XFMq@<3u`}>Qv9wBr=IsqP_X+T7ZMyV0C}{N1ZXWYX4B?@Y6ThD^(42c)7_su^ zzQA#`+EB%R2qWs;ABxeFzZ+lqzq)(Ns3_aEZFuPJP6-L=kWv(oQbJm37(xU_q!kN6 z7?4sr1q4w_7(h@EB!*7uK|vY}q!elV_Tlz<*1f*>|NG5Tv+SFfRT#a3a3VmnDBRCk{uHMfSdfahUX42haU{V~?vocJ~}OiSgNt(W9dlj5Rk$ zh$ucoa>m9LQk|J@na`dbmJh98Iw%*$V?*oY7`r#LzFj$Q_ zYgr$irmxp4$Xj;A2U(Z5n-c|-&wF1A`5hAd>#nF?)W{-0qfVlx3&|MqY{c>D5aY*g#3 z204Lm{(E1)cHSTU1c1te6PIj6nJ?mwZd86gWP9|+?twJE(INs7UyZ@!YC`WbhQKE) z-$TMcf(*pcPH=Ot;JcmH1t|tq_lnbOtSnP}KDbe-27Yy|ZQxIk(L7k5oXpw>o;*Kt z|LwD!oHg;vMC>Xam5V^!GL=goc~0hV6?XwPVVl#&+}s>ANv*aM7K6=l6ie~q#*Wj$ z0F&ZhrKuLcrwGKae};Avhi2b+DLyyCSJ;&%b%#dN|2qa?tI&%Z`KlZM?SpDPIa&CEJLl$oL+E(hvxMqPV#e3c3 zFE@D!+WbWDPSU>!2fG;hJE#R%vk+rD@mfJ$uMI%su=*YDaGrmD&)fT>VT*8EanR%i z&7b~Cw);Fv2ed-ROl1Uu0FJ;O7#1KFL~cTgVL7|HTEU&`yvrwO#o{?|ie{}ps$;&4 zu1tS=`}O}YD-jMCTEfz}S^ zHcsE;4TO%w+b*Czeb!6)9}l)E^(m%$@mJUlcX#)S%TN)0bwU)LNv*yo%#im8DwCje zI5@n{a|8gZI{Bf*wRf}s2yy@Ucyt)Pwg9vOHBm5&kc5XxDZ8;l+a$$Q17@Z1JCrcT zy~jsfDX$Qc%w7`t4!sNANqbu{4M4U`Y;#Yim`W z-GKtht;U8AaNFR~|M^@_3L6`|#N+!;d?Bq6@R-p4?CtFx*zCFmFhRGT-B)0ul0(A! z3Nm_b{PfTIx^d0;^dFRB$#nhO%F4XyT9F${___}Kc?Z1=KbeXpACzk_!9l(E=UEF~N=&d#we^jSbu9tea!|7S+jkRR(LKH; zc+OwOA?+ab?DGE2hQ!w?ecUEc=)yM|0(H##vj6^$KZ}E08ZUuVgu`9HdM>hp;}hKh zko>P~u0B4ptkDo+x2e8XL+<4`;#;0Q`#ah-2Cdi{W;dzIK9@mUZ13O@{LP1Is+9Bi zi_UoQBaefa;i`&?*-yT;lXKgksk{Sxo)hOPLF;9F>^qQox4wgD12%DgK;kEGIYcte zArgD__6N8rZPIkq)L(zjjpZHRkI(c!;oI_Y5VH-ZVrnuVM{BMCT(^82sxpng7l5SQ z+}}q>xaag3UoQaTgGSP@e1Hwerr%JpfJ4 z!H8_&r@Ave*0L#qbKuvw5Tu@tzCkyyyVlzWKhFm}g2mV1UTa&{CO!TBmQlI&C$B5V zv~7epr0xPV|JW;L_KkG;f>fcSqazC14Ey`{0_+|)_8pR4jRNjmU!+9==f`lEGO3*U5MUKI zy1!1ue)w>{!DFzm_&807SY`bu-G|8K`kx)4uJn&~ig@VtFTIFBO#NdIBM^1}bS4o9 z|M|ZJGaqLzLo(EE*Ji|WSet;voc^h+v7=*afPecoXtJHRXCr0tw{&sHd_Cdv;nxe^ z?<#h)4g6uN&lAt6O^STHRQ&$?SYW~=B!<*zXd^&aQknaIU*?NzK!bt%G>hEcSKqMix9IjfR~n;suL3Qwi96s+jgtPbqdtQ<#wBBhi_j! zv^CWC`0=K)av;lXaAQTTP%FDG=6Rx(yK4t|>a9`U#b>5hz~PSGCJ z?Rr@_3AWG3^5(7}Lgq0~Xt6cn0!f;KQ&}x9X3Rz4WI-y)iafz~7XPqUc=*PHf~YGz z89l;;Q{g4WKC>%MT&CbQKxox8^>Y`k7Dy+^5?Hdn)OB<-za>GXA(33V7p^5nvt~gf zY#VYyi+n97^T0lH)d=y3G;nD|F#U|h_N~Pc!AjFD<8eYa9Cw_6BLHK-7rt@BupJ@@ z=miIW{Vp8fh8GvWq~5s}vm=j@can&1x1>kYe0x~^rlEo7OJhk%G)r*tJf@Zp)%Cmbs;_)v)tjRJh)>l7`Y^_py|yId6g|iB;N+M%h<$gIo##Ew%pY zI*XM)d-=wK54+XY=R&lJRH~IEFsXVbcvWvV-Jz<=-H>5lT>(`70BduO)dvqAf(rfa z=lZ0H=JDMKriYS@AMz+)Ia;~fRX(U_Y#gw@ki+<8`ZsNnGLyNj1l5-1?O`ZNb>dea{Tn;P{cccHnp6QfD;2G;KY#Y!-c-4u z?8h%cYavk1R!svb7)yN!&EPrJ9`su4jW*`{yZHUx*$}K(W2EotPV@Ug?w3sNaDDab zS4YVL$w#RvDVA4u7(Kwfz6i9*_MIN-#uvxSYeSVRX8c8Q6dfJit~qo(m_6Lz+q1l4 z&t-91xHP5Jk+B_4D;GVgT#l5>9DH{6 zmgN}47-CjiRK!gEGmlemRuaRQp%_M-XAe#MD@ykoD(I~hnnQxwqW*fS2JQ5R#7v#Y zigaymYuN|jf0*lNwqO9dZ&s8L0zft0oy|q6cJPjYgQgmMWZND?!6TA7+`WsPG%+(v zj7o|9H2r?R98skE=A_{FsP!Xg4Pilqq;_ai6iw}s0Il=#*+cx|7hCV?DfYyeIZ{tw z1vg&s*&B8;Qc}~dJt!tkh|bs-IM{A_PC2Kyq~6N8fykpCmd%)gXIltO;^T{&yiBYLKBxMYY(0|43cJOZv3GwnLe}HCOfmXY>^K=mf zXov)VE%(O_3$3lhXWi3MQxe68e06IH>Ub5?zX=UqPh-ydz5r+pRD7$>XlM5iMq=1c zrN4lA>Z$hWI-8$0-$W9|p{Py_}i~v0U1UzR43VW@tV*=Rh9f0W3Cuu zKzI&gI0X*B*^34E>{lxIP@RHeVp8`AcwV_i=VF~sba|#`kTXZ1G-}2AZvR?}Z9Prl zg+v?H>)Z&V%%Vx!Q9db*7>FnyaIHnVp?o#$ijWv60vN-o4&C&^q^OEWwh-<=Ti?pWQ?vUta~ix%sEu9hi-o zW}?8v$;oD^ZOo~mFIaR&lrzK2vJ^L*40R^Oqe=wH`%62gOcrj{kXNehU-a^l)4J<9 zbS|dlLHtgV=+$CI19SZi$Iz+@y1XXm=rCy-^=0mNq-11FpUIkD}F;0z$Z=K<+v=5|t-Q zpFepq&=pMs){1g{87xS*DhKw-r>@T~#toh1x$-~HlhxexUD6}DuDM0W*H{wuu=UpC zZhdbpZJhdpHDUJiWM`)N`1*<@IIxuquP=#F*Oe&UCKulGVUs?0gXhTe@A_N<6Bgj}`%`$|XSZ`-td2VJA4 ze(7l!mr-^d?8(kNBUE^6Vy6FqkHki}*NPxJj5AG6{?%$116x7S2g)6JAZLZZUTfhi z#hwq9ot)?@!H$YT4x0O&Zxy9D852RtSGndeGYlz{iMeVT-+c^SOD-yD-G&7)p%c1u z-_9$IKQq%7BRa`Bd^W8ZXG_I;S%;tHUANx7)a&4a^&}jW`OOGR_q?3SK}?;95DuG^ zpytZq))`qfV!qq8YQ)m>4IxvS`r8<#QT9=4ShGSRTk@&RqpM~r*d^};M$vT$*n_p2 z+5z=sO&ml=RjJ8(JX76~a|9Y(8+z^Q1q7|!#7GxY9ylekwb;42ThlTVxWKasi_*6U zlig^?fL%Dms;?Vxm6Qzk$S}X^*Tw7$vp#*NaSnAJ=-Q%c181jPJY?EFlQp6 zJ2Z2=17!X$op@x8y;5A|siE&-jz4d=PVwib3pDpB^M!i-YRGk5nErh9e${0!*vA<> zu$~_nKx1HcdHXuAmHSd2%gU(P<5qBxT11{alBfFk`E$?n6=9{~qNZ|7lA#a!=2VIt z@vB7meO9sx1bT22$bxai|xq+H)&6%VXh35GG*5ppYlA#YXB%(OV$^DViZ@~ zaOskSMCtxHnKtJXOuNX-O;`$OgxT>PhyGIgg``OdDtL0W3PRlnZax<+Bz_1p4T4$T zDJ-#HUYAR-(9}KgOtL@GdJ#IczLLMSFLM=>7~*-c=?9sKOb-j=U7hNPJ`8`OeNx`3qjziy{41`kl03 zDj%09@=Jn^bP7J6sV!A4kYIf*!7Xm;VsMYCz;@Zxs?$M2T&a9PGr=`l-L6=G1G`8d z(fNzjRVGPZQBl}>Z)@D4@5n)%;FYry#eiQD@rtl0?I^c^tkRR%7lbWrCBLDZeb0#S zX%tfPu-#4bR_`xs||0dk01D>c=A%()V+;#ZOjit-IC&9@0EA8lj+&|iU) z{^hyB^2aKz0^XKK+3v%(JOpYf$>@)*we2UV{J4Ug@`0k)Dx$03=9O^!FkGHWhr30m zXnG4vlj|o{!Fcnh{Krtk1m&ng1eTN`<44HEgjK(jy7F1ROiZSuTg^pSG5fo}UR~N2 z%~K{3A!WMU{81%h`?idRoRd!^YDIXKj9|uWMHnU}>qp3>>I70?^xL;nMpLcT{mKcB zt+tCro=Gv4DXz#*Ri&-OAkNqA6}lJeI<>G&espzPL@+5U94RlNt2o=qB+NUTP-+_U zwBK4`JGq&`GDY=#`5dF+!``+kC@em44d)v53^_KEA-;2se-GDS&|J0T$=%e>>O#Q+ zzx~GLowX!G+W$aS>!x7XF87NOz&YH5Q&N){RS(qeC%~J4(ATxMZ`gwTTd5E;s#pMZ za;X|ft5tc%beNRh@FmEoDsIE6WKQ1>T;2#*kcKFfh`F9_LEqlm5&50u>m5sd#DEPd zOyBFpT?>YG)1p@EC~3FWu?`T@>C~ZE-Uey60Q#7(&vAR~(Onn~Nhf8KZ{T(0ap)>u zU)rSR5;Lk{5c9~Ud;G)fd4Urbs7h4C`ucSwA#u5W*%9n!vZ%DTZz-;E<`cT@J85N^ z=Q~m}$-%LmWknydTQWy|)x0^Dj8Hj(^B@A7K{4Y*sHimuKDf71ob%&}S!ZH}ZtyXU zvL`3M7nxjCGUf5|D2AaTV+T^OouX2l1sTI|*bU0YnW4Fbg|MlU^WDozWaPqNYarjX z!iF59QeYXd@&8dO#O?LxFTkTLxjzL5Ca$xL`quUqLBE!v7yFZ?;apG5Rc|ug>{n{Q z0)ndBTCUk8C@B4PV?#sVSa8bk@09OYxJX3Y@+TL5^n-qZtI$mp$~!jfiU1WBo#;mq zTN%OR|88Hi5cvzKb#qgf*rfCn4s7Z~D0p{*1l`^QviUUHvpe1vo>t!JVFRH#C9^OB4VrOvPU7v&)^*~C^Sclo9 zTmYt@(fJ@ngy`27@k`OgLVg6aDoM8>NlLcH9juW2<&`7|C%Q(zdGls{)_vM6*f}Jp zSB)t@LsPMZI`hMGqu()s_P+%MX_fY?v@s!f9zN^0EgRJ}CJ|lRx=Z-=G5Dz(?219= zx`;#Q=(R>{^*RHqFNQXBFci9GZDloEhG)(y?Uyi5G_lPXU(1-AoTOxQ!{JS^T z83-!X%w8d%jv?@?l9-v;rLxg}yTqtckCqHQ-N8T3e%k2f*Lg%-Y+IZ5A1cvwK^vV) zwrXOV7qbUjxp_9jOPzk|D+wqDM}Pk$y7FnI->zX4!WSn{8pKS2vcCe?U_}Nd0>pk@ zHJI%#2)L{XS1MDqeA`)vHS&1IF|-R>OmJ;{|BOzT@|tAZw>@(bF11ifzH%Qi zjgTAE8C+-@zs%|=IdrhQlSMBHiw^OL^OG_tcPhmiazzlYuC-k`A8b<1oxS7O*+{O1 zI$BEW;`XQ$cUXRwg4BF78zeQ5^_{}7EPmBUJ3mEc%Hj6xBxH$G!j;?4W?n3yqAzO2 z??UAymwUHq?2lHdGqLgde6_tsIP?X1nJj~y(~&{9fk(MxAW8qM%b;zTwVy6?c$ zCBlK?F-2W5?5i`f5jc|l0eXX>UK%VZQ?EH8T0Q=y4#nHQ7OuE33o|1tJ3E#&`lb)4 z_*>zy+gNFM@FZgWAzFe%W3Kav(<2_*^>Fz9&+zLtm*W!jFo7 zLv2%Qd#yZ#M5W5{&O$PBI9-})NLky{Q#_(NM%=T&3FoK*OV6-VTeBmA4W3$Nwn#i4 zh&8$rkwN{Vp+U?_l33xjVq+^PPGs3)s^n2V=E+FS{Q)mRs};dciGGY-WU(CTWlCCR zrgJ{~qc1LK8ruG8+xKd_?vavf9&H%+ZIL{ajtqbASZZKhrC&M+sT2v%>(?XcZoxU{ zZA%j=^YsLSwX0UyY{YcmXP4q`%<~k-K}4`@Opq(icx+QzyX@PKADS7f(NA$!@ZrPS zUx>w*pO%YJDb)AyV9^PgBD{P{A7$?;UAEv*v|5Nw<(TcNg8T(*&{cLcC^S784aJQ4 z(>~V>;v|AmHDC^Bs)#klu!JD@cQ*31WVSM7umIYB9{mO}`-*T_4pm_KSOh_RvW7mN zo0oSf8HuG^I1x8Sw3=H+AnBghtkX{7W-1H2c<;5p$*I7^iVE5D^%&~UPQ;@upEPMa z*^zQ(tOh1YDfsT}&Q|2MsHBt>RyW*Sp&0gMbp7K@1d1Ut5dHH4Jj}eXc8QZhHwY-T zu-0}_b9J9QS`r?41JbA^ELb#iZ(g5j2fGvwK2DT3hNPCgNt9*hEF`CBbrtzQB^IxO z!-Mqjpqz)~;`C?~603w9?8LlJmbohHi^YKRxiO%15UhUjUWBy;M-5&ok^Es)Tw}4s z@V3+~YOXqV`E6cvur!7+bj;c-!cg|Rwu#aH0!`?F4>4vHMbqo|I}^euJ+oi0*s-Zv zG!Q04+N~(;$e{%9m4wQm+C5v$7@8N{!(bR^XBYE)$IWVQ6i9Y1;f$`6id1Y_Oie%+Su7a zG`X;}HZeKb`=4cZ<3{Xwaa#@u?B6-utBw)vR5Q;jrUn8%vGh>%X7VehIeP|n#RG3R z0LxV%Wc)b#I0R!2gX?{%=KK)%-98{?{(`O0H(Nwr-C1cj#|fE8RBr1njiM*d0&AaylZuh_!5}=PQY~o{OEn2nsOc7Se35#_7cNev9LZe$6!`B zubjZ+Z41^Pjh#5 zBcp*Ie!1I9Yt5Hja54QpzACRH0gj5QJUV)CUR8}lC@i{-xe|%D_S5dSL=eyC8o7)nwiPf;-}D^T_!hX-Z0Sl zGj2=Qx|&Ao1`;Gyw@{}XFXYU4bjEjY zmk6l~K;XoZM>?__zAsdB-kNT(XqAEK2+4vo2RY<*1m(Noj`hOvNI;n{ zibmyj+gnMcPS{^l$>)|w?a;YJc+=kS@Zf~iEFR_>&Y{TNZ~u_qLypac_&v)nL$Wkn zDRB%<@+scIM^%?@f2-F*8#1LMws?CkRCP_asv0~KK^x|?J`mQioIP=2j>FRZ*6JjZ z4Xls+*$56r7pWTZA?_S*WNeAk$(QwVcwxFMLzn8_9xiReQ|dCc5ZXFVP$8J!#W1Cd zoXtYMe~NrWaa$NtQ&R3Nj;!b#-ri4X!n#{6jju(ws4oA&FYI@$BMEpho@Ts2VesE0 z$rgY?2oh#E9Wjf->M2eOR@l_P{TB@4Smxx-k6*q>3hZlNFXQq^4i9A1H|O zmHAnmtt@9A-SUBGw{~UyfJ-V$7Ux zRU;IS#7^L(Kc;W~R@dms@z77ci>7G~bB^z#CH*?4z3UN;DuoZU!qv zS$Wm*QF954c~V3!-%>cC*b<{BfJNVV;>@;0)C1JWMWdS*W#P%-?GCEvr=Uu&woK-G zeHjWsC@9~jv7HkdF{PJ+X8lHbe{#7%F2@rp3&ouu8LH88~c04WHh?w|b{pjMoJX!xe zc9TJ5R%>Ty(ABb6HG4 zK1whW$oef~1&?15kl-5STgHm_y`4A-4Do&V#tTkE$(vHpH=FHpG&q5FGix z$Jt~K#TUHb@7Q8>G=^JsG;;mGI6Ovb zt~Kdtx;0-8+v^)Kw_>k>^E8EI?bLg%rAgA65Yr4Iz}ixa&ZbeHyU;Y$B7DuaR&h6Gi--fKaw!U^Rh0J^Nt0+a_% zP`NqKQYsbluPzljtx)fmg&e*pbPf7$E*YcS6Aek3)@R8dwIOl-2_l>Fo#ULXE+gc^ zT*5W%Xc|SQXP{5vdo9GQz9>w#Fvwh_oH}!TDB}>C_g-rLsA{ybUc680gN|j1V|uXv zC$_E2lUaEyjXl#DZD@#qWLX6TBZp!j6B36r>^(vs&wDjgnP$CfJUR=L1JoO&~c9U@+!5BW(-oZ-}SXq-ll45K#fH~=aMi_ znDk>#v|)qJW!&e_p4MVgSk*QJ9YUU}Yp`pop?aP7}Z$d zQ2G1k*yrOqDWIrwS?LU4KJ`7FMTHsbD z^LSF_$Cs90!ovroj&%0StLPiIZe3+1O=Z|P@yWRQWV^k2Tj{9xunW85Z>@VMpbK>; z(=f;Go%)mX-X{yGnUS(}l})g9+TZ&uVH9P|=1ZcqOYOHm@RqyaX4qE9WkhX=3rK8; zmrvY6-?+zZFGxA~wfSt%-fT26duVbmX;k?MFZLQ}Uoxtu!|hbBGsZujIMCa>K8p{% zW1zrcl#Td$dO~3RR86Exy)vx0Bx(O_ktJgqr^@CIr_d{pd+K6KZ z3ZNeud$M_CF=R}%J4K?*SWK6lM`@rrn?%|B_nDHFP{xe_e;7;W#^k6q)#GtVm1v)Q zQ{g>@m}pg%`?AS)rS_*!pDg|L^{H%HC-2$7z-!Cl^%Q?L^{0)t=N5hOf2fHQ03hJX zlZOQ|QidnJqX@S9cmc2G*MbwF^*$GJKGUY_{oYRHMDfmd3{n%nDs6(&{ zhd~4by;^`K^8AGYq!Y@X1JHW0jTD7KS`>LHI|{~+{`?8F;G}oh#&$X-cNede2C?!e zMO|_U2hX^+lj=i!w`@l8Q`qtMPBsPWko)Mk*25`461z0Py(AdPdpz8Ie0M`AXhlnK z_K3SQicmb8&}sh$mQP-uNy)g$(~C&JP47&ujnnNC)>lG-W=bIle6 zP-97nrp}Sk>aI!OG8Bi&-dT7VAtr$hUIU!g&XcJ@agL12tVeS9X(?Qx z1lM;sBz(40@aK1u^;3aNC#k@?e11UHg5jSs(t1j$jzdTx=%th`3!;``kIL#)5Cf6m9$tCztJRmO84r#Dgz&)k{kMcK#R*-F+A!({h zG;;*7&XJDB9refsH;m1u}yX|1~+)5tA3C0V4zL*Cao2aP)niTUg54Ae2E3 zS#Lgja3F8!na%)bmE;gUyU=`{Qn6}ID~_WkC+xV)O@ChTz@r#6J2MVD#376GRD#Od zHTw7V_OFUc^UDMrc-t|ey(Z`=xUuNuq+4C2I-ak`%f&UHev?;DftsuSA)Rh`J88@H zYms5i8};(2%~p=Pu_nGd>oL@yp)zuprV`>R<4cUB9nl>a(6-!^R%mXWSzmuT&!|Hy zfs^qJqp|mb)hO5u-U(=w7swW zel4-u@*zNVjhgF1MEYG&F`TJodl1*8s{bB?X|fKz(g%kwNLQKpIYKQ&*2V=wfG5dR z9(V97LF=G2>`c;!w6y!hfGT*RKmrY6sBKea_4c!d)b=%~lOS;)cO1)BwV%>tzh%eT89`P_#LWk&3&?zECI71e%ntCeUy@(< zBRq@EMHwQXuFL#WRh%QPDFU2xI~gwWtp=tE4L_2Ebw6H!Fp>qBR&fs-k6;}R-f({bW($d=MmE>fJ=8@CbYm6MG zsy%Y>xUWee=CGr+1z?SUXu_@~K0Q|N=$z9+nn5*I{Ef$;8SUQ`@&lG#yHKn@{A(Bz z_k!2BO<)V7M<(WAm<->+r!$0BLB2;0W&a3DRuTEakRw7^qoNw8+Q;hjH6prLxr*m0p z&%fO7>BQXd^70K3dG@k9%BB?`-kT8N9Wr*noarn|2ol<{H7Cg)e?Vq>x=A#7oftA> z4jh`!wJL_(6B9E*(X#cwec%Z^+&bjPW%#+L zlImiWH3*eQu?g5?9xHw8q$OdOOb?~`mQ6GcNh%*E!6`WCknD=BvSY>dGQWcZf;l)8 zThGP$3U9SeugxEOMFij#LCDs4va_edMxfL8!@W{@l!7D9(W|Bt!l?-XcEcbCh{s;H zo}7jMFBM9fMu*6DLV8Tv()QLZC9by98n8|1Pkd}Sq0>ZK_hP+2F&UZ>I1A-Zy9seg zb;_VH(kH0sTvH$4HH7$!SSm0b;Ml3j_lWecahQFS&adWlz&XEp5N`|Bvq(#ytxiPjIrPg_PD(z z>+F96VpQbz+{*E--0l=JWMKa=1brrd|2TdXGNm%qT-Ss>w}6^ZYASzIUJfOy4X9EA z8#OPDV+*3NPB*)Mw-J42%bO4Y;U|h5?sLpG#P`L6E&R!ff)8S~ zpoAkio7yc_6m>i98km48XidQAdFselHYJ>buUyf%wfvo|w{Hpw(PL(9aFfh0+F&?J zU%z&zCj!ak3H6O|KN<)38Cn^`R+vK*T1t7fp-e&c+wOy4TnX4k&Gw1e5>eR*<0ZMf0s8D!*ef{GLM~nETux2PIT;47e zwPgL2wSHBh5~KG15;&{L$t-c&k&*@p&^djN(-kBGiq#0ApsFC1e%t1h4Y5g*o!pI% z`_BCS=iXD~^({W4@DPJAWQdV0@wTCYtZehQ53gQDxQ08dMHhBfdW+2`z;SZ)I7Ce$ z{yS(a1YZ%TaGdY0hO#Z|Rhg$GX@SBKjfj8RZIrqH0E*pi@v@VE*$pk#CT-Ft$7um|} zoVqez{5Y5fji-Z@{(AFf6!Q3^>gn@jaWr3XWoxDfpb&3&z<%-upBIF3blZGLc4Btctwn?zC36 zNU|jG^n_w7OW&|5c*z|d?cW?@a7Uy6OcH49~A+KV(09@hQtG zf-s4g4HgROkJg}^@onO%kd2`2ZK8Str#RKW1rPm?$iOwnRoy4vzN>oVsY|gsaq=LMQ|^05$aL*BHlI zUkIAii&RtfM7)|$kI9a#c3G`CbM~yf{V>$i=2}JwCd1A#*P>k)(Pyql@;;QKc&2H! zQ)^ckzAVYCU`dhKJj=!?qs?lqSo2_RN zQy64x-oNJ}&}|2ilIMQ5ma6Q0ej5`{Sr?F3{n<}n%EGVipIK(wlv`^Z;2E5q! z?_z(4-cWEVCUBpWN!5zi7~y7zhLbpf*~K}o{+mxd&ysmi92M6Fd9f)}C2<#v=L_v< z&v^G5WWR+FwzOb}MK(Tf?sq~Sd0Q$)rw3r~qnn6V1eJF8+$HhB;2_I3=QGBg(-J&w zyb*Hq3dq3#;@|V7LK~b{%-_Xmar9ct**mxJU2Y3)^~7Dm+CMs<ThAkqx?Sm(yO}>+9dyOHQ->4N5ds1-C z25b%9`TC-bR4fsEB#GLD&bOh&E|7n&d;+oKyVs24xp5$_itf8jLzvo69D})PS(os| zN${NuLp`aswC5$STuN@K)FTUhW9ueQ<9N<;D@#j9pNr=RtbBjHjshV<2k1#FOp;&V zB$;lbL7kDAX-KJPEq97Nmb&M{E3EAB={BErNlJDGZL2Hqbjt*xAn~Z9%`PF9adqXR zyRX0xh=HRQ(7)X&cklF<0!$*ewgPUL zV(`$n9K9Emg+h}OSy@?W2W2mqbl61?rhuDnb*3JzJ-u+20N~l?1skj7&lB!kn993B zqR7amBwyqf5RkmQ>sqH4D1Pnp9BFbyq{^0e26l}y*rHbBa$A7EKc56KR!o0OA0%iGM+hs=l&JwJv$_^B2qO-HEP_R{A*d?X|)RD}9J} zX)aki<>!84u#)q-af8IAtFq2xBXuxZ&(A$x0(?USbI$AF-p}LU7;fnRRK5>)A{UjP zyWpRU;bF6}q1(TGyP7HreXaC2AO2cwxaQ;(dhT>D4|LS2is-f;t9^4(vmj+5Ag8#% z`xhu9cU!mU5Pe&|pj`n2IM1#X(Fjn$3x*2=qSa7i6tiQ*Q#oY5(VSS&-e3Io?Z8T_ z$?U5Ac9At@l|Aq}go1u-EE1*G=h*$kOZz+xS8bEp)%`s-Z+oSUbg#~+8Dh=g?s&a+ zbdm=$I(Kfa7g}L)oWJr#wIt7VBBIWlDQN1Ilb>JJZ1AmMz+X%r+6kMcuRdAcZE3kM z({%RMD*Gdl>$g9@)$~~TBXs(TXk3PB{Y3a8GRxZfBLp0Rsp`dh_h?@vm=-bPICkyq zPaO$d_%vRfzmRg(oyypQG|I$E)h7bg3R=X#lGXvnwMISP^U5 zpy&!E3!`MqMrfx~73+cVUNuBy+{*v8{wxQa3lCbppW--25>_%Ul0coRrZJ;?eXd>) zKcJm^_V(^LE`#Dk26L8P%4A^PT#KZI=15`XyU9rb*N2KJh7SX?gKt|ne54>d{aB)Y zQX@E6%|`8DX+o8tIgEvc78o_EHyM7Kb!Ft_xG6ED%m)J{!7UmSq}}xC6Xz>Nzv*{c zVwX=?xqvTOxdrl(ykCM{T*9=+2Zx8h9_^%}-!}qY@RzC)R}nyUZ)ZoOF91Ra~o8l9SxPf>C6KRhP%QdQ+bdU?^#gNCJ}n-=c~zIzdtVaSwh6BijpHO>gR zMgi@%#ia^kq7hux^1I&Q)5u&Cp7UhpY?rqoeTrh3krTNZJz^pm&#)q>zT?H6GzlDo zpHA0BwQrvf>)EfVQ4CCMZIg|nc$1#kBet@Y(Jax4M-K7H;0_?DGvr<_5W? z60|7w`a`{9M(;iQrwwf2%`2&L|2Er0(ABkFTM) zAlp^hg5nkMFcRAA#%RzLGbPy|t51SJsHOs`bGUQ|e*I~;ygi+k*i$TlC#7i^SKfh!qWIBiUI;^T2 zFYJ{gpaFK!yJwBJ)_4b8enq8dHBkbGDAgUGsD7b5LSRj&sCPTI1InRs&hFDZj~~QJ zGQOlmB(DBCyrQLDYrEuNH~JRUL|`aDbt@2vJ#IhP7KYS`NSFpKc0xJHmvR=RUk>;u<_`?>+UxzYmBlLD$PWdB)eQ!SJg1cXy#ki^Pyelf&eowdJ?sFiI(Y=YjEL&D}Tzp_&a^2cMhBKUZ>LGlhkK~!13KGD$Ow=nVsAhg-YTaM?%#+RahoYFiD0|G$~lh5?!sHY9$(XrKc4hFG-nO z*tYI(unr8ilGrJi*#3!6mi#wQ85>W6_i6u^w|xAsR`{so|G~HYrHkn+usYVtB|yl~ z6FuKkdUj{WMuYS-FPOnrAig&u5Q81i77QdO zUQHtqzrG?6mwv;0cMynB8UjRsJ^_Lp?lld=WXOj=go7T-c^IZZXrE>PeFhw1)MM!p zh#T-aK!-pqlOYf#urkCc;om6`h%4|u378EU7P$901fmVT8$y{o5dKT>Kd=8E0rCqE diff --git a/external/libtommath-0.42.0/pics/radix.sxd b/external/libtommath-0.42.0/pics/radix.sxd deleted file mode 100755 index b9eb9a032d0b5229d4828911466490a95c126a2b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6181 zcma)A2{@Ep`$yTy5}{<75Lw0;*&5qeCS*yLEMd$H#xldqSWC7n$(o(WR*15OEE7d` zLYBxbOGL_6!hfdTdYAwEeb;x-b)M^-=lp*6Ip?1HIp;pNk=~J`928_Zmu(Jw4}M+C zORAF#9jUmX-B1KycNE;+-4%_16VO-;&^(Yg8MlR||4IE?|-EpD%1_mcmXQN&INI zS$;SIT#idbUWnm5iz_eZ2e>T6y~HbMpzrnX>FY*w&S<@;0O2HQd4w1(5|JC+{=U1& z?f$(EmOTD~8h*ZmhCQdUuMqkUY5N%&;WTNDWcu2Z-nKUzzkUn}x-?Gg(eWy_J26-8 zX2}0AjCemek0}B%&L04y8TeumAMqMVaK>Flm@z%|jyeII*BEzT4g2`QCuVN+8(-29 zhVlnJKB0xv!LFKTEUBEOvy{O#P?Jv)bDpH8+7|{@$Mb%THdZdSf)mYlc84AThyZ&? z>z1XQYzHx`MI1}rle`@DX(7ojh=tIhC}zi1W+XNsjpM(%-hA$+Gs<$`v`60BZc>5> zU7g>|b0if8CS6H`!oeEVkSqINZ&VIu6+|cKsr3NobtW5d%<87gw>Y?3xra{Kq_a4e zNl_~gKUv=}mYz8fLUdGrw^F!D{)(nRXxbvFH$pr=drRrno1qG3I6=m54mJGbmJBdDz+eW7BH0Q0=a8GvA@V2X5NFR1e>jo3q`iZVN> zs}#2(QN17GY@gnetxX4~3y8AnSblN(oPKV^IfHG!B9X93aqbgTj%*A4I`*N{tKvn4 z>V7FF6xu~Y9_@8p<|jaD(1khpEngb}-GyAuj(KTB@9=`sZDcPaQ3yt))|m}0yoZ;& zlu#n41h*XT)X86Vg|ElR&=Oj7#|umn;-zB+Q}fHYY)*Zh$z8aFx%ioRwl=0jv`h!Z zx2TIUsGySoqTCaC`alYJi^bBWL%x$lgOcpWR~^Is6gnlg6mFt86umAc+%bA44Oz2^Z#n-@MVT{m+d+N}S$v}dkQ9J%{FiT}pF*Jg;g>Mo7jvh7auqSD7* z@5zOZnnfww-PHtU!g6Z4(*>R)8=dX8I+p?9tN{+1 zHRrMG3_d%-)3XixU|(??aJ6q_z4zVg?le2uJ4d~38FLHXD~N9bz3cGRpOj%C8r%C8!Pyp|5+n@Dt6`S8u5x!pjS@3A z^;SKmu=kNL<2U?P#<_Jm&T90mE#9zY@3wky0Eg$d1u2GTP6x4^jc(pp-od7Fm_Iwv zVWDS>cBTCWetU4aZ}I-*wZr|djp`wRKD#XiHYa9Mt;C+QcsSo6`d;5?yYRBgb?-{> zoZ*18=Gzz5eWiWOTVEmk$R;<}y?xlA^w4{4m7Si-!DN>sFBFt7ccwj?hbWf2F?i>^ zzh>R$;kxyC}H$_bRh*@Gi9_jbp)0Z(0T_s09v>waDQoExQlM+qp!#Bd1FzKfaf zYco5Zw{- z;Iy)03!z)rr9H%3BF+i>7bo5bjjO%FW)c@FYJ+s51n}ww!75Y1O*s4zK`)V=!zG(5 z4R!-*ouhCbV^8JJA|IG!wAsXN)C#p5pkYWec6PVq8m#3`opUud-SCsug)$w#8J*0U zPh%IVb)o7-KAUxpTkuFBN8@WKPXRhu^NNVdLzx5#4v{V@ny3Nb7#)sscZx7O3YGzDIBfXF=e)KQOhVs<29IaxSVcJNl!lv$t0kFr zUS2)3kfHnmY9=!Mpk|gzR*3jWT{zf&L#xZ9p-`lEWq}KJkgEM)m{O>!#(vrf5QbS% zb}G&Frxm^AF+tIGv&}un?IdrUv;;&{h%^67oE`7DwK}4IzZ6(>%h9>tWW#Sl9 zU%Z2Vn(wKisvH1~2Ue%H-)?3j7@dD@q{i1szBiT}OKPLQC^9WM(8Xu}Km+FJ;tM)%O^eBQORDWf8Za)XSt!~H$O zD^u@E62+IC&3F3mg~guh_uDpPvAN9|GZ9)9&W~YH&CmJ1P`SXJ9CEd)TBF}7Uxa;v zv1bOO1ykwH7-U&FK+5m5o$)T6xWD${px>rGpe$o=&8co=jel+709l$D(3tn-`s8km z7e1hFF?!v{d}pVABRX^9yXr3Jf~{6&>Ef90=Of=!d!O6ImePl}7wQ)}q?hoh+PC&T ze%f62JX0t36|H{qP5sMRh z42Cn6W6g1drT(Tj+6RO0%K?rTnlr8(9()zVY^HArz8;?}dyW+AmcvXLT{qr!M#u== z@o``f5~^Ka51xGmoKuUPC{>D0v6bs2$GEXhNQ(L4_l7IaysF#_5$;LY?5?k823K(oRH(*3aR-M}lq6Qwcx}6(1*0+cX znriLexV$x8s#41M_5F_b;dOBJqWkmZci@?(h=yxY zIcHkV&daC!{3afbmCM^0cB)2lsRCMVJEB96bx~Qd=?29Q=YIP-fL1(atsj!iJIX4a zHPK!1)MU1O!aH^d#3DKD_`uX2ed#EbI*-^Co)Ip0g++L1ahr38Z`)Q zu0K#n1Q6wlBCih*1WAE_zp&)R{zm`XEXaUgV0Rn}Ptx$?vh`m{e+2@58TfC1$#3J3 z^{YV0PbEhb28DwYusD^!o1A1`l7R(8&CwXJj2Hy?4=_YfQc_O#ycKTPpo zVKV<44E(>rWPihce^+?2fXv$K}ZfZ`_JiNM2MUP@5PtJN=Ol(A&LO6JzF zdGWkdh)JhOL{s}xfv;V#WWZE^|Fev7Eb#KxUHT}5?%KW279C;~8|c7}&0Zen@mBFg ztF4rA+l>8JpE_JPmyp5!we*GjFg4Bi5LTQd&?nEYW>8c?Yvf~J(B@VhxbxwYab7vb z;`N^S@?as{gjt`Mf_PJ<+EIfox#QP#b#{9`Y-fUx+uxk4Gx_}5JWIF81ZO^#IUkh5 zny}dOt<~P6T4BVcYh+~P39;Tr$+1aTnB9`?I`^cMwd(2>ndU*|*rbUecE`s}-sh%V zZ!}JQ_~`6QW!*vrcn}4}rDb1yG;=nrRa?to47@&acw3P#+z1gEMp!GsM!vV6Y|&I0 zn*F+Ex;#8V{f)ziO9XJb(YS;8fa_R`1aqS?v7xS$Ie^7SNiT_L{Y><9lx@`Oh6o)B zAge3B8L(fr2_C2z{mgnB-cMiMG9Rp?=l-Zus?#BTH*+TY<#B)4=2$UiO11(eb-{4R zuA6p8b&UK{aBJA~X%zt{mHfz-;8hnN7X2B@axsy2lYDO+xsI1z?B_o`LUaQA_UBfc zN$@49BtA>AmbKyja$Pf+)ko4g`+?SqX|nhsT1NKtMMFlndj{eyY$6u}VJ{z;S()3g zp4Un_nM_P(I^z|-j(e++I}fRI62ni*sm!`>Jdg^t(<}JE_ubpmQRL3qGx=(VoankY z0b$dK%kN@y{HjEdyZqw{O?+;zj6K`QgBtK;+IOJH ziE?5U{gg-LT`Lz#dvcWC#uK7X^?-9%B>KIe9CTHcWk#!t%2l|{CHNInyclG_ljr8< zM0ONy0KH zYX)C|eDyQcAE%YTC;etl*1=k1@_3J!KNE-^w2FH7vFos^w7&Y?2+wS>cAh%hT%4Hy zGaR~b*Zh-z#iBY^Z>O8%`|NiYm3h}9yn68yfYrG0puG=sBW&bZ`O{HVKaZnK^qs3k z3$WvKLrMNhdNDIiVROqz_k1cUV~>qYB<7;ohL}cEPlys2^~a|Ywf*lJ`|$zrovk$* z1tsGhyyE_pv>u~XxGiCaI{Uru(F(cy;azOB!r zcKJNUI<{X-qaT}OY-KZVHMsUU?W9|q@t7ue%30w~o&p4z9#!5Ix2kY8MBDjW2~C@Z z*yQC5mWkO+O-5o`pni+v*?6FIB8!OVu}}^Vfq~+(KIFB zq4wpQ)x@>m^5yoAU*%3Vq-B4%vQ(l_($LV)%h2e!(i-i+tt($uTp(Btcplj;qjq0t zlRI*kBBG5+8|es5f8(CAFo$`Y939jF5QG-FmCTF|Bs>j!GjKyLBCp*n|Bb^2ED9=7 zeJ2c(AkWNLa%Qj?V!51=dndX6Ozns>Z0FXqTH_mEK79r>a|cG$thDc73!R^)&twz? z#X`#luemHWzNFNc?uW$PR)3h~MAr|I)niYSEUEu;oL7EjKJGP-QXCs0}B5mdHQ&u-1((6E6sGHVa_Dx{$SD33qdVn z9Ajf4U;@XmB3pY!Sugtgwkd5}D3TtT&@$oue0pH(+4)(`#*xe(JGQd|?ZcS^+i}fA zzdJVYMnB#AU+k^?Q!e!D7N7duaPL^|JFLoN4Hcl}MZ9FX_6UdfJ|(CWx1l&head5p zn(AS})$-s#+YG_PtrQm;m_v=`YVcIgf!ShtXKHlXws!GVbqTkPqmD0{d+ zo%3X|KQ2IFoV}~fQFx)ODy2%y=JC)6F0%bBGvbE!N!D4TBHNFWii6@mr>#k_zsRp7 z_Ak~iyZ<$5L{3%zDNs`NFNy1a68{=5lXFUc$^a<`^=F3Z7mwWkZ^87RJT}s)N{x$_C#m_bZf2xMO+$v!kbahw6ckTSkX!!; D!-Jt8 diff --git a/external/libtommath-0.42.0/pics/sliding_window.sxd b/external/libtommath-0.42.0/pics/sliding_window.sxd deleted file mode 100755 index 91e7c0d9f43b612ff0a59d86a71c8928fbd695f3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6787 zcma)B2UL?w(+@_?*T(eAoL==7Xd{CL68zakX}U)5R@j} zh)5NbDhNtP;0L{WulIc4cm91(_RZ`(GrKdp@0rN)4D>F4GnN{dmORxzyvYt0KnMvE&qR>X9(fc#YbJjJ+-V!~=FRlYdh<<2Nm zFv9X$%hRLn`NNf{=`YiKKC-HyrdZboE$i!!pni@0(utt&du#VcV~a1oI$*W`0@Lc` zx)Pre#iA@d-K9%<&z1=jXh?7Px=TTPRQtBL*WMmd<*n}x1BZ}Ylm-8s+!DgyxU!E zf9MvcPU>j>mZXQxd)60orZ07g{7&Gtt0X2(ABh>>kUjbc8Wyc0d2(x=4l|-vacnTo zA_Q3C&E~w~0Uu(6KP)2DFJO>*M-uN{bNATSyZ%E~e)CJTK&a=)wn7i@$nE`DX$6G^T>li1b%7gTKlB#Ov+|y!!sXs!>Z3G-DGhvlan_=nuNWg;!We( z^yWGKoEswkW)OD#nU^o*n_jNb1Pa<#61#Or(7F&qpxgAQ8*)xv-hW|NK-qZGarrq) zRHu9UeUQ+FU`{5lBa%poWN}?N=|X-%64HCw=f$7!ZZlWH=QGiY{D`a=&?cgKEfaWkH+ZF14c z1f%2RAiY*li%a}I5LJR7OMi$ch1qX}%Id>XJL?YG4OX4qwjcK(YgdLp48sqi^=b9{4v4zk zHs-(tW1KRn0vI>-YHi>ORHN{O5Dz5(VLT_b< z3l)i(1p#+^FU8zu8&em>nbX5kODK62#=iY2R|Gv>* zcYeS9wWmPL!cP!qPKc9NLev9)VB@(JH2VDeWq)7e5X37C}(-fIu$QRo|tXHj!ym)8IiG7?1v&P7{ z_9O1&BvYV|5(IplFe}Usc+=y_?t?W9sSahssqIo zcbAruObndj6XE3616`XX?N;>uN0H>-#;FvuY)Mq@K;z+NxQueuqKJ}Vu={=xtw4(-@SbT3$qKFzPlgs_<_&=>0EGvVO-63+vW;f`cz2)M2W2f$Y?65RM65IcjHam-5l)GMUkL04c29 z;kuXuiF0S%*dSitzfEjn5Sr)CFSW6}VmS){%<%#Mi2oW>NKaylyN9nc()~wBF&#e% zDO5i~N}CP&yYvcdrj$1iMIb^ ze1SUK0CYt)RMN478z~vqebtOdO{cff8g_0p?uwnj{wS{Hh^F#rMl((zvwh~aD8c)$AG(LS+Cf=PV$qxQ{!J`#%y&pDs3*_nC9?)YZkkfPsCyftkt@*NaV|wZlZm&Y zM$vC^Bw9h^=wp{$0aXMYLkl{vGGCA+Nv$h)TEhwK8rqhS-hDIvPNcF%!v)%)1SVZg zUGL1~0V+Za7ta|xY7GXMN$`2z0>TvD%(kxk3oeSe@xZj_*}59lmVpO&NzRy-{8#+O zf=@T1XfT9BeFBo=WFcxSd}bPtb5Q0AcdM*Js;(KTu8c?~tS7uWU{*RN(%Hbs_5b+kI!)fOC4NGtM3YEmy5^lYI9lcnp zbd|=r@1hEVRy298NlUt@J1Ix34~SXaG80rzFnfD#C8qQ(;uUp1H`#0Ou(^;tK)GD$ zoES%liKT{JsT$Dn-drce#y;s|up@xPv(j0TDYhWPkA1nS=l~QeG9lKgJ~(1_bDTMf zD^}xzhC0R4cOW_0wK^pN`b0SzVw)IzI73Pcx%)~1%tzmMy!egcCCS-xvxZ<_d78^F zK*FI$BkKw{;H?87=Uioi}ojHd#v)db(GYa@w+T-Bxh** zd#&!-dO`ah&rC*qd|tF5jd5Lvibgc08wbMF@dls7cV&*1E5vs|{Hc8#$RtJ3)SE`ujHhzUEmRpa z&n}EHG&F-F1*SSz9MUs-tME9djfZqt__2?^O$Xdu*rE7l%zwT#~6)5TC?PE*KV>IYg4I+-@FWb zoZ&vzCcgBYc6%?@H98z#jw;N2z`=Q)E!)J&d27XZsr3>@Q>*uG30u#8Rdy9Nb^4{z z>S}w@;y`mpCGh$v7v~+C39`vU()%INq_+dvWlKf?>I%=9(%{!xTBNV1+~oCfXP%Ii z?x;1H(+-wIQyl1LwK>nNwLkWcuw2L>Bq71nd&|2Gbh=r^-OcCGNxg7C%BE*B{u{qc z-wvzaK+caUyQ$irvUy?9pYm`LdsEwIHFCbP?pxl_^>N>jv0I2i8SlpBTu-Ugm95GN z3S=)1J^s@Ep=FVKC|Gg%)?8BE!&J$+;b$tW?SngoBj*xr?+zF7WaQhMmkD*9LwC~q zJ}&ATb{&?{O!TXKryASI}P}9G0b8;BRtrFss@mcr6Ox)^1 z*UI}KKQIddb2%1w7+{pTb&b{Y!m_a6@{TAdJ9KsO_-*_mXaeIuaL?6>^{7lY2HJ!5 zDt~IZFg9+Hej}i~kp|;3+8|JFvNdtV&&8?J;y?qp%Rhxrq~?8&qlXKUIlts1dNmro z+$mZ(7ct<+?D4Vnfzif0FNP8vjp~QzJ6Omi{HJ|x6)_Uav9V|n4Ts>DPdX^uV33_p$ zSn)I|)FZEqA-mBy_tt_yI_I%t+fB;75*l}HV<08fTGL>?)ZJe~ zDd{L07$cN{7<+q^EfQ{rvGsI0+17zi6#)^33R>!lKn}35u#PJdt@8sTguyxp3o98Y z0e{j;e~AE3IuRCD*5&|m{8T1n=V8YoEBzlepNtOe4*$uL;kfDH;R+WP#+>x=m*{C9 zA`l2f_$SQ){3+n$j6ys8#(R5v3wewF7!MQ%g9-oO{({=s{>Hg_Vx51W>}-XR&d5{y z+=Zb+P~l(LQ)7Rl|I;W=0l&bmSfu-j25XNWp8X#~|0j^+mxKS9lHblb)h{c3TEiWX zXe8F!1A~?Q)8(h`6%qyV-9Vv5MfjzK{{@x?fx-HEidV#-mZp;8l49nTH?$2b)wK0}OM5e87vYvST3n*R{`&HpLp>5jyL?U42; zG|~?E1BkYELCSEbqwO(3D2MQ0&iJ1&k^dh|^#2DF`wjd3)w!Q8D|Zi+?avWnY#foc z9$;IHC)z`XL*&OO|N0`}rzXfs|Dt|t_|g2|vuyIyEF0-@>g}I-wu$N8TsT#rTuZ1T z-uFFo+tYzJ@utC&?Pa6#3)>8!Fk{dLm-XP`7B8@0dC1MWqD~upL4a%Txpv{m61r&@ zP7$zlQ7`iR^OO>L!&IPGbX<)$+KOl}mZYgW}v@H^W(d)@XRif%E?4 zSfPE9$5MkCsi1EE*x~f66YBeh=eOu^Q{|f94*cL+G)l2Hbx8FrqU&aBJ+*PQiwYXA z`xpA|e~tdu{WO=VP0_-4+tAQ(eg_M;TIQ4vTw+(&<%X;6Umxi2Ps#Tj@>BrPrUdiG zzH42to3p7FZZk!@N*+k}BbuXRTr2 zt1{unzV6X-8Ry$+_~GsBgC8ga*iws1VVd`&!8Kk&5jPtHyUGZ>Zgq*t5mwWbO4ONc zmBPVD}Fx~-_HKwm@sGJU$ z&1cV&*xRtZacIuk-h1v-G@{ZIyT-z@{~}Lb;_R`3RUCK0AO{-Ouc>OW%%>SreitE_ z`+?J8B1#|KSd=0v3xcQs{MRD|L)Ue(Z?AGPRte=xaP?SxY!7IiU5^&IF1hguwpyTR z&HD9Tups3Ib&OsB8E>+V@!P%IkIyhgZE`;UZf~b}bi14un@pOj#PB7YX>8tRhoJFu zLag8*VdJ&kp0XqIiFcMs5YbBlS=>i*`h&B%7%h1+F0Zo$DQ#OXzGQ!_NxiYYmCLAz ziSB!PeSI!0&!&ro&Vm@O9egECW2)g6L9_g5L?vzImvL(V|4evl;e!Ks2ba1+l`(1B z0a<4|<@^SsUs^DgD-fCxGuMQRf1wg@p%A#IrZ(7iQTOW=5eMl2Q+CtQ%+!f0DM(lS z<&u7k!UN*_Eqa!C9@?NQR!MIO&SkT!Ek?(wZ`(>SO^A&e9A_n67*N)8%)D%_Ax#<@ zw2hDS=}PVSijOscArwF^0`V_~0k{`kknC^{p~9TY&nV z^sQgFob|L?AYTS3TjAb3%thRhO#p|=*;|Thk9uYPbv(n9PLq^D; zC)s-W<%C$IRJUb1BWjFFkD7}ZD4Nh`Y`q$5q<9l0Qq>OR>(%G6A0i7$+{F$eo}^q> zQG8Ho$?*13M5fv`NeaLv&2tCE0^A=eHYvV#2UI9kZ1&ZxWd`)qWdeB#pM#GO=$3AxSB8!kZz z7u2)obt%v_zd}@j*AwHo9E#EnNvi2NYn>4jd`7>EonvId%GzOHHB$SQkKrX4!8a4R z(jw&I)`z3bG5P(S&V!6DlJAI_bi%houd{{@zABHr^eMe@JbGTcRQ1}3_^LsYiOTC| zy9{58*YK-?)6RXP+0DD0>2b0x5~BOOeFZX-jkVGn)l;HcrGYN2Mb0==VW%fMu`QL; z*((EE<7P1t?;W>tj_q4M3g*IEqdw6Q&@Lv3zZP$GinHqJX`#618PxRT@JGtYytN!g ze{yI868M#J{-=uo`jc>SP1!&mtgfvh>|%{Z*(2S5TnUs8S30&ssLswb>*P$Kvqv5i zONDgs)4hKmCh9@=7DnAwRnd?7zHNA}Gs2FH9WrRLFxeOA=Gz^=Cs zhqsg3p8LgFSU3A=WPh_Uy>(w|NTY=1Yf~m=?gU15s-BRe<3%#~fyyYI_aOna9J>L- zpJ8#^IYU@bXjB;*Y?%Q{*}Cs^R@J^<>2v6G-;w4WL019Nq%@ogOKcZb?nqNhqc>Vr z^`hEBd>MC?ago>}jSC+S0nzW$lB5y{|QtrZmpy@CKE?@~|f-z?678 zz{HLZXL8CGhLVCL$7y;y9k}N!YVOzYTa@CL8BbGolZ+(%;fZ(F2v7Y-Ku8Dp`zqz1 z2V$pJDSwuKT&(wi^0iM{e61&OYW5apLPj<%cWBMy=V9(^=qR4xdcx0 thQCWA^`BY9za{@^{OJ<;yO1#bmj#2+Jab|K0C48y;UWM4)GwY={|BjT><0h< diff --git a/external/libtommath-0.42.0/pics/sliding_window.tif b/external/libtommath-0.42.0/pics/sliding_window.tif deleted file mode 100755 index bb4cb96ebff4e06478672dd3583bd26a51d85b5d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53880 zcmeFZcTkh-_BM>Ng>3;;RFrDR3L+pRG!+pA33j9_MWmO68j6YvC`Cm-(MzvMelPXPKtCgnqWSee~pzKJkx>!0tM*htQv9$7U{m0~teU{Q~J9ArZ zSHHT29jJCJsE^YYQ(%pxb(j}(`lXpyZHrQLPt}T6?)Ylkc3alE@r%o7t8Q7ah*z-Y zivySZ_h|5Bev-_e`_8Novd_I$6)u@k#HZ4ZLG^DLZcUGuwX7>Xq?2UO5OVOpS6MFB ztz&h3Z?xBJ#L*j{zipE+xMSUzkfN z&@DURQ*Au2SnUOc>f_Tjp%p5CmPVT*L@CW#j*F`FmV zeYtp?Xl2UZeOBf5mGA1nQj}bZc;wD}O(r1AxE%5y%Nghryj>I7FF7er@H=fNO68xE zMT>YO+BSbKOcU?BIF6bVaXMJ7bwF+J5YE9|$z%F+jApn8Uk1lgW2CJ0ZPiB`0?h0c zas`w>`7E=?K7G$G?0#`rhpf~%nn9I_+k@=Wh2Q)ImgB`8|qdj%6YiG!i~Z zX>q*BI~LRMZGG@|sqaRf6Kc_W*g_iN5~HmCV1==9w)Ifne&omR{(iTEQEGO7SQO4n zOmD?AJ6!Wlgkb+%6eRL`(Z-L7`7EZ;!d~%vZlLj$4A^XTM!N|w{&=vKe^D^UmGM>M z-Nl) zzkdAqZ?QkAKDg&B+pNFxq{K2{&qyc->y4aj=?i>Qw1^ixM3IW@%w2 z(YEdD^*D^kVg0W*msDbr9k2WISAyD&n)~U&njM|}p~~kjc~tmJSJMz~bu~}K{(;x7 zj81R63p+2x70H$>*G2^j_>^|PIHFr;JbmklRoEJ4iTADG@A=(?*GO`i=qU+R))cQ6 zvP--Waok%A$$)1Be)}Q!{JEa>D)sD_I!4dxD^@Qx8o70^!S_8=pX|q-VSf{-6?(ei z2gKhRrZ;Rqc5)?``OE+F+T(8+dS}l*ni=|8 zwI4&c1AnJMb~XBc{(MV{sh?KVi5e1q45goH7C`iztjOoc07RSXad}nH)W-9OC%7+$@KmAn=o~vWTm7UNJ%R*GxcaW4f(ObqcGBd98 z(^^@{ocYe*uB>fDchtQo*Jbk>AF#)Z5eHydHB(9_c+Hiwii897qv96d@+H)7Jt1aI$9;}yRHMnK7YQH zhJ~0zDkbw+9Ld8f30surwKUW8)qUzVo{`72se6CE6Cae-gRejnqkY&d(SGy1!(QWE zr;LZee_Nn**}gnq~B4VTn)Q@~0NxaAP2+IX$# z1vZlI(=F@wi}6#}8-2R;?rdYKxhCvIy27XKB0pLiy-VShLhc%-VcP8=#LL1Y42L9c zK{~jeVb|dq5-{^U?lW)v^~6;3s<4(aF`p4yU6-1J;5R`io!^zt7Cqwe^19IkA+>;? zuNZM)9E+1zo-IkxOxp`874rdeH;HzQ zWTU(U@1=!hs)0)5=b;;5{-uTX z5U+_weft*KCWGE&94-`z+%3PQyXWHKajIwg=Xyh!!fPZ{s z4nL~jD2;9?gPLz*UHkT-2)0^EZOHk6*my$2EY+PRLh-#g%!dklYJTq+FDc8iKGvoG zrH+T)d+lgt<$;rS818W2sBak%hTrAFTK=FzT6HKJV$2|SdNOgAYPPXVLNH-t(Zs9ww# z9=Z0vV*LH@soLGi2~AO)3T&cIpc<$;$wprOZGRTCA7gk3x$AYG28$@@#bJnwp_?f} zTV%|xm){#-oa1xa+rV(V2LHwXY-(rI=`b$sdqq7KtzRrn6rqfjCSyz~6W zQD&-xy(PKbF6HQlQ@B^ri)azTnx_2%Q*0Ike>Tn_%W3R~TkL+V$T{ibT%-`z^Y|W% zvLGQ^KBs-j+`M3N!FFqx?`y@Ix9S*lH^nuHdi&$0wFB3el?gwbzqN$eztkB$vUR|$ z`SUH(=&dBWPa|Ey>Po0TbP{iMikqC{W`E5Dy~FfQLZVORbGQP1f&MIl|!+`6612Of-Q?%WioDq&In zbl2GZ?}YIqWf+_@gyVeBOz*l%nuaKhKXX7VKihS<|O3*Xo-Rj%M zGMtC6BQ-}sCG~0`w{fX*_(}=6{Ny))qc}m}o!@G(!P&kuPJ-+cYF~J-%YIH&cm0CJ zGgto_bl18;zmk?&Ce^1vVfRq)JSt~j^2OudYP+tJyk>QmA5-7Zno%@@X}Ga>Ru11J zYHnk@s(kN5QNuZcjrkg@qFpw9f6hdyPzSAe*uAt_e!V4vr(H&FFtt}LJe_Fy;k&^BT@xjj0cot=@K5WS zEIBv+fi>Kv?6nenPFVEa@bB1??46BISQ`Xo2A@vh#$~-&vomRtsi*V(W#79BGIt*? z)(a6v)pfe{@)WQE-4Ay9Ier#1l|G*!NBOS2KlH5qsR03>y(^{j{kGqMNe@cIs((%> z^+-dJEJnIFWn+@2 zJnx7$5TZ_p_$(GhhfG=D;5)9~_ojTPuW#oKX~p_iQl<%jyv8Km_BTG5&l<}f&h^p1 zv8VLx?U+-(Tw_{uM|8K5e3KL8?EIOW0rJF=Z}ekHanauB`WXiw176gw_M3KHqs?V* z;^eu5P-;8eX~eN?ry(i7w%t*(o^uXN^AWF=+uxmDPX8CWda$vApF;m(9S>;Hdp|Gl z1H#$dNO_CKBLbAijN6S$?(+r&|_N_76L(A_wSN`^Cc%j^cs4};O zW8oTsy$#&F)Kf0Lx!mqAnvZB;Fyh;s_Dr80u8#|eW^Bd>Ey|0Ke2-L^hA7=`%dlrM z9i-e2rK%h7hlKIZZEp0p_|Df&bdapBFm&zcZ@M*#b+R|`oiFU|Rvug_KP+2P|IPse(Zg>g;5dWKPrCsj4)Gv060& zLo+0&{e0J@Sw6Qx1l=Hgu#o4O7QHXc!$H0}e%9?FmPWRQ^D?2#(K;&f;B8S?a- z(gK%JJy*GEt&tY#0JO+!vF1Ex=Wx@xM!Lfz-j-dd>V;AW;G!HJ`tinBMaNF`p;P6; z%&?MAv9xXLmkO!{Nl@0RZ|sSYd0)KKYU78d*)xs$w$LC&Fa*-;yWMZ#yA*fMN|8Q6 zGc?BEn zng9$QFDSEs7In<%VcH$1985M!gs{Q1M^S`b?d?O4%%JVjBlPqUzqM_7-hc2etN zGzEMfogvq)g%x%ac9IXZrdep;z8>e)U+L1}+|&ZFevHP|A9fg!#ddC9Ujpygfya4G zH;^J{TkS79pf>Di`{_Z+hQKzoYqT8zG|&#d?}7Hw1zosfdZeWue{*YWePL9)E7i+; z8R?LytbHgVvlCBYRXQ3~Ll3s3lq#zgDKjDMD=!^;CSWtl$akjYt8G-?(rnw9-}fw4 zgE$CNm!H>k+y}%n@=fW3xVxzR;-#Gk%NHW+(s_^eee{KdVJj9rGIKpquVt+`p(~#| zBQzWvjx_nt6#mO>-^My}64gUQPgpg4IPHvvuHdc3h1t=z@cB;33c5{4_D{oVC?*56 zHBuRK0h9ezZNM_wxwbp{i8wc0LMik2Zy}2aqMY6b?T{`-n$TtUq(WV^+b-ctyWOL4 zIJBaGQq$nUvR21f{@{=-z9yb=PeN2tGs@l%pKjODN>-e@z^LD!jL=r^f8|~OZ7I%r zMEz&VTf*w!cw_Q%cM{33Px+1jGojok{L=V&J<6f$E>q*3MeAF&C!VBL%pX};3)WQh zvJHez)x;6uNzKgd-@eupc@S7{m#HvweV{zb}J>VyFWtUW%2mbLNrj!`eL{U&_KD2wOc|f zmj+0=BkYK7k58O~c=bW$M^g^+LR{LRTRpjS#gr9pe&aC48*r&mKVA_>s91d98G{Si z3L>PC8GYy`5zdvB;sv2k(rg8iBswirHlt|iKK1Rg0rWQQCg3%6W-5 zSkR^Gf?cmDZ4g(8EAnz&6K>!Xa1E}ho%ICv*lov9o2nnLbB3?>JaA}>_=IafHzYzw zeLepAQP)k?O4i?7owz7Ky)9zRZp;}0lii-);W<@v9eDKzOKRB)#PPstR1O<4B_`ZxC~vTwaUl81mm@~G&C8lj8+tOf>;TiX# zZXl3n*cO>esnTm!(db>c`@I~qJCsV0;_kYw8k=Y|)O z#+?k!&eeX;!bv{#A>7^6KaETfzNR;rqm0)TukbUfjjt^Dl$x7WR;x@fX+q?=^C} zo=ha*=W zJY{Xu1xV0t6_Q&ejoQ<0dIn`ExBJ@gQZOpnQl_Puk~`~*o9Bd=cC{!>ukT|!ajUI> zqBCN@1%wltuK9_`yJJV{9{COAORE=r9P@dVevJP)@AzlH-KrfYY+h--I#$@h^>owj zWGAGUK~fys@#c*6H}DdNP19lc;lzwwa*b>o6crMey>DDs7G1WK@@R7H5~F-%yoctX zUqRRu8jSIiWwd1^ivS$zln(MSbsA1DGw8neh)-;c6_(43{nImSX&G4S`5kKio0XCg zQg@yf?MnL$%%SU_W>|T3Kek1~;`+y688<^wz9J*ep*%%ZNDO)V12uQmKmQXJ3eF0Y zRB4D9W9$v|T?jW8ua|ChIe35a`*%>Y3BX^?rFFQp*>>tkJWJmnm1b74*|@&;ojS{h zTRzm^Cwa53^(6-++RjY>%|Q7N?u-k~e_u%-w?;e9XJKir5YSeDQ>R+xhdrTkwU~z+ z4$REAJMmY11~QQ{Jm={2EWT=Q-`u;4uSj^BUN4>&F0|!k zeYalqFjN5>_Tqe}N>F<5Vciek_Zkv;brTZxGxUIK&7&FvrOYq59{Z$V4{Zu|<#zBx zuPF#xz2U~he%{9$kzMu&?iaxjP!BhW^x^8l-2i)*!O(^#J9@@yYI z;56wLBYj^n5BqV=DvNl>1$vxV4`+*g--lTSHM&KUHx3J4m91m8?8J)+-LJK|@{x$V z!#5%ZMvKx*A~ZU|eIUXGh}a=T;_kEmV=$8HEgKUeXjc&6mmE&J8qLT1AZ-8@Zbl}c zNX|P=PhGz+n+!DRJ>on5^}0mI-qIH6&W3cux-MnP(Gtcl0F8|m^W{Ehl$+V~K-F-2 z^hvMiyh_>a{7M}rUK^r|RB(eo3c(u(qW7(T(J?nW)-jCP2_<7@7?A0Bv%^VFt_|ZG zHcx38ON~)>oN{}$c)tuamf73xUYooj#E%+43{NwSF zSB)7$ACR-mX63n13U*XWG1<@#E{zB+*6gq#bn}Yu*;5ovgDsyWSrXnf0AI9>wVOXS z5Gv~dMbZ{rpS@x3#OxSQ1*1(*6%MShTe}y2s})b{&l}&bN1~f1y1L;4{hA9jneNwD zi*2Ss--bfkPX%bIuEvO5d*Do;+3NAwuHhb|9l@ znFU=f4!hlWGUz?uOs;5}nmyX{57GA+BHFJZJWH}=pKzIV za-NHS{Vr2gZ7E@XROp$Va%#a3q@4lhU+eN6zdHTCH*4I@%x7FNlbG-zA4iBd!xdm; zu}XM{a-0Q)bUoj5{y`q^a3i#-Vteq%t6ibz@)QFew4d~{+r#X|Hc6uq$$@)bXJ-$| zi_Gq1y>uLB@HqPrOmcI1nLQ+Vkul2Raq(&WqCH)5hp&Ek8WOSf=64h``&gc0 z0~2xVzBlT+sSgx+DJOk$VbtH5b`Tk3(#%qoh42sDck`9BD9eX&V5@Xb$hAB8D!e?y z8tu+0Kgt740>1j;d}(@jT-cRO~Za~e@eM!*K$~Xqrso7eH#~Ix>wP?&XOOY1|m_ToQ(rZOe!-$pto1FT7aT@ z`%yI?w$!KBXHJ^zKZVT{Q}NZ_fDsRT7;SpQEVW$p8L9|1sZ?5&{aHH}LmaZMxiP1# z#Mx5T-TL+pQd9f~e@*#nPhrHpb`2Lsj3@BSxHmo~U7wbGmmehkS^`u0#$#rP^mDCO z<(#lHPH`gyj!C(TjD2VO@L_p(9FvOt9)1B`%9TSKfVpu zXY#Rw9rD~{trWQ>{AS)Tc37*G?rq7%j2JvnNh9^?C*{rRF-|=SeIq8aG~(bo!Z)d# znUr9(R^=geof2#O-n4er$1-7NzpzlM5i)bIZO^P_8jqws4BWcx^3>iWKk|g_koD?9 zx&znc5#5t-GK6(S2O^^RP$G?6lZzrwwm*@^!HAEBdF<^mGV@)YTca-!!H55iWOxcp z{G=~~ilKY>Vd(3|An9*cF6M}97E+$Iyl&LW6XiZlBp6+r{`TFk%gd=UYRf>To86>X z?)c$`B}b){-a^^&>ON^`(BGMs1+$ecI-wkw4VTIvbrJ#;@1$KAJufV~d{HNsD%c`C zz}K|dQ`3ca?RN`D-Z_3@?OZ|Grf=uFe+<%QJMoNp=~S*3B0jWyu`AL+-0b?`J3k+j z4W1zrwNrspj+xxv8;sSs4vs{OR7w}d{lTru8{ln|MHDJdcR&Gz_I`%#iMSzNS|$2TB(xs98y)&GzB?U(an3 zMQZ*gufIncyU~l6iM%r&R^)~!6T)V)G-AZw)Sl*oai#yF1BO; zKs5Gg`MvI~rpW;z3rz*=eu_Fnh7>VEfre;lgJ=?q9vAIlbU5%{!WL`oPQQ_@5r;`z z#dpZ+e0x>y^f2Ffm(I3a(-;4Uv+nR7+}yPnXrB+!2ZkzHXwzY6-2A7Skr&T!L6EaIIt-~%Jfm*Y^(K{YI*Zh zh23ITZhWSUOHL>CM%>_@y*|!A;dDNble?JR=dLTx4nA(5;99TH67nKWivSnfCqp8<#Pn`V+^m{vkGx1s4D{v|=DqGI^_E4d;f%Rt!1O8D4HeQQU4SE3t>he6N(kCuH(Gl9? z2Z7uXtBnGI8Qk(mrYiaIE=g(Up{vXz1a0il$GF(sxNWRRtc`q|U!Hc2u=-tv&2+8n zah!AcPoqtff9P+NJ8g{K8D5M!ZT7Nm$3O422Y1>>;<)@`YsC&>gx4@QGpB4MJ{vd# za-9QzIvgq7hl!M_V0Iw9g|Z*p`XiUXXQzIRoc=KVMal?GVJx!U5 z;u{??8g~cG1HEH6+C32PYMpGWN`8$D1^y#r?*e#UpjS#_<^%h!68}J2=O)0_PMx4g z54&=@|NXmpaz1QNp<_4iBJ85|_@1+YpR=8ZW53V@$C|Yp;L+%~Q-RsF4b(wvaM?xj(y_iW`pI${2Zk1Doirh8o2yR!`iMtpo4;!H`hTRH_rCRo z-51jaHn@4mybo!Ovd^cBK4R|t%G3kJ&Zaf1@YDCWMLz=>(NgHkod^}pyHU%JS42_$ z%BQOz-&?m5xJ#%(`!vIvK_q3w|!s%seTJo|AT*+NUa-pKjV!N59k=j6F6n9oltI3A_^|eV46kR zb2Y>x?Q$9O|dEnHREnD?2Z!|e=W*!!EOYiH)EJlQ8mRVI1?VG_EHu^*yp3xqfEU=;8 z_4Ww)A!CClg+;=8!<2}+nS+BvZ4RbbbujD*%?HX=#(lC6Fhnj6=0hhcD4z@@Nb-)m zK__^`3u1eI4)_O4(3Jr)yhew*7{tc*GIcW@Ze;@;6j<21p~%s|O2L zgb;yXwgiQV<=l8T9U2&Ipwi9{b>z4zbLTh@huMQgwQ0a!FE1AKq&Y6mO(0d{{X6xL zSQy8~K%W~cS+ICK(YQd_wk37n41=no6>)rD2i$C_rzl!=*!!`n zSLT2MtOGIWGb8u@mtUZV#KEmDx&^)|oAUtmL|s>*@6=I`3(?A6lZik(EXy^DM2E~7 z2%~Wapr73-M*z;Ek8(lg^`I*7%<6XN35I^U)wL(a5r<^e>(@GVB8r}9JdC+&mL!9F zJ)dChzujH6T<<368_Ri7d1bM}T0e0nf#?C@Vqrq&g+-`>b>OB?LA6-2*bF@T)OHu_ z58Rz~QYQ+mo06u1c8mj&Wh{tS_fk$hIWb=)ScVF7+h+Fc09OUB+lvlcI!)d3q$diKwh}ppzWj>JMAX22j0_v zTzz}3)WQO~?)fxCxSMO#3W;G@c|8w9=u;rR%&XlbACV>jk4!Fkxwpw#yc0&3hDs@GvG0$9x~*Vo|TkwVyX_N zKkecsteeTv^j8X-@UIOV3fH(V6E!9CWEc;ffbfX{;Lw;DtrlU`fjb@3@*p$h`gSdG za@Iy>?M73(=7=9Sj>wY)3u*-c&apkm9f16$Pn3yKrna2^61BZ7(7Dk{ ztNzW$l6leLn38$#k>->|cYl;+3XKdy3@jCttlFfeE5Gqk)v+W2@c#4{g=~dSR zNG;w`a#(Pb7&WiTu)s9MLUi{p5ql;;Mjs1t5(AmU7##f7Uk<*YWdT|vpqzBwjjCWyQwJl$ z=%%NSt8$z7^g$X>3p&60hrEd$281|uP+P+FwGss6L3^mUJOL`iieX1CE$-Kfk-Qun zCsBvAEI`lce#EY?{Mo#HTEXIE)uL-tN*t@8`?zH3o*>E9>6@{lLSu1PKg~%5Wua@a zCW&N_XgAh$H-I_c{pDcZ^>k{1543exJJXaTMv+Mu)91h~3PFXxfC3}dD+S(5R!i6K zrd>?PnT515kacAFQC4tD6B!g^Pn(Ps9J)?+UO|F5{9pG7kw=i1sv#*U7=q(x(TlhD z0fu^p*Y-y#Kv%6*79y5Bk)tdPLhf@gb*`|kS|yVK(q}23aETkAcM{RgpBn9HfzE?J zc0u?bMnvUe>Q(Mt_qZpi93Um!uQdHbmHtFB|8q3&$u}}092|F@8tl=)_+!8xRo3(e zd(?y9!>px$qI@I%7A0Cm1*GJ=LOM#0mWub<|IkmJ^MYyDE0DP)=@o44I{w0v_~8pF>`eVCtB)~q#5>z=Gk`*XiCth6PXN3E@;z{dye zF?|PaDeX?}+i9q}G{>q;MMcM+GiXpq8FGJGqs9FpCaeMXwhA}aj)D=olw3F*n21$i zy{aqX|zjFurjG9h6`Lh~RF7O7G?;JppUmq6k~WLP9WUFjhmj$GFk#?!Jrv(uV=|~iB3R@Iu<5@Opi~sbe_sA&)%QDc z@jA&E&9EaMt~;bXaFB*##?~W#<@2VCLNkkKF#zB zyuFlzH7mhmXz6W&PhvS6E?+r8yrFQk@k0D`=q}Yq?;+Xsu{Kh8gyoOHS`sh$*ggDJ zxNACaf@l!q>*ag8!|5Ena_~T!O-t&RTSbp@UGz&-vKkPZT2;qhDF`hlMBS0=EelDu zJ|U$}``Tt##jH8?Yxni!h?x%pQK*-i6?YUt!DFD8yCI&ALO8~c$xawxXSV#ZCDbs%$N5-5aEe@lCW})o7SURg zK+cURI99m#6bIm-EM+Tsupc8go~|Vxc@A2J%fLPl&wh`PvAk?|0B`^~Ie=yojDcDb zIW)R_@YmJ#^y)1S2vT6CR}UnjpU_TJ*t2D%bZ8^=vS{w$eJc0GorfZ`!wr7>ps;B^nCE@@jI@)EV`B`*`R6W#z{-!^WOR89*Yi)q;4QbCi$~rq8AAIp3k1`kf#*Y;~-K>rZ@hwr-nVczyj`sUL!}n z0E!)Q8N^H_>(T~M#mrL126-W(vKKme#|~;ninp2C^uV0m5b*Up)D9J>7yr83vVs(P zv4@S+BfaHGnOXjj^gs@)UHPFyOv1*RJ^4{448m_WGGT9n=8)n0wE{@kpJM*LmR~IA z$@E_k1CY;$uwR=6(fadOE>Nvs^;$2I_vHLvIUfS=s^;I$&8x+I*Xo!3-q1NN9{s;R z`hVEGjDio^4zbXnwn=Iv8E!A>)-T?DzeJ^0syQ+E+X3E_g#p{Qo+5;BrENbVxK;f1 z&RlLDG0)M@mH2H2I`~#AAriIoNr{ORfX%CJZf>u7dwbp8-6P(;dzY1+9Z4h-%_*y2 zf9vSzAdpC8_{YV?&FyV%QEhE)C`CoW%a3eUo*b`|AT`p$`C_CLzg4T{r&wm_V$waZ5(UH7!2CT$cT>?ZD8Om zBvhzt930bb-rl4qPoB8r@ln3MzEoCYR8&+IY0b%dadB~3`T3-#rY34^T277vjYdl= zC`g8s4l%*O;o<4+O=huJo<2U5($Z2JTicqUp`lcZRTsNx8|LTcUL_|dQyJ;$>C_C; z@bIvv5!W~B3WkR7vb~Uygx9wM249BJW_^U~()WM)lf^wA^DYLXVYyZ}pk>qB4^iv( ztV=zO-eHK_bVlIiwo@Ao1+TsjGkmq~(jNy!HfroyE1Q0%N-^d{@4>SAI|G&t!dEO5 znKa$SjOyeCk=Wa<4AQ)3m-%dt^bH+GtF;%ErV9tl+U(b^{P^9|EG?v$f!9U1uygdVikC8iM{~r54>K_nIUa4yh_9o6acRS$`OC9|KvmkVheaZ*8caUJpVtw)ZO4+ zVXkr7(U_W=8ahxa^H}H_FH=ZLS3*RUE?>KLEz9pu4vs}0r!sWf4he-892nsB)L0-PkH zM37balwKhHQv>|I6W>-2j=3j)e+#zOvOUw$vheVxDuUx83Jin@v8_2S-JjV!X%AJv071K17uplK4hF)G? zk!WWtkZD~9*YqVp6>m=vz+tWI?8sOR z*u#1_()5f3`jzQoe(gR{8;%z%Zui>Me?weSl7t1C3X}3yn6o5RWx*7GQWiP{hA!v0 zB!;9Ifpm*9Z~)$uglQOk@L?*D$wBgA&wC;kGZ#I`aSCzCA5z822D!$0(Dr@-LVpo8 z+rF01{;%+QJ@r_R zIG8nyu#;&mCOOAE64k=$!Fw8j)^Xz7ba(k*k?CEa^}$~J!>`5m&XoVfPKLL zH&D$q%*LHZhzqc}U4%LpxaY+PaHx~|0m5<9^*uk{s9Hi_X$jiUdF4q0oT-d!voBDB zV0?*v#X&r+7@|q(n-gmB0Bu&4;vo)>E(YS`w!4lK5V{rerKit$SD_40K8UO5hBpI7 zp9V5B1`)11!=$MC-I~E>5Xrn;p`HQWBb$d1%19{Us*Yy7hY)h&$4WwZeeKKrX zo+GZG42(t$sBump%nr1vpW9W}K(^iu`!-(SKe9imPTLP8`R_r;EjLOnP@#&Uoc8`~ zY#b=?ISbJ0Ymd9Il4S4Wv?`!%U$P7v8yemNr~Mu#Dt#kMpbDFB0qLt;9G~*sPIv}F zX1gl)>$@gK0nAhltmgDcAa!)XW%ZUP5LE~kMvR6to-RT&<2$_jyYd9*TYtd z?`D+;LSGqs%#K7Lj)}0JQz9IXksw(#GLueG$%GK`6tm7n<_rZ?!%sy4j9@VpwiuQW z23v0{-uW(Aj{u7Kf$R!68&31e{7@Azl4ovc9&myCZrEE3i#~Zr-rEg0HcS!RjRFoY zxPpF7B@bp0bg}~DYCPw~oe(=aog&<*3XRUYJmzvi0Z)fBu{EqmyBa-UkCpILy_K7b zSomUDUk3*+ko@j#*Yxvezv!!pTnVCcBcz_!*uyi|pHLU2w9g#HR0}zdwL-%_rC@l; zSB&9MGH;_}JAqSKG$g!}2D@y5;oQNE!x^9)qY1|~XePcG{jxQJ_hj2+ z3!EiNfT3T;Zim@XJxGbkvt*m|D?gLN0o;HFOh;;DQ4^@+M8tJGmcpklo zmdJ=HrE1d5!ixp%psjXS5-{NrP}-)E*VO6@A6hELDtZhSw^)G7YemV~vx^GA3OJ+M zcUX{5T6X5TqoM-@DIaQezudXx&9{?m!cu}&NkOK0Z5r?~PbROd^=M}kB6w!^+dKr5 z3>b(HVc7>^V`lj&OXd9nM{YcYCk#9^NSngL|0EwC2!LuyJ50XyW=ZHctoxl3yDSo9!D|Dw`>Ughi0v- zEex_y8K4Ib>a^zAdK$d+=zcsorH4R(Q${Kl^1Jd68>&IdzGDpT zqNfSJ;*KnFLyCYaWJS-HR# z(*L0RkiEuyHPDN7h&w?BAgTBvoIFAeV{wOwun%6ayLXPlm;1pNPP)s;%EllhOQKO8 zno*>dkFcYN!yANLsk;sIFza0m$l47Va)0wWKnF~{P!p@QiGuV;1(1m_{l=hfILab%Cfz#@}SB4698#lq(a zGBBh~i@*SsS%3rC%NKJvzb%h_UoUw9#J11ri$edsawRxKov%@E)29G3VFi2`#!LwY z=;bsTZd(d(VE*|$JX3;s@$R~x8TQoa%EQU;Sz|fc|NYxbFz}U34%gU$v9+}&yY=Ke zZ+CO+S7PoSLtFEt3jAQ}#29F#do(%4lw9cfSu@BEyBVLYYU;!5Rt-|7b4k8fU>nOh3XKDc#R zAWUFD?bJ52wY4wLoVs}RY2nb@Z;vb2Z{j(xQSn9HLvZ%yz4x+tZ{NK!t5iYl8U#Zwusoix^xs0x^ugTvh!3i_Qpcl>8(XGbz)V)j9S7KPE1 z5zg7!oD$QNZ7g{fL?iy<(VoWv%I0rBcJpMuALm6UZx}JmLH05MWx@p1&}p|N02V=T zyjJ?q;loqM&>ZV(;pD}ZCjyd?AWxK37;gfWQR>sDPdy;;2m~d1zvTlC!bm2hoHaDq zj7x@w#17LK#^B{9WawrJiLADzC8EPVM%^Rv29PXSK)L+T2LfdRW(2Q~IlD&fbtb@W zE!X1em@cxivMEq-1_uYrr_L?!(Bj^i0c45?Lg^_(8@MGOmyH=tf^NdR%(9aV3~(=K zq=E+q21c@q{P@(tD}@zYjzp^}?fb`9qj3xDnI_|RU%#Gcdm@e;!RaXxFs{zVF!6PQ zb`MjPqhdLq!ooQ6V1--6fZloB6c9Jj;9A#e15HkKFqAM8z;G#WD%z8Wp$%kFJM^f7 z2%|U$H+E65&eh$LjA7;y8k`XO!ziFKxZWCAWYA*qPG=e`@c-jGk#+fKORukA*m~#= zIa%2fnEi<%l=Ez!v4_NHVSR0_<5|Iw|6bU_BiLsf3Nbr7d&K)_IswLErC^IRcBnNN z)($ABX@oHK1k(*FWYcJSE!ku^C2I=(8nPKm8K9E*kd(ykox{N$IDvIvgPHI40G)f1 z`a)t=ov4C1xmGvN!}%+>c4SfLm-O@!`+_AGy?-ucFl<3fFDfxU{;&cYCQdyc<4BdW z{pah(W zOw5$wSxTZ!OaWt0M@42k))CNP860ewl+ob8!~#I}p%rJL5W2eYwkFfN!#ZQMJxf|p zNNAa{3?qwj*q6JVcdV=`2l|oIyAz-Qnz@69K}blMDE`4hH!F79&C z`KA3!T7rUtshBC4X|ij*>qHetM@N;|iT|?y^3_&J=_L#zS9uK3?sh>vT31a?4GyOt z18QF^+|WgL!;a&7D=RA}kLht>-oqM~udA!8U)9kmgV9MU2@7M78*m&uy0I5Sm5K#! z=&Am4GQFCBl182v0FD$glrN#JM1uz%1i)hmESkpPF&u_6a&k4FufKP0LMpFFTxlBYCLD`Xb0N$c=fUx>ckt}3 zdExyh&!ex^pD&1m~cWBz4zMXvuYK;ZvHv2#Oz+#W+954=vzUoc0;s9)Z5X8$?DU@?IgY8vDQU z%6+4|eu@qCwt#+YFcYTvJpfiiAgWYC-ul)E8IVo!17-~ZHyPOu^bqE+ zue0J~LmLf+P)=rwb6vi=_2;oT#E}#)LqGTz7xviL!otE6j%n!T(CyF=K|vp{#Fc`M zTx`97MBpk;u0HqQevO2SZ}iG(RLU5*inXa@@rt0g0Kg4~XY`bS@H3Tm_|T!$urv@S zy;An_m>zCoRBsUF;3!|aLTev;-;?$67Xl_2hF4}-Tpdfyz3o&2(@r=J7g;pAe$xt zHk83+w+EWwps!!Q+T_*275`Ct@8M?LHOpsahJ`%F?2Su9%)XiRKUsIq}zX7Av#)lv@ zd41}(M>oP#C00Rh$nuq7}oEKHPf9_vtNg!(va;8?O% z3I>LE?CgReM9pn!fR6&9bu9txY6|VW(rhPijF0~kS!}QKMkD1D&QscSg3&z29uqo1eScdT#(*OXcr3|wz;b~I4FONNy1yO7yz_`DP5v_FQ#;D#f{$Qs zfc0oVS!wffP;zU5hDnSMdmjtb->dC%b_TPrK)7`wQsy8&>FwLy!*GFo5FDb<(hglQ@~6!5ql*h1qkHH=$bqMn|0 zB8yRRIR`ayiz*BO@^Ak4WcSLX2D$#q00-V&oI@52ue;w@CNS`B%Zj!Q-n<@Pnb*L( zhbv2Y6N@oo;Pq^%zc7D}$q$LQgs` z%FAJKQAbCop|SC-sj2A&k|GL$qKsXu#wAy7AtpIH8x1PcZ3qejjqx68(WGSoVve$29L)h@d5aL3mm7o z0FTI1184>FEM)J%ybBUggm5d_Fb1qPm;s&!eF#g36(;&>2R_~vKwY9N%kB`jb)M|*|RS*vX?M2_MNdC#yW-> z<9AKxd>+5Y_xt#~-|x?V-+w-T^$4@P?)$p0<#|1?=Y2Z*qkt~{RR98i07-FX!`dMj1+y*Q%%*-F5;H(H|AmEcOqWw<|nTiJ!dAw!5* zOa?a(PJ%OWwjH&>UOWJGFLya1H!_;3+x&JjmpVDt7%N1;uGw*;F0|bRrQ+Rg<|FtX z2|l>RMeM&OK;~ot@e=j(EU;k*Mqx=upj!yP1jGB^U;ghRY}#aN*5c3&^|oNNuQ>}6 zU+$c^yvuMkH?N7$>Ht{778rfMB>ehlB=2Lh z;FcHf6LJB6H_o-z6+`(J9qwQQv(RdFVU!yKieNk>38X3AEmER<^hEd||4*6TqLj|+}cK7pu^aruf?+q;A{I{pkvmcoZ!6O`!KLl&RKKdW;mAy2D1OSAOm*x+1BIgsr~&7T*ey6;JxdVn*oua6G(llW&l49KnBH)_AoDx_D$J! zb`&C~3`iD=fXa^vC@GfQaF1__SF3xzThbD|ue@#ZLDqvU|E!D4)p0}_P?l>vn~#k2LBgW;Gr70$vCFaMeY6&tOas7rp8zOGssj_;1vpOjnk^esz-Zo@P8}F5iU`>fFcb+ zz>pOgoa@>I`IZ+`@jdA2e`Tx=4CBmsV|MEJ_AjJeXgFM z++=D7vRF0H9BR$Vvrt%{MSuSDO4&mFiFpY2x0ikM^NvZ)DTVNKJalC0xEZw8YKnINVLBKHpvn{Lo9jGCyZ+qRO zGwmu{GV!ix=$UA+ra02gcFtzg-|tFm@$Cl==Wc+?!yvU&V!qi4#G>P~v14<<{k9>9 zKjL}SKJD0BB+tbpEN85h+8sgmLlv58`ysswgFICPz9LX1;VZIR?jX5Y)FdTE$S)+!)ro>>VS4@35?-grwJW^;c{~uGw3kYyy@I@OM7Y+%H|L}9?!)|MAE0< zFRR#{yi7eirRuk~6a*s0Z7jdd%#ELsTDK}vQahOF35cY5!}vPT{g<(1AfpS}sBooi zJi9jCewjSS74R6o77u|NMS{$+6DZlleuedZeGMB(>bS}EFx_tb*rv9>cU&CMhfr?9 z0HdEGATer9?340~iEq+50E^A7H%dI|7S1bM20P!|mE~F3fD*_2pufQW_;OSV0|dbY zmHXTbAUjB%P|YyO|5S+C{J`;NY)ife{azPH?5lzHf1UQtaI&MM)s^c2KvmCOK1TV$ z;1^r?lS}l?UxIWnF5FBt2Oii`?4y9)Nih5iT&csF*HIk)v&(-!|M$cTfy02ZM8G>J zacvT?zK;{jfPsi{C7EI1K_2FQ#!4L@X<5Uva@C`2V1{BJ7Zd32?hYPE0>+#Rh#%~; zssP^So%F8FZz0ow1TXn0v391fR2j84ku>bc72Flt$b1Q!D>X2-Y|$_Z{w340-eE~zdk@DUn@IXBovEt@B3Y^ckqdjnh=2F;_HK z$wvi=)zq)>5xd6@+1ytS<&zt`oSv zN$}XU=VJw z`Yd5o#idr*#yDwf^S1ZPc)Rijz$R+J#Z9|qDDrblX8HfBh4UzSY0dDN(mzu+N_5k$ z%jV+%f`!^7cqgl%53LW(+e6fH!JaosTKuwApc=|L3juw;vmdyL6L;3f3xtw`m14OC zkl>qH9gT6&QVE7RnKa{+sM^PQSiwiNkWj*L?QZFg;{t}@b;JQcbYnxGt8RJGPD2l0 zs^j3+QrHEt#3By>gM@_rkFNHBFZW$;GrBZ@hQ_;?y4PG$)(<$HuT@+u&D`5=yFkNO zCPT{^Evp%eXQ9{&598H;AbJAq*WKE>S_tN zDL1ritSO{UgR#j&!75zX@8hrp@d%t}$65VfzXUObswsDW=GHrUlW*VAoKw@;{L7sq zLJzlxhzq?<7J2oD(zaWcvD+(no;|zu@Xe-u+p6m=<3kk<&ffV`c>B$+z1xo5=-Tn8 z&XqrdBRB7S_wjlzd4*j%w$V_vi2BY#(S0%p#uu^uGsSe*CihI&c-IZ=ihGkjZjC}X z6Lj%#cHK6-^Pvkgpz)rh#rQ_k z{)Ja#`?9=hwzVsAUrl`sc!Uy~JuDOpa8Xt<05*66dqheS>oJqx;RLCAhZxi_jc0ls zDePYIdhb84ORCT}pj`R;)45+lcx!~$#xi=N%?zNWM)^81iaHP!;9bC^ocme*D`&LD z-EZZB8pRpSMFmZT$4a{Js%o!69A_Mdhc#E0ihFQ=5wu}R-T)_QvuWU>2YeTz2#z4^ zQaDy4hn?TnewzE0lP=jK|Nm!~&mD|+R7FZ9cv&vO=I;wj5ics`#yV{=my51YdMV5K zP3lM`CUakMKtO$ciPC7765k%@$LPA$Lw}jJ_&J7{?p-C?-y8>O!Hw`~F(p`7*=vID zlcWAwU-(CXPht@qMYr#A8u~tJIaOZ?+QH6?RK$i?%?6HPgDaR&1r*2;lD;f!YM64< zx(95HCC@phCho#p1H9h|QQOo_d{u3;{D6f6-KV1zAMeqf>fM%Rp%j$=b3G1T)|L9N zO}%`?T0(tlXpS4(#~{IVaw?rESV$;X$+lAgU?1(;e2zDofL?khr0d}>2#+WK=krzQ z^?Uws8*$>Yv+M0Kzz9p4f5Edb1Z8=VP$uOXvTO^;39EW_94!JI262$YJKZ zoK3@$VCw4%<3R zsr|CKCVcf|;hS8$$gje;ODtx1PyDk}3cqZu4{Y>-6jl)o!5SFaBB9IV{KKssh$P=K zEx49kE6h#l7Apj>*~PGmMz%-j|mEb;R{0qF^;mD7|=LezX zj^~ptdb>IfX7nu+e#+gj>gGd6qpb|Nmf@55x>|NQM(BflE0IlZ9UKFXZPJvX5W z2_Vrs1}zjbJ9<74tunhTLu8I=Xxo6n%8i%YhnGfK#Bk4+?9V-E-R`ZrK%SA`_$nEp zNMKe=;c@IbTpZ2*=+6^)Ih3y~rVk%=ts^q)r`5a>XeFq=jo$K}aP5~}HFr>a`%nIE z!*YbVhejQXg}=UK-sIYt_fH$MuNJ^DtHz3`;n15O!++)t@*Be~B_VV@^8bGGzt7o6 zo_;xF5ag*xJ*X3Ny|x%^RA%`(?Ik?2fkf&g{Ef&TgnUh=zospR;k@BdQ+l=iuT|1i zLjcj*H~(<|jf9=_l%uu0lFOy*C4Tx1>dz*+=j@j^-c_01fICs0)+N-gvrf5u{ zCd+4Rh${o_1X=SKNWROImoI&glOfy0I+fT>Eh+pq<|w}onZxgzDL=h{{~@LLi-&JW zb}Pll5NY=sbLu2|#DFZd+Hh*?xw=)Fjb;y5glyEe`3np~;WalFHJxFkE#^wPxnkPzu>)Z++(Q6i?d#F4j{qPmcm()!Xi0a&;&l;Xhm;V9J zFnEj;>ntPOve5}e7HFO-j(}!%DA*T z`w$ilfbG!)Ik>=teIKUz?)8mbTd8jFSI`rZF=;ge#C6oOj70nlcZPgvov=9wirU?F zDbdWC@m4qPi9hwv)=KG)M{p)0@GGPhV(MhW*+DF7^_%_~+=3MDW|Q7d_OKksa*^vl z8l5>~&c`~`w$96KEXXzTYBDRvKIUlRQ&`dH)o3xQ!uH`p_YyCsKK}A~(efMZ_np0}L_cTQ92~hvoHnQ1lh)d@UV+}$ zC!=WjjnZ;f={@~`>V_w(JuD$bvHxpxZ&FhEQYTx3THU5D+9Taz%YDGrm|xaSLA_5l z5c=uZf^z<`g#Z0xZutLyz8cnlB`-!1*zfZydY7Qui(%$9A*bID@IT7_!#8ILf^lEj z$WggT?~K(aGXxlFAJf)cyOG;%pBAljSF__-t$^1V>Y>_aW?^{rPJ)u4WK!F+F{YvDa7Bd5 z@N;hRFzbzQsDQ+sSPV5i9WtU^L^8(R(p>*O4#-HnUOe});Hd@v zIRJrhS}NVz-CAS9{j-t}`NDNYa$>SF!{7kUE#f=Ml2ri*js?+|pV(LU)yfqL$a8SiH|I?#5Pd8!MQx>)syaFf3hm8tjW zUa~D+2K8{W>yC2}qH^-w!N-ahs-9Geq3&o$p2b!54Wy%K%1$*14%I(^g(B) zC_80W@LcMk^On#DI5PuRS4mkpwIcU8QRG+Cz26?I95d8_q;j;>_^I-kC~@t5zUFE* zh-`GFLse!_qM5I6N`ULS7JM^EwO?+H-}n!HBRMVEU(LA0&CVOK0St+sNnfQA)rH0i z5O_E0)eft#(D{P#B+aJE)T#J`t)=7T=^dh2MlNAShvFiaGyM6x?1_~xsS=>o*m#at z{3X6=+m?+ACvGMBu2hpG+lyQJV~R&4~t)yh+TG?6<3vi-dj0g zKs9dqxOxSfNJI?4#cDBer539m!>`KDuX{s}R|%jA_euT5&RaA3u46Dx-ecys+;%kP zChEQXL2ZxYnhqa+I_7_U{)}`3`|mm*U3+Y^%QrV}8+~*QF*tgYA}lsA5v>)2$ z-1FR>)~4{7 zg4g(_&V$c3M$w#m-!e=J9Pi|QI~My=OmjY|Py0=`tJDAq%8C$Ni0RlSRlB9{_Y3<9 zRH>l~c=Xx_^i-O!6&1>Tdr%{8c!*$+910X`0mw7^L2J-FuXr8X4@^4R<-~>|`fI*| z<~Je|>@s#>En{FxmGFEsfwPnn3(eC~Gy3`#{45m2$&NUm+Ryu03o+$pOX5DqKpGc> z=Ud1o;LHO434(|Jc4iv?oO%S;d?~jnyJMNhIdxnxBBkQnxA@AOmVmj`{+MxXRikTSWdpNBk7*_J0)Hl8qGOl=mc``aIYn_o zU1VvyS1#hkO05kLB<_uGMc!g2uJp|pH@TgTS)LAzR2W=bkE@7+^?M}8oelWmw)Cdx zu@u~X<&PdrVjfZVH+Ba^9HU;+;^|+ zNG-x`{Hsv3^Q8`Xfp5j~`#ZqQDixN}CMR$r@is!MCSE%*T6%4q5l?Pi`Auf{yQyQ& zC0EcTe#L&5s*X$kk4DE^EhUyfA3K&a1@M=gnBx0nim0QIM|J9t>LtHw);Y!aA_8W} z18z~9i<3IG-x1+=7jXt3en5i!r@t*SW5qRt6PlG8YN&b3h}4;d&{EHdiCKI<61rsX zY>%|^AO9-qRFt^d5<|Mhu!u4}D&z<$p4``r)B0V6dXXCUB{6&w^8GDr`d6*~dT{2i2pq;hlTY^R^G)?OI!h+EUirWN8;B)rWjAL21%)-5%+7a9$5r z+wZVuz-foGx3*8CPOKru6Ea$BV6{1&fk6jpjllo34lsVdFF}4znK4}vc-9{2zd0-D zggfIok#hICu9STKUH(E`B#H=5TkFGQD-T(5DGnMm`CU+8eqX$nRqWh}5APZJkdb5m z+S5+{AuCWcrusYlNCrDyPOz^-j?P%;l-lAGXLusx(?-ZvVph_B%H5 z(pl)HyBfN*rZ$gN1$8zm58}h;lMthHEnEo}@QsAe>vm;wXi^#Tt-2(K?f_Nn zfeF-ZwX?JX^zl460T9mJ;RJBw9ybk?_$S&6a1Y3vcax746hYi~GL(OK-H5ahJ@#BO z{CAg4Hz{v8UvRNib_vY6RyQpky_@~K_bJFa*Ap7)5gJp^k|z%Yx`ja%M7rbJsPtX+ ztkRO8;4@*X`>HJ>3Mf&NW-d-JChs8{mQ1n0zKnP14f_Zhut6=p8B30JIzFCyEiak+rvA?1F>@QC_y?6c3>aoBshbwt;p!KPFS80E zTSl=}imz^cT>Ld5l8bhLCTjRX;W?#vkwfKms+R3;Mat7f=N5f=0HfjN&;Kf6;6e~! z5DM@Gmv}jJ#|5B-5pu~CH>SlfHCS_7!n9%!( ziy@5oHSgr!60oDqtyjz9$+#4`x#_aLZi*Ug=NnkCQ_sbj%4bRdnTUlRTroQiuV?uh zY(fugg1gq-%EABd&s~Nm=VpM1U*MY>ppqcYb2HPTbKi?$cnJ@{M^^QDR)X%!Wa|DV ze|a94cTLNx;GN(}{_9&IEVbj3{3E=9pd1TylMl&J2ax~lC$~EJzq3rJ)wTmGL;=jy zQ^nsB2FXU>Ecd#SWxP+f7sBn7Q%~)XvO+jI%!ZA@beVMbp73@vcmU6TUWEHiE%Y%Y z$0^0o4fz=(Kt|U4P967i&-~lZT|ECB<7MG07VCwrxXs+N7`jzVuE{gM%}`XyIZFgDrqVo()sl4ERPAk4IE&c^)@djH>SdMETud|clCytzoYkQu1VybQ~j~w zm`wZjnzv2bv0`lM)2!oORK2pF2K1&H0evLha6tZ$lb7gb-Ftyt`JCm$+DQ-#^XnrM zt72LS0t+?mnAGnIWOa%VKk zP>fEiM$oAm;5O+RxnZRx25edDADh;iP;FNSRSfBAaaH7So)QM^{SV21dmc6r!{P}Y z9Bt-%=pmN_gG;+!ElY7*?+$);be8YETO2{g>UyS6~m*zX7%&$;eExr7=RPcrXLLIE3V z%9L_Le`SYw!+QLccj+LURMrJdQ+y%ZWG3$Z%2q0tbyKb*Cy=E=y>rr%ccZZVrM?R{ z&YA@WBCuWoPI*wGyegjLMwVP)Xzxm&eoE5Xct8hO=j}-01m@mHsh(10Cl|nOj!#RF zmE-GAE3dJ<9+*tkBf3H&KAkY5s@YaMfzdx%H7E%16N*m<+M*}P|v zK&6|dp?Ojj`krX?NzuM*SCSlSNNh9Q!WG8M$l?s+{_=&0-!~_ps1kf4 ztL(FS+L{<4MpV!@00YB=wfBB42)|F=fX0er0i>*_8EyCS@ZsN=M&UlVb+Eil>1i2G zolrEnDPA$&$sw!#Qy$Lgy*;D!)pT1!PUemt`asrx^=rB*vFo)D`;6~v;(bD&ezPcD zp=wvPxM}qe)_a|ggno#_PEWf=TGW$RgHTTzT(lD@x=W{j z-*-3St3I~@&F3k*e{FzA)bVT19@l8?tS=u} z=BoAFTYZBI-qEm+dUk|8wH~o(|Fb^FDGBk00+--+RSG+Vl;g$}2-0geJ0Bd;HXLfcRurG9;2xsdN`!JySBI9E&#i~z)#KasgQ_%UY^-gJD%*JYF<`m7- zPdh~&DiFhk9oP+S<->fLlhx<8&*PWTg`=c_?!c)=9yemM2{@lQ^O@V)9>u_}yh?17 zRFq{eR|fFu=w1I}{7xEE(2n~<)Z|s?yA8ioh5HT6W?uFMwJsB3+N{r+{kW0SVebPz zrC~lFH7!LwOn*tv%v6?W2ZC?(RF6PwfLxksD_tqeTX){yf@*UBuV?FUgH)28)!7pk z<3tR<&%QQY?Of|l8=+5)Da`J2thK10_dCftSc};*OXgjQLy=o%E_u z-SxA6l@@I2{^;fn+CG=Z0>VN?Pa*Z`ZfJ6pzghn4lWb?EcBgWYuGQN%(wf_K)@R*@ zZ}q1VRuQ|3#c4;iVr`tEjqq2GRJff@=(obMQJJIU?C3ywQlt57mxx;JlmBR>_&c$Mh?ym=mfLejJ?Bk_?OLl)B^;P;^}T zpqG{Rwu;?Ue6*D_o16Wx!~MHpeDNx4u9(Qw>}U?@d}=sEf@wDCd(zsDb)G|6Gim__ z{QX7=x^v-uisEr`V@s@;5IdAzyztWCaN4=xjqhKRmDqz*bh~|b1&bLV;{B% z$1a6A`zCRtbg-7S%m|(2%cGx6ypd4el^epZe9}V4yz48+tHT0wf8LbyZDYh`=rMNf7Gnp@+UZ#5Us&@B%RBvEXQrG) z?PeWnIWiH*zJa}Md!?`a`E17QEZKST&eZ;8HGoy>&02M0#WRwVW^bTOvm+Qmo0l$? z#CNtONVfTiBdXF$^@!$$km|%Jy>uDh80Pb<^a{qf3N4<{eF*&k8S-_-^dEDy$f^UX z55|N@?<3BaE(-fOG<*(nFC(aR8Lm#vIv6{!J7WwszFsk?Yo1+~VYub>j|BRD9SGGf z2!P;#!D*Fe7oT1MtZ2_7PhZ_Bx8E7=<xxX_wF4)CQ z@BsTw<^3m_z5uChqK7UoTC(7Wl5E*rWn~C;!4{!%gsuPJaK(KSs!yi8)`WJEX<;0Hq$Q{{ZKBFW}~Gp zCj6rJRdw1;TqM9RWln9awd7>KTDV5p`Ls&n3AKc-5)@_;= zx}0owWN+5E9J@@!)_6_{tO=3Kh|3>H<3?-e3C*|DAF~AtGtqOo6+$I?*c-G)CBwnv zU9U6;yr^L{Qj>;7`q=vRA+@Rc@FG;V0IT_)rGA1FKAhaF_+Vr0=z@i17V7@c__{5U z7Gm?hjVrnM0hPh{(Du}CwJ;}9uG5H^L~0iUR*@WIm!A^D&Q*Y9qdt6LRaQ4xpCb0? z47cPaou%0EHa*duxH=`fKMtyrMlKwcATnjED1QG8s5Hnt7 z&#J*xx+CEajQi&^iae7SB`1;WR$`kfxSSP%xkV-Lr7`Vm7;-!j{Z*Fcu z2x4jqN3#~o{XiH^d96Jvw5IMxaXZ{0$1qzW5;g5;YxiC(-aCwV_DXV0)Ko=geQ!a~ ziWCIO?X21ZJ7$z=q8w@R3%N_P(u837gYCIJ(Em1E>S4(Li9Iu$ufXX2HLT8S&RhN! zmV(5#c9s2pW~s%D^`9!ZMtnGPOtr=&`pltPZwZZ&7Z>Um?W9nAfz}dxg=RdTP;Hb& zLOjtfFH}nOFakr;^Z8RFKD{BGK5(U8)>otLUe=Z6!!f{tZfH5C9=U$2tTZiD@48U2 z+`^T-kX<7yUxjuweiT)c-)8>jiu%N-S%DS`X7%R`&zqiHGR2Y0x#wL`zoGZ*-)PnZ==BM&jI!F>flpO7s( zfy33Q_1{>^((Ab7-IPWH>?URGkmkehu7;Y zTt|`*uE{elR%U#T_P9uDyw&Ph19TKr{-S#N^GJ;yVI(pm4 z{C3_E7p=I@;is%krzO7Rgv3u}&`n&~=jksbl`Qb#J||-PKZcPyCF^Z4-gjs4{Ah(& zwtq(ICpNmo=S;2&)rBPq87&zw4JPj9ZQkgxW>n;=C0%K-C-7-KnLp19M(_S(d`&w% zu_zT~sW8*Sw&mp1y2_y6#u|SQ@vD7SKJUKL99Y%t#yo-;Lio1fTNET^UohThtoiHL zQw1H)M=3p9-3f+khFE=9AB+w1`?YIbgYHc}i`S#oO_6A#s?Qt+y=7@>ezX%~&3+Rn zYY&>X#5E>nVB+WXiWp7X-hI7e7nz*SSBAr;2+QBRLTRwT-VGT$D+Ll8U@>OpvU*>T4~)Dp~Fh zZ14@&ag|Z4&Gk{%)fV?Rs4O4)pgvyLT@Le&E*U=43I%^69Im>@L6}XhkA0b!R!meP`odNhft7b{ z2M~F@8!^g(9fk<%bo|C`p>_cCWQ$#J# z8+R}r|IB=ULNsRTvcq**qNLmVPG#K<$_i5{>?v+d4J@?trRERU=x z#G+595gH#ca(6yM1#^5VQ=qHED`)JKMW>Noto#Kl1;&=l6rp%1uSQEjbGZ6jCnnMl z97V=&Thpmr)%Sg?N$s>u#1T0=#eabGe+AEdybbY1ybK}p1w&G?qF7dnv|cEIc^nb&P!3?Wvww?)b4X8QGoVAN82G#7fsm-H$sK zynXyVqi4Pc=vQ_uiC|H@uL&N7R0( zcJ5gDhALXI@DSO{yvCO2bi{ato~T>Qxss)-(zFw~+-jhsw*|A@;4Fe$oRPL z{vFm1ca^($mQpC-`QM9KX{ooAyM*u9^?O2B^#%NE)*Zf&5iZx1gA|gtaI}-cHI7au z&0aE9S@KdTs>EIBjzjhtx~gbo=usOI2D1Dwf?+W=4?5oggJW|AFkTs?wGzS zZ>!1v*#Y;&nGiB#d?8@^bWANOp}rlh$R`q_z6&RqJF)}sPwVO2wWiI_=X9yORGIj= z|D3ih0_}put9&b;IA)pPtLh@4nM8QzLc01$!`7(Z@9paRrF%i&d~M$=xGe1;Zq3t)B9E&S`CbR_~5>IRdM9yuReNsYVhK^GG0%q~G^Vul-!4=244JvDi8r z3<6{Pe0_+Sjj}=G4*}_;W18l5S5z#~_mtTBLA;(>glI>EN8(IKtXKRP=w>ui5N%<5-Oh5YbeHlLCgarZKrl^x%A|Aw(O`O?I6cG*O4K|UKU zIXmr*7{spa#9c^onE@(#FuAZ!dqv)QhFnXYAfx=Nl8=VJPty{g`{8zTI`p|XHDfaG z6~gCH$#CmB>aS#qkNHT>B%&jgS1l;I_W8Oj5iz*tk#VssN~%UX%$Z?mB(E=)l<$^S zXnfF+673?(?P>~B9A#$1^NfUM8rW4vt?^ESA}&3sn5yByu4hj7!uRrawsL}&c1#EB zt@%1=*um97D}o~-=ahA&XnWSBlc$AzVsjKfCMR8EESu@j7t5@4s}09yAa0QD$y3(?%#j_PJwXh7>ZFLpd%jMq6Cb9ErFlaDSif}>a z?PQ0lY>G;qoDd-M6PxaDwviaT>tg>1k*`-VclKQJs(I z&KOxcXB0zMcRXOudtSgrrkz$cC7;%i z5juA)qw_7ZwX`#c?W1N)2`EFkNFOJG`>Q zR)!awT~D^45l}r9j1bj z3+0v@r_~QN#b~(rGfCK$EAJ*>S1o^swg*ZOGg%y-?5|T$XfDSZehf-H*_9*}r}a19 z$oRx~%QwXR7buaXhiX?*zZV|oyk4$jZhS5o&q(8&a9BGj zUdw!dn72SjxOtd8YCrGrRyF9&!TunB75pEz$efMD9H*0$`hd{$#OEN;ioEq!!y8k4 z(Ehx8@&}^pPk>guUufoJ*_fAo@NRb1SFT23A39IAJld*|^)+UCe{N%sn;hK*(#)XL z=YX4WNn`(AzdYX_>7_lrzqicuNqm66+KiiC`89!*acx6So%c;XesJJv!y{~{XEe%;5K801ll&p5Tmp5m5%W7Yem4FQRI6gzPn zT_%dITD42b4KbTu^)Sv>{;N!uB{Xk@y%bm(#%MWUB7X-TPBPGoqrcPa>bXND(oT3b ztsbPMk=kEn-WzCjvv>|0?_QjvqadMc9;ab=YV-sLs#ABUC1t%9COdwjlA4md%5p*(+nA2I!x3DfpwZWx1Z+rQ*; zKp0c0Iw0^^?sUvhNLiGuv-RP}TW^q%)U5eLOBw$9()l7iO#Y=WJ82ps$4$So;?7 z5>455%Npw^wSw*}>kES{ejcHh#XS$Rs^cwP^W*(73`V&00VKkWl^Y;odf~$jGvD; z$XQTsg!`ybdr>!-n@sdZd;4s$)4t6u&OuV(pyH= zEA2#BO>U+}4NsR~hR_52nnh1%)a-Mk_o=^D67`-XCy`V@OrY%ZgI0Es->NdpRpK@@UQa(qSnTkwuAhv}vPs)!^Waki9I>+D$|J8p_#c zdwAX$Nf}V&>D>`}33$~u)w8w98oC)lrCl+}RSAmX^7@3|O%rZ{Z<`GN55Da%KHM{S zGww;COSl^9zIxGi-$0u~thAw$c`fEwZtqT=mzqBBqH?o0f=u-c)utPA?awy~hIpb? zyYsznVVKl+YvP4Uc1TCj@c`=e(U;9#6Q{@2R!tr{nM`Ns7Ugo$+RoVhlAm3wKef8Sgwv4y+GCvDozL&9 z?fp){h*@Q>TWoo?p(}z&eP!w-?Ha)>18AE|Waof9nPi2rvcT){&Of2zdpqm}Cr|JN1 zFSZAz&7w>3W+HwLdV0tQzQ*NW>ERh-f>C-82T9ed361@hvwhTl#jYDbY62M!ML@x7CNQPO9))fADJIfM5SH1Ikd9 zuepT?tHqPKh1DIhUBCX7m$&*S?4M}1l&&s{d@R=S^b0>AS2lSgrzFY219O;ys)6QT zN8FxAGJC#CkEGCI;Hbk@1=co`Uu}{Ob;d?Te3eXGbt;)m9`%g#p~Xtc-9Y3-dkQyr za>s*$a{Cw#qI;V}tkf_s9v?Vvaez*2dS_PyZj;7>o{18Os;e~`B45F5eg;M+N1%FBP?XKJ@QcWh}DIr zO&N`EY}>bkNNS$vprEH5U0)qsR|&ppss%UGnr~t_dv)a2EE*ccvPPmoi1gAbpcU#`UyOXos-cL>#!iY{ZD!f6iWO5;3lJhdDk zORP6tWGgSR)hs?}( zn(HSKH%E_led#=)5BZ_O8Qr?qZzZP`ka0?nY}8A_*_C>6zV=ALtjUY~Vlsm;;V4Jn zJ9lR^IB`rx{sQg8M$6UZpx5EJBm%#Jrqtj%Pxq5zo$}+_II)Lc57h{*^=Z3&RuX57 zn$pr_#ylDKbU1q$Z4%Qw)Td2VBvOcr|NqD*=FGrQvF!9-n>~X>mmua@vFEO+&Y?zU ztm}|N`aLFY?oEPS!{ga=7r1nYoxJyEa=}r)Qjgn|P^BtU8%=!pa%Q9b8Y)C;YN=n% zqDiIt_AuscRPxsTs#iA9Z?_IANmcNxWc^?o$Ms+C&0Cm@>R+xsL9ux>(=aoPm6LUX z{CsLW-rd_k<(7J0ob)JFqs~Dy|J)<}mlxb%j{4>J#GpRy$}xcklyN_%E-_3|Xwjb+ z;hQ~2^}SL$xwZS7MPFvX4|^p0O5c1GTf2PFRpZ3m(0m@S`-YG_m~?zP>6#T3tCQCd~srVIC^oC8dnb1C|3yi%&QUnlsIEzUPRYFD1^M zIHepaG%&lqb$v*K*TyR61J-MR)!!ioR}5*?-Mo8RN!-I#oP`%`6s#YBfy{c=?i@Lr zk(H8idE|cB^QhPS|ArF?rPS8$5Y3A9U{^1VxNUmBY5GUK4;nnuSA{h#5_O539sJeS zH)?$`-tWocyoIL5$LK&eeN56&-rOzbnSy*oBdBhfTc+k5O{n#5A2S*^9*iN%(b-;K z0tukQ5MUZi=5anB^KQiqZd1Rc7F;IDs-^*H{!+&cZGyo4Z;Hqu2&(hgaaXW`9XA;@H3v_&#iRwWbkiB!GVD9yu+{ISTTt?u^(JSIKS ziP+yT$8yFYkuY*QSCErgd!ogCDa}_rF5`1mU?;jfcw7bDfjP6N*+CsFQzjQoiKAz> z>q_OFSxMP#Lid~&BC~1rBwDCIw#Oi!*Z6#1*5~v)-AdxDbM6%0bZ3}NyH)#W{!4Q0 zNz*sH(Fl)ajj3%4S17=K#_ma5l0>^AFe)CUvfy^01IpVZe0NNCJ}N7i;$p3f;WtYm z)NSPoyZ+cJBxhkZrZrd&TsqtxZ67^apy=ysx>8H08A^m;zp*pk`IZ%4|M|GQc{^FH zman3#dWd;$;=|-~XOsh7Cho%u#RYS)VBV7zQ{2D!$@4*%RFTK{@Bz8Jz2kenqQ7|d z5Iz#IvyDwmk&Yqhn(OS=o_^^i!)5E=_IYM)LY*m$3zR<|B@L_ar?K4naOScI9|j9|n4Ta| z(JC$3a_G8wMlSX`0;3$@*HdSx#*Cj2z~$pWi?nF_+S$T~tLp1dpVdpvMJg(E$IRCj z(Cp)W_iv1kso()pUEEP;vFw-y4V@wF3;Hwdvwzqjn}l+CeiQ8N!2Shlst<*A;+q~k z+_kF{e{Nlp8<0TOw9^z3tJ4`XRw1yO+1Yzy#i=Y&GZe8XP8bngtM(eYkSAXJOtR}X ztHFOkck;B#(cd&-*5IJe=vwG)%20%x^t!#eS4<`T^2U;aawv~gn_K6zWJzoPX_}0K zp2%1!&&+>l;=G=Po~E}mLWWN9X$ln+EZePjr=c>!ZCI#U1(WhE;K8d<_N(Uehi#-5 zZX#>c9K?Jh6dY`kif{F(PiG}xwU~|!6lo^d0jECzS3Oi5Q$h_L-87W(Kxrz#>S5Tt z?aATVwjC=0v2`)O@Zz8#cxkqEG&=V)RY7cg)NQ->+2qoa*Yt#1901OH7R&{{&JO zDV>I)wdc~L!~^MGnPY*>tM`)znhV(tHgWm8A+rsOsctK+)tK-odOb)^Lib9o)tC(A zyB#SQ^;hBOQR`n<>k?q_JOC$=;pZ~4M(#dMOLJE1iXrEO$cGvzI^|Vq@WV}me_g1I z$j_lHv%~o>8qKkT3*Wl`I6_mawXV%sf1mdlSFbAaD!Gc}|?ONpP#@H5dmC8y}cH)w)2rVWFHIm?OVmH;`B(B7aCx-1}ua%GdYEbBtR$m}sqw zEmCs%&GZC&>T24)@;N)-I6}97#sHJ*x>o&qVkIutqPe3sk=Q}Ia=g5`(^7Oj2MS6d z^g`y-@=K2Vh#}X0nY*HB#)ECsy9?gs2JfhS>*HC!`Ge+nZ-+Lw&|T{-8JbC)hlcZp zv@~D(b^uo2R$q1<_v(zXh)}a@bDR4;?~TQ1&Kt6ic13Tawk_HhX_-(ye}l2TXBSl% z+$Wcw{;$YQe;^%@V+VV8q4=GjQbr2fkG$nD5oIV&m(RBGzS+8NU4=-(6BYw|%Hl|o z0s6P`0;+Ux6>;JSm&Q{j7hYzrw!OOa`$NYE=3_T;RcS>6ja$k`zrU`!QlDB8QNmLf zAZ3ub!K!Q{QN`)Mvk@HLVKXsS`(V|Bn+r!??o;Pi`(28GSu9nTz<3Y!KY+_eHkh|o z7!pMq-$qU_y9U%dyb;|(GBw3pRm|z4+NkYKrWU;7XK}VR>3q?nCIyB1F~wS>U8QM4 zvODFDu6!dqhR7|L6N>w7T*%BnN9!cqz0`W2eAaMXGw({gQ)Hp})#~nvGa*=sZ53Ss za$hIsB#Xl0G!^45W(t}{r&a2kt*d24f{2P;#Q(3b^NwpG>-uNY|NJl`rG=qwO6hTR(OO()&-U)&C z4Ene}f4uwXM>FVTX6~JH&n@Sk-*=B>PC{;VZ1=1P%;i`-27F6Rg4$~JG5bT7cDHEr z=e#&ym2668dMiSET`IO^x$IgjgIfBk<%8hzqiOL|ED4h_u0@(8Ug{N1?{~uCLyg>i z+uNusA6LTUZ?fQa68O!^ZEFPZ5&8pMH2z+Po5d%o{j9b5<#|VfiSOsEUUW32XERSl z&Kb>1z~J|#SkfJl0Zxw>Zz~1#h`PCGE?2KQ^zU!EaS+Z?_0dwE40L0WJo=u)>j8^J z4_dV)rWSp^>H{OF@zzk_eBl4s^E#3>^2L7YeW{nB|I**jUb)xKUaX{rbPv{b`KDKI zEv^>Nt@-+8Y5KDBw#Axz$3xa>jZ^%kDvPgUYf0uWmv$|<=-u<6**i)lgiReND@RGUOgAFmmF=}E+xRjuK6__R;!8*Tohog~)knf5VXS{~NWA#+x%2$` zSLbQUH1W)FW%p7su28FsxOdb_<@ZAJlX5oP2ZUtWo+J^zvVJm>L&Et|XC-v~R>ro> ze-Os8kZ;})(#3dg|Jdp1#&Ggs{AR_yELkdT$lgtprO7&b-ya)NZT{=c(5$NTpGB7! zKBTX7m40b-yS(OKSCT85cGGT7o6wqx>2E0IoqVTx(_muHlmQ`2t!rPd59dOJ|0_~a z)|aMWqquUy;F9Ei0V4*@aGd7r#XFSYBOA6N{pSj*o6Dh@$w@f>^?dF1xaSr*&&Kbr zZ@MvkbsSN4-&%ClV!3Ww`AS*FohatxfA)n3@Y@((){8Mr%QPi!vWbDcXh$#qbzEcM ziu5VPJ;(MQ(KEDstP@>xpfB9I`O?fvk}}L>nDQmUWPK{3k*$is^-Yy8Ee&30GJTTeuH7vZn#<$_ap& z9VWzhUqG_ABLP>93 zT_2RJQki{Yt7l|i+yUwr*uwV`fgs%_t*38#Ppqm*^$Z^(+XmWeaz`~2xE1J~Eq#zQ zuF|M;?HUInz7gZo>l$%Y?*Zt}5zOS>fw?i;hgn~_W>ct@d=W{7B^M!Is(pA+u~l=> zet96$!P&swXK)?z*B^jpu57W)Z1XHgeY8joMq$mMFhQ^#O}zNrz!=D|@qqSIFrxSi z3F%Zs_cZ)54zONVHi1R2d~CJ#F8%YqFj`-2tQ;o$eREcimrD21O7a(8lvI)I_A( zJTQ-g=Nsq%Nj+(=X*UTJSk(~mHhuo$We`bA?8?+90k)?m9jaZd#ZDQ+7`=vt{mD5P z$r=xL@c*(-QB-DMR zw`K)+yh zj3mbCMLgZB5SVAH<8kdd->pATv*rjZA2kS?Va@nP6{0>!JBeAo{E2?Q!56!&?k#8~ zrepQ)w&=_IAi1v=Qm%%E39yIQ`P4dScEmNyNhS6bMzkDRob3X|mPth2uXWiCcdOoA zYA7=NOu+U62hwP1?m*?8H zfWjglyn5$V$mUa9$3P}ktNeQWq}Q?Q$yp^+(FEAGUkgQxTvH#XbyL@FuPC_ODG5No z2X(thq9!O0-O4($H{?9d>%{13%C!!n^lfp!cI`+n$l=r$9ECmqs&#TU#7e$y1sC>( z2Q6NMqM5mr3fIYtW4E@)$|uHt!|pkzp(dXDbgiLM>qXKal66gKH_XslgW{^qbB(G} zF1b16CcE(t>F>0SukplvuBlXj=~<@6g`6M{j(NVpXj{i#yzfqlOYK;Sy0lLfNY{{W zzoKSTu=zZ*(>yI_bL*7mbV6{BZ{KUNs-+rX5E+;brX)~~lxf_M=U6o4MZ^kWYp~d- zvUIiR-5{@+^ITxc;A)d1b}V7O1j?9(cGI%zD=QLc&+vf&T&t`WCVN4uZcKXJf+wFB zc`+$mBS<#A?)C|Ifmg}a+a8B4CXZ(-imp?91Mv z(dp+V)U9C=A4+%-^98du6PeYvy+dBgQq0)Iq`Kss#H)qIxsE{qAyB?$DitJja&&4U znp;wkJ4e2a68WR;AYEr*RmjHZkdYMZ{9ha5y4U{jsw`~k%G{Z8SA?2PGtP}d~ zI-Uj5+;w+Nn|F5ncAk~Q0kiU=d5}?jXfxb@$xc}8NZqzk2FOr)X8GfrEDTRE&%XA| z|16rAee5v8p}DU;9Vx`MCk@xS#=-Q=;8lq`Ai5c;Ua9k_?WTsCMUF$A7B;eLfmwX?U(E zxb;So=2GW8+VE$n5o1A%(IDg6koS%$%I9%~bnJoIM)ZK3ln{QRu0W!RCnj)St+p;d zp=1R%T0SCTyf)vpk99xr{L5>JMwi2NS4vzK@bY2$4y(cTcUn$5ahF)P?Hc>r{xFI=M-o$QodrXO9Z)8coR3&7t)NDN# z_pmpXnx9AluaGH+h+aVYmW*~)IJXq9^5P>8&Kax6Dd%QRq$d-$L#Y);+bzR^>(F3W2Boa>p7r8CkrH zs+yI3TwF@*o1|c~>O-SkO|G5Nw8)8FJo)(Umf5p8!T9n%LVz-Mvbt#bmdn8W=e{d1 zPBw2haE%z+6{tf=U#g!uov1_?WSMQTJy{jmB$jce*RgtMrckr{j$++W%%>Y=nJ0A$ zQ~WO4M|T;6wk8b(8dW+QT3?Bf7n&5t0@pdl!tD#4Ue5TeX&9ZUs-XrL+9)a!TPgGB zW5wfmXO$(K!0V)S$&EKIjy|);JbqLzBmU_r!2n}^)qIQ6&bveTUP|$$Ty|URScC1` zi#W(97PRslK3LYQbzV_5M=PZ@S)ER-nmcpD-GGCV)0vAXTj^3QI!EYdy9-#^_igFM z4V<}02=*X6%DJL5C`-WUdy9w^NR2j`zscUdw`{kIDQ`cziO*outXkEMnTx%N@or%`5UUY;#87;kZW=6IW`mj59B{=gGGM1(wjJXkhz(X`VYQ@~?Gt0^e- zjy`7dMa_TV>EsRNIoCJ-wA3L3$5&zC@l`PyMtwiMQbF0(VL}( zv3@uDIxu>RX6KZ_r+$|ifon{2s!ugh#Z5f7JCfEaRs$6o0R%t%L6PmGJ>HPUn7Y!V z={*w`F4rG`-_jN7aoqkqUF0a+d{zc&`6~6^&7vRu2`alKagB9u(je~XMYZekT@quVE_V*u-Z0^$=12+O zAi4L#*x<3Zc9_u0z3IvZZzf7Nb*aJEdG)acJzGy_qSat>dCKX5mbipKXFoH%Ej!e`C|yxmsy} zCd`GM@?TSpaG6#zt+4v0SP)&iGWc|uUY+kt2pkU@CoW*=10Q$Oa;}Py>jS^PCh$!h zqVZnfn`+dKDQvt!En>!9ZRX0A(PuP-O9H&mG~DM5Rk7kpws-eS2M2n&<^;aRxmnMX z1(l-0=K1;Vw{##ykD=t+4`}}I3@!zwWHY(Y|L{0llzYn3&8q*B#lFUBOwHhf6 z%B4WGfPGImNkt87$|z({i(=)CpmB)=n|X7^I`Br!8V5~ZTQ**JZA0%&8rFR0tUr-9 z$9ihTfUS7yP~nM{I^E=9=4*3QyN0m<60x#mSlD2vi6S-6PuwfFYB*N0R^_PT=4yu7 zyWFhT^g;!#bt`V=mFB50jA860zQ>Q{s~qeqgz~&1SbHmmg|E%wt?gv8;%?*HhTg0^ zaT0nPb*D%eYZLnVv;@yk^(Uc|(hB3MLPkZx^Seh)`$d#|zNB%Z+1n*chy9J_m~Od! z)7Pg9ZvAfO^=ij7zc&H@?|vVP)Gg0|Ul*SXdP4cNFM2OE-m>C(rNb4Sy^CdE*UnQ6 zeWrZ*Qn-|f0iNDrkvNk}pJ$pxThz+-&6DmC>b$f9rfD}ZwWn6Tvid}k3aNTU=4t$b z+hVz-cMRS9#yTg5hH0F(##v0Z4O{d9g3Pe!8~xjJ%lqWL+{&-1HxDfqZDEvhc0a`5 z=!%pV3Bu~-JSCLr9qs-qZy}rE|0w#?w*T?uvz!x&>T+{1wNsa7p{iR|I82m^eUqUu z1=8`SoArySBe~*1nHT6Hw|2Q`t?Y{fRx4&|5 zmYqEd1G9H=ZKeKuiXC&4ZSMX5-D+So(W%1&$0%3aZg{*-IBE0I;%@~`p90|1)RD{Np;lip4o~n`b^PgQJ&(> zwe0-e+@Q6c^~|wnA3$2Nig8r>;M`p-c>tZTIuGfKs+}jX!2@pIE#j>0XzmImbE*~u z4*N2ai2-B{8Np8lG2J9%VJf~wE;F$inpEP%&Z{TCyGR%p$VP9pJ-+Xz6S7gZ@ck3X z?~4TpDofsIX_oe5vQqxmmnY8d45S-4^0`m=swWhJW~sPmP`=?=A|CSJ>p*WKI+yjG z2@87oi4-LHU?GBW%juS0(IjO1#E)*K{23GWQc&FzZL>2dtd@`kg3Mt=jQP8{kNbcE z>Gy}0;YvYQ+qOH=#A4$Tb zCA0F$UE@aot1P27++-yGJ)Gm=&MVkt_Gt*DiXzm~QCIU_LB)#Kvt|m3T-R}lzfbrw zC_0*{b)aVvMxr(svAgh%8P>fFC_P#V<3^p}sFG)Pm-Tw585rQSkBOfdy6{Qq`rmgt6^?P)cx`DGek zD<*q}?qNTJU}~IvHzNN-8A=1HK<1hrH$4CsfB>y@XJf^zwb2}X;&JN_w>-MqzuI}} zbM(SX(8g+I1Z0G@dMnXeOMrY9jI4VMh;6sUG)o^%LFt*CfGoUCR0 zh06{U!v)9(eUmJE0U$)#LNq*4rl>PI{LKm=1S*8F4vw-A7I#~tQRem-sf8W;B~Brp zIto(J(aqmLWgGYIp#NJCwND_Ls@J9Zjm`lvQ1ETY z!1eS-zu~=MyU9JLNi2&gU%2i~zb<8!V5ki9y^%gytX{xu6PpHzN-7imSBaMEN5Sa#04!399tAQ#QZFq0W)ad`E&G8 zW?b(%`pinnJ8&I$x&6nU!&Wl+;Dhy~66l%IZBMVfvWIOwBluW`AK@Opq=67f2p|N; zg?rXGk`}>>reJx?1YD$N#*IG;6$!hjcHLV@^{Xi!zr)1bnxC+Ch5N-#OjnjjViIB5 z>$sD3SL7Lf>9&ug{*L0?y!QWEaBiIX3hYaK3#xhCh?sCWW_wvRND;=*a5XywjOob_ zNiE>y8h3`yW2P3tUHVdVBm(#R!ld_zPd3YP%i5$59i`;&+2(T0FFzOO0eQSRC|@S z=(Tx9TDke``|$iv0n?olT{n}9LatQXxM^}SeCSTSmn>_G4^j!~_U@IS$&yLP&s!Lf znJ#iLs_@ZJM4IV0;cuGU&p4?MWn%~d*?xq-gYL?Pmv6^`W`wPEjtH%&PcB`h4xMz&+CwL z5KL+URuRi6Bv{{LT%gZL5;3wN3j>@=N8kG{Si}{}6ILjTEnm6IAODZn5U^sGR3Jvp zQ^R=mimztY7#Y*`N-Xxlx0G`pyboTJF!p~W`QiEBYlr8~^qZIh3D$=2Ij2;alb|F4 zTV%z&ISF4f-tS%X6(Ez^xWMk87ZB<{m;l(GLJG>fn8@v@aJtqa`MFN@g5b(DMdV+H z1uBLjmS{uvj&G&x$qp>E=WL6=VOO7<87q#Cy12NEoO>BBFJl}VnabKza51)3*xyk3 zBPs4ATZQbn>TSgmMS3eWZwF1OWbgmJNvPBJ;pzY5f%sKaYt@vsiT~P_9=5KJ8oAW) z=wHVShXwbE@~BAv>#+Dy$`NcDzku?;npbF%d6V^Z_5?0=L(-XZtVA#ykw%O*xx6VQx!F7=24gn40_H`0~&vDJtLl;7L(?1!-kEs(n$-LrZ`a8EY4p zN-GQ@4;dEUTPs0EBm|RgAPyGgj{9DV9rmdklBCu%NoxS_K!-rx@qEGYR`Z$oE$b5G zM=5D%$dAI4{i0ba^)d*-g#NN#+wM0Sc;m_9oUb0Pgm#ILad#YHsD|clVoY_|rxFH?l)}_$HDxoQDrfK{t>Kj(lW8^y>#p$ySQlo*OP9`{J0B2-v zTjX^Ew>&z@R?Ars#9t1wenK?qu*2e8Qp;XYy=8dX0YVb@c`3;p&AfTXrA4$$rLl^k zEZAmQ-&9@HdrjHtzZuSlRkW=^6F?MKec$f@Q8;1)dQN7-O-F`p0_s=EoXc-o)CrdL7_N7SdNg!KU%AlNFA zAi?l~E%2%gB6!?(3t6ksl))%anL`E;5We9>P^SPe!y2?`KjUwo=Di%M%LA8!;+ zi3chAQhBlgXlK(vIaCs=IrI=2k>~6~25Z3cxlrZJXyvpEJuD7w7pb*|YWTFNgHTZG zOB3ZF&RvKIDwi@I#+n}ixIxdk6v|}*^$O<>AoW|kLDPjez}t>|EDc1#gOLEpwAdmn zjKXthCqn~-lQU)EGxIjUcDyOtB00+U7IwU3m zz#&6Fynu>L;IGfV+Uv8<;FR-lj)Okr3@nX@Pw#yU0G9BP)0<=A!kGvEQ|<71LO~=R zQYAzX-BS=Ak(8g76p4ocimV?iA1@*+4>2VfJ! z10aTb@`*dFK&LK%Z+)o_nXV#`pp(rxhck12ts193k~Ap4pWUc^fTkg|&{Mgm+JS4r z2@`B?7m5~QN^gI$;)VzE(yl!?Wki7m(KEa@9|KXoVtK?&j2iIARZcMf`pVJ=&C&4A zoRBW!3}B29ULjQV~MAu&TW48dRPzvg8W(X=5vNf_W-9TwWLZLJW6$AlQSNLUg_~D5E zs^1pqldu3RMNmiL0xfqDn+yH*1+YdpgZV~?#DgI3bCu^7tHo;!dYwRe+-?{R6S85p zkq;7bf~nFGhl^dHvY<`q^1`RC5E5-gW|Ph(Dm}SFpA><9W}!S*LUuR zRbWv1Pb+nbhK>kfrU56B1N`8H2Dcb2;-{bjAh=}>FJBwh9sg?3wVh&q0 z{Q9DOy`_CF) z7I3NTAYhFHLToK$|LlYKwsD}kQ7C2MS69#t!GPzrP*z@8?hXX3pR#Hs^_>%fQt80e z@gVc1L3C*NuK&6v0>nj79zlExq?%dojVLdS_N8D!!3^0S0NV#hHB`k=io}22>P3+# zkMnq!ID#ZXFgMwGZ?>rp$Q@R(Z&_!W^q%)ec1ft;*R$CFYTDM>GPEfKch>Rp1+CCm z@~P@41OM38`ls3lcJFgL+ln&TTcgm#OMKymXa4$Y_`I%h$N9*Mf~%ang7%*LgAJDy z-gLS{jaVx!+(5tlQATVw4xi{<_5N$8>|(J8Z|Qo^5Y+y{IPgvnY(1tCcOPN*0&FVW zCqWu-32}W6#8Ys{?n6Zb>~N^+Q>=u20D`o=XftLH)|ijL6N_!GiiwE@z2icKx7cqW zoAv>Wu#5oln;Hd_EO|O z_a_JMmqZB5Fgzwo;Rn@L!Q{jZT-R2Ym!;$Vc|G36qfzU>{d3{b@$q2bsMW!$OmbCK zmF1W`2vy{R8R!??)Iv53z!2A_L;_X3!PZRyY~Jzo?2&Av7eWqbW@ct_BUc!#Aiby8 zXATp$b7ZCrsf`K*BJA1a9V{%hpPpSyE-VxU@Uu;qvk20vfiWmz;x(-VEZM#d^cKRJ z9l(P$L`NCk3bHj#l^(lf>7T+gp~=k$}Yl;;{WFr@*1?%HxGXU zC>;P2Ibhmw!j4^i%NHut1PZlrb6%*Xd;pW_zqobXxXdZ_VTJR=yNM4V8Exuqaub}% zG>C!jmDrBr-{6{k|BeBhQtk&&exw4bo#HO*T(@h6WH9`>^2x}g_!-aOeZP>-UBo_=^oS=fD$?>60spb*3)B{}4FqpCMJlp7V9y*EZ94M6e; zNe-E)sl}sf*}<2$@!o5UsFHP z3@%&Kj!Ke))L#zCTRq1;QmVqm<6%Vi7Wx4!Oz$QrOc{UttRI|*hld%ARFE)ZMEQ_; zfuAUV=G=fDHS6gDh(H^D^hzNGp+Rq0iN$t`85tUk3})BF z?`-?odiD;%zNZjaC9Z{O_T=p-pFY@XLV%9dEfa`twI1~KAjf|fa{t4dvY2BYUMZU&);%D6=H`o#J z)8T**M)_U-SxpG;S~2xMwTd)_J4ryr{@w-rdfU<$BSl3;7Xbb%yWAhPNpth7D~zdX z)_fq|t!9p(rq;hdEY5+9kk(bgj@AIpaT@@GlejoJ5gOzXA4|CP+6Er@A<;9I1%*8K zlBq6?Zz$AnaQr)*(e@FAV*c^(1$R)W%|DLe6x2?p-%uyvvlq@`fn#{|Vd`vQe!$h*`Q`!Ln-&L@Rn)J*b$~#B0);v%jY8q%pj4Mps3TWV zsJk~%sBh`;b3F=0fd5YdjJhfmFKGt~wP!mDWek68mEn5_QK&BPw|AttZ^NaS{`2{N DSo1$6 diff --git a/external/libtommath-0.42.0/poster.out b/external/libtommath-0.42.0/poster.out deleted file mode 100644 index e69de29..0000000 diff --git a/external/libtommath-0.42.0/poster.tex b/external/libtommath-0.42.0/poster.tex deleted file mode 100755 index e7388f4..0000000 --- a/external/libtommath-0.42.0/poster.tex +++ /dev/null @@ -1,35 +0,0 @@ -\documentclass[landscape,11pt]{article} -\usepackage{amsmath, amssymb} -\usepackage{hyperref} -\begin{document} -\hspace*{-3in} -\begin{tabular}{llllll} -$c = a + b$ & {\tt mp\_add(\&a, \&b, \&c)} & $b = 2a$ & {\tt mp\_mul\_2(\&a, \&b)} & \\ -$c = a - b$ & {\tt mp\_sub(\&a, \&b, \&c)} & $b = a/2$ & {\tt mp\_div\_2(\&a, \&b)} & \\ -$c = ab $ & {\tt mp\_mul(\&a, \&b, \&c)} & $c = 2^ba$ & {\tt mp\_mul\_2d(\&a, b, \&c)} \\ -$b = a^2 $ & {\tt mp\_sqr(\&a, \&b)} & $c = a/2^b, d = a \mod 2^b$ & {\tt mp\_div\_2d(\&a, b, \&c, \&d)} \\ -$c = \lfloor a/b \rfloor, d = a \mod b$ & {\tt mp\_div(\&a, \&b, \&c, \&d)} & $c = a \mod 2^b $ & {\tt mp\_mod\_2d(\&a, b, \&c)} \\ - && \\ -$a = b $ & {\tt mp\_set\_int(\&a, b)} & $c = a \vee b$ & {\tt mp\_or(\&a, \&b, \&c)} \\ -$b = a $ & {\tt mp\_copy(\&a, \&b)} & $c = a \wedge b$ & {\tt mp\_and(\&a, \&b, \&c)} \\ - && $c = a \oplus b$ & {\tt mp\_xor(\&a, \&b, \&c)} \\ - & \\ -$b = -a $ & {\tt mp\_neg(\&a, \&b)} & $d = a + b \mod c$ & {\tt mp\_addmod(\&a, \&b, \&c, \&d)} \\ -$b = |a| $ & {\tt mp\_abs(\&a, \&b)} & $d = a - b \mod c$ & {\tt mp\_submod(\&a, \&b, \&c, \&d)} \\ - && $d = ab \mod c$ & {\tt mp\_mulmod(\&a, \&b, \&c, \&d)} \\ -Compare $a$ and $b$ & {\tt mp\_cmp(\&a, \&b)} & $c = a^2 \mod b$ & {\tt mp\_sqrmod(\&a, \&b, \&c)} \\ -Is Zero? & {\tt mp\_iszero(\&a)} & $c = a^{-1} \mod b$ & {\tt mp\_invmod(\&a, \&b, \&c)} \\ -Is Even? & {\tt mp\_iseven(\&a)} & $d = a^b \mod c$ & {\tt mp\_exptmod(\&a, \&b, \&c, \&d)} \\ -Is Odd ? & {\tt mp\_isodd(\&a)} \\ -&\\ -$\vert \vert a \vert \vert$ & {\tt mp\_unsigned\_bin\_size(\&a)} & $res$ = 1 if $a$ prime to $t$ rounds? & {\tt mp\_prime\_is\_prime(\&a, t, \&res)} \\ -$buf \leftarrow a$ & {\tt mp\_to\_unsigned\_bin(\&a, buf)} & Next prime after $a$ to $t$ rounds. & {\tt mp\_prime\_next\_prime(\&a, t, bbs\_style)} \\ -$a \leftarrow buf[0..len-1]$ & {\tt mp\_read\_unsigned\_bin(\&a, buf, len)} \\ -&\\ -$b = \sqrt{a}$ & {\tt mp\_sqrt(\&a, \&b)} & $c = \mbox{gcd}(a, b)$ & {\tt mp\_gcd(\&a, \&b, \&c)} \\ -$c = a^{1/b}$ & {\tt mp\_n\_root(\&a, b, \&c)} & $c = \mbox{lcm}(a, b)$ & {\tt mp\_lcm(\&a, \&b, \&c)} \\ -&\\ -Greater Than & MP\_GT & Equal To & MP\_EQ \\ -Less Than & MP\_LT & Bits per digit & DIGIT\_BIT \\ -\end{tabular} -\end{document} diff --git a/external/libtommath-0.42.0/pre_gen/mpi.c b/external/libtommath-0.42.0/pre_gen/mpi.c deleted file mode 100644 index 7ba9d83..0000000 --- a/external/libtommath-0.42.0/pre_gen/mpi.c +++ /dev/null @@ -1,9524 +0,0 @@ -/* Start: bn_error.c */ -#include -#ifdef BN_ERROR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -static const struct { - int code; - char *msg; -} msgs[] = { - { MP_OKAY, "Successful" }, - { MP_MEM, "Out of heap" }, - { MP_VAL, "Value out of range" } -}; - -/* return a char * string for a given code */ -char *mp_error_to_string(int code) -{ - int x; - - /* scan the lookup table for the given message */ - for (x = 0; x < (int)(sizeof(msgs) / sizeof(msgs[0])); x++) { - if (msgs[x].code == code) { - return msgs[x].msg; - } - } - - /* generic reply for invalid code */ - return "Invalid error code"; -} - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_error.c */ - -/* Start: bn_fast_mp_invmod.c */ -#include -#ifdef BN_FAST_MP_INVMOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* computes the modular inverse via binary extended euclidean algorithm, - * that is c = 1/a mod b - * - * Based on slow invmod except this is optimized for the case where b is - * odd as per HAC Note 14.64 on pp. 610 - */ -int fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c) -{ - mp_int x, y, u, v, B, D; - int res, neg; - - /* 2. [modified] b must be odd */ - if (mp_iseven (b) == 1) { - return MP_VAL; - } - - /* init all our temps */ - if ((res = mp_init_multi(&x, &y, &u, &v, &B, &D, NULL)) != MP_OKAY) { - return res; - } - - /* x == modulus, y == value to invert */ - if ((res = mp_copy (b, &x)) != MP_OKAY) { - goto LBL_ERR; - } - - /* we need y = |a| */ - if ((res = mp_mod (a, b, &y)) != MP_OKAY) { - goto LBL_ERR; - } - - /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */ - if ((res = mp_copy (&x, &u)) != MP_OKAY) { - goto LBL_ERR; - } - if ((res = mp_copy (&y, &v)) != MP_OKAY) { - goto LBL_ERR; - } - mp_set (&D, 1); - -top: - /* 4. while u is even do */ - while (mp_iseven (&u) == 1) { - /* 4.1 u = u/2 */ - if ((res = mp_div_2 (&u, &u)) != MP_OKAY) { - goto LBL_ERR; - } - /* 4.2 if B is odd then */ - if (mp_isodd (&B) == 1) { - if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) { - goto LBL_ERR; - } - } - /* B = B/2 */ - if ((res = mp_div_2 (&B, &B)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* 5. while v is even do */ - while (mp_iseven (&v) == 1) { - /* 5.1 v = v/2 */ - if ((res = mp_div_2 (&v, &v)) != MP_OKAY) { - goto LBL_ERR; - } - /* 5.2 if D is odd then */ - if (mp_isodd (&D) == 1) { - /* D = (D-x)/2 */ - if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) { - goto LBL_ERR; - } - } - /* D = D/2 */ - if ((res = mp_div_2 (&D, &D)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* 6. if u >= v then */ - if (mp_cmp (&u, &v) != MP_LT) { - /* u = u - v, B = B - D */ - if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) { - goto LBL_ERR; - } - - if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) { - goto LBL_ERR; - } - } else { - /* v - v - u, D = D - B */ - if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) { - goto LBL_ERR; - } - - if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* if not zero goto step 4 */ - if (mp_iszero (&u) == 0) { - goto top; - } - - /* now a = C, b = D, gcd == g*v */ - - /* if v != 1 then there is no inverse */ - if (mp_cmp_d (&v, 1) != MP_EQ) { - res = MP_VAL; - goto LBL_ERR; - } - - /* b is now the inverse */ - neg = a->sign; - while (D.sign == MP_NEG) { - if ((res = mp_add (&D, b, &D)) != MP_OKAY) { - goto LBL_ERR; - } - } - mp_exch (&D, c); - c->sign = neg; - res = MP_OKAY; - -LBL_ERR:mp_clear_multi (&x, &y, &u, &v, &B, &D, NULL); - return res; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_fast_mp_invmod.c */ - -/* Start: bn_fast_mp_montgomery_reduce.c */ -#include -#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* computes xR**-1 == x (mod N) via Montgomery Reduction - * - * This is an optimized implementation of montgomery_reduce - * which uses the comba method to quickly calculate the columns of the - * reduction. - * - * Based on Algorithm 14.32 on pp.601 of HAC. -*/ -int fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) -{ - int ix, res, olduse; - mp_word W[MP_WARRAY]; - - /* get old used count */ - olduse = x->used; - - /* grow a as required */ - if (x->alloc < n->used + 1) { - if ((res = mp_grow (x, n->used + 1)) != MP_OKAY) { - return res; - } - } - - /* first we have to get the digits of the input into - * an array of double precision words W[...] - */ - { - register mp_word *_W; - register mp_digit *tmpx; - - /* alias for the W[] array */ - _W = W; - - /* alias for the digits of x*/ - tmpx = x->dp; - - /* copy the digits of a into W[0..a->used-1] */ - for (ix = 0; ix < x->used; ix++) { - *_W++ = *tmpx++; - } - - /* zero the high words of W[a->used..m->used*2] */ - for (; ix < n->used * 2 + 1; ix++) { - *_W++ = 0; - } - } - - /* now we proceed to zero successive digits - * from the least significant upwards - */ - for (ix = 0; ix < n->used; ix++) { - /* mu = ai * m' mod b - * - * We avoid a double precision multiplication (which isn't required) - * by casting the value down to a mp_digit. Note this requires - * that W[ix-1] have the carry cleared (see after the inner loop) - */ - register mp_digit mu; - mu = (mp_digit) (((W[ix] & MP_MASK) * rho) & MP_MASK); - - /* a = a + mu * m * b**i - * - * This is computed in place and on the fly. The multiplication - * by b**i is handled by offseting which columns the results - * are added to. - * - * Note the comba method normally doesn't handle carries in the - * inner loop In this case we fix the carry from the previous - * column since the Montgomery reduction requires digits of the - * result (so far) [see above] to work. This is - * handled by fixing up one carry after the inner loop. The - * carry fixups are done in order so after these loops the - * first m->used words of W[] have the carries fixed - */ - { - register int iy; - register mp_digit *tmpn; - register mp_word *_W; - - /* alias for the digits of the modulus */ - tmpn = n->dp; - - /* Alias for the columns set by an offset of ix */ - _W = W + ix; - - /* inner loop */ - for (iy = 0; iy < n->used; iy++) { - *_W++ += ((mp_word)mu) * ((mp_word)*tmpn++); - } - } - - /* now fix carry for next digit, W[ix+1] */ - W[ix + 1] += W[ix] >> ((mp_word) DIGIT_BIT); - } - - /* now we have to propagate the carries and - * shift the words downward [all those least - * significant digits we zeroed]. - */ - { - register mp_digit *tmpx; - register mp_word *_W, *_W1; - - /* nox fix rest of carries */ - - /* alias for current word */ - _W1 = W + ix; - - /* alias for next word, where the carry goes */ - _W = W + ++ix; - - for (; ix <= n->used * 2 + 1; ix++) { - *_W++ += *_W1++ >> ((mp_word) DIGIT_BIT); - } - - /* copy out, A = A/b**n - * - * The result is A/b**n but instead of converting from an - * array of mp_word to mp_digit than calling mp_rshd - * we just copy them in the right order - */ - - /* alias for destination word */ - tmpx = x->dp; - - /* alias for shifted double precision result */ - _W = W + n->used; - - for (ix = 0; ix < n->used + 1; ix++) { - *tmpx++ = (mp_digit)(*_W++ & ((mp_word) MP_MASK)); - } - - /* zero oldused digits, if the input a was larger than - * m->used+1 we'll have to clear the digits - */ - for (; ix < olduse; ix++) { - *tmpx++ = 0; - } - } - - /* set the max used and clamp */ - x->used = n->used + 1; - mp_clamp (x); - - /* if A >= m then A = A - m */ - if (mp_cmp_mag (x, n) != MP_LT) { - return s_mp_sub (x, n, x); - } - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_fast_mp_montgomery_reduce.c */ - -/* Start: bn_fast_s_mp_mul_digs.c */ -#include -#ifdef BN_FAST_S_MP_MUL_DIGS_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* Fast (comba) multiplier - * - * This is the fast column-array [comba] multiplier. It is - * designed to compute the columns of the product first - * then handle the carries afterwards. This has the effect - * of making the nested loops that compute the columns very - * simple and schedulable on super-scalar processors. - * - * This has been modified to produce a variable number of - * digits of output so if say only a half-product is required - * you don't have to compute the upper half (a feature - * required for fast Barrett reduction). - * - * Based on Algorithm 14.12 on pp.595 of HAC. - * - */ -int fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) -{ - int olduse, res, pa, ix, iz; - mp_digit W[MP_WARRAY]; - register mp_word _W; - - /* grow the destination as required */ - if (c->alloc < digs) { - if ((res = mp_grow (c, digs)) != MP_OKAY) { - return res; - } - } - - /* number of output digits to produce */ - pa = MIN(digs, a->used + b->used); - - /* clear the carry */ - _W = 0; - for (ix = 0; ix < pa; ix++) { - int tx, ty; - int iy; - mp_digit *tmpx, *tmpy; - - /* get offsets into the two bignums */ - ty = MIN(b->used-1, ix); - tx = ix - ty; - - /* setup temp aliases */ - tmpx = a->dp + tx; - tmpy = b->dp + ty; - - /* this is the number of times the loop will iterrate, essentially - while (tx++ < a->used && ty-- >= 0) { ... } - */ - iy = MIN(a->used-tx, ty+1); - - /* execute loop */ - for (iz = 0; iz < iy; ++iz) { - _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--); - - } - - /* store term */ - W[ix] = ((mp_digit)_W) & MP_MASK; - - /* make next carry */ - _W = _W >> ((mp_word)DIGIT_BIT); - } - - /* setup dest */ - olduse = c->used; - c->used = pa; - - { - register mp_digit *tmpc; - tmpc = c->dp; - for (ix = 0; ix < pa+1; ix++) { - /* now extract the previous digit [below the carry] */ - *tmpc++ = W[ix]; - } - - /* clear unused digits [that existed in the old copy of c] */ - for (; ix < olduse; ix++) { - *tmpc++ = 0; - } - } - mp_clamp (c); - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_fast_s_mp_mul_digs.c */ - -/* Start: bn_fast_s_mp_mul_high_digs.c */ -#include -#ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* this is a modified version of fast_s_mul_digs that only produces - * output digits *above* digs. See the comments for fast_s_mul_digs - * to see how it works. - * - * This is used in the Barrett reduction since for one of the multiplications - * only the higher digits were needed. This essentially halves the work. - * - * Based on Algorithm 14.12 on pp.595 of HAC. - */ -int fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs) -{ - int olduse, res, pa, ix, iz; - mp_digit W[MP_WARRAY]; - mp_word _W; - - /* grow the destination as required */ - pa = a->used + b->used; - if (c->alloc < pa) { - if ((res = mp_grow (c, pa)) != MP_OKAY) { - return res; - } - } - - /* number of output digits to produce */ - pa = a->used + b->used; - _W = 0; - for (ix = digs; ix < pa; ix++) { - int tx, ty, iy; - mp_digit *tmpx, *tmpy; - - /* get offsets into the two bignums */ - ty = MIN(b->used-1, ix); - tx = ix - ty; - - /* setup temp aliases */ - tmpx = a->dp + tx; - tmpy = b->dp + ty; - - /* this is the number of times the loop will iterrate, essentially its - while (tx++ < a->used && ty-- >= 0) { ... } - */ - iy = MIN(a->used-tx, ty+1); - - /* execute loop */ - for (iz = 0; iz < iy; iz++) { - _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--); - } - - /* store term */ - W[ix] = ((mp_digit)_W) & MP_MASK; - - /* make next carry */ - _W = _W >> ((mp_word)DIGIT_BIT); - } - - /* setup dest */ - olduse = c->used; - c->used = pa; - - { - register mp_digit *tmpc; - - tmpc = c->dp + digs; - for (ix = digs; ix < pa; ix++) { - /* now extract the previous digit [below the carry] */ - *tmpc++ = W[ix]; - } - - /* clear unused digits [that existed in the old copy of c] */ - for (; ix < olduse; ix++) { - *tmpc++ = 0; - } - } - mp_clamp (c); - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_fast_s_mp_mul_high_digs.c */ - -/* Start: bn_fast_s_mp_sqr.c */ -#include -#ifdef BN_FAST_S_MP_SQR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* the jist of squaring... - * you do like mult except the offset of the tmpx [one that - * starts closer to zero] can't equal the offset of tmpy. - * So basically you set up iy like before then you min it with - * (ty-tx) so that it never happens. You double all those - * you add in the inner loop - -After that loop you do the squares and add them in. -*/ - -int fast_s_mp_sqr (mp_int * a, mp_int * b) -{ - int olduse, res, pa, ix, iz; - mp_digit W[MP_WARRAY], *tmpx; - mp_word W1; - - /* grow the destination as required */ - pa = a->used + a->used; - if (b->alloc < pa) { - if ((res = mp_grow (b, pa)) != MP_OKAY) { - return res; - } - } - - /* number of output digits to produce */ - W1 = 0; - for (ix = 0; ix < pa; ix++) { - int tx, ty, iy; - mp_word _W; - mp_digit *tmpy; - - /* clear counter */ - _W = 0; - - /* get offsets into the two bignums */ - ty = MIN(a->used-1, ix); - tx = ix - ty; - - /* setup temp aliases */ - tmpx = a->dp + tx; - tmpy = a->dp + ty; - - /* this is the number of times the loop will iterrate, essentially - while (tx++ < a->used && ty-- >= 0) { ... } - */ - iy = MIN(a->used-tx, ty+1); - - /* now for squaring tx can never equal ty - * we halve the distance since they approach at a rate of 2x - * and we have to round because odd cases need to be executed - */ - iy = MIN(iy, (ty-tx+1)>>1); - - /* execute loop */ - for (iz = 0; iz < iy; iz++) { - _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--); - } - - /* double the inner product and add carry */ - _W = _W + _W + W1; - - /* even columns have the square term in them */ - if ((ix&1) == 0) { - _W += ((mp_word)a->dp[ix>>1])*((mp_word)a->dp[ix>>1]); - } - - /* store it */ - W[ix] = (mp_digit)(_W & MP_MASK); - - /* make next carry */ - W1 = _W >> ((mp_word)DIGIT_BIT); - } - - /* setup dest */ - olduse = b->used; - b->used = a->used+a->used; - - { - mp_digit *tmpb; - tmpb = b->dp; - for (ix = 0; ix < pa; ix++) { - *tmpb++ = W[ix] & MP_MASK; - } - - /* clear unused digits [that existed in the old copy of c] */ - for (; ix < olduse; ix++) { - *tmpb++ = 0; - } - } - mp_clamp (b); - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_fast_s_mp_sqr.c */ - -/* Start: bn_mp_2expt.c */ -#include -#ifdef BN_MP_2EXPT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* computes a = 2**b - * - * Simple algorithm which zeroes the int, grows it then just sets one bit - * as required. - */ -int -mp_2expt (mp_int * a, int b) -{ - int res; - - /* zero a as per default */ - mp_zero (a); - - /* grow a to accomodate the single bit */ - if ((res = mp_grow (a, b / DIGIT_BIT + 1)) != MP_OKAY) { - return res; - } - - /* set the used count of where the bit will go */ - a->used = b / DIGIT_BIT + 1; - - /* put the single bit in its place */ - a->dp[b / DIGIT_BIT] = ((mp_digit)1) << (b % DIGIT_BIT); - - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_2expt.c */ - -/* Start: bn_mp_abs.c */ -#include -#ifdef BN_MP_ABS_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* b = |a| - * - * Simple function copies the input and fixes the sign to positive - */ -int -mp_abs (mp_int * a, mp_int * b) -{ - int res; - - /* copy a to b */ - if (a != b) { - if ((res = mp_copy (a, b)) != MP_OKAY) { - return res; - } - } - - /* force the sign of b to positive */ - b->sign = MP_ZPOS; - - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_abs.c */ - -/* Start: bn_mp_add.c */ -#include -#ifdef BN_MP_ADD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* high level addition (handles signs) */ -int mp_add (mp_int * a, mp_int * b, mp_int * c) -{ - int sa, sb, res; - - /* get sign of both inputs */ - sa = a->sign; - sb = b->sign; - - /* handle two cases, not four */ - if (sa == sb) { - /* both positive or both negative */ - /* add their magnitudes, copy the sign */ - c->sign = sa; - res = s_mp_add (a, b, c); - } else { - /* one positive, the other negative */ - /* subtract the one with the greater magnitude from */ - /* the one of the lesser magnitude. The result gets */ - /* the sign of the one with the greater magnitude. */ - if (mp_cmp_mag (a, b) == MP_LT) { - c->sign = sb; - res = s_mp_sub (b, a, c); - } else { - c->sign = sa; - res = s_mp_sub (a, b, c); - } - } - return res; -} - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_add.c */ - -/* Start: bn_mp_add_d.c */ -#include -#ifdef BN_MP_ADD_D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* single digit addition */ -int -mp_add_d (mp_int * a, mp_digit b, mp_int * c) -{ - int res, ix, oldused; - mp_digit *tmpa, *tmpc, mu; - - /* grow c as required */ - if (c->alloc < a->used + 1) { - if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) { - return res; - } - } - - /* if a is negative and |a| >= b, call c = |a| - b */ - if (a->sign == MP_NEG && (a->used > 1 || a->dp[0] >= b)) { - /* temporarily fix sign of a */ - a->sign = MP_ZPOS; - - /* c = |a| - b */ - res = mp_sub_d(a, b, c); - - /* fix sign */ - a->sign = c->sign = MP_NEG; - - /* clamp */ - mp_clamp(c); - - return res; - } - - /* old number of used digits in c */ - oldused = c->used; - - /* sign always positive */ - c->sign = MP_ZPOS; - - /* source alias */ - tmpa = a->dp; - - /* destination alias */ - tmpc = c->dp; - - /* if a is positive */ - if (a->sign == MP_ZPOS) { - /* add digit, after this we're propagating - * the carry. - */ - *tmpc = *tmpa++ + b; - mu = *tmpc >> DIGIT_BIT; - *tmpc++ &= MP_MASK; - - /* now handle rest of the digits */ - for (ix = 1; ix < a->used; ix++) { - *tmpc = *tmpa++ + mu; - mu = *tmpc >> DIGIT_BIT; - *tmpc++ &= MP_MASK; - } - /* set final carry */ - ix++; - *tmpc++ = mu; - - /* setup size */ - c->used = a->used + 1; - } else { - /* a was negative and |a| < b */ - c->used = 1; - - /* the result is a single digit */ - if (a->used == 1) { - *tmpc++ = b - a->dp[0]; - } else { - *tmpc++ = b; - } - - /* setup count so the clearing of oldused - * can fall through correctly - */ - ix = 1; - } - - /* now zero to oldused */ - while (ix++ < oldused) { - *tmpc++ = 0; - } - mp_clamp(c); - - return MP_OKAY; -} - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_add_d.c */ - -/* Start: bn_mp_addmod.c */ -#include -#ifdef BN_MP_ADDMOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* d = a + b (mod c) */ -int -mp_addmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) -{ - int res; - mp_int t; - - if ((res = mp_init (&t)) != MP_OKAY) { - return res; - } - - if ((res = mp_add (a, b, &t)) != MP_OKAY) { - mp_clear (&t); - return res; - } - res = mp_mod (&t, c, d); - mp_clear (&t); - return res; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_addmod.c */ - -/* Start: bn_mp_and.c */ -#include -#ifdef BN_MP_AND_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* AND two ints together */ -int -mp_and (mp_int * a, mp_int * b, mp_int * c) -{ - int res, ix, px; - mp_int t, *x; - - if (a->used > b->used) { - if ((res = mp_init_copy (&t, a)) != MP_OKAY) { - return res; - } - px = b->used; - x = b; - } else { - if ((res = mp_init_copy (&t, b)) != MP_OKAY) { - return res; - } - px = a->used; - x = a; - } - - for (ix = 0; ix < px; ix++) { - t.dp[ix] &= x->dp[ix]; - } - - /* zero digits above the last from the smallest mp_int */ - for (; ix < t.used; ix++) { - t.dp[ix] = 0; - } - - mp_clamp (&t); - mp_exch (c, &t); - mp_clear (&t); - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_and.c */ - -/* Start: bn_mp_clamp.c */ -#include -#ifdef BN_MP_CLAMP_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* trim unused digits - * - * This is used to ensure that leading zero digits are - * trimed and the leading "used" digit will be non-zero - * Typically very fast. Also fixes the sign if there - * are no more leading digits - */ -void -mp_clamp (mp_int * a) -{ - /* decrease used while the most significant digit is - * zero. - */ - while (a->used > 0 && a->dp[a->used - 1] == 0) { - --(a->used); - } - - /* reset the sign flag if used == 0 */ - if (a->used == 0) { - a->sign = MP_ZPOS; - } -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_clamp.c */ - -/* Start: bn_mp_clear.c */ -#include -#ifdef BN_MP_CLEAR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* clear one (frees) */ -void -mp_clear (mp_int * a) -{ - int i; - - /* only do anything if a hasn't been freed previously */ - if (a->dp != NULL) { - /* first zero the digits */ - for (i = 0; i < a->used; i++) { - a->dp[i] = 0; - } - - /* free ram */ - XFREE(a->dp); - - /* reset members to make debugging easier */ - a->dp = NULL; - a->alloc = a->used = 0; - a->sign = MP_ZPOS; - } -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_clear.c */ - -/* Start: bn_mp_clear_multi.c */ -#include -#ifdef BN_MP_CLEAR_MULTI_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include - -void mp_clear_multi(mp_int *mp, ...) -{ - mp_int* next_mp = mp; - va_list args; - va_start(args, mp); - while (next_mp != NULL) { - mp_clear(next_mp); - next_mp = va_arg(args, mp_int*); - } - va_end(args); -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_clear_multi.c */ - -/* Start: bn_mp_cmp.c */ -#include -#ifdef BN_MP_CMP_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* compare two ints (signed)*/ -int -mp_cmp (mp_int * a, mp_int * b) -{ - /* compare based on sign */ - if (a->sign != b->sign) { - if (a->sign == MP_NEG) { - return MP_LT; - } else { - return MP_GT; - } - } - - /* compare digits */ - if (a->sign == MP_NEG) { - /* if negative compare opposite direction */ - return mp_cmp_mag(b, a); - } else { - return mp_cmp_mag(a, b); - } -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_cmp.c */ - -/* Start: bn_mp_cmp_d.c */ -#include -#ifdef BN_MP_CMP_D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* compare a digit */ -int mp_cmp_d(mp_int * a, mp_digit b) -{ - /* compare based on sign */ - if (a->sign == MP_NEG) { - return MP_LT; - } - - /* compare based on magnitude */ - if (a->used > 1) { - return MP_GT; - } - - /* compare the only digit of a to b */ - if (a->dp[0] > b) { - return MP_GT; - } else if (a->dp[0] < b) { - return MP_LT; - } else { - return MP_EQ; - } -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_cmp_d.c */ - -/* Start: bn_mp_cmp_mag.c */ -#include -#ifdef BN_MP_CMP_MAG_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* compare maginitude of two ints (unsigned) */ -int mp_cmp_mag (mp_int * a, mp_int * b) -{ - int n; - mp_digit *tmpa, *tmpb; - - /* compare based on # of non-zero digits */ - if (a->used > b->used) { - return MP_GT; - } - - if (a->used < b->used) { - return MP_LT; - } - - /* alias for a */ - tmpa = a->dp + (a->used - 1); - - /* alias for b */ - tmpb = b->dp + (a->used - 1); - - /* compare based on digits */ - for (n = 0; n < a->used; ++n, --tmpa, --tmpb) { - if (*tmpa > *tmpb) { - return MP_GT; - } - - if (*tmpa < *tmpb) { - return MP_LT; - } - } - return MP_EQ; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_cmp_mag.c */ - -/* Start: bn_mp_cnt_lsb.c */ -#include -#ifdef BN_MP_CNT_LSB_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -static const int lnz[16] = { - 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 -}; - -/* Counts the number of lsbs which are zero before the first zero bit */ -int mp_cnt_lsb(mp_int *a) -{ - int x; - mp_digit q, qq; - - /* easy out */ - if (mp_iszero(a) == 1) { - return 0; - } - - /* scan lower digits until non-zero */ - for (x = 0; x < a->used && a->dp[x] == 0; x++); - q = a->dp[x]; - x *= DIGIT_BIT; - - /* now scan this digit until a 1 is found */ - if ((q & 1) == 0) { - do { - qq = q & 15; - x += lnz[qq]; - q >>= 4; - } while (qq == 0); - } - return x; -} - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_cnt_lsb.c */ - -/* Start: bn_mp_copy.c */ -#include -#ifdef BN_MP_COPY_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* copy, b = a */ -int -mp_copy (mp_int * a, mp_int * b) -{ - int res, n; - - /* if dst == src do nothing */ - if (a == b) { - return MP_OKAY; - } - - /* grow dest */ - if (b->alloc < a->used) { - if ((res = mp_grow (b, a->used)) != MP_OKAY) { - return res; - } - } - - /* zero b and copy the parameters over */ - { - register mp_digit *tmpa, *tmpb; - - /* pointer aliases */ - - /* source */ - tmpa = a->dp; - - /* destination */ - tmpb = b->dp; - - /* copy all the digits */ - for (n = 0; n < a->used; n++) { - *tmpb++ = *tmpa++; - } - - /* clear high digits */ - for (; n < b->used; n++) { - *tmpb++ = 0; - } - } - - /* copy used count and sign */ - b->used = a->used; - b->sign = a->sign; - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_copy.c */ - -/* Start: bn_mp_count_bits.c */ -#include -#ifdef BN_MP_COUNT_BITS_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* returns the number of bits in an int */ -int -mp_count_bits (mp_int * a) -{ - int r; - mp_digit q; - - /* shortcut */ - if (a->used == 0) { - return 0; - } - - /* get number of digits and add that */ - r = (a->used - 1) * DIGIT_BIT; - - /* take the last digit and count the bits in it */ - q = a->dp[a->used - 1]; - while (q > ((mp_digit) 0)) { - ++r; - q >>= ((mp_digit) 1); - } - return r; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_count_bits.c */ - -/* Start: bn_mp_div.c */ -#include -#ifdef BN_MP_DIV_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -#ifdef BN_MP_DIV_SMALL - -/* slower bit-bang division... also smaller */ -int mp_div(mp_int * a, mp_int * b, mp_int * c, mp_int * d) -{ - mp_int ta, tb, tq, q; - int res, n, n2; - - /* is divisor zero ? */ - if (mp_iszero (b) == 1) { - return MP_VAL; - } - - /* if a < b then q=0, r = a */ - if (mp_cmp_mag (a, b) == MP_LT) { - if (d != NULL) { - res = mp_copy (a, d); - } else { - res = MP_OKAY; - } - if (c != NULL) { - mp_zero (c); - } - return res; - } - - /* init our temps */ - if ((res = mp_init_multi(&ta, &tb, &tq, &q, NULL) != MP_OKAY)) { - return res; - } - - - mp_set(&tq, 1); - n = mp_count_bits(a) - mp_count_bits(b); - if (((res = mp_abs(a, &ta)) != MP_OKAY) || - ((res = mp_abs(b, &tb)) != MP_OKAY) || - ((res = mp_mul_2d(&tb, n, &tb)) != MP_OKAY) || - ((res = mp_mul_2d(&tq, n, &tq)) != MP_OKAY)) { - goto LBL_ERR; - } - - while (n-- >= 0) { - if (mp_cmp(&tb, &ta) != MP_GT) { - if (((res = mp_sub(&ta, &tb, &ta)) != MP_OKAY) || - ((res = mp_add(&q, &tq, &q)) != MP_OKAY)) { - goto LBL_ERR; - } - } - if (((res = mp_div_2d(&tb, 1, &tb, NULL)) != MP_OKAY) || - ((res = mp_div_2d(&tq, 1, &tq, NULL)) != MP_OKAY)) { - goto LBL_ERR; - } - } - - /* now q == quotient and ta == remainder */ - n = a->sign; - n2 = (a->sign == b->sign ? MP_ZPOS : MP_NEG); - if (c != NULL) { - mp_exch(c, &q); - c->sign = (mp_iszero(c) == MP_YES) ? MP_ZPOS : n2; - } - if (d != NULL) { - mp_exch(d, &ta); - d->sign = (mp_iszero(d) == MP_YES) ? MP_ZPOS : n; - } -LBL_ERR: - mp_clear_multi(&ta, &tb, &tq, &q, NULL); - return res; -} - -#else - -/* integer signed division. - * c*b + d == a [e.g. a/b, c=quotient, d=remainder] - * HAC pp.598 Algorithm 14.20 - * - * Note that the description in HAC is horribly - * incomplete. For example, it doesn't consider - * the case where digits are removed from 'x' in - * the inner loop. It also doesn't consider the - * case that y has fewer than three digits, etc.. - * - * The overall algorithm is as described as - * 14.20 from HAC but fixed to treat these cases. -*/ -int mp_div (mp_int * a, mp_int * b, mp_int * c, mp_int * d) -{ - mp_int q, x, y, t1, t2; - int res, n, t, i, norm, neg; - - /* is divisor zero ? */ - if (mp_iszero (b) == 1) { - return MP_VAL; - } - - /* if a < b then q=0, r = a */ - if (mp_cmp_mag (a, b) == MP_LT) { - if (d != NULL) { - res = mp_copy (a, d); - } else { - res = MP_OKAY; - } - if (c != NULL) { - mp_zero (c); - } - return res; - } - - if ((res = mp_init_size (&q, a->used + 2)) != MP_OKAY) { - return res; - } - q.used = a->used + 2; - - if ((res = mp_init (&t1)) != MP_OKAY) { - goto LBL_Q; - } - - if ((res = mp_init (&t2)) != MP_OKAY) { - goto LBL_T1; - } - - if ((res = mp_init_copy (&x, a)) != MP_OKAY) { - goto LBL_T2; - } - - if ((res = mp_init_copy (&y, b)) != MP_OKAY) { - goto LBL_X; - } - - /* fix the sign */ - neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; - x.sign = y.sign = MP_ZPOS; - - /* normalize both x and y, ensure that y >= b/2, [b == 2**DIGIT_BIT] */ - norm = mp_count_bits(&y) % DIGIT_BIT; - if (norm < (int)(DIGIT_BIT-1)) { - norm = (DIGIT_BIT-1) - norm; - if ((res = mp_mul_2d (&x, norm, &x)) != MP_OKAY) { - goto LBL_Y; - } - if ((res = mp_mul_2d (&y, norm, &y)) != MP_OKAY) { - goto LBL_Y; - } - } else { - norm = 0; - } - - /* note hac does 0 based, so if used==5 then its 0,1,2,3,4, e.g. use 4 */ - n = x.used - 1; - t = y.used - 1; - - /* while (x >= y*b**n-t) do { q[n-t] += 1; x -= y*b**{n-t} } */ - if ((res = mp_lshd (&y, n - t)) != MP_OKAY) { /* y = y*b**{n-t} */ - goto LBL_Y; - } - - while (mp_cmp (&x, &y) != MP_LT) { - ++(q.dp[n - t]); - if ((res = mp_sub (&x, &y, &x)) != MP_OKAY) { - goto LBL_Y; - } - } - - /* reset y by shifting it back down */ - mp_rshd (&y, n - t); - - /* step 3. for i from n down to (t + 1) */ - for (i = n; i >= (t + 1); i--) { - if (i > x.used) { - continue; - } - - /* step 3.1 if xi == yt then set q{i-t-1} to b-1, - * otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */ - if (x.dp[i] == y.dp[t]) { - q.dp[i - t - 1] = ((((mp_digit)1) << DIGIT_BIT) - 1); - } else { - mp_word tmp; - tmp = ((mp_word) x.dp[i]) << ((mp_word) DIGIT_BIT); - tmp |= ((mp_word) x.dp[i - 1]); - tmp /= ((mp_word) y.dp[t]); - if (tmp > (mp_word) MP_MASK) - tmp = MP_MASK; - q.dp[i - t - 1] = (mp_digit) (tmp & (mp_word) (MP_MASK)); - } - - /* while (q{i-t-1} * (yt * b + y{t-1})) > - xi * b**2 + xi-1 * b + xi-2 - - do q{i-t-1} -= 1; - */ - q.dp[i - t - 1] = (q.dp[i - t - 1] + 1) & MP_MASK; - do { - q.dp[i - t - 1] = (q.dp[i - t - 1] - 1) & MP_MASK; - - /* find left hand */ - mp_zero (&t1); - t1.dp[0] = (t - 1 < 0) ? 0 : y.dp[t - 1]; - t1.dp[1] = y.dp[t]; - t1.used = 2; - if ((res = mp_mul_d (&t1, q.dp[i - t - 1], &t1)) != MP_OKAY) { - goto LBL_Y; - } - - /* find right hand */ - t2.dp[0] = (i - 2 < 0) ? 0 : x.dp[i - 2]; - t2.dp[1] = (i - 1 < 0) ? 0 : x.dp[i - 1]; - t2.dp[2] = x.dp[i]; - t2.used = 3; - } while (mp_cmp_mag(&t1, &t2) == MP_GT); - - /* step 3.3 x = x - q{i-t-1} * y * b**{i-t-1} */ - if ((res = mp_mul_d (&y, q.dp[i - t - 1], &t1)) != MP_OKAY) { - goto LBL_Y; - } - - if ((res = mp_lshd (&t1, i - t - 1)) != MP_OKAY) { - goto LBL_Y; - } - - if ((res = mp_sub (&x, &t1, &x)) != MP_OKAY) { - goto LBL_Y; - } - - /* if x < 0 then { x = x + y*b**{i-t-1}; q{i-t-1} -= 1; } */ - if (x.sign == MP_NEG) { - if ((res = mp_copy (&y, &t1)) != MP_OKAY) { - goto LBL_Y; - } - if ((res = mp_lshd (&t1, i - t - 1)) != MP_OKAY) { - goto LBL_Y; - } - if ((res = mp_add (&x, &t1, &x)) != MP_OKAY) { - goto LBL_Y; - } - - q.dp[i - t - 1] = (q.dp[i - t - 1] - 1UL) & MP_MASK; - } - } - - /* now q is the quotient and x is the remainder - * [which we have to normalize] - */ - - /* get sign before writing to c */ - x.sign = x.used == 0 ? MP_ZPOS : a->sign; - - if (c != NULL) { - mp_clamp (&q); - mp_exch (&q, c); - c->sign = neg; - } - - if (d != NULL) { - mp_div_2d (&x, norm, &x, NULL); - mp_exch (&x, d); - } - - res = MP_OKAY; - -LBL_Y:mp_clear (&y); -LBL_X:mp_clear (&x); -LBL_T2:mp_clear (&t2); -LBL_T1:mp_clear (&t1); -LBL_Q:mp_clear (&q); - return res; -} - -#endif - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_div.c */ - -/* Start: bn_mp_div_2.c */ -#include -#ifdef BN_MP_DIV_2_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* b = a/2 */ -int mp_div_2(mp_int * a, mp_int * b) -{ - int x, res, oldused; - - /* copy */ - if (b->alloc < a->used) { - if ((res = mp_grow (b, a->used)) != MP_OKAY) { - return res; - } - } - - oldused = b->used; - b->used = a->used; - { - register mp_digit r, rr, *tmpa, *tmpb; - - /* source alias */ - tmpa = a->dp + b->used - 1; - - /* dest alias */ - tmpb = b->dp + b->used - 1; - - /* carry */ - r = 0; - for (x = b->used - 1; x >= 0; x--) { - /* get the carry for the next iteration */ - rr = *tmpa & 1; - - /* shift the current digit, add in carry and store */ - *tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1)); - - /* forward carry to next iteration */ - r = rr; - } - - /* zero excess digits */ - tmpb = b->dp + b->used; - for (x = b->used; x < oldused; x++) { - *tmpb++ = 0; - } - } - b->sign = a->sign; - mp_clamp (b); - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_div_2.c */ - -/* Start: bn_mp_div_2d.c */ -#include -#ifdef BN_MP_DIV_2D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* shift right by a certain bit count (store quotient in c, optional remainder in d) */ -int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d) -{ - mp_digit D, r, rr; - int x, res; - mp_int t; - - - /* if the shift count is <= 0 then we do no work */ - if (b <= 0) { - res = mp_copy (a, c); - if (d != NULL) { - mp_zero (d); - } - return res; - } - - if ((res = mp_init (&t)) != MP_OKAY) { - return res; - } - - /* get the remainder */ - if (d != NULL) { - if ((res = mp_mod_2d (a, b, &t)) != MP_OKAY) { - mp_clear (&t); - return res; - } - } - - /* copy */ - if ((res = mp_copy (a, c)) != MP_OKAY) { - mp_clear (&t); - return res; - } - - /* shift by as many digits in the bit count */ - if (b >= (int)DIGIT_BIT) { - mp_rshd (c, b / DIGIT_BIT); - } - - /* shift any bit count < DIGIT_BIT */ - D = (mp_digit) (b % DIGIT_BIT); - if (D != 0) { - register mp_digit *tmpc, mask, shift; - - /* mask */ - mask = (((mp_digit)1) << D) - 1; - - /* shift for lsb */ - shift = DIGIT_BIT - D; - - /* alias */ - tmpc = c->dp + (c->used - 1); - - /* carry */ - r = 0; - for (x = c->used - 1; x >= 0; x--) { - /* get the lower bits of this word in a temp */ - rr = *tmpc & mask; - - /* shift the current word and mix in the carry bits from the previous word */ - *tmpc = (*tmpc >> D) | (r << shift); - --tmpc; - - /* set the carry to the carry bits of the current word found above */ - r = rr; - } - } - mp_clamp (c); - if (d != NULL) { - mp_exch (&t, d); - } - mp_clear (&t); - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_div_2d.c */ - -/* Start: bn_mp_div_3.c */ -#include -#ifdef BN_MP_DIV_3_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* divide by three (based on routine from MPI and the GMP manual) */ -int -mp_div_3 (mp_int * a, mp_int *c, mp_digit * d) -{ - mp_int q; - mp_word w, t; - mp_digit b; - int res, ix; - - /* b = 2**DIGIT_BIT / 3 */ - b = (((mp_word)1) << ((mp_word)DIGIT_BIT)) / ((mp_word)3); - - if ((res = mp_init_size(&q, a->used)) != MP_OKAY) { - return res; - } - - q.used = a->used; - q.sign = a->sign; - w = 0; - for (ix = a->used - 1; ix >= 0; ix--) { - w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]); - - if (w >= 3) { - /* multiply w by [1/3] */ - t = (w * ((mp_word)b)) >> ((mp_word)DIGIT_BIT); - - /* now subtract 3 * [w/3] from w, to get the remainder */ - w -= t+t+t; - - /* fixup the remainder as required since - * the optimization is not exact. - */ - while (w >= 3) { - t += 1; - w -= 3; - } - } else { - t = 0; - } - q.dp[ix] = (mp_digit)t; - } - - /* [optional] store the remainder */ - if (d != NULL) { - *d = (mp_digit)w; - } - - /* [optional] store the quotient */ - if (c != NULL) { - mp_clamp(&q); - mp_exch(&q, c); - } - mp_clear(&q); - - return res; -} - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_div_3.c */ - -/* Start: bn_mp_div_d.c */ -#include -#ifdef BN_MP_DIV_D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -static int s_is_power_of_two(mp_digit b, int *p) -{ - int x; - - /* fast return if no power of two */ - if ((b==0) || (b & (b-1))) { - return 0; - } - - for (x = 0; x < DIGIT_BIT; x++) { - if (b == (((mp_digit)1)<dp[0] & ((((mp_digit)1)<used)) != MP_OKAY) { - return res; - } - - q.used = a->used; - q.sign = a->sign; - w = 0; - for (ix = a->used - 1; ix >= 0; ix--) { - w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]); - - if (w >= b) { - t = (mp_digit)(w / b); - w -= ((mp_word)t) * ((mp_word)b); - } else { - t = 0; - } - q.dp[ix] = (mp_digit)t; - } - - if (d != NULL) { - *d = (mp_digit)w; - } - - if (c != NULL) { - mp_clamp(&q); - mp_exch(&q, c); - } - mp_clear(&q); - - return res; -} - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_div_d.c */ - -/* Start: bn_mp_dr_is_modulus.c */ -#include -#ifdef BN_MP_DR_IS_MODULUS_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* determines if a number is a valid DR modulus */ -int mp_dr_is_modulus(mp_int *a) -{ - int ix; - - /* must be at least two digits */ - if (a->used < 2) { - return 0; - } - - /* must be of the form b**k - a [a <= b] so all - * but the first digit must be equal to -1 (mod b). - */ - for (ix = 1; ix < a->used; ix++) { - if (a->dp[ix] != MP_MASK) { - return 0; - } - } - return 1; -} - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_dr_is_modulus.c */ - -/* Start: bn_mp_dr_reduce.c */ -#include -#ifdef BN_MP_DR_REDUCE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* reduce "x" in place modulo "n" using the Diminished Radix algorithm. - * - * Based on algorithm from the paper - * - * "Generating Efficient Primes for Discrete Log Cryptosystems" - * Chae Hoon Lim, Pil Joong Lee, - * POSTECH Information Research Laboratories - * - * The modulus must be of a special format [see manual] - * - * Has been modified to use algorithm 7.10 from the LTM book instead - * - * Input x must be in the range 0 <= x <= (n-1)**2 - */ -int -mp_dr_reduce (mp_int * x, mp_int * n, mp_digit k) -{ - int err, i, m; - mp_word r; - mp_digit mu, *tmpx1, *tmpx2; - - /* m = digits in modulus */ - m = n->used; - - /* ensure that "x" has at least 2m digits */ - if (x->alloc < m + m) { - if ((err = mp_grow (x, m + m)) != MP_OKAY) { - return err; - } - } - -/* top of loop, this is where the code resumes if - * another reduction pass is required. - */ -top: - /* aliases for digits */ - /* alias for lower half of x */ - tmpx1 = x->dp; - - /* alias for upper half of x, or x/B**m */ - tmpx2 = x->dp + m; - - /* set carry to zero */ - mu = 0; - - /* compute (x mod B**m) + k * [x/B**m] inline and inplace */ - for (i = 0; i < m; i++) { - r = ((mp_word)*tmpx2++) * ((mp_word)k) + *tmpx1 + mu; - *tmpx1++ = (mp_digit)(r & MP_MASK); - mu = (mp_digit)(r >> ((mp_word)DIGIT_BIT)); - } - - /* set final carry */ - *tmpx1++ = mu; - - /* zero words above m */ - for (i = m + 1; i < x->used; i++) { - *tmpx1++ = 0; - } - - /* clamp, sub and return */ - mp_clamp (x); - - /* if x >= n then subtract and reduce again - * Each successive "recursion" makes the input smaller and smaller. - */ - if (mp_cmp_mag (x, n) != MP_LT) { - s_mp_sub(x, n, x); - goto top; - } - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_dr_reduce.c */ - -/* Start: bn_mp_dr_setup.c */ -#include -#ifdef BN_MP_DR_SETUP_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* determines the setup value */ -void mp_dr_setup(mp_int *a, mp_digit *d) -{ - /* the casts are required if DIGIT_BIT is one less than - * the number of bits in a mp_digit [e.g. DIGIT_BIT==31] - */ - *d = (mp_digit)((((mp_word)1) << ((mp_word)DIGIT_BIT)) - - ((mp_word)a->dp[0])); -} - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_dr_setup.c */ - -/* Start: bn_mp_exch.c */ -#include -#ifdef BN_MP_EXCH_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* swap the elements of two integers, for cases where you can't simply swap the - * mp_int pointers around - */ -void -mp_exch (mp_int * a, mp_int * b) -{ - mp_int t; - - t = *a; - *a = *b; - *b = t; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_exch.c */ - -/* Start: bn_mp_expt_d.c */ -#include -#ifdef BN_MP_EXPT_D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* calculate c = a**b using a square-multiply algorithm */ -int mp_expt_d (mp_int * a, mp_digit b, mp_int * c) -{ - int res, x; - mp_int g; - - if ((res = mp_init_copy (&g, a)) != MP_OKAY) { - return res; - } - - /* set initial result */ - mp_set (c, 1); - - for (x = 0; x < (int) DIGIT_BIT; x++) { - /* square */ - if ((res = mp_sqr (c, c)) != MP_OKAY) { - mp_clear (&g); - return res; - } - - /* if the bit is set multiply */ - if ((b & (mp_digit) (((mp_digit)1) << (DIGIT_BIT - 1))) != 0) { - if ((res = mp_mul (c, &g, c)) != MP_OKAY) { - mp_clear (&g); - return res; - } - } - - /* shift to next bit */ - b <<= 1; - } - - mp_clear (&g); - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_expt_d.c */ - -/* Start: bn_mp_exptmod.c */ -#include -#ifdef BN_MP_EXPTMOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - - -/* this is a shell function that calls either the normal or Montgomery - * exptmod functions. Originally the call to the montgomery code was - * embedded in the normal function but that wasted alot of stack space - * for nothing (since 99% of the time the Montgomery code would be called) - */ -int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) -{ - int dr; - - /* modulus P must be positive */ - if (P->sign == MP_NEG) { - return MP_VAL; - } - - /* if exponent X is negative we have to recurse */ - if (X->sign == MP_NEG) { -#ifdef BN_MP_INVMOD_C - mp_int tmpG, tmpX; - int err; - - /* first compute 1/G mod P */ - if ((err = mp_init(&tmpG)) != MP_OKAY) { - return err; - } - if ((err = mp_invmod(G, P, &tmpG)) != MP_OKAY) { - mp_clear(&tmpG); - return err; - } - - /* now get |X| */ - if ((err = mp_init(&tmpX)) != MP_OKAY) { - mp_clear(&tmpG); - return err; - } - if ((err = mp_abs(X, &tmpX)) != MP_OKAY) { - mp_clear_multi(&tmpG, &tmpX, NULL); - return err; - } - - /* and now compute (1/G)**|X| instead of G**X [X < 0] */ - err = mp_exptmod(&tmpG, &tmpX, P, Y); - mp_clear_multi(&tmpG, &tmpX, NULL); - return err; -#else - /* no invmod */ - return MP_VAL; -#endif - } - -/* modified diminished radix reduction */ -#if defined(BN_MP_REDUCE_IS_2K_L_C) && defined(BN_MP_REDUCE_2K_L_C) && defined(BN_S_MP_EXPTMOD_C) - if (mp_reduce_is_2k_l(P) == MP_YES) { - return s_mp_exptmod(G, X, P, Y, 1); - } -#endif - -#ifdef BN_MP_DR_IS_MODULUS_C - /* is it a DR modulus? */ - dr = mp_dr_is_modulus(P); -#else - /* default to no */ - dr = 0; -#endif - -#ifdef BN_MP_REDUCE_IS_2K_C - /* if not, is it a unrestricted DR modulus? */ - if (dr == 0) { - dr = mp_reduce_is_2k(P) << 1; - } -#endif - - /* if the modulus is odd or dr != 0 use the montgomery method */ -#ifdef BN_MP_EXPTMOD_FAST_C - if (mp_isodd (P) == 1 || dr != 0) { - return mp_exptmod_fast (G, X, P, Y, dr); - } else { -#endif -#ifdef BN_S_MP_EXPTMOD_C - /* otherwise use the generic Barrett reduction technique */ - return s_mp_exptmod (G, X, P, Y, 0); -#else - /* no exptmod for evens */ - return MP_VAL; -#endif -#ifdef BN_MP_EXPTMOD_FAST_C - } -#endif -} - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_exptmod.c */ - -/* Start: bn_mp_exptmod_fast.c */ -#include -#ifdef BN_MP_EXPTMOD_FAST_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* computes Y == G**X mod P, HAC pp.616, Algorithm 14.85 - * - * Uses a left-to-right k-ary sliding window to compute the modular exponentiation. - * The value of k changes based on the size of the exponent. - * - * Uses Montgomery or Diminished Radix reduction [whichever appropriate] - */ - -#ifdef MP_LOW_MEM - #define TAB_SIZE 32 -#else - #define TAB_SIZE 256 -#endif - -int mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) -{ - mp_int M[TAB_SIZE], res; - mp_digit buf, mp; - int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize; - - /* use a pointer to the reduction algorithm. This allows us to use - * one of many reduction algorithms without modding the guts of - * the code with if statements everywhere. - */ - int (*redux)(mp_int*,mp_int*,mp_digit); - - /* find window size */ - x = mp_count_bits (X); - if (x <= 7) { - winsize = 2; - } else if (x <= 36) { - winsize = 3; - } else if (x <= 140) { - winsize = 4; - } else if (x <= 450) { - winsize = 5; - } else if (x <= 1303) { - winsize = 6; - } else if (x <= 3529) { - winsize = 7; - } else { - winsize = 8; - } - -#ifdef MP_LOW_MEM - if (winsize > 5) { - winsize = 5; - } -#endif - - /* init M array */ - /* init first cell */ - if ((err = mp_init(&M[1])) != MP_OKAY) { - return err; - } - - /* now init the second half of the array */ - for (x = 1<<(winsize-1); x < (1 << winsize); x++) { - if ((err = mp_init(&M[x])) != MP_OKAY) { - for (y = 1<<(winsize-1); y < x; y++) { - mp_clear (&M[y]); - } - mp_clear(&M[1]); - return err; - } - } - - /* determine and setup reduction code */ - if (redmode == 0) { -#ifdef BN_MP_MONTGOMERY_SETUP_C - /* now setup montgomery */ - if ((err = mp_montgomery_setup (P, &mp)) != MP_OKAY) { - goto LBL_M; - } -#else - err = MP_VAL; - goto LBL_M; -#endif - - /* automatically pick the comba one if available (saves quite a few calls/ifs) */ -#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C - if (((P->used * 2 + 1) < MP_WARRAY) && - P->used < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { - redux = fast_mp_montgomery_reduce; - } else -#endif - { -#ifdef BN_MP_MONTGOMERY_REDUCE_C - /* use slower baseline Montgomery method */ - redux = mp_montgomery_reduce; -#else - err = MP_VAL; - goto LBL_M; -#endif - } - } else if (redmode == 1) { -#if defined(BN_MP_DR_SETUP_C) && defined(BN_MP_DR_REDUCE_C) - /* setup DR reduction for moduli of the form B**k - b */ - mp_dr_setup(P, &mp); - redux = mp_dr_reduce; -#else - err = MP_VAL; - goto LBL_M; -#endif - } else { -#if defined(BN_MP_REDUCE_2K_SETUP_C) && defined(BN_MP_REDUCE_2K_C) - /* setup DR reduction for moduli of the form 2**k - b */ - if ((err = mp_reduce_2k_setup(P, &mp)) != MP_OKAY) { - goto LBL_M; - } - redux = mp_reduce_2k; -#else - err = MP_VAL; - goto LBL_M; -#endif - } - - /* setup result */ - if ((err = mp_init (&res)) != MP_OKAY) { - goto LBL_M; - } - - /* create M table - * - - * - * The first half of the table is not computed though accept for M[0] and M[1] - */ - - if (redmode == 0) { -#ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C - /* now we need R mod m */ - if ((err = mp_montgomery_calc_normalization (&res, P)) != MP_OKAY) { - goto LBL_RES; - } -#else - err = MP_VAL; - goto LBL_RES; -#endif - - /* now set M[1] to G * R mod m */ - if ((err = mp_mulmod (G, &res, P, &M[1])) != MP_OKAY) { - goto LBL_RES; - } - } else { - mp_set(&res, 1); - if ((err = mp_mod(G, P, &M[1])) != MP_OKAY) { - goto LBL_RES; - } - } - - /* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times */ - if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) { - goto LBL_RES; - } - - for (x = 0; x < (winsize - 1); x++) { - if ((err = mp_sqr (&M[1 << (winsize - 1)], &M[1 << (winsize - 1)])) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&M[1 << (winsize - 1)], P, mp)) != MP_OKAY) { - goto LBL_RES; - } - } - - /* create upper table */ - for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) { - if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&M[x], P, mp)) != MP_OKAY) { - goto LBL_RES; - } - } - - /* set initial mode and bit cnt */ - mode = 0; - bitcnt = 1; - buf = 0; - digidx = X->used - 1; - bitcpy = 0; - bitbuf = 0; - - for (;;) { - /* grab next digit as required */ - if (--bitcnt == 0) { - /* if digidx == -1 we are out of digits so break */ - if (digidx == -1) { - break; - } - /* read next digit and reset bitcnt */ - buf = X->dp[digidx--]; - bitcnt = (int)DIGIT_BIT; - } - - /* grab the next msb from the exponent */ - y = (mp_digit)(buf >> (DIGIT_BIT - 1)) & 1; - buf <<= (mp_digit)1; - - /* if the bit is zero and mode == 0 then we ignore it - * These represent the leading zero bits before the first 1 bit - * in the exponent. Technically this opt is not required but it - * does lower the # of trivial squaring/reductions used - */ - if (mode == 0 && y == 0) { - continue; - } - - /* if the bit is zero and mode == 1 then we square */ - if (mode == 1 && y == 0) { - if ((err = mp_sqr (&res, &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, mp)) != MP_OKAY) { - goto LBL_RES; - } - continue; - } - - /* else we add it to the window */ - bitbuf |= (y << (winsize - ++bitcpy)); - mode = 2; - - if (bitcpy == winsize) { - /* ok window is filled so square as required and multiply */ - /* square first */ - for (x = 0; x < winsize; x++) { - if ((err = mp_sqr (&res, &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, mp)) != MP_OKAY) { - goto LBL_RES; - } - } - - /* then multiply */ - if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, mp)) != MP_OKAY) { - goto LBL_RES; - } - - /* empty window and reset */ - bitcpy = 0; - bitbuf = 0; - mode = 1; - } - } - - /* if bits remain then square/multiply */ - if (mode == 2 && bitcpy > 0) { - /* square then multiply if the bit is set */ - for (x = 0; x < bitcpy; x++) { - if ((err = mp_sqr (&res, &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, mp)) != MP_OKAY) { - goto LBL_RES; - } - - /* get next bit of the window */ - bitbuf <<= 1; - if ((bitbuf & (1 << winsize)) != 0) { - /* then multiply */ - if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, mp)) != MP_OKAY) { - goto LBL_RES; - } - } - } - } - - if (redmode == 0) { - /* fixup result if Montgomery reduction is used - * recall that any value in a Montgomery system is - * actually multiplied by R mod n. So we have - * to reduce one more time to cancel out the factor - * of R. - */ - if ((err = redux(&res, P, mp)) != MP_OKAY) { - goto LBL_RES; - } - } - - /* swap res with Y */ - mp_exch (&res, Y); - err = MP_OKAY; -LBL_RES:mp_clear (&res); -LBL_M: - mp_clear(&M[1]); - for (x = 1<<(winsize-1); x < (1 << winsize); x++) { - mp_clear (&M[x]); - } - return err; -} -#endif - - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_exptmod_fast.c */ - -/* Start: bn_mp_exteuclid.c */ -#include -#ifdef BN_MP_EXTEUCLID_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* Extended euclidean algorithm of (a, b) produces - a*u1 + b*u2 = u3 - */ -int mp_exteuclid(mp_int *a, mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3) -{ - mp_int u1,u2,u3,v1,v2,v3,t1,t2,t3,q,tmp; - int err; - - if ((err = mp_init_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL)) != MP_OKAY) { - return err; - } - - /* initialize, (u1,u2,u3) = (1,0,a) */ - mp_set(&u1, 1); - if ((err = mp_copy(a, &u3)) != MP_OKAY) { goto _ERR; } - - /* initialize, (v1,v2,v3) = (0,1,b) */ - mp_set(&v2, 1); - if ((err = mp_copy(b, &v3)) != MP_OKAY) { goto _ERR; } - - /* loop while v3 != 0 */ - while (mp_iszero(&v3) == MP_NO) { - /* q = u3/v3 */ - if ((err = mp_div(&u3, &v3, &q, NULL)) != MP_OKAY) { goto _ERR; } - - /* (t1,t2,t3) = (u1,u2,u3) - (v1,v2,v3)q */ - if ((err = mp_mul(&v1, &q, &tmp)) != MP_OKAY) { goto _ERR; } - if ((err = mp_sub(&u1, &tmp, &t1)) != MP_OKAY) { goto _ERR; } - if ((err = mp_mul(&v2, &q, &tmp)) != MP_OKAY) { goto _ERR; } - if ((err = mp_sub(&u2, &tmp, &t2)) != MP_OKAY) { goto _ERR; } - if ((err = mp_mul(&v3, &q, &tmp)) != MP_OKAY) { goto _ERR; } - if ((err = mp_sub(&u3, &tmp, &t3)) != MP_OKAY) { goto _ERR; } - - /* (u1,u2,u3) = (v1,v2,v3) */ - if ((err = mp_copy(&v1, &u1)) != MP_OKAY) { goto _ERR; } - if ((err = mp_copy(&v2, &u2)) != MP_OKAY) { goto _ERR; } - if ((err = mp_copy(&v3, &u3)) != MP_OKAY) { goto _ERR; } - - /* (v1,v2,v3) = (t1,t2,t3) */ - if ((err = mp_copy(&t1, &v1)) != MP_OKAY) { goto _ERR; } - if ((err = mp_copy(&t2, &v2)) != MP_OKAY) { goto _ERR; } - if ((err = mp_copy(&t3, &v3)) != MP_OKAY) { goto _ERR; } - } - - /* make sure U3 >= 0 */ - if (u3.sign == MP_NEG) { - mp_neg(&u1, &u1); - mp_neg(&u2, &u2); - mp_neg(&u3, &u3); - } - - /* copy result out */ - if (U1 != NULL) { mp_exch(U1, &u1); } - if (U2 != NULL) { mp_exch(U2, &u2); } - if (U3 != NULL) { mp_exch(U3, &u3); } - - err = MP_OKAY; -_ERR: mp_clear_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL); - return err; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_exteuclid.c */ - -/* Start: bn_mp_fread.c */ -#include -#ifdef BN_MP_FREAD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* read a bigint from a file stream in ASCII */ -int mp_fread(mp_int *a, int radix, FILE *stream) -{ - int err, ch, neg, y; - - /* clear a */ - mp_zero(a); - - /* if first digit is - then set negative */ - ch = fgetc(stream); - if (ch == '-') { - neg = MP_NEG; - ch = fgetc(stream); - } else { - neg = MP_ZPOS; - } - - for (;;) { - /* find y in the radix map */ - for (y = 0; y < radix; y++) { - if (mp_s_rmap[y] == ch) { - break; - } - } - if (y == radix) { - break; - } - - /* shift up and add */ - if ((err = mp_mul_d(a, radix, a)) != MP_OKAY) { - return err; - } - if ((err = mp_add_d(a, y, a)) != MP_OKAY) { - return err; - } - - ch = fgetc(stream); - } - if (mp_cmp_d(a, 0) != MP_EQ) { - a->sign = neg; - } - - return MP_OKAY; -} - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_fread.c */ - -/* Start: bn_mp_fwrite.c */ -#include -#ifdef BN_MP_FWRITE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -int mp_fwrite(mp_int *a, int radix, FILE *stream) -{ - char *buf; - int err, len, x; - - if ((err = mp_radix_size(a, radix, &len)) != MP_OKAY) { - return err; - } - - buf = OPT_CAST(char) XMALLOC (len); - if (buf == NULL) { - return MP_MEM; - } - - if ((err = mp_toradix(a, buf, radix)) != MP_OKAY) { - XFREE (buf); - return err; - } - - for (x = 0; x < len; x++) { - if (fputc(buf[x], stream) == EOF) { - XFREE (buf); - return MP_VAL; - } - } - - XFREE (buf); - return MP_OKAY; -} - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_fwrite.c */ - -/* Start: bn_mp_gcd.c */ -#include -#ifdef BN_MP_GCD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* Greatest Common Divisor using the binary method */ -int mp_gcd (mp_int * a, mp_int * b, mp_int * c) -{ - mp_int u, v; - int k, u_lsb, v_lsb, res; - - /* either zero than gcd is the largest */ - if (mp_iszero (a) == MP_YES) { - return mp_abs (b, c); - } - if (mp_iszero (b) == MP_YES) { - return mp_abs (a, c); - } - - /* get copies of a and b we can modify */ - if ((res = mp_init_copy (&u, a)) != MP_OKAY) { - return res; - } - - if ((res = mp_init_copy (&v, b)) != MP_OKAY) { - goto LBL_U; - } - - /* must be positive for the remainder of the algorithm */ - u.sign = v.sign = MP_ZPOS; - - /* B1. Find the common power of two for u and v */ - u_lsb = mp_cnt_lsb(&u); - v_lsb = mp_cnt_lsb(&v); - k = MIN(u_lsb, v_lsb); - - if (k > 0) { - /* divide the power of two out */ - if ((res = mp_div_2d(&u, k, &u, NULL)) != MP_OKAY) { - goto LBL_V; - } - - if ((res = mp_div_2d(&v, k, &v, NULL)) != MP_OKAY) { - goto LBL_V; - } - } - - /* divide any remaining factors of two out */ - if (u_lsb != k) { - if ((res = mp_div_2d(&u, u_lsb - k, &u, NULL)) != MP_OKAY) { - goto LBL_V; - } - } - - if (v_lsb != k) { - if ((res = mp_div_2d(&v, v_lsb - k, &v, NULL)) != MP_OKAY) { - goto LBL_V; - } - } - - while (mp_iszero(&v) == 0) { - /* make sure v is the largest */ - if (mp_cmp_mag(&u, &v) == MP_GT) { - /* swap u and v to make sure v is >= u */ - mp_exch(&u, &v); - } - - /* subtract smallest from largest */ - if ((res = s_mp_sub(&v, &u, &v)) != MP_OKAY) { - goto LBL_V; - } - - /* Divide out all factors of two */ - if ((res = mp_div_2d(&v, mp_cnt_lsb(&v), &v, NULL)) != MP_OKAY) { - goto LBL_V; - } - } - - /* multiply by 2**k which we divided out at the beginning */ - if ((res = mp_mul_2d (&u, k, c)) != MP_OKAY) { - goto LBL_V; - } - c->sign = MP_ZPOS; - res = MP_OKAY; -LBL_V:mp_clear (&u); -LBL_U:mp_clear (&v); - return res; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_gcd.c */ - -/* Start: bn_mp_get_int.c */ -#include -#ifdef BN_MP_GET_INT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* get the lower 32-bits of an mp_int */ -unsigned long mp_get_int(mp_int * a) -{ - int i; - unsigned long res; - - if (a->used == 0) { - return 0; - } - - /* get number of digits of the lsb we have to read */ - i = MIN(a->used,(int)((sizeof(unsigned long)*CHAR_BIT+DIGIT_BIT-1)/DIGIT_BIT))-1; - - /* get most significant digit of result */ - res = DIGIT(a,i); - - while (--i >= 0) { - res = (res << DIGIT_BIT) | DIGIT(a,i); - } - - /* force result to 32-bits always so it is consistent on non 32-bit platforms */ - return res & 0xFFFFFFFFUL; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_get_int.c */ - -/* Start: bn_mp_grow.c */ -#include -#ifdef BN_MP_GROW_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* grow as required */ -int mp_grow (mp_int * a, int size) -{ - int i; - mp_digit *tmp; - - /* if the alloc size is smaller alloc more ram */ - if (a->alloc < size) { - /* ensure there are always at least MP_PREC digits extra on top */ - size += (MP_PREC * 2) - (size % MP_PREC); - - /* reallocate the array a->dp - * - * We store the return in a temporary variable - * in case the operation failed we don't want - * to overwrite the dp member of a. - */ - tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * size); - if (tmp == NULL) { - /* reallocation failed but "a" is still valid [can be freed] */ - return MP_MEM; - } - - /* reallocation succeeded so set a->dp */ - a->dp = tmp; - - /* zero excess digits */ - i = a->alloc; - a->alloc = size; - for (; i < a->alloc; i++) { - a->dp[i] = 0; - } - } - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_grow.c */ - -/* Start: bn_mp_init.c */ -#include -#ifdef BN_MP_INIT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* init a new mp_int */ -int mp_init (mp_int * a) -{ - int i; - - /* allocate memory required and clear it */ - a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * MP_PREC); - if (a->dp == NULL) { - return MP_MEM; - } - - /* set the digits to zero */ - for (i = 0; i < MP_PREC; i++) { - a->dp[i] = 0; - } - - /* set the used to zero, allocated digits to the default precision - * and sign to positive */ - a->used = 0; - a->alloc = MP_PREC; - a->sign = MP_ZPOS; - - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_init.c */ - -/* Start: bn_mp_init_copy.c */ -#include -#ifdef BN_MP_INIT_COPY_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* creates "a" then copies b into it */ -int mp_init_copy (mp_int * a, mp_int * b) -{ - int res; - - if ((res = mp_init (a)) != MP_OKAY) { - return res; - } - return mp_copy (b, a); -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_init_copy.c */ - -/* Start: bn_mp_init_multi.c */ -#include -#ifdef BN_MP_INIT_MULTI_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#include - -int mp_init_multi(mp_int *mp, ...) -{ - mp_err res = MP_OKAY; /* Assume ok until proven otherwise */ - int n = 0; /* Number of ok inits */ - mp_int* cur_arg = mp; - va_list args; - - va_start(args, mp); /* init args to next argument from caller */ - while (cur_arg != NULL) { - if (mp_init(cur_arg) != MP_OKAY) { - /* Oops - error! Back-track and mp_clear what we already - succeeded in init-ing, then return error. - */ - va_list clean_args; - - /* end the current list */ - va_end(args); - - /* now start cleaning up */ - cur_arg = mp; - va_start(clean_args, mp); - while (n--) { - mp_clear(cur_arg); - cur_arg = va_arg(clean_args, mp_int*); - } - va_end(clean_args); - res = MP_MEM; - break; - } - n++; - cur_arg = va_arg(args, mp_int*); - } - va_end(args); - return res; /* Assumed ok, if error flagged above. */ -} - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_init_multi.c */ - -/* Start: bn_mp_init_set.c */ -#include -#ifdef BN_MP_INIT_SET_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* initialize and set a digit */ -int mp_init_set (mp_int * a, mp_digit b) -{ - int err; - if ((err = mp_init(a)) != MP_OKAY) { - return err; - } - mp_set(a, b); - return err; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_init_set.c */ - -/* Start: bn_mp_init_set_int.c */ -#include -#ifdef BN_MP_INIT_SET_INT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* initialize and set a digit */ -int mp_init_set_int (mp_int * a, unsigned long b) -{ - int err; - if ((err = mp_init(a)) != MP_OKAY) { - return err; - } - return mp_set_int(a, b); -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_init_set_int.c */ - -/* Start: bn_mp_init_size.c */ -#include -#ifdef BN_MP_INIT_SIZE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* init an mp_init for a given size */ -int mp_init_size (mp_int * a, int size) -{ - int x; - - /* pad size so there are always extra digits */ - size += (MP_PREC * 2) - (size % MP_PREC); - - /* alloc mem */ - a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * size); - if (a->dp == NULL) { - return MP_MEM; - } - - /* set the members */ - a->used = 0; - a->alloc = size; - a->sign = MP_ZPOS; - - /* zero the digits */ - for (x = 0; x < size; x++) { - a->dp[x] = 0; - } - - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_init_size.c */ - -/* Start: bn_mp_invmod.c */ -#include -#ifdef BN_MP_INVMOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* hac 14.61, pp608 */ -int mp_invmod (mp_int * a, mp_int * b, mp_int * c) -{ - /* b cannot be negative */ - if (b->sign == MP_NEG || mp_iszero(b) == 1) { - return MP_VAL; - } - -#ifdef BN_FAST_MP_INVMOD_C - /* if the modulus is odd we can use a faster routine instead */ - if (mp_isodd (b) == 1) { - return fast_mp_invmod (a, b, c); - } -#endif - -#ifdef BN_MP_INVMOD_SLOW_C - return mp_invmod_slow(a, b, c); -#endif - - return MP_VAL; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_invmod.c */ - -/* Start: bn_mp_invmod_slow.c */ -#include -#ifdef BN_MP_INVMOD_SLOW_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* hac 14.61, pp608 */ -int mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c) -{ - mp_int x, y, u, v, A, B, C, D; - int res; - - /* b cannot be negative */ - if (b->sign == MP_NEG || mp_iszero(b) == 1) { - return MP_VAL; - } - - /* init temps */ - if ((res = mp_init_multi(&x, &y, &u, &v, - &A, &B, &C, &D, NULL)) != MP_OKAY) { - return res; - } - - /* x = a, y = b */ - if ((res = mp_mod(a, b, &x)) != MP_OKAY) { - goto LBL_ERR; - } - if ((res = mp_copy (b, &y)) != MP_OKAY) { - goto LBL_ERR; - } - - /* 2. [modified] if x,y are both even then return an error! */ - if (mp_iseven (&x) == 1 && mp_iseven (&y) == 1) { - res = MP_VAL; - goto LBL_ERR; - } - - /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */ - if ((res = mp_copy (&x, &u)) != MP_OKAY) { - goto LBL_ERR; - } - if ((res = mp_copy (&y, &v)) != MP_OKAY) { - goto LBL_ERR; - } - mp_set (&A, 1); - mp_set (&D, 1); - -top: - /* 4. while u is even do */ - while (mp_iseven (&u) == 1) { - /* 4.1 u = u/2 */ - if ((res = mp_div_2 (&u, &u)) != MP_OKAY) { - goto LBL_ERR; - } - /* 4.2 if A or B is odd then */ - if (mp_isodd (&A) == 1 || mp_isodd (&B) == 1) { - /* A = (A+y)/2, B = (B-x)/2 */ - if ((res = mp_add (&A, &y, &A)) != MP_OKAY) { - goto LBL_ERR; - } - if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) { - goto LBL_ERR; - } - } - /* A = A/2, B = B/2 */ - if ((res = mp_div_2 (&A, &A)) != MP_OKAY) { - goto LBL_ERR; - } - if ((res = mp_div_2 (&B, &B)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* 5. while v is even do */ - while (mp_iseven (&v) == 1) { - /* 5.1 v = v/2 */ - if ((res = mp_div_2 (&v, &v)) != MP_OKAY) { - goto LBL_ERR; - } - /* 5.2 if C or D is odd then */ - if (mp_isodd (&C) == 1 || mp_isodd (&D) == 1) { - /* C = (C+y)/2, D = (D-x)/2 */ - if ((res = mp_add (&C, &y, &C)) != MP_OKAY) { - goto LBL_ERR; - } - if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) { - goto LBL_ERR; - } - } - /* C = C/2, D = D/2 */ - if ((res = mp_div_2 (&C, &C)) != MP_OKAY) { - goto LBL_ERR; - } - if ((res = mp_div_2 (&D, &D)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* 6. if u >= v then */ - if (mp_cmp (&u, &v) != MP_LT) { - /* u = u - v, A = A - C, B = B - D */ - if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) { - goto LBL_ERR; - } - - if ((res = mp_sub (&A, &C, &A)) != MP_OKAY) { - goto LBL_ERR; - } - - if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) { - goto LBL_ERR; - } - } else { - /* v - v - u, C = C - A, D = D - B */ - if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) { - goto LBL_ERR; - } - - if ((res = mp_sub (&C, &A, &C)) != MP_OKAY) { - goto LBL_ERR; - } - - if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* if not zero goto step 4 */ - if (mp_iszero (&u) == 0) - goto top; - - /* now a = C, b = D, gcd == g*v */ - - /* if v != 1 then there is no inverse */ - if (mp_cmp_d (&v, 1) != MP_EQ) { - res = MP_VAL; - goto LBL_ERR; - } - - /* if its too low */ - while (mp_cmp_d(&C, 0) == MP_LT) { - if ((res = mp_add(&C, b, &C)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* too big */ - while (mp_cmp_mag(&C, b) != MP_LT) { - if ((res = mp_sub(&C, b, &C)) != MP_OKAY) { - goto LBL_ERR; - } - } - - /* C is now the inverse */ - mp_exch (&C, c); - res = MP_OKAY; -LBL_ERR:mp_clear_multi (&x, &y, &u, &v, &A, &B, &C, &D, NULL); - return res; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_invmod_slow.c */ - -/* Start: bn_mp_is_square.c */ -#include -#ifdef BN_MP_IS_SQUARE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* Check if remainders are possible squares - fast exclude non-squares */ -static const char rem_128[128] = { - 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, - 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, - 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, - 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, - 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, - 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, - 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, - 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1 -}; - -static const char rem_105[105] = { - 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, - 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, - 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, - 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, - 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1 -}; - -/* Store non-zero to ret if arg is square, and zero if not */ -int mp_is_square(mp_int *arg,int *ret) -{ - int res; - mp_digit c; - mp_int t; - unsigned long r; - - /* Default to Non-square :) */ - *ret = MP_NO; - - if (arg->sign == MP_NEG) { - return MP_VAL; - } - - /* digits used? (TSD) */ - if (arg->used == 0) { - return MP_OKAY; - } - - /* First check mod 128 (suppose that DIGIT_BIT is at least 7) */ - if (rem_128[127 & DIGIT(arg,0)] == 1) { - return MP_OKAY; - } - - /* Next check mod 105 (3*5*7) */ - if ((res = mp_mod_d(arg,105,&c)) != MP_OKAY) { - return res; - } - if (rem_105[c] == 1) { - return MP_OKAY; - } - - - if ((res = mp_init_set_int(&t,11L*13L*17L*19L*23L*29L*31L)) != MP_OKAY) { - return res; - } - if ((res = mp_mod(arg,&t,&t)) != MP_OKAY) { - goto ERR; - } - r = mp_get_int(&t); - /* Check for other prime modules, note it's not an ERROR but we must - * free "t" so the easiest way is to goto ERR. We know that res - * is already equal to MP_OKAY from the mp_mod call - */ - if ( (1L<<(r%11)) & 0x5C4L ) goto ERR; - if ( (1L<<(r%13)) & 0x9E4L ) goto ERR; - if ( (1L<<(r%17)) & 0x5CE8L ) goto ERR; - if ( (1L<<(r%19)) & 0x4F50CL ) goto ERR; - if ( (1L<<(r%23)) & 0x7ACCA0L ) goto ERR; - if ( (1L<<(r%29)) & 0xC2EDD0CL ) goto ERR; - if ( (1L<<(r%31)) & 0x6DE2B848L ) goto ERR; - - /* Final check - is sqr(sqrt(arg)) == arg ? */ - if ((res = mp_sqrt(arg,&t)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sqr(&t,&t)) != MP_OKAY) { - goto ERR; - } - - *ret = (mp_cmp_mag(&t,arg) == MP_EQ) ? MP_YES : MP_NO; -ERR:mp_clear(&t); - return res; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_is_square.c */ - -/* Start: bn_mp_jacobi.c */ -#include -#ifdef BN_MP_JACOBI_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* computes the jacobi c = (a | n) (or Legendre if n is prime) - * HAC pp. 73 Algorithm 2.149 - */ -int mp_jacobi (mp_int * a, mp_int * p, int *c) -{ - mp_int a1, p1; - int k, s, r, res; - mp_digit residue; - - /* if p <= 0 return MP_VAL */ - if (mp_cmp_d(p, 0) != MP_GT) { - return MP_VAL; - } - - /* step 1. if a == 0, return 0 */ - if (mp_iszero (a) == 1) { - *c = 0; - return MP_OKAY; - } - - /* step 2. if a == 1, return 1 */ - if (mp_cmp_d (a, 1) == MP_EQ) { - *c = 1; - return MP_OKAY; - } - - /* default */ - s = 0; - - /* step 3. write a = a1 * 2**k */ - if ((res = mp_init_copy (&a1, a)) != MP_OKAY) { - return res; - } - - if ((res = mp_init (&p1)) != MP_OKAY) { - goto LBL_A1; - } - - /* divide out larger power of two */ - k = mp_cnt_lsb(&a1); - if ((res = mp_div_2d(&a1, k, &a1, NULL)) != MP_OKAY) { - goto LBL_P1; - } - - /* step 4. if e is even set s=1 */ - if ((k & 1) == 0) { - s = 1; - } else { - /* else set s=1 if p = 1/7 (mod 8) or s=-1 if p = 3/5 (mod 8) */ - residue = p->dp[0] & 7; - - if (residue == 1 || residue == 7) { - s = 1; - } else if (residue == 3 || residue == 5) { - s = -1; - } - } - - /* step 5. if p == 3 (mod 4) *and* a1 == 3 (mod 4) then s = -s */ - if ( ((p->dp[0] & 3) == 3) && ((a1.dp[0] & 3) == 3)) { - s = -s; - } - - /* if a1 == 1 we're done */ - if (mp_cmp_d (&a1, 1) == MP_EQ) { - *c = s; - } else { - /* n1 = n mod a1 */ - if ((res = mp_mod (p, &a1, &p1)) != MP_OKAY) { - goto LBL_P1; - } - if ((res = mp_jacobi (&p1, &a1, &r)) != MP_OKAY) { - goto LBL_P1; - } - *c = s * r; - } - - /* done */ - res = MP_OKAY; -LBL_P1:mp_clear (&p1); -LBL_A1:mp_clear (&a1); - return res; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_jacobi.c */ - -/* Start: bn_mp_karatsuba_mul.c */ -#include -#ifdef BN_MP_KARATSUBA_MUL_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* c = |a| * |b| using Karatsuba Multiplication using - * three half size multiplications - * - * Let B represent the radix [e.g. 2**DIGIT_BIT] and - * let n represent half of the number of digits in - * the min(a,b) - * - * a = a1 * B**n + a0 - * b = b1 * B**n + b0 - * - * Then, a * b => - a1b1 * B**2n + ((a1 + a0)(b1 + b0) - (a0b0 + a1b1)) * B + a0b0 - * - * Note that a1b1 and a0b0 are used twice and only need to be - * computed once. So in total three half size (half # of - * digit) multiplications are performed, a0b0, a1b1 and - * (a1+b1)(a0+b0) - * - * Note that a multiplication of half the digits requires - * 1/4th the number of single precision multiplications so in - * total after one call 25% of the single precision multiplications - * are saved. Note also that the call to mp_mul can end up back - * in this function if the a0, a1, b0, or b1 are above the threshold. - * This is known as divide-and-conquer and leads to the famous - * O(N**lg(3)) or O(N**1.584) work which is asymptopically lower than - * the standard O(N**2) that the baseline/comba methods use. - * Generally though the overhead of this method doesn't pay off - * until a certain size (N ~ 80) is reached. - */ -int mp_karatsuba_mul (mp_int * a, mp_int * b, mp_int * c) -{ - mp_int x0, x1, y0, y1, t1, x0y0, x1y1; - int B, err; - - /* default the return code to an error */ - err = MP_MEM; - - /* min # of digits */ - B = MIN (a->used, b->used); - - /* now divide in two */ - B = B >> 1; - - /* init copy all the temps */ - if (mp_init_size (&x0, B) != MP_OKAY) - goto ERR; - if (mp_init_size (&x1, a->used - B) != MP_OKAY) - goto X0; - if (mp_init_size (&y0, B) != MP_OKAY) - goto X1; - if (mp_init_size (&y1, b->used - B) != MP_OKAY) - goto Y0; - - /* init temps */ - if (mp_init_size (&t1, B * 2) != MP_OKAY) - goto Y1; - if (mp_init_size (&x0y0, B * 2) != MP_OKAY) - goto T1; - if (mp_init_size (&x1y1, B * 2) != MP_OKAY) - goto X0Y0; - - /* now shift the digits */ - x0.used = y0.used = B; - x1.used = a->used - B; - y1.used = b->used - B; - - { - register int x; - register mp_digit *tmpa, *tmpb, *tmpx, *tmpy; - - /* we copy the digits directly instead of using higher level functions - * since we also need to shift the digits - */ - tmpa = a->dp; - tmpb = b->dp; - - tmpx = x0.dp; - tmpy = y0.dp; - for (x = 0; x < B; x++) { - *tmpx++ = *tmpa++; - *tmpy++ = *tmpb++; - } - - tmpx = x1.dp; - for (x = B; x < a->used; x++) { - *tmpx++ = *tmpa++; - } - - tmpy = y1.dp; - for (x = B; x < b->used; x++) { - *tmpy++ = *tmpb++; - } - } - - /* only need to clamp the lower words since by definition the - * upper words x1/y1 must have a known number of digits - */ - mp_clamp (&x0); - mp_clamp (&y0); - - /* now calc the products x0y0 and x1y1 */ - /* after this x0 is no longer required, free temp [x0==t2]! */ - if (mp_mul (&x0, &y0, &x0y0) != MP_OKAY) - goto X1Y1; /* x0y0 = x0*y0 */ - if (mp_mul (&x1, &y1, &x1y1) != MP_OKAY) - goto X1Y1; /* x1y1 = x1*y1 */ - - /* now calc x1+x0 and y1+y0 */ - if (s_mp_add (&x1, &x0, &t1) != MP_OKAY) - goto X1Y1; /* t1 = x1 - x0 */ - if (s_mp_add (&y1, &y0, &x0) != MP_OKAY) - goto X1Y1; /* t2 = y1 - y0 */ - if (mp_mul (&t1, &x0, &t1) != MP_OKAY) - goto X1Y1; /* t1 = (x1 + x0) * (y1 + y0) */ - - /* add x0y0 */ - if (mp_add (&x0y0, &x1y1, &x0) != MP_OKAY) - goto X1Y1; /* t2 = x0y0 + x1y1 */ - if (s_mp_sub (&t1, &x0, &t1) != MP_OKAY) - goto X1Y1; /* t1 = (x1+x0)*(y1+y0) - (x1y1 + x0y0) */ - - /* shift by B */ - if (mp_lshd (&t1, B) != MP_OKAY) - goto X1Y1; /* t1 = (x0y0 + x1y1 - (x1-x0)*(y1-y0))< -#ifdef BN_MP_KARATSUBA_SQR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* Karatsuba squaring, computes b = a*a using three - * half size squarings - * - * See comments of karatsuba_mul for details. It - * is essentially the same algorithm but merely - * tuned to perform recursive squarings. - */ -int mp_karatsuba_sqr (mp_int * a, mp_int * b) -{ - mp_int x0, x1, t1, t2, x0x0, x1x1; - int B, err; - - err = MP_MEM; - - /* min # of digits */ - B = a->used; - - /* now divide in two */ - B = B >> 1; - - /* init copy all the temps */ - if (mp_init_size (&x0, B) != MP_OKAY) - goto ERR; - if (mp_init_size (&x1, a->used - B) != MP_OKAY) - goto X0; - - /* init temps */ - if (mp_init_size (&t1, a->used * 2) != MP_OKAY) - goto X1; - if (mp_init_size (&t2, a->used * 2) != MP_OKAY) - goto T1; - if (mp_init_size (&x0x0, B * 2) != MP_OKAY) - goto T2; - if (mp_init_size (&x1x1, (a->used - B) * 2) != MP_OKAY) - goto X0X0; - - { - register int x; - register mp_digit *dst, *src; - - src = a->dp; - - /* now shift the digits */ - dst = x0.dp; - for (x = 0; x < B; x++) { - *dst++ = *src++; - } - - dst = x1.dp; - for (x = B; x < a->used; x++) { - *dst++ = *src++; - } - } - - x0.used = B; - x1.used = a->used - B; - - mp_clamp (&x0); - - /* now calc the products x0*x0 and x1*x1 */ - if (mp_sqr (&x0, &x0x0) != MP_OKAY) - goto X1X1; /* x0x0 = x0*x0 */ - if (mp_sqr (&x1, &x1x1) != MP_OKAY) - goto X1X1; /* x1x1 = x1*x1 */ - - /* now calc (x1+x0)**2 */ - if (s_mp_add (&x1, &x0, &t1) != MP_OKAY) - goto X1X1; /* t1 = x1 - x0 */ - if (mp_sqr (&t1, &t1) != MP_OKAY) - goto X1X1; /* t1 = (x1 - x0) * (x1 - x0) */ - - /* add x0y0 */ - if (s_mp_add (&x0x0, &x1x1, &t2) != MP_OKAY) - goto X1X1; /* t2 = x0x0 + x1x1 */ - if (s_mp_sub (&t1, &t2, &t1) != MP_OKAY) - goto X1X1; /* t1 = (x1+x0)**2 - (x0x0 + x1x1) */ - - /* shift by B */ - if (mp_lshd (&t1, B) != MP_OKAY) - goto X1X1; /* t1 = (x0x0 + x1x1 - (x1-x0)*(x1-x0))< -#ifdef BN_MP_LCM_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* computes least common multiple as |a*b|/(a, b) */ -int mp_lcm (mp_int * a, mp_int * b, mp_int * c) -{ - int res; - mp_int t1, t2; - - - if ((res = mp_init_multi (&t1, &t2, NULL)) != MP_OKAY) { - return res; - } - - /* t1 = get the GCD of the two inputs */ - if ((res = mp_gcd (a, b, &t1)) != MP_OKAY) { - goto LBL_T; - } - - /* divide the smallest by the GCD */ - if (mp_cmp_mag(a, b) == MP_LT) { - /* store quotient in t2 such that t2 * b is the LCM */ - if ((res = mp_div(a, &t1, &t2, NULL)) != MP_OKAY) { - goto LBL_T; - } - res = mp_mul(b, &t2, c); - } else { - /* store quotient in t2 such that t2 * a is the LCM */ - if ((res = mp_div(b, &t1, &t2, NULL)) != MP_OKAY) { - goto LBL_T; - } - res = mp_mul(a, &t2, c); - } - - /* fix the sign to positive */ - c->sign = MP_ZPOS; - -LBL_T: - mp_clear_multi (&t1, &t2, NULL); - return res; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_lcm.c */ - -/* Start: bn_mp_lshd.c */ -#include -#ifdef BN_MP_LSHD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* shift left a certain amount of digits */ -int mp_lshd (mp_int * a, int b) -{ - int x, res; - - /* if its less than zero return */ - if (b <= 0) { - return MP_OKAY; - } - - /* grow to fit the new digits */ - if (a->alloc < a->used + b) { - if ((res = mp_grow (a, a->used + b)) != MP_OKAY) { - return res; - } - } - - { - register mp_digit *top, *bottom; - - /* increment the used by the shift amount then copy upwards */ - a->used += b; - - /* top */ - top = a->dp + a->used - 1; - - /* base */ - bottom = a->dp + a->used - 1 - b; - - /* much like mp_rshd this is implemented using a sliding window - * except the window goes the otherway around. Copying from - * the bottom to the top. see bn_mp_rshd.c for more info. - */ - for (x = a->used - 1; x >= b; x--) { - *top-- = *bottom--; - } - - /* zero the lower digits */ - top = a->dp; - for (x = 0; x < b; x++) { - *top++ = 0; - } - } - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_lshd.c */ - -/* Start: bn_mp_mod.c */ -#include -#ifdef BN_MP_MOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* c = a mod b, 0 <= c < b */ -int -mp_mod (mp_int * a, mp_int * b, mp_int * c) -{ - mp_int t; - int res; - - if ((res = mp_init (&t)) != MP_OKAY) { - return res; - } - - if ((res = mp_div (a, b, NULL, &t)) != MP_OKAY) { - mp_clear (&t); - return res; - } - - if (t.sign != b->sign) { - res = mp_add (b, &t, c); - } else { - res = MP_OKAY; - mp_exch (&t, c); - } - - mp_clear (&t); - return res; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_mod.c */ - -/* Start: bn_mp_mod_2d.c */ -#include -#ifdef BN_MP_MOD_2D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* calc a value mod 2**b */ -int -mp_mod_2d (mp_int * a, int b, mp_int * c) -{ - int x, res; - - /* if b is <= 0 then zero the int */ - if (b <= 0) { - mp_zero (c); - return MP_OKAY; - } - - /* if the modulus is larger than the value than return */ - if (b >= (int) (a->used * DIGIT_BIT)) { - res = mp_copy (a, c); - return res; - } - - /* copy */ - if ((res = mp_copy (a, c)) != MP_OKAY) { - return res; - } - - /* zero digits above the last digit of the modulus */ - for (x = (b / DIGIT_BIT) + ((b % DIGIT_BIT) == 0 ? 0 : 1); x < c->used; x++) { - c->dp[x] = 0; - } - /* clear the digit that is not completely outside/inside the modulus */ - c->dp[b / DIGIT_BIT] &= - (mp_digit) ((((mp_digit) 1) << (((mp_digit) b) % DIGIT_BIT)) - ((mp_digit) 1)); - mp_clamp (c); - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_mod_2d.c */ - -/* Start: bn_mp_mod_d.c */ -#include -#ifdef BN_MP_MOD_D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -int -mp_mod_d (mp_int * a, mp_digit b, mp_digit * c) -{ - return mp_div_d(a, b, NULL, c); -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_mod_d.c */ - -/* Start: bn_mp_montgomery_calc_normalization.c */ -#include -#ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* - * shifts with subtractions when the result is greater than b. - * - * The method is slightly modified to shift B unconditionally upto just under - * the leading bit of b. This saves alot of multiple precision shifting. - */ -int mp_montgomery_calc_normalization (mp_int * a, mp_int * b) -{ - int x, bits, res; - - /* how many bits of last digit does b use */ - bits = mp_count_bits (b) % DIGIT_BIT; - - if (b->used > 1) { - if ((res = mp_2expt (a, (b->used - 1) * DIGIT_BIT + bits - 1)) != MP_OKAY) { - return res; - } - } else { - mp_set(a, 1); - bits = 1; - } - - - /* now compute C = A * B mod b */ - for (x = bits - 1; x < (int)DIGIT_BIT; x++) { - if ((res = mp_mul_2 (a, a)) != MP_OKAY) { - return res; - } - if (mp_cmp_mag (a, b) != MP_LT) { - if ((res = s_mp_sub (a, b, a)) != MP_OKAY) { - return res; - } - } - } - - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_montgomery_calc_normalization.c */ - -/* Start: bn_mp_montgomery_reduce.c */ -#include -#ifdef BN_MP_MONTGOMERY_REDUCE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* computes xR**-1 == x (mod N) via Montgomery Reduction */ -int -mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) -{ - int ix, res, digs; - mp_digit mu; - - /* can the fast reduction [comba] method be used? - * - * Note that unlike in mul you're safely allowed *less* - * than the available columns [255 per default] since carries - * are fixed up in the inner loop. - */ - digs = n->used * 2 + 1; - if ((digs < MP_WARRAY) && - n->used < - (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { - return fast_mp_montgomery_reduce (x, n, rho); - } - - /* grow the input as required */ - if (x->alloc < digs) { - if ((res = mp_grow (x, digs)) != MP_OKAY) { - return res; - } - } - x->used = digs; - - for (ix = 0; ix < n->used; ix++) { - /* mu = ai * rho mod b - * - * The value of rho must be precalculated via - * montgomery_setup() such that - * it equals -1/n0 mod b this allows the - * following inner loop to reduce the - * input one digit at a time - */ - mu = (mp_digit) (((mp_word)x->dp[ix]) * ((mp_word)rho) & MP_MASK); - - /* a = a + mu * m * b**i */ - { - register int iy; - register mp_digit *tmpn, *tmpx, u; - register mp_word r; - - /* alias for digits of the modulus */ - tmpn = n->dp; - - /* alias for the digits of x [the input] */ - tmpx = x->dp + ix; - - /* set the carry to zero */ - u = 0; - - /* Multiply and add in place */ - for (iy = 0; iy < n->used; iy++) { - /* compute product and sum */ - r = ((mp_word)mu) * ((mp_word)*tmpn++) + - ((mp_word) u) + ((mp_word) * tmpx); - - /* get carry */ - u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); - - /* fix digit */ - *tmpx++ = (mp_digit)(r & ((mp_word) MP_MASK)); - } - /* At this point the ix'th digit of x should be zero */ - - - /* propagate carries upwards as required*/ - while (u) { - *tmpx += u; - u = *tmpx >> DIGIT_BIT; - *tmpx++ &= MP_MASK; - } - } - } - - /* at this point the n.used'th least - * significant digits of x are all zero - * which means we can shift x to the - * right by n.used digits and the - * residue is unchanged. - */ - - /* x = x/b**n.used */ - mp_clamp(x); - mp_rshd (x, n->used); - - /* if x >= n then x = x - n */ - if (mp_cmp_mag (x, n) != MP_LT) { - return s_mp_sub (x, n, x); - } - - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_montgomery_reduce.c */ - -/* Start: bn_mp_montgomery_setup.c */ -#include -#ifdef BN_MP_MONTGOMERY_SETUP_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* setups the montgomery reduction stuff */ -int -mp_montgomery_setup (mp_int * n, mp_digit * rho) -{ - mp_digit x, b; - -/* fast inversion mod 2**k - * - * Based on the fact that - * - * XA = 1 (mod 2**n) => (X(2-XA)) A = 1 (mod 2**2n) - * => 2*X*A - X*X*A*A = 1 - * => 2*(1) - (1) = 1 - */ - b = n->dp[0]; - - if ((b & 1) == 0) { - return MP_VAL; - } - - x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */ - x *= 2 - b * x; /* here x*a==1 mod 2**8 */ -#if !defined(MP_8BIT) - x *= 2 - b * x; /* here x*a==1 mod 2**16 */ -#endif -#if defined(MP_64BIT) || !(defined(MP_8BIT) || defined(MP_16BIT)) - x *= 2 - b * x; /* here x*a==1 mod 2**32 */ -#endif -#ifdef MP_64BIT - x *= 2 - b * x; /* here x*a==1 mod 2**64 */ -#endif - - /* rho = -1/m mod b */ - *rho = (unsigned long)(((mp_word)1 << ((mp_word) DIGIT_BIT)) - x) & MP_MASK; - - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_montgomery_setup.c */ - -/* Start: bn_mp_mul.c */ -#include -#ifdef BN_MP_MUL_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* high level multiplication (handles sign) */ -int mp_mul (mp_int * a, mp_int * b, mp_int * c) -{ - int res, neg; - neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; - - /* use Toom-Cook? */ -#ifdef BN_MP_TOOM_MUL_C - if (MIN (a->used, b->used) >= TOOM_MUL_CUTOFF) { - res = mp_toom_mul(a, b, c); - } else -#endif -#ifdef BN_MP_KARATSUBA_MUL_C - /* use Karatsuba? */ - if (MIN (a->used, b->used) >= KARATSUBA_MUL_CUTOFF) { - res = mp_karatsuba_mul (a, b, c); - } else -#endif - { - /* can we use the fast multiplier? - * - * The fast multiplier can be used if the output will - * have less than MP_WARRAY digits and the number of - * digits won't affect carry propagation - */ - int digs = a->used + b->used + 1; - -#ifdef BN_FAST_S_MP_MUL_DIGS_C - if ((digs < MP_WARRAY) && - MIN(a->used, b->used) <= - (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { - res = fast_s_mp_mul_digs (a, b, c, digs); - } else -#endif -#ifdef BN_S_MP_MUL_DIGS_C - res = s_mp_mul (a, b, c); /* uses s_mp_mul_digs */ -#else - res = MP_VAL; -#endif - - } - c->sign = (c->used > 0) ? neg : MP_ZPOS; - return res; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_mul.c */ - -/* Start: bn_mp_mul_2.c */ -#include -#ifdef BN_MP_MUL_2_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* b = a*2 */ -int mp_mul_2(mp_int * a, mp_int * b) -{ - int x, res, oldused; - - /* grow to accomodate result */ - if (b->alloc < a->used + 1) { - if ((res = mp_grow (b, a->used + 1)) != MP_OKAY) { - return res; - } - } - - oldused = b->used; - b->used = a->used; - - { - register mp_digit r, rr, *tmpa, *tmpb; - - /* alias for source */ - tmpa = a->dp; - - /* alias for dest */ - tmpb = b->dp; - - /* carry */ - r = 0; - for (x = 0; x < a->used; x++) { - - /* get what will be the *next* carry bit from the - * MSB of the current digit - */ - rr = *tmpa >> ((mp_digit)(DIGIT_BIT - 1)); - - /* now shift up this digit, add in the carry [from the previous] */ - *tmpb++ = ((*tmpa++ << ((mp_digit)1)) | r) & MP_MASK; - - /* copy the carry that would be from the source - * digit into the next iteration - */ - r = rr; - } - - /* new leading digit? */ - if (r != 0) { - /* add a MSB which is always 1 at this point */ - *tmpb = 1; - ++(b->used); - } - - /* now zero any excess digits on the destination - * that we didn't write to - */ - tmpb = b->dp + b->used; - for (x = b->used; x < oldused; x++) { - *tmpb++ = 0; - } - } - b->sign = a->sign; - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_mul_2.c */ - -/* Start: bn_mp_mul_2d.c */ -#include -#ifdef BN_MP_MUL_2D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* shift left by a certain bit count */ -int mp_mul_2d (mp_int * a, int b, mp_int * c) -{ - mp_digit d; - int res; - - /* copy */ - if (a != c) { - if ((res = mp_copy (a, c)) != MP_OKAY) { - return res; - } - } - - if (c->alloc < (int)(c->used + b/DIGIT_BIT + 1)) { - if ((res = mp_grow (c, c->used + b / DIGIT_BIT + 1)) != MP_OKAY) { - return res; - } - } - - /* shift by as many digits in the bit count */ - if (b >= (int)DIGIT_BIT) { - if ((res = mp_lshd (c, b / DIGIT_BIT)) != MP_OKAY) { - return res; - } - } - - /* shift any bit count < DIGIT_BIT */ - d = (mp_digit) (b % DIGIT_BIT); - if (d != 0) { - register mp_digit *tmpc, shift, mask, r, rr; - register int x; - - /* bitmask for carries */ - mask = (((mp_digit)1) << d) - 1; - - /* shift for msbs */ - shift = DIGIT_BIT - d; - - /* alias */ - tmpc = c->dp; - - /* carry */ - r = 0; - for (x = 0; x < c->used; x++) { - /* get the higher bits of the current word */ - rr = (*tmpc >> shift) & mask; - - /* shift the current word and OR in the carry */ - *tmpc = ((*tmpc << d) | r) & MP_MASK; - ++tmpc; - - /* set the carry to the carry bits of the current word */ - r = rr; - } - - /* set final carry */ - if (r != 0) { - c->dp[(c->used)++] = r; - } - } - mp_clamp (c); - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_mul_2d.c */ - -/* Start: bn_mp_mul_d.c */ -#include -#ifdef BN_MP_MUL_D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* multiply by a digit */ -int -mp_mul_d (mp_int * a, mp_digit b, mp_int * c) -{ - mp_digit u, *tmpa, *tmpc; - mp_word r; - int ix, res, olduse; - - /* make sure c is big enough to hold a*b */ - if (c->alloc < a->used + 1) { - if ((res = mp_grow (c, a->used + 1)) != MP_OKAY) { - return res; - } - } - - /* get the original destinations used count */ - olduse = c->used; - - /* set the sign */ - c->sign = a->sign; - - /* alias for a->dp [source] */ - tmpa = a->dp; - - /* alias for c->dp [dest] */ - tmpc = c->dp; - - /* zero carry */ - u = 0; - - /* compute columns */ - for (ix = 0; ix < a->used; ix++) { - /* compute product and carry sum for this term */ - r = ((mp_word) u) + ((mp_word)*tmpa++) * ((mp_word)b); - - /* mask off higher bits to get a single digit */ - *tmpc++ = (mp_digit) (r & ((mp_word) MP_MASK)); - - /* send carry into next iteration */ - u = (mp_digit) (r >> ((mp_word) DIGIT_BIT)); - } - - /* store final carry [if any] and increment ix offset */ - *tmpc++ = u; - ++ix; - - /* now zero digits above the top */ - while (ix++ < olduse) { - *tmpc++ = 0; - } - - /* set used count */ - c->used = a->used + 1; - mp_clamp(c); - - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_mul_d.c */ - -/* Start: bn_mp_mulmod.c */ -#include -#ifdef BN_MP_MULMOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* d = a * b (mod c) */ -int mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) -{ - int res; - mp_int t; - - if ((res = mp_init (&t)) != MP_OKAY) { - return res; - } - - if ((res = mp_mul (a, b, &t)) != MP_OKAY) { - mp_clear (&t); - return res; - } - res = mp_mod (&t, c, d); - mp_clear (&t); - return res; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_mulmod.c */ - -/* Start: bn_mp_n_root.c */ -#include -#ifdef BN_MP_N_ROOT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* find the n'th root of an integer - * - * Result found such that (c)**b <= a and (c+1)**b > a - * - * This algorithm uses Newton's approximation - * x[i+1] = x[i] - f(x[i])/f'(x[i]) - * which will find the root in log(N) time where - * each step involves a fair bit. This is not meant to - * find huge roots [square and cube, etc]. - */ -int mp_n_root (mp_int * a, mp_digit b, mp_int * c) -{ - mp_int t1, t2, t3; - int res, neg; - - /* input must be positive if b is even */ - if ((b & 1) == 0 && a->sign == MP_NEG) { - return MP_VAL; - } - - if ((res = mp_init (&t1)) != MP_OKAY) { - return res; - } - - if ((res = mp_init (&t2)) != MP_OKAY) { - goto LBL_T1; - } - - if ((res = mp_init (&t3)) != MP_OKAY) { - goto LBL_T2; - } - - /* if a is negative fudge the sign but keep track */ - neg = a->sign; - a->sign = MP_ZPOS; - - /* t2 = 2 */ - mp_set (&t2, 2); - - do { - /* t1 = t2 */ - if ((res = mp_copy (&t2, &t1)) != MP_OKAY) { - goto LBL_T3; - } - - /* t2 = t1 - ((t1**b - a) / (b * t1**(b-1))) */ - - /* t3 = t1**(b-1) */ - if ((res = mp_expt_d (&t1, b - 1, &t3)) != MP_OKAY) { - goto LBL_T3; - } - - /* numerator */ - /* t2 = t1**b */ - if ((res = mp_mul (&t3, &t1, &t2)) != MP_OKAY) { - goto LBL_T3; - } - - /* t2 = t1**b - a */ - if ((res = mp_sub (&t2, a, &t2)) != MP_OKAY) { - goto LBL_T3; - } - - /* denominator */ - /* t3 = t1**(b-1) * b */ - if ((res = mp_mul_d (&t3, b, &t3)) != MP_OKAY) { - goto LBL_T3; - } - - /* t3 = (t1**b - a)/(b * t1**(b-1)) */ - if ((res = mp_div (&t2, &t3, &t3, NULL)) != MP_OKAY) { - goto LBL_T3; - } - - if ((res = mp_sub (&t1, &t3, &t2)) != MP_OKAY) { - goto LBL_T3; - } - } while (mp_cmp (&t1, &t2) != MP_EQ); - - /* result can be off by a few so check */ - for (;;) { - if ((res = mp_expt_d (&t1, b, &t2)) != MP_OKAY) { - goto LBL_T3; - } - - if (mp_cmp (&t2, a) == MP_GT) { - if ((res = mp_sub_d (&t1, 1, &t1)) != MP_OKAY) { - goto LBL_T3; - } - } else { - break; - } - } - - /* reset the sign of a first */ - a->sign = neg; - - /* set the result */ - mp_exch (&t1, c); - - /* set the sign of the result */ - c->sign = neg; - - res = MP_OKAY; - -LBL_T3:mp_clear (&t3); -LBL_T2:mp_clear (&t2); -LBL_T1:mp_clear (&t1); - return res; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_n_root.c */ - -/* Start: bn_mp_neg.c */ -#include -#ifdef BN_MP_NEG_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* b = -a */ -int mp_neg (mp_int * a, mp_int * b) -{ - int res; - if (a != b) { - if ((res = mp_copy (a, b)) != MP_OKAY) { - return res; - } - } - - if (mp_iszero(b) != MP_YES) { - b->sign = (a->sign == MP_ZPOS) ? MP_NEG : MP_ZPOS; - } else { - b->sign = MP_ZPOS; - } - - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_neg.c */ - -/* Start: bn_mp_or.c */ -#include -#ifdef BN_MP_OR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* OR two ints together */ -int mp_or (mp_int * a, mp_int * b, mp_int * c) -{ - int res, ix, px; - mp_int t, *x; - - if (a->used > b->used) { - if ((res = mp_init_copy (&t, a)) != MP_OKAY) { - return res; - } - px = b->used; - x = b; - } else { - if ((res = mp_init_copy (&t, b)) != MP_OKAY) { - return res; - } - px = a->used; - x = a; - } - - for (ix = 0; ix < px; ix++) { - t.dp[ix] |= x->dp[ix]; - } - mp_clamp (&t); - mp_exch (c, &t); - mp_clear (&t); - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_or.c */ - -/* Start: bn_mp_prime_fermat.c */ -#include -#ifdef BN_MP_PRIME_FERMAT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* performs one Fermat test. - * - * If "a" were prime then b**a == b (mod a) since the order of - * the multiplicative sub-group would be phi(a) = a-1. That means - * it would be the same as b**(a mod (a-1)) == b**1 == b (mod a). - * - * Sets result to 1 if the congruence holds, or zero otherwise. - */ -int mp_prime_fermat (mp_int * a, mp_int * b, int *result) -{ - mp_int t; - int err; - - /* default to composite */ - *result = MP_NO; - - /* ensure b > 1 */ - if (mp_cmp_d(b, 1) != MP_GT) { - return MP_VAL; - } - - /* init t */ - if ((err = mp_init (&t)) != MP_OKAY) { - return err; - } - - /* compute t = b**a mod a */ - if ((err = mp_exptmod (b, a, a, &t)) != MP_OKAY) { - goto LBL_T; - } - - /* is it equal to b? */ - if (mp_cmp (&t, b) == MP_EQ) { - *result = MP_YES; - } - - err = MP_OKAY; -LBL_T:mp_clear (&t); - return err; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_prime_fermat.c */ - -/* Start: bn_mp_prime_is_divisible.c */ -#include -#ifdef BN_MP_PRIME_IS_DIVISIBLE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* determines if an integers is divisible by one - * of the first PRIME_SIZE primes or not - * - * sets result to 0 if not, 1 if yes - */ -int mp_prime_is_divisible (mp_int * a, int *result) -{ - int err, ix; - mp_digit res; - - /* default to not */ - *result = MP_NO; - - for (ix = 0; ix < PRIME_SIZE; ix++) { - /* what is a mod LBL_prime_tab[ix] */ - if ((err = mp_mod_d (a, ltm_prime_tab[ix], &res)) != MP_OKAY) { - return err; - } - - /* is the residue zero? */ - if (res == 0) { - *result = MP_YES; - return MP_OKAY; - } - } - - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_prime_is_divisible.c */ - -/* Start: bn_mp_prime_is_prime.c */ -#include -#ifdef BN_MP_PRIME_IS_PRIME_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* performs a variable number of rounds of Miller-Rabin - * - * Probability of error after t rounds is no more than - - * - * Sets result to 1 if probably prime, 0 otherwise - */ -int mp_prime_is_prime (mp_int * a, int t, int *result) -{ - mp_int b; - int ix, err, res; - - /* default to no */ - *result = MP_NO; - - /* valid value of t? */ - if (t <= 0 || t > PRIME_SIZE) { - return MP_VAL; - } - - /* is the input equal to one of the primes in the table? */ - for (ix = 0; ix < PRIME_SIZE; ix++) { - if (mp_cmp_d(a, ltm_prime_tab[ix]) == MP_EQ) { - *result = 1; - return MP_OKAY; - } - } - - /* first perform trial division */ - if ((err = mp_prime_is_divisible (a, &res)) != MP_OKAY) { - return err; - } - - /* return if it was trivially divisible */ - if (res == MP_YES) { - return MP_OKAY; - } - - /* now perform the miller-rabin rounds */ - if ((err = mp_init (&b)) != MP_OKAY) { - return err; - } - - for (ix = 0; ix < t; ix++) { - /* set the prime */ - mp_set (&b, ltm_prime_tab[ix]); - - if ((err = mp_prime_miller_rabin (a, &b, &res)) != MP_OKAY) { - goto LBL_B; - } - - if (res == MP_NO) { - goto LBL_B; - } - } - - /* passed the test */ - *result = MP_YES; -LBL_B:mp_clear (&b); - return err; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_prime_is_prime.c */ - -/* Start: bn_mp_prime_miller_rabin.c */ -#include -#ifdef BN_MP_PRIME_MILLER_RABIN_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* Miller-Rabin test of "a" to the base of "b" as described in - * HAC pp. 139 Algorithm 4.24 - * - * Sets result to 0 if definitely composite or 1 if probably prime. - * Randomly the chance of error is no more than 1/4 and often - * very much lower. - */ -int mp_prime_miller_rabin (mp_int * a, mp_int * b, int *result) -{ - mp_int n1, y, r; - int s, j, err; - - /* default */ - *result = MP_NO; - - /* ensure b > 1 */ - if (mp_cmp_d(b, 1) != MP_GT) { - return MP_VAL; - } - - /* get n1 = a - 1 */ - if ((err = mp_init_copy (&n1, a)) != MP_OKAY) { - return err; - } - if ((err = mp_sub_d (&n1, 1, &n1)) != MP_OKAY) { - goto LBL_N1; - } - - /* set 2**s * r = n1 */ - if ((err = mp_init_copy (&r, &n1)) != MP_OKAY) { - goto LBL_N1; - } - - /* count the number of least significant bits - * which are zero - */ - s = mp_cnt_lsb(&r); - - /* now divide n - 1 by 2**s */ - if ((err = mp_div_2d (&r, s, &r, NULL)) != MP_OKAY) { - goto LBL_R; - } - - /* compute y = b**r mod a */ - if ((err = mp_init (&y)) != MP_OKAY) { - goto LBL_R; - } - if ((err = mp_exptmod (b, &r, a, &y)) != MP_OKAY) { - goto LBL_Y; - } - - /* if y != 1 and y != n1 do */ - if (mp_cmp_d (&y, 1) != MP_EQ && mp_cmp (&y, &n1) != MP_EQ) { - j = 1; - /* while j <= s-1 and y != n1 */ - while ((j <= (s - 1)) && mp_cmp (&y, &n1) != MP_EQ) { - if ((err = mp_sqrmod (&y, a, &y)) != MP_OKAY) { - goto LBL_Y; - } - - /* if y == 1 then composite */ - if (mp_cmp_d (&y, 1) == MP_EQ) { - goto LBL_Y; - } - - ++j; - } - - /* if y != n1 then composite */ - if (mp_cmp (&y, &n1) != MP_EQ) { - goto LBL_Y; - } - } - - /* probably prime now */ - *result = MP_YES; -LBL_Y:mp_clear (&y); -LBL_R:mp_clear (&r); -LBL_N1:mp_clear (&n1); - return err; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_prime_miller_rabin.c */ - -/* Start: bn_mp_prime_next_prime.c */ -#include -#ifdef BN_MP_PRIME_NEXT_PRIME_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* finds the next prime after the number "a" using "t" trials - * of Miller-Rabin. - * - * bbs_style = 1 means the prime must be congruent to 3 mod 4 - */ -int mp_prime_next_prime(mp_int *a, int t, int bbs_style) -{ - int err, res, x, y; - mp_digit res_tab[PRIME_SIZE], step, kstep; - mp_int b; - - /* ensure t is valid */ - if (t <= 0 || t > PRIME_SIZE) { - return MP_VAL; - } - - /* force positive */ - a->sign = MP_ZPOS; - - /* simple algo if a is less than the largest prime in the table */ - if (mp_cmp_d(a, ltm_prime_tab[PRIME_SIZE-1]) == MP_LT) { - /* find which prime it is bigger than */ - for (x = PRIME_SIZE - 2; x >= 0; x--) { - if (mp_cmp_d(a, ltm_prime_tab[x]) != MP_LT) { - if (bbs_style == 1) { - /* ok we found a prime smaller or - * equal [so the next is larger] - * - * however, the prime must be - * congruent to 3 mod 4 - */ - if ((ltm_prime_tab[x + 1] & 3) != 3) { - /* scan upwards for a prime congruent to 3 mod 4 */ - for (y = x + 1; y < PRIME_SIZE; y++) { - if ((ltm_prime_tab[y] & 3) == 3) { - mp_set(a, ltm_prime_tab[y]); - return MP_OKAY; - } - } - } - } else { - mp_set(a, ltm_prime_tab[x + 1]); - return MP_OKAY; - } - } - } - /* at this point a maybe 1 */ - if (mp_cmp_d(a, 1) == MP_EQ) { - mp_set(a, 2); - return MP_OKAY; - } - /* fall through to the sieve */ - } - - /* generate a prime congruent to 3 mod 4 or 1/3 mod 4? */ - if (bbs_style == 1) { - kstep = 4; - } else { - kstep = 2; - } - - /* at this point we will use a combination of a sieve and Miller-Rabin */ - - if (bbs_style == 1) { - /* if a mod 4 != 3 subtract the correct value to make it so */ - if ((a->dp[0] & 3) != 3) { - if ((err = mp_sub_d(a, (a->dp[0] & 3) + 1, a)) != MP_OKAY) { return err; }; - } - } else { - if (mp_iseven(a) == 1) { - /* force odd */ - if ((err = mp_sub_d(a, 1, a)) != MP_OKAY) { - return err; - } - } - } - - /* generate the restable */ - for (x = 1; x < PRIME_SIZE; x++) { - if ((err = mp_mod_d(a, ltm_prime_tab[x], res_tab + x)) != MP_OKAY) { - return err; - } - } - - /* init temp used for Miller-Rabin Testing */ - if ((err = mp_init(&b)) != MP_OKAY) { - return err; - } - - for (;;) { - /* skip to the next non-trivially divisible candidate */ - step = 0; - do { - /* y == 1 if any residue was zero [e.g. cannot be prime] */ - y = 0; - - /* increase step to next candidate */ - step += kstep; - - /* compute the new residue without using division */ - for (x = 1; x < PRIME_SIZE; x++) { - /* add the step to each residue */ - res_tab[x] += kstep; - - /* subtract the modulus [instead of using division] */ - if (res_tab[x] >= ltm_prime_tab[x]) { - res_tab[x] -= ltm_prime_tab[x]; - } - - /* set flag if zero */ - if (res_tab[x] == 0) { - y = 1; - } - } - } while (y == 1 && step < ((((mp_digit)1)<= ((((mp_digit)1)< -#ifdef BN_MP_PRIME_RABIN_MILLER_TRIALS_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - - -static const struct { - int k, t; -} sizes[] = { -{ 128, 28 }, -{ 256, 16 }, -{ 384, 10 }, -{ 512, 7 }, -{ 640, 6 }, -{ 768, 5 }, -{ 896, 4 }, -{ 1024, 4 } -}; - -/* returns # of RM trials required for a given bit size */ -int mp_prime_rabin_miller_trials(int size) -{ - int x; - - for (x = 0; x < (int)(sizeof(sizes)/(sizeof(sizes[0]))); x++) { - if (sizes[x].k == size) { - return sizes[x].t; - } else if (sizes[x].k > size) { - return (x == 0) ? sizes[0].t : sizes[x - 1].t; - } - } - return sizes[x-1].t + 1; -} - - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_prime_rabin_miller_trials.c */ - -/* Start: bn_mp_prime_random_ex.c */ -#include -#ifdef BN_MP_PRIME_RANDOM_EX_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* makes a truly random prime of a given size (bits), - * - * Flags are as follows: - * - * LTM_PRIME_BBS - make prime congruent to 3 mod 4 - * LTM_PRIME_SAFE - make sure (p-1)/2 is prime as well (implies LTM_PRIME_BBS) - * LTM_PRIME_2MSB_OFF - make the 2nd highest bit zero - * LTM_PRIME_2MSB_ON - make the 2nd highest bit one - * - * You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can - * have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself - * so it can be NULL - * - */ - -/* This is possibly the mother of all prime generation functions, muahahahahaha! */ -int mp_prime_random_ex(mp_int *a, int t, int size, int flags, ltm_prime_callback cb, void *dat) -{ - unsigned char *tmp, maskAND, maskOR_msb, maskOR_lsb; - int res, err, bsize, maskOR_msb_offset; - - /* sanity check the input */ - if (size <= 1 || t <= 0) { - return MP_VAL; - } - - /* LTM_PRIME_SAFE implies LTM_PRIME_BBS */ - if (flags & LTM_PRIME_SAFE) { - flags |= LTM_PRIME_BBS; - } - - /* calc the byte size */ - bsize = (size>>3) + ((size&7)?1:0); - - /* we need a buffer of bsize bytes */ - tmp = OPT_CAST(unsigned char) XMALLOC(bsize); - if (tmp == NULL) { - return MP_MEM; - } - - /* calc the maskAND value for the MSbyte*/ - maskAND = ((size&7) == 0) ? 0xFF : (0xFF >> (8 - (size & 7))); - - /* calc the maskOR_msb */ - maskOR_msb = 0; - maskOR_msb_offset = ((size & 7) == 1) ? 1 : 0; - if (flags & LTM_PRIME_2MSB_ON) { - maskOR_msb |= 0x80 >> ((9 - size) & 7); - } - - /* get the maskOR_lsb */ - maskOR_lsb = 1; - if (flags & LTM_PRIME_BBS) { - maskOR_lsb |= 3; - } - - do { - /* read the bytes */ - if (cb(tmp, bsize, dat) != bsize) { - err = MP_VAL; - goto error; - } - - /* work over the MSbyte */ - tmp[0] &= maskAND; - tmp[0] |= 1 << ((size - 1) & 7); - - /* mix in the maskORs */ - tmp[maskOR_msb_offset] |= maskOR_msb; - tmp[bsize-1] |= maskOR_lsb; - - /* read it in */ - if ((err = mp_read_unsigned_bin(a, tmp, bsize)) != MP_OKAY) { goto error; } - - /* is it prime? */ - if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY) { goto error; } - if (res == MP_NO) { - continue; - } - - if (flags & LTM_PRIME_SAFE) { - /* see if (a-1)/2 is prime */ - if ((err = mp_sub_d(a, 1, a)) != MP_OKAY) { goto error; } - if ((err = mp_div_2(a, a)) != MP_OKAY) { goto error; } - - /* is it prime? */ - if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY) { goto error; } - } - } while (res == MP_NO); - - if (flags & LTM_PRIME_SAFE) { - /* restore a to the original value */ - if ((err = mp_mul_2(a, a)) != MP_OKAY) { goto error; } - if ((err = mp_add_d(a, 1, a)) != MP_OKAY) { goto error; } - } - - err = MP_OKAY; -error: - XFREE(tmp); - return err; -} - - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_prime_random_ex.c */ - -/* Start: bn_mp_radix_size.c */ -#include -#ifdef BN_MP_RADIX_SIZE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* returns size of ASCII reprensentation */ -int mp_radix_size (mp_int * a, int radix, int *size) -{ - int res, digs; - mp_int t; - mp_digit d; - - *size = 0; - - /* special case for binary */ - if (radix == 2) { - *size = mp_count_bits (a) + (a->sign == MP_NEG ? 1 : 0) + 1; - return MP_OKAY; - } - - /* make sure the radix is in range */ - if (radix < 2 || radix > 64) { - return MP_VAL; - } - - if (mp_iszero(a) == MP_YES) { - *size = 2; - return MP_OKAY; - } - - /* digs is the digit count */ - digs = 0; - - /* if it's negative add one for the sign */ - if (a->sign == MP_NEG) { - ++digs; - } - - /* init a copy of the input */ - if ((res = mp_init_copy (&t, a)) != MP_OKAY) { - return res; - } - - /* force temp to positive */ - t.sign = MP_ZPOS; - - /* fetch out all of the digits */ - while (mp_iszero (&t) == MP_NO) { - if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) { - mp_clear (&t); - return res; - } - ++digs; - } - mp_clear (&t); - - /* return digs + 1, the 1 is for the NULL byte that would be required. */ - *size = digs + 1; - return MP_OKAY; -} - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_radix_size.c */ - -/* Start: bn_mp_radix_smap.c */ -#include -#ifdef BN_MP_RADIX_SMAP_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* chars used in radix conversions */ -const char *mp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/"; -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_radix_smap.c */ - -/* Start: bn_mp_rand.c */ -#include -#ifdef BN_MP_RAND_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* makes a pseudo-random int of a given size */ -int -mp_rand (mp_int * a, int digits) -{ - int res; - mp_digit d; - - mp_zero (a); - if (digits <= 0) { - return MP_OKAY; - } - - /* first place a random non-zero digit */ - do { - d = ((mp_digit) abs (rand ())) & MP_MASK; - } while (d == 0); - - if ((res = mp_add_d (a, d, a)) != MP_OKAY) { - return res; - } - - while (--digits > 0) { - if ((res = mp_lshd (a, 1)) != MP_OKAY) { - return res; - } - - if ((res = mp_add_d (a, ((mp_digit) abs (rand ())), a)) != MP_OKAY) { - return res; - } - } - - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_rand.c */ - -/* Start: bn_mp_read_radix.c */ -#include -#ifdef BN_MP_READ_RADIX_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* read a string [ASCII] in a given radix */ -int mp_read_radix (mp_int * a, const char *str, int radix) -{ - int y, res, neg; - char ch; - - /* zero the digit bignum */ - mp_zero(a); - - /* make sure the radix is ok */ - if (radix < 2 || radix > 64) { - return MP_VAL; - } - - /* if the leading digit is a - * minus set the sign to negative. - */ - if (*str == '-') { - ++str; - neg = MP_NEG; - } else { - neg = MP_ZPOS; - } - - /* set the integer to the default of zero */ - mp_zero (a); - - /* process each digit of the string */ - while (*str) { - /* if the radix < 36 the conversion is case insensitive - * this allows numbers like 1AB and 1ab to represent the same value - * [e.g. in hex] - */ - ch = (char) ((radix < 36) ? toupper (*str) : *str); - for (y = 0; y < 64; y++) { - if (ch == mp_s_rmap[y]) { - break; - } - } - - /* if the char was found in the map - * and is less than the given radix add it - * to the number, otherwise exit the loop. - */ - if (y < radix) { - if ((res = mp_mul_d (a, (mp_digit) radix, a)) != MP_OKAY) { - return res; - } - if ((res = mp_add_d (a, (mp_digit) y, a)) != MP_OKAY) { - return res; - } - } else { - break; - } - ++str; - } - - /* set the sign only if a != 0 */ - if (mp_iszero(a) != 1) { - a->sign = neg; - } - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_read_radix.c */ - -/* Start: bn_mp_read_signed_bin.c */ -#include -#ifdef BN_MP_READ_SIGNED_BIN_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* read signed bin, big endian, first byte is 0==positive or 1==negative */ -int mp_read_signed_bin (mp_int * a, const unsigned char *b, int c) -{ - int res; - - /* read magnitude */ - if ((res = mp_read_unsigned_bin (a, b + 1, c - 1)) != MP_OKAY) { - return res; - } - - /* first byte is 0 for positive, non-zero for negative */ - if (b[0] == 0) { - a->sign = MP_ZPOS; - } else { - a->sign = MP_NEG; - } - - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_read_signed_bin.c */ - -/* Start: bn_mp_read_unsigned_bin.c */ -#include -#ifdef BN_MP_READ_UNSIGNED_BIN_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* reads a unsigned char array, assumes the msb is stored first [big endian] */ -int mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c) -{ - int res; - - /* make sure there are at least two digits */ - if (a->alloc < 2) { - if ((res = mp_grow(a, 2)) != MP_OKAY) { - return res; - } - } - - /* zero the int */ - mp_zero (a); - - /* read the bytes in */ - while (c-- > 0) { - if ((res = mp_mul_2d (a, 8, a)) != MP_OKAY) { - return res; - } - -#ifndef MP_8BIT - a->dp[0] |= *b++; - a->used += 1; -#else - a->dp[0] = (*b & MP_MASK); - a->dp[1] |= ((*b++ >> 7U) & 1); - a->used += 2; -#endif - } - mp_clamp (a); - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_read_unsigned_bin.c */ - -/* Start: bn_mp_reduce.c */ -#include -#ifdef BN_MP_REDUCE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* reduces x mod m, assumes 0 < x < m**2, mu is - * precomputed via mp_reduce_setup. - * From HAC pp.604 Algorithm 14.42 - */ -int mp_reduce (mp_int * x, mp_int * m, mp_int * mu) -{ - mp_int q; - int res, um = m->used; - - /* q = x */ - if ((res = mp_init_copy (&q, x)) != MP_OKAY) { - return res; - } - - /* q1 = x / b**(k-1) */ - mp_rshd (&q, um - 1); - - /* according to HAC this optimization is ok */ - if (((unsigned long) um) > (((mp_digit)1) << (DIGIT_BIT - 1))) { - if ((res = mp_mul (&q, mu, &q)) != MP_OKAY) { - goto CLEANUP; - } - } else { -#ifdef BN_S_MP_MUL_HIGH_DIGS_C - if ((res = s_mp_mul_high_digs (&q, mu, &q, um)) != MP_OKAY) { - goto CLEANUP; - } -#elif defined(BN_FAST_S_MP_MUL_HIGH_DIGS_C) - if ((res = fast_s_mp_mul_high_digs (&q, mu, &q, um)) != MP_OKAY) { - goto CLEANUP; - } -#else - { - res = MP_VAL; - goto CLEANUP; - } -#endif - } - - /* q3 = q2 / b**(k+1) */ - mp_rshd (&q, um + 1); - - /* x = x mod b**(k+1), quick (no division) */ - if ((res = mp_mod_2d (x, DIGIT_BIT * (um + 1), x)) != MP_OKAY) { - goto CLEANUP; - } - - /* q = q * m mod b**(k+1), quick (no division) */ - if ((res = s_mp_mul_digs (&q, m, &q, um + 1)) != MP_OKAY) { - goto CLEANUP; - } - - /* x = x - q */ - if ((res = mp_sub (x, &q, x)) != MP_OKAY) { - goto CLEANUP; - } - - /* If x < 0, add b**(k+1) to it */ - if (mp_cmp_d (x, 0) == MP_LT) { - mp_set (&q, 1); - if ((res = mp_lshd (&q, um + 1)) != MP_OKAY) - goto CLEANUP; - if ((res = mp_add (x, &q, x)) != MP_OKAY) - goto CLEANUP; - } - - /* Back off if it's too big */ - while (mp_cmp (x, m) != MP_LT) { - if ((res = s_mp_sub (x, m, x)) != MP_OKAY) { - goto CLEANUP; - } - } - -CLEANUP: - mp_clear (&q); - - return res; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_reduce.c */ - -/* Start: bn_mp_reduce_2k.c */ -#include -#ifdef BN_MP_REDUCE_2K_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* reduces a modulo n where n is of the form 2**p - d */ -int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d) -{ - mp_int q; - int p, res; - - if ((res = mp_init(&q)) != MP_OKAY) { - return res; - } - - p = mp_count_bits(n); -top: - /* q = a/2**p, a = a mod 2**p */ - if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) { - goto ERR; - } - - if (d != 1) { - /* q = q * d */ - if ((res = mp_mul_d(&q, d, &q)) != MP_OKAY) { - goto ERR; - } - } - - /* a = a + q */ - if ((res = s_mp_add(a, &q, a)) != MP_OKAY) { - goto ERR; - } - - if (mp_cmp_mag(a, n) != MP_LT) { - s_mp_sub(a, n, a); - goto top; - } - -ERR: - mp_clear(&q); - return res; -} - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_reduce_2k.c */ - -/* Start: bn_mp_reduce_2k_l.c */ -#include -#ifdef BN_MP_REDUCE_2K_L_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* reduces a modulo n where n is of the form 2**p - d - This differs from reduce_2k since "d" can be larger - than a single digit. -*/ -int mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d) -{ - mp_int q; - int p, res; - - if ((res = mp_init(&q)) != MP_OKAY) { - return res; - } - - p = mp_count_bits(n); -top: - /* q = a/2**p, a = a mod 2**p */ - if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) { - goto ERR; - } - - /* q = q * d */ - if ((res = mp_mul(&q, d, &q)) != MP_OKAY) { - goto ERR; - } - - /* a = a + q */ - if ((res = s_mp_add(a, &q, a)) != MP_OKAY) { - goto ERR; - } - - if (mp_cmp_mag(a, n) != MP_LT) { - s_mp_sub(a, n, a); - goto top; - } - -ERR: - mp_clear(&q); - return res; -} - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_reduce_2k_l.c */ - -/* Start: bn_mp_reduce_2k_setup.c */ -#include -#ifdef BN_MP_REDUCE_2K_SETUP_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* determines the setup value */ -int mp_reduce_2k_setup(mp_int *a, mp_digit *d) -{ - int res, p; - mp_int tmp; - - if ((res = mp_init(&tmp)) != MP_OKAY) { - return res; - } - - p = mp_count_bits(a); - if ((res = mp_2expt(&tmp, p)) != MP_OKAY) { - mp_clear(&tmp); - return res; - } - - if ((res = s_mp_sub(&tmp, a, &tmp)) != MP_OKAY) { - mp_clear(&tmp); - return res; - } - - *d = tmp.dp[0]; - mp_clear(&tmp); - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_reduce_2k_setup.c */ - -/* Start: bn_mp_reduce_2k_setup_l.c */ -#include -#ifdef BN_MP_REDUCE_2K_SETUP_L_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* determines the setup value */ -int mp_reduce_2k_setup_l(mp_int *a, mp_int *d) -{ - int res; - mp_int tmp; - - if ((res = mp_init(&tmp)) != MP_OKAY) { - return res; - } - - if ((res = mp_2expt(&tmp, mp_count_bits(a))) != MP_OKAY) { - goto ERR; - } - - if ((res = s_mp_sub(&tmp, a, d)) != MP_OKAY) { - goto ERR; - } - -ERR: - mp_clear(&tmp); - return res; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_reduce_2k_setup_l.c */ - -/* Start: bn_mp_reduce_is_2k.c */ -#include -#ifdef BN_MP_REDUCE_IS_2K_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* determines if mp_reduce_2k can be used */ -int mp_reduce_is_2k(mp_int *a) -{ - int ix, iy, iw; - mp_digit iz; - - if (a->used == 0) { - return MP_NO; - } else if (a->used == 1) { - return MP_YES; - } else if (a->used > 1) { - iy = mp_count_bits(a); - iz = 1; - iw = 1; - - /* Test every bit from the second digit up, must be 1 */ - for (ix = DIGIT_BIT; ix < iy; ix++) { - if ((a->dp[iw] & iz) == 0) { - return MP_NO; - } - iz <<= 1; - if (iz > (mp_digit)MP_MASK) { - ++iw; - iz = 1; - } - } - } - return MP_YES; -} - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_reduce_is_2k.c */ - -/* Start: bn_mp_reduce_is_2k_l.c */ -#include -#ifdef BN_MP_REDUCE_IS_2K_L_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* determines if reduce_2k_l can be used */ -int mp_reduce_is_2k_l(mp_int *a) -{ - int ix, iy; - - if (a->used == 0) { - return MP_NO; - } else if (a->used == 1) { - return MP_YES; - } else if (a->used > 1) { - /* if more than half of the digits are -1 we're sold */ - for (iy = ix = 0; ix < a->used; ix++) { - if (a->dp[ix] == MP_MASK) { - ++iy; - } - } - return (iy >= (a->used/2)) ? MP_YES : MP_NO; - - } - return MP_NO; -} - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_reduce_is_2k_l.c */ - -/* Start: bn_mp_reduce_setup.c */ -#include -#ifdef BN_MP_REDUCE_SETUP_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* pre-calculate the value required for Barrett reduction - * For a given modulus "b" it calulates the value required in "a" - */ -int mp_reduce_setup (mp_int * a, mp_int * b) -{ - int res; - - if ((res = mp_2expt (a, b->used * 2 * DIGIT_BIT)) != MP_OKAY) { - return res; - } - return mp_div (a, b, a, NULL); -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_reduce_setup.c */ - -/* Start: bn_mp_rshd.c */ -#include -#ifdef BN_MP_RSHD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* shift right a certain amount of digits */ -void mp_rshd (mp_int * a, int b) -{ - int x; - - /* if b <= 0 then ignore it */ - if (b <= 0) { - return; - } - - /* if b > used then simply zero it and return */ - if (a->used <= b) { - mp_zero (a); - return; - } - - { - register mp_digit *bottom, *top; - - /* shift the digits down */ - - /* bottom */ - bottom = a->dp; - - /* top [offset into digits] */ - top = a->dp + b; - - /* this is implemented as a sliding window where - * the window is b-digits long and digits from - * the top of the window are copied to the bottom - * - * e.g. - - b-2 | b-1 | b0 | b1 | b2 | ... | bb | ----> - /\ | ----> - \-------------------/ ----> - */ - for (x = 0; x < (a->used - b); x++) { - *bottom++ = *top++; - } - - /* zero the top digits */ - for (; x < a->used; x++) { - *bottom++ = 0; - } - } - - /* remove excess digits */ - a->used -= b; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_rshd.c */ - -/* Start: bn_mp_set.c */ -#include -#ifdef BN_MP_SET_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* set to a digit */ -void mp_set (mp_int * a, mp_digit b) -{ - mp_zero (a); - a->dp[0] = b & MP_MASK; - a->used = (a->dp[0] != 0) ? 1 : 0; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_set.c */ - -/* Start: bn_mp_set_int.c */ -#include -#ifdef BN_MP_SET_INT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* set a 32-bit const */ -int mp_set_int (mp_int * a, unsigned long b) -{ - int x, res; - - mp_zero (a); - - /* set four bits at a time */ - for (x = 0; x < 8; x++) { - /* shift the number up four bits */ - if ((res = mp_mul_2d (a, 4, a)) != MP_OKAY) { - return res; - } - - /* OR in the top four bits of the source */ - a->dp[0] |= (b >> 28) & 15; - - /* shift the source up to the next four bits */ - b <<= 4; - - /* ensure that digits are not clamped off */ - a->used += 1; - } - mp_clamp (a); - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_set_int.c */ - -/* Start: bn_mp_shrink.c */ -#include -#ifdef BN_MP_SHRINK_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* shrink a bignum */ -int mp_shrink (mp_int * a) -{ - mp_digit *tmp; - int used = 1; - - if(a->used > 0) - used = a->used; - - if (a->alloc != used) { - if ((tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * used)) == NULL) { - return MP_MEM; - } - a->dp = tmp; - a->alloc = used; - } - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: v0.42.0 $ */ -/* $Date: 2010-06-02 15:09:36 +0200 $ */ - -/* End: bn_mp_shrink.c */ - -/* Start: bn_mp_signed_bin_size.c */ -#include -#ifdef BN_MP_SIGNED_BIN_SIZE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* get the size for an signed equivalent */ -int mp_signed_bin_size (mp_int * a) -{ - return 1 + mp_unsigned_bin_size (a); -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_signed_bin_size.c */ - -/* Start: bn_mp_sqr.c */ -#include -#ifdef BN_MP_SQR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* computes b = a*a */ -int -mp_sqr (mp_int * a, mp_int * b) -{ - int res; - -#ifdef BN_MP_TOOM_SQR_C - /* use Toom-Cook? */ - if (a->used >= TOOM_SQR_CUTOFF) { - res = mp_toom_sqr(a, b); - /* Karatsuba? */ - } else -#endif -#ifdef BN_MP_KARATSUBA_SQR_C -if (a->used >= KARATSUBA_SQR_CUTOFF) { - res = mp_karatsuba_sqr (a, b); - } else -#endif - { -#ifdef BN_FAST_S_MP_SQR_C - /* can we use the fast comba multiplier? */ - if ((a->used * 2 + 1) < MP_WARRAY && - a->used < - (1 << (sizeof(mp_word) * CHAR_BIT - 2*DIGIT_BIT - 1))) { - res = fast_s_mp_sqr (a, b); - } else -#endif -#ifdef BN_S_MP_SQR_C - res = s_mp_sqr (a, b); -#else - res = MP_VAL; -#endif - } - b->sign = MP_ZPOS; - return res; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_sqr.c */ - -/* Start: bn_mp_sqrmod.c */ -#include -#ifdef BN_MP_SQRMOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* c = a * a (mod b) */ -int -mp_sqrmod (mp_int * a, mp_int * b, mp_int * c) -{ - int res; - mp_int t; - - if ((res = mp_init (&t)) != MP_OKAY) { - return res; - } - - if ((res = mp_sqr (a, &t)) != MP_OKAY) { - mp_clear (&t); - return res; - } - res = mp_mod (&t, b, c); - mp_clear (&t); - return res; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_sqrmod.c */ - -/* Start: bn_mp_sqrt.c */ -#include -#ifdef BN_MP_SQRT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* this function is less generic than mp_n_root, simpler and faster */ -int mp_sqrt(mp_int *arg, mp_int *ret) -{ - int res; - mp_int t1,t2; - - /* must be positive */ - if (arg->sign == MP_NEG) { - return MP_VAL; - } - - /* easy out */ - if (mp_iszero(arg) == MP_YES) { - mp_zero(ret); - return MP_OKAY; - } - - if ((res = mp_init_copy(&t1, arg)) != MP_OKAY) { - return res; - } - - if ((res = mp_init(&t2)) != MP_OKAY) { - goto E2; - } - - /* First approx. (not very bad for large arg) */ - mp_rshd (&t1,t1.used/2); - - /* t1 > 0 */ - if ((res = mp_div(arg,&t1,&t2,NULL)) != MP_OKAY) { - goto E1; - } - if ((res = mp_add(&t1,&t2,&t1)) != MP_OKAY) { - goto E1; - } - if ((res = mp_div_2(&t1,&t1)) != MP_OKAY) { - goto E1; - } - /* And now t1 > sqrt(arg) */ - do { - if ((res = mp_div(arg,&t1,&t2,NULL)) != MP_OKAY) { - goto E1; - } - if ((res = mp_add(&t1,&t2,&t1)) != MP_OKAY) { - goto E1; - } - if ((res = mp_div_2(&t1,&t1)) != MP_OKAY) { - goto E1; - } - /* t1 >= sqrt(arg) >= t2 at this point */ - } while (mp_cmp_mag(&t1,&t2) == MP_GT); - - mp_exch(&t1,ret); - -E1: mp_clear(&t2); -E2: mp_clear(&t1); - return res; -} - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_sqrt.c */ - -/* Start: bn_mp_sub.c */ -#include -#ifdef BN_MP_SUB_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* high level subtraction (handles signs) */ -int -mp_sub (mp_int * a, mp_int * b, mp_int * c) -{ - int sa, sb, res; - - sa = a->sign; - sb = b->sign; - - if (sa != sb) { - /* subtract a negative from a positive, OR */ - /* subtract a positive from a negative. */ - /* In either case, ADD their magnitudes, */ - /* and use the sign of the first number. */ - c->sign = sa; - res = s_mp_add (a, b, c); - } else { - /* subtract a positive from a positive, OR */ - /* subtract a negative from a negative. */ - /* First, take the difference between their */ - /* magnitudes, then... */ - if (mp_cmp_mag (a, b) != MP_LT) { - /* Copy the sign from the first */ - c->sign = sa; - /* The first has a larger or equal magnitude */ - res = s_mp_sub (a, b, c); - } else { - /* The result has the *opposite* sign from */ - /* the first number. */ - c->sign = (sa == MP_ZPOS) ? MP_NEG : MP_ZPOS; - /* The second has a larger magnitude */ - res = s_mp_sub (b, a, c); - } - } - return res; -} - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_sub.c */ - -/* Start: bn_mp_sub_d.c */ -#include -#ifdef BN_MP_SUB_D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* single digit subtraction */ -int -mp_sub_d (mp_int * a, mp_digit b, mp_int * c) -{ - mp_digit *tmpa, *tmpc, mu; - int res, ix, oldused; - - /* grow c as required */ - if (c->alloc < a->used + 1) { - if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) { - return res; - } - } - - /* if a is negative just do an unsigned - * addition [with fudged signs] - */ - if (a->sign == MP_NEG) { - a->sign = MP_ZPOS; - res = mp_add_d(a, b, c); - a->sign = c->sign = MP_NEG; - - /* clamp */ - mp_clamp(c); - - return res; - } - - /* setup regs */ - oldused = c->used; - tmpa = a->dp; - tmpc = c->dp; - - /* if a <= b simply fix the single digit */ - if ((a->used == 1 && a->dp[0] <= b) || a->used == 0) { - if (a->used == 1) { - *tmpc++ = b - *tmpa; - } else { - *tmpc++ = b; - } - ix = 1; - - /* negative/1digit */ - c->sign = MP_NEG; - c->used = 1; - } else { - /* positive/size */ - c->sign = MP_ZPOS; - c->used = a->used; - - /* subtract first digit */ - *tmpc = *tmpa++ - b; - mu = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1); - *tmpc++ &= MP_MASK; - - /* handle rest of the digits */ - for (ix = 1; ix < a->used; ix++) { - *tmpc = *tmpa++ - mu; - mu = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1); - *tmpc++ &= MP_MASK; - } - } - - /* zero excess digits */ - while (ix++ < oldused) { - *tmpc++ = 0; - } - mp_clamp(c); - return MP_OKAY; -} - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_sub_d.c */ - -/* Start: bn_mp_submod.c */ -#include -#ifdef BN_MP_SUBMOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* d = a - b (mod c) */ -int -mp_submod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) -{ - int res; - mp_int t; - - - if ((res = mp_init (&t)) != MP_OKAY) { - return res; - } - - if ((res = mp_sub (a, b, &t)) != MP_OKAY) { - mp_clear (&t); - return res; - } - res = mp_mod (&t, c, d); - mp_clear (&t); - return res; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_submod.c */ - -/* Start: bn_mp_to_signed_bin.c */ -#include -#ifdef BN_MP_TO_SIGNED_BIN_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* store in signed [big endian] format */ -int mp_to_signed_bin (mp_int * a, unsigned char *b) -{ - int res; - - if ((res = mp_to_unsigned_bin (a, b + 1)) != MP_OKAY) { - return res; - } - b[0] = (unsigned char) ((a->sign == MP_ZPOS) ? 0 : 1); - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_to_signed_bin.c */ - -/* Start: bn_mp_to_signed_bin_n.c */ -#include -#ifdef BN_MP_TO_SIGNED_BIN_N_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* store in signed [big endian] format */ -int mp_to_signed_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen) -{ - if (*outlen < (unsigned long)mp_signed_bin_size(a)) { - return MP_VAL; - } - *outlen = mp_signed_bin_size(a); - return mp_to_signed_bin(a, b); -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_to_signed_bin_n.c */ - -/* Start: bn_mp_to_unsigned_bin.c */ -#include -#ifdef BN_MP_TO_UNSIGNED_BIN_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* store in unsigned [big endian] format */ -int mp_to_unsigned_bin (mp_int * a, unsigned char *b) -{ - int x, res; - mp_int t; - - if ((res = mp_init_copy (&t, a)) != MP_OKAY) { - return res; - } - - x = 0; - while (mp_iszero (&t) == 0) { -#ifndef MP_8BIT - b[x++] = (unsigned char) (t.dp[0] & 255); -#else - b[x++] = (unsigned char) (t.dp[0] | ((t.dp[1] & 0x01) << 7)); -#endif - if ((res = mp_div_2d (&t, 8, &t, NULL)) != MP_OKAY) { - mp_clear (&t); - return res; - } - } - bn_reverse (b, x); - mp_clear (&t); - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_to_unsigned_bin.c */ - -/* Start: bn_mp_to_unsigned_bin_n.c */ -#include -#ifdef BN_MP_TO_UNSIGNED_BIN_N_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* store in unsigned [big endian] format */ -int mp_to_unsigned_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen) -{ - if (*outlen < (unsigned long)mp_unsigned_bin_size(a)) { - return MP_VAL; - } - *outlen = mp_unsigned_bin_size(a); - return mp_to_unsigned_bin(a, b); -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_to_unsigned_bin_n.c */ - -/* Start: bn_mp_toom_mul.c */ -#include -#ifdef BN_MP_TOOM_MUL_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* multiplication using the Toom-Cook 3-way algorithm - * - * Much more complicated than Karatsuba but has a lower - * asymptotic running time of O(N**1.464). This algorithm is - * only particularly useful on VERY large inputs - * (we're talking 1000s of digits here...). -*/ -int mp_toom_mul(mp_int *a, mp_int *b, mp_int *c) -{ - mp_int w0, w1, w2, w3, w4, tmp1, tmp2, a0, a1, a2, b0, b1, b2; - int res, B; - - /* init temps */ - if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, - &a0, &a1, &a2, &b0, &b1, - &b2, &tmp1, &tmp2, NULL)) != MP_OKAY) { - return res; - } - - /* B */ - B = MIN(a->used, b->used) / 3; - - /* a = a2 * B**2 + a1 * B + a0 */ - if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_copy(a, &a1)) != MP_OKAY) { - goto ERR; - } - mp_rshd(&a1, B); - mp_mod_2d(&a1, DIGIT_BIT * B, &a1); - - if ((res = mp_copy(a, &a2)) != MP_OKAY) { - goto ERR; - } - mp_rshd(&a2, B*2); - - /* b = b2 * B**2 + b1 * B + b0 */ - if ((res = mp_mod_2d(b, DIGIT_BIT * B, &b0)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_copy(b, &b1)) != MP_OKAY) { - goto ERR; - } - mp_rshd(&b1, B); - mp_mod_2d(&b1, DIGIT_BIT * B, &b1); - - if ((res = mp_copy(b, &b2)) != MP_OKAY) { - goto ERR; - } - mp_rshd(&b2, B*2); - - /* w0 = a0*b0 */ - if ((res = mp_mul(&a0, &b0, &w0)) != MP_OKAY) { - goto ERR; - } - - /* w4 = a2 * b2 */ - if ((res = mp_mul(&a2, &b2, &w4)) != MP_OKAY) { - goto ERR; - } - - /* w1 = (a2 + 2(a1 + 2a0))(b2 + 2(b1 + 2b0)) */ - if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_mul_2(&b0, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp2, &b2, &tmp2)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_mul(&tmp1, &tmp2, &w1)) != MP_OKAY) { - goto ERR; - } - - /* w3 = (a0 + 2(a1 + 2a2))(b0 + 2(b1 + 2b2)) */ - if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_mul_2(&b2, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_mul(&tmp1, &tmp2, &w3)) != MP_OKAY) { - goto ERR; - } - - - /* w2 = (a2 + a1 + a0)(b2 + b1 + b0) */ - if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&b2, &b1, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul(&tmp1, &tmp2, &w2)) != MP_OKAY) { - goto ERR; - } - - /* now solve the matrix - - 0 0 0 0 1 - 1 2 4 8 16 - 1 1 1 1 1 - 16 8 4 2 1 - 1 0 0 0 0 - - using 12 subtractions, 4 shifts, - 2 small divisions and 1 small multiplication - */ - - /* r1 - r4 */ - if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - r0 */ - if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) { - goto ERR; - } - /* r1/2 */ - if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3/2 */ - if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) { - goto ERR; - } - /* r2 - r0 - r4 */ - if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) { - goto ERR; - } - /* r1 - r2 */ - if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - r2 */ - if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { - goto ERR; - } - /* r1 - 8r0 */ - if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - 8r4 */ - if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) { - goto ERR; - } - /* 3r2 - r1 - r3 */ - if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) { - goto ERR; - } - /* r1 - r2 */ - if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - r2 */ - if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { - goto ERR; - } - /* r1/3 */ - if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) { - goto ERR; - } - /* r3/3 */ - if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) { - goto ERR; - } - - /* at this point shift W[n] by B*n */ - if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_add(&w0, &w1, c)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, c, c)) != MP_OKAY) { - goto ERR; - } - -ERR: - mp_clear_multi(&w0, &w1, &w2, &w3, &w4, - &a0, &a1, &a2, &b0, &b1, - &b2, &tmp1, &tmp2, NULL); - return res; -} - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_toom_mul.c */ - -/* Start: bn_mp_toom_sqr.c */ -#include -#ifdef BN_MP_TOOM_SQR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* squaring using Toom-Cook 3-way algorithm */ -int -mp_toom_sqr(mp_int *a, mp_int *b) -{ - mp_int w0, w1, w2, w3, w4, tmp1, a0, a1, a2; - int res, B; - - /* init temps */ - if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL)) != MP_OKAY) { - return res; - } - - /* B */ - B = a->used / 3; - - /* a = a2 * B**2 + a1 * B + a0 */ - if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_copy(a, &a1)) != MP_OKAY) { - goto ERR; - } - mp_rshd(&a1, B); - mp_mod_2d(&a1, DIGIT_BIT * B, &a1); - - if ((res = mp_copy(a, &a2)) != MP_OKAY) { - goto ERR; - } - mp_rshd(&a2, B*2); - - /* w0 = a0*a0 */ - if ((res = mp_sqr(&a0, &w0)) != MP_OKAY) { - goto ERR; - } - - /* w4 = a2 * a2 */ - if ((res = mp_sqr(&a2, &w4)) != MP_OKAY) { - goto ERR; - } - - /* w1 = (a2 + 2(a1 + 2a0))**2 */ - if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_sqr(&tmp1, &w1)) != MP_OKAY) { - goto ERR; - } - - /* w3 = (a0 + 2(a1 + 2a2))**2 */ - if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_sqr(&tmp1, &w3)) != MP_OKAY) { - goto ERR; - } - - - /* w2 = (a2 + a1 + a0)**2 */ - if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sqr(&tmp1, &w2)) != MP_OKAY) { - goto ERR; - } - - /* now solve the matrix - - 0 0 0 0 1 - 1 2 4 8 16 - 1 1 1 1 1 - 16 8 4 2 1 - 1 0 0 0 0 - - using 12 subtractions, 4 shifts, 2 small divisions and 1 small multiplication. - */ - - /* r1 - r4 */ - if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - r0 */ - if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) { - goto ERR; - } - /* r1/2 */ - if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3/2 */ - if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) { - goto ERR; - } - /* r2 - r0 - r4 */ - if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) { - goto ERR; - } - /* r1 - r2 */ - if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - r2 */ - if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { - goto ERR; - } - /* r1 - 8r0 */ - if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - 8r4 */ - if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) { - goto ERR; - } - /* 3r2 - r1 - r3 */ - if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) { - goto ERR; - } - /* r1 - r2 */ - if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - r2 */ - if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { - goto ERR; - } - /* r1/3 */ - if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) { - goto ERR; - } - /* r3/3 */ - if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) { - goto ERR; - } - - /* at this point shift W[n] by B*n */ - if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_add(&w0, &w1, b)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, b, b)) != MP_OKAY) { - goto ERR; - } - -ERR: - mp_clear_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL); - return res; -} - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_toom_sqr.c */ - -/* Start: bn_mp_toradix.c */ -#include -#ifdef BN_MP_TORADIX_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* stores a bignum as a ASCII string in a given radix (2..64) */ -int mp_toradix (mp_int * a, char *str, int radix) -{ - int res, digs; - mp_int t; - mp_digit d; - char *_s = str; - - /* check range of the radix */ - if (radix < 2 || radix > 64) { - return MP_VAL; - } - - /* quick out if its zero */ - if (mp_iszero(a) == 1) { - *str++ = '0'; - *str = '\0'; - return MP_OKAY; - } - - if ((res = mp_init_copy (&t, a)) != MP_OKAY) { - return res; - } - - /* if it is negative output a - */ - if (t.sign == MP_NEG) { - ++_s; - *str++ = '-'; - t.sign = MP_ZPOS; - } - - digs = 0; - while (mp_iszero (&t) == 0) { - if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) { - mp_clear (&t); - return res; - } - *str++ = mp_s_rmap[d]; - ++digs; - } - - /* reverse the digits of the string. In this case _s points - * to the first digit [exluding the sign] of the number] - */ - bn_reverse ((unsigned char *)_s, digs); - - /* append a NULL so the string is properly terminated */ - *str = '\0'; - - mp_clear (&t); - return MP_OKAY; -} - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_toradix.c */ - -/* Start: bn_mp_toradix_n.c */ -#include -#ifdef BN_MP_TORADIX_N_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* stores a bignum as a ASCII string in a given radix (2..64) - * - * Stores upto maxlen-1 chars and always a NULL byte - */ -int mp_toradix_n(mp_int * a, char *str, int radix, int maxlen) -{ - int res, digs; - mp_int t; - mp_digit d; - char *_s = str; - - /* check range of the maxlen, radix */ - if (maxlen < 2 || radix < 2 || radix > 64) { - return MP_VAL; - } - - /* quick out if its zero */ - if (mp_iszero(a) == MP_YES) { - *str++ = '0'; - *str = '\0'; - return MP_OKAY; - } - - if ((res = mp_init_copy (&t, a)) != MP_OKAY) { - return res; - } - - /* if it is negative output a - */ - if (t.sign == MP_NEG) { - /* we have to reverse our digits later... but not the - sign!! */ - ++_s; - - /* store the flag and mark the number as positive */ - *str++ = '-'; - t.sign = MP_ZPOS; - - /* subtract a char */ - --maxlen; - } - - digs = 0; - while (mp_iszero (&t) == 0) { - if (--maxlen < 1) { - /* no more room */ - break; - } - if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) { - mp_clear (&t); - return res; - } - *str++ = mp_s_rmap[d]; - ++digs; - } - - /* reverse the digits of the string. In this case _s points - * to the first digit [exluding the sign] of the number - */ - bn_reverse ((unsigned char *)_s, digs); - - /* append a NULL so the string is properly terminated */ - *str = '\0'; - - mp_clear (&t); - return MP_OKAY; -} - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_toradix_n.c */ - -/* Start: bn_mp_unsigned_bin_size.c */ -#include -#ifdef BN_MP_UNSIGNED_BIN_SIZE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* get the size for an unsigned equivalent */ -int mp_unsigned_bin_size (mp_int * a) -{ - int size = mp_count_bits (a); - return (size / 8 + ((size & 7) != 0 ? 1 : 0)); -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_unsigned_bin_size.c */ - -/* Start: bn_mp_xor.c */ -#include -#ifdef BN_MP_XOR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* XOR two ints together */ -int -mp_xor (mp_int * a, mp_int * b, mp_int * c) -{ - int res, ix, px; - mp_int t, *x; - - if (a->used > b->used) { - if ((res = mp_init_copy (&t, a)) != MP_OKAY) { - return res; - } - px = b->used; - x = b; - } else { - if ((res = mp_init_copy (&t, b)) != MP_OKAY) { - return res; - } - px = a->used; - x = a; - } - - for (ix = 0; ix < px; ix++) { - t.dp[ix] ^= x->dp[ix]; - } - mp_clamp (&t); - mp_exch (c, &t); - mp_clear (&t); - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_xor.c */ - -/* Start: bn_mp_zero.c */ -#include -#ifdef BN_MP_ZERO_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* set to zero */ -void mp_zero (mp_int * a) -{ - int n; - mp_digit *tmp; - - a->sign = MP_ZPOS; - a->used = 0; - - tmp = a->dp; - for (n = 0; n < a->alloc; n++) { - *tmp++ = 0; - } -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_mp_zero.c */ - -/* Start: bn_prime_tab.c */ -#include -#ifdef BN_PRIME_TAB_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -const mp_digit ltm_prime_tab[] = { - 0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013, - 0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035, - 0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059, - 0x0061, 0x0065, 0x0067, 0x006B, 0x006D, 0x0071, 0x007F, -#ifndef MP_8BIT - 0x0083, - 0x0089, 0x008B, 0x0095, 0x0097, 0x009D, 0x00A3, 0x00A7, 0x00AD, - 0x00B3, 0x00B5, 0x00BF, 0x00C1, 0x00C5, 0x00C7, 0x00D3, 0x00DF, - 0x00E3, 0x00E5, 0x00E9, 0x00EF, 0x00F1, 0x00FB, 0x0101, 0x0107, - 0x010D, 0x010F, 0x0115, 0x0119, 0x011B, 0x0125, 0x0133, 0x0137, - - 0x0139, 0x013D, 0x014B, 0x0151, 0x015B, 0x015D, 0x0161, 0x0167, - 0x016F, 0x0175, 0x017B, 0x017F, 0x0185, 0x018D, 0x0191, 0x0199, - 0x01A3, 0x01A5, 0x01AF, 0x01B1, 0x01B7, 0x01BB, 0x01C1, 0x01C9, - 0x01CD, 0x01CF, 0x01D3, 0x01DF, 0x01E7, 0x01EB, 0x01F3, 0x01F7, - 0x01FD, 0x0209, 0x020B, 0x021D, 0x0223, 0x022D, 0x0233, 0x0239, - 0x023B, 0x0241, 0x024B, 0x0251, 0x0257, 0x0259, 0x025F, 0x0265, - 0x0269, 0x026B, 0x0277, 0x0281, 0x0283, 0x0287, 0x028D, 0x0293, - 0x0295, 0x02A1, 0x02A5, 0x02AB, 0x02B3, 0x02BD, 0x02C5, 0x02CF, - - 0x02D7, 0x02DD, 0x02E3, 0x02E7, 0x02EF, 0x02F5, 0x02F9, 0x0301, - 0x0305, 0x0313, 0x031D, 0x0329, 0x032B, 0x0335, 0x0337, 0x033B, - 0x033D, 0x0347, 0x0355, 0x0359, 0x035B, 0x035F, 0x036D, 0x0371, - 0x0373, 0x0377, 0x038B, 0x038F, 0x0397, 0x03A1, 0x03A9, 0x03AD, - 0x03B3, 0x03B9, 0x03C7, 0x03CB, 0x03D1, 0x03D7, 0x03DF, 0x03E5, - 0x03F1, 0x03F5, 0x03FB, 0x03FD, 0x0407, 0x0409, 0x040F, 0x0419, - 0x041B, 0x0425, 0x0427, 0x042D, 0x043F, 0x0443, 0x0445, 0x0449, - 0x044F, 0x0455, 0x045D, 0x0463, 0x0469, 0x047F, 0x0481, 0x048B, - - 0x0493, 0x049D, 0x04A3, 0x04A9, 0x04B1, 0x04BD, 0x04C1, 0x04C7, - 0x04CD, 0x04CF, 0x04D5, 0x04E1, 0x04EB, 0x04FD, 0x04FF, 0x0503, - 0x0509, 0x050B, 0x0511, 0x0515, 0x0517, 0x051B, 0x0527, 0x0529, - 0x052F, 0x0551, 0x0557, 0x055D, 0x0565, 0x0577, 0x0581, 0x058F, - 0x0593, 0x0595, 0x0599, 0x059F, 0x05A7, 0x05AB, 0x05AD, 0x05B3, - 0x05BF, 0x05C9, 0x05CB, 0x05CF, 0x05D1, 0x05D5, 0x05DB, 0x05E7, - 0x05F3, 0x05FB, 0x0607, 0x060D, 0x0611, 0x0617, 0x061F, 0x0623, - 0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653 -#endif -}; -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_prime_tab.c */ - -/* Start: bn_reverse.c */ -#include -#ifdef BN_REVERSE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* reverse an array, used for radix code */ -void -bn_reverse (unsigned char *s, int len) -{ - int ix, iy; - unsigned char t; - - ix = 0; - iy = len - 1; - while (ix < iy) { - t = s[ix]; - s[ix] = s[iy]; - s[iy] = t; - ++ix; - --iy; - } -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_reverse.c */ - -/* Start: bn_s_mp_add.c */ -#include -#ifdef BN_S_MP_ADD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* low level addition, based on HAC pp.594, Algorithm 14.7 */ -int -s_mp_add (mp_int * a, mp_int * b, mp_int * c) -{ - mp_int *x; - int olduse, res, min, max; - - /* find sizes, we let |a| <= |b| which means we have to sort - * them. "x" will point to the input with the most digits - */ - if (a->used > b->used) { - min = b->used; - max = a->used; - x = a; - } else { - min = a->used; - max = b->used; - x = b; - } - - /* init result */ - if (c->alloc < max + 1) { - if ((res = mp_grow (c, max + 1)) != MP_OKAY) { - return res; - } - } - - /* get old used digit count and set new one */ - olduse = c->used; - c->used = max + 1; - - { - register mp_digit u, *tmpa, *tmpb, *tmpc; - register int i; - - /* alias for digit pointers */ - - /* first input */ - tmpa = a->dp; - - /* second input */ - tmpb = b->dp; - - /* destination */ - tmpc = c->dp; - - /* zero the carry */ - u = 0; - for (i = 0; i < min; i++) { - /* Compute the sum at one digit, T[i] = A[i] + B[i] + U */ - *tmpc = *tmpa++ + *tmpb++ + u; - - /* U = carry bit of T[i] */ - u = *tmpc >> ((mp_digit)DIGIT_BIT); - - /* take away carry bit from T[i] */ - *tmpc++ &= MP_MASK; - } - - /* now copy higher words if any, that is in A+B - * if A or B has more digits add those in - */ - if (min != max) { - for (; i < max; i++) { - /* T[i] = X[i] + U */ - *tmpc = x->dp[i] + u; - - /* U = carry bit of T[i] */ - u = *tmpc >> ((mp_digit)DIGIT_BIT); - - /* take away carry bit from T[i] */ - *tmpc++ &= MP_MASK; - } - } - - /* add carry */ - *tmpc++ = u; - - /* clear digits above oldused */ - for (i = c->used; i < olduse; i++) { - *tmpc++ = 0; - } - } - - mp_clamp (c); - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_s_mp_add.c */ - -/* Start: bn_s_mp_exptmod.c */ -#include -#ifdef BN_S_MP_EXPTMOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ -#ifdef MP_LOW_MEM - #define TAB_SIZE 32 -#else - #define TAB_SIZE 256 -#endif - -int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) -{ - mp_int M[TAB_SIZE], res, mu; - mp_digit buf; - int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize; - int (*redux)(mp_int*,mp_int*,mp_int*); - - /* find window size */ - x = mp_count_bits (X); - if (x <= 7) { - winsize = 2; - } else if (x <= 36) { - winsize = 3; - } else if (x <= 140) { - winsize = 4; - } else if (x <= 450) { - winsize = 5; - } else if (x <= 1303) { - winsize = 6; - } else if (x <= 3529) { - winsize = 7; - } else { - winsize = 8; - } - -#ifdef MP_LOW_MEM - if (winsize > 5) { - winsize = 5; - } -#endif - - /* init M array */ - /* init first cell */ - if ((err = mp_init(&M[1])) != MP_OKAY) { - return err; - } - - /* now init the second half of the array */ - for (x = 1<<(winsize-1); x < (1 << winsize); x++) { - if ((err = mp_init(&M[x])) != MP_OKAY) { - for (y = 1<<(winsize-1); y < x; y++) { - mp_clear (&M[y]); - } - mp_clear(&M[1]); - return err; - } - } - - /* create mu, used for Barrett reduction */ - if ((err = mp_init (&mu)) != MP_OKAY) { - goto LBL_M; - } - - if (redmode == 0) { - if ((err = mp_reduce_setup (&mu, P)) != MP_OKAY) { - goto LBL_MU; - } - redux = mp_reduce; - } else { - if ((err = mp_reduce_2k_setup_l (P, &mu)) != MP_OKAY) { - goto LBL_MU; - } - redux = mp_reduce_2k_l; - } - - /* create M table - * - * The M table contains powers of the base, - * e.g. M[x] = G**x mod P - * - * The first half of the table is not - * computed though accept for M[0] and M[1] - */ - if ((err = mp_mod (G, P, &M[1])) != MP_OKAY) { - goto LBL_MU; - } - - /* compute the value at M[1<<(winsize-1)] by squaring - * M[1] (winsize-1) times - */ - if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) { - goto LBL_MU; - } - - for (x = 0; x < (winsize - 1); x++) { - /* square it */ - if ((err = mp_sqr (&M[1 << (winsize - 1)], - &M[1 << (winsize - 1)])) != MP_OKAY) { - goto LBL_MU; - } - - /* reduce modulo P */ - if ((err = redux (&M[1 << (winsize - 1)], P, &mu)) != MP_OKAY) { - goto LBL_MU; - } - } - - /* create upper table, that is M[x] = M[x-1] * M[1] (mod P) - * for x = (2**(winsize - 1) + 1) to (2**winsize - 1) - */ - for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) { - if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) { - goto LBL_MU; - } - if ((err = redux (&M[x], P, &mu)) != MP_OKAY) { - goto LBL_MU; - } - } - - /* setup result */ - if ((err = mp_init (&res)) != MP_OKAY) { - goto LBL_MU; - } - mp_set (&res, 1); - - /* set initial mode and bit cnt */ - mode = 0; - bitcnt = 1; - buf = 0; - digidx = X->used - 1; - bitcpy = 0; - bitbuf = 0; - - for (;;) { - /* grab next digit as required */ - if (--bitcnt == 0) { - /* if digidx == -1 we are out of digits */ - if (digidx == -1) { - break; - } - /* read next digit and reset the bitcnt */ - buf = X->dp[digidx--]; - bitcnt = (int) DIGIT_BIT; - } - - /* grab the next msb from the exponent */ - y = (buf >> (mp_digit)(DIGIT_BIT - 1)) & 1; - buf <<= (mp_digit)1; - - /* if the bit is zero and mode == 0 then we ignore it - * These represent the leading zero bits before the first 1 bit - * in the exponent. Technically this opt is not required but it - * does lower the # of trivial squaring/reductions used - */ - if (mode == 0 && y == 0) { - continue; - } - - /* if the bit is zero and mode == 1 then we square */ - if (mode == 1 && y == 0) { - if ((err = mp_sqr (&res, &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, &mu)) != MP_OKAY) { - goto LBL_RES; - } - continue; - } - - /* else we add it to the window */ - bitbuf |= (y << (winsize - ++bitcpy)); - mode = 2; - - if (bitcpy == winsize) { - /* ok window is filled so square as required and multiply */ - /* square first */ - for (x = 0; x < winsize; x++) { - if ((err = mp_sqr (&res, &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, &mu)) != MP_OKAY) { - goto LBL_RES; - } - } - - /* then multiply */ - if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, &mu)) != MP_OKAY) { - goto LBL_RES; - } - - /* empty window and reset */ - bitcpy = 0; - bitbuf = 0; - mode = 1; - } - } - - /* if bits remain then square/multiply */ - if (mode == 2 && bitcpy > 0) { - /* square then multiply if the bit is set */ - for (x = 0; x < bitcpy; x++) { - if ((err = mp_sqr (&res, &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, &mu)) != MP_OKAY) { - goto LBL_RES; - } - - bitbuf <<= 1; - if ((bitbuf & (1 << winsize)) != 0) { - /* then multiply */ - if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) { - goto LBL_RES; - } - if ((err = redux (&res, P, &mu)) != MP_OKAY) { - goto LBL_RES; - } - } - } - } - - mp_exch (&res, Y); - err = MP_OKAY; -LBL_RES:mp_clear (&res); -LBL_MU:mp_clear (&mu); -LBL_M: - mp_clear(&M[1]); - for (x = 1<<(winsize-1); x < (1 << winsize); x++) { - mp_clear (&M[x]); - } - return err; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_s_mp_exptmod.c */ - -/* Start: bn_s_mp_mul_digs.c */ -#include -#ifdef BN_S_MP_MUL_DIGS_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* multiplies |a| * |b| and only computes upto digs digits of result - * HAC pp. 595, Algorithm 14.12 Modified so you can control how - * many digits of output are created. - */ -int s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) -{ - mp_int t; - int res, pa, pb, ix, iy; - mp_digit u; - mp_word r; - mp_digit tmpx, *tmpt, *tmpy; - - /* can we use the fast multiplier? */ - if (((digs) < MP_WARRAY) && - MIN (a->used, b->used) < - (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { - return fast_s_mp_mul_digs (a, b, c, digs); - } - - if ((res = mp_init_size (&t, digs)) != MP_OKAY) { - return res; - } - t.used = digs; - - /* compute the digits of the product directly */ - pa = a->used; - for (ix = 0; ix < pa; ix++) { - /* set the carry to zero */ - u = 0; - - /* limit ourselves to making digs digits of output */ - pb = MIN (b->used, digs - ix); - - /* setup some aliases */ - /* copy of the digit from a used within the nested loop */ - tmpx = a->dp[ix]; - - /* an alias for the destination shifted ix places */ - tmpt = t.dp + ix; - - /* an alias for the digits of b */ - tmpy = b->dp; - - /* compute the columns of the output and propagate the carry */ - for (iy = 0; iy < pb; iy++) { - /* compute the column as a mp_word */ - r = ((mp_word)*tmpt) + - ((mp_word)tmpx) * ((mp_word)*tmpy++) + - ((mp_word) u); - - /* the new column is the lower part of the result */ - *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); - - /* get the carry word from the result */ - u = (mp_digit) (r >> ((mp_word) DIGIT_BIT)); - } - /* set carry if it is placed below digs */ - if (ix + iy < digs) { - *tmpt = u; - } - } - - mp_clamp (&t); - mp_exch (&t, c); - - mp_clear (&t); - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_s_mp_mul_digs.c */ - -/* Start: bn_s_mp_mul_high_digs.c */ -#include -#ifdef BN_S_MP_MUL_HIGH_DIGS_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* multiplies |a| * |b| and does not compute the lower digs digits - * [meant to get the higher part of the product] - */ -int -s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs) -{ - mp_int t; - int res, pa, pb, ix, iy; - mp_digit u; - mp_word r; - mp_digit tmpx, *tmpt, *tmpy; - - /* can we use the fast multiplier? */ -#ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C - if (((a->used + b->used + 1) < MP_WARRAY) - && MIN (a->used, b->used) < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { - return fast_s_mp_mul_high_digs (a, b, c, digs); - } -#endif - - if ((res = mp_init_size (&t, a->used + b->used + 1)) != MP_OKAY) { - return res; - } - t.used = a->used + b->used + 1; - - pa = a->used; - pb = b->used; - for (ix = 0; ix < pa; ix++) { - /* clear the carry */ - u = 0; - - /* left hand side of A[ix] * B[iy] */ - tmpx = a->dp[ix]; - - /* alias to the address of where the digits will be stored */ - tmpt = &(t.dp[digs]); - - /* alias for where to read the right hand side from */ - tmpy = b->dp + (digs - ix); - - for (iy = digs - ix; iy < pb; iy++) { - /* calculate the double precision result */ - r = ((mp_word)*tmpt) + - ((mp_word)tmpx) * ((mp_word)*tmpy++) + - ((mp_word) u); - - /* get the lower part */ - *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); - - /* carry the carry */ - u = (mp_digit) (r >> ((mp_word) DIGIT_BIT)); - } - *tmpt = u; - } - mp_clamp (&t); - mp_exch (&t, c); - mp_clear (&t); - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_s_mp_mul_high_digs.c */ - -/* Start: bn_s_mp_sqr.c */ -#include -#ifdef BN_S_MP_SQR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* low level squaring, b = a*a, HAC pp.596-597, Algorithm 14.16 */ -int s_mp_sqr (mp_int * a, mp_int * b) -{ - mp_int t; - int res, ix, iy, pa; - mp_word r; - mp_digit u, tmpx, *tmpt; - - pa = a->used; - if ((res = mp_init_size (&t, 2*pa + 1)) != MP_OKAY) { - return res; - } - - /* default used is maximum possible size */ - t.used = 2*pa + 1; - - for (ix = 0; ix < pa; ix++) { - /* first calculate the digit at 2*ix */ - /* calculate double precision result */ - r = ((mp_word) t.dp[2*ix]) + - ((mp_word)a->dp[ix])*((mp_word)a->dp[ix]); - - /* store lower part in result */ - t.dp[ix+ix] = (mp_digit) (r & ((mp_word) MP_MASK)); - - /* get the carry */ - u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); - - /* left hand side of A[ix] * A[iy] */ - tmpx = a->dp[ix]; - - /* alias for where to store the results */ - tmpt = t.dp + (2*ix + 1); - - for (iy = ix + 1; iy < pa; iy++) { - /* first calculate the product */ - r = ((mp_word)tmpx) * ((mp_word)a->dp[iy]); - - /* now calculate the double precision result, note we use - * addition instead of *2 since it's easier to optimize - */ - r = ((mp_word) *tmpt) + r + r + ((mp_word) u); - - /* store lower part */ - *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); - - /* get carry */ - u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); - } - /* propagate upwards */ - while (u != ((mp_digit) 0)) { - r = ((mp_word) *tmpt) + ((mp_word) u); - *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); - u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); - } - } - - mp_clamp (&t); - mp_exch (&t, b); - mp_clear (&t); - return MP_OKAY; -} -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_s_mp_sqr.c */ - -/* Start: bn_s_mp_sub.c */ -#include -#ifdef BN_S_MP_SUB_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* low level subtraction (assumes |a| > |b|), HAC pp.595 Algorithm 14.9 */ -int -s_mp_sub (mp_int * a, mp_int * b, mp_int * c) -{ - int olduse, res, min, max; - - /* find sizes */ - min = b->used; - max = a->used; - - /* init result */ - if (c->alloc < max) { - if ((res = mp_grow (c, max)) != MP_OKAY) { - return res; - } - } - olduse = c->used; - c->used = max; - - { - register mp_digit u, *tmpa, *tmpb, *tmpc; - register int i; - - /* alias for digit pointers */ - tmpa = a->dp; - tmpb = b->dp; - tmpc = c->dp; - - /* set carry to zero */ - u = 0; - for (i = 0; i < min; i++) { - /* T[i] = A[i] - B[i] - U */ - *tmpc = *tmpa++ - *tmpb++ - u; - - /* U = carry bit of T[i] - * Note this saves performing an AND operation since - * if a carry does occur it will propagate all the way to the - * MSB. As a result a single shift is enough to get the carry - */ - u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1)); - - /* Clear carry from T[i] */ - *tmpc++ &= MP_MASK; - } - - /* now copy higher words if any, e.g. if A has more digits than B */ - for (; i < max; i++) { - /* T[i] = A[i] - U */ - *tmpc = *tmpa++ - u; - - /* U = carry bit of T[i] */ - u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1)); - - /* Clear carry from T[i] */ - *tmpc++ &= MP_MASK; - } - - /* clear digits above used (since we may not have grown result above) */ - for (i = c->used; i < olduse; i++) { - *tmpc++ = 0; - } - } - - mp_clamp (c); - return MP_OKAY; -} - -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bn_s_mp_sub.c */ - -/* Start: bncore.c */ -#include -#ifdef BNCORE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* Known optimal configurations - - CPU /Compiler /MUL CUTOFF/SQR CUTOFF -------------------------------------------------------------- - Intel P4 Northwood /GCC v3.4.1 / 88/ 128/LTM 0.32 ;-) - AMD Athlon64 /GCC v3.4.4 / 80/ 120/LTM 0.35 - -*/ - -int KARATSUBA_MUL_CUTOFF = 80, /* Min. number of digits before Karatsuba multiplication is used. */ - KARATSUBA_SQR_CUTOFF = 120, /* Min. number of digits before Karatsuba squaring is used. */ - - TOOM_MUL_CUTOFF = 350, /* no optimal values of these are known yet so set em high */ - TOOM_SQR_CUTOFF = 400; -#endif - -/* $Source$ */ -/* $Revision: 0.41 $ */ -/* $Date: 2007-04-18 09:58:18 +0000 $ */ - -/* End: bncore.c */ - - -/* EOF */ diff --git a/external/libtommath-0.42.0/pretty.build b/external/libtommath-0.42.0/pretty.build deleted file mode 100755 index a708b8a..0000000 --- a/external/libtommath-0.42.0/pretty.build +++ /dev/null @@ -1,66 +0,0 @@ -#!/bin/perl -w -# -# Cute little builder for perl -# Total waste of development time... -# -# This will build all the object files and then the archive .a file -# requires GCC, GNU make and a sense of humour. -# -# Tom St Denis -use strict; - -my $count = 0; -my $starttime = time; -my $rate = 0; -print "Scanning for source files...\n"; -foreach my $filename (glob "*.c") { - ++$count; -} -print "Source files to build: $count\nBuilding...\n"; -my $i = 0; -my $lines = 0; -my $filesbuilt = 0; -foreach my $filename (glob "*.c") { - printf("Building %3.2f%%, ", (++$i/$count)*100.0); - if ($i % 4 == 0) { print "/, "; } - if ($i % 4 == 1) { print "-, "; } - if ($i % 4 == 2) { print "\\, "; } - if ($i % 4 == 3) { print "|, "; } - if ($rate > 0) { - my $tleft = ($count - $i) / $rate; - my $tsec = $tleft%60; - my $tmin = ($tleft/60)%60; - my $thour = ($tleft/3600)%60; - printf("%2d:%02d:%02d left, ", $thour, $tmin, $tsec); - } - my $cnt = ($i/$count)*30.0; - my $x = 0; - print "["; - for (; $x < $cnt; $x++) { print "#"; } - for (; $x < 30; $x++) { print " "; } - print "]\r"; - my $tmp = $filename; - $tmp =~ s/\.c/".o"/ge; - if (open(SRC, "<$tmp")) { - close SRC; - } else { - !system("make $tmp > /dev/null 2>/dev/null") or die "\nERROR: Failed to make $tmp!!!\n"; - open( SRC, "<$filename" ) or die "Couldn't open $filename for reading: $!"; - ++$lines while (); - close SRC or die "Error closing $filename after reading: $!"; - ++$filesbuilt; - } - - # update timer - if (time != $starttime) { - my $delay = time - $starttime; - $rate = $i/$delay; - } -} - -# finish building the library -printf("\nFinished building source (%d seconds, %3.2f files per second).\n", time - $starttime, $rate); -print "Compiled approximately $filesbuilt files and $lines lines of code.\n"; -print "Doing final make (building archive...)\n"; -!system("make > /dev/null 2>/dev/null") or die "\nERROR: Failed to perform last make command!!!\n"; -print "done.\n"; \ No newline at end of file diff --git a/external/libtommath-0.42.0/tombc/grammar.txt b/external/libtommath-0.42.0/tombc/grammar.txt deleted file mode 100755 index a780e75..0000000 --- a/external/libtommath-0.42.0/tombc/grammar.txt +++ /dev/null @@ -1,35 +0,0 @@ -program := program statement | statement | empty -statement := { statement } | - identifier = numexpression; | - identifier[numexpression] = numexpression; | - function(expressionlist); | - for (identifer = numexpression; numexpression; identifier = numexpression) { statement } | - while (numexpression) { statement } | - if (numexpresion) { statement } elif | - break; | - continue; - -elif := else statement | empty -function := abs | countbits | exptmod | jacobi | print | isprime | nextprime | issquare | readinteger | exit -expressionlist := expressionlist, expression | expression - -// LR(1) !!!? -expression := string | numexpression -numexpression := cmpexpr && cmpexpr | cmpexpr \|\| cmpexpr | cmpexpr -cmpexpr := boolexpr < boolexpr | boolexpr > boolexpr | boolexpr == boolexpr | - boolexpr <= boolexpr | boolexpr >= boolexpr | boolexpr -boolexpr := shiftexpr & shiftexpr | shiftexpr ^ shiftexpr | shiftexpr \| shiftexpr | shiftexpr -shiftexpr := addsubexpr << addsubexpr | addsubexpr >> addsubexpr | addsubexpr -addsubexpr := mulexpr + mulexpr | mulexpr - mulexpr | mulexpr -mulexpr := expr * expr | expr / expr | expr % expr | expr -expr := -nexpr | nexpr -nexpr := integer | identifier | ( numexpression ) | identifier[numexpression] - -identifier := identifer digits | identifier alpha | alpha -alpha := a ... z | A ... Z -integer := hexnumber | digits -hexnumber := 0xhexdigits -hexdigits := hexdigits hexdigit | hexdigit -hexdigit := 0 ... 9 | a ... f | A ... F -digits := digits digit | digit -digit := 0 ... 9 diff --git a/external/libtommath-0.42.0/tommath.h b/external/libtommath-0.42.0/tommath.h deleted file mode 100755 index cf9c499..0000000 --- a/external/libtommath-0.42.0/tommath.h +++ /dev/null @@ -1,584 +0,0 @@ -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com - */ -#ifndef BN_H_ -#define BN_H_ - -#include -#include -#include -#include -#include - -#include - -#ifndef MIN - #define MIN(x,y) ((x)<(y)?(x):(y)) -#endif - -#ifndef MAX - #define MAX(x,y) ((x)>(y)?(x):(y)) -#endif - -#ifdef __cplusplus -extern "C" { - -/* C++ compilers don't like assigning void * to mp_digit * */ -#define OPT_CAST(x) (x *) - -#else - -/* C on the other hand doesn't care */ -#define OPT_CAST(x) - -#endif - - -/* detect 64-bit mode if possible */ -#if defined(__x86_64__) - #if !(defined(MP_64BIT) && defined(MP_16BIT) && defined(MP_8BIT)) - #define MP_64BIT - #endif -#endif - -/* some default configurations. - * - * A "mp_digit" must be able to hold DIGIT_BIT + 1 bits - * A "mp_word" must be able to hold 2*DIGIT_BIT + 1 bits - * - * At the very least a mp_digit must be able to hold 7 bits - * [any size beyond that is ok provided it doesn't overflow the data type] - */ -#ifdef MP_8BIT - typedef unsigned char mp_digit; - typedef unsigned short mp_word; -#elif defined(MP_16BIT) - typedef unsigned short mp_digit; - typedef unsigned long mp_word; -#elif defined(MP_64BIT) - /* for GCC only on supported platforms */ -#ifndef CRYPT - typedef unsigned long long ulong64; - typedef signed long long long64; -#endif - - typedef unsigned long mp_digit; - typedef unsigned long mp_word __attribute__ ((mode(TI))); - - #define DIGIT_BIT 60 -#else - /* this is the default case, 28-bit digits */ - - /* this is to make porting into LibTomCrypt easier :-) */ -#ifndef CRYPT - #if defined(_MSC_VER) || defined(__BORLANDC__) - typedef unsigned __int64 ulong64; - typedef signed __int64 long64; - #else - typedef unsigned long long ulong64; - typedef signed long long long64; - #endif -#endif - - typedef unsigned long mp_digit; - typedef ulong64 mp_word; - -#ifdef MP_31BIT - /* this is an extension that uses 31-bit digits */ - #define DIGIT_BIT 31 -#else - /* default case is 28-bit digits, defines MP_28BIT as a handy macro to test */ - #define DIGIT_BIT 28 - #define MP_28BIT -#endif -#endif - -/* define heap macros */ -#ifndef CRYPT - /* default to libc stuff */ - #ifndef XMALLOC - #define XMALLOC malloc - #define XFREE free - #define XREALLOC realloc - #define XCALLOC calloc - #else - /* prototypes for our heap functions */ - extern void *XMALLOC(size_t n); - extern void *XREALLOC(void *p, size_t n); - extern void *XCALLOC(size_t n, size_t s); - extern void XFREE(void *p); - #endif -#endif - - -/* otherwise the bits per digit is calculated automatically from the size of a mp_digit */ -#ifndef DIGIT_BIT - #define DIGIT_BIT ((int)((CHAR_BIT * sizeof(mp_digit) - 1))) /* bits per digit */ -#endif - -#define MP_DIGIT_BIT DIGIT_BIT -#define MP_MASK ((((mp_digit)1)<<((mp_digit)DIGIT_BIT))-((mp_digit)1)) -#define MP_DIGIT_MAX MP_MASK - -/* equalities */ -#define MP_LT -1 /* less than */ -#define MP_EQ 0 /* equal to */ -#define MP_GT 1 /* greater than */ - -#define MP_ZPOS 0 /* positive integer */ -#define MP_NEG 1 /* negative */ - -#define MP_OKAY 0 /* ok result */ -#define MP_MEM -2 /* out of mem */ -#define MP_VAL -3 /* invalid input */ -#define MP_RANGE MP_VAL - -#define MP_YES 1 /* yes response */ -#define MP_NO 0 /* no response */ - -/* Primality generation flags */ -#define LTM_PRIME_BBS 0x0001 /* BBS style prime */ -#define LTM_PRIME_SAFE 0x0002 /* Safe prime (p-1)/2 == prime */ -#define LTM_PRIME_2MSB_ON 0x0008 /* force 2nd MSB to 1 */ - -typedef int mp_err; - -/* you'll have to tune these... */ -extern int KARATSUBA_MUL_CUTOFF, - KARATSUBA_SQR_CUTOFF, - TOOM_MUL_CUTOFF, - TOOM_SQR_CUTOFF; - -/* define this to use lower memory usage routines (exptmods mostly) */ -/* #define MP_LOW_MEM */ - -/* default precision */ -#ifndef MP_PREC - #ifndef MP_LOW_MEM - #define MP_PREC 32 /* default digits of precision */ - #else - #define MP_PREC 8 /* default digits of precision */ - #endif -#endif - -/* size of comba arrays, should be at least 2 * 2**(BITS_PER_WORD - BITS_PER_DIGIT*2) */ -#define MP_WARRAY (1 << (sizeof(mp_word) * CHAR_BIT - 2 * DIGIT_BIT + 1)) - -/* the infamous mp_int structure */ -typedef struct { - int used, alloc, sign; - mp_digit *dp; -} mp_int; - -/* callback for mp_prime_random, should fill dst with random bytes and return how many read [upto len] */ -typedef int ltm_prime_callback(unsigned char *dst, int len, void *dat); - - -#define USED(m) ((m)->used) -#define DIGIT(m,k) ((m)->dp[(k)]) -#define SIGN(m) ((m)->sign) - -/* error code to char* string */ -char *mp_error_to_string(int code); - -/* ---> init and deinit bignum functions <--- */ -/* init a bignum */ -int mp_init(mp_int *a); - -/* free a bignum */ -void mp_clear(mp_int *a); - -/* init a null terminated series of arguments */ -int mp_init_multi(mp_int *mp, ...); - -/* clear a null terminated series of arguments */ -void mp_clear_multi(mp_int *mp, ...); - -/* exchange two ints */ -void mp_exch(mp_int *a, mp_int *b); - -/* shrink ram required for a bignum */ -int mp_shrink(mp_int *a); - -/* grow an int to a given size */ -int mp_grow(mp_int *a, int size); - -/* init to a given number of digits */ -int mp_init_size(mp_int *a, int size); - -/* ---> Basic Manipulations <--- */ -#define mp_iszero(a) (((a)->used == 0) ? MP_YES : MP_NO) -#define mp_iseven(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 0)) ? MP_YES : MP_NO) -#define mp_isodd(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 1)) ? MP_YES : MP_NO) - -/* set to zero */ -void mp_zero(mp_int *a); - -/* set to a digit */ -void mp_set(mp_int *a, mp_digit b); - -/* set a 32-bit const */ -int mp_set_int(mp_int *a, unsigned long b); - -/* get a 32-bit value */ -unsigned long mp_get_int(mp_int * a); - -/* initialize and set a digit */ -int mp_init_set (mp_int * a, mp_digit b); - -/* initialize and set 32-bit value */ -int mp_init_set_int (mp_int * a, unsigned long b); - -/* copy, b = a */ -int mp_copy(mp_int *a, mp_int *b); - -/* inits and copies, a = b */ -int mp_init_copy(mp_int *a, mp_int *b); - -/* trim unused digits */ -void mp_clamp(mp_int *a); - -/* ---> digit manipulation <--- */ - -/* right shift by "b" digits */ -void mp_rshd(mp_int *a, int b); - -/* left shift by "b" digits */ -int mp_lshd(mp_int *a, int b); - -/* c = a / 2**b */ -int mp_div_2d(mp_int *a, int b, mp_int *c, mp_int *d); - -/* b = a/2 */ -int mp_div_2(mp_int *a, mp_int *b); - -/* c = a * 2**b */ -int mp_mul_2d(mp_int *a, int b, mp_int *c); - -/* b = a*2 */ -int mp_mul_2(mp_int *a, mp_int *b); - -/* c = a mod 2**d */ -int mp_mod_2d(mp_int *a, int b, mp_int *c); - -/* computes a = 2**b */ -int mp_2expt(mp_int *a, int b); - -/* Counts the number of lsbs which are zero before the first zero bit */ -int mp_cnt_lsb(mp_int *a); - -/* I Love Earth! */ - -/* makes a pseudo-random int of a given size */ -int mp_rand(mp_int *a, int digits); - -/* ---> binary operations <--- */ -/* c = a XOR b */ -int mp_xor(mp_int *a, mp_int *b, mp_int *c); - -/* c = a OR b */ -int mp_or(mp_int *a, mp_int *b, mp_int *c); - -/* c = a AND b */ -int mp_and(mp_int *a, mp_int *b, mp_int *c); - -/* ---> Basic arithmetic <--- */ - -/* b = -a */ -int mp_neg(mp_int *a, mp_int *b); - -/* b = |a| */ -int mp_abs(mp_int *a, mp_int *b); - -/* compare a to b */ -int mp_cmp(mp_int *a, mp_int *b); - -/* compare |a| to |b| */ -int mp_cmp_mag(mp_int *a, mp_int *b); - -/* c = a + b */ -int mp_add(mp_int *a, mp_int *b, mp_int *c); - -/* c = a - b */ -int mp_sub(mp_int *a, mp_int *b, mp_int *c); - -/* c = a * b */ -int mp_mul(mp_int *a, mp_int *b, mp_int *c); - -/* b = a*a */ -int mp_sqr(mp_int *a, mp_int *b); - -/* a/b => cb + d == a */ -int mp_div(mp_int *a, mp_int *b, mp_int *c, mp_int *d); - -/* c = a mod b, 0 <= c < b */ -int mp_mod(mp_int *a, mp_int *b, mp_int *c); - -/* ---> single digit functions <--- */ - -/* compare against a single digit */ -int mp_cmp_d(mp_int *a, mp_digit b); - -/* c = a + b */ -int mp_add_d(mp_int *a, mp_digit b, mp_int *c); - -/* c = a - b */ -int mp_sub_d(mp_int *a, mp_digit b, mp_int *c); - -/* c = a * b */ -int mp_mul_d(mp_int *a, mp_digit b, mp_int *c); - -/* a/b => cb + d == a */ -int mp_div_d(mp_int *a, mp_digit b, mp_int *c, mp_digit *d); - -/* a/3 => 3c + d == a */ -int mp_div_3(mp_int *a, mp_int *c, mp_digit *d); - -/* c = a**b */ -int mp_expt_d(mp_int *a, mp_digit b, mp_int *c); - -/* c = a mod b, 0 <= c < b */ -int mp_mod_d(mp_int *a, mp_digit b, mp_digit *c); - -/* ---> number theory <--- */ - -/* d = a + b (mod c) */ -int mp_addmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d); - -/* d = a - b (mod c) */ -int mp_submod(mp_int *a, mp_int *b, mp_int *c, mp_int *d); - -/* d = a * b (mod c) */ -int mp_mulmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d); - -/* c = a * a (mod b) */ -int mp_sqrmod(mp_int *a, mp_int *b, mp_int *c); - -/* c = 1/a (mod b) */ -int mp_invmod(mp_int *a, mp_int *b, mp_int *c); - -/* c = (a, b) */ -int mp_gcd(mp_int *a, mp_int *b, mp_int *c); - -/* produces value such that U1*a + U2*b = U3 */ -int mp_exteuclid(mp_int *a, mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3); - -/* c = [a, b] or (a*b)/(a, b) */ -int mp_lcm(mp_int *a, mp_int *b, mp_int *c); - -/* finds one of the b'th root of a, such that |c|**b <= |a| - * - * returns error if a < 0 and b is even - */ -int mp_n_root(mp_int *a, mp_digit b, mp_int *c); - -/* special sqrt algo */ -int mp_sqrt(mp_int *arg, mp_int *ret); - -/* is number a square? */ -int mp_is_square(mp_int *arg, int *ret); - -/* computes the jacobi c = (a | n) (or Legendre if b is prime) */ -int mp_jacobi(mp_int *a, mp_int *n, int *c); - -/* used to setup the Barrett reduction for a given modulus b */ -int mp_reduce_setup(mp_int *a, mp_int *b); - -/* Barrett Reduction, computes a (mod b) with a precomputed value c - * - * Assumes that 0 < a <= b*b, note if 0 > a > -(b*b) then you can merely - * compute the reduction as -1 * mp_reduce(mp_abs(a)) [pseudo code]. - */ -int mp_reduce(mp_int *a, mp_int *b, mp_int *c); - -/* setups the montgomery reduction */ -int mp_montgomery_setup(mp_int *a, mp_digit *mp); - -/* computes a = B**n mod b without division or multiplication useful for - * normalizing numbers in a Montgomery system. - */ -int mp_montgomery_calc_normalization(mp_int *a, mp_int *b); - -/* computes x/R == x (mod N) via Montgomery Reduction */ -int mp_montgomery_reduce(mp_int *a, mp_int *m, mp_digit mp); - -/* returns 1 if a is a valid DR modulus */ -int mp_dr_is_modulus(mp_int *a); - -/* sets the value of "d" required for mp_dr_reduce */ -void mp_dr_setup(mp_int *a, mp_digit *d); - -/* reduces a modulo b using the Diminished Radix method */ -int mp_dr_reduce(mp_int *a, mp_int *b, mp_digit mp); - -/* returns true if a can be reduced with mp_reduce_2k */ -int mp_reduce_is_2k(mp_int *a); - -/* determines k value for 2k reduction */ -int mp_reduce_2k_setup(mp_int *a, mp_digit *d); - -/* reduces a modulo b where b is of the form 2**p - k [0 <= a] */ -int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d); - -/* returns true if a can be reduced with mp_reduce_2k_l */ -int mp_reduce_is_2k_l(mp_int *a); - -/* determines k value for 2k reduction */ -int mp_reduce_2k_setup_l(mp_int *a, mp_int *d); - -/* reduces a modulo b where b is of the form 2**p - k [0 <= a] */ -int mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d); - -/* d = a**b (mod c) */ -int mp_exptmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d); - -/* ---> Primes <--- */ - -/* number of primes */ -#ifdef MP_8BIT - #define PRIME_SIZE 31 -#else - #define PRIME_SIZE 256 -#endif - -/* table of first PRIME_SIZE primes */ -extern const mp_digit ltm_prime_tab[]; - -/* result=1 if a is divisible by one of the first PRIME_SIZE primes */ -int mp_prime_is_divisible(mp_int *a, int *result); - -/* performs one Fermat test of "a" using base "b". - * Sets result to 0 if composite or 1 if probable prime - */ -int mp_prime_fermat(mp_int *a, mp_int *b, int *result); - -/* performs one Miller-Rabin test of "a" using base "b". - * Sets result to 0 if composite or 1 if probable prime - */ -int mp_prime_miller_rabin(mp_int *a, mp_int *b, int *result); - -/* This gives [for a given bit size] the number of trials required - * such that Miller-Rabin gives a prob of failure lower than 2^-96 - */ -int mp_prime_rabin_miller_trials(int size); - -/* performs t rounds of Miller-Rabin on "a" using the first - * t prime bases. Also performs an initial sieve of trial - * division. Determines if "a" is prime with probability - * of error no more than (1/4)**t. - * - * Sets result to 1 if probably prime, 0 otherwise - */ -int mp_prime_is_prime(mp_int *a, int t, int *result); - -/* finds the next prime after the number "a" using "t" trials - * of Miller-Rabin. - * - * bbs_style = 1 means the prime must be congruent to 3 mod 4 - */ -int mp_prime_next_prime(mp_int *a, int t, int bbs_style); - -/* makes a truly random prime of a given size (bytes), - * call with bbs = 1 if you want it to be congruent to 3 mod 4 - * - * You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can - * have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself - * so it can be NULL - * - * The prime generated will be larger than 2^(8*size). - */ -#define mp_prime_random(a, t, size, bbs, cb, dat) mp_prime_random_ex(a, t, ((size) * 8) + 1, (bbs==1)?LTM_PRIME_BBS:0, cb, dat) - -/* makes a truly random prime of a given size (bits), - * - * Flags are as follows: - * - * LTM_PRIME_BBS - make prime congruent to 3 mod 4 - * LTM_PRIME_SAFE - make sure (p-1)/2 is prime as well (implies LTM_PRIME_BBS) - * LTM_PRIME_2MSB_OFF - make the 2nd highest bit zero - * LTM_PRIME_2MSB_ON - make the 2nd highest bit one - * - * You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can - * have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself - * so it can be NULL - * - */ -int mp_prime_random_ex(mp_int *a, int t, int size, int flags, ltm_prime_callback cb, void *dat); - -/* ---> radix conversion <--- */ -int mp_count_bits(mp_int *a); - -int mp_unsigned_bin_size(mp_int *a); -int mp_read_unsigned_bin(mp_int *a, const unsigned char *b, int c); -int mp_to_unsigned_bin(mp_int *a, unsigned char *b); -int mp_to_unsigned_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen); - -int mp_signed_bin_size(mp_int *a); -int mp_read_signed_bin(mp_int *a, const unsigned char *b, int c); -int mp_to_signed_bin(mp_int *a, unsigned char *b); -int mp_to_signed_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen); - -int mp_read_radix(mp_int *a, const char *str, int radix); -int mp_toradix(mp_int *a, char *str, int radix); -int mp_toradix_n(mp_int * a, char *str, int radix, int maxlen); -int mp_radix_size(mp_int *a, int radix, int *size); - -int mp_fread(mp_int *a, int radix, FILE *stream); -int mp_fwrite(mp_int *a, int radix, FILE *stream); - -#define mp_read_raw(mp, str, len) mp_read_signed_bin((mp), (str), (len)) -#define mp_raw_size(mp) mp_signed_bin_size(mp) -#define mp_toraw(mp, str) mp_to_signed_bin((mp), (str)) -#define mp_read_mag(mp, str, len) mp_read_unsigned_bin((mp), (str), (len)) -#define mp_mag_size(mp) mp_unsigned_bin_size(mp) -#define mp_tomag(mp, str) mp_to_unsigned_bin((mp), (str)) - -#define mp_tobinary(M, S) mp_toradix((M), (S), 2) -#define mp_tooctal(M, S) mp_toradix((M), (S), 8) -#define mp_todecimal(M, S) mp_toradix((M), (S), 10) -#define mp_tohex(M, S) mp_toradix((M), (S), 16) - -/* lowlevel functions, do not call! */ -int s_mp_add(mp_int *a, mp_int *b, mp_int *c); -int s_mp_sub(mp_int *a, mp_int *b, mp_int *c); -#define s_mp_mul(a, b, c) s_mp_mul_digs(a, b, c, (a)->used + (b)->used + 1) -int fast_s_mp_mul_digs(mp_int *a, mp_int *b, mp_int *c, int digs); -int s_mp_mul_digs(mp_int *a, mp_int *b, mp_int *c, int digs); -int fast_s_mp_mul_high_digs(mp_int *a, mp_int *b, mp_int *c, int digs); -int s_mp_mul_high_digs(mp_int *a, mp_int *b, mp_int *c, int digs); -int fast_s_mp_sqr(mp_int *a, mp_int *b); -int s_mp_sqr(mp_int *a, mp_int *b); -int mp_karatsuba_mul(mp_int *a, mp_int *b, mp_int *c); -int mp_toom_mul(mp_int *a, mp_int *b, mp_int *c); -int mp_karatsuba_sqr(mp_int *a, mp_int *b); -int mp_toom_sqr(mp_int *a, mp_int *b); -int fast_mp_invmod(mp_int *a, mp_int *b, mp_int *c); -int mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c); -int fast_mp_montgomery_reduce(mp_int *a, mp_int *m, mp_digit mp); -int mp_exptmod_fast(mp_int *G, mp_int *X, mp_int *P, mp_int *Y, int mode); -int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int mode); -void bn_reverse(unsigned char *s, int len); - -extern const char *mp_s_rmap; - -#ifdef __cplusplus - } -#endif - -#endif - - -/* $Source$ */ -/* $Revision: 0.39 $ */ -/* $Date: 2006-04-06 19:49:59 +0000 $ */ diff --git a/external/libtommath-0.42.0/tommath.out b/external/libtommath-0.42.0/tommath.out deleted file mode 100755 index 9f62617..0000000 --- a/external/libtommath-0.42.0/tommath.out +++ /dev/null @@ -1,139 +0,0 @@ -\BOOKMARK [0][-]{chapter.1}{Introduction}{} -\BOOKMARK [1][-]{section.1.1}{Multiple Precision Arithmetic}{chapter.1} -\BOOKMARK [2][-]{subsection.1.1.1}{What is Multiple Precision Arithmetic?}{section.1.1} -\BOOKMARK [2][-]{subsection.1.1.2}{The Need for Multiple Precision Arithmetic}{section.1.1} -\BOOKMARK [2][-]{subsection.1.1.3}{Benefits of Multiple Precision Arithmetic}{section.1.1} -\BOOKMARK [1][-]{section.1.2}{Purpose of This Text}{chapter.1} -\BOOKMARK [1][-]{section.1.3}{Discussion and Notation}{chapter.1} -\BOOKMARK [2][-]{subsection.1.3.1}{Notation}{section.1.3} -\BOOKMARK [2][-]{subsection.1.3.2}{Precision Notation}{section.1.3} -\BOOKMARK [2][-]{subsection.1.3.3}{Algorithm Inputs and Outputs}{section.1.3} -\BOOKMARK [2][-]{subsection.1.3.4}{Mathematical Expressions}{section.1.3} -\BOOKMARK [2][-]{subsection.1.3.5}{Work Effort}{section.1.3} -\BOOKMARK [1][-]{section.1.4}{Exercises}{chapter.1} -\BOOKMARK [1][-]{section.1.5}{Introduction to LibTomMath}{chapter.1} -\BOOKMARK [2][-]{subsection.1.5.1}{What is LibTomMath?}{section.1.5} -\BOOKMARK [2][-]{subsection.1.5.2}{Goals of LibTomMath}{section.1.5} -\BOOKMARK [1][-]{section.1.6}{Choice of LibTomMath}{chapter.1} -\BOOKMARK [2][-]{subsection.1.6.1}{Code Base}{section.1.6} -\BOOKMARK [2][-]{subsection.1.6.2}{API Simplicity}{section.1.6} -\BOOKMARK [2][-]{subsection.1.6.3}{Optimizations}{section.1.6} -\BOOKMARK [2][-]{subsection.1.6.4}{Portability and Stability}{section.1.6} -\BOOKMARK [2][-]{subsection.1.6.5}{Choice}{section.1.6} -\BOOKMARK [0][-]{chapter.2}{Getting Started}{} -\BOOKMARK [1][-]{section.2.1}{Library Basics}{chapter.2} -\BOOKMARK [1][-]{section.2.2}{What is a Multiple Precision Integer?}{chapter.2} -\BOOKMARK [2][-]{subsection.2.2.1}{The mp\137int Structure}{section.2.2} -\BOOKMARK [1][-]{section.2.3}{Argument Passing}{chapter.2} -\BOOKMARK [1][-]{section.2.4}{Return Values}{chapter.2} -\BOOKMARK [1][-]{section.2.5}{Initialization and Clearing}{chapter.2} -\BOOKMARK [2][-]{subsection.2.5.1}{Initializing an mp\137int}{section.2.5} -\BOOKMARK [2][-]{subsection.2.5.2}{Clearing an mp\137int}{section.2.5} -\BOOKMARK [1][-]{section.2.6}{Maintenance Algorithms}{chapter.2} -\BOOKMARK [2][-]{subsection.2.6.1}{Augmenting an mp\137int's Precision}{section.2.6} -\BOOKMARK [2][-]{subsection.2.6.2}{Initializing Variable Precision mp\137ints}{section.2.6} -\BOOKMARK [2][-]{subsection.2.6.3}{Multiple Integer Initializations and Clearings}{section.2.6} -\BOOKMARK [2][-]{subsection.2.6.4}{Clamping Excess Digits}{section.2.6} -\BOOKMARK [0][-]{chapter.3}{Basic Operations}{} -\BOOKMARK [1][-]{section.3.1}{Introduction}{chapter.3} -\BOOKMARK [1][-]{section.3.2}{Assigning Values to mp\137int Structures}{chapter.3} -\BOOKMARK [2][-]{subsection.3.2.1}{Copying an mp\137int}{section.3.2} -\BOOKMARK [2][-]{subsection.3.2.2}{Creating a Clone}{section.3.2} -\BOOKMARK [1][-]{section.3.3}{Zeroing an Integer}{chapter.3} -\BOOKMARK [1][-]{section.3.4}{Sign Manipulation}{chapter.3} -\BOOKMARK [2][-]{subsection.3.4.1}{Absolute Value}{section.3.4} -\BOOKMARK [2][-]{subsection.3.4.2}{Integer Negation}{section.3.4} -\BOOKMARK [1][-]{section.3.5}{Small Constants}{chapter.3} -\BOOKMARK [2][-]{subsection.3.5.1}{Setting Small Constants}{section.3.5} -\BOOKMARK [2][-]{subsection.3.5.2}{Setting Large Constants}{section.3.5} -\BOOKMARK [1][-]{section.3.6}{Comparisons}{chapter.3} -\BOOKMARK [2][-]{subsection.3.6.1}{Unsigned Comparisions}{section.3.6} -\BOOKMARK [2][-]{subsection.3.6.2}{Signed Comparisons}{section.3.6} -\BOOKMARK [0][-]{chapter.4}{Basic Arithmetic}{} -\BOOKMARK [1][-]{section.4.1}{Introduction}{chapter.4} -\BOOKMARK [1][-]{section.4.2}{Addition and Subtraction}{chapter.4} -\BOOKMARK [2][-]{subsection.4.2.1}{Low Level Addition}{section.4.2} -\BOOKMARK [2][-]{subsection.4.2.2}{Low Level Subtraction}{section.4.2} -\BOOKMARK [2][-]{subsection.4.2.3}{High Level Addition}{section.4.2} -\BOOKMARK [2][-]{subsection.4.2.4}{High Level Subtraction}{section.4.2} -\BOOKMARK [1][-]{section.4.3}{Bit and Digit Shifting}{chapter.4} -\BOOKMARK [2][-]{subsection.4.3.1}{Multiplication by Two}{section.4.3} -\BOOKMARK [2][-]{subsection.4.3.2}{Division by Two}{section.4.3} -\BOOKMARK [1][-]{section.4.4}{Polynomial Basis Operations}{chapter.4} -\BOOKMARK [2][-]{subsection.4.4.1}{Multiplication by x}{section.4.4} -\BOOKMARK [2][-]{subsection.4.4.2}{Division by x}{section.4.4} -\BOOKMARK [1][-]{section.4.5}{Powers of Two}{chapter.4} -\BOOKMARK [2][-]{subsection.4.5.1}{Multiplication by Power of Two}{section.4.5} -\BOOKMARK [2][-]{subsection.4.5.2}{Division by Power of Two}{section.4.5} -\BOOKMARK [2][-]{subsection.4.5.3}{Remainder of Division by Power of Two}{section.4.5} -\BOOKMARK [0][-]{chapter.5}{Multiplication and Squaring}{} -\BOOKMARK [1][-]{section.5.1}{The Multipliers}{chapter.5} -\BOOKMARK [1][-]{section.5.2}{Multiplication}{chapter.5} -\BOOKMARK [2][-]{subsection.5.2.1}{The Baseline Multiplication}{section.5.2} -\BOOKMARK [2][-]{subsection.5.2.2}{Faster Multiplication by the ``Comba'' Method}{section.5.2} -\BOOKMARK [2][-]{subsection.5.2.3}{Polynomial Basis Multiplication}{section.5.2} -\BOOKMARK [2][-]{subsection.5.2.4}{Karatsuba Multiplication}{section.5.2} -\BOOKMARK [2][-]{subsection.5.2.5}{Toom-Cook 3-Way Multiplication}{section.5.2} -\BOOKMARK [2][-]{subsection.5.2.6}{Signed Multiplication}{section.5.2} -\BOOKMARK [1][-]{section.5.3}{Squaring}{chapter.5} -\BOOKMARK [2][-]{subsection.5.3.1}{The Baseline Squaring Algorithm}{section.5.3} -\BOOKMARK [2][-]{subsection.5.3.2}{Faster Squaring by the ``Comba'' Method}{section.5.3} -\BOOKMARK [2][-]{subsection.5.3.3}{Polynomial Basis Squaring}{section.5.3} -\BOOKMARK [2][-]{subsection.5.3.4}{Karatsuba Squaring}{section.5.3} -\BOOKMARK [2][-]{subsection.5.3.5}{Toom-Cook Squaring}{section.5.3} -\BOOKMARK [2][-]{subsection.5.3.6}{High Level Squaring}{section.5.3} -\BOOKMARK [0][-]{chapter.6}{Modular Reduction}{} -\BOOKMARK [1][-]{section.6.1}{Basics of Modular Reduction}{chapter.6} -\BOOKMARK [1][-]{section.6.2}{The Barrett Reduction}{chapter.6} -\BOOKMARK [2][-]{subsection.6.2.1}{Fixed Point Arithmetic}{section.6.2} -\BOOKMARK [2][-]{subsection.6.2.2}{Choosing a Radix Point}{section.6.2} -\BOOKMARK [2][-]{subsection.6.2.3}{Trimming the Quotient}{section.6.2} -\BOOKMARK [2][-]{subsection.6.2.4}{Trimming the Residue}{section.6.2} -\BOOKMARK [2][-]{subsection.6.2.5}{The Barrett Algorithm}{section.6.2} -\BOOKMARK [2][-]{subsection.6.2.6}{The Barrett Setup Algorithm}{section.6.2} -\BOOKMARK [1][-]{section.6.3}{The Montgomery Reduction}{chapter.6} -\BOOKMARK [2][-]{subsection.6.3.1}{Digit Based Montgomery Reduction}{section.6.3} -\BOOKMARK [2][-]{subsection.6.3.2}{Baseline Montgomery Reduction}{section.6.3} -\BOOKMARK [2][-]{subsection.6.3.3}{Faster ``Comba'' Montgomery Reduction}{section.6.3} -\BOOKMARK [2][-]{subsection.6.3.4}{Montgomery Setup}{section.6.3} -\BOOKMARK [1][-]{section.6.4}{The Diminished Radix Algorithm}{chapter.6} -\BOOKMARK [2][-]{subsection.6.4.1}{Choice of Moduli}{section.6.4} -\BOOKMARK [2][-]{subsection.6.4.2}{Choice of k}{section.6.4} -\BOOKMARK [2][-]{subsection.6.4.3}{Restricted Diminished Radix Reduction}{section.6.4} -\BOOKMARK [2][-]{subsection.6.4.4}{Unrestricted Diminished Radix Reduction}{section.6.4} -\BOOKMARK [1][-]{section.6.5}{Algorithm Comparison}{chapter.6} -\BOOKMARK [0][-]{chapter.7}{Exponentiation}{} -\BOOKMARK [1][-]{section.7.1}{Exponentiation Basics}{chapter.7} -\BOOKMARK [2][-]{subsection.7.1.1}{Single Digit Exponentiation}{section.7.1} -\BOOKMARK [1][-]{section.7.2}{k-ary Exponentiation}{chapter.7} -\BOOKMARK [2][-]{subsection.7.2.1}{Optimal Values of k}{section.7.2} -\BOOKMARK [2][-]{subsection.7.2.2}{Sliding-Window Exponentiation}{section.7.2} -\BOOKMARK [1][-]{section.7.3}{Modular Exponentiation}{chapter.7} -\BOOKMARK [2][-]{subsection.7.3.1}{Barrett Modular Exponentiation}{section.7.3} -\BOOKMARK [1][-]{section.7.4}{Quick Power of Two}{chapter.7} -\BOOKMARK [0][-]{chapter.8}{Higher Level Algorithms}{} -\BOOKMARK [1][-]{section.8.1}{Integer Division with Remainder}{chapter.8} -\BOOKMARK [2][-]{subsection.8.1.1}{Quotient Estimation}{section.8.1} -\BOOKMARK [2][-]{subsection.8.1.2}{Normalized Integers}{section.8.1} -\BOOKMARK [2][-]{subsection.8.1.3}{Radix- Division with Remainder}{section.8.1} -\BOOKMARK [1][-]{section.8.2}{Single Digit Helpers}{chapter.8} -\BOOKMARK [2][-]{subsection.8.2.1}{Single Digit Addition and Subtraction}{section.8.2} -\BOOKMARK [2][-]{subsection.8.2.2}{Single Digit Multiplication}{section.8.2} -\BOOKMARK [2][-]{subsection.8.2.3}{Single Digit Division}{section.8.2} -\BOOKMARK [2][-]{subsection.8.2.4}{Single Digit Root Extraction}{section.8.2} -\BOOKMARK [1][-]{section.8.3}{Random Number Generation}{chapter.8} -\BOOKMARK [1][-]{section.8.4}{Formatted Representations}{chapter.8} -\BOOKMARK [2][-]{subsection.8.4.1}{Reading Radix-n Input}{section.8.4} -\BOOKMARK [2][-]{subsection.8.4.2}{Generating Radix-n Output}{section.8.4} -\BOOKMARK [0][-]{chapter.9}{Number Theoretic Algorithms}{} -\BOOKMARK [1][-]{section.9.1}{Greatest Common Divisor}{chapter.9} -\BOOKMARK [2][-]{subsection.9.1.1}{Complete Greatest Common Divisor}{section.9.1} -\BOOKMARK [1][-]{section.9.2}{Least Common Multiple}{chapter.9} -\BOOKMARK [1][-]{section.9.3}{Jacobi Symbol Computation}{chapter.9} -\BOOKMARK [2][-]{subsection.9.3.1}{Jacobi Symbol}{section.9.3} -\BOOKMARK [1][-]{section.9.4}{Modular Inverse}{chapter.9} -\BOOKMARK [2][-]{subsection.9.4.1}{General Case}{section.9.4} -\BOOKMARK [1][-]{section.9.5}{Primality Tests}{chapter.9} -\BOOKMARK [2][-]{subsection.9.5.1}{Trial Division}{section.9.5} -\BOOKMARK [2][-]{subsection.9.5.2}{The Fermat Test}{section.9.5} -\BOOKMARK [2][-]{subsection.9.5.3}{The Miller-Rabin Test}{section.9.5} diff --git a/external/libtommath-0.42.0/tommath.src b/external/libtommath-0.42.0/tommath.src deleted file mode 100755 index 4065822..0000000 --- a/external/libtommath-0.42.0/tommath.src +++ /dev/null @@ -1,6350 +0,0 @@ -\documentclass[b5paper]{book} -\usepackage{hyperref} -\usepackage{makeidx} -\usepackage{amssymb} -\usepackage{color} -\usepackage{alltt} -\usepackage{graphicx} -\usepackage{layout} -\def\union{\cup} -\def\intersect{\cap} -\def\getsrandom{\stackrel{\rm R}{\gets}} -\def\cross{\times} -\def\cat{\hspace{0.5em} \| \hspace{0.5em}} -\def\catn{$\|$} -\def\divides{\hspace{0.3em} | \hspace{0.3em}} -\def\nequiv{\not\equiv} -\def\approx{\raisebox{0.2ex}{\mbox{\small $\sim$}}} -\def\lcm{{\rm lcm}} -\def\gcd{{\rm gcd}} -\def\log{{\rm log}} -\def\ord{{\rm ord}} -\def\abs{{\mathit abs}} -\def\rep{{\mathit rep}} -\def\mod{{\mathit\ mod\ }} -\renewcommand{\pmod}[1]{\ ({\rm mod\ }{#1})} -\newcommand{\floor}[1]{\left\lfloor{#1}\right\rfloor} -\newcommand{\ceil}[1]{\left\lceil{#1}\right\rceil} -\def\Or{{\rm\ or\ }} -\def\And{{\rm\ and\ }} -\def\iff{\hspace{1em}\Longleftrightarrow\hspace{1em}} -\def\implies{\Rightarrow} -\def\undefined{{\rm ``undefined"}} -\def\Proof{\vspace{1ex}\noindent {\bf Proof:}\hspace{1em}} -\let\oldphi\phi -\def\phi{\varphi} -\def\Pr{{\rm Pr}} -\newcommand{\str}[1]{{\mathbf{#1}}} -\def\F{{\mathbb F}} -\def\N{{\mathbb N}} -\def\Z{{\mathbb Z}} -\def\R{{\mathbb R}} -\def\C{{\mathbb C}} -\def\Q{{\mathbb Q}} -\definecolor{DGray}{gray}{0.5} -\newcommand{\emailaddr}[1]{\mbox{$<${#1}$>$}} -\def\twiddle{\raisebox{0.3ex}{\mbox{\tiny $\sim$}}} -\def\gap{\vspace{0.5ex}} -\makeindex -\begin{document} -\frontmatter -\pagestyle{empty} -\title{Multi--Precision Math} -\author{\mbox{ -%\begin{small} -\begin{tabular}{c} -Tom St Denis \\ -Algonquin College \\ -\\ -Mads Rasmussen \\ -Open Communications Security \\ -\\ -Greg Rose \\ -QUALCOMM Australia \\ -\end{tabular} -%\end{small} -} -} -\maketitle -This text has been placed in the public domain. This text corresponds to the v0.39 release of the -LibTomMath project. - -\begin{alltt} -Tom St Denis -111 Banning Rd -Ottawa, Ontario -K2L 1C3 -Canada - -Phone: 1-613-836-3160 -Email: tomstdenis@gmail.com -\end{alltt} - -This text is formatted to the international B5 paper size of 176mm wide by 250mm tall using the \LaTeX{} -{\em book} macro package and the Perl {\em booker} package. - -\tableofcontents -\listoffigures -\chapter*{Prefaces} -When I tell people about my LibTom projects and that I release them as public domain they are often puzzled. -They ask why I did it and especially why I continue to work on them for free. The best I can explain it is ``Because I can.'' -Which seems odd and perhaps too terse for adult conversation. I often qualify it with ``I am able, I am willing.'' which -perhaps explains it better. I am the first to admit there is not anything that special with what I have done. Perhaps -others can see that too and then we would have a society to be proud of. My LibTom projects are what I am doing to give -back to society in the form of tools and knowledge that can help others in their endeavours. - -I started writing this book because it was the most logical task to further my goal of open academia. The LibTomMath source -code itself was written to be easy to follow and learn from. There are times, however, where pure C source code does not -explain the algorithms properly. Hence this book. The book literally starts with the foundation of the library and works -itself outwards to the more complicated algorithms. The use of both pseudo--code and verbatim source code provides a duality -of ``theory'' and ``practice'' that the computer science students of the world shall appreciate. I never deviate too far -from relatively straightforward algebra and I hope that this book can be a valuable learning asset. - -This book and indeed much of the LibTom projects would not exist in their current form if it was not for a plethora -of kind people donating their time, resources and kind words to help support my work. Writing a text of significant -length (along with the source code) is a tiresome and lengthy process. Currently the LibTom project is four years old, -comprises of literally thousands of users and over 100,000 lines of source code, TeX and other material. People like Mads and Greg -were there at the beginning to encourage me to work well. It is amazing how timely validation from others can boost morale to -continue the project. Definitely my parents were there for me by providing room and board during the many months of work in 2003. - -To my many friends whom I have met through the years I thank you for the good times and the words of encouragement. I hope I -honour your kind gestures with this project. - -Open Source. Open Academia. Open Minds. - -\begin{flushright} Tom St Denis \end{flushright} - -\newpage -I found the opportunity to work with Tom appealing for several reasons, not only could I broaden my own horizons, but also -contribute to educate others facing the problem of having to handle big number mathematical calculations. - -This book is Tom's child and he has been caring and fostering the project ever since the beginning with a clear mind of -how he wanted the project to turn out. I have helped by proofreading the text and we have had several discussions about -the layout and language used. - -I hold a masters degree in cryptography from the University of Southern Denmark and have always been interested in the -practical aspects of cryptography. - -Having worked in the security consultancy business for several years in S\~{a}o Paulo, Brazil, I have been in touch with a -great deal of work in which multiple precision mathematics was needed. Understanding the possibilities for speeding up -multiple precision calculations is often very important since we deal with outdated machine architecture where modular -reductions, for example, become painfully slow. - -This text is for people who stop and wonder when first examining algorithms such as RSA for the first time and asks -themselves, ``You tell me this is only secure for large numbers, fine; but how do you implement these numbers?'' - -\begin{flushright} -Mads Rasmussen - -S\~{a}o Paulo - SP - -Brazil -\end{flushright} - -\newpage -It's all because I broke my leg. That just happened to be at about the same time that Tom asked for someone to review the section of the book about -Karatsuba multiplication. I was laid up, alone and immobile, and thought ``Why not?'' I vaguely knew what Karatsuba multiplication was, but not -really, so I thought I could help, learn, and stop myself from watching daytime cable TV, all at once. - -At the time of writing this, I've still not met Tom or Mads in meatspace. I've been following Tom's progress since his first splash on the -sci.crypt Usenet news group. I watched him go from a clueless newbie, to the cryptographic equivalent of a reformed smoker, to a real -contributor to the field, over a period of about two years. I've been impressed with his obvious intelligence, and astounded by his productivity. -Of course, he's young enough to be my own child, so he doesn't have my problems with staying awake. - -When I reviewed that single section of the book, in its very earliest form, I was very pleasantly surprised. So I decided to collaborate more fully, -and at least review all of it, and perhaps write some bits too. There's still a long way to go with it, and I have watched a number of close -friends go through the mill of publication, so I think that the way to go is longer than Tom thinks it is. Nevertheless, it's a good effort, -and I'm pleased to be involved with it. - -\begin{flushright} -Greg Rose, Sydney, Australia, June 2003. -\end{flushright} - -\mainmatter -\pagestyle{headings} -\chapter{Introduction} -\section{Multiple Precision Arithmetic} - -\subsection{What is Multiple Precision Arithmetic?} -When we think of long-hand arithmetic such as addition or multiplication we rarely consider the fact that we instinctively -raise or lower the precision of the numbers we are dealing with. For example, in decimal we almost immediate can -reason that $7$ times $6$ is $42$. However, $42$ has two digits of precision as opposed to one digit we started with. -Further multiplications of say $3$ result in a larger precision result $126$. In these few examples we have multiple -precisions for the numbers we are working with. Despite the various levels of precision a single subset\footnote{With the occasional optimization.} - of algorithms can be designed to accomodate them. - -By way of comparison a fixed or single precision operation would lose precision on various operations. For example, in -the decimal system with fixed precision $6 \cdot 7 = 2$. - -Essentially at the heart of computer based multiple precision arithmetic are the same long-hand algorithms taught in -schools to manually add, subtract, multiply and divide. - -\subsection{The Need for Multiple Precision Arithmetic} -The most prevalent need for multiple precision arithmetic, often referred to as ``bignum'' math, is within the implementation -of public-key cryptography algorithms. Algorithms such as RSA \cite{RSAREF} and Diffie-Hellman \cite{DHREF} require -integers of significant magnitude to resist known cryptanalytic attacks. For example, at the time of this writing a -typical RSA modulus would be at least greater than $10^{309}$. However, modern programming languages such as ISO C \cite{ISOC} and -Java \cite{JAVA} only provide instrinsic support for integers which are relatively small and single precision. - -\begin{figure}[!here] -\begin{center} -\begin{tabular}{|r|c|} -\hline \textbf{Data Type} & \textbf{Range} \\ -\hline char & $-128 \ldots 127$ \\ -\hline short & $-32768 \ldots 32767$ \\ -\hline long & $-2147483648 \ldots 2147483647$ \\ -\hline long long & $-9223372036854775808 \ldots 9223372036854775807$ \\ -\hline -\end{tabular} -\end{center} -\caption{Typical Data Types for the C Programming Language} -\label{fig:ISOC} -\end{figure} - -The largest data type guaranteed to be provided by the ISO C programming -language\footnote{As per the ISO C standard. However, each compiler vendor is allowed to augment the precision as they -see fit.} can only represent values up to $10^{19}$ as shown in figure \ref{fig:ISOC}. On its own the C language is -insufficient to accomodate the magnitude required for the problem at hand. An RSA modulus of magnitude $10^{19}$ could be -trivially factored\footnote{A Pollard-Rho factoring would take only $2^{16}$ time.} on the average desktop computer, -rendering any protocol based on the algorithm insecure. Multiple precision algorithms solve this very problem by -extending the range of representable integers while using single precision data types. - -Most advancements in fast multiple precision arithmetic stem from the need for faster and more efficient cryptographic -primitives. Faster modular reduction and exponentiation algorithms such as Barrett's algorithm, which have appeared in -various cryptographic journals, can render algorithms such as RSA and Diffie-Hellman more efficient. In fact, several -major companies such as RSA Security, Certicom and Entrust have built entire product lines on the implementation and -deployment of efficient algorithms. - -However, cryptography is not the only field of study that can benefit from fast multiple precision integer routines. -Another auxiliary use of multiple precision integers is high precision floating point data types. -The basic IEEE \cite{IEEE} standard floating point type is made up of an integer mantissa $q$, an exponent $e$ and a sign bit $s$. -Numbers are given in the form $n = q \cdot b^e \cdot -1^s$ where $b = 2$ is the most common base for IEEE. Since IEEE -floating point is meant to be implemented in hardware the precision of the mantissa is often fairly small -(\textit{23, 48 and 64 bits}). The mantissa is merely an integer and a multiple precision integer could be used to create -a mantissa of much larger precision than hardware alone can efficiently support. This approach could be useful where -scientific applications must minimize the total output error over long calculations. - -Yet another use for large integers is within arithmetic on polynomials of large characteristic (i.e. $GF(p)[x]$ for large $p$). -In fact the library discussed within this text has already been used to form a polynomial basis library\footnote{See \url{http://poly.libtomcrypt.org} for more details.}. - -\subsection{Benefits of Multiple Precision Arithmetic} -\index{precision} -The benefit of multiple precision representations over single or fixed precision representations is that -no precision is lost while representing the result of an operation which requires excess precision. For example, -the product of two $n$-bit integers requires at least $2n$ bits of precision to be represented faithfully. A multiple -precision algorithm would augment the precision of the destination to accomodate the result while a single precision system -would truncate excess bits to maintain a fixed level of precision. - -It is possible to implement algorithms which require large integers with fixed precision algorithms. For example, elliptic -curve cryptography (\textit{ECC}) is often implemented on smartcards by fixing the precision of the integers to the maximum -size the system will ever need. Such an approach can lead to vastly simpler algorithms which can accomodate the -integers required even if the host platform cannot natively accomodate them\footnote{For example, the average smartcard -processor has an 8 bit accumulator.}. However, as efficient as such an approach may be, the resulting source code is not -normally very flexible. It cannot, at runtime, accomodate inputs of higher magnitude than the designer anticipated. - -Multiple precision algorithms have the most overhead of any style of arithmetic. For the the most part the -overhead can be kept to a minimum with careful planning, but overall, it is not well suited for most memory starved -platforms. However, multiple precision algorithms do offer the most flexibility in terms of the magnitude of the -inputs. That is, the same algorithms based on multiple precision integers can accomodate any reasonable size input -without the designer's explicit forethought. This leads to lower cost of ownership for the code as it only has to -be written and tested once. - -\section{Purpose of This Text} -The purpose of this text is to instruct the reader regarding how to implement efficient multiple precision algorithms. -That is to not only explain a limited subset of the core theory behind the algorithms but also the various ``house keeping'' -elements that are neglected by authors of other texts on the subject. Several well reknowned texts \cite{TAOCPV2,HAC} -give considerably detailed explanations of the theoretical aspects of algorithms and often very little information -regarding the practical implementation aspects. - -In most cases how an algorithm is explained and how it is actually implemented are two very different concepts. For -example, the Handbook of Applied Cryptography (\textit{HAC}), algorithm 14.7 on page 594, gives a relatively simple -algorithm for performing multiple precision integer addition. However, the description lacks any discussion concerning -the fact that the two integer inputs may be of differing magnitudes. As a result the implementation is not as simple -as the text would lead people to believe. Similarly the division routine (\textit{algorithm 14.20, pp. 598}) does not -discuss how to handle sign or handle the dividend's decreasing magnitude in the main loop (\textit{step \#3}). - -Both texts also do not discuss several key optimal algorithms required such as ``Comba'' and Karatsuba multipliers -and fast modular inversion, which we consider practical oversights. These optimal algorithms are vital to achieve -any form of useful performance in non-trivial applications. - -To solve this problem the focus of this text is on the practical aspects of implementing a multiple precision integer -package. As a case study the ``LibTomMath''\footnote{Available at \url{http://math.libtomcrypt.com}} package is used -to demonstrate algorithms with real implementations\footnote{In the ISO C programming language.} that have been field -tested and work very well. The LibTomMath library is freely available on the Internet for all uses and this text -discusses a very large portion of the inner workings of the library. - -The algorithms that are presented will always include at least one ``pseudo-code'' description followed -by the actual C source code that implements the algorithm. The pseudo-code can be used to implement the same -algorithm in other programming languages as the reader sees fit. - -This text shall also serve as a walkthrough of the creation of multiple precision algorithms from scratch. Showing -the reader how the algorithms fit together as well as where to start on various taskings. - -\section{Discussion and Notation} -\subsection{Notation} -A multiple precision integer of $n$-digits shall be denoted as $x = (x_{n-1}, \ldots, x_1, x_0)_{ \beta }$ and represent -the integer $x \equiv \sum_{i=0}^{n-1} x_i\beta^i$. The elements of the array $x$ are said to be the radix $\beta$ digits -of the integer. For example, $x = (1,2,3)_{10}$ would represent the integer -$1\cdot 10^2 + 2\cdot10^1 + 3\cdot10^0 = 123$. - -\index{mp\_int} -The term ``mp\_int'' shall refer to a composite structure which contains the digits of the integer it represents, as well -as auxilary data required to manipulate the data. These additional members are discussed further in section -\ref{sec:MPINT}. For the purposes of this text a ``multiple precision integer'' and an ``mp\_int'' are assumed to be -synonymous. When an algorithm is specified to accept an mp\_int variable it is assumed the various auxliary data members -are present as well. An expression of the type \textit{variablename.item} implies that it should evaluate to the -member named ``item'' of the variable. For example, a string of characters may have a member ``length'' which would -evaluate to the number of characters in the string. If the string $a$ equals ``hello'' then it follows that -$a.length = 5$. - -For certain discussions more generic algorithms are presented to help the reader understand the final algorithm used -to solve a given problem. When an algorithm is described as accepting an integer input it is assumed the input is -a plain integer with no additional multiple-precision members. That is, algorithms that use integers as opposed to -mp\_ints as inputs do not concern themselves with the housekeeping operations required such as memory management. These -algorithms will be used to establish the relevant theory which will subsequently be used to describe a multiple -precision algorithm to solve the same problem. - -\subsection{Precision Notation} -The variable $\beta$ represents the radix of a single digit of a multiple precision integer and -must be of the form $q^p$ for $q, p \in \Z^+$. A single precision variable must be able to represent integers in -the range $0 \le x < q \beta$ while a double precision variable must be able to represent integers in the range -$0 \le x < q \beta^2$. The extra radix-$q$ factor allows additions and subtractions to proceed without truncation of the -carry. Since all modern computers are binary, it is assumed that $q$ is two. - -\index{mp\_digit} \index{mp\_word} -Within the source code that will be presented for each algorithm, the data type \textbf{mp\_digit} will represent -a single precision integer type, while, the data type \textbf{mp\_word} will represent a double precision integer type. In -several algorithms (notably the Comba routines) temporary results will be stored in arrays of double precision mp\_words. -For the purposes of this text $x_j$ will refer to the $j$'th digit of a single precision array and $\hat x_j$ will refer to -the $j$'th digit of a double precision array. Whenever an expression is to be assigned to a double precision -variable it is assumed that all single precision variables are promoted to double precision during the evaluation. -Expressions that are assigned to a single precision variable are truncated to fit within the precision of a single -precision data type. - -For example, if $\beta = 10^2$ a single precision data type may represent a value in the -range $0 \le x < 10^3$, while a double precision data type may represent a value in the range $0 \le x < 10^5$. Let -$a = 23$ and $b = 49$ represent two single precision variables. The single precision product shall be written -as $c \leftarrow a \cdot b$ while the double precision product shall be written as $\hat c \leftarrow a \cdot b$. -In this particular case, $\hat c = 1127$ and $c = 127$. The most significant digit of the product would not fit -in a single precision data type and as a result $c \ne \hat c$. - -\subsection{Algorithm Inputs and Outputs} -Within the algorithm descriptions all variables are assumed to be scalars of either single or double precision -as indicated. The only exception to this rule is when variables have been indicated to be of type mp\_int. This -distinction is important as scalars are often used as array indicies and various other counters. - -\subsection{Mathematical Expressions} -The $\lfloor \mbox{ } \rfloor$ brackets imply an expression truncated to an integer not greater than the expression -itself. For example, $\lfloor 5.7 \rfloor = 5$. Similarly the $\lceil \mbox{ } \rceil$ brackets imply an expression -rounded to an integer not less than the expression itself. For example, $\lceil 5.1 \rceil = 6$. Typically when -the $/$ division symbol is used the intention is to perform an integer division with truncation. For example, -$5/2 = 2$ which will often be written as $\lfloor 5/2 \rfloor = 2$ for clarity. When an expression is written as a -fraction a real value division is implied, for example ${5 \over 2} = 2.5$. - -The norm of a multiple precision integer, for example $\vert \vert x \vert \vert$, will be used to represent the number of digits in the representation -of the integer. For example, $\vert \vert 123 \vert \vert = 3$ and $\vert \vert 79452 \vert \vert = 5$. - -\subsection{Work Effort} -\index{big-Oh} -To measure the efficiency of the specified algorithms, a modified big-Oh notation is used. In this system all -single precision operations are considered to have the same cost\footnote{Except where explicitly noted.}. -That is a single precision addition, multiplication and division are assumed to take the same time to -complete. While this is generally not true in practice, it will simplify the discussions considerably. - -Some algorithms have slight advantages over others which is why some constants will not be removed in -the notation. For example, a normal baseline multiplication (section \ref{sec:basemult}) requires $O(n^2)$ work while a -baseline squaring (section \ref{sec:basesquare}) requires $O({{n^2 + n}\over 2})$ work. In standard big-Oh notation these -would both be said to be equivalent to $O(n^2)$. However, -in the context of the this text this is not the case as the magnitude of the inputs will typically be rather small. As a -result small constant factors in the work effort will make an observable difference in algorithm efficiency. - -All of the algorithms presented in this text have a polynomial time work level. That is, of the form -$O(n^k)$ for $n, k \in \Z^{+}$. This will help make useful comparisons in terms of the speed of the algorithms and how -various optimizations will help pay off in the long run. - -\section{Exercises} -Within the more advanced chapters a section will be set aside to give the reader some challenging exercises related to -the discussion at hand. These exercises are not designed to be prize winning problems, but instead to be thought -provoking. Wherever possible the problems are forward minded, stating problems that will be answered in subsequent -chapters. The reader is encouraged to finish the exercises as they appear to get a better understanding of the -subject material. - -That being said, the problems are designed to affirm knowledge of a particular subject matter. Students in particular -are encouraged to verify they can answer the problems correctly before moving on. - -Similar to the exercises of \cite[pp. ix]{TAOCPV2} these exercises are given a scoring system based on the difficulty of -the problem. However, unlike \cite{TAOCPV2} the problems do not get nearly as hard. The scoring of these -exercises ranges from one (the easiest) to five (the hardest). The following table sumarizes the -scoring system used. - -\begin{figure}[here] -\begin{center} -\begin{small} -\begin{tabular}{|c|l|} -\hline $\left [ 1 \right ]$ & An easy problem that should only take the reader a manner of \\ - & minutes to solve. Usually does not involve much computer time \\ - & to solve. \\ -\hline $\left [ 2 \right ]$ & An easy problem that involves a marginal amount of computer \\ - & time usage. Usually requires a program to be written to \\ - & solve the problem. \\ -\hline $\left [ 3 \right ]$ & A moderately hard problem that requires a non-trivial amount \\ - & of work. Usually involves trivial research and development of \\ - & new theory from the perspective of a student. \\ -\hline $\left [ 4 \right ]$ & A moderately hard problem that involves a non-trivial amount \\ - & of work and research, the solution to which will demonstrate \\ - & a higher mastery of the subject matter. \\ -\hline $\left [ 5 \right ]$ & A hard problem that involves concepts that are difficult for a \\ - & novice to solve. Solutions to these problems will demonstrate a \\ - & complete mastery of the given subject. \\ -\hline -\end{tabular} -\end{small} -\end{center} -\caption{Exercise Scoring System} -\end{figure} - -Problems at the first level are meant to be simple questions that the reader can answer quickly without programming a solution or -devising new theory. These problems are quick tests to see if the material is understood. Problems at the second level -are also designed to be easy but will require a program or algorithm to be implemented to arrive at the answer. These -two levels are essentially entry level questions. - -Problems at the third level are meant to be a bit more difficult than the first two levels. The answer is often -fairly obvious but arriving at an exacting solution requires some thought and skill. These problems will almost always -involve devising a new algorithm or implementing a variation of another algorithm previously presented. Readers who can -answer these questions will feel comfortable with the concepts behind the topic at hand. - -Problems at the fourth level are meant to be similar to those of the level three questions except they will require -additional research to be completed. The reader will most likely not know the answer right away, nor will the text provide -the exact details of the answer until a subsequent chapter. - -Problems at the fifth level are meant to be the hardest -problems relative to all the other problems in the chapter. People who can correctly answer fifth level problems have a -mastery of the subject matter at hand. - -Often problems will be tied together. The purpose of this is to start a chain of thought that will be discussed in future chapters. The reader -is encouraged to answer the follow-up problems and try to draw the relevance of problems. - -\section{Introduction to LibTomMath} - -\subsection{What is LibTomMath?} -LibTomMath is a free and open source multiple precision integer library written entirely in portable ISO C. By portable it -is meant that the library does not contain any code that is computer platform dependent or otherwise problematic to use on -any given platform. - -The library has been successfully tested under numerous operating systems including Unix\footnote{All of these -trademarks belong to their respective rightful owners.}, MacOS, Windows, Linux, PalmOS and on standalone hardware such -as the Gameboy Advance. The library is designed to contain enough functionality to be able to develop applications such -as public key cryptosystems and still maintain a relatively small footprint. - -\subsection{Goals of LibTomMath} - -Libraries which obtain the most efficiency are rarely written in a high level programming language such as C. However, -even though this library is written entirely in ISO C, considerable care has been taken to optimize the algorithm implementations within the -library. Specifically the code has been written to work well with the GNU C Compiler (\textit{GCC}) on both x86 and ARM -processors. Wherever possible, highly efficient algorithms, such as Karatsuba multiplication, sliding window -exponentiation and Montgomery reduction have been provided to make the library more efficient. - -Even with the nearly optimal and specialized algorithms that have been included the Application Programing Interface -(\textit{API}) has been kept as simple as possible. Often generic place holder routines will make use of specialized -algorithms automatically without the developer's specific attention. One such example is the generic multiplication -algorithm \textbf{mp\_mul()} which will automatically use Toom--Cook, Karatsuba, Comba or baseline multiplication -based on the magnitude of the inputs and the configuration of the library. - -Making LibTomMath as efficient as possible is not the only goal of the LibTomMath project. Ideally the library should -be source compatible with another popular library which makes it more attractive for developers to use. In this case the -MPI library was used as a API template for all the basic functions. MPI was chosen because it is another library that fits -in the same niche as LibTomMath. Even though LibTomMath uses MPI as the template for the function names and argument -passing conventions, it has been written from scratch by Tom St Denis. - -The project is also meant to act as a learning tool for students, the logic being that no easy-to-follow ``bignum'' -library exists which can be used to teach computer science students how to perform fast and reliable multiple precision -integer arithmetic. To this end the source code has been given quite a few comments and algorithm discussion points. - -\section{Choice of LibTomMath} -LibTomMath was chosen as the case study of this text not only because the author of both projects is one and the same but -for more worthy reasons. Other libraries such as GMP \cite{GMP}, MPI \cite{MPI}, LIP \cite{LIP} and OpenSSL -\cite{OPENSSL} have multiple precision integer arithmetic routines but would not be ideal for this text for -reasons that will be explained in the following sub-sections. - -\subsection{Code Base} -The LibTomMath code base is all portable ISO C source code. This means that there are no platform dependent conditional -segments of code littered throughout the source. This clean and uncluttered approach to the library means that a -developer can more readily discern the true intent of a given section of source code without trying to keep track of -what conditional code will be used. - -The code base of LibTomMath is well organized. Each function is in its own separate source code file -which allows the reader to find a given function very quickly. On average there are $76$ lines of code per source -file which makes the source very easily to follow. By comparison MPI and LIP are single file projects making code tracing -very hard. GMP has many conditional code segments which also hinder tracing. - -When compiled with GCC for the x86 processor and optimized for speed the entire library is approximately $100$KiB\footnote{The notation ``KiB'' means $2^{10}$ octets, similarly ``MiB'' means $2^{20}$ octets.} - which is fairly small compared to GMP (over $250$KiB). LibTomMath is slightly larger than MPI (which compiles to about -$50$KiB) but LibTomMath is also much faster and more complete than MPI. - -\subsection{API Simplicity} -LibTomMath is designed after the MPI library and shares the API design. Quite often programs that use MPI will build -with LibTomMath without change. The function names correlate directly to the action they perform. Almost all of the -functions share the same parameter passing convention. The learning curve is fairly shallow with the API provided -which is an extremely valuable benefit for the student and developer alike. - -The LIP library is an example of a library with an API that is awkward to work with. LIP uses function names that are often ``compressed'' to -illegible short hand. LibTomMath does not share this characteristic. - -The GMP library also does not return error codes. Instead it uses a POSIX.1 \cite{POSIX1} signal system where errors -are signaled to the host application. This happens to be the fastest approach but definitely not the most versatile. In -effect a math error (i.e. invalid input, heap error, etc) can cause a program to stop functioning which is definitely -undersireable in many situations. - -\subsection{Optimizations} -While LibTomMath is certainly not the fastest library (GMP often beats LibTomMath by a factor of two) it does -feature a set of optimal algorithms for tasks such as modular reduction, exponentiation, multiplication and squaring. GMP -and LIP also feature such optimizations while MPI only uses baseline algorithms with no optimizations. GMP lacks a few -of the additional modular reduction optimizations that LibTomMath features\footnote{At the time of this writing GMP -only had Barrett and Montgomery modular reduction algorithms.}. - -LibTomMath is almost always an order of magnitude faster than the MPI library at computationally expensive tasks such as modular -exponentiation. In the grand scheme of ``bignum'' libraries LibTomMath is faster than the average library and usually -slower than the best libraries such as GMP and OpenSSL by only a small factor. - -\subsection{Portability and Stability} -LibTomMath will build ``out of the box'' on any platform equipped with a modern version of the GNU C Compiler -(\textit{GCC}). This means that without changes the library will build without configuration or setting up any -variables. LIP and MPI will build ``out of the box'' as well but have numerous known bugs. Most notably the author of -MPI has recently stopped working on his library and LIP has long since been discontinued. - -GMP requires a configuration script to run and will not build out of the box. GMP and LibTomMath are still in active -development and are very stable across a variety of platforms. - -\subsection{Choice} -LibTomMath is a relatively compact, well documented, highly optimized and portable library which seems only natural for -the case study of this text. Various source files from the LibTomMath project will be included within the text. However, -the reader is encouraged to download their own copy of the library to actually be able to work with the library. - -\chapter{Getting Started} -\section{Library Basics} -The trick to writing any useful library of source code is to build a solid foundation and work outwards from it. First, -a problem along with allowable solution parameters should be identified and analyzed. In this particular case the -inability to accomodate multiple precision integers is the problem. Futhermore, the solution must be written -as portable source code that is reasonably efficient across several different computer platforms. - -After a foundation is formed the remainder of the library can be designed and implemented in a hierarchical fashion. -That is, to implement the lowest level dependencies first and work towards the most abstract functions last. For example, -before implementing a modular exponentiation algorithm one would implement a modular reduction algorithm. -By building outwards from a base foundation instead of using a parallel design methodology the resulting project is -highly modular. Being highly modular is a desirable property of any project as it often means the resulting product -has a small footprint and updates are easy to perform. - -Usually when I start a project I will begin with the header files. I define the data types I think I will need and -prototype the initial functions that are not dependent on other functions (within the library). After I -implement these base functions I prototype more dependent functions and implement them. The process repeats until -I implement all of the functions I require. For example, in the case of LibTomMath I implemented functions such as -mp\_init() well before I implemented mp\_mul() and even further before I implemented mp\_exptmod(). As an example as to -why this design works note that the Karatsuba and Toom-Cook multipliers were written \textit{after} the -dependent function mp\_exptmod() was written. Adding the new multiplication algorithms did not require changes to the -mp\_exptmod() function itself and lowered the total cost of ownership (\textit{so to speak}) and of development -for new algorithms. This methodology allows new algorithms to be tested in a complete framework with relative ease. - -FIGU,design_process,Design Flow of the First Few Original LibTomMath Functions. - -Only after the majority of the functions were in place did I pursue a less hierarchical approach to auditing and optimizing -the source code. For example, one day I may audit the multipliers and the next day the polynomial basis functions. - -It only makes sense to begin the text with the preliminary data types and support algorithms required as well. -This chapter discusses the core algorithms of the library which are the dependents for every other algorithm. - -\section{What is a Multiple Precision Integer?} -Recall that most programming languages, in particular ISO C \cite{ISOC}, only have fixed precision data types that on their own cannot -be used to represent values larger than their precision will allow. The purpose of multiple precision algorithms is -to use fixed precision data types to create and manipulate multiple precision integers which may represent values -that are very large. - -As a well known analogy, school children are taught how to form numbers larger than nine by prepending more radix ten digits. In the decimal system -the largest single digit value is $9$. However, by concatenating digits together larger numbers may be represented. Newly prepended digits -(\textit{to the left}) are said to be in a different power of ten column. That is, the number $123$ can be described as having a $1$ in the hundreds -column, $2$ in the tens column and $3$ in the ones column. Or more formally $123 = 1 \cdot 10^2 + 2 \cdot 10^1 + 3 \cdot 10^0$. Computer based -multiple precision arithmetic is essentially the same concept. Larger integers are represented by adjoining fixed -precision computer words with the exception that a different radix is used. - -What most people probably do not think about explicitly are the various other attributes that describe a multiple precision -integer. For example, the integer $154_{10}$ has two immediately obvious properties. First, the integer is positive, -that is the sign of this particular integer is positive as opposed to negative. Second, the integer has three digits in -its representation. There is an additional property that the integer posesses that does not concern pencil-and-paper -arithmetic. The third property is how many digits placeholders are available to hold the integer. - -The human analogy of this third property is ensuring there is enough space on the paper to write the integer. For example, -if one starts writing a large number too far to the right on a piece of paper they will have to erase it and move left. -Similarly, computer algorithms must maintain strict control over memory usage to ensure that the digits of an integer -will not exceed the allowed boundaries. These three properties make up what is known as a multiple precision -integer or mp\_int for short. - -\subsection{The mp\_int Structure} -\label{sec:MPINT} -The mp\_int structure is the ISO C based manifestation of what represents a multiple precision integer. The ISO C standard does not provide for -any such data type but it does provide for making composite data types known as structures. The following is the structure definition -used within LibTomMath. - -\index{mp\_int} -\begin{figure}[here] -\begin{center} -\begin{small} -%\begin{verbatim} -\begin{tabular}{|l|} -\hline -typedef struct \{ \\ -\hspace{3mm}int used, alloc, sign;\\ -\hspace{3mm}mp\_digit *dp;\\ -\} \textbf{mp\_int}; \\ -\hline -\end{tabular} -%\end{verbatim} -\end{small} -\caption{The mp\_int Structure} -\label{fig:mpint} -\end{center} -\end{figure} - -The mp\_int structure (fig. \ref{fig:mpint}) can be broken down as follows. - -\begin{enumerate} -\item The \textbf{used} parameter denotes how many digits of the array \textbf{dp} contain the digits used to represent -a given integer. The \textbf{used} count must be positive (or zero) and may not exceed the \textbf{alloc} count. - -\item The \textbf{alloc} parameter denotes how -many digits are available in the array to use by functions before it has to increase in size. When the \textbf{used} count -of a result would exceed the \textbf{alloc} count all of the algorithms will automatically increase the size of the -array to accommodate the precision of the result. - -\item The pointer \textbf{dp} points to a dynamically allocated array of digits that represent the given multiple -precision integer. It is padded with $(\textbf{alloc} - \textbf{used})$ zero digits. The array is maintained in a least -significant digit order. As a pencil and paper analogy the array is organized such that the right most digits are stored -first starting at the location indexed by zero\footnote{In C all arrays begin at zero.} in the array. For example, -if \textbf{dp} contains $\lbrace a, b, c, \ldots \rbrace$ where \textbf{dp}$_0 = a$, \textbf{dp}$_1 = b$, \textbf{dp}$_2 = c$, $\ldots$ then -it would represent the integer $a + b\beta + c\beta^2 + \ldots$ - -\index{MP\_ZPOS} \index{MP\_NEG} -\item The \textbf{sign} parameter denotes the sign as either zero/positive (\textbf{MP\_ZPOS}) or negative (\textbf{MP\_NEG}). -\end{enumerate} - -\subsubsection{Valid mp\_int Structures} -Several rules are placed on the state of an mp\_int structure and are assumed to be followed for reasons of efficiency. -The only exceptions are when the structure is passed to initialization functions such as mp\_init() and mp\_init\_copy(). - -\begin{enumerate} -\item The value of \textbf{alloc} may not be less than one. That is \textbf{dp} always points to a previously allocated -array of digits. -\item The value of \textbf{used} may not exceed \textbf{alloc} and must be greater than or equal to zero. -\item The value of \textbf{used} implies the digit at index $(used - 1)$ of the \textbf{dp} array is non-zero. That is, -leading zero digits in the most significant positions must be trimmed. - \begin{enumerate} - \item Digits in the \textbf{dp} array at and above the \textbf{used} location must be zero. - \end{enumerate} -\item The value of \textbf{sign} must be \textbf{MP\_ZPOS} if \textbf{used} is zero; -this represents the mp\_int value of zero. -\end{enumerate} - -\section{Argument Passing} -A convention of argument passing must be adopted early on in the development of any library. Making the function -prototypes consistent will help eliminate many headaches in the future as the library grows to significant complexity. -In LibTomMath the multiple precision integer functions accept parameters from left to right as pointers to mp\_int -structures. That means that the source (input) operands are placed on the left and the destination (output) on the right. -Consider the following examples. - -\begin{verbatim} - mp_mul(&a, &b, &c); /* c = a * b */ - mp_add(&a, &b, &a); /* a = a + b */ - mp_sqr(&a, &b); /* b = a * a */ -\end{verbatim} - -The left to right order is a fairly natural way to implement the functions since it lets the developer read aloud the -functions and make sense of them. For example, the first function would read ``multiply a and b and store in c''. - -Certain libraries (\textit{LIP by Lenstra for instance}) accept parameters the other way around, to mimic the order -of assignment expressions. That is, the destination (output) is on the left and arguments (inputs) are on the right. In -truth, it is entirely a matter of preference. In the case of LibTomMath the convention from the MPI library has been -adopted. - -Another very useful design consideration, provided for in LibTomMath, is whether to allow argument sources to also be a -destination. For example, the second example (\textit{mp\_add}) adds $a$ to $b$ and stores in $a$. This is an important -feature to implement since it allows the calling functions to cut down on the number of variables it must maintain. -However, to implement this feature specific care has to be given to ensure the destination is not modified before the -source is fully read. - -\section{Return Values} -A well implemented application, no matter what its purpose, should trap as many runtime errors as possible and return them -to the caller. By catching runtime errors a library can be guaranteed to prevent undefined behaviour. However, the end -developer can still manage to cause a library to crash. For example, by passing an invalid pointer an application may -fault by dereferencing memory not owned by the application. - -In the case of LibTomMath the only errors that are checked for are related to inappropriate inputs (division by zero for -instance) and memory allocation errors. It will not check that the mp\_int passed to any function is valid nor -will it check pointers for validity. Any function that can cause a runtime error will return an error code as an -\textbf{int} data type with one of the following values (fig \ref{fig:errcodes}). - -\index{MP\_OKAY} \index{MP\_VAL} \index{MP\_MEM} -\begin{figure}[here] -\begin{center} -\begin{tabular}{|l|l|} -\hline \textbf{Value} & \textbf{Meaning} \\ -\hline \textbf{MP\_OKAY} & The function was successful \\ -\hline \textbf{MP\_VAL} & One of the input value(s) was invalid \\ -\hline \textbf{MP\_MEM} & The function ran out of heap memory \\ -\hline -\end{tabular} -\end{center} -\caption{LibTomMath Error Codes} -\label{fig:errcodes} -\end{figure} - -When an error is detected within a function it should free any memory it allocated, often during the initialization of -temporary mp\_ints, and return as soon as possible. The goal is to leave the system in the same state it was when the -function was called. Error checking with this style of API is fairly simple. - -\begin{verbatim} - int err; - if ((err = mp_add(&a, &b, &c)) != MP_OKAY) { - printf("Error: %s\n", mp_error_to_string(err)); - exit(EXIT_FAILURE); - } -\end{verbatim} - -The GMP \cite{GMP} library uses C style \textit{signals} to flag errors which is of questionable use. Not all errors are fatal -and it was not deemed ideal by the author of LibTomMath to force developers to have signal handlers for such cases. - -\section{Initialization and Clearing} -The logical starting point when actually writing multiple precision integer functions is the initialization and -clearing of the mp\_int structures. These two algorithms will be used by the majority of the higher level algorithms. - -Given the basic mp\_int structure an initialization routine must first allocate memory to hold the digits of -the integer. Often it is optimal to allocate a sufficiently large pre-set number of digits even though -the initial integer will represent zero. If only a single digit were allocated quite a few subsequent re-allocations -would occur when operations are performed on the integers. There is a tradeoff between how many default digits to allocate -and how many re-allocations are tolerable. Obviously allocating an excessive amount of digits initially will waste -memory and become unmanageable. - -If the memory for the digits has been successfully allocated then the rest of the members of the structure must -be initialized. Since the initial state of an mp\_int is to represent the zero integer, the allocated digits must be set -to zero. The \textbf{used} count set to zero and \textbf{sign} set to \textbf{MP\_ZPOS}. - -\subsection{Initializing an mp\_int} -An mp\_int is said to be initialized if it is set to a valid, preferably default, state such that all of the members of the -structure are set to valid values. The mp\_init algorithm will perform such an action. - -\index{mp\_init} -\begin{figure}[here] -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_init}. \\ -\textbf{Input}. An mp\_int $a$ \\ -\textbf{Output}. Allocate memory and initialize $a$ to a known valid mp\_int state. \\ -\hline \\ -1. Allocate memory for \textbf{MP\_PREC} digits. \\ -2. If the allocation failed return(\textit{MP\_MEM}) \\ -3. for $n$ from $0$ to $MP\_PREC - 1$ do \\ -\hspace{3mm}3.1 $a_n \leftarrow 0$\\ -4. $a.sign \leftarrow MP\_ZPOS$\\ -5. $a.used \leftarrow 0$\\ -6. $a.alloc \leftarrow MP\_PREC$\\ -7. Return(\textit{MP\_OKAY})\\ -\hline -\end{tabular} -\end{center} -\caption{Algorithm mp\_init} -\end{figure} - -\textbf{Algorithm mp\_init.} -The purpose of this function is to initialize an mp\_int structure so that the rest of the library can properly -manipulte it. It is assumed that the input may not have had any of its members previously initialized which is certainly -a valid assumption if the input resides on the stack. - -Before any of the members such as \textbf{sign}, \textbf{used} or \textbf{alloc} are initialized the memory for -the digits is allocated. If this fails the function returns before setting any of the other members. The \textbf{MP\_PREC} -name represents a constant\footnote{Defined in the ``tommath.h'' header file within LibTomMath.} -used to dictate the minimum precision of newly initialized mp\_int integers. Ideally, it is at least equal to the smallest -precision number you'll be working with. - -Allocating a block of digits at first instead of a single digit has the benefit of lowering the number of usually slow -heap operations later functions will have to perform in the future. If \textbf{MP\_PREC} is set correctly the slack -memory and the number of heap operations will be trivial. - -Once the allocation has been made the digits have to be set to zero as well as the \textbf{used}, \textbf{sign} and -\textbf{alloc} members initialized. This ensures that the mp\_int will always represent the default state of zero regardless -of the original condition of the input. - -\textbf{Remark.} -This function introduces the idiosyncrasy that all iterative loops, commonly initiated with the ``for'' keyword, iterate incrementally -when the ``to'' keyword is placed between two expressions. For example, ``for $a$ from $b$ to $c$ do'' means that -a subsequent expression (or body of expressions) are to be evaluated upto $c - b$ times so long as $b \le c$. In each -iteration the variable $a$ is substituted for a new integer that lies inclusively between $b$ and $c$. If $b > c$ occured -the loop would not iterate. By contrast if the ``downto'' keyword were used in place of ``to'' the loop would iterate -decrementally. - -EXAM,bn_mp_init.c - -One immediate observation of this initializtion function is that it does not return a pointer to a mp\_int structure. It -is assumed that the caller has already allocated memory for the mp\_int structure, typically on the application stack. The -call to mp\_init() is used only to initialize the members of the structure to a known default state. - -Here we see (line @23,XMALLOC@) the memory allocation is performed first. This allows us to exit cleanly and quickly -if there is an error. If the allocation fails the routine will return \textbf{MP\_MEM} to the caller to indicate there -was a memory error. The function XMALLOC is what actually allocates the memory. Technically XMALLOC is not a function -but a macro defined in ``tommath.h``. By default, XMALLOC will evaluate to malloc() which is the C library's built--in -memory allocation routine. - -In order to assure the mp\_int is in a known state the digits must be set to zero. On most platforms this could have been -accomplished by using calloc() instead of malloc(). However, to correctly initialize a integer type to a given value in a -portable fashion you have to actually assign the value. The for loop (line @28,for@) performs this required -operation. - -After the memory has been successfully initialized the remainder of the members are initialized -(lines @29,used@ through @31,sign@) to their respective default states. At this point the algorithm has succeeded and -a success code is returned to the calling function. If this function returns \textbf{MP\_OKAY} it is safe to assume the -mp\_int structure has been properly initialized and is safe to use with other functions within the library. - -\subsection{Clearing an mp\_int} -When an mp\_int is no longer required by the application, the memory that has been allocated for its digits must be -returned to the application's memory pool with the mp\_clear algorithm. - -\begin{figure}[here] -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_clear}. \\ -\textbf{Input}. An mp\_int $a$ \\ -\textbf{Output}. The memory for $a$ shall be deallocated. \\ -\hline \\ -1. If $a$ has been previously freed then return(\textit{MP\_OKAY}). \\ -2. for $n$ from 0 to $a.used - 1$ do \\ -\hspace{3mm}2.1 $a_n \leftarrow 0$ \\ -3. Free the memory allocated for the digits of $a$. \\ -4. $a.used \leftarrow 0$ \\ -5. $a.alloc \leftarrow 0$ \\ -6. $a.sign \leftarrow MP\_ZPOS$ \\ -7. Return(\textit{MP\_OKAY}). \\ -\hline -\end{tabular} -\end{center} -\caption{Algorithm mp\_clear} -\end{figure} - -\textbf{Algorithm mp\_clear.} -This algorithm accomplishes two goals. First, it clears the digits and the other mp\_int members. This ensures that -if a developer accidentally re-uses a cleared structure it is less likely to cause problems. The second goal -is to free the allocated memory. - -The logic behind the algorithm is extended by marking cleared mp\_int structures so that subsequent calls to this -algorithm will not try to free the memory multiple times. Cleared mp\_ints are detectable by having a pre-defined invalid -digit pointer \textbf{dp} setting. - -Once an mp\_int has been cleared the mp\_int structure is no longer in a valid state for any other algorithm -with the exception of algorithms mp\_init, mp\_init\_copy, mp\_init\_size and mp\_clear. - -EXAM,bn_mp_clear.c - -The algorithm only operates on the mp\_int if it hasn't been previously cleared. The if statement (line @23,a->dp != NULL@) -checks to see if the \textbf{dp} member is not \textbf{NULL}. If the mp\_int is a valid mp\_int then \textbf{dp} cannot be -\textbf{NULL} in which case the if statement will evaluate to true. - -The digits of the mp\_int are cleared by the for loop (line @25,for@) which assigns a zero to every digit. Similar to mp\_init() -the digits are assigned zero instead of using block memory operations (such as memset()) since this is more portable. - -The digits are deallocated off the heap via the XFREE macro. Similar to XMALLOC the XFREE macro actually evaluates to -a standard C library function. In this case the free() function. Since free() only deallocates the memory the pointer -still has to be reset to \textbf{NULL} manually (line @33,NULL@). - -Now that the digits have been cleared and deallocated the other members are set to their final values (lines @34,= 0@ and @35,ZPOS@). - -\section{Maintenance Algorithms} - -The previous sections describes how to initialize and clear an mp\_int structure. To further support operations -that are to be performed on mp\_int structures (such as addition and multiplication) the dependent algorithms must be -able to augment the precision of an mp\_int and -initialize mp\_ints with differing initial conditions. - -These algorithms complete the set of low level algorithms required to work with mp\_int structures in the higher level -algorithms such as addition, multiplication and modular exponentiation. - -\subsection{Augmenting an mp\_int's Precision} -When storing a value in an mp\_int structure, a sufficient number of digits must be available to accomodate the entire -result of an operation without loss of precision. Quite often the size of the array given by the \textbf{alloc} member -is large enough to simply increase the \textbf{used} digit count. However, when the size of the array is too small it -must be re-sized appropriately to accomodate the result. The mp\_grow algorithm will provide this functionality. - -\newpage\begin{figure}[here] -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_grow}. \\ -\textbf{Input}. An mp\_int $a$ and an integer $b$. \\ -\textbf{Output}. $a$ is expanded to accomodate $b$ digits. \\ -\hline \\ -1. if $a.alloc \ge b$ then return(\textit{MP\_OKAY}) \\ -2. $u \leftarrow b\mbox{ (mod }MP\_PREC\mbox{)}$ \\ -3. $v \leftarrow b + 2 \cdot MP\_PREC - u$ \\ -4. Re-allocate the array of digits $a$ to size $v$ \\ -5. If the allocation failed then return(\textit{MP\_MEM}). \\ -6. for n from a.alloc to $v - 1$ do \\ -\hspace{+3mm}6.1 $a_n \leftarrow 0$ \\ -7. $a.alloc \leftarrow v$ \\ -8. Return(\textit{MP\_OKAY}) \\ -\hline -\end{tabular} -\end{center} -\caption{Algorithm mp\_grow} -\end{figure} - -\textbf{Algorithm mp\_grow.} -It is ideal to prevent re-allocations from being performed if they are not required (step one). This is useful to -prevent mp\_ints from growing excessively in code that erroneously calls mp\_grow. - -The requested digit count is padded up to next multiple of \textbf{MP\_PREC} plus an additional \textbf{MP\_PREC} (steps two and three). -This helps prevent many trivial reallocations that would grow an mp\_int by trivially small values. - -It is assumed that the reallocation (step four) leaves the lower $a.alloc$ digits of the mp\_int intact. This is much -akin to how the \textit{realloc} function from the standard C library works. Since the newly allocated digits are -assumed to contain undefined values they are initially set to zero. - -EXAM,bn_mp_grow.c - -A quick optimization is to first determine if a memory re-allocation is required at all. The if statement (line @24,alloc@) checks -if the \textbf{alloc} member of the mp\_int is smaller than the requested digit count. If the count is not larger than \textbf{alloc} -the function skips the re-allocation part thus saving time. - -When a re-allocation is performed it is turned into an optimal request to save time in the future. The requested digit count is -padded upwards to 2nd multiple of \textbf{MP\_PREC} larger than \textbf{alloc} (line @25, size@). The XREALLOC function is used -to re-allocate the memory. As per the other functions XREALLOC is actually a macro which evaluates to realloc by default. The realloc -function leaves the base of the allocation intact which means the first \textbf{alloc} digits of the mp\_int are the same as before -the re-allocation. All that is left is to clear the newly allocated digits and return. - -Note that the re-allocation result is actually stored in a temporary pointer $tmp$. This is to allow this function to return -an error with a valid pointer. Earlier releases of the library stored the result of XREALLOC into the mp\_int $a$. That would -result in a memory leak if XREALLOC ever failed. - -\subsection{Initializing Variable Precision mp\_ints} -Occasionally the number of digits required will be known in advance of an initialization, based on, for example, the size -of input mp\_ints to a given algorithm. The purpose of algorithm mp\_init\_size is similar to mp\_init except that it -will allocate \textit{at least} a specified number of digits. - -\begin{figure}[here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_init\_size}. \\ -\textbf{Input}. An mp\_int $a$ and the requested number of digits $b$. \\ -\textbf{Output}. $a$ is initialized to hold at least $b$ digits. \\ -\hline \\ -1. $u \leftarrow b \mbox{ (mod }MP\_PREC\mbox{)}$ \\ -2. $v \leftarrow b + 2 \cdot MP\_PREC - u$ \\ -3. Allocate $v$ digits. \\ -4. for $n$ from $0$ to $v - 1$ do \\ -\hspace{3mm}4.1 $a_n \leftarrow 0$ \\ -5. $a.sign \leftarrow MP\_ZPOS$\\ -6. $a.used \leftarrow 0$\\ -7. $a.alloc \leftarrow v$\\ -8. Return(\textit{MP\_OKAY})\\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm mp\_init\_size} -\end{figure} - -\textbf{Algorithm mp\_init\_size.} -This algorithm will initialize an mp\_int structure $a$ like algorithm mp\_init with the exception that the number of -digits allocated can be controlled by the second input argument $b$. The input size is padded upwards so it is a -multiple of \textbf{MP\_PREC} plus an additional \textbf{MP\_PREC} digits. This padding is used to prevent trivial -allocations from becoming a bottleneck in the rest of the algorithms. - -Like algorithm mp\_init, the mp\_int structure is initialized to a default state representing the integer zero. This -particular algorithm is useful if it is known ahead of time the approximate size of the input. If the approximation is -correct no further memory re-allocations are required to work with the mp\_int. - -EXAM,bn_mp_init_size.c - -The number of digits $b$ requested is padded (line @22,MP_PREC@) by first augmenting it to the next multiple of -\textbf{MP\_PREC} and then adding \textbf{MP\_PREC} to the result. If the memory can be successfully allocated the -mp\_int is placed in a default state representing the integer zero. Otherwise, the error code \textbf{MP\_MEM} will be -returned (line @27,return@). - -The digits are allocated and set to zero at the same time with the calloc() function (line @25,XCALLOC@). The -\textbf{used} count is set to zero, the \textbf{alloc} count set to the padded digit count and the \textbf{sign} flag set -to \textbf{MP\_ZPOS} to achieve a default valid mp\_int state (lines @29,used@, @30,alloc@ and @31,sign@). If the function -returns succesfully then it is correct to assume that the mp\_int structure is in a valid state for the remainder of the -functions to work with. - -\subsection{Multiple Integer Initializations and Clearings} -Occasionally a function will require a series of mp\_int data types to be made available simultaneously. -The purpose of algorithm mp\_init\_multi is to initialize a variable length array of mp\_int structures in a single -statement. It is essentially a shortcut to multiple initializations. - -\newpage\begin{figure}[here] -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_init\_multi}. \\ -\textbf{Input}. Variable length array $V_k$ of mp\_int variables of length $k$. \\ -\textbf{Output}. The array is initialized such that each mp\_int of $V_k$ is ready to use. \\ -\hline \\ -1. for $n$ from 0 to $k - 1$ do \\ -\hspace{+3mm}1.1. Initialize the mp\_int $V_n$ (\textit{mp\_init}) \\ -\hspace{+3mm}1.2. If initialization failed then do \\ -\hspace{+6mm}1.2.1. for $j$ from $0$ to $n$ do \\ -\hspace{+9mm}1.2.1.1. Free the mp\_int $V_j$ (\textit{mp\_clear}) \\ -\hspace{+6mm}1.2.2. Return(\textit{MP\_MEM}) \\ -2. Return(\textit{MP\_OKAY}) \\ -\hline -\end{tabular} -\end{center} -\caption{Algorithm mp\_init\_multi} -\end{figure} - -\textbf{Algorithm mp\_init\_multi.} -The algorithm will initialize the array of mp\_int variables one at a time. If a runtime error has been detected -(\textit{step 1.2}) all of the previously initialized variables are cleared. The goal is an ``all or nothing'' -initialization which allows for quick recovery from runtime errors. - -EXAM,bn_mp_init_multi.c - -This function intializes a variable length list of mp\_int structure pointers. However, instead of having the mp\_int -structures in an actual C array they are simply passed as arguments to the function. This function makes use of the -``...'' argument syntax of the C programming language. The list is terminated with a final \textbf{NULL} argument -appended on the right. - -The function uses the ``stdarg.h'' \textit{va} functions to step portably through the arguments to the function. A count -$n$ of succesfully initialized mp\_int structures is maintained (line @47,n++@) such that if a failure does occur, -the algorithm can backtrack and free the previously initialized structures (lines @27,if@ to @46,}@). - - -\subsection{Clamping Excess Digits} -When a function anticipates a result will be $n$ digits it is simpler to assume this is true within the body of -the function instead of checking during the computation. For example, a multiplication of a $i$ digit number by a -$j$ digit produces a result of at most $i + j$ digits. It is entirely possible that the result is $i + j - 1$ -though, with no final carry into the last position. However, suppose the destination had to be first expanded -(\textit{via mp\_grow}) to accomodate $i + j - 1$ digits than further expanded to accomodate the final carry. -That would be a considerable waste of time since heap operations are relatively slow. - -The ideal solution is to always assume the result is $i + j$ and fix up the \textbf{used} count after the function -terminates. This way a single heap operation (\textit{at most}) is required. However, if the result was not checked -there would be an excess high order zero digit. - -For example, suppose the product of two integers was $x_n = (0x_{n-1}x_{n-2}...x_0)_{\beta}$. The leading zero digit -will not contribute to the precision of the result. In fact, through subsequent operations more leading zero digits would -accumulate to the point the size of the integer would be prohibitive. As a result even though the precision is very -low the representation is excessively large. - -The mp\_clamp algorithm is designed to solve this very problem. It will trim high-order zeros by decrementing the -\textbf{used} count until a non-zero most significant digit is found. Also in this system, zero is considered to be a -positive number which means that if the \textbf{used} count is decremented to zero, the sign must be set to -\textbf{MP\_ZPOS}. - -\begin{figure}[here] -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_clamp}. \\ -\textbf{Input}. An mp\_int $a$ \\ -\textbf{Output}. Any excess leading zero digits of $a$ are removed \\ -\hline \\ -1. while $a.used > 0$ and $a_{a.used - 1} = 0$ do \\ -\hspace{+3mm}1.1 $a.used \leftarrow a.used - 1$ \\ -2. if $a.used = 0$ then do \\ -\hspace{+3mm}2.1 $a.sign \leftarrow MP\_ZPOS$ \\ -\hline \\ -\end{tabular} -\end{center} -\caption{Algorithm mp\_clamp} -\end{figure} - -\textbf{Algorithm mp\_clamp.} -As can be expected this algorithm is very simple. The loop on step one is expected to iterate only once or twice at -the most. For example, this will happen in cases where there is not a carry to fill the last position. Step two fixes the sign for -when all of the digits are zero to ensure that the mp\_int is valid at all times. - -EXAM,bn_mp_clamp.c - -Note on line @27,while@ how to test for the \textbf{used} count is made on the left of the \&\& operator. In the C programming -language the terms to \&\& are evaluated left to right with a boolean short-circuit if any condition fails. This is -important since if the \textbf{used} is zero the test on the right would fetch below the array. That is obviously -undesirable. The parenthesis on line @28,a->used@ is used to make sure the \textbf{used} count is decremented and not -the pointer ``a''. - -\section*{Exercises} -\begin{tabular}{cl} -$\left [ 1 \right ]$ & Discuss the relevance of the \textbf{used} member of the mp\_int structure. \\ - & \\ -$\left [ 1 \right ]$ & Discuss the consequences of not using padding when performing allocations. \\ - & \\ -$\left [ 2 \right ]$ & Estimate an ideal value for \textbf{MP\_PREC} when performing 1024-bit RSA \\ - & encryption when $\beta = 2^{28}$. \\ - & \\ -$\left [ 1 \right ]$ & Discuss the relevance of the algorithm mp\_clamp. What does it prevent? \\ - & \\ -$\left [ 1 \right ]$ & Give an example of when the algorithm mp\_init\_copy might be useful. \\ - & \\ -\end{tabular} - - -%%% -% CHAPTER FOUR -%%% - -\chapter{Basic Operations} - -\section{Introduction} -In the previous chapter a series of low level algorithms were established that dealt with initializing and maintaining -mp\_int structures. This chapter will discuss another set of seemingly non-algebraic algorithms which will form the low -level basis of the entire library. While these algorithm are relatively trivial it is important to understand how they -work before proceeding since these algorithms will be used almost intrinsically in the following chapters. - -The algorithms in this chapter deal primarily with more ``programmer'' related tasks such as creating copies of -mp\_int structures, assigning small values to mp\_int structures and comparisons of the values mp\_int structures -represent. - -\section{Assigning Values to mp\_int Structures} -\subsection{Copying an mp\_int} -Assigning the value that a given mp\_int structure represents to another mp\_int structure shall be known as making -a copy for the purposes of this text. The copy of the mp\_int will be a separate entity that represents the same -value as the mp\_int it was copied from. The mp\_copy algorithm provides this functionality. - -\newpage\begin{figure}[here] -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_copy}. \\ -\textbf{Input}. An mp\_int $a$ and $b$. \\ -\textbf{Output}. Store a copy of $a$ in $b$. \\ -\hline \\ -1. If $b.alloc < a.used$ then grow $b$ to $a.used$ digits. (\textit{mp\_grow}) \\ -2. for $n$ from 0 to $a.used - 1$ do \\ -\hspace{3mm}2.1 $b_{n} \leftarrow a_{n}$ \\ -3. for $n$ from $a.used$ to $b.used - 1$ do \\ -\hspace{3mm}3.1 $b_{n} \leftarrow 0$ \\ -4. $b.used \leftarrow a.used$ \\ -5. $b.sign \leftarrow a.sign$ \\ -6. return(\textit{MP\_OKAY}) \\ -\hline -\end{tabular} -\end{center} -\caption{Algorithm mp\_copy} -\end{figure} - -\textbf{Algorithm mp\_copy.} -This algorithm copies the mp\_int $a$ such that upon succesful termination of the algorithm the mp\_int $b$ will -represent the same integer as the mp\_int $a$. The mp\_int $b$ shall be a complete and distinct copy of the -mp\_int $a$ meaing that the mp\_int $a$ can be modified and it shall not affect the value of the mp\_int $b$. - -If $b$ does not have enough room for the digits of $a$ it must first have its precision augmented via the mp\_grow -algorithm. The digits of $a$ are copied over the digits of $b$ and any excess digits of $b$ are set to zero (step two -and three). The \textbf{used} and \textbf{sign} members of $a$ are finally copied over the respective members of -$b$. - -\textbf{Remark.} This algorithm also introduces a new idiosyncrasy that will be used throughout the rest of the -text. The error return codes of other algorithms are not explicitly checked in the pseudo-code presented. For example, in -step one of the mp\_copy algorithm the return of mp\_grow is not explicitly checked to ensure it succeeded. Text space is -limited so it is assumed that if a algorithm fails it will clear all temporarily allocated mp\_ints and return -the error code itself. However, the C code presented will demonstrate all of the error handling logic required to -implement the pseudo-code. - -EXAM,bn_mp_copy.c - -Occasionally a dependent algorithm may copy an mp\_int effectively into itself such as when the input and output -mp\_int structures passed to a function are one and the same. For this case it is optimal to return immediately without -copying digits (line @24,a == b@). - -The mp\_int $b$ must have enough digits to accomodate the used digits of the mp\_int $a$. If $b.alloc$ is less than -$a.used$ the algorithm mp\_grow is used to augment the precision of $b$ (lines @29,alloc@ to @33,}@). In order to -simplify the inner loop that copies the digits from $a$ to $b$, two aliases $tmpa$ and $tmpb$ point directly at the digits -of the mp\_ints $a$ and $b$ respectively. These aliases (lines @42,tmpa@ and @45,tmpb@) allow the compiler to access the digits without first dereferencing the -mp\_int pointers and then subsequently the pointer to the digits. - -After the aliases are established the digits from $a$ are copied into $b$ (lines @48,for@ to @50,}@) and then the excess -digits of $b$ are set to zero (lines @53,for@ to @55,}@). Both ``for'' loops make use of the pointer aliases and in -fact the alias for $b$ is carried through into the second ``for'' loop to clear the excess digits. This optimization -allows the alias to stay in a machine register fairly easy between the two loops. - -\textbf{Remarks.} The use of pointer aliases is an implementation methodology first introduced in this function that will -be used considerably in other functions. Technically, a pointer alias is simply a short hand alias used to lower the -number of pointer dereferencing operations required to access data. For example, a for loop may resemble - -\begin{alltt} -for (x = 0; x < 100; x++) \{ - a->num[4]->dp[x] = 0; -\} -\end{alltt} - -This could be re-written using aliases as - -\begin{alltt} -mp_digit *tmpa; -a = a->num[4]->dp; -for (x = 0; x < 100; x++) \{ - *a++ = 0; -\} -\end{alltt} - -In this case an alias is used to access the -array of digits within an mp\_int structure directly. It may seem that a pointer alias is strictly not required -as a compiler may optimize out the redundant pointer operations. However, there are two dominant reasons to use aliases. - -The first reason is that most compilers will not effectively optimize pointer arithmetic. For example, some optimizations -may work for the Microsoft Visual C++ compiler (MSVC) and not for the GNU C Compiler (GCC). Also some optimizations may -work for GCC and not MSVC. As such it is ideal to find a common ground for as many compilers as possible. Pointer -aliases optimize the code considerably before the compiler even reads the source code which means the end compiled code -stands a better chance of being faster. - -The second reason is that pointer aliases often can make an algorithm simpler to read. Consider the first ``for'' -loop of the function mp\_copy() re-written to not use pointer aliases. - -\begin{alltt} - /* copy all the digits */ - for (n = 0; n < a->used; n++) \{ - b->dp[n] = a->dp[n]; - \} -\end{alltt} - -Whether this code is harder to read depends strongly on the individual. However, it is quantifiably slightly more -complicated as there are four variables within the statement instead of just two. - -\subsubsection{Nested Statements} -Another commonly used technique in the source routines is that certain sections of code are nested. This is used in -particular with the pointer aliases to highlight code phases. For example, a Comba multiplier (discussed in chapter six) -will typically have three different phases. First the temporaries are initialized, then the columns calculated and -finally the carries are propagated. In this example the middle column production phase will typically be nested as it -uses temporary variables and aliases the most. - -The nesting also simplies the source code as variables that are nested are only valid for their scope. As a result -the various temporary variables required do not propagate into other sections of code. - - -\subsection{Creating a Clone} -Another common operation is to make a local temporary copy of an mp\_int argument. To initialize an mp\_int -and then copy another existing mp\_int into the newly intialized mp\_int will be known as creating a clone. This is -useful within functions that need to modify an argument but do not wish to actually modify the original copy. The -mp\_init\_copy algorithm has been designed to help perform this task. - -\begin{figure}[here] -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_init\_copy}. \\ -\textbf{Input}. An mp\_int $a$ and $b$\\ -\textbf{Output}. $a$ is initialized to be a copy of $b$. \\ -\hline \\ -1. Init $a$. (\textit{mp\_init}) \\ -2. Copy $b$ to $a$. (\textit{mp\_copy}) \\ -3. Return the status of the copy operation. \\ -\hline -\end{tabular} -\end{center} -\caption{Algorithm mp\_init\_copy} -\end{figure} - -\textbf{Algorithm mp\_init\_copy.} -This algorithm will initialize an mp\_int variable and copy another previously initialized mp\_int variable into it. As -such this algorithm will perform two operations in one step. - -EXAM,bn_mp_init_copy.c - -This will initialize \textbf{a} and make it a verbatim copy of the contents of \textbf{b}. Note that -\textbf{a} will have its own memory allocated which means that \textbf{b} may be cleared after the call -and \textbf{a} will be left intact. - -\section{Zeroing an Integer} -Reseting an mp\_int to the default state is a common step in many algorithms. The mp\_zero algorithm will be the algorithm used to -perform this task. - -\begin{figure}[here] -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_zero}. \\ -\textbf{Input}. An mp\_int $a$ \\ -\textbf{Output}. Zero the contents of $a$ \\ -\hline \\ -1. $a.used \leftarrow 0$ \\ -2. $a.sign \leftarrow$ MP\_ZPOS \\ -3. for $n$ from 0 to $a.alloc - 1$ do \\ -\hspace{3mm}3.1 $a_n \leftarrow 0$ \\ -\hline -\end{tabular} -\end{center} -\caption{Algorithm mp\_zero} -\end{figure} - -\textbf{Algorithm mp\_zero.} -This algorithm simply resets a mp\_int to the default state. - -EXAM,bn_mp_zero.c - -After the function is completed, all of the digits are zeroed, the \textbf{used} count is zeroed and the -\textbf{sign} variable is set to \textbf{MP\_ZPOS}. - -\section{Sign Manipulation} -\subsection{Absolute Value} -With the mp\_int representation of an integer, calculating the absolute value is trivial. The mp\_abs algorithm will compute -the absolute value of an mp\_int. - -\begin{figure}[here] -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_abs}. \\ -\textbf{Input}. An mp\_int $a$ \\ -\textbf{Output}. Computes $b = \vert a \vert$ \\ -\hline \\ -1. Copy $a$ to $b$. (\textit{mp\_copy}) \\ -2. If the copy failed return(\textit{MP\_MEM}). \\ -3. $b.sign \leftarrow MP\_ZPOS$ \\ -4. Return(\textit{MP\_OKAY}) \\ -\hline -\end{tabular} -\end{center} -\caption{Algorithm mp\_abs} -\end{figure} - -\textbf{Algorithm mp\_abs.} -This algorithm computes the absolute of an mp\_int input. First it copies $a$ over $b$. This is an example of an -algorithm where the check in mp\_copy that determines if the source and destination are equal proves useful. This allows, -for instance, the developer to pass the same mp\_int as the source and destination to this function without addition -logic to handle it. - -EXAM,bn_mp_abs.c - -This fairly trivial algorithm first eliminates non--required duplications (line @27,a != b@) and then sets the -\textbf{sign} flag to \textbf{MP\_ZPOS}. - -\subsection{Integer Negation} -With the mp\_int representation of an integer, calculating the negation is also trivial. The mp\_neg algorithm will compute -the negative of an mp\_int input. - -\begin{figure}[here] -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_neg}. \\ -\textbf{Input}. An mp\_int $a$ \\ -\textbf{Output}. Computes $b = -a$ \\ -\hline \\ -1. Copy $a$ to $b$. (\textit{mp\_copy}) \\ -2. If the copy failed return(\textit{MP\_MEM}). \\ -3. If $a.used = 0$ then return(\textit{MP\_OKAY}). \\ -4. If $a.sign = MP\_ZPOS$ then do \\ -\hspace{3mm}4.1 $b.sign = MP\_NEG$. \\ -5. else do \\ -\hspace{3mm}5.1 $b.sign = MP\_ZPOS$. \\ -6. Return(\textit{MP\_OKAY}) \\ -\hline -\end{tabular} -\end{center} -\caption{Algorithm mp\_neg} -\end{figure} - -\textbf{Algorithm mp\_neg.} -This algorithm computes the negation of an input. First it copies $a$ over $b$. If $a$ has no used digits then -the algorithm returns immediately. Otherwise it flips the sign flag and stores the result in $b$. Note that if -$a$ had no digits then it must be positive by definition. Had step three been omitted then the algorithm would return -zero as negative. - -EXAM,bn_mp_neg.c - -Like mp\_abs() this function avoids non--required duplications (line @21,a != b@) and then sets the sign. We -have to make sure that only non--zero values get a \textbf{sign} of \textbf{MP\_NEG}. If the mp\_int is zero -than the \textbf{sign} is hard--coded to \textbf{MP\_ZPOS}. - -\section{Small Constants} -\subsection{Setting Small Constants} -Often a mp\_int must be set to a relatively small value such as $1$ or $2$. For these cases the mp\_set algorithm is useful. - -\newpage\begin{figure}[here] -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_set}. \\ -\textbf{Input}. An mp\_int $a$ and a digit $b$ \\ -\textbf{Output}. Make $a$ equivalent to $b$ \\ -\hline \\ -1. Zero $a$ (\textit{mp\_zero}). \\ -2. $a_0 \leftarrow b \mbox{ (mod }\beta\mbox{)}$ \\ -3. $a.used \leftarrow \left \lbrace \begin{array}{ll} - 1 & \mbox{if }a_0 > 0 \\ - 0 & \mbox{if }a_0 = 0 - \end{array} \right .$ \\ -\hline -\end{tabular} -\end{center} -\caption{Algorithm mp\_set} -\end{figure} - -\textbf{Algorithm mp\_set.} -This algorithm sets a mp\_int to a small single digit value. Step number 1 ensures that the integer is reset to the default state. The -single digit is set (\textit{modulo $\beta$}) and the \textbf{used} count is adjusted accordingly. - -EXAM,bn_mp_set.c - -First we zero (line @21,mp_zero@) the mp\_int to make sure that the other members are initialized for a -small positive constant. mp\_zero() ensures that the \textbf{sign} is positive and the \textbf{used} count -is zero. Next we set the digit and reduce it modulo $\beta$ (line @22,MP_MASK@). After this step we have to -check if the resulting digit is zero or not. If it is not then we set the \textbf{used} count to one, otherwise -to zero. - -We can quickly reduce modulo $\beta$ since it is of the form $2^k$ and a quick binary AND operation with -$2^k - 1$ will perform the same operation. - -One important limitation of this function is that it will only set one digit. The size of a digit is not fixed, meaning source that uses -this function should take that into account. Only trivially small constants can be set using this function. - -\subsection{Setting Large Constants} -To overcome the limitations of the mp\_set algorithm the mp\_set\_int algorithm is ideal. It accepts a ``long'' -data type as input and will always treat it as a 32-bit integer. - -\begin{figure}[here] -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_set\_int}. \\ -\textbf{Input}. An mp\_int $a$ and a ``long'' integer $b$ \\ -\textbf{Output}. Make $a$ equivalent to $b$ \\ -\hline \\ -1. Zero $a$ (\textit{mp\_zero}) \\ -2. for $n$ from 0 to 7 do \\ -\hspace{3mm}2.1 $a \leftarrow a \cdot 16$ (\textit{mp\_mul2d}) \\ -\hspace{3mm}2.2 $u \leftarrow \lfloor b / 2^{4(7 - n)} \rfloor \mbox{ (mod }16\mbox{)}$\\ -\hspace{3mm}2.3 $a_0 \leftarrow a_0 + u$ \\ -\hspace{3mm}2.4 $a.used \leftarrow a.used + 1$ \\ -3. Clamp excess used digits (\textit{mp\_clamp}) \\ -\hline -\end{tabular} -\end{center} -\caption{Algorithm mp\_set\_int} -\end{figure} - -\textbf{Algorithm mp\_set\_int.} -The algorithm performs eight iterations of a simple loop where in each iteration four bits from the source are added to the -mp\_int. Step 2.1 will multiply the current result by sixteen making room for four more bits in the less significant positions. In step 2.2 the -next four bits from the source are extracted and are added to the mp\_int. The \textbf{used} digit count is -incremented to reflect the addition. The \textbf{used} digit counter is incremented since if any of the leading digits were zero the mp\_int would have -zero digits used and the newly added four bits would be ignored. - -Excess zero digits are trimmed in steps 2.1 and 3 by using higher level algorithms mp\_mul2d and mp\_clamp. - -EXAM,bn_mp_set_int.c - -This function sets four bits of the number at a time to handle all practical \textbf{DIGIT\_BIT} sizes. The weird -addition on line @38,a->used@ ensures that the newly added in bits are added to the number of digits. While it may not -seem obvious as to why the digit counter does not grow exceedingly large it is because of the shift on line @27,mp_mul_2d@ -as well as the call to mp\_clamp() on line @40,mp_clamp@. Both functions will clamp excess leading digits which keeps -the number of used digits low. - -\section{Comparisons} -\subsection{Unsigned Comparisions} -Comparing a multiple precision integer is performed with the exact same algorithm used to compare two decimal numbers. For example, -to compare $1,234$ to $1,264$ the digits are extracted by their positions. That is we compare $1 \cdot 10^3 + 2 \cdot 10^2 + 3 \cdot 10^1 + 4 \cdot 10^0$ -to $1 \cdot 10^3 + 2 \cdot 10^2 + 6 \cdot 10^1 + 4 \cdot 10^0$ by comparing single digits at a time starting with the highest magnitude -positions. If any leading digit of one integer is greater than a digit in the same position of another integer then obviously it must be greater. - -The first comparision routine that will be developed is the unsigned magnitude compare which will perform a comparison based on the digits of two -mp\_int variables alone. It will ignore the sign of the two inputs. Such a function is useful when an absolute comparison is required or if the -signs are known to agree in advance. - -To facilitate working with the results of the comparison functions three constants are required. - -\begin{figure}[here] -\begin{center} -\begin{tabular}{|r|l|} -\hline \textbf{Constant} & \textbf{Meaning} \\ -\hline \textbf{MP\_GT} & Greater Than \\ -\hline \textbf{MP\_EQ} & Equal To \\ -\hline \textbf{MP\_LT} & Less Than \\ -\hline -\end{tabular} -\end{center} -\caption{Comparison Return Codes} -\end{figure} - -\begin{figure}[here] -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_cmp\_mag}. \\ -\textbf{Input}. Two mp\_ints $a$ and $b$. \\ -\textbf{Output}. Unsigned comparison results ($a$ to the left of $b$). \\ -\hline \\ -1. If $a.used > b.used$ then return(\textit{MP\_GT}) \\ -2. If $a.used < b.used$ then return(\textit{MP\_LT}) \\ -3. for n from $a.used - 1$ to 0 do \\ -\hspace{+3mm}3.1 if $a_n > b_n$ then return(\textit{MP\_GT}) \\ -\hspace{+3mm}3.2 if $a_n < b_n$ then return(\textit{MP\_LT}) \\ -4. Return(\textit{MP\_EQ}) \\ -\hline -\end{tabular} -\end{center} -\caption{Algorithm mp\_cmp\_mag} -\end{figure} - -\textbf{Algorithm mp\_cmp\_mag.} -By saying ``$a$ to the left of $b$'' it is meant that the comparison is with respect to $a$, that is if $a$ is greater than $b$ it will return -\textbf{MP\_GT} and similar with respect to when $a = b$ and $a < b$. The first two steps compare the number of digits used in both $a$ and $b$. -Obviously if the digit counts differ there would be an imaginary zero digit in the smaller number where the leading digit of the larger number is. -If both have the same number of digits than the actual digits themselves must be compared starting at the leading digit. - -By step three both inputs must have the same number of digits so its safe to start from either $a.used - 1$ or $b.used - 1$ and count down to -the zero'th digit. If after all of the digits have been compared, no difference is found, the algorithm returns \textbf{MP\_EQ}. - -EXAM,bn_mp_cmp_mag.c - -The two if statements (lines @24,if@ and @28,if@) compare the number of digits in the two inputs. These two are -performed before all of the digits are compared since it is a very cheap test to perform and can potentially save -considerable time. The implementation given is also not valid without those two statements. $b.alloc$ may be -smaller than $a.used$, meaning that undefined values will be read from $b$ past the end of the array of digits. - - - -\subsection{Signed Comparisons} -Comparing with sign considerations is also fairly critical in several routines (\textit{division for example}). Based on an unsigned magnitude -comparison a trivial signed comparison algorithm can be written. - -\begin{figure}[here] -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_cmp}. \\ -\textbf{Input}. Two mp\_ints $a$ and $b$ \\ -\textbf{Output}. Signed Comparison Results ($a$ to the left of $b$) \\ -\hline \\ -1. if $a.sign = MP\_NEG$ and $b.sign = MP\_ZPOS$ then return(\textit{MP\_LT}) \\ -2. if $a.sign = MP\_ZPOS$ and $b.sign = MP\_NEG$ then return(\textit{MP\_GT}) \\ -3. if $a.sign = MP\_NEG$ then \\ -\hspace{+3mm}3.1 Return the unsigned comparison of $b$ and $a$ (\textit{mp\_cmp\_mag}) \\ -4 Otherwise \\ -\hspace{+3mm}4.1 Return the unsigned comparison of $a$ and $b$ \\ -\hline -\end{tabular} -\end{center} -\caption{Algorithm mp\_cmp} -\end{figure} - -\textbf{Algorithm mp\_cmp.} -The first two steps compare the signs of the two inputs. If the signs do not agree then it can return right away with the appropriate -comparison code. When the signs are equal the digits of the inputs must be compared to determine the correct result. In step -three the unsigned comparision flips the order of the arguments since they are both negative. For instance, if $-a > -b$ then -$\vert a \vert < \vert b \vert$. Step number four will compare the two when they are both positive. - -EXAM,bn_mp_cmp.c - -The two if statements (lines @22,if@ and @26,if@) perform the initial sign comparison. If the signs are not the equal then which ever -has the positive sign is larger. The inputs are compared (line @30,if@) based on magnitudes. If the signs were both -negative then the unsigned comparison is performed in the opposite direction (line @31,mp_cmp_mag@). Otherwise, the signs are assumed to -be both positive and a forward direction unsigned comparison is performed. - -\section*{Exercises} -\begin{tabular}{cl} -$\left [ 2 \right ]$ & Modify algorithm mp\_set\_int to accept as input a variable length array of bits. \\ - & \\ -$\left [ 3 \right ]$ & Give the probability that algorithm mp\_cmp\_mag will have to compare $k$ digits \\ - & of two random digits (of equal magnitude) before a difference is found. \\ - & \\ -$\left [ 1 \right ]$ & Suggest a simple method to speed up the implementation of mp\_cmp\_mag based \\ - & on the observations made in the previous problem. \\ - & -\end{tabular} - -\chapter{Basic Arithmetic} -\section{Introduction} -At this point algorithms for initialization, clearing, zeroing, copying, comparing and setting small constants have been -established. The next logical set of algorithms to develop are addition, subtraction and digit shifting algorithms. These -algorithms make use of the lower level algorithms and are the cruicial building block for the multiplication algorithms. It is very important -that these algorithms are highly optimized. On their own they are simple $O(n)$ algorithms but they can be called from higher level algorithms -which easily places them at $O(n^2)$ or even $O(n^3)$ work levels. - -MARK,SHIFTS -All of the algorithms within this chapter make use of the logical bit shift operations denoted by $<<$ and $>>$ for left and right -logical shifts respectively. A logical shift is analogous to sliding the decimal point of radix-10 representations. For example, the real -number $0.9345$ is equivalent to $93.45\%$ which is found by sliding the the decimal two places to the right (\textit{multiplying by $\beta^2 = 10^2$}). -Algebraically a binary logical shift is equivalent to a division or multiplication by a power of two. -For example, $a << k = a \cdot 2^k$ while $a >> k = \lfloor a/2^k \rfloor$. - -One significant difference between a logical shift and the way decimals are shifted is that digits below the zero'th position are removed -from the number. For example, consider $1101_2 >> 1$ using decimal notation this would produce $110.1_2$. However, with a logical shift the -result is $110_2$. - -\section{Addition and Subtraction} -In common twos complement fixed precision arithmetic negative numbers are easily represented by subtraction from the modulus. For example, with 32-bit integers -$a - b\mbox{ (mod }2^{32}\mbox{)}$ is the same as $a + (2^{32} - b) \mbox{ (mod }2^{32}\mbox{)}$ since $2^{32} \equiv 0 \mbox{ (mod }2^{32}\mbox{)}$. -As a result subtraction can be performed with a trivial series of logical operations and an addition. - -However, in multiple precision arithmetic negative numbers are not represented in the same way. Instead a sign flag is used to keep track of the -sign of the integer. As a result signed addition and subtraction are actually implemented as conditional usage of lower level addition or -subtraction algorithms with the sign fixed up appropriately. - -The lower level algorithms will add or subtract integers without regard to the sign flag. That is they will add or subtract the magnitude of -the integers respectively. - -\subsection{Low Level Addition} -An unsigned addition of multiple precision integers is performed with the same long-hand algorithm used to add decimal numbers. That is to add the -trailing digits first and propagate the resulting carry upwards. Since this is a lower level algorithm the name will have a ``s\_'' prefix. -Historically that convention stems from the MPI library where ``s\_'' stood for static functions that were hidden from the developer entirely. - -\newpage -\begin{figure}[!here] -\begin{center} -\begin{small} -\begin{tabular}{l} -\hline Algorithm \textbf{s\_mp\_add}. \\ -\textbf{Input}. Two mp\_ints $a$ and $b$ \\ -\textbf{Output}. The unsigned addition $c = \vert a \vert + \vert b \vert$. \\ -\hline \\ -1. if $a.used > b.used$ then \\ -\hspace{+3mm}1.1 $min \leftarrow b.used$ \\ -\hspace{+3mm}1.2 $max \leftarrow a.used$ \\ -\hspace{+3mm}1.3 $x \leftarrow a$ \\ -2. else \\ -\hspace{+3mm}2.1 $min \leftarrow a.used$ \\ -\hspace{+3mm}2.2 $max \leftarrow b.used$ \\ -\hspace{+3mm}2.3 $x \leftarrow b$ \\ -3. If $c.alloc < max + 1$ then grow $c$ to hold at least $max + 1$ digits (\textit{mp\_grow}) \\ -4. $oldused \leftarrow c.used$ \\ -5. $c.used \leftarrow max + 1$ \\ -6. $u \leftarrow 0$ \\ -7. for $n$ from $0$ to $min - 1$ do \\ -\hspace{+3mm}7.1 $c_n \leftarrow a_n + b_n + u$ \\ -\hspace{+3mm}7.2 $u \leftarrow c_n >> lg(\beta)$ \\ -\hspace{+3mm}7.3 $c_n \leftarrow c_n \mbox{ (mod }\beta\mbox{)}$ \\ -8. if $min \ne max$ then do \\ -\hspace{+3mm}8.1 for $n$ from $min$ to $max - 1$ do \\ -\hspace{+6mm}8.1.1 $c_n \leftarrow x_n + u$ \\ -\hspace{+6mm}8.1.2 $u \leftarrow c_n >> lg(\beta)$ \\ -\hspace{+6mm}8.1.3 $c_n \leftarrow c_n \mbox{ (mod }\beta\mbox{)}$ \\ -9. $c_{max} \leftarrow u$ \\ -10. if $olduse > max$ then \\ -\hspace{+3mm}10.1 for $n$ from $max + 1$ to $oldused - 1$ do \\ -\hspace{+6mm}10.1.1 $c_n \leftarrow 0$ \\ -11. Clamp excess digits in $c$. (\textit{mp\_clamp}) \\ -12. Return(\textit{MP\_OKAY}) \\ -\hline -\end{tabular} -\end{small} -\end{center} -\caption{Algorithm s\_mp\_add} -\end{figure} - -\textbf{Algorithm s\_mp\_add.} -This algorithm is loosely based on algorithm 14.7 of HAC \cite[pp. 594]{HAC} but has been extended to allow the inputs to have different magnitudes. -Coincidentally the description of algorithm A in Knuth \cite[pp. 266]{TAOCPV2} shares the same deficiency as the algorithm from \cite{HAC}. Even the -MIX pseudo machine code presented by Knuth \cite[pp. 266-267]{TAOCPV2} is incapable of handling inputs which are of different magnitudes. - -The first thing that has to be accomplished is to sort out which of the two inputs is the largest. The addition logic -will simply add all of the smallest input to the largest input and store that first part of the result in the -destination. Then it will apply a simpler addition loop to excess digits of the larger input. - -The first two steps will handle sorting the inputs such that $min$ and $max$ hold the digit counts of the two -inputs. The variable $x$ will be an mp\_int alias for the largest input or the second input $b$ if they have the -same number of digits. After the inputs are sorted the destination $c$ is grown as required to accomodate the sum -of the two inputs. The original \textbf{used} count of $c$ is copied and set to the new used count. - -At this point the first addition loop will go through as many digit positions that both inputs have. The carry -variable $\mu$ is set to zero outside the loop. Inside the loop an ``addition'' step requires three statements to produce -one digit of the summand. First -two digits from $a$ and $b$ are added together along with the carry $\mu$. The carry of this step is extracted and stored -in $\mu$ and finally the digit of the result $c_n$ is truncated within the range $0 \le c_n < \beta$. - -Now all of the digit positions that both inputs have in common have been exhausted. If $min \ne max$ then $x$ is an alias -for one of the inputs that has more digits. A simplified addition loop is then used to essentially copy the remaining digits -and the carry to the destination. - -The final carry is stored in $c_{max}$ and digits above $max$ upto $oldused$ are zeroed which completes the addition. - - -EXAM,bn_s_mp_add.c - -We first sort (lines @27,if@ to @35,}@) the inputs based on magnitude and determine the $min$ and $max$ variables. -Note that $x$ is a pointer to an mp\_int assigned to the largest input, in effect it is a local alias. Next we -grow the destination (@37,init@ to @42,}@) ensure that it can accomodate the result of the addition. - -Similar to the implementation of mp\_copy this function uses the braced code and local aliases coding style. The three aliases that are on -lines @56,tmpa@, @59,tmpb@ and @62,tmpc@ represent the two inputs and destination variables respectively. These aliases are used to ensure the -compiler does not have to dereference $a$, $b$ or $c$ (respectively) to access the digits of the respective mp\_int. - -The initial carry $u$ will be cleared (line @65,u = 0@), note that $u$ is of type mp\_digit which ensures type -compatibility within the implementation. The initial addition (line @66,for@ to @75,}@) adds digits from -both inputs until the smallest input runs out of digits. Similarly the conditional addition loop -(line @81,for@ to @90,}@) adds the remaining digits from the larger of the two inputs. The addition is finished -with the final carry being stored in $tmpc$ (line @94,tmpc++@). Note the ``++'' operator within the same expression. -After line @94,tmpc++@, $tmpc$ will point to the $c.used$'th digit of the mp\_int $c$. This is useful -for the next loop (line @97,for@ to @99,}@) which set any old upper digits to zero. - -\subsection{Low Level Subtraction} -The low level unsigned subtraction algorithm is very similar to the low level unsigned addition algorithm. The principle difference is that the -unsigned subtraction algorithm requires the result to be positive. That is when computing $a - b$ the condition $\vert a \vert \ge \vert b\vert$ must -be met for this algorithm to function properly. Keep in mind this low level algorithm is not meant to be used in higher level algorithms directly. -This algorithm as will be shown can be used to create functional signed addition and subtraction algorithms. - -MARK,GAMMA - -For this algorithm a new variable is required to make the description simpler. Recall from section 1.3.1 that a mp\_digit must be able to represent -the range $0 \le x < 2\beta$ for the algorithms to work correctly. However, it is allowable that a mp\_digit represent a larger range of values. For -this algorithm we will assume that the variable $\gamma$ represents the number of bits available in a -mp\_digit (\textit{this implies $2^{\gamma} > \beta$}). - -For example, the default for LibTomMath is to use a ``unsigned long'' for the mp\_digit ``type'' while $\beta = 2^{28}$. In ISO C an ``unsigned long'' -data type must be able to represent $0 \le x < 2^{32}$ meaning that in this case $\gamma \ge 32$. - -\newpage\begin{figure}[!here] -\begin{center} -\begin{small} -\begin{tabular}{l} -\hline Algorithm \textbf{s\_mp\_sub}. \\ -\textbf{Input}. Two mp\_ints $a$ and $b$ ($\vert a \vert \ge \vert b \vert$) \\ -\textbf{Output}. The unsigned subtraction $c = \vert a \vert - \vert b \vert$. \\ -\hline \\ -1. $min \leftarrow b.used$ \\ -2. $max \leftarrow a.used$ \\ -3. If $c.alloc < max$ then grow $c$ to hold at least $max$ digits. (\textit{mp\_grow}) \\ -4. $oldused \leftarrow c.used$ \\ -5. $c.used \leftarrow max$ \\ -6. $u \leftarrow 0$ \\ -7. for $n$ from $0$ to $min - 1$ do \\ -\hspace{3mm}7.1 $c_n \leftarrow a_n - b_n - u$ \\ -\hspace{3mm}7.2 $u \leftarrow c_n >> (\gamma - 1)$ \\ -\hspace{3mm}7.3 $c_n \leftarrow c_n \mbox{ (mod }\beta\mbox{)}$ \\ -8. if $min < max$ then do \\ -\hspace{3mm}8.1 for $n$ from $min$ to $max - 1$ do \\ -\hspace{6mm}8.1.1 $c_n \leftarrow a_n - u$ \\ -\hspace{6mm}8.1.2 $u \leftarrow c_n >> (\gamma - 1)$ \\ -\hspace{6mm}8.1.3 $c_n \leftarrow c_n \mbox{ (mod }\beta\mbox{)}$ \\ -9. if $oldused > max$ then do \\ -\hspace{3mm}9.1 for $n$ from $max$ to $oldused - 1$ do \\ -\hspace{6mm}9.1.1 $c_n \leftarrow 0$ \\ -10. Clamp excess digits of $c$. (\textit{mp\_clamp}). \\ -11. Return(\textit{MP\_OKAY}). \\ -\hline -\end{tabular} -\end{small} -\end{center} -\caption{Algorithm s\_mp\_sub} -\end{figure} - -\textbf{Algorithm s\_mp\_sub.} -This algorithm performs the unsigned subtraction of two mp\_int variables under the restriction that the result must be positive. That is when -passing variables $a$ and $b$ the condition that $\vert a \vert \ge \vert b \vert$ must be met for the algorithm to function correctly. This -algorithm is loosely based on algorithm 14.9 \cite[pp. 595]{HAC} and is similar to algorithm S in \cite[pp. 267]{TAOCPV2} as well. As was the case -of the algorithm s\_mp\_add both other references lack discussion concerning various practical details such as when the inputs differ in magnitude. - -The initial sorting of the inputs is trivial in this algorithm since $a$ is guaranteed to have at least the same magnitude of $b$. Steps 1 and 2 -set the $min$ and $max$ variables. Unlike the addition routine there is guaranteed to be no carry which means that the final result can be at -most $max$ digits in length as opposed to $max + 1$. Similar to the addition algorithm the \textbf{used} count of $c$ is copied locally and -set to the maximal count for the operation. - -The subtraction loop that begins on step seven is essentially the same as the addition loop of algorithm s\_mp\_add except single precision -subtraction is used instead. Note the use of the $\gamma$ variable to extract the carry (\textit{also known as the borrow}) within the subtraction -loops. Under the assumption that two's complement single precision arithmetic is used this will successfully extract the desired carry. - -For example, consider subtracting $0101_2$ from $0100_2$ where $\gamma = 4$ and $\beta = 2$. The least significant bit will force a carry upwards to -the third bit which will be set to zero after the borrow. After the very first bit has been subtracted $4 - 1 \equiv 0011_2$ will remain, When the -third bit of $0101_2$ is subtracted from the result it will cause another carry. In this case though the carry will be forced to propagate all the -way to the most significant bit. - -Recall that $\beta < 2^{\gamma}$. This means that if a carry does occur just before the $lg(\beta)$'th bit it will propagate all the way to the most -significant bit. Thus, the high order bits of the mp\_digit that are not part of the actual digit will either be all zero, or all one. All that -is needed is a single zero or one bit for the carry. Therefore a single logical shift right by $\gamma - 1$ positions is sufficient to extract the -carry. This method of carry extraction may seem awkward but the reason for it becomes apparent when the implementation is discussed. - -If $b$ has a smaller magnitude than $a$ then step 9 will force the carry and copy operation to propagate through the larger input $a$ into $c$. Step -10 will ensure that any leading digits of $c$ above the $max$'th position are zeroed. - -EXAM,bn_s_mp_sub.c - -Like low level addition we ``sort'' the inputs. Except in this case the sorting is hardcoded -(lines @24,min@ and @25,max@). In reality the $min$ and $max$ variables are only aliases and are only -used to make the source code easier to read. Again the pointer alias optimization is used -within this algorithm. The aliases $tmpa$, $tmpb$ and $tmpc$ are initialized -(lines @42,tmpa@, @43,tmpb@ and @44,tmpc@) for $a$, $b$ and $c$ respectively. - -The first subtraction loop (lines @47,u = 0@ through @61,}@) subtract digits from both inputs until the smaller of -the two inputs has been exhausted. As remarked earlier there is an implementation reason for using the ``awkward'' -method of extracting the carry (line @57, >>@). The traditional method for extracting the carry would be to shift -by $lg(\beta)$ positions and logically AND the least significant bit. The AND operation is required because all of -the bits above the $\lg(\beta)$'th bit will be set to one after a carry occurs from subtraction. This carry -extraction requires two relatively cheap operations to extract the carry. The other method is to simply shift the -most significant bit to the least significant bit thus extracting the carry with a single cheap operation. This -optimization only works on twos compliment machines which is a safe assumption to make. - -If $a$ has a larger magnitude than $b$ an additional loop (lines @64,for@ through @73,}@) is required to propagate -the carry through $a$ and copy the result to $c$. - -\subsection{High Level Addition} -Now that both lower level addition and subtraction algorithms have been established an effective high level signed addition algorithm can be -established. This high level addition algorithm will be what other algorithms and developers will use to perform addition of mp\_int data -types. - -Recall from section 5.2 that an mp\_int represents an integer with an unsigned mantissa (\textit{the array of digits}) and a \textbf{sign} -flag. A high level addition is actually performed as a series of eight separate cases which can be optimized down to three unique cases. - -\begin{figure}[!here] -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_add}. \\ -\textbf{Input}. Two mp\_ints $a$ and $b$ \\ -\textbf{Output}. The signed addition $c = a + b$. \\ -\hline \\ -1. if $a.sign = b.sign$ then do \\ -\hspace{3mm}1.1 $c.sign \leftarrow a.sign$ \\ -\hspace{3mm}1.2 $c \leftarrow \vert a \vert + \vert b \vert$ (\textit{s\_mp\_add})\\ -2. else do \\ -\hspace{3mm}2.1 if $\vert a \vert < \vert b \vert$ then do (\textit{mp\_cmp\_mag}) \\ -\hspace{6mm}2.1.1 $c.sign \leftarrow b.sign$ \\ -\hspace{6mm}2.1.2 $c \leftarrow \vert b \vert - \vert a \vert$ (\textit{s\_mp\_sub}) \\ -\hspace{3mm}2.2 else do \\ -\hspace{6mm}2.2.1 $c.sign \leftarrow a.sign$ \\ -\hspace{6mm}2.2.2 $c \leftarrow \vert a \vert - \vert b \vert$ \\ -3. Return(\textit{MP\_OKAY}). \\ -\hline -\end{tabular} -\end{center} -\caption{Algorithm mp\_add} -\end{figure} - -\textbf{Algorithm mp\_add.} -This algorithm performs the signed addition of two mp\_int variables. There is no reference algorithm to draw upon from -either \cite{TAOCPV2} or \cite{HAC} since they both only provide unsigned operations. The algorithm is fairly -straightforward but restricted since subtraction can only produce positive results. - -\begin{figure}[here] -\begin{small} -\begin{center} -\begin{tabular}{|c|c|c|c|c|} -\hline \textbf{Sign of $a$} & \textbf{Sign of $b$} & \textbf{$\vert a \vert > \vert b \vert $} & \textbf{Unsigned Operation} & \textbf{Result Sign Flag} \\ -\hline $+$ & $+$ & Yes & $c = a + b$ & $a.sign$ \\ -\hline $+$ & $+$ & No & $c = a + b$ & $a.sign$ \\ -\hline $-$ & $-$ & Yes & $c = a + b$ & $a.sign$ \\ -\hline $-$ & $-$ & No & $c = a + b$ & $a.sign$ \\ -\hline &&&&\\ - -\hline $+$ & $-$ & No & $c = b - a$ & $b.sign$ \\ -\hline $-$ & $+$ & No & $c = b - a$ & $b.sign$ \\ - -\hline &&&&\\ - -\hline $+$ & $-$ & Yes & $c = a - b$ & $a.sign$ \\ -\hline $-$ & $+$ & Yes & $c = a - b$ & $a.sign$ \\ - -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Addition Guide Chart} -\label{fig:AddChart} -\end{figure} - -Figure~\ref{fig:AddChart} lists all of the eight possible input combinations and is sorted to show that only three -specific cases need to be handled. The return code of the unsigned operations at step 1.2, 2.1.2 and 2.2.2 are -forwarded to step three to check for errors. This simplifies the description of the algorithm considerably and best -follows how the implementation actually was achieved. - -Also note how the \textbf{sign} is set before the unsigned addition or subtraction is performed. Recall from the descriptions of algorithms -s\_mp\_add and s\_mp\_sub that the mp\_clamp function is used at the end to trim excess digits. The mp\_clamp algorithm will set the \textbf{sign} -to \textbf{MP\_ZPOS} when the \textbf{used} digit count reaches zero. - -For example, consider performing $-a + a$ with algorithm mp\_add. By the description of the algorithm the sign is set to \textbf{MP\_NEG} which would -produce a result of $-0$. However, since the sign is set first then the unsigned addition is performed the subsequent usage of algorithm mp\_clamp -within algorithm s\_mp\_add will force $-0$ to become $0$. - -EXAM,bn_mp_add.c - -The source code follows the algorithm fairly closely. The most notable new source code addition is the usage of the $res$ integer variable which -is used to pass result of the unsigned operations forward. Unlike in the algorithm, the variable $res$ is merely returned as is without -explicitly checking it and returning the constant \textbf{MP\_OKAY}. The observation is this algorithm will succeed or fail only if the lower -level functions do so. Returning their return code is sufficient. - -\subsection{High Level Subtraction} -The high level signed subtraction algorithm is essentially the same as the high level signed addition algorithm. - -\newpage\begin{figure}[!here] -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_sub}. \\ -\textbf{Input}. Two mp\_ints $a$ and $b$ \\ -\textbf{Output}. The signed subtraction $c = a - b$. \\ -\hline \\ -1. if $a.sign \ne b.sign$ then do \\ -\hspace{3mm}1.1 $c.sign \leftarrow a.sign$ \\ -\hspace{3mm}1.2 $c \leftarrow \vert a \vert + \vert b \vert$ (\textit{s\_mp\_add}) \\ -2. else do \\ -\hspace{3mm}2.1 if $\vert a \vert \ge \vert b \vert$ then do (\textit{mp\_cmp\_mag}) \\ -\hspace{6mm}2.1.1 $c.sign \leftarrow a.sign$ \\ -\hspace{6mm}2.1.2 $c \leftarrow \vert a \vert - \vert b \vert$ (\textit{s\_mp\_sub}) \\ -\hspace{3mm}2.2 else do \\ -\hspace{6mm}2.2.1 $c.sign \leftarrow \left \lbrace \begin{array}{ll} - MP\_ZPOS & \mbox{if }a.sign = MP\_NEG \\ - MP\_NEG & \mbox{otherwise} \\ - \end{array} \right .$ \\ -\hspace{6mm}2.2.2 $c \leftarrow \vert b \vert - \vert a \vert$ \\ -3. Return(\textit{MP\_OKAY}). \\ -\hline -\end{tabular} -\end{center} -\caption{Algorithm mp\_sub} -\end{figure} - -\textbf{Algorithm mp\_sub.} -This algorithm performs the signed subtraction of two inputs. Similar to algorithm mp\_add there is no reference in either \cite{TAOCPV2} or -\cite{HAC}. Also this algorithm is restricted by algorithm s\_mp\_sub. Chart \ref{fig:SubChart} lists the eight possible inputs and -the operations required. - -\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{|c|c|c|c|c|} -\hline \textbf{Sign of $a$} & \textbf{Sign of $b$} & \textbf{$\vert a \vert \ge \vert b \vert $} & \textbf{Unsigned Operation} & \textbf{Result Sign Flag} \\ -\hline $+$ & $-$ & Yes & $c = a + b$ & $a.sign$ \\ -\hline $+$ & $-$ & No & $c = a + b$ & $a.sign$ \\ -\hline $-$ & $+$ & Yes & $c = a + b$ & $a.sign$ \\ -\hline $-$ & $+$ & No & $c = a + b$ & $a.sign$ \\ -\hline &&&& \\ -\hline $+$ & $+$ & Yes & $c = a - b$ & $a.sign$ \\ -\hline $-$ & $-$ & Yes & $c = a - b$ & $a.sign$ \\ -\hline &&&& \\ -\hline $+$ & $+$ & No & $c = b - a$ & $\mbox{opposite of }a.sign$ \\ -\hline $-$ & $-$ & No & $c = b - a$ & $\mbox{opposite of }a.sign$ \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Subtraction Guide Chart} -\label{fig:SubChart} -\end{figure} - -Similar to the case of algorithm mp\_add the \textbf{sign} is set first before the unsigned addition or subtraction. That is to prevent the -algorithm from producing $-a - -a = -0$ as a result. - -EXAM,bn_mp_sub.c - -Much like the implementation of algorithm mp\_add the variable $res$ is used to catch the return code of the unsigned addition or subtraction operations -and forward it to the end of the function. On line @38, != MP_LT@ the ``not equal to'' \textbf{MP\_LT} expression is used to emulate a -``greater than or equal to'' comparison. - -\section{Bit and Digit Shifting} -MARK,POLY -It is quite common to think of a multiple precision integer as a polynomial in $x$, that is $y = f(\beta)$ where $f(x) = \sum_{i=0}^{n-1} a_i x^i$. -This notation arises within discussion of Montgomery and Diminished Radix Reduction as well as Karatsuba multiplication and squaring. - -In order to facilitate operations on polynomials in $x$ as above a series of simple ``digit'' algorithms have to be established. That is to shift -the digits left or right as well to shift individual bits of the digits left and right. It is important to note that not all ``shift'' operations -are on radix-$\beta$ digits. - -\subsection{Multiplication by Two} - -In a binary system where the radix is a power of two multiplication by two not only arises often in other algorithms it is a fairly efficient -operation to perform. A single precision logical shift left is sufficient to multiply a single digit by two. - -\newpage\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_mul\_2}. \\ -\textbf{Input}. One mp\_int $a$ \\ -\textbf{Output}. $b = 2a$. \\ -\hline \\ -1. If $b.alloc < a.used + 1$ then grow $b$ to hold $a.used + 1$ digits. (\textit{mp\_grow}) \\ -2. $oldused \leftarrow b.used$ \\ -3. $b.used \leftarrow a.used$ \\ -4. $r \leftarrow 0$ \\ -5. for $n$ from 0 to $a.used - 1$ do \\ -\hspace{3mm}5.1 $rr \leftarrow a_n >> (lg(\beta) - 1)$ \\ -\hspace{3mm}5.2 $b_n \leftarrow (a_n << 1) + r \mbox{ (mod }\beta\mbox{)}$ \\ -\hspace{3mm}5.3 $r \leftarrow rr$ \\ -6. If $r \ne 0$ then do \\ -\hspace{3mm}6.1 $b_{n + 1} \leftarrow r$ \\ -\hspace{3mm}6.2 $b.used \leftarrow b.used + 1$ \\ -7. If $b.used < oldused - 1$ then do \\ -\hspace{3mm}7.1 for $n$ from $b.used$ to $oldused - 1$ do \\ -\hspace{6mm}7.1.1 $b_n \leftarrow 0$ \\ -8. $b.sign \leftarrow a.sign$ \\ -9. Return(\textit{MP\_OKAY}).\\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm mp\_mul\_2} -\end{figure} - -\textbf{Algorithm mp\_mul\_2.} -This algorithm will quickly multiply a mp\_int by two provided $\beta$ is a power of two. Neither \cite{TAOCPV2} nor \cite{HAC} describe such -an algorithm despite the fact it arises often in other algorithms. The algorithm is setup much like the lower level algorithm s\_mp\_add since -it is for all intents and purposes equivalent to the operation $b = \vert a \vert + \vert a \vert$. - -Step 1 and 2 grow the input as required to accomodate the maximum number of \textbf{used} digits in the result. The initial \textbf{used} count -is set to $a.used$ at step 4. Only if there is a final carry will the \textbf{used} count require adjustment. - -Step 6 is an optimization implementation of the addition loop for this specific case. That is since the two values being added together -are the same there is no need to perform two reads from the digits of $a$. Step 6.1 performs a single precision shift on the current digit $a_n$ to -obtain what will be the carry for the next iteration. Step 6.2 calculates the $n$'th digit of the result as single precision shift of $a_n$ plus -the previous carry. Recall from ~SHIFTS~ that $a_n << 1$ is equivalent to $a_n \cdot 2$. An iteration of the addition loop is finished with -forwarding the carry to the next iteration. - -Step 7 takes care of any final carry by setting the $a.used$'th digit of the result to the carry and augmenting the \textbf{used} count of $b$. -Step 8 clears any leading digits of $b$ in case it originally had a larger magnitude than $a$. - -EXAM,bn_mp_mul_2.c - -This implementation is essentially an optimized implementation of s\_mp\_add for the case of doubling an input. The only noteworthy difference -is the use of the logical shift operator on line @52,<<@ to perform a single precision doubling. - -\subsection{Division by Two} -A division by two can just as easily be accomplished with a logical shift right as multiplication by two can be with a logical shift left. - -\newpage\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_div\_2}. \\ -\textbf{Input}. One mp\_int $a$ \\ -\textbf{Output}. $b = a/2$. \\ -\hline \\ -1. If $b.alloc < a.used$ then grow $b$ to hold $a.used$ digits. (\textit{mp\_grow}) \\ -2. If the reallocation failed return(\textit{MP\_MEM}). \\ -3. $oldused \leftarrow b.used$ \\ -4. $b.used \leftarrow a.used$ \\ -5. $r \leftarrow 0$ \\ -6. for $n$ from $b.used - 1$ to $0$ do \\ -\hspace{3mm}6.1 $rr \leftarrow a_n \mbox{ (mod }2\mbox{)}$\\ -\hspace{3mm}6.2 $b_n \leftarrow (a_n >> 1) + (r << (lg(\beta) - 1)) \mbox{ (mod }\beta\mbox{)}$ \\ -\hspace{3mm}6.3 $r \leftarrow rr$ \\ -7. If $b.used < oldused - 1$ then do \\ -\hspace{3mm}7.1 for $n$ from $b.used$ to $oldused - 1$ do \\ -\hspace{6mm}7.1.1 $b_n \leftarrow 0$ \\ -8. $b.sign \leftarrow a.sign$ \\ -9. Clamp excess digits of $b$. (\textit{mp\_clamp}) \\ -10. Return(\textit{MP\_OKAY}).\\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm mp\_div\_2} -\end{figure} - -\textbf{Algorithm mp\_div\_2.} -This algorithm will divide an mp\_int by two using logical shifts to the right. Like mp\_mul\_2 it uses a modified low level addition -core as the basis of the algorithm. Unlike mp\_mul\_2 the shift operations work from the leading digit to the trailing digit. The algorithm -could be written to work from the trailing digit to the leading digit however, it would have to stop one short of $a.used - 1$ digits to prevent -reading past the end of the array of digits. - -Essentially the loop at step 6 is similar to that of mp\_mul\_2 except the logical shifts go in the opposite direction and the carry is at the -least significant bit not the most significant bit. - -EXAM,bn_mp_div_2.c - -\section{Polynomial Basis Operations} -Recall from ~POLY~ that any integer can be represented as a polynomial in $x$ as $y = f(\beta)$. Such a representation is also known as -the polynomial basis \cite[pp. 48]{ROSE}. Given such a notation a multiplication or division by $x$ amounts to shifting whole digits a single -place. The need for such operations arises in several other higher level algorithms such as Barrett and Montgomery reduction, integer -division and Karatsuba multiplication. - -Converting from an array of digits to polynomial basis is very simple. Consider the integer $y \equiv (a_2, a_1, a_0)_{\beta}$ and recall that -$y = \sum_{i=0}^{2} a_i \beta^i$. Simply replace $\beta$ with $x$ and the expression is in polynomial basis. For example, $f(x) = 8x + 9$ is the -polynomial basis representation for $89$ using radix ten. That is, $f(10) = 8(10) + 9 = 89$. - -\subsection{Multiplication by $x$} - -Given a polynomial in $x$ such as $f(x) = a_n x^n + a_{n-1} x^{n-1} + ... + a_0$ multiplying by $x$ amounts to shifting the coefficients up one -degree. In this case $f(x) \cdot x = a_n x^{n+1} + a_{n-1} x^n + ... + a_0 x$. From a scalar basis point of view multiplying by $x$ is equivalent to -multiplying by the integer $\beta$. - -\newpage\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_lshd}. \\ -\textbf{Input}. One mp\_int $a$ and an integer $b$ \\ -\textbf{Output}. $a \leftarrow a \cdot \beta^b$ (equivalent to multiplication by $x^b$). \\ -\hline \\ -1. If $b \le 0$ then return(\textit{MP\_OKAY}). \\ -2. If $a.alloc < a.used + b$ then grow $a$ to at least $a.used + b$ digits. (\textit{mp\_grow}). \\ -3. If the reallocation failed return(\textit{MP\_MEM}). \\ -4. $a.used \leftarrow a.used + b$ \\ -5. $i \leftarrow a.used - 1$ \\ -6. $j \leftarrow a.used - 1 - b$ \\ -7. for $n$ from $a.used - 1$ to $b$ do \\ -\hspace{3mm}7.1 $a_{i} \leftarrow a_{j}$ \\ -\hspace{3mm}7.2 $i \leftarrow i - 1$ \\ -\hspace{3mm}7.3 $j \leftarrow j - 1$ \\ -8. for $n$ from 0 to $b - 1$ do \\ -\hspace{3mm}8.1 $a_n \leftarrow 0$ \\ -9. Return(\textit{MP\_OKAY}). \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm mp\_lshd} -\end{figure} - -\textbf{Algorithm mp\_lshd.} -This algorithm multiplies an mp\_int by the $b$'th power of $x$. This is equivalent to multiplying by $\beta^b$. The algorithm differs -from the other algorithms presented so far as it performs the operation in place instead storing the result in a separate location. The -motivation behind this change is due to the way this function is typically used. Algorithms such as mp\_add store the result in an optionally -different third mp\_int because the original inputs are often still required. Algorithm mp\_lshd (\textit{and similarly algorithm mp\_rshd}) is -typically used on values where the original value is no longer required. The algorithm will return success immediately if -$b \le 0$ since the rest of algorithm is only valid when $b > 0$. - -First the destination $a$ is grown as required to accomodate the result. The counters $i$ and $j$ are used to form a \textit{sliding window} over -the digits of $a$ of length $b$. The head of the sliding window is at $i$ (\textit{the leading digit}) and the tail at $j$ (\textit{the trailing digit}). -The loop on step 7 copies the digit from the tail to the head. In each iteration the window is moved down one digit. The last loop on -step 8 sets the lower $b$ digits to zero. - -\newpage -FIGU,sliding_window,Sliding Window Movement - -EXAM,bn_mp_lshd.c - -The if statement (line @24,if@) ensures that the $b$ variable is greater than zero since we do not interpret negative -shift counts properly. The \textbf{used} count is incremented by $b$ before the copy loop begins. This elminates -the need for an additional variable in the for loop. The variable $top$ (line @42,top@) is an alias -for the leading digit while $bottom$ (line @45,bottom@) is an alias for the trailing edge. The aliases form a -window of exactly $b$ digits over the input. - -\subsection{Division by $x$} - -Division by powers of $x$ is easily achieved by shifting the digits right and removing any that will end up to the right of the zero'th digit. - -\newpage\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_rshd}. \\ -\textbf{Input}. One mp\_int $a$ and an integer $b$ \\ -\textbf{Output}. $a \leftarrow a / \beta^b$ (Divide by $x^b$). \\ -\hline \\ -1. If $b \le 0$ then return. \\ -2. If $a.used \le b$ then do \\ -\hspace{3mm}2.1 Zero $a$. (\textit{mp\_zero}). \\ -\hspace{3mm}2.2 Return. \\ -3. $i \leftarrow 0$ \\ -4. $j \leftarrow b$ \\ -5. for $n$ from 0 to $a.used - b - 1$ do \\ -\hspace{3mm}5.1 $a_i \leftarrow a_j$ \\ -\hspace{3mm}5.2 $i \leftarrow i + 1$ \\ -\hspace{3mm}5.3 $j \leftarrow j + 1$ \\ -6. for $n$ from $a.used - b$ to $a.used - 1$ do \\ -\hspace{3mm}6.1 $a_n \leftarrow 0$ \\ -7. $a.used \leftarrow a.used - b$ \\ -8. Return. \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm mp\_rshd} -\end{figure} - -\textbf{Algorithm mp\_rshd.} -This algorithm divides the input in place by the $b$'th power of $x$. It is analogous to dividing by a $\beta^b$ but much quicker since -it does not require single precision division. This algorithm does not actually return an error code as it cannot fail. - -If the input $b$ is less than one the algorithm quickly returns without performing any work. If the \textbf{used} count is less than or equal -to the shift count $b$ then it will simply zero the input and return. - -After the trivial cases of inputs have been handled the sliding window is setup. Much like the case of algorithm mp\_lshd a sliding window that -is $b$ digits wide is used to copy the digits. Unlike mp\_lshd the window slides in the opposite direction from the trailing to the leading digit. -Also the digits are copied from the leading to the trailing edge. - -Once the window copy is complete the upper digits must be zeroed and the \textbf{used} count decremented. - -EXAM,bn_mp_rshd.c - -The only noteworthy element of this routine is the lack of a return type since it cannot fail. Like mp\_lshd() we -form a sliding window except we copy in the other direction. After the window (line @59,for (;@) we then zero -the upper digits of the input to make sure the result is correct. - -\section{Powers of Two} - -Now that algorithms for moving single bits as well as whole digits exist algorithms for moving the ``in between'' distances are required. For -example, to quickly multiply by $2^k$ for any $k$ without using a full multiplier algorithm would prove useful. Instead of performing single -shifts $k$ times to achieve a multiplication by $2^{\pm k}$ a mixture of whole digit shifting and partial digit shifting is employed. - -\subsection{Multiplication by Power of Two} - -\newpage\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_mul\_2d}. \\ -\textbf{Input}. One mp\_int $a$ and an integer $b$ \\ -\textbf{Output}. $c \leftarrow a \cdot 2^b$. \\ -\hline \\ -1. $c \leftarrow a$. (\textit{mp\_copy}) \\ -2. If $c.alloc < c.used + \lfloor b / lg(\beta) \rfloor + 2$ then grow $c$ accordingly. \\ -3. If the reallocation failed return(\textit{MP\_MEM}). \\ -4. If $b \ge lg(\beta)$ then \\ -\hspace{3mm}4.1 $c \leftarrow c \cdot \beta^{\lfloor b / lg(\beta) \rfloor}$ (\textit{mp\_lshd}). \\ -\hspace{3mm}4.2 If step 4.1 failed return(\textit{MP\_MEM}). \\ -5. $d \leftarrow b \mbox{ (mod }lg(\beta)\mbox{)}$ \\ -6. If $d \ne 0$ then do \\ -\hspace{3mm}6.1 $mask \leftarrow 2^d$ \\ -\hspace{3mm}6.2 $r \leftarrow 0$ \\ -\hspace{3mm}6.3 for $n$ from $0$ to $c.used - 1$ do \\ -\hspace{6mm}6.3.1 $rr \leftarrow c_n >> (lg(\beta) - d) \mbox{ (mod }mask\mbox{)}$ \\ -\hspace{6mm}6.3.2 $c_n \leftarrow (c_n << d) + r \mbox{ (mod }\beta\mbox{)}$ \\ -\hspace{6mm}6.3.3 $r \leftarrow rr$ \\ -\hspace{3mm}6.4 If $r > 0$ then do \\ -\hspace{6mm}6.4.1 $c_{c.used} \leftarrow r$ \\ -\hspace{6mm}6.4.2 $c.used \leftarrow c.used + 1$ \\ -7. Return(\textit{MP\_OKAY}). \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm mp\_mul\_2d} -\end{figure} - -\textbf{Algorithm mp\_mul\_2d.} -This algorithm multiplies $a$ by $2^b$ and stores the result in $c$. The algorithm uses algorithm mp\_lshd and a derivative of algorithm mp\_mul\_2 to -quickly compute the product. - -First the algorithm will multiply $a$ by $x^{\lfloor b / lg(\beta) \rfloor}$ which will ensure that the remainder multiplicand is less than -$\beta$. For example, if $b = 37$ and $\beta = 2^{28}$ then this step will multiply by $x$ leaving a multiplication by $2^{37 - 28} = 2^{9}$ -left. - -After the digits have been shifted appropriately at most $lg(\beta) - 1$ shifts are left to perform. Step 5 calculates the number of remaining shifts -required. If it is non-zero a modified shift loop is used to calculate the remaining product. -Essentially the loop is a generic version of algorithm mp\_mul\_2 designed to handle any shift count in the range $1 \le x < lg(\beta)$. The $mask$ -variable is used to extract the upper $d$ bits to form the carry for the next iteration. - -This algorithm is loosely measured as a $O(2n)$ algorithm which means that if the input is $n$-digits that it takes $2n$ ``time'' to -complete. It is possible to optimize this algorithm down to a $O(n)$ algorithm at a cost of making the algorithm slightly harder to follow. - -EXAM,bn_mp_mul_2d.c - -The shifting is performed in--place which means the first step (line @24,a != c@) is to copy the input to the -destination. We avoid calling mp\_copy() by making sure the mp\_ints are different. The destination then -has to be grown (line @31,grow@) to accomodate the result. - -If the shift count $b$ is larger than $lg(\beta)$ then a call to mp\_lshd() is used to handle all of the multiples -of $lg(\beta)$. Leaving only a remaining shift of $lg(\beta) - 1$ or fewer bits left. Inside the actual shift -loop (lines @45,if@ to @76,}@) we make use of pre--computed values $shift$ and $mask$. These are used to -extract the carry bit(s) to pass into the next iteration of the loop. The $r$ and $rr$ variables form a -chain between consecutive iterations to propagate the carry. - -\subsection{Division by Power of Two} - -\newpage\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_div\_2d}. \\ -\textbf{Input}. One mp\_int $a$ and an integer $b$ \\ -\textbf{Output}. $c \leftarrow \lfloor a / 2^b \rfloor, d \leftarrow a \mbox{ (mod }2^b\mbox{)}$. \\ -\hline \\ -1. If $b \le 0$ then do \\ -\hspace{3mm}1.1 $c \leftarrow a$ (\textit{mp\_copy}) \\ -\hspace{3mm}1.2 $d \leftarrow 0$ (\textit{mp\_zero}) \\ -\hspace{3mm}1.3 Return(\textit{MP\_OKAY}). \\ -2. $c \leftarrow a$ \\ -3. $d \leftarrow a \mbox{ (mod }2^b\mbox{)}$ (\textit{mp\_mod\_2d}) \\ -4. If $b \ge lg(\beta)$ then do \\ -\hspace{3mm}4.1 $c \leftarrow \lfloor c/\beta^{\lfloor b/lg(\beta) \rfloor} \rfloor$ (\textit{mp\_rshd}). \\ -5. $k \leftarrow b \mbox{ (mod }lg(\beta)\mbox{)}$ \\ -6. If $k \ne 0$ then do \\ -\hspace{3mm}6.1 $mask \leftarrow 2^k$ \\ -\hspace{3mm}6.2 $r \leftarrow 0$ \\ -\hspace{3mm}6.3 for $n$ from $c.used - 1$ to $0$ do \\ -\hspace{6mm}6.3.1 $rr \leftarrow c_n \mbox{ (mod }mask\mbox{)}$ \\ -\hspace{6mm}6.3.2 $c_n \leftarrow (c_n >> k) + (r << (lg(\beta) - k))$ \\ -\hspace{6mm}6.3.3 $r \leftarrow rr$ \\ -7. Clamp excess digits of $c$. (\textit{mp\_clamp}) \\ -8. Return(\textit{MP\_OKAY}). \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm mp\_div\_2d} -\end{figure} - -\textbf{Algorithm mp\_div\_2d.} -This algorithm will divide an input $a$ by $2^b$ and produce the quotient and remainder. The algorithm is designed much like algorithm -mp\_mul\_2d by first using whole digit shifts then single precision shifts. This algorithm will also produce the remainder of the division -by using algorithm mp\_mod\_2d. - -EXAM,bn_mp_div_2d.c - -The implementation of algorithm mp\_div\_2d is slightly different than the algorithm specifies. The remainder $d$ may be optionally -ignored by passing \textbf{NULL} as the pointer to the mp\_int variable. The temporary mp\_int variable $t$ is used to hold the -result of the remainder operation until the end. This allows $d$ and $a$ to represent the same mp\_int without modifying $a$ before -the quotient is obtained. - -The remainder of the source code is essentially the same as the source code for mp\_mul\_2d. The only significant difference is -the direction of the shifts. - -\subsection{Remainder of Division by Power of Two} - -The last algorithm in the series of polynomial basis power of two algorithms is calculating the remainder of division by $2^b$. This -algorithm benefits from the fact that in twos complement arithmetic $a \mbox{ (mod }2^b\mbox{)}$ is the same as $a$ AND $2^b - 1$. - -\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_mod\_2d}. \\ -\textbf{Input}. One mp\_int $a$ and an integer $b$ \\ -\textbf{Output}. $c \leftarrow a \mbox{ (mod }2^b\mbox{)}$. \\ -\hline \\ -1. If $b \le 0$ then do \\ -\hspace{3mm}1.1 $c \leftarrow 0$ (\textit{mp\_zero}) \\ -\hspace{3mm}1.2 Return(\textit{MP\_OKAY}). \\ -2. If $b > a.used \cdot lg(\beta)$ then do \\ -\hspace{3mm}2.1 $c \leftarrow a$ (\textit{mp\_copy}) \\ -\hspace{3mm}2.2 Return the result of step 2.1. \\ -3. $c \leftarrow a$ \\ -4. If step 3 failed return(\textit{MP\_MEM}). \\ -5. for $n$ from $\lceil b / lg(\beta) \rceil$ to $c.used$ do \\ -\hspace{3mm}5.1 $c_n \leftarrow 0$ \\ -6. $k \leftarrow b \mbox{ (mod }lg(\beta)\mbox{)}$ \\ -7. $c_{\lfloor b / lg(\beta) \rfloor} \leftarrow c_{\lfloor b / lg(\beta) \rfloor} \mbox{ (mod }2^{k}\mbox{)}$. \\ -8. Clamp excess digits of $c$. (\textit{mp\_clamp}) \\ -9. Return(\textit{MP\_OKAY}). \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm mp\_mod\_2d} -\end{figure} - -\textbf{Algorithm mp\_mod\_2d.} -This algorithm will quickly calculate the value of $a \mbox{ (mod }2^b\mbox{)}$. First if $b$ is less than or equal to zero the -result is set to zero. If $b$ is greater than the number of bits in $a$ then it simply copies $a$ to $c$ and returns. Otherwise, $a$ -is copied to $b$, leading digits are removed and the remaining leading digit is trimed to the exact bit count. - -EXAM,bn_mp_mod_2d.c - -We first avoid cases of $b \le 0$ by simply mp\_zero()'ing the destination in such cases. Next if $2^b$ is larger -than the input we just mp\_copy() the input and return right away. After this point we know we must actually -perform some work to produce the remainder. - -Recalling that reducing modulo $2^k$ and a binary ``and'' with $2^k - 1$ are numerically equivalent we can quickly reduce -the number. First we zero any digits above the last digit in $2^b$ (line @41,for@). Next we reduce the -leading digit of both (line @45,&=@) and then mp\_clamp(). - -\section*{Exercises} -\begin{tabular}{cl} -$\left [ 3 \right ] $ & Devise an algorithm that performs $a \cdot 2^b$ for generic values of $b$ \\ - & in $O(n)$ time. \\ - &\\ -$\left [ 3 \right ] $ & Devise an efficient algorithm to multiply by small low hamming \\ - & weight values such as $3$, $5$ and $9$. Extend it to handle all values \\ - & upto $64$ with a hamming weight less than three. \\ - &\\ -$\left [ 2 \right ] $ & Modify the preceding algorithm to handle values of the form \\ - & $2^k - 1$ as well. \\ - &\\ -$\left [ 3 \right ] $ & Using only algorithms mp\_mul\_2, mp\_div\_2 and mp\_add create an \\ - & algorithm to multiply two integers in roughly $O(2n^2)$ time for \\ - & any $n$-bit input. Note that the time of addition is ignored in the \\ - & calculation. \\ - & \\ -$\left [ 5 \right ] $ & Improve the previous algorithm to have a working time of at most \\ - & $O \left (2^{(k-1)}n + \left ({2n^2 \over k} \right ) \right )$ for an appropriate choice of $k$. Again ignore \\ - & the cost of addition. \\ - & \\ -$\left [ 2 \right ] $ & Devise a chart to find optimal values of $k$ for the previous problem \\ - & for $n = 64 \ldots 1024$ in steps of $64$. \\ - & \\ -$\left [ 2 \right ] $ & Using only algorithms mp\_abs and mp\_sub devise another method for \\ - & calculating the result of a signed comparison. \\ - & -\end{tabular} - -\chapter{Multiplication and Squaring} -\section{The Multipliers} -For most number theoretic problems including certain public key cryptographic algorithms, the ``multipliers'' form the most important subset of -algorithms of any multiple precision integer package. The set of multiplier algorithms include integer multiplication, squaring and modular reduction -where in each of the algorithms single precision multiplication is the dominant operation performed. This chapter will discuss integer multiplication -and squaring, leaving modular reductions for the subsequent chapter. - -The importance of the multiplier algorithms is for the most part driven by the fact that certain popular public key algorithms are based on modular -exponentiation, that is computing $d \equiv a^b \mbox{ (mod }c\mbox{)}$ for some arbitrary choice of $a$, $b$, $c$ and $d$. During a modular -exponentiation the majority\footnote{Roughly speaking a modular exponentiation will spend about 40\% of the time performing modular reductions, -35\% of the time performing squaring and 25\% of the time performing multiplications.} of the processor time is spent performing single precision -multiplications. - -For centuries general purpose multiplication has required a lengthly $O(n^2)$ process, whereby each digit of one multiplicand has to be multiplied -against every digit of the other multiplicand. Traditional long-hand multiplication is based on this process; while the techniques can differ the -overall algorithm used is essentially the same. Only ``recently'' have faster algorithms been studied. First Karatsuba multiplication was discovered in -1962. This algorithm can multiply two numbers with considerably fewer single precision multiplications when compared to the long-hand approach. -This technique led to the discovery of polynomial basis algorithms (\textit{good reference?}) and subquently Fourier Transform based solutions. - -\section{Multiplication} -\subsection{The Baseline Multiplication} -\label{sec:basemult} -\index{baseline multiplication} -Computing the product of two integers in software can be achieved using a trivial adaptation of the standard $O(n^2)$ long-hand multiplication -algorithm that school children are taught. The algorithm is considered an $O(n^2)$ algorithm since for two $n$-digit inputs $n^2$ single precision -multiplications are required. More specifically for a $m$ and $n$ digit input $m \cdot n$ single precision multiplications are required. To -simplify most discussions, it will be assumed that the inputs have comparable number of digits. - -The ``baseline multiplication'' algorithm is designed to act as the ``catch-all'' algorithm, only to be used when the faster algorithms cannot be -used. This algorithm does not use any particularly interesting optimizations and should ideally be avoided if possible. One important -facet of this algorithm, is that it has been modified to only produce a certain amount of output digits as resolution. The importance of this -modification will become evident during the discussion of Barrett modular reduction. Recall that for a $n$ and $m$ digit input the product -will be at most $n + m$ digits. Therefore, this algorithm can be reduced to a full multiplier by having it produce $n + m$ digits of the product. - -Recall from ~GAMMA~ the definition of $\gamma$ as the number of bits in the type \textbf{mp\_digit}. We shall now extend the variable set to -include $\alpha$ which shall represent the number of bits in the type \textbf{mp\_word}. This implies that $2^{\alpha} > 2 \cdot \beta^2$. The -constant $\delta = 2^{\alpha - 2lg(\beta)}$ will represent the maximal weight of any column in a product (\textit{see ~COMBA~ for more information}). - -\newpage\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{s\_mp\_mul\_digs}. \\ -\textbf{Input}. mp\_int $a$, mp\_int $b$ and an integer $digs$ \\ -\textbf{Output}. $c \leftarrow \vert a \vert \cdot \vert b \vert \mbox{ (mod }\beta^{digs}\mbox{)}$. \\ -\hline \\ -1. If min$(a.used, b.used) < \delta$ then do \\ -\hspace{3mm}1.1 Calculate $c = \vert a \vert \cdot \vert b \vert$ by the Comba method (\textit{see algorithm~\ref{fig:COMBAMULT}}). \\ -\hspace{3mm}1.2 Return the result of step 1.1 \\ -\\ -Allocate and initialize a temporary mp\_int. \\ -2. Init $t$ to be of size $digs$ \\ -3. If step 2 failed return(\textit{MP\_MEM}). \\ -4. $t.used \leftarrow digs$ \\ -\\ -Compute the product. \\ -5. for $ix$ from $0$ to $a.used - 1$ do \\ -\hspace{3mm}5.1 $u \leftarrow 0$ \\ -\hspace{3mm}5.2 $pb \leftarrow \mbox{min}(b.used, digs - ix)$ \\ -\hspace{3mm}5.3 If $pb < 1$ then goto step 6. \\ -\hspace{3mm}5.4 for $iy$ from $0$ to $pb - 1$ do \\ -\hspace{6mm}5.4.1 $\hat r \leftarrow t_{iy + ix} + a_{ix} \cdot b_{iy} + u$ \\ -\hspace{6mm}5.4.2 $t_{iy + ix} \leftarrow \hat r \mbox{ (mod }\beta\mbox{)}$ \\ -\hspace{6mm}5.4.3 $u \leftarrow \lfloor \hat r / \beta \rfloor$ \\ -\hspace{3mm}5.5 if $ix + pb < digs$ then do \\ -\hspace{6mm}5.5.1 $t_{ix + pb} \leftarrow u$ \\ -6. Clamp excess digits of $t$. \\ -7. Swap $c$ with $t$ \\ -8. Clear $t$ \\ -9. Return(\textit{MP\_OKAY}). \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm s\_mp\_mul\_digs} -\end{figure} - -\textbf{Algorithm s\_mp\_mul\_digs.} -This algorithm computes the unsigned product of two inputs $a$ and $b$, limited to an output precision of $digs$ digits. While it may seem -a bit awkward to modify the function from its simple $O(n^2)$ description, the usefulness of partial multipliers will arise in a subsequent -algorithm. The algorithm is loosely based on algorithm 14.12 from \cite[pp. 595]{HAC} and is similar to Algorithm M of Knuth \cite[pp. 268]{TAOCPV2}. -Algorithm s\_mp\_mul\_digs differs from these cited references since it can produce a variable output precision regardless of the precision of the -inputs. - -The first thing this algorithm checks for is whether a Comba multiplier can be used instead. If the minimum digit count of either -input is less than $\delta$, then the Comba method may be used instead. After the Comba method is ruled out, the baseline algorithm begins. A -temporary mp\_int variable $t$ is used to hold the intermediate result of the product. This allows the algorithm to be used to -compute products when either $a = c$ or $b = c$ without overwriting the inputs. - -All of step 5 is the infamous $O(n^2)$ multiplication loop slightly modified to only produce upto $digs$ digits of output. The $pb$ variable -is given the count of digits to read from $b$ inside the nested loop. If $pb \le 1$ then no more output digits can be produced and the algorithm -will exit the loop. The best way to think of the loops are as a series of $pb \times 1$ multiplications. That is, in each pass of the -innermost loop $a_{ix}$ is multiplied against $b$ and the result is added (\textit{with an appropriate shift}) to $t$. - -For example, consider multiplying $576$ by $241$. That is equivalent to computing $10^0(1)(576) + 10^1(4)(576) + 10^2(2)(576)$ which is best -visualized in the following table. - -\begin{figure}[here] -\begin{center} -\begin{tabular}{|c|c|c|c|c|c|l|} -\hline && & 5 & 7 & 6 & \\ -\hline $\times$&& & 2 & 4 & 1 & \\ -\hline &&&&&&\\ - && & 5 & 7 & 6 & $10^0(1)(576)$ \\ - &2 & 3 & 6 & 1 & 6 & $10^1(4)(576) + 10^0(1)(576)$ \\ - 1 & 3 & 8 & 8 & 1 & 6 & $10^2(2)(576) + 10^1(4)(576) + 10^0(1)(576)$ \\ -\hline -\end{tabular} -\end{center} -\caption{Long-Hand Multiplication Diagram} -\end{figure} - -Each row of the product is added to the result after being shifted to the left (\textit{multiplied by a power of the radix}) by the appropriate -count. That is in pass $ix$ of the inner loop the product is added starting at the $ix$'th digit of the reult. - -Step 5.4.1 introduces the hat symbol (\textit{e.g. $\hat r$}) which represents a double precision variable. The multiplication on that step -is assumed to be a double wide output single precision multiplication. That is, two single precision variables are multiplied to produce a -double precision result. The step is somewhat optimized from a long-hand multiplication algorithm because the carry from the addition in step -5.4.1 is propagated through the nested loop. If the carry was not propagated immediately it would overflow the single precision digit -$t_{ix+iy}$ and the result would be lost. - -At step 5.5 the nested loop is finished and any carry that was left over should be forwarded. The carry does not have to be added to the $ix+pb$'th -digit since that digit is assumed to be zero at this point. However, if $ix + pb \ge digs$ the carry is not set as it would make the result -exceed the precision requested. - -EXAM,bn_s_mp_mul_digs.c - -First we determine (line @30,if@) if the Comba method can be used first since it's faster. The conditions for -sing the Comba routine are that min$(a.used, b.used) < \delta$ and the number of digits of output is less than -\textbf{MP\_WARRAY}. This new constant is used to control the stack usage in the Comba routines. By default it is -set to $\delta$ but can be reduced when memory is at a premium. - -If we cannot use the Comba method we proceed to setup the baseline routine. We allocate the the destination mp\_int -$t$ (line @36,init@) to the exact size of the output to avoid further re--allocations. At this point we now -begin the $O(n^2)$ loop. - -This implementation of multiplication has the caveat that it can be trimmed to only produce a variable number of -digits as output. In each iteration of the outer loop the $pb$ variable is set (line @48,MIN@) to the maximum -number of inner loop iterations. - -Inside the inner loop we calculate $\hat r$ as the mp\_word product of the two mp\_digits and the addition of the -carry from the previous iteration. A particularly important observation is that most modern optimizing -C compilers (GCC for instance) can recognize that a $N \times N \rightarrow 2N$ multiplication is all that -is required for the product. In x86 terms for example, this means using the MUL instruction. - -Each digit of the product is stored in turn (line @68,tmpt@) and the carry propagated (line @71,>>@) to the -next iteration. - -\subsection{Faster Multiplication by the ``Comba'' Method} -MARK,COMBA - -One of the huge drawbacks of the ``baseline'' algorithms is that at the $O(n^2)$ level the carry must be -computed and propagated upwards. This makes the nested loop very sequential and hard to unroll and implement -in parallel. The ``Comba'' \cite{COMBA} method is named after little known (\textit{in cryptographic venues}) Paul G. -Comba who described a method of implementing fast multipliers that do not require nested carry fixup operations. As an -interesting aside it seems that Paul Barrett describes a similar technique in his 1986 paper \cite{BARRETT} written -five years before. - -At the heart of the Comba technique is once again the long-hand algorithm. Except in this case a slight -twist is placed on how the columns of the result are produced. In the standard long-hand algorithm rows of products -are produced then added together to form the final result. In the baseline algorithm the columns are added together -after each iteration to get the result instantaneously. - -In the Comba algorithm the columns of the result are produced entirely independently of each other. That is at -the $O(n^2)$ level a simple multiplication and addition step is performed. The carries of the columns are propagated -after the nested loop to reduce the amount of work requiored. Succintly the first step of the algorithm is to compute -the product vector $\vec x$ as follows. - -\begin{equation} -\vec x_n = \sum_{i+j = n} a_ib_j, \forall n \in \lbrace 0, 1, 2, \ldots, i + j \rbrace -\end{equation} - -Where $\vec x_n$ is the $n'th$ column of the output vector. Consider the following example which computes the vector $\vec x$ for the multiplication -of $576$ and $241$. - -\newpage\begin{figure}[here] -\begin{small} -\begin{center} -\begin{tabular}{|c|c|c|c|c|c|} - \hline & & 5 & 7 & 6 & First Input\\ - \hline $\times$ & & 2 & 4 & 1 & Second Input\\ -\hline & & $1 \cdot 5 = 5$ & $1 \cdot 7 = 7$ & $1 \cdot 6 = 6$ & First pass \\ - & $4 \cdot 5 = 20$ & $4 \cdot 7+5=33$ & $4 \cdot 6+7=31$ & 6 & Second pass \\ - $2 \cdot 5 = 10$ & $2 \cdot 7 + 20 = 34$ & $2 \cdot 6+33=45$ & 31 & 6 & Third pass \\ -\hline 10 & 34 & 45 & 31 & 6 & Final Result \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Comba Multiplication Diagram} -\end{figure} - -At this point the vector $x = \left < 10, 34, 45, 31, 6 \right >$ is the result of the first step of the Comba multipler. -Now the columns must be fixed by propagating the carry upwards. The resultant vector will have one extra dimension over the input vector which is -congruent to adding a leading zero digit. - -\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{Comba Fixup}. \\ -\textbf{Input}. Vector $\vec x$ of dimension $k$ \\ -\textbf{Output}. Vector $\vec x$ such that the carries have been propagated. \\ -\hline \\ -1. for $n$ from $0$ to $k - 1$ do \\ -\hspace{3mm}1.1 $\vec x_{n+1} \leftarrow \vec x_{n+1} + \lfloor \vec x_{n}/\beta \rfloor$ \\ -\hspace{3mm}1.2 $\vec x_{n} \leftarrow \vec x_{n} \mbox{ (mod }\beta\mbox{)}$ \\ -2. Return($\vec x$). \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm Comba Fixup} -\end{figure} - -With that algorithm and $k = 5$ and $\beta = 10$ the following vector is produced $\vec x= \left < 1, 3, 8, 8, 1, 6 \right >$. In this case -$241 \cdot 576$ is in fact $138816$ and the procedure succeeded. If the algorithm is correct and as will be demonstrated shortly more -efficient than the baseline algorithm why not simply always use this algorithm? - -\subsubsection{Column Weight.} -At the nested $O(n^2)$ level the Comba method adds the product of two single precision variables to each column of the output -independently. A serious obstacle is if the carry is lost, due to lack of precision before the algorithm has a chance to fix -the carries. For example, in the multiplication of two three-digit numbers the third column of output will be the sum of -three single precision multiplications. If the precision of the accumulator for the output digits is less then $3 \cdot (\beta - 1)^2$ then -an overflow can occur and the carry information will be lost. For any $m$ and $n$ digit inputs the maximum weight of any column is -min$(m, n)$ which is fairly obvious. - -The maximum number of terms in any column of a product is known as the ``column weight'' and strictly governs when the algorithm can be used. Recall -from earlier that a double precision type has $\alpha$ bits of resolution and a single precision digit has $lg(\beta)$ bits of precision. Given these -two quantities we must not violate the following - -\begin{equation} -k \cdot \left (\beta - 1 \right )^2 < 2^{\alpha} -\end{equation} - -Which reduces to - -\begin{equation} -k \cdot \left ( \beta^2 - 2\beta + 1 \right ) < 2^{\alpha} -\end{equation} - -Let $\rho = lg(\beta)$ represent the number of bits in a single precision digit. By further re-arrangement of the equation the final solution is -found. - -\begin{equation} -k < {{2^{\alpha}} \over {\left (2^{2\rho} - 2^{\rho + 1} + 1 \right )}} -\end{equation} - -The defaults for LibTomMath are $\beta = 2^{28}$ and $\alpha = 2^{64}$ which means that $k$ is bounded by $k < 257$. In this configuration -the smaller input may not have more than $256$ digits if the Comba method is to be used. This is quite satisfactory for most applications since -$256$ digits would allow for numbers in the range of $0 \le x < 2^{7168}$ which, is much larger than most public key cryptographic algorithms require. - -\newpage\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{fast\_s\_mp\_mul\_digs}. \\ -\textbf{Input}. mp\_int $a$, mp\_int $b$ and an integer $digs$ \\ -\textbf{Output}. $c \leftarrow \vert a \vert \cdot \vert b \vert \mbox{ (mod }\beta^{digs}\mbox{)}$. \\ -\hline \\ -Place an array of \textbf{MP\_WARRAY} single precision digits named $W$ on the stack. \\ -1. If $c.alloc < digs$ then grow $c$ to $digs$ digits. (\textit{mp\_grow}) \\ -2. If step 1 failed return(\textit{MP\_MEM}).\\ -\\ -3. $pa \leftarrow \mbox{MIN}(digs, a.used + b.used)$ \\ -\\ -4. $\_ \hat W \leftarrow 0$ \\ -5. for $ix$ from 0 to $pa - 1$ do \\ -\hspace{3mm}5.1 $ty \leftarrow \mbox{MIN}(b.used - 1, ix)$ \\ -\hspace{3mm}5.2 $tx \leftarrow ix - ty$ \\ -\hspace{3mm}5.3 $iy \leftarrow \mbox{MIN}(a.used - tx, ty + 1)$ \\ -\hspace{3mm}5.4 for $iz$ from 0 to $iy - 1$ do \\ -\hspace{6mm}5.4.1 $\_ \hat W \leftarrow \_ \hat W + a_{tx+iy}b_{ty-iy}$ \\ -\hspace{3mm}5.5 $W_{ix} \leftarrow \_ \hat W (\mbox{mod }\beta)$\\ -\hspace{3mm}5.6 $\_ \hat W \leftarrow \lfloor \_ \hat W / \beta \rfloor$ \\ -\\ -6. $oldused \leftarrow c.used$ \\ -7. $c.used \leftarrow digs$ \\ -8. for $ix$ from $0$ to $pa$ do \\ -\hspace{3mm}8.1 $c_{ix} \leftarrow W_{ix}$ \\ -9. for $ix$ from $pa + 1$ to $oldused - 1$ do \\ -\hspace{3mm}9.1 $c_{ix} \leftarrow 0$ \\ -\\ -10. Clamp $c$. \\ -11. Return MP\_OKAY. \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm fast\_s\_mp\_mul\_digs} -\label{fig:COMBAMULT} -\end{figure} - -\textbf{Algorithm fast\_s\_mp\_mul\_digs.} -This algorithm performs the unsigned multiplication of $a$ and $b$ using the Comba method limited to $digs$ digits of precision. - -The outer loop of this algorithm is more complicated than that of the baseline multiplier. This is because on the inside of the -loop we want to produce one column per pass. This allows the accumulator $\_ \hat W$ to be placed in CPU registers and -reduce the memory bandwidth to two \textbf{mp\_digit} reads per iteration. - -The $ty$ variable is set to the minimum count of $ix$ or the number of digits in $b$. That way if $a$ has more digits than -$b$ this will be limited to $b.used - 1$. The $tx$ variable is set to the to the distance past $b.used$ the variable -$ix$ is. This is used for the immediately subsequent statement where we find $iy$. - -The variable $iy$ is the minimum digits we can read from either $a$ or $b$ before running out. Computing one column at a time -means we have to scan one integer upwards and the other downwards. $a$ starts at $tx$ and $b$ starts at $ty$. In each -pass we are producing the $ix$'th output column and we note that $tx + ty = ix$. As we move $tx$ upwards we have to -move $ty$ downards so the equality remains valid. The $iy$ variable is the number of iterations until -$tx \ge a.used$ or $ty < 0$ occurs. - -After every inner pass we store the lower half of the accumulator into $W_{ix}$ and then propagate the carry of the accumulator -into the next round by dividing $\_ \hat W$ by $\beta$. - -To measure the benefits of the Comba method over the baseline method consider the number of operations that are required. If the -cost in terms of time of a multiply and addition is $p$ and the cost of a carry propagation is $q$ then a baseline multiplication would require -$O \left ((p + q)n^2 \right )$ time to multiply two $n$-digit numbers. The Comba method requires only $O(pn^2 + qn)$ time, however in practice, -the speed increase is actually much more. With $O(n)$ space the algorithm can be reduced to $O(pn + qn)$ time by implementing the $n$ multiply -and addition operations in the nested loop in parallel. - -EXAM,bn_fast_s_mp_mul_digs.c - -As per the pseudo--code we first calculate $pa$ (line @47,MIN@) as the number of digits to output. Next we begin the outer loop -to produce the individual columns of the product. We use the two aliases $tmpx$ and $tmpy$ (lines @61,tmpx@, @62,tmpy@) to point -inside the two multiplicands quickly. - -The inner loop (lines @70,for@ to @72,}@) of this implementation is where the tradeoff come into play. Originally this comba -implementation was ``row--major'' which means it adds to each of the columns in each pass. After the outer loop it would then fix -the carries. This was very fast except it had an annoying drawback. You had to read a mp\_word and two mp\_digits and write -one mp\_word per iteration. On processors such as the Athlon XP and P4 this did not matter much since the cache bandwidth -is very high and it can keep the ALU fed with data. It did, however, matter on older and embedded cpus where cache is often -slower and also often doesn't exist. This new algorithm only performs two reads per iteration under the assumption that the -compiler has aliased $\_ \hat W$ to a CPU register. - -After the inner loop we store the current accumulator in $W$ and shift $\_ \hat W$ (lines @75,W[ix]@, @78,>>@) to forward it as -a carry for the next pass. After the outer loop we use the final carry (line @82,W[ix]@) as the last digit of the product. - -\subsection{Polynomial Basis Multiplication} -To break the $O(n^2)$ barrier in multiplication requires a completely different look at integer multiplication. In the following algorithms -the use of polynomial basis representation for two integers $a$ and $b$ as $f(x) = \sum_{i=0}^{n} a_i x^i$ and -$g(x) = \sum_{i=0}^{n} b_i x^i$ respectively, is required. In this system both $f(x)$ and $g(x)$ have $n + 1$ terms and are of the $n$'th degree. - -The product $a \cdot b \equiv f(x)g(x)$ is the polynomial $W(x) = \sum_{i=0}^{2n} w_i x^i$. The coefficients $w_i$ will -directly yield the desired product when $\beta$ is substituted for $x$. The direct solution to solve for the $2n + 1$ coefficients -requires $O(n^2)$ time and would in practice be slower than the Comba technique. - -However, numerical analysis theory indicates that only $2n + 1$ distinct points in $W(x)$ are required to determine the values of the $2n + 1$ unknown -coefficients. This means by finding $\zeta_y = W(y)$ for $2n + 1$ small values of $y$ the coefficients of $W(x)$ can be found with -Gaussian elimination. This technique is also occasionally refered to as the \textit{interpolation technique} (\textit{references please...}) since in -effect an interpolation based on $2n + 1$ points will yield a polynomial equivalent to $W(x)$. - -The coefficients of the polynomial $W(x)$ are unknown which makes finding $W(y)$ for any value of $y$ impossible. However, since -$W(x) = f(x)g(x)$ the equivalent $\zeta_y = f(y) g(y)$ can be used in its place. The benefit of this technique stems from the -fact that $f(y)$ and $g(y)$ are much smaller than either $a$ or $b$ respectively. As a result finding the $2n + 1$ relations required -by multiplying $f(y)g(y)$ involves multiplying integers that are much smaller than either of the inputs. - -When picking points to gather relations there are always three obvious points to choose, $y = 0, 1$ and $ \infty$. The $\zeta_0$ term -is simply the product $W(0) = w_0 = a_0 \cdot b_0$. The $\zeta_1$ term is the product -$W(1) = \left (\sum_{i = 0}^{n} a_i \right ) \left (\sum_{i = 0}^{n} b_i \right )$. The third point $\zeta_{\infty}$ is less obvious but rather -simple to explain. The $2n + 1$'th coefficient of $W(x)$ is numerically equivalent to the most significant column in an integer multiplication. -The point at $\infty$ is used symbolically to represent the most significant column, that is $W(\infty) = w_{2n} = a_nb_n$. Note that the -points at $y = 0$ and $\infty$ yield the coefficients $w_0$ and $w_{2n}$ directly. - -If more points are required they should be of small values and powers of two such as $2^q$ and the related \textit{mirror points} -$\left (2^q \right )^{2n} \cdot \zeta_{2^{-q}}$ for small values of $q$. The term ``mirror point'' stems from the fact that -$\left (2^q \right )^{2n} \cdot \zeta_{2^{-q}}$ can be calculated in the exact opposite fashion as $\zeta_{2^q}$. For -example, when $n = 2$ and $q = 1$ then following two equations are equivalent to the point $\zeta_{2}$ and its mirror. - -\begin{eqnarray} -\zeta_{2} = f(2)g(2) = (4a_2 + 2a_1 + a_0)(4b_2 + 2b_1 + b_0) \nonumber \\ -16 \cdot \zeta_{1 \over 2} = 4f({1\over 2}) \cdot 4g({1 \over 2}) = (a_2 + 2a_1 + 4a_0)(b_2 + 2b_1 + 4b_0) -\end{eqnarray} - -Using such points will allow the values of $f(y)$ and $g(y)$ to be independently calculated using only left shifts. For example, when $n = 2$ the -polynomial $f(2^q)$ is equal to $2^q((2^qa_2) + a_1) + a_0$. This technique of polynomial representation is known as Horner's method. - -As a general rule of the algorithm when the inputs are split into $n$ parts each there are $2n - 1$ multiplications. Each multiplication is of -multiplicands that have $n$ times fewer digits than the inputs. The asymptotic running time of this algorithm is -$O \left ( k^{lg_n(2n - 1)} \right )$ for $k$ digit inputs (\textit{assuming they have the same number of digits}). Figure~\ref{fig:exponent} -summarizes the exponents for various values of $n$. - -\begin{figure} -\begin{center} -\begin{tabular}{|c|c|c|} -\hline \textbf{Split into $n$ Parts} & \textbf{Exponent} & \textbf{Notes}\\ -\hline $2$ & $1.584962501$ & This is Karatsuba Multiplication. \\ -\hline $3$ & $1.464973520$ & This is Toom-Cook Multiplication. \\ -\hline $4$ & $1.403677461$ &\\ -\hline $5$ & $1.365212389$ &\\ -\hline $10$ & $1.278753601$ &\\ -\hline $100$ & $1.149426538$ &\\ -\hline $1000$ & $1.100270931$ &\\ -\hline $10000$ & $1.075252070$ &\\ -\hline -\end{tabular} -\end{center} -\caption{Asymptotic Running Time of Polynomial Basis Multiplication} -\label{fig:exponent} -\end{figure} - -At first it may seem like a good idea to choose $n = 1000$ since the exponent is approximately $1.1$. However, the overhead -of solving for the 2001 terms of $W(x)$ will certainly consume any savings the algorithm could offer for all but exceedingly large -numbers. - -\subsubsection{Cutoff Point} -The polynomial basis multiplication algorithms all require fewer single precision multiplications than a straight Comba approach. However, -the algorithms incur an overhead (\textit{at the $O(n)$ work level}) since they require a system of equations to be solved. This makes the -polynomial basis approach more costly to use with small inputs. - -Let $m$ represent the number of digits in the multiplicands (\textit{assume both multiplicands have the same number of digits}). There exists a -point $y$ such that when $m < y$ the polynomial basis algorithms are more costly than Comba, when $m = y$ they are roughly the same cost and -when $m > y$ the Comba methods are slower than the polynomial basis algorithms. - -The exact location of $y$ depends on several key architectural elements of the computer platform in question. - -\begin{enumerate} -\item The ratio of clock cycles for single precision multiplication versus other simpler operations such as addition, shifting, etc. For example -on the AMD Athlon the ratio is roughly $17 : 1$ while on the Intel P4 it is $29 : 1$. The higher the ratio in favour of multiplication the lower -the cutoff point $y$ will be. - -\item The complexity of the linear system of equations (\textit{for the coefficients of $W(x)$}) is. Generally speaking as the number of splits -grows the complexity grows substantially. Ideally solving the system will only involve addition, subtraction and shifting of integers. This -directly reflects on the ratio previous mentioned. - -\item To a lesser extent memory bandwidth and function call overheads. Provided the values are in the processor cache this is less of an -influence over the cutoff point. - -\end{enumerate} - -A clean cutoff point separation occurs when a point $y$ is found such that all of the cutoff point conditions are met. For example, if the point -is too low then there will be values of $m$ such that $m > y$ and the Comba method is still faster. Finding the cutoff points is fairly simple when -a high resolution timer is available. - -\subsection{Karatsuba Multiplication} -Karatsuba \cite{KARA} multiplication when originally proposed in 1962 was among the first set of algorithms to break the $O(n^2)$ barrier for -general purpose multiplication. Given two polynomial basis representations $f(x) = ax + b$ and $g(x) = cx + d$, Karatsuba proved with -light algebra \cite{KARAP} that the following polynomial is equivalent to multiplication of the two integers the polynomials represent. - -\begin{equation} -f(x) \cdot g(x) = acx^2 + ((a + b)(c + d) - (ac + bd))x + bd -\end{equation} - -Using the observation that $ac$ and $bd$ could be re-used only three half sized multiplications would be required to produce the product. Applying -this algorithm recursively, the work factor becomes $O(n^{lg(3)})$ which is substantially better than the work factor $O(n^2)$ of the Comba technique. It turns -out what Karatsuba did not know or at least did not publish was that this is simply polynomial basis multiplication with the points -$\zeta_0$, $\zeta_{\infty}$ and $\zeta_{1}$. Consider the resultant system of equations. - -\begin{center} -\begin{tabular}{rcrcrcrc} -$\zeta_{0}$ & $=$ & & & & & $w_0$ \\ -$\zeta_{1}$ & $=$ & $w_2$ & $+$ & $w_1$ & $+$ & $w_0$ \\ -$\zeta_{\infty}$ & $=$ & $w_2$ & & & & \\ -\end{tabular} -\end{center} - -By adding the first and last equation to the equation in the middle the term $w_1$ can be isolated and all three coefficients solved for. The simplicity -of this system of equations has made Karatsuba fairly popular. In fact the cutoff point is often fairly low\footnote{With LibTomMath 0.18 it is 70 and 109 digits for the Intel P4 and AMD Athlon respectively.} -making it an ideal algorithm to speed up certain public key cryptosystems such as RSA and Diffie-Hellman. - -\newpage\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_karatsuba\_mul}. \\ -\textbf{Input}. mp\_int $a$ and mp\_int $b$ \\ -\textbf{Output}. $c \leftarrow \vert a \vert \cdot \vert b \vert$ \\ -\hline \\ -1. Init the following mp\_int variables: $x0$, $x1$, $y0$, $y1$, $t1$, $x0y0$, $x1y1$.\\ -2. If step 2 failed then return(\textit{MP\_MEM}). \\ -\\ -Split the input. e.g. $a = x1 \cdot \beta^B + x0$ \\ -3. $B \leftarrow \mbox{min}(a.used, b.used)/2$ \\ -4. $x0 \leftarrow a \mbox{ (mod }\beta^B\mbox{)}$ (\textit{mp\_mod\_2d}) \\ -5. $y0 \leftarrow b \mbox{ (mod }\beta^B\mbox{)}$ \\ -6. $x1 \leftarrow \lfloor a / \beta^B \rfloor$ (\textit{mp\_rshd}) \\ -7. $y1 \leftarrow \lfloor b / \beta^B \rfloor$ \\ -\\ -Calculate the three products. \\ -8. $x0y0 \leftarrow x0 \cdot y0$ (\textit{mp\_mul}) \\ -9. $x1y1 \leftarrow x1 \cdot y1$ \\ -10. $t1 \leftarrow x1 + x0$ (\textit{mp\_add}) \\ -11. $x0 \leftarrow y1 + y0$ \\ -12. $t1 \leftarrow t1 \cdot x0$ \\ -\\ -Calculate the middle term. \\ -13. $x0 \leftarrow x0y0 + x1y1$ \\ -14. $t1 \leftarrow t1 - x0$ (\textit{s\_mp\_sub}) \\ -\\ -Calculate the final product. \\ -15. $t1 \leftarrow t1 \cdot \beta^B$ (\textit{mp\_lshd}) \\ -16. $x1y1 \leftarrow x1y1 \cdot \beta^{2B}$ \\ -17. $t1 \leftarrow x0y0 + t1$ \\ -18. $c \leftarrow t1 + x1y1$ \\ -19. Clear all of the temporary variables. \\ -20. Return(\textit{MP\_OKAY}).\\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm mp\_karatsuba\_mul} -\end{figure} - -\textbf{Algorithm mp\_karatsuba\_mul.} -This algorithm computes the unsigned product of two inputs using the Karatsuba multiplication algorithm. It is loosely based on the description -from Knuth \cite[pp. 294-295]{TAOCPV2}. - -\index{radix point} -In order to split the two inputs into their respective halves, a suitable \textit{radix point} must be chosen. The radix point chosen must -be used for both of the inputs meaning that it must be smaller than the smallest input. Step 3 chooses the radix point $B$ as half of the -smallest input \textbf{used} count. After the radix point is chosen the inputs are split into lower and upper halves. Step 4 and 5 -compute the lower halves. Step 6 and 7 computer the upper halves. - -After the halves have been computed the three intermediate half-size products must be computed. Step 8 and 9 compute the trivial products -$x0 \cdot y0$ and $x1 \cdot y1$. The mp\_int $x0$ is used as a temporary variable after $x1 + x0$ has been computed. By using $x0$ instead -of an additional temporary variable, the algorithm can avoid an addition memory allocation operation. - -The remaining steps 13 through 18 compute the Karatsuba polynomial through a variety of digit shifting and addition operations. - -EXAM,bn_mp_karatsuba_mul.c - -The new coding element in this routine, not seen in previous routines, is the usage of goto statements. The conventional -wisdom is that goto statements should be avoided. This is generally true, however when every single function call can fail, it makes sense -to handle error recovery with a single piece of code. Lines @61,if@ to @75,if@ handle initializing all of the temporary variables -required. Note how each of the if statements goes to a different label in case of failure. This allows the routine to correctly free only -the temporaries that have been successfully allocated so far. - -The temporary variables are all initialized using the mp\_init\_size routine since they are expected to be large. This saves the -additional reallocation that would have been necessary. Also $x0$, $x1$, $y0$ and $y1$ have to be able to hold at least their respective -number of digits for the next section of code. - -The first algebraic portion of the algorithm is to split the two inputs into their halves. However, instead of using mp\_mod\_2d and mp\_rshd -to extract the halves, the respective code has been placed inline within the body of the function. To initialize the halves, the \textbf{used} and -\textbf{sign} members are copied first. The first for loop on line @98,for@ copies the lower halves. Since they are both the same magnitude it -is simpler to calculate both lower halves in a single loop. The for loop on lines @104,for@ and @109,for@ calculate the upper halves $x1$ and -$y1$ respectively. - -By inlining the calculation of the halves, the Karatsuba multiplier has a slightly lower overhead and can be used for smaller magnitude inputs. - -When line @152,err@ is reached, the algorithm has completed succesfully. The ``error status'' variable $err$ is set to \textbf{MP\_OKAY} so that -the same code that handles errors can be used to clear the temporary variables and return. - -\subsection{Toom-Cook $3$-Way Multiplication} -Toom-Cook $3$-Way \cite{TOOM} multiplication is essentially the polynomial basis algorithm for $n = 2$ except that the points are -chosen such that $\zeta$ is easy to compute and the resulting system of equations easy to reduce. Here, the points $\zeta_{0}$, -$16 \cdot \zeta_{1 \over 2}$, $\zeta_1$, $\zeta_2$ and $\zeta_{\infty}$ make up the five required points to solve for the coefficients -of the $W(x)$. - -With the five relations that Toom-Cook specifies, the following system of equations is formed. - -\begin{center} -\begin{tabular}{rcrcrcrcrcr} -$\zeta_0$ & $=$ & $0w_4$ & $+$ & $0w_3$ & $+$ & $0w_2$ & $+$ & $0w_1$ & $+$ & $1w_0$ \\ -$16 \cdot \zeta_{1 \over 2}$ & $=$ & $1w_4$ & $+$ & $2w_3$ & $+$ & $4w_2$ & $+$ & $8w_1$ & $+$ & $16w_0$ \\ -$\zeta_1$ & $=$ & $1w_4$ & $+$ & $1w_3$ & $+$ & $1w_2$ & $+$ & $1w_1$ & $+$ & $1w_0$ \\ -$\zeta_2$ & $=$ & $16w_4$ & $+$ & $8w_3$ & $+$ & $4w_2$ & $+$ & $2w_1$ & $+$ & $1w_0$ \\ -$\zeta_{\infty}$ & $=$ & $1w_4$ & $+$ & $0w_3$ & $+$ & $0w_2$ & $+$ & $0w_1$ & $+$ & $0w_0$ \\ -\end{tabular} -\end{center} - -A trivial solution to this matrix requires $12$ subtractions, two multiplications by a small power of two, two divisions by a small power -of two, two divisions by three and one multiplication by three. All of these $19$ sub-operations require less than quadratic time, meaning that -the algorithm can be faster than a baseline multiplication. However, the greater complexity of this algorithm places the cutoff point -(\textbf{TOOM\_MUL\_CUTOFF}) where Toom-Cook becomes more efficient much higher than the Karatsuba cutoff point. - -\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_toom\_mul}. \\ -\textbf{Input}. mp\_int $a$ and mp\_int $b$ \\ -\textbf{Output}. $c \leftarrow a \cdot b $ \\ -\hline \\ -Split $a$ and $b$ into three pieces. E.g. $a = a_2 \beta^{2k} + a_1 \beta^{k} + a_0$ \\ -1. $k \leftarrow \lfloor \mbox{min}(a.used, b.used) / 3 \rfloor$ \\ -2. $a_0 \leftarrow a \mbox{ (mod }\beta^{k}\mbox{)}$ \\ -3. $a_1 \leftarrow \lfloor a / \beta^k \rfloor$, $a_1 \leftarrow a_1 \mbox{ (mod }\beta^{k}\mbox{)}$ \\ -4. $a_2 \leftarrow \lfloor a / \beta^{2k} \rfloor$, $a_2 \leftarrow a_2 \mbox{ (mod }\beta^{k}\mbox{)}$ \\ -5. $b_0 \leftarrow a \mbox{ (mod }\beta^{k}\mbox{)}$ \\ -6. $b_1 \leftarrow \lfloor a / \beta^k \rfloor$, $b_1 \leftarrow b_1 \mbox{ (mod }\beta^{k}\mbox{)}$ \\ -7. $b_2 \leftarrow \lfloor a / \beta^{2k} \rfloor$, $b_2 \leftarrow b_2 \mbox{ (mod }\beta^{k}\mbox{)}$ \\ -\\ -Find the five equations for $w_0, w_1, ..., w_4$. \\ -8. $w_0 \leftarrow a_0 \cdot b_0$ \\ -9. $w_4 \leftarrow a_2 \cdot b_2$ \\ -10. $tmp_1 \leftarrow 2 \cdot a_0$, $tmp_1 \leftarrow a_1 + tmp_1$, $tmp_1 \leftarrow 2 \cdot tmp_1$, $tmp_1 \leftarrow tmp_1 + a_2$ \\ -11. $tmp_2 \leftarrow 2 \cdot b_0$, $tmp_2 \leftarrow b_1 + tmp_2$, $tmp_2 \leftarrow 2 \cdot tmp_2$, $tmp_2 \leftarrow tmp_2 + b_2$ \\ -12. $w_1 \leftarrow tmp_1 \cdot tmp_2$ \\ -13. $tmp_1 \leftarrow 2 \cdot a_2$, $tmp_1 \leftarrow a_1 + tmp_1$, $tmp_1 \leftarrow 2 \cdot tmp_1$, $tmp_1 \leftarrow tmp_1 + a_0$ \\ -14. $tmp_2 \leftarrow 2 \cdot b_2$, $tmp_2 \leftarrow b_1 + tmp_2$, $tmp_2 \leftarrow 2 \cdot tmp_2$, $tmp_2 \leftarrow tmp_2 + b_0$ \\ -15. $w_3 \leftarrow tmp_1 \cdot tmp_2$ \\ -16. $tmp_1 \leftarrow a_0 + a_1$, $tmp_1 \leftarrow tmp_1 + a_2$, $tmp_2 \leftarrow b_0 + b_1$, $tmp_2 \leftarrow tmp_2 + b_2$ \\ -17. $w_2 \leftarrow tmp_1 \cdot tmp_2$ \\ -\\ -Continued on the next page.\\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm mp\_toom\_mul} -\end{figure} - -\newpage\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_toom\_mul} (continued). \\ -\textbf{Input}. mp\_int $a$ and mp\_int $b$ \\ -\textbf{Output}. $c \leftarrow a \cdot b $ \\ -\hline \\ -Now solve the system of equations. \\ -18. $w_1 \leftarrow w_4 - w_1$, $w_3 \leftarrow w_3 - w_0$ \\ -19. $w_1 \leftarrow \lfloor w_1 / 2 \rfloor$, $w_3 \leftarrow \lfloor w_3 / 2 \rfloor$ \\ -20. $w_2 \leftarrow w_2 - w_0$, $w_2 \leftarrow w_2 - w_4$ \\ -21. $w_1 \leftarrow w_1 - w_2$, $w_3 \leftarrow w_3 - w_2$ \\ -22. $tmp_1 \leftarrow 8 \cdot w_0$, $w_1 \leftarrow w_1 - tmp_1$, $tmp_1 \leftarrow 8 \cdot w_4$, $w_3 \leftarrow w_3 - tmp_1$ \\ -23. $w_2 \leftarrow 3 \cdot w_2$, $w_2 \leftarrow w_2 - w_1$, $w_2 \leftarrow w_2 - w_3$ \\ -24. $w_1 \leftarrow w_1 - w_2$, $w_3 \leftarrow w_3 - w_2$ \\ -25. $w_1 \leftarrow \lfloor w_1 / 3 \rfloor, w_3 \leftarrow \lfloor w_3 / 3 \rfloor$ \\ -\\ -Now substitute $\beta^k$ for $x$ by shifting $w_0, w_1, ..., w_4$. \\ -26. for $n$ from $1$ to $4$ do \\ -\hspace{3mm}26.1 $w_n \leftarrow w_n \cdot \beta^{nk}$ \\ -27. $c \leftarrow w_0 + w_1$, $c \leftarrow c + w_2$, $c \leftarrow c + w_3$, $c \leftarrow c + w_4$ \\ -28. Return(\textit{MP\_OKAY}) \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm mp\_toom\_mul (continued)} -\end{figure} - -\textbf{Algorithm mp\_toom\_mul.} -This algorithm computes the product of two mp\_int variables $a$ and $b$ using the Toom-Cook approach. Compared to the Karatsuba multiplication, this -algorithm has a lower asymptotic running time of approximately $O(n^{1.464})$ but at an obvious cost in overhead. In this -description, several statements have been compounded to save space. The intention is that the statements are executed from left to right across -any given step. - -The two inputs $a$ and $b$ are first split into three $k$-digit integers $a_0, a_1, a_2$ and $b_0, b_1, b_2$ respectively. From these smaller -integers the coefficients of the polynomial basis representations $f(x)$ and $g(x)$ are known and can be used to find the relations required. - -The first two relations $w_0$ and $w_4$ are the points $\zeta_{0}$ and $\zeta_{\infty}$ respectively. The relation $w_1, w_2$ and $w_3$ correspond -to the points $16 \cdot \zeta_{1 \over 2}, \zeta_{2}$ and $\zeta_{1}$ respectively. These are found using logical shifts to independently find -$f(y)$ and $g(y)$ which significantly speeds up the algorithm. - -After the five relations $w_0, w_1, \ldots, w_4$ have been computed, the system they represent must be solved in order for the unknown coefficients -$w_1, w_2$ and $w_3$ to be isolated. The steps 18 through 25 perform the system reduction required as previously described. Each step of -the reduction represents the comparable matrix operation that would be performed had this been performed by pencil. For example, step 18 indicates -that row $1$ must be subtracted from row $4$ and simultaneously row $0$ subtracted from row $3$. - -Once the coeffients have been isolated, the polynomial $W(x) = \sum_{i=0}^{2n} w_i x^i$ is known. By substituting $\beta^{k}$ for $x$, the integer -result $a \cdot b$ is produced. - -EXAM,bn_mp_toom_mul.c - -The first obvious thing to note is that this algorithm is complicated. The complexity is worth it if you are multiplying very -large numbers. For example, a 10,000 digit multiplication takes approximaly 99,282,205 fewer single precision multiplications with -Toom--Cook than a Comba or baseline approach (this is a savings of more than 99$\%$). For most ``crypto'' sized numbers this -algorithm is not practical as Karatsuba has a much lower cutoff point. - -First we split $a$ and $b$ into three roughly equal portions. This has been accomplished (lines @40,mod@ to @69,rshd@) with -combinations of mp\_rshd() and mp\_mod\_2d() function calls. At this point $a = a2 \cdot \beta^2 + a1 \cdot \beta + a0$ and similiarly -for $b$. - -Next we compute the five points $w0, w1, w2, w3$ and $w4$. Recall that $w0$ and $w4$ can be computed directly from the portions so -we get those out of the way first (lines @72,mul@ and @77,mul@). Next we compute $w1, w2$ and $w3$ using Horners method. - -After this point we solve for the actual values of $w1, w2$ and $w3$ by reducing the $5 \times 5$ system which is relatively -straight forward. - -\subsection{Signed Multiplication} -Now that algorithms to handle multiplications of every useful dimensions have been developed, a rather simple finishing touch is required. So far all -of the multiplication algorithms have been unsigned multiplications which leaves only a signed multiplication algorithm to be established. - -\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_mul}. \\ -\textbf{Input}. mp\_int $a$ and mp\_int $b$ \\ -\textbf{Output}. $c \leftarrow a \cdot b$ \\ -\hline \\ -1. If $a.sign = b.sign$ then \\ -\hspace{3mm}1.1 $sign = MP\_ZPOS$ \\ -2. else \\ -\hspace{3mm}2.1 $sign = MP\_ZNEG$ \\ -3. If min$(a.used, b.used) \ge TOOM\_MUL\_CUTOFF$ then \\ -\hspace{3mm}3.1 $c \leftarrow a \cdot b$ using algorithm mp\_toom\_mul \\ -4. else if min$(a.used, b.used) \ge KARATSUBA\_MUL\_CUTOFF$ then \\ -\hspace{3mm}4.1 $c \leftarrow a \cdot b$ using algorithm mp\_karatsuba\_mul \\ -5. else \\ -\hspace{3mm}5.1 $digs \leftarrow a.used + b.used + 1$ \\ -\hspace{3mm}5.2 If $digs < MP\_ARRAY$ and min$(a.used, b.used) \le \delta$ then \\ -\hspace{6mm}5.2.1 $c \leftarrow a \cdot b \mbox{ (mod }\beta^{digs}\mbox{)}$ using algorithm fast\_s\_mp\_mul\_digs. \\ -\hspace{3mm}5.3 else \\ -\hspace{6mm}5.3.1 $c \leftarrow a \cdot b \mbox{ (mod }\beta^{digs}\mbox{)}$ using algorithm s\_mp\_mul\_digs. \\ -6. $c.sign \leftarrow sign$ \\ -7. Return the result of the unsigned multiplication performed. \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm mp\_mul} -\end{figure} - -\textbf{Algorithm mp\_mul.} -This algorithm performs the signed multiplication of two inputs. It will make use of any of the three unsigned multiplication algorithms -available when the input is of appropriate size. The \textbf{sign} of the result is not set until the end of the algorithm since algorithm -s\_mp\_mul\_digs will clear it. - -EXAM,bn_mp_mul.c - -The implementation is rather simplistic and is not particularly noteworthy. Line @22,?@ computes the sign of the result using the ``?'' -operator from the C programming language. Line @37,<<@ computes $\delta$ using the fact that $1 << k$ is equal to $2^k$. - -\section{Squaring} -\label{sec:basesquare} - -Squaring is a special case of multiplication where both multiplicands are equal. At first it may seem like there is no significant optimization -available but in fact there is. Consider the multiplication of $576$ against $241$. In total there will be nine single precision multiplications -performed which are $1\cdot 6$, $1 \cdot 7$, $1 \cdot 5$, $4 \cdot 6$, $4 \cdot 7$, $4 \cdot 5$, $2 \cdot 6$, $2 \cdot 7$ and $2 \cdot 5$. Now consider -the multiplication of $123$ against $123$. The nine products are $3 \cdot 3$, $3 \cdot 2$, $3 \cdot 1$, $2 \cdot 3$, $2 \cdot 2$, $2 \cdot 1$, -$1 \cdot 3$, $1 \cdot 2$ and $1 \cdot 1$. On closer inspection some of the products are equivalent. For example, $3 \cdot 2 = 2 \cdot 3$ -and $3 \cdot 1 = 1 \cdot 3$. - -For any $n$-digit input, there are ${{\left (n^2 + n \right)}\over 2}$ possible unique single precision multiplications required compared to the $n^2$ -required for multiplication. The following diagram gives an example of the operations required. - -\begin{figure}[here] -\begin{center} -\begin{tabular}{ccccc|c} -&&1&2&3&\\ -$\times$ &&1&2&3&\\ -\hline && $3 \cdot 1$ & $3 \cdot 2$ & $3 \cdot 3$ & Row 0\\ - & $2 \cdot 1$ & $2 \cdot 2$ & $2 \cdot 3$ && Row 1 \\ - $1 \cdot 1$ & $1 \cdot 2$ & $1 \cdot 3$ &&& Row 2 \\ -\end{tabular} -\end{center} -\caption{Squaring Optimization Diagram} -\end{figure} - -MARK,SQUARE -Starting from zero and numbering the columns from right to left a very simple pattern becomes obvious. For the purposes of this discussion let $x$ -represent the number being squared. The first observation is that in row $k$ the $2k$'th column of the product has a $\left (x_k \right)^2$ term in it. - -The second observation is that every column $j$ in row $k$ where $j \ne 2k$ is part of a double product. Every non-square term of a column will -appear twice hence the name ``double product''. Every odd column is made up entirely of double products. In fact every column is made up of double -products and at most one square (\textit{see the exercise section}). - -The third and final observation is that for row $k$ the first unique non-square term, that is, one that hasn't already appeared in an earlier row, -occurs at column $2k + 1$. For example, on row $1$ of the previous squaring, column one is part of the double product with column one from row zero. -Column two of row one is a square and column three is the first unique column. - -\subsection{The Baseline Squaring Algorithm} -The baseline squaring algorithm is meant to be a catch-all squaring algorithm. It will handle any of the input sizes that the faster routines -will not handle. - -\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{s\_mp\_sqr}. \\ -\textbf{Input}. mp\_int $a$ \\ -\textbf{Output}. $b \leftarrow a^2$ \\ -\hline \\ -1. Init a temporary mp\_int of at least $2 \cdot a.used +1$ digits. (\textit{mp\_init\_size}) \\ -2. If step 1 failed return(\textit{MP\_MEM}) \\ -3. $t.used \leftarrow 2 \cdot a.used + 1$ \\ -4. For $ix$ from 0 to $a.used - 1$ do \\ -\hspace{3mm}Calculate the square. \\ -\hspace{3mm}4.1 $\hat r \leftarrow t_{2ix} + \left (a_{ix} \right )^2$ \\ -\hspace{3mm}4.2 $t_{2ix} \leftarrow \hat r \mbox{ (mod }\beta\mbox{)}$ \\ -\hspace{3mm}Calculate the double products after the square. \\ -\hspace{3mm}4.3 $u \leftarrow \lfloor \hat r / \beta \rfloor$ \\ -\hspace{3mm}4.4 For $iy$ from $ix + 1$ to $a.used - 1$ do \\ -\hspace{6mm}4.4.1 $\hat r \leftarrow 2 \cdot a_{ix}a_{iy} + t_{ix + iy} + u$ \\ -\hspace{6mm}4.4.2 $t_{ix + iy} \leftarrow \hat r \mbox{ (mod }\beta\mbox{)}$ \\ -\hspace{6mm}4.4.3 $u \leftarrow \lfloor \hat r / \beta \rfloor$ \\ -\hspace{3mm}Set the last carry. \\ -\hspace{3mm}4.5 While $u > 0$ do \\ -\hspace{6mm}4.5.1 $iy \leftarrow iy + 1$ \\ -\hspace{6mm}4.5.2 $\hat r \leftarrow t_{ix + iy} + u$ \\ -\hspace{6mm}4.5.3 $t_{ix + iy} \leftarrow \hat r \mbox{ (mod }\beta\mbox{)}$ \\ -\hspace{6mm}4.5.4 $u \leftarrow \lfloor \hat r / \beta \rfloor$ \\ -5. Clamp excess digits of $t$. (\textit{mp\_clamp}) \\ -6. Exchange $b$ and $t$. \\ -7. Clear $t$ (\textit{mp\_clear}) \\ -8. Return(\textit{MP\_OKAY}) \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm s\_mp\_sqr} -\end{figure} - -\textbf{Algorithm s\_mp\_sqr.} -This algorithm computes the square of an input using the three observations on squaring. It is based fairly faithfully on algorithm 14.16 of HAC -\cite[pp.596-597]{HAC}. Similar to algorithm s\_mp\_mul\_digs, a temporary mp\_int is allocated to hold the result of the squaring. This allows the -destination mp\_int to be the same as the source mp\_int. - -The outer loop of this algorithm begins on step 4. It is best to think of the outer loop as walking down the rows of the partial results, while -the inner loop computes the columns of the partial result. Step 4.1 and 4.2 compute the square term for each row, and step 4.3 and 4.4 propagate -the carry and compute the double products. - -The requirement that a mp\_word be able to represent the range $0 \le x < 2 \beta^2$ arises from this -very algorithm. The product $a_{ix}a_{iy}$ will lie in the range $0 \le x \le \beta^2 - 2\beta + 1$ which is obviously less than $\beta^2$ meaning that -when it is multiplied by two, it can be properly represented by a mp\_word. - -Similar to algorithm s\_mp\_mul\_digs, after every pass of the inner loop, the destination is correctly set to the sum of all of the partial -results calculated so far. This involves expensive carry propagation which will be eliminated in the next algorithm. - -EXAM,bn_s_mp_sqr.c - -Inside the outer loop (line @32,for@) the square term is calculated on line @35,r =@. The carry (line @42,>>@) has been -extracted from the mp\_word accumulator using a right shift. Aliases for $a_{ix}$ and $t_{ix+iy}$ are initialized -(lines @45,tmpx@ and @48,tmpt@) to simplify the inner loop. The doubling is performed using two -additions (line @57,r + r@) since it is usually faster than shifting, if not at least as fast. - -The important observation is that the inner loop does not begin at $iy = 0$ like for multiplication. As such the inner loops -get progressively shorter as the algorithm proceeds. This is what leads to the savings compared to using a multiplication to -square a number. - -\subsection{Faster Squaring by the ``Comba'' Method} -A major drawback to the baseline method is the requirement for single precision shifting inside the $O(n^2)$ nested loop. Squaring has an additional -drawback that it must double the product inside the inner loop as well. As for multiplication, the Comba technique can be used to eliminate these -performance hazards. - -The first obvious solution is to make an array of mp\_words which will hold all of the columns. This will indeed eliminate all of the carry -propagation operations from the inner loop. However, the inner product must still be doubled $O(n^2)$ times. The solution stems from the simple fact -that $2a + 2b + 2c = 2(a + b + c)$. That is the sum of all of the double products is equal to double the sum of all the products. For example, -$ab + ba + ac + ca = 2ab + 2ac = 2(ab + ac)$. - -However, we cannot simply double all of the columns, since the squares appear only once per row. The most practical solution is to have two -mp\_word arrays. One array will hold the squares and the other array will hold the double products. With both arrays the doubling and -carry propagation can be moved to a $O(n)$ work level outside the $O(n^2)$ level. In this case, we have an even simpler solution in mind. - -\newpage\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{fast\_s\_mp\_sqr}. \\ -\textbf{Input}. mp\_int $a$ \\ -\textbf{Output}. $b \leftarrow a^2$ \\ -\hline \\ -Place an array of \textbf{MP\_WARRAY} mp\_digits named $W$ on the stack. \\ -1. If $b.alloc < 2a.used + 1$ then grow $b$ to $2a.used + 1$ digits. (\textit{mp\_grow}). \\ -2. If step 1 failed return(\textit{MP\_MEM}). \\ -\\ -3. $pa \leftarrow 2 \cdot a.used$ \\ -4. $\hat W1 \leftarrow 0$ \\ -5. for $ix$ from $0$ to $pa - 1$ do \\ -\hspace{3mm}5.1 $\_ \hat W \leftarrow 0$ \\ -\hspace{3mm}5.2 $ty \leftarrow \mbox{MIN}(a.used - 1, ix)$ \\ -\hspace{3mm}5.3 $tx \leftarrow ix - ty$ \\ -\hspace{3mm}5.4 $iy \leftarrow \mbox{MIN}(a.used - tx, ty + 1)$ \\ -\hspace{3mm}5.5 $iy \leftarrow \mbox{MIN}(iy, \lfloor \left (ty - tx + 1 \right )/2 \rfloor)$ \\ -\hspace{3mm}5.6 for $iz$ from $0$ to $iz - 1$ do \\ -\hspace{6mm}5.6.1 $\_ \hat W \leftarrow \_ \hat W + a_{tx + iz}a_{ty - iz}$ \\ -\hspace{3mm}5.7 $\_ \hat W \leftarrow 2 \cdot \_ \hat W + \hat W1$ \\ -\hspace{3mm}5.8 if $ix$ is even then \\ -\hspace{6mm}5.8.1 $\_ \hat W \leftarrow \_ \hat W + \left ( a_{\lfloor ix/2 \rfloor}\right )^2$ \\ -\hspace{3mm}5.9 $W_{ix} \leftarrow \_ \hat W (\mbox{mod }\beta)$ \\ -\hspace{3mm}5.10 $\hat W1 \leftarrow \lfloor \_ \hat W / \beta \rfloor$ \\ -\\ -6. $oldused \leftarrow b.used$ \\ -7. $b.used \leftarrow 2 \cdot a.used$ \\ -8. for $ix$ from $0$ to $pa - 1$ do \\ -\hspace{3mm}8.1 $b_{ix} \leftarrow W_{ix}$ \\ -9. for $ix$ from $pa$ to $oldused - 1$ do \\ -\hspace{3mm}9.1 $b_{ix} \leftarrow 0$ \\ -10. Clamp excess digits from $b$. (\textit{mp\_clamp}) \\ -11. Return(\textit{MP\_OKAY}). \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm fast\_s\_mp\_sqr} -\end{figure} - -\textbf{Algorithm fast\_s\_mp\_sqr.} -This algorithm computes the square of an input using the Comba technique. It is designed to be a replacement for algorithm -s\_mp\_sqr when the number of input digits is less than \textbf{MP\_WARRAY} and less than $\delta \over 2$. -This algorithm is very similar to the Comba multiplier except with a few key differences we shall make note of. - -First, we have an accumulator and carry variables $\_ \hat W$ and $\hat W1$ respectively. This is because the inner loop -products are to be doubled. If we had added the previous carry in we would be doubling too much. Next we perform an -addition MIN condition on $iy$ (step 5.5) to prevent overlapping digits. For example, $a_3 \cdot a_5$ is equal -$a_5 \cdot a_3$. Whereas in the multiplication case we would have $5 < a.used$ and $3 \ge 0$ is maintained since we double the sum -of the products just outside the inner loop we have to avoid doing this. This is also a good thing since we perform -fewer multiplications and the routine ends up being faster. - -Finally the last difference is the addition of the ``square'' term outside the inner loop (step 5.8). We add in the square -only to even outputs and it is the square of the term at the $\lfloor ix / 2 \rfloor$ position. - -EXAM,bn_fast_s_mp_sqr.c - -This implementation is essentially a copy of Comba multiplication with the appropriate changes added to make it faster for -the special case of squaring. - -\subsection{Polynomial Basis Squaring} -The same algorithm that performs optimal polynomial basis multiplication can be used to perform polynomial basis squaring. The minor exception -is that $\zeta_y = f(y)g(y)$ is actually equivalent to $\zeta_y = f(y)^2$ since $f(y) = g(y)$. Instead of performing $2n + 1$ -multiplications to find the $\zeta$ relations, squaring operations are performed instead. - -\subsection{Karatsuba Squaring} -Let $f(x) = ax + b$ represent the polynomial basis representation of a number to square. -Let $h(x) = \left ( f(x) \right )^2$ represent the square of the polynomial. The Karatsuba equation can be modified to square a -number with the following equation. - -\begin{equation} -h(x) = a^2x^2 + \left ((a + b)^2 - (a^2 + b^2) \right )x + b^2 -\end{equation} - -Upon closer inspection this equation only requires the calculation of three half-sized squares: $a^2$, $b^2$ and $(a + b)^2$. As in -Karatsuba multiplication, this algorithm can be applied recursively on the input and will achieve an asymptotic running time of -$O \left ( n^{lg(3)} \right )$. - -If the asymptotic times of Karatsuba squaring and multiplication are the same, why not simply use the multiplication algorithm -instead? The answer to this arises from the cutoff point for squaring. As in multiplication there exists a cutoff point, at which the -time required for a Comba based squaring and a Karatsuba based squaring meet. Due to the overhead inherent in the Karatsuba method, the cutoff -point is fairly high. For example, on an AMD Athlon XP processor with $\beta = 2^{28}$, the cutoff point is around 127 digits. - -Consider squaring a 200 digit number with this technique. It will be split into two 100 digit halves which are subsequently squared. -The 100 digit halves will not be squared using Karatsuba, but instead using the faster Comba based squaring algorithm. If Karatsuba multiplication -were used instead, the 100 digit numbers would be squared with a slower Comba based multiplication. - -\newpage\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_karatsuba\_sqr}. \\ -\textbf{Input}. mp\_int $a$ \\ -\textbf{Output}. $b \leftarrow a^2$ \\ -\hline \\ -1. Initialize the following temporary mp\_ints: $x0$, $x1$, $t1$, $t2$, $x0x0$ and $x1x1$. \\ -2. If any of the initializations on step 1 failed return(\textit{MP\_MEM}). \\ -\\ -Split the input. e.g. $a = x1\beta^B + x0$ \\ -3. $B \leftarrow \lfloor a.used / 2 \rfloor$ \\ -4. $x0 \leftarrow a \mbox{ (mod }\beta^B\mbox{)}$ (\textit{mp\_mod\_2d}) \\ -5. $x1 \leftarrow \lfloor a / \beta^B \rfloor$ (\textit{mp\_lshd}) \\ -\\ -Calculate the three squares. \\ -6. $x0x0 \leftarrow x0^2$ (\textit{mp\_sqr}) \\ -7. $x1x1 \leftarrow x1^2$ \\ -8. $t1 \leftarrow x1 + x0$ (\textit{s\_mp\_add}) \\ -9. $t1 \leftarrow t1^2$ \\ -\\ -Compute the middle term. \\ -10. $t2 \leftarrow x0x0 + x1x1$ (\textit{s\_mp\_add}) \\ -11. $t1 \leftarrow t1 - t2$ \\ -\\ -Compute final product. \\ -12. $t1 \leftarrow t1\beta^B$ (\textit{mp\_lshd}) \\ -13. $x1x1 \leftarrow x1x1\beta^{2B}$ \\ -14. $t1 \leftarrow t1 + x0x0$ \\ -15. $b \leftarrow t1 + x1x1$ \\ -16. Return(\textit{MP\_OKAY}). \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm mp\_karatsuba\_sqr} -\end{figure} - -\textbf{Algorithm mp\_karatsuba\_sqr.} -This algorithm computes the square of an input $a$ using the Karatsuba technique. This algorithm is very similar to the Karatsuba based -multiplication algorithm with the exception that the three half-size multiplications have been replaced with three half-size squarings. - -The radix point for squaring is simply placed exactly in the middle of the digits when the input has an odd number of digits, otherwise it is -placed just below the middle. Step 3, 4 and 5 compute the two halves required using $B$ -as the radix point. The first two squares in steps 6 and 7 are rather straightforward while the last square is of a more compact form. - -By expanding $\left (x1 + x0 \right )^2$, the $x1^2$ and $x0^2$ terms in the middle disappear, that is $(x0 - x1)^2 - (x1^2 + x0^2) = 2 \cdot x0 \cdot x1$. -Now if $5n$ single precision additions and a squaring of $n$-digits is faster than multiplying two $n$-digit numbers and doubling then -this method is faster. Assuming no further recursions occur, the difference can be estimated with the following inequality. - -Let $p$ represent the cost of a single precision addition and $q$ the cost of a single precision multiplication both in terms of time\footnote{Or -machine clock cycles.}. - -\begin{equation} -5pn +{{q(n^2 + n)} \over 2} \le pn + qn^2 -\end{equation} - -For example, on an AMD Athlon XP processor $p = {1 \over 3}$ and $q = 6$. This implies that the following inequality should hold. -\begin{center} -\begin{tabular}{rcl} -${5n \over 3} + 3n^2 + 3n$ & $<$ & ${n \over 3} + 6n^2$ \\ -${5 \over 3} + 3n + 3$ & $<$ & ${1 \over 3} + 6n$ \\ -${13 \over 9}$ & $<$ & $n$ \\ -\end{tabular} -\end{center} - -This results in a cutoff point around $n = 2$. As a consequence it is actually faster to compute the middle term the ``long way'' on processors -where multiplication is substantially slower\footnote{On the Athlon there is a 1:17 ratio between clock cycles for addition and multiplication. On -the Intel P4 processor this ratio is 1:29 making this method even more beneficial. The only common exception is the ARMv4 processor which has a -ratio of 1:7. } than simpler operations such as addition. - -EXAM,bn_mp_karatsuba_sqr.c - -This implementation is largely based on the implementation of algorithm mp\_karatsuba\_mul. It uses the same inline style to copy and -shift the input into the two halves. The loop from line @54,{@ to line @70,}@ has been modified since only one input exists. The \textbf{used} -count of both $x0$ and $x1$ is fixed up and $x0$ is clamped before the calculations begin. At this point $x1$ and $x0$ are valid equivalents -to the respective halves as if mp\_rshd and mp\_mod\_2d had been used. - -By inlining the copy and shift operations the cutoff point for Karatsuba multiplication can be lowered. On the Athlon the cutoff point -is exactly at the point where Comba squaring can no longer be used (\textit{128 digits}). On slower processors such as the Intel P4 -it is actually below the Comba limit (\textit{at 110 digits}). - -This routine uses the same error trap coding style as mp\_karatsuba\_sqr. As the temporary variables are initialized errors are -redirected to the error trap higher up. If the algorithm completes without error the error code is set to \textbf{MP\_OKAY} and -mp\_clears are executed normally. - -\subsection{Toom-Cook Squaring} -The Toom-Cook squaring algorithm mp\_toom\_sqr is heavily based on the algorithm mp\_toom\_mul with the exception that squarings are used -instead of multiplication to find the five relations. The reader is encouraged to read the description of the latter algorithm and try to -derive their own Toom-Cook squaring algorithm. - -\subsection{High Level Squaring} -\newpage\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_sqr}. \\ -\textbf{Input}. mp\_int $a$ \\ -\textbf{Output}. $b \leftarrow a^2$ \\ -\hline \\ -1. If $a.used \ge TOOM\_SQR\_CUTOFF$ then \\ -\hspace{3mm}1.1 $b \leftarrow a^2$ using algorithm mp\_toom\_sqr \\ -2. else if $a.used \ge KARATSUBA\_SQR\_CUTOFF$ then \\ -\hspace{3mm}2.1 $b \leftarrow a^2$ using algorithm mp\_karatsuba\_sqr \\ -3. else \\ -\hspace{3mm}3.1 $digs \leftarrow a.used + b.used + 1$ \\ -\hspace{3mm}3.2 If $digs < MP\_ARRAY$ and $a.used \le \delta$ then \\ -\hspace{6mm}3.2.1 $b \leftarrow a^2$ using algorithm fast\_s\_mp\_sqr. \\ -\hspace{3mm}3.3 else \\ -\hspace{6mm}3.3.1 $b \leftarrow a^2$ using algorithm s\_mp\_sqr. \\ -4. $b.sign \leftarrow MP\_ZPOS$ \\ -5. Return the result of the unsigned squaring performed. \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm mp\_sqr} -\end{figure} - -\textbf{Algorithm mp\_sqr.} -This algorithm computes the square of the input using one of four different algorithms. If the input is very large and has at least -\textbf{TOOM\_SQR\_CUTOFF} or \textbf{KARATSUBA\_SQR\_CUTOFF} digits then either the Toom-Cook or the Karatsuba Squaring algorithm is used. If -neither of the polynomial basis algorithms should be used then either the Comba or baseline algorithm is used. - -EXAM,bn_mp_sqr.c - -\section*{Exercises} -\begin{tabular}{cl} -$\left [ 3 \right ] $ & Devise an efficient algorithm for selection of the radix point to handle inputs \\ - & that have different number of digits in Karatsuba multiplication. \\ - & \\ -$\left [ 2 \right ] $ & In ~SQUARE~ the fact that every column of a squaring is made up \\ - & of double products and at most one square is stated. Prove this statement. \\ - & \\ -$\left [ 3 \right ] $ & Prove the equation for Karatsuba squaring. \\ - & \\ -$\left [ 1 \right ] $ & Prove that Karatsuba squaring requires $O \left (n^{lg(3)} \right )$ time. \\ - & \\ -$\left [ 2 \right ] $ & Determine the minimal ratio between addition and multiplication clock cycles \\ - & required for equation $6.7$ to be true. \\ - & \\ -$\left [ 3 \right ] $ & Implement a threaded version of Comba multiplication (and squaring) where you \\ - & compute subsets of the columns in each thread. Determine a cutoff point where \\ - & it is effective and add the logic to mp\_mul() and mp\_sqr(). \\ - &\\ -$\left [ 4 \right ] $ & Same as the previous but also modify the Karatsuba and Toom-Cook. You must \\ - & increase the throughput of mp\_exptmod() for random odd moduli in the range \\ - & $512 \ldots 4096$ bits significantly ($> 2x$) to complete this challenge. \\ - & \\ -\end{tabular} - -\chapter{Modular Reduction} -MARK,REDUCTION -\section{Basics of Modular Reduction} -\index{modular residue} -Modular reduction is an operation that arises quite often within public key cryptography algorithms and various number theoretic algorithms, -such as factoring. Modular reduction algorithms are the third class of algorithms of the ``multipliers'' set. A number $a$ is said to be \textit{reduced} -modulo another number $b$ by finding the remainder of the division $a/b$. Full integer division with remainder is a topic to be covered -in~\ref{sec:division}. - -Modular reduction is equivalent to solving for $r$ in the following equation. $a = bq + r$ where $q = \lfloor a/b \rfloor$. The result -$r$ is said to be ``congruent to $a$ modulo $b$'' which is also written as $r \equiv a \mbox{ (mod }b\mbox{)}$. In other vernacular $r$ is known as the -``modular residue'' which leads to ``quadratic residue''\footnote{That's fancy talk for $b \equiv a^2 \mbox{ (mod }p\mbox{)}$.} and -other forms of residues. - -Modular reductions are normally used to create either finite groups, rings or fields. The most common usage for performance driven modular reductions -is in modular exponentiation algorithms. That is to compute $d = a^b \mbox{ (mod }c\mbox{)}$ as fast as possible. This operation is used in the -RSA and Diffie-Hellman public key algorithms, for example. Modular multiplication and squaring also appears as a fundamental operation in -elliptic curve cryptographic algorithms. As will be discussed in the subsequent chapter there exist fast algorithms for computing modular -exponentiations without having to perform (\textit{in this example}) $b - 1$ multiplications. These algorithms will produce partial results in the -range $0 \le x < c^2$ which can be taken advantage of to create several efficient algorithms. They have also been used to create redundancy check -algorithms known as CRCs, error correction codes such as Reed-Solomon and solve a variety of number theoeretic problems. - -\section{The Barrett Reduction} -The Barrett reduction algorithm \cite{BARRETT} was inspired by fast division algorithms which multiply by the reciprocal to emulate -division. Barretts observation was that the residue $c$ of $a$ modulo $b$ is equal to - -\begin{equation} -c = a - b \cdot \lfloor a/b \rfloor -\end{equation} - -Since algorithms such as modular exponentiation would be using the same modulus extensively, typical DSP\footnote{It is worth noting that Barrett's paper -targeted the DSP56K processor.} intuition would indicate the next step would be to replace $a/b$ by a multiplication by the reciprocal. However, -DSP intuition on its own will not work as these numbers are considerably larger than the precision of common DSP floating point data types. -It would take another common optimization to optimize the algorithm. - -\subsection{Fixed Point Arithmetic} -The trick used to optimize the above equation is based on a technique of emulating floating point data types with fixed precision integers. Fixed -point arithmetic would become very popular as it greatly optimize the ``3d-shooter'' genre of games in the mid 1990s when floating point units were -fairly slow if not unavailable. The idea behind fixed point arithmetic is to take a normal $k$-bit integer data type and break it into $p$-bit -integer and a $q$-bit fraction part (\textit{where $p+q = k$}). - -In this system a $k$-bit integer $n$ would actually represent $n/2^q$. For example, with $q = 4$ the integer $n = 37$ would actually represent the -value $2.3125$. To multiply two fixed point numbers the integers are multiplied using traditional arithmetic and subsequently normalized by -moving the implied decimal point back to where it should be. For example, with $q = 4$ to multiply the integers $9$ and $5$ they must be converted -to fixed point first by multiplying by $2^q$. Let $a = 9(2^q)$ represent the fixed point representation of $9$ and $b = 5(2^q)$ represent the -fixed point representation of $5$. The product $ab$ is equal to $45(2^{2q})$ which when normalized by dividing by $2^q$ produces $45(2^q)$. - -This technique became popular since a normal integer multiplication and logical shift right are the only required operations to perform a multiplication -of two fixed point numbers. Using fixed point arithmetic, division can be easily approximated by multiplying by the reciprocal. If $2^q$ is -equivalent to one than $2^q/b$ is equivalent to the fixed point approximation of $1/b$ using real arithmetic. Using this fact dividing an integer -$a$ by another integer $b$ can be achieved with the following expression. - -\begin{equation} -\lfloor a / b \rfloor \mbox{ }\approx\mbox{ } \lfloor (a \cdot \lfloor 2^q / b \rfloor)/2^q \rfloor -\end{equation} - -The precision of the division is proportional to the value of $q$. If the divisor $b$ is used frequently as is the case with -modular exponentiation pre-computing $2^q/b$ will allow a division to be performed with a multiplication and a right shift. Both operations -are considerably faster than division on most processors. - -Consider dividing $19$ by $5$. The correct result is $\lfloor 19/5 \rfloor = 3$. With $q = 3$ the reciprocal is $\lfloor 2^q/5 \rfloor = 1$ which -leads to a product of $19$ which when divided by $2^q$ produces $2$. However, with $q = 4$ the reciprocal is $\lfloor 2^q/5 \rfloor = 3$ and -the result of the emulated division is $\lfloor 3 \cdot 19 / 2^q \rfloor = 3$ which is correct. The value of $2^q$ must be close to or ideally -larger than the dividend. In effect if $a$ is the dividend then $q$ should allow $0 \le \lfloor a/2^q \rfloor \le 1$ in order for this approach -to work correctly. Plugging this form of divison into the original equation the following modular residue equation arises. - -\begin{equation} -c = a - b \cdot \lfloor (a \cdot \lfloor 2^q / b \rfloor)/2^q \rfloor -\end{equation} - -Using the notation from \cite{BARRETT} the value of $\lfloor 2^q / b \rfloor$ will be represented by the $\mu$ symbol. Using the $\mu$ -variable also helps re-inforce the idea that it is meant to be computed once and re-used. - -\begin{equation} -c = a - b \cdot \lfloor (a \cdot \mu)/2^q \rfloor -\end{equation} - -Provided that $2^q \ge a$ this algorithm will produce a quotient that is either exactly correct or off by a value of one. In the context of Barrett -reduction the value of $a$ is bound by $0 \le a \le (b - 1)^2$ meaning that $2^q \ge b^2$ is sufficient to ensure the reciprocal will have enough -precision. - -Let $n$ represent the number of digits in $b$. This algorithm requires approximately $2n^2$ single precision multiplications to produce the quotient and -another $n^2$ single precision multiplications to find the residue. In total $3n^2$ single precision multiplications are required to -reduce the number. - -For example, if $b = 1179677$ and $q = 41$ ($2^q > b^2$), then the reciprocal $\mu$ is equal to $\lfloor 2^q / b \rfloor = 1864089$. Consider reducing -$a = 180388626447$ modulo $b$ using the above reduction equation. The quotient using the new formula is $\lfloor (a \cdot \mu) / 2^q \rfloor = 152913$. -By subtracting $152913b$ from $a$ the correct residue $a \equiv 677346 \mbox{ (mod }b\mbox{)}$ is found. - -\subsection{Choosing a Radix Point} -Using the fixed point representation a modular reduction can be performed with $3n^2$ single precision multiplications. If that were the best -that could be achieved a full division\footnote{A division requires approximately $O(2cn^2)$ single precision multiplications for a small value of $c$. -See~\ref{sec:division} for further details.} might as well be used in its place. The key to optimizing the reduction is to reduce the precision of -the initial multiplication that finds the quotient. - -Let $a$ represent the number of which the residue is sought. Let $b$ represent the modulus used to find the residue. Let $m$ represent -the number of digits in $b$. For the purposes of this discussion we will assume that the number of digits in $a$ is $2m$, which is generally true if -two $m$-digit numbers have been multiplied. Dividing $a$ by $b$ is the same as dividing a $2m$ digit integer by a $m$ digit integer. Digits below the -$m - 1$'th digit of $a$ will contribute at most a value of $1$ to the quotient because $\beta^k < b$ for any $0 \le k \le m - 1$. Another way to -express this is by re-writing $a$ as two parts. If $a' \equiv a \mbox{ (mod }b^m\mbox{)}$ and $a'' = a - a'$ then -${a \over b} \equiv {{a' + a''} \over b}$ which is equivalent to ${a' \over b} + {a'' \over b}$. Since $a'$ is bound to be less than $b$ the quotient -is bound by $0 \le {a' \over b} < 1$. - -Since the digits of $a'$ do not contribute much to the quotient the observation is that they might as well be zero. However, if the digits -``might as well be zero'' they might as well not be there in the first place. Let $q_0 = \lfloor a/\beta^{m-1} \rfloor$ represent the input -with the irrelevant digits trimmed. Now the modular reduction is trimmed to the almost equivalent equation - -\begin{equation} -c = a - b \cdot \lfloor (q_0 \cdot \mu) / \beta^{m+1} \rfloor -\end{equation} - -Note that the original divisor $2^q$ has been replaced with $\beta^{m+1}$ where in this case $q$ is a multiple of $lg(\beta)$. Also note that the -exponent on the divisor when added to the amount $q_0$ was shifted by equals $2m$. If the optimization had not been performed the divisor -would have the exponent $2m$ so in the end the exponents do ``add up''. Using the above equation the quotient -$\lfloor (q_0 \cdot \mu) / \beta^{m+1} \rfloor$ can be off from the true quotient by at most two. The original fixed point quotient can be off -by as much as one (\textit{provided the radix point is chosen suitably}) and now that the lower irrelevent digits have been trimmed the quotient -can be off by an additional value of one for a total of at most two. This implies that -$0 \le a - b \cdot \lfloor (q_0 \cdot \mu) / \beta^{m+1} \rfloor < 3b$. By first subtracting $b$ times the quotient and then conditionally subtracting -$b$ once or twice the residue is found. - -The quotient is now found using $(m + 1)(m) = m^2 + m$ single precision multiplications and the residue with an additional $m^2$ single -precision multiplications, ignoring the subtractions required. In total $2m^2 + m$ single precision multiplications are required to find the residue. -This is considerably faster than the original attempt. - -For example, let $\beta = 10$ represent the radix of the digits. Let $b = 9999$ represent the modulus which implies $m = 4$. Let $a = 99929878$ -represent the value of which the residue is desired. In this case $q = 8$ since $10^7 < 9999^2$ meaning that $\mu = \lfloor \beta^{q}/b \rfloor = 10001$. -With the new observation the multiplicand for the quotient is equal to $q_0 = \lfloor a / \beta^{m - 1} \rfloor = 99929$. The quotient is then -$\lfloor (q_0 \cdot \mu) / \beta^{m+1} \rfloor = 9993$. Subtracting $9993b$ from $a$ and the correct residue $a \equiv 9871 \mbox{ (mod }b\mbox{)}$ -is found. - -\subsection{Trimming the Quotient} -So far the reduction algorithm has been optimized from $3m^2$ single precision multiplications down to $2m^2 + m$ single precision multiplications. As -it stands now the algorithm is already fairly fast compared to a full integer division algorithm. However, there is still room for -optimization. - -After the first multiplication inside the quotient ($q_0 \cdot \mu$) the value is shifted right by $m + 1$ places effectively nullifying the lower -half of the product. It would be nice to be able to remove those digits from the product to effectively cut down the number of single precision -multiplications. If the number of digits in the modulus $m$ is far less than $\beta$ a full product is not required for the algorithm to work properly. -In fact the lower $m - 2$ digits will not affect the upper half of the product at all and do not need to be computed. - -The value of $\mu$ is a $m$-digit number and $q_0$ is a $m + 1$ digit number. Using a full multiplier $(m + 1)(m) = m^2 + m$ single precision -multiplications would be required. Using a multiplier that will only produce digits at and above the $m - 1$'th digit reduces the number -of single precision multiplications to ${m^2 + m} \over 2$ single precision multiplications. - -\subsection{Trimming the Residue} -After the quotient has been calculated it is used to reduce the input. As previously noted the algorithm is not exact and it can be off by a small -multiple of the modulus, that is $0 \le a - b \cdot \lfloor (q_0 \cdot \mu) / \beta^{m+1} \rfloor < 3b$. If $b$ is $m$ digits than the -result of reduction equation is a value of at most $m + 1$ digits (\textit{provided $3 < \beta$}) implying that the upper $m - 1$ digits are -implicitly zero. - -The next optimization arises from this very fact. Instead of computing $b \cdot \lfloor (q_0 \cdot \mu) / \beta^{m+1} \rfloor$ using a full -$O(m^2)$ multiplication algorithm only the lower $m+1$ digits of the product have to be computed. Similarly the value of $a$ can -be reduced modulo $\beta^{m+1}$ before the multiple of $b$ is subtracted which simplifes the subtraction as well. A multiplication that produces -only the lower $m+1$ digits requires ${m^2 + 3m - 2} \over 2$ single precision multiplications. - -With both optimizations in place the algorithm is the algorithm Barrett proposed. It requires $m^2 + 2m - 1$ single precision multiplications which -is considerably faster than the straightforward $3m^2$ method. - -\subsection{The Barrett Algorithm} -\newpage\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_reduce}. \\ -\textbf{Input}. mp\_int $a$, mp\_int $b$ and $\mu = \lfloor \beta^{2m}/b \rfloor, m = \lceil lg_{\beta}(b) \rceil, (0 \le a < b^2, b > 1)$ \\ -\textbf{Output}. $a \mbox{ (mod }b\mbox{)}$ \\ -\hline \\ -Let $m$ represent the number of digits in $b$. \\ -1. Make a copy of $a$ and store it in $q$. (\textit{mp\_init\_copy}) \\ -2. $q \leftarrow \lfloor q / \beta^{m - 1} \rfloor$ (\textit{mp\_rshd}) \\ -\\ -Produce the quotient. \\ -3. $q \leftarrow q \cdot \mu$ (\textit{note: only produce digits at or above $m-1$}) \\ -4. $q \leftarrow \lfloor q / \beta^{m + 1} \rfloor$ \\ -\\ -Subtract the multiple of modulus from the input. \\ -5. $a \leftarrow a \mbox{ (mod }\beta^{m+1}\mbox{)}$ (\textit{mp\_mod\_2d}) \\ -6. $q \leftarrow q \cdot b \mbox{ (mod }\beta^{m+1}\mbox{)}$ (\textit{s\_mp\_mul\_digs}) \\ -7. $a \leftarrow a - q$ (\textit{mp\_sub}) \\ -\\ -Add $\beta^{m+1}$ if a carry occured. \\ -8. If $a < 0$ then (\textit{mp\_cmp\_d}) \\ -\hspace{3mm}8.1 $q \leftarrow 1$ (\textit{mp\_set}) \\ -\hspace{3mm}8.2 $q \leftarrow q \cdot \beta^{m+1}$ (\textit{mp\_lshd}) \\ -\hspace{3mm}8.3 $a \leftarrow a + q$ \\ -\\ -Now subtract the modulus if the residue is too large (e.g. quotient too small). \\ -9. While $a \ge b$ do (\textit{mp\_cmp}) \\ -\hspace{3mm}9.1 $c \leftarrow a - b$ \\ -10. Clear $q$. \\ -11. Return(\textit{MP\_OKAY}) \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm mp\_reduce} -\end{figure} - -\textbf{Algorithm mp\_reduce.} -This algorithm will reduce the input $a$ modulo $b$ in place using the Barrett algorithm. It is loosely based on algorithm 14.42 of HAC -\cite[pp. 602]{HAC} which is based on the paper from Paul Barrett \cite{BARRETT}. The algorithm has several restrictions and assumptions which must -be adhered to for the algorithm to work. - -First the modulus $b$ is assumed to be positive and greater than one. If the modulus were less than or equal to one than subtracting -a multiple of it would either accomplish nothing or actually enlarge the input. The input $a$ must be in the range $0 \le a < b^2$ in order -for the quotient to have enough precision. If $a$ is the product of two numbers that were already reduced modulo $b$, this will not be a problem. -Technically the algorithm will still work if $a \ge b^2$ but it will take much longer to finish. The value of $\mu$ is passed as an argument to this -algorithm and is assumed to be calculated and stored before the algorithm is used. - -Recall that the multiplication for the quotient on step 3 must only produce digits at or above the $m-1$'th position. An algorithm called -$s\_mp\_mul\_high\_digs$ which has not been presented is used to accomplish this task. The algorithm is based on $s\_mp\_mul\_digs$ except that -instead of stopping at a given level of precision it starts at a given level of precision. This optimal algorithm can only be used if the number -of digits in $b$ is very much smaller than $\beta$. - -While it is known that -$a \ge b \cdot \lfloor (q_0 \cdot \mu) / \beta^{m+1} \rfloor$ only the lower $m+1$ digits are being used to compute the residue, so an implied -``borrow'' from the higher digits might leave a negative result. After the multiple of the modulus has been subtracted from $a$ the residue must be -fixed up in case it is negative. The invariant $\beta^{m+1}$ must be added to the residue to make it positive again. - -The while loop at step 9 will subtract $b$ until the residue is less than $b$. If the algorithm is performed correctly this step is -performed at most twice, and on average once. However, if $a \ge b^2$ than it will iterate substantially more times than it should. - -EXAM,bn_mp_reduce.c - -The first multiplication that determines the quotient can be performed by only producing the digits from $m - 1$ and up. This essentially halves -the number of single precision multiplications required. However, the optimization is only safe if $\beta$ is much larger than the number of digits -in the modulus. In the source code this is evaluated on lines @36,if@ to @44,}@ where algorithm s\_mp\_mul\_high\_digs is used when it is -safe to do so. - -\subsection{The Barrett Setup Algorithm} -In order to use algorithm mp\_reduce the value of $\mu$ must be calculated in advance. Ideally this value should be computed once and stored for -future use so that the Barrett algorithm can be used without delay. - -\newpage\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_reduce\_setup}. \\ -\textbf{Input}. mp\_int $a$ ($a > 1$) \\ -\textbf{Output}. $\mu \leftarrow \lfloor \beta^{2m}/a \rfloor$ \\ -\hline \\ -1. $\mu \leftarrow 2^{2 \cdot lg(\beta) \cdot m}$ (\textit{mp\_2expt}) \\ -2. $\mu \leftarrow \lfloor \mu / b \rfloor$ (\textit{mp\_div}) \\ -3. Return(\textit{MP\_OKAY}) \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm mp\_reduce\_setup} -\end{figure} - -\textbf{Algorithm mp\_reduce\_setup.} -This algorithm computes the reciprocal $\mu$ required for Barrett reduction. First $\beta^{2m}$ is calculated as $2^{2 \cdot lg(\beta) \cdot m}$ which -is equivalent and much faster. The final value is computed by taking the integer quotient of $\lfloor \mu / b \rfloor$. - -EXAM,bn_mp_reduce_setup.c - -This simple routine calculates the reciprocal $\mu$ required by Barrett reduction. Note the extended usage of algorithm mp\_div where the variable -which would received the remainder is passed as NULL. As will be discussed in~\ref{sec:division} the division routine allows both the quotient and the -remainder to be passed as NULL meaning to ignore the value. - -\section{The Montgomery Reduction} -Montgomery reduction\footnote{Thanks to Niels Ferguson for his insightful explanation of the algorithm.} \cite{MONT} is by far the most interesting -form of reduction in common use. It computes a modular residue which is not actually equal to the residue of the input yet instead equal to a -residue times a constant. However, as perplexing as this may sound the algorithm is relatively simple and very efficient. - -Throughout this entire section the variable $n$ will represent the modulus used to form the residue. As will be discussed shortly the value of -$n$ must be odd. The variable $x$ will represent the quantity of which the residue is sought. Similar to the Barrett algorithm the input -is restricted to $0 \le x < n^2$. To begin the description some simple number theory facts must be established. - -\textbf{Fact 1.} Adding $n$ to $x$ does not change the residue since in effect it adds one to the quotient $\lfloor x / n \rfloor$. Another way -to explain this is that $n$ is (\textit{or multiples of $n$ are}) congruent to zero modulo $n$. Adding zero will not change the value of the residue. - -\textbf{Fact 2.} If $x$ is even then performing a division by two in $\Z$ is congruent to $x \cdot 2^{-1} \mbox{ (mod }n\mbox{)}$. Actually -this is an application of the fact that if $x$ is evenly divisible by any $k \in \Z$ then division in $\Z$ will be congruent to -multiplication by $k^{-1}$ modulo $n$. - -From these two simple facts the following simple algorithm can be derived. - -\newpage\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{Montgomery Reduction}. \\ -\textbf{Input}. Integer $x$, $n$ and $k$ \\ -\textbf{Output}. $2^{-k}x \mbox{ (mod }n\mbox{)}$ \\ -\hline \\ -1. for $t$ from $1$ to $k$ do \\ -\hspace{3mm}1.1 If $x$ is odd then \\ -\hspace{6mm}1.1.1 $x \leftarrow x + n$ \\ -\hspace{3mm}1.2 $x \leftarrow x/2$ \\ -2. Return $x$. \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm Montgomery Reduction} -\end{figure} - -The algorithm reduces the input one bit at a time using the two congruencies stated previously. Inside the loop $n$, which is odd, is -added to $x$ if $x$ is odd. This forces $x$ to be even which allows the division by two in $\Z$ to be congruent to a modular division by two. Since -$x$ is assumed to be initially much larger than $n$ the addition of $n$ will contribute an insignificant magnitude to $x$. Let $r$ represent the -final result of the Montgomery algorithm. If $k > lg(n)$ and $0 \le x < n^2$ then the final result is limited to -$0 \le r < \lfloor x/2^k \rfloor + n$. As a result at most a single subtraction is required to get the residue desired. - -\begin{figure}[here] -\begin{small} -\begin{center} -\begin{tabular}{|c|l|} -\hline \textbf{Step number ($t$)} & \textbf{Result ($x$)} \\ -\hline $1$ & $x + n = 5812$, $x/2 = 2906$ \\ -\hline $2$ & $x/2 = 1453$ \\ -\hline $3$ & $x + n = 1710$, $x/2 = 855$ \\ -\hline $4$ & $x + n = 1112$, $x/2 = 556$ \\ -\hline $5$ & $x/2 = 278$ \\ -\hline $6$ & $x/2 = 139$ \\ -\hline $7$ & $x + n = 396$, $x/2 = 198$ \\ -\hline $8$ & $x/2 = 99$ \\ -\hline $9$ & $x + n = 356$, $x/2 = 178$ \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Example of Montgomery Reduction (I)} -\label{fig:MONT1} -\end{figure} - -Consider the example in figure~\ref{fig:MONT1} which reduces $x = 5555$ modulo $n = 257$ when $k = 9$ (note $\beta^k = 512$ which is larger than $n$). The result of -the algorithm $r = 178$ is congruent to the value of $2^{-9} \cdot 5555 \mbox{ (mod }257\mbox{)}$. When $r$ is multiplied by $2^9$ modulo $257$ the correct residue -$r \equiv 158$ is produced. - -Let $k = \lfloor lg(n) \rfloor + 1$ represent the number of bits in $n$. The current algorithm requires $2k^2$ single precision shifts -and $k^2$ single precision additions. At this rate the algorithm is most certainly slower than Barrett reduction and not terribly useful. -Fortunately there exists an alternative representation of the algorithm. - -\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{Montgomery Reduction} (modified I). \\ -\textbf{Input}. Integer $x$, $n$ and $k$ ($2^k > n$) \\ -\textbf{Output}. $2^{-k}x \mbox{ (mod }n\mbox{)}$ \\ -\hline \\ -1. for $t$ from $1$ to $k$ do \\ -\hspace{3mm}1.1 If the $t$'th bit of $x$ is one then \\ -\hspace{6mm}1.1.1 $x \leftarrow x + 2^tn$ \\ -2. Return $x/2^k$. \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm Montgomery Reduction (modified I)} -\end{figure} - -This algorithm is equivalent since $2^tn$ is a multiple of $n$ and the lower $k$ bits of $x$ are zero by step 2. The number of single -precision shifts has now been reduced from $2k^2$ to $k^2 + k$ which is only a small improvement. - -\begin{figure}[here] -\begin{small} -\begin{center} -\begin{tabular}{|c|l|r|} -\hline \textbf{Step number ($t$)} & \textbf{Result ($x$)} & \textbf{Result ($x$) in Binary} \\ -\hline -- & $5555$ & $1010110110011$ \\ -\hline $1$ & $x + 2^{0}n = 5812$ & $1011010110100$ \\ -\hline $2$ & $5812$ & $1011010110100$ \\ -\hline $3$ & $x + 2^{2}n = 6840$ & $1101010111000$ \\ -\hline $4$ & $x + 2^{3}n = 8896$ & $10001011000000$ \\ -\hline $5$ & $8896$ & $10001011000000$ \\ -\hline $6$ & $8896$ & $10001011000000$ \\ -\hline $7$ & $x + 2^{6}n = 25344$ & $110001100000000$ \\ -\hline $8$ & $25344$ & $110001100000000$ \\ -\hline $9$ & $x + 2^{7}n = 91136$ & $10110010000000000$ \\ -\hline -- & $x/2^k = 178$ & \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Example of Montgomery Reduction (II)} -\label{fig:MONT2} -\end{figure} - -Figure~\ref{fig:MONT2} demonstrates the modified algorithm reducing $x = 5555$ modulo $n = 257$ with $k = 9$. -With this algorithm a single shift right at the end is the only right shift required to reduce the input instead of $k$ right shifts inside the -loop. Note that for the iterations $t = 2, 5, 6$ and $8$ where the result $x$ is not changed. In those iterations the $t$'th bit of $x$ is -zero and the appropriate multiple of $n$ does not need to be added to force the $t$'th bit of the result to zero. - -\subsection{Digit Based Montgomery Reduction} -Instead of computing the reduction on a bit-by-bit basis it is actually much faster to compute it on digit-by-digit basis. Consider the -previous algorithm re-written to compute the Montgomery reduction in this new fashion. - -\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{Montgomery Reduction} (modified II). \\ -\textbf{Input}. Integer $x$, $n$ and $k$ ($\beta^k > n$) \\ -\textbf{Output}. $\beta^{-k}x \mbox{ (mod }n\mbox{)}$ \\ -\hline \\ -1. for $t$ from $0$ to $k - 1$ do \\ -\hspace{3mm}1.1 $x \leftarrow x + \mu n \beta^t$ \\ -2. Return $x/\beta^k$. \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm Montgomery Reduction (modified II)} -\end{figure} - -The value $\mu n \beta^t$ is a multiple of the modulus $n$ meaning that it will not change the residue. If the first digit of -the value $\mu n \beta^t$ equals the negative (modulo $\beta$) of the $t$'th digit of $x$ then the addition will result in a zero digit. This -problem breaks down to solving the following congruency. - -\begin{center} -\begin{tabular}{rcl} -$x_t + \mu n_0$ & $\equiv$ & $0 \mbox{ (mod }\beta\mbox{)}$ \\ -$\mu n_0$ & $\equiv$ & $-x_t \mbox{ (mod }\beta\mbox{)}$ \\ -$\mu$ & $\equiv$ & $-x_t/n_0 \mbox{ (mod }\beta\mbox{)}$ \\ -\end{tabular} -\end{center} - -In each iteration of the loop on step 1 a new value of $\mu$ must be calculated. The value of $-1/n_0 \mbox{ (mod }\beta\mbox{)}$ is used -extensively in this algorithm and should be precomputed. Let $\rho$ represent the negative of the modular inverse of $n_0$ modulo $\beta$. - -For example, let $\beta = 10$ represent the radix. Let $n = 17$ represent the modulus which implies $k = 2$ and $\rho \equiv 7$. Let $x = 33$ -represent the value to reduce. - -\newpage\begin{figure} -\begin{center} -\begin{tabular}{|c|c|c|} -\hline \textbf{Step ($t$)} & \textbf{Value of $x$} & \textbf{Value of $\mu$} \\ -\hline -- & $33$ & --\\ -\hline $0$ & $33 + \mu n = 50$ & $1$ \\ -\hline $1$ & $50 + \mu n \beta = 900$ & $5$ \\ -\hline -\end{tabular} -\end{center} -\caption{Example of Montgomery Reduction} -\end{figure} - -The final result $900$ is then divided by $\beta^k$ to produce the final result $9$. The first observation is that $9 \nequiv x \mbox{ (mod }n\mbox{)}$ -which implies the result is not the modular residue of $x$ modulo $n$. However, recall that the residue is actually multiplied by $\beta^{-k}$ in -the algorithm. To get the true residue the value must be multiplied by $\beta^k$. In this case $\beta^k \equiv 15 \mbox{ (mod }n\mbox{)}$ and -the correct residue is $9 \cdot 15 \equiv 16 \mbox{ (mod }n\mbox{)}$. - -\subsection{Baseline Montgomery Reduction} -The baseline Montgomery reduction algorithm will produce the residue for any size input. It is designed to be a catch-all algororithm for -Montgomery reductions. - -\newpage\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_montgomery\_reduce}. \\ -\textbf{Input}. mp\_int $x$, mp\_int $n$ and a digit $\rho \equiv -1/n_0 \mbox{ (mod }n\mbox{)}$. \\ -\hspace{11.5mm}($0 \le x < n^2, n > 1, (n, \beta) = 1, \beta^k > n$) \\ -\textbf{Output}. $\beta^{-k}x \mbox{ (mod }n\mbox{)}$ \\ -\hline \\ -1. $digs \leftarrow 2n.used + 1$ \\ -2. If $digs < MP\_ARRAY$ and $m.used < \delta$ then \\ -\hspace{3mm}2.1 Use algorithm fast\_mp\_montgomery\_reduce instead. \\ -\\ -Setup $x$ for the reduction. \\ -3. If $x.alloc < digs$ then grow $x$ to $digs$ digits. \\ -4. $x.used \leftarrow digs$ \\ -\\ -Eliminate the lower $k$ digits. \\ -5. For $ix$ from $0$ to $k - 1$ do \\ -\hspace{3mm}5.1 $\mu \leftarrow x_{ix} \cdot \rho \mbox{ (mod }\beta\mbox{)}$ \\ -\hspace{3mm}5.2 $u \leftarrow 0$ \\ -\hspace{3mm}5.3 For $iy$ from $0$ to $k - 1$ do \\ -\hspace{6mm}5.3.1 $\hat r \leftarrow \mu n_{iy} + x_{ix + iy} + u$ \\ -\hspace{6mm}5.3.2 $x_{ix + iy} \leftarrow \hat r \mbox{ (mod }\beta\mbox{)}$ \\ -\hspace{6mm}5.3.3 $u \leftarrow \lfloor \hat r / \beta \rfloor$ \\ -\hspace{3mm}5.4 While $u > 0$ do \\ -\hspace{6mm}5.4.1 $iy \leftarrow iy + 1$ \\ -\hspace{6mm}5.4.2 $x_{ix + iy} \leftarrow x_{ix + iy} + u$ \\ -\hspace{6mm}5.4.3 $u \leftarrow \lfloor x_{ix+iy} / \beta \rfloor$ \\ -\hspace{6mm}5.4.4 $x_{ix + iy} \leftarrow x_{ix+iy} \mbox{ (mod }\beta\mbox{)}$ \\ -\\ -Divide by $\beta^k$ and fix up as required. \\ -6. $x \leftarrow \lfloor x / \beta^k \rfloor$ \\ -7. If $x \ge n$ then \\ -\hspace{3mm}7.1 $x \leftarrow x - n$ \\ -8. Return(\textit{MP\_OKAY}). \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm mp\_montgomery\_reduce} -\end{figure} - -\textbf{Algorithm mp\_montgomery\_reduce.} -This algorithm reduces the input $x$ modulo $n$ in place using the Montgomery reduction algorithm. The algorithm is loosely based -on algorithm 14.32 of \cite[pp.601]{HAC} except it merges the multiplication of $\mu n \beta^t$ with the addition in the inner loop. The -restrictions on this algorithm are fairly easy to adapt to. First $0 \le x < n^2$ bounds the input to numbers in the same range as -for the Barrett algorithm. Additionally if $n > 1$ and $n$ is odd there will exist a modular inverse $\rho$. $\rho$ must be calculated in -advance of this algorithm. Finally the variable $k$ is fixed and a pseudonym for $n.used$. - -Step 2 decides whether a faster Montgomery algorithm can be used. It is based on the Comba technique meaning that there are limits on -the size of the input. This algorithm is discussed in ~COMBARED~. - -Step 5 is the main reduction loop of the algorithm. The value of $\mu$ is calculated once per iteration in the outer loop. The inner loop -calculates $x + \mu n \beta^{ix}$ by multiplying $\mu n$ and adding the result to $x$ shifted by $ix$ digits. Both the addition and -multiplication are performed in the same loop to save time and memory. Step 5.4 will handle any additional carries that escape the inner loop. - -Using a quick inspection this algorithm requires $n$ single precision multiplications for the outer loop and $n^2$ single precision multiplications -in the inner loop. In total $n^2 + n$ single precision multiplications which compares favourably to Barrett at $n^2 + 2n - 1$ single precision -multiplications. - -EXAM,bn_mp_montgomery_reduce.c - -This is the baseline implementation of the Montgomery reduction algorithm. Lines @30,digs@ to @35,}@ determine if the Comba based -routine can be used instead. Line @47,mu@ computes the value of $\mu$ for that particular iteration of the outer loop. - -The multiplication $\mu n \beta^{ix}$ is performed in one step in the inner loop. The alias $tmpx$ refers to the $ix$'th digit of $x$ and -the alias $tmpn$ refers to the modulus $n$. - -\subsection{Faster ``Comba'' Montgomery Reduction} -MARK,COMBARED - -The Montgomery reduction requires fewer single precision multiplications than a Barrett reduction, however it is much slower due to the serial -nature of the inner loop. The Barrett reduction algorithm requires two slightly modified multipliers which can be implemented with the Comba -technique. The Montgomery reduction algorithm cannot directly use the Comba technique to any significant advantage since the inner loop calculates -a $k \times 1$ product $k$ times. - -The biggest obstacle is that at the $ix$'th iteration of the outer loop the value of $x_{ix}$ is required to calculate $\mu$. This means the -carries from $0$ to $ix - 1$ must have been propagated upwards to form a valid $ix$'th digit. The solution as it turns out is very simple. -Perform a Comba like multiplier and inside the outer loop just after the inner loop fix up the $ix + 1$'th digit by forwarding the carry. - -With this change in place the Montgomery reduction algorithm can be performed with a Comba style multiplication loop which substantially increases -the speed of the algorithm. - -\newpage\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{fast\_mp\_montgomery\_reduce}. \\ -\textbf{Input}. mp\_int $x$, mp\_int $n$ and a digit $\rho \equiv -1/n_0 \mbox{ (mod }n\mbox{)}$. \\ -\hspace{11.5mm}($0 \le x < n^2, n > 1, (n, \beta) = 1, \beta^k > n$) \\ -\textbf{Output}. $\beta^{-k}x \mbox{ (mod }n\mbox{)}$ \\ -\hline \\ -Place an array of \textbf{MP\_WARRAY} mp\_word variables called $\hat W$ on the stack. \\ -1. if $x.alloc < n.used + 1$ then grow $x$ to $n.used + 1$ digits. \\ -Copy the digits of $x$ into the array $\hat W$ \\ -2. For $ix$ from $0$ to $x.used - 1$ do \\ -\hspace{3mm}2.1 $\hat W_{ix} \leftarrow x_{ix}$ \\ -3. For $ix$ from $x.used$ to $2n.used - 1$ do \\ -\hspace{3mm}3.1 $\hat W_{ix} \leftarrow 0$ \\ -Elimiate the lower $k$ digits. \\ -4. for $ix$ from $0$ to $n.used - 1$ do \\ -\hspace{3mm}4.1 $\mu \leftarrow \hat W_{ix} \cdot \rho \mbox{ (mod }\beta\mbox{)}$ \\ -\hspace{3mm}4.2 For $iy$ from $0$ to $n.used - 1$ do \\ -\hspace{6mm}4.2.1 $\hat W_{iy + ix} \leftarrow \hat W_{iy + ix} + \mu \cdot n_{iy}$ \\ -\hspace{3mm}4.3 $\hat W_{ix + 1} \leftarrow \hat W_{ix + 1} + \lfloor \hat W_{ix} / \beta \rfloor$ \\ -Propagate carries upwards. \\ -5. for $ix$ from $n.used$ to $2n.used + 1$ do \\ -\hspace{3mm}5.1 $\hat W_{ix + 1} \leftarrow \hat W_{ix + 1} + \lfloor \hat W_{ix} / \beta \rfloor$ \\ -Shift right and reduce modulo $\beta$ simultaneously. \\ -6. for $ix$ from $0$ to $n.used + 1$ do \\ -\hspace{3mm}6.1 $x_{ix} \leftarrow \hat W_{ix + n.used} \mbox{ (mod }\beta\mbox{)}$ \\ -Zero excess digits and fixup $x$. \\ -7. if $x.used > n.used + 1$ then do \\ -\hspace{3mm}7.1 for $ix$ from $n.used + 1$ to $x.used - 1$ do \\ -\hspace{6mm}7.1.1 $x_{ix} \leftarrow 0$ \\ -8. $x.used \leftarrow n.used + 1$ \\ -9. Clamp excessive digits of $x$. \\ -10. If $x \ge n$ then \\ -\hspace{3mm}10.1 $x \leftarrow x - n$ \\ -11. Return(\textit{MP\_OKAY}). \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm fast\_mp\_montgomery\_reduce} -\end{figure} - -\textbf{Algorithm fast\_mp\_montgomery\_reduce.} -This algorithm will compute the Montgomery reduction of $x$ modulo $n$ using the Comba technique. It is on most computer platforms significantly -faster than algorithm mp\_montgomery\_reduce and algorithm mp\_reduce (\textit{Barrett reduction}). The algorithm has the same restrictions -on the input as the baseline reduction algorithm. An additional two restrictions are imposed on this algorithm. The number of digits $k$ in the -the modulus $n$ must not violate $MP\_WARRAY > 2k +1$ and $n < \delta$. When $\beta = 2^{28}$ this algorithm can be used to reduce modulo -a modulus of at most $3,556$ bits in length. - -As in the other Comba reduction algorithms there is a $\hat W$ array which stores the columns of the product. It is initially filled with the -contents of $x$ with the excess digits zeroed. The reduction loop is very similar the to the baseline loop at heart. The multiplication on step -4.1 can be single precision only since $ab \mbox{ (mod }\beta\mbox{)} \equiv (a \mbox{ mod }\beta)(b \mbox{ mod }\beta)$. Some multipliers such -as those on the ARM processors take a variable length time to complete depending on the number of bytes of result it must produce. By performing -a single precision multiplication instead half the amount of time is spent. - -Also note that digit $\hat W_{ix}$ must have the carry from the $ix - 1$'th digit propagated upwards in order for this to work. That is what step -4.3 will do. In effect over the $n.used$ iterations of the outer loop the $n.used$'th lower columns all have the their carries propagated forwards. Note -how the upper bits of those same words are not reduced modulo $\beta$. This is because those values will be discarded shortly and there is no -point. - -Step 5 will propagate the remainder of the carries upwards. On step 6 the columns are reduced modulo $\beta$ and shifted simultaneously as they are -stored in the destination $x$. - -EXAM,bn_fast_mp_montgomery_reduce.c - -The $\hat W$ array is first filled with digits of $x$ on line @49,for@ then the rest of the digits are zeroed on line @54,for@. Both loops share -the same alias variables to make the code easier to read. - -The value of $\mu$ is calculated in an interesting fashion. First the value $\hat W_{ix}$ is reduced modulo $\beta$ and cast to a mp\_digit. This -forces the compiler to use a single precision multiplication and prevents any concerns about loss of precision. Line @101,>>@ fixes the carry -for the next iteration of the loop by propagating the carry from $\hat W_{ix}$ to $\hat W_{ix+1}$. - -The for loop on line @113,for@ propagates the rest of the carries upwards through the columns. The for loop on line @126,for@ reduces the columns -modulo $\beta$ and shifts them $k$ places at the same time. The alias $\_ \hat W$ actually refers to the array $\hat W$ starting at the $n.used$'th -digit, that is $\_ \hat W_{t} = \hat W_{n.used + t}$. - -\subsection{Montgomery Setup} -To calculate the variable $\rho$ a relatively simple algorithm will be required. - -\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_montgomery\_setup}. \\ -\textbf{Input}. mp\_int $n$ ($n > 1$ and $(n, 2) = 1$) \\ -\textbf{Output}. $\rho \equiv -1/n_0 \mbox{ (mod }\beta\mbox{)}$ \\ -\hline \\ -1. $b \leftarrow n_0$ \\ -2. If $b$ is even return(\textit{MP\_VAL}) \\ -3. $x \leftarrow (((b + 2) \mbox{ AND } 4) << 1) + b$ \\ -4. for $k$ from 0 to $\lceil lg(lg(\beta)) \rceil - 2$ do \\ -\hspace{3mm}4.1 $x \leftarrow x \cdot (2 - bx)$ \\ -5. $\rho \leftarrow \beta - x \mbox{ (mod }\beta\mbox{)}$ \\ -6. Return(\textit{MP\_OKAY}). \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm mp\_montgomery\_setup} -\end{figure} - -\textbf{Algorithm mp\_montgomery\_setup.} -This algorithm will calculate the value of $\rho$ required within the Montgomery reduction algorithms. It uses a very interesting trick -to calculate $1/n_0$ when $\beta$ is a power of two. - -EXAM,bn_mp_montgomery_setup.c - -This source code computes the value of $\rho$ required to perform Montgomery reduction. It has been modified to avoid performing excess -multiplications when $\beta$ is not the default 28-bits. - -\section{The Diminished Radix Algorithm} -The Diminished Radix method of modular reduction \cite{DRMET} is a fairly clever technique which can be more efficient than either the Barrett -or Montgomery methods for certain forms of moduli. The technique is based on the following simple congruence. - -\begin{equation} -(x \mbox{ mod } n) + k \lfloor x / n \rfloor \equiv x \mbox{ (mod }(n - k)\mbox{)} -\end{equation} - -This observation was used in the MMB \cite{MMB} block cipher to create a diffusion primitive. It used the fact that if $n = 2^{31}$ and $k=1$ that -then a x86 multiplier could produce the 62-bit product and use the ``shrd'' instruction to perform a double-precision right shift. The proof -of the above equation is very simple. First write $x$ in the product form. - -\begin{equation} -x = qn + r -\end{equation} - -Now reduce both sides modulo $(n - k)$. - -\begin{equation} -x \equiv qk + r \mbox{ (mod }(n-k)\mbox{)} -\end{equation} - -The variable $n$ reduces modulo $n - k$ to $k$. By putting $q = \lfloor x/n \rfloor$ and $r = x \mbox{ mod } n$ -into the equation the original congruence is reproduced, thus concluding the proof. The following algorithm is based on this observation. - -\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{Diminished Radix Reduction}. \\ -\textbf{Input}. Integer $x$, $n$, $k$ \\ -\textbf{Output}. $x \mbox{ mod } (n - k)$ \\ -\hline \\ -1. $q \leftarrow \lfloor x / n \rfloor$ \\ -2. $q \leftarrow k \cdot q$ \\ -3. $x \leftarrow x \mbox{ (mod }n\mbox{)}$ \\ -4. $x \leftarrow x + q$ \\ -5. If $x \ge (n - k)$ then \\ -\hspace{3mm}5.1 $x \leftarrow x - (n - k)$ \\ -\hspace{3mm}5.2 Goto step 1. \\ -6. Return $x$ \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm Diminished Radix Reduction} -\label{fig:DR} -\end{figure} - -This algorithm will reduce $x$ modulo $n - k$ and return the residue. If $0 \le x < (n - k)^2$ then the algorithm will loop almost always -once or twice and occasionally three times. For simplicity sake the value of $x$ is bounded by the following simple polynomial. - -\begin{equation} -0 \le x < n^2 + k^2 - 2nk -\end{equation} - -The true bound is $0 \le x < (n - k - 1)^2$ but this has quite a few more terms. The value of $q$ after step 1 is bounded by the following. - -\begin{equation} -q < n - 2k - k^2/n -\end{equation} - -Since $k^2$ is going to be considerably smaller than $n$ that term will always be zero. The value of $x$ after step 3 is bounded trivially as -$0 \le x < n$. By step four the sum $x + q$ is bounded by - -\begin{equation} -0 \le q + x < (k + 1)n - 2k^2 - 1 -\end{equation} - -With a second pass $q$ will be loosely bounded by $0 \le q < k^2$ after step 2 while $x$ will still be loosely bounded by $0 \le x < n$ after step 3. After the second pass it is highly unlike that the -sum in step 4 will exceed $n - k$. In practice fewer than three passes of the algorithm are required to reduce virtually every input in the -range $0 \le x < (n - k - 1)^2$. - -\begin{figure} -\begin{small} -\begin{center} -\begin{tabular}{|l|} -\hline -$x = 123456789, n = 256, k = 3$ \\ -\hline $q \leftarrow \lfloor x/n \rfloor = 482253$ \\ -$q \leftarrow q*k = 1446759$ \\ -$x \leftarrow x \mbox{ mod } n = 21$ \\ -$x \leftarrow x + q = 1446780$ \\ -$x \leftarrow x - (n - k) = 1446527$ \\ -\hline -$q \leftarrow \lfloor x/n \rfloor = 5650$ \\ -$q \leftarrow q*k = 16950$ \\ -$x \leftarrow x \mbox{ mod } n = 127$ \\ -$x \leftarrow x + q = 17077$ \\ -$x \leftarrow x - (n - k) = 16824$ \\ -\hline -$q \leftarrow \lfloor x/n \rfloor = 65$ \\ -$q \leftarrow q*k = 195$ \\ -$x \leftarrow x \mbox{ mod } n = 184$ \\ -$x \leftarrow x + q = 379$ \\ -$x \leftarrow x - (n - k) = 126$ \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Example Diminished Radix Reduction} -\label{fig:EXDR} -\end{figure} - -Figure~\ref{fig:EXDR} demonstrates the reduction of $x = 123456789$ modulo $n - k = 253$ when $n = 256$ and $k = 3$. Note that even while $x$ -is considerably larger than $(n - k - 1)^2 = 63504$ the algorithm still converges on the modular residue exceedingly fast. In this case only -three passes were required to find the residue $x \equiv 126$. - - -\subsection{Choice of Moduli} -On the surface this algorithm looks like a very expensive algorithm. It requires a couple of subtractions followed by multiplication and other -modular reductions. The usefulness of this algorithm becomes exceedingly clear when an appropriate modulus is chosen. - -Division in general is a very expensive operation to perform. The one exception is when the division is by a power of the radix of representation used. -Division by ten for example is simple for pencil and paper mathematics since it amounts to shifting the decimal place to the right. Similarly division -by two (\textit{or powers of two}) is very simple for binary computers to perform. It would therefore seem logical to choose $n$ of the form $2^p$ -which would imply that $\lfloor x / n \rfloor$ is a simple shift of $x$ right $p$ bits. - -However, there is one operation related to division of power of twos that is even faster than this. If $n = \beta^p$ then the division may be -performed by moving whole digits to the right $p$ places. In practice division by $\beta^p$ is much faster than division by $2^p$ for any $p$. -Also with the choice of $n = \beta^p$ reducing $x$ modulo $n$ merely requires zeroing the digits above the $p-1$'th digit of $x$. - -Throughout the next section the term ``restricted modulus'' will refer to a modulus of the form $\beta^p - k$ whereas the term ``unrestricted -modulus'' will refer to a modulus of the form $2^p - k$. The word ``restricted'' in this case refers to the fact that it is based on the -$2^p$ logic except $p$ must be a multiple of $lg(\beta)$. - -\subsection{Choice of $k$} -Now that division and reduction (\textit{step 1 and 3 of figure~\ref{fig:DR}}) have been optimized to simple digit operations the multiplication by $k$ -in step 2 is the most expensive operation. Fortunately the choice of $k$ is not terribly limited. For all intents and purposes it might -as well be a single digit. The smaller the value of $k$ is the faster the algorithm will be. - -\subsection{Restricted Diminished Radix Reduction} -The restricted Diminished Radix algorithm can quickly reduce an input modulo a modulus of the form $n = \beta^p - k$. This algorithm can reduce -an input $x$ within the range $0 \le x < n^2$ using only a couple passes of the algorithm demonstrated in figure~\ref{fig:DR}. The implementation -of this algorithm has been optimized to avoid additional overhead associated with a division by $\beta^p$, the multiplication by $k$ or the addition -of $x$ and $q$. The resulting algorithm is very efficient and can lead to substantial improvements over Barrett and Montgomery reduction when modular -exponentiations are performed. - -\newpage\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_dr\_reduce}. \\ -\textbf{Input}. mp\_int $x$, $n$ and a mp\_digit $k = \beta - n_0$ \\ -\hspace{11.5mm}($0 \le x < n^2$, $n > 1$, $0 < k < \beta$) \\ -\textbf{Output}. $x \mbox{ mod } n$ \\ -\hline \\ -1. $m \leftarrow n.used$ \\ -2. If $x.alloc < 2m$ then grow $x$ to $2m$ digits. \\ -3. $\mu \leftarrow 0$ \\ -4. for $i$ from $0$ to $m - 1$ do \\ -\hspace{3mm}4.1 $\hat r \leftarrow k \cdot x_{m+i} + x_{i} + \mu$ \\ -\hspace{3mm}4.2 $x_{i} \leftarrow \hat r \mbox{ (mod }\beta\mbox{)}$ \\ -\hspace{3mm}4.3 $\mu \leftarrow \lfloor \hat r / \beta \rfloor$ \\ -5. $x_{m} \leftarrow \mu$ \\ -6. for $i$ from $m + 1$ to $x.used - 1$ do \\ -\hspace{3mm}6.1 $x_{i} \leftarrow 0$ \\ -7. Clamp excess digits of $x$. \\ -8. If $x \ge n$ then \\ -\hspace{3mm}8.1 $x \leftarrow x - n$ \\ -\hspace{3mm}8.2 Goto step 3. \\ -9. Return(\textit{MP\_OKAY}). \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm mp\_dr\_reduce} -\end{figure} - -\textbf{Algorithm mp\_dr\_reduce.} -This algorithm will perform the Dimished Radix reduction of $x$ modulo $n$. It has similar restrictions to that of the Barrett reduction -with the addition that $n$ must be of the form $n = \beta^m - k$ where $0 < k <\beta$. - -This algorithm essentially implements the pseudo-code in figure~\ref{fig:DR} except with a slight optimization. The division by $\beta^m$, multiplication by $k$ -and addition of $x \mbox{ mod }\beta^m$ are all performed simultaneously inside the loop on step 4. The division by $\beta^m$ is emulated by accessing -the term at the $m+i$'th position which is subsequently multiplied by $k$ and added to the term at the $i$'th position. After the loop the $m$'th -digit is set to the carry and the upper digits are zeroed. Steps 5 and 6 emulate the reduction modulo $\beta^m$ that should have happend to -$x$ before the addition of the multiple of the upper half. - -At step 8 if $x$ is still larger than $n$ another pass of the algorithm is required. First $n$ is subtracted from $x$ and then the algorithm resumes -at step 3. - -EXAM,bn_mp_dr_reduce.c - -The first step is to grow $x$ as required to $2m$ digits since the reduction is performed in place on $x$. The label on line @49,top:@ is where -the algorithm will resume if further reduction passes are required. In theory it could be placed at the top of the function however, the size of -the modulus and question of whether $x$ is large enough are invariant after the first pass meaning that it would be a waste of time. - -The aliases $tmpx1$ and $tmpx2$ refer to the digits of $x$ where the latter is offset by $m$ digits. By reading digits from $x$ offset by $m$ digits -a division by $\beta^m$ can be simulated virtually for free. The loop on line @61,for@ performs the bulk of the work (\textit{corresponds to step 4 of algorithm 7.11}) -in this algorithm. - -By line @68,mu@ the pointer $tmpx1$ points to the $m$'th digit of $x$ which is where the final carry will be placed. Similarly by line @71,for@ the -same pointer will point to the $m+1$'th digit where the zeroes will be placed. - -Since the algorithm is only valid if both $x$ and $n$ are greater than zero an unsigned comparison suffices to determine if another pass is required. -With the same logic at line @82,sub@ the value of $x$ is known to be greater than or equal to $n$ meaning that an unsigned subtraction can be used -as well. Since the destination of the subtraction is the larger of the inputs the call to algorithm s\_mp\_sub cannot fail and the return code -does not need to be checked. - -\subsubsection{Setup} -To setup the restricted Diminished Radix algorithm the value $k = \beta - n_0$ is required. This algorithm is not really complicated but provided for -completeness. - -\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_dr\_setup}. \\ -\textbf{Input}. mp\_int $n$ \\ -\textbf{Output}. $k = \beta - n_0$ \\ -\hline \\ -1. $k \leftarrow \beta - n_0$ \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm mp\_dr\_setup} -\end{figure} - -EXAM,bn_mp_dr_setup.c - -\subsubsection{Modulus Detection} -Another algorithm which will be useful is the ability to detect a restricted Diminished Radix modulus. An integer is said to be -of restricted Diminished Radix form if all of the digits are equal to $\beta - 1$ except the trailing digit which may be any value. - -\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_dr\_is\_modulus}. \\ -\textbf{Input}. mp\_int $n$ \\ -\textbf{Output}. $1$ if $n$ is in D.R form, $0$ otherwise \\ -\hline -1. If $n.used < 2$ then return($0$). \\ -2. for $ix$ from $1$ to $n.used - 1$ do \\ -\hspace{3mm}2.1 If $n_{ix} \ne \beta - 1$ return($0$). \\ -3. Return($1$). \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm mp\_dr\_is\_modulus} -\end{figure} - -\textbf{Algorithm mp\_dr\_is\_modulus.} -This algorithm determines if a value is in Diminished Radix form. Step 1 rejects obvious cases where fewer than two digits are -in the mp\_int. Step 2 tests all but the first digit to see if they are equal to $\beta - 1$. If the algorithm manages to get to -step 3 then $n$ must be of Diminished Radix form. - -EXAM,bn_mp_dr_is_modulus.c - -\subsection{Unrestricted Diminished Radix Reduction} -The unrestricted Diminished Radix algorithm allows modular reductions to be performed when the modulus is of the form $2^p - k$. This algorithm -is a straightforward adaptation of algorithm~\ref{fig:DR}. - -In general the restricted Diminished Radix reduction algorithm is much faster since it has considerably lower overhead. However, this new -algorithm is much faster than either Montgomery or Barrett reduction when the moduli are of the appropriate form. - -\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_reduce\_2k}. \\ -\textbf{Input}. mp\_int $a$ and $n$. mp\_digit $k$ \\ -\hspace{11.5mm}($a \ge 0$, $n > 1$, $0 < k < \beta$, $n + k$ is a power of two) \\ -\textbf{Output}. $a \mbox{ (mod }n\mbox{)}$ \\ -\hline -1. $p \leftarrow \lceil lg(n) \rceil$ (\textit{mp\_count\_bits}) \\ -2. While $a \ge n$ do \\ -\hspace{3mm}2.1 $q \leftarrow \lfloor a / 2^p \rfloor$ (\textit{mp\_div\_2d}) \\ -\hspace{3mm}2.2 $a \leftarrow a \mbox{ (mod }2^p\mbox{)}$ (\textit{mp\_mod\_2d}) \\ -\hspace{3mm}2.3 $q \leftarrow q \cdot k$ (\textit{mp\_mul\_d}) \\ -\hspace{3mm}2.4 $a \leftarrow a - q$ (\textit{s\_mp\_sub}) \\ -\hspace{3mm}2.5 If $a \ge n$ then do \\ -\hspace{6mm}2.5.1 $a \leftarrow a - n$ \\ -3. Return(\textit{MP\_OKAY}). \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm mp\_reduce\_2k} -\end{figure} - -\textbf{Algorithm mp\_reduce\_2k.} -This algorithm quickly reduces an input $a$ modulo an unrestricted Diminished Radix modulus $n$. Division by $2^p$ is emulated with a right -shift which makes the algorithm fairly inexpensive to use. - -EXAM,bn_mp_reduce_2k.c - -The algorithm mp\_count\_bits calculates the number of bits in an mp\_int which is used to find the initial value of $p$. The call to mp\_div\_2d -on line @31,mp_div_2d@ calculates both the quotient $q$ and the remainder $a$ required. By doing both in a single function call the code size -is kept fairly small. The multiplication by $k$ is only performed if $k > 1$. This allows reductions modulo $2^p - 1$ to be performed without -any multiplications. - -The unsigned s\_mp\_add, mp\_cmp\_mag and s\_mp\_sub are used in place of their full sign counterparts since the inputs are only valid if they are -positive. By using the unsigned versions the overhead is kept to a minimum. - -\subsubsection{Unrestricted Setup} -To setup this reduction algorithm the value of $k = 2^p - n$ is required. - -\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_reduce\_2k\_setup}. \\ -\textbf{Input}. mp\_int $n$ \\ -\textbf{Output}. $k = 2^p - n$ \\ -\hline -1. $p \leftarrow \lceil lg(n) \rceil$ (\textit{mp\_count\_bits}) \\ -2. $x \leftarrow 2^p$ (\textit{mp\_2expt}) \\ -3. $x \leftarrow x - n$ (\textit{mp\_sub}) \\ -4. $k \leftarrow x_0$ \\ -5. Return(\textit{MP\_OKAY}). \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm mp\_reduce\_2k\_setup} -\end{figure} - -\textbf{Algorithm mp\_reduce\_2k\_setup.} -This algorithm computes the value of $k$ required for the algorithm mp\_reduce\_2k. By making a temporary variable $x$ equal to $2^p$ a subtraction -is sufficient to solve for $k$. Alternatively if $n$ has more than one digit the value of $k$ is simply $\beta - n_0$. - -EXAM,bn_mp_reduce_2k_setup.c - -\subsubsection{Unrestricted Detection} -An integer $n$ is a valid unrestricted Diminished Radix modulus if either of the following are true. - -\begin{enumerate} -\item The number has only one digit. -\item The number has more than one digit and every bit from the $\beta$'th to the most significant is one. -\end{enumerate} - -If either condition is true than there is a power of two $2^p$ such that $0 < 2^p - n < \beta$. If the input is only -one digit than it will always be of the correct form. Otherwise all of the bits above the first digit must be one. This arises from the fact -that there will be value of $k$ that when added to the modulus causes a carry in the first digit which propagates all the way to the most -significant bit. The resulting sum will be a power of two. - -\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_reduce\_is\_2k}. \\ -\textbf{Input}. mp\_int $n$ \\ -\textbf{Output}. $1$ if of proper form, $0$ otherwise \\ -\hline -1. If $n.used = 0$ then return($0$). \\ -2. If $n.used = 1$ then return($1$). \\ -3. $p \leftarrow \lceil lg(n) \rceil$ (\textit{mp\_count\_bits}) \\ -4. for $x$ from $lg(\beta)$ to $p$ do \\ -\hspace{3mm}4.1 If the ($x \mbox{ mod }lg(\beta)$)'th bit of the $\lfloor x / lg(\beta) \rfloor$ of $n$ is zero then return($0$). \\ -5. Return($1$). \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm mp\_reduce\_is\_2k} -\end{figure} - -\textbf{Algorithm mp\_reduce\_is\_2k.} -This algorithm quickly determines if a modulus is of the form required for algorithm mp\_reduce\_2k to function properly. - -EXAM,bn_mp_reduce_is_2k.c - - - -\section{Algorithm Comparison} -So far three very different algorithms for modular reduction have been discussed. Each of the algorithms have their own strengths and weaknesses -that makes having such a selection very useful. The following table sumarizes the three algorithms along with comparisons of work factors. Since -all three algorithms have the restriction that $0 \le x < n^2$ and $n > 1$ those limitations are not included in the table. - -\begin{center} -\begin{small} -\begin{tabular}{|c|c|c|c|c|c|} -\hline \textbf{Method} & \textbf{Work Required} & \textbf{Limitations} & \textbf{$m = 8$} & \textbf{$m = 32$} & \textbf{$m = 64$} \\ -\hline Barrett & $m^2 + 2m - 1$ & None & $79$ & $1087$ & $4223$ \\ -\hline Montgomery & $m^2 + m$ & $n$ must be odd & $72$ & $1056$ & $4160$ \\ -\hline D.R. & $2m$ & $n = \beta^m - k$ & $16$ & $64$ & $128$ \\ -\hline -\end{tabular} -\end{small} -\end{center} - -In theory Montgomery and Barrett reductions would require roughly the same amount of time to complete. However, in practice since Montgomery -reduction can be written as a single function with the Comba technique it is much faster. Barrett reduction suffers from the overhead of -calling the half precision multipliers, addition and division by $\beta$ algorithms. - -For almost every cryptographic algorithm Montgomery reduction is the algorithm of choice. The one set of algorithms where Diminished Radix reduction truly -shines are based on the discrete logarithm problem such as Diffie-Hellman \cite{DH} and ElGamal \cite{ELGAMAL}. In these algorithms -primes of the form $\beta^m - k$ can be found and shared amongst users. These primes will allow the Diminished Radix algorithm to be used in -modular exponentiation to greatly speed up the operation. - - - -\section*{Exercises} -\begin{tabular}{cl} -$\left [ 3 \right ]$ & Prove that the ``trick'' in algorithm mp\_montgomery\_setup actually \\ - & calculates the correct value of $\rho$. \\ - & \\ -$\left [ 2 \right ]$ & Devise an algorithm to reduce modulo $n + k$ for small $k$ quickly. \\ - & \\ -$\left [ 4 \right ]$ & Prove that the pseudo-code algorithm ``Diminished Radix Reduction'' \\ - & (\textit{figure~\ref{fig:DR}}) terminates. Also prove the probability that it will \\ - & terminate within $1 \le k \le 10$ iterations. \\ - & \\ -\end{tabular} - - -\chapter{Exponentiation} -Exponentiation is the operation of raising one variable to the power of another, for example, $a^b$. A variant of exponentiation, computed -in a finite field or ring, is called modular exponentiation. This latter style of operation is typically used in public key -cryptosystems such as RSA and Diffie-Hellman. The ability to quickly compute modular exponentiations is of great benefit to any -such cryptosystem and many methods have been sought to speed it up. - -\section{Exponentiation Basics} -A trivial algorithm would simply multiply $a$ against itself $b - 1$ times to compute the exponentiation desired. However, as $b$ grows in size -the number of multiplications becomes prohibitive. Imagine what would happen if $b$ $\approx$ $2^{1024}$ as is the case when computing an RSA signature -with a $1024$-bit key. Such a calculation could never be completed as it would take simply far too long. - -Fortunately there is a very simple algorithm based on the laws of exponents. Recall that $lg_a(a^b) = b$ and that $lg_a(a^ba^c) = b + c$ which -are two trivial relationships between the base and the exponent. Let $b_i$ represent the $i$'th bit of $b$ starting from the least -significant bit. If $b$ is a $k$-bit integer than the following equation is true. - -\begin{equation} -a^b = \prod_{i=0}^{k-1} a^{2^i \cdot b_i} -\end{equation} - -By taking the base $a$ logarithm of both sides of the equation the following equation is the result. - -\begin{equation} -b = \sum_{i=0}^{k-1}2^i \cdot b_i -\end{equation} - -The term $a^{2^i}$ can be found from the $i - 1$'th term by squaring the term since $\left ( a^{2^i} \right )^2$ is equal to -$a^{2^{i+1}}$. This observation forms the basis of essentially all fast exponentiation algorithms. It requires $k$ squarings and on average -$k \over 2$ multiplications to compute the result. This is indeed quite an improvement over simply multiplying by $a$ a total of $b-1$ times. - -While this current method is a considerable speed up there are further improvements to be made. For example, the $a^{2^i}$ term does not need to -be computed in an auxilary variable. Consider the following equivalent algorithm. - -\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{Left to Right Exponentiation}. \\ -\textbf{Input}. Integer $a$, $b$ and $k$ \\ -\textbf{Output}. $c = a^b$ \\ -\hline \\ -1. $c \leftarrow 1$ \\ -2. for $i$ from $k - 1$ to $0$ do \\ -\hspace{3mm}2.1 $c \leftarrow c^2$ \\ -\hspace{3mm}2.2 $c \leftarrow c \cdot a^{b_i}$ \\ -3. Return $c$. \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Left to Right Exponentiation} -\label{fig:LTOR} -\end{figure} - -This algorithm starts from the most significant bit and works towards the least significant bit. When the $i$'th bit of $b$ is set $a$ is -multiplied against the current product. In each iteration the product is squared which doubles the exponent of the individual terms of the -product. - -For example, let $b = 101100_2 \equiv 44_{10}$. The following chart demonstrates the actions of the algorithm. - -\newpage\begin{figure} -\begin{center} -\begin{tabular}{|c|c|} -\hline \textbf{Value of $i$} & \textbf{Value of $c$} \\ -\hline - & $1$ \\ -\hline $5$ & $a$ \\ -\hline $4$ & $a^2$ \\ -\hline $3$ & $a^4 \cdot a$ \\ -\hline $2$ & $a^8 \cdot a^2 \cdot a$ \\ -\hline $1$ & $a^{16} \cdot a^4 \cdot a^2$ \\ -\hline $0$ & $a^{32} \cdot a^8 \cdot a^4$ \\ -\hline -\end{tabular} -\end{center} -\caption{Example of Left to Right Exponentiation} -\end{figure} - -When the product $a^{32} \cdot a^8 \cdot a^4$ is simplified it is equal $a^{44}$ which is the desired exponentiation. This particular algorithm is -called ``Left to Right'' because it reads the exponent in that order. All of the exponentiation algorithms that will be presented are of this nature. - -\subsection{Single Digit Exponentiation} -The first algorithm in the series of exponentiation algorithms will be an unbounded algorithm where the exponent is a single digit. It is intended -to be used when a small power of an input is required (\textit{e.g. $a^5$}). It is faster than simply multiplying $b - 1$ times for all values of -$b$ that are greater than three. - -\newpage\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_expt\_d}. \\ -\textbf{Input}. mp\_int $a$ and mp\_digit $b$ \\ -\textbf{Output}. $c = a^b$ \\ -\hline \\ -1. $g \leftarrow a$ (\textit{mp\_init\_copy}) \\ -2. $c \leftarrow 1$ (\textit{mp\_set}) \\ -3. for $x$ from 1 to $lg(\beta)$ do \\ -\hspace{3mm}3.1 $c \leftarrow c^2$ (\textit{mp\_sqr}) \\ -\hspace{3mm}3.2 If $b$ AND $2^{lg(\beta) - 1} \ne 0$ then \\ -\hspace{6mm}3.2.1 $c \leftarrow c \cdot g$ (\textit{mp\_mul}) \\ -\hspace{3mm}3.3 $b \leftarrow b << 1$ \\ -4. Clear $g$. \\ -5. Return(\textit{MP\_OKAY}). \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm mp\_expt\_d} -\end{figure} - -\textbf{Algorithm mp\_expt\_d.} -This algorithm computes the value of $a$ raised to the power of a single digit $b$. It uses the left to right exponentiation algorithm to -quickly compute the exponentiation. It is loosely based on algorithm 14.79 of HAC \cite[pp. 615]{HAC} with the difference that the -exponent is a fixed width. - -A copy of $a$ is made first to allow destination variable $c$ be the same as the source variable $a$. The result is set to the initial value of -$1$ in the subsequent step. - -Inside the loop the exponent is read from the most significant bit first down to the least significant bit. First $c$ is invariably squared -on step 3.1. In the following step if the most significant bit of $b$ is one the copy of $a$ is multiplied against $c$. The value -of $b$ is shifted left one bit to make the next bit down from the most signficant bit the new most significant bit. In effect each -iteration of the loop moves the bits of the exponent $b$ upwards to the most significant location. - -EXAM,bn_mp_expt_d.c - -Line @29,mp_set@ sets the initial value of the result to $1$. Next the loop on line @31,for@ steps through each bit of the exponent starting from -the most significant down towards the least significant. The invariant squaring operation placed on line @333,mp_sqr@ is performed first. After -the squaring the result $c$ is multiplied by the base $g$ if and only if the most significant bit of the exponent is set. The shift on line -@47,<<@ moves all of the bits of the exponent upwards towards the most significant location. - -\section{$k$-ary Exponentiation} -When calculating an exponentiation the most time consuming bottleneck is the multiplications which are in general a small factor -slower than squaring. Recall from the previous algorithm that $b_{i}$ refers to the $i$'th bit of the exponent $b$. Suppose instead it referred to -the $i$'th $k$-bit digit of the exponent of $b$. For $k = 1$ the definitions are synonymous and for $k > 1$ algorithm~\ref{fig:KARY} -computes the same exponentiation. A group of $k$ bits from the exponent is called a \textit{window}. That is it is a small window on only a -portion of the entire exponent. Consider the following modification to the basic left to right exponentiation algorithm. - -\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{$k$-ary Exponentiation}. \\ -\textbf{Input}. Integer $a$, $b$, $k$ and $t$ \\ -\textbf{Output}. $c = a^b$ \\ -\hline \\ -1. $c \leftarrow 1$ \\ -2. for $i$ from $t - 1$ to $0$ do \\ -\hspace{3mm}2.1 $c \leftarrow c^{2^k} $ \\ -\hspace{3mm}2.2 Extract the $i$'th $k$-bit word from $b$ and store it in $g$. \\ -\hspace{3mm}2.3 $c \leftarrow c \cdot a^g$ \\ -3. Return $c$. \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{$k$-ary Exponentiation} -\label{fig:KARY} -\end{figure} - -The squaring on step 2.1 can be calculated by squaring the value $c$ successively $k$ times. If the values of $a^g$ for $0 < g < 2^k$ have been -precomputed this algorithm requires only $t$ multiplications and $tk$ squarings. The table can be generated with $2^{k - 1} - 1$ squarings and -$2^{k - 1} + 1$ multiplications. This algorithm assumes that the number of bits in the exponent is evenly divisible by $k$. -However, when it is not the remaining $0 < x \le k - 1$ bits can be handled with algorithm~\ref{fig:LTOR}. - -Suppose $k = 4$ and $t = 100$. This modified algorithm will require $109$ multiplications and $408$ squarings to compute the exponentiation. The -original algorithm would on average have required $200$ multiplications and $400$ squrings to compute the same value. The total number of squarings -has increased slightly but the number of multiplications has nearly halved. - -\subsection{Optimal Values of $k$} -An optimal value of $k$ will minimize $2^{k} + \lceil n / k \rceil + n - 1$ for a fixed number of bits in the exponent $n$. The simplest -approach is to brute force search amongst the values $k = 2, 3, \ldots, 8$ for the lowest result. Table~\ref{fig:OPTK} lists optimal values of $k$ -for various exponent sizes and compares the number of multiplication and squarings required against algorithm~\ref{fig:LTOR}. - -\begin{figure}[here] -\begin{center} -\begin{small} -\begin{tabular}{|c|c|c|c|c|c|} -\hline \textbf{Exponent (bits)} & \textbf{Optimal $k$} & \textbf{Work at $k$} & \textbf{Work with ~\ref{fig:LTOR}} \\ -\hline $16$ & $2$ & $27$ & $24$ \\ -\hline $32$ & $3$ & $49$ & $48$ \\ -\hline $64$ & $3$ & $92$ & $96$ \\ -\hline $128$ & $4$ & $175$ & $192$ \\ -\hline $256$ & $4$ & $335$ & $384$ \\ -\hline $512$ & $5$ & $645$ & $768$ \\ -\hline $1024$ & $6$ & $1257$ & $1536$ \\ -\hline $2048$ & $6$ & $2452$ & $3072$ \\ -\hline $4096$ & $7$ & $4808$ & $6144$ \\ -\hline -\end{tabular} -\end{small} -\end{center} -\caption{Optimal Values of $k$ for $k$-ary Exponentiation} -\label{fig:OPTK} -\end{figure} - -\subsection{Sliding-Window Exponentiation} -A simple modification to the previous algorithm is only generate the upper half of the table in the range $2^{k-1} \le g < 2^k$. Essentially -this is a table for all values of $g$ where the most significant bit of $g$ is a one. However, in order for this to be allowed in the -algorithm values of $g$ in the range $0 \le g < 2^{k-1}$ must be avoided. - -Table~\ref{fig:OPTK2} lists optimal values of $k$ for various exponent sizes and compares the work required against algorithm~\ref{fig:KARY}. - -\begin{figure}[here] -\begin{center} -\begin{small} -\begin{tabular}{|c|c|c|c|c|c|} -\hline \textbf{Exponent (bits)} & \textbf{Optimal $k$} & \textbf{Work at $k$} & \textbf{Work with ~\ref{fig:KARY}} \\ -\hline $16$ & $3$ & $24$ & $27$ \\ -\hline $32$ & $3$ & $45$ & $49$ \\ -\hline $64$ & $4$ & $87$ & $92$ \\ -\hline $128$ & $4$ & $167$ & $175$ \\ -\hline $256$ & $5$ & $322$ & $335$ \\ -\hline $512$ & $6$ & $628$ & $645$ \\ -\hline $1024$ & $6$ & $1225$ & $1257$ \\ -\hline $2048$ & $7$ & $2403$ & $2452$ \\ -\hline $4096$ & $8$ & $4735$ & $4808$ \\ -\hline -\end{tabular} -\end{small} -\end{center} -\caption{Optimal Values of $k$ for Sliding Window Exponentiation} -\label{fig:OPTK2} -\end{figure} - -\newpage\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{Sliding Window $k$-ary Exponentiation}. \\ -\textbf{Input}. Integer $a$, $b$, $k$ and $t$ \\ -\textbf{Output}. $c = a^b$ \\ -\hline \\ -1. $c \leftarrow 1$ \\ -2. for $i$ from $t - 1$ to $0$ do \\ -\hspace{3mm}2.1 If the $i$'th bit of $b$ is a zero then \\ -\hspace{6mm}2.1.1 $c \leftarrow c^2$ \\ -\hspace{3mm}2.2 else do \\ -\hspace{6mm}2.2.1 $c \leftarrow c^{2^k}$ \\ -\hspace{6mm}2.2.2 Extract the $k$ bits from $(b_{i}b_{i-1}\ldots b_{i-(k-1)})$ and store it in $g$. \\ -\hspace{6mm}2.2.3 $c \leftarrow c \cdot a^g$ \\ -\hspace{6mm}2.2.4 $i \leftarrow i - k$ \\ -3. Return $c$. \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Sliding Window $k$-ary Exponentiation} -\end{figure} - -Similar to the previous algorithm this algorithm must have a special handler when fewer than $k$ bits are left in the exponent. While this -algorithm requires the same number of squarings it can potentially have fewer multiplications. The pre-computed table $a^g$ is also half -the size as the previous table. - -Consider the exponent $b = 111101011001000_2 \equiv 31432_{10}$ with $k = 3$ using both algorithms. The first algorithm will divide the exponent up as -the following five $3$-bit words $b \equiv \left ( 111, 101, 011, 001, 000 \right )_{2}$. The second algorithm will break the -exponent as $b \equiv \left ( 111, 101, 0, 110, 0, 100, 0 \right )_{2}$. The single digit $0$ in the second representation are where -a single squaring took place instead of a squaring and multiplication. In total the first method requires $10$ multiplications and $18$ -squarings. The second method requires $8$ multiplications and $18$ squarings. - -In general the sliding window method is never slower than the generic $k$-ary method and often it is slightly faster. - -\section{Modular Exponentiation} - -Modular exponentiation is essentially computing the power of a base within a finite field or ring. For example, computing -$d \equiv a^b \mbox{ (mod }c\mbox{)}$ is a modular exponentiation. Instead of first computing $a^b$ and then reducing it -modulo $c$ the intermediate result is reduced modulo $c$ after every squaring or multiplication operation. - -This guarantees that any intermediate result is bounded by $0 \le d \le c^2 - 2c + 1$ and can be reduced modulo $c$ quickly using -one of the algorithms presented in ~REDUCTION~. - -Before the actual modular exponentiation algorithm can be written a wrapper algorithm must be written first. This algorithm -will allow the exponent $b$ to be negative which is computed as $c \equiv \left (1 / a \right )^{\vert b \vert} \mbox{(mod }d\mbox{)}$. The -value of $(1/a) \mbox{ mod }c$ is computed using the modular inverse (\textit{see \ref{sec;modinv}}). If no inverse exists the algorithm -terminates with an error. - -\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_exptmod}. \\ -\textbf{Input}. mp\_int $a$, $b$ and $c$ \\ -\textbf{Output}. $y \equiv g^x \mbox{ (mod }p\mbox{)}$ \\ -\hline \\ -1. If $c.sign = MP\_NEG$ return(\textit{MP\_VAL}). \\ -2. If $b.sign = MP\_NEG$ then \\ -\hspace{3mm}2.1 $g' \leftarrow g^{-1} \mbox{ (mod }c\mbox{)}$ \\ -\hspace{3mm}2.2 $x' \leftarrow \vert x \vert$ \\ -\hspace{3mm}2.3 Compute $d \equiv g'^{x'} \mbox{ (mod }c\mbox{)}$ via recursion. \\ -3. if $p$ is odd \textbf{OR} $p$ is a D.R. modulus then \\ -\hspace{3mm}3.1 Compute $y \equiv g^{x} \mbox{ (mod }p\mbox{)}$ via algorithm mp\_exptmod\_fast. \\ -4. else \\ -\hspace{3mm}4.1 Compute $y \equiv g^{x} \mbox{ (mod }p\mbox{)}$ via algorithm s\_mp\_exptmod. \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm mp\_exptmod} -\end{figure} - -\textbf{Algorithm mp\_exptmod.} -The first algorithm which actually performs modular exponentiation is algorithm s\_mp\_exptmod. It is a sliding window $k$-ary algorithm -which uses Barrett reduction to reduce the product modulo $p$. The second algorithm mp\_exptmod\_fast performs the same operation -except it uses either Montgomery or Diminished Radix reduction. The two latter reduction algorithms are clumped in the same exponentiation -algorithm since their arguments are essentially the same (\textit{two mp\_ints and one mp\_digit}). - -EXAM,bn_mp_exptmod.c - -In order to keep the algorithms in a known state the first step on line @29,if@ is to reject any negative modulus as input. If the exponent is -negative the algorithm tries to perform a modular exponentiation with the modular inverse of the base $G$. The temporary variable $tmpG$ is assigned -the modular inverse of $G$ and $tmpX$ is assigned the absolute value of $X$. The algorithm will recuse with these new values with a positive -exponent. - -If the exponent is positive the algorithm resumes the exponentiation. Line @63,dr_@ determines if the modulus is of the restricted Diminished Radix -form. If it is not line @65,reduce@ attempts to determine if it is of a unrestricted Diminished Radix form. The integer $dr$ will take on one -of three values. - -\begin{enumerate} -\item $dr = 0$ means that the modulus is not of either restricted or unrestricted Diminished Radix form. -\item $dr = 1$ means that the modulus is of restricted Diminished Radix form. -\item $dr = 2$ means that the modulus is of unrestricted Diminished Radix form. -\end{enumerate} - -Line @69,if@ determines if the fast modular exponentiation algorithm can be used. It is allowed if $dr \ne 0$ or if the modulus is odd. Otherwise, -the slower s\_mp\_exptmod algorithm is used which uses Barrett reduction. - -\subsection{Barrett Modular Exponentiation} - -\newpage\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{s\_mp\_exptmod}. \\ -\textbf{Input}. mp\_int $a$, $b$ and $c$ \\ -\textbf{Output}. $y \equiv g^x \mbox{ (mod }p\mbox{)}$ \\ -\hline \\ -1. $k \leftarrow lg(x)$ \\ -2. $winsize \leftarrow \left \lbrace \begin{array}{ll} - 2 & \mbox{if }k \le 7 \\ - 3 & \mbox{if }7 < k \le 36 \\ - 4 & \mbox{if }36 < k \le 140 \\ - 5 & \mbox{if }140 < k \le 450 \\ - 6 & \mbox{if }450 < k \le 1303 \\ - 7 & \mbox{if }1303 < k \le 3529 \\ - 8 & \mbox{if }3529 < k \\ - \end{array} \right .$ \\ -3. Initialize $2^{winsize}$ mp\_ints in an array named $M$ and one mp\_int named $\mu$ \\ -4. Calculate the $\mu$ required for Barrett Reduction (\textit{mp\_reduce\_setup}). \\ -5. $M_1 \leftarrow g \mbox{ (mod }p\mbox{)}$ \\ -\\ -Setup the table of small powers of $g$. First find $g^{2^{winsize}}$ and then all multiples of it. \\ -6. $k \leftarrow 2^{winsize - 1}$ \\ -7. $M_{k} \leftarrow M_1$ \\ -8. for $ix$ from 0 to $winsize - 2$ do \\ -\hspace{3mm}8.1 $M_k \leftarrow \left ( M_k \right )^2$ (\textit{mp\_sqr}) \\ -\hspace{3mm}8.2 $M_k \leftarrow M_k \mbox{ (mod }p\mbox{)}$ (\textit{mp\_reduce}) \\ -9. for $ix$ from $2^{winsize - 1} + 1$ to $2^{winsize} - 1$ do \\ -\hspace{3mm}9.1 $M_{ix} \leftarrow M_{ix - 1} \cdot M_{1}$ (\textit{mp\_mul}) \\ -\hspace{3mm}9.2 $M_{ix} \leftarrow M_{ix} \mbox{ (mod }p\mbox{)}$ (\textit{mp\_reduce}) \\ -10. $res \leftarrow 1$ \\ -\\ -Start Sliding Window. \\ -11. $mode \leftarrow 0, bitcnt \leftarrow 1, buf \leftarrow 0, digidx \leftarrow x.used - 1, bitcpy \leftarrow 0, bitbuf \leftarrow 0$ \\ -12. Loop \\ -\hspace{3mm}12.1 $bitcnt \leftarrow bitcnt - 1$ \\ -\hspace{3mm}12.2 If $bitcnt = 0$ then do \\ -\hspace{6mm}12.2.1 If $digidx = -1$ goto step 13. \\ -\hspace{6mm}12.2.2 $buf \leftarrow x_{digidx}$ \\ -\hspace{6mm}12.2.3 $digidx \leftarrow digidx - 1$ \\ -\hspace{6mm}12.2.4 $bitcnt \leftarrow lg(\beta)$ \\ -Continued on next page. \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm s\_mp\_exptmod} -\end{figure} - -\newpage\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{s\_mp\_exptmod} (\textit{continued}). \\ -\textbf{Input}. mp\_int $a$, $b$ and $c$ \\ -\textbf{Output}. $y \equiv g^x \mbox{ (mod }p\mbox{)}$ \\ -\hline \\ -\hspace{3mm}12.3 $y \leftarrow (buf >> (lg(\beta) - 1))$ AND $1$ \\ -\hspace{3mm}12.4 $buf \leftarrow buf << 1$ \\ -\hspace{3mm}12.5 if $mode = 0$ and $y = 0$ then goto step 12. \\ -\hspace{3mm}12.6 if $mode = 1$ and $y = 0$ then do \\ -\hspace{6mm}12.6.1 $res \leftarrow res^2$ \\ -\hspace{6mm}12.6.2 $res \leftarrow res \mbox{ (mod }p\mbox{)}$ \\ -\hspace{6mm}12.6.3 Goto step 12. \\ -\hspace{3mm}12.7 $bitcpy \leftarrow bitcpy + 1$ \\ -\hspace{3mm}12.8 $bitbuf \leftarrow bitbuf + (y << (winsize - bitcpy))$ \\ -\hspace{3mm}12.9 $mode \leftarrow 2$ \\ -\hspace{3mm}12.10 If $bitcpy = winsize$ then do \\ -\hspace{6mm}Window is full so perform the squarings and single multiplication. \\ -\hspace{6mm}12.10.1 for $ix$ from $0$ to $winsize -1$ do \\ -\hspace{9mm}12.10.1.1 $res \leftarrow res^2$ \\ -\hspace{9mm}12.10.1.2 $res \leftarrow res \mbox{ (mod }p\mbox{)}$ \\ -\hspace{6mm}12.10.2 $res \leftarrow res \cdot M_{bitbuf}$ \\ -\hspace{6mm}12.10.3 $res \leftarrow res \mbox{ (mod }p\mbox{)}$ \\ -\hspace{6mm}Reset the window. \\ -\hspace{6mm}12.10.4 $bitcpy \leftarrow 0, bitbuf \leftarrow 0, mode \leftarrow 1$ \\ -\\ -No more windows left. Check for residual bits of exponent. \\ -13. If $mode = 2$ and $bitcpy > 0$ then do \\ -\hspace{3mm}13.1 for $ix$ form $0$ to $bitcpy - 1$ do \\ -\hspace{6mm}13.1.1 $res \leftarrow res^2$ \\ -\hspace{6mm}13.1.2 $res \leftarrow res \mbox{ (mod }p\mbox{)}$ \\ -\hspace{6mm}13.1.3 $bitbuf \leftarrow bitbuf << 1$ \\ -\hspace{6mm}13.1.4 If $bitbuf$ AND $2^{winsize} \ne 0$ then do \\ -\hspace{9mm}13.1.4.1 $res \leftarrow res \cdot M_{1}$ \\ -\hspace{9mm}13.1.4.2 $res \leftarrow res \mbox{ (mod }p\mbox{)}$ \\ -14. $y \leftarrow res$ \\ -15. Clear $res$, $mu$ and the $M$ array. \\ -16. Return(\textit{MP\_OKAY}). \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm s\_mp\_exptmod (continued)} -\end{figure} - -\textbf{Algorithm s\_mp\_exptmod.} -This algorithm computes the $x$'th power of $g$ modulo $p$ and stores the result in $y$. It takes advantage of the Barrett reduction -algorithm to keep the product small throughout the algorithm. - -The first two steps determine the optimal window size based on the number of bits in the exponent. The larger the exponent the -larger the window size becomes. After a window size $winsize$ has been chosen an array of $2^{winsize}$ mp\_int variables is allocated. This -table will hold the values of $g^x \mbox{ (mod }p\mbox{)}$ for $2^{winsize - 1} \le x < 2^{winsize}$. - -After the table is allocated the first power of $g$ is found. Since $g \ge p$ is allowed it must be first reduced modulo $p$ to make -the rest of the algorithm more efficient. The first element of the table at $2^{winsize - 1}$ is found by squaring $M_1$ successively $winsize - 2$ -times. The rest of the table elements are found by multiplying the previous element by $M_1$ modulo $p$. - -Now that the table is available the sliding window may begin. The following list describes the functions of all the variables in the window. -\begin{enumerate} -\item The variable $mode$ dictates how the bits of the exponent are interpreted. -\begin{enumerate} - \item When $mode = 0$ the bits are ignored since no non-zero bit of the exponent has been seen yet. For example, if the exponent were simply - $1$ then there would be $lg(\beta) - 1$ zero bits before the first non-zero bit. In this case bits are ignored until a non-zero bit is found. - \item When $mode = 1$ a non-zero bit has been seen before and a new $winsize$-bit window has not been formed yet. In this mode leading $0$ bits - are read and a single squaring is performed. If a non-zero bit is read a new window is created. - \item When $mode = 2$ the algorithm is in the middle of forming a window and new bits are appended to the window from the most significant bit - downwards. -\end{enumerate} -\item The variable $bitcnt$ indicates how many bits are left in the current digit of the exponent left to be read. When it reaches zero a new digit - is fetched from the exponent. -\item The variable $buf$ holds the currently read digit of the exponent. -\item The variable $digidx$ is an index into the exponents digits. It starts at the leading digit $x.used - 1$ and moves towards the trailing digit. -\item The variable $bitcpy$ indicates how many bits are in the currently formed window. When it reaches $winsize$ the window is flushed and - the appropriate operations performed. -\item The variable $bitbuf$ holds the current bits of the window being formed. -\end{enumerate} - -All of step 12 is the window processing loop. It will iterate while there are digits available form the exponent to read. The first step -inside this loop is to extract a new digit if no more bits are available in the current digit. If there are no bits left a new digit is -read and if there are no digits left than the loop terminates. - -After a digit is made available step 12.3 will extract the most significant bit of the current digit and move all other bits in the digit -upwards. In effect the digit is read from most significant bit to least significant bit and since the digits are read from leading to -trailing edges the entire exponent is read from most significant bit to least significant bit. - -At step 12.5 if the $mode$ and currently extracted bit $y$ are both zero the bit is ignored and the next bit is read. This prevents the -algorithm from having to perform trivial squaring and reduction operations before the first non-zero bit is read. Step 12.6 and 12.7-10 handle -the two cases of $mode = 1$ and $mode = 2$ respectively. - -FIGU,expt_state,Sliding Window State Diagram - -By step 13 there are no more digits left in the exponent. However, there may be partial bits in the window left. If $mode = 2$ then -a Left-to-Right algorithm is used to process the remaining few bits. - -EXAM,bn_s_mp_exptmod.c - -Lines @31,if@ through @45,}@ determine the optimal window size based on the length of the exponent in bits. The window divisions are sorted -from smallest to greatest so that in each \textbf{if} statement only one condition must be tested. For example, by the \textbf{if} statement -on line @37,if@ the value of $x$ is already known to be greater than $140$. - -The conditional piece of code beginning on line @42,ifdef@ allows the window size to be restricted to five bits. This logic is used to ensure -the table of precomputed powers of $G$ remains relatively small. - -The for loop on line @60,for@ initializes the $M$ array while lines @71,mp_init@ and @75,mp_reduce@ through @85,}@ initialize the reduction -function that will be used for this modulus. - --- More later. - -\section{Quick Power of Two} -Calculating $b = 2^a$ can be performed much quicker than with any of the previous algorithms. Recall that a logical shift left $m << k$ is -equivalent to $m \cdot 2^k$. By this logic when $m = 1$ a quick power of two can be achieved. - -\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_2expt}. \\ -\textbf{Input}. integer $b$ \\ -\textbf{Output}. $a \leftarrow 2^b$ \\ -\hline \\ -1. $a \leftarrow 0$ \\ -2. If $a.alloc < \lfloor b / lg(\beta) \rfloor + 1$ then grow $a$ appropriately. \\ -3. $a.used \leftarrow \lfloor b / lg(\beta) \rfloor + 1$ \\ -4. $a_{\lfloor b / lg(\beta) \rfloor} \leftarrow 1 << (b \mbox{ mod } lg(\beta))$ \\ -5. Return(\textit{MP\_OKAY}). \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm mp\_2expt} -\end{figure} - -\textbf{Algorithm mp\_2expt.} - -EXAM,bn_mp_2expt.c - -\chapter{Higher Level Algorithms} - -This chapter discusses the various higher level algorithms that are required to complete a well rounded multiple precision integer package. These -routines are less performance oriented than the algorithms of chapters five, six and seven but are no less important. - -The first section describes a method of integer division with remainder that is universally well known. It provides the signed division logic -for the package. The subsequent section discusses a set of algorithms which allow a single digit to be the 2nd operand for a variety of operations. -These algorithms serve mostly to simplify other algorithms where small constants are required. The last two sections discuss how to manipulate -various representations of integers. For example, converting from an mp\_int to a string of character. - -\section{Integer Division with Remainder} -\label{sec:division} - -Integer division aside from modular exponentiation is the most intensive algorithm to compute. Like addition, subtraction and multiplication -the basis of this algorithm is the long-hand division algorithm taught to school children. Throughout this discussion several common variables -will be used. Let $x$ represent the divisor and $y$ represent the dividend. Let $q$ represent the integer quotient $\lfloor y / x \rfloor$ and -let $r$ represent the remainder $r = y - x \lfloor y / x \rfloor$. The following simple algorithm will be used to start the discussion. - -\newpage\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{Radix-$\beta$ Integer Division}. \\ -\textbf{Input}. integer $x$ and $y$ \\ -\textbf{Output}. $q = \lfloor y/x\rfloor, r = y - xq$ \\ -\hline \\ -1. $q \leftarrow 0$ \\ -2. $n \leftarrow \vert \vert y \vert \vert - \vert \vert x \vert \vert$ \\ -3. for $t$ from $n$ down to $0$ do \\ -\hspace{3mm}3.1 Maximize $k$ such that $kx\beta^t$ is less than or equal to $y$ and $(k + 1)x\beta^t$ is greater. \\ -\hspace{3mm}3.2 $q \leftarrow q + k\beta^t$ \\ -\hspace{3mm}3.3 $y \leftarrow y - kx\beta^t$ \\ -4. $r \leftarrow y$ \\ -5. Return($q, r$) \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm Radix-$\beta$ Integer Division} -\label{fig:raddiv} -\end{figure} - -As children we are taught this very simple algorithm for the case of $\beta = 10$. Almost instinctively several optimizations are taught for which -their reason of existing are never explained. For this example let $y = 5471$ represent the dividend and $x = 23$ represent the divisor. - -To find the first digit of the quotient the value of $k$ must be maximized such that $kx\beta^t$ is less than or equal to $y$ and -simultaneously $(k + 1)x\beta^t$ is greater than $y$. Implicitly $k$ is the maximum value the $t$'th digit of the quotient may have. The habitual method -used to find the maximum is to ``eyeball'' the two numbers, typically only the leading digits and quickly estimate a quotient. By only using leading -digits a much simpler division may be used to form an educated guess at what the value must be. In this case $k = \lfloor 54/23\rfloor = 2$ quickly -arises as a possible solution. Indeed $2x\beta^2 = 4600$ is less than $y = 5471$ and simultaneously $(k + 1)x\beta^2 = 6900$ is larger than $y$. -As a result $k\beta^2$ is added to the quotient which now equals $q = 200$ and $4600$ is subtracted from $y$ to give a remainder of $y = 841$. - -Again this process is repeated to produce the quotient digit $k = 3$ which makes the quotient $q = 200 + 3\beta = 230$ and the remainder -$y = 841 - 3x\beta = 181$. Finally the last iteration of the loop produces $k = 7$ which leads to the quotient $q = 230 + 7 = 237$ and the -remainder $y = 181 - 7x = 20$. The final quotient and remainder found are $q = 237$ and $r = y = 20$ which are indeed correct since -$237 \cdot 23 + 20 = 5471$ is true. - -\subsection{Quotient Estimation} -\label{sec:divest} -As alluded to earlier the quotient digit $k$ can be estimated from only the leading digits of both the divisor and dividend. When $p$ leading -digits are used from both the divisor and dividend to form an estimation the accuracy of the estimation rises as $p$ grows. Technically -speaking the estimation is based on assuming the lower $\vert \vert y \vert \vert - p$ and $\vert \vert x \vert \vert - p$ lower digits of the -dividend and divisor are zero. - -The value of the estimation may off by a few values in either direction and in general is fairly correct. A simplification \cite[pp. 271]{TAOCPV2} -of the estimation technique is to use $t + 1$ digits of the dividend and $t$ digits of the divisor, in particularly when $t = 1$. The estimate -using this technique is never too small. For the following proof let $t = \vert \vert y \vert \vert - 1$ and $s = \vert \vert x \vert \vert - 1$ -represent the most significant digits of the dividend and divisor respectively. - -\textbf{Proof.}\textit{ The quotient $\hat k = \lfloor (y_t\beta + y_{t-1}) / x_s \rfloor$ is greater than or equal to -$k = \lfloor y / (x \cdot \beta^{\vert \vert y \vert \vert - \vert \vert x \vert \vert - 1}) \rfloor$. } -The first obvious case is when $\hat k = \beta - 1$ in which case the proof is concluded since the real quotient cannot be larger. For all other -cases $\hat k = \lfloor (y_t\beta + y_{t-1}) / x_s \rfloor$ and $\hat k x_s \ge y_t\beta + y_{t-1} - x_s + 1$. The latter portion of the inequalility -$-x_s + 1$ arises from the fact that a truncated integer division will give the same quotient for at most $x_s - 1$ values. Next a series of -inequalities will prove the hypothesis. - -\begin{equation} -y - \hat k x \le y - \hat k x_s\beta^s -\end{equation} - -This is trivially true since $x \ge x_s\beta^s$. Next we replace $\hat kx_s\beta^s$ by the previous inequality for $\hat kx_s$. - -\begin{equation} -y - \hat k x \le y_t\beta^t + \ldots + y_0 - (y_t\beta^t + y_{t-1}\beta^{t-1} - x_s\beta^t + \beta^s) -\end{equation} - -By simplifying the previous inequality the following inequality is formed. - -\begin{equation} -y - \hat k x \le y_{t-2}\beta^{t-2} + \ldots + y_0 + x_s\beta^s - \beta^s -\end{equation} - -Subsequently, - -\begin{equation} -y_{t-2}\beta^{t-2} + \ldots + y_0 + x_s\beta^s - \beta^s < x_s\beta^s \le x -\end{equation} - -Which proves that $y - \hat kx \le x$ and by consequence $\hat k \ge k$ which concludes the proof. \textbf{QED} - - -\subsection{Normalized Integers} -For the purposes of division a normalized input is when the divisors leading digit $x_n$ is greater than or equal to $\beta / 2$. By multiplying both -$x$ and $y$ by $j = \lfloor (\beta / 2) / x_n \rfloor$ the quotient remains unchanged and the remainder is simply $j$ times the original -remainder. The purpose of normalization is to ensure the leading digit of the divisor is sufficiently large such that the estimated quotient will -lie in the domain of a single digit. Consider the maximum dividend $(\beta - 1) \cdot \beta + (\beta - 1)$ and the minimum divisor $\beta / 2$. - -\begin{equation} -{{\beta^2 - 1} \over { \beta / 2}} \le 2\beta - {2 \over \beta} -\end{equation} - -At most the quotient approaches $2\beta$, however, in practice this will not occur since that would imply the previous quotient digit was too small. - -\subsection{Radix-$\beta$ Division with Remainder} -\newpage\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_div}. \\ -\textbf{Input}. mp\_int $a, b$ \\ -\textbf{Output}. $c = \lfloor a/b \rfloor$, $d = a - bc$ \\ -\hline \\ -1. If $b = 0$ return(\textit{MP\_VAL}). \\ -2. If $\vert a \vert < \vert b \vert$ then do \\ -\hspace{3mm}2.1 $d \leftarrow a$ \\ -\hspace{3mm}2.2 $c \leftarrow 0$ \\ -\hspace{3mm}2.3 Return(\textit{MP\_OKAY}). \\ -\\ -Setup the quotient to receive the digits. \\ -3. Grow $q$ to $a.used + 2$ digits. \\ -4. $q \leftarrow 0$ \\ -5. $x \leftarrow \vert a \vert , y \leftarrow \vert b \vert$ \\ -6. $sign \leftarrow \left \lbrace \begin{array}{ll} - MP\_ZPOS & \mbox{if }a.sign = b.sign \\ - MP\_NEG & \mbox{otherwise} \\ - \end{array} \right .$ \\ -\\ -Normalize the inputs such that the leading digit of $y$ is greater than or equal to $\beta / 2$. \\ -7. $norm \leftarrow (lg(\beta) - 1) - (\lceil lg(y) \rceil \mbox{ (mod }lg(\beta)\mbox{)})$ \\ -8. $x \leftarrow x \cdot 2^{norm}, y \leftarrow y \cdot 2^{norm}$ \\ -\\ -Find the leading digit of the quotient. \\ -9. $n \leftarrow x.used - 1, t \leftarrow y.used - 1$ \\ -10. $y \leftarrow y \cdot \beta^{n - t}$ \\ -11. While ($x \ge y$) do \\ -\hspace{3mm}11.1 $q_{n - t} \leftarrow q_{n - t} + 1$ \\ -\hspace{3mm}11.2 $x \leftarrow x - y$ \\ -12. $y \leftarrow \lfloor y / \beta^{n-t} \rfloor$ \\ -\\ -Continued on the next page. \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm mp\_div} -\end{figure} - -\newpage\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_div} (continued). \\ -\textbf{Input}. mp\_int $a, b$ \\ -\textbf{Output}. $c = \lfloor a/b \rfloor$, $d = a - bc$ \\ -\hline \\ -Now find the remainder fo the digits. \\ -13. for $i$ from $n$ down to $(t + 1)$ do \\ -\hspace{3mm}13.1 If $i > x.used$ then jump to the next iteration of this loop. \\ -\hspace{3mm}13.2 If $x_{i} = y_{t}$ then \\ -\hspace{6mm}13.2.1 $q_{i - t - 1} \leftarrow \beta - 1$ \\ -\hspace{3mm}13.3 else \\ -\hspace{6mm}13.3.1 $\hat r \leftarrow x_{i} \cdot \beta + x_{i - 1}$ \\ -\hspace{6mm}13.3.2 $\hat r \leftarrow \lfloor \hat r / y_{t} \rfloor$ \\ -\hspace{6mm}13.3.3 $q_{i - t - 1} \leftarrow \hat r$ \\ -\hspace{3mm}13.4 $q_{i - t - 1} \leftarrow q_{i - t - 1} + 1$ \\ -\\ -Fixup quotient estimation. \\ -\hspace{3mm}13.5 Loop \\ -\hspace{6mm}13.5.1 $q_{i - t - 1} \leftarrow q_{i - t - 1} - 1$ \\ -\hspace{6mm}13.5.2 t$1 \leftarrow 0$ \\ -\hspace{6mm}13.5.3 t$1_0 \leftarrow y_{t - 1}, $ t$1_1 \leftarrow y_t,$ t$1.used \leftarrow 2$ \\ -\hspace{6mm}13.5.4 $t1 \leftarrow t1 \cdot q_{i - t - 1}$ \\ -\hspace{6mm}13.5.5 t$2_0 \leftarrow x_{i - 2}, $ t$2_1 \leftarrow x_{i - 1}, $ t$2_2 \leftarrow x_i, $ t$2.used \leftarrow 3$ \\ -\hspace{6mm}13.5.6 If $\vert t1 \vert > \vert t2 \vert$ then goto step 13.5. \\ -\hspace{3mm}13.6 t$1 \leftarrow y \cdot q_{i - t - 1}$ \\ -\hspace{3mm}13.7 t$1 \leftarrow $ t$1 \cdot \beta^{i - t - 1}$ \\ -\hspace{3mm}13.8 $x \leftarrow x - $ t$1$ \\ -\hspace{3mm}13.9 If $x.sign = MP\_NEG$ then \\ -\hspace{6mm}13.10 t$1 \leftarrow y$ \\ -\hspace{6mm}13.11 t$1 \leftarrow $ t$1 \cdot \beta^{i - t - 1}$ \\ -\hspace{6mm}13.12 $x \leftarrow x + $ t$1$ \\ -\hspace{6mm}13.13 $q_{i - t - 1} \leftarrow q_{i - t - 1} - 1$ \\ -\\ -Finalize the result. \\ -14. Clamp excess digits of $q$ \\ -15. $c \leftarrow q, c.sign \leftarrow sign$ \\ -16. $x.sign \leftarrow a.sign$ \\ -17. $d \leftarrow \lfloor x / 2^{norm} \rfloor$ \\ -18. Return(\textit{MP\_OKAY}). \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm mp\_div (continued)} -\end{figure} -\textbf{Algorithm mp\_div.} -This algorithm will calculate quotient and remainder from an integer division given a dividend and divisor. The algorithm is a signed -division and will produce a fully qualified quotient and remainder. - -First the divisor $b$ must be non-zero which is enforced in step one. If the divisor is larger than the dividend than the quotient is implicitly -zero and the remainder is the dividend. - -After the first two trivial cases of inputs are handled the variable $q$ is setup to receive the digits of the quotient. Two unsigned copies of the -divisor $y$ and dividend $x$ are made as well. The core of the division algorithm is an unsigned division and will only work if the values are -positive. Now the two values $x$ and $y$ must be normalized such that the leading digit of $y$ is greater than or equal to $\beta / 2$. -This is performed by shifting both to the left by enough bits to get the desired normalization. - -At this point the division algorithm can begin producing digits of the quotient. Recall that maximum value of the estimation used is -$2\beta - {2 \over \beta}$ which means that a digit of the quotient must be first produced by another means. In this case $y$ is shifted -to the left (\textit{step ten}) so that it has the same number of digits as $x$. The loop on step eleven will subtract multiples of the -shifted copy of $y$ until $x$ is smaller. Since the leading digit of $y$ is greater than or equal to $\beta/2$ this loop will iterate at most two -times to produce the desired leading digit of the quotient. - -Now the remainder of the digits can be produced. The equation $\hat q = \lfloor {{x_i \beta + x_{i-1}}\over y_t} \rfloor$ is used to fairly -accurately approximate the true quotient digit. The estimation can in theory produce an estimation as high as $2\beta - {2 \over \beta}$ but by -induction the upper quotient digit is correct (\textit{as established on step eleven}) and the estimate must be less than $\beta$. - -Recall from section~\ref{sec:divest} that the estimation is never too low but may be too high. The next step of the estimation process is -to refine the estimation. The loop on step 13.5 uses $x_i\beta^2 + x_{i-1}\beta + x_{i-2}$ and $q_{i - t - 1}(y_t\beta + y_{t-1})$ as a higher -order approximation to adjust the quotient digit. - -After both phases of estimation the quotient digit may still be off by a value of one\footnote{This is similar to the error introduced -by optimizing Barrett reduction.}. Steps 13.6 and 13.7 subtract the multiple of the divisor from the dividend (\textit{Similar to step 3.3 of -algorithm~\ref{fig:raddiv}} and then subsequently add a multiple of the divisor if the quotient was too large. - -Now that the quotient has been determine finializing the result is a matter of clamping the quotient, fixing the sizes and de-normalizing the -remainder. An important aspect of this algorithm seemingly overlooked in other descriptions such as that of Algorithm 14.20 HAC \cite[pp. 598]{HAC} -is that when the estimations are being made (\textit{inside the loop on step 13.5}) that the digits $y_{t-1}$, $x_{i-2}$ and $x_{i-1}$ may lie -outside their respective boundaries. For example, if $t = 0$ or $i \le 1$ then the digits would be undefined. In those cases the digits should -respectively be replaced with a zero. - -EXAM,bn_mp_div.c - -The implementation of this algorithm differs slightly from the pseudo code presented previously. In this algorithm either of the quotient $c$ or -remainder $d$ may be passed as a \textbf{NULL} pointer which indicates their value is not desired. For example, the C code to call the division -algorithm with only the quotient is - -\begin{verbatim} -mp_div(&a, &b, &c, NULL); /* c = [a/b] */ -\end{verbatim} - -Lines @108,if@ and @113,if@ handle the two trivial cases of inputs which are division by zero and dividend smaller than the divisor -respectively. After the two trivial cases all of the temporary variables are initialized. Line @147,neg@ determines the sign of -the quotient and line @148,sign@ ensures that both $x$ and $y$ are positive. - -The number of bits in the leading digit is calculated on line @151,norm@. Implictly an mp\_int with $r$ digits will require $lg(\beta)(r-1) + k$ bits -of precision which when reduced modulo $lg(\beta)$ produces the value of $k$. In this case $k$ is the number of bits in the leading digit which is -exactly what is required. For the algorithm to operate $k$ must equal $lg(\beta) - 1$ and when it does not the inputs must be normalized by shifting -them to the left by $lg(\beta) - 1 - k$ bits. - -Throughout the variables $n$ and $t$ will represent the highest digit of $x$ and $y$ respectively. These are first used to produce the -leading digit of the quotient. The loop beginning on line @184,for@ will produce the remainder of the quotient digits. - -The conditional ``continue'' on line @186,continue@ is used to prevent the algorithm from reading past the leading edge of $x$ which can occur when the -algorithm eliminates multiple non-zero digits in a single iteration. This ensures that $x_i$ is always non-zero since by definition the digits -above the $i$'th position $x$ must be zero in order for the quotient to be precise\footnote{Precise as far as integer division is concerned.}. - -Lines @214,t1@, @216,t1@ and @222,t2@ through @225,t2@ manually construct the high accuracy estimations by setting the digits of the two mp\_int -variables directly. - -\section{Single Digit Helpers} - -This section briefly describes a series of single digit helper algorithms which come in handy when working with small constants. All of -the helper functions assume the single digit input is positive and will treat them as such. - -\subsection{Single Digit Addition and Subtraction} - -Both addition and subtraction are performed by ``cheating'' and using mp\_set followed by the higher level addition or subtraction -algorithms. As a result these algorithms are subtantially simpler with a slight cost in performance. - -\newpage\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_add\_d}. \\ -\textbf{Input}. mp\_int $a$ and a mp\_digit $b$ \\ -\textbf{Output}. $c = a + b$ \\ -\hline \\ -1. $t \leftarrow b$ (\textit{mp\_set}) \\ -2. $c \leftarrow a + t$ \\ -3. Return(\textit{MP\_OKAY}) \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm mp\_add\_d} -\end{figure} - -\textbf{Algorithm mp\_add\_d.} -This algorithm initiates a temporary mp\_int with the value of the single digit and uses algorithm mp\_add to add the two values together. - -EXAM,bn_mp_add_d.c - -Clever use of the letter 't'. - -\subsubsection{Subtraction} -The single digit subtraction algorithm mp\_sub\_d is essentially the same except it uses mp\_sub to subtract the digit from the mp\_int. - -\subsection{Single Digit Multiplication} -Single digit multiplication arises enough in division and radix conversion that it ought to be implement as a special case of the baseline -multiplication algorithm. Essentially this algorithm is a modified version of algorithm s\_mp\_mul\_digs where one of the multiplicands -only has one digit. - -\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_mul\_d}. \\ -\textbf{Input}. mp\_int $a$ and a mp\_digit $b$ \\ -\textbf{Output}. $c = ab$ \\ -\hline \\ -1. $pa \leftarrow a.used$ \\ -2. Grow $c$ to at least $pa + 1$ digits. \\ -3. $oldused \leftarrow c.used$ \\ -4. $c.used \leftarrow pa + 1$ \\ -5. $c.sign \leftarrow a.sign$ \\ -6. $\mu \leftarrow 0$ \\ -7. for $ix$ from $0$ to $pa - 1$ do \\ -\hspace{3mm}7.1 $\hat r \leftarrow \mu + a_{ix}b$ \\ -\hspace{3mm}7.2 $c_{ix} \leftarrow \hat r \mbox{ (mod }\beta\mbox{)}$ \\ -\hspace{3mm}7.3 $\mu \leftarrow \lfloor \hat r / \beta \rfloor$ \\ -8. $c_{pa} \leftarrow \mu$ \\ -9. for $ix$ from $pa + 1$ to $oldused$ do \\ -\hspace{3mm}9.1 $c_{ix} \leftarrow 0$ \\ -10. Clamp excess digits of $c$. \\ -11. Return(\textit{MP\_OKAY}). \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm mp\_mul\_d} -\end{figure} -\textbf{Algorithm mp\_mul\_d.} -This algorithm quickly multiplies an mp\_int by a small single digit value. It is specially tailored to the job and has a minimal of overhead. -Unlike the full multiplication algorithms this algorithm does not require any significnat temporary storage or memory allocations. - -EXAM,bn_mp_mul_d.c - -In this implementation the destination $c$ may point to the same mp\_int as the source $a$ since the result is written after the digit is -read from the source. This function uses pointer aliases $tmpa$ and $tmpc$ for the digits of $a$ and $c$ respectively. - -\subsection{Single Digit Division} -Like the single digit multiplication algorithm, single digit division is also a fairly common algorithm used in radix conversion. Since the -divisor is only a single digit a specialized variant of the division algorithm can be used to compute the quotient. - -\newpage\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_div\_d}. \\ -\textbf{Input}. mp\_int $a$ and a mp\_digit $b$ \\ -\textbf{Output}. $c = \lfloor a / b \rfloor, d = a - cb$ \\ -\hline \\ -1. If $b = 0$ then return(\textit{MP\_VAL}).\\ -2. If $b = 3$ then use algorithm mp\_div\_3 instead. \\ -3. Init $q$ to $a.used$ digits. \\ -4. $q.used \leftarrow a.used$ \\ -5. $q.sign \leftarrow a.sign$ \\ -6. $\hat w \leftarrow 0$ \\ -7. for $ix$ from $a.used - 1$ down to $0$ do \\ -\hspace{3mm}7.1 $\hat w \leftarrow \hat w \beta + a_{ix}$ \\ -\hspace{3mm}7.2 If $\hat w \ge b$ then \\ -\hspace{6mm}7.2.1 $t \leftarrow \lfloor \hat w / b \rfloor$ \\ -\hspace{6mm}7.2.2 $\hat w \leftarrow \hat w \mbox{ (mod }b\mbox{)}$ \\ -\hspace{3mm}7.3 else\\ -\hspace{6mm}7.3.1 $t \leftarrow 0$ \\ -\hspace{3mm}7.4 $q_{ix} \leftarrow t$ \\ -8. $d \leftarrow \hat w$ \\ -9. Clamp excess digits of $q$. \\ -10. $c \leftarrow q$ \\ -11. Return(\textit{MP\_OKAY}). \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm mp\_div\_d} -\end{figure} -\textbf{Algorithm mp\_div\_d.} -This algorithm divides the mp\_int $a$ by the single mp\_digit $b$ using an optimized approach. Essentially in every iteration of the -algorithm another digit of the dividend is reduced and another digit of quotient produced. Provided $b < \beta$ the value of $\hat w$ -after step 7.1 will be limited such that $0 \le \lfloor \hat w / b \rfloor < \beta$. - -If the divisor $b$ is equal to three a variant of this algorithm is used which is called mp\_div\_3. It replaces the division by three with -a multiplication by $\lfloor \beta / 3 \rfloor$ and the appropriate shift and residual fixup. In essence it is much like the Barrett reduction -from chapter seven. - -EXAM,bn_mp_div_d.c - -Like the implementation of algorithm mp\_div this algorithm allows either of the quotient or remainder to be passed as a \textbf{NULL} pointer to -indicate the respective value is not required. This allows a trivial single digit modular reduction algorithm, mp\_mod\_d to be created. - -The division and remainder on lines @44,/@ and @45,%@ can be replaced often by a single division on most processors. For example, the 32-bit x86 based -processors can divide a 64-bit quantity by a 32-bit quantity and produce the quotient and remainder simultaneously. Unfortunately the GCC -compiler does not recognize that optimization and will actually produce two function calls to find the quotient and remainder respectively. - -\subsection{Single Digit Root Extraction} - -Finding the $n$'th root of an integer is fairly easy as far as numerical analysis is concerned. Algorithms such as the Newton-Raphson approximation -(\ref{eqn:newton}) series will converge very quickly to a root for any continuous function $f(x)$. - -\begin{equation} -x_{i+1} = x_i - {f(x_i) \over f'(x_i)} -\label{eqn:newton} -\end{equation} - -In this case the $n$'th root is desired and $f(x) = x^n - a$ where $a$ is the integer of which the root is desired. The derivative of $f(x)$ is -simply $f'(x) = nx^{n - 1}$. Of particular importance is that this algorithm will be used over the integers not over the a more continuous domain -such as the real numbers. As a result the root found can be above the true root by few and must be manually adjusted. Ideally at the end of the -algorithm the $n$'th root $b$ of an integer $a$ is desired such that $b^n \le a$. - -\newpage\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_n\_root}. \\ -\textbf{Input}. mp\_int $a$ and a mp\_digit $b$ \\ -\textbf{Output}. $c^b \le a$ \\ -\hline \\ -1. If $b$ is even and $a.sign = MP\_NEG$ return(\textit{MP\_VAL}). \\ -2. $sign \leftarrow a.sign$ \\ -3. $a.sign \leftarrow MP\_ZPOS$ \\ -4. t$2 \leftarrow 2$ \\ -5. Loop \\ -\hspace{3mm}5.1 t$1 \leftarrow $ t$2$ \\ -\hspace{3mm}5.2 t$3 \leftarrow $ t$1^{b - 1}$ \\ -\hspace{3mm}5.3 t$2 \leftarrow $ t$3 $ $\cdot$ t$1$ \\ -\hspace{3mm}5.4 t$2 \leftarrow $ t$2 - a$ \\ -\hspace{3mm}5.5 t$3 \leftarrow $ t$3 \cdot b$ \\ -\hspace{3mm}5.6 t$3 \leftarrow \lfloor $t$2 / $t$3 \rfloor$ \\ -\hspace{3mm}5.7 t$2 \leftarrow $ t$1 - $ t$3$ \\ -\hspace{3mm}5.8 If t$1 \ne $ t$2$ then goto step 5. \\ -6. Loop \\ -\hspace{3mm}6.1 t$2 \leftarrow $ t$1^b$ \\ -\hspace{3mm}6.2 If t$2 > a$ then \\ -\hspace{6mm}6.2.1 t$1 \leftarrow $ t$1 - 1$ \\ -\hspace{6mm}6.2.2 Goto step 6. \\ -7. $a.sign \leftarrow sign$ \\ -8. $c \leftarrow $ t$1$ \\ -9. $c.sign \leftarrow sign$ \\ -10. Return(\textit{MP\_OKAY}). \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm mp\_n\_root} -\end{figure} -\textbf{Algorithm mp\_n\_root.} -This algorithm finds the integer $n$'th root of an input using the Newton-Raphson approach. It is partially optimized based on the observation -that the numerator of ${f(x) \over f'(x)}$ can be derived from a partial denominator. That is at first the denominator is calculated by finding -$x^{b - 1}$. This value can then be multiplied by $x$ and have $a$ subtracted from it to find the numerator. This saves a total of $b - 1$ -multiplications by t$1$ inside the loop. - -The initial value of the approximation is t$2 = 2$ which allows the algorithm to start with very small values and quickly converge on the -root. Ideally this algorithm is meant to find the $n$'th root of an input where $n$ is bounded by $2 \le n \le 5$. - -EXAM,bn_mp_n_root.c - -\section{Random Number Generation} - -Random numbers come up in a variety of activities from public key cryptography to simple simulations and various randomized algorithms. Pollard-Rho -factoring for example, can make use of random values as starting points to find factors of a composite integer. In this case the algorithm presented -is solely for simulations and not intended for cryptographic use. - -\newpage\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_rand}. \\ -\textbf{Input}. An integer $b$ \\ -\textbf{Output}. A pseudo-random number of $b$ digits \\ -\hline \\ -1. $a \leftarrow 0$ \\ -2. If $b \le 0$ return(\textit{MP\_OKAY}) \\ -3. Pick a non-zero random digit $d$. \\ -4. $a \leftarrow a + d$ \\ -5. for $ix$ from 1 to $d - 1$ do \\ -\hspace{3mm}5.1 $a \leftarrow a \cdot \beta$ \\ -\hspace{3mm}5.2 Pick a random digit $d$. \\ -\hspace{3mm}5.3 $a \leftarrow a + d$ \\ -6. Return(\textit{MP\_OKAY}). \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm mp\_rand} -\end{figure} -\textbf{Algorithm mp\_rand.} -This algorithm produces a pseudo-random integer of $b$ digits. By ensuring that the first digit is non-zero the algorithm also guarantees that the -final result has at least $b$ digits. It relies heavily on a third-part random number generator which should ideally generate uniformly all of -the integers from $0$ to $\beta - 1$. - -EXAM,bn_mp_rand.c - -\section{Formatted Representations} -The ability to emit a radix-$n$ textual representation of an integer is useful for interacting with human parties. For example, the ability to -be given a string of characters such as ``114585'' and turn it into the radix-$\beta$ equivalent would make it easier to enter numbers -into a program. - -\subsection{Reading Radix-n Input} -For the purposes of this text we will assume that a simple lower ASCII map (\ref{fig:ASC}) is used for the values of from $0$ to $63$ to -printable characters. For example, when the character ``N'' is read it represents the integer $23$. The first $16$ characters of the -map are for the common representations up to hexadecimal. After that they match the ``base64'' encoding scheme which are suitable chosen -such that they are printable. While outputting as base64 may not be too helpful for human operators it does allow communication via non binary -mediums. - -\newpage\begin{figure}[here] -\begin{center} -\begin{tabular}{cc|cc|cc|cc} -\hline \textbf{Value} & \textbf{Char} & \textbf{Value} & \textbf{Char} & \textbf{Value} & \textbf{Char} & \textbf{Value} & \textbf{Char} \\ -\hline -0 & 0 & 1 & 1 & 2 & 2 & 3 & 3 \\ -4 & 4 & 5 & 5 & 6 & 6 & 7 & 7 \\ -8 & 8 & 9 & 9 & 10 & A & 11 & B \\ -12 & C & 13 & D & 14 & E & 15 & F \\ -16 & G & 17 & H & 18 & I & 19 & J \\ -20 & K & 21 & L & 22 & M & 23 & N \\ -24 & O & 25 & P & 26 & Q & 27 & R \\ -28 & S & 29 & T & 30 & U & 31 & V \\ -32 & W & 33 & X & 34 & Y & 35 & Z \\ -36 & a & 37 & b & 38 & c & 39 & d \\ -40 & e & 41 & f & 42 & g & 43 & h \\ -44 & i & 45 & j & 46 & k & 47 & l \\ -48 & m & 49 & n & 50 & o & 51 & p \\ -52 & q & 53 & r & 54 & s & 55 & t \\ -56 & u & 57 & v & 58 & w & 59 & x \\ -60 & y & 61 & z & 62 & $+$ & 63 & $/$ \\ -\hline -\end{tabular} -\end{center} -\caption{Lower ASCII Map} -\label{fig:ASC} -\end{figure} - -\newpage\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_read\_radix}. \\ -\textbf{Input}. A string $str$ of length $sn$ and radix $r$. \\ -\textbf{Output}. The radix-$\beta$ equivalent mp\_int. \\ -\hline \\ -1. If $r < 2$ or $r > 64$ return(\textit{MP\_VAL}). \\ -2. $ix \leftarrow 0$ \\ -3. If $str_0 =$ ``-'' then do \\ -\hspace{3mm}3.1 $ix \leftarrow ix + 1$ \\ -\hspace{3mm}3.2 $sign \leftarrow MP\_NEG$ \\ -4. else \\ -\hspace{3mm}4.1 $sign \leftarrow MP\_ZPOS$ \\ -5. $a \leftarrow 0$ \\ -6. for $iy$ from $ix$ to $sn - 1$ do \\ -\hspace{3mm}6.1 Let $y$ denote the position in the map of $str_{iy}$. \\ -\hspace{3mm}6.2 If $str_{iy}$ is not in the map or $y \ge r$ then goto step 7. \\ -\hspace{3mm}6.3 $a \leftarrow a \cdot r$ \\ -\hspace{3mm}6.4 $a \leftarrow a + y$ \\ -7. If $a \ne 0$ then $a.sign \leftarrow sign$ \\ -8. Return(\textit{MP\_OKAY}). \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm mp\_read\_radix} -\end{figure} -\textbf{Algorithm mp\_read\_radix.} -This algorithm will read an ASCII string and produce the radix-$\beta$ mp\_int representation of the same integer. A minus symbol ``-'' may precede the -string to indicate the value is negative, otherwise it is assumed to be positive. The algorithm will read up to $sn$ characters from the input -and will stop when it reads a character it cannot map the algorithm stops reading characters from the string. This allows numbers to be embedded -as part of larger input without any significant problem. - -EXAM,bn_mp_read_radix.c - -\subsection{Generating Radix-$n$ Output} -Generating radix-$n$ output is fairly trivial with a division and remainder algorithm. - -\newpage\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_toradix}. \\ -\textbf{Input}. A mp\_int $a$ and an integer $r$\\ -\textbf{Output}. The radix-$r$ representation of $a$ \\ -\hline \\ -1. If $r < 2$ or $r > 64$ return(\textit{MP\_VAL}). \\ -2. If $a = 0$ then $str = $ ``$0$'' and return(\textit{MP\_OKAY}). \\ -3. $t \leftarrow a$ \\ -4. $str \leftarrow$ ``'' \\ -5. if $t.sign = MP\_NEG$ then \\ -\hspace{3mm}5.1 $str \leftarrow str + $ ``-'' \\ -\hspace{3mm}5.2 $t.sign = MP\_ZPOS$ \\ -6. While ($t \ne 0$) do \\ -\hspace{3mm}6.1 $d \leftarrow t \mbox{ (mod }r\mbox{)}$ \\ -\hspace{3mm}6.2 $t \leftarrow \lfloor t / r \rfloor$ \\ -\hspace{3mm}6.3 Look up $d$ in the map and store the equivalent character in $y$. \\ -\hspace{3mm}6.4 $str \leftarrow str + y$ \\ -7. If $str_0 = $``$-$'' then \\ -\hspace{3mm}7.1 Reverse the digits $str_1, str_2, \ldots str_n$. \\ -8. Otherwise \\ -\hspace{3mm}8.1 Reverse the digits $str_0, str_1, \ldots str_n$. \\ -9. Return(\textit{MP\_OKAY}).\\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm mp\_toradix} -\end{figure} -\textbf{Algorithm mp\_toradix.} -This algorithm computes the radix-$r$ representation of an mp\_int $a$. The ``digits'' of the representation are extracted by reducing -successive powers of $\lfloor a / r^k \rfloor$ the input modulo $r$ until $r^k > a$. Note that instead of actually dividing by $r^k$ in -each iteration the quotient $\lfloor a / r \rfloor$ is saved for the next iteration. As a result a series of trivial $n \times 1$ divisions -are required instead of a series of $n \times k$ divisions. One design flaw of this approach is that the digits are produced in the reverse order -(see~\ref{fig:mpradix}). To remedy this flaw the digits must be swapped or simply ``reversed''. - -\begin{figure} -\begin{center} -\begin{tabular}{|c|c|c|} -\hline \textbf{Value of $a$} & \textbf{Value of $d$} & \textbf{Value of $str$} \\ -\hline $1234$ & -- & -- \\ -\hline $123$ & $4$ & ``4'' \\ -\hline $12$ & $3$ & ``43'' \\ -\hline $1$ & $2$ & ``432'' \\ -\hline $0$ & $1$ & ``4321'' \\ -\hline -\end{tabular} -\end{center} -\caption{Example of Algorithm mp\_toradix.} -\label{fig:mpradix} -\end{figure} - -EXAM,bn_mp_toradix.c - -\chapter{Number Theoretic Algorithms} -This chapter discusses several fundamental number theoretic algorithms such as the greatest common divisor, least common multiple and Jacobi -symbol computation. These algorithms arise as essential components in several key cryptographic algorithms such as the RSA public key algorithm and -various Sieve based factoring algorithms. - -\section{Greatest Common Divisor} -The greatest common divisor of two integers $a$ and $b$, often denoted as $(a, b)$ is the largest integer $k$ that is a proper divisor of -both $a$ and $b$. That is, $k$ is the largest integer such that $0 \equiv a \mbox{ (mod }k\mbox{)}$ and $0 \equiv b \mbox{ (mod }k\mbox{)}$ occur -simultaneously. - -The most common approach (cite) is to reduce one input modulo another. That is if $a$ and $b$ are divisible by some integer $k$ and if $qa + r = b$ then -$r$ is also divisible by $k$. The reduction pattern follows $\left < a , b \right > \rightarrow \left < b, a \mbox{ mod } b \right >$. - -\newpage\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{Greatest Common Divisor (I)}. \\ -\textbf{Input}. Two positive integers $a$ and $b$ greater than zero. \\ -\textbf{Output}. The greatest common divisor $(a, b)$. \\ -\hline \\ -1. While ($b > 0$) do \\ -\hspace{3mm}1.1 $r \leftarrow a \mbox{ (mod }b\mbox{)}$ \\ -\hspace{3mm}1.2 $a \leftarrow b$ \\ -\hspace{3mm}1.3 $b \leftarrow r$ \\ -2. Return($a$). \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm Greatest Common Divisor (I)} -\label{fig:gcd1} -\end{figure} - -This algorithm will quickly converge on the greatest common divisor since the residue $r$ tends diminish rapidly. However, divisions are -relatively expensive operations to perform and should ideally be avoided. There is another approach based on a similar relationship of -greatest common divisors. The faster approach is based on the observation that if $k$ divides both $a$ and $b$ it will also divide $a - b$. -In particular, we would like $a - b$ to decrease in magnitude which implies that $b \ge a$. - -\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{Greatest Common Divisor (II)}. \\ -\textbf{Input}. Two positive integers $a$ and $b$ greater than zero. \\ -\textbf{Output}. The greatest common divisor $(a, b)$. \\ -\hline \\ -1. While ($b > 0$) do \\ -\hspace{3mm}1.1 Swap $a$ and $b$ such that $a$ is the smallest of the two. \\ -\hspace{3mm}1.2 $b \leftarrow b - a$ \\ -2. Return($a$). \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm Greatest Common Divisor (II)} -\label{fig:gcd2} -\end{figure} - -\textbf{Proof} \textit{Algorithm~\ref{fig:gcd2} will return the greatest common divisor of $a$ and $b$.} -The algorithm in figure~\ref{fig:gcd2} will eventually terminate since $b \ge a$ the subtraction in step 1.2 will be a value less than $b$. In other -words in every iteration that tuple $\left < a, b \right >$ decrease in magnitude until eventually $a = b$. Since both $a$ and $b$ are always -divisible by the greatest common divisor (\textit{until the last iteration}) and in the last iteration of the algorithm $b = 0$, therefore, in the -second to last iteration of the algorithm $b = a$ and clearly $(a, a) = a$ which concludes the proof. \textbf{QED}. - -As a matter of practicality algorithm \ref{fig:gcd1} decreases far too slowly to be useful. Specially if $b$ is much larger than $a$ such that -$b - a$ is still very much larger than $a$. A simple addition to the algorithm is to divide $b - a$ by a power of some integer $p$ which does -not divide the greatest common divisor but will divide $b - a$. In this case ${b - a} \over p$ is also an integer and still divisible by -the greatest common divisor. - -However, instead of factoring $b - a$ to find a suitable value of $p$ the powers of $p$ can be removed from $a$ and $b$ that are in common first. -Then inside the loop whenever $b - a$ is divisible by some power of $p$ it can be safely removed. - -\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{Greatest Common Divisor (III)}. \\ -\textbf{Input}. Two positive integers $a$ and $b$ greater than zero. \\ -\textbf{Output}. The greatest common divisor $(a, b)$. \\ -\hline \\ -1. $k \leftarrow 0$ \\ -2. While $a$ and $b$ are both divisible by $p$ do \\ -\hspace{3mm}2.1 $a \leftarrow \lfloor a / p \rfloor$ \\ -\hspace{3mm}2.2 $b \leftarrow \lfloor b / p \rfloor$ \\ -\hspace{3mm}2.3 $k \leftarrow k + 1$ \\ -3. While $a$ is divisible by $p$ do \\ -\hspace{3mm}3.1 $a \leftarrow \lfloor a / p \rfloor$ \\ -4. While $b$ is divisible by $p$ do \\ -\hspace{3mm}4.1 $b \leftarrow \lfloor b / p \rfloor$ \\ -5. While ($b > 0$) do \\ -\hspace{3mm}5.1 Swap $a$ and $b$ such that $a$ is the smallest of the two. \\ -\hspace{3mm}5.2 $b \leftarrow b - a$ \\ -\hspace{3mm}5.3 While $b$ is divisible by $p$ do \\ -\hspace{6mm}5.3.1 $b \leftarrow \lfloor b / p \rfloor$ \\ -6. Return($a \cdot p^k$). \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm Greatest Common Divisor (III)} -\label{fig:gcd3} -\end{figure} - -This algorithm is based on the first except it removes powers of $p$ first and inside the main loop to ensure the tuple $\left < a, b \right >$ -decreases more rapidly. The first loop on step two removes powers of $p$ that are in common. A count, $k$, is kept which will present a common -divisor of $p^k$. After step two the remaining common divisor of $a$ and $b$ cannot be divisible by $p$. This means that $p$ can be safely -divided out of the difference $b - a$ so long as the division leaves no remainder. - -In particular the value of $p$ should be chosen such that the division on step 5.3.1 occur often. It also helps that division by $p$ be easy -to compute. The ideal choice of $p$ is two since division by two amounts to a right logical shift. Another important observation is that by -step five both $a$ and $b$ are odd. Therefore, the diffrence $b - a$ must be even which means that each iteration removes one bit from the -largest of the pair. - -\subsection{Complete Greatest Common Divisor} -The algorithms presented so far cannot handle inputs which are zero or negative. The following algorithm can handle all input cases properly -and will produce the greatest common divisor. - -\newpage\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_gcd}. \\ -\textbf{Input}. mp\_int $a$ and $b$ \\ -\textbf{Output}. The greatest common divisor $c = (a, b)$. \\ -\hline \\ -1. If $a = 0$ then \\ -\hspace{3mm}1.1 $c \leftarrow \vert b \vert $ \\ -\hspace{3mm}1.2 Return(\textit{MP\_OKAY}). \\ -2. If $b = 0$ then \\ -\hspace{3mm}2.1 $c \leftarrow \vert a \vert $ \\ -\hspace{3mm}2.2 Return(\textit{MP\_OKAY}). \\ -3. $u \leftarrow \vert a \vert, v \leftarrow \vert b \vert$ \\ -4. $k \leftarrow 0$ \\ -5. While $u.used > 0$ and $v.used > 0$ and $u_0 \equiv v_0 \equiv 0 \mbox{ (mod }2\mbox{)}$ \\ -\hspace{3mm}5.1 $k \leftarrow k + 1$ \\ -\hspace{3mm}5.2 $u \leftarrow \lfloor u / 2 \rfloor$ \\ -\hspace{3mm}5.3 $v \leftarrow \lfloor v / 2 \rfloor$ \\ -6. While $u.used > 0$ and $u_0 \equiv 0 \mbox{ (mod }2\mbox{)}$ \\ -\hspace{3mm}6.1 $u \leftarrow \lfloor u / 2 \rfloor$ \\ -7. While $v.used > 0$ and $v_0 \equiv 0 \mbox{ (mod }2\mbox{)}$ \\ -\hspace{3mm}7.1 $v \leftarrow \lfloor v / 2 \rfloor$ \\ -8. While $v.used > 0$ \\ -\hspace{3mm}8.1 If $\vert u \vert > \vert v \vert$ then \\ -\hspace{6mm}8.1.1 Swap $u$ and $v$. \\ -\hspace{3mm}8.2 $v \leftarrow \vert v \vert - \vert u \vert$ \\ -\hspace{3mm}8.3 While $v.used > 0$ and $v_0 \equiv 0 \mbox{ (mod }2\mbox{)}$ \\ -\hspace{6mm}8.3.1 $v \leftarrow \lfloor v / 2 \rfloor$ \\ -9. $c \leftarrow u \cdot 2^k$ \\ -10. Return(\textit{MP\_OKAY}). \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm mp\_gcd} -\end{figure} -\textbf{Algorithm mp\_gcd.} -This algorithm will produce the greatest common divisor of two mp\_ints $a$ and $b$. The algorithm was originally based on Algorithm B of -Knuth \cite[pp. 338]{TAOCPV2} but has been modified to be simpler to explain. In theory it achieves the same asymptotic working time as -Algorithm B and in practice this appears to be true. - -The first two steps handle the cases where either one of or both inputs are zero. If either input is zero the greatest common divisor is the -largest input or zero if they are both zero. If the inputs are not trivial than $u$ and $v$ are assigned the absolute values of -$a$ and $b$ respectively and the algorithm will proceed to reduce the pair. - -Step five will divide out any common factors of two and keep track of the count in the variable $k$. After this step, two is no longer a -factor of the remaining greatest common divisor between $u$ and $v$ and can be safely evenly divided out of either whenever they are even. Step -six and seven ensure that the $u$ and $v$ respectively have no more factors of two. At most only one of the while--loops will iterate since -they cannot both be even. - -By step eight both of $u$ and $v$ are odd which is required for the inner logic. First the pair are swapped such that $v$ is equal to -or greater than $u$. This ensures that the subtraction on step 8.2 will always produce a positive and even result. Step 8.3 removes any -factors of two from the difference $u$ to ensure that in the next iteration of the loop both are once again odd. - -After $v = 0$ occurs the variable $u$ has the greatest common divisor of the pair $\left < u, v \right >$ just after step six. The result -must be adjusted by multiplying by the common factors of two ($2^k$) removed earlier. - -EXAM,bn_mp_gcd.c - -This function makes use of the macros mp\_iszero and mp\_iseven. The former evaluates to $1$ if the input mp\_int is equivalent to the -integer zero otherwise it evaluates to $0$. The latter evaluates to $1$ if the input mp\_int represents a non-zero even integer otherwise -it evaluates to $0$. Note that just because mp\_iseven may evaluate to $0$ does not mean the input is odd, it could also be zero. The three -trivial cases of inputs are handled on lines @23,zero@ through @29,}@. After those lines the inputs are assumed to be non-zero. - -Lines @32,if@ and @36,if@ make local copies $u$ and $v$ of the inputs $a$ and $b$ respectively. At this point the common factors of two -must be divided out of the two inputs. The block starting at line @43,common@ removes common factors of two by first counting the number of trailing -zero bits in both. The local integer $k$ is used to keep track of how many factors of $2$ are pulled out of both values. It is assumed that -the number of factors will not exceed the maximum value of a C ``int'' data type\footnote{Strictly speaking no array in C may have more than -entries than are accessible by an ``int'' so this is not a limitation.}. - -At this point there are no more common factors of two in the two values. The divisions by a power of two on lines @60,div_2d@ and @67,div_2d@ remove -any independent factors of two such that both $u$ and $v$ are guaranteed to be an odd integer before hitting the main body of the algorithm. The while loop -on line @72, while@ performs the reduction of the pair until $v$ is equal to zero. The unsigned comparison and subtraction algorithms are used in -place of the full signed routines since both values are guaranteed to be positive and the result of the subtraction is guaranteed to be non-negative. - -\section{Least Common Multiple} -The least common multiple of a pair of integers is their product divided by their greatest common divisor. For two integers $a$ and $b$ the -least common multiple is normally denoted as $[ a, b ]$ and numerically equivalent to ${ab} \over {(a, b)}$. For example, if $a = 2 \cdot 2 \cdot 3 = 12$ -and $b = 2 \cdot 3 \cdot 3 \cdot 7 = 126$ the least common multiple is ${126 \over {(12, 126)}} = {126 \over 6} = 21$. - -The least common multiple arises often in coding theory as well as number theory. If two functions have periods of $a$ and $b$ respectively they will -collide, that is be in synchronous states, after only $[ a, b ]$ iterations. This is why, for example, random number generators based on -Linear Feedback Shift Registers (LFSR) tend to use registers with periods which are co-prime (\textit{e.g. the greatest common divisor is one.}). -Similarly in number theory if a composite $n$ has two prime factors $p$ and $q$ then maximal order of any unit of $\Z/n\Z$ will be $[ p - 1, q - 1] $. - -\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_lcm}. \\ -\textbf{Input}. mp\_int $a$ and $b$ \\ -\textbf{Output}. The least common multiple $c = [a, b]$. \\ -\hline \\ -1. $c \leftarrow (a, b)$ \\ -2. $t \leftarrow a \cdot b$ \\ -3. $c \leftarrow \lfloor t / c \rfloor$ \\ -4. Return(\textit{MP\_OKAY}). \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm mp\_lcm} -\end{figure} -\textbf{Algorithm mp\_lcm.} -This algorithm computes the least common multiple of two mp\_int inputs $a$ and $b$. It computes the least common multiple directly by -dividing the product of the two inputs by their greatest common divisor. - -EXAM,bn_mp_lcm.c - -\section{Jacobi Symbol Computation} -To explain the Jacobi Symbol we shall first discuss the Legendre function\footnote{Arrg. What is the name of this?} off which the Jacobi symbol is -defined. The Legendre function computes whether or not an integer $a$ is a quadratic residue modulo an odd prime $p$. Numerically it is -equivalent to equation \ref{eqn:legendre}. - -\textit{-- Tom, don't be an ass, cite your source here...!} - -\begin{equation} -a^{(p-1)/2} \equiv \begin{array}{rl} - -1 & \mbox{if }a\mbox{ is a quadratic non-residue.} \\ - 0 & \mbox{if }a\mbox{ divides }p\mbox{.} \\ - 1 & \mbox{if }a\mbox{ is a quadratic residue}. - \end{array} \mbox{ (mod }p\mbox{)} -\label{eqn:legendre} -\end{equation} - -\textbf{Proof.} \textit{Equation \ref{eqn:legendre} correctly identifies the residue status of an integer $a$ modulo a prime $p$.} -An integer $a$ is a quadratic residue if the following equation has a solution. - -\begin{equation} -x^2 \equiv a \mbox{ (mod }p\mbox{)} -\label{eqn:root} -\end{equation} - -Consider the following equation. - -\begin{equation} -0 \equiv x^{p-1} - 1 \equiv \left \lbrace \left (x^2 \right )^{(p-1)/2} - a^{(p-1)/2} \right \rbrace + \left ( a^{(p-1)/2} - 1 \right ) \mbox{ (mod }p\mbox{)} -\label{eqn:rooti} -\end{equation} - -Whether equation \ref{eqn:root} has a solution or not equation \ref{eqn:rooti} is always true. If $a^{(p-1)/2} - 1 \equiv 0 \mbox{ (mod }p\mbox{)}$ -then the quantity in the braces must be zero. By reduction, - -\begin{eqnarray} -\left (x^2 \right )^{(p-1)/2} - a^{(p-1)/2} \equiv 0 \nonumber \\ -\left (x^2 \right )^{(p-1)/2} \equiv a^{(p-1)/2} \nonumber \\ -x^2 \equiv a \mbox{ (mod }p\mbox{)} -\end{eqnarray} - -As a result there must be a solution to the quadratic equation and in turn $a$ must be a quadratic residue. If $a$ does not divide $p$ and $a$ -is not a quadratic residue then the only other value $a^{(p-1)/2}$ may be congruent to is $-1$ since -\begin{equation} -0 \equiv a^{p - 1} - 1 \equiv (a^{(p-1)/2} + 1)(a^{(p-1)/2} - 1) \mbox{ (mod }p\mbox{)} -\end{equation} -One of the terms on the right hand side must be zero. \textbf{QED} - -\subsection{Jacobi Symbol} -The Jacobi symbol is a generalization of the Legendre function for any odd non prime moduli $p$ greater than 2. If $p = \prod_{i=0}^n p_i$ then -the Jacobi symbol $\left ( { a \over p } \right )$ is equal to the following equation. - -\begin{equation} -\left ( { a \over p } \right ) = \left ( { a \over p_0} \right ) \left ( { a \over p_1} \right ) \ldots \left ( { a \over p_n} \right ) -\end{equation} - -By inspection if $p$ is prime the Jacobi symbol is equivalent to the Legendre function. The following facts\footnote{See HAC \cite[pp. 72-74]{HAC} for -further details.} will be used to derive an efficient Jacobi symbol algorithm. Where $p$ is an odd integer greater than two and $a, b \in \Z$ the -following are true. - -\begin{enumerate} -\item $\left ( { a \over p} \right )$ equals $-1$, $0$ or $1$. -\item $\left ( { ab \over p} \right ) = \left ( { a \over p} \right )\left ( { b \over p} \right )$. -\item If $a \equiv b$ then $\left ( { a \over p} \right ) = \left ( { b \over p} \right )$. -\item $\left ( { 2 \over p} \right )$ equals $1$ if $p \equiv 1$ or $7 \mbox{ (mod }8\mbox{)}$. Otherwise, it equals $-1$. -\item $\left ( { a \over p} \right ) \equiv \left ( { p \over a} \right ) \cdot (-1)^{(p-1)(a-1)/4}$. More specifically -$\left ( { a \over p} \right ) = \left ( { p \over a} \right )$ if $p \equiv a \equiv 1 \mbox{ (mod }4\mbox{)}$. -\end{enumerate} - -Using these facts if $a = 2^k \cdot a'$ then - -\begin{eqnarray} -\left ( { a \over p } \right ) = \left ( {{2^k} \over p } \right ) \left ( {a' \over p} \right ) \nonumber \\ - = \left ( {2 \over p } \right )^k \left ( {a' \over p} \right ) -\label{eqn:jacobi} -\end{eqnarray} - -By fact five, - -\begin{equation} -\left ( { a \over p } \right ) = \left ( { p \over a } \right ) \cdot (-1)^{(p-1)(a-1)/4} -\end{equation} - -Subsequently by fact three since $p \equiv (p \mbox{ mod }a) \mbox{ (mod }a\mbox{)}$ then - -\begin{equation} -\left ( { a \over p } \right ) = \left ( { {p \mbox{ mod } a} \over a } \right ) \cdot (-1)^{(p-1)(a-1)/4} -\end{equation} - -By putting both observations into equation \ref{eqn:jacobi} the following simplified equation is formed. - -\begin{equation} -\left ( { a \over p } \right ) = \left ( {2 \over p } \right )^k \left ( {{p\mbox{ mod }a'} \over a'} \right ) \cdot (-1)^{(p-1)(a'-1)/4} -\end{equation} - -The value of $\left ( {{p \mbox{ mod }a'} \over a'} \right )$ can be found by using the same equation recursively. The value of -$\left ( {2 \over p } \right )^k$ equals $1$ if $k$ is even otherwise it equals $\left ( {2 \over p } \right )$. Using this approach the -factors of $p$ do not have to be known. Furthermore, if $(a, p) = 1$ then the algorithm will terminate when the recursion requests the -Jacobi symbol computation of $\left ( {1 \over a'} \right )$ which is simply $1$. - -\newpage\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_jacobi}. \\ -\textbf{Input}. mp\_int $a$ and $p$, $a \ge 0$, $p \ge 3$, $p \equiv 1 \mbox{ (mod }2\mbox{)}$ \\ -\textbf{Output}. The Jacobi symbol $c = \left ( {a \over p } \right )$. \\ -\hline \\ -1. If $a = 0$ then \\ -\hspace{3mm}1.1 $c \leftarrow 0$ \\ -\hspace{3mm}1.2 Return(\textit{MP\_OKAY}). \\ -2. If $a = 1$ then \\ -\hspace{3mm}2.1 $c \leftarrow 1$ \\ -\hspace{3mm}2.2 Return(\textit{MP\_OKAY}). \\ -3. $a' \leftarrow a$ \\ -4. $k \leftarrow 0$ \\ -5. While $a'.used > 0$ and $a'_0 \equiv 0 \mbox{ (mod }2\mbox{)}$ \\ -\hspace{3mm}5.1 $k \leftarrow k + 1$ \\ -\hspace{3mm}5.2 $a' \leftarrow \lfloor a' / 2 \rfloor$ \\ -6. If $k \equiv 0 \mbox{ (mod }2\mbox{)}$ then \\ -\hspace{3mm}6.1 $s \leftarrow 1$ \\ -7. else \\ -\hspace{3mm}7.1 $r \leftarrow p_0 \mbox{ (mod }8\mbox{)}$ \\ -\hspace{3mm}7.2 If $r = 1$ or $r = 7$ then \\ -\hspace{6mm}7.2.1 $s \leftarrow 1$ \\ -\hspace{3mm}7.3 else \\ -\hspace{6mm}7.3.1 $s \leftarrow -1$ \\ -8. If $p_0 \equiv a'_0 \equiv 3 \mbox{ (mod }4\mbox{)}$ then \\ -\hspace{3mm}8.1 $s \leftarrow -s$ \\ -9. If $a' \ne 1$ then \\ -\hspace{3mm}9.1 $p' \leftarrow p \mbox{ (mod }a'\mbox{)}$ \\ -\hspace{3mm}9.2 $s \leftarrow s \cdot \mbox{mp\_jacobi}(p', a')$ \\ -10. $c \leftarrow s$ \\ -11. Return(\textit{MP\_OKAY}). \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm mp\_jacobi} -\end{figure} -\textbf{Algorithm mp\_jacobi.} -This algorithm computes the Jacobi symbol for an arbitrary positive integer $a$ with respect to an odd integer $p$ greater than three. The algorithm -is based on algorithm 2.149 of HAC \cite[pp. 73]{HAC}. - -Step numbers one and two handle the trivial cases of $a = 0$ and $a = 1$ respectively. Step five determines the number of two factors in the -input $a$. If $k$ is even than the term $\left ( { 2 \over p } \right )^k$ must always evaluate to one. If $k$ is odd than the term evaluates to one -if $p_0$ is congruent to one or seven modulo eight, otherwise it evaluates to $-1$. After the the $\left ( { 2 \over p } \right )^k$ term is handled -the $(-1)^{(p-1)(a'-1)/4}$ is computed and multiplied against the current product $s$. The latter term evaluates to one if both $p$ and $a'$ -are congruent to one modulo four, otherwise it evaluates to negative one. - -By step nine if $a'$ does not equal one a recursion is required. Step 9.1 computes $p' \equiv p \mbox{ (mod }a'\mbox{)}$ and will recurse to compute -$\left ( {p' \over a'} \right )$ which is multiplied against the current Jacobi product. - -EXAM,bn_mp_jacobi.c - -As a matter of practicality the variable $a'$ as per the pseudo-code is reprensented by the variable $a1$ since the $'$ symbol is not valid for a C -variable name character. - -The two simple cases of $a = 0$ and $a = 1$ are handled at the very beginning to simplify the algorithm. If the input is non-trivial the algorithm -has to proceed compute the Jacobi. The variable $s$ is used to hold the current Jacobi product. Note that $s$ is merely a C ``int'' data type since -the values it may obtain are merely $-1$, $0$ and $1$. - -After a local copy of $a$ is made all of the factors of two are divided out and the total stored in $k$. Technically only the least significant -bit of $k$ is required, however, it makes the algorithm simpler to follow to perform an addition. In practice an exclusive-or and addition have the same -processor requirements and neither is faster than the other. - -Line @59, if@ through @70, }@ determines the value of $\left ( { 2 \over p } \right )^k$. If the least significant bit of $k$ is zero than -$k$ is even and the value is one. Otherwise, the value of $s$ depends on which residue class $p$ belongs to modulo eight. The value of -$(-1)^{(p-1)(a'-1)/4}$ is compute and multiplied against $s$ on lines @73, if@ through @75, }@. - -Finally, if $a1$ does not equal one the algorithm must recurse and compute $\left ( {p' \over a'} \right )$. - -\textit{-- Comment about default $s$ and such...} - -\section{Modular Inverse} -\label{sec:modinv} -The modular inverse of a number actually refers to the modular multiplicative inverse. Essentially for any integer $a$ such that $(a, p) = 1$ there -exist another integer $b$ such that $ab \equiv 1 \mbox{ (mod }p\mbox{)}$. The integer $b$ is called the multiplicative inverse of $a$ which is -denoted as $b = a^{-1}$. Technically speaking modular inversion is a well defined operation for any finite ring or field not just for rings and -fields of integers. However, the former will be the matter of discussion. - -The simplest approach is to compute the algebraic inverse of the input. That is to compute $b \equiv a^{\Phi(p) - 1}$. If $\Phi(p)$ is the -order of the multiplicative subgroup modulo $p$ then $b$ must be the multiplicative inverse of $a$. The proof of which is trivial. - -\begin{equation} -ab \equiv a \left (a^{\Phi(p) - 1} \right ) \equiv a^{\Phi(p)} \equiv a^0 \equiv 1 \mbox{ (mod }p\mbox{)} -\end{equation} - -However, as simple as this approach may be it has two serious flaws. It requires that the value of $\Phi(p)$ be known which if $p$ is composite -requires all of the prime factors. This approach also is very slow as the size of $p$ grows. - -A simpler approach is based on the observation that solving for the multiplicative inverse is equivalent to solving the linear -Diophantine\footnote{See LeVeque \cite[pp. 40-43]{LeVeque} for more information.} equation. - -\begin{equation} -ab + pq = 1 -\end{equation} - -Where $a$, $b$, $p$ and $q$ are all integers. If such a pair of integers $ \left < b, q \right >$ exist than $b$ is the multiplicative inverse of -$a$ modulo $p$. The extended Euclidean algorithm (Knuth \cite[pp. 342]{TAOCPV2}) can be used to solve such equations provided $(a, p) = 1$. -However, instead of using that algorithm directly a variant known as the binary Extended Euclidean algorithm will be used in its place. The -binary approach is very similar to the binary greatest common divisor algorithm except it will produce a full solution to the Diophantine -equation. - -\subsection{General Case} -\newpage\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_invmod}. \\ -\textbf{Input}. mp\_int $a$ and $b$, $(a, b) = 1$, $p \ge 2$, $0 < a < p$. \\ -\textbf{Output}. The modular inverse $c \equiv a^{-1} \mbox{ (mod }b\mbox{)}$. \\ -\hline \\ -1. If $b \le 0$ then return(\textit{MP\_VAL}). \\ -2. If $b_0 \equiv 1 \mbox{ (mod }2\mbox{)}$ then use algorithm fast\_mp\_invmod. \\ -3. $x \leftarrow \vert a \vert, y \leftarrow b$ \\ -4. If $x_0 \equiv y_0 \equiv 0 \mbox{ (mod }2\mbox{)}$ then return(\textit{MP\_VAL}). \\ -5. $B \leftarrow 0, C \leftarrow 0, A \leftarrow 1, D \leftarrow 1$ \\ -6. While $u.used > 0$ and $u_0 \equiv 0 \mbox{ (mod }2\mbox{)}$ \\ -\hspace{3mm}6.1 $u \leftarrow \lfloor u / 2 \rfloor$ \\ -\hspace{3mm}6.2 If ($A.used > 0$ and $A_0 \equiv 1 \mbox{ (mod }2\mbox{)}$) or ($B.used > 0$ and $B_0 \equiv 1 \mbox{ (mod }2\mbox{)}$) then \\ -\hspace{6mm}6.2.1 $A \leftarrow A + y$ \\ -\hspace{6mm}6.2.2 $B \leftarrow B - x$ \\ -\hspace{3mm}6.3 $A \leftarrow \lfloor A / 2 \rfloor$ \\ -\hspace{3mm}6.4 $B \leftarrow \lfloor B / 2 \rfloor$ \\ -7. While $v.used > 0$ and $v_0 \equiv 0 \mbox{ (mod }2\mbox{)}$ \\ -\hspace{3mm}7.1 $v \leftarrow \lfloor v / 2 \rfloor$ \\ -\hspace{3mm}7.2 If ($C.used > 0$ and $C_0 \equiv 1 \mbox{ (mod }2\mbox{)}$) or ($D.used > 0$ and $D_0 \equiv 1 \mbox{ (mod }2\mbox{)}$) then \\ -\hspace{6mm}7.2.1 $C \leftarrow C + y$ \\ -\hspace{6mm}7.2.2 $D \leftarrow D - x$ \\ -\hspace{3mm}7.3 $C \leftarrow \lfloor C / 2 \rfloor$ \\ -\hspace{3mm}7.4 $D \leftarrow \lfloor D / 2 \rfloor$ \\ -8. If $u \ge v$ then \\ -\hspace{3mm}8.1 $u \leftarrow u - v$ \\ -\hspace{3mm}8.2 $A \leftarrow A - C$ \\ -\hspace{3mm}8.3 $B \leftarrow B - D$ \\ -9. else \\ -\hspace{3mm}9.1 $v \leftarrow v - u$ \\ -\hspace{3mm}9.2 $C \leftarrow C - A$ \\ -\hspace{3mm}9.3 $D \leftarrow D - B$ \\ -10. If $u \ne 0$ goto step 6. \\ -11. If $v \ne 1$ return(\textit{MP\_VAL}). \\ -12. While $C \le 0$ do \\ -\hspace{3mm}12.1 $C \leftarrow C + b$ \\ -13. While $C \ge b$ do \\ -\hspace{3mm}13.1 $C \leftarrow C - b$ \\ -14. $c \leftarrow C$ \\ -15. Return(\textit{MP\_OKAY}). \\ -\hline -\end{tabular} -\end{center} -\end{small} -\end{figure} -\textbf{Algorithm mp\_invmod.} -This algorithm computes the modular multiplicative inverse of an integer $a$ modulo an integer $b$. This algorithm is a variation of the -extended binary Euclidean algorithm from HAC \cite[pp. 608]{HAC}. It has been modified to only compute the modular inverse and not a complete -Diophantine solution. - -If $b \le 0$ than the modulus is invalid and MP\_VAL is returned. Similarly if both $a$ and $b$ are even then there cannot be a multiplicative -inverse for $a$ and the error is reported. - -The astute reader will observe that steps seven through nine are very similar to the binary greatest common divisor algorithm mp\_gcd. In this case -the other variables to the Diophantine equation are solved. The algorithm terminates when $u = 0$ in which case the solution is - -\begin{equation} -Ca + Db = v -\end{equation} - -If $v$, the greatest common divisor of $a$ and $b$ is not equal to one then the algorithm will report an error as no inverse exists. Otherwise, $C$ -is the modular inverse of $a$. The actual value of $C$ is congruent to, but not necessarily equal to, the ideal modular inverse which should lie -within $1 \le a^{-1} < b$. Step numbers twelve and thirteen adjust the inverse until it is in range. If the original input $a$ is within $0 < a < p$ -then only a couple of additions or subtractions will be required to adjust the inverse. - -EXAM,bn_mp_invmod.c - -\subsubsection{Odd Moduli} - -When the modulus $b$ is odd the variables $A$ and $C$ are fixed and are not required to compute the inverse. In particular by attempting to solve -the Diophantine $Cb + Da = 1$ only $B$ and $D$ are required to find the inverse of $a$. - -The algorithm fast\_mp\_invmod is a direct adaptation of algorithm mp\_invmod with all all steps involving either $A$ or $C$ removed. This -optimization will halve the time required to compute the modular inverse. - -\section{Primality Tests} - -A non-zero integer $a$ is said to be prime if it is not divisible by any other integer excluding one and itself. For example, $a = 7$ is prime -since the integers $2 \ldots 6$ do not evenly divide $a$. By contrast, $a = 6$ is not prime since $a = 6 = 2 \cdot 3$. - -Prime numbers arise in cryptography considerably as they allow finite fields to be formed. The ability to determine whether an integer is prime or -not quickly has been a viable subject in cryptography and number theory for considerable time. The algorithms that will be presented are all -probablistic algorithms in that when they report an integer is composite it must be composite. However, when the algorithms report an integer is -prime the algorithm may be incorrect. - -As will be discussed it is possible to limit the probability of error so well that for practical purposes the probablity of error might as -well be zero. For the purposes of these discussions let $n$ represent the candidate integer of which the primality is in question. - -\subsection{Trial Division} - -Trial division means to attempt to evenly divide a candidate integer by small prime integers. If the candidate can be evenly divided it obviously -cannot be prime. By dividing by all primes $1 < p \le \sqrt{n}$ this test can actually prove whether an integer is prime. However, such a test -would require a prohibitive amount of time as $n$ grows. - -Instead of dividing by every prime, a smaller, more mangeable set of primes may be used instead. By performing trial division with only a subset -of the primes less than $\sqrt{n} + 1$ the algorithm cannot prove if a candidate is prime. However, often it can prove a candidate is not prime. - -The benefit of this test is that trial division by small values is fairly efficient. Specially compared to the other algorithms that will be -discussed shortly. The probability that this approach correctly identifies a composite candidate when tested with all primes upto $q$ is given by -$1 - {1.12 \over ln(q)}$. The graph (\ref{pic:primality}, will be added later) demonstrates the probability of success for the range -$3 \le q \le 100$. - -At approximately $q = 30$ the gain of performing further tests diminishes fairly quickly. At $q = 90$ further testing is generally not going to -be of any practical use. In the case of LibTomMath the default limit $q = 256$ was chosen since it is not too high and will eliminate -approximately $80\%$ of all candidate integers. The constant \textbf{PRIME\_SIZE} is equal to the number of primes in the test base. The -array \_\_prime\_tab is an array of the first \textbf{PRIME\_SIZE} prime numbers. - -\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_prime\_is\_divisible}. \\ -\textbf{Input}. mp\_int $a$ \\ -\textbf{Output}. $c = 1$ if $n$ is divisible by a small prime, otherwise $c = 0$. \\ -\hline \\ -1. for $ix$ from $0$ to $PRIME\_SIZE$ do \\ -\hspace{3mm}1.1 $d \leftarrow n \mbox{ (mod }\_\_prime\_tab_{ix}\mbox{)}$ \\ -\hspace{3mm}1.2 If $d = 0$ then \\ -\hspace{6mm}1.2.1 $c \leftarrow 1$ \\ -\hspace{6mm}1.2.2 Return(\textit{MP\_OKAY}). \\ -2. $c \leftarrow 0$ \\ -3. Return(\textit{MP\_OKAY}). \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm mp\_prime\_is\_divisible} -\end{figure} -\textbf{Algorithm mp\_prime\_is\_divisible.} -This algorithm attempts to determine if a candidate integer $n$ is composite by performing trial divisions. - -EXAM,bn_mp_prime_is_divisible.c - -The algorithm defaults to a return of $0$ in case an error occurs. The values in the prime table are all specified to be in the range of a -mp\_digit. The table \_\_prime\_tab is defined in the following file. - -EXAM,bn_prime_tab.c - -Note that there are two possible tables. When an mp\_digit is 7-bits long only the primes upto $127$ may be included, otherwise the primes -upto $1619$ are used. Note that the value of \textbf{PRIME\_SIZE} is a constant dependent on the size of a mp\_digit. - -\subsection{The Fermat Test} -The Fermat test is probably one the oldest tests to have a non-trivial probability of success. It is based on the fact that if $n$ is in -fact prime then $a^{n} \equiv a \mbox{ (mod }n\mbox{)}$ for all $0 < a < n$. The reason being that if $n$ is prime than the order of -the multiplicative sub group is $n - 1$. Any base $a$ must have an order which divides $n - 1$ and as such $a^n$ is equivalent to -$a^1 = a$. - -If $n$ is composite then any given base $a$ does not have to have a period which divides $n - 1$. In which case -it is possible that $a^n \nequiv a \mbox{ (mod }n\mbox{)}$. However, this test is not absolute as it is possible that the order -of a base will divide $n - 1$ which would then be reported as prime. Such a base yields what is known as a Fermat pseudo-prime. Several -integers known as Carmichael numbers will be a pseudo-prime to all valid bases. Fortunately such numbers are extremely rare as $n$ grows -in size. - -\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_prime\_fermat}. \\ -\textbf{Input}. mp\_int $a$ and $b$, $a \ge 2$, $0 < b < a$. \\ -\textbf{Output}. $c = 1$ if $b^a \equiv b \mbox{ (mod }a\mbox{)}$, otherwise $c = 0$. \\ -\hline \\ -1. $t \leftarrow b^a \mbox{ (mod }a\mbox{)}$ \\ -2. If $t = b$ then \\ -\hspace{3mm}2.1 $c = 1$ \\ -3. else \\ -\hspace{3mm}3.1 $c = 0$ \\ -4. Return(\textit{MP\_OKAY}). \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm mp\_prime\_fermat} -\end{figure} -\textbf{Algorithm mp\_prime\_fermat.} -This algorithm determines whether an mp\_int $a$ is a Fermat prime to the base $b$ or not. It uses a single modular exponentiation to -determine the result. - -EXAM,bn_mp_prime_fermat.c - -\subsection{The Miller-Rabin Test} -The Miller-Rabin (citation) test is another primality test which has tighter error bounds than the Fermat test specifically with sequentially chosen -candidate integers. The algorithm is based on the observation that if $n - 1 = 2^kr$ and if $b^r \nequiv \pm 1$ then after upto $k - 1$ squarings the -value must be equal to $-1$. The squarings are stopped as soon as $-1$ is observed. If the value of $1$ is observed first it means that -some value not congruent to $\pm 1$ when squared equals one which cannot occur if $n$ is prime. - -\begin{figure}[!here] -\begin{small} -\begin{center} -\begin{tabular}{l} -\hline Algorithm \textbf{mp\_prime\_miller\_rabin}. \\ -\textbf{Input}. mp\_int $a$ and $b$, $a \ge 2$, $0 < b < a$. \\ -\textbf{Output}. $c = 1$ if $a$ is a Miller-Rabin prime to the base $a$, otherwise $c = 0$. \\ -\hline -1. $a' \leftarrow a - 1$ \\ -2. $r \leftarrow n1$ \\ -3. $c \leftarrow 0, s \leftarrow 0$ \\ -4. While $r.used > 0$ and $r_0 \equiv 0 \mbox{ (mod }2\mbox{)}$ \\ -\hspace{3mm}4.1 $s \leftarrow s + 1$ \\ -\hspace{3mm}4.2 $r \leftarrow \lfloor r / 2 \rfloor$ \\ -5. $y \leftarrow b^r \mbox{ (mod }a\mbox{)}$ \\ -6. If $y \nequiv \pm 1$ then \\ -\hspace{3mm}6.1 $j \leftarrow 1$ \\ -\hspace{3mm}6.2 While $j \le (s - 1)$ and $y \nequiv a'$ \\ -\hspace{6mm}6.2.1 $y \leftarrow y^2 \mbox{ (mod }a\mbox{)}$ \\ -\hspace{6mm}6.2.2 If $y = 1$ then goto step 8. \\ -\hspace{6mm}6.2.3 $j \leftarrow j + 1$ \\ -\hspace{3mm}6.3 If $y \nequiv a'$ goto step 8. \\ -7. $c \leftarrow 1$\\ -8. Return(\textit{MP\_OKAY}). \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Algorithm mp\_prime\_miller\_rabin} -\end{figure} -\textbf{Algorithm mp\_prime\_miller\_rabin.} -This algorithm performs one trial round of the Miller-Rabin algorithm to the base $b$. It will set $c = 1$ if the algorithm cannot determine -if $b$ is composite or $c = 0$ if $b$ is provably composite. The values of $s$ and $r$ are computed such that $a' = a - 1 = 2^sr$. - -If the value $y \equiv b^r$ is congruent to $\pm 1$ then the algorithm cannot prove if $a$ is composite or not. Otherwise, the algorithm will -square $y$ upto $s - 1$ times stopping only when $y \equiv -1$. If $y^2 \equiv 1$ and $y \nequiv \pm 1$ then the algorithm can report that $a$ -is provably composite. If the algorithm performs $s - 1$ squarings and $y \nequiv -1$ then $a$ is provably composite. If $a$ is not provably -composite then it is \textit{probably} prime. - -EXAM,bn_mp_prime_miller_rabin.c - - - - -\backmatter -\appendix -\begin{thebibliography}{ABCDEF} -\bibitem[1]{TAOCPV2} -Donald Knuth, \textit{The Art of Computer Programming}, Third Edition, Volume Two, Seminumerical Algorithms, Addison-Wesley, 1998 - -\bibitem[2]{HAC} -A. Menezes, P. van Oorschot, S. Vanstone, \textit{Handbook of Applied Cryptography}, CRC Press, 1996 - -\bibitem[3]{ROSE} -Michael Rosing, \textit{Implementing Elliptic Curve Cryptography}, Manning Publications, 1999 - -\bibitem[4]{COMBA} -Paul G. Comba, \textit{Exponentiation Cryptosystems on the IBM PC}. IBM Systems Journal 29(4): 526-538 (1990) - -\bibitem[5]{KARA} -A. Karatsuba, Doklay Akad. Nauk SSSR 145 (1962), pp.293-294 - -\bibitem[6]{KARAP} -Andre Weimerskirch and Christof Paar, \textit{Generalizations of the Karatsuba Algorithm for Polynomial Multiplication}, Submitted to Design, Codes and Cryptography, March 2002 - -\bibitem[7]{BARRETT} -Paul Barrett, \textit{Implementing the Rivest Shamir and Adleman Public Key Encryption Algorithm on a Standard Digital Signal Processor}, Advances in Cryptology, Crypto '86, Springer-Verlag. - -\bibitem[8]{MONT} -P.L.Montgomery. \textit{Modular multiplication without trial division}. Mathematics of Computation, 44(170):519-521, April 1985. - -\bibitem[9]{DRMET} -Chae Hoon Lim and Pil Joong Lee, \textit{Generating Efficient Primes for Discrete Log Cryptosystems}, POSTECH Information Research Laboratories - -\bibitem[10]{MMB} -J. Daemen and R. Govaerts and J. Vandewalle, \textit{Block ciphers based on Modular Arithmetic}, State and {P}rogress in the {R}esearch of {C}ryptography, 1993, pp. 80-89 - -\bibitem[11]{RSAREF} -R.L. Rivest, A. Shamir, L. Adleman, \textit{A Method for Obtaining Digital Signatures and Public-Key Cryptosystems} - -\bibitem[12]{DHREF} -Whitfield Diffie, Martin E. Hellman, \textit{New Directions in Cryptography}, IEEE Transactions on Information Theory, 1976 - -\bibitem[13]{IEEE} -IEEE Standard for Binary Floating-Point Arithmetic (ANSI/IEEE Std 754-1985) - -\bibitem[14]{GMP} -GNU Multiple Precision (GMP), \url{http://www.swox.com/gmp/} - -\bibitem[15]{MPI} -Multiple Precision Integer Library (MPI), Michael Fromberger, \url{http://thayer.dartmouth.edu/~sting/mpi/} - -\bibitem[16]{OPENSSL} -OpenSSL Cryptographic Toolkit, \url{http://openssl.org} - -\bibitem[17]{LIP} -Large Integer Package, \url{http://home.hetnet.nl/~ecstr/LIP.zip} - -\bibitem[18]{ISOC} -JTC1/SC22/WG14, ISO/IEC 9899:1999, ``A draft rationale for the C99 standard.'' - -\bibitem[19]{JAVA} -The Sun Java Website, \url{http://java.sun.com/} - -\end{thebibliography} - -\input{tommath.ind} - -\end{document} diff --git a/external/libtommath-0.42.0/tommath_class.h b/external/libtommath-0.42.0/tommath_class.h deleted file mode 100755 index 1e29c8f..0000000 --- a/external/libtommath-0.42.0/tommath_class.h +++ /dev/null @@ -1,999 +0,0 @@ -#if !(defined(LTM1) && defined(LTM2) && defined(LTM3)) -#if defined(LTM2) -#define LTM3 -#endif -#if defined(LTM1) -#define LTM2 -#endif -#define LTM1 - -#if defined(LTM_ALL) -#define BN_ERROR_C -#define BN_FAST_MP_INVMOD_C -#define BN_FAST_MP_MONTGOMERY_REDUCE_C -#define BN_FAST_S_MP_MUL_DIGS_C -#define BN_FAST_S_MP_MUL_HIGH_DIGS_C -#define BN_FAST_S_MP_SQR_C -#define BN_MP_2EXPT_C -#define BN_MP_ABS_C -#define BN_MP_ADD_C -#define BN_MP_ADD_D_C -#define BN_MP_ADDMOD_C -#define BN_MP_AND_C -#define BN_MP_CLAMP_C -#define BN_MP_CLEAR_C -#define BN_MP_CLEAR_MULTI_C -#define BN_MP_CMP_C -#define BN_MP_CMP_D_C -#define BN_MP_CMP_MAG_C -#define BN_MP_CNT_LSB_C -#define BN_MP_COPY_C -#define BN_MP_COUNT_BITS_C -#define BN_MP_DIV_C -#define BN_MP_DIV_2_C -#define BN_MP_DIV_2D_C -#define BN_MP_DIV_3_C -#define BN_MP_DIV_D_C -#define BN_MP_DR_IS_MODULUS_C -#define BN_MP_DR_REDUCE_C -#define BN_MP_DR_SETUP_C -#define BN_MP_EXCH_C -#define BN_MP_EXPT_D_C -#define BN_MP_EXPTMOD_C -#define BN_MP_EXPTMOD_FAST_C -#define BN_MP_EXTEUCLID_C -#define BN_MP_FREAD_C -#define BN_MP_FWRITE_C -#define BN_MP_GCD_C -#define BN_MP_GET_INT_C -#define BN_MP_GROW_C -#define BN_MP_INIT_C -#define BN_MP_INIT_COPY_C -#define BN_MP_INIT_MULTI_C -#define BN_MP_INIT_SET_C -#define BN_MP_INIT_SET_INT_C -#define BN_MP_INIT_SIZE_C -#define BN_MP_INVMOD_C -#define BN_MP_INVMOD_SLOW_C -#define BN_MP_IS_SQUARE_C -#define BN_MP_JACOBI_C -#define BN_MP_KARATSUBA_MUL_C -#define BN_MP_KARATSUBA_SQR_C -#define BN_MP_LCM_C -#define BN_MP_LSHD_C -#define BN_MP_MOD_C -#define BN_MP_MOD_2D_C -#define BN_MP_MOD_D_C -#define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C -#define BN_MP_MONTGOMERY_REDUCE_C -#define BN_MP_MONTGOMERY_SETUP_C -#define BN_MP_MUL_C -#define BN_MP_MUL_2_C -#define BN_MP_MUL_2D_C -#define BN_MP_MUL_D_C -#define BN_MP_MULMOD_C -#define BN_MP_N_ROOT_C -#define BN_MP_NEG_C -#define BN_MP_OR_C -#define BN_MP_PRIME_FERMAT_C -#define BN_MP_PRIME_IS_DIVISIBLE_C -#define BN_MP_PRIME_IS_PRIME_C -#define BN_MP_PRIME_MILLER_RABIN_C -#define BN_MP_PRIME_NEXT_PRIME_C -#define BN_MP_PRIME_RABIN_MILLER_TRIALS_C -#define BN_MP_PRIME_RANDOM_EX_C -#define BN_MP_RADIX_SIZE_C -#define BN_MP_RADIX_SMAP_C -#define BN_MP_RAND_C -#define BN_MP_READ_RADIX_C -#define BN_MP_READ_SIGNED_BIN_C -#define BN_MP_READ_UNSIGNED_BIN_C -#define BN_MP_REDUCE_C -#define BN_MP_REDUCE_2K_C -#define BN_MP_REDUCE_2K_L_C -#define BN_MP_REDUCE_2K_SETUP_C -#define BN_MP_REDUCE_2K_SETUP_L_C -#define BN_MP_REDUCE_IS_2K_C -#define BN_MP_REDUCE_IS_2K_L_C -#define BN_MP_REDUCE_SETUP_C -#define BN_MP_RSHD_C -#define BN_MP_SET_C -#define BN_MP_SET_INT_C -#define BN_MP_SHRINK_C -#define BN_MP_SIGNED_BIN_SIZE_C -#define BN_MP_SQR_C -#define BN_MP_SQRMOD_C -#define BN_MP_SQRT_C -#define BN_MP_SUB_C -#define BN_MP_SUB_D_C -#define BN_MP_SUBMOD_C -#define BN_MP_TO_SIGNED_BIN_C -#define BN_MP_TO_SIGNED_BIN_N_C -#define BN_MP_TO_UNSIGNED_BIN_C -#define BN_MP_TO_UNSIGNED_BIN_N_C -#define BN_MP_TOOM_MUL_C -#define BN_MP_TOOM_SQR_C -#define BN_MP_TORADIX_C -#define BN_MP_TORADIX_N_C -#define BN_MP_UNSIGNED_BIN_SIZE_C -#define BN_MP_XOR_C -#define BN_MP_ZERO_C -#define BN_PRIME_TAB_C -#define BN_REVERSE_C -#define BN_S_MP_ADD_C -#define BN_S_MP_EXPTMOD_C -#define BN_S_MP_MUL_DIGS_C -#define BN_S_MP_MUL_HIGH_DIGS_C -#define BN_S_MP_SQR_C -#define BN_S_MP_SUB_C -#define BNCORE_C -#endif - -#if defined(BN_ERROR_C) - #define BN_MP_ERROR_TO_STRING_C -#endif - -#if defined(BN_FAST_MP_INVMOD_C) - #define BN_MP_ISEVEN_C - #define BN_MP_INIT_MULTI_C - #define BN_MP_COPY_C - #define BN_MP_MOD_C - #define BN_MP_SET_C - #define BN_MP_DIV_2_C - #define BN_MP_ISODD_C - #define BN_MP_SUB_C - #define BN_MP_CMP_C - #define BN_MP_ISZERO_C - #define BN_MP_CMP_D_C - #define BN_MP_ADD_C - #define BN_MP_EXCH_C - #define BN_MP_CLEAR_MULTI_C -#endif - -#if defined(BN_FAST_MP_MONTGOMERY_REDUCE_C) - #define BN_MP_GROW_C - #define BN_MP_RSHD_C - #define BN_MP_CLAMP_C - #define BN_MP_CMP_MAG_C - #define BN_S_MP_SUB_C -#endif - -#if defined(BN_FAST_S_MP_MUL_DIGS_C) - #define BN_MP_GROW_C - #define BN_MP_CLAMP_C -#endif - -#if defined(BN_FAST_S_MP_MUL_HIGH_DIGS_C) - #define BN_MP_GROW_C - #define BN_MP_CLAMP_C -#endif - -#if defined(BN_FAST_S_MP_SQR_C) - #define BN_MP_GROW_C - #define BN_MP_CLAMP_C -#endif - -#if defined(BN_MP_2EXPT_C) - #define BN_MP_ZERO_C - #define BN_MP_GROW_C -#endif - -#if defined(BN_MP_ABS_C) - #define BN_MP_COPY_C -#endif - -#if defined(BN_MP_ADD_C) - #define BN_S_MP_ADD_C - #define BN_MP_CMP_MAG_C - #define BN_S_MP_SUB_C -#endif - -#if defined(BN_MP_ADD_D_C) - #define BN_MP_GROW_C - #define BN_MP_SUB_D_C - #define BN_MP_CLAMP_C -#endif - -#if defined(BN_MP_ADDMOD_C) - #define BN_MP_INIT_C - #define BN_MP_ADD_C - #define BN_MP_CLEAR_C - #define BN_MP_MOD_C -#endif - -#if defined(BN_MP_AND_C) - #define BN_MP_INIT_COPY_C - #define BN_MP_CLAMP_C - #define BN_MP_EXCH_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_CLAMP_C) -#endif - -#if defined(BN_MP_CLEAR_C) -#endif - -#if defined(BN_MP_CLEAR_MULTI_C) - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_CMP_C) - #define BN_MP_CMP_MAG_C -#endif - -#if defined(BN_MP_CMP_D_C) -#endif - -#if defined(BN_MP_CMP_MAG_C) -#endif - -#if defined(BN_MP_CNT_LSB_C) - #define BN_MP_ISZERO_C -#endif - -#if defined(BN_MP_COPY_C) - #define BN_MP_GROW_C -#endif - -#if defined(BN_MP_COUNT_BITS_C) -#endif - -#if defined(BN_MP_DIV_C) - #define BN_MP_ISZERO_C - #define BN_MP_CMP_MAG_C - #define BN_MP_COPY_C - #define BN_MP_ZERO_C - #define BN_MP_INIT_MULTI_C - #define BN_MP_SET_C - #define BN_MP_COUNT_BITS_C - #define BN_MP_ABS_C - #define BN_MP_MUL_2D_C - #define BN_MP_CMP_C - #define BN_MP_SUB_C - #define BN_MP_ADD_C - #define BN_MP_DIV_2D_C - #define BN_MP_EXCH_C - #define BN_MP_CLEAR_MULTI_C - #define BN_MP_INIT_SIZE_C - #define BN_MP_INIT_C - #define BN_MP_INIT_COPY_C - #define BN_MP_LSHD_C - #define BN_MP_RSHD_C - #define BN_MP_MUL_D_C - #define BN_MP_CLAMP_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_DIV_2_C) - #define BN_MP_GROW_C - #define BN_MP_CLAMP_C -#endif - -#if defined(BN_MP_DIV_2D_C) - #define BN_MP_COPY_C - #define BN_MP_ZERO_C - #define BN_MP_INIT_C - #define BN_MP_MOD_2D_C - #define BN_MP_CLEAR_C - #define BN_MP_RSHD_C - #define BN_MP_CLAMP_C - #define BN_MP_EXCH_C -#endif - -#if defined(BN_MP_DIV_3_C) - #define BN_MP_INIT_SIZE_C - #define BN_MP_CLAMP_C - #define BN_MP_EXCH_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_DIV_D_C) - #define BN_MP_ISZERO_C - #define BN_MP_COPY_C - #define BN_MP_DIV_2D_C - #define BN_MP_DIV_3_C - #define BN_MP_INIT_SIZE_C - #define BN_MP_CLAMP_C - #define BN_MP_EXCH_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_DR_IS_MODULUS_C) -#endif - -#if defined(BN_MP_DR_REDUCE_C) - #define BN_MP_GROW_C - #define BN_MP_CLAMP_C - #define BN_MP_CMP_MAG_C - #define BN_S_MP_SUB_C -#endif - -#if defined(BN_MP_DR_SETUP_C) -#endif - -#if defined(BN_MP_EXCH_C) -#endif - -#if defined(BN_MP_EXPT_D_C) - #define BN_MP_INIT_COPY_C - #define BN_MP_SET_C - #define BN_MP_SQR_C - #define BN_MP_CLEAR_C - #define BN_MP_MUL_C -#endif - -#if defined(BN_MP_EXPTMOD_C) - #define BN_MP_INIT_C - #define BN_MP_INVMOD_C - #define BN_MP_CLEAR_C - #define BN_MP_ABS_C - #define BN_MP_CLEAR_MULTI_C - #define BN_MP_REDUCE_IS_2K_L_C - #define BN_S_MP_EXPTMOD_C - #define BN_MP_DR_IS_MODULUS_C - #define BN_MP_REDUCE_IS_2K_C - #define BN_MP_ISODD_C - #define BN_MP_EXPTMOD_FAST_C -#endif - -#if defined(BN_MP_EXPTMOD_FAST_C) - #define BN_MP_COUNT_BITS_C - #define BN_MP_INIT_C - #define BN_MP_CLEAR_C - #define BN_MP_MONTGOMERY_SETUP_C - #define BN_FAST_MP_MONTGOMERY_REDUCE_C - #define BN_MP_MONTGOMERY_REDUCE_C - #define BN_MP_DR_SETUP_C - #define BN_MP_DR_REDUCE_C - #define BN_MP_REDUCE_2K_SETUP_C - #define BN_MP_REDUCE_2K_C - #define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C - #define BN_MP_MULMOD_C - #define BN_MP_SET_C - #define BN_MP_MOD_C - #define BN_MP_COPY_C - #define BN_MP_SQR_C - #define BN_MP_MUL_C - #define BN_MP_EXCH_C -#endif - -#if defined(BN_MP_EXTEUCLID_C) - #define BN_MP_INIT_MULTI_C - #define BN_MP_SET_C - #define BN_MP_COPY_C - #define BN_MP_ISZERO_C - #define BN_MP_DIV_C - #define BN_MP_MUL_C - #define BN_MP_SUB_C - #define BN_MP_NEG_C - #define BN_MP_EXCH_C - #define BN_MP_CLEAR_MULTI_C -#endif - -#if defined(BN_MP_FREAD_C) - #define BN_MP_ZERO_C - #define BN_MP_S_RMAP_C - #define BN_MP_MUL_D_C - #define BN_MP_ADD_D_C - #define BN_MP_CMP_D_C -#endif - -#if defined(BN_MP_FWRITE_C) - #define BN_MP_RADIX_SIZE_C - #define BN_MP_TORADIX_C -#endif - -#if defined(BN_MP_GCD_C) - #define BN_MP_ISZERO_C - #define BN_MP_ABS_C - #define BN_MP_ZERO_C - #define BN_MP_INIT_COPY_C - #define BN_MP_CNT_LSB_C - #define BN_MP_DIV_2D_C - #define BN_MP_CMP_MAG_C - #define BN_MP_EXCH_C - #define BN_S_MP_SUB_C - #define BN_MP_MUL_2D_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_GET_INT_C) -#endif - -#if defined(BN_MP_GROW_C) -#endif - -#if defined(BN_MP_INIT_C) -#endif - -#if defined(BN_MP_INIT_COPY_C) - #define BN_MP_COPY_C -#endif - -#if defined(BN_MP_INIT_MULTI_C) - #define BN_MP_ERR_C - #define BN_MP_INIT_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_INIT_SET_C) - #define BN_MP_INIT_C - #define BN_MP_SET_C -#endif - -#if defined(BN_MP_INIT_SET_INT_C) - #define BN_MP_INIT_C - #define BN_MP_SET_INT_C -#endif - -#if defined(BN_MP_INIT_SIZE_C) - #define BN_MP_INIT_C -#endif - -#if defined(BN_MP_INVMOD_C) - #define BN_MP_ISZERO_C - #define BN_MP_ISODD_C - #define BN_FAST_MP_INVMOD_C - #define BN_MP_INVMOD_SLOW_C -#endif - -#if defined(BN_MP_INVMOD_SLOW_C) - #define BN_MP_ISZERO_C - #define BN_MP_INIT_MULTI_C - #define BN_MP_MOD_C - #define BN_MP_COPY_C - #define BN_MP_ISEVEN_C - #define BN_MP_SET_C - #define BN_MP_DIV_2_C - #define BN_MP_ISODD_C - #define BN_MP_ADD_C - #define BN_MP_SUB_C - #define BN_MP_CMP_C - #define BN_MP_CMP_D_C - #define BN_MP_CMP_MAG_C - #define BN_MP_EXCH_C - #define BN_MP_CLEAR_MULTI_C -#endif - -#if defined(BN_MP_IS_SQUARE_C) - #define BN_MP_MOD_D_C - #define BN_MP_INIT_SET_INT_C - #define BN_MP_MOD_C - #define BN_MP_GET_INT_C - #define BN_MP_SQRT_C - #define BN_MP_SQR_C - #define BN_MP_CMP_MAG_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_JACOBI_C) - #define BN_MP_CMP_D_C - #define BN_MP_ISZERO_C - #define BN_MP_INIT_COPY_C - #define BN_MP_CNT_LSB_C - #define BN_MP_DIV_2D_C - #define BN_MP_MOD_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_KARATSUBA_MUL_C) - #define BN_MP_MUL_C - #define BN_MP_INIT_SIZE_C - #define BN_MP_CLAMP_C - #define BN_MP_SUB_C - #define BN_MP_ADD_C - #define BN_MP_LSHD_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_KARATSUBA_SQR_C) - #define BN_MP_INIT_SIZE_C - #define BN_MP_CLAMP_C - #define BN_MP_SQR_C - #define BN_MP_SUB_C - #define BN_S_MP_ADD_C - #define BN_MP_LSHD_C - #define BN_MP_ADD_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_LCM_C) - #define BN_MP_INIT_MULTI_C - #define BN_MP_GCD_C - #define BN_MP_CMP_MAG_C - #define BN_MP_DIV_C - #define BN_MP_MUL_C - #define BN_MP_CLEAR_MULTI_C -#endif - -#if defined(BN_MP_LSHD_C) - #define BN_MP_GROW_C - #define BN_MP_RSHD_C -#endif - -#if defined(BN_MP_MOD_C) - #define BN_MP_INIT_C - #define BN_MP_DIV_C - #define BN_MP_CLEAR_C - #define BN_MP_ADD_C - #define BN_MP_EXCH_C -#endif - -#if defined(BN_MP_MOD_2D_C) - #define BN_MP_ZERO_C - #define BN_MP_COPY_C - #define BN_MP_CLAMP_C -#endif - -#if defined(BN_MP_MOD_D_C) - #define BN_MP_DIV_D_C -#endif - -#if defined(BN_MP_MONTGOMERY_CALC_NORMALIZATION_C) - #define BN_MP_COUNT_BITS_C - #define BN_MP_2EXPT_C - #define BN_MP_SET_C - #define BN_MP_MUL_2_C - #define BN_MP_CMP_MAG_C - #define BN_S_MP_SUB_C -#endif - -#if defined(BN_MP_MONTGOMERY_REDUCE_C) - #define BN_FAST_MP_MONTGOMERY_REDUCE_C - #define BN_MP_GROW_C - #define BN_MP_CLAMP_C - #define BN_MP_RSHD_C - #define BN_MP_CMP_MAG_C - #define BN_S_MP_SUB_C -#endif - -#if defined(BN_MP_MONTGOMERY_SETUP_C) -#endif - -#if defined(BN_MP_MUL_C) - #define BN_MP_TOOM_MUL_C - #define BN_MP_KARATSUBA_MUL_C - #define BN_FAST_S_MP_MUL_DIGS_C - #define BN_S_MP_MUL_C - #define BN_S_MP_MUL_DIGS_C -#endif - -#if defined(BN_MP_MUL_2_C) - #define BN_MP_GROW_C -#endif - -#if defined(BN_MP_MUL_2D_C) - #define BN_MP_COPY_C - #define BN_MP_GROW_C - #define BN_MP_LSHD_C - #define BN_MP_CLAMP_C -#endif - -#if defined(BN_MP_MUL_D_C) - #define BN_MP_GROW_C - #define BN_MP_CLAMP_C -#endif - -#if defined(BN_MP_MULMOD_C) - #define BN_MP_INIT_C - #define BN_MP_MUL_C - #define BN_MP_CLEAR_C - #define BN_MP_MOD_C -#endif - -#if defined(BN_MP_N_ROOT_C) - #define BN_MP_INIT_C - #define BN_MP_SET_C - #define BN_MP_COPY_C - #define BN_MP_EXPT_D_C - #define BN_MP_MUL_C - #define BN_MP_SUB_C - #define BN_MP_MUL_D_C - #define BN_MP_DIV_C - #define BN_MP_CMP_C - #define BN_MP_SUB_D_C - #define BN_MP_EXCH_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_NEG_C) - #define BN_MP_COPY_C - #define BN_MP_ISZERO_C -#endif - -#if defined(BN_MP_OR_C) - #define BN_MP_INIT_COPY_C - #define BN_MP_CLAMP_C - #define BN_MP_EXCH_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_PRIME_FERMAT_C) - #define BN_MP_CMP_D_C - #define BN_MP_INIT_C - #define BN_MP_EXPTMOD_C - #define BN_MP_CMP_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_PRIME_IS_DIVISIBLE_C) - #define BN_MP_MOD_D_C -#endif - -#if defined(BN_MP_PRIME_IS_PRIME_C) - #define BN_MP_CMP_D_C - #define BN_MP_PRIME_IS_DIVISIBLE_C - #define BN_MP_INIT_C - #define BN_MP_SET_C - #define BN_MP_PRIME_MILLER_RABIN_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_PRIME_MILLER_RABIN_C) - #define BN_MP_CMP_D_C - #define BN_MP_INIT_COPY_C - #define BN_MP_SUB_D_C - #define BN_MP_CNT_LSB_C - #define BN_MP_DIV_2D_C - #define BN_MP_EXPTMOD_C - #define BN_MP_CMP_C - #define BN_MP_SQRMOD_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_PRIME_NEXT_PRIME_C) - #define BN_MP_CMP_D_C - #define BN_MP_SET_C - #define BN_MP_SUB_D_C - #define BN_MP_ISEVEN_C - #define BN_MP_MOD_D_C - #define BN_MP_INIT_C - #define BN_MP_ADD_D_C - #define BN_MP_PRIME_MILLER_RABIN_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_PRIME_RABIN_MILLER_TRIALS_C) -#endif - -#if defined(BN_MP_PRIME_RANDOM_EX_C) - #define BN_MP_READ_UNSIGNED_BIN_C - #define BN_MP_PRIME_IS_PRIME_C - #define BN_MP_SUB_D_C - #define BN_MP_DIV_2_C - #define BN_MP_MUL_2_C - #define BN_MP_ADD_D_C -#endif - -#if defined(BN_MP_RADIX_SIZE_C) - #define BN_MP_COUNT_BITS_C - #define BN_MP_INIT_COPY_C - #define BN_MP_ISZERO_C - #define BN_MP_DIV_D_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_RADIX_SMAP_C) - #define BN_MP_S_RMAP_C -#endif - -#if defined(BN_MP_RAND_C) - #define BN_MP_ZERO_C - #define BN_MP_ADD_D_C - #define BN_MP_LSHD_C -#endif - -#if defined(BN_MP_READ_RADIX_C) - #define BN_MP_ZERO_C - #define BN_MP_S_RMAP_C - #define BN_MP_RADIX_SMAP_C - #define BN_MP_MUL_D_C - #define BN_MP_ADD_D_C - #define BN_MP_ISZERO_C -#endif - -#if defined(BN_MP_READ_SIGNED_BIN_C) - #define BN_MP_READ_UNSIGNED_BIN_C -#endif - -#if defined(BN_MP_READ_UNSIGNED_BIN_C) - #define BN_MP_GROW_C - #define BN_MP_ZERO_C - #define BN_MP_MUL_2D_C - #define BN_MP_CLAMP_C -#endif - -#if defined(BN_MP_REDUCE_C) - #define BN_MP_REDUCE_SETUP_C - #define BN_MP_INIT_COPY_C - #define BN_MP_RSHD_C - #define BN_MP_MUL_C - #define BN_S_MP_MUL_HIGH_DIGS_C - #define BN_FAST_S_MP_MUL_HIGH_DIGS_C - #define BN_MP_MOD_2D_C - #define BN_S_MP_MUL_DIGS_C - #define BN_MP_SUB_C - #define BN_MP_CMP_D_C - #define BN_MP_SET_C - #define BN_MP_LSHD_C - #define BN_MP_ADD_C - #define BN_MP_CMP_C - #define BN_S_MP_SUB_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_REDUCE_2K_C) - #define BN_MP_INIT_C - #define BN_MP_COUNT_BITS_C - #define BN_MP_DIV_2D_C - #define BN_MP_MUL_D_C - #define BN_S_MP_ADD_C - #define BN_MP_CMP_MAG_C - #define BN_S_MP_SUB_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_REDUCE_2K_L_C) - #define BN_MP_INIT_C - #define BN_MP_COUNT_BITS_C - #define BN_MP_DIV_2D_C - #define BN_MP_MUL_C - #define BN_S_MP_ADD_C - #define BN_MP_CMP_MAG_C - #define BN_S_MP_SUB_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_REDUCE_2K_SETUP_C) - #define BN_MP_INIT_C - #define BN_MP_COUNT_BITS_C - #define BN_MP_2EXPT_C - #define BN_MP_CLEAR_C - #define BN_S_MP_SUB_C -#endif - -#if defined(BN_MP_REDUCE_2K_SETUP_L_C) - #define BN_MP_INIT_C - #define BN_MP_2EXPT_C - #define BN_MP_COUNT_BITS_C - #define BN_S_MP_SUB_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_REDUCE_IS_2K_C) - #define BN_MP_REDUCE_2K_C - #define BN_MP_COUNT_BITS_C -#endif - -#if defined(BN_MP_REDUCE_IS_2K_L_C) -#endif - -#if defined(BN_MP_REDUCE_SETUP_C) - #define BN_MP_2EXPT_C - #define BN_MP_DIV_C -#endif - -#if defined(BN_MP_RSHD_C) - #define BN_MP_ZERO_C -#endif - -#if defined(BN_MP_SET_C) - #define BN_MP_ZERO_C -#endif - -#if defined(BN_MP_SET_INT_C) - #define BN_MP_ZERO_C - #define BN_MP_MUL_2D_C - #define BN_MP_CLAMP_C -#endif - -#if defined(BN_MP_SHRINK_C) -#endif - -#if defined(BN_MP_SIGNED_BIN_SIZE_C) - #define BN_MP_UNSIGNED_BIN_SIZE_C -#endif - -#if defined(BN_MP_SQR_C) - #define BN_MP_TOOM_SQR_C - #define BN_MP_KARATSUBA_SQR_C - #define BN_FAST_S_MP_SQR_C - #define BN_S_MP_SQR_C -#endif - -#if defined(BN_MP_SQRMOD_C) - #define BN_MP_INIT_C - #define BN_MP_SQR_C - #define BN_MP_CLEAR_C - #define BN_MP_MOD_C -#endif - -#if defined(BN_MP_SQRT_C) - #define BN_MP_N_ROOT_C - #define BN_MP_ISZERO_C - #define BN_MP_ZERO_C - #define BN_MP_INIT_COPY_C - #define BN_MP_RSHD_C - #define BN_MP_DIV_C - #define BN_MP_ADD_C - #define BN_MP_DIV_2_C - #define BN_MP_CMP_MAG_C - #define BN_MP_EXCH_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_SUB_C) - #define BN_S_MP_ADD_C - #define BN_MP_CMP_MAG_C - #define BN_S_MP_SUB_C -#endif - -#if defined(BN_MP_SUB_D_C) - #define BN_MP_GROW_C - #define BN_MP_ADD_D_C - #define BN_MP_CLAMP_C -#endif - -#if defined(BN_MP_SUBMOD_C) - #define BN_MP_INIT_C - #define BN_MP_SUB_C - #define BN_MP_CLEAR_C - #define BN_MP_MOD_C -#endif - -#if defined(BN_MP_TO_SIGNED_BIN_C) - #define BN_MP_TO_UNSIGNED_BIN_C -#endif - -#if defined(BN_MP_TO_SIGNED_BIN_N_C) - #define BN_MP_SIGNED_BIN_SIZE_C - #define BN_MP_TO_SIGNED_BIN_C -#endif - -#if defined(BN_MP_TO_UNSIGNED_BIN_C) - #define BN_MP_INIT_COPY_C - #define BN_MP_ISZERO_C - #define BN_MP_DIV_2D_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_TO_UNSIGNED_BIN_N_C) - #define BN_MP_UNSIGNED_BIN_SIZE_C - #define BN_MP_TO_UNSIGNED_BIN_C -#endif - -#if defined(BN_MP_TOOM_MUL_C) - #define BN_MP_INIT_MULTI_C - #define BN_MP_MOD_2D_C - #define BN_MP_COPY_C - #define BN_MP_RSHD_C - #define BN_MP_MUL_C - #define BN_MP_MUL_2_C - #define BN_MP_ADD_C - #define BN_MP_SUB_C - #define BN_MP_DIV_2_C - #define BN_MP_MUL_2D_C - #define BN_MP_MUL_D_C - #define BN_MP_DIV_3_C - #define BN_MP_LSHD_C - #define BN_MP_CLEAR_MULTI_C -#endif - -#if defined(BN_MP_TOOM_SQR_C) - #define BN_MP_INIT_MULTI_C - #define BN_MP_MOD_2D_C - #define BN_MP_COPY_C - #define BN_MP_RSHD_C - #define BN_MP_SQR_C - #define BN_MP_MUL_2_C - #define BN_MP_ADD_C - #define BN_MP_SUB_C - #define BN_MP_DIV_2_C - #define BN_MP_MUL_2D_C - #define BN_MP_MUL_D_C - #define BN_MP_DIV_3_C - #define BN_MP_LSHD_C - #define BN_MP_CLEAR_MULTI_C -#endif - -#if defined(BN_MP_TORADIX_C) - #define BN_MP_ISZERO_C - #define BN_MP_INIT_COPY_C - #define BN_MP_DIV_D_C - #define BN_MP_CLEAR_C - #define BN_MP_S_RMAP_C -#endif - -#if defined(BN_MP_TORADIX_N_C) - #define BN_MP_ISZERO_C - #define BN_MP_INIT_COPY_C - #define BN_MP_DIV_D_C - #define BN_MP_CLEAR_C - #define BN_MP_S_RMAP_C -#endif - -#if defined(BN_MP_UNSIGNED_BIN_SIZE_C) - #define BN_MP_COUNT_BITS_C -#endif - -#if defined(BN_MP_XOR_C) - #define BN_MP_INIT_COPY_C - #define BN_MP_CLAMP_C - #define BN_MP_EXCH_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_MP_ZERO_C) -#endif - -#if defined(BN_PRIME_TAB_C) -#endif - -#if defined(BN_REVERSE_C) -#endif - -#if defined(BN_S_MP_ADD_C) - #define BN_MP_GROW_C - #define BN_MP_CLAMP_C -#endif - -#if defined(BN_S_MP_EXPTMOD_C) - #define BN_MP_COUNT_BITS_C - #define BN_MP_INIT_C - #define BN_MP_CLEAR_C - #define BN_MP_REDUCE_SETUP_C - #define BN_MP_REDUCE_C - #define BN_MP_REDUCE_2K_SETUP_L_C - #define BN_MP_REDUCE_2K_L_C - #define BN_MP_MOD_C - #define BN_MP_COPY_C - #define BN_MP_SQR_C - #define BN_MP_MUL_C - #define BN_MP_SET_C - #define BN_MP_EXCH_C -#endif - -#if defined(BN_S_MP_MUL_DIGS_C) - #define BN_FAST_S_MP_MUL_DIGS_C - #define BN_MP_INIT_SIZE_C - #define BN_MP_CLAMP_C - #define BN_MP_EXCH_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_S_MP_MUL_HIGH_DIGS_C) - #define BN_FAST_S_MP_MUL_HIGH_DIGS_C - #define BN_MP_INIT_SIZE_C - #define BN_MP_CLAMP_C - #define BN_MP_EXCH_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_S_MP_SQR_C) - #define BN_MP_INIT_SIZE_C - #define BN_MP_CLAMP_C - #define BN_MP_EXCH_C - #define BN_MP_CLEAR_C -#endif - -#if defined(BN_S_MP_SUB_C) - #define BN_MP_GROW_C - #define BN_MP_CLAMP_C -#endif - -#if defined(BNCORE_C) -#endif - -#ifdef LTM3 -#define LTM_LAST -#endif -#include -#include -#else -#define LTM_LAST -#endif - -/* $Source$ */ -/* $Revision: 0.36 $ */ -/* $Date: 2005-08-01 16:37:28 +0000 $ */ diff --git a/external/libtommath-0.42.0/tommath_superclass.h b/external/libtommath-0.42.0/tommath_superclass.h deleted file mode 100755 index 89d5516..0000000 --- a/external/libtommath-0.42.0/tommath_superclass.h +++ /dev/null @@ -1,76 +0,0 @@ -/* super class file for PK algos */ - -/* default ... include all MPI */ -#define LTM_ALL - -/* RSA only (does not support DH/DSA/ECC) */ -/* #define SC_RSA_1 */ - -/* For reference.... On an Athlon64 optimizing for speed... - - LTM's mpi.o with all functions [striped] is 142KiB in size. - -*/ - -/* Works for RSA only, mpi.o is 68KiB */ -#ifdef SC_RSA_1 - #define BN_MP_SHRINK_C - #define BN_MP_LCM_C - #define BN_MP_PRIME_RANDOM_EX_C - #define BN_MP_INVMOD_C - #define BN_MP_GCD_C - #define BN_MP_MOD_C - #define BN_MP_MULMOD_C - #define BN_MP_ADDMOD_C - #define BN_MP_EXPTMOD_C - #define BN_MP_SET_INT_C - #define BN_MP_INIT_MULTI_C - #define BN_MP_CLEAR_MULTI_C - #define BN_MP_UNSIGNED_BIN_SIZE_C - #define BN_MP_TO_UNSIGNED_BIN_C - #define BN_MP_MOD_D_C - #define BN_MP_PRIME_RABIN_MILLER_TRIALS_C - #define BN_REVERSE_C - #define BN_PRIME_TAB_C - - /* other modifiers */ - #define BN_MP_DIV_SMALL /* Slower division, not critical */ - - /* here we are on the last pass so we turn things off. The functions classes are still there - * but we remove them specifically from the build. This also invokes tweaks in functions - * like removing support for even moduli, etc... - */ -#ifdef LTM_LAST - #undef BN_MP_TOOM_MUL_C - #undef BN_MP_TOOM_SQR_C - #undef BN_MP_KARATSUBA_MUL_C - #undef BN_MP_KARATSUBA_SQR_C - #undef BN_MP_REDUCE_C - #undef BN_MP_REDUCE_SETUP_C - #undef BN_MP_DR_IS_MODULUS_C - #undef BN_MP_DR_SETUP_C - #undef BN_MP_DR_REDUCE_C - #undef BN_MP_REDUCE_IS_2K_C - #undef BN_MP_REDUCE_2K_SETUP_C - #undef BN_MP_REDUCE_2K_C - #undef BN_S_MP_EXPTMOD_C - #undef BN_MP_DIV_3_C - #undef BN_S_MP_MUL_HIGH_DIGS_C - #undef BN_FAST_S_MP_MUL_HIGH_DIGS_C - #undef BN_FAST_MP_INVMOD_C - - /* To safely undefine these you have to make sure your RSA key won't exceed the Comba threshold - * which is roughly 255 digits [7140 bits for 32-bit machines, 15300 bits for 64-bit machines] - * which means roughly speaking you can handle upto 2536-bit RSA keys with these defined without - * trouble. - */ - #undef BN_S_MP_MUL_DIGS_C - #undef BN_S_MP_SQR_C - #undef BN_MP_MONTGOMERY_REDUCE_C -#endif - -#endif - -/* $Source$ */ -/* $Revision: 0.36 $ */ -/* $Date: 2005-08-01 16:37:28 +0000 $ */ diff --git a/external/libtompoly-0.04/LICENSE b/external/libtompoly-0.04/LICENSE deleted file mode 100644 index 87c21ca..0000000 --- a/external/libtompoly-0.04/LICENSE +++ /dev/null @@ -1,4 +0,0 @@ -LibTomPoly is hereby placed in the Public Domain. - --- Tom St Denis - diff --git a/external/libtompoly-0.04/changes.txt b/external/libtompoly-0.04/changes.txt deleted file mode 100644 index d7ed38a..0000000 --- a/external/libtompoly-0.04/changes.txt +++ /dev/null @@ -1,24 +0,0 @@ -May 5th, 2004 -v0.04 - Fixed a bug in pb_monic() which for zero valued inputs could cause a segfault - - Daniel Richards (kyhwana@kyhwana.org) found several typos in the manual. - - Fixed bug in pb_shrink() that would leak memory - -Jan 25th, 2004 -v0.03 - Added pb_rawsize(), pb_readraw(), pb_toraw() - - Fixed bug in pb_monic() where it would only check the first [not leading] coefficient for one - -Jan 3rd, 2004 -v0.02 - Update pb_div() to shift r(x) after multplying it wit b(x) to save a bit of time - - improved pb_gcd() to handle inputs which are zero - - Added pb_shrink() - - fixed pb_invmod() - - added pb_exteuclid() [back ported that code into LTM... hehehe] - - added pb_exptmod() [this led me to find a bug in LTM!!!] - - added pb_monic() - - added pb_isirreduc() - - Some minor additions to test/documentation - -Dec 31st, 2003 -v0.01 ++ thanks goes to Martin Marcel, Greg Rose and Colin Percival for providing some missing knowledge and - helping me get this release going - - Initial release. diff --git a/external/libtompoly-0.04/demo/demo.c b/external/libtompoly-0.04/demo/demo.c deleted file mode 100644 index a6fe41c..0000000 --- a/external/libtompoly-0.04/demo/demo.c +++ /dev/null @@ -1,216 +0,0 @@ -#include - -void draw_poly(pb_poly *a) -{ - int x; - char buf[8192]; - - if (a->used == 0) { - printf("0"); - } else { - for (x = a->used - 1; x >= 0; x--) { - if (mp_iszero(&(a->terms[x])) == MP_YES) continue; - mp_toradix(&(a->terms[x]), buf, 10); - if ((x != a->used - 1) && a->terms[x].sign == MP_ZPOS) { - printf("+"); - } - printf(" %sx^%d ", buf, x); - } - } - if (mp_iszero(&(a->characteristic)) == MP_NO) { - mp_toradix(&(a->characteristic), buf, 10); - printf(" (mod %s)", buf); - } - printf("\n"); -} - -int main(void) -{ - mp_int chara; - pb_poly a,b,c,d,e; - mp_int aa,bb,cc,dd,ee; - int res; - - mp_init(&chara); - mp_init_multi(&aa,&bb,&cc,&dd,&ee,NULL); - pb_init_size(&a, &chara, 32); - pb_init_size(&b, &chara, 32); - pb_init_size(&c, &chara, 32); - pb_init_size(&d, &chara, 32); - pb_init_size(&e, &chara, 32); - - /* a = 3x + 4 */ - mp_set(&(a.terms[1]), 3); - mp_set(&(a.terms[0]), 4); - a.used = 2; - pb_clamp(&a); - printf("a == \n"); - draw_poly(&a); - - /* b = 7x^2 + 5x + 7 */ - mp_set(&(b.terms[2]), 7); - mp_set(&(b.terms[1]), 5); - mp_set(&(b.terms[0]), 7); - b.used = 3; - pb_clamp(&b); - printf("b == \n"); - draw_poly(&b); - - /* c = a + b */ - printf("a + b\n"); - pb_add(&a, &b, &c); - draw_poly(&c); - - /* c = b + a */ - printf("b + a\n"); - pb_add(&b, &a, &c); - draw_poly(&c); - - /* now test clearing */ - printf("Shifting previous up one\n"); - pb_lshd(&c, 1); - draw_poly(&c); - pb_rshd(&c, 1); - draw_poly(&c); - pb_lshd(&c, 1); - pb_add(&a, &b, &c); - printf("previous add (test if excess cleared)\n"); - draw_poly(&c); - - /* multiply */ - printf("Multiply:\n"); - draw_poly(&a); - draw_poly(&b); - pb_mul(&a, &b, &c); - draw_poly(&c); - - /* subtract */ - printf("a - b\n"); - pb_sub(&a, &b, &c); - draw_poly(&c); - printf("b - a\n"); - pb_sub(&b, &a, &c); - draw_poly(&c); - - - /* now hijack the char */ - mp_set(&(a.characteristic), 17); - mp_set(&(b.characteristic), 17); - mp_set(&(c.characteristic), 17); - mp_set(&(d.characteristic), 17); - mp_set(&(e.characteristic), 17); - - /* perform modular addition */ - printf("a + b (in GF(17))\n"); - pb_add(&a, &b, &c); - draw_poly(&c); - pb_add(&b, &a, &c); - draw_poly(&c); - - /* perform modular subtaction */ - printf("a - b (in GF(17))\n"); - pb_sub(&a, &b, &c); - draw_poly(&c); - printf("b - a (in GF(17))\n"); - pb_sub(&b, &a, &c); - draw_poly(&c); - - /* perform division */ - printf("Division (b/a)\n"); - pb_div(&b, &a, &c, &d); - draw_poly(&a); - draw_poly(&b); - printf("Q == \n"); draw_poly(&c); - printf("R == \n"); draw_poly(&d); - - /* now test it */ - pb_mul(&a, &c, &c); - pb_add(&c, &d, &c); - printf("aQ + R =\n"); draw_poly(&c); - - /* test mod */ - pb_mod(&b, &a, &c); - printf("b mod a == "); draw_poly(&c); - - /* test GCD of (x^2 - 1) and 5*x^4+5*x^3+7*x^2+8*x+1 [should be x+1] */ - printf("GCD Test\n"); - pb_zero(&a); - mp_set(&(a.terms[2]), 1); - mp_set(&(a.terms[0]), 16); - a.used = 3; - pb_clamp(&a); - printf("a == \n"); - draw_poly(&a); - - pb_zero(&b); - mp_set(&(b.terms[4]), 5); - mp_set(&(b.terms[3]), 5); - mp_set(&(b.terms[2]), 7); - mp_set(&(b.terms[1]), 8); - mp_set(&(b.terms[0]), 1); - b.used = 6; - pb_clamp(&b); - printf("b == \n"); - draw_poly(&b); - - pb_gcd(&a, &b, &c); - printf("GCD: "); draw_poly(&c); - - /* test GCD */ - pb_div(&a, &c, &d, &e); - printf("a/c == "); draw_poly(&d); printf("a mod c == "); draw_poly(&e); pb_mul(&d, &c, &e); printf("should be a: "); draw_poly(&e); - pb_div(&b, &c, &d, &e); - printf("b/c == "); draw_poly(&d); printf("b mod c == "); draw_poly(&e); pb_mul(&d, &c, &e); printf("should be b: "); draw_poly(&e); - - /* test modular inverse... x^2 + 3 or so should work nice */ - printf("Modular Inverse\n"); - pb_zero(&a); - mp_set(&(a.terms[2]), 1); - mp_set(&(a.terms[1]), 0); - mp_set(&(a.terms[0]), 3); - a.used = 3; - pb_clamp(&a); - printf("a == \n"); - draw_poly(&a); - - /* take inverse of 2x + 9 */ - pb_zero(&b); - mp_set(&(b.terms[1]), 2); - mp_set(&(b.terms[0]), 9); - b.used = 2; - pb_clamp(&b); - printf("b == \n"); - draw_poly(&b); - - /* invert */ - pb_invmod(&b, &a, &c); - printf("Inverse\n"); - draw_poly(&c); - - /* test */ - pb_mulmod(&b, &c, &a, &d); - pb_mul(&b, &c, &e); - printf("This should be 1 : "); draw_poly(&d); - printf("This should be equal to k*a + 1: "); draw_poly(&e); - - /* now b has order [dividing] 17^2 - 1 == 288 so b^287 should equal c */ - printf("exptmod test\n"); - mp_set(&aa, 287); - pb_exptmod(&b, &aa, &a, &d); - printf("This should be invmod : "); draw_poly(&d); - - /* test irreduc */ - printf("Irreducibility testing\n"); - pb_isirreduc(&a, &res); - printf("This should be 1 : %d\n", res); - - pb_isirreduc(&b, &res); - printf("This should be 0 : %d\n", res); - - - - return EXIT_SUCCESS; -} - - - diff --git a/external/libtompoly-0.04/makefile b/external/libtompoly-0.04/makefile deleted file mode 100644 index c14f34d..0000000 --- a/external/libtompoly-0.04/makefile +++ /dev/null @@ -1,56 +0,0 @@ -#Makefile for GCC by Tom St Denis -CFLAGS += -fPIC -I. -Os -Wall -W -I../libtommath-0.42.0 - -VERSION=0.04 - -#default files to install -LIBNAME=libtompoly.a -HEADERS=tompoly.h - -#LIBPATH-The directory for libtomcrypt to be installed to. -#INCPATH-The directory to install the header files for libtommath. -#DATAPATH-The directory to install the pdf docs. -DESTDIR= -LIBPATH=/usr/lib -INCPATH=/usr/include -DATAPATH=/usr/share/doc/libtompoly/pdf - -default: libtompoly.a - -OBJECTS = pb_init.o pb_clear.o pb_init_size.o pb_grow.o pb_copy.o pb_clamp.o pb_init_copy.o \ -pb_add.o pb_sub.o pb_mul.o pb_div.o pb_zero.o pb_lshd.o pb_rshd.o pb_exch.o pb_mod.o \ -pb_addmod.o pb_submod.o pb_mulmod.o pb_gcd.o pb_init_multi.o pb_clear_multi.o pb_invmod.o \ -pb_cmp.o pb_shrink.o pb_exteuclid.o pb_monic.o pb_exptmod.o pb_isirreduc.o pb_rawsize.o \ -pb_toraw.o pb_readraw.o - -libtompoly.a: $(OBJECTS) - ar $(ARFLAGS) libtompoly.a $(OBJECTS) - -install: libtompoly.a - install -d -g root -o root $(DESTDIR)$(LIBPATH) - install -d -g root -o root $(DESTDIR)$(INCPATH) - install -g root -o root $(LIBNAME) $(DESTDIR)$(LIBPATH) - install -g root -o root $(HEADERS) $(DESTDIR)$(INCPATH) - -demo: demo/demo.o libtompoly.a - gcc demo/demo.o libtompoly.a -ltommath -o pbdemo - -mandvi: pb.tex - echo "hello" > pb.ind - latex pb > /dev/null - latex pb > /dev/null - makeindex pb - latex pb > /dev/null - -manual: mandvi - pdflatex pb >/dev/null - -clean: - rm -f *.o *.a *.obj *.lib *.exe pbdemo demo/*.o demo/*.obj demo/*.exe - rm -f *.idx *.ilg *.ind *.lof *.out *.toc *.dvi *.log *.aux - -zipup: manual clean - cd .. ; rm -rf ltp* libtompoly-$(VERSION) ; mkdir libtompoly-$(VERSION) ; \ - cp -R ./libtompoly/* ./libtompoly-$(VERSION)/ ; \ - tar -c libtompoly-$(VERSION)/* | bzip2 -9vvc > ltp-$(VERSION).tar.bz2 ; \ - zip -9 -r ltp-$(VERSION).zip libtompoly-$(VERSION)/* diff --git a/external/libtompoly-0.04/makefile.msvc b/external/libtompoly-0.04/makefile.msvc deleted file mode 100644 index 8fddcd4..0000000 --- a/external/libtompoly-0.04/makefile.msvc +++ /dev/null @@ -1,17 +0,0 @@ -#Makefile for MSVC by Tom St Denis -CFLAGS = /W3 /Ox /I. - -default: tompoly.lib - -OBJECTS = pb_init.obj pb_clear.obj pb_init_size.obj pb_grow.obj pb_copy.obj pb_clamp.obj pb_init_copy.obj \ -pb_add.obj pb_sub.obj pb_mul.obj pb_div.obj pb_zero.obj pb_lshd.obj pb_rshd.obj pb_exch.obj pb_mod.obj \ -pb_addmod.obj pb_submod.obj pb_mulmod.obj pb_gcd.obj pb_init_multi.obj pb_clear_multi.obj pb_invmod.obj \ -pb_cmp.obj pb_shrink.obj pb_exteuclid.obj pb_monic.obj pb_exptmod.obj pb_isirreduc.obj pb_rawsize.obj \ -pb_toraw.obj pb_readraw.obj - -tompoly.lib: $(OBJECTS) - lib /out:tompoly.lib $(OBJECTS) - -demo: demo/demo.obj tompoly.lib - cl demo.obj tompoly.lib tommath.lib - diff --git a/external/libtompoly-0.04/pb.pdf b/external/libtompoly-0.04/pb.pdf deleted file mode 100644 index c15f7dcb78aebe7bc82883648f6b17b25a3f0cb1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 193637 zcmbqb1yoku(pFFjDQT2$P~t6kK}5Qwq#Nn(Mx?u>8x$l&I;6W>1f`Lbkd%15Wf}jO4Ro(z3}tlM<`BBkhLy?F8Uz2)O8cdFcoa64rit02SE0^bI;VAxgyw*Z?BkHS+bmNAj~w5uHp-mt zCAuPLvRP9C+WxAuuX;b*4?zFtdY5yu)FWq+)-upTW#P9lx79PZwIM&-7#UO+89f^d zJ8K<18*=t9Z%F9r8fo!aIFhTf0&hS$;LLDfzt~yf%xr8RbyVOo*1&pl(3h`sbCZ9) zA;%9l{C|63QBqbRXM-@aLZIYqtYBt#IGo(v&eT*L*yL{uL1*{*Ch8wo!r;(9t~?Xr z+d?7WxqycSED4Yd1OYygIr~4H9Q4I90i$A(wzklb)w3m61(YEmM9w0o=Li_<52Ap7 z6y>Y6!oc9aw^lg`i*Z)8+C{}BdPJDXqcP5WO+;VxJ8%3D1Tn={X@#)IEwP^-?NQNW zh$f;FqA5k~i`YC(mlu&em^ zRyb7vy*CT@mIwj@@H6>u6?w)Lo(5t2PICcum>U>S1Z6(Ufr_?ILm^3BRViIdHX$TCLBc%MJ=STK%z6bPE1NNGljihE@J9zJX*uSxzv1?|s#vxyulZ z=+jC}A+T!2g%0bH+sc~Zd4cAw8WB1a%j(mM&-K6sC(E02>9~F~;xpe&8q_{joHh!< ztBP-STHreRiv-qmBATvIgxV(ciog^rLtD(H+lC?zl|5t|ugMM%iz^~3_0G#5?B{@LM z9AMagcF7;3_IJ;MlY^mO9gCeDd>#M*AA>^4A!mLga~AdgyN^N6eDj;ve)TaB3~<`> zpZ}f_-Y49%7>8rEZ=B+CiZujwXHlo%i&inIl#U3aucj{X7QGd4*EG4kR`$fz;CX6G z1?~79)9}&`-ZHL*Cn;o$yo{7{n{>rupnO{etIiLZo%kz6ugs?-4IsSuVmB48x;QK} z%WMa}9n;lgZF=wWX#`_9qW15?!hf_wU^w zvP&*WgC@DTz8-RY-~0IlV%e}de1I%&(`anzgO9Fe=Dqwt_KHxb(RBNu)fLt!0q8+g zOhQ-bDHMi#hC*(HDn>jN_54(0Nph~&s-i;otoV8xz;N}m0PnYgQq!SXh(!bj_4c1l(rl)P;YV|DMjV@JIcQ=k4QtS#lLlwHAAp7ptO+r!I0@^IxCT#T6u|kQI7O)5=waQ&gBH z!>f>~UzIP~6aCg;(&~BIjr1$2`-dazk0-IWa)x{t8P#Qsa*NXYkQPw8>EHG%=6Afq zC@&~W3@P{=^z7!OO1xj63crD@+r?c&9GW{yPwVAyZN)lmLKzQ`<*~srQ=R2W<4?|?+MyD66^PL6Ii*sc z%5@yR6L2V;Ha30fD@tnV@gS?BUX{3Lc)WSlME#EM8!}bFNPg^Y`t_HCRs&ZV7#0*| z)OuKGv{H%XN~2slPfKpU(_)^I7N^R|n=4YG_*qGA?y>1U9K9q*39%;-{X_>|9je*q}OxGot*!pa-kCkdqN`{{59@eU+UwM3c4b8n6Pcgtf}T{BjqwVU z*k2x5y|7Z`lkC8ct^NR)pP*{6r9Yz;S)EVZvhVs$$Y{fmJkhJri-@by-fRbv>*_(* z%F-$jo+^FBTFM&Q6T&n@!qwrw3+dGd2Nt7D;2A{XZkx_(QzgF85@MscA!_PkDN!US z@Kk?c+ySxB;N+pW4+%}rF!HO>DhN!la?rzIf_w{ifMl2tL%A$s$Q9G_$YypmaG%5Lx8 z8-M*=xpCM$cg>zs1nJ2-oi@{PI?|l^Rc9LXEU(!VpL%h6C<46uyEJsNXTMLgq zn=OV8SJwtnFX5#d2Y0L#a9oz2V`zA5Uu&{Q7@aTL5(X7I#S(Uo7?!rLD`ZCwPBZZo z?=P~mm7s1tPVf)9@5Yepd&?9hjhJG+u|=6osq`05 z!gL7;TSt6OO|@4Cv|E@d7Djm!2Sr3zk1xcWPO*Fz8Gm=90D?FO#EF-l^*8@i4b(zGQ8L13oof2|c zSSx3F#W&bC%2(ExG?>)J@)IUpd$*!XV8x(b{j9=%M(Vw@n+Q)g zisD4quJ-MkoxVal_WpqnA8s@cwc%AlS3BuZ6UFAT#~pP?&k zzu-rjM3(bVa7Wl_XqhC^mxD-9>k39_Ghn@ORv=8-t)fdy3`~Oz+1-6>uE?ob`*D{x zOns3k^NqkmT+Xgtp4Hbm4ri0@)k+W%CRgp)67S823t!B9v*f1w;BIptok3T1224Ep zNr+t1TU2v2e0Y4_hE7R*+eewt2my-BZ+}ap5bzJVZu5P0XGrBN1M zb8`y-C99G{&QiAwIrIyp1d`qPtFtl)c=HRkgnmhd(DQ^1K<4w$U|(_~?ELoRurtYJ z$YEcu0{e0m*q5uozFYDCU?!3};B-JHS6z-Tx>QI~y|x z97GNU!I&oRNh&Gw64@&XoEuKs7;-R$B9~&2#1BeXgt_YYG1c(nD?C^gk)vww*kCp%99)8mn2+n*KAb>3ee#s$VcEIBQ zDr|jM)~_ai9=rdgSggP%0u%%o3}FTX;S>UbGDBhi$mGGyznc7cGWmCMfdLm}W#u3T zvjWr#kd+`ngn+~TQHTID!+tTY^X&FN%EiF}@JujrFr4*VPhc>VnFGj=U^rlGe`oV{ z+TV8)_M73Kr`&%j8yh<_41geDC=m4FXB99TGZgxFd-=0)zuEu42>IU>2Sf+>nNUFb zW<84<0PDsM`MXr~vv9w8!M_On--Ls*G6Qr57z_h86+{k(0mcXZyO{B_Y`=NJzYqRk z5c|0&fY_kS5IA6QK;-yKPxu!6f795%5B_I<31L0U;1FgGfPV!80EqP;;T_2DF7WST z|5@gSow+H%}TIQUE0ILEmEqicSR{vdXMrUtlWFa*X71FRnegpI$o z{{NTj*KIrp-T$LpUy%g>zL?p7&~s*7;BzvX4M04970z!1;|{WSol(^vIzY^_kut`7w7ydf5q`~{DI?z zv2*-&A7wH|!eoN=yz6Hhg(0(Jwh~uXP2r;vXp!O9J2rXUer?u{?{MRGvEC?35&e!= zCZWPjqd0>4#|G3Ma4rOn#w2Kmb!Rb`u-~@tGpf}IQvrWzl_K%|(W{AaH=A>d{h7fv z3~Y+GlPTJh)Kui6o)l8x#%%5eNP9eft1f)$-LR`Qx!ily4gZq;I*uK? zaW&*<%2@2HyxasE1@;F?s)h@tLUQiDARTjB@@szkm}ZDhCQoFHj*A#KI?2f`HJj@x zN~ZaAgr3h#V2)L`t}bt??zu7%jTDaJhkM1iQw(+}b#95*1T(hu3--Gk&n#?nz3Y3u zLuY)^S;p*;72DWTHAdAhc%~-+B?WD>jAyB+fQw10C|B(9ee{(*KUwuA`09G1)!d=2 zsa9UjQ2}cbN^kI?0k4muq*sEM0xwhUJ$JEeLFpCaYf)WV43;t;gAxS1J8v_{OxDaE za+iB_S06SiCKkXZ?57{g734f`E0=s02+B#<-|$wu932*zq>w>L8xQKsavmrm;=9qi z*^el71hg8*vEt{DKFiu6Qjjkvoi_JwY(UUr(kc3Qb8rcUXjwDgP`2B>M3y1M=SaY9 zU!&@&YZMCggRqoJEKjG8A3<=BiwYtqmUyqL1uMU2yB*&U6BhUexD_;?&;bW_2*{IXPQ~$stpNh<`KvGV4#yXI2gLe? z-vI&P`0Udkxt#Om-@Nr7mXJXG&jIEjhp_{w9(Z&xD^Pd?4h(|>Em-JZRYl*@&#xH& z{AvD2sXzc*0%r%rU<1TD!>Ftr%s?Rmh{+1{cmFCYeuMbG1N?LS{#(JI>;T;a=!*^D zO@NpW0|){5-vRuui4pc&3If2}_fY>2xAFfK2Bbs|0FInh9zdrI24w@b^B<)kfYA6Q zHJ)4GzttB&!+ohD0VDxb-!KSJwfz-u@_iqF#W!DE;@=7e0%!n0Q(y=jzz|S?egy*x z{D&6ytLcAn(tj%%D^Lot0pJUeh@A~i4g&!w=dV2SyUN&p-O69k#Cfp$yH4+UjQjRT zKR|*%!GOO?{U87;e7E>ofaV=yK5TG&DqZRL_ImS`4OQH|O;QS)3WT{QOxQM6nX2@%>AKoY6du0KlGUwc*P`^i!1 zA*E1L&G2g^UVP{xo3e1=-rJOqUK7-g^jXW)Zz_v5`VM$logU6mk1Mo^rU-aZKU^Ci z?|fYtI&Z0T4_oIA?q-;eaKxbV$zf@pN@#$VAt83ZPt!^uq0cZ5dgBVg2fyhMAG_f) zKK|>doHva(^ji18V ziX7l1z>vR+srp6+cGh}-XefM<`CrNf2B`b9>gOww2?f|z2Jj{t#w1Z6-e^Tp);t_%X5&v<=%rvI=Q3Imi0 zl;6J=LSL-(+u|R>-Vc?~|5rbM7xsW|%Wq*1DAoTu>_OyMFYxhSzQ=#(9+m862qM)T zo2yrS=GB-HeQciw-;Sk_^C=1_N~xsq_Y;&Mpv^HcevogVZ7f=fa)F|T@b2&K`_uT( zpWXLd=AYg7+ZfV6>z01+^?|@YmVRg3axTZ;B_q&J^LM{Y>-`h}z&~=5--d`l?4U2| z{_jIX$qJ&6lZ0^VUKLCuBQfI2o6_A2Xd4m;o#($7KD*z*gRYJu&Ght6irbTNT2VP@@O>d{Z4X4%KMxhk#e|tM9^k_Y+K9i8D3}9jA(l5^>wv2&Q8J967qMV z`v;qwgAbFDj3~F%F8jsG2jz>U22J<7Vz_Y(Wzhuc8D`Qe2$FU!b zFqAR}yf+GtLW>pg#Q}3p-)s6baSK0mqT=H{CR`UTH=5F1e@%q=um;A#TgN9#!t`ji z1{A1qP6w~K$HXBf1TJHp(f=!xc929{IEGGi6h% zH2AR5zBiVFyklt1qqgk_NujDZ}EHZ_}mpy{1do%UM(Nh_h?GI5?26=v*nd zqT?-+O0GihDQ5COnsRQ3PDujCL)TlURAN%c)fgW4DD6JNsRWjtO9@}rpnC4~6vPu5 z{Mk-F;?99n+ZZiHX#MjH??7Si38>?>L3#a;AOa}7kkc9^Z@II-(USQ7%Uj5wP)tO+ zle|2F%+owMtk(E$j0Y-;UG`6_!Q8N5RMn@H8h$8Vr|L@6#rH69FvMM)+Pa^&SV-qR&`V>a6!5@ff|@qY(PjI{A%4dg`6yuIi(9bi#+v z*U3>L=~&#*L=9C{x;L#B^jn`k@VFmIcW&fT#yhplCN`g2ySHSr%WC*lC{qI$tCJ<2JT9|e=r&XQM96SCgp~S@ zrc}3#&F3nTc@-H!b1$x4uVX40H-zuQ=lYLmW&Mr{htAB+=#Lr2u9I+UYaRz(q;L8R zRnQEUf2ZWELg-wFhAZzEu*hlr{IfoHHwQ5YbE5M0fWhed7rUZtj{CBN?a+zAd#^^Y zabH@;Y&CdpZ|JjXil2U{u5(9vweqy#L)_%FVo>}QF_Yoy^|iiI%HG{3xJ4u}R_43; zBLup^rEW~*;f4qIvXREeowb=a0x^3cW2@`t9w^tFhFHvg_!LaYsgo5`E;r?>&&@?z z=8)%Bs1Pr0WVbi7!Z3Rk<<3KgkN4ymr$tLpXLKtDO1Pg`;GG~Mc#Y}(A%6ef6Z#c? zokzi6;`cdv`g{2GWpeX}VGW=p`JTtlW=<_(DTp(d~C6 z4Bch+<7RO^TvL?eIBA;{CwBxh&v^pXJ=6qE!o}~b1lwl zF|#@V8c|7&@@l-3EYi)c>$y#z4wluksv2pus^@s=WZ4K4A^n3++LsVnRfehUjW61* zJ<^Fo?8k|8&)w{2(eD#de)%w%js^X+>ZD4OiJZ||04QaqnRTK1-+4|`?V>(Gc6K_8GO;_(rDd32kp{$auDPIkD8nE0aXyX?>WP zq>5UKDOJ+fl${Lkki3@`S0XX`ksu_@XO+Y8QuVDRQ7h)(C10PfNJj=Npp2LJ6$L_7zY^RWg>XF?QtY7XFeDC}~I5 zp0XU~8c3Nw9rlZ9@zzf`1KZMmx&dY~qm$Ae+EtTf!ULSTGBhl`9~SLD#gh41+*W#E z{ShH0j+9_}aDmX{Hj-OqyXkw}xu%qRfvB!{!=#WdRHMtgt_l?Q#~E?4+e8jmB&>W2 zZyQ+R*gpyy-w_7I=9L(CT#qhnfxYbTqcFQQS4{MdKj3O(CCVZt7cTm)Rw^~wvg`>- zQoA~N+p+hROx1ua#E(uMyDITY#PW02#WNBGlANb|H(XaMo4QdPxU7&i~ zGE5x?a`a>}$;TeNb=q?Jp8TkM`NWe`LsPCDbHU0|r9bu+CCgo=&3sfh(Xgf0g%!ST z1w{D7Vr@zii;mdRboC6#P(FU9Ozc){2B}BbM!MIpNoBgAuixFTzQ;h-w}00iMNBX# zK3Wb_p1jZ`zb?pHHJ^+WkuEh!JSqMYEtv{EIm>kqvRg@9pOuAac-V&JUyB`m5Ltfb zM?%veT=X$$T0{$uZp|FAq^c$rDsNfg1Y=a|OrSnAaFxwC)!y`o8}yvLjLA=!K}Y|&O(k4hKdr)+bB z7&`fM+0LSntG^kHUa$|Yk7l`FU~!`gvFCa1?xKI2u@YT=h>aAB8yV&Yo+FPwRLuFq z;~3ZRfR8hzWFl4iceJCRE?!sW>kfUg+Aba2+M9Zky<;cd(ydyNP=9uc)FVyXMQU>u z{KTtP(ikybI{AbaUtsZ$a@TY7P4&WS6mV``M79evHOx=F=WL0N7JbDS3a!0dF&;pej4A&EsD@#1E5kT~5%lI01@V8N2^e|uqUd2^nIgkkq{0E9qBnvOw` z@<^5$b>irmCF@G;-P0idy3DMge!K`P9TxubND@JIe{y3VKZg_^!#;~;f`{hYW^MLI zkGt=MS#V^nf_g^6^JO3R)nzV@RU1iRGRcX+^a=;iQY!@4^TF8sikIn#Ca7!uu=)wK zLOsYYv$dXI?qWC zXT+=MKJH+6Wiy_9c2Y60P2Q0!HE)8k8WKLm)>Y_@cT_A3H+Hw?io(&c#l}(}NC;Yb z6G`$+mTKTij=^h2#2ju8(~Nn-GF9VUikWu~wKVnQafur=>Y8s<4 zlX4|ne1ZyLoKt$)HS!@XR7q51s6uvs#PeffnBXygNyxr&@ubk0J2H`9VTXd(QSY=` zEGxrAw)4}2+X2t+dhg%Bv)idPez~hGtQa0?ze9mPjk|o~E+7E@{Yw-WqNr>!E`;SeTrf>V6lb#DNK@`47Q)8Ue}O5j z9Ez-fO;dy=8lAq%Sf~fPwdba1Go#OL}h%l>4g*V zE2w6r0C!=omPuQZ#_AN6LUGLbWb(7QX*yUdFLYr=G|)?# zGU_8rG@1)!aj!1Oc(^D>EyS}9V09m%F1KGg9o`%?4+A~EI}@K`;RWFpa!yC?G!kU1G<`<01>I4>A|OqL+axS_prxa-bxQnvNR?3mllJs ziCl8OILgHUn?8wu4qmr^ghIzbpvp%u!^x|wY>sDL&ao*{T9Q)_hg=<6my-Kel zcEs=Be{g|DG?}uv3Gd3=`?Lfyqas&tj=tUU=@N>g6qCZG6wSLe=fK-|@gt^ty|~;p z3*|$Rbl39`m^2mdVt16VjsxEOWi7D5w|PJ1#xk zp-;tt(GY-BeR(;wc^2wcI(Jqxde@AR>RZgCLUM##3Y5AU4C)FTiv()&X>hW!`f4aZ zv_3LP86xP)B~2=gb|g<<*pHGp*L%G2yHk-hXJhNsD1EOl=0dR$$?{X$J0}?wF=$RN z81`QJ1|y~kiYz=%dHfdlwcW6vp&>Fu1b6Y2d&!kZl4Y-00(g6xyBvP`Jq1;Ym)z00 zRm`I&2t)?;y^oVc7G#w2DBoM(SMqzbG&Q=&qFm~kxvLd}vevbPG87-yC)nHLKk&S8 zyqCN8loR$6<>np4#DpD7Y0I>`C!qxlP8D{zsY+aUOV-A*NfjO2A>IYR=@R*?n@-0S zjv;TPYFx#w#TBq$j##y7KkL^!u1ncUa1WJ7QNwhB2A^n&tzJ`n)Jh=zfaRXS!a&!7&K2)sb1vtO+90r~5Sp3V5ZXYVXrIy#o<0 zMJ{$IMm4$D5t;PtEmmavpcwWFGQ4Hl!KW!fOK^Evbx+11IA~+4F#S{it-^Gx$;-<+ zZ`l!9rY0hDo)YHD5uAD+yk?rBHCm23s5d-)J$xID+TwHHmg%Zcy_Zi-SnNBjk=6PL z29dG}=ME;Ge7_nl$H0{E2T5Z#8I; z*2;iQQh%dJsVcJ#n}b)w7l+xqZ^y^IxBGdQIKA_Uv=d7m<<9sD8ae~b#Q~mqi#t&W zqRvA6@lHbsfy4qNyoT06CZaU9NYWd^5eS`+siS=?7x=L470g>(1JFndju{%#!~Q-omG)#@+rd!*tj;XQ;mlGC{CaL>Wk<_)_Th=zWE{bbkxUe=#R{% zq?qh0Tx1&7iXcr`E-yoZh6hCPSd)A5$PL0h*<+6nq9UuXGF|lgNNi*{9IY1H#qTR$ zsx6{tU_h^>%@|=^HE)7W0&Mu=FFis+ zeMGtRI|Xxo2Im_!@MjAB%lVuikI@5%2+oqhKc-;5pEx>e51*wI&>s%?eEIBWnf`i! zA9BXM0AmCYU>Xq)jG#e)<0@=r7X#wPZk| zB|mF>e>r;u91H<)0??;oX5#=7Ee8acG6i~bz^ENCar#{@mb0TrEWBJ?EN8pH!h3$Q zheeh}UPkonm)_9U){>Kj#Z1fAklEBo+t$KN$J)u#mf6DEfB{I(-`fBG{tiO-` zfqt6L{B*KUU3PBL-?sL@a%4Z84gUcg0o)m|vtJLg{XA&+6Y2tt zA80b3JHX%Jsh{@pE1m*Ffl>Is#8UvPW^<$R+8Lgj>qnVsM5lg_BphD5lIuVcAN?X^ zIQn`xRUjUz3Te*U(?i?2xJFA129wOLXqo5*vhf zwt_k^hj+VjT0pi!>pGg27k`urR@)8_4Y6Z-GVy1JwTO|Hl66fwPl3ZA z5jTjCO2&DmE??jGAH>`Y6W1$HJjxrc@OU-OPqcOuV}wi`5-A`O;CjVpU|0UsbF$*2 zX+OtreSi32eSryn&+T0eAlR0XLq`k>@TD6XhEb7SF!-9;oYScm0 zLx^lTZYhLz#bEt{LQJAhEXPE&>n(@?>+IMO!)&HCfp}OZk4+V?4XI&TC^EAL4c6rN z+h@>Ex3ZWpb$3aOCD-zZipp3&nC!tl zx^7LSh%h8EW~tLF@jzQ?G*pl9q?ts3(WNdZCzDoawC%+xlCXDm9wG9Ef$D}<)B!`5 zahZ6_p2mWGb@Pou!==U7lW8m`i<^0AFsv!L(klluJIpG(ONrhU0@peB*~_cf#?WtB zv>d*;^@$|tv-7zB>U(W38%)G&C6qLtPL(6kDX+sG2-*wsFh{6%N%DYO;^KxU9X4ep zsVX@#O?NM>y>!H{=Ww=p=89J(x~JnU1{n}AT=2eoDV%u!ttSG(hJegvEOLY!2gg0l z@4B}H6gZ}ZTAf(chOxt56~`S7lz}@Y1Naa;lM{BwJM?leJ77j?gc^4HSF8oDs`8P6 zJurwbP|>Adr)b81jx{7>shkE3;68~!%#x>Mg^mr~hBv>d zq;Yr!Gvf%?H4FmVYp*Dft^|4Xd6!z<5QAWp@WuD!cQ;%4t$4(Y((u8NbPq!&viaQa zB4S8_*~>*L1sB`izpfU3yf#-CY~&u>^d5O9_{0^J)If_2k(c9faXIr_^&`KH81_wQ zYx0EsNu8zDI)We@|4^Psb+N%Ng3CoLyD^ILWf0zPy4KZg)WL;^ORZSiLD?Wj{wE98~)uj`6WF5P5n_@6jyQD(DyIi z-m9@&E`MxOPjpwpgNTk}_*wekl!f-HX}>_*EiEkW?0}7KZ7)&tc20VVczBQ%Tq+J% zvM~PS`l5VwN1jU?XQsTWWuZac9+`@=yrpcEv(VVnqLkOLhLK_FD6OOY!-*b@3c2c4LXFkOCCbWu-5krUGeoQA z4gD@5tlqj|s@%c+83EuO2I4E(+tY>XxnzC;%AW~k887%jkMaq8cY*6QU#yqs5l34^ zqI_qu{y2^uHRjF(jDYy8qxoWOk#@UV&|R-x;%7%s!ZSGtRA{O+(Vxll&35j~8luZA z@|sL4-&K(<$$z((R!TaC>`eGxqoFvbyCoVplV`OYqk5fafmxD64yQ-N!-@ivq z_++G?4Y%!SX+v?$`{oQ+t}-#VH?Qg0E>qn4jN14?B@+2%CcDnfVj=sSjC-99hKC5| zp^i#Tk9OsPRuNN9@Q!M`-3g>{)8D})<;kh+Q9jnsbw)x-U^L=AvkcdV=9A|pjhx`6 zqwOrbEp9glyf_v2eM}x%&q;0sIu)kXgm~(>*!1j4y|)V7wiq<+Y9IaKa>DipM8e2xp?bB0An_A*X$!`WxX*njeqO@+Ka3xqL`z(ylr4FU4 z*@`!5S(ny*8mn>=sFlKClO!JsBEEG$(SR~5W=&8MizsCv%|t9{QPRkV81L;Z{p1U^ z%Q7~D(u0NzkF|^iNixio65u83x+HFmF&h{!_yo^jkgfr^Ud~Hw*yMzt$2U_8*6!&LI7t76S+M;D4Ba z`K=`*CpZ{g5Z{@(RHwMFifkohNO97`Bf#d4GEe6VrpR1=o2z_>T6$%_l z`t8Q&yY=nH-|LY7MEd@CnCXXR{m)(evvT7bF$|2nf`IY=v*H{0(%G4>Z^ZBqHOZ6rpZtm4;^R2dbFoV=#;G{5G)WF<;@MNO=lk4 ziFjm`NFHY9r1+evG9qbhVdXZv*p{9bZqVfzT#oB~Xs?opZl(xt61+;jA1=DUJiypn zeBgXHXra7t+ZaDcfSz(jVBvl5YU>_z!Xl%CzH7-HMVpd?oBdrc1miM|3SDYzl)bGA zj}NonKj|JWz)uCy?%Q2Msy{C65Z`QH(R9`5|CHETok*tX@+2fMq*LyNP2nXwm5C>h z93X_T0+Ja4C+Q~|3r!xKAfp#s(8O`*{djxZAM+iQzQ`9SxUIqX;fnp7`;dx;D*LYIrP-%r!4EghHDBXj zV(nD3v{CH3YS^pJOKF0;?pMxOklj9d9TA2(C-5FcO`SMrLd7~~)bmBhm3M?Vl~0+L zd#Q3)o!{kizWWeV-?^6%TkdFE5?h-c_~Daz>h{yc_D6%A!NIk6);qhLDXn?vmL~Ei z{3Sx@ee-VLukkr3qK)mSq+o8lQjnN(9NfZRSD}rx7d`?XN#ozWKDBHqh_n|yWzu~* zGQ`EAOWZWY#?)PKqsq84u_fVxSM_^|4Q}QFkO&=tY?=J9q6tSuojR2>Zw$CXSUK>ZixE{A#ChLY5oZ+7i-eNwD6fehU5@yM1v+24=TOI~U9M}g{h+g@C5jzrkT zfb>zL>2t;PBV1i_M$JBOFUokc>WFx9v)@coPlGs8GVK!R>G-o?wkLH8XlO<9vkPGc zSFVs_Z(b$5849%__kHDQnrl`lkjN+|wUv4(f?VPAOy;UBva6${@`KH*J0;Z*1mL_k zd~DzsSXvE5I_)9v@p~OY=B_Ds7$S3H#@XlCTn{lz5AItCC=tuLLbUZ{RC6Qk;L6fY zJCW(a=rQR+c;L26-4ml|gG#P7eGC2i5Ze_y9~`|!+Z(FS#FH=S-crgqQhlcg`nJe&Ptx?u zmGLTIB*?CB_H~ zNG`BvYT~8D;EkJqs`e_TD+O_CS`d%MJ|SR}CC2u+Yy!WX#O5aLv<$N^;^ohG@pmpX za$gPUmDAmw&<$I%;$GumcE-GhPFFl%)yv{c$KpAp03+0E>}dXQ=R&62jZx%GBvhn) zw*Uq1#e>sL*Rapl=%(_ycO)7gepFN>YI$*MwqpWK^n&3Gf++e0;vnkQr>VW=MWTTQ zYB3u|d+RmVM7+j7G>@>to!d(cLFvJ9bXC55GbT6o=mg!ePa>uYrYo5+`9Ii3)-}iC zC0n~all9B>N3_+RRJwV8nu^cIUgK#f(%-OL;Ft438T^m9?6 zu@rN9O~3mEm%b3p9~^sy-)j9ujL2ONgl%jB(*0iah-)v!UV#P@3>Eg zOO;jZ$!t7xW;@xPo#viM!o5_P6jUR~_!e1Io9aRc9wR}jM@OMeYsL1KV375IGKM^p zb9#!=lt$=ocPvZkrH7pfH;H$JS?dr2ef3MC-m?$jsWDiM@jBBzQJkeMejE*FvCeC$ z-Dp75T*O-B&pry~q{D75TRJ=*LrS`xDeiJ$!s|_L_M&#SI z7A#?%i}js@hsLk*B%{>B)bTM5P+n7L>L`JTP0bHBR9p}5Z+P8{4(8XNMm!ERr>919 zxJ6wNJb&RM&5MV$7pIAdb*%U}`~}ywIa+6Nd+f4kba-4f@#8pD`cdbe>EfCoivax# z!f4%tLC>3K8Vs6F5P4sDqwh8aRcjlhezAo+^U5*0`9rg z+B**@OKe@X@9DRjOA2HQjw^uLbK!G!7fWD zUpvd1HyrNseKt8g4DL1VqQPQ1E(xZmNDfW@F27@6fb9GZ7ygWW&k@DX*cUkc^6#)O za2o#mZO?Gvxg1}i@7H7Oz)60fx9}U3JBM7~klcS*3J~bbkl$9qe;pM4!%e{)0R8@l zrN7RJ{$c6aU$}t&VLlafuB~qpf5)CbO&Rv^VIy z=0zqPDoY3LihJ6oQfiFtOFFF^zUePQMNOi`z1TTAK`E?Gd%rHecz#7SDg5Yo)-6H10fzBvvnRENSwJ!La8p0xWF zn?Y@{0;m&1?%d|%S7Kf~&$2cXN|q5>31*ar$~;Wt?+mQ>@@@E|oG3)JcNnTy?IId?>(!}c?_UcS{T@hH66 zUC8i(`{w2hNIzj<@3~R64t%LA%U~)zU(K&20y$`Ih9vgIK2~SlNpk2FETl&m$ICQa1>i!Wit;yx74_+ASJFyNtCVWc7zUc-#dD|V6 z*2eTmS06lmi6zI6*_fU+|0yLEM(7;Q%9t$3f(7YH=9i#+Uc$WoVV?8gz}PWeOjvDD zu`M|b?aBl9{e*^j4NC$wy?3Ke%N&~T=01AevQ&COi`ZxAG#2$r{+<|?f^_S_T^jGY za{k!8M|Tn%-A@Ib=9c6h61!z(d@!nqI$y55s zC@*hJkBc^yw{PE`g51VsVLblWB%&ZHA1B7TqE=K<{X9@LS50H{5=FFb%;0##teU*9 zaz>C7QgcvF5ShkJS^q#Hs-T=im%x0+wwtnQOjFS;in}LTY>Rp&PkJ+88A-MEhcxT5 z4Z22}K8Rd4YQ9V?AN+_|hOc@Kzqi$T z9A7NU$KvYd`XlFhS7bs;1VzUMs)G?`xQ(Z9mxIHls~t$3&b8xhsr@y_g!-GVO06hZ z45pRiE|e|R)poU_VJkbib90=gfpZc#SOyJi;`>{h72H@IpY@xf(ewNx95rC$wp*N} z%0B4Kx7fTF%0}-Nj;dLy)`=E-u&KVI-s@39Bn>F9r*daP+g5m8rQepr2X3}=$GWp@ zsF1Dg>b<{+))e}or8GCrGug7QCN!abl6{xLP+cKRwss9CW6hvnM`#Ju<1g}9bZ2L? zIkV>OoiwioaF(3PWr$~@%*iDbMrDoOq+1T*JC{Wrp0uLH%-WKW9UWq=6}@W-xB)Ib zA*p>}=|%VEx@AL3A%2fVVg~kW>?L%qQB(W$H;-4=%%XBiay_Hc)SgWcu+DKPs}aPu zK$R@tM+A$BUB(H)e={H%siZz-o=8KrN>Grmf+Ur4RUnLx4E5p!s~Hap?%IV>4@cDO zI0t_^R%9dO_2$;m={{_(vvJMB*YozUHwx|n|Xm8ve zUSX^;P&u@@64=y*a+Ksj``id^$KP~<=eF+2@rPpJSe{zFW2h~S+Tt>w#_OnTPTLbs zo9he@Tbwx4o-{c1F%;XSV3_4?nO=l5^mBaZ^e(WAhkRFXsW=iR{>{)N$<@!uF%xHAdVx(;iH^@WJvFdT$$lli6T0)K~G&edsv-)EbU0 zun*oO34Qz1xB_|vT*7i&4H)<5;&Z4r7?L)EKNWA=bvPG2tCq2)FFtX}My(4cnM`!JlRxY37qsX?!z(d&OIUaA-2lZ(Qnfg*;tI>+QWwTx>I$|3 zTS`%A#FHkYzNI3&1Pr4{-CR7TcliS+kjmk;I-^<(YT?(ah9<#B?{J&q!4i!Gj+O)q zZysy}tG3?qzD>{tS`*I+kYu53*2R)(S=n9FK^3xXj1B%ARE6`xWps@;J@KU5_T<&0 zK)F>)5yq_0rI8$E0D4?4cRygl>(@Q?G=G z1EI(0~vc=+odISM$1RBjMD&R4nE_?xBn$YwEJV)JA<)G7FY)k6nQxalxX%j~!PQJknh zmc9A{fu`h`NEK?vBIgdnxa1s|Z)iB&(0VvdIs0Tu@Zia0YNzlUKd!ExHjGiK09M;p zzG?`x=t9}V<)lu}<~Q~PPWf$#4`xbp>Co^Y(@H)x6N2NUBZo7E8kZFOrPYW|k@f6G zitCmgFc~}*DEBZ|E=Z7MDfav~9R^iiXqf5%&b&(sY=n|A`#(Yl6IGK2Y>c&u^Oa|9Bldv8~yh~d-3 z4wT(tQph1+v3?$gKLWX|PBhHX^gJ}vbRuI_@sQkl_k<@*Aco*co*ws8z4*Ixr7HGy zrP8S=|Hs~Y$5Y+@@#C@ySy>@ulVk7f6|y(Q!Ld2^P9$VymYq#yq$DddBAcSf7AiAR z2z{?}=#IMke7f(?w3P%^?W&PI~KY4B6b@#Ds!R3<@xf_XGoQtOGwydgEJ=!+e z=ijTdK6&y1%g4mqRe}0BFL(GR{Z?o0hooV-Po8IDOE0xij z-zsq4|0Xf_08AnXE9v50CqLmJ0 zs8?N{*T;^p|BCOmSj#w8UVZw>C0z`qwH=@FaI28oPP#AesZHL+J=P$$oRi0}|1=cx z0ecn$SAvT%;r$z9^KidJwQ+@8!ak`sSGrf36TiCmXB4KD>glX>MsU5%7R;Jpxb~@n zz%*Hi=q}+|EsNxh&*$lV#Yt)ihbJVoa*M+C$!Qks(!E?anG+d>K89hVdyp(ldSjtT z(Krzs2p3OB(>#^mB`jLgJW0<>Az7R)(xs5v)Z0<=mZ&m+HJAz8DL=0ZUD{-%Q10zS zA@zf|!Fwmf2{Ri02LBy)kNOS%L;6A=aeUjS9r_wDyO?+t1u`JVywckZ=|0VZR??zS;)l@s;ggn!tS|q;k^hI0bW7aLZl~g8YdE) zlhK)bem8eqcRF7@I`P$Mxb^#(fU=fv!{0_~BbxD*TOt${WcAQZ{6%V)Ot-I&Z3Sti zvMpn|P?x(&5-u*%l9fViX6MM5lf0}0atu%F--pw!?$UBlU;O+k!w%-1mm?(f0_y3R zdq&-+bn?M)Ot^r$<;%y%mvES~Yhpt$Hdfuc%rtzD^>lWpL3uItRAbp!a+CHCR7sDG zR2gpDEm7urQ&3et%}_hb?_B1X%RDw!7i^X(KfD>Q}`1qPAhu&n@rNny6hePVXJW-9n)~jM#PD^h4@C8ZaBJt z$T>37l4qxs%V)TRo>bl-pljtRe0FK;n2|QIFz+c2R{IdRx^}Vv#?H%<#v#H`*qz54 zEi8-FJiVKIMrl@)9LL&1N^xg(5{=wS^6NNmVYLkQ-BcT&KZE6`G)nOB?6Nx#B@LNZ zH0Mwa0~FOYbt ziPE&Scpb+_YADerZAS{4o)Ny@G8Wt8GL}qesBjzLXUE?)$PanFs8kRdsZlM1M)ygo z!r%MY@{E*dRTeTGnyn$X51xu@B+v@5qrc!V_dy9(A_UlS51I;2mxd&lh6OX!8 zgK)f>Cmr20Ul!6X!UuV|ArhNa5Il+OwzZ^3>*KVQBFqbR&%SAvzZ#4hOXZ68oN$i4 zsrqI2)v-&H4;oX-H?eAuiTM7qtMPIlwwM3yuD1X4KBCnC=d<^BsXt^y`M#_D&}#4k zcibcE^?pT;sx^KW91UrJ{=Q~{1^4gr{&t@@+}_{hzZd+k)hXZ< z79Zd)-uGw!$?kr{*8ama_|Mj1Bumuy>K&}ZfD-6nA^z`2=_~Z#IE^9=6n^ywQ8J$n>?EQW4GhnMivA4jLsms~FJeV!;6?;{>GkT?7=r>Miorm8WuxudI7 z$x}}stKVnvtd6dXTHB7g?k%slC^PrPRF?Gm{>5?C*jAZ(5#vCtZN2&I<4SDLEuY}J zQ?1`8QYuBIc{X-bg0bQpTG;_ZnaEtdnVmYUBq;vc0w%TjxCGF>c`@e>}Tu z)&B3$#@Jt9x2jwC=!0$WAtw4g{tH%h=?($-ZQO=7sWv*xaMSFqb7pw;J_Awxonz{KgI3i^X+Dq~#wLUYPYrP>g+P_a5VX zN1(y5wvZ6OKr`A#Odd**8DbalKr{G)RG$bXg)FagsX)2GW`nydEc%O`b1tPxph}j> zm^}Ybc0`Sx2f_X@FnrfsIv>*AFRp?oUVw*&C*g2{Uq8%ZH$h$siTuXeeYGS zCwGYqamH=$VilH{8uawu(PQ%w__#v)lymsjJv}19C3iWBB|r7trHYCWYq-~%)O%-z zhR4Ujee(X92m!{AK>`w)Y#m7MrE{BJ=Qm1D3js0vBo{*;!XC6A<7+E97skEeW^#` zLG}!@ZWz0~-bUmM+v0|MKd)c^UKYmO1Bq^-_n)l>(4Fjr=0twYfA(z7cG@XPXPb%a?#nj5==ogStP3YGy7IQUd(dtL`Kzw`1hSA{ z(tJkW5)u_`T|(=3>f_1-K6CRP&!RE>Dzg^qu3pln%?z&8^&1OC!S~*r_b*m@`B{h* zucC0Ey@62U#F-LSo&xvPTDSTvTLsn`4QVxA11W(g#btDy;XxtQcxLcd0mA1=phTH^ zpW|Cnl9%pQkVoETAlm8ixPHC#OkiLBONI#i(Da9|EGc-ONx_CN&FjZw z*fRBIWV_Rvswi_ul~c=c6Y8?oA@(?t)JEev3M$6LnRr-QCJzA#mz07knG4shaQ)T3 zlCtH_cc-6@z&WbovERrU96Qcut78#NhE_65X>&W>oyqS;=VB|yHmc)U)s$cNq9g2O zf4>*)6X6|}uy~P#X<&Q$_j?hNRqy+{iP#g66*+3M`|VzI82kPv?{D{_pZCDODVLuI zu(g46xj(yo9ntLnrd$L+J})?2@^fBZBz@rT8VsDhknwTA!DDbh`PU;i`yKv0_m5rh zu*h=ch|6!}mqRXNf4IFJHfDU^-T>?PpNbi+`YLX~|EqpMzf3|i1Gg!Gu7IV@VxH%G zVf3Jig?bnnTbj1AjuLz6*M-_h45krF^URTt28@BN=BFnD3?i;S&Ags&rk2V&6+g@$ zt(Qg_;{=`URz(k&Cp5&fyachn&o$7_lXSk=*t9xYxk)nMLjNm*YEa!nIWn&+ix4WOnlR ztj^PS>B>iDpU5S+>YU`*rYMG;?l*LKw|J|rrCTY;YJeFs{*Cv`F(1*mk3Pd=nx68b z8cKAndp=Bwmol!cI!Loh_RO<*D?N(ERh#2A!e+&?*umi-yu>=w7#H%0R+!snmxzX7 zpsMJ(f>d`?`!&87Vq2XnrzfABIHQQtJ56|AWBTS60tTq}-~Xn1EsPd#?$e<61D(JE}En=>+7YOJrEP0&UmR1vDN3`-Z)NyPh zAvwFI)?!>3{oYVaywCfaCH`f21|wK%B&w6|7Z|!`b$Bu+61NoV9BmzE9oPFbuxz3< z=!lyh@%7FG7G8c%GmVB>%FXFzh{l&9S;mq2aH(Uk&kE0$yNYe(@*oCh@Ec4D=XdqJ z574<`SF-2KRb;OjYQt>;Hv;?5HN_9Gms!V-ShVPcWxbScx@?GXr!k97R29q&tq3Aj za{QX9gyXrc7mBdpP^SrT+cZ1LRbbP4c&#BatJezMF!AvC>i9;M%rwqihsnwAShs0_~d*l zb3jJhqN|3Nlv=?K>%LH~U|^x@DI&^Jim;lXQ+u6@>jE*ZHdy1m!rENX%TpPAQznm6 z&d+I)D-15Wetwg65xa&A4W|AE10N?;{0s5B4oRP_!8Yy9ve-9d=2LXZW%5*3H$x_w zuL@q*w4A)bqe}He5sz<31*WTO(LGivcUhK7&XuF#RteTi!kY=PO*FUTP{;5z6O^8P zHJ*=&yO^v_q{lLVe?d3Co^y;dJ;N-Y)jR7|vk|itg&oPgFfKG39Qi01YhJkI^vSjv ze^Zze+E5F*TVbG%UV9BJTCGBzK90Gbv_d)gq1|hW8&oZHH5BdJ*G>u9x%(0IMi|qf zp?zL*+Ur{L*Pc(lLb1rb7BH*$HZPMvD>x+W`S9Rd&JQOg)mI1mK&;|*N#n9%{cj-{ zxdp`9EKQ7YpB=?E=o=YPZ}hnNN>EY(+B+c~KTcx8!lv`V&?n~RW z1k3R~rZzVrTpzM3V#B_ko;Wc(U(3eXV0LUw>{0=o$wlJjqlN$$r&yK`+m{F`*h^yc z3GszAI2*~Ug@}(Uej%@8Hdi`Lgx39)nfzpCpYWTxPXnGF+TvQMW6jx+mV&1HH{V<; z_@*#`R=&`B=B-9Z*wd#psV^`@IVUw-WKhLWf>r&8U9xCrTGkyPi7?TdFZ?I2%;LVE zTv%255|8F3k~T0;PgqxG7KJ(zFS|#^^^i{CG%M-~{&Ov9ya(xpgpMB`IEjaaU@q0O z)%FCte|=iHLq?YDHsV-?oub_GlEE^_FetZax}p7YN9x}|g2P+nZy>>eh5ZMG2Z&zt zuf)?Ir;T|J2s#fdUH9*O-}mv4oWM8nQgJ=|hOdXtS<^40N z>mN$jpIOU!k5Ggn!2qJ${!ExY;@0q+y!=9lNPdF90*NC8uRmwzL7uEe1PA&16SVuo z^u0rW0Et6*;fQy_VddvxFZM%<&?64*zXc?}Q+@s!3;}NZKQtGA!4PmP9r@pXm$JJJ z&I3OOQUF5;CE{#_GcF6Wx+)!KkqXSSvCmx0%3@StkO_~FYyH@;;#aPecwU5kKo;7V zKIOmuIocd2MDmu6^qtu7g7oAZC95Kw3uMk~p3SH-O44{w$J(J>cbOILF|KHCZdk3Y zpSnw;7CyvKy+vBBWFIcLY88;Q_n1@Y;;r&WBUaViqPoLvXN zzPj*iKwe<%)&}0nolh66U^S+_HB@RN8_QBx&ofLCDUn{|Q67Z$xURDsOc0|*qT7r=6%A%hGcZ?QB%)_Eti!ZtjkV+3^&7mZ z^F>F~06sEDbi#5w$KOY)rIP(J4+h{dbc$@kj7gJNuu%JL7yevXcoVC8_9H$>xo&1bdfi9GFrIkvbLb>sC z)5p(Yvw%?jvNUDKvrN?~s6V!U^M|q$HKxB-66%g)okG96GJ2Trkbc6vsp$=7k6iW#pmafs`hskulmOU|GmoBEpMl*rXLo+q*s zj~|<=c*fF_(fi3xGy1J@P)#{ucP7>?Hl?N++i+jp_ZNrwxspzM%El8fMmKfRYvz5@ zSB$@IzdOdMN6s|$z=UsD-5j@@kAd|RQR3_A@DCc41TMMPQL!x;;koHws`JCn302Cqzo^dN9@1rfC*H%w^<_HC)ym)Jy|SDp zVdu;9Cq!Du9`-L(QhP^bVt<-}1fz6D2VOH{S?}+D`1vLgFWu!k4}62K_-8xm-+4w` z#Blo=6zA0|@4#(^uxyLf9F9lFKjG?C-&9O82%o2&oQs;)Cmiq*z4|&kP z+5h3z*9>@0{^6?YeZ-0NCN1f1xA*u3-$}ccSx4U9KD`mk@aK=b-%6<}>Ljy_mgms&7A?sJ}z@Hwud*G^u}&PLR9BQRO+34g8-g zEDoa+B)&Nk7zae?JG3qRLv(^L1#^Qfm5&<{;sqT30&xHYK+pm{5I>aXkK$kc04G0( zE&=A#Llr|{1Z1!MnRbN-MEm=(+5RT;@6;9<_=NI++_9_;=dz&zvHtopQ5qrs=W>#LyWBnBFt)eaRRe&S#B_$6)kf#k>A?d2w;E z%ipcIHTh{KMd8)_fvB@doNDnO&H1KhP9;}U;HdL#Fuow@P8fdI@58HRXgBEXS=S4D zyhDg1vL*a=y}x?am=`LXKuvk3^@Sv@Y0vEoa-Y6f-b=iJm!>)+e1o>3s#Bki zi#Da=>^AK!(pl!-p)8V;R=ulpe5$$}-zrQ7+pB^eJZYyIt>o0;o4MP^IY@QejLKq^ zM`@eAcTTGES$>2Hg_M;^WA)G{t?_361T+@vPYD>fy&@Tm9Pca$)|lf=SLCuuim7!2 zT0?Gcx}AwhHIZpE_E3pcPn{&bKVFZrO)fXY6EV>BS}M`>#a#FNV4XGf4UI(nI?m@Z zbUFlNW&x&Rm?f;VCjDv_lFohml=p(5#7#Zna~7FWx(qI1PuABi$uZ7b z`lHU?wemu)Pa7;7rXz27D$X}NE)vZ>Zon0=U>F$8!o;b07fbHOxP|W93nrYqmFwz{ zLYdl_C))0(vA<@tSIUrD-pLz9VY-|rgUVpP-|od8;z!d}@2j0Dt9et38@f!UsQn|;=1DT6_8-=LtS*-3tNA-tpP!mQPg zb?>v(k1dkHY9El|Iv_kedq5qOkXW z3MSkMFtb}oZ>@g#&FP$e8$~T4IH3~P^GJHaaSX>}j+JK5>|qFz^N4U4F_xKgm<`8n z!7-)Paa5dfdz83Np~iOh=94LTcld2P8@S#Rp^&uqZx;W_U)s`tRmc(xN64PEy#kV~4o~s!CQ) z+;BSOdwti@EB=-`j>b6OnHk3pUM%e)zDLi60`JJYFuTQ4#mXAs8sXsRAsO3A>d8NP zJF!#rQJAYC-Ec3g2wsWL$hSSNVoRl!da7Y{%iitl-HQu_Uy#JWj8{=7)}pHq zBW1Oi-L5EGx^yyJHu;;gzU9XFd_#7?vd65-(1;{k52T}caKx*~`~g)&hM5u6e>Lyj zR(;`ca=z^vnx+JGoh8I~NofS%lpKwLS$Wr+NJQyY^Fu)?duDV2qm@twhj??J*8^3X zR3^EmvBu0V2+JW@H%QywpXj1&GcS6HGh;#>Q$mv?`#>Pp!Ja9xCO@c174~~Cpvqhgp%0S6P|8Y> z)tE{SHHsh5f4L`E*n{R(+(mqYzT=AzU5fxigTZDz-bkxPBYZ*6OkfnPx#j6Bha5qx zIg^)6Tkk#dE1n$Kk6%5Wz%k0y%hW%4@zK~>jn;K)G`Ddx;<`e9v9!F7vAN0U;qD+y z_G0J*@ukuNSwGek%=k+d2JB)~CF5Se?YGpe&nWh`el{hdP)(f%b zpDv}H+9DRL8I`OnW1E?zlL<~G30Bn zhjN8-8y_py<@!@u1!hSgy8)f_|hIfdYWtnIZJCVuW|Xi!K* zirU+<_NfM1nF7w`&HHc768Y6w$=M3c=|84k@LUg8;(@fhJ zB2G>kBiED0GfdH8#z}LQpem)ERN3UoJ6jvejkEW6eT1^fo3}iM-*78%q>QEBEkBd~ zq;5)_wM@crGMIqHym7j$;X=M;2f+|OZo>Uqtaqw=Sc*bM&A)0L|2uIo@2|wcy#J6m z_`6fgAzXhDarTJT5qa-Bl>CRd9^tx(2xQL-I0KO(9Qihk zA_BORe=YfEf#h$x8xewB1RUV}IWq|P_#dkMUlq0gkXQP!a`v~P!(n;hsE}~j2kMX{ z@kjCk5FP{((;Kw*52>elfdTo4pm(6p6#;B6e=0nbBpa&(@70irU5*_Jl?`|Jc&7zN z|Gh_vdU7`jr;kmOGBCxWW0-Uu~;{grCq z1HseXythoJQer4sLUf4nzDx+FbG|8On%L}R+Df{qyM(e5HvHy<@_h3*^R=m7vYctm zD6*|GiBtYHciYrkw^q5uC`w0_3e%5qbPs(LO|=qF6LU85RL~v?)Gno5diQ2qP_0d#Ji`*Axa~U{Y{d3NIDC!Z5|5phciv2I z@|W7?j;8ly{&i@kxMq3T>PEQ`#ryi+QU`g#q_69hk|L zdXgS)%^r7Mq{9}EFP+kKDIQHE#4!4@r!>s^nYAD~AG=FOCjZe^v*%)|ii_;ggB(g+RQvcP6zJx}SL6WW= zm(K2cUV+E)I~bMEdCNDRpA3Jdo-32w| z9uvBAQ_cO@RsB44Vonur3W&ms=l3+%zJ-zB2%589Tk&=bg=5@)XQ%U}-Gm}?nm@(s z3Bzl~Rk?&y>6{5zGWS2zy`qWsdSyy@T z^UVtyI^H^h7w$E2#IxgEinBv4*1hM#saz54A-T1XwEppyoL9GYNX!^lH|@QdljjrB z6Ipx06dO)_V%j8g#H{lTvD|!;VdI2;Ux|s)hP^s-bZgA49P%l$%lu^_o>S9^966)6 zd{{5E!XM}LL@>DWD&{D>n2ciE z{c>cEpd`VPP0XmW*=QaccnL0j5KGO1m{-+Q<0B0^#6XdVb3T~QEIgG^Z9kV-`*7)m|4s2~de&v6!szWXWM^$w|xARZf0C@L# zn{W?p>0tdsEJeIvP2B(7x6JYKBdwNTwMVFH!1o87`amgkkluH|=RKg;=LKOV_n$j> z-vPTm?>@0IV%OOJ9$3tf&mGVugJ=T>>4WzjaLw`}d2>OzND5rU=Ry6Dp{@|=gZCY< z&hqYaf*n;kBHQ+TJNt*w1jM;SgfQS26abNa!C@30U>5}gz%L|#KrBDljp>l|#-K;( z#Kq|#+H?>_xDK2SB1gyS47G-F{i1C|_Vd536M`2EG>TtDuQU?{QpZoA;$M#_mdD{F#|?yVAw^D z9RMz1o`J(eT*AVCq%QvZenS2h{)am816M$P9>Dbsw5lK+E;5uYKQG{GAB(R?F0YuIZ;3}XH2T~Ics3f9tf4oEq{nAl~1(1I@ zqd>TIz#IeW1ZW8Pf!P94CtK;{%+G z;MfFWFhO)?P)Edlkw5OJU#IzDS?eFx30RK6+63tQc>!%cSkn=UIiSu5l?3a8$p6w& z|I1^)C%ExEd1wP#q)FY18`#U-)}M^LR>-!Sxy+S*C2;a5cp5=f+bae_kZar zBry7yJ@vg#2#^8{yTHuH1q4)K5CmN4&$r@V^e9M(_AhG$qCuT?z<)4YomW!W2Zl5)}MjI_j{b{!iBf z;0uq46T*uCDPWF+jzUC$2l$&yi2Khw>epZ1kpL9`xKcpZ0}jdp<2{!M0^ITO0I-6n zr0_pN!GBY$|6w`j;YJ*E2IB>~Oay!))I$OQDIm3p{{RR7vd180jDI`P!A2(pa2+_A zj10$tnD|0q4jd#9rvd@Z5f?Y&EIl7Lm}Q`nK#=$cNcdMU zbtG!=Kb=(oBM1US$0N+m#SPBIBQSy>SkD1-)IWm4zl`6JaK!(xQi!D!EKEE=uL=<7 z{?Z9#S{~q$AR_eVGQ%$z;RyTjKdciXv<~8&I*$Or4+QE4ZrHlnBjO1`ENwk) zEn(mT>IiqTMBZ|C@NnCI1M*))5@KQNYT*Dobh-b){_Vfsyq`RH9AH-N`&X{E);0&19?tu>Ea6^G`&Z_0 z(C5euPHShDNQ#rf2!yz6{ww|Cr!3$yDwqT|?x!Zzk2e`GZ1=InA*n+^oIQt;R zPs_>`YT@qT3OWD%!U5_ICIHMG?u?kcV4_&sT6iD_49qVM08xXeLo^_o5G@cjO9!G0(Szti3?POOBSdxJPM}p_dbq*%18X5~A?NJ( zYC)YWzhA;ZTRmKz+}v#)Ko5XU|0}iM>sAhMxGVAtae|sVK#}dYb_HJ`+wSIaq(eY*fBL(*>`yv3kNx@oSNfpiETPuc zU@q)`AnNA~b%lc0f}yc+@G$?rh(N%!20wH+XDC=${`zqs)D#ddFaa!KR$zVR`TuN@ z0y`AXkAj8x4wj?;f6+Qvw2~8 z8itSedjhC{fG6W0`tND$;$aVYs6JO$_UP>8=ofg&_ejh6GyV;JZSI$RlUlkST*?GJrru6z%Rk{7YkkS6{;G(aaQ-6{X5CvxI(Y7hS26qIQgNkN3f|7o>ageK6}Y_r zI*YcXj8Suq>V}NaXbC?{8-$14Qk*rGJCDST&y77Bcg^j%vWiwDssFmRR^(dW&Co)b z(YdtLc*E34t_8#RGub#Z!N$h&!j&VktFQg?Wr$w0yElX3Opa6F;6gS0(?e0n3yCKTdiV6L-5h#V5a&PLoU3R9IwIUuPke^_@|w0V@U7DMR*T zZ$|Wns=4aRB6Ks?=ff)?@Q0_bzt$8Ij>(m))|Wbt7v5?8T0c?y>}=ji{_`s5J9g%9Ki5W?Pv7*)G~GQ@(mpH>5q-D! z`P%Cb`BT=a_k9BVGT6sVxXd0#wyk;I*S@8EeJm-^vCFT3UmTgi=PE_IJ8({8v@>=&OUbOo*rTo}jqrH@BenS-)EJ zV_A^m(&djL@Nsl`>bvWLxXYOX6+tDN^SZqWA*WJFn+1)TS5Nyt`E>VMXG-Y+&D80c zh>n+=ToJUpr#epib3LkV5jA_-yQCP9Joa^2WWq;pynfj945ZHDtT_3@Wu<^ppB?Gh znh1~9!d>e0PcqDRCF`}^zmCibY>~uNsl^RA*PVGt-<Uc;-ZQEO>_xieb&n3-Pl(+dk##&nrFXDO< zHTyo%Ki^G#^p!^JmEJ3ND^0$vy>1n}FnB@yG*x<~p8agtHwl*6+otEZ2+KAbjdI_T zF9m(g)H4`%?9%MLnJ%MJKrS@Ne2W)AOe85Aig`x zBf`J`UNxvAsQc0K&bvb$Y%Qb_NCi9z9@KV+IqK1gfEO4Xyp5j^G!;=V85y`Yo$*+ELh08pQX4Y=uM3sH9jKotUYaJGR$%n^C4k#Dg?z6G}bFb~8R@eSfHz~SIuTR8Z~ z9!LsMh{Jvnjvf#v4~Vxd#Mu_&Y6FM3Aq#VddO$o53UmeqT7bVG34tREJ$U>6J9$7( z9z<52{k$M;18)2UkpS+sfjU_IxPgH1f89W$!y}I%?;Lr?1`fC12bBn!1d-aul;7d| z(G>DYUzjT#?qCVRZUb}=cY^(O?e6vCzPpVp?8i4&a1YnN9>m?zBX zuM~2w{*`jFJyZ|?n?Ozlm=!U!2%!$L4{Z;mI*6M)K*RuQA_NIbAnN`rIlv0Y77!;W zK=S|vyMdYO3`+5EHHQJ|5P1bPhkL>x4*New2$(1k3y38I2C;%zLu??n5IcxH!~x<6 zae}}h&JY)fE5r@r4)K6^LcAc}5Fdyy#1akwy&D+%g9|%|7t9uj9qz7B&?Zj+q7lM{ zEetU|enP|C2(%2u-G4K^f5Er^Po_I)*KaW-h(GniQvDZ(6aov)cMJ*iIA9IhPyGZU zg@BXdAA-oGcv~H9YpOOjB}#@OD$X+>j5DIHhH^5aqeeYclET(_s-^IW&=uZX^1P1c zI3~6Vkxm(2yOtC>IFeAst!a4@)Aj{>&UIZLR0c8v13^V@_DI!6U*FJx^ez6vF9AN8 z^IHwyzIc6GVe+SHr>~JVU|bBz=4EKT-HcA_@c2XsuDd-ir6QfTl36KUlZJXJo)v0D zLIT=rCUR7Ev{;%HcgzH}Hljc*<{NQzS6L}vFG6eS%u$4hIHkQ!NXx1pvKr*APr8Hz z27e?pAhS3zdQGOx4;n_g7@A+kNEN#1LW&zmcpFcy85O-Xjx5<t8*~Ew&n%!%|{SIyCAr# zjJG!_iqM3fNR z)oK~GC$GaaZP>!O8srJ$lk~G7ey?tsmU_BSw99K4YD7_BzBL_;6qtQwL>`Z>8F}U3?uNQsCoRki0AIc zfm|uxjctroA%6K9&ja%e-c1F3C0briX1GxmjdxwArYBL=0|if1WKS}riPcq#;Hx*P z=y2SF?tbWl&IA=kZg%6H%kIZ6-`Tp(rA?vND4sq?|IAHoi=ko8S-!dFg%=0DW4>UB zwf0DwcG2;SCB@sq_p2axm$0wCs(Ykbv4biC|G1I7B2U~>C|ObJqP<7hMxQV7aHq-r zrsFWqjec}EqkraJ^uUU7w|uLuZ0ZKu^vGF~7@_(PkxqieYkq3b^oO)6rh5Gw&Q840 zE7MDbsk0b;&zkPL_^F)QU7L)ZsxLNvk;}QrUm)UU;jtO6&oN@zP72nWau=?0)h4BR^#ZKNcMwI7SV|mLvZz;F%MvRFFuPyH}U7?abSDT&5V6Iu$ z&b{MJWcD06Zy@Q4uFu50%%Z~+tjLugen@(AA(~yNI-S|@cJ=ZN+p&A<-LX5l-curD zVKS8T;ks;CP8I0vzRM?)iPSFO>-kg+h&C@egtDj%C0>+BP&om`YcD3|dboai=VNPi zvt7)YT{jU`cDK?e(pE}h7Mf=X+NQE!r#zRoT9dq6Ky@rkpWiv2R9nwEQ7GE`PaEWW?-(`l>RMWe$(^ z3PJ8?qXb!1RMqw1X(yJYlli`wMad4fYiwHBnv_o*>bB}e3p&(op3m7XJ6D^nTKSKQ z-gXR!?B_WW>q+*t5s&TUQe3dw-V%hwcm_UvCr>DlwK6Gxv?k52YVp?xG4x_*8u zASB?%$)PMw?AuAu+^uZ%)tSIj=@QdTceM=Z>$yB`EhB z6Puc}%iUy2-S?gVP-=F3H=h6=5fPyog|;dgvt4GEI?} z-@+L63?#u%29n0EkSXZJoz$>p{1iW+aw88uLy@UBxW@3*=^2+8KaJSqqIoDqBu~tZ z)|IL2>;b+*Lv^{vl+e!?3ddu(dWP@aczG@6@wO?E5aT?C>7YeLq2YMfqU0Mof7csI z7V@;T50!TOrk&9eyhi-`2(9l#+&R|}bW36hK2Pv!$G)!Iu#WzgxZX?h*l~ZhSBr1r zkF&peyokDG`~`~u^QBrYWtyK4*QqGOqVU(JIjKVIGffsgGLv1EfA1NgF2Uk9H znYVvzt$O7}C2x*BsiePlG5N?nn)=L_+|@pNy&mTky9??JSA=hR+n*bK9>sd6M03z* zzGB-+>d_r1UlO_G%V~=4sv|i9d;DBqmOs$dJEnY?{@7uxSdFf9v6T6ViN05wg^Y*~ zD}&G5cG7Wn7KV2-}%RDXV8v!vRQ>g`+X7*h12PV5f+n?8S7dt3g$$?>6s9mHoq=Esn_^&sFI#1S}g~S_B2fgt>W$& z<3_>4`7kb`(!d-#y%(M4`rlkW^TB8B*RE_$1_*67a8KeuOXWhttKxU7uArfgAG_y1K>n`+3ewdO;PJl%6ku#SB%&Zwe+el_f5gK=ih_cM$^~U0q+B@91JpS` zODW)3F+!?2B&8tl{3N9aA_S2?lu~{w@Hb+Lpuq3N6rgE3i}1t*P9uT{0qO7M6z?N4 z3KEtaX$P<*A-fvaSO9qD{E$(OoMHYBV1#)=1HS_pU@!bjC3Y0R0GqkU9|IUIeFN=b zDw>n%SB0;+vS|^pQ`zC76FOw`#bYy1vrbaPClD&R(xKy>Bf;RL6D7qVqLj~PjmY^V z!61L^INdosB^?dT2s(!G>t0s%3*zHn-5Y9qJ1>1}_&l;ueB~6CH(|H4PWuV>(AOq> zk3>euoEvAx98lhqgPCutmPxrm(zAYI zbhf2HN(VEIz^qIUCFLo7*i#KHHaxQ9ayiE^({R^NVp#;D_^oA4-V;etsq#w&3ztE( zD-_U_k|6mo%V5-4+A9q2`(ocV#Nr2j`bv_`qs0!V+}oX4TB5&{NBNAH`>9#JRi6#1 zS+ukiVsu4FbgS!4;*P06hvl{0gt=|30-n5F6lq$epbbx1(%Rf( z)+*EM7U{0EWbITT@37rsB<_UQo_)lZN%2to{o6#(SgATTZ))*C7hRFvjZzuLo1rvA z>`n3l^2Bj2=T@1S1agn3$W@>3xYpZrvwQdpRlPNg=E``{H_kgREg!<477G_Ed=CAp z@@PZ8pyWbNC8Z9(H%0gM3l z+>3R_YGEzRP=i}>JZJ>gMlCluW;)0Q%ZIGoshEY<0w~kZXkDlkoW*+dWeVle+IHHB z^1+@0WrLW~l+@Q_#&%t6!Hc;yrI}|0x|zQ2Vpg9NiaH-9>5Kp5yt8;#JlynKu-tn8 zfT(wXqGymqD0Q`@i>jdXW#U~)ebKMD*AY1Fadoq>Y0myi(DaL#;<-dh zLb-ZZu?4i2GIcI5?f8-h*_dNmE}3; zL;WpV-3tpQpfE9Wm&m+{`daUh?XT^eBFFkp);#BdRmg6Hg%DhkiT-d0JMo-%xzP~K z%v|M~*$bbG8@qZc$>Vo72wLu{s4m7NU}{X3P^UyxpA)!Wye!JTjGyc;Abaony)Gt& zasAsi8lDfz&IOF(CY>Z76!WV`W$k!hvMK$Xp_`$v4*u$7p@+j0yFMBC#^Au+Np_k7 z`}+nfDDD|ai}~D-1}pfkmJ-TG^z^YlinbFHDSqFVL37{zyddA}?!Eb%=DdsgUVR+z zjfIV2rJVs38-hG%;mXcoE8|}DrNj0`1Hn5qJMO3aSLL%K?bWp1hViv(KJ%nCci*iV z?<7&(C9+c3=*TR47kzopC++^JUdhkZEs8>~$%P%RX#3=t>(@w~*{e)=wcN$*w7z?i zR-d|XTJ&UAjWG*L*&<`{`mO%v0IDnkVxKM#YF)NYb^6B9np@3t@pw*oa2RRl zU^jn<^}>*)d2Tla+6%S>8U=TYP@M8_0R@qIcORT0(1g8ue=-q5i!ZvIll4lwo`-rn3}&j{J&|_&y@pBvE4|XU0h!OO#%4_CGtGwmXriNZrF>FP2_2V`nhwZ!x@c z-CHS9Oep;(2YucI4nO%%~S4~$-n^|u@K6z(uc_`}r9lzZcaRqNbW?9Dvtv0&e zc1&4`z8`Smx=ZT|kXLxV{sRU0MaIJvBxQMmTlsT$u&q#=B+f(vW2yJBet2A(D%4sy3mQUxgdL=^CjpZuttaaW~{G zd7J%dU9sn;onZFj?L4WGT+OA4{!FG&P8=KT{^+|C_c3j4Vor~gm?}EmXE71=%(Iyx z6My?gldbF|`^K2Y;{=t4^TfAvN@&k2rHP#WC?X3HnK@?n<+EY;q-^rYjZcO3x0v!t zZk>JRkG7jHhpv%ORZ*)`G`Z(k^y1V^tsX>4;*}nT}J;9Yp1LNKbnKt~N!xwSj=kv|0oA{^qVNPS{A5Pm{au=4?Rdpz?%$N^6aZblMZs_42Dp1+3NK3lq+7 zlp`5B-RH$GE|7*sceoee!ij{&(rqt3XHgyNQ>1t-X6hn8sz0Q3MYyzNv-CpcVorFq zzr*k@$vpFR`>6`X-bXPy6JNb;=!eQFlO*3i=F3+fsJ{F0_7GWPBZq5tMFtGI3a`1jt{uJ{@ zUEu^=MrP`R$7$RfcW_Two(D3ya;v+rN3BvzdR2$2tHQ3(b5e}VyD?cEWb>A%*Lx5TxYT@AygIGXafmO!b6&MD9w~z%Q;R@VlAi!PA)&Y2_0Ot}% z;EH4J;0A#LTLk#CZwQcY6<|(CGYIl(|K@l9ILN-c8`3Oc~V&O$!EZ%FzVh7hm@AsoVBj>r!i4<~D=tB0cl)B|`^**YM-4S}Yf)o zAktq^*;)R1Rz%-A{Vj8E`g-O{+EzC_>Kj>Y0Rg0i3W}pE)u{QzOrlI!O7DU(DassL z+*l1$aRO$Ac4&UD?(QeM5)Ba3!SVV#Z#EYcRt_=K_>b;RG)f;m9HEs$i@}Dmz(B z9mUBs{ z|7Or|UUxi%cgn$!FONw>Jo!7DN|5I7uo~a;_W;2VP4)P}Hlnj3fjIjB(={>AU;{Z0 z-h*FsBa*EU0;Fq65ERrffpg(*uhVLM038U3lN3PJCWSA1cVMFvgi@ueey+7Tzd*049Pzxo_ zC1$xI4-T(=*n$3G$_y5iu$a9M_ zfVtz4Z{<{JY-TrdNTZ!;H0Wl%qjdkG7+oFQ!C%{(7j3+&0dlgW5HcQ+6qr!%1VV6q8KwNT>N2pZ*3R znSv+g4=Q{cjmK5Qi&GDpeuHnmm=ILEYKCoB5yN;K3DZdkjDb=_&RO9{M=&!GhQ=9n z7fnmLgKbCAXTr{YmXH5tq`IinK?&V#?9cKsU;3JsWjW;BykDYzlEk2BTYeLD9;{1& zgEf5D&Q$^K@hUlGjDF_|CiQ%?(AfOZn#@vjrO zUj6oE$0D*MpO|f(`0Ki2WrE9DBVGAA*ZY3%;{9<PCMcTDh(ae~G(#=Ym}iOV3mdrJHnGCTR%{p^E_;w?lh_gJ4+3$r8VL(59do zGZ=<30CUS|YHVHv685%Q)T4Ua+z zO06+4W)NAaWn_H;Udb;qc8AU4f8RkK`HV!g@SNT%SS z)FIwtHcp*;fhIx3mVxx*Br^v5fKYHCCW^#kUz_B437pq-vkAW<*tDe^0LLrZSMy?yxjJxQ3ShJmNe^+4`PD1FnLJE9ZG<0|{mBJw;mG5*v^x{-`lJ95w4o zR+QW7D|uB7<&<8m;vRl{cGCGG{D_)%ghqD!@P4CvVi)=>^K(3-Er9>XG3fO zdbnm@m4rEaa0$$tuTjf^uB|M%Ew$M8XkMztv~ujE3^nk!C+wOe9_?1|%lOq-GV-W3 z9z5+&E+E|O@`_I2x7RsD{FY|z9V&quxLgq2vO_(hyW>J;wwJAzSlV9FE^hK7K-0hz z)*K0EK(~;{UeO(ZEo!Li+Gz-0h@aUh1{*&Yh=`wF@QlpUQ*83BzN&Fx&<*!3)V*%{ zSU>NYp=`{x#(TJqQ-0$~ZDPjd*`l82K}tPFlj^Wnja0zr_PjKZB4wd2guOH|IEXkn z0TW6?PZ9c18QWj>sB52rUup3z;A??P;d|Jp+P%Fz@E((JF{?9KQwf~~g39T+%v*GJ)Sr)Xn znm0E|niySO5`sodN9YcSnC{|v&QZ(cm%o|$LNLeJ9}BA@5^p_AFo|)Yq0SW&%GKC^ z-WADBd|on+FK}0z$d6PLozvdX7D)-L8Sr3YLu)I`H292MFT>LAEA55Xev}}q#67+E$MTOE;mV%z9i%n-eV@=zbowZAK8e6UIe4_F-G$sQ4_mWng zhy+?@oBKHG#@{?q!SWP4noZa4g;qwDzn_d6Q@(}eUZOvy&kz!-UTg~8m0w6ws#?+{ zsx8pP)i+T-*;7#&Lp=z^V$jdKs8Vs|9cZ^~i`S0q0n2#EiiGn*6(SuAM%PGI){MT> zn%RxVeli(Rw`naUGJ*#${OlQQy{goT*hgN7M3sNL;unx#e=JA1461V(P%J7k;LI({ z)oR=w=)p_m`|UEuz6A|)N3NxLYrm@!M0vg5d|VaV%_2HTqQ8;mQ5JPwkLfkJ(R;@6 z#K?j8y7*{n`Jn1^wK|RpUDEV4R;J@r8n#50$~w9MMa+0c<}CDc4BPuF!du}Fy7~|S zP$B)q7T@MP_0bl%@XF&xnlz%jS##uvNQ0(T^vyg2W~ds7$~aiKCo?TAVBuH$5|)&T zU4#>`M=3Gdd@bWAs27_wxbD8--w7Xb5ylN9oH<1DhH8}!iauPfi+@LQ08)H{)0+P1 zOTFY~2K$j*Xj{r3#-Vaj>tJfOij&TZ}%EN?f=RLob?0ZygPCa`68N()v@ZyUC z`V7RfS>|jm;;yL31}hWnNY4HvduWE(VYPscIF~%lR%BTC&z*eRLWxP2wQ^oi6BeFr zP%nWiIXhB~#^Nc25~bs!m*9qpG}~KH%(pvEJuy!kvG?{5W~`nY!Y^lC;;Uj?#|plK zMOzX6+-Tn5mcWtv>-11($50c;4l5+pl#N*yP#PHY?r3dJxxGzz9BKh<3at z<)ng|W&)RLpuSiS3_--Xw-e+}YiZrN4!LObVn@tcbQPQ&Db!93>6X7X;iwj`t-`LCeJ!n}QAx=cJGQfanLkHJKOkh*SL!WVky z81S_4{qZ$fWR??;b(WT%&^}f2naSn%l0s_dC^a%CC&Bs)t);~*e9%Xz@B0MN<`R?_l&HxrO02XCV3GvXge*5-GUVZi4~)xbFVeq60KNJ+AXE_+ zb$$(DxaMnIzgG*NA0%Jy$wy}RNH8#SN&XO%3N{C}l!`*GH$~VN2WF2u;+-Z|#wA)M zG{G^FvRZZ|q=+bsrm%#1kP znqd9LU&kRGCckfda-8OC^-Y(Bill~lkydsqv%FoL9ZJ}h1h5~$%ky{%Ef^;@CKK2M z31}vJ>(RF&nKd1GNqRHhjr9-P7`)|gsb9!sMo2YOvsgc^B^MrQkfz-F+6p(Vh#q5v zFKx4_&`R~?={*muiQxKZ=-9&K-r3rnk3BIzBnr1L`9%(F7oi9Dn9|QB!4aG$JnAjj zDG6&6+YVF}0!6YKKFJIpv-%~2g%)k*SqKgu>Wq~+G!MpWNJ`wbW1Y;824$U$JaB$m zl}M!`)TbNnY(L zLTAn#?QnaoF#ra28g<8O^p(h5b)rT+M(aS9b>q-!W0irzQ zUFA}8h?z==T=lle(Bw2+y$3SAewGrcJ;jSE5rNi=ZO4!k3FoA5dlTW_ci*cE!Eu?3 zH$~OZL!qD6&4#KdD1D~Frl=j~P@&`zd7mi3AEOE~+A>q+l&IGYC%itMdLFTR!3Nlb zUpI$MnqDf~>KRy*-Ds+4wlcV#I(q2d+b{G|O~vvKFn=`tXj_Bl?x&F2ykngU2IBcx zCayOosNSt^s)tGUT2lu@Ti0xYnfeLUvpZefAN#RJ3M&Ia)K$TA0<&4Moa4oa#K5Hc zLug@etJJJcuzLUUH+AO)MX&cMU-01P@W8=Z?5~`G6c!rr@4*oA%l+#Y$10$2U6Xy6 z)~^y}Z9QAREEM-MkDrTt?^j>$AN_(FfukPlj4_;eVo^z^zc1v5+KeS$*GFpvrzGfi z@5Jg}V-RyoF2P-zj2ZlvFgDwZf9D zQkBKUp$esRnCj_*PD~1s)FjzGzM$>7`DVfvF71t$WRm*)X>Oj*YV*5f4jy+ba(@rw zw5dwWv@fT+;UVXhKHmoJxYuv1#Nxh#OkSo+9W4|DX}+` zIq#NUyj%a&|3%J&8iadyOiXX1 z*BZ?z*T|vzJYy6>nn;kPa)2Mgz5%4c?||XKE>}vM*bfYZJJnn1=^$K1GYpkF@gjL` zVvQ)PTx_dlXY+_1hYwXLk#O?SeM?3vF;{nxkCZ)~k@K`%LZmY=Y(nTL5o=U8|3Dmv z^5~miU)eG6V7$UN>HzpJRNxBHip$*47WFJb&);SR3*nNXH*LmRD=xz(cnaqe8aPk& z#yHm1_(qUNU4x9%6g<$K5vmp}SWo9-50r+&aG|{e@7A5p(r4Yzt;4ZoWz)WIJNe1B zn@{EE3N3MHqVCgXpwg%$zQdJ2OI{;>WO!s2%QG;fI5ImJpVA1`&4ju|8%VPHdKU%) zDl6gV!mEU;0s1t9-TPhN>HJ=SM0>nMYB}e~&!dinnn>W~9j5wyN?< zHC#@2IA4axCR~>qT@+dHCO_TeAP@>2mH2oRRjP89@AfUFmoI$1{ZI(u0rocAu_L*# zu2qUiqk?Xmy$GD`Y~&Dxk*v>opEvV9J8HlSIIymR_y84}Mg`ws*7G?x;XeA+=_09w z3Z1x@ui2e$v)sYSw|=VJL06O&<$Tm)xQ=Bo(rh8p5iM1Hs0{E%D*k%A$C>A;5&8uF zpb>MZQ{AaY_T*zTMW{IOsLHF|8YR7U@3-F;bZ)R2-e#^In*q zTE?pXkqUfnpe<}SvDkmXlaVDyGn)-mT|D zQI`Gst(HWT6a5}Mt5PLs#09R9$Ms~NxWC(Yr^*bCCwHbVzyLwr7pzuQMe{70Yxx+z z+;%kldG6NprQYEa+bh=x9zVLF#lR`kiOPkLv$I%K%8Jq+rpf_lCc%9yj4COFK&{V6 zEbE^*&hH;~$5nB36>n?FUMwVn!{SygylZRgdL`-NR7Z{$E1^948fIuCvuP zE@UGnFdBHs43ByZ@@6eXC5>4MMys%l)jmRXQ=8y4`yhwxOvopHpOy%BB> znoe0FSg{}my+zT=v^0(iby!`t|9B>KEe%;eAY^S$AwUvcv>$bF0Yok`_>wN;L|wfs zpJlMOQYcoH1e>_Sx0g9@?pG~^fIYYGF1wmmfy|IoK!Rg1mt`6Zs5B>Yvm}J2@kJgu z*?NZ=*{PQ90;!pvA^_3|yhUGp^uUmLrx89MgLyn*!y!T}J9wA_c6}>6tYZI@NyPaG z^1GaiAU23f(JVpdss%^Vmq&yB_Io|V_OZF<(~ae0>RumaOkIkG2O$E%iR9_X#~o<= zu9i_Xz_MDOa_!)Qo(6TNy17&LavPJjMsrq+PYhk5m9zpe8y#xSV<+q~=?^6l zY39YNWOnshQfa0&B4J(l1gDRTTKcpjVWIB=llT{0EMx>OWSW!N&DEY549Vx&P}P-| zigq`kNlyt2e0ecwLC2QpY0heuWKTu+qw+puB^4)RVd_YPuwbWH?2+_h4lCmy_6fX5 zEazeDIJbqx)Gj)BC_s(LjbXkBaeS(YEv2%aP$GdX(HE@)xrTi16uYziY)xH-=FyVq z>OG(8;Bfy1`-R%AAKbX2-S&{!C@%qzS z^3REzj6ZY{e-N(#&BQtBZZGwljUHT_Lk#tO)Z{CA`)z^3Z=j7@+k$-m9m{GH_cmpt9?WZZAe89%@cKnkG! z|FdxChivB$$<8mq&QH0{pA$iUV_*J!X&6|4=VPGN832woe`Z{n02O|JJb(55efzKe zU$1OGi|72-V*P0i`fCf_4+Fn{d=4x7kKEH=57wVXJHJ|gePsstn=k`v{xJb;$bP*t z{wz}TqxI`}e!Q{)YXAP|`}GdMdjLMoOg{`U0cY@I3*gEFMq&oID*br=gF&VTc+ULs z)BVLq0e1aGK>eRqeJlTms&D44|6i%TA>OpOHU*jeKc)Hxkx#EID9Q27i7AQkZ4Qv7 zF75f+Hrg|#AdL<#4+;tjBM>YcCmt3mcPZ9Y0`ZQY&QpzqPC;ItQZBC9N^3;A!D=YA zqr%cK<9G|EOy!#0D^un1g5=RB7~8RqQQpi?avz+cFp0{g{`=%yNAK1mI&oWUMG-W* zWz5O-amZt>i1XN7CHM#d2~+avd@CZA*5V3t#BEl?1LZ_-fG*?SXYSaBCG9I`rJ~yL zG1}p4Qs=#bHk(kjwzJ1}^A&zIzPQiv`J>jAI-MhABw8-F_XWJt&Cey2ZhJgS&K-?p zrMv=Db?e8kjA5%IEEJ8{ujTD*8>wpqA!TV#nNZjqeP`}-542|xmLUfct7g|8gUt79 z>-Qx**QdwczTs{wE2BP9>nF}zPZBn`N!vZRq2- zfkhnm66twX%AH?ywd>auO1@>F&&K86S{OIzLqa-NkbXYzo1QS=)l3u*teRyvw#%CiqSef|)Ie~Dy-I*iLrbT?Y1J;tJIy6SFuJBYI~-8x6w z=-4jTZiq>6qNMrh(9g5?N}SrRacVfMpmw}-Q|mc~K1{!%ayaRz*>riBvzD~Hw74av z<=Sl>IZp9(nblq4+zv@Gq0_#6gLYetxL$a03O9kKt_eQ4AxR(9{0U&0=zCS#f@!fP-x)!V&L8$@169SzTDWSmA+gH z8X)d98?Jwvo9O{}#y@Uw|KZ&HpQ^qAZ2aF;-?FkFMTCD$%<`&$Tj<~P6!br5fj>__ zzxDiWX8zw%egAd5KTpm7q3Rpp2~5q-4DiwVVN}b?_QRa*KaqX^HgEj-R2Y6<48W-X zvZ2`jB>VnRN%xO0;MWYp#`Hs_VrXUTVDi(f?%!xa0e+4Dxh7Q3^h3Nk?)WJzl92y} zfm6?@ie7Y$(Gc5BMH};|Ul4sBJrjWgvithM#Wm5HFohu5mdma6sZPU5IE^`YYp(eVvaq!@xIIo=XbSC#S_3f^^s7&=i= zE{5PdUZPy?NRU!cGNuP2oh@-7lmwvs(w0!9=O9rKS0ZaKhMherV1p}zTai-lNOX}v z4I4qAu)HQeEeAMsEZ}N_W?sC0ZQ!r?2tXt4$lTt<2cWUfylo(`0U+O_VZd$Ptl|;C z)))^ZABce{bS9m5ta*KY;;n^WMZv4HmPgA@>x&Bp^8$iz=|M0eda%S>9r5a&i`pvk zfC6JopU-^KlJPR%Zo~6^?Sv$vwbq6fc~edFL4@Q*q#m@>t=HH2%lz?RB|W&Xw}wNo z6&OOaFgYb&Lgzew)-(cYUzz|4x>Fab@OR+bV?4yyJY-k*M{a}x4i(T0Z7Fx$6VC}O z2t@L^mo+@^r?|E#SuZ_TL4#oE^p6yHF=QMu9WM*)&o)WGlL7ug!B*b6!=gaKB->BA zA}#T`q0k84Ab12g`5<@+R_}6niDVCifn4d7fs~Oj8dw#XnSpdWm6wFCLO>v&wDF*M zy}f)WfIuFQa}U1m)5@Uo-ktV#7Uh(Q=f1%McKL|9gM$cOT#8rq#5ooSsd)t+aSe=` zpIRE5y5%|BpCs`nB>q`gWa1wF1bR{!)K}pvILm^x-6Z6t2o3xMJj0h03Z0m1MA0!g zH%0qzrlo;BJ;iUVX`6GW-+yT6v5y!8b#*2)Js%|mTT?VV5owmvG51E@S^|=$MAx|S zOhsLe9qDQIqH8ex%w*%X+Rn{L#&M`=t7j_W9F*yoSy%{C0sH=&u5qR2SI+|j>`&$imMgc#u$zE?gGx)(2 zvMQZI(2QsdgH|`;hHpvA`==iV&=HW^fbSBU=b7)oID%K ziDnjJ(#J@yZh0}7Sj9s?z)7;nE3_Ux7AKf#jCN`{TswP#*jdX=;>H*ZGp;=@!Sxl#MtN-0L%Al$ zg*a8;rCIEgO8HUDeNf^kT0y1%$lJQN^1hL2=2oL?HTxe&S*;Exp|4Yo0D1jj_B-9Jnh=TBf-!<)1s6W(DI}T<$$e8R|L#~iA(q4*=DCdDn zN)u&mMfOe!O@Ext5A9p2V03K1Dh!cMgaw^?k4*#o8v9jwjV$9)_B}htQFoSxyYR)E zuy~uWixyL%g@SoB8e_ZghPHX^rRF1tfXiFb6gjkhEH_O>Wg0w$%ku85_DUxx>;@rP8 zev0gLeo9J`+PTvF{YW*#{N$#)Zsc766?FG0fjh)0)_aEIK2%7HVUJK4I5VBbOj=e* z_6*KhZCSG=nzkk`a=c;pZx8+w_yVa$-u+5^A#s!qUJ~fa{KU*_z+c z_C{D`&;xn&anjL@uYjFYrbz1UJz4+a$9S6q(CPI7qE3F8E#|oy3f0di9dlw^B4Xc9 z1a5oR&APu)OWj&2bq1@!V(b{-Ou&K`DeX08$qBDvZcd>&U(ffr1_fSUFF7PZZkNZl zZmmN~Z{ZeXB%vVM%4GD#lJ*|+3-7YXYRcHEd3h>jxCCTrZXE0L9|lS@Z?Oagq1hQ* z=2NIGuU3Lwpr1YikY zk{iNlaG|nxzOWpnwm++#;RN{@OuwTjjfj)pDnVSg<>TbL*(l9AUNgD7&!lNHP0$s;;+he=$l@Z3gAqwfW+b7wRGH|IIa|u z4)kwaAgkTIn}Io&7BagG=VYj~;2>Lvy4KdejV@)TfW$;87L7%kMWJq*@KZxO`jjTN zCCvi+Y@k_>g;K!%&O=9IaGk-Ir%*^TRUgK6Zn(C4tS?u*G~RD z9wK43VRt)na)k%|5=`k)K0RfLTM{@B@(L2}y%`4^L z?wy0*+Y9#+TzzeXuz(b&m>c!=U9c!%AI?2il`v&1wT2X)BD!KwwN^@aQPro8-8Hf4y(gW%DV% zl8j4mW6@9Dhcc^_lk^1PGvLnchc3^A+O^CrfaHm0U=pycX~m-Y+;3~&evmqRu8zgZ?5=g)L&JP1g|1q4@nuxRRNe{EV$H-KKFpVd zF<=cshrSe7Af()?1sLN91Ce-n2u%z(dw&^jtNOf)%;MxGP2G{U`SDSz-NkT{nvhkh z%*&Ls@QVYjTSJq3LA9V149-&wGP9CdGU8EkT9&`7szFPe8@|d3Zb7DzOUd!9h3%Kr zx)sCFxw^|3(QzCpWu>?8s=un3*GH`@wDE5$gnY$bzHnZMWBpXtKBMHH$4br4X=wVS zpcesROQhOo^6VSygHl-5HGS~S1(pi`kd)ge*-WB!za`V`5LHiAqXK1s8DIRM5@dd3 z>ocg@V`i-9#b63@(4t_GbeHipebahrsw$f}=3`iLfj%?kbE*qP;XMBgr%#9WeUr6W zaJ>T)S>V=dip6NZqOv2Y*_!}>uS14d~kYGZ25iPb_(vz&K-1X^y z5h(qrKJzOS`40o7e^Q^b0r1E_Kumf-4D<`c{22!P#UV?SPx2$5^iTE3zlxQ9i>?09 zo&zkB|8#)=0~GVG4(MPzX39T3C{s8lm8yZRQYKoWD2kha{LSO`1|SqaXJjY z;v#@e*3Y_uKhEy&4`u+i$NbY{_{SDN{p)|);|J#V1HxnhxNH4^>itC*@+;0kJKyL>U+yD{a;xXy@q#zi`76T(e`Xl5} zk=Hv)kQgwfKn;QU$sq8dm5ER%ilEk$p}^AU1WmWmW?`A!k?6^B-+EtbPrVOKX4 zT^T=?6)}44wYzmbp01p+FT&($EF#$v4-i8QquL6%^XagWzV!j#dea*nC!Y;1K%P$I zD+7HA9vlUa>~FT?eF&T!OdEGNauJx$i&r9{v?iDMR;>N|! zIz~Q!Ne&$3aaqF!f<>XEh=2{rD1_{s`(_&) zSo&RHdz*^BW{prm52Tqz$U(K%yj*%DTJPuNcMqG;G}c+`^DyvcnM-s| zm@g)l`=zIoK4Mp>rMubK_@yxp-N*+Dt(z%&mR4y1uP-zgd`~~0vj1=~Im3Sjxrtb} zro&jH!&n#i;TdvJ8f`1ScVodWyxJ;rRjUJ`bHxt?I%eD&#%=7 z`R%iH%ym<)mmp7Bg+x|lJPZt8H{6lm4$baxxxc=G0M;rsSOSVDCA^AdIqN`bCYC<` zyjJY(IMvJtHh>M{pGU`I`-gG&Up%S*!cP9TpZ-7bRQzQb`ol%@ zAO8A3O#FWeBkg~Bz5gyi{fkudXXF0{5$q>Zds97t+2l{t$iE3;0VbvYU(&$-H2nOH z!~bRY`G2MG^$(}~zo=ey?e$Gff0MofJn;lB_BZM4pTENY^YYi99<%?i|0VyoI@!Mz)%g{{u>TA%e`k#t0o2~Fc;>GW3?mz$ zOxJ%J!6dqTQ1DtFgqrk6ig`v@9D@~_!xa!z6BGc|J*Whzu#7M{NOph?_PDBK97jXuMzLVxs5H`;+!4@ ztAJJt0?0^Cr2v*ug%nXxNb}}@$Ubjk6v2&$22xZC1hLUp=6wsoi>io%qKHQqO_m*T z3yYVnx#|vNYZ-F(u?UzA?ISNIzO6U@)F50yff*Yh}2gFQP;Y_ z<5@#Dg6tB(`EtA&mxds01en#Vve6nZNGW36EYlyI5yET%Qu5dXM~_2i&>5s0uz5=-pO^ zEZ9m`0a|g^8m#QNiS|jBss}F7n{Qx)&3ZCGJI0XTD#A!|(-BQ@Nm;vsHo_hdg*MY) zuXtA*aNl;h8i!MdQx$kNTnfMS5!`l{0R8Za_^kEhm(!Wt!VboSSnczLA5X>%|N7~1 z_$JEja3lTuxCxdcj!r00EHCdH?_xhb;&%vO;9uE{Q4o0%OFX-4+1lV8p?Ftg5xT&o zfjrI%eF=bW@*BX;p158Z9o_@E=|`_wy$b4x0WCm9<$QWPgRGC!*`dwd!}f|{sDHrq z<=+9WKDI6f@?P~6cn2i(8mK@#YAuq`^TL1R;CtSggEjkTEuu*B6gWeAc^_amQxDAZ zeci2~Ab|AEP!|vey9+x|ArL4^LW01HQwql0Z@XbrJfK~82*I&W6Km}ENRVXd6H&^3 z9N=DcFsU32WGINcVDGVeI7@_@jb{Xt{Ev1zX$+(DXYD-FO|G(=JI`%)M3ATpi!a-f zb`0uwl~mC43#OaIx1|l>fBNsSK7NbrcO10 z!7!Km*^g%C@(a_omrtRLyWA;{kz1M#h2U!XGrn)4`j@dCD$FOHLDk9c1GHa3bxzPN z$wl+t#OZMyR$rMjtCujyvJ!uo&JnrJb?&WV9#Lv0zdFWaR&j1D9kOXagUaNn=7-$} zsq``5i+)_Pd_S}o#a#{qQG*;%AO`WK;MvhIQJM&*t`@tsKcu-rK1<+{JlWW0XR~^y zl^n`pmw#(5w8(GC8A%oFNHf83+`w6ZpZUY9?-|G0yvmzi*8J<0XWF5bqmqZW%Q8`m zhK507rHY>}%Bq366c(;#QPm!R$p^MMO|`19T%{VqIHJu7D^f0#Z{D`J79Xuj;|D3S zHkOwAH*n*{-(7NJgIT+AaIfTXIR^>H26=5<794w$@)QQ|#3(X%SAn(Ce(*R1iB!bV zaQTu%KVLz&yM{y=Er#5Lpr;cX+kDX^XiaIba$Q^&e4dk-{uv4)DLC$!C8A%Emd4#X zzPzGaUH3@|hQ4LPGFT=A{9Zv9cLN!*p;IXah){x_98n9)2tX{}_g zh;vIQjV@=}Yg*rJT*)-$;BH)v(B}_DMsy0v3LJG-n@wypXZ|_r9abdQSB{k&%h??| zL=T&BOVW$ZFU{v&n#8*Y=ojY{PWQD+=4bhuOA&?Bs@+D>rIMqh9T_d+pNu{E=8VGC zPqK!v#2J$e)ZW95!$2Eku0dN;MUZpYY>w0oB{4a#g;Lk|1~AAyz)fF@#eIF|&h_k} zI@}xXK8oO#ZH_l91FMm4*gkodR69B&FlZ=C<${$HnSyS;9!}E;Nh(0Dmm~x374ubN zDw_{pI(B{E#U{RB=BTM_)CP3R83$YJ_qF5MKDCrB0dC+OCFVWw;=)!nNv_!&xF(9o zs#8_D!_+juevA#Rc8KiI;=Yv)2WsFUF zi-B!w|3+s7ql9AaalmZAkN`)UMA+I|lJIWSHI8}Qbn|vyySkk^rb{n5y9lSVtNaN|WrFMjZ&`C%sK=0u0y@G^wUj~*2A1B! zzVzUj#=&%`3^#UTXPRUj6uZ-sQ{QtR)ibE?a5{`e;FHB|EZS*0<)3P%Y)?X0<|qZd zg%-O$R5+=KDmYPW;7rWgR>O2u%k~%rRW%)%*I7UL#J@oCH9C+aD;-NT$_~_SO8i{f zA56hT?QL`K=?B{Hlo#01u=M<}foXkHI|w7}aQl)eE~*6+XB$VX4tro6`O4Jr>aK6({^{4w5^tFaQZGo(5 z5?r`GYL|q$1*tg2muPRWW5~Y@Q@`c*_D+vm!kpo7W2B4?+f4OJ3AWf0a(0kwu(h^Y zlpQQAg@T&^O2{R>yx8)TrWk~9qIwEtCdy25cKkZn%FSZj?uq1Yf-xliE!8*$o<4G~ z*&cj0#ax|bXy-hA))+z-@j0n~{=;_Cp!zxTc9hf+*Y2!Ei)~Fm%jgSP37;m}uC9!9 z5=}9o>eI-aPX7#1X~(vQExRR!JO+>YHDcwVg@X*Jxw1nP&xcALSwbFT!c{!^viise z>XX_bM^@+*+p=e{Pn1AzqI8`aPUxW;tz^v8!!)PKf`lm410J2_AaaSTjoTEVbIp0o zKs;m$?0O5XFCn*|!Z$1->?ni_KxoIv8M#)rXJ`8v+% zlB}2W(&)A1GwOYBSPr=`Phbe^;IEgmD)!q9o8S=(W-#d%zXwS`ITz;(M(lN&a_klo zheugz1>1YY=Z7thhaLo&~uV_(RE%mKS&kTr-phPEw|lDPUJe_?3q$GZ6P6Ue5058 zpdv*|^m-hjuN_d|#3_RHL&`ooxREZRq>{e5gYSOqn+PE{v{uTGtmJvpa&DsS2fNBL>$SJEol!}~f)mM5(1&mJmM}eb;?`mXR zg}K?pGS$)xpCLkYmXSyB*JUXdSJ^-(ae3%Y}>Z%v3+o!Mqk%IkBX#Sl`qOq zw|uWrhu&KGq})MiFN;;-=ub#RycJqC>XJEZNV8(zymc!)JuNEwJ#|xEz;%0841U}* z7Eb}h!A#kd#)krID>C>&ax8vQY$6X|zl^#YY9#K|QM=LiR+qrompn1APOJ)+QdQ$^ z_`+_%bsdi#!8s;V3Z~#elV_OGer2u$|EDXl>?gE>D?Rzeo->?<(OeijCw1+ebZ;r& zGN$jsb5x7kIA+-z99BBk0H^uUGRbxUEc)`jxjM@epW*D~!tFTbZMx|4teRuKf^uFZ zO0b+a68apenc6-@<3VW7hrDeXqb|h!hGWx=mv2bff`ZadwV=~+{OHdtRyY~ z|CkPF`DW}S?N!&>g+Eq14kK-^{PLX%gn@)0TZm72tuX6WSJ+m22y5VI|9`2IQ z3`~Lw$TwEmayeb8Lq}y}lamUdT2SqrOb`9a{VcfX*5{D*n3>eR#aa(^~S;!Qo z_`60F`zV9Y=5Q%q;r^Ufw_>X|P7XWe&Weef`FK1!whM`yV<0Yrgx#!FWG8UOE86ag zv{5kr;u|poMMTZMG@Qda7Cl_Q@lAZu$#4p4PBb@e6mK zHrZDWkr@J#oM4oa3=!qsZ-!Ib=0ff>CW6ieL)3z9I-F+O6mg~!*PfN?+xp%XEVo$; zwRR=@wDZxMS$o)XCWO!=8RwbNfE04GuIhd*V=Ud`nta!y31!gAFA?QyP>m zjRn`R-yT2sx{^#iEM-QoxJm2h(u>*CZb<#bsgkez4HN$P)n1?Y(vi>$29EWa=#E|* zjpBOF3$3J-+>GS0xr}A6C9BTIG=X-a@rdEgj+aP_$s&l6&r?*D8}RN;g@&t2pG_+8 zbcWYlM@G~Q5%m%21Me%yHOUP9zrb66(2svb`F>!a|0Uk~dqt!_ zoXMGf(2xI8;PNv^_b=SAh@iBxlnMZFRZ#dB3Ky1tQn>u=`E`K5xM6w#m-`3c%JQT6 z56G2);dj6D-yqk&j`uGS*Z)f50!X4|U<61d0JUUU*ndF`3oBR6AJk&8vA=rGr+z4heQPM{5x^{qy6vt|JA<#N#C!r{`lO# z_xx)AE=2ixT)*x8$9sO;_6JoBC=vC?PwN-Z!^Zv(2Q&siMXEpC(f$hb0KC}$Hyqai zRJAEuzmhK$&1$wUo*I&>fv6m?pzl&pHAYOeAd_!)LOv3RsN$DgD1ICCn2+jw;DVFE zp-r|LQwzcTPJWOCp&|-&wM?>;+!V(;+bG$C7?1m-RqXQDMQiP6t!HzsS*uSniDmHc zyIsI!1Ww?hcyQn0j4Hs%fkbi$1Oo0w|!9lp8fq`6sP^8}{@Lzr> zS^(}S79>W6*4y>YJL{Pwk?s~=SA%HpaS7L2+f#CDwMRDlixubl?3UYxSLN_C%O3*C?5+2>*2deubfEWY4 z(d`bB5~5e9GdkqeJJYxY3>^~;6(YPl*l@*)g9P)jbOO6rB{#ZP4)5J=x7^P19P{_4 zW}ReGh2Ty@3_B5`od-M+MA#i7oDs^cs*d?qu+Z6tIKWlVfkFz9crDSwVL>+SJYS}S=b4GMqM~i}%gBjtk z=b|<~3a;y=6jJOt>b>V&t}sQNid^9mMAxLHFEA1Vp5Tr8;9{R$u{bkI{zOWuPAR>L z5jO`_N2O4)3cuezUx-zzHSD4OYCudl!;cod_w|dm(ePow11HqvQ$$3>xUSdTiWS3W z>)IWUCvKv40W8CD+SswUCg0znOWA01r`oXZ`@V=f=55Mb6UY zAyst{>!tE^`RPqGP7B5D(a{wA?9a^}$`3)GZdRMdgGbQ2SF>PAl!|8jKFYYiT>G(j za)m$@SyN#LSAP*90oUYgyOAD?pqSpnWaPWVO>^i_6&U1g+r5J8}8k;a_;=;Mm9Nd->U&^aUwkMdS{p~VKp|c#8CDsx@G`5)t zm8_-Qe(IF<@wc{0Xj2?or^Xihpw9{HWs2bbtktH~YI0OgOcveO?dZ=}66uY%xm~Gc%LL%yi_Q z>2CK-&)oU$IX@~Y>#fYnsEmrpReL{st;++VoHhK6U zQMW>1A9+@nHk8|}HZHmw&&T?O$la8!!WvW*uNUX)m0ng&{XUP5et9y3bSFsThU-ZJ zw13l_=cU!dBSr{7uj@^B*QQeqz5jd7vL$y#zgDMAPdPrISYXp=)b-t+mZ6*(kqfNQCyI~BOSJAs1n zzUYslEG<2abN4qm0SWCr71tGct0af0dB;t5qoFMvaDDZVgM^V`2`_m1JGC&N_vx`_ z+ma*+uOhN`x(@x9UcRm2{#L2%8CC|&(|COv#)6~606^0p+DPW22GL(Kn^?Bpb=a4l zxJ#oX)0@6btE|(oxf@?Rs_z&ny>$ahs2^S>enXtZycFB5TMQ~BJ$2`_@!gc3)1K#d zoS^z*-Mb8v?>hthRCNoWwgnsK8rDxTe2yfZMZCnUOQK7(V2qNfZc8oMgN_)o zJGAvoUA?qgDE-uX>KbSWg|O2<-zni2M>tY&me(-*aSH03SQvPWj95J70~5mHqy$co zX0Gm?;?BfGxSu`0^tK5fJGiucb>r{J(AH?3Gp4sp2L9O)~?hn;me9yms z4qA){m-SFPzCPVw3$c>ccI5dY;?>@8CzQpQ#}dZ2D!~|WYEAPLchMKlaN}XFP}|qG zJ^2(f4Q^)-?V8^3b^iNn40-AMh{4on{+Lpk{ZZeJg5)v@4zDz13<4m>1~;;|O@aH4 z&NqJm6%YY=c8b8f3x97QMhy0*f7h??Q$&A?jQ^2s{I?;nclr3Ie5HGzSo(t(__tgg zRar3w0kPl4!2XUGcyCYr3or27%D?E>|H~ZMznt(_0sG4!*w2R9e}o3u-v_~dG6U}k zeecWw^M4buKb?c$eQw`F6YU($ob)V>tltw2f3|o3(cOLTjQ$oV|4Wzjj}GZymF+*S z@vl(iAGtgXzd;E9O_#F%bC2Jj|J%O*`8}5ZGJyS`kNW@To%gt8yq}LhweLGg@#oL- zckN66KJNW{U-Nw=kD2v9aGGpP?-b1c+~rhKU0%Meu%ni?gFJ;>(F*144Gje70_qAw zO+-oD(k^Qhn3N|w?ZsBlngHrOF)VMpGarA|$*_0Kh}|JLW9`S<9!9f&&7hk!JF**G z;w|qImqmr8(YDs6_h}7m=ca}09EJfI(xayz?CDg-fh!90iw9SQ?xds`0*`VG0KE4H zXyv5`}+^%cuVK_E4j2a2=nRc;n`i4hB zTQ`Yw1lxPdRkd{Xm^HUv)Yu=@ADeF88 zxIXjT@z4-O=tNAzX-^tLAY7K!o1p)9~?%5U(33K-M9h zuKaP^-^jXccNckxfGYD|Qa99Kyka4I`hT!?U17cn%V;d z7~yf=%we!T};6VEzB7a8;( z5Ew}4{^3=bFN5wL^!)y55xisjO-}>j*%tup$%juh>`FGuB}u@|UeGm5f6@??f-@&g zOTy1sV0;Apcp^Yhuy9I`nf12LEjM*Yl3?Z2%qR6TPVu`WY43FUd|Z5MNOXHxckKlC zWZGr22x&%U4`;0dS^?M#juaDbPgKE~6m3j$8G0I=frp2KD&ABjzBkIp57_*b#VQ6i z%1KdG(eeece1-zS9soH{9I$+ab5;cNd~0QPR1jw^Q}|YUlm%x{W9^k*I@&z&z3@M@71QKjkrc z-rLSiv4wZPMcO)$CVgB3`(Ozoo6z)A%$;%@Yd8bfA;wdn6>}R&&Jh|czfd!!jhx|W z1aq{xa<}u zX}AC(u=vnmd=-l#99kv2rI%h$t38p~cN2yeQht0Fhw@M0MmZN$G@rtb`K-9xxQm9l zN&p*(CmvED<^}Mnzt`PwE@RmGczScw>g8llxEKjpipd}&T9AF0+!bK5+Kse{k}NyP zJ?~3`cY9nZoO`z6k?_(&a!}DycN4Q*m7pu-AXPFnZ{%Eb2r8EZTiDFi@v>)S{ql6( zj9sL(M>*6sxmc?vzC9^xOG+XZDtH?pNAFSvv>%J!1a375%v7-)18ET_Bv+0}=&4GL z&-v{;N&-f)d!F%W3%cGx{>=>6mdUA9hRXc`yZlB}NQ1Q@FbzOWL9w3byZ&d7(!nC3x1?3G`I7S;XO-rEJE{GJUu$lb>&$!wt| zkv!SvL1qW|9!HUj4BVN8z6kez(h0zXfETrc zr``6xx}dM#!B8w@2SpsAt1Sa=>5$a z6za%ez+Vc$K^!`hDyvG>SsGS#}qZ6-UNmlJE)NbyOaXjeFM|$Mf={{-qeEF#68gSmnP8)S1CQsVVK)*L*&IRCL zo3W(Jw`P15VQ1(-yAc~7%?rXG|Ir%Gb~Kq7B;IqpcfeXp^vAXQl)}9QlR(zGSLEs95U?hc8ze}JwR{E6 zk-61j`i^5vKW`*Z@b*lQ6ep3CCgIyrM1gtjx>bjSM3Dsvok-hQDAJDBY^D?zby-CF#t03J#ZSaXtH}oRPQ`m?hsGf<6L=X^2|ihlA@{VxwWd>tM*3VGoQ;89^JBXUwI@=UL%}d zFndx{K|((Hen5-wBKYc>(!ymfO5Dc0*Mt}QkY`U&MI(DREm27*a{X!lLVNhQHFM1d zgg{NwP2?`f(8Rw`nW;_?BQRv7OYJol+j)%ST9^3Y^_#s1!{ zPuihkq$hOfc0Xw5cqRn5L!fipma5Vb8g&`!y(s**Wl>!pEv;-O6_2=A^f~zHspCun zCa1IJls$4K7Rn44f^5Zv?N=gGMvqgGranfCq@I2d_gdDgcTA-wiYXC4Q!c(A4Q9=z z^t4ub@=uN~%yC96FrnD_;FEk%KE70a#MJ9_7uWUVQh)6)5xMGYKXZ;?lTtB2mVf!+ zsQT1(=Zo1C8h%zYnd7xyAu|_|EI=bc?DC;%x*`_fbH%!TB;1IF0#W^hM0`iw90eCw zYGPGb)flITqt7As!%O)*r?X1x@n+_z;zOd_XK}Lbv$A8>&!a z?TVRV7aa})jpE;FDi~YiO;ZMPe54)=v3!A}Prk>p*5IcOs|i%ZH@976csK!m*^kDh zfG*#ydXxfV57sE73Cy#wsJURzAHUrT5$w^XVA$*(Yo?EjdPvtWHZ~BemWmn9mTI4= zE&r(WA?pND!?5bAl~SubP4PTC^__%sE(8=DqtxY_s|I$w-M!$r?tm*VyROx^yx zw@-FtVAPj0REnxxn&sIfwDHL{N*l{!(cf$lf72g4%)fH9)H)0}S_iVQQ@M;lhjWLD zo@a+abi3{;_F?)uUYei4M#?aV6&c7{RVJlga%cU=CP$3UzTG@2UV$5;_e#`9bBwDk z7CFyzI+->0NtpJfa+5@1ohugxTS!N#@?1D5Tx!ThvDkV+GPk==>dfe@vYTJJo4#hG zHr;wDIdYN$V`{Cz@0G%M^eNL#-f*)WfFF|9<{|+oxtd0i*rRIYBb8j<=y25i^Plv*k&XvyDgN~!Q+a}D! zY#x3fmu-?@@U5?8V@vyje0bfU7Kdy1BoDfqC-;R1nFcxJIeWB%EGQ89Fg!z;c0sC}?#Ga8sP>tM-z_{Pk1uv-+%2R!_kjj0 z@q5qoGNSPwqx=)5+)9GH#}``G%K;1-d1<3L!@LiNlxN`mo>3H!s4*fl{4aDT$~U0o zqnK52zwC90A=6t{zOCV&;aZuErJ_Ndc z0SR&pM7c3hdXqGPz-6kCiNxfjdD+6@qMb9mHbBO&CXdg)0n4qS6ym&bZ4B$z27*c2+1GqyosVQd&;Iz4heoud zzk!yE<7=^Dspj}`Bxn8aBpqYV zkBRH^vh?gBcOXxbQlGv>AlZ1F3Fp-r$xSx-FRI*&re?PY2Bn6X!+X_}*?do?r(fq- zlL?+oo}TCEm|LVq?v&|wGJo0FZi~C8S%Nd&nYMS9kAt1;RQLQYgoCFOCr>kvr_gGi zb9xt7ur<#a*tRdmkNJ5Qs20u}*DRU)du*I&XqP;3--eXt!Ih0sBuL|jO zp@$xrjSk=bxEQB+Zuq>u5rjr%u||REg~TIqUQ(t05V1-e{UwihH zW6euE=Sw4WGkHT<8-Tef-q{yXUDmooXjGETK`P&`?t zLH(`}rZ$4)n^soXcV8XE(E|eDAw}g!sa@ORnKjYu1=lxGEgm?-eZ~wEo8_VGNqMC~ zC-lZ{#38sI%Fejpap4kZVhJ7+uQ^kZ==rc0!*G7L9fYO2SWsKzx0L`IgUp~p!qV!U z9|f*OLD zlb?xC3lX6CEpG6H1Pzi|{J<@2)>%+c4NW2mL#UU;+DJn68MZwig`jpTf89Q9ib;5( zL^+7xM~W};%UiU*F%m6OcF27cl?BqvjAYQvFhcHHu8jtw$ZSZ71Di;(M`v}!FM$AS z9T#ml0VF4~(m!ODa|I4$a4piYbQ>$X-Rb4AjA8LWw8~H3j#C%&#*h-2pGbR*oj6dY zLrf!Ou-_&(Q)j6z;7`%9o{naw4i1)TEsvLuEezF7?WV z3?l7eMLDYZ&NU6!>NAmiA%YmyRrH%JWLB9!rCVl}F_b&FB0a{I7q#C)pm#u{9WKU){n%dpKJg&FC`C^Stoyi&nPE(>} z?W<^5?;`hRNyO*Ugq`e(O6x)sqG8UA@m9wfXc5ki=)LG3L^EAmql7AIjm zR9!~#tZu5vrq8OX2G1j;nx1uV-`M2NEHbhPne5=pV4Iw&#*1t4EnQ&{lnX@Q%Fl%f2oNNV*`;Mx@|9ZW zgfZqgGT}Sn9I!v>ck5RxJ(ihqB}j;zrV4nZmEt&-W(N=;y3M|T}SMYo@&@8x(VAu(%Nw$VvU`vb7Fq_pu<;SGyujRAS@B8ft} zwid?4ww8pO_mw@@#;gJJm!X1ep9&bhmJ6muOV`vZr2HOCi616X=Au9NS{@A-&7RBe z3o)MZy24dsRActDAJ_K~yPGoZbv~C|>)@Pq$N*|h2WdVFO2UUh~vJ59cwyN}UTcUdgR2bZFcxd${SmSo7W%h{4e@z8{m9K5BBo!r zoI1yHTfap3qF%oUR_yaoEKLCm_-ip9d1n1(>VS-q&Zo))b!8z`kVS8r{?VYizDur2Mm zLY8}4?RGOT_f#Rz2B+c_h!$kP%8+tVEVF$=n)wXC;n;Gc%;k~gUFrK(4&#pC?iofDy|{})HxXM8lio{-yVw#nzwSdiI$|*`MyX`}rjlkj&P60n z)rXq$B5PBUhru7T1>+_p{xUkC=H_KM`Pf@a`{#@`+g?ZQH~_G-^<-DnDXY8hy-z7Y zSbCB`dlumFz4`_KCd`N>56M&|0Q#d?N&WF$X2?N>weLd8Yf9gnFqf(`Gqoq=&utX& zPwo^oAy5b8!P(L^@J?79BVelgaOJcfPx^5J;#8^%F?3KX8@cHko2%;@i6awrc4bQ< zKl*riRt_39yOWbvj{3UR0PnJHt4fT4T7YOxI|(D+O2nv*f9i0y7`QbzP>)Ln(yn}z z3btHnY-ojV|I1EQ=3G$c+9f^0RHV3;xc}NCxwAQlw;=!0{36J=GKNwMXCO1%xqAEbnkb zqi|$^&|L`!L9w|TR+C_usVXM;#Y0*Ow6x0P&l(YNM*S03NQY=Ql}LHO&dk0_h@55%e?M{vvZROv$LBv1NqUHWO( zL^Vd?x^^6SCNJ(lCluFCQ=7B#cVS`=ONLAC2w`Q*3BnX^6&q)5IPJR2o7coLDznOo zmoYRAaV>>Zqkd(B;kvdX)K z-}Gv!;f0?*a{2KcX+2OS5-V>$lQm~~h}XH5c$1omZ>$H?Q{Rb=Uh>Pa7>hzG;mG&Ga)5V{V;X)RUHX4VY41~#OMd3 z(Tf_CxD?|Qs}@;6hKH9d;+_3kg4}L7ov*B2Bnmoa{)tfmEn`!8O}({BwZ=$7`9t)k z{U>|~*K&cDz@^SJgI%r6u@7TosonxvOzZ6iq8ZV-Ew0%Jy^O{;!sfd)We<57Mrtb; z=UH&6;H9Iian|7q-fhHTIMh~Sm7?pRY2E2xTa`6w&}Gy{8v0tTnio1Rzdd76Yo4bM zpxTw9DFnGhI|`XSPii9te=+H6K$-Nkz^bdorvMiH>e8|9n)B69sIGP`pdm(*;Q!%BW0JiUZ7s10K;P0$Byp>&?Y#A!5B@h zenrH$YucS@D-J!EcH4>uFwlhO6ylD&>jPt%waqH_5z=^ZJoS28Cn94jO^f``*fr1i z!mMg4id3Lfb1JKq1yAOXiFowXnJAsw@=i{4Tg|%>s@H0-fdu0?;1o5Ebeh z9AC0=7~OQz5EzSs;V54QB3d;?v!MOep3zK^VOtEKL?k80gVAoh)*63dGl=#+ZvX|S zz2%^*SZvr%pncHsN1=&{K8Th+Yb<%>$Sv8ZtD_vy7|HHSe7d896=bGx#J6~jyX^kd z;@)EXO58B)9sj;uXTk{uybc;CqGKm?0c%*A-lq^Gk(6TGU~HXs6$=wJ8A4v+M^~w& z&bqgeAiw$vq74C!r=I>#T+w8Y-{jXCJsInXcPZsPi!6obE)?1A5k=Ue$qEInd$nbl zg?lEPe;kL>&tDfq^n8|8tayuRDb~xz0*x-jhNlQcNT}I)9q9L)KRfi{Nzy~VLgfQ| z^nf#Sz4F=bGhVS;LC|(ETR`|c5pimAVj$MVWvCHn)LP%|jCyn*T&+Fy%@Hv7G7(9t z&1srT9L?vuC^pCR6F>|X=8=B485pFn!Hf_D21VFvar@v`6v6dtcVHJ&;yHf(YGp6E z&ECDzl*D5pwU*{8D{gGKAJPso4j=nY#b8`=hmm9D0zf_}e`>7zg!L)fj7o@e)}_U> zJ`cpfMB=;-id>2%ba_b#I^^+~6_HBmxuh}l@gXvj@dG2!<(C}J@d*+7Pf(8b(4QAG z@xw~zqmxVEJ`?@8kkyVXjX+$uCTY=l5b>#_3aRy=(1qS{lLvtJCV?5vuBm%?gk=+P zGM6h|<{_A)uCvjJCR)F6JoK9BNCf6G3~YrxTGkJB&_Dx<9%j1<(`R(-gX{O_&QA{P z1MMBwZkNWdA(>dZypeXBnHiA&O4A)`ZLCAPkUeUPu%B};DKq?FG*8o(zf)Xfentr? zGpxgPs%+0qvr{kj!% zYums-4t(-id~OVh5{)w$le9ikt6JJ_rhbQ+acRV>El6Z>fhbwUY^o%xwOC~-ly2ya zKfES}v_Vp~E4JINZk!vHJ`j`W&|J2|5!Ea;v<&XA zwBScdNyy7%f;xCkjVF5vqe~SZCiq!m@+j`$mweANs6BC+ZZ{IcsuHYM8@45#C9bgk|T`nBURM^zH*MD}29Za@IEKRsp zOgXKZMYl-wSlwWYxc-SNcwFw(2pi%D$1<<$}v`9*z4{xae-l1=V-DLF{O3ecp-%! z#N+O&1PD&bXdr!^O>SLY6u@ zJW@1nS!Ua&20NM~cpY7A)nzw`db{cBg^PXg_f|hfFicywl3;MztJ>WXku}+Cb|5k$ zdwt#@nTNJuKrBFq%N+KXU_A(1ztL$r*BgE}YnsO-nb51>9mUnob|37J5L94lffwyS zm*&RK$5I=|6Ha2&vYL?fOBc1+JP6IwE=*aWalU1U1X~Y#W~1i)njeLHCvtrM*)zkM zS*{qQlnqy|UA*s=_N3oF!=a0A<82e_=#BK=n*eYC(h~H_heM+atNIl+pM6LC-*F-4 ze+Ik%U+hKx9e02C>iClv`iYzW!3+JvF65Uy2T2K82}zOPaQDCCg?>wj|CIoz|83=8 zc%k0__y3W1|CbZ~$_xErF~Y+BpJ^ecpTIja9_u^e%|=J}A6TLPH<9aqOUNHLmb4q6^F>-HBi={GXx*DKDz_RrtM zJ9GaY!SLT6@08Ckd;EhG`nmG!)}OC`C5irS_1CrEw|_qWzWwv~KVSd8_1~WV-2Y$q z`ulhOy7~*f^ta^xPb-^$piJ-Z62l*kbAJW*=^5$h|7Uhd-bxlx1*!bYJ^Z)1NQecW zasCppm}4M(za?^l86SVq&dLvshC1B|qt*+S`UGIMyhvbWDe6h4@KM#F4B_<@;SlnQ zSkx$?LUw@+c+vrK7Vs8U;0IubY`vK$mC|=Fi|*sD`x&2{1Hu%|?a-tPJ4I9Udy7C| zKsV_RrSJjb@wl?-(tOb*CT7gT1F`{NAo=)`#K2|Id3Uk_0kZ)=XTbSSgHa0nkXNfB z@+gia0@rgJfWrs}qDM>paFZ4YM(CR|2NzW*&Wk4I$F>hc82m+eAPJvlGn=dv5(Y{> z>uZ*ad?7w)e!j0qYeXt^B_5+;cp7dWNEyeJ$Sp&N>~l9M_a! zjJV`koO9qcSoi_t)FZ0z9Hu0dAun`y_UQEfpdR6(a3H(EE3P*QY>y%=3mqL2pUBU_}FyOR~Znhx;QnD4M*Dj%(J1 z)*A)`!{dF7rUoX%K!V=++;npG9VAqgm9N(vPXNvkog>4)?>pVfNcDPH*tt^qd&2<# z8!t>{Y3v-;_)Ffs=32-|aITe7#nb_9g%YfTRNJ>|mMb{l<(Zl($1n%WU0v7p#kSE? zvlAS-lwI(B1|4@4a;Vrq%DoH@4Ou74?RHDG+?}sWt0@ZS4P^lb{t9!krF5|JTV>#Mi z6^&vOkC|g4yW^sohjp*|N?N_@Wivkd>a`E5a}^LQw^Pfcvn)CXM)crPaOk!%CPeL* zkpa96YlE5YOgJQwNu4Xx;_i$z1j9`s)OYCh=B{lLc(Pbe;dOFadXVw;eppH(x6;St zkl%}cX%|^U-tT!2;=0_hrn{8k=sq2KLx9{b>?h*JTBlQ^=8R*PiC?tEZRFT@&vLJZqJW z#B*oaN(!Km#96RBR@YH+yGqKUBK&vQ~aSB}|kt zE`7={sj)R0+eI6c4jtl@ObvmfHWF|l?}e2lZmaJ&KQ8R!;c$-WI=g}s1X{d1UVj91 zC^JwJS2vkDZM~8tU*xKd3^&WfI$PBfDTOYN&3nZ&Dt4F%Ulb^uxtvZVR9u|2bMzQR zH5S+U-wj@kFDqXcq|V0b=DdW(UHi=u4F-}vF#iTEw(kis#=9TrZxqY_=YaD&b^3>1`Da$u zpMGef63XHd;=l3D?;_z}?a+P;Kl=6NN&nl*zsQyU3*P+K^Zlw;ex;lLizOQ4yLl@+ zGuu1e%=D9PX8jL}<=w@}#_;dx=D&)Af5(=8UZMBz_nsof_G`M+uQ&JKw^`ZQe?@?Q zF8_XIen)`W82-q^cprbGXZ%T?|K@u1FLzPa_kgGWl>nBvP(?IBQI68k{BQ)?bO?@s z3n#z;5?oaj!22PRM3Cl#UpG-Q(HAiiNs_2y9|AlI%PEOG26hVM5 z1N;DaSi)heeKKhUbEliwfDp+FJ_JD$q4DzZS;B=C0e%OBLxQgMTg1Y^KG);_s4tce zp#VUhp9`1_@f83vhtG&Y5J->+ZwCTGiGYnFP|4myQ0yR74>Y*S32grMf`yJ#*|EWV3T+*U<4QWd~i`&`ar>O=p{MyCahudV)UKKLB#4e zM~Yy67Dc;0sC8wmS<3Oc6rf@-H2L(PXtPk+BoD-a>SSZn6i7g-VuRx?FST4{g2+2u zg#4wv=K=od1J9x!f_~=lP_=R(WxT!F6v;qjCzl>}Ki`P^! z8_jDP?A@kM>e&$AKR@B@#qgsk!Q16M^3>EGH=#Y!7if0LVTMII0xW<7DiZTK08GjuGI}bZ@x=qwB@7gNg)SU@?ZZRS zJxvKPSSp3mUhR)+Lot3z?2Zpq5N=5oak>7?{SH19+~JG zdBWYqcCXK+Yj-{RG>OeE%EZls>=!^$8Lm0#rE^BYYsHZwvY|19VTuZ zcphszIvfvbMMc#gF>o8)p|mk>_6XOc=4+F!%N|eDEDDv?boOs5UU~{=rHKW0I^$~y zXEO>Kn!r2kn7C|RfX6Mw+PX@$+74V`u;>Go7hYLiiZXN9AMHyZ+{vWYp^3+AKo+r*XA#OjA_Y6fw9T)} z8m4f24#R|g1`e`rEbDDEBDE|0bTc?#+;Nu)w?t>vEKTI4S;=x$T&9Nl`Dj5v|NE%X z@&+n>O8ZjK({3AF`=T31)?!EPuHS&Gq&6VxIrgI#J2@-DO`6=@Bl>)@GSkB6@=ZI7 zYE}+4hNxvtj>~@4NI9b=@mgN7SYcf6oF8t6S3cSGUx=vF>Fk|@KOx{rA}uC>~wRgs#n47YCAznqiK z@Yp>(wvtme75$1t;yICqgFlMG=9TZ~ZU2Mpla|3ZBTt28HTlktQP)BT-ptKx^F~UN z^_!LXI5XA~Ma(4P`NC9EEHy4|*O(?xo6wxG-NET@lvvjFM+#O~o$W{MePmF*X55v- zBdjG7LedL334>XVu%31m)w>jrmF8IP-7u_%C~ME}*=IDYmnwOoA4Su{T3c{G@vL(i z?0$wElTk*BbW0MCwm6%750p0g@#5bBH@l?_^?-B6iit49W0|xShz&&@wsUuUrh~rO ze4?ub(!Q!t{yfE;Hb#^_1$5_uN{ex-S~u5Y8NPNuKp-`fkU1$?x=6^WQU62o_1q4# zc5}1TxH~@$gXOuT)iqaZXgl;JWX=)u;~BMXny@rc=5=#u!t1K(bW7b`LiLX5?5e&u z`W-lr+rTa6^T;s0!*XZ%Ak2#z4XF(32?d7xO`*xKa?pN`^qI6t5H!|7#$lce8je|p z*D%M>aZ4*dU6Tiwij2D#Mm^-(EdAt|=nPA9*c`_&V*?h2N72{knzn18J*19z$JgEg zP3&z>WrQ?qPO2*N+%w~<*Z!b)mwKH5A64H@HeYf*584x*kk{C(ztK6rhDrTzgIsL? zOwat&h=Bdq%FNFfzYCq;auVe~{8E^aQ<32pQKghp;FtQl!VJ?tKKsuBCi>r2e!rjp zZv4vnemnoAFvIq)nSM7Sct873`ScGLf`2*NuR7;_zkeFPzHj|8!^QIc!9Ne@=eKde z)1ZE@3Q;pLyhlSaGBM(@GyI3TjQU^2%ufOGt5{?B?JE2xW`52_{qcXF;kOI<`&aw_ zX~z1y)hjz4tvVk2-`cyrPdfdb_@Vn_;OSlbu>ASzui}S+p8fw24Q9cm_=NFwfypU2 zM#4z~0fF(0-AT==7+Qm@qJc5JK_AARAAGE4jx1ylT8sY@QL&bFwODYUQ9T^Jm}O#| z9Qg=}$>hPY{Sxl@gM*hzIqi|_`u$e-OaT2QeOCD$Ax=djr)%8qfDT^lSZ5XQ!N~ z3lv!t5Ks{T)$+4)?_t4fTVv)jf5nFhV|P zSmgm8A(bWzv=`FA+U#fopIov}NFQJjH}8%T*I9Ed@wno7{Wcss(E!;nVEXwx-2n-q zZ4qFi@PN<&ec-Ef@^A!=Iz<53VodRT#0AQ<3$n?5^7uE*?O+UK0b<~#Ul4QkB=daV zy6Hfo92Qn6UXOG%)a41K54%f?OJOClCkw!Q=)sU*&IDzGk%mC9%Qnr(;;KUq)RD*Y zCV7La>y2%5bnE~i$8bRidAannB12gtVTVfC6h`XFH{yfOP^zKJT7NuC^h|RUH@-5# zzvoPT&2G_Ixj|VQiB7~p#a+i~&*SG&!Q5Taqh!N&qi=C`+QJI>m>)Njm zT?NsieGM56s6W3cgH}9l_~5m~zLOEkU_A&mGKkhiEYnwV9->&iKF zE%ie_0m5nR4%f9(vno{!m2)i|Z%;&X?V)+VQ7V2?l9jcOJ#^J-Me9xcXDvIbZtw(JV zDMcIV#M2Rz$SA1m=t6(>&|ux3O5pfjwL~5R)<~^&hqX43=ka1hD%&dOBf5Cl4n6Gn zcs9~ zia_zX1)rm1w8=qkmh2UE*u3=9dH?aEoT<_#|CxMl4zz&`4F2#=Y zgIG0;k<^LP=b#i?W)UwXY%tJ;R1!DqGoL)QttC8_B*su`!qRAsyze!>sqNh>?H(OL zXJEAbSai~MD9NO<#KAQWhaTo_-+7Iz+zM_!!|iduzlYz8tbraoN`|l`Xs>9@)?O-j zaXN$VqnUj|Za9TWYrO_Y@sP3KJe%y6WYHba|02pNdtjX0`E;!cbZvO>6$p2p*1o4l zU^2VZAtCPdoBfrhnFT`KV~>f-@+co9#`vXNB1T(Z3FAJW5w@> zDg+)0LnUI^I+pOwuo;nfE%-*q4!uZ8a&p&5}8OV6-XGzZoHpJ*x}whO{j2(|_?GUg_k2d*(l-ejLCGTp^7zNy+94be<5-KS;n$10z7iBR&4 z!B`|}Vf8Iw+ufb%rVlVD(JkYh3Ug~RnL3L|UzoJC9-W9P3aBklF%%QZ9@#WGwvvVT zZI6;7FIOCS>sDu?2osYttuTe2R#aP;?7?|oawF3#IDeaI8qe6XFR;XO%j<1|e-mdm zH!($#p%^J|OoU6m3tYrsuPpw*f*;p7yC*aK1MZO@>LFbU)s#ggpFQ$U$g5R!{}PsYuV&4_)I*$>$aRA z$iocT%b~wUpJEKNFwr}C4e8pd=P8&J;K2)Y$m0R`hI*d~*QvmZ6~PD7H#rd80ZfUL z6#wtKmg%1br2j+5@t-FBw14VargvTWN5_$w=@(u5Q#JoZ*Gj91D)0-u7x3iYJ2d}V zzk4r{{Z$hFESmjUrTX1oi~ao!zpC1IE&98vrG6J@zY5#GobGRBE!+Fif5_UO1+QOZ z?YpA=M}R#2d$8<#+3@d+cmL8cG;{fj%>7Mj{#EAw^RL7QjrYbW-tUi}YWU~&AF`L8 z>DSWg9~C<0pV#{L{92|zeaZhSQW@XtjsJ6nPQ`*N?r2Ro4ooPHN+42!I2qA^e+p}==AA;RSn<6V>hazA59RzI;VJ1l0~zC zUHmFpMYk>BAQd|k_=vu=1JVIVLl7)P@(xJW6x*j$A07w~q8;f& z1ejkGK(aItJHWsuW?;_`Xq{ISA6!YgjX_;LZW$$T$j(JYpyem~2MN$G02>ACa2?)< zIuIe90JcM{!GeIcdmUW{04r~pf*0{@Ivd{oUwY`-_)^HUco74HJ?4af(U=JCc|vX- zE`@j|R?v6}zv_Ma>WK|J8QBYT(5}-i;dSk8Aj9CTjyC`p67@O{o#WLw-gX(>3Kv^8 z<^k`>5|@g(rflC9UJ9FvGqpb5Q{rLpnj^9^RGpaWXSq4Q zF3K!6P-H^1c$!2g-J%J%mETshE+r9?@`H!2uWTX-Q&tV*wi2G4<5R$Q!y(ULl(8fC zwrVu~rYY_z+5}N~^bROHsZ#EAfQ(eEuNGSA?7ai}*CtnnS}_TEtWUd#;4S1GVz!Pp z1)B{wpJC>l31-+c&X({842OKZ`W3aHG(O1{jUDBqG{7p0jRqKmc2gd)AbuUiO}C!E z&LvdVZgKeRTBUI^?lG%J;C-MB%t)-RXM1Ya*vM6}fw3m0 zZ!v$`){8s@TS!>x5&l_mKrLdFp0%EblC90AiT7APcw{u|JF5-r!WPQ~{!rH7@Iqkp z@R%B>L+KnR>X5A$d)snC#cYKdx_wA`z!m=WO#7H=xyFI2uY;8kiRO0QxHUZL^TD@?wxNeYD!k*Ek49@y znZ=d)t}*TPfkd@lUa@?os;F&mRzH2AP6)mn`-y}q7Es36bwR*9mP$7)q?aYv&(~tv~ zdZ(}d4`=THU0Jj4{U+&{9ox2T+fF*RZFg+jw(X9Mj&0kDSs9h8 zQ8jDMnkzG7jsL3O^M4FZ%G9tug(>DUUscGAd^9DiEA8p@r}z%0!zs=ZYb$ojj>X;& z1bftlSuW>9LH9%`kO#qTWU87%Nk5|mGZ$0KPrJxwqZZpSu{i7>*E1s##Vv4Nz_P_Z zZwxZ)UiPbkwVWy3R8GLYzCyMO1|J+ADN;#~Hhvv|#KFI-gEJvB)8+7wE(yAGe8|By z@mX32%*up6T4J0Ikwr!q-3E17oY(2!&Fxaz9|-2$*entWvod?Snmk6g`bXz>e}$-52;CJ7;s%3V zp#C@*e~)7~C3P}pam-d|HLX2r%ITWMAAvt=xhRM&9vR9Q4ss!D{?+nmWK*?4Q!01D z2%7lb=8#JZ60201ejw3+Jp#Wt_j!m~t{ps$RpmFkKR~zGv zuZB$?8;^l;w%eA<1Ix&bEjOz+Y(f3X0qc3j(#)EAU!MT7J35wvqs`fL2)qk@Cc)XF z8UbV9CwI)G$HByta@LOO1dmcC)+fn!9>wX*#0rH0)8%pF{9Pjt<73ooeirB0SQRFR zL{p11R|e{ILde-ZAPo#-*|ot~-&uD~p?&;oucLj!BYbx1NK=;tRSmcoCKp4wt+-SK zHM95CfZCjj(NK2jdjTixB;qA;j_j8Wtq(iRk&+kpLzA(zg0^#Rh@A)_&x`t2e;!FG zX)1IUJfE7rmEEiGS-U3V4x=$3Vxq;){m>c-Hb~8kN2WnObfuN#kTOTf3pd)ga7WWt zgs9xte=>UiN@+b47b*EEybFA#j5gl3#=t-cFzcQYU|bQ}+BnZ8jsN7la&|H!VG zunT+Les-Fi0}%fh@*4}>#?`ZkgL_yL;{q0wp?(rGz2M7|u@qU;pn){kzDR-mfKoBR zO;hJXBUvby8SHtYxcDf1sMBxCQ)#M`AGj9S4x3Nj zrD@i=+}6OiWsnz?HA;6z$K|(X(eg?_0H3e{j^59TKM8LgOw<@JnCl~(ITl@eJgN7Y{a#mYP+V*X4=( z#pB+^SROpMS3P%G3Jcy)+1G@A>5%V&! z<_M6penj72WJNl|4IFG&YdD(YrXg@iGf8otv>+-MH0|hfUv2cq`*8-^xcAl#r(x`Q zJ^8j`hQY7N1$_z&T!Atc7p5FTpJpszEt0lRl#uQiO6l&u5s&|}1OC4ekAJ3o zDZ+n?N0$Gvw`2JGuE@VK=lvW1;FlNI5cp$nCoTTp;2&Rm5C3oZ_;*t9e<2_L^Ll^R zkAK5ISicnK|EM6p%0VkrrJnzYVenDkn3pRjZvxNyE#0@E=YfU_ zs{-pMfVeO-AOIL8CnQW{0V4R3K1h=flp`Pn5F0Qs8^BH#3V@6=09Z9%vM*jV03-|_ z!r9ibp^@G(P)@SplLaC!-x}=R*HRn6$bht{_?=@giug2rIhN)i_jX1gzc)96l)T@= znD}B0qwnp3G8hPNZvmvJr?vq|@u8?ZkXicd$2PKpeS7*KPH*LSn~K969zjQd=zc ziW-B+2X6^#U-vmxxsu}}tO%T{-n#OBSXKcwy)de@w$Y0Mtoxa4xKCxZ56GZcYfs+@ zobt^oli%kQ&!hem8qjQY6MkurX}~GLDdi*UU{jKUkJ1AbMmE?d?4$9~=HO`}W`j-L z4d8BBeR-K34-^0L^V#qTS4H8WNSBe)W7uwM8w4OT!#9g8#sLr?$CnlC*XRcH9w2}l z-%VZZioX_~4j`Y#4ip_2XYL!b6s!zDdh5K-N_Whc@edsoo)yPfgM(U zfv$Jym;i;(@3;k`GhcnG2dw;c-LKN$!JapP?c|=MV|>H9A$E%I(($}UKfm+#%kH!C zzbW}3_RF5L@`L7mq~lr5K1qLfsr)*8`aKvA6*@f>ae5AP@5aUfb?Zg+^KnEl%c5yh z5XCou^;tS*rl=bZjgzQz`OAn7?c-Os@jI9RH1!AHFm27-H~jOr-7n7tORG=5km_}t zJ>RF5PrvUvSGeHUPEX(PyP|yX`WKJk-cCE-{bFR=-uz;;TR!|^l&pR5h!S6I0@k)I zasD(9H=nvM5g{OIf?1)G0el1FgWszct^_6#+b_Fq<{Fyq9YIFAK(1=)>u(`!KPuDO zIQX-ale=kchqdl`Ev-RXm-+DEV#r5(sg{(;mN@PuO_#w+e~#F@ikL!#7qJz-R4Zba z@ZVlfHw_TpL`6_KaXccUFCB4SaqeA2_fN*2^OPCP6az-tnK4drS`TufYg6}gprVIm zt->ZW^9Q3@=@eB*x#lGLR74~ZAEP{&WW!(`luvihFA2Yi1I|}oE=*^lkB=1-X6lur zqbP`u3Fii-9;l&AVmF;dr6vG0bHU&Ba6p%)njK@UUA(+>0g%&PFK?l+qKq|UW=LB3 z!;4y}-jy`aK_lir6xx(%P$BB(UH~uo=?E!c#=?yDz*bH^5X3ROcn9&)AXgnZkFL#B z30@2JS+pp081)Yr8mg1A>hyaj$pKWo?6Bv~zA!aPzc2;P3K&*|at_%79p(G^d_6z# zlLzxd&ycIutcA`Z=;)E6QBwl>93uMkK@w8641Ew#U{xQ=uN)f$evVn{i)V{BCo6E0 zl8dlH`S?Il4A)S1AGK_3NQNpCKR6Ze@5V_yX|y^UzwP$xB4 zXf=(5K?aV+-l6UHH+A5wZ;4fp8l(I^$alb_@l~m3z65b6-5t-0Hz3Z7D{}VOf;mRy zH7bHcKydIvM8Nx1nNS21iHlU7?yXAU{PAKyqPdVtOK?+P45Lh5-STKXI0au4?$yKPrRhU>{UKVg8HeMuv4jHdn?jhxm3VQUe-i1D$HNBbzjG`QC*q^KG7lq-l24xS{ z8Io>Cbiq~$+75XDcGHy39VCbR*!#);?q93rekpxdk>k&N0em9&Q_6?DdQB1E6R|=2 z$WcGNSx=cY*rwK@!|f1<6B{QFvn2aQyj-_&L3}pJF!M4z!~D8gk6=SFmHRW&$+>uC zk+ik6WRP++k2us;aIj5kA^pWN7@$d=u<_EBzLg*xo~0XWbA>C_`Q=v2-w(7Ha~dPd z9%xgz8Td6)Gv5e8c2WytFjtc=MLN&ecR8XFLtGr=DLo0dDN|$hc)aYAKgg;hSXlncJHEd>}Ky zfI@s2lMjd(nQ$foBsQ#aw~*5;JU!{X;;@wl)vJQXor8^wLBqU0ZEbtSRI6cA!c>if z+Y2e;b6Ql~L`&YD9Iw6u5jU09Dmb35LG?)YC=7^Z{}5^Vsc{8w!&Z*Y6YOaR2}M-; z?Gh8}$ZvBacX(Mjee75SwBzw_7-W&^Kl~-tnVlsGEZ37a})&2m)OM0lDuge8eKQpn#(H2tV4vI}vALnQ8u;+uHQ5@PCD z8r_WaTh>Ls6%C`H-YRfDA)Z#Py2Efzb?w*WVf2khZD0?JjO+X)JQtA3Xe15|jbYeo zOSHsFU$fw3qotyZ%kAr`0E8C|u6Q*!=4x{?!>g-WVpBkj|2~@d6OA)vy3dFuXfRv% zTE154S8mnhTwkQt0S=2i-}w=F3w(xnf=jkEaKNs}W_QEYj>+8{AS5MM23kugJ&J`M zXBZ?hcMP~P;Xbu%5RTQ9Qm7D&B)5q$ZBtHXue$3GvFB1A@U*tNAK}GXmp`V`R-?;k zV;O|9&P~$JKxc&DEGX4Zxpry@9z&gmu=VWu*T?$?`ofjNz(hNQ_mNL|#~(JVHB0OE zj<_RHSceQ6iNh`tf!WXE$}N1}59pQ|W&<;t@1@PJxbtQESz$Ya!XsK$+2^?_b}AGO zDr`-|nTu;ygcKt?Z}i$pk2S6|RN`t)+Ra%Pml2v9T@-MBbLf#UHm@=a3en7hXT~LY zb&FZ3!J=ooT`pB)svzA19~)(GzxOQU7PeYRHcnzUR((*=xBKS6aCf^@n?fc$l0>nj zk#|DIwR7DS3I>`rNklRnQ!g~TZn7db+3jzC*Vn%@)(LMR2ZkZB

@r&%l|qN&Ww^osJX^)nV7^*U{cGKw)s3`SAE=nBPXBw zeDKv7)**M3#3Fk7EFYQp9WUbQE3GQvVf8jxk_5J=DNVrY4fZ8LoC{kH3Ju9Y5r1yW zI`UzVfJ2C5yb}Ubkp=wHY=?VFAVH$goh3}$Lfh?I+9iHVFed<((AIAv>8+B>#l{I?Ria9+J5TP zK`^P1>8+vxI`;+>qShNrDzRVh_2Jrv>#_X0YCrVvQ#vyc;;<#fF#eBxD&?7&j z-$Y6CW7v@b;&wZH88u>c4Zo6!&3Ui5Y9lvOmL#GoCF7?Q)TEDdYh%kh-l+Vw6nq6V zrtOnu%??Z-jeLo|FMm)YSO6#u12!G!Dw+m#NX)C|joobTl^s_zBm}LMV%iFpJVqi{ zSNCR%>6y-#^5!Nn$N=Lkat*tteBGmm9pAN7(M$S0CDb?Dbiu-O~m$=4Wuek~R z<>Cmj8gy#3HoA<&CLf1Ubk%j>n$q$uacOn}&HF9+H}0%S_3y9>UKPMz>j*?~6>bNZ z{kDNaZUz-W3mVH?m%b|vh^1twOR*L*q;*F1HEDX3ECk$kiN(zXTi$Lj1{-&ybW*g3 zDz&iC{g!T%FK_UMH&j6>gb0qu=p1zP7pBsBIKCX4dVY5y?!l)id}EZQek+pnG{M|Q zL3p4^QHeG&%#m3zcXNf(;cnbQy$rPC=@g zG&N*A6M#(GNUvpG0Zm~>I-7?fKGNy1hDhIDrhHmA&{jGf$0FeQg`YbnDmhS4=gSQm zzV|%eU1@ELaFR%NIl`S~=C^1__9@lHhqwlzp)+c%OJOq#LSs_m+J;wrHN?mks_>o) zhAu~)_o4RM>bMwVd2U+J;ZMBXYxmZDNZ2~45V=nvo4n{x+e#i~?jRL12P`{Q@1$l= z8@%Kdg4^0H7kefl$4}z^Vt^Pz`ZyYcJrjyi>QokCSFblh6HRRi3EF=!7xA9 z8)c4jh76=(;ggSd`nMjlz1&)}+graa!T+qW?91^NAceslT}~yxZB2FSu0?_rsliAH z%rh7;V4dWoSIX*@O{yYU?R@9zz#naEQg2 z0%9{+1P4$Q8XVn4UV%%f&45kOK{Ia7yy3H7Mg>#j!Z=J}3lLRBkp`mSG`){hXNd0RPam+CCh zN*7!0sO$2IUt1b~bGrV!vRbk6n=0FHbY7LmL~a6frsGzgxHH)b1mL8&Jr#rf*q;=i z4AeZ`&u3A^VOY)h%e{_@)d^cw zL62G3v`=jWpu1hm{rHhec!4-gM}N#3i9GA^23VI}D!|l6CDd)9)vcZr(K{;1&9qYV z+s{HzKPUJTBd_G%Jv&eE2t!@De_A+usF)2{2!Wk!F|AvS5eeDdj{VJ{!Da&2kYmD3E!?vG6)x#YPp{x!5}U1i ze*Kp*7dH+vqWRY4&}CKEZp13FNK;(|Hs^MQJas_7O26;mrsO_uE!K$2;3Y=WnV;Sd z>kU_uVMY8}cr4}J#nCx{0|O@vkC*%PDMH4P3=O@@0#say?~rZd+zke4WIhM6c`xc` zGxCX$?5`)kKQC_CHkXCmPA6v5Q?lHIf6__|jjEQuV_ao28Jl}Q%q0`nOKItOgN~TA z!|f&zOvf5ZHezzW!^r`Gc28gh-^CFhFI+$6>d^zEwlQAKaJip; z+JLu8$Oq-PHhtMM&sAP3msbPjyzJxWw$%YINHeNrl);O5zi82D##$F+)lEI3^@QDT zpc>qkkKK}iIzY6i6T^4^hS9l?l-dC~!GwDpb+h3Y4iGfbgBJX7|MFt~Bk@F9zAyEM zpN=m<>xNs+)8CLRKI$%s{VUD&B5VZx=ZX^tCgmA*jNXr%z}4Xb2BWh*iXxUVU`6gl zps|r@P5tS7=*~%0VvPCAtDRJsu_04h!|6EG)ZumY_YOHKW}v7W&3V%+it~QEo#J4dwY8ytk zfPB9X_mL}ELz3;T{g44PAO7kJQ9!? z)9yh+v7<_Nb|oc#Ieu&?jmYkeCkq4g97%u@&HPA6oV&%l3 z7_>V%>My zChCrgEjmB;&A|g_B5$-PYx9i{@qB&iQ8K;m9KVv2qD_bnq2m+W5Jd6eu+!Em$TIr6 z&vSj02m@dZ-!_^r8IJ8pvP-=gxXN04Bi|$T$9WgbZ=?baf(o4NyC~74p=p>~dQ*_C zEptn$q2K7DJ8%kh;T_yyqYxz+RGz zLK-@wn%#3{xnZ(6X_Gsmg*U)IUyV$KG6^xe?-OH?9>dgo2`c7;L63vjSDPi(bnI!Q z{q{OI+A(DAgNZa|ot*s3qdMt%R@&$G z7tG7(cl#qcrE`i}`V4Xr1=L*+^quIC;5}u0M;Nlnb*`i-{Z>4ptMi&L!d)31Ok~so&EL)atKOp2V9Cl3UsK<&>uGi{_6Co9lEf3U&g zLf(EQk+7qAGdt-1yo2Z!a6R`%&^`RlmfD}U96=GpxZM&s5GVJ5p2K#_6imP46XY2& zhlpl{LpFit;H+fhSFhl_nFnntt^$wQ@)EEcMq!eEt}4VK!7S)`S$rfpeu8%r*W7;R z_8_UV^01^I!*ND!jXDejrN-fM=$uo_M|>~swkPc6DwFezR03voVDUXP<%*CchhloX>x1LxE!o8kpCU zb;IT(iCEnDm!Z2q>E%Tvg=>WH#z>XkH^Gq7dIqME@=R8>&MP@rgsZ5Xb~J1VL1iDv zL+0z|kEl4tV#Rw-Tzk35l6rY&%y$j-<~5)iiRBq8zAmiv5H+R@$m*XBX;sdNQ-a|~ z^wO1SM4QXZ{`8-nr^qIqR8)!y{JsyZW(N8r@N&AW1*P_8wY1(h)y z>eS>Q*VGUA#A!;qL**Sl42c|BA~2hYDx%&9t0QJ!zw<;(qBq%o&27AOsfAmbVLH2R zItXQkpf(p~xvUNZN8U(zmNqTQL}>SEH_NtTbfTBTYiZqtOw>L5=X!j?fVv`eEfECn zi*4%1oqbD>RQ;`}oyp2F$ZU1tyLGiy>Y?X1lG_Ob1Vr_QHB4^ytX^6+W=gn`w?}{3 zn7fD~$nk`4qlq49#fR3swv?bFserD$ys9<$TR~o%);Qfd57z3lQY-pB~*tlK!-6 zaoee;ip@j)9Q!6vEUKiLn#l6bxJ8J^GN7J_$Ai@tSPHZSU%+5d?5mzfNd&rU9!k_5 zUB2cErNn#f5%fFzjf-`2ha5{?kkRE6X#CT7f)7iJy0%<&$LG~3{^^Y;O%qAAd}n=A z)*~qg@>dQOhilqAf%=+p(n_At#OxhS&@ytSx}KM0;d=#sa_}$~Q9OeK-Jjq6&3JyN z#z4t059qu>%2+s#L)c?-sonyBYycVD`CfhV>M2R+I8{uC8Xb&)!|g53waygzmQ|tP zj|LAL^PTOsIXoY^*Xzf<60~u%_OoLQU3S&E4sb8ZWP9{x(|M3n!qeWXa}yBz-uWhv zzRHmhLSSk#gIo4Y04!b)8zvDu+yql1mGv?L0axWyZFIiOgdE}4h);lvk*Tj0eIjD) zh?X*YRe7r14EKq594tgE4?P$3{3NMXY-Eoi_+V+r__}6{RZ438228M>_IZc&554jQ!T};yi`{_&Sr@*TX9IV zhfNF;FL#raO=^+OJVTE?XKhD@Y;ui|ck|za65&#w3dP8N=t-{bK0P#Q3KJe7I68MMy>NW%kn1MZI?ZJx()k9_$W4vjqVl*f_XU%6r7s!nAbUk$f zW?t}*s9O&6>SZWKBD@a^klK|$r}DOSzRvm>>p%6QR|`t3rupdA7ZI?z68!p%zOTk1 zJXVlZ*xu|ZZgbjHP%ItoVB3=}H@IK=j?u`-XkX{85`>t|IBepW4eiRFB@n$wQ-MN@ zY3Vg)W^F1-m=MgDQje&wo1|ug=adD_t2CIWn!|MTi)I`z(0*)&3&oRa7PnOypwTZ^ zOuH3!rJ$)WWrGlCl)!N>$t&XwQpvVC0?&0L^g;P@D~Ai$Fuu8MDCfK2<|R||>+|TG zA2FH`u#|joGkdD{=sj*Bru;M?*d;0SBK1dedcl=XB2t=B1@+i>)Q)O6 zjv+?3z5V#aAL7ye8Ve9`e)|A=kszMNKH(fw(bft4?q>OWNK%DP zuHYR@w#p`o>)^_bR&Byt<_TtKmh}pIUisSsr;0N5xkCMxr=_8huuCF(WQ_Xk<5MAA zY{V>-#K){&e=SS)3AZJB*PdlGn2~ecI%Dt)QX-4Eg9zKnIkxJ<*bNV+!6u{F)|eWi zqLOJ9xMqulK2udE0i%ewYSAg`(%#wAtQgT;*+3u9S{Hy zRsw_zdu^RqO%N$gxT&;L^+&wDJT@Z9^WF$gLx>prSV;TD`cSphI!VQQds{a|AMATi%wvxb8BD1peUCmc)FVjA!(N0;qIBD2 zuZ`+|zh>mHJ0eB#!VY1mmGav>ZX~B-Q0gzQzyKeu5h*O`qqY)l9@(_68F>K)UAGK5%LpKDiHpy1(jtX1`jmlt8J&}hp2EX+6?I&WV3b3=EVjU1JPl58b2$q=8$admj2PfJWCES+$ zwA)-lRwTHx3siBBI4d)L4b}3O&X;DRvGV>>xq`_k)tc`A$XFy}~ly zm5u~p??Yl^w~d5=moFgWYcJ1yPdqpdiS-h1=XM)9@95cv1qw03-&rC-j5@e474&3% zzFT!)sum|KCp90!5`IS=wCe%QFG;YNa=XFcQ1w^R<&UJICc@OCkSOSYEwZusP&my4M(e=t;6ZjaBL=20^`W%jBmguXV06}6)Q4bMF>)^*g z;(S47v+vx=FVCRuv?A%8n!?)@bX3Z!8gMQS0J4zS?v};BlUB5mk)ckDVHiu4uE|@) zX=)rsyg$m?ysPn+aBe%XEwSpRNU*Q3LIUie6kZTaqQw@b0ZRLT>_mid04oCx6$pZx z0X$Dy>{_>WFa!CE3t;x3y-3&9@>-!*Qi+(0QoSlLV-=W3St*TyEf1gu1nBus_m@Rf zhq)B&-kAIxJ#r-tKrMcTdH7FOefzpG!Jg;J1PRgX4zqp8wAG38^5Tcvr}mqSxLID0 zpV!PHZ6|Z1$8U3dir8u^4?+Nhjhc+4n`L1^ZisofD{w(Q?O}(Kioz+|vVn2D<+dCh z&ms`g)8zWnUjI!^rrIZnGs{{b5IA{o>vL){IG6ITm^5ax z-4A6)mWu-_ z6~B3C6N@w4vakl)cG*MiM2N%QZP6ZV$v9R?(zI3=GH?%Fn;q?7Gm=zbHAhclY?8{J zX6W_j5^d8vna$Hfh7~{a79Nn=rtdtH%k9jZP%8lV&%V z!bG0J7-1H2d9vxd3)f88bm1+4Tqula?wgcnVWO1o-rZvII=KzbAm&7Qa1J`i@$nj5 zETYaLDD5WS2e#F~zQ&YjJcL;r-fg$b$IpmZbIVh)$de5bPlp-L+XDi7(VHILo5*HS zNtEo@Qy@5bRCR60=FsJL0=D^MWOx~YKF!k~KnDao`ZEF6RKLavw@qp+4J%^smx=n= z^A5wi*CHR}sM|ukKff)15i8w7lx-uPKW?y5W!1z{uM9|BL^}i;PdF~o-6bwZ%!=zc zY3Hl8h}O77RJdxh4-F?;O)l=9)uqJRUm~NfX_xg@K`zW|Ee7;*bH&AjwJ(s1OCt*_ z7gea9>w{0`FPhzB7|2Y3XnL{PD@%qn{C2s7RIH(%|yRpi3iNSmQcUaKxm^q#bYQBY>v z@fZxxF`Wr@bQ+`?U3RC}QxiRLR}MX52ZkHJh|I@(bCr&b4LMGhck`?@@l;qfq()1q zeh&u!TD(3ny>z&W+q@xvW2Ee8ukE3vsdxSsj&*-I_6vFTSlX7%R<{qw!p+kW%Vd;lSB{`j|vl zC(WhZ3twnD6I;tcG!6?$`}I*Q{vNx$40u3IMMr#Q5?7RGC%`20fbO=bEE+^ID8`51wToY|sr?$;2Zy#14 zJtl@MsXJcO-ye{($Br-`KKoEdKWVQ%g#Z;bzfX^VSb{m$@jugM!=ym`H)#965bOUN zwEbUhh5ts|>A$>}|0^zJtGyIWI=2w$d`x6-b-;wQqsO!H65z{mM z>G{hO=YK)A|HtM24z~Z7-_QRa*3S4}SUcmFtKt6?7;S7uYy4Gg|2sQoTT3SgS_2y^ zD?M7~HnwrHr*$xMrTwS*vXPmIsUxkm+1JQFv%K@u3eXDC3jc$b z7o(M=m7v?&{!#yZU4PE=j}?54 zF#T)JpPKPs>-}?%zYHn=)PLTWKYf4AVg5Ql6WyP}{Es{T$Jn3se3d_Af6BiD;Tiw# zQSet#0Xxf|f3AN8!ZR{3{SQ`^jO=v(=YjC?Zd?iPi$kReB&RU~EfpgyjA#auhT;pg zmluOn5ypDsx@Vd~@?sB_1q2kDbqR%aDC(mKp;Y(@%$nV$udVGK7q3%?&!=wOi}zFa zJcpjVhqoMu9^zpHm3vNfhO8BUsX~dt$I}3U%d`xKay(^YrHd zQ_?V?r*m7sg~Z0B{IVfkcbM0w^NQf0Hyc z&5;NG6&5jQQ0fT67t9Ah<&$v*NL9i1`ItIIn6Kz*%o>Cmz>5j^rGf9` zkbaCS#mcu|x!^oY*>+SAx3W+XrSD7t{8{wV%(Y4H4(YrOVn|s+jYS^s3h(l7@p?Xt z1}sP&yj#G^z5;p?0)wxM$z#0k$MMsK&{_R0u(rqm!nrv|c!Qm~-?6|009_G4PvLam z(Sz_Ii5L>?fOVya(0;{|=irV7kOO_k`Vc)MEyDu{x!5d#!vU^bN1S8-6f`;5`VM{KjV3mj4+>836pA z^uq(cST_Fs+x~W$ZwEmJJ$?!X7T>Sjp3lzdpn%6By{QvGTQa0DU8!ABB%gx@~6}t|L7=Un~R(vMt3T53xD@7;m z7F6yl$NN$zJVZDzv>nJ?vpVneX>iFaO}M?bGRYM4<86cuj1wSxH}L#*5gl@+B*f?9 zC?{Sog!fb6d8;hMUq#vo1i1{<%8i1%V@^%CCekb1M%sPO209wJo2@%+GbeerTihBQ zu;1v$_hr_Asi&CM@xM}0OdMy5p^S%K-P;>)UK_EOIk+DqR_D%iWdIG?98|oG3Y+Lh zem^r!-V27;n5dekn|eFyB*;82=Qrw=mx>nwnUk=&Qox-ExfD0piIwdtE0BDE52BhLeXv* ziI{2tV}!zfxBlMp_GQg;m=D%JAn~r9XUl!~V~NcTmeBEMSxR0qLWg2FLMSZQ{Yf9N zs7cp>wPsAqJUDhNxz???^=@1q>OQ9KA^+A{adXpIk)^>hQOCNLx@|k?j~PuW70989 zkW>7gurshRfJluY$*=q#MwribCg=6zgJz4OmW4~pX3Gp)s;8@RRT%t(POUOA%x96E`{kMklUDhg z2X2!>Xt;7G$|y=Q58LUm;<4yT_~vAer?<JxXsgVC=hzs;UXTgFOxju`)i!Lk~oY! z1Z1UXtCs$JaPH3P8v31WB*KJ|)_Cr?@*29E?9XLfmFZ;j{j{MK!_~fC(bYk;@$oi> zPki3B@8g*?z0xMydx6O`s5P@gVNU$XS>Pcor|I*fqpOAzrTIjmo7SSVlzl%4JZ2O} zSZ(f}kHJ+y#*56V)RghVS--|esa~!2#k+B6`JN`?{)6h1;=#q|z zR^Fq7?-XbFe9h6qy?wrv4A%+pdW8YZaC8{Tb}vu6{dckhD)0JTO@HkUOoJ?N=VCOJ z$I*w;3ejkzl^=2DCF)h>u{d;T1z*#T_++CDciABpy$9*ZqMR3 zTT7a!!H=TDio+uPsRbtG77khW=6IE*>%bwG4y**qwn=@%@Tv@vOxses5*K_&WJx!;rHs(oD4XA{Bm2dv?9L-%{B=OtCEwGZ0z9X8ZB z&uNCjECrj~n-I)Iu0e%)w$tiwa8rK}hGL1rF(Da4YtFdR zYqK04JJ}>IQ{r40ZGPo63ux0Jioh)!*0>JX6+ zdfo)4^B^$)aO-%@v{0#+6qQEnGRaTHBs}u4oU@W~J<>GasazaztO9u^#FI^6`_X0K z(%KTQK>ba3hsKxe4krFcw>mSpYQwD*Nl2B5lt)!rEwL%UA}r#p+upu#=2Jlhcv`Q* zb7#x>@go!-QxxAoFT=OdHT#r#Eldp6EseC?sn-^@w~&mPrmCa6BUQ^k%In#=lR_4j zA5ngq9Wg#G!sZH83YkQ=>*j4X73qxua~-)%+l zW$ZPa=yD&<<%mD#Z|M~tmnE;82E=_$B!nBhbbr9lxoSgRQBKwm*|ZVSFIdn?A~+ey z%5AXfcX6CjZ%uc;1}xNwR~>dfrV4%(8!@X|r^36^^{7q)nr zWmI_f(q;irIA)1<94HX9po9h;BKLgcv}t5=?xw4u!W%;JE7sL^vhjFV>I%_2_2L58 zOrD1^E1~rM)7P0GeGsH28?31(rBm=SKn@P|VAZ#;PgPOZg-LMsypSIc`>NfpMys{D zXEO=FSsCy;tef__Ir$6W0u?EuXDQS$>)&y(E1s z-eNp^t=@09xqdZ$IqZ3%Cjbq%TjSKZaVK7=^@t16`PJv%QDw6& zirzU@LqrSDKYBVbhEI&a2KkNXXRC{8yv=w#rqcB68OVR*mG1sZ!yA=$Tdp`dDjUKb zLP6;zOMC1M86GiD`CT5le;oH-FZtV2*VT$Pe#V&F2G7;LNKFQa+^Qz#t|9qK-^-Tp zjRrw%m3gPtXEx*r4|&ugcYmPNh%{3D_7J`N{qAEwwb!=0^*9Pk!@&Rj9!D_$ES|LW z=6hZ{@C0lmMjh}a6!FDks<_i77o0;eSldhJGbH*{n#}b;Vr$*>T zcgqfC+!h+STl0ch#RG9nKt>i;CmmLsc8s0bi3IMcxw4h@572C|w;8tEBSh^Qh9sUc zx=5{9?l*098cU1Xpu^<{7kjDeH} z)!5WLMiUR0(8TJICnCuHKfJwVR2=KtwHw^s-QC^Yf)fbt?(Po3J-E9EcMTBS3GVLh zZl|+sueIO3&w0P^$Dv0W_Ydv(mC&&=_8 z?c#OZdbad zu!}4=F!5OHHeXI#u*}c@tN`^PzG|(C)^i|ouye7P!njmJ@G%?qCWbL?y|+y6SHtjz z{j|;OtgljV7eDr#1S-|{)2iHB+exZ8>ki$luGAwjlnl2(U zxrc?{C8jpQi7`f*b_TYc4ey|g0luSvJI%cK=um^42gTWw+y;+T(M2c`GcYY)c?`_XZEcKrV zdl4D|a!YD3K=H!?iChd6At86#ksdpC=ifdKfWS{E?v=%q<*7+By&y!F7DE<>wW|*| z;m5&C%g70^q}K6Gm4?8kI(L8kh-zsEiqjXd2FZeAq-j^*ts?_@Ln&C#gP!S&uTQ)3wde`n zH)4FCckDdLl&peKf*P0=3Ei=Yd2;K?5pPk(9ENGKTYQ4<)0mbw!I!+HRW4YZeKj#{ zS~Me*BPUn(M~I{|jm3i7dFWVp+0z;WO=Zv5R@qN;T1xg3*4>Hkk99JSxy$C(={eoV_aDW%3mt z;H}dYzB-jmKzsFIqd$^_rp@;>dF7q z&;TmYzci}<9W(oXvIYOCp)modfq!XezjG1(rlBcFh>OU4254x)YX3n*WBI-N*}vo) zrr(zQe~D;-5&s)q@So%TM-`2U>F>=!SpR?%{)x@z{EIL6|3ZfVNN6Ge!Alk(Z0R!? zF&HzLGMN9NSUE5_{X?PpO)2@iPRI;kRsVJk0I)%T2J^c{^#9LqP5=~~3!ppw`)Eu| z%)i8?e?0(ANB%bVujRj{*Z|m!Uw?lcJlk)454PXn7c9(w3SL|QdFi*czbyv{X`H{* zB35?BzY9pecJk+S{!>8u1)KPng2cwo_LrXYPbdXD3m4n}8l{+Qto7M@{v1jOQ&0mt zB<|}OA|h3x5@Ih>3Q%y0zy8NVn*z~R&;l@XsKd|Lhi8}tI9V-~&n>p&Em_I??cCXQ z`(tmF4R=qkcTZKX1`8?mPVPHhb}XUDxWPL}8)#oahs%z?L0y1=xjh0|SzSSfQXxZ! zP^AzP#R&pIK>_7t#FHr?W@03w?j@s&VgT)K-q}Ew6rv#y5=}g+#$qar!+-HhOYinO zD*8whiq{&_Qc93>AFi zd1O*L1q_$+u8MJC=xv?K6tWx18hX&5eF#ca6SPOa(MFK57r3h!NWxO+r`(%u%9E)h z8HJ`MoKjoo(mP+_dn`voz*6h0E7;2T8Wfb!huKX%NZ`8(MUcVH(Nd8v1&TIb6J26i z>)bsDMrlpRuM%HW)oyh4OY)It(17Q@5RX;(p%*nqf9>2x#C*sW|Jn1r44&OyThtMJ z7yr&b+ZnG>q=2b7F@_Jk(^>YG4t9pgM*=#7W;Qx8GQr?SFZ%xGZF+^kB$mR33mcR> zFD!~`7A~053iR{YpB!n!6NnHMJh&N{sM2h}tDTV(`4tk84^ut|3>WC(SYeW3z%+&* zi}RuCp;H)Hke?IwiU55R;)+On!BEtiDiJmCPJA0l z{lPU4vIxRabg#b`v}@p9-U9)$2+yZhl6r()9$`;6dkHfThI7b@ViyTBzFQvQWAhax z4f$&U(&)Kqz(!xj@p93e&Oc%f7Q0FuG|hIBI8DsI6G1u2=XW0Z(vMy5+s)te=6w;w z7rOZg1_~PFXF&Xt_3oL=4|}u$>R#%{kKyCP1a;Y&zb6L?3L5jx zi)H|yf*X=94W>q+0)gg6wFis7Wyd{5u?um-0j5GOd1*5t85>1x0e(Xm2~pr*F!z%< zE~f1pnU@|+ELfTaS4`!7tCv4Yfwm}WhWb$J{rzaudVAl|_<rofq%#A2F!1cDk4WXEYqDAW|R_8xqA6R zNlzNJ6tT7rI4@t%MN*PpiHhG{VG9;&=UxjQoBWU<{IJ3M30^*KkHN0BCe6779fM~6 zNF9|2`=MvWEuV)wTEruvkSjB*K->* z1{YPy{fdgSE!0Z=*>jErZO$G<1;_pxY5G+jX;YcY9rxR=T18n>cz5=JYRg1124YV# zUhJV>Szlh)AbY0ih$ygj-_AB(mi)J%boR~Eh+ZK1kJlpdErA6Crq2f&V2e%5_Nq`> zm&r&SYABL#OE$NMrdU+B;bYdE{WaqDAgX2RpUir%xpjDj<60JqBcbb1?v^%r!aR&N zjpv)vTq@}z#Vm9T*LErs%#|8|@=y?F#M-Y6%Q{Ix=g_?J!m%@orjOiGSiemW&R^!c zK5Egmwqw_qvXQP0H|A78yjcnRwb}VHV~Cx2T}sRZlaNNf*3o%mvWsl7A2-}E(pmO1 z6Zi=6&MX|Sw)4zl)H!|8)Gn2@T8}>Sw79mtnclw=Y_j&5Y`=T5ECy*8K#shBB_oWN z)NOHD-_+lx-WBiK!bJ48FQqkcX(bfP2XMkHj$4M^ekRzffI`#`ZZ?x2)~O9;d=JEw zt;icFVl9PR8=cm=8vID{mqotvWA;t3p1rQXa7>77lTAEDg>Cd%Q!TS4sD{`N3PA+y~tydlpy64p-c-C zu=7P(#5^}z`?PUxd(E;UJ;U0<(mIwx)kI$A=?B70uL&h?N=xlfU7NNNiDtfRZ%k=R z9S5eFLa1pnB&QF2ZTRSmis-i@#y+-CE~y4#93L^-+jY(`1#{cW8*7w4?>xoa#aMJ~ z>Y~ndlD=~-p4-Mw^Rz%yS*b*CUt`ETt4-@-i#sZ~QVy1UL(lMVLtY-O5jB&~(4web3NwIDBdJ$%BpX?&Cp{>A z$<5xcY$~R*-jU8n+OgWRn^QVbc1#kZxv^%uWh}n^t_!mnSF{Tk6PYxeg|Z zTtzM=V>SV_=yV4J5_E3|1wrn{xWqJ5@6T3>xE8SJSnz>^$QJ1tdlMlppK!yOKQiyTC1LgG0j&q71Lk>=EEf{hkt4bG*kB z8}Hq%uoc-Gc#~clcvhDfrEN{Vqi7ddxmIs>_}qn@h}e^gsCGH~oP+p?mJ5bxpoNZ+ zMF-wwnrY2;g9%op#s+D*QQ2bE#XYK3_0sFB#gCU6+-TmvK>pcp!b*}t1FjVjsuzen zYVZl79~U~e_yK3{<8Wi<2|}8?uNO;dsR5f3hPh}b zp+k^PljbLV1!4E?rTxzEr=8Io3_XeL>pSa??Mu1hnY(1v{%;mB>LU#bpIUAg^pIl? z&_F5Y&ImZe5 zCcW(JFCw&1ZwaTSu1c18l2(klz35`+HxKB)ea6SV(`@$+7pW59tWe-6p@OPu2uNu_ zBS#XcI7$9AbHtv3`!wUZfLTS>+>8%uVxXYSM024%IH>{t%A3!4H_0gNkhQ8dGfhVJ z4i?TZY6p`yQ0pUe2Ir~0HI2*D%B8IOQO*>jyy`H8!Uwu5YhY!<#u*4lH1%gaDi z!A%)G77QJu$;8&Q8pEMqF>N2RAaoFC{5-A-T7bIFdMIL!KRRFIQ{(4?P>(h}81_RG zzfMgU6iTjBtD-~@lkeEPdL2SLYAP;$wR~%)JaYVuVccJPG(SyQcKOujR~1*^66%S# zhA6I{7xuw#*cX%4G%OGg>_J0!x}p(!+(mL%1aB%eEk6G2S(jdVoNVj^I?iXKNLSRSO`n?3tMo#P|`{-k7-oPQ&p+JQma1(S$h=c6*JTJW_NLP*m3yj~e zyQeUv!N;A{;2l+&v-#YoLjQG={^znKLHeYCdq;Kqde8bTxT%E^B6o>`o|s5=g3EYI zY0LQ2C!=|A%L0hS^rH{_2x&}H5Z;m)yb26*ictG~6L+NzS#6AIppU^lRNLJ_YOgd} zv8|8Iad1Y{!@()*ad;Nl<0Y!uSn$`*$cvZkX=xGli|Lqj*X5H~9b)W>9w|TBU62?C zxov7P8P`$pniEIJ-DPceetL}IGW2Y&Uye=LzD!6OhkQTUt|(OGDNXTIFmCTF(aMt3 zn80aWg}Xo3($^H;3{IZvBgnAp<#DRT2lQAngMZ+&+h#ahW7`mW^moqVcV06M(PFV4Z z>og`W5lOYi)Oold4s;mD7NhBr zFTo^o&$ypo#H+@I%w{_#u{K&VOOoX?*t3Sc>$1i8dU;*nA*KyMpd*euGAqtIf6dhJ zW1>H;=kR_y7iIrqLtCN+)QG;TDZCULmBq6?91m%Gy&ca)!{Kzf@1 z*e%qy+N6`vm+DBy&rq%x2LS7K&GUKXSoK|Hs!1;P4UVs?Ij0fv-lb9hFl2OMU2}7> ziYd~Kv<)ORVsOyzYGj6{#QAgK1htI;?b800{K0p8mu#?BznhlW8UV<;Q)8lf(9lis zUL#&x45NbJ`7{3vcuh}m&Y^B*sNKUgKo!V)%y1}iSo)BAMp5l?!=I?$ z%#}?Zv3Msuxw$J7bD&_W(T;;_2c@l~PN;B0bH4jjy7eLbY|3*&r!6b!{jNG@QaeQr zm*#p^RVe4d3Wp*}WHGsqUZdRLYL=FFGmg3m2^lxWU%>Do-kKvUi#}+t?s_T{6C5mG zE--<8?T8{gtjHK-boeB))@eW|kW4o`Yck5s<}{9` z2M!?B0#$S^xfqE4M#Bl)W17RW>gh0!eU~7evwo14mPJ1?e*!J!4V{FLkaT^~ZIs&N zKI_MXxLxQ+T@;r!1${t=P`MYrbGq_s$b|!mjPG$NeN)EEC7bE>^KkbEc1K?6L3uU) zeHi*%#&wP3vGvdSv7A1f9j9ew3xG;|sZH4DsWjqWnV`EC9!m&*aB{J-2ew=G@K#ja ztk4ZltfuKA&u*&nGg}>DB_IK9xk8nqz0}@Ob$S`Bre%q%Igs_cye)}Ze*G7eysm|8 zCktYTa5(TEG#QcY+3+FCN};I;eOl!c7Av$5U6touuFTBya6H6Vs5$%RKVbCVz&-Aq55PV2n8U^h zmF|4{g5_3DohiHu2&La8lR0U2k>2@0nyh1nDViS2R58#KCC8>2kLqD#Od8L0i4IR% zfYHn7){O|*>B_C9t0NM~RgaZaVjQ$M++Dq~zJ=0Bv3ep?jsg z!cQ<4qhK0+q>OfiN6~6H@K}RHI6(|mGh*WlXn2-Q^@vptYrHGaiXJ?4H9{JasYfk% zknh(Oah1_rhc*#25L}9o6l`dU@RV7NJ2A;mDW=mu1`b~r zf%%QAtRwv`se(03Nc(J@X3A=>V*@$+?9Y zkV7B8&k;|Qj%uO_Ph;UD=0?RZ5y20UR^e}k?>O(mQ4S>0L=VXQnlt|P`Hl;fB|M2c zbW@pu&WnnlX((ES`mWRmcXs@LBm{^M(%~bm+TLoI+)gYL_3){KR3`99=A>x{hKt|E}zpGviKNR@$oo7bM<9fE*gGTNar%Vp0bjj#xwK3{lPhCR~_T9 zV#uRHs36I8+*jj@Q!o#1q9}~5(k-kRD^F7KA{@xOH>aKbkduSDsgrTmMt+8WU;t=7 z(Sz`Ccl}-4VUN-rjLXoo70KXyq7}ye98SrsiarN!f(97m%N4{d_v4J;9G<7M^?tn= zw}b2HhZ<)uuzbHH&u~eC<=cW6b}5X!@iNEQq34L!Vtb=bq~_WIZBAOM{oFp69&AaS zas9%uNem2F7b$b~4a3vD9rC7vO53o{l-|wvV;05_niuSz`7IEG$~<|YVI^N+KU4Ec z-Cwgm9)i~tE7o}2Hse8&Gv~i9(cs@GUf_#XGpRI7Cw))T%^7|y_I`P))A=BTJ>-d# z)(%-=p3skzC|z71Jm6+K5TF8C zH9*hv+@D8;kFDO`9hPOP-yM{A#X{b^rP~wzZ4f^5Ad4@S+u@lI^<=&0vq_(04_gSL zkJ=V1Op1T8Y`Lsug|+M+srMGU*NoaIes0`X@|WA(lRf%FddPmBdbS$=vQo~jd3n6B zbQk_e5fE=?QFou0ngD0=k_^6+796(Rxu9zhSm9aDxd{-rtir}mA0JUK3D)Mp^UTd> za@FjqwON$B!0qj*d(dQ!4F`k~Kun@Am{y*rkvRoC!bEMBZSpAk+&P2^rl%o}v-MX; z)MK#l_RPLsgh=s6-Gvs9yZo?v+9;W%Dj0wFbpv|y4S1)(PFWU~LHgL7N!1O0p)0y^ zWcnY>zrT0x`oA^*SOMnSUjh1mG|c_w=qUcZVXlaTyt3RUfcK{)^Pd{#vixoq{@wih z!x{T6;s1Y;p#Qf4|L*?L0o=#mo91!=rv4ino}Kwm_YYuz{nrrvAL;miHW~XZB5z{u zV$AR>4FAg={4)+O`L{Uy?_qdlKp6g?op*mDy8qK9{KFuF)@1(8fdv?EfIRxYKmTdX z{W%9XazYM9PC)7$kl$u!C1mFWG&N%boDm>@{%aiz`|r7Pc4mMd$OOot|Joif%CGGJ zQ-B)?*Z{!#-(C$^^ZVo1Hvepf_FJU=-z_|VbNDX@58&thmkc-)2NT!-+QCz_R6{XE zSNW=`1$_+Gas+`)fasVC8d_ZvB#4eL8>xi~8YIaq2_7$#B15PIBqsQI0UfCkvi5UN zA7z3z%@@rTVCYo{x(Mi*5d+l|;fkCH=*ER$yqq(BY2TBWyLo<|YtwPhwd*X$H7+N4 zdsvds!IFqTMMRj0DA3^DDU3wD;JDr-{vWHUoXrVs} zD22buNQK0hOX4b1LT&WiXIl3^Gq4eUE(D&eL*qt_IzZ&bi)AuL1T`v2_<$_xZ(&xx zIF`ri0DG~gpQ`gro*2EsZNar6LU#;PqHLTZE~XeTVor-Bek)ue=@Xrc9u9Luod~I- zbaid>PKi+V35{za^k*5O7m+>&vp^hTY_7*`w-qW-nSyzVc&_jVPkdo#;2FQcUP>Zm zV6O5hB1g`=SUM}&MYj1AGz#=S(W_UV=8%>GOmQ|*+S1qL6IxID;5R&_%8e2r(%Muj zc2T6#`?2{furXp*MVVj=R6i6%NIl#TN$m8vEl^OuS42TJ=H3s8AZ$z#r9U9QftuZl zqB|RLTHkSi*8o}G(~3S{!t3j&=nDiO8$39cSnfSJ3L%DM-e&i5!le~S*CV2 z{jF>1Rhn4+E{IYP3vL6%`ox;Y@p$D`@(S@mU}jy&W^Ms6b{XCcY|>@Tgkbi@Wk`17?|y>MU=cqZeMgwk@K&n?50dZNdYG-$El~)GE9jS9hR)w zF-Y3|cy#CK*|%Z3tPjaDKG@Vuv%-dk@SVZQ;@@A@>_%R-f+5-}S)QK`l^Z!gS1o;? zB@?ADKPtFPR%J>MaDNZlXD8$DHI%f>o;-q9Fh;QSiRTXdzZuXm0bGeVRc-CyPl;h8|Q_bF{)>??IB=xg8 zTRhn@pBAqbl^XZ`064jRX~|b`pHRLs4;fO^-nBBQRB_i;W;Q&sccWK}QU@>1Pc!7s zBA?Uj^CoKWRhPrLtr}yzed7In4`!f}+1=SsiO(8~cweb^Io?nVc#^aSh5`lV%;{dJ zzs(1&@V|v(UfC_ry}Q>}7Vk|08FK{MHfF+`-Pqc;QUZkHq@G9NVjWkVt1(a#+l4xt ze(xeIxJDhGr-GJ2j7-`yz$XmrNjq}Bn%lWhET>$^G?GW%jik25w!SEev_ealuZDr4Q>~TGKl^!%sSjZaTkSzN2So6`o_(ZRvBX@I zu5>r2UN2k1_mNS{#+(e2%B&~G^g@-L^3S`(P5ua5?=qhy(<>4@z1J&a7@kF5Q3X!i z%*+d_j|I<%A@8k2EJ!Z!)--N0&NiLU596?#@0U4;^p?Lh=%AB0O&gYdmXy}`kZljnmFhISkF9alWZ!mH zvD!2c5u>t3bESIGx&KqdWd+qlE39Z4qDbE6V9bffxya6SbMSawK(~>b7sA=ymYb&F z+-(0dkGH{1&DkQyiD7vb4UK60$bds+J%*`X+s3LjN<}2-_aUX)Ipx%vUArG7);ky# zWEf1z&15woL)+!ElcTX)8?4Vlv9d7U2m!As1WSO{JQSb>)S&%PGH~0^X78ZN(DAAN zv-Wle* zM6Z5Z^5+5mQGKzp0|GgJZ|n*vp8kwp0S@I?V^%qRYhyx&e;e)ZrPp7#FR}ur{;Is# z0d>OP`nm#=Np!4$=B~`Y+Rbn=|Che5|16q*D?t8PH2pd$z$pNtRqP!9N*gi%_D24B zYQMktVm5&OHRd*^fb%goF)?;9wlOqzB-8}Fo`K%R)(OCX2SlY9GywI{pYz&)W;cX@ z>-uZ|fI{&<#g`cWR{Q{prN8F>ExyDFxR>s?pZ`Tqop@ul1nc?p5TODk#IM+jUvaq$ zg6Ru!$V~i*OoH_fP!APa3#1i=sR|3w6bcG7zn)c&c?+CByPfa9Hs2R}pBz6qyv}Lt z`@Y6FS4L#2YsRSJht~&Fksx8}FcPRC7vvNcf}?*}^?`vztgfTU(O1FbM9wt}@|XP5 zg^Zj>=*&U!H3#vdpp2sEM@7*{KfD4zQTNiQ@8 z<4xG?DsqH;1#q~*ms=o1JY4=x@7$ZvQ$a1=KhGE`34kzRzjRwO5?ZF<;R!x>qyaS;~TI9KI|M zlAL7d5$aSkX8T=qZrQ0CH&eiVgBw^_2(YTi(9-uE(1$$mCJ!&OL|fKWDEYjxlEM1nMKF~#18~?VZC|!ysnG>J}CpG9}w7$7cC<^FxyYuKoh@gQ@jGqm~Hbkvh9@JZ_>ZebL0y|Yd zJ3r#~Ry~A}3cg6alQRJ!c3u$x2Rtah$!;}qoeDUmPd|!u6Z*UgkOFUUJcu;m$-K!n zS$5mrhS+>pd(T~#O81>UJ@bFaeeYV1uJ+AA3|&7Xa9c)sLuj|&en4nfc6kfX6G9X? zB5*s#e?@3dba;hWlS8qqvnJy6 zgcsa4?h98~%#>_GnV{M?De~&Uw}MnqmKQ#ZW!H|{<9qWl@R&v=L4fc-vJ_*Du(F$(S#Q(5 zZp5h>$dO$#u!%9gFsDpw0f^AnhveQ=Lwifs7_ ziVD+J?YFu>hfk~H>qZz}IPwjG{mA+L35I=}3?!#V@9fyyi{&GJFs;fn@kAVgHSzMyQnVmR(t74&GYmVQH$AbjjVmANwMtXY z&wb~v@ilq<;Lv^0xIma~Y26rO{;f=H981Jzxh8 z74vOq_*9jp;l@5CE<7C}2TgARAPSVTkL5v*E@p;Vj$C9s2@Wk72F3$iLeu%qRU)Tf z!6&Cf!=aV?t1+~{Psp?H-0R{eKNAi|PV$b$iyqjQ%yRJoe=t4Ez$cxiCCJq^f-ei7 z-E03cEVplwj=!HJJ@Lxv3e$e?Oyi(;6#q4;VlFCGCyuP)^weQZzr91+qAoJRd9#@f zsnDSXzb$!CEX${4)TY>7!U)0InX33~J8gJvxuhU#Gd>mEZT2Gn_RRd;{CP`$lG3Q( z4Nv?^|2={LA%$Osx}xkG+;`Xu&^vC6P#;t(&ox-QpeTW4NA__9Ino06`Bxv%<1{I2 zIQ+R`4shTpo@k!-&KPP>6aGtcE6Q)XgL8Ib-E%I9tJq&{QDpH122m}OcImv8``O4Q zZ!cp(7KC1i1O>~)e^gpJ+8q<_&KBV#bzboa*q{@~7U%+~E+>7bcp0?E2X6AD+Vlw{>DZQlx0|}{pN$= zoe*BTmuaOIN?5W-?t@De)-lhbxbTl@VL5r_(9E~ zjZI2Vq`gfEuWd^!a|iFa0O6R#|8d})ALtZo0wEEnumJ()Vla$r@**$qTWh5ubVQh1 z!#PIyH0j*EZt@cPATo#jng92;R74SfR|t^KM2T5i%mFEJ6G1A><>cpZd-^^@lf|?| z%0V~eWHg@nFQM@Mp4UFtpdkgbFmY=6Q5$M;=t(NeZ*~j_dMpoPRKpstn8S_dER+2Y z)FyX)LZwKGi9gr+FF~)|v@3_EYTr%RfDFZ~_2sU4rW*OmH{0|*Tx&18Y8nSb)9y5j z?!YdthxcHSG9Wo|$+x`dDcdI2clU}{B^|BP zsPJwcaJ-#2r z^ZM>Gh7mf^S@>t#$kf%ebDbOy_ zpWX|-z;P&`Lt(w4w4z9K@oG4_?VOZHRQ(TXbp1mM-$%EHwEKt?$ehen6uc0~1`KsF z@v*lxgu6!43CS#XuSi8%IP}g0EsI9j$#NNcV84f^)-39ks^{IA#)t(VD~Rj_B1WZJ zB%2+v5@h%svaOvV_#4>RotZ5Wjm-W)w|Rstx0NiVRaPz)x`*4&BZ@3bo2S4EZwum% z>^0s-Yu288r7ts)6vs`J6fXy>f_>TIp~@w0cja%$3EDC4K0WTV-R{3T&<+<^-IVIp zJdoYK;`4lAwl%D;?Mc9X4$|o||47VS&(G@X#Bo0mPqlK!0(H#gZdE8PAO%cygd~t( zWD$qkenGpVs>0|I)bxXhOjP2TqTmc`?)qXX zyub8lDTTtXqt3j{AX3-9FUzua557-h{t9gu?dU^?t;w5yzu%!dz! zyisH?mA060iqT*ZB8tQ1!=MNH_d@>P=I1YNyT{m~w)XMw>Na8ImGSS<8xO)MyW{lH zUlsYbQA|1*ZLZ>N zeRIKcnYF5Ol2ZC~J34~k&nhHQ6kPz7ve?1s#hkcr+v8-9X-hf1=8L5THJ^jSOj?Ip zvgR6j`hH8CSN3i+wmBaz$`nu%D5Lq9Mk$=kkjsjSC=iN;0xM%@=yNnsh#le_Ej?9d zBE$ zEge&VssqREVUu0xIV$Q0efNZo)Gdg9&3m;Z950E}hIi##u?D;un{^+!#`*lV1*hrEV$ zdFgYU`iOwQSjLPTf8Vpst*j9cHZz}gvSS}^X#+3frjbyD;al@5#L(LAHJO!cCYKMX z>*!}E^|UrcSCwzNPXnZlRC+-b9e(CUA3ottac&%7$o<64dkf<8=`bn5xo8$wrwx*0pwGr`(xCCQkk!y)-(9JLPpP{yvk>-)u{BY zUu@u zKrve+HG<+RtV8%0(4c$gXJs}av#ylG%ZDw%(Hv)2Z)OIg6b7cH?dx|M+F+d?$X?OY zn%BAK4va{mbVGw;5S&j%ga-xJ^#&YDVHqxy{V!`1WgTpD~oy$_r)wllP7?1qgUr@K+#t|4qu=FLH zE1vZA=->jQrrU%3c^U*=c*2mR9Nt|Ot!k#3j%Hq}EL`Ml&KB;6DK>k2D#HE)1NVzh zGCcIzTqnK~T4d`nhrJ}$#a#zCLFx}&vY8V-NI#ONJCyI~ZB#!2-?ul52&c(M)4LjV zh(5K5fd@#+)pnmL)c6w&;x7_U%PUmt#B;-PFRxzf#lIl01Zp^8bY1GQAu3xBCo(fT0l&e>JVRJhxHlHp%O&5sfve{}D#(_{2U1>!50eH4m6EBYhOvw~ptP5LafVBB~O`y%fEa^N zEk80M*Rtj`53hc5FXVGxcouP6$Q_EB_9UqV47iB^eynQ}XEO&Eumf}@fY3`%#yChS zr`>A&M29|>z^-Cf2LAZ;uHfILT*=4cfNbHo^1>#oq~-!txHtCn9RSQ*6cH{TNEoX1 zVFiaUVpnR1>J|nzofE6uiW_wZ~k zUJm=^Nkd0i7Nke1sj&+i<(jmLe7d*h$a8>!{|OBjBX3DT*=?h>$y65R*9Xrj21h}WJx~JA25^v!Q z+d|}KBGSRpmgn61A8)gs?IV)R!jSI!4B{ncDPWhmX(jF zs`>z4(go86 z^F`A(6cGvq9S{5@W*As@fsJ)sX=+|sM18su7d$;LH_6mueJzEzYO9!MwQ#l2JUvW7 zZ(mYc9#=}auv{N6oX((S=kapw2Xjx~Cy-7%pATj3k~@#uefe6#Q`P#Tv&(UTUrEXa z+Bprc46r5?hQsUoKzjEjhIl3r3s4VRDu>65L8dxXFpeOtihQDWGtnHdb0$*+XYBdd zpS{S2kF33N`=(eI;) z_=5=S;6R-M{udV-3dgr?>hLDF9e<57+xoD#_v9kV%@TppOOs(&#!Jq%rG7;z!=@3F zlin?_m7_MR?YeGbge0JPj=TK$y@QkUm4)>R)F?Bhd(SOahY)vl$9V(BUu zKSQKE*us+sFEwA;6H5W@D;-iskpqp2GqP zeR-pqc45TSZ5HzumfC!L(A6%!D}eCFoXD%;5@?|gD>cIlp4Q$y-Nk&*l!Y`VziZA; zc`?q4qS{#t_fa?WUt^ElLtwfEjkAsoQ;k5;PwC?!-VNBC{AvUrW}vqY>^km^YqwfJ+wCZ z$IR<=nnUqMr0C{d&x+e``MOPj&*PWFeG_j7KJ+OwSUMqJ-Y(!eLVUQ0UcE;1@$Yicgn)V5x*6`T@@@_KPE5|Vx@KG)!d2;qkzdFzhT1wB&r3tM=2I*6r7{=_&7QQh>u@$3 z9@c}cHKWzsuZF?>;^I2$4QsgStud($FB?NjKw!vfy%#R{I-}JyFHMQq$bAxmqKiag ztq?8wRaqGn6OH7(t#*fq2V{@52wZlWUdt$qaIG{}p=0z+cIbrOHZ3zL49}lUaF%&b zblj|UXP*cnDLPY*yw!^y%8gEH%0s)WAzQQ@ms53!Uf~T5VllHos0vU}``^K|2O2u1 zDe)5|k2V@>OBlm+mEK133F#(9!*(F{MI&laA|nLyaTYyI%bDf{iYF{p6Oaj8F=hqE z&_X?~Y62F1=s=TNZR!wDm|PLJ?}M%A85%ZZ1xfU)rAXAbA1UY);)>xeZhCM?=E#e+ zV=gS7@Hh#x5zY`4G>+N{v5j6lM9eEcmE|Qk!arU}rW1+?Rl2uo4^&GM`&tqUWfZjG zA`W9}$3$H94*68Dks}f^)|<%Wd_9# z$bfU=@PP?4(Ipolljm~SFDgm?W|>#%q2S#GeyN4~Tr4me-hWvw`ePOJIrhA1nbal0 zq{YGUv*I=@!?i`S%*y8BjlA6wu0Wm3Y;3~EpO%vjZUgnMd0kHOO@{nnCqKV`&YMdC z8*Dn_)3HiTSDG<7&4(mH)_;FMm3w8+ut=f$u}}Ln|8l9*y!LsPk1HarJ3tHpKgP}v z_$J5wey2xM!QZX8@wXUl!=EaMa%{P?kT#XN;_X=+=KDxc&>Y`U|f5nc-KK>|gxU zUmOZc0Exox4{EC0-&qvDnU;S)XJ)QHFrLtw9BjWPIRTa`2Y^_?4lrRk02Bwte|!9b zlyY$W9v)-k{1q(wlM})ATXgL2+p_@-Z`NN=7J&N+aCTYQf9;QzcUZuaV5zOp=#moT5$MTCv^831f`mUTz z{|DgF1Y@lP?fdgs@!KHl>|W zZ-MvyxocjA33q3H(@J-H?|B{1S0B$)Z)+0|I&FG&%@j5@DDWUh|7IZrL3d{^5kv;W z-mwuH2tAV|R}jq~M2sb0&~RzNLBqnYfD*gr1~GPYWfTM>RUx}z6GB=ZnuSjAHUw4N z8$06y{cFedI6|Y)P)lsUTtD!TST3k>0XgflBQmap;7}g#fX+Nx2Jn<+&o}$~v5y>;O69qe)RRAz zRGs&A0t*ln&<=pXHGr)P7XajS^Hd648VKzAhuZS$eDNMYx;cwy0o8rkCc{RsSV9ML zy#mPtapP3xY`I#OAwJ`>1L=4^N4g~D^jT+QKE!ff9q=nED3p_J5Hj4Y&FZ+3TL;&&-4<&{*b&ZxWI~S=TKIv0CLXfnh0l%1#JN@l95eHfAq0<^7Z`62ODi4cW>t z=`R7oDgVq)xcK-@c<}e&@0;uh)lxU4=HL-N&@IvL)vrJa`yGA+N~3RZC;(5KFM$$@ z19*`$j?X{|!sG1-9$KE6pHYx^;6&}6J8+`Vjjx`cln!vBY>;o@#9xmu*x&CnW23zt zpDizm<9mC;cpwKVfCUu+3E$s&mGGf0UID5o3Fe{c>KYOU*A=nh+1MCR-|s~Neu&>@ z+z@x~fWe);Yyqp38L=J_`|E3e`Tzzy{u04Ffjd3v@3HbV$FlE(Oq1|9ym1s9jddxQ zdMM|}1$77h6+C`S9^t;OXoQ5wHzO9#4n~~n@a-qY(t)5)a(HU)!#L348W=OzS}v0jR$MT9vpgy8fqu6J z?F1>+3Sv`Mt7ej_wgz+2l(N`jlU>Kat+M3S`me9P6vxKGtS2+oU2%WL)B%HRRfUfj zliJ=#lkr+XsG6w7hGz06WQ|F9!yTUw01J~*>>!1 zLz)^djqi1;10(5*`1uGJXU|S`FF`K*oowxC>2kGKtre}@PXAXyIinDriGKZ5a|#tv zxUSNv?d2C8R-diSiiv}RKY32#^+pV=ooT#VGZ=}pmt#N|frBV!B2dNuA?0R9VVocD|^>A7BOL{gW( zP)W;2@3U~9j?92xmdz$~6kOymH=4nXh33)c+>IYx3f2CMv(Vge+BKJTn7_@@hTlG$ z(CL#UZEQ%ic!Sl>`rY3=0kOnPFEWK1fizofF;kDt@075@JCEinJK8ml0RNz&wIdnN zvg?pnXIvC(0)v4S0nF{BS6O=ZF)?2ihi}NtLIIOVN#+N|EDRIioc(q&(e3xfM{d7C zz0#tag^Z-ga>>um;Q_SOYkPx8X~S}l%7%RPfjmuDT*F8MnAq{}WH6{)*ul>YRs+p+ zrQFak*3N7IZQE8hVEM*TAm$qOW<>NsC-drL9Wp5*ft=zyGC8H@Fd%-okvZi7qnxxLj0p@Ut-(=4u+Qn_|fQ6inF^cnJZj>a3BT;CU2 zv;}bUQtmrZD6;RWioNKQR00v zJ9Y6NTpJ$$8>kYXW+x00g>{0o0Hj@&p!|vuB<*60*ywOAMwe>WtLNHFiEhC34UpfL z)V!1o+7*_JnWTl*W(X8M!GhjIyT;6nfhtDw6e*dWa*VU3Qj<1j zWLa1!dZbEAGV6UoEIMA?KsD*s`O3EZ1`4jC`L42lkMFD0?-JST*Wi2!_hms&Op8(< z+LM!{ArgY~7E~o)UPLX>n+l(b|kQa=5XJ(ILQasUAhmDGuj+0!kk%Z7U50O zlod5aUDX(9Fug(h+^?nx95!Stpl4y-w#ZtXuN5Ehf?z5teO!qsSG@_mZ?*XA6e2Pq zUqIeZ`--5wtJM~VFO@Jm`q8kp^tk@)vdX^M69Yzbok(+`&CkJQIr8pZ`=}t4Dga+M z>Vt@HNQ`G5DqqTBa9J(YaZYg(Ay&GAwI)&2zcB#fi-=4w=!Om9y)Af2*YU`XX^Nv<_R!p7zoN~4&W*54#pj_*c}qaV42t4>?(O+% zpYy%y0C8(5=B`vwz*f=Ac}>fakT`7?OMTTT4y`21|wOw|5(Zi?*qy z@>;C%-xHvj8BXfrv_chOJeCo-V`XUI={z@g7(N?)+dA=7%E66mWBR)%d*{wI1apju znh64K61i8S%y}PymHxuxm$32yZP}Tk$uNq8>a3&&iKEbKx5~27b@%J~4d%d_&i3pk znh9R8a38o3jOB=7y@Cp|(ZLX`Zx}+RzlwR}c9^T@Z;-cM_s<};l8|bhAW2g9na+#- zzrFpag6`X<7Vc$Ux$H0S%;djU@bg+vY|9(yw>JIfX5_1+fwsstP?Sg$$$=>?7xFQc zEg<)y9AMB#A8zA{?l)%16!&fxZ9lOM3x*Cn)Cc1oV@mokf*uqMl&aLxVjzoj?n}d#=Dgro z75N!wHmY$sQy*{84kcgs%~Y!|(X1ajxr-e^M!uCGCq9oiQ*up-jdry-?1|1{dqd^y z#K`8ofAU7qfopW)RHXG|M^?Ds*NUzM zYm7oBy(2x&&XE>`_Mii*0MP--IUw)%fNsqQOlz*N(mv6m_ipNqX-DmA!Ndd>oeh@D z4T6ntcLDw0;eCdjL%(B8g6y9*lSTK=Eg~iTIeV@KsR{LFv6=)!a|F1Ofy7!~)@t@~ zj@U3L&OtdBP`7Al^EV`f10&fPUrG<-=`anqU6#Hcjtd;U%A!zTx5MlaMpB%A1iXSV-c-gMCy7 z*OIw|+C$aRZxTJ4ZJ@T;JstT%+*bv8x+ewm8pk%h?}9zEvo2vNjpDV(-@Vf!hnH~4 zGLe4qf&c(UW+MX`m0Es^ZD()bvUsdmnOG~lx^l~NDZ7qQUX#qdHGWhrJucBX(b*SI z-z|5v=UejtjQ=3kkhTPZ3e)>9`}+IrDXvPqk8YNFb_rPzZ}&&S&`F$%TFEo3D30(g z-`$r*_J@v538F>?)veY5!3a$FjYP!ZT4M+H`1%rBdXOgZX^Fhz>2a_Jnur1>zm;^= zS<8kV-;l8tYK)xMjCcxXHP5heqDC zszMa`hXE)BFEyCC(jP%Y^5+=YIJ1R*jl0HZDgt!XOW0xY?SV}MQ-5{lk>&YrHm7cT1CAPa!ClNw z675{@*W0zuOXT%f_W~a|kgDo)pDxksZ<;H&O<{lO%sfCM%JRkPd22$u4n`!^H?ddU zU$(y>h7i!U&Q9kc)_GYJJ_cV}nMlu;F0w1nTlI_GSY+!7+ zpAjE@e{i3j2VUF?T6VGVL`;I(z0{_5f1IN8xF;R1oR)wMD=lMqYndABixQXZBjS|2 z9HXWNp+?AfECgH$evqQK6+a@0>$d44J&NG*G@Qli;1l6Sd7jDnHW^tXsi@g(`xI;;#n>raw6P@NSx*1-xZffZdR6VNw9le@GUDT4 z)S^cAeu;)mZ&kV;c+Gw<-u#qs^c8KMpDM;*27S6Du`53a*YD#u_B+RE2Wb8roiCkBFW!9c4yg`zaSbAtBK|oq3gIiqN)_QS zISRqDl>s09ve?UfnxzcNr+OzAZHt*Zsok&f#Dn7T(jjR^# z=_qYWyT3x*nQBQ$D9B}sJ4OiR4)J0_%CeAO3MQUI5%FXjUuX-@g^wa>84`pyE+$!C z+IY+TD<0DV@AIzS8LFIcsfG?5LHaMOZ%0~UX}sA$N4%c-X?`9?5ZFWQ4bWh{OB2&y z`p zdHBv$wMy9`LzSkOj#F0*d3;mDtu#D{erxS8nkqOvAXLax7-RDrG6Rb?ED{^nXw@`7 zRX9kC4gN;tN&I>Rhr!JSZvO7V)#Y<6IRWkTxkax(13jCaX3KJQGR77=`fF61 zVj&HDSlMi*?yrOxcu>p~(%#}tqXw2o5^}D+Ha~A+<{81&wPCb9d0N3D?0r4YmR=DI zC#9a?jI5=5IJ{O7%~54Z${O!=<)PES`InWq?(LnFno7*=rB4b{w87-DJ>SxJfeF-GzYb0Cb+iVP8fO3ee zrY|oZQ69B+k^hR%yO3wwgCdmgN;%5d%kKs{i^icg+98i9!_@;TZ9JqKj9!DAOp>zx3Z(89)P7qm962L^5kH zutqC?$d3Z;=QQ=i?TBO6zvETq_$nGE)p`jx(26$9OnIRxn}ba zqlq>d8_SZ>?B@uFJ=?3lALEf&ePS_VDPcREK6b3I?_m<3;N0M-Y(563_wLe%tjSpc z^Y-C8yQBDg@Ybu*pWBwDTfl2;Xo=gnhL;EVb?QolxDh<~j|E+9i(_z|BY1?F*%Q=L z-|^sSTs=(vks?#mHu*_e#@$P}%%MluvQANQOJH-yDq#aT<*!Km%&!`;$3vf55%0pK ziU5a?0InBNn7<{xH^k_|tzD*_AVsH-81(hgbA5=9e*JU{(@vJ;DDn8m`*_qF0<({r zO7Y?gqbS{{PL&FIat!2x-CdH2ac8R5JKK#rlzdOpq~t6S*Q8qLUj{o$?{DU4Vw2{w zm-nfW*h(#!kVo#Ga^ti|x40%fXanEa2gwbwn)R>U z<5I2RG;HJ{-3f(D92%WJ7+vMp^5_PuIpWh0ua@OJ=v9aN9?|e0@v=hkrS_FNwgUo4 z%YHQy#pTd1_A;wpT;bPs#db%BlC6@&Q?cL{j*ZM6hVEF6+-#h>79TD_nPpby` z&PH1JGeFg5FK$urN!!+-B*-fq#S|+B4lT7@1&?5Cgy6(p#I5zCub*D6CE#oSV^;AA zvbTJer4_X;A_b$2gz-{z$(-gbUctf?#5M>F->oiZ_ptSStEuSvIQ%7lB*5YR4)|Kr zj5r|C8f4BT7 zSEH$;(_{1V78IBk8&a(hftOWVgGEK|Or54i&ssda{PY`0G`~q_Ve`i*#Z;6s+qB$h z@zHE?GU5ln& zf^8Ikq%25ULZyuo-l)wijU`|LZakc9u{^NtagEaEEg@*}>_>PKs_kH~2Ssg9SU9H6 zCSmrTd$QPR@JXvkD|<@}f{^;2mP%)zkH8%(4r<8~trTY1O6BmemHD(_gAu-b>5ZSE z3SRj=k3}waqdtzYWjOS#0$GoUw-z0e3krYp^T+F2s-;rA&4pE7Q+HBA*1{Qfhm)+| zX52Ai7`C1^o_8w*2am&f=YhI;Aa`6%d!o%R#KS8VC9InE ziZu?=;F(cgfnUPCrVpCXAW|5g)q?`?e2Hn`EtAwzo->m}t(GdQW4ii6gTw}9YNF{^ zuy?sBxzlAc^!MsV6$UpvBB<)ICRnSj!n=qmSUqXrn4tMRDOE~p7{6S{xQae%>_`Mr z&$UEZM0>O5{auz|X6Ah&vGuWA@&w@T7}sWUCC|jPeZ5RSk631U=Gl~>Z9%S)oS`*n zHi`(0;xZ7bKO8tFO|OxHQwmunsNMrp3+h9^_4|PEnrhI>W9v)8@)T#-|Y|!+M-DB zx@OtWaskCcjZaW0N{=@8|8Nc!zBw0-16BtUz|1WRdn#7Dk*LMmYZsOru(ON4q8Akr zl`GRN=Kg8Uliun;pFTTDI~7Iu%#^J%jV^h;ka=wEvcj=)$aK;uX9?A^nR-K24xoc7 z!GL>&y@&;d_o|V3VQ}rmead4e^f3~XC25Aov|mSwxv8@Il_3Wafp3kGyN}Y8){Ng=tKdq z)X69~vqT)*$J`OH{p((zeHq*X0+Ce&(fwbhqAv=dRo`xEmvh3zvqu|QPQj%xMVSZ~)iA8dv^b;uuIGb}- zy|Yx071J)$;EOPe_VO=(AbB;aPBzww^m3vi8De;W>l38z$ zJVU>x%#2gEkC{R54{6ga$9!}t3sviRN$sC4K`R*2=wF#Ieyfk{0n{h?fT@Zh0~ zjbDPug&tgdjg7xKjRRj0It2Iz^i^)1=sMWka_!cQqiFCQBv}HXA9YB43~?Knv&z&z zj1)FeX4bcm^5ahSHM}0GY)|@;DUqJWmAI(ELnKhDQ%Coj@v`K~$y85~Aq~y%uliPp zKy5{D?~Sb9L4E3Lp4Ch#ZBi@)8Qb5-TL}r}G4G&Vt}QUFL{WMM11qNY7a2E-)I|f* zs9!cUg<;aPCW3C)djL?!#mXYSvQ19vb0W!JaJ3~^Nm9(+Cu7+}Gc;uTzn*<|wt4u! z3MW3@n9`#{5__eMoR)+CYT5`MM@k}dHy5zX>l{u1i-w21KgCEo5vRY@W*St5@1}sz z-pu$3gKs(4)g}%Pv=bh1)JLl5jf#bmfUV6-GRX#hxeoaRj|l_0+lm z-ODu&E3H)*vpXmISrh7O6*he_x>U{Xrn8g6m*JSn&Qm+ZjzCK_Ftb)tC<9z?MotwI zc%(-WwqNYV-uAS+bt&;ponSC$1hhR;r!-aLY@}}R<7MIbX4(6|Lx}2JI_64V zQ-Qs#exS*vWn`=yq2}dgElfqr9b1-UCM?w2D~@+;rj{S`G>+Z-W0Li8#_N3ZAOvCL zzNb7&J4mf0`g`0FpYUR(+51$nHjAlQnmQ6Jd~kWW-ED0uB2`%Ky>${-?zEzvC$XvK;^Y%VGM_ z-Tr6${y&nD|GE5wg8Yk({HK8A|G*|3KfnkF<39k)KR0%!pNajD9zQV2Pm<9;&#?U~ zBH{eWPvZEQ^nXJmLHJiXJKLgcjUjkx&Q9Z|Anvo@Gk!wSYi5^2g85CEdK*v z;rtibJemLWOsNa0`b75C{q)D9jBajSND9+(J6uL)_j0oCMA}c*BcV zl%_J@gtE-*OMVDQaz_v^z`y`k1?2uFaErh)Gte#|+kk;`d@=x+T3Z8R{qpLAtN?Tj z;%F0^SOp|Nn8C3+f?)~O5HbXa>&Bt%q1h4m@(-QVz4-1tfO2#Z$^hyT$S?sSqRINP zp5O^MM}P(hqsGky5#)SqGd$)Gn(Ervs`k41r+&9fe>cK41+RI1$bekOGpm4K(>WD5beER z>xX?4k^wUZXA2uf1nwLH2jSxO;sFep5JaG#fC32_9wE3B4B+l&1ml9ai}3)7Gz@@S z0J?*GJaTz@1mKuCaC6`2@A`|r1mHYHG=u!~(;|U5^%y4jXQU&K>|TI;O4w^yuRFgSQ|8R-EHwLKu<{;C)Z}M1X*!N6hONe{ug%FbN;B5avqVk@zEopV=S* zIQ0I=eSaqS2jc%wzh@(u9r_^)sqL~8qNMmE3ke>w6IxY$3Ij!CopnS0)s5W_si=I- zM!;Ttla0vY`bO9jarn6EATWY2>xL{ee}WI>KnyzaCon=!;J>N$`woNvPxB|}3tGgF zIH7ug7a3Xm3WU&Y--Zx6>H880q5FUrIa&LuA{^#NAUt>gCu%$Y04HL*{y|}ET7F8g z?Ya>iHyvAkO0e;M-YD#N`(>M4Q3~qnYA`H=pN(!HCrDr;NWf1|F8`ZX5gSYtCcjU5 zz{1(-j(F&}wjwjSm>A^f<9RWh<5Tx$#nSRY9(wDSu3+;acXR4 zLODL>MpQ-aqB0Ff@pLaxLfnM8axMvfOu6g;sXCRrR=VyPUxNR5r7M-r8eR4mY*aoX} z-Zmfn`r>LjZ`0T>WQEz1Z@ts)OaXZesqN4&?-kv~fOKGu8#X(@#0dh!L?U?E-?3Xt)>F1 zjUwoLv0OVR;uKlKzkX)+44!IK73e+WR;l>cH+QUGi6dE%WfRE~*){Q{Opz~D5!yBM zT8dXl&THzg1JU$5>iw3jLe((%uZv8sscieNYYE_R=6_0)exk;8U_zrmVw(taYvfD@ z(6C2{YTdQ=j5T5RBT(2zuB6Ci9)j;?aeNVLoxh0Mv9b%TXwq1+mLl-sF<)~qg0(p@}Q=$9Tm`jGPQ%&%)oIkbfM!OuEm3TiqA~ZRMn>>#UDu**b?|XhmI!unl2? zo4p@0rJUk;M!r^f)$YczU+p>EJs}OEOzYi`+#_tF)=rwQj+sW{mhiq796p2gb8N@h z&=`l?Yto~oKs``fg<8hT;Bl$B)t8pG%qV(r1=y@a8mT$wXuM$D*58?ew>oI6Hv<88 z;fn6makFtC+=aa;&N_Lw+c2&wlghcdWExJtSCVl%T^s5p+W0i0-^#-Hy}>P0YIMNo zw8}6Mkei54)d>zXWn<6bq%)hCe03Ia8Yst&5^}t#)=c!(D(woq<=$y%PMv|*P{#8P z-9;tv2`=_Q`>cT_2RqDCNK=31Zhp9??I}kzDDdE!%8$;vkpQQgHtafQDotI`4Xx#$ z3#3wB798LcVSJhQuDNKiCe6y39@kx&Kirr!aP=|Ff6i*p2Wp5z%xQ+_MbX z4O1ETDHajt2~>p^#Y(8Rk9=8CnGoZ~U`2EE@a*!0e_2si?8WAG(N?}i#qk{DKPGiDr8@PLuV#OWc&Q0>Hv=M}sm3I%Gny6ti^fW;kb*s)jE3KhT@$2|NGMBP%{g`HRK zde}V3+z#_14QkIGsj%RZvsb%cmH7Rbc^RI2;%*EFGApeZ_$%B~<3Z5F@h>r&iTF>8 zFSK;8f(qWTXlb1W($0h^3)DiM`bDbO(L6yZ2xHA> z6nprRnS|yMjU^-R4R{1>HKVyHVsb_Ngl@s&w8f2)0l{)k2?60Ui;)afO?(|+;n3%m z$sal*B&sli^OgBjk%Nobtf7hgHZFIrn*Me*q` zgP%1|6tqWj%t{g{Eiz^m;Z7^b)Yld}UBMY1Dnh8tEagB%TDDH=b2mI+l;8c^&Jv7s zAT+h_05-kivqyLzVZ_Cm#Ze2>C&jo$m?z;SSJLJ_Ra*`#^c~&OB+=cReUmlyGe8O= z4WMwIA$%+!TNj^FBl_d4?u6AMFMfq+?hv0h%RyT(P2PRpv8y{j!#zMx&u%bbLhotd z4LR4bKx`-qUk+v#D;Ckq3pF!(*?UVB%@5o?o{kkC55}4R6V8HUv>a++Yv!L@{GNdm z*dPKvE9|AQ2hMffu$(_h8Qa7=*jn9+%(o-yWuw#BwxRdWp88JAlgm^d;2PX2GP1jt z{lTuhHP=3Ned)}S8O(6i&JPZ-g2VRvurXa7^efv;0VSV?iNGxV562Bh^^EB>8{2+i z?zMO>yV@4NG;;U57JFr{5ADA({1){e7aXDkFV?W*kmRi6_;CUFjyG-~#GwpH0J!#` z?hITWgL#Oz6hsW*dD|K)fKT4}_NcV&C5aWp13tYazP{>m{T9&nIU;lZo#7&WoKWmrvyznHP({>_6~*(j}jHOl-V9CLNgqM-D^loyNDZ;-J!O&Bko%v*#F)4~FOLFh)*+##~E9ZZ~ zJ<>rY#^=v8#u6%nY{SEr_4n8C)tj43K9rfuuI_~hG+%1@#l7STlLl-1Ts(o;v{46Z z#yOwLXx+?f(w)rp@id|89D1zDG7Ty2V|;m^FrVX!9#1dqAmO`SBmG%a3ZcEpDr@$1 zx#nKrTNq;@##}TwtJXr?+^!^#gOufz7F)qE>Q|OVdgTdOpL8O#8L&WM@}>5XVk!17 zGuxolkCkIdi(G`d@@Ru$a>-69m#F%^_<_^?+leV-wF}IQ_}ztiXaINLXt=$6{X1`K z70FQlw3|q&jOU;u7ajY$D2iU|NE4O>?rPJUN!1FVsUUmklLU)IT8*1~8B zn`OQ|zBE`nq*?Qpxx}Om@bt`y)};l@7t(=kTD*+SLpn;%EA8&^?Srk=nw%NoK&V%; z;vih_@L(S#40IEMTFYl2yqB$M=bF30brtZoBM2pU%^gdMt{r}!UNZgoGBK#CxLKx> zT3%#XKAPOI1d#KQHg%qCS9;7w8K!xLQLPa+J8*)W`lE6%hs5rf#|M z@4!28Rs42hBEG;YT4Q-pT4PhkqkTT$%3Odw!3GHR^6w{?1L^uM0~nkcqo~O6vF~;S zuwt{rTRHbF)$UefL?Ti!yAPX+4%sR)CGMjqc-Cp!>>WPoGv2)cG)vi$pAJP@N6EZ% z8hK!_&AnY0xU+?T@zvp7N5;UkLexT)d};~=darGSbXHwvy2|6W`p7hgmE753#wbm| zRGC>5%*IKNs(&O*O?Fzggt`GVJqJ=n7B)GaVcv|*M85_a@P7>fKp)HsDjA=guIzR) zw|*O}B#L_HCLj^F%L%8+mmrK)y_MA|A%dzMkiXDR$}F(z@5V*AW}l+G9Xn@i68afs zr#|dF^K*X`gmUd2XGsSuiT!2tULD;VDeZet1Wg*je5cxJygSPoNkHrI{iIqjAm>wiIaa{aG91544 zf``+W?>;tT=Dy3JEq5^008fCy92MDu4bGPpyx_QJ7IY!rr$UMk3cdOXRagdu)Jyl| zK9U}wRustr0srQ1I0rxI9_r32mPOADa0W8fjGHC`?pxAF zde*_B9TuX+%ba_&8m!1$&L_{RQP=aGP&_u z2eQ<@^#P-rr_Y|6vFaqR5K{$_ji&LtSk zyPlpH6hAhGrVF6uX*hjQl~fhOhY;Vq84jh^TPHj>#|dmwPC65XIJ?|1r_l%;suQ?! zS2R}tjWk;Y5er%%zsoI^OW6fr{u zlpNK3z&ty|%|p>!1k zKLjsyBJNRr!kkaRoHO`dRQgWDzTGMwQjsR+%8@0fL7&Y))Q1S2$or#1fnmc3hr*s6 zy5_nza>0XE$J$g#j5Mr+b^k)IGSouQ7@~-5ltIPl<3ax}%7(c2K_CyE34vI+LrNuI zOy!yk(N;dntqBE6`qHTOAe?*|@1Q@N(7Xz-Brjg6;*cm>YJEi3k8XI8`jzdP;^?r7 zS86S<*EO(w@vc_h9xJL>Tq~pXV8N#>fH5WZLiF4BnNJP8og|8Q!HR~Zr%_BCmk*%$oNeHPwxO>eXDif+*la0A20v06jJHO{pqbxa+(yBaZHV|SBBwoEs)|JXxL~PNE zSd@_MV;YA_LayRfbF~+@ia_v`)Vd~(ASGL;}qWZ;p zotF|tL-nx9aYB*R$k|&O>%|M&I1pzQvW6u$5+qqhdHZI30nCZ8{qJ|N`?j@mt1YNx zQnOcO%(&BBu2;mNn}H2Ee~abDJ*b*Ms+V>l6}$!NtwHLLmVM^-o^dp5dZ-O^H4dp5 z;PC5qa=Zi8@7)P8BjRDJ>K;w_a} zuarVYlcy_6d*KlPzxsm-w$!H2yJQb_vCVAeA*vugdLZK}^O&wlD(j6+Xy5qyoEfY- z^`DbX(`Bk)be^OQMvHfp((b9b{cK}UVXDuhnA^RVNSu-VnQO;J`KaZ^30Hexa;M79aOZEqyU$(^w&pZPp@BHNr zm}XgNkJ(!x-?z{l*Wni@qaYdFH(uS<++$Q9^)3oPKU_HsEzu@Pfq^i`=%cdHZ3FE!q1oJ2qb?f~pz_cxY@2xw^T%aDi zwyQg(9rmh)$0QXnVAdHg=gg@ip?54y%70igA3{S>V4CZI?*ri1kwAuX^i-FQ3P5ch zjkBq}Kd;>v&H|>Ec4!-P2`)ey9xllP=CQ{*c+5{5_gT~7RN>sWu^f=lI}CsB`?Y*= z)I}p>KiaAsjmjE2<(Akur~d^Znw;^AyHwud&77V9{O| z5^vIW-C`LSu8LI;G?LDUUJ3r(zBza-dyURSrx?^Jtx**H1cwKT50jy-1s?)INH3aB za5Ed9y{9WcsPwGBdBPb&@k&@iZ3;cK({Ha^ zW^lF}`+3Cx$Fvs4G>po!oP?RQfqBeITUQl_#pp_ds;9)QxjfGG!sw`w=Q!%M@>W0g`Fx04t}sXoK_QZg0rcIei7?*`AhP`=D0TR}o2R!F-nqGFVFalv1u z#4SeH<;fKJG?G}aL3(_nQnvLsB^$m|n#M4#jn=Z(8>>BJ<8dDBsI`Jl7DGgY=}sk; zN^brvxAm<^T_%n19Vrhww8u743fMtbPu3s;N9-;6uQ) zN!q8Qgr`^bw*=!BvuOJ&F_@!Zf; z7xjCt;Jl}?Dn0wNN;S+_dg(GYnI+SbW<69CCxG?7co4JCESo+MqS4P53dj~d)RuRo zT=|)Q!eXB2Bfs&$VhoX5&KE8mE?5Wrh$!y}1pn57zU|=bZ%M($x@X#rPr>EQAc8F` zbri63!@3CHr9w(upT~a3BB7m7ZCDV?R|tINDIVr$&+4i3*s{;1(N$@F5VOHC8+8zj z=MzxFNXLq2J&Y7aUaRf`A(5$tOCZrEV`Rd_FoXs8TeZe_M^Kf2Np2tI-3d~>h)g%v zV?ZMO0@;+zSZ=kX<0yc4rg>V~ywlJjMC~D#z1EtX*r@D=)pmDt2ptPSCe|*mrB75v znRNCi1J`E;|62mZd?!=*qQoU|!gt0={Nz=&1a%{dqb8x!JT|5$gWRcM;xX(ve2z3? zmJzJK-tnXSS8(P#RG<%y11L8$`$~d~xdU9cqWuRd{Jfx~zx?#y^RA6`lbAag!#BJ< z;vD@2g*CjYbM_ORUPjinTAecdRDaj)HxytwR%Si>VYf?TshSN%rN)O0mK_qB=Z0eQFcN zhn{KXK69Z-y42aMf-q8v7?vSL>f=_Lr&2{i8gFH}fYI{yyI^mj+us!H(dlOkd>VKA zgjt4;{V8%+)v~4i4cz0U4+qoMnLu;u4}>w?<3#~BZIY*Ea@8HT=jMK53ri~=M2bw$ zckhDWHC4Y}a2+{$a(Rt-^LrY>?WS@P#*1Ie;>V1O{d1+zm%Bzm;k%*PI6a%r?@?Y& zUy4ai1Acpi4|0*uptWwry-LF#CW2NZhHaVbEYCebK-0@x`qsG^_h4G&Mbk;c$Tx4{ zCy9eC`8FTE8#xx61vfuTD2_fWKvEk`g*_UNtFzr{j}rl|N)O!)P}5-d_NrN41d8h) z@vaU-k$CB8zS^|lZ=g)HmSeFUFvD{wj8DV zzImvVp<`BH$;<^L@DL((`7qnyFR*alcijFFJ^r4olZ!tzpVcAe6RMZdX9G6v`1#?0 zTWU(;RP z2qs(WV`+q9QedB$Y=qL`s4O3{xsn}%6jD_3a5T9XC%$@*il5w+R;-390%MM?9tOL? zpu_HJ*}LYpN8$L!8$Ejpo>nmq`iGx`UByF0EM!w2%vlWvINIjhdj}AO+%1 zJnynn=dD844(dzucVfep86wHMXDn~~{JSJJ&!{fpwyuzkr+S*;o3p6dP<#l=GL<7A z73P)-GCm-Z(IH($R>#AkL~YgZ1$~IDNYAr5x$_~zZNzTGOCw)=sOJ^pT=Lt^3oOfd z!8}D9T|89NbUccrbqw^S?JetT8jZH|YBia#0z((=Y)(7ZSyFqATOx-EOzCA9(cwsV zlRcKTlc#=jOpW7Mkj?n`B?EkUwK~})DE`(oQ*=#9OO2mMoGz5hJCqE6+Fnbx!M=gi zoRj4UE|#6V%b^-;>jrNko@RkCIuo-ufBP2Ky$?@CNAl$uMWUl?+N8+uq~*V2vDELd z^11mH?9|R0C>iHn$+LojbgpLB*K!{uXt}#8&ZyY#v--V24U}M^1)otD7lp(+O?%NV zf3AMH8=X%duOzjz)SjfG^x7Vaf(-s8tTBy^whr4%Ibjl+r@Y0+iNnM z1hL6MGemWKb{JldNPT7@b=nDL#quSqRQeOxKLVrA2&N0peCF=GUN(%IbVB>hS|Nh^&?FTsysRxyX%x-b>>T0Rwqggd&>SgQWp z?)I1}bY=IBH@ZfPf$VFPZ{BL69Pn;OR+%H2rE36h>XWAj5l20vd_8(I_S?JW03oiX z*V**Y>=W5u{%tmPWmc$rP~Z_AU@3d?U`#r(C7T= zEub)H5-b9vO3>sR_PSWvvkb3F!H`k#Y7ie)g;s*Bb1(0&{GXAv_|}M@qb(|<3q}hO zCU5qR;e^2^QxtV6U|Ha%}hQ+b0ZKH%>!69e}p5QRJySux)ySux) zyE_4byIXK~2?P)B44g^UT6?c|%Xi-I{5sb)Gxcy95ezOfL9^?z@@3tjQ8CAPhsPvEYt$=lB! z^FG02h&YKTSP!l2do1(}M#B)p8#!p3Qt?nFG~$Vi97JL-+(U|9>}}^w&dGV0j9W2& z3WM-rR@9C+WH1@=p2R@BF)IIJne8n+S>tk{7P)-}PU8GAbN1O;crjph&MS(;(I+Qw zXdx7z?5@WkEdraTz0-=FxbrMng^F2sN(A<>HnXosWmsmy9z!rUh~v@U2Fffx;8a?pUA=DlW?!=RWR0QsvzG(uJ{=nF*$-M53t9YG&kpVcv_(G1UHPIG zuT462*d4BTico*Kz&3OY$#Axl_fs)_cMiiK8APum_W*-On$MX%Wb|l{BYFUc+s|Xz zE6S~B;#F;2O~awJcb71S?)M2S!?*ZT_3Fuu7U&h^wVIEVJGt{s1=_dtlRS4Q?-Pr% zye_xKuBm~+_(_-$NHqpuvCY`r6lcR=IrFzUM_ypVCgI9sfakZ*27TaV35TXjPo`2T z%_NivCNr*n-7H$|u{v^eL7FRvMDBYSRB=gc&cMvq5d7{}!1=4-8wL%SrD<$yXy>nQ zo&l=W%clPZ5o7pMBjo>vi0Dspp??w){X$j!6Cy?rV)gkGBE|p$8T|`HOjU`GUrhB6 zh#08gFUFr=@Gg5ZTSpsvf`3zf`YtsN%^0WC4F@;;H-%JZ20q z0sKe!7{D3e0&oSm0o?x%B>Ro3`a6*9k3j(SA*==i-7i+5KYl>~G7t;ZfBOC#_>18; zGZ9Ggj`bI440H}w5P8xsW+WC`77%FcH@NIi2pBU9GXWhfNNxsH5JYRl0>Yw!EKt|| zQrBZ){RK#*1@+}`@}+;P=NCW>RP2|m-|rMu69XgT?`!O4)w#GW{wGYQwMe z7grL9T?tg0@vl8>jK8my36%c+g3kI+=otw3_pi{%|APjOh~BT^6*RJR)B`A*8i9T# z^{n&_^#H1709iADf|&_ux00=cnI&jsWlceu4rTxuDSS%AXYXWXspsSfa5S?tGy)i!fpnN0 z%p3rJ4JQE|J=4NM6Lu09T_kVcuL>-f(j4yFBDU@|1PRqOANZ z#uKiuPd6N=Jd+Q{&l63ZJe~VqIcHuuH=Z>`Eir%|C4%)g427uJZ;1G#39<(C_zjVX z;zz7~i$3E9xzP(!*zJ$#iXi7tTk=A+3ph+!ig<(*3%;S^Yh`2w7Xo(~?VfjhW(5xKlSuj0_dg`m=>*Fr(o3-NWvy5(CmZ9SYu0ez{Rxkh^(g0PrdJ zIH=`-IOI@K2wPT|5DT<~P}DL>2go_r_mHqfWVFC)M(EhD2JDOh1oY^iAiez3dkDl# zwl-g<#-%>siTRQ>67&pe&!W~9_%gy$A8n>-zN_OvGj0vIHKbqe8Pp>gMG}%zCCb32 ziSo*+MV@9w?AxZrmvs_-kiOJ1E4qMu;T*{$P+nl`&L_d7*%ofmJI{A>nqCkTzHWjeN29X^aT)jDYg2bI!;z24KvFnhU+(j|5&9^EHQhz{!~02S z4@)dgF?76T??!6qWc$T+xQpJR&JG)jVToB(dw!SIPP0bKRqqR*Pg8D?$GCC+I*qV% zCD5{xd7j4p;rsYgD7J0TN`-9{oQmTNY&ZfpB zbuJSk?MdHZtLVbP-O3sg@2CFIiq>b63^tZHZ-ch!bKUEpIw8AS3FWWWxeJEgqQt}5 zNFJlp9ZK$M+R;|)Bp6);?Lgi;j_3i6ir~{qk_G6SfB?7NWBj18h7r6O6Jdc&njX%5$?6kpp*xT#vaM17Kh=9I*h$sPRw38gv6xfQiqgPfPxu1hqJNCSI? z?#^UjtP$k`19wvDO|I!)(Nc;ov)rM9t@M^|>FKVILPTDhO_tlps=LI*6j2AM#=EBU z8Kg|*vMhJnuc0A+@@cWRfvQj$x3*6JC+50Q6lnVMV0TIkKR|8zZFad!o* zzMm8{t#gnH@8Qtq`M>%znGSKyVsMYy#R~(*SJ*)7z z`6Jg#o*Z)Xx8?2%B4%+!6XjTObUeAjI4tLJ+N^eCho4)&RF?SvP_UPZ6VI$-x6MN= z@M3}x(be6o{QA(mjU)eo#7OF!`Z}xoMF7UY`6{(Z)OX>d^(!JE$#+YmBNo0gEn!)y8mZm~BLzKYc2Z`DM6KuV zc95Ombs9?dQ>IZvW&7xsaQqu&6u7p8#ToXLNTwqR;-1apIB@ca#*1nW0JlXh(#<%Q zh@HsJdT}YvY2Pkb5}AA3xq}SG8}rOII|XWX5}sNjL+n0Tj8fV4m|pa&_@I)vvEw}M zGxIJf@g4C^M(S8q&()N7vc5TQ@4P@-PjFkB21kL6>bWH1@Bq5~@UBR8My#sy_up(J zIwqx7c@U|~tRA3mA%CiEE>Drhj{2r8E3>=5+|%s^we&rPXb%DUq^M844Bhm|zBKEW zmdCXWS)Epo%-0gTGetlIE?;QXSL;Q_U-qIJlr>>KrJ-7L0P{sj(7ucfq^aXM2eLIF zm&Mf59NQir*H+1q1X#NukJ?!tf@JxsmkqQUCB}Jc(&PH2jUi=9h1Ap+qp-4B5pp3@k5cWFJkFKqYfXMmHeC8)j``VAT&+(uXyekVOtyl8@8}N*3w0 zW6NAa>Io!w^jfBRlDlgjC$8cwfzyYjARMGU*P-abAfz{JyN6e`Nq3&mymC_VLk3wK ziaWjq#b#<;YdTrRrTgNIN$XqvftF25o@Dz_p7P?}@tN$Q8=Y@ahYwQN8ivkO2dY;Q z7-5x{dg*o~4?LRPphZ?PXj>7wcoYfYZl=iRq(5$i@cuo1{uRXh6`%gEmRS8-bM&t| zrmTODpXop=Uj7k3{|cD?#}X@fQ6V{baZvoM_@9V;|6K(1Pfpw4@%?{`pFzr;|80rY zzf|}4`1x-{zRaKo{3C$=7b0IeP=p4GpnpYujLZaV%xwR8jg>ygVYc~u9Q)hd`=4>_ zpUc@`H5i%yHFgBWfB(q)wMgk7kskf8MNfYX&_BG!U*fBOY=FE*)?d`g|Iuq?WT5@O z@ETbY-Ebz75eu9|nQ`VL42L7r!qP-3O%xCWU^Dc;wSO};)*j^e7K&0FJ5HV@878JC z97wbKRd7@ku~u$+G%vs&OG3E__i?48^LFy=>A0=)?rzd!bMmS!=czR(rxVc)e>5HH z!4DA`M_6xK6|OsZR~YPzDLlW>MUnZ6z@P#!nu#h)jTqCT0V6am0 z<9`YAzyBxC70C27c}yv#Ya$ONb_CojY955 zfPcf5M}QF3t^ejj0PI_DU9f;CTD5Zl!zTf-Z3e0DP+sIg{+Y-vuo>?TlsDE}F(PxoYLb|yLzn03Y!jrt}IEAA32k{~D`kNAj0G%qJ z@0UNkE2L|#tf>%8?KPCGT7Dym-0fM6MTiKGCrZqqOM!b{LMzZMgl9P0$xIkyHSHf3 z(bi`@3Dm%BYEdOpz_MJ*!oN;A;6Ec8e2Lmyw#DMyB7lnO(cO!>yxKdPQYkoDRtz1~ z9m@&8#>=&3MdRjwq1hdVXAOtMvivaomN$E?=3P2M&n2ZVXS`@P{tf{~vRNxG?K^0; zDe$K>T4+fE=6g)$J}?s7rA;S>%8#>bTbsD9Y;U0)_B5U&=-x_JVoviI)YkgBipa5o z`}U3$)vA6(BuLdGdhM{|$w2uA8RmR>hy~yC>>#g56Y{ohd%%S(<{9qRWEc~|pEEZ6 z0EnLd6B#O-k|U1vOV>HMY#1Ohx(%OrQMwy5q{mRR%$-}+oTGXdMzpr%2}`ob z(3oZG_g5DxN(CtfS3pLQm~OUlDJV9&%{?)EJ;X{Q_zQ9A;p^Bs{_W-;6NC*BZSejB z{m+kVE(}oM%XaU%^Nu`hMw*o0b}dzCOt6RFHN%)KQt42(qx?Ab*0jgMfJL*6o>G{o zj5$dazTb*QdfsMhIs6%T>0nCb?@maLld?oLciY@Fns;>@VyeKi!?codM>&9`9D9Le zKTadTQam@FXJ&lPh64yQhNj#9X0qeom5FsBjl^Q$>P^teyd< ztc+MZz=;G;3M?dKCuS%`i71G;#EX#zNqyo`sB6xB1m4E#aa$t~>0WbC4 z{uC)i`JBUMfwj;gi66hbb;fNqssH*uIZf)!;Px z#fD#^)|ZCU@j8S`WuTUDlz_OLdZ8_O&(@_Y+d!TScW6HQ(1^vdrsd~!N1xS-V$s&6 z&8;7=iW0WdBgw7`Ug*u8__3#1ge^y8Q#+ zD=+wu$I5VdogT!apVgzhfM|Qf%wQXZZ3%n-v|@^Vt%BUW4phF$Gg)AmU{03nM*Y?^ z?e`HEuhu~k62NDvuSxs-Qn;ZZ?l*Zy{phIvNK*?(_};|8hjk2GZ({oly{p*eh|H+5 z$Q8=^c5xHnHQA83m@<-kBim7kQX~5Zwy?PmZB%v|Sw6Vf@8^qoB)o6wmEzSyGF-Fb z)STxh1J1udet@$N%a`e@s48ecCpO*HGU=E#w5zk~YjHK>hd5I_D9k0w9$2xmcX%7w zsURlI4o|My;t_%lpD2`ltjy#5p*Ah8^j7M=|BA*d2hZYl7g2pYqXZCMPjAoua<4cG z4~mB*zGfgUYR59CC~B)$mpBw)O_e9Na%P7sr5`m3V=sVz2Ylr993++6yLod%H#4US#u{!_Se9I`npuy)Fz4c&#OiPw zam}%z_A?`IOtTG9ceHxRDjy5PEIGOsix&G{rvkL~+c>X`D;8MSG*SVvvrh*_X>v8p zNeGp#Zt`|NxKH?=Fuq?vMeK)A7!nUD4B1>4nHh^&kjCibanIovy8S%EY+7Uc%ugz1 zsd^;*)oKJVoap%>JGvXt!EKNUbhZjO7uh&ZxcFMxFPyM=KQ1AwqSMJ=gm|(yfcKeP z+GroC3Pl&%2)OPR5|0p+yz~@P&tfVnR6DgYdObb(Q+j<_cHJ{6fG+KrUE9 zyWsN?Zpj%$K$c6LoB`lguf|)j~=S9EDr{N}i`xG?vSp%Ei{j#_C-fmc0;Bc8}>MGwk zya_PMtSm<@b;&Ciz)Ha(qq~9_^Om%JVf_Xc;>VH%=@26ZU z9ryRyC3B-IFr-gQs~YH=J3GntS}g7sUx?tvaA&{TQs+q`FTI?UumhGqTA7sjHFW5A zFtY*Wg6C*9%xq%Ys4PZ#9AY}PLNbhMN@gaYCyndIgfuEgiiS7VI&Spa%Au)Cpr_Oc zYmlu~sQ1S>IU_swE0ljGtZ=sF8gK*oVgkHQJOFPjEEzVTt!nB#Z zpYZy~p9@6Jw|mvl#_tc`X!zTNdAA2sZ7k#@=R;vPcL@nsx23O%lAAd#@5ws-G+E`% zktwmt&zLE(2#1pNSu1W7SY-ltX0LAUbm-tMTN(7tadM@y+v*p9@I|@Pm5ldf=RRq}wyovuU!@qguzgMUK z<@EipymI>gKz#6bubi3bZ%+BImni?kDVI?c7FSgQIpy*!|Mp7j_sfaD`?0?>{<^sT z4=(xtsO;|!ImnCsQ&;2f@3a2J9S3#IpWZk<=pD{~)7AJ7PwoGB_RjY|T=ZYQ_1~Mu zK>Mp}Ky8E7U;@4Q`TO_Z9d_2=;upX2SwR9D|8&^@JjL&bKKifcyezb! znB_mY>~u^lY%KrV2fa;3ikj<tDYDINZEYI9Tk_3q7XEE*0=`>6t$X|}Y!|m^ znmRismq*y{_C30^J$MV0@D+r048$9R`0^_U3G~fv;1j<#Iq2!?8E!*{l9$%ezE#Ca zOA|sNBkRxf6{bnPb>0!C;nfC%LqekDMKy(g1bh6xr@OzWE0hZsy3FCqu9mLR3|2Z| z`f}J0iChZ_+QwRbgBGbt<=dFcCK+i7W`0YO%!?@_>>C<|z+Lx8DRSzITzoAtu_N)0r zj-InISVBPD`>6>i(_59qy{`P%3I-f9%kM|eq+sGE`Zg98*QC8~bnDI?zksa(-`V*K z`^~Imyu7n}o7(Oxed_~Gz~RBM<&*lhaBt_OBc}Kpude)vG++r?dz(aSubg>Nz#P6z0`%Mh$^*q`(%xGc zGrx&f&9^@Oxt2seFo|N3AVcmRWDNW=9+B(UOi2bUlQfrDG%SJ5U|Dq)^P6v)4!7Q z6|{4)>-@DdMM&tBs~uaFj}-4Z<{_v23e1(&&GXen27yCjDlP#9dL8ZCH_hC6AgTGz z5kzaf=F5!{OzZV)#yAz94hnBB^b~}iThB(|S%i|gf@oTf;I<+gBXx7Bn?t6)*Q6z> z{<%D7v(!jwCh@6z*23%^Jp8WLftUUrCis3RB7V}lkxjp7JF_dBC+pxRZ0#xtbro#b zY!Af3yB<=qQz-|Ql8;;B495mWVk<%c%a{VB52JHCN6=roM7!Oc);_p1blKXQi5V}M z26|T&7!u0~NjXr#86asnh)9Y1sy|_$n4rTh@`IL+Y;K3YD8i(q+!uSqphp+8 zm5L~HCva3(M+*;^f8wT(`9;3{{-beo zgExaudzw&{;plYWPPyE1km1F$qFP~*F18>h%N+KJi$ko>_$PSubCYo~r0OhS;|LJS zFTgh^ok{1JPh&w_kU3vV65j!#-zWWjSJLy-wSC0abo9gKE<^l8H)=$VUph-hb*cP( zgzwi`{_|uCIL1WA>coz2P@iHaA>gWzEr9=6>=j;|T#JG(`?~2dqI-EhtAl4-kE@|< z6Q8siT~DLo)fzISV5mR%p7_E}Hshmjr-# z=U8TrFB366&IKfrz12GR-T-POU%z88xzssJLLRw=PGVJ>I>deG)${}UJJp;pIW~@| zlLj-oCOl!7gu8n6aZO4wCh-f#Ksm+qqD`6aAIHYB!{J<3lLLxsy6QeS6dt6fy2nEZ zX{%*NyH2ABE3LRPo?_2;7duZQ#MCjDzH8eULH=kavuP&^%bvbp`ba6Z)HXKF-L3^d zxS$g%?#g3r3R`^br|5}&RAtTN*(M}d;-%tffwmq08js1cs?Fbtk62qBxI7WUUuL}I z-r&xpdP`~3E7>RtT)+q`G3}?Cr%v0WHfLm)b~O9&9>repVTutyg)R2I_?NWbyH77$7`%bA|q+3pE($gRrXBxY&UN( ztyYlCx%DzS`12A3)Y!gM-vz(jFZB!4!~1&eCBmiKwX){ygS0qw+LNm_xt=8Tq4T_j zmT%e1j4ZHOOUbV!XHp2AwS>>fN#d}}Q0@YS4sLyuc1Ym(r2|{4G$a%_ENRf3W$qd+ zUJ4=_-boe-A9oPTjRBI1HrQ)-6r4$wL@Gfbypy8Y4Uzjs^gSGX_zmt_A?e<09zH| zu0}uMh%9UlSel`aJ_eVl#~R+5zKP~gy{fk`PSYpPhvJXvSYb}WTm0|Z`s+y_-wspf z+C+O;3gq<$4zM>AR(I)8&sQ1PFg3JOB5KN}5!NHUC&J)b-!>C3A15&>AhV}@KvYmp z9aqUYIzG@up{5(Zio09{!r-!9EhyL7A%48LslI-jPrEZTp91RuLwm_Jn`Bs&BKgFM zXsi|%^`V0fpry4x*W&f2PR2nV!`@XEV|~18R#uN9n-Bvn4u2Chf)sMcSLx8?Idlgw z?M1Y0cS0TC{83?2J56I1Xrh+Ih?fq#x3)+bWv(K%jKe`_w~5eSF%*TG_9=HulE3JB zcp*>Bz&)tKqL2RP)j2Dkd?~lQUzAMnr(Epar7E%1MIlV~Cn4ZI1tP>eO#UR)&nwDOJZ1d1|vfJu#91Uuz zeK3X*q1^8Gk6IZBNKqJ{(L+muY?V4vRSc*FACQ5f=jgB(c(2BHY(E*}>Vj45_Br7% z+OXb=Q4Cy_y3f(CI3*T6hO2$%Nn)5aZqj)YVL#C3hFRkxG^)=miX0H9%cFgc|ICt3 z4cAw4`)1S^eIzhA0xE0;jL#d|ItA)RtFN=5#KrEU-_I&dQtJDPq!!#0$-Zy=W{O)v z!dRg?Zdz)d)g~2K_BZM6ydU?8Iw<^M+4*fh&4Nk~w-w*{bXwg6ZQcNi5u5m_W92=F zSLi3lSmE-ItAB2F!zzA)>^a!K-EkW_Fp&l;FX>D3!zYs%yFD|@7Ky{Em0La*S=jtY1#ZjYH{O&g6!-{Kw@cTz>{ z=fWsmRkh+N^Z|g!^|I`aw1U7&{lZ&^Joq>DL3h5)x#puKH3uPCa-w-ZCf(l>Gu-PK zkWK73dJU-o5T6Ve3H(2-{{6YG-)H zW%bqD=GR-%lfpdGl=)QD7;IhPPb$szSQim2CDEE4Un??Mt$wr<(*|+zM#wDgBdURk zj}KwDk&WD)VvZk;bBCIVtKrx{H_%1xYAD9guA7W*Cz*BVt0*xVi&?#i2GP(U`s_CQ zC1oH-WvgvmxQ#W`G=(iBT&mzl<|WFgazym@_iS_mq3o+Hp;Mv${@^@zr64&vwqi|* z2{Y*s|64g4*tt>Wum^md&vE$NjEdYfOF0Ef99w&2Mr3W=t^#$v8~gfQ@E*hT&LJ}$ z5A&b$FI_@kcx&np(lu|*n+Un$u?g}$KLjTD6pzKgAtzSBs>d%#`=gl8QTq#Ek7$3!Y%dJ|keNFBv zGg|G3QpiiajR{g1K8SA`sCnGs%8@U~`W}OOtYx{4+l8M#ZjdPUD2%zbV}@a*VcUF> zT|j)D?-O#Ok!HraM_wW@ntw(4aG7K?>6}FyggwSIpH7IiCX~QhEt#*Re;yjpiHCks zP(nbFm7!a*_gyg61Ap6-X>O{2CYU`k`+G=1Dt?mtF?jR}rEA;S7oJM$Grej}R5oFa=~7!-D>n$!3{}FNlpo!tj1F^Nq(WN8ik|x{_{b9%``? zP~Jr4fgY|6mhN0I;OZsrfiH)60n^T~8_wfwE4P|~Gfos#TF%X|*}Ez~v(8!}qZ!C2p=liu)z;HM2A5-c!)F zC!)VXK}j$OtP=(yRi)CWj!MlrNhhp}uBAK=DO8_qA;VAf!m!JMf5J!!DS4{1h}m76 z&t{6F#we*{7tl~W5I%q>H8iNwJ|p=tf89pR=gGpOd&7GL~kEUo~nXTEsnFkz_1npVd=h;751 z)z$zG!BKY;chR49u#3K+`9=yW0b-v9XF)3aICFc2eKSc?E?<2?_>K1%p`KaK;=Q% z;M)`#zkYP(6ZMa$*etBqpr6#l1r)Mpvf+@c1cuT&!?9jJ%^V%Ky+wP#pmgKTx&%_BzmVEkuTCx&~fv`L}eB@!vx+b=#FGhH=W&BFFzJuOZPsZBX1&M za5ygH5@@-J9sXle5SCM%J--^RjCIy9lj>H)l{NrIPiij+pG^XR?MHwQnbro+ql9oz zzI=I|5{F1K#35m{9Fz`6eoC=NQ&nCa@LboqnNkQ6Q~5J~M+tjzbNl$`{O{fckMWqd zTK3%S=5J*Hm!D?Bmv?pTSnT+`O@c9ER)#38t=*dM6(agbT3p${dq0P#+VkLKOFl}m zW$g5rul3d#oW73(iDf!beehqRF-n15xN3K245A zE5T|8buy*bv~e>oIV1*&YWB(?#Hd<_Zv#G+m@T=reaV3=uf5u>QX@rGkh9W)(u)6f z{h?pyqq2|Uk$%vT^#Oa=6G;%N4;Q*{eYPMJVxA6%B(9-m@6LC998Xi-EartP1BqQ4 zz%>S)t)SrIy#ARYVurOlS&?7=Y68C0AqK_eJT*ms0gl7=TE?82I!Z97YXh zjO_?bB)mS#Y1|EgE^2V_A=UxR0N83OhF?u*DKoVq!t7pQY}DQ77E>=j$LH1n zS?+wk_4E@XK0}X_o%r`bS!A}5@a}DsN1dY|$2xP3u^vQSSjkRxb;-MZZ8av|R&|Ag zAJD%PDQYXh5PIxIWK9p9wIZ<;+7>eHwf5rC?yqbS$`90FkB-9(K5S-in@LRB7TiD` zOGB85n3?%(ZTBiiX=t#{vS(^qq{VRawS_6)MR9(M7x{D#fsOM)YZ``ECXbuaXvJ&0 z1xRLt8Lb)|?xop{u*o4rb)OHxLyw-l+I9N5nkVa$f%KErj@urX^XY}0FMKfT-J2U1 zRuSt*nfI50wz^VR23#FhUfl2jGd0TbXF6G2;lkN8ZOQpJLE5+=4lhPZ6^%u2%>GM3 zrvmB(M7vM;LSH)?a+FI<_Bn#%wpvKYK$5|kXk(8!1g?lewG^T8Zs9jiCCGYj%Q~ZaI8c=N(HI-4Mp4hL(cVSj8!Hl(6gJ{E z9}bER+>Fp|H#|cxAT}Nd>e0K++1#U7I5V?mdxNDFL%k;4*S9gx(DP zh$}YMV<7Rd;p7OsIHAi1I%<#sYljG~ijBOVjCl$;^If4|(5Hd!%6x12GdCp)Id`*> zzVSr+*hU`VH?3ebBHLbzTST(@Cuc~Pfz1}%)@!IF$lI)z!dWF>WjIv1&tIn^fiD=%QZIFHMlj0?rq^sUQ zXX3<~65RGUm*L^B9Ii<0>Y0CBomVvl-z4}TLS26pq^M`HS3MK`Vh11Ez4yr{T^|#gOmvazK7Y&OCO&>oY zU;y8zIbg#x^9ucr85Zw~yziFN|KQg6%iXRte4SW&NhhW8w|WTp>UsO$;yI~ z&2%D$fZf!6%7AuJy-G(mgDOkvSQyT2-uS}wdC9CyTk1O@VRnASUIuX-Yr$aLZfPH| zbx!rAeM&Rb(}%)nSN!a$0UU6}xBB^w&sw71nT);lu?NS4EFPTix|!&xhLcGP%;4gU zbI)J2VYKWPdo8Zb05gs0@j= zhL*es6P22Xfb^nb#&b66BnI7}*^FNwxip=WCdw4|j&JR!X1_K)U@TwX^`lDzzAlf> zaX8-Tax@3$>c@?+4Vqwl?@-|A6=P@ljEUO{qlq4oaIM_C5IMI~9fxhKm0~24PXY0l z4)4*qU)!ajkMMvIXkUxCyAXsiT-0>z?+)9rJx<8t*}8UF{T(7bw3_#}>tC2+nUtu! zi5^(679bsLpQ_#BC=Jn)Os}94y~rN7m&EGb_6^>IWCWypPz-5t%H+u|q6J85->8Xm z=e!9CZg)fJd&ugmq2u5C6d7h?S@=j1EVtS9nTSTmr)nF}(!)fLbE!PxEE|ZQIhZmj zuF*M@{^OpPdH=)aTS}K$93sC`8ER6pYR9vmsNq=+)Jn!rhg10&wqqRhEtrYhtYJE1 za-DNw>>0U&YPx9VgXH8*(AHImWf=^~)^NB&E|dt2-@-TNd+TJstU8aj=yQz0UmC_y z!Pvmp95?kn_LrwBWatgWnr?Tke(rQ@*X*=qTHGgro_-$FL_cGQw*E>d>uA_|JWntE ziun`7MnEhP!_r0rl+`5cCNL}^j``#=7iZR+rIZ=`iS>sxgQ0Zg-sjI7TKRGqiwOLP z;&;JQ$jwGA>=mVN_G>|*V91PMSU%O+?P5`rf2ioyv zn5xuRSey4^7_x%b;n?E%_81-HZy}X9efGY0(Q>KNU(Y9Kd#?7AW>+IowOw7zVs(Z~ zQ{M&L?)!hNGB?^uK6H4@vu)?Cu1B`HFeAe$3jnLk+}Mh#2$Km51LFzWvM!$N0CK*Q z4x?$zbY@b6n<$mb(^Om&qO>rJ;92^DpWNxreI=Vr7Ief9=n(Qd*q<`p@72s$hw zGo>d7v9X9%#L7FfaPp4j2Fmi*aMRjT`ih(YEkOURndX9r9uAe=7`D@lQP`~n@v0c* z&$Qyw?W^=%rYAV;MJ{j~XYIm`uvF7gUDotup=ibviVg`mRBN*#S23QG3WTSpsv^UE zij(oh=1VWPtjRg^N#cQ|Z4<={5AxcSkFB2G z6L7e9>_O79fbHQq-ftU~FLITJ77!@3GH$LhO`7-)b23EJzlV6CpWxtA#KZsP;xk0R zxp3(t`nTw~hPpUL*wXZaBjh0*U7@%-f9#%4mIF!QYI!19(V-zBR({ zs+Qbq4ctrlJ$;unDM&!vB9p9{Nbpk#kA})=$I)f1tp!%Jjp}@!*1*G)8W;OP96a%| zA1xCw;AF=(Rn0EHJ!bOZ!NYupU214eHuxO`XHr_A)8kg8EgyGzukuO|DH?YmPi0Hz zThh_#tgAy?&sJ68ND;Mq-JBCtrUuq63!e2o4Ff&;kEgT<;fKyQQ%fIpmQ-}#?%i|r zLRWr6FeMG-ECYN>W=Dp_eux^GnHGyz!;R(E4jgrl2XJ>x z)k&9|@LH*xeG?N;l0u$|*0g<`ix<;^G3IjrK%u#2{kR#H*NRX5<_p;M59J^hY@QR( zCWRP&G2GhXD0Gkg2X6oeDl7jDkjO=l!S?ihbRZ4(RVu&ne3s$zK-)z2yS1$#Q=0OU zg|bVh2IR3hhI_v|u|pb4b_Czm<1Fqx143s5G!!^gM zD@mSUKPw$UQ@Y2wo-U^v06309-Y!6WOhpsUo#OU$l?kKr^1FD~B@5qnaI$NDiw@pu zn|kUrgs0Yr>HT?_TMwz@_~Fehco)*y4EX3WtQUKCTdWqCTXngzvE!ZN0px~dnD5zeAlCqR)X$NiK+t=v4VwlH9Lgr~N%IIwY@@D8s_Kc# z5I2|nK)>|J1;T*t2l>~VB$RRf>iEc6wd*KoZl)eCDUO;^SaHBR#+Sk7^zHM@Yz z0hKhWN(+Xk0)+6#aX0QWBVjr`T(irT_uMJcO}B3?9JhC&Dz*mH^C>h(mQP1aY@C07 zfPRw$RyaS9QpS@aLFX6Ze6HryKYoYw@OK~vtKluBOuJi)Yi$4uIoz8LI>5U*l99z zg0A(k?pg{&bv-I!;i=rJiO2r2f2~6I0L`EpaNMm;YfX6i;B2kHB6w5oF0>O{t%pxa zqdcFqTAk)aD+TMjbe+`AAuCrV%H67)gQ`KfM{P()uixG`4iv1CJq%lL>Ru zF?r1n7Bco-I+s{s(~#6sq)=>EZmw2sZsi-ZYy|9vmJTuNlxW6-)6hjBHCMZ%Z}05# zoi}@MPr{njKnf~e=T~nS`P^vW+Ll684Iz~{E0HF{2NTwf9~Ak;!u=AqLQk$b$jBI| z%kw>Kk@7gw@HW&!Q13dO39#D(^M4H2{=^hbKI%Q5Z)vKr z%RhUQ$>fDF;N(QcBZ4MJOLF`rRw&0zt~a8NUB2i>_C(82*Y11K*?o{1h9&i^7@ej6 zmq;Cx4v}Pohj(!2pTyE+lG|~1U}Ab4u=vG*YP9vNagKvYUT|8ET5;oD`{3ZZxdbp6 zV!4uy#wv4e;dmwSK5ucfj7yW=t!!WwraFd|vREAtx-jU%Bz9$75q6Q5>nSuFoJXLz ztajlnLI%f9SCDHY1)(l7Q{Tv^+|?U)^6!ty47)u<)7O>iRx=*drWfV3my9>bAoQ6wRlLpFUs1XEWq`Sl`|rSbDzFh#nGnpq|%=%RF3Z3VED-C zGsy|i9`l9{zvj@&tea;bl4yR*-yF^Y#UO8+O$lWnVsBz%0*KI6V2-`&#MM7DV_xn#x%Pzl*{|+f7+jz@(nF5R29*j-5&T6^ zno2WrhU^;(di7#5^&cl-GXYC%)68=&m8ExXF)&vh&KZ6z%8%%&P#Z-W!7a{w)ZB>J zEn2BZIOdr%&1`r)UyCiu-iJ;izj5V?HW)jK6H}~b)LP}wl>b>>pJElN3;vD;0%1GH zs|(%L1C^?D$C+U$T=pQyZpuoCt&x(m!S3b^5&UGEW$$>gH>Vr!gs|a*5~{N?2#oJ(oE(hN z+zFy1Hs~$sz%~;mbak1OW}U?3 z#T?U+?@Oy|cDX`x0bmw`uT8m~2o0y}%*W4q$ly^$7yE=UCG z_KKG#cg=2`*h3DFJ+SzYRy&iCv~H`MTS6R=r(T_Q$(YLQQ;n7%*Yp^qi((K+Xi@c5 z+hlJR_DsFTw$j5o0{L+vB=34kf8O_H?;IZEc(Dv@bKh@GjEiJ;nZ)t?+FM@FNg>zf z8bCu+s;(n`MXv6R41e8shc0yn?fSc=Z%NVH@p_1nykIGV3}?7)uDqG@*l|tK9UpdU zPCfIkGO3C`sXRQ%>CJ088&OpeY?;$X9GxL zNuO}Qtb1wwsZYiS@DGQ3cN_Q6=A~QDLT;d zN?wW}97H_&|8Vve0CgnG{xA^S-3jjQZXvi!kl^m_oXW z*8yUR+s{nM$mPVBr-VA+elYIK1QSgY+c@MH;t@LHN_l`sVxHgeJQi<8TpbgLM`s$x zqhh~GUcjJigJPcrn^wwoO`phyUkySeiS#Eu4|dv=&)RKV-90z zNjW-K$2hPE-GpS(G5tY7cFn!!@dc?PnM!3e8Sn8+VYW)`t0l+22C_i8ioAVgg zDRXLsbK=uiXoa*AHl3=4+Wj&rx!GbqFs}Ue7iRSLxvuc0NjHWaLxSX~J@!8<%lTHD z1q2x^gdtDo6)}TiP9zGuDv7m20P}~8daq)?pSKcdiZAtCPJQXMj=W4&8yNLIrU*VI zbR2C48P?rAYMYo|NVt8By;Eghq5n!RTRX$m&x8OT`o-xsa$g8o*p8%OL%y&OW9u_c zuLZx%ia^Ac;zLHR^kLG5vUuC?B~<2lfyc((H*c%fv)=Lug-fnwy{%BEl#|QuDY=?k zH&Uip-9jQMaR!W5MO@iO^ze|TZ^~MqwCRq|GB!kKifaptuf7H^C#c`yqWaUbRmgdu>RklF7Ig}z zFL)3GA5=7@IszOSi<6HalEx_%XCml8@a0y@h>bK6i)b|C7%7NhSHK1Wx1?SA7anwr z?oV%XNuW3!PUW~h(x6;*ysz)HbS|lT&~U}zrR8B1R5Xl=d9`yEWa4^|Ag(a-#x)8D zt#?=vy{w@GqEGL>rYkA27RvP0c_~#E3T6YLb`$VckiAq9sNy;#6Qr1bFxp)fTNx7Dt?e4w3{$b}`9TgWYkF$(|6C zDEo1&n*h^GdkYrx41@r>S<))PI%smCf~+f)%OJK@UBRuJr8}>}Lp>=v#aF#;#v4>a@U!PWdg5G?LxF> zgPc;z-R>o*%RX_r7ARcBbQ))rHFZvd1q%93ik{mU&0tI-V(-w66@NIdI@$M*?;$f`TXY3)>K`BUZ`Y!&^%*+ju6NXC2)(;di)5Kq+J$maPY zs=2&zatva>3Nv-T?ieB zJ8%v`edoyVy!gHE=^8_GU62AVWj`5QP>D)t22lLL!UM3iB{TmJ{Z0Cw`0!n)ZlJa6VU26&b1WmFl5JcBjAEv8{*F z)hFhLKWJc`4%O2BEZ)UiVecys3~Z>ICwUYRtCf+nPkh~^ZS=`~30}yu%A*PGv}nsp zT*q`Dx~SH&Bb)0K!mw)@llOGR04X#xq5Aem!%Aw#z|JPQXAeB@&h+PlBXO)?3QRcs z0+?DqZo2^fsg|B0Y}i&oc8%C^eB5DZueyq0V5R^K>b`pK#y*$b3DNu_?sKIC1pANQ z-qF+2TE6QD@jPJlhUp~2Iys)T=Ys7caz*fm_k_VcH^M;z(ZGQ251W=~eKSvGdrlgq zg83yQ%mF2Nmh{KbM;HzX`5fQm>{k@}1-s|f+1Ps;)Nxhg9`el^QUqVQx}#v(AcF;2 z6MJW@6r(9{gsd6^v&`pQ{c>x8%$<%?$c|WtRmOz)Vsh(r0|)TLaT7WGuPc`sG4{ZZ zU8Tsqj~Hg9fG^uf1&|pWvtDOk#CR&dhb!y0c2Fij9Fj>ol78h4#hzs9W*g+j__K@! z_h;N#?X8*PTM7;3v;`ial?q4~gzd<*`0KeUq6}Mfi7w-ZftgnLI>^v*jglVw?HYI} z9?@ySws;lWwQ-fPSxsGxSWN~PUoWvZINZT(*W@U@GHc4$W6K$5GQ8V?8V4JB^!@pe zi(c|NV`8Kp|#(LuHg+87i78*cmF3;81naX?4RHJsN* z;DO-lSqKrCf!B@!>keKm&?WeVpChult3=^ETqEAwA?6w#9nJ?Er&U2jo}KV`lLjdbWMk!QJir6PDkA9~LhS5m5;^Ref+#r`%;>kIZL?L$nL z>DLX-E@O5J=~1sYl$5J(zx%BRR3UH&uBDb)7Dw#+7nUn4LERdyle&=8>M)?hU$LoC zyt!Ja$IcquJj~35$E^BTFc4kCI)nj}r0G85QEOGUjUPvqWoL@S6GC6SYoA=<{QjLM zag z8IdSz+qZD9WJv;HSE+V>EF;|sH}!M$qrtg{Pi5Na6^)z5hDOe8i2Ra7bJA!sfs-6y zNwQncMer?+4X8fgG>rvm-|TP>_aN6l`St#~v%QpHsQ8Cz&pzC2QX~SU>7%BSq0IpG zk|ukN3^*AbFUdPA=`qVlcA>bnbIe7NAZgOAH?&(Kh_-|Ilo7fs>qr{rlAlwSAEfyR z36s#`={AiXyo3~42XpA1d~riA?%9Gnmh96r_X8PyhsH}?%mGekl7`y02`Xk6?=j7m9=L|hRP)kV@=X`)WAX@clU8o&gjE?qqT+Q#q8N=f5+RQHmESgnrxz`lR|3C?VlC4WJO`|H#q>VwWeb%}IsDik-VW~+;V+r?TQk086^4uN65uiWvuO9YceFve(UjU+E^05atumf;_|m4es`;@wQUxf z8=g?pV>${!KKzCpvl~Ggrwhgfw**6QXEcCk@$D;bB!_1O>!4#0zoD0hF~3O-{tQv# zb`GXMC@%Vy`|z5|N!Om8?CoP;4VYz66{n48_n8d(iEkF@=^fX94kv`!7_V@>Q@3G< z==iTx;tm_=oN>2iRePX&tR8S1P&@Ggr3*jpq_4Wd6T4g#yaFZW>~e?9HK!^iMdB)m z(TBx#G}ga!=Rt(2%%ZEfD*d8s|+8K&Ijvxk|d z5d7tu!0{t*i_7AY(_#~6ShY}q4x3zVAmw-Uyp=QeibLd9j%bc38s5o6rT^Y=-vAdzQs~r$U1vX`Bi1 zlRYS@tEI9H+N$iY7F?WBuhG;_DEV{_W_)UJrpT)wKhSLj)vRe!+G8)cU^nfl(Zz-L z`g&$RC?aYo1KEbrX1g9NU=7GOR&Oi@bchgf?jQ9TC=@nTzn2}tI*wFs#2)p*HGmh9 zf-)+bEK#pzvWvoSaE?NQ2a}5plC7t?PPli|blwuVJce2xqp!@lsURRpk@p z%1L&DlwX{ts{Cfo7_5I{F=LF_lOIiw#t|6~O4riSwLtjwRf#9mlBT_X9#VuKF;bATstEXA&699HP>7=dt>L8`#Vi&DlL_> z-u-dM@bOU;Atj@E0LuRL0$Yhuc(a&#;< zv`2NIKEYk%0e^*{e88L+-5Y7Mfq(Y{i)d$5{@iJ+Wy*KU=m7u6zVFPQTA$=mlYFel z_@ZcNnBU2Wvc>gkN655nmRgX@(1bI{+BeUGgzd!h#lAC!xB5eq0rIfH2!7QDP7%?d zAt}xRUJ~RCLCN%DRMUpWy=69i2P!{&?aH%pL+n=3X#mC9VDRJ;oNdWO*2PqYF!>7J z?tC=rbTE3=b>feGNFSMUJE%XEL!sv*Oisb)X|#CFi)3KtWUt}owLOe!rdz)*4{i@Z z)C`&)BXoPMIGA{}t4x&W7?piG7mMGh$fU=u%s?h&P*(}la4Le6X_fv#LuKbx%XSO1 zsOXQdlnjL2Tm0Rf>ixAF51GjC4K(UfO)e1j2bFvs2uED+C z#h1tAA+}p$X*@2-3j_=zOz zO*%5Ri;iGMjvW0j}NgM@C;dt-orUw&5aW~o! zdL!y#rMJM5K*5?6+yPAtn4lL<`D!@VTuKKew4_2@N>HyPwQiF4-CfVh^YjA1+tVkHp6yWI<1|V%gil!gftujbV#+0?hSk>oWhzu z_2+LeMYyCub3+u;o63U(9I!KGII(0_k;5a6duf~)iBb$WI9|T?iG3~y@KG+v%(dC2 zz6nB*-ctRHCQZwsYiKf%tLM{E)52f-hsX{!QJl-lXD9UG^Q7jyI;PR~_ajnJ^LcSH zz!)^O;axI&1vEaMp173Iqx$$b-n{FB#@RL$WC21BmODi4_2_b zz%-lHLzs*4gDI3d?E_Kr5{MC>Y*h@hl)WzDjDqSe8PnbS5K4i}^8Lp34tiJ8_9#7L zcB!1kY|D?)i6-?koH9S98PCWcytKy0czO6~Fr^cnI3VFW1XXKbIYz^=!AA|>r&&X- z!0?2}ty_L!fNClewX;o~vM`HXS#Lqw&1bZX@02Gu>0a>%KcD4?8WA_)Q|rx*v@CJr z5t2jdzCBAC)82MHoT}BcH&4A>Q3c1jr=wWf#WW&RfKCwCJ_Rd?jO14h&2Np~EHi$1 z?LlBm*alw2z#{&3UaH`6@#h`XcY8w}VcSDv;~evASrLA8+zT)C*yK57@Hnj24x46= zwX*f^`NXTn+RI;tJ_B(i;q#xJqE`6i5WOP~Blj|Yt$2W6pNF!eyv>8ffpt`R!b{RW zeIiRwEG0(Xey&y{71QfdV8!Gjd!$6{PIE7(z*rA2t7UnmAQR7awr}Jzg|pI=%UpuU zh5gl@Fmh3C=R@55{;-Dwv$isZ&*B!lYFb4*B&x4mn((^joWz(WKtJ8z`NZ zXe-#D$L%UG&b5|o$NXY&VlTDq5Sr>m+mIJt$xfAU{kV$I{>b0}jb#BVa}PKj5nY zOX~kz5dTd0ZQg&e*8fj!|8}uI+yA!M9{^navf7`4f%89OZ~ek31^^WQM!BIpJ1^61L*Ic_`d%Ip6~w+&G)~6>-_`v;06DIkBGVJLICUm2LMx>^$8b&gZYW=|MK^Qcm4bC35SB2gY)^rK)?<-dZqwmJ#7J) z-2mSI%jbprMFIdDjs0n00?-}+h}{6x?kD62HWmUl4n_ht0KPdp2LPHIaE_Uck${zv zuEaOSu6R;Zt0Cw(KIN*Tc+0Z8wf1B{jV8BIB z@Z3)qKW&*A0D_(x12}$e;?pre&eQ&r>z?Sp&p*+bIhg<-z;yuUJfC~g324aExu?&Q z%zt4>Fg^i-|Gw>hV@NOp{`(CY!31y#2h;B(fHvlT9RQ>QF8{wmNJOcqj?Y(j2@1Q# z!JlAcQInjdk3|qk3nUT{fxVIU0nnJGOtAoz%Vy)f z#jWF|oZH29(w4GKTyqcm?>5@wlPy^~A>}@K>EZF}I)tUL-!jjEXh1&r2^cIaNSI)P zz7i#jA;gS_1&WOYe+6A!{Q(jZNU}FjqVGdzUo9|cGzvOgO;rbwhr}I!FbOaiC@fsS zoA3|lp!yI(E4<$jMFsG|{5lv^2?g3lkz9@{I>20j>_4V0>P)>c&|%Pl3(y0ij;F;H zC%a<~=NbbC6MG<4Z{WJW?S=DqY6}3lIwHIV_IPWKI)((J+F{ZAsY?E;LFbC(5hv}z zw0L)SI~PvyuJVyH^O3`!U?p_skxGCtNrRDr<(pr*e_F&N4Xe+6j5Lf9oU`!VsS@5R z+fPDh;nkrGKxc8F&hmclt%Z)On7Md5uWTJY-sg3MPd&nZOr1|f`sC>FE=2kZ=%d>( z|F8q04M{i9-dWAw@ESkXUGVX^U@FWA)yqQLGc&4rw#N4(*1I4O#=cs|4n1G1ysHf$l3RvR&3?)qmCEhlKi!G zWHjifss}PkkCF%ac6RJL=_@qk2efzZvGE_QL41$$3cZCG2w-pFjzydROREWBAK{Lb z1GOQ$)d{_Y8qs#yJ1^_+{I5RidI@=mOlwp49Ckf?eyk%23Zg(LQBT)vrA4x3AfP1$ z6ASY7cyLc9MESD!x0K(aaPP3rad@SV-(uDV_4H3P+LfGw&L z+suQhrAb%zxF6F zXH}1roz;nOxxp4JNKkh)cPssrS!R})p{puJ8n#^p!IC%Rx2mVh{F6l-D$ZyL?0POB zVgg3SQxs6T8gC=qfHZ}7PV;pvyZ#_%6oV*ysPs$-G426@{HU3aUeYLM*$!L?xo8$v zyWOF%x$Bx@M20gHG9fb6`7}!R&8BKoLFz3um`s>|^e-jA}@Z!~-SP|L`Z4ato@;(zpxO3EA`LbMCTJ$X+ z`Yyb-6kT{dy<4bOpDt^#jnEtX0*A_(m>arTi5^W@myN}5UEVUg`gRYnOwk&-7lvav zxGt=OoCvnGgHnX7Ls5+LGvYN(U!~RiO2zHwZ5kEq7!2oIol?2DqqsVM99uPNDv0nq z-F_Q1vEXk?J5BDYcg>d<3X*l}Z{?0FJMOv77L{hBI~fc)ogy>&w$&956Wb$AeBACH zw)>9CD|@@N))spWZb1r6Qq3jjut8dSt3;)@Gmp*Miu<54;qV2~R5&w6C;+HJm zmi$^nPVp(e?YAi+jb0Q?#2#%RbYqyx1W5HKK@5y*0>OkamBi=yC{Ou@=3sJWVszjoK1GO+gSd_^Ke zGbgY?xTH`?9G}&p!`$a`ZrHsYKBZKyF@bUtCDsyL-tC~5LW!I72N=9{MKAJ0OwUh z%uqcGCr}6?RXx4vaiDT)k1K&w0}WDP%6RYu%y3<+L9IFl)fko$V}GrR>H?za(5>7~ z-v-v3fJAlwW!}q(bc`svV;LSpBP%(B z`4ocLDyvNSxN+ar`PQpCzui)9MXi)ZMl<@VvG6X=0ySBO!w*!(2a|_JJV}Bl9W~PMD+GO1on1Y9Wg7L;nuO(?|g&camsxtx@7m?K1GjONx%E3X~o@E zYP;|A2!WKIH%R75J{p!y^D!!3HsH!M~-aRsH$Cumb zaJx-^P|{#Kd+oH`d}@>ywf2tg0_t5&7}b02yEj?~(qK*LIfXl#n&HO5WHxYezcc<-lg#j+AIZGf+8qdZEeyHj-5R? z>4jntCJLFaXjJWZ0yy*NayI(w@l9|0=(6&{i)zlv!Dm7$l}hK}Vshv<#rzAfCHFWh zTRPEs4vL5~DEhrE(SgsEaV4BY)R!Ce#08sj*{bEOoPfoO_vn07#OCA)oDjOe3nWCe z+{skcX(bEEdV(*639J%Cw5m?sNL}XLRLZE6E~cXUl~fBKH0sEm;#-={-rzIofzOq> ziDoIP9@^o~Fe_bGx0UgxX)nC@yR@`bN$S#+PDiMiz}vgT-fGZgKA#wgA89;0NaE34 z+{V+t<$~)lxQ7Idzu&N1|A|fv^d`mvHx7)nYfw?_jzfP1+MPwD@uuCH;>r$|r~U-V z&ps<44N{1CF^3k)@tCqDZuQNeP#Vt{(#txlFEy;isj^0hVRaQie8jicgUD(=^A#Jyw?LjM(IjT~S>XM|Li~`IeD!>k#k7s2Y`4jAA}Y3!B&YRs5s<(d@*cil@Nt__nW9cFUJKTOP}Y|< z;_;$xNy6u;)QPayQ*-T6vCl6l7oF_IBNj@YUJrkr?cb?4mWyOBB{ECE)CRsmF4xZ^ z7c=tNTK`;M-E*01R>84e^=~QNvUd35R5Pm&3Oh*{SLgA0bV}p z9Oe8o&n)*1UnomTs2bZFH{>R0i?qd!r9)lCuONk?sDaRn0ZWI|4mDt5lRHEHmfWxagA-y|5aRYsht!6RS)^p*d0s+E)s^2U9z;`_jdZ~B zOqGl@zah8owoNk(F`8vq z9BT4xu18jn)^LbBH2g;H-HqHT@ci+vot%TR4{5n9MiWZa6p)e|tZi5z7QcMgfQ>;P zpp6NCU)t1d_UPasOMBy+TQwPjJPB;6dBg?|54F6qeiSc(_WFe^M3CT&FKMm(OPQXfHCj75vyVLka zCf>h4l7T~)|C}Ge3=ah-$@38t94bHgqzjdv<8Z%%o<8Lv!l<|`!xJiq*rT34?m$mh zh5g#9zm{kX#3FIrG+FFefU>ofm&wo1S>LHFQwh@pWv9knev9V&{;H`B_+_Wh@?DL6 zOs+=^_i^)2-aI%1&rQ?i{m+&7oeaypSUNT&2swHFb~4{kqeilbFiP1ZrBU~DI+{t( zT92m0qxKmG#^F}?pj-_u*!8kp$E0Iag*>zu1$Z#lqc2CB4IH^QzXhCfXGK&my?5AE zddqw$MDv3Mwy7X?lK%irk`0GXXY14~F?w3e9#=`P0=xLUu~*~^;~>29ej}ccXY93~ z>ebll7wYkF`Iy^Qq-b(=4Us~>AgB1645WHZ0+#P7E!DYwD9$}Un+KR19KIuAB(|Rn zWg6^ckRZ$+7~~AZ-7T7qlR?)n1?0e6HC&;O_nO_DVz{COTJn2uS={zupno>2C5+I5 zi*Z#!G|p#{#!PrnMITjKYA2;Gwocxk5sB}=91?Xb@LF(4mJNZ7*N`6dSo^eeuq?6( z^;%Pc&{Ih7QAtzAIN3wQQJEplPso&T8`S7)E~Po-d)Vf^5SzoE!TNQ6qLoXE2BaR> zs4eQBnhmBsqMoN5l|#`;Ztjm4Gp3OKdrS31%%WhhqwiWsyt{PfCuf^9-C7bEq74TU zXrr#2O2&~s2LV<&X6TrvIM|aP?v0LzRDCJ2gGA`C`)Uxs)gNX2h2(k}jCA?zv(Q{R zR|=n_pBv$6OjePVLUoUl)Tu2_G?-N=xO0>Ja&#j-R4+f~SLzx5=4pb1*r}o_Y_&I4 z`{O9(OexZ*>uK63f^u_asUq21v#UjgL3v=#v)lCDpQ)YJ7Y&Hrw5NJJZq&vFlZCU> zb&?`Ktwi33g+UC&&9}+KNWoACQ`d%~ zqnTEW#)USLjEZ79+-Odg#>AZ6hdY%YbNzlub3Frp60K~un7yXau}%#W*p!tLH>`=Hm!NW% zwqV?_l7B?%?K1k9FE&X&cYnw-a-9bj$0Oa>I1Cd#=zOJLjAJBN5xfb{VH3EGH1u&n z*RYB_6rBx4LdVHm~7`WMU->4 zZahz#{iavo{YBvKN#C*1y^nS_ZSG3v7iDPSRX@Ck6?1qmzt9Urp;bUpnX^s9PqI)Yrawt}qV)|{@it>~^O<)S zXn7_ID`jCnBexg}>M;~A*si=u;WeQ!9d_sx>vLUC>@$TsvSP3Gz|=Yjob#e_3)7@i z-LiR9{K}c(cxtrNC4dC@7YJUcA@}BBq$>ZS}5cVsy z_oQ;-q4uwHRC5J8ub@}Y$sG{%n0O0&ueOqc!6fR!tic0X%HX1$bd&hjl&7@uPwj*q zi>XW(ss>!h;y(;%5od+FVWxe}L$y{L<%E1EFn%yzDnekzm(6Tr87LLnSNJ)4=xj@A zD#yS}JjK^7dr!J!2v;81kP&G&b$=rx9lXrCsHRr(W`!q+Ccca1GoGjXc*H#czN+UAXQO`F-4IZO2s6e`zE?GS>Il6mix zBGj-Ixx3`G&vGQvf8a^6G_6TCG0x<4^4VlyZ{Wa^jIrl3TmATCjv9jZJt%q0#%nsZ z`o|3dK5kE>X+QC{+3NHL`3*-SIz+K@bEq4qQi8$-mD}omWnx_SPJ|FF#PYifvv#L^ zb9W0rBxX>@yzexuzVm6MA60#T1-qC}e1P*3E4iId8B$@YiL|GA_JTTrc0Y+MLh6&V z-05Gt%PiNrDHo(!gMLsbvszt<`tpW3OKOu&no--k_M*On zhicUxx3(g@8EhYtm6b(Ms({MkPO0_BX(pY-+*XbEPVm|&oBFdrh%)n%ysb5SKB)rUo9Rp?r^hyHGU?J}+GC<}kSx1w6*ByBhE}npI{cf6CD+yB{cHS1OqY`ccG=6( z!IR|MbZA!yCGO$oh6atdEu6;_ZlgAYnr@&ER~{dwEI^!(U->z{w}~{l{#wE~F5XFS zE~57l^J8Va$4FQMd>AyzP-^&%vO6Q2^1euV@qCE3B3!e|Mk&riSMP_8z-lwZGyc2q z`$8+TV-fI;EEMR`k~N_Vf<)j`Xg7&zn3) z<^P0>{uQT(R%d$7P`rGza6Y9G{`!8|`<)^AYs>zxDx&NxPq~pl|2P0R(0@@_0qKFK zYNdZs{@nYe4Nz|OiIe5I>?|NT0oZ@B>4}>IFs7c*KHK+1Vdh{1d;nP!0N;x|RzS|= zuQbH3f;E3YSu--Q0y1_lNeMt2f`Q>*nTJ2q5CDv8mj8Pi!j&ibzM-cmFTzvSVLm|* zoqLw_Rwl@R0doLWU&N`8&izg7+s<&$<#NM33n;Y#ttoVaVe4JamYku}+tZ|$p}oQT z;l`2;d(WSTm-S#Su+nee?K4)3!NFpaL!i>`#* z0ZA#NgXgZ`0dt^!5bygu&VM?Pd=w*IkSpeUeD}fDzUN1{ssMt1SZDg9nj74896N6&FZAKXa3MPUYEZeNAa^|x z@U}K#bPjkwj;VEE`z$9gJfw>3dI<-z<)bW0r~R!VaC&i3L6*78amnpn4D;J>BOHqO zmo4wS(I53@tjSW~(Kp~!-*kPG!z>HGy1QNe?mbxVQ{6F>G1BQ59u0!1O4APUb^(@1 z9K?$O$gf(|?Uk5yx^5sQwl8rtP$x4K5H5r2$naitI0(VdPVTmu$1jg)k-!AaVl2k9-$_1ij(mV>wXg0egEO`iM7yJoG69GOg~TKzjKWz8H(&USBM6mCg1KFHm{{~D=7zc00*ZYtgRz3)KlFX0?)r)d9nM=!+%B$Got%~)b2Apz{ zX(jIRCOUC5hPww=!fQ7zm8rO&Rk%XBj^klU<2)n>v09S{SZNAl=-4~OMo79bK5IPP zXQr<|iG2=Cm_O?iM`iXU{5XV^vqvxE*~Rh$3n3-R%j2Yfurs~kJ0veg zF$Yd$#bVLdx)|uV--V}k>75ezIHY-)bW-ROqu|@k)EtsbUIARr#2%tn?1YZiGbwMj zIvQd-uhL&xbq94fe1j@dqO(Q^CPB)r?lpzlT$p99VyS6W~8{ks#mqj3b9D)%1L2qHwXjI}r=rW>h)nBSR$(2Ct zAgMX_fd_$^oZo{Hma(t_9RKgDcis2YeN{-LVNUj&0f%caCd0Roy`KHHLs}o zqP$&*^ILb1D1DoJUs3voUBfT4dx?p0D9hq&BlPK!mr#AFAgxCfm3z`gf@kXD2oH3l zo(_H}DAo(kQ5=u>eq0z$?O?BI4|-XRzDZOlp=qa_#q54H&W|)fDC9Yatsim4F88`; zE)p%OP)Y^6FRU`m^!ZGYduyXsk69$#{<-(s#^ja*Up1W$4sNO3RfZi!{&Oxm<6chE zky$9UNBRLF{D~c9-QfwYmgj*7@N4*~q-2KWIAasL5oV7`Q@{I6`SZq8Wl;wcR$!za z^M-nHH1waQNnO>L-lwnTq5C(LCiN0EXuhHgsS@2P{#*d&voO&~bLq6b&GrvL_rrtUDt5r0e%$ugR#j51dMF=86-JftezWSk^-LA(xH9zX_a^6JjvRE!rbl)%Sqr6ltQ|IYZrCzcFdK*TW zR&AvM7NVM;&Bz%VQkV$3yx0C?m_*RGYqqS00um(la+n@Q9De#W$3i|s1JwbWGiL3@ zhSJ44B3#!D-2^R0k+F$OEy@U$9!ooX^Q_U%quqc2Hvb4vM>S7)KbG{z-mZ? zib@pa<8Cp|bhrmQXKvLKaVeDv#)<#7G_bph&2>VDmqJl&O1Wh4%}`DfpGheNJy3hd zA~!eN9CP6Wn)#NESe-cg#NqBJHt*g`TM`+6jMnnDM;L_>q_x7wJiOpG##hHFh`=&P6hD9bvyw)38Zvx_1PN-KJ7S@g#->tXLh4HtD#R z<5m%lnZK>X-uP^dmELzMq1|i;_+nZ)?}dLYiGIgf>gdr#=HX~3H6LzYanqMVGZ4Nb zw|N#-uAiuOCpMa)q5LWYOYz5s!w(z&M}o@L9ND{wxea1{*+)3KzE%!Mj4Ak`xz56@XkJBwx?$&(IM9yr|&Fxz9fLi9vt1bYYWxA+d>aU zoCE^ZP~10Hgm1#y0kjB$X4;Q-)T_2F-76jND^7~stFE-S0Mqb*jb+H4R`c^RKEL(S zCz8G_HJofZ)S}%yTRfuhQi#mx(wkyXWkth%)}-@7xB?H#eR24R-hSiU2y)sC}*xCy(xzl*|ERR zeSwrCiPh<>mmW;V428z{8K&0ew*G6@+{cU#JoJNU-5Yx zYs#s3JHH1Wwy zKbo&uM#U(V?@mD)N2Qzs-iz(9_cM~8MW@>M zu?oR9&C%7}qU*+a=h-Ggl>lcSTHL6gRn)-7>N0;a^%H|hSlQPzxls_qWxn&SILmd~ zDs(kaL~ajnH_Y65#PF`kjis%NPSGD`LHhJf)*7Mo-be<4ca(eZ+U@KhKz2aAt`>AVn?mO}W0sby_s6VReu0TD6%9FXRr7}fHCV>lG z&$fTU3`7$b=Zm_nf}|Tni2U$UI0olIW#O?{ZH5nF$r4E~~s z#u;OQ6}3D*nGLFmGuN?WPWXPgu*9sl8h>GO;~g!zF+3{1Onn_~rUPLNLk<2HE3fxI zI)!X`CzHcW=g0VVu$4HDE2jsnGiWt7HI@jSF6jo<3rGxxS;oXsp)fhNO>b42q$sjqO8o86(h+^PocknS1Nz zF2_aZ+bo?ndI@q1-zaRzd|a9N(2D7vUVj*SXbMxBQFN=8)e7{!<9$_Hba#OCCkkqb zIJdUzlA6h?sj$U%Ps!@AZkQZqelcAC%2KCBhw8D{jQNdsX6sbZY@1bft6FXgRNudr zo3udbv%Vr5v)e|DJ>Z}#|O?Ie*im* zX10#J`!hyYZ=3_9f26R~Ru)d|Jo(R!kM7{}7MZp26+iO~tG2HDaF6$jY1ntd823K& zXh(8O&ffapd@Q>u$V_h&_De5@*!hVRYVip!{#(c9>B$#6S@0$1^BtjOkeatD-JHS} zI;6utl&P1l0!s>VNy-YW14EZ0CGMLU?i~q;J>U|wsb8}-MS2<9c~VGXW=M@-}o{H}!i?0)CNO zj$8`$uryXiHgp{v$HB*Y+Rm<_*atpQ59N9-;e@Y8rwT?9#6N!={kGYeB(=db-_wa)gcsHWuo;pRo1 z19UX2=5|h(W+0M^*OfKk0uuUDjLQ``BV-SCr=VV2x5~bBoOS*~L+^g{RhL8RR@&Gl zNs(-|`Iupls3ydaN-HsnK}IZO9 zU4Bs2LNmQ1gC`=`NiFa-W2YEllecyJ-zcnA87E0xK9}w)&fA2gf4!*mV3qD=n#UB+ zX#Nf+B1%?15Tv~uq6-9J#eh%GD3iVWZmY{oZd^jNP~o-VW^i9@w@Zt=c}|Ba1p&!& zYeVTK-Iw6BFaP=h!7zBQSM8`ePPv>0TCe`Fccs2H0c$J}oz(my zx`&9-gS&hp^QED4`@F#LjfALkgz_b8*mr8&q0j!W6W8G{)KR-kYZ$_`);#ds-Xk25 zGJMe(HGd2$ht!by=Fh?i+V* zkfbGh?*{Tw4DjudUk(Vjjpco_ys`@0a8Wd>l_?=7`Ql!pYZV3;bvuV>hr+Tar`)T& zl4>|j(2Db1-o_$xt`>u))-f`dDT;(Q-t`8-qUBJD+`KDMc6K8;(gmYZTW4;TrQCMK zb443CGi^I>qq{^i%m@=Z3q879PQwecyE3gT@}~N@t_~WEXWL%QZw{T-#`*O7!Sxi) zy~2tc{V6^FqZc0w_vic~rCOp@UXGvrOq$VDD7z*}5S5jL7B*g@N&w{Y3~0;AT0eQ( zmanCzG!**h`sVp62u-6di3non^{g*9Xc7??OAc~NoZt694JYCr_}iurWgcF&3KZ?< zcsklw8;2w*+E7N<4askY!ArP0+s_MM6=4B~p0}6aPh7^?OzeQ8uhdB{y*F7$yuRFg zeI3ag#IXH%1aag2@eu{YsaOmYJ-}8-M^oSt{?%KxC&eYm~{yD1p98r}5L{jAdk<@p9 zSgIZ%l4?qCLH`m-wFAUb9qFC^5lj8&N`t5OsehH;dn&dKh@Y}@0>1y;dpZ99|7K-p zBj9+J!a%?Vc)9xJ3N|*td*Gb^>85aWH~_-z?8E8unR zXDgqnfVa?}uLW%Xil9D4Y=3v<%Se;c1)vv0(+gQU0!9X449V%*83Oj0pM$%Ah`c0V zF%yCM^AI9nd~$&T0rRu72mo)8KOHeLKB)n0nVtuZCiGt~@-qVJegAj*7+=af5-|SK z#rWJVfRg99Hek!~)DpnE((`|# zG6AU1xc~)%zfqYf0q%Jj5Pzex0I0uA`x}+@iTdJF3ULQR%NIq@86bie!jlg6m!`ZB z0OA?h|IPuB%m}!vo*GY~Z=!4CU}#76Bf6<;q{p!cxj8A-kd++bp(gE1mUwZpr zTmYSb)hB;&0kr-ac>m%8GzPF>My^VvZwG|!9lM1HioEgBrf00?A$+jr8PJK?D{K@_7)n9ElGBtLz19a7sWX4~kf#MgD>4o^KrN4;GFT`KUYyfxv z6XB0Th9_%&jfNM7r`9n2()dDovKWx{diKr><;hsU6#W7H+!e>i}Z?y1Lr z_ouz1-tYD@(LEc&{@dg~&pb8ecSrtt=E)(yd-KmT0HZjbhZ-PND`jeF>hO=rkm4WO zSt$RUOP?(HJ(s@B#LO>t|H1Y=rT%7nYiJM9!VFkA2P) z*2YiI48YU*uZQu=w9Wi7Rll5-wl)C##(HOODC_88VQK~7rhlg(&cpNkbB}@&@GvHz zS2i_tHnfwoGc+;;JlypS?Rj_rbZB~68$&C>=bMD!x!V8|m4sF4L>w(F^mMJP4DARg zluS(R2>}1w7#JxTs?rcB8`{|eW;g=CxMTr5lxYDs7lR(+j|WIy#tG+fh)` zE15c27y`D6j(TQ*`x3AxWM`=B05~V53lL1;Z0cY_VB!k+9S5+Iz(!Z!9MEz~dO165 z14n&BJBkm| z{=c@)Wkr)Bh{F4R3OBPh?-!V@f-6Cvz=Z2tjvsz%ZbRU z?!S2S8@J50zw!5v|NV(i_9ij*(>MQPY#@FTMi?>-2QUmnG>j8}urL43G2&xJ!4{tj zDpn>gB64%!t5aOxHSrjSGn3zz391)b0es~%CQ#wL$N+0 zv%bplydG>PW3||s^DSxoh4@!FgjT%7A=tiVyL^OdV@J__;L}g(lb<(u-9zUXbD9nD z?uTQCPjzK|#0${@0Dl7AgTmM9I&ay>o>z8@ckj|1jMW%h%E6OV?zG}qv@zs) z^iFIoXHC_8Imct?xqOY1P8*kv2)3uk-&Kn3r}?I`7w?Vd@Z5e(Ol7h^?k8b<5N?Q}hj-!v9l ztmjth+7@^D!yl(IgCnvIh^jMFUq+;kP5 zZqFP1CYG!ND3av`+JQDNtuC{JHkz%a4c{A_&}cutfvdTvB8i(zm$;~GocFsuuac2n z2jnBQwZ4bN`wmxDyC2IrCam534QgvKdvrWbZG+UP{@YKtn8T+VHb=iJTCrIN@7Xg{ zO3!?d12mSvR4k4Y!mJh|f?3=kYM4(Ch>q@eR60qr=25+FB&|k2HtlWHVYM11o$-S~ z$)q`Sa6@Tl39+-aaO0wJa&Y-$Yl)_&u8*?YF^Ub7yOvjRLGyj8Wb4V00<1p-yN?T< ztgF7Pr!XK5CP&*$^)kzIotvJ=6c+z5d#le^xuz>}x7h|=*0|+Ob1a&msw*(FmlYe9 zv7`m7r}uL1NH@`9Q-pDiYnL8{>I%$kjajXBzARAeh1$S+3e*r=a}>evYEJ=2rLxWY z4NPk~dP~NK=p8QY71TkiPxJ@II~_6yzdcU%LVwqLUr<}Cj|j0EU+8gDpvxR*;{A@9 z4h}jMzpP-|0|2AS(dX^N(f|DV%je&I{rdLtGd_1jZ-2zy{Bv)?8xQT)w+|n_`|$}} -\def\twiddle{\raisebox{0.3ex}{\mbox{\tiny $\sim$}}} -\def\gap{\vspace{0.5ex}} -\makeindex -\begin{document} -\frontmatter -\pagestyle{empty} -\title{LibTomPoly User Manual \\ v0.04} -\author{Tom St Denis \\ tomstdenis@iahu.ca} -\maketitle -This text and library are hereby placed in the public domain. This book has been -formatted for B5 [176x250] paper using the \LaTeX{} {\em book} macro package. - -\vspace{10cm} - -\begin{flushright}Open Source. Open Academia. Open Minds. - -\mbox{ } - -Tom St Denis, - -Ontario, Canada -\end{flushright} - -\tableofcontents -\listoffigures -\mainmatter -\pagestyle{headings} -\chapter{Introduction} -\section{What is LibTomPoly?} -LibTomPoly is a public domain open source library to provide polynomial basis arithmetic. It uses the public domain -library LibTomMath (not included) for the integer arithmetic and extends the functonality to provide polynomial arithmetic. - -Technically speaking the library allows the user to perform arithmetic on elements from the group $GF(p)[x]$ and to -a lesser extent (this will change in the future) over $\Z[x]$. Essentially the math you can do with integers (including -forming rings and fields) you can do with with polynomials and now you can do with LibTomPoly. - -\section{License} -LibTomPoly is public domain. Enjoy. - -\section{Terminology} -Throughout this manual and within the library there will be some terminology that not everyone is familiar with. It is afterall -weird math. - -\begin{figure}[here] -\begin{center} -\begin{small} -\begin{tabular}{|l|l|} -\hline \textbf{Term} & \textbf{Definition} \\ -\hline monic polynomial & A polynomial where the leading coefficient is a one. \\ -\hline irreducible polynomial & A polynomial that has no factors in a given group. \\ - & For instance, $x^2 + 4$ is irreducible in $\Z[x]$ but not \\ - & in $GF(17)[x]$ since $x^2 + 4 = (x+8)(x+9) \mbox{ (mod }17\mbox{)}$. \\ -\hline primitive polynomial & An irreducible polynomial which generates all of \\ - & elements of a given field (e.g. $GF(p)[x]/v(x)$) \\ -\hline characteristic & An integer $k$ such that $k \cdot p(x) \equiv 0$ \\ -\hline deg() & Functon returns degree of polynomial, e.g. deg($x^6 + x^3 + 1$) = 6 \\ -\hline -\end{tabular} -\end{small} -\end{center} -\caption{Terminology} -\end{figure} - -\section{Building the Library} -The library is not ready for production yet but you can test out the library manually if you want. To build the library -simply type - -\begin{alltt} -make -\end{alltt} - -Which will build ``libtompoly.a''. To build a Win32 library with MSVC type - -\begin{alltt} -nmake -f makefile.msvc -\end{alltt} - -To build against this library include ``tompoly.h'' and link against ``libtompoly.a'' (or tommath.lib as appropriate). -To build the included demo type - -\begin{alltt} -make demo -\end{alltt} - -Which will build ``demo'' in the current directory. The demo is not interactive and produces results which must be manually -inspected. - -\chapter{Getting Started} - -\section{The LibTomMath Connection} -LibTomPoly is really just an extension of LibTomMath\footnote{\url{http://math.libtomcrypt.org}}. As such the library has -been designed in much the same way as far as argument passing and error handling events are concerned. The reader is -encouraged to become familiar with LibTomMath before diving into LibTomPoly. - -\section{The pb\_poly structure} -A polynomial can characterized by a few variables. Given the C structure as follows - -\begin{alltt} -typedef struct \{ - int used, /* number of terms */ - alloc; /* number of terms available (total) */ - mp_int characteristic, /* characteristic, zero if not finite */ - *terms; /* terms of polynomial */ -\} pb_poly; -\end{alltt} - -\begin{enumerate} - \item The \textbf{used} member indicates how many terms of the \textbf{terms} array are used to represent the polynomial. - \item The \textbf{alloc} member indicates the size of the \textbf{terms} array. Also note that even if \textbf{used} - is less than \textbf{alloc} the mp\_ints above \textbf{used} in the array must be set to a valid representation - of zero. - \item The \textbf{characteristic} member is an mp\_int representing the characteristic of the polynomial. If the desire is to - have a null characteristic (e.g. $\Z[x]$) this element must still be initialized to a valid representation - of zero. - \item The \textbf{terms} member is a dynamically sized array of mp\_int values which represent the coefficients for - the terms of the polynomial. They start from least to most significant degree. E.g. $p(x) = \sum_{i=0}^{used-1} terms_i \cdot x^i$. -\end{enumerate} - -\section{Return Codes} -The library uses the return codes from LibTomMath. They are - -\index{MP\_OKAY}\index{MP\_YES}\index{MP\_NO}\index{MP\_VAL}\index{MP\_MEM} -\begin{figure}[here!] -\begin{center} -\begin{small} -\begin{tabular}{|l|l|} -\hline \textbf{Code} & \textbf{Meaning} \\ -\hline MP\_OKAY & The function succeeded. \\ -\hline MP\_VAL & The function input was invalid. \\ -\hline MP\_MEM & Heap memory exhausted. \\ -\hline &\\ -\hline MP\_YES & Response is yes. \\ -\hline MP\_NO & Response is no. \\ -\hline -\end{tabular} -\end{small} -\end{center} -\caption{Return Codes} -\end{figure} - -\section{Function Argument Passing} -Just like LibTomMath the arguments are meant to be read left to right where the destination is on the right. Consider -the following. - -\begin{alltt} -pb_add(a, b, c); /* c = a + b */ -pb_mul(a, b, c); /* c = a * b */ -\end{alltt} - -Also like LibTomMath input arguments can be specified as output arguments. Consider. - -\begin{alltt} -pb_mul(a, b, a); /* a = a * b */ -pb_gcd(a, b, b); /* b = (a, b) */ -\end{alltt} - -However, polynomial math raises another consideration. The characteristic of the result is taken from the right most -argument passed to the function. Not all functions will return an error code if the characteristics of the inputs -do not match so it's important to keep this in mind. In general the results are undefined if not all of the polynomials -have identical characteristics. - -\section{Initializing Polynomials} -In order to use a pb\_poly structure with one of the functions in this library the structure must be initialized. -There are three functions provided to initialize pb\_poly structures. - -\subsection{Default Initialization} -\index{pb\_init} -\begin{alltt} -int pb_init(pb_poly *a, mp_int *characteristic); -\end{alltt} -This will initialize ``a'' with the given ``characteristic'' such that the polynomial represented is a constant zero. -The mp\_int characteristic must be a valid initialized mp\_int even if a characteristic of zero is desired. By default, -the polynomial will be initialized so there are ``PB\_TERMS'' terms available. This will grow automatically as required -by the other functions. - -\subsection{Initilization of Given Size} -\index{pb\_init\_size} -\begin{alltt} -int pb_init_size(pb_poly *a, mp_int *characteristic, int size); -\end{alltt} -This behaves similar to pb\_init() except it will allocate ``size'' terms to initialize instead of ``PB\_TERMS''. This -is useful if you happen to know in advance how many terms you want. - -\subsection{Initilization of a Copy} -\index{pb\_init\_copy} -\begin{alltt} -int pb_init_copy(pb_poly *a, pb_poly *b); -\end{alltt} - -This will initialize ``a'' so it is a verbatim copy of ``b''. It will copy the characteristic and all of the terms -from ``b'' into ``a''. - -\subsection{Freeing a Polynomial} -\index{pb\_clear} -\begin{alltt} -int pb_clear(pb_poly *a); -\end{alltt} - -This will free all the memory required by ``a'' and mark it as been freed. You can repeatedly pb\_clear() the same -pb\_poly safely. - -\chapter{Basic Operations} -\section{Comparison} -Comparisions with polynomials is a bit less intuitive then with integers. Is $x^2 + 3$ greater than $x^2 + x + 4$? To -create a rational form of comparison the following comparison codes were designed. - -\begin{figure}[here] -\begin{small} -\begin{center} -\begin{tabular}{|l|l|} -\hline \textbf{Code} & \textbf{Meaning} \\ -\hline PB\_EQ & The polynomials are exactly equal \\ -\hline PB\_DEG\_LT & The left polynomial has a lower degree than the right. \\ -\hline PB\_DEG\_EQ & Both have the same degree. \\ -\hline PB\_DEG\_GT & The left polynomial has a higher degree than the right. \\ -\hline -\end{tabular} -\end{center} -\end{small} -\caption{Compare Codes} -\end{figure} - -\index{pb\_cmp} -\begin{alltt} -int pb_cmp(pb_poly *a, pb_poly *b); -\end{alltt} - -This will compare the polynomial ``a'' to the left of the polynomial ``b''. It will return one of the four -codes listed above. Note that the function does not compare the characteristics. So if $a \in GF(17)[x]$ and -$b \in GF(11)[x]$ were both equal to $x^2 + 3$ they would compare to PB\_EQ. Whereas $x^3 + 4$ -would compare to PB\_DEG\_LT, $x^1 + 7$ would compare to $PB\_DEG\_GT$ and $x^2 + 7$ would compare to $PB\_DEG\_EQ$\footnote{If the polynomial $a$ were on the left for all three cases.}. - -\section{Copying and Swapping} -\index{pb\_copy} -\begin{alltt} -int pb_copy(pb_poly *src, pb_poly *dest); -\end{alltt} -This will copy the polynomial from ``src'' to ``dest'' verbatim. - -\index{pb\_exch} -\begin{alltt} -int pb_exch(pb_poly *a, pb_poly *b); -\end{alltt} -This will exchange the contents of ``a'' with ``b''. - -\section{Multiplying and Dividing by $x$} -\index{pb\_lshd} \index{pb\_rshd} -\begin{alltt} -int pb_lshd(pb_poly *a, int i); -int pb_rshd(pb_poly *a, int i); -\end{alltt} -These will multiply (or divide, respectfully) the polynomial ``a'' by $x^i$. If $i \le 0$ the functions return without -performing any operation. For example, - -\begin{alltt} -pb_lshd(a, 2); /* a(x) = a(x) * x^2 */ -pb_rshd(a, 7); /* a(x) = a(x) / x^7 */ -\end{alltt} - -\chapter{Basic Arithmetic} -\section{Addition, Subtraction and Multiplication} -\index{pb\_add} \index{pb\_sub} -\begin{alltt} -int pb_add(pb_poly *a, pb_poly *b, pb_poly *c); -int pb_sub(pb_poly *a, pb_poly *b, pb_poly *c); -int pb_mul(pb_poly *a, pb_poly *b, pb_poly *c); -\end{alltt} - -These will add (subtract or multiply, respectfully) the polynomial ``a'' and polynomial ``b'' and store the result in -polynomial ``c''. The characteristic from ``c'' is used to calculate the result. Note that the coefficients of ``c'' -will always be positive provided the characteristic of ``c'' is greater than zero. - -Quick examples of usage. - -\begin{alltt} -pb_add(a, b, c); /* c = a + b */ -pb_sub(b, a, c); /* c = b - a */ -pb_mul(c, a, a); /* a = c * a */ -\end{alltt} - -\section{Division} -\index{pb\_div} -\begin{alltt} -int pb_div(pb_poly *a, pb_poly *b, pb_poly *c, pb_poly *d); -\end{alltt} -This will divide the polynomial ``a'' by ``b'' and store the quotient in ``c'' and remainder in ``d''. That is - -\begin{equation} -b(x) \cdot c(x) + d(x) = a(x) -\end{equation} - -The value of $deg(d(x))$ is always less than $deg(b(x))$. Either of ``c'' and ``d'' can be set to \textbf{NULL} to -signify their value is not desired. This is useful if you only want the quotient or remainder but not both. - -Since one of the destinations can be \textbf{NULL} the characteristic of the result is taken from ``b''. The function -will return an error if the characteristic of ``a'' differs from that of ``b''. - -This function is defined for polynomials in $GF(p)[x]$ only. A routine pb\_zdiv()\footnote{To be written!} allows the -division of polynomials in $\Z[x]$. - -\section{Modular Functions} -\index{pb\_addmod} \index{pb\_submod} \index{pb\_mulmod} -\begin{alltt} -int pb_addmod(pb_poly *a, pb_poly *b, pb_poly *c, pb_poly *d); -int pb_submod(pb_poly *a, pb_poly *b, pb_poly *c, pb_poly *d); -int pb_mulmod(pb_poly *a, pb_poly *b, pb_poly *c, pb_poly *d); -\end{alltt} - -These add (subtract or multiply respectfully) the polynomial ``a'' and the polynomial ``b'' modulo the polynomial ``c'' -and store the result in the polynomial ``d''. - -\chapter{Algebraic Functions} - -\section{Monic Reductions} -\index{pb\_monic} -\begin{alltt} -int pb_monic(pb_poly *a, pb_poly *b) -\end{alltt} -Makes ``b'' the monic representation of ``a'' by ensuring the most significant coefficient is one. Only defined -over $GF(p)[x]$. Note that this is not a straight copy to ``b'' so you must ensure the characteristic of the two -are equal before you call the function\footnote{Note that $a == b$ is acceptable as well.}. Monic polynomials -are related to their original polynomial through an integer $k$ as follows - -\begin{equation} -a(x) \cdot k^{-1} \equiv b(x) -\end{equation} - -\section{Extended Euclidean Algorithm} -\index{pb\_exteuclid} -\begin{alltt} -int pb_exteuclid(pb_poly *a, pb_poly *b, - pb_poly *U1, pb_poly *U2, pb_poly *U3); -\end{alltt} - -This will compute the Euclidean algorithm and find values ``U1'', ``U2'', ``U3'' such that - -\begin{equation} -a(x) \cdot U1(x) + b(x) \cdot U2(x) = U3(x) -\end{equation} - -The value of ``U3'' is reduced to a monic polynomial. The three destination variables are all optional and can -be specified as \textbf{NULL} if they are not desired. - -\section{Greatest Common Divisor} -\index{pb\_gcd} -\begin{alltt} -int pb_gcd(pb_poly *a, pb_poly *b, pb_poly *c); -\end{alltt} -This finds the monic greatest common divisor of the two polynomials ``a'' and ``b'' and store the result in ``c''. The -operation is only defined over $GF(p)[x]$. - -\section{Modular Inverse} -\index{pb\_invmod} -\begin{alltt} -int pb_invmod(pb_poly *a, pb_poly *b, pb_poly *c); -\end{alltt} -This finds the modular inverse of ``a'' modulo ``b'' and stores the result in ``c''. The operation is only defined over -$GF(p)[x]$. If the operation succeed then the following congruency should hold true. - -\begin{equation} -a(x)c(x) \equiv 1 \mbox{ (mod }b(x)\mbox{)} -\end{equation} - -\section{Modular Exponentiation} -\index{pb\_exptmod} -\begin{alltt} -int pb_exptmod (pb_poly * G, mp_int * X, pb_poly * P, pb_poly * Y); -\end{alltt} - -This raise ``G'' to the power of ``X'' modulo ``P'' and stores the result in ``Y''. Or as a congruence - -\begin{equation} -Y(x) \equiv G(x)^X \mbox{ (mod }P(x)\mbox{)} -\end{equation} - -Where ``X'' can be negative\footnote{But in that case $G^{-1}(x)$ must exist modulo $P(x)$.} or positive. This function -is only defined over $GF(p)[x]$. - -\section{Irreducibility Testing} -\index{pb\_isirreduc} -\begin{alltt} -int pb_isirreduc(pb_poly *a, int *res); -\end{alltt} -Sets ``res'' to MP\_YES if ``a'' is irreducible (only for $GF(p)[x]$) otherwise sets ``res'' to MP\_NO. - -\input{pb.ind} - -\end{document} diff --git a/external/libtompoly-0.04/pb_add.c b/external/libtompoly-0.04/pb_add.c deleted file mode 100644 index eb3c8f7..0000000 --- a/external/libtompoly-0.04/pb_add.c +++ /dev/null @@ -1,73 +0,0 @@ -/* LibTomPoly, Polynomial Basis Math -- Tom St Denis - * - * LibTomPoly is a public domain library that provides - * polynomial basis arithmetic support. It relies on - * LibTomMath for large integer support. - * - * This library is free for all purposes without any - * express guarantee that it works. - * - * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org - */ -#include - -int pb_add(pb_poly *a, pb_poly *b, pb_poly *c) -{ - int err, x, y, z, characteristic; - pb_poly *tmp; - - /* grow c to be the max size */ - y = MAX(a->used, b->used); - if (c->alloc < y) { - if ((err = pb_grow(c, y)) != MP_OKAY) { - return err; - } - } - - /* do we need to concern char */ - characteristic = mp_iszero(&(c->characteristic)); - - /* add the terms */ - z = MIN(a->used, b->used); - for (x = 0; x < z; x++) { - if ((err = mp_add(&(a->terms[x]), &(b->terms[x]), &(c->terms[x]))) != MP_OKAY) { - return err; - } - if (characteristic == MP_NO) { - if ((err = mp_mod(&(c->terms[x]), &(c->characteristic), &(c->terms[x]))) != MP_OKAY) { - return err; - } - } - } - - /* excess digits? */ - if (y != z) { - if (a->used == y) { - tmp = a; - } else { - tmp = b; - } - for (x = z; x < y; x++) { - if (characteristic == MP_NO) { - if ((err = mp_mod(&(tmp->terms[x]), &(c->characteristic), &(c->terms[x]))) != MP_OKAY) { - return err; - } - } else { - if ((err = mp_copy(&(tmp->terms[x]), &(c->terms[x]))) != MP_OKAY) { - return err; - } - } - } - } - - /* zero excess */ - for (x = y; x < c->used; x++) { - mp_zero(&(c->terms[x])); - } - c->used = y; - pb_clamp(c); - - return MP_OKAY; -} - - diff --git a/external/libtompoly-0.04/pb_addmod.c b/external/libtompoly-0.04/pb_addmod.c deleted file mode 100644 index 7587e1e..0000000 --- a/external/libtompoly-0.04/pb_addmod.c +++ /dev/null @@ -1,35 +0,0 @@ -/* LibTomPoly, Polynomial Basis Math -- Tom St Denis - * - * LibTomPoly is a public domain library that provides - * polynomial basis arithmetic support. It relies on - * LibTomMath for large integer support. - * - * This library is free for all purposes without any - * express guarantee that it works. - * - * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org - */ -#include - -int pb_addmod(pb_poly *a, pb_poly *b, pb_poly *c, pb_poly *d) -{ - int err; - pb_poly tmp; - - if ((err = pb_init(&tmp, &(d->characteristic))) != MP_OKAY) { - return err; - } - if ((err = pb_add(a, b, &tmp)) != MP_OKAY) { - goto __TMP; - } - if ((err = pb_mod(&tmp, c, d)) != MP_OKAY) { - goto __TMP; - } - - err = MP_OKAY; -__TMP: pb_clear(&tmp); - return err; -} - - - diff --git a/external/libtompoly-0.04/pb_clamp.c b/external/libtompoly-0.04/pb_clamp.c deleted file mode 100644 index c99e7b4..0000000 --- a/external/libtompoly-0.04/pb_clamp.c +++ /dev/null @@ -1,21 +0,0 @@ -/* LibTomPoly, Polynomial Basis Math -- Tom St Denis - * - * LibTomPoly is a public domain library that provides - * polynomial basis arithmetic support. It relies on - * LibTomMath for large integer support. - * - * This library is free for all purposes without any - * express guarantee that it works. - * - * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org - */ -#include - -void pb_clamp(pb_poly *a) -{ - while (a->used > 0 && (mp_iszero(&(a->terms[a->used-1])) == MP_YES)) { - --(a->used); - } -} - - diff --git a/external/libtompoly-0.04/pb_clear.c b/external/libtompoly-0.04/pb_clear.c deleted file mode 100644 index ecfb5c0..0000000 --- a/external/libtompoly-0.04/pb_clear.c +++ /dev/null @@ -1,32 +0,0 @@ -/* LibTomPoly, Polynomial Basis Math -- Tom St Denis - * - * LibTomPoly is a public domain library that provides - * polynomial basis arithmetic support. It relies on - * LibTomMath for large integer support. - * - * This library is free for all purposes without any - * express guarantee that it works. - * - * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org - */ -#include - -void pb_clear(pb_poly *a) -{ - int x; - - if (a->terms != NULL) { - /* free stuff */ - for (x = 0; x < a->alloc; x++) { - mp_clear(&(a->terms[x])); - } - free(a->terms); - mp_clear(&(a->characteristic)); - - /* prevent double frees */ - a->terms = NULL; - a->alloc = a->used = 0; - } -} - - diff --git a/external/libtompoly-0.04/pb_clear_multi.c b/external/libtompoly-0.04/pb_clear_multi.c deleted file mode 100644 index a1dff4a..0000000 --- a/external/libtompoly-0.04/pb_clear_multi.c +++ /dev/null @@ -1,25 +0,0 @@ -/* LibTomPoly, Polynomial Basis Math -- Tom St Denis - * - * LibTomPoly is a public domain library that provides - * polynomial basis arithmetic support. It relies on - * LibTomMath for large integer support. - * - * This library is free for all purposes without any - * express guarantee that it works. - * - * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org - */ -#include -#include - -void pb_clear_multi(pb_poly *mp, ...) -{ - pb_poly* next_mp = mp; - va_list args; - va_start(args, mp); - while (next_mp != NULL) { - pb_clear(next_mp); - next_mp = va_arg(args, pb_poly*); - } - va_end(args); -} diff --git a/external/libtompoly-0.04/pb_cmp.c b/external/libtompoly-0.04/pb_cmp.c deleted file mode 100644 index 0812d61..0000000 --- a/external/libtompoly-0.04/pb_cmp.c +++ /dev/null @@ -1,32 +0,0 @@ -/* LibTomPoly, Polynomial Basis Math -- Tom St Denis - * - * LibTomPoly is a public domain library that provides - * polynomial basis arithmetic support. It relies on - * LibTomMath for large integer support. - * - * This library is free for all purposes without any - * express guarantee that it works. - * - * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org - */ -#include - -int pb_cmp(pb_poly *a, pb_poly *b) -{ - int x; - - if (a->used > b->used) { - return PB_DEG_GT; - } else if (a->used < b->used) { - return PB_DEG_LT; - } - - for (x = 0; x < a->used; x++) { - if (mp_cmp(&(a->terms[x]), &(b->terms[x])) != MP_EQ) { - return PB_DEG_EQ; - } - } - return PB_EQ; -} - - diff --git a/external/libtompoly-0.04/pb_copy.c b/external/libtompoly-0.04/pb_copy.c deleted file mode 100644 index d9ae366..0000000 --- a/external/libtompoly-0.04/pb_copy.c +++ /dev/null @@ -1,51 +0,0 @@ -/* LibTomPoly, Polynomial Basis Math -- Tom St Denis - * - * LibTomPoly is a public domain library that provides - * polynomial basis arithmetic support. It relies on - * LibTomMath for large integer support. - * - * This library is free for all purposes without any - * express guarantee that it works. - * - * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org - */ -#include - -/* dest = src */ -int pb_copy(pb_poly *src, pb_poly *dest) -{ - int err, x; - - /* avoid trivial copies */ - if (src == dest) { - return MP_OKAY; - } - - /* grow dest as required */ - if (dest->alloc < src->used) { - if ((err = pb_grow(dest, src->used)) != MP_OKAY) { - return err; - } - } - - /* set the characteristic */ - if ((err = mp_copy(&(src->characteristic), &(dest->characteristic))) != MP_OKAY) { - return err; - } - - /* copy digits */ - for (x = 0; x < src->used; x++) { - if ((err = mp_copy(&(src->terms[x]), &(dest->terms[x]))) != MP_OKAY) { - return err; - } - } - - /* zero excess digits */ - for (x = src->used; x < dest->used; x++) { - mp_zero(&(dest->terms[x])); - } - dest->used = src->used; - return MP_OKAY; -} - - diff --git a/external/libtompoly-0.04/pb_div.c b/external/libtompoly-0.04/pb_div.c deleted file mode 100644 index 84d5665..0000000 --- a/external/libtompoly-0.04/pb_div.c +++ /dev/null @@ -1,135 +0,0 @@ -/* LibTomPoly, Polynomial Basis Math -- Tom St Denis - * - * LibTomPoly is a public domain library that provides - * polynomial basis arithmetic support. It relies on - * LibTomMath for large integer support. - * - * This library is free for all purposes without any - * express guarantee that it works. - * - * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org - */ -#include - - -/* Divides a by b (uses the char of b as the char of the result) only for - * polynomials over GF(p^k)[x] - */ -int pb_div(pb_poly *a, pb_poly *b, pb_poly *c, pb_poly *d) -{ - int err, x; - pb_poly p, q, r; - mp_int tmp, tmp2; - - /* if ||b|| > ||a|| it's a simple copy over */ - if (b->used > a->used) { - if (d != NULL) { - pb_copy(a, d); - } - if (c != NULL) { - pb_zero(c); - } - } - - /* zero divisor */ - if (b->used == 0) { - return MP_VAL; - } - - /* compare chars */ - if (mp_cmp(&(a->characteristic), &(b->characteristic)) != MP_EQ) { - return MP_VAL; - } - - /* we don't support char zero! */ - if (mp_iszero(&(b->characteristic)) == MP_YES) { - return MP_VAL; - } - - /* get a copy of "a" to work with */ - if ((err = pb_init_copy(&p, a)) != MP_OKAY) { - return err; - } - - /* init a temp quotient */ - if ((err = pb_init_size(&q, &(b->characteristic), a->used - b->used + 1)) != MP_OKAY) { - goto __P; - } - - /* init a temp polynomial we can work with */ - if ((err = pb_init_size(&r, &(b->characteristic), a->used)) != MP_OKAY) { - goto __Q; - } - - /* now init an mp_int we can work with */ - if ((err = mp_init(&tmp)) != MP_OKAY) { - goto __R; - } - - /* and the inverse of the leading digit of b(x) */ - if ((err = mp_init(&tmp2)) != MP_OKAY) { - goto __TMP; - } - if ((err = mp_invmod(&(b->terms[b->used - 1]), &(b->characteristic), &tmp2)) != MP_OKAY) { - goto __TMP2; - } - - /* now let's reduce us some digits */ - for (x = a->used - 1; x >= b->used-1; x--) { - /* skip zero digits */ - if (mp_iszero(&(p.terms[x])) == MP_YES) { - continue; - } - - /* now we have a leading digit of p(x), call it A - and a leading digit of b(x), call it B - - Now we want to reduce it so we need A + CB = 0 which turns into - A + CB = 0 - CB = -A - C = -A/B - - So we multiply b(x) by C * x^k [where k = ||p(x)|| - ||b(x)||], add that to p(x) and - we must reduced one digit - */ - - /* multiply 1/B [tmp2] by A */ - if ((err = mp_mulmod(&tmp2, &(p.terms[x]), &(b->characteristic), &tmp)) != MP_OKAY) { goto __TMP2; } - - /* tmp is now a term of the quotient */ - if ((err = mp_copy(&tmp, &(q.terms[x - b->used + 1]))) != MP_OKAY) { goto __TMP2; } - - /* create r(x) = C */ - pb_zero(&r); - if ((err = mp_copy(&tmp, &(r.terms[0]))) != MP_OKAY) { goto __TMP2; } - r.used = 1; - - /* now multiply r(x) by b(x)*x^k and subtract from p(x) */ - if ((err = pb_mul(b, &r, &r)) != MP_OKAY) { goto __TMP2; } - if ((err = pb_lshd(&r, x - b->used + 1)) != MP_OKAY) { goto __TMP2; } - if ((err = pb_sub(&p, &r, &p)) != MP_OKAY) { goto __TMP2; } - } - - /* setup q properly (so q.used is valid) */ - q.used = a->used; - pb_clamp(&q); - - /* ok so now p(x) is the remainder and q(x) is the quotient */ - if (c != NULL) { - pb_exch(&q, c); - } - if (d != NULL) { - pb_exch(&p, d); - } - - err = MP_OKAY; - -__TMP2: mp_clear(&tmp2); -__TMP : mp_clear(&tmp); -__R : pb_clear(&r); -__Q : pb_clear(&q); -__P : pb_clear(&p); - return err; -} - - diff --git a/external/libtompoly-0.04/pb_exch.c b/external/libtompoly-0.04/pb_exch.c deleted file mode 100644 index b2925b9..0000000 --- a/external/libtompoly-0.04/pb_exch.c +++ /dev/null @@ -1,20 +0,0 @@ -/* LibTomPoly, Polynomial Basis Math -- Tom St Denis - * - * LibTomPoly is a public domain library that provides - * polynomial basis arithmetic support. It relies on - * LibTomMath for large integer support. - * - * This library is free for all purposes without any - * express guarantee that it works. - * - * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org - */ -#include - -void pb_exch(pb_poly *a, pb_poly *b) -{ - pb_poly tmp; - tmp = *a; *a = *b; *b = tmp; -} - - diff --git a/external/libtompoly-0.04/pb_exptmod.c b/external/libtompoly-0.04/pb_exptmod.c deleted file mode 100644 index e203b72..0000000 --- a/external/libtompoly-0.04/pb_exptmod.c +++ /dev/null @@ -1,186 +0,0 @@ -/* LibTomPoly, Polynomial Basis Math -- Tom St Denis - * - * LibTomPoly is a public domain library that provides - * polynomial basis arithmetic support. It relies on - * LibTomMath for large integer support. - * - * This library is free for all purposes without any - * express guarantee that it works. - * - * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org - */ -#include - -#ifdef MP_LOW_MEM - #define TAB_SIZE 32 -#else - #define TAB_SIZE 256 -#endif - -int pb_exptmod (pb_poly * G, mp_int * X, pb_poly * P, pb_poly * Y) -{ - pb_poly M[TAB_SIZE], res; - mp_digit buf; - int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize; - - /* find window size */ - x = mp_count_bits (X); - if (x <= 7) { - winsize = 2; - } else if (x <= 36) { - winsize = 3; - } else if (x <= 140) { - winsize = 4; - } else if (x <= 450) { - winsize = 5; - } else if (x <= 1303) { - winsize = 6; - } else if (x <= 3529) { - winsize = 7; - } else { - winsize = 8; - } - -#ifdef MP_LOW_MEM - if (winsize > 5) { - winsize = 5; - } -#endif - - /* init M array */ - /* init first cell */ - if ((err = pb_init(&M[1], &(Y->characteristic))) != MP_OKAY) { - return err; - } - - /* now init the second half of the array */ - for (x = 1<<(winsize-1); x < (1 << winsize); x++) { - if ((err = pb_init(&M[x], &(Y->characteristic))) != MP_OKAY) { - for (y = 1<<(winsize-1); y < x; y++) { - pb_clear (&M[y]); - } - pb_clear(&M[1]); - return err; - } - } - - /* create M table - * - * The M table contains powers of the base, - * e.g. M[x] = G**x mod P - * - * The first half of the table is not - * computed though accept for M[0] and M[1] - */ - - if (X->sign == MP_ZPOS) { - if ((err = pb_mod (G, P, &M[1])) != MP_OKAY) { goto __M; } - } else { - if ((err = pb_invmod(G, P, &M[1])) != MP_OKAY) { goto __M; } - } - - /* compute the value at M[1<<(winsize-1)] by squaring - * M[1] (winsize-1) times - */ - if ((err = pb_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) { goto __M; } - - for (x = 0; x < (winsize - 1); x++) { - if ((err = pb_mulmod (&M[1 << (winsize - 1)], &M[1 << (winsize - 1)], - P, &M[1 << (winsize - 1)])) != MP_OKAY) { goto __M; } - } - - /* create upper table, that is M[x] = M[x-1] * M[1] (mod P) - * for x = (2**(winsize - 1) + 1) to (2**winsize - 1) - */ - for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) { - if ((err = pb_mulmod (&M[x - 1], &M[1], P, &M[x])) != MP_OKAY) { goto __M; } - } - - /* setup result */ - if ((err = pb_init (&res, &(Y->characteristic))) != MP_OKAY) { goto __M; } - mp_set (&(res.terms[0]), 1); res.used = 1; - - /* set initial mode and bit cnt */ - mode = 0; - bitcnt = 1; - buf = 0; - digidx = X->used - 1; - bitcpy = 0; - bitbuf = 0; - - for (;;) { - /* grab next digit as required */ - if (--bitcnt == 0) { - /* if digidx == -1 we are out of digits */ - if (digidx == -1) { - break; - } - /* read next digit and reset the bitcnt */ - buf = X->dp[digidx--]; - bitcnt = (int) DIGIT_BIT; - } - - /* grab the next msb from the exponent */ - y = (buf >> (mp_digit)(DIGIT_BIT - 1)) & 1; - buf <<= (mp_digit)1; - - /* if the bit is zero and mode == 0 then we ignore it - * These represent the leading zero bits before the first 1 bit - * in the exponent. Technically this opt is not required but it - * does lower the # of trivial squaring/reductions used - */ - if (mode == 0 && y == 0) { - continue; - } - - /* if the bit is zero and mode == 1 then we square */ - if (mode == 1 && y == 0) { - if ((err = pb_mulmod (&res, &res, P, &res)) != MP_OKAY) { goto __RES; } - continue; - } - - /* else we add it to the window */ - bitbuf |= (y << (winsize - ++bitcpy)); - mode = 2; - - if (bitcpy == winsize) { - /* ok window is filled so square as required and multiply */ - /* square first */ - for (x = 0; x < winsize; x++) { - if ((err = pb_mulmod (&res, &res, P, &res)) != MP_OKAY) { goto __RES; } - } - - /* then multiply */ - if ((err = pb_mulmod (&res, &M[bitbuf], P, &res)) != MP_OKAY) { goto __RES; } - - /* empty window and reset */ - bitcpy = 0; - bitbuf = 0; - mode = 1; - } - } - - /* if bits remain then square/multiply */ - if (mode == 2 && bitcpy > 0) { - /* square then multiply if the bit is set */ - for (x = 0; x < bitcpy; x++) { - if ((err = pb_mulmod (&res, &res, P, &res)) != MP_OKAY) { goto __RES; } - - bitbuf <<= 1; - if ((bitbuf & (1 << winsize)) != 0) { - /* then multiply */ - if ((err = pb_mulmod (&res, &M[1], P, &res)) != MP_OKAY) { goto __RES; } - } - } - } - - pb_exch (&res, Y); - err = MP_OKAY; -__RES:pb_clear (&res); -__M: - pb_clear(&M[1]); - for (x = 1<<(winsize-1); x < (1 << winsize); x++) { - pb_clear (&M[x]); - } - return err; -} diff --git a/external/libtompoly-0.04/pb_exteuclid.c b/external/libtompoly-0.04/pb_exteuclid.c deleted file mode 100644 index 2fb6911..0000000 --- a/external/libtompoly-0.04/pb_exteuclid.c +++ /dev/null @@ -1,74 +0,0 @@ -/* LibTomPoly, Polynomial Basis Math -- Tom St Denis - * - * LibTomPoly is a public domain library that provides - * polynomial basis arithmetic support. It relies on - * LibTomMath for large integer support. - * - * This library is free for all purposes without any - * express guarantee that it works. - * - * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org - */ -#include - -/* Extended euclidean algorithm of (a, b) produces - a*u1 + b*u2 = u3 - */ -int pb_exteuclid(pb_poly *a, pb_poly *b, pb_poly *U1, pb_poly *U2, pb_poly *U3) -{ - pb_poly u1,u2,u3,v1,v2,v3,t1,t2,t3,q,tmp; - int err; - - if ((err = pb_init_multi(&(b->characteristic), - &u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL)) != MP_OKAY) { - return err; - } - - /* initialize, (u1,u2,u3) = (1,0,a) */ - mp_set(&(u1.terms[0]), 1); u1.used = 1; - if ((err = pb_copy(a, &u3)) != MP_OKAY) { goto _ERR; } - - /* initialize, (v1,v2,v3) = (0,1,b) */ - mp_set(&(v2.terms[0]), 1); v2.used = 1; - if ((err = pb_copy(b, &v3)) != MP_OKAY) { goto _ERR; } - - /* loop while v3 != 0 */ - while (v3.used > 0) { - /* q = u3/v3 */ - if ((err = pb_div(&u3, &v3, &q, NULL)) != MP_OKAY) { goto _ERR; } - - /* (t1,t2,t3) = (u1,u2,u3) - (v1,v2,v3)q */ - if ((err = pb_mul(&v1, &q, &tmp)) != MP_OKAY) { goto _ERR; } - if ((err = pb_sub(&u1, &tmp, &t1)) != MP_OKAY) { goto _ERR; } - if ((err = pb_mul(&v2, &q, &tmp)) != MP_OKAY) { goto _ERR; } - if ((err = pb_sub(&u2, &tmp, &t2)) != MP_OKAY) { goto _ERR; } - if ((err = pb_mul(&v3, &q, &tmp)) != MP_OKAY) { goto _ERR; } - if ((err = pb_sub(&u3, &tmp, &t3)) != MP_OKAY) { goto _ERR; } - - /* (u1,u2,u3) = (v1,v2,v3) */ - if ((err = pb_copy(&v1, &u1)) != MP_OKAY) { goto _ERR; } - if ((err = pb_copy(&v2, &u2)) != MP_OKAY) { goto _ERR; } - if ((err = pb_copy(&v3, &u3)) != MP_OKAY) { goto _ERR; } - - /* (v1,v2,v3) = (t1,t2,t3) */ - if ((err = pb_copy(&t1, &v1)) != MP_OKAY) { goto _ERR; } - if ((err = pb_copy(&t2, &v2)) != MP_OKAY) { goto _ERR; } - if ((err = pb_copy(&t3, &v3)) != MP_OKAY) { goto _ERR; } - } - - /* reduce U3 to monic but we have to mangle all three to remain consistent */ - pb_zero(&v1); - if ((err = mp_copy(&(u3.terms[u3.used-1]), &(v1.terms[0]))) != MP_OKAY) { goto _ERR; } - v1.used = 1; - - /* copy result out */ - if (U1 != NULL) { if ((err = pb_div(&u1, &v1, U1, NULL)) != MP_OKAY) { goto _ERR; }} - if (U2 != NULL) { if ((err = pb_div(&u2, &v1, U2, NULL)) != MP_OKAY) { goto _ERR; }} - if (U3 != NULL) { if ((err = pb_div(&u3, &v1, U3, NULL)) != MP_OKAY) { goto _ERR; }} - - err = MP_OKAY; -_ERR: pb_clear_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL); - return err; -} - - diff --git a/external/libtompoly-0.04/pb_gcd.c b/external/libtompoly-0.04/pb_gcd.c deleted file mode 100644 index 12749b6..0000000 --- a/external/libtompoly-0.04/pb_gcd.c +++ /dev/null @@ -1,69 +0,0 @@ -/* LibTomPoly, Polynomial Basis Math -- Tom St Denis - * - * LibTomPoly is a public domain library that provides - * polynomial basis arithmetic support. It relies on - * LibTomMath for large integer support. - * - * This library is free for all purposes without any - * express guarantee that it works. - * - * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org - */ -#include - -/* returns the monic GCD only for GF(p^k)[x] */ -int pb_gcd(pb_poly *a, pb_poly *b, pb_poly *c) -{ - pb_poly A, B, tmp; - int err; - - if (mp_iszero(&(c->characteristic)) == MP_YES) { - return MP_VAL; - } - - /* special cases (one or both are zero) */ - if (a->used == 0 && b->used == 0) { - /* both zero, set to 1 */ - pb_zero(c); - c->used = 1; - mp_set(&(c->terms[0]), 1); - return MP_OKAY; - } else if (a->used == 0) { - return pb_copy(b, c); - } else if (b->used == 0) { - return pb_copy(a, c); - } - - if ((err = pb_init(&tmp, &(c->characteristic))) != MP_OKAY) { - return err; - } - if ((err = pb_init_copy(&A, a)) != MP_OKAY) { - goto __TMP; - } - if ((err = pb_init_copy(&B, b)) != MP_OKAY) { - goto __A; - } - - while (B.used > 0) { - if ((err = pb_mod(&A, &B, &tmp)) != MP_OKAY) { - goto __B; - } - /* A = B, B = tmp */ - if ((err = pb_copy(&B, &A)) != MP_OKAY) { - goto __B; - } - if ((err = pb_copy(&tmp, &B)) != MP_OKAY) { - goto __B; - } - } - - /* ensure it's monic */ - err = pb_monic(&A, c); - -__B : pb_clear(&B); -__A : pb_clear(&A); -__TMP: pb_clear(&tmp); - return err; -} - - diff --git a/external/libtompoly-0.04/pb_grow.c b/external/libtompoly-0.04/pb_grow.c deleted file mode 100644 index b9e34e5..0000000 --- a/external/libtompoly-0.04/pb_grow.c +++ /dev/null @@ -1,46 +0,0 @@ -/* LibTomPoly, Polynomial Basis Math -- Tom St Denis - * - * LibTomPoly is a public domain library that provides - * polynomial basis arithmetic support. It relies on - * LibTomMath for large integer support. - * - * This library is free for all purposes without any - * express guarantee that it works. - * - * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org - */ -#include - -int pb_grow(pb_poly *a, int size) -{ - mp_int *tmp; - int x, err; - - if (a->alloc < size) { - /* pad size upwards */ - size += (PB_TERMS - (size % PB_TERMS)); - - /* regrow terms */ - tmp = realloc(a->terms, sizeof(mp_int) * size); - if (tmp == NULL) { - return MP_MEM; - } - a->terms = tmp; - - /* zero the new stuff (prevents mp_clear from double freeing) */ - memset(a->terms + a->alloc, 0, (size - a->alloc) * sizeof(mp_int)); - - /* now init the terms */ - for (x = a->alloc; x < size; x++) { - if ((err = mp_init(&(a->terms[x]))) != MP_OKAY) { - return err; - } - } - - /* update info */ - a->alloc = size; - } - return MP_OKAY; -} - - diff --git a/external/libtompoly-0.04/pb_init.c b/external/libtompoly-0.04/pb_init.c deleted file mode 100644 index c312534..0000000 --- a/external/libtompoly-0.04/pb_init.c +++ /dev/null @@ -1,49 +0,0 @@ -/* LibTomPoly, Polynomial Basis Math -- Tom St Denis - * - * LibTomPoly is a public domain library that provides - * polynomial basis arithmetic support. It relies on - * LibTomMath for large integer support. - * - * This library is free for all purposes without any - * express guarantee that it works. - * - * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org - */ -#include - -/* initialize a */ -int pb_init(pb_poly *a, mp_int *characteristic) -{ - int x, y, err; - - /* init characteristic */ - if ((err = mp_init_copy(&(a->characteristic), characteristic)) != MP_OKAY) { - return err; - } - - /* now allocate an array of mp_ints */ - if ((a->terms = calloc(PB_TERMS, sizeof(mp_int))) == NULL) { - mp_clear(&(a->characteristic)); - return MP_MEM; - } - - /* now initialize them all */ - for (x = 0; x < PB_TERMS; x++) { - if ((err = mp_init(&(a->terms[x]))) != MP_OKAY) { - /* free stuff */ - for (y = 0; y < x; y++) { - mp_clear(&(a->terms[y])); - } - free(a->terms); - mp_clear(&(a->characteristic)); - return err; - } - } - - /* set our parameters */ - a->used = 0; - a->alloc = PB_TERMS; - return MP_OKAY; -} - - diff --git a/external/libtompoly-0.04/pb_init_copy.c b/external/libtompoly-0.04/pb_init_copy.c deleted file mode 100644 index dc93f2f..0000000 --- a/external/libtompoly-0.04/pb_init_copy.c +++ /dev/null @@ -1,21 +0,0 @@ -/* LibTomPoly, Polynomial Basis Math -- Tom St Denis - * - * LibTomPoly is a public domain library that provides - * polynomial basis arithmetic support. It relies on - * LibTomMath for large integer support. - * - * This library is free for all purposes without any - * express guarantee that it works. - * - * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org - */ -#include - -int pb_init_copy(pb_poly *a, pb_poly *b) -{ - int err; - if ((err = pb_init(a, &(b->characteristic))) != MP_OKAY) { - return err; - } - return pb_copy(b, a); -} diff --git a/external/libtompoly-0.04/pb_init_multi.c b/external/libtompoly-0.04/pb_init_multi.c deleted file mode 100644 index f704b86..0000000 --- a/external/libtompoly-0.04/pb_init_multi.c +++ /dev/null @@ -1,50 +0,0 @@ -/* LibTomPoly, Polynomial Basis Math -- Tom St Denis - * - * LibTomPoly is a public domain library that provides - * polynomial basis arithmetic support. It relies on - * LibTomMath for large integer support. - * - * This library is free for all purposes without any - * express guarantee that it works. - * - * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org - */ -#include -#include - -int pb_init_multi(mp_int *characteristic, pb_poly *pb, ...) -{ - mp_err res = MP_OKAY; /* Assume ok until proven otherwise */ - int n = 0; /* Number of ok inits */ - pb_poly* cur_arg = pb; - va_list args; - - va_start(args, pb); /* init args to next argument from caller */ - while (cur_arg != NULL) { - if (pb_init(cur_arg, characteristic) != MP_OKAY) { - /* Oops - error! Back-track and mp_clear what we already - succeeded in init-ing, then return error. - */ - va_list clean_args; - - /* end the current list */ - va_end(args); - - /* now start cleaning up */ - cur_arg = pb; - va_start(clean_args, pb); - while (n--) { - pb_clear(cur_arg); - cur_arg = va_arg(clean_args, pb_poly*); - } - va_end(clean_args); - res = MP_MEM; - break; - } - n++; - cur_arg = va_arg(args, pb_poly*); - } - va_end(args); - return res; /* Assumed ok, if error flagged above. */ -} - diff --git a/external/libtompoly-0.04/pb_init_size.c b/external/libtompoly-0.04/pb_init_size.c deleted file mode 100644 index bf44027..0000000 --- a/external/libtompoly-0.04/pb_init_size.c +++ /dev/null @@ -1,58 +0,0 @@ -/* LibTomPoly, Polynomial Basis Math -- Tom St Denis - * - * LibTomPoly is a public domain library that provides - * polynomial basis arithmetic support. It relies on - * LibTomMath for large integer support. - * - * This library is free for all purposes without any - * express guarantee that it works. - * - * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org - */ -#include - -/* initialize a */ -int pb_init_size(pb_poly *a, mp_int *characteristic, int size) -{ - int x, y, err; - - /* enforce a minimum size */ - if (size < 1) { - size = 1; - } - - /* pad size upwards */ - size += (PB_TERMS - (size % PB_TERMS)); - - - /* init characteristic */ - if ((err = mp_init_copy(&(a->characteristic), characteristic)) != MP_OKAY) { - return err; - } - - /* now allocate an array of mp_ints */ - if ((a->terms = calloc(size, sizeof(mp_int))) == NULL) { - mp_clear(&(a->characteristic)); - return MP_MEM; - } - - /* now initialize them all */ - for (x = 0; x < size; x++) { - if ((err = mp_init(&(a->terms[x]))) != MP_OKAY) { - /* free stuff */ - for (y = 0; y < x; y++) { - mp_clear(&(a->terms[y])); - } - free(a->terms); - mp_clear(&(a->characteristic)); - return err; - } - } - - /* set our parameters */ - a->used = 0; - a->alloc = size; - return MP_OKAY; -} - - diff --git a/external/libtompoly-0.04/pb_invmod.c b/external/libtompoly-0.04/pb_invmod.c deleted file mode 100644 index 5607dec..0000000 --- a/external/libtompoly-0.04/pb_invmod.c +++ /dev/null @@ -1,33 +0,0 @@ -/* LibTomPoly, Polynomial Basis Math -- Tom St Denis - * - * LibTomPoly is a public domain library that provides - * polynomial basis arithmetic support. It relies on - * LibTomMath for large integer support. - * - * This library is free for all purposes without any - * express guarantee that it works. - * - * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org - */ -#include - -int pb_invmod(pb_poly *a, pb_poly *b, pb_poly *c) -{ - int err; - pb_poly tmp; - - if ((err = pb_init(&tmp, &(c->characteristic))) != MP_OKAY) { - return err; - } - - if ((err = pb_exteuclid(a, b, c, NULL, &tmp)) != MP_OKAY) { goto _ERR; } - - /* if deg(tmp(x)) > 0 then there is no invmod */ - if (tmp.used > 1) { err = MP_VAL; goto _ERR; } - - err = MP_OKAY; -_ERR: pb_clear(&tmp); - return err; -} - - diff --git a/external/libtompoly-0.04/pb_isirreduc.c b/external/libtompoly-0.04/pb_isirreduc.c deleted file mode 100644 index 7600386..0000000 --- a/external/libtompoly-0.04/pb_isirreduc.c +++ /dev/null @@ -1,59 +0,0 @@ -/* LibTomPoly, Polynomial Basis Math -- Tom St Denis - * - * LibTomPoly is a public domain library that provides - * polynomial basis arithmetic support. It relies on - * LibTomMath for large integer support. - * - * This library is free for all purposes without any - * express guarantee that it works. - * - * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org - */ -#include - -/* is a(x) irreducible? */ -int pb_isirreduc(pb_poly *a, int *res) -{ - pb_poly u, tmp, fm, d; - int err, i; - - /* default to no */ - *res = MP_NO; - - /* init temps */ - if ((err = pb_init_multi(&(a->characteristic), - &u, &tmp, &fm, &d, NULL)) != MP_OKAY) { - return err; - } - - /* fm = monic(a(x)) */ - if ((err = pb_monic(a, &fm)) != MP_OKAY) { goto _ERR; } - - /* u = x */ - mp_set(&(u.terms[1]), 1); u.used = 2; - - /* loop */ - for (i = 1; i <= (a->used / 2); i++) { - /* u = u^p mod fm */ - if ((err = pb_exptmod(&u, &(a->characteristic), &fm, &u)) != MP_OKAY) { goto _ERR; } - - /* tmp = u - x */ - pb_zero(&tmp); - mp_set(&(tmp.terms[1]), 1); tmp.used = 2; - if ((err = pb_sub(&u, &tmp, &tmp)) != MP_OKAY) { goto _ERR; } - - /* d = gcd(fm, tmp) */ - if ((err = pb_gcd(&fm, &tmp, &d)) != MP_OKAY) { goto _ERR; } - - /* if d != 1 then reducible */ - if (d.used > 1) { err = MP_OKAY; goto _ERR; } - } - - /* irreducible */ - *res = MP_YES; - err = MP_OKAY; -_ERR: pb_clear_multi(&u, &tmp, &fm, &d, NULL); - return err; -} - - diff --git a/external/libtompoly-0.04/pb_lshd.c b/external/libtompoly-0.04/pb_lshd.c deleted file mode 100644 index 155b391..0000000 --- a/external/libtompoly-0.04/pb_lshd.c +++ /dev/null @@ -1,42 +0,0 @@ -/* LibTomPoly, Polynomial Basis Math -- Tom St Denis - * - * LibTomPoly is a public domain library that provides - * polynomial basis arithmetic support. It relies on - * LibTomMath for large integer support. - * - * This library is free for all purposes without any - * express guarantee that it works. - * - * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org - */ -#include - -int pb_lshd(pb_poly *a, int x) -{ - int err, y; - - if (x <= 0) { - return MP_OKAY; - } - - /* grow as required */ - if (a->alloc < (a->used + x)) { - if ((err = pb_grow(a, a->used + x)) != MP_OKAY) { - return err; - } - } - - /* shift */ - for (y = a->used + x; y >= x; y--) { - mp_exch(&(a->terms[y-x]), &(a->terms[y])); - } - - /* zero lower digits */ - for (y = 0; y < x; y++) { - mp_zero(&(a->terms[y])); - } - a->used += x; - - return MP_OKAY; -} - diff --git a/external/libtompoly-0.04/pb_mod.c b/external/libtompoly-0.04/pb_mod.c deleted file mode 100644 index 4be21e9..0000000 --- a/external/libtompoly-0.04/pb_mod.c +++ /dev/null @@ -1,19 +0,0 @@ -/* LibTomPoly, Polynomial Basis Math -- Tom St Denis - * - * LibTomPoly is a public domain library that provides - * polynomial basis arithmetic support. It relies on - * LibTomMath for large integer support. - * - * This library is free for all purposes without any - * express guarantee that it works. - * - * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org - */ -#include - -int pb_mod(pb_poly *a, pb_poly *b, pb_poly *c) -{ - return pb_div(a, b, NULL, c); -} - - diff --git a/external/libtompoly-0.04/pb_monic.c b/external/libtompoly-0.04/pb_monic.c deleted file mode 100644 index 19107bb..0000000 --- a/external/libtompoly-0.04/pb_monic.c +++ /dev/null @@ -1,60 +0,0 @@ -/* LibTomPoly, Polynomial Basis Math -- Tom St Denis - * - * LibTomPoly is a public domain library that provides - * polynomial basis arithmetic support. It relies on - * LibTomMath for large integer support. - * - * This library is free for all purposes without any - * express guarantee that it works. - * - * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org - */ -#include - -/* makes b equal to the monic polynomial form of a */ -int pb_monic(pb_poly *a, pb_poly *b) -{ - mp_int tmp; - int err, x; - - /* must be in GF(p)[x] */ - if (mp_iszero(&(b->characteristic)) == MP_YES) { - return MP_VAL; - } - - /* if it's already monic just copy */ - if (a->used == 0 || mp_cmp_d(&(a->terms[a->used - 1]), 1) == MP_EQ) { - return pb_copy(a, b); - } - - /* grow b to hold result */ - if (b->alloc < a->used) { - if ((err = pb_grow(b, a->used)) != MP_OKAY) { - return err; - } - } - - /* now init tmp and find the inverse of the leading digit */ - if ((err = mp_init(&tmp)) != MP_OKAY) { - return err; - } - - if ((err = mp_invmod(&(a->terms[a->used-1]), &(b->characteristic), &tmp)) != MP_OKAY) { goto _ERR; } - - /* now reduce each coefficient */ - for (x = 0; x < a->used; x++) { - if ((err = mp_mulmod(&(a->terms[x]), &tmp, &(b->characteristic), &(b->terms[x]))) != MP_OKAY) { goto _ERR; } - } - - /* zero excess digits */ - for (x = a->used; x < b->used; x++) { - mp_zero(&(b->terms[x])); - } - b->used = a->used; - - err = MP_OKAY; -_ERR: mp_clear(&tmp); - return err; -} - - diff --git a/external/libtompoly-0.04/pb_mul.c b/external/libtompoly-0.04/pb_mul.c deleted file mode 100644 index b215f54..0000000 --- a/external/libtompoly-0.04/pb_mul.c +++ /dev/null @@ -1,62 +0,0 @@ -/* LibTomPoly, Polynomial Basis Math -- Tom St Denis - * - * LibTomPoly is a public domain library that provides - * polynomial basis arithmetic support. It relies on - * LibTomMath for large integer support. - * - * This library is free for all purposes without any - * express guarantee that it works. - * - * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org - */ -#include - -int pb_mul(pb_poly *a, pb_poly *b, pb_poly *c) -{ - int err, x, y; - pb_poly tmp; - mp_int tmp2; - - /* make temp */ - if ((err = pb_init_size(&tmp, &(c->characteristic), a->used + b->used)) != MP_OKAY) { - return err; - } - - if ((err = mp_init(&tmp2)) != MP_OKAY) { - goto __TMP; - } - - /* multiply the terms */ - for (x = 0; x < a->used; x++) { - for (y = 0; y < b->used; y++) { - if ((err = mp_mul(&(a->terms[x]), &(b->terms[y]), &tmp2)) != MP_OKAY) { - goto __TMP2; - } - if ((err = mp_add(&tmp2, &(tmp.terms[x+y]), &(tmp.terms[x+y]))) != MP_OKAY) { - goto __TMP2; - } - } - } - - /* now reduce the terms as required */ - if (mp_iszero(&(c->characteristic)) == MP_NO) { - for (x = 0; x < (a->used + b->used); x++) { - if ((err = mp_mod(&(tmp.terms[x]), &(c->characteristic), &(tmp.terms[x]))) != MP_OKAY) { - goto __TMP2; - } - } - } - - /* set digit count */ - tmp.used = a->used + b->used; - pb_clamp(&tmp); - - /* exchange tmp and c */ - pb_exch(&tmp, c); - - err = MP_OKAY; - -__TMP2: mp_clear(&tmp2); -__TMP : pb_clear(&tmp); - return err; -} diff --git a/external/libtompoly-0.04/pb_mulmod.c b/external/libtompoly-0.04/pb_mulmod.c deleted file mode 100644 index b960043..0000000 --- a/external/libtompoly-0.04/pb_mulmod.c +++ /dev/null @@ -1,35 +0,0 @@ -/* LibTomPoly, Polynomial Basis Math -- Tom St Denis - * - * LibTomPoly is a public domain library that provides - * polynomial basis arithmetic support. It relies on - * LibTomMath for large integer support. - * - * This library is free for all purposes without any - * express guarantee that it works. - * - * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org - */ -#include - -int pb_mulmod(pb_poly *a, pb_poly *b, pb_poly *c, pb_poly *d) -{ - int err; - pb_poly tmp; - - if ((err = pb_init(&tmp, &(d->characteristic))) != MP_OKAY) { - return err; - } - if ((err = pb_mul(a, b, &tmp)) != MP_OKAY) { - goto __TMP; - } - if ((err = pb_mod(&tmp, c, d)) != MP_OKAY) { - goto __TMP; - } - - err = MP_OKAY; -__TMP: pb_clear(&tmp); - return err; -} - - - diff --git a/external/libtompoly-0.04/pb_rawsize.c b/external/libtompoly-0.04/pb_rawsize.c deleted file mode 100644 index 43ccc76..0000000 --- a/external/libtompoly-0.04/pb_rawsize.c +++ /dev/null @@ -1,32 +0,0 @@ -/* LibTomPoly, Polynomial Basis Math -- Tom St Denis - * - * LibTomPoly is a public domain library that provides - * polynomial basis arithmetic support. It relies on - * LibTomMath for large integer support. - * - * This library is free for all purposes without any - * express guarantee that it works. - * - * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org - */ -#include - -int pb_rawsize(pb_poly *a) -{ - int x, y; - - /* 2 bytes for # of coefficients */ - y = 2; - - /* characteristic */ - y += 2 + mp_signed_bin_size(&(a->characteristic)); - - /* all of the terms */ - for (x = 0; x < a->used; x++) { - y += 2 + mp_signed_bin_size(&(a->terms[x])); - } - - return y; -} - - diff --git a/external/libtompoly-0.04/pb_readraw.c b/external/libtompoly-0.04/pb_readraw.c deleted file mode 100644 index 8e4b70a..0000000 --- a/external/libtompoly-0.04/pb_readraw.c +++ /dev/null @@ -1,55 +0,0 @@ -/* LibTomPoly, Polynomial Basis Math -- Tom St Denis - * - * LibTomPoly is a public domain library that provides - * polynomial basis arithmetic support. It relies on - * LibTomMath for large integer support. - * - * This library is free for all purposes without any - * express guarantee that it works. - * - * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org - */ -#include - -int pb_readraw(pb_poly *a, unsigned char *buf, int len) -{ - int terms, x, y, z, err; - - /* zero poly */ - pb_zero(a); - - /* must be at least four bytes */ - if (len < 4) { - return MP_VAL; - } - - /* number of terms */ - terms = ((unsigned)buf[0]) | ((unsigned)buf[1]<<8); - y = 2; - - /* grow to the right size */ - if (a->alloc < terms) { - if ((err = pb_grow(a, terms)) != MP_OKAY) { - return err; - } - } - - /* read characteristic */ - z = ((unsigned)buf[y]) | ((unsigned)buf[y+1]<<8); y += 2; - if (z + y > len) { return MP_VAL; } - if ((err = mp_read_signed_bin(&(a->characteristic), buf+y, z)) != MP_OKAY) { return err; } - y += z; - - - /* read terms */ - for (x = 0; x < terms; x++) { - z = ((unsigned)buf[y]) | ((unsigned)buf[y+1]<<8); y += 2; - if (z + y > len) { return MP_VAL; } - if ((err = mp_read_signed_bin(&(a->characteristic), buf+y, z)) != MP_OKAY) { return err; } - y += z; - } - - return MP_OKAY; -} - - diff --git a/external/libtompoly-0.04/pb_rshd.c b/external/libtompoly-0.04/pb_rshd.c deleted file mode 100644 index 2662ab1..0000000 --- a/external/libtompoly-0.04/pb_rshd.c +++ /dev/null @@ -1,38 +0,0 @@ -/* LibTomPoly, Polynomial Basis Math -- Tom St Denis - * - * LibTomPoly is a public domain library that provides - * polynomial basis arithmetic support. It relies on - * LibTomMath for large integer support. - * - * This library is free for all purposes without any - * express guarantee that it works. - * - * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org - */ -#include - -int pb_rshd(pb_poly *a, int x) -{ - int y; - - if (x >= a->used) { - pb_zero(a); - return MP_OKAY; - } - - if (x <= 0) { - return MP_OKAY; - } - - for (y = x; y < a->used; y++) { - mp_exch(&(a->terms[y]), &(a->terms[y-x])); - } - - for (y = a->used - x; y < a->used; y++) { - mp_zero(&(a->terms[y])); - } - a->used -= x; - - return MP_OKAY; -} - diff --git a/external/libtompoly-0.04/pb_shrink.c b/external/libtompoly-0.04/pb_shrink.c deleted file mode 100644 index 68a3a58..0000000 --- a/external/libtompoly-0.04/pb_shrink.c +++ /dev/null @@ -1,44 +0,0 @@ -/* LibTomPoly, Polynomial Basis Math -- Tom St Denis - * - * LibTomPoly is a public domain library that provides - * polynomial basis arithmetic support. It relies on - * LibTomMath for large integer support. - * - * This library is free for all purposes without any - * express guarantee that it works. - * - * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org - */ -#include - -int pb_shrink(pb_poly *a) -{ - int err, x; - mp_int *tmp; - - /* first resize the array of terms */ - if (a->used != a->alloc && a->used > 0) { - /* free the mp_ints */ - for (x = a->used; x < a->alloc; x++) { - mp_clear(&(a->terms[x])); - } - - /* resize the array of pointers */ - tmp = realloc(a->terms, sizeof(mp_int) * a->used); - if (tmp == NULL) { - return MP_MEM; - } - a->terms = tmp; - a->alloc = a->used; - } - - /* now shrink each mp_int */ - for (x = 0; x < a->used; x++) { - if ((err = mp_shrink(&(a->terms[x]))) != MP_OKAY) { - return err; - } - } - return MP_OKAY; -} - - diff --git a/external/libtompoly-0.04/pb_sub.c b/external/libtompoly-0.04/pb_sub.c deleted file mode 100644 index b82a2e8..0000000 --- a/external/libtompoly-0.04/pb_sub.c +++ /dev/null @@ -1,86 +0,0 @@ -/* LibTomPoly, Polynomial Basis Math -- Tom St Denis - * - * LibTomPoly is a public domain library that provides - * polynomial basis arithmetic support. It relies on - * LibTomMath for large integer support. - * - * This library is free for all purposes without any - * express guarantee that it works. - * - * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org - */ -#include - -int pb_sub(pb_poly *a, pb_poly *b, pb_poly *c) -{ - int neg, err, x, y, z, characteristic; - pb_poly *tmp; - - /* grow c to be the max size */ - y = MAX(a->used, b->used); - if (c->alloc < y) { - if ((err = pb_grow(c, y)) != MP_OKAY) { - return err; - } - } - - /* do we need to concern char */ - characteristic = mp_iszero(&(c->characteristic)); - - /* sub the terms */ - z = MIN(a->used, b->used); - for (x = 0; x < z; x++) { - if ((err = mp_sub(&(a->terms[x]), &(b->terms[x]), &(c->terms[x]))) != MP_OKAY) { - return err; - } - if (characteristic == MP_NO) { - if ((err = mp_mod(&(c->terms[x]), &(c->characteristic), &(c->terms[x]))) != MP_OKAY) { - return err; - } - } - } - - /* excess digits? */ - if (y != z) { - if (a->used == y) { - tmp = a; - neg = 0; - } else { - tmp = b; - neg = 1; - } - for (x = z; x < y; x++) { - if (characteristic == MP_NO) { - if ((err = mp_mod(&(tmp->terms[x]), &(c->characteristic), &(c->terms[x]))) != MP_OKAY) { - return err; - } - if (neg) { - if ((err = mp_sub(&(c->characteristic), &(c->terms[x]), &(c->terms[x]))) != MP_OKAY) { - return err; - } - } - } else { - if (neg) { - if ((err = mp_neg(&(tmp->terms[x]), &(c->terms[x]))) != MP_OKAY) { - return err; - } - } else { - if ((err = mp_copy(&(tmp->terms[x]), &(c->terms[x]))) != MP_OKAY) { - return err; - } - } - } - } - } - - /* zero excess */ - for (x = y; x < c->used; x++) { - mp_zero(&(c->terms[x])); - } - c->used = y; - pb_clamp(c); - - return MP_OKAY; -} - - diff --git a/external/libtompoly-0.04/pb_submod.c b/external/libtompoly-0.04/pb_submod.c deleted file mode 100644 index bfa2f8e..0000000 --- a/external/libtompoly-0.04/pb_submod.c +++ /dev/null @@ -1,35 +0,0 @@ -/* LibTomPoly, Polynomial Basis Math -- Tom St Denis - * - * LibTomPoly is a public domain library that provides - * polynomial basis arithmetic support. It relies on - * LibTomMath for large integer support. - * - * This library is free for all purposes without any - * express guarantee that it works. - * - * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org - */ -#include - -int pb_submod(pb_poly *a, pb_poly *b, pb_poly *c, pb_poly *d) -{ - int err; - pb_poly tmp; - - if ((err = pb_init(&tmp, &(d->characteristic))) != MP_OKAY) { - return err; - } - if ((err = pb_sub(a, b, &tmp)) != MP_OKAY) { - goto __TMP; - } - if ((err = pb_mod(&tmp, c, d)) != MP_OKAY) { - goto __TMP; - } - - err = MP_OKAY; -__TMP: pb_clear(&tmp); - return err; -} - - - diff --git a/external/libtompoly-0.04/pb_toraw.c b/external/libtompoly-0.04/pb_toraw.c deleted file mode 100644 index 8c0c63f..0000000 --- a/external/libtompoly-0.04/pb_toraw.c +++ /dev/null @@ -1,42 +0,0 @@ -/* LibTomPoly, Polynomial Basis Math -- Tom St Denis - * - * LibTomPoly is a public domain library that provides - * polynomial basis arithmetic support. It relies on - * LibTomMath for large integer support. - * - * This library is free for all purposes without any - * express guarantee that it works. - * - * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org - */ -#include - -int pb_toraw(pb_poly *a, unsigned char *dst) -{ - int err, x, y, z; - - /* store the # of terms */ - dst[0] = a->used & 255; - dst[1] = (a->used >> 8) & 255; - y = 2; - - /* store the characteristic */ - z = mp_signed_bin_size(&(a->characteristic)); - dst[y++] = z&255; - dst[y++] = (z>>8)&255; - if ((err = mp_to_signed_bin(&(a->characteristic), dst+y)) != MP_OKAY) { return err; } - y += z; - - for (x = 0; x < a->used; x++) { - z = mp_signed_bin_size(&(a->terms[x])); - dst[y++] = z&255; - dst[y++] = (z>>8)&255; - if ((err = mp_to_signed_bin(&(a->terms[x]), dst+y)) != MP_OKAY) { return err; } - y += z; - } - - return MP_OKAY; -} - - - diff --git a/external/libtompoly-0.04/pb_zero.c b/external/libtompoly-0.04/pb_zero.c deleted file mode 100644 index ca51a91..0000000 --- a/external/libtompoly-0.04/pb_zero.c +++ /dev/null @@ -1,23 +0,0 @@ -/* LibTomPoly, Polynomial Basis Math -- Tom St Denis - * - * LibTomPoly is a public domain library that provides - * polynomial basis arithmetic support. It relies on - * LibTomMath for large integer support. - * - * This library is free for all purposes without any - * express guarantee that it works. - * - * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org - */ -#include - -void pb_zero(pb_poly *a) -{ - int x; - for (x = 0; x < a->used; x++) { - mp_zero(&(a->terms[x])); - } - a->used = 0; -} - - diff --git a/external/libtompoly-0.04/tompoly.h b/external/libtompoly-0.04/tompoly.h deleted file mode 100644 index 646a903..0000000 --- a/external/libtompoly-0.04/tompoly.h +++ /dev/null @@ -1,115 +0,0 @@ -/* LibTomPoly, Polynomial Basis Math -- Tom St Denis - * - * LibTomPoly is a public domain library that provides - * polynomial basis arithmetic support. It relies on - * LibTomMath for large integer support. - * - * This library is free for all purposes without any - * express guarantee that it works. - * - * Tom St Denis, tomstdenis@iahu.ca, http://poly.libtomcrypt.org - */ -#ifndef TOMPOLY_H_ -#define TOMPOLY_H_ - -#include - -/* this structure holds a polynomial */ -typedef struct { - int used, /* number of terms */ - alloc; /* number of terms available (total) */ - mp_int characteristic, /* characteristic, zero if not finite */ - *terms; /* terms of polynomial */ -} pb_poly; - - -/* default number of terms */ -#define PB_TERMS 4 - -/* Compare codes */ -#define PB_EQ 0 /* They're exactly equal */ -#define PB_DEG_LT 1 /* The left has a lower degree */ -#define PB_DEG_EQ 2 /* same degree */ -#define PB_DEG_GT 3 /* The left has a higher degree */ - -int pb_init(pb_poly *a, mp_int *characteristic); -int pb_init_size(pb_poly *a, mp_int *characteristic, int size); -int pb_init_copy(pb_poly *a, pb_poly *b); -int pb_init_multi(mp_int *characteristic, pb_poly *pb, ...); -void pb_clear_multi(pb_poly *mp, ...); -void pb_clear(pb_poly *a); - -int pb_shrink(pb_poly *a); -int pb_grow(pb_poly *a, int size); -void pb_clamp(pb_poly *a); - -/* dest(x) := src(x) */ -int pb_copy(pb_poly *src, pb_poly *dest); - -/* compare these */ -int pb_cmp(pb_poly *a, pb_poly *b); - -/* swap contents of a(x) and b(x) */ -void pb_exch(pb_poly *a, pb_poly *b); - -/* a(x) = 0 */ -void pb_zero(pb_poly *a); - -/* a(x) = a(x) / I(x)^x */ -int pb_rshd(pb_poly *a, int x); - -/* a(x) = a(x) * I(x)^x */ -int pb_lshd(pb_poly *a, int x); - -/* c(x) = a(x) + b(x) */ -int pb_add(pb_poly *a, pb_poly *b, pb_poly *c); - -/* c(x) = a(x) - b(x) */ -int pb_sub(pb_poly *a, pb_poly *b, pb_poly *c); - -/* c(x) = a(x) * b(x) */ -int pb_mul(pb_poly *a, pb_poly *b, pb_poly *c); - -/* c(x) * b(x) + d(x) = a(x) */ -int pb_div(pb_poly *a, pb_poly *b, pb_poly *c, pb_poly *d); - -/* c(x) = a(x) mod b(x) */ -int pb_mod(pb_poly *a, pb_poly *b, pb_poly *c); - -/* d(x) = (a(x) + b(x)) mod c(x) */ -int pb_addmod(pb_poly *a, pb_poly *b, pb_poly *c, pb_poly *d); - -/* d(x) = (a(x) - b(x)) mod c(x) */ -int pb_submod(pb_poly *a, pb_poly *b, pb_poly *c, pb_poly *d); - -/* d(x) = (a(x) * b(x)) mod c(x) */ -int pb_mulmod(pb_poly *a, pb_poly *b, pb_poly *c, pb_poly *d); - - -/* mathy stuff */ - -/* makes b equal to the monic polynomial form of a */ -int pb_monic(pb_poly *a, pb_poly *b); - -/* returns the monic GCD of a,b in GF(p^k)[x] */ -int pb_gcd(pb_poly *a, pb_poly *b, pb_poly *c); - -/* Extended euclidean algorithm of (a, b) produces a*u1 + b*u2 = u3 */ -int pb_exteuclid(pb_poly *a, pb_poly *b, pb_poly *U1, pb_poly *U2, pb_poly *U3); - -/* finds the inverse of a modulo b and stores it in c such that a*c == 1 mod b */ -int pb_invmod(pb_poly *a, pb_poly *b, pb_poly *c); - -/* computes Y == G^X mod P [accepts negative values for X] */ -int pb_exptmod (pb_poly * G, mp_int * X, pb_poly * P, pb_poly * Y); - -/* is a(x) irreducible (GF(p)[x] only) */ -int pb_isirreduc(pb_poly *a, int *res); - - -/* I/O */ -int pb_rawsize(pb_poly *a); -int pb_toraw(pb_poly *a, unsigned char *dst); -int pb_readraw(pb_poly *a, unsigned char *buf, int len); - -#endif From 574bbec067d2c7d04acb95cafad79b1075315f49 Mon Sep 17 00:00:00 2001 From: hasufell Date: Sat, 24 May 2014 23:12:15 +0200 Subject: [PATCH 07/26] KEYGEN: first implementation --- src/keypair.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/keypair.h | 49 ++++++++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+) create mode 100644 src/keypair.c create mode 100644 src/keypair.h diff --git a/src/keypair.c b/src/keypair.c new file mode 100644 index 0000000..a187dc7 --- /dev/null +++ b/src/keypair.c @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2014 FH Bielefeld + * + * This file is part of a FH Bielefeld project. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "context.h" +#include "keypair.h" +#include "poly.h" + +#include +#include + +#include + + +bool ntru_create_keypair( + fmpz_poly_t f, + fmpz_poly_t g, + keypair *pair, + ntru_context *ctx) +{ + bool retval = true; + fmpz_poly_t Fq, + Fp, + priv; + + fmpz_poly_init(Fq); + fmpz_poly_init(Fp); + fmpz_poly_init(priv); + + + if (!poly_inverse_poly_q(f, Fq, ctx)) { + retval = false; + goto cleanup; + } + + if (!poly_inverse_poly_q(f, Fp, ctx)) { + retval = false; + goto cleanup; + } + + poly_starmultiply(Fq, g, priv, ctx, ctx->q); + fmpz_poly_scalar_mul_ui(priv, priv, ctx->p); + fmpz_poly_mod(priv, ctx->q); + + fmpz_poly_init(pair->priv); + fmpz_poly_init(pair->pub); + + fmpz_poly_set(pair->priv, priv); + fmpz_poly_set(pair->pub, Fp); + +cleanup: + fmpz_poly_clear(Fq); + fmpz_poly_clear(Fp); + fmpz_poly_clear(priv); + return retval; +} + diff --git a/src/keypair.h b/src/keypair.h new file mode 100644 index 0000000..9412c42 --- /dev/null +++ b/src/keypair.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2014 FH Bielefeld + * + * This file is part of a FH Bielefeld project. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef NTRU_KEYPAIR_H +#define NTRU_KEYPAIR_H + + +#include "context.h" + +#include +#include +#include + + +typedef struct keypair keypair; + + +struct keypair { + fmpz_poly_t priv; + fmpz_poly_t pub; +}; + + +bool ntru_create_keypair( + fmpz_poly_t f, + fmpz_poly_t g, + keypair *pair, + ntru_context *ctx); + + +#endif /* NTRU_KEYPAIR_H */ From 805559a8cafe3ba69b6a9ac3293fd10aeecb5c35 Mon Sep 17 00:00:00 2001 From: hasufell Date: Sun, 25 May 2014 00:58:01 +0200 Subject: [PATCH 08/26] BUILD: add keypair to build --- src/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Makefile b/src/Makefile index 77126fb..de7a68a 100644 --- a/src/Makefile +++ b/src/Makefile @@ -37,8 +37,8 @@ endif LIBS += -L. -lgmp -lmpfr -lm # objects -PQC_OBJS = poly.o mem.o encrypt.o decrypt.o -PQC_HEADERS = err.h poly.h context.h encrypt.h decrypt.h +PQC_OBJS = poly.o mem.o encrypt.o decrypt.o keypair.o +PQC_HEADERS = err.h poly.h context.h encrypt.h decrypt.h keypair.h # CUNIT_OBJS = cunit.o # includes From 1443b11fa877ecd50200af0005b7ebcee135133c Mon Sep 17 00:00:00 2001 From: hasufell Date: Sun, 25 May 2014 00:58:22 +0200 Subject: [PATCH 09/26] KEYGEN: fix keys --- src/keypair.c | 17 +++++++++-------- src/keypair.h | 1 + 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/keypair.c b/src/keypair.c index a187dc7..7c2c25b 100644 --- a/src/keypair.c +++ b/src/keypair.c @@ -38,11 +38,11 @@ bool ntru_create_keypair( bool retval = true; fmpz_poly_t Fq, Fp, - priv; + pub; fmpz_poly_init(Fq); fmpz_poly_init(Fp); - fmpz_poly_init(priv); + fmpz_poly_init(pub); if (!poly_inverse_poly_q(f, Fq, ctx)) { @@ -55,20 +55,21 @@ bool ntru_create_keypair( goto cleanup; } - poly_starmultiply(Fq, g, priv, ctx, ctx->q); - fmpz_poly_scalar_mul_ui(priv, priv, ctx->p); - fmpz_poly_mod(priv, ctx->q); + poly_starmultiply(Fq, g, pub, ctx, ctx->q); + fmpz_poly_scalar_mul_ui(pub, pub, ctx->p); + fmpz_poly_mod(pub, ctx->q); fmpz_poly_init(pair->priv); fmpz_poly_init(pair->pub); - fmpz_poly_set(pair->priv, priv); - fmpz_poly_set(pair->pub, Fp); + fmpz_poly_set(pair->priv, f); + fmpz_poly_set(pair->priv_inv, Fp); + fmpz_poly_set(pair->pub, pub); cleanup: fmpz_poly_clear(Fq); fmpz_poly_clear(Fp); - fmpz_poly_clear(priv); + fmpz_poly_clear(pub); return retval; } diff --git a/src/keypair.h b/src/keypair.h index 9412c42..1dc8bcc 100644 --- a/src/keypair.h +++ b/src/keypair.h @@ -35,6 +35,7 @@ typedef struct keypair keypair; struct keypair { fmpz_poly_t priv; + fmpz_poly_t priv_inv; fmpz_poly_t pub; }; From 8fd5a6c829458770968f00754a8aec5a28089426 Mon Sep 17 00:00:00 2001 From: hasufell Date: Sun, 25 May 2014 00:58:34 +0200 Subject: [PATCH 10/26] ENC: fix encryption --- src/encrypt.c | 27 +++++++-------------------- src/encrypt.h | 5 +++-- 2 files changed, 10 insertions(+), 22 deletions(-) diff --git a/src/encrypt.c b/src/encrypt.c index 0368349..5d319ea 100644 --- a/src/encrypt.c +++ b/src/encrypt.c @@ -35,34 +35,21 @@ * m = the message poly * q = large mod * - * @param ctx ntru_context* the ntru context - * @param rnd pb_poly* the random poly * @param msg pb_poly* the message to encrypt * @param pubKey pb_poly* the public key + * @param rnd pb_poly* the random poly * @param out pb_poly* the output poly [out] + * @param ctx ntru_context* the ntru context */ -void ntru_encrypt_poly(fmpz_poly_t rnd, +void ntru_encrypt_poly( fmpz_poly_t msg, fmpz_poly_t pub_key, + fmpz_poly_t rnd, fmpz_poly_t out, ntru_context *ctx) { - poly_starmultiply(pub_key, rnd, out, ctx, ctx->q); - fmpz_poly_zero(out); - - for(unsigned int i = 0; i <= ctx->N - 1; i++) { - fmpz_poly_t tmp_poly; - fmpz_t tmp_coeff; - fmpz *e_coeff_i = fmpz_poly_get_coeff_ptr(out, i), - *m_coeff_i = fmpz_poly_get_coeff_ptr(msg, i); - - fmpz_poly_init(tmp_poly); - fmpz_init(tmp_coeff); - - fmpz_add_n(tmp_coeff, e_coeff_i, m_coeff_i); - fmpz_mod_ui(tmp_coeff, tmp_coeff, ctx->q); - - fmpz_poly_set_coeff_fmpz(out, i, tmp_coeff); - } + poly_starmultiply(pub_key, rnd, out, ctx, ctx->q); + fmpz_poly_add(out, out, msg); + fmpz_poly_mod_unsigned(out, ctx->q); } diff --git a/src/encrypt.h b/src/encrypt.h index 181bf15..18dcaa4 100644 --- a/src/encrypt.h +++ b/src/encrypt.h @@ -30,9 +30,10 @@ #include -void ntru_encrypt_poly(fmpz_poly_t rnd, +void ntru_encrypt_poly( fmpz_poly_t msg, - fmpz_poly_t pubKey, + fmpz_poly_t pub_key, + fmpz_poly_t rnd, fmpz_poly_t out, ntru_context *ctx); From 23d95ae992c908d4aa212211d2e799de126dadac Mon Sep 17 00:00:00 2001 From: hasufell Date: Sun, 25 May 2014 01:04:09 +0200 Subject: [PATCH 11/26] KEYGEN: fix priv_inv key --- src/keypair.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/keypair.c b/src/keypair.c index 7c2c25b..5b72911 100644 --- a/src/keypair.c +++ b/src/keypair.c @@ -50,7 +50,7 @@ bool ntru_create_keypair( goto cleanup; } - if (!poly_inverse_poly_q(f, Fp, ctx)) { + if (!poly_inverse_poly_p(f, Fp, ctx)) { retval = false; goto cleanup; } From dda90cabcf11f3dccf9660e2c93e5c168f51c5ca Mon Sep 17 00:00:00 2001 From: hasufell Date: Sun, 25 May 2014 01:04:30 +0200 Subject: [PATCH 12/26] DEC: use a central lift after we are done --- src/decrypt.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/decrypt.c b/src/decrypt.c index 13845d1..60f6700 100644 --- a/src/decrypt.c +++ b/src/decrypt.c @@ -53,4 +53,5 @@ void ntru_decrypt_poly( poly_starmultiply(priv_key, encr_msg, a, ctx, ctx->q); fmpz_poly_mod(a, ctx->q); poly_starmultiply(a, priv_key_inv, out, ctx, ctx->p); + fmpz_poly_mod(out, ctx->p); } From 32f2eb2295db59bdd2a3aecf6276532d519e22d8 Mon Sep 17 00:00:00 2001 From: hasufell Date: Sun, 25 May 2014 01:11:56 +0200 Subject: [PATCH 13/26] KEYGEN: add doxygen comments --- src/keypair.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/keypair.h b/src/keypair.h index 1dc8bcc..79d2eb3 100644 --- a/src/keypair.h +++ b/src/keypair.h @@ -33,9 +33,25 @@ typedef struct keypair keypair; +/** + * This struct holds the keypair, + * both private and public components. + */ struct keypair { + /** + * First part of the private key, + * a random polynom. + */ fmpz_poly_t priv; + /** + * Second part of the private key, + * the priv polynom inverted. + */ fmpz_poly_t priv_inv; + /** + * The public key, computed as: + * h = p * (Fq * g) mod q + */ fmpz_poly_t pub; }; From eb8fa515b4f219395ae126c8622c39d14c270ca7 Mon Sep 17 00:00:00 2001 From: hasufell Date: Sun, 25 May 2014 01:13:34 +0200 Subject: [PATCH 14/26] DOC: fix more doxygen comments --- src/decrypt.c | 3 +-- src/encrypt.c | 2 +- src/poly.c | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/decrypt.c b/src/decrypt.c index 60f6700..f162f00 100644 --- a/src/decrypt.c +++ b/src/decrypt.c @@ -34,9 +34,8 @@ * @param priv_key the polynom containing the private key to decrypt * the message * @param priv_key_inv the inverse polynome to the private key - * @param context the ntru_context * @param out the result polynom is written in here [out] - * + * @param ctx the ntru_context */ void ntru_decrypt_poly( fmpz_poly_t encr_msg, diff --git a/src/encrypt.c b/src/encrypt.c index 5d319ea..d529b07 100644 --- a/src/encrypt.c +++ b/src/encrypt.c @@ -36,7 +36,7 @@ * q = large mod * * @param msg pb_poly* the message to encrypt - * @param pubKey pb_poly* the public key + * @param pub_key pb_poly* the public key * @param rnd pb_poly* the random poly * @param out pb_poly* the output poly [out] * @param ctx ntru_context* the ntru context diff --git a/src/poly.c b/src/poly.c index b1e032c..3d88e4a 100644 --- a/src/poly.c +++ b/src/poly.c @@ -433,7 +433,7 @@ cleanup: * and Fast NTRU Key Creation." * * @param a polynomial to invert - * @param Fq polynomial [out] + * @param Fp polynomial [out] * @param ctx NTRU context */ bool poly_inverse_poly_p(fmpz_poly_t a, From bdb12ac1757a28062c6eb8800fd4232d4898779d Mon Sep 17 00:00:00 2001 From: hasufell Date: Sun, 25 May 2014 01:36:44 +0200 Subject: [PATCH 15/26] BUILD: rm obsolete tompoly/tommath references --- Makefile | 2 -- src/Makefile | 18 ++++-------------- 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/Makefile b/Makefile index 0f8d809..8107b07 100644 --- a/Makefile +++ b/Makefile @@ -8,8 +8,6 @@ clean: $(MAKE) -C src clean clean-all: clean - $(MAKE) -C external/libtommath-0.42.0 clean - $(MAKE) -C external/libtompoly-0.04 clean $(MAKE) -C external/flint-2.4.3 clean doc: diff --git a/src/Makefile b/src/Makefile index de7a68a..4b5bb0b 100644 --- a/src/Makefile +++ b/src/Makefile @@ -45,15 +45,11 @@ PQC_HEADERS = err.h poly.h context.h encrypt.h decrypt.h keypair.h INCS = -I. ifndef UNBUNDLE -LIBTOMMATH = ../external/libtommath-0.42.0/libtommath.a -LIBTOMPOLY = ../external/libtompoly-0.04/libtompoly.a LIBFLINT = ../external/flint-2.4.3/libflint.a INCS += -I../external/libtommath-0.42.0 \ -I../external/libtompoly-0.04 \ -I../external/flint-2.4.3 else -LIBTOMMATH = -ltommath -LIBTOMPOLY = -ltompoly LIBFLINT = -lflint endif @@ -68,12 +64,6 @@ all: libpqc.a libpqc.so # $(CC) $(CFLAGS) -o $@ $(CUNIT_OBJS) $(LDFLAGS) $(CUNIT_LIBS) $(PQC_LIBS) $(LIBS) ifndef UNBUNDLE -$(LIBTOMMATH): - $(MAKE) -C ../external/libtommath-0.42.0 - -$(LIBTOMPOLY): - $(MAKE) -C ../external/libtompoly-0.04 - $(LIBFLINT): cd ../external/flint-2.4.3 && ./configure --prefix=/usr --with-gmp=/usr --with-mpfr=/usr --disable-shared $(MAKE) -C ../external/flint-2.4.3 @@ -82,13 +72,13 @@ endif libpqc.a: $(PQC_OBJS) $(PQC_HEADERS) $(AR) cru libpqc.a $(PQC_OBJS) -libpqc.so: libpqc.a $(PQC_HEADERS) $(LIBTOMMATH) $(LIBTOMPOLY) $(LIBFLINT) +libpqc.so: libpqc.a $(PQC_HEADERS) $(LIBFLINT) $(CC) -shared $(CFLAGS) -o $@ $(LDFLAGS) \ - libpqc.a $(LIBTOMMATH) $(LIBTOMPOLY) $(LIBFLINT) $(LIBS) + libpqc.a $(LIBFLINT) $(LIBS) -main: main.o libpqc.a $(LIBTOMMATH) $(LIBTOMPOLY) $(LIBFLINT) +main: main.o libpqc.a $(LIBFLINT) $(CC) $(CFLAGS) -o $@ $(LDFLAGS) \ - main.o $(LIBTOMPOLY) libpqc.a $(LIBTOMPOLY) $(LIBTOMMATH) $(LIBFLINT) $(LIBS) + main.o libpqc.a $(LIBFLINT) $(LIBS) install: $(INSTALL_DIR) "$(DESTDIR)$(INSTALL_BINDIR)" From f3ac38a6c09dcaeb35aa69658dce801767630e11 Mon Sep 17 00:00:00 2001 From: hasufell Date: Sun, 25 May 2014 01:40:07 +0200 Subject: [PATCH 16/26] POLY: add print functions --- src/poly.c | 23 +++++++++++++++++++++++ src/poly.h | 4 ++++ 2 files changed, 27 insertions(+) diff --git a/src/poly.c b/src/poly.c index 3d88e4a..4eb97bf 100644 --- a/src/poly.c +++ b/src/poly.c @@ -602,3 +602,26 @@ cleanup: return retval; } + +/** + * Draws a polynomial to stdout. + * + * @param poly draw this + */ +void poly_draw(fmpz_poly_t poly) +{ + fmpz_poly_print(poly); + flint_printf("\n"); +} + +/** + * Draws a polynomial to stdout, + * in pretty format. + * + * @param poly draw this + */ +void poly_draw_pretty(fmpz_poly_t poly) +{ + fmpz_poly_print_pretty(poly, "x"); + flint_printf("\n"); +} diff --git a/src/poly.h b/src/poly.h index a92ad3a..839898a 100644 --- a/src/poly.h +++ b/src/poly.h @@ -70,5 +70,9 @@ bool poly_inverse_poly_p(fmpz_poly_t a, fmpz_poly_t Fp, ntru_context *ctx); +void poly_draw(fmpz_poly_t poly); + +void poly_draw_pretty(fmpz_poly_t poly); + #endif /* NTRU_POLY_H */ From 89447a7abb708a73c45ad9f9ee41528b0708cd78 Mon Sep 17 00:00:00 2001 From: hasufell Date: Sun, 25 May 2014 01:48:55 +0200 Subject: [PATCH 17/26] POLY: rm obsolete doxygen comment --- src/poly.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/poly.c b/src/poly.c index 4eb97bf..a7912d5 100644 --- a/src/poly.c +++ b/src/poly.c @@ -79,9 +79,8 @@ static void poly_mod2_to_modq(fmpz_poly_t a, /** * Initializes and builds a polynomial with the * coefficient values of c[] of size len within NTRU - * context ctx and returns a newly allocated polynomial - * pointer which is not clamped. For an empty polynom, - * both parameters can be NULL/0. + * context ctx and returns a newly allocated polynomial. + * For an empty polynom, both parameters can be NULL/0. * * @param c array of polynomial coefficients, can be NULL * @param len size of the coefficient array, can be 0 From 13b54fa7f5fb975c916c870c18be6b7fa7720f16 Mon Sep 17 00:00:00 2001 From: hasufell Date: Sun, 25 May 2014 02:15:24 +0200 Subject: [PATCH 18/26] DOC: add brief/file comments --- src/context.h | 6 ++++++ src/decrypt.c | 7 +++++++ src/decrypt.h | 6 ++++++ src/encrypt.c | 7 +++++++ src/encrypt.h | 6 ++++++ src/err.h | 6 ++++++ src/keypair.c | 17 +++++++++++++++++ src/keypair.h | 6 ++++++ src/mem.c | 7 +++++++ src/mem.h | 6 ++++++ src/poly.c | 8 ++++++++ src/poly.h | 5 +++++ 12 files changed, 87 insertions(+) diff --git a/src/context.h b/src/context.h index e0e0883..d534431 100644 --- a/src/context.h +++ b/src/context.h @@ -19,6 +19,12 @@ * MA 02110-1301 USA */ +/** + * @file context.h + * This file defines the ntru_context + * and related data types. + * @brief NTRU context types + */ #ifndef NTRU_CONTEXT_H #define NTRU_CONTEXT_H diff --git a/src/decrypt.c b/src/decrypt.c index f162f00..2123caf 100644 --- a/src/decrypt.c +++ b/src/decrypt.c @@ -19,6 +19,13 @@ * MA 02110-1301 USA */ +/** + * @file decrypt.c + * This file handles the NTRU decryption + * algorithm. + * @brief NTRU decryption + */ + #include "decrypt.h" #include diff --git a/src/decrypt.h b/src/decrypt.h index d610ecd..e4447f6 100644 --- a/src/decrypt.h +++ b/src/decrypt.h @@ -19,6 +19,12 @@ * MA 02110-1301 USA */ +/** + * @file decrypt.h + * Header for the external API of decrypt.c. + * @brief header for decrypt.c + */ + #ifndef NTRU_DECRYPT_H #define NTRU_DECRYPT_H diff --git a/src/encrypt.c b/src/encrypt.c index d529b07..9a366d3 100644 --- a/src/encrypt.c +++ b/src/encrypt.c @@ -19,6 +19,13 @@ * MA 02110-1301 USA */ +/** + * @file encrypt.c + * This file handles the NTRU encryption + * algorithm. + * @brief NTRU encryption + */ + #include "encrypt.h" #include diff --git a/src/encrypt.h b/src/encrypt.h index 18dcaa4..886c3b8 100644 --- a/src/encrypt.h +++ b/src/encrypt.h @@ -19,6 +19,12 @@ * MA 02110-1301 USA */ +/** + * @file encrypt.h + * Header for the internal API of encrypt.c. + * @brief header for encrypt.c + */ + #ifndef PQC_ENCRYPT_H #define PQC_ENCRYPT_H diff --git a/src/err.h b/src/err.h index 747c6c5..531b3c5 100644 --- a/src/err.h +++ b/src/err.h @@ -19,6 +19,12 @@ * MA 02110-1301 USA */ +/** + * @file err.h + * This file provides error macros + * and functions for the NTRU cryptosystem. + * @brief error handling + */ #ifndef NTRU_ERR_H #define NTRU_ERR_H diff --git a/src/keypair.c b/src/keypair.c index 5b72911..8f3dd4d 100644 --- a/src/keypair.c +++ b/src/keypair.c @@ -19,6 +19,13 @@ * MA 02110-1301 USA */ +/** + * @file keypair.c + * This file handles the creation of the + * key pair and possibly common operations on them. + * @brief key creation and operations + */ + #include "context.h" #include "keypair.h" #include "poly.h" @@ -29,6 +36,16 @@ #include +/** + * Creates an NTRU key pair, + * consisting of public and private + * components. + * + * @param f a random polynomial + * @param g a random polynomial + * @param pair store private and public components here [out] + * @param ctx the NTRU context + */ bool ntru_create_keypair( fmpz_poly_t f, fmpz_poly_t g, diff --git a/src/keypair.h b/src/keypair.h index 79d2eb3..680ef12 100644 --- a/src/keypair.h +++ b/src/keypair.h @@ -19,6 +19,12 @@ * MA 02110-1301 USA */ +/** + * @file keypair.h + * Header for internal API of keypair.c. + * @brief header for keypair.c + */ + #ifndef NTRU_KEYPAIR_H #define NTRU_KEYPAIR_H diff --git a/src/mem.c b/src/mem.c index 7a63f58..49429cc 100644 --- a/src/mem.c +++ b/src/mem.c @@ -19,6 +19,13 @@ * MA 02110-1301 USA */ +/** + * @file mem.c + * This file provides functions for + * memory management. + * @brief memory management + */ + #include "mem.h" #include diff --git a/src/mem.h b/src/mem.h index eabe1e9..8c0ca3c 100644 --- a/src/mem.h +++ b/src/mem.h @@ -19,6 +19,12 @@ * MA 02110-1301 USA */ +/** + * @file mem.h + * Header for the internal API of mem.c. + * @brief header for mem.c + */ + #ifndef NTRU_MEM_H #define NTRU_MEM_H diff --git a/src/poly.c b/src/poly.c index a7912d5..e78706d 100644 --- a/src/poly.c +++ b/src/poly.c @@ -19,6 +19,14 @@ * MA 02110-1301 USA */ +/** + * @file poly.c + * This files purpose is to handle polynomials + * in general, allowing modification, arithmetic + * and common algorithms like inverting them. + * @brief operations on polynomials + */ + #include "context.h" #include "err.h" #include "mem.h" diff --git a/src/poly.h b/src/poly.h index 839898a..0707a95 100644 --- a/src/poly.h +++ b/src/poly.h @@ -19,6 +19,11 @@ * MA 02110-1301 USA */ +/** + * @file poly.h + * Header for the internal API of poly.c. + * @brief header for poly.c + */ #ifndef NTRU_POLY_H #define NTRU_POLY_H From b604ecd915b66c9d0f3fffab9705c3df9c3cdf98 Mon Sep 17 00:00:00 2001 From: hasufell Date: Sun, 25 May 2014 02:15:40 +0200 Subject: [PATCH 19/26] DOC: update Doxyfile --- Doxyfile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Doxyfile b/Doxyfile index 1798d35..3328d71 100644 --- a/Doxyfile +++ b/Doxyfile @@ -380,7 +380,7 @@ EXTRACT_PACKAGE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. -EXTRACT_STATIC = NO +EXTRACT_STATIC = YES # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. @@ -686,7 +686,7 @@ INPUT_ENCODING = UTF-8 # *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py # *.f90 *.f *.for *.vhd *.vhdl -FILE_PATTERNS = +FILE_PATTERNS = *.c *.h # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. @@ -1676,7 +1676,7 @@ HIDE_UNDOC_RELATIONS = YES # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) -HAVE_DOT = NO +HAVE_DOT = YES # The DOT_NUM_THREADS specifies the number of dot invocations doxygen is # allowed to run in parallel. When set to 0 (the default) doxygen will @@ -1757,7 +1757,7 @@ INCLUDE_GRAPH = YES # documented header file showing the documented files that directly or # indirectly include this file. -INCLUDED_BY_GRAPH = YES +INCLUDED_BY_GRAPH = NO # If the CALL_GRAPH and HAVE_DOT options are set to YES then # doxygen will generate a call dependency graph for every global function From 3905b4aba9f39d2905a3324e23379f4c33aeb010 Mon Sep 17 00:00:00 2001 From: hasufell Date: Sun, 25 May 2014 03:56:39 +0200 Subject: [PATCH 20/26] POLY: improve doxygen comments --- src/poly.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/poly.c b/src/poly.c index e78706d..d3b7049 100644 --- a/src/poly.c +++ b/src/poly.c @@ -152,6 +152,9 @@ void poly_delete_all(fmpz_poly_t *poly, ...) * so we don't have to deal with the intermediate * nmod_poly_t type if we don't need it. * + * This also normalises the coefficients to the interval + * 0 <= r < m. + * * @param a the polynom to apply the modulus to * @param mod the modulus */ @@ -174,6 +177,9 @@ void fmpz_poly_mod_unsigned(fmpz_poly_t a, * so we don't have to deal with the intermediate * nmod_poly_t type if we don't need it. * + * This also normalises the coefficients to the interval + * -m/2 <= r < m/2. + * * @param a the polynom to apply the modulus to * @param mod the modulus */ From b71e4b1ce2595e236a195d88411f8757942cbcd5 Mon Sep 17 00:00:00 2001 From: hasufell Date: Sun, 25 May 2014 03:57:51 +0200 Subject: [PATCH 21/26] POLY: improve inline doc --- src/poly.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/poly.c b/src/poly.c index d3b7049..023c7b1 100644 --- a/src/poly.c +++ b/src/poly.c @@ -597,7 +597,7 @@ bool poly_inverse_poly_p(fmpz_poly_t a, fmpz_poly_set_coeff_fmpz_n(Fp, j, b_i); } - /* check if the f * Fq = 1 (mod p) condition holds true */ + /* check if the f * Fp = 1 (mod p) condition holds true */ fmpz_poly_set(a_tmp, a); poly_starmultiply(a_tmp, Fp, a_tmp, ctx, ctx->p); if (!fmpz_poly_is_one(a_tmp)) From 3ea4006b1c70f9185251d99db301467ecaf468d8 Mon Sep 17 00:00:00 2001 From: hasufell Date: Sun, 25 May 2014 04:06:05 +0200 Subject: [PATCH 22/26] DEC: fix memory leak --- src/decrypt.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/decrypt.c b/src/decrypt.c index 2123caf..185fff8 100644 --- a/src/decrypt.c +++ b/src/decrypt.c @@ -60,4 +60,6 @@ void ntru_decrypt_poly( fmpz_poly_mod(a, ctx->q); poly_starmultiply(a, priv_key_inv, out, ctx, ctx->p); fmpz_poly_mod(out, ctx->p); + + fmpz_poly_clear(a); } From c3eb0e52f4c0218c1c5219f6fe61a6bab0368e16 Mon Sep 17 00:00:00 2001 From: hasufell Date: Sun, 25 May 2014 04:06:24 +0200 Subject: [PATCH 23/26] KEYGEN: add deletion method --- src/keypair.c | 13 +++++++++++++ src/keypair.h | 2 ++ 2 files changed, 15 insertions(+) diff --git a/src/keypair.c b/src/keypair.c index 8f3dd4d..bd608f5 100644 --- a/src/keypair.c +++ b/src/keypair.c @@ -90,3 +90,16 @@ cleanup: return retval; } +/** + * Used to free the inner structure + * of a keypair. This will not call free() + * on the pair itself. + * + * @param pair the pair to free the inner structure of + */ +void ntru_delete_keypair(keypair *pair) +{ + fmpz_poly_clear(pair->priv_inv); + fmpz_poly_clear(pair->priv); + fmpz_poly_clear(pair->pub); +} diff --git a/src/keypair.h b/src/keypair.h index 680ef12..71f0154 100644 --- a/src/keypair.h +++ b/src/keypair.h @@ -68,5 +68,7 @@ bool ntru_create_keypair( keypair *pair, ntru_context *ctx); +void ntru_delete_keypair(keypair *pair); + #endif /* NTRU_KEYPAIR_H */ From aa018591920ab231aa5a55804b3be09e60553574 Mon Sep 17 00:00:00 2001 From: hasufell Date: Sun, 25 May 2014 04:07:51 +0200 Subject: [PATCH 24/26] KEYGEN: fix missing initialisation --- src/keypair.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/keypair.c b/src/keypair.c index bd608f5..82952ad 100644 --- a/src/keypair.c +++ b/src/keypair.c @@ -77,6 +77,7 @@ bool ntru_create_keypair( fmpz_poly_mod(pub, ctx->q); fmpz_poly_init(pair->priv); + fmpz_poly_init(pair->priv_inv); fmpz_poly_init(pair->pub); fmpz_poly_set(pair->priv, f); From fd0ba50c850b2b6a45cdcc5d329928d4a11dfea5 Mon Sep 17 00:00:00 2001 From: hasufell Date: Sun, 25 May 2014 04:16:48 +0200 Subject: [PATCH 25/26] POLY: rework poly_new() Don't allocate anything here, just operate on the parameters. --- src/poly.c | 24 +++++++++++------------- src/poly.h | 7 ++++--- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/poly.c b/src/poly.c index 023c7b1..dfe4da1 100644 --- a/src/poly.c +++ b/src/poly.c @@ -90,22 +90,21 @@ static void poly_mod2_to_modq(fmpz_poly_t a, * context ctx and returns a newly allocated polynomial. * For an empty polynom, both parameters can be NULL/0. * + * @param new_poly the polynomial to initialize and + * fill with coefficients * @param c array of polynomial coefficients, can be NULL * @param len size of the coefficient array, can be 0 * @return newly allocated polynomial pointer, must be freed * with fmpz_poly_clear() */ -fmpz_poly_t *poly_new(int const * const c, +void poly_new(fmpz_poly_t new_poly, + int const * const c, const size_t len) { - fmpz_poly_t *new_poly = ntru_malloc(sizeof(*new_poly)); - - fmpz_poly_init(*new_poly); + fmpz_poly_init(new_poly); for (unsigned int i = 0; i < len; i++) - fmpz_poly_set_coeff_si(*new_poly, i, c[i]); - - return new_poly; + fmpz_poly_set_coeff_si(new_poly, i, c[i]); } /** @@ -116,10 +115,9 @@ fmpz_poly_t *poly_new(int const * const c, * * @param poly the polynomial to delete */ -void poly_delete(fmpz_poly_t *poly) +void poly_delete(fmpz_poly_t poly) { - fmpz_poly_clear(*poly); - free(poly); + fmpz_poly_clear(poly); } /** @@ -132,16 +130,16 @@ void poly_delete(fmpz_poly_t *poly) * @param poly the polynomial to delete * @param ... follow up polynomials */ -void poly_delete_all(fmpz_poly_t *poly, ...) +void poly_delete_all(fmpz_poly_t poly, ...) { - fmpz_poly_t *next_poly; + fmpz_poly_struct *next_poly; va_list args; next_poly = poly; va_start(args, poly); while (next_poly != NULL) { poly_delete(next_poly); - next_poly = va_arg(args, fmpz_poly_t*); + next_poly = va_arg(args, fmpz_poly_struct*); } va_end(args); } diff --git a/src/poly.h b/src/poly.h index 0707a95..61667d1 100644 --- a/src/poly.h +++ b/src/poly.h @@ -38,12 +38,13 @@ #include -fmpz_poly_t *poly_new(int const * const c, +void poly_new(fmpz_poly_t new_poly, + int const * const c, const size_t len); -void poly_delete(fmpz_poly_t *poly); +void poly_delete(fmpz_poly_t poly); -void poly_delete_all(fmpz_poly_t *poly, ...); +void poly_delete_all(fmpz_poly_t poly, ...); void fmpz_poly_mod_unsigned(fmpz_poly_t a, unsigned int mod); From d274a1af03fccce8e87eda4efaca60bfe83418d5 Mon Sep 17 00:00:00 2001 From: hasufell Date: Sun, 25 May 2014 04:40:49 +0200 Subject: [PATCH 26/26] BUILD: fix UNBUNDLE, rm obsolete libtom references --- src/Makefile | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Makefile b/src/Makefile index 4b5bb0b..ce3136b 100644 --- a/src/Makefile +++ b/src/Makefile @@ -46,11 +46,10 @@ INCS = -I. ifndef UNBUNDLE LIBFLINT = ../external/flint-2.4.3/libflint.a -INCS += -I../external/libtommath-0.42.0 \ - -I../external/libtompoly-0.04 \ - -I../external/flint-2.4.3 +INCS += -I../external/flint-2.4.3 else LIBFLINT = -lflint +INCS += -I/usr/include/flint endif